为什么符号在opengl投影矩阵中很重要

发布于 2024-08-21 23:37:32 字数 838 浏览 11 评论 0原文

我正在研究一个计算机视觉问题,需要使用校准相机渲染 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 乘以任何非负标量并获得完全相同的渲染结果,但是一旦我乘以负标量,就不会渲染任何内容。这是怎么回事?

谢谢!

I'm working on a computer vision problem which requires rendering a 3d model using a calibrated camera. I'm writing a function that breaks the calibrated camera matrix into a modelview matrix and a projection matrix, but I've run into an interesting phenomenon in opengl that defies explanation (at least by me).

The short description is that negating the projection matrix results in nothing being rendered (at least in my experience). I would expect that multiplying the projection matrix by any scalar would have no effect, because it transforms homogeneous coordinates, which are unaffected by scaling.

Below is my reasoning why I find this to be unexpected; maybe someone can point out where my reasoning is flawed.

Imagine the following perspective projection matrix, which gives correct results:

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

Multiplying this by camera coordinates gives homogeneous clip coordinates:

[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]

Finally, to get normalized device coordinates, we divide x_c, y_c, and z_c by w_c:

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

Now, if we negate P, the resulting clip coordinates should be negated, but since they are homogeneous coordinates, multiplying by any scalar (e.g. -1) shouldn't have any affect on the resulting normalized device coordinates. However, in openGl, negating P results in nothing being rendered. I can multiply P by any non-negative scalar and get the exact same rendered results, but as soon as I multiply by a negative scalar, nothing renders. What is going on here??

Thanks!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

白云悠悠 2024-08-28 23:37:32

嗯,其要点是削波测试是通过以下方式完成的:

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

乘以负值会破坏此测试。

Well, the gist of it is that clipping testing is done through:

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

Multiplying by a negative value breaks this test.

风蛊 2024-08-28 23:37:32

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

来自红皮书,附录G:

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

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

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

I just found this tidbit, which makes progress toward an answer:

From Red book, appendix G:

Avoid using negative w vertex coordinates and negative q texture coordinates. OpenGL might not clip such coordinates correctly and might make interpolation errors when shading primitives defined by such coordinates.

Inverting the projection matrix will result in negative W clipping coordinate, and apparently opengl doesn't like this. But can anyone explain WHY opengl doesn't handle this case?

reference: http://glprogramming.com/red/appendixg.html

巡山小妖精 2024-08-28 23:37:32

我能想到的原因:

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

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

有关转换的 OpenGL 常见问题解答部分提供了更多详细信息。

Reasons I can think of:

  • By inverting the projection matrix, the coordinates will no longer be within your zNear and zFar planes of the view frustum (necessarily greater than 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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文