学习内容

  • 场景(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
2
3
4
5
6
7
8
9
10
11
三维坐标 → 存储在 → 缓冲区

通过 → 矩阵 → 进行变换(移动/旋转/缩放)

由 → 着色器 → 处理(顶点着色器 + 片元着色器)

使用 → 纹理 → 贴图增加细节

在 → 坐标系 → 中定位(世界/局部/相机)

整个流程 → 渲染管线 → 输出到屏幕

图元

图元就是一些 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 圆盘