three.js 完整笔记

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 场景,支持几何体、材质贴图、光照阴影、相机控制、动画、粒子、后期特效等。

基础三要素(场景必备)

  1. Scene(场景):3D 世界,所有物体放置于此
  2. Camera(相机):相当于眼睛,决定观察视角
  3. 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. 相机两种类型

  1. PerspectiveCamera 透视相机:近大远小,最常用,模拟人眼视觉
  2. 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. 性能优化(实战必看)

  1. InstancedMesh:批量渲染大量相同物体(草地、树木、粒子),大幅减少绘制调用
  2. LOD:远处用低面数模型,近处用高精度
  3. 模型压缩:Draco、Meshopt,降低文件体积
  4. 合并静态几何体,减少 draw call
  5. 控制阴影数量:阴影开销高,不要给太多光源开阴影
  6. 移动端限制 pixelRatio,避免高分辨率卡顿

10. 配套工具

11. 局限(客观缺点)

  1. 不是完整游戏引擎:无内置物理、UI、场景编辑器(物理需引 cannon-es)
  2. 移动端性能上限有限,面数/灯光过多易掉帧
  3. 浏览器差异、移动端 WebGL 兼容性偶有坑

12. 安装方式

  1. CDN 直接引入,快速写 demo
  2. 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. 阴影完整要点

  1. 渲染器开阴影:renderer.shadowMap.enabled = true;
  2. 光源开投影:light.castShadow = true;
  3. 物体:mesh.castShadow = true(投影)+ mesh.receiveShadow = true(接收)
  4. 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. 常见误区

  1. ❌ 共用材质 dispose 多次(一次即可)
  2. ❌ 以为 MeshBasicMaterial 能接收光照(不响应任何光源)
  3. ❌ 旋转直接写角度,忘用弧度
  4. ❌ 大量独立 Mesh 不用 InstancedMesh → draw call 爆炸
  5. ❌ 模型导入发黑:多半忘了环境光/环境贴图,或法线贴图翻转

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 原生不自带,需自实现或用第三方库

相关推荐
xxwl5851 小时前
第六章---计算几何
笔记·学习·算法
ss2731 小时前
AI时代首先数据库-PostgreSQL实战笔记 | 12 PostgreSQL数据目录与重要文件结构
数据库·笔记·postgresql
Song_RsHt1 小时前
Gateway (上):路由与转发,微服务的统一入口
java·笔记·后端·学习·gateway
骑士雄师2 小时前
《结构化思维》第五章 · 精读回顾(案例版 · 含结构图)
笔记
xxwl5852 小时前
区域赛算法模版第五章---数学与数论
c++·笔记·算法
David猪大卫3 小时前
【C++修炼】string类:string类的模拟实现
c语言·开发语言·数据结构·c++·经验分享·笔记·学习
lisw053 小时前
计算生物学学习笔记:NHGRI基因组数据科学分析、可视化和信息学实验室空间(AnVIL)
笔记·计算生物学
骑士雄师5 小时前
结构化思维》第一、二章 → prompt review skill 优化启发清单
笔记
David猪大卫5 小时前
【C++修炼】STL容器—模板进阶:非类型模板参数、模板特化、模板分离编译
c语言·开发语言·c++·经验分享·笔记·学习·面试