在 OpenGL 中,(如何)我可以在两个深度缓冲区之间进行深度测试?
Posted
技术标签:
【中文标题】在 OpenGL 中,(如何)我可以在两个深度缓冲区之间进行深度测试?【英文标题】:In OpenGL, (how) can I depth test between two depth buffers? 【发布时间】:2015-10-25 23:04:03 【问题描述】:假设我有两个深度缓冲区(“DA”和“DB”)。我想将 DA 附加到帧缓冲区,并以正常/“传统”方式呈现给它(每个片段深度都针对 GL_LESS 进行测试,如果它通过,则将其绘制并将其深度写入深度缓冲区)。
然后,我想附上 DB- 在这里我想以传统方式引用/使用 DB,还想用 GL_GREATER 对 DA 进行深度测试。如果片段通过了两个测试,我仍然只想将深度写入 DB。
这将完成的是,在第二遍中绘制的任何内容只有在它在第一遍的内容之后,但在在任何其他内容之前时才会绘制第二遍。
OpenGL 2.1(或 OpenGL ES 2)是否提供任何此类功能?如果没有正式提供它,我能做些什么来解决它?
如果它不提供,这里有一个关于我会如何做的想法,我想接受理智检查......
您附加一个作为深度缓冲区的渲染缓冲区,然后手动填充深度。并手动执行“如果深度大于 DA 时的纹素”测试(失败时,丢弃片段)。我很好奇我会遇到什么问题?有没有一种简单的方法来模拟正式指定深度缓冲区的深度精度?表演会很糟糕吗?还有其他顾虑吗?
【问题讨论】:
【参考方案1】:我不相信有办法拥有多个深度缓冲区。我认为至少可能存在特定于供应商的扩展,但通过扩展注册表进行的搜索即使为此也是空的。
您在上一段中已经开始考虑的内容似乎是您想到的唯一合理直接的选项。您使用深度纹理作为第二个深度缓冲区,并根据片段与片段着色器中深度纹理值的比较丢弃片段。
您不必手动填充深度纹理。如果深度值是由较早的渲染过程生成的,您可以使用glCopyTexImage2D()
将它们从主深度缓冲区复制到深度纹理。此功能在 OpenGL 2.1 中可用。在较新的版本中,您还可以使用glBlitFramebuffer()
进行复制。
关于您的担忧:
精度是一个非常有效的问题。当我过去玩类似的东西时,我遇到了一些相当严重的精度问题。它们可能可以解决,但您绝对需要注意它,并仔细考虑您的精度要求是什么,以及如何在必要时捏造这些值。
我当然希望性能会有所下降。固定功能深度缓冲区具有大量优化的优势,例如早期深度测试,这是您使用“自制”深度缓冲区无法获得的。不过,我不一定认为它会很可怕。如果这是您需要的,那么值得一试。
我认为这在 ES 2.0 中几乎是不行的,至少在不依赖扩展的情况下。您可能会考虑将深度值写入颜色纹理,但我认为它会变得非常丑陋且效率低下。 ES 2.0 非常简单。但是对于您计划做的事情,您超出了其预期的功能集。 ES 3.0 增加了深度纹理,以及其他一些可以发挥作用的功能。
【讨论】:
好的。害怕那个。幸运的是,我的用例允许我使用 minimal 工件将“DA”捏造为 world_pos.z以上是关于在 OpenGL 中,(如何)我可以在两个深度缓冲区之间进行深度测试?的主要内容,如果未能解决你的问题,请参考以下文章
OpenGL如何在模板测试失败且深度测试成功时写入模板缓冲区?
OpenGL ES 学习教程 DEPTH_TEST(深度缓冲测试)