Skip to content

Commit

Permalink
Added inverse matrices to camera data.
Browse files Browse the repository at this point in the history
  • Loading branch information
facundo-villa committed Feb 3, 2024
1 parent cd15779 commit f38e37d
Show file tree
Hide file tree
Showing 3 changed files with 120 additions and 10 deletions.
7 changes: 5 additions & 2 deletions assets/engine/shaders/ssao.comp
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,9 @@ struct Camera {
mat4 view_matrix;
mat4 projection_matrix;
mat4 view_projection;
mat4 inverse_view_matrix;
mat4 inverse_projection_matrix;
mat4 inverse_view_projection;
};

layout(set=0,binding=0,scalar) buffer readonly CameraBuffer {
Expand All @@ -84,7 +87,7 @@ vec3 get_view_position(vec2 uv) {
uv /= textureSize(depth, 0).xy;
float depth_value = texture(depth, uv).r;
vec4 clip_space = vec4(uv * 2.0 - 1.0, depth_value, 1.0);
vec4 view_space = inverse(camera.projection_matrix) * clip_space;
vec4 view_space = camera.inverse_projection_matrix * clip_space;
view_space /= view_space.w;
return view_space.xyz;
}
Expand All @@ -93,7 +96,7 @@ vec3 get_view_position(ivec2 coords) {
float depth_value = texelFetch(depth, coords, 0).r;
vec2 uv = (vec2(coords) + vec2(0.5)) / vec2(textureSize(depth, 0).xy);
vec4 clip_space = vec4(uv * 2.0 - 1.0, depth_value, 1.0);
vec4 view_space = inverse(camera.projection_matrix) * clip_space;
vec4 view_space = camera.inverse_projection_matrix * clip_space;
view_space /= view_space.w;
return view_space.xyz;
}
Expand Down
96 changes: 96 additions & 0 deletions src/math.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,46 @@ pub fn from_normal(normal: crate::Vector3) -> maths_rs::Mat4f {
))
}

/// Left handed row major 4x4 matrix inverse
pub fn inverse(m: maths_rs::Mat4f) -> maths_rs::Mat4f {
let mut inv = maths_rs::Mat4f::default();

inv[0] = m[5] * m[10] * m[15] - m[5] * m[11] * m[14] - m[9] * m[6] * m[15] + m[9] * m[7] * m[14] + m[13] * m[6] * m[11] - m[13] * m[7] * m[10];
inv[4] = -m[4] * m[10] * m[15] + m[4] * m[11] * m[14] + m[8] * m[6] * m[15] - m[8] * m[7] * m[14] - m[12] * m[6] * m[11] + m[12] * m[7] * m[10];
inv[8] = m[4] * m[9] * m[15] - m[4] * m[11] * m[13] - m[8] * m[5] * m[15] + m[8] * m[7] * m[13] + m[12] * m[5] * m[11] - m[12] * m[7] * m[9];
inv[12] = -m[4] * m[9] * m[14] + m[4] * m[10] * m[13] + m[8] * m[5] * m[14] - m[8] * m[6] * m[13] - m[12] * m[5] * m[10] + m[12] * m[6] * m[9];
inv[1] = -m[1] * m[10] * m[15] + m[1] * m[11] * m[14] + m[9] * m[2] * m[15] - m[9] * m[3] * m[14] - m[13] * m[2] * m[11] + m[13] * m[3] * m[10];
inv[5] = m[0] * m[10] * m[15] - m[0] * m[11] * m[14] - m[8] * m[2] * m[15] + m[8] * m[3] * m[14] + m[12] * m[2] * m[11] - m[12] * m[3] * m[10];
inv[9] = -m[0] * m[9] * m[15] + m[0] * m[11] * m[13] + m[8] * m[1] * m[15] - m[8] * m[3] * m[13] - m[12] * m[1] * m[11] + m[12] * m[3] * m[9];
inv[13] = m[0] * m[9] * m[14] - m[0] * m[10] * m[13] - m[8] * m[1] * m[14] + m[8] * m[2] * m[13] + m[12] * m[1] * m[10] - m[12] * m[2] * m[9];
inv[2] = m[1] * m[6] * m[15] - m[1] * m[7] * m[14] - m[5] * m[2] * m[15] + m[5] * m[3] * m[14] + m[13] * m[2] * m[7] - m[13] * m[3] * m[6];
inv[6] = -m[0] * m[6] * m[15] + m[0] * m[7] * m[14] + m[4] * m[2] * m[15] - m[4] * m[3] * m[14] - m[12] * m[2] * m[7] + m[12] * m[3] * m[6];
inv[10] = m[0] * m[5] * m[15] - m[0] * m[7] * m[13] - m[4] * m[1] * m[15] + m[4] * m[3] * m[13] + m[12] * m[1] * m[7] - m[12] * m[3] * m[5];
inv[14] = -m[0] * m[5] * m[14] + m[0] * m[6] * m[13] + m[4] * m[1] * m[14] - m[4] * m[2] * m[13] - m[12] * m[1] * m[6] + m[12] * m[2] * m[5];
inv[3] = -m[1] * m[6] * m[11] + m[1] * m[7] * m[10] + m[5] * m[2] * m[11] - m[5] * m[3] * m[10] - m[9] * m[2] * m[7] + m[9] * m[3] * m[6];
inv[7] = m[0] * m[6] * m[11] - m[0] * m[7] * m[10] - m[4] * m[2] * m[11] + m[4] * m[3] * m[10] + m[8] * m[2] * m[7] - m[8] * m[3] * m[6];
inv[11] = -m[0] * m[5] * m[11] + m[0] * m[7] * m[9] + m[4] * m[1] * m[11] - m[4] * m[3] * m[9] - m[8] * m[1] * m[7] + m[8] * m[3] * m[5];
inv[15] = m[0] * m[5] * m[10] - m[0] * m[6] * m[9] - m[4] * m[1] * m[10] + m[4] * m[2] * m[9] + m[8] * m[1] * m[6] - m[8] * m[2] * m[5];

let det = m[0] * inv[0] + m[1] * inv[4] + m[2] * inv[8] + m[3] * inv[12];

if det == 0f32 {
panic!("Matrix is not invertible");
}

let det = 1.0 / det;

for i in 0..16 {
inv[i] = inv[i] * det;
}

inv
}

