Three.js 入门教程:从零构建 3D 场景
一、背景与概念
为什么需要 Three.js?
原生 WebGL API 极其冗长——仅画一个三角形就需要上百行代码。Three.js 对 WebGL 进行了优雅的抽象,让开发者能用面向对象的方式构建 3D 场景。它是目前 GitHub 上 Star 最多的 3D Web 库(100k+ stars),被广泛应用于产品展示、数据可视化、游戏和 AR/VR。
核心概念
Three.js 的世界观类似拍电影:
| 概念 |
类比 |
说明 |
| Scene(场景) |
舞台 |
容纳所有 3D 对象的容器 |
| Camera(相机) |
摄像机 |
决定观众看到什么,常用 PerspectiveCamera |
| Renderer(渲染器) |
放映机 |
将场景通过相机渲染到 Canvas |
| Mesh(网格) |
演员 |
由 Geometry(形状)+ Material(材质)组成 |
| Light(光源) |
灯光 |
没有光就看不到任何东西 |
| Animation Loop |
播放 |
每帧更新场景并重新渲染 |
二、分步操作
第一步:搭建项目骨架
使用 Vite 快速启动:
npm create vite@latest my-three-app -- --template vanilla
cd my-three-app
npm install three
npm run dev
在 main.js 中构建最小场景:
import * as THREE from 'three';
const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(75, innerWidth / innerHeight, 0.1, 1000);
const renderer = new THREE.WebGLRenderer();
renderer.setSize(innerWidth, innerHeight);
document.body.appendChild(renderer.domElement);
第二步:添加第一个物体
const geometry = new THREE.BoxGeometry(1, 1, 1);
const material = new THREE.MeshPhongMaterial({ color: 0xff6600 });
const cube = new THREE.Mesh(geometry, material);
scene.add(cube);
const light = new THREE.DirectionalLight(0xffffff, 1);
light.position.set(2, 2, 5);
scene.add(light);
camera.position.z = 3;
第三步:渲染循环
function animate() {
requestAnimationFrame(animate); // 请求下一帧
cube.rotation.x += 0.01;
cube.rotation.y += 0.01;
renderer.render(scene, camera);
}
animate();
第四步:丰富场景
添加多个物体和辅助工具:
scene.add(new THREE.AxesHelper(3));
const grid = new THREE.GridHelper(10, 10);
scene.add(grid);
const sphere = new THREE.Mesh(
new THREE.SphereGeometry(0.5, 32, 32),
new THREE.MeshStandardMaterial({ color: 0x4488ff, roughness: 0.2, metalness: 0.8 })
);
sphere.position.x = -2;
scene.add(sphere);
第五步:响应用户交互
import { OrbitControls } from 'three/addons/controls/OrbitControls.js';
const controls = new OrbitControls(camera, renderer.domElement);
controls.enableDamping = true; // 开启惯性
controls.dampingFactor = 0.05;
function animate() {
requestAnimationFrame(animate);
controls.update(); // 必须在 render 前更新
renderer.render(scene, camera);
}
三、常用 Geometry 速查
| Geometry |
用途 |
BoxGeometry(w, h, d) |
立方体/盒子 |
SphereGeometry(r, segW, segH) |
球体 |
CylinderGeometry(rT, rB, h, seg) |
圆柱/圆锥 |
PlaneGeometry(w, h) |
平面 |
TorusGeometry(r, tube, radSeg, tubSeg) |
圆环 |
BufferGeometry |
自定义几何体(高性能) |
四、常用 Material 速查
| Material |
特性 |
需要光照 |
MeshBasicMaterial |
不受光影响,纯色 |
否 |
MeshStandardMaterial |
PBR 物理渲染(推荐) |
是 |
MeshPhongMaterial |
经典 Blinn-Phong 光照 |
是 |
MeshNormalMaterial |
法线可视化(调试用) |
否 |
MeshToonMaterial |
卡通风格 |
是 |
五、思考题
- 如何让立方体沿着圆形轨迹运动?(提示:用三角函数修改 position 而非 rotation)
renderer.setPixelRatio 设为 devicePixelRatio 的作用是什么?何时应降低它?
- 如果场景中有 10000 个立方体,如何优化性能?(提示:InstancedMesh)
Three.js 3D可视化毕设入门
背景
Three.js 是浏览器端 3D 渲染的事实标准。毕设中如果能加入 3D 元素——产品 3D 展示、校园导览、数据可视化地球、虚拟展厅——会立刻让项目档次提升。Three.js 屏蔽了 WebGL 的复杂性,前端开发者无需学 OpenGL 也能做 3D。
核心概念
三要素
Scene (场景) → 容納所有 3D 物体
Camera (相机) → 观察视角
Renderer (渲染器) → 绘制到屏幕
const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(75, w/h, 0.1, 1000);
const renderer = new THREE.WebGLRenderer();
function animate() {
requestAnimationFrame(animate);
renderer.render(scene, camera);
}
animate();
四大组件
| 组件 |
说明 |
示例 |
| Geometry |
形状 |
Box, Sphere, Cylinder, BufferGeometry |
| Material |
材质 |
MeshBasic, MeshPhong, MeshStandard |
| Light |
光照 |
Ambient, Directional, Point, Spot |
| Controls |
交互 |
OrbitControls, FlyControls |
分步操作
第一步:引入 Three.js
npm install three
import * as THREE from 'three';
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js';
第二步:创建第一个立方体
const geometry = new THREE.BoxGeometry(1, 1, 1);
const material = new THREE.MeshPhongMaterial({ color: 0x3b82f6 });
const cube = new THREE.Mesh(geometry, material);
scene.add(cube);
scene.add(new THREE.AmbientLight(0x404040));
const light = new THREE.DirectionalLight(0xffffff, 1);
light.position.set(5, 5, 5);
scene.add(light);
第三步:添加交互
const controls = new OrbitControls(camera, renderer.domElement);
controls.enableDamping = true;
controls.autoRotate = true;
第四步:加载 3D 模型
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js';
const loader = new GLTFLoader();
loader.load('/models/building.glb', (gltf) => {
scene.add(gltf.scene);
});
毕设推荐场景
校园 3D 导览
Blender 建模校园建筑 → glTF 导出 → Three.js 加载 → OrbitControls 漫游。
产品 3D 展示
商品 360 度旋转查看,支持缩放和材质切换。
数据可视化
3D 柱状图、3D 地图、3D 粒子效果。
虚拟展厅
COVID 期间流行的线上展厅,三维空间展示作品。
思考题
- PerspectiveCamera 和 OrthographicCamera 的区别?各自适用场景?
- 为什么需要光照?MeshBasicMaterial 和 MeshStandardMaterial 的区别?
- 加载大型 3D 模型时如何优化性能?
小结
Three.js 是毕设的"视觉杀手锏"。一个带 3D 元素的毕设项目,在答辩演示时视觉冲击力远超传统 2D 页面。