【问题标题】:How can I write a different value to the depth buffer than the value used for depth comparisson?如何将与用于深度比较的值不同的值写入深度缓冲区?
【发布时间】:2017-07-09 13:46:31
【问题描述】:

在 Open GL 中,是否可以在启用常规深度测试的情况下渲染多边形,但是当深度缓冲区值实际写入深度缓冲区时,我想写入自定义值?

(原因是我正在渲染一个粒子系统,应该针对场景中的几何图形进行深度测试,但我想在粒子系统所在的位置写入一个非常大的深度值,从而利用深度-模糊后处理步骤以进一步模糊粒子系统)

更新 进一步细化问题,是否可以不进行多次渲染?

【问题讨论】:

  • 如果问题是“是否可能”,那么答案是肯定的。在 FBO 中渲染场景,使用其深度纹理附件在片段着色器中进行“手动”深度测试(discarding 片段将无法通过深度测试)并将任意深度值输出到另一个深度缓冲区(可能如果需要,通过 FBO 的 blitting 进行初始化)。不能保证所有这些的性能......
  • 感谢更新问题。
  • 我从未使用过 ARB_conservative_depth,但它可以解决您的问题。

标签: opengl depth-buffer depth-testing


【解决方案1】:

你没有。

OpenGL 不允许你撒谎。深度测试根据要写入深度缓冲区的传入值测试深度缓冲区中的值。一旦该测试通过,测试的深度值将被写入深度缓冲区。期间。

除了测试深度值之外,您不能(ab)使用深度测试来做其他事情。

ARB_conservative_depth/GL 4.2 确实允许您非常限制这种形式。基本上,您向实现承诺您只会以使其小于或大于原始值的方式更改深度。但即便如此,它也只会在特定情况下起作用,而且只有在您保持在您指定的范围内时才有效。

强制执行early fragment tests 同样不允许您这样做。规范明确规定深度将在您的着色器执行之前写入。所以你写给gl_FragDepth的任何东西都会被忽略

【讨论】:

  • 谢谢,基本上保守的深度会帮助我,但由于我是 opengl es 3.0,我只需要重新考虑我的算法
【解决方案2】:

一次性完成的一种方法是“手动”进行深度测试。

glDepthFunc 设置为GL_ALWAYS

然后在片段着色器中,对深度缓冲区的当前值进行采样,并根据它使用discard;丢弃片段

要对深度缓冲区的当前值进行采样,您需要ARM_shader_framebuffer_fetch_depth_stencil(通常在移动平台上)或NV_texture_barrier。然而,如果同一个 drawcall 的多个粒子相互叠加渲染,则后者将产生未定义的结果,而在这种情况下,前者将使用在同一位置渲染的最后一个粒子的写入深度值。

您也可以在渲染粒子之前将当前深度缓冲区复制到深度纹理中,然后使用该深度纹理进行手动深度测试,从而无需任何扩展。这也避免了相互叠加渲染的粒子会产生干扰,因为它们都会使用旧的深度值进行手动测试。

【讨论】:

    【解决方案3】:

    您可以在片段着色器中使用 gl_FragDepth 来编写您的自定义值。

    gl_FragDepth = 0.3;
    

    https://www.khronos.org/registry/OpenGL-Refpages/gl4/html/gl_FragDepth.xhtml

    【讨论】:

    • 如果你写入gl_FragDepth,这个值也会被用来做深度比较。该问题明确要求修改所写深度的方法,而不是深度测试本身。 Afaik,除非将几何图形渲染两次,否则不可能使用不同的值进行测试和编写。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-30
    相关资源
    最近更新 更多