Skip to content

Commit 16d28cc

Browse files
authored
RenderGraph Labelization (#10644)
# Objective The whole `Cow<'static, str>` naming for nodes and subgraphs in `RenderGraph` is a mess. ## Solution Replaces hardcoded and potentially overlapping strings for nodes and subgraphs inside `RenderGraph` with bevy's labelsystem. --- ## Changelog * Two new labels: `RenderLabel` and `RenderSubGraph`. * Replaced all uses for hardcoded strings with those labels * Moved `Taa` label from its own mod to all the other `Labels3d` * `add_render_graph_edges` now needs a tuple of labels * Moved `ScreenSpaceAmbientOcclusion` label from its own mod with the `ShadowPass` label to `LabelsPbr` * Removed `NodeId` * Renamed `Edges.id()` to `Edges.label()` * Removed `NodeLabel` * Changed examples according to the new label system * Introduced new `RenderLabel`s: `Labels2d`, `Labels3d`, `LabelsPbr`, `LabelsUi` * Introduced new `RenderSubGraph`s: `SubGraph2d`, `SubGraph3d`, `SubGraphUi` * Removed `Reflect` and `Default` derive from `CameraRenderGraph` component struct * Improved some error messages ## Migration Guide For Nodes and SubGraphs, instead of using hardcoded strings, you now pass labels, which can be derived with structs and enums. ```rs // old #[derive(Default)] struct MyRenderNode; impl MyRenderNode { pub const NAME: &'static str = "my_render_node" } render_app .add_render_graph_node::<ViewNodeRunner<MyRenderNode>>( core_3d::graph::NAME, MyRenderNode::NAME, ) .add_render_graph_edges( core_3d::graph::NAME, &[ core_3d::graph::node::TONEMAPPING, MyRenderNode::NAME, core_3d::graph::node::END_MAIN_PASS_POST_PROCESSING, ], ); // new use bevy::core_pipeline::core_3d::graph::{Labels3d, SubGraph3d}; #[derive(Debug, Hash, PartialEq, Eq, Clone, RenderLabel)] pub struct MyRenderLabel; #[derive(Default)] struct MyRenderNode; render_app .add_render_graph_node::<ViewNodeRunner<MyRenderNode>>( SubGraph3d, MyRenderLabel, ) .add_render_graph_edges( SubGraph3d, ( Labels3d::Tonemapping, MyRenderLabel, Labels3d::EndMainPassPostProcessing, ), ); ``` ### SubGraphs #### in `bevy_core_pipeline::core_2d::graph` | old string-based path | new label | |-----------------------|-----------| | `NAME` | `SubGraph2d` | #### in `bevy_core_pipeline::core_3d::graph` | old string-based path | new label | |-----------------------|-----------| | `NAME` | `SubGraph3d` | #### in `bevy_ui::render` | old string-based path | new label | |-----------------------|-----------| | `draw_ui_graph::NAME` | `graph::SubGraphUi` | ### Nodes #### in `bevy_core_pipeline::core_2d::graph` | old string-based path | new label | |-----------------------|-----------| | `node::MSAA_WRITEBACK` | `Labels2d::MsaaWriteback` | | `node::MAIN_PASS` | `Labels2d::MainPass` | | `node::BLOOM` | `Labels2d::Bloom` | | `node::TONEMAPPING` | `Labels2d::Tonemapping` | | `node::FXAA` | `Labels2d::Fxaa` | | `node::UPSCALING` | `Labels2d::Upscaling` | | `node::CONTRAST_ADAPTIVE_SHARPENING` | `Labels2d::ConstrastAdaptiveSharpening` | | `node::END_MAIN_PASS_POST_PROCESSING` | `Labels2d::EndMainPassPostProcessing` | #### in `bevy_core_pipeline::core_3d::graph` | old string-based path | new label | |-----------------------|-----------| | `node::MSAA_WRITEBACK` | `Labels3d::MsaaWriteback` | | `node::PREPASS` | `Labels3d::Prepass` | | `node::DEFERRED_PREPASS` | `Labels3d::DeferredPrepass` | | `node::COPY_DEFERRED_LIGHTING_ID` | `Labels3d::CopyDeferredLightingId` | | `node::END_PREPASSES` | `Labels3d::EndPrepasses` | | `node::START_MAIN_PASS` | `Labels3d::StartMainPass` | | `node::MAIN_OPAQUE_PASS` | `Labels3d::MainOpaquePass` | | `node::MAIN_TRANSMISSIVE_PASS` | `Labels3d::MainTransmissivePass` | | `node::MAIN_TRANSPARENT_PASS` | `Labels3d::MainTransparentPass` | | `node::END_MAIN_PASS` | `Labels3d::EndMainPass` | | `node::BLOOM` | `Labels3d::Bloom` | | `node::TONEMAPPING` | `Labels3d::Tonemapping` | | `node::FXAA` | `Labels3d::Fxaa` | | `node::UPSCALING` | `Labels3d::Upscaling` | | `node::CONTRAST_ADAPTIVE_SHARPENING` | `Labels3d::ContrastAdaptiveSharpening` | | `node::END_MAIN_PASS_POST_PROCESSING` | `Labels3d::EndMainPassPostProcessing` | #### in `bevy_core_pipeline` | old string-based path | new label | |-----------------------|-----------| | `taa::draw_3d_graph::node::TAA` | `Labels3d::Taa` | #### in `bevy_pbr` | old string-based path | new label | |-----------------------|-----------| | `draw_3d_graph::node::SHADOW_PASS` | `LabelsPbr::ShadowPass` | | `ssao::draw_3d_graph::node::SCREEN_SPACE_AMBIENT_OCCLUSION` | `LabelsPbr::ScreenSpaceAmbientOcclusion` | | `deferred::DEFFERED_LIGHTING_PASS` | `LabelsPbr::DeferredLightingPass` | #### in `bevy_render` | old string-based path | new label | |-----------------------|-----------| | `main_graph::node::CAMERA_DRIVER` | `graph::CameraDriverLabel` | #### in `bevy_ui::render` | old string-based path | new label | |-----------------------|-----------| | `draw_ui_graph::node::UI_PASS` | `graph::LabelsUi::UiPass` | --- ## Future work * Make `NodeSlot`s also use types. Ideally, we have an enum with unit variants where every variant resembles one slot. Then to make sure you are using the right slot enum and make rust-analyzer play nicely with it, we should make an associated type in the `Node` trait. With today's system, we can introduce 3rd party slots to a node, and i wasnt sure if this was used, so I didn't do this in this PR. ## Unresolved Questions When looking at the `post_processing` example, we have a struct for the label and a struct for the node, this seems like boilerplate and on discord, @IceSentry (sowy for the ping) [asked](https://discord.com/channels/691052431525675048/743663924229963868/1175197016947699742) if a node could automatically introduce a label (or i completely misunderstood that). The problem with that is, that nodes like `EmptyNode` exist multiple times *inside the same* (sub)graph, so there we need extern labels to distinguish between those. Hopefully we can find a way to reduce boilerplate and still have everything unique. For EmptyNode, we could maybe make a macro which implements an "empty node" for a type, but for nodes which contain code and need to be present multiple times, this could get nasty...
1 parent b66f2fd commit 16d28cc

File tree

27 files changed

+725
-671
lines changed

27 files changed

+725
-671
lines changed

crates/bevy_core_pipeline/src/bloom/mod.rs

Lines changed: 12 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@ mod upsampling_pipeline;
55
pub use settings::{BloomCompositeMode, BloomPrefilterSettings, BloomSettings};
66

77
use crate::{
8-
core_2d::{self, CORE_2D},
9-
core_3d::{self, CORE_3D},
8+
core_2d::graph::{Labels2d, SubGraph2d},
9+
core_3d::graph::{Labels3d, SubGraph3d},
1010
};
1111
use bevy_app::{App, Plugin};
1212
use bevy_asset::{load_internal_asset, Handle};
@@ -72,30 +72,20 @@ impl Plugin for BloomPlugin {
7272
),
7373
)
7474
// Add bloom to the 3d render graph
75-
.add_render_graph_node::<ViewNodeRunner<BloomNode>>(
76-
CORE_3D,
77-
core_3d::graph::node::BLOOM,
78-
)
75+
.add_render_graph_node::<ViewNodeRunner<BloomNode>>(SubGraph3d, Labels3d::Bloom)
7976
.add_render_graph_edges(
80-
CORE_3D,
81-
&[
82-
core_3d::graph::node::END_MAIN_PASS,
83-
core_3d::graph::node::BLOOM,
84-
core_3d::graph::node::TONEMAPPING,
85-
],
77+
SubGraph3d,
78+
(
79+
Labels3d::EndMainPass,
80+
Labels3d::Bloom,
81+
Labels3d::Tonemapping,
82+
),
8683
)
8784
// Add bloom to the 2d render graph
88-
.add_render_graph_node::<ViewNodeRunner<BloomNode>>(
89-
CORE_2D,
90-
core_2d::graph::node::BLOOM,
91-
)
85+
.add_render_graph_node::<ViewNodeRunner<BloomNode>>(SubGraph2d, Labels2d::Bloom)
9286
.add_render_graph_edges(
93-
CORE_2D,
94-
&[
95-
core_2d::graph::node::MAIN_PASS,
96-
core_2d::graph::node::BLOOM,
97-
core_2d::graph::node::TONEMAPPING,
98-
],
87+
SubGraph2d,
88+
(Labels2d::MainPass, Labels2d::Bloom, Labels2d::Tonemapping),
9989
);
10090
}
10191

