bevy_pbr/light/point_light.rs
1use bevy_render::view::Visibility;
2
3use super::*;
4
5/// A light that emits light in all directions from a central point.
6///
7/// Real-world values for `intensity` (luminous power in lumens) based on the electrical power
8/// consumption of the type of real-world light are:
9///
10/// | Luminous Power (lumen) (i.e. the intensity member) | Incandescent non-halogen (Watts) | Incandescent halogen (Watts) | Compact fluorescent (Watts) | LED (Watts) |
11/// |------|-----|----|--------|-------|
12/// | 200 | 25 | | 3-5 | 3 |
13/// | 450 | 40 | 29 | 9-11 | 5-8 |
14/// | 800 | 60 | | 13-15 | 8-12 |
15/// | 1100 | 75 | 53 | 18-20 | 10-16 |
16/// | 1600 | 100 | 72 | 24-28 | 14-17 |
17/// | 2400 | 150 | | 30-52 | 24-30 |
18/// | 3100 | 200 | | 49-75 | 32 |
19/// | 4000 | 300 | | 75-100 | 40.5 |
20///
21/// Source: [Wikipedia](https://en.wikipedia.org/wiki/Lumen_(unit)#Lighting)
22#[derive(Component, Debug, Clone, Copy, Reflect)]
23#[reflect(Component, Default, Debug)]
24#[require(CubemapFrusta, CubemapVisibleEntities, Transform, Visibility)]
25pub struct PointLight {
26 /// The color of this light source.
27 pub color: Color,
28
29 /// Luminous power in lumens, representing the amount of light emitted by this source in all directions.
30 pub intensity: f32,
31
32 /// Cut-off for the light's area-of-effect. Fragments outside this range will not be affected by
33 /// this light at all, so it's important to tune this together with `intensity` to prevent hard
34 /// lighting cut-offs.
35 pub range: f32,
36
37 /// Simulates a light source coming from a spherical volume with the given
38 /// radius.
39 ///
40 /// This affects the size of specular highlights created by this light, as
41 /// well as the soft shadow penumbra size. Because of this, large values may
42 /// not produce the intended result -- for example, light radius does not
43 /// affect shadow softness or diffuse lighting.
44 pub radius: f32,
45
46 /// Whether this light casts shadows.
47 pub shadows_enabled: bool,
48
49 /// Whether soft shadows are enabled.
50 ///
51 /// Soft shadows, also known as *percentage-closer soft shadows* or PCSS,
52 /// cause shadows to become blurrier (i.e. their penumbra increases in
53 /// radius) as they extend away from objects. The blurriness of the shadow
54 /// depends on the [`PointLight::radius`] of the light; larger lights result
55 /// in larger penumbras and therefore blurrier shadows.
56 ///
57 /// Currently, soft shadows are rather noisy if not using the temporal mode.
58 /// If you enable soft shadows, consider choosing
59 /// [`ShadowFilteringMethod::Temporal`] and enabling temporal antialiasing
60 /// (TAA) to smooth the noise out over time.
61 ///
62 /// Note that soft shadows are significantly more expensive to render than
63 /// hard shadows.
64 #[cfg(feature = "experimental_pbr_pcss")]
65 pub soft_shadows_enabled: bool,
66
67 /// A bias used when sampling shadow maps to avoid "shadow-acne", or false shadow occlusions
68 /// that happen as a result of shadow-map fragments not mapping 1:1 to screen-space fragments.
69 /// Too high of a depth bias can lead to shadows detaching from their casters, or
70 /// "peter-panning". This bias can be tuned together with `shadow_normal_bias` to correct shadow
71 /// artifacts for a given scene.
72 pub shadow_depth_bias: f32,
73
74 /// A bias applied along the direction of the fragment's surface normal. It is scaled to the
75 /// shadow map's texel size so that it can be small close to the camera and gets larger further
76 /// away.
77 pub shadow_normal_bias: f32,
78
79 /// The distance from the light to near Z plane in the shadow map.
80 ///
81 /// Objects closer than this distance to the light won't cast shadows.
82 /// Setting this higher increases the shadow map's precision.
83 ///
84 /// This only has an effect if shadows are enabled.
85 pub shadow_map_near_z: f32,
86}
87
88impl Default for PointLight {
89 fn default() -> Self {
90 PointLight {
91 color: Color::WHITE,
92 // 1,000,000 lumens is a very large "cinema light" capable of registering brightly at Bevy's
93 // default "very overcast day" exposure level. For "indoor lighting" with a lower exposure,
94 // this would be way too bright.
95 intensity: 1_000_000.0,
96 range: 20.0,
97 radius: 0.0,
98 shadows_enabled: false,
99 shadow_depth_bias: Self::DEFAULT_SHADOW_DEPTH_BIAS,
100 shadow_normal_bias: Self::DEFAULT_SHADOW_NORMAL_BIAS,
101 shadow_map_near_z: Self::DEFAULT_SHADOW_MAP_NEAR_Z,
102 #[cfg(feature = "experimental_pbr_pcss")]
103 soft_shadows_enabled: false,
104 }
105 }
106}
107
108impl PointLight {
109 pub const DEFAULT_SHADOW_DEPTH_BIAS: f32 = 0.08;
110 pub const DEFAULT_SHADOW_NORMAL_BIAS: f32 = 0.6;
111 pub const DEFAULT_SHADOW_MAP_NEAR_Z: f32 = 0.1;
112}