bevy_pbr/light/
directional_light.rs

1use bevy_render::view::{self, Visibility};
2
3use super::*;
4
5/// A Directional light.
6///
7/// Directional lights don't exist in reality but they are a good
8/// approximation for light sources VERY far away, like the sun or
9/// the moon.
10///
11/// The light shines along the forward direction of the entity's transform. With a default transform
12/// this would be along the negative-Z axis.
13///
14/// Valid values for `illuminance` are:
15///
16/// | Illuminance (lux) | Surfaces illuminated by                        |
17/// |-------------------|------------------------------------------------|
18/// | 0.0001            | Moonless, overcast night sky (starlight)       |
19/// | 0.002             | Moonless clear night sky with airglow          |
20/// | 0.05–0.3          | Full moon on a clear night                     |
21/// | 3.4               | Dark limit of civil twilight under a clear sky |
22/// | 20–50             | Public areas with dark surroundings            |
23/// | 50                | Family living room lights                      |
24/// | 80                | Office building hallway/toilet lighting        |
25/// | 100               | Very dark overcast day                         |
26/// | 150               | Train station platforms                        |
27/// | 320–500           | Office lighting                                |
28/// | 400               | Sunrise or sunset on a clear day.              |
29/// | 1000              | Overcast day; typical TV studio lighting       |
30/// | 10,000–25,000     | Full daylight (not direct sun)                 |
31/// | 32,000–100,000    | Direct sunlight                                |
32///
33/// Source: [Wikipedia](https://en.wikipedia.org/wiki/Lux)
34///
35/// ## Shadows
36///
37/// To enable shadows, set the `shadows_enabled` property to `true`.
38///
39/// 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).
40///
41/// To modify the cascade setup, such as the number of cascades or the maximum shadow distance,
42/// change the [`CascadeShadowConfig`] component of the entity with the [`DirectionalLight`].
43///
44/// To control the resolution of the shadow maps, use the [`DirectionalLightShadowMap`] resource.
45#[derive(Component, Debug, Clone, Reflect)]
46#[reflect(Component, Default, Debug, Clone)]
47#[require(
48    Cascades,
49    CascadesFrusta,
50    CascadeShadowConfig,
51    CascadesVisibleEntities,
52    Transform,
53    Visibility,
54    VisibilityClass
55)]
56#[component(on_add = view::add_visibility_class::<LightVisibilityClass>)]
57pub struct DirectionalLight {
58    /// The color of the light.
59    ///
60    /// By default, this is white.
61    pub color: Color,
62
63    /// Illuminance in lux (lumens per square meter), representing the amount of
64    /// light projected onto surfaces by this light source. Lux is used here
65    /// instead of lumens because a directional light illuminates all surfaces
66    /// more-or-less the same way (depending on the angle of incidence). Lumens
67    /// can only be specified for light sources which emit light from a specific
68    /// area.
69    pub illuminance: f32,
70
71    /// Whether this light casts shadows.
72    ///
73    /// Note that shadows are rather expensive and become more so with every
74    /// light that casts them. In general, it's best to aggressively limit the
75    /// number of lights with shadows enabled to one or two at most.
76    pub shadows_enabled: bool,
77
78    /// Whether soft shadows are enabled, and if so, the size of the light.
79    ///
80    /// Soft shadows, also known as *percentage-closer soft shadows* or PCSS,
81    /// cause shadows to become blurrier (i.e. their penumbra increases in
82    /// radius) as they extend away from objects. The blurriness of the shadow
83    /// depends on the size of the light; larger lights result in larger
84    /// penumbras and therefore blurrier shadows.
85    ///
86    /// Currently, soft shadows are rather noisy if not using the temporal mode.
87    /// If you enable soft shadows, consider choosing
88    /// [`ShadowFilteringMethod::Temporal`] and enabling temporal antialiasing
89    /// (TAA) to smooth the noise out over time.
90    ///
91    /// Note that soft shadows are significantly more expensive to render than
92    /// hard shadows.
93    #[cfg(feature = "experimental_pbr_pcss")]
94    pub soft_shadow_size: Option<f32>,
95
96    /// Whether this directional light contributes diffuse lighting to meshes
97    /// with lightmaps.
98    ///
99    /// Set this to false if your lightmap baking tool bakes the direct diffuse
100    /// light from this directional light into the lightmaps in order to avoid
101    /// counting the radiance from this light twice. Note that the specular
102    /// portion of the light is always considered, because Bevy currently has no
103    /// means to bake specular light.
104    ///
105    /// By default, this is set to true.
106    pub affects_lightmapped_mesh_diffuse: bool,
107
108    /// A value that adjusts the tradeoff between self-shadowing artifacts and
109    /// proximity of shadows to their casters.
110    ///
111    /// This value frequently must be tuned to the specific scene; this is
112    /// normal and a well-known part of the shadow mapping workflow. If set too
113    /// low, unsightly shadow patterns appear on objects not in shadow as
114    /// objects incorrectly cast shadows on themselves, known as *shadow acne*.
115    /// If set too high, shadows detach from the objects casting them and seem
116    /// to "fly" off the objects, known as *Peter Panning*.
117    pub shadow_depth_bias: f32,
118
119    /// A bias applied along the direction of the fragment's surface normal. It
120    /// is scaled to the shadow map's texel size so that it is automatically
121    /// adjusted to the orthographic projection.
122    pub shadow_normal_bias: f32,
123}
124
125impl Default for DirectionalLight {
126    fn default() -> Self {
127        DirectionalLight {
128            color: Color::WHITE,
129            illuminance: light_consts::lux::AMBIENT_DAYLIGHT,
130            shadows_enabled: false,
131            shadow_depth_bias: Self::DEFAULT_SHADOW_DEPTH_BIAS,
132            shadow_normal_bias: Self::DEFAULT_SHADOW_NORMAL_BIAS,
133            affects_lightmapped_mesh_diffuse: true,
134            #[cfg(feature = "experimental_pbr_pcss")]
135            soft_shadow_size: None,
136        }
137    }
138}
139
140impl DirectionalLight {
141    pub const DEFAULT_SHADOW_DEPTH_BIAS: f32 = 0.02;
142    pub const DEFAULT_SHADOW_NORMAL_BIAS: f32 = 1.8;
143}