diff --git a/crates/bevy_pbr/src/cluster/assign.rs b/crates/bevy_pbr/src/cluster/assign.rs index 69de548b57ae6..12d971d9c1340 100644 --- a/crates/bevy_pbr/src/cluster/assign.rs +++ b/crates/bevy_pbr/src/cluster/assign.rs @@ -21,9 +21,9 @@ use bevy_utils::{prelude::default, tracing::warn}; use crate::{ prelude::EnvironmentMapLight, ClusterConfig, ClusterFarZMode, Clusters, ExtractedPointLight, - GlobalVisibleClusterableObjects, LightProbe, PointLight, SpotLight, ViewClusterBindings, - VisibleClusterableObjects, VolumetricLight, CLUSTERED_FORWARD_STORAGE_BUFFER_COUNT, - MAX_UNIFORM_BUFFER_CLUSTERABLE_OBJECTS, + GlobalVisibleClusterableObjects, LightProbe, ShadowsStyle, PointLight, SpotLight, + ViewClusterBindings, VisibleClusterableObjects, VolumetricLight, + CLUSTERED_FORWARD_STORAGE_BUFFER_COUNT, MAX_UNIFORM_BUFFER_CLUSTERABLE_OBJECTS, }; use super::ClusterableObjectOrderData; @@ -124,11 +124,11 @@ impl ClusterableObjectType { match point_light.spot_light_angles { Some((_, outer_angle)) => ClusterableObjectType::SpotLight { outer_angle, - shadows_enabled: point_light.shadows_enabled, + shadows_enabled: point_light.shadows.enabled(), volumetric: point_light.volumetric, }, None => ClusterableObjectType::PointLight { - shadows_enabled: point_light.shadows_enabled, + shadows_enabled: point_light.shadows.enabled(), volumetric: point_light.volumetric, }, } @@ -154,6 +154,7 @@ pub(crate) fn assign_objects_to_clusters( Entity, &GlobalTransform, &PointLight, + &ShadowsStyle, Option<&RenderLayers>, Option<&VolumetricLight>, &ViewVisibility, @@ -162,6 +163,7 @@ pub(crate) fn assign_objects_to_clusters( Entity, &GlobalTransform, &SpotLight, + &ShadowsStyle, Option<&RenderLayers>, Option<&VolumetricLight>, &ViewVisibility, @@ -187,13 +189,21 @@ pub(crate) fn assign_objects_to_clusters( .iter() .filter(|(.., visibility)| visibility.get()) .map( - |(entity, transform, point_light, maybe_layers, volumetric, _visibility)| { + |( + entity, + transform, + point_light, + point_light_shadows, + maybe_layers, + volumetric, + _visibility, + )| { ClusterableObjectAssignmentData { entity, transform: GlobalTransform::from_translation(transform.translation()), range: point_light.range, object_type: ClusterableObjectType::PointLight { - shadows_enabled: point_light.shadows_enabled, + shadows_enabled: point_light_shadows.enabled(), volumetric: volumetric.is_some(), }, render_layers: maybe_layers.unwrap_or_default().clone(), @@ -206,14 +216,22 @@ pub(crate) fn assign_objects_to_clusters( .iter() .filter(|(.., visibility)| visibility.get()) .map( - |(entity, transform, spot_light, maybe_layers, volumetric, _visibility)| { + |( + entity, + transform, + spot_light, + spot_light_shadows, + maybe_layers, + volumetric, + _visibility, + )| { ClusterableObjectAssignmentData { entity, transform: *transform, range: spot_light.range, object_type: ClusterableObjectType::SpotLight { outer_angle: spot_light.outer_angle, - shadows_enabled: spot_light.shadows_enabled, + shadows_enabled: spot_light_shadows.enabled(), volumetric: volumetric.is_some(), }, render_layers: maybe_layers.unwrap_or_default().clone(), diff --git a/crates/bevy_pbr/src/lib.rs b/crates/bevy_pbr/src/lib.rs index 0f68411eba48a..7f00989cad128 100644 --- a/crates/bevy_pbr/src/lib.rs +++ b/crates/bevy_pbr/src/lib.rs @@ -82,7 +82,7 @@ pub mod prelude { SpotLightBundle, }, fog::{DistanceFog, FogFalloff}, - light::{light_consts, AmbientLight, DirectionalLight, PointLight, SpotLight}, + light::{light_consts, AmbientLight, DirectionalLight, PointLight, SpotLight, ShadowsStyle}, light_probe::{ environment_map::{EnvironmentMapLight, ReflectionProbeBundle}, LightProbe, diff --git a/crates/bevy_pbr/src/light/directional_light.rs b/crates/bevy_pbr/src/light/directional_light.rs index 06c277aef731c..49a43012b8460 100644 --- a/crates/bevy_pbr/src/light/directional_light.rs +++ b/crates/bevy_pbr/src/light/directional_light.rs @@ -56,6 +56,7 @@ use super::*; CascadesFrusta, CascadeShadowConfig, CascadesVisibleEntities, + LightShadows, Transform, Visibility )] @@ -73,30 +74,23 @@ pub struct DirectionalLight { /// area. pub illuminance: f32, - /// Whether this light casts shadows. + /// The angular size of this light in radians. This must be a value in the + /// range [0, π). /// - /// Note that shadows are rather expensive and become more so with every - /// light that casts them. In general, it's best to aggressively limit the - /// number of lights with shadows enabled to one or two at most. - pub shadows_enabled: bool, - - /// Whether soft shadows are enabled, and if so, the size of the light. - /// - /// Soft shadows, also known as *percentage-closer soft shadows* or PCSS, - /// cause shadows to become blurrier (i.e. their penumbra increases in - /// radius) as they extend away from objects. The blurriness of the shadow - /// depends on the size of the light; larger lights result in larger - /// penumbras and therefore blurrier shadows. + /// The angular size of an object is how large it appears in one's field + /// of view. For example, if viewed from the surface of the Earth, if one + /// were to draw a line (specifically a *great circle*]) across the sky + /// through the center of the Sun, the Sun would cover roughly 0.5 degrees + /// of that circle, or 8.73e-3 radians. /// - /// Currently, soft shadows are rather noisy if not using the temporal mode. - /// If you enable soft shadows, consider choosing - /// [`ShadowFilteringMethod::Temporal`] and enabling temporal antialiasing - /// (TAA) to smooth the noise out over time. + /// This value controls the radius of soft shadow penumbras, as well as + /// some volumetric lighting effects. See [`LightShadows`] for more + /// information on soft shadows. /// - /// Note that soft shadows are significantly more expensive to render than - /// hard shadows. - #[cfg(feature = "experimental_pbr_pcss")] - pub soft_shadow_size: Option, + /// Note that this is not the same thing as the *solid angle* (or "angular + /// area", roughly) that this light covers in the sky. That is a separate + /// measurement, with units of *steradians* rather than radians. + pub angular_size: f32, /// A value that adjusts the tradeoff between self-shadowing artifacts and /// proximity of shadows to their casters. @@ -120,11 +114,9 @@ impl Default for DirectionalLight { DirectionalLight { color: Color::WHITE, illuminance: light_consts::lux::AMBIENT_DAYLIGHT, - shadows_enabled: false, + angular_size: Self::SUN_ANGULAR_SIZE, shadow_depth_bias: Self::DEFAULT_SHADOW_DEPTH_BIAS, shadow_normal_bias: Self::DEFAULT_SHADOW_NORMAL_BIAS, - #[cfg(feature = "experimental_pbr_pcss")] - soft_shadow_size: None, } } } @@ -132,4 +124,5 @@ impl Default for DirectionalLight { impl DirectionalLight { pub const DEFAULT_SHADOW_DEPTH_BIAS: f32 = 0.02; pub const DEFAULT_SHADOW_NORMAL_BIAS: f32 = 1.8; + pub const SUN_ANGULAR_SIZE: f32 = 8.72665e-3; } diff --git a/crates/bevy_pbr/src/light/mod.rs b/crates/bevy_pbr/src/light/mod.rs index 0b93c93c6792c..36000802a358e 100644 --- a/crates/bevy_pbr/src/light/mod.rs +++ b/crates/bevy_pbr/src/light/mod.rs @@ -296,9 +296,11 @@ pub struct Cascade { pub(crate) texel_size: f32, } -pub fn clear_directional_light_cascades(mut lights: Query<(&DirectionalLight, &mut Cascades)>) { - for (directional_light, mut cascades) in lights.iter_mut() { - if !directional_light.shadows_enabled { +pub fn clear_directional_light_cascades( + mut lights: Query<(&ShadowsStyle, &mut Cascades), With>, +) { + for (directional_light_shadows, mut cascades) in lights.iter_mut() { + if !directional_light_shadows.enabled() { continue; } cascades.cascades.clear(); @@ -308,12 +310,15 @@ pub fn clear_directional_light_cascades(mut lights: Query<(&DirectionalLight, &m pub fn build_directional_light_cascades( directional_light_shadow_map: Res, views: Query<(Entity, &GlobalTransform, &P, &Camera)>, - mut lights: Query<( - &GlobalTransform, - &DirectionalLight, - &CascadeShadowConfig, - &mut Cascades, - )>, + mut lights: Query< + ( + &GlobalTransform, + &ShadowsStyle, + &CascadeShadowConfig, + &mut Cascades, + ), + With, + >, ) { let views = views .iter() @@ -326,8 +331,8 @@ pub fn build_directional_light_cascades( }) .collect::>(); - for (transform, directional_light, cascades_config, mut cascades) in &mut lights { - if !directional_light.shadows_enabled { + for (transform, directional_light_shadows, cascades_config, mut cascades) in &mut lights { + if !directional_light_shadows.enabled() { continue; } @@ -443,10 +448,59 @@ fn calculate_cascade( texel_size: cascade_texel_size, } } + +/// Add this component to a light ([`DirectionalLight`], [`PointLight`], or +/// [`SpotLight`]) to control what style of shadows it casts. +#[derive(Copy, Clone, Default, Component, PartialEq, Eq, Hash, Debug, Reflect)] +#[reflect(Component, Default, Debug)] +pub enum ShadowsStyle { + /// Disables all shadows for this light. + #[default] + None, + + /// Enables hard shadows for this light, which will not blur as they extend + /// away from objeccts. + Hard, + + /// Enables soft shadows for this light. + /// + /// Soft shadows, also known as *percentage-closer soft shadows* or PCSS, + /// cause shadows to become blurrier (i.e. their penumbra increases in + /// radius) as they extend away from objects. The blurriness of the shadow + /// depends on the size of the light; larger lights result in larger + /// penumbras and therefore blurrier shadows. + /// + /// Currently, soft shadows are rather noisy if not using the temporal mode. + /// If you enable soft shadows, consider choosing + /// [`ShadowFilteringMethod::Temporal`] and enabling temporal antialiasing + /// (TAA) to smooth the noise out over time. + /// + /// Note that soft shadows are significantly more expensive to render than + /// hard shadows. + #[cfg(feature = "experimental_pbr_pcss")] + Soft, +} + +impl ShadowsStyle { + pub fn enabled(&self) -> bool { + *self != ShadowsStyle::None + } + + #[inline] + #[allow(unreachable_patterns)] + pub(crate) fn if_soft(&self, num: f32) -> f32 { + match self { + ShadowsStyle::None | ShadowsStyle::Hard => 0.0, + _ => num, + } + } +} + /// Add this component to make a [`Mesh3d`] not cast shadows. #[derive(Debug, Component, Reflect, Default)] #[reflect(Component, Default, Debug)] pub struct NotShadowCaster; + /// Add this component to make a [`Mesh3d`] not receive shadows. /// /// **Note:** If you're using diffuse transmission, setting [`NotShadowReceiver`] will @@ -455,6 +509,7 @@ pub struct NotShadowCaster; #[derive(Debug, Component, Reflect, Default)] #[reflect(Component, Default, Debug)] pub struct NotShadowReceiver; + /// Add this component to make a [`Mesh3d`] using a PBR material with [`diffuse_transmission`](crate::pbr_material::StandardMaterial::diffuse_transmission)`> 0.0` /// receive shadows on its diffuse transmission lobe. (i.e. its “backside”) /// @@ -541,21 +596,22 @@ pub fn update_directional_light_frusta( mut views: Query< ( &Cascades, - &DirectionalLight, + &ShadowsStyle, &ViewVisibility, &mut CascadesFrusta, ), ( + With, // Prevents this query from conflicting with camera queries. Without, ), >, ) { - for (cascades, directional_light, visibility, mut frusta) in &mut views { + for (cascades, directional_light_shadows, visibility, mut frusta) in &mut views { // The frustum is used for culling meshes to the light for shadow mapping // so if shadow mapping is disabled for this light, then the frustum is // not needed. - if !directional_light.shadows_enabled || !visibility.get() { + if !directional_light_shadows.enabled() || !visibility.get() { continue; } @@ -579,7 +635,13 @@ pub fn update_directional_light_frusta( pub fn update_point_light_frusta( global_lights: Res, mut views: Query< - (Entity, &GlobalTransform, &PointLight, &mut CubemapFrusta), + ( + Entity, + &GlobalTransform, + &PointLight, + &ShadowsStyle, + &mut CubemapFrusta, + ), Or<(Changed, Changed)>, >, ) { @@ -588,13 +650,13 @@ pub fn update_point_light_frusta( .map(|CubeMapFace { target, up }| Transform::IDENTITY.looking_at(*target, *up)) .collect::>(); - for (entity, transform, point_light, mut cubemap_frusta) in &mut views { + for (entity, transform, point_light, light_shadows, mut cubemap_frusta) in &mut views { // The frusta are used for culling meshes to the light for shadow mapping // so if shadow mapping is disabled for this light, then the frusta are // not needed. // Also, if the light is not relevant for any cluster, it will not be in the // global lights set and so there is no need to update its frusta. - if !point_light.shadows_enabled || !global_lights.entities.contains(&entity) { + if !light_shadows.enabled() || !global_lights.entities.contains(&entity) { continue; } @@ -627,17 +689,23 @@ pub fn update_point_light_frusta( pub fn update_spot_light_frusta( global_lights: Res, mut views: Query< - (Entity, &GlobalTransform, &SpotLight, &mut Frustum), + ( + Entity, + &GlobalTransform, + &SpotLight, + &ShadowsStyle, + &mut Frustum, + ), Or<(Changed, Changed)>, >, ) { - for (entity, transform, spot_light, mut frustum) in &mut views { + for (entity, transform, spot_light, spot_light_shadows, mut frustum) in &mut views { // The frusta are used for culling meshes to the light for shadow mapping // so if shadow mapping is disabled for this light, then the frusta are // not needed. // Also, if the light is not relevant for any cluster, it will not be in the // global lights set and so there is no need to update its frusta. - if !spot_light.shadows_enabled || !global_lights.entities.contains(&entity) { + if !spot_light_shadows.enabled() || !global_lights.entities.contains(&entity) { continue; } @@ -679,13 +747,13 @@ pub fn check_dir_light_mesh_visibility( mut commands: Commands, mut directional_lights: Query< ( - &DirectionalLight, + &ShadowsStyle, &CascadesFrusta, &mut CascadesVisibleEntities, Option<&RenderLayers>, &ViewVisibility, ), - Without, + With, >, visible_entity_query: Query< ( @@ -709,8 +777,13 @@ pub fn check_dir_light_mesh_visibility( ) { let visible_entity_ranges = visible_entity_ranges.as_deref(); - for (directional_light, frusta, mut visible_entities, maybe_view_mask, light_view_visibility) in - &mut directional_lights + for ( + directional_light_shadows, + frusta, + mut visible_entities, + maybe_view_mask, + light_view_visibility, + ) in &mut directional_lights { let mut views_to_remove = Vec::new(); for (view, cascade_view_entities) in &mut visible_entities.entities { @@ -734,7 +807,7 @@ pub fn check_dir_light_mesh_visibility( } // NOTE: If shadow mapping is disabled for the light then it must have no visible entities - if !directional_light.shadows_enabled || !light_view_visibility.get() { + if !directional_light_shadows.enabled() || !light_view_visibility.get() { continue; } @@ -844,6 +917,7 @@ pub fn check_point_light_mesh_visibility( visible_point_lights: Query<&VisibleClusterableObjects>, mut point_lights: Query<( &PointLight, + &ShadowsStyle, &GlobalTransform, &CubemapFrusta, &mut CubemapVisibleEntities, @@ -851,6 +925,7 @@ pub fn check_point_light_mesh_visibility( )>, mut spot_lights: Query<( &SpotLight, + &ShadowsStyle, &GlobalTransform, &Frustum, &mut VisibleMeshEntities, @@ -890,6 +965,7 @@ pub fn check_point_light_mesh_visibility( // Point lights if let Ok(( point_light, + point_light_shadows, transform, cubemap_frusta, mut cubemap_visible_entities, @@ -901,7 +977,7 @@ pub fn check_point_light_mesh_visibility( } // NOTE: If shadow mapping is disabled for the light then it must have no visible entities - if !point_light.shadows_enabled { + if !point_light_shadows.enabled() { continue; } @@ -983,13 +1059,19 @@ pub fn check_point_light_mesh_visibility( } // Spot lights - if let Ok((point_light, transform, frustum, mut visible_entities, maybe_view_mask)) = - spot_lights.get_mut(light_entity) + if let Ok(( + point_light, + spot_light_shadows, + transform, + frustum, + mut visible_entities, + maybe_view_mask, + )) = spot_lights.get_mut(light_entity) { visible_entities.clear(); // NOTE: If shadow mapping is disabled for the light then it must have no visible entities - if !point_light.shadows_enabled { + if !spot_light_shadows.enabled() { continue; } diff --git a/crates/bevy_pbr/src/light/point_light.rs b/crates/bevy_pbr/src/light/point_light.rs index ee08a57ba1e39..d651c5e59ec89 100644 --- a/crates/bevy_pbr/src/light/point_light.rs +++ b/crates/bevy_pbr/src/light/point_light.rs @@ -21,7 +21,13 @@ use super::*; /// Source: [Wikipedia](https://en.wikipedia.org/wiki/Lumen_(unit)#Lighting) #[derive(Component, Debug, Clone, Copy, Reflect)] #[reflect(Component, Default, Debug)] -#[require(CubemapFrusta, CubemapVisibleEntities, Transform, Visibility)] +#[require( + CubemapFrusta, + CubemapVisibleEntities, + LightShadows, + Transform, + Visibility +)] pub struct PointLight { /// The color of this light source. pub color: Color, @@ -43,27 +49,6 @@ pub struct PointLight { /// affect shadow softness or diffuse lighting. pub radius: f32, - /// Whether this light casts shadows. - pub shadows_enabled: bool, - - /// Whether soft shadows are enabled. - /// - /// Soft shadows, also known as *percentage-closer soft shadows* or PCSS, - /// cause shadows to become blurrier (i.e. their penumbra increases in - /// radius) as they extend away from objects. The blurriness of the shadow - /// depends on the [`PointLight::radius`] of the light; larger lights result - /// in larger penumbras and therefore blurrier shadows. - /// - /// Currently, soft shadows are rather noisy if not using the temporal mode. - /// If you enable soft shadows, consider choosing - /// [`ShadowFilteringMethod::Temporal`] and enabling temporal antialiasing - /// (TAA) to smooth the noise out over time. - /// - /// Note that soft shadows are significantly more expensive to render than - /// hard shadows. - #[cfg(feature = "experimental_pbr_pcss")] - pub soft_shadows_enabled: bool, - /// A bias used when sampling shadow maps to avoid "shadow-acne", or false shadow occlusions /// that happen as a result of shadow-map fragments not mapping 1:1 to screen-space fragments. /// Too high of a depth bias can lead to shadows detaching from their casters, or @@ -95,12 +80,9 @@ impl Default for PointLight { intensity: 1_000_000.0, range: 20.0, radius: 0.0, - shadows_enabled: false, shadow_depth_bias: Self::DEFAULT_SHADOW_DEPTH_BIAS, shadow_normal_bias: Self::DEFAULT_SHADOW_NORMAL_BIAS, shadow_map_near_z: Self::DEFAULT_SHADOW_MAP_NEAR_Z, - #[cfg(feature = "experimental_pbr_pcss")] - soft_shadows_enabled: false, } } } diff --git a/crates/bevy_pbr/src/light/spot_light.rs b/crates/bevy_pbr/src/light/spot_light.rs index 845d55e697317..78cabe438bf01 100644 --- a/crates/bevy_pbr/src/light/spot_light.rs +++ b/crates/bevy_pbr/src/light/spot_light.rs @@ -9,7 +9,7 @@ use super::*; /// the transform, and can be specified with [`Transform::looking_at`](Transform::looking_at). #[derive(Component, Debug, Clone, Copy, Reflect)] #[reflect(Component, Default, Debug)] -#[require(Frustum, VisibleMeshEntities, Transform, Visibility)] +#[require(Frustum, VisibleMeshEntities, LightShadows, Transform, Visibility)] pub struct SpotLight { /// The color of the light. /// @@ -35,31 +35,6 @@ pub struct SpotLight { /// affect shadow softness or diffuse lighting. pub radius: f32, - /// Whether this light casts shadows. - /// - /// Note that shadows are rather expensive and become more so with every - /// light that casts them. In general, it's best to aggressively limit the - /// number of lights with shadows enabled to one or two at most. - pub shadows_enabled: bool, - - /// Whether soft shadows are enabled. - /// - /// Soft shadows, also known as *percentage-closer soft shadows* or PCSS, - /// cause shadows to become blurrier (i.e. their penumbra increases in - /// radius) as they extend away from objects. The blurriness of the shadow - /// depends on the [`SpotLight::radius`] of the light; larger lights result in larger - /// penumbras and therefore blurrier shadows. - /// - /// Currently, soft shadows are rather noisy if not using the temporal mode. - /// If you enable soft shadows, consider choosing - /// [`ShadowFilteringMethod::Temporal`] and enabling temporal antialiasing - /// (TAA) to smooth the noise out over time. - /// - /// Note that soft shadows are significantly more expensive to render than - /// hard shadows. - #[cfg(feature = "experimental_pbr_pcss")] - pub soft_shadows_enabled: bool, - /// A value that adjusts the tradeoff between self-shadowing artifacts and /// proximity of shadows to their casters. /// @@ -115,14 +90,11 @@ impl Default for SpotLight { intensity: 1_000_000.0, range: 20.0, radius: 0.0, - shadows_enabled: false, shadow_depth_bias: Self::DEFAULT_SHADOW_DEPTH_BIAS, shadow_normal_bias: Self::DEFAULT_SHADOW_NORMAL_BIAS, shadow_map_near_z: Self::DEFAULT_SHADOW_MAP_NEAR_Z, inner_angle: 0.0, outer_angle: core::f32::consts::FRAC_PI_4, - #[cfg(feature = "experimental_pbr_pcss")] - soft_shadows_enabled: false, } } } diff --git a/crates/bevy_pbr/src/render/light.rs b/crates/bevy_pbr/src/render/light.rs index c2a61d16e08e2..35e7cd7478f9f 100644 --- a/crates/bevy_pbr/src/render/light.rs +++ b/crates/bevy_pbr/src/render/light.rs @@ -51,13 +51,12 @@ pub struct ExtractedPointLight { pub range: f32, pub radius: f32, pub transform: GlobalTransform, - pub shadows_enabled: bool, + pub shadows: ShadowsStyle, pub shadow_depth_bias: f32, pub shadow_normal_bias: f32, pub shadow_map_near_z: f32, pub spot_light_angles: Option<(f32, f32)>, pub volumetric: bool, - pub soft_shadows_enabled: bool, } #[derive(Component, Debug)] @@ -65,15 +64,15 @@ pub struct ExtractedDirectionalLight { pub color: LinearRgba, pub illuminance: f32, pub transform: GlobalTransform, - pub shadows_enabled: bool, pub volumetric: bool, + pub angular_size: f32, + pub shadows: ShadowsStyle, pub shadow_depth_bias: f32, pub shadow_normal_bias: f32, pub cascade_shadow_config: CascadeShadowConfig, pub cascades: EntityHashMap>, pub frusta: EntityHashMap>, pub render_layers: RenderLayers, - pub soft_shadow_size: Option, } // NOTE: These must match the bit flags in bevy_pbr/src/render/mesh_view_types.wgsl! @@ -101,7 +100,7 @@ pub struct GpuDirectionalLight { color: Vec4, dir_to_light: Vec3, flags: u32, - soft_shadow_size: f32, + tan_half_angular_size: f32, shadow_depth_bias: f32, shadow_normal_bias: f32, num_cascades: u32, @@ -210,6 +209,7 @@ pub fn extract_lights( Query<( RenderEntity, &PointLight, + &ShadowsStyle, &CubemapVisibleEntities, &GlobalTransform, &ViewVisibility, @@ -221,6 +221,7 @@ pub fn extract_lights( Query<( RenderEntity, &SpotLight, + &ShadowsStyle, &VisibleMeshEntities, &GlobalTransform, &ViewVisibility, @@ -233,6 +234,7 @@ pub fn extract_lights( ( RenderEntity, &DirectionalLight, + &ShadowsStyle, &CascadesVisibleEntities, &Cascades, &CascadeShadowConfig, @@ -271,6 +273,7 @@ pub fn extract_lights( let Ok(( render_entity, point_light, + point_light_shadows, cubemap_visible_entities, transform, view_visibility, @@ -301,7 +304,7 @@ pub fn extract_lights( range: point_light.range, radius: point_light.radius, transform: *transform, - shadows_enabled: point_light.shadows_enabled, + shadows: *point_light_shadows, shadow_depth_bias: point_light.shadow_depth_bias, // The factor of SQRT_2 is for the worst-case diagonal offset shadow_normal_bias: point_light.shadow_normal_bias @@ -310,10 +313,6 @@ pub fn extract_lights( shadow_map_near_z: point_light.shadow_map_near_z, spot_light_angles: None, volumetric: volumetric_light.is_some(), - #[cfg(feature = "experimental_pbr_pcss")] - soft_shadows_enabled: point_light.soft_shadows_enabled, - #[cfg(not(feature = "experimental_pbr_pcss"))] - soft_shadows_enabled: false, }; point_lights_values.push(( render_entity, @@ -332,6 +331,7 @@ pub fn extract_lights( if let Ok(( render_entity, spot_light, + spot_light_shadows, visible_entities, transform, view_visibility, @@ -363,7 +363,7 @@ pub fn extract_lights( range: spot_light.range, radius: spot_light.radius, transform: *transform, - shadows_enabled: spot_light.shadows_enabled, + shadows: *spot_light_shadows, shadow_depth_bias: spot_light.shadow_depth_bias, // The factor of SQRT_2 is for the worst-case diagonal offset shadow_normal_bias: spot_light.shadow_normal_bias @@ -372,10 +372,6 @@ pub fn extract_lights( shadow_map_near_z: spot_light.shadow_map_near_z, spot_light_angles: Some((spot_light.inner_angle, spot_light.outer_angle)), volumetric: volumetric_light.is_some(), - #[cfg(feature = "experimental_pbr_pcss")] - soft_shadows_enabled: spot_light.soft_shadows_enabled, - #[cfg(not(feature = "experimental_pbr_pcss"))] - soft_shadows_enabled: false, }, render_visible_entities, *frustum, @@ -389,6 +385,7 @@ pub fn extract_lights( for ( entity, directional_light, + directional_light_shadows, visible_entities, cascades, cascade_config, @@ -447,11 +444,8 @@ pub fn extract_lights( illuminance: directional_light.illuminance, transform: *transform, volumetric: volumetric_light.is_some(), - #[cfg(feature = "experimental_pbr_pcss")] - soft_shadow_size: directional_light.soft_shadow_size, - #[cfg(not(feature = "experimental_pbr_pcss"))] - soft_shadow_size: None, - shadows_enabled: directional_light.shadows_enabled, + angular_size: directional_light.angular_size, + shadows: *directional_light_shadows, shadow_depth_bias: directional_light.shadow_depth_bias, // The factor of SQRT_2 is for the worst-case diagonal offset shadow_normal_bias: directional_light.shadow_normal_bias @@ -784,7 +778,7 @@ pub fn prepare_lights( let point_light_shadow_maps_count = point_lights .iter() - .filter(|light| light.1.shadows_enabled && light.1.spot_light_angles.is_none()) + .filter(|light| light.1.shadows.enabled() && light.1.spot_light_angles.is_none()) .count() .min(max_texture_cubes); @@ -798,7 +792,7 @@ pub fn prepare_lights( let directional_shadow_enabled_count = directional_lights .iter() .take(MAX_DIRECTIONAL_LIGHTS) - .filter(|(_, light)| light.shadows_enabled) + .filter(|(_, light)| light.shadows.enabled()) .count() .min(max_texture_array_layers / MAX_CASCADES_PER_LIGHT); @@ -816,7 +810,7 @@ pub fn prepare_lights( let spot_light_shadow_maps_count = point_lights .iter() - .filter(|(_, light, _)| light.shadows_enabled && light.spot_light_angles.is_some()) + .filter(|(_, light, _)| light.shadows.enabled() && light.spot_light_angles.is_some()) .count() .min(max_texture_array_layers - directional_shadow_enabled_count * MAX_CASCADES_PER_LIGHT); @@ -848,8 +842,8 @@ pub fn prepare_lights( // lights are chosen if the light count limit is exceeded. directional_lights.sort_by(|(entity_1, light_1), (entity_2, light_2)| { directional_light_order( - (entity_1, &light_1.volumetric, &light_1.shadows_enabled), - (entity_2, &light_2.volumetric, &light_2.shadows_enabled), + (entity_1, &light_1.volumetric, &light_1.shadows.enabled()), + (entity_2, &light_2.volumetric, &light_2.shadows.enabled()), ) }); @@ -864,7 +858,7 @@ pub fn prepare_lights( let mut flags = PointLightFlags::NONE; // Lights are sorted, shadow enabled lights are first - if light.shadows_enabled + if light.shadows.enabled() && (index < point_light_shadow_maps_count || (light.spot_light_angles.is_some() && index - point_light_count < spot_light_shadow_maps_count)) @@ -877,7 +871,7 @@ pub fn prepare_lights( 1.0, light.shadow_map_near_z, ); - if light.shadows_enabled + if light.shadows.enabled() && light.volumetric && (index < point_light_volumetric_enabled_count || (light.spot_light_angles.is_some() @@ -934,11 +928,7 @@ pub fn prepare_lights( spot_light_tan_angle, pad_a: 0.0, pad_b: 0.0, - soft_shadow_size: if light.soft_shadows_enabled { - light.radius - } else { - 0.0 - }, + soft_shadow_size: light.shadows.if_soft(light.radius), }); global_light_meta.entity_to_index.insert(entity, index); } @@ -954,13 +944,13 @@ pub fn prepare_lights( // Lights are sorted, volumetric and shadow enabled lights are first if light.volumetric - && light.shadows_enabled + && light.shadows.enabled() && (index < directional_volumetric_enabled_count) { flags |= DirectionalLightFlags::VOLUMETRIC; } // Shadow enabled lights are second - if light.shadows_enabled && (index < directional_shadow_enabled_count) { + if light.shadows.enabled() && (index < directional_shadow_enabled_count) { flags |= DirectionalLightFlags::SHADOWS_ENABLED; } @@ -980,7 +970,7 @@ pub fn prepare_lights( // direction is negated to be ready for N.L dir_to_light: light.transform.back().into(), flags: flags.bits(), - soft_shadow_size: light.soft_shadow_size.unwrap_or_default(), + tan_half_angular_size: light.shadows.if_soft(ops::tan(light.angular_size * 0.5)), shadow_depth_bias: light.shadow_depth_bias, shadow_normal_bias: light.shadow_normal_bias, num_cascades: num_cascades as u32, @@ -1144,7 +1134,7 @@ pub fn prepare_lights( continue; }; - if !light.shadows_enabled { + if !light.shadows.enabled() { if let Some(entities) = light_view_entities.remove(&entity) { despawn_entities(&mut commands, entities); } @@ -1257,7 +1247,7 @@ pub fn prepare_lights( continue; }; - if !light.shadows_enabled { + if !light.shadows.enabled() { if let Some(entities) = light_view_entities.remove(&entity) { despawn_entities(&mut commands, entities); } diff --git a/crates/bevy_pbr/src/render/mesh_view_types.wgsl b/crates/bevy_pbr/src/render/mesh_view_types.wgsl index a3648340f3bd0..7bbeb93e4bd9d 100644 --- a/crates/bevy_pbr/src/render/mesh_view_types.wgsl +++ b/crates/bevy_pbr/src/render/mesh_view_types.wgsl @@ -33,7 +33,7 @@ struct DirectionalLight { direction_to_light: vec3, // 'flags' is a bit field indicating various options. u32 is 32 bits so we have up to 32 options. flags: u32, - soft_shadow_size: f32, + tan_half_angular_size: f32, shadow_depth_bias: f32, shadow_normal_bias: f32, num_cascades: u32, diff --git a/crates/bevy_pbr/src/render/shadow_sampling.wgsl b/crates/bevy_pbr/src/render/shadow_sampling.wgsl index 22f2e28310bd0..b6c4c669c67d8 100644 --- a/crates/bevy_pbr/src/render/shadow_sampling.wgsl +++ b/crates/bevy_pbr/src/render/shadow_sampling.wgsl @@ -222,11 +222,11 @@ fn search_for_blockers_in_shadow_map( light_local: vec2, depth: f32, array_index: i32, - texel_size: f32, - search_size: f32, + light_tan_half_angular_size: f32, ) -> f32 { let shadow_map_size = vec2(textureDimensions(view_bindings::directional_shadow_textures)); - let uv_offset_scale = search_size / (texel_size * shadow_map_size); + //TODO: this is likely not correct. + let uv_offset_scale = light_tan_half_angular_size * depth / shadow_map_size; let offset0 = D3D_SAMPLE_POINT_POSITIONS[0] * uv_offset_scale; let offset1 = D3D_SAMPLE_POINT_POSITIONS[1] * uv_offset_scale; @@ -286,14 +286,17 @@ fn sample_shadow_map_pcss( depth: f32, array_index: i32, texel_size: f32, - light_size: f32, + light_tan_half_angular_size: f32, ) -> f32 { // Determine the average Z value of the closest blocker. let z_blocker = search_for_blockers_in_shadow_map( - light_local, depth, array_index, texel_size, light_size); + light_local, depth, array_index, light_tan_half_angular_size); + //TODO: check correctness. Maybe missing a factor of 2 next to tan_half_angular_size? + //Depends on if it's blur radius or diameter + // // Don't let the blur size go below 0.5, or shadows will look unacceptably aliased. - let blur_size = max((z_blocker - depth) * light_size / depth, 0.5); + let blur_size = max(texel_size * light_tan_half_angular_size * (z_blocker - depth), 0.5); // FIXME: We can't use Castano '13 here because that has a hard-wired fixed // size. So we instead use Jimenez '14 unconditionally. In the non-temporal diff --git a/crates/bevy_pbr/src/render/shadows.wgsl b/crates/bevy_pbr/src/render/shadows.wgsl index 0e539f00091c5..5f86a41db1a18 100644 --- a/crates/bevy_pbr/src/render/shadows.wgsl +++ b/crates/bevy_pbr/src/render/shadows.wgsl @@ -191,9 +191,9 @@ fn sample_directional_cascade( let texel_size = (*cascade).texel_size; // If soft shadows are enabled, use the PCSS path. - if ((*light).soft_shadow_size > 0.0) { + if ((*light).tan_half_angular_size > 0.0) { return sample_shadow_map_pcss( - light_local.xy, light_local.z, array_index, texel_size, (*light).soft_shadow_size); + light_local.xy, light_local.z, array_index, texel_size, (*light).tan_half_angular_size); } return sample_shadow_map(light_local.xy, light_local.z, array_index, texel_size); diff --git a/examples/3d/3d_scene.rs b/examples/3d/3d_scene.rs index 5ea7e20b29662..20f0cfaa61789 100644 --- a/examples/3d/3d_scene.rs +++ b/examples/3d/3d_scene.rs @@ -1,6 +1,6 @@ //! A simple 3D scene with light shining over a cube sitting on a plane. -use bevy::prelude::*; +use bevy::{pbr::ShadowsStyle, prelude::*}; fn main() { App::new() @@ -29,10 +29,8 @@ fn setup( )); // light commands.spawn(( - PointLight { - shadows_enabled: true, - ..default() - }, + PointLight::default(), + ShadowsStyle::Hard, Transform::from_xyz(4.0, 8.0, 4.0), )); // camera diff --git a/examples/3d/3d_shapes.rs b/examples/3d/3d_shapes.rs index 0346abd3526d5..d24cc3f8e96ac 100644 --- a/examples/3d/3d_shapes.rs +++ b/examples/3d/3d_shapes.rs @@ -10,6 +10,7 @@ use std::f32::consts::PI; use bevy::pbr::wireframe::{WireframeConfig, WireframePlugin}; use bevy::{ color::palettes::basic::SILVER, + pbr::ShadowsStyle, prelude::*, render::{ render_asset::RenderAssetUsages, @@ -112,12 +113,12 @@ fn setup( commands.spawn(( PointLight { - shadows_enabled: true, intensity: 10_000_000., range: 100.0, shadow_depth_bias: 0.2, ..default() }, + ShadowsStyle::Hard, Transform::from_xyz(8.0, 16.0, 8.0), )); diff --git a/examples/3d/anti_aliasing.rs b/examples/3d/anti_aliasing.rs index f41ca3576fe99..43f3c9b56b131 100644 --- a/examples/3d/anti_aliasing.rs +++ b/examples/3d/anti_aliasing.rs @@ -11,7 +11,7 @@ use bevy::{ smaa::{Smaa, SmaaPreset}, }, image::{ImageSampler, ImageSamplerDescriptor}, - pbr::CascadeShadowConfigBuilder, + pbr::{CascadeShadowConfigBuilder, ShadowsStyle}, prelude::*, render::{ camera::TemporalJitter, @@ -285,9 +285,9 @@ fn setup( commands.spawn(( DirectionalLight { illuminance: light_consts::lux::FULL_DAYLIGHT, - shadows_enabled: true, ..default() }, + ShadowsStyle::Hard, Transform::from_rotation(Quat::from_euler(EulerRot::ZYX, 0.0, PI * -0.15, PI * -0.15)), CascadeShadowConfigBuilder { maximum_distance: 3.0, diff --git a/examples/3d/atmospheric_fog.rs b/examples/3d/atmospheric_fog.rs index e24736cdd1644..ae4c8995ebce4 100644 --- a/examples/3d/atmospheric_fog.rs +++ b/examples/3d/atmospheric_fog.rs @@ -8,7 +8,7 @@ //! | `S` | Toggle Directional Light Fog Influence | use bevy::{ - pbr::{CascadeShadowConfigBuilder, NotShadowCaster}, + pbr::{CascadeShadowConfigBuilder, ShadowsStyle, NotShadowCaster}, prelude::*, }; @@ -58,9 +58,9 @@ fn setup_terrain_scene( commands.spawn(( DirectionalLight { color: Color::srgb(0.98, 0.95, 0.82), - shadows_enabled: true, ..default() }, + ShadowsStyle::Hard, Transform::from_xyz(0.0, 0.0, 0.0).looking_at(Vec3::new(-0.15, -0.05, 0.25), Vec3::Y), cascade_shadow_config, )); diff --git a/examples/3d/camera_sub_view.rs b/examples/3d/camera_sub_view.rs index 0fea1633d0455..e0a9e8f27fb57 100644 --- a/examples/3d/camera_sub_view.rs +++ b/examples/3d/camera_sub_view.rs @@ -7,6 +7,7 @@ //! camera //! - Rapidly change the sub view offset to get a screen shake effect use bevy::{ + pbr::ShadowsStyle, prelude::*, render::camera::{ScalingMode, SubCameraView, Viewport}, }; @@ -45,10 +46,8 @@ fn setup( // Light commands.spawn(( - PointLight { - shadows_enabled: true, - ..default() - }, + PointLight::default(), + ShadowsStyle::Hard, Transform::from_xyz(4.0, 8.0, 4.0), )); diff --git a/examples/3d/color_grading.rs b/examples/3d/color_grading.rs index 60195426e8020..5801a8776f6a8 100644 --- a/examples/3d/color_grading.rs +++ b/examples/3d/color_grading.rs @@ -7,7 +7,7 @@ use std::{ use bevy::{ ecs::system::EntityCommands, - pbr::CascadeShadowConfigBuilder, + pbr::{CascadeShadowConfigBuilder, ShadowsStyle}, prelude::*, render::view::{ColorGrading, ColorGradingGlobal, ColorGradingSection}, }; @@ -376,9 +376,9 @@ fn add_basic_scene(commands: &mut Commands, asset_server: &AssetServer) { commands.spawn(( DirectionalLight { illuminance: 15000.0, - shadows_enabled: true, ..default() }, + ShadowsStyle::Hard, Transform::from_rotation(Quat::from_euler(EulerRot::ZYX, 0.0, PI * -0.15, PI * -0.15)), CascadeShadowConfigBuilder { maximum_distance: 3.0, diff --git a/examples/3d/deferred_rendering.rs b/examples/3d/deferred_rendering.rs index 2bca5a5be7b6b..9870ad4849a30 100644 --- a/examples/3d/deferred_rendering.rs +++ b/examples/3d/deferred_rendering.rs @@ -11,7 +11,7 @@ use bevy::{ math::ops, pbr::{ CascadeShadowConfigBuilder, DefaultOpaqueRendererMethod, DirectionalLightShadowMap, - NotShadowCaster, NotShadowReceiver, OpaqueRendererMethod, + ShadowsStyle, NotShadowCaster, NotShadowReceiver, OpaqueRendererMethod, }, prelude::*, }; @@ -66,9 +66,9 @@ fn setup( commands.spawn(( DirectionalLight { illuminance: 15_000., - shadows_enabled: true, ..default() }, + ShadowsStyle::Hard, CascadeShadowConfigBuilder { num_cascades: 3, maximum_distance: 10.0, @@ -129,10 +129,10 @@ fn setup( PointLight { intensity: 800.0, radius: 0.125, - shadows_enabled: true, color: sphere_color, ..default() }, + ShadowsStyle::Hard, sphere_pos, )); diff --git a/examples/3d/depth_of_field.rs b/examples/3d/depth_of_field.rs index d6ca77bbde0ca..ac719ee31c290 100644 --- a/examples/3d/depth_of_field.rs +++ b/examples/3d/depth_of_field.rs @@ -15,7 +15,7 @@ use bevy::{ dof::{self, DepthOfField, DepthOfFieldMode}, tonemapping::Tonemapping, }, - pbr::Lightmap, + pbr::{ShadowsStyle, Lightmap}, prelude::*, render::camera::PhysicalCameraParameters, }; @@ -184,7 +184,7 @@ fn tweak_scene( mut commands: Commands, asset_server: Res, mut materials: ResMut>, - mut lights: Query<&mut DirectionalLight, Changed>, + mut lights: Query<&mut ShadowsStyle, Changed>, mut named_entities: Query< (Entity, &Name, &MeshMaterial3d), (With, Without), @@ -192,7 +192,7 @@ fn tweak_scene( ) { // Turn on shadows. for mut light in lights.iter_mut() { - light.shadows_enabled = true; + *light = ShadowsStyle::Hard; } // Add a nice lightmap to the circuit board. diff --git a/examples/3d/fog.rs b/examples/3d/fog.rs index 1df8c3ce4f3dc..a23d6e679439d 100644 --- a/examples/3d/fog.rs +++ b/examples/3d/fog.rs @@ -16,7 +16,7 @@ use bevy::{ math::ops, - pbr::{NotShadowCaster, NotShadowReceiver}, + pbr::{ShadowsStyle, NotShadowCaster, NotShadowReceiver}, prelude::*, }; @@ -107,10 +107,8 @@ fn setup_pyramid_scene( // light commands.spawn(( - PointLight { - shadows_enabled: true, - ..default() - }, + PointLight::default(), + ShadowsStyle::Hard, Transform::from_xyz(0.0, 1.0, 0.0), )); } diff --git a/examples/3d/fog_volumes.rs b/examples/3d/fog_volumes.rs index 68fc6d0ea783e..6e0a1eee80c96 100644 --- a/examples/3d/fog_volumes.rs +++ b/examples/3d/fog_volumes.rs @@ -7,7 +7,7 @@ use bevy::{ math::vec3, - pbr::{FogVolume, VolumetricFog, VolumetricLight}, + pbr::{FogVolume, ShadowsStyle, VolumetricFog, VolumetricLight}, prelude::*, }; @@ -46,10 +46,10 @@ fn setup(mut commands: Commands, asset_server: Res) { commands.spawn(( Transform::from_xyz(1.0, 1.0, -0.3).looking_at(vec3(0.0, 0.5, 0.0), Vec3::Y), DirectionalLight { - shadows_enabled: true, illuminance: 32000.0, ..default() }, + ShadowsStyle::Hard, // Make sure to add this for the light to interact with the fog. VolumetricLight, )); diff --git a/examples/3d/irradiance_volumes.rs b/examples/3d/irradiance_volumes.rs index b3da971e3680c..5bc14fa130551 100644 --- a/examples/3d/irradiance_volumes.rs +++ b/examples/3d/irradiance_volumes.rs @@ -18,7 +18,8 @@ use bevy::{ core_pipeline::Skybox, math::{uvec3, vec3}, pbr::{ - irradiance_volume::IrradianceVolume, ExtendedMaterial, MaterialExtension, NotShadowCaster, + irradiance_volume::IrradianceVolume, ExtendedMaterial, ShadowsStyle, MaterialExtension, + NotShadowCaster, }, prelude::*, render::render_resource::{AsBindGroup, ShaderRef, ShaderType}, @@ -257,9 +258,9 @@ fn spawn_light(commands: &mut Commands) { commands.spawn(( PointLight { intensity: 250000.0, - shadows_enabled: true, ..default() }, + ShadowsStyle::Hard, Transform::from_xyz(4.0762, 5.9039, 1.0055), )); } diff --git a/examples/3d/lighting.rs b/examples/3d/lighting.rs index 0f862b2aa6925..5aa8821a4ffb1 100644 --- a/examples/3d/lighting.rs +++ b/examples/3d/lighting.rs @@ -5,7 +5,7 @@ use std::f32::consts::PI; use bevy::{ color::palettes::css::*, - pbr::CascadeShadowConfigBuilder, + pbr::{CascadeShadowConfigBuilder, ShadowsStyle}, prelude::*, render::camera::{Exposure, PhysicalCameraParameters}, }; @@ -122,9 +122,9 @@ fn setup( PointLight { intensity: 100_000.0, color: RED.into(), - shadows_enabled: true, ..default() }, + ShadowsStyle::Hard, Transform::from_xyz(1.0, 2.0, 0.0), )) .with_children(|builder| { @@ -144,11 +144,11 @@ fn setup( SpotLight { intensity: 100_000.0, color: LIME.into(), - shadows_enabled: true, inner_angle: 0.6, outer_angle: 0.8, ..default() }, + ShadowsStyle::Hard, Transform::from_xyz(-1.0, 2.0, 0.0).looking_at(Vec3::new(-1.0, 0.0, 0.0), Vec3::Z), )) .with_child(( @@ -167,9 +167,9 @@ fn setup( PointLight { intensity: 100_000.0, color: BLUE.into(), - shadows_enabled: true, ..default() }, + ShadowsStyle::Hard, Transform::from_xyz(0.0, 4.0, 0.0), )) .with_children(|builder| { @@ -187,9 +187,9 @@ fn setup( commands.spawn(( DirectionalLight { illuminance: light_consts::lux::OVERCAST_DAY, - shadows_enabled: true, ..default() }, + ShadowsStyle::Hard, Transform { translation: Vec3::new(0.0, 2.0, 0.0), rotation: Quat::from_rotation_x(-PI / 4.), diff --git a/examples/3d/load_gltf.rs b/examples/3d/load_gltf.rs index ac82e24f09fc0..bd46ed77d2f8b 100644 --- a/examples/3d/load_gltf.rs +++ b/examples/3d/load_gltf.rs @@ -1,7 +1,7 @@ //! Loads and renders a glTF file as a scene. use bevy::{ - pbr::{CascadeShadowConfigBuilder, DirectionalLightShadowMap}, + pbr::{CascadeShadowConfigBuilder, DirectionalLightShadowMap, ShadowsStyle}, prelude::*, }; use std::f32::consts::*; @@ -28,10 +28,8 @@ fn setup(mut commands: Commands, asset_server: Res) { )); commands.spawn(( - DirectionalLight { - shadows_enabled: true, - ..default() - }, + DirectionalLight::default(), + ShadowsStyle::Hard, // This is a relatively small scene, so use tighter shadow // cascade bounds than the default for better quality. // We also adjusted the shadow map to be larger since we're diff --git a/examples/3d/load_gltf_extras.rs b/examples/3d/load_gltf_extras.rs index e787b121ef523..da3b706dfdd77 100644 --- a/examples/3d/load_gltf_extras.rs +++ b/examples/3d/load_gltf_extras.rs @@ -2,6 +2,7 @@ use bevy::{ gltf::{GltfExtras, GltfMaterialExtras, GltfMeshExtras, GltfSceneExtras}, + pbr::ShadowsStyle, prelude::*, }; @@ -22,10 +23,7 @@ fn setup(mut commands: Commands, asset_server: Res) { Transform::from_xyz(2.0, 2.0, 2.0).looking_at(Vec3::ZERO, Vec3::Y), )); - commands.spawn(DirectionalLight { - shadows_enabled: true, - ..default() - }); + commands.spawn((DirectionalLight::default(), ShadowsStyle::Hard)); // a barebones scene containing one of each gltf_extra type commands.spawn(SceneRoot(asset_server.load( diff --git a/examples/3d/meshlet.rs b/examples/3d/meshlet.rs index 60e8791b7ddf3..7386e7807143d 100644 --- a/examples/3d/meshlet.rs +++ b/examples/3d/meshlet.rs @@ -8,7 +8,7 @@ mod camera_controller; use bevy::{ pbr::{ experimental::meshlet::{MeshletMesh3d, MeshletPlugin}, - CascadeShadowConfigBuilder, DirectionalLightShadowMap, + CascadeShadowConfigBuilder, DirectionalLightShadowMap, ShadowsStyle, }, prelude::*, render::render_resource::AsBindGroup, @@ -64,9 +64,9 @@ fn setup( commands.spawn(( DirectionalLight { illuminance: light_consts::lux::FULL_DAYLIGHT, - shadows_enabled: true, ..default() }, + ShadowsStyle::Hard, CascadeShadowConfigBuilder { num_cascades: 1, maximum_distance: 15.0, diff --git a/examples/3d/motion_blur.rs b/examples/3d/motion_blur.rs index 8e1bfea468011..be91c2a051347 100644 --- a/examples/3d/motion_blur.rs +++ b/examples/3d/motion_blur.rs @@ -5,6 +5,7 @@ use bevy::{ core_pipeline::motion_blur::MotionBlur, image::{ImageAddressMode, ImageFilterMode, ImageSampler, ImageSamplerDescriptor}, math::ops, + pbr::ShadowsStyle, prelude::*, }; @@ -67,9 +68,9 @@ fn setup_scene( commands.spawn(( DirectionalLight { illuminance: 3_000.0, - shadows_enabled: true, ..default() }, + ShadowsStyle::Hard, Transform::default().looking_to(Vec3::new(-1.0, -0.7, -1.0), Vec3::X), )); // Sky diff --git a/examples/3d/order_independent_transparency.rs b/examples/3d/order_independent_transparency.rs index 03590eb21b3ca..b55e73b73edca 100644 --- a/examples/3d/order_independent_transparency.rs +++ b/examples/3d/order_independent_transparency.rs @@ -37,10 +37,7 @@ fn setup( // light commands.spawn(( - PointLight { - shadows_enabled: false, - ..default() - }, + PointLight::default(), Transform::from_xyz(4.0, 8.0, 4.0), RenderLayers::layer(1), )); diff --git a/examples/3d/parallax_mapping.rs b/examples/3d/parallax_mapping.rs index 47d83a4e76960..a5e3f0a0cb04e 100644 --- a/examples/3d/parallax_mapping.rs +++ b/examples/3d/parallax_mapping.rs @@ -3,7 +3,7 @@ use std::fmt; -use bevy::{image::ImageLoaderSettings, math::ops, prelude::*}; +use bevy::{image::ImageLoaderSettings, math::ops, pbr::ShadowsStyle, prelude::*}; fn main() { App::new() @@ -221,10 +221,8 @@ fn setup( // light commands .spawn(( - PointLight { - shadows_enabled: true, - ..default() - }, + PointLight::default(), + ShadowsStyle::Hard, Transform::from_xyz(2.0, 1.0, -1.1), )) .with_children(|commands| { diff --git a/examples/3d/pcss.rs b/examples/3d/pcss.rs index 0f96396cb0e9c..1340affd64661 100644 --- a/examples/3d/pcss.rs +++ b/examples/3d/pcss.rs @@ -9,7 +9,7 @@ use bevy::{ Skybox, }, math::vec3, - pbr::{CubemapVisibleEntities, ShadowFilteringMethod, VisibleMeshEntities}, + pbr::{CubemapVisibleEntities, ShadowsStyle, ShadowFilteringMethod, VisibleMeshEntities}, prelude::*, render::{ camera::TemporalJitter, @@ -141,9 +141,9 @@ fn main() { } /// Creates all the objects in the scene. -fn setup(mut commands: Commands, asset_server: Res, app_status: Res) { +fn setup(mut commands: Commands, asset_server: Res) { spawn_camera(&mut commands, &asset_server); - spawn_light(&mut commands, &app_status); + spawn_light(&mut commands); spawn_gltf_scene(&mut commands, &asset_server); spawn_buttons(&mut commands); } @@ -176,13 +176,14 @@ fn spawn_camera(commands: &mut Commands, asset_server: &AssetServer) { } /// Spawns the initial light. -fn spawn_light(commands: &mut Commands, app_status: &AppStatus) { +fn spawn_light(commands: &mut Commands) { // Because this light can become a directional light, point light, or spot // light depending on the settings, we add the union of the components // necessary for this light to behave as all three of those. commands .spawn(( - create_directional_light(app_status), + directional_light(), + ShadowsStyle::Soft, Transform::from_rotation(Quat::from_array([ 0.6539259, -0.34646285, @@ -286,21 +287,26 @@ fn handle_light_type_change( }; app_status.light_type = light_type; + let shadow_style = if app_status.soft_shadows { + ShadowsStyle::Soft + } else { + ShadowsStyle::Hard + }; + for light in lights.iter_mut() { let mut light_commands = commands.entity(light); light_commands - .remove::() - .remove::() - .remove::(); + .remove::<(DirectionalLight, PointLight, SpotLight)>() + .insert(shadow_style); match light_type { LightType::Point => { - light_commands.insert(create_point_light(&app_status)); + light_commands.insert(point_light()); } LightType::Spot => { - light_commands.insert(create_spot_light(&app_status)); + light_commands.insert(spot_light()); } LightType::Directional => { - light_commands.insert(create_directional_light(&app_status)); + light_commands.insert(directional_light()); } } } @@ -342,7 +348,7 @@ fn handle_shadow_filter_change( /// Handles requests from the user to toggle soft shadows on and off. fn handle_pcss_toggle( - mut lights: Query>, + mut lights: Query<&mut ShadowsStyle>, mut events: EventReader>, mut app_status: ResMut, ) { @@ -352,43 +358,34 @@ fn handle_pcss_toggle( }; app_status.soft_shadows = value; + let new_light_shadows = if value { + ShadowsStyle::Soft + } else { + ShadowsStyle::Hard + }; + // Recreating the lights is the simplest way to toggle soft shadows. - for (directional_light, point_light, spot_light) in lights.iter_mut() { - if let Some(mut directional_light) = directional_light { - *directional_light = create_directional_light(&app_status); - } - if let Some(mut point_light) = point_light { - *point_light = create_point_light(&app_status); - } - if let Some(mut spot_light) = spot_light { - *spot_light = create_spot_light(&app_status); - } + for mut light_shadows in &mut lights { + *light_shadows = new_light_shadows; } } } /// Creates the [`DirectionalLight`] component with the appropriate settings. -fn create_directional_light(app_status: &AppStatus) -> DirectionalLight { +fn directional_light() -> DirectionalLight { DirectionalLight { - shadows_enabled: true, - soft_shadow_size: if app_status.soft_shadows { - Some(LIGHT_RADIUS) - } else { - None - }, shadow_depth_bias: DIRECTIONAL_SHADOW_DEPTH_BIAS, + angular_size: PI * 0.1, ..default() } } /// Creates the [`PointLight`] component with the appropriate settings. -fn create_point_light(app_status: &AppStatus) -> PointLight { +fn point_light() -> PointLight { PointLight { intensity: POINT_LIGHT_INTENSITY, range: POINT_LIGHT_RANGE, - shadows_enabled: true, radius: LIGHT_RADIUS, - soft_shadows_enabled: app_status.soft_shadows, shadow_depth_bias: POINT_SHADOW_DEPTH_BIAS, shadow_map_near_z: SHADOW_MAP_NEAR_Z, ..default() @@ -396,13 +393,11 @@ fn create_point_light(app_status: &AppStatus) -> PointLight { } /// Creates the [`SpotLight`] component with the appropriate settings. -fn create_spot_light(app_status: &AppStatus) -> SpotLight { +fn spot_light() -> SpotLight { SpotLight { intensity: POINT_LIGHT_INTENSITY, range: POINT_LIGHT_RANGE, radius: LIGHT_RADIUS, - shadows_enabled: true, - soft_shadows_enabled: app_status.soft_shadows, shadow_depth_bias: DIRECTIONAL_SHADOW_DEPTH_BIAS, shadow_map_near_z: SHADOW_MAP_NEAR_Z, ..default() diff --git a/examples/3d/post_processing.rs b/examples/3d/post_processing.rs index 54a9e9089f163..b9fe3f3e65ee7 100644 --- a/examples/3d/post_processing.rs +++ b/examples/3d/post_processing.rs @@ -5,7 +5,9 @@ use std::f32::consts::PI; use bevy::{ - core_pipeline::post_process::ChromaticAberration, pbr::CascadeShadowConfigBuilder, prelude::*, + core_pipeline::post_process::ChromaticAberration, + pbr::{CascadeShadowConfigBuilder, ShadowsStyle}, + prelude::*, }; /// The number of units per frame to add to or subtract from intensity when the @@ -107,9 +109,9 @@ fn spawn_scene(commands: &mut Commands, asset_server: &AssetServer) { commands.spawn(( DirectionalLight { illuminance: 15000.0, - shadows_enabled: true, ..default() }, + ShadowsStyle::Hard, Transform::from_rotation(Quat::from_euler(EulerRot::ZYX, 0.0, PI * -0.15, PI * -0.15)), CascadeShadowConfigBuilder { maximum_distance: 3.0, diff --git a/examples/3d/scrolling_fog.rs b/examples/3d/scrolling_fog.rs index 55118625721fd..4b8e1252fbc24 100644 --- a/examples/3d/scrolling_fog.rs +++ b/examples/3d/scrolling_fog.rs @@ -19,7 +19,7 @@ use bevy::{ ImageAddressMode, ImageFilterMode, ImageLoaderSettings, ImageSampler, ImageSamplerDescriptor, }, - pbr::{DirectionalLightShadowMap, FogVolume, VolumetricFog, VolumetricLight}, + pbr::{DirectionalLightShadowMap, FogVolume, ShadowsStyle, VolumetricFog, VolumetricLight}, prelude::*, }; @@ -67,10 +67,8 @@ fn setup( // Spawn a directional light shining at the camera with the VolumetricLight component. commands.spawn(( - DirectionalLight { - shadows_enabled: true, - ..default() - }, + DirectionalLight::default(), + ShadowsStyle::Hard, Transform::from_xyz(-5.0, 5.0, -7.0).looking_at(Vec3::new(0.0, 0.0, 0.0), Vec3::Y), VolumetricLight, )); diff --git a/examples/3d/shadow_biases.rs b/examples/3d/shadow_biases.rs index 10fe6cffec51d..3b34ca4a11b17 100644 --- a/examples/3d/shadow_biases.rs +++ b/examples/3d/shadow_biases.rs @@ -3,7 +3,10 @@ #[path = "../helpers/camera_controller.rs"] mod camera_controller; -use bevy::{pbr::ShadowFilteringMethod, prelude::*}; +use bevy::{ + pbr::{ShadowsStyle, ShadowFilteringMethod}, + prelude::*, +}; use camera_controller::{CameraController, CameraControllerPlugin}; fn main() { @@ -48,21 +51,25 @@ fn setup( commands .spawn((light_transform, Visibility::default(), Lights)) .with_children(|builder| { - builder.spawn(PointLight { - intensity: 0.0, - range: spawn_plane_depth, - color: Color::WHITE, - shadow_depth_bias: 0.0, - shadow_normal_bias: 0.0, - shadows_enabled: true, - ..default() - }); - builder.spawn(DirectionalLight { - shadow_depth_bias: 0.0, - shadow_normal_bias: 0.0, - shadows_enabled: true, - ..default() - }); + builder.spawn(( + PointLight { + intensity: 0.0, + range: spawn_plane_depth, + color: Color::WHITE, + shadow_depth_bias: 0.0, + shadow_normal_bias: 0.0, + ..default() + }, + ShadowsStyle::Hard, + )); + builder.spawn(( + DirectionalLight { + shadow_depth_bias: 0.0, + shadow_normal_bias: 0.0, + ..default() + }, + ShadowsStyle::Hard, + )); }); // camera diff --git a/examples/3d/shadow_caster_receiver.rs b/examples/3d/shadow_caster_receiver.rs index edc8631aa9abe..96b2973b34758 100644 --- a/examples/3d/shadow_caster_receiver.rs +++ b/examples/3d/shadow_caster_receiver.rs @@ -4,7 +4,7 @@ use std::f32::consts::PI; use bevy::{ color::palettes::basic::{BLUE, LIME, RED}, - pbr::{CascadeShadowConfigBuilder, NotShadowCaster, NotShadowReceiver}, + pbr::{CascadeShadowConfigBuilder, ShadowsStyle, NotShadowCaster, NotShadowReceiver}, prelude::*, }; @@ -76,18 +76,18 @@ fn setup( intensity: 0.0, range: spawn_plane_depth, color: Color::WHITE, - shadows_enabled: true, ..default() }, + ShadowsStyle::Hard, Transform::from_xyz(5.0, 5.0, 0.0), )); commands.spawn(( DirectionalLight { illuminance: light_consts::lux::OVERCAST_DAY, - shadows_enabled: true, ..default() }, + ShadowsStyle::Hard, Transform::from_rotation(Quat::from_euler(EulerRot::ZYX, 0.0, PI / 2., -PI / 4.)), CascadeShadowConfigBuilder { first_cascade_far_bound: 7.0, diff --git a/examples/3d/split_screen.rs b/examples/3d/split_screen.rs index 69f150368e87f..8700dce064397 100644 --- a/examples/3d/split_screen.rs +++ b/examples/3d/split_screen.rs @@ -3,7 +3,10 @@ use std::f32::consts::PI; use bevy::{ - pbr::CascadeShadowConfigBuilder, prelude::*, render::camera::Viewport, window::WindowResized, + pbr::{CascadeShadowConfigBuilder, ShadowsStyle}, + prelude::*, + render::camera::Viewport, + window::WindowResized, }; fn main() { @@ -34,10 +37,8 @@ fn setup( // Light commands.spawn(( Transform::from_rotation(Quat::from_euler(EulerRot::ZYX, 0.0, 1.0, -PI / 4.)), - DirectionalLight { - shadows_enabled: true, - ..default() - }, + DirectionalLight::default(), + ShadowsStyle::Hard, CascadeShadowConfigBuilder { num_cascades: if cfg!(all( feature = "webgl2", diff --git a/examples/3d/spotlight.rs b/examples/3d/spotlight.rs index c92843404ef37..b358e3a6eb2cd 100644 --- a/examples/3d/spotlight.rs +++ b/examples/3d/spotlight.rs @@ -5,7 +5,7 @@ use std::f32::consts::*; use bevy::{ color::palettes::basic::{MAROON, RED}, math::ops, - pbr::NotShadowCaster, + pbr::{ShadowsStyle, NotShadowCaster}, prelude::*, }; use rand::{Rng, SeedableRng}; @@ -93,11 +93,11 @@ fn setup( SpotLight { intensity: 40_000.0, // lumens color: Color::WHITE, - shadows_enabled: true, inner_angle: PI / 4.0 * 0.85, outer_angle: PI / 4.0, ..default() }, + ShadowsStyle::Hard, Transform::from_xyz(1.0 + x, 2.0, z) .looking_at(Vec3::new(1.0 + x, 0.0, z), Vec3::X), )) diff --git a/examples/3d/ssao.rs b/examples/3d/ssao.rs index 17c54db633a8d..88bcfcd73dc0b 100644 --- a/examples/3d/ssao.rs +++ b/examples/3d/ssao.rs @@ -3,7 +3,7 @@ use bevy::{ core_pipeline::experimental::taa::{TemporalAntiAliasPlugin, TemporalAntiAliasing}, math::ops, - pbr::{ScreenSpaceAmbientOcclusion, ScreenSpaceAmbientOcclusionQualityLevel}, + pbr::{ShadowsStyle, ScreenSpaceAmbientOcclusion, ScreenSpaceAmbientOcclusionQualityLevel}, prelude::*, render::camera::TemporalJitter, }; @@ -71,10 +71,8 @@ fn setup( )); commands.spawn(( - DirectionalLight { - shadows_enabled: true, - ..default() - }, + DirectionalLight::default(), + ShadowsStyle::Hard, Transform::from_rotation(Quat::from_euler(EulerRot::ZYX, 0.0, PI * -0.15, PI * -0.15)), )); diff --git a/examples/3d/tonemapping.rs b/examples/3d/tonemapping.rs index f802154cb390e..bbf2979e1e729 100644 --- a/examples/3d/tonemapping.rs +++ b/examples/3d/tonemapping.rs @@ -2,7 +2,7 @@ use bevy::{ core_pipeline::tonemapping::Tonemapping, - pbr::CascadeShadowConfigBuilder, + pbr::{CascadeShadowConfigBuilder, ShadowsStyle}, prelude::*, reflect::TypePath, render::{ @@ -115,9 +115,9 @@ fn setup_basic_scene(mut commands: Commands, asset_server: Res) { commands.spawn(( DirectionalLight { illuminance: 15_000., - shadows_enabled: true, ..default() }, + ShadowsStyle::Hard, Transform::from_rotation(Quat::from_euler(EulerRot::ZYX, 0.0, PI * -0.15, PI * -0.15)), CascadeShadowConfigBuilder { maximum_distance: 3.0, diff --git a/examples/3d/transmission.rs b/examples/3d/transmission.rs index b6a6425baf495..e1201246f9923 100644 --- a/examples/3d/transmission.rs +++ b/examples/3d/transmission.rs @@ -27,7 +27,7 @@ use bevy::{ tonemapping::Tonemapping, }, math::ops, - pbr::{NotShadowCaster, PointLightShadowMap, TransmittedShadowReceiver}, + pbr::{ShadowsStyle, NotShadowCaster, PointLightShadowMap, TransmittedShadowReceiver}, prelude::*, render::{ camera::{Exposure, TemporalJitter}, @@ -294,9 +294,9 @@ fn setup( intensity: 4_000.0, radius: 0.2, range: 5.0, - shadows_enabled: true, ..default() }, + ShadowsStyle::Hard, Flicker, )); diff --git a/examples/3d/transparency_3d.rs b/examples/3d/transparency_3d.rs index 35cb7c1d14f25..7879657252804 100644 --- a/examples/3d/transparency_3d.rs +++ b/examples/3d/transparency_3d.rs @@ -2,7 +2,7 @@ //! Shows the effects of different blend modes. //! The `fade_transparency` system smoothly changes the transparency over time. -use bevy::{math::ops, prelude::*}; +use bevy::{math::ops, pbr::ShadowsStyle, prelude::*}; fn main() { App::new() @@ -82,10 +82,8 @@ fn setup( // Light commands.spawn(( - PointLight { - shadows_enabled: true, - ..default() - }, + PointLight::default(), + ShadowsStyle::Hard, Transform::from_xyz(4.0, 8.0, 4.0), )); diff --git a/examples/3d/two_passes.rs b/examples/3d/two_passes.rs index f80125472e7b0..8f6e53c17f1cb 100644 --- a/examples/3d/two_passes.rs +++ b/examples/3d/two_passes.rs @@ -1,6 +1,6 @@ //! Renders two 3d passes to the same window from different perspectives. -use bevy::prelude::*; +use bevy::{pbr::ShadowsStyle, prelude::*}; fn main() { App::new() @@ -30,10 +30,8 @@ fn setup( // Light commands.spawn(( - PointLight { - shadows_enabled: true, - ..default() - }, + PointLight::default(), + ShadowsStyle::Hard, Transform::from_xyz(4.0, 8.0, 4.0), )); diff --git a/examples/3d/update_gltf_scene.rs b/examples/3d/update_gltf_scene.rs index 651fc038761fd..949719f1b25c8 100644 --- a/examples/3d/update_gltf_scene.rs +++ b/examples/3d/update_gltf_scene.rs @@ -1,7 +1,10 @@ //! Update a scene from a glTF file, either by spawning the scene as a child of another entity, //! or by accessing the entities of the scene. -use bevy::{pbr::DirectionalLightShadowMap, prelude::*}; +use bevy::{ + pbr::{DirectionalLightShadowMap, ShadowsStyle}, + prelude::*, +}; fn main() { App::new() @@ -18,10 +21,8 @@ struct MovedScene; fn setup(mut commands: Commands, asset_server: Res) { commands.spawn(( Transform::from_xyz(4.0, 25.0, 8.0).looking_at(Vec3::ZERO, Vec3::Y), - DirectionalLight { - shadows_enabled: true, - ..default() - }, + DirectionalLight::default(), + ShadowsStyle::Hard, )); commands.spawn(( Camera3d::default(), diff --git a/examples/3d/vertex_colors.rs b/examples/3d/vertex_colors.rs index 90eb67abd7ce3..41624e81ee65f 100644 --- a/examples/3d/vertex_colors.rs +++ b/examples/3d/vertex_colors.rs @@ -1,6 +1,6 @@ //! Illustrates the use of vertex colors. -use bevy::{prelude::*, render::mesh::VertexAttributeValues}; +use bevy::{pbr::ShadowsStyle, prelude::*, render::mesh::VertexAttributeValues}; fn main() { App::new() @@ -43,10 +43,8 @@ fn setup( // Light commands.spawn(( - PointLight { - shadows_enabled: true, - ..default() - }, + PointLight::default(), + ShadowsStyle::Hard, Transform::from_xyz(4.0, 5.0, 4.0).looking_at(Vec3::ZERO, Vec3::Y), )); diff --git a/examples/3d/visibility_range.rs b/examples/3d/visibility_range.rs index 17bc26439b189..51b913b0413ac 100644 --- a/examples/3d/visibility_range.rs +++ b/examples/3d/visibility_range.rs @@ -6,7 +6,7 @@ use bevy::{ core_pipeline::prepass::{DepthPrepass, NormalPrepass}, input::mouse::MouseWheel, math::vec3, - pbr::{light_consts::lux::FULL_DAYLIGHT, CascadeShadowConfigBuilder}, + pbr::{light_consts::lux::FULL_DAYLIGHT, CascadeShadowConfigBuilder, ShadowsStyle}, prelude::*, render::view::VisibilityRange, }; @@ -131,9 +131,9 @@ fn setup( commands.spawn(( DirectionalLight { illuminance: FULL_DAYLIGHT, - shadows_enabled: true, ..default() }, + ShadowsStyle::Hard, Transform::from_rotation(Quat::from_euler(EulerRot::ZYX, 0.0, PI * -0.15, PI * -0.15)), CascadeShadowConfigBuilder { maximum_distance: 30.0, diff --git a/examples/3d/volumetric_fog.rs b/examples/3d/volumetric_fog.rs index 9cfef624c6594..450cfbeb02cf6 100644 --- a/examples/3d/volumetric_fog.rs +++ b/examples/3d/volumetric_fog.rs @@ -4,7 +4,7 @@ use bevy::{ color::palettes::css::RED, core_pipeline::{bloom::Bloom, tonemapping::Tonemapping, Skybox}, math::vec3, - pbr::{FogVolume, VolumetricFog, VolumetricLight}, + pbr::{FogVolume, ShadowsStyle, VolumetricFog, VolumetricLight}, prelude::*, }; @@ -88,12 +88,12 @@ fn setup(mut commands: Commands, asset_server: Res, app_settings: R commands.spawn(( Transform::from_xyz(-0.4, 1.9, 1.0), PointLight { - shadows_enabled: true, range: 150.0, color: RED.into(), intensity: 1000.0, ..default() }, + ShadowsStyle::Hard, VolumetricLight, MoveBackAndForthHorizontally { min_x: -1.93, @@ -108,11 +108,11 @@ fn setup(mut commands: Commands, asset_server: Res, app_settings: R SpotLight { intensity: 5000.0, // lumens color: Color::WHITE, - shadows_enabled: true, inner_angle: 0.76, outer_angle: 0.94, ..default() }, + ShadowsStyle::Hard, VolumetricLight, )); @@ -156,11 +156,11 @@ fn create_text(app_settings: &AppSettings) -> Text { /// lights with shadows. fn tweak_scene( mut commands: Commands, - mut lights: Query<(Entity, &mut DirectionalLight), Changed>, + mut lights: Query<(Entity, &mut ShadowsStyle), Changed>, ) { - for (light, mut directional_light) in lights.iter_mut() { + for (light, mut directional_light_shadows) in lights.iter_mut() { // Shadows are needed for volumetric lights to work. - directional_light.shadows_enabled = true; + *directional_light_shadows = ShadowsStyle::Hard; commands.entity(light).insert(VolumetricLight); } } diff --git a/examples/animation/animated_fox.rs b/examples/animation/animated_fox.rs index 537e83a3bc87e..61a327b1b066a 100644 --- a/examples/animation/animated_fox.rs +++ b/examples/animation/animated_fox.rs @@ -5,7 +5,7 @@ use std::{f32::consts::PI, time::Duration}; use bevy::{ animation::{AnimationTargetId, RepeatAnimation}, color::palettes::css::WHITE, - pbr::CascadeShadowConfigBuilder, + pbr::{CascadeShadowConfigBuilder, ShadowsStyle}, prelude::*, }; use rand::{Rng, SeedableRng}; @@ -99,19 +99,18 @@ fn setup( )); // Light - commands.spawn(( + let bundle = ( Transform::from_rotation(Quat::from_euler(EulerRot::ZYX, 0.0, 1.0, -PI / 4.)), - DirectionalLight { - shadows_enabled: true, - ..default() - }, + DirectionalLight::default(), + ShadowsStyle::Hard, CascadeShadowConfigBuilder { first_cascade_far_bound: 200.0, maximum_distance: 400.0, ..default() } .build(), - )); + ); + commands.spawn(bundle); // Fox commands.spawn(SceneRoot( diff --git a/examples/animation/animation_graph.rs b/examples/animation/animation_graph.rs index 8238bfd116c5c..275067557f876 100644 --- a/examples/animation/animation_graph.rs +++ b/examples/animation/animation_graph.rs @@ -8,6 +8,7 @@ use bevy::{ basic::WHITE, css::{ANTIQUE_WHITE, DARK_GREEN}, }, + pbr::ShadowsStyle, prelude::*, ui::RelativeCursorPosition, }; @@ -225,9 +226,9 @@ fn setup_scene( commands.spawn(( PointLight { intensity: 10_000_000.0, - shadows_enabled: true, ..default() }, + ShadowsStyle::Hard, Transform::from_xyz(-4.0, 8.0, 13.0), )); diff --git a/examples/animation/animation_masks.rs b/examples/animation/animation_masks.rs index 734b4c1c06346..793da28402ee5 100644 --- a/examples/animation/animation_masks.rs +++ b/examples/animation/animation_masks.rs @@ -3,6 +3,7 @@ use bevy::{ animation::{AnimationTarget, AnimationTargetId}, color::palettes::css::{LIGHT_GRAY, WHITE}, + pbr::ShadowsStyle, prelude::*, utils::hashbrown::HashSet, }; @@ -131,9 +132,9 @@ fn setup_scene( commands.spawn(( PointLight { intensity: 10_000_000.0, - shadows_enabled: true, ..default() }, + ShadowsStyle::Hard, Transform::from_xyz(-4.0, 8.0, 13.0), )); diff --git a/examples/animation/eased_motion.rs b/examples/animation/eased_motion.rs index f6254cd65de35..457ae58de8873 100644 --- a/examples/animation/eased_motion.rs +++ b/examples/animation/eased_motion.rs @@ -6,6 +6,7 @@ use bevy::{ animation::{animated_field, AnimationTarget, AnimationTargetId}, color::palettes::css::{ORANGE, SILVER}, math::vec3, + pbr::ShadowsStyle, prelude::*, }; @@ -55,11 +56,11 @@ fn setup( // Some light to see something commands.spawn(( PointLight { - shadows_enabled: true, intensity: 10_000_000., range: 100.0, ..default() }, + ShadowsStyle::Hard, Transform::from_xyz(8., 16., 8.), )); diff --git a/examples/app/headless_renderer.rs b/examples/app/headless_renderer.rs index 8fe2ef5871acf..90b6eb8555be6 100644 --- a/examples/app/headless_renderer.rs +++ b/examples/app/headless_renderer.rs @@ -11,6 +11,7 @@ use bevy::{ app::{AppExit, ScheduleRunnerPlugin}, core_pipeline::tonemapping::Tonemapping, image::TextureFormatPixelInfo, + pbr::ShadowsStyle, prelude::*, render::{ camera::RenderTarget, @@ -178,10 +179,8 @@ fn setup( )); // light commands.spawn(( - PointLight { - shadows_enabled: true, - ..default() - }, + PointLight::default(), + ShadowsStyle::Hard, Transform::from_xyz(4.0, 8.0, 4.0), )); diff --git a/examples/asset/multi_asset_sync.rs b/examples/asset/multi_asset_sync.rs index 2e21f8fe32df3..c69b78d63017d 100644 --- a/examples/asset/multi_asset_sync.rs +++ b/examples/asset/multi_asset_sync.rs @@ -9,7 +9,7 @@ use std::{ }, }; -use bevy::{gltf::Gltf, prelude::*, tasks::AsyncComputeTaskPool}; +use bevy::{gltf::Gltf, pbr::ShadowsStyle, prelude::*, tasks::AsyncComputeTaskPool}; use event_listener::Event; use futures_lite::Future; @@ -194,10 +194,8 @@ fn setup_scene( // Light commands.spawn(( - DirectionalLight { - shadows_enabled: true, - ..default() - }, + DirectionalLight::default(), + ShadowsStyle::Hard, Transform::from_rotation(Quat::from_euler(EulerRot::ZYX, 0.0, 1.0, -PI / 4.)), )); diff --git a/examples/asset/repeated_texture.rs b/examples/asset/repeated_texture.rs index 34664a9e42b5c..4be6423045bb8 100644 --- a/examples/asset/repeated_texture.rs +++ b/examples/asset/repeated_texture.rs @@ -4,6 +4,7 @@ use bevy::{ image::{ImageAddressMode, ImageLoaderSettings, ImageSampler, ImageSamplerDescriptor}, math::Affine2, + pbr::ShadowsStyle, prelude::*, }; @@ -79,10 +80,8 @@ fn setup( // light commands.spawn(( - PointLight { - shadows_enabled: true, - ..default() - }, + PointLight::default(), + ShadowsStyle::Hard, Transform::from_xyz(4.0, 8.0, 4.0), )); // camera diff --git a/examples/camera/first_person_view_model.rs b/examples/camera/first_person_view_model.rs index 78168eac5ddbf..5ea961edeeb8d 100644 --- a/examples/camera/first_person_view_model.rs +++ b/examples/camera/first_person_view_model.rs @@ -45,8 +45,11 @@ use std::f32::consts::FRAC_PI_2; use bevy::{ - color::palettes::tailwind, input::mouse::AccumulatedMouseMotion, pbr::NotShadowCaster, - prelude::*, render::view::RenderLayers, + color::palettes::tailwind, + input::mouse::AccumulatedMouseMotion, + pbr::{ShadowsStyle, NotShadowCaster}, + prelude::*, + render::view::RenderLayers, }; fn main() { @@ -181,9 +184,9 @@ fn spawn_lights(mut commands: Commands) { commands.spawn(( PointLight { color: Color::from(tailwind::ROSE_300), - shadows_enabled: true, ..default() }, + ShadowsStyle::Hard, Transform::from_xyz(-2.0, 4.0, -0.75), // The light source illuminates both the world model and the view model. RenderLayers::from_layers(&[DEFAULT_RENDER_LAYER, VIEW_MODEL_RENDER_LAYER]), diff --git a/examples/ecs/fallible_systems.rs b/examples/ecs/fallible_systems.rs index 740976dadfa6b..9170ae6bb71e5 100644 --- a/examples/ecs/fallible_systems.rs +++ b/examples/ecs/fallible_systems.rs @@ -1,6 +1,7 @@ //! Showcases how fallible systems can be make use of rust's powerful result handling syntax. use bevy::math::sampling::UniformMeshSampler; +use bevy::pbr::ShadowsStyle; use bevy::prelude::*; use rand::distributions::Distribution; @@ -29,10 +30,8 @@ fn setup( // Spawn a light: commands.spawn(( - PointLight { - shadows_enabled: true, - ..default() - }, + PointLight::default(), + ShadowsStyle::Hard, Transform::from_xyz(4.0, 8.0, 4.0), )); diff --git a/examples/games/alien_cake_addict.rs b/examples/games/alien_cake_addict.rs index c8a91ab5fd0cf..95eae14ae9297 100644 --- a/examples/games/alien_cake_addict.rs +++ b/examples/games/alien_cake_addict.rs @@ -2,7 +2,7 @@ use std::f32::consts::PI; -use bevy::prelude::*; +use bevy::{pbr::ShadowsStyle, prelude::*}; use rand::{Rng, SeedableRng}; use rand_chacha::ChaCha8Rng; @@ -124,10 +124,10 @@ fn setup(mut commands: Commands, asset_server: Res, mut game: ResMu StateScoped(GameState::Playing), PointLight { intensity: 2_000_000.0, - shadows_enabled: true, range: 30.0, ..default() }, + ShadowsStyle::Hard, Transform::from_xyz(4.0, 10.0, 4.0), )); diff --git a/examples/games/loading_screen.rs b/examples/games/loading_screen.rs index a24043c1b46d4..363ea465d14f6 100644 --- a/examples/games/loading_screen.rs +++ b/examples/games/loading_screen.rs @@ -1,5 +1,5 @@ //! Shows how to create a loading screen that waits for assets to load and render. -use bevy::{ecs::system::SystemId, prelude::*}; +use bevy::{ecs::system::SystemId, pbr::ShadowsStyle, prelude::*}; use pipelines_ready::*; // The way we'll go about doing this in this example is to @@ -152,10 +152,8 @@ fn load_level_1( // Spawn the light. commands.spawn(( - DirectionalLight { - shadows_enabled: true, - ..default() - }, + DirectionalLight::default(), + ShadowsStyle::Hard, Transform::from_xyz(3.0, 3.0, 2.0).looking_at(Vec3::ZERO, Vec3::Y), LevelComponents, )); @@ -183,10 +181,8 @@ fn load_level_2( // Spawn the light. commands.spawn(( - DirectionalLight { - shadows_enabled: true, - ..default() - }, + DirectionalLight::default(), + ShadowsStyle::Hard, Transform::from_xyz(3.0, 3.0, 2.0).looking_at(Vec3::ZERO, Vec3::Y), LevelComponents, )); diff --git a/examples/gizmos/3d_gizmos.rs b/examples/gizmos/3d_gizmos.rs index 1a34717bf3698..f539a716da535 100644 --- a/examples/gizmos/3d_gizmos.rs +++ b/examples/gizmos/3d_gizmos.rs @@ -3,7 +3,7 @@ #[path = "../helpers/camera_controller.rs"] mod camera_controller; -use bevy::{color::palettes::css::*, prelude::*}; +use bevy::{color::palettes::css::*, pbr::ShadowsStyle, prelude::*}; use camera_controller::{CameraController, CameraControllerPlugin}; use std::f32::consts::PI; @@ -67,10 +67,8 @@ fn setup( )); // light commands.spawn(( - PointLight { - shadows_enabled: true, - ..default() - }, + PointLight::default(), + ShadowsStyle::Hard, Transform::from_xyz(4.0, 8.0, 4.0), )); diff --git a/examples/gizmos/axes.rs b/examples/gizmos/axes.rs index 1ecfa340bace8..bec4b720ca830 100644 --- a/examples/gizmos/axes.rs +++ b/examples/gizmos/axes.rs @@ -1,6 +1,6 @@ //! This example demonstrates the implementation and behavior of the axes gizmo. -use bevy::{prelude::*, render::primitives::Aabb}; +use bevy::{pbr::ShadowsStyle, prelude::*, render::primitives::Aabb}; use rand::{Rng, SeedableRng}; use rand_chacha::ChaCha8Rng; use std::f32::consts::PI; @@ -48,10 +48,8 @@ fn setup( // Lights... commands.spawn(( - PointLight { - shadows_enabled: true, - ..default() - }, + PointLight::default(), + ShadowsStyle::Hard, Transform::from_xyz(2., 6., 0.), )); diff --git a/examples/gizmos/light_gizmos.rs b/examples/gizmos/light_gizmos.rs index c21b4b94e66e7..d8efc5e4a9407 100644 --- a/examples/gizmos/light_gizmos.rs +++ b/examples/gizmos/light_gizmos.rs @@ -4,6 +4,7 @@ use std::f32::consts::{FRAC_PI_2, PI}; use bevy::{ color::palettes::css::{DARK_CYAN, GOLD, GRAY, PURPLE}, + pbr::ShadowsStyle, prelude::*, }; @@ -65,31 +66,31 @@ fn setup( { commands.spawn(( PointLight { - shadows_enabled: true, range: 2.0, color: DARK_CYAN.into(), ..default() }, + ShadowsStyle::Hard, Transform::from_xyz(0.0, 1.5, 0.0), )); commands.spawn(( SpotLight { - shadows_enabled: true, range: 3.5, color: PURPLE.into(), outer_angle: PI / 4.0, inner_angle: PI / 4.0 * 0.8, ..default() }, + ShadowsStyle::Hard, Transform::from_xyz(4.0, 2.0, 0.0).looking_at(Vec3::X * 1.5, Vec3::Y), )); commands.spawn(( DirectionalLight { color: GOLD.into(), illuminance: DirectionalLight::default().illuminance * 0.05, - shadows_enabled: true, ..default() }, + ShadowsStyle::Hard, Transform::from_xyz(-4.0, 2.0, 0.0).looking_at(Vec3::NEG_X * 1.5, Vec3::Y), )); } diff --git a/examples/math/custom_primitives.rs b/examples/math/custom_primitives.rs index a072b4476412c..9d4b05cdf5229 100644 --- a/examples/math/custom_primitives.rs +++ b/examples/math/custom_primitives.rs @@ -12,6 +12,7 @@ use bevy::{ }, Isometry2d, }, + pbr::ShadowsStyle, prelude::*, render::{ camera::ScalingMode, @@ -147,12 +148,12 @@ fn setup( // Point light for 3D commands.spawn(( PointLight { - shadows_enabled: true, intensity: 10_000_000., range: 100.0, shadow_depth_bias: 0.2, ..default() }, + ShadowsStyle::Hard, Transform::from_xyz(8.0, 12.0, 1.0), )); diff --git a/examples/math/random_sampling.rs b/examples/math/random_sampling.rs index 710678e208ede..fb387f065840a 100644 --- a/examples/math/random_sampling.rs +++ b/examples/math/random_sampling.rs @@ -3,6 +3,7 @@ use bevy::{ input::mouse::{AccumulatedMouseMotion, MouseButtonInput}, math::prelude::*, + pbr::ShadowsStyle, prelude::*, render::mesh::SphereKind, }; @@ -81,10 +82,8 @@ fn setup( // A light: commands.spawn(( - PointLight { - shadows_enabled: true, - ..default() - }, + PointLight::default(), + ShadowsStyle::Hard, Transform::from_xyz(4.0, 8.0, 4.0), )); diff --git a/examples/math/sampling_primitives.rs b/examples/math/sampling_primitives.rs index e200486fbfd6b..b5cc5ef7cde33 100644 --- a/examples/math/sampling_primitives.rs +++ b/examples/math/sampling_primitives.rs @@ -316,7 +316,6 @@ fn setup( range: 4.0, radius: 0.6, intensity: 1.0, - shadows_enabled: false, color: Color::LinearRgba(INSIDE_POINT_COLOR), ..default() }, @@ -330,7 +329,6 @@ fn setup( PointLight { color: SKY_COLOR, intensity: 2_000.0, - shadows_enabled: false, ..default() }, Transform::from_xyz(4.0, 8.0, 4.0), diff --git a/examples/mobile/src/lib.rs b/examples/mobile/src/lib.rs index ee49c01c58a25..be94c687dacbc 100644 --- a/examples/mobile/src/lib.rs +++ b/examples/mobile/src/lib.rs @@ -4,6 +4,7 @@ use bevy::{ color::palettes::basic::*, input::{gestures::RotationGesture, touch::TouchPhase}, log::{Level, LogPlugin}, + pbr::ShadowsStyle, prelude::*, window::{AppLifecycle, WindowMode}, winit::WinitSettings, @@ -97,17 +98,18 @@ fn setup_scene( Transform::from_xyz(1.5, 1.5, 1.5), )); // light - commands.spawn(( - PointLight { - intensity: 1_000_000.0, - // Shadows makes some Android devices segfault, this is under investigation - // https://github.com/bevyengine/bevy/issues/8214 - #[cfg(not(target_os = "android"))] - shadows_enabled: true, - ..default() - }, - Transform::from_xyz(4.0, 8.0, 4.0), - )); + commands + .spawn(( + PointLight { + intensity: 1_000_000.0, + ..default() + }, + Transform::from_xyz(4.0, 8.0, 4.0), + )) + // Shadows makes some Android devices segfault, this is under investigation + // https://github.com/bevyengine/bevy/issues/8214 + .insert_if(ShadowsStyle::Hard, || cfg!(not(target_os = "android"))); + // camera commands.spawn(( Camera3d::default(), diff --git a/examples/movement/smooth_follow.rs b/examples/movement/smooth_follow.rs index ccf31e7cf66ee..84ce9733823cd 100644 --- a/examples/movement/smooth_follow.rs +++ b/examples/movement/smooth_follow.rs @@ -2,6 +2,7 @@ use bevy::{ math::{prelude::*, vec3, NormedVectorSpace}, + pbr::ShadowsStyle, prelude::*, }; use rand::SeedableRng; @@ -70,9 +71,9 @@ fn setup( commands.spawn(( PointLight { intensity: 15_000_000.0, - shadows_enabled: true, ..default() }, + ShadowsStyle::Hard, Transform::from_xyz(4.0, 8.0, 4.0), )); diff --git a/examples/picking/mesh_picking.rs b/examples/picking/mesh_picking.rs index 40ba4806b30fc..33ee3c5986f5d 100644 --- a/examples/picking/mesh_picking.rs +++ b/examples/picking/mesh_picking.rs @@ -21,7 +21,10 @@ use std::f32::consts::PI; -use bevy::{color::palettes::tailwind::*, picking::pointer::PointerInteraction, prelude::*}; +use bevy::{ + color::palettes::tailwind::*, pbr::ShadowsStyle, picking::pointer::PointerInteraction, + prelude::*, +}; fn main() { App::new() @@ -129,12 +132,12 @@ fn setup_scene( // Light commands.spawn(( PointLight { - shadows_enabled: true, intensity: 10_000_000., range: 100.0, shadow_depth_bias: 0.2, ..default() }, + ShadowsStyle::Hard, Transform::from_xyz(8.0, 16.0, 8.0), )); diff --git a/examples/picking/simple_picking.rs b/examples/picking/simple_picking.rs index c3da9bfa85db1..9c9cc7dd1f3ca 100644 --- a/examples/picking/simple_picking.rs +++ b/examples/picking/simple_picking.rs @@ -1,6 +1,6 @@ //! A simple scene to demonstrate picking events for UI and mesh entities. -use bevy::prelude::*; +use bevy::{pbr::ShadowsStyle, prelude::*}; fn main() { App::new() @@ -48,10 +48,8 @@ fn setup_scene( // Light commands.spawn(( - PointLight { - shadows_enabled: true, - ..default() - }, + PointLight::default(), + ShadowsStyle::Hard, Transform::from_xyz(4.0, 8.0, 4.0), )); diff --git a/examples/remote/server.rs b/examples/remote/server.rs index 39033218a7379..b1a013330e538 100644 --- a/examples/remote/server.rs +++ b/examples/remote/server.rs @@ -1,6 +1,7 @@ //! A Bevy app that you can connect to with the BRP and edit. use bevy::math::ops::cos; +use bevy::pbr::ShadowsStyle; use bevy::{ input::common_conditions::input_just_pressed, prelude::*, @@ -42,10 +43,8 @@ fn setup( // light commands.spawn(( - PointLight { - shadows_enabled: true, - ..default() - }, + PointLight::default(), + ShadowsStyle::Hard, Transform::from_xyz(4.0, 8.0, 4.0), )); diff --git a/examples/shader/automatic_instancing.rs b/examples/shader/automatic_instancing.rs index d3cd7c45ccfb6..c03490d3f6c5f 100644 --- a/examples/shader/automatic_instancing.rs +++ b/examples/shader/automatic_instancing.rs @@ -1,7 +1,7 @@ //! Shows that multiple instances of a cube are automatically instanced in one draw call //! Try running this example in a graphics profiler and all the cubes should be only a single draw call. -use bevy::prelude::*; +use bevy::{pbr::ShadowsStyle, prelude::*}; fn main() { App::new() @@ -23,10 +23,8 @@ fn setup( )); // light commands.spawn(( - PointLight { - shadows_enabled: true, - ..default() - }, + PointLight::default(), + ShadowsStyle::Hard, Transform::from_xyz(0.0, 16.0, 8.0), )); diff --git a/examples/shader/shader_prepass.rs b/examples/shader/shader_prepass.rs index b53f9fe941729..dc96cc49d8d77 100644 --- a/examples/shader/shader_prepass.rs +++ b/examples/shader/shader_prepass.rs @@ -4,7 +4,7 @@ use bevy::{ core_pipeline::prepass::{DepthPrepass, MotionVectorPrepass, NormalPrepass}, - pbr::{NotShadowCaster, PbrPlugin}, + pbr::{ShadowsStyle, NotShadowCaster, PbrPlugin}, prelude::*, reflect::TypePath, render::render_resource::{AsBindGroup, ShaderRef, ShaderType}, @@ -116,10 +116,8 @@ fn setup( // light commands.spawn(( - PointLight { - shadows_enabled: true, - ..default() - }, + PointLight::default(), + ShadowsStyle::Hard, Transform::from_xyz(4.0, 8.0, 4.0), )); diff --git a/examples/stress_tests/many_cameras_lights.rs b/examples/stress_tests/many_cameras_lights.rs index 4d527faec3e58..5a038a198f605 100644 --- a/examples/stress_tests/many_cameras_lights.rs +++ b/examples/stress_tests/many_cameras_lights.rs @@ -4,6 +4,7 @@ use std::f32::consts::PI; use bevy::{ math::ops::{cos, sin}, + pbr::ShadowsStyle, prelude::*, render::camera::Viewport, }; @@ -48,9 +49,9 @@ fn setup( PointLight { color: Color::hsv(angle.to_degrees(), 1.0, 1.0), intensity: 2_000_000.0 / NUM_LIGHTS as f32, - shadows_enabled: true, ..default() }, + ShadowsStyle::Hard, Transform::from_xyz(sin(angle) * 4.0, 2.0, cos(angle) * 4.0), )); } diff --git a/examples/stress_tests/many_cubes.rs b/examples/stress_tests/many_cubes.rs index 2853bd5fa0fe0..21cb2ccfc6962 100644 --- a/examples/stress_tests/many_cubes.rs +++ b/examples/stress_tests/many_cubes.rs @@ -14,7 +14,7 @@ use argh::FromArgs; use bevy::{ diagnostic::{FrameTimeDiagnosticsPlugin, LogDiagnosticsPlugin}, math::{DVec2, DVec3}, - pbr::NotShadowCaster, + pbr::{ShadowsStyle, NotShadowCaster}, prelude::*, render::{ batching::NoAutomaticBatching, @@ -241,13 +241,12 @@ fn setup( } } - commands.spawn(( - DirectionalLight { - shadows_enabled: args.shadows, - ..default() - }, - Transform::IDENTITY.looking_at(Vec3::new(0.0, -1.0, -1.0), Vec3::Y), - )); + commands + .spawn(( + DirectionalLight::default(), + Transform::IDENTITY.looking_at(Vec3::new(0.0, -1.0, -1.0), Vec3::Y), + )) + .insert_if(ShadowsStyle::Hard, || args.shadows); } fn init_textures(args: &Args, images: &mut Assets) -> Vec> { diff --git a/examples/stress_tests/many_foxes.rs b/examples/stress_tests/many_foxes.rs index 4752afd6e1d3c..d696d703a200e 100644 --- a/examples/stress_tests/many_foxes.rs +++ b/examples/stress_tests/many_foxes.rs @@ -6,7 +6,7 @@ use std::{f32::consts::PI, time::Duration}; use argh::FromArgs; use bevy::{ diagnostic::{FrameTimeDiagnosticsPlugin, LogDiagnosticsPlugin}, - pbr::CascadeShadowConfigBuilder, + pbr::{CascadeShadowConfigBuilder, ShadowsStyle}, prelude::*, window::{PresentMode, WindowResolution}, winit::{UpdateMode, WinitSettings}, @@ -209,10 +209,8 @@ fn setup( // Light commands.spawn(( Transform::from_rotation(Quat::from_euler(EulerRot::ZYX, 0.0, 1.0, -PI / 4.)), - DirectionalLight { - shadows_enabled: true, - ..default() - }, + DirectionalLight::default(), + ShadowsStyle::Hard, CascadeShadowConfigBuilder { first_cascade_far_bound: 0.9 * radius, maximum_distance: 2.8 * radius, diff --git a/examples/testbed/3d.rs b/examples/testbed/3d.rs index a017a10be7f30..f1a9f18161a8d 100644 --- a/examples/testbed/3d.rs +++ b/examples/testbed/3d.rs @@ -62,6 +62,7 @@ mod light { use bevy::{ color::palettes::css::{DEEP_PINK, LIME, RED}, + pbr::ShadowsStyle, prelude::*, }; @@ -96,9 +97,9 @@ mod light { PointLight { intensity: 100_000.0, color: RED.into(), - shadows_enabled: true, ..default() }, + ShadowsStyle::Hard, Transform::from_xyz(1.0, 2.0, 0.0), StateScoped(CURRENT_SCENE), )); @@ -107,11 +108,11 @@ mod light { SpotLight { intensity: 100_000.0, color: LIME.into(), - shadows_enabled: true, inner_angle: 0.6, outer_angle: 0.8, ..default() }, + ShadowsStyle::Hard, Transform::from_xyz(-1.0, 2.0, 0.0).looking_at(Vec3::new(-1.0, 0.0, 0.0), Vec3::Z), StateScoped(CURRENT_SCENE), )); @@ -119,9 +120,9 @@ mod light { commands.spawn(( DirectionalLight { illuminance: light_consts::lux::OVERCAST_DAY, - shadows_enabled: true, ..default() }, + ShadowsStyle::Hard, Transform { translation: Vec3::new(0.0, 2.0, 0.0), rotation: Quat::from_rotation_x(-PI / 4.), @@ -192,7 +193,7 @@ mod bloom { } mod gltf { - use bevy::prelude::*; + use bevy::{pbr::ShadowsStyle, prelude::*}; const CURRENT_SCENE: super::Scene = super::Scene::Gltf; @@ -210,10 +211,8 @@ mod gltf { )); commands.spawn(( - DirectionalLight { - shadows_enabled: true, - ..default() - }, + DirectionalLight::default(), + ShadowsStyle::Hard, StateScoped(CURRENT_SCENE), )); commands.spawn(( @@ -228,7 +227,7 @@ mod gltf { mod animation { use std::{f32::consts::PI, time::Duration}; - use bevy::{prelude::*, scene::SceneInstanceReady}; + use bevy::{pbr::ShadowsStyle, prelude::*, scene::SceneInstanceReady}; const CURRENT_SCENE: super::Scene = super::Scene::Animation; const FOX_PATH: &str = "models/animated/Fox.glb"; @@ -262,10 +261,8 @@ mod animation { commands.spawn(( Transform::from_rotation(Quat::from_euler(EulerRot::ZYX, 0.0, 1.0, -PI / 4.)), - DirectionalLight { - shadows_enabled: true, - ..default() - }, + DirectionalLight::default(), + ShadowsStyle::Hard, StateScoped(CURRENT_SCENE), )); diff --git a/examples/tools/scene_viewer/scene_viewer_plugin.rs b/examples/tools/scene_viewer/scene_viewer_plugin.rs index 49f4805d06eb7..956b9fd7eed61 100644 --- a/examples/tools/scene_viewer/scene_viewer_plugin.rs +++ b/examples/tools/scene_viewer/scene_viewer_plugin.rs @@ -4,7 +4,8 @@ //! - Insert an initialized `SceneHandle` resource into your App's `AssetServer`. use bevy::{ - gltf::Gltf, input::common_conditions::input_just_pressed, prelude::*, scene::InstanceId, + gltf::Gltf, input::common_conditions::input_just_pressed, pbr::ShadowsStyle, prelude::*, + scene::InstanceId, }; use std::{f32::consts::*, fmt}; @@ -144,12 +145,15 @@ fn scene_load_check( fn update_lights( key_input: Res>, time: Res