bevy_pbr/light/directional_light.rs
1use bevy_render::view::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///
46/// ```
47/// # use bevy_app::prelude::*;
48/// # use bevy_pbr::DirectionalLightShadowMap;
49/// App::new()
50/// .insert_resource(DirectionalLightShadowMap { size: 2048 });
51/// ```
52#[derive(Component, Debug, Clone, Reflect)]
53#[reflect(Component, Default, Debug)]
54#[require(
55 Cascades,
56 CascadesFrusta,
57 CascadeShadowConfig,
58 CascadesVisibleEntities,
59 Transform,
60 Visibility
61)]
62pub struct DirectionalLight {
63 /// The color of the light.
64 ///
65 /// By default, this is white.
66 pub color: Color,
67
68 /// Illuminance in lux (lumens per square meter), representing the amount of
69 /// light projected onto surfaces by this light source. Lux is used here
70 /// instead of lumens because a directional light illuminates all surfaces
71 /// more-or-less the same way (depending on the angle of incidence). Lumens
72 /// can only be specified for light sources which emit light from a specific
73 /// area.
74 pub illuminance: f32,
75
76 /// Whether this light casts shadows.
77 ///
78 /// Note that shadows are rather expensive and become more so with every
79 /// light that casts them. In general, it's best to aggressively limit the
80 /// number of lights with shadows enabled to one or two at most.
81 pub shadows_enabled: bool,
82
83 /// Whether soft shadows are enabled, and if so, the size of the light.
84 ///
85 /// Soft shadows, also known as *percentage-closer soft shadows* or PCSS,
86 /// cause shadows to become blurrier (i.e. their penumbra increases in
87 /// radius) as they extend away from objects. The blurriness of the shadow
88 /// depends on the size of the light; larger lights result in larger
89 /// penumbras and therefore blurrier shadows.
90 ///
91 /// Currently, soft shadows are rather noisy if not using the temporal mode.
92 /// If you enable soft shadows, consider choosing
93 /// [`ShadowFilteringMethod::Temporal`] and enabling temporal antialiasing
94 /// (TAA) to smooth the noise out over time.
95 ///
96 /// Note that soft shadows are significantly more expensive to render than
97 /// hard shadows.
98 #[cfg(feature = "experimental_pbr_pcss")]
99 pub soft_shadow_size: Option<f32>,
100
101 /// A value that adjusts the tradeoff between self-shadowing artifacts and
102 /// proximity of shadows to their casters.
103 ///
104 /// This value frequently must be tuned to the specific scene; this is
105 /// normal and a well-known part of the shadow mapping workflow. If set too
106 /// low, unsightly shadow patterns appear on objects not in shadow as
107 /// objects incorrectly cast shadows on themselves, known as *shadow acne*.
108 /// If set too high, shadows detach from the objects casting them and seem
109 /// to "fly" off the objects, known as *Peter Panning*.
110 pub shadow_depth_bias: f32,
111
112 /// A bias applied along the direction of the fragment's surface normal. It
113 /// is scaled to the shadow map's texel size so that it is automatically
114 /// adjusted to the orthographic projection.
115 pub shadow_normal_bias: f32,
116}
117
118impl Default for DirectionalLight {
119 fn default() -> Self {
120 DirectionalLight {
121 color: Color::WHITE,
122 illuminance: light_consts::lux::AMBIENT_DAYLIGHT,
123 shadows_enabled: false,
124 shadow_depth_bias: Self::DEFAULT_SHADOW_DEPTH_BIAS,
125 shadow_normal_bias: Self::DEFAULT_SHADOW_NORMAL_BIAS,
126 #[cfg(feature = "experimental_pbr_pcss")]
127 soft_shadow_size: None,
128 }
129 }
130}
131
132impl DirectionalLight {
133 pub const DEFAULT_SHADOW_DEPTH_BIAS: f32 = 0.02;
134 pub const DEFAULT_SHADOW_NORMAL_BIAS: f32 = 1.8;
135}