13

我正在研究一个需要使用校准相机渲染 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 乘以任何非负标量并获得完全相同的渲染结果,但只要我乘以负标量,就不会渲染任何内容。这里发生了什么??

谢谢!

4

3 回答 3

10

好吧,它的要点是剪辑测试是通过以下方式完成的:

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

乘以负值会破坏此测试。

于 2010-02-18T08:19:11.673 回答
2

我刚刚发现了这个花絮,它在答案方面取得了进展:

来自红皮书,附录 G:

避免使用负 w 顶点坐标和负 q 纹理坐标。OpenGL 可能无法正确裁剪此类坐标,并且在对此类坐标定义的图元进行着色时可能会产生插值错误。

反转投影矩阵将导致负 W 裁剪坐标,显然 opengl 不喜欢这样。但是谁能解释为什么opengl不处理这种情况?

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

于 2010-02-18T05:41:26.737 回答
0

我能想到的原因:

  • 通过反转投影矩阵,坐标将不再位于视锥体的 zNear 和 zFar 平面内(必须大于 0)。
  • To create window coordinates, the normalized device coordinates are translated/scaled by the viewport. So, if you've used a negative scalar for the clip coordinates, the normalized device coordinates (now inverted) translate the viewport to window coordinates that are... off of your window (to the left and below, if you will)

Also, since you mentioned using a camera matrix and that you have inverted the projection matrix, I have to ask... to which matrices are you applying what from the camera matrix? Operating on the projection matrix save near/far/fovy/aspect causes all sorts of problems in the depth buffer including anything that uses z (depth testing, face culling, etc).

The OpenGL FAQ section on transformations has some more details.

于 2010-02-18T09:58:10.493 回答