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)]
|
||||
#[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,
|
||||
|
|
|
@ -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]));
|
||||
}
|
||||
}
|
|
@ -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,
|
||||
|
|
|
@ -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();
|
||||
|
|
Loading…
Reference in New Issue