crates/bevy_core_pipeline/src/contrast_adaptive_sharpening/mod.rs

Lines changed: 26 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use crate::{
2-
core_2d::{self, CORE_2D},
3-
core_3d::{self, CORE_3D},
2+
core_2d::graph::{Labels2d, SubGraph2d},
3+
core_3d::graph::{Labels3d, SubGraph3d},
44
fullscreen_vertex_shader::fullscreen_shader_vertex_state,
55
};
66
use bevy_app::prelude::*;
@@ -124,31 +124,37 @@ impl Plugin for CASPlugin {
124124
.add_systems(Render, prepare_cas_pipelines.in_set(RenderSet::Prepare));
125125

126126
{
127-
use core_3d::graph::node::*;
128127
render_app
129-
.add_render_graph_node::<CASNode>(CORE_3D, CONTRAST_ADAPTIVE_SHARPENING)
130-
.add_render_graph_edge(CORE_3D, TONEMAPPING, CONTRAST_ADAPTIVE_SHARPENING)
128+
.add_render_graph_node::<CASNode>(SubGraph3d, Labels3d::ContrastAdaptiveSharpening)
129+
.add_render_graph_edge(
130+
SubGraph3d,
131+
Labels3d::Tonemapping,
132+
Labels3d::ContrastAdaptiveSharpening,
133+
)
131134
.add_render_graph_edges(
132-
CORE_3D,
133-
&[
134-
FXAA,
135-
CONTRAST_ADAPTIVE_SHARPENING,
136-
END_MAIN_PASS_POST_PROCESSING,
137-
],
135+
SubGraph3d,
136+
(
137+
Labels3d::Fxaa,
138+
Labels3d::ContrastAdaptiveSharpening,
139+
Labels3d::EndMainPassPostProcessing,
140+
),
138141
);
139142
}
140143
{
141-
use core_2d::graph::node::*;
142144
render_app
143-
.add_render_graph_node::<CASNode>(CORE_2D, CONTRAST_ADAPTIVE_SHARPENING)
144-
.add_render_graph_edge(CORE_2D, TONEMAPPING, CONTRAST_ADAPTIVE_SHARPENING)
145+
.add_render_graph_node::<CASNode>(SubGraph2d, Labels2d::ConstrastAdaptiveSharpening)
146+
.add_render_graph_edge(
147+
SubGraph2d,
148+
Labels2d::Tonemapping,
149+
Labels2d::ConstrastAdaptiveSharpening,
150+
)
145151
.add_render_graph_edges(
146-
CORE_2D,
147-
&[
148-
FXAA,
149-
CONTRAST_ADAPTIVE_SHARPENING,
150-
END_MAIN_PASS_POST_PROCESSING,
151-
],
152+
SubGraph2d,
153+
(
154+
Labels2d::Fxaa,
155+
Labels2d::ConstrastAdaptiveSharpening,
156+
Labels2d::EndMainPassPostProcessing,
157+
),
152158
);
153159
}
154160
}

