透視投影,與Z BUFFER求值

2021-08-22 17:20:39 字數 3785 閱讀 7229

透視投影,與z buffer求值 為什麼有透視。因為眼球是個透鏡。假如地球生物進化的都靠超聲波探測空間,那也許眼睛就不會有變成球,而是其他形狀... 為什麼有人玩3d頭暈?其中乙個重要的作用是,眼球不完全是個透鏡。所以當視野大於60度,螢幕四周投影的變形就比眼球投影視網膜利害多。而且人腦習慣了矯正眼球投影的資訊。突然有個螢幕上粗糙的模擬眼球成像,大腦還真一時適應不了。

z buffer數值計算,以及perspective projection matrix設定,使用d3d或者opengl,可以直接讓顯示卡完成這些工作。但是弄清z buffer如何計算,以及project matrix的原理。對於進行各種高階影象處理,非常有用。例如shadowmap的應用。目前為了得到好的shadowmap,很多人在如何加大shadowmap精度做了很多努力(改變生成shadowmap時的perspective project matrix來生成精度更合理的shadowmap) 。比如透視空間的perspective shadow map,light空間的light-space perspective shadow,perspective shadowmap變種trapezoidal shadow maps,改正交投影為對數引數投影的 logarithmic shadow maps。另外,doom3中shadow volume採用的無限遠平面透視矩陣繪製stencil shadow volume。都需要對perspective projection有透徹了解。

以下描述z buffer計算以及perspective projection matrix原理。

假設座標在 world space 是 pw =

經過camera space transform 得到 pe =

然後經過project transform 轉為 device space,這裡假設轉為 zp 範圍 [-1,1](openg的z buffer)

pe在near平面的投影為: xep = n* xe/(-ze) (n為近平面到eye距離). 注意這裡opengl 右手系camera space是z軸負方向為眼睛看的方向。當計算投影時,x,y都應該除以乙個正的數值。所以ze取負。

這麼做的目的是為了讓在view space中所有在視錐平截體內的點,x數值投影到近平面上,都在near平面上的left到right。 接下來是求最後在device space裡x,y,z的數值,device space是座標為-1到1的立方體。其中x/2+0.5,y/2+0.5 分別再乘以視窗長寬就是螢幕上畫素的位置。那麼螢幕這個畫素的z數值就可以按以下方法求出: 需要把view space中(left,right,top,bottom,near,far)的frustum轉換到長寬為(-1,1)的正方體內,就是說,把xe,ye,ze都對映到[-1,1]的範圍內。前面已經求出了xe在camera space near平面上的投影xep。這個投影的數值就是在frustum平截體near平面上的位置。 把平截體near平面對映到-1,1的正方形很簡單,x方向按如下對映: xp = (xep - left)*2/(right-left) -1 。

當xep在left到right變化時,xp在-1到1變化。xp就是z buffer數值。 因為顯示卡硬體(gpu)的掃瞄線差值都是透視矯正的,考慮投影後,頂點xp和yp都是 1/(-ze) 的線性關係。那麼在device單位立方體內,zp 的範圍在[-1,1]之間,zp也就是z buffer的數值。根據前面推導,要保證透視校正,zp也是以1/(-ze)的線性關係。即,總能找到乙個公式,使得 zp = a* 1/(-ze) + b。

也就是說,不管a和b是什麼,在z buffer中的數值,總是和物體頂點在camera space中的 -1/ze 成線性的關係。 我們要做的就是求a 和b。 求a和b,我們利用以下條件: 當ze = far 時, zp = 1 當ze = near時,zp = -1(在opengl下是這樣。在d3d下是zp =0) 這實際是個2元一次方程。有了兩個已知解,可以求出a和b。opengl下, a = 2nf/(f-n), b = (f+n)/(f-n)

這樣一來,我們就知道z buffer的數值如何求得。先把物體頂點世界座標pw變換到camera space中得到pe。然後再經過透視投影變換,求得ze->zp的數值。把這個數值填入z buffer,就是顯示卡用來比較哪個畫素在前,哪個畫素在後的依據了。 這也就是為什麼near和far設定不合適的時候,很容易發生z fighting。一般情況下,離螢幕很近的一段距離,已經用掉了90%的z 浮點精度。在用於渲染視角裡中遠距離的場景時,深度的判別只靠剩下的10%精度來進行。 具體推導可以看看

