Three.js 基础知识
Three.js 是一个功能强大的 JavaScript 库,用于在 Web 浏览器中创建和渲染 3D 场景。本文档系统整理了 Three.js 的核心知识点,涵盖场景创建、几何体与材质、相机、渲染、光源、GUI 控件以及辅助工具,旨在帮助开发者快速上手并构建交互式 3D 应用。内容结构清晰,包含代码示例,便于学习和实践。
一、创建 3D 场景
1. 创建三维场景
场景是 Three.js 的核心容器,用于存放物体、光源和相机等。
const scene = new Three.Scene();
2. 物体形状 (Geometry)
几何体定义了物体的形状,Three.js 提供了多种内置几何体,满足不同需求:
- BoxGeometry:长方体
- CapsuleGeometry:胶囊体
- CircleGeometry:圆形平面
- ConeGeometry:圆锥体
- CylinderGeometry:圆柱体
- DodecahedronGeometry:十二面体
- EdgesGeometry:边缘几何体(辅助查看)
- ExtrudeGeometry:拉伸几何体
- IcosahedronGeometry:二十面体
- LatheGeometry:柱面几何体
- OctahedronGeometry:八面体
- PlaneGeometry:平面
- PolyhedronGeometry:多面体
- RingGeometry:圆环
- ShapeGeometry:自定义形状缓冲
- SphereGeometry:球体
- TetrahedronGeometry:四面体
- TorusGeometry:圆环
- TorusKnotGeometry:螺旋
- TubeGeometry:管道
- WireframeGeometry:三维线框
示例:创建一个立方体几何体:
const geometry = new Three.BoxGeometry(1, 1, 1);
3. 物体材质 (Material)
材质决定物体的外观和光照效果。常用材质包括:
- LineBasicMaterial:基础线条材质
- LineDashedMaterial:虚线材质
- MeshBasicMaterial:基础材质,不受光照影响
- MeshDepthMaterial:深度材质
- MeshDistanceMaterial:距离材质
- MeshLambertMaterial:Lambert 材质,适合非光泽表面
- MeshMatcapMaterial:Matcap 材质
- MeshNormalMaterial:法线材质
- MeshPhongMaterial:Phong 材质,支持高光
- MeshPhysicalMaterial:物理材质,高级光照效果
- MeshStandardMaterial:标准材质,基于物理渲染
- MeshToonMaterial:卡通风格材质
- PointsMaterial:点材质
材质属性:
color
:颜色(例如0xff0000
表示红色)map
:贴图transparent
:是否开启透明(true
/false
)side
:可见面(Three.FrontSide
、Three.DoubleSide
、Three.BackSide
)shininess
:高光亮度(默认 30)specular
:高光颜色
示例:创建带颜色的标准材质:
const material = new Three.MeshStandardMaterial({
color: 0xff0000,
side: Three.DoubleSide,
shininess: 50,
});
4. 创建物体
物体由几何体和材质组合而成,常用类型包括:
- Mesh:网格模型
- Points:点模型
- Line:线模型
- LineSegments:线段模型
- LineLoop:闭合线条模型
- Sphere:球模型
- Cone:圆锥模型
- Cylinder:圆柱模型
- Torus:圆环模型
示例:创建并添加立方体到场景:
const mesh = new Three.Mesh(geometry, material);
scene.add(mesh);
5. 调整模型位置
通过以下属性调整物体的位置、旋转和缩放:
position
:位置(x, y, z
)rotation
:旋转(弧度制)scale
:缩放
示例:
mesh.position.set(0, 1, 0); // 设置位置
mesh.rotation.set(Math.PI / 4, 0, 0); // 绕 X 轴旋转 45 度
mesh.scale.set(2, 2, 2); // 放大 2 倍
6. 添加至场景
将物体、光源等添加到场景中:
scene.add(mesh);
二、透视投影相机
1. 创建透视相机
透视相机模拟人眼视角,参数包括:
fov
:视野角度(度)aspect
:画布宽高比(通常为窗口宽高比)near
:近平面距离far
:远平面距离
示例:
const camera = new Three.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
2. 设置相机位置
调整相机在场景中的位置:
camera.position.set(0, 0, 5); // 相机位于 z=5
3. 设置观察目标
指定相机观察的点:
camera.lookAt(new Three.Vector3(0, 0, 0)); // 看向场景原点
4. 更新宽高比
当窗口大小变化时,更新相机宽高比并重新计算投影矩阵:
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
三、渲染
1. 创建渲染器
使用 WebGL 渲染器渲染场景:
const renderer = new Three.WebGLRenderer({ antialias: true });
2. 设置渲染器属性
配置渲染器的尺寸、像素比和背景颜色:
renderer.setSize(window.innerWidth, window.innerHeight); // 设置画布尺寸
renderer.setPixelRatio(window.devicePixelRatio); // 适配高分辨率屏幕
renderer.setClearColor(0x000000, 1); // 设置背景颜色(黑色,不透明)
3. 添加渲染器到 DOM
将渲染器画布添加到页面:
document.body.appendChild(renderer.domElement);
4. 渲染场景
执行单次渲染:
renderer.render(scene, camera);
5. 动画循环
使用 requestAnimationFrame
实现实时渲染:
function animate() {
renderer.render(scene, camera);
requestAnimationFrame(animate);
}
animate();
渲染器属性:
antialias
:开启抗锯齿setPixelRatio
:设置设备像素比setClearColor
:设置背景颜色setClearAlpha
:设置背景透明度setSize
:设置渲染尺寸domElement
:渲染器画布元素dispose
:销毁渲染器setAnimationLoop
:设置自定义动画循环
四、光源
光源为场景提供照明,影响物体的明暗效果。常用光源包括:
- AmbientLight:环境光,均匀照亮场景
- PointLight:点光源,类似灯泡(可用
PointLightHelper
可视化) - SpotLight:聚光灯,类似手电筒
- DirectionalLight:平行光,类似太阳光(可用
DirectionalLightHelper
可视化)
1. 添加光源
创建光源并设置颜色和强度:
const ambientLight = new Three.AmbientLight(0xffffff, 0.5); // 白色环境光,强度 0.5
scene.add(ambientLight);
const pointLight = new Three.PointLight(0xffffff, 1); // 白色点光源,强度 1
pointLight.position.set(5, 5, 5);
scene.add(pointLight);
2. 调整光源属性
- 强度:
light.intensity = 1;
- 衰减:
light.decay = 0;
(默认 2,0 表示不衰减) - 位置:
light.position.set(x, y, z);
五、GUI 控件
使用 dat.GUI
库创建交互式界面,方便调试和调整参数。
1. 创建 GUI 对象
const gui = new dat.GUI();
2. 添加控件
通过 add
方法添加可调节的参数,支持数字、布尔值、数组和对象。
示例:控制物体颜色和旋转速度:
const params = { color: '#ff0000', rotationSpeed: 0.01 };
gui.addColor(params, 'color').name('颜色').onChange((value) => {
mesh.material.color.set(value);
});
gui.add(params, 'rotationSpeed', 0, 0.1, 0.01).name('旋转速度');
- 参数类型:
- 数字:生成拖动条(指定
min
,max
,step
) - 数组:生成下拉选择框
- 对象:生成标签选择框
- 布尔值:生成单选框
- 数字:生成拖动条(指定
3. 设置控件属性
- 名称:
gui.add().name('自定义名称');
- 步长:
gui.add().step(0.1);
- 回调:
gui.add().onChange((value) => { /* 响应变化 */ });
4. 添加文件夹
使用 addFolder
组织控件,保持界面整洁:
const folder = gui.addFolder('位置');
folder.add(mesh.position, 'x', -10, 10, 0.1).name('X 轴');
folder.add(mesh.position, 'y', -10, 10, 0.1).name('Y 轴');
folder.add(mesh.position, 'z', -10, 10, 0.1).name('Z 轴');
六、其他辅助工具
1. 添加坐标轴
坐标轴辅助线帮助调试场景中的方向和位置:
const axesHelper = new Three.AxesHelper(300); // 坐标轴长度 300
scene.add(axesHelper);
2. 添加网格辅助线
网格平面便于观察空间关系:
const gridHelper = new Three.GridHelper(200, 50); // 网格大小 200,50 个格子
scene.add(gridHelper);
3. 循环渲染
通过动画循环实现动态更新:
function animate() {
mesh.rotation.y += params.rotationSpeed; // 根据 GUI 参数旋转
renderer.render(scene, camera);
requestAnimationFrame(animate);
}
animate();
七、总结
本文档全面介绍了 Three.js 的基础知识,包括场景构建、几何体与材质、相机设置、渲染、光源、GUI 控件和辅助工具。开发者可通过以上内容快速搭建 3D 场景,并结合 dat.GUI
实现交互式调试。建议在实践中结合官方文档和示例,深入探索 Three.js 的高级功能,如动画、纹理、着色器等,以创建更复杂的 3D 应用。