I am making multiple gradients with GLSL. However, when I started using a loop instead
of a lengthy else if
condition, the compile time jumped from 2-4sec to 40sec !
// (simplified code)
vec3 gradient(vec3 from, vec3 to, float cursor, int colorSpace) {
vec3 color;
// !! The more switch case there are, the slower it gets, but only perceptible when using a loop (in getBackgroundColor function bellow)
switch(colorSpace) {
case 0:
color = mix(
from,
to,
cursor
);
break;
case 1:
// return gradient, but using Oklab colors
case 2:
// return gradient but using IPT colors, etc
// ... up to 13
}
return color;
}
vec4 getBackgroundColor (vec2 uv, EffectOptions opt) {
vec3 color;
if (opt.effect == 0) {
// transparent
} else if (opt.effect == 1) {
// pattern from image
} else if (opt.effect == 2) {
// gradient
color = gradient(
opt.color0,
backgroundColor,
uvxCursor,
opt.gradientColorSpace
);
} else if (opt.effect == 3) { // debug gradients by showing all of them
uv.y = -uv.y;
uv += 1.;
uv/= 2.;
float uvxCursor = clamp(uv.x, 0., 1.);
int totalBand = 13; // !! totalBand can be 2, it doesn't seem to changes the compile time at all
// Simple loop to avoid a lengthy elseif
// !! Extremely slow: 40sec compilation time. What is wrong with this loop ??
for (int i = 0; i < totalBand; i++) {
if (uv.y < float(i+1)/float(totalBand)) {
color = gradient(
opt.color0,
backgroundColor,
uvxCursor,
i
);
break;
}
}
}
// else... up to 10
return vec4(color, 1.);
}
If I use a else if statement like bellow, the compilation goes back to 2sec.
if (uv.y < 1./13.) {
color = gradient(
opt.color0,
backgroundColor,
uvxCursor,
0
);
} else if (uv.y < 2./13.) {
color = gradient(
opt.color0,
backgroundColor,
uvxCursor,
1
);
} // ... up to 13
I have seen this answer https://stackoverflow.com/questions/54408908/custom-shader-material-taking-forever-to-initialize , and it might have something to do with "dynamic branching".
But I am quite new to shaders and have a limited understanding. Is there something obviously wrong with using a loop that I am not seeing ?
PS: I am also using ThreeJS version v135 right now (not the latest). I don't think it is an issue, but if nobody sees an issue with the loop above, then I will have to think outside the box.
PS 2: I profiled my web page, and I think the issue is 99% likely to come from GLSL compilation based on https://discourse.threejs.org/t/getprograminfolog-performance-issue/41069