working shadows kinda
This commit is contained in:
parent
45ec2fd936
commit
d3d2437fa2
|
|
@ -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<na::Vector3<f32>> {
|
||||
let body = self.bodies.get(rigid_body_handle)?;
|
||||
return Some(*body.translation());
|
||||
pub fn clear_ofb(&mut self) {
|
||||
let mut coll_to_del: Vec<ColliderHandle> = 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))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
20
src/main.rs
20
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,
|
||||
|
|
|
|||
|
|
@ -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),
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
Loading…
Reference in New Issue