現實中“二向箔” -----透視投影變換及其投影矩陣


有沒有想過這樣的問題,計算機是如何把3維的模型顯示到2維的屏幕上?照相機又是如何把3維的世界記錄成2維的照片的?

發現了嗎?世界被降維了!而投影矩陣(  Projection Matrix  )就是進行這步降維的關鍵,它就像是一張二向箔,將3維的世界變成一幅幅壯麗的二維畫卷.......
 
有多種類型的投影,比如說正交投影( Orthographic Projection )、透視投影等(Perspective Projection ) 。
人的眼睛使用的是 透視投影,在這種投影下,同樣大小的物體放在近處就會顯得比放在遠處大。
 
在這里使用OpenGL里對透視投影矩陣的定義來介紹
 
透視投影矩陣要解決一個問題:一個三維坐標上的點,它在一個二維平面(像平面)上的坐標是多少?
 
相機是小孔成像模型,所有被采集到的光線都要通過光心這一點,於是光心(紅點)和原始三維點(藍點)的連線所交於像平面(藍線)的點(黃點)就是最終要成像的點。像平面距離光心的距離為n。如下圖,假設相機是朝Z軸的負方向看的,並且Z軸穿過光心和像平面的中心。

哎,有讀者嫌棄我畫的圖太丑,其實我也是這么覺得的,沒那么多時間畫圖(好像有時間就能畫好似的....)。下面就用參考資料里的圖吧。
細心的讀者會發現圖中多個一個平面,距離光心得距離是f,這個平面的意義在於z的值小於-f的點都不會投射到像平面上。至於為什么要多這個far平面嘛.....大家看到最后就會明白了。<( ̄︶ ̄)>

好了,如圖所示,根據相似三角形原理,就可以求出一個三維點(xe,ye,ze)在像平面上的坐標(xp,yp)。
另外,根據opengl的實現,需要將坐標轉化成 NDC(normalized device coordinates) ,簡單來說,就是定義一定范圍的坐標范圍,這個范圍形成一個類似錐型的區域(frustum),將這個區域內的坐標按照3個坐標軸的方向映射成[-1,1]的值,最終形成一個立方體。
如圖所示,例如z=-n的平面被映射成z=-1,z=-f的平面被映射成z=1。
原先的x坐標從[l,r] 被映射成x坐標為[-1,1]
原先的y坐標從[b,t] 被映射成y坐標為[-1,1]。
 
現在我們需要把這些坐標的變化寫成矩陣的形式,寫成矩陣 M projection
但是 像平面上的坐標(x p ,y p )的計算公式中是有除法的,這樣的話就沒辦法寫成線性的矩陣運算的形式了。沒關系,我們可以使用3維點的 齊次坐標(Homogeneous Coordinates) 來運算。

最終就可以獲得NDC坐標(發現沒?除法出現了!):
 
需要構造出M projection
因為最后需要除的數是-Ze, 所以需要保證W clip的值為-Ze, 於是 M矩陣的最后一行應該為[0 0 -1 0].。
 
其次,要保證除x和y要被線性映射成[-1,1]。

 先設計一個線性方程:

當x p = r 時 x n=1
求解出
又:
看上是不是就可以寫成矩陣形式了?
同理可以獲得y方向上的坐標轉換公式,就得到了前兩行矩陣:
接下來就只剩下第三行需要求解了。
我們知道z的值是不依賴x和y的,於是第三行的前兩個元素為0,設另外兩個值為A、B:
最終得到的坐標為:
齊次坐標下的w是等於1的,所以等式變為:
要求解A、B怎么辦?找兩個點代入進去呀。
這兩個點為(-n, -1) 和 (-f, 1)。於是:
解得
最終,得到了完整的投影矩陣:
注意到沒!Z e和Z n的關系不是線性的!
在接近near平面時精度高,在接近far平面時精度低,如果far和near相距較大時,就會產生深度精度問題(z-fighting),所以在滿足需求的情況下,far和near要盡可能接近。
 
好了,世界就這樣被二維化了,Enjoy it!

 

參考資料

http://www.songho.ca/opengl/gl_projectionmatrix_mathml.html


 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM