Skip to content

Commit

Permalink
render graph utils
Browse files Browse the repository at this point in the history
  • Loading branch information
IceSentry committed Mar 16, 2023
1 parent 3073d23 commit e59d32e
Show file tree
Hide file tree
Showing 5 changed files with 129 additions and 92 deletions.
76 changes: 28 additions & 48 deletions crates/bevy_core_pipeline/src/bloom/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,15 @@ mod upsampling_pipeline;

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

use crate::{core_2d, core_3d};
use crate::{add_node, core_2d, core_3d};
use bevy_app::{App, Plugin};
use bevy_asset::{load_internal_asset, HandleUntyped};
use bevy_ecs::{
prelude::{Component, Entity},
query::{QueryState, With},
schedule::IntoSystemConfig,
system::{Commands, Query, Res, ResMut},
world::World,
world::{FromWorld, World},
};
use bevy_math::UVec2;
use bevy_reflect::TypeUuid;
Expand All @@ -22,7 +22,7 @@ use bevy_render::{
ComponentUniforms, DynamicUniformIndex, ExtractComponentPlugin, UniformComponentPlugin,
},
prelude::Color,
render_graph::{Node, NodeRunError, RenderGraph, RenderGraphContext, SlotInfo, SlotType},
render_graph::{Node, NodeRunError, RenderGraphContext, SlotInfo, SlotType},
render_resource::*,
renderer::{RenderContext, RenderDevice},
texture::{CachedTexture, TextureCache},
Expand Down Expand Up @@ -79,54 +79,32 @@ impl Plugin for BloomPlugin {
));

// Add bloom to the 3d render graph
{
let bloom_node = BloomNode::new(&mut render_app.world);
let mut graph = render_app.world.resource_mut::<RenderGraph>();
let draw_3d_graph = graph
.get_sub_graph_mut(crate::core_3d::graph::NAME)
.unwrap();
draw_3d_graph.add_node(core_3d::graph::node::BLOOM, bloom_node);
draw_3d_graph.add_slot_edge(
draw_3d_graph.input_node().id,
crate::core_3d::graph::input::VIEW_ENTITY,
core_3d::graph::node::BLOOM,
BloomNode::IN_VIEW,
);
// MAIN_PASS -> BLOOM -> TONEMAPPING
draw_3d_graph.add_node_edge(
crate::core_3d::graph::node::MAIN_PASS,
core_3d::graph::node::BLOOM,
);
draw_3d_graph.add_node_edge(
add_node::<BloomNode>(
render_app,
core_3d::graph::NAME,
core_3d::graph::node::BLOOM,
core_3d::graph::input::VIEW_ENTITY,
BloomNode::IN_VIEW,
&[
core_3d::graph::node::MAIN_PASS,
core_3d::graph::node::BLOOM,
crate::core_3d::graph::node::TONEMAPPING,
);
}
core_3d::graph::node::TONEMAPPING,
],
);

// Add bloom to the 2d render graph
{
let bloom_node = BloomNode::new(&mut render_app.world);
let mut graph = render_app.world.resource_mut::<RenderGraph>();
let draw_2d_graph = graph
.get_sub_graph_mut(crate::core_2d::graph::NAME)
.unwrap();
draw_2d_graph.add_node(core_2d::graph::node::BLOOM, bloom_node);
draw_2d_graph.add_slot_edge(
draw_2d_graph.input_node().id,
crate::core_2d::graph::input::VIEW_ENTITY,
add_node::<BloomNode>(
render_app,
core_2d::graph::NAME,
core_2d::graph::node::BLOOM,
core_2d::graph::input::VIEW_ENTITY,
BloomNode::IN_VIEW,
&[
core_2d::graph::node::MAIN_PASS,
core_2d::graph::node::BLOOM,
BloomNode::IN_VIEW,
);
// MAIN_PASS -> BLOOM -> TONEMAPPING
draw_2d_graph.add_node_edge(
crate::core_2d::graph::node::MAIN_PASS,
core_2d::graph::node::BLOOM,
);
draw_2d_graph.add_node_edge(
core_2d::graph::node::BLOOM,
crate::core_2d::graph::node::TONEMAPPING,
);
}
core_2d::graph::node::TONEMAPPING,
],
);
}
}

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

