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 1/5] 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 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 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 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 literal 11192 zcmZ9R2b^71wZ?DCkO-kkRRI&wC`Cj9Sdbn}z-YjL6}>Z=xf2GbIVBL1kQoG&sMx#4 zhzKaCC@OXl8}{Bs!S>$s^<sU`r~m(*`-SB_KQ{aOzV)qj_Fm_lJr`Xt|A<A6#=OQJ zjXfK`p4Vt!`!?pIG|+Zy&#Ts~TXXE>)WESPoOqmuy&4PJK0SNm>0w^T80i}tHLwR` zA9S^S+t@qIjRoY+2j7LTu(5k%)tct2wQE<cIlI|EKHi+1+BDp14iAmCngc@<t^TQ@ zjV*nPi*IPOe|UPJ8hUWl`^y(|kD<|l)@95+FxRwUxVdV0Y<=JGIinlL`unDa#zxOs z*^ckVdK-<g>8bJQspi<=;ACs6qr3k8v61ny>Cpj}*Ed0+hrK-r{j83D=JeoTYodWV zrxV(hGYRft&ks@L>S-)$c+XumH%tssc<6HWY29;cY_h*^xUKgz)}fE!%;Kzh5!&4T z7BqUnn;6y@WZqSOe9R@F_cS&$Pqtd4&DO~H6lVLhRc&rt?c6KEo0oM~HCJ=nE`3wc zdm1z7!+n!e&Hk}rAT<^=W|=Q<<DSNLW<p~V&5eB;T*ph9&r<6&&NoQStKAM>BkNo@ zC$)2SfTt$<MkmMnCR(FYXp0&<(Jr`O%VVGei`y~NOHR|;YSzA9z-7N~XYQY#u<ov1 ztA7Z69ZzPi@bNx2)J1Jwyz9|5=iYnk-eG{t{JWV`H(gWz3HtqYS9I#m>E^cU@-m98 zd5?h0J>SQ7bK&UF;Ml~-+_KiLzl86Esy*$PzLBwkmc90U)XzVS4Xv?}=EPXLX1sof z8;4q#GVRLu%O0N?yJSwA%U=lT?;B}N^flXWlRdC*5Bl_EtJ$tSd2!zWAA#%rC9&!C zV~th3Uw(IvLm2XdnRjDYb2b0=JMvOrO?LPZZPlCwZOwI=?{{?guGk!322cDY;95WL zRqBV=`fADdovZcb)_1+$|82~*{!X}8>hEl`Mx)kOOMTzFT3>Gc2QaMvLFQWDchD>K z!)txD)c5_X_2t&*kZ;%jG4uWPd)n_J(%-Gu_cQf;_i8=4^*mo)@4fTp>Un<pJnw^h z`EK|;!?WJ1xu%+DYR!|IcRC|^YTbGB(Q2ODyctIF)VlNBW6hJBcPArxYWL^O?Z<aP zpC49y)=}FB&3D#)dry1h_i#AaD}31;ZS!9d_Z#uu-;XTwmQlldiw~fN&ul5fYbo3{ zIn)n=`~HZ{F}^!9W!w769qv8Uj)v=9!tm0+C$lm2L#g8XCO!=8y5#yE%<P)ftSk4M z%sTzfmolv7edLESyv%<nvtDcO4_eNg^{nW`4&<Jz!Asj?VdETT_o^1}8nE|p@8@@7 z+56Mr`qlNDcOir8wB%n5@tKAD!^Jg)dr(@#HT$<r>{^dvZO&U5_9^F$eexWUoAWYe z_o-%|<envJ=H(nQZzr1Eytgy!*~u_Zemx_3IUmgPyO*2y;f_bmJh|U~^77rA=l3l) z@24G)nt5`+ar4rP--7M!k^I}e@0d3i^V!}2=AZU+xCdab{XP!n-#>$^$y4j+aKHIO zQ11oXbG5@bQT%4isl#We&$a%7*>&l2t#ZFDwPUE{H{iEqJ>L(<NjzoauEEQF{1L@x zZw;U8Vuo|L>#N+~fR(Q-+;{Wb!hQGrtycXPb@AT9^$!;AySBM->ul}f{zj|yw{`KE zE<W4Ew-@gH{B2e1`Fp7HyF2_0y5>2t7sIn;3F8!c=ri1#p?)eIwx4pbz0@bRkK#Yk z{|7Sr9Grhojs2MqV0alnklDC%?r{*<+Tn+Rt$7A3@LXBS@GSDYF&5u4@Y2E$2iLqK z;K?(VyoZ5}UB$lL<HH%&Qoj{#IrAeJuFKe;*@t{ThWl~-;?#R2xZd|jc<yT~zN5g# z!jA^mykp?WGZx>Yz{axPW5L!^kLS_gTI)D?Y8i{~F<@h<bv)R5>d{UBtFK@r??kZA ze5TX0lfY_v^FFA>|5$Kc&*R`(kFoe34>lJ51aQqe8J;|2@jVf2ENeamY%TS8P6hj3 zUD;XlX<#+Id7stdKOOA7v&S>QYW5-T;+f#A$9Qtj0vpTsAoqRu-S>TQuHT36QF6}) z*F8T8o_iRJZxz^>_gKj+PwdIyy7s5Q)z&bw_NRhV*LZT*f{ktAJzvdy9z)Ihcm~S# z8oPj@b~QbfKfR+}$Q;izz}53ixLWl*tIP9jxSF2x_$tq5eh$O><{NiC>zLKE_UD3q z#^KKc+nZ}U&%6oNqi()uwp#ps;F`Z4t|#wIKUj}?at6TO<C@MrT3~(Z-lLaUE&dJQ z`fP^aY8Nx|Y%T%k*%(jm^TEdQY=*&ViI0G5?J>C8C?mDU!KrOLxi0`4OYI4;TH=%7 zT6-F<HpNKojo{Qap4>~p#!~w-uv(t&Ca`<)p2qCkAhWu7GxL@X-pahBgRdxfTfs90 z&vvli+m&FyKWG0QUB!Gg!^`+J%*LIw_7{Pz5&mMZ&-*r>_j2ZI8G6+H+aP}-!`jvo zC->#xeF}dC*!L^(SAwmbbL>@MJ?ini8eBcEf$LMxS@l}5_cE5e*MWNre?7R?c>`RJ zdg{CpY%OD{^CqzUi092<ed>7+-U7akaVW!ha^DIz<}=;SEKlqm;M$uT;I%jJgxB@n z2-l;Y8aH)$Zieeq&wAel_Fl%4_ik`+;kSV6y>5l;QBR%sfURXLb>0iEy?Gy8pL%+8 z8~A#Ly)mBL_k)ey(s{2w09MPpz5}cl|3|>JUmu0netisH_waGJ9`)4tM3?82aDD3W zd<xuK_@}|O?wxQw>gmmAz}C8xkveyQYi~Xa*QcKM{c~XT6^zvSJlMS&OAo&QzJp;8 zjprU;1RL}Hx}8~`*q6YyUtfmTetiYLl99E16|6@+HNFO}p0C68smJpTaBtz?1lOEz z!S$$TkKYDc%UJ4s2VDF0UAR8=tnqtb_1drR!`-W~)c*lkeGMZ${2@3!G@kqZ2yDzA z-pwpe>}TNG!=J-z5ATK7z1|1cqn;YS09Vg1;ri6$`4zag@Lz*#&Trs))U(Hb09(sg z>ii?P_VAzJ`qb0Ie+H}nmXTWj0(P&)(yxC7-^1{oGj4y>mN0U^e*@S4{5!n%=Re?e zAO8v0qn;Z7)#dqbxIXoG{s-J!`0v2A?(gAx)U&5QfURXLb^Zvh{rMAIpL+W9XRvzh z&;P>RtFhGoKd^dz$NmCO&y3qMwc4})hu5C{6<&MRnD_U4n+MmUo_);k@+^SsQ;%mM zxR<o>9(e89Zg4&7+0!DhwTvZiF?g0b@jL*oPdz=`9jsn^wg=q38cXgHu)5!G-m^X7 z>6vkRrdE5l7koQ8`CG9!TrHmE#QfhVcQD`FSlIrZvM*firq17&2ZGI0{{#2fpV`ab zFvj*{tYP>YM(qBrdjNPdvpENWz06TRkfCOdI6XTUT%YlS;Pn|l7+#;nL*RPUQ{#{> z&!KRA>hT-~?qxmU4~5sdOW}Id^9+`Otz|5Ehl96LC!QnV`qcA`9|l&h&-meR_i8M) zmV>XLR-W%8;Ca6KeZFe?lJiJ#?bng;+OMPFbzeur^{A)DF<qWV!S$)fb1b;_>(TI9 z_c*v7_4MK~U~3smo#Vl^Un}7H)YGpM!0NSMC&JyUvD7~atnN9I`j3TgD?NN1JU!HJ z57qP~=keg$!zaLN4^M{Iy*?4HM?E!8>GGTk*QXxOY2ez!)8V!58E`%7+2fgDYZ*(O zv%s~7E8+Uo)5EjD>a~YYg1c8^slN)W?zxistKqYSp9A-P`ET2E;d<2bu09!@K3mg1 ztLYVc4s2nFXP7;I{O_oo0nT#I7S9CF6W8N8@)U5+k+oni&k^;fGStiwC+9q{XIl1j zK76L|r@`yFxDKvIJ?Gv9VCxu5oeRN!qv217-wx0D`V6=p^&30q=QF|9GM2n&fqhTI zpAGjnRO&nju17s}E&^N2n7zuroqxywLTj&{3$`!zPrp6!{B1IO**87UW2o6Tan{ib zuHQl*ynYMo;VY?=_pBeTM?EzLx;!noKJ|D8!M)T8-vF<5FNW(;&$~JVwwAHvT>`G( z!t>$!)U(E6uzLL#M&Rz%SZa-e>-jqd&pWN(cUMhca>l{6UoU{yeoesZz9!*%)Kg=s z%QFqvrykEnaP8Nn@LKmWxE}TNYZKU7#!}~UaP8M-xIXptYYSMt_G>HLy&6mXE5PdY z{M`nx=kE+WJ=EX+{`D}jrde?9;g#^(!xzHqUax}dQBRGlyFAyx^{L16B5>{Di{Z8I zwQxP^+2eMwwTz|COTe{<FNNz<PY+)PR<Aw04(?u!rT)vo>h=761$?%A8?S_Wzns6X zg6mPw`TJ^c`fN@6tfp6-^Vf4D-@UVY^4xe0SWkWfz80>QJ--fI&$-vb)jY>@UcLct zp0VV;5nRu;H^J3v-kag(8uP4rE3=npm9e)l)I6)i+0PDe?(;VAEIG#Pl{~SXVApQU z?^~YO+rh5SnD4DTvFpM9jW9ODEVqAIi*x;(wSR|Sjn}n0r`9`&&BF8C-w9W{fnj}P zYSz25lYdnw-{*59vHT6Z8SG_$)Nf*_c~5cf`7Ut%uHFr=-_<SfmDI^Qdn;UzdTP9< z%ky5iKJ|Fs2kxa#_-*i7_x*4^>e>GXz}7OByxYO`yZRtppL*8#A+UP=u09NRuf|gA z4sbooKLXG9q2HdX=}XQ>!L?r>gV%n29A5YJ3Ai5h)c9nV=TmTf>hXLUT>Et=yw?2; zT#tJCbr;xL#!~0A;M%Xx!S$)9U!Mo7*M5Bg?p}?h{ujaO^(?;|UeEF`!P7(i_E1e< z*7Rj??crD8wTEAY*S&rXu17sJzTV~e23((dJl_P@9)1g6>wX)qM?HJ|4%k}8Qs=wi z+QaX`^{J<a-v_JL9{vFCUX7*x55em7EdLSQb>)6PhI_x9<v)SzQO{ZaQ*iohP5Z2- 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 zcmZvl1%Mq@wnZP11b2c<g1fsn7MQ`^Lx?~iNrwm!G{N27-F*gkml@pM-QD4@)$i?a z=s)lOqW0cL?m4$^-FnrXWX2nJj`16faT*ghCT&ay@-t;)T$Bb{w~lkKbvIde;o&3t zExhDXi)x>&F`lOm+vNCk1$W^X+-Kkr_4zSRfvz?s#}pjq^B9l+8<+EakS>jh8ok!- z-D`sldab)=@4iEa_8vZB)S&*o2Mrw3zjwcZ!}|9fF>v?(`b|*$1`g>vXk@?Y&=rq5 ze%HqM)ZS=}95S>|-(7q6Z6DM=Y~GQJt$;+W<1uQZv3s9E;0YSjg8TIA*Sqh?9sBDu zV6hc;AFxEnfxT;ED(u>N4;eWah|;AoHRs`d`wXHq_;`(JI1g<f-eKzw?ijGc)}=8$ zXU1BLQ-^()CSN>!_9kB<e4Zv>vdOzOG;A_(um1fu?>}tBz`p&5!@Kc+9Rd3OC3n=a zl!1J#a}p+cogw`?qP$9SKLcBuwNKX4^q+_8hOPge_&7IS$DIcC?lq`=$3BDB8M1qO z-##M-whvinjShRa#=_X!M~)aeazyX;0Rx8jAJNhmLGRl>cxd~`A^o_deTHG^O3lll zZ_>B_kpAlo8PLAk$N>ZT59{bf-A`id(b|@4>0Zz6YR;X84J0wM(#+eZ+FBRJYqt~n zU_4WtIor`jwek-KH+${Y7*%t4F<U-IpzqazyEabLXXpMbsiuQ-b_v?B{!H31Yw6Os ztRoK#t`&0?e8jLmLxvCSgWHIXzOF`V@341k+}h#KTn)k6yE*&L)jfaHM~oWU>h*!Y z>8Ybz<N3eo!`hqIV*JKOo%P;>`!sD`8*SV)9cz_wbM1O{XsM^UlI?44bXw@+O(5SC zKCDl_fg_nI`5t5WVjX<nv3zlO*T#YH)-B!cCSlAe9om2a&<=hEd_bSRBb+?1)dleQ zUIwn?Jq>TJ0DZeQ-hq$J&)uf>Y1O#n)V{46H<5Mx+M)eb$Di<K9nD_G?;36|T^f^* z<x9ZFYpe#(^;{p^v5q@k&#nKa|8+gL|C|2T^=$u}{@3*!-B}-dJ-aks?676+b!of; zuh;Ayc%8%F$MR;M<8_O@dCew-kDb%jHJZ6Y`)jUx!0R=e7oKajFu0DlA-rC*KJc;m zTi0x0)mqnVx2m<S*{BZfuR8XH*K2n0Sl+y5M~~%Rv+*0Z!#nLojOO0jwZkTMoAK;5 zz7zi@?$&q${MS9*cc7bcH}*?)KY!Uq^sYIc8k?g_<0EjrHXnE5pLXJ(|Ba8|n3`wx zW<v%JXdgDXxsz_N<1RceJL=cwXK;JJ{)0ICyioJ`yHo%6!M&TyX{@i0fZYf7--FXw zjcubbbXfZ?O|2QvZPDo4XK?>veVQ9!H|Ej2EThKA;r)Ae<Q~3rA2&nitUI=mJGM7^ zanCrpv;b-}*2c<Z?D)*lI`_g~&2jbjIX3%PTa)*MJC^o|DZ1v%v#sV+OFo}-HJ{vk z<}jbnI=?f_+~P~a|H|K`<JpC&<9TlVd1lq|)cF67d_KGCcyh;!{Wg;SmH)3bH;04p zaXwt5@pt{zd~)+SpVt34od56O)|a(d^Qk4DYq92&n{UEazNxr&=JUJT+GNd|a{kR9 zp8QoK^lx$Fz-ye`xK%k4r`9=cT(lY|H*PdX;?z3F*<+298+Q*!;?(|%Yxd(@>gSCT zKl7+ff#x-_Z^v}bUEi~V{e<^y(hfc?cGuJl98(izTu*X1wzxYvoZ}uGetN*I$wPfQ z_yjF%Z9U;$A2ofZCDWvwdvqLK_+H-B)r_5-v)J*>?X@&cy(h@;=GLKRtacCUnvru4 zj&V2^Xz`iAexD7W4QwspbApYZg%Q2q9eY-=_qE&_mgMZ1YAdw3_qtm0EDiP}cOI7I z$T;%lIsC-FBG`GBJ7yaPpH&=hO@O)8<Nr@^`ZC`Z92sBUm%}-Wzk8_jA3hT7x(Gj= zWX6R*3wKVPhwM|%gZq)(x+dl9m}<_0+&xJxd8U9kr}|IZvej`mMsq#He`~n!HsJ%| zlN7!iyw1ZYxYs@YW8kih@WbI=&+y~nu9@)D;ZqfUK78uJFNaT4`1SDah2IMI{VVzI zg-=)bqwuUZ`+geky%hhK;jYv0x8bhQ@Q>l{=iy(&eg6vo89r;_<8aYk)3Hwo?@{=a z@ScUw0H3|^p71%~-h1<ct(jBD^_vec4p`mmE%%wD=Jj2mg^h9D<oV;e@wp<`Z&}Wi z-JzLB?z2U08vfhX^1GO`YfwHvIXqv=VQ;R1%fWuaujt^TS6Ps%T?1Fb_3_X)J#im! z*2bx$mJb1rp`N&p!TKjQ`lQ@I$>rHz)<QEr_qKHn@J4Iwzk2HWsDn3F4WG^%uQB>= zxz~PG_&A)MvpiFsGoPJu$GL;E^P}dR$$fsR8JB0LaXusE#y#2cQ8P~NbJ94k@e~wq z&6eo=ObJ($&&+@G4D~*ml`egD=u;2pQ$NR>hO@c#b3D1v7&Yh7wc|6zeC}Z$OS2Pc zZ%$M5+Wds#G?@eUj`w=c;l8(5?)!S>zH5iOKlCZw{lNF?*ggABUAgbo;rfp%T>Xf` zwfkNjf7h+=)ZyAMD_pzp)UkW^eY)~nJMnu8H=pm&@t6DV9PXO_sBm@PlVf+y`i>m# z*>~e`=gW8F%6&Jk+;`(}$M@a1a^H)?&F6b@xc<HuhimuUI9$8$#+CbST)FSXmHSRy zx$nc_=J$QLa^Ht5_kB3rv+u)|`%YZB@515M>pO7ezWauIJw_Mq{QI68yJz2X!>!l% z+{%5=t=#wAaL4yOw{qWc!_C*DaQ%J9t@ecr*S=vV?t5<hwfl}+x$n1?`)(WV`1^L^ zzS~y&(S@t~ZdvWVTZTKn@0OK+-r{ZS8a{^><d~ns?^!FchhT0j)Y4aGkDLcA7rU3} zCw3nZ|IGfgDA;|-^AF@$obwVKezY&yvU|=LOM%TDzC75RZB*d*pB2D9>->JGEq*J4 zwS}()u5l~F6Q?bHtAMo~MBnzfD%f1=SE2dLT#duJwEaRK^2Ipp$Nt30w>r3vy9PYt zYKz~RU~S=RfoohZc;d9hZ*8!))VmJYT<Y=p2e{_?Cp@{d#cy4(w&Yq5Y(Dk)tPl43 zj&9A*24FRPbM4jQzahAey%9WPYm48;U~S=>fNR{Q@Wg40-)3NKsd;m-xzyvc1=uxo zK&$30!D{+u?W)CpE3jjy$F0F?z7u5KZ39m|+7r7iSX<V<+_mjGcWrpC_kwFCvD<@d z&%NOpLtFfI0Bds$pUd*tb_Cbj`@+@yUXa@R!IM{eV*7)&?ZcYx_}&Fpa~z-d132{6 zwli4mVCGal5Ukb)j?XTge0GJaRi8nfd<MhS^x2R*(C<P+;N~}8yY=kESv|E61$&Ld zcLO^&hqtczFt9%A#<z1;i~k64jUNfuCu?SRus-UE*#qnthqT7n6Re-QV+`l47XQ7# z_1f$WSM%L5*JdAhu8sD@?hDqIYqK9%E%yDvHTP(^n(v{>JqDiK+7o*KSX*)*2v&>z zAaKonFkH=d+T=b2p4{3Kdnj02avug(%e6fmY%h+f&3PNeSzUYt=R7}-1bYv8_W5x% z=VLhhcuyVMvU|?>$AQfeemvM~b{*HOjq?c{`l!2?%a7tPw_}Nobse4rwzlLt8SFJ4 z+PWuB0jp{Eo;Vd;?~&8s`lu(z>EL#b<TwMYmK<k-YmT$v`lu(z*<gE2j&s0j$#E{Y z<~R?ok9w}d`C#iazxFZAk3C-iwr}m`Q@aqn6Gwb50_&&lH9L{Bn)njVm$vX_oUd%* ztBQU#IM?_Zu=DQOYkVE&>pA>*jc;h#J*WSFfz1*AZ*X0&H^SBWk|XQ&Cirq3es9p8 z*qg!HvOaDBn_u1aA-|Txx~x;2*xSH$+}q)5{!Au5cfhSR&z3vE`l+Y3yTGYUdt&bf zYja+2<t&fwUa(qn+y_n$ZSlJwtj!$vaF)mRAlMwK?IEyQeRezyPhRbbeFUs6_xYn> zwb&m6*WCYstJP=ff8oikJ+Y62wI%lxV71tv1lQb8!PWYf>-{u5xwR+u8L+nGeip2j z`{FsUy*Q>e=j{Q`>dEl}xQ_oKT+N>m=6bvY&-mIC`!ZNt#(xE@7W=E<n)@}lT771` z4o`0FiG2gCExF$WtHu5nxaNKvu2!EJ@4%B=dt%=OYfJ9;z-pPd_rdn!nA)7T=Q*qU zPT@PuCtx-2ee=3!ehOEgglE6}Gcb>t4u5Tl{T$pm_6s!i#C{1j);!u$+gISrIn1q3 za()f&obwwr_2m2(oSfSBZ`J)BSX**^5AK}n2Q>BM`VpMow57hEz}9C@eKumg?BQqd z#~gm5{nFCR6YbZQ=Ffnl{f1`Wexm)}(rWA<Ev?4>iDpeTmbN>z8aqx)Gd8`9i)P){ zX<gCBL$@YtaLnjk&>heG=2QOw-W6;v<MhcqcLO`m?onAo<D;o(o+kijp0y=*LU8BU ziO|#&J2BW;=U-duoCIuMuaiE>IT^Tf&dJf#lXD7ia%#&Oni8xnxuybl&NVffdU8zz zPH);$Uw5$itWTd@^J&4>?kC!GEzLa9rf+F=9n65{&usm~Z^o8ZV`pk<HFjn+YpSuc zw6q#KYfGzZXf`zKwodCxk3GQFWDSlPy(if5%x^w**U;=>a~Y@43EWrebAVl6+B5fa zf}MMxPgz%Up{Zx?=LTo)wIy~QaOc>0(bN+=AJ|yemA2GAKiIt5y>`jD0K9X~1<}-# zb0KhYYRkG>7_2S176Er&SBs*lC)Z-&^rkKKEe<xHcI(SJSORYCexfbe(##WWsg_pP z#?ol!^%K8kT3U@=wx!kB<<PFAjvBjsORKRfw6waeRz$OI>$I-)xDwc!tids(uMBoP z^P5lI^|K1tT*m2>b+szkwWZzX-$(eW<r%sfxITYZhpW~1sx{zw{%TL`nqY0_ZR0GD zZ5^<hwzWCSmt(E_JC%QcC+4iKy%%S-#QqapYg!ks=I>kcU1mLaYSNzA^}*V%WUMxN z-2klS^WCwoYH9J`5ZgUySG4>$f~)EOBmSF!{rJ6G+r}Jfe(x41&t~9S^X70hzjvqR zE#RqHdt$c)Ys>eTt-xy5yD4Y6zP|Tt4feZV_%`qp;RjN`_HE(%sOLV~4(vKytz|dX zdwzR#^WV|xy*F52b;rJhylVP8mpg#foR=NJew-KeJ{)S!i`e_zpXK%idwui$%AaTU zgRAFVu|HVtFk-B0C$QQ8j^x=HY@R%0%`*_Lo;<sN)skmduv*PC2yUM2spc6BS5KZH zV726F2dkMU_u){mbvlN2=gW6Xb>9)M13MSaiTwH&ckMWzjyoKD4|>+#2)LR(I>)<% z{W!<kMslc`SDZY1g6rBF1y`$UZ!dV(p7zA<4c3;mw+~p&e)dr3i0^*jI?n!ZHGjXK zH9i`iakM9P3|L#nIRLEYIQw#z>+4>25ZHYxu?NHJxQD>i{PPtV_fUAo)t=bHz}hnI z;b67cj{w))N5a(xmY$A+C%5**9u3x(+{b{`Vm}sKa~}s++pXk29-iFV6MF(!TXLTW zR?GT332ZNpsqOgI{eLpp`P1&)9>`hEyzURDg558|PlLOkWdArFu8+F$r*Kw_|CwNO zhMxu2=cLxXdp1}f_4u3vt}*Afcw)|j>!Y4~?tHMhv{}a)oYj)^La^h?-7_u%>l6FM zV8=YBH7}Qd)$~iRmx9fs%`q<Etd^XYgS`jBuK+uS@s4>V_zLDuJwJoK3T&LV#9a+` zjfY<YHcw)%1?!_erj`3Tu(`BZ+hv^9%;9ys9&EkY<8J_GkJpy5{slHRd;Gt_`l`q0 zMzHn7=O(b<tJE*09{2v6!NzJ!+%4c5cPm`YIZ51YaAUREhtCf+bC~ybaGoi5g8jJP zso%k&=6)y6v*0dpFOK?5xf`yYJ^UW9TGrFOV6_1p$#WmrJoTA!KU_U|9ssK)&x2sK zn&%<7dFnIeVYqtoJOWlro=3rI=E*(%7}z=;Lwm<{XO7hCGsQWn&y?Na&Zp0m$HDgy zlV{2ka5Zc5ner6ak8`Z;Ne(sVSe!i1fa~7%EL^QVQ=Wro@6w*w=fT>tcf9~si~U7# z&HWNwtv*Lyh9|f7#J&R7mfWv`)nb1QTywt;SF6v8H{i*wJ+W_swI%mkV6|MIx54(} znA*HPPjgl`htIBe!9KfOWBz>UJ-9wutL_``!_|}b1F)L+oJaQZ57Er0J-#1<KPrdo z$^GCHH2t+(*E^imQrBnTTG!`r>&n`<t}o!~8S6{1^{CgnzJi-idwjnJ|F62fLDyfq zb$!ZNEp>edu62D6x31hv*7XBiJ!Aa{&Rl8BeEkGApZ56v4E|qr{erH)cI*0<vzm1| zpTB|YbMkk1eNO%X*GJv>UpcEKp3Bm44Z_EP>yu~RxNv>c<1-%E>lWUn#S_yNu8(^5 zk#1mfX|s+$iC0UG3Bb;I_=NCU$3$>_)Z;TTxW-J<;;Ca&xIXHsV=}P0v{{FL7Dp{P zrvN+0;ZwqE9aF*eQIF5m;2JYci>Hq6aDCKM$FyK`X|oRh43L^RT}#u0oufSKW`O%= z_tfJvV<(@P;A-``HZ$B<ZSJeHa`xlCs%;hyHTP9<a?b{KZZduku;Z)8rzg1j%nnzp z<Ie#%R-4a)jOF=z-n@La&Iz^__jUcP!&>L&oLcpni$l#?#i?T+u=AH%=LK7<dVJ;s zSD*ReYPHq{;KpjR){NyjwJr#@7VFpFI=p^<H_+yI_OuW<-xn4Erw{doIn?Y!oag+a z;9kr@_F$iri=nCK`Mfw-E$e6ru$s^3<XIAKp6r?CSqe=(d6ovNCC@TowVG#HxOuY2 znP)jP_2gL|td=}0fYr>Cy=_IfbvlN2=j$@&NWFeva8By?1)uko`)=y|TE{B*UJW13 z<|J=}tF6jmer;;TUjufoeb?2t8oG0=ZFR6V&;AZ|P0nj^_|e|0W%r!1*9My-d>!y2 zrIvrd)#~rG{t3^sTzg{I1#8RiP}c*SU)_6Dz6OVNS*JL$8-VM$8^YD<?@%}D<g+nc ztuOuMopcj;YSW(ln}W4vjyD54hI)K92Rj$>*#fMedh%}xPJZo)-3qMDYqCCPd2HK& z)skadaB^si-*#Ya=GdCEJht9obELK%z-rzX$=e5>yxJ4HBUoF$WAz2A#oiBGbN7d< zd9Nh*0C;k1PwY-$ZOOeeSS|K};F^0ExLUntyTX%OdtwKHwI%mpuv+fLAz*uPOl{8F z_MFv|V<@<ezZ+bwuIFL!jITYh!@=4z{s^#I>?6T7_wI1D`a9Y^;K{8$v3r8GCHE+> zTI_p)Ywo?_YV~)t`@oZ1dt&zmYfJ9^z-pPd{lWI)nA)7TcFyYg4m}2}mi^o3_yKVB zy#F2u_WjrI+}aX*5V&*f!D#A<Jp^p5d9|gsL&1K}G`Bv<c^J5J&co5vlk*60a%#)( zL5>7#ORl59opT+Hrk-5KfYY0{)ORe{`pl_Mes6Ic_+xZG(T;Cv=81MfOXJ5;W3>~} z?AuTLPHJg2_T-jUV^2Y|rW$){ORKS`wKQYX%jsy=ZJpK?{S2@*S%YInKNIYD<~N_Z z?_Xzu&1IZEndh^?&U2pKUh8w<>Y3+r!I@`mi9HY8Ire-s^~7EPHrBk_Qs;$W^Lm~1 zNzRMFopWA{rk<RafRj^O*3hM3ZOL^RxO1+{(bSXc3UGSUmin#)o6q|6$u++UZ0&xc zUER{m6YZLoR@cF`Xp?s72p#KpT}!L6*SEA9djpy^`N<gnYH2n0-z}}Kp&QYx+d8c) zJ>CSiCTnoa=r@BM&-~_7cMaVFHkWbw<acSef?Z$QGxxWFo%?*3^ZMToSI^wv0nXfO zOYEKC&aro)sVDYsu(9UVmfG(Dn^(KnE;;Xocg}eqntF2H4^B>PSyvB$wI$bsU~|=b z<{`Lxay<-AZ`xAdBVhAsx4vA<N8#4)C)#5z%{<Zm)6(kN_%E7y{lxF_mR4h*XlXU} zNwm(tqkXES)!3(7T3uJqpjo$dT332}7Hmz{;F!^$13RAi&8P0VdLC>p<Mhe8dI9X( z((dzbG-tIuLtg@~&ynw2FN4+U?`U6z=lQEWv9E!(nfDdW^86n5b@0T@rMmVPIjbf1 z4e-_+`B~zdU^Sn^zDK?d_T%?yZEta?`F&cPJnw>Q{qMom>dzA2ho^q+iTwbqE#DtL z1glx^JDlbE`fm6UIPZp^fK!|L#~f<bCN{>O^Lz^4zVOe$_4lct!}U?mn*RdqnpurQ zyScnSzXV%T-j}}u>#KfQtH!Uv>b?V|9?y9X{swHl&Y!;4YOnUCExmpVR!iRR;A&o% zA2|E*x~PB8p=R%5$6m9=)#YooxYy4yeE0hqT(AEx`f|7*IL>ciKaQjAR}MAD5hu?d z;ClW4gsau-?|`}f+7mmDg>dBhj|*0FPJYKv9^WqDI!;%(TK&0lH+aU;p4joh+A_`r zU^U0_?`6sL^*){m>^+*;iQ#qJN#JVrXU>ztGp_c;P6pPNaVH0>#XbeN=AII+R)0S^ z6+F4MCw6MEw&b1$tQLEBaLqj}T&@0oayoc&YftR-U~S1g16VD4;EZ5<aZGK;H<~}E zo(b&yX?Je@J8o*`^?sZMTz~F5E8P1tzq6YSu8+F${+&3r#P<Z7GkkWiKKYs99AJIa z<1;6?#>~~?iJ2R&k9vL{GY{BY+N`4oXSL*<5A3*d_lEhw`oz8f*fI0_$pyh``lZ)} zz~<5B82<e}wd7m`>^%^^DBLmf`^m+?{v1v{ziV6^Y@D{lEdh3ohc5{>Phyq=>!Ut~ z>u5hqgUzMQ+WfnQYUXe+UIv`KcsZ~i_X+i7In>-I#Kw5-mj~Np_SqG{*=Mz-z7@fa zmwk36u)gZ?Ss82(@mU4z_Yn2`ZgN$yvDy;X2Ci|d!PV-|GgpTjt1bKQ8enzz()8vz z`}&$-dv{;d*S?)M=SZ95J8x@&>%QI#uI7Hb4rf2kqx#w$YR;p$?(6DxUw2=24CKbT z{HN~g>%rCh4(m7@=)}iyw5`vf<~ZWy*+?6C^SxwaxLV!UH-TsW(4N>$!P>HaYz9_~ zeRFWly#-vY?&Vv;lUsXYw*qTR?ybRUv2O#exwnO@)%|)qcyen`?Dk-7$=w^QmVIvr zu)R2@Hm~u9oYl?Y^J7P_&yRf1?hDta{(Pe!yhG=Td2jTGtGR|fvY!q>GoSX<uoL)y z{myG=bp5qkS0B!5scRQ-t!r1fb=B|xgWw%{tFFOt>rt<D4S}0ad+KTj|F61+qU*2S zx(0GqOI^djwXWfC>#FZuBj6o+tFDpo%$2sx*Y05RX-{2yfd5xrd!p;F-MV(;tY%$a zlfA(8S+zI3KCAYD>!WV`D9&n$-w*6H2;U#9Po6uY!TPAjXAHQ;9MIy4IS{UodY)AW zfz74OI`-wPmYj!xo%8TR!L^RV;QFY?=WuY1Iikf=$B}S-)KkY%Vh(NAaWH4K<U9uK z9ETqZu5}y-*GD}*$AfFk2`!#FPK4{Do;pqfn@gK@9L-tHobJIVgY)b<73{~oQ2i7R zHTOcXF+LAZ13RyI-kc7ej(c1^K4*0DITNl{pDky>jn(E}d=6(nj<4-(4mHOYC-=Ev z=QHD<2X=h*_?+L#=K{D|9sfeOvD$ooWGv5lmR$t47W>!VI;`~)&Z$+Oi#gP+Rh&95 z1v}@d^)j%vs>kQ@PCi$_)oQI*!j08ttr^R6YP||<E!MBUb>x|SHCVf`xu%{IdkxrY zzCMS(=5@WeHndr*>*ZQ)oRjxDxSDfv1Lw?%`t=-Y&WYHu^Dd??&%4+Low&MVA~$a2 zKdZs>?7a!Dwkn!6YEv`c>R`unoYZ_Xwyg16!KqRG7LKntj1gzdyTA+6XZYRl;f3D= z-wu9IqxrkTd*S-1C+5CRKKH}*Q%^4sfE`O);vNLIm$4p#*RdXk>!Y4LkATgkEqNXV zA3>h@JO<ZKJwE>dw{`LP-2C?){tLg8!@sAgzw@i6Ut*pH*SUEHUgzdnc&+z2xIXI1 z@q8zr7vTD-r`{LAj-@SeFM;daybP~ny#m)qJ$YUQn@d~ryaujw^EzBVb$wjxZ-D(X z^p`U?z{Z>WN6qgDet*fFy@mD^hjV5g=S)rijQ2LU&e=QgdCE0@7hd~#53Y}T`gk8~ z9&O3{0l4<@AzVLo>-dPXn*Q$HpMd)?uC|ZCa&122KLh)W*Y+t`9@`gSf8Va{bFh3l z{)U4;JNyznEoa9vr?L8YKYG7;Z+VZU=C8qZF1~@+_46&f&c%0debkfV`%XST!1Ytl zeEkS^ENzMV30&9D&+t0dFK~U-ljm2kxwIwEZ{Rxbzr*!Y&${>noO?;TbElT?zQD$x z{HM+Zf1KrSb1@FQ);F$y(SSoewT#!vrwd#^_4Lpc>{!|o*9~0fVtjZVYXZ1F>d7-9 z*j(C@XCiQ&i;3a-spsCA1nl2S?|kn}ik^GNIOj-B|GIu$NAhFH;d=6%@h8K#jz2kE zEzbvSYQ`Vgia(n3@4Rs@%i+J@<=@qrn8T0%p5HRmK}g5H<>z?*8-Dq>yZra?w1xZc z*;PJ!Cq7S$r(Xa4JpYZr`&!SAnZauQyLt9+ezo}f@8jwJK+C@eSj~SYFFAUGdvGL& zHK`@X9N?N`F1Xs99LX^^SUoxHLoGSx1=k$&!PWFnj`_jr$zktm$*}-fEqp<+<Ag5+ zw)XIa!Oq8q%&^yJ5e{=0r?2)uxIXH+mhMUJM}GXb5_2v6cM`?^-rRp9QS86P<iC#? z?7xlZ^`4G%YFGwrY@YSYfz|vwTDdP)0IPd%$8RODy6@WYTN$k0e10_l-0UiFYskLf zKD{c3x;4mG<FMxZoN9G&TT9Q+z}A4T%F(oSYpe-gi(@GcpG}VK`cl(3{q+LZ{?>-8 z)&ACjtJnVi0avg6tqWK8KF>S<dSLrgOF!#_)x$Rc*Zwwy+n;)V4!055xTdYy-^TFt z=h*hArf>S&1YG;u6s}hL+YGK=``a9@Ui;e;uI~GI`r8U@e`@JxYp{CwHsIRdws8AX zPk-BijceMP{cR6Ve~xW`YWk+X-r(Bb4sf;FUmv)7?Qci8dhM?tT)i(x`s)ww&S7l& z830!IS?4<2i6eEI!#dUUOPxD|Yn=n(YPHT?;Oe!`UE%7r&cSf?K^&=b2-rI7I%|ik zr_Q0^)M*auRMRhY?gp-P4uh-JI)}s6Yn>zD>b1_@;p!tfQs*9E>#XZ#Pq=#O90g9D z=CDpR{Zi*%;9BS2aJ5?JK5%vCB>U37VD(z(esFdBNuB$HUDs;4?xVr#;bXvcT^|5< zU8|4bc{M5L135->G;PiGau7WIIkx?&>6`uz2G{-$fveU24uz}N{tkny*ZvNNtLvBk zjsV+VT`xz%)zjZm;M(8OaQjnFf5(80YucLq9Scu?j%|Nx`li3*z_q{Q;cB(N6X5FB znCo{USiSal5?tLimHti!+h1L0r@+<I->Kl*-)V6BQ%`@VgN<w2n*E&tPk)YWe`@-s zzcazLzq8<KwZF6B>b1Xf;Oe!%bK&ZBUpf!ooujVL^Wo~bk1hbGPIFkNntrMCLU66~ zBDh+u^J2Jqt@9GNdad(PxO&}}E`wXAv6=VF!Ro2=3UKN)hjpsympZQm*E+9)tJONM zhO5^)uYs%AI<JMRkL1XDxejcdb-i2<S5KWcfK#VAtW!<D)cG%Pt@Gb-wOZ$maCOJZ zy1oglUhBLWuI@EXowtBp*Y&#J3Rlnk-UhDg`gXYMT0P&F?f@Itv^CfDo$&PM*!HKU zZ~D6nT>HBlu2%cI2d-ZGyBDrr`@0XW?)6H4_k-<EE&V(IRu6v=T>E<nZhz|O?_scU zO<S|SN8sttvF%Sy-}Lt=xc2uLT&?!^AGmt$@4s;M+TY`Fb^X%c6JYyOOFvJ7)x)0x z*Z!V{+n@TF)^p_<uyIXWv%hEI>Cdt4Pfg$S_Z+zP_dHy!_V)r@z4rGaT)p=95?sA6 zNBVmi+?}JY&sX5;xsP52r%rQNr<#7L^EGg-^L4mdt@91Idad(KxO%PgEx7t1j@0=! z*gESvdk3zbI^PAS&bPqUsit4*d=Fgfd>^h>>-+$&UhDi2u3qc>2(CVoBXxcZwoYTS zK0X1fr_N8osnZ<Rsit4*{0v;{{2Z=U>-++)?)A*R^d(rm*7+4&-D{jWzXrRm>vjJI zuAaKT1=n@`9o%)TKBl#<zXu!Fv^CfD5AgKo*!HKUZ~FTYT>JY8u2%c|8LnRY`vtCE z`}-BH?%GIyzk%(qu9x58>gn$faP99;xc#YTU*bnD{OpCFM|Iem{f&c`{v6x>)bve% z<AQ5{<H6Nxe_i0}wZE=#_1a%IxVmd9{f!T|zq-yQKvPeD6M}1h6T#bvQP1_87;IeA z*6eQ*c=~f}`%}|5{Y?t4{Y?f}tNl$5SFio~zl)+?`<oK3u3!3_3f>)F*XPt|>bZ}m z0jExLSf`qPsk1w{);TR)t=2gmT)oygJzTxkIRjk1?n^Vmt+TGPnb6cz=gi>LX%6dD z(=T<-0<Lw=3RkOj&IVVnb@qU(*E)N`)kl{3oE>hRb-m1irk*<I1gB1OSf`qPsdFxH zt#fX;TCH;)xVrO{eQ92}daZLlxVqOk*L{At>$+a|1<=&3VNz@hg6q0o2;SDxbKfqE zW?a+OT-S@h)1PD8pPIhuZ&7gVZ!x%9?Qe0odhKrsxO(kxNw|95mzIKe-j|j}Q%`@( zfNOut!rSOiJ@@T$VB?y$W`E1W)1PD8pPIhuZv}AeZ$-FT?QbQxdhKszc!y3M`T5`~ zXzF!eS{2@TUur{BPk*a{Yk#Z5+sLb)>$ip)N7L5qZ%ugm>lmB<)bve%Yk_Njz2IuK zzqR4&wZC=X>h=2l1Fl~8rGLV^Q)^wH>!PXWK3Wf)I?dsAP}47Ut`DwtZU9%Sb#4e( zuXSz&SFd$$3|H4L_t7SB>#Y0IrfBM^b2D)2G>3Jn>6bb;2iH2cfUDIyw}h+LI=6zW z*E+X`tB)*oZUeW@x-V^urk*;t1E)@NSf`qPsdIa9t+O{=t=72%T;1`rFZF?|*E)BE ztJi(0FTC@<)DKPF8r+xqgX_8;0B>vQxo>wuGp=cCuIruQ>Cdt4Pfg$SHxOL=+Xb#x z``Z<+Ui%vaSFimIhO5_oX$ZXYzSNGUp8ke{Yk#}J+vra{{S5;f*R(bJ8xBu@j%|Nx z`li1T;M(6vxLWORcer}(Zx6V7?Qc)Gdfk^s!8`9ud!ebPzrDe=zkT3s^rxPEX<x8$ zO<S|S{ov`(vF%Sy-}JXXxb`<1u2%aS16Qy89ROFa{T&Ebulv$L@b1)F_oai;)N>yl z0#2Rguue7oQs<%ITIXSKwOZ%laP?Z}5peZd=aF#rx-T6Cx6ZmR9gU`*I*$RTPIFkN zntrMCSa7ZLIJjD^^LV&=t@8x9dad(BxVnDXKTm>NXWf@hMpI9nr+`zZIjmDnztnju zxYl_ZT&>o523-Agj_gZkg4JuCXTjC$zH~Oc^S*Qrnz}W(FP#gn>-s!+TT9QnJ|E4v zrmeZIFMy{%$F@H;ebe8C;M(6saJAas#c=i7-z9MM+TW#c^|~)z2JgHtU5=)n{;mMm z{;q_#(Vu$yy9#Vv)7I?oYIyo{Z2MEwH~n1$uKisLSF8P92UoBCT@P2U{oMdpulv%! z;GOrSf1|0VzZ=1|znkD~^rxQwZU!6Iv^D#?1)lyK+y2z_O@Ft7Yk#-F)oOpY!_{kl zcfi$ae|N&w>%MdsygRkled%sA_1s7IfK#VAtW!<D)Ojzs)_EUXt=4%zT)o!$09?J+ z`5;`q?n@8Bt+Vb+52LB4&PTwh(;U{RreErO6kO|k46at|{105c*7;w!dad(uxcW%y z%D(gj+&b&N^dy>k>U;{EI?Z97YWk(lr@^((XW(kJ&gbCj&vIm6dLFD^>wE#OUiYOJ z;hp!Tm(bL$!F}mva9!80z}s4SzE8Z0W?a+OT-UF`)1PD8pPIhu?{#qP?+v(G?e9&v zdhPEmxO(mHZMb^fm)?PQ-k07*Q%`^Ifop&7!`tXjJ@@SgVB?y$W`7^T)1PD8pPIhu z?;~*S?_;=H?e7z~dhPF1xO(mHGq`%)mp+Gg-j}{WQ%`?if@^<Y!Q1FhJ^g(RHm+%F z_V*1u{W-S%sp*^kz6IC*zJsgP{=SE+*ZzKhtJnU1gsazm=_h!1YOVXy&uHqokA4BC zPIFkNntrMCS8%QKH@I4@^LMy<t@97Kdad(MxO&}}_~SkQZ(kY*O+9sv3r?Npuue7o zQs;Q!T4xuyTCKAyT)o!W4X$4693QSek}|R{O#pX3>%KH0ntJM-2%I|2VV!FFrOwI0 zwazKwYW{EA=I0Jmfz@;Ex-st5@ESJ_T&?!k9j@M72hBf2JRRKs9o?nLVP0!e(>FCu z53adqfUDJ-W`wKf`C&~n!E4;iaJ5>~EO7Pa-r1~aR(NVMuQjRZo0?_=*W5keYPF`G zaP?dhYnmNi<K}>?)tcsnt2g(9W=(U!Q<HhENlo9>G&i{Bo(Ha0Ynm6X?lnl<eDE4K zKU}TWv;bVaUb_Y1smZ+7q^56jF9fc+7ly0Vnihepd*3B)QFx7846asdS{$z4d@eNS zX$g30GOsnM>6_e3f@|)j;A*v|rQzz{V~JY^UgMU9tJRv8lXKMdv^+dDnb(@s^iA#+ zz%}=ZaJ5>~N^o_*w<K<5c#T^Hu2ySW6|Qcadx8JkjBOmL$-LI2rf+hu2ClhRhpW|^ z)_|+KXC-b;c#T^Nu2yU61y^tGwauE=hNmX;T9cZ-$-NG^=Kcp<t=9BUxVqydZe4hd zTMw>QYg!+!ZZDaq4dAKCyw;?qZ*p%4uDLgYtJRt|fva!Kk+@C4HEuJwTCHhwxO$zZ zE#Rriyw;?qZ*p%5uDQ2@tJRvefva!Lk+^NaHEuh&TCHh&xO(&X)4X=Q;i<{I)}*Fy za_<1Hx%<G?YE3)B)qUP2t}ndC^@FR`n)<`l>$MvIPfg~vCN+JNdna(sy)#^`*0c*; zeIQ5Tb_LhCL2$KN(_pxI-3x}mQ<HhENloA6ZU@)gL*Z(*reSdP-8d3A99-i@z}0F^ zBjM_GJ?#!pP3E;GHGPwN4{*)BCtR)8v=>}`6i4Fr2G_WK;A*v|ec|f$dAA=tHJR6% z)bvg6{lPW&Xt-Lf=>WL;7>>jp2(EDl!PRO_2gB9to_Pp7HJR6%)bvg6L%}uoVQ{rt z(-Cm>!#NUnB)G;M1y`#z9Sv8n^K=Y6HJR6%)bvg6W5G4|ad5R-(+P0(<2e#{BDlt# z1XrsyoeWp6>**ADYBH}isp*^Cr-Ezl)8J~grZeE`r*kCkOmK}m3$9jcIvcKDzZaYX zPfg~vCN+JN`&@9%eI8t`)^q_}{d|tZT?npm7s1tPO&7z}>-VQi;Hk;H)}*Fya$gFr zxi5pO)tat=t6$EMxGTXm?kc!it?6pGdfmsbfu|<(T9cZ-$$c%j=DrTDR%^Neu6{j7 z;{FA$asP&^)tYXEtJj)tf~O|)T9cZ-$$c}p=Dr24R%^Nqu6`>=;%*1mxI5r#wWd4a z>h;>)1y4=pwI(%vllyLP&3zACt=4oOT>V~-#N7|BaSy=NYE2Kq)$8-_A$V#suQjRZ zo7@kBYwkzjYPF`v;OdWZB<?@p8uwqgTCM4ExO&|)pMa+(^IDUdzRCS0xaNKeu2yS$ z2Cn`zN8+9Z*SP24YPF{4;p+9;y#P;5=Cvj@eUtk|aLxS^T&>ph3S9kVj>NqRu5quy z)oM+z!`16P{sufXnb(@s^iA$J!8P|=aJ5>~J8<>4ITH6SxW>H)SF1I>4_B}A^Z`6I znb(@s^iA#$!8P|saJ5>~Cvf$TITH6NxW;`3SF1IB4p*=1=?i#jGOsnM>6_eNf@|)t z;A*v|Z{X@*b0qFtaE<#8u2yUM9<E;RyC2}G$-LI2rf+ip2(Gz*f~(b<eu1n1%#pZX z!8PtTxLU30cer}}p7{qnHJR6%)bvg6KfyIOE)BI>)3|8r<8UNyJaCQc0#~awb%m?f zXK*)oYBH}isp*^C<AZDN3E*nAritL{6LKVOVsMR{1g=(VniQ^HzpG3JPfg~vCN+JN zdvb8iJq28?)-;uzV@i(1O%1Mb)4<hgP2J(@^?5ffJT;lun$+}7?&-ia_w;bJTGNbh z^%*!4HxszV%?wwoHO&H7uk$o3JT;lun$+}7?%BXKcMrH)t!Z|+dQXnT%>k})bHdeX 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>, From e9e6aec8f8ba96c169c3b3651dc294bc0d50019e Mon Sep 17 00:00:00 2001 From: zomseffen <steffen@tom.bi> Date: Mon, 19 May 2025 11:44:05 +0200 Subject: [PATCH 2/5] first working version of volumetric shadows --- shaders/compiled/frag_rt_quad.spv | Bin 48832 -> 76768 bytes shaders/compiled/rt_compute_grow_one.spv | Bin 4744 -> 4744 bytes shaders/compiled/rt_compute_grow_three.spv | Bin 4852 -> 4892 bytes shaders/compiled/rt_compute_grow_two.spv | Bin 4852 -> 4892 bytes shaders/compiled/rt_compute_mempos.spv | Bin 45852 -> 49864 bytes shaders/compiled/rt_compute_rasterize.spv | Bin 23524 -> 23524 bytes shaders/rt_compute_grow_one.comp | 2 +- shaders/rt_compute_grow_three.comp | 4 +- shaders/rt_compute_grow_two.comp | 4 +- shaders/rt_compute_mempos.comp | 54 ++-- shaders/rt_compute_rasterize.comp | 4 +- shaders/rt_quad.frag | 285 ++++++++++++++++++++- src/app_data.rs | 1 + src/buffer.rs | 2 +- src/command_buffer.rs | 35 +-- src/main.rs | 3 +- src/scene/empty_volume.rs | 39 ++- src/scene/generators.rs | 11 +- src/scene/mod.rs | 65 ++--- src/scene/volumetrics/mod.rs | 11 +- 20 files changed, 426 insertions(+), 94 deletions(-) diff --git a/shaders/compiled/frag_rt_quad.spv b/shaders/compiled/frag_rt_quad.spv index 5523307721e2846a9fac6286f038154b20da90df..a738849b8da732710694744fb2f76179284f1f06 100644 GIT binary patch literal 76768 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Ñ_UrT;zjr*Igv0M9Fui>`$cV0_=X^s2)uCcqG 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 literal 48832 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 E2PMuS2LJ#7 diff --git a/shaders/compiled/rt_compute_grow_one.spv b/shaders/compiled/rt_compute_grow_one.spv index 23863abd403c5b111fbfab3367c669fdc790a780..ee4c26c5932b2774ea1210466d17b7a2ca06bd90 100644 GIT binary patch delta 1597 zcmZ9LOHUM05QT5^8dv}`BM$+A0UQzW{Qwj}KyXGBm7t<47BCoM6oIgD(`qD=7#E~> z#`p)+goKp~<JuqKlBMwnm>6~CcbYEJ+LP)!r_Q-mx4ZAGXV<fveO^PObME5egGY<2 z59dZ!=jRK{&Xw_N3?{w$u6?MwN?pQ@l4m35%)RA>xtW!P#|3F+ZhULQ`|eFPU@0R? zh&*>S*R_|(V>I3oR-Mba;;>c>&*9g&_FWCW^`-bnk>8D^wrRp6nptL}TA~)>8GKFT zB0{73Bd)fp)xw*}8A5&3SG<MLrS%!IyqZ@7>U6FrG^#K}NUURMo}3Az#9byQ2-WIo zazi*+N;G--;8nt})sQ!YhDv`M>TTtpOZ7<U;9L20O0QQvv}yGl4<;(!`O<$ga}W7f zlz-x=h1U_fq}P+BD-WP+w|eX4G2RMJ5yPk%avPynqsNzK>)OH6;C|RhpDVs_Kin2d zvxQl(wCCZOaP9zD%~XF+jd$q|655!wKWtRIhR_4)0fenzm-GJ}d<fA7cg2j|U}?7S zFgU*9BXC<M&3s3}(rm-W!0M%X=wZG)PQ;s?fLk+Z*6bu$nl(EGRzuaza~hl^o<wix z3|KXJ2RT&IR5QQd1Bnmsh1+mxX6yq?Gkz8vUv~~}>!g{lA1uu_eIBe{s^i)D{sRyl zq-W8t2Sd?0nYC+aJGGsIcLA>9_LRe5)rJT=d?R4nkaXM7MX)sWP3ilqpcAgst^=YR z|3~QH*y1s8{HZU&ZHP4U<-pQ3WRxs!+7<Bb<};A1go^qr+U_U7VdG$<vdPcGt`pY? zwH%MQT1uNDR9oZyiQkH9H_7I?4UT)J;i|<wcmDI-g;NW<tH!+1V5w@B``4-$6?&vi z{ojH@^%S*_)g9cot8?75$*IZ=`cq<sXbIMmy<TVVDcS0!gYBex45#ETq~!mQnhpK0 M@xBcG&FTAp0jNKOyZ`_I delta 1596 zcmZ9MOHUL*6osqhZ3Jd`ia0QUgCM>ifFdX$4v44(6<x95VTe%#!p2Rjkw{`(nBEzq zKR``LSh+B+{Q)jnxG??z6Qi#DPETKHZF0NLx#!faTQ$|JW!5t5-CkXtb8c|q&b@_| zyE6kTb91vx&K2@k7mRzg?e(a73S5yJWSowiQ@57pXQr0t@6SprbR!$jy>H(5PAr8) zJ~7N&#q}sZjL~>Ym~}4e^1@smJd0n;HUHJ%8=vyNZ}U^wtaL*(MLf-vU5wiZmF|hS z$|zS2-_4jNJfb7wDX<>RZ)B8LZC8O>8RZi{L!foK8Wzn$(qZJY7sr99=PmOnSc}v$ z`HHk)v8dk52G5H8YBljProRgHrs9tUnl&1HEuKv3cvVxIQ2mi$tmKWq1N4g~Dj0u8 z;}0BF@M=Pj^cqI#8hfMmYr(}a-T+P#{cKL#P7^vR9fvfV*91=IxF4QFGbBDyKc7vM zW)t^-r9BSsgmW3NiYfn=oX&PHp~j^Brcv=qLL1Tsgsoni^Z#AA9nltUiy8NUrP;&| zaJ=FDaGNL1d<VeNtl@)T)lxq6u)aG)#ETt<TQO-?><Czz6*~%6LFLVJ44fbyL??6{ ztem`kTrz3OncqJFi7(y>x5cHIu?sBCcsDpc?<CyjNi*LmurzDB2drAk<H`O0ry;sX zkD{)7!OF?3u5*`ct7sp2EpEF!8~SqJlU=@ka@LS^YiIy0O?8uUD4`p!+pY_uG5jKe zFWW2qbFlb6hu~ILnw32dmZq}$(!@=>0FJkN5w4uRO>1`yY;~nabA#8VrM~_PTqZ6N zsy`BOd8ADc%B^yI;@6_wRYvn%2gf~=aOL8j8~=H3!pQ|4WkcRzuvj+D`*Yco676qY zpIb0nK0)q%c?<8&@+|L6Vxm;v{zGD!NCm5jF0VECkZANqgUy6$^e5$?P0If+IUV|6 M;C&kUQx&)W0O19N<p2Nx diff --git a/shaders/compiled/rt_compute_grow_three.spv b/shaders/compiled/rt_compute_grow_three.spv index 625eb4ba9966b3720f7f14f1a68c5358ae1f5679..b3a00fdec2595f9c3219e4bbddfb63801c7fde0d 100644 GIT binary patch literal 4892 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 literal 4852 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 diff --git a/shaders/compiled/rt_compute_grow_two.spv b/shaders/compiled/rt_compute_grow_two.spv index 5d56e66caf168269f4509489428ae5c815dcfeab..08a31878e0e8a22d40f5e975cb8acbef6278fa6e 100644 GIT binary patch literal 4892 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 literal 4852 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 diff --git a/shaders/compiled/rt_compute_mempos.spv b/shaders/compiled/rt_compute_mempos.spv index 891a76f8bbc50dd19122341f24f594e8c8404310..e7775cd3e01e3480b7c248a5413ab9c051c54010 100644 GIT binary patch literal 49864 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 Q0N7mG{Cm7|{~quE0Z0Up2><{9 literal 45852 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 AkpKVy diff --git a/shaders/compiled/rt_compute_rasterize.spv b/shaders/compiled/rt_compute_rasterize.spv index fc8e3b052d2ac700e2fdfc121aea111a5f5debd9..be9960867a8fcbafa9761fb3ef29a6a0c4daebd6 100644 GIT binary patch delta 7284 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 delta 7258 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 diff --git a/shaders/rt_compute_grow_one.comp b/shaders/rt_compute_grow_one.comp index 27e27eb..6fc2845 100644 --- a/shaders/rt_compute_grow_one.comp +++ b/shaders/rt_compute_grow_one.comp @@ -30,7 +30,7 @@ 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; + uint compound_start = 1; // 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]; diff --git a/shaders/rt_compute_grow_three.comp b/shaders/rt_compute_grow_three.comp index 2127584..652a4cf 100644 --- a/shaders/rt_compute_grow_three.comp +++ b/shaders/rt_compute_grow_three.comp @@ -32,9 +32,9 @@ layout(binding = 8) buffer SizeBuffer3D { layout (local_size_x = 16, local_size_y = 1, local_size_z = 1) in; void main() { - uint index = gl_GlobalInvocationID.x; + uint index = gl_GlobalInvocationID.x * 2 + 1; uint output_offset = 0; - uint compound_start = 0; + uint compound_start = 1; // 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]; diff --git a/shaders/rt_compute_grow_two.comp b/shaders/rt_compute_grow_two.comp index 0631b0c..12acbb4 100644 --- a/shaders/rt_compute_grow_two.comp +++ b/shaders/rt_compute_grow_two.comp @@ -32,9 +32,9 @@ layout(binding = 8) readonly buffer SizeBuffer3D { layout (local_size_x = 16, local_size_y = 1, local_size_z = 1) in; void main() { - uint index = gl_GlobalInvocationID.x; + uint index = gl_GlobalInvocationID.x * 2 + 1; uint output_offset = 0; - uint compound_start = 0; + uint compound_start = 1; // 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]; diff --git a/shaders/rt_compute_mempos.comp b/shaders/rt_compute_mempos.comp index 25c5a63..831a827 100644 --- a/shaders/rt_compute_mempos.comp +++ b/shaders/rt_compute_mempos.comp @@ -198,22 +198,28 @@ void add_cube(uint cube_num, float scale, vec3 pos, vec3 color) { } +uint cohort_index_from_pos(uint x, uint y, uint z, uint block_size, uint compound_size) { + uint steps = compound_size / block_size; + return (z / block_size) * (steps*steps) + (y / block_size) * steps + (x / block_size); +} + void main() { uint index = gl_GlobalInvocationID.x; uint output_offset = 1; uint input_offset = 0; - uint compound_start = 0; + uint compound_start = 1; 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]); } + output_offset = compounds[compound_start + 8]; + uint compound_grid_size = compounds[compound_start]; uint parent_start = 0; uint cohort_start = 0; @@ -230,21 +236,30 @@ void main() { 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; + uint x_no_offset = (cohort_index % steps) * size; + uint y_no_offset = (((cohort_index - (cohort_index % steps)) % (steps * steps)) / (steps)) * size; + uint z_no_offset = (((cohort_index - (cohort_index % (steps * steps)))) / (steps * steps)) * size; + + uint parent_size = size * 2; + uint parent_steps = compounds[compound_start] / parent_size; + uint x_parent = uint(floor(float(x_no_offset) / float(parent_size))) * parent_size; + uint y_parent = uint(floor(float(y_no_offset) / float(parent_size))) * parent_size; + uint z_parent = uint(floor(float(z_no_offset) / float(parent_size))) * parent_size; + + uint parent = output_offset + parent_start + cohort_index_from_pos(x_parent, y_parent, z_parent, parent_size, compound_grid_size) * 9;; + if (size == compounds[compound_start]) { + parent = 0; + } // 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); + uint x = x_no_offset + (size - 1); + uint y = y_no_offset + (size - 1); + uint z = z_no_offset + (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]; @@ -283,19 +298,20 @@ void main() { } if (contained_entries > 0) { - out_memory[output_offset + cohort_start + cohort_index * 9 + 0] = parent * uint(size != 64); + out_memory[output_offset + cohort_start + cohort_index * 9 + 0] = parent; if (size > 2) { // add child node reference + uint child_size = size / 2; 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 + out_memory[output_offset + cohort_start + cohort_index * 9 + 1] = output_offset + cohort_end + cohort_index_from_pos(x_no_offset, y_no_offset, z_no_offset, child_size, compound_grid_size) * 9; // xyz + out_memory[output_offset + cohort_start + cohort_index * 9 + 2] = output_offset + cohort_end + cohort_index_from_pos(x_no_offset + child_size, y_no_offset, z_no_offset, child_size, compound_grid_size) * 9; // Xyz + out_memory[output_offset + cohort_start + cohort_index * 9 + 3] = output_offset + cohort_end + cohort_index_from_pos(x_no_offset, y_no_offset + child_size, z_no_offset, child_size, compound_grid_size) * 9; // xYz + out_memory[output_offset + cohort_start + cohort_index * 9 + 4] = output_offset + cohort_end + cohort_index_from_pos(x_no_offset + child_size, y_no_offset + child_size, z_no_offset, child_size, compound_grid_size) * 9; // XYz + out_memory[output_offset + cohort_start + cohort_index * 9 + 5] = output_offset + cohort_end + cohort_index_from_pos(x_no_offset, y_no_offset, z_no_offset + child_size, child_size, compound_grid_size) * 9; // xyZ + out_memory[output_offset + cohort_start + cohort_index * 9 + 6] = output_offset + cohort_end + cohort_index_from_pos(x_no_offset + child_size, y_no_offset, z_no_offset + child_size, child_size, compound_grid_size) * 9; // XyZ + out_memory[output_offset + cohort_start + cohort_index * 9 + 7] = output_offset + cohort_end + cohort_index_from_pos(x_no_offset, y_no_offset + child_size, z_no_offset + child_size, child_size, compound_grid_size) * 9; // xYZ + out_memory[output_offset + cohort_start + cohort_index * 9 + 8] = output_offset + cohort_end + cohort_index_from_pos(x_no_offset + child_size, y_no_offset + child_size, z_no_offset + child_size, child_size, compound_grid_size) * 9; // XYZ } else { // copy color values and add cubes to rendering diff --git a/shaders/rt_compute_rasterize.comp b/shaders/rt_compute_rasterize.comp index 67912b2..836a54c 100644 --- a/shaders/rt_compute_rasterize.comp +++ b/shaders/rt_compute_rasterize.comp @@ -9,7 +9,7 @@ layout(binding = 0) uniform UniformBufferObject { bool[16] use_geom_shader; } ubo; -layout(binding = 3) readonly buffer SceneInfoBuffer { +layout(binding = 3) readonly buffer CompoundBuffer { uint compounds[]; }; @@ -175,7 +175,7 @@ void add_cube(uint cube_num, float scale, vec3 pos, vec3 color) { void main() { uint index = gl_GlobalInvocationID.x; uint output_offset = 0; - uint compound_start = 0; + uint compound_start = 1; // 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]; diff --git a/shaders/rt_quad.frag b/shaders/rt_quad.frag index 378ccc8..d43de76 100644 --- a/shaders/rt_quad.frag +++ b/shaders/rt_quad.frag @@ -24,13 +24,19 @@ layout(binding = 0) uniform UniformBufferObject { // 3 - diffuse raster size (float, needs to be decoded) // 4 - max recursive rays // 5 - diffuse rays per hit +// 6 - maximum number of compounds per light layout(binding = 2) readonly buffer SceneInfoBuffer{ uint infos[]; } scene_info; -layout(binding = 4) buffer SceneInfoBuffer2 { - uint infos[]; -} scene_info2; +layout(binding = 3) readonly buffer CompoundBuffer { + uint compounds[]; +}; + +layout(binding = 10) readonly buffer OctTreeMemory { + uint oct_tree_mem[]; +}; + uint max_num_lights = scene_info.infos[0]; uint max_iterations_per_light = scene_info.infos[1]; // diffuse raytracing using a quadratic raster of rays @@ -41,6 +47,7 @@ float pos_infinity = uintBitsToFloat(0x7F800000); // set limit for maximal iterations uint max_iterations = max_num_lights * max_iterations_per_light * raster_points; uint iteration_num = 0; +uint max_num_compounds = scene_info.infos[6]; uvec4 unpack_color(uint val) { // left most 8 bits first @@ -52,7 +59,7 @@ uvec4 unpack_color(uint val) { return uvec4(val4, val3, val2, val1); } -uint array_descr_offset = 6 + max_num_lights; +uint array_descr_offset = 6 + max_num_lights + max_num_compounds; uint color_array_offset = 24 + 1; uint sample_neighbor_from_scene_info(uint volume_start, uvec2 raster_pos, uint f) { @@ -204,6 +211,63 @@ vec3 reflect_vector(vec3 direction, uint facing) { return direction - 2.0 * dot(direction, normal) * normal; } +uvec3 parent_child_vec(uint child_size, uint child_index) { + if (child_index == 1) { + return uvec3(0, 0, 0); + } + if (child_index == 2) { + return uvec3(child_size, 0, 0); + } + if (child_index == 3) { + return uvec3(0, child_size, 0); + } + if (child_index == 4) { + return uvec3(child_size, child_size, 0); + } + if (child_index == 5) { + return uvec3(0, 0, child_size); + } + if (child_index == 6) { + return uvec3(child_size, 0, child_size); + } + if (child_index == 7) { + return uvec3(0, child_size, child_size); + } + if (child_index == 8) { + return uvec3(child_size, child_size, child_size); + } + return uvec3(0, 0, 0); +} + +uint next_oct_tree_child(vec3 mid_point, vec3 check_pos, bool child_open[8]) { + if (check_pos.x <= mid_point.x && check_pos.y <= mid_point.y && check_pos.z <= mid_point.z && child_open[0]) { + return 1; + } + if (check_pos.x >= mid_point.x && check_pos.y <= mid_point.y && check_pos.z <= mid_point.z && child_open[1]) { + return 2; + } + if (check_pos.x <= mid_point.x && check_pos.y >= mid_point.y && check_pos.z <= mid_point.z && child_open[2]) { + return 3; + } + if (check_pos.x >= mid_point.x && check_pos.y >= mid_point.y && check_pos.z <= mid_point.z && child_open[3]) { + return 4; + } + if (check_pos.x <= mid_point.x && check_pos.y <= mid_point.y && check_pos.z >= mid_point.z && child_open[4]) { + return 5; + } + if (check_pos.x >= mid_point.x && check_pos.y <= mid_point.y && check_pos.z >= mid_point.z && child_open[5]) { + return 6; + } + if (check_pos.x <= mid_point.x && check_pos.y >= mid_point.y && check_pos.z >= mid_point.z && child_open[6]) { + return 7; + } + if (check_pos.x >= mid_point.x && check_pos.y >= mid_point.y && check_pos.z >= mid_point.z && child_open[7]) { + return 8; + } + + return 0; // return to parent +} + struct Tracing { vec3 end_pos; uvec4 end_color; @@ -259,6 +323,210 @@ Tracing trace_ray(uint volume_start, vec3 starting_pos, vec3 start_direction, fl while (iteration_num < max_iterations) { iteration_num ++; + + uint compound_num = 0; + while (scene_info.infos[volume_index + 6 + max_num_lights + compound_num] != 0 && compound_num < max_num_compounds && iteration_num < max_iterations && !result.has_hit) { + //iteration_num ++; + uint compound_start = scene_info.infos[volume_index + 6 + max_num_lights + compound_num]; + uint oct_tree_index = compounds[compound_start + 8]; + uint compound_grid_size = compounds[compound_start]; + float compound_scale = uintBitsToFloat(compounds[compound_start + 1]); + vec3 compound_pos = vec3(uintBitsToFloat(compounds[compound_start + 5]), uintBitsToFloat(compounds[compound_start + 6]), uintBitsToFloat(compounds[compound_start + 7])); + // check if we hit the volume + float x_border = compound_pos.x + float((compound_grid_size) * uint(!x_pos)) * compound_scale; + float y_border = compound_pos.y + float((compound_grid_size) * uint(!y_pos)) * compound_scale; + float z_border = compound_pos.z + float((compound_grid_size) * uint(!z_pos)) * compound_scale; + + if (!x_null) { + x_factor = (x_border - pos.x) / direction.x; + } else { + x_factor = max_factor; + } + if (!y_null) { + y_factor = (y_border - pos.y) / direction.y; + } else { + y_factor = max_factor; + } + if (!z_null) { + z_factor = (z_border - pos.z) / direction.z; + } else { + z_factor = max_factor; + } + + vec3 intersection_pos = pos; + bool is_x_hit = false; + bool is_y_hit = false; + bool is_z_hit = false; + bool hit_inside = false; + if ((compound_pos.x <= intersection_pos.x && intersection_pos.x <= compound_pos.x + float(compound_grid_size) * compound_scale) && + (compound_pos.y <= intersection_pos.y && intersection_pos.y <= compound_pos.y + float(compound_grid_size) * compound_scale) && + (compound_pos.z <= intersection_pos.z && intersection_pos.z <= compound_pos.z + float(compound_grid_size) * compound_scale)){ + hit_inside = true; + } else { + vec3 intersection_pos_x = pos + x_factor * direction; + vec3 intersection_pos_y = pos + y_factor * direction; + vec3 intersection_pos_z = pos + z_factor * direction; + if ((compound_pos.x <= intersection_pos_x.x && intersection_pos_x.x <= compound_pos.x + float(compound_grid_size) * compound_scale) && + (compound_pos.y <= intersection_pos_x.y && intersection_pos_x.y <= compound_pos.y + float(compound_grid_size) * compound_scale) && + (compound_pos.z <= intersection_pos_x.z && intersection_pos_x.z <= compound_pos.z + float(compound_grid_size) * compound_scale) && x_factor > 0.0) { + hit_inside = true; + is_x_hit = true; + intersection_pos = intersection_pos_x; + } + + if ((compound_pos.x <= intersection_pos_y.x && intersection_pos_y.x <= compound_pos.x + float(compound_grid_size) * compound_scale) && + (compound_pos.y <= intersection_pos_y.y && intersection_pos_y.y <= compound_pos.y + float(compound_grid_size) * compound_scale) && + (compound_pos.z <= intersection_pos_y.z && intersection_pos_y.z <= compound_pos.z + float(compound_grid_size) * compound_scale) && y_factor > 0.0 && (y_factor < x_factor || !is_x_hit)) { + hit_inside = true; + is_y_hit = true; + intersection_pos = intersection_pos_y; + } + + if ((compound_pos.x <= intersection_pos_z.x && intersection_pos_z.x <= compound_pos.x + float(compound_grid_size) * compound_scale) && + (compound_pos.y <= intersection_pos_z.y && intersection_pos_z.y <= compound_pos.y + float(compound_grid_size) * compound_scale) && + (compound_pos.z <= intersection_pos_z.z && intersection_pos_z.z <= compound_pos.z + float(compound_grid_size) * compound_scale) && z_factor > 0.0 && (z_factor < x_factor || !is_x_hit) && (z_factor < y_factor || !is_y_hit)) { + hit_inside = true; + is_z_hit = true; + intersection_pos = intersection_pos_z; + } + } + + // check that either the hit is in range or we are inside of the compound from the start + if (hit_inside) { + vec3 oct_tree_pos = vec3(compound_pos); + uint current_size = compound_grid_size; + vec3 mid_point = oct_tree_pos + float(current_size / 2) * vec3(compound_scale, compound_scale, compound_scale); + bool children_open[8] = {true, true, true, true, true, true, true, true}; + uint oct_tree_address = oct_tree_index; + // iterate through the oct_tree + uint check_it = 0; + uint prev_child = 0; + uint prev_prev_child = 0; + + uvec3 grid_pos = uvec3(0, 0, 0); + uvec3 parent_pos = uvec3(0, 0, 0); + + bool has_moved = false; + while (!result.has_hit && check_it < 60) { + // failsafe to get out in case has_moved runs into an accuracy issue + check_it ++; + oct_tree_pos = vec3(grid_pos) * compound_scale + compound_pos; + mid_point = oct_tree_pos + (float(current_size / 2) * vec3(compound_scale, compound_scale, compound_scale)); + + uint child_index = next_oct_tree_child(mid_point, intersection_pos, children_open); + if (child_index == 0) { + // go up to parent + // if parent is 0 abort, as we have reached the root node again and try to exit it + if (oct_tree_mem[oct_tree_address] == 0) { + break; + } + for (int i=0; i < 8; i++) { + children_open[i] = true; + } + uint parent_index = oct_tree_mem[oct_tree_address]; + // check which child we came from + child_index = 1 * uint(oct_tree_address == oct_tree_mem[parent_index + 1]) + 2 * uint(oct_tree_address == oct_tree_mem[parent_index + 2]) + 3 * uint(oct_tree_address == oct_tree_mem[parent_index + 3]) + 4 * uint(oct_tree_address == oct_tree_mem[parent_index + 4]) + 5 * uint(oct_tree_address == oct_tree_mem[parent_index + 5]) + 6 * uint(oct_tree_address == oct_tree_mem[parent_index + 6]) + 7 * uint(oct_tree_address == oct_tree_mem[parent_index + 7]) + 8 * uint(oct_tree_address == oct_tree_mem[parent_index + 8]); + // mark as done to avoid reinvestigating, since intersection_pos is on its edge + children_open[child_index - 1] = false; + if (!has_moved) { + for (int i=0; i < child_index; i++) { + children_open[i] = false; + } + } + prev_prev_child = prev_child; + prev_child = oct_tree_address; + + uvec3 back_vec = parent_child_vec(current_size, child_index); + grid_pos -= parent_child_vec(current_size, child_index); + current_size *= 2; + oct_tree_address = parent_index; + // todo remove once parent is implemented + //break; + } else { + // go down into child + if (current_size == 2) { + // check block if hit break + if (oct_tree_mem[oct_tree_address + child_index] != 0) { + result.has_hit = true; + result.end_color = uvec4(255, 0, 0, 32); + break; + } + } else { + // check if the child has content, else skip to next child of current parent + uint x = oct_tree_mem[oct_tree_address + child_index]; + if (oct_tree_mem[x] != 0) { + // change base address and position to child + current_size /= 2; + oct_tree_address = x; + grid_pos += parent_child_vec(current_size, child_index); + for (int i=0; i < 8; i++) { + children_open[i] = true; + } + continue; + } + } + children_open[child_index - 1] = false; + + // we did not go deeper or had a hit, so intersection pos needs to be updated + // new intersection pos calc + vec3 offset = vec3(parent_child_vec(current_size / 2, child_index)) * compound_scale; + vec3 low = oct_tree_pos + offset; + float x_border = low.x + float((compound_scale * current_size / 2) * uint(x_pos)); + float y_border = low.y + float((compound_scale * current_size / 2) * uint(y_pos)); + float z_border = low.z + float((compound_scale * current_size / 2) * uint(z_pos)); + + if (!x_null) { + x_factor = (x_border - pos.x) / direction.x; + } else { + x_factor = max_factor; + } + if (!y_null) { + y_factor = (y_border - pos.y) / direction.y; + } else { + y_factor = max_factor; + } + if (!z_null) { + z_factor = (z_border - pos.z) / direction.z; + } else { + z_factor = max_factor; + } + float smallest_factor = min(min(x_factor, y_factor), z_factor); + + has_moved = length(intersection_pos - (pos + smallest_factor * direction)) > 0.00001; + //has_moved = intersection_pos != (pos + smallest_factor * direction); + intersection_pos = pos + smallest_factor * direction; + } + } + + uint hit_facing = uint(is_x_hit) * (2 + uint(x_pos)) + uint(is_y_hit) * (4 + uint(y_pos)) + uint(is_z_hit && !z_pos); + //result.has_hit = true; + if (!has_moved) { + //result.has_hit = true; + } + if (!((compound_pos.x <= intersection_pos.x && intersection_pos.x <= compound_pos.x + float(compound_grid_size) * compound_scale) && + (compound_pos.y <= intersection_pos.y && intersection_pos.y <= compound_pos.y + float(compound_grid_size) * compound_scale) && + (compound_pos.z <= intersection_pos.z && intersection_pos.z <= compound_pos.z + float(compound_grid_size) * compound_scale))) { + //result.has_hit = true; + } + + if (!((compound_pos.x <= oct_tree_pos.x && oct_tree_pos.x <= compound_pos.x + float(compound_grid_size) * compound_scale) && + (compound_pos.y <= oct_tree_pos.y && oct_tree_pos.y <= compound_pos.y + float(compound_grid_size) * compound_scale) && + (compound_pos.z <= oct_tree_pos.z && oct_tree_pos.z <= compound_pos.z + float(compound_grid_size) * compound_scale))) { + //result.has_hit = true; + } + result.end_pos = intersection_pos; + result.end_facing = hit_facing; + result.end_volume = volume_index; + result.end_direction = direction; + } + + compound_num += 1; + } + + if (result.has_hit) { + break; + } + float x_border = volume_pos_x + float((scene_info.infos[volume_index + 3]) * uint(x_pos)) * volume_scale - 0.5 * volume_scale; float y_border = volume_pos_y + float((scene_info.infos[volume_index + 4]) * uint(y_pos)) * volume_scale - 0.5 * volume_scale; float z_border = volume_pos_z + float((scene_info.infos[volume_index + 5]) * uint(z_pos)) * volume_scale - 0.5 * volume_scale; @@ -267,12 +535,18 @@ Tracing trace_ray(uint volume_start, vec3 starting_pos, vec3 start_direction, fl if (!x_null) { x_factor = (x_border - pos.x) / direction.x; + } else { + x_factor = max_factor; } if (!y_null) { y_factor = (y_border - pos.y) / direction.y; + } else { + y_factor = max_factor; } if (!z_null) { z_factor = (z_border - pos.z) / direction.z; + } else { + z_factor = max_factor; } if ((x_factor >= max_factor) && (y_factor >= max_factor) && (z_factor >= max_factor)) { @@ -515,6 +789,7 @@ void main() { float opacity = float(color_roughness.w) / 255.0; vec3 color_seen_through; if (t.has_hit) { + //color_seen_through = vec3(float(t.end_color.x) / 255.0, float(t.end_color.y) / 255.0, float(t.end_color.z) / 255.0); color_seen_through = diffuse_tracing(t.end_volume, t.end_raster, t.end_pos, t.end_facing) * orig_color_sample * t.color_mul; color_seen_through = add_reflection(t.end_direction, t.end_facing, t.end_volume, t.end_pos, t.end_color, color_seen_through); } @@ -525,6 +800,8 @@ void main() { color_direct = add_reflection(normalize(clamped_pos - ubo.camera_pos), facing, fragVolumeStart, clamped_pos, color_roughness, color_direct); color_sum = opacity * color_direct + (1.0 - opacity) * color_seen_through; + + //color_sum = color_seen_through; } else { color_sum = diffuse_tracing(fragVolumeStart, clamped_raster_pos, clamped_pos, facing); diff --git a/src/app_data.rs b/src/app_data.rs index bfacaf4..2bfad28 100644 --- a/src/app_data.rs +++ b/src/app_data.rs @@ -99,6 +99,7 @@ pub struct AppData { pub compute_task_oct_tree_nodes: u64, // values passed to shader pub num_lights_per_volume: u32, + pub num_compound_per_volume: u32, pub min_light_weight: f32, pub max_iterations_per_light: u32, pub diffuse_raster_steps: u32, diff --git a/src/buffer.rs b/src/buffer.rs index c2b7572..9326b71 100644 --- a/src/buffer.rs +++ b/src/buffer.rs @@ -212,7 +212,7 @@ pub unsafe fn create_descriptor_set_layout( .binding(3) .descriptor_type(vk::DescriptorType::STORAGE_BUFFER) .descriptor_count(1) - .stage_flags(vk::ShaderStageFlags::COMPUTE); + .stage_flags(vk::ShaderStageFlags::COMPUTE | vk::ShaderStageFlags::FRAGMENT); let storage_binding_compute_out_color = vk::DescriptorSetLayoutBinding::builder() .binding(4) diff --git a/src/command_buffer.rs b/src/command_buffer.rs index 7b6289b..ae41ae1 100644 --- a/src/command_buffer.rs +++ b/src/command_buffer.rs @@ -85,14 +85,6 @@ pub unsafe fn create_command_buffers(device: &Device, data: &mut app_data::AppDa .size(vk::WHOLE_SIZE as u64) .build(); - device.cmd_pipeline_barrier(*command_buffer, - vk::PipelineStageFlags::COMPUTE_SHADER, - vk::PipelineStageFlags::VERTEX_INPUT, - vk::DependencyFlags::DEVICE_GROUP, - &[] as &[vk::MemoryBarrier], - &[buffer_memory_barrier_index, buffer_memory_barrier_vertex], - &[] as &[vk::ImageMemoryBarrier]); - // compute storage barrier let buffer_memory_barrier_color = vk::BufferMemoryBarrier::builder() .buffer(data.compute_out_storage_buffers_color[i]) @@ -155,7 +147,7 @@ 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_one_size / 2) 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]) @@ -191,7 +183,7 @@ 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_one_size / 2) 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]) @@ -227,17 +219,10 @@ 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_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(); + device.cmd_dispatch(*command_buffer, (data.compute_task_oct_tree_nodes as f64 / 16.0).ceil() as u32, 1, 1); let buffer_memory_barrier_out = vk::BufferMemoryBarrier::builder() - .buffer(data.compute_out_storage_buffers_size_two[i]) + .buffer(data.compute_out_storage_buffers_oct_tree[i]) .src_access_mask(vk::AccessFlags::SHADER_WRITE) .dst_access_mask(vk::AccessFlags::SHADER_READ) .size(vk::WHOLE_SIZE as u64) @@ -245,10 +230,18 @@ 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::COMPUTE_SHADER, + vk::PipelineStageFlags::FRAGMENT_SHADER, vk::DependencyFlags::DEVICE_GROUP, &[] as &[vk::MemoryBarrier], - &[buffer_memory_barrier_in, buffer_memory_barrier_out], + &[buffer_memory_barrier_out], + &[] as &[vk::ImageMemoryBarrier]); + + device.cmd_pipeline_barrier(*command_buffer, + vk::PipelineStageFlags::COMPUTE_SHADER, + vk::PipelineStageFlags::VERTEX_INPUT, + vk::DependencyFlags::DEVICE_GROUP, + &[] as &[vk::MemoryBarrier], + &[buffer_memory_barrier_index, buffer_memory_barrier_vertex], &[] as &[vk::ImageMemoryBarrier]); } // start render pass diff --git a/src/main.rs b/src/main.rs index d5905b4..9c525e7 100644 --- a/src/main.rs +++ b/src/main.rs @@ -195,6 +195,7 @@ impl App { let mut data = app_data::AppData::default(); data.use_geometry_shader = false; data.num_lights_per_volume = 5; + data.num_compound_per_volume = 5; data.min_light_weight = 0.0001; data.max_iterations_per_light = 20; data.diffuse_raster_steps = 0; @@ -281,7 +282,7 @@ impl App { self.update_uniform_buffer(image_index)?; let time = self.appstart.elapsed().as_secs_f32() / 1.0; - self.scene_handler.point_lights[0].borrow_mut().set_pos(cgmath::vec3((10.0 + 64.0) as f32 + time.sin() * 2.0, (10.0 + 64.0) as f32 + time.cos() * 2.0, 11.0)); + //self.scene_handler.point_lights[0].borrow_mut().set_pos(cgmath::vec3((10.0 + 64.0) as f32 + time.sin() * 2.0, (10.0 + 64.0) as f32 + time.cos() * 2.0, 11.0)); self.synchronized = 0; if self.synchronized < MAX_FRAMES_IN_FLIGHT { diff --git a/src/scene/empty_volume.rs b/src/scene/empty_volume.rs index 36e3a1f..00ee843 100644 --- a/src/scene/empty_volume.rs +++ b/src/scene/empty_volume.rs @@ -13,6 +13,7 @@ use crate::scene::oct_tree::OctTree; use super::memorizable::Memorizable; use super::light::LightSource; use super::light::PointLight; +use super::volumetrics::ShapeComposition; use super::AppData; use super::LightsIter; use super::Scene; @@ -1063,10 +1064,10 @@ impl EmptyVolume { let mut out_index = vec![]; for index in 0..weighted_indices.len() { - out_index.push(weighted_indices[weighted_indices.len() - (index + 1)].1 as u32); if out_index.len() == light_number as usize { break; } + out_index.push(weighted_indices[weighted_indices.len() - (index + 1)].1 as u32); } while out_index.len() < light_number as usize { out_index.push(0); @@ -1074,6 +1075,31 @@ impl EmptyVolume { out_index } + pub fn select_compounds(&self, compounds: &Vec<Rc<RefCell<ShapeComposition>>>, compound_number: u32) -> Vec<u32> { + let mut weighted_indices = vec![]; + for compound in compounds { + let bbox_low = compound.borrow().bbox_low; + let bbox_high = compound.borrow().bbox_high; + let diag = bbox_high - bbox_low; + if (self.real_position.x < bbox_high.x || self.real_position.y < bbox_high.y || self.real_position.z < bbox_high.z) && (bbox_low.x < self.real_position.x + self.size_x as f32 || bbox_low.y < self.real_position.y + self.size_y as f32 || bbox_low.z < self.real_position.z + self.size_z as f32) { + let le = diag.dot(diag); + weighted_indices.push((le, compound.borrow().get_memory_start())); + } + } + weighted_indices.sort_by(|a, b| a.0.partial_cmp(&b.0).unwrap()); + let mut out_index = vec![]; + for index in 0..weighted_indices.len() { + if out_index.len() == compound_number as usize { + break; + } + out_index.push(weighted_indices[weighted_indices.len() - (index + 1)].1 as u32); + } + while out_index.len() < compound_number as usize { + out_index.push(0); + } + out_index + } + pub fn combine_results(first: &Rc<RefCell<OctTree<Cube>>>,first_neighbors: &Rc<OctTree<Rc<RefCell<EmptyVolume>>>>, second: &Rc<RefCell<OctTree<Cube>>>, second_neighbors: &Rc<OctTree<Rc<RefCell<EmptyVolume>>>>, facing: vertex::Facing) { let mut first_start; let mut second_start; @@ -1261,6 +1287,7 @@ impl Memorizable for EmptyVolume { mem_size += 12; //color/roughness buffer sizes, 2 values each mem_size += 12; //neighbor buffer sizes, 2 values each mem_size += 1; //scale of the volume, 1 float + mem_size += data.num_compound_per_volume; // compound references // this covers full color and roughness mem_size += (self.color_top.len() as u32).max(1); @@ -1296,12 +1323,20 @@ impl Memorizable for EmptyVolume { mem_index += 1; v[mem_index] = self.size_z as u32; mem_index += 1; - //Todo: insert lights + //insert lights let selected_lights = self.select_lights(scene.get_light_iter(), data.num_lights_per_volume, data.min_light_weight); for light in selected_lights { v[mem_index] = light; mem_index += 1; } + + // compound references + let selected_compounds = self.select_compounds(&scene.volumetrics, data.num_compound_per_volume); + for compound in selected_compounds { + v[mem_index] = compound; + mem_index += 1; + } + //color/roughness buffer sizes, 2 values each if self.color_top.len() > 1 { v[mem_index] = self.size_x as u32; diff --git a/src/scene/generators.rs b/src/scene/generators.rs index c628790..a1a4a89 100644 --- a/src/scene/generators.rs +++ b/src/scene/generators.rs @@ -57,7 +57,7 @@ pub fn generate_test_scene(scene: &mut Scene, data: &mut AppData) -> Result<(Poi let shade = (rng.gen_range(0..25) as f32) / 100.0; let cube = Cube { pos: vec3(10.0, 10.0, 10.0), - color: vec3(0.0, 0.0, 0.9), + color: vec3(0.9, 0.9, 0.9), tex_coord: vec2(0.0, 0.0), transparent: true, roughness: 32, @@ -66,7 +66,7 @@ pub fn generate_test_scene(scene: &mut Scene, data: &mut AppData) -> Result<(Poi let cube = Cube { pos: vec3(10.0, 10.0, 9.0), - color: vec3(0.0, 0.0, 0.9), + color: vec3(0.9, 0.9, 0.9), tex_coord: vec2(0.0, 0.0), transparent: true, roughness: 32, @@ -93,7 +93,7 @@ pub fn generate_test_scene(scene: &mut Scene, data: &mut AppData) -> Result<(Poi oct_tree2.set_cube(cube.clone()); scene.point_lights.push(Rc::new(RefCell::new(PointLight::init(vec3(11.0 + grid_size as f32, 11.0 + grid_size as f32, 11.0) * scale, vec3(2.0, 2.0, 2.0))))); - scene.point_lights.push(Rc::new(RefCell::new(PointLight::init(vec3(9.0 + grid_size as f32, 9.0 + grid_size as f32, 11.0) * scale, vec3(0.5, 0.5, 0.5))))); + //scene.point_lights.push(Rc::new(RefCell::new(PointLight::init(vec3(9.0 + grid_size as f32, 9.0 + grid_size as f32, 11.0) * scale, vec3(0.5, 0.5, 0.5))))); scene.directional_lights.push(Rc::new(RefCell::new(DirectionalLight::init(vec3(1.0, 1.0, -1.0), vec3(0.1, 0.1, 0.1))))); let cube = Cuboid { @@ -112,13 +112,16 @@ pub fn generate_test_scene(scene: &mut Scene, data: &mut AppData) -> Result<(Poi size: Vector3 {x: 0.5, y: 0.5, z: 0.5} * scale }; let index = scene.sized_vertices.len(); - cube.draw(&data.topology, index, scene); + //cube.draw(&data.topology, index, scene); let tree_ref_one = Rc::new(RefCell::new(oct_tree1.clone())); let tree_ref_two = Rc::new(RefCell::new(oct_tree2.clone())); scene.oct_trees = vec![vec![vec![tree_ref_two.clone(), tree_ref_two.clone(), tree_ref_two.clone()], vec![tree_ref_two.clone(), tree_ref_one.clone(), tree_ref_two.clone()], vec![tree_ref_two.clone(), tree_ref_two.clone(), tree_ref_two.clone()]], vec![vec![tree_ref_two.clone(), tree_ref_two.clone(), tree_ref_two.clone()], vec![tree_ref_two.clone(), tree_ref_one.clone(), tree_ref_two.clone()], vec![tree_ref_two.clone(), tree_ref_two.clone(), tree_ref_two.clone()]]]; + //scene.oct_trees = vec![vec![vec![tree_ref_two.clone(), tree_ref_two.clone(), tree_ref_two.clone()], vec![tree_ref_two.clone(), tree_ref_one.clone(), tree_ref_two.clone()], vec![tree_ref_two.clone(), tree_ref_two.clone(), tree_ref_two.clone()]]]; 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: 5.0, z: 5.0 },Vector3 { x: 0, y: 0, z: 255 }, 64, false)))); + comp.included_shapes.push(Rc::new(RefCell::new(Sphere::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 }, 2.0, Vector3 { x: 0, y: 255, z: 0 }, 64, false)))); comp.included_shapes.push(Rc::new(RefCell::new(Sphere::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 }, 2.5, Vector3 { x: 255, y: 0, z: 0 }, 64, false)))); comp.excluded_shapes.push(Rc::new(RefCell::new(Sphere::new(Vector3 { x: 5.0 + grid_size as f32, y: 5.0 + grid_size as f32, z: 11.5 }, Vector3 { x: 0.0, y: 0.0, z: 0.0 }, 1.5, Vector3 { x: 0, y: 255, z: 0 }, 64, false)))); diff --git a/src/scene/mod.rs b/src/scene/mod.rs index 924bed0..395271d 100644 --- a/src/scene/mod.rs +++ b/src/scene/mod.rs @@ -181,49 +181,25 @@ impl Scene { pub fn update_memory(&mut self, data: &mut AppData, reuse_memory: bool) { // reuse_memory controls whether a fresh data vector is created or the existing one is used if it is the right size - let mut memory_index = 6; + let mut memory_index = 7; // 0 - location for the maximum number of lights referenced per chunk (also will be the invalid memory allocation for pointing to a nonexistant neighbor) // 1 - location for the max iterations per light // 2 - diffuse raster samples (2*n + 1) * (2*n + 1) so as to always have at least the central fragment covered // 3 - diffuse raster size // 4 - max recursive rays // 5 - diffuse rays per hit + // 6 - maximum number of compounds per light for memorizable in &self.memorizables { memorizable.borrow_mut().set_memory_start(memory_index); memory_index += memorizable.borrow_mut().get_buffer_mem_size(data) as usize; } - //println!("Memory size is {} kB, max indes is {}", memory_index * 32 / 8 /1024 + 1, memory_index); - let mut volume_vec; - let needs_overwrite; - if !reuse_memory || memory_index != self.rt_memory.len() { - volume_vec = vec![data.num_lights_per_volume; memory_index]; - needs_overwrite = true; - } else { - needs_overwrite = false; - volume_vec = self.rt_memory.clone(); - } - volume_vec[1] = data.max_iterations_per_light; - volume_vec[2] = data.diffuse_raster_steps; - volume_vec[3] = u32::from_ne_bytes(data.diffuse_raster_size.to_ne_bytes()); - volume_vec[4] = data.max_recursive_rays; - volume_vec[5] = data.diffuse_rays_per_hit; - - for memorizable in &self.memorizables { - if needs_overwrite || memorizable.borrow().is_dirty() { - volume_vec = memorizable.borrow_mut().insert_into_memory(volume_vec, data, &self); - } - } - - self.rt_memory = volume_vec; - data.scene_rt_memory_size = (self.rt_memory.len() * 4) as u64; // size of the needed buffer size in bytes - - let mut data_len = 0; + let mut compound_data_len = 1; for compound in &self.volumetrics { - compound.borrow_mut().set_memory_start(data_len); - data_len += compound.borrow().get_compound_buffer_mem_size(data) as usize; + compound.borrow_mut().set_memory_start(compound_data_len); + compound_data_len += compound.borrow().get_compound_buffer_mem_size(data) as usize; } - let mut volumetrics_memory = vec![0; data_len]; + let mut volumetrics_memory = vec![compound_data_len as u32; compound_data_len]; let mut compute_task_one_size = 0; let mut compute_task_one_out_size = 0; @@ -238,13 +214,40 @@ impl Scene { compute_task_one_out_size += compound.borrow().size.pow(3) as usize; } + //println!("Memory size is {} kB, max indes is {}", memory_index * 32 / 8 /1024 + 1, memory_index); + let mut volume_vec; + let needs_overwrite; + if !reuse_memory || memory_index != self.rt_memory.len() { + volume_vec = vec![data.num_lights_per_volume; memory_index]; + needs_overwrite = true; + } else { + needs_overwrite = false; + volume_vec = self.rt_memory.clone(); + } + volume_vec[0] = data.num_lights_per_volume; + volume_vec[1] = data.max_iterations_per_light; + volume_vec[2] = data.diffuse_raster_steps; + volume_vec[3] = u32::from_ne_bytes(data.diffuse_raster_size.to_ne_bytes()); + volume_vec[4] = data.max_recursive_rays; + volume_vec[5] = data.diffuse_rays_per_hit; + volume_vec[6] = data.num_compound_per_volume; + + for memorizable in &self.memorizables { + if needs_overwrite || memorizable.borrow().is_dirty() { + volume_vec = memorizable.borrow_mut().insert_into_memory(volume_vec, data, &self); + } + } + + self.rt_memory = volume_vec; + data.scene_rt_memory_size = (self.rt_memory.len() * 4) as u64; // size of the needed buffer size in bytes + self.volumetrics_memory = volumetrics_memory; data.scene_rt_volumetric_size = (self.volumetrics_memory.len() * 4) as u64; // size of the needed buffer size in bytes 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; + 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 8797cc3..cf72f67 100644 --- a/src/scene/volumetrics/mod.rs +++ b/src/scene/volumetrics/mod.rs @@ -37,11 +37,13 @@ pub struct ShapeComposition { pub included_shapes: Vec<Rc<RefCell<dyn Volumetrics>>>, pub excluded_shapes: Vec<Rc<RefCell<dyn Volumetrics>>>, dirty: bool, + pub bbox_low: Vector3<f32>, + pub bbox_high: Vector3<f32>, } impl ShapeComposition { pub fn new(size: u32) -> Self { - Self { memory_start: 0, target_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, bbox_low: Vector3 { x: 0.0, y: 0.0, z: 0.0 }, bbox_high: Vector3 { x: 0.0, y: 0.0, z: 0.0 } } } } @@ -61,7 +63,7 @@ impl CompoundMemorizable for ShapeComposition { impl Memorizable for ShapeComposition { fn get_buffer_mem_size(&self, data: &AppData) -> u32 { - //size, scale, memory_end, num_included, num_excluded, pos, wrapping address, included_address, excluded_address + //size, scale, memory_end, num_included, num_excluded, pos, target address, included_address, excluded_address 1 + 1 + 1 + 1 + 1 + 3 + 1 + self.included_shapes.len() as u32 + self.excluded_shapes.len() as u32 } @@ -118,6 +120,8 @@ impl Memorizable for ShapeComposition { } let bbox_high_pos_ind = bbox_high - bbox_low; + self.bbox_low = bbox_low; + self.bbox_high = bbox_high; let scale = bbox_high_pos_ind.x.max(bbox_high_pos_ind.y.max(bbox_high_pos_ind.z)) / (self.size as f32); v[self.memory_start + 1] = u32::from_ne_bytes(scale.to_ne_bytes()); @@ -127,7 +131,7 @@ impl Memorizable for ShapeComposition { v[self.memory_start + 5] = u32::from_ne_bytes(bbox_low.x.to_ne_bytes()); v[self.memory_start + 6] = u32::from_ne_bytes(bbox_low.y.to_ne_bytes()); v[self.memory_start + 7] = u32::from_ne_bytes(bbox_low.z.to_ne_bytes()); - v[self.memory_start + 8] = 0; //TODO add wrapping reference + v[self.memory_start + 8] = self.target_memory_start as u32; self.prev_memory_size = self.get_compound_buffer_mem_size(data); self.dirty = false; @@ -153,7 +157,6 @@ impl ShapeComposition { add_size *= 8; size /= 2; } - nodes } From 8375885a403493495d8eaa5198438c8948bc4ecd Mon Sep 17 00:00:00 2001 From: zomseffen <steffen@tom.bi> Date: Wed, 28 May 2025 15:04:58 +0200 Subject: [PATCH 3/5] volumetric in quad fragf finished for now. --- shaders/compiled/frag_rt_quad.spv | Bin 76768 -> 74304 bytes shaders/rt_quad.frag | 88 +++++++++++++++++------------- src/scene/generators.rs | 6 +- 3 files changed, 52 insertions(+), 42 deletions(-) diff --git a/shaders/compiled/frag_rt_quad.spv b/shaders/compiled/frag_rt_quad.spv index a738849b8da732710694744fb2f76179284f1f06..ff99d3f5c66a518a3a53221f0ae536d218268665 100644 GIT binary patch literal 74304 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 literal 76768 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Ñ_UrT;zjr*Igv0M9Fui>`$cV0_=X^s2)uCcqG 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 diff --git a/shaders/rt_quad.frag b/shaders/rt_quad.frag index d43de76..c59b4e4 100644 --- a/shaders/rt_quad.frag +++ b/shaders/rt_quad.frag @@ -337,6 +337,9 @@ Tracing trace_ray(uint volume_start, vec3 starting_pos, vec3 start_direction, fl float y_border = compound_pos.y + float((compound_grid_size) * uint(!y_pos)) * compound_scale; float z_border = compound_pos.z + float((compound_grid_size) * uint(!z_pos)) * compound_scale; + // go over the borders by this amount + float overstep = 0.00001 / length(direction); + if (!x_null) { x_factor = (x_border - pos.x) / direction.x; } else { @@ -352,6 +355,9 @@ Tracing trace_ray(uint volume_start, vec3 starting_pos, vec3 start_direction, fl } else { z_factor = max_factor; } + x_factor += overstep; + y_factor += overstep; + z_factor += overstep; vec3 intersection_pos = pos; bool is_x_hit = false; @@ -361,14 +367,14 @@ Tracing trace_ray(uint volume_start, vec3 starting_pos, vec3 start_direction, fl if ((compound_pos.x <= intersection_pos.x && intersection_pos.x <= compound_pos.x + float(compound_grid_size) * compound_scale) && (compound_pos.y <= intersection_pos.y && intersection_pos.y <= compound_pos.y + float(compound_grid_size) * compound_scale) && (compound_pos.z <= intersection_pos.z && intersection_pos.z <= compound_pos.z + float(compound_grid_size) * compound_scale)){ - hit_inside = true; + //hit_inside = true; } else { vec3 intersection_pos_x = pos + x_factor * direction; vec3 intersection_pos_y = pos + y_factor * direction; vec3 intersection_pos_z = pos + z_factor * direction; if ((compound_pos.x <= intersection_pos_x.x && intersection_pos_x.x <= compound_pos.x + float(compound_grid_size) * compound_scale) && (compound_pos.y <= intersection_pos_x.y && intersection_pos_x.y <= compound_pos.y + float(compound_grid_size) * compound_scale) && - (compound_pos.z <= intersection_pos_x.z && intersection_pos_x.z <= compound_pos.z + float(compound_grid_size) * compound_scale) && x_factor > 0.0) { + (compound_pos.z <= intersection_pos_x.z && intersection_pos_x.z <= compound_pos.z + float(compound_grid_size) * compound_scale) && x_factor > 0.0 && x_factor <= max_factor) { hit_inside = true; is_x_hit = true; intersection_pos = intersection_pos_x; @@ -376,7 +382,7 @@ Tracing trace_ray(uint volume_start, vec3 starting_pos, vec3 start_direction, fl if ((compound_pos.x <= intersection_pos_y.x && intersection_pos_y.x <= compound_pos.x + float(compound_grid_size) * compound_scale) && (compound_pos.y <= intersection_pos_y.y && intersection_pos_y.y <= compound_pos.y + float(compound_grid_size) * compound_scale) && - (compound_pos.z <= intersection_pos_y.z && intersection_pos_y.z <= compound_pos.z + float(compound_grid_size) * compound_scale) && y_factor > 0.0 && (y_factor < x_factor || !is_x_hit)) { + (compound_pos.z <= intersection_pos_y.z && intersection_pos_y.z <= compound_pos.z + float(compound_grid_size) * compound_scale) && y_factor > 0.0 && y_factor <= max_factor && (y_factor < x_factor || !is_x_hit)) { hit_inside = true; is_y_hit = true; intersection_pos = intersection_pos_y; @@ -384,7 +390,7 @@ Tracing trace_ray(uint volume_start, vec3 starting_pos, vec3 start_direction, fl if ((compound_pos.x <= intersection_pos_z.x && intersection_pos_z.x <= compound_pos.x + float(compound_grid_size) * compound_scale) && (compound_pos.y <= intersection_pos_z.y && intersection_pos_z.y <= compound_pos.y + float(compound_grid_size) * compound_scale) && - (compound_pos.z <= intersection_pos_z.z && intersection_pos_z.z <= compound_pos.z + float(compound_grid_size) * compound_scale) && z_factor > 0.0 && (z_factor < x_factor || !is_x_hit) && (z_factor < y_factor || !is_y_hit)) { + (compound_pos.z <= intersection_pos_z.z && intersection_pos_z.z <= compound_pos.z + float(compound_grid_size) * compound_scale) && z_factor > 0.0 && z_factor <= max_factor && (z_factor < x_factor || !is_x_hit) && (z_factor < y_factor || !is_y_hit)) { hit_inside = true; is_z_hit = true; intersection_pos = intersection_pos_z; @@ -400,6 +406,7 @@ Tracing trace_ray(uint volume_start, vec3 starting_pos, vec3 start_direction, fl uint oct_tree_address = oct_tree_index; // iterate through the oct_tree uint check_it = 0; + uint max_check_it = 60; uint prev_child = 0; uint prev_prev_child = 0; @@ -407,7 +414,7 @@ Tracing trace_ray(uint volume_start, vec3 starting_pos, vec3 start_direction, fl uvec3 parent_pos = uvec3(0, 0, 0); bool has_moved = false; - while (!result.has_hit && check_it < 60) { + while (!result.has_hit && check_it < max_check_it) { // failsafe to get out in case has_moved runs into an accuracy issue check_it ++; oct_tree_pos = vec3(grid_pos) * compound_scale + compound_pos; @@ -428,11 +435,6 @@ Tracing trace_ray(uint volume_start, vec3 starting_pos, vec3 start_direction, fl child_index = 1 * uint(oct_tree_address == oct_tree_mem[parent_index + 1]) + 2 * uint(oct_tree_address == oct_tree_mem[parent_index + 2]) + 3 * uint(oct_tree_address == oct_tree_mem[parent_index + 3]) + 4 * uint(oct_tree_address == oct_tree_mem[parent_index + 4]) + 5 * uint(oct_tree_address == oct_tree_mem[parent_index + 5]) + 6 * uint(oct_tree_address == oct_tree_mem[parent_index + 6]) + 7 * uint(oct_tree_address == oct_tree_mem[parent_index + 7]) + 8 * uint(oct_tree_address == oct_tree_mem[parent_index + 8]); // mark as done to avoid reinvestigating, since intersection_pos is on its edge children_open[child_index - 1] = false; - if (!has_moved) { - for (int i=0; i < child_index; i++) { - children_open[i] = false; - } - } prev_prev_child = prev_child; prev_child = oct_tree_address; @@ -440,15 +442,13 @@ Tracing trace_ray(uint volume_start, vec3 starting_pos, vec3 start_direction, fl grid_pos -= parent_child_vec(current_size, child_index); current_size *= 2; oct_tree_address = parent_index; - // todo remove once parent is implemented - //break; } else { // go down into child if (current_size == 2) { // check block if hit break if (oct_tree_mem[oct_tree_address + child_index] != 0) { result.has_hit = true; - result.end_color = uvec4(255, 0, 0, 32); + result.end_color = unpack_color(oct_tree_mem[oct_tree_address + child_index]); break; } } else { @@ -477,43 +477,57 @@ Tracing trace_ray(uint volume_start, vec3 starting_pos, vec3 start_direction, fl if (!x_null) { x_factor = (x_border - pos.x) / direction.x; + if (x_factor <= 0.0) { + x_factor = max_factor; + } } else { x_factor = max_factor; } if (!y_null) { y_factor = (y_border - pos.y) / direction.y; + if (y_factor <= 0.0) { + y_factor = max_factor; + } } else { y_factor = max_factor; } if (!z_null) { z_factor = (z_border - pos.z) / direction.z; + if (z_factor <= 0.0) { + z_factor = max_factor; + } } else { z_factor = max_factor; } float smallest_factor = min(min(x_factor, y_factor), z_factor); - has_moved = length(intersection_pos - (pos + smallest_factor * direction)) > 0.00001; - //has_moved = intersection_pos != (pos + smallest_factor * direction); + if (x_factor == smallest_factor) { + is_x_hit = true; + is_y_hit = false; + is_z_hit = false; + } + if (y_factor == smallest_factor) { + is_x_hit = false; + is_y_hit = true; + is_z_hit = false; + } + if (z_factor == smallest_factor) { + is_x_hit = false; + is_y_hit = false; + is_z_hit = true; + } + + // move a bit further to fully enter the next quadrant + smallest_factor += overstep; + + //has_moved = length(intersection_pos - (pos + smallest_factor * direction)) >= 0.00001; + has_moved = intersection_pos != (pos + smallest_factor * direction); intersection_pos = pos + smallest_factor * direction; } } uint hit_facing = uint(is_x_hit) * (2 + uint(x_pos)) + uint(is_y_hit) * (4 + uint(y_pos)) + uint(is_z_hit && !z_pos); //result.has_hit = true; - if (!has_moved) { - //result.has_hit = true; - } - if (!((compound_pos.x <= intersection_pos.x && intersection_pos.x <= compound_pos.x + float(compound_grid_size) * compound_scale) && - (compound_pos.y <= intersection_pos.y && intersection_pos.y <= compound_pos.y + float(compound_grid_size) * compound_scale) && - (compound_pos.z <= intersection_pos.z && intersection_pos.z <= compound_pos.z + float(compound_grid_size) * compound_scale))) { - //result.has_hit = true; - } - - if (!((compound_pos.x <= oct_tree_pos.x && oct_tree_pos.x <= compound_pos.x + float(compound_grid_size) * compound_scale) && - (compound_pos.y <= oct_tree_pos.y && oct_tree_pos.y <= compound_pos.y + float(compound_grid_size) * compound_scale) && - (compound_pos.z <= oct_tree_pos.z && oct_tree_pos.z <= compound_pos.z + float(compound_grid_size) * compound_scale))) { - //result.has_hit = true; - } result.end_pos = intersection_pos; result.end_facing = hit_facing; result.end_volume = volume_index; @@ -711,8 +725,7 @@ vec3 get_lighting_color(uint volume_start, vec3 starting_pos, vec4 orig_color_sa return color_sum; } -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); +vec3 diffuse_tracing(uint volume_start, uvec4 color_roughness, vec3 pos, uint f) { vec4 orig_color_sample = vec4(float(color_roughness.x) / 255.0, float(color_roughness.y) / 255.0, float(color_roughness.z) / 255.0, 1); vec3 normal = normal_for_facing(f); @@ -733,10 +746,6 @@ vec3 diffuse_tracing(uint volume_start, uvec2 raster_pos, vec3 pos, uint f) { return color_sum; } -vec3 diffuse_tracing(uint volume_start, vec2 raster_pos, vec3 pos, uint f) { - return diffuse_tracing(volume_start, uvec2(uint(floor(raster_pos.x)), uint(floor(raster_pos.y))), pos, f); -} - vec3 clamp_to_volume(uint volume_start, vec3 position) { float volume_pos_x = uintBitsToFloat(scene_info.infos[volume_start + 0]); float volume_pos_y = uintBitsToFloat(scene_info.infos[volume_start + 1]); @@ -766,7 +775,7 @@ vec3 add_reflection(vec3 view_vector, uint f, uint volume_start, vec3 pos, uvec4 vec3 reflection_direction = reflect_vector(view_vector, f); Tracing reflection_tracing = trace_ray(volume_start, pos, reflection_direction, pos_infinity, true); if (reflection_tracing.has_hit || reflection_tracing.has_transparent_hit) { - vec3 color_from_reflection = diffuse_tracing(reflection_tracing.end_volume, reflection_tracing.end_raster, reflection_tracing.end_pos, reflection_tracing.end_facing) * orig_color_sample; + vec3 color_from_reflection = diffuse_tracing(reflection_tracing.end_volume, reflection_tracing.end_color, reflection_tracing.end_pos, reflection_tracing.end_facing) * orig_color_sample; color_sum = color_sum * (1.0 - reflectivity) + color_from_reflection * reflectivity; } } @@ -783,14 +792,15 @@ void main() { uint orig_neighbor = sample_neighbor_from_scene_info(fragVolumeStart, clamped_raster_pos, facing); if (orig_neighbor != 0) { - vec3 color_direct = diffuse_tracing(fragVolumeStart, clamped_raster_pos, clamped_pos, facing); + vec3 color_direct = diffuse_tracing(fragVolumeStart, color_roughness, clamped_pos, facing); Tracing t = trace_ray(fragVolumeStart, ubo.camera_pos, clamped_pos - ubo.camera_pos, pos_infinity, false); float opacity = float(color_roughness.w) / 255.0; vec3 color_seen_through; if (t.has_hit) { //color_seen_through = vec3(float(t.end_color.x) / 255.0, float(t.end_color.y) / 255.0, float(t.end_color.z) / 255.0); - color_seen_through = diffuse_tracing(t.end_volume, t.end_raster, t.end_pos, t.end_facing) * orig_color_sample * t.color_mul; + + color_seen_through = diffuse_tracing(t.end_volume, t.end_color, t.end_pos, t.end_facing) * orig_color_sample * t.color_mul; color_seen_through = add_reflection(t.end_direction, t.end_facing, t.end_volume, t.end_pos, t.end_color, color_seen_through); } else { @@ -804,7 +814,7 @@ void main() { //color_sum = color_seen_through; } else { - color_sum = diffuse_tracing(fragVolumeStart, clamped_raster_pos, clamped_pos, facing); + color_sum = diffuse_tracing(fragVolumeStart, color_roughness, clamped_pos, facing); color_sum = add_reflection(normalize(clamped_pos - ubo.camera_pos), facing, fragVolumeStart, clamped_pos, color_roughness, color_sum); } diff --git a/src/scene/generators.rs b/src/scene/generators.rs index a1a4a89..eca7594 100644 --- a/src/scene/generators.rs +++ b/src/scene/generators.rs @@ -94,7 +94,7 @@ pub fn generate_test_scene(scene: &mut Scene, data: &mut AppData) -> Result<(Poi scene.point_lights.push(Rc::new(RefCell::new(PointLight::init(vec3(11.0 + grid_size as f32, 11.0 + grid_size as f32, 11.0) * scale, vec3(2.0, 2.0, 2.0))))); //scene.point_lights.push(Rc::new(RefCell::new(PointLight::init(vec3(9.0 + grid_size as f32, 9.0 + grid_size as f32, 11.0) * scale, vec3(0.5, 0.5, 0.5))))); - scene.directional_lights.push(Rc::new(RefCell::new(DirectionalLight::init(vec3(1.0, 1.0, -1.0), vec3(0.1, 0.1, 0.1))))); + //scene.directional_lights.push(Rc::new(RefCell::new(DirectionalLight::init(vec3(1.0, 1.0, -1.0), vec3(0.1, 0.1, 0.1))))); let cube = Cuboid { pos: vec3(11.0 + grid_size as f32, 11.0 + grid_size as f32, 11.0) * scale, @@ -116,8 +116,8 @@ pub fn generate_test_scene(scene: &mut Scene, data: &mut AppData) -> Result<(Poi let tree_ref_one = Rc::new(RefCell::new(oct_tree1.clone())); let tree_ref_two = Rc::new(RefCell::new(oct_tree2.clone())); - scene.oct_trees = vec![vec![vec![tree_ref_two.clone(), tree_ref_two.clone(), tree_ref_two.clone()], vec![tree_ref_two.clone(), tree_ref_one.clone(), tree_ref_two.clone()], vec![tree_ref_two.clone(), tree_ref_two.clone(), tree_ref_two.clone()]], vec![vec![tree_ref_two.clone(), tree_ref_two.clone(), tree_ref_two.clone()], vec![tree_ref_two.clone(), tree_ref_one.clone(), tree_ref_two.clone()], vec![tree_ref_two.clone(), tree_ref_two.clone(), tree_ref_two.clone()]]]; - //scene.oct_trees = vec![vec![vec![tree_ref_two.clone(), tree_ref_two.clone(), tree_ref_two.clone()], vec![tree_ref_two.clone(), tree_ref_one.clone(), tree_ref_two.clone()], vec![tree_ref_two.clone(), tree_ref_two.clone(), tree_ref_two.clone()]]]; + //scene.oct_trees = vec![vec![vec![tree_ref_two.clone(), tree_ref_two.clone(), tree_ref_two.clone()], vec![tree_ref_two.clone(), tree_ref_one.clone(), tree_ref_two.clone()], vec![tree_ref_two.clone(), tree_ref_two.clone(), tree_ref_two.clone()]], vec![vec![tree_ref_two.clone(), tree_ref_two.clone(), tree_ref_two.clone()], vec![tree_ref_two.clone(), tree_ref_one.clone(), tree_ref_two.clone()], vec![tree_ref_two.clone(), tree_ref_two.clone(), tree_ref_two.clone()]]]; + scene.oct_trees = vec![vec![vec![tree_ref_two.clone(), tree_ref_two.clone(), tree_ref_two.clone()], vec![tree_ref_two.clone(), tree_ref_one.clone(), tree_ref_two.clone()], vec![tree_ref_two.clone(), tree_ref_two.clone(), tree_ref_two.clone()]]]; 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: 5.0, z: 5.0 },Vector3 { x: 0, y: 0, z: 255 }, 64, false)))); From fa6495e4cc0296b217dd9908c3257c7b5df01782 Mon Sep 17 00:00:00 2001 From: zomseffen <steffen@tom.bi> Date: Wed, 4 Jun 2025 15:50:43 +0200 Subject: [PATCH 4/5] build shaders with placeholders --- build.rs | 28 +- shaders/compiled/frag_rt_quad.spv | Bin 74304 -> 75396 bytes shaders/rt_lib.frag | 794 ++++++++++++++++++++++++++++++ shaders/rt_quad.frag | 25 +- shaders/rt_quad_placeholder.frag | 51 ++ 5 files changed, 895 insertions(+), 3 deletions(-) create mode 100644 shaders/rt_lib.frag create mode 100644 shaders/rt_quad_placeholder.frag diff --git a/build.rs b/build.rs index 67aaf3a..4a669e3 100644 --- a/build.rs +++ b/build.rs @@ -2,6 +2,28 @@ use std::process::Command; use std::io::{self, Write}; use std::path::Path; +use std::fs::File; +use std::io::{BufReader, BufRead, Error}; + +fn insert_place_holders(path: &str) { + let input = File::open(path).unwrap(); + let mut output = File::create(path.replace("_placeholder", "")).unwrap(); + let buffered = BufReader::new(input); + + for line in buffered.lines() { + let line_str = line.unwrap(); + if line_str.contains("#include ") { + let replacer = File::open(format!("shaders/{}", line_str.clone().split_off(9))).expect(format!("could not find the lib file shaders/{}", line_str.clone().split_off(9)).as_str()); + let replacement_buffered = BufReader::new(replacer); + for replacement_line in replacement_buffered.lines() { + write!(output, "{}\n", replacement_line.unwrap()).expect("could not write"); + } + } else { + write!(output, "{}\n", line_str).expect("could not write"); + } + } +} + fn main() { println!("cargo::rerun-if-changed=shaders/cube.frag"); println!("cargo::rerun-if-changed=shaders/cube.geom"); @@ -12,7 +34,8 @@ fn main() { println!("cargo::rerun-if-changed=shaders/cuboid.vert"); println!("cargo::rerun-if-changed=shaders/rt_quad.vert"); - println!("cargo::rerun-if-changed=shaders/rt_quad.frag"); + println!("cargo::rerun-if-changed=shaders/rt_lib.frag"); + println!("cargo::rerun-if-changed=shaders/rt_quad_placeholder.frag"); println!("cargo::rerun-if-changed=shaders/rt_compute_rasterize.comp"); println!("cargo::rerun-if-changed=shaders/rt_compute_grow_one.comp"); @@ -20,6 +43,9 @@ fn main() { println!("cargo::rerun-if-changed=shaders/rt_compute_grow_three.comp"); println!("cargo::rerun-if-changed=shaders/rt_compute_mempos.comp"); + // replace placeholders + insert_place_holders("shaders/rt_quad_placeholder.frag"); + std::fs::remove_file("shaders/compiled/geo_cube.spv").unwrap_or(()); std::fs::remove_file("shaders/compiled/frag_cube.spv").unwrap_or(()); std::fs::remove_file("shaders/compiled/vert_cube.spv").unwrap_or(()); diff --git a/shaders/compiled/frag_rt_quad.spv b/shaders/compiled/frag_rt_quad.spv index ff99d3f5c66a518a3a53221f0ae536d218268665..2cb51676fe4ce25969e602887b6c40c458704b28 100644 GIT binary patch literal 75396 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ΕymN-j*)yg<a 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 H=g<EDF?wh9 literal 74304 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 diff --git a/shaders/rt_lib.frag b/shaders/rt_lib.frag new file mode 100644 index 0000000..bc293db --- /dev/null +++ b/shaders/rt_lib.frag @@ -0,0 +1,794 @@ +layout(binding = 0) uniform UniformBufferObject { + mat4 model; + mat4 geom_rot; + mat4 view; + mat4 proj; + vec3 camera_pos; + bool[16] use_geom_shader; +} ubo; + +// 0 - location for the maximum number of lights referenced per chunk (also will be the invalid memory allocation for pointing to a nonexistant neighbor) +// 1 - location for the max iterations per light +// 2 - diffuse raster samples (2*n + 1) * (2*n + 1) so as to always have at least the central fragment covered +// 3 - diffuse raster size (float, needs to be decoded) +// 4 - max recursive rays +// 5 - diffuse rays per hit +// 6 - maximum number of compounds per light +layout(binding = 2) readonly buffer SceneInfoBuffer{ + uint infos[]; +} scene_info; + +layout(binding = 3) readonly buffer CompoundBuffer { + uint compounds[]; +}; + +layout(binding = 10) readonly buffer OctTreeMemory { + uint oct_tree_mem[]; +}; + +uint max_num_lights = scene_info.infos[0]; +uint max_iterations_per_light = scene_info.infos[1]; +// diffuse raytracing using a quadratic raster of rays +int half_diffuse_raster_steps = int(scene_info.infos[2]); +float raster_distance = uintBitsToFloat(scene_info.infos[3]); +int raster_points = (2 * half_diffuse_raster_steps + 1) * (2 * half_diffuse_raster_steps + 1); +float pos_infinity = uintBitsToFloat(0x7F800000); +// set limit for maximal iterations +uint max_iterations = max_num_lights * max_iterations_per_light * raster_points; +uint iteration_num = 0; +uint max_num_compounds = scene_info.infos[6]; + +uvec4 unpack_color(uint val) { + // left most 8 bits first + uint val1 = (val >> 24); + uint val2 = (val << 8) >> 24; + uint val3 = (val << 16) >> 24; + uint val4 = (val << 24) >> 24; + + return uvec4(val4, val3, val2, val1); +} + +uint array_descr_offset = 6 + max_num_lights + max_num_compounds; +uint color_array_offset = 24 + 1; + +uint sample_neighbor_from_scene_info(uint volume_start, uvec2 raster_pos, uint f) { + uint array_descr_start = volume_start + array_descr_offset; + uint color_array_start = array_descr_start + color_array_offset; + + uint top_color_size_u = scene_info.infos[array_descr_start]; + uint top_color_size_v = scene_info.infos[array_descr_start + 1]; + + uint bottom_color_size_u = scene_info.infos[array_descr_start + 2]; + uint bottom_color_size_v = scene_info.infos[array_descr_start + 3]; + + uint left_color_size_u = scene_info.infos[array_descr_start + 4]; + uint left_color_size_v = scene_info.infos[array_descr_start + 5]; + + uint right_color_size_u = scene_info.infos[array_descr_start + 6]; + uint right_color_size_v = scene_info.infos[array_descr_start + 7]; + + uint front_color_size_u = scene_info.infos[array_descr_start + 8]; + uint front_color_size_v = scene_info.infos[array_descr_start + 9]; + + uint back_color_size_u = scene_info.infos[array_descr_start + 10]; + uint back_color_size_v = scene_info.infos[array_descr_start + 11]; + + uint top_neighbor_size_u = scene_info.infos[array_descr_start + 12]; + uint top_neighbor_size_v = scene_info.infos[array_descr_start + 13]; + + uint bottom_neighbor_size_u = scene_info.infos[array_descr_start + 14]; + uint bottom_neighbor_size_v = scene_info.infos[array_descr_start + 15]; + + uint left_neighbor_size_u = scene_info.infos[array_descr_start + 16]; + uint left_neighbor_size_v = scene_info.infos[array_descr_start + 17]; + + uint right_neighbor_size_u = scene_info.infos[array_descr_start + 18]; + uint right_neighbor_size_v = scene_info.infos[array_descr_start + 19]; + + uint front_neighbor_size_u = scene_info.infos[array_descr_start + 20]; + uint front_neighbor_size_v = scene_info.infos[array_descr_start + 21]; + + uint back_neighbor_size_u = scene_info.infos[array_descr_start + 22]; + uint back_neighbor_size_v = scene_info.infos[array_descr_start + 23]; + + uint top_color_size = top_color_size_u * top_color_size_v; + uint bottom_color_size = bottom_color_size_u * bottom_color_size_v; + uint left_color_size = left_color_size_u * left_color_size_v; + uint right_color_size = right_color_size_u * right_color_size_v; + uint front_color_size = front_color_size_u * front_color_size_v; + uint back_color_size = back_color_size_u * back_color_size_v; + + uint color_array_end = color_array_start + top_color_size + bottom_color_size + left_color_size + right_color_size + front_color_size + back_color_size; + + uint top_neighbor_size = top_neighbor_size_u * top_neighbor_size_v; + uint bottom_neighbor_size = bottom_neighbor_size_u * bottom_neighbor_size_v; + uint left_neighbor_size = left_neighbor_size_u * left_neighbor_size_v; + uint right_neighbor_size = right_neighbor_size_u * right_neighbor_size_v; + uint front_neighbor_size = front_neighbor_size_u * front_neighbor_size_v; + uint back_neighbor_size = back_neighbor_size_u * back_neighbor_size_v; + + // maybe do an array solution for this as well + uint array_start = color_array_end + uint(f > 0) * top_neighbor_size + uint(f > 1) * bottom_neighbor_size + uint(f > 2) * left_neighbor_size + uint(f > 3) * right_neighbor_size + uint(f > 4) * front_neighbor_size; + uint us[6] = {top_neighbor_size_u, bottom_neighbor_size_u, left_neighbor_size_u, right_neighbor_size_u, front_neighbor_size_u, back_neighbor_size_u}; + uint vs[6] = {top_neighbor_size_v, bottom_neighbor_size_v, left_neighbor_size_v, right_neighbor_size_v, front_neighbor_size_v, back_neighbor_size_v}; + uint u_size = us[f]; + uint v_size = vs[f]; + uint value = scene_info.infos[array_start + raster_pos.x * v_size * uint(u_size > 1) + raster_pos.y * uint(v_size > 1)]; + return value; +} + +uint sample_neighbor_from_scene_info(uint volume_start, vec2 raster_pos, uint f) { + return sample_neighbor_from_scene_info(volume_start, uvec2(uint(floor(raster_pos.x)), uint(floor(raster_pos.y))), f); +} + +uvec4 sample_color_from_scene_info(uint volume_start, uvec2 raster_pos, uint f) { + uint array_descr_start = volume_start + array_descr_offset; + uint color_array_start = array_descr_start + color_array_offset; + + uint top_color_size_u = scene_info.infos[array_descr_start]; + uint top_color_size_v = scene_info.infos[array_descr_start + 1]; + + uint bottom_color_size_u = scene_info.infos[array_descr_start + 2]; + uint bottom_color_size_v = scene_info.infos[array_descr_start + 3]; + + uint left_color_size_u = scene_info.infos[array_descr_start + 4]; + uint left_color_size_v = scene_info.infos[array_descr_start + 5]; + + uint right_color_size_u = scene_info.infos[array_descr_start + 6]; + uint right_color_size_v = scene_info.infos[array_descr_start + 7]; + + uint front_color_size_u = scene_info.infos[array_descr_start + 8]; + uint front_color_size_v = scene_info.infos[array_descr_start + 9]; + + uint back_color_size_u = scene_info.infos[array_descr_start + 10]; + uint back_color_size_v = scene_info.infos[array_descr_start + 11]; + + uint top_size = top_color_size_u * top_color_size_v; + uint bottom_size = bottom_color_size_u * bottom_color_size_v; + uint left_size = left_color_size_u * left_color_size_v; + uint right_size = right_color_size_u * right_color_size_v; + uint front_size = front_color_size_u * front_color_size_v; + uint back_size = back_color_size_u * back_color_size_v; + + // maybe do an array solution for this as well + uint array_start = color_array_start + uint(f > 0) * top_size + uint(f > 1) * bottom_size + uint(f > 2) * left_size + uint(f > 3) * right_size + uint(f > 4) * front_size; + uint us[6] = {top_color_size_u, bottom_color_size_u, left_color_size_u, right_color_size_u, front_color_size_u, back_color_size_u}; + uint vs[6] = {top_color_size_v, bottom_color_size_v, left_color_size_v, right_color_size_v, front_color_size_v, back_color_size_v}; + uint u_size = us[f]; + uint v_size = vs[f]; + uint value = scene_info.infos[array_start + clamp(raster_pos.x, 0, u_size) * v_size * uint(u_size > 1) + clamp(raster_pos.y, 0, v_size) * uint(v_size > 1)]; + return unpack_color(value); +} + +uvec4 sample_color_from_scene_info(uint volume_start, vec2 raster_pos, uint f) { + return sample_color_from_scene_info(volume_start, uvec2(uint(floor(raster_pos.x)), uint(floor(raster_pos.y))), f); +} + +vec3 get_light_position(uint light_index) { + return vec3(uintBitsToFloat(scene_info.infos[light_index + 1]), uintBitsToFloat(scene_info.infos[light_index + 2]), uintBitsToFloat(scene_info.infos[light_index + 3])); +} + +vec3 get_light_color(uint light_index) { + return vec3(float(scene_info.infos[light_index + 4]) / 255.0, float(scene_info.infos[light_index + 5]) / 255.0, float(scene_info.infos[light_index + 6]) / 255.0); +} + +vec3 normal_for_facing(uint facing) { + if (facing == 0) { + return vec3(0.0, 0.0, -1.0); + } + if (facing == 1) { + return vec3(0.0, 0.0, 1.0); + } + if (facing == 2) { + return vec3(1.0, 0.0, 0.0); + } + if (facing == 3) { + return vec3(-1.0, 0.0, 0.0); + } + if (facing == 4) { + return vec3(0.0, 1.0, 0.0); + } + if (facing == 5) { + return vec3(0.0, -1.0, 0.0); + } + + return vec3(0.0, 0.0, 0.0); +} + +vec3 reflect_vector(vec3 direction, uint facing) { + vec3 normal = normal_for_facing(facing); + return direction - 2.0 * dot(direction, normal) * normal; +} + +uvec3 parent_child_vec(uint child_size, uint child_index) { + if (child_index == 1) { + return uvec3(0, 0, 0); + } + if (child_index == 2) { + return uvec3(child_size, 0, 0); + } + if (child_index == 3) { + return uvec3(0, child_size, 0); + } + if (child_index == 4) { + return uvec3(child_size, child_size, 0); + } + if (child_index == 5) { + return uvec3(0, 0, child_size); + } + if (child_index == 6) { + return uvec3(child_size, 0, child_size); + } + if (child_index == 7) { + return uvec3(0, child_size, child_size); + } + if (child_index == 8) { + return uvec3(child_size, child_size, child_size); + } + return uvec3(0, 0, 0); +} + +uint next_oct_tree_child(vec3 mid_point, vec3 check_pos, bool child_open[8]) { + if (check_pos.x <= mid_point.x && check_pos.y <= mid_point.y && check_pos.z <= mid_point.z && child_open[0]) { + return 1; + } + if (check_pos.x >= mid_point.x && check_pos.y <= mid_point.y && check_pos.z <= mid_point.z && child_open[1]) { + return 2; + } + if (check_pos.x <= mid_point.x && check_pos.y >= mid_point.y && check_pos.z <= mid_point.z && child_open[2]) { + return 3; + } + if (check_pos.x >= mid_point.x && check_pos.y >= mid_point.y && check_pos.z <= mid_point.z && child_open[3]) { + return 4; + } + if (check_pos.x <= mid_point.x && check_pos.y <= mid_point.y && check_pos.z >= mid_point.z && child_open[4]) { + return 5; + } + if (check_pos.x >= mid_point.x && check_pos.y <= mid_point.y && check_pos.z >= mid_point.z && child_open[5]) { + return 6; + } + if (check_pos.x <= mid_point.x && check_pos.y >= mid_point.y && check_pos.z >= mid_point.z && child_open[6]) { + return 7; + } + if (check_pos.x >= mid_point.x && check_pos.y >= mid_point.y && check_pos.z >= mid_point.z && child_open[7]) { + return 8; + } + + return 0; // return to parent +} + +struct Tracing { + vec3 end_pos; + uvec4 end_color; + uint end_volume; + uint end_facing; + float end_factor; + uint end_cycle; + bool has_hit; + vec3 color_mul; + uvec2 end_raster; + + vec3 end_direction; + bool has_transparent_hit; +}; + +Tracing trace_ray(uint volume_start, vec3 starting_pos, vec3 start_direction, float start_max_factor, bool allow_reflect) { + vec3 direction = start_direction; + float max_factor = start_max_factor; + vec3 pos = starting_pos; + // setup volume info + uint volume_index = volume_start; + float volume_scale = uintBitsToFloat(scene_info.infos[volume_index + array_descr_offset + color_array_offset - 1]); + float volume_pos_x = uintBitsToFloat(scene_info.infos[volume_index + 0]); + float volume_pos_y = uintBitsToFloat(scene_info.infos[volume_index + 1]); + float volume_pos_z = uintBitsToFloat(scene_info.infos[volume_index + 2]); + + bool x_pos = direction.x > 0.0; + bool x_null = (direction.x == 0.0); + + bool y_pos = direction.y > 0.0; + bool y_null = (direction.y == 0.0); + + bool z_pos = direction.z > 0.0; + bool z_null = (direction.z == 0.0); + + // default is max factor, that way we avoid collision when going parallel to an axis. The other directions will score a hit + float x_factor = max_factor; + float y_factor = max_factor; + float z_factor = max_factor; + + Tracing result; + result.has_hit = false; + result.has_transparent_hit = false; + result.color_mul = vec3(1.0, 1.0, 1.0); + + // intermediate storage for transparent hit values + vec3 end_pos_transparent; + uvec4 end_color_transparent; + uint end_volume_transparent; + uint end_facing_transparent; + uvec2 end_raster_transparent; + vec3 color_mul_transparent; + + uint next_volumetric_index = 0; + uint[5] done_volumetrics; + for (int i=0; i < 5; i++) { + done_volumetrics[i] = 0; + } + + while (iteration_num < max_iterations) { + iteration_num ++; + + uint compound_num = 0; + while (scene_info.infos[volume_index + 6 + max_num_lights + compound_num] != 0 && compound_num < max_num_compounds && iteration_num < max_iterations && !result.has_hit) { + uint compound_start = scene_info.infos[volume_index + 6 + max_num_lights + compound_num]; + + bool already_checked = false; + for (int i=0; i < 5; i++) { + if (compound_start == done_volumetrics[i]) { + already_checked = true; + break; + } + } + if (already_checked) { + compound_num += 1; + continue; + } + done_volumetrics[next_volumetric_index] = compound_start; + next_volumetric_index = (next_volumetric_index + 1) % 5; + + //iteration_num ++; + uint oct_tree_index = compounds[compound_start + 8]; + uint compound_grid_size = compounds[compound_start]; + float compound_scale = uintBitsToFloat(compounds[compound_start + 1]); + vec3 compound_pos = vec3(uintBitsToFloat(compounds[compound_start + 5]), uintBitsToFloat(compounds[compound_start + 6]), uintBitsToFloat(compounds[compound_start + 7])); + // check if we hit the volume + float x_border = compound_pos.x + float((compound_grid_size) * uint(!x_pos)) * compound_scale; + float y_border = compound_pos.y + float((compound_grid_size) * uint(!y_pos)) * compound_scale; + float z_border = compound_pos.z + float((compound_grid_size) * uint(!z_pos)) * compound_scale; + + // go over the borders by this amount + float overstep = 0.00001 / length(direction); + + if (!x_null) { + x_factor = (x_border - pos.x) / direction.x; + } else { + x_factor = max_factor; + } + if (!y_null) { + y_factor = (y_border - pos.y) / direction.y; + } else { + y_factor = max_factor; + } + if (!z_null) { + z_factor = (z_border - pos.z) / direction.z; + } else { + z_factor = max_factor; + } + x_factor += overstep; + y_factor += overstep; + z_factor += overstep; + + vec3 intersection_pos = pos; + bool is_x_hit = false; + bool is_y_hit = false; + bool is_z_hit = false; + bool hit_inside = false; + if ((compound_pos.x <= intersection_pos.x && intersection_pos.x <= compound_pos.x + float(compound_grid_size) * compound_scale) && + (compound_pos.y <= intersection_pos.y && intersection_pos.y <= compound_pos.y + float(compound_grid_size) * compound_scale) && + (compound_pos.z <= intersection_pos.z && intersection_pos.z <= compound_pos.z + float(compound_grid_size) * compound_scale)){ + //hit_inside = true; + } else { + vec3 intersection_pos_x = pos + x_factor * direction; + vec3 intersection_pos_y = pos + y_factor * direction; + vec3 intersection_pos_z = pos + z_factor * direction; + if ((compound_pos.x <= intersection_pos_x.x && intersection_pos_x.x <= compound_pos.x + float(compound_grid_size) * compound_scale) && + (compound_pos.y <= intersection_pos_x.y && intersection_pos_x.y <= compound_pos.y + float(compound_grid_size) * compound_scale) && + (compound_pos.z <= intersection_pos_x.z && intersection_pos_x.z <= compound_pos.z + float(compound_grid_size) * compound_scale) && x_factor > 0.0 && x_factor <= max_factor) { + hit_inside = true; + is_x_hit = true; + intersection_pos = intersection_pos_x; + } + + if ((compound_pos.x <= intersection_pos_y.x && intersection_pos_y.x <= compound_pos.x + float(compound_grid_size) * compound_scale) && + (compound_pos.y <= intersection_pos_y.y && intersection_pos_y.y <= compound_pos.y + float(compound_grid_size) * compound_scale) && + (compound_pos.z <= intersection_pos_y.z && intersection_pos_y.z <= compound_pos.z + float(compound_grid_size) * compound_scale) && y_factor > 0.0 && y_factor <= max_factor && (y_factor < x_factor || !is_x_hit)) { + hit_inside = true; + is_y_hit = true; + intersection_pos = intersection_pos_y; + } + + if ((compound_pos.x <= intersection_pos_z.x && intersection_pos_z.x <= compound_pos.x + float(compound_grid_size) * compound_scale) && + (compound_pos.y <= intersection_pos_z.y && intersection_pos_z.y <= compound_pos.y + float(compound_grid_size) * compound_scale) && + (compound_pos.z <= intersection_pos_z.z && intersection_pos_z.z <= compound_pos.z + float(compound_grid_size) * compound_scale) && z_factor > 0.0 && z_factor <= max_factor && (z_factor < x_factor || !is_x_hit) && (z_factor < y_factor || !is_y_hit)) { + hit_inside = true; + is_z_hit = true; + intersection_pos = intersection_pos_z; + } + } + + // check that either the hit is in range or we are inside of the compound from the start + if (hit_inside) { + vec3 oct_tree_pos = vec3(compound_pos); + uint current_size = compound_grid_size; + vec3 mid_point = oct_tree_pos + float(current_size / 2) * vec3(compound_scale, compound_scale, compound_scale); + bool children_open[8] = {true, true, true, true, true, true, true, true}; + uint oct_tree_address = oct_tree_index; + // iterate through the oct_tree + uint check_it = 0; + uint max_check_it = 60; + uint prev_child = 0; + uint prev_prev_child = 0; + + uvec3 grid_pos = uvec3(0, 0, 0); + uvec3 parent_pos = uvec3(0, 0, 0); + + bool has_moved = false; + while (!result.has_hit && check_it < max_check_it) { + // failsafe to get out in case has_moved runs into an accuracy issue + check_it ++; + oct_tree_pos = vec3(grid_pos) * compound_scale + compound_pos; + mid_point = oct_tree_pos + (float(current_size / 2) * vec3(compound_scale, compound_scale, compound_scale)); + + uint child_index = next_oct_tree_child(mid_point, intersection_pos, children_open); + if (child_index == 0) { + // go up to parent + // if parent is 0 abort, as we have reached the root node again and try to exit it + if (oct_tree_mem[oct_tree_address] == 0) { + break; + } + for (int i=0; i < 8; i++) { + children_open[i] = true; + } + uint parent_index = oct_tree_mem[oct_tree_address]; + // check which child we came from + child_index = 1 * uint(oct_tree_address == oct_tree_mem[parent_index + 1]) + 2 * uint(oct_tree_address == oct_tree_mem[parent_index + 2]) + 3 * uint(oct_tree_address == oct_tree_mem[parent_index + 3]) + 4 * uint(oct_tree_address == oct_tree_mem[parent_index + 4]) + 5 * uint(oct_tree_address == oct_tree_mem[parent_index + 5]) + 6 * uint(oct_tree_address == oct_tree_mem[parent_index + 6]) + 7 * uint(oct_tree_address == oct_tree_mem[parent_index + 7]) + 8 * uint(oct_tree_address == oct_tree_mem[parent_index + 8]); + // mark as done to avoid reinvestigating, since intersection_pos is on its edge + children_open[child_index - 1] = false; + prev_prev_child = prev_child; + prev_child = oct_tree_address; + + uvec3 back_vec = parent_child_vec(current_size, child_index); + grid_pos -= parent_child_vec(current_size, child_index); + current_size *= 2; + oct_tree_address = parent_index; + } else { + // go down into child + if (current_size == 2) { + // check block if hit break + if (oct_tree_mem[oct_tree_address + child_index] != 0) { + result.has_hit = true; + result.end_color = unpack_color(oct_tree_mem[oct_tree_address + child_index]); + break; + } + } else { + // check if the child has content, else skip to next child of current parent + uint x = oct_tree_mem[oct_tree_address + child_index]; + if (oct_tree_mem[x] != 0) { + // change base address and position to child + current_size /= 2; + oct_tree_address = x; + grid_pos += parent_child_vec(current_size, child_index); + for (int i=0; i < 8; i++) { + children_open[i] = true; + } + continue; + } + } + children_open[child_index - 1] = false; + + // we did not go deeper or had a hit, so intersection pos needs to be updated + // new intersection pos calc + vec3 offset = vec3(parent_child_vec(current_size / 2, child_index)) * compound_scale; + vec3 low = oct_tree_pos + offset; + float x_border = low.x + float((compound_scale * current_size / 2) * uint(x_pos)); + float y_border = low.y + float((compound_scale * current_size / 2) * uint(y_pos)); + float z_border = low.z + float((compound_scale * current_size / 2) * uint(z_pos)); + + if (!x_null) { + x_factor = (x_border - pos.x) / direction.x; + if (x_factor <= 0.0) { + x_factor = max_factor; + } + } else { + x_factor = max_factor; + } + if (!y_null) { + y_factor = (y_border - pos.y) / direction.y; + if (y_factor <= 0.0) { + y_factor = max_factor; + } + } else { + y_factor = max_factor; + } + if (!z_null) { + z_factor = (z_border - pos.z) / direction.z; + if (z_factor <= 0.0) { + z_factor = max_factor; + } + } else { + z_factor = max_factor; + } + float smallest_factor = min(min(x_factor, y_factor), z_factor); + + if (x_factor == smallest_factor) { + is_x_hit = true; + is_y_hit = false; + is_z_hit = false; + } + if (y_factor == smallest_factor) { + is_x_hit = false; + is_y_hit = true; + is_z_hit = false; + } + if (z_factor == smallest_factor) { + is_x_hit = false; + is_y_hit = false; + is_z_hit = true; + } + + // move a bit further to fully enter the next quadrant + smallest_factor += overstep; + + //has_moved = length(intersection_pos - (pos + smallest_factor * direction)) >= 0.00001; + has_moved = intersection_pos != (pos + smallest_factor * direction); + intersection_pos = pos + smallest_factor * direction; + } + } + + uint hit_facing = uint(is_x_hit) * (2 + uint(x_pos)) + uint(is_y_hit) * (4 + uint(y_pos)) + uint(is_z_hit && !z_pos); + //result.has_hit = true; + result.end_pos = intersection_pos; + result.end_facing = hit_facing; + result.end_volume = volume_index; + result.end_direction = direction; + } + + compound_num += 1; + } + + if (result.has_hit) { + break; + } + + float x_border = volume_pos_x + float((scene_info.infos[volume_index + 3]) * uint(x_pos)) * volume_scale - 0.5 * volume_scale; + float y_border = volume_pos_y + float((scene_info.infos[volume_index + 4]) * uint(y_pos)) * volume_scale - 0.5 * volume_scale; + float z_border = volume_pos_z + float((scene_info.infos[volume_index + 5]) * uint(z_pos)) * volume_scale - 0.5 * volume_scale; + + bool needs_next_light = false; + + if (!x_null) { + x_factor = (x_border - pos.x) / direction.x; + } else { + x_factor = max_factor; + } + if (!y_null) { + y_factor = (y_border - pos.y) / direction.y; + } else { + y_factor = max_factor; + } + if (!z_null) { + z_factor = (z_border - pos.z) / direction.z; + } else { + z_factor = max_factor; + } + + if ((x_factor >= max_factor) && (y_factor >= max_factor) && (z_factor >= max_factor)) { + // no hit, finish tracking + break; + } else { + // if there is a border hit before reaching the end + // change to the relevant next volume + // Todo: look into removing ifs from this + uint hit_facing = 0; + uint u = 0; + uint v = 0; + + bool is_x_smallest = x_factor < y_factor && x_factor < z_factor; + bool is_y_smallest = y_factor < x_factor && y_factor < z_factor; + bool is_z_smallest = z_factor <= x_factor && z_factor <= y_factor; + + hit_facing = uint(is_x_smallest) * (2 + uint(x_pos)) + uint(is_y_smallest) * (4 + uint(y_pos)) + uint(is_z_smallest && !z_pos); + float smallest_factor = min(min(x_factor, y_factor), z_factor); // maybe use multiplication instead? + vec3 intersection_pos = pos + smallest_factor * direction; + u = uint(is_x_smallest) * (uint(round((intersection_pos.y - volume_pos_y) / volume_scale))) + + uint(is_y_smallest || is_z_smallest) * (uint(round((intersection_pos.x - volume_pos_x) / volume_scale))); + v = uint(is_x_smallest || is_y_smallest) * (uint(round((intersection_pos.z - volume_pos_z) / volume_scale))) + + uint(is_z_smallest) * (uint(round((intersection_pos.y - volume_pos_y) / volume_scale))); + + uint next_neighbor = sample_neighbor_from_scene_info(volume_index, uvec2(u, v), hit_facing); + uvec4 color_sample = sample_color_from_scene_info(volume_index, uvec2(u, v), hit_facing); + + if (color_sample.xyz == uvec3(0, 0, 0)) { + // not a color hit, so check neighbor + if (next_neighbor != 0) { + volume_index = next_neighbor; + volume_scale = uintBitsToFloat(scene_info.infos[volume_index + array_descr_offset + color_array_offset - 1]); + volume_pos_x = uintBitsToFloat(scene_info.infos[volume_index + 0]); + volume_pos_y = uintBitsToFloat(scene_info.infos[volume_index + 1]); + volume_pos_z = uintBitsToFloat(scene_info.infos[volume_index + 2]); + } else { + // neighbor miss + end_color_transparent = uvec4(255, 0, 0, 255); + result.end_color = uvec4(255, 0, 0, 255); + break; + } + } else { + if (next_neighbor != 0) { + // transparent hit, move on but change the color + end_volume_transparent = volume_index; + color_mul_transparent = result.color_mul; + + volume_index = next_neighbor; + volume_scale = uintBitsToFloat(scene_info.infos[volume_index + array_descr_offset + color_array_offset - 1]); + volume_pos_x = uintBitsToFloat(scene_info.infos[volume_index + 0]); + volume_pos_y = uintBitsToFloat(scene_info.infos[volume_index + 1]); + volume_pos_z = uintBitsToFloat(scene_info.infos[volume_index + 2]); + result.color_mul = result.color_mul * vec3(float(color_sample.x) / 255.0, float(color_sample.y) / 255.0, float(color_sample.z) / 255.0); + result.has_transparent_hit = true; + result.end_volume = volume_index; + result.end_direction = direction; + + end_color_transparent = color_sample; + end_raster_transparent = uvec2(u, v); + end_pos_transparent = intersection_pos; + end_facing_transparent = hit_facing; + + // stop iterating if there is barely anything left to see + if (max(result.color_mul.x, max(result.color_mul.y, result.color_mul.z)) < 0.1) { + break; + } + } else { + // color hit, either reflect or move on + result.end_pos = intersection_pos; + result.end_facing = hit_facing; + result.end_color = color_sample; + result.end_raster = uvec2(u, v); + result.has_hit = true; + result.end_volume = volume_index; + result.end_direction = direction; + + float reflectivity = 1.0 - float(color_sample.w) / 255.0; + vec3 refltective_color_mul = result.color_mul * vec3(float(color_sample.x) / 255.0, float(color_sample.y) / 255.0, float(color_sample.z) / 255.0); + vec3 visibility_after_reflection = refltective_color_mul * reflectivity; + //break; + //max(visibility_after_reflection.x, max(visibility_after_reflection.y, visibility_after_reflection.z)) >= 0.1 && + if (max(visibility_after_reflection.x, max(visibility_after_reflection.y, visibility_after_reflection.z)) >= 0.1 && allow_reflect) { + // do reflect + direction = reflect_vector(direction, hit_facing); + pos = intersection_pos; + //max_factor -= smallest_factor; + + x_pos = direction.x > 0.0; + x_null = (direction.x == 0.0); + + y_pos = direction.y > 0.0; + y_null = (direction.y == 0.0); + + z_pos = direction.z > 0.0; + z_null = (direction.z == 0.0); + } else { + break; + } + } + } + } + } + + result.end_factor = min(min(x_factor, y_factor), z_factor); + result.end_cycle = iteration_num; + + // in case we have a transparent hit but no hit afterwards + if (!result.has_hit && result.has_transparent_hit) { + // did we stop because nothing could be seen through the object? + if (max(result.color_mul.x, max(result.color_mul.y, result.color_mul.z)) < 0.1) { + // if so count it as a hit and recover the pre transparent color multiplier + result.has_hit = true; + result.color_mul = color_mul_transparent; + } + result.end_pos = end_pos_transparent; + result.end_color = end_color_transparent; + result.end_volume = end_volume_transparent; + result.end_facing = end_facing_transparent; + result.end_raster = end_raster_transparent; + } + + return result; +} + +vec3 get_lighting_color(uint volume_start, vec3 starting_pos, vec4 orig_color_sample, vec3 normal) { + uint light_num = 0; + + // initialize color + vec3 color_sum = vec3(0.0, 0.0, 0.0);// + (orig_color_sample.xyz * 0.005); + + while (iteration_num < max_iterations) { + // setup light info + uint light_index = scene_info.infos[volume_start + 6 + light_num]; + if (light_index == 0) { + // abort if there is no new light + break; + } + vec3 light_direction; + float max_factor; + if (scene_info.infos[light_index] == 0) { + //point light + light_direction = get_light_position(light_index) - starting_pos; + max_factor = 1.0; + } else if (scene_info.infos[light_index] == 1) { + // directional light + light_direction = -normalize(get_light_position(light_index)); + max_factor = pos_infinity; + } + vec3 light_color = get_light_color(light_index); + + Tracing result = trace_ray(volume_start, starting_pos, light_direction, max_factor, false); + // add result, if there is a hit the null vector will be added + color_sum += float(!result.has_hit) * result.color_mul * max(dot(normal, normalize(light_direction)), 0.0) * (orig_color_sample.xyz * light_color) / (length(light_direction) * length(light_direction)); + + light_num += 1; + if (light_num >= max_num_lights) { + break; + } + } + + return color_sum; +} + +vec3 diffuse_tracing(uint volume_start, uvec4 color_roughness, vec3 pos, uint f) { + vec4 orig_color_sample = vec4(float(color_roughness.x) / 255.0, float(color_roughness.y) / 255.0, float(color_roughness.z) / 255.0, 1); + vec3 normal = normal_for_facing(f); + + vec3 color_sum = vec3(0.0, 0.0, 0.0); + for (int u_offset = -half_diffuse_raster_steps; u_offset <= half_diffuse_raster_steps; u_offset++) { + for (int v_offset = -half_diffuse_raster_steps; v_offset <= half_diffuse_raster_steps; v_offset++) { + float x_offset = raster_distance * float(u_offset) * float(f == 0 || f == 1 || f == 4 || f == 5); + float y_offset = raster_distance * float(u_offset) * float(f == 2 || f == 3); + y_offset += raster_distance * float(v_offset) * float(f == 0 || f == 1); + float z_offset = raster_distance * float(v_offset) * float(f == 4 || f == 5 || f == 2 || f == 3); + + vec3 offset = vec3(x_offset, y_offset, z_offset); + + color_sum += get_lighting_color(volume_start, pos + offset, orig_color_sample, normal) / float(raster_points); + } + } + + return color_sum; +} + +vec3 clamp_to_volume(uint volume_start, vec3 position) { + float volume_pos_x = uintBitsToFloat(scene_info.infos[volume_start + 0]); + float volume_pos_y = uintBitsToFloat(scene_info.infos[volume_start + 1]); + float volume_pos_z = uintBitsToFloat(scene_info.infos[volume_start + 2]); + float volume_scale = uintBitsToFloat(scene_info.infos[volume_start + array_descr_offset + color_array_offset - 1]); + + float high_x_border = volume_pos_x + float(scene_info.infos[volume_start + 3]) * volume_scale - 0.501 * volume_scale; + float high_y_border = volume_pos_y + float(scene_info.infos[volume_start + 4]) * volume_scale - 0.501 * volume_scale; + float high_z_border = volume_pos_z + float(scene_info.infos[volume_start + 5]) * volume_scale - 0.501 * volume_scale; + + float low_x_border = float(volume_pos_x) - 0.501 * volume_scale; + float low_y_border = float(volume_pos_y) - 0.501 * volume_scale; + float low_z_border = float(volume_pos_z) - 0.501 * volume_scale; + + return vec3(min(max(position.x, low_x_border), high_x_border), min(max(position.y, low_y_border), high_y_border), min(max(position.z, low_z_border), high_z_border)); +} + +vec2 clamp_to_quad(vec2 raster_pos, uvec2 min_raster_pos, uvec2 max_raster_pos) { + return vec2(max(min_raster_pos.x, min(max_raster_pos.x - 1, raster_pos.x)), max(min_raster_pos.y, min(max_raster_pos.y - 1, raster_pos.y))); +} + +vec3 add_reflection(vec3 view_vector, uint f, uint volume_start, vec3 pos, uvec4 color_sample, vec3 color_sum) { + float reflectivity = 1.0 - float(color_sample.w) / 255.0; + + if (reflectivity > 0.01) { + vec3 orig_color_sample = vec3(float(color_sample.x) / 255.0, float(color_sample.y) / 255.0, float(color_sample.z) / 255.0); + vec3 reflection_direction = reflect_vector(view_vector, f); + Tracing reflection_tracing = trace_ray(volume_start, pos, reflection_direction, pos_infinity, true); + if (reflection_tracing.has_hit || reflection_tracing.has_transparent_hit) { + vec3 color_from_reflection = diffuse_tracing(reflection_tracing.end_volume, reflection_tracing.end_color, reflection_tracing.end_pos, reflection_tracing.end_facing) * orig_color_sample; + color_sum = color_sum * (1.0 - reflectivity) + color_from_reflection * reflectivity; + } + } + + return color_sum; +} \ No newline at end of file diff --git a/shaders/rt_quad.frag b/shaders/rt_quad.frag index c59b4e4..d5f4a7b 100644 --- a/shaders/rt_quad.frag +++ b/shaders/rt_quad.frag @@ -321,13 +321,34 @@ Tracing trace_ray(uint volume_start, vec3 starting_pos, vec3 start_direction, fl uvec2 end_raster_transparent; vec3 color_mul_transparent; + uint next_volumetric_index = 0; + uint[5] done_volumetrics; + for (int i=0; i < 5; i++) { + done_volumetrics[i] = 0; + } + while (iteration_num < max_iterations) { iteration_num ++; uint compound_num = 0; while (scene_info.infos[volume_index + 6 + max_num_lights + compound_num] != 0 && compound_num < max_num_compounds && iteration_num < max_iterations && !result.has_hit) { - //iteration_num ++; uint compound_start = scene_info.infos[volume_index + 6 + max_num_lights + compound_num]; + + bool already_checked = false; + for (int i=0; i < 5; i++) { + if (compound_start == done_volumetrics[i]) { + already_checked = true; + break; + } + } + if (already_checked) { + compound_num += 1; + continue; + } + done_volumetrics[next_volumetric_index] = compound_start; + next_volumetric_index = (next_volumetric_index + 1) % 5; + + //iteration_num ++; uint oct_tree_index = compounds[compound_start + 8]; uint compound_grid_size = compounds[compound_start]; float compound_scale = uintBitsToFloat(compounds[compound_start + 1]); @@ -820,4 +841,4 @@ void main() { } outColor = vec4(color_sum, 1.0); -} \ No newline at end of file +} diff --git a/shaders/rt_quad_placeholder.frag b/shaders/rt_quad_placeholder.frag new file mode 100644 index 0000000..0f69b04 --- /dev/null +++ b/shaders/rt_quad_placeholder.frag @@ -0,0 +1,51 @@ +#version 450 + +layout(location = 0) in vec2 fragRasterPos; +layout(location = 1) flat in uint fragVolumeStart; +layout(location = 2) in vec3 origPosition; +layout(location = 3) flat in uint facing; +layout(location = 4) flat in uvec2 minRasterPos; +layout(location = 5) flat in uvec2 maxRasterPos; + +layout(location = 0) out vec4 outColor; + +#include rt_lib.frag + +void main() { + vec3 clamped_pos = clamp_to_volume(fragVolumeStart, origPosition); + vec2 clamped_raster_pos = clamp_to_quad(fragRasterPos, minRasterPos, maxRasterPos); + uvec4 color_roughness = sample_color_from_scene_info(fragVolumeStart, clamped_raster_pos, facing); + vec3 orig_color_sample = vec3(float(color_roughness.x) / 255.0, float(color_roughness.y) / 255.0, float(color_roughness.z) / 255.0); + vec3 color_sum; + + uint orig_neighbor = sample_neighbor_from_scene_info(fragVolumeStart, clamped_raster_pos, facing); + if (orig_neighbor != 0) { + vec3 color_direct = diffuse_tracing(fragVolumeStart, color_roughness, clamped_pos, facing); + + Tracing t = trace_ray(fragVolumeStart, ubo.camera_pos, clamped_pos - ubo.camera_pos, pos_infinity, false); + float opacity = float(color_roughness.w) / 255.0; + vec3 color_seen_through; + if (t.has_hit) { + //color_seen_through = vec3(float(t.end_color.x) / 255.0, float(t.end_color.y) / 255.0, float(t.end_color.z) / 255.0); + + color_seen_through = diffuse_tracing(t.end_volume, t.end_color, t.end_pos, t.end_facing) * orig_color_sample * t.color_mul; + color_seen_through = add_reflection(t.end_direction, t.end_facing, t.end_volume, t.end_pos, t.end_color, color_seen_through); + } + else { + // Todo: hit sky box + color_seen_through = vec3(0.0, 0.0, 0.0); + } + + color_direct = add_reflection(normalize(clamped_pos - ubo.camera_pos), facing, fragVolumeStart, clamped_pos, color_roughness, color_direct); + color_sum = opacity * color_direct + (1.0 - opacity) * color_seen_through; + + //color_sum = color_seen_through; + } + else { + color_sum = diffuse_tracing(fragVolumeStart, color_roughness, clamped_pos, facing); + + color_sum = add_reflection(normalize(clamped_pos - ubo.camera_pos), facing, fragVolumeStart, clamped_pos, color_roughness, color_sum); + } + + outColor = vec4(color_sum, 1.0); +} \ No newline at end of file From 68cd58f038ff5f1d5ab6971a7a413abc419f07e1 Mon Sep 17 00:00:00 2001 From: zomseffen <steffen@tom.bi> Date: Thu, 5 Jun 2025 13:45:46 +0200 Subject: [PATCH 5/5] depth ordering volumetrics --- shaders/compiled/frag_rt_quad.spv | Bin 75396 -> 79752 bytes shaders/rt_lib.frag | 353 +++++++++++++++++------------ shaders/rt_quad.frag | 354 ++++++++++++++++++------------ 3 files changed, 415 insertions(+), 292 deletions(-) diff --git a/shaders/compiled/frag_rt_quad.spv b/shaders/compiled/frag_rt_quad.spv index 2cb51676fe4ce25969e602887b6c40c458704b28..ed483a0278a02bd315d8bb39048283cb0c6542b4 100644 GIT binary patch literal 79752 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 literal 75396 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ΕymN-j*)yg<a z!j1E05oam5dg3e%R!f|IU^V0HQLp(jaPzbe?T+2+w|eqh9-Mh!4lLK^+N}uAysrS3 zr`^in%)8fgx%2K?t^!`1+IY6pZr|Q3XiJP$!D_cMrvva`4Xoxme2o7ZU|;_wA8o5s zE~R)6B~F~R!5M@14{~kpfpx*orTu#^A=l<Hu|C*iK%4g!^2FQ_obh>&A>WvYw%Z8Y zMQvZkw5>kI@qR{o`q&a|AMO$F9S2ahp!i-YK3moLDfk$FYq;&ylh3x`jBy*VJTbQi zH)HOA*3!voJFwjRcBD4Gaoxu|gFWwR+X*Ze??QcQhhv_l^&D+i_&)gAxABalzkd3A z-=$BEh26o<`#ZGB81{gxXAkcQR?8mV3#{fIHs)?%HDm5VoV~&Jb88*bJ+lv7-Tks3 zwJ-OJ`o5GCDDD?=ayt-goOAI_ZU@2D?e_p`x&Gcm90Jzg>ze-Vt3%=H`g@Nj*MEI% z1Ht-x-O%4PJshsC|6$bf<Z}dA|MHqX7_P4WAZmH`-w?3-&phqhc>1KTF7N`B)9U>+ z6x?b<og9w@+o$i@({31CJ?(~rZL4k``%|kW#?fG7_+B(IM!?neKZ;tOagG8v$2l5J zUH_5P^7tPE*8kjk9zC~=g{$j7hFYF{#)I`Q=Y0ZPUH@^^a{XP`W5N2D>pBUpuKz@8 zdB%1e*g4QPnOeRvPcdBI<H3G0#W6b$bF)8V=xZC>>h~%8(Y@-vbbrR?^O@47Px}4_ zxIB-XXgf-I9ytlFp7TgI*mml(*Vlw8;F-vCTZ(r3KABqGzMSJz!E@BMQ>f*!oes`< z=rpiAIi3m5`Sc91T${(s*<jBH_IDPwJnhZ}uUXs9p_XS}&jUNJ=4dYVX>4QYYdqWP zXFSho-voQ^Nc?Ys^*O&j9xec@>6bPaf^Fm68ROevpGB!B&P8C?FmWyhtLZzXj(rK( z_}a|vd}=k<bq#9Q{8DOTI@gzhGoRl9%e6UYSAa8TmxJZW<tlLI`bw}oF|Pq<{jLVf zbMCkn?773fjA>halB@RgaUHnabJy!fDfirW;p*9Q-virDJ$vp3aQ2*b`?`@@JvrYD zPR=)h<+0rY&Kykz%ah}6;LO9VV7WHu?+$S0?{=^}?d}4*Hs*3CwLE+7Zm@gK9L>c( zjcp8lGgtbR>+1R@{(WHM?^*As`@w3yqCHS+&P}ujYmKePeO#Z`bESvSY_Gp|_oX@9 z3)c1pv%3++=S_~A+l|(17XH5>e%|BGN^$Su-g@?=_5j7&XHnLVH2C8U{&dY9qkH#3 zigBN$U-`qe=I0vbXMDBze;=&>)3yH(z-o_D65}zjdSaN9T4MYVT*i13uJ!~aF`jDS z=`kFKT4Fo{E@S)%u4bQ!@nf)h@^I{GiSaC0E&MsK{e=GnZ0_ODgPjl8)HQm6Vhr2q ztNlyXM?GuloX$t_<>w|@OFuIa`@GN3OQO#Uc8%w!&YHdiF4y?w27k4|Uu*C;8vN}B zf49N^)8L;r_?Hdd!R9aX^Y461?%(#7+`s27`C<*;ufhFW-O}H`%`Lfqi(7L4_O|5y zt!>Hu+uD-v+~EH0Y-#szWlQeg#+KZ_g)O;%16%T=8{EHlE$#k|Ysvk)){-CJ;Qk$J zY4>keOYYyQmfXKjExCV_T5|smwdB_o{7JBXcN)9=`GTwa_ouO2`}e0Mf34;@j(&!Z z`#=2WV4s)dS;{ZK`lx#ja{sHv|CeC3@Lz#_#*+50fb~(gy~m4M{C^F$eV!5h2HZ_K znW8OzzXfYEhR2vZw%>t`kv?AstNGj@asSY=x8rJ0+dqP}8P{V~9^0S5W!$&mYHv~! z_s`&Niur0!+rNOd8TSopd2D|LmvR3FSM$AH;{F}nO);+awEYKIn{nT!mdEx_a2fYs zaJBa+iTiJGH^sQx)AoI^Hsg8@lE?M|xQzP|T<t?j;(iS7rWjXy+I|AoW?au@^4R_h zF5`X%SG$vvxSxZ&DaO^FwqJm?8P{{7JhrdEW!#zA^J?BSCGO1NZY1MsPupH#ZN~N7 zDvzx<xQyEgSKA7|#O(v`h8tIV+V%x&Gp^@od2F+S%eb?{)n=n4?i}F6)t<I<g0&gf zbG<w^zXMjrofod=_Ye|yK5*h{Puuyy+KlTpLmu0L;4<#Qa5cZrkhqJ06IXlME(+FW zT(3Ry*cJzuahHUv`Mrq5T?(AI+S7Jvur}j*4U@;V47iND99(T#O5!dLPF(G2y8>97 zalIDGV_OMa#$5%j=JzxbcU5rWYERqMz}k$vBDFlWHNa)uwcu)g-y?C?1}Coev|R_R z&A48h<*}^?F5_+hSM#&n#N7~_xZ2ZpBd|8(u1hVCZ4+=AcQd%!rj*3p9Gtk?({>9n z#kk%pw0PCNAMOt?<8B348(`rM`IL%hZ{Wn$p19k9wHeoY4tZ?bfy=l%z}2>=B<_yj z#MPd*JAt(scUx+CY`cKVxVypCcBLfl?%>4Lp0;~{wHbG3YI$sXfy=o2z}5DqB<{Z8 z#MPd*`+>C?cTZ}0YzKhLxCg=24x}XR!QjNzp0<a8wHbGRYI$sjfy=mu!_@{-5_b?d zakZ!I5nye`J(OA=+YqqV{_rli*X(>2H59Ioy6p#3tHpm9_>H3daJbjdv_A^2kGk!T zq*hD&5n!*4;UnQ*)6#wvTpxAYA5E<m|1n^%RpH0Ly~d>dShzmwwjWKc7XR_!j)G4B z&q7K2iC}%yZ9k4$E$t_P=PLMQ@B);yKMt&qy6umpR!jR6z}~-we*^9u=f3Mius-VX zISK4M#-|&spL%?zfSs%OoGhlO$LAEV^AVp@!TPDk=QOZmj?d{}{nX=g2H0`M=S;AE z>W=w%YPI;E4PLC^=YacBGH2(4^-;I|S=4H2e?EA{f`1e2c{%OB1=dI1_UBQnrTv9q z&$r><278`N`-{N(sN4PmYPI-Z0`~kDekpicO4@%1tdF|wFQ!(D|K;GF3w{OI^GMoX z3D!s5_LotsrTx|5{R@5#*yB3wuLbL)Zu_gK)zbcYuxk?jUGTi@!P|J|F@XAeaJ8x6 zsaz9$kADMP-TQy_w7n6{^-141f%R3-ez+NIpW4!HD!A<P7PwkFe!I_G;p)vkZ$ooU z)93AAebv+F9bo&_mOk$Umwny^SM$9`#(6hfz1inIXzqjbc`sOB_4Iik*nYL8&-=k; zpAW#*d|#42AB3wn`+Nw^y^}s42J5SyJ|6+wueS90eQ??5qj0tNiavh;S8w+D7@GSn zeLfD>S3Q0H5NyBN++WvGtEK;^!HX6A8E|>L{s_KqVgE6B%Yr`(E{~7r;O_T5_?+(v z>Yq^T!??z>y>0X}pQotxNj@)tJ->v%2wuJ5KLu}G@Rz{b7W`*mkI%IKIoRVZ`TPQG zAI3G7?QNr<`8-dpPul+y?E2(0q+h|!Sv@|lfYojPGPOLmUxUl`zk%C_dVGEhR=54D z)biMV2X@WU|L?)`wD!hypV!gU)8-Fg<78j_5v-4TeBJ<?YtAEo0;{$6So@fM6Rw_p zmw0cX8B=@q*`LAYsx7(x1#GUiPrq-YsfYg+Y_7@U9k5!N$KT-U%{=~&W<2f5;~!vi z(UyCycU$)Mds6M``=4NK&iiZB^4Q)3tN9F7Ts}ixobmWtn389ui_~}_>O~8EF|f~2 zm!Qrw)X#{QXHq_M{i5LNU)J1t+!_8p+?Y9+`+3rT(A51*ME(Jo|60$2wT-OW?;$<} zYfG$;z{bj&*!E*I^~CxF%zv#|+7jziu(mzO%kS{~7i@g>%-iQ+=fXL4oN}>a)IWY- zft?#|j#r-VdoW$C=hU{hop#s3|FRA~^InGHYe`DhVW}EBuS*wtKd|etEOpkwe@iaw zVC}yjS91T&xRU$t#FgBC8?NO3dvGQ9-+(K*|L$AK{kPsq?!WI=a{o=YlKbztmE3>3 zt>gn5e7gqs-)AfR{kPdl?!U`ca{o=XlKbzmmE3=eE&NH=$bW~e<fj*0-G7fQc5DAV zwvzkrv6b9^k4>IE(*bvV!+XQ;falongzKa3zH)ul;@=mn7CsBOd{#RvTpxAYyC2lz zKRej=Ij_tC?xz2fDca&UCs>;?+(Yu%<^~%hInM)D^LR|$d0X~&T<vK)A6T1l-HY<r z766xV7lf;o&uSNfCtvMpyD(UraoyAM*cJtsaTkNDc~6vl7l$XV_Ox9Btj)L{8}ite z0+(@@hO2qsleqohiK{(rmjP=tuE&@>w&lQO+~whF<+Iuq;EAg}ZC3<qGw!m~^4L}e zmvL8ttKC`TyDB_!wWsZBU~R_rn3u=42Dps7CS1)EaOPnxc;aeL+qJ>kjO)2W9^1O$ zGVXeCwXKSL*M}#r_O#sqtj)OVP|IW62wcY97_K&3k?$t(#MPd*n}W3&*K?UXw#~t1 z+%2?G<|*QC2~XUXy{ey+p=&d)=fwV$#N7&9#@!mOwonmw8+hVsPup$5+KlVDRUX^+ zV2|za9l#!wxkuU&tdF|wx1&~z|IT2KweVfQ9wTYLD_9?O+wVlJ7XRJB?)~sRz{^t7 zeowGI>bBpFS}p#2gWZea`+(g;X}>R6A9dUBMXeV9{lV^y@B_fEY1$tM)<@m;`%$aK z|6s6d6@CcVIZpdS!TPA%{vc|#_zwj4Dfr>we%18*$U$&5@0s%6?FhJf?jsXxFq-R= zzK4MIRnK|43v8d-(rzfY?DI&tT04IG9(ovDz1in*G}knJ9tGA{J$)VxwqI@Oa|F2T zb0l1?d|x~YuHNi(G@AP$eU1U^tDZiO0o$*(^f?w>_Bjr&R=zJD4_9yYIRVYRlRhVc z^;J)w$AaxwTl$;?F8iDeS1aEa9|u=&_IW&-`z?K*0M=JMeSQOMzuMeihf%Ag|C7M8 z6}%fff5E4K%j554czHaX0xyq`Q{kIY@;>x5uzeWUShlx~e&%x`wLZz`4Deh9KNGx2 z!OsFOTkx~N9?xli4%p)}{9Nz=O7b}mY#+uomhEk$pZT0ltxwv26YTorz23Lr=Byr{ z3&85OKc8A2+qc1G`-|ZAp&p-$!RofZkXjzwrC`@A{eK6%bn953?sFNMdfHqLHjmkP zXXA6SE5I{RuSU_=bA>+fzY=V}*+*A_ZKEEatHH+1``2s0YVAGQJ_lS2SI<68yz9`6 zsXhDhdaz^Dma%;oyfnGlKK*_VO+EYuu(@VzH-a-ZeI1)V@xKYIfAYQ=tXAed6|UaQ z`xZ3gYfs*{g3Vo9?ptna+1vNA+SB*#U~R7JCDiiR?gXo8yMtQ3G4D5hzjqgSHfnX> z56a8;gDYY4wHzhy2bZt0@5@&x^cBIrA6%I_?*|_xUfzHB{_(Mbt3O`zyqCTgZcOLa z{CzKdADVjJOWzN69n4=_-b+6K)|OZgf{m3mHr7LE>WTF*II*-P)+1nTd0+m0u<_M1 zuRj1g7tX8Wl#3ms{_*=E*tyZ>c;)%~mnXo>V6(mLw7U-KS%+1yuTJr`DkbaSG3I=) zL7l#yrk#5B&@*r~=OBCNNAPa=$rSBr`(v=S{N2~HV71tv1DCOX0#_^F4?Pc0Z0%|L z0$5vOzX(=~{ionE_DgWJcgQh${|uhk+SB&uU~P&03$R-L#^z<PW3f+d&aYZIziZKt zuX29Zggd`$Q>U+2Xs4d}eHE_eH8gqt8r}^*nW8;ye*@N*zpeN!SS^2B@jI~EYm~J4 zJ-F=eb+}sj-s=zW^rt;-{|MHW{@wtqrN2Lc)yn?fgqQuj1y{S1v1ELIhNnO6>F+OK zZRziAuv+^2D_G6`vNrF49k;n?cWu<lwON<GeU)po4&1d_k2?MTgLdk-aBdqw{VrV1 zbIHdXd+&jL`L`$9{z*|Yj@Z86ueo~SegH1xeh63dm@@9iU|+`7_7O$RxMJgeT66Wp z{R~{j{T#05@nqaD!M=>E?F)*Uaa)-BtD37P?o7RU#+@0i=CNel4zMrdYU@Q&Gp^Wt z{r4>7>WSM2T;|&suIAo1?yO*6#?>|pMa?*3<NEJm$kh{f4saQFPPm$T+_-ateHmBV zTog6qh>h#Nry*CD`*#}U9@@AaqV?}7ZAi@Z;TyI}`@7d0fo;DDwbw4~{`NqwUDp2g zfOYa-xYbAdysk~|b=C9rB4GEey61gkso7ThqG0<EU%bJWfZOIG;w^yRl3;z*{o5b4 zrNI8XAledVX|V0`_YeKRYWn8;|I2{wUz>9!&s=Rv+$|}-HlsLK?J-ZsTcA5v{i!n- z%M(LA$KDEXwHzZWfql7#+E%2f8Aog${+lLp^~7BjT*h4uuJ$Ie+#73veHmBV>J&BO zh!bbc7H*$+9OGJWHO~ze`&YA_?bB`@aM}O5aJ3vu>w|sSzqa)#YQ_;K&IT<!z5fm2 z_N$)$)of?`wA&b5_P+^SEyvtuU|;sHZBvSxam0zUc?(bHTh!e1aBI!w6!qk@CD=H| zOPm4v&|lVhE4bQ+Xs*XLU|;5=ZEK2}am0zUZ3|DIkL}?0YtiO<sM*f;X}1Ho?0-kN zn%5`$-x=)7{<ZByQ8SJ>adv6p>3r9kXFhg=>tjCJ%ty^Q#!H+%z-2yr!qvQ~G@rf2 zyv#@2UKBOsh!ba@7M{-ct$Fg<4{k2{X)_-+;}|b-4gi<=90*t2iniu+FxZ#*Xgi3a zW*l+i9MZzm`JoMdSk05)K)7x6(`J5Z#x=g&<2&aW-z)Ce%7pc%-jLip=WbWv?Q6UZ z^$rwc?L?jX`@zK1$9XYt&xu3O)Z^0yHfHHF6ixln`aa=Eu<g{Hqv6!PoFi?+C~EdE zPVA$=_FulgI2uhoJ|n>PU;2zhQ&0b+z_wHOZ<W%Q^@p5&y_XpcHW$aQzj>JJG1R`y zRi7~wHFFgwkFj8LeUp;88i%GHpYdRGEqx}SsVCQoVB4viYx=TIuE&DS#r*Y89=i~G z65O>sxz59}O-56{sa}ucz{XH_j3-e0a*W!Jr>Hqbv3tw;m8)kwCxV;%<0Lfo_;iDt z`(p~4`eSuICxdOLZa$|{`!XMGr%=@FU!2&dft&l|bTsw&oB?j`k2BHKGv{Z4ZKv*> zr!VWw`PpD|as2w5hq<0hom}-fhoWY#;^c82xVb;hM^lf_H^I&Q@hvp<<az<vcIxJu zzO0k$g<x|rfBln(`{Ubi_s1C&_o@5iA~f~vkBh;^P<M=%Qu}f}v|U0`bBtp5$D7#Y z>KV^v;O73g98EnwSAd)Q<4QF3jQJ|C?bOZZ8fstWqwQ*nn*ECt`&w{we_V&A9-r&M z&HeFRH1+Jy?}2Tn?wqGD>&*ELU~_T&`kRNj-b9^T^|_IvX0GDoaWlBNKc=Fo$LAJs zbAQ~5rk=UF4QxAgb4_2?$@O-yxtPEH$;16|2i*N}E+zZpPBiuGkGsIeP<M>?Q2TN{ zwB1cnbBtp5$2-{N>KV^{;O73gA5A?z4}hEd<3Tj_tj|MW+o_w+Bh<dkN87^`HTxGQ z_V>Zf{qZQ8dVGEWZtjoA(A3la<6zsVJLl=kI&=O*u(>#X{msK%pQKK%`aD5VGgoo) zcnaLyA5WvH$LASvbAS8@O+EYL$6(v3n``>APOi^_&BgrnPaf`%=iu&-3n|$jKS5K^ z{&*g240Xr&BDF8qL)!}!HODA+e|WzwSI>A}0yp=^&(PH4^K)=>fBXVXJ!5_uY&&)H z`4zP<^U?N8ikkh46Z;i#bAP;wrXHVPgPZ%~H)!hV|F>Y<sXOQC%Q|!Z8rWPMzy9W7 zuD_>FuKN6rqGqn*<ncPVxj+7ZrXHU^f}8u}4K(%a<v)RKr*5w4%R0Hf2{sq=*FSl< zKmH7Nf4oJV{qYyDdiKZLU}LB|#&@WFxgOg7N>Ou+V)uvdf8^>J&)>n#{qYYp_4vFC zZtjnNqN!)h?}2TnZa)8}_GLcW{zXx<e{o{J4{q*{|DdVI=L2wae|(6hp8fF=*mmm9 zdHS->oPP{97ss!^d6?^`)X7z!Pbg~UDo!5%1vmG{XK3p2`5fHbA77xUXRf{k+fLnF z)0cH}{R(U@=C6P9aDU9y(cT|S?X>+dGgv+QqZim1>W;BDb;hWzgQDgb#qJN^pUTxU zo<88_{^*OQ9-mpj&HXVentIk}Hn8o~&1Vkk<fCnNikkh46MIf@bAQZ*rXHWU!Oi_K z51M-Bd|t5a)SdJ6Wt};n4{R=uUw`v3*9EAPt3LBn)XY_!JQf5u_s2qL>hW0^+}t0F zps6R<MZvaHH`nxKom>|Kn~VADpFG?ji^DyC+)By$V+l0%?2jeE#!z>ROH=#uc-6KP zMa?ma-5)+LkgI1r%Yd8vV_7uy_$&u*?vLfs)HCK4z_wF2pOvVSkG2&lYW6Qq?3KaI z{jmy~dVE#|H}}VCXzJ;Ib+GN!o%8f%ojG3vY%Y#pfAcWcwWyP;K5J6c%vGE`)&@8C z$2w^0@mUw#+#l<qsVCR<!M0O3*YstbTsHuli}~xHJlr1}!QCJEH=BI_vN4)^_Qxh* zW2igE&8U63KeTO1QFDx9_lM7K<mz&tXXIJRuHbzrzILN*NX$OeyVuy~Dti=o&l>Mc zy;qIReQ%0=>`R?z;Qi^(SaSWhD!6gCDY$;y6<q%v8hoz?KcK-6E4VogY4BkUKBB?L zH2C-ipHy)3JE6f(Z1C=apA0^w;Ewm~f}aCEx8N6pFDbbGH#GQ@1$Vs97u<L+6x{ZI zZ}1Na?sz^axa;#}!L|F_w8qJL`n$9x_cv)v?(flt8_(aO4L4tZf41cQ_H4=h-Pw}+ zo3r7@^Y>;;?r+SN+~1WgxxXbFZtZW#h8xe{jt$=i{$#<`{k_=Ot^JMIlKcCxCHHq> zOYU#NhWl@a`&+Oj_jh2!ogaS#Hr(3Ze+@TZfBUuM{`PCQ`TN_i;qHeHNVv7X-x_W{ zhZkJk-)xQD+TUy~xxd+3a(}b6<o;%B$^FgNlKZ=@CHHq*!_C*<Z4Gz4{&s7)wZGk3 za(}xuTz`MNHQfE{@3)rR-)=3rzuQ`Jf3r2*+TUsoH=e)KT5^A*wdAK3-1YRgS!1{M z_gG8rZ?Tr#-(wAL?S}^Uw^&QNzrh-Ae*X4qxbxv}u7+FtJF6x4_f^CFzKy@H8gA|H ztA-DR`}?Zl*4q}`_S+X+yT7X%f7|=Js^QlDj%v91`n##&#`AYl!?pXnsNvTB7HYWT z_qR{O_4hYVOYU!+mfYVn4Y&69Os&0F^K;h$>`AYGekSX+O|ESLw5`Ej54Cxnlc(Lb zV6UOtyynTZamZEMgT2;j^ZF-`ZAY+L_)g$E@Xhx}c82St9-m#n<=;^33fE8lWS&Xe z=WbwipL^$f8N0)~;XYf}o_KqJwdMOUdxF)>*Xy%9zI%hsH~H-YR-0P%vv14Z?nist z?g!SEe)b2e*^k$Kd3+B9m;D?BS1ZSJFg)YYp0<a8wWXg!!D{y7{e(Qe1HolKhr`w0 zEXFeko_@5a?Ga#Y>1Qxl&3?R3k>}pB3*4XLJlWp;G!(A>Nc}m&kzlodal3B}?`_l) zV>q}O<0v%s`|21+gVhql`ysW&7zs8;`FYbQxO(y!4OUBx5n#2%I0oE|F&0fdd5i<A zC5HE1YKbucYz*f)^Dz;wo;;2Pt0ji_YHEow8QhF<9GZIaI3BE)7~bEhrO$7GJ(its z@Ac%domAMo?~}(irLc8_<>uu%{50?>lv}~Zm7iMJLEQ)`#U?m6tN+P-0Jm!DbV zv#H%fwmTQ>vF!Vh^T6JlTYpq_RNtij7R8tL3u?QyW0-<|A=nsq*L&yNU^UFG_Zsr^ zDaJCkIBhQl+tx9A{`?O35{kOH$<5Qg&BONAX@42m_MS(~<#Mpv8Q_dftsI+q$giL_ zp0#7Wiu!7bFYVXVc5D0de0VMRX6o?k;Mc+Ls>gmkTpxAcXUVUm7~8(YY5QHUv2qUl z9$YQCYg2O^H&ACDZUh_4+PrVpM)76dx72p)^mQwEJ4*Vx4Xoz#qWIhnKLH+}JK*}M z$LCJ4xy0u#uzu>fKHLrNCXRbbd)nRu)|P+c`(ChG&SlQ;eQ@Ka&Hdn8j8o6=18{xR z^FH@Mu(7nI-9zAVogRjl>+}d*AN9ofKG;~=e82nyYG1CSwnr&y&b>It>0{s=r}jU9 zHjksJ-(2$_g4JA~#IVkL{U^Zo;hO1deEU_uiQ*dDuQ+3T3S6$~({QzNO`n06Yx*O& ze(H(yV{o~q&%*Un&ze35?q*!BsrIz}30RwZ^hs*D_<8D6Yy1Lr&Mz;59f!4h_a*9| zQG7W!Kd<f9_Te%83$QVAet8+JhPgFI@}E+SWo&Ws`z6@C66;rBW95AF3fS|FdfL1S zR?l~jehoH`y8Gg{)V^FFZNH(Y*|#|3e+}%Il9xVm$E&Y(^7=j4ygaTP^Xp)>oC~z6 z**<e<T-&?f{s4B)&F>9rU*@O&M~a$#iZjkXfy;G&6RzepJ?9)X`}F)`d*h`2pTTDr z{4ZeVI&=Fr*tylucyfKx{;y!$=Unm*Sk3;=Vjesn{0*-DVV#ryYKieLuze=Rzrku- z;h(+xKKwn3dr*7Y{s*kh-2P52kL^Qndo1mLtLr0pVrYxs$6#&7_<&j-+o#|%xBtS` z%6rex;EAg}Z9fNV%RS*2U^V;sgjycoufSzLOkJhsoMjGXLQ6l|({^UCw)E2rtQLC* zxQyK!uI4!=u{+_3tvzk~fVCxdU$9#2vw+Lkv%=MUMxEHR!4q41+RhHvme_NE)%>2A z@4w~*I~M!Y=DdB$oT$4$ea|;HSS{Bd@1^HKQ%^thf?Zd+$Ju=FA@H2n=ZCB1?-UmR ztGUL;&EE?xh-NJ9`QG|MV0B~L_rhS;Hs8Bl1g?+z6mr&QQLs5`b4)&GQ_GkZ2RkPF zPuwNY)H9|f!R45if{!T1v@~2TW9kQ1YmR9dG-GMcn3e^rr|;#!<(QU->!Y4AtpGMh zZH~!jg=!hoN?^xS-s7)~rk*ja0xrk2Dtvq~rq$qT8Pn=uwdR=CKr@#1jA>1<dd9RC zxE#~kaDCJ>rggyPsLe6?yi?5>?$7nX{mCzXAG86SZQnX?Y0KX-YzX!@2(=r>=cH=J zaX)SZ9#)KVW4M~vflaA>c^y#Sgt9fo^SC(U*$nJH%6xAQ-iDavaj}K|l>D3cTY_z; zo_77gj;U-nK#h{|Yz4Nhy5l(ke>JZ$=4)=|nB2AjZ-q~M<)yD}G8fx|$Kab|b33@2 zbFl+;=0bgY${rN^6Q{o&!S26|X(zCAQ65h_qp4>ub^+T?J?(Y{I~QfU-O$uC7rTRP ztM2$t#9z(vnXkE-V{+RQoVn0fUi#W5bFmkA5<Z!Wz2R!k#lF;;3-x^{hf?fMoc{I$ zyKgh5{lU&fc^n>qrk=St5Ntd3v^xmwT$Jq&MpMsR90Injx^vNuznbGSUvo3Z<aQW1 zbD^)i^tDZV2ZB9r!Vd?#@1|7kbLt?tnts`5YVkh;T(%z!cmC6U2wY9StfN}mcY(|H zL*eF}_D90i^vl@QZ11^ZIM{jDHViBmA4Pp?tsh<B5d|Ju<E+IfxaZRH7#)qK9-lE_ z`zd{nfve}c0As<nQ+H2|r_P?zHjbj^x``8e0=OA_BAR-9js-V!oP?(CoOoY28SME! z=jh|$YMJxn!R0yn1h_uxQ|fj92H3dTGOiQB=A+I1lrdQ6z1m4&$LJo@-|;yIQ>Zfs z`gBv&oC9&jcQV-VmFI?2(A48|D%g1{eNKa`C)d-#wo|wNGpW<RwlgSd_AgHCv%t;R zXQQdd=Nxb|$8*utvj*pZ%QZM3u9h|UCb(RKZ^89ZpHi>E1z_W9%eXECn~yfvAY-u3 z8hjh<7@b%B9iP6LZ|nG81a>`KL)#h0`MQKU^QF(l6gB5doVmCZ>|B)RukWC#$LBJz zb6Wab4p+~(t^nIk-TtqlPXF4jq^Q}yII*t=H)CIerXHVb!Oa}6LsQRsT@NnT>$`BZ ztk?Iz<$B!!*GGLy)jn6=2sW;^jO!+_`Dk+uG6w6c!OdXD=)CIh`1H+uTgP`Q*!6G? zZD$<k>sIQ_mp->pZlgF~V&mx}S9e^VKkop0{>(V<gnRyv{VsTac>b2{Zn&C$j@uab zfQ_TgbMNicYKd_lxa{M8_=!ay55UVl9)zpump&c>8%LXc+)J&NJ{|#=eS9C@UG(uN zyzJu#a5eqX$75jQXtR%psnrHBPTvzf4t5`v=l&m}smJFDu;VX%o`kDsPdo*-ow{rH z47D%sMYTOmQFE=tiTxvRGxm?s)Z_CkxS8W~XzI?D*N2~g%f0?QTur<0qh0`)d;LYY zKI&7L3w?eHHm<ge>m{)HXmh`14A$AdKLa~P_n`ic&pG%7wJ+yDpPy6IoC9&j_cGY= zmFNCnqN&H{S77I<^mzrYo?KrA+fLp7e?y)Awf&l+X8+>E{w=r}`!zK6`1}ss%<=bV z>RE%=!Q~qK0j`!c_#?PngE!#%s86Za;7?%VYRkCZ1e=dG*C1oC&KkT0c8t!e{*F)I z%(r!X{|t6LTtnL#$N74jI`gH^UnpwMmpF6rSFm$Yp8MZHQ;*Nzz|Lvu^LMy<#`O=d z?bPl6pVaAJ+q)Ds`xhtnd*Ej5f1#<z=ilIFj_;$XXTAOdF4yY=xLVfhLvXoXAL&m~ zpHi>a$6(`X%eX!Pn~yfvAY-u38hi?NjLxh6j!)mrw{?8~3wAwRL)#fAIerHA+@8<= zK8LIMxm}*~e*rg!wzT^aoNI!|{#S6{Ut|oPRP<3#oSD#!rOox~<%x%v$G5hbDQd2l z*z@g3{CzGgKB~s%;5DWLAJ<XaFlxDTkQmlk&)#6yvpffPqN&HH5BOf<ls<jY)HAMG zz_wF&46{-DatzvLrKmXuabnL7ZpNMiO+7wyf}1(cg{JP9sj9j8U%BVzfvaU*<^`8~ zZa%m^>Qm}HH$T|8+A^*Mz~-aPIm{TWvyT=8J4WYKf5+z>EKKdoInZYzikfpE&iEDq zJHGN9yeOJ_d=>*cPo>Y|XzIyz39#+d?SCoi^sjA6ikkh46MJcJGj=~T_4q6UZsxcw zntIk?IdHiK%fr>O1}lKeHCPd@kNT8)4ORjhS6jxlGT3~yxds`7b=F`Nuw!&y^>=*w zX1=ZCyDHfAa1Cu|9Or9w>dcout5MXPFLCB#4X|@jo`cs!Q;*MDVCS^-SsP6~<5~x7 zJ9YbCk2?KpTbH6{|Kh}6AKZ++0h)SzHUu|w+z3rQ>$NesT(3>wYFV#M!R2~w2G>V@ zO1)m2gN>^#<JtmjKH6M^jKMl<uqD_rI<NXWK7BLa*75BRc0F7}+ZiW04gjCXTI4*v z6<n=6Pj3x3hPJfZ25h_VZMDNQhV9_`sOLPrJ=j><T(2FevtHVEps2ZC;>6wwT=umy z+-t-`%%RU-cY*7pZX2~-!JgOi+-*0w+KqLa-NCj~ciz&kb>?jkuz5L``kRw^??vs) z^O8P$Qq;^_+`PUVO&(rr%+2e|-uSrxa($7TLt<EGAMOKoAC}jSebLn8vmf|j;*~!8 zqp4>-4glLu-7y?Q?aMJ}JCLI07{rNvFt{1}5H$7p913pcco>?xW2UMG^1t#}IUKH* zH68>mkCh|f`lwH-kCnk-<7&&ehJejSn{${kSZ5u(z>d**)!*?s2S-x-at`zvN>OtT z#2Mc(u;VMQ9mCPo<8u_)c`AL5MpI9&Bfz#(xBpSp>0jGOikkh46MHnc8G8(xdVG!n zH**||rk*tz2QJrOJX|enFacby!9=(|>Qm}9I2LSNZ5h`ju=!|n4KfDntifckV{~5i zcYOM0zOCbX9N6`64Q*!}=j#OO%$GjLQ`DR<apvM1VCSN|cASW&9-ouI&S~k>ji#P) zO#$0Z-TqIZPXF3Yrl{G!II&L!H)EfMrXHWu!Oa}cKvU0poe3`2>nylh*6VC=xnAeM z^--Tvuh+R?<7&&e&I6l|HrF6yu+AEs4|a^stNxBp-^{mle7^~HJzPWE87Db@3*60G z<oa>}T&=vmTnIOYwzT^;*mmI;!OQE*#c+MpbA7o4Y%FcA*LSG1UfM3DsJUL^#J&t% z_H{YDyuMrk*GJtpUSF;Rm)Do8;A*+PTn)CJy7QKPtut@efX&Of)Zd)U`#S36t<SX- zHS-oH@9V*3-rt3v$eiW6_&vBj>dE^Cu-Btp7jJ~CCGVTSwo^Cn^lP2GZw8x}W6|H7 z%=;GV<gL$Cikf+go7cq=<WXK1Z^g&sCf7x|IV6U){8oI7X`ON1hRyeM=5Yr&d8pq` zQL~NMHeQGC0(%VRcb@NttNDs{Pp!>VX!q6{Z)K-_&*45a+v~60G2BV5ZhutO1N_h9 zS=;?!d2)FOtbcqT2J3S=$1zp)2>(;_e3j2yz7JQojqjBo1$#aS|3QO4R`Yx}<8ioc z^wXB-u0I58Grs2$=jsWtIchWi2dUM>Pf|ZcN$$^p{T`3Dr@?aZkEp#z5&szcY^^_6 z=szj&3*eP|wf$c#@K3>h-sWC-3GBLB`#rXwQ~!eEOZ&^U-P&`n-{<`$_!QdveO`0+ zc>WcddX9@%z-k%Ot6=jF|25b#<ol4n0qdil^U-g?#?j_IhWuv~b2Mjh;=Kkoe!f5T zJFr^5ccx8EfB*fi--DeW_k!#5I#^A+d*KgY_d?e6k8pj|^|8$xVE2F4_)l>C)LkR@ zqgwpm1ebgCEqJ*{{|r|v_vl~X>dEVEaJfhS+TichJbUzSaNFpoE#vt+Sex;a|3ARy zsLlM{qiV_jJ+PX#e^Se1`#0EUJ=*>SmTTLZdHN67J+AG2YI%NV<pc1J_!!T2+Vy*v zTAMMbst@^}TE5Hp5m?RR!E@FpU|;SNZ68y{^l9%CapHUd_L$1|vc3d=PVqZ++T!;W zSX=t@OWkVeZ)UhJ`_ncPMa_LF_SnfjRd-As)b^vTckOHKao2~sFU6PkS!%nrIZZ*I z6>N-re{?pm+N0RaL*7X-mU)QNc6P9Ba}3V`c1_gHP42bCzRkn-)@eT{*!CV@<}w#p z?F?|nrdE#4JTjm2fXjKG7oK_77Qgwx+KlPn>d9l9A8d^91>pMRm|qaA=6i^&??UkO zqdjdG25ZauE&?{bdcIq=C|KQiu6w=%w^*%dPrSv!Wo}Er%iNZPt9fiEx2538O?zT3 z4c3<2`hktFp4^rJt2c977R^4iXI_>Ao3pm`u{^lUcLjKv?}~7>cZz&hf+t_?iM29V zTk>56Y<%_PyDC_{neS?7_Mtubt`0V5ZRukTaGCF#@G{@E;A-y``K}F5zS<LO9k90K zyDr%H>dALKuzEA!_0jA@d-B}?Y|h%!$A;iC-;Lm9z8k~UJ}mOx1fG1gC)TE5ZOL~t zu<_NC@8)3jX1-gX*@yPzyCvA1wWW{#;4<F<@G{@6;A-XfWw(YWU+syt4Om<9-4<+o z_2j!9SiPC=_GtE@J^AhcHfL?=V@GhA?@sVC-<{!Vei<>x+b;0rt39!H1#3&byMc|b zo_u!)t2guA1I<3PC*M86=BzD!>;*3K-5Xx!yAND#E5aq;ec{Phdt&Ve)|Pzt2OD2K z`5pjPZ{~X-ntf<bz6XKLS)1owud{0D?_jW6{+99(xSFwZJvkKa^+cO7<lbW@#$j;p zQ?+@IDvxa-*tyZBk36;`z}_Qi8w8feHUw;5+6IH=8*{hd{aqK>f0x%b+VnY`T0QNL z1Sj@TuspWm;KUvVmM8X6U}M`xn{Dj#Xt4K`&XaruTup!b*QS;}MuP1>*OgIlHP7Gr zYg3E=Xs~-moAV|2dh5N9*XuEb?=fK8XOE19s~Ow-rSV{2-Zy9)M>&IH9C7-b0513K zM7Z;ky>l#FANB0pN#N{T?TIxRtSx^xbsShN_f#i<lasdNDQe~<&R+WlIPX843whoL zlUj8myv+F|c$srITp#u1d@?vWYfsLnfVJ7r6l!^X3*uDpZ1ksYZvK7uY5K75&j8y- zuAl3a`$5MfcMTky^Pc|B0++d;4KH&)2d<BLaz7WG+_fjxd0=hkaVE7qw)4SiiSbQv zVrYxsx4_!6W*30fvS!}~`*I&?yO5&hxWtKb5!n5h_v07C)yloD7XM4Y=4bBChdj3L zfQ_Z?Qm{O>%fUHrF9XYS++G3pxV4Qo+jyK_3HI1@Ps^`@tLbka+SJ5XQ|BK38nENE z_8$H^>gy@KT;K23c5D0czWIA#W8@zG2C!Q0;pNv-jAd+b+TIAZZH|MRz@Br}%}t(r zc=NEmb=uzyw!Pytm#JX2Gr$>}nz?6e<{|f)fbm@0a__o_jgPsy73|#SI&m9Zt-Ma$ z4mW3Q_9-u~6L-SPeR3CEE&Jqduv+@O7o7FJ2Q1He-v@TRZKEyk_3sC3GluW=9{`u{ z^&f=mqi&9OP^;<h`~HW)c^@x-1g_5%=2iZEus-Uxe~4Pmb@RJvKLD$F3?+xh;OgOz zgY!P$x&0yBdC9Y@C*W%N8=EJ=wo%V_(VqgVFV?FacK~soh7aNVl>3Bd;A*)~Nc<n6 zX-oVcgN>)|IGwj=!RD>aaXw0|mT~?B>^O~`aXk-L4}Sq%j`Kx$InJNL)sn|cVB4r? zoIeArm*f07+`k3NIDY|GYmW0}G;N9hOR(|OGtOUu&0Cw}e2!Wz<9rqDINhTe*RSE~ z;lBZw<NPhW9Or9rwdC<Tux->c&fkO8%W=LAA76~~4{){SIRA*IE%D#bhoYWw{t0Z} z+8pOA)M}2wz4Iox{2QIO;A-Aa{Ds<=*8%lEQ~pEooFUFUybX4rWbXb7-lmoRbf0(7 z)bqC(e*@c2J?;Ju?%!zl4>a}6*SlcbsyiM(lTb@8{{*Y$bDj6#YJRrjnEnmUn6&+i zqUM;yiSs_#&sNfh+;e1nt>w;<ZJn32{Qz9Hm6yJ@(bxI^5M2IU&_{5!*7Gmw<f{HL zrFY+Uf8zA_DcJp+dHgTf`7e*r&(PE}|DS_xr=E6SfSv!c-Ir+Ung6fAwpDj-{A@)n zx%h)rYMK9;;A)xwUUFXUDQz=T)SN?c;&gyBhsKjThw-(Re?s53bzai8v(Z*w`r1Zc z=f4lONyN`H?!Is}=YLjeU*@Vl3uPgS{fX1xY+#S8%;W5E=f6C6%z>t!`JWSPJN2}i z3+()t?dC>P&-~8=wynDJ-;KXoa+w#bmieC#u9o><0Gu&to1dcQn8b;*AUN}HJh^ii zUu(H@WLxJYZ5IZYZRMq}ZQ{Eq*yA;PF}UkJd)23PJz5+-6A3R*(N}wXmjIhve3vYI zZKvHi^54JGmUc^l%RZNe>yv*^r5{)yb@#!t)V|yY+LocHIc~9i<ol9hKTAB7yu^N< zCwBa4W1U=<13TXE<>6&6E5P+pH<y*DlZ&<$DQe~-PA=)+T)cm5=8`tn>3e0c^BKMh zyv$`)xIXIUvO0Bg(Y6{z&0NGY$|ZT_b57?aZLHJx8sK%wJ$y~LxlF0=Q`Q2j>1RLM z)b#g$ZEdihU4*X#-=-Mbx^UaXz8<(g_I#GIK3q*d`!wbTVB=_e5N$*1jVSh|?Q;6| zoU(DPo0p%<$<xm!;4+U*;bk71!OJ{0hpXwAJhlKEN1J`LKBECUmw9erEzdo^wfrS& z*T?s*=48J8Y3u&YeboTCTJAUEw-wqD<|uw!!`0%K=Lg%Mc@EQ_=OEjHjjJv3wgbCA z6K{LCTH?iT2ek6OZ%4RV{L=4EXg<f)o_==*8&_NWb^)7@w)C+p*gYA(8{B)aTo-nS ztL1adJ;1h6PyTy?)th<kg=U}HT`&LrJvIAsU+oQc4ZRMm58nsw^9J9O>Mz$vf0nJ< z7i<jux$IQ?f%W&_d)HsCPyF`>Z-+hp2h{%O*8XyRlFvcl{<XjP99;V!NNs$%KJKSG z>iuM${tm%b{@Wdg!quD?+iO#^eg5qZYx#}T?$4X+{{3wFFnk?f`PuY9G<DBIgQ$IZ zepWx6qGlYiaj&Z5s+*_pb%ucVLQmdZaOWxeWGGzC&oc5%<w$rp+_ll3w!^^M<Q`MQ z!R4`X6kIKPBm47cG}~&=`?L{Y_2fAcyaRdVK7SNkA9c?Oj%761@n}oCW58v*vG6ez z_1uSy1KU=cYcrTyEiop551?<kdv7AVoTFpmY94o)qe<{?xO1dEZ6|}Z$(^I)z~ym$ zJY20gM<<}!R(s~?8({V1c_O$R>q&5Z)H6rjV8^2^?WTasb|=G~BlXPDDPY@bbB@Mq zqa?;@;KPbJIvrll(HU^H4;gdj=uCJw+&R*2Ea&$uur|4KbT+trFL(}ItvN^MqS;n^ z=IA`Idh$FUT#ogdaDCJ>N8bWF9&KrN0k~{;A>27q&m4UlY+G&4(W%sG;)|$Ht>?!v zT?`)v&$;yyxSGfEcc^`NEURBixt8LwEKW|Bf!(W~(|rDNId~glmd{_VKvPeSSAuP) zo_1G(`#0KMji#P^?rXrdRd+nzJF0nJF<)~t$K-Y$IQPH$%1d9{=<8fu4=&&TeHX6g zT--qI%eheh9_4n5{fX1xjbQg=#&i?dxp0rf=VmnZ%*9l&?bOrm7O-<sw!0NgJ#%pz z*tY7<h4-#%j?a9}%^cJ39pKD`zVg!7Hkpe%!R33gyWnch#XZ!%oD224DUVR>Pn`bl z1)oaEnC=5R7v+1Z`_a@h7Y~4Kr=E5Xf}M-9-9u>VnTv<PwpDj7y75<YeCBIz=9t{R z56)cZD=&R*6W>R{<$IJL)NS)`v_A&dM?GyG2bb?9eh9a}w0Q!qk9zK7o&+09TjD$g zHox$v;boj>;QFX1&X2&x(&l<SOP%%7_G8LVD9(x4ap#(>?)*JZ?eQyqp};TJIQhH; zFX!fGaL1kRc>Wx&k9ykt0$jFv8SWU<=9h4N)H9}EfsLijoPJ8JmYA=C%lZB_+&&WX zH*kH_)8@C}vdwGoGLPTE^-)hAzXuyjn|ZuKt(KU702?Fxk8tzIGk`bX`l!d}PvEl6 zn{e|=o44Tls3(s<gN>!lJYJ_(Gp6UVzkr>i+z-DER?D?2et$(9LSONF2d);s+<*NI z&Erpd?w9@!Hm<hB`v=%LNxXN#YKa%Wf1;K58}Gr@;+KB^h35T?_VoL2uyM7;?|rcO zXiFde0Xr|@AArmE5g)?UGN&JbZKIz2KL)Ee^ZEqMKD9gl9xrP4<vrkk!Q~$R4DOod z`N-$+nebb__SK%YUx2#{-!BVa+iADYPpP%p&i5|WEba4a;>-lsC-#}){fV3R)xF?q z`c2{5ZHx}EakSaTSF~3%hWn~FxZGEraJ9@&&e?s?Y^$Dp`l6|a&jR*-Hs}6X;rgh@ zXEw0+J2}tK4%bgT|0dQPVCT}JeI&Vh|28LBTlURdVDnYac;*JXU&H5tyJzx!^LgR= zsAo^i2Uc&6d44p<Jhd3}0%+<P&w^mz=VZ(a!Szv(&%)qx%!|PFQ_q+e1!v6KGv>v> z+A`+F!RD);V`T}jbD_;O_WZ7vIam_x8iy|hcaAbAOT+b1&z$rFt2gIl88qjlyml{( zrk?RG2R^KrljY(1sK;joa5*O{!u3<noU8=SoM_LStPIwcIavj4zUmp{s$kbW<5>-^ z)*R33Xw7}S2AX<uT@zgH>$TwesK;k*a5<iJ;QFa&JnMop9_<;=dSGoC&-!5VRnHo4 z0Ct?(Tw|}>YWDB3u@TsH58oKB&mNoy=D@xQTp#uLYzFqdl<_tN%f<ei{`$vnOR(od zZT|cI@_Zk;KX^Xk+unBC_49WFv?az?;4;6h;bnf?!1Ym2o9)2KZ(A|N*xOU<AHN;J z$!`a+-26zn+6lZ2we4-E-53L?wHZUdoxy6m!~9OeE?_l_FV}5mir){~kOsS=>*L=G zTtSQh*mi@fdylpUwJ-0f)pw_ir+AMhPVRexovVCbWG}GVRN5M6AFwauXxp1Iieemb z;_M4Hj$?Dq<gx7sRtw)BUj9bF0dRfP<8vUm{EdKv;QFcO`w9nx)jg*2-un=EH{AE$ z+7s_ku(tfWori(d%-7>a9^Zjr^UdBr9IiIC=w}c-{b*0yBf#3y&tR~c{dk_1$9D+0 z?57K^R*q*VJpE`-+atl+($6rkn*DgLkjHm8xa{XBxSHqC%-hlM^rJm(M}W1ZpOIiS z`|%tr_kQ1f;+}ACXd6v^48`lW-?JJE_Br1fVC{14<$DEV$lbffa=#{z3E*;{PK2vX zC7%0q64;mfRNJwXrzpk|C(dzT=fWH&gXQM9K5b6`o8yKQ{k?zr2AaD5$5YD_>qM|Q zX)~rgwv)hW;ob0Z&rgBtqaL4=!R4Mm1+JfZ_WY?}^>UA#2Ja?U_q_JRI~}YoYj*}% z&3xVS^7x(!F89b;aJ8w#%pN%#o_@5a?Kxm=>E~Rqn*F%v<?%faT=sK5T&*0>H{t0= zd)j^rtS$Xq09Laf_q;s57lO-vz71C^_xwfh^rJm(F9vH%KbL^j?8iMX&z`vy+}tzY zK~vYqXZV+iDO17e<8ruqp66WwR?B_qm0-2kIO!+ORdC}tSBY~qTs?8F0jnj>wP3X} z&UJ9(<Q~fF_w{h~#Q82*EpfgFRx?iiR_O+~dD@3|pJ98<+z56Kv}c}f0%x9_N4b95 z{T$%t+I~9ot6g4xM|3LO^~_w{Qv2s~4!J(gi#gm1?qB<RY~NP<A6VZ<$o0|R>+kJg z=fu7}cgZuycY@1%hr8hAy~EvbebjA#2en#qxfkp`p0<0y^2EL$oO_4+z;cf_pL;$4 z&YVq!+s5~T529;}-$R98_J)2Bqic)bBZXhqUcc|7Ys-7dN5S52tW?L)9@`HJn|bJ) zXCjY-wLeDjocsi}FVD%^en?UCoGdQS{p#{bwf!mT%-_>s=P!Hd8MyP}`OZ0&>ytVC z5!gA+UioqDpU=?b`sj~a^(@%6*WYW^b714=S|!&f@qYp?_rvq>azDHP*GJu${w~yu zU}O5dQFE5-r``Sk)7tLmVA|#7{(lKx?*E_F{@MR>eKKc12lp@b|1WC)?0>mFnWJBd zDeusK#`!C_dd>;2fYowNconSXIU(;qe+~ZxuFY}0Os!@=9*4gLXHO^B*U;3H%kRXL zsYNcohpQ)-*THJZ<qu%B@;vuPxN&k!c%FL$uAVr50;?s?n_#sv&RcNf<d`wepW*6> z^B1sM;=B!3E6<mIg`1~+XwUib9k6qt-8uUWwOZ!q?_f2#$Ll}9&TF2#ybIPx-S&T@ zR&zc*kNgv?HWi#0@4?mM^DnSInJfGGH(WhF@7F$=2Yvp7rk?Y|2jHALY_C1G4-1?9 z>zn7-AAz-d?l4E+&wLE_H#_q@?Gw0u>YiWzOYO_^i?&ZG^Uc~mzlbw`pMyOXoSV<U za&4~Tm*AX#zW~eqKC;)4uUeSz(NSx&y>ZkNyQ06G+qc0c&wR}U)_*Fp{?6CTXzKa* zA$oz;{0^7#hv2W47#-kdjNWMK`A$<OSS>Mz5koC8`hbm5u5Dj5_2e-NSS>Mpma3K* zvx1v3W<yg?9<zhh62s5F)DmM3urbR0GbfsQ@|X*(mKZ)?RZEPy!Oa-+ps6R1dBJLl zF^L#zUSHfZUVq#t<@HCsy#7q8`5v{uwRS)Iu)VeXYGTW+<yX|)&p)!}3(!~j>~=x; ziP&>oEClzM@!74u+S7JnaChOmNa1Tc?U|cJ!Jb>+>eb#$a{Z0vUSAA+GqwKSmo8rW zV{Yv|xjx#xCM{9hy(SsMV{%C}^?bg&6j&{7mIj-H_i<^{4^2JC@iJiBse2qRNA1hw zSlhA`HRn~F`<Laxxpqv&KXbGKy0-YOSooEDekF8m@msm@EBE9o=-RSAtAcY*Glurq zRx51gp>OVoRtIbMoaQ*!1p9KF+SZ_`IZkora4oRo%)Nj-_X4ZXer@>i#MFO%_&T+} z?^`{G$n|kQCcd@vwF>_0g6}EXuLrlk+)v5%(ck-{^}(ZSfA5brsQq()B-clO_t}Qv z$+f@xY@^yg_bPII;=eKYzQTW#+CTSea((poS>mSPJ8FOLtv0Lub8jWr$MI($S=-*< zlHR=b_jjhn`JL%iupRpUx;hW&Ez2^DXIW~t4Q=nvp?_(Xk=Yak7jB7-f-Gh4p~zHG z!4gH>I0_3<9H^+c_uhLeF5FsXwtqi(FT2n8o%5dOx~_XX&;7p7`@GLL{=ng@C&$*D zOUK`<!Jg~h4emkPr|5mbUdMfC{lABe+m_t6a$`FduD)~O+WQu+y<g!z$M-8-`>?`| zA5*yYv4zj(`c5cZ`^3VHpWMQy7H<Cs74G_QaKqO=7r{%>#MZe9Ymn!^6WH@&>)%{; zrtQMvOZ)bX-8S=K2e9i@_>S;1;Q6;lc7p4p?!6@6j>FvcB~ENtu-7l2<?RAj^KX{p zvn$+d6`$R}`l-8C%)xi}wf1%Qi1x(p0oG>SUQc;!dxF*SH=TQd)jUtG2i?HFtU=q} z9BS4e_WYzK_2lgiHgCq(13Z&F-oM)7*AuKQ{r3W^rT;!)U-qx9H^)E@`xhtAK4AN^ zM(3p5zo~2^c3<%3wCeh+^#^;O_?|#M0Ir|9Ih^NeV&}B)7p&Fs*tcUy--E!l*1_<Z z<g`|8@f!lxmRg5`)m;BQ*9U-oS*y1FIn?Y=oIJz9sdX4wo?1tMtySIcRNBBJ!9E+h zaA=>=oP$wdZK+poAMNlP4PH!}`sLQ2@z~b$;d#mU#(^_F?{9g=Hy*qtdDYGBdZ3or zNnq~<ZQlEGZEa{%z+N+Lt^@Me4g`D6w7Dk8wOPwFu-8zV>w{eE+HlDFj%}m0YwmP- zH~j6_{N~YLKmA>s^vN@D23W1`J!Znyv-g+<R`WYH$1)qN=6rJRm*?XgG;`I@bq|57 z=RMS+U^R23?!&;Y>)~_d9J%&~gLCb*Eo8nsjw8UvYR^95NO1NL+8tl|o(H#oeeA0{ zIp%|XzW9Am8|_hWH4k6rBE<(|`yIO1JMSrf4>m?U+R<S9(w3SQfK!uWKL&2@P8{0e zcWjH_!s4gRK8!yOY!2=DoNy6XJ%{g++weUe%`s_DKPP}Ya?EOcP6Vsz>pan>roVfQ zlfc_@WbHl~tmb{Mzc#h_p8{43KNUO;-{thzk#;d$A9dG_(`kLVZfHA=L(O$VT-RuI zd6&j+EAQ0s&a|oXOt7`M2NBmj$l!HdeyBff_8<cq?EY)N26vzx*kGUMgE$=55L)*f z?opPITU+)ZD+*V?sBrVGEPNjK@1-sL`oi54+||OLY2oh|ZvKro{{MLFf0M$sw=3N7 zZ(6waFEreH+xWA{@A>eVmTUSaH1&Ko^JlPHKATwzR;!=!oDDZm-Y+<}mZ7O9&pBYV z<T)3tR`V=}n`d<y&v|I-$#XtfEqN{gtF8O2XoI!)|AlbJX&>5M)11#<Pi?97VzAd; zo7YmF=fNf5t+1(U_u8w8z0U5@%rgt0%i!~9r#Jj^xSGDs0l9N|6|Hm3*8SX-v{!NX z(tdSgw@vPAz~%_Q7HnTDntSd#xIXIMXYwmJ%xz!d#NGg|<Gc~B<~W_3a>sEKt+BR_ z^A_4$Ieclqt+CrC_w8VFgx>+K<Gd5DkGkWO-^^id`w|=5jy~=NFQ84Xd*Ggf(T)9H zuv*s5`@qJi8{_=DAMCZwp5_6#TAk|;w)i{*S92cc_cag0jn$UikAQ3LN8xJzHZF0G z!Hw0HxW~aY?g_ZsyCv>PxUt&uY<>!?o@aCFej3f%wR;U+Pt@$s^Y|>dp2z3l^*pYI zt0mv_U}MxX<`=+q%rC;#>OJ~Wi_gn&wKb)#HE?6KrLI@>;b^VvRW!$<-MU;C)l%1M z;9A$~aOYm;#~Wa^)b%FV81>Zk7P!{+He9XFk9S&p{sLF4^W(2@W3{EOcfsndb^Q&^ zv1m^%?}4q)XSUbu?_f23Q@dLH{{gPG{}Wzo{})^>wf`GzjCyMS54hI;U$~m{H$MJj zFV$x~xLTd7ABG#NEpZ<K*SPiJYR;G38y|%mt1WRK1J}3>;A(XaZ3s73Th8@HVD;8> z{c$vF*Y0_IAFO77p65@1y<fsV3HLgLe+q6)_F<of8>62#bNW11H>Qo8p8*e~4gV}$ zpX|pz2i8YjAJ?hRgWaE)&*!;Z?6X{d{oK=T242E=wE0|@r=Kr^S2Q-C@$zk&z3-R6 z{fIZWIgQoFSf5>A1}~z`z4H~gTI&8PSS?5PpI<{WxAu(V>)@4)BlUg*uBNZ!)~4n& z#OI0YzHP?xO>E9(_oI&OTX40xVB@u^)n}B?5BXKJ=Ce({Z{zEFmwexWt0kW{HRD$` z@mDtSZS?tFY>wG|rnv4ihhg_Mlq37h{TtkY_5cpYGo04_V^`Yt<Z#~=zC{cFNelmZ z3-8>*_iEw$w(t=xd~6G!)Ns$2bMbp{YsmY7Hn^H=Vm>eVK71y8Hi!1a{s62kzx&u6 ztmbvIZh3rv2(JBX30HGnO+P<^ryuQ!{V`Zu`q>JsW<Q=!d3-y7Yd=4QtGO1XpRM8P zM|)y_2G*8-wgIczkJm{a-(P_3C;XT2`g^5c!Szv(&#%Gt_e#If#-X0yD{Tu_uji#B zJmb}#e4W7BGT!aLYL3@=B-huquM5~~lGyFR^*rqWS99&ndD;=4ezhldC$P5c&vyo^ zrLV4F`_J=e7qC9+dFJg3c1+q5w>!AT?E&A7Lp|S@?+G?mn{|4Bs3phVVCO`}+6`Rm z{4HF~=U(dU4o{uh6War<Ep_$;tEI1A;5y#kaDCKMXCJU*(w4Zs;2PHtZk_6>b04s= z+N{(2UM)HLgPoHZ>i}@Ab3eG6&+gPY5S}`<Cw356Tk0GPR!d()z;(Ps;rghj&i%oT zNn7F$0N1!-aO+f0ox{P#YO_w)GqvOx32tBbC~(a=8g5SY<QxMwPMbML(5fZpIPeyQ zj|bPB6X51lPtJ*8<FuJ`EUj8{P6p?Cc)v}7*PK(~=2TD41Hr~=Gv_2)wT?UsyOQG| zu+J3N;`B2OO+EZzu=VA0v+3aV@NdtdulD%P0DHg0cP3b0zehDrd-|RQwr|&=#Lq@k z51#|}JS5*C;PkDp_V^wOb`Hn)FmU=dPJ8;E3%2jP-|&1Mj;5Y`M}R$F$#*0;ee0_| zzVpD&tN6|br*Gr5XYX?q*z@A}^m8AemVLmcjAaamuMr&X12&@_*<in48&&XVuzP~B zwASZd;Aryclk4hpcmbMv?!jZgYKb`(Y_1x!5KTSLj^n^;UbEy`1Xs_wJs#{>lgD#= z0-Acx&xzoiALF&hc2Z+=emO>cGscs_)|EM9U8kU_XFR8Z)e^H9Y+W_xG&J?pbvjtB z)^!G4J$0Q4wyxx{u0NouXY79jr!M2Q$F`)gS(jtf*T2Q^dY=WhZhf2&^2`VKj8i#$ zjpJ}Wbf6vIV6XRtf+sdupGgh&Gs?+Dp8|Hy97vme<5K#}KGN8WTKIJ>{QAO;yRmS; z+q|W4?Y9<g{@YvlorQPBes|%1w|Q^j#y?iL`5!ObdY>v>|7Q!=|M`Yzo}3N$9IfH- zzIJXcLsQS(ItQ$l&k4^3tNA%$*4*WA-#2P=&Go#hWvw_5td`%`TmV)(pW{9JSJ3+M z^DJ!_a;SN|#2N3!V8@&L%<*1=rk?Sx1gmAdmx9&m=cAXw&69a;p3BkHlV=rJEqSg0 ztJOSL!p)O4)jU_BsVC3XV727A2CTO3bJlg=-(3rLoc5vJbLd=D_Z)gZ+yHj|YjYmT zbIoo7dp~G%PRjH9v76Uo-Vf4h)5m$Op7`6q6PtMFtUUeR0rs9U&iN~k?Jlsnv^kgM z+S=iN4>;d1I<MvWIj8*{NxqZ25AJtz_G^Cg=&zst-c$NG2fQcl2dgau+gC^02jJ@Q zc@V5m{r%5FaP@q4@-Wyqb?4xtw7#5!+8*Iha}J6#2cH0&dp^GQ?=^oCuI_lfC*}Hk zPd*LSe{SQyA?-78b^X0(<@$TiJ_pv{_k}sntKsVUdr!+Vo)^IS`#Y74=S8@>{@(NQ ze2(!F*za~6r+u4GpY-)I*tzHX4Cmb%urcc9a}839|0`hER=L;xRrpeltPQV$T^rQ% zUE}Lu<FqBu8(?!M&zoTLB<3x!KI*fYvAqp8mo~@dIMn<cBG=AVp7q2weZB)W#^;aN H=g<EDF?wh9 diff --git a/shaders/rt_lib.frag b/shaders/rt_lib.frag index bc293db..e2acfd1 100644 --- a/shaders/rt_lib.frag +++ b/shaders/rt_lib.frag @@ -36,7 +36,8 @@ float pos_infinity = uintBitsToFloat(0x7F800000); // set limit for maximal iterations uint max_iterations = max_num_lights * max_iterations_per_light * raster_points; uint iteration_num = 0; -uint max_num_compounds = scene_info.infos[6]; +const uint absolute_max_compounds = 10; +uint max_num_compounds = min(scene_info.infos[6], absolute_max_compounds); uvec4 unpack_color(uint val) { // left most 8 bits first @@ -311,20 +312,39 @@ Tracing trace_ray(uint volume_start, vec3 starting_pos, vec3 start_direction, fl vec3 color_mul_transparent; uint next_volumetric_index = 0; - uint[5] done_volumetrics; - for (int i=0; i < 5; i++) { + uint[absolute_max_compounds] done_volumetrics; + for (int i=0; i < max_num_compounds; i++) { done_volumetrics[i] = 0; } + uint[absolute_max_compounds] compound_starts; + float[absolute_max_compounds] hit_factors; + bool[absolute_max_compounds] is_x_hits; + bool[absolute_max_compounds] is_y_hits; + bool[absolute_max_compounds] is_z_hits; + bool[absolute_max_compounds] hits_inside; + while (iteration_num < max_iterations) { iteration_num ++; + for (int i=0; i < max_num_compounds; i++) { + compound_starts[i] = 0; + hit_factors[i] = 0.0; + is_x_hits[i] = false; + is_y_hits[i] = false; + is_z_hits[i] = false; + hits_inside[i] = false; + } + uint compound_num = 0; + // go over the borders by this amount + float overstep = 0.00001 / length(direction); + uint hits = 0; while (scene_info.infos[volume_index + 6 + max_num_lights + compound_num] != 0 && compound_num < max_num_compounds && iteration_num < max_iterations && !result.has_hit) { uint compound_start = scene_info.infos[volume_index + 6 + max_num_lights + compound_num]; bool already_checked = false; - for (int i=0; i < 5; i++) { + for (int i=0; i < max_num_compounds; i++) { if (compound_start == done_volumetrics[i]) { already_checked = true; break; @@ -334,8 +354,6 @@ Tracing trace_ray(uint volume_start, vec3 starting_pos, vec3 start_direction, fl compound_num += 1; continue; } - done_volumetrics[next_volumetric_index] = compound_start; - next_volumetric_index = (next_volumetric_index + 1) % 5; //iteration_num ++; uint oct_tree_index = compounds[compound_start + 8]; @@ -347,9 +365,6 @@ Tracing trace_ray(uint volume_start, vec3 starting_pos, vec3 start_direction, fl float y_border = compound_pos.y + float((compound_grid_size) * uint(!y_pos)) * compound_scale; float z_border = compound_pos.z + float((compound_grid_size) * uint(!z_pos)) * compound_scale; - // go over the borders by this amount - float overstep = 0.00001 / length(direction); - if (!x_null) { x_factor = (x_border - pos.x) / direction.x; } else { @@ -369,15 +384,18 @@ Tracing trace_ray(uint volume_start, vec3 starting_pos, vec3 start_direction, fl y_factor += overstep; z_factor += overstep; - vec3 intersection_pos = pos; + vec3 intersection_pos = pos + 10.0 * overstep * direction; bool is_x_hit = false; bool is_y_hit = false; bool is_z_hit = false; bool hit_inside = false; + float hit_factor; + // check that either the hit is in range or we are inside of the compound from the start if ((compound_pos.x <= intersection_pos.x && intersection_pos.x <= compound_pos.x + float(compound_grid_size) * compound_scale) && (compound_pos.y <= intersection_pos.y && intersection_pos.y <= compound_pos.y + float(compound_grid_size) * compound_scale) && (compound_pos.z <= intersection_pos.z && intersection_pos.z <= compound_pos.z + float(compound_grid_size) * compound_scale)){ - //hit_inside = true; + hit_inside = true; + hit_factor = 10.0 * overstep; } else { vec3 intersection_pos_x = pos + x_factor * direction; vec3 intersection_pos_y = pos + y_factor * direction; @@ -388,6 +406,7 @@ Tracing trace_ray(uint volume_start, vec3 starting_pos, vec3 start_direction, fl hit_inside = true; is_x_hit = true; intersection_pos = intersection_pos_x; + hit_factor = x_factor; } if ((compound_pos.x <= intersection_pos_y.x && intersection_pos_y.x <= compound_pos.x + float(compound_grid_size) * compound_scale) && @@ -396,6 +415,7 @@ Tracing trace_ray(uint volume_start, vec3 starting_pos, vec3 start_direction, fl hit_inside = true; is_y_hit = true; intersection_pos = intersection_pos_y; + hit_factor = y_factor; } if ((compound_pos.x <= intersection_pos_z.x && intersection_pos_z.x <= compound_pos.x + float(compound_grid_size) * compound_scale) && @@ -404,149 +424,185 @@ Tracing trace_ray(uint volume_start, vec3 starting_pos, vec3 start_direction, fl hit_inside = true; is_z_hit = true; intersection_pos = intersection_pos_z; + hit_factor = z_factor; } } - // check that either the hit is in range or we are inside of the compound from the start - if (hit_inside) { - vec3 oct_tree_pos = vec3(compound_pos); - uint current_size = compound_grid_size; - vec3 mid_point = oct_tree_pos + float(current_size / 2) * vec3(compound_scale, compound_scale, compound_scale); - bool children_open[8] = {true, true, true, true, true, true, true, true}; - uint oct_tree_address = oct_tree_index; - // iterate through the oct_tree - uint check_it = 0; - uint max_check_it = 60; - uint prev_child = 0; - uint prev_prev_child = 0; + compound_starts[hits] = compound_start; + hit_factors[hits] = hit_factor; + is_x_hits[hits] = is_x_hit; + is_y_hits[hits] = is_y_hit; + is_z_hits[hits] = is_z_hit; + hits_inside[hits] = hit_inside; + hits += 1 * uint(hit_inside); - uvec3 grid_pos = uvec3(0, 0, 0); - uvec3 parent_pos = uvec3(0, 0, 0); - - bool has_moved = false; - while (!result.has_hit && check_it < max_check_it) { - // failsafe to get out in case has_moved runs into an accuracy issue - check_it ++; - oct_tree_pos = vec3(grid_pos) * compound_scale + compound_pos; - mid_point = oct_tree_pos + (float(current_size / 2) * vec3(compound_scale, compound_scale, compound_scale)); - - uint child_index = next_oct_tree_child(mid_point, intersection_pos, children_open); - if (child_index == 0) { - // go up to parent - // if parent is 0 abort, as we have reached the root node again and try to exit it - if (oct_tree_mem[oct_tree_address] == 0) { - break; - } - for (int i=0; i < 8; i++) { - children_open[i] = true; - } - uint parent_index = oct_tree_mem[oct_tree_address]; - // check which child we came from - child_index = 1 * uint(oct_tree_address == oct_tree_mem[parent_index + 1]) + 2 * uint(oct_tree_address == oct_tree_mem[parent_index + 2]) + 3 * uint(oct_tree_address == oct_tree_mem[parent_index + 3]) + 4 * uint(oct_tree_address == oct_tree_mem[parent_index + 4]) + 5 * uint(oct_tree_address == oct_tree_mem[parent_index + 5]) + 6 * uint(oct_tree_address == oct_tree_mem[parent_index + 6]) + 7 * uint(oct_tree_address == oct_tree_mem[parent_index + 7]) + 8 * uint(oct_tree_address == oct_tree_mem[parent_index + 8]); - // mark as done to avoid reinvestigating, since intersection_pos is on its edge - children_open[child_index - 1] = false; - prev_prev_child = prev_child; - prev_child = oct_tree_address; - - uvec3 back_vec = parent_child_vec(current_size, child_index); - grid_pos -= parent_child_vec(current_size, child_index); - current_size *= 2; - oct_tree_address = parent_index; - } else { - // go down into child - if (current_size == 2) { - // check block if hit break - if (oct_tree_mem[oct_tree_address + child_index] != 0) { - result.has_hit = true; - result.end_color = unpack_color(oct_tree_mem[oct_tree_address + child_index]); - break; - } - } else { - // check if the child has content, else skip to next child of current parent - uint x = oct_tree_mem[oct_tree_address + child_index]; - if (oct_tree_mem[x] != 0) { - // change base address and position to child - current_size /= 2; - oct_tree_address = x; - grid_pos += parent_child_vec(current_size, child_index); - for (int i=0; i < 8; i++) { - children_open[i] = true; - } - continue; - } - } - children_open[child_index - 1] = false; - - // we did not go deeper or had a hit, so intersection pos needs to be updated - // new intersection pos calc - vec3 offset = vec3(parent_child_vec(current_size / 2, child_index)) * compound_scale; - vec3 low = oct_tree_pos + offset; - float x_border = low.x + float((compound_scale * current_size / 2) * uint(x_pos)); - float y_border = low.y + float((compound_scale * current_size / 2) * uint(y_pos)); - float z_border = low.z + float((compound_scale * current_size / 2) * uint(z_pos)); - - if (!x_null) { - x_factor = (x_border - pos.x) / direction.x; - if (x_factor <= 0.0) { - x_factor = max_factor; - } - } else { - x_factor = max_factor; - } - if (!y_null) { - y_factor = (y_border - pos.y) / direction.y; - if (y_factor <= 0.0) { - y_factor = max_factor; - } - } else { - y_factor = max_factor; - } - if (!z_null) { - z_factor = (z_border - pos.z) / direction.z; - if (z_factor <= 0.0) { - z_factor = max_factor; - } - } else { - z_factor = max_factor; - } - float smallest_factor = min(min(x_factor, y_factor), z_factor); - - if (x_factor == smallest_factor) { - is_x_hit = true; - is_y_hit = false; - is_z_hit = false; - } - if (y_factor == smallest_factor) { - is_x_hit = false; - is_y_hit = true; - is_z_hit = false; - } - if (z_factor == smallest_factor) { - is_x_hit = false; - is_y_hit = false; - is_z_hit = true; - } - - // move a bit further to fully enter the next quadrant - smallest_factor += overstep; - - //has_moved = length(intersection_pos - (pos + smallest_factor * direction)) >= 0.00001; - has_moved = intersection_pos != (pos + smallest_factor * direction); - intersection_pos = pos + smallest_factor * direction; - } - } - - uint hit_facing = uint(is_x_hit) * (2 + uint(x_pos)) + uint(is_y_hit) * (4 + uint(y_pos)) + uint(is_z_hit && !z_pos); - //result.has_hit = true; - result.end_pos = intersection_pos; - result.end_facing = hit_facing; - result.end_volume = volume_index; - result.end_direction = direction; - } + done_volumetrics[next_volumetric_index] = compound_start; + next_volumetric_index = (next_volumetric_index + 1) % max_num_compounds; compound_num += 1; } + for (int i =0; i < hits; i++) { + if (result.has_hit) { + break; + } + // find encounters in order + float min_factor = max_factor; + uint min_index = 0; + for (int j = 0; j < hits; j++) { + if (hit_factors[j] < min_factor) { + min_factor = hit_factors[j]; + min_index = j; + } + } + // set up the compound + uint compound_start = compound_starts[min_index]; + bool is_x_hit = is_x_hits[min_index]; + bool is_y_hit = is_y_hits[min_index]; + bool is_z_hit = is_z_hits[min_index]; + uint oct_tree_index = compounds[compound_start + 8]; + uint compound_grid_size = compounds[compound_start]; + float compound_scale = uintBitsToFloat(compounds[compound_start + 1]); + vec3 compound_pos = vec3(uintBitsToFloat(compounds[compound_start + 5]), uintBitsToFloat(compounds[compound_start + 6]), uintBitsToFloat(compounds[compound_start + 7])); + vec3 intersection_pos = pos + hit_factors[min_index] * direction; + // invalidate the min found + hit_factors[min_index] = max_factor; + + vec3 oct_tree_pos = vec3(compound_pos); + uint current_size = compound_grid_size; + vec3 mid_point = oct_tree_pos + float(current_size / 2) * vec3(compound_scale, compound_scale, compound_scale); + bool children_open[8] = {true, true, true, true, true, true, true, true}; + uint oct_tree_address = oct_tree_index; + // iterate through the oct_tree + uint check_it = 0; + uint max_check_it = 60; + uint prev_child = 0; + uint prev_prev_child = 0; + + uvec3 grid_pos = uvec3(0, 0, 0); + uvec3 parent_pos = uvec3(0, 0, 0); + + bool has_moved = false; + while (!result.has_hit && check_it < max_check_it) { + // failsafe to get out in case has_moved runs into an accuracy issue + check_it ++; + oct_tree_pos = vec3(grid_pos) * compound_scale + compound_pos; + mid_point = oct_tree_pos + (float(current_size / 2) * vec3(compound_scale, compound_scale, compound_scale)); + + uint child_index = next_oct_tree_child(mid_point, intersection_pos, children_open); + if (child_index == 0) { + // go up to parent + // if parent is 0 abort, as we have reached the root node again and try to exit it + if (oct_tree_mem[oct_tree_address] == 0) { + break; + } + for (int i=0; i < 8; i++) { + children_open[i] = true; + } + uint parent_index = oct_tree_mem[oct_tree_address]; + // check which child we came from + child_index = 1 * uint(oct_tree_address == oct_tree_mem[parent_index + 1]) + 2 * uint(oct_tree_address == oct_tree_mem[parent_index + 2]) + 3 * uint(oct_tree_address == oct_tree_mem[parent_index + 3]) + 4 * uint(oct_tree_address == oct_tree_mem[parent_index + 4]) + 5 * uint(oct_tree_address == oct_tree_mem[parent_index + 5]) + 6 * uint(oct_tree_address == oct_tree_mem[parent_index + 6]) + 7 * uint(oct_tree_address == oct_tree_mem[parent_index + 7]) + 8 * uint(oct_tree_address == oct_tree_mem[parent_index + 8]); + // mark as done to avoid reinvestigating, since intersection_pos is on its edge + children_open[child_index - 1] = false; + prev_prev_child = prev_child; + prev_child = oct_tree_address; + + uvec3 back_vec = parent_child_vec(current_size, child_index); + grid_pos -= parent_child_vec(current_size, child_index); + current_size *= 2; + oct_tree_address = parent_index; + } else { + // go down into child + if (current_size == 2) { + // check block if hit break + if (oct_tree_mem[oct_tree_address + child_index] != 0) { + result.has_hit = true; + result.end_color = unpack_color(oct_tree_mem[oct_tree_address + child_index]); + break; + } + } else { + // check if the child has content, else skip to next child of current parent + uint x = oct_tree_mem[oct_tree_address + child_index]; + if (oct_tree_mem[x] != 0) { + // change base address and position to child + current_size /= 2; + oct_tree_address = x; + grid_pos += parent_child_vec(current_size, child_index); + for (int i=0; i < 8; i++) { + children_open[i] = true; + } + continue; + } + } + children_open[child_index - 1] = false; + + // we did not go deeper or had a hit, so intersection pos needs to be updated + // new intersection pos calc + vec3 offset = vec3(parent_child_vec(current_size / 2, child_index)) * compound_scale; + vec3 low = oct_tree_pos + offset; + float x_border = low.x + float((compound_scale * current_size / 2) * uint(x_pos)); + float y_border = low.y + float((compound_scale * current_size / 2) * uint(y_pos)); + float z_border = low.z + float((compound_scale * current_size / 2) * uint(z_pos)); + + if (!x_null) { + x_factor = (x_border - pos.x) / direction.x; + if (x_factor <= 0.0) { + x_factor = max_factor; + } + } else { + x_factor = max_factor; + } + if (!y_null) { + y_factor = (y_border - pos.y) / direction.y; + if (y_factor <= 0.0) { + y_factor = max_factor; + } + } else { + y_factor = max_factor; + } + if (!z_null) { + z_factor = (z_border - pos.z) / direction.z; + if (z_factor <= 0.0) { + z_factor = max_factor; + } + } else { + z_factor = max_factor; + } + float smallest_factor = min(min(x_factor, y_factor), z_factor); + + if (x_factor == smallest_factor) { + is_x_hit = true; + is_y_hit = false; + is_z_hit = false; + } + if (y_factor == smallest_factor) { + is_x_hit = false; + is_y_hit = true; + is_z_hit = false; + } + if (z_factor == smallest_factor) { + is_x_hit = false; + is_y_hit = false; + is_z_hit = true; + } + + // move a bit further to fully enter the next quadrant + smallest_factor += overstep; + + //has_moved = length(intersection_pos - (pos + smallest_factor * direction)) >= 0.00001; + has_moved = intersection_pos != (pos + smallest_factor * direction); + intersection_pos = pos + smallest_factor * direction; + } + } + + uint hit_facing = uint(is_x_hit) * (2 + uint(x_pos)) + uint(is_y_hit) * (4 + uint(y_pos)) + uint(is_z_hit && !z_pos); + //result.has_hit = true; + result.end_pos = intersection_pos; + result.end_facing = hit_facing; + result.end_volume = volume_index; + result.end_direction = direction; + } + if (result.has_hit) { break; } @@ -667,6 +723,11 @@ Tracing trace_ray(uint volume_start, vec3 starting_pos, vec3 start_direction, fl z_pos = direction.z > 0.0; z_null = (direction.z == 0.0); + + // clear volumetrics for reevaluation + for (int i=0; i < max_num_compounds; i++) { + done_volumetrics[i] = 0; + } } else { break; } diff --git a/shaders/rt_quad.frag b/shaders/rt_quad.frag index d5f4a7b..5fad61a 100644 --- a/shaders/rt_quad.frag +++ b/shaders/rt_quad.frag @@ -47,7 +47,8 @@ float pos_infinity = uintBitsToFloat(0x7F800000); // set limit for maximal iterations uint max_iterations = max_num_lights * max_iterations_per_light * raster_points; uint iteration_num = 0; -uint max_num_compounds = scene_info.infos[6]; +const uint absolute_max_compounds = 10; +uint max_num_compounds = min(scene_info.infos[6], absolute_max_compounds); uvec4 unpack_color(uint val) { // left most 8 bits first @@ -322,20 +323,40 @@ Tracing trace_ray(uint volume_start, vec3 starting_pos, vec3 start_direction, fl vec3 color_mul_transparent; uint next_volumetric_index = 0; - uint[5] done_volumetrics; - for (int i=0; i < 5; i++) { + uint[absolute_max_compounds] done_volumetrics; + for (int i=0; i < max_num_compounds; i++) { done_volumetrics[i] = 0; } + uint[absolute_max_compounds] compound_starts; + float[absolute_max_compounds] hit_factors; + bool[absolute_max_compounds] is_x_hits; + bool[absolute_max_compounds] is_y_hits; + bool[absolute_max_compounds] is_z_hits; + bool[absolute_max_compounds] hits_inside; + while (iteration_num < max_iterations) { iteration_num ++; + for (int i=0; i < max_num_compounds; i++) { + compound_starts[i] = 0; + hit_factors[i] = 0.0; + is_x_hits[i] = false; + is_y_hits[i] = false; + is_z_hits[i] = false; + hits_inside[i] = false; + } + uint compound_num = 0; + // go over the borders by this amount + float overstep = 0.00001 / length(direction); + uint hits = 0; + // todo needs depth ordering of volumetrics inside of the volume while (scene_info.infos[volume_index + 6 + max_num_lights + compound_num] != 0 && compound_num < max_num_compounds && iteration_num < max_iterations && !result.has_hit) { uint compound_start = scene_info.infos[volume_index + 6 + max_num_lights + compound_num]; bool already_checked = false; - for (int i=0; i < 5; i++) { + for (int i=0; i < max_num_compounds; i++) { if (compound_start == done_volumetrics[i]) { already_checked = true; break; @@ -345,8 +366,6 @@ Tracing trace_ray(uint volume_start, vec3 starting_pos, vec3 start_direction, fl compound_num += 1; continue; } - done_volumetrics[next_volumetric_index] = compound_start; - next_volumetric_index = (next_volumetric_index + 1) % 5; //iteration_num ++; uint oct_tree_index = compounds[compound_start + 8]; @@ -358,9 +377,6 @@ Tracing trace_ray(uint volume_start, vec3 starting_pos, vec3 start_direction, fl float y_border = compound_pos.y + float((compound_grid_size) * uint(!y_pos)) * compound_scale; float z_border = compound_pos.z + float((compound_grid_size) * uint(!z_pos)) * compound_scale; - // go over the borders by this amount - float overstep = 0.00001 / length(direction); - if (!x_null) { x_factor = (x_border - pos.x) / direction.x; } else { @@ -380,15 +396,18 @@ Tracing trace_ray(uint volume_start, vec3 starting_pos, vec3 start_direction, fl y_factor += overstep; z_factor += overstep; - vec3 intersection_pos = pos; + vec3 intersection_pos = pos + 10.0 * overstep * direction; bool is_x_hit = false; bool is_y_hit = false; bool is_z_hit = false; bool hit_inside = false; + float hit_factor; + // check that either the hit is in range or we are inside of the compound from the start if ((compound_pos.x <= intersection_pos.x && intersection_pos.x <= compound_pos.x + float(compound_grid_size) * compound_scale) && (compound_pos.y <= intersection_pos.y && intersection_pos.y <= compound_pos.y + float(compound_grid_size) * compound_scale) && (compound_pos.z <= intersection_pos.z && intersection_pos.z <= compound_pos.z + float(compound_grid_size) * compound_scale)){ - //hit_inside = true; + hit_inside = true; + hit_factor = 10.0 * overstep; } else { vec3 intersection_pos_x = pos + x_factor * direction; vec3 intersection_pos_y = pos + y_factor * direction; @@ -399,6 +418,7 @@ Tracing trace_ray(uint volume_start, vec3 starting_pos, vec3 start_direction, fl hit_inside = true; is_x_hit = true; intersection_pos = intersection_pos_x; + hit_factor = x_factor; } if ((compound_pos.x <= intersection_pos_y.x && intersection_pos_y.x <= compound_pos.x + float(compound_grid_size) * compound_scale) && @@ -407,6 +427,7 @@ Tracing trace_ray(uint volume_start, vec3 starting_pos, vec3 start_direction, fl hit_inside = true; is_y_hit = true; intersection_pos = intersection_pos_y; + hit_factor = y_factor; } if ((compound_pos.x <= intersection_pos_z.x && intersection_pos_z.x <= compound_pos.x + float(compound_grid_size) * compound_scale) && @@ -415,149 +436,185 @@ Tracing trace_ray(uint volume_start, vec3 starting_pos, vec3 start_direction, fl hit_inside = true; is_z_hit = true; intersection_pos = intersection_pos_z; + hit_factor = z_factor; } } - // check that either the hit is in range or we are inside of the compound from the start - if (hit_inside) { - vec3 oct_tree_pos = vec3(compound_pos); - uint current_size = compound_grid_size; - vec3 mid_point = oct_tree_pos + float(current_size / 2) * vec3(compound_scale, compound_scale, compound_scale); - bool children_open[8] = {true, true, true, true, true, true, true, true}; - uint oct_tree_address = oct_tree_index; - // iterate through the oct_tree - uint check_it = 0; - uint max_check_it = 60; - uint prev_child = 0; - uint prev_prev_child = 0; + compound_starts[hits] = compound_start; + hit_factors[hits] = hit_factor; + is_x_hits[hits] = is_x_hit; + is_y_hits[hits] = is_y_hit; + is_z_hits[hits] = is_z_hit; + hits_inside[hits] = hit_inside; + hits += 1 * uint(hit_inside); - uvec3 grid_pos = uvec3(0, 0, 0); - uvec3 parent_pos = uvec3(0, 0, 0); - - bool has_moved = false; - while (!result.has_hit && check_it < max_check_it) { - // failsafe to get out in case has_moved runs into an accuracy issue - check_it ++; - oct_tree_pos = vec3(grid_pos) * compound_scale + compound_pos; - mid_point = oct_tree_pos + (float(current_size / 2) * vec3(compound_scale, compound_scale, compound_scale)); - - uint child_index = next_oct_tree_child(mid_point, intersection_pos, children_open); - if (child_index == 0) { - // go up to parent - // if parent is 0 abort, as we have reached the root node again and try to exit it - if (oct_tree_mem[oct_tree_address] == 0) { - break; - } - for (int i=0; i < 8; i++) { - children_open[i] = true; - } - uint parent_index = oct_tree_mem[oct_tree_address]; - // check which child we came from - child_index = 1 * uint(oct_tree_address == oct_tree_mem[parent_index + 1]) + 2 * uint(oct_tree_address == oct_tree_mem[parent_index + 2]) + 3 * uint(oct_tree_address == oct_tree_mem[parent_index + 3]) + 4 * uint(oct_tree_address == oct_tree_mem[parent_index + 4]) + 5 * uint(oct_tree_address == oct_tree_mem[parent_index + 5]) + 6 * uint(oct_tree_address == oct_tree_mem[parent_index + 6]) + 7 * uint(oct_tree_address == oct_tree_mem[parent_index + 7]) + 8 * uint(oct_tree_address == oct_tree_mem[parent_index + 8]); - // mark as done to avoid reinvestigating, since intersection_pos is on its edge - children_open[child_index - 1] = false; - prev_prev_child = prev_child; - prev_child = oct_tree_address; - - uvec3 back_vec = parent_child_vec(current_size, child_index); - grid_pos -= parent_child_vec(current_size, child_index); - current_size *= 2; - oct_tree_address = parent_index; - } else { - // go down into child - if (current_size == 2) { - // check block if hit break - if (oct_tree_mem[oct_tree_address + child_index] != 0) { - result.has_hit = true; - result.end_color = unpack_color(oct_tree_mem[oct_tree_address + child_index]); - break; - } - } else { - // check if the child has content, else skip to next child of current parent - uint x = oct_tree_mem[oct_tree_address + child_index]; - if (oct_tree_mem[x] != 0) { - // change base address and position to child - current_size /= 2; - oct_tree_address = x; - grid_pos += parent_child_vec(current_size, child_index); - for (int i=0; i < 8; i++) { - children_open[i] = true; - } - continue; - } - } - children_open[child_index - 1] = false; - - // we did not go deeper or had a hit, so intersection pos needs to be updated - // new intersection pos calc - vec3 offset = vec3(parent_child_vec(current_size / 2, child_index)) * compound_scale; - vec3 low = oct_tree_pos + offset; - float x_border = low.x + float((compound_scale * current_size / 2) * uint(x_pos)); - float y_border = low.y + float((compound_scale * current_size / 2) * uint(y_pos)); - float z_border = low.z + float((compound_scale * current_size / 2) * uint(z_pos)); - - if (!x_null) { - x_factor = (x_border - pos.x) / direction.x; - if (x_factor <= 0.0) { - x_factor = max_factor; - } - } else { - x_factor = max_factor; - } - if (!y_null) { - y_factor = (y_border - pos.y) / direction.y; - if (y_factor <= 0.0) { - y_factor = max_factor; - } - } else { - y_factor = max_factor; - } - if (!z_null) { - z_factor = (z_border - pos.z) / direction.z; - if (z_factor <= 0.0) { - z_factor = max_factor; - } - } else { - z_factor = max_factor; - } - float smallest_factor = min(min(x_factor, y_factor), z_factor); - - if (x_factor == smallest_factor) { - is_x_hit = true; - is_y_hit = false; - is_z_hit = false; - } - if (y_factor == smallest_factor) { - is_x_hit = false; - is_y_hit = true; - is_z_hit = false; - } - if (z_factor == smallest_factor) { - is_x_hit = false; - is_y_hit = false; - is_z_hit = true; - } - - // move a bit further to fully enter the next quadrant - smallest_factor += overstep; - - //has_moved = length(intersection_pos - (pos + smallest_factor * direction)) >= 0.00001; - has_moved = intersection_pos != (pos + smallest_factor * direction); - intersection_pos = pos + smallest_factor * direction; - } - } - - uint hit_facing = uint(is_x_hit) * (2 + uint(x_pos)) + uint(is_y_hit) * (4 + uint(y_pos)) + uint(is_z_hit && !z_pos); - //result.has_hit = true; - result.end_pos = intersection_pos; - result.end_facing = hit_facing; - result.end_volume = volume_index; - result.end_direction = direction; - } + done_volumetrics[next_volumetric_index] = compound_start; + next_volumetric_index = (next_volumetric_index + 1) % max_num_compounds; compound_num += 1; } + for (int i =0; i < hits; i++) { + if (result.has_hit) { + break; + } + // find encounters in order + float min_factor = max_factor; + uint min_index = 0; + for (int j = 0; j < hits; j++) { + if (hit_factors[j] < min_factor) { + min_factor = hit_factors[j]; + min_index = j; + } + } + // set up the compound + uint compound_start = compound_starts[min_index]; + bool is_x_hit = is_x_hits[min_index]; + bool is_y_hit = is_y_hits[min_index]; + bool is_z_hit = is_z_hits[min_index]; + uint oct_tree_index = compounds[compound_start + 8]; + uint compound_grid_size = compounds[compound_start]; + float compound_scale = uintBitsToFloat(compounds[compound_start + 1]); + vec3 compound_pos = vec3(uintBitsToFloat(compounds[compound_start + 5]), uintBitsToFloat(compounds[compound_start + 6]), uintBitsToFloat(compounds[compound_start + 7])); + vec3 intersection_pos = pos + hit_factors[min_index] * direction; + // invalidate the min found + hit_factors[min_index] = max_factor; + + vec3 oct_tree_pos = vec3(compound_pos); + uint current_size = compound_grid_size; + vec3 mid_point = oct_tree_pos + float(current_size / 2) * vec3(compound_scale, compound_scale, compound_scale); + bool children_open[8] = {true, true, true, true, true, true, true, true}; + uint oct_tree_address = oct_tree_index; + // iterate through the oct_tree + uint check_it = 0; + uint max_check_it = 60; + uint prev_child = 0; + uint prev_prev_child = 0; + + uvec3 grid_pos = uvec3(0, 0, 0); + uvec3 parent_pos = uvec3(0, 0, 0); + + bool has_moved = false; + while (!result.has_hit && check_it < max_check_it) { + // failsafe to get out in case has_moved runs into an accuracy issue + check_it ++; + oct_tree_pos = vec3(grid_pos) * compound_scale + compound_pos; + mid_point = oct_tree_pos + (float(current_size / 2) * vec3(compound_scale, compound_scale, compound_scale)); + + uint child_index = next_oct_tree_child(mid_point, intersection_pos, children_open); + if (child_index == 0) { + // go up to parent + // if parent is 0 abort, as we have reached the root node again and try to exit it + if (oct_tree_mem[oct_tree_address] == 0) { + break; + } + for (int i=0; i < 8; i++) { + children_open[i] = true; + } + uint parent_index = oct_tree_mem[oct_tree_address]; + // check which child we came from + child_index = 1 * uint(oct_tree_address == oct_tree_mem[parent_index + 1]) + 2 * uint(oct_tree_address == oct_tree_mem[parent_index + 2]) + 3 * uint(oct_tree_address == oct_tree_mem[parent_index + 3]) + 4 * uint(oct_tree_address == oct_tree_mem[parent_index + 4]) + 5 * uint(oct_tree_address == oct_tree_mem[parent_index + 5]) + 6 * uint(oct_tree_address == oct_tree_mem[parent_index + 6]) + 7 * uint(oct_tree_address == oct_tree_mem[parent_index + 7]) + 8 * uint(oct_tree_address == oct_tree_mem[parent_index + 8]); + // mark as done to avoid reinvestigating, since intersection_pos is on its edge + children_open[child_index - 1] = false; + prev_prev_child = prev_child; + prev_child = oct_tree_address; + + uvec3 back_vec = parent_child_vec(current_size, child_index); + grid_pos -= parent_child_vec(current_size, child_index); + current_size *= 2; + oct_tree_address = parent_index; + } else { + // go down into child + if (current_size == 2) { + // check block if hit break + if (oct_tree_mem[oct_tree_address + child_index] != 0) { + result.has_hit = true; + result.end_color = unpack_color(oct_tree_mem[oct_tree_address + child_index]); + break; + } + } else { + // check if the child has content, else skip to next child of current parent + uint x = oct_tree_mem[oct_tree_address + child_index]; + if (oct_tree_mem[x] != 0) { + // change base address and position to child + current_size /= 2; + oct_tree_address = x; + grid_pos += parent_child_vec(current_size, child_index); + for (int i=0; i < 8; i++) { + children_open[i] = true; + } + continue; + } + } + children_open[child_index - 1] = false; + + // we did not go deeper or had a hit, so intersection pos needs to be updated + // new intersection pos calc + vec3 offset = vec3(parent_child_vec(current_size / 2, child_index)) * compound_scale; + vec3 low = oct_tree_pos + offset; + float x_border = low.x + float((compound_scale * current_size / 2) * uint(x_pos)); + float y_border = low.y + float((compound_scale * current_size / 2) * uint(y_pos)); + float z_border = low.z + float((compound_scale * current_size / 2) * uint(z_pos)); + + if (!x_null) { + x_factor = (x_border - pos.x) / direction.x; + if (x_factor <= 0.0) { + x_factor = max_factor; + } + } else { + x_factor = max_factor; + } + if (!y_null) { + y_factor = (y_border - pos.y) / direction.y; + if (y_factor <= 0.0) { + y_factor = max_factor; + } + } else { + y_factor = max_factor; + } + if (!z_null) { + z_factor = (z_border - pos.z) / direction.z; + if (z_factor <= 0.0) { + z_factor = max_factor; + } + } else { + z_factor = max_factor; + } + float smallest_factor = min(min(x_factor, y_factor), z_factor); + + if (x_factor == smallest_factor) { + is_x_hit = true; + is_y_hit = false; + is_z_hit = false; + } + if (y_factor == smallest_factor) { + is_x_hit = false; + is_y_hit = true; + is_z_hit = false; + } + if (z_factor == smallest_factor) { + is_x_hit = false; + is_y_hit = false; + is_z_hit = true; + } + + // move a bit further to fully enter the next quadrant + smallest_factor += overstep; + + //has_moved = length(intersection_pos - (pos + smallest_factor * direction)) >= 0.00001; + has_moved = intersection_pos != (pos + smallest_factor * direction); + intersection_pos = pos + smallest_factor * direction; + } + } + + uint hit_facing = uint(is_x_hit) * (2 + uint(x_pos)) + uint(is_y_hit) * (4 + uint(y_pos)) + uint(is_z_hit && !z_pos); + //result.has_hit = true; + result.end_pos = intersection_pos; + result.end_facing = hit_facing; + result.end_volume = volume_index; + result.end_direction = direction; + } + if (result.has_hit) { break; } @@ -678,6 +735,11 @@ Tracing trace_ray(uint volume_start, vec3 starting_pos, vec3 start_direction, fl z_pos = direction.z > 0.0; z_null = (direction.z == 0.0); + + // clear volumetrics for reevaluation + for (int i=0; i < max_num_compounds; i++) { + done_volumetrics[i] = 0; + } } else { break; }