three.js 入门与源码结构解析:从旋转立方体到 WebGL/WebGPU 双渲染器体系
本文以 three.js 仓库根目录的 README 为主体,讲清这个"易用、轻量、跨浏览器的通用 JavaScript 3D 库"的定位与最小可用示例,并结合 src/ 下的模块入口、package.json 的导出映射与测试脚本,帮助你在读完之后既能跑通官方示例,又能快速定位源码、理解 three.js 当前的模块组织方式与 WebGL/WebGPU 双线渲染架构。
项目定位:一个易用的通用 3D 库
README 对项目的定义非常凝练:
The aim of the project is to create an easy-to-use, lightweight, cross-browser, general-purpose 3D library.
即创建一个易用、轻量、跨浏览器的通用 3D 库。README 同时说明了当前的构建范围:官方构建(build)只包含 WebGL 与 WebGPU 两种渲染器,而 SVG 和 CSS3D 渲染器以 addons(附加模块)的形式存在,需要按需引入。
package.json 佐证了这一定位:包名 three,"type": "module",关键词覆盖了 webgl、webgl2、webgpu、webxr、webaudio、canvas、svg、html5 等能力面(见 package.json)。当前仓库中 npm 发布的版本号为 0.185.0,而 src/constants.js 中 REVISION 已推进到 '186dev',说明源码正处于 r186 的开发周期中——阅读本文内容时应以该仓库快照为准。
快速上手:README 官方最小示例
README 的 "Usage" 一节给出了官方最小可运行示例:创建一个场景(Scene)、相机(Camera)和一个立方体网格(Mesh),将其加入场景,再创建 WebGLRenderer 并把视口挂到 document.body 上,最后用动画循环驱动立方体旋转。完整代码如下:
import * as THREE from 'three';
const width = window.innerWidth, height = window.innerHeight;
// init
const camera = new THREE.PerspectiveCamera( 70, width / height, 0.01, 10 );
camera.position.z = 1;
const scene = new THREE.Scene();
const geometry = new THREE.BoxGeometry( 0.2, 0.2, 0.2 );
const material = new THREE.MeshNormalMaterial();
const mesh = new THREE.Mesh( geometry, material );
scene.add( mesh );
const renderer = new THREE.WebGLRenderer( { antialias: true } );
renderer.setSize( width, height );
renderer.setAnimationLoop( animate );
document.body.appendChild( renderer.domElement );
// animation
function animate( time ) {
mesh.rotation.x = time / 2000;
mesh.rotation.y = time / 1000;
renderer.render( scene, camera );
}
逐行拆解这段代码中每个 API 的取值依据:
new THREE.PerspectiveCamera( 70, width / height, 0.01, 10 ):四个参数分别是垂直视场角fov、宽高比aspect、近裁剪面near和远裁剪面far。从 src/cameras/PerspectiveCamera.js 的构造函数签名constructor( fov = 50, aspect = 1, near = 0.1, far = 2000 )可以看到默认值:fov 默认 50 度、near 默认 0.1、far 默认 2000。示例中选择near = 0.01、far = 10是为了匹配 0.2 大小的立方体与camera.position.z = 1的近距观察尺度;fov = 70则让立方体在视口中占比更醒目。new THREE.BoxGeometry( 0.2, 0.2, 0.2 ):边长 0.2 的立方体。由于相机位于 z=1,近裁剪面 0.01,立方体完整落在视锥体内。new THREE.MeshNormalMaterial():法线着色材质,不依赖任何贴图与光源即可呈现立体感,是官方示例常用的"零依赖"选择。new THREE.WebGLRenderer( { antialias: true } ):开启多采样抗锯齿。WebGLRenderer只接受 WebGL 2 上下文——从 src/renderers/WebGLRenderer.js 的类注释可确认:"This renderer uses WebGL 2 to display scenes. WebGL 1 is not supported sincer163." 构造函数源码中还会对传入的WebGL1上下文直接抛出THREE.WebGLRenderer: WebGL 1 is not supported since r163.错误(见 src/renderers/WebGLRenderer.js)。renderer.setAnimationLoop( animate ):这是 three.js 官方推荐的动画驱动方式(内部基于浏览器的高帧率请求机制,并在 WebXR 场景下自动切换到 XR 会话帧回调),回调参数time为时间戳(毫秒),示例用time / 2000与time / 1000让立方体沿 X、Y 轴以不同角速度旋转。
README 说明"如果一切顺利,你应该看到旋转的立方体"。除了最小示例,仓库在 examples/index.html 提供了数百个按主题分类的完整示例(webgl_*、webgpu_*、webxr_*、physics_* 等),是官方文档之外最好的学习入口。
WebGLRenderer 构造参数的默认值
README 示例只演示了 antialias: true,而 src/renderers/WebGLRenderer.js 的构造函数解构了全部可配参数,默认值如下表(这些默认值是调优渲染器行为时的基准):
| 参数 | 默认值 | 说明 |
|---|---|---|
canvas |
自动创建 | 复用的画布元素 |
context |
null |
显式传入的 WebGL2 上下文(传 WebGL1 会抛错) |
depth |
true |
是否创建深度缓冲 |
stencil |
false |
是否创建模板缓冲 |
alpha |
false |
画布是否带 alpha 通道(透明背景) |
antialias |
false |
多采样抗锯齿 |
premultipliedAlpha |
true |
预乘 alpha |
preserveDrawingBuffer |
false |
帧间保留绘制缓冲(截图场景需要,有性能代价) |
powerPreference |
'default' |
GPU 功耗偏好(如 high-performance) |
failIfMajorPerformanceCaveat |
false |
软件渲染时是否直接失败 |
reversedDepthBuffer |
false |
反转深度缓冲(适配特定渲染管线) |
outputBufferType |
UnsignedByteType |
输出缓冲数据类型(HDR 场景可改为浮点) |
模块入口与包导出结构:读懂 import from 'three'
README 示例中的 import * as THREE from 'three' 到底导出了什么?结合仓库源码可以给出精确答案。
package.json 的 exports 字段定义了包的入口映射:
"exports": {
".": {
"import": "./build/three.module.js",
"require": "./build/three.cjs"
},
"./examples/fonts/*": "./examples/fonts/*",
"./examples/jsm/*": "./examples/jsm/*",
"./addons": "./examples/jsm/Addons.js",
"./addons/*": "./examples/jsm/*",
"./src/*": "./src/*",
"./webgpu": "./build/three.webgpu.js",
"./tsl": "./build/three.tsl.js"
}
这对应了源码中四个聚合入口文件:
- src/Three.js —— 即
three主包。它先export * from './Three.Core.js'导出核心 API,再补上 WebGL 渲染器相关类:WebGLRenderer、WebGLCubeRenderTarget、ShaderLib、UniformsLib、UniformsUtils、ShaderChunk、PMREMGenerator、WebGLUtils。 - src/Three.Core.js —— 渲染器无关的核心层,约 188 行导出声明,覆盖
Scene、Object3D、Mesh、InstancedMesh、BufferGeometry、各类几何体(export * from './geometries/Geometries.js')、全部材质(export * from './materials/Materials.js')、相机、灯光、纹理、加载器、动画系统(AnimationMixer、AnimationClip、AnimationAction等)、数学工具(Matrix4、Quaternion、Color、ColorManagement)与辅助对象(AxesHelper、GridHelper等)。值得注意的是文件末尾的两处运行时逻辑:检测__THREE_DEVTOOLS__全局对象并向其派发register事件(浏览器开发者扩展钩子),以及向window.__THREE__写入REVISION、在检测到重复实例时告警(见 src/Three.Core.js)。仓库中的 devtools/ 目录即为配套的浏览器开发者扩展。 - src/Three.WebGPU.js ——
three/webgpu入口,在核心层之上导出WebGPURenderer、WebGPUBackend、WebGLBackend(WebGL 后备后端)、通用Renderer/RenderPipeline、节点材质(NodeMaterials)、Compute 相关类(StorageTexture、StorageBufferAttribute等)以及TSL命名空间。 - src/Three.TSL.js ——
three/tsl入口,约 675 行,将 TSL(Three Shading Language)的各个节点/工具函数以命名导出形式重新暴露(如BRDF_GGX、Fn、If、Loop、各类 Shadow Filter 与生命周期钩子OnBeforeFrameUpdate等),TSL 的完整规范文档见 docs/TSL.md。
这套"核心 + 渲染器"的分层结构解释了 README 中"当前构建只含 WebGL 与 WebGPU 渲染器"的说法:Three.Core.js 不绑定任何渲染器,而 WebGL 与 WebGPU 各自叠加在其上,SVG/CSS3D 等渲染器则留在 examples/jsm 的 addons 中,可通过 three/addons/* 按需引入。
克隆仓库:用 --depth=1 避免 2GB 历史下载
README 的 "Cloning this repository" 一节特别提醒:带着完整历史克隆本仓库约需下载 2 GB。如果不需要全部提交历史,应使用 depth 参数大幅缩减体积:
git clone --depth=1 https://github.com/mrdoob/three.js.git
这条建议源于仓库积累了十余年的提交记录。浅克隆后若后续需要完整历史,可以再执行 git fetch --unshallow 补全(此为通用 git 用法,README 未展开)。
版本与变更日志
README 将变更日志(Change log)指向上游的 Releases 页面,仓库自身不维护 CHANGELOG 文件;版本演进以 npm 版本与源码 REVISION 为准。当前快照中:
- package.json 的
version为0.185.0(npm 发布版); - src/constants.js 的
REVISION为'186dev'(源码开发版)。
另外 src/constants.js 中可以看到具体的 API 演进示例:PCFSoftShadowMap 自 r186 起被标记为 @deprecated,建议改用 PCFShadowMap。阅读旧示例代码遇到弃用警告时,可对照该文件中的注释判断迁移方向。
本地开发与测试:验证你的理解
理解源码最快的方式是跑起来并跑通测试。package.json 的 scripts 字段提供了完整的开发工作流(均基于 Node.js,无额外框架依赖):
| 脚本 | 命令 | 用途 |
|---|---|---|
dev / start |
node utils/build/dev.js && node utils/server.js -p 8080 |
启动本地开发服务器(端口 8080),浏览器加载开发版构建,可边改源码边看效果 |
build |
rollup -c utils/build/rollup.config.js |
用 Rollup 构建发布产物 |
lint |
npm run lint-core(即 eslint src) |
核心源码 ESLint 检查 |
test-unit |
node test/unit/puppeteer.unit.js --testPage=UnitTests.html --mode=headless |
基于 Puppeteer 的无头单元测试(280+ 个测试文件位于 test/unit/) |
test-unit-addons |
node test/unit/puppeteer.unit.js --testPage=UnitTestsAddons.html --mode=headless |
addons 的单元测试 |
test-e2e |
node test/e2e/puppeteer.js |
端到端测试(test/e2e/),--webgpu 可测 WebGPU 路径 |
test-treeshake |
rollup -c test/rollup.treeshake.config.js |
树摇测试,验证按需导入的包体积 |
make-screenshot |
node test/e2e/puppeteer.js --make |
重新生成示例截图(对应 examples/screenshots/ 下的 600+ 张 jpg) |
其中 dev 脚本值得展开:它先执行 utils/build/dev.js 生成开发构建,再由 utils/server.js 起一个本地静态/服务代理,这是官方推荐的本地调试方式——配合浏览器 DevTools 扩展(devtools/)可以直接在页面上检查 three.js 场景对象的层级与属性。
小结
- three.js 的目标是"易用、轻量、跨浏览器的通用 3D 库",官方构建内置 WebGL(仅 WebGL 2) 与 WebGPU 两种渲染器,SVG/CSS3D 等作为 addons 提供。
- 官方最小示例 =
Scene+PerspectiveCamera+BoxGeometry+MeshNormalMaterial+WebGLRenderer.setAnimationLoop,所有构造参数默认值均可在源码中查证。 - 包入口由
package.json的exports映射到四个聚合文件:src/Three.js(WebGL)、src/Three.Core.js(渲染器无关核心)、src/Three.WebGPU.js(WebGPU + Compute)、src/Three.TSL.js(着色语言 TSL),分层清晰且支持树摇。 - 克隆仓库建议
--depth=1以避免约 2 GB 的历史下载;本地开发用npm run dev起 8080 端口服务,质量保障由 Puppeteer 单测/e2e/树摇测试共同覆盖。
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust0627
Hy4-previewHy4 preview 是由腾讯混元团队研发的新一代混合专家(MoE)旗舰模型。模型总参数量 770B,每个 token 激活 49B,主干共包含78层,第一层采用标准 FFN,其余 77 层均为 MoE 结构,每层包含 256 个路由专家与 1 个共享专家,每个 token 激活 top-8 路由专家及共享专家。主干之外原生内置 1 层 MTP(总参数量 10B,激活 0.7B)以支持投机解码。Python00
GLM-5.3GLM-5.3 与 GLM-5.2 使用相同的基座模型——所有提升均来自后训练。与 GLM-5.2 相比,它在复杂编程和长程任务上的表现显著提升。Jinja00
GLM-5.3-FlashGLM-5.3-Flash (320B-A18B),是GLM-5系列的首个原生多模态模型。320B总参数,能力超过GLM-5.2Jinja00
Spark-X2.5-4BSpark-X2.5-4B 旨在让强大的 AI 更实用、更高效、更易获得。在广泛日常任务中表现强劲,涵盖对话、写作、翻译、推理、编码、工具调用以及智能体工作流,并在同等规模的开源模型中取得领先成绩。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00
Spark-X2.5-1.7BSpark-X2.5-1.7B 旨在让强大的 AI 更加实用、高效且易于获取。这些模型在广泛的日常任务中表现出色,涵盖对话、写作、翻译、推理、编程、工具调用和智能体工作流,并在同等规模的开源模型中取得领先结果。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00