From 51760f30f1b46e1349afa8056623d374994b6525 Mon Sep 17 00:00:00 2001
From: zomseffen <steffen@tom.bi>
Date: Mon, 28 Apr 2025 11:03:19 +0200
Subject: [PATCH] adds sparse oct_tree generation in compute

---
 build.rs                                   |   4 +-
 shaders/compile.bat                        |   2 +-
 shaders/compile.sh                         |   2 +-
 shaders/compiled/rt_compute_combine.spv    | Bin 5128 -> 0 bytes
 shaders/compiled/rt_compute_grow_one.spv   | Bin 7116 -> 4744 bytes
 shaders/compiled/rt_compute_grow_three.spv | Bin 11192 -> 4852 bytes
 shaders/compiled/rt_compute_grow_two.spv   | Bin 9304 -> 4852 bytes
 shaders/compiled/rt_compute_mempos.spv     | Bin 0 -> 45852 bytes
 shaders/compiled/rt_compute_rasterize.spv  | Bin 39216 -> 23524 bytes
 shaders/rt_compute_combine.comp            |  51 ---
 shaders/rt_compute_grow_one.comp           |  35 +--
 shaders/rt_compute_grow_three.comp         |  55 +---
 shaders/rt_compute_grow_two.comp           |  48 +--
 shaders/rt_compute_mempos.comp             | 349 +++++++++++++++++++++
 shaders/rt_compute_rasterize.comp          |   2 +-
 src/app_data.rs                            |   7 +-
 src/buffer.rs                              |  58 +++-
 src/command_buffer.rs                      |  37 ++-
 src/main.rs                                |  29 +-
 src/scene/generators.rs                    |   4 +-
 src/scene/mod.rs                           |   7 +
 src/scene/volumetrics/mod.rs               |  22 +-
 22 files changed, 498 insertions(+), 214 deletions(-)
 delete mode 100644 shaders/compiled/rt_compute_combine.spv
 create mode 100644 shaders/compiled/rt_compute_mempos.spv
 delete mode 100644 shaders/rt_compute_combine.comp
 create mode 100644 shaders/rt_compute_mempos.comp

