Tiled Forward Rendering #5

Merged
SeanOMik merged 15 commits from feature/tiled-forward-rendering into main 2024-03-23 14:38:43 +00:00
4 changed files with 52 additions and 30 deletions
Showing only changes of commit 76ec9606ec - Show all commits

View File

@ -39,9 +39,11 @@ impl Projection {
#[derive(Copy, Clone, bytemuck::Pod, bytemuck::Zeroable)]
pub struct CameraUniform {
/// 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
pub view_proj: glam::Mat4,
pub view_projection: glam::Mat4,
/// The position of the camera
pub position: glam::Vec3,
_padding: u32,
@ -51,8 +53,9 @@ pub struct CameraUniform {
impl Default for CameraUniform {
fn default() -> Self {
Self {
view_mat: glam::Mat4::IDENTITY,
view_proj: glam::Mat4::IDENTITY,
view: glam::Mat4::IDENTITY,
inverse_projection: glam::Mat4::IDENTITY,
view_projection: glam::Mat4::IDENTITY,
position: Default::default(),
_padding: 0,
}
@ -60,10 +63,11 @@ impl Default for 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 {
view_mat,
view_proj,
view,
inverse_projection,
view_projection,
position,
_padding: 0
}
@ -101,7 +105,7 @@ impl RenderCamera {
///
/// Returns: A tuple with the view projection as the first element, and the
/// 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 forward = camera.transform.forward();
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);
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 => {
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);
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() {
let (view_proj, view_mat) = self.inuse_camera.calc_view_projection(&camera);
let pos = camera.transform.translation;
let uniform = CameraUniform::new(view_mat, *view_proj, pos);
let uniform = self.inuse_camera.calc_view_projection(&camera);
//let pos = camera.transform.translation;
//let uniform = CameraUniform::new(view_mat, *view_proj, pos);
self.camera_buffer.write_buffer(&self.queue, 0, &[uniform]);
} else {
warn!("Missing camera!");

View File

@ -20,9 +20,10 @@ struct VertexOutput {
}
struct CameraUniform {
view_mat: mat4x4<f32>,
view_proj: mat4x4<f32>,
view_pos: vec3<f32>,
view: mat4x4<f32>,
projection: mat4x4<f32>,
view_projection: mat4x4<f32>,
position: vec3<f32>,
};
struct Light {
@ -63,7 +64,7 @@ fn vs_main(
var out: VertexOutput;
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
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> {
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 ////
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> {
let light_color = point_light.color.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 ////
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
struct CameraUniform {
view_mat: mat4x4<f32>,
view_proj: mat4x4<f32>,
view_pos: vec3<f32>,
view: mat4x4<f32>,
projection: mat4x4<f32>,
view_projection: mat4x4<f32>,
position: vec3<f32>,
};
struct Light {
@ -103,12 +104,12 @@ fn cs_main(
atomicMin(&wg_min_depth, depth_uint);
atomicMax(&wg_max_depth, depth_uint);
workgroupBarrier();
// convert them back into floats
var min_depth: f32 = bitcast<f32>(wg_min_depth);
var max_depth: f32 = bitcast<f32>(wg_max_depth);
workgroupBarrier();
// Create the frustum planes that will be used for this time
if (local_invocation_index == 0u) {
var negative_step = (2.0 * vec2<f32>(tile_id)) / vec2<f32>(tile_number);
@ -124,14 +125,14 @@ fn cs_main(
// convert the side and top planes from clip to view space
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);
}
// 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[5] *= u_camera.view_mat;
wg_frustum_planes[5] *= u_camera.view;
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
// for more lights than we have.
var light_index = i * thread_count + local_invocation_index;
if (light_index > u_lights.light_count) {
if (light_index >= u_lights.light_count) {
break;
}
@ -157,14 +158,15 @@ fn cs_main(
var radius = light.range;
if (light.light_ty == LIGHT_TY_DIRECTIONAL) {
add_light(light_index);
//add_light(light_index);
} else if (light.light_ty == LIGHT_TY_POINT
&& sphere_inside_frustrum(wg_frustum_planes, position, radius)) {
// TODO: add the light to the transparent geometry list
add_light(light_index);
// TODO: spotlights
if (!sphere_inside_plane(position, radius, wg_frustum_planes[4])) {
add_light(light_index);
/*var offset: u32 = wg_visible_light_count;
if (offset < MAX_TILE_VISIBLE_LIGHTS) {