diff --git a/src/main.rs b/src/main.rs
index 84a07ad..eca7b28 100644
--- a/src/main.rs
+++ b/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
         }
diff --git a/src/scene/empty_volume.rs b/src/scene/empty_volume.rs
index b7f2cb9..f3d851a 100644
--- a/src/scene/empty_volume.rs
+++ b/src/scene/empty_volume.rs
@@ -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 {
diff --git a/src/scene/generators.rs b/src/scene/generators.rs
index 9461344..3527dd0 100644
--- a/src/scene/generators.rs
+++ b/src/scene/generators.rs
@@ -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),
diff --git a/src/scene/light.rs b/src/scene/light.rs
index 9c64389..b15e77b 100644
--- a/src/scene/light.rs
+++ b/src/scene/light.rs
@@ -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);
     }
 }
\ No newline at end of file
diff --git a/src/scene/memorizable.rs b/src/scene/memorizable.rs
index 22d8519..2551a58 100644
--- a/src/scene/memorizable.rs
+++ b/src/scene/memorizable.rs
@@ -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);
 }
\ No newline at end of file
diff --git a/src/scene/mod.rs b/src/scene/mod.rs
index b9e7b91..fc72d62 100644
--- a/src/scene/mod.rs
+++ b/src/scene/mod.rs
@@ -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);