From 66b8c9007075e63297c720e3aa2a2acd53ea6a69 Mon Sep 17 00:00:00 2001 From: Rob Kelly Date: Thu, 4 Sep 2025 14:21:17 -0600 Subject: [PATCH] Sobel filter sampling for gunk normal maps --- assets/materials/grunk_jittery.material | Bin 1205 -> 1205 bytes .../grunk_overlays/bright_overlay.material | Bin 887 -> 890 bytes .../grunk_overlays/crystal_overlay.material | Bin 934 -> 937 bytes .../grunk_overlays/danger_overlay.material | Bin 950 -> 949 bytes .../grunk_overlays/debug_overlay.material | Bin 856 -> 862 bytes .../grunk_overlays/gunk_overlay.material | Bin 1005 -> 1005 bytes .../grunk_overlays/lowrez_overlay.material | Bin 999 -> 1000 bytes .../grunk_overlays/oily_overlay.material | Bin 953 -> 954 bytes assets/npc/shambler/shambler.material | Bin 1255 -> 1255 bytes src/shaders/gunk/canvas_grunk.gdshader | 1 + src/shaders/gunk/common.gdshaderinc | 97 ++++++++++++++++++ src/shaders/gunk/debug_overlay.gdshader | 23 +---- src/shaders/gunk/gunk.gdshader | 18 +--- src/shaders/gunk/gunk_overlay.gdshader | 31 ++---- 14 files changed, 116 insertions(+), 54 deletions(-) diff --git a/assets/materials/grunk_jittery.material b/assets/materials/grunk_jittery.material index e67f5becc0e35f9cd95dfecb71c473d462fe33ca..60595a0d145dcaab057f92d1174626e39883d7fb 100644 GIT binary patch literal 1205 zcmV;m1WNl-Q$s@n000005C8x$3;+O~1ONaiwJ-f(Fbka|0QT{sL-5!n9k?bq={%|O z{2P3{2(SIPlodSU`E~?0+Zx%*LH2epde*@=>ID&0cf zXfOY#@W1CEo(Rx!q6d@*{{>vW$Xg!_-s_QO{AcjLz<@uSn>2REY-KLOrh>CEH>~2V zn>~J->+Ywy`m>Wp)*SCOm$mG%V=5_J98tcE>8u=Ww7cd?k?UTWz3s|dnvqnsy+|=I z6|SvDsbz11gI_B}Z?4n$ncR#oqu2iklefAo;k>oR8k5Ef=QeT+=c^qr$4_ojF2p9) z95$o&a#F?Sa%~s1Wmml{v)F9SfDCB84R-l}i1<*+Fr_gheEkN(K2#@SMa5)Xh#15f%>|RD6s? z$YEnusj-&aR6JHfJ^w>kOj17ngZQxX|My@$A0s-b4mzon4;l;g=QL^JL`4=QJ2-66 z01EJ}UJQ-daOrht19+J(R(!-es;;hw$`kH)5l&j77n{c4y6vwqe7*aC z#OtYjNIg*jVgFGnqrAD}I29x(T<}T`A=@DEDn(4@ai1FO)q<3bk~@4+p4L+i;&tbYg8w7fl?mY^ zJ}PCq65x<9vR+NQjKQ!L;du3kqSiip6b8pV$Aj_gX6y_gGc+pwD#_5HwrCB2UGZ+> zKNdK4I&=V%%k|4;;zBV%4b&> z5rQak`%ODvAsm|poxMRaJyg9Ph-zummOW#to{!fQ!%F;ACwoB%S)V)BMS0{K!KpXjo>&T zFh@^5J_#tF9`?(sY*H^QEE;1J{KT^7L$#1T3VFRX zD3S^TSltNC*Ll%~uC+kCy6>UQf8?z`DGlIe))zIte5IWJd(K5TX_=sx0VutG8>(iU T@bfvT0F8!|3BGs3Qd2`ivM@&B literal 1205 zcmV;m1WNl-Q$s@n000005C8x%3;+O~1ONaiwJ-f(F$;*Y=f>4??p;y;Mdj z9~DOmfdGX7kpS-6E@5#`6+Yv`P#yWr4L(kpd(CAnd+eA>3in2oFJn5JV~y&rxpL%cU75YD&1;&m)Y@Jp z3^5e0t)tYkC&9t5m7_P;Y5Y!Z#+T9SKZMC!FGo0Uccd|CY&bWPTR30WcsYJ@lX4+8 zspha5HJFzgo6B7TvQ~9Vu-~cH^fX9eBu9}*Aj|7=hupO?zTT^<%~(~ls`l3UZqCAH zd264Y0mB6mNhJx5mHvf=Y6ZDg)lJ=S12d!%Uj z20Srj#MqHp@$cwZN~|2~2S-H;Yf37W0&=5+;)Dt7NGg>Q@|V~-i4i|GIzmKPJZ@C! zK>`7X$g)ynHLmz#rf*|6d+Lg_b;`UPhgT9^27H*ViHjew$IN5uHZZG#m?2 zRo&QZ2@(T~bQxko#1e*}HGuD^QN2-UMrb5SK?)fTU;+^`s^SI`KvN~nv5-WFAR{73 znv|qen8tAk;{w0pH0E9mjoC2iQD*{pnJ!g)z&om3*CWf*_uI)PEs={2<8R#dZ4AEN zW-#Jq)Gnl+s9>;Pu#^ej(|LSqk^?q)Q7(|}6K0trHq*FG%@=9`3PypQxp-IGsq&om zRt-?RQQ6?;T0!aJWNdE@#U8*K>gCJaG=Wq6sojL?LJ@VM?uh3|+^2ZkIip|z7wpE2 z(2<{%vResg$QW6!&@N&$sC77AJ))?;(-wunb-(k0cy~+e%#dlc>V6hv)v>l{+DJ$B zA6q!~Md-LBSL&Cq#RY~AH3(fl!h|92tyg(o&_G&I%1Qj0UYd5Z61sa0nz|cz4!kTN z(IAT=x8LOR6~d8O(7_ud(?i9(foMykw(J>G@oc7-he65vnWQ!Qb(4R&}C-a=!5_2j*6FdA1t>f1y6|43SWP#nMwSzl;;$x1o>_neDx`Z7T;15i5sHdM_x T;paQ4T#aUu2fkOrQd2`io25?N diff --git a/assets/materials/grunk_overlays/bright_overlay.material b/assets/materials/grunk_overlays/bright_overlay.material index 3cdf6bc4f53c70e03fb3ae6d3ca7869f8f483732..b4ad64710e17c1dca55128f9324dc930faa64f76 100644 GIT binary patch delta 880 zcmV-$1CRXo2KoknQd2`i0ssI201yBGJqQ2*VgmpGD77#BU_A%L8US`AeMRunBpo39 z49tKxkCCRq1&EPNP3c_6n)wi}YY`GXDlaueH^U`8>Pt7PHTpJ$8jP28Bw zAP8neNN5U@B1{2Y0AK)b0NiVNH{{+WV)|dei>|a)TJBi`juhpQff;{K&Xlo!^}Y$Q zIv-=UtIhU*%Kw<3uoE?Md`Rj4A)ioMzOaMk2sNPp2L1;S`2!rKl}-6lY57z+n8~!+ z260<=yU@Oqg8gxjZMF?dA5Jfim9AiR{Df!msOT8Z_vUt&nQ=ubr;8;8wnIrus~Yj;zeGw z|B)jI@vCLhURCS-r}@USa<9jxs&al1 zQw8XQ0z`~}qo{u&L8j0MjYyKh6dD6?0+BH*?h>E`8BgL6Qzn{_jY*|4%>mv39v=MV zJZpQ*#SO`a?V(){`YC5{#WE8EeEX;-z*jfu07v~{^hV(qVB%x(ivVwd&@LScyLj;a z73Lm9cL#2+gYT6*;{Xn;+HzqR(f*H{S zV90qErdE}1BmYLYy|iM_!r5WWb1M4DwSH1qJu&KY2f3BCF9}+gB{ZXYsPQ!NMIq|?DROma}mo% z%IJTDlFt7ERtOOqESV%E0y(La(EtneW4Lhx$AzRCCH^ZgDRBVc|Hu)5_|-CLuc~wY z&wS%qxz|%uRX9J0sRHyl@c~AFqNp)FQ)q-nBuQZkjR9~1kufXo5}*VbPtp`qCYq3q zNu@H)0oni_{2(6xzb(;_a+n<2_O_pN1|gQ48_?e;cY<-K-rr$vLUebqhcWnH$ukFdnC0B(y$kk>KQw=-l)+_DydZepx|KoLXbN4M zOn6vCp?C?`O}OK$@;gn;wcAqPgpjLqaoao2scta02wGHZWj_-I64$!{-r<0hK_sn> zt;)vgCyI+}P=wQ>=%%4xHb*ocK)q?mnHz&nxVw245{f_IU#BH?@1`2Ysh=Ky^VJ& z&nv)(KSNUll3pUaAP^Rv5Oeg&d>9<@7{kU9FepLC;yVR9v4)HqAQTeOneb^Il8Vx3 N)V}A58wOHSLqkq8oZSEb diff --git a/assets/materials/grunk_overlays/crystal_overlay.material b/assets/materials/grunk_overlays/crystal_overlay.material index 9cd186c15f1014616177c966fca25d1460e601fc..e7870adc42971cfacebd4eed421aa1397fb4870a 100644 GIT binary patch delta 867 zcmV-p1DyP(2dM{tQd2`i0ssI201yBG^9TR{kpln#D77#BVDkq(900bahDhM>G#xV3 z4d@dvm$@1*cNJSHZQp#LEMCbfKL z2g}^_fc_WwFB0+xvNb=;Lt!cg<^gZaQA@k>t<*A6D877Lo9&V99e;~@c@62E-^VQ4 z!XUjIv)Hmu5q19N)^ccExvU}WrXZ(2BO`72g`3K`X;`ID9XrhO4HMo~QPqtab2>9u zG{J!)qQ}#Pan%y4<7$RuG}$K}MzpK6n?DU}_O?5TTE!FMqGATpjszWVwpS&;dAnsd ztgr2`2C=@}JuzH|hJWpNS^UB0WVLf!*k}rIu2adzHrp6h(-eUI02k^BqCQP>$1w|p zha79)3^_kQKOrwB9Av2s>GgV@Xt`lQtz;IQTmx)guYV(x%=K?jQd-imaKd9{GI?~5YbOV|=JCSm z@V2)-NMdf5{C_sZCk*4SS+-frW)w3#<-F{LQw;fZyq!na{h(ocV_p~i&@PL_xRWq} zd9yL(y`Y5wk)kNWlvqODTk$SbE05keFo~8s-+CTKS^0;&C`?Q_4B*^wV#D77AG#%nb zCbSZy5Q)JDng;a)9Bv~6nqgR3D2K3Oe9@jkw(Zu-c-xvuH}*jdU4J;!;gizXo+8Ia z@A%kwV9gxqcLah61XE)GY5;ct3{E>m$@1*cMJS8QOp#LEMCbfL0 z2g}^_fc_WwFB0+xk~KfeLm?^#<^gZaQA@k>t<*A6D877Lo2`-U9e;azc@62E-^VN3 z!XUjIv)Hmu@pS&?)^ccExvU}WrXZs}BO`72g`3K`X;`ID9XrhO4HMo~G1ZM4b2>9u zG`WE?f=3gEQNi&>l0pX3j)WX$UOZvGRwm~3YyBKvucQq+UXb{o zfMlcr2!Q|N2zopvE47jL6>W(JYvoc#NCO5IV=Z6Al7*yk+{l z4Jr;2a5rne?SJjFhSh7)ZpJdEh|V4*UQWPiix3^V%+oCV!2o;HtXllTwJaWECV~Ve z%prmIBY*+X%oaQ=gmbjrl?tG?$)LYterwKqLe@ z8;rQtf-EOtw9y6U*FBpECPWweosbU3QDs1Lr%{j_JAdk@s^1CuB<1zE(-AsibF}@* zYn>TpB;v!lG>HgFevmVQPvWMt`3tABQW<0pMQEM+dD77#BV6_LG8~{dXi%0O#CLI(5 z8Ae@X{*2d+5j>v5R?(hG{Sy#@TOL@v@xBnpLE>e**WvyYokc(R7AZzxk&Gx^8{}CQK0pbOX z93?*g1DuP~@{JrU%gDm{Kk}b|fIpH?CcH|{xCnV7XIZDJw6I8EjpeknDPKA*?^JJv zW7=$2UiW2x56-$9WqX_D%ci}wYS2dR)7a~lcQa*eU$vr@(>ibDIBrc8?&g)uUPBr^ z(V2@{L!Hm$kk;8fJ63s#1a0N27CQH=6z0%x!z>2_egG$tamyQx5^L1zOzP$aRVB&Y zY`w15{4cLC72*l1NEjvqZ3JDP6&hSb?#q}$9&0&&!Bjm;r;t`SDAxhh>(yf*<@#rSet<66U{Rt#2*^iDi?24)uBk^+S~$s=74u6Zop=>vdWn&I zGMP*#7%eNwmCHuG(e`C5G0E3fubbGdvTmaf|4aUN{11~+0vCT^^dL|IiBck&XxOHp zQkmvX2)=IWTWT#^g035(dn;$8;RuC2?2F0Q=N6+q_HU0heSepaldGcjXKiwb^B_Gg z3MZ)V~ zqB3X_{R-p=!!8t!im7MiPg<0unfN?`DS0Y2!8*si>VQ%*w5Em5Wlxs9?_O#`&yv>} zVD?-=t~lu_XHbfS^^?SYi9;wVxN^Q=43-dYX8hn)fKhn}zJumg_C6}z#K=+2#7*it`LxXF{KL7v# delta 943 zcmV;g15o_62et=)Qd2`i0ssI201yBGrw9N5o&x{?D77#BV5bMA8~{csj7ad%CLI(V za|U>l?4Q|Bn>aoLy$jDI=r$)S%P48bAlt@dZ+zWNnp|Rc?$ku0=4r1)ZR7TZX&pCz zs^IHmh+~GBLA;hLO95&CZ~%M&m%C`A2T$G|J$PMAUw7JnI;{sSOPb)V8$Bpv<^G5K zdedtC-{V%cAoutGa~G+|nX=ZfUdTnQa*#Fq)n@zu!G8%4sSqLK z#*UJn{{qg%Y57JEmSt?={2%#WV89=ePbj=fUU3n=B4=5rsus zg=5-mSzh;ltsuO0H_G-l%eR{L(yBolxld!STi(sIwSCo!R!-}@k>l7kQMj8|GJ6ea z^h9SaY7KQhlS5i(_v~2ZB@(oit6J#Xvr?Etzb&&I1pWXgsqvBJjYbJyN}NgE+@Pu? zxtp!m)tcYJE6jy>f+|v$$-p3>+v9>mjL3Z}rtoEdEw8fXmUiP#muyrXB!EEVprPZ< z_Kx7oM6_Dg*KS#NSzqpsFjtw_e%Hk#K8Ub3ToyKFoVeUZurtkemdUisJ#spBB5nnF z3pF=5H!P@?6f8mtmXd0LA~Kjv zzep-o+N?mq5TIf)o&zb^KjY)`lOgB@3Iib^A1N-r+DN;m9z}`aBx6|2FOhU&R*dN- zM)JvIGM!+wRY|g3HtLPGZ^bf`d~Nl*ncXVuHVW~-COl45`_DHAH}{S$~vV556(U12wJ|Ct<*dzz_N4kK|r+t zC!<~q26XhUjb?zu7=L(qw!+E?yOVKdg(dC)cn|t1YCp02TenucP@A1aLreBiq7*N% z_PgWP%q>A=3Toq3_8!r53n9p$C$>MZ);ZEfCLW_JQdA@nKu#|BzAahY9qENl6{V~N zP*LeLiGBrggkcwoMrG<*nfVq)XevHWQc9jmO}x%AuR5R%rci02bJ>$+@4J__(6i+A z379=skSi`)${Cv?Vf`erU*Zso3O1cD7=tCmn;AcN6<|~zg72=mmA#HiH8C<)GjY>A RBr4uhbYF*Dumn<5LqqwNzCM6&Hk_GXlKBTepoFNy%UCUG&gE$P1vCUn7JK4WL} zzV#WjrS6Tp&`1GY0Ac`W0Nk=theJ2avV1vv_Gzx<-A{9W_rz4^N?WDXoaIPEel=-f z|M$4*KF!5f=l_p$_UPwK8Mdp}%?Imr4DD8%?f(b=C6svaVN`=t{{wtJY5Belmg6(s z{0I3zK)@fty&PuX_fcQ$tP*TnY@u%Ye%03I?o5&ctD8=u%>Cc`G3j|ZJgt-gJ56x^|3#QTNgTLz^)aMWydhiT|i=w2gFN~rxJ4yeFI`Z0u;*6Ubl^iEgkY*(0Nu`WL)kF+2EL1O) z!I};>7a@6x_eIv9ywEO2%&RjhuwwN2PRMYsH1chtpX-eQ$s@%zK{F> delta 846 zcmV-U1F`(x2G|CFQd2`i0ssI201yBG><0hTcy>U)y* z0~M<{{15qGau^O2=ao!ij)o<2H(M>MGnVxNfixxuBrNrFwRzh5IxmsKzhpy`iU4SH(SgL?gt%`hY)iP<_ z8UuiqsDU{`BQi5GlB81TV1hAYRpS8?fb=BKq6je}G18`zl1kQp2=MtpKmZR9zKgHJ z=a;vHskJFRo}1u6pXw($@sr2kQT4ggj|6VQ_>^YO=q(?A)l$}^j7N*Q?WT@QDLH0X z%=N9_dg9#Q*I8uO0%Hj2Nw!;Y!5EB^r?*b~y)-Ao-t5rm;9PoT zuOyZyBKgWfkPBu1rG_M_Em2Dv$6=+w+_z4H17um6DrU%wBP>jIq#CPhWQlW4Rh8}g7><|AkVh8Q5K7s_Bw7n{?P z*u~rG%0ga07DMJ$85Li>@Qfy;cWWx!Aneps0VVn#P2V9?MH8iThv!^o;8 YETTKQKmS>v4YWv6ur`bV6H-${LxUKR?EnA( diff --git a/assets/materials/grunk_overlays/gunk_overlay.material b/assets/materials/grunk_overlays/gunk_overlay.material index a8fb140e82ab25c7fcc7b04271886e0072c11575..39a9cb16826e21745fbac2f7ee0d97a4ae20a491 100644 GIT binary patch literal 1005 zcmV<}q0{{RhwJ-f(cL-e`02Zs0NC5979d<7iJ_yj3 z-2c{MK%&wiNPNDzOGik|_a25Odz+EHVasl$$xUw8pEH!z+#8dAbT3fb90|jQrEiAf z0vjTTKmr+-Q*Z!y0EPfDsDfN}JGUpV{Nlm2XKOssVZ^<65#VB&+&{?ga}47Y(_yzNl7aQ>Iha2 zKIJa(`1+$UOt73IfEZN-tK+$oG6MU!F+8WEImQoMZ%TOU7+IE^2_7qQk%gdcCpCkkF@#0Nt2EYii|6YbaiT|l(w|n`}@T4rCS)AGg+NrHyF(vx{Xw$j*qIT<{HA zBA=RUD~vvvGSYlSq;C@O8p9#Rx`4PPQ)`Mn7SR$-Y{Nr~8s9)u+vm8c#3)n4?8|a| zrZK-jyui$W%qz!Y=vF1J;Ci@oBq3h4CFxsYlm!ZDn@=A@b%Z+@t|^p(wmbyisAf&` bwOOi(k+GW5mgWbka8J>HTWV(qQd2`iO;hJY literal 1005 zcmV<}q0{{RhwJ-f(a|m4?04D2`NZ{}$9Wb;8^dOG> zOccG;A)8{50yGGT*OX4!Iq?wuBeJ&z*&ES!lO~tAZH!IJ0}vi#`oQx;YY)R6&;4N@ zmww5B54x-+Qg8rx0EPfDsDfN}JGUpV{36RSmS4<7U5hfkmfkPkp4H^AEWbFV?f!>6 zfAntnzsK){#m3-mR`}#c4^>SF|YTt}wKo`Ba+AUt$fm?rA<`{Q{aiG1X)2pRf zc3l(EmiB0#-5-usex`RPHynk)mB(r+#?)(=t5WgW&TcAiOl=Ln0S*BFJ2?ITKjCnk z<1zA1d6bJis@WL#{XENadhr@5gki*8*=E9GPb$lB@+Tq#Wy1{{EbvtnRKb_3TPR%{ zHI67(DaPHoGTg8&%OQ;NF@YdLLkQYIwU?%Dd z6-ZtZ@(CD989q5w#MyRn7Cb*dKQXP7ra&_hh9L+Sofa08c4V|P;s44`OeH0jUt7kSlU;BA9 z%XV50W#IvUtf&!1g^&!*%p?VcEC+Cck*O+j0}{aVBoE?{Q-lacG;BseNl8g72j&P= zCfHQBhxqF=T(FcQgBS&Z-|^ka4%a?z4A03ZT=4_v=qXp8T|g7g}de?SjPlWn~@k_6(u-v;jQCeYwj%tuhpux2u#=A zlO--o7FCst@Khm>%gdFlo@4~%;l)bo3BU-l|6YbaiT`P3cYXQL@T4rC@_sWz#nak) z$5(X1oj^&l7A?)7655okY-yQM&8`Ujo^!K8fJV<6KAzSorHy#}yNh)Ik=+qFvEZ9p zBAA-&SC~GSGPco*c-$o7HOZmex`4QqsWrtOi)fH0w&5W`-G88|>~n-wVw7oOCTBT{ zY2PmdFL+h}^GdZCx>X5R;C}8LOo*eBl0Ypn$^wP7&8Lr{I>H?c*A&V?TONXMOtZH6 b(kz9EkzLKGPxFIRxTmN-FQT&pQd2`ir}^e$ diff --git a/assets/materials/grunk_overlays/lowrez_overlay.material b/assets/materials/grunk_overlays/lowrez_overlay.material index 08a4e36f4485339ba47f8ac67677119a1bbf575d..f68b700a252164d353a6a8ceae6effb9772807c8 100644 GIT binary patch delta 971 zcmV;+12p{S2j~YJQd2`i0ssI201yBGc?kdj&;tMfD77#BV0j2NksKR;bXfH}GGI|z zMz)Q~-uP-a(&Q%hQI@}{%dsX3uTjYge8-0w(Is(`0!TqDFbFv(U9IM7orx zjCT7^a_%BEohfS#>xEo@)G7yAvtMnt|5^Ss_=d~E3Lzp0F8+g@i_`Lr7c9%TGWvh= ze}I5LS5Mzu9mYgJsOT_vsHQB zms0T6-6-4JHD7AlORENL5H>+GH#&pZbQ+R9a}<=nH<|5rc&{15p9JSD`H*dkT#Y9A3(j^u8(URQ%?Y<%N( zSXzo>sa1zTA)M>#xt@s*6%apspgvX75&cv-OrwVN(Zj>s=Fql*oZVMbWI$Uli*q3Je3PD9i zMKvU7vIQB7R;y(~<|hW`CG((kgXk_mOD!x*34Tl<$VMpL7;^C+$a1V?FfbLM9VrH~ z7_AcjADsOB|4msOQsJ{yz^BzJK_FZDDaep9V*-yCB1}p>NJeB>e6^Eyu|7o^0VR1< z%sLSV#VQ_5het9B!!Xp2mdcT;n~i#>?Mtz|Bwt&-ZeF*_x}7ovfUKwyMU!v>7Ju@P zQ${qRVKWL!N(zdV1DpzcNEeQ0`xCK1v5ljG8MSZ!c8sdwA~uePH{Jf|X40wE-IAv!VniF1+~& zSk1nt;5A+KmPfU?%XLA@z{a(5E`LvL8=VnpagE*a1>gLqpQ%(&zvH delta 970 zcmV;*12z2U2j>SIQd2`i0ssI201yBGbqN3f&jSDeD77#BV08#BksKR;4pH+*yELmT zBiqJgZ+x{IX>ybMD9gvBChW1oYgDoV-|=BabV+O)8pkAB8HAh@Fa>V_cL0O{u!w%! zW%+U!ZS>&FyQ2p$i|NswwodCo%aWpeb)yGmtla;SUvFBi|BKwp73BW@k9>9IG`f_h zjCT7^a_%B6ohfS#>xEo@)G7yAvtMnt|5^SsIETx^il89~F8+g@i_`Lr7c9%T((wP} z{{R7h7f;(K>62j^u8(URQx;Y<%N% zSXzo>sa1!;pquOBxt@s*l@LFCpgz@65&cv+OrwVN(c{D1=1V1teG7?BPgk1awvK%WJ3{2%`M~Z$l93n|U+tt_tWQx!K*=2y zb56WLv1$j)*^!LGFbt)mrEsLmW~1I|`%)|~$=6n|o7b(fZl??ZfUBq>L6dL-7JuTD zQ${qRVKWL!N(zdV1DFc1VRRq=(OOV!`>1+G?MpshJ3%#Y$6M3$_Gh!gAMM#J@wVCL zV#xJw!$6l24@SiY6jFwG?lEu7PuG0tjVJClr2Bj?*FGcPN+5Npq0f7UQE@K+rh-!K6 zDuNnnrsZ6*l+emFG0L&rQsUQ}(TjZ%#(9BWjO?m|73sxsex}GPt!a9I07@f;x6b#+ sKnalshRcRt;6exGJJh@~&*6(bF}kannQ8t_73e9Nud+B;0#Z{$LyEfE?f?J) diff --git a/assets/materials/grunk_overlays/oily_overlay.material b/assets/materials/grunk_overlays/oily_overlay.material index 049abf1201befd38ac306e980943152be2fa7055..5a3e29df73c32810c23ebac102b2fdbb097ff707 100644 GIT binary patch delta 551 zcmV+?0@(ez2f7C#Qd2`i0ssI201yBGw+H|Lq5}W`D77#BV7CXw8~|47i;*EQ2JrlW zZcga2SaSh?Dkul2qAbf^P*5;dtJQWwDoMFWTnkbu1vD9kh!Tv{ki38pTyPYsOR?IKa zbmCP^_7Wrclx5ioMpL=SRm(=b()OuXVv?_|UN^CSTV>r!9R7f&s8KyaXoh4)l7d2( z17Lz7V`bw35`gp|5CV--!ik1$3M!Rp4ps>MHh1y8iOf(Iy6dl?i7Wkcx0^=Y9{sxa zy4_*~hxILE)%R`qIJzo`lG#n3^D;;eiNZ$ojhru5ceVL*byPb0@NU7l&-b6$XB4bg zTG0W2Iieg!*>|(e&MBRIb{js3R})Y|(zRpI$I=*S23W?Cm$wyk4z-KVBc=s5Ld5~y z`f^O`BN@xSC8UBt+V(3@Q=S{;LV@LK)f^VgLWMjlWq!D_;xDdlBLo}i3Cstob&9l+ zh{x}WiISvWBc}}b8cVi(M@nI5{gpMtDXQ6WO`=}mIV!FTT|+SSsEmAyA~rRTCmZEU zrX~*O7*bs>gEb{%E?Y9zd+}18^P*k{7PGqwV#NtBIfGIpte+&dOB_N`!H)90@?k#2e}6!Qd2`i0ssI201yBGvj_kHp#uN_D77#BV6z9k8~}D{jFBNR2Atgo z9#2TISaSh?D3?mgL8>UrvKN#TjMZwjosdduTqLdqH7*4-8HR`wjG#zfKnO0l5IK-a z@p`>RNC2sE{r^WQ;*>zS44_^wpaLn^Pct+`G;?%91Obl@4wM#Ot)$(oOHo!h$(R-M zOEjH$6_dThNIqp*c7oAVE^^hfQLnUpDwde!Ypd6PP3%@#w-SdxfTgHGy+UY)WJZ#L zLY4zyf+1sN;{g(2^dL|IjZ(sihHVNem1z!A2yWX#rP=E;?%EY*ab@&e>;_TT!@k~o zO>QyT!}_+d#`kmmIKL`x&#WfrIT@tKMd2j+evTKbruKZfIx5|{;Eti*kNcR1;uA;x#Zx$LkvD47d!Dm&BIsjA$2`C#MxOLW%>& z_2rm0MKYFs+en3rw9!{0rkoq)Lt)F+#vC@xj0$O1aQ1Lz?JuZqAOs)j$;}6>b&j-= ziU;qC9a%|UBPR@enI&6!M`U3mEtS>5R#XOYPNKX59bxN*qEVT8R%X6M5t@q6lb!M> zQxmUqD5%bqp*Jl+E=#iPef3fsdX`>i6tlYuV#O&hIfGIpte+(IOB_N`!Ikp`W3YsH oGvf!Z7mT1o@EtU_viDKxCPt2GCT^OCM8$iG?hB9$mQqtgL-FciTc$Hk@{2`tL7 zgpptwLRxCl`cgC23Rm6K_~t&Q608!Y!}h)o6orZCwp2_+^Vi z(f~jWZ^VSDPK`1>D^QVi2KR^s>#s|c=c}2P~Q;>gqB$?BVPZGWsl+7#p5(Be=HQr)JJNeGo%%YVfd0K8% z<+_s#Om~WXC)G5rHfE|)9qkGvC?x|$3(UnkJ}-Q9UQ+1fWZ96>O~uJvH#R6TA~h#W zl*oX*UauZMiJXrR;WFj)2$AKek%UL6l=Tb|fyj{j34}ZpVLD7`c0PY(N=zn`h`-3t z5K)I5*ZOz{Wn8HL^e*0+}NNY!+#jkfd4KQ8y!I|QUn0N@IWQ| z&$6Nd;6H^1*^H140w`dLM*kO#h&Y;NdE)ByFv4-vW>rx}%V_3_iqcEaA$Kc$Dog=^ W0H`5Bgb*T`5lIS?WEiv40u%ytH!Uv! delta 636 zcmV-?0)zeM3FirrIVU01He6!{V|#1KUb4M6N4#yDByzKs?2qFb7>Zz!<6_f}1Qz9( zWRYMQLYivQ`cyO43SV8-H8gsG+Wfm&%Xi&BFIx*i?C|`MM})*Ix!+VX7Sq~d z7>(8NKLAW>#`nXwnN_+lRgiysrI^!=Q4&5El+7$kf_d4%8gH?qoqT6(ZqZtjJS}&s zavjR$r9;KOlWH1Q3o}=$j&_9-l#+j<1?FNpJuiB4NGWn~vTVr6rru;Pn;H}u5t$5!E;`a$|#r4F6wB1OC5QYIFd(ND%-4!vmG< zKg)^=fd3R4WHLfF2%vZ=8vS1|BI0J6C5o%l!wAPyn_Wd2EhCvHDoiAxL+)1iRGb2V W0H`5Bgb*T`5lIS?WEiv40u%y4%ruh# diff --git a/src/shaders/gunk/canvas_grunk.gdshader b/src/shaders/gunk/canvas_grunk.gdshader index a6210a0..48b8f7f 100644 --- a/src/shaders/gunk/canvas_grunk.gdshader +++ b/src/shaders/gunk/canvas_grunk.gdshader @@ -1,3 +1,4 @@ +// -*- mode: glsl -*- /* Gunk shader adapted to a canvas item */ shader_type canvas_item; diff --git a/src/shaders/gunk/common.gdshaderinc b/src/shaders/gunk/common.gdshaderinc index 2661020..86c144f 100644 --- a/src/shaders/gunk/common.gdshaderinc +++ b/src/shaders/gunk/common.gdshaderinc @@ -1,3 +1,4 @@ +// -*- mode: glsl -*- // Common logic for gunk shaders group_uniforms gunk_material; @@ -36,6 +37,23 @@ uniform sampler2D overlay_albedo: hint_default_transparent, filter_nearest; uniform sampler2D overlay_emission: hint_default_transparent, filter_nearest; uniform float overlay_emission_scale = 1.0; +#if defined(USE_MASK) +group_uniforms gunk_mask; +uniform float edge_bleed = 0.25; +uniform sampler2D gunk_mask; +#endif + + +float bump_sample(vec2 uv, vec3 uvt, float dx, float dy) { + vec2 offset = vec2(dx / pixellation, dy / pixellation); + float height = texture(gunk_noise, uvt + vec3(offset, 0.0)).r; +#if defined(USE_MASK) + float mask = texture(gunk_mask, uv + offset).r; + height *= smoothstep(1.0, 0.0, mask); +#endif + return height; +} + vec3 rim_glow( vec3 normal, vec3 view, @@ -89,3 +107,82 @@ vec3 base_emission(vec2 uv, float value) { float base_specular() { return 0.5 * inversesqrt(specular_contribution); } + +// Convolution methods + +vec3 godot_convolution(vec2 uv, vec3 uvt) { + // from https://github.com/godotengine/godot/blob/master/core/io/image.cpp#L3758 + float here = bump_sample(uv, uvt, 0.0, 0.0); + float to_right = bump_sample(uv, uvt, 1.0, 0.0); + float above = bump_sample(uv, uvt, 0.0, -1.0); + vec3 up = vec3(0.0, 1.0, (here - above) * bump_strength); + vec3 across = vec3(1.0, 0.0, (to_right - here) * bump_strength); + return normalize(cross(across, up)); +} + +vec3 minimal_convolution(vec2 uv, vec3 uvt) { + float h_center = bump_sample(uv, uvt, 0.0, 0.0); + float h_right = bump_sample(uv, uvt, 1.0, 0.0); + float h_down = bump_sample(uv, uvt, 0.0, 1.0); + float dX = (h_center - h_right); + float dY = (h_center - h_down); + float dZ = 1.0 / bump_strength; + return normalize(vec3(dX, dY, dZ)); +} + +vec3 cross_convolution(vec2 uv, vec3 uvt) { + float h_right = bump_sample(uv, uvt, 1.0, 0.0); + float h_down = bump_sample(uv, uvt, 0.0, 1.0); + float h_left = bump_sample(uv, uvt, -1.0, 0.0); + float h_up = bump_sample(uv, uvt, 0.0, -1.0); + float dX = (h_left - h_right); + float dY = (h_right - h_down); + float dZ = 1.0 / bump_strength * 2.0; + return normalize(vec3(dX, dY, dZ)); +} + +vec3 sobel_convolution(vec2 uv, vec3 uvt) { + float tl = bump_sample(uv, uvt, -1.0, -1.0); + float l = bump_sample(uv, uvt, -1.0, 0.0); + float bl = bump_sample(uv, uvt, -1.0, 1.0); + float t = bump_sample(uv, uvt, 0.0, -1.0); + float b = bump_sample(uv, uvt, 0.0, 1.0); + float tr = bump_sample(uv, uvt, 1.0, -1.0); + float r = bump_sample(uv, uvt, 1.0, 0.0); + float br = bump_sample(uv, uvt, 1.0, 1.0); + float dX = (tr + 2.0 * r + br) - (tl + 2.0 * l + bl); + float dY = (bl + 2.0 * b + br) - (tl + 2.0 * t + tr); + float dZ = 1.0 / bump_strength * 8.0; + return normalize(vec3(dX, dY, dZ)); +} + +vec3 scharr_convolution(vec2 uv, vec3 uvt) { + float tl = bump_sample(uv, uvt, -1.0, -1.0); + float l = bump_sample(uv, uvt, -1.0, 0.0); + float bl = bump_sample(uv, uvt, -1.0, 1.0); + float t = bump_sample(uv, uvt, 0.0, -1.0); + float b = bump_sample(uv, uvt, 0.0, 1.0); + float tr = bump_sample(uv, uvt, 1.0, -1.0); + float r = bump_sample(uv, uvt, 1.0, 0.0); + float br = bump_sample(uv, uvt, 1.0, 1.0); + float dX = 3.0*tl + 10.0*l + 3.0*bl - 3.0*tr - 10.0*r - 3.0*br; + float dY = 3.0*tl + 10.0*t + 3.0*tr - 3.0*bl - 10.0*b - 3.0*br; + float dZ = 1.0 / bump_strength * 12.0; + return normalize(vec3(dX, dY, dZ)); +} + +vec3 sobel_5x5_convolution(vec2 uv, vec3 uvt) { + // Expensive!! + // TODO this can be decomposed into a few small matrix ops + float s[25]; + for (int i = 0; i < 5; i++) { + for (int j = 0; j < 5; j++) { + s[i*5 + j] = bump_sample(uv, uvt, float(i - 2), float(j - 2)); + } + } + + float dX = 4.0 * (s[3] + s[23] - s[1] - s[21]) + 5.0 * (s[4] + s[24] - s[0] - s[20]) + 8.0 * (s[9] + s[19] - s[5] - s[15]) + 10.0 * (s[8] + s[14] + s[18] - s[6] - s[10] - s[16]) + 20.0 * (s[13] - s[11]); + float dY = 4.0 * (s[19] + s[15] - s[9] - s[5]) + 5.0 * (s[24] + s[20] - s[4] - s[0]) + 8.0 * (s[23] + s[21] - s[3] - s[1]) + 10.0 * (s[18] + s[22] + s[16] - s[8] - s[2] - s[6]) + 20.0 * (s[17] - s[7]); + float dZ = 1.0 / bump_strength * 240.0; + return normalize(vec3(dX, dY, dZ)); +} diff --git a/src/shaders/gunk/debug_overlay.gdshader b/src/shaders/gunk/debug_overlay.gdshader index ce61a08..27395f9 100644 --- a/src/shaders/gunk/debug_overlay.gdshader +++ b/src/shaders/gunk/debug_overlay.gdshader @@ -1,31 +1,16 @@ +// -*- mode: glsl -*- shader_type spatial; render_mode depth_prepass_alpha, unshaded; +#define USE_MASK #include "common.gdshaderinc" -group_uniforms gunk_mask; -uniform float edge_bleed = 0.25; -uniform sampler2D gunk_mask; - - -float bump_sample(vec2 uv, vec3 uvt, float dx, float dy) { - vec2 offset = vec2(dx / pixellation, dy / pixellation); - float height = texture(gunk_noise, uvt + vec3(offset, 0.0)).r; - float mask = texture(gunk_mask, uv + offset / uv_scale).r; - return height * smoothstep(1.0, 0.0, mask); -} void fragment() { vec3 uvt = scale_uvt(UV, TIME); float value = sample_noise(uvt); - // Build normal map from bump map - float h_center = bump_sample(UV, uvt, 0.0, 0.0); - float h_right = bump_sample(UV, uvt, 1.0, 0.0); - float h_down = bump_sample(UV, uvt, 0.0, 1.0); - float dx = (h_center - h_right) * bump_strength; - float dy = (h_center - h_down) * bump_strength; - vec3 normal_diff_map = normalize(vec3(dx, dy, 1.0)); - ALBEDO = normal_diff_map / 2.0 + 0.5; + vec3 nmap = sobel_convolution(UV, uvt); + ALBEDO = nmap / 2.0 + 0.5; } diff --git a/src/shaders/gunk/gunk.gdshader b/src/shaders/gunk/gunk.gdshader index 7eeb42d..a2109b5 100644 --- a/src/shaders/gunk/gunk.gdshader +++ b/src/shaders/gunk/gunk.gdshader @@ -1,3 +1,4 @@ +// -*- mode: glsl -*- shader_type spatial; render_mode depth_prepass_alpha; @@ -23,11 +24,6 @@ void vertex() { VERTEX *= 1.0 + jitter; } -float bump_sample(vec3 uvt, float dx, float dy) { - vec2 offset = vec2(dx / pixellation, dy / pixellation); - return texture(gunk_noise, uvt + vec3(offset, 0.0)).r; -} - void fragment() { vec3 uvt = scale_uvt(UV, TIME); float value = sample_noise(uvt); @@ -36,17 +32,11 @@ void fragment() { EMISSION = base_emission(UV, value); SPECULAR = base_specular(); - // Build normal map from bump map - float h_center = bump_sample(uvt, 0.0, 0.0); - float h_right = bump_sample(uvt, 1.0, 0.0); - float h_down = bump_sample(uvt, 0.0, 1.0); - float dx = (h_center - h_right) * bump_strength; - float dy = (h_center - h_down) * bump_strength; - vec3 normal_diff_map = normalize(vec3(dx, dy, 1.0)); - NORMAL_MAP = normal_diff_map / 2.0 + 0.5; + vec3 nmap = sobel_convolution(UV, uvt); + NORMAL_MAP = nmap / 2.0 + 0.5; // add fresnel - vec3 world_normal = mat3(TANGENT, BINORMAL, NORMAL) * normal_diff_map; + vec3 world_normal = mat3(TANGENT, BINORMAL, NORMAL) * nmap; EMISSION += rim_glow( world_normal, VIEW, diff --git a/src/shaders/gunk/gunk_overlay.gdshader b/src/shaders/gunk/gunk_overlay.gdshader index 8593895..3027073 100644 --- a/src/shaders/gunk/gunk_overlay.gdshader +++ b/src/shaders/gunk/gunk_overlay.gdshader @@ -1,20 +1,10 @@ +// -*- mode: glsl -*- shader_type spatial; render_mode depth_prepass_alpha; +#define USE_MASK #include "common.gdshaderinc" -group_uniforms gunk_mask; -uniform float edge_bleed = 0.25; -uniform sampler2D gunk_mask; - - -float bump_sample(vec2 uv, vec3 uvt, float dx, float dy) { - vec2 offset = vec2(dx / pixellation, dy / pixellation); - float height = texture(gunk_noise, uvt + vec3(offset, 0.0)).r; - float mask = texture(gunk_mask, uv + offset / uv_scale).r; - return height * smoothstep(1.0, 0.0, mask); -} - void fragment() { vec3 uvt = scale_uvt(UV, TIME); float value = sample_noise(uvt); @@ -23,17 +13,16 @@ void fragment() { EMISSION = base_emission(UV, value); SPECULAR = base_specular(); - // Build normal map from bump map - float h_center = bump_sample(UV, uvt, 0.0, 0.0); - float h_right = bump_sample(UV, uvt, 1.0, 0.0); - float h_down = bump_sample(UV, uvt, 0.0, 1.0); - float dx = (h_center - h_right) * bump_strength; - float dy = (h_center - h_down) * bump_strength; - vec3 normal_diff_map = normalize(vec3(dx, dy, 1.0)); - NORMAL_MAP = normal_diff_map / 2.0 + 0.5; + // vec3 nmap = minimal_convolution(UV, uvt); + // vec3 nmap = cross_convolution(UV, uvt); + vec3 nmap = sobel_convolution(UV, uvt); + // vec3 nmap = sobel_5x5_convolution(UV, uvt); + // vec3 nmap = scharr_convolution(UV, uvt); + // vec3 nmap = godot_convolution(UV, uvt); + NORMAL_MAP = nmap / 2.0 + 0.5; // add fresnel - vec3 world_normal = mat3(TANGENT, BINORMAL, NORMAL) * normal_diff_map; + vec3 world_normal = mat3(TANGENT, BINORMAL, NORMAL) * nmap; EMISSION += rim_glow( world_normal, VIEW,