Frustum和透视矩阵
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是一个float或double(对于测试,我只使用了float)。
我使用的测试值是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!
只有一次!然后在任何你想要的地方使用它
而且,除法非常昂贵,您可以预先计算除法并将其存储在数组中,您只需要在执行过程中从数组中获取预先计算的元素。
例如:如果顶部和底部范围很小,那么您可以在一个小数组中表示计算(实际上它是除数和除数的映射)
我认为问题出在Perspective()
中:当计算ymax
时,不应该乘以zNear
。从数学上讲,你投影到一个单位距离的平面上,而不是zNear
平面;这种价值在那里没有任何意义。
请尝试仅设置ymax= tan(fovy*Math<T>::PI/360.0)
。仍然不能保证它会是正确的,但这应该更理智。。。
相关文章:
- 在 OpenGL 中使用透视与正交投影时的光线投射(鼠标拾取)
- 透视视图的任何解决方案 openGL qt.
- 从固定函数迁移到 GLSL OpenGL:我应该如何修改我的视图(lookAt)矩阵和透视矩阵?
- 禁用对透视的焦点
- OpenGL 透视投影裁剪多边形与顶点在视锥体之外 = 错误的纹理映射?
- 如何在透视视图中绘制文本
- OpenCV 透视编辑和裁剪
- 从正交投影平滑过渡到透视投影
- 部分透视/高斯消除 - 交换列而不是产生错误输出的行
- 现代Opengl:同时正投影和透视投影
- 食人魔:模拟透视视图缩放对象
- 是胶质项目缺少透视划分的文档
- 绕Y轴旋转二维正方形,并使用DirectX或openGL以透视投影方式显示
- OpenGL-Frustum不剔除远平面以外的多边形
- 透视投影 OPENGL 和计算着色器
- Frustum和透视矩阵
- 透视矩阵的旋转角度
- C++快速排序透视优化
- 透视到世界空间逆投影
- OpenCV RHO 单应性方法不适用于透视变换