From 2435c9426d3b5aba64f2aafffe1d5fc8fa06d5a7 Mon Sep 17 00:00:00 2001 From: clayjohn Date: Wed, 3 May 2023 01:06:34 -0700 Subject: 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) --- .../effects/cubemap_downsampler_raster.glsl | 204 ++++++++++----------- 1 file changed, 101 insertions(+), 103 deletions(-) (limited to 'servers') 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; } -- cgit v1.2.3