Skip to main content

bevy_light/
directional_light.rs

1use bevy_asset::Handle;
2use bevy_camera::{
3    primitives::{CascadesFrusta, Frustum},
4    visibility::{self, CascadesVisibleEntities, ViewVisibility, Visibility, VisibilityClass},
5    Camera,
6};
7use bevy_color::Color;
8use bevy_ecs::prelude::*;
9use bevy_image::Image;
10use bevy_math::primitives::ViewFrustum;
11use bevy_reflect::prelude::*;
12use bevy_transform::components::Transform;
13use tracing::warn;
14
15use super::{
16    cascade::CascadeShadowConfig, cluster::ClusterVisibilityClass, light_consts, Cascades,
17};
18
19/// A Directional light.
20///
21/// Directional lights don't exist in reality but they are a good
22/// approximation for light sources VERY far away, like the sun or
23/// the moon.
24///
25/// The light shines along the forward direction of the entity's transform. With a default transform
26/// this would be along the negative-Z axis.
27///
28/// Valid values for `illuminance` are:
29///
30/// | Illuminance (lux) | Surfaces illuminated by                        |
31/// |-------------------|------------------------------------------------|
32/// | 0.0001            | Moonless, overcast night sky (starlight)       |
33/// | 0.002             | Moonless clear night sky with airglow          |
34/// | 0.05–0.3          | Full moon on a clear night                     |
35/// | 3.4               | Dark limit of civil twilight under a clear sky |
36/// | 20–50             | Public areas with dark surroundings            |
37/// | 50                | Family living room lights                      |
38/// | 80                | Office building hallway/toilet lighting        |
39/// | 100               | Very dark overcast day                         |
40/// | 150               | Train station platforms                        |
41/// | 320–500           | Office lighting                                |
42/// | 400               | Sunrise or sunset on a clear day.              |
43/// | 1000              | Overcast day; typical TV studio lighting       |
44/// | 10,000–25,000     | Full daylight (not direct sun)                 |
45/// | 32,000–100,000    | Direct sunlight                                |
46///
47/// Source: [Wikipedia](https://en.wikipedia.org/wiki/Lux)
48///
49/// Some of these are provided as constants in [`light_consts::lux`].
50///
51/// ## Shadows
52///
53/// To enable shadows, set the `shadow_maps_enabled` property to `true`.
54///
55/// Shadows are produced via [cascaded shadow maps](https://developer.download.nvidia.com/SDK/10.5/opengl/src/cascaded_shadow_maps/doc/cascaded_shadow_maps.pdf).
56///
57/// To modify the cascade setup, such as the number of cascades or the maximum shadow distance,
58/// change the [`CascadeShadowConfig`] component of the entity with the [`DirectionalLight`].
59///
60/// To control the resolution of the shadow maps, use the [`DirectionalLightShadowMap`] resource.
61#[derive(#[doc =
"**Required Components**: [`Cascades`], [`CascadesFrusta`], [`CascadeShadowConfig`], [`CascadesVisibleEntities`], [`Transform`], [`Visibility`], [`VisibilityClass`]. \n\n A component's Required Components are inserted whenever it is inserted. Note that this will also insert the required components _of_ the required components, recursively, in depth-first order."]
impl bevy_ecs::component::Component for DirectionalLight where
    Self: ::core::marker::Send + ::core::marker::Sync + 'static {
    const STORAGE_TYPE: bevy_ecs::component::StorageType =
        bevy_ecs::component::StorageType::Table;
    type Mutability = bevy_ecs::component::Mutable;
    fn register_required_components(_requiree:
            bevy_ecs::component::ComponentId,
        required_components:
            &mut bevy_ecs::component::RequiredComponentsRegistrator) {
        required_components.register_required::<Cascades>(<Cascades as
                ::core::default::Default>::default);
        required_components.register_required::<CascadesFrusta>(<CascadesFrusta
                as ::core::default::Default>::default);
        required_components.register_required::<CascadeShadowConfig>(<CascadeShadowConfig
                as ::core::default::Default>::default);
        required_components.register_required::<CascadesVisibleEntities>(<CascadesVisibleEntities
                as ::core::default::Default>::default);
        required_components.register_required::<Transform>(<Transform as
                ::core::default::Default>::default);
        required_components.register_required::<Visibility>(<Visibility as
                ::core::default::Default>::default);
        required_components.register_required::<VisibilityClass>(<VisibilityClass
                as ::core::default::Default>::default);
    }
    fn on_add()
        -> ::core::option::Option<bevy_ecs::lifecycle::ComponentHook> {
        ::core::option::Option::Some(visibility::add_visibility_class::<ClusterVisibilityClass>)
    }
    fn clone_behavior() -> bevy_ecs::component::ComponentCloneBehavior {
        use bevy_ecs::component::{
            DefaultCloneBehaviorBase, DefaultCloneBehaviorViaClone,
        };
        (&&&bevy_ecs::component::DefaultCloneBehaviorSpecialization::<Self>::default()).default_clone_behavior()
    }
    fn relationship_accessor()
        ->
            ::core::option::Option<bevy_ecs::relationship::ComponentRelationshipAccessor<Self>> {
        ::core::option::Option::None
    }
}Component, #[automatically_derived]
impl ::core::fmt::Debug for DirectionalLight {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        let names: &'static _ =
            &["color", "illuminance", "shadow_maps_enabled",
                        "contact_shadows_enabled", "soft_shadow_size",
                        "affects_lightmapped_mesh_diffuse", "shadow_depth_bias",
                        "shadow_normal_bias"];
        let values: &[&dyn ::core::fmt::Debug] =
            &[&self.color, &self.illuminance, &self.shadow_maps_enabled,
                        &self.contact_shadows_enabled, &self.soft_shadow_size,
                        &self.affects_lightmapped_mesh_diffuse,
                        &self.shadow_depth_bias, &&self.shadow_normal_bias];
        ::core::fmt::Formatter::debug_struct_fields_finish(f,
            "DirectionalLight", names, values)
    }
}Debug, #[automatically_derived]
impl ::core::clone::Clone for DirectionalLight {
    #[inline]
    fn clone(&self) -> DirectionalLight {
        let _: ::core::clone::AssertParamIsClone<Color>;
        let _: ::core::clone::AssertParamIsClone<f32>;
        let _: ::core::clone::AssertParamIsClone<bool>;
        let _: ::core::clone::AssertParamIsClone<Option<f32>>;
        *self
    }
}Clone, #[automatically_derived]
impl ::core::marker::Copy for DirectionalLight { }Copy, const _: () =
    {
        impl bevy_reflect::GetTypeRegistration for DirectionalLight where  {
            fn get_type_registration() -> bevy_reflect::TypeRegistration {
                let mut registration =
                    bevy_reflect::TypeRegistration::of::<Self>();
                registration.insert::<bevy_reflect::ReflectFromPtr>(bevy_reflect::FromType::<Self>::from_type());
                registration.insert::<bevy_reflect::ReflectFromReflect>(bevy_reflect::FromType::<Self>::from_type());
                registration.register_type_data::<ReflectComponent, Self>();
                registration.register_type_data::<ReflectDefault, Self>();
                registration
            }
            #[inline(never)]
            fn register_type_dependencies(registry:
                    &mut bevy_reflect::TypeRegistry) {
                <Color as
                        bevy_reflect::__macro_exports::RegisterForReflection>::__register(registry);
                <f32 as
                        bevy_reflect::__macro_exports::RegisterForReflection>::__register(registry);
                <bool as
                        bevy_reflect::__macro_exports::RegisterForReflection>::__register(registry);
                <Option<f32> as
                        bevy_reflect::__macro_exports::RegisterForReflection>::__register(registry);
            }
        }
        impl bevy_reflect::Typed for DirectionalLight where  {
            #[inline]
            fn type_info() -> &'static bevy_reflect::TypeInfo {
                static CELL: bevy_reflect::utility::NonGenericTypeInfoCell =
                    bevy_reflect::utility::NonGenericTypeInfoCell::new();
                CELL.get_or_set(||
                        {
                            bevy_reflect::TypeInfo::Struct(bevy_reflect::structs::StructInfo::new::<Self>(&[bevy_reflect::NamedField::new::<Color>("color"),
                                                bevy_reflect::NamedField::new::<f32>("illuminance"),
                                                bevy_reflect::NamedField::new::<bool>("shadow_maps_enabled"),
                                                bevy_reflect::NamedField::new::<bool>("contact_shadows_enabled"),
                                                bevy_reflect::NamedField::new::<Option<f32>>("soft_shadow_size"),
                                                bevy_reflect::NamedField::new::<bool>("affects_lightmapped_mesh_diffuse"),
                                                bevy_reflect::NamedField::new::<f32>("shadow_depth_bias"),
                                                bevy_reflect::NamedField::new::<f32>("shadow_normal_bias")]))
                        })
            }
        }
        #[allow(deprecated, reason =
        "derives on a deprecated type shouldn't be considered a usage")]
        impl bevy_reflect::TypePath for DirectionalLight where  {
            fn type_path() -> &'static str {
                "bevy_light::directional_light::DirectionalLight"
            }
            fn short_type_path() -> &'static str { "DirectionalLight" }
            fn type_ident() -> ::core::option::Option<&'static str> {
                ::core::option::Option::Some("DirectionalLight")
            }
            fn crate_name() -> ::core::option::Option<&'static str> {
                ::core::option::Option::Some("bevy_light::directional_light".split(':').next().unwrap())
            }
            fn module_path() -> ::core::option::Option<&'static str> {
                ::core::option::Option::Some("bevy_light::directional_light")
            }
        }
        impl bevy_reflect::Reflect for DirectionalLight where  {
            #[inline]
            fn into_any(self:
                    bevy_reflect::__macro_exports::alloc_utils::Box<Self>)
                ->
                    bevy_reflect::__macro_exports::alloc_utils::Box<dyn ::core::any::Any> {
                self
            }
            #[inline]
            fn as_any(&self) -> &dyn ::core::any::Any { self }
            #[inline]
            fn as_any_mut(&mut self) -> &mut dyn ::core::any::Any { self }
            #[inline]
            fn into_reflect(self:
                    bevy_reflect::__macro_exports::alloc_utils::Box<Self>)
                ->
                    bevy_reflect::__macro_exports::alloc_utils::Box<dyn bevy_reflect::Reflect> {
                self
            }
            #[inline]
            fn as_reflect(&self) -> &dyn bevy_reflect::Reflect { self }
            #[inline]
            fn as_reflect_mut(&mut self) -> &mut dyn bevy_reflect::Reflect {
                self
            }
            #[inline]
            fn set(&mut self,
                value:
                    bevy_reflect::__macro_exports::alloc_utils::Box<dyn bevy_reflect::Reflect>)
                ->
                    ::core::result::Result<(),
                    bevy_reflect::__macro_exports::alloc_utils::Box<dyn bevy_reflect::Reflect>> {
                *self = <dyn bevy_reflect::Reflect>::take(value)?;
                ::core::result::Result::Ok(())
            }
        }
        #[allow(non_upper_case_globals)]
        const _: () =
            {
                static __INVENTORY: ::inventory::Node =
                    ::inventory::Node {
                        value: &{
                                bevy_reflect::__macro_exports::auto_register::AutomaticReflectRegistrations(<DirectionalLight
                                        as
                                        bevy_reflect::__macro_exports::auto_register::RegisterForReflection>::__register)
                            },
                        next: ::inventory::__private::UnsafeCell::new(::inventory::__private::Option::None),
                    };
                #[link_section = ".text.startup"]
                unsafe extern "C" fn __ctor() {
                    unsafe {
                        ::inventory::ErasedNode::submit(__INVENTORY.value,
                            &__INVENTORY)
                    }
                }
                #[used]
                #[link_section = ".init_array"]
                static __CTOR: unsafe extern "C" fn() = __ctor;
            };
        impl bevy_reflect::structs::Struct for DirectionalLight where  {
            fn field(&self, name: &str)
                -> ::core::option::Option<&dyn bevy_reflect::PartialReflect> {
                match name {
                    "color" => ::core::option::Option::Some(&self.color),
                    "illuminance" =>
                        ::core::option::Option::Some(&self.illuminance),
                    "shadow_maps_enabled" =>
                        ::core::option::Option::Some(&self.shadow_maps_enabled),
                    "contact_shadows_enabled" =>
                        ::core::option::Option::Some(&self.contact_shadows_enabled),
                    "soft_shadow_size" =>
                        ::core::option::Option::Some(&self.soft_shadow_size),
                    "affects_lightmapped_mesh_diffuse" =>
                        ::core::option::Option::Some(&self.affects_lightmapped_mesh_diffuse),
                    "shadow_depth_bias" =>
                        ::core::option::Option::Some(&self.shadow_depth_bias),
                    "shadow_normal_bias" =>
                        ::core::option::Option::Some(&self.shadow_normal_bias),
                    _ => ::core::option::Option::None,
                }
            }
            fn field_mut(&mut self, name: &str)
                ->
                    ::core::option::Option<&mut dyn bevy_reflect::PartialReflect> {
                match name {
                    "color" => ::core::option::Option::Some(&mut self.color),
                    "illuminance" =>
                        ::core::option::Option::Some(&mut self.illuminance),
                    "shadow_maps_enabled" =>
                        ::core::option::Option::Some(&mut self.shadow_maps_enabled),
                    "contact_shadows_enabled" =>
                        ::core::option::Option::Some(&mut self.contact_shadows_enabled),
                    "soft_shadow_size" =>
                        ::core::option::Option::Some(&mut self.soft_shadow_size),
                    "affects_lightmapped_mesh_diffuse" =>
                        ::core::option::Option::Some(&mut self.affects_lightmapped_mesh_diffuse),
                    "shadow_depth_bias" =>
                        ::core::option::Option::Some(&mut self.shadow_depth_bias),
                    "shadow_normal_bias" =>
                        ::core::option::Option::Some(&mut self.shadow_normal_bias),
                    _ => ::core::option::Option::None,
                }
            }
            fn field_at(&self, index: usize)
                -> ::core::option::Option<&dyn bevy_reflect::PartialReflect> {
                match index {
                    0usize => ::core::option::Option::Some(&self.color),
                    1usize => ::core::option::Option::Some(&self.illuminance),
                    2usize =>
                        ::core::option::Option::Some(&self.shadow_maps_enabled),
                    3usize =>
                        ::core::option::Option::Some(&self.contact_shadows_enabled),
                    4usize =>
                        ::core::option::Option::Some(&self.soft_shadow_size),
                    5usize =>
                        ::core::option::Option::Some(&self.affects_lightmapped_mesh_diffuse),
                    6usize =>
                        ::core::option::Option::Some(&self.shadow_depth_bias),
                    7usize =>
                        ::core::option::Option::Some(&self.shadow_normal_bias),
                    _ => ::core::option::Option::None,
                }
            }
            fn field_at_mut(&mut self, index: usize)
                ->
                    ::core::option::Option<&mut dyn bevy_reflect::PartialReflect> {
                match index {
                    0usize => ::core::option::Option::Some(&mut self.color),
                    1usize =>
                        ::core::option::Option::Some(&mut self.illuminance),
                    2usize =>
                        ::core::option::Option::Some(&mut self.shadow_maps_enabled),
                    3usize =>
                        ::core::option::Option::Some(&mut self.contact_shadows_enabled),
                    4usize =>
                        ::core::option::Option::Some(&mut self.soft_shadow_size),
                    5usize =>
                        ::core::option::Option::Some(&mut self.affects_lightmapped_mesh_diffuse),
                    6usize =>
                        ::core::option::Option::Some(&mut self.shadow_depth_bias),
                    7usize =>
                        ::core::option::Option::Some(&mut self.shadow_normal_bias),
                    _ => ::core::option::Option::None,
                }
            }
            fn name_at(&self, index: usize) -> ::core::option::Option<&str> {
                match index {
                    0usize => ::core::option::Option::Some("color"),
                    1usize => ::core::option::Option::Some("illuminance"),
                    2usize =>
                        ::core::option::Option::Some("shadow_maps_enabled"),
                    3usize =>
                        ::core::option::Option::Some("contact_shadows_enabled"),
                    4usize => ::core::option::Option::Some("soft_shadow_size"),
                    5usize =>
                        ::core::option::Option::Some("affects_lightmapped_mesh_diffuse"),
                    6usize => ::core::option::Option::Some("shadow_depth_bias"),
                    7usize =>
                        ::core::option::Option::Some("shadow_normal_bias"),
                    _ => ::core::option::Option::None,
                }
            }
            fn index_of_name(&self, name: &str)
                -> ::core::option::Option<usize> {
                match name {
                    "color" => ::core::option::Option::Some(0usize),
                    "illuminance" => ::core::option::Option::Some(1usize),
                    "shadow_maps_enabled" =>
                        ::core::option::Option::Some(2usize),
                    "contact_shadows_enabled" =>
                        ::core::option::Option::Some(3usize),
                    "soft_shadow_size" => ::core::option::Option::Some(4usize),
                    "affects_lightmapped_mesh_diffuse" =>
                        ::core::option::Option::Some(5usize),
                    "shadow_depth_bias" => ::core::option::Option::Some(6usize),
                    "shadow_normal_bias" =>
                        ::core::option::Option::Some(7usize),
                    _ => ::core::option::Option::None,
                }
            }
            fn field_len(&self) -> usize { 8usize }
            fn iter_fields(&self) -> bevy_reflect::structs::FieldIter {
                bevy_reflect::structs::FieldIter::new(self)
            }
            fn to_dynamic_struct(&self)
                -> bevy_reflect::structs::DynamicStruct {
                let mut dynamic: bevy_reflect::structs::DynamicStruct =
                    ::core::default::Default::default();
                dynamic.set_represented_type(bevy_reflect::PartialReflect::get_represented_type_info(self));
                dynamic.insert_boxed("color",
                    bevy_reflect::PartialReflect::to_dynamic(&self.color));
                dynamic.insert_boxed("illuminance",
                    bevy_reflect::PartialReflect::to_dynamic(&self.illuminance));
                dynamic.insert_boxed("shadow_maps_enabled",
                    bevy_reflect::PartialReflect::to_dynamic(&self.shadow_maps_enabled));
                dynamic.insert_boxed("contact_shadows_enabled",
                    bevy_reflect::PartialReflect::to_dynamic(&self.contact_shadows_enabled));
                dynamic.insert_boxed("soft_shadow_size",
                    bevy_reflect::PartialReflect::to_dynamic(&self.soft_shadow_size));
                dynamic.insert_boxed("affects_lightmapped_mesh_diffuse",
                    bevy_reflect::PartialReflect::to_dynamic(&self.affects_lightmapped_mesh_diffuse));
                dynamic.insert_boxed("shadow_depth_bias",
                    bevy_reflect::PartialReflect::to_dynamic(&self.shadow_depth_bias));
                dynamic.insert_boxed("shadow_normal_bias",
                    bevy_reflect::PartialReflect::to_dynamic(&self.shadow_normal_bias));
                dynamic
            }
        }
        impl bevy_reflect::PartialReflect for DirectionalLight where  {
            #[inline]
            fn get_represented_type_info(&self)
                -> ::core::option::Option<&'static bevy_reflect::TypeInfo> {
                ::core::option::Option::Some(<Self as
                            bevy_reflect::Typed>::type_info())
            }
            #[inline]
            fn try_apply(&mut self, value: &dyn bevy_reflect::PartialReflect)
                -> ::core::result::Result<(), bevy_reflect::ApplyError> {
                if let bevy_reflect::ReflectRef::Struct(struct_value) =
                        bevy_reflect::PartialReflect::reflect_ref(value) {
                    for (name, value) in
                        bevy_reflect::structs::Struct::iter_fields(struct_value) {
                        if let ::core::option::Option::Some(v) =
                                bevy_reflect::structs::Struct::field_mut(self, name) {
                            bevy_reflect::PartialReflect::try_apply(v, value)?;
                        }
                    }
                } else {
                    return ::core::result::Result::Err(bevy_reflect::ApplyError::MismatchedKinds {
                                from_kind: bevy_reflect::PartialReflect::reflect_kind(value),
                                to_kind: bevy_reflect::ReflectKind::Struct,
                            });
                }
                ::core::result::Result::Ok(())
            }
            #[inline]
            fn reflect_kind(&self) -> bevy_reflect::ReflectKind {
                bevy_reflect::ReflectKind::Struct
            }
            #[inline]
            fn reflect_ref(&self) -> bevy_reflect::ReflectRef {
                bevy_reflect::ReflectRef::Struct(self)
            }
            #[inline]
            fn reflect_mut(&mut self) -> bevy_reflect::ReflectMut {
                bevy_reflect::ReflectMut::Struct(self)
            }
            #[inline]
            fn reflect_owned(self:
                    bevy_reflect::__macro_exports::alloc_utils::Box<Self>)
                -> bevy_reflect::ReflectOwned {
                bevy_reflect::ReflectOwned::Struct(self)
            }
            #[inline]
            fn try_into_reflect(self:
                    bevy_reflect::__macro_exports::alloc_utils::Box<Self>)
                ->
                    ::core::result::Result<bevy_reflect::__macro_exports::alloc_utils::Box<dyn bevy_reflect::Reflect>,
                    bevy_reflect::__macro_exports::alloc_utils::Box<dyn bevy_reflect::PartialReflect>> {
                ::core::result::Result::Ok(self)
            }
            #[inline]
            fn try_as_reflect(&self)
                -> ::core::option::Option<&dyn bevy_reflect::Reflect> {
                ::core::option::Option::Some(self)
            }
            #[inline]
            fn try_as_reflect_mut(&mut self)
                -> ::core::option::Option<&mut dyn bevy_reflect::Reflect> {
                ::core::option::Option::Some(self)
            }
            #[inline]
            fn into_partial_reflect(self:
                    bevy_reflect::__macro_exports::alloc_utils::Box<Self>)
                ->
                    bevy_reflect::__macro_exports::alloc_utils::Box<dyn bevy_reflect::PartialReflect> {
                self
            }
            #[inline]
            fn as_partial_reflect(&self)
                -> &dyn bevy_reflect::PartialReflect {
                self
            }
            #[inline]
            fn as_partial_reflect_mut(&mut self)
                -> &mut dyn bevy_reflect::PartialReflect {
                self
            }
            fn reflect_partial_eq(&self,
                value: &dyn bevy_reflect::PartialReflect)
                -> ::core::option::Option<bool> {
                (bevy_reflect::structs::struct_partial_eq)(self, value)
            }
            fn reflect_partial_cmp(&self,
                value: &dyn bevy_reflect::PartialReflect)
                -> ::core::option::Option<::core::cmp::Ordering> {
                (bevy_reflect::structs::struct_partial_cmp)(self, value)
            }
            fn debug(&self, f: &mut ::core::fmt::Formatter<'_>)
                -> ::core::fmt::Result {
                ::core::fmt::Debug::fmt(self, f)
            }
            #[inline]
            fn reflect_clone(&self)
                ->
                    ::core::result::Result<bevy_reflect::__macro_exports::alloc_utils::Box<dyn bevy_reflect::Reflect>,
                    bevy_reflect::ReflectCloneError> {
                ::core::result::Result::Ok(bevy_reflect::__macro_exports::alloc_utils::Box::new(::core::clone::Clone::clone(self)))
            }
        }
        impl bevy_reflect::FromReflect for DirectionalLight where  {
            fn from_reflect(reflect: &dyn bevy_reflect::PartialReflect)
                -> ::core::option::Option<Self> {
                if let bevy_reflect::ReflectRef::Struct(__ref_struct) =
                        bevy_reflect::PartialReflect::reflect_ref(reflect) {
                    let mut __this =
                        <Self as ::core::default::Default>::default();
                    if let ::core::option::Option::Some(__field) =
                            (||
                                        <Color as
                                                bevy_reflect::FromReflect>::from_reflect(bevy_reflect::structs::Struct::field(__ref_struct,
                                                    "color")?))() {
                        __this.color = __field;
                    }
                    if let ::core::option::Option::Some(__field) =
                            (||
                                        <f32 as
                                                bevy_reflect::FromReflect>::from_reflect(bevy_reflect::structs::Struct::field(__ref_struct,
                                                    "illuminance")?))() {
                        __this.illuminance = __field;
                    }
                    if let ::core::option::Option::Some(__field) =
                            (||
                                        <bool as
                                                bevy_reflect::FromReflect>::from_reflect(bevy_reflect::structs::Struct::field(__ref_struct,
                                                    "shadow_maps_enabled")?))() {
                        __this.shadow_maps_enabled = __field;
                    }
                    if let ::core::option::Option::Some(__field) =
                            (||
                                        <bool as
                                                bevy_reflect::FromReflect>::from_reflect(bevy_reflect::structs::Struct::field(__ref_struct,
                                                    "contact_shadows_enabled")?))() {
                        __this.contact_shadows_enabled = __field;
                    }
                    if let ::core::option::Option::Some(__field) =
                            (||
                                        <Option<f32> as
                                                bevy_reflect::FromReflect>::from_reflect(bevy_reflect::structs::Struct::field(__ref_struct,
                                                    "soft_shadow_size")?))() {
                        __this.soft_shadow_size = __field;
                    }
                    if let ::core::option::Option::Some(__field) =
                            (||
                                        <bool as
                                                bevy_reflect::FromReflect>::from_reflect(bevy_reflect::structs::Struct::field(__ref_struct,
                                                    "affects_lightmapped_mesh_diffuse")?))() {
                        __this.affects_lightmapped_mesh_diffuse = __field;
                    }
                    if let ::core::option::Option::Some(__field) =
                            (||
                                        <f32 as
                                                bevy_reflect::FromReflect>::from_reflect(bevy_reflect::structs::Struct::field(__ref_struct,
                                                    "shadow_depth_bias")?))() {
                        __this.shadow_depth_bias = __field;
                    }
                    if let ::core::option::Option::Some(__field) =
                            (||
                                        <f32 as
                                                bevy_reflect::FromReflect>::from_reflect(bevy_reflect::structs::Struct::field(__ref_struct,
                                                    "shadow_normal_bias")?))() {
                        __this.shadow_normal_bias = __field;
                    }
                    ::core::option::Option::Some(__this)
                } else { ::core::option::Option::None }
            }
        }
    };Reflect)]
