render: get forward+ rendering working with multiple light sources

This commit is contained in:
SeanOMik 2024-03-19 20:26:15 -04:00
parent 014abcf7e6
commit 834a864544
Signed by: SeanOMik
GPG Key ID: FEC9E2FC15235964
4 changed files with 31 additions and 33 deletions

View File

@ -215,15 +215,12 @@ pub(crate) enum LightType {
#[repr(C)] #[repr(C)]
#[derive(Default, Debug, Copy, Clone, bytemuck::Pod, bytemuck::Zeroable)] #[derive(Default, Debug, Copy, Clone, bytemuck::Pod, bytemuck::Zeroable)]
pub(crate) struct LightUniform { pub(crate) struct LightUniform {
pub light_type: u32, // LightType
pub enabled: u32, // bool
pub _padding: [u32; 2],
pub position: glam::Vec3, pub position: glam::Vec3,
pub _padding2: u32, pub light_type: u32, // LightType
pub direction: glam::Vec3, pub direction: glam::Vec3,
pub _padding3: u32, pub enabled: u32, // bool
pub color: glam::Vec3, pub color: glam::Vec3,
// no padding is needed here since cutoff acts as the padding // no padding is needed here since range acts as the padding
// that would usually be needed for the vec3 // that would usually be needed for the vec3
pub range: f32, pub range: f32,
@ -240,11 +237,8 @@ impl LightUniform {
Self { Self {
light_type: LightType::Point as u32, light_type: LightType::Point as u32,
enabled: true as u32, // TODO enabled: true as u32, // TODO
_padding: [0; 2],
position: transform.translation, position: transform.translation,
_padding2: 0,
direction: transform.forward(), direction: transform.forward(),
_padding3: 0,
color: light.color, color: light.color,
range: 1.5, range: 1.5,
@ -261,11 +255,8 @@ impl LightUniform {
Self { Self {
light_type: LightType::Directional as u32, light_type: LightType::Directional as u32,
enabled: true as u32, // TODO: take from component enabled: true as u32, // TODO: take from component
_padding: [0; 2],
position: transform.translation, position: transform.translation,
_padding2: 0,
direction: transform.forward(), direction: transform.forward(),
_padding3: 0,
color: light.color, color: light.color,
range: 0.0, range: 0.0,

View File

@ -24,9 +24,10 @@ pub(crate) struct LightCullCompute {
} }
impl LightCullCompute { impl LightCullCompute {
fn create_grid(device: &wgpu::Device, screen_size: PhysicalSize<u32>, workgroup_size: glam::UVec2) -> LightIndicesGridBuffer { /// Create the LightIndiciesGridBuffer object
fn create_grid(device: &wgpu::Device, workgroup_size: glam::UVec2) -> LightIndicesGridBuffer {
let mut contents = Vec::<u8>::new(); let mut contents = Vec::<u8>::new();
let contents_len = workgroup_size.x * workgroup_size.y * mem::size_of::<u8>() as u32; let contents_len = workgroup_size.x * workgroup_size.y * 200 * mem::size_of::<u32>() as u32;
contents.resize(contents_len as _, 0); contents.resize(contents_len as _, 0);
let light_indices_buffer = device.create_buffer_init(&wgpu::util::BufferInitDescriptor { let light_indices_buffer = device.create_buffer_init(&wgpu::util::BufferInitDescriptor {
@ -167,7 +168,7 @@ impl LightCullCompute {
}); });
let workgroup_size = glam::UVec2::new((screen_size.width as f32 / 16.0).ceil() as u32, (screen_size.height as f32 / 16.0).ceil() as u32); let workgroup_size = glam::UVec2::new((screen_size.width as f32 / 16.0).ceil() as u32, (screen_size.height as f32 / 16.0).ceil() as u32);
let light_grid = Self::create_grid(&device, screen_size, workgroup_size); let light_grid = Self::create_grid(&device, workgroup_size);
let depth_tex_pair = depth_texture.create_bind_group(&device); let depth_tex_pair = depth_texture.create_bind_group(&device);
@ -228,5 +229,10 @@ impl LightCullCompute {
} }
self.queue.submit(std::iter::once(encoder.finish())); self.queue.submit(std::iter::once(encoder.finish()));
self.device.poll(wgpu::Maintain::Wait); self.device.poll(wgpu::Maintain::Wait);
self.cleanup();
}
pub fn cleanup(&mut self) {
self.queue.write_buffer(&self.light_indices_grid.index_counter_buffer, 0, &bytemuck::cast_slice(&[0]));
} }
} }

View File

@ -27,11 +27,10 @@ struct CameraUniform {
}; };
struct Light { struct Light {
light_ty: u32,
enabled: u32,
position: vec3<f32>, position: vec3<f32>,
light_ty: u32,
direction: vec3<f32>, direction: vec3<f32>,
enabled: u32,
color: vec3<f32>, color: vec3<f32>,
range: f32, range: f32,

View File

@ -14,11 +14,10 @@ struct CameraUniform {
}; };
struct Light { struct Light {
light_ty: u32,
enabled: u32,
position: vec3<f32>, position: vec3<f32>,
light_ty: u32,
direction: vec3<f32>, direction: vec3<f32>,
enabled: u32,
color: vec3<f32>, color: vec3<f32>,
range: f32, range: f32,
@ -148,23 +147,26 @@ fn cs_main(
let light_index = i; let light_index = i;
let light = u_lights.data[light_index]; let light = u_lights.data[light_index];
let position_vec4 = u_camera.view * vec4<f32>(light.position, 1.0);
let position = position_vec4.xyz;
let radius = light.range;
if (light.light_ty == LIGHT_TY_DIRECTIONAL) { if (light.enabled == 1u) {
add_light(light_index); let position_vec4 = u_camera.view * vec4<f32>(light.position, 1.0);
} else if (light.light_ty == LIGHT_TY_POINT let position = position_vec4.xyz;
&& sphere_inside_frustrum(wg_frustum_planes, position, radius)) { let radius = light.range;
// TODO: add the light to the transparent geometry list
add_light(light_index); if (light.light_ty == LIGHT_TY_DIRECTIONAL) {
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
if (!sphere_inside_plane(position, radius, wg_frustum_planes[4])) { add_light(light_index);
if (!sphere_inside_plane(position, radius, wg_frustum_planes[4])) {
}
} }
// TODO: spotlights
} }
// TODO: spotlights
} }
workgroupBarrier(); workgroupBarrier();