逐漸被d3d拋棄的w buffer,場景遠近與w數值是線性的。即,100公尺的距離,在near=1 far=101時,每一公尺在d3d w buffer的表示中,就是差不多 1/100 那麼大。但是在z buffer中就完全不是均勻分配。

下面考慮perspective projection matrix。 根據線性代數原理,我們知道無法用乙個3x3的matrix對頂點(x,y,z)進行透視對映。無法通過乙個3x3的矩陣得到 x/z 的形式。進而引進齊次座標矩陣---4x4 matrix。頂點座標(x,y,z,w)。 齊次座標中,頂點(x, y, z, w)相當於(x/w, y/w, z/w, 1)。 看到這個頂點座標,我們會聯想到前面我們最終求出的z buffer數值zp和單位device space中的xp座標。利用矩陣乘法,可以得到乙個矩陣mp,使得(xe,ye,ze,1)的頂點座標轉換為齊次座標規一化後的 (xp,yp,zp,1) 。 即: vp = mp * ve . vp是單位裝置座標系的頂點座標(xp,yp,zp,1)。ve是camera space頂點座標(xe,ye,ze,1)。

考慮 xp = (xep - left)*2/(right-left) -1 (xep = -n* xe/ze) yp = (yep - left)*2/(right-left) -1 (yep = -n* ye/ze) zp = a* 1/ze + b

為了得到4x4 matrix,我們需要把(xp,yp,zp,1)轉為齊次座標 (-xp*ze, -yp*ye, -zp*ze, -ze) 。然後由矩陣乘法公式和上面已知座標,就可以得到projection matrix。

xp*(-ze) = m0 m1 m2 m3 xe yp*(-ze) = m4 m5 m6 m7 x ye zp*(-ze) = m8 m9 m10 m11 ze -ze = m12 m13 m14 m15 1

這裡拿 m0, m1, m2, m3 的求解來舉例: m0* xe + m1* ye + m2* ze + m3= (-ze)*(-n*xe/ze-left )*2/(right-left) +ze m1 = 2n/(right-left) m2 = 0 m3 = (right+left)/(right-left) m4 = 0

最後得到opengl 的 perspective projection matrix:

[ 2n/(right-left) 0 (right+left)/(right-left) 0 ] [ 0 2*near/(top-bottom) (top+bottom)/(top-bottom) 0 ] [ 0 0 -(far+near)/(far-near) -2far*near/(far-near) ] [ 0 0 -1 0 ]

d3d 的左手系透視投影矩陣和opengl有以下區別。 1, d3d device space 不是個立方體,是個扁盒子。z的區間只有[0,1] 。x,y區間還是[-1,1] 2,d3d的camera space z軸朝向正方向,計算camera space中投影時不用 xep = n*xe/(-ze), 而是 xep = n*xe/ze 3,d3d中,從camera space的視椎平截體到device space的單位體(扁盒子)攝影,採用了很奇怪的作法。把frustum右上角對映為device單位體的(0,0,0)位置

請re d3d perspective projection matrix推導過程~

Android OpenGL透視投影

首先申明下,本文為筆者學習 opengl es應用開發實踐指南 的筆記,並加入筆者自己的理解和歸納總結。1 透視除法 opengl會把每個gl position的x y和z分量都除以它的w分量。當w分量用來表示距離的時候,會使得較遠處的物體被移動到距離渲染區域中心更近的地方。新增w分量建立三維圖 p...

透視投影矯正

答案 因為投影矩陣變換後,線性關係變了。假設矩陣變換前,b是a和c兩個點的線性插值,b ta 1 t c,其中b是由a和c插值而來的。變換後a變成了a c變成了c 直接將b進行透視變換成了b 變換前即使 b ta 1 t c 三個點各自變換後,發現b ta 1 t c 推導過程不難,我看了兩種。但是...

透視投影矩陣

1.將投影面上x,y,z方向上的點,投影到剪裁空間有一定比例關係 2.y方向上的比例關係 y y0 y y0 z tan fov 2 y y tan fov 2 z 讓f 1 tan fov 2 y f z y 3.x方向上的比例關係 x f z x 根據相似三角形原理 tan fovx 2 tan...