Make TAA non-experimental, fixes (#18349)

The first 4 commits are designed to be reviewed independently.

- Mark TAA non-experimental now that motion vectors are written for
skinned and morphed meshes, along with skyboxes, and add it to
DefaultPlugins
- Adjust halton sequence to match what DLSS is going to use, doesn't
really affect anything, but may as well
- Make MipBias a required component on TAA instead of inserting it in
the render world
- Remove MipBias, TemporalJitter, RenderLayers, etc from the render
world if they're removed from the main world (fixes a retained render
world bug)
- Remove TAA components from the render world properly if
TemporalAntiAliasing is removed from the main world (fixes a retained
render world bug)
- extract_taa_settings() now has to query over `Option<&mut
TemporalAntiAliasing>`, which will match every single camera, in order
to cover cameras that had TemporalAntiAliasing removed this frame. This
kind of sucks, but I can't think of anything better.
- We probably have the same bug with every other rendering feature
component we have.

---------

Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
This commit is contained in:
JMS55 2025-06-02 09:04:08 -07:00 committed by GitHub
parent dc4737923c
commit 8255e6cda9
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
10 changed files with 75 additions and 63 deletions

View File

@ -1,9 +0,0 @@
//! Experimental rendering features.
//!
//! Experimental features are features with known problems, missing features,
//! compatibility issues, low performance, and/or future breaking changes, but
//! are included nonetheless for testing purposes.
pub mod taa {
pub use crate::taa::{TemporalAntiAliasNode, TemporalAntiAliasPlugin, TemporalAntiAliasing};
}

View File

@ -10,18 +10,17 @@ use bevy_app::Plugin;
use contrast_adaptive_sharpening::CasPlugin;
use fxaa::FxaaPlugin;
use smaa::SmaaPlugin;
use taa::TemporalAntiAliasPlugin;
pub mod contrast_adaptive_sharpening;
pub mod experimental;
pub mod fxaa;
pub mod smaa;
mod taa;
pub mod taa;
#[derive(Default)]
pub struct AntiAliasingPlugin;
impl Plugin for AntiAliasingPlugin {
fn build(&self, app: &mut bevy_app::App) {
app.add_plugins((FxaaPlugin, CasPlugin, SmaaPlugin));
app.add_plugins((FxaaPlugin, SmaaPlugin, TemporalAntiAliasPlugin, CasPlugin));
}
}

View File

@ -62,7 +62,7 @@ impl Plugin for TemporalAntiAliasPlugin {
.add_systems(
Render,
(
prepare_taa_jitter_and_mip_bias.in_set(RenderSystems::ManageViews),
prepare_taa_jitter.in_set(RenderSystems::ManageViews),
prepare_taa_pipelines.in_set(RenderSystems::Prepare),
prepare_taa_history_textures.in_set(RenderSystems::PrepareResources),
),
@ -113,7 +113,6 @@ impl Plugin for TemporalAntiAliasPlugin {
///
/// # 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`].
///
/// [Currently](https://github.com/bevyengine/bevy/issues/8423), TAA cannot be used with [`bevy_render::camera::OrthographicProjection`].
@ -126,11 +125,9 @@ impl Plugin for TemporalAntiAliasPlugin {
///
/// 1. Write particle motion vectors to the motion vectors prepass texture
/// 2. Render particles after TAA
///
/// If no [`MipBias`] component is attached to the camera, TAA will add a `MipBias(-1.0)` component.
#[derive(Component, Reflect, Clone)]
#[reflect(Component, Default, Clone)]
#[require(TemporalJitter, DepthPrepass, MotionVectorPrepass)]
#[require(TemporalJitter, MipBias, DepthPrepass, MotionVectorPrepass)]
#[doc(alias = "Taa")]
pub struct TemporalAntiAliasing {
/// Set to true to delete the saved temporal history (past frames).
@ -345,16 +342,11 @@ impl SpecializedRenderPipeline for TaaPipeline {
}
fn extract_taa_settings(mut commands: Commands, mut main_world: ResMut<MainWorld>) {
let mut cameras_3d = main_world.query_filtered::<(
let mut cameras_3d = main_world.query::<(
RenderEntity,
&Camera,
&Projection,
&mut TemporalAntiAliasing,
), (
With<Camera3d>,
With<TemporalJitter>,
With<DepthPrepass>,
With<MotionVectorPrepass>,
Option<&mut TemporalAntiAliasing>,
)>();
for (entity, camera, camera_projection, mut taa_settings) in
@ -364,14 +356,12 @@ fn extract_taa_settings(mut commands: Commands, mut main_world: ResMut<MainWorld
let mut entity_commands = commands
.get_entity(entity)
.expect("Camera entity wasn't synced.");
if camera.is_active && has_perspective_projection {
entity_commands.insert(taa_settings.clone());
taa_settings.reset = false;
if taa_settings.is_some() && camera.is_active && has_perspective_projection {
entity_commands.insert(taa_settings.as_deref().unwrap().clone());
taa_settings.as_mut().unwrap().reset = false;
} else {
// TODO: needs better strategy for cleaning up
entity_commands.remove::<(
TemporalAntiAliasing,
// components added in prepare systems (because `TemporalAntiAliasNode` does not query extracted components)
TemporalAntiAliasHistoryTextures,
TemporalAntiAliasPipelineId,
)>();
@ -379,13 +369,22 @@ fn extract_taa_settings(mut commands: Commands, mut main_world: ResMut<MainWorld
}
}
fn prepare_taa_jitter_and_mip_bias(
fn prepare_taa_jitter(
frame_count: Res<FrameCount>,
mut query: Query<(Entity, &mut TemporalJitter, Option<&MipBias>), With<TemporalAntiAliasing>>,
mut commands: Commands,
mut query: Query<
&mut TemporalJitter,
(
With<TemporalAntiAliasing>,
With<Camera3d>,
With<TemporalJitter>,
With<DepthPrepass>,
With<MotionVectorPrepass>,
),
>,
) {
// Halton sequence (2, 3) - 0.5, skipping i = 0
// Halton sequence (2, 3) - 0.5
let halton_sequence = [
vec2(0.0, 0.0),
vec2(0.0, -0.16666666),
vec2(-0.25, 0.16666669),
vec2(0.25, -0.3888889),
@ -393,17 +392,12 @@ fn prepare_taa_jitter_and_mip_bias(
vec2(0.125, 0.2777778),
vec2(-0.125, -0.2777778),
vec2(0.375, 0.055555582),
vec2(-0.4375, 0.3888889),
];
let offset = halton_sequence[frame_count.0 as usize % halton_sequence.len()];
for (entity, mut jitter, mip_bias) in &mut query {
for mut jitter in &mut query {
jitter.offset = offset;
if mip_bias.is_none() {
commands.entity(entity).insert(MipBias(-1.0));
}
}
}

View File

@ -1101,6 +1101,7 @@ pub fn extract_cameras(
Option<&ColorGrading>,
Option<&Exposure>,
Option<&TemporalJitter>,
Option<&MipBias>,
Option<&RenderLayers>,
Option<&Projection>,
Has<NoIndirectDrawing>,
@ -1123,6 +1124,7 @@ pub fn extract_cameras(
color_grading,
exposure,
temporal_jitter,
mip_bias,
render_layers,
projection,
no_indirect_drawing,
@ -1134,6 +1136,7 @@ pub fn extract_cameras(
ExtractedView,
RenderVisibleEntities,
TemporalJitter,
MipBias,
RenderLayers,
Projection,
NoIndirectDrawing,
@ -1220,14 +1223,26 @@ pub fn extract_cameras(
if let Some(temporal_jitter) = temporal_jitter {
commands.insert(temporal_jitter.clone());
} else {
commands.remove::<TemporalJitter>();
}
if let Some(mip_bias) = mip_bias {
commands.insert(mip_bias.clone());
} else {
commands.remove::<MipBias>();
}
if let Some(render_layers) = render_layers {
commands.insert(render_layers.clone());
} else {
commands.remove::<RenderLayers>();
}
if let Some(perspective) = projection {
commands.insert(perspective.clone());
} else {
commands.remove::<Projection>();
}
if no_indirect_drawing
@ -1237,6 +1252,8 @@ pub fn extract_cameras(
)
{
commands.insert(NoIndirectDrawing);
} else {
commands.remove::<NoIndirectDrawing>();
}
};
}
@ -1337,6 +1354,12 @@ impl TemporalJitter {
/// Camera component specifying a mip bias to apply when sampling from material textures.
///
/// Often used in conjunction with antialiasing post-process effects to reduce textures blurriness.
#[derive(Default, Component, Reflect)]
#[derive(Component, Reflect, Clone)]
#[reflect(Default, Component)]
pub struct MipBias(pub f32);
impl Default for MipBias {
fn default() -> Self {
Self(-1.0)
}
}

View File

@ -5,16 +5,16 @@ use std::{f32::consts::PI, fmt::Write};
use bevy::{
anti_aliasing::{
contrast_adaptive_sharpening::ContrastAdaptiveSharpening,
experimental::taa::{TemporalAntiAliasPlugin, TemporalAntiAliasing},
fxaa::{Fxaa, Sensitivity},
smaa::{Smaa, SmaaPreset},
taa::TemporalAntiAliasing,
},
core_pipeline::prepass::{DepthPrepass, MotionVectorPrepass},
image::{ImageSampler, ImageSamplerDescriptor},
pbr::CascadeShadowConfigBuilder,
prelude::*,
render::{
camera::TemporalJitter,
camera::{MipBias, TemporalJitter},
render_asset::RenderAssetUsages,
render_resource::{Extent3d, TextureDimension, TextureFormat},
view::Hdr,
@ -23,7 +23,7 @@ use bevy::{
fn main() {
App::new()
.add_plugins((DefaultPlugins, TemporalAntiAliasPlugin))
.add_plugins(DefaultPlugins)
.add_systems(Startup, setup)
.add_systems(Update, (modify_aa, modify_sharpening, update_ui))
.run();
@ -32,6 +32,7 @@ fn main() {
type TaaComponents = (
TemporalAntiAliasing,
TemporalJitter,
MipBias,
DepthPrepass,
MotionVectorPrepass,
);

View File

@ -3,7 +3,7 @@
use std::f32::consts::PI;
use bevy::{
anti_aliasing::experimental::taa::{TemporalAntiAliasPlugin, TemporalAntiAliasing},
anti_aliasing::taa::TemporalAntiAliasing,
core_pipeline::{
prepass::{DepthPrepass, MotionVectorPrepass},
Skybox,
@ -120,7 +120,6 @@ fn main() {
}),
..default()
}))
.add_plugins(TemporalAntiAliasPlugin)
.add_event::<WidgetClickEvent<AppSetting>>()
.add_systems(Startup, setup)
.add_systems(Update, widgets::handle_ui_interactions::<AppSetting>)

View File

@ -11,7 +11,7 @@
//! interactions change based on the density of the fog.
use bevy::{
anti_aliasing::experimental::taa::{TemporalAntiAliasPlugin, TemporalAntiAliasing},
anti_aliasing::taa::TemporalAntiAliasing,
core_pipeline::bloom::Bloom,
image::{
ImageAddressMode, ImageFilterMode, ImageLoaderSettings, ImageSampler,
@ -32,7 +32,6 @@ fn main() {
..default()
}))
.insert_resource(DirectionalLightShadowMap { size: 4096 })
.add_plugins(TemporalAntiAliasPlugin)
.add_systems(Startup, setup)
.add_systems(Update, scroll_fog)
.run();

View File

@ -1,7 +1,7 @@
//! A scene showcasing screen space ambient occlusion.
use bevy::{
anti_aliasing::experimental::taa::{TemporalAntiAliasPlugin, TemporalAntiAliasing},
anti_aliasing::taa::TemporalAntiAliasing,
math::ops,
pbr::{ScreenSpaceAmbientOcclusion, ScreenSpaceAmbientOcclusionQualityLevel},
prelude::*,
@ -15,7 +15,7 @@ fn main() {
brightness: 1000.,
..default()
})
.add_plugins((DefaultPlugins, TemporalAntiAliasPlugin))
.add_plugins(DefaultPlugins)
.add_systems(Startup, setup)
.add_systems(Update, update)
.run();

View File

@ -35,14 +35,17 @@ use bevy::{
},
};
// *Note:* TAA is not _required_ for specular transmission, but
// it _greatly enhances_ the look of the resulting blur effects.
// Sadly, it's not available under WebGL.
#[cfg(any(feature = "webgpu", not(target_arch = "wasm32")))]
use bevy::anti_aliasing::experimental::taa::{TemporalAntiAliasPlugin, TemporalAntiAliasing};
use bevy::anti_aliasing::taa::TemporalAntiAliasing;
use rand::random;
fn main() {
let mut app = App::new();
app.add_plugins(DefaultPlugins)
App::new()
.add_plugins(DefaultPlugins)
.insert_resource(ClearColor(Color::BLACK))
.insert_resource(PointLightShadowMap { size: 2048 })
.insert_resource(AmbientLight {
@ -50,15 +53,8 @@ fn main() {
..default()
})
.add_systems(Startup, setup)
.add_systems(Update, (example_control_system, flicker_system));
// *Note:* TAA is not _required_ for specular transmission, but
// it _greatly enhances_ the look of the resulting blur effects.
// Sadly, it's not available under WebGL.
#[cfg(any(feature = "webgpu", not(target_arch = "wasm32")))]
app.add_plugins(TemporalAntiAliasPlugin);
app.run();
.add_systems(Update, (example_control_system, flicker_system))
.run();
}
/// set up a simple 3D scene

View File

@ -0,0 +1,10 @@
---
title: TAA is no longer experimental
pull_requests: [18349]
---
TAA is no longer experimental.
`TemporalAntiAliasPlugin` no longer needs to be added to your app to use TAA. It is now part of DefaultPlugins/AntiAliasingPlugin.
`TemporalAntiAliasing` now uses `MipBias` as a required component in the main world, instead of overriding it manually in the render world.