GLSL - 优化 if-else

Mar*_*key 4 shader if-statement glsl

我有 GLSL 移动着色器(ES 2.0),里面有这个:

float b = texture2D(t, texCoord).r;
float s = 0.0;
if (b > 240.0) s = b - 2322.2;
else if (b > 90.0) s = b - 74.0;    
else if (b < 10.0) s = b / 10.0;
else s = b - 10.0;  
Run Code Online (Sandbox Code Playgroud)

会不会很慢?我知道,应该避免着色器中的分支。有什么办法,如何重写这个来删除 ifs 吗?

Rab*_*d76 5

我建议使用 GLSL 函数mixstep.

mixa根据[0.0, 1.0] 范围内的浮点插值值在 2 个值之间进行插值。如果a等于 0.0,则返回第一个值;如果a等于 1.0,则返回第二个值。

step测试某个值是否小于边缘值。如果小于则返回 0.0,否则返回 1.0。

如果您结合这两个函数,您的代码将如下所示:

float b = texture2D(t, texCoord).r;
float s = mix(
    mix( b/10.0, b-10.0,   step(10.0, b) ),
    mix( b-74.0, b-2322.2, step(240.0, b) ),
    step(90.0, b) );
Run Code Online (Sandbox Code Playgroud)

请注意, 的结果step要么正好是 0.0,要么正好是 1.0,这导致mix要么返回第一个值,要么返回第二个值。

  • 根据我的经验,使用“step”和“mix”*总是*慢**,即使在制服上“踩”时,您的代码需要始终执行*所有*操作,只留下*可以*优化的两个lerp ,而OP的原始代码有机会只执行一个操作。不过,暂时搁置这一点,我认为这里的正确答案应该是“在目标硬件上进行配置并在必要时进行优化”,尽管我高度怀疑这是过早优化的情况。 (4认同)