Opengl GLSL,更改glPosition.z以创建深度缓冲区中的平面更改?

Opengl GLSL,更改glPosition.z以创建深度缓冲区中的平面更改?,opengl,opengl-es,depth-buffer,Opengl,Opengl Es,Depth Buffer,我正在画一堆四合院上的贴花。相同的几何体,不同的纹理。Z-战斗是显而易见的结果。由于分批渲染,我无法控制渲染顺序或使用glPolygonoffset。所以我在顶点着色器中调整深度值 gl_Position = uMVPMatrix * pos; gl_Position.z += aDepthLayer * uMinStep * gl_Position.w; gl_位置保持剪辑坐标。这意味着z的更改将沿其视图光线移动顶点,并将其移到前面或推到后面。对于标准化设备坐标,剪辑坐标除以

我正在画一堆四合院上的贴花。相同的几何体,不同的纹理。Z-战斗是显而易见的结果。由于分批渲染,我无法控制渲染顺序或使用glPolygonoffset。所以我在顶点着色器中调整深度值

    gl_Position = uMVPMatrix * pos;
    gl_Position.z += aDepthLayer * uMinStep * gl_Position.w;
gl_位置保持剪辑坐标。这意味着z的更改将沿其视图光线移动顶点,并将其移到前面或推到后面。对于标准化设备坐标,剪辑坐标除以gl_Position.w(=-Zclip)。因此,深度缓冲区不具有线性分布,并且对于近平面具有更高的分辨率。通过预乘应该固定的gl_Position.w,我应该能够向NDC应用一个固定量(uMinStep)。

最小步长应该是1/(2^GL\u DEPTH\u BITS-1)。或者,由于NDC空间从-1.0变为1.0,它可能必须是这个数量的两倍。但是,它不适用于这些值。minStep大约为0.00000006,但它不会将纹理带到前面。当我将该值加倍时,两者都不存在。如果我降低一个0(10的刻度),它就工作了。(是啊,真了不起!)

但是它不能沿截锥体均匀工作。当四边形接近近平面时,使纹理位于另一个纹理前面的值在四边形接近远平面时不一定会这样做。当我使平截头体变深时,同样的效果也会发生。如果我改变眼睛的坐标,我会期待这种行为,因为非线性的z缓冲区分布。但是,对gl_Position.w进行预乘似乎不足以抵消这一点。

  • 我是否错过了剪辑坐标的某些转换?我一般需要使用不同的公式吗?我是否必须以某种方式包含深度范围[0,1]

  • 沿平截头体的不同行为是否是非线性浮点精度而不是非线性z缓冲区分布的结果?因此,也许计算是正确的,但minStep不能通过管道中某个点的浮动来正确处理

  • 一般问题:我如何计算gl_位置(剪辑坐标)的z偏移,这将在以后的深度缓冲区中创建固定的更改?我如何才能确保无论四元体放置在平截头体中的什么位置,z平移都会使一个纹理位于另一个纹理之前


  • 一些材料:
    OpenGL深度缓冲区常见问题解答

    与可读性更好的公式相同(但有些拼写错误,请小心)

    从眼坐标到z缓冲区的计算。当我乘以投影矩阵时,大多数情况已经发生了。

    在大多数深度缓冲区计算公式中,投影矩阵中变成A和B部分的元素的说明。

    我认为您的方法确实存在浮点精度问题。您最好不要在分割之前修改
    z_片段
    ,而是通过写入fragement着色器中的
    gl_FragDepth
    直接将修改应用于
    gl_FragCoord.z
    。OpenGL的默认剪辑卷约定的另一个问题是它映射“代码> ZYNDC=0 (FP精度最高的区域),在视图VULME的中间。你可能也会觉得有趣。谢谢。那篇文章我已经看了一段时间了我不能使用gl_FragDepth,因为我需要在GLES20项目中使用此函数。你认为在投影发生之前,如果我走“很长的路”,对眼睛坐标进行非线性z移位,精度会更好吗?“除法前修改z_剪辑”是什么意思?这正是我正在做的。好吧,我写了“最好不要在除法之前修改[…],而是使用片段着色器]”,所以我知道这就是你已经做过的…;)我不知道GLE中不存在
    gl_FragDepth
    ,所以我的建议是毫无用处的。在眼睛空间中执行与在剪辑空间中执行不会导致问题的显著差异(因为剪辑空间和眼睛空间只是彼此的线性变换),您只需引入额外的问题,即x和y位置将略微移动。因此,我真的没有什么好的建议给你,我很抱歉地说。吉姆·布林在1998年5月至6月的专栏《IEEE计算机图形与应用》中解释了深度测试计算的奇怪之处和不同的精度,该专栏在《吉姆·布林的角落:记法,记法,记法》一书中再版。可能有助于解释发生了什么。专栏的一般建议是尽可能增加Z附近的数值。谢谢。建议将近平面推出,因为zBuffer没有线性分布。其最高分辨率接近zNear。