diff --git a/shaders/compiled/frag_rt_quad.spv b/shaders/compiled/frag_rt_quad.spv
index 8b8614a..9e46dcc 100644
Binary files a/shaders/compiled/frag_rt_quad.spv and b/shaders/compiled/frag_rt_quad.spv differ
diff --git a/shaders/rt_quad.frag b/shaders/rt_quad.frag
index 7094bd4..aca2709 100644
--- a/shaders/rt_quad.frag
+++ b/shaders/rt_quad.frag
@@ -149,11 +149,11 @@ uvec4 sample_color_from_scene_info(uint volume_start, uvec2 raster_pos, uint f)
 }
 
 vec3 get_light_position(uint light_index) {
-    return vec3(uintBitsToFloat(scene_info.infos[light_index]), uintBitsToFloat(scene_info.infos[light_index + 1]), uintBitsToFloat(scene_info.infos[light_index + 2]));
+    return vec3(uintBitsToFloat(scene_info.infos[light_index + 1]), uintBitsToFloat(scene_info.infos[light_index + 2]), uintBitsToFloat(scene_info.infos[light_index + 3]));
 }
 
 vec3 get_light_color(uint light_index) {
-    return vec3(float(scene_info.infos[light_index + 3]) / 255.0, float(scene_info.infos[light_index + 4]) / 255.0, float(scene_info.infos[light_index + 5]) / 255.0);
+    return vec3(float(scene_info.infos[light_index + 4]) / 255.0, float(scene_info.infos[light_index + 5]) / 255.0, float(scene_info.infos[light_index + 6]) / 255.0);
 }
 
 vec3 normal_for_facing(uint facing) {
@@ -377,7 +377,7 @@ vec3 get_lighting_color(uint volume_start, vec3 starting_pos, vec4 orig_color_sa
     uint light_num = 0;
 
     // initialize color
-    vec3 color_sum = vec3(0.0, 0.0, 0.0) + (orig_color_sample.xyz * 0.01);
+    vec3 color_sum = vec3(0.0, 0.0, 0.0);// + (orig_color_sample.xyz * 0.01);
 
     uint max_iterations = max_num_lights * max_iterations_per_light;
     uint iteration = 0;
@@ -388,10 +388,20 @@ vec3 get_lighting_color(uint volume_start, vec3 starting_pos, vec4 orig_color_sa
             // abort if there is no new light
             break;
         }
-        vec3 light_direction = get_light_position(light_index) - starting_pos;
+        vec3 light_direction;
+        float max_factor;
+        if (scene_info.infos[light_index] == 0) {
+            //point light
+            light_direction = get_light_position(light_index) - starting_pos;
+            max_factor = 1.0;
+        } else if (scene_info.infos[light_index] == 1) {
+            // directional light
+            light_direction = -normalize(get_light_position(light_index));
+            max_factor = pos_infinity;
+        }
         vec3 light_color = get_light_color(light_index);
 
-        Tracing result = trace_ray(volume_start, starting_pos, light_direction, 1.0, iteration, max_iterations, false);
+        Tracing result = trace_ray(volume_start, starting_pos, light_direction, max_factor, iteration, max_iterations, false);
         // add result, if there is a hit the null vector will be added
         color_sum += float(!result.has_hit) * result.color_mul * max(dot(normal, normalize(light_direction)), 0.0) * (orig_color_sample.xyz * light_color) / (length(light_direction) * length(light_direction));
         
diff --git a/src/main.rs b/src/main.rs
index a81a664..93958e3 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -190,7 +190,7 @@ impl App {
         let entry = Entry::new(loader).map_err(|b| anyhow!("{}", b))?;
         let mut data = app_data::AppData::default();
         data.use_geometry_shader = false;
-        data.num_lights_per_volume = 2;
+        data.num_lights_per_volume = 5;
         data.max_iterations_per_light = 20;
         data.diffuse_raster_steps = 0;
         data.diffuse_raster_size = 0.01;
@@ -218,9 +218,9 @@ impl App {
         create_framebuffers(&device, &mut data)?;
 
 
-        //image::create_texture_image(&instance, &device, &mut data)?;
-        //image::create_texture_image_view(&device, &mut data)?;
-        //image::create_texture_sampler(&device, &mut data)?;
+        image::create_texture_image(&instance, &device, &mut data)?;
+        image::create_texture_image_view(&device, &mut data)?;
+        image::create_texture_sampler(&device, &mut data)?;
         
         scene_handler.prepare_data(&instance, &device, &mut data)?;
 
diff --git a/src/scene/empty_volume.rs b/src/scene/empty_volume.rs
index 4c36e55..5277686 100644
--- a/src/scene/empty_volume.rs
+++ b/src/scene/empty_volume.rs
@@ -10,7 +10,12 @@ use crate::primitives::cube::Cube;
 use crate::primitives::quad::Quad;
 use crate::scene::oct_tree::OctTree;
 
+use super::memorizable::Memorizable;
+use super::light::LightSource;
 use super::light::PointLight;
+use super::AppData;
+use super::LightsIter;
+use super::Scene;
 
 pub struct EmptyVolume {
     pub memory_start: usize,
@@ -863,12 +868,37 @@ 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};
+        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()));
+        }
+        weighted_indices.sort_by(|a, b| a.0.partial_cmp(&b.0).unwrap());
+
+        let mut out_index = vec![];
+        for index in 0..weighted_indices.len() {
+            out_index.push(weighted_indices[weighted_indices.len() - (index + 1)].1 as u32);
+            if out_index.len() == light_number as usize {
+                break;
+            }
+        }
+        while out_index.len() < light_number as usize {
+            out_index.push(0);
+        }
+        out_index
+    }
+}
+
+impl Memorizable for EmptyVolume {
     // MARK: Get Buffer Mem Size
-    pub fn get_buffer_mem_size(&self, light_number: u32) -> u32 {
+    fn get_buffer_mem_size(&self,  data: &AppData) -> u32 {
         let mut mem_size: u32 = 0;
         mem_size += 3; //pos
         mem_size += 3; //max sizes
-        mem_size += light_number; // light references
+        mem_size += data.num_lights_per_volume; // light references
         mem_size += 12; //color/roughness buffer sizes, 2 values each
         mem_size += 12; //neighbor buffer sizes, 2 values each
 
@@ -890,7 +920,7 @@ impl EmptyVolume {
         mem_size
     }
     // MARK: insert into Memory
-    pub fn insert_into_memory(&self, mut v: Vec<u32>, light_number: u32, lights: &Vec<PointLight>) -> Vec<u32> {
+    fn insert_into_memory(&self, mut v: Vec<u32>, data: &AppData, scene: &Scene) -> Vec<u32> {
         let mut mem_index = self.memory_start;
         //pos
         v[mem_index] = self.position.x as u32;
@@ -907,7 +937,7 @@ impl EmptyVolume {
         v[mem_index] = self.size_z as u32;
         mem_index += 1;
         //Todo: insert lights
-        let selected_lights = self.select_lights(lights, light_number);
+        let selected_lights = self.select_lights(scene.get_light_iter(), data.num_lights_per_volume);
         for light in selected_lights {
             v[mem_index] = light;
             mem_index += 1;
@@ -1207,26 +1237,12 @@ impl EmptyVolume {
         v
     }
 
-    pub fn select_lights(&self, lights: &Vec<PointLight>, 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};
-        let mut weighted_indices = vec![];
-        for light in lights {
-            let weight = light.weighted_distance(center);
-            weighted_indices.push((weight, light.memory_start));
-        }
-        weighted_indices.sort_by(|a, b| a.0.partial_cmp(&b.0).unwrap());
+    fn get_memory_start(&self) -> usize {
+        self.memory_start
+    }
 
-        let mut out_index = vec![];
-        for index in 0..weighted_indices.len() {
-            out_index.push(weighted_indices[weighted_indices.len() - (index + 1)].1 as u32);
-            if out_index.len() == light_number as usize {
-                break;
-            }
-        }
-        while out_index.len() < light_number as usize {
-            out_index.push(0);
-        }
-        out_index
+    fn set_memory_start(&mut self, memory_start: usize) {
+        self.memory_start = memory_start;
     }
 }
 
diff --git a/src/scene/light.rs b/src/scene/light.rs
index 20a33ef..d6a4c82 100644
--- a/src/scene/light.rs
+++ b/src/scene/light.rs
@@ -1,6 +1,22 @@
 use cgmath::{InnerSpace, MetricSpace, Vector3};
 
 use crate::vertex;
+use super::memorizable::Memorizable;
+use super::AppData;
+use super::Scene;
+
+pub enum LightType {
+    POINT,
+    DIRECTION
+}
+
+pub trait Light {
+    fn get_light_type(&self) -> LightType;
+    fn weighted_distance(&self, center: Vector3<usize>) -> f32;
+}
+
+pub trait LightSource: Light + Memorizable {}
+
 
 #[derive(Clone, Debug, PartialEq)]
 pub struct PointLight{
@@ -9,26 +25,151 @@ pub struct PointLight{
     pub memory_start: usize,
 }
 
-impl PointLight {
-    pub fn get_buffer_mem_size(&self) -> u32 {
-        3 + 3
+impl Memorizable for PointLight {
+    fn get_buffer_mem_size(&self, data: &AppData) -> u32 {
+        1 + 3 + 3
     }
 
-    pub fn insert_into_memory(&self, mut v: Vec<u32>) -> Vec<u32> { 
-        v[self.memory_start] = u32::from_ne_bytes(self.pos.x.to_ne_bytes());
-        v[self.memory_start + 1] = u32::from_ne_bytes(self.pos.y.to_ne_bytes());
-        v[self.memory_start + 2] = u32::from_ne_bytes(self.pos.z.to_ne_bytes());
+    fn insert_into_memory(&self, mut v: Vec<u32>, data: &AppData, scene: &Scene) -> Vec<u32> { 
+        v[self.memory_start] = LightType::POINT as u32;
 
-        v[self.memory_start + 3] = (self.color.x * 255.0) as u32;
-        v[self.memory_start + 4] = (self.color.y * 255.0) as u32;
-        v[self.memory_start + 5] = (self.color.z * 255.0) as u32;
+        v[self.memory_start + 1] = u32::from_ne_bytes(self.pos.x.to_ne_bytes());
+        v[self.memory_start + 2] = u32::from_ne_bytes(self.pos.y.to_ne_bytes());
+        v[self.memory_start + 3] = u32::from_ne_bytes(self.pos.z.to_ne_bytes());
+
+        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;
         v
     }
 
-    pub fn weighted_distance(&self, center: Vector3<usize>) -> f32 {
+    fn get_memory_start(&self) -> usize {
+        self.memory_start
+    }
+
+    fn set_memory_start(&mut self, memory_start: usize) {
+        self.memory_start = memory_start;
+    }
+}
+
+impl Light for PointLight {
+    fn get_light_type(&self) -> LightType {
+        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});
         let light_intensity = self.color.magnitude();
 
         light_intensity / distance.powf(2.0)        
     }
+}
+
+impl LightSource for PointLight {}
+
+#[derive(Clone, Debug, PartialEq)]
+pub struct DirectionalLight{
+    pub direction: vertex::Vec3,
+    pub color: vertex::Vec3,
+    pub memory_start: usize,
+}
+
+impl Memorizable for DirectionalLight {
+    fn get_buffer_mem_size(&self, data: &AppData) -> u32 {
+        1 + 3 + 3
+    }
+
+    fn insert_into_memory(&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());
+        v[self.memory_start + 2] = u32::from_ne_bytes(self.direction.y.to_ne_bytes());
+        v[self.memory_start + 3] = u32::from_ne_bytes(self.direction.z.to_ne_bytes());
+
+        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;
+        v
+    }
+
+    fn get_memory_start(&self) -> usize {
+        self.memory_start
+    }
+
+    fn set_memory_start(&mut self, memory_start: usize) {
+        self.memory_start = memory_start;
+    }
+}
+
+impl Light for DirectionalLight {
+    fn get_light_type(&self) -> LightType {
+        LightType::DIRECTION
+    }
+
+    fn weighted_distance(&self, center: Vector3<usize>) -> f32 {
+        let light_intensity = self.color.magnitude();
+
+        light_intensity
+    }
+}
+
+impl LightSource for DirectionalLight {}
+
+#[cfg(test)]
+mod test {
+    use super::*;
+
+    #[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 data= AppData::default();
+        let scene = Scene::default();
+
+        let mem_size = p.get_buffer_mem_size(&data);
+        assert!(mem_size == 7);
+
+        let mut memory = vec![0; 7];
+        p.insert_into_memory(memory, &data, &scene);
+    }
+
+    #[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 data= AppData::default();
+        let scene = Scene::default();
+
+        let mem_size = p.get_buffer_mem_size(&data);
+        assert!(mem_size == 7);
+
+        let mut memory = vec![0; 6];
+        p.insert_into_memory(memory, &data, &scene);
+    }
+
+    #[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 data= AppData::default();
+        let scene = Scene::default();
+
+        let mem_size = p.get_buffer_mem_size(&data);
+        assert!(mem_size == 7);
+
+        let mut memory = vec![0; 7];
+        p.insert_into_memory(memory, &data, &scene);
+    }
+
+    #[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 data= AppData::default();
+        let scene = Scene::default();
+
+        let mem_size = p.get_buffer_mem_size(&data);
+        assert!(mem_size == 7);
+
+        let mut memory = vec![0; 6];
+        p.insert_into_memory(memory, &data, &scene);
+    }
 }
\ No newline at end of file
diff --git a/src/scene/memorizable.rs b/src/scene/memorizable.rs
new file mode 100644
index 0000000..22d8519
--- /dev/null
+++ b/src/scene/memorizable.rs
@@ -0,0 +1,10 @@
+use super::light::LightSource;
+use super::AppData;
+use super::Scene;
+
+pub trait Memorizable {
+    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_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 6672fc2..e9d19e7 100644
--- a/src/scene/mod.rs
+++ b/src/scene/mod.rs
@@ -1,8 +1,10 @@
 mod oct_tree;
 mod empty_volume;
 mod light;
+mod memorizable;
 
 use anyhow::Ok;
+use light::{DirectionalLight, LightSource};
 use vulkanalia::prelude::v1_0::*;
 use anyhow::Result;
 
@@ -11,6 +13,7 @@ use cgmath::{vec2, vec3, Vector3};
 use std::cell::RefCell;
 use std::rc::Rc;
 
+use crate::scene::memorizable::Memorizable;
 use crate::app_data::AppData;
 use crate::buffer;
 use crate::primitives::rec_cuboid::Cuboid;
@@ -54,7 +57,8 @@ pub struct Scene {
 
     pub rt_memory: Vec<u32>,
 
-    pub point_lights: Vec<PointLight>,
+    point_lights: Vec<Rc<RefCell<PointLight>>>,
+    directional_lights: Vec<Rc<RefCell<DirectionalLight>>>,
 }
 
 impl Scene {
@@ -99,8 +103,9 @@ impl Scene {
         };
         oct_tree.set_cube(cube.clone());
 
-        self.point_lights.push(PointLight { pos: vec3(11.0, 11.0, 11.0), color: vec3(1.0, 1.0, 1.0), memory_start: 0 });
-        self.point_lights.push(PointLight { pos: vec3(9.0, 9.0, 11.0), color: vec3(0.5, 0.5, 0.5), memory_start: 0 });
+        self.point_lights.push(Rc::new(RefCell::new(PointLight { pos: vec3(11.0, 11.0, 11.0), color: vec3(1.0, 1.0, 1.0), memory_start: 0 })));
+        self.point_lights.push(Rc::new(RefCell::new(PointLight { pos: vec3(9.0, 9.0, 11.0), color: vec3(0.5, 0.5, 0.5), memory_start: 0 })));
+        self.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 })));
 
         let empty_volumes: Vec<Rc<RefCell<EmptyVolume>>>;
         (empty_volumes, _) = EmptyVolume::from_oct_tree(&oct_tree);
@@ -156,14 +161,14 @@ impl Scene {
         // 3 - diffuse raster size
         // 4 - max recursive rays
         // 5 - diffuse rays per hit
-        for light in &mut self.point_lights {
-            light.memory_start = memory_index;
-            memory_index += light.get_buffer_mem_size() as usize;
+        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 volume in &empty_volumes {
-            volume.borrow_mut().memory_start = memory_index;
-            memory_index += volume.borrow().get_buffer_mem_size(data.num_lights_per_volume) as usize;
+            volume.borrow_mut().set_memory_start(memory_index);
+            memory_index += volume.borrow().get_buffer_mem_size(data) as usize;
 
         }
         for volume in &empty_volumes {
@@ -181,10 +186,10 @@ impl Scene {
         volume_vec[5] = data.diffuse_rays_per_hit;
         
         for volume in &empty_volumes {
-            volume_vec = volume.borrow().insert_into_memory(volume_vec, data.num_lights_per_volume, &self.point_lights);
+            volume_vec = volume.borrow().insert_into_memory(volume_vec, data, &self);
         }
-        for light in &self.point_lights {
-            volume_vec = light.insert_into_memory(volume_vec);
+        for light in LightsIter::new(self) {
+            volume_vec = light.borrow().insert_into_memory(volume_vec, data, &self);
         }
         //println!("volume_vec print {:?}", volume_vec);
 
@@ -229,4 +234,40 @@ impl Scene {
         device.destroy_buffer(self.vertex_buffer_quad, None);
         device.free_memory(self.vertex_buffer_memory_quad, None);   
     }
+
+    fn get_light_iter(&self) -> LightsIter {
+        LightsIter::new(self)
+    }
+}
+
+
+pub struct LightsIter<'a> {
+    light_index: usize,
+    scene: &'a Scene,
+}
+
+impl<'a> LightsIter<'a> {
+    fn new(scene: &'a Scene) -> Self {
+        LightsIter {light_index: 0, scene: scene}
+    }
+}
+
+impl<'a> Iterator for LightsIter<'a> {
+    type Item = Rc<RefCell<dyn LightSource>>;
+
+    fn next(&mut self) -> Option<Self::Item> {
+        if self.light_index >= self.scene.point_lights.len() {
+            if self.light_index - self.scene.point_lights.len() >= self.scene.directional_lights.len() {
+                None
+            } else {
+                let result = self.scene.directional_lights[self.light_index - self.scene.point_lights.len()].clone();
+                self.light_index += 1;
+                Some(result)
+            }
+        } else {
+            let result = self.scene.point_lights[self.light_index].clone();
+            self.light_index += 1;
+            Some(result)
+        }
+    }    
 }
\ No newline at end of file
diff --git a/src/scene/oct_tree.rs b/src/scene/oct_tree.rs
index 7b8212d..c9f94fa 100644
--- a/src/scene/oct_tree.rs
+++ b/src/scene/oct_tree.rs
@@ -601,7 +601,7 @@ mod test {
     #[test]
     fn test_oct_tree(){
         let mut test_tree: OctTree<Cube> = OctTree::create(512).unwrap();
-        let test_cube = Cube{color: Vector3 { x: 1.0, y: 0.0, z: 0.0 }, pos: Vector3 { x: 5.0, y: 2.0, z: 10.0 }, tex_coord: Vector2{x: 0.0, y: 0.0}, transparent: false};
+        let test_cube = Cube{color: Vector3 { x: 1.0, y: 0.0, z: 0.0 }, pos: Vector3 { x: 5.0, y: 2.0, z: 10.0 }, tex_coord: Vector2{x: 0.0, y: 0.0}, transparent: false, roughness: 128};
 
         test_tree.set_cube(test_cube.clone());