所以看起来iOS上GL_ALPHA_TEST的性能非常差。引用Apple:
在计算片段的颜色值之前,图形硬件通常会在图形管道的早期执行深度测试。如果您的应用程序在OpenGL ES 1.1中使用alpha测试或在OpenGL ES 2.0片段着色器中使用
discard
指令,则必须禁用某些硬件深度缓冲区优化。特别是,这可能需要完全计算片段的颜色才被丢弃,因为片段不可见。使用alpha测试或丢弃来杀死像素的替代方法是使用alpha混合,alpha强制为零。这有效地消除了对帧缓冲区颜色的任何贡献,同时保留了Z缓冲区优化。这确实会改变存储在深度缓冲区中的值,因此可能需要对透明图元进行从前到后的排序。
如果需要使用alpha测试或
discard
指令,请在处理不需要它的任何基元后在场景中单独绘制这些对象。在片段着色器的早期放置discard
指令,以避免执行结果未使用的计算。
我想知道:他们究竟是什么意思“使用α混合与alpha强制为零”。你怎么能做到这一点?或者,有没有其他方法可以根据alpha值省略/隐藏像素?
我考虑过使用纹理合成器或各种混合模式(包括glBlendFuncSeparateOES
)。但是,这项工作似乎没什么。我想有一个单独的alpha纹理和使用纹理合并器可以工作。不过,我真的更喜欢只有一个纹理。
答案 0 :(得分:1)
这个问题很深刻,与深度缓冲有关。您可以在着色器代码中将alpha设置为零,但仍然会输出深度片段,因此根据您使用alpha测试的原因,它只是部分解决方法。所以你可以偏差alpha和缩放大数(以避免着色器分支)然后钳位你会得到一个锐利的描绘alpha测试边缘,但透明像素仍将填充zbuffer,如果那是你使用alpha测试的原因你仍然没有好转。你无法真正解决着色器中的核心问题。您可以调整您的内容以最小化这个并且可能绘制不透明的未经测试的z并且最后进行alpha测试的transprency。这种影响z的细节可以从平台到平台。在某些平台上,zbuffer优化(如早期z和粗糙z)可能会从那时起永久禁用,直到下一次清除,因此在延迟alpha测试时你可以获得性能,但实际上这取决于实现的细节。
调整艺术品以最小化透明片段,并在渲染时尽可能晚地使用alpha测试,如果无法避免的话。
此外,如果你有一个丢弃函数,在着色器的末尾使用它来对抗恒定的alpha测试,它可能是违反直觉的,但是一些实现优化了这个alpha测试丢弃以使用比着色器分支更好的固定功能硬件(在某些平台上)。这又取决于GPU线程流控制的复杂程度。具有高效分支的未来平台可能会从早期实现这一目标中受益,您基本上是试图利用隐藏的实施优化方式,这些优化因平台而异,并且将来会发生变化。