diff --git a/shaders/compile.bat b/shaders/compile.bat
index 27ac9c4..01e5f2c 100644
--- a/shaders/compile.bat
+++ b/shaders/compile.bat
@@ -4,4 +4,7 @@ C:/VulkanSDK/1.3.280.0/Bin/glslc.exe shaders/cube.geom -o shaders/geo_cube.spv
 
 C:/VulkanSDK/1.3.280.0/Bin/glslc.exe shaders/cuboid.vert -o shaders/vert_cuboid.spv
 C:/VulkanSDK/1.3.280.0/Bin/glslc.exe shaders/cuboid.frag -o shaders/frag_cuboid.spv
-C:/VulkanSDK/1.3.280.0/Bin/glslc.exe shaders/cuboid.geom -o shaders/geo_cuboid.spv
\ No newline at end of file
+C:/VulkanSDK/1.3.280.0/Bin/glslc.exe shaders/cuboid.geom -o shaders/geo_cuboid.spv
+
+C:/VulkanSDK/1.3.280.0/Bin/glslc.exe shaders/rt_quad.vert -o shaders/vert_rt_quad.spv
+C:/VulkanSDK/1.3.280.0/Bin/glslc.exe shaders/rt_quad.frag -o shaders/frag_rt_quad.spv
\ No newline at end of file
diff --git a/shaders/frag_rt_quad.spv b/shaders/frag_rt_quad.spv
new file mode 100644
index 0000000..50157c9
Binary files /dev/null and b/shaders/frag_rt_quad.spv differ
diff --git a/shaders/rt_quad.frag b/shaders/rt_quad.frag
new file mode 100644
index 0000000..ffaa3b5
--- /dev/null
+++ b/shaders/rt_quad.frag
@@ -0,0 +1,10 @@
+#version 450
+
+layout(location = 0) flat in uvec2 fragRasterPos;
+layout(location = 1) flat in uint fragVolumeStart;
+
+layout(location = 0) out vec4 outColor;
+
+void main() {
+    outColor = vec4(1, 0, 0, 1);
+}
\ No newline at end of file
diff --git a/shaders/rt_quad.vert b/shaders/rt_quad.vert
new file mode 100644
index 0000000..4b679a4
--- /dev/null
+++ b/shaders/rt_quad.vert
@@ -0,0 +1,27 @@
+#version 450
+
+layout(binding = 0) uniform UniformBufferObject {
+    mat4 model;
+    mat4 geom_rot;
+    mat4 view;
+    mat4 proj;
+    bool[16] use_geom_shader;
+} ubo;
+
+
+layout(location = 0) in vec3 inPosition;
+layout(location = 1) in uvec2 inRasterPos;
+layout(location = 2) in uint inVolumeStart;
+
+layout(location = 0) out uvec2 rasterPos;
+layout(location = 1) out uint volumeStart;
+
+void main() {
+    if (ubo.use_geom_shader[0]) {
+        gl_Position = ubo.geom_rot * ubo.model *  vec4(inPosition, 1.0);
+    } else {
+        gl_Position = ubo.proj * ubo.view * ubo.geom_rot * ubo.model *  vec4(inPosition, 1.0);
+    }
+    rasterPos = inRasterPos;
+    volumeStart = inVolumeStart;
+}
\ No newline at end of file
diff --git a/shaders/vert_rt_quad.spv b/shaders/vert_rt_quad.spv
new file mode 100644
index 0000000..62118cc
Binary files /dev/null and b/shaders/vert_rt_quad.spv differ
diff --git a/src/app_data.rs b/src/app_data.rs
index 71a99e6..fcf3f73 100644
--- a/src/app_data.rs
+++ b/src/app_data.rs
@@ -21,6 +21,7 @@ pub struct AppData {
     pub render_pass: vk::RenderPass,
     pub pipeline_cube: vk::Pipeline,
     pub pipeline_cuboid: vk::Pipeline,
+    pub pipeline_quad: vk::Pipeline,
     pub framebuffers: Vec<vk::Framebuffer>,
     pub command_pool: vk::CommandPool,
     pub command_buffers: Vec<vk::CommandBuffer>,
diff --git a/src/command_buffer.rs b/src/command_buffer.rs
index f9c5a68..050e21c 100644
--- a/src/command_buffer.rs
+++ b/src/command_buffer.rs
@@ -107,6 +107,26 @@ pub unsafe fn create_command_buffers(device: &Device, data: &mut app_data::AppDa
             device.cmd_draw_indexed(*command_buffer, scene_handler.indices_cuboid.len() as u32, 1, 0, 0, 0);
         }
 
+        if scene_handler.rt_vertices.len() != 0 {
+            device.cmd_bind_pipeline(
+                *command_buffer, vk::PipelineBindPoint::GRAPHICS, data.pipeline_quad); //todo build own pipeline
+        
+            device.cmd_bind_vertex_buffers(*command_buffer, 0, &[scene_handler.vertex_buffer_quad], &[0]);
+            device.cmd_bind_index_buffer(*command_buffer, scene_handler.index_buffer_quad, 0, vk::IndexType::UINT32);
+        
+        
+            device.cmd_bind_descriptor_sets(
+                *command_buffer,
+                vk::PipelineBindPoint::GRAPHICS,
+                data.pipeline_layout,
+                0,
+                &[data.descriptor_sets[i]],
+                &[],
+            );
+
+            device.cmd_draw_indexed(*command_buffer, scene_handler.indices_rt.len() as u32, 1, 0, 0, 0);
+        }
+
         device.cmd_end_render_pass(*command_buffer);
 
         device.end_command_buffer(*command_buffer)?;
diff --git a/src/main.rs b/src/main.rs
index 5fa20a9..1118eb0 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -365,6 +365,7 @@ impl App {
         self.device.free_command_buffers(self.data.command_pool, &self.data.command_buffers);
         self.device.destroy_pipeline(self.data.pipeline_cube, None);
         self.device.destroy_pipeline(self.data.pipeline_cuboid, None);
+        self.device.destroy_pipeline(self.data.pipeline_quad, None);
         self.device.destroy_pipeline_layout(self.data.pipeline_layout, None);
         self.device.destroy_render_pass(self.data.render_pass, None);
         self.data.swapchain_image_views
@@ -668,64 +669,93 @@ unsafe fn create_logical_device(
 }
 
 unsafe fn create_pipeline(device: &Device, data: &mut app_data::AppData) -> Result<()> {
+    // set up shaders for cubes
+    // load the byte data
     let vert_cube = include_bytes!("../shaders/vert_cube.spv");
     let geo_cube = include_bytes!("../shaders/geo_cube.spv");
     let frag_cube = include_bytes!("../shaders/frag_cube.spv");
-
+    // create the shaders
     let vert_shader_module_cube = create_shader_module(device, &vert_cube[..])?;
     let geo_shader_module_cube = create_shader_module(device, &geo_cube[..])?;
     let frag_shader_module_cube = create_shader_module(device, &frag_cube[..])?;
-
+    //create the shader stage for the vertex shader
     let vert_stage_cube = vk::PipelineShaderStageCreateInfo::builder()
         .stage(vk::ShaderStageFlags::VERTEX)
         .module(vert_shader_module_cube)
         .name(b"main\0");
-
+    //create the shader stage for the geometry shader
     let geo_stage_cube = vk::PipelineShaderStageCreateInfo::builder()
         .stage(vk::ShaderStageFlags::GEOMETRY)
         .module(geo_shader_module_cube)
         .name(b"main\0");
-
+    //create the shader stage for the fragment shader
     let frag_stage_cube = vk::PipelineShaderStageCreateInfo::builder()
         .stage(vk::ShaderStageFlags::FRAGMENT)
         .module(frag_shader_module_cube)
         .name(b"main\0");
-
+    // create the binding description for the cube vertex
     let binding_descriptions_cube = &[vertex::Vertex::binding_description()];
     let attribute_descriptions_cube = vertex::Vertex::attribute_descriptions();
     let vertex_input_state_cube = vk::PipelineVertexInputStateCreateInfo::builder()
         .vertex_binding_descriptions(binding_descriptions_cube)
         .vertex_attribute_descriptions(&attribute_descriptions_cube);
 
+    // set up shaders for cuboids
+    // load the byte data
     let vert_cuboid = include_bytes!("../shaders/vert_cuboid.spv");
     let geo_cuboid = include_bytes!("../shaders/geo_cuboid.spv");
     let frag_cuboid = include_bytes!("../shaders/frag_cuboid.spv");
-
+    // create the shaders
     let vert_shader_module_cuboid = create_shader_module(device, &vert_cuboid[..])?;
     let geo_shader_module_cuboid = create_shader_module(device, &geo_cuboid[..])?;
     let frag_shader_module_cuboid = create_shader_module(device, &frag_cuboid[..])?;
-
+    //create the shader stage for the vertex shader
     let vert_stage_cuboid = vk::PipelineShaderStageCreateInfo::builder()
         .stage(vk::ShaderStageFlags::VERTEX)
         .module(vert_shader_module_cuboid)
         .name(b"main\0");
-
+    //create the shader stage for the geometry shader
     let geo_stage_cuboid = vk::PipelineShaderStageCreateInfo::builder()
         .stage(vk::ShaderStageFlags::GEOMETRY)
         .module(geo_shader_module_cuboid)
         .name(b"main\0");
-
+    //create the shader stage for the fragment shader
     let frag_stage_cuboid = vk::PipelineShaderStageCreateInfo::builder()
         .stage(vk::ShaderStageFlags::FRAGMENT)
         .module(frag_shader_module_cuboid)
         .name(b"main\0");
-
+    // create the binding description for the sized vertex
     let binding_descriptions_cuboid = &[vertex::SizedVertex::binding_description()];
     let attribute_descriptions_cuboid = vertex::SizedVertex::attribute_descriptions();
     let vertex_input_state_cuboid = vk::PipelineVertexInputStateCreateInfo::builder()
         .vertex_binding_descriptions(binding_descriptions_cuboid)
         .vertex_attribute_descriptions(&attribute_descriptions_cuboid);
 
+    // set up shaders for quads/raytracing
+    // load the byte data
+    let vert_quad = include_bytes!("../shaders/vert_rt_quad.spv");
+    let frag_quad = include_bytes!("../shaders/frag_rt_quad.spv");
+    // create the shaders
+    let vert_shader_module_quad = create_shader_module(device, &vert_quad[..])?;
+    let frag_shader_module_quad = create_shader_module(device, &frag_quad[..])?;
+    //create the shader stage for the vertex shader
+    let vert_stage_quad = vk::PipelineShaderStageCreateInfo::builder()
+        .stage(vk::ShaderStageFlags::VERTEX)
+        .module(vert_shader_module_quad)
+        .name(b"main\0");
+    //create the shader stage for the fragment shader
+    let frag_stage_quad = vk::PipelineShaderStageCreateInfo::builder()
+        .stage(vk::ShaderStageFlags::FRAGMENT)
+        .module(frag_shader_module_quad)
+        .name(b"main\0");
+    // create the binding description for the quad vertex
+    let binding_descriptions_quad = &[vertex::RTVertex::binding_description()];
+    let attribute_descriptions_quad = vertex::RTVertex::attribute_descriptions();
+    let vertex_input_state_quad = vk::PipelineVertexInputStateCreateInfo::builder()
+        .vertex_binding_descriptions(binding_descriptions_quad)
+        .vertex_attribute_descriptions(&attribute_descriptions_quad);
+
+    // define input assembly and object type. This is altered when using geometry shader
     let mut topology = vk::PrimitiveTopology::TRIANGLE_LIST;
     if data.use_geometry_shader {
         topology = vk::PrimitiveTopology::POINT_LIST;
@@ -736,6 +766,7 @@ unsafe fn create_pipeline(device: &Device, data: &mut app_data::AppData) -> Resu
         .topology(topology)
         .primitive_restart_enable(false);
 
+    // define viewport and other transformations when projecting onto the screen
     let viewport = vk::Viewport::builder()
         .x(0.0)
         .y(0.0)
@@ -793,12 +824,13 @@ unsafe fn create_pipeline(device: &Device, data: &mut app_data::AppData) -> Resu
         .attachments(attachments)
         .blend_constants([0.0, 0.0, 0.0, 0.0]);
 
+    // define the work pipeline
     let set_layouts = &[data.descriptor_set_layout];
     let layout_info = vk::PipelineLayoutCreateInfo::builder()
         .set_layouts(set_layouts);
 
     data.pipeline_layout = device.create_pipeline_layout(&layout_info, None)?;
-
+    // define stages for the cubes pipeline
     let stages_cube = &[vert_stage_cube, frag_stage_cube];
     let stages_geom_cube = &[vert_stage_cube, geo_stage_cube,frag_stage_cube];
 
@@ -820,7 +852,7 @@ unsafe fn create_pipeline(device: &Device, data: &mut app_data::AppData) -> Resu
     else {
         info_cube = info_cube.stages(stages_cube);
     }
-
+    // define stages for the cuboid pipeline
     let stages_cuboid = &[vert_stage_cuboid, frag_stage_cuboid];
     let stages_geom_cuboid = &[vert_stage_cuboid, geo_stage_cuboid,frag_stage_cuboid];
 
@@ -842,11 +874,30 @@ unsafe fn create_pipeline(device: &Device, data: &mut app_data::AppData) -> Resu
     else {
         info_cuboid = info_cuboid.stages(stages_cuboid);
     }
+    // define stages for the quad/rt pipeline
+    let stages_quad = &[vert_stage_quad, frag_stage_quad];
 
-    let pipelines = device.create_graphics_pipelines(vk::PipelineCache::null(), &[info_cube, info_cuboid], None)?.0;
+    let mut info_quad = vk::GraphicsPipelineCreateInfo::builder()
+        .vertex_input_state(&vertex_input_state_quad)
+        .input_assembly_state(&input_assembly_state)
+        .viewport_state(&viewport_state)
+        .rasterization_state(&rasterization_state)
+        .multisample_state(&multisample_state)
+        .depth_stencil_state(&depth_stencil_state)
+        .color_blend_state(&color_blend_state)
+        .layout(data.pipeline_layout)
+        .render_pass(data.render_pass)
+        .subpass(0);
+
+
+    info_quad = info_quad.stages(stages_quad);
+
+    // create the pipeline
+    let pipelines = device.create_graphics_pipelines(vk::PipelineCache::null(), &[info_cube, info_cuboid, info_quad], None)?.0;
 
     data.pipeline_cube = pipelines[0];
     data.pipeline_cuboid = pipelines[1];
+    data.pipeline_quad = pipelines[2];
 
     device.destroy_shader_module(vert_shader_module_cube, None);
     device.destroy_shader_module(geo_shader_module_cube, None);
@@ -856,6 +907,9 @@ unsafe fn create_pipeline(device: &Device, data: &mut app_data::AppData) -> Resu
     device.destroy_shader_module(geo_shader_module_cuboid, None);
     device.destroy_shader_module(frag_shader_module_cuboid, None);
 
+    device.destroy_shader_module(vert_shader_module_quad, None);
+    device.destroy_shader_module(frag_shader_module_quad, None);
+
     Ok(())
 }
 
diff --git a/src/primitives/cube.rs b/src/primitives/cube.rs
index cfc75b4..fd27a1e 100644
--- a/src/primitives/cube.rs
+++ b/src/primitives/cube.rs
@@ -11,55 +11,57 @@ pub struct Cube{
     pub tex_coord: vertex::Vec2
 }
 
+const cube_size: f32 = 0.48;
+
 impl Drawable for Cube {
     fn draw(& self, topology: &vk::PrimitiveTopology, start_index: usize, scene: &mut Scene) {
         if *topology == vk::PrimitiveTopology::TRIANGLE_LIST {
             // 0 top left far
             scene.vertices.push(vertex::Vertex::new(
-                vec3(self.pos.x as f32 - 0.5, self.pos.y as f32 + 0.5, self.pos.z as f32 + 0.5),
+                vec3(self.pos.x as f32 - cube_size, self.pos.y as f32 + cube_size, self.pos.z as f32 + cube_size),
                 self.color,
                 self.tex_coord
             ));
             // 1 top right far
             scene.vertices.push(vertex::Vertex::new(
-                vec3(self.pos.x as f32 + 0.5, self.pos.y as f32 + 0.5, self.pos.z as f32 + 0.5),
+                vec3(self.pos.x as f32 + cube_size, self.pos.y as f32 + cube_size, self.pos.z as f32 + cube_size),
                 self.color,
                 self.tex_coord
             ));
             // 2 top left near
             scene.vertices.push(vertex::Vertex::new(
-                vec3(self.pos.x as f32 - 0.5, self.pos.y as f32 - 0.5, self.pos.z as f32 + 0.5),
+                vec3(self.pos.x as f32 - cube_size, self.pos.y as f32 - cube_size, self.pos.z as f32 + cube_size),
                 self.color,
                 self.tex_coord
             ));
             // 3 top right near
             scene.vertices.push(vertex::Vertex::new(
-                vec3(self.pos.x as f32 + 0.5, self.pos.y as f32 - 0.5, self.pos.z as f32 + 0.5),
+                vec3(self.pos.x as f32 + cube_size, self.pos.y as f32 - cube_size, self.pos.z as f32 + cube_size),
                 self.color,
                 self.tex_coord
             ));
 
             // 4 bottom left far
             scene.vertices.push(vertex::Vertex::new(
-                vec3(self.pos.x as f32 - 0.5, self.pos.y as f32 + 0.5, self.pos.z as f32 - 0.5),
+                vec3(self.pos.x as f32 - cube_size, self.pos.y as f32 + cube_size, self.pos.z as f32 - cube_size),
                 self.color,
                 self.tex_coord
             ));
             // 5 bottom right far
             scene.vertices.push(vertex::Vertex::new(
-                vec3(self.pos.x as f32 + 0.5, self.pos.y as f32 + 0.5, self.pos.z as f32 - 0.5),
+                vec3(self.pos.x as f32 + cube_size, self.pos.y as f32 + cube_size, self.pos.z as f32 - cube_size),
                 self.color,
                 self.tex_coord
             ));
             // 6 bottom left near
             scene.vertices.push(vertex::Vertex::new(
-                vec3(self.pos.x as f32 - 0.5, self.pos.y as f32 - 0.5, self.pos.z as f32 - 0.5),
+                vec3(self.pos.x as f32 - cube_size, self.pos.y as f32 - cube_size, self.pos.z as f32 - cube_size),
                 self.color,
                 self.tex_coord
             ));
             // 7 bottom right near
             scene.vertices.push(vertex::Vertex::new(
-                vec3(self.pos.x as f32 + 0.5, self.pos.y as f32 - 0.5, self.pos.z as f32 - 0.5),
+                vec3(self.pos.x as f32 + cube_size, self.pos.y as f32 - cube_size, self.pos.z as f32 - cube_size),
                 self.color,
                 self.tex_coord
             ));
diff --git a/src/primitives/mod.rs b/src/primitives/mod.rs
index 7b1f5d3..261af80 100644
--- a/src/primitives/mod.rs
+++ b/src/primitives/mod.rs
@@ -1,3 +1,4 @@
 pub mod cube;
 pub mod rec_cuboid;
+pub mod quad;
 pub mod drawable;
\ No newline at end of file
diff --git a/src/primitives/quad.rs b/src/primitives/quad.rs
new file mode 100644
index 0000000..0068e27
--- /dev/null
+++ b/src/primitives/quad.rs
@@ -0,0 +1,55 @@
+use vulkanalia::prelude::v1_0::*;
+use cgmath::vec3;
+use crate::vertex;
+use crate::scene::Scene;
+use crate::primitives::drawable::Drawable;
+
+#[derive(Clone, Debug, PartialEq)]
+pub struct Quad{
+    pub pos1: vertex::Vec3,
+    pub pos2: vertex::Vec3,
+    pub pos3: vertex::Vec3,
+    pub pos4: vertex::Vec3,
+    pub raster_pos: cgmath::Vector2<u32>,
+    pub volume_index: u32,
+}
+
+impl Drawable for Quad {
+    fn draw(& self, topology: &vk::PrimitiveTopology, start_index: usize, scene: &mut Scene) {
+        if *topology == vk::PrimitiveTopology::TRIANGLE_LIST {
+            // 0 top left far
+            scene.rt_vertices.push(vertex::RTVertex::new(
+                vec3(self.pos1.x as f32, self.pos1.y as f32, self.pos1.z as f32),
+                self.raster_pos,
+                self.volume_index
+            ));
+            // 1 top right far
+            scene.rt_vertices.push(vertex::RTVertex::new(
+                vec3(self.pos2.x as f32, self.pos2.y as f32, self.pos2.z as f32),
+                self.raster_pos,
+                self.volume_index
+            ));
+            // 2 top left near
+            scene.rt_vertices.push(vertex::RTVertex::new(
+                vec3(self.pos3.x as f32, self.pos3.y as f32, self.pos3.z as f32),
+                self.raster_pos,
+                self.volume_index
+            ));
+            // 3 top right near
+            scene.rt_vertices.push(vertex::RTVertex::new(
+                vec3(self.pos4.x as f32, self.pos4.y as f32, self.pos4.z as f32),
+                self.raster_pos,
+                self.volume_index
+            ));
+            
+            // top
+            scene.indices_rt.push(start_index as u32 + 2);
+            scene.indices_rt.push(start_index as u32 + 1);
+            scene.indices_rt.push(start_index as u32 + 0);
+
+            scene.indices_rt.push(start_index as u32 + 0);
+            scene.indices_rt.push(start_index as u32 + 3);
+            scene.indices_rt.push(start_index as u32 + 2);       
+        }
+    }
+}
\ No newline at end of file
diff --git a/src/scene.rs b/src/scene.rs
index f5bc778..2b12710 100644
--- a/src/scene.rs
+++ b/src/scene.rs
@@ -7,27 +7,32 @@ use cgmath::{vec2, vec3, Vector3};
 use std::cell::RefCell;
 use std::rc::Rc;
 
+use std::time::Instant;
+
 use crate::app_data::AppData;
 use crate::buffer;
 use crate::primitives::rec_cuboid::Cuboid;
 use crate::vertex;
 use crate::primitives::cube::Cube;
+use crate::primitives::quad::Quad;
 use crate::primitives::drawable::Drawable;
 
 extern crate rand;
 use rand::Rng;
 
-const CHUNK_SIZE_EXPONENT: u32 = 9;
+const CHUNK_SIZE_EXPONENT: u32 = 6;
 const CHUNK_SIZE: usize = (2 as usize).pow(CHUNK_SIZE_EXPONENT);
-const MAX_TREE_DEPTH: usize = 7;
+const MAX_TREE_DEPTH: usize = 4;
 const MIN_CHUNK_SIZE: usize = CHUNK_SIZE / (2 as usize).pow(MAX_TREE_DEPTH as u32);
 
 #[derive(Clone, Debug, Default)]
 pub struct Scene {
     pub vertices: Vec<vertex::Vertex>,
     pub sized_vertices: Vec<vertex::SizedVertex>,
+    pub rt_vertices: Vec<vertex::RTVertex>,
     pub indices_cube: Vec<u32>,
     pub indices_cuboid: Vec<u32>,
+    pub indices_rt: Vec<u32>,
 
     pub vertex_buffer_cube: vk::Buffer,
     pub vertex_buffer_memory_cube: vk::DeviceMemory,
@@ -40,18 +45,22 @@ pub struct Scene {
 
     pub index_buffer_cuboid: vk::Buffer,
     pub index_buffer_memory_cuboid: vk::DeviceMemory,
+
+    pub vertex_buffer_quad: vk::Buffer,
+    pub vertex_buffer_memory_quad: vk::DeviceMemory,
+
+    pub index_buffer_quad: vk::Buffer,
+    pub index_buffer_memory_quad: vk::DeviceMemory,
 }
 
 impl Scene {
     pub unsafe fn prepare_data(&mut self, instance: &vulkanalia::Instance, device: &vulkanalia::Device, data: &AppData) -> Result<()> {
         let mut rng = rand::thread_rng();
-        let grid_size = 512; //CHUNK_SIZE as i32;
+        let grid_size = CHUNK_SIZE as i32;
 
         // todo store the chunks somewhere (or only use them as intermediary for neighbouthood calculation idc)
         let mut oct_tree: OctTree<Cube> = OctTree::create(CHUNK_SIZE)?;
 
-        //todo use the 14 vertice box method. Not using geometry shaders seems to be faster... make this a setting?
-        // have cube elements with a method asking for vertices, while giving a primitive type -> method for preferred primitive type as well as one collecting all primitives
         for x_index in 0..grid_size {
             for y_index in 0..grid_size {
                 let shade = (rng.gen_range(0..25) as f32) / 100.0;
@@ -65,8 +74,18 @@ impl Scene {
             }
         }
 
-        let mut test = EmptyVolume::from_oct_tree(&oct_tree);
-        println!("number of empty volumes is {}", test.len());
+        let shade = (rng.gen_range(0..25) as f32) / 100.0;
+        let cube = Cube {
+            pos: vec3(10.0, 10.0, 10.0),
+            color: vec3(shade, 1.0, shade),
+            tex_coord: vec2(0.0, 0.0)
+        };
+
+        oct_tree.set_cube(cube.clone());
+
+        let mut empty_volumes: Vec<Rc<RefCell<EmptyVolume>>>;
+        (empty_volumes, _) = EmptyVolume::from_oct_tree(&oct_tree);
+        println!("number of empty volumes is {}", empty_volumes.len());
 
         let oct_tree_iter = OctTreeIter::create(&oct_tree)?;
         for item in  oct_tree_iter {
@@ -74,7 +93,7 @@ impl Scene {
             let index = self.vertices.len();
             match item {
                 Some(cube) => {
-                    if (cube.pos.x + cube.pos.y) as usize % 2 == 0{
+                    /*if (cube.pos.x + cube.pos.y) as usize % 2 == 0{
                         /**/
                         let cuboid = Cuboid {
                             pos: cube.pos,
@@ -86,11 +105,19 @@ impl Scene {
                     }
                     else {
                         cube.draw(&data.topology, index, self);
-                    }
+                    }*/
+                    cube.draw(&data.topology, index, self);
                 }
                 None => {}
             }
         }
+
+        for volume in empty_volumes {
+            let quads = volume.borrow().to_quads();
+            for quad in quads {
+                quad.draw(&data.topology, self.rt_vertices.len(), self);
+            }
+        }
         
         if self.vertices.len() != 0 {
             (self.vertex_buffer_cube, self.vertex_buffer_memory_cube) = buffer::create_vertex_buffer(instance, device, &data, &self.vertices)?;
@@ -102,6 +129,11 @@ impl Scene {
             (self.index_buffer_cuboid, self.index_buffer_memory_cuboid) = buffer::create_index_buffer(&instance, &device, &data, &self.indices_cuboid)?;
         }
 
+        if self.rt_vertices.len() != 0 {
+            (self.vertex_buffer_quad, self.vertex_buffer_memory_quad) = buffer::create_vertex_buffer(instance, device, &data, &self.rt_vertices)?;
+            (self.index_buffer_quad, self.index_buffer_memory_quad) = buffer::create_index_buffer(&instance, &device, &data, &self.indices_rt)?;
+        }
+
         Ok(())
 
     }
@@ -117,7 +149,13 @@ impl Scene {
         device.free_memory(self.index_buffer_memory_cuboid, None);
 
         device.destroy_buffer(self.vertex_buffer_cuboid, None);
-        device.free_memory(self.vertex_buffer_memory_cuboid, None);   
+        device.free_memory(self.vertex_buffer_memory_cuboid, None);
+
+        device.destroy_buffer(self.index_buffer_quad, None);
+        device.free_memory(self.index_buffer_memory_quad, None);
+
+        device.destroy_buffer(self.vertex_buffer_quad, None);
+        device.free_memory(self.vertex_buffer_memory_quad, None);   
     }
 }
 
@@ -617,22 +655,22 @@ struct EmptyVolume {
     pub color_back: Vec<Vector3<u8>>,
     pub color_top: Vec<Vector3<u8>>,
     pub color_bottom: Vec<Vector3<u8>>,
-    pub color_left: Vec<Vector3<u8>>,
-    pub color_right: Vec<Vector3<u8>>,
+    pub color_back_rn: Vec<Vector3<u8>>,
+    pub color_front_rn: Vec<Vector3<u8>>,
 
     pub roughness_front: Vec<Vector3<u8>>,
     pub roughness_back: Vec<Vector3<u8>>,
     pub roughness_top: Vec<Vector3<u8>>,
     pub roughness_bottom: Vec<Vector3<u8>>,
-    pub roughness_left: Vec<Vector3<u8>>,
-    pub roughness_right: Vec<Vector3<u8>>,
+    pub roughness_back_rn: Vec<Vector3<u8>>,
+    pub roughness_front_rn: Vec<Vector3<u8>>,
 
-    pub neighbor_front: Vec<Rc<RefCell<Self>>>,
-    pub neighbor_back: Vec<Rc<RefCell<Self>>>,
-    pub neighbor_top: Vec<Rc<RefCell<Self>>>,
-    pub neighbor_bottom: Vec<Rc<RefCell<Self>>>,
-    pub neighbor_left: Vec<Rc<RefCell<Self>>>,
-    pub neighbor_right: Vec<Rc<RefCell<Self>>>,
+    pub neighbor_front: Vec<Option<Rc<RefCell<Self>>>>,
+    pub neighbor_back: Vec<Option<Rc<RefCell<Self>>>>,
+    pub neighbor_top: Vec<Option<Rc<RefCell<Self>>>>,
+    pub neighbor_bottom: Vec<Option<Rc<RefCell<Self>>>>,
+    pub neighbor_back_rn: Vec<Option<Rc<RefCell<Self>>>>,
+    pub neighbor_front_rn: Vec<Option<Rc<RefCell<Self>>>>,
 }
 
 impl EmptyVolume {
@@ -642,11 +680,12 @@ impl EmptyVolume {
         self.position[2] + self.size_z > pos[2] && pos[2] >= self.position[2]
     }
 
-    pub fn from_oct_tree(tree: &OctTree<Cube>) -> Vec<Rc<RefCell<EmptyVolume>>> {
+    pub fn from_oct_tree(tree: &OctTree<Cube>) -> (Vec<Rc<RefCell<EmptyVolume>>>, OctTree<Rc<RefCell<EmptyVolume>>>) {
+        // todo: ppotentially use a child exist check while going through the oct tree to find some obvios starting empty volumes. Will still need to check for possible expansions though
         let mut volumes: Vec<Rc<RefCell<EmptyVolume>>> = vec![];
 
         let mut neighbors: OctTree<Rc<RefCell<EmptyVolume>>> = OctTree::create(tree.size).unwrap();
-
+        let start_time = Instant::now();
         // iterate over all block positions in the oct tree
         for x_index in 0..tree.size {
             for y_index in 0..tree.size {
@@ -664,6 +703,7 @@ impl EmptyVolume {
                             for volume in &volumes {
                                 if volume.borrow().contains(&Vector3{x: x_index, y: y_index, z: z_index}) {
                                     contained = true;
+                                    break;
                                 }
                             }
                             if contained {
@@ -736,20 +776,20 @@ impl EmptyVolume {
                                 color_back: vec![],
                                 color_top: vec![],
                                 color_bottom: vec![],
-                                color_left: vec![],
-                                color_right: vec![],
+                                color_back_rn: vec![],
+                                color_front_rn: vec![],
                                 roughness_front: vec![],
                                 roughness_back: vec![],
                                 roughness_top: vec![],
                                 roughness_bottom: vec![],
-                                roughness_left: vec![],
-                                roughness_right: vec![],
+                                roughness_back_rn: vec![],
+                                roughness_front_rn: vec![],
                                 neighbor_front: vec![],
                                 neighbor_back: vec![],
                                 neighbor_top: vec![],
                                 neighbor_bottom: vec![],
-                                neighbor_left: vec![],
-                                neighbor_right: vec![],
+                                neighbor_back_rn: vec![],
+                                neighbor_front_rn: vec![],
                             };
                             println!("adding neighbor references");
                             //fill in info in the neighbor octtree
@@ -757,12 +797,202 @@ impl EmptyVolume {
                             for x in 0..x_size+1 {
                                 for y in 0..y_size+1 {
                                     for z in 0..z_size+1 {
+                                        // fill only the edges
                                         if x == 0 || x == x_size || y == 0 || y == y_size || z==0 || z == z_size {
                                             neighbors.set_element(reference.clone(), reference.borrow().position.x + x, reference.borrow().position.y + y, reference.borrow().position.z + z)
                                         }
                                     }   
                                 }
                             }
+                            println!("add the border information for color and roughness");
+                            let x_min_pos;
+                            if reference.borrow().position.x == 0 {
+                                // will result in an empty color and roughness map.
+                                x_min_pos = 0;
+                            }
+                            else {
+                                x_min_pos = reference.borrow().position.x -1;
+                            }
+                            let y_min_pos;
+                            if reference.borrow().position.y == 0 {
+                                // will result in an empty color and roughness map.
+                                y_min_pos = 0;
+                            }
+                            else {
+                                y_min_pos = reference.borrow().position.y -1;
+                            }
+                            let z_min_pos;
+                            if reference.borrow().position.z == 0 {
+                                // will result in an empty color and roughness map.
+                                z_min_pos = 0;
+                            }
+                            else {
+                                z_min_pos = reference.borrow().position.z -1;
+                            }
+                            let x_max_pos = reference.borrow().position.x + reference.borrow().size_x;
+                            let y_max_pos = reference.borrow().position.y + reference.borrow().size_y;
+                            let z_max_pos = reference.borrow().position.z + reference.borrow().size_z;
+                            // bottom face of the volume
+                            let mut bottom_colors = vec![];
+                            let mut bottom_roughness = vec![];
+                            let mut bottom_elements_num = 0;
+                            for x in 0..x_size+1 {
+                                for y in 0..y_size+1 {
+                                    if let Some(c) = tree.get_element(reference.borrow().position.x + x, reference.borrow().position.y + y, z_min_pos) {
+                                        bottom_elements_num += 1;
+                                        let u8_color = Vector3 {x: (c.color * 255.0).x.min(255.0).max(0.0) as u8, y: (c.color * 255.0).y.min(255.0).max(0.0) as u8, z: (c.color * 255.0).z.min(255.0).max(0.0) as u8};
+                                        bottom_colors.push(u8_color);
+                                        bottom_roughness.push(Vector3 {x: 128, y: 128, z: 128});
+                                    }
+                                    else {
+                                        bottom_colors.push(Vector3 { x: 255, y: 255, z: 255 });
+                                        bottom_roughness.push(Vector3 {x: 255, y: 255, z: 255});
+                                    }
+                                }
+                            }
+                            if bottom_elements_num > 0 {
+                                reference.borrow_mut().color_bottom = bottom_colors;
+                                reference.borrow_mut().roughness_bottom = bottom_roughness;
+                            }
+                            else {
+                                reference.borrow_mut().color_bottom= vec![];
+                                reference.borrow_mut().roughness_bottom= vec![];
+                            }
+                            // top face of the volume
+                            let mut top_colors = vec![];
+                            let mut top_roughness = vec![];
+                            let mut top_elements_num = 0;
+                            for x in 0..x_size+1 {
+                                for y in 0..y_size+1 {
+                                    if let Some(c) = tree.get_element(reference.borrow().position.x + x, reference.borrow().position.y + y, z_max_pos) {
+                                        top_elements_num += 1;
+                                        let u8_color = Vector3 {x: (c.color * 255.0).x.min(255.0).max(0.0) as u8, y: (c.color * 255.0).y.min(255.0).max(0.0) as u8, z: (c.color * 255.0).z.min(255.0).max(0.0) as u8};
+                                        top_colors.push(u8_color);
+                                        top_roughness.push(Vector3 {x: 128, y: 128, z: 128});
+                                    }
+                                    else {
+                                        top_colors.push(Vector3 { x: 255, y: 255, z: 255 });
+                                        top_roughness.push(Vector3 {x: 255, y: 255, z: 255});
+                                    }
+                                }
+                            }
+                            if top_elements_num > 0 {
+                                reference.borrow_mut().color_top = top_colors;
+                                reference.borrow_mut().roughness_top = top_roughness;
+                            }
+                            else {
+                                reference.borrow_mut().color_top= vec![];
+                                reference.borrow_mut().roughness_top= vec![];
+                            }
+
+                            // back face of the volume
+                            let mut back_colors_rn = vec![];
+                            let mut back_roughness_rn = vec![];
+                            let mut back_elements_num_rn = 0;
+                            for x in 0..x_size+1 {
+                                for z in 0..z_size+1 {
+                                    if let Some(c) = tree.get_element(reference.borrow().position.x + x, y_max_pos, reference.borrow().position.z + z) {
+                                        back_elements_num_rn += 1;
+                                        let u8_color = Vector3 {x: (c.color * 255.0).x.min(255.0).max(0.0) as u8, y: (c.color * 255.0).y.min(255.0).max(0.0) as u8, z: (c.color * 255.0).z.min(255.0).max(0.0) as u8};
+                                        back_colors_rn.push(u8_color);
+                                        back_roughness_rn.push(Vector3 {x: 128, y: 128, z: 128});
+                                    }
+                                    else {
+                                        back_colors_rn.push(Vector3 { x: 255, y: 255, z: 255 });
+                                        back_roughness_rn.push(Vector3 {x: 255, y: 255, z: 255});
+                                    }
+                                }
+                            }
+                            if back_elements_num_rn > 0 {
+                                reference.borrow_mut().color_back_rn = back_colors_rn;
+                                reference.borrow_mut().roughness_back_rn = back_roughness_rn;
+                            }
+                            else {
+                                reference.borrow_mut().color_back_rn= vec![];
+                                reference.borrow_mut().roughness_back_rn= vec![];
+                            }
+
+                            // front face of the volume
+                            let mut front_colors_rn = vec![];
+                            let mut front_roughness_rn = vec![];
+                            let mut front_elements_num_rn = 0;
+                            for x in 0..x_size+1 {
+                                for z in 0..z_size+1 {
+                                    if let Some(c) = tree.get_element(reference.borrow().position.x + x, y_min_pos, reference.borrow().position.z + z) {
+                                        front_elements_num_rn += 1;
+                                        let u8_color = Vector3 {x: (c.color * 255.0).x.min(255.0).max(0.0) as u8, y: (c.color * 255.0).y.min(255.0).max(0.0) as u8, z: (c.color * 255.0).z.min(255.0).max(0.0) as u8};
+                                        front_colors_rn.push(u8_color);
+                                        front_roughness_rn.push(Vector3 {x: 128, y: 128, z: 128});
+                                    }
+                                    else {
+                                        front_colors_rn.push(Vector3 { x: 255, y: 255, z: 255 });
+                                        front_roughness_rn.push(Vector3 {x: 255, y: 255, z: 255});
+                                    }
+                                }
+                            }
+                            if front_elements_num_rn > 0 {
+                                reference.borrow_mut().color_front_rn = front_colors_rn;
+                                reference.borrow_mut().roughness_front_rn = front_roughness_rn;
+                            }
+                            else {
+                                reference.borrow_mut().color_front_rn= vec![];
+                                reference.borrow_mut().roughness_front_rn= vec![];
+                            }
+
+                            // front face of the volume
+                            let mut front_colors = vec![];
+                            let mut front_roughness = vec![];
+                            let mut front_elements_num = 0;
+                            for y in 0..y_size+1 {
+                                for z in 0..z_size+1 {
+                                    if let Some(c) = tree.get_element(x_min_pos, reference.borrow().position.y + y, reference.borrow().position.z + z) {
+                                        front_elements_num += 1;
+                                        let u8_color = Vector3 {x: (c.color * 255.0).x.min(255.0).max(0.0) as u8, y: (c.color * 255.0).y.min(255.0).max(0.0) as u8, z: (c.color * 255.0).z.min(255.0).max(0.0) as u8};
+                                        front_colors.push(u8_color);
+                                        front_roughness.push(Vector3 {x: 128, y: 128, z: 128});
+                                    }
+                                    else {
+                                        front_colors.push(Vector3 { x: 255, y: 255, z: 255 });
+                                        front_roughness.push(Vector3 {x: 255, y: 255, z: 255});
+                                    }
+                                }
+                            }
+                            if front_elements_num > 0 {
+                                reference.borrow_mut().color_front = front_colors;
+                                reference.borrow_mut().roughness_front = front_roughness;
+                            }
+                            else {
+                                reference.borrow_mut().color_front= vec![];
+                                reference.borrow_mut().roughness_front= vec![];
+                            }
+
+                            // back face of the volume
+                            let mut back_colors = vec![];
+                            let mut back_roughness = vec![];
+                            let mut back_elements_num = 0;
+                            for y in 0..y_size+1 {
+                                for z in 0..z_size+1 {
+                                    if let Some(c) = tree.get_element(x_max_pos, reference.borrow().position.y + y, reference.borrow().position.z + z) {
+                                        back_elements_num += 1;
+                                        let u8_color = Vector3 {x: (c.color * 255.0).x.min(255.0).max(0.0) as u8, y: (c.color * 255.0).y.min(255.0).max(0.0) as u8, z: (c.color * 255.0).z.min(255.0).max(0.0) as u8};
+                                        back_colors.push(u8_color);
+                                        back_roughness.push(Vector3 {x: 128, y: 128, z: 128});
+                                    }
+                                    else {
+                                        back_colors.push(Vector3 { x: 255, y: 255, z: 255 });
+                                        back_roughness.push(Vector3 {x: 255, y: 255, z: 255});
+                                    }
+                                }
+                            }
+                            if back_elements_num > 0 {
+                                reference.borrow_mut().color_back = back_colors;
+                                reference.borrow_mut().roughness_back = back_roughness;
+                            }
+                            else {
+                                reference.borrow_mut().color_back= vec![];
+                                reference.borrow_mut().roughness_back= vec![];
+                            }
+                            
                             println!("new volume done");
                             //push to the list
                             volumes.push(reference);
@@ -771,8 +1001,268 @@ impl EmptyVolume {
                 }
             }
         }
+        println!("add the neighbor linkage for all the volumes of the oct tree");
+        for reference in volumes.iter_mut() {
+            let x_min_pos;
+            if reference.borrow().position.x == 0 {
+                // will result in an empty color and roughness map.
+                x_min_pos = 0;
+            }
+            else {
+                x_min_pos = reference.borrow().position.x -1;
+            }
+            let y_min_pos;
+            if reference.borrow().position.y == 0 {
+                // will result in an empty color and roughness map.
+                y_min_pos = 0;
+            }
+            else {
+                y_min_pos = reference.borrow().position.y -1;
+            }
+            let z_min_pos;
+            if reference.borrow().position.z == 0 {
+                // will result in an empty color and roughness map.
+                z_min_pos = 0;
+            }
+            else {
+                z_min_pos = reference.borrow().position.z -1;
+            }
+            let x_max_pos = reference.borrow().position.x + reference.borrow().size_x;
+            let y_max_pos = reference.borrow().position.y + reference.borrow().size_y;
+            let z_max_pos = reference.borrow().position.z + reference.borrow().size_z;
+            // bottom face of the volume
+            let mut bottom_neighbors = vec![];
+            let mut bottom_elements_num = 0;
+            if z_min_pos != 0 {
+                for x in 0..reference.borrow().size_x {
+                    for y in 0..reference.borrow().size_y {
+                        if let Some(c) = neighbors.get_element(reference.borrow().position.x + x, reference.borrow().position.y + y, z_min_pos) {
+                            bottom_elements_num += 1;
+                            bottom_neighbors.push(Some(c.clone()));
+                        }
+                        else {
+                            bottom_neighbors.push(None);
+                        }
+                    }
+                }
+            }
+            if bottom_elements_num > 0 {
+                reference.borrow_mut().neighbor_bottom = bottom_neighbors;
+            }
+            else {
+                reference.borrow_mut().neighbor_bottom = vec![None];
+            }
+            // top face of the volume
+            let mut top_neighbors = vec![];
+            let mut top_elements_num = 0;
+            for x in 0..reference.borrow().size_x {
+                for y in 0..reference.borrow().size_y {
+                    if let Some(c) = neighbors.get_element(reference.borrow().position.x + x, reference.borrow().position.y + y, z_max_pos) {
+                        top_elements_num += 1;
+                        top_neighbors.push(Some(c.clone()));
+                    }
+                    else {
+                        top_neighbors.push(None);
+                    }
+                }
+            }
+            if top_elements_num > 0 {
+                reference.borrow_mut().neighbor_top = top_neighbors;
+            }
+            else {
+                reference.borrow_mut().neighbor_top = vec![None];
+            }
 
-        volumes
+            // left face of the volume
+            let mut back_neighbors_rn = vec![];
+            let mut back_elements_num_rn = 0;
+            for x in 0..reference.borrow().size_x {
+                for z in 0..reference.borrow().size_z {
+                    if let Some(c) = neighbors.get_element(reference.borrow().position.x + x, y_max_pos, reference.borrow().position.z + z) {
+                        back_elements_num_rn += 1;
+                        back_neighbors_rn.push(Some(c.clone()));
+                    }
+                    else {
+                        back_neighbors_rn.push(None);
+                    }
+                }
+            }
+            if back_elements_num_rn > 0 {
+                reference.borrow_mut().neighbor_back_rn = back_neighbors_rn;
+            }
+            else {
+                reference.borrow_mut().neighbor_back_rn = vec![None];
+            }
+
+            // right face of the volume
+            let mut front_neighbors_rn = vec![];
+            let mut front_elements_num_rn = 0;
+            if y_min_pos != 0{
+                for x in 0..reference.borrow().size_x {
+                    for z in 0..reference.borrow().size_z {
+                        if let Some(c) = neighbors.get_element(reference.borrow().position.x + x, y_min_pos, reference.borrow().position.z + z) {
+                            front_elements_num_rn += 1;
+                            front_neighbors_rn.push(Some(c.clone()));
+                        }
+                        else {
+                            front_neighbors_rn.push(None);
+                        }
+                    }
+                }
+            }
+            if front_elements_num_rn > 0 {
+                reference.borrow_mut().neighbor_front_rn = front_neighbors_rn;
+            }
+            else {
+                reference.borrow_mut().neighbor_front_rn = vec![None];
+            }
+
+            // front face of the volume
+            let mut front_neighbors = vec![];
+            let mut front_elements_num = 0;
+            if x_min_pos != 0 {
+                for y in 0..reference.borrow().size_y {
+                    for z in 0..reference.borrow().size_z {
+                        if let Some(c) = neighbors.get_element(x_min_pos, reference.borrow().position.y + y, reference.borrow().position.z + z) {
+                            front_elements_num += 1;
+                            front_neighbors.push(Some(c.clone()));
+                        }
+                        else {
+                            front_neighbors.push(None);
+                        }
+                    }
+                }
+            }
+            if front_elements_num > 0 {
+                reference.borrow_mut().neighbor_front = front_neighbors;
+            }
+            else {
+                reference.borrow_mut().neighbor_front = vec![None];
+            }
+
+            // back face of the volume
+            let mut back_neighbors = vec![];
+            let mut back_elements_num = 0;
+            for y in 0..reference.borrow().size_y {
+                for z in 0..reference.borrow().size_z {
+                    if let Some(c) = neighbors.get_element(x_max_pos, reference.borrow().position.y + y, reference.borrow().position.z + z) {
+                        back_elements_num += 1;
+                        back_neighbors.push(Some(c.clone()));
+                    }
+                    else {
+                        back_neighbors.push(None);
+                    }
+                }
+            }
+            if back_elements_num > 0 {
+                reference.borrow_mut().neighbor_back = back_neighbors;
+            }
+            else {
+                reference.borrow_mut().neighbor_back = vec![None];
+            }
+        }
+        println!("volume creation took {} s", start_time.elapsed().as_millis() as f32 / 1000.0);
+        (volumes, neighbors)
+    }
+
+    fn to_quads(&self) -> Vec<Quad> {
+        let mut quads = vec![];
+        let float_pos = Vector3 {x: self.position.x as f32, y: self.position.y as f32, z: self.position.z as f32};
+        //bottom sides of the volumes, top side of the block
+        for x in 0..self.size_x {
+            for y in 0..self.size_y {
+                let index = x * self.size_y + y;
+                if self.color_bottom.len() == 0 {
+                    continue;
+                }
+                if self.neighbor_bottom.len() > index {
+                    if let Some(_) = self.neighbor_bottom[index] {
+                        continue;
+                    }
+                }
+                let quad = Quad {
+                    pos1: float_pos + Vector3 { x: -0.5 + x as f32, y: -0.5 + y as f32, z: -0.5 },
+                    pos4: float_pos + Vector3 { x: 0.5 + x as f32, y: -0.5 + y as f32, z: -0.5 }, 
+                    pos3: float_pos + Vector3 { x: 0.5 + x as f32, y: 0.5 + y as f32, z: -0.5 }, 
+                    pos2: float_pos + Vector3 { x: -0.5 + x as f32, y: 0.5 + y as f32, z: -0.5 }, 
+                    raster_pos: cgmath::Vector2 { x: x as u32, y: y as u32 }, 
+                    volume_index: 0
+                };
+                quads.push(quad);
+            }
+        }
+        //top sides of the volumes, bottom side of the block
+        for x in 0..self.size_x {
+            for y in 0..self.size_y {
+                let index = x * self.size_y + y;
+                if self.color_top.len() == 0 {
+                    continue;
+                }
+                if self.neighbor_top.len() > index {
+                    if let Some(_) = self.neighbor_top[index] {
+                        continue;
+                    }
+                }
+                let quad = Quad {
+                    pos4: float_pos + Vector3 { x: -0.5 + x as f32, y: -0.5 + y as f32, z: self.size_z as f32 - 0.5 },
+                    pos1: float_pos + Vector3 { x: 0.5 + x as f32, y: -0.5 + y as f32, z: self.size_z as f32 - 0.5 }, 
+                    pos2: float_pos + Vector3 { x: 0.5 + x as f32, y: 0.5 + y as f32, z: self.size_z as f32 - 0.5 }, 
+                    pos3: float_pos + Vector3 { x: -0.5 + x as f32, y: 0.5 + y as f32, z: self.size_z as f32 - 0.5 }, 
+                    raster_pos: cgmath::Vector2 { x: x as u32, y: y as u32 }, 
+                    volume_index: 0
+                };
+                quads.push(quad);
+            }
+        }
+
+        //front sides of the volumes, back side of the block
+        for x in 0..self.size_x {
+            for z in 0..self.size_z {
+                let index = x * self.size_z + z;
+                if self.color_front_rn.len() == 0 {
+                    continue;
+                }
+                if self.neighbor_front_rn.len() > index {
+                    if let Some(_) = self.neighbor_front_rn[index] {
+                        continue;
+                    }
+                }
+                let quad = Quad {
+                    pos1: float_pos + Vector3 { x: -0.5 + x as f32, y: -0.5 + 0 as f32, z: z as f32 - 0.5 },
+                    pos4: float_pos + Vector3 { x: -0.5 + x as f32, y: -0.5 + 0 as f32, z: z as f32 + 0.5 }, 
+                    pos3: float_pos + Vector3 { x: 0.5 + x as f32, y: -0.5 + 0 as f32, z: z as f32 + 0.5 }, 
+                    pos2: float_pos + Vector3 { x: 0.5 + x as f32, y: -0.5 + 0 as f32, z: z as f32 - 0.5 }, 
+                    raster_pos: cgmath::Vector2 { x: x as u32, y: z as u32 }, 
+                    volume_index: 0
+                };
+                quads.push(quad);
+            }
+        }
+
+        //back sides of the volumes, front side of the block
+        for x in 0..self.size_x {
+            for z in 0..self.size_z {
+                let index = x * self.size_z + z;
+                if self.color_back_rn.len() == 0 {
+                    continue;
+                }
+                if self.neighbor_back_rn.len() > index {
+                    if let Some(_) = self.neighbor_back_rn[index] {
+                        continue;
+                    }
+                }
+                let quad = Quad {
+                    pos4: float_pos + Vector3 { x: -0.5 + x as f32, y: -0.5 + self.size_y as f32, z: z as f32 - 0.5 },
+                    pos1: float_pos + Vector3 { x: -0.5 + x as f32, y: -0.5 + self.size_y as f32, z: z as f32 + 0.5 }, 
+                    pos2: float_pos + Vector3 { x: 0.5 + x as f32, y: -0.5 + self.size_y as f32, z: z as f32 + 0.5 }, 
+                    pos3: float_pos + Vector3 { x: 0.5 + x as f32, y: -0.5 + self.size_y as f32, z: z as f32 - 0.5 }, 
+                    raster_pos: cgmath::Vector2 { x: x as u32, y: z as u32 }, 
+                    volume_index: 0
+                };
+                quads.push(quad);
+            }
+        }
+        quads
     }
 }
 
diff --git a/src/vertex.rs b/src/vertex.rs
index a94ddec..1d221de 100644
--- a/src/vertex.rs
+++ b/src/vertex.rs
@@ -161,4 +161,73 @@ impl Hash for SizedVertex {
         self.tex_coord[0].to_bits().hash(state);
         self.tex_coord[1].to_bits().hash(state);
     }
-}
\ No newline at end of file
+}
+
+#[repr(C)]
+#[derive(Copy, Clone, Debug)]
+pub struct RTVertex {
+    pub pos: Vec3,
+    pub raster_pos: cgmath::Vector2<u32>,
+    pub volume_start: u32,
+}
+
+impl RTVertex {
+    pub const fn new(pos: Vec3, raster_pos: cgmath::Vector2<u32>, volume_start: u32) -> Self {
+        Self { pos, raster_pos, volume_start }
+    }
+}
+impl VertexContainer<3> for RTVertex {
+    fn binding_description() -> vk::VertexInputBindingDescription {
+        vk::VertexInputBindingDescription::builder()
+            .binding(0)
+            .stride(size_of::<RTVertex>() as u32)
+            .input_rate(vk::VertexInputRate::VERTEX)
+            .build()
+    }
+
+    fn attribute_descriptions() -> [vk::VertexInputAttributeDescription; 3] {
+        let pos = vk::VertexInputAttributeDescription::builder()
+            .binding(0)
+            .location(0)
+            .format(vk::Format::R32G32B32_SFLOAT)
+            .offset(0)
+            .build();
+
+        let raster_pos = vk::VertexInputAttributeDescription::builder()
+            .binding(0)
+            .location(1)
+            .format(vk::Format::R32G32_UINT)
+            .offset(size_of::<Vec3>() as u32)
+            .build();
+        
+        let volume_start = vk::VertexInputAttributeDescription::builder()
+            .binding(0)
+            .location(2)
+            .format(vk::Format::R32_UINT)
+            .offset((size_of::<Vec3>() + size_of::<cgmath::Vector2<u32>>()) as u32)
+            .build();
+        [pos, raster_pos, volume_start]
+    }
+}
+
+
+impl PartialEq for RTVertex {
+    fn eq(&self, other: &Self) -> bool {
+        self.pos == other.pos
+            && self.raster_pos == other.raster_pos
+            && self.volume_start == other.volume_start
+    }
+}
+
+impl Eq for RTVertex {}
+
+impl Hash for RTVertex {
+    fn hash<H: Hasher>(&self, state: &mut H) {
+        self.pos[0].to_bits().hash(state);
+        self.pos[1].to_bits().hash(state);
+        self.pos[2].to_bits().hash(state);
+        self.raster_pos[0].hash(state);
+        self.raster_pos[1].hash(state);
+        self.volume_start.hash(state);
+    }
+}