diff --git a/build.rs b/build.rs
index 3a366b4..67aaf3a 100644
--- a/build.rs
+++ b/build.rs
@@ -18,7 +18,7 @@ fn main() {
     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");
+    println!("cargo::rerun-if-changed=shaders/rt_compute_mempos.comp");
 
     std::fs::remove_file("shaders/compiled/geo_cube.spv").unwrap_or(());
     std::fs::remove_file("shaders/compiled/frag_cube.spv").unwrap_or(());
@@ -32,7 +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(());
+    std::fs::remove_file("shaders/compiled/rt_compute_mempos.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 bb4fe6a..7717e6c 100644
--- a/shaders/compile.bat
+++ b/shaders/compile.bat
@@ -13,4 +13,4 @@ C:/VulkanSDK/1.3.280.0/Bin/glslc.exe shaders/rt_compute_rasterize.comp -o shader
 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
-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
+C:/VulkanSDK/1.3.280.0/Bin/glslc.exe shaders/rt_compute_mempos.comp -o shaders/compiled/rt_compute_mempos.spv
\ No newline at end of file
diff --git a/shaders/compile.sh b/shaders/compile.sh
index 88be158..9507c17 100755
--- a/shaders/compile.sh
+++ b/shaders/compile.sh
@@ -14,4 +14,4 @@ glslc shaders/rt_compute_rasterize.comp -o shaders/compiled/rt_compute_rasterize
 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
-glslc shaders/rt_compute_combine.comp -o shaders/compiled/rt_compute_combine.spv
\ No newline at end of file
+glslc shaders/rt_compute_mempos.comp -o shaders/compiled/rt_compute_mempos.spv
\ No newline at end of file
diff --git a/shaders/compiled/rt_compute_combine.spv b/shaders/compiled/rt_compute_combine.spv
deleted file mode 100644
index 61fd2eede649f37bb5eeab8520360a7cb2ee79f2..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 5128
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
YXgt>aBiNW{c#>KEzibZwtLJ3@2k>IUEdT%j

diff --git a/shaders/compiled/rt_compute_grow_one.spv b/shaders/compiled/rt_compute_grow_one.spv
index 82ea0be971467cc84c96ddcbd851106015f6c56c..23863abd403c5b111fbfab3367c669fdc790a780 100644
GIT binary patch
literal 4744
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

literal 7116
zcmZ9Q2bf%C6^8F-Gn<eeQh_9H5{*)fC`A;3gn&ylnn;3e)nT$b8z%0~th2L$Gzbxh
z2-tg6u!4e$Vy_W<@4aE~U1@^)zIX1){?FX!Is1R#cgo++y}QqLPg*%8%eu1Z+01NN
zSC&6>vq>l!T2DUqZP>hF^;m0g^~tB4XuzzjJC8GFHZdi}$=FDxR@X5dn}e=4H^<J<
zwr+AKfp15coK4I6HkA7|ZtUA|Zh2sIv^>_@Ib1Cd*Xq^sV69mlXw`O9jhmXp)#?Mo
z<AZ5HiHLN5`Bdhp)d#DWFqUAhY1?qQZ@96wGQ7UNqcKov)f)Bn=j8q#)|+LG@z&^g
ztK1kG8mqPn-SrPNMn)Us^+A?bY2qlcx1-S475drZLqpYOhT7I~9nKj8m)P?$iae!k
zO16&iaLsMa8ii}S*r#>Zr@pa)%5biivh&eLh>XQqvmb3ICN4AX%5hId%0&IqhD#u(
zl>5i3)q1%)GTI{1bJ~Ni*j6617d~7WYn2BY!|lB8>{3Ac981{&Fs??kyrW`(b+2Yz
zr&b(<9iirvZ;!Tcjn}lLJm(;|)vVOVMk~!~y@fU<dmY-A2`!G5Q<<9kOiyyk)>gCj
z^#UHx@ZF4?Inj23le}Wowl2=s#AS=ky-mR58jhwfFR0gs8qJY*`o^u>=|i$hxzD(f
z#$eUGThn-Zdt0?JQf@Z#nh|TC@2FKTW;mShn={&MY;SAre0z7GGE!|;%K2^e6zeFV
zkB?Q$dF`=_DuXnc>s`Wx<69e9ANOZpYfCWsV#XfKn&<J;KJ`&QkL=(pbJd*gTytIK
z+ovlI``UatJp9iCr}g8WqkizTzFOql18IG^^<A&?zm_qrZ%_C{{orYRwWx0&r1j<2
zKLWG<t&9`(OL?y#WobS8C+gW7X+631{JvQ4sIGQBzaO5r{ov!>dEUXJeyZ`|&A&U5
zXKI=!H*XCVd1{?`lhD#Uxq17r$W!agbB}4B+`L0r<f%>MwfEy)8E4~1oORUZpxIOI
z+c`ZW`*j7_C;0L<&G}ON_OQJ<k1X?+Q^UE%3#j3p^<qA~aMz@%FM@l&VsrFQW29`Z
zpI&h1P&*!O><rAu_?e9Q)R$5v-lJt;*CjXZXhzqhW?i}OOsv!QuottI^T?NCKIT7w
z(OBo14_d_->p83NEo9C<aBpstIpg+T)gt!sVCQh}n;7-Q-k${aY}Ad{w*})lEAqEN
zytCjVVAmAfUmDhM%{vS1T90EE$K9Cc6yF2S$@g4t&hr`Fr<&&^_gz;rFWz(We1GNU
zy}pQ1Gf(b29C`8nn&*2eH}5?~jGB3J-&OODCDt|Hhq*uRB<q?uzlC7W$i808&qZ)G
zd7Q^$_#F5W)OhFBmhmO9*Ud@Ivp3GQ9mD84jB{;r-wCx7ICXp1cffkyt9B~4qu(|7
zc(-?>cxTq|Zu|y026ufapWDILCET7`pKyD|zcJGM{tjMFxbfA5+avz{k>>B|;Cnl`
ze^;dO2NG_*g9Ts9u6;jeVbd|++cP)=`*k*^ekLd6dC0|{g>hofL3|JAcO;|d=y)eJ
z<})t9eDp75)bAK`ECO3Q_%g6H*RlfN=U&WjfbY4!h+7WsP526Mnzs@jdHN#nfna@C
zuy6PHAk13ox1ia}55`=VzI)k+d>-b0T)#N#Jp`Q2dn`QW)faKcf%OGH9-QW#0FOL<
z5%*BAzF6;Su(i}9=3(Hp)`{?_r7z+h4%Qd79s#zVdc>Rr_I~#j=W{Yx&DgkmwTM3j
zoX&kJJm%IHagPM+3w|0n&3hC)^7KXAqrv)O&8LH{r5-Vl0oz0Si#4ACRx>twS1sbt
z1Uq-^aSd3_-x1MwYr(OeHQ>lSJCB*@eYw4DpW7Rb>APUhMD97@bkFC)V-9^0_gJt#
z*Y0;k9=^wc)3tAatNC4vwLbwIb@fN?6T$lS(9?a48!<KK@p~mVR^Mh!?Mlv6enFva
zVT_n3gVUI&z}3>2r*_0V4X$R)Cf>kJj8Dg`Z@zxlb3UVbto<3_^gHoPxMy>9ap%th
z8>4Q1KciaYUkFa~D{y0?XSRYb#MC2a0PGxB6>|)NjZ=3Hzu9ULKLk$i<|4S-HZ1O@
z29CSYAGzDX`r>Y$4OR>PFgUGUhpUZXQM&<-+WI4R6s#|5KL@N9{w6rB-GZx)VNrV=
z9JTdF?hdfNsC_Y5E$;RbuzPV%eV$vDQC+-?ad(0DFwQ9O-UMG-VBf3Dz`kdW{*Jkv
zaX;px|GA9%9b=7GfUObyO0f5OEBCsJ@hZ$1b-(xWeVDbaC63%{!G0fuUk6TWzW{FS
z_+GsbY>ay3ya=4eyclkrdVG^!0(LHak@r$?f5Kk|PV2lJZj5@=c?H;7`l8M&!S-&%
zyb5fbdffM`!Pj6*G5wMI8n8a^?f|1ad^dp8vv~tNJ)1Ye)AhayZj5@=cymY0Tj0j2
z$9mriz5&x0c{hU7v$+YL&h<99G3rt0?O<!^i#j)h)3dn+Zk&3Y%{#!?W1fxv$bBbR
z-_1o|y$h^11M|ENGO9)Vd%@{>y$_zA*Zbk=9zFm!Mm=hLup{O}aO2ctpC1N0m%hmR
z2sk~jkHXWrJ_a{NJ?eZMY%P6J=M&)cybi&QQ;+ldB=|PW^E!li7HXbL)VUpOKgHR7
z3al0}tH7VeJj0u^$@zQxnL@j<IPcHG%~QXNIX=(m<2$YIbJ$NX-)XUPTlWjtF3g-S
zG5VOJ{zXj99C57o%i#3xz5@6A75=Y+)ARfq+!*zU`FcmpH{iyp$C-Z<>|FXH?_1#X
z?!FCA=lTxZ81<<0U9h$EMV;?~)4TgV+&J}!`2jfX$sfYqXZ+s$5!e{@xbGi><G!uw
zeXAKO_N;docrT-O?6*74*-`HOdG6ks>+!CBikTn$XW)Za^uQfpW7K00KL<Nc@Lzz_
zUi&5781<<0EASndKKtS~j6U{-zF%W%u1_4be+y3g;&<@0FMbbC@9Gb5W7MO@A3I|H
z1UF7S?(@%J=h7E>e*yO={IB42uD`*JQI9%*2U|;D)cFTE?TdfHjZ=@9e}U7!_%}T5
zi#y@Qs7GJi1&+S3roEtMY}yyzeVnbMbFN~%8}sht{lBNsyr2JoeY_v_doeZdM;!I<
z1IHfj2fGJ-u3a9!|AOriefEyrbwy3bv`6h#`F=*{bc|a613OQgc~@7Ksri2r>+4f9
z|1z-omovt`C*gD7?sGEO$9<}IV`}DzW6lyd?ZX~;+J{r%X>Ux08>1dIj_8P)1~*PU
z_A(vpT>2t!2DqO!2A>H}=b8mKMm_4x23t#C<oW;3v=8UPjZ=@9Bf-`VJ`bMu;e5C;
b>d}V_z|n`+^bXXF^$y}Z9q;FoPQ(5W=mDDN

diff --git a/shaders/compiled/rt_compute_grow_three.spv b/shaders/compiled/rt_compute_grow_three.spv
index 1a326caea5fc67c7b274178dab385db84aee2961..625eb4ba9966b3720f7f14f1a68c5358ae1f5679 100644
GIT binary patch
literal 4852
zcmZ9OX>$}+6o#9GA-ID33I<Tzao-m})QCnwz!h~Ik_isZOph}Y6x>ij#C_ivM8u{1
z;7_ppQI=X|mCw`DC%KibIyvwAp5>l<`}S0ZhgOVa*}UwS?6~aLZ19|r4WVRc3kp9r
zzIl9AuRpo!>T51H<M?d2NHk{=ITieTtW|5Y4IG0lMprwbz^*W`VQPoKe<IA!j?Tu$
zt798BjE&z>o#=F`z5cFdz1nQF>($9dw?5Ht?5vx&Fv)AQCz{ifX+njJbba|k)@ZaR
z>(AjUFlXA{td2GFZMEk5_Rf5w)^FtP^|u%C1<ade`E<WC-LK|TQ@wh>)SZ7KZ*}tN
z_9Wxgx&$ih?F{sFrGDG=)KtBjp$>FHGc`SMg*~68$WzHivUT{Gp4+<(8aH;cPy4P<
zW4(!5v(PKqCiE7WF`PZOq7C*poK?ZQFm+0@-gK+LQ{df&z98%1H?z`U-YeZYD~=Sp
zcxII9;62)lZ55BR?E}r$Uscu*bd!pD4pD6FegThr{ucj0yD^n_TZ82{Y}>*6rE8^#
znb*oE>rK4pXufx5dp&PeyLr(wa=kx08}(;#GxgrcPB-5%&<6G1iHTaP-mO(TIWNM!
z+P8vD_v+Q6ckij%Brnf-52|m=!IkU~cwOGiyXDJuZ8e`_pB#}jhX)dPBs&7$(yg_7
zom#iv?#H!Y-GxQW)c$O|Y9BTG{4C%Z<L-J_wX;ipI(`A>e(vJ0ch5)tE~<mCC{%k4
z7n)~cKkwf1nb?3YgGW3Er~SPrKG8pT+Fvc|y(4LVx&8TJDc0YMpY2~M?h#U!_VaE<
zKkrT2Pi{ZIY4`ID-hPWQ&%<}><9qcyf=B;UbEdS;JC@eTty_ado!Z>GA+)qkZrvU%
z>eS}exyQ6lZrvYP)TzzZ4ff-^H_wkE^6aCw7|nO?zFpHZI*4D6`2=4!pauUPJo`@O
z&)n^J=ZDJNV$Gt*aFOF|_B)JE`^)X`oW_5|r~Qw>eWHKxw7**P_j^eD%k6&@X8&LC
zek0!fli2kTei_x)i%%iP^+z$EQMhNSsh<Y7m)IKPN8{&V>Nl0#HPkMKn|mzgWBze?
zW9m!j;@-qd!OkT&?@YWiso7WVHyLyKosVMnavk{+%*Xn3@aEe4WY9`{%(J?ToywYH
z;L*b7b4LbyRg2tvz^>umH{y-O-tPx{HtOaZ+k)||c5m?;;odrka%X!6?`&%BP44%v
zX5C(VoXI}0+`8BC=BQaG-(PBR2A{)Y-Y>z<<o!CGzhB|i<gvf6!Hco8QR6p4Z7IJT
zejC=L=3dQnp6~F^W1jQK4`Q*8@4>N;LtwdeKa@FY*2xc-n){FMz;io-F1PNdGDpoi
zxp&<4E@36_pm*H)eQ(;e{Bjs~&py7pzfmf9dyL>0V*22oN6P(wCgtlA?wwhmaPP#X
zgj=_D4zJGP^*Ma1<ZGGI@8x*RZ_4lJ7H0NL7h&qRvLol0i=Ev(v2%<6VZSHh-M9WP
zdYp_u1@kd}D&Dw0);JAp@8C<p_FT&Z=io=NvoOCqW0AKEJeu(3;IwW9JnD=^-ML_6
zd)c>pJP)&%`fq3}@#kaCW$a(}AwLOoKh7_Xeiwk#buWa+y2c{!BCxUG7lYHfOW;vw
zEb=Y|8;f~Yf$gOpIhTRcUYEn8m$AsZ0&FaLT?w|IdgNRM_WkZD&*y5enz`}r)gu2I
zaJu%j@L1be<Xs0g7W{f}T6Y6H>WoF+jbLLj^G#rTsYlMuVDHeY<;=H$)y$2%s}}jU
zf?YfIxCX4Y8jE|k798`e0Y~j^Mb7NqmwUIp=iUu{`Ym{8qV{%hy5~FKv4*k8yAy28
z+5H`mN9=BJI{P?W&EKJz{a$eNH6FG1fsMVuogTw)z|>sF-xs;L#x`SW`#4ki1EsbF
zA2|<#)0~IkYH7~Hb8;SmtC_QrFK{FNQOy3<8+V>fc=ee5F>v}j@i^SGIZ(dyC&1>Y
zTfY^r7WGep)A}0RoVYXFz)xc8Q8NK{jn~UHCc);ZyN189YT`Qn*b+~b*n6-Y?7h(Y
zo7lkbz<i89jW@23b(>&&1aE<z<9Fs*iEm@(sQddQe+sj=y~I)51N%J(?}OcU@M*BU
z<NMkPHb*^jo&~2l&%w=8k8fxf*tLvB-EOdF6#RK`+UEthIqK2pMX<e$Mcqqa&m(eP
z2AiiIcYY7Ji!H&7N9`-%Jqdpm?7NCyuYuLfi}$D&^>2XF^E&`f&+komx~I3`=BP)H
zx98-%12<1S=6DzETE?R8J#cz{@59rzK7gB}9(_Ip+sjz=`3Rhz-^XzC)FbB;u;&uz
v`6+lm=6Ra$*{GT4z4Z=z*YwfjGjO`j7jU)DG3$+~rQd~j_P=aic0Kk#L7bw`

literal 11192
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
T*YhFYy7ONe^Z5Tk=QaKYr<yo7

diff --git a/shaders/compiled/rt_compute_grow_two.spv b/shaders/compiled/rt_compute_grow_two.spv
index 136cf1cc67e27c903ca67e60b97961589a257a90..5d56e66caf168269f4509489428ae5c815dcfeab 100644
GIT binary patch
literal 4852
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

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

diff --git a/shaders/compiled/rt_compute_mempos.spv b/shaders/compiled/rt_compute_mempos.spv
new file mode 100644
index 0000000000000000000000000000000000000000..891a76f8bbc50dd19122341f24f594e8c8404310
GIT binary patch
literal 45852
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
AkpKVy

literal 0
HcmV?d00001

diff --git a/shaders/compiled/rt_compute_rasterize.spv b/shaders/compiled/rt_compute_rasterize.spv
index 9ad3d50fe254abd45e6798f712cf9e2c61881ecb..fc8e3b052d2ac700e2fdfc121aea111a5f5debd9 100644
GIT binary patch
literal 23524
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
bi-Dbw?U`|}(c-j0G~@Ku{v+2%-D~-Oo#WPn

literal 39216
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
XO>@E3>w20So|?>SO=|k)@9X{_BoJC}

diff --git a/shaders/rt_compute_combine.comp b/shaders/rt_compute_combine.comp
deleted file mode 100644
index c70c19e..0000000
--- a/shaders/rt_compute_combine.comp
+++ /dev/null
@@ -1,51 +0,0 @@
-#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/shaders/rt_compute_grow_one.comp b/shaders/rt_compute_grow_one.comp
index f4161f4..27e27eb 100644
--- a/shaders/rt_compute_grow_one.comp
+++ b/shaders/rt_compute_grow_one.comp
@@ -43,40 +43,11 @@ void main() {
     vec3 mid_offset = vec3(compound_scale * 0.5, compound_scale * 0.5, compound_scale * 0.5);
     uint y = index % compound_grid_size;
     uint z = (index - y) / compound_grid_size;
-    vec3 compound_pos = vec3(uintBitsToFloat(compounds[compound_start + 5]), uintBitsToFloat(compounds[compound_start + 6]), uintBitsToFloat(compounds[compound_start + 7]));
     // iterate upwards along the x axis
-    bool seen_empty = false;
-    uint start = 0;
-    uint last_col = 0;
+    uint sum = 0;
     for (uint x=0; x < compound_grid_size; x++) {
         uint color_val = grid_in[output_offset + x * compound_grid_size * compound_grid_size + y * compound_grid_size + z];
-        bool transparent = transparent_grid[output_offset + x * compound_grid_size * compound_grid_size + y * compound_grid_size + z];
-        grid_out[output_offset + x * compound_grid_size * compound_grid_size + y * compound_grid_size + z] = 0;
-        // check if we need to stop a volume
-        if (color_val != 0 && !transparent) {
-            // check if we are in a volume right now
-            if (seen_empty) {
-                // close the current volume
-                grid_out[output_offset + start * compound_grid_size * compound_grid_size + y * compound_grid_size + z] = x - start;
-                seen_empty = false;
-                last_col = 0;
-            }
-        } else {
-            // check if transparency changed
-            if (seen_empty && transparent && last_col != color_val) {
-                // if we switch colors close the current volume and prepare for a new one
-                grid_out[output_offset + start * compound_grid_size * compound_grid_size + y * compound_grid_size + z] = x - start;
-                seen_empty = false;
-            }
-            // start a new volume if we are not in one right now
-            if (!seen_empty) {
-                seen_empty = true;
-                start = x;
-                last_col = color_val;
-            }
-        }
-    }
-    if (seen_empty) {
-        grid_out[output_offset + start * compound_grid_size * compound_grid_size + y * compound_grid_size + z] = compound_grid_size - start;
+        sum += uint(color_val != 0);
+        grid_out[output_offset + x * compound_grid_size * compound_grid_size + y * compound_grid_size + z] = sum;
     }
 }
\ No newline at end of file
diff --git a/shaders/rt_compute_grow_three.comp b/shaders/rt_compute_grow_three.comp
index 0460631..2127584 100644
--- a/shaders/rt_compute_grow_three.comp
+++ b/shaders/rt_compute_grow_three.comp
@@ -37,7 +37,7 @@ void main() {
     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;
+        output_offset += compounds[compound_start] * compounds[compound_start] * compounds[compound_start];
         index -= compounds[compound_start] * compounds[compound_start];
         compound_start = compounds[compound_start + 2];
     }
@@ -47,55 +47,10 @@ void main() {
     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 - x) / compound_grid_size;
-    vec3 compound_pos = vec3(uintBitsToFloat(compounds[compound_start + 5]), uintBitsToFloat(compounds[compound_start + 6]), uintBitsToFloat(compounds[compound_start + 7]));
-    // iterate upwards along the x axis
-    bool seen_empty = false;
-    uint start = 0;
-    uint start_x_size = 0;
-    uint start_y_size = 0;
-    uint last_col = 0;
+    // iterate upwards along the z axis
+    uint sum = 0;
     for (uint z=0; z < compound_grid_size; z++) {
-        uint color_val = grid_in[output_offset + x * compound_grid_size * compound_grid_size + y * compound_grid_size + z];
-        bool transparent = transparent_grid[output_offset + x * compound_grid_size * compound_grid_size + y * compound_grid_size + z];
-        uint current_x_size = grid_size_in[output_offset + (x * compound_grid_size * compound_grid_size + y * compound_grid_size + z) * 2];
-        uint current_y_size = grid_size_in[output_offset + (x * compound_grid_size * compound_grid_size + y * compound_grid_size + z) * 2 + 1];
-        
-        grid_out[output_offset + (x * compound_grid_size * compound_grid_size + y * compound_grid_size + z) * 3] = 0;
-        grid_out[output_offset + (x * compound_grid_size * compound_grid_size + y * compound_grid_size + z) * 3 + 1] = 0;
-        grid_out[output_offset + (x * compound_grid_size * compound_grid_size + y * compound_grid_size + z) * 3 + 2] = 0;
-        // check if we need to stop a volume
-        if (color_val != 0 && !transparent) {
-            // check if we are in a volume right now
-            if (seen_empty) {
-                // close the current volume
-                grid_out[output_offset + (x * compound_grid_size * compound_grid_size + y * compound_grid_size + start) * 3] = start_x_size;
-                grid_out[output_offset + (x * compound_grid_size * compound_grid_size + y * compound_grid_size + start) * 3 + 1] = start_y_size;
-                grid_out[output_offset + (x * compound_grid_size * compound_grid_size + y * compound_grid_size + start) * 3 + 2] = z - start;
-                seen_empty = false;
-                last_col = 0;
-            }
-        } else {
-            // check if transparency changed
-            if (seen_empty && ((transparent && last_col != color_val) || (start_x_size != current_x_size) || (start_y_size != current_y_size))) {
-                // if we switch colors or size close the current volume and prepare for a new one
-                grid_out[output_offset + (x * compound_grid_size * compound_grid_size + y * compound_grid_size + start) * 3] = start_x_size;
-                grid_out[output_offset + (x * compound_grid_size * compound_grid_size + y * compound_grid_size + start) * 3 + 1] = start_y_size;
-                grid_out[output_offset + (x * compound_grid_size * compound_grid_size + y * compound_grid_size + start) * 3 + 2] = z - start;
-                seen_empty = false;
-            }
-            // start a new volume if we are not in one right now
-            if (!seen_empty && current_x_size != 0 && current_y_size != 0) {
-                seen_empty = true;
-                start = z;
-                start_x_size = current_x_size;
-                start_y_size = current_y_size;
-                last_col = color_val;
-            }
-        }
-    }
-    if (seen_empty) {
-        grid_out[output_offset + (x * compound_grid_size * compound_grid_size + y * compound_grid_size + start) * 3] = start_x_size;
-        grid_out[output_offset + (x * compound_grid_size * compound_grid_size + y * compound_grid_size + start) * 3 + 1] = start_y_size;
-        grid_out[output_offset + (x * compound_grid_size * compound_grid_size + y * compound_grid_size + start) * 3 + 2] = compound_grid_size - start;
+        sum += grid_size_in[output_offset + x * compound_grid_size * compound_grid_size + y * compound_grid_size + z];
+        grid_out[output_offset + x * compound_grid_size * compound_grid_size + y * compound_grid_size + z] = sum;
     }
 }
\ No newline at end of file
diff --git a/shaders/rt_compute_grow_two.comp b/shaders/rt_compute_grow_two.comp
index c2ec2f6..0631b0c 100644
--- a/shaders/rt_compute_grow_two.comp
+++ b/shaders/rt_compute_grow_two.comp
@@ -37,7 +37,7 @@ void main() {
     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;
+        output_offset += compounds[compound_start] * compounds[compound_start] * compounds[compound_start];
         index -= compounds[compound_start] * compounds[compound_start];
         compound_start = compounds[compound_start + 2];
     }
@@ -47,48 +47,10 @@ void main() {
     vec3 mid_offset = vec3(compound_scale * 0.5, compound_scale * 0.5, compound_scale * 0.5);
     uint x = index % compound_grid_size;
     uint z = (index - x) / compound_grid_size;
-    vec3 compound_pos = vec3(uintBitsToFloat(compounds[compound_start + 5]), uintBitsToFloat(compounds[compound_start + 6]), uintBitsToFloat(compounds[compound_start + 7]));
-    // iterate upwards along the x axis
-    bool seen_empty = false;
-    uint start = 0;
-    uint start_x_size = 0;
-    uint last_col = 0;
+    // iterate upwards along the y axis
+    uint sum = 0;
     for (uint y=0; y < compound_grid_size; y++) {
-        uint color_val = grid_in[output_offset + x * compound_grid_size * compound_grid_size + y * compound_grid_size + z];
-        bool transparent = transparent_grid[output_offset + x * compound_grid_size * compound_grid_size + y * compound_grid_size + z];
-        uint current_x_size = grid_size_in[output_offset + x * compound_grid_size * compound_grid_size + y * compound_grid_size + z];
-        
-        grid_out[output_offset + (x * compound_grid_size * compound_grid_size + y * compound_grid_size + z) * 2] = 0;
-        grid_out[output_offset + (x * compound_grid_size * compound_grid_size + y * compound_grid_size + z) * 2 + 1] = 0;
-        // check if we need to stop a volume
-        if (color_val != 0 && !transparent) {
-            // check if we are in a volume right now
-            if (seen_empty) {
-                // close the current volume
-                grid_out[output_offset + (x * compound_grid_size * compound_grid_size + start * compound_grid_size + z) * 2] = start_x_size;
-                grid_out[output_offset + (x * compound_grid_size * compound_grid_size + start * compound_grid_size + z) * 2 + 1] = y - start;
-                seen_empty = false;
-                last_col = 0;
-            }
-        } else {
-            // check if transparency changed
-            if (seen_empty && ((transparent && last_col != color_val) || (start_x_size != current_x_size))) {
-                // if we switch colors or size close the current volume and prepare for a new one
-                grid_out[output_offset + (x * compound_grid_size * compound_grid_size + start * compound_grid_size + z) * 2] = start_x_size;
-                grid_out[output_offset + (x * compound_grid_size * compound_grid_size + start * compound_grid_size + z) * 2 + 1] = y - start;
-                seen_empty = false;
-            }
-            // start a new volume if we are not in one right now
-            if (!seen_empty && current_x_size != 0) {
-                seen_empty = true;
-                start = y;
-                start_x_size = current_x_size;
-                last_col = color_val;
-            }
-        }
-    }
-    if (seen_empty) {
-        grid_out[output_offset + (x * compound_grid_size * compound_grid_size + start * compound_grid_size + z) * 2] = start_x_size;
-        grid_out[output_offset + (x * compound_grid_size * compound_grid_size + start * compound_grid_size + z) * 2 + 1] = compound_grid_size - start;
+        sum += grid_size_in[output_offset + x * compound_grid_size * compound_grid_size + y * compound_grid_size + z];
+        grid_out[output_offset + x * compound_grid_size * compound_grid_size + y * compound_grid_size + z] = sum;
     }
 }
\ No newline at end of file
diff --git a/shaders/rt_compute_mempos.comp b/shaders/rt_compute_mempos.comp
new file mode 100644
index 0000000..25c5a63
--- /dev/null
+++ b/shaders/rt_compute_mempos.comp
@@ -0,0 +1,349 @@
+#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) readonly buffer SizeBuffer3D {
+   uint grid_size_in[];
+};
+
+layout(binding = 10) buffer OutMemory {
+   uint out_memory[];
+};
+
+layout(binding = 2) readonly buffer SceneInfoBuffer{
+     uint infos[]; 
+} scene_info;
+
+uint max_num_lights = scene_info.infos[0];
+
+layout (local_size_x = 16, local_size_y = 1, local_size_z = 1) in;
+
+uint num_nodes(uint size) {
+   uint nodes = 0;
+   uint add_size = 1;
+   while (size >= 2) {
+      nodes += add_size;
+      add_size = add_size * 8;
+      size = size / 2;
+   }
+
+   return nodes;
+}
+
+layout(binding = 5) buffer SizedVertices {
+   float vertices[];
+};
+
+layout(binding = 6) buffer Indices {
+   uint indices[];
+};
+
+vec3 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 vec3(val4 / 255.0, val3 / 255.0, val2 / 255.0);
+}
+
+void add_cube(uint cube_num, float scale, vec3 pos, vec3 color) {
+    // add node info for the cube
+    //vertice 0
+    vertices[(cube_num * 8 + 0) * 11 + 0] = pos.x - 0.5 * scale;
+    vertices[(cube_num * 8 + 0) * 11 + 1] = pos.y + 0.5 * scale;
+    vertices[(cube_num * 8 + 0) * 11 + 2] = pos.z + 0.5 * scale;
+
+    vertices[(cube_num * 8 + 0) * 11 + 3] = color.x;
+    vertices[(cube_num * 8 + 0) * 11 + 4] = color.y;
+    vertices[(cube_num * 8 + 0) * 11 + 5] = color.z;
+
+    //vertice 1
+    vertices[(cube_num * 8 + 1) * 11 + 0] = pos.x + 0.5 * scale;
+    vertices[(cube_num * 8 + 1) * 11 + 1] = pos.y + 0.5 * scale;
+    vertices[(cube_num * 8 + 1) * 11 + 2] = pos.z + 0.5 * scale;
+
+    vertices[(cube_num * 8 + 1) * 11 + 3] = color.x;
+    vertices[(cube_num * 8 + 1) * 11 + 4] = color.y;
+    vertices[(cube_num * 8 + 1) * 11 + 5] = color.z;
+
+    //vertice 2
+    vertices[(cube_num * 8 + 2) * 11 + 0] = pos.x - 0.5 * scale;
+    vertices[(cube_num * 8 + 2) * 11 + 1] = pos.y - 0.5 * scale;
+    vertices[(cube_num * 8 + 2) * 11 + 2] = pos.z + 0.5 * scale;
+
+    vertices[(cube_num * 8 + 2) * 11 + 3] = color.x;
+    vertices[(cube_num * 8 + 2) * 11 + 4] = color.y;
+    vertices[(cube_num * 8 + 2) * 11 + 5] = color.z;
+
+    //vertice 3
+    vertices[(cube_num * 8 + 3) * 11 + 0] = pos.x + 0.5 * scale;
+    vertices[(cube_num * 8 + 3) * 11 + 1] = pos.y - 0.5 * scale;
+    vertices[(cube_num * 8 + 3) * 11 + 2] = pos.z + 0.5 * scale;
+
+    vertices[(cube_num * 8 + 3) * 11 + 3] = color.x;
+    vertices[(cube_num * 8 + 3) * 11 + 4] = color.y;
+    vertices[(cube_num * 8 + 3) * 11 + 5] = color.z;
+
+    //vertice 4
+    vertices[(cube_num * 8 + 4) * 11 + 0] = pos.x - 0.5 * scale;
+    vertices[(cube_num * 8 + 4) * 11 + 1] = pos.y + 0.5 * scale;
+    vertices[(cube_num * 8 + 4) * 11 + 2] = pos.z - 0.5 * scale;
+
+    vertices[(cube_num * 8 + 4) * 11 + 3] = color.x;
+    vertices[(cube_num * 8 + 4) * 11 + 4] = color.y;
+    vertices[(cube_num * 8 + 4) * 11 + 5] = color.z;
+
+    //vertice 5
+    vertices[(cube_num * 8 + 5) * 11 + 0] = pos.x + 0.5 * scale;
+    vertices[(cube_num * 8 + 5) * 11 + 1] = pos.y + 0.5 * scale;
+    vertices[(cube_num * 8 + 5) * 11 + 2] = pos.z - 0.5 * scale;
+
+    vertices[(cube_num * 8 + 5) * 11 + 3] = color.x;
+    vertices[(cube_num * 8 + 5) * 11 + 4] = color.y;
+    vertices[(cube_num * 8 + 5) * 11 + 5] = color.z;
+    
+    //vertice 6
+    vertices[(cube_num * 8 + 6) * 11 + 0] = pos.x - 0.5 * scale;
+    vertices[(cube_num * 8 + 6) * 11 + 1] = pos.y - 0.5 * scale;
+    vertices[(cube_num * 8 + 6) * 11 + 2] = pos.z - 0.5 * scale;
+
+    vertices[(cube_num * 8 + 6) * 11 + 3] = color.x;
+    vertices[(cube_num * 8 + 6) * 11 + 4] = color.y;
+    vertices[(cube_num * 8 + 6) * 11 + 5] = color.z;
+
+    //vertice 7
+    vertices[(cube_num * 8 + 7) * 11 + 0] = pos.x + 0.5 * scale;
+    vertices[(cube_num * 8 + 7) * 11 + 1] = pos.y - 0.5 * scale;
+    vertices[(cube_num * 8 + 7) * 11 + 2] = pos.z - 0.5 * scale;
+
+    vertices[(cube_num * 8 + 7) * 11 + 3] = color.x;
+    vertices[(cube_num * 8 + 7) * 11 + 4] = color.y;
+    vertices[(cube_num * 8 + 7) * 11 + 5] = color.z;
+
+    //add indices for the cube
+    //top
+    indices[cube_num * 36 + 0] = cube_num * 8 + 3;
+    indices[cube_num * 36 + 1] = cube_num * 8 + 0;
+    indices[cube_num * 36 + 2] = cube_num * 8 + 2;
+
+    indices[cube_num * 36 + 3] = cube_num * 8 + 3;
+    indices[cube_num * 36 + 4] = cube_num * 8 + 1;
+    indices[cube_num * 36 + 5] = cube_num * 8 + 0;
+
+    //bottom
+    indices[cube_num * 36 + 6] = cube_num * 8 + 6;
+    indices[cube_num * 36 + 7] = cube_num * 8 + 4;
+    indices[cube_num * 36 + 8] = cube_num * 8 + 7;
+
+    indices[cube_num * 36 + 9] = cube_num * 8 + 4;
+    indices[cube_num * 36 + 10] = cube_num * 8 + 5;
+    indices[cube_num * 36 + 11] = cube_num * 8 + 7;
+
+    //left
+    indices[cube_num * 36 + 12] = cube_num * 8 + 0;
+    indices[cube_num * 36 + 13] = cube_num * 8 + 4;
+    indices[cube_num * 36 + 14] = cube_num * 8 + 2;
+
+    indices[cube_num * 36 + 15] = cube_num * 8 + 6;
+    indices[cube_num * 36 + 16] = cube_num * 8 + 2;
+    indices[cube_num * 36 + 17] = cube_num * 8 + 4;
+
+    //right
+    indices[cube_num * 36 + 18] = cube_num * 8 + 1;
+    indices[cube_num * 36 + 19] = cube_num * 8 + 3;
+    indices[cube_num * 36 + 20] = cube_num * 8 + 5;
+
+    indices[cube_num * 36 + 21] = cube_num * 8 + 5;
+    indices[cube_num * 36 + 22] = cube_num * 8 + 3;
+    indices[cube_num * 36 + 23] = cube_num * 8 + 7;
+
+    //near
+    indices[cube_num * 36 + 24] = cube_num * 8 + 6;
+    indices[cube_num * 36 + 25] = cube_num * 8 + 3;
+    indices[cube_num * 36 + 26] = cube_num * 8 + 2;
+
+    indices[cube_num * 36 + 27] = cube_num * 8 + 3;
+    indices[cube_num * 36 + 28] = cube_num * 8 + 6;
+    indices[cube_num * 36 + 29] = cube_num * 8 + 7;
+
+    //far
+    indices[cube_num * 36 + 30] = cube_num * 8 + 0;
+    indices[cube_num * 36 + 31] = cube_num * 8 + 1;
+    indices[cube_num * 36 + 32] = cube_num * 8 + 4;
+
+    indices[cube_num * 36 + 33] = cube_num * 8 + 5;
+    indices[cube_num * 36 + 34] = cube_num * 8 + 4;
+    indices[cube_num * 36 + 35] = cube_num * 8 + 1;
+
+}
+
+void main() {
+   uint index = gl_GlobalInvocationID.x;
+   uint output_offset = 1;
+   uint input_offset = 0;
+   uint compound_start = 0;
+
+   uint nodes = num_nodes(compounds[compound_start]);
+   // iterate over the compounds and find the work index inside of it
+   while (index > nodes) {
+      output_offset += nodes * 9;
+      input_offset += compounds[compound_start] * compounds[compound_start] * compounds[compound_start];
+      index -= nodes;
+      compound_start = compounds[compound_start + 2];
+      nodes = num_nodes(compounds[compound_start]);
+   }
+
+   uint compound_grid_size = compounds[compound_start];
+   uint parent_start = 0;
+   uint cohort_start = 0;
+   uint cohort_index = index;
+   uint size = compounds[compound_start];
+   nodes = 0;
+   uint add_size = 1;
+   while (cohort_index >= add_size) {
+      nodes += add_size;
+      cohort_index -= add_size;
+      parent_start = cohort_start;
+      cohort_start = nodes * 9;
+      add_size *= 8;
+      size = size / 2;
+   }
+
+   uint parent = parent_start + ((cohort_index - cohort_index % 8) / 8) * 9;
+   uint start = cohort_start + 9 * cohort_index;
+   uint steps = compounds[compound_start] / size;
+
+   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 = (cohort_index % steps) * size;
+   uint y = (((cohort_index - (cohort_index % steps)) % (steps * steps)) / (steps)) * size;
+   uint z = (((cohort_index - (cohort_index % (steps * steps)))) / (steps * steps)) * size;
+
+   // plus one size offset, since we want to place the nodes at the far end. This aligns with the iteration directions in the previous shaders
+   x = x  + (size - 1);
+   y = y  + (size - 1);
+   z = z  + (size - 1);
+
+   // sum of all elements with coordinates lower than x, y, z
+   uint contained_entries = grid_size_in[input_offset + x * compound_grid_size * compound_grid_size + y * compound_grid_size + z];
+   if (z > size) {
+      // remove contained from z neighbor
+      contained_entries = contained_entries - grid_size_in[input_offset + x * compound_grid_size * compound_grid_size + y * compound_grid_size + z - size];
+   }
+
+   if (y > size) {
+      if (z > size) {
+         // add back the section we will remove twice
+         contained_entries = contained_entries + int(grid_size_in[input_offset + x * compound_grid_size * compound_grid_size + (y - size) * compound_grid_size + z - size]);
+      }
+      // remove contained from y neighbor
+      contained_entries = contained_entries - int(grid_size_in[input_offset + x * compound_grid_size * compound_grid_size + (y - size) * compound_grid_size + z]);
+   }
+
+   if (x > size) {
+      if (z > size) {
+         // add the portion already removed through the z neighbor
+         contained_entries = contained_entries + grid_size_in[input_offset + (x - size) * compound_grid_size * compound_grid_size + y * compound_grid_size + z - size];
+      }
+
+      if (y > size) {
+         // add the portion already removed by the y neighbor
+         contained_entries = contained_entries + grid_size_in[input_offset + (x - size) * compound_grid_size * compound_grid_size + (y - size) * compound_grid_size + z];
+
+         if (z > size) {
+            // remove the portion already added through the z neighbor
+            contained_entries = contained_entries - grid_size_in[input_offset + (x - size) * compound_grid_size * compound_grid_size + (y - size) * compound_grid_size + z - size];
+         }
+      }
+
+      // remove contained from x neighbor
+      contained_entries = contained_entries - grid_size_in[input_offset + (x - size) * compound_grid_size * compound_grid_size + y * compound_grid_size + z];
+   }
+
+   if (contained_entries > 0) {
+      out_memory[output_offset + cohort_start + cohort_index * 9 + 0] = parent * uint(size != 64);
+
+      if (size > 2) {
+         // add child node reference
+         uint cohort_end = cohort_start + 9 * add_size;
+         out_memory[output_offset + cohort_start + cohort_index * 9 + 1] = cohort_end + cohort_index * 9 + 9 * 0; // xyz
+         out_memory[output_offset + cohort_start + cohort_index * 9 + 2] = cohort_end + cohort_index * 9 + 9 * 1; // Xyz
+         out_memory[output_offset + cohort_start + cohort_index * 9 + 3] = cohort_end + cohort_index * 9 + 9 * 2; // xYz
+         out_memory[output_offset + cohort_start + cohort_index * 9 + 4] = cohort_end + cohort_index * 9 + 9 * 3; // XYz
+         out_memory[output_offset + cohort_start + cohort_index * 9 + 5] = cohort_end + cohort_index * 9 + 9 * 4; // xyZ
+         out_memory[output_offset + cohort_start + cohort_index * 9 + 6] = cohort_end + cohort_index * 9 + 9 * 5; // XyZ
+         out_memory[output_offset + cohort_start + cohort_index * 9 + 7] = cohort_end + cohort_index * 9 + 9 * 6; // xYZ
+         out_memory[output_offset + cohort_start + cohort_index * 9 + 8] = cohort_end + cohort_index * 9 + 9 * 7; // XYZ
+
+      } else {
+         // copy color values and add cubes to rendering
+         out_memory[output_offset + cohort_start + cohort_index * 9 + 1] = grid_in[input_offset + (x - 1) * compound_grid_size * compound_grid_size + (y - 1) * compound_grid_size + (z - 1)]; // xyz
+         out_memory[output_offset + cohort_start + cohort_index * 9 + 2] = grid_in[input_offset + (x - 0) * compound_grid_size * compound_grid_size + (y - 1) * compound_grid_size + (z - 1)]; // Xyz
+         out_memory[output_offset + cohort_start + cohort_index * 9 + 3] = grid_in[input_offset + (x - 1) * compound_grid_size * compound_grid_size + (y - 0) * compound_grid_size + (z - 1)]; // xYz
+         out_memory[output_offset + cohort_start + cohort_index * 9 + 4] = grid_in[input_offset + (x - 0) * compound_grid_size * compound_grid_size + (y - 0) * compound_grid_size + (z - 1)]; // XYz
+         out_memory[output_offset + cohort_start + cohort_index * 9 + 5] = grid_in[input_offset + (x - 1) * compound_grid_size * compound_grid_size + (y - 1) * compound_grid_size + (z - 0)]; // xyZ
+         out_memory[output_offset + cohort_start + cohort_index * 9 + 6] = grid_in[input_offset + (x - 0) * compound_grid_size * compound_grid_size + (y - 1) * compound_grid_size + (z - 0)]; // XyZ
+         out_memory[output_offset + cohort_start + cohort_index * 9 + 7] = grid_in[input_offset + (x - 1) * compound_grid_size * compound_grid_size + (y - 0) * compound_grid_size + (z - 0)]; // xYZ
+         out_memory[output_offset + cohort_start + cohort_index * 9 + 8] = grid_in[input_offset + (x - 0) * compound_grid_size * compound_grid_size + (y - 0) * compound_grid_size + (z - 0)]; // XYZ
+      
+         vec3 compound_pos = vec3(uintBitsToFloat(compounds[compound_start + 5]), uintBitsToFloat(compounds[compound_start + 6]), uintBitsToFloat(compounds[compound_start + 7]));
+         vec3 check_pos = compound_pos + vec3(float(x) * compound_scale, float(y) * compound_scale, float(z) * compound_scale) + mid_offset;
+         if (out_memory[output_offset + cohort_start + cohort_index * 9 + 1] != 0) {
+            add_cube(input_offset + (z - 1) * compound_grid_size * compound_grid_size + (y - 1) * compound_grid_size + (x - 1), compound_scale, check_pos - vec3(1.0, 1.0, 1.0) * compound_scale, unpack_color(out_memory[output_offset + cohort_start + cohort_index * 9 + 1]));
+         }
+         if (out_memory[output_offset + cohort_start + cohort_index * 9 + 2] != 0) {
+            add_cube(input_offset + (z - 1) * compound_grid_size * compound_grid_size + (y - 1) * compound_grid_size + (x - 0), compound_scale, check_pos - vec3(0.0, 1.0, 1.0) * compound_scale, unpack_color(out_memory[output_offset + cohort_start + cohort_index * 9 + 2]));
+         }
+         if (out_memory[output_offset + cohort_start + cohort_index * 9 + 3] != 0) {
+            add_cube(input_offset + (z - 1) * compound_grid_size * compound_grid_size + (y - 0) * compound_grid_size + (x - 1), compound_scale, check_pos - vec3(1.0, 0.0, 1.0) * compound_scale, unpack_color(out_memory[output_offset + cohort_start + cohort_index * 9 + 3]));
+         }
+         if (out_memory[output_offset + cohort_start + cohort_index * 9 + 4] != 0) {
+            add_cube(input_offset + (z - 1) * compound_grid_size * compound_grid_size + (y - 0) * compound_grid_size + (x - 0), compound_scale, check_pos - vec3(0.0, 0.0, 1.0) * compound_scale, unpack_color(out_memory[output_offset + cohort_start + cohort_index * 9 + 4]));
+         }
+         if (out_memory[output_offset + cohort_start + cohort_index * 9 + 5] != 0) {
+            add_cube(input_offset + (z - 0) * compound_grid_size * compound_grid_size + (y - 1) * compound_grid_size + (x - 1), compound_scale, check_pos - vec3(1.0, 1.0, 0.0) * compound_scale, unpack_color(out_memory[output_offset + cohort_start + cohort_index * 9 + 5]));
+         }
+         if (out_memory[output_offset + cohort_start + cohort_index * 9 + 6] != 0) {
+            add_cube(input_offset + (z - 0) * compound_grid_size * compound_grid_size + (y - 1) * compound_grid_size + (x - 0), compound_scale, check_pos - vec3(0.0, 1.0, 0.0) * compound_scale, unpack_color(out_memory[output_offset + cohort_start + cohort_index * 9 + 6]));
+         }
+         if (out_memory[output_offset + cohort_start + cohort_index * 9 + 7] != 0) {
+            add_cube(input_offset + (z - 0) * compound_grid_size * compound_grid_size + (y - 0) * compound_grid_size + (x - 1), compound_scale, check_pos - vec3(1.0, 0.0, 0.0) * compound_scale, unpack_color(out_memory[output_offset + cohort_start + cohort_index * 9 + 7]));
+         }
+         if (out_memory[output_offset + cohort_start + cohort_index * 9 + 8] != 0) {
+            add_cube(input_offset + (z - 0) * compound_grid_size * compound_grid_size + (y - 0) * compound_grid_size + (x - 0), compound_scale, check_pos - vec3(0.0, 0.0, 0.0) * compound_scale, unpack_color(out_memory[output_offset + cohort_start + cohort_index * 9 + 8]));
+         }
+      }
+   } else {
+      out_memory[output_offset + cohort_start + cohort_index * 9 + 0] = 0;
+      out_memory[output_offset + cohort_start + cohort_index * 9 + 1] = 0;
+      out_memory[output_offset + cohort_start + cohort_index * 9 + 2] = 0;
+      out_memory[output_offset + cohort_start + cohort_index * 9 + 3] = 0;
+      out_memory[output_offset + cohort_start + cohort_index * 9 + 4] = 0;
+      out_memory[output_offset + cohort_start + cohort_index * 9 + 5] = 0;
+      out_memory[output_offset + cohort_start + cohort_index * 9 + 6] = 0;
+      out_memory[output_offset + cohort_start + cohort_index * 9 + 7] = 0;
+      out_memory[output_offset + cohort_start + cohort_index * 9 + 8] = 0;
+   }
+}
\ No newline at end of file
diff --git a/shaders/rt_compute_rasterize.comp b/shaders/rt_compute_rasterize.comp
index 8603805..67912b2 100644
--- a/shaders/rt_compute_rasterize.comp
+++ b/shaders/rt_compute_rasterize.comp
@@ -349,7 +349,7 @@ void main() {
         if (render) {
             grid[output_offset + x * compound_grid_size * compound_grid_size + y * compound_grid_size + z] = color_int;
             transparent_grid[output_offset + x * compound_grid_size * compound_grid_size + y * compound_grid_size + z] = transparent;
-            add_cube(output_offset + index * compound_grid_size + z, compound_scale, check_pos, color);
+            //add_cube(output_offset + index * compound_grid_size + z, compound_scale, check_pos, color);
         } else {
             grid[output_offset + x * compound_grid_size * compound_grid_size + y * compound_grid_size + z] = 0;
             transparent_grid[output_offset + x * compound_grid_size * compound_grid_size + y * compound_grid_size + z] = false;
diff --git a/src/app_data.rs b/src/app_data.rs
index 0dafc31..bfacaf4 100644
--- a/src/app_data.rs
+++ b/src/app_data.rs
@@ -27,7 +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 pipeline_compute_mempos: vk::Pipeline,
 
     pub framebuffers: Vec<vk::Framebuffer>,
     pub command_pool: vk::CommandPool,
@@ -60,6 +60,9 @@ pub struct AppData {
     pub compute_out_storage_buffers_size_three: Vec<vk::Buffer>,
     pub compute_out_storage_buffers_memory_size_three: Vec<vk::DeviceMemory>,
 
+    pub compute_out_storage_buffers_oct_tree: Vec<vk::Buffer>,
+    pub compute_out_storage_buffers_memory_oct_tree: Vec<vk::DeviceMemory>,
+
     pub compute_out_cuboid_buffers: Vec<vk::Buffer>,
     pub compute_out_cuboid_buffers_memory: Vec<vk::DeviceMemory>,
 
@@ -92,6 +95,8 @@ pub struct AppData {
     pub compute_task_one_size: usize,
     pub compute_task_one_out_buffer_size: u64,
     pub compute_task_one_out_size: u64,
+    pub compute_task_oct_tree_size: u64,
+    pub compute_task_oct_tree_nodes: u64,
     // values passed to shader
     pub num_lights_per_volume: u32,
     pub min_light_weight: f32,
diff --git a/src/buffer.rs b/src/buffer.rs
index 8374162..c2b7572 100644
--- a/src/buffer.rs
+++ b/src/buffer.rs
@@ -206,7 +206,7 @@ pub unsafe fn create_descriptor_set_layout(
         .binding(2)
         .descriptor_type(vk::DescriptorType::STORAGE_BUFFER)
         .descriptor_count(1)
-        .stage_flags(vk::ShaderStageFlags::FRAGMENT);
+        .stage_flags(vk::ShaderStageFlags::FRAGMENT | vk::ShaderStageFlags::COMPUTE);
 
     let storage_binding_compute_in = vk::DescriptorSetLayoutBinding::builder()
         .binding(3)
@@ -250,7 +250,13 @@ pub unsafe fn create_descriptor_set_layout(
         .descriptor_count(1)
         .stage_flags(vk::ShaderStageFlags::FRAGMENT | vk::ShaderStageFlags::COMPUTE);
 
-    let bindings = &[ubo_binding, sampler_binding, storage_binding_render, storage_binding_compute_in, storage_binding_compute_out_color, storage_binding_compute_cuboid_out, storage_binding_compute_cuboid_index_out, storage_binding_compute_out_size_two, storage_binding_compute_out_size_three, storage_binding_compute_out_size_transparent];
+    let storage_binding_compute_out_oct_tree = vk::DescriptorSetLayoutBinding::builder()
+        .binding(10)
+        .descriptor_type(vk::DescriptorType::STORAGE_BUFFER)
+        .descriptor_count(1)
+        .stage_flags(vk::ShaderStageFlags::FRAGMENT | vk::ShaderStageFlags::COMPUTE);
+
+    let bindings = &[ubo_binding, sampler_binding, storage_binding_render, storage_binding_compute_in, storage_binding_compute_out_color, storage_binding_compute_cuboid_out, storage_binding_compute_cuboid_index_out, storage_binding_compute_out_size_two, storage_binding_compute_out_size_three, storage_binding_compute_out_size_transparent, storage_binding_compute_out_oct_tree];
     let info = vk::DescriptorSetLayoutCreateInfo::builder()
         .bindings(bindings);
     
@@ -311,6 +317,9 @@ pub unsafe fn create_storage_buffers(
     data.compute_out_cuboid_index_buffers.clear();
     data.compute_out_cuboid_index_buffers_memory.clear();
 
+    data.compute_out_storage_buffers_oct_tree.clear();
+    data.compute_out_storage_buffers_memory_oct_tree.clear();
+
     for _ in 0..data.swapchain_images.len() {
         let (storage_buffer, storage_buffer_memory) = create_buffer(
             instance,
@@ -363,7 +372,7 @@ pub unsafe fn create_storage_buffers(
             instance,
             device,
             data,
-            (size_of::<u32>() * 2) as u64 * data.compute_task_one_out_buffer_size.max(1),
+            (size_of::<u32>()) as u64 * data.compute_task_one_out_buffer_size.max(1),
             vk::BufferUsageFlags::STORAGE_BUFFER,
             vk::MemoryPropertyFlags::DEVICE_LOCAL,
         )?;
@@ -375,7 +384,7 @@ pub unsafe fn create_storage_buffers(
             instance,
             device,
             data,
-            (size_of::<u32>() * 3) as u64 * data.compute_task_one_out_buffer_size.max(1),
+            (size_of::<u32>()) as u64 * data.compute_task_one_out_buffer_size.max(1),
             vk::BufferUsageFlags::STORAGE_BUFFER,
             vk::MemoryPropertyFlags::DEVICE_LOCAL,
         )?;
@@ -383,6 +392,18 @@ pub unsafe fn create_storage_buffers(
         data.compute_out_storage_buffers_size_three.push(storage_buffer);
         data.compute_out_storage_buffers_memory_size_three.push(storage_buffer_memory);
 
+        let (storage_buffer, storage_buffer_memory) = create_buffer(
+            instance,
+            device,
+            data,
+            (size_of::<u32>()) as u64 * data.compute_task_oct_tree_size.max(1),
+            vk::BufferUsageFlags::STORAGE_BUFFER,
+            vk::MemoryPropertyFlags::DEVICE_LOCAL,
+        )?;
+
+        data.compute_out_storage_buffers_oct_tree.push(storage_buffer);
+        data.compute_out_storage_buffers_memory_oct_tree.push(storage_buffer_memory);
+
         let (storage_buffer, storage_buffer_memory) = create_buffer(
             instance,
             device,
@@ -551,8 +572,12 @@ pub unsafe fn create_descriptor_pool(device: &Device, data: &mut app_data::AppDa
     let compute_out_storage_transparent_size = vk::DescriptorPoolSize::builder()
         .type_(vk::DescriptorType::STORAGE_BUFFER)
         .descriptor_count(data.swapchain_images.len() as u32);
+
+    let compute_out_storage_oct_tree = vk::DescriptorPoolSize::builder()
+        .type_(vk::DescriptorType::STORAGE_BUFFER)
+        .descriptor_count(data.swapchain_images.len() as u32);
     
-    let pool_sizes = &[ubo_size, sampler_size, render_storage_size, compute_in_storage_size, compute_out_storage_color_size, compute_out_cuboid_size, compute_out_cuboid_index_size, compute_out_storage_size_two_size, compute_out_storage_size_three_size, compute_out_storage_transparent_size];
+    let pool_sizes = &[ubo_size, sampler_size, render_storage_size, compute_in_storage_size, compute_out_storage_color_size, compute_out_cuboid_size, compute_out_cuboid_index_size, compute_out_storage_size_two_size, compute_out_storage_size_three_size, compute_out_storage_transparent_size, compute_out_storage_oct_tree];
     let info = vk::DescriptorPoolCreateInfo::builder()
         .pool_sizes(pool_sizes)
         .max_sets(data.swapchain_images.len() as u32);
@@ -625,7 +650,7 @@ pub unsafe fn create_descriptor_sets(device: &Device, data: &mut app_data::AppDa
         let info = vk::DescriptorBufferInfo::builder()
             .buffer(data.compute_out_storage_buffers_color[i])
             .offset(0)
-            .range((size_of::<u32>() * 3) as u64 * data.compute_task_one_out_buffer_size.max(1));
+            .range((size_of::<u32>()) as u64 * data.compute_task_one_out_buffer_size.max(1));
         let storage_info = &[info];
 
         let storage_write_compute_out_color = vk::WriteDescriptorSet::builder()
@@ -638,7 +663,7 @@ pub unsafe fn create_descriptor_sets(device: &Device, data: &mut app_data::AppDa
         let info = vk::DescriptorBufferInfo::builder()
             .buffer(data.compute_out_storage_buffers_size_two[i])
             .offset(0)
-            .range((size_of::<u32>() * 2) as u64 * data.compute_task_one_out_buffer_size.max(1));
+            .range((size_of::<u32>()) as u64 * data.compute_task_one_out_buffer_size.max(1));
         let storage_info = &[info];
 
         let storage_write_compute_out_size_two = vk::WriteDescriptorSet::builder()
@@ -651,7 +676,7 @@ pub unsafe fn create_descriptor_sets(device: &Device, data: &mut app_data::AppDa
         let info = vk::DescriptorBufferInfo::builder()
             .buffer(data.compute_out_storage_buffers_size_three[i])
             .offset(0)
-            .range((size_of::<u32>() * 3) as u64 * data.compute_task_one_out_buffer_size.max(1));
+            .range((size_of::<u32>()) as u64 * data.compute_task_one_out_buffer_size.max(1));
         let storage_info = &[info];
 
         let storage_write_compute_out_size_three = vk::WriteDescriptorSet::builder()
@@ -664,7 +689,7 @@ pub unsafe fn create_descriptor_sets(device: &Device, data: &mut app_data::AppDa
         let info = vk::DescriptorBufferInfo::builder()
             .buffer(data.compute_out_storage_buffers_transparent[i])
             .offset(0)
-            .range((size_of::<bool>() * 3) as u64 * data.compute_task_one_out_buffer_size.max(1));
+            .range((size_of::<bool>()) as u64 * data.compute_task_one_out_buffer_size.max(1));
         let storage_info = &[info];
 
         let storage_write_compute_out_transparent = vk::WriteDescriptorSet::builder()
@@ -674,6 +699,19 @@ pub unsafe fn create_descriptor_sets(device: &Device, data: &mut app_data::AppDa
             .descriptor_type(vk::DescriptorType::STORAGE_BUFFER)
             .buffer_info(storage_info);
 
+        let info = vk::DescriptorBufferInfo::builder()
+            .buffer(data.compute_out_storage_buffers_oct_tree[i])
+            .offset(0)
+            .range((size_of::<u32>()) as u64 * data.compute_task_oct_tree_size.max(1));
+        let storage_info = &[info];
+
+        let storage_write_compute_out_oct_tree = vk::WriteDescriptorSet::builder()
+            .dst_set(data.descriptor_sets[i])
+            .dst_binding(10)
+            .dst_array_element(0)
+            .descriptor_type(vk::DescriptorType::STORAGE_BUFFER)
+            .buffer_info(storage_info);
+
         let info = vk::DescriptorBufferInfo::builder()
             .buffer(data.compute_out_cuboid_buffers[i])
             .offset(0)
@@ -702,7 +740,7 @@ pub unsafe fn create_descriptor_sets(device: &Device, data: &mut app_data::AppDa
         
 
         device.update_descriptor_sets(
-            &[ubo_write, sampler_write, storage_write_render, storage_write_compute_in, storage_write_compute_out_color, storage_write_compute_cuboid_out, storage_write_compute_cuboid_index_out, storage_write_compute_out_size_two, storage_write_compute_out_size_three, storage_write_compute_out_transparent],
+            &[ubo_write, sampler_write, storage_write_render, storage_write_compute_in, storage_write_compute_out_color, storage_write_compute_cuboid_out, storage_write_compute_cuboid_index_out, storage_write_compute_out_size_two, storage_write_compute_out_size_three, storage_write_compute_out_transparent, storage_write_compute_out_oct_tree],
             &[] as &[vk::CopyDescriptorSet],
         );
     }
diff --git a/src/command_buffer.rs b/src/command_buffer.rs
index e477391..7b6289b 100644
--- a/src/command_buffer.rs
+++ b/src/command_buffer.rs
@@ -156,6 +156,13 @@ pub unsafe fn create_command_buffers(device: &Device, data: &mut app_data::AppDa
                     &[]);
             
             device.cmd_dispatch(*command_buffer, (data.compute_task_one_size as f64 / 16.0).ceil() as u32, 1, 1);
+            
+            let buffer_memory_barrier_in = vk::BufferMemoryBarrier::builder()
+                .buffer(data.compute_out_storage_buffers_size_three[i])
+                .src_access_mask(vk::AccessFlags::SHADER_READ)
+                .dst_access_mask(vk::AccessFlags::SHADER_WRITE)
+                .size(vk::WHOLE_SIZE as u64)
+                .build();
 
             let buffer_memory_barrier_out = vk::BufferMemoryBarrier::builder()
                 .buffer(data.compute_out_storage_buffers_size_two[i])
@@ -169,7 +176,7 @@ pub unsafe fn create_command_buffers(device: &Device, data: &mut app_data::AppDa
                 vk::PipelineStageFlags::COMPUTE_SHADER,
                 vk::DependencyFlags::DEVICE_GROUP,
                 &[] as &[vk::MemoryBarrier],
-                &[buffer_memory_barrier_out],
+                &[buffer_memory_barrier_in, buffer_memory_barrier_out],
                 &[] as &[vk::ImageMemoryBarrier]);
 
             // grow z axis
@@ -185,6 +192,13 @@ pub unsafe fn create_command_buffers(device: &Device, data: &mut app_data::AppDa
                     &[]);
             
             device.cmd_dispatch(*command_buffer, (data.compute_task_one_size as f64 / 16.0).ceil() as u32, 1, 1);
+            
+            let buffer_memory_barrier_in = vk::BufferMemoryBarrier::builder()
+                .buffer(data.compute_out_storage_buffers_size_two[i])
+                .src_access_mask(vk::AccessFlags::SHADER_READ)
+                .dst_access_mask(vk::AccessFlags::SHADER_WRITE)
+                .size(vk::WHOLE_SIZE as u64)
+                .build();
 
             let buffer_memory_barrier_out = vk::BufferMemoryBarrier::builder()
                 .buffer(data.compute_out_storage_buffers_size_three[i])
@@ -198,12 +212,12 @@ pub unsafe fn create_command_buffers(device: &Device, data: &mut app_data::AppDa
                 vk::PipelineStageFlags::COMPUTE_SHADER,
                 vk::DependencyFlags::DEVICE_GROUP,
                 &[] as &[vk::MemoryBarrier],
-                &[buffer_memory_barrier_out],
+                &[buffer_memory_barrier_in, buffer_memory_barrier_out],
                 &[] as &[vk::ImageMemoryBarrier]);
 
-            // combine element
+            // calculate mem size
             device.cmd_bind_pipeline(
-                *command_buffer, vk::PipelineBindPoint::COMPUTE, data.pipeline_compute_combine);
+                *command_buffer, vk::PipelineBindPoint::COMPUTE, data.pipeline_compute_mempos);
 
             device.cmd_bind_descriptor_sets(
                 *command_buffer, 
@@ -213,10 +227,17 @@ pub unsafe fn create_command_buffers(device: &Device, data: &mut app_data::AppDa
                 &[data.descriptor_sets[i]],
                     &[]);
             
-            device.cmd_dispatch(*command_buffer, (data.compute_task_one_size as f64 / 16.0).ceil() as u32, 1, 1);
+            device.cmd_dispatch(*command_buffer, data.compute_task_oct_tree_nodes as u32, 1, 1);
+            
+            let buffer_memory_barrier_in = vk::BufferMemoryBarrier::builder()
+                .buffer(data.compute_out_storage_buffers_size_three[i])
+                .src_access_mask(vk::AccessFlags::SHADER_READ)
+                .dst_access_mask(vk::AccessFlags::SHADER_WRITE)
+                .size(vk::WHOLE_SIZE as u64)
+                .build();
 
             let buffer_memory_barrier_out = vk::BufferMemoryBarrier::builder()
-                .buffer(data.render_storage_buffers[i])
+                .buffer(data.compute_out_storage_buffers_size_two[i])
                 .src_access_mask(vk::AccessFlags::SHADER_WRITE)
                 .dst_access_mask(vk::AccessFlags::SHADER_READ)
                 .size(vk::WHOLE_SIZE as u64)
@@ -224,10 +245,10 @@ pub unsafe fn create_command_buffers(device: &Device, data: &mut app_data::AppDa
 
             device.cmd_pipeline_barrier(*command_buffer,
                 vk::PipelineStageFlags::COMPUTE_SHADER,
-                vk::PipelineStageFlags::FRAGMENT_SHADER,
+                vk::PipelineStageFlags::COMPUTE_SHADER,
                 vk::DependencyFlags::DEVICE_GROUP,
                 &[] as &[vk::MemoryBarrier],
-                &[buffer_memory_barrier_out],
+                &[buffer_memory_barrier_in, buffer_memory_barrier_out],
                 &[] as &[vk::ImageMemoryBarrier]);
         }
         // start render pass
diff --git a/src/main.rs b/src/main.rs
index 1b2714e..d5905b4 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -441,13 +441,20 @@ impl App {
             .iter()
             .for_each(|m| self.device.free_memory(*m, None));
 
-            self.data.compute_out_storage_buffers_size_three
+        self.data.compute_out_storage_buffers_size_three
             .iter()
             .for_each(|b| self.device.destroy_buffer(*b, None));
         self.data.compute_out_storage_buffers_memory_size_three
             .iter()
             .for_each(|m| self.device.free_memory(*m, None));
 
+        self.data.compute_out_storage_buffers_oct_tree
+            .iter()
+            .for_each(|b| self.device.destroy_buffer(*b, None));
+        self.data.compute_out_storage_buffers_memory_oct_tree
+            .iter()
+            .for_each(|m| self.device.free_memory(*m, None));
+
         self.data.compute_out_cuboid_buffers
             .iter()
             .for_each(|b| self.device.destroy_buffer(*b, None));
@@ -474,7 +481,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(self.data.pipeline_compute_mempos, None);
 
         self.device.destroy_pipeline_layout(self.data.pipeline_layout, None);
         self.device.destroy_render_pass(self.data.render_pass, None);
@@ -897,13 +904,13 @@ unsafe fn create_pipeline(device: &Device, data: &mut app_data::AppData) -> Resu
         .name(b"main\0");
 
     // load the byte data
-    let compute_bytes = include_bytes!("../shaders/compiled/rt_compute_combine.spv");
+    let compute_bytes = include_bytes!("../shaders/compiled/rt_compute_mempos.spv");
     // create the shaders
-    let compute_shader_module_combine = create_shader_module(device, &compute_bytes[..])?;
+    let compute_shader_module_mempos = create_shader_module(device, &compute_bytes[..])?;
     //create the shader stage for the compute shader
-    let compute_stage_combine = vk::PipelineShaderStageCreateInfo::builder()
+    let compute_stage_mempos = vk::PipelineShaderStageCreateInfo::builder()
         .stage(vk::ShaderStageFlags::COMPUTE)
-        .module(compute_shader_module_combine)
+        .module(compute_shader_module_mempos)
         .name(b"main\0");
 
     // define input assembly and object type. This is altered when using geometry shader
@@ -1062,11 +1069,11 @@ unsafe fn create_pipeline(device: &Device, data: &mut app_data::AppData) -> Resu
         .stage(compute_stage_grow_three)
         .layout(data.pipeline_layout);
 
-    let info_compute_combine = vk::ComputePipelineCreateInfo::builder()
-        .stage(compute_stage_combine)
+    let info_compute_mempos = vk::ComputePipelineCreateInfo::builder()
+        .stage(compute_stage_mempos)
         .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;
+    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_mempos], None)?.0;
 
     data.pipeline_cube = pipelines[0];
     data.pipeline_cuboid = pipelines[1];
@@ -1076,7 +1083,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];
+    data.pipeline_compute_mempos = compute_pipelines[4];
 
     device.destroy_shader_module(vert_shader_module_cube, None);
     device.destroy_shader_module(geo_shader_module_cube, None);
@@ -1093,7 +1100,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);
+    device.destroy_shader_module(compute_shader_module_mempos, None);
 
     Ok(())
 }
diff --git a/src/scene/generators.rs b/src/scene/generators.rs
index 3b7f372..c628790 100644
--- a/src/scene/generators.rs
+++ b/src/scene/generators.rs
@@ -127,12 +127,12 @@ pub fn generate_test_scene(scene: &mut Scene, data: &mut AppData) -> Result<(Poi
     let mut comp = ShapeComposition::new(64);
     comp.included_shapes.push(Rc::new(RefCell::new(Cone::new(Vector3 { x: 20.0 + grid_size as f32, y: 5.0 + grid_size as f32, z: 10.0 }, Vector3 { x: 0.0, y: 0.0, z: 0.0 }, 0.0, 2.5, Vector3 { x: 0.0, y: 10.0, z: 0.0 },Vector3 { x: 0, y: 255, z: 0 }, 64, false))));
     comp.excluded_shapes.push(Rc::new(RefCell::new(Cone::new(Vector3 { x: 20.0 + grid_size as f32, y: 5.0 + grid_size as f32, z: 10.0 }, Vector3 { x: 0.0, y: 0.0, z: 0.0 }, 0.0, 1.5, Vector3 { x: 0.0, y: 10.0, z: 0.0 },Vector3 { x: 0, y: 255, z: 0 }, 64, false))));
-    scene.volumetrics.push(Rc::new(RefCell::new(comp)));
+    //scene.volumetrics.push(Rc::new(RefCell::new(comp)));
 
     let mut comp = ShapeComposition::new(64);
     comp.included_shapes.push(Rc::new(RefCell::new(Rect::new(Vector3 { x: -5.0 + grid_size as f32, y: 5.0 + grid_size as f32, z: 10.0 }, Vector3 { x: 0.0, y: 0.0, z: 0.0 }, Vector3 { x: 5.0, y: 10.0, z: 2.0 },Vector3 { x: 0, y: 0, z: 255 }, 64, false))));
     comp.excluded_shapes.push(Rc::new(RefCell::new(Rect::new(Vector3 { x: -5.0 + grid_size as f32, y: 5.0 + grid_size as f32, z: 10.0 }, Vector3 { x: 0.0, y: 0.0, z: 0.0 }, Vector3 { x: 3.0, y: 8.0, z: 2.0 },Vector3 { x: 0, y: 0, z: 255 }, 64, false))));
-    scene.volumetrics.push(Rc::new(RefCell::new(comp)));
+    //scene.volumetrics.push(Rc::new(RefCell::new(comp)));
 
     Ok((cgmath::point3(5.0, 5.0, 10.0)))
 }
diff --git a/src/scene/mod.rs b/src/scene/mod.rs
index 6fc3b0c..924bed0 100644
--- a/src/scene/mod.rs
+++ b/src/scene/mod.rs
@@ -227,7 +227,12 @@ impl Scene {
 
         let mut compute_task_one_size = 0;
         let mut compute_task_one_out_size = 0;
+        let mut target_index = 1;
+        let mut node_count = 0;
         for compound in &self.volumetrics {
+            compound.borrow_mut().target_memory_start = target_index;
+            target_index += compound.borrow().get_target_buffer_mem_size();
+            node_count += compound.borrow().get_num_nodes();
             volumetrics_memory = compound.borrow_mut().insert_into_memory(volumetrics_memory, data, &self);
             compute_task_one_size += compound.borrow().size.pow(2) as usize;
             compute_task_one_out_size += compound.borrow().size.pow(3) as usize;
@@ -238,6 +243,8 @@ impl Scene {
         data.compute_task_one_size = compute_task_one_size;
         data.compute_task_one_out_buffer_size = (compute_task_one_out_size * 4) as u64;
         data.compute_task_one_out_size = compute_task_one_out_size as u64;
+        data.compute_task_oct_tree_size = target_index as u64;
+        data.compute_task_oct_tree_nodes = node_count as u64;
     }
 
     pub unsafe fn destroy(&mut self, device: &vulkanalia::Device) {
diff --git a/src/scene/volumetrics/mod.rs b/src/scene/volumetrics/mod.rs
index 8e7ade9..8797cc3 100644
--- a/src/scene/volumetrics/mod.rs
+++ b/src/scene/volumetrics/mod.rs
@@ -31,6 +31,7 @@ enum ShapeTypes {
 #[derive(Clone, Debug)]
 pub struct ShapeComposition {
     memory_start: usize,
+    pub target_memory_start: u32,
     prev_memory_size: u32,
     pub size: u32,
     pub included_shapes: Vec<Rc<RefCell<dyn Volumetrics>>>,
@@ -40,7 +41,7 @@ pub struct ShapeComposition {
 
 impl ShapeComposition {
     pub fn new(size: u32) -> Self {
-        Self { memory_start: 0, prev_memory_size: 0, size: size, included_shapes: vec![], excluded_shapes: vec![], dirty: true }
+        Self { memory_start: 0, target_memory_start: 0, prev_memory_size: 0, size: size, included_shapes: vec![], excluded_shapes: vec![], dirty: true }
     }
 }
 
@@ -142,6 +143,25 @@ impl Memorizable for ShapeComposition {
     }
 }
 
+impl ShapeComposition {
+    pub fn get_num_nodes(&self) -> u32 {
+        let mut nodes = 0;
+        let mut add_size = 1;
+        let mut size = self.size;
+        while  size >= 2 {
+            nodes += add_size;
+            add_size *= 8;
+            size /= 2;
+        }
+
+        nodes
+    }
+
+    pub fn get_target_buffer_mem_size(&self) -> u32 {
+        self.get_num_nodes() * 9
+    }
+}
+
 #[derive(Clone, Debug, PartialEq)]
 pub struct Sphere {
     pos: Vector3<f32>,