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}