diff --git a/crates/bevy_core_pipeline/src/core_3d/main_pass_3d_node.rs b/crates/bevy_core_pipeline/src/core_3d/main_pass_3d_node.rs index ec9aa7a6ff884..a57fc6af12971 100644 --- a/crates/bevy_core_pipeline/src/core_3d/main_pass_3d_node.rs +++ b/crates/bevy_core_pipeline/src/core_3d/main_pass_3d_node.rs @@ -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::>(); - 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); } @@ -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::>(); - 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); }