Three.js基础知识

news2024/9/27 15:14:24

目录

  • Three.js简介
  • 官方文档和资源导航
  • Three.js特点
  • 环境搭建
  • 场景
  • 物体
  • 相机
  • 渲染器

Three.js简介

Three.js 概述 Three.js 是一个基于 WebGL 的 JavaScript 库,用于在浏览器中创建和展示3D图形。WebGL 是一种在浏览器中直接支持硬件加速的3D图形接口,但它的API直接使用起来非常底层和复杂。Three.js 提供了一层抽象,使得开发者能够更容易地创建复杂的3D场景、对象、动画和交互。它包括了场景管理、几何形状、材质、光源、相机、动画系统等多个组件,同时还处理了兼容性问题,使得3D图形可以在多种现代浏览器上运行。

官方文档和资源导航

Three.js官方网站及文档:

Three.js官网
Three.js官方文档:这里包含了详尽的API参考、指南和教程,帮助你学习和使用Three.js的所有功能。

GitHub仓库:

Three.js GitHub: 这里你可以找到Three.js的源代码,查看提交记录,提交问题或贡献代码。

示例和教程:

Three.js在线示例:官方提供的一系列示例代码,覆盖了从基础到高级的多种应用场景,非常适合作为学习的起点。
Three.js Fundamentals:这是一个非官方但非常受欢迎的学习资源,提供了大量教程和深入解释,适合各个层次的学习者。

社区与支持:

Three.js论坛:官方论坛,可以在这里提问、分享项目或寻找解决方案。
Stack Overflow上的Three.js标签:在Stack Overflow上查找或提出有关Three.js的问题,这是一个活跃的技术问答社区。
社交媒体:关注Three.js的Twitter账号获取最新动态和社区信息。

中文资源:

Three.js中文文档:这是一个非官方的中文文档网站,提供了Three.js的中文翻译文档,适合中文用户学习。
本地搭建Three.js官方文档:如果你想在本地搭建Three.js的文档环境,可以参考GitHub上的这个仓库。

Three.js特点

  • 易用性:Three.js 提供了高级接口,让开发者无需深入了解底层WebGL API就能创建3D应用。
  • 广泛支持:Three.js 兼容多种浏览器,包括桌面和移动设备,减少了跨平台的开发工作。
  • 丰富的功能:内置了许多3D对象、几何形状、纹理、光照和相机类型,以及动画和物理系统的支持。
  • 活跃的社区:有大量示例、插件和教程,以及活跃的开发者社区,方便学习和解决问题。
  • 性能优化:Three.js 对一些常见操作进行了优化,如批处理渲染,以提高性能。

环境搭建

HTML 文件:

首先,你需要一个HTML文件来承载你的JavaScript代码和WebGL画布。在<head>部分引入Three.js库文件,这通常是three.js或压缩后的three.min.js

   <!DOCTYPE html>
   <html>
   <head>
     <title>My First Three.js Scene</title>
     <script src="path/to/three.js"></script>
   </head>
   <body>
     <canvas id="canvas"></canvas>
     <script src="main.js"></script>
   </body>
   </html>

CSS:

可以设置一些基本的CSS,确保画布占满整个视口。

   body { margin: 0; }
   canvas { display: block; }

JavaScript 文件(main.js):

在JavaScript文件中,创建一个场景(Scene)、相机(Camera)、渲染器(Renderer),并添加一个简单的3D物体,例如一个立方体(Cube)。

   var scene = new THREE.Scene();
   var camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
   var renderer = new THREE.WebGLRenderer();
   renderer.setSize(window.innerWidth, window.innerHeight);
   document.body.appendChild(renderer.domElement);

   var geometry = new THREE.BoxGeometry(1, 1, 1);
   var material = new THREE.MeshBasicMaterial({ color: 0x00ff00 });
   var cube = new THREE.Mesh(geometry, material);
   scene.add(cube);

   camera.position.z = 5;

   function animate() {
     requestAnimationFrame(animate);
     renderer.render(scene, camera);
   }
   animate();

上面创建一个绿色的立方体,置于相机前方,并在页面上持续渲染。requestAnimationFrame(animate)用于创建动画,不断地重新渲染场景。

场景

在Three.js中,THREE.Scene类是3D场景的基础,它是一个容器,用于存储所有要在3D空间中渲染的对象,包括几何体、光源、相机和其他辅助对象。

基本结构