62#[reflect(Component, Default, Debug, Clone)]
63#[require(
64    Cascades,
65    CascadesFrusta,
66    CascadeShadowConfig,
67    CascadesVisibleEntities,
68    Transform,
69    Visibility,
70    VisibilityClass
71)]
72#[component(on_add = visibility::add_visibility_class::<ClusterVisibilityClass>)]
73pub struct DirectionalLight {
74    /// The color of the light.
75    ///
76    /// By default, this is white.
77    pub color: Color,
78
79    /// Illuminance in lux (lumens per square meter), representing the amount of
80    /// light projected onto surfaces by this light source. Lux is used here
81    /// instead of lumens because a directional light illuminates all surfaces
82    /// more-or-less the same way (depending on the angle of incidence). Lumens
83    /// can only be specified for light sources which emit light from a specific
84    /// area.
85    /// The default is [`light_consts::lux::AMBIENT_DAYLIGHT`] = 10,000.
86    pub illuminance: f32,
87
88    /// Whether this light casts shadows.
89    ///
90    /// Note that shadows are rather expensive and become more so with every
91    /// light that casts them. In general, it's best to aggressively limit the
92    /// number of lights with shadows enabled to one or two at most.
93    pub shadow_maps_enabled: bool,
94
95    /// Whether this light casts contact shadows.
96    pub contact_shadows_enabled: bool,
97
98    /// Whether soft shadows are enabled, and if so, the size of the light.
99    ///
100    /// Soft shadows, also known as *percentage-closer soft shadows* or PCSS,
101    /// cause shadows to become blurrier (i.e. their penumbra increases in
102    /// radius) as they extend away from objects. The blurriness of the shadow
103    /// depends on the size of the light; larger lights result in larger
104    /// penumbras and therefore blurrier shadows.
105    ///
106    /// Currently, soft shadows are rather noisy if not using the temporal mode.
107    /// If you enable soft shadows, consider choosing
108    /// [`ShadowFilteringMethod::Temporal`] and enabling temporal antialiasing
109    /// (TAA) to smooth the noise out over time.
110    ///
111    /// Note that soft shadows are significantly more expensive to render than
112    /// hard shadows.
113    ///
114    /// [`ShadowFilteringMethod::Temporal`]: crate::ShadowFilteringMethod::Temporal
115    #[cfg(feature = "experimental_pbr_pcss")]
116    pub soft_shadow_size: Option<f32>,
117
118    /// Whether this directional light contributes diffuse lighting to meshes
119    /// with lightmaps.
120    ///
121    /// Set this to false if your lightmap baking tool bakes the direct diffuse
122    /// light from this directional light into the lightmaps in order to avoid
123    /// counting the radiance from this light twice. Note that the specular
124    /// portion of the light is always considered, because Bevy currently has no
125    /// means to bake specular light.
126    ///
127    /// By default, this is set to true.
128    pub affects_lightmapped_mesh_diffuse: bool,
129
130    /// A value that adjusts the tradeoff between self-shadowing artifacts and
131    /// proximity of shadows to their casters.
132    ///
133    /// This value frequently must be tuned to the specific scene; this is
134    /// normal and a well-known part of the shadow mapping workflow. If set too
135    /// low, unsightly shadow patterns appear on objects not in shadow as
136    /// objects incorrectly cast shadows on themselves, known as *shadow acne*.
137    /// If set too high, shadows detach from the objects casting them and seem
138    /// to "fly" off the objects, known as *Peter Panning*.
139    pub shadow_depth_bias: f32,
140
141    /// A bias applied along the direction of the fragment's surface normal. It
142    /// is scaled to the shadow map's texel size so that it is automatically
143    /// adjusted to the orthographic projection.
144    pub shadow_normal_bias: f32,
145}
146
147impl Default for DirectionalLight {
148    fn default() -> Self {
149        DirectionalLight {
150            color: Color::WHITE,
151            illuminance: light_consts::lux::AMBIENT_DAYLIGHT,
152            shadow_maps_enabled: false,
153            contact_shadows_enabled: false,
154            shadow_depth_bias: Self::DEFAULT_SHADOW_DEPTH_BIAS,
155            shadow_normal_bias: Self::DEFAULT_SHADOW_NORMAL_BIAS,
156            affects_lightmapped_mesh_diffuse: true,
157            #[cfg(feature = "experimental_pbr_pcss")]
158            soft_shadow_size: None,
159        }
160    }
161}
162
163impl DirectionalLight {
164    /// The default value of [`DirectionalLight::shadow_depth_bias`].
165    pub const DEFAULT_SHADOW_DEPTH_BIAS: f32 = 0.02;
166    /// The default value of [`DirectionalLight::shadow_normal_bias`].
167    pub const DEFAULT_SHADOW_NORMAL_BIAS: f32 = 1.8;
168}
169
170/// Add to a [`DirectionalLight`] to add a light texture effect.
171/// A texture mask is applied to the light source to modulate its intensity,  
172/// simulating patterns like window shadows, gobo/cookie effects, or soft falloffs.
173#[derive(#[automatically_derived]
impl ::core::clone::Clone for DirectionalLightTexture {
    #[inline]
    fn clone(&self) -> DirectionalLightTexture {
        DirectionalLightTexture {
            image: ::core::clone::Clone::clone(&self.image),
            tiled: ::core::clone::Clone::clone(&self.tiled),
        }
    }
}Clone, #[doc =
"**Required Components**: [`DirectionalLight`]. \n\n A component's Required Components are inserted whenever it is inserted. Note that this will also insert the required components _of_ the required components, recursively, in depth-first order."]
impl bevy_ecs::component::Component for DirectionalLightTexture where
    Self: ::core::marker::Send + ::core::marker::Sync + 'static {
    const STORAGE_TYPE: bevy_ecs::component::StorageType =
        bevy_ecs::component::StorageType::Table;
    type Mutability = bevy_ecs::component::Mutable;
    fn register_required_components(_requiree:
            bevy_ecs::component::ComponentId,
        required_components:
            &mut bevy_ecs::component::RequiredComponentsRegistrator) {
        required_components.register_required::<DirectionalLight>(<DirectionalLight
                as ::core::default::Default>::default);
    }
    fn clone_behavior() -> bevy_ecs::component::ComponentCloneBehavior {
        use bevy_ecs::component::{
            DefaultCloneBehaviorBase, DefaultCloneBehaviorViaClone,
        };
        (&&&bevy_ecs::component::DefaultCloneBehaviorSpecialization::<Self>::default()).default_clone_behavior()
    }
    fn relationship_accessor()
        ->
            ::core::option::Option<bevy_ecs::relationship::ComponentRelationshipAccessor<Self>> {
        ::core::option::Option::None
    }
}Component, #[automatically_derived]
impl ::core::fmt::Debug for DirectionalLightTexture {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::debug_struct_field2_finish(f,
            "DirectionalLightTexture", "image", &self.image, "tiled",
            &&self.tiled)
    }
}Debug, const _: () =
    {
        impl bevy_reflect::GetTypeRegistration for DirectionalLightTexture
            where  {
            fn get_type_registration() -> bevy_reflect::TypeRegistration {
                let mut registration =
                    bevy_reflect::TypeRegistration::of::<Self>();
                registration.insert::<bevy_reflect::ReflectFromPtr>(bevy_reflect::FromType::<Self>::from_type());
                registration.insert::<bevy_reflect::ReflectFromReflect>(bevy_reflect::FromType::<Self>::from_type());
                registration.register_type_data::<ReflectComponent, Self>();
                registration
            }
            #[inline(never)]
            fn register_type_dependencies(registry:
                    &mut bevy_reflect::TypeRegistry) {
                <Handle<Image> as
                        bevy_reflect::__macro_exports::RegisterForReflection>::__register(registry);
                <bool as
                        bevy_reflect::__macro_exports::RegisterForReflection>::__register(registry);
            }
        }
        impl bevy_reflect::Typed for DirectionalLightTexture where  {
            #[inline]
            fn type_info() -> &'static bevy_reflect::TypeInfo {
                static CELL: bevy_reflect::utility::NonGenericTypeInfoCell =
                    bevy_reflect::utility::NonGenericTypeInfoCell::new();
                CELL.get_or_set(||
                        {
                            bevy_reflect::TypeInfo::Struct(bevy_reflect::structs::StructInfo::new::<Self>(&[bevy_reflect::NamedField::new::<Handle<Image>>("image"),
                                                bevy_reflect::NamedField::new::<bool>("tiled")]))
                        })
            }
        }
        #[allow(deprecated, reason =
        "derives on a deprecated type shouldn't be considered a usage")]
        impl bevy_reflect::TypePath for DirectionalLightTexture where  {
            fn type_path() -> &'static str {
                "bevy_light::directional_light::DirectionalLightTexture"
            }
            fn short_type_path() -> &'static str { "DirectionalLightTexture" }
            fn type_ident() -> ::core::option::Option<&'static str> {
                ::core::option::Option::Some("DirectionalLightTexture")
            }
            fn crate_name() -> ::core::option::Option<&'static str> {
                ::core::option::Option::Some("bevy_light::directional_light".split(':').next().unwrap())
            }
            fn module_path() -> ::core::option::Option<&'static str> {
                ::core::option::Option::Some("bevy_light::directional_light")
            }
        }
        impl bevy_reflect::Reflect for DirectionalLightTexture where  {
            #[inline]
            fn into_any(self:
                    bevy_reflect::__macro_exports::alloc_utils::Box<Self>)
                ->
                    bevy_reflect::__macro_exports::alloc_utils::Box<dyn ::core::any::Any> {
                self
            }
            #[inline]
            fn as_any(&self) -> &dyn ::core::any::Any { self }
            #[inline]
            fn as_any_mut(&mut self) -> &mut dyn ::core::any::Any { self }
            #[inline]
            fn into_reflect(self:
                    bevy_reflect::__macro_exports::alloc_utils::Box<Self>)
                ->
                    bevy_reflect::__macro_exports::alloc_utils::Box<dyn bevy_reflect::Reflect> {
                self
            }
            #[inline]
            fn as_reflect(&self) -> &dyn bevy_reflect::Reflect { self }
            #[inline]
            fn as_reflect_mut(&mut self) -> &mut dyn bevy_reflect::Reflect {
                self
            }
            #[inline]
            fn set(&mut self,
                value:
                    bevy_reflect::__macro_exports::alloc_utils::Box<dyn bevy_reflect::Reflect>)
                ->
                    ::core::result::Result<(),
                    bevy_reflect::__macro_exports::alloc_utils::Box<dyn bevy_reflect::Reflect>> {
                *self = <dyn bevy_reflect::Reflect>::take(value)?;
                ::core::result::Result::Ok(())
            }
        }
        #[allow(non_upper_case_globals)]
        const _: () =
            {
                static __INVENTORY: ::inventory::Node =
                    ::inventory::Node {
                        value: &{
                                bevy_reflect::__macro_exports::auto_register::AutomaticReflectRegistrations(<DirectionalLightTexture
                                        as
                                        bevy_reflect::__macro_exports::auto_register::RegisterForReflection>::__register)
                            },
                        next: ::inventory::__private::UnsafeCell::new(::inventory::__private::Option::None),
                    };
                #[link_section = ".text.startup"]
                unsafe extern "C" fn __ctor() {
                    unsafe {
                        ::inventory::ErasedNode::submit(__INVENTORY.value,
                            &__INVENTORY)
                    }
                }
                #[used]
                #[link_section = ".init_array"]
                static __CTOR: unsafe extern "C" fn() = __ctor;
            };
        impl bevy_reflect::structs::Struct for DirectionalLightTexture where
            {
            fn field(&self, name: &str)
                -> ::core::option::Option<&dyn bevy_reflect::PartialReflect> {
                match name {
                    "image" => ::core::option::Option::Some(&self.image),
                    "tiled" => ::core::option::Option::Some(&self.tiled),
                    _ => ::core::option::Option::None,
                }
            }
            fn field_mut(&mut self, name: &str)
                ->
                    ::core::option::Option<&mut dyn bevy_reflect::PartialReflect> {
                match name {
                    "image" => ::core::option::Option::Some(&mut self.image),
                    "tiled" => ::core::option::Option::Some(&mut self.tiled),
                    _ => ::core::option::Option::None,
                }
            }
            fn field_at(&self, index: usize)
                -> ::core::option::Option<&dyn bevy_reflect::PartialReflect> {
                match index {
                    0usize => ::core::option::Option::Some(&self.image),
                    1usize => ::core::option::Option::Some(&self.tiled),
                    _ => ::core::option::Option::None,
                }
            }
            fn field_at_mut(&mut self, index: usize)
                ->
                    ::core::option::Option<&mut dyn bevy_reflect::PartialReflect> {
                match index {
                    0usize => ::core::option::Option::Some(&mut self.image),
                    1usize => ::core::option::Option::Some(&mut self.tiled),
                    _ => ::core::option::Option::None,
                }
            }
            fn name_at(&self, index: usize) -> ::core::option::Option<&str> {
                match index {
                    0usize => ::core::option::Option::Some("image"),
                    1usize => ::core::option::Option::Some("tiled"),
                    _ => ::core::option::Option::None,
                }
            }
            fn index_of_name(&self, name: &str)
                -> ::core::option::Option<usize> {
                match name {
                    "image" => ::core::option::Option::Some(0usize),
                    "tiled" => ::core::option::Option::Some(1usize),
                    _ => ::core::option::Option::None,
                }
            }
            fn field_len(&self) -> usize { 2usize }
            fn iter_fields(&self) -> bevy_reflect::structs::FieldIter {
                bevy_reflect::structs::FieldIter::new(self)
            }
            fn to_dynamic_struct(&self)
                -> bevy_reflect::structs::DynamicStruct {
                let mut dynamic: bevy_reflect::structs::DynamicStruct =
                    ::core::default::Default::default();
                dynamic.set_represented_type(bevy_reflect::PartialReflect::get_represented_type_info(self));
                dynamic.insert_boxed("image",
                    bevy_reflect::PartialReflect::to_dynamic(&self.image));
                dynamic.insert_boxed("tiled",
                    bevy_reflect::PartialReflect::to_dynamic(&self.tiled));
                dynamic
            }
        }
        impl bevy_reflect::PartialReflect for DirectionalLightTexture where  {
            #[inline]
            fn get_represented_type_info(&self)
                -> ::core::option::Option<&'static bevy_reflect::TypeInfo> {
                ::core::option::Option::Some(<Self as
                            bevy_reflect::Typed>::type_info())
            }
            #[inline]
            fn try_apply(&mut self, value: &dyn bevy_reflect::PartialReflect)
                -> ::core::result::Result<(), bevy_reflect::ApplyError> {
                if let bevy_reflect::ReflectRef::Struct(struct_value) =
                        bevy_reflect::PartialReflect::reflect_ref(value) {
                    for (name, value) in
                        bevy_reflect::structs::Struct::iter_fields(struct_value) {
                        if let ::core::option::Option::Some(v) =
                                bevy_reflect::structs::Struct::field_mut(self, name) {
                            bevy_reflect::PartialReflect::try_apply(v, value)?;
                        }
                    }
                } else {
                    return ::core::result::Result::Err(bevy_reflect::ApplyError::MismatchedKinds {
                                from_kind: bevy_reflect::PartialReflect::reflect_kind(value),
                                to_kind: bevy_reflect::ReflectKind::Struct,
                            });
                }
                ::core::result::Result::Ok(())
            }
            #[inline]
            fn reflect_kind(&self) -> bevy_reflect::ReflectKind {
                bevy_reflect::ReflectKind::Struct
            }
            #[inline]
            fn reflect_ref(&self) -> bevy_reflect::ReflectRef {
                bevy_reflect::ReflectRef::Struct(self)
            }
            #[inline]
            fn reflect_mut(&mut self) -> bevy_reflect::ReflectMut {
                bevy_reflect::ReflectMut::Struct(self)
            }
            #[inline]
            fn reflect_owned(self:
                    bevy_reflect::__macro_exports::alloc_utils::Box<Self>)
                -> bevy_reflect::ReflectOwned {
                bevy_reflect::ReflectOwned::Struct(self)
            }
            #[inline]
            fn try_into_reflect(self:
                    bevy_reflect::__macro_exports::alloc_utils::Box<Self>)
                ->
                    ::core::result::Result<bevy_reflect::__macro_exports::alloc_utils::Box<dyn bevy_reflect::Reflect>,
                    bevy_reflect::__macro_exports::alloc_utils::Box<dyn bevy_reflect::PartialReflect>> {
                ::core::result::Result::Ok(self)
            }
            #[inline]
            fn try_as_reflect(&self)
                -> ::core::option::Option<&dyn bevy_reflect::Reflect> {
                ::core::option::Option::Some(self)
            }
            #[inline]
            fn try_as_reflect_mut(&mut self)
                -> ::core::option::Option<&mut dyn bevy_reflect::Reflect> {
                ::core::option::Option::Some(self)
            }
            #[inline]
            fn into_partial_reflect(self:
                    bevy_reflect::__macro_exports::alloc_utils::Box<Self>)
                ->
                    bevy_reflect::__macro_exports::alloc_utils::Box<dyn bevy_reflect::PartialReflect> {
                self
            }
            #[inline]
            fn as_partial_reflect(&self)
                -> &dyn bevy_reflect::PartialReflect {
                self
            }
            #[inline]
            fn as_partial_reflect_mut(&mut self)
                -> &mut dyn bevy_reflect::PartialReflect {
                self
            }
            fn reflect_partial_eq(&self,
                value: &dyn bevy_reflect::PartialReflect)
                -> ::core::option::Option<bool> {
                (bevy_reflect::structs::struct_partial_eq)(self, value)
            }
            fn reflect_partial_cmp(&self,
                value: &dyn bevy_reflect::PartialReflect)
                -> ::core::option::Option<::core::cmp::Ordering> {
                (bevy_reflect::structs::struct_partial_cmp)(self, value)
            }
            fn debug(&self, f: &mut ::core::fmt::Formatter<'_>)
                -> ::core::fmt::Result {
                ::core::fmt::Debug::fmt(self, f)
            }
            #[inline]
            #[allow(unreachable_code, reason =
            "Ignored fields without a `clone` attribute will early-return with an error")]
            fn reflect_clone(&self)
                ->
                    ::core::result::Result<bevy_reflect::__macro_exports::alloc_utils::Box<dyn bevy_reflect::Reflect>,
                    bevy_reflect::ReflectCloneError> {
                ::core::result::Result::Ok(bevy_reflect::__macro_exports::alloc_utils::Box::new(Self {
                            image: <Handle<Image> as
                                        bevy_reflect::PartialReflect>::reflect_clone_and_take(&self.image)?,
                            tiled: <bool as
                                        bevy_reflect::PartialReflect>::reflect_clone_and_take(&self.tiled)?,
                        }))
            }
        }
        impl bevy_reflect::FromReflect for DirectionalLightTexture where  {
            fn from_reflect(reflect: &dyn bevy_reflect::PartialReflect)
                -> ::core::option::Option<Self> {
                if let bevy_reflect::ReflectRef::Struct(__ref_struct) =
                        bevy_reflect::PartialReflect::reflect_ref(reflect) {
                    let __this =
                        Self {
                            image: <Handle<Image> as
                                        bevy_reflect::FromReflect>::from_reflect(bevy_reflect::structs::Struct::field(__ref_struct,
                                            "image")?)?,
                            tiled: <bool as
                                        bevy_reflect::FromReflect>::from_reflect(bevy_reflect::structs::Struct::field(__ref_struct,
                                            "tiled")?)?,
                        };
                    ::core::option::Option::Some(__this)
                } else { ::core::option::Option::None }
            }
        }
    };Reflect, impl ::core::default::Default for DirectionalLightTextureTemplate {
    fn default() -> Self {
        Self {
            image: ::core::default::Default::default(),
            tiled: ::core::default::Default::default(),
        }
    }
}FromTemplate)]
174#[reflect(Component, Debug)]
175#[require(DirectionalLight)]
176pub struct DirectionalLightTexture {
177    /// The texture image. Only the R channel is read.
178    pub image: Handle<Image>,
179    /// Whether to tile the image infinitely, or use only a single tile centered at the light's translation
180    pub tiled: bool,
181}
182
183/// Controls the resolution of [`DirectionalLight`] and [`SpotLight`](crate::SpotLight) shadow maps.
184///
185/// ```
186/// # use bevy_app::prelude::*;
187/// # use bevy_light::DirectionalLightShadowMap;
188/// App::new()
189///     .insert_resource(DirectionalLightShadowMap { size: 4096 });
190/// ```
191#[derive(impl bevy_ecs::resource::Resource for DirectionalLightShadowMap where
    Self: ::core::marker::Send + ::core::marker::Sync + 'static {}Resource, #[automatically_derived]
