具有两个不同投影矩阵的深度缓冲区 [英] A Depth buffer with two different projection matrices

查看:98
本文介绍了具有两个不同投影矩阵的深度缓冲区的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用默认的OpenGL值,例如glDepthRangef(0.0,1.0);、 gldepthfunc(GL_LESS);和glClearDepthf(1.f);因为我的投影矩阵将右手坐标更改为左手坐标.我的意思是,我的近平面和远平面z值在NDC中应该是[-1,1].

I am using the default OpenGL values like glDepthRangef(0.0,1.0);, gldepthfunc(GL_LESS); and glClearDepthf(1.f); because my projection matrices change the right hand coordinate to the left hand coordinate. I mean, My near plane and the far plane z-values are supposed to be [-1 , 1] in NDC.

问题是,当我在一个FBO上绘制两个包含相同RBO的对象时,例如下面的代码,

The problem is when I draw two objects at the one FBO including same RBOs, for example, like this code below,

    glEnable(GL_DEPTH_TEST);
    glClearDepthf(1.f);
    glClearColor(0.0,0.0,0.0,0.0);
    glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);

    drawObj1(); // this uses 1) the orthogonal projection below 
    drawObj2(); // this uses 2) the perspective projection below

    glDisable(GL_DEPTH_TEST);

始终,对象1在对象2上方.

always, the object1 is above the object2.

1)正交

2)透视

但是,当他们使用相同的投影时,不管它是什么,它都可以正常工作.

However, when they use same projection whatever it is, it works fine.

您认为我应该去哪一部分?

Which part do you think I should go over?

-更新-

将眼睛坐标从NDC覆盖到屏幕坐标,实际上会发生什么?

Coverting Eye coordinate to NDC to Screen coordinate, what really happens?

我的理解是,经过两次投影后,其NDC形状与下图相同,乘以2)透视矩阵后的z值不必失真.但是,根据derbass的正确答案,如果将视图坐标中的z值乘以透视矩阵,则z值将在NDC中双曲线失真.

My understanding is because after both of projections, its NDC shape is same as images below, its z-value after multiplying 2) perspective matrix doesn't have to be distorted. However, according to the derbass's good answer, if z-value in the view coordinate is multiplied by the perspective matrix, the z-value would be hyperbolically distorted in NDC.

如果是这样,例如,如果一个顶点位置在眼睛(视图)坐标中为[-240.0、0.0,-100.0],坐标为[w:480.0,h:320.0],则用[-0.01]裁剪,-100],在NDC中是[-1,0,-1]还是[something> =-1,0,-1]?而且其z值仍与-1相同,不是吗?当它的z值失真时?

If so, if one vertex position, for example, is [-240.0, 0.0, -100.0] in the eye(view) coordinate with [w:480.0,h:320.0], and I clipped it with [-0.01,-100], would it be [-1,0,-1] or [something>=-1,0,-1] in NDC ? And its z value is still same as -1, isn't it? when its z-value is distorted?

1)正交

2)透视

推荐答案

您不能期望将顶点的z值投影到相同的窗口空间z值,只是因为您对a使用了相同的近距离和远距离值透视和正交投影矩阵.

You can't expect that the z values of your vertices are projected to the same window space z value just because you use the same near and far values for a perspecitive and an orthogonal projection matrix.

在预定情况下,眼部空间z值将双曲线失真为NDC z值.在正交情况下,它只有一点点地缩放和移动.

In the prespecitve case, the eye space z value will be hyperbolically distorted to the NDC z value. In the orthogonal case, it is just linaerily scaled and shifted.

如果"Obj2"仅位于平面z_eye = const中,则可以预先计算其在透视情况下应具有的变形深度.但是,如果深度的范围不为零,则此方法将无效.我可以想到处理这种情况的不同方法:

If your "Obj2" lies just in a flat plane z_eye=const, you can pre-calulate the distorted depth it should have in the perspective case. But if it has a non-zero extent into depth, this will not work. I can think of different approaches to deal with the situation:

  1. 根据z缓冲区期望的双曲失真来调整gl_FragDepth,从而固定"片段着色器中对象2的深度.

  1. "Fix" the depth of object two in the fragment shader by adjusting the gl_FragDepth according to the hyperbolic distortion your z buffer expects.

也使用线性z缓冲区. w缓冲.

Use a linear z-buffer, aka. a w buffer.

这些方法在概念上是彼此相反的.在这两种情况下,您都可以使用gl_FragDepth进行游戏,以使其与其他渲染过程的约定匹配.

These approaches are conceptually the inverse of each other. In both cases, you have play with gl_FragDepth so that it matches the conventions of the other render pass.

更新

我的理解是,经过两次投影后,其NDC形状 与下面的图片相同,乘以2)透视后的z值 矩阵不必失真.

My understanding is because after both of projections, its NDC shape is same as images below, its z-value after multiplying 2) perspective matrix doesn't have to be distorted.

好吧,这些图像显示了从剪辑空间到NDC的转换.而这种转变就是投影矩阵和透视图分割所完成的工作.当处于规范化的设备坐标中时,不会发生进一步的失真.它只是根据glDepthRange()设置线性转换为窗口空间z.

Well, these images show the conversion from clip space to NDC. And that transfromation is what the projection matrix followed by the perspective divide do. When it is in normalized device coords, no further distortion does occur. It is just linearily transformed to window space z according to the glDepthRange() setup.

但是,根据 如果将视图坐标中的z值乘以derbass的好答案 通过透视矩阵,z值将是双曲线的 在NDC中失真了.

However, according to the derbass's good answer, if z-value in the view coordinate is multiplied by the perspective matrix, the z-value would be hyperbolically distorted in NDC.

透视图矩阵应用于完整的4D均匀眼空间矢量,因此将其应用于z_eye以及x_eyey_eye以及w_eye(通常仅为1,但不会不必).

The perspective matrix is applied to the complete 4D homogenous eye space vector, so it is applied to z_eye as well as to x_eye, y_eye and also w_eye (which is typically just 1, but doesn't have to).

因此,透视案例的结果NDC坐标被弯曲变形为

So the resulting NDC coordinates for the perspective case are hyberbolically distorted to

         f + n        2 * f * n              B
z_ndc = ------- + ----------------- = A + -------
         n - f     (n - f) * z_eye         z_eye

而在正交情况下,它们只是线性变换为

while, in the orthogonal case, they are just linearily transformed to

         - 2              f + n    
z_ndc = ------- z_eye - --------- = C * z_eye + D
         f - n           (f - n) 

对于n=1f=10,它看起来像这样(请注意,部分绘制了视锥范围之外的范围.当然,剪切将防止这些值出现在GL中).

For n=1 and f=10, it will look like this (note that I plotted the range partly outside of the frustum. Clipping will prevent these values from occuring in the GL, of course).

如果是,例如,如果一个顶点位置是[-240.0,0.0,-100.0] 在眼睛(视图)中与[w:480.0,h:320.0]坐标,然后将其剪裁 与[-0.01,-100]对应,则为[-1,0,-1]或[something> =-1,0,-1] NDC?而且其z值仍与-1相同,不是吗?当它的z值时 失真了吗?

If so, if one vertex position, for example, is [-240.0, 0.0, -100.0] in the eye(view) coordinate with [w:480.0,h:320.0], and I clipped it with [-0.01,-100], would it be [-1,0,-1] or [something>=-1,0,-1] in NDC ? And its z value is still same as -1, isn't it? when its z-value is distorted?

始终将远平面上的点转换为z_ndc=1,并将近平面上的点转换为z_ndc=-1.这就是投影矩阵的构造方式,而这正是上面图中两个图形相交的地方.因此,对于这些琐碎的情况,不同的映射根本无关紧要.但是对于所有其他距离,它们都会.

Points at the far plane are always transformed to z_ndc=1, and points at the near plane to z_ndc=-1. This is how the projection matrices were constructed, and this is exactly where the two graphs in the plot above intersect. So for these trivial cases, the different mappings do not matter at all. But for all other distances, they will.

这篇关于具有两个不同投影矩阵的深度缓冲区的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