1

我正在尝试编写一种方法来计算我正在处理的相机类的视锥角。我知道MVP 矩阵是正确的,因为它被推到了我的顶点着色器中,而且屏幕上的一切确实都是正确的,不仅如此,我还从这个矩阵计算了世界空间平截头体平面,它们是正确的。此外,这些方法在几个不同的相机配置中进行了单元测试,并给出了预期的结果。

我试图通过将 NDC 角转换为 MVP 矩阵的倒数来计算截锥角。

//  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 的远平面所期望的。我对这个程序有什么不明白的地方?

4

1 回答 1

2

没有看你的数字那么重,我只是做出一个疯狂的猜测:

我希望您不要忘记在将转换后的角扩展到 4D 齐次坐标(通过添加 a 1)并将它们乘以逆 MVP 之后,将它们除以它们的第 4 个分量。

这是必要的,因为 MVP 矩阵(实际上是投影部分)及其逆矩阵不是仿射变换,因此w除了1应用于同质向量时会导致 - 值。当您(或实际上是您的着色器)在转换向量时应用通常的前向 MVP 乘法时,这也是一样的,只是固定功能图形硬件会w为您进行除法(所谓的透视除法,因为这实际上是导致更远的对象的原因在屏幕上变小)。

于 2013-04-22T07:59:59.220 回答