current not working well
This commit is contained in:
parent
7a3f5fce9f
commit
45ec2fd936
|
|
@ -11,6 +11,7 @@ dependencies = [
|
||||||
"nalgebra",
|
"nalgebra",
|
||||||
"rand",
|
"rand",
|
||||||
"rapier3d",
|
"rapier3d",
|
||||||
|
"strum",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
@ -312,6 +313,12 @@ dependencies = [
|
||||||
"stable_deref_trait",
|
"stable_deref_trait",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "heck"
|
||||||
|
version = "0.5.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "image"
|
name = "image"
|
||||||
version = "0.24.9"
|
version = "0.24.9"
|
||||||
|
|
@ -785,6 +792,27 @@ version = "1.1.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f"
|
checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "strum"
|
||||||
|
version = "0.27.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "af23d6f6c1a224baef9d3f61e287d2761385a5b88fdab4eb4c6f11aeb54c4bcf"
|
||||||
|
dependencies = [
|
||||||
|
"strum_macros",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "strum_macros"
|
||||||
|
version = "0.27.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7695ce3845ea4b33927c055a39dc438a45b059f7c1b3d91d38d10355fb8cbca7"
|
||||||
|
dependencies = [
|
||||||
|
"heck",
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "syn"
|
name = "syn"
|
||||||
version = "2.0.110"
|
version = "2.0.110"
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,7 @@ rapier3d = { version = "0.31", features = [ "simd-stable" ] }
|
||||||
nalgebra = {version="0.34", features = ["convert-glam027"]}
|
nalgebra = {version="0.34", features = ["convert-glam027"]}
|
||||||
glam = "0.27"
|
glam = "0.27"
|
||||||
rand = "0.9.2"
|
rand = "0.9.2"
|
||||||
|
strum = { version = "0.27", features = ["derive"] }
|
||||||
|
|
||||||
[[bin]]
|
[[bin]]
|
||||||
name = "tools"
|
name = "tools"
|
||||||
|
|
|
||||||
10
src/main.rs
10
src/main.rs
|
|
@ -19,7 +19,7 @@ async fn main() {
|
||||||
|
|
||||||
// Physics Initialization
|
// Physics Initialization
|
||||||
world.register_free_collider(
|
world.register_free_collider(
|
||||||
ColliderBuilder::cuboid(50.0, 10.0, 50.0)
|
ColliderBuilder::cuboid(100.0, 10.0, 100.0)
|
||||||
.restitution(0.2)
|
.restitution(0.2)
|
||||||
.build(),
|
.build(),
|
||||||
None,
|
None,
|
||||||
|
|
@ -42,6 +42,10 @@ async fn main() {
|
||||||
if mq::is_key_pressed(mq::KeyCode::C) {
|
if mq::is_key_pressed(mq::KeyCode::C) {
|
||||||
add_objects(&mut world);
|
add_objects(&mut world);
|
||||||
}
|
}
|
||||||
|
if mq::is_key_pressed(mq::KeyCode::M) {
|
||||||
|
renderer.apply_config();
|
||||||
|
}
|
||||||
|
|
||||||
// Physics Simulation
|
// Physics Simulation
|
||||||
world.step();
|
world.step();
|
||||||
renderer.draw(&mut world);
|
renderer.draw(&mut world);
|
||||||
|
|
@ -59,8 +63,8 @@ fn add_objects(world: &mut World) {
|
||||||
.build(),
|
.build(),
|
||||||
);
|
);
|
||||||
world.register_collider(
|
world.register_collider(
|
||||||
ColliderBuilder::cuboid(3.0, 3.0, 3.0)
|
ColliderBuilder::cuboid(10.0, 10.0, 10.0)
|
||||||
.restitution(1.0)
|
.restitution(0.5)
|
||||||
.build(),
|
.build(),
|
||||||
body,
|
body,
|
||||||
None,
|
None,
|
||||||
|
|
|
||||||
125
src/rendering.rs
125
src/rendering.rs
|
|
@ -4,14 +4,17 @@ use crate::{
|
||||||
graphics_util::draw_cuboid,
|
graphics_util::draw_cuboid,
|
||||||
};
|
};
|
||||||
use macroquad::prelude as mq;
|
use macroquad::prelude as mq;
|
||||||
|
use macroquad::ui::{hash, Ui};
|
||||||
|
|
||||||
use rapier3d::prelude::*;
|
use rapier3d::prelude::*;
|
||||||
|
use strum::IntoEnumIterator;
|
||||||
|
mod ui;
|
||||||
|
|
||||||
const DEPTH_MAP_SIZE: u32 = 512;
|
const DEPTH_MAP_SIZE: u32 = 2048;
|
||||||
const ENABLE_SHADOWS: bool = true;
|
|
||||||
|
|
||||||
const LIGHT_PROJECTION_SIZE: f32 = 20.0;
|
const LIGHT_PROJECTION_SIZE: f32 = 40.0;
|
||||||
const LIGHT_NEAR: f32 = 10.0;
|
const LIGHT_NEAR: f32 = 50.0;
|
||||||
const LIGHT_FAR: f32 = 100.0;
|
const LIGHT_FAR: f32 = 400.0;
|
||||||
|
|
||||||
pub struct Light {
|
pub struct Light {
|
||||||
projection_matrix: mq::Mat4,
|
projection_matrix: mq::Mat4,
|
||||||
|
|
@ -54,7 +57,60 @@ pub struct Renderer {
|
||||||
depth_target: mq::RenderTarget,
|
depth_target: mq::RenderTarget,
|
||||||
pub light: Light,
|
pub light: Light,
|
||||||
pub camera: cam::FirstPersonCamera,
|
pub camera: cam::FirstPersonCamera,
|
||||||
has_light_moved: bool,
|
ui_state: ui::MaterialUi,
|
||||||
|
pub enable_shadows: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(strum::EnumIter, Debug)]
|
||||||
|
pub enum MaterialUni {
|
||||||
|
RenderNormalsBool,
|
||||||
|
RenderShadowsBool,
|
||||||
|
ShadowStepCount,
|
||||||
|
ShadowStepSize,
|
||||||
|
ShadowMinBias,
|
||||||
|
ShadowFacBias,
|
||||||
|
ShadowMaxBias,
|
||||||
|
LightPosition,
|
||||||
|
LightSpaceMatrix,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl MaterialUni {
|
||||||
|
pub fn as_str(&self) -> &'static str {
|
||||||
|
use MaterialUni::*;
|
||||||
|
match self {
|
||||||
|
RenderNormalsBool => "render_normals_bool",
|
||||||
|
RenderShadowsBool => "render_shadows_bool",
|
||||||
|
ShadowStepCount => "shadow_step_count",
|
||||||
|
ShadowStepSize => "shadow_step_size",
|
||||||
|
ShadowMinBias => "shadow_min_bias",
|
||||||
|
ShadowFacBias => "shadow_fac_bias",
|
||||||
|
ShadowMaxBias => "shadow_max_bias",
|
||||||
|
LightPosition => "light_position",
|
||||||
|
LightSpaceMatrix => "light_space_matrix",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pub fn as_type(&self) -> mq::UniformType {
|
||||||
|
use mq::UniformType::*;
|
||||||
|
use MaterialUni::*;
|
||||||
|
match self {
|
||||||
|
RenderNormalsBool => Int1,
|
||||||
|
RenderShadowsBool => Int1,
|
||||||
|
ShadowStepCount => Int1,
|
||||||
|
ShadowStepSize => Int1,
|
||||||
|
ShadowMinBias => Float1,
|
||||||
|
ShadowFacBias => Float1,
|
||||||
|
ShadowMaxBias => Float1,
|
||||||
|
LightPosition => Float3,
|
||||||
|
LightSpaceMatrix => Mat4,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pub fn uniform_list() -> Vec<mq::UniformDesc> {
|
||||||
|
let mut ret: Vec<mq::UniformDesc> = Default::default();
|
||||||
|
for member in MaterialUni::iter() {
|
||||||
|
ret.push(mq::UniformDesc::new(member.as_str(), member.as_type()));
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Renderer {
|
impl Renderer {
|
||||||
|
|
@ -71,19 +127,14 @@ impl Renderer {
|
||||||
depth_write: true,
|
depth_write: true,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
},
|
},
|
||||||
uniforms: vec![
|
uniforms: MaterialUni::uniform_list(),
|
||||||
mq::UniformDesc::new("render_normals_bool", mq::UniformType::Int1),
|
|
||||||
mq::UniformDesc::new("render_shadows_bool", mq::UniformType::Int1),
|
|
||||||
mq::UniformDesc::new("light_position", mq::UniformType::Float3),
|
|
||||||
mq::UniformDesc::new("light_space_matrix", mq::UniformType::Mat4),
|
|
||||||
],
|
|
||||||
textures: vec![String::from("shadow_map")],
|
textures: vec![String::from("shadow_map")],
|
||||||
..Default::default()
|
..Default::default()
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
material.set_uniform("render_normals_bool", 0);
|
material.set_uniform(MaterialUni::RenderNormalsBool.as_str(), 0);
|
||||||
material.set_uniform("render_shadows_bool", ENABLE_SHADOWS);
|
material.set_uniform(MaterialUni::RenderShadowsBool.as_str(), true as i32);
|
||||||
|
|
||||||
let depth_material = mq::load_material(
|
let depth_material = mq::load_material(
|
||||||
mq::ShaderSource::Glsl {
|
mq::ShaderSource::Glsl {
|
||||||
|
|
@ -92,7 +143,7 @@ impl Renderer {
|
||||||
},
|
},
|
||||||
mq::MaterialParams {
|
mq::MaterialParams {
|
||||||
pipeline_params: mq::PipelineParams {
|
pipeline_params: mq::PipelineParams {
|
||||||
// cull_face: macroquad::miniquad::CullFace::Back,
|
cull_face: macroquad::miniquad::CullFace::Back,
|
||||||
depth_test: mq::Comparison::LessOrEqual,
|
depth_test: mq::Comparison::LessOrEqual,
|
||||||
depth_write: true,
|
depth_write: true,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
|
|
@ -126,25 +177,30 @@ impl Renderer {
|
||||||
depth_target: depth_map_texture,
|
depth_target: depth_map_texture,
|
||||||
light,
|
light,
|
||||||
camera,
|
camera,
|
||||||
has_light_moved: true,
|
ui_state: ui::MaterialUi::new(),
|
||||||
|
enable_shadows: true,
|
||||||
};
|
};
|
||||||
r.light
|
r.light
|
||||||
.set_location(mq::vec3(10.0, 40.0, 10.0), mq::Vec3::NEG_Y);
|
.set_location(mq::vec3(10.0, 40.0, 10.0), mq::Vec3::NEG_Y);
|
||||||
r.update_light();
|
r.update_light();
|
||||||
|
r.apply_config();
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
pub fn apply_config(&mut self) {
|
||||||
|
self.ui_state.apply(&self.base_material);
|
||||||
|
self.enable_shadows = self.ui_state.render_shadows_bool;
|
||||||
|
}
|
||||||
pub fn update_camera(&mut self) {
|
pub fn update_camera(&mut self) {
|
||||||
self.camera.update(mq::get_frame_time());
|
self.camera.update(mq::get_frame_time());
|
||||||
}
|
}
|
||||||
pub fn update_light(&mut self) {
|
pub fn update_light(&mut self) {
|
||||||
let light_space_matrix = self.light.get_space_matrix();
|
let light_space_matrix = self.light.get_space_matrix();
|
||||||
self.base_material
|
self.base_material
|
||||||
.set_uniform("light_position", self.light.position);
|
.set_uniform(MaterialUni::LightPosition.as_str(), self.light.position);
|
||||||
self.base_material
|
self.base_material
|
||||||
.set_uniform("light_space_matrix", light_space_matrix);
|
.set_uniform(MaterialUni::LightSpaceMatrix.as_str(), light_space_matrix);
|
||||||
self.depth_material
|
self.depth_material
|
||||||
.set_uniform("light_space_matrix", light_space_matrix);
|
.set_uniform(MaterialUni::LightSpaceMatrix.as_str(), light_space_matrix);
|
||||||
self.has_light_moved = true;
|
|
||||||
}
|
}
|
||||||
fn render_depth(&mut self, mut world: &mut World) {
|
fn render_depth(&mut self, mut world: &mut World) {
|
||||||
mq::set_camera(&mq::Camera3D {
|
mq::set_camera(&mq::Camera3D {
|
||||||
|
|
@ -177,22 +233,29 @@ impl Renderer {
|
||||||
}
|
}
|
||||||
fn render_ui(&mut self) {
|
fn render_ui(&mut self) {
|
||||||
mq::set_default_camera();
|
mq::set_default_camera();
|
||||||
mq::draw_texture_ex(
|
// mq::draw_texture_ex(
|
||||||
&self.depth_target.texture,
|
// &self.depth_target.texture,
|
||||||
0.,
|
// 0.,
|
||||||
0.,
|
// 0.,
|
||||||
mq::WHITE,
|
// mq::WHITE,
|
||||||
mq::DrawTextureParams {
|
// mq::DrawTextureParams {
|
||||||
flip_y: true,
|
// flip_y: true,
|
||||||
dest_size: Some(mq::vec2(200.0, 200.0)),
|
// dest_size: Some(mq::vec2(200.0, 200.0)),
|
||||||
..Default::default()
|
// ..Default::default()
|
||||||
|
// },
|
||||||
|
// );
|
||||||
|
macroquad::ui::root_ui().window(
|
||||||
|
hash!("MaterialWindow"),
|
||||||
|
mq::vec2(20.0, 20.0),
|
||||||
|
mq::vec2(300.0, 300.0),
|
||||||
|
|ui| {
|
||||||
|
self.ui_state.ui(ui);
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
pub fn draw(&mut self, mut world: &mut World) {
|
pub fn draw(&mut self, mut world: &mut World) {
|
||||||
if ENABLE_SHADOWS {
|
if self.enable_shadows {
|
||||||
self.render_depth(&mut world);
|
self.render_depth(&mut world);
|
||||||
self.has_light_moved = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
self.render_default(&mut world);
|
self.render_default(&mut world);
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,115 @@
|
||||||
|
use crate::rendering::{self, MaterialUni};
|
||||||
|
use macroquad::prelude::*;
|
||||||
|
use macroquad::ui::{hash, Ui};
|
||||||
|
|
||||||
|
use strum::IntoEnumIterator;
|
||||||
|
|
||||||
|
// A struct that stores editable versions of all MaterialUni uniforms.
|
||||||
|
pub struct MaterialUi {
|
||||||
|
pub render_normals_bool: bool,
|
||||||
|
pub render_shadows_bool: bool,
|
||||||
|
pub shadow_step_count: u32,
|
||||||
|
pub shadow_step_size: u32,
|
||||||
|
pub shadow_min_bias: f32,
|
||||||
|
pub shadow_fac_bias: f32,
|
||||||
|
pub shadow_max_bias: f32,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl MaterialUi {
|
||||||
|
pub fn new() -> Self {
|
||||||
|
Self {
|
||||||
|
render_normals_bool: false,
|
||||||
|
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,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pub fn apply(&self, material: ¯oquad::prelude::Material) {
|
||||||
|
use MaterialUni::*;
|
||||||
|
material.set_uniform(RenderNormalsBool.as_str(), self.render_normals_bool as i32);
|
||||||
|
material.set_uniform(RenderShadowsBool.as_str(), self.render_shadows_bool as i32);
|
||||||
|
material.set_uniform(ShadowStepCount.as_str(), self.shadow_step_count as i32);
|
||||||
|
material.set_uniform(ShadowStepSize.as_str(), self.shadow_step_size as i32);
|
||||||
|
material.set_uniform(ShadowMinBias.as_str(), self.shadow_min_bias / 1000f32);
|
||||||
|
material.set_uniform(ShadowFacBias.as_str(), self.shadow_fac_bias / 1000f32);
|
||||||
|
material.set_uniform(ShadowMaxBias.as_str(), self.shadow_max_bias / 1000f32);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl MaterialUi {
|
||||||
|
pub fn ui(&mut self, ui: &mut Ui) {
|
||||||
|
use crate::rendering::MaterialUni::*;
|
||||||
|
|
||||||
|
for uniform in rendering::MaterialUni::iter() {
|
||||||
|
match uniform {
|
||||||
|
RenderNormalsBool => {
|
||||||
|
ui.checkbox(
|
||||||
|
hash!("RenderNormalsBool"),
|
||||||
|
"Render Normals",
|
||||||
|
&mut self.render_normals_bool,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
RenderShadowsBool => {
|
||||||
|
ui.checkbox(
|
||||||
|
hash!("RenderShadowsBool"),
|
||||||
|
"Render Shadows",
|
||||||
|
&mut self.render_shadows_bool,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
ShadowStepCount => {
|
||||||
|
ui.drag(
|
||||||
|
hash!("ShadowStepCount"),
|
||||||
|
"Shadow Step Count",
|
||||||
|
Some((1, 15)),
|
||||||
|
&mut self.shadow_step_count,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
ShadowStepSize => {
|
||||||
|
ui.drag(
|
||||||
|
hash!("ShadowStepSize"),
|
||||||
|
"Shadow Step Size",
|
||||||
|
Some((1, 15)),
|
||||||
|
&mut self.shadow_step_size,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
ShadowMinBias => {
|
||||||
|
ui.slider(
|
||||||
|
hash!("ShadowMinBiasSlider"),
|
||||||
|
"1/1000th Min Bias",
|
||||||
|
0.0..1000.0, // min..max range
|
||||||
|
&mut self.shadow_min_bias,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
ShadowFacBias => {
|
||||||
|
ui.slider(
|
||||||
|
hash!("ShadowFacBiasSlider"),
|
||||||
|
"1/1000th Fac Bias",
|
||||||
|
0.0..1000.0, // min..max range
|
||||||
|
&mut self.shadow_fac_bias,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
ShadowMaxBias => {
|
||||||
|
ui.slider(
|
||||||
|
hash!("ShadowMaxBiasSlider"),
|
||||||
|
"1/1000th Max Bias",
|
||||||
|
0.0..200000.0, // min..max range
|
||||||
|
&mut self.shadow_max_bias,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
_ => continue,
|
||||||
|
}
|
||||||
|
|
||||||
|
ui.separator();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,11 +1,13 @@
|
||||||
|
|
||||||
#version 330 core
|
#version 330 core
|
||||||
|
|
||||||
|
precision highp float;
|
||||||
|
|
||||||
in float dist_to_cam;
|
in float dist_to_cam;
|
||||||
|
|
||||||
out vec4 FragColor;
|
out vec4 FragColor;
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
float c = gl_FragCoord.z * gl_FragCoord.w;
|
float c = gl_FragCoord.z / gl_FragCoord.w;
|
||||||
FragColor = vec4(c, c, c, c);
|
FragColor = vec4(c, c, c, c);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,6 @@
|
||||||
#version 330 core
|
#version 330 core
|
||||||
|
precision highp float;
|
||||||
|
|
||||||
attribute vec3 position;
|
attribute vec3 position;
|
||||||
attribute vec3 normal; // Ensure this attribute exists!
|
attribute vec3 normal; // Ensure this attribute exists!
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,13 +1,23 @@
|
||||||
#version 330 core
|
#version 330 core
|
||||||
|
|
||||||
|
precision highp float;
|
||||||
|
precision highp sampler2D;
|
||||||
|
|
||||||
in vec4 v_normal;
|
in vec4 v_normal;
|
||||||
in vec4 color;
|
in vec4 color;
|
||||||
in vec3 light_direction;
|
in vec3 light_direction;
|
||||||
in vec4 v_light_space_position; // New: Position transformed by LightSpaceMatrix
|
in vec4 v_light_space_position;
|
||||||
|
|
||||||
uniform int render_normals_bool;
|
uniform int render_normals_bool;
|
||||||
uniform int render_shadows_bool;
|
uniform int render_shadows_bool;
|
||||||
uniform sampler2D shadow_map; // New: Depth map texture
|
|
||||||
|
uniform float shadow_max_bias;
|
||||||
|
uniform float shadow_min_bias;
|
||||||
|
uniform float shadow_fac_bias;
|
||||||
|
uniform int shadow_step_size;
|
||||||
|
uniform int shadow_step_count;
|
||||||
|
|
||||||
|
uniform highp sampler2D shadow_map;
|
||||||
|
|
||||||
out vec4 FragColor;
|
out vec4 FragColor;
|
||||||
|
|
||||||
|
|
@ -18,69 +28,59 @@ const float diffuse_strenght = 0.7;
|
||||||
* Calculates the shadow factor (0.0 for shadow, 1.0 for lit).
|
* Calculates the shadow factor (0.0 for shadow, 1.0 for lit).
|
||||||
*/
|
*/
|
||||||
float calculate_shadow() {
|
float calculate_shadow() {
|
||||||
float min_bias = 0.003;
|
float cosTheta = dot(normalize(v_normal.xyz), normalize(light_direction));
|
||||||
float max_bias = 0.01;
|
float bias = shadow_fac_bias * tan(acos(cosTheta));
|
||||||
float dot_product = dot(normalize(v_normal.xyz), normalize(light_direction));
|
bias = clamp(bias, shadow_min_bias, shadow_max_bias);
|
||||||
float bias = max(max_bias * (1.0 - dot_product), min_bias);
|
// float bias = max(shadow_max_bias * (1.0 - dot_product), shadow_min_bias);
|
||||||
|
|
||||||
// float bias = 0;
|
|
||||||
|
|
||||||
// 1. Perspective divide to get Normalized Device Coordinates (NDC)
|
// 1. Perspective divide to get Normalized Device Coordinates (NDC)
|
||||||
vec3 proj_coords = v_light_space_position.xyz / v_light_space_position.w;
|
vec3 proj_coords = v_light_space_position.xyz / v_light_space_position.w;
|
||||||
|
proj_coords = proj_coords * 0.5 + 0.5;
|
||||||
|
|
||||||
// 2. Transform to texture coordinates (0 to 1 range)
|
float current_depth = proj_coords.z;
|
||||||
vec2 tex_coords = proj_coords.xy * 0.5 + 0.5;
|
|
||||||
|
|
||||||
// 3. Get the closest depth from the light's perspective (shadow map)
|
// Deal with coords outside texture or infinite distance (no objects found)
|
||||||
// We sample the red channel since Macroquad's depth texture stores depth data there.
|
if (proj_coords.x > 1.0 || proj_coords.x < 0.0 || proj_coords.y > 1.0 || proj_coords.y < 0.0 || current_depth > 1.0) {
|
||||||
float closest_depth = texture(shadow_map, tex_coords).r;
|
|
||||||
|
|
||||||
// 4. Get the current fragment's depth from the light's perspective
|
|
||||||
// float current_depth = proj_coords.z;
|
|
||||||
float current_depth = proj_coords.z * 0.5 + 0.5;
|
|
||||||
// float current_depth = v_light_space_position.z;
|
|
||||||
// 5. Check if the fragment is outside the light frustum
|
|
||||||
if (tex_coords.x > 1.0 || tex_coords.x < 0.0 || tex_coords.y > 1.0 || tex_coords.y < 0.0 || current_depth > 1.0) {
|
|
||||||
return 1.0;
|
return 1.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// float shadow = 0.0;
|
vec2 texelSize = 1.0 / textureSize(shadow_map, 0);
|
||||||
// vec2 texelSize = 1.0 / textureSize(shadow_map, 0);
|
|
||||||
// int x_ran = 1;
|
|
||||||
// for (int x = -x_ran; x <= x_ran; x++)
|
|
||||||
// {
|
|
||||||
// for (int y = -x_ran; y <= x_ran; y++)
|
|
||||||
// {
|
|
||||||
// float pcfDepth = texture(shadow_map, tex_coords + vec2(x, y) * texelSize).x;
|
|
||||||
// shadow += current_depth - bias > pcfDepth ? 0.0 : 1.0;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// shadow = current_depth - bias > closest_depth ? 0.0 : 1.0;
|
|
||||||
|
|
||||||
// shadow /= ((2 * x_ran) + 1) * ((2 * x_ran) + 1);
|
float shadow = 0;
|
||||||
|
|
||||||
// 6. Compare depths with a bias: if current depth > closest depth, we are in shadow (0.0)
|
int range = (shadow_step_count - 1) / 2;
|
||||||
float shadow = current_depth - bias > closest_depth ? 0.0 : 1.0;
|
for (int x = -range; x <= range; x++)
|
||||||
|
{
|
||||||
|
for (int y = -range; y <= range; y++)
|
||||||
|
{
|
||||||
|
float pcfDepth = texture(shadow_map, proj_coords.xy + (vec2(x, y) * texelSize) * shadow_step_size).r;
|
||||||
|
shadow += current_depth - bias > pcfDepth ? 0.0 : 1.0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
shadow /= shadow_step_count * shadow_step_count;
|
||||||
|
|
||||||
return min(max(shadow, 0), 1);
|
return shadow;
|
||||||
}
|
}
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
float diff = max(dot(normalize(vec3(v_normal.x, v_normal.y, v_normal.z)), normalize(light_direction)), 0) * diffuse_strenght;
|
float diff = max(dot(normalize(vec3(v_normal.x, v_normal.y, v_normal.z)), normalize(light_direction)), 0) * diffuse_strenght;
|
||||||
|
vec4 app_color;
|
||||||
if (render_normals_bool == 1) {
|
if (render_normals_bool == 1) {
|
||||||
FragColor = vec4(v_normal);
|
app_color = normalize(abs(v_normal));
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
app_color = normalize(color);
|
||||||
|
}
|
||||||
|
|
||||||
if (render_shadows_bool == 1) {
|
if (render_shadows_bool == 1) {
|
||||||
float lighting = ambient_strenght + diff;
|
float shadow_factor = calculate_shadow();
|
||||||
FragColor = normalize(v_normal) * lighting;
|
|
||||||
return;
|
float lighting = ambient_strenght + diff * shadow_factor;
|
||||||
|
|
||||||
|
FragColor = app_color * lighting;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
float lighting = ambient_strenght + diff;
|
||||||
|
FragColor = app_color * lighting;
|
||||||
}
|
}
|
||||||
|
|
||||||
float shadow_factor = calculate_shadow();
|
|
||||||
|
|
||||||
float lighting = ambient_strenght + diff * shadow_factor;
|
|
||||||
|
|
||||||
FragColor = normalize(abs(v_normal)) * lighting;
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
#version 330 core
|
#version 330 core
|
||||||
|
precision highp float;
|
||||||
|
|
||||||
attribute vec3 position;
|
attribute vec3 position;
|
||||||
attribute vec4 color0;
|
attribute vec4 color0;
|
||||||
|
|
|
||||||
|
|
@ -1,149 +0,0 @@
|
||||||
use macroquad::prelude::{self as mq, UniformDesc};
|
|
||||||
|
|
||||||
#[macroquad::main("Normal Shading")]
|
|
||||||
async fn main() {
|
|
||||||
let vertex = include_str!("shader.vert");
|
|
||||||
let fragment = include_str!("shader.frag");
|
|
||||||
|
|
||||||
let material = mq::load_material(
|
|
||||||
mq::ShaderSource::Glsl { vertex, fragment },
|
|
||||||
mq::MaterialParams {
|
|
||||||
pipeline_params: mq::PipelineParams {
|
|
||||||
depth_test: mq::Comparison::LessOrEqual,
|
|
||||||
depth_write: true,
|
|
||||||
..Default::default()
|
|
||||||
},
|
|
||||||
uniforms: vec![UniformDesc::new(
|
|
||||||
"render_normals_bool",
|
|
||||||
mq::UniformType::Int1,
|
|
||||||
)],
|
|
||||||
..Default::default()
|
|
||||||
},
|
|
||||||
)
|
|
||||||
.unwrap();
|
|
||||||
material.set_uniform("render_normals_bool", 1);
|
|
||||||
|
|
||||||
loop {
|
|
||||||
mq::clear_background(mq::GRAY);
|
|
||||||
mq::set_camera(&mq::Camera3D {
|
|
||||||
position: mq::vec3(4.0, 4.0, 4.0),
|
|
||||||
target: mq::vec3(0.0, 0.0, 0.0),
|
|
||||||
up: mq::vec3(0.0, 1.0, 0.0),
|
|
||||||
..Default::default()
|
|
||||||
});
|
|
||||||
|
|
||||||
mq::gl_use_material(&material);
|
|
||||||
|
|
||||||
draw_cuboid(mq::vec3(3.0, 0.0, 0.0), mq::vec3(1.0, 2.0, 3.0), mq::RED);
|
|
||||||
|
|
||||||
mq::gl_use_default_material();
|
|
||||||
mq::set_default_camera();
|
|
||||||
mq::next_frame().await;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn generate_normals_smooth(vertexes: &mut Vec<mq::Vertex>, indices: &[u16]) {
|
|
||||||
for v in vertexes.iter_mut() {
|
|
||||||
v.normal = mq::vec4(0.0, 0.0, 0.0, 0.0);
|
|
||||||
}
|
|
||||||
|
|
||||||
for i in 0..(indices.len() / 3) {
|
|
||||||
let idx0 = indices[i * 3 + 0] as usize;
|
|
||||||
let idx1 = indices[i * 3 + 1] as usize;
|
|
||||||
let idx2 = indices[i * 3 + 2] as usize;
|
|
||||||
|
|
||||||
let pos0 = vertexes[idx0].position;
|
|
||||||
let pos1 = vertexes[idx1].position;
|
|
||||||
let pos2 = vertexes[idx2].position;
|
|
||||||
|
|
||||||
let side1 = pos1 - pos0;
|
|
||||||
let side2 = pos2 - pos0;
|
|
||||||
let normal = side1.cross(side2);
|
|
||||||
|
|
||||||
let normal_vec4 = mq::vec4(normal.x, normal.y, normal.z, 0.0);
|
|
||||||
|
|
||||||
vertexes[idx0].normal = vertexes[idx0].normal + normal_vec4;
|
|
||||||
vertexes[idx1].normal = vertexes[idx1].normal + normal_vec4;
|
|
||||||
vertexes[idx2].normal = vertexes[idx2].normal + normal_vec4;
|
|
||||||
}
|
|
||||||
|
|
||||||
for v in vertexes.iter_mut() {
|
|
||||||
v.normal.z = 0.0;
|
|
||||||
let normalized = v.normal.normalize();
|
|
||||||
v.normal = normalized;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
pub fn draw_cuboid(center: mq::Vec3, size: mq::Vec3, color: mq::Color) {
|
|
||||||
use mq::{Vec2, Vec3, Vertex};
|
|
||||||
let hs = size * 0.5;
|
|
||||||
let mut positions = [
|
|
||||||
Vec3::new(-hs.x, -hs.y, -hs.z),
|
|
||||||
Vec3::new(hs.x, -hs.y, -hs.z),
|
|
||||||
Vec3::new(hs.x, hs.y, -hs.z),
|
|
||||||
Vec3::new(-hs.x, hs.y, -hs.z),
|
|
||||||
Vec3::new(-hs.x, -hs.y, hs.z),
|
|
||||||
Vec3::new(hs.x, -hs.y, hs.z),
|
|
||||||
Vec3::new(hs.x, hs.y, hs.z),
|
|
||||||
Vec3::new(-hs.x, hs.y, hs.z),
|
|
||||||
];
|
|
||||||
for i in 0..positions.len() {
|
|
||||||
positions[i] += center;
|
|
||||||
}
|
|
||||||
|
|
||||||
let faces = [
|
|
||||||
([0, 1, 2, 3], Vec3::new(0.0, 0.0, -1.0)), // Back
|
|
||||||
([5, 4, 7, 6], Vec3::new(0.0, 0.0, 1.0)), // Front
|
|
||||||
([4, 0, 3, 7], Vec3::new(-1.0, 0.0, 0.0)), // Left
|
|
||||||
([1, 5, 6, 2], Vec3::new(1.0, 0.0, 0.0)), // Right
|
|
||||||
([3, 2, 6, 7], Vec3::new(0.0, 1.0, 0.0)), // Up
|
|
||||||
([4, 5, 1, 0], Vec3::new(0.0, -1.0, 0.0)), // Down
|
|
||||||
];
|
|
||||||
|
|
||||||
let uvs = [
|
|
||||||
Vec2::new(0.0, 0.0),
|
|
||||||
Vec2::new(1.0, 0.0),
|
|
||||||
Vec2::new(1.0, 1.0),
|
|
||||||
Vec2::new(0.0, 1.0),
|
|
||||||
];
|
|
||||||
|
|
||||||
let mut vertices = [Vertex {
|
|
||||||
position: mq::Vec3::ZERO,
|
|
||||||
uv: mq::Vec2::ZERO,
|
|
||||||
color: color.into(),
|
|
||||||
normal: mq::Vec4::ZERO,
|
|
||||||
}; 24];
|
|
||||||
|
|
||||||
let mut vi = 0;
|
|
||||||
for (face, normal) in faces.iter() {
|
|
||||||
for (j, &corner) in face.iter().enumerate() {
|
|
||||||
let pos = positions[corner];
|
|
||||||
vertices[vi] = Vertex {
|
|
||||||
position: mq::vec3(pos.x, pos.y, pos.z),
|
|
||||||
uv: mq::vec2(uvs[j].x, uvs[j].y),
|
|
||||||
color: color.into(),
|
|
||||||
normal: mq::vec4(normal.x, normal.y, normal.z, 0.0),
|
|
||||||
};
|
|
||||||
vi += 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut indices = [0u16; 36];
|
|
||||||
for i in 0..6 {
|
|
||||||
let base = (i * 4) as u16;
|
|
||||||
let offset = i * 6;
|
|
||||||
indices[offset + 0] = base;
|
|
||||||
indices[offset + 1] = base + 1;
|
|
||||||
indices[offset + 2] = base + 2;
|
|
||||||
indices[offset + 3] = base;
|
|
||||||
indices[offset + 4] = base + 2;
|
|
||||||
indices[offset + 5] = base + 3;
|
|
||||||
}
|
|
||||||
generate_normals_smooth(&mut vertices.into(), &indices);
|
|
||||||
|
|
||||||
unsafe {
|
|
||||||
mq::get_internal_gl()
|
|
||||||
.quad_gl
|
|
||||||
.draw_mode(mq::DrawMode::Triangles);
|
|
||||||
mq::get_internal_gl().quad_gl.geometry(&vertices, &indices);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,22 +0,0 @@
|
||||||
|
|
||||||
#version 330 core
|
|
||||||
|
|
||||||
in vec4 v_normal;
|
|
||||||
in vec4 color;
|
|
||||||
uniform int render_normals_bool;
|
|
||||||
|
|
||||||
out vec4 FragColor;
|
|
||||||
|
|
||||||
const float ambient_strenght = 0.3;
|
|
||||||
const float diffuse_strenght = 0.7;
|
|
||||||
|
|
||||||
void main() {
|
|
||||||
vec3 lightDir = vec3(1.0, 0.3, 0.2);
|
|
||||||
float diff = max(dot(normalize(vec3(v_normal.x, v_normal.y, v_normal.z)), normalize(lightDir)), 0) * diffuse_strenght;
|
|
||||||
if (render_normals_bool == 1) {
|
|
||||||
FragColor = vec4(v_normal);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
FragColor = color * (1 / 256.0) * (ambient_strenght + diff);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,17 +0,0 @@
|
||||||
|
|
||||||
#version 330 core
|
|
||||||
|
|
||||||
attribute vec3 position;
|
|
||||||
attribute vec4 color0;
|
|
||||||
attribute vec4 normal;
|
|
||||||
|
|
||||||
uniform mat4 Model;
|
|
||||||
uniform mat4 Projection;
|
|
||||||
|
|
||||||
out vec4 v_normal;
|
|
||||||
out vec4 color;
|
|
||||||
void main() {
|
|
||||||
color = color0;
|
|
||||||
v_normal = normal;
|
|
||||||
gl_Position = Projection * Model * vec4(position, 1.0);
|
|
||||||
}
|
|
||||||
Loading…
Reference in New Issue