diff --git a/shaders/compiled/frag_rt_quad.spv b/shaders/compiled/frag_rt_quad.spv
index e1575e8..2c447ea 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 e9baaa8..82944b5 100644
--- a/shaders/rt_quad.frag
+++ b/shaders/rt_quad.frag
@@ -16,6 +16,10 @@ layout(binding = 0) uniform UniformBufferObject {
     bool[16] use_geom_shader;
 } ubo;
 
+// 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 (float, needs to be decoded)
 layout(binding = 2) buffer SceneInfoBuffer{
      uint infos[]; 
 } scene_info;
@@ -350,8 +354,8 @@ vec3 diffuse_tracing(uint volume_start, uvec2 raster_pos, vec3 pos, uint f) {
     vec3 normal = normal_for_facing(f);
 
     // diffuse raytracing using a quadratic raster of rays
-    int raster_half_steps = 0;
-    float raster_distance = 0.01;
+    int raster_half_steps = int(scene_info.infos[2]);
+    float raster_distance = uintBitsToFloat(scene_info.infos[3]);
     int raster_points = (2 * raster_half_steps + 1) * (2 * raster_half_steps + 1);
 
     vec3 color_sum = vec3(0.0, 0.0, 0.0);
@@ -389,18 +393,21 @@ vec3 clamp_to_volume(uint volume_start, vec3 position) {
 
 void main() {
     vec3 clamped_pos = clamp_to_volume(fragVolumeStart, origPosition);
+    uvec4 color_roughness = sample_color_from_scene_info(fragVolumeStart, fragRasterPos, facing);
+    vec3 orig_color_sample = vec3(float(color_roughness.x) / 255.0, float(color_roughness.y) / 255.0, float(color_roughness.z) / 255.0);
     vec3 color_sum = diffuse_tracing(fragVolumeStart, fragRasterPos, clamped_pos, facing);
 
     uint orig_neighbor = sample_neighbor_from_scene_info(fragVolumeStart, fragRasterPos, facing);
     if (orig_neighbor != 0) {
         float pos_infinity = uintBitsToFloat(0x7F800000);
         Tracing t = trace_ray(fragVolumeStart, ubo.camera_pos, clamped_pos - ubo.camera_pos, 100.0, 0, 20);
+        float opacity = float(color_roughness.w) / 255.0;
         if (t.has_hit) {
-            color_sum += diffuse_tracing(t.end_volume, t.end_raster, t.end_pos, t.end_facing);
+            color_sum = opacity * color_sum + (1.0 - opacity) * diffuse_tracing(t.end_volume, t.end_raster, t.end_pos, t.end_facing) * orig_color_sample;
         }
         else {
             // Todo: hit sky box
-            color_sum += vec3(0.0, 0.0, 0.0);
+            color_sum = opacity * color_sum + (1.0 - opacity) * vec3(0.0, 0.0, 0.0);
         }
         
     }
diff --git a/src/app_data.rs b/src/app_data.rs
index 91d507a..2464a26 100644
--- a/src/app_data.rs
+++ b/src/app_data.rs
@@ -60,6 +60,9 @@ pub struct AppData {
     pub topology: vk::PrimitiveTopology,
 
     pub scene_rt_memory_size: u64,
+    // values passed to shader
     pub num_lights_per_volume: u32,
     pub max_iterations_per_light: u32,
+    pub diffuse_raster_steps: u32,
+    pub diffuse_raster_size: f32,
 }
\ No newline at end of file
diff --git a/src/main.rs b/src/main.rs
index 2e8d209..2ac22ee 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -180,6 +180,8 @@ impl App {
         data.use_geometry_shader = false;
         data.num_lights_per_volume = 2;
         data.max_iterations_per_light = 20;
+        data.diffuse_raster_steps = 2;
+        data.diffuse_raster_size = 0.01;
         let mut scene_handler = scene::Scene::default();
         
         //load_model::load_model(&mut data)?;
diff --git a/src/primitives/cube.rs b/src/primitives/cube.rs
index 31a760e..6f7371d 100644
--- a/src/primitives/cube.rs
+++ b/src/primitives/cube.rs
@@ -10,6 +10,7 @@ pub struct Cube{
     pub color: vertex::Vec3,
     pub tex_coord: vertex::Vec2,
     pub transparent: bool,
+    pub roughness: u8,
 }
 
 const CUBE_SIZE: f32 = 0.5;
diff --git a/src/scene/empty_volume.rs b/src/scene/empty_volume.rs
index 7581195..1357e0a 100644
--- a/src/scene/empty_volume.rs
+++ b/src/scene/empty_volume.rs
@@ -50,9 +50,9 @@ impl EmptyVolume {
         self.position[2] + self.size_z > pos[2] && pos[2] >= self.position[2]
     }
 
-    fn check_transparent(cube_result: Option<Cube>, transparent_color: &Vector3<f32>) -> bool {
+    fn check_transparent(cube_result: Option<Cube>, transparent_color: &Vector3<f32>, transparent_roughness: &u8) -> bool {
         if let Some(c) = cube_result {
-            return c.transparent && &c.color == transparent_color
+            return c.transparent && &c.color == transparent_color && &c.roughness == transparent_roughness
         }
         false
     }
@@ -73,9 +73,11 @@ impl EmptyVolume {
                     let query_result = tree.test_element(x_index, y_index, z_index);
                     let mut transparent = false;
                     let mut transparent_color = Vector3 {x: 0.0, y: 0.0, z: 0.0};
+                    let mut tranparent_roughness = 0;
                     if let Some(c) = query_result.3 {
                         transparent = c.transparent;
                         transparent_color = c.color;
+                        tranparent_roughness = c.roughness;
                     }
                     if !query_result.0 || transparent {
                         
@@ -112,7 +114,7 @@ impl EmptyVolume {
                                 while z < z_size.max(1) && y < y_size.max(1) {
                                     let query_result = tree.test_element(x_index + x_size + 1, y_index + y, z_index + z);
                                     check_its += 1;
-                                    grow &= ((!query_result.0 && !transparent) || (transparent && EmptyVolume::check_transparent(query_result.3, &transparent_color))) &&
+                                    grow &= ((!query_result.0 && !transparent) || (transparent && EmptyVolume::check_transparent(query_result.3, &transparent_color, &tranparent_roughness))) &&
                                         neighbors.get_element(x_index + x_size + 1, y_index + y, z_index + z).is_none();
 
                                     if query_result.1 > 1 {
@@ -159,7 +161,7 @@ impl EmptyVolume {
                                 while z < z_size.max(1) && x < x_size.max(1) {
                                     let query_result = tree.test_element(x_index + x, y_index + y_size + 1, z_index + z);
                                     check_its += 1;
-                                    grow &= ((!query_result.0 && !transparent) || (transparent && EmptyVolume::check_transparent(query_result.3, &transparent_color))) &&
+                                    grow &= ((!query_result.0 && !transparent) || (transparent && EmptyVolume::check_transparent(query_result.3, &transparent_color, &tranparent_roughness))) &&
                                         neighbors.get_element(x_index + x, y_index + y_size + 1, z_index + z).is_none();
 
                                     if query_result.1 > 1 {
@@ -207,7 +209,7 @@ impl EmptyVolume {
                                 while y < y_size.max(1) && x < x_size.max(1) {
                                     let query_result = tree.test_element(x_index + x, y_index + y, z_index + z_size + 1);
                                     check_its += 1;
-                                    grow &= ((!query_result.0 && !transparent) || (transparent && EmptyVolume::check_transparent(query_result.3, &transparent_color))) &&
+                                    grow &= ((!query_result.0 && !transparent) || (transparent && EmptyVolume::check_transparent(query_result.3, &transparent_color, &tranparent_roughness))) &&
                                         neighbors.get_element(x_index + x, y_index + y, z_index + z_size + 1).is_none();
 
                                     if query_result.1 > 1 {
@@ -323,7 +325,7 @@ impl EmptyVolume {
                                     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(128);
+                                    bottom_roughness.push(c.roughness);
                                 }
                                 else {
                                     bottom_colors.push(Vector3 { x: 0, y: 0, z: 0 });
@@ -349,7 +351,7 @@ impl EmptyVolume {
                                     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(128);
+                                    top_roughness.push(c.roughness);
                                 }
                                 else {
                                     top_colors.push(Vector3 { x: 0, y: 0, z: 0 });
@@ -376,7 +378,7 @@ impl EmptyVolume {
                                     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(128);
+                                    back_roughness.push(c.roughness);
                                 }
                                 else {
                                     back_colors.push(Vector3 { x: 0, y: 0, z: 0 });
@@ -403,7 +405,7 @@ impl EmptyVolume {
                                     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(128);
+                                    front_roughness.push(c.roughness);
                                 }
                                 else {
                                     front_colors.push(Vector3 { x: 0, y: 0, z: 0 });
@@ -430,7 +432,7 @@ impl EmptyVolume {
                                     left_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};
                                     left_colors.push(u8_color);
-                                    left_roughness.push(128);
+                                    left_roughness.push(c.roughness);
                                 }
                                 else {
                                     left_colors.push(Vector3 { x: 0, y: 0, z: 0 });
@@ -457,7 +459,7 @@ impl EmptyVolume {
                                     right_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};
                                     right_colors.push(u8_color);
-                                    right_roughness.push(128);
+                                    right_roughness.push(c.roughness);
                                 }
                                 else {
                                     right_colors.push(Vector3 { x: 0, y: 0, z: 0 });
diff --git a/src/scene/mod.rs b/src/scene/mod.rs
index c5703a7..0ed0efb 100644
--- a/src/scene/mod.rs
+++ b/src/scene/mod.rs
@@ -73,6 +73,7 @@ impl Scene {
                     color: vec3(shade, 1.0, shade),
                     tex_coord: vec2(0.0, 0.0),
                     transparent: false,
+                    roughness: 128,
                 };
 
                 oct_tree.set_cube(cube.clone());
@@ -85,6 +86,7 @@ impl Scene {
             color: vec3(1.0, 0.0, 0.0),
             tex_coord: vec2(0.0, 0.0),
             transparent: true,
+            roughness: 32,
         };
         oct_tree.set_cube(cube.clone());
 
@@ -93,10 +95,11 @@ impl Scene {
             color: vec3(1.0, 0.0, 0.0),
             tex_coord: vec2(0.0, 0.0),
             transparent: true,
+            roughness: 32,
         };
         oct_tree.set_cube(cube.clone());
 
-        self.point_lights.push(PointLight { pos: vec3(11.0, 11.0, 11.0), color: vec3(0.5, 0.5, 0.5), memory_start: 0 });
+        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 });
 
         let empty_volumes: Vec<Rc<RefCell<EmptyVolume>>>;
@@ -146,9 +149,11 @@ impl Scene {
         let index = self.sized_vertices.len();
         cube.draw(&data.topology, index, self);
         
-        let mut memory_index = 2; 
+        let mut memory_index = 4; 
         // 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
         for light in &mut self.point_lights {
             light.memory_start = memory_index;
             memory_index += light.get_buffer_mem_size() as usize;
@@ -168,6 +173,8 @@ impl Scene {
         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());
         
         for volume in &empty_volumes {
             volume_vec = volume.borrow().insert_into_memory(volume_vec, data.num_lights_per_volume, &self.point_lights);