crates/bevy_core_pipeline/src/core_2d/camera_2d.rs

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
1-
use crate::tonemapping::{DebandDither, Tonemapping};
1+
use crate::{
2+
core_3d::graph::SubGraph3d,
3+
tonemapping::{DebandDither, Tonemapping},
4+
};
25
use bevy_ecs::prelude::*;
36
use bevy_reflect::Reflect;
47
use bevy_render::{
@@ -12,6 +15,8 @@ use bevy_render::{
1215
};
1316
use bevy_transform::prelude::{GlobalTransform, Transform};
1417

18+
use super::graph::SubGraph2d;
19+
1520
#[derive(Component, Default, Reflect, Clone, ExtractComponent)]
1621
#[extract_component_filter(With<Camera>)]
1722
#[reflect(Component)]
@@ -49,7 +54,7 @@ impl Default for Camera2dBundle {
4954
projection.far(),
5055
);
5156
Self {
52-
camera_render_graph: CameraRenderGraph::new(crate::core_2d::graph::NAME),
57+
camera_render_graph: CameraRenderGraph::new(SubGraph2d),
5358
projection,
5459
visible_entities: VisibleEntities::default(),
5560
frustum,
@@ -88,7 +93,7 @@ impl Camera2dBundle {
8893
projection.far(),
8994
);
9095
Self {
91-
camera_render_graph: CameraRenderGraph::new(crate::core_2d::graph::NAME),
96+
camera_render_graph: CameraRenderGraph::new(SubGraph3d),
9297
projection,
9398
visible_entities: VisibleEntities::default(),
9499
frustum,

crates/bevy_core_pipeline/src/core_2d/mod.rs

Lines changed: 33 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -2,22 +2,27 @@ mod camera_2d;
22
mod main_pass_2d_node;
33

44
pub mod graph {
5-
pub const NAME: &str = "core_2d";
5+
use bevy_render::render_graph::{RenderLabel, RenderSubGraph};
6+
7+
#[derive(Debug, Hash, PartialEq, Eq, Clone, RenderSubGraph)]
8+
pub struct SubGraph2d;
9+
610
pub mod input {
711
pub const VIEW_ENTITY: &str = "view_entity";
812
}
9-
pub mod node {
10-
pub const MSAA_WRITEBACK: &str = "msaa_writeback";
11-
pub const MAIN_PASS: &str = "main_pass";
12-
pub const BLOOM: &str = "bloom";
13-
pub const TONEMAPPING: &str = "tonemapping";
14-
pub const FXAA: &str = "fxaa";
15-
pub const UPSCALING: &str = "upscaling";
16-
pub const CONTRAST_ADAPTIVE_SHARPENING: &str = "contrast_adaptive_sharpening";
17-
pub const END_MAIN_PASS_POST_PROCESSING: &str = "end_main_pass_post_processing";
13+
14+
#[derive(Debug, Hash, PartialEq, Eq, Clone, RenderLabel)]
15+
pub enum Labels2d {
16+
MsaaWriteback,
17+
MainPass,
18+
Bloom,
19+
Tonemapping,
20+
Fxaa,
21+
Upscaling,
22+
ConstrastAdaptiveSharpening,
23+
EndMainPassPostProcessing,
1824
}
1925
}
20-
pub const CORE_2D: &str = graph::NAME;
2126

2227
use std::ops::Range;
2328

@@ -41,6 +46,8 @@ use bevy_utils::{nonmax::NonMaxU32, FloatOrd};
4146

4247
use crate::{tonemapping::TonemappingNode, upscaling::UpscalingNode};
4348

49+
use self::graph::{Labels2d, SubGraph2d};
50+
4451
pub struct Core2dPlugin;
4552

4653
impl Plugin for Core2dPlugin {
@@ -60,21 +67,23 @@ impl Plugin for Core2dPlugin {
6067
sort_phase_system::<Transparent2d>.in_set(RenderSet::PhaseSort),
6168
);
6269

63-
use graph::node::*;
6470
render_app
65-
.add_render_sub_graph(CORE_2D)
66-
.add_render_graph_node::<MainPass2dNode>(CORE_2D, MAIN_PASS)
67-
.add_render_graph_node::<ViewNodeRunner<TonemappingNode>>(CORE_2D, TONEMAPPING)
68-
.add_render_graph_node::<EmptyNode>(CORE_2D, END_MAIN_PASS_POST_PROCESSING)
69-
.add_render_graph_node::<ViewNodeRunner<UpscalingNode>>(CORE_2D, UPSCALING)
71+
.add_render_sub_graph(SubGraph2d)
72+
.add_render_graph_node::<MainPass2dNode>(SubGraph2d, Labels2d::MainPass)
73+
.add_render_graph_node::<ViewNodeRunner<TonemappingNode>>(
74+
SubGraph2d,
75+
Labels2d::Tonemapping,
76+
)
77+
.add_render_graph_node::<EmptyNode>(SubGraph2d, Labels2d::EndMainPassPostProcessing)
78+
.add_render_graph_node::<ViewNodeRunner<UpscalingNode>>(SubGraph2d, Labels2d::Upscaling)
7079
.add_render_graph_edges(
71-
CORE_2D,
72-
&[
73-
MAIN_PASS,
74-
TONEMAPPING,
75-
END_MAIN_PASS_POST_PROCESSING,
76-
UPSCALING,
77-
],
80+
SubGraph2d,
81+
(
82+
Labels2d::MainPass,
83+
Labels2d::Tonemapping,
84+
Labels2d::EndMainPassPostProcessing,
85+
Labels2d::Upscaling,
86+
),
7887
);
7988
}
8089
}

crates/bevy_core_pipeline/src/core_3d/camera_3d.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ use bevy_render::{
1111
use bevy_transform::prelude::{GlobalTransform, Transform};
1212
use serde::{Deserialize, Serialize};
1313

14+
use super::graph::SubGraph3d;
15+
1416
/// Configuration for the "main 3d render graph".
1517
#[derive(Component, Reflect, Clone, ExtractComponent)]
1618
#[extract_component_filter(With<Camera>)]
@@ -150,7 +152,7 @@ pub struct Camera3dBundle {
150152
impl Default for Camera3dBundle {
151153
fn default() -> Self {
152154
Self {
153-
camera_render_graph: CameraRenderGraph::new(crate::core_3d::graph::NAME),
155+
camera_render_graph: CameraRenderGraph::new(SubGraph3d),
154156
camera: Default::default(),
155157
projection: Default::default(),
156158
visible_entities: Default::default(),

0 commit comments

Comments
 (0)