diff --git a/res/shaders/pbr.wgsl b/res/shaders/pbr.wgsl index c274862..51312f2 100644 --- a/res/shaders/pbr.wgsl +++ b/res/shaders/pbr.wgsl @@ -47,9 +47,9 @@ fn vs_main( // Fragment shader @group(2)@binding(0) -var t_light_depth: binding_array; +var t_light_depth: texture_depth_2d_array; @group(2) @binding(1) -var s_light_depth: binding_array; +var s_light_depth: sampler_comparison; @group(3) @binding(0) var t_diffuse: texture_2d; @@ -76,9 +76,10 @@ fn sample_direct_light(index: i32, light_coords: vec4) -> f32 { let light_local = light_coords.xy * flip_correction * proj_correction + vec2(0.5, 0.5); return textureSampleCompareLevel( - t_light_depth[index], - s_light_depth[index], + t_light_depth, + s_light_depth, light_local, + index, light_coords.z * proj_correction ); } diff --git a/src/core/state.rs b/src/core/state.rs index e1786cd..c16d696 100644 --- a/src/core/state.rs +++ b/src/core/state.rs @@ -1,5 +1,5 @@ use cgmath::prelude::*; -use wgpu::{InstanceDescriptor, Backends}; +use wgpu::{InstanceDescriptor, Backends, TextureView, TextureViewDescriptor}; use std::default::Default; use std::num::NonZeroU32; use std::time::Duration; @@ -37,12 +37,11 @@ pub struct State { light_buffer: wgpu::Buffer, light_debug_pass: RenderPass, light_bind_group: wgpu::BindGroup, - #[allow(dead_code)] - light_bind_group_layout: wgpu::BindGroupLayout, light_depth_bind_group: wgpu::BindGroup, light_depth_bind_group_layout: wgpu::BindGroupLayout, light_depth_pass: RenderPass, - light_depth_textures: [Texture; 6], + light_depth_texture: Texture, + light_depth_texture_target_views: [TextureView; 6], light_matrix_uniform: u32, light_matrix_buffer: wgpu::Buffer, } @@ -141,36 +140,35 @@ impl State { "depth_texture", Some(wgpu::CompareFunction::Less), 1, - wgpu::TextureUsages::RENDER_ATTACHMENT | wgpu::TextureUsages::COPY_SRC, + wgpu::TextureUsages::RENDER_ATTACHMENT, ); - let light_depth_textures: [Texture; 6] = (0..6) + let light_depth_texture = Texture::create_depth_texture( + &device, + &config, + "light_depth_texture", + Some(wgpu::CompareFunction::Less), + 6, + wgpu::TextureUsages::RENDER_ATTACHMENT | wgpu::TextureUsages::TEXTURE_BINDING, + ); + + let light_depth_texture_target_views = (0..6) .map(|i| { - Texture::create_depth_texture( - &device, - &config, - format!("light_depth_texture_{}", i).as_str(), - Some(wgpu::CompareFunction::Less), - 1, - wgpu::TextureUsages::TEXTURE_BINDING | wgpu::TextureUsages::COPY_DST, - ) + light_depth_texture.texture.create_view(&TextureViewDescriptor { + label: Some("light_depth_texture_view"), + format: None, + dimension: Some(wgpu::TextureViewDimension::D2), + aspect: wgpu::TextureAspect::All, + base_mip_level: 0, + mip_level_count: None, + base_array_layer: i as u32, + array_layer_count: NonZeroU32::new(1), + }) }) .collect::>() .try_into() - .expect("failed to create light depth textures"); - - let light_depth_texture_views: [&wgpu::TextureView; 6] = (0..6) - .map(|i| &light_depth_textures[i].view) - .collect::>() - .try_into() .expect("failed to create light depth texture views"); - let light_depth_texture_samplers: [&wgpu::Sampler; 6] = (0..6) - .map(|i| &light_depth_textures[i].sampler) - .collect::>() - .try_into() - .expect("failed to create light depth texture samplers"); - let light_uniform = LightUniform::new([100.0, 60.0, 0.0], [1.0, 1.0, 1.0, 200000.0]); // We'll want to update our lights position, so we use COPY_DST @@ -242,16 +240,16 @@ impl State { visibility: wgpu::ShaderStages::FRAGMENT, ty: wgpu::BindingType::Texture { multisampled: false, - view_dimension: wgpu::TextureViewDimension::D2, + view_dimension: wgpu::TextureViewDimension::D2Array, sample_type: wgpu::TextureSampleType::Depth, }, - count: NonZeroU32::new(6), + count: NonZeroU32::new(1), }, wgpu::BindGroupLayoutEntry { binding: 1, visibility: wgpu::ShaderStages::FRAGMENT, ty: wgpu::BindingType::Sampler(wgpu::SamplerBindingType::Comparison), - count: NonZeroU32::new(6), + count: NonZeroU32::new(1), }, ], label: Some("Light Bind Group Layout"), @@ -263,11 +261,11 @@ impl State { // depth textures wgpu::BindGroupEntry { binding: 0, - resource: wgpu::BindingResource::TextureViewArray(&light_depth_texture_views), + resource: wgpu::BindingResource::TextureView(&light_depth_texture.view), }, wgpu::BindGroupEntry { binding: 1, - resource: wgpu::BindingResource::SamplerArray(&light_depth_texture_samplers), + resource: wgpu::BindingResource::Sampler(&light_depth_texture.sampler), }, ], label: Some("Light Depth Bind Group"), @@ -425,11 +423,11 @@ impl State { light_buffer, light_debug_pass, light_bind_group, - light_bind_group_layout, light_depth_bind_group, light_depth_bind_group_layout, light_depth_pass, - light_depth_textures, + light_depth_texture, + light_depth_texture_target_views, light_matrix_uniform, light_matrix_buffer, } @@ -450,44 +448,47 @@ impl State { "depth_texture", Some(wgpu::CompareFunction::Less), 1, - wgpu::TextureUsages::RENDER_ATTACHMENT | wgpu::TextureUsages::COPY_SRC, + wgpu::TextureUsages::RENDER_ATTACHMENT, ); // recreate light depth textures - for i in 0..6 { - self.light_depth_textures[i] = Texture::create_depth_texture( - &self.device, - &self.config, - format!("light_depth_texture_{}", i).as_str(), - Some(wgpu::CompareFunction::Less), - 1, - wgpu::TextureUsages::TEXTURE_BINDING | wgpu::TextureUsages::COPY_DST, - ); - } + self.light_depth_texture = Texture::create_depth_texture( + &self.device, + &self.config, + "light_depth_texture", + Some(wgpu::CompareFunction::Less), + 6, + wgpu::TextureUsages::RENDER_ATTACHMENT | wgpu::TextureUsages::TEXTURE_BINDING, + ); - let light_depth_texture_views: [&wgpu::TextureView; 6] = (0..6) - .map(|i| &self.light_depth_textures[i].view) + self.light_depth_texture_target_views = (0..6) + .map(|i| { + self.light_depth_texture.texture.create_view(&TextureViewDescriptor { + label: Some("light_depth_texture_view"), + format: None, + dimension: Some(wgpu::TextureViewDimension::D2), + aspect: wgpu::TextureAspect::All, + base_mip_level: 0, + mip_level_count: None, + base_array_layer: i as u32, + array_layer_count: NonZeroU32::new(1), + }) + }) .collect::>() .try_into() .expect("failed to create light depth texture views"); - let light_depth_texture_samplers: [&wgpu::Sampler; 6] = (0..6) - .map(|i| &self.light_depth_textures[i].sampler) - .collect::>() - .try_into() - .expect("failed to create light depth texture samplers"); - self.light_depth_bind_group = self.device.create_bind_group(&wgpu::BindGroupDescriptor { layout: &self.light_depth_bind_group_layout, entries: &[ // depth textures wgpu::BindGroupEntry { binding: 0, - resource: wgpu::BindingResource::TextureViewArray(&light_depth_texture_views), + resource: wgpu::BindingResource::TextureView(&self.light_depth_texture.view), }, wgpu::BindGroupEntry { binding: 1, - resource: wgpu::BindingResource::SamplerArray(&light_depth_texture_samplers), + resource: wgpu::BindingResource::Sampler(&self.light_depth_texture.sampler), }, ], label: Some("Light Depth Bind Group"), @@ -550,7 +551,7 @@ impl State { label: Some("Light Depth Render Pass"), color_attachments: &[], depth_stencil_attachment: Some(wgpu::RenderPassDepthStencilAttachment { - view: &self.depth_texture.view, + view: &self.light_depth_texture_target_views[i], depth_ops: Some(wgpu::Operations { load: wgpu::LoadOp::Clear(1.0), store: true, @@ -568,12 +569,6 @@ impl State { ); } - depth_encoder.copy_texture_to_texture( - self.depth_texture.texture.as_image_copy(), - self.light_depth_textures[i].texture.as_image_copy(), - self.depth_texture.texture.size() - ); - self.queue.submit(std::iter::once(depth_encoder.finish())); }