three.js 完整笔记
-
- [一、three.js 是什么](#一、three.js 是什么)
- 二、核心知识点
-
- [1. 坐标系](#1. 坐标系)
- [2. 相机两种类型](#2. 相机两种类型)
- [3. 材质(重点区分)](#3. 材质(重点区分))
- [4. 灯光系统](#4. 灯光系统)
- [5. Addons(官方扩展包,需单独导入,高频使用)](#5. Addons(官方扩展包,需单独导入,高频使用))
- [6. 模型格式选型](#6. 模型格式选型)
- [7. 渲染器新选择:WebGPURenderer](#7. 渲染器新选择:WebGPURenderer)
- [8. 交互:射线投射 Raycaster](#8. 交互:射线投射 Raycaster)
- [9. 性能优化(实战必看)](#9. 性能优化(实战必看))
- [10. 配套工具](#10. 配套工具)
- [11. 局限(客观缺点)](#11. 局限(客观缺点))
- [12. 安装方式](#12. 安装方式)
- [13. 动画相关](#13. 动画相关)
-
- [帧动画 / 骨骼动画](#帧动画 / 骨骼动画)
- [Tween 补间动画(addon)](#Tween 补间动画(addon))
- 渲染循环注意点
- [14. 纹理 Texture](#14. 纹理 Texture)
- [15. 阴影完整要点](#15. 阴影完整要点)
- [16. 分组 Object3D](#16. 分组 Object3D)
- [17. 常用工具类 MathUtils](#17. 常用工具类 MathUtils)
- [18. 几何体新老版本区别](#18. 几何体新老版本区别)
- [19. 空间坐标相关](#19. 空间坐标相关)
- [20. 资源释放(SPA 项目重点,易被忽略)](#20. 资源释放(SPA 项目重点,易被忽略))
- [21. 多场景、多渲染目标](#21. 多场景、多渲染目标)
- [22. 单位规范](#22. 单位规范)
- [23. 版本注意事项](#23. 版本注意事项)
- [24. 常见误区](#24. 常见误区)
- [25. 相关生态周边库](#25. 相关生态周边库)
- [26. 抗锯齿](#26. 抗锯齿)
- [27. 裁剪与可视剔除](#27. 裁剪与可视剔除)
一、three.js 是什么
Three.js 是一个基于 WebGL 的 JavaScript 3D 图形库 ,简单说:用 JS 在浏览器里写 3D 效果,不需要安装插件。
官网:threejs.org
浏览器原生只支持 2D 画布(Canvas),WebGL 可直接调用显卡做 3D 渲染,但原生 WebGL API 非常底层、代码繁琐。Three.js 对 WebGL 做了封装,用简单 API 即可创建 3D 场景,支持几何体、材质贴图、光照阴影、相机控制、动画、粒子、后期特效等。
基础三要素(场景必备)
- Scene(场景):3D 世界,所有物体放置于此
- Camera(相机):相当于眼睛,决定观察视角
- Renderer(渲染器):把场景+相机画面绘制到网页
几何体 + 材质 → Mesh(网格物体,即 3D 模型)
能做什么
- 网页 3D 产品展示(手机、家具、汽车预览)
- 网页 3D 小游戏
- 数据可视化、3D 地图
- 网页 VR / AR 页面
- 交互式艺术、动态 3D 海报
特点
✅ 纯前端 JS,浏览器直接运行
✅ 开源免费,MIT 协议,可商用
✅ 支持模型导入:GLB/GLTF(最常用)、OBJ 等
✅ 跨平台:电脑、手机浏览器都能用
❌ 是渲染库不是引擎:无内置物理、UI、编辑器;物理需搭配 cannon.js,模型制作一般用 Blender
最简示例代码
js
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.MeshBasicMaterial({ color: 0x00ff00 });
const cube = new THREE.Mesh(geometry, material);
scene.add(cube);
camera.position.z = 5;
function animate() {
requestAnimationFrame(animate);
cube.rotation.x += 0.01;
cube.rotation.y += 0.01;
renderer.render(scene, camera);
}
animate();
运行后网页出现一个旋转的绿色立方体。
二、核心知识点
1. 坐标系
右手坐标系:X 向右(红)、Y 向上(绿)、Z 朝向观察者(蓝)
js
const axesHelper = new THREE.AxesHelper(5);
scene.add(axesHelper); // 显示坐标轴辅助线
2. 相机两种类型
- PerspectiveCamera 透视相机:近大远小,最常用,模拟人眼视觉
- OrthographicCamera 正交相机:无近大远小,适合 CAD、2.5D、工程图
3. 材质(重点区分)
MeshBasicMaterial:基础材质,不受光照影响MeshStandardMaterial:PBR 物理材质,支持金属度、粗糙度,写实首选MeshPhysicalMaterial:增强 PBR,支持玻璃透射、清漆、色散(水、玻璃、钻石)MeshPhongMaterial:老式反光材质,新项目一般不推荐ShaderMaterial:自定义着色器(GLSL),做高级特效、水面、光晕
常用属性:roughness 粗糙度、metalness 金属度、emissive 自发光、transparent 透明、opacity 透明度
注意:
MeshBasicMaterial不响应灯光,要有光影必须用 Standard/Phong 类材质
4. 灯光系统
AmbientLight:环境光,均匀照亮,无阴影DirectionalLight:平行光(太阳光),支持阴影PointLight:点光源(灯泡),向四周发光SpotLight:聚光灯(手电筒),锥形光束
5. Addons(官方扩展包,需单独导入,高频使用)
不属于 three.js 核心代码,不能直接从 three 主包导入 ,须从 three/addons/ 引入:
- OrbitControls 轨道控制器:鼠标拖拽旋转、滚轮缩放场景,绝大多数项目都会用
js
import { OrbitControls } from 'three/addons/controls/OrbitControls.js';
- GLTFLoader:加载 GLB/glTF 模型(行业标准格式),支持 Draco 压缩,减小体积
js
import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js';
- PostProcessing:后期特效,bloom 泛光、轮廓描边、SSR 反射
js
import { EffectComposer } from 'three/addons/postprocessing/EffectComposer.js';
- CSS3DRenderer:把网页 DOM 元素放进 3D 空间(3D 网页卡片)
js
import { CSS3DRenderer } from 'three/addons/renderers/CSS3DRenderer.js';
- WebXR 相关:网页 VR/AR 控制器、手部追踪工具
核心 vs Addons 速记:
✅ 核心:Scene、Camera、WebGLRenderer、基础几何体、基础材质、基础灯光、TextureLoader ------
import * as THREE from 'three'直接用⚠️ Addons:控制器、各类模型加载器、后期管线、WebXR ------ 需
three/addons/单独导入注:TextureLoader(图片贴图加载器)是核心自带 ;GLTFLoader/OBJLoader/STLLoader 属于 Addons
6. 模型格式选型
- glTF / GLB:首选!Web3D 标准,文件小、加载快,Blender 直接导出,支持材质、动画;GLB 是二进制单文件,更方便
- OBJ+MTL:老格式,不支持动画
- STL:CAD 模型,仅存几何、不带材质,多用于 3D 打印
7. 渲染器新选择:WebGPURenderer
性能远高于旧 WebGL,支持更多 GPU 特效;浏览器不支持时可自动降级 WebGLRenderer
8. 交互:射线投射 Raycaster
实现鼠标点击拾取 3D 物体。原理:从相机向鼠标位置发射射线,检测与哪些模型相交
9. 性能优化(实战必看)
- InstancedMesh:批量渲染大量相同物体(草地、树木、粒子),大幅减少绘制调用
- LOD:远处用低面数模型,近处用高精度
- 模型压缩:Draco、Meshopt,降低文件体积
- 合并静态几何体,减少 draw call
- 控制阴影数量:阴影开销高,不要给太多光源开阴影
- 移动端限制
pixelRatio,避免高分辨率卡顿
10. 配套工具
- Blender:建模、展 UV、调材质,导出 glb
- glTF Viewer:在线预览 glb,提前检查模型
- 官方示例:threejs.org/examples
- 文档:threejs.org/docs
11. 局限(客观缺点)
- 不是完整游戏引擎:无内置物理、UI、场景编辑器(物理需引 cannon-es)
- 移动端性能上限有限,面数/灯光过多易掉帧
- 浏览器差异、移动端 WebGL 兼容性偶有坑
12. 安装方式
- CDN 直接引入,快速写 demo
- npm 安装(vite/webpack):
npm install three,ES 模块 import
13. 动画相关
帧动画 / 骨骼动画
AnimationMixer:动画混合器,加载 glTF 骨骼动画的核心,驱动人物走动、挥手AnimationClip:动画片段,一个模型可携带多个(走路、跳跃、待机)AnimationAction:动画实例,控制播放、暂停、淡入淡出、混合
常见用法:多个动作平滑过渡(待机→跑步)
Tween 补间动画(addon)
Tween.js:位置、旋转、颜色平滑过渡(物体移动、弹窗动画),是属性插值动画
渲染循环注意点
requestAnimationFrame:跟随屏幕刷新率,一般 60 帧- 循环内不要频繁新建物体/材质,会产生大量 GC 垃圾导致卡顿
- 用
clock.getDelta()保证动画速度在不同帧率下一致:
js
const clock = new THREE.Clock();
function animate() {
requestAnimationFrame(animate);
const delta = clock.getDelta();
cube.rotation.y += delta * 2; // 按时间驱动,帧率变化速度不变
renderer.render(scene, camera);
}
14. 纹理 Texture
TextureLoader:加载图片纹理(贴图)- 贴图分类:颜色、法线、粗糙度、金属、AO 环境闭塞(PBR 写实必备)
CubeTexture立方体贴图:环境贴图,做天空盒、物体反射VideoTexture:把视频作为材质贴图
坑点:跨域图片不能直接作为纹理,服务器需配置 CORS
15. 阴影完整要点
- 渲染器开阴影:
renderer.shadowMap.enabled = true; - 光源开投影:
light.castShadow = true; - 物体:
mesh.castShadow = true(投影)+mesh.receiveShadow = true(接收) shadow.mapSize阴影贴图分辨率,越大越清晰、越耗性能
仅平行光/点光源/聚光灯支持阴影;环境光无阴影
16. 分组 Object3D
js
const group = new THREE.Group();
group.add(cube1, cube2);
scene.add(group);
group.position.x = 2; // 整个组一起平移
Scene、Camera、Mesh、Group 都继承自 Object3D ,都有 position/rotation/scale
rotation 默认是弧度 ,角度转弧度:
THREE.MathUtils.degToRad(45)
17. 常用工具类 MathUtils
js
THREE.MathUtils.degToRad(degrees) // 角度→弧度
THREE.MathUtils.radToDeg(radians) // 弧度→角度
THREE.MathUtils.clamp(value, min, max) // 限制区间
THREE.MathUtils.lerp(a, b, alpha) // 线性插值
18. 几何体新老版本区别
- BufferGeometry:新版默认,数据存 GPU 缓冲区,性能高(BoxGeometry 本质即它)
- Geometry :旧版,已废弃,新项目不要用
几何体属性:顶点、法线、UV;可自定义顶点做不规则模型
19. 空间坐标相关
position:世界坐标(简写).getWorldPosition(target):获取物体在场景中的世界坐标lookAt():让物体/相机/灯光看向某坐标,如camera.lookAt(cube.position)
20. 资源释放(SPA 项目重点,易被忽略)
不释放会内存泄漏,页面越来越卡:
js
mesh.geometry.dispose();
mesh.material.dispose();
texture.dispose();
scene.remove(mesh);
21. 多场景、多渲染目标
- 可多 Scene、多相机切换视角(第一/第三人称切换)
- RenderTarget 离屏渲染:把 3D 结果当贴图贴到另一模型(监控屏、镜像效果)
22. 单位规范
Three.js 无内置单位,1 是自定义单位。行业惯例 1 单位 = 1 米
23. 版本注意事项
- 大版本 API 改动大,不要混用不同版本的 three 和 addons(必须完全一致,否则报错)
- 锁版本,不用
latest,上线固定版本号
24. 常见误区
- ❌ 共用材质 dispose 多次(一次即可)
- ❌ 以为 MeshBasicMaterial 能接收光照(不响应任何光源)
- ❌ 旋转直接写角度,忘用弧度
- ❌ 大量独立 Mesh 不用 InstancedMesh → draw call 爆炸
- ❌ 模型导入发黑:多半忘了环境光/环境贴图,或法线贴图翻转
25. 相关生态周边库
- cannon-es / Ammo.js:物理引擎(碰撞、重力、刚体)
- lil-gui:网页调试面板,实时调参数,开发神器
- troika-three-text:高性能 3D 文字
- postprocessing:官方后期管线(bloom、景深、抗锯齿)
- @react-three/fiber + drei:React 生态封装
26. 抗锯齿
new THREE.WebGLRenderer({ antialias: true });WebGPU 有更好的方案;开启会耗性能
27. 裁剪与可视剔除
- Frustum culling(视锥剔除):默认开启,视野外物体不渲染
mesh.frustumCulled = false关闭剔除(极少用)- 遮挡剔除:three.js 原生不自带,需自实现或用第三方库