Model Transform 模型变换
2D变换
Linear Transformation 线性变换
x′=ax+by
y′=cx+dy
矩阵形式为
[x′y]=[acbd][xy]
Scale Matrix 缩放
[sxxsyy]=[sx00sy][xy]
Reflection Matrix 镜像
Horizontal reflection:
[−xy]=[−1001][xy]
Shear Matrix 切变
Horizontal shift:
[x+ay]=[10a1][xy]
Rotate 旋转
默认绕原点(0,0)逆时针方向(counterclockwise)旋转
Rθ=[cosθsinθ−sinθcosθ]
推导:

Translation 平移
x′=x+tx
y′=y+ty
这个变换无法直接写为统一的矩阵形式
[x′y]=[acbd][xy]+[txty]
因为平移不是线性变换
但是为了变换的形式的统一,可以引入齐次坐标(homogeneous coordinates)来表示
齐次坐标
对于二维向量,增加一个维度w
2D Point = (x,y,1)T
2D Vector =(x,y,0)T
在矩阵运算时
⎣⎡x′y′w′⎦⎤=⎣⎡100010txty1⎦⎤⋅⎣⎡xy1⎦⎤=⎣⎡x+txy+ty1⎦⎤
同时,增加的维度在运算时也具有意义
对于⎣⎡xyw⎦⎤,在w不为0时,表示为一个点,标准化运算后为⎣⎡x/wy/w1⎦⎤
- vector + vector = vector
- point - point = vector
- point + vector = point
- point + point = ??
对于最后一种情况,得到的也是一个点,在进行标准化运算后,得到的是两点的中点
引入齐次坐标的目的是能够使用一个矩阵乘一个向量来表示所有变换
以上[x′y]=[acbd][xy]+[txty]形式的变换,统称为仿射变换(Affine Transformations)
用齐次坐标的形式来表示
⎣⎡x′y′1⎦⎤=⎣⎡ac0bd0txty1⎦⎤⋅⎣⎡xy1⎦⎤
Scale
S(sx,sy)=⎣⎡sx000sy0001⎦⎤
Rotation
R(θ)=⎣⎡cosθsinθ0−sinθcosθ0001⎦⎤
Translation
T(tx,ty)=⎣⎡100010txty1⎦⎤
Inverse Transform 逆变换
逆矩阵M−1,即做与矩阵M相反的变换
Composing Transform 组合变换
因为矩阵运算具有结合律,不同类型的变换可以通过多个矩阵相乘合成为一个变换矩阵。但需要注意矩阵运算不满足交换律,因此变换是具有顺序的,例如先旋转再平移、先平移再旋转可能会得到不同的结果。
在使用多个矩阵进行变换时,变换是从右向左应用的
例如T(1,0)⋅R45°⋅⎣⎡xy1⎦⎤中,先进行Rotate变换,再进行Translate变换
通过预先将多个矩阵变换合成为一个矩阵,可以在运算时提高性能
Decomposing Complex Transforms 分解变换
如何绕任意一个点进行旋转变换?
由于我们定义的旋转矩阵是绕原点进行旋转的,可以先将这个点移动到原点,进行旋转变换后,再进行一次平移还原到原来的位置。可表示为T(c)⋅R(α)⋅T(−c)
旋转变换的一些性质
对于旋转矩阵Rθ=[cosθsinθ−sinθcosθ]
若旋转角度为−θ,则有R−θ=[cosθ−sinθsinθcosθ]=RθT
即旋转−θ是旋转θ的转置,而通过定义我们可以知道旋转−θ与旋转θ是互逆的操作,有R−θ=Rθ−1
由此可得RθT=Rθ−1,旋转矩阵的逆矩阵等于转置矩阵
在数学中,如果一个矩阵的逆等于转置,称这个矩阵为正交矩阵
3D变换
3D Point = (x,y,z,1)T
3D Vector =(x,y,z,0)T
(x,y,z,w)三维向量,w不为0时即为三维空间中一点(x/w,y/w,z/w)
3D 仿射变换
⎣⎡x′y′z′1⎦⎤=⎣⎡adg0beh0cfi0txtytz1⎦⎤⋅⎣⎡xyz1⎦⎤
应用这个矩阵时,先进行线性变换,再进行平移
Scale
S(sx,sy,sz)=⎣⎡sx0000sy0000sz00001⎦⎤
Translation
T(tx,ty,tz)=⎣⎡100001000010txtytz1⎦⎤
Rotation(x-, y-,z- axis)
Rx(θ)=⎣⎡10000cosθsinθ00−sinθcosθ00001⎦⎤
Ry(θ)=⎣⎡cosθ0−sinθ00100sinθ0cosθ00001⎦⎤
Rz(θ)=⎣⎡cosθsinθ00−sinθcosθ0000100001⎦⎤
Euler angles 欧拉角
对三维空间中的旋转,可以用分别绕x,y,z轴的三个旋转组合而成
Rxyz(α,β,γ)=Rx(α)Ry(β)Rz(γ)
通常把三个分量称为roll,pitch,yaw
但是欧拉角旋转在两个轴重合时,会出现失去一个自由度的情况,称为万向节死锁
Rodrigues' Rotation Formula
绕任意轴axis旋转α角度的公式,轴axis是默认经过原点的
(n,α)=cos(α)I=(1−cos(α))nnT+sin(α)N
N=⎣⎡0nz−ny−nz0nxny−nx0⎦⎤
Quaternion 四元数旋转
能够应用于插值运算
留个坑详解四元数(未完成)
View Transform 观测变换
进行观测变换需要大量信息,包括:摄像机的位置和朝向、投影的类型、视场的大小( FOV field of view)、渲染的分辨率
通常可以把观测变换分解为三个流程
- Camera Transform 相机变换
- Projection Transform 投影变换
- Viewport Transform 视口变换
在变换流程中坐标系统有特定的名称:

Figure 8.2 from Fundamentals of Computer Graphics, 5th Edition
一些别名
camera space也叫eye space,camera transformation也称作viewing transformation,canonical view volume也叫clip space或normalized device coordinates(NDC),screen space也叫pxiel coordinates
Fundamentals of Computer Graphics, 5th Edition P159
Camera Transform
相机变换将点转变为归一化坐标(canonical cooridnates)
定义一个相机变换:
- Position e
- Look-at/gaze direction g^
- Up direction t^
由于运动是相对的,为了简化相机变换,我们可以把摄像机相对物体的运动看做物体相对摄像机的运动。把摄像机固定在原点,up朝向y轴,look at朝向−z轴
用变换来描述:
- 将摄像机移动到原点
- 把g^转到−Z
- 把t^转到Y
- 把(g^×t^)转到X
写成矩阵形式Mcam=RviewTview
Tview=⎣⎡100001000010−xe−ye−ze1⎦⎤
将摄像机的坐标轴旋转到XYZ轴方向并不容易求,但是我们可以将XYZ旋转到摄像机的坐标轴方向得到逆矩阵,在上文我们证明了旋转矩阵的逆等于转置,由此可以求出Rview
Rview−1=⎣⎡xg^×t^yg^×t^zg^×t^0xtytzt0x−gy−gz−g00001⎦⎤ Rview=⎣⎡xg^×t^xtx−g0yg^×t^yty−g0zg^×t^ztz−g00001⎦⎤
合并后得到
Mcam=⎣⎡xg^×t^xtx−g0yg^×t^yty−g0zg^×t^ztz−g0−xe−ye−ze1⎦⎤
Viewport Trasnform 视口变换
将经过camera transform变换后得到的NDC坐标绘制到大小为nx×ny像素大小的屏幕上,需要将NDC的标准正方形[−1,−1]2映射到[−0.5,nx−0.5]×[−0.5,ny−0.5]的矩形
4×3的像素映射为[−0.5,3.5]×[−0.5,2.5]

Figure 3.10 from Fundamentals of Computer Graphics, 5th Edition
写作矩阵形式:
Mvp=⎣⎡2nx00002ny0000102nx−12ny−101⎦⎤
此处暂时忽略了z坐标,因为z轴方向的距离并不会影响投影的位置。但在后续处理中会用到z坐标来处理遮挡关系
Projection Transform 投影变换
Orthographic projection 正交投影
在空间中定义一个范围[l,r]×[b,t]×[f,n],称作orthographic view volume,将这个范围映射到一个[−1,1]3的标准(canonical)立方体内
Mortho=⎣⎡r−l20000t−b20000n−f200001⎦⎤⎣⎡100001000010−2r+l−2t+b−2n+f1⎦⎤=⎣⎡r−l20000t−b20000n−f20l−rl+rb−tb+tf−nf+n1⎦⎤
在经过Mvp和Mortho的组合变换后,一个点应该变为⎣⎡xpixelypixelzcanonical1⎦⎤,z坐标仍然在[−1,1]范围内,之后会在深度缓冲中使用
Perspective Transform 透视变换
透视投影在空间中的范围称作Frustum

Figure 8.13 from Fundamentals of Computer Graphics, 5th Edition
通过侧视图,我们可以推导出在进行透视投影后,y轴方向的长度会变为ys=zdy

Figure 8.8 from Fundamentals of Computer Graphics, 5th Edition
z坐标出现在了分母,导致我们不能直接使用纺射变换来推导透视投影矩阵
但是我们可以对齐次坐标运算进行推广,来实现在仿射变换中使用除法
先前我们规定用[xyz1]T来表示三维空间中的一点(x,y,z),并且保证仿射变换矩阵的第四行始终为[0001]
现在我们可以定义将w定义为x,y,z坐标的分母,用齐次坐标[xyzw]T来表示带点(x/w,y/w,z/w),也就是将(x,y,z,w)各分量同时除以w,0项仍然为0,得到(x/w,y/w,z/w,1)。这个操作称为齐次除法或透视除法。这样我们就可以在矩阵的第四行使用任意值来支持更广泛的变换
具体来说,线性变换允许我们实现
x′=ax+by+cz
仿射变换将变换扩展为
x′=ax+by+c+d
将w定义为分母就可以实现计算
x′=ex+fy+gz+hax+by+cz+d
这种变换可以称作线性有理函数,但是一个额外的约束条件是,坐标每个分量的分母都是相同的
x′=ex+fy+gz+ha1x+b1y+c1z+d1
y′=ex+fy+gz+ha2x+b2y+c2z+d2
z′=ex+fy+gz+ha3x+b3y+c3z+d3
将这些变换合并为一个矩阵
⎣⎡x~y~z~w~⎦⎤=⎣⎡a1a2a3eb1b2b3fc1c2c3gd1d2d3h⎦⎤=⎣⎡xyz1⎦⎤
对于这个变换矩阵M,与任意的常数k相乘不会改变结果
Perspective Projection 透视投影
在透视投影中,我们将采用惯例,将摄像机放在原点,朝向−z方向,所以任意一点(x,y,z)到摄像机的距离为−z;将近裁剪平面作为投影平面,所以投影平面的距离为−n(n < 0)
透视投影也可以分解为两个步骤,先将投影区域Frustum压缩成正交投影中的轴对齐的一个四方柱体,再进行正交投影
通过侧视图和俯视图,利用三角形相似进行推导,可以得到⎣⎡xyz1⎦⎤⇒⎣⎡nx/zny/zunknown1⎦⎤==⎣⎡nxnyunknownn⎦⎤
将齐次除法还原,⎣⎡nxnyunknownz⎦⎤,此时已经够推导出矩阵的一部分
Mpersp→ortho=⎣⎡n0?00n?000?100?0⎦⎤
再考虑一些特殊点:
-
近平面上的点在压缩后不会发生变化,⎣⎡xyn1⎦⎤⇒⎣⎡xyn1⎦⎤==⎣⎡nxnyn2n⎦⎤,考虑Mpersp→ortho矩阵中的第三行与这个坐标相乘,得到了n2,显然与x,y无关,由此可以得出第三行的前两项为0,利用待定系数法设第三行为[00AB],有An+B=n2
-
远平面上的点在压缩后z坐标不会改变,我们已经得出第三行与x,y无关,所以取远平面的中心点来计算⎣⎡00f1⎦⎤⇒⎣⎡00f1⎦⎤==⎣⎡00f2f⎦⎤,根据设出的值可以得到Af+B=f2
于是有方程组{An+B=n2Af+B=f2 解得:{A=n+fB=−nf
最终我们得到
Mpersp→ortho=⎣⎡n0000n0000n+f100−nf0⎦⎤
Mpersp=Mpersp→ortho=⎣⎡r−l2n0000t−b2n00l−rl+rb−tb+tn−fn+f100f−n2fn0⎦⎤
OpenGL使用的矩阵
MOpenGL=⎣⎡r−l2∣n∣0000t−b2∣n∣00l−rl+rb−tb+t∣n∣−∣f∣∣n∣+∣f∣−100∣f∣−∣n∣2∣f∣∣n∣0⎦⎤
投影变换的流程
compute Mvp
compute Mpersp
compute Mcam
M=MvpMperspMcam
将M传入顶点着色器计算
参考资料
Fundamentals of Computer Graphics, 5th Edition
GAMES101 Lecture03-04