From 66902df99c3eaecff01189024e74cd510d04c00f Mon Sep 17 00:00:00 2001
From: zomseffen <steffen@tom.bi>
Date: Thu, 30 Jan 2025 11:03:30 +0100
Subject: [PATCH] transparency first version

---
 shaders/compiled/frag_rt_quad.spv | Bin 28684 -> 34356 bytes
 shaders/compiled/vert_cube.spv    | Bin 2524 -> 2572 bytes
 shaders/compiled/vert_cuboid.spv  | Bin 2656 -> 2704 bytes
 shaders/compiled/vert_rt_quad.spv | Bin 2824 -> 2872 bytes
 shaders/cube.vert                 |   1 +
 shaders/cuboid.vert               |   1 +
 shaders/rt_quad.frag              | 118 +++++++++++++++++++++++++-----
 shaders/rt_quad.vert              |   1 +
 src/buffer.rs                     |  47 ++++++++++--
 src/main.rs                       |  22 +-----
 src/primitives/cube.rs            |  18 ++---
 src/scene/empty_volume.rs         |  61 ++++++++++-----
 src/scene/mod.rs                  |  18 +++--
 src/scene/oct_tree.rs             |  30 ++++----
 14 files changed, 225 insertions(+), 92 deletions(-)

diff --git a/shaders/compiled/frag_rt_quad.spv b/shaders/compiled/frag_rt_quad.spv
index c161614af1f3c7a74aac100e1e0b7072db833a5c..8a2654c17ddedafad7387f0c269c55a7530b553d 100644
GIT binary patch
literal 34356
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

literal 28684
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
D6zj0a

