Skip to content

Commit c06c566

Browse files
committed
Use loop for bi- and trilinear filtering in shader to speed up shader compilation and avoid WebGL crashes when many layers are present
1 parent d29e888 commit c06c566

File tree

1 file changed

+44
-24
lines changed

1 file changed

+44
-24
lines changed

frontend/javascripts/viewer/shaders/filtering.glsl.ts

Lines changed: 44 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -13,20 +13,32 @@ export const getBilinearColorFor: ShaderModule = {
1313
coordsUVW = coordsUVW + vec3(-0.5, -0.5, 0.0);
1414
vec2 bifilteringParams = (coordsUVW - floor(coordsUVW)).xy;
1515
coordsUVW = floor(coordsUVW);
16-
1716
bool supportsPrecomputedBucketAddress = false;
18-
vec4 a = getColorForCoords(layerIndex, d_texture_width, packingDegree, coordsUVW, supportsPrecomputedBucketAddress);
19-
vec4 b = getColorForCoords(layerIndex, d_texture_width, packingDegree, coordsUVW + vec3(1, 0, 0), supportsPrecomputedBucketAddress);
20-
vec4 c = getColorForCoords(layerIndex, d_texture_width, packingDegree, coordsUVW + vec3(0, 1, 0), supportsPrecomputedBucketAddress);
21-
vec4 d = getColorForCoords(layerIndex, d_texture_width, packingDegree, coordsUVW + vec3(1, 1, 0), supportsPrecomputedBucketAddress);
22-
if (a.a < 0.0 || b.a < 0.0 || c.a < 0.0 || d.a < 0.0) {
17+
18+
// Do not unroll this loop as it will lead to much slower compilation and
19+
// possibly WebGL crashes, because some compilers cannot optimize it as well then.
20+
vec4 samples[4];
21+
int idx = 0;
22+
for (int y = 0; y <= 1; y++) {
23+
for (int x = 0; x <= 1; x++) {
24+
vec3 offset = vec3(x, y, 0);
25+
samples[idx] = getColorForCoords(
26+
layerIndex, d_texture_width, packingDegree,
27+
coordsUVW + offset,
28+
supportsPrecomputedBucketAddress
29+
);
30+
idx++;
31+
}
32+
}
33+
34+
if (samples[0].a < 0.0 || samples[1].a < 0.0 || samples[2].a < 0.0 || samples[3].a < 0.0) {
2335
// We need to check all four colors for a negative parts, because there will be black
2436
// lines at the borders otherwise (black gets mixed with data)
2537
return vec4(0.0, 0.0, 0.0, -1.0);
2638
}
2739
28-
vec4 ab = mix(a, b, bifilteringParams.x);
29-
vec4 cd = mix(c, d, bifilteringParams.x);
40+
vec4 ab = mix(samples[0], samples[1], bifilteringParams.x);
41+
vec4 cd = mix(samples[2], samples[3], bifilteringParams.x);
3042
3143
return mix(ab, cd, bifilteringParams.y);
3244
}
@@ -46,29 +58,37 @@ export const getTrilinearColorFor: ShaderModule = {
4658
coordsUVW = floor(coordsUVW);
4759
bool supportsPrecomputedBucketAddress = false;
4860
49-
vec4 a = getColorForCoords(layerIndex, d_texture_width, packingDegree, coordsUVW, supportsPrecomputedBucketAddress);
50-
vec4 b = getColorForCoords(layerIndex, d_texture_width, packingDegree, coordsUVW + vec3(1, 0, 0), supportsPrecomputedBucketAddress);
51-
vec4 c = getColorForCoords(layerIndex, d_texture_width, packingDegree, coordsUVW + vec3(0, 1, 0), supportsPrecomputedBucketAddress);
52-
vec4 d = getColorForCoords(layerIndex, d_texture_width, packingDegree, coordsUVW + vec3(1, 1, 0), supportsPrecomputedBucketAddress);
53-
54-
vec4 a2 = getColorForCoords(layerIndex, d_texture_width, packingDegree, coordsUVW + vec3(0, 0, 1), supportsPrecomputedBucketAddress);
55-
vec4 b2 = getColorForCoords(layerIndex, d_texture_width, packingDegree, coordsUVW + vec3(1, 0, 1), supportsPrecomputedBucketAddress);
56-
vec4 c2 = getColorForCoords(layerIndex, d_texture_width, packingDegree, coordsUVW + vec3(0, 1, 1), supportsPrecomputedBucketAddress);
57-
vec4 d2 = getColorForCoords(layerIndex, d_texture_width, packingDegree, coordsUVW + vec3(1, 1, 1), supportsPrecomputedBucketAddress);
61+
// Do not unroll this loop as it will lead to much slower compilation and
62+
// possibly WebGL crashes, because some compilers cannot optimize it as well then.
63+
vec4 samples[8];
64+
int idx = 0;
65+
for (int z = 0; z <= 1; z++) {
66+
for (int y = 0; y <= 1; y++) {
67+
for (int x = 0; x <= 1; x++) {
68+
vec3 offset = vec3(x, y, z);
69+
samples[idx] = getColorForCoords(
70+
layerIndex, d_texture_width, packingDegree,
71+
coordsUVW + offset,
72+
supportsPrecomputedBucketAddress
73+
);
74+
idx++;
75+
}
76+
}
77+
}
5878
59-
if (a.a < 0.0 || b.a < 0.0 || c.a < 0.0 || d.a < 0.0 ||
60-
a2.a < 0.0 || b2.a < 0.0 || c2.a < 0.0 || d2.a < 0.0) {
61-
// We need to check all four colors for a negative parts, because there will be black
79+
if (samples[0].a < 0.0 || samples[1].a < 0.0 || samples[2].a < 0.0 || samples[3].a < 0.0 ||
80+
samples[4].a < 0.0 || samples[5].a < 0.0 || samples[6].a < 0.0 || samples[7].a < 0.0) {
81+
// We need to check all eight colors for a negative parts, because there will be black
6282
// lines at the borders otherwise (black gets mixed with data)
6383
return vec4(0.0, 0.0, 0.0, -1.0);
6484
}
6585
66-
vec4 ab = mix(a, b, bifilteringParams.x);
67-
vec4 cd = mix(c, d, bifilteringParams.x);
86+
vec4 ab = mix(samples[0], samples[1], bifilteringParams.x);
87+
vec4 cd = mix(samples[2], samples[3], bifilteringParams.x);
6888
vec4 abcd = mix(ab, cd, bifilteringParams.y);
6989
70-
vec4 ab2 = mix(a2, b2, bifilteringParams.x);
71-
vec4 cd2 = mix(c2, d2, bifilteringParams.x);
90+
vec4 ab2 = mix(samples[4], samples[5], bifilteringParams.x);
91+
vec4 cd2 = mix(samples[6], samples[7], bifilteringParams.x);
7292
7393
vec4 abcd2 = mix(ab2, cd2, bifilteringParams.y);
7494

0 commit comments

Comments
 (0)