OpenGL投影矩陣的構造

參考:html

http://www.songho.ca/opengl/gl_projectionmatrix.html數組


3D空間中的對象,最終顯示在屏幕上,須要進行一系列的矩陣變化,將其從世界空間,轉化到屏幕上。緩存

座標的具體轉化過程是:數據結構


世界座標world---->視座標eye-----》不一樣的投影方法(平行投影,透視投影)投影面上座標--->正則座標(將可視體轉化成2*2*2的正方體)---->屏幕座標(像素點)htm

其中modelView矩陣 將世界座標轉化到eye座標,  而projection矩陣將視座標轉化到正則座標, 以後的像素生成不禁咱們控制。對象


Opengl使用的矩陣和通常數學中使用的矩陣不一樣,二者互爲轉置(transpose), 這有點相似於2維數組存儲時行有先仍是列優先的問題, 普通是行優先, 而OPENGL採用的是列優先的存儲方式。(詳細見數據結構---數組---多維數組的存儲方式)get


有了以上討論,要構造一個投影矩陣就須要知道:數學

   採用的投影方法, 如何轉化到正則座標io


照相機的座標系:照相機在原點, 面朝Z負方向, 向上是y軸。model


可視體:平行投影中是一個和照相機座標軸平行的立方體, 由left right bottom top near 和 far 6個值來定義, 其中near表示 近平面距離照相機的位置, far表示遠平面距離照相機的距離

下圖是一個平行投影的可視體。

1:平行投影

        對於任意在這個可視體中的點,咱們須要將其轉化到一個正則可視體的座標系中2*2*2

        即將[left, right]->[-1, 1]  [-near, -far]-->[-1, 1]  [bottom, top]->[-1, 1]

        假設點的eye座標: xe ye ze we

        則正則座標  xn yn zn wn


        其中wn 應該是1 表示沒有透視效果

        xn = (1-(-1))/(R-L)*(xe-L)+-1

        yn = (1-(-1))/(T-B)*(ye-B) + -1 

        zn = (1-(-1))/(-F-(-n))*(ze-(-n)) + -1

        wn = 1

         

        xn = 2/(R-L)*xe- (R+L)/(R-L)

        yn = 2/(T-B)*ye-(T+B)/(T-B) 

        zn = 2/(N-F)*ze - (-F+-N)/(N-F)

       wn = 1

       一般視座標中的we = 1

       因此數學上的投影矩陣形式是:

      2/(R-L)       0         0       -(R+L)/(R-L)

      0           2/(T-B)     0       -(T+B)/(T-B)

      0                0     2/(N-F)      (F+N)/(N-F)

      0                0          0                1               

      

2: 透視投影

        透視投影須要首先將視座標轉化到可視體的近面上, 接着再進行正則化。

       

            所以有3鍾座標:

           xe ye ze we  視座標

           xp yp zp wp 近平面投影座標

           xc yc zc wc 切割空間座標

           xn yn zn wn 正則座標


           由於透視投影有近大遠小的特色,須要引入切割空間座標 用於轉化到 正則座標 xn = xc/wc  yn = yc/wc  zn = zc/wc

            其中wc 和 ze 相關:  wc = -ze  

            而投影矩陣 * 視座標的結果是 切割空間座標  即: projectionMatrix * (xe, ye, ze, we) = (xc, yc, zc, wc)

     

第一步:

           縮放x y 方向           

           xp = -n/ze * xe

           yp = -n/ze * ye

第二步 正則化 可視體:          

          設近平面的 範圍是 Left  Right Bottom Top

           兩個平面的z位置是  [-Near,   -Far]

          因此 [L, R] ->[-1, 1]  [B, T]--->[-1, 1]  [-N, -F]--->[-1, 1]

           相似於平行投影咱們獲得 xn xp yn yp zn ze 之間的關係,   須要注意zn 是和 ze 之間存在關係, 由於ze範圍纔是在[-N, -F] 

           xn = 2/(R-L)*xp- (R+L)/(R-L)

           yn = 2/(T-B)*yp-(T+B)/(T-B) 

           zn = zc/wc 

           zc 和 ze 之間的關係不明確, 可是必須是線性關係  即 zc = A*ze + B*xe + C*ye + D*we


計算xn yn 和 xe ye 的關係: 將1/-ze 提出來, 做爲wc 座標縮放因子

           xn = (2/(R-L)*n*xe+(R+L)/(R-L)*ze ) / -ze

           yn = (2/(T-B)*n*ye+(T+B)/(T-B)*ze)/ -ze

           因此

               xc = 2/(R-L)*n*xe+(R+L)/(R-L)*ze 

              yc = 2/(T-B)*n*ye+(T+B)/(T-B)*ze

              wc = -ze

 初步的投影矩陣 xe ye we  xc yc wc 的關係是:                   

            2/(R-L)*n          0               (R+L)/(R-L)       0

            0                  2/(T-B)*n       (T+B)/(T-B)        0

            ?                          ?                       A                B

             0                        0                       -1                0

而ze 和 zc之間存在關係   zc 和 xe, ye 之間是獨立的, 因此上面的投影矩陣的第3行前兩列爲0, 後兩列 係數是 A B  

           zn = (Aze + Bwe)/wc = (Aze+B)/ -ze  視座標的we = 1

           根據[-N, -F] ---> [-1, 1] 的正則關係

           -1 = (A*-N+B)/ N

            1 = (A*-F+B) /  F

           A*-N + B = -N

           A*-F + B = F

          determ = F-N

          A = -(N+F)/(F-N)

          B = -2NF/(F-N)   


          zn = Aze+B/-ze  =  -A + B/-ze = (N+F)/(F-N) - B/ze            zn的值最後將存儲在深度緩存中, 取值範圍[-1, 1]

         設 F-N = diff           zn = 2N/diff + 1 + 2NF/(diff*ze)

         其中 ze [-N, -F], ze 越靠近 -F 則zn 變化率越小 d(zn)/d(ze) = -2NF/(diff*ze*ze)


因此獲得了整個透視投影矩陣:

         求解矩陣採用待定係數法, 已知 座標軸之間的獨立關係, 以及變換後 取值範圍的關係, 求解係數。

相關文章
相關標籤/搜索