diff options
author | Clément Foucault <foucault.clem@gmail.com> | 2021-02-08 17:43:24 +0300 |
---|---|---|
committer | Clément Foucault <foucault.clem@gmail.com> | 2021-02-08 17:43:24 +0300 |
commit | 1d56589f149bd733a47a2f53de705a99165c70a9 (patch) | |
tree | 682773d8d91e428232f6929159f3bf924f2e1680 | |
parent | f6cc14f86e3695150a033e99f0ad0b27a55d0007 (diff) |
EEVEE: Add back support for user occlusion on eevee_specular BSDF
7 files changed, 59 insertions, 30 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 2f6f8327f58..d250c9c9cce 100644 --- a/source/blender/draw/engines/eevee/shaders/ambient_occlusion_lib.glsl +++ b/source/blender/draw/engines/eevee/shaders/ambient_occlusion_lib.glsl @@ -246,7 +246,7 @@ float specular_occlusion(float NV, float AO, float roughness) } /* Use the right occlusion */ -float occlusion_compute(vec3 N, vec3 vpos, float user_occlusion, vec4 rand, out vec3 bent_normal) +float occlusion_compute(vec3 N, vec3 vpos, vec4 rand, out vec3 bent_normal) { #ifndef USE_REFRACTION if ((int(aoSettings) & USE_AO) != 0) { @@ -276,10 +276,10 @@ float occlusion_compute(vec3 N, vec3 vpos, float user_occlusion, vec4 rand, out /* Scale by user factor */ visibility = pow(visibility, aoFactor); - return min(visibility, user_occlusion); + return visibility; } #endif bent_normal = N; - return user_occlusion; + return 1.0; } 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 473b50767dd..28aaa6afd44 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,8 +10,7 @@ struct ClosureInputDiffuse { #define CLOSURE_INPUT_Diffuse_DEFAULT ClosureInputDiffuse(vec3(0.0), vec3(0.0)) struct ClosureEvalDiffuse { - vec3 bent_normal; /** Normal pointing in the least occluded direction. */ - float ambient_occlusion; /** Final occlusion factor. */ + float dummy; }; /* Stubs. */ @@ -27,9 +26,7 @@ ClosureEvalDiffuse closure_Diffuse_eval_init(inout ClosureInputDiffuse cl_in, cl_out.radiance = vec3(0.0); ClosureEvalDiffuse cl_eval; - float user_ao = 1.0; /* TODO(fclem) wire the real one through ClosureEvalCommon. */ - cl_eval.ambient_occlusion = occlusion_compute( - cl_in.N, cl_common.vP, user_ao, cl_common.rand, cl_eval.bent_normal); + cl_eval.dummy = 0.0; return cl_eval; } @@ -52,7 +49,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_eval.bent_normal, grid.local_pos); + grid.data, cl_common.P, cl_common.bent_normal, grid.local_pos); cl_out.radiance += grid.attenuation * probe_radiance; } @@ -64,11 +61,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_eval.bent_normal); + vec3 probe_radiance = probe_evaluate_world_diff(cl_common.bent_normal); cl_out.radiance += cl_common.diffuse_accum * probe_radiance; } /* Apply occlusion on radiance before the light loop. */ - cl_out.radiance *= gtao_multibounce(cl_eval.ambient_occlusion, cl_in.albedo); + cl_out.radiance *= gtao_multibounce(cl_common.occlusion, cl_in.albedo); } void closure_Diffuse_eval_end(ClosureInputDiffuse cl_in, 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 4fa87efa291..96f2cd6557c 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 @@ -3,7 +3,6 @@ #pragma BLENDER_REQUIRE(lights_lib.glsl) #pragma BLENDER_REQUIRE(lightprobe_lib.glsl) #pragma BLENDER_REQUIRE(ambient_occlusion_lib.glsl) -#pragma BLENDER_REQUIRE(ssr_lib.glsl) struct ClosureInputGlossy { vec3 N; /** Shading normal. */ @@ -16,6 +15,7 @@ struct ClosureEvalGlossy { vec4 ltc_mat; /** LTC matrix values. */ float ltc_brdf_scale; /** LTC BRDF scaling. */ vec3 probe_sampling_dir; /** Direction to sample probes from. */ + float spec_occlusion; /** Specular Occlusion. */ }; /* Stubs. */ @@ -47,6 +47,7 @@ ClosureEvalGlossy closure_Glossy_eval_init(inout ClosureInputGlossy cl_in, ClosureEvalGlossy cl_eval; cl_eval.ltc_mat = texture(utilTex, vec3(lut_uv, LTC_MAT_LAYER)); cl_eval.probe_sampling_dir = specular_dominant_dir(cl_in.N, cl_common.V, sqr(cl_in.roughness)); + cl_eval.spec_occlusion = specular_occlusion(NV, cl_common.occlusion, cl_in.roughness); /* The brdf split sum LUT is applied after the radiance accumulation. * Correct the LTC so that its energy is constant. */ @@ -105,7 +106,7 @@ void closure_Glossy_indirect_end(ClosureInputGlossy cl_in, cl_out.radiance += cl_common.specular_accum * probe_radiance; } - /* TODO(fclem) Apply occlusion. */ + cl_out.radiance *= cl_eval.spec_occlusion; } void closure_Glossy_eval_end(ClosureInputGlossy cl_in, 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 ae7f08f8998..edadb63a71f 100644 --- a/source/blender/draw/engines/eevee/shaders/closure_eval_lib.glsl +++ b/source/blender/draw/engines/eevee/shaders/closure_eval_lib.glsl @@ -22,6 +22,7 @@ **/ #define CLOSURE_VARS_DECLARE(t0, t1, t2, t3) \ + ClosureInputCommon in_common = CLOSURE_INPUT_COMMON_DEFAULT; \ ClosureInput##t0 in_##t0##_0 = CLOSURE_INPUT_##t0##_DEFAULT; \ ClosureInput##t1 in_##t1##_1 = CLOSURE_INPUT_##t1##_DEFAULT; \ ClosureInput##t2 in_##t2##_2 = CLOSURE_INPUT_##t2##_DEFAULT; \ @@ -32,6 +33,7 @@ ClosureOutput##t3 out_##t3##_3; #define CLOSURE_EVAL_DECLARE(t0, t1, t2, t3) \ + ClosureEvalCommon cl_common = closure_Common_eval_init(in_common); \ ClosureEval##t0 eval_##t0##_0 = closure_##t0##_eval_init(in_##t0##_0, cl_common, out_##t0##_0); \ ClosureEval##t1 eval_##t1##_1 = closure_##t1##_eval_init(in_##t1##_1, cl_common, out_##t1##_1); \ ClosureEval##t2 eval_##t2##_2 = closure_##t2##_eval_init(in_##t2##_2, cl_common, out_##t2##_2); \ @@ -51,7 +53,8 @@ /* Inputs are inout so that callers can get the final inputs used for evaluation. */ #define CLOSURE_EVAL_FUNCTION_DECLARE(name, t0, t1, t2, t3) \ - void closure_##name##_eval(inout ClosureInput##t0 in_##t0##_0, \ + void closure_##name##_eval(ClosureInputCommon in_common, \ + inout ClosureInput##t0 in_##t0##_0, \ inout ClosureInput##t1 in_##t1##_1, \ inout ClosureInput##t2 in_##t2##_2, \ inout ClosureInput##t3 in_##t3##_3, \ @@ -60,7 +63,6 @@ out ClosureOutput##t2 out_##t2##_2, \ out ClosureOutput##t3 out_##t3##_3) \ { \ - ClosureEvalCommon cl_common = closure_Common_eval_init(); \ CLOSURE_EVAL_DECLARE(t0, t1, t2, t3); \ \ ClosurePlanarData planar; \ @@ -97,7 +99,8 @@ } #define CLOSURE_EVAL_FUNCTION(name, t0, t1, t2, t3) \ - closure_##name##_eval(in_##t0##_0, \ + closure_##name##_eval(in_common, \ + in_##t0##_0, \ in_##t1##_1, \ in_##t2##_2, \ in_##t3##_3, \ @@ -153,18 +156,39 @@ * will be optimized out. * \{ */ +struct ClosureInputCommon { + /** Custom occlusion value set by the user. */ + float occlusion; +}; + +#define CLOSURE_INPUT_COMMON_DEFAULT ClosureInputCommon(1.0) + struct ClosureEvalCommon { - vec3 V; /** View vector. */ - vec3 P; /** Surface position. */ - vec3 N; /** Normal vector, always facing camera. */ - vec3 vN; /** Normal vector, always facing camera. (viewspace) */ - vec3 vP; /** Surface position. (viewspace) */ - vec3 vNg; /** Geometric normal, always facing camera. (viewspace) */ - vec4 rand; /** Random numbers. 3 random sequences. zw is a random point on a circle. */ - - float specular_accum; /** Specular probe accumulator. Shared between planar and cubemap probe. */ - float diffuse_accum; /** Diffuse probe accumulator. */ - float tracing_depth; /** Viewspace depth to start raytracing from. */ + /** View vector. */ + vec3 V; + /** Surface position. */ + vec3 P; + /** Normal vector, always facing camera. */ + vec3 N; + /** Normal vector, always facing camera. (viewspace) */ + vec3 vN; + /** Surface position. (viewspace) */ + vec3 vP; + /** Geometric normal, always facing camera. (viewspace) */ + vec3 vNg; + /** Random numbers. 3 random sequences. zw is a random point on a circle. */ + vec4 rand; + /** Final occlusion factor. Mix of the user occlusion and SSAO. */ + float occlusion; + /** Least occluded direction in the hemisphere. */ + vec3 bent_normal; + + /** Specular probe accumulator. Shared between planar and cubemap probe. */ + float specular_accum; + /** Diffuse probe accumulator. */ + float diffuse_accum; + /** Viewspace depth to start raytracing from. */ + float tracing_depth; }; /* Common cl_out struct used by most closures. */ @@ -172,7 +196,7 @@ struct ClosureOutput { vec3 radiance; }; -ClosureEvalCommon closure_Common_eval_init(void) +ClosureEvalCommon closure_Common_eval_init(ClosureInputCommon cl_in) { ClosureEvalCommon cl_eval; cl_eval.rand = texelfetch_noise_tex(gl_FragCoord.xy); @@ -191,6 +215,11 @@ ClosureEvalCommon closure_Common_eval_init(void) /* Convert to view Z. */ cl_eval.tracing_depth = get_view_z_from_depth(cl_eval.tracing_depth); + /* TODO(fclem) Do occlusion evaluation per Closure using shading normal. */ + cl_eval.occlusion = min( + cl_in.occlusion, + occlusion_compute(cl_eval.N, cl_eval.vP, cl_eval.rand, cl_eval.bent_normal)); + cl_eval.specular_accum = 1.0; cl_eval.diffuse_accum = 1.0; return cl_eval; diff --git a/source/blender/draw/engines/eevee/shaders/lightprobe_lib.glsl b/source/blender/draw/engines/eevee/shaders/lightprobe_lib.glsl index 3d1ad95060a..fe4f3dcaa2f 100644 --- a/source/blender/draw/engines/eevee/shaders/lightprobe_lib.glsl +++ b/source/blender/draw/engines/eevee/shaders/lightprobe_lib.glsl @@ -225,7 +225,7 @@ void fallback_cubemap(vec3 N, #ifdef SSR_AO vec4 rand = texelfetch_noise_tex(gl_FragCoord.xy); vec3 bent_normal; - float final_ao = occlusion_compute(N, viewPosition, 1.0, rand, bent_normal); + float final_ao = occlusion_compute(N, viewPosition, rand, bent_normal); final_ao = specular_occlusion(dot(N, V), final_ao, roughness); #else const float final_ao = 1.0; diff --git a/source/blender/gpu/shaders/material/gpu_shader_material_ambient_occlusion.glsl b/source/blender/gpu/shaders/material/gpu_shader_material_ambient_occlusion.glsl index eea8d19efce..d718cc3f4fe 100644 --- a/source/blender/gpu/shaders/material/gpu_shader_material_ambient_occlusion.glsl +++ b/source/blender/gpu/shaders/material/gpu_shader_material_ambient_occlusion.glsl @@ -4,7 +4,7 @@ void node_ambient_occlusion( { vec3 bent_normal; vec4 rand = texelfetch_noise_tex(gl_FragCoord.xy); - result_ao = occlusion_compute(normalize(normal), viewPosition, 1.0, rand, bent_normal); + result_ao = occlusion_compute(normalize(normal), viewPosition, rand, bent_normal); result_color = result_ao * color; } #else diff --git a/source/blender/gpu/shaders/material/gpu_shader_material_eevee_specular.glsl b/source/blender/gpu/shaders/material/gpu_shader_material_eevee_specular.glsl index 7e6dfc42591..429c4ed41ac 100644 --- a/source/blender/gpu/shaders/material/gpu_shader_material_eevee_specular.glsl +++ b/source/blender/gpu/shaders/material/gpu_shader_material_eevee_specular.glsl @@ -17,6 +17,8 @@ void node_eevee_specular(vec4 diffuse, { CLOSURE_VARS_DECLARE_3(Diffuse, Glossy, Glossy); + in_common.occlusion = occlusion; + in_Diffuse_0.N = normal; /* Normalized during eval. */ in_Diffuse_0.albedo = diffuse.rgb; |