【问题标题】:Is there a sensible way to implement depth peeling on OpenGL ES 2.0?在 OpenGL ES 2.0 上实现深度剥离是否有明智的方法?
【发布时间】:2016-11-28 14:20:04
【问题描述】:

由于 OpenGL ES 2.0 缺少 GL_ALPHA_TESTglAlphaFunc,因此为透明对象实现深度剥离的常规方法显然不起作用。理论上我可以在片段着色器中使用if (alpha < 1) discard;,但由于它是一个分支,恐怕它可能太慢了。

还有其他方法可以解决这个问题吗?

与仅接受从后到前渲染中过度绘制的成本相比,有人对if (alpha < 1) discard; 的性能有经验吗?

编辑:虽然我似乎在上面描述了纯 alpha 测试,但我的目标实际上是实现类似于深度剥离或 early-z 的东西。我正在解决的问题是,通过从后到前的渲染,我在不透明像素上得到了大量的透支。所以我想分两次渲染。首先是使用 alpha func ==1 从前到后打开 alpha 测试(这是“深度剥离”或“early-z”通过)。第二个是开启了 alpha 混合和深度测试的从后到前。

【问题讨论】:

  • 你确定你的意思是深度剥离吗?深度剥离是一种实现与顺序无关的透明度的技术,但您说您已经在进行从后到前的渲染。我想知道你是不是想说 alpha 测试。
  • 你是对的。尽管我的目标与深度剥离(或 early-z)非常相似,但我想要 alpha 测试之类的东西。从前到后或从后到前渲染我没有问题,但是从后到前渲染时性能会受到很大影响。在繁重的场景中,我可能会得到平均 8 倍的透支。这些是浪费了数千万像素着色器调用,而其中只有一小部分是半透明的。所以我想在我的第一次通过 alpha 测试时从前到后绘制,以填充深度缓冲区,然后在我的第二次通过时从前到后绘制,这次使用深度测试和 alpha 混合。

标签: opengl-es opengl-es-2.0


【解决方案1】:

一般来说,不惜一切代价避免大量使用discard。它绝对不是 early-zs 测试的通用替代品,并且会导致像素之间的数据依赖关系出现一些可怕的问题(直到 late-z,您才能自信地解决深度值,因为您不提前知道是否着色器实际上是否会丢弃片段)。

您没有确切说明您的用例是什么,但如果它是不透明精灵的 2D 渲染层,那么一个很好的解决方法是将每个精灵的几何体调整为两批 - 真正不透明的东西,可以使用深度测试禁用混合(从前到后渲染),并混合您在第二遍中绘制的内容(启用深度测试后从后到前渲染,但禁用深度写入)。

这篇博客很好地概述了这项技术:

如果您的内容是经过 alpha 测试的任意 3D 内容,那么我担心无论您尝试哪种方式都会遇到麻烦,因为丢弃从未真正有效。

【讨论】:

  • 我的情况确实是 2D 并且在不透明部分上使用几何图形是我正在考虑的替代方案,但它比链接中的示例复杂得多。内容虽然 2D 不是精灵,但复杂的 2D 网格......所以我猜它可能有资格作为任意 3D 内容。为这些网格生成“早期 z”几何图形将非常困难。手动绘制它也很费力。我想我要测试丢弃路径,如果结果不令人满意,请尝试弄清楚如何处理不透明几何体。
  • 是的,对于没有任何预处理手段的任意网格,那么该技术并不容易工作 - 我从未尝试过在平台上对纹理进行预处理。一个词或警告是,discard 对性能的影响在 GPU 供应商和硬件版本中可能有些不稳定,因此您可能想在几台设备上试用它。
  • 所以我做了一些实验,虽然对于我的案例discard 确实提供了小的性能提升,但这还不够。我将使用自定义几何进行深度测试
  • @solidpixel clip 怎么样?
  • ES 2.0 中不存在用户可控的剪辑窗格。
猜你喜欢
  • 1970-01-01
  • 2013-09-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-02-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多