diff options
3 files changed, 32 insertions, 12 deletions
diff --git a/source/blender/draw/engines/eevee/shaders/ambient_occlusion_lib.glsl b/source/blender/draw/engines/eevee/shaders/ambient_occlusion_lib.glsl index d250c9c9cce..7c0ae3881d7 100644 --- a/source/blender/draw/engines/eevee/shaders/ambient_occlusion_lib.glsl +++ b/source/blender/draw/engines/eevee/shaders/ambient_occlusion_lib.glsl @@ -191,15 +191,15 @@ void gtao_deferred( dirs.xy = get_ao_dir(noise.x * 0.5); dirs.zw = get_ao_dir(noise.x * 0.5 + 0.5); - bent_normal = normal * 1e-8; - visibility = 1e-8; + bent_normal = vec3(0.0); + visibility = 0.0; horizons = unpack_horizons(horizons); integrate_slice(normal, dirs.xy, horizons.xy, visibility, bent_normal); integrate_slice(normal, dirs.zw, horizons.zw, visibility, bent_normal); - bent_normal = normalize(bent_normal / visibility); + bent_normal = safe_normalize(bent_normal); visibility *= 0.5; /* We integrated 2 slices. */ } @@ -240,6 +240,17 @@ float gtao_multibounce(float visibility, vec3 albedo) return max(x, ((x * a + b) * x + c) * x); } +float diffuse_occlusion(vec3 N, vec3 vis_cone_dir, float vis_cone_aperture_cos, vec3 albedo) +{ + if ((int(aoSettings) & USE_AO) == 0) { + return 1.0; + } + /* If the shading normal is orthogonal to the geometric normal, it should be half lit. */ + float horizon_fac = saturate(dot(N, vis_cone_dir) * 0.5 + 0.5); + float ao = vis_cone_aperture_cos * horizon_fac; + return gtao_multibounce(ao, albedo); +} + float specular_occlusion(float NV, float AO, float roughness) { return saturate(pow(NV + AO, roughness) - 1.0 + AO); @@ -263,10 +274,6 @@ float occlusion_compute(vec3 N, vec3 vpos, vec4 rand, out vec3 bent_normal) visibility = max(1e-3, visibility); if ((int(aoSettings) & USE_BENT_NORMAL) != 0) { - /* The bent normal will show the facet look of the mesh. Try to minimize this. */ - float mix_fac = visibility * visibility * visibility; - bent_normal = normalize(mix(bent_normal, vnor, mix_fac)); - bent_normal = transform_direction(ViewMatrixInverse, bent_normal); } else { diff --git a/source/blender/draw/engines/eevee/shaders/bsdf_common_lib.glsl b/source/blender/draw/engines/eevee/shaders/bsdf_common_lib.glsl index 25eb0133616..f050cf3a08a 100644 --- a/source/blender/draw/engines/eevee/shaders/bsdf_common_lib.glsl +++ b/source/blender/draw/engines/eevee/shaders/bsdf_common_lib.glsl @@ -1,6 +1,15 @@ #pragma BLENDER_REQUIRE(common_math_lib.glsl) +vec3 diffuse_dominant_dir(vec3 N, vec3 vis_cone_dir, float vis_cone_aperture_cos) +{ + /* TODO(fclem) revisit this. bent too much towards vis_cone_dir. */ + vis_cone_aperture_cos *= sqr(vis_cone_aperture_cos); + + N = mix(vis_cone_dir, N, vis_cone_aperture_cos); + return normalize(N); +} + vec3 specular_dominant_dir(vec3 N, vec3 V, float roughness) { vec3 R = -reflect(V, N); diff --git a/source/blender/draw/engines/eevee/shaders/closure_eval_diffuse_lib.glsl b/source/blender/draw/engines/eevee/shaders/closure_eval_diffuse_lib.glsl index 28aaa6afd44..1e65d3ccb87 100644 --- a/source/blender/draw/engines/eevee/shaders/closure_eval_diffuse_lib.glsl +++ b/source/blender/draw/engines/eevee/shaders/closure_eval_diffuse_lib.glsl @@ -10,7 +10,8 @@ struct ClosureInputDiffuse { #define CLOSURE_INPUT_Diffuse_DEFAULT ClosureInputDiffuse(vec3(0.0), vec3(0.0)) struct ClosureEvalDiffuse { - float dummy; + vec3 probe_sampling_dir; /** Direction to sample probes from. */ + float ambient_occlusion; /** Final occlusion for distant lighting. */ }; /* Stubs. */ @@ -26,7 +27,10 @@ ClosureEvalDiffuse closure_Diffuse_eval_init(inout ClosureInputDiffuse cl_in, cl_out.radiance = vec3(0.0); ClosureEvalDiffuse cl_eval; - cl_eval.dummy = 0.0; + cl_eval.ambient_occlusion = diffuse_occlusion( + cl_in.N, cl_common.bent_normal, cl_common.occlusion, cl_in.albedo); + cl_eval.probe_sampling_dir = diffuse_dominant_dir( + cl_in.N, cl_common.bent_normal, cl_common.occlusion); return cl_eval; } @@ -49,7 +53,7 @@ void closure_Diffuse_grid_eval(ClosureInputDiffuse cl_in, inout ClosureOutputDiffuse cl_out) { vec3 probe_radiance = probe_evaluate_grid( - grid.data, cl_common.P, cl_common.bent_normal, grid.local_pos); + grid.data, cl_common.P, cl_eval.probe_sampling_dir, grid.local_pos); cl_out.radiance += grid.attenuation * probe_radiance; } @@ -61,11 +65,11 @@ void closure_Diffuse_indirect_end(ClosureInputDiffuse cl_in, /* If not enough light has been accumulated from probes, use the world specular cubemap * to fill the remaining energy needed. */ if (cl_common.diffuse_accum > 0.0) { - vec3 probe_radiance = probe_evaluate_world_diff(cl_common.bent_normal); + vec3 probe_radiance = probe_evaluate_world_diff(cl_eval.probe_sampling_dir); cl_out.radiance += cl_common.diffuse_accum * probe_radiance; } /* Apply occlusion on radiance before the light loop. */ - cl_out.radiance *= gtao_multibounce(cl_common.occlusion, cl_in.albedo); + cl_out.radiance *= cl_eval.ambient_occlusion; } void closure_Diffuse_eval_end(ClosureInputDiffuse cl_in, |