目录
- 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.Fog
或THREE.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();
代码分析:
- 创建了一个场景和相机,相机被放置在一个观察位置。
- 设置了一个WebGL渲染器,并将其附加到HTML文档中。
- 加载了一个环境纹理,并将其应用到立方体和球体的材质上,这样物体表面会反映出环境的映射。
- 创建了两个不同的3D几何体(立方体和球体),并分别设置了材质和位置。
- 添加了三种不同类型的光照:环境光(AmbientLight),平行光(DirectionalLight)和点光源(PointLight),以产生不同的光照效果。
- 设置了线性雾(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();
代码分析:
- 导入Three.js库:通常通过模块导入,这里使用的是ES模块导入语法。
- 创建场景:
THREE.Scene
是所有3D对象的容器。 - 创建相机:
THREE.PerspectiveCamera
用于定义视角,参数分别为视角角度、宽高比、近裁剪平面和远裁剪平面。 - 创建渲染器:
THREE.WebGLRenderer
负责将3D场景渲染到屏幕,设置渲染器大小并将其附加到HTML文档中。 - 创建几何体:
THREE.BoxGeometry
创建一个立方体的形状,参数表示边长。 - 创建材质:
THREE.MeshBasicMaterial
是最简单的材质类型,color属性设置为红色(十六进制值0xff0000代表红色)。 - 创建Mesh:
THREE.Mesh
是实际的3D物体,由几何体和材质组合而成。 - 添加Mesh到场景:将创建的立方体Mesh添加到场景中。
- 渲染循环:
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);
代码分析:
- 创建相机:THREE.PerspectiveCamera是Three.js中最常用的相机类型,它模拟人眼的透视视角。构造函数接收四个参数:
fov
(Field of View):视角,以度数表示。较大的值会显示更广阔的视野,但物体看起来更小;较小的值则相反。aspect
:画面宽高比,通常是窗口宽度除以高度。near
:近裁剪面,相机能显示的最近距离。far
:远裁剪面,相机能显示的最远距离。
- 设置相机位置:
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场景。