Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
bevyengine
GitHub Repository: bevyengine/bevy
Path: blob/main/crates/bevy_light/src/probe.rs
6598 views
1
use bevy_asset::Handle;
2
use bevy_camera::visibility::Visibility;
3
use bevy_ecs::prelude::*;
4
use bevy_image::Image;
5
use bevy_math::{Quat, UVec2};
6
use bevy_reflect::prelude::*;
7
use bevy_transform::components::Transform;
8
9
/// A marker component for a light probe, which is a cuboid region that provides
10
/// global illumination to all fragments inside it.
11
///
12
/// Note that a light probe will have no effect unless the entity contains some
13
/// kind of illumination, which can either be an [`EnvironmentMapLight`] or an
14
/// [`IrradianceVolume`].
15
///
16
/// The light probe range is conceptually a unit cube (1×1×1) centered on the
17
/// origin. The [`Transform`] applied to this entity can scale, rotate, or translate
18
/// that cube so that it contains all fragments that should take this light probe into account.
19
///
20
/// When multiple sources of indirect illumination can be applied to a fragment,
21
/// the highest-quality one is chosen. Diffuse and specular illumination are
22
/// considered separately, so, for example, Bevy may decide to sample the
23
/// diffuse illumination from an irradiance volume and the specular illumination
24
/// from a reflection probe. From highest priority to lowest priority, the
25
/// ranking is as follows:
26
///
27
/// | Rank | Diffuse | Specular |
28
/// | ---- | -------------------- | -------------------- |
29
/// | 1 | Lightmap | Lightmap |
30
/// | 2 | Irradiance volume | Reflection probe |
31
/// | 3 | Reflection probe | View environment map |
32
/// | 4 | View environment map | |
33
///
34
/// Note that ambient light is always added to the diffuse component and does
35
/// not participate in the ranking. That is, ambient light is applied in
36
/// addition to, not instead of, the light sources above.
37
///
38
/// A terminology note: Unfortunately, there is little agreement across game and
39
/// graphics engines as to what to call the various techniques that Bevy groups
40
/// under the term *light probe*. In Bevy, a *light probe* is the generic term
41
/// that encompasses both *reflection probes* and *irradiance volumes*. In
42
/// object-oriented terms, *light probe* is the superclass, and *reflection
43
/// probe* and *irradiance volume* are subclasses. In other engines, you may see
44
/// the term *light probe* refer to an irradiance volume with a single voxel, or
45
/// perhaps some other technique, while in Bevy *light probe* refers not to a
46
/// specific technique but rather to a class of techniques. Developers familiar
47
/// with other engines should be aware of this terminology difference.
48
#[derive(Component, Debug, Clone, Copy, Default, Reflect)]
49
#[reflect(Component, Default, Debug, Clone)]
50
#[require(Transform, Visibility)]
51
pub struct LightProbe;
52
53
impl LightProbe {
54
/// Creates a new light probe component.
55
#[inline]
56
pub fn new() -> Self {
57
Self
58
}
59
}
60
61
/// A pair of cubemap textures that represent the surroundings of a specific
62
/// area in space.
63
///
64
/// See `bevy_pbr::environment_map` for detailed information.
65
#[derive(Clone, Component, Reflect)]
66
#[reflect(Component, Default, Clone)]
67
pub struct EnvironmentMapLight {
68
/// The blurry image that represents diffuse radiance surrounding a region.
69
pub diffuse_map: Handle<Image>,
70
71
/// The typically-sharper, mipmapped image that represents specular radiance
72
/// surrounding a region.
73
pub specular_map: Handle<Image>,
74
75
/// Scale factor applied to the diffuse and specular light generated by this component.
76
///
77
/// After applying this multiplier, the resulting values should
78
/// be in units of [cd/m^2](https://en.wikipedia.org/wiki/Candela_per_square_metre).
79
///
80
/// See also <https://google.github.io/filament/Filament.html#lighting/imagebasedlights/iblunit>.
81
pub intensity: f32,
82
83
/// World space rotation applied to the environment light cubemaps.
84
/// This is useful for users who require a different axis, such as the Z-axis, to serve
85
/// as the vertical axis.
86
pub rotation: Quat,
87
88
/// Whether the light from this environment map contributes diffuse lighting
89
/// to meshes with lightmaps.
90
///
91
/// Set this to false if your lightmap baking tool bakes the diffuse light
92
/// from this environment light into the lightmaps in order to avoid
93
/// counting the radiance from this environment map twice.
94
///
95
/// By default, this is set to true.
96
pub affects_lightmapped_mesh_diffuse: bool,
97
}
98
99
impl Default for EnvironmentMapLight {
100
fn default() -> Self {
101
EnvironmentMapLight {
102
diffuse_map: Handle::default(),
103
specular_map: Handle::default(),
104
intensity: 0.0,
105
rotation: Quat::IDENTITY,
106
affects_lightmapped_mesh_diffuse: true,
107
}
108
}
109
}
110
111
/// A generated environment map that is filtered at runtime.
112
///
113
/// See `bevy_pbr::light_probe::generate` for detailed information.
114
#[derive(Clone, Component, Reflect)]
115
#[reflect(Component, Default, Clone)]
116
pub struct GeneratedEnvironmentMapLight {
117
/// Source cubemap to be filtered on the GPU, size must be a power of two.
118
pub environment_map: Handle<Image>,
119
120
/// Scale factor applied to the diffuse and specular light generated by this
121
/// component. Expressed in cd/m² (candela per square meter).
122
pub intensity: f32,
123
124
/// World-space rotation applied to the cubemap.
125
pub rotation: Quat,
126
127
/// Whether this light contributes diffuse lighting to meshes that already
128
/// have baked lightmaps.
129
pub affects_lightmapped_mesh_diffuse: bool,
130
}
131
132
impl Default for GeneratedEnvironmentMapLight {
133
fn default() -> Self {
134
GeneratedEnvironmentMapLight {
135
environment_map: Handle::default(),
136
intensity: 0.0,
137
rotation: Quat::IDENTITY,
138
affects_lightmapped_mesh_diffuse: true,
139
}
140
}
141
}
142
143
/// Lets the atmosphere contribute environment lighting (reflections and ambient diffuse) to your scene.
144
///
145
/// Attach this to a [`Camera3d`](bevy_camera::Camera3d) to light the entire view, or to a
146
/// [`LightProbe`] to light only a specific region.
147
/// Behind the scenes, this generates an environment map from the atmosphere for image-based lighting
148
/// and inserts a corresponding [`GeneratedEnvironmentMapLight`].
149
///
150
/// For HDRI-based lighting, use a preauthored [`EnvironmentMapLight`] or filter one at runtime with
151
/// [`GeneratedEnvironmentMapLight`].
152
#[derive(Component, Clone)]
153
pub struct AtmosphereEnvironmentMapLight {
154
/// Controls how bright the atmosphere's environment lighting is.
155
/// Increase this value to brighten reflections and ambient diffuse lighting.
156
///
157
/// The default is `1.0` so that the generated environment lighting matches
158
/// the light intensity of the atmosphere in the scene.
159
pub intensity: f32,
160
/// Whether the diffuse contribution should affect meshes that already have lightmaps.
161
pub affects_lightmapped_mesh_diffuse: bool,
162
/// Cubemap resolution in pixels (must be a power-of-two).
163
pub size: UVec2,
164
}
165
166
impl Default for AtmosphereEnvironmentMapLight {
167
fn default() -> Self {
168
Self {
169
intensity: 1.0,
170
affects_lightmapped_mesh_diffuse: true,
171
size: UVec2::new(512, 512),
172
}
173
}
174
}
175
176
/// The component that defines an irradiance volume.
177
///
178
/// See `bevy_pbr::irradiance_volume` for detailed information.
179
///
180
/// This component requires the [`LightProbe`] component, and is typically used with
181
/// [`bevy_transform::components::Transform`] to place the volume appropriately.
182
#[derive(Clone, Reflect, Component, Debug)]
183
#[reflect(Component, Default, Debug, Clone)]
184
#[require(LightProbe)]
185
pub struct IrradianceVolume {
186
/// The 3D texture that represents the ambient cubes, encoded in the format
187
/// described in `bevy_pbr::irradiance_volume`.
188
pub voxels: Handle<Image>,
189
190
/// Scale factor applied to the diffuse and specular light generated by this component.
191
///
192
/// After applying this multiplier, the resulting values should
193
/// be in units of [cd/m^2](https://en.wikipedia.org/wiki/Candela_per_square_metre).
194
///
195
/// See also <https://google.github.io/filament/Filament.html#lighting/imagebasedlights/iblunit>.
196
pub intensity: f32,
197
198
/// Whether the light from this irradiance volume has an effect on meshes
199
/// with lightmaps.
200
///
201
/// Set this to false if your lightmap baking tool bakes the light from this
202
/// irradiance volume into the lightmaps in order to avoid counting the
203
/// irradiance twice. Frequently, applications use irradiance volumes as a
204
/// lower-quality alternative to lightmaps for capturing indirect
205
/// illumination on dynamic objects, and such applications will want to set
206
/// this value to false.
207
///
208
/// By default, this is set to true.
209
pub affects_lightmapped_meshes: bool,
210
}
211
212
impl Default for IrradianceVolume {
213
#[inline]
214
fn default() -> Self {
215
IrradianceVolume {
216
voxels: Handle::default(),
217
intensity: 0.0,
218
affects_lightmapped_meshes: true,
219
}
220
}
221
}
222
223