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
//! distance from the view, in a similar manner to a skybox. Essentially, these
//! *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
//! interior enclosed areas.
//!
//! 2. If attached to a [`LightProbe`], environment maps represent the immediate
//! surroundings of a specific location in the scene. These types of
//! 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
//! 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
#![expect(deprecated)]
use bevy_asset::{AssetId, Handle};
use bevy_ecs::{
bundle::Bundle, component::Component, query::QueryItem, reflect::ReflectComponent,
@ -137,6 +137,10 @@ pub struct EnvironmentMapIds {
/// surrounding a region in space. For more information, see
/// [`crate::environment_map`].
#[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 {
/// Contains a transform that specifies the position of this reflection probe in space.
pub spatial: SpatialBundle,

View file

@ -23,7 +23,7 @@ use bevy_render::{
settings::WgpuFeatures,
sync_world::RenderEntity,
texture::{FallbackImage, GpuImage, Image},
view::ExtractedView,
view::{ExtractedView, Visibility},
Extract, ExtractSchedule, Render, RenderApp, RenderSet,
};
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
/// 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
/// kind of illumination, which can either be an [`EnvironmentMapLight`] or an
/// [`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,
/// the highest-quality one is chosen. Diffuse and specular illumination are
/// 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.
#[derive(Component, Debug, Clone, Copy, Default, Reflect)]
#[reflect(Component, Default, Debug)]
#[require(Transform, Visibility)]
pub struct LightProbe;
/// 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.
/// When objects leave the camera, they will disappear from reflections.
/// Alternatives that don't suffer from this problem include
/// [`crate::environment_map::ReflectionProbeBundle`]s. The advantage of SSR is
/// An alternative that doesn't suffer from this problem is the combination of
/// a [`LightProbe`](crate::LightProbe) and [`EnvironmentMapLight`]. The advantage of SSR is
/// that it can reflect all objects, not just static ones.
///
/// SSR is an approximation technique and produces artifacts in some situations.

View file

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