如何解决通过统一突破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] 举报,一经查实,本站将立刻删除。