diff options
Diffstat (limited to 'source/blender/draw/engines/eevee/shaders/closure_eval_diffuse_lib.glsl')
-rw-r--r-- | source/blender/draw/engines/eevee/shaders/closure_eval_diffuse_lib.glsl | 85 |
1 files changed, 85 insertions, 0 deletions
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 new file mode 100644 index 00000000000..1e65d3ccb87 --- /dev/null +++ b/source/blender/draw/engines/eevee/shaders/closure_eval_diffuse_lib.glsl @@ -0,0 +1,85 @@ +#pragma BLENDER_REQUIRE(lights_lib.glsl) +#pragma BLENDER_REQUIRE(lightprobe_lib.glsl) +#pragma BLENDER_REQUIRE(ambient_occlusion_lib.glsl) + +struct ClosureInputDiffuse { + vec3 N; /** Shading normal. */ + vec3 albedo; /** Used for multibounce GTAO approximation. Not applied to final radiance. */ +}; + +#define CLOSURE_INPUT_Diffuse_DEFAULT ClosureInputDiffuse(vec3(0.0), vec3(0.0)) + +struct ClosureEvalDiffuse { + vec3 probe_sampling_dir; /** Direction to sample probes from. */ + float ambient_occlusion; /** Final occlusion for distant lighting. */ +}; + +/* Stubs. */ +#define ClosureOutputDiffuse ClosureOutput +#define closure_Diffuse_planar_eval(cl_in, cl_eval, cl_common, data, cl_out) +#define closure_Diffuse_cubemap_eval(cl_in, cl_eval, cl_common, data, cl_out) + +ClosureEvalDiffuse closure_Diffuse_eval_init(inout ClosureInputDiffuse cl_in, + ClosureEvalCommon cl_common, + out ClosureOutputDiffuse cl_out) +{ + cl_in.N = safe_normalize(cl_in.N); + cl_out.radiance = vec3(0.0); + + ClosureEvalDiffuse cl_eval; + 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; +} + +void closure_Diffuse_light_eval(ClosureInputDiffuse cl_in, + ClosureEvalDiffuse cl_eval, + ClosureEvalCommon cl_common, + ClosureLightData light, + inout ClosureOutputDiffuse cl_out) +{ + float radiance = light_diffuse(light.data, cl_in.N, cl_common.V, light.L); + /* TODO(fclem) We could try to shadow lights that are shadowless with the ambient_occlusion + * factor here. */ + cl_out.radiance += light.data.l_color * (light.vis * light.contact_shadow * radiance); +} + +void closure_Diffuse_grid_eval(ClosureInputDiffuse cl_in, + ClosureEvalDiffuse cl_eval, + ClosureEvalCommon cl_common, + ClosureGridData grid, + inout ClosureOutputDiffuse cl_out) +{ + vec3 probe_radiance = probe_evaluate_grid( + grid.data, cl_common.P, cl_eval.probe_sampling_dir, grid.local_pos); + cl_out.radiance += grid.attenuation * probe_radiance; +} + +void closure_Diffuse_indirect_end(ClosureInputDiffuse cl_in, + ClosureEvalDiffuse cl_eval, + ClosureEvalCommon cl_common, + inout ClosureOutputDiffuse cl_out) +{ + /* 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.probe_sampling_dir); + cl_out.radiance += cl_common.diffuse_accum * probe_radiance; + } + /* Apply occlusion on radiance before the light loop. */ + cl_out.radiance *= cl_eval.ambient_occlusion; +} + +void closure_Diffuse_eval_end(ClosureInputDiffuse cl_in, + ClosureEvalDiffuse cl_eval, + ClosureEvalCommon cl_common, + inout ClosureOutputDiffuse cl_out) +{ +#if defined(DEPTH_SHADER) || defined(WORLD_BACKGROUND) + /* This makes shader resources become unused and avoid issues with samplers. (see T59747) */ + cl_out.radiance = vec3(0.0); + return; +#endif +} |