Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Smaller TAA fixes #10200

Merged
merged 9 commits into from
Oct 27, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion crates/bevy_core_pipeline/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,10 @@ pub use skybox::Skybox;
/// Experimental features that are not yet finished. Please report any issues you encounter!
pub mod experimental {
pub mod taa {
pub use crate::taa::*;
pub use crate::taa::{
TemporalAntiAliasBundle, TemporalAntiAliasNode, TemporalAntiAliasPlugin,
TemporalAntiAliasSettings,
};
}
}

Expand Down
63 changes: 34 additions & 29 deletions crates/bevy_core_pipeline/src/taa/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ use bevy_render::{
ExtractSchedule, MainWorld, Render, RenderApp, RenderSet,
};

mod draw_3d_graph {
pub mod draw_3d_graph {
pub mod node {
/// Label for the TAA render node.
pub const TAA: &str = "taa";
Expand All @@ -61,7 +61,7 @@ impl Plugin for TemporalAntiAliasPlugin {
};

render_app
.init_resource::<SpecializedRenderPipelines<TAAPipeline>>()
.init_resource::<SpecializedRenderPipelines<TaaPipeline>>()
.add_systems(ExtractSchedule, extract_taa_settings)
.add_systems(
Render,
Expand All @@ -71,7 +71,10 @@ impl Plugin for TemporalAntiAliasPlugin {
prepare_taa_history_textures.in_set(RenderSet::PrepareResources),
),
)
.add_render_graph_node::<ViewNodeRunner<TAANode>>(CORE_3D, draw_3d_graph::node::TAA)
.add_render_graph_node::<ViewNodeRunner<TemporalAntiAliasNode>>(
CORE_3D,
draw_3d_graph::node::TAA,
)
.add_render_graph_edges(
CORE_3D,
&[
Expand All @@ -88,7 +91,7 @@ impl Plugin for TemporalAntiAliasPlugin {
return;
};

render_app.init_resource::<TAAPipeline>();
render_app.init_resource::<TaaPipeline>();
}
}

Expand All @@ -110,14 +113,13 @@ pub struct TemporalAntiAliasBundle {
/// # Tradeoffs
///
/// Pros:
/// * Filters more types of aliasing than MSAA, such as textures and singular bright pixels (specular aliasing)
/// * Cost scales with screen/view resolution, unlike MSAA which scales with number of triangles
/// * Filters more types of aliasing than MSAA, such as textures and singular bright pixels
/// * Greatly increases the quality of stochastic rendering techniques such as SSAO, shadow mapping, etc
/// * Greatly increases the quality of stochastic rendering techniques such as SSAO, certain shadow map sampling methods, etc
///
/// Cons:
/// * Chance of "ghosting" - ghostly trails left behind moving objects
/// * Thin geometry, lighting detail, or texture lines may flicker or disappear
/// * Slightly blurs the image, leading to a softer look (using an additional sharpening pass can reduce this)
/// * Thin geometry, lighting detail, or texture lines may flicker noisily or disappear
///
/// Because TAA blends past frames with the current frame, when the frames differ too much
/// (such as with fast moving objects or camera cuts), ghosting artifacts may occur.
Expand All @@ -130,7 +132,7 @@ pub struct TemporalAntiAliasBundle {
/// and add the [`DepthPrepass`], [`MotionVectorPrepass`], and [`TemporalJitter`]
/// components to your camera.
///
/// Cannot be used with [`bevy_render::camera::OrthographicProjection`].
/// [Currently](https://github.com/bevyengine/bevy/issues/8423) cannot be used with [`bevy_render::camera::OrthographicProjection`].
///
/// Currently does not support skinned meshes and morph targets.
/// There will probably be ghosting artifacts if used with them.
Expand All @@ -151,7 +153,7 @@ pub struct TemporalAntiAliasSettings {
/// representative of the current frame, such as in sudden camera cuts.
///
/// After setting this to true, it will automatically be toggled
/// back to false after one frame.
/// back to false at the end of the frame.
pub reset: bool,
}

Expand All @@ -161,16 +163,17 @@ impl Default for TemporalAntiAliasSettings {
}
}

/// Render [`bevy_render::render_graph::Node`] used by temporal anti-aliasing.
#[derive(Default)]
struct TAANode;
pub struct TemporalAntiAliasNode;

impl ViewNode for TAANode {
impl ViewNode for TemporalAntiAliasNode {
type ViewQuery = (
&'static ExtractedCamera,
&'static ViewTarget,
&'static TAAHistoryTextures,
&'static TemporalAntiAliasHistoryTextures,
&'static ViewPrepassTextures,
&'static TAAPipelineId,
&'static TemporalAntiAliasPipelineId,
);

fn run(
Expand All @@ -183,7 +186,7 @@ impl ViewNode for TAANode {
world: &World,
) -> Result<(), NodeRunError> {
let (Some(pipelines), Some(pipeline_cache)) = (
world.get_resource::<TAAPipeline>(),
world.get_resource::<TaaPipeline>(),
world.get_resource::<PipelineCache>(),
) else {
return Ok(());
Expand Down Expand Up @@ -240,13 +243,13 @@ impl ViewNode for TAANode {
}

#[derive(Resource)]
struct TAAPipeline {
struct TaaPipeline {
taa_bind_group_layout: BindGroupLayout,
nearest_sampler: Sampler,
linear_sampler: Sampler,
}

impl FromWorld for TAAPipeline {
impl FromWorld for TaaPipeline {
fn from_world(world: &mut World) -> Self {
let render_device = world.resource::<RenderDevice>();

Expand Down Expand Up @@ -328,7 +331,7 @@ impl FromWorld for TAAPipeline {
],
});

TAAPipeline {
TaaPipeline {
taa_bind_group_layout,
nearest_sampler,
linear_sampler,
Expand All @@ -337,13 +340,13 @@ impl FromWorld for TAAPipeline {
}

#[derive(PartialEq, Eq, Hash, Clone)]
struct TAAPipelineKey {
struct TaaPipelineKey {
hdr: bool,
reset: bool,
}

impl SpecializedRenderPipeline for TAAPipeline {
type Key = TAAPipelineKey;
impl SpecializedRenderPipeline for TaaPipeline {
type Key = TaaPipelineKey;

fn specialize(&self, key: Self::Key) -> RenderPipelineDescriptor {
let mut shader_defs = vec![];
Expand Down Expand Up @@ -440,7 +443,7 @@ fn prepare_taa_jitter_and_mip_bias(
}

#[derive(Component)]
struct TAAHistoryTextures {
pub struct TemporalAntiAliasHistoryTextures {
write: CachedTexture,
read: CachedTexture,
}
Expand Down Expand Up @@ -480,12 +483,12 @@ fn prepare_taa_history_textures(
let history_2_texture = texture_cache.get(&render_device, texture_descriptor);

let textures = if frame_count.0 % 2 == 0 {
TAAHistoryTextures {
TemporalAntiAliasHistoryTextures {
write: history_1_texture,
read: history_2_texture,
}
} else {
TAAHistoryTextures {
TemporalAntiAliasHistoryTextures {
write: history_2_texture,
read: history_1_texture,
}
Expand All @@ -497,17 +500,17 @@ fn prepare_taa_history_textures(
}

#[derive(Component)]
struct TAAPipelineId(CachedRenderPipelineId);
pub struct TemporalAntiAliasPipelineId(CachedRenderPipelineId);

fn prepare_taa_pipelines(
mut commands: Commands,
pipeline_cache: Res<PipelineCache>,
mut pipelines: ResMut<SpecializedRenderPipelines<TAAPipeline>>,
pipeline: Res<TAAPipeline>,
mut pipelines: ResMut<SpecializedRenderPipelines<TaaPipeline>>,
pipeline: Res<TaaPipeline>,
views: Query<(Entity, &ExtractedView, &TemporalAntiAliasSettings)>,
) {
for (entity, view, taa_settings) in &views {
let mut pipeline_key = TAAPipelineKey {
let mut pipeline_key = TaaPipelineKey {
hdr: view.hdr,
reset: taa_settings.reset,
};
Expand All @@ -519,6 +522,8 @@ fn prepare_taa_pipelines(
pipelines.specialize(&pipeline_cache, &pipeline, pipeline_key);
}

commands.entity(entity).insert(TAAPipelineId(pipeline_id));
commands
.entity(entity)
.insert(TemporalAntiAliasPipelineId(pipeline_id));
}
}
9 changes: 8 additions & 1 deletion crates/bevy_core_pipeline/src/taa/taa.wgsl
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,14 @@ fn taa(@location(0) uv: vec2<f32>) -> Output {
// Blend current and past sample
// Use more of the history if we're confident in it (reduces noise when there is no motion)
// https://hhoppe.com/supersample.pdf, section 4.1
let current_color_factor = clamp(1.0 / history_confidence, MIN_HISTORY_BLEND_RATE, DEFAULT_HISTORY_BLEND_RATE);
var current_color_factor = clamp(1.0 / history_confidence, MIN_HISTORY_BLEND_RATE, DEFAULT_HISTORY_BLEND_RATE);

// Reject history when motion vectors point off screen
if any(saturate(history_uv) != history_uv) {
current_color_factor = 1.0;
history_confidence = 1.0;
}

current_color = mix(history_color, current_color, current_color_factor);
#endif // #ifndef RESET

Expand Down
4 changes: 2 additions & 2 deletions crates/bevy_pbr/src/prepass/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -185,7 +185,7 @@ pub fn update_previous_view_projections(
query: Query<(Entity, &Camera, &GlobalTransform), (With<Camera3d>, With<MotionVectorPrepass>)>,
) {
for (entity, camera, camera_transform) in &query {
commands.entity(entity).insert(PreviousViewProjection {
commands.entity(entity).try_insert(PreviousViewProjection {
view_proj: camera.projection_matrix() * camera_transform.compute_matrix().inverse(),
});
}
Expand All @@ -205,7 +205,7 @@ pub fn update_mesh_previous_global_transforms(
for (entity, transform) in &meshes {
commands
.entity(entity)
.insert(PreviousGlobalTransform(transform.affine()));
.try_insert(PreviousGlobalTransform(transform.affine()));
}
}
}
Expand Down