render: get forward+ rendering working with multiple light sources
This commit is contained in:
parent
014abcf7e6
commit
834a864544
|
@ -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,
|
||||||
|
|
|
@ -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]));
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -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,
|
||||||
|
|
|
@ -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();
|
||||||
|
|
Loading…
Reference in New Issue