Implement Shadows #24
|
@ -86,58 +86,6 @@ impl Node for MeshPass {
|
||||||
//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,
|
||||||
|
@ -158,6 +106,82 @@ impl Node for MeshPass {
|
||||||
let device = graph.device();
|
let device = graph.device();
|
||||||
let surface_config_format = graph.view_target().format();
|
let surface_config_format = graph.view_target().format();
|
||||||
|
|
||||||
|
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 dir_light_projection_buf = graph
|
||||||
|
.slot_value(ShadowMapsPassSlots::DirLightProjectionBuffer)
|
||||||
|
.expect("missing ShadowMapsPassSlots::DirLightProjectionBuffer")
|
||||||
|
.as_buffer()
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
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,
|
||||||
|
},
|
||||||
|
wgpu::BindGroupLayoutEntry {
|
||||||
|
binding: 2,
|
||||||
|
visibility: wgpu::ShaderStages::VERTEX_FRAGMENT,
|
||||||
|
ty: wgpu::BindingType::Buffer {
|
||||||
|
ty: wgpu::BufferBindingType::Uniform,
|
||||||
|
has_dynamic_offset: false,
|
||||||
|
min_binding_size: None,
|
||||||
|
},
|
||||||
|
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),
|
||||||
|
},
|
||||||
|
wgpu::BindGroupEntry {
|
||||||
|
binding: 2,
|
||||||
|
resource: wgpu::BindingResource::Buffer(wgpu::BufferBinding {
|
||||||
|
buffer: dir_light_projection_buf,
|
||||||
|
offset: 0,
|
||||||
|
size: None,
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
|
||||||
|
self.shadows_atlas = Some(ShadowsAtlasBgPair {
|
||||||
|
layout: Arc::new(atlas_layout),
|
||||||
|
bg: Arc::new(atlas_bg),
|
||||||
|
});
|
||||||
|
|
||||||
let camera_bgl = graph.bind_group_layout(BasePassSlots::Camera);
|
let camera_bgl = graph.bind_group_layout(BasePassSlots::Camera);
|
||||||
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 =
|
||||||
|
|
|
@ -27,13 +27,14 @@ pub enum ShadowMapsPassSlots {
|
||||||
ShadowAtlasTexture,
|
ShadowAtlasTexture,
|
||||||
ShadowAtlasTextureView,
|
ShadowAtlasTextureView,
|
||||||
ShadowAtlasSampler,
|
ShadowAtlasSampler,
|
||||||
|
DirLightProjectionBuffer,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Hash, PartialEq, RenderGraphLabel)]
|
#[derive(Debug, Clone, Hash, PartialEq, RenderGraphLabel)]
|
||||||
pub struct ShadowMapsPassLabel;
|
pub struct ShadowMapsPassLabel;
|
||||||
|
|
||||||
struct LightDepthMap {
|
struct LightDepthMap {
|
||||||
light_projection_buffer: wgpu::Buffer,
|
light_projection_buffer: Arc<wgpu::Buffer>,
|
||||||
bindgroup: wgpu::BindGroup,
|
bindgroup: wgpu::BindGroup,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -158,7 +159,7 @@ impl ShadowMapsPass {
|
||||||
self.depth_maps.insert(
|
self.depth_maps.insert(
|
||||||
entity,
|
entity,
|
||||||
LightDepthMap {
|
LightDepthMap {
|
||||||
light_projection_buffer,
|
light_projection_buffer: Arc::new(light_projection_buffer),
|
||||||
bindgroup: bg,
|
bindgroup: bg,
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
@ -202,6 +203,12 @@ impl Node for ShadowMapsPass {
|
||||||
Some(SlotValue::Sampler(self.atlas_sampler.clone())),
|
Some(SlotValue::Sampler(self.atlas_sampler.clone())),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
node.add_sampler_slot(
|
||||||
|
ShadowMapsPassSlots::DirLightProjectionBuffer,
|
||||||
|
SlotAttribute::Output,
|
||||||
|
Some(SlotValue::Lazy),
|
||||||
|
);
|
||||||
|
|
||||||
node
|
node
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -222,6 +229,12 @@ impl Node for ShadowMapsPass {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// update the light projection buffer slot
|
||||||
|
let (_, dir_depth_map) = self.depth_maps.iter().next().unwrap();
|
||||||
|
let val = graph.slot_value_mut(ShadowMapsPassSlots::DirLightProjectionBuffer)
|
||||||
|
.unwrap();
|
||||||
|
*val = SlotValue::Buffer(dir_depth_map.light_projection_buffer.clone());
|
||||||
|
|
||||||
if self.pipeline.is_none() {
|
if self.pipeline.is_none() {
|
||||||
let shader = Rc::new(Shader {
|
let shader = Rc::new(Shader {
|
||||||
label: Some("shader_shadows".into()),
|
label: Some("shader_shadows".into()),
|
||||||
|
|
|
@ -156,6 +156,7 @@ impl BasicRenderer {
|
||||||
|
|
||||||
|
|
||||||
forward_plus_graph.add_edge(LightBasePassLabel, LightCullComputePassLabel);
|
forward_plus_graph.add_edge(LightBasePassLabel, LightCullComputePassLabel);
|
||||||
|
forward_plus_graph.add_edge(LightCullComputePassLabel, MeshesPassLabel);
|
||||||
forward_plus_graph.add_edge(MeshPrepNodeLabel, MeshesPassLabel);
|
forward_plus_graph.add_edge(MeshPrepNodeLabel, MeshesPassLabel);
|
||||||
|
|
||||||
// run ShadowMapsPass after MeshPrep and before MeshesPass
|
// run ShadowMapsPass after MeshPrep and before MeshesPass
|
||||||
|
|
|
@ -118,6 +118,8 @@ var t_light_grid: texture_storage_2d<rg32uint, read_write>; // vec2<u32>
|
||||||
var t_shadow_maps_atlas: texture_2d<f32>;
|
var t_shadow_maps_atlas: texture_2d<f32>;
|
||||||
@group(5) @binding(1)
|
@group(5) @binding(1)
|
||||||
var s_shadow_maps_atlas: sampler;
|
var s_shadow_maps_atlas: sampler;
|
||||||
|
@group(5) @binding(2)
|
||||||
|
var<uniform> u_light_space_matrix: mat4x4<f32>;
|
||||||
|
|
||||||
@fragment
|
@fragment
|
||||||
fn fs_main(in: VertexOutput) -> @location(0) vec4<f32> {
|
fn fs_main(in: VertexOutput) -> @location(0) vec4<f32> {
|
||||||
|
|
Loading…
Reference in New Issue