diff --git a/lyra-game/src/render/graph/passes/meshes.rs b/lyra-game/src/render/graph/passes/meshes.rs index 5264b14..46f67ed 100644 --- a/lyra-game/src/render/graph/passes/meshes.rs +++ b/lyra-game/src/render/graph/passes/meshes.rs @@ -15,7 +15,7 @@ use crate::render::{ use super::{ BasePassSlots, LightBasePassSlots, LightCullComputePassSlots, MeshBufferStorage, RenderAssets, - RenderMeshes, + RenderMeshes, ShadowMapsPassSlots, }; #[derive(Debug, Hash, Clone, Default, PartialEq, RenderGraphLabel)] @@ -26,6 +26,12 @@ pub enum MeshesPassSlots { Material, } +/// Stores the bind group and bind group layout for the shadow atlas texture +struct ShadowsAtlasBgPair { + layout: Arc, + bg: Arc, +} + //#[derive(Default)] #[allow(dead_code)] pub struct MeshPass { @@ -33,11 +39,14 @@ pub struct MeshPass { pipeline: Option, material_bgl: Arc, - transform_buffers: Option, + // TODO: find a better way to extract these resources from the main world to be used in the // render stage. + transform_buffers: Option, render_meshes: Option, mesh_buffers: Option, + + shadows_atlas: Option, } impl MeshPass { @@ -46,43 +55,89 @@ impl MeshPass { default_texture: None, pipeline: None, material_bgl, + transform_buffers: None, render_meshes: None, mesh_buffers: None, + + shadows_atlas: None, } } fn transform_buffers(&self) -> AtomicRef { - self.transform_buffers - .as_ref() - .unwrap() - .get() + self.transform_buffers.as_ref().unwrap().get() } fn render_meshes(&self) -> AtomicRef { - self.render_meshes - .as_ref() - .unwrap() - .get() + self.render_meshes.as_ref().unwrap().get() } fn mesh_buffers(&self) -> AtomicRef> { - self.mesh_buffers - .as_ref() - .unwrap() - .get() + self.mesh_buffers.as_ref().unwrap().get() } } impl Node for MeshPass { fn desc( &mut self, - _: &mut crate::render::graph::RenderGraph, + graph: &mut crate::render::graph::RenderGraph, ) -> crate::render::graph::NodeDesc { // load the default texture //let bytes = include_bytes!("../../default_texture.png"); //self.default_texture = Some(RenderTexture::from_bytes(device, &graph.queue, texture_bind_group_layout.clone(), bytes, "default_texture").unwrap()); + let atlas_view = graph + .slot_value(ShadowMapsPassSlots::ShadowAtlasTextureView) + .expect("missing ShadowMapsPassSlots::ShadowAtlasTextureView") + .as_texture_view().unwrap(); + let atlas_sampler = graph + .slot_value(ShadowMapsPassSlots::ShadowAtlasSampler) + .expect("missing ShadowMapsPassSlots::ShadowAtlasSampler") + .as_sampler().unwrap(); + + let device = graph.device(); + let atlas_layout = device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor { + label: Some("bgl_shadows_atlas"), + entries: &[ + wgpu::BindGroupLayoutEntry { + binding: 0, + visibility: wgpu::ShaderStages::FRAGMENT, + ty: wgpu::BindingType::Texture { + sample_type: wgpu::TextureSampleType::Depth, + view_dimension: wgpu::TextureViewDimension::D2, + multisampled: false, + }, + count: None, + }, + wgpu::BindGroupLayoutEntry { + binding: 1, + visibility: wgpu::ShaderStages::FRAGMENT, + ty: wgpu::BindingType::Sampler(wgpu::SamplerBindingType::Filtering), + count: None, + }, + ], + }); + + let atlas_bg = device.create_bind_group(&wgpu::BindGroupDescriptor { + label: Some("bg_shadows_atlas"), + layout: &atlas_layout, + entries: &[ + wgpu::BindGroupEntry { + binding: 0, + resource: wgpu::BindingResource::TextureView(atlas_view), + }, + wgpu::BindGroupEntry { + binding: 1, + resource: wgpu::BindingResource::Sampler(atlas_sampler), + } + ], + }); + + self.shadows_atlas = Some(ShadowsAtlasBgPair { + layout: Arc::new(atlas_layout), + bg: Arc::new(atlas_bg), + }); + NodeDesc::new( NodeType::Render, None, @@ -107,18 +162,18 @@ impl Node for MeshPass { let lights_bgl = graph.bind_group_layout(LightBasePassSlots::Lights); let light_grid_bgl = graph.bind_group_layout(LightCullComputePassSlots::LightIndicesGridGroup); + let atlas_bgl = self.shadows_atlas.as_ref().unwrap().layout.clone(); let shader = Rc::new(Shader { label: Some("base_shader".into()), source: include_str!("../../shaders/base.wgsl").to_string(), }); - let transforms = world .try_get_resource_data::() .expect("Missing transform buffers"); self.transform_buffers = Some(transforms.clone()); - + let render_meshes = world .try_get_resource_data::() .expect("Missing transform buffers"); @@ -128,7 +183,6 @@ impl Node for MeshPass { .try_get_resource_data::>() .expect("Missing render meshes"); self.mesh_buffers = Some(mesh_buffers.clone()); - let transforms = transforms.get::(); @@ -142,6 +196,7 @@ impl Node for MeshPass { camera_bgl.clone(), lights_bgl.clone(), light_grid_bgl.clone(), + atlas_bgl, ], push_constant_ranges: vec![], vertex: VertexState { @@ -202,6 +257,8 @@ impl Node for MeshPass { let light_grid_bg = graph.bind_group(LightCullComputePassSlots::LightIndicesGridGroup); + let shadows_atlas_bg = &self.shadows_atlas.as_ref().unwrap().bg; + //let material_bg = graph.bind_group(MeshesPassSlots::Material); /* let pipeline = graph.pipeline(context.label.clone()) @@ -284,6 +341,8 @@ impl Node for MeshPass { pass.set_bind_group(4, light_grid_bg, &[]); + pass.set_bind_group(5, shadows_atlas_bg, &[]); + // if this mesh uses indices, use them to draw the mesh if let Some((idx_type, indices)) = buffers.buffer_indices.as_ref() { let indices_len = indices.count() as u32; diff --git a/lyra-game/src/render/renderer.rs b/lyra-game/src/render/renderer.rs index 73c9910..da9dd1d 100755 --- a/lyra-game/src/render/renderer.rs +++ b/lyra-game/src/render/renderer.rs @@ -147,12 +147,13 @@ impl BasicRenderer { forward_plus_graph.add_node(LightCullComputePassLabel, LightCullComputePass::new(size)); debug!("Adding mesh pass"); + forward_plus_graph.add_node(ShadowMapsPassLabel, ShadowMapsPass::new(&device)); + let mesh_prep = MeshPrepNode::new(&device); let material_bgl = mesh_prep.material_bgl.clone(); forward_plus_graph.add_node(MeshPrepNodeLabel, mesh_prep); forward_plus_graph.add_node(MeshesPassLabel, MeshPass::new(material_bgl)); - forward_plus_graph.add_node(ShadowMapsPassLabel, ShadowMapsPass::new(&device)); forward_plus_graph.add_edge(LightBasePassLabel, LightCullComputePassLabel); forward_plus_graph.add_edge(MeshPrepNodeLabel, MeshesPassLabel); diff --git a/lyra-game/src/render/shaders/base.wgsl b/lyra-game/src/render/shaders/base.wgsl index 8fd9c34..3eefbf0 100755 --- a/lyra-game/src/render/shaders/base.wgsl +++ b/lyra-game/src/render/shaders/base.wgsl @@ -114,6 +114,11 @@ var u_light_indices: array; @group(4) @binding(1) var t_light_grid: texture_storage_2d; // vec2 +@group(5) @binding(0) +var t_shadow_maps_atlas: texture_2d; +@group(5) @binding(1) +var s_shadow_maps_atlas: sampler; + @fragment fn fs_main(in: VertexOutput) -> @location(0) vec4 { if (u_camera.tile_debug == 1u) {