Glsl 通过统一的

Glsl 通过统一的,glsl,webgl,Glsl,Webgl,我想计算浏览器中GLSL中浮动矩阵的每行最小值,大约1000行,4000列 基于前面的答案(请参阅),我使用了一个for循环。但是,我希望使用统一的上限,这在WebGL GLSL ES 1.0中是不可能的。这是因为行的长度是在片段着色器之后定义的,我希望避免与#DEFINEs混淆 因此,我发现这个变通方法-固定周期长度,由统一定义为if/break,可以: #define MAX_INT 65536 void main(void) { float m = 0.0; float k

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

基于前面的答案(请参阅),我使用了一个
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; }
  };
}
#定义最大值65536
真空总管(真空){
浮点数m=0.0;
浮动k=-1.0;
int r=40;
对于(int i=0;ia?m:a;
如果(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);
}

另外,作为旁白,上面的特定示例没有输出任何内容,因此大多数驱动程序都会将整个着色器转换为不可操作。根据GPU体系结构,中断(退出)循环不会释放该内核。它将等待相关的并行内核也退出其循环。ES3(循环/条件出口)也受到这种需求的约束。实现早期退出(同样取决于体系结构)是值得的。空闲内核使用的功率只有繁忙内核使用的功率的一小部分。更少的能量。。。少一些热量。。更高的时钟速度(如果可用)=增加了总体吞吐量。这是正在发生的事情的缩略600字符注释版本。经验法则是执行时间最长的核心是时间4所有PAR核
uniform int limit;

void main() {
  float sum = 0;
  for (int i = 0; i < 3; ++i) {
    float temp = texture2D(tex, vec2(float(i) / 3, 0)).r;
    sum += temp * step(float(i), float(limit));
  }
  gl_FragColor = vec4(sum);
}
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), float(limit)) * texture2D(tex, vec2(float(1) / 3, 0)).r;
  sum += step(float(2), float(limit)) * texture2D(tex, vec2(float(2) / 3, 0)).r;
  gl_FragColor = vec4(sum);
}