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;
state.light_manager.clear();
state.light_manager.add_light(Light {
position: sun_pos.cast::<f32>().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::<f32>().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();

View File

@ -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<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 {
@ -263,6 +278,20 @@ impl LightManager {
queue: &wgpu::Queue,
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 {
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);
}
}

View File

@ -123,10 +123,6 @@ fn fs_main(input: VSOutput) -> @location(0) vec4<f32> {
let offset = offset_info.x;
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) {
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<f32> {
default: {}
}
lighting += light_contrib;
if (!always_lit) {
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);