1.1 罗德里格斯旋转公式
绕任意轴n旋转α度(其中I为单位矩阵)
R(n,α)=cos(α)I+(1−cos(α))nnT+sin(α)⎣⎢⎡0nz−ny−nz0nxny−nx0⎦⎥⎤
TODO:后面补3D数学基础时再来推导一遍吧
1.2 什么是视图变换
视图变换是想如何拍一张照片:
- 找一个好的地方并安排拍照的人(Model Transformation 模型变换)
- 找一个好的地方并且安放好相机(View Transformation 视图变换)
- 拍照,将3D画面处理为2D画面(Projection Transformation 投影变换)
1.3 定义相机
相机有三个非常重要的属性:(此处的^代表一个单位向量)
- Position e
- Look-at/gaze direction g^
- up direction t^ (控制相机选择,固定相机)

如果相机和所有物件一起移动,这个"相片会是一样的",因此,将相机固定于(0,0,0),向着−z方向看
将 e 移到原点,可得变换矩阵:
Tview=⎣⎢⎢⎢⎡100001000010−xe−ye−ze1⎦⎥⎥⎥⎤
将世界坐标系转换到摄像机坐标系,也就是Rotate g to −Z, t to Y, (g×t) to X
直接变换我们可能想不出,为什么不考虑一下X to (g×t), Y to t, Z to −g呢,因为旋转矩阵的逆矩阵就是其转置矩阵,因此我们写出了后者就得到了前者
Rview−1=⎣⎢⎢⎢⎡xg^×t^yg^×t^zg^×t^0xtytzt0x−gy−gz−g00001⎦⎥⎥⎥⎤
可得到:
Rview⎣⎢⎢⎢⎡xg^×t^xtx−g0yg^×t^yty−g0zg^×t^ztz−g00001⎦⎥⎥⎥⎤
同时我们结合上一节也能得到Mview=RviewTview
4.1 正交投影 Orthographic
正交投影:
- 把相机放原点,看向−Z,头向着Y
- 扔掉Z轴
- 不管 x, y 范围有多大,都把它移到[−1,1]∗[−1,1]上
通常的做法是:记录一个长方体的 [l,r][b,t][f,n] (x, y, z轴范围),将其移动到原点,再缩放为[−1,1]3
Mortho=⎣⎢⎢⎢⎡2/(r−l)00002/(t−b)00002/(n−f)00001⎦⎥⎥⎥⎤⎣⎢⎢⎢⎡100001000010−(r+l)/2−(b+t)/2−(n+r)/21⎦⎥⎥⎥⎤
ps:为什么此处是near - far(n - f),因为我们的camera是朝着−Z方向的,因此数值越小反而越远
4.2 透视投影 Perspective
做透视投影,要先投影再正交变换Mpersp−>ortho,将frustum(视椎)挤压为一个长方形
那如何来做这个"压扁"操作呢:
由上图可知,利用相似三角形的性质,可以得出x′=(n/z)x , y′=(n/z)y , 但是z的变化是我们仍不知道的,例如:
⎣⎢⎢⎢⎡xyz1⎦⎥⎥⎥⎤=>⎣⎢⎢⎢⎡nx/zny/zunknown1⎦⎥⎥⎥⎤=>(multbyz)⎣⎢⎢⎢⎡nxnystillunknownz⎦⎥⎥⎥⎤
同时又可以通过矩阵叉乘得到未知矩阵的一部分
Mpersp−>ortho=⎣⎢⎢⎢⎡n0?00n?000?100?0⎦⎥⎥⎥⎤
但是f,n平面的z在被挤压过后是不变的,只是中间的平面会变
由此我们可以得到
[00AB]⎣⎢⎢⎢⎡xyn1⎦⎥⎥⎥⎤=n2−>An+B=n2
同理代入f , 可以得到一个方程组:
{An+B=n2Af+B=f2=>{A=n+fB=−nf
因此我们的矩阵最终写为
Mpersp−>ortho=⎣⎢⎢⎢⎡n0000n0000n+f100−nf0⎦⎥⎥⎥⎤
5 光栅化处理及视口变换
把东西画在屏幕上的过程就叫作光栅化
5.1 定义视椎体宽高比和垂直可视角度

- fov:垂直可视角度
- t:在y轴的高度
- n:近平面上的z轴的点
- r:中心点到右边的距离
宽高比(aspect)= r/t
5.2 像素以及屏幕
pixel即picture element,pixel的范围:(0,0) to (width−1,height−1),中心:(x+0.5,y+0.5)
屏幕覆盖范围:(0,0) to (width,height)
5.3 视口变换
将x,y转换:[−1,1]2 to [0,width]×[0,height]
Mviewport=⎣⎢⎢⎢⎡width/20000height/2000010width/2height/201⎦⎥⎥⎥⎤