创建一个场景非常简单,只需调用new THREE.Scene()。这个构造函数不接受任何参数,它初始化了场景的一些内部属性,如children数组,用于存储场景中的所有对象。

const scene = new THREE.Scene();

属性

THREE.Scene继承自THREE.Object3D,因此它具有Object3D的所有属性。主要关注以下几个关键属性:

  • children: 一个数组,包含了场景中的所有子对象,如几何体、相机、光源等。
  • fog: 可选的雾(fog)效果,可以是THREE.FogTHREE.FogExp2的一个实例,影响场景中远处物体的可见性。
  • background: 可以设置为颜色、纹理或渐变,定义场景的背景。

方法

THREE.Scene同样继承了THREE.Object3D的大部分方法,包括但不限于:

  • add(object): 添加一个3D对象到场景的子对象列表中。
  • remove(object): 从场景中移除一个3D对象。
  • getObjectById(id): 根据对象的ID获取对象。
  • getObjectByName(name): 根据对象的名称获取对象。
  • raycast(raycaster, intersects): 用于执行射线投射,用于检测鼠标或触摸事件与场景中对象的交互。
  • traverse(callback): 遍历场景图中的所有子对象,对每个对象执行回调函数。
// 引入Three.js库
import * as THREE from 'three';

// 创建场景
const scene = new THREE.Scene();

// 创建相机
const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
camera.position.set(0, 5, 10);

// 创建渲染器
const renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);

// 加载环境纹理
const environmentTextureLoader = new THREE.TextureLoader();
const environmentMap = environmentTextureLoader.load('path/to/environment_map.jpg');

// 创建立方体
const cubeGeo = new THREE.BoxGeometry(2, 2, 2);
const cubeMat = new THREE.MeshPhongMaterial({
  color: 0x44aa88,
  envMap: environmentMap,
});
const cube = new THREE.Mesh(cubeGeo, cubeMat);
cube.rotation.x = -0.2;
scene.add(cube);

// 创建球体
const sphereGeo = new THREE.SphereGeometry(1, 32, 32);
const sphereMat = new THREE.MeshPhongMaterial({
  color: 0xff8844,
  envMap: environmentMap,
});
const sphere = new THREE.Mesh(sphereGeo, sphereMat);
sphere.position.y = 3;
scene.add(sphere);

// 添加光照
const ambientLight = new THREE.AmbientLight(0x404040); // soft white light
scene.add(ambientLight);

const directionalLight = new THREE.DirectionalLight(0xffffff, 1);
directionalLight.position.set(1, 1, 1).normalize();
scene.add(directionalLight);

const pointLight = new THREE.PointLight(0xff0000, 1, 100);
pointLight.position.set(-10, 20, 15);
scene.add(pointLight);

// 添加雾效果
scene.fog = new THREE.FogExp2(0x000000, 0.002); // black fog with low density

// 渲染循环
function animate() {
  requestAnimationFrame(animate);
  cube.rotation.y += 0.01;
  sphere.rotation.y -= 0.01;
  renderer.render(scene, camera);
}
animate();

代码分析:

  1. 创建了一个场景和相机,相机被放置在一个观察位置。
  2. 设置了一个WebGL渲染器,并将其附加到HTML文档中。
  3. 加载了一个环境纹理,并将其应用到立方体和球体的材质上,这样物体表面会反映出环境的映射。
  4. 创建了两个不同的3D几何体(立方体和球体),并分别设置了材质和位置。
  5. 添加了三种不同类型的光照:环境光(AmbientLight),平行光(DirectionalLight)和点光源(PointLight),以产生不同的光照效果。
  6. 设置了线性雾(FogExp2),当物体远离相机时,它们会逐渐消失在黑色的雾中。

物体

在Three.js中,创建和操作3D物体通常涉及以下几个步骤:创建几何体(Geometry)、定义材质(Material)以及组合这两个元素创建Mesh,然后将其添加到场景(Scene)中。

// 引入Three.js库
import * as THREE from 'three';

// 创建场景
const scene = new THREE.Scene();

// 创建相机
const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
camera.position.z = 5; // 设置相机位置

// 创建渲染器
const renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);

// 创建立方体几何体
const geometry = new THREE.BoxGeometry(1, 1, 1); // 宽度、高度、深度各为1

// 创建红色材质
const material = new THREE.MeshBasicMaterial({ color: 0xff0000 }); // 红色

// 创建Mesh(物体)
const cube = new THREE.Mesh(geometry, material); // 将几何体和材质组合成Mesh

