Fix geometry depth binding not updating after resize, refactoring
This commit is contained in:
parent
7b752703ea
commit
3676f8fef5
6 changed files with 210 additions and 219 deletions
|
@ -35,31 +35,16 @@ fn vs_main(
|
||||||
|
|
||||||
// Fragment shader
|
// Fragment shader
|
||||||
|
|
||||||
@group(2)@binding(0)
|
@group(1) @binding(0)
|
||||||
var t_light_depth: texture_depth_2d_array;
|
var t_light_depth: texture_depth_2d_array;
|
||||||
@group(2) @binding(1)
|
@group(1) @binding(1)
|
||||||
var s_light_depth: sampler_comparison;
|
var s_light_depth: sampler_comparison;
|
||||||
|
|
||||||
@group(2)@binding(2)
|
@group(2) @binding(0)
|
||||||
var t_geometry_depth: texture_depth_2d;
|
var t_geometry_depth: texture_depth_2d;
|
||||||
@group(2) @binding(3)
|
@group(2) @binding(1)
|
||||||
var s_geometry_depth: sampler;
|
var s_geometry_depth: sampler;
|
||||||
|
|
||||||
@group(3) @binding(0)
|
|
||||||
var t_diffuse: texture_2d<f32>;
|
|
||||||
@group(3)@binding(1)
|
|
||||||
var s_diffuse: sampler;
|
|
||||||
|
|
||||||
@group(3)@binding(2)
|
|
||||||
var t_normal: texture_2d<f32>;
|
|
||||||
@group(3) @binding(3)
|
|
||||||
var s_normal: sampler;
|
|
||||||
|
|
||||||
@group(3)@binding(4)
|
|
||||||
var t_roughness_metalness: texture_2d<f32>;
|
|
||||||
@group(3) @binding(5)
|
|
||||||
var s_roughness_metalness: sampler;
|
|
||||||
|
|
||||||
fn fog_noise(pos: vec3<f32>) -> f32 {
|
fn fog_noise(pos: vec3<f32>) -> f32 {
|
||||||
var p = pos * FOG_SCALE;
|
var p = pos * FOG_SCALE;
|
||||||
p.x += global_uniforms.time * 0.01;
|
p.x += global_uniforms.time * 0.01;
|
||||||
|
@ -91,15 +76,7 @@ fn ray_march(origin: vec3<f32>, direction: vec3<f32>, scene_depth: f32) -> f32 {
|
||||||
return density;
|
return density;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn scene_depth(clip_position: vec4<f32>) -> f32 {
|
fn depth_to_linear(depth: f32) -> f32 {
|
||||||
if (clip_position.w <= 0.0) {
|
|
||||||
return 0.0;
|
|
||||||
}
|
|
||||||
|
|
||||||
let ndc = clip_position.xy / clip_position.w;
|
|
||||||
let uv = ndc * vec2<f32>(0.5, -0.5) + vec2<f32>(0.5, 0.5);
|
|
||||||
let depth = textureSample(t_geometry_depth, s_geometry_depth, uv);
|
|
||||||
|
|
||||||
// convert to linear [near, far] range
|
// convert to linear [near, far] range
|
||||||
let z_near = camera.planes.x;
|
let z_near = camera.planes.x;
|
||||||
let z_far = camera.planes.y;
|
let z_far = camera.planes.y;
|
||||||
|
@ -109,15 +86,21 @@ fn scene_depth(clip_position: vec4<f32>) -> f32 {
|
||||||
@fragment
|
@fragment
|
||||||
fn fs_main(vert: FogVertexOutput) -> @location(0) vec4<f32> {
|
fn fs_main(vert: FogVertexOutput) -> @location(0) vec4<f32> {
|
||||||
let cam_to_volume = vert.world_position.xyz - camera.position.xyz;
|
let cam_to_volume = vert.world_position.xyz - camera.position.xyz;
|
||||||
let distance_to_volume = length(cam_to_volume);
|
var distance_to_volume = length(cam_to_volume);
|
||||||
let direction = cam_to_volume / distance_to_volume;
|
let direction = cam_to_volume / distance_to_volume;
|
||||||
// FIXME: t_geometry_depth is 0
|
// FIXME: geom depth should always be greater than the volume surface depth...
|
||||||
var geometry_depth = scene_depth(vert.clip_position) - distance_to_volume;
|
// why is this broken?
|
||||||
geometry_depth = 3000.0;
|
distance_to_volume = depth_to_linear(vert.clip_position.z);
|
||||||
|
let uv = vert.clip_position.xy / camera.planes.xy;
|
||||||
|
let depth = textureSample(t_geometry_depth, s_geometry_depth, uv);
|
||||||
|
let geometry_depth = depth_to_linear(depth) - distance_to_volume;
|
||||||
if (geometry_depth <= 0.0)
|
if (geometry_depth <= 0.0)
|
||||||
{
|
{
|
||||||
return vec4<f32>(0.0);
|
return vec4<f32>(0.0);
|
||||||
}
|
}
|
||||||
|
return vec4<f32>(1.0);
|
||||||
|
|
||||||
|
/*
|
||||||
let density = ray_march(vert.world_position.xyz, direction, geometry_depth);
|
let density = ray_march(vert.world_position.xyz, direction, geometry_depth);
|
||||||
|
|
||||||
var in_light = 0.0;
|
var in_light = 0.0;
|
||||||
|
@ -170,4 +153,5 @@ fn fs_main(vert: FogVertexOutput) -> @location(0) vec4<f32> {
|
||||||
result = result / (result + vec3(1.0));
|
result = result / (result + vec3(1.0));
|
||||||
|
|
||||||
return vec4(result, density * FOG_ALPHA);
|
return vec4(result, density * FOG_ALPHA);
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,7 +15,7 @@ struct Light {
|
||||||
color: vec4<f32>,
|
color: vec4<f32>,
|
||||||
matrices: array<mat4x4<f32>, 6>,
|
matrices: array<mat4x4<f32>, 6>,
|
||||||
}
|
}
|
||||||
@group(1) @binding(0)
|
@group(0) @binding(1)
|
||||||
var<uniform> light: Light;
|
var<uniform> light: Light;
|
||||||
|
|
||||||
struct GlobalUniforms {
|
struct GlobalUniforms {
|
||||||
|
@ -24,7 +24,7 @@ struct GlobalUniforms {
|
||||||
use_shadowmaps: u32,
|
use_shadowmaps: u32,
|
||||||
_padding: u32,
|
_padding: u32,
|
||||||
}
|
}
|
||||||
@group(1) @binding(1)
|
@group(0) @binding(2)
|
||||||
var<uniform> global_uniforms: GlobalUniforms;
|
var<uniform> global_uniforms: GlobalUniforms;
|
||||||
|
|
||||||
struct VertexInput {
|
struct VertexInput {
|
||||||
|
|
|
@ -47,24 +47,24 @@ fn vs_main(
|
||||||
|
|
||||||
// Fragment shader
|
// Fragment shader
|
||||||
|
|
||||||
@group(2)@binding(0)
|
@group(1) @binding(0)
|
||||||
var t_light_depth: texture_depth_2d_array;
|
var t_light_depth: texture_depth_2d_array;
|
||||||
@group(2) @binding(1)
|
@group(1) @binding(1)
|
||||||
var s_light_depth: sampler_comparison;
|
var s_light_depth: sampler_comparison;
|
||||||
|
|
||||||
@group(3) @binding(0)
|
@group(2) @binding(0)
|
||||||
var t_diffuse: texture_2d<f32>;
|
var t_diffuse: texture_2d<f32>;
|
||||||
@group(3)@binding(1)
|
@group(2) @binding(1)
|
||||||
var s_diffuse: sampler;
|
var s_diffuse: sampler;
|
||||||
|
|
||||||
@group(3)@binding(2)
|
@group(2) @binding(2)
|
||||||
var t_normal: texture_2d<f32>;
|
var t_normal: texture_2d<f32>;
|
||||||
@group(3) @binding(3)
|
@group(2) @binding(3)
|
||||||
var s_normal: sampler;
|
var s_normal: sampler;
|
||||||
|
|
||||||
@group(3)@binding(4)
|
@group(2) @binding(4)
|
||||||
var t_roughness_metalness: texture_2d<f32>;
|
var t_roughness_metalness: texture_2d<f32>;
|
||||||
@group(3) @binding(5)
|
@group(2) @binding(5)
|
||||||
var s_roughness_metalness: sampler;
|
var s_roughness_metalness: sampler;
|
||||||
|
|
||||||
@fragment
|
@fragment
|
||||||
|
|
|
@ -46,31 +46,27 @@ pub trait DrawLight<'a> {
|
||||||
fn draw_light_mesh(
|
fn draw_light_mesh(
|
||||||
&mut self,
|
&mut self,
|
||||||
mesh: &'a Mesh,
|
mesh: &'a Mesh,
|
||||||
camera_bind_group: &'a wgpu::BindGroup,
|
global_bind_group: &'a wgpu::BindGroup,
|
||||||
light_bind_group: &'a wgpu::BindGroup,
|
|
||||||
);
|
);
|
||||||
|
|
||||||
fn draw_light_mesh_instanced(
|
fn draw_light_mesh_instanced(
|
||||||
&mut self,
|
&mut self,
|
||||||
mesh: &'a Mesh,
|
mesh: &'a Mesh,
|
||||||
instances: Range<u32>,
|
instances: Range<u32>,
|
||||||
camera_bind_group: &'a wgpu::BindGroup,
|
global_bind_group: &'a wgpu::BindGroup,
|
||||||
light_bind_group: &'a wgpu::BindGroup,
|
|
||||||
);
|
);
|
||||||
|
|
||||||
fn draw_light_model(
|
fn draw_light_model(
|
||||||
&mut self,
|
&mut self,
|
||||||
model: &'a Model,
|
model: &'a Model,
|
||||||
camera_bind_group: &'a wgpu::BindGroup,
|
global_bind_group: &'a wgpu::BindGroup,
|
||||||
light_bind_group: &'a wgpu::BindGroup,
|
|
||||||
);
|
);
|
||||||
|
|
||||||
fn draw_light_model_instanced(
|
fn draw_light_model_instanced(
|
||||||
&mut self,
|
&mut self,
|
||||||
model: &'a Model,
|
model: &'a Model,
|
||||||
instances: Range<u32>,
|
instances: Range<u32>,
|
||||||
camera_bind_group: &'a wgpu::BindGroup,
|
global_bind_group: &'a wgpu::BindGroup,
|
||||||
light_bind_group: &'a wgpu::BindGroup,
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -81,48 +77,42 @@ impl<'a, 'b> DrawLight<'b> for wgpu::RenderPass<'a>
|
||||||
fn draw_light_mesh(
|
fn draw_light_mesh(
|
||||||
&mut self,
|
&mut self,
|
||||||
mesh: &'b Mesh,
|
mesh: &'b Mesh,
|
||||||
camera_bind_group: &'b wgpu::BindGroup,
|
global_bind_group: &'b wgpu::BindGroup
|
||||||
light_bind_group: &'b wgpu::BindGroup,
|
|
||||||
) {
|
) {
|
||||||
self.draw_light_mesh_instanced(mesh, 0..1, camera_bind_group, light_bind_group);
|
self.draw_light_mesh_instanced(mesh, 0..1, global_bind_group);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn draw_light_mesh_instanced(
|
fn draw_light_mesh_instanced(
|
||||||
&mut self,
|
&mut self,
|
||||||
mesh: &'b Mesh,
|
mesh: &'b Mesh,
|
||||||
instances: Range<u32>,
|
instances: Range<u32>,
|
||||||
camera_bind_group: &'b wgpu::BindGroup,
|
global_bind_group: &'b wgpu::BindGroup
|
||||||
light_bind_group: &'b wgpu::BindGroup,
|
|
||||||
) {
|
) {
|
||||||
self.set_vertex_buffer(0, mesh.vertex_buffer.slice(..));
|
self.set_vertex_buffer(0, mesh.vertex_buffer.slice(..));
|
||||||
self.set_index_buffer(mesh.index_buffer.slice(..), wgpu::IndexFormat::Uint32);
|
self.set_index_buffer(mesh.index_buffer.slice(..), wgpu::IndexFormat::Uint32);
|
||||||
self.set_bind_group(0, camera_bind_group, &[]);
|
self.set_bind_group(0, global_bind_group, &[]);
|
||||||
self.set_bind_group(1, light_bind_group, &[]);
|
|
||||||
self.draw_indexed(0..mesh.num_elements, 0, instances);
|
self.draw_indexed(0..mesh.num_elements, 0, instances);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn draw_light_model(
|
fn draw_light_model(
|
||||||
&mut self,
|
&mut self,
|
||||||
model: &'b Model,
|
model: &'b Model,
|
||||||
camera_bind_group: &'b wgpu::BindGroup,
|
global_bind_group: &'b wgpu::BindGroup
|
||||||
light_bind_group: &'b wgpu::BindGroup,
|
|
||||||
) {
|
) {
|
||||||
self.draw_light_model_instanced(model, 0..1, camera_bind_group, light_bind_group);
|
self.draw_light_model_instanced(model, 0..1, global_bind_group);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn draw_light_model_instanced(
|
fn draw_light_model_instanced(
|
||||||
&mut self,
|
&mut self,
|
||||||
model: &'b Model,
|
model: &'b Model,
|
||||||
instances: Range<u32>,
|
instances: Range<u32>,
|
||||||
camera_bind_group: &'b wgpu::BindGroup,
|
global_bind_group: &'b wgpu::BindGroup
|
||||||
light_bind_group: &'b wgpu::BindGroup,
|
|
||||||
) {
|
) {
|
||||||
for mesh in &model.meshes {
|
for mesh in &model.meshes {
|
||||||
self.draw_light_mesh_instanced(
|
self.draw_light_mesh_instanced(
|
||||||
mesh,
|
mesh,
|
||||||
instances.clone(),
|
instances.clone(),
|
||||||
camera_bind_group,
|
global_bind_group
|
||||||
light_bind_group,
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -69,6 +69,7 @@ pub trait DrawModel<'a> {
|
||||||
mesh: &'a Mesh,
|
mesh: &'a Mesh,
|
||||||
material: &'a Material,
|
material: &'a Material,
|
||||||
bind_groups: Vec<&'a wgpu::BindGroup>,
|
bind_groups: Vec<&'a wgpu::BindGroup>,
|
||||||
|
add_texture_binds: bool,
|
||||||
);
|
);
|
||||||
fn draw_mesh_instanced(
|
fn draw_mesh_instanced(
|
||||||
&mut self,
|
&mut self,
|
||||||
|
@ -76,18 +77,21 @@ pub trait DrawModel<'a> {
|
||||||
material: &'a Material,
|
material: &'a Material,
|
||||||
instances: Range<u32>,
|
instances: Range<u32>,
|
||||||
bind_groups: Vec<&'a wgpu::BindGroup>,
|
bind_groups: Vec<&'a wgpu::BindGroup>,
|
||||||
|
add_texture_binds: bool,
|
||||||
);
|
);
|
||||||
|
|
||||||
fn draw_model(
|
fn draw_model(
|
||||||
&mut self,
|
&mut self,
|
||||||
model: &'a Model,
|
model: &'a Model,
|
||||||
bind_groups: Vec<&'a wgpu::BindGroup>,
|
bind_groups: Vec<&'a wgpu::BindGroup>,
|
||||||
|
add_texture_binds: bool,
|
||||||
);
|
);
|
||||||
fn draw_model_instanced(
|
fn draw_model_instanced(
|
||||||
&mut self,
|
&mut self,
|
||||||
model: &'a Model,
|
model: &'a Model,
|
||||||
instances: Range<u32>,
|
instances: Range<u32>,
|
||||||
bind_groups: Vec<&'a wgpu::BindGroup>,
|
bind_groups: Vec<&'a wgpu::BindGroup>,
|
||||||
|
add_texture_binds: bool,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -100,8 +104,9 @@ impl<'a, 'b> DrawModel<'b> for wgpu::RenderPass<'a>
|
||||||
mesh: &'b Mesh,
|
mesh: &'b Mesh,
|
||||||
material: &'b Material,
|
material: &'b Material,
|
||||||
bind_groups: Vec<&'a wgpu::BindGroup>,
|
bind_groups: Vec<&'a wgpu::BindGroup>,
|
||||||
|
add_texture_binds: bool,
|
||||||
) {
|
) {
|
||||||
self.draw_mesh_instanced(mesh, material, 0..1, bind_groups);
|
self.draw_mesh_instanced(mesh, material, 0..1, bind_groups, add_texture_binds);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn draw_mesh_instanced(
|
fn draw_mesh_instanced(
|
||||||
|
@ -110,13 +115,16 @@ impl<'a, 'b> DrawModel<'b> for wgpu::RenderPass<'a>
|
||||||
material: &'b Material,
|
material: &'b Material,
|
||||||
instances: Range<u32>,
|
instances: Range<u32>,
|
||||||
bind_groups: Vec<&'a wgpu::BindGroup>,
|
bind_groups: Vec<&'a wgpu::BindGroup>,
|
||||||
|
add_texture_binds: bool,
|
||||||
) {
|
) {
|
||||||
self.set_vertex_buffer(0, mesh.vertex_buffer.slice(..));
|
self.set_vertex_buffer(0, mesh.vertex_buffer.slice(..));
|
||||||
self.set_index_buffer(mesh.index_buffer.slice(..), wgpu::IndexFormat::Uint32);
|
self.set_index_buffer(mesh.index_buffer.slice(..), wgpu::IndexFormat::Uint32);
|
||||||
for (i, group) in bind_groups.iter().enumerate() {
|
for (i, group) in bind_groups.iter().enumerate() {
|
||||||
self.set_bind_group(i as u32, group, &[]);
|
self.set_bind_group(i as u32, group, &[]);
|
||||||
}
|
}
|
||||||
self.set_bind_group(bind_groups.len() as u32, &material.bind_group, &[]);
|
if add_texture_binds {
|
||||||
|
self.set_bind_group(bind_groups.len() as u32, &material.bind_group, &[]);
|
||||||
|
}
|
||||||
self.draw_indexed(0..mesh.num_elements, 0, instances);
|
self.draw_indexed(0..mesh.num_elements, 0, instances);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -124,8 +132,9 @@ impl<'a, 'b> DrawModel<'b> for wgpu::RenderPass<'a>
|
||||||
&mut self,
|
&mut self,
|
||||||
model: &'b Model,
|
model: &'b Model,
|
||||||
bind_groups: Vec<&'a wgpu::BindGroup>,
|
bind_groups: Vec<&'a wgpu::BindGroup>,
|
||||||
|
add_texture_binds: bool,
|
||||||
) {
|
) {
|
||||||
self.draw_model_instanced(model, 0..1, bind_groups);
|
self.draw_model_instanced(model, 0..1, bind_groups, add_texture_binds);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn draw_model_instanced(
|
fn draw_model_instanced(
|
||||||
|
@ -133,6 +142,7 @@ impl<'a, 'b> DrawModel<'b> for wgpu::RenderPass<'a>
|
||||||
model: &'b Model,
|
model: &'b Model,
|
||||||
instances: Range<u32>,
|
instances: Range<u32>,
|
||||||
bind_groups: Vec<&'a wgpu::BindGroup>,
|
bind_groups: Vec<&'a wgpu::BindGroup>,
|
||||||
|
add_texture_binds: bool,
|
||||||
) {
|
) {
|
||||||
for mesh in &model.meshes {
|
for mesh in &model.meshes {
|
||||||
let material = &model.materials[mesh.material];
|
let material = &model.materials[mesh.material];
|
||||||
|
@ -141,6 +151,7 @@ impl<'a, 'b> DrawModel<'b> for wgpu::RenderPass<'a>
|
||||||
material,
|
material,
|
||||||
instances.clone(),
|
instances.clone(),
|
||||||
bind_groups.clone(),
|
bind_groups.clone(),
|
||||||
|
add_texture_binds,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,21 +38,23 @@ pub struct State {
|
||||||
camera: Camera,
|
camera: Camera,
|
||||||
camera_uniform: CameraUniform,
|
camera_uniform: CameraUniform,
|
||||||
camera_buffer: wgpu::Buffer,
|
camera_buffer: wgpu::Buffer,
|
||||||
camera_bind_group: wgpu::BindGroup,
|
global_bind_group: wgpu::BindGroup,
|
||||||
camera_controller: CameraController,
|
camera_controller: CameraController,
|
||||||
geom_instances: Vec<Instance>,
|
geom_instances: Vec<Instance>,
|
||||||
geom_instance_buffer: wgpu::Buffer,
|
geom_instance_buffer: wgpu::Buffer,
|
||||||
fog_instances: Vec<Instance>,
|
fog_instances: Vec<Instance>,
|
||||||
fog_instance_buffer: wgpu::Buffer,
|
fog_instance_buffer: wgpu::Buffer,
|
||||||
geometry_depth_texture: Texture,
|
geometry_depth_texture: Texture,
|
||||||
|
light_depth_texture: Texture,
|
||||||
geom_model: Model,
|
geom_model: Model,
|
||||||
fog_model: Model,
|
fog_model: Model,
|
||||||
light_model: Model,
|
light_model: Model,
|
||||||
light_uniform: LightUniform,
|
light_uniform: LightUniform,
|
||||||
light_buffer: wgpu::Buffer,
|
light_buffer: wgpu::Buffer,
|
||||||
light_debug_pass: RenderPass,
|
light_debug_pass: RenderPass,
|
||||||
light_bind_group: wgpu::BindGroup,
|
light_depth_bind_group: wgpu::BindGroup,
|
||||||
depth_bind_group: wgpu::BindGroup,
|
geometry_depth_bind_group: wgpu::BindGroup,
|
||||||
|
geometry_depth_bind_group_layout: wgpu::BindGroupLayout,
|
||||||
light_depth_pass: RenderPass,
|
light_depth_pass: RenderPass,
|
||||||
light_depth_texture_target_views: [wgpu::TextureView; SHADOW_MAP_LAYERS as usize],
|
light_depth_texture_target_views: [wgpu::TextureView; SHADOW_MAP_LAYERS as usize],
|
||||||
global_uniforms: GlobalUniforms,
|
global_uniforms: GlobalUniforms,
|
||||||
|
@ -124,41 +126,87 @@ impl State {
|
||||||
usage: wgpu::BufferUsages::UNIFORM | wgpu::BufferUsages::COPY_DST,
|
usage: wgpu::BufferUsages::UNIFORM | wgpu::BufferUsages::COPY_DST,
|
||||||
});
|
});
|
||||||
let camera_uniform_size = mem::size_of::<CameraUniform>() as u64;
|
let camera_uniform_size = mem::size_of::<CameraUniform>() as u64;
|
||||||
let camera_bind_group_layout =
|
|
||||||
|
let light_uniform = LightUniform::new([0.0, 0.0, 0.0], [1.0, 1.0, 1.0, 250000.0]);
|
||||||
|
let light_buffer = device.create_buffer_init(&wgpu::util::BufferInitDescriptor {
|
||||||
|
label: Some("Light UB"),
|
||||||
|
contents: bytemuck::cast_slice(&[light_uniform]),
|
||||||
|
usage: wgpu::BufferUsages::UNIFORM | wgpu::BufferUsages::COPY_DST,
|
||||||
|
});
|
||||||
|
let light_uniform_size = mem::size_of::<LightUniform>() as u64;
|
||||||
|
|
||||||
|
let global_uniforms = GlobalUniforms::default();
|
||||||
|
let global_uniforms_buffer = device.create_buffer_init(&wgpu::util::BufferInitDescriptor {
|
||||||
|
label: Some("Light Matrix UB"),
|
||||||
|
contents: bytemuck::cast_slice(&[global_uniforms]),
|
||||||
|
usage: wgpu::BufferUsages::UNIFORM | wgpu::BufferUsages::COPY_DST,
|
||||||
|
});
|
||||||
|
let global_uniform_size = mem::size_of::<GlobalUniforms>() as u64;
|
||||||
|
|
||||||
|
let global_bind_group_layout =
|
||||||
device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
|
device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
|
||||||
entries: &[wgpu::BindGroupLayoutEntry {
|
entries: &[
|
||||||
binding: 0,
|
// CameraUniform
|
||||||
visibility: wgpu::ShaderStages::VERTEX | wgpu::ShaderStages::FRAGMENT,
|
wgpu::BindGroupLayoutEntry {
|
||||||
ty: wgpu::BindingType::Buffer {
|
binding: 0,
|
||||||
ty: wgpu::BufferBindingType::Uniform,
|
visibility: wgpu::ShaderStages::VERTEX | wgpu::ShaderStages::FRAGMENT,
|
||||||
has_dynamic_offset: false,
|
ty: wgpu::BindingType::Buffer {
|
||||||
min_binding_size: wgpu::BufferSize::new(camera_uniform_size),
|
ty: wgpu::BufferBindingType::Uniform,
|
||||||
|
has_dynamic_offset: false,
|
||||||
|
min_binding_size: wgpu::BufferSize::new(camera_uniform_size),
|
||||||
|
},
|
||||||
|
count: None,
|
||||||
},
|
},
|
||||||
count: None,
|
// LightUniform
|
||||||
}],
|
wgpu::BindGroupLayoutEntry {
|
||||||
|
binding: 1,
|
||||||
|
visibility: wgpu::ShaderStages::VERTEX | wgpu::ShaderStages::FRAGMENT,
|
||||||
|
ty: wgpu::BindingType::Buffer {
|
||||||
|
ty: wgpu::BufferBindingType::Uniform,
|
||||||
|
has_dynamic_offset: false,
|
||||||
|
min_binding_size: wgpu::BufferSize::new(light_uniform_size),
|
||||||
|
},
|
||||||
|
count: None,
|
||||||
|
},
|
||||||
|
// global_uniforms
|
||||||
|
wgpu::BindGroupLayoutEntry {
|
||||||
|
binding: 2,
|
||||||
|
visibility: wgpu::ShaderStages::VERTEX | wgpu::ShaderStages::FRAGMENT,
|
||||||
|
ty: wgpu::BindingType::Buffer {
|
||||||
|
ty: wgpu::BufferBindingType::Uniform,
|
||||||
|
has_dynamic_offset: false,
|
||||||
|
min_binding_size: wgpu::BufferSize::new(global_uniform_size),
|
||||||
|
},
|
||||||
|
count: None,
|
||||||
|
},
|
||||||
|
],
|
||||||
label: Some("camera_bind_group_layout"),
|
label: Some("camera_bind_group_layout"),
|
||||||
});
|
});
|
||||||
let camera_bind_group = device.create_bind_group(&wgpu::BindGroupDescriptor {
|
let camera_bind_group = device.create_bind_group(&wgpu::BindGroupDescriptor {
|
||||||
layout: &camera_bind_group_layout,
|
layout: &global_bind_group_layout,
|
||||||
entries: &[wgpu::BindGroupEntry {
|
entries: &[
|
||||||
binding: 0,
|
// CameraUniform
|
||||||
resource: camera_buffer.as_entire_binding(),
|
wgpu::BindGroupEntry {
|
||||||
}],
|
binding: 0,
|
||||||
|
resource: camera_buffer.as_entire_binding(),
|
||||||
|
},
|
||||||
|
// light struct
|
||||||
|
wgpu::BindGroupEntry {
|
||||||
|
binding: 1,
|
||||||
|
resource: light_buffer.as_entire_binding(),
|
||||||
|
},
|
||||||
|
// global_uniforms
|
||||||
|
wgpu::BindGroupEntry {
|
||||||
|
binding: 2,
|
||||||
|
resource: global_uniforms_buffer.as_entire_binding(),
|
||||||
|
}
|
||||||
|
],
|
||||||
label: Some("camera_bind_group"),
|
label: Some("camera_bind_group"),
|
||||||
});
|
});
|
||||||
|
|
||||||
let camera_controller = CameraController::new(400.0, 2.0);
|
let camera_controller = CameraController::new(400.0, 2.0);
|
||||||
|
|
||||||
let geometry_depth_texture = Texture::create_depth_texture(
|
let geometry_depth_texture = State::create_geometry_depth_texture(&device, &config);
|
||||||
&device,
|
|
||||||
"geometry_depth_texture",
|
|
||||||
None,
|
|
||||||
config.width,
|
|
||||||
config.height,
|
|
||||||
1,
|
|
||||||
wgpu::TextureUsages::RENDER_ATTACHMENT | wgpu::TextureUsages::TEXTURE_BINDING,
|
|
||||||
true,
|
|
||||||
);
|
|
||||||
|
|
||||||
let light_depth_texture = Texture::create_depth_texture(
|
let light_depth_texture = Texture::create_depth_texture(
|
||||||
&device,
|
&device,
|
||||||
|
@ -188,71 +236,7 @@ impl State {
|
||||||
.try_into()
|
.try_into()
|
||||||
.expect("failed to create light depth texture views");
|
.expect("failed to create light depth texture views");
|
||||||
|
|
||||||
let light_uniform = LightUniform::new([0.0, 0.0, 0.0], [1.0, 1.0, 1.0, 250000.0]);
|
let light_depth_bind_group_layout =
|
||||||
|
|
||||||
let light_buffer = device.create_buffer_init(&wgpu::util::BufferInitDescriptor {
|
|
||||||
label: Some("Light UB"),
|
|
||||||
contents: bytemuck::cast_slice(&[light_uniform]),
|
|
||||||
usage: wgpu::BufferUsages::UNIFORM | wgpu::BufferUsages::COPY_DST,
|
|
||||||
});
|
|
||||||
|
|
||||||
let global_uniforms = GlobalUniforms::default();
|
|
||||||
let global_uniforms_buffer = device.create_buffer_init(&wgpu::util::BufferInitDescriptor {
|
|
||||||
label: Some("Light Matrix UB"),
|
|
||||||
contents: bytemuck::cast_slice(&[global_uniforms]),
|
|
||||||
usage: wgpu::BufferUsages::UNIFORM | wgpu::BufferUsages::COPY_DST,
|
|
||||||
});
|
|
||||||
|
|
||||||
let light_uniform_size = mem::size_of::<LightUniform>() as u64;
|
|
||||||
let light_matrix_uniform_size = mem::size_of::<GlobalUniforms>() as u64;
|
|
||||||
let light_bind_group_layout =
|
|
||||||
device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
|
|
||||||
entries: &[
|
|
||||||
// LightUniform
|
|
||||||
wgpu::BindGroupLayoutEntry {
|
|
||||||
binding: 0,
|
|
||||||
visibility: wgpu::ShaderStages::VERTEX | wgpu::ShaderStages::FRAGMENT,
|
|
||||||
ty: wgpu::BindingType::Buffer {
|
|
||||||
ty: wgpu::BufferBindingType::Uniform,
|
|
||||||
has_dynamic_offset: false,
|
|
||||||
min_binding_size: wgpu::BufferSize::new(light_uniform_size),
|
|
||||||
},
|
|
||||||
count: None,
|
|
||||||
},
|
|
||||||
// matrix index, use shadowmaps
|
|
||||||
wgpu::BindGroupLayoutEntry {
|
|
||||||
binding: 1,
|
|
||||||
// TODO: remove fragment vis once no shadowmap uniform
|
|
||||||
visibility: wgpu::ShaderStages::VERTEX | wgpu::ShaderStages::FRAGMENT,
|
|
||||||
ty: wgpu::BindingType::Buffer {
|
|
||||||
ty: wgpu::BufferBindingType::Uniform,
|
|
||||||
has_dynamic_offset: false,
|
|
||||||
min_binding_size: wgpu::BufferSize::new(light_matrix_uniform_size),
|
|
||||||
},
|
|
||||||
count: None,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
label: Some("Light Bind Group Layout"),
|
|
||||||
});
|
|
||||||
|
|
||||||
let light_bind_group = device.create_bind_group(&wgpu::BindGroupDescriptor {
|
|
||||||
layout: &light_bind_group_layout,
|
|
||||||
entries: &[
|
|
||||||
// light struct
|
|
||||||
wgpu::BindGroupEntry {
|
|
||||||
binding: 0,
|
|
||||||
resource: light_buffer.as_entire_binding(),
|
|
||||||
},
|
|
||||||
// matrix index
|
|
||||||
wgpu::BindGroupEntry {
|
|
||||||
binding: 1,
|
|
||||||
resource: global_uniforms_buffer.as_entire_binding(),
|
|
||||||
},
|
|
||||||
],
|
|
||||||
label: Some("Light Bind Group"),
|
|
||||||
});
|
|
||||||
|
|
||||||
let depth_bind_group_layout =
|
|
||||||
device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
|
device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
|
||||||
entries: &[
|
entries: &[
|
||||||
// light cubemap
|
// light cubemap
|
||||||
|
@ -272,29 +256,12 @@ impl State {
|
||||||
ty: wgpu::BindingType::Sampler(wgpu::SamplerBindingType::Comparison),
|
ty: wgpu::BindingType::Sampler(wgpu::SamplerBindingType::Comparison),
|
||||||
count: None,
|
count: None,
|
||||||
},
|
},
|
||||||
// geometry depth
|
|
||||||
wgpu::BindGroupLayoutEntry {
|
|
||||||
binding: 2,
|
|
||||||
visibility: wgpu::ShaderStages::FRAGMENT,
|
|
||||||
ty: wgpu::BindingType::Texture {
|
|
||||||
multisampled: false,
|
|
||||||
view_dimension: wgpu::TextureViewDimension::D2,
|
|
||||||
sample_type: wgpu::TextureSampleType::Depth,
|
|
||||||
},
|
|
||||||
count: None,
|
|
||||||
},
|
|
||||||
wgpu::BindGroupLayoutEntry {
|
|
||||||
binding: 3,
|
|
||||||
visibility: wgpu::ShaderStages::FRAGMENT,
|
|
||||||
ty: wgpu::BindingType::Sampler(wgpu::SamplerBindingType::Filtering),
|
|
||||||
count: None,
|
|
||||||
},
|
|
||||||
],
|
],
|
||||||
label: Some("Depth Bind Group Layout"),
|
label: Some("Light Bind Group Layout"),
|
||||||
});
|
});
|
||||||
|
|
||||||
let depth_bind_group = device.create_bind_group(&wgpu::BindGroupDescriptor {
|
let light_depth_bind_group = device.create_bind_group(&wgpu::BindGroupDescriptor {
|
||||||
layout: &depth_bind_group_layout,
|
layout: &light_depth_bind_group_layout,
|
||||||
entries: &[
|
entries: &[
|
||||||
// light cubemap
|
// light cubemap
|
||||||
wgpu::BindGroupEntry {
|
wgpu::BindGroupEntry {
|
||||||
|
@ -305,20 +272,35 @@ impl State {
|
||||||
binding: 1,
|
binding: 1,
|
||||||
resource: wgpu::BindingResource::Sampler(&light_depth_texture.sampler),
|
resource: wgpu::BindingResource::Sampler(&light_depth_texture.sampler),
|
||||||
},
|
},
|
||||||
// geometry depth
|
|
||||||
wgpu::BindGroupEntry {
|
|
||||||
binding: 2,
|
|
||||||
resource: wgpu::BindingResource::TextureView(&geometry_depth_texture.view),
|
|
||||||
},
|
|
||||||
wgpu::BindGroupEntry {
|
|
||||||
binding: 3,
|
|
||||||
resource: wgpu::BindingResource::Sampler(&geometry_depth_texture.sampler),
|
|
||||||
},
|
|
||||||
],
|
],
|
||||||
label: Some("Depth Bind Group"),
|
label: Some("Light Bind Group"),
|
||||||
});
|
});
|
||||||
|
|
||||||
surface.configure(&device, &config);
|
let geometry_depth_bind_group_layout =
|
||||||
|
device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
|
||||||
|
entries: &[
|
||||||
|
// geometry depth
|
||||||
|
wgpu::BindGroupLayoutEntry {
|
||||||
|
binding: 0,
|
||||||
|
visibility: wgpu::ShaderStages::FRAGMENT,
|
||||||
|
ty: wgpu::BindingType::Texture {
|
||||||
|
multisampled: false,
|
||||||
|
view_dimension: wgpu::TextureViewDimension::D2,
|
||||||
|
sample_type: wgpu::TextureSampleType::Depth,
|
||||||
|
},
|
||||||
|
count: None,
|
||||||
|
},
|
||||||
|
wgpu::BindGroupLayoutEntry {
|
||||||
|
binding: 1,
|
||||||
|
visibility: wgpu::ShaderStages::FRAGMENT,
|
||||||
|
ty: wgpu::BindingType::Sampler(wgpu::SamplerBindingType::Filtering),
|
||||||
|
count: None,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
label: Some("Depth Bind Group Layout"),
|
||||||
|
});
|
||||||
|
|
||||||
|
let geometry_depth_bind_group = State::create_geometry_depth_bind_group(&device, &geometry_depth_bind_group_layout, &geometry_depth_texture);
|
||||||
|
|
||||||
let texture_bind_group_layout =
|
let texture_bind_group_layout =
|
||||||
device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
|
device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
|
||||||
|
@ -433,8 +415,7 @@ impl State {
|
||||||
let light_depth_pass = RenderPass::new(
|
let light_depth_pass = RenderPass::new(
|
||||||
&device,
|
&device,
|
||||||
&[
|
&[
|
||||||
&camera_bind_group_layout,
|
&global_bind_group_layout,
|
||||||
&light_bind_group_layout,
|
|
||||||
],
|
],
|
||||||
&[],
|
&[],
|
||||||
"depth.wgsl",
|
"depth.wgsl",
|
||||||
|
@ -451,9 +432,8 @@ impl State {
|
||||||
let geometry_pass = RenderPass::new(
|
let geometry_pass = RenderPass::new(
|
||||||
&device,
|
&device,
|
||||||
&[
|
&[
|
||||||
&camera_bind_group_layout,
|
&global_bind_group_layout,
|
||||||
&light_bind_group_layout,
|
&light_depth_bind_group_layout,
|
||||||
&depth_bind_group_layout,
|
|
||||||
&texture_bind_group_layout,
|
&texture_bind_group_layout,
|
||||||
],
|
],
|
||||||
&[],
|
&[],
|
||||||
|
@ -470,7 +450,7 @@ impl State {
|
||||||
|
|
||||||
let light_debug_pass = RenderPass::new(
|
let light_debug_pass = RenderPass::new(
|
||||||
&device,
|
&device,
|
||||||
&[&camera_bind_group_layout, &light_bind_group_layout],
|
&[&global_bind_group_layout],
|
||||||
&[],
|
&[],
|
||||||
"light_debug.wgsl",
|
"light_debug.wgsl",
|
||||||
Some(config.format),
|
Some(config.format),
|
||||||
|
@ -486,10 +466,9 @@ impl State {
|
||||||
let fog_pass = RenderPass::new(
|
let fog_pass = RenderPass::new(
|
||||||
&device,
|
&device,
|
||||||
&[
|
&[
|
||||||
&camera_bind_group_layout,
|
&global_bind_group_layout,
|
||||||
&light_bind_group_layout,
|
&light_depth_bind_group_layout,
|
||||||
&depth_bind_group_layout,
|
&geometry_depth_bind_group_layout,
|
||||||
&texture_bind_group_layout,
|
|
||||||
],
|
],
|
||||||
&[],
|
&[],
|
||||||
"fog.wgsl",
|
"fog.wgsl",
|
||||||
|
@ -514,21 +493,23 @@ impl State {
|
||||||
camera,
|
camera,
|
||||||
camera_uniform,
|
camera_uniform,
|
||||||
camera_buffer,
|
camera_buffer,
|
||||||
camera_bind_group,
|
global_bind_group: camera_bind_group,
|
||||||
camera_controller,
|
camera_controller,
|
||||||
geom_instances,
|
geom_instances,
|
||||||
geom_instance_buffer,
|
geom_instance_buffer,
|
||||||
fog_instances,
|
fog_instances,
|
||||||
fog_instance_buffer,
|
fog_instance_buffer,
|
||||||
geometry_depth_texture,
|
geometry_depth_texture,
|
||||||
|
light_depth_texture,
|
||||||
geom_model,
|
geom_model,
|
||||||
fog_model,
|
fog_model,
|
||||||
light_model,
|
light_model,
|
||||||
light_uniform,
|
light_uniform,
|
||||||
light_buffer,
|
light_buffer,
|
||||||
light_debug_pass,
|
light_debug_pass,
|
||||||
light_bind_group,
|
light_depth_bind_group,
|
||||||
depth_bind_group,
|
geometry_depth_bind_group,
|
||||||
|
geometry_depth_bind_group_layout,
|
||||||
light_depth_pass,
|
light_depth_pass,
|
||||||
light_depth_texture_target_views,
|
light_depth_texture_target_views,
|
||||||
global_uniforms,
|
global_uniforms,
|
||||||
|
@ -536,6 +517,37 @@ impl State {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn create_geometry_depth_bind_group(device: &wgpu::Device, layout: &wgpu::BindGroupLayout, geometry_depth_texture: &Texture) -> wgpu::BindGroup {
|
||||||
|
device.create_bind_group(&wgpu::BindGroupDescriptor {
|
||||||
|
layout: layout,
|
||||||
|
entries: &[
|
||||||
|
// geometry depth
|
||||||
|
wgpu::BindGroupEntry {
|
||||||
|
binding: 0,
|
||||||
|
resource: wgpu::BindingResource::TextureView(&geometry_depth_texture.view),
|
||||||
|
},
|
||||||
|
wgpu::BindGroupEntry {
|
||||||
|
binding: 1,
|
||||||
|
resource: wgpu::BindingResource::Sampler(&geometry_depth_texture.sampler),
|
||||||
|
},
|
||||||
|
],
|
||||||
|
label: Some("Depth Bind Group"),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fn create_geometry_depth_texture(device: &wgpu::Device, config: &wgpu::SurfaceConfiguration) -> Texture {
|
||||||
|
Texture::create_depth_texture(
|
||||||
|
&device,
|
||||||
|
"geometry_depth_texture",
|
||||||
|
None,
|
||||||
|
config.width,
|
||||||
|
config.height,
|
||||||
|
1,
|
||||||
|
wgpu::TextureUsages::RENDER_ATTACHMENT | wgpu::TextureUsages::TEXTURE_BINDING,
|
||||||
|
true,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
pub fn resize(&mut self, new_size: winit::dpi::PhysicalSize<u32>) {
|
pub fn resize(&mut self, new_size: winit::dpi::PhysicalSize<u32>) {
|
||||||
if new_size.width > 0 && new_size.height > 0 {
|
if new_size.width > 0 && new_size.height > 0 {
|
||||||
self.size = new_size;
|
self.size = new_size;
|
||||||
|
@ -545,16 +557,8 @@ impl State {
|
||||||
self.camera
|
self.camera
|
||||||
.projection
|
.projection
|
||||||
.resize(new_size.width, new_size.height);
|
.resize(new_size.width, new_size.height);
|
||||||
self.geometry_depth_texture = Texture::create_depth_texture(
|
self.geometry_depth_texture = State::create_geometry_depth_texture(&self.device, &self.config);
|
||||||
&self.device,
|
self.geometry_depth_bind_group = State::create_geometry_depth_bind_group(&self.device, &self.geometry_depth_bind_group_layout, &self.geometry_depth_texture);
|
||||||
"geometry_depth_texture",
|
|
||||||
None,
|
|
||||||
self.config.width,
|
|
||||||
self.config.height,
|
|
||||||
1,
|
|
||||||
wgpu::TextureUsages::RENDER_ATTACHMENT | wgpu::TextureUsages::TEXTURE_BINDING,
|
|
||||||
true,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -638,7 +642,8 @@ impl State {
|
||||||
light_depth_render_pass.draw_model_instanced(
|
light_depth_render_pass.draw_model_instanced(
|
||||||
&self.geom_model,
|
&self.geom_model,
|
||||||
0..self.geom_instances.len() as u32,
|
0..self.geom_instances.len() as u32,
|
||||||
[&self.camera_bind_group, &self.light_bind_group].into(),
|
[&self.global_bind_group].into(),
|
||||||
|
false,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -690,7 +695,8 @@ impl State {
|
||||||
geom_render_pass.draw_model_instanced(
|
geom_render_pass.draw_model_instanced(
|
||||||
&self.geom_model,
|
&self.geom_model,
|
||||||
0..self.geom_instances.len() as u32,
|
0..self.geom_instances.len() as u32,
|
||||||
[&self.camera_bind_group, &self.light_bind_group, &self.depth_bind_group].into(),
|
[&self.global_bind_group, &self.light_depth_bind_group].into(),
|
||||||
|
true,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
geometry_encoder.pop_debug_group();
|
geometry_encoder.pop_debug_group();
|
||||||
|
@ -723,8 +729,7 @@ impl State {
|
||||||
light_debug_render_pass.set_pipeline(&self.light_debug_pass.pipeline);
|
light_debug_render_pass.set_pipeline(&self.light_debug_pass.pipeline);
|
||||||
light_debug_render_pass.draw_light_model(
|
light_debug_render_pass.draw_light_model(
|
||||||
&self.light_model,
|
&self.light_model,
|
||||||
&self.camera_bind_group,
|
&self.global_bind_group,
|
||||||
&self.light_bind_group,
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
geometry_encoder.pop_debug_group();
|
geometry_encoder.pop_debug_group();
|
||||||
|
@ -763,7 +768,8 @@ impl State {
|
||||||
fog_render_pass.draw_model_instanced(
|
fog_render_pass.draw_model_instanced(
|
||||||
&self.fog_model,
|
&self.fog_model,
|
||||||
0..self.fog_instances.len() as u32,
|
0..self.fog_instances.len() as u32,
|
||||||
[&self.camera_bind_group, &self.light_bind_group, &self.depth_bind_group].into(),
|
[&self.global_bind_group, &self.light_depth_bind_group, &self.geometry_depth_bind_group].into(),
|
||||||
|
false,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
fog_encoder.pop_debug_group();
|
fog_encoder.pop_debug_group();
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue