From fa6495e4cc0296b217dd9908c3257c7b5df01782 Mon Sep 17 00:00:00 2001
From: zomseffen <steffen@tom.bi>
Date: Wed, 4 Jun 2025 15:50:43 +0200
Subject: [PATCH] build shaders with placeholders

---
 build.rs                          |  28 +-
 shaders/compiled/frag_rt_quad.spv | Bin 74304 -> 75396 bytes
 shaders/rt_lib.frag               | 794 ++++++++++++++++++++++++++++++
 shaders/rt_quad.frag              |  25 +-
 shaders/rt_quad_placeholder.frag  |  51 ++
 5 files changed, 895 insertions(+), 3 deletions(-)
 create mode 100644 shaders/rt_lib.frag
 create mode 100644 shaders/rt_quad_placeholder.frag

diff --git a/build.rs b/build.rs
index 67aaf3a..4a669e3 100644
--- a/build.rs
+++ b/build.rs
@@ -2,6 +2,28 @@ use std::process::Command;
 use std::io::{self, Write};
 use std::path::Path;
 
+use std::fs::File;
+use std::io::{BufReader, BufRead, Error};
+
+fn insert_place_holders(path: &str) {
+    let input = File::open(path).unwrap();
+    let mut output = File::create(path.replace("_placeholder", "")).unwrap();
+    let buffered = BufReader::new(input);
+
+    for line in buffered.lines() {
+        let line_str = line.unwrap();
+        if line_str.contains("#include ") {
+            let replacer = File::open(format!("shaders/{}", line_str.clone().split_off(9))).expect(format!("could not find the lib file shaders/{}", line_str.clone().split_off(9)).as_str());
+            let replacement_buffered = BufReader::new(replacer);
+            for replacement_line in replacement_buffered.lines() {
+                write!(output, "{}\n", replacement_line.unwrap()).expect("could not write");
+            }
+        } else {
+            write!(output, "{}\n", line_str).expect("could not write");
+        }
+    }
+}
+
 fn main() {
     println!("cargo::rerun-if-changed=shaders/cube.frag");
     println!("cargo::rerun-if-changed=shaders/cube.geom");
@@ -12,7 +34,8 @@ fn main() {
     println!("cargo::rerun-if-changed=shaders/cuboid.vert");
 
     println!("cargo::rerun-if-changed=shaders/rt_quad.vert");
-    println!("cargo::rerun-if-changed=shaders/rt_quad.frag");
+    println!("cargo::rerun-if-changed=shaders/rt_lib.frag");
+    println!("cargo::rerun-if-changed=shaders/rt_quad_placeholder.frag");
 
     println!("cargo::rerun-if-changed=shaders/rt_compute_rasterize.comp");
     println!("cargo::rerun-if-changed=shaders/rt_compute_grow_one.comp");
@@ -20,6 +43,9 @@ fn main() {
     println!("cargo::rerun-if-changed=shaders/rt_compute_grow_three.comp");
     println!("cargo::rerun-if-changed=shaders/rt_compute_mempos.comp");
 
+    // replace placeholders
+    insert_place_holders("shaders/rt_quad_placeholder.frag");
+
     std::fs::remove_file("shaders/compiled/geo_cube.spv").unwrap_or(());
     std::fs::remove_file("shaders/compiled/frag_cube.spv").unwrap_or(());
     std::fs::remove_file("shaders/compiled/vert_cube.spv").unwrap_or(());
diff --git a/shaders/compiled/frag_rt_quad.spv b/shaders/compiled/frag_rt_quad.spv
index ff99d3f5c66a518a3a53221f0ae536d218268665..2cb51676fe4ce25969e602887b6c40c458704b28 100644
GIT binary patch
literal 75396
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
H=g<EDF?wh9

literal 74304
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

diff --git a/shaders/rt_lib.frag b/shaders/rt_lib.frag
new file mode 100644
index 0000000..bc293db
--- /dev/null
+++ b/shaders/rt_lib.frag
@@ -0,0 +1,794 @@
+layout(binding = 0) uniform UniformBufferObject {
+    mat4 model;
+    mat4 geom_rot;
+    mat4 view;
+    mat4 proj;
+    vec3 camera_pos;
+    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)
+// 4 - max recursive rays
+// 5 - diffuse rays per hit
+// 6 - maximum number of compounds per light
+layout(binding = 2) readonly buffer SceneInfoBuffer{
+     uint infos[]; 
+} scene_info;
+
+layout(binding = 3) readonly buffer CompoundBuffer {
+   uint compounds[];
+};
+
+layout(binding = 10) readonly buffer OctTreeMemory {
+   uint oct_tree_mem[];
+};
+
+uint max_num_lights = scene_info.infos[0];
+uint max_iterations_per_light = scene_info.infos[1];
+// diffuse raytracing using a quadratic raster of rays
+int half_diffuse_raster_steps = int(scene_info.infos[2]);
+float raster_distance = uintBitsToFloat(scene_info.infos[3]);
+int raster_points = (2 * half_diffuse_raster_steps + 1) * (2 * half_diffuse_raster_steps + 1);
+float pos_infinity = uintBitsToFloat(0x7F800000);
+// set limit for maximal iterations
+uint max_iterations = max_num_lights * max_iterations_per_light * raster_points;
+uint iteration_num = 0;
+uint max_num_compounds = scene_info.infos[6];
+
+uvec4 unpack_color(uint val) {
+    // left most 8 bits first
+    uint val1 = (val >> 24);
+    uint val2 = (val << 8) >> 24;
+    uint val3 = (val << 16) >> 24;
+    uint val4 = (val << 24) >> 24;
+
+    return uvec4(val4, val3, val2, val1);
+}
+
+uint array_descr_offset = 6 + max_num_lights + max_num_compounds;
+uint color_array_offset = 24 + 1;
+
+uint sample_neighbor_from_scene_info(uint volume_start, uvec2 raster_pos, uint f) {
+    uint array_descr_start = volume_start + array_descr_offset;
+    uint color_array_start = array_descr_start + color_array_offset;
+
+    uint top_color_size_u = scene_info.infos[array_descr_start];
+    uint top_color_size_v = scene_info.infos[array_descr_start + 1];
+
+    uint bottom_color_size_u = scene_info.infos[array_descr_start + 2];
+    uint bottom_color_size_v = scene_info.infos[array_descr_start + 3];
+
+    uint left_color_size_u = scene_info.infos[array_descr_start + 4];
+    uint left_color_size_v = scene_info.infos[array_descr_start + 5];
+
+    uint right_color_size_u = scene_info.infos[array_descr_start + 6];
+    uint right_color_size_v = scene_info.infos[array_descr_start + 7];
+
+    uint front_color_size_u = scene_info.infos[array_descr_start + 8];
+    uint front_color_size_v = scene_info.infos[array_descr_start + 9];
+
+    uint back_color_size_u = scene_info.infos[array_descr_start + 10];
+    uint back_color_size_v = scene_info.infos[array_descr_start + 11];
+
+    uint top_neighbor_size_u = scene_info.infos[array_descr_start + 12];
+    uint top_neighbor_size_v = scene_info.infos[array_descr_start + 13];
+
+    uint bottom_neighbor_size_u = scene_info.infos[array_descr_start + 14];
+    uint bottom_neighbor_size_v = scene_info.infos[array_descr_start + 15];
+
+    uint left_neighbor_size_u = scene_info.infos[array_descr_start + 16];
+    uint left_neighbor_size_v = scene_info.infos[array_descr_start + 17];
+
+    uint right_neighbor_size_u = scene_info.infos[array_descr_start + 18];
+    uint right_neighbor_size_v = scene_info.infos[array_descr_start + 19];
+
+    uint front_neighbor_size_u = scene_info.infos[array_descr_start + 20];
+    uint front_neighbor_size_v = scene_info.infos[array_descr_start + 21];
+
+    uint back_neighbor_size_u = scene_info.infos[array_descr_start + 22];
+    uint back_neighbor_size_v = scene_info.infos[array_descr_start + 23];
+
+    uint top_color_size = top_color_size_u * top_color_size_v;
+    uint bottom_color_size = bottom_color_size_u * bottom_color_size_v;
+    uint left_color_size = left_color_size_u * left_color_size_v;
+    uint right_color_size = right_color_size_u * right_color_size_v;
+    uint front_color_size = front_color_size_u * front_color_size_v;
+    uint back_color_size = back_color_size_u * back_color_size_v;
+
+    uint color_array_end = color_array_start + top_color_size + bottom_color_size + left_color_size + right_color_size + front_color_size + back_color_size;
+
+    uint top_neighbor_size = top_neighbor_size_u * top_neighbor_size_v;
+    uint bottom_neighbor_size = bottom_neighbor_size_u * bottom_neighbor_size_v;
+    uint left_neighbor_size = left_neighbor_size_u * left_neighbor_size_v;
+    uint right_neighbor_size = right_neighbor_size_u * right_neighbor_size_v;
+    uint front_neighbor_size = front_neighbor_size_u * front_neighbor_size_v;
+    uint back_neighbor_size = back_neighbor_size_u * back_neighbor_size_v;
+
+    // maybe do an array solution for this as well
+    uint array_start = color_array_end + uint(f > 0) * top_neighbor_size + uint(f > 1) * bottom_neighbor_size + uint(f > 2) * left_neighbor_size + uint(f > 3) * right_neighbor_size + uint(f > 4) * front_neighbor_size;
+    uint us[6] = {top_neighbor_size_u, bottom_neighbor_size_u, left_neighbor_size_u, right_neighbor_size_u, front_neighbor_size_u, back_neighbor_size_u};
+    uint vs[6] = {top_neighbor_size_v, bottom_neighbor_size_v, left_neighbor_size_v, right_neighbor_size_v, front_neighbor_size_v, back_neighbor_size_v};
+    uint u_size = us[f];
+    uint v_size = vs[f];
+    uint value = scene_info.infos[array_start + raster_pos.x * v_size * uint(u_size > 1) + raster_pos.y * uint(v_size > 1)];
+    return value; 
+}
+
+uint sample_neighbor_from_scene_info(uint volume_start, vec2 raster_pos, uint f) {
+    return sample_neighbor_from_scene_info(volume_start, uvec2(uint(floor(raster_pos.x)), uint(floor(raster_pos.y))), f);
+}
+
+uvec4 sample_color_from_scene_info(uint volume_start, uvec2 raster_pos, uint f) {
+    uint array_descr_start = volume_start + array_descr_offset;
+    uint color_array_start = array_descr_start + color_array_offset;
+
+    uint top_color_size_u = scene_info.infos[array_descr_start];
+    uint top_color_size_v = scene_info.infos[array_descr_start + 1];
+
+    uint bottom_color_size_u = scene_info.infos[array_descr_start + 2];
+    uint bottom_color_size_v = scene_info.infos[array_descr_start + 3];
+
+    uint left_color_size_u = scene_info.infos[array_descr_start + 4];
+    uint left_color_size_v = scene_info.infos[array_descr_start + 5];
+
+    uint right_color_size_u = scene_info.infos[array_descr_start + 6];
+    uint right_color_size_v = scene_info.infos[array_descr_start + 7];
+
+    uint front_color_size_u = scene_info.infos[array_descr_start + 8];
+    uint front_color_size_v = scene_info.infos[array_descr_start + 9];
+
+    uint back_color_size_u = scene_info.infos[array_descr_start + 10];
+    uint back_color_size_v = scene_info.infos[array_descr_start + 11];
+
+    uint top_size = top_color_size_u * top_color_size_v;
+    uint bottom_size = bottom_color_size_u * bottom_color_size_v;
+    uint left_size = left_color_size_u * left_color_size_v;
+    uint right_size = right_color_size_u * right_color_size_v;
+    uint front_size = front_color_size_u * front_color_size_v;
+    uint back_size = back_color_size_u * back_color_size_v;
+
+    // maybe do an array solution for this as well
+    uint array_start = color_array_start + uint(f > 0) * top_size + uint(f > 1) * bottom_size + uint(f > 2) * left_size + uint(f > 3) * right_size + uint(f > 4) * front_size;
+    uint us[6] = {top_color_size_u, bottom_color_size_u, left_color_size_u, right_color_size_u, front_color_size_u, back_color_size_u};
+    uint vs[6] = {top_color_size_v, bottom_color_size_v, left_color_size_v, right_color_size_v, front_color_size_v, back_color_size_v};
+    uint u_size = us[f];
+    uint v_size = vs[f];
+    uint value = scene_info.infos[array_start + clamp(raster_pos.x, 0, u_size) * v_size * uint(u_size > 1) + clamp(raster_pos.y, 0, v_size) * uint(v_size > 1)];
+    return unpack_color(value); 
+}
+
+uvec4 sample_color_from_scene_info(uint volume_start, vec2 raster_pos, uint f) {
+    return sample_color_from_scene_info(volume_start, uvec2(uint(floor(raster_pos.x)), uint(floor(raster_pos.y))), f);
+}
+
+vec3 get_light_position(uint light_index) {
+    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 + 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) {
+    if (facing == 0) {
+        return vec3(0.0, 0.0, -1.0);
+    }
+    if (facing == 1) {
+        return vec3(0.0, 0.0, 1.0);
+    }
+    if (facing == 2) {
+        return vec3(1.0, 0.0, 0.0);
+    }
+    if (facing == 3) {
+        return vec3(-1.0, 0.0, 0.0);
+    }
+    if (facing == 4) {
+        return vec3(0.0, 1.0, 0.0);
+    }
+    if (facing == 5) {
+        return vec3(0.0, -1.0, 0.0);
+    }
+
+    return vec3(0.0, 0.0, 0.0);
+}
+
+vec3 reflect_vector(vec3 direction, uint facing) {
+    vec3 normal = normal_for_facing(facing);
+    return direction - 2.0 * dot(direction, normal) * normal;
+}
+
+uvec3 parent_child_vec(uint child_size, uint child_index) {
+    if (child_index == 1) {
+        return uvec3(0, 0, 0);
+    }
+    if (child_index == 2) {
+        return uvec3(child_size, 0, 0);
+    }
+    if (child_index == 3) {
+        return uvec3(0, child_size, 0);
+    }
+    if (child_index == 4) {
+        return uvec3(child_size, child_size, 0);
+    }
+    if (child_index == 5) {
+        return uvec3(0, 0, child_size);
+    }
+    if (child_index == 6) {
+        return uvec3(child_size, 0, child_size);
+    }
+    if (child_index == 7) {
+        return uvec3(0, child_size, child_size);
+    }
+    if (child_index == 8) {
+        return uvec3(child_size, child_size, child_size);
+    }
+    return uvec3(0, 0, 0);
+}
+
+uint next_oct_tree_child(vec3 mid_point, vec3 check_pos, bool child_open[8]) {
+    if (check_pos.x <= mid_point.x && check_pos.y <= mid_point.y && check_pos.z <= mid_point.z && child_open[0]) {
+        return 1;
+    }
+    if (check_pos.x >= mid_point.x && check_pos.y <= mid_point.y && check_pos.z <= mid_point.z && child_open[1]) {
+        return 2;
+    }
+    if (check_pos.x <= mid_point.x && check_pos.y >= mid_point.y && check_pos.z <= mid_point.z && child_open[2]) {
+        return 3;
+    }
+    if (check_pos.x >= mid_point.x && check_pos.y >= mid_point.y && check_pos.z <= mid_point.z && child_open[3]) {
+        return 4;
+    }
+    if (check_pos.x <= mid_point.x && check_pos.y <= mid_point.y && check_pos.z >= mid_point.z && child_open[4]) {
+        return 5;
+    }
+    if (check_pos.x >= mid_point.x && check_pos.y <= mid_point.y && check_pos.z >= mid_point.z && child_open[5]) {
+        return 6;
+    }
+    if (check_pos.x <= mid_point.x && check_pos.y >= mid_point.y && check_pos.z >= mid_point.z && child_open[6]) {
+        return 7;
+    }
+    if (check_pos.x >= mid_point.x && check_pos.y >= mid_point.y && check_pos.z >= mid_point.z && child_open[7]) {
+        return 8;
+    }
+
+    return 0; // return to parent
+}
+
+struct Tracing {
+    vec3 end_pos;
+    uvec4 end_color;
+    uint end_volume;
+    uint end_facing;
+    float end_factor;
+    uint end_cycle;
+    bool has_hit;
+    vec3 color_mul;
+    uvec2 end_raster;
+
+    vec3 end_direction;
+    bool has_transparent_hit;
+};
+
+Tracing trace_ray(uint volume_start, vec3 starting_pos, vec3 start_direction, float start_max_factor, bool allow_reflect) {
+    vec3 direction = start_direction;
+    float max_factor = start_max_factor;
+    vec3 pos = starting_pos;
+    // setup volume info
+    uint volume_index = volume_start;
+    float volume_scale = uintBitsToFloat(scene_info.infos[volume_index + array_descr_offset + color_array_offset - 1]);
+    float volume_pos_x = uintBitsToFloat(scene_info.infos[volume_index + 0]); 
+    float volume_pos_y = uintBitsToFloat(scene_info.infos[volume_index + 1]); 
+    float volume_pos_z = uintBitsToFloat(scene_info.infos[volume_index + 2]); 
+
+    bool x_pos = direction.x > 0.0;
+    bool x_null = (direction.x == 0.0);
+    
+    bool y_pos = direction.y > 0.0;
+    bool y_null = (direction.y == 0.0);
+
+    bool z_pos = direction.z > 0.0;
+    bool z_null = (direction.z == 0.0);
+
+    // default is max factor, that way we avoid collision when going parallel to an axis. The other directions will score a hit
+    float x_factor = max_factor;
+    float y_factor = max_factor;
+    float z_factor = max_factor;
+
+    Tracing result;
+    result.has_hit = false;
+    result.has_transparent_hit = false;
+    result.color_mul = vec3(1.0, 1.0, 1.0);
+
+    // intermediate storage for transparent hit values
+    vec3 end_pos_transparent;
+    uvec4 end_color_transparent;
+    uint end_volume_transparent;
+    uint end_facing_transparent;
+    uvec2 end_raster_transparent;
+    vec3 color_mul_transparent;
+
+    uint next_volumetric_index = 0;
+    uint[5] done_volumetrics;
+    for (int i=0; i < 5; i++) {
+        done_volumetrics[i] = 0;
+    }
+
+    while (iteration_num < max_iterations) {
+        iteration_num ++;
+
+        uint compound_num = 0;
+        while (scene_info.infos[volume_index + 6 + max_num_lights + compound_num] != 0 && compound_num < max_num_compounds && iteration_num < max_iterations && !result.has_hit) {
+            uint compound_start = scene_info.infos[volume_index + 6 + max_num_lights + compound_num];
+            
+            bool already_checked = false;
+            for (int i=0; i < 5; i++) {
+                if (compound_start == done_volumetrics[i]) {
+                    already_checked = true;
+                    break;
+                }
+            }            
+            if (already_checked) {
+                compound_num += 1;
+                continue;
+            }
+            done_volumetrics[next_volumetric_index] = compound_start;
+            next_volumetric_index = (next_volumetric_index + 1) % 5;
+
+            //iteration_num ++;
+            uint oct_tree_index = compounds[compound_start + 8];
+            uint compound_grid_size = compounds[compound_start];
+            float compound_scale = uintBitsToFloat(compounds[compound_start + 1]);
+            vec3 compound_pos = vec3(uintBitsToFloat(compounds[compound_start + 5]), uintBitsToFloat(compounds[compound_start + 6]), uintBitsToFloat(compounds[compound_start + 7]));
+            // check if we hit the volume
+            float x_border = compound_pos.x + float((compound_grid_size) * uint(!x_pos)) * compound_scale;
+            float y_border = compound_pos.y + float((compound_grid_size) * uint(!y_pos)) * compound_scale;
+            float z_border = compound_pos.z + float((compound_grid_size) * uint(!z_pos)) * compound_scale;
+
+            // go over the borders by this amount
+            float overstep = 0.00001 / length(direction);
+
+            if (!x_null) {
+                x_factor = (x_border - pos.x) / direction.x;
+            } else {
+                x_factor = max_factor;
+            }
+            if (!y_null) {
+                y_factor = (y_border - pos.y) / direction.y;
+            } else {
+                y_factor = max_factor;
+            }
+            if (!z_null) {
+                z_factor = (z_border - pos.z) / direction.z;
+            } else {
+                z_factor = max_factor;
+            }
+            x_factor += overstep;
+            y_factor += overstep;
+            z_factor += overstep;
+
+            vec3 intersection_pos = pos;
+            bool is_x_hit = false;
+            bool is_y_hit = false;
+            bool is_z_hit = false;
+            bool hit_inside = false;
+            if ((compound_pos.x <= intersection_pos.x && intersection_pos.x <= compound_pos.x + float(compound_grid_size) * compound_scale) && 
+                (compound_pos.y <= intersection_pos.y && intersection_pos.y <= compound_pos.y + float(compound_grid_size) * compound_scale) && 
+                (compound_pos.z <= intersection_pos.z && intersection_pos.z <= compound_pos.z + float(compound_grid_size) * compound_scale)){
+                //hit_inside = true;
+            } else {
+                vec3 intersection_pos_x = pos + x_factor * direction;
+                vec3 intersection_pos_y = pos + y_factor * direction;
+                vec3 intersection_pos_z = pos + z_factor * direction;
+                if ((compound_pos.x <= intersection_pos_x.x && intersection_pos_x.x <= compound_pos.x + float(compound_grid_size) * compound_scale) && 
+                    (compound_pos.y <= intersection_pos_x.y && intersection_pos_x.y <= compound_pos.y + float(compound_grid_size) * compound_scale) && 
+                    (compound_pos.z <= intersection_pos_x.z && intersection_pos_x.z <= compound_pos.z + float(compound_grid_size) * compound_scale) && x_factor > 0.0 && x_factor <= max_factor) {
+                    hit_inside = true;
+                    is_x_hit = true;
+                    intersection_pos = intersection_pos_x;
+                }
+                    
+                if ((compound_pos.x <= intersection_pos_y.x && intersection_pos_y.x <= compound_pos.x + float(compound_grid_size) * compound_scale) && 
+                    (compound_pos.y <= intersection_pos_y.y && intersection_pos_y.y <= compound_pos.y + float(compound_grid_size) * compound_scale) && 
+                    (compound_pos.z <= intersection_pos_y.z && intersection_pos_y.z <= compound_pos.z + float(compound_grid_size) * compound_scale) && y_factor > 0.0 && y_factor <= max_factor && (y_factor < x_factor || !is_x_hit)) {
+                    hit_inside = true;
+                    is_y_hit = true;
+                    intersection_pos = intersection_pos_y;
+                }
+                        
+                if ((compound_pos.x <= intersection_pos_z.x && intersection_pos_z.x <= compound_pos.x + float(compound_grid_size) * compound_scale) && 
+                    (compound_pos.y <= intersection_pos_z.y && intersection_pos_z.y <= compound_pos.y + float(compound_grid_size) * compound_scale) && 
+                    (compound_pos.z <= intersection_pos_z.z && intersection_pos_z.z <= compound_pos.z + float(compound_grid_size) * compound_scale) && z_factor > 0.0 && z_factor <= max_factor && (z_factor < x_factor || !is_x_hit) && (z_factor < y_factor || !is_y_hit)) {
+                    hit_inside = true;
+                    is_z_hit = true;
+                    intersection_pos = intersection_pos_z;
+                }
+            }
+
+            // check that either the hit is in range or we are inside of the compound from the start
+            if (hit_inside) {
+                vec3 oct_tree_pos = vec3(compound_pos);
+                uint current_size = compound_grid_size;
+                vec3 mid_point = oct_tree_pos + float(current_size / 2) * vec3(compound_scale, compound_scale, compound_scale);
+                bool children_open[8] = {true, true, true, true, true, true, true, true};
+                uint oct_tree_address = oct_tree_index;
+                // iterate through the oct_tree
+                uint check_it = 0;
+                uint max_check_it = 60;
+                uint prev_child = 0;
+                uint prev_prev_child = 0;
+
+                uvec3 grid_pos = uvec3(0, 0, 0);
+                uvec3 parent_pos = uvec3(0, 0, 0);
+
+                bool has_moved = false;
+                while (!result.has_hit && check_it < max_check_it) {
+                    // failsafe to get out in case has_moved runs into an accuracy issue
+                    check_it ++;
+                    oct_tree_pos = vec3(grid_pos) * compound_scale + compound_pos;
+                    mid_point = oct_tree_pos + (float(current_size / 2) * vec3(compound_scale, compound_scale, compound_scale));
+
+                    uint child_index = next_oct_tree_child(mid_point, intersection_pos, children_open);
+                    if (child_index == 0) {
+                        // go up to parent
+                        // if parent is 0 abort, as we have reached the root node again and try to exit it
+                        if (oct_tree_mem[oct_tree_address] == 0) {
+                            break;
+                        }
+                        for (int i=0; i < 8; i++) {
+                            children_open[i] = true;
+                        }
+                        uint parent_index = oct_tree_mem[oct_tree_address];
+                        // check which child we came from
+                        child_index = 1 * uint(oct_tree_address == oct_tree_mem[parent_index + 1]) + 2 * uint(oct_tree_address == oct_tree_mem[parent_index + 2]) + 3 * uint(oct_tree_address == oct_tree_mem[parent_index + 3]) + 4 * uint(oct_tree_address == oct_tree_mem[parent_index + 4]) + 5 * uint(oct_tree_address == oct_tree_mem[parent_index + 5]) + 6 * uint(oct_tree_address == oct_tree_mem[parent_index + 6]) + 7 * uint(oct_tree_address == oct_tree_mem[parent_index + 7]) + 8 * uint(oct_tree_address == oct_tree_mem[parent_index + 8]);
+                        // mark as done to avoid reinvestigating, since intersection_pos is on its edge                        
+                        children_open[child_index - 1] = false;
+                        prev_prev_child = prev_child;
+                        prev_child = oct_tree_address;
+
+                        uvec3 back_vec = parent_child_vec(current_size, child_index);
+                        grid_pos -= parent_child_vec(current_size, child_index);
+                        current_size *= 2;
+                        oct_tree_address = parent_index;
+                    } else {
+                        // go down into child
+                        if (current_size == 2) {
+                            // check block if hit break
+                            if (oct_tree_mem[oct_tree_address + child_index] != 0) {
+                                result.has_hit = true;
+                                result.end_color = unpack_color(oct_tree_mem[oct_tree_address + child_index]);
+                                break;
+                            }                            
+                        } else {
+                            // check if the child has content, else skip to next child of current parent
+                            uint x = oct_tree_mem[oct_tree_address + child_index];
+                            if (oct_tree_mem[x] != 0) {
+                                // change base address and position to child
+                                current_size /= 2;
+                                oct_tree_address = x;
+                                grid_pos += parent_child_vec(current_size, child_index);
+                                for (int i=0; i < 8; i++) {
+                                    children_open[i] = true;
+                                }
+                                continue;
+                            }
+                        }
+                        children_open[child_index - 1] = false;
+                        
+                        // we did not go deeper or had a hit, so intersection pos needs to be updated
+                        // new intersection pos calc
+                        vec3 offset = vec3(parent_child_vec(current_size / 2, child_index)) * compound_scale;
+                        vec3 low = oct_tree_pos + offset;
+                        float x_border = low.x + float((compound_scale * current_size / 2) * uint(x_pos));
+                        float y_border = low.y + float((compound_scale * current_size / 2) * uint(y_pos));
+                        float z_border = low.z + float((compound_scale * current_size / 2) * uint(z_pos));
+
+                        if (!x_null) {
+                            x_factor = (x_border - pos.x) / direction.x;
+                            if (x_factor <= 0.0) {
+                                x_factor = max_factor;
+                            }
+                        } else {
+                            x_factor = max_factor;
+                        }
+                        if (!y_null) {
+                            y_factor = (y_border - pos.y) / direction.y;
+                            if (y_factor <= 0.0) {
+                                y_factor = max_factor;
+                            }
+                        } else {
+                            y_factor = max_factor;
+                        }
+                        if (!z_null) {
+                            z_factor = (z_border - pos.z) / direction.z;
+                            if (z_factor <= 0.0) {
+                                z_factor = max_factor;
+                            }
+                        } else {
+                            z_factor = max_factor;
+                        }
+                        float smallest_factor = min(min(x_factor, y_factor), z_factor);
+
+                        if (x_factor == smallest_factor) {
+                            is_x_hit = true;
+                            is_y_hit = false;
+                            is_z_hit = false;
+                        }
+                        if (y_factor == smallest_factor) {
+                            is_x_hit = false;
+                            is_y_hit = true;
+                            is_z_hit = false;
+                        }
+                        if (z_factor == smallest_factor) {
+                            is_x_hit = false;
+                            is_y_hit = false;
+                            is_z_hit = true;
+                        }
+
+                        // move a bit further to fully enter the next quadrant 
+                        smallest_factor += overstep;
+
+                        //has_moved = length(intersection_pos - (pos + smallest_factor * direction)) >= 0.00001;
+                        has_moved = intersection_pos != (pos + smallest_factor * direction);
+                        intersection_pos = pos + smallest_factor * direction;
+                    }
+                }
+
+                uint hit_facing = uint(is_x_hit) * (2 + uint(x_pos)) + uint(is_y_hit) * (4 + uint(y_pos)) + uint(is_z_hit && !z_pos);
+                //result.has_hit = true;
+                result.end_pos = intersection_pos;
+                result.end_facing = hit_facing;
+                result.end_volume = volume_index;
+                result.end_direction = direction;
+            }
+
+            compound_num += 1;
+        }
+
+        if (result.has_hit) {
+            break;
+        }
+
+        float x_border = volume_pos_x + float((scene_info.infos[volume_index + 3]) * uint(x_pos)) * volume_scale - 0.5 * volume_scale;
+        float y_border = volume_pos_y + float((scene_info.infos[volume_index + 4]) * uint(y_pos)) * volume_scale - 0.5 * volume_scale;
+        float z_border = volume_pos_z + float((scene_info.infos[volume_index + 5]) * uint(z_pos)) * volume_scale - 0.5 * volume_scale;
+        
+        bool needs_next_light = false;
+
+        if (!x_null) {
+            x_factor = (x_border - pos.x) / direction.x;
+        } else {
+            x_factor = max_factor;
+        }
+        if (!y_null) {
+            y_factor = (y_border - pos.y) / direction.y;
+        } else {
+            y_factor = max_factor;
+        }
+        if (!z_null) {
+            z_factor = (z_border - pos.z) / direction.z;
+        } else {
+            z_factor = max_factor;
+        }
+
+        if ((x_factor >= max_factor) && (y_factor >= max_factor) && (z_factor >= max_factor)) {
+            // no hit, finish tracking
+            break;
+        } else {
+            // if there is a border hit before reaching the end
+            // change to the relevant next volume
+            // Todo: look into removing ifs from this
+            uint hit_facing = 0;
+            uint u = 0;
+            uint v = 0;
+
+            bool is_x_smallest = x_factor < y_factor && x_factor < z_factor;
+            bool is_y_smallest = y_factor < x_factor && y_factor < z_factor;
+            bool is_z_smallest = z_factor <= x_factor && z_factor <= y_factor;
+
+            hit_facing = uint(is_x_smallest) * (2 + uint(x_pos)) + uint(is_y_smallest) * (4 + uint(y_pos)) + uint(is_z_smallest && !z_pos);
+            float smallest_factor = min(min(x_factor, y_factor), z_factor); // maybe use multiplication instead?
+            vec3 intersection_pos = pos + smallest_factor * direction;
+            u = uint(is_x_smallest) * (uint(round((intersection_pos.y - volume_pos_y) / volume_scale))) + 
+                uint(is_y_smallest || is_z_smallest) * (uint(round((intersection_pos.x - volume_pos_x) / volume_scale)));
+            v = uint(is_x_smallest || is_y_smallest) * (uint(round((intersection_pos.z - volume_pos_z) / volume_scale))) +
+                uint(is_z_smallest) * (uint(round((intersection_pos.y - volume_pos_y) / volume_scale)));
+
+            uint next_neighbor = sample_neighbor_from_scene_info(volume_index, uvec2(u, v), hit_facing);
+            uvec4 color_sample = sample_color_from_scene_info(volume_index, uvec2(u, v), hit_facing);
+
+            if (color_sample.xyz == uvec3(0, 0, 0)) {
+                // not a color hit, so check neighbor
+                if (next_neighbor != 0) {
+                    volume_index = next_neighbor;
+                    volume_scale = uintBitsToFloat(scene_info.infos[volume_index + array_descr_offset + color_array_offset - 1]);
+                    volume_pos_x = uintBitsToFloat(scene_info.infos[volume_index + 0]); 
+                    volume_pos_y = uintBitsToFloat(scene_info.infos[volume_index + 1]); 
+                    volume_pos_z = uintBitsToFloat(scene_info.infos[volume_index + 2]);
+                } else {
+                    // neighbor miss
+                    end_color_transparent = uvec4(255, 0, 0, 255);
+                    result.end_color = uvec4(255, 0, 0, 255);
+                    break;
+                }
+            } else {
+                if (next_neighbor != 0) {
+                    // transparent hit, move on but change the color
+                    end_volume_transparent = volume_index;
+                    color_mul_transparent = result.color_mul;
+
+                    volume_index = next_neighbor;
+                    volume_scale = uintBitsToFloat(scene_info.infos[volume_index + array_descr_offset + color_array_offset - 1]);
+                    volume_pos_x = uintBitsToFloat(scene_info.infos[volume_index + 0]); 
+                    volume_pos_y = uintBitsToFloat(scene_info.infos[volume_index + 1]); 
+                    volume_pos_z = uintBitsToFloat(scene_info.infos[volume_index + 2]);
+                    result.color_mul = result.color_mul * vec3(float(color_sample.x) / 255.0, float(color_sample.y) / 255.0, float(color_sample.z) / 255.0);
+                    result.has_transparent_hit = true;
+                    result.end_volume = volume_index;
+                    result.end_direction = direction;
+
+                    end_color_transparent = color_sample;
+                    end_raster_transparent = uvec2(u, v);
+                    end_pos_transparent = intersection_pos;
+                    end_facing_transparent = hit_facing;
+
+                    // stop iterating if there is barely anything left to see
+                    if (max(result.color_mul.x, max(result.color_mul.y, result.color_mul.z)) < 0.1) {
+                        break;
+                    }                    
+                } else {
+                    // color hit, either reflect or move on
+                    result.end_pos = intersection_pos;
+                    result.end_facing = hit_facing;
+                    result.end_color = color_sample;
+                    result.end_raster = uvec2(u, v);
+                    result.has_hit = true;
+                    result.end_volume = volume_index;
+                    result.end_direction = direction;
+
+                    float reflectivity = 1.0 - float(color_sample.w) / 255.0;
+                    vec3 refltective_color_mul = result.color_mul * vec3(float(color_sample.x) / 255.0, float(color_sample.y) / 255.0, float(color_sample.z) / 255.0);
+                    vec3 visibility_after_reflection = refltective_color_mul * reflectivity;
+                    //break;
+                    //max(visibility_after_reflection.x, max(visibility_after_reflection.y, visibility_after_reflection.z)) >= 0.1 && 
+                    if (max(visibility_after_reflection.x, max(visibility_after_reflection.y, visibility_after_reflection.z)) >= 0.1 && allow_reflect) {
+                        // do reflect
+                        direction = reflect_vector(direction, hit_facing);
+                        pos = intersection_pos;
+                        //max_factor -= smallest_factor;
+
+                        x_pos = direction.x > 0.0;
+                        x_null = (direction.x == 0.0);
+                        
+                        y_pos = direction.y > 0.0;
+                        y_null = (direction.y == 0.0);
+
+                        z_pos = direction.z > 0.0;
+                        z_null = (direction.z == 0.0);
+                    } else {
+                        break;
+                    }
+                }
+            }
+        }
+    }
+
+    result.end_factor = min(min(x_factor, y_factor), z_factor);
+    result.end_cycle = iteration_num;
+
+    // in case we have a transparent hit but no hit afterwards
+    if (!result.has_hit && result.has_transparent_hit) {
+        // did we stop because nothing could be seen through the object?
+        if (max(result.color_mul.x, max(result.color_mul.y, result.color_mul.z)) < 0.1) {
+            // if so count it as a hit and recover the pre transparent color multiplier
+            result.has_hit = true;
+            result.color_mul = color_mul_transparent;
+        }
+        result.end_pos = end_pos_transparent;
+        result.end_color = end_color_transparent;
+        result.end_volume = end_volume_transparent;
+        result.end_facing = end_facing_transparent;
+        result.end_raster = end_raster_transparent;
+    }
+
+    return result;
+}
+
+vec3 get_lighting_color(uint volume_start, vec3 starting_pos, vec4 orig_color_sample, vec3 normal) {
+    uint light_num = 0;
+
+    // initialize color
+    vec3 color_sum = vec3(0.0, 0.0, 0.0);// + (orig_color_sample.xyz * 0.005);
+
+    while (iteration_num < max_iterations) {
+        // setup light info
+        uint light_index = scene_info.infos[volume_start + 6 + light_num];
+        if (light_index == 0) {
+            // abort if there is no new light
+            break;
+        }
+        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, max_factor, 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));
+
+        light_num += 1;
+        if (light_num >= max_num_lights) {
+            break;
+        }
+    }
+
+    return color_sum;
+}
+
+vec3 diffuse_tracing(uint volume_start, uvec4 color_roughness, vec3 pos, uint f) {
+    vec4 orig_color_sample = vec4(float(color_roughness.x) / 255.0, float(color_roughness.y) / 255.0, float(color_roughness.z) / 255.0, 1);
+    vec3 normal = normal_for_facing(f);
+
+    vec3 color_sum = vec3(0.0, 0.0, 0.0);
+    for (int u_offset = -half_diffuse_raster_steps; u_offset <= half_diffuse_raster_steps; u_offset++) {
+        for (int v_offset = -half_diffuse_raster_steps; v_offset <= half_diffuse_raster_steps; v_offset++) {
+            float x_offset = raster_distance * float(u_offset) * float(f == 0 || f == 1 || f == 4 || f == 5);
+            float y_offset = raster_distance * float(u_offset) * float(f == 2 || f == 3);
+            y_offset += raster_distance * float(v_offset) * float(f == 0 || f == 1);
+            float z_offset = raster_distance * float(v_offset) * float(f == 4 || f == 5 || f == 2 || f == 3);
+
+            vec3 offset = vec3(x_offset, y_offset, z_offset);
+
+            color_sum += get_lighting_color(volume_start, pos + offset, orig_color_sample, normal) / float(raster_points);
+        }
+    }
+
+    return color_sum;
+}
+
+vec3 clamp_to_volume(uint volume_start, vec3 position) {
+    float volume_pos_x = uintBitsToFloat(scene_info.infos[volume_start + 0]); 
+    float volume_pos_y = uintBitsToFloat(scene_info.infos[volume_start + 1]); 
+    float volume_pos_z = uintBitsToFloat(scene_info.infos[volume_start + 2]); 
+    float volume_scale = uintBitsToFloat(scene_info.infos[volume_start + array_descr_offset + color_array_offset - 1]);
+
+    float high_x_border = volume_pos_x + float(scene_info.infos[volume_start + 3]) * volume_scale - 0.501 * volume_scale;
+    float high_y_border = volume_pos_y + float(scene_info.infos[volume_start + 4]) * volume_scale - 0.501 * volume_scale;
+    float high_z_border = volume_pos_z + float(scene_info.infos[volume_start + 5]) * volume_scale - 0.501 * volume_scale;
+
+    float low_x_border = float(volume_pos_x) - 0.501 * volume_scale;
+    float low_y_border = float(volume_pos_y) - 0.501 * volume_scale;
+    float low_z_border = float(volume_pos_z) - 0.501 * volume_scale;
+
+    return vec3(min(max(position.x, low_x_border), high_x_border), min(max(position.y, low_y_border), high_y_border), min(max(position.z, low_z_border), high_z_border));
+}
+
+vec2 clamp_to_quad(vec2 raster_pos, uvec2 min_raster_pos, uvec2 max_raster_pos) {
+    return vec2(max(min_raster_pos.x, min(max_raster_pos.x - 1, raster_pos.x)), max(min_raster_pos.y, min(max_raster_pos.y - 1, raster_pos.y)));
+}
+
+vec3 add_reflection(vec3 view_vector, uint f, uint volume_start, vec3 pos, uvec4 color_sample, vec3 color_sum) {
+    float reflectivity = 1.0 - float(color_sample.w) / 255.0;
+
+    if (reflectivity > 0.01) {
+        vec3 orig_color_sample = vec3(float(color_sample.x) / 255.0, float(color_sample.y) / 255.0, float(color_sample.z) / 255.0);
+        vec3 reflection_direction = reflect_vector(view_vector, f);
+        Tracing reflection_tracing = trace_ray(volume_start, pos, reflection_direction, pos_infinity, true);
+        if (reflection_tracing.has_hit || reflection_tracing.has_transparent_hit) {
+            vec3 color_from_reflection = diffuse_tracing(reflection_tracing.end_volume, reflection_tracing.end_color, reflection_tracing.end_pos, reflection_tracing.end_facing) * orig_color_sample;
+            color_sum = color_sum * (1.0 - reflectivity) + color_from_reflection * reflectivity;
+        }
+    }
+
+    return color_sum;
+}
\ No newline at end of file
diff --git a/shaders/rt_quad.frag b/shaders/rt_quad.frag
index c59b4e4..d5f4a7b 100644
--- a/shaders/rt_quad.frag
+++ b/shaders/rt_quad.frag
@@ -321,13 +321,34 @@ Tracing trace_ray(uint volume_start, vec3 starting_pos, vec3 start_direction, fl
     uvec2 end_raster_transparent;
     vec3 color_mul_transparent;
 
+    uint next_volumetric_index = 0;
+    uint[5] done_volumetrics;
+    for (int i=0; i < 5; i++) {
+        done_volumetrics[i] = 0;
+    }
+
     while (iteration_num < max_iterations) {
         iteration_num ++;
 
         uint compound_num = 0;
         while (scene_info.infos[volume_index + 6 + max_num_lights + compound_num] != 0 && compound_num < max_num_compounds && iteration_num < max_iterations && !result.has_hit) {
-            //iteration_num ++;
             uint compound_start = scene_info.infos[volume_index + 6 + max_num_lights + compound_num];
+            
+            bool already_checked = false;
+            for (int i=0; i < 5; i++) {
+                if (compound_start == done_volumetrics[i]) {
+                    already_checked = true;
+                    break;
+                }
+            }            
+            if (already_checked) {
+                compound_num += 1;
+                continue;
+            }
+            done_volumetrics[next_volumetric_index] = compound_start;
+            next_volumetric_index = (next_volumetric_index + 1) % 5;
+
+            //iteration_num ++;
             uint oct_tree_index = compounds[compound_start + 8];
             uint compound_grid_size = compounds[compound_start];
             float compound_scale = uintBitsToFloat(compounds[compound_start + 1]);
@@ -820,4 +841,4 @@ void main() {
     }
 
     outColor = vec4(color_sum, 1.0);
-}
\ No newline at end of file
+}
diff --git a/shaders/rt_quad_placeholder.frag b/shaders/rt_quad_placeholder.frag
new file mode 100644
index 0000000..0f69b04
--- /dev/null
+++ b/shaders/rt_quad_placeholder.frag
@@ -0,0 +1,51 @@
+#version 450
+
+layout(location = 0) in vec2 fragRasterPos;
+layout(location = 1) flat in uint fragVolumeStart;
+layout(location = 2) in vec3 origPosition;
+layout(location = 3) flat in uint facing;
+layout(location = 4) flat in uvec2 minRasterPos;
+layout(location = 5) flat in uvec2 maxRasterPos;
+
+layout(location = 0) out vec4 outColor;
+
+#include rt_lib.frag
+
+void main() {
+    vec3 clamped_pos = clamp_to_volume(fragVolumeStart, origPosition);
+    vec2 clamped_raster_pos = clamp_to_quad(fragRasterPos, minRasterPos, maxRasterPos);
+    uvec4 color_roughness = sample_color_from_scene_info(fragVolumeStart, clamped_raster_pos, 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;
+
+    uint orig_neighbor = sample_neighbor_from_scene_info(fragVolumeStart, clamped_raster_pos, facing);
+    if (orig_neighbor != 0) {
+        vec3 color_direct = diffuse_tracing(fragVolumeStart, color_roughness, clamped_pos, facing);
+
+        Tracing t = trace_ray(fragVolumeStart, ubo.camera_pos, clamped_pos - ubo.camera_pos, pos_infinity, false);
+        float opacity = float(color_roughness.w) / 255.0;
+        vec3 color_seen_through;
+        if (t.has_hit) {
+            //color_seen_through = vec3(float(t.end_color.x) / 255.0, float(t.end_color.y) / 255.0, float(t.end_color.z) / 255.0);
+            
+            color_seen_through = diffuse_tracing(t.end_volume, t.end_color, t.end_pos, t.end_facing) * orig_color_sample * t.color_mul;
+            color_seen_through = add_reflection(t.end_direction, t.end_facing, t.end_volume, t.end_pos, t.end_color, color_seen_through);
+        }
+        else {
+            // Todo: hit sky box
+            color_seen_through = vec3(0.0, 0.0, 0.0);
+        }
+
+        color_direct = add_reflection(normalize(clamped_pos - ubo.camera_pos), facing, fragVolumeStart, clamped_pos, color_roughness, color_direct);
+        color_sum = opacity * color_direct + (1.0 - opacity) * color_seen_through;
+        
+        //color_sum = color_seen_through;
+    }
+    else {
+        color_sum = diffuse_tracing(fragVolumeStart, color_roughness, clamped_pos, facing);
+
+        color_sum = add_reflection(normalize(clamped_pos - ubo.camera_pos), facing, fragVolumeStart, clamped_pos, color_roughness, color_sum);
+    }
+
+    outColor = vec4(color_sum, 1.0);
+}
\ No newline at end of file