Skip to content

Commit

Permalink
cascade rough implementation system
Browse files Browse the repository at this point in the history
  • Loading branch information
KDahir247 committed Jan 15, 2023
1 parent 2d20e1e commit d167f04
Show file tree
Hide file tree
Showing 18 changed files with 291 additions and 8 deletions.
2 changes: 1 addition & 1 deletion crates/mani/fabled_math/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,4 @@ name = "fabled_math"
version = "0.1.0"
edition = "2018"

[dependencies]
[dependencies]
10 changes: 6 additions & 4 deletions crates/mani/fabled_render/src/camera/calculation/camera.rs
Original file line number Diff line number Diff line change
Expand Up @@ -65,9 +65,11 @@ pub fn un_project(
}

// todo this is +X=RIGHT, +Y=UP, +Z=BACK we want +Z=FORWARD.
pub fn compute_look_at_matrix(translation: Vector3, rotation: Quaternion) -> Matrix4x4 {
const Y_VEC3: Vector3 = Vector3::UP;

pub fn compute_look_at_matrix(
translation: Vector3,
up_vector: Vector3,
rotation: Quaternion,
) -> Matrix4x4 {
let forward = forward_vec3(rotation);

let neg_translation = -translation;
Expand All @@ -76,7 +78,7 @@ pub fn compute_look_at_matrix(translation: Vector3, rotation: Quaternion) -> Mat
value: normalize(-forward.value),
};
let x_axis = Vector3 {
value: normalize(cross(Y_VEC3.value, z_axis.value)),
value: normalize(cross(up_vector.value, z_axis.value)),
};
let y_axis = Vector3 {
value: cross(z_axis.value, x_axis.value),
Expand Down
25 changes: 25 additions & 0 deletions crates/mani/fabled_render/src/camera/component/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ pub use aperture::*;
pub use aspect_ratio::*;
pub use clipping_plane::*;
pub use f_stop::*;
use fabled_component::{Unique, Untracked};
use fabled_math::Matrix4x4;
pub use fov::*;
pub use iso_speed::*;
pub use oblique::*;
Expand Down Expand Up @@ -30,3 +32,26 @@ mod viewport;
// Orthographic
// FStop -> ISO Speed -> Shutter -> ClippingPlane -> Viewport -> Orientation ->
// Oblique (optional)


// The active camera's projection matrix.
// This is a resource since there can only be one camera rendered to a screen
#[derive(Copy, Clone, PartialEq)]
pub struct RenderProjection {
pub projection_matrix: Matrix4x4,
}

impl Unique for RenderProjection {
type Tracking = Untracked;
}

// The active camera's view matrix
// This is a resource since there can only be one camera rendered to a screen.
#[derive(Copy, Clone, PartialEq)]
pub struct RenderView {
pub view_matrix: Matrix4x4,
}

impl Unique for RenderView {
type Tracking = Untracked;
}
26 changes: 26 additions & 0 deletions crates/mani/fabled_render/src/light/component/csm.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
use fabled_component::{Component, Modification, Unique};
use fabled_math::{Matrix4x4, Vector3, Vector4};


// There will only be one Cascade map that can be active at any given time.
#[derive(Copy, Clone, PartialEq)]
pub struct CascadeSplit {
pub splits: Vector4,
pub lambda: f32,
}

impl Unique for CascadeSplit {
type Tracking = Modification;
}


#[derive(Copy, Clone, PartialEq)]
pub struct CascadeFrustum {
pub center: [Vector3; 4],
pub min_extent: [Vector3; 4],
pub max_extent: [Vector3; 4],
}

impl Unique for CascadeFrustum {
type Tracking = Modification;
}
2 changes: 2 additions & 0 deletions crates/mani/fabled_render/src/light/component/mod.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
mod appearance;
mod attenuation;
mod csm;
mod ies_profile;
mod light_caster;
mod light_channel;
Expand All @@ -12,6 +13,7 @@ mod sun_light;

pub use appearance::*;
pub use attenuation::*;
pub use csm::*;
pub use ies_profile::*;
pub use light_caster::*;
pub use light_channel::*;
Expand Down
5 changes: 3 additions & 2 deletions crates/mani/fabled_render/src/light/mod.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
pub use component::*;
pub use constant::*;
pub use container::*;
pub use contract::*;
pub use conversion::*;
pub use ext::*;
pub use contract::*;

mod component;
mod constant;
mod container;
mod contract;
mod conversion;
mod ext;
mod contract;
4 changes: 3 additions & 1 deletion crates/mani/fabled_system/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,10 @@ edition = "2018"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
shipyard = {version = "0.5.0", features = ["thread_local", "parallel"]}
shipyard = {version = "0.6.2", features = ["thread_local", "parallel"]}
fabled_transform = {path = "../fabled_transform", version = "*"}
fabled_render = {path = "../fabled_render", version = "*"}
fabled_math = {path = "../fabled_math", version = "*"}
rayon = {version = "1.5.1"}
bitflags = {version = "1.2.1"}
crunchy = {version = "0.2.2", features = ["default"]}
1 change: 1 addition & 0 deletions crates/mani/fabled_system/src/container/camera/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@

3 changes: 3 additions & 0 deletions crates/mani/fabled_system/src/container/lighting/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
mod csm_view;

pub use csm_view::*;
4 changes: 4 additions & 0 deletions crates/mani/fabled_system/src/container/mod.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
mod camera;
mod lighting;
mod world_flag;

pub use camera::*;
pub use lighting::*;
pub use world_flag::*;
1 change: 1 addition & 0 deletions crates/mani/fabled_system/src/startup/camera/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@

10 changes: 10 additions & 0 deletions crates/mani/fabled_system/src/startup/lighting/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
use fabled_render::light::CascadeSplit;


pub fn construct_cascade_resource(primary_world: &shipyard::World) {
primary_world.add_unique(CascadeSplit {
splits: Default::default(),
});

// add the rest of the cascade parameter.
}
4 changes: 4 additions & 0 deletions crates/mani/fabled_system/src/startup/mod.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
mod entity;
mod lighting;
mod world;
mod camera;

pub use entity::*;
pub use lighting::*;
pub use camera::*;
pub use world::*;
Empty file.
Original file line number Diff line number Diff line change
@@ -0,0 +1,197 @@
use crate::PerspectiveCameraViewMut;
use fabled_math::matrix4x4_math::inverse_mat4;
use fabled_math::vector_math::{length, normalize, pow, round};
use fabled_math::{from_euler_quat, EulerOrder, Matrix4x4, Swizzles4, Vector3, Vector4};
use fabled_render::camera::{
compute_look_at_matrix, compute_orthographic_matrix, compute_perspective_matrix, AspectRatio,
ClippingPlane, Fov, RenderProjection, RenderView,
};
use fabled_render::light::{CascadeFrustum, CascadeSplit};
use fabled_transform::{Rotation, Translation};
use shipyard::{
EntitiesViewMut, IntoIter, IntoWithId, IntoWorkload, UniqueView, UniqueViewMut, View, ViewMut,
Workload,
};

const MAX_CASCADE_SIZE: usize = 4;

fn compute_csm_split_system(
plane: View<ClippingPlane>,
mut csm_split: UniqueViewMut<CascadeSplit>,
) {
for clipping_plane in plane.iter() {
let clipping_range = clipping_plane.far - clipping_plane.near;

let ratio = clipping_plane.far / clipping_plane.near;
let rcp_clipping_range = 1.0 / clipping_range;

let lambda = Vector4::broadcast(csm_split.lambda);

// 4 Cascades
let p = Vector4::set(0.25, 0.5, 0.75, 1.0);

let p_pow = Vector4 {
value: pow(Vector4::broadcast(ratio).value, p.value),
};

let p_mul_range = p * clipping_range;
let log = p_pow * clipping_plane.near;

let uniform = p_mul_range + clipping_plane.near;
let log_min_uniform = log - uniform;
let d = lambda * log_min_uniform + uniform;

// X = split_1, Y = split_2, Z = split_3, W = split_4
let cascade_split = (d - clipping_plane.near) * rcp_clipping_range;

csm_split.splits = cascade_split;
}
}

fn compute_csm_frustum_system(
cascade_split: UniqueView<CascadeSplit>,
projection: UniqueView<RenderProjection>,
view: UniqueView<RenderView>,
mut frustum: UniqueViewMut<CascadeFrustum>,
) {
let inverse_view_projection = inverse_mat4(view.view_matrix * projection.projection_matrix);

for cascade_index in 0..MAX_CASCADE_SIZE {
let mut frustum_corner_ws = [
Vector3::set(-1.0, 1.0, 0.0),
Vector3::set(1.0, 1.0, 0.0),
Vector3::set(1.0, -1.0, 0.0),
Vector3::set(-1.0, -1.0, 0.0),
Vector3::set(-1.0, 1.0, 1.0),
Vector3::set(1.0, 1.0, 1.0),
Vector3::set(1.0, -1.0, 1.0),
Vector3::set(-1.0, -1.0, 1.0),
];

let prev_split_distance = if cascade_index == 0 {
0.0
} else {
cascade_split.splits.value[cascade_index - 1]
};

let current_split_distance = cascade_split.splits.value[cascade_index];

for index in 0..8 {
// temp solution
let inverse_point = inverse_view_projection
* Vector4::set(
frustum_corner_ws[index].x(),
frustum_corner_ws[index].y(),
frustum_corner_ws[index].z(),
1.0,
);

frustum_corner_ws[index] = inverse_point.xyz() / inverse_point.w();
}


for index in 0..4 {
let corner_ray = frustum_corner_ws[index + 4] - frustum_corner_ws[index];
let near_corner_ray = corner_ray * prev_split_distance;
let far_corner_ray = corner_ray * current_split_distance;
frustum_corner_ws[index + 4] = frustum_corner_ws[i] + far_corner_ray;
frustum_corner_ws[i] = frustum_corner_ws[index] + near_corner_ray;
}

let mut frustum_center = Vector3::ZERO;

for index in 0..8 {
frustum_center += frustum_corner_ws[index];
}
frustum_center *= 0.125;

let mut sphere_radius = 0.0f32;

for index in 0..8 {
let dist = length((frustum_corner_ws[index] - frustum_center).value);
sphere_radius = sphere_radius.max(dist);
}

sphere_radius = (sphere_radius * 16.0).ceil() * 0.0625;

let max_extent = Vector3::broadcast(sphere_radius);
let min_extent = -max_extent;

// assignment
frustum.max_extent[cascade_index] = max_extent;
frustum.min_extent[cascade_index] = min_extent;
frustum.center[cascade_index] = frustum_center;
}
}


fn compute_csm_shadow_matrix_system(
cascade_frustum: UniqueViewMut<CascadeFrustum>,
mut projection: UniqueView<RenderProjection>,
mut view: UniqueView<RenderView>,
) {
for cascade_index in 0..MAX_CASCADE_SIZE {
let maximum_extent = cascade_frustum.max_extent[cascade_index];
let minimum_extent = cascade_frustum.min_extent[cascade_index];

let cascade_extent = maximum_extent - minimum_extent;

let orthographic_rect = Vector4::set(
maximum_extent.x(),
minimum_extent.x(),
maximum_extent.y(),
minimum_extent.y(),
);

let mut light_orthographic_matrix = compute_orthographic_matrix(
orthographic_rect,
ClippingPlane::new(cascade_extent.z(), 0.0),
);

// todo: khal the direction is hard coded.
let light_direction = cascade_frustum.center[cascade_index]
- Vector3 {
value: normalize(Vector3::set(-0.1, -0.5, 0.0).value),
} * -maximum_extent.z();

let light_view_matrix = compute_look_at_matrix(
cascade_frustum.center[cascade_index],
Vector3::UP,
from_euler_quat(light_direction, EulerOrder::XYZ),
);

let shadow_matrix = light_orthographic_matrix * light_view_matrix;

let shadow_origin = (shadow_matrix * Vector4::W) * (2048.0 * 0.5);

let rounded_origin = Vector4 {
value: round(shadow_origin.value),
};

let mut round_offset = rounded_origin - shadow_origin;

round_offset = round_offset * 2.0 / 2048.0;

let shadow_w = shadow_matrix.column_w + round_offset;

light_orthographic_matrix = Matrix4x4::set(
light_orthographic_matrix.column_x,
light_orthographic_matrix.column_y,
light_orthographic_matrix.column_z,
shadow_w,
);

projection.projection_matrix = light_orthographic_matrix;
view.view_matrix = light_view_matrix;
}
}


pub fn construct_cascade_shadow_map() -> Workload {
(
compute_csm_split_system,
compute_csm_frustum_system,
compute_csm_shadow_matrix_system,
)
.into_workload()
}
3 changes: 3 additions & 0 deletions crates/mani/fabled_system/src/system/lighting/mod.rs
Original file line number Diff line number Diff line change
@@ -1,2 +1,5 @@
mod chromatic_adaption_system;
mod construct_cascade_system;

pub use chromatic_adaption_system::*;
pub use construct_cascade_system::*;
2 changes: 2 additions & 0 deletions crates/mani/fabled_system/src/system/mod.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
mod color;
mod lighting;
mod transform;

pub use color::*;
pub use transform::*;

0 comments on commit d167f04

Please sign in to comment.