我正在尝试编写一个方法来计算我正在处理的相机类的视锥体角。我知道 MVP矩阵是正确的,因为它被推入我的顶点着色器,实际上屏幕上的一切都是正确的,不仅如此,我还是从这个矩阵计算了世界空间平截头体平面并且它们是正确的。这些方法也是在几种不同的相机配置中进行单元测试,并给出了预期的结果。
我试图通过用MVP矩阵的逆转换NDC角来计算平截头体角。
// Fill with the corners in clip space.
QVector< Vector3f > corners( 8 );
corners[0] << 1.0f, 1.0f, 1.0f;
corners[1] << -1.0f, 1.0f, 1.0f;
corners[2] << 1.0f, -1.0f, 1.0f;
corners[3] << -1.0f, -1.0f, 1.0f;
corners[4] << 1.0f, 1.0f, -1.0f;
corners[5] << -1.0f, 1.0f, -1.0f;
corners[6] << 1.0f, -1.0f, -1.0f;
corners[7] << -1.0f, -1.0f, -1.0f;
// Then transform back into worldspace.
for ( Vector3f& c : corners ) {
c = mult( mvp.inverse(), c );
}
看起来足够可观,但如果我加入我的MVP(专栏专业):
-1.68199 0.0 1.68199 0.0
-0.720796 3.00332 -0.720796 0.0
-0.671735 -0.322433 -0.671735 35.8534
-0.669589 -0.321403 -0.669589 37.3363
这是一款近距离剪辑为0.8,距离为500.0,FOV为35.0°,视口大小为800x600,位于[25.0,12.0,25.0]的相机,查看原点(y
是向上轴)。我得到了这些角落:
-0.988515, 0.00116634, -0.393982
-0.393982, 0.00116634, -0.988515
-0.845201, -0.595974, -0.250669
-0.250669, -0.595974, -0.845201
30.2115, 14.9772, 30.8061
30.8061, 14.9772, 30.2115
30.3548, 14.38, 30.9494
30.9494, 14.38, 30.3548
不要太长时间地盯着这些数字(你会发疯),只要注意到没有角落数百个单位,这是你所期望的500.0的远平面。我对这个程序有什么不了解?
答案 0 :(得分:2)
如果不仔细查看你的数字,我只是猜测:
我希望你不要忘记在将它们转换为4D同质坐标(通过添加1
)并将它们乘以逆MVP后,将它们的第4个分量除以它们。
这是必要的,因为MVP矩阵(实际上是投影部分)及其逆不是仿射变换,因此当应用于同质向量时,导致w
- 除1
之外的值。当你(或实际上你的着色器)在变换向量时应用通常的前向MVP乘法时,这是相同的,只是固定函数图形硬件为你做w
除法(所谓的透视除法,因为这是什么实际上导致更远的物体在屏幕上更小。)