注:本文是基于闫令琪老师的 GAMES101-现代计算机图形学入门 视频课程以及虎书《Fundamentals of Computer Graphics》做的笔记。转载请注明出处。
主要内容
- 光栅化
- 几何
- 光线追踪
- 模拟/动画
依赖(Dependencies)
- 线性代数 (Linear algebra)
- 微积分 (calculus)
- 统计 (statistics)
- 光学 (optics)
- 力学 (mechanics)
- 信号处理 (signal processing)
- 数值分析(numerical analysis)
1.线性代数
向量默认是列向量
-
向量点积
- 用于计算两个向量之间的夹角
- 用于计算向量的投影
- 衡量两个向量接近程度
- 根据点乘的正负判断两个向量的方向关系(同向还是反向)
-
向量叉积
- 遵循右手螺旋定则,四指由第一个向量旋转至第二个向量
- 用于根据x ,y轴确定z轴
- 用于确定向量的左右关系,如果xy平面内的向量a×b结果是正的(与z轴方向相同),表明b在a的左侧,若是负的则b在a的右侧
- 用于判断点是否在三角形内部
- 有些地方会使用左手坐标系,即z轴方向与xy的叉积相反
- 仍然遵顼结合律,a × (b+c)=a × b + a × c
- 两个同向向量叉积是零向量,零向量也是向量
-
矩阵乘法
A×B = C
A的列数必须等于B的行数,C的第i行第j列的数等于A的第i行向量与B的第j列向量的数量积
2D仿射变换(Affine Transformations)
线性变换(Linear Transformation)都可以用矩阵来表示:
[ x ′ y ′ ] = [ a b c d ] [ x y ] x ′ = a x + b y y ′ = c x + d y \begin{bmatrix} x' \\ y'\end{bmatrix} = \begin{bmatrix} a & b \\ c & d \end{bmatrix} \begin{bmatrix} x \\ y\end{bmatrix} \\ x'=ax+by\\ y'=cx+dy [x′y′]=[acbd][xy]x′=ax+byy′=cx+dy -
缩放(Scale)
[ x ′ y ′ ] = [ s x 0 0 s y ] [ x y ] x ′ = s x x y ′ = s y y \begin{bmatrix} x' \\ y'\end{bmatrix} = \begin{bmatrix} s_x & 0 \\ 0 & s_y \end{bmatrix} \begin{bmatrix} x \\ y\end{bmatrix} \\ x'=s_x x\\ y'=s_y y [x′y′]=[sx00sy][xy]x′=sxxy′=syy
-
对称(Reflection)
沿y轴对称:
[ x ′ y ′ ] = [ − 1 0 0 1 ] [ x y ] x ′ = − x y ′ = y \begin{bmatrix} x' \\ y'\end{bmatrix} = \begin{bmatrix} -1 & 0 \\ 0 & 1 \end{bmatrix} \begin{bmatrix} x \\ y\end{bmatrix} \\ x'=-x\\ y'=y [x′y′]=[−1001][xy]x′=−xy′=y
沿x轴对称只要将1和-1互换即可 -
错切(Shear)
[ x ′ y ′ ] = [ 1 a 0 1 ] [ x y ] x ′ = x + a y y ′ = y \begin{bmatrix} x' \\ y'\end{bmatrix} = \begin{bmatrix} 1 & a \\ 0 & 1 \end{bmatrix} \begin{bmatrix} x \\ y\end{bmatrix} \\ x'=x+ay\\ y'=y [x′y′]=[10a1][xy]x′=x+ayy′=y
-
旋转(Rotation)
旋转中心为(0,0)时:
[ x ′ y ′ ] = [ c o s θ − s i n θ s i n θ c o s θ ] [ x y ] x ′ = x c o s θ − y s i n θ y ′ = x s i n θ + y c o s θ \begin{bmatrix} x' \\ y'\end{bmatrix} = \begin{bmatrix} cosθ & -sinθ \\ sinθ & cosθ \end{bmatrix} \begin{bmatrix} x \\ y\end{bmatrix} \\ x'=xcosθ-ysinθ\\ y'=xsinθ+ycosθ [x′y′]=[cosθsinθ−sinθcosθ][xy]x′=xcosθ−ysinθy′=xsinθ+ycosθ
不难发现旋转矩阵是正交矩阵,即逆矩阵等于转置矩阵
R θ − 1 = R θ T = [ x ′ y ′ ] = [ c o s θ s i n θ − s i n θ c o s θ ] R_θ^{-1} = R_θ^T =\begin{bmatrix} x' \\ y'\end{bmatrix} = \begin{bmatrix} cosθ & sinθ \\ -sinθ & cosθ \end{bmatrix} Rθ−1=RθT=[x′y′]=[cosθ−sinθsinθcosθ] -
平移 (translation)
[ x ′ y ′ ] = [ 1 0 0 1 ] [ x y ] + [ t x t y ] \begin{bmatrix} x' \\ y'\end{bmatrix} = \begin{bmatrix} 1 & 0 \\ 0 & 1 \end{bmatrix} \begin{bmatrix} x \\ y\end{bmatrix}+ \begin{bmatrix} t_x \\ t_y\end{bmatrix} [x′y′]=[1001][xy]+[txty]
-
齐次坐标(Homogeneous Coordinates)
平移不是线性变换,我们无法使用一个二维矩阵来表示这个T ,因此引入齐次坐标的概念
把二维坐标增加一个维度:
点写成:
(x,y,1)
向量写成:
(x,y,0)
只有向量最后一个数是0时才符合向量的平移不变性质,且用点坐标减去点坐标得到的向量最后一位是0,用点+向量得到的第三位是1,符合基本定理
当点坐标的第三维不为1时:
(x,y,w)
写成(x/w,y/w,1)
来保证第三位是1,因此两个点坐标相加的结果是他们的中点至此,包括平移在内的以上的所有变换都可以写成下面的形式:
[ x ′ y ′ 1 ] = [ a b t x c d t y 0 0 1 ] [ x y 1 ] \begin{bmatrix} x' \\ y' \\1 \end{bmatrix} = \begin{bmatrix} a & b &t_x \\ c & d & t_y\\ 0&0&1\end{bmatrix} \begin{bmatrix} x \\ y\\1\end{bmatrix} ⎣⎡x′y′1⎦⎤=⎣⎡ac0bd0txty1⎦⎤⎣⎡xy1⎦⎤
-
逆变换 (Inverse Transformations)
逆变换可以通过乘以逆矩阵来表示
因为
[ x y 1 ] = A − 1 ⋅ A ⋅ [ x y 1 ] \begin{bmatrix} x \\ y \\1 \end{bmatrix} = A^{-1}·A·\begin{bmatrix} x \\ y \\1 \end{bmatrix} ⎣⎡xy1⎦⎤=A−1⋅A⋅⎣⎡xy1⎦⎤ -
复合变换 (Composing Transformations)
变换的顺序改变,结果也会改变(矩阵乘法不满足交换律)
先旋转再平移: 先左乘旋转变换矩阵,再左乘平移变换矩阵
[ x ′ y ′ 1 ] = T 1 , 0 ⋅ R 45 [ x y 1 ] \begin{bmatrix} x' \\ y' \\1 \end{bmatrix} =T_{1,0} ·R_{45}\begin{bmatrix} x \\ y \\1 \end{bmatrix} ⎣⎡x′y′1⎦⎤=T1,0⋅R45⎣⎡xy1⎦⎤
如果按先后顺序有一系列变换:
A 1 , A 2 , . . . , A n A_1,A_2,...,A_n A1,A2,...,An
可以通过矩阵乘法合并为一个矩阵:
A = A n . . . A 2 A 1 A=A_n ...A_2A_1 A=An...A2A1
然后导出结果:
[ x ′ y ′ 1 ] = A ⋅ [ x y 1 ] \begin{bmatrix} x' \\ y' \\1 \end{bmatrix} =A·\begin{bmatrix} x \\ y \\1 \end{bmatrix} ⎣⎡x′y′1⎦⎤=A⋅⎣⎡xy1⎦⎤
3D变换 (3D Transformations)
-
齐次坐标
依然是使用其次坐标来表示三维的点和向量
点:
(x,y,z,1)
向量:
(x,y,z,0)
(x,y,z,w)
视作点(x/w,y/w,z/w,1)
-
3D仿射变换矩阵
[ x ′ y ′ z ′ 1 ] = [ a b c t x d e f t y g h i t z 0 0 0 1 ] [ x y z 1 ] \begin{bmatrix} x' \\ y' \\z'\\1 \end{bmatrix} = \begin{bmatrix} a & b & c &t_x \\ d & e &f& t_y\\ g&h&i&t_z \\0&0&0&1\end{bmatrix} \begin{bmatrix} x \\ y\\z\\1\end{bmatrix} ⎣⎢⎢⎡x′y′z′1⎦⎥⎥⎤=⎣⎢⎢⎡adg0beh0cfi0txtytz1⎦⎥⎥⎤⎣⎢⎢⎡xyz1⎦⎥⎥⎤
表示的依然是先线性变换再平移- 缩放
S ( s x , s y , s z ) = [ s x 0 0 0 0 s y 0 0 0 0 s z 0 0 0 0 1 ] S(s_x,s_y,s_z)=\begin{bmatrix} s_x & 0 & 0 & 0 \\ 0 & s_y &0 & 0\\0&0&s_z&0 \\0&0&0&1\end{bmatrix} S(sx,sy,sz)=⎣⎢⎢⎡sx0000sy0000sz00001⎦⎥⎥⎤
- 缩放
-
平移
T ( t x , t y , t z ) = [ 0 0 0 t x 0 0 0 t y 0 0 0 t z 0 0 0 1 ] T(t_x,t_y,t_z)=\begin{bmatrix} 0 & 0 & 0 &t_x \\ 0 & 0 & 0 & t_y\\ 0 & 0 & 0 & t_z \\0&0&0&1\end{bmatrix} T(tx,ty,tz)=⎣⎢⎢⎡000000000000txtytz1⎦⎥⎥⎤ -
旋转
绕x轴旋转α角度:
R x ( α ) = [ 1 0 0 0 0 c o s α − s i n α 0 0 s i n α c o s α 0 0 0 0 1 ] R_x(α) = \begin{bmatrix} 1 & 0 & 0 & 0 \\ 0 & cosα & -sinα & 0\\ 0&sinα&cosα&0 \\0&0&0&1\end{bmatrix} Rx(α)=⎣⎢⎢⎡10000cosαsinα00−sinαcosα00001⎦⎥⎥⎤
绕y轴旋转α角度:
R y ( α ) = [ c o s α 0 s i n α 0 0 1 0 0 − s i n α 0 c o s α 0 0 0 0 1 ] R_y(α) = \begin{bmatrix} cosα & 0 & sinα & 0 \\ 0 & 1 & 0 & 0\\ -sinα&0&cosα&0 \\0&0&0&1\end{bmatrix} Ry(α)=⎣⎢⎢⎡cosα0−sinα00100sinα0cosα00001⎦⎥⎥⎤ 绕y轴旋转时α变成了-α,这是因为x轴是y轴叉乘z轴得到的,z轴是x轴叉乘y轴,方向都是正的,而y轴按顺序由 z轴叉乘x轴得到,方向是相反的。
绕z轴旋转α角度:
R z ( α ) = [ c o s α − s i n α 0 0 s i n α c o s α 0 0 0 0 1 0 0 0 0 1 ] R_z(α) = \begin{bmatrix} cosα & -sinα & 0 & 0 \\ sinα&cosα & 0 & 0\\ 0&0&1&0 \\0&0&0&1\end{bmatrix} Rz(α)=⎣⎢⎢⎡cosαsinα00−sinαcosα0000100001⎦⎥⎥⎤绕某一根轴旋转时,拿x轴举例,旋转后所有点的x坐标不变,所以矩阵的第一行第一列是1,第一行其他列都是0。这样矩阵乘法之后可以保证x还是x。然后我们从x轴方向往原点看,即看yz平面,此时yz平面上的变化是所有的点在绕原点旋转,那么就可以直接使用二维的旋转变换矩阵来表示y,z坐标的变换,第二行和第三行就是这样得到的。