Split opaque and transparent phases (#8090)
# Objective Fixes #8089. ## Solution Splits the MainPass3dNode into 2 nodes, one for the opaque + alpha passes and one for the transparent pass. --- ## Changelog - Split MainPass3dNode into MainOpaquePass3dNode and MainTransparentPass3dNode - Combine opaque and alpha phases in MainOpaquePass3dNode into one pass - Create `START_MAIN_PASS` and `END_MAIN_PASS` empty nodes as labels - Main pass becomes `START_MAIN_PASS -> MAIN_OPAQUE_PASS -> MAIN_TRANSPARENT_PASS -> END_MAIN_PASS` ## Migration Guide Nodes that previously added edges involving `MAIN_PASS` should now add edges to or from `START_MAIN_PASS` or `END_MAIN_PASS` respectively.
This commit is contained in:
parent
53667dea56
commit
ae31361949
@ -83,7 +83,7 @@ impl Plugin for BloomPlugin {
|
||||
draw_3d_graph.add_node(core_3d::graph::node::BLOOM, bloom_node);
|
||||
// MAIN_PASS -> BLOOM -> TONEMAPPING
|
||||
draw_3d_graph.add_node_edge(
|
||||
crate::core_3d::graph::node::MAIN_PASS,
|
||||
crate::core_3d::graph::node::END_MAIN_PASS,
|
||||
core_3d::graph::node::BLOOM,
|
||||
);
|
||||
draw_3d_graph.add_node_edge(
|
||||
|
||||
@ -0,0 +1,126 @@
|
||||
use crate::{
|
||||
clear_color::{ClearColor, ClearColorConfig},
|
||||
core_3d::{Camera3d, Opaque3d},
|
||||
prepass::{DepthPrepass, MotionVectorPrepass, NormalPrepass},
|
||||
};
|
||||
use bevy_ecs::prelude::*;
|
||||
use bevy_render::{
|
||||
camera::ExtractedCamera,
|
||||
render_graph::{Node, NodeRunError, RenderGraphContext},
|
||||
render_phase::RenderPhase,
|
||||
render_resource::{LoadOp, Operations, RenderPassDepthStencilAttachment, RenderPassDescriptor},
|
||||
renderer::RenderContext,
|
||||
view::{ExtractedView, ViewDepthTexture, ViewTarget},
|
||||
};
|
||||
#[cfg(feature = "trace")]
|
||||
use bevy_utils::tracing::info_span;
|
||||
|
||||
use super::{AlphaMask3d, Camera3dDepthLoadOp};
|
||||
|
||||
/// A [`Node`] that runs the [`Opaque3d`] and [`AlphaMask3d`] [`RenderPhase`].
|
||||
pub struct MainOpaquePass3dNode {
|
||||
query: QueryState<
|
||||
(
|
||||
&'static ExtractedCamera,
|
||||
&'static RenderPhase<Opaque3d>,
|
||||
&'static RenderPhase<AlphaMask3d>,
|
||||
&'static Camera3d,
|
||||
&'static ViewTarget,
|
||||
&'static ViewDepthTexture,
|
||||
Option<&'static DepthPrepass>,
|
||||
Option<&'static NormalPrepass>,
|
||||
Option<&'static MotionVectorPrepass>,
|
||||
),
|
||||
With<ExtractedView>,
|
||||
>,
|
||||
}
|
||||
|
||||
impl MainOpaquePass3dNode {
|
||||
pub fn new(world: &mut World) -> Self {
|
||||
Self {
|
||||
query: world.query_filtered(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Node for MainOpaquePass3dNode {
|
||||
fn update(&mut self, world: &mut World) {
|
||||
self.query.update_archetypes(world);
|
||||
}
|
||||
|
||||
fn run(
|
||||
&self,
|
||||
graph: &mut RenderGraphContext,
|
||||
render_context: &mut RenderContext,
|
||||
world: &World,
|
||||
) -> Result<(), NodeRunError> {
|
||||
let view_entity = graph.view_entity();
|
||||
let Ok((
|
||||
camera,
|
||||
opaque_phase,
|
||||
alpha_mask_phase,
|
||||
camera_3d,
|
||||
target,
|
||||
depth,
|
||||
depth_prepass,
|
||||
normal_prepass,
|
||||
motion_vector_prepass
|
||||
)) = self.query.get_manual(world, view_entity) else {
|
||||
// No window
|
||||
return Ok(());
|
||||
};
|
||||
|
||||
// Run the opaque pass, sorted front-to-back
|
||||
// NOTE: Scoped to drop the mutable borrow of render_context
|
||||
#[cfg(feature = "trace")]
|
||||
let _main_opaque_pass_3d_span = info_span!("main_opaque_pass_3d").entered();
|
||||
|
||||
let mut render_pass = render_context.begin_tracked_render_pass(RenderPassDescriptor {
|
||||
label: Some("main_opaque_pass_3d"),
|
||||
// NOTE: The opaque pass loads the color
|
||||
// buffer as well as writing to it.
|
||||
color_attachments: &[Some(target.get_color_attachment(Operations {
|
||||
load: match camera_3d.clear_color {
|
||||
ClearColorConfig::Default => {
|
||||
LoadOp::Clear(world.resource::<ClearColor>().0.into())
|
||||
}
|
||||
ClearColorConfig::Custom(color) => LoadOp::Clear(color.into()),
|
||||
ClearColorConfig::None => LoadOp::Load,
|
||||
},
|
||||
store: true,
|
||||
}))],
|
||||
depth_stencil_attachment: Some(RenderPassDepthStencilAttachment {
|
||||
view: &depth.view,
|
||||
// NOTE: The opaque main pass loads the depth buffer and possibly overwrites it
|
||||
depth_ops: Some(Operations {
|
||||
load: if depth_prepass.is_some()
|
||||
|| normal_prepass.is_some()
|
||||
|| motion_vector_prepass.is_some()
|
||||
{
|
||||
// if any prepass runs, it will generate a depth buffer so we should use it,
|
||||
// even if only the normal_prepass is used.
|
||||
Camera3dDepthLoadOp::Load
|
||||
} else {
|
||||
// NOTE: 0.0 is the far plane due to bevy's use of reverse-z projections.
|
||||
camera_3d.depth_load_op.clone()
|
||||
}
|
||||
.into(),
|
||||
store: true,
|
||||
}),
|
||||
stencil_ops: None,
|
||||
}),
|
||||
});
|
||||
|
||||
if let Some(viewport) = camera.viewport.as_ref() {
|
||||
render_pass.set_camera_viewport(viewport);
|
||||
}
|
||||
|
||||
opaque_phase.render(&mut render_pass, world, view_entity);
|
||||
|
||||
if !alpha_mask_phase.items.is_empty() {
|
||||
alpha_mask_phase.render(&mut render_pass, world, view_entity);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
@ -1,213 +0,0 @@
|
||||
use crate::{
|
||||
clear_color::{ClearColor, ClearColorConfig},
|
||||
core_3d::{AlphaMask3d, Camera3d, Opaque3d, Transparent3d},
|
||||
prepass::{DepthPrepass, MotionVectorPrepass, NormalPrepass},
|
||||
};
|
||||
use bevy_ecs::prelude::*;
|
||||
use bevy_render::{
|
||||
camera::ExtractedCamera,
|
||||
render_graph::{Node, NodeRunError, RenderGraphContext},
|
||||
render_phase::RenderPhase,
|
||||
render_resource::{LoadOp, Operations, RenderPassDepthStencilAttachment, RenderPassDescriptor},
|
||||
renderer::RenderContext,
|
||||
view::{ExtractedView, ViewDepthTexture, ViewTarget},
|
||||
};
|
||||
#[cfg(feature = "trace")]
|
||||
use bevy_utils::tracing::info_span;
|
||||
|
||||
use super::Camera3dDepthLoadOp;
|
||||
|
||||
pub struct MainPass3dNode {
|
||||
query: QueryState<
|
||||
(
|
||||
&'static ExtractedCamera,
|
||||
&'static RenderPhase<Opaque3d>,
|
||||
&'static RenderPhase<AlphaMask3d>,
|
||||
&'static RenderPhase<Transparent3d>,
|
||||
&'static Camera3d,
|
||||
&'static ViewTarget,
|
||||
&'static ViewDepthTexture,
|
||||
Option<&'static DepthPrepass>,
|
||||
Option<&'static NormalPrepass>,
|
||||
Option<&'static MotionVectorPrepass>,
|
||||
),
|
||||
With<ExtractedView>,
|
||||
>,
|
||||
}
|
||||
|
||||
impl MainPass3dNode {
|
||||
pub fn new(world: &mut World) -> Self {
|
||||
Self {
|
||||
query: world.query_filtered(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Node for MainPass3dNode {
|
||||
fn update(&mut self, world: &mut World) {
|
||||
self.query.update_archetypes(world);
|
||||
}
|
||||
|
||||
fn run(
|
||||
&self,
|
||||
graph: &mut RenderGraphContext,
|
||||
render_context: &mut RenderContext,
|
||||
world: &World,
|
||||
) -> Result<(), NodeRunError> {
|
||||
let view_entity = graph.view_entity();
|
||||
let Ok((
|
||||
camera,
|
||||
opaque_phase,
|
||||
alpha_mask_phase,
|
||||
transparent_phase,
|
||||
camera_3d,
|
||||
target,
|
||||
depth,
|
||||
depth_prepass,
|
||||
normal_prepass,
|
||||
motion_vector_prepass,
|
||||
)) = self.query.get_manual(world, view_entity) else {
|
||||
// No window
|
||||
return Ok(());
|
||||
};
|
||||
|
||||
// Always run opaque pass to ensure screen is cleared
|
||||
{
|
||||
// Run the opaque pass, sorted front-to-back
|
||||
// NOTE: Scoped to drop the mutable borrow of render_context
|
||||
#[cfg(feature = "trace")]
|
||||
let _main_opaque_pass_3d_span = info_span!("main_opaque_pass_3d").entered();
|
||||
|
||||
let mut render_pass = render_context.begin_tracked_render_pass(RenderPassDescriptor {
|
||||
label: Some("main_opaque_pass_3d"),
|
||||
// NOTE: The opaque pass loads the color
|
||||
// buffer as well as writing to it.
|
||||
color_attachments: &[Some(target.get_color_attachment(Operations {
|
||||
load: match camera_3d.clear_color {
|
||||
ClearColorConfig::Default => {
|
||||
LoadOp::Clear(world.resource::<ClearColor>().0.into())
|
||||
}
|
||||
ClearColorConfig::Custom(color) => LoadOp::Clear(color.into()),
|
||||
ClearColorConfig::None => LoadOp::Load,
|
||||
},
|
||||
store: true,
|
||||
}))],
|
||||
depth_stencil_attachment: Some(RenderPassDepthStencilAttachment {
|
||||
view: &depth.view,
|
||||
// NOTE: The opaque main pass loads the depth buffer and possibly overwrites it
|
||||
depth_ops: Some(Operations {
|
||||
load: if depth_prepass.is_some()
|
||||
|| normal_prepass.is_some()
|
||||
|| motion_vector_prepass.is_some()
|
||||
{
|
||||
// if any prepass runs, it will generate a depth buffer so we should use it,
|
||||
// even if only the normal_prepass is used.
|
||||
Camera3dDepthLoadOp::Load
|
||||
} else {
|
||||
// NOTE: 0.0 is the far plane due to bevy's use of reverse-z projections.
|
||||
camera_3d.depth_load_op.clone()
|
||||
}
|
||||
.into(),
|
||||
store: true,
|
||||
}),
|
||||
stencil_ops: None,
|
||||
}),
|
||||
});
|
||||
|
||||
if let Some(viewport) = camera.viewport.as_ref() {
|
||||
render_pass.set_camera_viewport(viewport);
|
||||
}
|
||||
|
||||
opaque_phase.render(&mut render_pass, world, view_entity);
|
||||
}
|
||||
|
||||
if !alpha_mask_phase.items.is_empty() {
|
||||
// Run the alpha mask pass, sorted front-to-back
|
||||
// NOTE: Scoped to drop the mutable borrow of render_context
|
||||
#[cfg(feature = "trace")]
|
||||
let _main_alpha_mask_pass_3d_span = info_span!("main_alpha_mask_pass_3d").entered();
|
||||
|
||||
let mut render_pass = render_context.begin_tracked_render_pass(RenderPassDescriptor {
|
||||
label: Some("main_alpha_mask_pass_3d"),
|
||||
// NOTE: The alpha_mask pass loads the color buffer as well as overwriting it where appropriate.
|
||||
color_attachments: &[Some(target.get_color_attachment(Operations {
|
||||
load: LoadOp::Load,
|
||||
store: true,
|
||||
}))],
|
||||
depth_stencil_attachment: Some(RenderPassDepthStencilAttachment {
|
||||
view: &depth.view,
|
||||
// NOTE: The alpha mask pass loads the depth buffer and possibly overwrites it
|
||||
depth_ops: Some(Operations {
|
||||
load: LoadOp::Load,
|
||||
store: true,
|
||||
}),
|
||||
stencil_ops: None,
|
||||
}),
|
||||
});
|
||||
|
||||
if let Some(viewport) = camera.viewport.as_ref() {
|
||||
render_pass.set_camera_viewport(viewport);
|
||||
}
|
||||
|
||||
alpha_mask_phase.render(&mut render_pass, world, view_entity);
|
||||
}
|
||||
|
||||
if !transparent_phase.items.is_empty() {
|
||||
// Run the transparent pass, sorted back-to-front
|
||||
// NOTE: Scoped to drop the mutable borrow of render_context
|
||||
#[cfg(feature = "trace")]
|
||||
let _main_transparent_pass_3d_span = info_span!("main_transparent_pass_3d").entered();
|
||||
|
||||
let mut render_pass = render_context.begin_tracked_render_pass(RenderPassDescriptor {
|
||||
label: Some("main_transparent_pass_3d"),
|
||||
// NOTE: The transparent pass loads the color buffer as well as overwriting it where appropriate.
|
||||
color_attachments: &[Some(target.get_color_attachment(Operations {
|
||||
load: LoadOp::Load,
|
||||
store: true,
|
||||
}))],
|
||||
depth_stencil_attachment: Some(RenderPassDepthStencilAttachment {
|
||||
view: &depth.view,
|
||||
// NOTE: For the transparent pass we load the depth buffer. There should be no
|
||||
// need to write to it, but store is set to `true` as a workaround for issue #3776,
|
||||
// https://github.com/bevyengine/bevy/issues/3776
|
||||
// so that wgpu does not clear the depth buffer.
|
||||
// As the opaque and alpha mask passes run first, opaque meshes can occlude
|
||||
// transparent ones.
|
||||
depth_ops: Some(Operations {
|
||||
load: LoadOp::Load,
|
||||
store: true,
|
||||
}),
|
||||
stencil_ops: None,
|
||||
}),
|
||||
});
|
||||
|
||||
if let Some(viewport) = camera.viewport.as_ref() {
|
||||
render_pass.set_camera_viewport(viewport);
|
||||
}
|
||||
|
||||
transparent_phase.render(&mut render_pass, world, view_entity);
|
||||
}
|
||||
|
||||
// WebGL2 quirk: if ending with a render pass with a custom viewport, the viewport isn't
|
||||
// reset for the next render pass so add an empty render pass without a custom viewport
|
||||
#[cfg(feature = "webgl")]
|
||||
if camera.viewport.is_some() {
|
||||
#[cfg(feature = "trace")]
|
||||
let _reset_viewport_pass_3d = info_span!("reset_viewport_pass_3d").entered();
|
||||
let pass_descriptor = RenderPassDescriptor {
|
||||
label: Some("reset_viewport_pass_3d"),
|
||||
color_attachments: &[Some(target.get_color_attachment(Operations {
|
||||
load: LoadOp::Load,
|
||||
store: true,
|
||||
}))],
|
||||
depth_stencil_attachment: None,
|
||||
};
|
||||
|
||||
render_context
|
||||
.command_encoder()
|
||||
.begin_render_pass(&pass_descriptor);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,115 @@
|
||||
use crate::core_3d::Transparent3d;
|
||||
use bevy_ecs::prelude::*;
|
||||
use bevy_render::{
|
||||
camera::ExtractedCamera,
|
||||
render_graph::{Node, NodeRunError, RenderGraphContext},
|
||||
render_phase::RenderPhase,
|
||||
render_resource::{LoadOp, Operations, RenderPassDepthStencilAttachment, RenderPassDescriptor},
|
||||
renderer::RenderContext,
|
||||
view::{ExtractedView, ViewDepthTexture, ViewTarget},
|
||||
};
|
||||
#[cfg(feature = "trace")]
|
||||
use bevy_utils::tracing::info_span;
|
||||
|
||||
/// A [`Node`] that runs the [`Transparent3d`] [`RenderPhase`].
|
||||
pub struct MainTransparentPass3dNode {
|
||||
query: QueryState<
|
||||
(
|
||||
&'static ExtractedCamera,
|
||||
&'static RenderPhase<Transparent3d>,
|
||||
&'static ViewTarget,
|
||||
&'static ViewDepthTexture,
|
||||
),
|
||||
With<ExtractedView>,
|
||||
>,
|
||||
}
|
||||
|
||||
impl MainTransparentPass3dNode {
|
||||
pub fn new(world: &mut World) -> Self {
|
||||
Self {
|
||||
query: world.query_filtered(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Node for MainTransparentPass3dNode {
|
||||
fn update(&mut self, world: &mut World) {
|
||||
self.query.update_archetypes(world);
|
||||
}
|
||||
|
||||
fn run(
|
||||
&self,
|
||||
graph: &mut RenderGraphContext,
|
||||
render_context: &mut RenderContext,
|
||||
world: &World,
|
||||
) -> Result<(), NodeRunError> {
|
||||
let view_entity = graph.view_entity();
|
||||
let Ok((
|
||||
camera,
|
||||
transparent_phase,
|
||||
target,
|
||||
depth,
|
||||
)) = self.query.get_manual(world, view_entity) else {
|
||||
// No window
|
||||
return Ok(());
|
||||
};
|
||||
|
||||
if !transparent_phase.items.is_empty() {
|
||||
// Run the transparent pass, sorted back-to-front
|
||||
// NOTE: Scoped to drop the mutable borrow of render_context
|
||||
#[cfg(feature = "trace")]
|
||||
let _main_transparent_pass_3d_span = info_span!("main_transparent_pass_3d").entered();
|
||||
|
||||
let mut render_pass = render_context.begin_tracked_render_pass(RenderPassDescriptor {
|
||||
label: Some("main_transparent_pass_3d"),
|
||||
// NOTE: The transparent pass loads the color buffer as well as overwriting it where appropriate.
|
||||
color_attachments: &[Some(target.get_color_attachment(Operations {
|
||||
load: LoadOp::Load,
|
||||
store: true,
|
||||
}))],
|
||||
depth_stencil_attachment: Some(RenderPassDepthStencilAttachment {
|
||||
view: &depth.view,
|
||||
// NOTE: For the transparent pass we load the depth buffer. There should be no
|
||||
// need to write to it, but store is set to `true` as a workaround for issue #3776,
|
||||
// https://github.com/bevyengine/bevy/issues/3776
|
||||
// so that wgpu does not clear the depth buffer.
|
||||
// As the opaque and alpha mask passes run first, opaque meshes can occlude
|
||||
// transparent ones.
|
||||
depth_ops: Some(Operations {
|
||||
load: LoadOp::Load,
|
||||
store: true,
|
||||
}),
|
||||
stencil_ops: None,
|
||||
}),
|
||||
});
|
||||
|
||||
if let Some(viewport) = camera.viewport.as_ref() {
|
||||
render_pass.set_camera_viewport(viewport);
|
||||
}
|
||||
|
||||
transparent_phase.render(&mut render_pass, world, view_entity);
|
||||
}
|
||||
|
||||
// WebGL2 quirk: if ending with a render pass with a custom viewport, the viewport isn't
|
||||
// reset for the next render pass so add an empty render pass without a custom viewport
|
||||
#[cfg(feature = "webgl")]
|
||||
if camera.viewport.is_some() {
|
||||
#[cfg(feature = "trace")]
|
||||
let _reset_viewport_pass_3d = info_span!("reset_viewport_pass_3d").entered();
|
||||
let pass_descriptor = RenderPassDescriptor {
|
||||
label: Some("reset_viewport_pass_3d"),
|
||||
color_attachments: &[Some(target.get_color_attachment(Operations {
|
||||
load: LoadOp::Load,
|
||||
store: true,
|
||||
}))],
|
||||
depth_stencil_attachment: None,
|
||||
};
|
||||
|
||||
render_context
|
||||
.command_encoder()
|
||||
.begin_render_pass(&pass_descriptor);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
@ -1,5 +1,6 @@
|
||||
mod camera_3d;
|
||||
mod main_pass_3d_node;
|
||||
mod main_opaque_pass_3d_node;
|
||||
mod main_transparent_pass_3d_node;
|
||||
|
||||
pub mod graph {
|
||||
pub const NAME: &str = "core_3d";
|
||||
@ -9,7 +10,10 @@ pub mod graph {
|
||||
pub mod node {
|
||||
pub const MSAA_WRITEBACK: &str = "msaa_writeback";
|
||||
pub const PREPASS: &str = "prepass";
|
||||
pub const MAIN_PASS: &str = "main_pass";
|
||||
pub const START_MAIN_PASS: &str = "start_main_pass";
|
||||
pub const MAIN_OPAQUE_PASS: &str = "main_opaque_pass";
|
||||
pub const MAIN_TRANSPARENT_PASS: &str = "main_transparent_pass";
|
||||
pub const END_MAIN_PASS: &str = "end_main_pass";
|
||||
pub const BLOOM: &str = "bloom";
|
||||
pub const TONEMAPPING: &str = "tonemapping";
|
||||
pub const FXAA: &str = "fxaa";
|
||||
@ -21,7 +25,8 @@ pub mod graph {
|
||||
use std::cmp::Reverse;
|
||||
|
||||
pub use camera_3d::*;
|
||||
pub use main_pass_3d_node::*;
|
||||
pub use main_opaque_pass_3d_node::*;
|
||||
pub use main_transparent_pass_3d_node::*;
|
||||
|
||||
use bevy_app::{App, Plugin};
|
||||
use bevy_ecs::prelude::*;
|
||||
@ -82,20 +87,33 @@ impl Plugin for Core3dPlugin {
|
||||
);
|
||||
|
||||
let prepass_node = PrepassNode::new(&mut render_app.world);
|
||||
let pass_node_3d = MainPass3dNode::new(&mut render_app.world);
|
||||
let opaque_node_3d = MainOpaquePass3dNode::new(&mut render_app.world);
|
||||
let transparent_node_3d = MainTransparentPass3dNode::new(&mut render_app.world);
|
||||
let tonemapping = TonemappingNode::new(&mut render_app.world);
|
||||
let upscaling = UpscalingNode::new(&mut render_app.world);
|
||||
let mut graph = render_app.world.resource_mut::<RenderGraph>();
|
||||
|
||||
let mut draw_3d_graph = RenderGraph::default();
|
||||
draw_3d_graph.add_node(graph::node::PREPASS, prepass_node);
|
||||
draw_3d_graph.add_node(graph::node::MAIN_PASS, pass_node_3d);
|
||||
draw_3d_graph.add_node(graph::node::START_MAIN_PASS, EmptyNode);
|
||||
draw_3d_graph.add_node(graph::node::MAIN_OPAQUE_PASS, opaque_node_3d);
|
||||
draw_3d_graph.add_node(graph::node::MAIN_TRANSPARENT_PASS, transparent_node_3d);
|
||||
draw_3d_graph.add_node(graph::node::END_MAIN_PASS, EmptyNode);
|
||||
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);
|
||||
|
||||
draw_3d_graph.add_node_edge(graph::node::PREPASS, graph::node::MAIN_PASS);
|
||||
draw_3d_graph.add_node_edge(graph::node::MAIN_PASS, graph::node::TONEMAPPING);
|
||||
draw_3d_graph.add_node_edge(graph::node::PREPASS, graph::node::START_MAIN_PASS);
|
||||
draw_3d_graph.add_node_edge(graph::node::START_MAIN_PASS, graph::node::MAIN_OPAQUE_PASS);
|
||||
draw_3d_graph.add_node_edge(
|
||||
graph::node::MAIN_OPAQUE_PASS,
|
||||
graph::node::MAIN_TRANSPARENT_PASS,
|
||||
);
|
||||
draw_3d_graph.add_node_edge(
|
||||
graph::node::MAIN_TRANSPARENT_PASS,
|
||||
graph::node::END_MAIN_PASS,
|
||||
);
|
||||
draw_3d_graph.add_node_edge(graph::node::END_MAIN_PASS, graph::node::TONEMAPPING);
|
||||
draw_3d_graph.add_node_edge(
|
||||
graph::node::TONEMAPPING,
|
||||
graph::node::END_MAIN_PASS_POST_PROCESSING,
|
||||
|
||||
@ -45,7 +45,7 @@ impl Plugin for MsaaWritebackPlugin {
|
||||
);
|
||||
core_3d.add_node_edge(
|
||||
crate::core_3d::graph::node::MSAA_WRITEBACK,
|
||||
crate::core_3d::graph::node::MAIN_PASS,
|
||||
crate::core_3d::graph::node::START_MAIN_PASS,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ -81,7 +81,7 @@ impl Plugin for TemporalAntiAliasPlugin {
|
||||
draw_3d_graph.add_node(draw_3d_graph::node::TAA, taa_node);
|
||||
// MAIN_PASS -> TAA -> BLOOM -> TONEMAPPING
|
||||
draw_3d_graph.add_node_edge(
|
||||
crate::core_3d::graph::node::MAIN_PASS,
|
||||
crate::core_3d::graph::node::END_MAIN_PASS,
|
||||
draw_3d_graph::node::TAA,
|
||||
);
|
||||
draw_3d_graph.add_node_edge(draw_3d_graph::node::TAA, crate::core_3d::graph::node::BLOOM);
|
||||
|
||||
@ -292,7 +292,7 @@ impl Plugin for PbrPlugin {
|
||||
draw_3d_graph.add_node(draw_3d_graph::node::SHADOW_PASS, shadow_pass_node);
|
||||
draw_3d_graph.add_node_edge(
|
||||
draw_3d_graph::node::SHADOW_PASS,
|
||||
bevy_core_pipeline::core_3d::graph::node::MAIN_PASS,
|
||||
bevy_core_pipeline::core_3d::graph::node::START_MAIN_PASS,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ -124,7 +124,7 @@ pub fn build_ui_render(app: &mut App) {
|
||||
RunGraphOnViewNode::new(draw_ui_graph::NAME),
|
||||
);
|
||||
graph_3d.add_node_edge(
|
||||
bevy_core_pipeline::core_3d::graph::node::MAIN_PASS,
|
||||
bevy_core_pipeline::core_3d::graph::node::END_MAIN_PASS,
|
||||
draw_ui_graph::node::UI_PASS,
|
||||
);
|
||||
graph_3d.add_node_edge(
|
||||
|
||||
Loading…
Reference in New Issue
Block a user