關於學習投影矩陣的隨筆

2022-07-29 04:30:11 字數 2712 閱讀 2179

最好請查閱關於opengl與d3d中投影矩陣推導的相關部落格,再看此篇。(主要是記錄給自己看,幫助理解,以供以後修正優化,舉一反三之用,所以會有晦澀或者不詳細之處,請諒解,如果能幫助到正好需要的小夥伴那就更好了,自己也是圖形學的初學者,歡迎交流和指正)。

d3d中 投影矩陣的推導:

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

兩者都是關於投影矩陣的推導思路和相關公式,區別是乙個是opengl版本乙個是d3d版本,具體差別是兩者的預設座標系(前者中的眼座標系)不同(opengl是右手座標系,d3d是左手座標系),歸一化裝置座標系(兩者都是右手座標系,所以數值中帶負號的一般是opengl的投影矩陣,不帶的就是d3d(其實這麼說,很不完善。),兩篇文章中都用列矩陣來表述投影矩陣,這點要注意)大小不同(主要是z值的範圍不同,opgl版本中稱為ndc(normalized device coordination),d3d版本中稱為規範視域體(canonical view volume)),所以就導致最後的成像投影矩陣略有差別(原理和過程其實相似,表述的差別而已)。

對了,插乙個概念,由於投影變換,是與攝像頭的方位都有關係的(設想乙個旋轉或者平移的攝像機,它所呈獻的畫面肯定是變化的),而這與投影矩陣沒有關係,因為投影矩陣把這些條件先確定下來(比如始終位於原點,方向始終是z軸平行(opengl中是z軸負方向,d3d中是z軸正方向))。而比如攝像機的方位對於最後成像的影響,在此投影矩陣得出後,再叉乘該攝像機方位矩陣,就可以了。(其實就是成像先後的關係和矩陣的相互關係思考清楚就可以了,投影矩陣是確定視椎體後的固有屬性,與攝像機的方位無關,與成像有關。又可以說投影矩陣其實就是確認視椎體的形狀,大小與ndc形狀之間的對應關係而已。)

但是這邊特地給出兩個版本的鏈結,並不是要畫蛇添足的介紹兩次。其實是兩者的推導略有不同。或者詳略各有差異,結合來看才能更清楚,投影矩陣的原理和推導的過程。

推薦先看d3d版本的推導,因為其中先介紹了正交投影(orthographic projection)的推導過程及原理。正交投影就是將裁剪後的視域(稱為view volume)座標轉換到ndc中,就是兩個變換——平移(使得原點重合)和縮放(使得大小相同),由於是平移和縮放,變換順序可以交換(矩陣叉乘的順序是不能隨便變換的,此處特殊(由矩陣叉乘的特性來決定的,詳細的解釋可以查閱相關資料))。

投影矩陣的推導原理,這邊也要解釋下這兩篇文章沒有詳細說明的地方,就是通過射線投影的原理得到近介面的對應點,但是此近截面上的點並不是最後ndc中的最後目標點,但是可以根據此點的x,y座標得到最後目標點的x,y座標與原始x與y的關係,但是因為近截面的z值始終是n,也就是捨棄了沿著投影原點射出的射線上的z值,要理清這個概念,那z值的對應關係怎麼確認呢,就是通過齊次變化中的w值,來做減維處理(具體看opengl那篇文章,說的明白些,推薦結合3d基礎數學:圖形與遊戲開發中的投影變換來理解)。(再插一句,就是要理解任何乙個維度的點,都可以用更高維度的形式去表示,簡單來說比如二維空間中的a點(x,y)到三維空間中就可以表示(x,y,1),可以理解為投射到z=1平面上的點((x,y,1)投影到z=1平面不就是它本身麼?擴充套件開來說(x*z,y*z,z)這個集合裡的點投影到z=1的平面上時,都與(x,y,1)重合,也就可以說是同一點。所以以此來理解4維甚至更高維度的現象(其實,我也很難想象更高維度的具體表現,我覺得是無法用這種3維座標系表示圖去展示4維甚至更高維投影到低維的表現,但是可以從數學層面去推。)同理,3維空間中的(x,y,z)點就是4維空間中的(x,y,z,1)點,也就是和(x*w,y*w,z*w,w)點關於w=1的平面上的投影點重合(其實這麼說不對,應該說是w=1的3d座標系重合)。這也是下面推導的思考基礎。))

通過相似三角形原理和正交投影的公式和推導過程我們知道了

,那怎麼消除z值呢?怎麼得到z'與z的關係呢?(這裡暫時都用d3d公式)

貌似想不出來,只能按照文章中的方法,試圖去求z'z的值,然後通過(x'z,y'z,z'z,z)投影到w = 1 的3d座標系中不就是(x',y',z',1)該點麼。該投影過程就是降維過程,也就是齊次變換。

那現在的問題就是怎麼求得(x,y,z,1)到(x'z,y'z,z'z,z)的變換矩陣了。這就是透視投影矩陣~!

然後就是文章中的,根據

先求的這個4x4矩陣的第一行,第二行(列向量),也就是[2n/(r-l),0,-(r+l)/(r-l),0]和[2n/(t-b),0,-(t+b)/(t-b),0].

然後第四行的[a4,b4,c4,d4]*[x,y,z,1] = z,因此第四行為[0,0,1,0]

那麼只剩第三行[a3,b3,c3,d3]求值了。a3*x+b3*y+c3*z+d3 = z'z;其實x,y的值不能影響到z'與z的對應關係,所以其對應係數就應該是0,所以變成 c3*z+d3 = z'z,轉成z『=c3+d3/z;發現兩者原來是倒數關係。(這也是z-fighting的原因,當然了只要精度足夠大就沒有z-fighting問題,但是問題就是浮點數的精度是有限制的。)然後帶入兩對已知值,z』=ndc中的最小值時,z也是近介面上的值,即z'=0,z=n。z』=ndc的最大值時,z也是遠截面上的值,即z『=1,z=f;

求得 第三行就是[0,0,f/(f-n),-fn/(f-n)]

因此

別忘了將結果做其次變換後得到(x』,y',z',1);

OpenGL 投影矩陣的推導

計算機顯示器是乙個2d平面。opengl渲染的3d場景必須以2d影象方式投影到計算機螢幕上。gl projection矩陣用於該投影變換。首先,它將所有定點資料從觀察座標轉換到裁減座標。接著,這些裁減座標通過除以w分量的方式轉換到歸一化裝置座標 ndc 本文主要推導正交投影矩陣和透視投影矩陣。注意n...

透視投影矩陣的構建

投影矩陣最終建立的是乙個平截頭體 也可以稱為臺 在這種變換下呈現遠小近大的效果。這裡我將我學到知識記錄下來,以後備忘用。首先是使用opengl的glfrustum函式,它要求傳入的是前後 左右 上下等引數,這要求這個平截頭體是軸對稱的。由它構成的矩陣是為 如果我們使用的不是glfrustum,而是g...

3D 投影矩陣學習1

先看一下名詞 在矩陣數學中,也有乙個名詞叫投影矩陣,其定義為 若矩陣a既是對稱矩陣,又是冪等矩陣,則稱a為投影矩陣。這裡說的是3d世界中的投影矩陣 其作用是幫助把3d物體顯示在2維計算機平面。什麼是投影 計算機顯示器是乙個二維表面,所以如果你想顯示三維影象,你需要一種方法把3d幾何體轉換成一種可作為...