【发布时间】:2016-05-08 08:01:52
【问题描述】:
我正在开发用于 2D 冲击波的后处理 GLSL (ES) 片段着色器。在一个圆圈中稍微扭曲纹理很容易,它已经适用于单个冲击波。现在我需要同时支持多波,我的想法:
第一个想法:对每个波进行后处理(绑定 FBO -> 绑定先前的纹理 -> 绘制调用)。易于实现,但有很多状态更改和绘图调用。
第二个想法:添加包含所有波的所有信息的数据纹理和带有数字波的单个制服,所以我可以这样做:
uniform int count;
uniform sampler2D dataTex;
const float dataTexSize = 32;
[...]
vec4 pixel;
for(int i = 0; i < count; i++)
{
vec2 dataTexPos = vec2(i / dataTexSize, 0);
pixel += shockwave(texture2D(dataTex, dataTexPos));
}
pixel /= float(count);
[...]
但显然 GPU 不喜欢带有非常量表达式且驱动程序无法展开的循环。
是否有给着色器“动态工作量”的最佳实践?我的 OpenGL 版本是 2.0 ES。
【问题讨论】:
-
您可以尝试在您可以访问的任何硬件上分析这两种实现。
-
问题是,第二个想法根本行不通,因为我无法将带有 for 循环的着色器编译为非常数。我想知道是否有办法做到这一点。
-
"但显然 GPU 不喜欢带有非常数表达式的循环" 不,糟糕的 GPU 不喜欢那样。 ES 2.0 不允许非常量循环,但实际上现代 GPU 完全可以使用它。近十年前,Desktop GL 3.0 放弃了这些要求。在移动领域,GL ES 3.0 放弃了这些要求。
-
你完全正确。但不幸的是,我仅限于 2.0 ES。
标签: opengl-es glsl fragment-shader