// 将Mesh添加到场景中
scene.add(cube);

// 渲染循环
function animate() {
  requestAnimationFrame(animate);
  renderer.render(scene, camera);
}
animate();

代码分析:

  1. 导入Three.js库:通常通过模块导入,这里使用的是ES模块导入语法。
  2. 创建场景THREE.Scene是所有3D对象的容器。
  3. 创建相机THREE.PerspectiveCamera用于定义视角,参数分别为视角角度、宽高比、近裁剪平面和远裁剪平面。
  4. 创建渲染器THREE.WebGLRenderer负责将3D场景渲染到屏幕,设置渲染器大小并将其附加到HTML文档中。
  5. 创建几何体THREE.BoxGeometry创建一个立方体的形状,参数表示边长。
  6. 创建材质THREE.MeshBasicMaterial是最简单的材质类型,color属性设置为红色(十六进制值0xff0000代表红色)。
  7. 创建MeshTHREE.Mesh是实际的3D物体,由几何体和材质组合而成。
  8. 添加Mesh到场景:将创建的立方体Mesh添加到场景中。
  9. 渲染循环requestAnimationFrame用于创建动画循环,不断调用renderer.render渲染场景和相机视图。

相机

在Three.js中,相机(Camera)是观察3D场景的关键元素。相机定义了用户观察3D世界的视点和视角。

// 创建相机
const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);

// 设置相机位置
camera.position.set(0, 3, 5);

代码分析:

  1. 创建相机:THREE.PerspectiveCamera是Three.js中最常用的相机类型,它模拟人眼的透视视角。构造函数接收四个参数:
  • fov(Field of View):视角,以度数表示。较大的值会显示更广阔的视野,但物体看起来更小;较小的值则相反。
  • aspect:画面宽高比,通常是窗口宽度除以高度。
  • near:近裁剪面,相机能显示的最近距离。
  • far:远裁剪面,相机能显示的最远距离。
  1. 设置相机位置camera.position.set(x, y, z)用于设置相机在3D空间中的位置。在这个例子中,相机位于(0, 3, 5)的位置,这意味着它在X轴的正方向上离原点0单位,Y轴上3单位,Z轴上5单位。这个位置通常根据场景的需求进行调整,以达到理想的观察效果。

相机的其他重要属性和方法包括:

  • .lookAt():使相机朝向特定的目标点。
  • .rotateOnAxis().rotateX(), .rotateY(), .rotateZ():用于旋转相机。
  • .zoom:控制相机的焦距,影响视角的宽窄。

渲染器

在Three.js中,渲染器(Renderer)是将3D场景转换为2D图像显示在屏幕上的关键组件。以下是创建和配置渲染器的典型代码,以及对其关键部分的解析:

// 创建渲染器
const renderer = new THREE.WebGLRenderer({
  antialias: true, // 反锯齿
});

// 设置渲染器尺寸
renderer.setSize(window.innerWidth, window.innerHeight);

// 将渲染器的canvas元素添加到HTML文档中
document.body.appendChild(renderer.domElement);

代码解析:

  • 创建渲染器:THREE.WebGLRenderer是Three.js的主要渲染器,它利用WebGL API在浏览器中绘制3D图形。构造函数可以接受一个配置对象作为参数,其中antialias是可选的,设置为true开启反锯齿,以获得更平滑的边缘。
  • 设置渲染器尺寸:setSize(width, height)方法用于设置渲染器输出的canvas元素的宽度和高度。通常我们会将其设置为浏览器窗口的宽度和高度,以确保全屏显示。
  • 添加到文档:renderer.domElement返回渲染器生成的canvas元素,将其添加到HTML文档的body元素中,这样渲染器就可以开始工作并显示3D场景。

除了上述基本配置,渲染器还可以进行其他高级设置,例如:

  • 颜色清除:renderer.clearColor(color, alpha)可以设置背景颜色和透明度。
  • 阴影支持:renderer.shadowMap.enabled = true开启阴影支持。
  • 线框模式:renderer_wireframe = true可以切换到线框模式,显示模型的轮廓。
  • 性能优化:renderer.sortObjects = false关闭对象排序,可能会提高渲染速度,但可能导致某些效果不正确。

在渲染循环中,renderer.render(scene, camera)是实际进行渲染的命令,它将当前场景和相机视图呈现到canvas上。例如:

function animate() {
  requestAnimationFrame(animate);
  // 更新物体、动画等...
  renderer.render(scene, camera);
}
animate();

