Skip to content

Commit

Permalink
edit: better light view
Browse files Browse the repository at this point in the history
  • Loading branch information
Sufhal committed Sep 15, 2024
1 parent 11a28b2 commit 7c22d2c
Show file tree
Hide file tree
Showing 3 changed files with 76 additions and 9 deletions.
8 changes: 4 additions & 4 deletions src/modules/camera/camera.rs
Original file line number Diff line number Diff line change
Expand Up @@ -227,7 +227,7 @@ impl CameraController {
#[derive(Debug, Copy, Clone, bytemuck::Pod, bytemuck::Zeroable)]
pub struct CameraUniform {
view_position: [f32; 4],
view_proj: [[f32; 4]; 4],
pub view_proj: [[f32; 4]; 4],
view_matrix: [[f32; 4]; 4],
projection_matrix: [[f32; 4]; 4],
}
Expand All @@ -243,17 +243,17 @@ impl CameraUniform {
}

pub fn update_view_proj(&mut self, camera: &Camera, projection: &Projection, directional_light: &DirectionalLight) {
let projection_matrix = projection.calc_matrix();
let view_matrix = camera.calc_matrix();
match camera.use_directional_light {
true => {
let uniform = directional_light.uniform(projection.aspect);
let uniform = directional_light.uniform_from_camera((projection_matrix * view_matrix).into());
self.view_position = uniform.view_position;
self.view_proj = uniform.view_proj;
self.view_matrix = uniform.view_matrix;
self.projection_matrix = uniform.projection_matrix;
}
false => {
let projection_matrix = projection.calc_matrix();
let view_matrix = camera.calc_matrix();
self.view_position = camera.position.to_homogeneous().into();
self.view_proj = (projection_matrix * view_matrix).into();
self.view_matrix = view_matrix.into();
Expand Down
74 changes: 70 additions & 4 deletions src/modules/core/directional_light.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use cgmath::{perspective, Deg, Matrix4, Point3, Vector3};
use cgmath::{perspective, Deg, EuclideanSpace, InnerSpace, Matrix4, Point3, SquareMatrix, Vector3, Vector4, Zero};
use crate::modules::camera::camera::OPENGL_TO_WGPU_MATRIX;

use super::texture::Texture;
Expand Down Expand Up @@ -49,9 +49,8 @@ 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, 100000.0);
let light_view = Matrix4::look_at_rh(self.position, self.target, Vector3::unit_y());
let light_projection = OPENGL_TO_WGPU_MATRIX * perspective(Deg(28.0), aspect, 0.1, 100.0);
let mx_view_proj = light_projection * light_view;

DirectionalLightUniform {
Expand All @@ -62,6 +61,13 @@ impl DirectionalLight {
}
}

pub fn uniform_from_camera(&self, camera_view_proj: Matrix4<f32>) -> DirectionalLightUniform {
DirectionalLightUniform {
view_proj: calculate_light_view_proj(camera_view_proj, self).into(),
..Default::default()
}
}


}

Expand All @@ -83,4 +89,64 @@ impl Default for DirectionalLightUniform {
projection_matrix: Default::default(),
}
}
}

fn calculate_light_view_proj(camera_view_proj: Matrix4<f32>, directional_light: &DirectionalLight) -> Matrix4<f32> {

let light_direction = Vector3::new(-0.5, -1.0, -0.5).normalize(); // Diagonale depuis la gauche et vers l'arrière
let frustum_center = get_frustum_center(camera_view_proj);
let light_position = frustum_center - light_direction * 100.0;

let light_view = Matrix4::look_at_rh(
light_position,
frustum_center,
Vector3::unit_y()
);

let light_projection = OPENGL_TO_WGPU_MATRIX * perspective(Deg(28.0), 1.0, 0.1, 100.0);

light_projection * light_view
}


fn get_frustum_corners(camera_view_proj: Matrix4<f32>) -> [Point3<f32>; 8] {
let inverse_view_proj = camera_view_proj.invert().unwrap();
let mut frustum_corners = [
Vector4::new(-1.0, -1.0, -1.0, 1.0), // Near bottom left
Vector4::new(1.0, -1.0, -1.0, 1.0), // Near bottom right
Vector4::new(1.0, 1.0, -1.0, 1.0), // Near top right
Vector4::new(-1.0, 1.0, -1.0, 1.0), // Near top left
Vector4::new(-1.0, -1.0, 1.0, 1.0), // Far bottom left
Vector4::new(1.0, -1.0, 1.0, 1.0), // Far bottom right
Vector4::new(1.0, 1.0, 1.0, 1.0), // Far top right
Vector4::new(-1.0, 1.0, 1.0, 1.0), // Far top left
];

for corner in &mut frustum_corners {
*corner = inverse_view_proj * *corner;
*corner /= corner.w;
}

let frustum_points = frustum_corners.map(|v| Point3::new(v.x, v.y, v.z));
frustum_points
}

fn get_frustum_center(camera_view_proj: Matrix4<f32>) -> Point3<f32> {
let frustum_corners = get_frustum_corners(camera_view_proj);

// Prendre les points proches (0-3) et éloignés (4-7)
let mut center = Point3::new(0.0, 0.0, 0.0);

for corner in &frustum_corners {
center.x += corner.x;
center.y += corner.y;
center.z += corner.z;
}

// Diviser par 8 pour obtenir la moyenne
center.x /= 8.0;
center.y /= 8.0;
center.z /= 8.0;

center
}
3 changes: 2 additions & 1 deletion src/modules/state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -452,7 +452,8 @@ 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.shadow_pipeline.uniforms.directional_light = self.directional_light.uniform(self.projection.aspect);
self.shadow_pipeline.uniforms.directional_light = self.directional_light.uniform_from_camera(self.common_pipeline.uniforms.camera.view_proj.into());
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]));

Expand Down

0 comments on commit 7c22d2c

Please sign in to comment.