optimize light selection
This commit is contained in:
parent
1a30887a7d
commit
7a58ba9733
6 changed files with 62 additions and 13 deletions
Binary file not shown.
|
@ -62,6 +62,7 @@ pub struct AppData {
|
||||||
pub scene_rt_memory_size: u64,
|
pub scene_rt_memory_size: u64,
|
||||||
// values passed to shader
|
// values passed to shader
|
||||||
pub num_lights_per_volume: u32,
|
pub num_lights_per_volume: u32,
|
||||||
|
pub min_light_weight: f32,
|
||||||
pub max_iterations_per_light: u32,
|
pub max_iterations_per_light: u32,
|
||||||
pub diffuse_raster_steps: u32,
|
pub diffuse_raster_steps: u32,
|
||||||
pub diffuse_raster_size: f32,
|
pub diffuse_raster_size: f32,
|
||||||
|
|
|
@ -192,6 +192,7 @@ impl App {
|
||||||
let mut data = app_data::AppData::default();
|
let mut data = app_data::AppData::default();
|
||||||
data.use_geometry_shader = false;
|
data.use_geometry_shader = false;
|
||||||
data.num_lights_per_volume = 5;
|
data.num_lights_per_volume = 5;
|
||||||
|
data.min_light_weight = 0.0001;
|
||||||
data.max_iterations_per_light = 20;
|
data.max_iterations_per_light = 20;
|
||||||
data.diffuse_raster_steps = 0;
|
data.diffuse_raster_steps = 0;
|
||||||
data.diffuse_raster_size = 0.01;
|
data.diffuse_raster_size = 0.01;
|
||||||
|
|
|
@ -969,12 +969,13 @@ impl EmptyVolume {
|
||||||
quads
|
quads
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn select_lights(&self, lights: LightsIter, light_number: u32) -> Vec<u32> {
|
pub fn select_lights(&self, lights: LightsIter, light_number: u32, min_light_weight: f32) -> Vec<u32> {
|
||||||
let center = self.position + Vector3{x: self.size_x / 2, y: self.size_y / 2, z: self.size_z / 2};
|
|
||||||
let mut weighted_indices = vec![];
|
let mut weighted_indices = vec![];
|
||||||
for light in lights {
|
for light in lights {
|
||||||
let weight = light.borrow().weighted_distance(center);
|
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});
|
||||||
weighted_indices.push((weight, light.borrow().get_memory_start()));
|
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());
|
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;
|
v[mem_index] = self.size_z as u32;
|
||||||
mem_index += 1;
|
mem_index += 1;
|
||||||
//Todo: insert lights
|
//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 {
|
for light in selected_lights {
|
||||||
v[mem_index] = light;
|
v[mem_index] = light;
|
||||||
mem_index += 1;
|
mem_index += 1;
|
||||||
|
|
|
@ -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 shade = (rng.gen_range(0..25) as f32) / 100.0;
|
||||||
let cube = Cube {
|
let cube = Cube {
|
||||||
pos: vec3(10.0, 10.0, 10.0),
|
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),
|
tex_coord: vec2(0.0, 0.0),
|
||||||
transparent: true,
|
transparent: true,
|
||||||
roughness: 32,
|
roughness: 32,
|
||||||
|
@ -63,7 +63,7 @@ pub fn generate_test_scene(scene: &mut Scene, data: &mut AppData) -> Result<(Poi
|
||||||
|
|
||||||
let cube = Cube {
|
let cube = Cube {
|
||||||
pos: vec3(10.0, 10.0, 9.0),
|
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),
|
tex_coord: vec2(0.0, 0.0),
|
||||||
transparent: true,
|
transparent: true,
|
||||||
roughness: 32,
|
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);
|
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;
|
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))
|
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))
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
use cgmath::AbsDiffEq;
|
||||||
use cgmath::{InnerSpace, MetricSpace, Vector3};
|
use cgmath::{InnerSpace, MetricSpace, Vector3};
|
||||||
|
|
||||||
use crate::vertex;
|
use crate::vertex;
|
||||||
|
@ -12,7 +13,7 @@ pub enum LightType {
|
||||||
|
|
||||||
pub trait Light {
|
pub trait Light {
|
||||||
fn get_light_type(&self) -> LightType;
|
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 {}
|
pub trait LightSource: Light + Memorizable {}
|
||||||
|
@ -57,8 +58,53 @@ impl Light for PointLight {
|
||||||
LightType::POINT
|
LightType::POINT
|
||||||
}
|
}
|
||||||
|
|
||||||
fn weighted_distance(&self, center: Vector3<usize>) -> f32 {
|
fn weighted_distance(&self, pos: Vector3<usize>, size: 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});
|
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();
|
let light_intensity = self.color.magnitude();
|
||||||
|
|
||||||
light_intensity / distance.powf(2.0)
|
light_intensity / distance.powf(2.0)
|
||||||
|
@ -106,7 +152,7 @@ impl Light for DirectionalLight {
|
||||||
LightType::DIRECTION
|
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();
|
let light_intensity = self.color.magnitude();
|
||||||
|
|
||||||
light_intensity
|
light_intensity
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue