ThreeJS基础知识

26 阅读5分钟

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.FrontSideThree.DoubleSideThree.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 应用。