From a97234574dd64acc98c5f52f62cb72accb0bba46 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Foucault?= Date: Sun, 24 Oct 2021 19:18:46 +0200 Subject: EEVEE: Deffered: Change normal packing for better negative normals The spheremap encoding has a singularity issue for inverted normals which are used by the translucent BSDF. This fixes the issue. --- .../engines/eevee/shaders/eevee_gbuffer_lib.glsl | 34 +++++++++++++++------- .../eevee/shaders/eevee_subsurface_eval_frag.glsl | 9 +++--- .../eevee/shaders/eevee_surface_deferred_frag.glsl | 2 +- 3 files changed, 30 insertions(+), 15 deletions(-) (limited to 'source/blender/draw/engines/eevee/shaders') diff --git a/source/blender/draw/engines/eevee/shaders/eevee_gbuffer_lib.glsl b/source/blender/draw/engines/eevee/shaders/eevee_gbuffer_lib.glsl index caec0fb1673..15a1349c417 100644 --- a/source/blender/draw/engines/eevee/shaders/eevee_gbuffer_lib.glsl +++ b/source/blender/draw/engines/eevee/shaders/eevee_gbuffer_lib.glsl @@ -25,12 +25,24 @@ float gbuffer_decode_unit_float_from_uint(uint packed_scalar, const uint bit_siz /* Expects input to be normalized. */ vec2 gbuffer_encode_normal(vec3 normal) { - return normal_encode(normal_world_to_view(normal)); + vec3 vN = normal_world_to_view(normal); + bool neg = vN.z < 0.0; + if (neg) { + vN.z = -vN.z; + } + vec2 packed_normal = normal_encode(vN); + // return packed_normal; + return (neg) ? -packed_normal : packed_normal; } vec3 gbuffer_decode_normal(vec2 packed_normal) { - return normal_view_to_world(normal_decode(packed_normal)); + bool neg = packed_normal.y < 0.0; + vec3 vN = normal_decode(abs(packed_normal)); + if (neg) { + vN.z = -vN.z; + } + return normal_view_to_world(vN); } /* Note: does not handle negative colors. */ @@ -89,16 +101,18 @@ void gbuffer_load_global_data(vec4 transmit_normal_in, out float thickness) ClosureDiffuse gbuffer_load_diffuse_data(vec4 color_in, vec4 normal_in, vec4 data_in) { ClosureDiffuse data_out; - if (normal_in.x > 0.0) { - data_out.color = color_in.rgb; - data_out.N = gbuffer_decode_normal(normal_in.xy); - } - else { + if (normal_in.z == -1.0) { + /* Transmission data is Refraction data. */ data_out.color = vec3(0.0); data_out.N = vec3(1.0); + data_out.sss_id = 0u; + } + else { + data_out.color = color_in.rgb; + data_out.N = gbuffer_decode_normal(normal_in.xy); + data_out.sss_id = uint(normal_in.z * 1024.0); } data_out.sss_radius = data_in.rgb; - data_out.sss_id = uint(normal_in.z * 1024.0); return data_out; } @@ -137,9 +151,9 @@ ClosureReflection gbuffer_load_reflection_data(sampler2D reflect_color_tx, ClosureRefraction gbuffer_load_refraction_data(vec4 color_in, vec4 normal_in, vec4 data_in) { ClosureRefraction data_out; - if (normal_in.x < 0.0) { + if (normal_in.z == -1.0) { data_out.color = color_in.rgb; - data_out.N = gbuffer_decode_normal(-normal_in.xy); + data_out.N = gbuffer_decode_normal(normal_in.xy); data_out.ior = data_in.x; data_out.roughness = data_in.y; } diff --git a/source/blender/draw/engines/eevee/shaders/eevee_subsurface_eval_frag.glsl b/source/blender/draw/engines/eevee/shaders/eevee_subsurface_eval_frag.glsl index 9e0a07d9c94..de4c8cb59a6 100644 --- a/source/blender/draw/engines/eevee/shaders/eevee_subsurface_eval_frag.glsl +++ b/source/blender/draw/engines/eevee/shaders/eevee_subsurface_eval_frag.glsl @@ -74,14 +74,15 @@ void main(void) vec4 tra_nor_in = texture(transmit_normal_tx, center_uv); vec4 tra_dat_in = texture(transmit_data_tx, center_uv); - if (tra_nor_in.x < 0.0) { - /* Refraction transmission case. */ + ClosureDiffuse diffuse = gbuffer_load_diffuse_data(tra_col_in, tra_nor_in, tra_dat_in); + + if (diffuse.sss_id <= 0u) { + /* Normal diffuse is already in combined pass. */ + /* Refraction also go into this case. */ out_combined = vec4(0.0); return; } - ClosureDiffuse diffuse = gbuffer_load_diffuse_data(tra_col_in, tra_nor_in, tra_dat_in); - float max_radius = max_v3(diffuse.sss_radius); float homcoord = ProjectionMatrix[2][3] * vP.z + ProjectionMatrix[3][3]; diff --git a/source/blender/draw/engines/eevee/shaders/eevee_surface_deferred_frag.glsl b/source/blender/draw/engines/eevee/shaders/eevee_surface_deferred_frag.glsl index 7578794c206..51e00ef43d3 100644 --- a/source/blender/draw/engines/eevee/shaders/eevee_surface_deferred_frag.glsl +++ b/source/blender/draw/engines/eevee/shaders/eevee_surface_deferred_frag.glsl @@ -75,7 +75,7 @@ void main(void) if (g_data.transmit_rand == 0.0) { out_transmit_color = g_refraction_data.color; - out_transmit_normal.xy = -gbuffer_encode_normal(g_refraction_data.N); + out_transmit_normal.xy = gbuffer_encode_normal(g_refraction_data.N); out_transmit_normal.z = -1.0; out_transmit_normal.w = thickness; out_transmit_data.x = g_refraction_data.ior; -- cgit v1.2.3