Opengl es 如何在没有if-else分支的情况下实现此功能?(GLSL)

Opengl es 如何在没有if-else分支的情况下实现此功能?(GLSL),opengl-es,glsl,glsles,Opengl Es,Glsl,Glsles,我正在使用opengles2.0 如果可能的话,我想消除片段着色器中的分支。但有一个功能我无法改进: float HS(in float p, in float c) { float ap = abs(p); if( ap > (c*1.5) ) { return ap - c ; } else { return mod(ap+0.5*c,c)-0.5*c; } } c在大多数情况下都是常量,如果在这种情况下有用的话。

我正在使用
opengles2.0

如果可能的话,我想消除片段着色器中的分支。但有一个功能我无法改进:

float HS(in float p, in float c) {

    float ap = abs(p);

    if( ap > (c*1.5) ) {
        return ap - c ;
    } else {
        return mod(ap+0.5*c,c)-0.5*c;
    }

}
c
在大多数情况下都是常量,如果在这种情况下有用的话。我这样使用这个函数:

vec3 op = sign(p1)*vec3(
    HS(p1.x, cc),
    HS(p1.y, cc),
    HS(p1.z, cc)
);
这里有一个“消除”分支的技巧。但它所做的更重要的事情是将代码矢量化。毕竟,编译器可能为您消除了分支;它不太可能意识到它可以做到这一点:

vec3 HSvec(in vec3 p, in const float c)
{
  vec3 ap = abs(p);
  vec3 side1 = ap - c;
  const float val = 0.5 * c;
  vec3 side2 = mod(ap + val, vec3(c)) - val;

  bvec3 tests = greaterThan(ap, vec3(c*1.5));
  return mix(side2, side1, vec3(tests));
}
这消除了大量冗余计算,同时也消除了大量计算


这里的关键是
mix
功能
mix
基于第三个参数在两个参数之间执行线性插值。但是由于
bool
转换为
float
的值正好是1.0或0.0,因此实际上只需选择
side1
side2
。并且此选择是由组件操作的结果定义的。

是要提高此代码的性能,还是要删除该条件?因为这是两件不同的事情。我想通过先删除if-else分支来提高代码的性能。如果这不是提高性能的最有效方法呢?在这种情况下,我对任何类型的优化都很好奇。它是有效的,但代码应该是:
lessThan(vec3(c*1.5),ap)
@IterAtor:Or
大于
;我们也有。到目前为止,我还没有听说过比更伟大的。这就是我一直在寻找的答案。您能给我一些提示吗,这段代码应该如何进行更优化?调用mod()可能比较昂贵,所以如果您遇到性能问题,尝试避免这样做会很好。但是,如果没有看到代码的其余部分,就很难说这是否可能。