summaryrefslogtreecommitdiff
path: root/servers/rendering/renderer_rd
diff options
context:
space:
mode:
authorclayjohn <claynjohn@gmail.com>2023-05-03 01:06:34 -0700
committerRĂ©mi Verschelde <rverschelde@gmail.com>2023-05-12 12:07:01 +0200
commit2435c9426d3b5aba64f2aafffe1d5fc8fa06d5a7 (patch)
tree6fa1687a3e17948ee3f6dd63ca62d2a32326d0a3 /servers/rendering/renderer_rd
parente68e2fad25eaba112bee37234be89d1bb5829869 (diff)
Use proper UV in cubemap downsampler raster
This removes bias in cubemap downsampling shader that resulted in the bottom of cubemaps being over represented (cherry picked from commit fb77021559c42d5512f12baa07dcf94c47b7ab15)
Diffstat (limited to 'servers/rendering/renderer_rd')
-rw-r--r--servers/rendering/renderer_rd/shaders/effects/cubemap_downsampler_raster.glsl204
1 files changed, 101 insertions, 103 deletions
diff --git a/servers/rendering/renderer_rd/shaders/effects/cubemap_downsampler_raster.glsl b/servers/rendering/renderer_rd/shaders/effects/cubemap_downsampler_raster.glsl
index 0828ffd921..b8c64d09f4 100644
--- a/servers/rendering/renderer_rd/shaders/effects/cubemap_downsampler_raster.glsl
+++ b/servers/rendering/renderer_rd/shaders/effects/cubemap_downsampler_raster.glsl
@@ -55,109 +55,107 @@ void main() {
// Converted from compute shader which uses absolute coordinates.
// Could possibly simplify this
float face_size = float(params.face_size);
+ float inv_face_size = 1.0 / face_size;
+ vec2 id = floor(uv_interp);
- if (uv_interp.x < face_size && uv_interp.y < face_size) {
- float inv_face_size = 1.0 / face_size;
-
- float u0 = (uv_interp.x * 2.0 + 1.0 - 0.75) * inv_face_size - 1.0;
- float u1 = (uv_interp.x * 2.0 + 1.0 + 0.75) * inv_face_size - 1.0;
-
- float v0 = (uv_interp.y * 2.0 + 1.0 - 0.75) * -inv_face_size + 1.0;
- float v1 = (uv_interp.y * 2.0 + 1.0 + 0.75) * -inv_face_size + 1.0;
-
- float weights[4];
- weights[0] = calcWeight(u0, v0);
- weights[1] = calcWeight(u1, v0);
- weights[2] = calcWeight(u0, v1);
- weights[3] = calcWeight(u1, v1);
-
- const float wsum = 0.5 / (weights[0] + weights[1] + weights[2] + weights[3]);
- for (int i = 0; i < 4; i++) {
- weights[i] = weights[i] * wsum + .125;
- }
-
- vec3 dir;
- vec4 color;
- switch (params.face_id) {
- case 0:
- get_dir_0(dir, u0, v0);
- color = textureLod(source_cubemap, normalize(dir), 0.0) * weights[0];
-
- get_dir_0(dir, u1, v0);
- color += textureLod(source_cubemap, normalize(dir), 0.0) * weights[1];
-
- get_dir_0(dir, u0, v1);
- color += textureLod(source_cubemap, normalize(dir), 0.0) * weights[2];
-
- get_dir_0(dir, u1, v1);
- color += textureLod(source_cubemap, normalize(dir), 0.0) * weights[3];
- break;
- case 1:
- get_dir_1(dir, u0, v0);
- color = textureLod(source_cubemap, normalize(dir), 0.0) * weights[0];
-
- get_dir_1(dir, u1, v0);
- color += textureLod(source_cubemap, normalize(dir), 0.0) * weights[1];
-
- get_dir_1(dir, u0, v1);
- color += textureLod(source_cubemap, normalize(dir), 0.0) * weights[2];
-
- get_dir_1(dir, u1, v1);
- color += textureLod(source_cubemap, normalize(dir), 0.0) * weights[3];
- break;
- case 2:
- get_dir_2(dir, u0, v0);
- color = textureLod(source_cubemap, normalize(dir), 0.0) * weights[0];
-
- get_dir_2(dir, u1, v0);
- color += textureLod(source_cubemap, normalize(dir), 0.0) * weights[1];
-
- get_dir_2(dir, u0, v1);
- color += textureLod(source_cubemap, normalize(dir), 0.0) * weights[2];
-
- get_dir_2(dir, u1, v1);
- color += textureLod(source_cubemap, normalize(dir), 0.0) * weights[3];
- break;
- case 3:
- get_dir_3(dir, u0, v0);
- color = textureLod(source_cubemap, normalize(dir), 0.0) * weights[0];
-
- get_dir_3(dir, u1, v0);
- color += textureLod(source_cubemap, normalize(dir), 0.0) * weights[1];
-
- get_dir_3(dir, u0, v1);
- color += textureLod(source_cubemap, normalize(dir), 0.0) * weights[2];
-
- get_dir_3(dir, u1, v1);
- color += textureLod(source_cubemap, normalize(dir), 0.0) * weights[3];
- break;
- case 4:
- get_dir_4(dir, u0, v0);
- color = textureLod(source_cubemap, normalize(dir), 0.0) * weights[0];
-
- get_dir_4(dir, u1, v0);
- color += textureLod(source_cubemap, normalize(dir), 0.0) * weights[1];
-
- get_dir_4(dir, u0, v1);
- color += textureLod(source_cubemap, normalize(dir), 0.0) * weights[2];
-
- get_dir_4(dir, u1, v1);
- color += textureLod(source_cubemap, normalize(dir), 0.0) * weights[3];
- break;
- default:
- get_dir_5(dir, u0, v0);
- color = textureLod(source_cubemap, normalize(dir), 0.0) * weights[0];
-
- get_dir_5(dir, u1, v0);
- color += textureLod(source_cubemap, normalize(dir), 0.0) * weights[1];
-
- get_dir_5(dir, u0, v1);
- color += textureLod(source_cubemap, normalize(dir), 0.0) * weights[2];
-
- get_dir_5(dir, u1, v1);
- color += textureLod(source_cubemap, normalize(dir), 0.0) * weights[3];
- break;
- }
- frag_color = color;
+ float u1 = (id.x * 2.0 + 1.0 + 0.75) * inv_face_size - 1.0;
+ float u0 = (id.x * 2.0 + 1.0 - 0.75) * inv_face_size - 1.0;
+
+ float v0 = (id.y * 2.0 + 1.0 - 0.75) * -inv_face_size + 1.0;
+ float v1 = (id.y * 2.0 + 1.0 + 0.75) * -inv_face_size + 1.0;
+
+ float weights[4];
+ weights[0] = calcWeight(u0, v0);
+ weights[1] = calcWeight(u1, v0);
+ weights[2] = calcWeight(u0, v1);
+ weights[3] = calcWeight(u1, v1);
+
+ const float wsum = 0.5 / (weights[0] + weights[1] + weights[2] + weights[3]);
+ for (int i = 0; i < 4; i++) {
+ weights[i] = weights[i] * wsum + .125;
+ }
+
+ vec3 dir;
+ vec4 color;
+ switch (params.face_id) {
+ case 0:
+ get_dir_0(dir, u0, v0);
+ color = textureLod(source_cubemap, normalize(dir), 0.0) * weights[0];
+
+ get_dir_0(dir, u1, v0);
+ color += textureLod(source_cubemap, normalize(dir), 0.0) * weights[1];
+
+ get_dir_0(dir, u0, v1);
+ color += textureLod(source_cubemap, normalize(dir), 0.0) * weights[2];
+
+ get_dir_0(dir, u1, v1);
+ color += textureLod(source_cubemap, normalize(dir), 0.0) * weights[3];
+ break;
+ case 1:
+ get_dir_1(dir, u0, v0);
+ color = textureLod(source_cubemap, normalize(dir), 0.0) * weights[0];
+
+ get_dir_1(dir, u1, v0);
+ color += textureLod(source_cubemap, normalize(dir), 0.0) * weights[1];
+
+ get_dir_1(dir, u0, v1);
+ color += textureLod(source_cubemap, normalize(dir), 0.0) * weights[2];
+
+ get_dir_1(dir, u1, v1);
+ color += textureLod(source_cubemap, normalize(dir), 0.0) * weights[3];
+ break;
+ case 2:
+ get_dir_2(dir, u0, v0);
+ color = textureLod(source_cubemap, normalize(dir), 0.0) * weights[0];
+
+ get_dir_2(dir, u1, v0);
+ color += textureLod(source_cubemap, normalize(dir), 0.0) * weights[1];
+
+ get_dir_2(dir, u0, v1);
+ color += textureLod(source_cubemap, normalize(dir), 0.0) * weights[2];
+
+ get_dir_2(dir, u1, v1);
+ color += textureLod(source_cubemap, normalize(dir), 0.0) * weights[3];
+ break;
+ case 3:
+ get_dir_3(dir, u0, v0);
+ color = textureLod(source_cubemap, normalize(dir), 0.0) * weights[0];
+
+ get_dir_3(dir, u1, v0);
+ color += textureLod(source_cubemap, normalize(dir), 0.0) * weights[1];
+
+ get_dir_3(dir, u0, v1);
+ color += textureLod(source_cubemap, normalize(dir), 0.0) * weights[2];
+
+ get_dir_3(dir, u1, v1);
+ color += textureLod(source_cubemap, normalize(dir), 0.0) * weights[3];
+ break;
+ case 4:
+ get_dir_4(dir, u0, v0);
+ color = textureLod(source_cubemap, normalize(dir), 0.0) * weights[0];
+
+ get_dir_4(dir, u1, v0);
+ color += textureLod(source_cubemap, normalize(dir), 0.0) * weights[1];
+
+ get_dir_4(dir, u0, v1);
+ color += textureLod(source_cubemap, normalize(dir), 0.0) * weights[2];
+
+ get_dir_4(dir, u1, v1);
+ color += textureLod(source_cubemap, normalize(dir), 0.0) * weights[3];
+ break;
+ default:
+ get_dir_5(dir, u0, v0);
+ color = textureLod(source_cubemap, normalize(dir), 0.0) * weights[0];
+
+ get_dir_5(dir, u1, v0);
+ color += textureLod(source_cubemap, normalize(dir), 0.0) * weights[1];
+
+ get_dir_5(dir, u0, v1);
+ color += textureLod(source_cubemap, normalize(dir), 0.0) * weights[2];
+
+ get_dir_5(dir, u1, v1);
+ color += textureLod(source_cubemap, normalize(dir), 0.0) * weights[3];
+ break;
}
+ frag_color = color;
}