From 9b006fdf751e2f9bfdc3a66c98b29ee95aa7f0c7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=A0=94=E7=A9=B6=E7=A4=BE=E4=BA=A4?= Date: Tue, 10 Sep 2024 00:11:16 +0800 Subject: [PATCH] bevy_pbr: Make choosing of diffuse indirect lighting explicit. (#15093) # Objective Make choosing of diffuse indirect lighting explicit, instead of using numerical conditions like `all(indirect_light == vec3(0.0f))`, as using that may lead to unwanted light leakage. ## Solution Use an explicit `found_diffuse_indirect` condition to indicate the found indirect lighting source. ## Testing I have tested examples `lightmaps`, `irradiance_volumes` and `reflection_probes`, there are no visual changes. For further testing, consider a "cave" scene with lightmaps and irradiance volumes. In the cave there are some purly dark occluded area, those dark area will sample the irradiance volume, and that is easy to leak light. --- crates/bevy_pbr/src/render/pbr_functions.wgsl | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/crates/bevy_pbr/src/render/pbr_functions.wgsl b/crates/bevy_pbr/src/render/pbr_functions.wgsl index 35e683c4ffd18..268a50163f688 100644 --- a/crates/bevy_pbr/src/render/pbr_functions.wgsl +++ b/crates/bevy_pbr/src/render/pbr_functions.wgsl @@ -545,19 +545,20 @@ fn apply_pbr_lighting( // example, both lightmaps and irradiance volumes are present. var indirect_light = vec3(0.0f); + var found_diffuse_indirect = false; #ifdef LIGHTMAP - if (all(indirect_light == vec3(0.0f))) { - indirect_light += in.lightmap_light * diffuse_color; - } + indirect_light += in.lightmap_light * diffuse_color; + found_diffuse_indirect = true; #endif -#ifdef IRRADIANCE_VOLUME { +#ifdef IRRADIANCE_VOLUME // Irradiance volume light (indirect) - if (all(indirect_light == vec3(0.0f))) { + if (!found_diffuse_indirect) { let irradiance_volume_light = irradiance_volume::irradiance_volume_light( in.world_position.xyz, in.N); indirect_light += irradiance_volume_light * diffuse_color * diffuse_occlusion; + found_diffuse_indirect = true; } #endif @@ -574,7 +575,7 @@ fn apply_pbr_lighting( let environment_light = environment_map::environment_map_light( environment_map_lighting_input, - any(indirect_light != vec3(0.0f)) + found_diffuse_indirect ); // If screen space reflections are going to be used for this material, don't @@ -589,7 +590,7 @@ fn apply_pbr_lighting( if (!use_ssr) { let environment_light = environment_map::environment_map_light( &lighting_input, - any(indirect_light != vec3(0.0f)) + found_diffuse_indirect ); indirect_light += environment_light.diffuse * diffuse_occlusion +