Skip to content

Commit bf1a3d9

Browse files
committed
render graph utils
1 parent e77eb00 commit bf1a3d9

File tree

5 files changed

+129
-92
lines changed

5 files changed

+129
-92
lines changed

crates/bevy_core_pipeline/src/bloom/mod.rs

Lines changed: 28 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,15 @@ mod upsampling_pipeline;
44

55
pub use settings::{BloomCompositeMode, BloomPrefilterSettings, BloomSettings};
66

7-
use crate::{core_2d, core_3d};
7+
use crate::{add_node, core_2d, core_3d};
88
use bevy_app::{App, Plugin};
99
use bevy_asset::{load_internal_asset, HandleUntyped};
1010
use bevy_ecs::{
1111
prelude::{Component, Entity},
1212
query::{QueryState, With},
1313
schedule::IntoSystemConfig,
1414
system::{Commands, Query, Res, ResMut},
15-
world::World,
15+
world::{FromWorld, World},
1616
};
1717
use bevy_math::UVec2;
1818
use bevy_reflect::TypeUuid;
@@ -22,7 +22,7 @@ use bevy_render::{
2222
ComponentUniforms, DynamicUniformIndex, ExtractComponentPlugin, UniformComponentPlugin,
2323
},
2424
prelude::Color,
25-
render_graph::{Node, NodeRunError, RenderGraph, RenderGraphContext, SlotInfo, SlotType},
25+
render_graph::{Node, NodeRunError, RenderGraphContext, SlotInfo, SlotType},
2626
render_resource::*,
2727
renderer::{RenderContext, RenderDevice},
2828
texture::{CachedTexture, TextureCache},
@@ -79,54 +79,32 @@ impl Plugin for BloomPlugin {
7979
));
8080

8181
// Add bloom to the 3d render graph
82-
{
83-
let bloom_node = BloomNode::new(&mut render_app.world);
84-
let mut graph = render_app.world.resource_mut::<RenderGraph>();
85-
let draw_3d_graph = graph
86-
.get_sub_graph_mut(crate::core_3d::graph::NAME)
87-
.unwrap();
88-
draw_3d_graph.add_node(core_3d::graph::node::BLOOM, bloom_node);
89-
draw_3d_graph.add_slot_edge(
90-
draw_3d_graph.input_node().id,
91-
crate::core_3d::graph::input::VIEW_ENTITY,
92-
core_3d::graph::node::BLOOM,
93-
BloomNode::IN_VIEW,
94-
);
95-
// MAIN_PASS -> BLOOM -> TONEMAPPING
96-
draw_3d_graph.add_node_edge(
97-
crate::core_3d::graph::node::MAIN_PASS,
98-
core_3d::graph::node::BLOOM,
99-
);
100-
draw_3d_graph.add_node_edge(
82+
add_node::<BloomNode>(
83+
render_app,
84+
core_3d::graph::NAME,
85+
core_3d::graph::node::BLOOM,
86+
core_3d::graph::input::VIEW_ENTITY,
87+
BloomNode::IN_VIEW,
88+
&[
89+
core_3d::graph::node::MAIN_PASS,
10190
core_3d::graph::node::BLOOM,
102-
crate::core_3d::graph::node::TONEMAPPING,
103-
);
104-
}
91+
core_3d::graph::node::TONEMAPPING,
92+
],
93+
);
10594

10695
// Add bloom to the 2d render graph
107-
{
108-
let bloom_node = BloomNode::new(&mut render_app.world);
109-
let mut graph = render_app.world.resource_mut::<RenderGraph>();
110-
let draw_2d_graph = graph
111-
.get_sub_graph_mut(crate::core_2d::graph::NAME)
112-
.unwrap();
113-
draw_2d_graph.add_node(core_2d::graph::node::BLOOM, bloom_node);
114-
draw_2d_graph.add_slot_edge(
115-
draw_2d_graph.input_node().id,
116-
crate::core_2d::graph::input::VIEW_ENTITY,
96+
add_node::<BloomNode>(
97+
render_app,
98+
core_2d::graph::NAME,
99+
core_2d::graph::node::BLOOM,
100+
core_2d::graph::input::VIEW_ENTITY,
101+
BloomNode::IN_VIEW,
102+
&[
103+
core_2d::graph::node::MAIN_PASS,
117104
core_2d::graph::node::BLOOM,
118-
BloomNode::IN_VIEW,
119-
);
120-
// MAIN_PASS -> BLOOM -> TONEMAPPING
121-
draw_2d_graph.add_node_edge(
122-
crate::core_2d::graph::node::MAIN_PASS,
123-
core_2d::graph::node::BLOOM,
124-
);
125-
draw_2d_graph.add_node_edge(
126-
core_2d::graph::node::BLOOM,
127-
crate::core_2d::graph::node::TONEMAPPING,
128-
);
129-
}
105+
core_2d::graph::node::TONEMAPPING,
106+
],
107+
);
130108
}
131109
}
132110

