1. 程式人生 > >OpenGL投影矩陣

OpenGL投影矩陣

目錄

綜述

電腦螢幕是2D表面,必須將OpenGL渲染的3D場景作為2D影象投影到計算機螢幕上,所以就需要用到投影變換MpM_p。首先,MpM_p將所有頂點資料從眼睛座標轉換為裁剪座標。然後,這些裁剪座標的各分量(x,y,z)通過除以w分量被變換到規範化座標(NDC)。所以MpM_p其實做了兩步操作:

  1. 將相機空間座標變換到投影空間
  2. 將投影空間座標變換到NDC空間

因此,我們必須記住裁剪(視錐體剔除)和NDC變換都整合到了MpM_p變換中,下面的章節描述了怎樣從left、right、bottom、top、near、far這6個引數構造投影矩陣MpM_p。需要注意的是視錐裁剪是在各個分量(x

cx_cycy_czcz_c)除以wcw_c之前完成的。xcx_cycy_czcz_c通過與wcw_c作比較,如果任何裁剪空間座標比wc-w_c小,或者比wcw_c大這個座標都將會被丟棄。wc<xc,yc,zc<wc-w_c<x_c,y_c,z_c<w_c 然後,OpenGL將重繪發生剪下的多邊形邊緣(如下圖所示)。 在這裡插入圖片描述

透視投影

在透視投影中,一個3D點在從金字塔平截頭視錐體空間(相機空間)被對映到一個立方體空間(NDC);其各分量範圍被如下對映: x: [l,r]->[-1,1] y: [b,t]->[-1,1] z: [-n,-f]->[-1,1] 在這裡插入圖片描述

注意,相機空間是在右手座標系中定義的,但是NDC使用的是左手座標系。也就是說,原點處的相機沿著相機空間中Z-Z軸看,但是在NDC空間中它是看向+Z+Z軸的。由於**glFrustum()**的near和far引數只接受正數,所以我們需要在構造投影矩陣的時候讓Z軸反向。

在OpenGL中,一個在相機空間的3D點會被投影到近平面(投影平面)上。下圖展示瞭如何將相機空間中的點(xe,ye,ze)(x_e,y_e,z_e)投影到近平面上(xp,yp,zp)(x_p,y_p,z_p)在這裡插入圖片描述

從視錐體的頂檢視來看,相機空間的x座標,xex_e

e被對映到xpx_p,其通過使用相似三角形的比率來計算,如下所示: 在這裡插入圖片描述

從視錐體的側檢視來看,ypy_p也是類似的方式計算: 在這裡插入圖片描述

注意,xpypx_p和y_p取決於zez_e;他們與ze-z_e成反比。換句話說,他們都被ze-z_e除。這是構造投影矩陣MpM_p的第一條線索。在通過乘以MpM_p矩陣來變換眼睛座標系之後,裁剪座標仍然是齊次座標。它最終需要變為歸一化裝置座標(NDC),所以還需要除以裁剪座標的ww分量。 在這裡插入圖片描述

因此,我們可以將裁剪座標的ww分量設定為ze-z_e。並且,MpM_p矩陣的第4行變為(0,0,1,0)(0,0,-1,0)在這裡插入圖片描述

接下來,我們將xpx_pypy_p對映到具有線性關係的NDC空間的xnx_nyny_n: [l,r]⇒[-1,1] [b,t]⇒[-1,1] 在這裡插入圖片描述

然後,我們將xpx_pypy_p代入上述方程式。 在這裡插入圖片描述

注意,我們使每個方程都除以ze-z_e,以進行透視除法(xc/wc,yc/wc)(x_c/w_c,y_c/w_c).我們之前將wcw_c設定為ze-z_e,並且括號內術語變為裁剪座標系的xcx_cycy_c

從這些方程式中,我們可以找到MpM_p的第1行和第2行。 在這裡插入圖片描述 現在,我們只有用第3行的MpM_p來解決。znz_n與其他演算法略有不同,因為相機空間中的zez_e總是被投影到近平面上的n-n。但是我們需要用於裁剪和深度測試的唯一z-z值,並且在以後我們不會去逆變換深度值。由於我們知道z不依賴於x或y值,因此我們借用ww分量來找到znz_nzez_e之間的關係,可以像下面這樣指定MpM_p的第3行。 在這裡插入圖片描述 在相機空間中,we=1.0w_e=1.0因此等式變為: zn=Aze+Bzez_n= \frac{Az_e+B}{-z_e} 為了找到係數A和B,我們使用(ze,zn)(z_e,z_n)的關係;(n,1)(-n,-1)(f,1)(-f,1),並將它們放入上面的等式中。 在這裡插入圖片描述 為了求解A和B的等式,重寫B的等式(1): B=Ann(1)B=An-n (1') 將方程(1’)代入方程(2)中的B,然後求解A: 在這裡插入圖片描述 將A放入方程(1)中以找到B : 在這裡插入圖片描述

我們找到了A和B,因此zez_eznz_n的變換如下: 在這裡插入圖片描述 最終,我們找到了全部MpM_p矩陣的元素,完成的矩陣如下所示: 在這裡插入圖片描述 上述矩陣是通用的視錐體矩陣。如果視錐是對稱的(r=lr=-lt=bt=-b),那麼它可以被簡化為如下矩陣: 在這裡插入圖片描述

在離開之前,請再看一下等式(3)中