Three.js 概述
目的与范围
本文档提供 Three.js 库架构的高层概览,包括其模块组织、分发格式、核心系统以及不同子系统间的交互方式。有关特定子系统的详细信息,请参阅:
什么是 Three.js
Three.js 是一个跨平台的 JavaScript 3D 图形库,旨在简化 WebGL 和 WebGPU 编程。它在 GPU API 之上提供高层抽象,提供基于场景图的架构用于在网页浏览器中渲染 3D 内容。
当前版本:REVISION = '183dev',定义于 src/constants.js1
主要能力:
- 通过 WebGL 2 和 WebGPU 实现硬件加速 3D 渲染
- 具有层次变换的场景图管理
- 基于物理渲染(PBR)的材质系统
- 动画、骨骼绑定与形态目标
- 常见 3D 文件格式的导入/导出(GLTF, FBX, OBJ)
- 后处理效果与阴影
分发格式
Three.js 以支持不同用例和渲染后端的多种构建变体形式分发:
| 构建输出 | 入口点 | 格式 | 用途 |
|---|---|---|---|
| three.core.js | src/Three.Core.js | ESM | 核心数学、场景图、几何体系统 |
| three.module.js | src/Three.js | ESM | 核心 + WebGL 渲染器 |
| three.webgpu.js | src/Three.WebGPU.js | ESM | 核心 + WebGPU 渲染器 + 节点材质系统 |
| three.cjs | src/Three.Core.js | CommonJS | Node.js 兼容性 |
| three.tsl.js | src/Three.TSL.js | ESM | WebGPU 的 Three 着色语言(TSL)导出 |
包导出(来自 package.json8-20):
"exports": {
".": {
"import": "./build/three.module.js",
"require": "./build/three.cjs"
},
"./webgpu": "./build/three.webgpu.js",
"./tsl": "./build/three.tsl.js",
"./addons": "./examples/jsm/Addons.js"
}高层架构
系统组织图
核心子系统
场景图与渲染管线
Three.js 遵循场景图范式,其中 3D 对象组织在层次树结构中。渲染过程将此逻辑场景表示转换为 GPU 命令。
关键类:
Scenesrc/scenes/Scene.js10-194 - 可渲染对象、光源、雾效、背景的根容器Object3Dsrc/core/Object3D.js1-1164 - 所有场景图节点的基类,具有变换层次结构WebGLRenderersrc/renderers/WebGLRenderer.js64-2500 - 主要渲染编排和 WebGL API 包装器
数学与变换系统
核心数学层提供 3D 变换、空间查询和几何计算的原始类型。
变换层次结构:每个 Object3D 维护局部变换(matrix)和世界空间变换(matrixWorld)。世界矩阵通过在遍历期间将父级世界矩阵向下相乘来计算。
材质与着色器系统
材质定义表面外观并控制着色器生成。Three.js 使用基于模板的着色器系统,其中 GLSL 代码根据材质属性从可重用片段组装而成。
着色器编译过程:
- 材质属性确定所需的着色器特性(例如
USE_MAP、USE_NORMALMAP) WebGLPrograms生成程序配置哈希值- 如果未缓存,则从
ShaderLib模板和ShaderChunk包含项组装 GLSL 源代码 - 通过
WebGLProgramsrc/renderers/webgl/WebGLProgram.js309-495 编译和链接着色器
几何体与缓冲区管理
几何体数据存储在 BufferGeometry 中,使用类型化数组,这些数组被高效上传到 GPU 缓冲区。
关键类:
BufferGeometrysrc/core/BufferGeometry.js1-1283 - 顶点属性容器BufferAttributesrc/core/BufferAttribute.js1-400 - 带元数据的类型化数组包装器WebGLAttributesbuild/three.module.js61-294 - GPU 缓冲区生命周期管理WebGLBindingStates- 管理顶点数组对象(VAO)以实现高效属性绑定
渲染后端:WebGL vs WebGPU
Three.js 支持两种不同架构的渲染后端:
| 特性 | WebGLRenderer | WebGPURenderer |
|---|---|---|
| 入口点 | src/renderers/WebGLRenderer.js | 包含在 three.webgpu.js 中 |
| API | WebGL 2 | WebGPU |
| 材质系统 | 固定材质类型 | 基于节点的(NodeMaterial) |
| 着色器语言 | GLSL(基于模板) | WGSL(节点图) |
| 坐标系 | WebGLCoordinateSystem | WebGPUCoordinateSystem |
| 多目标 | 单渲染目标 | 多渲染目标(MRT) |
WebGL 架构 src/renderers/WebGLRenderer.js64-2500:
- 管理 20+ 子系统(状态、程序、纹理、几何体等)
- 通过
WebGLPrograms缓存系统进行着色器编译 - 通过
WebGLState进行状态管理,最小化冗余 GPU 调用
WebGPU 架构 build/three.webgpu.js1-2485272:
- 基于节点的材质系统,着色器从节点图构造
- TSL (Three Shading Language),用于在 JavaScript 中表达着色器逻辑
- 现代 GPU 特性:计算着色器、存储缓冲区、MRT
常量系统
Three.js 在整个代码库中为配置使用数值和字符串常量。这些常量集中在 src/constants.js1-1071
关键常量类别:
| 类别 | 示例 | 用途 |
|---|---|---|
| 混合 | NoBlending, NormalBlending, AdditiveBlending | 控制 alpha 合成 |
| 剔除 | CullFaceNone, CullFaceBack, FrontSide, DoubleSide | 面可见性 |
| 深度测试 | LessDepth, LessEqualDepth, AlwaysDepth | Z 缓冲区比较 |
| 纹理过滤 | NearestFilter, LinearFilter, LinearMipmapLinearFilter | 纹理采样 |
| 纹理格式 | RGBAFormat, RGBFormat, DepthFormat | 像素格式规范 |
| 阴影映射 | BasicShadowMap, PCFShadowMap, VSMShadowMap | 阴影过滤算法 |
| 色调映射 | NoToneMapping, ACESFilmicToneMapping, AgXToneMapping | HDR 到 LDR 转换 |
构建系统
构建系统使用 Rollup 从无 TypeScript 的 JavaScript 源代码生成多种分发格式。
构建配置 utils/build/rollup.config.js66-143:
构建输出:
three.core.js:不含渲染器的核心库three.module.js:核心 + WebGLRendererthree.webgpu.js:核心 + WebGPURenderer + 节点材质系统three.tsl.js:用于 WebGPU 的 TSL (Three Shading Language) 重新导出- 生产环境的压缩版本(
.min.js)
GLSL 处理 utils/build/rollup.config.js4-36:glsl() 插件通过从标记为 /* glsl */ 的模板字面量中删除注释和多余空白来压缩 GLSL 着色器代码。
模块组织
源代码按逻辑目录组织:
src/
├── constants.js # 系统级常量
├── Three.js # WebGL 入口点
├── Three.Core.js # 仅核心入口点
├── Three.WebGPU.js # WebGPU 入口点
├── Three.TSL.js # TSL 重新导出
├── animation/ # 动画系统
├── cameras/ # 相机类型
├── core/ # Object3D, BufferGeometry, Raycaster
├── geometries/ # 程序化几何体生成器
├── lights/ # 光源类型
├── loaders/ # 加载器基类
├── materials/ # 材质基类
├── math/ # 数学原始类型
├── objects/ # Mesh, Line, Points, Sprite
├── renderers/ # WebGLRenderer 和子系统
│ ├── webgl/ # WebGL 后端组件
│ ├── shaders/ # GLSL 着色器库
│ └── webxr/ # WebXR 支持
├── scenes/ # Scene, Fog
└── textures/ # 纹理类
examples/jsm/ # 附加模块(不在核心中)
├── loaders/ # GLTFLoader, FBXLoader 等
├── controls/ # OrbitControls 等
├── postprocessing/ # 后处理效果
└── exporters/ # 场景导出器核心 vs 示例:
- 核心 (
src/):打包在主分发中,稳定 API - 示例 (
examples/jsm/):附加模块,通过/addons/*路径单独导入
使用模式
基本渲染设置
典型的 Three.js 应用程序遵循此模式(来自 README.md24-58):
import * as THREE from 'three';
// 1. 创建场景
const scene = new THREE.Scene();
// 2. 创建相机
const camera = new THREE.PerspectiveCamera(
70, // 视野角度
window.innerWidth / window.innerHeight, // 宽高比
0.01, // 近平面
10 // 远平面
);
// 3. 创建几何体和材质
const geometry = new THREE.BoxGeometry(0.2, 0.2, 0.2);
const material = new THREE.MeshNormalMaterial();
// 4. 创建网格并添加到场景
const mesh = new THREE.Mesh(geometry, material);
scene.add(mesh);
// 5. 创建渲染器
const renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
// 6. 动画循环
renderer.setAnimationLoop((time) => {
mesh.rotation.x = time / 2000;
mesh.rotation.y = time / 1000;
renderer.render(scene, camera);
});关键技术细节
坐标系
- 右手坐标系:+X 向右,+Y 向上,+Z 朝向观察者
- WebGL:映射到 OpenGL 约定 src/constants.js1071
- WebGPU:不同的裁剪空间映射 src/constants.js1071
色彩空间管理
- 线性工作流:内部在线性色彩空间中操作
- 自动转换:sRGB 纹理在 GPU 上转换为线性
- 色调映射:在最终着色器通道中应用 HDR 到 LDR 转换
- 色彩空间:
SRGBColorSpace、LinearSRGBColorSpace、NoColorSpacesrc/constants.js804-840
内存管理
- 手动释放:必须通过
.dispose()方法显式释放 GPU 资源 - 资源跟踪:
WebGLProperties使用 WeakMap 将 GPU 对象与 JS 对象关联 - 上下文丢失:通过
webglcontextlost事件自动恢复 src/renderers/WebGLRenderer.js1073-1103
性能考虑
渲染优化
- 绘制调用批处理:
BatchedMesh将多个对象合并为单次绘制调用 - 实例化渲染:
InstancedMesh用于渲染同一几何体的多个副本 - 视锥剔除:通过边界体积自动可见性判定
- 细节层次(LOD):基于距离的自动网格切换
着色器编译
- 程序缓存:
WebGLPrograms按材质+光照哈希值缓存编译的着色器 - 延迟编译:着色器在首次渲染时编译,而非构造时
- 预热:
renderer.compile(scene, camera)预编译所有材质 src/renderers/WebGLRenderer.js1350-1420
扩展点
自定义材质
ShaderMaterial:对顶点和片元着色器的完全控制onBeforeCompile:在编译前修改内置材质着色器的钩子NodeMaterial(WebGPU):基于节点图的材质系统
自定义几何体
BufferGeometry:直接操作顶点属性- 程序化生成:在 JavaScript 中以编程方式创建几何体
- 计算着色器 (WebGPU):GPU 端几何体生成
渲染管线
onBeforeRender/onAfterRender:渲染期间的每对象回调- 渲染目标:用于效果和阴影的离屏渲染
- 多通道渲染:对渲染序列的手动控制