Implemented lighting buffer resize and pre-calculated range by min_attenuation

This commit is contained in:
Verox001 2025-05-07 20:12:10 +02:00
parent 4371bb2749
commit e4e0c3078f
3 changed files with 44 additions and 20 deletions

View File

@ -52,16 +52,12 @@ pub async fn run() {
let sun_pos = bodies[0].position / 1.496e11; let sun_pos = bodies[0].position / 1.496e11;
state.light_manager.clear(); state.light_manager.clear();
state.light_manager.add_light(Light { state.light_manager.add_light(Light::new_point(
position: sun_pos.cast::<f32>().unwrap(), sun_pos.cast::<f32>().unwrap(),
direction: Vector3::new(0.0, 0.0, 0.0), Vector3::from([1.0, 1.0, 0.8]),
color: Vector3::from([1.0, 1.0, 0.8]), 5.0,
intensity: 5.0, 1.0 / 1000.0,
range: 100000000.0, ));
inner_cutoff: 0.0,
light_type: LightType::Point,
outer_cutoff: 0.0,
});
let instances = bodies let instances = bodies
.iter() .iter()
@ -78,7 +74,7 @@ pub async fn run() {
scale: 0.05, scale: 0.05,
shape: solar_engine::Shape::Sphere, shape: solar_engine::Shape::Sphere,
always_lit: i == 0, // Sun always_lit: i == 0, // Sun
is_transparent: false is_transparent: false,
} }
}) })
.collect(); .collect();

View File

@ -1,5 +1,5 @@
use bytemuck::{Pod, Zeroable}; use bytemuck::{Pod, Zeroable};
use cgmath::{EuclideanSpace, Matrix4, Point3, Transform, Vector3}; use cgmath::{EuclideanSpace, Matrix4, Point3, Transform, Vector3, Zero};
use wgpu::util::DeviceExt; use wgpu::util::DeviceExt;
#[repr(u32)] #[repr(u32)]
@ -53,6 +53,21 @@ impl Light {
outer_cutoff: self.outer_cutoff, outer_cutoff: self.outer_cutoff,
} }
} }
pub fn new_point(position: Vector3<f32>, color: Vector3<f32>, intensity: f32, min_attenuation: f32) -> Self {
let range = (intensity / min_attenuation).sqrt().max(1.0);
Self {
light_type: LightType::Point,
position,
direction: Vector3::zero(),
color,
intensity,
range,
inner_cutoff: 0.0,
outer_cutoff: 0.0,
}
}
} }
pub struct LightManager { pub struct LightManager {
@ -263,6 +278,20 @@ impl LightManager {
queue: &wgpu::Queue, queue: &wgpu::Queue,
assignment: &ClusterAssignment, assignment: &ClusterAssignment,
) { ) {
let new_index_bytes = assignment.cluster_light_indices.len() * std::mem::size_of::<u32>();
let new_offset_bytes = assignment.cluster_offsets.len() * std::mem::size_of::<[u32; 2]>();
let needs_resize = self.cluster_buffers.as_ref().map(|buffers| {
let index_size_ok = new_index_bytes <= buffers.light_indices.size() as usize;
let offset_size_ok = new_offset_bytes <= buffers.offsets.size() as usize;
!(index_size_ok && offset_size_ok)
}).unwrap_or(true);
if needs_resize {
let buffers = self.create_cluster_buffers(device, assignment);
self.cluster_buffers = Some(buffers);
}
if let Some(buffers) = &self.cluster_buffers { if let Some(buffers) = &self.cluster_buffers {
queue.write_buffer(&buffers.light_indices, 0, bytemuck::cast_slice(&assignment.cluster_light_indices)); queue.write_buffer(&buffers.light_indices, 0, bytemuck::cast_slice(&assignment.cluster_light_indices));
@ -273,9 +302,6 @@ impl LightManager {
.collect(); .collect();
queue.write_buffer(&buffers.offsets, 0, bytemuck::cast_slice(&offset_pairs)); queue.write_buffer(&buffers.offsets, 0, bytemuck::cast_slice(&offset_pairs));
} else {
let buffers = self.create_cluster_buffers(device, assignment);
self.cluster_buffers = Some(buffers);
} }
} }

View File

@ -123,10 +123,6 @@ fn fs_main(input: VSOutput) -> @location(0) vec4<f32> {
let offset = offset_info.x; let offset = offset_info.x;
let count = offset_info.y; let count = offset_info.y;
if (always_lit) {
return vec4<f32>(input.frag_color, 2.0);
}
for (var i = 0u; i < count; i = i + 1u) { for (var i = 0u; i < count; i = i + 1u) {
let light_index = cluster_light_indices[offset + i]; let light_index = cluster_light_indices[offset + i];
let light = all_lights[light_index]; let light = all_lights[light_index];
@ -159,8 +155,14 @@ fn fs_main(input: VSOutput) -> @location(0) vec4<f32> {
default: {} default: {}
} }
if (!always_lit) {
lighting += light_contrib; lighting += light_contrib;
} }
}
if (always_lit) {
lighting = vec3<f32>(1.0, 1.0, 1.0) * 2.0;
}
return vec4<f32>(input.frag_color * lighting, 1.0); return vec4<f32>(input.frag_color * lighting, 1.0);
} }