这个animate函数会每帧调用一次,确保连续渲染3D场景。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2170325.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

OJ在线评测系统 原生Java代码沙箱核心实现流程三 整理封装输出结果 拿到程序执行时间(stopwatch类) 和 运行内存

我们在之前的操作中已经拿到程序进行了编译和运行 接下来我们要将我们的结果输出 整理输出 // 4.收集整理输出结果 ExecuteCodeResponse executeCodeResponse new ExecuteCodeResponse(); ArrayList<String> outputList new ArrayList<>();for (ExecuteMessage…

Library介绍(一)

之前和大家介绍过cell delay是如何计算的。那么&#xff0c;本文将着重和大家介绍一些timing lib中的各个参数定义是什么意思。会分以下几个部分介绍&#xff1a;库属性描述、时序弧介绍、环境描述、单元描述。之前介绍的cell delay template就是单元描述中的一部分。本文主要介…

网络安全入门必备:这四点你做到了吗?

数据的鸿沟无疑是显而易见的&#xff0c;网络安全领域亟需熟练的专业人员。 组织在这方面投入巨大资金&#xff0c;但挑战依旧存在。 根据最新的研究&#xff0c;有64%的违规行为是导致机构过去一年收入损失及/或罚款的主要原因。 60%的组织在努力招聘网络安全人才&#xff…

【市场解读】新能源汽车换代问题

参考文献&#xff1a;百分点舆情中心《新能源汽车换代问题消费者情绪洞察报告》 行业背景 新能源汽车市场竞争加剧&#xff0c;车企不断推陈出新政府发布《汽车以旧换新补贴实施细则》&#xff0c;激励市场发展 *对汽车换代问题媒体关注度与网友讨论度高&#xff0c;正面声量…

电脑退域后系统黑屏

之前加入域时迁移了账号系统&#xff0c;导致退域后本地账号系统没了东西黑屏但能看到鼠标。也登不了域账号了一顿慌张&#xff08;操作如下&#xff09; 解决&#xff1a;又加回了域哈哈哈 重启电脑按F8进不去安全模式&#xff0c;找不到触发时间... winr打开运行&#xff0c;…

都说网络安全缺口那么大,但为何招聘数量却不多?总算明白了!

为啥网安领域缺口多达300多万人&#xff0c;但网安工程师也就是白帽黑客却很少&#xff0c;难道又是砖家在忽悠人&#xff1f; 原因主要为这三点: 首先是学校的原因&#xff0c;很多学校网络安全课程用的还都是十年前的老教材&#xff0c;教学脱离社会需求&#xff0c;实操技能…

【Python报错已解决】TypeError: expected Tensor as element 1 in argument 0, but got int

&#x1f3ac; 鸽芷咕&#xff1a;个人主页 &#x1f525; 个人专栏: 《C干货基地》《粉丝福利》 ⛺️生活的理想&#xff0c;就是为了理想的生活! 专栏介绍 在软件开发和日常使用中&#xff0c;BUG是不可避免的。本专栏致力于为广大开发者和技术爱好者提供一个关于BUG解决的经…

NHANES数据(复杂调查数据)亚组交互函数2.3版(P for interaction)发布---用于一键生成交互效应表

写在前面的话&#xff0c;本函数只支持NHANES数据(复杂调查数据)的逻辑回归和线性回归&#xff0c;其他类型均不支持&#xff0c;请注意甄别&#xff0c;电子产品&#xff0c;买错不能退换。 在SCI文章中&#xff0c;交互效应表格&#xff08;通常是表五&#xff09;能为文章锦…

多类别物体检测系统源码分享

多类别物体检测检测系统源码分享 [一条龙教学YOLOV8标注好的数据集一键训练_70全套改进创新点发刊_Web前端展示] 1.研究背景与意义 项目参考AAAI Association for the Advancement of Artificial Intelligence 项目来源AACV Association for the Advancement of Computer V…

“领航猿1号” 正式更名为 “AGI舰长”

亲爱的朋友们&#xff0c;很高兴的告诉大家&#xff1a; 我各个平台的账号昵称正式 由“领航猿1号” 更名为 “AGI舰长” 为什么更名&#xff1a; 为了更好的更专注的为大家提供关于“AI大模型全栈”的分享&#xff0c;特此以 AI 为关键元素更名账号名称&#xff0c;大家可以…

企业内网知识问答库小程序源码系统 收录好+排名高 带完整的安装代码包以及搭建部署教程

系统概述 企业内网知识问答库小程序源码系统是一款集知识收集、整理、检索与分享于一体的综合解决方案。它基于现代Web技术和小程序框架开发&#xff0c;旨在为企业内部员工提供一个便捷、高效的知识交流平台。该系统不仅支持文本、图片、视频等多种形式的内容输入&#xff0c…

国际版短剧系统开发,海外多语言切换短剧APP源码部署上架

一、背景与需求 1. 背景介绍 随着全球化进程的加速和移动互联网的普及&#xff0c;短剧作为一种新型娱乐形式在全球范围内迅速走红。海外短剧系统是针对这一市场需求而开发的&#xff0c;旨在为全球观众提供高质量的短剧内容&#xff0c;并通过多样化的平台和服务&#xff0c…

禁止吸烟监测系统 基于图像处理的吸烟检测系统 YOLOv7

吸烟是引发火灾的重要原因之一。烟头在未熄灭的情况下&#xff0c;其表面温度可达200℃-300℃&#xff0c;中心温度甚至能高达700℃-800℃。在易燃、易爆的生产环境中&#xff0c;如化工厂、加油站、仓库等&#xff0c;一个小小的烟头就可能引发灾难性的火灾&#xff0c;造成巨…

【前端样式】Sweetalert2简单用法

1、 先安装sweetalert2库&#xff1a; npm install sweetalert2 2、引用SweetAlert2 库&#xff1a; import Swal from sweetalert2 &#xff1b; 3、代码拷过去直接去测试&#xff0c;vue代码 <template><div><el-button style"color: #C03639" clic…

【计算机网络 - 基础问题】每日 3 题(二十八)

✍个人博客&#xff1a;Pandaconda-CSDN博客 &#x1f4e3;专栏地址&#xff1a;http://t.csdnimg.cn/fYaBd &#x1f4da;专栏简介&#xff1a;在这个专栏中&#xff0c;我将会分享 C 面试中常见的面试题给大家~ ❤️如果有收获的话&#xff0c;欢迎点赞&#x1f44d;收藏&…

Kafka学习笔记(一)Linux环境基于Zookeeper搭建Kafka集群、Kafka的架构

文章目录 1 Kafka简介1.1 什么是Kafka1.2 Kafka的应用场景1.3 Kafka的优势 2 搭建Kafka集群2.1 搭建Zookeeper集群2.1.1 上传并解压安装包2.1.2 修改配置文件2.2.3 创建dataDir和myid文件2.2.4 分发到另外两个节点2.2.5 修改node-02节点、node-03节点的配置文件和myid文件2.2.6…

【原创教程】西门子_部件手动模式FB块编辑

1、软件配置 ①软件配置 名称 版本 博图 V16 2、建立FB块 在编辑手动程序前应该建立手动程序的FB块&#xff0c;FB块的建立内容如下图所示 ①FB块的输入接口 Input:FB块的输入接口&#xff0c;将下拉列表中的数据应用于该FB块所编辑的程序中。 NO&#xff1a;当前部件…

数据科学 - 字符文本处理

1. 字符串的基本操作 1.1 结构操作 1.1.1 拼接 • 字符串之间拼接 字符串之间的拼接使用进行字符串的拼接 a World b Hello print(b a) • 列表中的字符串拼接 将以分隔符‘,’为例子 str [apple,banana] print(,.join(str)); • 字符串中选择 通过索引进行切片操…

一个 Java 语言简化处理 PDF 的框架,提供了一套简单易用的 API 接口,满足多样化需求又能简化开发流程的处理方案(附教程)

前言 当前市面上处理 PDF 文件的工具众多&#xff0c;但它们往往存在一定的局限性&#xff0c;比如复杂交互、功能单一等问题。尤其对于那些需要频繁生成或编辑 PDF 文档的应用场景来说&#xff0c;找到一个既能满足多样化需求又能简化开发流程的处理方案显得尤为重要。那么&a…

思想和认知,从身边的事情和从小经历就在培养。谁在起跑线!

世界地图就像一张藏宝图&#xff0c;有的地方有宝藏&#xff0c;有的地方物资匮乏。当你拼命努力却一直挖不到宝藏的时候&#xff0c;不妨换个位置挖掘。如果你运气好&#xff0c;很可能就挖到一堆金子直接实现财富自由。运气不好&#xff0c;也能轻松过上小康生活。财富和位置…