簡體   English   中英

Frustum和Perspective矩陣

[英]Frustum and Perspective matrices

我有一些轉換矩陣的代碼,我添加了一些處理Frustum和Perspective的函數。

事情是,當我調用透視圖時,一切看起來好像我有一個非常大的視野(好在屏幕中間,而在邊緣非常拉伸)。 當我增加近似值時,這種效果會更糟。

    void Frustum(T left, T right, T bottom, T top, T zNear, T zFar)
    {
        m[0][0]=2.0f*zNear/(right-left);
        m[1][0]=0.0f;
        m[2][0]=(right+left)/(right-left);
        m[3][0]=0.0f;
        m[0][1]=0.0f;
        m[1][1]=2.0f*zNear/(top-bottom);
        m[2][1]=(top+bottom)/(top-bottom);
        m[3][1]=0.0f;
        m[0][2]=0.0f;
        m[1][2]=0.0f;
        m[2][2]=-(zFar+zNear)/(zFar-zNear);
        m[3][2]=-2.0f*zFar*zNear/(zFar-zNear);
        m[0][3]=0.0f;
        m[1][3]=0.0f;
        m[2][3]=-1.0f;
        m[3][3]=0.0f;
    }

    void Perspective(T fovy,T aspectRatio,T zNear,T zFar)
    {
        T xmin,xmax,ymin,ymax;
        ymax= zNear* tan(fovy*Math<T>::PI/360.0);
        ymin= -ymax;
        xmin= ymin*aspectRatio;
        xmax= ymax*aspectRatio;
        Frustum(xmin,xmax,ymin,ymax,zNear,zFar);
    }

T是浮點數或雙精度,因為類是模板化的(對於測試我只使用浮點數)。

我使用的測試值是fovy="60" znear="1.0" zfar="1000.0" ,當我將它們更改為fovy="60" znear="10.0" zfar="1000.0"它會變得更糟。

請注意,矩陣是DirectX風格,但我在OpenGL中使用它們,因此我在着色器中更改了乘法的順序。

你們看到我的代碼有什么問題嗎?

謝謝

問題是,當我開始使用轉置的矩陣(DirectX風格)時,我想我還必須轉換截頭數學,這不是一個好主意。

這就是Frustum函數的樣子:

    void Frustum(T left, T right, T bottom, T top, T zNear, T zFar)
    {
        T zDelta = (zFar-zNear);
        T dir = (right-left);
        T height = (top-bottom);
        T zNear2 = 2*zNear;

        m[0][0]=2.0f*zNear/dir;
        m[0][1]=0.0f;
        m[0][2]=(right+left)/dir;
        m[0][3]=0.0f;
        m[1][0]=0.0f;
        m[1][1]=zNear2/height;
        m[1][2]=(top+bottom)/height;
        m[1][3]=0.0f;
        m[2][0]=0.0f;
        m[2][1]=0.0f;
        m[2][2]=-(zFar+zNear)/zDelta;
        m[2][3]=-zNear2*zFar/zDelta;
        m[3][0]=0.0f;
        m[3][1]=0.0f;
        m[3][2]=-1.0f;
        m[3][3]=0.0f;
    }

計算

z_delta=(zfar-znear);//used two times!
direction=(right-left);//used two times!
height=(top-bottom);//used two times!
znear_2=2.0f*znear; //used 3 times!

只有一次! 然后在任何地方使用它

除法是如此昂貴,你可以預先計算分區並存儲在數組中,你只需要在執行中從數組中獲取預先計算的元素。

例如:如果頂部和底部范圍很小,那么您可以用小數組表示計算(實際上它是一個divison和一個分隔符的映射)

我認為問題出在Perspective() :當計算ymax ,你不應該乘以zNear 在數學上,你是投射到單位距離的平面上, 而不是 zNear平面; 那個價值在那里沒有生意。

嘗試只設置ymax= tan(fovy*Math<T>::PI/360.0) 仍然無法保證它是正確的,但這應該更加明智......

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM