diff --git a/shaders/compiled/frag_rt_quad.spv b/shaders/compiled/frag_rt_quad.spv index 216c161..6669b93 100644 Binary files a/shaders/compiled/frag_rt_quad.spv and b/shaders/compiled/frag_rt_quad.spv differ diff --git a/src/app_data.rs b/src/app_data.rs index 789c374..f7e5b20 100644 --- a/src/app_data.rs +++ b/src/app_data.rs @@ -62,6 +62,7 @@ pub struct AppData { pub scene_rt_memory_size: u64, // values passed to shader pub num_lights_per_volume: u32, + pub min_light_weight: f32, pub max_iterations_per_light: u32, pub diffuse_raster_steps: u32, pub diffuse_raster_size: f32, diff --git a/src/main.rs b/src/main.rs index db7c7a7..a1a99cd 100644 --- a/src/main.rs +++ b/src/main.rs @@ -192,6 +192,7 @@ impl App { let mut data = app_data::AppData::default(); data.use_geometry_shader = false; data.num_lights_per_volume = 5; + data.min_light_weight = 0.0001; data.max_iterations_per_light = 20; data.diffuse_raster_steps = 0; data.diffuse_raster_size = 0.01; diff --git a/src/scene/empty_volume.rs b/src/scene/empty_volume.rs index cf265b7..6466572 100644 --- a/src/scene/empty_volume.rs +++ b/src/scene/empty_volume.rs @@ -969,12 +969,13 @@ impl EmptyVolume { quads } - pub fn select_lights(&self, lights: LightsIter, light_number: u32) -> Vec<u32> { - let center = self.position + Vector3{x: self.size_x / 2, y: self.size_y / 2, z: self.size_z / 2}; + pub fn select_lights(&self, lights: LightsIter, light_number: u32, min_light_weight: f32) -> Vec<u32> { let mut weighted_indices = vec![]; - for light in lights { - let weight = light.borrow().weighted_distance(center); - weighted_indices.push((weight, light.borrow().get_memory_start())); + for light in lights { + let weight = light.borrow().weighted_distance(self.position + self.tree_offset * self.tree_size, Vector3{x: self.size_x, y: self.size_y, z: self.size_z}); + if weight >= min_light_weight { + weighted_indices.push((weight, light.borrow().get_memory_start())); + } } weighted_indices.sort_by(|a, b| a.0.partial_cmp(&b.0).unwrap()); @@ -1213,7 +1214,7 @@ impl Memorizable for EmptyVolume { v[mem_index] = self.size_z as u32; mem_index += 1; //Todo: insert lights - let selected_lights = self.select_lights(scene.get_light_iter(), data.num_lights_per_volume); + let selected_lights = self.select_lights(scene.get_light_iter(), data.num_lights_per_volume, data.min_light_weight); for light in selected_lights { v[mem_index] = light; mem_index += 1; diff --git a/src/scene/generators.rs b/src/scene/generators.rs index 3b3a6fa..0552b27 100644 --- a/src/scene/generators.rs +++ b/src/scene/generators.rs @@ -54,7 +54,7 @@ pub fn generate_test_scene(scene: &mut Scene, data: &mut AppData) -> Result<(Poi let shade = (rng.gen_range(0..25) as f32) / 100.0; let cube = Cube { pos: vec3(10.0, 10.0, 10.0), - color: vec3(0.9, 0.9, 0.9), + color: vec3(0.0, 0.0, 0.9), tex_coord: vec2(0.0, 0.0), transparent: true, roughness: 32, @@ -63,7 +63,7 @@ pub fn generate_test_scene(scene: &mut Scene, data: &mut AppData) -> Result<(Poi let cube = Cube { pos: vec3(10.0, 10.0, 9.0), - color: vec3(0.9, 0.9, 0.9), + color: vec3(0.0, 0.0, 0.9), tex_coord: vec2(0.0, 0.0), transparent: true, roughness: 32, @@ -212,7 +212,7 @@ pub fn generate_test_scene2(scene: &mut Scene, data: &mut AppData, chunk_num_x: cube.draw(&data.topology, index, scene); } - scene.directional_lights.push(Rc::new(RefCell::new(DirectionalLight { direction: vec3(0.0, 0.0, -1.0), color: vec3(0.1, 0.1, 0.1), memory_start: 0 }))); + //scene.directional_lights.push(Rc::new(RefCell::new(DirectionalLight { direction: vec3(0.5, 0.0, -1.0), color: vec3(0.1, 0.1, 0.1), memory_start: 0 }))); scene.oct_trees = oct_trees; Ok(cgmath::point3((max_x as f32 / 2.0) as f32, (max_y as f32 / 2.0) as f32, height_map[(max_x as f32 / 2.0).floor() as usize][(max_y as f32 / 2.0).floor() as usize] + 2000.0)) diff --git a/src/scene/light.rs b/src/scene/light.rs index d6a4c82..bf39edc 100644 --- a/src/scene/light.rs +++ b/src/scene/light.rs @@ -1,3 +1,4 @@ +use cgmath::AbsDiffEq; use cgmath::{InnerSpace, MetricSpace, Vector3}; use crate::vertex; @@ -12,7 +13,7 @@ pub enum LightType { pub trait Light { fn get_light_type(&self) -> LightType; - fn weighted_distance(&self, center: Vector3<usize>) -> f32; + fn weighted_distance(&self, pos: Vector3<usize>, size: Vector3<usize>) -> f32; } pub trait LightSource: Light + Memorizable {} @@ -57,8 +58,53 @@ impl Light for PointLight { LightType::POINT } - fn weighted_distance(&self, center: Vector3<usize>) -> f32 { - let distance = self.pos.distance(vertex::Vec3{x: center.x as f32, y: center.y as f32, z: center.z as f32}); + fn weighted_distance(&self, pos: Vector3<usize>, size: Vector3<usize>) -> f32 { + let low_end = vertex::Vec3{x: pos.x as f32, y: pos.y as f32, z: pos.z as f32}; + let high_end = vertex::Vec3{x: (pos.x + size.x) as f32, y: (pos.y + size.y) as f32, z: (pos.z + size.z) as f32}; + let distance; + if low_end.x <= self.pos.x && self.pos.x <= high_end.x && low_end.y <= self.pos.y && self.pos.y <= high_end.y && low_end.z <= self.pos.z && self.pos.z <= high_end.z { + let diff_low = self.pos - low_end; + let diff_high = self.pos - high_end; + distance = diff_low.x.abs().min(diff_low.y.abs().min(diff_low.z.abs().min(diff_high.x.abs().min(diff_high.y.abs().min(diff_high.z.abs()))))); + } else { + let mut offset_vec = vertex::Vec3 {x: 0.0, y: 0.0, z: 0.0}; + + while !(low_end.x <= self.pos.x + offset_vec.x && self.pos.x + offset_vec.x <= high_end.x && low_end.y <= self.pos.y + offset_vec.y && self.pos.y + offset_vec.y <= high_end.y && low_end.z <= self.pos.z + offset_vec.z && self.pos.z + offset_vec.z <= high_end.z) { + let diff_low = (self.pos + offset_vec) - low_end; + let diff_high = (self.pos + offset_vec) - high_end; + + let mut new_diff = vertex::Vec3 {x: 0.0, y: 0.0, z: 0.0}; + if diff_low.x.abs() < diff_high.x.abs() { + new_diff.x += diff_low.x; + } else { + new_diff.x += diff_high.x; + } + + if diff_low.y.abs() < diff_high.y.abs() { + new_diff.y += diff_low.y; + } else { + new_diff.y += diff_high.y; + } + + if diff_low.z.abs() < diff_high.z.abs() { + new_diff.z += diff_low.z; + } else { + new_diff.z += diff_high.z; + } + + if ((new_diff.x < new_diff.y || new_diff.y == 0.0) && (new_diff.x < new_diff.z || new_diff.z == 0.0) && new_diff.x != 0.0) { + offset_vec.x -= new_diff.x; + } else { + if (new_diff.y < new_diff.z || new_diff.z == 0.0) && new_diff.y != 0.0 { + offset_vec.y -= new_diff.y; + } else { + offset_vec.z -= new_diff.z; + } + } + } + + distance = offset_vec.magnitude(); + } let light_intensity = self.color.magnitude(); light_intensity / distance.powf(2.0) @@ -106,7 +152,7 @@ impl Light for DirectionalLight { LightType::DIRECTION } - fn weighted_distance(&self, center: Vector3<usize>) -> f32 { + fn weighted_distance(&self, pos: Vector3<usize>, size: Vector3<usize>) -> f32 { let light_intensity = self.color.magnitude(); light_intensity