[英]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.