Skip to content

Commit

Permalink
Merge pull request bevyengine#9 from robtfm/patch-taa
Browse files Browse the repository at this point in the history
Patch taa
  • Loading branch information
JMS55 authored Mar 3, 2023
2 parents 51631c0 + 17771e5 commit 81e9d29
Show file tree
Hide file tree
Showing 11 changed files with 191 additions and 230 deletions.
7 changes: 7 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -641,6 +641,13 @@ description = "Showcases wireframe rendering"
category = "3D Rendering"
wasm = true

[[example]]
name = "no_prepass"
path = "tests/3d/no_prepass.rs"

[package.metadata.example.no_prepass]
hidden = true

# Animation
[[example]]
name = "animated_fox"
Expand Down
37 changes: 22 additions & 15 deletions crates/bevy_core_pipeline/src/prepass/node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -74,20 +74,22 @@ impl Node for PrepassNode {
}

let mut color_attachments = vec![];
if let Some(view_normals_texture) = &view_prepass_textures.normal {
color_attachments.push(Some(RenderPassColorAttachment {
view: &view_normals_texture.default_view,
resolve_target: None,
ops: Operations {
load: LoadOp::Clear(Color::BLACK.into()),
store: true,
},
}));
} else {
color_attachments.push(None);
}
if let Some(view_motion_vectors_texture) = &view_prepass_textures.motion_vectors {
color_attachments.push(Some(RenderPassColorAttachment {
color_attachments.push(
view_prepass_textures
.normal
.as_ref()
.map(|view_normals_texture| RenderPassColorAttachment {
view: &view_normals_texture.default_view,
resolve_target: None,
ops: Operations {
load: LoadOp::Clear(Color::BLACK.into()),
store: true,
},
}),
);

color_attachments.push(view_prepass_textures.motion_vectors.as_ref().map(
|view_motion_vectors_texture| RenderPassColorAttachment {
view: &view_motion_vectors_texture.default_view,
resolve_target: None,
ops: Operations {
Expand All @@ -96,7 +98,12 @@ impl Node for PrepassNode {
load: LoadOp::Clear(Color::rgb_linear(1.0, 1.0, 1.0).into()),
store: true,
},
}));
},
));

if color_attachments.iter().all(Option::is_none) {
// all attachments are none: clear the attachment list so that no fragment shader is required
color_attachments.clear();
}

{
Expand Down
3 changes: 2 additions & 1 deletion crates/bevy_core_pipeline/src/taa/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,7 @@ pub struct TemporalAntialiasBundle {
/// Cannot be used with [`bevy_render::camera::OrthographicProjection`].
///
/// Currently does not support skinned meshes. There will probably be ghosting artifacts if used with them.
/// 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.
/// Failure to do so will lead to ghosting artifacts. For instance, if particle effects
Expand Down Expand Up @@ -484,7 +485,7 @@ fn prepare_taa_jitter(
let offset = halton_sequence[frame_count.0 as usize % halton_sequence.len()];

for mut jitter in &mut query {
jitter.offset = offset;
jitter.offset = offset - 0.5;
}
}

Expand Down
195 changes: 47 additions & 148 deletions crates/bevy_ecs/src/schedule/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -82,112 +82,60 @@ fn ambiguous_with(graph_info: &mut GraphInfo, set: BoxedSystemSet) {
/// Types that can be converted into a [`SystemSetConfig`].
///
/// This has been implemented for all types that implement [`SystemSet`] and boxed trait objects.
pub trait IntoSystemSetConfig {
pub trait IntoSystemSetConfig: Sized {
/// Convert into a [`SystemSetConfig`].
#[doc(hidden)]
fn into_config(self) -> SystemSetConfig;
/// Add to the provided `set`.
#[track_caller]
fn in_set(self, set: impl FreeSystemSet) -> SystemSetConfig;
/// Add to the provided "base" `set`. For more information on base sets, see [`SystemSet::is_base`].
#[track_caller]
fn in_base_set(self, set: impl BaseSystemSet) -> SystemSetConfig;
/// Add this set to the schedules's default base set.
fn in_default_base_set(self) -> SystemSetConfig;
/// Run before all systems in `set`.
fn before<M>(self, set: impl IntoSystemSet<M>) -> SystemSetConfig;
/// Run after all systems in `set`.
fn after<M>(self, set: impl IntoSystemSet<M>) -> SystemSetConfig;
/// Run the systems in this set only if the [`Condition`] is `true`.
///
/// The `Condition` will be evaluated at most once (per schedule run),
/// the first time a system in this set prepares to run.
fn run_if<M>(self, condition: impl Condition<M>) -> SystemSetConfig;
/// Suppress warnings and errors that would result from systems in this set having ambiguities
/// (conflicting access but indeterminate order) with systems in `set`.
fn ambiguous_with<M>(self, set: impl IntoSystemSet<M>) -> SystemSetConfig;
/// Suppress warnings and errors that would result from systems in this set having ambiguities
/// (conflicting access but indeterminate order) with any other system.
fn ambiguous_with_all(self) -> SystemSetConfig;
}

impl<S: SystemSet> IntoSystemSetConfig for S {
fn into_config(self) -> SystemSetConfig {
SystemSetConfig::new(Box::new(self))
}

#[track_caller]
fn in_set(self, set: impl FreeSystemSet) -> SystemSetConfig {
self.into_config().in_set(set)
}

/// Add to the provided "base" `set`. For more information on base sets, see [`SystemSet::is_base`].
#[track_caller]
fn in_base_set(self, set: impl BaseSystemSet) -> SystemSetConfig {
self.into_config().in_base_set(set)
}

/// Add this set to the schedules's default base set.
fn in_default_base_set(self) -> SystemSetConfig {
self.into_config().in_default_base_set()
}

/// Run before all systems in `set`.
fn before<M>(self, set: impl IntoSystemSet<M>) -> SystemSetConfig {
self.into_config().before(set)
}

/// Run after all systems in `set`.
fn after<M>(self, set: impl IntoSystemSet<M>) -> SystemSetConfig {
self.into_config().after(set)
}

/// Run the systems in this set only if the [`Condition`] is `true`.
///
/// The `Condition` will be evaluated at most once (per schedule run),
/// the first time a system in this set prepares to run.
fn run_if<M>(self, condition: impl Condition<M>) -> SystemSetConfig {
self.into_config().run_if(condition)
}

/// Suppress warnings and errors that would result from systems in this set having ambiguities
/// (conflicting access but indeterminate order) with systems in `set`.
fn ambiguous_with<M>(self, set: impl IntoSystemSet<M>) -> SystemSetConfig {
self.into_config().ambiguous_with(set)
}

/// Suppress warnings and errors that would result from systems in this set having ambiguities
/// (conflicting access but indeterminate order) with any other system.
fn ambiguous_with_all(self) -> SystemSetConfig {
self.into_config().ambiguous_with_all()
}
}

impl IntoSystemSetConfig for BoxedSystemSet {
impl<S: SystemSet> IntoSystemSetConfig for S {
fn into_config(self) -> SystemSetConfig {
SystemSetConfig::new(self)
}

#[track_caller]
fn in_set(self, set: impl FreeSystemSet) -> SystemSetConfig {
self.into_config().in_set(set)
}

#[track_caller]
fn in_base_set(self, set: impl BaseSystemSet) -> SystemSetConfig {
self.into_config().in_base_set(set)
}

fn in_default_base_set(self) -> SystemSetConfig {
self.into_config().in_default_base_set()
}

fn before<M>(self, set: impl IntoSystemSet<M>) -> SystemSetConfig {
self.into_config().before(set)
}

fn after<M>(self, set: impl IntoSystemSet<M>) -> SystemSetConfig {
self.into_config().after(set)
}

fn run_if<M>(self, condition: impl Condition<M>) -> SystemSetConfig {
self.into_config().run_if(condition)
}

fn ambiguous_with<M>(self, set: impl IntoSystemSet<M>) -> SystemSetConfig {
self.into_config().ambiguous_with(set)
SystemSetConfig::new(Box::new(self))
}
}

fn ambiguous_with_all(self) -> SystemSetConfig {
self.into_config().ambiguous_with_all()
impl IntoSystemSetConfig for BoxedSystemSet {
fn into_config(self) -> SystemSetConfig {
SystemSetConfig::new(self)
}
}

Expand Down Expand Up @@ -273,33 +221,52 @@ impl IntoSystemSetConfig for SystemSetConfig {
///
/// This has been implemented for boxed [`System<In=(), Out=()>`](crate::system::System)
/// trait objects and all functions that turn into such.
pub trait IntoSystemConfig<Marker, Config = SystemConfig> {
pub trait IntoSystemConfig<Marker, Config = SystemConfig>: Sized
where
Config: IntoSystemConfig<(), Config>,
{
/// Convert into a [`SystemConfig`].
#[doc(hidden)]
fn into_config(self) -> Config;
/// Add to `set` membership.
#[track_caller]
fn in_set(self, set: impl FreeSystemSet) -> Config;
fn in_set(self, set: impl FreeSystemSet) -> Config {
self.into_config().in_set(set)
}
/// Add to the provided "base" `set`. For more information on base sets, see [`SystemSet::is_base`].
#[track_caller]
fn in_base_set(self, set: impl BaseSystemSet) -> Config;
fn in_base_set(self, set: impl BaseSystemSet) -> Config {
self.into_config().in_base_set(set)
}
/// Don't add this system to the schedules's default set.
fn no_default_base_set(self) -> Config;
fn no_default_base_set(self) -> Config {
self.into_config().no_default_base_set()
}
/// Run before all systems in `set`.
fn before<M>(self, set: impl IntoSystemSet<M>) -> Config;
fn before<M>(self, set: impl IntoSystemSet<M>) -> Config {
self.into_config().before(set)
}
/// Run after all systems in `set`.
fn after<M>(self, set: impl IntoSystemSet<M>) -> Config;
fn after<M>(self, set: impl IntoSystemSet<M>) -> Config {
self.into_config().after(set)
}
/// Run only if the [`Condition`] is `true`.
///
/// The `Condition` will be evaluated at most once (per schedule run),
/// when the system prepares to run.
fn run_if<M>(self, condition: impl Condition<M>) -> Config;
fn run_if<M>(self, condition: impl Condition<M>) -> Config {
self.into_config().run_if(condition)
}
/// Suppress warnings and errors that would result from this system having ambiguities
/// (conflicting access but indeterminate order) with systems in `set`.
fn ambiguous_with<M>(self, set: impl IntoSystemSet<M>) -> Config;
fn ambiguous_with<M>(self, set: impl IntoSystemSet<M>) -> Config {
self.into_config().ambiguous_with(set)
}
/// Suppress warnings and errors that would result from this system having ambiguities
/// (conflicting access but indeterminate order) with any other system.
fn ambiguous_with_all(self) -> Config;
fn ambiguous_with_all(self) -> Config {
self.into_config().ambiguous_with_all()
}
}

impl<Marker, F> IntoSystemConfig<Marker> for F
Expand All @@ -309,80 +276,12 @@ where
fn into_config(self) -> SystemConfig {
SystemConfig::new(Box::new(IntoSystem::into_system(self)))
}

#[track_caller]
fn in_set(self, set: impl FreeSystemSet) -> SystemConfig {
self.into_config().in_set(set)
}

#[track_caller]
fn in_base_set(self, set: impl BaseSystemSet) -> SystemConfig {
self.into_config().in_base_set(set)
}

fn no_default_base_set(self) -> SystemConfig {
self.into_config().no_default_base_set()
}

fn before<M>(self, set: impl IntoSystemSet<M>) -> SystemConfig {
self.into_config().before(set)
}

fn after<M>(self, set: impl IntoSystemSet<M>) -> SystemConfig {
self.into_config().after(set)
}

fn run_if<M>(self, condition: impl Condition<M>) -> SystemConfig {
self.into_config().run_if(condition)
}

fn ambiguous_with<M>(self, set: impl IntoSystemSet<M>) -> SystemConfig {
self.into_config().ambiguous_with(set)
}

fn ambiguous_with_all(self) -> SystemConfig {
self.into_config().ambiguous_with_all()
}
}

impl IntoSystemConfig<()> for BoxedSystem<(), ()> {
fn into_config(self) -> SystemConfig {
SystemConfig::new(self)
}

#[track_caller]
fn in_set(self, set: impl FreeSystemSet) -> SystemConfig {
self.into_config().in_set(set)
}

#[track_caller]
fn in_base_set(self, set: impl BaseSystemSet) -> SystemConfig {
self.into_config().in_base_set(set)
}

fn no_default_base_set(self) -> SystemConfig {
self.into_config().no_default_base_set()
}

fn before<M>(self, set: impl IntoSystemSet<M>) -> SystemConfig {
self.into_config().before(set)
}

fn after<M>(self, set: impl IntoSystemSet<M>) -> SystemConfig {
self.into_config().after(set)
}

fn run_if<M>(self, condition: impl Condition<M>) -> SystemConfig {
self.into_config().run_if(condition)
}

fn ambiguous_with<M>(self, set: impl IntoSystemSet<M>) -> SystemConfig {
self.into_config().ambiguous_with(set)
}

fn ambiguous_with_all(self) -> SystemConfig {
self.into_config().ambiguous_with_all()
}
}

impl IntoSystemConfig<()> for SystemConfig {
Expand Down
14 changes: 9 additions & 5 deletions crates/bevy_ecs/src/schedule/set.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,14 +37,18 @@ pub trait SystemSet: DynHash + Debug + Send + Sync + 'static {
fn dyn_clone(&self) -> Box<dyn SystemSet>;
}

/// A system set that is never contained in another set.
/// Systems and other system sets may only belong to one base set.
/// A marker trait for `SystemSet` types where [`is_base`] returns `true`.
/// This should only be implemented for types that satisfy this requirement.
/// It is automatically implemented for base set types by `#[derive(SystemSet)]`.
///
/// This should only be implemented for types that return `true` from [`SystemSet::is_base`].
/// [`is_base`]: SystemSet::is_base
pub trait BaseSystemSet: SystemSet {}

/// System sets that are *not* base sets. This should not be implemented for
/// any types that implement [`BaseSystemSet`].
/// A marker trait for `SystemSet` types where [`is_base`] returns `false`.
/// This should only be implemented for types that satisfy this requirement.
/// It is automatically implemented for non-base set types by `#[derive(SystemSet)]`.
///
/// [`is_base`]: SystemSet::is_base
pub trait FreeSystemSet: SystemSet {}

impl PartialEq for dyn SystemSet {
Expand Down
6 changes: 5 additions & 1 deletion crates/bevy_pbr/src/material.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use crate::{
render, AlphaMode, DrawMesh, DrawPrepass, EnvironmentMapLight, MeshPipeline, MeshPipelineKey,
MeshUniform, PrepassPlugin, RenderLightSystems, SetMeshBindGroup, SetMeshViewBindGroup, Shadow,
MeshUniform, PrepassPipelinePlugin, PrepassPlugin, RenderLightSystems, SetMeshBindGroup,
SetMeshViewBindGroup, Shadow,
};
use bevy_app::{App, IntoSystemAppConfig, Plugin};
use bevy_asset::{AddAsset, AssetEvent, AssetServer, Assets, Handle};
Expand Down Expand Up @@ -207,6 +208,9 @@ where
.add_system(queue_material_meshes::<M>.in_set(RenderSet::Queue));
}

// PrepassPipelinePlugin is required for shadow mapping and the optional PrepassPlugin
app.add_plugin(PrepassPipelinePlugin::<M>::default());

if self.prepass_enabled {
app.add_plugin(PrepassPlugin::<M>::default());
}
Expand Down
Loading

0 comments on commit 81e9d29

Please sign in to comment.