研究对象
计算机图形学 Computer Graphics 研究如何用计算机生成、表示和操纵视觉内容。它既处理最终的二维图像,也处理产生图像所需的三维场景、材质、光照和运动。课程沿四条主线展开:
光栅化 Rasterization :把三维图元投影并离散成屏幕像素,适合实时渲染;
几何 Geometry :描述曲线、曲面和复杂物体,并对网格进行细分、简化等处理;
光传输 Light Transport :模拟光在场景中的发射、反射、折射与散射,得到物理可信的图像;
动画与模拟 Animation and Simulation :描述物体随时间的运动,并用力学规律生成布料、流体等动态效果。
典型应用包括电子游戏、电影特效、动画、工业设计、科学与医学可视化、VR/AR、数字绘画、物理仿真、GUI 和字体排版。共同挑战是构造可交互的虚拟世界,同时理解现实中的几何、光学和运动规律,并把这些规律变成高效算法、硬件管线与显示技术。
图形学的输入通常是场景模型,输出是图像或动画;计算机视觉 Computer Vision 则从图像推断场景信息,图像处理 Image Processing 主要在已有图像上做变换。OpenGL、DirectX 和 Vulkan 是实现图形管线的接口,建模软件与游戏引擎是生产工具,它们都不等同于图形学本身。
向量
点表示位置,向量 Vector 表示位移或方向。给定两个点 A A A 和 B B B ,从 A A A 指向 B B B 的向量为
A B → = B − A . \overrightarrow{AB}=B-A.
A B = B − A .
向量 v = ( x , y , z ) T \mathbf v=(x,y,z)^T v = ( x , y , z ) T 的长度为
∥ v ∥ = x 2 + y 2 + z 2 . \lVert\mathbf v\rVert=\sqrt{x^2+y^2+z^2}.
∥ v ∥ = x 2 + y 2 + z 2 .
非零向量除以自身长度可得到单位向量 v ^ = v / ∥ v ∥ \hat{\mathbf v}=\mathbf v/\lVert\mathbf v\rVert v ^ = v / ∥ v ∥ 。单位向量只保留方向,常用于相机朝向、表面法线和光线方向。向量加法满足平行四边形法则,标量乘法改变长度;负标量还会反转方向。
点积
两个向量的 点积 Dot Product 为
a ⋅ b = ∥ a ∥ ∥ b ∥ cos θ = a x b x + a y b y + a z b z . \mathbf a\cdot\mathbf b
=\lVert\mathbf a\rVert\lVert\mathbf b\rVert\cos\theta
=a_xb_x+a_yb_y+a_zb_z.
a ⋅ b = ∥ a ∥ ∥ b ∥ cos θ = a x b x + a y b y + a z b z .
它把两个向量映射为一个标量,最常见的用途有三类:
判断方向接近程度:单位向量的点积就是夹角余弦;正值表示夹角小于 90 ∘ 90^\circ 9 0 ∘ ,负值表示方向大致相反。
计算投影:a \mathbf a a 在单位方向 b ^ \hat{\mathbf b} b ^ 上的标量投影是 a ⋅ b ^ \mathbf a\cdot\hat{\mathbf b} a ⋅ b ^ ,向量投影是 ( a ⋅ b ^ ) b ^ (\mathbf a\cdot\hat{\mathbf b})\hat{\mathbf b} ( a ⋅ b ^ ) b ^ 。
分解向量:在一组正交单位基下,点积直接给出向量沿各坐标轴的分量。
图形学中的 Lambert 余弦项、镜面高光和视锥判断都大量使用点积。实际计算夹角前应先归一化,否则点积还混入了长度因素。
投影公式可以从正交分解得到。设 b ≠ 0 \mathbf b\ne\mathbf0 b = 0 ,a \mathbf a a 沿 b \mathbf b b 的分量为 a ∥ = λ b \mathbf a_\parallel=\lambda\mathbf b a ∥ = λ b ,剩余分量 a − λ b \mathbf a-\lambda\mathbf b a − λ b 应与 b \mathbf b b 垂直,因此
( a − λ b ) ⋅ b = 0. (\mathbf a-\lambda\mathbf b)\cdot\mathbf b=0.
( a − λ b ) ⋅ b = 0.
展开后
λ = a ⋅ b b ⋅ b , \lambda=
\frac{\mathbf a\cdot\mathbf b}
{\mathbf b\cdot\mathbf b},
λ = b ⋅ b a ⋅ b ,
于是
proj b a = a ⋅ b b ⋅ b b . \operatorname{proj}_{\mathbf b}\mathbf a
=
\frac{\mathbf a\cdot\mathbf b}
{\mathbf b\cdot\mathbf b}\mathbf b.
proj b a = b ⋅ b a ⋅ b b .
当 b \mathbf b b 是单位向量时,分母等于 1,这就退化为 ( a ⋅ b ) b (\mathbf a\cdot\mathbf b)\mathbf b ( a ⋅ b ) b 。投影是后续相机坐标分解、光照余弦和碰撞响应的共同基础。
叉积
三维向量的 叉积 Cross Product 为
a × b = ( a y b z − a z b y a z b x − a x b z a x b y − a y b x ) . \mathbf a\times\mathbf b=
\begin{pmatrix}
a_yb_z-a_zb_y\\
a_zb_x-a_xb_z\\
a_xb_y-a_yb_x
\end{pmatrix}.
a × b = a y b z − a z b y a z b x − a x b z a x b y − a y b x .
结果垂直于 a \mathbf a a 与 b \mathbf b b 所在平面,长度为 ∥ a ∥ ∥ b ∥ sin θ \lVert\mathbf a\rVert\lVert\mathbf b\rVert\sin\theta ∥ a ∥ ∥ b ∥ sin θ ,方向由右手定则确定。交换两个操作数会反向:a × b = − ( b × a ) \mathbf a\times\mathbf b=-(\mathbf b\times\mathbf a) a × b = − ( b × a ) 。
把 a \mathbf a a 作为底边,b \mathbf b b 在垂直于 a \mathbf a a 方向上的高度为 ∥ b ∥ sin θ \lVert\mathbf b\rVert\sin\theta ∥ b ∥ sin θ ,所以
∥ a × b ∥ = ∥ a ∥ ∥ b ∥ sin θ \lVert\mathbf a\times\mathbf b\rVert
=
\lVert\mathbf a\rVert
\lVert\mathbf b\rVert\sin\theta
∥ a × b ∥ = ∥ a ∥ ∥ b ∥ sin θ
正好是两向量张成的平行四边形面积,三角形面积则是它的一半。叉积方向同时给这块面积附加了朝向。
二维叉积常把向量嵌入 z = 0 z=0 z = 0 平面。对有向边 A → B A\to B A → B 和测试点 P P P ,
s = ( B − A ) × ( P − A ) s=(B-A)\times(P-A)
s = ( B − A ) × ( P − A )
的 z z z 分量为正,表示 P P P 在边的左侧;为负则在右侧。二维叉积的结果 z z z 分量用于方向和面积判断,这里的 z z z 不是场景深度。若三角形 A B C ABC A BC 按逆时针排列,分别计算有向边 A → B A\to B A → B 、B → C B\to C B → C 、C → A C\to A C → A 与测试点形成的三个叉积;三个 z z z 分量都大于等于零时,P P P 位于三角形内部或边界。顺时针顶点会让三个符号整体反转。这把叉积、有向面积和后续光栅化内部测试连接起来。
点积提取同向分量,叉积编码垂直方向与有向面积;后续光照和光栅化会反复使用这两种几何含义。
坐标系
三维 正交坐标系 Orthonormal Coordinate Frame 由三个两两垂直的单位向量 u , v , w \mathbf u,\mathbf v,\mathbf w u , v , w 组成:
∥ u ∥ = ∥ v ∥ = ∥ w ∥ = 1 , u ⋅ v = v ⋅ w = w ⋅ u = 0. \lVert\mathbf u\rVert=\lVert\mathbf v\rVert=\lVert\mathbf w\rVert=1,
\qquad
\mathbf u\cdot\mathbf v
=\mathbf v\cdot\mathbf w
=\mathbf w\cdot\mathbf u
=0.
∥ u ∥ = ∥ v ∥ = ∥ w ∥ = 1 , u ⋅ v = v ⋅ w = w ⋅ u = 0.
若它们还满足 u × v = w \mathbf u\times\mathbf v=\mathbf w u × v = w ,便构成右手坐标系。任意向量 p \mathbf p p 都可以写成
p = ( p ⋅ u ) u + ( p ⋅ v ) v + ( p ⋅ w ) w . \mathbf p=(\mathbf p\cdot\mathbf u)\mathbf u
+(\mathbf p\cdot\mathbf v)\mathbf v
+(\mathbf p\cdot\mathbf w)\mathbf w.
p = ( p ⋅ u ) u + ( p ⋅ v ) v + ( p ⋅ w ) w .
模型坐标、世界坐标、相机坐标和屏幕坐标描述的是同一个对象在不同参考系下的数值。后续的变换矩阵,本质上是在这些坐标系之间转换表示。
矩阵
矩阵 Matrix 把一组数组织为线性映射。若 A A A 为 m × n m\times n m × n 矩阵,B B B 为 n × p n\times p n × p 矩阵,则乘积 C = A B C=AB C = A B 为 m × p m\times p m × p 矩阵,其中
C i j = ∑ k = 1 n A i k B k j . C_{ij}=\sum_{k=1}^{n}A_{ik}B_{kj}.
C ij = k = 1 ∑ n A ik B kj .
矩阵乘法满足结合律和分配律,但一般不满足交换律:A B ≠ B A AB\ne BA A B = B A 。这一点决定了几何变换的执行次序不能随意交换。把列向量放在矩阵右侧时,复合变换会从右向左作用。
单位矩阵 I I I 不改变向量。可逆矩阵 A A A 存在逆矩阵 A − 1 A^{-1} A − 1 ,满足 A A − 1 = A − 1 A = I AA^{-1}=A^{-1}A=I A A − 1 = A − 1 A = I ;复合变换的逆为
( A B ) − 1 = B − 1 A − 1 . (AB)^{-1}=B^{-1}A^{-1}.
( A B ) − 1 = B − 1 A − 1 .
转置会交换行列,且 ( A B ) T = B T A T (AB)^T=B^TA^T ( A B ) T = B T A T 。正交矩阵的列向量构成正交单位基,因此 R − 1 = R T R^{-1}=R^T R − 1 = R T 。三维旋转矩阵正是这一类矩阵,它既保持长度,也保持夹角。
长度保持性可以直接验证:
∥ R x ∥ 2 = ( R x ) T ( R x ) = x T R T R x = x T x = ∥ x ∥ 2 . \lVert R\mathbf x\rVert^2
=(R\mathbf x)^T(R\mathbf x)
=\mathbf x^TR^TR\mathbf x
=\mathbf x^T\mathbf x
=\lVert\mathbf x\rVert^2.
∥ R x ∥ 2 = ( R x ) T ( R x ) = x T R T R x = x T x = ∥ x ∥ 2 .
同理,
( R a ) ⋅ ( R b ) = a T R T R b = a ⋅ b , (R\mathbf a)\cdot(R\mathbf b)
=
\mathbf a^TR^TR\mathbf b
=
\mathbf a\cdot\mathbf b,
( R a ) ⋅ ( R b ) = a T R T R b = a ⋅ b ,
所以向量长度与夹角都不变。反射矩阵也可能是正交矩阵;旋转还要求 det R = 1 \det R=1 det R = 1 ,而镜像的行列式为 − 1 -1 − 1 。