第 10 章 3D 图形数学专题 (Mathematical Topics from 3D Graphics)
核心结论
-
图形管线概述:顶点 → 图元装配 → 裁剪 / 投影 → 光栅化 → 像素着色 → 输出;每阶段都有专属数学。
-
3D 视图 = 4 个矩阵相乘:模型矩阵 × 视图矩阵 × 投影矩阵 × 视口矩阵(实际 GPU 中前两个合一为 model-view,第三与第四合一为 projection-viewport)。
-
多边形网格:顶点 + 索引 + 邻接;索引网格节省内存;strip / fan 进一步压缩;拓扑查询需邻接结构。
-
纹理映射:UV 坐标、采样器、mipmap、过滤模式;GPU 内建纹理单元完成;切线空间用于法线贴图。
-
局部光照模型:环境光 + 漫反射 (
n · l) + 镜面反射(Phong / Blinn-Phong)三部分叠加;渲染方程是物理正确的扩展。 -
骨骼动画:每顶点 4 个骨骼权重 + 4×4 骨骼变换矩阵;GPU 蒙皮(skinning)在顶点着色器中完成。
-
凹凸映射:法线贴图(扰动法向量)、视差贴图(深度位移)、环境光遮蔽(ambient occlusion);用纹理表达细节而无需更多三角形。
|
本章主旨
本章是全书的"图形应用章"——把第 1-9 章的数学工具落地到真实图形管线。涵盖视图构造、网格表达、纹理采样、光照模型、骨骼动画、凹凸贴图、完整 GPU 管线、HLSL shader 实例。这是全书最贴近实战的一章——学完本章应能"读懂 GPU shader 代码 + 解释每个矩阵 / 公式的来源"。 |
一、核心概念
本章围绕 7 个核心概念展开:从图形管线整体出发,依次介绍视图、网格、纹理、光照、动画、凹凸贴图,最后给完整 GPU 管线与 shader 示例。
| 概念 | 定义 + 重要性 | 实现提示 |
|---|---|---|
图形管线概述 |
顶点 → 图元装配 → 顶点着色 → 裁剪 / 投影 → 光栅化 → 片段着色 → 输出。每阶段可编程(现代 GPU)或固定。 |
§10.10;理解阶段划分才能定位性能瓶颈与数学作用点。 |
3D 视图构造 |
模型矩阵 → 视图矩阵(look-at) → 投影矩阵(透视 / 正交) → 视口变换;最终把世界点变换到屏幕像素。 |
§10.2-§10.3;模型 / 视图矩阵是 4×4 齐次矩阵;投影矩阵决定视锥体形状。 |
多边形网格 |
顶点 + 索引列表 + 邻接信息;strip / fan 进一步压缩带宽;BVH / 八叉树加速查询。 |
§10.4;FBX / glTF 导入后通常用索引三角网格存储。 |
纹理映射 |
UV 坐标把网格表面参数化到 [0, 1]² 纹理空间;采样 + 过滤 + mipmap 是 GPU 纹理单元的工作。 |
§10.5;纹理单元硬件优化(缓存 / LOD);采样器状态决定过滤模式。 |
局部光照模型 |
环境光 + 漫反射 |
§10.6;Phong / Blinn-Phong 是经验模型;物理正确的 PBR 用 BRDF + 微表面模型。 |
骨骼动画 |
每顶点关联若干骨骼 + 权重;顶点位置 = Σ 权重_i · 骨骼_i · 顶点;GPU 蒙皮在 vertex shader 完成。 |
§10.8;4 骨骼 / 顶点是 GPU 优化上限(uniform 寄存器约束)。 |
凹凸映射 (Bump mapping) |
法线贴图(在切线空间编码扰动法向量)、视差贴图(位移)、位移贴图(实际几何位移);用纹理模拟细节而无需更多三角形。 |
§10.9;切线空间 ( |
二、详细笔记
2.1 图形管线概述 (Graphics Pipeline Overview)
What:把 3D 场景转换为 2D 像素的多阶段流水线;现代 GPU 大部分阶段可编程(shader)。
Why:理解管线才能定位"代码在哪一阶段"、"GPU 在做什么"、"性能瓶颈在哪"。
How:
典型实时管线(§10.10):
-
设置场景:相机、光照、雾、深度缓冲。
-
可见性判定:粗筛(视锥剔除、八叉树 / BVH)。
-
对象级渲染状态:材质、纹理、着色器绑定。
-
几何生成 / 提交:顶点 / 索引数据送 GPU。
-
顶点级操作:model-view 变换、骨骼蒙皮、顶点光照(vertex shader)。
-
裁剪 / 投影 / 背面剔除:把 3D 三角形映射到 2D 屏幕空间;剔除背向三角形。
-
光栅化:把三角形离散为像素(fragment)。
-
片段级操作:纹理采样、像素光照、深度测试(fragment shader)。
-
输出合并:深度测试、混合、写入 framebuffer。
|
每阶段的核心数学
|
When:写 shader 时必须知道在哪一阶段;性能调优时定位瓶颈阶段。
Example:GPU 顶点着色器对应"顶点级操作"阶段;片段着色器对应"片段级操作"阶段;几何 / 计算着色器对应更上层的"图元装配 / 通用计算"。
2.2 3D 视图构造 (3D Viewing)
What:4 个矩阵链把世界坐标变换到屏幕像素。
Why:3D 场景到 2D 屏幕的核心数学;理解每个矩阵的作用才能定位"模型去哪了"。
How:
变换链:
各矩阵作用:
-
模型矩阵:物体 → 世界(§3.3 + §6.4 齐次)。
-
视图矩阵(look-at):世界 → 相机;由相机位置 / 目标 / 上方向构造。
-
投影矩阵:相机视锥 → NDC(§6.5);透视 / 正交。
-
视口矩阵:NDC → 屏幕像素。
视图矩阵构造(look-at):
|
相机空间约定
本书(左手系):+x 右、+y 上、+z 前;OpenGL(右手系):+x 右、+y 上、+z 后(朝向观察者);DirectX(左手系):+x 右、+y 上、+z 前。跨引擎时注意 z 翻转。 |
When:所有 3D 渲染;VR / AR(眼盒 / FOV);shadow mapping(光视图矩阵)。
Example:相机在 (0, 0, 5)、朝 (0, 0, 0)、上方向 (0, 1, 0)。视图矩阵 = 平移 (0, 0, -5) ——把相机移到原点。
2.3 多边形网格 (Polygon Meshes)
What:顶点 + 边 + 面的数据结构;通常用索引三角网格存储(节省内存)。
Why:3D 模型的标准存储格式;GPU 输入格式;BVH / 邻接查询基础。
How:
索引三角网格结构:
| 数据 | 内容 |
|---|---|
顶点数组 |
|
索引数组 |
|
邻接(可选) |
边邻接、面邻接(用于拓扑查询) |
strip / fan 压缩:
-
Triangle strip:
indices = [0, 1, 2, 3, 4, …],每 3 个连续索引 + 前两个 = 1 个三角形;节省索引 3 倍。 -
Triangle fan:以第 0 个顶点为中心,扇形展开;适合圆盘 / 锥体。
|
索引 vs 直接三角形数组
|
When:模型导入(FBX / glTF → 索引网格);渲染提交;碰撞器构造(凸包 / BVH)。
Example:立方体 8 顶点 + 12 三角形 × 3 索引 = 8 顶点 + 36 索引(而非 36 顶点)。
2.4 纹理映射 (Texture Mapping)
What:把 2D 图像"贴"到 3D 网格表面;UV 坐标 (u, v) ∈ [0, 1]² 把网格顶点映射到纹理像素 (texel)。
Why:用图像而非几何表达表面细节(颜色、法线、粗糙度等);节省内存远胜增加三角形。
How:
UV 坐标 + 采样:
| 操作 | 说明 |
|---|---|
顶点 UV |
每个顶点存 (u, v);三角形内像素 UV = 重心坐标插值 |
采样 |
纹理单元根据 UV 取对应 texel 颜色 |
过滤 |
双线性 / 三线性 / 各向异性;处理"一个像素覆盖多 texel"(放大)或"多个像素覆盖一 texel"(缩小) |
Mipmap |
预生成多级 LOD;远处自动用低分辨率;解决 闪烁 与 锯齿 |
寻址模式 |
wrap / clamp / mirror / border;处理 UV ∈ [0, 1] 之外的情况 |
|
纹理单元的硬件优化
|
When:所有 3D 渲染(颜色 / 法线 / 材质参数);粒子精灵;UI 字体;后期处理。
Example:纹理 256×256;UV (0.5, 0.5) 取 texel 中心;UV (0, 0) 取左下角(wrap 模式下 (1.5, 0.7) 取 (0.5, 0.7))。
2.5 局部光照模型 (Standard Local Lighting Model)
What:经验光照模型——环境光 + 漫反射 + 镜面反射;不依赖其他表面("局部")。
Why:简单、便宜、视觉效果"够用";实时渲染主流;PBR 是更物理正确的替代。
How:
Blinn-Phong 三部分:
展开:
其中 h = normalize(l + v) 是 半向量,p 是 shininess 指数。
|
Phong vs Blinn-Phong
|
When:所有实时渲染;移动端 / 老硬件;非 PBR 项目。
Example:太阳光(方向光)l = (0, 1, 0)、表面法向量 n = (0, 0, 1)、n · l = 0 ⇒ 表面背向太阳,无光照。
2.6 骨骼动画 (Skeletal Animation)
What:用层级骨骼链驱动网格顶点位置;每顶点存骨骼索引 + 权重;GPU 蒙皮在 vertex shader 中完成。
Why:角色动画的关键技术;用少量骨骼驱动大量顶点;内存 / 性能远胜逐顶点关键帧。
How:
数据结构(§10.8):
| 数据 | 内容 |
|---|---|
骨骼层级 |
每骨骼 4×4 变换矩阵 + 父骨骼索引 |
顶点蒙皮 |
每顶点 4 个骨骼索引 + 4 个权重(权重和 = 1) |
动画关键帧 |
每骨骼的 SRT(缩放 / 旋转 / 平移)时间序列 |
GPU 蒙皮(vertex shader):
其中 B_i 是骨骼 i 的世界变换矩阵、w_i 是权重。
|
4 骨骼限制的原因
GPU 顶点着色器的 uniform 寄存器数量有限;4 骨骼 / 顶点是大多数 GPU 的优化上限(可设 8 骨骼但寄存器压力更大)。多于 4 骨骼需 多 pass 蒙皮 或软件蒙皮。 |
When:角色 / 生物 / 机械动画;面部表情(Blend Shape + 骨骼);任何"骨架驱动网格"的场景。
Example:人形角色 50 根骨骼、5000 顶点;每顶点 4 权重;GPU 每帧 5000 顶点 × 4 骨骼 = 20000 次矩阵乘加 = 几毫秒。
2.7 凹凸映射 (Bump Mapping)
What:用纹理(法线贴图 / 视差贴图 / 位移贴图)模拟表面细节,不增加几何。
Why:节省内存 / 带宽 / 渲染时间;细节由 GPU 计算;劣势是无法改变 silhouette。
How:
法线贴图(§10.9):
-
纹理存"扰动法向量"(RGB ∈ [0, 1] 编码为切线空间向量 ∈ [-1, 1])。
-
vertex shader 输出切线空间基
(T, B, N)。 -
fragment shader:
N' = normalize(T · n.x + B · n.y + N · n.z),用N'替换n计算光照。
视差贴图 / 步进视差:进一步用高度图模拟"深度位移"——UV 自适应偏移。
位移贴图:真正位移顶点(tessellation / geometry shader),需要更多三角形。
|
切线空间 = TBN 基
法线贴图编码的是 切线空间 法向量;vertex shader 必须输出 (T, B, N) 三正交基(T = tangent、B = binormal、N = normal)。切线空间的好处:法线贴图与模型朝向无关——同一贴图可用于不同朝向的物体。 |
When:所有 3D 渲染;墙面 / 砖块 / 皮肤毛孔 / 岩石细节;与 PBR 配合使用。
Example:砖墙——基础立方体 + 砖块法线贴图;GPU 在 fragment 中按法线贴图扰动 n,产生"凹凸感"而无需细分几何。
三、关键图表
视觉图表
非可视化条目
|
非可视化条目(表 / 算法)
|
核心公式对照表
|
核心公式对照表
|
四、思维导图
mindmap
root((第 10 章 3D 图形数学))
图形管线
顶点图元片段
可编程shader
每阶段数学
3D视图
模型视图投影链
lookat构造
视锥体
网格
索引三角
strip压缩
邻接查询
纹理
UV坐标
mipmap过滤
压缩格式
光照
BlinnPhong
环境漫反射镜面
半向量简化
骨骼动画
4骨骼权重
GPU蒙皮
uniform限制
凹凸映射
法线贴图
TBN切线空间
视差位移
五、重点与易错点
-
图形管线每阶段都有数学:顶点变换、投影、光栅化插值、光照、纹理采样——定位性能瓶颈必先理解管线阶段。
-
*模型矩阵 / 视图矩阵 / 投影矩阵*是 3 个独立概念:模型 = 物体→世界,视图 = 世界→相机,投影 = 相机→NDC。混用会导致"模型错位 / 相机错位 / 投影失真"。
-
法线变换矩阵 =
(M⁻¹)ᵀ:直接用 model 矩阵变换法向量会因非均匀缩放而失真;必须用逆转置。 -
索引网格比直接三角省内存 3 倍以上:现代 GPU 顶点缓存依赖索引复用;导入模型务必索引化。
-
Blinn-Phong 用半向量
h = normalize(l + v)比 Phong 反射向量便宜:效果相近、GPU 友好。 -
光照 dot 积必须
max(0, …):负值代表背面,应无光照;忘记max(0)会导致背光面反而"发光"。 -
4 骨骼蒙皮是 GPU uniform 寄存器上限:多于 4 骨骼需多 pass 蒙皮(VRAM → RAM → GPU 多次)或软件蒙皮(CPU 慢)。
-
法线贴图用切线空间(TBN):贴图与模型朝向无关,可复用;vertex shader 必须输出 TBN 给 fragment。
-
mipmap 是必须的:远处不缩 mipmap 会闪烁 / 锯齿;硬件自动 LOD 选择基于屏幕空间梯度。
-
PBR 是 Blinn-Phong 的物理升级:BRDF + 微表面 + 能量守恒;现代 AAA 默认使用(UE5 / Unity HDRP)。
-
跨章衔接:第 11 章力学用本节光照 / 蒙皮做物理可视化;第 12 章把 Blinn-Phong 推广到 PBR;第 13 章曲线用于角色手部 IK。