From 1077bc59a2e2e853c2699023afab750a3c7b8300 Mon Sep 17 00:00:00 2001 From: Nils Hasenbanck Date: Wed, 18 Dec 2024 18:04:51 +0100 Subject: [PATCH] Change render order of entities and models This lets entities properly draw their transparent parts. Our draw order now is: Model Opaque -> Entities -> Model Transparent --- korangar/src/graphics/engine.rs | 12 ++- korangar/src/graphics/passes/forward/mod.rs | 2 +- korangar/src/graphics/passes/forward/model.rs | 94 +++++++++++-------- 3 files changed, 64 insertions(+), 44 deletions(-) diff --git a/korangar/src/graphics/engine.rs b/korangar/src/graphics/engine.rs index 7b73513c..2fa80173 100644 --- a/korangar/src/graphics/engine.rs +++ b/korangar/src/graphics/engine.rs @@ -991,20 +991,28 @@ impl GraphicsEngine { .forward_pass_context .create_pass(&mut forward_encoder, &engine_context.global_context, None); - let draw_data = ModelBatchDrawData { + let batch_data = &ModelBatchDrawData { batches: instruction.model_batches, instructions: instruction.models, #[cfg(feature = "debug")] show_wireframe: instruction.render_settings.show_wireframe, }; + engine_context.forward_model_drawer.draw(&mut render_pass, ForwardModelDrawData { + batch_data, + draw_transparent: false, + }); + engine_context.forward_entity_drawer.draw(&mut render_pass, instruction.entities); engine_context .forward_indicator_drawer .draw(&mut render_pass, instruction.indicator.as_ref()); - engine_context.forward_model_drawer.draw(&mut render_pass, draw_data); + engine_context.forward_model_drawer.draw(&mut render_pass, ForwardModelDrawData { + batch_data, + draw_transparent: true, + }); #[cfg(feature = "debug")] { diff --git a/korangar/src/graphics/passes/forward/mod.rs b/korangar/src/graphics/passes/forward/mod.rs index 3ff78a0b..f47327a0 100644 --- a/korangar/src/graphics/passes/forward/mod.rs +++ b/korangar/src/graphics/passes/forward/mod.rs @@ -14,7 +14,7 @@ pub(crate) use aabb::ForwardAabbDrawer; pub(crate) use circle::ForwardCircleDrawer; pub(crate) use entity::ForwardEntityDrawer; pub(crate) use indicator::ForwardIndicatorDrawer; -pub(crate) use model::ForwardModelDrawer; +pub(crate) use model::{ForwardModelDrawData, ForwardModelDrawer}; #[cfg(feature = "debug")] pub(crate) use rectangle::ForwardRectangleDrawer; use wgpu::{ diff --git a/korangar/src/graphics/passes/forward/model.rs b/korangar/src/graphics/passes/forward/model.rs index 3f3409e2..b2b90f6b 100644 --- a/korangar/src/graphics/passes/forward/model.rs +++ b/korangar/src/graphics/passes/forward/model.rs @@ -31,6 +31,11 @@ struct InstanceData { inv_world: [[f32; 4]; 4], } +pub(crate) struct ForwardModelDrawData<'a> { + pub(crate) batch_data: &'a ModelBatchDrawData<'a>, + pub(crate) draw_transparent: bool, +} + pub(crate) struct ForwardModelDrawer { multi_draw_indirect_support: bool, instance_data_buffer: Buffer, @@ -51,7 +56,7 @@ pub(crate) struct ForwardModelDrawer { impl Drawer<{ BindGroupCount::Two }, { ColorAttachmentCount::One }, { DepthAttachmentCount::One }> for ForwardModelDrawer { type Context = ForwardRenderPassContext; - type DrawData<'data> = ModelBatchDrawData<'data>; + type DrawData<'data> = ForwardModelDrawData<'data>; fn new( capabilities: &Capabilities, @@ -192,7 +197,9 @@ impl Drawer<{ BindGroupCount::Two }, { ColorAttachmentCount::One }, { DepthAttac } fn draw(&mut self, pass: &mut RenderPass<'_>, draw_data: Self::DrawData<'_>) { - if self.opaque_batches.is_empty() && self.transparent_batches.is_empty() { + if (!draw_data.draw_transparent && self.opaque_batches.is_empty()) + || (draw_data.draw_transparent && self.transparent_batches.is_empty()) + { return; } @@ -232,45 +239,50 @@ impl Drawer<{ BindGroupCount::Two }, { ColorAttachmentCount::One }, { DepthAttac pass.set_bind_group(2, &self.bind_group, &[]); - #[cfg(feature = "debug")] - let opaque_pipeline = if draw_data.show_wireframe { - &self.wireframe_pipeline - } else { - &self.opaque_pipeline - }; - #[cfg(not(feature = "debug"))] - let opaque_pipeline = &self.opaque_pipeline; - - pass.set_pipeline(opaque_pipeline); - - process_batches( - pass, - &self.opaque_batches, - &draw_data, - &self.instance_index_vertex_buffer, - &self.command_buffer, - self.multi_draw_indirect_support, - ); - - #[cfg(feature = "debug")] - let transparent_pipeline = if draw_data.show_wireframe { - &self.wireframe_pipeline - } else { - &self.transparent_pipeline - }; - #[cfg(not(feature = "debug"))] - let transparent_pipeline = &self.transparent_pipeline; - - pass.set_pipeline(transparent_pipeline); - - process_batches( - pass, - &self.transparent_batches, - &draw_data, - &self.instance_index_vertex_buffer, - &self.command_buffer, - self.multi_draw_indirect_support, - ); + match draw_data.draw_transparent { + false => { + #[cfg(feature = "debug")] + let opaque_pipeline = if draw_data.batch_data.show_wireframe { + &self.wireframe_pipeline + } else { + &self.opaque_pipeline + }; + #[cfg(not(feature = "debug"))] + let opaque_pipeline = &self.opaque_pipeline; + + pass.set_pipeline(opaque_pipeline); + + process_batches( + pass, + &self.opaque_batches, + &draw_data.batch_data, + &self.instance_index_vertex_buffer, + &self.command_buffer, + self.multi_draw_indirect_support, + ); + } + true => { + #[cfg(feature = "debug")] + let transparent_pipeline = if draw_data.batch_data.show_wireframe { + &self.wireframe_pipeline + } else { + &self.transparent_pipeline + }; + #[cfg(not(feature = "debug"))] + let transparent_pipeline = &self.transparent_pipeline; + + pass.set_pipeline(transparent_pipeline); + + process_batches( + pass, + &self.transparent_batches, + &draw_data.batch_data, + &self.instance_index_vertex_buffer, + &self.command_buffer, + self.multi_draw_indirect_support, + ); + } + } } }