Skip to content

Commit

Permalink
add: shadows to terrain
Browse files Browse the repository at this point in the history
  • Loading branch information
Sufhal committed Sep 15, 2024
1 parent b3215a6 commit 11a28b2
Show file tree
Hide file tree
Showing 9 changed files with 90 additions and 51 deletions.
2 changes: 1 addition & 1 deletion src/modules/camera/camera.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ impl Camera {
}

pub struct Projection {
aspect: f32,
pub aspect: f32,
fovy: Rad<f32>,
znear: f32,
zfar: f32,
Expand Down
Empty file.
6 changes: 3 additions & 3 deletions src/modules/core/directional_light.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ impl DirectionalLight {
let texture = device.create_texture(&wgpu::TextureDescriptor {
label: Some("Shadow Map Texture"),
size: wgpu::Extent3d {
width: 512,
height: 512,
width: 4096,
height: 4096,
depth_or_array_layers: 1,
},
mip_level_count: 1,
Expand Down Expand Up @@ -51,7 +51,7 @@ impl DirectionalLight {
pub fn uniform(&self, aspect: f32) -> DirectionalLightUniform {
let up = Vector3::unit_y();
let light_view = Matrix4::look_at_rh(self.position, self.target, up);
let light_projection = OPENGL_TO_WGPU_MATRIX * perspective(Deg(28.0), aspect, 0.1, 100.0);
let light_projection = OPENGL_TO_WGPU_MATRIX * perspective(Deg(28.0), aspect, 0.1, 100000.0);
let mx_view_proj = light_projection * light_view;

DirectionalLightUniform {
Expand Down
3 changes: 1 addition & 2 deletions src/modules/core/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,4 @@ pub mod scene;
pub mod skinning;
pub mod motions;
pub mod raycaster;
pub mod directional_light;
pub mod cascaded_shadows;
pub mod directional_light;
2 changes: 1 addition & 1 deletion src/modules/environment/cycle.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use crate::modules::utils::functions::{denormalize_f32, normalize_f32};

const REAL_TIME: bool = false;
const REAL_TIME: bool = true;
const MS_IN_DAY: u64 = 24 * 3600 * 1000;
const UTC: u64 = 2;
const DAY_START_HOUR: u64 = 5;
Expand Down
58 changes: 54 additions & 4 deletions src/modules/pipelines/common_pipeline.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
use wgpu::util::DeviceExt;
use crate::modules::{camera::camera::CameraUniform, core::light::LightUniform, environment::{cycle::CycleUniform, fog::FogUniform, sun::SunUniform}};
use crate::modules::{camera::camera::CameraUniform, core::{directional_light::{self, DirectionalLight, DirectionalLightUniform}, light::LightUniform}, environment::{cycle::CycleUniform, fog::FogUniform, sun::SunUniform}};

pub struct Buffers {
pub light: wgpu::Buffer,
pub camera: wgpu::Buffer,
pub cycle: wgpu::Buffer,
pub sun: wgpu::Buffer,
pub fog: wgpu::Buffer,
pub directional_light: wgpu::Buffer,
}

pub struct Uniforms {
Expand All @@ -15,6 +16,7 @@ pub struct Uniforms {
pub cycle: CycleUniform,
pub sun: SunUniform,
pub fog: FogUniform,
pub directional_light: DirectionalLightUniform,
}

pub struct CommonPipeline {
Expand All @@ -28,11 +30,12 @@ impl CommonPipeline {

pub fn new(
device: &wgpu::Device,
directional_light: &DirectionalLight,
) -> Self {
let uniforms = Self::create_uniforms();
let buffers = Self::create_buffers(device, &uniforms);
let global_bind_group_layout = Self::create_global_bind_group_layout(device);
let global_bind_group = Self::create_global_bind_group(device, &global_bind_group_layout, &buffers);
let global_bind_group = Self::create_global_bind_group(device, &global_bind_group_layout, &buffers, directional_light);
Self {
global_bind_group_layout,
global_bind_group,
Expand Down Expand Up @@ -99,12 +102,41 @@ impl CommonPipeline {
},
count: None,
},
// shadow sampler
wgpu::BindGroupLayoutEntry {
binding: 5,
visibility: wgpu::ShaderStages::FRAGMENT,
ty: wgpu::BindingType::Sampler(wgpu::SamplerBindingType::Comparison),
count: None,
},
// shadow texture
wgpu::BindGroupLayoutEntry {
binding: 6,
visibility: wgpu::ShaderStages::FRAGMENT,
ty: wgpu::BindingType::Texture {
multisampled: false,
sample_type: wgpu::TextureSampleType::Depth,
view_dimension: wgpu::TextureViewDimension::D2,
},
count: None,
},
// directional light
wgpu::BindGroupLayoutEntry {
binding: 7,
visibility: wgpu::ShaderStages::VERTEX_FRAGMENT,
ty: wgpu::BindingType::Buffer {
ty: wgpu::BufferBindingType::Uniform,
has_dynamic_offset: false,
min_binding_size: None,
},
count: None,
},
],
label: Some("global_bind_group_layout"),
})
}

fn create_global_bind_group(device: &wgpu::Device, global_layout: &wgpu::BindGroupLayout, buffers: &Buffers) -> wgpu::BindGroup {
fn create_global_bind_group(device: &wgpu::Device, global_layout: &wgpu::BindGroupLayout, buffers: &Buffers, directional_light: &DirectionalLight) -> wgpu::BindGroup {
device.create_bind_group(&wgpu::BindGroupDescriptor {
layout: &global_layout,
entries: &[
Expand All @@ -127,7 +159,19 @@ impl CommonPipeline {
wgpu::BindGroupEntry {
binding: 4,
resource: buffers.fog.as_entire_binding(),
}
},
wgpu::BindGroupEntry {
binding: 5,
resource: wgpu::BindingResource::Sampler(&directional_light.shadow_texture.sampler),
},
wgpu::BindGroupEntry {
binding: 6,
resource: wgpu::BindingResource::TextureView(&directional_light.shadow_texture.view),
},
wgpu::BindGroupEntry {
binding: 7,
resource: buffers.directional_light.as_entire_binding(),
},
],
label: Some("light_bind_group"),
})
Expand All @@ -145,6 +189,7 @@ impl CommonPipeline {
cycle: CycleUniform::default(),
sun: SunUniform::default(),
fog: FogUniform::default(),
directional_light: DirectionalLightUniform::default(),
}
}

Expand Down Expand Up @@ -175,6 +220,11 @@ impl CommonPipeline {
contents: bytemuck::cast_slice(&[uniforms.fog]),
usage: wgpu::BufferUsages::UNIFORM | wgpu::BufferUsages::COPY_DST,
}),
directional_light: device.create_buffer_init(&wgpu::util::BufferInitDescriptor {
label: Some("Directional Light Buffer"),
contents: bytemuck::cast_slice(&[uniforms.directional_light]),
usage: wgpu::BufferUsages::UNIFORM | wgpu::BufferUsages::COPY_DST,
}),
}
}

Expand Down
8 changes: 6 additions & 2 deletions src/modules/state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,7 @@ impl<'a> State<'a> {
let mut ui = UserInterface::new(&device, &config, &multisampled_texture, window.scale_factor() as f32);
ui.std_out.push(format!("MSAA set to {sample_count}, supported values are {:?}", supported_sample_count));

let directional_light = DirectionalLight::new([400.0, 300.0, 200.0], [376.0, 182.0, 641.0], &device);
let directional_light = DirectionalLight::new([300.0, 400.0, 200.0], [376.0, 182.0, 641.0], &device);

let camera = camera::Camera::new((376.0, 182.0, 641.0), cgmath::Deg(-90.0), cgmath::Deg(-20.0));
// let camera = camera::Camera::new((0.0, 5.0, 10.0), cgmath::Deg(-90.0), cgmath::Deg(-20.0));
Expand All @@ -171,7 +171,7 @@ impl<'a> State<'a> {

let depth_texture = texture::Texture::create_depth_texture(&device, &config, sample_count, "depth_texture");

let common_pipeline = CommonPipeline::new(&device);
let common_pipeline = CommonPipeline::new(&device, &directional_light);
let terrain_pipeline = TerrainPipeline::new(&device, &config, Some(texture::Texture::DEPTH_FORMAT), &multisampled_texture, &common_pipeline);
let water_pipeline = WaterPipeline::new(&device, &config, Some(texture::Texture::DEPTH_FORMAT), &multisampled_texture, &common_pipeline);
let sun_pipeline = SunPipeline::new(&device, &config, Some(texture::Texture::DEPTH_FORMAT), &multisampled_texture, &common_pipeline);
Expand Down Expand Up @@ -452,6 +452,10 @@ impl<'a> State<'a> {
terrain.update(elapsed_time, delta_ms as f32, &self.queue);
}

self.shadow_pipeline.uniforms.directional_light = self.directional_light.uniform(self.projection.aspect);
self.queue.write_buffer(&self.shadow_pipeline.buffers.directional_light, 0, bytemuck::cast_slice(&[self.shadow_pipeline.uniforms.directional_light]));
self.queue.write_buffer(&self.common_pipeline.buffers.directional_light, 0, bytemuck::cast_slice(&[self.shadow_pipeline.uniforms.directional_light]));

self.common_pipeline.uniforms.cycle.day_factor = self.terrains[0].environment.cycle.day_factor;
self.common_pipeline.uniforms.cycle.night_factor = self.terrains[0].environment.cycle.night_factor;
self.queue.write_buffer(&self.common_pipeline.buffers.cycle, 0, bytemuck::cast_slice(&[self.common_pipeline.uniforms.cycle]));
Expand Down
37 changes: 0 additions & 37 deletions src/modules/terrain/chunk.rs
Original file line number Diff line number Diff line change
Expand Up @@ -119,43 +119,6 @@ impl Chunk {
}
}
}

// if let Some(property) = state.properties.properties.get(&area_object.id) {
// match property {
// Property::Building(building) => {

// if let Ok(model_objects) = load_model_glb(
// &building.file,
// &state.device,
// &state.queue,
// &state.skinned_models_pipeline,
// &state.simple_models_pipeline,
// ).await {
// for mut object in model_objects {
// if let Some(object3d) = &mut object.object3d {
// match object3d {
// Object3D::Simple(simple) => {
// let instance = simple.request_instance(&state.device);
// instance.set_position(cgmath::Vector3::from([
// area_object.position[0],
// area_object.position[1] + area_object.offset,
// area_object.position[2]
// ]));
// instance.set_rotation(cgmath::Quaternion::from_angle_y(cgmath::Rad::from(cgmath::Deg(area_object.rotation[1]))));
// instance.take();
// },
// _ => ()
// };
// }
// }
// } else {
// println!("cannot load object {}: {}", &building.id, &building.file);
// }
// }
// }
// } else {
// println!("areaobject {} not found in properties", &area_object.id);
// }
}
}

Expand Down
25 changes: 24 additions & 1 deletion src/shaders/terrain.wgsl
Original file line number Diff line number Diff line change
Expand Up @@ -94,10 +94,19 @@ struct Fog {
}
@group(0) @binding(4) var<uniform> fog: Fog;

@group(0) @binding(5) var shadow_sampler: sampler_comparison;
@group(0) @binding(6) var shadow_texture: texture_depth_2d;
struct DirectionalLight {
view_position: vec4<f32>,
view_proj: mat4x4<f32>,
view_matrix: mat4x4<f32>,
projection_matrix: mat4x4<f32>,
}
@group(0) @binding(7) var<uniform> directional_light: DirectionalLight;

struct ChunkInformations {
textures_count: u32,
}

@group(1) @binding(1) var<uniform> chunk_informations: ChunkInformations;
@group(1) @binding(2) var sampler_tex: sampler;
@group(1) @binding(3) var tex_0: texture_2d<f32>;
Expand Down Expand Up @@ -225,6 +234,20 @@ fn fs_main(in: VertexOutput) -> @location(0) vec4<f32> {

var final_color = result.rgb;


let light_space_position = directional_light.view_proj * vec4<f32>(in.world_position, 1.0);
let proj_correction = 1.0 / light_space_position.w;
let proj_coords = light_space_position.xy * vec2<f32>(0.5, -0.5) * proj_correction + 0.5;

let shadow = textureSampleCompare(
shadow_texture,
shadow_sampler,
proj_coords.xy,
light_space_position.z * proj_correction,
);

final_color *= denormalize_value_between(shadow, 0.2, 1.0);

// fog
if fog.enabled == 1.0 {
let fog_color = mix(fog.night_color, fog.day_color, sun_light_factor);
Expand Down

0 comments on commit 11a28b2

Please sign in to comment.