@@ -145,8 +123,10 @@ pub struct BloomNode {
145123

146124
impl BloomNode {
147125
pub const IN_VIEW: &'static str = "view";
126+
}
148127

149-
pub fn new(world: &mut World) -> Self {
128+
impl FromWorld for BloomNode {
129+
fn from_world(world: &mut World) -> Self {
150130
Self {
151131
view_query: QueryState::new(world),
152132
}

crates/bevy_core_pipeline/src/fxaa/mod.rs

Lines changed: 21 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use crate::{core_2d, core_3d, fullscreen_vertex_shader::fullscreen_shader_vertex_state};
1+
use crate::{add_node, core_2d, core_3d, fullscreen_vertex_shader::fullscreen_shader_vertex_state};
22
use bevy_app::prelude::*;
33
use bevy_asset::{load_internal_asset, HandleUntyped};
44
use bevy_derive::Deref;
@@ -9,7 +9,6 @@ use bevy_reflect::{
99
use bevy_render::{
1010
extract_component::{ExtractComponent, ExtractComponentPlugin},
1111
prelude::Camera,
12-
render_graph::RenderGraph,
1312
render_resource::*,
1413
renderer::RenderDevice,
1514
texture::BevyDefault,
@@ -92,52 +91,32 @@ impl Plugin for FxaaPlugin {
9291
.init_resource::<SpecializedRenderPipelines<FxaaPipeline>>()
9392
.add_system(prepare_fxaa_pipelines.in_set(RenderSet::Prepare));
9493

95-
{
96-
let fxaa_node = FxaaNode::new(&mut render_app.world);
97-
let mut binding = render_app.world.resource_mut::<RenderGraph>();
98-
let graph = binding.get_sub_graph_mut(core_3d::graph::NAME).unwrap();
99-
100-
graph.add_node(core_3d::graph::node::FXAA, fxaa_node);
101-
102-
graph.add_slot_edge(
103-
graph.input_node().id,
104-
core_3d::graph::input::VIEW_ENTITY,
105-
core_3d::graph::node::FXAA,
106-
FxaaNode::IN_VIEW,
107-
);
108-
109-
graph.add_node_edge(
94+
// Add node to 3d graph
95+
add_node::<FxaaNode>(
96+
render_app,
97+
core_3d::graph::NAME,
98+
core_3d::graph::node::FXAA,
99+
core_3d::graph::input::VIEW_ENTITY,
100+
FxaaNode::IN_VIEW,
101+
&[
110102
core_3d::graph::node::TONEMAPPING,
111103
core_3d::graph::node::FXAA,
112-
);
113-
graph.add_node_edge(
114-
core_3d::graph::node::FXAA,
115104
core_3d::graph::node::END_MAIN_PASS_POST_PROCESSING,
116-
);
117-
}
118-
{
119-
let fxaa_node = FxaaNode::new(&mut render_app.world);
120-
let mut binding = render_app.world.resource_mut::<RenderGraph>();
121-
let graph = binding.get_sub_graph_mut(core_2d::graph::NAME).unwrap();
122-
123-
graph.add_node(core_2d::graph::node::FXAA, fxaa_node);
124-
125-
graph.add_slot_edge(
126-
graph.input_node().id,
127-
core_2d::graph::input::VIEW_ENTITY,
128-
core_2d::graph::node::FXAA,
129-
FxaaNode::IN_VIEW,
130-
);
131-
132-
graph.add_node_edge(
105+
],
106+
);
107+
// Add node to 2d graph
108+
add_node::<FxaaNode>(
109+
render_app,
110+
core_2d::graph::NAME,
111+
core_2d::graph::node::FXAA,
112+
core_2d::graph::input::VIEW_ENTITY,
113+
FxaaNode::IN_VIEW,
114+
&[
133115
core_2d::graph::node::TONEMAPPING,
134116
core_2d::graph::node::FXAA,
135-
);
136-
graph.add_node_edge(
137-
core_2d::graph::node::FXAA,
138117
core_2d::graph::node::END_MAIN_PASS_POST_PROCESSING,
139-
);
140-
}
118+
],
119+
);
141120
}
142121
}
143122

crates/bevy_core_pipeline/src/fxaa/node.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,10 @@ pub struct FxaaNode {
2929

3030
impl FxaaNode {
3131
pub const IN_VIEW: &'static str = "view";
32+
}
3233

33-
pub fn new(world: &mut World) -> Self {
34+
impl FromWorld for FxaaNode {
35+
fn from_world(world: &mut World) -> Self {
3436
Self {
3537
query: QueryState::new(world),
3638
cached_texture_bind_group: Mutex::new(None),

crates/bevy_core_pipeline/src/lib.rs

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,12 @@ use crate::{
3434
};
3535
use bevy_app::{App, Plugin};
3636
use bevy_asset::load_internal_asset;
37-
use bevy_render::{extract_resource::ExtractResourcePlugin, prelude::Shader};
37+
use bevy_ecs::world::FromWorld;
38+
use bevy_render::{
39+
extract_resource::ExtractResourcePlugin,
40+
prelude::Shader,
41+
render_graph::{Node, RenderGraph},
42+
};
3843

3944
#[derive(Default)]
4045
pub struct CorePipelinePlugin;
@@ -64,3 +69,24 @@ impl Plugin for CorePipelinePlugin {
6469
.add_plugin(FxaaPlugin);
6570
}
6671
}
72+
73+
/// Utility function to add a [`Node`] to the [`RenderGraph`]
74+
/// * Create the [`Node`] using the [`FromWorld`] implementation
75+
/// * Add it to the graph
76+
/// * Automatically add the required node edges based on the given ordering
77+
pub fn add_node<T: Node + FromWorld>(
78+
render_app: &mut App,
79+
sub_graph_name: &'static str,
80+
node_name: &'static str,
81+
output_slot: &'static str,
82+
input_slot: &'static str,
83+
edges: &[&'static str],
84+
) {
85+
let node = T::from_world(&mut render_app.world);
86+
let mut render_graph = render_app.world.resource_mut::<RenderGraph>();
87+
88+
let graph = render_graph.get_sub_graph_mut(sub_graph_name).unwrap();
89+
graph.add_node_with_edges(node_name, node, edges);
90+
91+
graph.add_slot_edge(graph.input_node().id, output_slot, node_name, input_slot);
92+
}

crates/bevy_render/src/render_graph/graph.rs

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,26 @@ impl RenderGraph {
119119
id
120120
}
121121

122+
/// Adds the `node` with the `name` to the graph.
123+
/// If the name is already present replaces it instead.
124+
/// Also adds `node_edge` based on the order of the given `edges`.
125+
pub fn add_node_with_edges<T>(
126+
&mut self,
127+
name: impl Into<Cow<'static, str>>,
128+
node: T,
129+
edges: &[&'static str],
130+
) -> NodeId
131+
where
132+
T: Node,
133+
{
134+
let id = self.add_node(name, node);
135+
for window in edges.windows(2) {
136+
let [a, b] = window else { break; };
137+
self.add_node_edge(*a, *b);
138+
}
139+
id
140+
}
141+
122142
/// Removes the `node` with the `name` from the graph.
123143
/// If the name is does not exist, nothing happens.
124144
pub fn remove_node(
@@ -583,6 +603,36 @@ impl RenderGraph {
583603
pub fn get_sub_graph_mut(&mut self, name: impl AsRef<str>) -> Option<&mut RenderGraph> {
584604
self.sub_graphs.get_mut(name.as_ref())
585605
}
606+
607+
/// Retrieves the sub graph corresponding to the `name`.
608+
///
609+
/// # Panics
610+
///
611+
/// Panics if any invalid node name is given.
612+
///
613+
/// # See also
614+
///
615+
/// - [`get_sub_graph`](Self::get_sub_graph) for a fallible version.
616+
pub fn sub_graph(&self, name: impl AsRef<str>) -> &RenderGraph {
617+
self.sub_graphs
618+
.get(name.as_ref())
619+
.unwrap_or_else(|| panic!("Node {} not found in sub_graph", name.as_ref()))
620+
}
621+
622+
/// Retrieves the sub graph corresponding to the `name` mutably.
623+
///
624+
/// # Panics
625+
///
626+
/// Panics if any invalid node name is given.
627+
///
628+
/// # See also
629+
///
630+
/// - [`get_sub_graph_mut`](Self::get_sub_graph_mut) for a fallible version.
631+
pub fn sub_graph_mut(&mut self, name: impl AsRef<str>) -> &mut RenderGraph {
632+
self.sub_graphs
633+
.get_mut(name.as_ref())
634+
.unwrap_or_else(|| panic!("Node {} not found in sub_graph", name.as_ref()))
635+
}
586636
}
587637

588638
impl Debug for RenderGraph {

0 commit comments

Comments
 (0)