adds naive update for light and volumes
This commit is contained in:
parent
90b16a3d5c
commit
579820334d
6 changed files with 158 additions and 52 deletions
12
src/main.rs
12
src/main.rs
|
@ -22,6 +22,7 @@ use vulkanalia::bytecode::Bytecode;
|
|||
|
||||
use std::collections::HashSet;
|
||||
use std::ffi::CStr;
|
||||
use std::time::{Duration, SystemTime};
|
||||
use std::os::raw::c_void;
|
||||
|
||||
// extension imports
|
||||
|
@ -182,6 +183,7 @@ struct App {
|
|||
scene_handler: scene::Scene,
|
||||
show_frame_rate: bool,
|
||||
synchronized: usize,
|
||||
appstart: Instant,
|
||||
}
|
||||
|
||||
impl App {
|
||||
|
@ -244,7 +246,8 @@ impl App {
|
|||
cur_pos: cur_pos,
|
||||
scene_handler,
|
||||
show_frame_rate: false,
|
||||
synchronized: 0
|
||||
synchronized: 0,
|
||||
appstart: Instant::now(),
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -276,7 +279,14 @@ impl App {
|
|||
self.data.images_in_flight[image_index] = in_flight_fence;
|
||||
|
||||
self.update_uniform_buffer(image_index)?;
|
||||
let time = self.appstart.elapsed().as_secs_f32() / 1.0;
|
||||
self.scene_handler.point_lights[0].borrow_mut().set_pos(cgmath::vec3((10.0 + 64.0) as f32 + time.sin(), (10.0 + 64.0) as f32 + time.cos(), 11.0));
|
||||
self.synchronized = 0;
|
||||
|
||||
if self.synchronized < MAX_FRAMES_IN_FLIGHT {
|
||||
if self.scene_handler.is_dirty() {
|
||||
self.scene_handler.update_memory(&mut self.data, true)
|
||||
}
|
||||
buffer::update_storage_buffer(&self.instance, &self.device, &self.data, image_index, &self.scene_handler)?;
|
||||
self.synchronized += 1
|
||||
}
|
||||
|
|
|
@ -17,6 +17,7 @@ use super::AppData;
|
|||
use super::LightsIter;
|
||||
use super::Scene;
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct EmptyVolume {
|
||||
pub memory_start: usize,
|
||||
|
||||
|
@ -49,6 +50,9 @@ pub struct EmptyVolume {
|
|||
pub neighbor_front: Vec<Option<Rc<RefCell<Self>>>>,
|
||||
|
||||
pub scale: f32,
|
||||
|
||||
old_memory_size: u32,
|
||||
dirty: bool,
|
||||
}
|
||||
|
||||
impl EmptyVolume {
|
||||
|
@ -304,6 +308,8 @@ impl EmptyVolume {
|
|||
neighbor_back: vec![],
|
||||
neighbor_front: vec![],
|
||||
scale: tree.borrow().scale,
|
||||
old_memory_size: 0,
|
||||
dirty: true,
|
||||
};
|
||||
println!("adding neighbor references");
|
||||
// MARK: fill in info in the neighbor octtree
|
||||
|
@ -1274,7 +1280,7 @@ impl Memorizable for EmptyVolume {
|
|||
mem_size
|
||||
}
|
||||
// MARK: insert into Memory
|
||||
fn insert_into_memory(&self, mut v: Vec<u32>, data: &AppData, scene: &Scene) -> Vec<u32> {
|
||||
fn insert_into_memory(&mut self, mut v: Vec<u32>, data: &AppData, scene: &Scene) -> Vec<u32> {
|
||||
let mut mem_index = self.memory_start;
|
||||
//pos
|
||||
v[mem_index] = u32::from_ne_bytes(self.real_position.x.to_ne_bytes());
|
||||
|
@ -1591,6 +1597,9 @@ impl Memorizable for EmptyVolume {
|
|||
v[mem_index] = 0;
|
||||
mem_index += 1;
|
||||
}
|
||||
|
||||
self.dirty = false;
|
||||
self.old_memory_size = self.get_buffer_mem_size(data);
|
||||
//println!("last memory index of volume was {}, equivalent to {}kB", mem_index, mem_index * 32 / 8 / 1024);
|
||||
v
|
||||
}
|
||||
|
@ -1602,6 +1611,13 @@ impl Memorizable for EmptyVolume {
|
|||
fn set_memory_start(&mut self, memory_start: usize) {
|
||||
self.memory_start = memory_start;
|
||||
}
|
||||
|
||||
fn get_prev_buffer_mem_size(&self) -> u32 {
|
||||
self.old_memory_size
|
||||
}
|
||||
fn is_dirty(&self) -> bool {
|
||||
self.dirty
|
||||
}
|
||||
}
|
||||
|
||||
impl PartialEq for EmptyVolume {
|
||||
|
|
|
@ -91,9 +91,9 @@ pub fn generate_test_scene(scene: &mut Scene, data: &mut AppData) -> Result<(Poi
|
|||
};
|
||||
oct_tree2.set_cube(cube.clone());
|
||||
|
||||
scene.point_lights.push(Rc::new(RefCell::new(PointLight { pos: vec3(11.0 + grid_size as f32, 11.0 + grid_size as f32, 11.0) * scale, color: vec3(2.0, 2.0, 2.0), memory_start: 0 })));
|
||||
scene.point_lights.push(Rc::new(RefCell::new(PointLight { pos: vec3(9.0 + grid_size as f32, 9.0 + grid_size as f32, 11.0) * scale, color: vec3(0.5, 0.5, 0.5), memory_start: 0 })));
|
||||
scene.directional_lights.push(Rc::new(RefCell::new(DirectionalLight { direction: vec3(1.0, 1.0, -1.0), color: vec3(0.1, 0.1, 0.1), memory_start: 0 })));
|
||||
scene.point_lights.push(Rc::new(RefCell::new(PointLight::init(vec3(11.0 + grid_size as f32, 11.0 + grid_size as f32, 11.0) * scale, vec3(2.0, 2.0, 2.0)))));
|
||||
scene.point_lights.push(Rc::new(RefCell::new(PointLight::init(vec3(9.0 + grid_size as f32, 9.0 + grid_size as f32, 11.0) * scale, vec3(0.5, 0.5, 0.5)))));
|
||||
scene.directional_lights.push(Rc::new(RefCell::new(DirectionalLight::init(vec3(1.0, 1.0, -1.0), vec3(0.1, 0.1, 0.1)))));
|
||||
|
||||
let cube = Cuboid {
|
||||
pos: vec3(11.0 + grid_size as f32, 11.0 + grid_size as f32, 11.0) * scale,
|
||||
|
@ -204,7 +204,7 @@ pub fn generate_test_scene2(scene: &mut Scene, data: &mut AppData, chunk_num_x:
|
|||
let center_x = rng.gen_range(0..max_x) as f32;
|
||||
let center_y = rng.gen_range(0..max_y) as f32;
|
||||
let final_height = height_map[center_x.floor() as usize][center_y.floor() as usize] + height;
|
||||
scene.point_lights.push(Rc::new(RefCell::new(PointLight { pos: vec3(center_x, center_y, final_height), color: vec3(1.0, 1.0, 1.0), memory_start: 0 })));
|
||||
scene.point_lights.push(Rc::new(RefCell::new(PointLight::init(vec3(center_x, center_y, final_height), vec3(1.0, 1.0, 1.0)))));
|
||||
|
||||
let cube = Cuboid {
|
||||
pos: vec3(center_x, center_y, final_height),
|
||||
|
|
|
@ -22,9 +22,21 @@ pub trait LightSource: Light + Memorizable {}
|
|||
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
pub struct PointLight{
|
||||
pub pos: vertex::Vec3,
|
||||
pub color: vertex::Vec3,
|
||||
pos: vertex::Vec3,
|
||||
color: vertex::Vec3,
|
||||
pub memory_start: usize,
|
||||
dirty: bool,
|
||||
}
|
||||
|
||||
impl PointLight {
|
||||
pub fn init(pos: vertex::Vec3, color: vertex::Vec3) -> Self {
|
||||
Self { pos: pos, color: color, memory_start: 0, dirty: true }
|
||||
}
|
||||
|
||||
pub fn set_pos(&mut self, pos: vertex::Vec3) {
|
||||
self.pos = pos;
|
||||
self.dirty = true;
|
||||
}
|
||||
}
|
||||
|
||||
impl Memorizable for PointLight {
|
||||
|
@ -32,7 +44,7 @@ impl Memorizable for PointLight {
|
|||
1 + 3 + 3
|
||||
}
|
||||
|
||||
fn insert_into_memory(&self, mut v: Vec<u32>, data: &AppData, scene: &Scene) -> Vec<u32> {
|
||||
fn insert_into_memory(&mut self, mut v: Vec<u32>, data: &AppData, scene: &Scene) -> Vec<u32> {
|
||||
v[self.memory_start] = LightType::POINT as u32;
|
||||
|
||||
v[self.memory_start + 1] = u32::from_ne_bytes(self.pos.x.to_ne_bytes());
|
||||
|
@ -42,6 +54,9 @@ impl Memorizable for PointLight {
|
|||
v[self.memory_start + 4] = (self.color.x * 255.0) as u32;
|
||||
v[self.memory_start + 5] = (self.color.y * 255.0) as u32;
|
||||
v[self.memory_start + 6] = (self.color.z * 255.0) as u32;
|
||||
|
||||
self.dirty = false;
|
||||
|
||||
v
|
||||
}
|
||||
|
||||
|
@ -52,6 +67,13 @@ impl Memorizable for PointLight {
|
|||
fn set_memory_start(&mut self, memory_start: usize) {
|
||||
self.memory_start = memory_start;
|
||||
}
|
||||
|
||||
fn get_prev_buffer_mem_size(&self) -> u32 {
|
||||
1 + 3 + 3
|
||||
}
|
||||
fn is_dirty(&self) -> bool {
|
||||
self.dirty
|
||||
}
|
||||
}
|
||||
|
||||
impl Light for PointLight {
|
||||
|
@ -120,9 +142,16 @@ impl LightSource for PointLight {}
|
|||
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
pub struct DirectionalLight{
|
||||
pub direction: vertex::Vec3,
|
||||
pub color: vertex::Vec3,
|
||||
direction: vertex::Vec3,
|
||||
color: vertex::Vec3,
|
||||
pub memory_start: usize,
|
||||
dirty: bool,
|
||||
}
|
||||
|
||||
impl DirectionalLight {
|
||||
pub fn init(direction: vertex::Vec3, color: vertex::Vec3) -> Self {
|
||||
Self { direction: direction, color: color, memory_start: 0, dirty: true }
|
||||
}
|
||||
}
|
||||
|
||||
impl Memorizable for DirectionalLight {
|
||||
|
@ -130,7 +159,7 @@ impl Memorizable for DirectionalLight {
|
|||
1 + 3 + 3
|
||||
}
|
||||
|
||||
fn insert_into_memory(&self, mut v: Vec<u32>, data: &AppData, scene: &Scene) -> Vec<u32> {
|
||||
fn insert_into_memory(&mut self, mut v: Vec<u32>, data: &AppData, scene: &Scene) -> Vec<u32> {
|
||||
v[self.memory_start] = LightType::DIRECTION as u32;
|
||||
|
||||
v[self.memory_start + 1] = u32::from_ne_bytes(self.direction.x.to_ne_bytes());
|
||||
|
@ -140,6 +169,10 @@ impl Memorizable for DirectionalLight {
|
|||
v[self.memory_start + 4] = (self.color.x * 255.0) as u32;
|
||||
v[self.memory_start + 5] = (self.color.y * 255.0) as u32;
|
||||
v[self.memory_start + 6] = (self.color.z * 255.0) as u32;
|
||||
|
||||
self.dirty = false;
|
||||
|
||||
|
||||
v
|
||||
}
|
||||
|
||||
|
@ -150,6 +183,13 @@ impl Memorizable for DirectionalLight {
|
|||
fn set_memory_start(&mut self, memory_start: usize) {
|
||||
self.memory_start = memory_start;
|
||||
}
|
||||
|
||||
fn get_prev_buffer_mem_size(&self) -> u32 {
|
||||
1 + 3 + 3
|
||||
}
|
||||
fn is_dirty(&self) -> bool {
|
||||
self.dirty
|
||||
}
|
||||
}
|
||||
|
||||
impl Light for DirectionalLight {
|
||||
|
@ -176,7 +216,7 @@ mod test {
|
|||
|
||||
#[test]
|
||||
fn test_memorizable() {
|
||||
let p = PointLight {pos: vertex::Vec3 { x: 1.0, y: 2.0, z: 3.0}, color: vertex::Vec3 { x: 0.0, y: 1.0, z: 0.0}, memory_start: 0};
|
||||
let mut p = PointLight::init(vertex::Vec3 { x: 1.0, y: 2.0, z: 3.0}, vertex::Vec3 { x: 0.0, y: 1.0, z: 0.0});
|
||||
let data= AppData::default();
|
||||
let scene = Scene::default();
|
||||
|
||||
|
@ -184,13 +224,15 @@ mod test {
|
|||
assert!(mem_size == 7);
|
||||
|
||||
let mut memory = vec![0; 7];
|
||||
assert!(!p.dirty);
|
||||
p.insert_into_memory(memory, &data, &scene);
|
||||
assert!(p.dirty);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic]
|
||||
fn test_mem_size() {
|
||||
let p = PointLight {pos: vertex::Vec3 { x: 1.0, y: 2.0, z: 3.0}, color: vertex::Vec3 { x: 0.0, y: 1.0, z: 0.0}, memory_start: 0};
|
||||
let mut p = PointLight::init(vertex::Vec3 { x: 1.0, y: 2.0, z: 3.0}, vertex::Vec3 { x: 0.0, y: 1.0, z: 0.0});
|
||||
let data= AppData::default();
|
||||
let scene = Scene::default();
|
||||
|
||||
|
@ -198,12 +240,14 @@ mod test {
|
|||
assert!(mem_size == 7);
|
||||
|
||||
let mut memory = vec![0; 6];
|
||||
assert!(!p.dirty);
|
||||
p.insert_into_memory(memory, &data, &scene);
|
||||
assert!(p.dirty);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_memorizable_directional_light() {
|
||||
let p = DirectionalLight {direction: vertex::Vec3 { x: 1.0, y: 2.0, z: 3.0}, color: vertex::Vec3 { x: 0.0, y: 1.0, z: 0.0}, memory_start: 0};
|
||||
let mut p = DirectionalLight::init(vertex::Vec3 { x: 1.0, y: 2.0, z: 3.0}, vertex::Vec3 { x: 0.0, y: 1.0, z: 0.0});
|
||||
let data= AppData::default();
|
||||
let scene = Scene::default();
|
||||
|
||||
|
@ -211,13 +255,15 @@ mod test {
|
|||
assert!(mem_size == 7);
|
||||
|
||||
let mut memory = vec![0; 7];
|
||||
assert!(!p.dirty);
|
||||
p.insert_into_memory(memory, &data, &scene);
|
||||
assert!(p.dirty);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic]
|
||||
fn test_mem_size_directional_light() {
|
||||
let p = DirectionalLight {direction: vertex::Vec3 { x: 1.0, y: 2.0, z: 3.0}, color: vertex::Vec3 { x: 0.0, y: 1.0, z: 0.0}, memory_start: 0};
|
||||
let mut p = DirectionalLight::init(vertex::Vec3 { x: 1.0, y: 2.0, z: 3.0}, vertex::Vec3 { x: 0.0, y: 1.0, z: 0.0});
|
||||
let data= AppData::default();
|
||||
let scene = Scene::default();
|
||||
|
||||
|
@ -225,6 +271,8 @@ mod test {
|
|||
assert!(mem_size == 7);
|
||||
|
||||
let mut memory = vec![0; 6];
|
||||
assert!(!p.dirty);
|
||||
p.insert_into_memory(memory, &data, &scene);
|
||||
assert!(p.dirty);
|
||||
}
|
||||
}
|
|
@ -2,9 +2,11 @@ use super::light::LightSource;
|
|||
use super::AppData;
|
||||
use super::Scene;
|
||||
|
||||
pub trait Memorizable {
|
||||
pub trait Memorizable: core::fmt::Debug {
|
||||
fn get_buffer_mem_size(&self, data: &AppData) -> u32;
|
||||
fn insert_into_memory(&self, v: Vec<u32>, data: &AppData, scene: &Scene) -> Vec<u32>;
|
||||
fn get_prev_buffer_mem_size(&self) -> u32;
|
||||
fn is_dirty(&self) -> bool;
|
||||
fn insert_into_memory(&mut self, v: Vec<u32>, data: &AppData, scene: &Scene) -> Vec<u32>;
|
||||
fn get_memory_start(&self) -> usize;
|
||||
fn set_memory_start(&mut self, memory_start: usize);
|
||||
}
|
|
@ -59,8 +59,10 @@ pub struct Scene {
|
|||
|
||||
pub oct_trees: Vec<Vec<Vec<Rc<RefCell<OctTree<Cube>>>>>>,
|
||||
|
||||
point_lights: Vec<Rc<RefCell<PointLight>>>,
|
||||
directional_lights: Vec<Rc<RefCell<DirectionalLight>>>,
|
||||
pub point_lights: Vec<Rc<RefCell<PointLight>>>,
|
||||
pub directional_lights: Vec<Rc<RefCell<DirectionalLight>>>,
|
||||
|
||||
pub memorizables: Vec<Rc<RefCell<dyn Memorizable>>>,
|
||||
}
|
||||
|
||||
impl Scene {
|
||||
|
@ -121,48 +123,27 @@ impl Scene {
|
|||
z_index += 1;
|
||||
}
|
||||
println!("number of empty volumes is {}", empty_volumes.len());
|
||||
|
||||
let mut memory_index = 6;
|
||||
// 0 - location for the maximum number of lights referenced per chunk (also will be the invalid memory allocation for pointing to a nonexistant neighbor)
|
||||
// 1 - location for the max iterations per light
|
||||
// 2 - diffuse raster samples (2*n + 1) * (2*n + 1) so as to always have at least the central fragment covered
|
||||
// 3 - diffuse raster size
|
||||
// 4 - max recursive rays
|
||||
// 5 - diffuse rays per hit
|
||||
for light in LightsIter::new(self) {
|
||||
light.borrow_mut().set_memory_start(memory_index);
|
||||
memory_index += light.borrow_mut().get_buffer_mem_size(data) as usize;
|
||||
|
||||
for light in &self.point_lights {
|
||||
self.memorizables.push(light.clone());
|
||||
}
|
||||
|
||||
for light in &self.directional_lights {
|
||||
self.memorizables.push(light.clone());
|
||||
}
|
||||
|
||||
for volume in &empty_volumes {
|
||||
volume.borrow_mut().set_memory_start(memory_index);
|
||||
memory_index += volume.borrow().get_buffer_mem_size(data) as usize;
|
||||
|
||||
self.memorizables.push(volume.clone());
|
||||
}
|
||||
|
||||
self.update_memory(data, false);
|
||||
|
||||
for volume in &empty_volumes {
|
||||
let quads = volume.borrow().to_quads();
|
||||
for quad in quads {
|
||||
quad.draw(&data.topology, self.rt_vertices.len(), self);
|
||||
}
|
||||
}
|
||||
println!("Memory size is {} kB, max indes is {}", memory_index * 32 / 8 /1024 + 1, memory_index);
|
||||
let mut volume_vec = vec![data.num_lights_per_volume; memory_index];
|
||||
volume_vec[1] = data.max_iterations_per_light;
|
||||
volume_vec[2] = data.diffuse_raster_steps;
|
||||
volume_vec[3] = u32::from_ne_bytes(data.diffuse_raster_size.to_ne_bytes());
|
||||
volume_vec[4] = data.max_recursive_rays;
|
||||
volume_vec[5] = data.diffuse_rays_per_hit;
|
||||
|
||||
for volume in &empty_volumes {
|
||||
volume_vec = volume.borrow().insert_into_memory(volume_vec, data, &self);
|
||||
}
|
||||
for light in LightsIter::new(self) {
|
||||
volume_vec = light.borrow().insert_into_memory(volume_vec, data, &self);
|
||||
}
|
||||
//println!("volume_vec print {:?}", volume_vec);
|
||||
|
||||
self.rt_memory = volume_vec;
|
||||
data.scene_rt_memory_size = (self.rt_memory.len() * 4) as u64; // size of the needed buffer size in bytes
|
||||
|
||||
if self.vertices.len() != 0 {
|
||||
(self.vertex_buffer_cube, self.vertex_buffer_memory_cube) = buffer::create_vertex_buffer(instance, device, &data, &self.vertices)?;
|
||||
|
@ -184,6 +165,55 @@ impl Scene {
|
|||
|
||||
}
|
||||
|
||||
pub fn is_dirty(&self) -> bool {
|
||||
for memorizable in &self.memorizables {
|
||||
if memorizable.borrow().is_dirty() {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
pub fn update_memory(&mut self, data: &mut AppData, reuse_memory: bool) {
|
||||
// reuse_memory controls whether a fresh data vector is created or the existing one is used if it is the right size
|
||||
let mut memory_index = 6;
|
||||
// 0 - location for the maximum number of lights referenced per chunk (also will be the invalid memory allocation for pointing to a nonexistant neighbor)
|
||||
// 1 - location for the max iterations per light
|
||||
// 2 - diffuse raster samples (2*n + 1) * (2*n + 1) so as to always have at least the central fragment covered
|
||||
// 3 - diffuse raster size
|
||||
// 4 - max recursive rays
|
||||
// 5 - diffuse rays per hit
|
||||
for memorizable in &self.memorizables {
|
||||
memorizable.borrow_mut().set_memory_start(memory_index);
|
||||
memory_index += memorizable.borrow_mut().get_buffer_mem_size(data) as usize;
|
||||
}
|
||||
|
||||
//println!("Memory size is {} kB, max indes is {}", memory_index * 32 / 8 /1024 + 1, memory_index);
|
||||
let mut volume_vec;
|
||||
let needs_overwrite;
|
||||
if !reuse_memory || memory_index != self.rt_memory.len() {
|
||||
volume_vec = vec![data.num_lights_per_volume; memory_index];
|
||||
needs_overwrite = true;
|
||||
} else {
|
||||
needs_overwrite = false;
|
||||
volume_vec = self.rt_memory.clone();
|
||||
}
|
||||
volume_vec[1] = data.max_iterations_per_light;
|
||||
volume_vec[2] = data.diffuse_raster_steps;
|
||||
volume_vec[3] = u32::from_ne_bytes(data.diffuse_raster_size.to_ne_bytes());
|
||||
volume_vec[4] = data.max_recursive_rays;
|
||||
volume_vec[5] = data.diffuse_rays_per_hit;
|
||||
|
||||
for memorizable in &self.memorizables {
|
||||
if needs_overwrite || memorizable.borrow().is_dirty() {
|
||||
volume_vec = memorizable.borrow_mut().insert_into_memory(volume_vec, data, &self);
|
||||
}
|
||||
}
|
||||
|
||||
self.rt_memory = volume_vec;
|
||||
data.scene_rt_memory_size = (self.rt_memory.len() * 4) as u64; // size of the needed buffer size in bytes
|
||||
}
|
||||
|
||||
pub unsafe fn destroy(&mut self, device: &vulkanalia::Device) {
|
||||
device.destroy_buffer(self.index_buffer_cube, None);
|
||||
device.free_memory(self.index_buffer_memory_cube, None);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue