微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

通过统一突破GLSL循环

如何解决通过统一突破GLSL循环

我想计算浏览器中GLSL中约1000行,4000列的浮点矩阵的每行最小值。

基于先前的答案(请参阅this),我使用了for循环。但是,我想使用统一的上限,这在WebGL GLSL ES 1.0中是不可能的。这是因为行的长度是在片段着色器之后定义的,我想避免弄乱#DEFINE s。

因此,我发现此解决方法-使用统一定义的if/break固定周期长度-可以正常工作:

#define MAX_INT 65536
  
void main(void) {
  float m = 0.0;
  float k = -1.0;
  int   r = 40;

  for(int i = 0; i < MAX_INT; ++i){
    float ndx = floor(gl_FragCoord.y) * float(r) + float(i); 
    float a = getPoint(values,dimensions,ndx).x;
    m = m > a ? m : a;
    if (i >= r) { break; }
  };
}

现在的问题是:这有很大的弊端吗?我在做些奇怪的事情,我想念什么吗?

解决方法

我相信,但不是完全确定,唯一的风险是某些驱动程序/ GPU仍会造成长循环。

作为一个例子,想象一下这个循环

uniform int limit;

void main() {
  float sum = 0;
  for (int i = 0; i < 3; ++i) {
    sum += texture2D(tex,vec2(float(i) / 3,0)).r;
    if (i >= limit) {
      break;
    }
  }
  gl_FragColor = vec4(sum);
}

可以像这样由驱动程序重写

uniform int limit;

void main() {
  float sum = 0;
  for (int i = 0; i < 3; ++i) {
    float temp = texture2D(tex,0)).r;
    sum += temp * step(float(i),float(limit));
  }
  gl_FragColor = vec4(sum);
}

没有分支。我不知道是否仍然存在没有条件的此类驱动程序/ gpu,但是需要为循环使用const整数表达式的想法是,这样,如果驱动程序可以删除分支和/或在编译时展开循环/ GPU决定两者之一。

uniform int limit;

void main() {
  float sum = 0;
  sum += step(float(0),float(limit)) * texture2D(tex,vec2(float(0) / 3,0)).r;
  sum += step(float(1),vec2(float(1) / 3,0)).r;
  sum += step(float(2),vec2(float(2) / 3,0)).r;
  gl_FragColor = vec4(sum);
}

此外,顺便提一句,您上面的特定示例不输出任何内容,因此大多数驱动程序会将整个着色器变为无操作。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。