我正在研究一个计算机视觉问题,需要使用校准相机渲染 3D 模型。我正在编写一个函数,将校准的相机矩阵分解为模型视图矩阵和投影矩阵,但我在 opengl 中遇到了一个有趣的现象,它无法解释(至少对我来说)。

简而言之,否定投影矩阵不会导致任何内容被渲染(至少根据我的经验)。我希望将投影矩阵乘以任何标量都不会产生任何效果,因为它会变换齐次坐标,而不受缩放的影响。

以下是我认为这是出乎意料的原因;也许有人可以指出我的推理有缺陷。

想象一下以下透视投影矩阵,它给出了正确的结果:

    [ a b c 0 ]
P = [ 0 d e 0 ]
    [ 0 0 f g ]
    [ 0 0 h 0 ]

将其乘以相机坐标即可得到齐次剪辑坐标:

[x_c]   [ a b c 0 ]   [X_e]
[y_c] = [ 0 d e 0 ] * [Y_e]
[z_c]   [ 0 0 f g ]   [Z_e]
[w_c]   [ 0 0 h 0 ]   [W_e]

最后,为了获得标准化的设备坐标,我们将 x_c、y_c 和 z_c 除以 w_c:

[x_n]   [x_c/w_c]
[y_n] = [y_c/w_c]
[z_n]   [z_c/w_c]

现在,如果我们对 P 取反,则生成的剪辑坐标也应该取反,但由于它们是齐次坐标,因此乘以任何标量(例如-1) 不应对生成的标准化设备坐标产生任何影响。然而,在 openGl 中,否定 P 不会导致任何内容被渲染。我可以将 P 乘以任何非负标量并获得完全相同的渲染结果,但是一旦我乘以负标量,就不会渲染任何内容。这里发生了什么??

谢谢!

有帮助吗?

解决方案

好了,它的要点是,削波的测试是通过完成:

-w_c < x_c < w_c
-w_c < y_c < w_c
-w_c < z_c < w_c

由负值打破了这种测试乘法。

其他提示

我刚刚发现这个珍闻,这使得朝向一个答案进展:

从红皮书,附录G:

  

避免使用负瓦特顶点坐标和负Q纹理坐标。的OpenGL可能无法正确剪辑这样的坐标和阴影化由这种坐标定义的原语,当可能使内插误差。

反向投影矩阵将导致负W¯¯裁剪坐标,显然的OpenGL不喜欢此。但是,任何人都可以解释为什么OpenGL的不处理这种情况?

参考: http://glprogramming.com/red/appendixg.html

我能想到的原因:

  • 通过反转投影矩阵,坐标将不再位于视锥体的 zNear 和 zFar 平面内(必须大于 0)。
  • 为了创建窗口坐标,标准化设备坐标由视口进行平移/缩放。因此,如果您对剪辑坐标使用负标量,则标准化设备坐标(现在已反转)会将视口转换为窗口坐标...离开你的窗户(如果你愿意的话,在左边和下面)

另外,既然你提到使用相机矩阵并且你已经反转了投影矩阵,我不得不问......您将相机矩阵中的内容应用于哪些矩阵?对投影矩阵进行操作保存近/远/fovy/aspect 会导致深度缓冲区中出现各种问题,包括使用 z 的任何问题(深度测试、面剔除等)。

OpenGL 常见问题解答部分 转变 有一些更多的细节。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top