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)]
#[derive(Default, Debug, Copy, Clone, bytemuck::Pod, bytemuck::Zeroable)]
pub(crate) struct LightUniform {
pub light_type: u32, // LightType
pub enabled: u32, // bool
pub _padding: [u32; 2],
pub position: glam::Vec3,
pub _padding2: u32,
pub light_type: u32, // LightType
pub direction: glam::Vec3,
pub _padding3: u32,
pub enabled: u32, // bool
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
pub range: f32,
@ -240,11 +237,8 @@ impl LightUniform {
Self {
light_type: LightType::Point as u32,
enabled: true as u32, // TODO
_padding: [0; 2],
position: transform.translation,
_padding2: 0,
direction: transform.forward(),
_padding3: 0,
color: light.color,
range: 1.5,
@ -261,11 +255,8 @@ impl LightUniform {
Self {
light_type: LightType::Directional as u32,
enabled: true as u32, // TODO: take from component
_padding: [0; 2],
position: transform.translation,
_padding2: 0,
direction: transform.forward(),
_padding3: 0,
color: light.color,
range: 0.0,

View File

@ -24,9 +24,10 @@ pub(crate) struct 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 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);
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 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);
@ -228,5 +229,10 @@ impl LightCullCompute {
}
self.queue.submit(std::iter::once(encoder.finish()));
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 {
light_ty: u32,
enabled: u32,
position: vec3<f32>,
light_ty: u32,
direction: vec3<f32>,
enabled: u32,
color: vec3<f32>,
range: f32,

View File

@ -14,11 +14,10 @@ struct CameraUniform {
};
struct Light {
light_ty: u32,
enabled: u32,
position: vec3<f32>,
light_ty: u32,
direction: vec3<f32>,
enabled: u32,
color: vec3<f32>,
range: f32,
@ -148,23 +147,26 @@ fn cs_main(
let light_index = i;
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) {
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 (light.enabled == 1u) {
let position_vec4 = u_camera.view * vec4<f32>(light.position, 1.0);
let position = position_vec4.xyz;
let radius = light.range;
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();