diff --git a/shaders/compiled/vert_cube.spv b/shaders/compiled/vert_cube.spv
index 7c214fabc49344e8cee85a07a4b6b727824c20f7..668eeae60fc5b071a7f579d3e428c42130368ddf 100644
GIT binary patch
literal 2572
zcmZ9L?UEB!5Qc}{&4Q>1@~PsQWl>kr6%`OgV3!3GB$}mA|E5ARi$f(dsYw>mU)+M;
zhBsk(Q+`xg<@3zU2?Hn9Io)sf+ow<WnZ<>*{ZX_pdNF!Ax*L`2NVEVFfh`w%t8=fj
zF`W%JE?his#Gz=h2sGvuqFhVJxSyozZz1bQ8@Y{qgLIKaehch>LR^XtMy*b-)$O)A
zw|axgq&J=YJc@gxB#nE+B##HP<WX$gfm&RW4n}*!dO(AS`q_<WKR1b@@6%*A%f~nN
zc6Z~vd;cN%xJ{$*;f}`HFdnfl^E2MNJczS#FVAME^H}SBl*B*PF>gP~vxg;C@~vUe
zAIEvWH_4{*%Q_n1d(*gA<evW6AI3RVEYdgd`x*Lj^d|a)QEw;Ce~9y0{1_9o#MSj>
z(`1%pX_43XqF(VNo!v`*p;P6V`m7nw_9&U$Os2DbI*8{yYuC3o8qIyy<IG$Qe$FmQ
z=SLQpv*Zrj*(l4)xTRvYNm@ekoHH@s#gDhMEFTs;=bof<C~7gSm%x^h!$=$3{=4i|
zoBv?173i}VkM$XzeW>%a<!vG%m)P?>dsOFX%X@+Zp4js|`&Z{_%liWfJh7*|@;<%~
z;~ZRwGmqF|uog4$-kxcXd>>~JSFl%0v*0^tSNZjoIm5dU^Uj_V-h-HR1x#Jcx;#6?
zd6x5EL0sC-zHa+XYkP)%=U%s+xwdyX%D?+6XLzRi2{h;5L{7rDSK8KcivI)bV%qv&
zVAn7IIQBvICgM6*+1|zXbQ;_DWsKMg+3c%1>tashn#3Psw=UzZRJQ#W^E~r5k$s5g
zX&*tHU$9?AcbV@fyIgBHhIWEI)Oix!73??A&1>DK*}bRO3Ys$sz0s$b-`?5_{no4P
z_bV3aX`-9g_*Hi6@&4NHvg@-4^0n71OujX|k3`Xv>&Bl)Gq<&b{GV1>urFbIhViY+
z7xHVjD=eIM8`~P3?;Uo}4Ezqd=ZPDy?Hdy_|F`UNgJ0V>Cw7Ucn8&x{lJhr+v)bYm
zXLAg3zRu9OT_xIC9Y^&2PP8*SRbkHTFEYK(?)sN_eXk*(Am&%!g15?k1~GpVF}HnR
zL&QVOS#)E<`Nq7Bi2p_&?ROA);^wiR?;-2RU1IFnxe8;OV;@wQ{RnX%R+zonVUo^r
z1CejMerNtGdG&pSc)l^#>>KzP@ts-oHTt1#+&|pk-q;8G5$<>a-8=eLLLV-oi-(xc
z(2eo^gqX|d;-L?pqstQyyf4t@HIcx(f-W9-U!uzu54@}B^6GuRhAkd=*U{ycc-i+&
z?0Vm~u*F=V$2ZV7k$T^^E3Dr4n_%*d*I)1ZEo{#(W6HjNg<bEvwsG~o+yC%JzDD=^
Zaz<@-ZGC<(J4hGN=QpMO9~ECl{s%?~xhwzx

literal 2524
zcmZ9M_fix=5XMK~z=S!Ac!&WL<{SV|y;D!YGW>gm+@fnOyVTxc`pZ|)*YG7QU&>Hr
zmEUh?`y3srZ@RzvI!yO0{e9y@&aHCm+^~D>{MzjLgg9Y?#a?edX-;;!?aA{OPQ%#X
z`U@hQjbgC|Bun#giasitkTfLsBo8ICl79X5Y5yk20k_uGo2~lnY`uA>wXnS0>U7^H
zQ7ehlsMU`1XrUXwiQugccyYRrth7TyMT{_a#SOXj%JD3X7qfin*2>~yl+V6+t$4ak
zr8v{ETguu|qJ2<*@VU#&C|hdfSyyV0OTBO6=xvB``{g`)?J=K^8df?{tBBEgHQ$bM
zW$Rb3gulq754sWQFO$|>ls}L1ZuHLkdmNp!tP^+REERjG;1_j)$7%OT{6QU|Hh)HK
z@~I{9^6j|Oolh5{-WfG=wvr^hGwNYBtcw1aQJnTt78o<r9co#U<(@ZC%rH(pgdg)1
z=V|n=mSuUn@MFGl+JjtOQ{iO{N;XLvvgtFcB5CN??C}Eq7t^Es$B#aQe%Sa;ODq=H
z|9<o+^uxyQqs08c{`aGQp&vGWUnS-T_Setfhj##v2US<Uxg+uE2XEnkgk|=aH;b6O
z50?L;d>%0F1;$QpFk*sHgJI}k)Ie_Ik&9W|?6H}1X!D(7lY?_+9NNqmo4i}~%RZ(Y
z<V4>gjagSEJLOMbu&HI2ephP;!``mnHQK8Z*74F_E1kD8BAa`_0UMPkeI!OGaH`@C
zYo`V{*GijSgOO{a_Nru+gk0F<p%$|@OJ@;pi*|g;zfIb9?N;Ls=`6GNNGC2e@72zo
z!A7Ogf9nHh2=Vu6r*E87FE+gevwHSRCocS|cIx5o^!BiJ^1$c(h<3Q(#KWE_G2+2J
zCUNfL6ny@P<4bLp?_7zQeNi?!;n&MEi;vwXG0VsMp$6)Epq-rN-;_>1aQN7~FRTBN
zbbRd`oA(BGQSY5N%!-B24<US;Gs?oOwn~^cGi8o9#P+lEXJ5o-hC3zOB+T%;BJI}B
z`XxSRyCi2N#7CczUsd~<g!s&a*v#R81l%~|(&1QsI0q%*pA`rDkOV();?U2dk_pLU
zap>9c64TbhPLvq^Fy6@$qc?M!B(t29;18d3X8uWWIXfjGKOAc24V;ni?x^{u`hgAa
zr|wU0=mY(*JD!)$9eFF(hYQldjdMvl9Nv#{E=vcuK3tKGAGrBlm5yK7<7=|P&F{K&
ze8J7{hIIVGzTcD$ZhlkJ@%6ax`?Tz^?=!N&Sk~iP(x)Y1-)kin_Wian{NZyR_Wh1*
v@_UZ&`(4>#-?8C^eW(BSM(#`J`(j27?bw|0z067YRygCE!v3v_FH8Oa#&WcY

diff --git a/shaders/compiled/vert_cuboid.spv b/shaders/compiled/vert_cuboid.spv
index e4f35031f142b9c04db55e28b96d2d349cfd3c48..239c7fb38a43525ca0d7b6725926a8158726c361 100644
GIT binary patch
literal 2704
zcmZ9M?Q#@V5Qc{&8xRyhK2;1Gq8LRZDj<qLLVyjpvVov~x0c-r4z-!tn%yA!i(Am!
z@Fpy8%8x3me4d#(%gEX4oPOWa-KS4?PiAM9_D0d3=s@&Z^e`&d;b;aXf}1b)R(q?x
zGM)@pE?hjX#ldK{Fx2LC{9JR$PA^H-Pb167266}a7U>}Okq5{uzZv#F2rw7zk6P_+
ztJ7(<Z*}{lQFlD~X&85hNg8(tNgnqn$<tW7eKorz?GJYcb%O>L^&A?}-XgQ_(quc!
zcW&%%Z^wD((G%kFsz#MHIcI}-NG|jIe2H&*9A`V-Je#0SZO!*-68~7|timYIo|Iha
zZw~$5PMr6;qin2ynMVVDcN}+%*yA61gE%LPS?UM>C_|r*-a&sn>~6;S_i;Xnp8;V@
zUfr{7oJ^7|E#hil<SU<~lda@uDplU;nK|RLK1@b8lkudN_T#CaxqG%d98S;7$KJUb
z{On<pPOmIDd&(QuvtgE(c5_9KleDDtv)|Y}jGwJ%Sw1NI?0=F@DY&^}9<VFY7CReB
zTE3zMeib~A96~n0<)oRL_(czwz^*#SQ2)=*I@SHe`mG|tPwr(uYgqRa>-QW9esVAS
zS>L*!Sij$q;3xOOuY8a5qn(WncE*uA1lOWR*1<cik@Ir~aRt0s!ouG<a2+VODd$_|
z+`T8vi=24{PF>EtygS%=m-DfJxWvvz9sBKzy~A_oqK=&jad?aWAL`h75Szmhth8GM
ziPevzIUh~r1o5q<*j!KYcOSc)*z;G|J=gyjct3j+ah<EMZ*|^Ift^2X<Q9l#-Hlln
zV`|sL{vf+~X?LZ<_D9b9jN3%^Al@fFjM(3R-#~X6?+ClT=5Q44ID5$R1iCBWx6zGj
z-ly1or`!UXJqxw*Ofi0_t>@+|_WQR!A)h9?akXD$Hy__GexKblYoNb)x#ILUhYyh`
zdVXE|^JvC4mk|H+iVOG>*gLduRc9f-c%$ONeRsg-V1K`1_s-zoM)y8>?ZwWZobm6m
z>l@C+&ZM07-seneAMSG|J-<ZPyvNycY4aD1y<8&;dv_GE|Mu9vUd7s89z#6)4QqRP
zvf}LNpG10#-SrRlp1p~Dh8SOc4ZlV9Gl=n<h_UU<5+WaL-bL3Y+^@}hi2Sd_5uZi$
zlQ)j_{s37<?qg$3&s7}Tl>4aStVgi>xZ<qMCY`p|D~SHud+tp9LR`;2LA+lZb9P2P
zMVv!(zD7O7+WpP@t&MfC9^s7_(0!w`6zXshT|U@+fv%176>Kh}%ZECAiLRe~@cRl~
zza|p=uAs{Yzpv5tl@ESb(e<m>{Tf(4_+3ZWx8%#ZuY&7!UjxgzLXB^ruOjujuUA~X
z?l<A|*WUAb-EV=tzqBdqej8k`yI8w=-K~F^k-O-AfA(mDUF@0P(<ahEJoB3q2fr=!
P2i2M1m-t^^a~b&$h|a{a

literal 2656
zcmZ9NYjYGu6o!W+n;@u&TvZGk;w6g48z726Lcm>hHHksLZiVawhuX}fW;cj_;xFjm
z@K0F&DKAx4`8+ezYeT2b_Bn6A=hEl&!1UDOT#_70jwa6~cawS@Po_W;u-R(w^tO7-
zqw!$*(&hJMJfBQgL^;RsbIl-o+gYwYk1Qcw<O}3$WF6T=zD1__n_~Zi05i#vq|@tn
z*4I0|JN=#g{r+hD(=hE1vpnq&vNGKnXAe_(ha+B=?+gzHF`)$`uA!C8CC`%MyFA-1
z%Dr0$ySr(*e(wSCxK*n<<2czX2I-J}mOuI4>3&-5^~++6I^kOH!z}$V#_Ym=Sv;t*
zI-fNhjM9D;WAwxJAT7x@P0zsZ73j0cIrRI({zh7UpO)kFQSD#j>Yf#&Y@8K2?750x
z)g_+g<E`vxI$~}0nYH1wHq7>KXQT0UzLQSQtkJWB;c#+hJ<iD0;?G%S`6Ok9IXmvK
zRt$@>=FL>I%<>x2&$+_6n?71AigHl-Ip-{&KwvY~+~HMaYx@SWyuL*T`zZD-@&eMu
zb`Gu<(&abUixv7L#^Zg$&pyR|+WM^^A(q(Fe)cf-)7I}X68yxT_OrjSpSFI#Bf(GX
zf4}-Zz7u&qxDNC1j>fkizLg7zE7%LQS;h4Ixa^zDJYwEU%spVn6tjkasf$^Ix%CaX
zeGB1jnA>*{+kVg5=J4D%5ZlgQJH+#wk8NkKZ4D=2$y>nERzHpATWBL^h;QGtt@SLw
zhuOunPx1Q<dmC|GZ0sZGzNK^6-cyd)Jf8O17_rD{!}VV>YmjrTv7LpOxsI{7kwb{N
zw9R8J!9I@eGTw{q`kMbF+9~!><7sqPuwO<ut~I~H?w!Tv(VS1{gJ+8IUuCy%o?EYW
z=xwOyJeYCix7n@7yW870*v(@M&);O1D{egPr3N#e+_#Y=d3;m8{~73OZ6V)B4HoPx
z*yfbqY0g4??QVmGe7-Mhu)eR@%^CcA=;jlbukHH_^?!q|Z#dWXJ&MUUpYKtA$me_X
z{0iTYd7Pz7&R-yY+pARJEKeZ52WRe_ufwiqTc7;~+ZmrhP9o0uPa?g<?)nG5XJ?TQ
z5#y_`;@4(hK#cFqjP0B*AmV|uh%P7Om-8AT{wr~`Uq|#4H;(;&3t2)o;n>rQ4aPRX
z-f1xV5qR%5n7!Fx($0Dr(O<sjzKLIm>)CsV`Q=!%Z{!2ScWKQx=!dqvzq!A?u@Ckm
z-0>2+cl0fVK3ql@51fzD<@mk==PJ5*=)))I`iTd>Pto;@dwdOBJotTvuCI9TyN<43
z-1i&U;=%7Gy1q4D_k9IB?)xgXm@D-77WxVj_kFFw;=bPo(_g;lao_J?o4@ANeg7Og
x?z^_UxbOBqypb=_{r;R$mtEU4zo!kvZ^<*iIql%Lh3<Fc*(SU8zue|3@*frcz$^d&

diff --git a/shaders/compiled/vert_rt_quad.spv b/shaders/compiled/vert_rt_quad.spv
index 87bf2ac84c9aec689dbfae2c3194ae9683b22846..f89cebab28a8c4fce1b823a9904031e00bbc5a1d 100644
GIT binary patch
literal 2872
zcmZ9M`*IXT6vmtE1q3f3R~6%ic!{796%a)r;kHp$6NpCtn_6}|v8maat=ZXl`HNT3
z*YG7QU&>3BReryjIlBX$`qJlo=hCN7pV`L3@<HbgxFhZb_q{9EF}EPbiE9^ox3}F}
zo#eySOP4R=@uF)Kj`+MJjnx!J{g5EPA*={r2=|4rg)L!Q_*U2v8v0w%{-=^O-C@`5
zMcvKKZtre17>}b#{&Vc3I3zwAhRhH0u<!9ZRPzhTAf68E4lQ}q>u9-yx|PmM!fu+4
zZcTT0eYW}NvGVC=t->a=8>K@ZYj5ihf9|#C(@~VAxx|?-_3j7%W1XWD<1Bq#a%DU<
z4EiIV^`mh*A-=4mC4M^bQIUJ{Lx1QqRnbrn#Xm|Vx83WK_u^>FXFER2{ZCTGmOL`H
zbQ1EACPiNSi+bThl5dA!)T#1JY}Bln+i@7*36s2^4E!vP+ObXJcxIy>-jCJNAMY5F
z*^vduyJr1K?lbX~AMYHJhclK~-hDrfrz5|e_p@9~yO@KJ?9^D!X&1ARW?^rB5`43m
zm)-s#Bzt8&%uYz|Rg808`8+SKEgTg#r1OR>`n{q5rY{%l)0~F?sW^IBk3%PJO|V>W
z&&JW`dK@}&PXvpDdp3?YsK=ob_lIC{aPzqGKFk<?Jihsn2kxl2uHKP*b0$4v#?A>W
z)0axMh-X$<N6Kx+aaTBY&as(-qb}o+;i!wV&5yH~p+$j(jrrkM0~_+()+~N6&^ZrZ
zX2^Vz=eA}sOXzk-eqZK#qnI6w<#z`gb#g9qWcqPsAjgud*pW|3Vx~I6Y5CKCbnbUX
z{|{-0L&yG{cI?ETlzv!yM_^s3bo#@Lo|Vqb;sdv+Y`hgY>mVn79r<$)>ca0@rSqn6
zoJZb{a6sTZ^kV`uVfxFGS>!veomgr(A?cKMtMjyEmg%oaCNFiL)y_TP7A5h{)*Ebq
z{MK9S)QisV3jMKqI+DqY|B`m<;r{6FXvanmh(}+kIO3_{yx`oEoA_UpL~d%a{2y1G
z=~tw42Jh9?&fU?8-_TAxJm;Y^n{e2_)J{ESN55Zj*uRpDFFA=vXI?FSQ!?>pN8hSA
z;vY)J*Y1nXJi}Q&X4rJ%nPGBX(JONgW|4)@-(q<Cb#;ojJ|QqK%mj0AUEb7kQo#1R
zyqSSB6~_$xrA)7CXZ<UGY_A9(3FJp!SKN~Ja{~E00=ap|WdYuN-js}wosZ930{m~v
zgZ{Qa96WjG$GgIc@IXGi`-O_rHsju_IQn6J?^hhX+0tY%8><5G_+vjW{HnazJ`gw`
zA8KZ%J`|W+YQCX<pyT(C?oV&%1O2c&UXsimnLX>nWy$d7^ND19m`C%uDjDAT@Tp|t
z;4SVm$;5R8i@PQn-r_!&Of0;`U6)K;z3(@q!&}@<$;6g?+4nW+^}er5hhtffZ%JMg
z>V3amarM665l1}!*z0}2E1mO8pR(`wq}Th7j$gg+^q)TPP4)!7N8X6<79ATi{y^Yc
j!^Ss>j*Z#+M&ORv_}<Vh?mNkRW7zoi(Erm-uL}PIO=8tv

literal 2824
zcmZ9M`*IXj5XKMLOAtgvt}4b20g0j!6%a)r;kF4ZBoK`Lx3%m};-O||QnR!1@)xh5
zui;BrzLb|LtNea5)4K;ws&l%({<=?}K0RBTS(tThpF8Ldx$j-Mj<^{iPFS<p+nvqM
z(kLG+UAlY`#v86y5aAq_#i~n&J)fY@Nfsq*k_VDUk`2kG<Xg#>q^7?a?SCps-5qf4
zPPe_j-tOG(_IG!?qx|PM>c&2ax&xm@{oL<G@b(8hpY-GLAS5)z2<vFLS@$|;CVo53
zhPTGs+flau?78ykW{tupw;QH|DAwN8AAIh$6Q#p$mgZ6?T<YEP(T^cUCw8;+d5M+h
zQNwr?b&DLMA9{l*(`mJ$Q{!i;^rky4&Q9Fjh_bCH%cGyl_!39QmyUey(?smqf?w1H
z?vs4e|DujiTj`@V#oUhl?j1kMdr3c<_^1)zIF2Vi>fxPO4gK+6KA9X@V7y<}8|6_Z
zyyEemK6x@hiRFFw(s(?KHuGMV3uzYb?UStl<(y_Q18L@WrYC{di@DhD^?kBa*29eW
z<X(k1*B0lXu%_fq$*OGLiq(*;>c80w1^P0kA%7{3UWRel#4SrK7uc(D^f`>fChmpA
z;=o>w;|;<%Y~ucqSRB|iuDlPk1dpL?>&>_$`RNB=-WdtY?D^6xax!Bq`o`iMFzyA$
zZWuYisKGFFFlyjzV(o0^#pVYevqC-8fj;%si{Aij&V$Rm7#Dr&s~2;FZRhZtF|}*O
zoLDTsCHSb5bD0^lk17K>=H<nYenJ}a(~_JNpI&2gzf=0ZUppA~as7WydrQK)P}v8h
zGk>RL(;GNobBg3`$Po&hmbizsQv;l9mCZfCIP0+XmSmrVv#>dbTFgEookhO4v=htu
z$D|$CZZ)2e&NBNQ>Exy6ceQh8usLbGsr3OLLjL!((>MIoi*3ENdfpdCUidBT)WhBB
z?FZU9haC9NYljO?KJ3K`BOlz4B+k9K3IC!rVyVr}`=Y|kz9O45Ij^mqUSJcys-1Xn
z&cj}-F#PwWQ;+$vA5<9rhti2BC-K<Ks@-Q@I`QVm-l#C*pGb#m_r+$G!7Ly1Yc}!B
zFFCL1JLMj{Jqym?LiqhyQKxwOqY~za8DTE2i%l)ZB=~+8o0&LSVa&u|%JjB&*1zK8
zJ0<yCLVolW#kI80OUTa~lbd%vBLO$gf^;}`KAf`>@ZXdN`<#S0aPrWP4<(C|$Kvqr
z7b;BK1pBzc=!fw>sW5u8p~+x2mL$Z($IlG?s=W9<m2f^BYG$TBlQ75Bd_(=fhWC%|
zPjBc0{jfV;lFl8OJ?q0|>EOosQaT*w(KuJ7gIgcIl1?1B#eFTExUk39WP@AWH`0j(
zx47%li3|IFLpHd@-IPvjiI;s}mL2weMK&1AdVEXzvLx*L?FtL~en%Mb@bQOzzbl*b
zOHSGMd$Pm6W5WykPXFm2-(*L^_sAQqRW?3m{IP^@4d0{6#>Z?um2gLVd~etm_nmaU
PF?@V`*#GIKS0(=gucy$q

diff --git a/shaders/cube.vert b/shaders/cube.vert
index 9e5c24b..7e1bf91 100644
--- a/shaders/cube.vert
+++ b/shaders/cube.vert
@@ -5,6 +5,7 @@ layout(binding = 0) uniform UniformBufferObject {
     mat4 geom_rot;
     mat4 view;
     mat4 proj;
+    vec3 camera_pos;
     bool[16] use_geom_shader;
 } ubo;
 
diff --git a/shaders/cuboid.vert b/shaders/cuboid.vert
index 99c6ccf..882c0b2 100644
--- a/shaders/cuboid.vert
+++ b/shaders/cuboid.vert
@@ -5,6 +5,7 @@ layout(binding = 0) uniform UniformBufferObject {
     mat4 geom_rot;
     mat4 view;
     mat4 proj;
+    vec3 camera_pos;
     bool[16] use_geom_shader;
 } ubo;
 
diff --git a/shaders/rt_quad.frag b/shaders/rt_quad.frag
index bac8002..93b04be 100644
--- a/shaders/rt_quad.frag
+++ b/shaders/rt_quad.frag
@@ -7,6 +7,15 @@ layout(location = 3) flat in uint facing;
 
 layout(location = 0) out vec4 outColor;
 
+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 = 2) buffer SceneInfoBuffer{
      uint infos[]; 
 } scene_info;
@@ -122,7 +131,7 @@ uvec4 sample_color_from_scene_info(uint volume_start, uvec2 raster_pos, uint f)
     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 + raster_pos.x * v_size * uint(u_size > 1) + raster_pos.y * uint(v_size > 1)];
+    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); 
 }
 
@@ -142,6 +151,8 @@ struct Tracing {
     float end_factor;
     uint end_cycle;
     bool has_hit;
+    vec3 color_mul;
+    uvec2 end_raster;
 };
 
 Tracing trace_ray(uint volume_start, vec3 starting_pos, vec3 direction, float max_factor, uint start_cycle, uint max_cycle) {
@@ -167,6 +178,7 @@ Tracing trace_ray(uint volume_start, vec3 starting_pos, vec3 direction, float ma
     float z_factor = max_factor;
 
     Tracing result;
+    result.color_mul = vec3(1.0, 1.0, 1.0);
 
     while (cycle < max_cycle) {
         cycle ++;
@@ -250,10 +262,20 @@ Tracing trace_ray(uint volume_start, vec3 starting_pos, vec3 direction, float ma
                     break;
                 }
             } else {
-                // color hit, move on
-                result.end_color = color_sample;
-                result.has_hit = true;
-                break;
+                if (next_neighbor != 0) {
+                    // transparent hit, move on but change the color
+                    volume_index = next_neighbor;
+                    volume_pos_x = scene_info.infos[volume_index + 0]; 
+                    volume_pos_y = scene_info.infos[volume_index + 1]; 
+                    volume_pos_z = 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);
+                } else {
+                    // color hit, move on
+                    result.end_color = color_sample;
+                    result.end_raster = uvec2(u, v);
+                    result.has_hit = true;
+                    break;
+                }
             }
         }
     }
@@ -264,7 +286,7 @@ Tracing trace_ray(uint volume_start, vec3 starting_pos, vec3 direction, float ma
     return result;
 }
 
-vec3 get_lighting_color(uint volume_start, vec3 starting_pos, vec4 orig_color_sample) {
+vec3 get_lighting_color(uint volume_start, vec3 starting_pos, vec4 orig_color_sample, vec3 normal) {
     uint max_light_num = scene_info.infos[0];
     uint light_num = 0;
 
@@ -286,7 +308,7 @@ vec3 get_lighting_color(uint volume_start, vec3 starting_pos, vec4 orig_color_sa
         Tracing result = trace_ray(volume_start, starting_pos, light_direction, 1.0, iteration, max_iterations);
         if (!result.has_hit) {
             // no hit, add light color result
-            color_sum += (orig_color_sample.xyz * light_color) / ((0.01 * length(light_direction) * length(light_direction)) + 1.0);
+            color_sum += result.color_mul * max(dot(normal, normalize(light_direction)), 0.0) * (orig_color_sample.xyz * light_color) / (length(light_direction) * length(light_direction));
         }
         iteration = result.end_cycle;
 
@@ -299,15 +321,33 @@ vec3 get_lighting_color(uint volume_start, vec3 starting_pos, vec4 orig_color_sa
     return color_sum;
 }
 
-void main() {
-    uint max_length = scene_info.infos[0];
-    uint last = scene_info.infos[max_length];
-    
-    uvec4 color_roughness = sample_color_from_scene_info(fragVolumeStart, fragRasterPos, facing);
-    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_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(0.0, 1.0, 0.0);
+    }
+    if (facing == 3) {
+        return vec3(0.0, -1.0, 0.0);
+    }
+    if (facing == 4) {
+        return vec3(1.0, 0.0, 0.0);
+    }
+    if (facing == 5) {
+        return vec3(-1.0, 0.0, 0.0);
+    }
 
-    // singular raytracing
-    //vec3 color_sum = get_lighting_color(fragVolumeStart, origPosition, orig_color_sample);
+    return vec3(0.0, 0.0, 0.0);
+}
+
+vec3 diffuse_tracing(uint volume_start, uvec2 raster_pos, vec3 pos, uint f) {
+    uvec4 color_roughness = sample_color_from_scene_info(volume_start, raster_pos, 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);
 
     // diffuse raytracing using a quadratic raster of rays
     int raster_half_steps = 0;
@@ -317,16 +357,54 @@ void main() {
     vec3 color_sum = vec3(0.0, 0.0, 0.0);
     for (int u_offset = -raster_half_steps; u_offset <= raster_half_steps; u_offset++) {
         for (int v_offset = -raster_half_steps; v_offset <= raster_half_steps; v_offset++) {
-            float x_offset = raster_distance * float(u_offset) * float(facing == 0 || facing == 1 || facing == 4 || facing == 5);
-            float y_offset = raster_distance * float(u_offset) * float(facing == 2 || facing == 3);
-            y_offset += raster_distance * float(v_offset) * float(facing == 0 || facing == 1);
-            float z_offset = raster_distance * float(v_offset) * float(facing == 4 || facing == 5 || facing == 2 || facing == 3);
+            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(fragVolumeStart, origPosition + offset, orig_color_sample) / float(raster_points);
+            color_sum += get_lighting_color(volume_start, origPosition + offset, orig_color_sample, normal) / float(raster_points);
         }
     }
 
+    return color_sum;
+}
+
+vec3 clamp_to_volume(uint volume_start, vec3 position) {
+    uint volume_pos_x = scene_info.infos[volume_start + 0]; 
+    uint volume_pos_y = scene_info.infos[volume_start + 1]; 
+    uint volume_pos_z = scene_info.infos[volume_start + 2]; 
+
+    float high_x_border = float(volume_pos_x + (scene_info.infos[volume_start + 3])) - 0.5;
+    float high_y_border = float(volume_pos_y + (scene_info.infos[volume_start + 4])) - 0.5;
+    float high_z_border = float(volume_pos_z + (scene_info.infos[volume_start + 5])) - 0.5;
+
+    float low_x_border = float(volume_pos_x) - 0.5;
+    float low_y_border = float(volume_pos_y) - 0.5;
+    float low_z_border = float(volume_pos_z) - 0.5;
+
+    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));
+}
+
+void main() {
+    vec3 clamped_pos = clamp_to_volume(fragVolumeStart, origPosition);
+    vec3 color_sum = diffuse_tracing(fragVolumeStart, fragRasterPos, clamped_pos, facing);
+
+    uint orig_neighbor = sample_neighbor_from_scene_info(fragVolumeStart, fragRasterPos, facing);
+    if (orig_neighbor != 0) {
+        float pos_infinity = uintBitsToFloat(0x7F800000);
+        Tracing t = trace_ray(fragVolumeStart, ubo.camera_pos, clamped_pos - ubo.camera_pos, 100.0, 0, 20);
+        if (t.has_hit) {
+            color_sum += diffuse_tracing(t.end_volume, t.end_raster, t.end_pos, t.end_facing);
+        }
+        else {
+            // Todo: hit sky box
+            color_sum += vec3(0.0, 0.0, 0.0);
+        }
+        
+    }
+
+
     outColor = vec4(color_sum, 1.0);
 }
\ No newline at end of file
diff --git a/shaders/rt_quad.vert b/shaders/rt_quad.vert
index b027c8d..47b98b0 100644
--- a/shaders/rt_quad.vert
+++ b/shaders/rt_quad.vert
@@ -5,6 +5,7 @@ layout(binding = 0) uniform UniformBufferObject {
     mat4 geom_rot;
     mat4 view;
     mat4 proj;
+    vec3 camera_pos;
     bool[16] use_geom_shader;
 } ubo;
 
diff --git a/src/buffer.rs b/src/buffer.rs
index 15e96d5..13b0159 100644
--- a/src/buffer.rs
+++ b/src/buffer.rs
@@ -1,5 +1,6 @@
 use anyhow::{anyhow, Result};
 
+use cgmath::Point3;
 use vulkanalia::prelude::v1_0::*;
 
 use std::mem::size_of;
@@ -10,6 +11,7 @@ pub type Mat4 = cgmath::Matrix4<f32>;
 use crate::app_data;
 use crate::command_buffer;
 use crate::vertex::VertexContainer;
+use crate::scene;
 
 pub unsafe fn create_buffer(
     instance: &Instance,
@@ -163,9 +165,6 @@ pub unsafe fn create_index_buffer(
         vk::MemoryPropertyFlags::DEVICE_LOCAL,
     )?;
 
-    let index_buffer = index_buffer;
-    let index_buffer_memory = index_buffer_memory;
-
     copy_buffer(device, data, staging_buffer, index_buffer, size)?;
 
     device.destroy_buffer(staging_buffer, None);
@@ -181,6 +180,7 @@ pub struct UniformBufferObject {
     pub geom_rot: Mat4,
     pub view: Mat4,
     pub proj: Mat4,
+    pub camera_pos: Point3<f32>,
     pub use_geom_shader: [bool; 16],
 }
 
@@ -192,7 +192,7 @@ pub unsafe fn create_descriptor_set_layout(
         .binding(0)
         .descriptor_type(vk::DescriptorType::UNIFORM_BUFFER)
         .descriptor_count(1)
-        .stage_flags(vk::ShaderStageFlags::VERTEX | vk::ShaderStageFlags::GEOMETRY);
+        .stage_flags(vk::ShaderStageFlags::VERTEX | vk::ShaderStageFlags::GEOMETRY | vk::ShaderStageFlags::FRAGMENT);
 
     let sampler_binding = vk::DescriptorSetLayoutBinding::builder()
         .binding(1)
@@ -254,8 +254,8 @@ pub unsafe fn create_storage_buffers(
             device,
             data,
             data.scene_rt_memory_size,
-            vk::BufferUsageFlags::STORAGE_BUFFER,
-            vk::MemoryPropertyFlags::HOST_COHERENT | vk::MemoryPropertyFlags::HOST_VISIBLE,
+            vk::BufferUsageFlags::TRANSFER_DST | vk::BufferUsageFlags::STORAGE_BUFFER,
+            vk::MemoryPropertyFlags::DEVICE_LOCAL,
         )?;
 
         data.storage_buffers.push(storage_buffer);
@@ -265,6 +265,41 @@ pub unsafe fn create_storage_buffers(
     Ok(())
 }
 
+pub unsafe fn update_storage_buffer(
+    instance: &Instance,
+    device: &Device,
+    data: &app_data::AppData,
+    image_index: usize,
+    scene_handler: &scene::Scene,
+) -> Result<()> {
+    let (staging_buffer, staging_buffer_memory) = create_buffer(
+        instance,
+        device,
+        data,
+        data.scene_rt_memory_size,
+        vk::BufferUsageFlags::TRANSFER_SRC,
+        vk::MemoryPropertyFlags::HOST_COHERENT | vk::MemoryPropertyFlags::HOST_VISIBLE,
+    )?;
+
+    let memory = device.map_memory(
+        staging_buffer_memory,
+        0,
+        data.scene_rt_memory_size,
+        vk::MemoryMapFlags::empty(),
+    )?;
+
+    memcpy(scene_handler.rt_memory.as_ptr(), memory.cast(), scene_handler.rt_memory.len());
+    
+    device.unmap_memory(staging_buffer_memory);
+
+    copy_buffer(device, data, staging_buffer, data.storage_buffers[image_index], data.scene_rt_memory_size)?;
+
+    device.destroy_buffer(staging_buffer, None);
+    device.free_memory(staging_buffer_memory, None);
+
+    Ok(())
+}
+
 pub unsafe fn create_descriptor_pool(device: &Device, data: &mut app_data::AppData) -> Result<()> {
     let ubo_size = vk::DescriptorPoolSize::builder()
         .type_(vk::DescriptorType::UNIFORM_BUFFER)
diff --git a/src/main.rs b/src/main.rs
index bda1050..2e8d209 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -257,7 +257,7 @@ impl App {
 
         self.update_uniform_buffer(image_index)?;
         if self.synchronized < MAX_FRAMES_IN_FLIGHT {
-            self.update_storage_buffer(image_index)?;
+            buffer::update_storage_buffer(&self.instance, &self.device, &self.data, image_index, &self.scene_handler)?;
             self.synchronized += 1
         }
 
@@ -434,7 +434,8 @@ impl App {
             );
 
         let ubo = buffer::UniformBufferObject { model, geom_rot: rot_mat4, view, proj, 
-            use_geom_shader: [self.data.use_geometry_shader, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false]};
+            use_geom_shader: [self.data.use_geometry_shader, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false], 
+            camera_pos: self.cur_pos.clone()};
 
         let memory = self.device.map_memory(
             self.data.uniform_buffers_memory[image_index],
@@ -449,25 +450,10 @@ impl App {
 
         Ok(())
     }
-
-    unsafe fn update_storage_buffer(&mut self, image_index: usize) -> Result<()> {
-        let memory = self.device.map_memory(
-            self.data.storage_buffers_memory[image_index],
-            0,
-            self.data.scene_rt_memory_size,
-            vk::MemoryMapFlags::empty(),
-        )?;
-        
-        memcpy(self.scene_handler.rt_memory.as_ptr(), memory.cast(), self.scene_handler.rt_memory.len());
-        
-        self.device.unmap_memory(self.data.storage_buffers_memory[image_index]);
-
-        Ok(())
-    }
 }
 
 //================================================
-// Instance
+// MARK: Instance
 //================================================
 
 unsafe fn create_instance(window: &Window, entry: &Entry, data: &mut app_data::AppData) -> Result<Instance> {
diff --git a/src/primitives/cube.rs b/src/primitives/cube.rs
index 38d5f8f..31a760e 100644
--- a/src/primitives/cube.rs
+++ b/src/primitives/cube.rs
@@ -12,57 +12,57 @@ pub struct Cube{
     pub transparent: bool,
 }
 
-const cube_size: f32 = 0.48;
+const CUBE_SIZE: f32 = 0.5;
 
 impl Drawable for Cube {
     fn draw(& self, topology: &vk::PrimitiveTopology, start_index: usize, scene: &mut Scene) {
         if *topology == vk::PrimitiveTopology::TRIANGLE_LIST {
             // 0 top left far
             scene.vertices.push(vertex::Vertex::new(
-                vec3(self.pos.x as f32 - cube_size, self.pos.y as f32 + cube_size, self.pos.z as f32 + cube_size),
+                vec3(self.pos.x as f32 - CUBE_SIZE, self.pos.y as f32 + CUBE_SIZE, self.pos.z as f32 + CUBE_SIZE),
                 self.color,
                 self.tex_coord
             ));
             // 1 top right far
             scene.vertices.push(vertex::Vertex::new(
-                vec3(self.pos.x as f32 + cube_size, self.pos.y as f32 + cube_size, self.pos.z as f32 + cube_size),
+                vec3(self.pos.x as f32 + CUBE_SIZE, self.pos.y as f32 + CUBE_SIZE, self.pos.z as f32 + CUBE_SIZE),
                 self.color,
                 self.tex_coord
             ));
             // 2 top left near
             scene.vertices.push(vertex::Vertex::new(
-                vec3(self.pos.x as f32 - cube_size, self.pos.y as f32 - cube_size, self.pos.z as f32 + cube_size),
+                vec3(self.pos.x as f32 - CUBE_SIZE, self.pos.y as f32 - CUBE_SIZE, self.pos.z as f32 + CUBE_SIZE),
                 self.color,
                 self.tex_coord
             ));
             // 3 top right near
             scene.vertices.push(vertex::Vertex::new(
-                vec3(self.pos.x as f32 + cube_size, self.pos.y as f32 - cube_size, self.pos.z as f32 + cube_size),
+                vec3(self.pos.x as f32 + CUBE_SIZE, self.pos.y as f32 - CUBE_SIZE, self.pos.z as f32 + CUBE_SIZE),
                 self.color,
                 self.tex_coord
             ));
 
             // 4 bottom left far
             scene.vertices.push(vertex::Vertex::new(
-                vec3(self.pos.x as f32 - cube_size, self.pos.y as f32 + cube_size, self.pos.z as f32 - cube_size),
+                vec3(self.pos.x as f32 - CUBE_SIZE, self.pos.y as f32 + CUBE_SIZE, self.pos.z as f32 - CUBE_SIZE),
                 self.color,
                 self.tex_coord
             ));
             // 5 bottom right far
             scene.vertices.push(vertex::Vertex::new(
-                vec3(self.pos.x as f32 + cube_size, self.pos.y as f32 + cube_size, self.pos.z as f32 - cube_size),
+                vec3(self.pos.x as f32 + CUBE_SIZE, self.pos.y as f32 + CUBE_SIZE, self.pos.z as f32 - CUBE_SIZE),
                 self.color,
                 self.tex_coord
             ));
             // 6 bottom left near
             scene.vertices.push(vertex::Vertex::new(
-                vec3(self.pos.x as f32 - cube_size, self.pos.y as f32 - cube_size, self.pos.z as f32 - cube_size),
+                vec3(self.pos.x as f32 - CUBE_SIZE, self.pos.y as f32 - CUBE_SIZE, self.pos.z as f32 - CUBE_SIZE),
                 self.color,
                 self.tex_coord
             ));
             // 7 bottom right near
             scene.vertices.push(vertex::Vertex::new(
-                vec3(self.pos.x as f32 + cube_size, self.pos.y as f32 - cube_size, self.pos.z as f32 - cube_size),
+                vec3(self.pos.x as f32 + CUBE_SIZE, self.pos.y as f32 - CUBE_SIZE, self.pos.z as f32 - CUBE_SIZE),
                 self.color,
                 self.tex_coord
             ));
diff --git a/src/scene/empty_volume.rs b/src/scene/empty_volume.rs
index 50961dc..7581195 100644
--- a/src/scene/empty_volume.rs
+++ b/src/scene/empty_volume.rs
@@ -1,7 +1,6 @@
 use cgmath::Vector3;
 
 use std::cell::RefCell;
-use std::collections::HashSet;
 use std::rc::Rc;
 
 use std::time::Instant;
@@ -50,6 +49,14 @@ impl EmptyVolume {
         self.position[1] + self.size_y > pos[1] && pos[1] >= self.position[1] &&
         self.position[2] + self.size_z > pos[2] && pos[2] >= self.position[2]
     }
+
+    fn check_transparent(cube_result: Option<Cube>, transparent_color: &Vector3<f32>) -> bool {
+        if let Some(c) = cube_result {
+            return c.transparent && &c.color == transparent_color
+        }
+        false
+    }
+
     // MARK: From Oct Tree
     pub fn from_oct_tree(tree: &OctTree<Cube>) -> (Vec<Rc<RefCell<EmptyVolume>>>, OctTree<Rc<RefCell<EmptyVolume>>>) {
         // todo: ppotentially use a child exist check while going through the oct tree to find some obvios starting empty volumes. Will still need to check for possible expansions though
@@ -64,8 +71,14 @@ impl EmptyVolume {
                 for z_index in 0..tree.size {
                     // check if there is a block at that position
                     let query_result = tree.test_element(x_index, y_index, z_index);
-                    
-                    if !query_result.0 {
+                    let mut transparent = false;
+                    let mut transparent_color = Vector3 {x: 0.0, y: 0.0, z: 0.0};
+                    if let Some(c) = query_result.3 {
+                        transparent = c.transparent;
+                        transparent_color = c.color;
+                    }
+                    if !query_result.0 || transparent {
+                        
                         //if not check that it is not already inside of a volume
                         let mut contained = false;
                         for volume in &volumes {
@@ -99,7 +112,7 @@ impl EmptyVolume {
                                 while z < z_size.max(1) && y < y_size.max(1) {
                                     let query_result = tree.test_element(x_index + x_size + 1, y_index + y, z_index + z);
                                     check_its += 1;
-                                    grow &= !query_result.0 &&
+                                    grow &= ((!query_result.0 && !transparent) || (transparent && EmptyVolume::check_transparent(query_result.3, &transparent_color))) &&
                                         neighbors.get_element(x_index + x_size + 1, y_index + y, z_index + z).is_none();
 
                                     if query_result.1 > 1 {
@@ -146,7 +159,7 @@ impl EmptyVolume {
                                 while z < z_size.max(1) && x < x_size.max(1) {
                                     let query_result = tree.test_element(x_index + x, y_index + y_size + 1, z_index + z);
                                     check_its += 1;
-                                    grow &= !query_result.0 &&
+                                    grow &= ((!query_result.0 && !transparent) || (transparent && EmptyVolume::check_transparent(query_result.3, &transparent_color))) &&
                                         neighbors.get_element(x_index + x, y_index + y_size + 1, z_index + z).is_none();
 
                                     if query_result.1 > 1 {
@@ -194,7 +207,7 @@ impl EmptyVolume {
                                 while y < y_size.max(1) && x < x_size.max(1) {
                                     let query_result = tree.test_element(x_index + x, y_index + y, z_index + z_size + 1);
                                     check_its += 1;
-                                    grow &= !query_result.0 &&
+                                    grow &= ((!query_result.0 && !transparent) || (transparent && EmptyVolume::check_transparent(query_result.3, &transparent_color))) &&
                                         neighbors.get_element(x_index + x, y_index + y, z_index + z_size + 1).is_none();
 
                                     if query_result.1 > 1 {
@@ -683,12 +696,14 @@ impl EmptyVolume {
         for x in 0..self.size_x {
             for y in 0..self.size_y {
                 let index = x * self.size_y + y;
-                if self.color_bottom.len() == 0 {
+                if self.color_bottom.len() <= index {
                     continue;
                 }
                 if self.neighbor_bottom.len() > index {
                     if let Some(_) = self.neighbor_bottom[index] {
-                        continue;
+                        if self.color_bottom[index] == (Vector3 {x: 0, y: 0, z: 0}) {
+                            continue;
+                        }
                     }
                 }
                 let quad = Quad {
@@ -707,12 +722,14 @@ impl EmptyVolume {
         for x in 0..self.size_x {
             for y in 0..self.size_y {
                 let index = x * self.size_y + y;
-                if self.color_top.len() == 0 {
+                if self.color_top.len() <= 0 {
                     continue;
                 }
                 if self.neighbor_top.len() > index {
                     if let Some(_) = self.neighbor_top[index] {
-                        continue;
+                        if self.color_top[index] == (Vector3 {x: 0, y: 0, z: 0}) {
+                            continue;
+                        }
                     }
                 }
                 let quad = Quad {
@@ -732,12 +749,14 @@ impl EmptyVolume {
         for x in 0..self.size_x {
             for z in 0..self.size_z {
                 let index = x * self.size_z + z;
-                if self.color_front.len() == 0 {
+                if self.color_front.len() <= 0 {
                     continue;
                 }
                 if self.neighbor_front.len() > index {
                     if let Some(_) = self.neighbor_front[index] {
-                        continue;
+                        if self.color_front[index] == (Vector3 {x: 0, y: 0, z: 0}) {
+                            continue;
+                        }
                     }
                 }
                 let quad = Quad {
@@ -757,12 +776,14 @@ impl EmptyVolume {
         for x in 0..self.size_x {
             for z in 0..self.size_z {
                 let index = x * self.size_z + z;
-                if self.color_back.len() == 0 {
+                if self.color_back.len() <= 0 {
                     continue;
                 }
                 if self.neighbor_back.len() > index {
                     if let Some(_) = self.neighbor_back[index] {
-                        continue;
+                        if self.color_back[index] == (Vector3 {x: 0, y: 0, z: 0}) {
+                            continue;
+                        }
                     }
                 }
                 let quad = Quad {
@@ -782,12 +803,14 @@ impl EmptyVolume {
         for y in 0..self.size_y {
             for z in 0..self.size_z {
                 let index = y * self.size_z + z;
-                if self.color_left.len() == 0 {
+                if self.color_left.len() <= 0 {
                     continue;
                 }
                 if self.neighbor_left.len() > index {
                     if let Some(_) = self.neighbor_left[index] {
-                        continue;
+                        if self.color_left[index] == (Vector3 {x: 0, y: 0, z: 0}) {
+                            continue;
+                        }
                     }
                 }
                 let quad = Quad {
@@ -807,12 +830,14 @@ impl EmptyVolume {
         for y in 0..self.size_y {
             for z in 0..self.size_z {
                 let index = y * self.size_z + z;
-                if self.color_right.len() == 0 {
+                if self.color_right.len() <= 0 {
                     continue;
                 }
                 if self.neighbor_right.len() > index {
                     if let Some(_) = self.neighbor_right[index] {
-                        continue;
+                        if self.color_right[index] == (Vector3 {x: 0, y: 0, z: 0}) {
+                            continue;
+                        }
                     }
                 }
                 let quad = Quad {
diff --git a/src/scene/mod.rs b/src/scene/mod.rs
index a91b1a8..c5703a7 100644
--- a/src/scene/mod.rs
+++ b/src/scene/mod.rs
@@ -11,7 +11,6 @@ use cgmath::{vec2, vec3, Vector3};
 use std::cell::RefCell;
 use std::rc::Rc;
 
-use crate::app_data;
 use crate::app_data::AppData;
 use crate::buffer;
 use crate::primitives::rec_cuboid::Cuboid;
@@ -68,7 +67,7 @@ impl Scene {
 
         for x_index in 0..grid_size {
             for y_index in 0..grid_size {
-                let shade = (rng.gen_range(0..25) as f32) / 100.0;
+                let shade = (rng.gen_range(0..50) as f32) / 100.0;
                 let cube = Cube {
                     pos: vec3(x_index as f32, y_index as f32, 5.0),
                     color: vec3(shade, 1.0, shade),
@@ -83,17 +82,24 @@ impl Scene {
         let shade = (rng.gen_range(0..25) as f32) / 100.0;
         let cube = Cube {
             pos: vec3(10.0, 10.0, 10.0),
-            color: vec3(1.0, 1.0, 0.0),
+            color: vec3(1.0, 0.0, 0.0),
             tex_coord: vec2(0.0, 0.0),
             transparent: true,
         };
+        oct_tree.set_cube(cube.clone());
 
+        let cube = Cube {
+            pos: vec3(10.0, 10.0, 9.0),
+            color: vec3(1.0, 0.0, 0.0),
+            tex_coord: vec2(0.0, 0.0),
+            transparent: true,
+        };
         oct_tree.set_cube(cube.clone());
 
         self.point_lights.push(PointLight { pos: vec3(11.0, 11.0, 11.0), color: vec3(0.5, 0.5, 0.5), memory_start: 0 });
         self.point_lights.push(PointLight { pos: vec3(9.0, 9.0, 11.0), color: vec3(0.5, 0.5, 0.5), memory_start: 0 });
 
-        let mut empty_volumes: Vec<Rc<RefCell<EmptyVolume>>>;
+        let empty_volumes: Vec<Rc<RefCell<EmptyVolume>>>;
         (empty_volumes, _) = EmptyVolume::from_oct_tree(&oct_tree);
         println!("number of empty volumes is {}", empty_volumes.len());
 
@@ -124,7 +130,7 @@ impl Scene {
 
         let cube = Cuboid {
             pos: vec3(11.0, 11.0, 11.0),
-            color: vec3(shade, 1.0, shade),
+            color: vec3(1.0, 1.0, 1.0),
             tex_coord: vec2(0.0, 0.0),
             size: Vector3 {x: 0.5, y: 0.5, z: 0.5}
         };
@@ -133,7 +139,7 @@ impl Scene {
 
         let cube = Cuboid {
             pos: vec3(9.0, 9.0, 11.0),
-            color: vec3(shade, 1.0, shade),
+            color: vec3(1.0, 1.0, 1.0),
             tex_coord: vec2(0.0, 0.0),
             size: Vector3 {x: 0.5, y: 0.5, z: 0.5}
         };
diff --git a/src/scene/oct_tree.rs b/src/scene/oct_tree.rs
index bdab4db..7b8212d 100644
--- a/src/scene/oct_tree.rs
+++ b/src/scene/oct_tree.rs
@@ -7,7 +7,7 @@ use crate::primitives::cube::Cube;
 
 extern crate rand;
 
-pub const CHUNK_SIZE_EXPONENT: u32 = 8;
+pub const CHUNK_SIZE_EXPONENT: u32 = 6;
 pub const CHUNK_SIZE: usize = (2 as usize).pow(CHUNK_SIZE_EXPONENT);
 pub const MAX_TREE_DEPTH: usize = CHUNK_SIZE_EXPONENT as usize - 2;
 pub const MIN_CHUNK_SIZE: usize = CHUNK_SIZE / (2 as usize).pow(MAX_TREE_DEPTH as u32);
@@ -378,13 +378,13 @@ impl<T: Clone> OctTree<T> {
         }
     }
 
-    pub fn test_element(&self, x: usize, y: usize, z: usize) -> (bool, usize, (usize, usize, usize)) {
+    pub fn test_element(&self, x: usize, y: usize, z: usize) -> (bool, usize, (usize, usize, usize), Option<T>) {
         self.test_element_internal(x, y, z, 0, 0, 0)
     }
 
-    fn test_element_internal(&self, x: usize, y: usize, z: usize, node_start_x: usize, node_start_y: usize, node_start_z: usize) -> (bool, usize, (usize, usize, usize)) {
+    fn test_element_internal(&self, x: usize, y: usize, z: usize, node_start_x: usize, node_start_y: usize, node_start_z: usize) -> (bool, usize, (usize, usize, usize), Option<T>) {
         if x >= self.size || y >= self.size || z >= self.size {
-            return (false, 0, (0, 0, 0))
+            return (false, 0, (0, 0, 0), None)
         }
 
         if self.size > MIN_CHUNK_SIZE {
@@ -396,7 +396,7 @@ impl<T: Clone> OctTree<T> {
                             Some(child) => {
                                 child.borrow().test_element_internal(x - mid_point, y - mid_point, z - mid_point, node_start_x + mid_point, node_start_y + mid_point, node_start_z + mid_point)
                             },
-                            None => (false, mid_point, (node_start_x + mid_point, node_start_y + mid_point, node_start_z + mid_point))
+                            None => (false, mid_point, (node_start_x + mid_point, node_start_y + mid_point, node_start_z + mid_point), None)
                         }
                     }
                     else {
@@ -404,7 +404,7 @@ impl<T: Clone> OctTree<T> {
                             Some(child) => {
                                 child.borrow().test_element_internal( x - mid_point, y - mid_point, z, node_start_x + mid_point, node_start_y + mid_point, node_start_z)
                             },
-                            None => (false, mid_point, (node_start_x + mid_point, node_start_y + mid_point, node_start_z))
+                            None => (false, mid_point, (node_start_x + mid_point, node_start_y + mid_point, node_start_z), None)
                         }
                     }
                 }
@@ -414,7 +414,7 @@ impl<T: Clone> OctTree<T> {
                             Some(child) => {
                                 child.borrow().test_element_internal(x - mid_point, y, z - mid_point, node_start_x + mid_point, node_start_y, node_start_z + mid_point)
                             },
-                            None => (false, mid_point, (node_start_x + mid_point, node_start_y, node_start_z + mid_point))
+                            None => (false, mid_point, (node_start_x + mid_point, node_start_y, node_start_z + mid_point), None)
                         }
                     }
                     else {
@@ -422,7 +422,7 @@ impl<T: Clone> OctTree<T> {
                             Some(child) => {
                                 child.borrow().test_element_internal(x - mid_point, y, z, node_start_x + mid_point, node_start_y, node_start_z)
                             },
-                            None => (false, mid_point, (node_start_x + mid_point, node_start_y, node_start_z))
+                            None => (false, mid_point, (node_start_x + mid_point, node_start_y, node_start_z), None)
                         }
                     }
                 }
@@ -434,7 +434,7 @@ impl<T: Clone> OctTree<T> {
                             Some(child) => {
                                 child.borrow().test_element_internal(x, y - mid_point, z - mid_point, node_start_x, node_start_y + mid_point, node_start_z + mid_point)
                             },
-                            None => (false, mid_point, (node_start_x, node_start_y + mid_point, node_start_z + mid_point))
+                            None => (false, mid_point, (node_start_x, node_start_y + mid_point, node_start_z + mid_point), None)
                         }
                     }
                     else {
@@ -442,7 +442,7 @@ impl<T: Clone> OctTree<T> {
                             Some(child) => {
                                 child.borrow().test_element_internal(x, y - mid_point, z, node_start_x, node_start_y + mid_point, node_start_z)
                             },
-                            None => (false, mid_point, (node_start_x, node_start_y + mid_point, node_start_z))
+                            None => (false, mid_point, (node_start_x, node_start_y + mid_point, node_start_z), None)
                         }
                     }
                 }
@@ -452,7 +452,7 @@ impl<T: Clone> OctTree<T> {
                             Some(child) => {
                                 child.borrow().test_element_internal(x, y, z - mid_point, node_start_x, node_start_y, node_start_z + mid_point)
                             },
-                            None => (false, mid_point, (node_start_x, node_start_y, node_start_z + mid_point))
+                            None => (false, mid_point, (node_start_x, node_start_y, node_start_z + mid_point), None)
                         }
                     }
                     else {
@@ -460,18 +460,18 @@ impl<T: Clone> OctTree<T> {
                             Some(child) => {
                                 child.borrow().test_element_internal(x, y, z, node_start_x, node_start_y, node_start_z)
                             },
-                            None => (false, mid_point, (node_start_x , node_start_y, node_start_z))
+                            None => (false, mid_point, (node_start_x , node_start_y, node_start_z), None)
                         }
                     }
                 }
             }
         }
         else {
-            if let Some(_) = self.blocks[z * MIN_CHUNK_SIZE * MIN_CHUNK_SIZE + y * MIN_CHUNK_SIZE + x] {
-                (true, 1, (x, y, z))
+            if let Some(c) = &self.blocks[z * MIN_CHUNK_SIZE * MIN_CHUNK_SIZE + y * MIN_CHUNK_SIZE + x] {
+                (true, 1, (x, y, z), Some(c.clone()))
             }
             else {
-                (false, 1, (x, y, z))
+                (false, 1, (x, y, z), None)
             }
         }
     }