From e4e0c3078fd8a4e37fd565624c8fc2bc8322b4d6 Mon Sep 17 00:00:00 2001 From: Verox001 Date: Wed, 7 May 2025 20:12:10 +0200 Subject: [PATCH] Implemented lighting buffer resize and pre-calculated range by min_attenuation --- simulator/src/main.rs | 18 +++++++----------- solar_engine/src/light.rs | 34 ++++++++++++++++++++++++++++++---- solar_engine/src/shader.wgsl | 12 +++++++----- 3 files changed, 44 insertions(+), 20 deletions(-) diff --git a/simulator/src/main.rs b/simulator/src/main.rs index 06f14bf..fff855d 100644 --- a/simulator/src/main.rs +++ b/simulator/src/main.rs @@ -52,16 +52,12 @@ pub async fn run() { let sun_pos = bodies[0].position / 1.496e11; state.light_manager.clear(); - state.light_manager.add_light(Light { - position: sun_pos.cast::().unwrap(), - direction: Vector3::new(0.0, 0.0, 0.0), - color: Vector3::from([1.0, 1.0, 0.8]), - intensity: 5.0, - range: 100000000.0, - inner_cutoff: 0.0, - light_type: LightType::Point, - outer_cutoff: 0.0, - }); + state.light_manager.add_light(Light::new_point( + sun_pos.cast::().unwrap(), + Vector3::from([1.0, 1.0, 0.8]), + 5.0, + 1.0 / 1000.0, + )); let instances = bodies .iter() @@ -78,7 +74,7 @@ pub async fn run() { scale: 0.05, shape: solar_engine::Shape::Sphere, always_lit: i == 0, // Sun - is_transparent: false + is_transparent: false, } }) .collect(); diff --git a/solar_engine/src/light.rs b/solar_engine/src/light.rs index 3e56e05..d1e1d75 100644 --- a/solar_engine/src/light.rs +++ b/solar_engine/src/light.rs @@ -1,5 +1,5 @@ use bytemuck::{Pod, Zeroable}; -use cgmath::{EuclideanSpace, Matrix4, Point3, Transform, Vector3}; +use cgmath::{EuclideanSpace, Matrix4, Point3, Transform, Vector3, Zero}; use wgpu::util::DeviceExt; #[repr(u32)] @@ -53,6 +53,21 @@ impl Light { outer_cutoff: self.outer_cutoff, } } + + pub fn new_point(position: Vector3, color: Vector3, 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 { @@ -263,6 +278,20 @@ impl LightManager { queue: &wgpu::Queue, assignment: &ClusterAssignment, ) { + let new_index_bytes = assignment.cluster_light_indices.len() * std::mem::size_of::(); + 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 { queue.write_buffer(&buffers.light_indices, 0, bytemuck::cast_slice(&assignment.cluster_light_indices)); @@ -273,9 +302,6 @@ impl LightManager { .collect(); 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); } } diff --git a/solar_engine/src/shader.wgsl b/solar_engine/src/shader.wgsl index 46930e0..62a0c3c 100644 --- a/solar_engine/src/shader.wgsl +++ b/solar_engine/src/shader.wgsl @@ -123,10 +123,6 @@ fn fs_main(input: VSOutput) -> @location(0) vec4 { let offset = offset_info.x; let count = offset_info.y; - if (always_lit) { - return vec4(input.frag_color, 2.0); - } - for (var i = 0u; i < count; i = i + 1u) { let light_index = cluster_light_indices[offset + i]; let light = all_lights[light_index]; @@ -159,7 +155,13 @@ fn fs_main(input: VSOutput) -> @location(0) vec4 { default: {} } - lighting += light_contrib; + if (!always_lit) { + lighting += light_contrib; + } + } + + if (always_lit) { + lighting = vec3(1.0, 1.0, 1.0) * 2.0; } return vec4(input.frag_color * lighting, 1.0);