Migrate motion blur, TAA, SSAO, and SSR to required components (#15572)

# Objective

Again, a step forward in the migration to required components: a bunch
of camera rendering cormponents!

Note that this does not include the camera components themselves yet,
because the naming and API for `Camera` hasn't been fully decided yet.

## Solution

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

- Deprecate `MotionBlurBundle` in favor of the `MotionBlur` component
- Deprecate `TemporalAntiAliasBundle` in favor of the
`TemporalAntiAliasing` component
- Deprecate `ScreenSpaceAmbientOcclusionBundle` in favor of the
`ScreenSpaceAmbientOcclusion` component
- Deprecate `ScreenSpaceReflectionsBundle` in favor of the
`ScreenSpaceReflections` component

---

## Migration Guide

`MotionBlurBundle`, `TemporalAntiAliasBundle`,
`ScreenSpaceAmbientOcclusionBundle`, and `ScreenSpaceReflectionsBundle`
have been deprecated in favor of the `MotionBlur`,
`TemporalAntiAliasing`, `ScreenSpaceAmbientOcclusion`, and
`ScreenSpaceReflections` components instead. Inserting them will now
also insert the other components required by them automatically.
This commit is contained in:
Joona Aalto 2024-10-02 01:45:31 +03:00 committed by GitHub
parent ed151e756c
commit 22af24aacf
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
11 changed files with 76 additions and 58 deletions

View file

@ -33,8 +33,8 @@ pub use skybox::Skybox;
/// ///
/// Expect bugs, missing features, compatibility issues, low performance, and/or future breaking changes. /// Expect bugs, missing features, compatibility issues, low performance, and/or future breaking changes.
pub mod experimental { pub mod experimental {
#[expect(deprecated)]
pub mod taa { pub mod taa {
#[allow(deprecated)]
pub use crate::taa::{ pub use crate::taa::{
TemporalAntiAliasBundle, TemporalAntiAliasNode, TemporalAntiAliasPlugin, TemporalAntiAliasBundle, TemporalAntiAliasNode, TemporalAntiAliasPlugin,
TemporalAntiAliasSettings, TemporalAntiAliasing, TemporalAntiAliasSettings, TemporalAntiAliasing,

View file

@ -1,7 +1,8 @@
//! Per-object, per-pixel motion blur. //! Per-object, per-pixel motion blur.
//! //!
//! Add the [`MotionBlurBundle`] to a camera to enable motion blur. See [`MotionBlur`] for more //! Add the [`MotionBlur`] component to a camera to enable motion blur.
//! documentation.
#![expect(deprecated)]
use crate::{ use crate::{
core_3d::graph::{Core3d, Node3d}, core_3d::graph::{Core3d, Node3d},
@ -27,6 +28,10 @@ pub mod pipeline;
/// Adds [`MotionBlur`] and the required depth and motion vector prepasses to a camera entity. /// Adds [`MotionBlur`] and the required depth and motion vector prepasses to a camera entity.
#[derive(Bundle, Default)] #[derive(Bundle, Default)]
#[deprecated(
since = "0.15.0",
note = "Use the `MotionBlur` component instead. Inserting it will now also insert the other components required by it automatically."
)]
pub struct MotionBlurBundle { pub struct MotionBlurBundle {
pub motion_blur: MotionBlur, pub motion_blur: MotionBlur,
pub depth_prepass: DepthPrepass, pub depth_prepass: DepthPrepass,
@ -51,22 +56,22 @@ pub struct MotionBlurBundle {
/// # Usage /// # Usage
/// ///
/// Add the [`MotionBlur`] component to a camera to enable and configure motion blur for that /// Add the [`MotionBlur`] component to a camera to enable and configure motion blur for that
/// camera. Motion blur also requires the depth and motion vector prepass, which can be added more /// camera.
/// easily to the camera with the [`MotionBlurBundle`].
/// ///
/// ``` /// ```
/// # use bevy_core_pipeline::{core_3d::Camera3dBundle, motion_blur::MotionBlurBundle}; /// # use bevy_core_pipeline::{core_3d::Camera3dBundle, motion_blur::MotionBlur};
/// # use bevy_ecs::prelude::*; /// # use bevy_ecs::prelude::*;
/// # fn test(mut commands: Commands) { /// # fn test(mut commands: Commands) {
/// commands.spawn(( /// commands.spawn((
/// Camera3dBundle::default(), /// Camera3dBundle::default(),
/// MotionBlurBundle::default(), /// MotionBlur::default(),
/// )); /// ));
/// # } /// # }
/// ```` /// ````
#[derive(Reflect, Component, Clone, ExtractComponent, ShaderType)] #[derive(Reflect, Component, Clone, ExtractComponent, ShaderType)]
#[reflect(Component, Default)] #[reflect(Component, Default)]
#[extract_component_filter(With<Camera>)] #[extract_component_filter(With<Camera>)]
#[require(DepthPrepass, MotionVectorPrepass)]
pub struct MotionBlur { pub struct MotionBlur {
/// The strength of motion blur from `0.0` to `1.0`. /// The strength of motion blur from `0.0` to `1.0`.
/// ///

View file

@ -1,3 +1,5 @@
#![expect(deprecated)]
use crate::{ use crate::{
core_3d::graph::{Core3d, Node3d}, core_3d::graph::{Core3d, Node3d},
fullscreen_vertex_shader::fullscreen_shader_vertex_state, fullscreen_vertex_shader::fullscreen_shader_vertex_state,
@ -88,6 +90,10 @@ impl Plugin for TemporalAntiAliasPlugin {
/// Bundle to apply temporal anti-aliasing. /// Bundle to apply temporal anti-aliasing.
#[derive(Bundle, Default, Clone)] #[derive(Bundle, Default, Clone)]
#[deprecated(
since = "0.15.0",
note = "Use the `TemporalAntiAlias` component instead. Inserting it will now also insert the other components required by it automatically."
)]
pub struct TemporalAntiAliasBundle { pub struct TemporalAntiAliasBundle {
pub settings: TemporalAntiAliasing, pub settings: TemporalAntiAliasing,
pub jitter: TemporalJitter, pub jitter: TemporalJitter,
@ -119,25 +125,24 @@ pub struct TemporalAntiAliasBundle {
/// ///
/// # Usage Notes /// # Usage Notes
/// ///
/// The [`TemporalAntiAliasPlugin`] must be added to your app.
/// Any camera with this component must also disable [`Msaa`] by setting it to [`Msaa::Off`]. /// Any camera with this component must also disable [`Msaa`] by setting it to [`Msaa::Off`].
/// ///
/// Requires that you add [`TemporalAntiAliasPlugin`] to your app, /// [Currently](https://github.com/bevyengine/bevy/issues/8423), TAA cannot be used with [`bevy_render::camera::OrthographicProjection`].
/// and add the [`DepthPrepass`], [`MotionVectorPrepass`], and [`TemporalJitter`]
/// components to your camera.
/// ///
/// [Currently](https://github.com/bevyengine/bevy/issues/8423) cannot be used with [`bevy_render::camera::OrthographicProjection`]. /// TAA also does not work well with alpha-blended meshes, as it requires depth writing to determine motion.
///
/// Does not work well with alpha-blended meshes as it requires depth writing to determine motion.
/// ///
/// It is very important that correct motion vectors are written for everything on screen. /// It is very important that correct motion vectors are written for everything on screen.
/// Failure to do so will lead to ghosting artifacts. For instance, if particle effects /// Failure to do so will lead to ghosting artifacts. For instance, if particle effects
/// are added using a third party library, the library must either: /// are added using a third party library, the library must either:
///
/// 1. Write particle motion vectors to the motion vectors prepass texture /// 1. Write particle motion vectors to the motion vectors prepass texture
/// 2. Render particles after TAA /// 2. Render particles after TAA
/// ///
/// If no [`MipBias`] component is attached to the camera, TAA will add a MipBias(-1.0) component. /// If no [`MipBias`] component is attached to the camera, TAA will add a `MipBias(-1.0)` component.
#[derive(Component, Reflect, Clone)] #[derive(Component, Reflect, Clone)]
#[reflect(Component, Default)] #[reflect(Component, Default)]
#[require(TemporalJitter, DepthPrepass, MotionVectorPrepass)]
#[doc(alias = "Taa")] #[doc(alias = "Taa")]
pub struct TemporalAntiAliasing { pub struct TemporalAntiAliasing {
/// Set to true to delete the saved temporal history (past frames). /// Set to true to delete the saved temporal history (past frames).

View file

@ -1,3 +1,5 @@
#![expect(deprecated)]
use crate::NodePbr; use crate::NodePbr;
use bevy_app::{App, Plugin}; use bevy_app::{App, Plugin};
use bevy_asset::{load_internal_asset, Handle}; use bevy_asset::{load_internal_asset, Handle};
@ -129,6 +131,10 @@ impl Plugin for ScreenSpaceAmbientOcclusionPlugin {
/// Bundle to apply screen space ambient occlusion. /// Bundle to apply screen space ambient occlusion.
#[derive(Bundle, Default, Clone)] #[derive(Bundle, Default, Clone)]
#[deprecated(
since = "0.15.0",
note = "Use the `ScreenSpaceAmbientOcclusion` component instead. Inserting it will now also insert the other components required by it automatically."
)]
pub struct ScreenSpaceAmbientOcclusionBundle { pub struct ScreenSpaceAmbientOcclusionBundle {
pub settings: ScreenSpaceAmbientOcclusion, pub settings: ScreenSpaceAmbientOcclusion,
pub depth_prepass: DepthPrepass, pub depth_prepass: DepthPrepass,
@ -146,8 +152,7 @@ pub struct ScreenSpaceAmbientOcclusionBundle {
/// ///
/// # Usage Notes /// # Usage Notes
/// ///
/// Requires that you add [`ScreenSpaceAmbientOcclusionPlugin`] to your app, /// Requires that you add [`ScreenSpaceAmbientOcclusionPlugin`] to your app.
/// and add the [`DepthPrepass`] and [`NormalPrepass`] components to your camera.
/// ///
/// It strongly recommended that you use SSAO in conjunction with /// It strongly recommended that you use SSAO in conjunction with
/// TAA ([`bevy_core_pipeline::experimental::taa::TemporalAntiAliasing`]). /// TAA ([`bevy_core_pipeline::experimental::taa::TemporalAntiAliasing`]).
@ -156,6 +161,7 @@ pub struct ScreenSpaceAmbientOcclusionBundle {
/// SSAO is not supported on `WebGL2`, and is not currently supported on `WebGPU` or `DirectX12`. /// SSAO is not supported on `WebGL2`, and is not currently supported on `WebGPU` or `DirectX12`.
#[derive(Component, ExtractComponent, Reflect, PartialEq, Eq, Hash, Clone, Default, Debug)] #[derive(Component, ExtractComponent, Reflect, PartialEq, Eq, Hash, Clone, Default, Debug)]
#[reflect(Component, Debug, Default, Hash, PartialEq)] #[reflect(Component, Debug, Default, Hash, PartialEq)]
#[require(DepthPrepass, NormalPrepass)]
#[doc(alias = "Ssao")] #[doc(alias = "Ssao")]
pub struct ScreenSpaceAmbientOcclusion { pub struct ScreenSpaceAmbientOcclusion {
pub quality_level: ScreenSpaceAmbientOcclusionQualityLevel, pub quality_level: ScreenSpaceAmbientOcclusionQualityLevel,

View file

@ -1,5 +1,7 @@
//! Screen space reflections implemented via raymarching. //! Screen space reflections implemented via raymarching.
#![expect(deprecated)]
use bevy_app::{App, Plugin}; use bevy_app::{App, Plugin};
use bevy_asset::{load_internal_asset, Handle}; use bevy_asset::{load_internal_asset, Handle};
use bevy_core_pipeline::{ use bevy_core_pipeline::{
@ -58,6 +60,10 @@ pub struct ScreenSpaceReflectionsPlugin;
/// A convenient bundle to add screen space reflections to a camera, along with /// A convenient bundle to add screen space reflections to a camera, along with
/// the depth and deferred prepasses required to enable them. /// the depth and deferred prepasses required to enable them.
#[derive(Bundle, Default)] #[derive(Bundle, Default)]
#[deprecated(
since = "0.15.0",
note = "Use the `ScreenSpaceReflections` components instead. Inserting it will now also insert the other components required by it automatically."
)]
pub struct ScreenSpaceReflectionsBundle { pub struct ScreenSpaceReflectionsBundle {
/// The component that enables SSR. /// The component that enables SSR.
pub settings: ScreenSpaceReflections, pub settings: ScreenSpaceReflections,
@ -70,8 +76,8 @@ pub struct ScreenSpaceReflectionsBundle {
/// Add this component to a camera to enable *screen-space reflections* (SSR). /// Add this component to a camera to enable *screen-space reflections* (SSR).
/// ///
/// Screen-space reflections currently require deferred rendering in order to /// Screen-space reflections currently require deferred rendering in order to
/// appear. Therefore, you'll generally need to add a [`DepthPrepass`] and a /// appear. Therefore, they also need the [`DepthPrepass`] and [`DeferredPrepass`]
/// [`DeferredPrepass`] to the camera as well. /// components, which are inserted automatically.
/// ///
/// SSR currently performs no roughness filtering for glossy reflections, so /// SSR currently performs no roughness filtering for glossy reflections, so
/// only very smooth surfaces will reflect objects in screen space. You can /// only very smooth surfaces will reflect objects in screen space. You can
@ -92,6 +98,7 @@ pub struct ScreenSpaceReflectionsBundle {
/// which is required for screen-space raymarching. /// which is required for screen-space raymarching.
#[derive(Clone, Copy, Component, Reflect)] #[derive(Clone, Copy, Component, Reflect)]
#[reflect(Component, Default)] #[reflect(Component, Default)]
#[require(DepthPrepass, DeferredPrepass)]
#[doc(alias = "Ssr")] #[doc(alias = "Ssr")]
pub struct ScreenSpaceReflections { pub struct ScreenSpaceReflections {
/// The maximum PBR roughness level that will enable screen space /// The maximum PBR roughness level that will enable screen space

View file

@ -5,15 +5,15 @@ use std::{f32::consts::PI, fmt::Write};
use bevy::{ use bevy::{
core_pipeline::{ core_pipeline::{
contrast_adaptive_sharpening::ContrastAdaptiveSharpening, contrast_adaptive_sharpening::ContrastAdaptiveSharpening,
experimental::taa::{ experimental::taa::{TemporalAntiAliasPlugin, TemporalAntiAliasing},
TemporalAntiAliasBundle, TemporalAntiAliasPlugin, TemporalAntiAliasing,
},
fxaa::{Fxaa, Sensitivity}, fxaa::{Fxaa, Sensitivity},
prepass::{DepthPrepass, MotionVectorPrepass},
smaa::{Smaa, SmaaPreset}, smaa::{Smaa, SmaaPreset},
}, },
pbr::CascadeShadowConfigBuilder, pbr::CascadeShadowConfigBuilder,
prelude::*, prelude::*,
render::{ render::{
camera::TemporalJitter,
render_asset::RenderAssetUsages, render_asset::RenderAssetUsages,
render_resource::{Extent3d, TextureDimension, TextureFormat}, render_resource::{Extent3d, TextureDimension, TextureFormat},
texture::{ImageSampler, ImageSamplerDescriptor}, texture::{ImageSampler, ImageSamplerDescriptor},
@ -28,6 +28,13 @@ fn main() {
.run(); .run();
} }
type TaaComponents = (
TemporalAntiAliasing,
TemporalJitter,
DepthPrepass,
MotionVectorPrepass,
);
fn modify_aa( fn modify_aa(
keys: Res<ButtonInput<KeyCode>>, keys: Res<ButtonInput<KeyCode>>,
mut camera: Query< mut camera: Query<
@ -51,7 +58,7 @@ fn modify_aa(
camera = camera camera = camera
.remove::<Fxaa>() .remove::<Fxaa>()
.remove::<Smaa>() .remove::<Smaa>()
.remove::<TemporalAntiAliasBundle>(); .remove::<TaaComponents>();
} }
// MSAA // MSAA
@ -59,7 +66,7 @@ fn modify_aa(
camera = camera camera = camera
.remove::<Fxaa>() .remove::<Fxaa>()
.remove::<Smaa>() .remove::<Smaa>()
.remove::<TemporalAntiAliasBundle>(); .remove::<TaaComponents>();
*msaa = Msaa::Sample4; *msaa = Msaa::Sample4;
} }
@ -82,7 +89,7 @@ fn modify_aa(
*msaa = Msaa::Off; *msaa = Msaa::Off;
camera = camera camera = camera
.remove::<Smaa>() .remove::<Smaa>()
.remove::<TemporalAntiAliasBundle>() .remove::<TaaComponents>()
.insert(Fxaa::default()); .insert(Fxaa::default());
} }
@ -115,7 +122,7 @@ fn modify_aa(
*msaa = Msaa::Off; *msaa = Msaa::Off;
camera = camera camera = camera
.remove::<Fxaa>() .remove::<Fxaa>()
.remove::<TemporalAntiAliasBundle>() .remove::<TaaComponents>()
.insert(Smaa::default()); .insert(Smaa::default());
} }
@ -141,7 +148,7 @@ fn modify_aa(
camera camera
.remove::<Fxaa>() .remove::<Fxaa>()
.remove::<Smaa>() .remove::<Smaa>()
.insert(TemporalAntiAliasBundle::default()); .insert(TemporalAntiAliasing::default());
} }
} }

View file

@ -1,11 +1,7 @@
//! Demonstrates how to enable per-object motion blur. This rendering feature can be configured per //! Demonstrates how to enable per-object motion blur. This rendering feature can be configured per
//! camera using the [`MotionBlur`] component.z //! camera using the [`MotionBlur`] component.z
use bevy::{ use bevy::{core_pipeline::motion_blur::MotionBlur, math::ops, prelude::*};
core_pipeline::motion_blur::{MotionBlur, MotionBlurBundle},
math::ops,
prelude::*,
};
fn main() { fn main() {
let mut app = App::new(); let mut app = App::new();
@ -23,18 +19,15 @@ fn main() {
fn setup_camera(mut commands: Commands) { fn setup_camera(mut commands: Commands) {
commands.spawn(( commands.spawn((
Camera3dBundle::default(), Camera3dBundle::default(),
// Add the MotionBlurBundle to a camera to enable motion blur. // Add the `MotionBlur` component to a camera to enable motion blur.
// Motion blur requires the depth and motion vector prepass, which this bundle adds. // Motion blur requires the depth and motion vector prepass, which this bundle adds.
// Configure the amount and quality of motion blur per-camera using this component. // Configure the amount and quality of motion blur per-camera using this component.
MotionBlurBundle { MotionBlur {
motion_blur: MotionBlur {
shutter_angle: 1.0, shutter_angle: 1.0,
samples: 2, samples: 2,
#[cfg(all(feature = "webgl2", target_arch = "wasm32", not(feature = "webgpu")))] #[cfg(all(feature = "webgl2", target_arch = "wasm32", not(feature = "webgpu")))]
_webgl2_padding: Default::default(), _webgl2_padding: Default::default(),
}, },
..default()
},
)); ));
} }

View file

@ -13,7 +13,7 @@
use bevy::{ use bevy::{
core_pipeline::{ core_pipeline::{
bloom::Bloom, bloom::Bloom,
experimental::taa::{TemporalAntiAliasBundle, TemporalAntiAliasPlugin}, experimental::taa::{TemporalAntiAliasPlugin, TemporalAntiAliasing},
}, },
pbr::{DirectionalLightShadowMap, FogVolume, VolumetricFog, VolumetricLight}, pbr::{DirectionalLightShadowMap, FogVolume, VolumetricFog, VolumetricLight},
prelude::*, prelude::*,
@ -59,7 +59,7 @@ fn setup(
msaa: Msaa::Off, msaa: Msaa::Off,
..default() ..default()
}, },
TemporalAntiAliasBundle::default(), TemporalAntiAliasing::default(),
Bloom::default(), Bloom::default(),
VolumetricFog { VolumetricFog {
ambient_intensity: 0.0, ambient_intensity: 0.0,

View file

@ -1,12 +1,9 @@
//! A scene showcasing screen space ambient occlusion. //! A scene showcasing screen space ambient occlusion.
use bevy::{ use bevy::{
core_pipeline::experimental::taa::{TemporalAntiAliasBundle, TemporalAntiAliasPlugin}, core_pipeline::experimental::taa::{TemporalAntiAliasPlugin, TemporalAntiAliasing},
math::ops, math::ops,
pbr::{ pbr::{ScreenSpaceAmbientOcclusion, ScreenSpaceAmbientOcclusionQualityLevel},
ScreenSpaceAmbientOcclusion, ScreenSpaceAmbientOcclusionBundle,
ScreenSpaceAmbientOcclusionQualityLevel,
},
prelude::*, prelude::*,
render::camera::TemporalJitter, render::camera::TemporalJitter,
}; };
@ -29,8 +26,8 @@ fn setup(
mut meshes: ResMut<Assets<Mesh>>, mut meshes: ResMut<Assets<Mesh>>,
mut materials: ResMut<Assets<StandardMaterial>>, mut materials: ResMut<Assets<StandardMaterial>>,
) { ) {
commands commands.spawn((
.spawn(Camera3dBundle { Camera3dBundle {
camera: Camera { camera: Camera {
hdr: true, hdr: true,
..default() ..default()
@ -38,9 +35,10 @@ fn setup(
transform: Transform::from_xyz(-2.0, 2.0, -2.0).looking_at(Vec3::ZERO, Vec3::Y), transform: Transform::from_xyz(-2.0, 2.0, -2.0).looking_at(Vec3::ZERO, Vec3::Y),
msaa: Msaa::Off, msaa: Msaa::Off,
..default() ..default()
}) },
.insert(ScreenSpaceAmbientOcclusionBundle::default()) ScreenSpaceAmbientOcclusion::default(),
.insert(TemporalAntiAliasBundle::default()); TemporalAntiAliasing::default(),
));
let material = materials.add(StandardMaterial { let material = materials.add(StandardMaterial {
base_color: Color::srgb(0.5, 0.5, 0.5), base_color: Color::srgb(0.5, 0.5, 0.5),

View file

@ -9,7 +9,6 @@ use bevy::{
math::{vec3, vec4}, math::{vec3, vec4},
pbr::{ pbr::{
DefaultOpaqueRendererMethod, ExtendedMaterial, MaterialExtension, ScreenSpaceReflections, DefaultOpaqueRendererMethod, ExtendedMaterial, MaterialExtension, ScreenSpaceReflections,
ScreenSpaceReflectionsBundle,
}, },
prelude::*, prelude::*,
render::{ render::{
@ -247,7 +246,7 @@ fn spawn_camera(commands: &mut Commands, asset_server: &AssetServer) {
brightness: 5000.0, brightness: 5000.0,
..default() ..default()
}) })
.insert(ScreenSpaceReflectionsBundle::default()) .insert(ScreenSpaceReflections::default())
.insert(Fxaa::default()); .insert(Fxaa::default());
} }

View file

@ -36,9 +36,7 @@ use bevy::{
}; };
#[cfg(not(all(feature = "webgl2", target_arch = "wasm32")))] #[cfg(not(all(feature = "webgl2", target_arch = "wasm32")))]
use bevy::core_pipeline::experimental::taa::{ use bevy::core_pipeline::experimental::taa::{TemporalAntiAliasPlugin, TemporalAntiAliasing};
TemporalAntiAliasBundle, TemporalAntiAliasPlugin, TemporalAntiAliasing,
};
use rand::random; use rand::random;
fn main() { fn main() {
@ -324,7 +322,7 @@ fn setup(
..default() ..default()
}, },
#[cfg(not(all(feature = "webgl2", target_arch = "wasm32")))] #[cfg(not(all(feature = "webgl2", target_arch = "wasm32")))]
TemporalAntiAliasBundle::default(), TemporalAntiAliasing::default(),
EnvironmentMapLight { EnvironmentMapLight {
intensity: 25.0, intensity: 25.0,
diffuse_map: asset_server.load("environment_maps/pisa_diffuse_rgb9e5_zstd.ktx2"), diffuse_map: asset_server.load("environment_maps/pisa_diffuse_rgb9e5_zstd.ktx2"),