1. 程式人生 > >OpenGL中frustum投影矩陣的推導

OpenGL中frustum投影矩陣的推導

OpenGL中,有一個函式叫frustum,字面的意思是截錐體,也就是一個去掉頭部的錐體,如下圖所示,

看了一下《計算機圖形學》(英文名Computer Graphics with OpenGL)的透視投影推導過程,比較全面,各種情況都有描述。不過最近又參考了網上的一些資料,發現這裡【1】的推導過程比較單純直接。我們看一下,

注意到上面這個圖,觀察者的位置相對於(0,0,0)這個點是在右邊的,也就目光是沿Z軸方向(所以距離 眼睛越近,顯得越大嘛),OpenGL的camera也就是(0,0,0)點,沿-Z方向。

把xe對映到xp,ye對映到yp是這樣的,

    式(1)

通過Mprojection矩陣,把eye座標投影到NDC空間(Normalized

 Device Coordinates, 歸一化裝置座標系),

注意下上面的ndc和clip座標系之間,只差了一個係數 wclip,他們都是3維齊次座標【2】。下面這個方程中,c就是clip,變換矩陣的第4行設定為(0, 0, -1, 0),為什麼呢?因為這一行實際上只處理係數wc,看前面我們知道xp與yp分別和(-Ze)成反比,所以這裡我們也期望,wc和(-ze)成反比,且最後能歸一化wc/(-ze)=1。

接下來的一步,就是完成xp,yp到xn,yn的歸一化對映:[l, r] ⇒ [-1, 1] and [b, t] ⇒ [-1, 1],首先來看對映[l, r] ⇒ [-1, 1],如下圖

這是一個非常簡單的線性對映,寫成方程式就是,

其中\beta就是xp=0時在xn軸上的截距,根據對映,當xp=r時,xn=1,代入到該式中,就可以得到,

然後變換一下格式,

現在把\beta代回最上面那個式子,就得到了,

 式(2)

同樣的道理,可以得到

         式(3)

把式(2),式(3)代回到式(1),就得到這樣一個結果,

這兩個結果,結合我們前面得到的wc=-ze,整個矩陣就可以等價地寫成下面的形式,

現在只有矩陣的第3行是未知的,我們這樣處理,

因為在eye的空間,we=1(w是一個和透視距離有關的量,0表示無窮遠點,參考【2】),所以,

,和上面的道理類似,對映  (ze, zn)滿足範圍為近點=(-n, -1),遠點= (-f, 1), 

求解該線性方程組,得到,

這樣,得到

 式(4)

最後得到的矩陣就可以寫成

這個矩陣,也正是我們frustum函式變換所採用的矩陣。

這裡也順便提一下Z-finghting。根據式(4),Zn和Ze的關係為

因此,當[-n, -f]的距離比較大的時候,因為有理數取值都有誤差,在遠點就容易形成z-finghting,也就是當兩個實體在遠點有交接時,因為誤差產生的距離抖動,無法準確得到交接線從而產生類似下圖的結果,

本文結束。

參考