Migrate reflection probes to required components (#15737)

# Objective

Getting closer to the end! Another part of the required components
migration: reflection probes.

## Solution

As per the [proposal added by
Cart](https://hackmd.io/@bevy/required_components/%2FNmpIh0tGSiayGlswbfcEzw)
(Proposal 2), make `LightProbe` require `Transform` and `Visibility`,
and deprecate `ReflectionProbeBundle`.

Note that this proposal wasn't officially blessed yet, but it is the
only existing one that really works, so I implemented it here for
consideration.

## Testing

I ran the reflection probe example, and it appears to work.

---

## Migration Guide

`ReflectionProbeBundle` has been deprecated in favor of inserting the
`LightProbe` and `EnvironmentMapLight` components directly. Inserting
them will now automatically insert `Transform` and `Visibility`
components.

---------

Co-authored-by: Tim Blackbird <justthecooldude@gmail.com>
Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
This commit is contained in:
Joona Aalto 2024-10-09 02:59:27 +03:00 committed by GitHub
parent a89ae8e9d9
commit bc352561c9
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 21 additions and 20 deletions

View File

@ -11,15 +11,13 @@
//! 1. If attached to a view, they represent the objects located a very far //! 1. If attached to a view, they represent the objects located a very far
//! distance from the view, in a similar manner to a skybox. Essentially, these //! distance from the view, in a similar manner to a skybox. Essentially, these
//! *view environment maps* represent a higher-quality replacement for //! *view environment maps* represent a higher-quality replacement for
//! [`crate::AmbientLight`] for outdoor scenes. The indirect light from such //! [`AmbientLight`](crate::AmbientLight) for outdoor scenes. The indirect light from such
//! environment maps are added to every point of the scene, including //! environment maps are added to every point of the scene, including
//! interior enclosed areas. //! interior enclosed areas.
//! //!
//! 2. If attached to a [`LightProbe`], environment maps represent the immediate //! 2. If attached to a [`LightProbe`], environment maps represent the immediate
//! surroundings of a specific location in the scene. These types of //! surroundings of a specific location in the scene. These types of
//! environment maps are known as *reflection probes*. //! environment maps are known as *reflection probes*.
//! [`ReflectionProbeBundle`] is available as a mechanism to conveniently add
//! these to a scene.
//! //!
//! Typically, environment maps are static (i.e. "baked", calculated ahead of //! Typically, environment maps are static (i.e. "baked", calculated ahead of
//! time) and so only reflect fixed static geometry. The environment maps must //! time) and so only reflect fixed static geometry. The environment maps must
@ -46,6 +44,8 @@
//! //!
//! [several pre-filtered environment maps]: https://github.com/KhronosGroup/glTF-Sample-Environments //! [several pre-filtered environment maps]: https://github.com/KhronosGroup/glTF-Sample-Environments
#![expect(deprecated)]
use bevy_asset::{AssetId, Handle}; use bevy_asset::{AssetId, Handle};
use bevy_ecs::{ use bevy_ecs::{
bundle::Bundle, component::Component, query::QueryItem, reflect::ReflectComponent, bundle::Bundle, component::Component, query::QueryItem, reflect::ReflectComponent,
@ -137,6 +137,10 @@ pub struct EnvironmentMapIds {
/// surrounding a region in space. For more information, see /// surrounding a region in space. For more information, see
/// [`crate::environment_map`]. /// [`crate::environment_map`].
#[derive(Bundle, Clone)] #[derive(Bundle, Clone)]
#[deprecated(
since = "0.15.0",
note = "Use the `LightProbe` and `EnvironmentMapLight` components instead. Inserting them will now also insert the other components required by them automatically."
)]
pub struct ReflectionProbeBundle { pub struct ReflectionProbeBundle {
/// Contains a transform that specifies the position of this reflection probe in space. /// Contains a transform that specifies the position of this reflection probe in space.
pub spatial: SpatialBundle, pub spatial: SpatialBundle,

View File

@ -23,7 +23,7 @@ use bevy_render::{
settings::WgpuFeatures, settings::WgpuFeatures,
sync_world::RenderEntity, sync_world::RenderEntity,
texture::{FallbackImage, GpuImage, Image}, texture::{FallbackImage, GpuImage, Image},
view::ExtractedView, view::{ExtractedView, Visibility},
Extract, ExtractSchedule, Render, RenderApp, RenderSet, Extract, ExtractSchedule, Render, RenderApp, RenderSet,
}; };
use bevy_transform::{components::Transform, prelude::GlobalTransform}; use bevy_transform::{components::Transform, prelude::GlobalTransform};
@ -65,15 +65,14 @@ pub struct LightProbePlugin;
/// A marker component for a light probe, which is a cuboid region that provides /// A marker component for a light probe, which is a cuboid region that provides
/// global illumination to all fragments inside it. /// global illumination to all fragments inside it.
/// ///
/// The light probe range is conceptually a unit cube (1×1×1) centered on the
/// origin. The [`bevy_transform::prelude::Transform`] applied to this entity
/// can scale, rotate, or translate that cube so that it contains all fragments
/// that should take this light probe into account.
///
/// Note that a light probe will have no effect unless the entity contains some /// Note that a light probe will have no effect unless the entity contains some
/// kind of illumination, which can either be an [`EnvironmentMapLight`] or an /// kind of illumination, which can either be an [`EnvironmentMapLight`] or an
/// [`IrradianceVolume`]. /// [`IrradianceVolume`].
/// ///
/// The light probe range is conceptually a unit cube (1×1×1) centered on the
/// origin. The [`Transform`] applied to this entity can scale, rotate, or translate
/// that cube so that it contains all fragments that should take this light probe into account.
///
/// When multiple sources of indirect illumination can be applied to a fragment, /// When multiple sources of indirect illumination can be applied to a fragment,
/// the highest-quality one is chosen. Diffuse and specular illumination are /// the highest-quality one is chosen. Diffuse and specular illumination are
/// considered separately, so, for example, Bevy may decide to sample the /// considered separately, so, for example, Bevy may decide to sample the
@ -104,6 +103,7 @@ pub struct LightProbePlugin;
/// with other engines should be aware of this terminology difference. /// with other engines should be aware of this terminology difference.
#[derive(Component, Debug, Clone, Copy, Default, Reflect)] #[derive(Component, Debug, Clone, Copy, Default, Reflect)]
#[reflect(Component, Default, Debug)] #[reflect(Component, Default, Debug)]
#[require(Transform, Visibility)]
pub struct LightProbe; pub struct LightProbe;
/// A GPU type that stores information about a light probe. /// A GPU type that stores information about a light probe.

View File

@ -86,8 +86,8 @@ pub struct ScreenSpaceReflectionsBundle {
/// ///
/// As with all screen-space techniques, SSR can only reflect objects on screen. /// As with all screen-space techniques, SSR can only reflect objects on screen.
/// When objects leave the camera, they will disappear from reflections. /// When objects leave the camera, they will disappear from reflections.
/// Alternatives that don't suffer from this problem include /// An alternative that doesn't suffer from this problem is the combination of
/// [`crate::environment_map::ReflectionProbeBundle`]s. The advantage of SSR is /// a [`LightProbe`](crate::LightProbe) and [`EnvironmentMapLight`]. The advantage of SSR is
/// that it can reflect all objects, not just static ones. /// that it can reflect all objects, not just static ones.
/// ///
/// SSR is an approximation technique and produces artifacts in some situations. /// SSR is an approximation technique and produces artifacts in some situations.

View File

@ -136,20 +136,17 @@ fn spawn_sphere(
// Spawns the reflection probe. // Spawns the reflection probe.
fn spawn_reflection_probe(commands: &mut Commands, cubemaps: &Cubemaps) { fn spawn_reflection_probe(commands: &mut Commands, cubemaps: &Cubemaps) {
commands.spawn(ReflectionProbeBundle { commands.spawn((
spatial: SpatialBundle { LightProbe,
// 2.0 because the sphere's radius is 1.0 and we want to fully enclose it. EnvironmentMapLight {
transform: Transform::from_scale(Vec3::splat(2.0)),
..SpatialBundle::default()
},
light_probe: LightProbe,
environment_map: EnvironmentMapLight {
diffuse_map: cubemaps.diffuse.clone(), diffuse_map: cubemaps.diffuse.clone(),
specular_map: cubemaps.specular_reflection_probe.clone(), specular_map: cubemaps.specular_reflection_probe.clone(),
intensity: 5000.0, intensity: 5000.0,
..default() ..default()
}, },
}); // 2.0 because the sphere's radius is 1.0 and we want to fully enclose it.
Transform::from_scale(Vec3::splat(2.0)),
));
} }
// Spawns the help text. // Spawns the help text.