Skip to content

Commit

Permalink
Clean up 2d render phases (#12982)
Browse files Browse the repository at this point in the history
# Objective

Currently, the 2d pipeline only has a transparent pass that is used for
everything. I want to have separate passes for opaque/alpha
mask/transparent meshes just like in 3d.

This PR does the basic work to start adding new phases to the 2d
pipeline and get the current setup a bit closer to 3d.

## Solution

- Use `ViewNode` for `MainTransparentPass2dNode`
- Added `Node2d::StartMainPass`, `Node2d::EndMainPass`
- Rename everything to clarify that the main pass is currently the
transparent pass

---

## Changelog

- Added `Node2d::StartMainPass`, `Node2d::EndMainPass`

## Migration Guide

If you were using `Node2d::MainPass` to order your own custom render
node. You now need to order it relative to `Node2d::StartMainPass` or
`Node2d::EndMainPass`.
  • Loading branch information
IceSentry committed May 8, 2024
1 parent 0dddfa0 commit 64e1a78
Show file tree
Hide file tree
Showing 6 changed files with 41 additions and 50 deletions.
2 changes: 1 addition & 1 deletion crates/bevy_core_pipeline/src/bloom/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ impl Plugin for BloomPlugin {
.add_render_graph_node::<ViewNodeRunner<BloomNode>>(Core2d, Node2d::Bloom)
.add_render_graph_edges(
Core2d,
(Node2d::MainPass, Node2d::Bloom, Node2d::Tonemapping),
(Node2d::EndMainPass, Node2d::Bloom, Node2d::Tonemapping),
);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,67 +3,49 @@ use bevy_ecs::prelude::*;
use bevy_render::{
camera::ExtractedCamera,
diagnostic::RecordDiagnostics,
render_graph::{Node, NodeRunError, RenderGraphContext},
render_graph::{NodeRunError, RenderGraphContext, ViewNode},
render_phase::SortedRenderPhase,
render_resource::RenderPassDescriptor,
renderer::RenderContext,
view::{ExtractedView, ViewTarget},
view::ViewTarget,
};
#[cfg(feature = "trace")]
use bevy_utils::tracing::info_span;

pub struct MainPass2dNode {
query: QueryState<
(
&'static ExtractedCamera,
&'static SortedRenderPhase<Transparent2d>,
&'static ViewTarget,
),
With<ExtractedView>,
>,
}

impl FromWorld for MainPass2dNode {
fn from_world(world: &mut World) -> Self {
Self {
query: world.query_filtered(),
}
}
}
#[derive(Default)]
pub struct MainTransparentPass2dNode {}

impl Node for MainPass2dNode {
fn update(&mut self, world: &mut World) {
self.query.update_archetypes(world);
}
impl ViewNode for MainTransparentPass2dNode {
type ViewQuery = (
&'static ExtractedCamera,
&'static SortedRenderPhase<Transparent2d>,
&'static ViewTarget,
);

fn run(
fn run<'w>(
&self,
graph: &mut RenderGraphContext,
render_context: &mut RenderContext,
world: &World,
render_context: &mut RenderContext<'w>,
(camera, transparent_phase, target): bevy_ecs::query::QueryItem<'w, Self::ViewQuery>,
world: &'w World,
) -> Result<(), NodeRunError> {
let view_entity = graph.view_entity();
let Ok((camera, transparent_phase, target)) = self.query.get_manual(world, view_entity)
else {
// no target
return Ok(());
};

{
if !transparent_phase.items.is_empty() {
#[cfg(feature = "trace")]
let _main_pass_2d = info_span!("main_pass_2d").entered();
let _main_pass_2d = info_span!("main_transparent_pass_2d").entered();

let diagnostics = render_context.diagnostic_recorder();

let mut render_pass = render_context.begin_tracked_render_pass(RenderPassDescriptor {
label: Some("main_pass_2d"),
label: Some("main_transparent_pass_2d"),
color_attachments: &[Some(target.get_color_attachment())],
depth_stencil_attachment: None,
timestamp_writes: None,
occlusion_query_set: None,
});

let pass_span = diagnostics.pass_span(&mut render_pass, "main_pass_2d");
let pass_span = diagnostics.pass_span(&mut render_pass, "main_transparent_pass_2d");

if let Some(viewport) = camera.viewport.as_ref() {
render_pass.set_camera_viewport(viewport);
Expand Down
19 changes: 14 additions & 5 deletions crates/bevy_core_pipeline/src/core_2d/mod.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
mod camera_2d;
mod main_pass_2d_node;
mod main_transparent_pass_2d_node;

pub mod graph {
use bevy_render::render_graph::{RenderLabel, RenderSubGraph};
Expand All @@ -14,7 +14,9 @@ pub mod graph {
#[derive(Debug, Hash, PartialEq, Eq, Clone, RenderLabel)]
pub enum Node2d {
MsaaWriteback,
MainPass,
StartMainPass,
MainTransparentPass,
EndMainPass,
Bloom,
Tonemapping,
Fxaa,
Expand All @@ -27,7 +29,7 @@ pub mod graph {
use std::ops::Range;

pub use camera_2d::*;
pub use main_pass_2d_node::*;
pub use main_transparent_pass_2d_node::*;

use bevy_app::{App, Plugin};
use bevy_ecs::prelude::*;
Expand Down Expand Up @@ -68,14 +70,21 @@ impl Plugin for Core2dPlugin {

render_app
.add_render_sub_graph(Core2d)
.add_render_graph_node::<MainPass2dNode>(Core2d, Node2d::MainPass)
.add_render_graph_node::<EmptyNode>(Core2d, Node2d::StartMainPass)
.add_render_graph_node::<ViewNodeRunner<MainTransparentPass2dNode>>(
Core2d,
Node2d::MainTransparentPass,
)
.add_render_graph_node::<EmptyNode>(Core2d, Node2d::EndMainPass)
.add_render_graph_node::<ViewNodeRunner<TonemappingNode>>(Core2d, Node2d::Tonemapping)
.add_render_graph_node::<EmptyNode>(Core2d, Node2d::EndMainPassPostProcessing)
.add_render_graph_node::<ViewNodeRunner<UpscalingNode>>(Core2d, Node2d::Upscaling)
.add_render_graph_edges(
Core2d,
(
Node2d::MainPass,
Node2d::StartMainPass,
Node2d::MainTransparentPass,
Node2d::EndMainPass,
Node2d::Tonemapping,
Node2d::EndMainPassPostProcessing,
Node2d::Upscaling,
Expand Down
2 changes: 1 addition & 1 deletion crates/bevy_core_pipeline/src/msaa_writeback.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ impl Plugin for MsaaWritebackPlugin {
{
render_app
.add_render_graph_node::<MsaaWritebackNode>(Core2d, Node2d::MsaaWriteback)
.add_render_graph_edge(Core2d, Node2d::MsaaWriteback, Node2d::MainPass);
.add_render_graph_edge(Core2d, Node2d::MsaaWriteback, Node2d::StartMainPass);
}
{
render_app
Expand Down
12 changes: 6 additions & 6 deletions crates/bevy_sprite/src/mesh2d/material.rs
Original file line number Diff line number Diff line change
Expand Up @@ -389,7 +389,7 @@ pub fn queue_material2d_meshes<M: Material2d>(
}

for (view, visible_entities, tonemapping, dither, mut transparent_phase) in &mut views {
let draw_transparent_pbr = transparent_draw_functions.read().id::<DrawMaterial2d<M>>();
let draw_transparent_2d = transparent_draw_functions.read().id::<DrawMaterial2d<M>>();

let mut view_key = Mesh2dPipelineKey::from_msaa_samples(msaa.samples())
| Mesh2dPipelineKey::from_hdr(view.hdr);
Expand All @@ -410,7 +410,7 @@ pub fn queue_material2d_meshes<M: Material2d>(
let Some(mesh_instance) = render_mesh_instances.get_mut(visible_entity) else {
continue;
};
let Some(material2d) = render_materials.get(*material_asset_id) else {
let Some(material_2d) = render_materials.get(*material_asset_id) else {
continue;
};
let Some(mesh) = render_meshes.get(mesh_instance.mesh_asset_id) else {
Expand All @@ -424,7 +424,7 @@ pub fn queue_material2d_meshes<M: Material2d>(
&material2d_pipeline,
Material2dKey {
mesh_key,
bind_group_data: material2d.key.clone(),
bind_group_data: material_2d.key.clone(),
},
&mesh.layout,
);
Expand All @@ -437,18 +437,18 @@ pub fn queue_material2d_meshes<M: Material2d>(
}
};

mesh_instance.material_bind_group_id = material2d.get_bind_group_id();
mesh_instance.material_bind_group_id = material_2d.get_bind_group_id();

let mesh_z = mesh_instance.transforms.transform.translation.z;
transparent_phase.add(Transparent2d {
entity: *visible_entity,
draw_function: draw_transparent_pbr,
draw_function: draw_transparent_2d,
pipeline: pipeline_id,
// NOTE: Back-to-front ordering for transparent with ascending sort means far should have the
// lowest sort key and getting closer should increase. As we have
// -z in front of the camera, the largest distance is -far with values increasing toward the
// camera. As such we can just use mesh_z as the distance
sort_key: FloatOrd(mesh_z + material2d.depth_bias),
sort_key: FloatOrd(mesh_z + material_2d.depth_bias),
// Batching is done in batch_and_prepare_render_phase
batch_range: 0..1,
extra_index: PhaseItemExtraIndex::NONE,
Expand Down
2 changes: 1 addition & 1 deletion crates/bevy_ui/src/render/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ pub fn build_ui_render(app: &mut App) {
if let Some(graph_2d) = graph.get_sub_graph_mut(Core2d) {
graph_2d.add_sub_graph(SubGraphUi, ui_graph_2d);
graph_2d.add_node(NodeUi::UiPass, RunGraphOnViewNode::new(SubGraphUi));
graph_2d.add_node_edge(Node2d::MainPass, NodeUi::UiPass);
graph_2d.add_node_edge(Node2d::EndMainPass, NodeUi::UiPass);
graph_2d.add_node_edge(Node2d::EndMainPassPostProcessing, NodeUi::UiPass);
graph_2d.add_node_edge(NodeUi::UiPass, Node2d::Upscaling);
}
Expand Down

0 comments on commit 64e1a78

Please sign in to comment.