From 5d0b9fe2ac664181aebca66d625a5b7c38f0ef11 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois?= Date: Thu, 7 Apr 2022 00:52:21 +0200 Subject: [PATCH 1/6] raise MAX_POINT_LIGHT_SHADOW_MAPS --- crates/bevy_pbr/src/render/light.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/bevy_pbr/src/render/light.rs b/crates/bevy_pbr/src/render/light.rs index aa23d63568e3e..9753ca0c8e14f 100644 --- a/crates/bevy_pbr/src/render/light.rs +++ b/crates/bevy_pbr/src/render/light.rs @@ -225,7 +225,7 @@ pub const MAX_UNIFORM_BUFFER_POINT_LIGHTS: usize = 256; #[cfg(feature = "webgl")] pub const MAX_POINT_LIGHT_SHADOW_MAPS: usize = 1; #[cfg(not(feature = "webgl"))] -pub const MAX_POINT_LIGHT_SHADOW_MAPS: usize = 10; +pub const MAX_POINT_LIGHT_SHADOW_MAPS: usize = 256; pub const MAX_DIRECTIONAL_LIGHTS: usize = 1; pub const POINT_SHADOW_LAYERS: u32 = (6 * MAX_POINT_LIGHT_SHADOW_MAPS) as u32; pub const DIRECTIONAL_SHADOW_LAYERS: u32 = MAX_DIRECTIONAL_LIGHTS as u32; From dfe96a68a9cc2cfdf9764e69a41a03012e205b76 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois?= Date: Thu, 7 Apr 2022 01:08:38 +0200 Subject: [PATCH 2/6] don't overallocate --- crates/bevy_pbr/src/render/light.rs | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/crates/bevy_pbr/src/render/light.rs b/crates/bevy_pbr/src/render/light.rs index 9753ca0c8e14f..d25766c1e6f05 100644 --- a/crates/bevy_pbr/src/render/light.rs +++ b/crates/bevy_pbr/src/render/light.rs @@ -227,7 +227,6 @@ pub const MAX_POINT_LIGHT_SHADOW_MAPS: usize = 1; #[cfg(not(feature = "webgl"))] pub const MAX_POINT_LIGHT_SHADOW_MAPS: usize = 256; pub const MAX_DIRECTIONAL_LIGHTS: usize = 1; -pub const POINT_SHADOW_LAYERS: u32 = (6 * MAX_POINT_LIGHT_SHADOW_MAPS) as u32; pub const DIRECTIONAL_SHADOW_LAYERS: u32 = MAX_DIRECTIONAL_LIGHTS as u32; pub const SHADOW_FORMAT: TextureFormat = TextureFormat::Depth32Float; @@ -704,6 +703,12 @@ pub fn prepare_lights( let mut point_lights: Vec<_> = point_lights.iter().collect::>(); + let nb_shadow_lights = point_lights + .iter() + .filter(|light| light.1.shadows_enabled) + .count() + .min(MAX_POINT_LIGHT_SHADOW_MAPS); + // Sort point lights with shadows enabled first, then by a stable key so that the index can be used // to render at most `MAX_POINT_LIGHT_SHADOW_MAPS` point light shadows. point_lights.sort_by(|(entity_1, light_1), (entity_2, light_2)| { @@ -759,7 +764,7 @@ pub fn prepare_lights( size: Extent3d { width: point_light_shadow_map.size as u32, height: point_light_shadow_map.size as u32, - depth_or_array_layers: POINT_SHADOW_LAYERS, + depth_or_array_layers: nb_shadow_lights.max(1) as u32 * 6, }, mip_level_count: 1, sample_count: 1, From b04c83dabd725267a17c16dca14937207d58053b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois?= Date: Thu, 7 Apr 2022 01:37:08 +0200 Subject: [PATCH 3/6] use device limits Co-authored-by: Robert Swain --- crates/bevy_pbr/src/render/light.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/crates/bevy_pbr/src/render/light.rs b/crates/bevy_pbr/src/render/light.rs index d25766c1e6f05..adda49d838b1e 100644 --- a/crates/bevy_pbr/src/render/light.rs +++ b/crates/bevy_pbr/src/render/light.rs @@ -707,7 +707,8 @@ pub fn prepare_lights( .iter() .filter(|light| light.1.shadows_enabled) .count() - .min(MAX_POINT_LIGHT_SHADOW_MAPS); + .min(MAX_POINT_LIGHT_SHADOW_MAPS) + .min(render_device.limits().max_texture_array_layers / 6); // Sort point lights with shadows enabled first, then by a stable key so that the index can be used // to render at most `MAX_POINT_LIGHT_SHADOW_MAPS` point light shadows. From 2af5d3cf38333444739ea534d1d45cdc3b449173 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois?= Date: Thu, 7 Apr 2022 01:44:59 +0200 Subject: [PATCH 4/6] use the limit --- crates/bevy_pbr/src/render/light.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/crates/bevy_pbr/src/render/light.rs b/crates/bevy_pbr/src/render/light.rs index adda49d838b1e..a47c3d54c5a6c 100644 --- a/crates/bevy_pbr/src/render/light.rs +++ b/crates/bevy_pbr/src/render/light.rs @@ -708,7 +708,7 @@ pub fn prepare_lights( .filter(|light| light.1.shadows_enabled) .count() .min(MAX_POINT_LIGHT_SHADOW_MAPS) - .min(render_device.limits().max_texture_array_layers / 6); + .min((render_device.limits().max_texture_array_layers / 6) as usize); // Sort point lights with shadows enabled first, then by a stable key so that the index can be used // to render at most `MAX_POINT_LIGHT_SHADOW_MAPS` point light shadows. @@ -729,7 +729,7 @@ pub fn prepare_lights( for (index, &(entity, light)) in point_lights.iter().enumerate() { let mut flags = PointLightFlags::NONE; // Lights are sorted, shadow enabled lights are first - if light.shadows_enabled && index < MAX_POINT_LIGHT_SHADOW_MAPS { + if light.shadows_enabled && index < nb_shadow_lights { flags |= PointLightFlags::SHADOWS_ENABLED; } gpu_point_lights.push(GpuPointLight { @@ -822,7 +822,7 @@ pub fn prepare_lights( for &(light_entity, light) in point_lights .iter() // Lights are sorted, shadow enabled lights are first - .take(MAX_POINT_LIGHT_SHADOW_MAPS) + .take(nb_shadow_lights) .filter(|(_, light)| light.shadows_enabled) { let light_index = *global_light_meta From d39b81f693f19d40aecc02de9872262496601fdd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois?= Date: Thu, 7 Apr 2022 08:11:49 +0200 Subject: [PATCH 5/6] remove const --- crates/bevy_pbr/src/render/light.rs | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/crates/bevy_pbr/src/render/light.rs b/crates/bevy_pbr/src/render/light.rs index a47c3d54c5a6c..213ef54e9413f 100644 --- a/crates/bevy_pbr/src/render/light.rs +++ b/crates/bevy_pbr/src/render/light.rs @@ -220,12 +220,6 @@ pub struct GpuLights { // NOTE: this must be kept in sync with the same constants in pbr.frag pub const MAX_UNIFORM_BUFFER_POINT_LIGHTS: usize = 256; -// FIXME: How should we handle shadows for clustered forward? Limiting to maximum 10 -// point light shadow maps for now -#[cfg(feature = "webgl")] -pub const MAX_POINT_LIGHT_SHADOW_MAPS: usize = 1; -#[cfg(not(feature = "webgl"))] -pub const MAX_POINT_LIGHT_SHADOW_MAPS: usize = 256; pub const MAX_DIRECTIONAL_LIGHTS: usize = 1; pub const DIRECTIONAL_SHADOW_LAYERS: u32 = MAX_DIRECTIONAL_LIGHTS as u32; pub const SHADOW_FORMAT: TextureFormat = TextureFormat::Depth32Float; @@ -703,12 +697,14 @@ pub fn prepare_lights( let mut point_lights: Vec<_> = point_lights.iter().collect::>(); - let nb_shadow_lights = point_lights + #[cfg(not(feature = "webgl"))] + let max_point_light_shadow_maps = point_lights .iter() .filter(|light| light.1.shadows_enabled) .count() - .min(MAX_POINT_LIGHT_SHADOW_MAPS) .min((render_device.limits().max_texture_array_layers / 6) as usize); + #[cfg(feature = "webgl")] + let max_point_light_shadow_maps = 1; // Sort point lights with shadows enabled first, then by a stable key so that the index can be used // to render at most `MAX_POINT_LIGHT_SHADOW_MAPS` point light shadows. @@ -729,7 +725,7 @@ pub fn prepare_lights( for (index, &(entity, light)) in point_lights.iter().enumerate() { let mut flags = PointLightFlags::NONE; // Lights are sorted, shadow enabled lights are first - if light.shadows_enabled && index < nb_shadow_lights { + if light.shadows_enabled && index < max_point_light_shadow_maps { flags |= PointLightFlags::SHADOWS_ENABLED; } gpu_point_lights.push(GpuPointLight { @@ -765,7 +761,7 @@ pub fn prepare_lights( size: Extent3d { width: point_light_shadow_map.size as u32, height: point_light_shadow_map.size as u32, - depth_or_array_layers: nb_shadow_lights.max(1) as u32 * 6, + depth_or_array_layers: max_point_light_shadow_maps.max(1) as u32 * 6, }, mip_level_count: 1, sample_count: 1, @@ -822,7 +818,7 @@ pub fn prepare_lights( for &(light_entity, light) in point_lights .iter() // Lights are sorted, shadow enabled lights are first - .take(nb_shadow_lights) + .take(max_point_light_shadow_maps) .filter(|(_, light)| light.shadows_enabled) { let light_index = *global_light_meta From d5133358f2a36a2dcb86028bd0805b244307d471 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois?= Date: Thu, 7 Apr 2022 17:31:48 +0200 Subject: [PATCH 6/6] update comments --- crates/bevy_pbr/src/light.rs | 2 +- crates/bevy_pbr/src/render/light.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/bevy_pbr/src/light.rs b/crates/bevy_pbr/src/light.rs index 90eda98082ae0..69eddb985944e 100644 --- a/crates/bevy_pbr/src/light.rs +++ b/crates/bevy_pbr/src/light.rs @@ -655,7 +655,7 @@ fn cluster_space_light_aabb( } // Sort point lights with shadows enabled first, then by a stable key so that the index -// can be used to render at most `MAX_POINT_LIGHT_SHADOW_MAPS` point light shadows and +// can be used to limit the number of point light shadows to render based on the device and // we keep a stable set of lights visible pub(crate) fn point_light_order( (entity_1, shadows_enabled_1): (&Entity, &bool), diff --git a/crates/bevy_pbr/src/render/light.rs b/crates/bevy_pbr/src/render/light.rs index 213ef54e9413f..a1b527faa5e54 100644 --- a/crates/bevy_pbr/src/render/light.rs +++ b/crates/bevy_pbr/src/render/light.rs @@ -707,7 +707,7 @@ pub fn prepare_lights( let max_point_light_shadow_maps = 1; // Sort point lights with shadows enabled first, then by a stable key so that the index can be used - // to render at most `MAX_POINT_LIGHT_SHADOW_MAPS` point light shadows. + // to render at most `max_point_light_shadow_maps` point light shadows. point_lights.sort_by(|(entity_1, light_1), (entity_2, light_2)| { point_light_order( (entity_1, &light_1.shadows_enabled),