From 8152d624439d070e6cc927e5b60a6f3275967ff6 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 b390a42ca1a8c8..64362f722e59ef 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 84e5f95783983d..893c1dfe4fbb18 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 61f9aa17c770db..02d4d0ca257e5e 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 28ddb9056c75eb..f7484fe76fc165 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();