Tiled Forward Rendering #5
|
@ -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,
|
||||||
|
}
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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!");
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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,12 +104,12 @@ 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) {
|
||||||
var negative_step = (2.0 * vec2<f32>(tile_id)) / vec2<f32>(tile_number);
|
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
|
// 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) {
|
||||||
|
|
Loading…
Reference in New Issue