khora_lanes/render_lane/shadows_lane/algo/
pass.rs1use khora_core::renderer::api::command::{
24 BindGroupId, LoadOp, Operations, RenderPassDepthStencilAttachment, RenderPassDescriptor,
25 StoreOp,
26};
27use khora_core::renderer::api::pipeline::RenderPipelineId;
28use khora_core::renderer::api::resource::{BufferId, TextureViewId};
29use khora_core::renderer::api::util::IndexFormat;
30use khora_core::renderer::traits::CommandEncoder;
31
32#[derive(Debug, Clone, Copy)]
34pub struct ShadowDrawCmd {
35 pub model_bg: BindGroupId,
38 pub model_offset: u32,
40 pub vertex_buffer: BufferId,
42 pub index_buffer: BufferId,
44 pub index_count: u32,
46 pub index_format: IndexFormat,
48}
49
50pub struct AttachmentPass {
53 pub target_view: TextureViewId,
55 pub base_array_layer: u32,
59 pub camera_bg: BindGroupId,
62 pub camera_offset: u32,
64 pub draw_cmds: Vec<ShadowDrawCmd>,
66}
67
68pub fn record_depth_pass(
74 encoder: &mut dyn CommandEncoder,
75 pipeline: &RenderPipelineId,
76 pass_data: &AttachmentPass,
77) {
78 let depth_attachment = RenderPassDepthStencilAttachment {
79 view: &pass_data.target_view,
80 depth_ops: Some(Operations {
81 load: LoadOp::Clear(1.0),
82 store: StoreOp::Store,
83 }),
84 stencil_ops: None,
85 base_array_layer: pass_data.base_array_layer,
86 };
87
88 let mut pass = encoder.begin_render_pass(&RenderPassDescriptor {
89 label: Some("Shadow Pass"),
90 color_attachments: &[],
91 depth_stencil_attachment: Some(depth_attachment),
92 });
93
94 pass.set_pipeline(pipeline);
95 pass.set_bind_group(0, &pass_data.camera_bg, &[pass_data.camera_offset]);
96
97 for cmd in &pass_data.draw_cmds {
98 pass.set_bind_group(1, &cmd.model_bg, &[cmd.model_offset]);
99 pass.set_vertex_buffer(0, &cmd.vertex_buffer, 0);
100 pass.set_index_buffer(&cmd.index_buffer, 0, cmd.index_format);
101 pass.draw_indexed(0..cmd.index_count, 0, 0..1);
102 }
103}
104
105pub fn build_draw_cmds(
112 device: &dyn khora_core::renderer::GraphicsDevice,
113 render_world: &khora_data::render::RenderWorld,
114 gpu_meshes: &khora_data::assets::Assets<khora_core::renderer::api::scene::GpuMesh>,
115 model_ring: &mut khora_core::renderer::api::util::dynamic_uniform_buffer::DynamicUniformRingBuffer,
116) -> Vec<ShadowDrawCmd> {
117 let mut draw_cmds = Vec::with_capacity(render_world.meshes.len());
118 for mesh in &render_world.meshes {
119 if let Some(gpu_mesh) = gpu_meshes.get(&mesh.cpu_mesh_uuid) {
120 let model_mat = mesh.transform.to_matrix();
121 let normal_mat = if let Some(inv) = model_mat.inverse() {
122 inv.transpose()
123 } else {
124 continue;
125 };
126 let model_uniforms = khora_core::renderer::api::scene::ModelUniforms {
127 model_matrix: model_mat.to_cols_array_2d(),
128 normal_matrix: normal_mat.to_cols_array_2d(),
129 };
130 let model_offset = match model_ring.push(device, bytemuck::bytes_of(&model_uniforms)) {
131 Ok(off) => off,
132 Err(e) => {
133 log::error!("StandardShadowsLane: failed to push model uniform: {:?}", e);
134 continue;
135 }
136 };
137 draw_cmds.push(ShadowDrawCmd {
138 model_bg: *model_ring.current_bind_group(),
139 model_offset,
140 vertex_buffer: gpu_mesh.vertex_buffer,
141 index_buffer: gpu_mesh.index_buffer,
142 index_count: gpu_mesh.index_count,
143 index_format: gpu_mesh.index_format,
144 });
145 }
146 }
147 draw_cmds
148}