Skip to content

Commit

Permalink
Migrate lights to required components (#15554)
Browse files Browse the repository at this point in the history
# Objective

Another step in the migration to required components: lights!

Note that this does not include `EnvironmentMapLight` or reflection
probes yet, because their API hasn't been fully chosen yet.

## Solution

As per the [selected
proposals](https://hackmd.io/@bevy/required_components/%2FLLnzwz9XTxiD7i2jiUXkJg):

- Deprecate `PointLightBundle` in favor of the `PointLight` component
- Deprecate `SpotLightBundle` in favor of the `PointLight` component
- Deprecate `DirectionalLightBundle` in favor of the `DirectionalLight`
component

## Testing

I ran some examples with lights.

---

## Migration Guide

`PointLightBundle`, `SpotLightBundle`, and `DirectionalLightBundle` have
been deprecated. Use the `PointLight`, `SpotLight`, and
`DirectionalLight` components instead. Adding them will now insert the
other components required by them automatically.
  • Loading branch information
Jondolf authored Oct 1, 2024
1 parent 383c2e5 commit de888a3
Show file tree
Hide file tree
Showing 104 changed files with 538 additions and 720 deletions.
58 changes: 24 additions & 34 deletions crates/bevy_gltf/src/loader.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,7 @@ use bevy_ecs::{
use bevy_hierarchy::{BuildChildren, ChildBuild, WorldChildBuilder};
use bevy_math::{Affine2, Mat4, Vec3};
use bevy_pbr::{
DirectionalLight, DirectionalLightBundle, PbrBundle, PointLight, PointLightBundle, SpotLight,
SpotLightBundle, StandardMaterial, UvChannel, MAX_JOINTS,
DirectionalLight, PbrBundle, PointLight, SpotLight, StandardMaterial, UvChannel, MAX_JOINTS,
};
use bevy_render::{
alpha::AlphaMode,
Expand Down Expand Up @@ -1523,14 +1522,11 @@ fn load_node(
if let Some(light) = gltf_node.light() {
match light.kind() {
gltf::khr_lights_punctual::Kind::Directional => {
let mut entity = parent.spawn(DirectionalLightBundle {
directional_light: DirectionalLight {
color: Color::srgb_from_array(light.color()),
// NOTE: KHR_punctual_lights defines the intensity units for directional
// lights in lux (lm/m^2) which is what we need.
illuminance: light.intensity(),
..Default::default()
},
let mut entity = parent.spawn(DirectionalLight {
color: Color::srgb_from_array(light.color()),
// NOTE: KHR_punctual_lights defines the intensity units for directional
// lights in lux (lm/m^2) which is what we need.
illuminance: light.intensity(),
..Default::default()
});
if let Some(name) = light.name() {
Expand All @@ -1543,17 +1539,14 @@ fn load_node(
}
}
gltf::khr_lights_punctual::Kind::Point => {
let mut entity = parent.spawn(PointLightBundle {
point_light: PointLight {
color: Color::srgb_from_array(light.color()),
// NOTE: KHR_punctual_lights defines the intensity units for point lights in
// candela (lm/sr) which is luminous intensity and we need luminous power.
// For a point light, luminous power = 4 * pi * luminous intensity
intensity: light.intensity() * core::f32::consts::PI * 4.0,
range: light.range().unwrap_or(20.0),
radius: 0.0,
..Default::default()
},
let mut entity = parent.spawn(PointLight {
color: Color::srgb_from_array(light.color()),
// NOTE: KHR_punctual_lights defines the intensity units for point lights in
// candela (lm/sr) which is luminous intensity and we need luminous power.
// For a point light, luminous power = 4 * pi * luminous intensity
intensity: light.intensity() * core::f32::consts::PI * 4.0,
range: light.range().unwrap_or(20.0),
radius: 0.0,
..Default::default()
});
if let Some(name) = light.name() {
Expand All @@ -1569,19 +1562,16 @@ fn load_node(
inner_cone_angle,
outer_cone_angle,
} => {
let mut entity = parent.spawn(SpotLightBundle {
spot_light: SpotLight {
color: Color::srgb_from_array(light.color()),
// NOTE: KHR_punctual_lights defines the intensity units for spot lights in
// candela (lm/sr) which is luminous intensity and we need luminous power.
// For a spot light, we map luminous power = 4 * pi * luminous intensity
intensity: light.intensity() * core::f32::consts::PI * 4.0,
range: light.range().unwrap_or(20.0),
radius: light.range().unwrap_or(0.0),
inner_angle: inner_cone_angle,
outer_angle: outer_cone_angle,
..Default::default()
},
let mut entity = parent.spawn(SpotLight {
color: Color::srgb_from_array(light.color()),
// NOTE: KHR_punctual_lights defines the intensity units for spot lights in
// candela (lm/sr) which is luminous intensity and we need luminous power.
// For a spot light, we map luminous power = 4 * pi * luminous intensity
intensity: light.intensity() * core::f32::consts::PI * 4.0,
range: light.range().unwrap_or(20.0),
radius: light.range().unwrap_or(0.0),
inner_angle: inner_cone_angle,
outer_angle: outer_cone_angle,
..Default::default()
});
if let Some(name) = light.name() {
Expand Down
14 changes: 14 additions & 0 deletions crates/bevy_pbr/src/bundle.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
#![expect(deprecated)]

use crate::{
CascadeShadowConfig, Cascades, DirectionalLight, Material, PointLight, SpotLight,
StandardMaterial,
Expand Down Expand Up @@ -97,6 +99,10 @@ pub struct CascadesVisibleEntities {

/// A component bundle for [`PointLight`] entities.
#[derive(Debug, Bundle, Default, Clone)]
#[deprecated(
since = "0.15.0",
note = "Use the `PointLight` component instead. Inserting it will now also insert the other components required by it automatically."
)]
pub struct PointLightBundle {
pub point_light: PointLight,
pub cubemap_visible_entities: CubemapVisibleEntities,
Expand All @@ -115,6 +121,10 @@ pub struct PointLightBundle {

/// A component bundle for spot light entities
#[derive(Debug, Bundle, Default, Clone)]
#[deprecated(
since = "0.15.0",
note = "Use the `SpotLight` component instead. Inserting it will now also insert the other components required by it automatically."
)]
pub struct SpotLightBundle {
pub spot_light: SpotLight,
pub visible_entities: VisibleMeshEntities,
Expand All @@ -133,6 +143,10 @@ pub struct SpotLightBundle {

/// A component bundle for [`DirectionalLight`] entities.
#[derive(Debug, Bundle, Default, Clone)]
#[deprecated(
since = "0.15.0",
note = "Use the `DirectionalLight` component instead. Inserting it will now also insert the other components required by it automatically."
)]
pub struct DirectionalLightBundle {
pub directional_light: DirectionalLight,
pub frusta: CascadesFrusta,
Expand Down
1 change: 1 addition & 0 deletions crates/bevy_pbr/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ pub use volumetric_fog::{
/// The PBR prelude.
///
/// This includes the most common types in this crate, re-exported for your convenience.
#[expect(deprecated)]
pub mod prelude {
#[doc(hidden)]
pub use crate::{
Expand Down
15 changes: 13 additions & 2 deletions crates/bevy_pbr/src/light/directional_light.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
use bevy_render::{view::Visibility, world_sync::SyncToRenderWorld};

use super::*;

/// A Directional light.
Expand Down Expand Up @@ -36,8 +38,8 @@ use super::*;
///
/// 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).
///
/// To modify the cascade set up, such as the number of cascades or the maximum shadow distance,
/// change the [`CascadeShadowConfig`] component of the [`DirectionalLightBundle`].
/// To modify the cascade setup, such as the number of cascades or the maximum shadow distance,
/// change the [`CascadeShadowConfig`] component of the entity with the [`DirectionalLight`].
///
/// To control the resolution of the shadow maps, use the [`DirectionalLightShadowMap`] resource:
///
Expand All @@ -49,6 +51,15 @@ use super::*;
/// ```
#[derive(Component, Debug, Clone, Reflect)]
#[reflect(Component, Default, Debug)]
#[require(
Cascades,
CascadesFrusta,
CascadeShadowConfig,
CascadesVisibleEntities,
Transform,
Visibility,
SyncToRenderWorld
)]
pub struct DirectionalLight {
/// The color of the light.
///
Expand Down
9 changes: 9 additions & 0 deletions crates/bevy_pbr/src/light/point_light.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
use bevy_render::{view::Visibility, world_sync::SyncToRenderWorld};

use super::*;

/// A light that emits light in all directions from a central point.
Expand All @@ -19,6 +21,13 @@ use super::*;
/// Source: [Wikipedia](https://en.wikipedia.org/wiki/Lumen_(unit)#Lighting)
#[derive(Component, Debug, Clone, Copy, Reflect)]
#[reflect(Component, Default, Debug)]
#[require(
CubemapFrusta,
CubemapVisibleEntities,
Transform,
Visibility,
SyncToRenderWorld
)]
pub struct PointLight {
/// The color of this light source.
pub color: Color,
Expand Down
3 changes: 3 additions & 0 deletions crates/bevy_pbr/src/light/spot_light.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
use bevy_render::{view::Visibility, world_sync::SyncToRenderWorld};

use super::*;

/// A light that emits light in a given direction from a central point.
Expand All @@ -7,6 +9,7 @@ use super::*;
/// the transform, and can be specified with [`Transform::looking_at`](Transform::looking_at).
#[derive(Component, Debug, Clone, Copy, Reflect)]
#[reflect(Component, Default, Debug)]
#[require(Frustum, VisibleMeshEntities, Transform, Visibility, SyncToRenderWorld)]
pub struct SpotLight {
/// The color of the light.
///
Expand Down
9 changes: 4 additions & 5 deletions examples/3d/3d_scene.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,14 +30,13 @@ fn setup(
..default()
});
// light
commands.spawn(PointLightBundle {
point_light: PointLight {
commands.spawn((
PointLight {
shadows_enabled: true,
..default()
},
transform: Transform::from_xyz(4.0, 8.0, 4.0),
..default()
});
Transform::from_xyz(4.0, 8.0, 4.0),
));
// camera
commands.spawn(Camera3dBundle {
transform: Transform::from_xyz(-2.5, 4.5, 9.0).looking_at(Vec3::ZERO, Vec3::Y),
Expand Down
9 changes: 4 additions & 5 deletions examples/3d/3d_shapes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -116,17 +116,16 @@ fn setup(
));
}

commands.spawn(PointLightBundle {
point_light: PointLight {
commands.spawn((
PointLight {
shadows_enabled: true,
intensity: 10_000_000.,
range: 100.0,
shadow_depth_bias: 0.2,
..default()
},
transform: Transform::from_xyz(8.0, 16.0, 8.0),
..default()
});
Transform::from_xyz(8.0, 16.0, 8.0),
));

// ground plane
commands.spawn(PbrBundle {
Expand Down
8 changes: 4 additions & 4 deletions examples/3d/3d_viewport_to_world.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,10 +66,10 @@ fn setup(
));

// light
commands.spawn(DirectionalLightBundle {
transform: Transform::from_translation(Vec3::ONE).looking_at(Vec3::ZERO, Vec3::Y),
..default()
});
commands.spawn((
DirectionalLight::default(),
Transform::from_translation(Vec3::ONE).looking_at(Vec3::ZERO, Vec3::Y),
));

// camera
commands.spawn(Camera3dBundle {
Expand Down
18 changes: 6 additions & 12 deletions examples/3d/anisotropy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -252,24 +252,18 @@ fn add_skybox_and_environment_map(

/// Spawns a rotating directional light.
fn spawn_directional_light(commands: &mut Commands) {
commands.spawn(DirectionalLightBundle {
directional_light: DirectionalLight {
color: WHITE.into(),
illuminance: 3000.0,
..default()
},
commands.spawn(DirectionalLight {
color: WHITE.into(),
illuminance: 3000.0,
..default()
});
}

/// Spawns a rotating point light.
fn spawn_point_light(commands: &mut Commands) {
commands.spawn(PointLightBundle {
point_light: PointLight {
color: WHITE.into(),
intensity: 200000.0,
..default()
},
commands.spawn(PointLight {
color: WHITE.into(),
intensity: 200000.0,
..default()
});
}
Expand Down
18 changes: 6 additions & 12 deletions examples/3d/anti_aliasing.rs
Original file line number Diff line number Diff line change
Expand Up @@ -281,26 +281,20 @@ fn setup(
});

// Light
commands.spawn(DirectionalLightBundle {
directional_light: DirectionalLight {
commands.spawn((
DirectionalLight {
illuminance: light_consts::lux::FULL_DAYLIGHT,
shadows_enabled: true,
..default()
},
transform: Transform::from_rotation(Quat::from_euler(
EulerRot::ZYX,
0.0,
PI * -0.15,
PI * -0.15,
)),
cascade_shadow_config: CascadeShadowConfigBuilder {
Transform::from_rotation(Quat::from_euler(EulerRot::ZYX, 0.0, PI * -0.15, PI * -0.15)),
CascadeShadowConfigBuilder {
maximum_distance: 3.0,
first_cascade_far_bound: 0.9,
..default()
}
.into(),
..default()
});
.build(),
));

// Camera
commands.spawn((
Expand Down
10 changes: 4 additions & 6 deletions examples/3d/atmospheric_fog.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,17 +58,15 @@ fn setup_terrain_scene(
.build();

// Sun
commands.spawn(DirectionalLightBundle {
directional_light: DirectionalLight {
commands.spawn((
DirectionalLight {
color: Color::srgb(0.98, 0.95, 0.82),
shadows_enabled: true,
..default()
},
transform: Transform::from_xyz(0.0, 0.0, 0.0)
.looking_at(Vec3::new(-0.15, -0.05, 0.25), Vec3::Y),
Transform::from_xyz(0.0, 0.0, 0.0).looking_at(Vec3::new(-0.15, -0.05, 0.25), Vec3::Y),
cascade_shadow_config,
..default()
});
));

// Terrain
commands.spawn(SceneBundle {
Expand Down
9 changes: 4 additions & 5 deletions examples/3d/auto_exposure.rs
Original file line number Diff line number Diff line change
Expand Up @@ -110,14 +110,13 @@ fn setup(
brightness: 0.0,
});

commands.spawn(PointLightBundle {
point_light: PointLight {
commands.spawn((
PointLight {
intensity: 2000.0,
..default()
},
transform: Transform::from_xyz(0.0, 0.0, 0.0),
..default()
});
Transform::from_xyz(0.0, 0.0, 0.0),
));

commands.spawn(ImageBundle {
image: UiImage {
Expand Down
5 changes: 1 addition & 4 deletions examples/3d/blend_modes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -167,10 +167,7 @@ fn setup(
}

// Light
commands.spawn(PointLightBundle {
transform: Transform::from_xyz(4.0, 8.0, 4.0),
..default()
});
commands.spawn((PointLight::default(), Transform::from_xyz(4.0, 8.0, 4.0)));

// Camera
commands.spawn(Camera3dBundle {
Expand Down
Loading

0 comments on commit de888a3

Please sign in to comment.