impl BloomNode {
pub const IN_VIEW: &'static str = "view";
}

pub fn new(world: &mut World) -> Self {
impl FromWorld for BloomNode {
fn from_world(world: &mut World) -> Self {
Self {
view_query: QueryState::new(world),
}
Expand Down
63 changes: 21 additions & 42 deletions crates/bevy_core_pipeline/src/fxaa/mod.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::{core_2d, core_3d, fullscreen_vertex_shader::fullscreen_shader_vertex_state};
use crate::{add_node, core_2d, core_3d, fullscreen_vertex_shader::fullscreen_shader_vertex_state};
use bevy_app::prelude::*;
use bevy_asset::{load_internal_asset, HandleUntyped};
use bevy_derive::Deref;
Expand All @@ -9,7 +9,6 @@ use bevy_reflect::{
use bevy_render::{
extract_component::{ExtractComponent, ExtractComponentPlugin},
prelude::Camera,
render_graph::RenderGraph,
render_resource::*,
renderer::RenderDevice,
texture::BevyDefault,
Expand Down Expand Up @@ -92,52 +91,32 @@ impl Plugin for FxaaPlugin {
.init_resource::<SpecializedRenderPipelines<FxaaPipeline>>()
.add_system(prepare_fxaa_pipelines.in_set(RenderSet::Prepare));

{
let fxaa_node = FxaaNode::new(&mut render_app.world);
let mut binding = render_app.world.resource_mut::<RenderGraph>();
let graph = binding.get_sub_graph_mut(core_3d::graph::NAME).unwrap();

graph.add_node(core_3d::graph::node::FXAA, fxaa_node);

graph.add_slot_edge(
graph.input_node().id,
core_3d::graph::input::VIEW_ENTITY,
core_3d::graph::node::FXAA,
FxaaNode::IN_VIEW,
);

graph.add_node_edge(
// Add node to 3d graph
add_node::<FxaaNode>(
render_app,
core_3d::graph::NAME,
core_3d::graph::node::FXAA,
core_3d::graph::input::VIEW_ENTITY,
FxaaNode::IN_VIEW,
&[
core_3d::graph::node::TONEMAPPING,
core_3d::graph::node::FXAA,
);
graph.add_node_edge(
core_3d::graph::node::FXAA,
core_3d::graph::node::END_MAIN_PASS_POST_PROCESSING,
);
}
{
let fxaa_node = FxaaNode::new(&mut render_app.world);
let mut binding = render_app.world.resource_mut::<RenderGraph>();
let graph = binding.get_sub_graph_mut(core_2d::graph::NAME).unwrap();

graph.add_node(core_2d::graph::node::FXAA, fxaa_node);

graph.add_slot_edge(
graph.input_node().id,
core_2d::graph::input::VIEW_ENTITY,
core_2d::graph::node::FXAA,
FxaaNode::IN_VIEW,
);

graph.add_node_edge(
],
);
// Add node to 2d graph
add_node::<FxaaNode>(
render_app,
core_2d::graph::NAME,
core_2d::graph::node::FXAA,
core_2d::graph::input::VIEW_ENTITY,
FxaaNode::IN_VIEW,
&[
core_2d::graph::node::TONEMAPPING,
core_2d::graph::node::FXAA,
);
graph.add_node_edge(
core_2d::graph::node::FXAA,
core_2d::graph::node::END_MAIN_PASS_POST_PROCESSING,
);
}
],
);
}
}

Expand Down
4 changes: 3 additions & 1 deletion crates/bevy_core_pipeline/src/fxaa/node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,10 @@ pub struct FxaaNode {

impl FxaaNode {
pub const IN_VIEW: &'static str = "view";
}

pub fn new(world: &mut World) -> Self {
impl FromWorld for FxaaNode {
fn from_world(world: &mut World) -> Self {
Self {
query: QueryState::new(world),
cached_texture_bind_group: Mutex::new(None),
Expand Down
28 changes: 27 additions & 1 deletion crates/bevy_core_pipeline/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,12 @@ use crate::{
};
use bevy_app::{App, Plugin};
use bevy_asset::load_internal_asset;
use bevy_render::{extract_resource::ExtractResourcePlugin, prelude::Shader};
use bevy_ecs::world::FromWorld;
use bevy_render::{
extract_resource::ExtractResourcePlugin,
prelude::Shader,
render_graph::{Node, RenderGraph},
};

#[derive(Default)]
pub struct CorePipelinePlugin;
Expand Down Expand Up @@ -64,3 +69,24 @@ impl Plugin for CorePipelinePlugin {
.add_plugin(FxaaPlugin);
}
}

/// Utility function to add a [`Node`] to the [`RenderGraph`]
/// * Create the [`Node`] using the [`FromWorld`] implementation
/// * Add it to the graph
/// * Automatically add the required node edges based on the given ordering
pub fn add_node<T: Node + FromWorld>(
render_app: &mut App,
sub_graph_name: &'static str,
node_name: &'static str,
output_slot: &'static str,
input_slot: &'static str,
edges: &[&'static str],
) {
let node = T::from_world(&mut render_app.world);
let mut render_graph = render_app.world.resource_mut::<RenderGraph>();

let graph = render_graph.get_sub_graph_mut(sub_graph_name).unwrap();
graph.add_node_with_edges(node_name, node, edges);

graph.add_slot_edge(graph.input_node().id, output_slot, node_name, input_slot);
}
50 changes: 50 additions & 0 deletions crates/bevy_render/src/render_graph/graph.rs
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,26 @@ impl RenderGraph {
id
}

/// Adds the `node` with the `name` to the graph.
/// If the name is already present replaces it instead.
/// Also adds `node_edge` based on the order of the given `edges`.
pub fn add_node_with_edges<T>(
&mut self,
name: impl Into<Cow<'static, str>>,
node: T,
edges: &[&'static str],
) -> NodeId
where
T: Node,
{
let id = self.add_node(name, node);
for window in edges.windows(2) {
let [a, b] = window else { break; };
self.add_node_edge(*a, *b);
}
id
}

/// Removes the `node` with the `name` from the graph.
/// If the name is does not exist, nothing happens.
pub fn remove_node(
Expand Down Expand Up @@ -583,6 +603,36 @@ impl RenderGraph {
pub fn get_sub_graph_mut(&mut self, name: impl AsRef<str>) -> Option<&mut RenderGraph> {
self.sub_graphs.get_mut(name.as_ref())
}

/// Retrieves the sub graph corresponding to the `name`.
///
/// # Panics
///
/// Panics if any invalid node name is given.
///
/// # See also
///
/// - [`get_sub_graph`](Self::get_sub_graph) for a fallible version.
pub fn sub_graph(&self, name: impl AsRef<str>) -> &RenderGraph {
self.sub_graphs
.get(name.as_ref())
.unwrap_or_else(|| panic!("Node {} not found in sub_graph", name.as_ref()))
}

/// Retrieves the sub graph corresponding to the `name` mutably.
///
/// # Panics
///
/// Panics if any invalid node name is given.
///
/// # See also
///
/// - [`get_sub_graph_mut`](Self::get_sub_graph_mut) for a fallible version.
pub fn sub_graph_mut(&mut self, name: impl AsRef<str>) -> &mut RenderGraph {
self.sub_graphs
.get_mut(name.as_ref())
.unwrap_or_else(|| panic!("Node {} not found in sub_graph", name.as_ref()))
}
}

impl Debug for RenderGraph {
Expand Down

0 comments on commit e59d32e

Please sign in to comment.