午夜视频在线网站,日韩视频精品在线,中文字幕精品一区二区三区在线,在线播放精品,1024你懂我懂的旧版人,欧美日韩一级黄色片,一区二区三区在线观看视频

分享

OpenGL學習腳印: 投影矩陣的推導

 方海龍的書館 2014-10-28

OpenGL學習腳印: 投影矩陣的推導

寫在前面

               本節(jié)內容翻譯和整理自http://www. songho的博客《OpenGL Projection Matrix》內容,以供自己和初學者熟悉投影矩陣推導過程。

通過本節(jié),你可以了解到:

  •  投影矩陣計算的階段
  •  透視投影和正交投影的矩陣推導
本節(jié)的要點就在于:   閱讀時,自己拿筆推導一遍。

1.概覽

計算機屏幕是2維的,OpenGL渲染的3D場景必須以2D形式的圖像投影到屏幕上。GL_PROJECTION 矩陣就是用來設置投影變換的。首先,它將所有頂點從眼坐標(照相機坐標)轉換到裁剪坐標系下。然后,這些裁剪坐標通過透視除法,即除以裁剪坐標中w分量,轉換到歸一化設備坐標系(NDC)

                                                                                                                               
                                                                                                      一個由視錐裁剪的三角形

因此,我們要記住,裁剪(視錐剔除frustum culling)NDC轉換都集成到了GL_PROJECTION 矩陣。接下來的部分描述了怎么樣通過left, right, bottom, top, near and far 這6個界限參數(shù)來構造投影矩陣。

注意:

   視錐剔除是在裁剪坐標系中進行的,并且恰好在透視除法之前進行。裁剪坐標xc, yc 和 zc 通過與wc比較來進行測試。 如果某個坐標值比Wc小或者比Wc大,那么這個頂點將被丟棄。然后,OpenGL會重新在裁剪進行的地方構造多邊形的邊緣。

補充內容:

實際上,眼坐標系下坐標在乘以投影矩陣后,裁剪測試和透視除法都是由GPU來執(zhí)行的。而后面這兩個過程處理的裁剪坐標系數(shù)據(jù)都是由投影矩陣變換的。

1. 裁剪測試也即視錐剔除

-Wc < Xc,Yc,Zc < Wc

2. NDC透視除法

Xn = Xc / Wc  Yn = Yc / Wc   Zn = Zc / Wc

這里需要注意的是,我們在構造16個參數(shù)的投影矩陣的同時,不僅要考慮到裁剪,還要考慮到透視除法的過程。這樣,最終的NDC坐標才會滿足:

-1 < Xn,Yn,Zn < 1

2.透視投影

在透視投影中,在眼坐標下截頭椎體(a truncated pyramid frustum)內的3D點被映射到NDC下一個立方體中;x坐標從[l,r]映射到[-1,1],y坐標從[b,t]映射到[-1,1],z坐標從[n,f]映射到[-1,1]。

注意:

     眼坐標系使用右手坐標系,而NDC使用左手坐標系。這就是說,眼坐標系下,在原點處的照相機朝著-Z軸看去,但是在NDC中它朝著+Z軸看去。因為glFrustum() 僅接受正的nearfar距離,我們在構造GL_PROJECTION 矩陣時,需要取其相反數(shù)。眼坐標系和NDC坐標系如下圖所示:



OpenGL,眼坐標下3D點被投影到近裁剪面(即投影平面)。下圖展示了眼坐標系下點(xe, ye, ze) 如何投影到近裁剪面上的 (xp, yp, zp) 的。(左側是視錐的俯視圖,右側是視錐的側視圖,拿出右手構成右手坐標系,然后比劃比劃就出來了)


根據(jù)三角形的相似性,由俯視圖可得出:

由側視圖可以得出:

補充: xp 和yp其實是一個中間值,我們要找的是(Xc, Yc, Zc)和 (Xn, Yn, Zn)之間的關系,但是可以利用:

這一關系做過渡,后面利用xp和yp,映射到NDC中xn和yn的線性關系就利用到了 xp 和yp。這一點很重要。


注意,這里 xp 和yp 都依賴于ze,他們與 -ze成反比。換句話說,他們都被 -ze相除。這個事構造GL_PROJECTION    矩陣最初的線索。在眼坐標通過乘以 GL_PROJECTION    來轉換時,裁剪坐標系仍然是一個齊次坐標系。通過對裁剪坐標進行透視除法得到最終的NDC坐標。下圖解釋了這個過程:


因此我們可以把裁剪坐標系下的w分量設為-ze,那么GL_PROJECTION矩陣第4行變?yōu)?0, 0, -1, 0),如下圖(求出了投影矩陣第4行):


下現(xiàn)在我們把xp和yp,映射到NDC中xn和yn,他們之間是線性關系: [l, r] ? [-1, 1]和[b, t] ? [-1, 1].

線性關系如下圖所示:

則可以推導出:

細節(jié)部分有刪節(jié),這個推導過程使用的就是簡單的y=kx+b線性關系推導,同理利用[b, t] ? [-1, 1]可推得:

將上面的 xp 和yp帶入求得:

注意這里Xn和Yn已經(jīng)是NDC中的坐標了,通過這兩個坐標可以求出GL_PROJECTION 的前兩行來,書寫如下(求出了投影矩陣第1,2,4行):

現(xiàn)在怎么求出第3行呢?

找出zn與找出xnyn不同,因為 ze總是被投影近裁剪面-n上。但是我們需要唯一的Z值進行裁剪和深度測試。另外,我們還能夠unproject即反向變換(inverse transform)。因為Z值不依賴于x或者y,因此我們借用w分量來找出 zn 和 ze之間的關系。

因此我們可以這樣指定第3行:

在眼坐標下We等于1,因此上式變?yōu)?

我們使用(ze, zn)的關系(-n, -1)和 (-f, 1)來求解出系數(shù)A,B;

細節(jié)部分有刪節(jié),使用消元法即可求出:

我們求出了A和B,那么ze和zn關系如下式:

最終的投影矩陣如下式:

這個公式對應的是一般的視錐,如果視錐是對稱的,即r = -l ,t= -b,那么有:

z-fighting

在繼續(xù)之前,我們來看看表示ze和zn關系的式3.這是一個有理函數(shù),并且ze和zn之間不是線性關系。這意味著,在近裁剪面的精度很高,而遠裁剪面則很小。如果[-n, -f]范圍變得大寫,就會引起深度精度問題,即z-fighting。在遠裁剪面附近,ze的小變化根本不影響zn值。近裁剪面和遠裁剪面之間的n和f舉例,應該盡可能小,來減少深度緩存的精度問題??蓞⒖枷聢D來幫助理解。


3.正交投影

構造正交投影的矩陣簡單很多。所有的是眼坐標下xe, ye 和ze,都被線性的映射到NDC中。我們需要做的就是講長方體視景體縮放為規(guī)范視見體,然后移動到原點。如下圖所示:

以xe和xn之間映射關系為例,[l,r]=>[-1,1],則可以推導如下:

y,z也有類似推導,這里省略,最后得出投影矩陣為:

如果視錐是對稱的話,即r = -l ,t= -b的話,則可以簡化為:


到這里透視投影和正交投影矩陣推導完畢。


    本站是提供個人知識管理的網(wǎng)絡存儲空間,所有內容均由用戶發(fā)布,不代表本站觀點。請注意甄別內容中的聯(lián)系方式、誘導購買等信息,謹防詐騙。如發(fā)現(xiàn)有害或侵權內容,請點擊一鍵舉報。
    轉藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多