render: bind the shadow map atlas to the meshes shaders

This commit is contained in:
SeanOMik 2024-06-30 21:42:08 -04:00
parent 7b2d2424a3
commit 1c649b2eb6
Signed by: SeanOMik
GPG Key ID: FEC9E2FC15235964
3 changed files with 84 additions and 19 deletions

View File

@ -15,7 +15,7 @@ use crate::render::{
use super::{ use super::{
BasePassSlots, LightBasePassSlots, LightCullComputePassSlots, MeshBufferStorage, RenderAssets, BasePassSlots, LightBasePassSlots, LightCullComputePassSlots, MeshBufferStorage, RenderAssets,
RenderMeshes, RenderMeshes, ShadowMapsPassSlots,
}; };
#[derive(Debug, Hash, Clone, Default, PartialEq, RenderGraphLabel)] #[derive(Debug, Hash, Clone, Default, PartialEq, RenderGraphLabel)]
@ -26,6 +26,12 @@ pub enum MeshesPassSlots {
Material, Material,
} }
/// Stores the bind group and bind group layout for the shadow atlas texture
struct ShadowsAtlasBgPair {
layout: Arc<wgpu::BindGroupLayout>,
bg: Arc<wgpu::BindGroup>,
}
//#[derive(Default)] //#[derive(Default)]
#[allow(dead_code)] #[allow(dead_code)]
pub struct MeshPass { pub struct MeshPass {
@ -33,11 +39,14 @@ pub struct MeshPass {
pipeline: Option<RenderPipeline>, pipeline: Option<RenderPipeline>,
material_bgl: Arc<wgpu::BindGroupLayout>, material_bgl: Arc<wgpu::BindGroupLayout>,
transform_buffers: Option<ResourceData>,
// TODO: find a better way to extract these resources from the main world to be used in the // TODO: find a better way to extract these resources from the main world to be used in the
// render stage. // render stage.
transform_buffers: Option<ResourceData>,
render_meshes: Option<ResourceData>, render_meshes: Option<ResourceData>,
mesh_buffers: Option<ResourceData>, mesh_buffers: Option<ResourceData>,
shadows_atlas: Option<ShadowsAtlasBgPair>,
} }
impl MeshPass { impl MeshPass {
@ -46,43 +55,89 @@ impl MeshPass {
default_texture: None, default_texture: None,
pipeline: None, pipeline: None,
material_bgl, material_bgl,
transform_buffers: None, transform_buffers: None,
render_meshes: None, render_meshes: None,
mesh_buffers: None, mesh_buffers: None,
shadows_atlas: None,
} }
} }
fn transform_buffers(&self) -> AtomicRef<TransformBuffers> { fn transform_buffers(&self) -> AtomicRef<TransformBuffers> {
self.transform_buffers self.transform_buffers.as_ref().unwrap().get()
.as_ref()
.unwrap()
.get()
} }
fn render_meshes(&self) -> AtomicRef<RenderMeshes> { fn render_meshes(&self) -> AtomicRef<RenderMeshes> {
self.render_meshes self.render_meshes.as_ref().unwrap().get()
.as_ref()
.unwrap()
.get()
} }
fn mesh_buffers(&self) -> AtomicRef<RenderAssets<MeshBufferStorage>> { fn mesh_buffers(&self) -> AtomicRef<RenderAssets<MeshBufferStorage>> {
self.mesh_buffers self.mesh_buffers.as_ref().unwrap().get()
.as_ref()
.unwrap()
.get()
} }
} }
impl Node for MeshPass { impl Node for MeshPass {
fn desc( fn desc(
&mut self, &mut self,
_: &mut crate::render::graph::RenderGraph, graph: &mut crate::render::graph::RenderGraph,
) -> crate::render::graph::NodeDesc { ) -> crate::render::graph::NodeDesc {
// load the default texture // load the default texture
//let bytes = include_bytes!("../../default_texture.png"); //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()); //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( NodeDesc::new(
NodeType::Render, NodeType::Render,
None, None,
@ -107,13 +162,13 @@ impl Node for MeshPass {
let lights_bgl = graph.bind_group_layout(LightBasePassSlots::Lights); let lights_bgl = graph.bind_group_layout(LightBasePassSlots::Lights);
let light_grid_bgl = let light_grid_bgl =
graph.bind_group_layout(LightCullComputePassSlots::LightIndicesGridGroup); graph.bind_group_layout(LightCullComputePassSlots::LightIndicesGridGroup);
let atlas_bgl = self.shadows_atlas.as_ref().unwrap().layout.clone();
let shader = Rc::new(Shader { let shader = Rc::new(Shader {
label: Some("base_shader".into()), label: Some("base_shader".into()),
source: include_str!("../../shaders/base.wgsl").to_string(), source: include_str!("../../shaders/base.wgsl").to_string(),
}); });
let transforms = world let transforms = world
.try_get_resource_data::<TransformBuffers>() .try_get_resource_data::<TransformBuffers>()
.expect("Missing transform buffers"); .expect("Missing transform buffers");
@ -129,7 +184,6 @@ impl Node for MeshPass {
.expect("Missing render meshes"); .expect("Missing render meshes");
self.mesh_buffers = Some(mesh_buffers.clone()); self.mesh_buffers = Some(mesh_buffers.clone());
let transforms = transforms.get::<TransformBuffers>(); let transforms = transforms.get::<TransformBuffers>();
self.pipeline = Some(RenderPipeline::create( self.pipeline = Some(RenderPipeline::create(
@ -142,6 +196,7 @@ impl Node for MeshPass {
camera_bgl.clone(), camera_bgl.clone(),
lights_bgl.clone(), lights_bgl.clone(),
light_grid_bgl.clone(), light_grid_bgl.clone(),
atlas_bgl,
], ],
push_constant_ranges: vec![], push_constant_ranges: vec![],
vertex: VertexState { vertex: VertexState {
@ -202,6 +257,8 @@ impl Node for MeshPass {
let light_grid_bg = graph.bind_group(LightCullComputePassSlots::LightIndicesGridGroup); 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 material_bg = graph.bind_group(MeshesPassSlots::Material);
/* let pipeline = graph.pipeline(context.label.clone()) /* 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(4, light_grid_bg, &[]);
pass.set_bind_group(5, shadows_atlas_bg, &[]);
// if this mesh uses indices, use them to draw the mesh // if this mesh uses indices, use them to draw the mesh
if let Some((idx_type, indices)) = buffers.buffer_indices.as_ref() { if let Some((idx_type, indices)) = buffers.buffer_indices.as_ref() {
let indices_len = indices.count() as u32; let indices_len = indices.count() as u32;

View File

@ -147,12 +147,13 @@ impl BasicRenderer {
forward_plus_graph.add_node(LightCullComputePassLabel, LightCullComputePass::new(size)); forward_plus_graph.add_node(LightCullComputePassLabel, LightCullComputePass::new(size));
debug!("Adding mesh pass"); debug!("Adding mesh pass");
forward_plus_graph.add_node(ShadowMapsPassLabel, ShadowMapsPass::new(&device));
let mesh_prep = MeshPrepNode::new(&device); let mesh_prep = MeshPrepNode::new(&device);
let material_bgl = mesh_prep.material_bgl.clone(); let material_bgl = mesh_prep.material_bgl.clone();
forward_plus_graph.add_node(MeshPrepNodeLabel, mesh_prep); forward_plus_graph.add_node(MeshPrepNodeLabel, mesh_prep);
forward_plus_graph.add_node(MeshesPassLabel, MeshPass::new(material_bgl)); 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(LightBasePassLabel, LightCullComputePassLabel);
forward_plus_graph.add_edge(MeshPrepNodeLabel, MeshesPassLabel); forward_plus_graph.add_edge(MeshPrepNodeLabel, MeshesPassLabel);

View File

@ -114,6 +114,11 @@ var<storage, read_write> u_light_indices: array<u32>;
@group(4) @binding(1) @group(4) @binding(1)
var t_light_grid: texture_storage_2d<rg32uint, read_write>; // vec2<u32> var t_light_grid: texture_storage_2d<rg32uint, read_write>; // vec2<u32>
@group(5) @binding(0)
var t_shadow_maps_atlas: texture_2d<f32>;
@group(5) @binding(1)
var s_shadow_maps_atlas: sampler;
@fragment @fragment
fn fs_main(in: VertexOutput) -> @location(0) vec4<f32> { fn fs_main(in: VertexOutput) -> @location(0) vec4<f32> {
if (u_camera.tile_debug == 1u) { if (u_camera.tile_debug == 1u) {