所謂的坐标系變換就是調用某個函數後得到的坐标。
關系如下圖:(當時小謝給我畫的~)
綠色框框内的表示需要自己寫代碼的~

齊次坐标(Homogeneous coordinates)
三維頂點(x,y,z),引入新分量w,得到(x,y,z,w)。
若w==1,則向量(x, y, z, 1)為空間中的點。
若w==0,則向量(x, y, z, 0)為方向。
二者差別:對于旋轉,二者無差別。當旋轉點和方向時,結果是一樣的。
但對于平移(将點沿着某個方向移動),平移一個方向是毫無意義的。
齊次坐标使得可以用同一個公式對點和方向作運算。
三種model transform(Translate,Rotate,Scale):
1、平移矩陣(Translation matrices)
平移矩陣是最簡單的變換矩陣。
平移矩陣是這樣的:
其中,X、Y、Z是點的位移增量。
例如,若想把向量(10, 10, 10, 1)沿X軸方向平移10個機關,可得:
這樣就得到了齊次向量(20,10,10,1)!末尾的1表示這是一個點,而不是方向。經過變換計算後,點仍然是點。
對一個代表Z軸負方向的向量作上述平移變換:
還是原來的(0,0,-1,0)方向,恰好印證了前面的結論:”平移一個方向是毫無意義的”。
代碼表示平移變換:
2、縮放矩陣(Scaling matrices)
例如把一個向量(點或方向皆可)沿各方向放大2倍:
w還是沒變。大多數情況一般不會去縮放向量,但在某些特殊情況下它就派上用場了。(機關矩陣隻是縮放矩陣的一個特例,其(X, Y, Z) = (1, 1, 1)。機關矩陣同時也是旋轉矩陣的一個特例,其(X, Y, Z)=(0, 0, 0))。
用C++表示:
是以在旋轉中,下一幀圖形的位置為:
(1)旋轉XY軸
(2)旋轉XZ軸
(3)旋轉YZ軸
把這些矩陣相乘就能将旋轉、平移和縮放向量組合起來,例如:
注意:首先執行縮放,接着旋轉,最後才是平移。這就是矩陣乘法的工作方式。
變換的順序不同,得出的結果也不同。
實際上,上述順序正是在變換遊戲角色或者其他物體時所需的:先縮放;再調整方向;最後平移。例如,假設有個船的模型(為簡化,略去旋轉):
錯誤做法:
按(10, 0, 0)平移船體。船體中心目前距離原點10個機關。
将船體放大2倍。以原點為參照,每個坐标都變成原來的2倍,就出問題了。最後您得到的是一艘放大的船,但其中心位于2*10=20。這并非您預期的結果。
正确做法:
将船體放大2倍,得到一艘中心位于原點的大船。
平移船體。船大小不變,移動距離也正确。
模型(Model)、觀察(View)和投影(Projection)矩陣
1、模型矩陣
這個三維模型和可愛的紅色三角形一樣,由一組頂點定義。頂點的XYZ坐标是相對于物體中心定義的:也就是說,若某頂點位于(0,0,0),則其位于物體的中心。
我們希望能夠移動它,玩家也需要用鍵鼠控制這個模型。隻需記住:縮放旋轉平移就夠了。在每一幀中,用算出的這個矩陣去乘(在GLSL中乘,不是在C++中)所有的頂點,物體就會移動。唯一不動的是世界空間(World Space)的中心。
現在,物體所有頂點都位于世界空間。下圖中黑色箭頭的意思是:從模型空間(Model Space)(頂點都相對于模型的中心定義)變換到世界空間(頂點都相對于世界空間中心定義)。
下圖概括了這一過程:
錄影機的原理也是相通的。如果想換個角度觀察一隻猴子,您可以移動錄影機也可以移動猴子
起初,錄影機位于世界坐标系的原點。移動世界隻需乘一個矩陣。假如你想把錄影機向右(X軸正方向)移動3個機關,這和把整個世界(包括網格)向左(X軸負方向)移3個機關是等效的!
下圖展示了:從世界空間(頂點都相對于世界空間中心定義)到錄影機空間(Camera Space,頂點都相對于錄影機定義)的變換。
趁腦袋還沒爆炸,來欣賞一下GLM強大的glm::LookAt函數吧:
下圖解釋了上述變換過程:
3、投影矩陣
現在,我們處于錄影機空間中。這意味着,經曆了這麼多變換後,現在一個坐标X==0且Y==0的頂點,應該被畫在螢幕的中心。但僅有x、y坐标還不足以确定物體是否應該畫在螢幕上:它到錄影機的距離(z)也很重要!兩個x、y坐标相同的頂點,z值較大的一個将會最終顯示在螢幕上。
這就是所謂的透視投影(perspective projection):
好在用一個4x4矩陣就能表示這個投影:
4、最後一個變換:
從錄影機空間(頂點都相對于錄影機定義)到齊次坐空間(Homogeneous Space)(頂點都在一個小立方體中定義。立方體内的物體都會在螢幕上顯示)的變換。
最後一幅圖示:
再添幾張圖,以便大家更好地了解投影變換。投影前,藍色物體都位于錄影機空間中,紅色的東西是錄影機的平截頭體(frustum):這是錄影機實際能看見的區域。
用投影矩陣去乘前面的結果,得到如下效果:
此圖中,平截頭體變成了一個正方體(每條棱的範圍都是-1到1,圖不太明顯),所有的藍色物體都經過了相同的變形。是以,離錄影機近的物體就顯得大一些,遠的顯得小一些。這和現實生活一樣!
讓我們從平截頭體的”後面”看看它們的模樣:
這就是您得到的圖像!看上去太方方正正了,是以,還需要做一次數學變換使之适合實際的視窗大小。
這就是實際渲染的圖像啦!
總結
第一步:建立模型觀察投影(MVP)矩陣。任何要渲染的模型都要做這一步。
第二步:把MVP傳給GLSL
第三步:在GLSL中用MVP變換頂點
搞定!三角形和第二課的一樣,仍然在原點(0,0,0),然而是從點(4,3,3)透視觀察的;錄影機的朝上方向為(0,1,0),視野(field of view)45°。