浏览器早已不只用来展示文字、图片和表单。产品展示、数据可视化、互动叙事、数字孪生、在线展厅,甚至轻量游戏与 XR 体验,都可以直接运行在网页里。

问题是,原生 WebGL 很强,却不算友好。你需要自己处理着色器、缓冲区、矩阵、纹理和渲染状态。three.js 做的事情,就是在这些底层能力之上提供一套更符合 JavaScript 开发习惯的 3D 抽象。

截至 2026 年 7 月 29 日,three.js 在 GitHub 已获得约 11.4 万 Star,NPM 当前版本为 0.185.1;NPM 统计的最近一个月下载量约 4952 万次。它不是突然走红的新项目,而是一套从 2010 年持续演进至今的 Web 3D 基础设施。

three.js 是什么?

three.js 是由 mrdoob 发起并由社区长期维护的 JavaScript 3D 库,采用 MIT 许可证。

项目地址:https://github.com/mrdoob/three.js

官方网站:https://threejs.org/

官方对它的定位很克制:易于使用、轻量、跨浏览器、通用的 3D 库。当前核心构建提供 WebGL 与 WebGPU 渲染器,SVG、CSS3D 等能力则以扩展形式存在。

three.js 不会替你决定作品应该长什么样,也不是一套包含关卡、物理、联网和资产管线的完整游戏引擎。它更像一个组织良好的 3D 工具箱:把浏览器图形 API 中高频而复杂的部分封装起来,同时保留足够多的底层控制能力。

先理解六个核心对象

第一次接触 three.js,最重要的不是背 API,而是理解一次渲染由哪些对象协作完成。

1. Scene:场景

Scene 是 3D 世界的根容器。模型、灯光、相机辅助器和分组对象都可以加入场景,并以树状结构组织。

2. Camera:相机

相机决定从哪里、以什么投影方式观察场景。最常见的是 PerspectiveCamera,适合模拟人眼透视;OrthographicCamera 没有近大远小的效果,更适合工程视图、地图和部分数据可视化。

3. Renderer:渲染器

渲染器把场景与相机转换成浏览器中的像素。大多数项目仍从 WebGLRenderer 开始;面向新图形能力的项目也可以评估 WebGPU 渲染路径。

4. Geometry:几何体

几何体描述顶点、法线、UV 等数据。three.js 自带立方体、球体、平面、圆环等基础几何,也可以通过加载器读取外部模型。

5. Material:材质

材质决定表面如何响应光照、纹理和视角。MeshBasicMaterial 不受灯光影响,适合简单展示;MeshStandardMaterial 基于 PBR 思路,更适合常见产品与写实场景。

6. Mesh:网格对象

Mesh 将几何体与材质组合成一个可放入场景的对象。它拥有位置、旋转和缩放,也可以成为其他对象的父节点。

用一句话概括就是:把 Geometry 与 Material 组合成 Mesh,加入 Scene,再由 Camera 和 Renderer 完成绘制。

最小上手:做一个可旋转的 3D 物体

官方推荐使用 NPM 与构建工具管理项目。下面用 Vite 创建一个最小示例:

1
2
3
4
5
npm create vite@latest three-demo -- --template vanilla
cd three-demo
npm install
npm install three
npm run dev

src/style.css 改成:

1
2
3
4
5
6
7
8
9
10
11
html,
body {
width: 100%;
height: 100%;
margin: 0;
overflow: hidden;
}

canvas {
display: block;
}

再将 src/main.js 改成下面这段代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
import * as THREE from 'three';
import { OrbitControls } from 'three/addons/controls/OrbitControls.js';
import './style.css';

const scene = new THREE.Scene();
scene.background = new THREE.Color(0xf4f5f7);

const camera = new THREE.PerspectiveCamera(
55,
window.innerWidth / window.innerHeight,
0.1,
100
);
camera.position.set(0, 1.2, 4);

const renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2));
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);

const geometry = new THREE.TorusKnotGeometry(0.8, 0.28, 160, 24);
const material = new THREE.MeshStandardMaterial({
color: 0x19b978,
metalness: 0.25,
roughness: 0.35
});
const mesh = new THREE.Mesh(geometry, material);
scene.add(mesh);

const keyLight = new THREE.DirectionalLight(0xffffff, 3);
keyLight.position.set(3, 4, 5);
scene.add(keyLight);
scene.add(new THREE.HemisphereLight(0xffffff, 0x334455, 1.2));

const controls = new OrbitControls(camera, renderer.domElement);
controls.enableDamping = true;

renderer.setAnimationLoop(() => {
mesh.rotation.y += 0.003;
controls.update();
renderer.render(scene, camera);
});

window.addEventListener('resize', () => {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
});

这段代码已经覆盖了 three.js 的基本闭环:创建场景、相机和渲染器,组合几何体与材质,加入灯光和交互控制,然后在动画循环中绘制。

three.js 能做什么?

1. 3D 产品展示与配置器

汽车、家具、鞋服和电子产品可以在网页中被旋转、缩放、拆解,并实时切换颜色、材质和部件。配合 glTF/GLB 模型、环境贴图和后期处理,可以做出很成熟的在线展示体验。

2. 数据可视化

地理空间、网络拓扑、粒子系统和大规模时序数据,可以用深度、空间与动画表达。three.js 提供场景管理和渲染基础,但信息层级与交互设计仍需要开发者自己完成。

3. 互动官网与数字叙事

滚动驱动镜头、3D 字体、粒子转场和沉浸式场景,是品牌官网与数字展览中的常见用法。three.js 可以与普通 DOM、音频和动画库协同,而不要求整页都变成 3D。

4. 游戏与互动体验

它足以支撑很多轻量网页游戏、物理实验和多人互动场景。不过物理、寻路、状态同步、编辑器和关卡系统通常需要自己实现或引入其他库。

5. WebXR、AR 与 VR

three.js 提供 WebXR 相关能力,可以连接支持的浏览器与设备。真正上线时仍要考虑设备能力、输入方式、帧率和浏览器兼容性。

为什么它长期保持影响力?

把底层图形 API 变成对象模型

原生 WebGL 更接近图形编程接口,而 three.js 提供了场景树、相机、材质、灯光、加载器和动画系统。开发者可以先完成作品,再逐步深入着色器与渲染细节。

示例库本身就是重要文档

three.js 官方示例覆盖模型加载、材质、后处理、粒子、阴影、动画、WebXR 和 WebGPU 等大量方向。遇到具体需求时,从相近示例反向阅读 API,通常比从头通读文档更有效。

生态足够成熟

官方 addons 中已经包含 OrbitControlsGLTFLoader、后期处理等常用模块。React 项目还可以使用 React Three Fiber 与 Drei,用组件和 Hooks 组织场景;但它们最终仍建立在 three.js 的对象与渲染能力之上。

抽象层级比较平衡

three.js 比原生 WebGL 更易用,又比完整游戏引擎更开放。对于需要把 3D 深度嵌入网页交互、产品界面或数据系统的团队,这个位置非常合适。

WebGL 与 WebGPU 应该怎么选?

three.js 当前同时推进 WebGL 与 WebGPU。WebGPU 提供更现代的 GPU 接口和计算能力,但浏览器、设备、第三方扩展和现有代码的成熟度并不完全一致。

对大多数需要广泛兼容的项目,WebGLRenderer 仍是稳妥起点。只有当项目确实需要 WebGPU 特性,并能控制目标浏览器与设备范围时,再评估 WebGPURenderer 和 TSL 等新路径。

技术选型不必追求标签更新。能在目标设备上稳定运行、拥有清楚的降级策略,比单纯使用更新的渲染 API 更重要。

做生产项目时最容易忽略的性能问题

控制 Draw Call

大量独立 Mesh 会带来大量绘制调用。重复对象优先考虑 InstancedMesh,静态物体可以按材质与空间关系合理合并。

管理模型与纹理体积

网页 3D 的第一道瓶颈往往不是 GPU,而是下载与解析。模型通常优先选择 glTF/GLB,并按实际画面需要控制面数、纹理分辨率和压缩格式。

不要无条件追求最高像素比

高 DPR 手机的渲染成本可能迅速增加。使用 Math.min(window.devicePixelRatio, 2) 之类的上限,是常见的质量与性能折中。

及时释放 GPU 资源

在单页应用中切换页面或场景时,应对不再使用的 Geometry、Material、Texture 和 Render Target 调用 dispose()。只从场景树移除对象,并不会自动释放对应 GPU 资源。

用真实设备检查

桌面开发机上的流畅并不能代表移动端。应该持续观察加载时间、帧率、显存占用、发热与交互响应,并为弱设备准备更低的模型和效果等级。

使用前需要知道的边界

  • three.js 是 3D 渲染库,不是开箱即用的完整游戏引擎
  • 物理、联网、关卡编辑和复杂 UI 通常需要其他工具配合
  • 高质量效果仍依赖建模、材质、灯光、动画与美术设计
  • 3D 页面需要认真处理加载进度、失败状态和移动端性能
  • 项目保持较快发布节奏,升级前应阅读 Migration Guide
  • 无障碍与 SEO 不能只依赖 Canvas,关键信息仍应有 HTML 表达

最后一点尤其重要。3D 应该服务内容和交互,而不是把本来简单的页面变得难用。产品、运营和工具类网站只在真正需要空间表达时使用 3D,通常会得到更好的结果。

适合哪些人?

  • 想进入 Web 3D、WebGL 或 WebGPU 的前端开发者
  • 要做 3D 产品展示、数字展厅和互动官网的团队
  • 需要地理空间、科学或网络数据可视化的人
  • 想在 React、Vue 等现有 Web 项目中嵌入 3D 的开发者
  • 希望从场景搭建逐步深入 Shader 与图形学的人

如果你的目标是大型商业游戏,并且强依赖完整编辑器、物理、动画状态机和跨平台发布,Unity、Godot 或 Unreal Engine 可能更匹配;如果目标是让 3D 自然地成为网页的一部分,three.js 仍然是最值得先掌握的工具之一。

我的评价

three.js 的价值,不只是“让网页能显示一个旋转立方体”。它真正降低的是浏览器 3D 的组织成本:你可以用一套稳定的对象模型管理场景、资产、材质、动画和渲染,再根据项目需要深入底层。

十多年持续维护、超过 11 万 GitHub Star 和每月数千万次 NPM 下载,说明它已经不是一个小众视觉库,而是 Web 3D 生态的重要公共层。

对于初学者,最好的起点仍然很简单:先跑通一个场景,再加载一个真实模型,随后加入交互和性能监控。不要急着追求复杂特效。只要把场景、相机、渲染器、几何体、材质和 Mesh 这条主线真正理解,three.js 后面的世界就会清楚很多。

参考链接

延伸阅读