three.js
学习内容
场景(Scene)、相机(Camera)、渲染器(Renderer)
几何体(Geometry)、材质(Material)、网格(Mesh)
光照(Light)与阴影
模型加载(GLTF、OBJ 等格式)
动画系统(Tween、关键帧动画)
交互(Raycaster、鼠标事件)
后期处理(Post-processing)
名词解释
着色器(Shader)
定义:运行在显卡(GPU)上的程序,用于控制 3D 物体表面的颜色、光照、阴影等视觉效果
类型:
顶点着色器(Vertex Shader):处理每个顶点的位置、颜色、法向量等
片元着色器(Fragment Shader):决定屏幕上每个像素最终显示的颜色
类比:就像给 3D 模型“上色”的工人,决定它看起来是金属、塑料还是玻璃
缓冲区(Buffer)
定义:内存中的一块区域,用于存储图形数据,如顶点坐标、颜色、法向量、纹理坐标等
作用:将这些数据从 CPU 发送到 GPU,供着色器使用
类比:就像一个“数据快递箱”,把模型的几何信息打包发送给显卡处理
纹理(Texture)
定义:一张 2D 图片,贴在 3D 模型表面,用来增加细节(如木纹、人脸、砖墙等)
作用:让模型看起来更真实,避免“塑料感”
类比:就像给一个空白的纸盒子贴上包装纸
渲染管线(Rendering Pipeline)
定义:从 3D 模型到 2D 屏幕图像的整个处理流程
主要阶段:
顶点处理:用顶点着色器处理每个顶点
图元装配:将顶点组成三角形等图元
光栅化:将三角形转换为像素(片元)
片元处理:用片元着色器计算每个像素颜色
输出:将结果写入帧缓冲区,显示在屏幕上
类比:就像一条“3D 到 2D 的流水线”,每个环节加工一次,最终产出图像
三维坐标(3D Coordinate)
定义:用三个数值(x、y、z)表示空间中一个点的位置
x:左右方向(水平)
y:上下方向(垂直)
z:前后方向(深度)
作用:精确描述 3D 空间中物体的位置、大小和方向
示例:点(2,3,1)表示在 X 轴 2 单位、Y 轴 3 单位、Z 轴 1 单位的位置
矩阵(Matrix)
定义:一个数字表格,用于表示 3D 空间中的变换
用途:
平移(移动位置)
旋转(改变方向)
缩放(改变大小)
特点:多个变换可以通过矩阵乘法合并成一个矩阵,高效计算
类比:就像一个“魔法变幻盒”,输入一个点,输出变换后的新点
向量(Vector)
定义:有大小和方向的量,通常用(x,y,z)表示
用途:
表示位置(从原点到某点的向量)
表示方向(从光照方向、摄像机朝向)
表示速度、力、法线等物理量
常见操作:加法、减法、点乘(判断角度)、叉乘(求垂直向量)
类比:就像一个“带箭头的线段”,告诉你“往哪走”和“走多远”
法线(Normal)
定义:法线是一个向量,它垂直于某个表面(如平面、曲线、三角形等)
通俗理解:一根竹竿垂直矗立在平静的水面,这根竹竿的方向就是水面的法线方向
法线的表示:通常用一个单位向量(长度为 1 的向量)表示,例如:
(0,1,0):表示垂直向上的法线(比如水平地面的法线)
(0,0,1):表示朝向屏幕外的法线
(1,0,0):表示向右的法线
主要用途
光照计算(最重要)
光照效果(如明暗、高光)依赖于光线方向和表面法线之间的夹角
当光线垂直照射表面(光线方向与法线方向一致)时,表面最亮
当光线斜射或背对表面时,表面变暗
没有正确的法线,3D 物体就不会有真实的光影效果,看起来像“扁平”的
背面剔除(Backface Culling)
显卡可以通过法线判断一个三角形是面向摄像机还是背对摄像机
背对摄像机的面可以被“剔除”不渲染,提升性能
碰撞检测与物理模拟
- 当两个物体碰撞时,法线可以用来计算反弹方向、摩擦力等
法线贴图(Normal Mapping)
一种高级纹理技术,通过一张特殊的纹理(法线贴图)来“伪造”表面细节(如凹凸、划痕),而不需要增加模型的几何复杂度
这张贴图存储的是每个像素的法线方向,用来欺骗光照系统,让平摊的表面看起来有凹凸感
类型
面法线(Face Normal):垂直于整个三角形面的向量,用于平面着色
顶点法线(Vertex Normal):每个顶点有一个法线,通常是相邻面法线的平均值,用于实现平滑着色(如球体)
例子:假设有一个 3D 立方体,每个面都有一个法线,指向外侧
当灯光从上方照射时,顶面的法线与光线夹角小,所以最亮
侧面的法线与光线夹角大,所以较暗
背面的法线几乎与光线相反,所以最暗甚至看不见
总结
项目 说明 本质 垂直于表面的向量 形式 单位向量(x,y,z) 核心作用 决定光照效果,让 3D 物体看起来有立体感 常见应用 光照、阴影、法线贴图、物理碰撞
FOV(Field of View,视场角)
定义:是垂直方向的视角角度(单位:度),默认以垂直方向为基准
值越大看到的场景越广(类似鱼眼镜头)
值越小看到的场景越窄(类似望远镜)
常用取值范围
FOV 值 视觉效果 类比 30°~45° 较窄视野,远处物体显得更大 望远镜、长焦镜头 50°~75° 自然、舒适,接近人眼视角 标准镜头(推荐用于大多数应用) 90°~120° 广角,边缘有拉伸变形 手机超广角、游戏常用 >120° 极端广角,明显畸变 鱼眼镜头 人眼的 FOV 参考
单眼水平视野约 150°~160°
双眼重叠区域(清晰视觉)约 120°
垂直视觉约 135°
但人眼中央清晰区域只有 30°~50°
如何选择合适的 FOV
应用场景 推荐 FOV 说明 产品展示/室内漫游 45° ~ 60° 减少畸变,真实感强 第一人称游戏 70° ~ 90° 更沉浸,视野更广 第三人称游戏/相机跟随 60° ~ 75° 平衡角色与环境 数据可视化/抽象 3D 50° ~ 75° 默认即可 VR/AR 80° ~ 100°+ 匹配头显设备的实际视野 总结
问题 答案 FOV 是什么? 垂直视角角度,控制相机“看得多宽” 默认用多少? 75°(Three.js 推荐值) 怎么选? 一般 50°~75°;游戏可更大;展示类宜更小 修改后要做什么? 调用 camera.updateProjectionMatrix() 太大有什么问题? 边缘畸变、物体变形、不真实
总结关系图
1 | 三维坐标 → 存储在 → 缓冲区 |
图元
图元就是一些 3D 的形状
BoxGeometry 立方体
参数:
width
height
depth
widthSegments
heightSegments
depthSegments
CircleGeometry 平面圆
参数:
radius
segments
thetaStart:起始角度
thetaLength:圆弧的中心角
ConeGeometry 圆锥
参数:
radius
height
radialSegments:径向分段。指沿半径方向的分段数
heightSegments:高度分段。指沿垂直方向的分段数量
openEnded: Boolean 锥体的底部是否有开口
thetaStart
thetaLength
CylinderGeometry 圆柱
参数:
radiusTop:顶部半径
radiusBottom:底部半径
height
radialSegments
heightSegments
openEnded: Boolean 圆柱的顶部和底部是否有开口
thetaStart
thetaLength
DodecahedronGeometry 十二面体
参数:
radius:半径
detail:将其设置为大于 0 的值会添加顶点,使其不再是十二面体
ExtrudeGeometry 拉伸几何体
IcosahedronGeometry 二十面体
参数:
radius
detail:将其设置为大于 0 的值会添加顶点,使其不再是二十面体
LatheGeometry 绕着一条线旋转形成的形状。
提供一系列点作为 2D 轮廓,并告诉 Three.js 沿着某条轴旋转时需要将侧面分成多少块。形状如灯泡、保龄球瓶、蜡烛、蜡烛台、酒瓶、玻璃杯等
参数:
points:二维空间中的一组点,每个点的 x 坐标必须大于 0
segments:要生成的圆周段数,默认 12
phiStart:起始角度
phiLength:弧度
OctahedronGeometry 八面体
参数:
radius
detail:将其设置为大于 0 的值会添加顶点,使其不再是八面体
ParametricGeometry
通过提供一个函数(将网格中 2D 的点转成对应的 3D 点)生成的表面
参数:
func:函数参数。默认生成一个曲面的平面
slices:函数参数的切片数量。默认 8
stacks:函数参数的切片分段。默认 8
PlaneGeometry 2D 平面
参数:
width
height
widthSegments:宽度分段
heightSegments:高度分段
PolyhedronGeometry 多面体
将一些环绕着中心点的三角形投影到球体上
参数:
vertices:描述基础形状的平面顶点数组
indices:描述基础形状的扁平索引数组
radius
detail:几何体要细分多少个级别。细节越多,形状越平滑
RingGeometry
中间有洞的 2D 圆盘






