透視投影矩陣的推導


視錐體

 

 

如圖,近截面與遠截面之間構成的這個四棱台就是視錐體,而透視投影矩陣的任務就是把位於視錐體內的物體的頂點X,Y,Z坐標映射到[-1,1]范圍。這就相當於把這個四棱台扭曲變形成一個立方體。這個立方體叫做規則觀察體   (Canonical View Volume, CVV)。如下圖:

 

變換方法或規則:

如下圖,有一點P,位於視錐體內,設坐標為(x,y,z).分別對x,y坐標和z坐標的變換到[-1,1]的方式進行討論:

1.x,y坐標的變換方式:

(1)連接視點eye與P點與近裁剪面交於P’點

(2)設近裁剪面的寬度為W,高度為H,P’點的x坐標范圍是[-W/2,W/2],y坐標范圍是[-H/2,H/2],然后分別線性映射至[-1,1]內即可。

 

2.z坐標的變換方式

 z坐標的范圍是N至F,需要映射到[-1,1],映射方法暫時按下,不做想法。

 

透視投影函數形式

void Matrix4X4::initPersProjMatrix(float FOV, const float aspect, float zNear, float zFar) 

透視投影矩陣構建函數的參數:

Fov:縱向的視角大小

 

aspect:裁剪面的寬高比

zNear:近裁剪面離攝像機的距離,圖中的n

zFar:遠裁剪面離攝像機的距離,圖中的f

 

通過這幾個參數和三角函數的數學知識可以求得近裁剪面的高度,參考上圖:

 

 

 

求得點P在近裁剪面的投影點P’的坐標

 

根據相似三角形對應邊長度的比率相同,由圖可得

 

其中

 

x’,y’的范圍沿原點對稱,只要將他們分別除以W/2,H/2,即可以使范圍位於[-1,1]內。前面已求得W,H,因此:

 

 

假設

我們最后需要的坐標點P’’即是

 

推導矩陣

然后為了自動化的得到這個結果,我們使用矩陣這種數學工具,將一個矩陣乘以一個向量,得到一個新的向量,使得我們所有的運算步驟和運算數據蘊藏在矩陣和乘法中。下面的工作就是尋找到一個矩陣使得:

 

我們發現求解

很難找出合適的m00、m02,因為左邊x和z是以加法的形式相鄰,右邊z確成為了x的分母。

解決方法:將右邊的以四維列向量表示的坐標每一項乘以z,所以有:

 

 

 

所以可以求得矩陣為

 

最后求得投影矩陣為

將這樣的矩陣乘以視錐體內的一個頂點坐標,得到一個新的向量,再將這個向量的每個分量除以第四個分量(z),這樣就可以得到頂點映射到規則立方觀察體后的新的坐標。

 

注意:z坐標的映射方式的獲得,最后我們是為了方便矩陣乘法的操作反向求得了z坐標與cvv中的z坐標的映射方式:

可見兩者的映射並不是線性的,當z越大時,z的變化對z’’的擾動越小

 

代碼示例:

1 void Matrix4X4::initPersProjMatrix(float FOV, const float aspect, float zNear, float zFar) {
2     const float zRange = zNear - zFar;
3     const float tanHalfFOV = tanf(ToRadian(FOV / 2.0f));
4 
5     elements[0][0] = 1.0f / (tanHalfFOV * aspect);  elements[0][1] = 0.0f;             elements[0][2] = 0.0f;           elements[0][3] = 0.0;
6     elements[1][0] = 0.0f;                     elements[1][1] = 1.0f / tanHalfFOV;   elements[1][2] = 0.0f;            elements[1][3] = 0.0;
7     elements[2][0] = 0.0f;                     elements[2][1] = 0.0f;              elements[2][2] = (-zNear - zFar) / zRange;  elements[2][3] = 2.0f * zFar*zNear / zRange;
8     elements[3][0] = 0.0f;                     elements[3][1] = 0.0f;             elements[3][2] = 1.0f;            elements[3][3] = 0.0;
9 }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM