render: add some fields to the camera uniform

This commit is contained in:
SeanOMik 2024-03-17 16:07:24 -04:00
parent 5c1ce809ff
commit 76ec9606ec
Signed by: SeanOMik
GPG Key ID: FEC9E2FC15235964
4 changed files with 52 additions and 30 deletions

View File

@ -39,9 +39,11 @@ impl Projection {
#[derive(Copy, Clone, bytemuck::Pod, bytemuck::Zeroable)] #[derive(Copy, Clone, bytemuck::Pod, bytemuck::Zeroable)]
pub struct CameraUniform { pub struct CameraUniform {
/// The view matrix of the camera /// The view matrix of the camera
pub view_mat: glam::Mat4, pub view: glam::Mat4,
/// The inverse of the projection matrix of the camera
pub inverse_projection: glam::Mat4,
/// The view projection matrix /// The view projection matrix
pub view_proj: glam::Mat4, pub view_projection: glam::Mat4,
/// The position of the camera /// The position of the camera
pub position: glam::Vec3, pub position: glam::Vec3,
_padding: u32, _padding: u32,
@ -51,8 +53,9 @@ pub struct CameraUniform {
impl Default for CameraUniform { impl Default for CameraUniform {
fn default() -> Self { fn default() -> Self {
Self { Self {
view_mat: glam::Mat4::IDENTITY, view: glam::Mat4::IDENTITY,
view_proj: glam::Mat4::IDENTITY, inverse_projection: glam::Mat4::IDENTITY,
view_projection: glam::Mat4::IDENTITY,
position: Default::default(), position: Default::default(),
_padding: 0, _padding: 0,
} }
@ -60,10 +63,11 @@ impl Default for CameraUniform {
} }
impl CameraUniform { impl CameraUniform {
pub fn new(view_mat: glam::Mat4, view_proj: glam::Mat4, position: glam::Vec3) -> Self { pub fn new(view: glam::Mat4, inverse_projection: glam::Mat4, view_projection: glam::Mat4, position: glam::Vec3) -> Self {
Self { Self {
view_mat, view,
view_proj, inverse_projection,
view_projection,
position, position,
_padding: 0 _padding: 0
} }
@ -101,7 +105,7 @@ impl RenderCamera {
/// ///
/// Returns: A tuple with the view projection as the first element, and the /// Returns: A tuple with the view projection as the first element, and the
/// view matrix as the second. /// view matrix as the second.
pub fn calc_view_projection(&mut self, camera: &CameraComponent) -> (&glam::Mat4, glam::Mat4) { pub fn calc_view_projection(&mut self, camera: &CameraComponent) -> CameraUniform {
let position = camera.transform.translation; let position = camera.transform.translation;
let forward = camera.transform.forward(); let forward = camera.transform.forward();
let up = camera.transform.up(); let up = camera.transform.up();
@ -117,7 +121,15 @@ impl RenderCamera {
let proj = glam::Mat4::perspective_rh_gl(camera.fov.to_radians(), self.aspect, self.znear, self.zfar); let proj = glam::Mat4::perspective_rh_gl(camera.fov.to_radians(), self.aspect, self.znear, self.zfar);
self.view_proj = OPENGL_TO_WGPU_MATRIX * proj * view; self.view_proj = OPENGL_TO_WGPU_MATRIX * proj * view;
(&self.view_proj, view) //(&self.view_proj, view)
CameraUniform {
view,
inverse_projection: proj.inverse(),
view_projection: self.view_proj,
position,
_padding: 0,
}
}, },
CameraProjectionMode::Orthographic => { CameraProjectionMode::Orthographic => {
let target = camera.transform.rotation * glam::Vec3::new(0.0, 0.0, -1.0); let target = camera.transform.rotation * glam::Vec3::new(0.0, 0.0, -1.0);
@ -132,7 +144,14 @@ impl RenderCamera {
let proj = glam::Mat4::orthographic_rh_gl(-size_x, size_x, -size_y, size_y, self.znear, self.zfar); let proj = glam::Mat4::orthographic_rh_gl(-size_x, size_x, -size_y, size_y, self.znear, self.zfar);
self.view_proj = OPENGL_TO_WGPU_MATRIX * proj; self.view_proj = OPENGL_TO_WGPU_MATRIX * proj;
(&self.view_proj, view)
CameraUniform {
view,
inverse_projection: proj.inverse(),
view_projection: self.view_proj,
position,
_padding: 0,
}
}, },
} }
} }

View File

@ -504,9 +504,9 @@ impl Renderer for BasicRenderer {
} }
if let Some(camera) = main_world.view_iter::<&mut CameraComponent>().next() { if let Some(camera) = main_world.view_iter::<&mut CameraComponent>().next() {
let (view_proj, view_mat) = self.inuse_camera.calc_view_projection(&camera); let uniform = self.inuse_camera.calc_view_projection(&camera);
let pos = camera.transform.translation; //let pos = camera.transform.translation;
let uniform = CameraUniform::new(view_mat, *view_proj, pos); //let uniform = CameraUniform::new(view_mat, *view_proj, pos);
self.camera_buffer.write_buffer(&self.queue, 0, &[uniform]); self.camera_buffer.write_buffer(&self.queue, 0, &[uniform]);
} else { } else {
warn!("Missing camera!"); warn!("Missing camera!");

View File

@ -20,9 +20,10 @@ struct VertexOutput {
} }
struct CameraUniform { struct CameraUniform {
view_mat: mat4x4<f32>, view: mat4x4<f32>,
view_proj: mat4x4<f32>, projection: mat4x4<f32>,
view_pos: vec3<f32>, view_projection: mat4x4<f32>,
position: vec3<f32>,
}; };
struct Light { struct Light {
@ -63,7 +64,7 @@ fn vs_main(
var out: VertexOutput; var out: VertexOutput;
out.tex_coords = model.tex_coords; out.tex_coords = model.tex_coords;
out.clip_position = u_camera.view_proj * u_model_transform * vec4<f32>(model.position, 1.0); out.clip_position = u_camera.view_projection * u_model_transform * vec4<f32>(model.position, 1.0);
// the normal mat is actually only a mat3x3, but there's a bug in wgpu: https://github.com/gfx-rs/wgpu-rs/issues/36 // the normal mat is actually only a mat3x3, but there's a bug in wgpu: https://github.com/gfx-rs/wgpu-rs/issues/36
let normal_mat = mat3x3(u_model_normal_matrix[0].xyz, u_model_normal_matrix[1].xyz, u_model_normal_matrix[2].xyz); let normal_mat = mat3x3(u_model_normal_matrix[0].xyz, u_model_normal_matrix[1].xyz, u_model_normal_matrix[2].xyz);
@ -174,7 +175,7 @@ fn debug_grid(in: VertexOutput) -> vec4<f32> {
fn blinn_phong_dir_light(world_pos: vec3<f32>, world_norm: vec3<f32>, dir_light: Light, material: Material, specular_factor: vec3<f32>) -> vec3<f32> { fn blinn_phong_dir_light(world_pos: vec3<f32>, world_norm: vec3<f32>, dir_light: Light, material: Material, specular_factor: vec3<f32>) -> vec3<f32> {
let light_color = dir_light.color.xyz; let light_color = dir_light.color.xyz;
let camera_view_pos = u_camera.view_pos.xyz; let camera_view_pos = u_camera.position;
//// Ambient light //// //// Ambient light ////
var ambient_color = light_color * material.ambient.xyz * material.diffuse.xyz; var ambient_color = light_color * material.ambient.xyz * material.diffuse.xyz;
@ -204,7 +205,7 @@ fn blinn_phong_dir_light(world_pos: vec3<f32>, world_norm: vec3<f32>, dir_light:
fn blinn_phong_point_light(world_pos: vec3<f32>, world_norm: vec3<f32>, point_light: Light, material: Material, specular_factor: vec3<f32>) -> vec3<f32> { fn blinn_phong_point_light(world_pos: vec3<f32>, world_norm: vec3<f32>, point_light: Light, material: Material, specular_factor: vec3<f32>) -> vec3<f32> {
let light_color = point_light.color.xyz; let light_color = point_light.color.xyz;
let light_pos = point_light.position.xyz; let light_pos = point_light.position.xyz;
let camera_view_pos = u_camera.view_pos.xyz; let camera_view_pos = u_camera.position;
//// Ambient light //// //// Ambient light ////
var ambient_color = light_color * material.ambient.xyz * material.diffuse.xyz; var ambient_color = light_color * material.ambient.xyz * material.diffuse.xyz;

View File

@ -14,9 +14,10 @@ const LIGHT_TY_SPOT = 2u;
// local_invocation_index // local_invocation_index
struct CameraUniform { struct CameraUniform {
view_mat: mat4x4<f32>, view: mat4x4<f32>,
view_proj: mat4x4<f32>, projection: mat4x4<f32>,
view_pos: vec3<f32>, view_projection: mat4x4<f32>,
position: vec3<f32>,
}; };
struct Light { struct Light {
@ -103,11 +104,11 @@ fn cs_main(
atomicMin(&wg_min_depth, depth_uint); atomicMin(&wg_min_depth, depth_uint);
atomicMax(&wg_max_depth, depth_uint); atomicMax(&wg_max_depth, depth_uint);
workgroupBarrier();
// convert them back into floats // convert them back into floats
var min_depth: f32 = bitcast<f32>(wg_min_depth); var min_depth: f32 = bitcast<f32>(wg_min_depth);
var max_depth: f32 = bitcast<f32>(wg_max_depth); var max_depth: f32 = bitcast<f32>(wg_max_depth);
workgroupBarrier();
// Create the frustum planes that will be used for this time // Create the frustum planes that will be used for this time
if (local_invocation_index == 0u) { if (local_invocation_index == 0u) {
@ -124,14 +125,14 @@ fn cs_main(
// convert the side and top planes from clip to view space // convert the side and top planes from clip to view space
for (var i = 0u; i < 4u; i++) { for (var i = 0u; i < 4u; i++) {
wg_frustum_planes[i] *= u_camera.view_proj; wg_frustum_planes[i] *= u_camera.view_projection;
wg_frustum_planes[i] /= length(wg_frustum_planes[i].xyz); wg_frustum_planes[i] /= length(wg_frustum_planes[i].xyz);
} }
// convert near and far planes from clip to view space // convert near and far planes from clip to view space
wg_frustum_planes[4] *= u_camera.view_mat; wg_frustum_planes[4] *= u_camera.view;
wg_frustum_planes[4] /= length(wg_frustum_planes[4].xyz); wg_frustum_planes[4] /= length(wg_frustum_planes[4].xyz);
wg_frustum_planes[5] *= u_camera.view_mat; wg_frustum_planes[5] *= u_camera.view;
wg_frustum_planes[5] /= length(wg_frustum_planes[5].xyz); wg_frustum_planes[5] /= length(wg_frustum_planes[5].xyz);
} }
@ -148,7 +149,7 @@ fn cs_main(
// find the light index to check on this thread, make sure we're not trying to test // find the light index to check on this thread, make sure we're not trying to test
// for more lights than we have. // for more lights than we have.
var light_index = i * thread_count + local_invocation_index; var light_index = i * thread_count + local_invocation_index;
if (light_index > u_lights.light_count) { if (light_index >= u_lights.light_count) {
break; break;
} }
@ -157,14 +158,15 @@ fn cs_main(
var radius = light.range; var radius = light.range;
if (light.light_ty == LIGHT_TY_DIRECTIONAL) { if (light.light_ty == LIGHT_TY_DIRECTIONAL) {
add_light(light_index); //add_light(light_index);
} else if (light.light_ty == LIGHT_TY_POINT } else if (light.light_ty == LIGHT_TY_POINT
&& sphere_inside_frustrum(wg_frustum_planes, position, radius)) { && sphere_inside_frustrum(wg_frustum_planes, position, radius)) {
// TODO: add the light to the transparent geometry list // TODO: add the light to the transparent geometry list
add_light(light_index);
// TODO: spotlights // TODO: spotlights
if (!sphere_inside_plane(position, radius, wg_frustum_planes[4])) { if (!sphere_inside_plane(position, radius, wg_frustum_planes[4])) {
add_light(light_index);
/*var offset: u32 = wg_visible_light_count; /*var offset: u32 = wg_visible_light_count;
if (offset < MAX_TILE_VISIBLE_LIGHTS) { if (offset < MAX_TILE_VISIBLE_LIGHTS) {