diff --git a/crates/bevy_light/src/directional_light.rs b/crates/bevy_light/src/directional_light.rs index e83c26c26b47e..39e52fb5f02e8 100644 --- a/crates/bevy_light/src/directional_light.rs +++ b/crates/bevy_light/src/directional_light.rs @@ -9,6 +9,7 @@ use bevy_ecs::prelude::*; use bevy_image::Image; use bevy_reflect::prelude::*; use bevy_transform::components::Transform; +use tracing::warn; use super::{ cascade::CascadeShadowConfig, cluster::ClusterVisibilityClass, light_consts, Cascades, @@ -182,6 +183,8 @@ pub struct DirectionalLightTexture { pub struct DirectionalLightShadowMap { // The width and height of each cascade. /// + /// Must be a power of two to avoid unstable cascade positioning. + /// /// Defaults to `2048`. pub size: usize, } @@ -192,6 +195,14 @@ impl Default for DirectionalLightShadowMap { } } +pub fn validate_shadow_map_size(mut shadow_map: ResMut) { + if shadow_map.is_changed() && !shadow_map.size.is_power_of_two() { + let new_size = shadow_map.size.next_power_of_two(); + warn!("Non-power-of-two DirectionalLightShadowMap sizes are not supported, correcting {} to {new_size}", shadow_map.size); + shadow_map.size = new_size; + } +} + pub fn update_directional_light_frusta( mut views: Query< ( diff --git a/crates/bevy_light/src/lib.rs b/crates/bevy_light/src/lib.rs index 06dc5ac7ca3eb..34cdaea60fd44 100644 --- a/crates/bevy_light/src/lib.rs +++ b/crates/bevy_light/src/lib.rs @@ -48,6 +48,8 @@ pub use directional_light::{ DirectionalLightTexture, }; +use crate::directional_light::validate_shadow_map_size; + /// Constants for operating with the light units: lumens, and lux. pub mod light_consts { /// Approximations for converting the wattage of lamps to lumens. @@ -145,6 +147,7 @@ impl Plugin for LightPlugin { .add_systems( PostUpdate, ( + validate_shadow_map_size.before(build_directional_light_cascades), add_clusters .in_set(SimulationLightSystems::AddClusters) .after(CameraUpdateSystems),