2013年2月5日 星期二

OpenGL projection matrix

OpenGL projection matrix

      

       為了將 3D 場景呈現在 2D 的顯示裝置, 必須透過 projection transform 3D 座標 轉換成 2D 座標, 不論是 OpenGL ES 1.1 fixed function pipeline或是 OpenGL ES 2.0/3.0 vertex shader, 都需要使用投影矩陣(projection matrix)來進行 projection transform. 根據投影方式Projection matrix 分為兩種, 分別是透視投影 (perspective projection) 以及平行投影 (parallel projection), 本文說明如何推導 OpenGL ES perspective projection matrix.




圖一是 3D coordinate轉換到 2D (screen)coordinate 的完整流程.
圖一 transform pipeline
不論是 OpenGL ES fixed function pipeline 或是 programmable pipeline, 都可以使用 (left, right, top, bottom, near, far) 六個參數定義 perspective projection matrix. 整個perspective projection matrix 的推導和第 2, 3個步驟相關, 也就是從 eye coordinate 轉換到 Normalize Device coordinate(NDC). 因為Normalize Device coordinate range 則皆為 (-1, 1), 因此步驟 2,3 等效於將 eye coordinate x 分量的數值由 (left, right) mapping (-1, 1), y 分量的數值由 (top, bottom) mapping (-1,1), 同理在 z 方向由 (near, far) mapping (-1, 1).
OpenGL ES , eye coordinate 使用右手座標系, 這表示 eye 的座標為 (0,0,0), 並看向 –Z, 如圖二所式.
圖二 perspective frustum

圖三 perspective projection

如圖三所示, 使用 camera model, 藉由相似三角形, 我們將 eye coordinate 中一個端點(Vertex) 投影到 near plane 的關係式描述如EQ1, 此為 Xp Xe 之間的關係式:

EQ1
同理可證 座標的 Y 分量如下:

EQ2
EQ1 以及 EQ2得知, Xp 以及 Yp 的數值大小和 –Ze 的倒數成比例關係, 我們用矩陣運算表示圖一中的步驟 2, 3 如下:
EQ3

有了 EQ1 以及 EQ2, 接著我們只要找出 Xp, Yp NDC coordinate 之間的關係, 我們就可以得到 eye coordinate Normalize Device Coordinate 之間的轉換關係.

本文前面已經有提到 Xp, Yp NDC 的線性關係是 [left, right] -> [-1, 1] ,  [top, bottom] -> [-1, 1], 用圖四的藍色線段表示這個關係:

圖四  Xp, Xn 對應關係圖
以直線方程式 y = mx+b表示圖中的藍色線段, 得到:
EQ5
Xp=R, Xn = 1 帶入 EQ5, 解出 b 如下:
EQ6
解出 b , 帶入EQ5 Xn Xp 的關係式如下:
EQ7
EQ1帶入 EQ7, 我們可以推導 Xn Xe 的關係式如下:

EQ8
EQ8 中的 1/-Ze 就是圖一中的第 3 步驟 Divided by W, EQ8 的分子部分是 EQ3 Xc另外, 用同樣的方法可以推導Yn Ye 的關係, 所以完成了projection Matrix 一部分的內容如下:
EQ9
接下來是projection matrix 第三列,  Zc Ze 的關係. 這部分可以參考書籍 : 3D Computer Graphics; Alan Watt
根據先前推導 Xc, Yc的假設, 所有Ze皆會投影到 near plane , 也就是 –n, 但是我們需要每個 vertex depth 以方便rasterization進行 per-pixel depth testing. 因此Zc Ze 的關係不同於 Xc Xe 或是 Yc Ye 的推導方式. 我們需要借助 We. EQ9 改寫如下:
EQ10
EQ3, 
EQ11
eye coordinate, We = 1:
EQ12
Zn = -1, Ze = -n 帶入 EQ12:
EQ13
Zn = 1, Ze = -f 帶入 EQ12:
EQ14
EQ13 的結果帶入 EQ14:
EQ15
EQ15 的結果再帶入 EQ13 解出 B:
EQ16
A, B 分別帶入EQ12::
EQ17
到此, 已經推導出 projection matrix 第三列的內容, 列出完整的 projection matrix 內容如下:

EQ18
.END

1 則留言: