Skip to content

Commit

Permalink
bevy_core_pipeline: Merge main_pass_3d mask and transparent passes in…
Browse files Browse the repository at this point in the history
…to one

They use the same configuration so merging them gives better performance,
particularly on mobile, as the attachments have to be written out and read in
between passes.
  • Loading branch information
superdump committed Jun 21, 2022
1 parent c4fc5d8 commit edadd96
Showing 1 changed file with 30 additions and 49 deletions.
79 changes: 30 additions & 49 deletions crates/bevy_core_pipeline/src/core_3d/main_pass_3d_node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -111,36 +111,44 @@ impl Node for MainPass3dNode {
}
}

let pass_descriptor = RenderPassDescriptor {
label: Some("main_alpha_mask_and_transparent_pass_3d"),
// NOTE: The alpha_mask and transparent passes load the color buffer as well as
// overwriting it where appropriate.
color_attachments: &[target.get_color_attachment(Operations {
load: LoadOp::Load,
store: true,
})],
depth_stencil_attachment: Some(RenderPassDepthStencilAttachment {
view: &depth.view,
// NOTE: The alpha mask and transparent passes load the depth buffer and possibly
// overwrite it
// 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,
}),
};
let render_pass = render_context
.command_encoder
.begin_render_pass(&pass_descriptor);
let mut tracked_pass = TrackedRenderPass::new(render_pass);

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 pass_descriptor = 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: &[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,
}),
};

let draw_functions = world.resource::<DrawFunctions<AlphaMask3d>>();

let render_pass = render_context
.command_encoder
.begin_render_pass(&pass_descriptor);
let mut draw_functions = draw_functions.write();
let mut tracked_pass = TrackedRenderPass::new(render_pass);
if let Some(viewport) = camera.viewport.as_ref() {
tracked_pass.set_camera_viewport(viewport);
}
Expand All @@ -152,39 +160,12 @@ impl Node for MainPass3dNode {

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 pass_descriptor = RenderPassDescriptor {
label: Some("main_transparent_pass_3d"),
// NOTE: The transparent pass loads the color buffer as well as overwriting it where appropriate.
color_attachments: &[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,
}),
};

let draw_functions = world.resource::<DrawFunctions<Transparent3d>>();

let render_pass = render_context
.command_encoder
.begin_render_pass(&pass_descriptor);
let mut draw_functions = draw_functions.write();
let mut tracked_pass = TrackedRenderPass::new(render_pass);
if let Some(viewport) = camera.viewport.as_ref() {
tracked_pass.set_camera_viewport(viewport);
}
Expand Down

0 comments on commit edadd96

Please sign in to comment.