#[cfg(test)]
mod tests {
use maths_rs::mat::{MatInverse, MatTranspose};

#[test]
fn test_from_normal() {
let value = super::from_normal(crate::Vector3::new(0f32, 0f32, 1f32));
Expand Down Expand Up @@ -96,4 +134,62 @@ mod tests {
maths_rs::Vec4f::from((0f32, 0f32, 0f32, 1f32)),
)));
}

#[test]
fn test_inverse_matrix() {
let value = maths_rs::Mat4f::from((
maths_rs::Vec4f::from((1f32, 0f32, 0f32, 0f32)),
maths_rs::Vec4f::from((0f32, 1f32, 0f32, 0f32)),
maths_rs::Vec4f::from((0f32, 0f32, 1f32, 0f32)),
maths_rs::Vec4f::from((0f32, 0f32, 0f32, 1f32)),
));
let value = super::inverse(value);
assert_eq!(value, maths_rs::Mat4f::from((
maths_rs::Vec4f::from((1f32, 0f32, 0f32, 0f32)),
maths_rs::Vec4f::from((0f32, 1f32, 0f32, 0f32)),
maths_rs::Vec4f::from((0f32, 0f32, 1f32, 0f32)),
maths_rs::Vec4f::from((0f32, 0f32, 0f32, 1f32)),
)));

let value = maths_rs::Mat4f::from((
maths_rs::Vec4f::from((1f32, 0f32, 0f32, 0f32)),
maths_rs::Vec4f::from((0f32, 2f32, 0f32, 0f32)),
maths_rs::Vec4f::from((0f32, 0f32, 3f32, 0f32)),
maths_rs::Vec4f::from((0f32, 0f32, 0f32, 1f32)),
));
let value = super::inverse(value);
assert_eq!(value, maths_rs::Mat4f::from((
maths_rs::Vec4f::from((1f32, 0f32, 0f32, 0f32)),
maths_rs::Vec4f::from((0f32, 0.5f32, 0f32, 0f32)),
maths_rs::Vec4f::from((0f32, 0f32, 1f32 / 3f32, 0f32)),
maths_rs::Vec4f::from((0f32, 0f32, 0f32, 1f32)),
)));

let nearly_equal = |a: f32, b: f32| (a - b).abs() < 0.0001f32;

let value = maths_rs::Mat4f::from((
maths_rs::Vec4f::from((1f32, 2f32, 3f32, 4f32)),
maths_rs::Vec4f::from((5f32, 1f32, 6f32, 7f32)),
maths_rs::Vec4f::from((8f32, 9f32, 1f32, 10f32)),
maths_rs::Vec4f::from((11f32, 12f32, 13f32, 1f32)),
));
let value = value.inverse();

assert!(nearly_equal(value[0], -212f32/507.0f32));
assert!(nearly_equal(value[1], 55f32/338f32));
assert!(nearly_equal(value[2], 157f32/3042f32));
assert!(nearly_equal(value[3], 53f32/3042f32));
assert!(nearly_equal(value[4], 103f32/507f32));
assert!(nearly_equal(value[5], -61f32/338f32));
assert!(nearly_equal(value[6], 127f32/3042f32));
assert!(nearly_equal(value[7], 101f32/3042f32));
assert!(nearly_equal(value[8], 79f32/507f32));
assert!(nearly_equal(value[9], 9f32/338f32));
assert!(nearly_equal(value[10], -257f32/3042f32));
assert!(nearly_equal(value[11], 107f32/3042f32));
assert!(nearly_equal(value[12], 23f32/169f32));
assert!(nearly_equal(value[13], 5f32/169f32));
assert!(nearly_equal(value[14], 5f32/169f32));
assert!(nearly_equal(value[15], -8f32/169f32));
}
}
27 changes: 19 additions & 8 deletions src/rendering/visibility_model/render_domain.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use std::rc::Rc;
use std::sync::RwLock;

