From d3d2437fa289251900c86a0b8212876c3ee7b91b Mon Sep 17 00:00:00 2001 From: Flima Desktop Date: Wed, 3 Dec 2025 21:28:27 +0000 Subject: [PATCH] working shadows kinda --- src/engine.rs | 46 ++++++++++++++++++++---- src/main.rs | 20 +++++++---- src/rendering.rs | 85 +++++++++++++++++++++++++++++++++------------ src/rendering/ui.rs | 6 ++-- 4 files changed, 118 insertions(+), 39 deletions(-) diff --git a/src/engine.rs b/src/engine.rs index 676e9a5..fa7a3be 100644 --- a/src/engine.rs +++ b/src/engine.rs @@ -2,7 +2,7 @@ use std::collections::HashMap; use macroquad::prelude as mq; use nalgebra as na; -use rapier3d::prelude as rp; +use rapier3d::prelude::{self as rp, ColliderHandle}; fn random_color() -> mq::Color { return mq::Color::new( @@ -53,12 +53,17 @@ impl World { ); } - pub fn position_of_rb( - &self, - rigid_body_handle: rp::RigidBodyHandle, - ) -> Option> { - let body = self.bodies.get(rigid_body_handle)?; - return Some(*body.translation()); + pub fn clear_ofb(&mut self) { + let mut coll_to_del: Vec = Vec::new(); + for (handle, col) in self.colliders.iter() { + if (col.translation().y < -15.0) { + coll_to_del.push(handle); + } + } + for handle in coll_to_del { + self.colliders + .remove(handle, &mut self.island_manager, &mut self.bodies, false); + } } pub fn position_of_collider( @@ -138,3 +143,30 @@ impl Default for World { }; } } + +pub fn collider_world_aabb(world: &World, handle: rp::ColliderHandle) -> (mq::Vec3, mq::Vec3) { + use rp::ShapeType; + let pos: glam::Vec3 = world.position_of_collider(handle).unwrap().into(); + let shape = world.colliders.get(handle).unwrap().shape(); + + match shape.shape_type() { + ShapeType::Cuboid => { + let he: glam::Vec3 = (shape.as_cuboid().unwrap().half_extents * 2.0).into(); + let min = mq::vec3(pos.x - he.x * 0.5, pos.y - he.y * 0.5, pos.z - he.z * 0.5); + let max = mq::vec3(pos.x + he.x * 0.5, pos.y + he.y * 0.5, pos.z + he.z * 0.5); + (min, max) + } + + ShapeType::Ball => { + let r = shape.as_ball().unwrap().radius; + let min = pos - mq::vec3(r, r, r); + let max = pos + mq::vec3(r, r, r); + (min, max) + } + + _ => { + // Default fallback + (pos - mq::vec3(1.0, 1.0, 1.0), pos + mq::vec3(1.0, 1.0, 1.0)) + } + } +} diff --git a/src/main.rs b/src/main.rs index 8c8a232..59bc919 100644 --- a/src/main.rs +++ b/src/main.rs @@ -8,7 +8,6 @@ mod camera; mod rendering; mod graphics_util; -use graphics_util::*; use crate::rendering::Renderer; @@ -19,20 +18,21 @@ async fn main() { // Physics Initialization world.register_free_collider( - ColliderBuilder::cuboid(100.0, 10.0, 100.0) - .restitution(0.2) + ColliderBuilder::cuboid(50.0, 5.0, 50.0) + .restitution(0.5) .build(), None, ); add_objects(&mut world); + let mut i = 0; loop { renderer.update_camera(); if mq::is_key_pressed(mq::KeyCode::L) { renderer .light .set_location(renderer.camera.position, renderer.camera.front); - renderer.update_light(); + renderer.update_light(&world); println!( "Light Pos: {}, Light Front Vec{}", renderer.light.position, renderer.light.front @@ -50,7 +50,13 @@ async fn main() { world.step(); renderer.draw(&mut world); - mq::next_frame().await + mq::next_frame().await; + + i += 1; + if i > 30 { + world.clear_ofb(); + renderer.update_light(&world); + } } } @@ -63,8 +69,8 @@ fn add_objects(world: &mut World) { .build(), ); world.register_collider( - ColliderBuilder::cuboid(10.0, 10.0, 10.0) - .restitution(0.5) + ColliderBuilder::cuboid(5.0, 5.0, 5.0) + .restitution(0.3) .build(), body, None, diff --git a/src/rendering.rs b/src/rendering.rs index 0bc0a52..36fdec7 100644 --- a/src/rendering.rs +++ b/src/rendering.rs @@ -1,10 +1,10 @@ use crate::{ camera::{self as cam, FirstPersonCamera}, - engine::World, + engine::{self, World}, graphics_util::draw_cuboid, }; use macroquad::prelude as mq; -use macroquad::ui::{hash, Ui}; +use macroquad::ui::hash; use rapier3d::prelude::*; use strum::IntoEnumIterator; @@ -143,7 +143,7 @@ impl Renderer { }, mq::MaterialParams { pipeline_params: mq::PipelineParams { - cull_face: macroquad::miniquad::CullFace::Back, + // cull_face: macroquad::miniquad::CullFace::Back, depth_test: mq::Comparison::LessOrEqual, depth_write: true, ..Default::default() @@ -182,7 +182,6 @@ impl Renderer { }; r.light .set_location(mq::vec3(10.0, 40.0, 10.0), mq::Vec3::NEG_Y); - r.update_light(); r.apply_config(); return r; } @@ -193,15 +192,57 @@ impl Renderer { pub fn update_camera(&mut self) { self.camera.update(mq::get_frame_time()); } - pub fn update_light(&mut self) { + pub fn update_light(&mut self, world: &World) { + let light_view = self.light.view_matrix; + + let mut min_ls = mq::vec3(f32::MAX, f32::MAX, f32::MAX); + let mut max_ls = mq::vec3(f32::MIN, f32::MIN, f32::MIN); + + // 1. iterate all world objects + for (handle, _) in world.colliders.iter() { + let (min_ws, max_ws) = engine::collider_world_aabb(world, handle); + + // 2. get 8 corners of the world-space AABB + for &corner in &[ + mq::vec3(min_ws.x, min_ws.y, min_ws.z), + mq::vec3(min_ws.x, min_ws.y, max_ws.z), + mq::vec3(min_ws.x, max_ws.y, min_ws.z), + mq::vec3(min_ws.x, max_ws.y, max_ws.z), + mq::vec3(max_ws.x, min_ws.y, min_ws.z), + mq::vec3(max_ws.x, min_ws.y, max_ws.z), + mq::vec3(max_ws.x, max_ws.y, min_ws.z), + mq::vec3(max_ws.x, max_ws.y, max_ws.z), + ] { + // 3. transform to light space + let p = light_view.transform_point3(corner); + + min_ls.x = min_ls.x.min(p.x); + min_ls.y = min_ls.y.min(p.y); + min_ls.z = min_ls.z.min(p.z); + + max_ls.x = max_ls.x.max(p.x); + max_ls.y = max_ls.y.max(p.y); + max_ls.z = max_ls.z.max(p.z); + } + } + + // 4. build tight-fitting orthographic projection + self.light.projection_matrix = mq::Mat4::orthographic_rh( + min_ls.x, max_ls.x, // left/right + min_ls.y, max_ls.y, // bottom/top + -max_ls.z, -min_ls.z, // near/far (RH coordinate system) + ); + + // 5. upload to materials let light_space_matrix = self.light.get_space_matrix(); self.base_material - .set_uniform(MaterialUni::LightPosition.as_str(), self.light.position); + .set_uniform("light_position", self.light.position); self.base_material - .set_uniform(MaterialUni::LightSpaceMatrix.as_str(), light_space_matrix); + .set_uniform("light_space_matrix", light_space_matrix); self.depth_material - .set_uniform(MaterialUni::LightSpaceMatrix.as_str(), light_space_matrix); + .set_uniform("light_space_matrix", light_space_matrix); } + fn render_depth(&mut self, mut world: &mut World) { mq::set_camera(&mq::Camera3D { position: self.light.position, @@ -211,7 +252,7 @@ impl Renderer { ..Default::default() }); mq::gl_use_material(&self.depth_material); - mq::clear_background(mq::DARKGRAY); + mq::clear_background(mq::BLACK); draw_world(&mut world, None); mq::gl_use_default_material(); mq::set_default_camera(); @@ -220,12 +261,12 @@ impl Renderer { .set_texture("shadow_map", self.depth_target.texture.clone()); } fn render_default(&mut self, mut world: &mut World) { - mq::clear_background(mq::LIGHTGRAY); + mq::clear_background(mq::DARKGRAY); self.camera.apply(); draw_world(&mut world, Some(&self.base_material)); - mq::draw_sphere(self.light.position, 0.25, None, mq::WHITE); + // mq::draw_sphere(self.light.position, 0.25, None, mq::WHITE); mq::draw_grid(20, 1., mq::BLACK, mq::GRAY); mq::gl_use_default_material(); @@ -233,17 +274,17 @@ impl Renderer { } fn render_ui(&mut self) { mq::set_default_camera(); - // mq::draw_texture_ex( - // &self.depth_target.texture, - // 0., - // 0., - // mq::WHITE, - // mq::DrawTextureParams { - // flip_y: true, - // dest_size: Some(mq::vec2(200.0, 200.0)), - // ..Default::default() - // }, - // ); + mq::draw_texture_ex( + &self.depth_target.texture, + 320., + 20., + mq::WHITE, + mq::DrawTextureParams { + flip_y: true, + dest_size: Some(mq::vec2(200.0, 200.0)), + ..Default::default() + }, + ); macroquad::ui::root_ui().window( hash!("MaterialWindow"), mq::vec2(20.0, 20.0), diff --git a/src/rendering/ui.rs b/src/rendering/ui.rs index 6e18383..a840cef 100644 --- a/src/rendering/ui.rs +++ b/src/rendering/ui.rs @@ -22,9 +22,9 @@ impl MaterialUi { render_shadows_bool: true, shadow_step_count: 1, shadow_step_size: 1, - shadow_min_bias: 0.0, - shadow_fac_bias: 0.0, - shadow_max_bias: 0.0, + shadow_min_bias: 5.0, + shadow_fac_bias: 1.0, + shadow_max_bias: 100.0, } } pub fn apply(&self, material: ¯oquad::prelude::Material) {