【问题标题】:OpenGL ES 3.x How to (performantly) render blended triangles front-to-back with alpha-blending and early-reject occluded fragments?OpenGL ES 3.x 如何(高效地)使用 alpha 混合和早期拒绝遮挡片段从前到后渲染混合三角形?
【发布时间】:2021-11-21 08:22:06
【问题描述】:

我最近发现,通过使用GL_ONE_MINUS_DST_ALPHA, GL_ONE,在片段着色器中预乘片段的 alpha 和在渲染之前将目标 alpha 清除为黑色。

我突然想到,如果可以将它与 early-z 拒绝或某种早期“目标 alpha 测试”结合起来,以丢弃不会对最终像素颜色产生影响的片段,那将是很棒的.

在使用前后 alpha 混合进行渲染时,如果此位置的目标 alpha 已包含值 1.0,则可以跳过片段。 我做了原型实现,通过使用 GL_EXT_shader_framebuffer_fetch 在像素着色器开始时测试目标 alpha,然后如果值高于某个阈值,则手动丢弃片段。这行得通,但它实际上让我的测试硬件(Snapdragon XR2)变得更慢 - 所以我想知道:

  1. 如果目标 alpha 已经超过某个阈值,是否有可能甚至不执行片段着色器?

或者,如果可以只写入完全不透明的片段的深度缓冲区,并且对于所有 alpha 值小于 1 的片段保持当前深度缓冲区值不变(但仍然对每个片段进行深度测试)片段),这应该允许硬件对被遮挡的片段使用 early-z 拒绝。所以,

  1. 这是否可能(即使用深度测试,但只为不透明片段更新深度缓冲区值,而其他片段保持不变)?

底线这将允许将 alpha 混合精灵的过度绘制减少到仅对最终像素颜色有贡献的那些片段,我想知道是否有一种高效的方法来做到这一点。

【问题讨论】:

    标签: opengl-es opengl-es-3.0


    【解决方案1】:

    对于第 2 点,我认为您可以在片段着色器中修改 gl_FragDepth 以实现接近的效果,但这样做会禁用 early-z 拒绝,因此无济于事。

    我认为减少过度绘制的一种可行方法是创建一个工具来为每个精灵生成一个网格,该网格旨在覆盖精灵不透明部分的相当比例而不使用太多顶点。我想对于一个典型的精灵,即使只是一个放置良好的四边形也可以覆盖 80% 以上。

    您将在启用深度写入的情况下渲染生成的精灵的不透明几何图形,然后在启用深度测试的情况下以普通方式进行第二次传递以覆盖透明部分。

    您将大大减少过度绘制,但会显着增加代码的复杂性和渲染的顶点数量。您可以将绘图调用加倍,但如果您正在使用纹理数组并使用纹理数组,则可能会从 1 个绘图调用加倍到 2 个绘图调用,这很好。我从来没有尝试过,所以不能说是否值得付出所有的努力。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-11-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多