diff --git a/build.rs b/build.rs
index 532b465..3a366b4 100644
--- a/build.rs
+++ b/build.rs
@@ -17,6 +17,8 @@ fn main() {
     println!("cargo::rerun-if-changed=shaders/rt_compute_rasterize.comp");
     println!("cargo::rerun-if-changed=shaders/rt_compute_grow_one.comp");
     println!("cargo::rerun-if-changed=shaders/rt_compute_grow_two.comp");
+    println!("cargo::rerun-if-changed=shaders/rt_compute_grow_three.comp");
+    println!("cargo::rerun-if-changed=shaders/rt_compute_combine.comp");
 
     std::fs::remove_file("shaders/compiled/geo_cube.spv").unwrap_or(());
     std::fs::remove_file("shaders/compiled/frag_cube.spv").unwrap_or(());
@@ -30,6 +32,7 @@ fn main() {
     std::fs::remove_file("shaders/compiled/rt_compute_grow_one.spv").unwrap_or(());
     std::fs::remove_file("shaders/compiled/rt_compute_grow_two.spv").unwrap_or(());
     std::fs::remove_file("shaders/compiled/rt_compute_grow_three.spv").unwrap_or(());
+    std::fs::remove_file("shaders/compiled/rt_compute_combine.spv").unwrap_or(());
 
     if std::env::consts::OS == "windows" {
         let mut command = Command::new("./shaders/compile.bat");
diff --git a/shaders/compile.bat b/shaders/compile.bat
index 50c3d62..bb4fe6a 100644
--- a/shaders/compile.bat
+++ b/shaders/compile.bat
@@ -12,4 +12,5 @@ C:/VulkanSDK/1.3.280.0/Bin/glslc.exe shaders/rt_quad.frag -o shaders/compiled/fr
 C:/VulkanSDK/1.3.280.0/Bin/glslc.exe shaders/rt_compute_rasterize.comp -o shaders/compiled/rt_compute_rasterize.spv
 C:/VulkanSDK/1.3.280.0/Bin/glslc.exe shaders/rt_compute_grow_one.comp -o shaders/compiled/rt_compute_grow_one.spv
 C:/VulkanSDK/1.3.280.0/Bin/glslc.exe shaders/rt_compute_grow_two.comp -o shaders/compiled/rt_compute_grow_two.spv
-C:/VulkanSDK/1.3.280.0/Bin/glslc.exe shaders/rt_compute_grow_three.comp -o shaders/compiled/rt_compute_grow_three.spv
\ No newline at end of file
+C:/VulkanSDK/1.3.280.0/Bin/glslc.exe shaders/rt_compute_grow_three.comp -o shaders/compiled/rt_compute_grow_three.spv
+C:/VulkanSDK/1.3.280.0/Bin/glslc.exe shaders/rt_compute_combine.comp -o shaders/compiled/rt_compute_combine.spv
\ No newline at end of file
diff --git a/shaders/compile.sh b/shaders/compile.sh
index 8f37a28..88be158 100755
--- a/shaders/compile.sh
+++ b/shaders/compile.sh
@@ -13,4 +13,5 @@ glslc shaders/rt_quad.frag -o shaders/compiled/frag_rt_quad.spv
 glslc shaders/rt_compute_rasterize.comp -o shaders/compiled/rt_compute_rasterize.spv
 glslc shaders/rt_compute_grow_one.comp -o shaders/compiled/rt_compute_grow_one.spv
 glslc shaders/rt_compute_grow_two.comp -o shaders/compiled/rt_compute_grow_two.spv
-glslc shaders/rt_compute_grow_three.comp -o shaders/compiled/rt_compute_grow_three.spv
\ No newline at end of file
+glslc shaders/rt_compute_grow_three.comp -o shaders/compiled/rt_compute_grow_three.spv
+glslc shaders/rt_compute_combine.comp -o shaders/compiled/rt_compute_combine.spv
\ No newline at end of file
diff --git a/shaders/compiled/rt_compute_combine.spv b/shaders/compiled/rt_compute_combine.spv
new file mode 100644
index 0000000..61fd2ee
Binary files /dev/null and b/shaders/compiled/rt_compute_combine.spv differ
diff --git a/shaders/rt_compute_combine.comp b/shaders/rt_compute_combine.comp
new file mode 100644
index 0000000..c70c19e
--- /dev/null
+++ b/shaders/rt_compute_combine.comp
@@ -0,0 +1,51 @@
+#version 450
+
+layout(binding = 0) uniform UniformBufferObject {
+    mat4 model;
+    mat4 geom_rot;
+    mat4 view;
+    mat4 proj;
+    vec3 camera_pos;
+    bool[16] use_geom_shader;
+} ubo;
+
+layout(binding = 3) readonly buffer CompoundBuffer {
+   uint compounds[];
+};
+
+layout(binding = 4) readonly buffer ColorBuffer {
+   uint grid_in[];
+};
+
+layout(binding = 9) readonly buffer TransparentBuffer {
+   bool transparent_grid[];
+};
+
+layout(binding = 8) buffer SizeBuffer3D {
+   uint grid_size_in[];
+};
+
+layout (local_size_x = 16, local_size_y = 1, local_size_z = 1) in;
+
+void main() {
+    uint index = gl_GlobalInvocationID.x;
+    uint output_offset = 0;
+    uint compound_start = 0;
+    // iterate over the compounds and find the work index inside of it
+    while (index > compounds[compound_start] * compounds[compound_start]) {
+        output_offset += compounds[compound_start] * compounds[compound_start] * compounds[compound_start] * 2;
+        index -= compounds[compound_start] * compounds[compound_start];
+        compound_start = compounds[compound_start + 2];
+    }
+    // grid pos in the task
+    uint compound_grid_size = compounds[compound_start];
+    float compound_scale = uintBitsToFloat(compounds[compound_start + 1]);
+    vec3 mid_offset = vec3(compound_scale * 0.5, compound_scale * 0.5, compound_scale * 0.5);
+    uint x = index % compound_grid_size;
+    uint y = ((index) % (compound_grid_size * compound_grid_size) - x) / (compound_grid_size);
+    uint z = (index - x - y * compound_grid_size) / (compound_grid_size * compound_grid_size);
+
+    uint size_x = grid_size_in[output_offset + (x * compound_grid_size * compound_grid_size + y * compound_grid_size + z) * 3];
+    uint size_y = grid_size_in[output_offset + (x * compound_grid_size * compound_grid_size + y * compound_grid_size + z) * 3 + 1];
+    uint size_z = grid_size_in[output_offset + (x * compound_grid_size * compound_grid_size + y * compound_grid_size + z) * 3 + 2];
+}
\ No newline at end of file
diff --git a/src/app_data.rs b/src/app_data.rs
index 6469600..0dafc31 100644
--- a/src/app_data.rs
+++ b/src/app_data.rs
@@ -27,6 +27,7 @@ pub struct AppData {
     pub pipeline_compute_grow_one: vk::Pipeline,
     pub pipeline_compute_grow_two: vk::Pipeline,
     pub pipeline_compute_grow_three: vk::Pipeline,
+    pub pipeline_compute_combine: vk::Pipeline,
 
     pub framebuffers: Vec<vk::Framebuffer>,
     pub command_pool: vk::CommandPool,
diff --git a/src/command_buffer.rs b/src/command_buffer.rs
index 3a70d1f..e477391 100644
--- a/src/command_buffer.rs
+++ b/src/command_buffer.rs
@@ -200,6 +200,35 @@ pub unsafe fn create_command_buffers(device: &Device, data: &mut app_data::AppDa
                 &[] as &[vk::MemoryBarrier],
                 &[buffer_memory_barrier_out],
                 &[] as &[vk::ImageMemoryBarrier]);
+
+            // combine element
+            device.cmd_bind_pipeline(
+                *command_buffer, vk::PipelineBindPoint::COMPUTE, data.pipeline_compute_combine);
+
+            device.cmd_bind_descriptor_sets(
+                *command_buffer, 
+                vk::PipelineBindPoint::COMPUTE, 
+                data.pipeline_layout, 
+                0, 
+                &[data.descriptor_sets[i]],
+                    &[]);
+            
+            device.cmd_dispatch(*command_buffer, (data.compute_task_one_size as f64 / 16.0).ceil() as u32, 1, 1);
+
+            let buffer_memory_barrier_out = vk::BufferMemoryBarrier::builder()
+                .buffer(data.render_storage_buffers[i])
+                .src_access_mask(vk::AccessFlags::SHADER_WRITE)
+                .dst_access_mask(vk::AccessFlags::SHADER_READ)
+                .size(vk::WHOLE_SIZE as u64)
+                .build();
+
+            device.cmd_pipeline_barrier(*command_buffer,
+                vk::PipelineStageFlags::COMPUTE_SHADER,
+                vk::PipelineStageFlags::FRAGMENT_SHADER,
+                vk::DependencyFlags::DEVICE_GROUP,
+                &[] as &[vk::MemoryBarrier],
+                &[buffer_memory_barrier_out],
+                &[] as &[vk::ImageMemoryBarrier]);
         }
         // start render pass
         let clear_values = &[color_clear_value, depth_clear_value];
diff --git a/src/main.rs b/src/main.rs
index 64de5c4..1b2714e 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -474,6 +474,7 @@ impl App {
         self.device.destroy_pipeline(self.data.pipeline_compute_grow_one, None);
         self.device.destroy_pipeline(self.data.pipeline_compute_grow_two, None);
         self.device.destroy_pipeline(self.data.pipeline_compute_grow_three, None);
+        self.device.destroy_pipeline(self.data.pipeline_compute_combine, None);
 
         self.device.destroy_pipeline_layout(self.data.pipeline_layout, None);
         self.device.destroy_render_pass(self.data.render_pass, None);
@@ -895,6 +896,16 @@ unsafe fn create_pipeline(device: &Device, data: &mut app_data::AppData) -> Resu
         .module(compute_shader_module_grow_three)
         .name(b"main\0");
 
+    // load the byte data
+    let compute_bytes = include_bytes!("../shaders/compiled/rt_compute_combine.spv");
+    // create the shaders
+    let compute_shader_module_combine = create_shader_module(device, &compute_bytes[..])?;
+    //create the shader stage for the compute shader
+    let compute_stage_combine = vk::PipelineShaderStageCreateInfo::builder()
+        .stage(vk::ShaderStageFlags::COMPUTE)
+        .module(compute_shader_module_combine)
+        .name(b"main\0");
+
     // 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 {
@@ -1051,7 +1062,11 @@ unsafe fn create_pipeline(device: &Device, data: &mut app_data::AppData) -> Resu
         .stage(compute_stage_grow_three)
         .layout(data.pipeline_layout);
 
-    let compute_pipelines = device.create_compute_pipelines(vk::PipelineCache::null(), &[info_compute_rasterize, info_compute_grow_one, info_compute_grow_two, info_compute_grow_three], None)?.0;
+    let info_compute_combine = vk::ComputePipelineCreateInfo::builder()
+        .stage(compute_stage_combine)
+        .layout(data.pipeline_layout);
+
+    let compute_pipelines = device.create_compute_pipelines(vk::PipelineCache::null(), &[info_compute_rasterize, info_compute_grow_one, info_compute_grow_two, info_compute_grow_three, info_compute_combine], None)?.0;
 
     data.pipeline_cube = pipelines[0];
     data.pipeline_cuboid = pipelines[1];
@@ -1061,6 +1076,7 @@ unsafe fn create_pipeline(device: &Device, data: &mut app_data::AppData) -> Resu
     data.pipeline_compute_grow_one = compute_pipelines[1];
     data.pipeline_compute_grow_two = compute_pipelines[2];
     data.pipeline_compute_grow_three = compute_pipelines[3];
+    data.pipeline_compute_combine = compute_pipelines[4];
 
     device.destroy_shader_module(vert_shader_module_cube, None);
     device.destroy_shader_module(geo_shader_module_cube, None);
@@ -1077,6 +1093,7 @@ unsafe fn create_pipeline(device: &Device, data: &mut app_data::AppData) -> Resu
     device.destroy_shader_module(compute_shader_module_grow_one, None);
     device.destroy_shader_module(compute_shader_module_grow_two, None);
     device.destroy_shader_module(compute_shader_module_grow_three, None);
+    device.destroy_shader_module(compute_shader_module_combine, None);
 
     Ok(())
 }