impl ::core::clone::Clone for DirectionalLightShadowMap {
    #[inline]
    fn clone(&self) -> DirectionalLightShadowMap {
        DirectionalLightShadowMap {
            size: ::core::clone::Clone::clone(&self.size),
        }
    }
}Clone, #[automatically_derived]
impl ::core::fmt::Debug for DirectionalLightShadowMap {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::debug_struct_field1_finish(f,
            "DirectionalLightShadowMap", "size", &&self.size)
    }
}Debug, const _: () =
    {
        impl bevy_reflect::GetTypeRegistration for DirectionalLightShadowMap
            where  {
            fn get_type_registration() -> bevy_reflect::TypeRegistration {
                let mut registration =
                    bevy_reflect::TypeRegistration::of::<Self>();
                registration.insert::<bevy_reflect::ReflectFromPtr>(bevy_reflect::FromType::<Self>::from_type());
                registration.insert::<bevy_reflect::ReflectFromReflect>(bevy_reflect::FromType::<Self>::from_type());
                registration.register_type_data::<ReflectResource, Self>();
                registration.register_type_data::<ReflectDefault, Self>();
                registration
            }
            #[inline(never)]
            fn register_type_dependencies(registry:
                    &mut bevy_reflect::TypeRegistry) {
                <usize as
                        bevy_reflect::__macro_exports::RegisterForReflection>::__register(registry);
            }
        }
        impl bevy_reflect::Typed for DirectionalLightShadowMap where  {
            #[inline]
            fn type_info() -> &'static bevy_reflect::TypeInfo {
                static CELL: bevy_reflect::utility::NonGenericTypeInfoCell =
                    bevy_reflect::utility::NonGenericTypeInfoCell::new();
                CELL.get_or_set(||
                        {
                            bevy_reflect::TypeInfo::Struct(bevy_reflect::structs::StructInfo::new::<Self>(&[bevy_reflect::NamedField::new::<usize>("size")]))
                        })
            }
        }
        #[allow(deprecated, reason =
        "derives on a deprecated type shouldn't be considered a usage")]
        impl bevy_reflect::TypePath for DirectionalLightShadowMap where  {
            fn type_path() -> &'static str {
                "bevy_light::directional_light::DirectionalLightShadowMap"
            }
            fn short_type_path() -> &'static str {
                "DirectionalLightShadowMap"
            }
            fn type_ident() -> ::core::option::Option<&'static str> {
                ::core::option::Option::Some("DirectionalLightShadowMap")
            }
            fn crate_name() -> ::core::option::Option<&'static str> {
                ::core::option::Option::Some("bevy_light::directional_light".split(':').next().unwrap())
            }
            fn module_path() -> ::core::option::Option<&'static str> {
                ::core::option::Option::Some("bevy_light::directional_light")
            }
        }
        impl bevy_reflect::Reflect for DirectionalLightShadowMap where  {
            #[inline]
            fn into_any(self:
                    bevy_reflect::__macro_exports::alloc_utils::Box<Self>)
                ->
                    bevy_reflect::__macro_exports::alloc_utils::Box<dyn ::core::any::Any> {
                self
            }
            #[inline]
            fn as_any(&self) -> &dyn ::core::any::Any { self }
            #[inline]
            fn as_any_mut(&mut self) -> &mut dyn ::core::any::Any { self }
            #[inline]
            fn into_reflect(self:
                    bevy_reflect::__macro_exports::alloc_utils::Box<Self>)
                ->
                    bevy_reflect::__macro_exports::alloc_utils::Box<dyn bevy_reflect::Reflect> {
                self
            }
            #[inline]
            fn as_reflect(&self) -> &dyn bevy_reflect::Reflect { self }
            #[inline]
            fn as_reflect_mut(&mut self) -> &mut dyn bevy_reflect::Reflect {
                self
            }
            #[inline]
            fn set(&mut self,
                value:
                    bevy_reflect::__macro_exports::alloc_utils::Box<dyn bevy_reflect::Reflect>)
                ->
                    ::core::result::Result<(),
                    bevy_reflect::__macro_exports::alloc_utils::Box<dyn bevy_reflect::Reflect>> {
                *self = <dyn bevy_reflect::Reflect>::take(value)?;
                ::core::result::Result::Ok(())
            }
        }
        #[allow(non_upper_case_globals)]
        const _: () =
            {
                static __INVENTORY: ::inventory::Node =
                    ::inventory::Node {
                        value: &{
                                bevy_reflect::__macro_exports::auto_register::AutomaticReflectRegistrations(<DirectionalLightShadowMap
                                        as
                                        bevy_reflect::__macro_exports::auto_register::RegisterForReflection>::__register)
                            },
                        next: ::inventory::__private::UnsafeCell::new(::inventory::__private::Option::None),
                    };
                #[link_section = ".text.startup"]
                unsafe extern "C" fn __ctor() {
                    unsafe {
                        ::inventory::ErasedNode::submit(__INVENTORY.value,
                            &__INVENTORY)
                    }
                }
                #[used]
                #[link_section = ".init_array"]
                static __CTOR: unsafe extern "C" fn() = __ctor;
            };
        impl bevy_reflect::structs::Struct for DirectionalLightShadowMap where
             {
            fn field(&self, name: &str)
                -> ::core::option::Option<&dyn bevy_reflect::PartialReflect> {
                match name {
                    "size" => ::core::option::Option::Some(&self.size),
                    _ => ::core::option::Option::None,
                }
            }
            fn field_mut(&mut self, name: &str)
                ->
                    ::core::option::Option<&mut dyn bevy_reflect::PartialReflect> {
                match name {
                    "size" => ::core::option::Option::Some(&mut self.size),
                    _ => ::core::option::Option::None,
                }
            }
            fn field_at(&self, index: usize)
                -> ::core::option::Option<&dyn bevy_reflect::PartialReflect> {
                match index {
                    0usize => ::core::option::Option::Some(&self.size),
                    _ => ::core::option::Option::None,
                }
            }
            fn field_at_mut(&mut self, index: usize)
                ->
                    ::core::option::Option<&mut dyn bevy_reflect::PartialReflect> {
                match index {
                    0usize => ::core::option::Option::Some(&mut self.size),
                    _ => ::core::option::Option::None,
                }
            }
            fn name_at(&self, index: usize) -> ::core::option::Option<&str> {
                match index {
                    0usize => ::core::option::Option::Some("size"),
                    _ => ::core::option::Option::None,
                }
            }
            fn index_of_name(&self, name: &str)
                -> ::core::option::Option<usize> {
                match name {
                    "size" => ::core::option::Option::Some(0usize),
                    _ => ::core::option::Option::None,
                }
            }
            fn field_len(&self) -> usize { 1usize }
            fn iter_fields(&self) -> bevy_reflect::structs::FieldIter {
                bevy_reflect::structs::FieldIter::new(self)
            }
            fn to_dynamic_struct(&self)
                -> bevy_reflect::structs::DynamicStruct {
                let mut dynamic: bevy_reflect::structs::DynamicStruct =
                    ::core::default::Default::default();
                dynamic.set_represented_type(bevy_reflect::PartialReflect::get_represented_type_info(self));
                dynamic.insert_boxed("size",
                    bevy_reflect::PartialReflect::to_dynamic(&self.size));
                dynamic
            }
        }
        impl bevy_reflect::PartialReflect for DirectionalLightShadowMap where
            {
            #[inline]
            fn get_represented_type_info(&self)
                -> ::core::option::Option<&'static bevy_reflect::TypeInfo> {
                ::core::option::Option::Some(<Self as
                            bevy_reflect::Typed>::type_info())
            }
            #[inline]
            fn try_apply(&mut self, value: &dyn bevy_reflect::PartialReflect)
                -> ::core::result::Result<(), bevy_reflect::ApplyError> {
                if let bevy_reflect::ReflectRef::Struct(struct_value) =
                        bevy_reflect::PartialReflect::reflect_ref(value) {
                    for (name, value) in
                        bevy_reflect::structs::Struct::iter_fields(struct_value) {
                        if let ::core::option::Option::Some(v) =
                                bevy_reflect::structs::Struct::field_mut(self, name) {
                            bevy_reflect::PartialReflect::try_apply(v, value)?;
                        }
                    }
                } else {
                    return ::core::result::Result::Err(bevy_reflect::ApplyError::MismatchedKinds {
                                from_kind: bevy_reflect::PartialReflect::reflect_kind(value),
                                to_kind: bevy_reflect::ReflectKind::Struct,
                            });
                }
                ::core::result::Result::Ok(())
            }
            #[inline]
            fn reflect_kind(&self) -> bevy_reflect::ReflectKind {
                bevy_reflect::ReflectKind::Struct
            }
            #[inline]
            fn reflect_ref(&self) -> bevy_reflect::ReflectRef {
                bevy_reflect::ReflectRef::Struct(self)
            }
            #[inline]
            fn reflect_mut(&mut self) -> bevy_reflect::ReflectMut {
                bevy_reflect::ReflectMut::Struct(self)
            }
            #[inline]
            fn reflect_owned(self:
                    bevy_reflect::__macro_exports::alloc_utils::Box<Self>)
                -> bevy_reflect::ReflectOwned {
                bevy_reflect::ReflectOwned::Struct(self)
            }
            #[inline]
            fn try_into_reflect(self:
                    bevy_reflect::__macro_exports::alloc_utils::Box<Self>)
                ->
                    ::core::result::Result<bevy_reflect::__macro_exports::alloc_utils::Box<dyn bevy_reflect::Reflect>,
                    bevy_reflect::__macro_exports::alloc_utils::Box<dyn bevy_reflect::PartialReflect>> {
                ::core::result::Result::Ok(self)
            }
            #[inline]
            fn try_as_reflect(&self)
                -> ::core::option::Option<&dyn bevy_reflect::Reflect> {
                ::core::option::Option::Some(self)
            }
            #[inline]
            fn try_as_reflect_mut(&mut self)
                -> ::core::option::Option<&mut dyn bevy_reflect::Reflect> {
                ::core::option::Option::Some(self)
            }
            #[inline]
            fn into_partial_reflect(self:
                    bevy_reflect::__macro_exports::alloc_utils::Box<Self>)
                ->
                    bevy_reflect::__macro_exports::alloc_utils::Box<dyn bevy_reflect::PartialReflect> {
                self
            }
            #[inline]
            fn as_partial_reflect(&self)
                -> &dyn bevy_reflect::PartialReflect {
                self
            }
            #[inline]
            fn as_partial_reflect_mut(&mut self)
                -> &mut dyn bevy_reflect::PartialReflect {
                self
            }
            fn reflect_partial_eq(&self,
                value: &dyn bevy_reflect::PartialReflect)
                -> ::core::option::Option<bool> {
                (bevy_reflect::structs::struct_partial_eq)(self, value)
            }
            fn reflect_partial_cmp(&self,
                value: &dyn bevy_reflect::PartialReflect)
                -> ::core::option::Option<::core::cmp::Ordering> {
                (bevy_reflect::structs::struct_partial_cmp)(self, value)
            }
            fn debug(&self, f: &mut ::core::fmt::Formatter<'_>)
                -> ::core::fmt::Result {
                ::core::fmt::Debug::fmt(self, f)
            }
            #[inline]
            fn reflect_clone(&self)
                ->
                    ::core::result::Result<bevy_reflect::__macro_exports::alloc_utils::Box<dyn bevy_reflect::Reflect>,
                    bevy_reflect::ReflectCloneError> {
                ::core::result::Result::Ok(bevy_reflect::__macro_exports::alloc_utils::Box::new(::core::clone::Clone::clone(self)))
            }
        }
        impl bevy_reflect::FromReflect for DirectionalLightShadowMap where  {
            fn from_reflect(reflect: &dyn bevy_reflect::PartialReflect)
                -> ::core::option::Option<Self> {
                if let bevy_reflect::ReflectRef::Struct(__ref_struct) =
                        bevy_reflect::PartialReflect::reflect_ref(reflect) {
                    let mut __this =
                        <Self as ::core::default::Default>::default();
                    if let ::core::option::Option::Some(__field) =
                            (||
                                        <usize as
                                                bevy_reflect::FromReflect>::from_reflect(bevy_reflect::structs::Struct::field(__ref_struct,
                                                    "size")?))() {
                        __this.size = __field;
                    }
                    ::core::option::Option::Some(__this)
                } else { ::core::option::Option::None }
            }
        }
    };Reflect)]
