diff options
author | Clément Foucault <foucault.clem@gmail.com> | 2021-02-20 18:54:06 +0300 |
---|---|---|
committer | Clément Foucault <foucault.clem@gmail.com> | 2021-02-21 03:33:56 +0300 |
commit | 1a9fe57a9f6e53e5f34c95441be27296dadefa75 (patch) | |
tree | 27db7dc426bc1ff532e83d590702aa5cfa1bebab /source | |
parent | 274d7b87fdf25bff97569ae346ec1d5020558637 (diff) |
EEVEE: Planar Reflections: Fix regression
Fix regression with roughness not masking reflections when not using
Screen Space raytracing.
The trick was to only evaluate one planar per pixel, the one with
the most influence. This should not be too limiting since this is what
we do for SSR.
Also change evaluation order do not apply occlusion on planars probes.
Diffstat (limited to 'source')
4 files changed, 36 insertions, 29 deletions
diff --git a/source/blender/draw/engines/eevee/shaders/closure_eval_glossy_lib.glsl b/source/blender/draw/engines/eevee/shaders/closure_eval_glossy_lib.glsl index ae7f371e8d2..5c10a7f451f 100644 --- a/source/blender/draw/engines/eevee/shaders/closure_eval_glossy_lib.glsl +++ b/source/blender/draw/engines/eevee/shaders/closure_eval_glossy_lib.glsl @@ -84,13 +84,13 @@ void closure_Glossy_planar_eval(ClosureInputGlossy cl_in, inout ClosureOutputGlossy cl_out) { #ifndef STEP_RESOLVE /* SSR already evaluates planar reflections. */ + float attenuation = planar.attenuation * probe_attenuation_planar_normal_roughness( + planar.data, cl_in.N, cl_in.roughness); + vec3 probe_radiance = probe_evaluate_planar( planar.id, planar.data, cl_common.P, cl_in.N, cl_common.V, cl_in.roughness); - cl_out.radiance += planar.attenuation * probe_radiance; -#else - /* HACK: Fix an issue with planar reflections still being counted inside the specular - * accumulator. This only works because we only use one Glossy closure in the resolve pass. */ - cl_common.specular_accum += planar.attenuation; + + cl_out.radiance = mix(cl_out.radiance, probe_radiance, attenuation); #endif } diff --git a/source/blender/draw/engines/eevee/shaders/closure_eval_lib.glsl b/source/blender/draw/engines/eevee/shaders/closure_eval_lib.glsl index 7b38d5442dc..b372a8c2467 100644 --- a/source/blender/draw/engines/eevee/shaders/closure_eval_lib.glsl +++ b/source/blender/draw/engines/eevee/shaders/closure_eval_lib.glsl @@ -65,13 +65,6 @@ { \ CLOSURE_EVAL_DECLARE(t0, t1, t2, t3); \ \ - for (int i = 0; cl_common.specular_accum > 0.0 && i < prbNumPlanar && i < MAX_PLANAR; i++) { \ - ClosurePlanarData planar = closure_planar_eval_init(i, cl_common); \ - if (planar.attenuation > 1e-8) { \ - CLOSURE_META_SUBROUTINE_DATA(planar_eval, planar, t0, t1, t2, t3); \ - } \ - } \ -\ /* Starts at 1 because 0 is world cubemap. */ \ for (int i = 1; cl_common.specular_accum > 0.0 && i < prbNumRenderCube && i < MAX_PROBE; \ i++) { \ @@ -91,6 +84,11 @@ \ CLOSURE_META_SUBROUTINE(indirect_end, t0, t1, t2, t3); \ \ + ClosurePlanarData planar = closure_planar_eval_init(cl_common); \ + if (planar.attenuation > 1e-8) { \ + CLOSURE_META_SUBROUTINE_DATA(planar_eval, planar, t0, t1, t2, t3); \ + } \ +\ for (int i = 0; i < laNumLight && i < MAX_LIGHT; i++) { \ ClosureLightData light = closure_light_eval_init(cl_common, i); \ if (light.vis > 1e-8) { \ @@ -281,14 +279,20 @@ struct ClosurePlanarData { float attenuation; /** Attenuation. */ }; -ClosurePlanarData closure_planar_eval_init(int planar_id, inout ClosureEvalCommon cl_common) +ClosurePlanarData closure_planar_eval_init(inout ClosureEvalCommon cl_common) { ClosurePlanarData planar; - planar.id = planar_id; - planar.data = planars_data[planar_id]; - planar.attenuation = probe_attenuation_planar(planar.data, cl_common.P, cl_common.N, 0.0); - planar.attenuation = min(planar.attenuation, cl_common.specular_accum); - cl_common.specular_accum -= planar.attenuation; + planar.attenuation = 0.0; + + /* Find planar with the maximum weight. TODO(fclem) */ + for (int i = 0; i < prbNumPlanar && i < MAX_PLANAR; i++) { + float attenuation = probe_attenuation_planar(planars_data[i], cl_common.P); + if (attenuation > planar.attenuation) { + planar.id = i; + planar.attenuation = attenuation; + planar.data = planars_data[i]; + } + } return planar; } diff --git a/source/blender/draw/engines/eevee/shaders/effect_ssr_frag.glsl b/source/blender/draw/engines/eevee/shaders/effect_ssr_frag.glsl index b49cd987a6e..b7caaf127bf 100644 --- a/source/blender/draw/engines/eevee/shaders/effect_ssr_frag.glsl +++ b/source/blender/draw/engines/eevee/shaders/effect_ssr_frag.glsl @@ -182,7 +182,8 @@ void main() for (int i = 0; i < MAX_PLANAR && i < prbNumPlanar; i++) { PlanarData pd = planars_data[i]; - float fade = probe_attenuation_planar(pd, W, wN, 0.0); + float fade = probe_attenuation_planar(pd, W); + fade *= probe_attenuation_planar_normal_roughness(pd, wN, 0.0); if (fade > 0.5) { /* Find view vector / reflection plane intersection. */ @@ -525,7 +526,8 @@ void raytrace_resolve(ClosureInputGlossy cl_in, for (int i = 0; i < MAX_PLANAR && i < prbNumPlanar; i++) { pd = planars_data[i]; - float fade = probe_attenuation_planar(pd, P, N, 0.0); + float fade = probe_attenuation_planar(pd, P); + fade *= probe_attenuation_planar_normal_roughness(pd, N, 0.0); if (fade > 0.5) { planar_index = float(i); diff --git a/source/blender/draw/engines/eevee/shaders/lightprobe_lib.glsl b/source/blender/draw/engines/eevee/shaders/lightprobe_lib.glsl index d2381537772..6507534ce67 100644 --- a/source/blender/draw/engines/eevee/shaders/lightprobe_lib.glsl +++ b/source/blender/draw/engines/eevee/shaders/lightprobe_lib.glsl @@ -116,25 +116,26 @@ float probe_attenuation_cube(int pd_id, vec3 W) return fac; } -float probe_attenuation_planar(PlanarData pd, vec3 W, vec3 N, float roughness) +float probe_attenuation_planar(PlanarData pd, vec3 W) { - /* Normal Facing */ - float fac = saturate(dot(pd.pl_normal, N) * pd.pl_facing_scale + pd.pl_facing_bias); - /* Distance from plane */ - fac *= saturate(abs(dot(pd.pl_plane_eq, vec4(W, 1.0))) * pd.pl_fade_scale + pd.pl_fade_bias); - + float fac = saturate(abs(dot(pd.pl_plane_eq, vec4(W, 1.0))) * pd.pl_fade_scale + + pd.pl_fade_bias); /* Fancy fast clipping calculation */ vec2 dist_to_clip; dist_to_clip.x = dot(pd.pl_clip_pos_x, W); dist_to_clip.y = dot(pd.pl_clip_pos_y, W); /* compare and add all tests */ fac *= step(2.0, dot(step(pd.pl_clip_edges, dist_to_clip.xxyy), vec2(-1.0, 1.0).xyxy)); + return fac; +} +float probe_attenuation_planar_normal_roughness(PlanarData pd, vec3 N, float roughness) +{ + /* Normal Facing */ + float fac = saturate(dot(pd.pl_normal, N) * pd.pl_facing_scale + pd.pl_facing_bias); /* Decrease influence for high roughness */ - fac *= saturate(1.0 - roughness * 10.0); - - return fac; + return fac * saturate(1.0 - roughness * 10.0); } float probe_attenuation_grid(GridData gd, vec3 W, out vec3 localpos) |