use log::error;
use maths_rs::mat::{MatProjection, MatRotate3D};
use maths_rs::mat::{MatInverse, MatProjection, MatRotate3D};
use maths_rs::{prelude::MatTranslate, Mat4f};

use crate::core::entity::EntityBuilder;
Expand Down Expand Up @@ -216,7 +216,7 @@ impl VisibilityWorldRenderDomain {
diffuse = ghi_instance.create_image(Some("diffuse"), Extent::new(1920, 1080, 1), ghi::Formats::RGBA16(ghi::Encodings::UnsignedNormalized), None, ghi::Uses::RenderTarget | ghi::Uses::Storage | ghi::Uses::TransferDestination, ghi::DeviceAccesses::GpuRead, ghi::UseCases::DYNAMIC);
depth_target = ghi_instance.create_image(Some("depth_target"), Extent::new(1920, 1080, 1), ghi::Formats::Depth32, None, ghi::Uses::DepthStencil | ghi::Uses::Image, ghi::DeviceAccesses::GpuRead, ghi::UseCases::DYNAMIC);

camera_data_buffer_handle = ghi_instance.create_buffer(Some("Visibility Camera Data"), 16 * 4 * 4, ghi::Uses::Storage, ghi::DeviceAccesses::CpuWrite | ghi::DeviceAccesses::GpuRead, ghi::UseCases::DYNAMIC);
camera_data_buffer_handle = ghi_instance.create_buffer(Some("Visibility Camera Data"), std::mem::size_of::<[ShaderCameraData; 8]>(), ghi::Uses::Storage, ghi::DeviceAccesses::CpuWrite | ghi::DeviceAccesses::GpuRead, ghi::UseCases::DYNAMIC);

meshes_data_buffer = ghi_instance.create_buffer(Some("Visibility Meshes Data"), std::mem::size_of::<[ShaderInstanceData; MAX_INSTANCES]>(), ghi::Uses::Storage, ghi::DeviceAccesses::CpuWrite | ghi::DeviceAccesses::GpuRead, ghi::UseCases::STATIC);
meshlets_data_buffer = ghi_instance.create_buffer(Some("Visibility Meshlets Data"), std::mem::size_of::<[ShaderMeshletData; MAX_MESHLETS]>(), ghi::Uses::Storage, ghi::DeviceAccesses::CpuWrite | ghi::DeviceAccesses::GpuRead, ghi::UseCases::STATIC);
Expand Down Expand Up @@ -613,17 +613,14 @@ impl VisibilityWorldRenderDomain {

let view_projection_matrix = projection_matrix * view_matrix;

struct ShaderCameraData {
view_matrix: maths_rs::Mat4f,
projection_matrix: maths_rs::Mat4f,
view_projection_matrix: maths_rs::Mat4f,
}

let camera_data_reference = unsafe { (camera_data_buffer.as_mut_ptr() as *mut ShaderCameraData).as_mut().unwrap() };

camera_data_reference.view_matrix = view_matrix;
camera_data_reference.projection_matrix = projection_matrix;
camera_data_reference.view_projection_matrix = view_projection_matrix;
camera_data_reference.inverse_view_matrix = math::inverse(view_matrix);
camera_data_reference.inverse_projection_matrix = math::inverse(projection_matrix);
camera_data_reference.inverse_view_projection_matrix = math::inverse(view_projection_matrix);

command_buffer_recording.start_region("Visibility Render Model");

Expand Down Expand Up @@ -702,6 +699,17 @@ struct LightingData {
lights: [LightData; MAX_LIGHTS],
}

#[repr(C)]
#[derive(Copy, Clone)]
struct ShaderCameraData {
view_matrix: maths_rs::Mat4f,
projection_matrix: maths_rs::Mat4f,
view_projection_matrix: maths_rs::Mat4f,
inverse_view_matrix: maths_rs::Mat4f,
inverse_projection_matrix: maths_rs::Mat4f,
inverse_view_projection_matrix: maths_rs::Mat4f,
}

#[repr(C)]
#[derive(Copy, Clone)]
struct LightData {
Expand Down Expand Up @@ -1486,6 +1494,9 @@ pub const CAMERA_STRUCT_GLSL: &'static str = "struct Camera {
mat4 view;
mat4 projection_matrix;
mat4 view_projection;
mat4 inverse_view_matrix;
mat4 inverse_projection_matrix;
mat4 inverse_view_projection_matrix;
};";

pub const MESHLET_STRUCT_GLSL: &'static str = "struct Meshlet {
Expand Down

0 comments on commit f38e37d

Please sign in to comment.