192#[reflect(Resource, Debug, Default, Clone)]
193pub struct DirectionalLightShadowMap {
194    // The width and height of each cascade.
195    ///
196    /// Must be a power of two to avoid unstable cascade positioning.
197    ///
198    /// Defaults to `2048`.
199    pub size: usize,
200}
201
202impl Default for DirectionalLightShadowMap {
203    fn default() -> Self {
204        Self { size: 2048 }
205    }
206}
207
208pub fn validate_shadow_map_size(mut shadow_map: ResMut<DirectionalLightShadowMap>) {
209    if shadow_map.is_changed() && !shadow_map.size.is_power_of_two() {
210        let new_size = shadow_map.size.next_power_of_two();
211        {
    use ::tracing::__macro_support::Callsite as _;
    static __CALLSITE: ::tracing::callsite::DefaultCallsite =
        {
            static META: ::tracing::Metadata<'static> =
                {
                    ::tracing_core::metadata::Metadata::new("event src/directional_light.rs:211",
                        "bevy_light::directional_light", ::tracing::Level::WARN,
                        ::tracing_core::__macro_support::Option::Some("src/directional_light.rs"),
                        ::tracing_core::__macro_support::Option::Some(211u32),
                        ::tracing_core::__macro_support::Option::Some("bevy_light::directional_light"),
                        ::tracing_core::field::FieldSet::new(&["message"],
                            ::tracing_core::callsite::Identifier(&__CALLSITE)),
                        ::tracing::metadata::Kind::EVENT)
                };
            ::tracing::callsite::DefaultCallsite::new(&META)
        };
    let enabled =
        ::tracing::Level::WARN <= ::tracing::level_filters::STATIC_MAX_LEVEL
                &&
                ::tracing::Level::WARN <=
                    ::tracing::level_filters::LevelFilter::current() &&
            {
                let interest = __CALLSITE.interest();
                !interest.is_never() &&
                    ::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
                        interest)
            };
    if enabled {
        (|value_set: ::tracing::field::ValueSet|
                    {
                        let meta = __CALLSITE.metadata();
                        ::tracing::Event::dispatch(meta, &value_set);
                        ;
                    })({
                #[allow(unused_imports)]
                use ::tracing::field::{debug, display, Value};
                __CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&format_args!("Non-power-of-two DirectionalLightShadowMap sizes are not supported, correcting {0} to {1}",
                                                    shadow_map.size, new_size) as
                                            &dyn ::tracing::field::Value))])
            });
    } else { ; }
};warn!("Non-power-of-two DirectionalLightShadowMap sizes are not supported, correcting {} to {new_size}", shadow_map.size);
212        shadow_map.size = new_size;
213    }
214}
215
216/// Updates the frusta for all visible shadow mapped [`DirectionalLight`]s.
217pub fn update_directional_light_frusta(
218    mut views: Query<
219        (
220            &Cascades,
221            &DirectionalLight,
222            &ViewVisibility,
223            &mut CascadesFrusta,
224        ),
225        (
226            // Prevents this query from conflicting with camera queries.
227            Without<Camera>,
228        ),
229    >,
230) {
231    for (cascades, directional_light, visibility, mut frusta) in &mut views {
232        // The frustum is used for culling meshes to the light for shadow mapping
233        // so if shadow mapping is disabled for this light, then the frustum is
234        // not needed.
235        if !directional_light.shadow_maps_enabled || !visibility.get() {
236            continue;
237        }
238
239        frusta.frusta = cascades
240            .cascades
241            .iter()
242            .map(|(view, cascades)| {
243                (
244                    *view,
245                    cascades
246                        .iter()
247                        .map(|c| Frustum(ViewFrustum::from_clip_from_world(&c.clip_from_world)))
248                        .collect::<Vec<_>>(),
249                )
250            })
251            .collect();
252    }
253}
254
255/// Add to a [`DirectionalLight`] to control rendering of the visible solar disk in the sky.
256/// Affects only the disk’s appearance, not the light’s illuminance or shadows.
257/// Requires a `bevy::pbr::Atmosphere` component on a [`Camera3d`](bevy_camera::Camera3d) to have any effect.
258///
259/// By default, the atmosphere is rendered with [`SunDisk::EARTH`], which approximates the
260/// apparent size and brightness of the Sun as seen from Earth. You can also disable the sun
261/// disk entirely with [`SunDisk::OFF`].
262///
263/// In order to cause the sun to "glow" and light up the surrounding sky, enable bloom
264/// in your post-processing pipeline by adding a `Bloom` component to your camera.
265#[derive(#[doc =
"**Required Components**: [`DirectionalLight`]. \n\n A component's Required Components are inserted whenever it is inserted. Note that this will also insert the required components _of_ the required components, recursively, in depth-first order."]
impl bevy_ecs::component::Component for SunDisk where
    Self: ::core::marker::Send + ::core::marker::Sync + 'static {
    const STORAGE_TYPE: bevy_ecs::component::StorageType =
        bevy_ecs::component::StorageType::Table;
    type Mutability = bevy_ecs::component::Mutable;
    fn register_required_components(_requiree:
            bevy_ecs::component::ComponentId,
        required_components:
            &mut bevy_ecs::component::RequiredComponentsRegistrator) {
        required_components.register_required::<DirectionalLight>(<DirectionalLight
                as ::core::default::Default>::default);
    }
    fn clone_behavior() -> bevy_ecs::component::ComponentCloneBehavior {
        use bevy_ecs::component::{
            DefaultCloneBehaviorBase, DefaultCloneBehaviorViaClone,
        };
        (&&&bevy_ecs::component::DefaultCloneBehaviorSpecialization::<Self>::default()).default_clone_behavior()
    }
    fn relationship_accessor()
        ->
            ::core::option::Option<bevy_ecs::relationship::ComponentRelationshipAccessor<Self>> {
        ::core::option::Option::None
    }
}Component, #[automatically_derived]
impl ::core::clone::Clone for SunDisk {
    #[inline]
    fn clone(&self) -> SunDisk {
        SunDisk {
            angular_size: ::core::clone::Clone::clone(&self.angular_size),
            intensity: ::core::clone::Clone::clone(&self.intensity),
        }
    }
}Clone)]
266#[require(DirectionalLight)]
267pub struct SunDisk {
268    /// The angular size (diameter) of the sun disk in radians, as observed from the scene.
269    pub angular_size: f32,
270    /// Multiplier for the brightness of the sun disk.
271    ///
272    /// `0.0` disables the disk entirely (atmospheric scattering still occurs),
273    /// `1.0` is the default physical intensity, and values `>1.0` overexpose it.
274    pub intensity: f32,
275}
276
277impl SunDisk {
278    /// Earth-like parameters for the sun disk.
279    ///
280    /// Uses the mean apparent size (~32 arcminutes) of the Sun at 1 AU distance
281    /// with default intensity.
282    pub const EARTH: SunDisk = SunDisk {
283        angular_size: 0.00930842,
284        intensity: 1.0,
285    };
286
287    /// No visible sun disk.
288    ///
289    /// Keeps scattering and directional light illumination, but hides the disk itself.
290    pub const OFF: SunDisk = SunDisk {
291        angular_size: 0.0,
292        intensity: 0.0,
293    };
294}
295
296impl Default for SunDisk {
297    fn default() -> Self {
298        Self::EARTH
299    }
300}
301
302impl Default for &SunDisk {
303    fn default() -> Self {
304        &SunDisk::EARTH
305    }
306}