解决方案#1:
- 以任何顺序首先渲染所有非透明对象,启用深度缓冲区。这包括所有使用 alpha 测试而不使用alpha 混合的对象。
- 对于
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)
对象(烟雾/玻璃/草):将透明场景从最远的多边形渲染到最近的多边形,并禁用深度缓冲区写入 ( glDepthMask(GL_FALSE)
)。如果所有透明对象都是凸面且不相交,则可以对对象进行排序而不是对多边形进行排序。
- 对于
glBlendFunc(GL_SRC_ALPHA, GL_ONE)
和(火,“魔法”粒子系统,发光):以任何顺序渲染透明场景,并禁用glBlend(GL_ONE, GL_ONE)
深度缓冲区写入 ( )。glDepthMask(GL_FALSE)
- 在第 3 步之后不要渲染任何启用深度缓冲的对象。
解决方案#2:
使用深度剥离(google it)。特别是如果透明对象彼此相交。不适用于需要解决方案 #1 的粒子系统和草。
然后几乎每一帧都在 CPU 上手动对它们进行排序
插入排序适用于已排序或部分排序的数据。
必须有一种方法可以将其委托给 GPU ......
我认为您可以使用具有通道(例如,alpha)的纹理在几何着色器中生成草多边形(以正确的顺序),该通道标记有草和没有草的区域。需要 OpenGL 4,并且您可能必须对将馈送到着色器以生成草地补丁的多边形执行某种更高级别的排序。
单个灌木可以在顶点着色器中旋转(+- 90/180/270 度)以保持正确的多边形顺序,如果它们在所有方向上都是完全对称的。
还有合并排序算法,可以很好地并行化并且可以在 GPU 上执行,使用 GDGPU 方法或 OpenCL/CUDA。
然而,使用类似的东西来渲染 5 个草丛大致相当于试图用榴弹发射器杀死一只蟑螂 - 这样做很有趣,但效率不高。
我建议在您真正遇到性能问题之前忘记“将其卸载到 GPU”。使用分析器并始终在优化之前进行测量,否则您将浪费大量开发时间进行不必要的优化。