From c019a60b39c5683656025bc9d24a02744aa59dea Mon Sep 17 00:00:00 2001 From: Carter Anderson Date: Fri, 4 Nov 2022 22:19:02 +0000 Subject: [PATCH] Add "end of main pass post processing" render graph node (#6468) # Objective Bevy UI (and third party plugins) currently have no good way to position themselves after all post processing effects. They currently use the tonemapping node, but this is not adequate if there is anything after tonemapping (such as FXAA). ## Solution Add a logical `END_MAIN_PASS_POST_PROCESSING` RenderGraph node that main pass post processing effects position themselves before, and things like UIs can position themselves after. --- crates/bevy_core_pipeline/src/core_2d/mod.rs | 15 +++++++++++++-- crates/bevy_core_pipeline/src/core_3d/mod.rs | 15 +++++++++++++-- crates/bevy_core_pipeline/src/fxaa/mod.rs | 12 ++++++++++++ crates/bevy_ui/src/render/mod.rs | 4 ++-- 4 files changed, 40 insertions(+), 6 deletions(-) diff --git a/crates/bevy_core_pipeline/src/core_2d/mod.rs b/crates/bevy_core_pipeline/src/core_2d/mod.rs index b390a42ca1a8c..64362f722e59e 100644 --- a/crates/bevy_core_pipeline/src/core_2d/mod.rs +++ b/crates/bevy_core_pipeline/src/core_2d/mod.rs @@ -10,6 +10,7 @@ pub mod graph { pub const MAIN_PASS: &str = "main_pass"; pub const TONEMAPPING: &str = "tonemapping"; pub const UPSCALING: &str = "upscaling"; + pub const END_MAIN_PASS_POST_PROCESSING: &str = "end_main_pass_post_processing"; } } @@ -21,7 +22,7 @@ use bevy_ecs::prelude::*; use bevy_render::{ camera::Camera, extract_component::ExtractComponentPlugin, - render_graph::{RenderGraph, SlotInfo, SlotType}, + render_graph::{EmptyNode, RenderGraph, SlotInfo, SlotType}, render_phase::{ batch_phase_system, sort_phase_system, BatchedPhaseItem, CachedRenderPipelinePhaseItem, DrawFunctionId, DrawFunctions, EntityPhaseItem, PhaseItem, RenderPhase, @@ -63,6 +64,7 @@ impl Plugin for Core2dPlugin { let mut draw_2d_graph = RenderGraph::default(); draw_2d_graph.add_node(graph::node::MAIN_PASS, pass_node_2d); draw_2d_graph.add_node(graph::node::TONEMAPPING, tonemapping); + draw_2d_graph.add_node(graph::node::END_MAIN_PASS_POST_PROCESSING, EmptyNode); draw_2d_graph.add_node(graph::node::UPSCALING, upscaling); let input_node_id = draw_2d_graph.set_input(vec![SlotInfo::new( graph::input::VIEW_ENTITY, @@ -96,7 +98,16 @@ impl Plugin for Core2dPlugin { .add_node_edge(graph::node::MAIN_PASS, graph::node::TONEMAPPING) .unwrap(); draw_2d_graph - .add_node_edge(graph::node::TONEMAPPING, graph::node::UPSCALING) + .add_node_edge( + graph::node::TONEMAPPING, + graph::node::END_MAIN_PASS_POST_PROCESSING, + ) + .unwrap(); + draw_2d_graph + .add_node_edge( + graph::node::END_MAIN_PASS_POST_PROCESSING, + graph::node::UPSCALING, + ) .unwrap(); graph.add_sub_graph(graph::NAME, draw_2d_graph); } diff --git a/crates/bevy_core_pipeline/src/core_3d/mod.rs b/crates/bevy_core_pipeline/src/core_3d/mod.rs index 84e5f95783983..893c1dfe4fbb1 100644 --- a/crates/bevy_core_pipeline/src/core_3d/mod.rs +++ b/crates/bevy_core_pipeline/src/core_3d/mod.rs @@ -10,6 +10,7 @@ pub mod graph { pub const MAIN_PASS: &str = "main_pass"; pub const TONEMAPPING: &str = "tonemapping"; pub const UPSCALING: &str = "upscaling"; + pub const END_MAIN_PASS_POST_PROCESSING: &str = "end_main_pass_post_processing"; } } @@ -24,7 +25,7 @@ use bevy_render::{ camera::{Camera, ExtractedCamera}, extract_component::ExtractComponentPlugin, prelude::Msaa, - render_graph::{RenderGraph, SlotInfo, SlotType}, + render_graph::{EmptyNode, RenderGraph, SlotInfo, SlotType}, render_phase::{ sort_phase_system, CachedRenderPipelinePhaseItem, DrawFunctionId, DrawFunctions, EntityPhaseItem, PhaseItem, RenderPhase, @@ -73,6 +74,7 @@ impl Plugin for Core3dPlugin { let mut draw_3d_graph = RenderGraph::default(); draw_3d_graph.add_node(graph::node::MAIN_PASS, pass_node_3d); draw_3d_graph.add_node(graph::node::TONEMAPPING, tonemapping); + draw_3d_graph.add_node(graph::node::END_MAIN_PASS_POST_PROCESSING, EmptyNode); draw_3d_graph.add_node(graph::node::UPSCALING, upscaling); let input_node_id = draw_3d_graph.set_input(vec![SlotInfo::new( graph::input::VIEW_ENTITY, @@ -106,7 +108,16 @@ impl Plugin for Core3dPlugin { .add_node_edge(graph::node::MAIN_PASS, graph::node::TONEMAPPING) .unwrap(); draw_3d_graph - .add_node_edge(graph::node::TONEMAPPING, graph::node::UPSCALING) + .add_node_edge( + graph::node::TONEMAPPING, + graph::node::END_MAIN_PASS_POST_PROCESSING, + ) + .unwrap(); + draw_3d_graph + .add_node_edge( + graph::node::END_MAIN_PASS_POST_PROCESSING, + graph::node::UPSCALING, + ) .unwrap(); graph.add_sub_graph(graph::NAME, draw_3d_graph); } diff --git a/crates/bevy_core_pipeline/src/fxaa/mod.rs b/crates/bevy_core_pipeline/src/fxaa/mod.rs index 61f9aa17c770d..02d4d0ca257e5 100644 --- a/crates/bevy_core_pipeline/src/fxaa/mod.rs +++ b/crates/bevy_core_pipeline/src/fxaa/mod.rs @@ -118,6 +118,12 @@ impl Plugin for FxaaPlugin { graph .add_node_edge(core_3d::graph::node::TONEMAPPING, FXAA_NODE_3D) .unwrap(); + graph + .add_node_edge( + FXAA_NODE_3D, + core_3d::graph::node::END_MAIN_PASS_POST_PROCESSING, + ) + .unwrap(); } { let fxaa_node = FxaaNode::new(&mut render_app.world); @@ -138,6 +144,12 @@ impl Plugin for FxaaPlugin { graph .add_node_edge(core_2d::graph::node::TONEMAPPING, FXAA_NODE_2D) .unwrap(); + graph + .add_node_edge( + FXAA_NODE_2D, + core_2d::graph::node::END_MAIN_PASS_POST_PROCESSING, + ) + .unwrap(); } } } diff --git a/crates/bevy_ui/src/render/mod.rs b/crates/bevy_ui/src/render/mod.rs index 28ddb9056c75e..f7484fe76fc16 100644 --- a/crates/bevy_ui/src/render/mod.rs +++ b/crates/bevy_ui/src/render/mod.rs @@ -117,7 +117,7 @@ pub fn build_ui_render(app: &mut App) { .unwrap(); graph_2d .add_node_edge( - bevy_core_pipeline::core_2d::graph::node::TONEMAPPING, + bevy_core_pipeline::core_2d::graph::node::END_MAIN_PASS_POST_PROCESSING, draw_ui_graph::node::UI_PASS, ) .unwrap(); @@ -143,7 +143,7 @@ pub fn build_ui_render(app: &mut App) { .unwrap(); graph_3d .add_node_edge( - bevy_core_pipeline::core_3d::graph::node::TONEMAPPING, + bevy_core_pipeline::core_3d::graph::node::END_MAIN_PASS_POST_PROCESSING, draw_ui_graph::node::UI_PASS, ) .unwrap();