Created
February 15, 2023 02:21
-
-
Save ryley-o/8b9fb20eba19484024f03b48d4648113 to your computer and use it in GitHub Desktop.
Script for project 412
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Comments: This script is minified and very difficult to read. Will likely need help from artist to understand it. | |
script project 412: | |
document.body.innerHTML += '<div class=\"tggl\"><span>2d </span><input type=\"checkbox\" id=\"tt\" onclick=\"javascript:window.main.persp=1-window.main.persp\"><label for=\"tt\"><i></i></label><span> 3d</span></div>'\nlet tokenHash = tokenData.hash,_=THREE,de=b=>{var f,o,a,e={},d=b.split(\"\"),c=f=d[0],g=[c],h=o=256;for(b=1;b<d.length;b++)a=d[b].charCodeAt(0),a=h>a?d[b]:e[a]?e[a]:f+c,g.push(a),c=a.charAt(0),e[o]=f+c,o++,f=a;return g.join(\"\")}\nclass Rand{constructor(t){this.ua=0;let sfc32=function(u){let a=parseInt(u.substr(0,8),16),b=parseInt(u.substr(8,8),16),c=parseInt(u.substr(16,8),16),d=parseInt(u.substr(24,8),16);return _=>{;a|=0;b|=0;c|=0;d|=0;let t=(((a+b)|0)+d)|0;d=(d+1)|0;a=b^(b>>>9);b=(c+(c<<3))|0;c=(c<<21)|(c>>>11);c=(c+t)|0;return (t>>>0)/4294967296;};};this.pa=new sfc32(t.substr(2,32));this.pb=new sfc32(t.substr(34,32));for(let i=0;i<1e6;i+=2){this.pa();this.pb();};};r(){this.ua=!this.ua;return this.ua?this.pa():this.pb();};}\nlet rn = new Rand(tokenHash),inv = (rn.r() < 0.5),colorSchemes=['ùùùäåñÕ\\'S#Jßc\u001c\\'_ä?ñ\\'a','\"+3@ÌÿÌÿÌÿÌÿÌÿÌÿÌÿ','(03¦\u0001»þÍ\":Û»»»»»»»','-7CÿBBt¯hÿ)3\u0014æ#××ááà','\u001b\u001d\u001e\u001b\u001d\u001es%ú#â\\`ÔßÐ\u0010ÿШC»»»','\u0011\u0012\u0013222Â(2Ä=àÆOC¥ÕWµÄ=îîî','..5SNNSNSNNNÿÿÿ','\u001d\u0019\b¶L|\u0016Ó½&ak°Zl%ÊÂ','ûñÇûñÇÌ$\u001d\u001a×!E ±bhj|od','..5SNNSNSNNNÿÿÿ','\u001c\u001f\\'OOO¯KW¯ÓåÀy}¤¤y ¦¥îíî','%#O%#OpPP`´ß¯UUÿðÃÐÓp','$&&¢hj¥j£jk£jq£k¥£¢','+\u0019@%ÿÿÿÿÿÿÿ','*!\u001cÌ\u001a\u001cðå:fÿÅek\u0006Ó×Ï','$\u001f3/)Bÿ H¶ æÀ®ÿïaUÂÿßøøò','333MMMÿ++ûðæÍ ?ÿÞÿ õÞ³','\u0015\u0014\u001b\u0011\u000f\u0018ÿggaÿÊÿÊ ¢wÿ¢wÿaÿÊíìî','\u0012\u001b!\u0012\u001c!äGT½÷½QTÀ·~¸P¥¤ÿÿÿ','(03¦\u0001»þÍ\":Û»»»»»»»','(((\u001d\u001d\u001dÅ\u0015/ÉÐ\\\\ÿÂK³ÞïÓ¹sÎôîîî','JE>000á2\u001aj°\u0017ÿÀ\u0005rÏìHòòò*§ç','ÿÿÿµ@{{µ@µ{@@{µ{@µ@µ{øøø','(*6(*6ÿ\\\\WZ÷óùWÇÿÿjÁíþññð','+$@5ÿÓÿÓÿÓÿÓÿÓÿÓÿÓ','\u001a\u001a\u001a\u001a\u001a\u001aô_à$ú\u0019eÿô_XÑëÄŵ','\u0012\u0012\u0012âss¹yÿº{¾ÜáÀúÞÞÞ','$$$ÇVF³;а<r³ÌÈ Ñ!°°°','\u001b\u001c\u001d$%&øQ\u001bVWGúw\u001d,p·ð.O<¡¦','\u001b\u001d\u001e\u001b\u001d\u001es%ú#â`ÔßÐ\u0010ÿШC»»»','\u001e\u001e\u001e495Ï?a{·[é³*LÔ¥Ä8úúö','[email protected]ücB@CüéOûkuP{4ââÿÿÿ'],colors=[];\ncolorSchemes.forEach(cs=>{let scheme=cs.match(/.{1,3}/g),tm=[];for(let i=0;i<scheme.length;i++){let t=[];scheme[i].split('').forEach(s=>t.push(s.charCodeAt(0)));tm.push(t);if((i+1)%9==0){colors.push(tm);tm=[]}}});\nif( rn.r() > 0.5 ) {\n colors = []\n colors.push([[0,255,0],[0,255,0],[128,128,128],[0,255,0],[128,128,128],[255,0,64],[0,0,255],[0,0,0],[255,255,0]])\n colors.push([[255,0,0],[255,0,0],[255,255,255],[0,255,0],[255,255,255],[0,0,255],[0,0,255],[0,0,0],[255,255,0]])\n colors.push([[0,255,255],[255,0,0],[0,255,0],[0,255,0],[255,255,255],[0,0,255],[0,0,255],[0,255,0],[255,255,0]])\n colors.push([[0,0,0],[0,0,0],[0,0,255],[0,255,0],[255,255,255],[0,255,0],[255,0,255],[255,255,255],[0,0,0]])\n colors.push([[255,255,255],[255,0,0],[0,0,0],[0,0,0],[0,0,0],[0,0,0],[0,0,0],[0,0,0],[0,0,0]])\n colors.push([[255,255,255],[255,255,255],[0,0,0],[0,0,0],[0,0,0],[0,0,0],[0,0,0],[0,0,0],[0,0,0]])\n colors.push([[0,0,0],[255,255,255],[255,255,255],[255,255,255],[0,0,0],[128,128,128],[255,255,255],[255,255,255],[255,255,255]])\n colors.push([[255,255,255],[0,0,255],[0,0,0],[255,255,255],[255,0,0],[128,128,128],[255,255,255],[255,255,255],[255,255,255]])\n colors.push([[255,255,255],[255,255,255],[0,0,0],[255,255,255],[0,0,0],[128,128,128],[255,255,255],[255,255,255],[255,255,255]])\n colors.push([[0,0,0],[255,255,255],[255,0,255],[255,255,255],[0,0,0],[255,255,255],[0,0,0],[0,0,0],[255,255,255]])\n colors.push([[0,0,0],[255,255,255],[255,255,0],[255,255,255],[0,0,0],[255,255,255],[0,0,0],[0,0,0],[255,255,255]])\n colors.push([[0,0,0],[255,255,255],[0,255,0],[255,255,255],[0,0,0],[255,255,255],[0,0,0],[0,0,0],[255,255,255]])\n}\nlet colorIndex = Math.floor(rn.r()*colors.length)\nwindow.pal = colors[colorIndex]\nlet renderer = new _.WebGLRenderer(),scene = new _.Scene(), camera = new _.OrthographicCamera(),ww = innerWidth, wh = innerHeight,passthrough='varying vec2 vUv;void main(){vUv=uv;gl_Position=projectionMatrix*modelViewMatrix*vec4(position,1.);}';\ndocument.head.appendChild(document.createElement('style')).innerText=`html,body,canvas{width:100%;height:100%;padding:0;margin:0;position:fixed;overflow:hidden;}.tggl{position:fixed;z-index:10;font-family:Helvetica, sans-serif;color:#ffffff;font-size:10px;left:50%;bottom:10px;}label{display:inline-block;width:28px;height:16px;border-radius:100px;border:solid 1px #ffffff;top:3px;position:relative;}input{display:none;}i{height:14px;width:14px;background: #ffffff;display: inline-block;border-radius:100px;margin-left:2px;margin-top:1px;}input:checked+label>i {margin-left:12px;}`;\nlet ccv=document.createElement('canvas')\nlet aes = 1 + Math.floor(10 * rn.r());\nlet esrng = 10 + 300 * rn.r()\nif(rn.r()>.99){aes = 25;esrng=300;}\nlet curl = 0.3, dens = .998;\nlet cr=(r,o,s,c)=>{r.setRenderTarget(o.w);r.render(s,c);r.setRenderTarget(r.getRenderTarget());o.swap()}\nvar un='undefined',rnd=_=>{return rn.r()},zeros=n=>{return typeof n===un||isNaN(n)?[]:typeof ArrayBuffer===un?new Array(n).fill(0):new Float64Array(n)},randf=(a,b)=>{return rnd()*(b-a)+a;},randi=(a,b)=>{return Math.floor(rnd()*(b-a)+a);}\nclass GPUComputationRenderer{constructor(x,y,r){let v=[],a=0,s=new _.Scene(),c=new _.Camera(),p={T:{value:0}},C=()=>{return new _.WebGLRenderTarget(x,y,{wrapS:1001,wrapT:1001,minFilter:1003,magFilter:1003,format:1023,type:1015,depthBuffer:0})},S=(c,u)=>{let m=new _.ShaderMaterial({uniforms:u||{},vertexShader:'void main(){gl_Position=vec4(position,1.);}',fragmentShader:c});m.defines.rr='vec2('+x+','+y+')';return m;},M=S('uniform sampler2D T;void main(){vec2 uv=gl_FragCoord.xy/rr.xy;gl_FragColor=texture2D(T,uv);}',p),m=new _.Mesh(new _.PlaneGeometry(2,2),M),T=r.setRenderTarget,D=(n,o)=>{let t=r.getRenderTarget();m.material=n;T(o);r.render(s,c);m.material=M;T(t);},R=(i,o)=>{p.T.value=i;D(M,o);};c.position.z=1;s.add(m);this.v=(n,c,t)=>{let w={n:n,i:t,m:S(c),t:[],minFilter:1003,magFilter:1003};v.push(w);return w;};this.i=()=>{v.forEach(v=>{v.t=[C(),C()];R(v.i,v.t[0]);R(v.i,v.t[1]);v.d.forEach(d=>{v.m.uniforms[d.n]={value:0};v.m.fragmentShader='uniform sampler2D '+d.n+';\\n'+v.m.fragmentShader;});});a=0;};this.c=()=>{let c=a,n=a===0?1:0;v.forEach(v=>{let u=v.m.uniforms;v.d.forEach(d=>{u[d.n].value=d.t[c].texture;});D(v.m,v.t[n])});a=n};this.t=()=>{return new _.DataTexture(new Float32Array(x*y*4),x,y,1023,1015)};this.g=(v)=>{return v.t[a]}}};\nclass Text extends _.CanvasTexture{constructor(){super(ccv);ccv.width=2048;ccv.height=1024;let strs=[`../$ăĄĀĂĄĈāĈąĊċăčċĆĎďćĀĖĒ$ėĖĕĘčĚč\\nč__Āă|.ăģĪ/ħĩĤĨ$ĭ$ĪģĬİģĥıķĴĶďĚIJğŀ.IJIJęěĄ\\nł\\\\ĵłėŊİōĖŏĦİŁŕĿŗŎŗńİľćăʼnřŒŝľŃŤĄĽĉĀŅĉŬņŦťţűūśŐŕăĕŠőŴĮ/ŲijįŔŽſĸŶƃżůſŖľŜľĄIJšűƂƉƈĀ\\\\ƆƔŰņƗƓƋƙŻƚƈIJƗĨƚšŧ$ũĎłƍēŮŸƯƓƫƨŔƨũ.\\\\žƦƸĴĵŃƽī|ƾƿ_ĬǀŌLJžǂljNjǀdžljƼƽNJǃŒƾ`,`.Ā.__āĂăĀăćąĉĈČċĊĄąĂĒĆĕĆĄČ\\nā/Ā]ĀĜĂ]|ą\\\\ěĈĢĤĦġģģāĬąĭıĭ.ij|Ě.ĠĹĀ[ĄĭDĀ)ĸĻĽĀoŀł.ļĴŋĮŌĀıŏģđēĶňĠijīąĜŘ_ĨİŜĨ|ČĬţŏőĀ\\\\_ŗ\\nĠ.ũŎŊŘĥijűĀOŧŃŎŸĮĭ:Żĵ\\nĥşĒ|ŘŮƆƅƄƈƋƊƍŦŏĚũĉƅĉăƔ_|ũƗƓŢƕƛƖƝƜƕƘŮă,ƘơƩ`,`.._ĂāăĂ_ĄćĆĈāĀĀćĎčĉďă\\n./Ą|ĘČ\\\\Ěć)Ěę.ęģĢĥġ\\\\ėĢ\\nę(Ăę_|ġĖāıěĴģĮĢİĺĤ|Ĩģĕ\\\\Ć|Ńİ_łĮĆ/ŅŌĂň_/ńġŒ`,`.Ā_Ă㥹_āĆăĈĆĀĈč.ĂċćĐĂ\\nĀ/ĔĂĘĄěć\\\\ĝĚĔ.)Ġ_ĘĘė.ĨĪĬħĀ|Ĩ/ĖĮĩġħĦĬĶĢĹĸĴĭčĮŁ|Ľ.\\nķĶăě,ĐŇĽń/ʼnĪőŐňŁĩĨ\\n\\\\ĜąŐĘŃŔʼnŜŢśĜŚšıĦ`,`.#āĂĀĂăąā.ĄćĊăČĆ#ĉđĄĒĉĈđĈčĕĈ\\nĖĒĝėĐĚēĔĝĘġĞħĠĔģĢąĚěğįĥċĎĠĮĵĢĤĩĹĭĐĮİĻĬĪĽīijłļŃĨŊĖŌĐ\\nĎľćőĪŒőķŕŐŖŗĴıĄ`];this.str = de(strs[Math.floor(rn.r()*strs.length)]).replaceAll('.',' ');this.ln=this.str.split('\\n')[0].length}fill(v){let n=(!v)?1:4;return `rgba(${pal[n][0]},${pal[n][1]},${pal[n][2]},1)`;}update(v){let sp = new Array(this.str.split('\\n')[0].length).fill('#').join(''),ctx=ccv.getContext('2d'),lns=this.str.split('\\n');lns.push('','-','Training ~~~> '+(v?'True':'False'),sp,sp,sp,sp,sp);ctx.clearRect(0,0,ccv.width,ccv.height);ctx.fillStyle=this.fill(v);ctx.fillRect(0,0,ccv.width,ccv.height);ctx.fillStyle=this.fill(!v);ctx.font=70+\"px courier,monospace\";lns.forEach((l,i)=>{ctx.fillText(l,80,40+((2+i)*72));});}}\nclass Window extends _.Mesh{constructor(id,tt,ty,x,y,w=(.2+rn.r()*.4)*ww,h=(.2+rn.r()*.4)*wh){super();let t=this;Object.assign(t,{zid:id,drg:0,rsx:0,rsy:0});t.d=(id==0)?new _.Vector2(dims.x*1.01,dims.y*1.01):new _.Vector2(Math.min(w,h),Math.min(w,h));t.c=(id==0)?new _.Vector2(200*rn.r()-100,200*rn.r()-100):new _.Vector2((-ww+t.d.x)/2+rn.r()*(ww-t.d.x),(-wh+t.d.y)/2+rn.r()*(wh-t.d.y));t.p=t.position;t.s=t.scale;t.p.set(t.c.x,t.c.y,t.zid);t.s.set(t.d.x,t.d.y,1);t.geometry=new _.PlaneBufferGeometry(1,1);t.material=new _.ShaderMaterial({uniforms:{dims:{value:t.d},tex:{value:tt},tsz:{value:new _.Vector2(tt.image.width,tt.image.height)},wp:{value:t.p},wr:{value:t.s},inv:{value:(inv?1:0)},ch:{value:1},sd:{value:dims},type:{value:ty}},vertexShader:passthrough,fragmentShader:de('varying vec2ćUv;uniformćĉċdimsďđēĕ sampler2D texĞĒĔĖĈĊĬszİĠijĉ3 wpĹIJėcĽwrŁġĴċsdňĖfloat ĄĎĐıġbool chŎ ŐŒŔtype;Ťœ roĐdBox(Ńċcenĭr,ŷĢizežŬŔr ){Ůeturn ħąthŶmaŵ absŶŹŻĨƈ-ƀƂ +Ůž0.0ƈƭƣŇ }ƅşircħŶŊ pƄőŭƇƉƋƍƏƑźgƔŶpƮŮ;ƱƳĄnĨųrdĨMaskŶƳĚstƽťľidƔƈƊrƌƎƐƷĤpŶǝŔƧwǣƔƩƫž1ƫNjǬĥ(ǰǶ0ǸǺ)Ǎ}voǣ ƗĄ(Ɖƺsč =Čv *ľr.xy /ĢdƦ ŶĿȚȜƣņȥȖ ƪ5ƭȞŌȡŊŶȬƈ;ĒŶŧũȒȓǹƬ)ĢȑȓƹȑȞȲĶzȩȞȨțƭȗ8ȃȱĘȳǷɇ.Ȝȗƪ12ȭȧșȜȿȞȸķɖȪəɛƭƧɆƪȁ 24Ǻɡtɣɗȫ.ɚ5ȿȿ;ĴĽcŰŔȓĭxǃeĪȸĮžȐȕ).rgbɻĘƻȒȔȪĚĜȶfƞhǦɾuʀȊiƙʞǟŃ3ɓ9 ƣŖɥ.8Ƕʩʫnȕɘʮʰʪŕʳʭ8ƈʉmŜƔǞeǮ ʗsɤƣɮƫ1žˆˈɭɯɬpɤɹ ;ʤʔmʢƞɿžʦʨǶ3ˡ)žǼ˄-cƵƷeljʸɆɚɔˎȦ 13ȃž5˷ɵɬȽɹ˗ɿ˙˛ş˝˟ƪ2Ƕ̇ɵċˤʹǑrǓǕrǗǙƞ˪Ƹʓƣ˯2˱ěˇ˳˵˺˹ȾȂȾȵ˘ȓ˚ʣ̄˟ɵˢ̭ˣ˥lǭŶ˨̖ˬ̘ŷŶ26̜Ĝˏ̠̣ ̢ʽ˻̤˾̧ʡ̪ʟžɼ(̆̈̈̈́ǐǒĔ̑̓ǚƴƶ̗NJ̙ɒɭ̼ɬ˲ʸ̀̈́̓̌ȽƭȄ͈̩˜͋ ̬ƪ̮ͱ̰ş̲ǽʪ˩̷͚̹͜ 4ɫˍ̝̿˶́ͦĄ̦̏͆̀̂ʤ͌ļ͎.̉͏̊͒n̎̐ǖǘ͘˫˭͝ĊŶͿ̞̽ͣ΄ͥ˺ͨ˾ƲƾŔǰʔůűųƙͼˆȝɭΣζ̛Ƭž͠Ήʟ́͊ʥ͍˴ɔȽ̤ΕΗ͕Ἱ˅iǞχ˾gl_FragCŝĔʍʏʔʤ;ϒϔϖϘϚșaʔͨƣsʿoˁĭ˧ȬǶ5žǯώŔΪ'),transparent:1}); };updatePosition(p){this.c.x+=p.x;this.c.y-=p.y;};updateDimensions(p){let t=this,dx=t.d.x,dy=t.d.y;if(t.rsx){t.d.x+=p.x;t.d.x=Math.max(t.d.x,360);t.c.x+=(t.d.x-dx)/2;}if(t.rsy){t.d.y+=p.y;t.d.y=Math.max(t.d.y,240);t.c.y-=(t.d.y-dy)/2;}}step(e){let t=this,ev=t.c.clone().normalize();t.p.x+=((t.c.x+ev.x*1000*e)-t.p.x)*.6;t.p.y+=((t.c.y+ev.y*1000*e)-t.p.y)*.6;t.s.x+=(t.d.x-t.s.x)*.6;t.s.y+=(t.d.y-t.s.y)*.6;t.material.uniforms.dims.value=new _.Vector2(t.s.x,t.s.y);t.p.z=((t.zid+1)*150)-150;t.material.uniforms.wp.value=t.p;t.material.uniforms.wr.value=t.s;}}class Ascii extends _.WebGLRenderTarget{constructor(w,h,r){super(w*devicePixelRatio,h*devicePixelRatio);let u=this,g=\" ▏▎▍▌▋▊▉`◦~+¤▲▜▓═╤╟╩═╫╬╪⁃)10‘™◊∞ .˚◦©o@● '^;-\\zbB ␣▗▘▚▙░☻.:-=+*#▒\".split(''),c=document.createElement('canvas'),s=256,t=8,a=c.getContext('2d');c.width=c.height=s*t;a.font='300px courier,monospace';g.forEach((l,i)=>a.fillText(l,s*(i%t)+10,s*(Math.floor(i/t))+200));u.w=w;u.h=h;u.renderer=r;u.cp=new GPUComputationRenderer(w,h,r);u.rv = u.cp.v( 'accumulateTex', de('uniform vec2 mouse;ĀĂĄĆĈĊ res;voidČain(){ėċuv=gl_FragCoĄd.xy/rrĹyĝĉ4 p=textuĚ2D(accumulaŇTň,ī);p.b+=(1.-sčothsŇp(.0,.5,((lengūŷčďe-Ŝ*ĩŤ.,Ěs.ĻƉĹ)Ə/ŴƏ)/ƆƑ5)*.2ŞŠ=cŖmůşb,0ƇťŝƤ-=Ƥƚ01;ĮİIJĴolĄƭ;}'),u.cp.t());u.rv.m.uniforms={mouse:{value:new _.Vector2()},res:{value:new _.Vector2(w,h)}};u.rv.d=[u.rv];u.cp.i();u.s=new _.Scene();u.c=new _.OrthographicCamera(-1,1,1,-1,.01,10);u.mat=new _.ShaderMaterial({uniforms:{ms:{value:8*devicePixelRatio},dpr:{value:devicePixelRatio},data:{value:null},res:{value:new _.Vector2(w,h)},seed:{value:new _.Vector3(rn.r(),rn.r(),rn.r())},txt:{value:new _.CanvasTexture(c)},bgc:{value:new _.Vector3(pal[2][0],pal[2][1],pal[2][2])},fgc:{value:new _.Vector3(pal[0][0],pal[0][1],pal[0][2])}},vertexShader:passthrough,fragmentShader:de('varying vec2ćUv;uniform float msďđēĕėęě dprĠĒĔĖsampler2DħěaīĢĮİIJĴĶ txtĻĭćĉċreğĐĬģĈc3 bgcņŐĉœfŖŘĖőœseed;voidĝaĄ(){őċp=gl_FragCoĔd.xy;ĘĚĜmm=teńuŋĶ(ĸta,(ƄĔ(p/Ğ)/Ɩr(ŋsƚs))*(1./Ĩrƥ.b*8.;Ē(ŢŤƀ>.5)Ƈ=ƞ(Ƈ);ŵŷŹŻoęr=ő4ǁix(ŕc/255.,Ŝǔǖǘ,ƊƌƎD(ŃtƔmodƘ,ƛƣƜƲ+űǁm/ƲǚęƗƷſyƱ.ǯǾ).a),Ʃǃ}'),transparent:1,depthWrite:0,depthTest:0});u.mesh=new _.Mesh(new _.PlaneBufferGeometry(w,h),u.mat);u.s.add(u.mesh);u.c.position.z=1;u.c.updateProjectionMatrix()}updatePosition(p){this.rv.m.uniforms.mouse.value=new _.Vector2(p.x/this.w,1-p.y/this.h)}step(){let t=this;t.cp.c();t.mesh.material.uniforms.data.value=t.cp.g(t.rv).texture;t.renderer.setRenderTarget(t);t.renderer.render(t.s,t.c);t.renderer.setRenderTarget(null);}}\nclass SlabOpBase{constructor(f,u,g){this.g=g;this.uniforms=u;this.ca=new _.OrthographicCamera(-1,1,1,-1,0,1);this.sc=new _.Scene();this.sc.add(new _.Mesh(new _.PlaneGeometry(2*(g.size.x-2)/g.size.x,2*(g.size.y-2)/g.size.y),new _.ShaderMaterial({uniforms:u,fragmentShader:f,depthWrite:0,depthTest:0,blending:0})))};}\nclass AdvectOp extends SlabOpBase{constructor(g){super(de('uniform sampler2D v;ĀĂĄĆĈĊČĎĐaēāăąđec2 gzĞĕġfloatĦsĩĠĆĬĮİtIJĔĴ Ķį dIJvģĥb(Ęċčďŀ,ŃĤ p){Ŏ4 ij;ŗ.xy=ĶĄ(p-.5)+Ťřj.zw=ŚŜ+1.;Ŕ uvŮj/ħśyŜŴńŀ11=textureď(d,ŷŽ)Žƀŏd2ƄƆƈƊƌDƎƐvūyƓſŎĥd12ƅƇƉƋƍƏƑxwƤyƕƧ2ƪƚƭƝƟƑŬƴƶ a=ŢůƵƋƭn mix(njǎƨ1,ƗǓaś),ǐƎƩǔƸ,ǗxǙǗƣ;}voidNjain(ŒƦŐ=gl_FragCoĄdŽ-Ĺ*(ŲŻs)*ƺƜƍv,ǵǷǹǻǽrǿŜŻzƒƔȏǸǺǼĭr=ŔƎs*ņa,ő,0.,Ų)Ǧ'),{v:{},a:{},gz:{},gs:{},ts:{},ds:{}},g)};compute(r,v,a,o){[['v',v.r.texture],['a',a.r.texture],['gz',this.g.size],['gs',1],['ts',1],['ds',dens]].forEach(u=>{this.uniforms[u[0]].value=u[1]});cr(r,o,this.sc,this.ca);}}\nclass JacobiOp extends SlabOpBase{constructor(g){super(de('uniform sampler2D x;ĀĂĄĆĈĊČĎĐbēāăą vec2 gzĞĕġfloat aĪĠĆĭįıbt;void main(){ģĥ uv=gl_FragCoĄd.xy/ĨŚy,xo=ʼn2(1.ŝzŚ,.0),yţť(0.,ŨŪ.y);ŏőœŕoĮrŤĤ4((textureď(x,Ō-Ţ)Ś+ƋƍƏƑDƓƕv+ƘƚƜƎƐƒƔƖŲƙxƛƌƨƟơŌ+ƭƚa*ƧƞƒbƢƮ)/ĺ,ŶDŽŷŨŽ}'),{x:{},b:{},gz:{},a:{},bt:{}},g);}compute(r,x,b,o){for(var i=0;i<50;i++)this.step(r,x,b,o);}step(r,x,b,o){[['x',x.r.texture],['b',b.r.texture],['gz',this.g.size],['a',-1],['bt',4]].forEach(u=>{this.uniforms[u[0]].value=u[1]});cr(r,o,this.sc,this.ca)}}\nclass DivergenceOp extends SlabOpBase{constructor(g){super(de('uniform sampler2D v;ĀĂĄĆvec2 gzēāăą floatĜs;void main(){ĘĚ uv=gl_FragCoĄd.xy/ĝʼny,xo=ĸ2(1.Ōzʼn,.0),yŒŔ(0.,ŗř.y);ľŀłńoĥrœę4((.5Ōs)*(textureď(v,Ļ+ő)ʼn-ƁƃƅƇDƉƋv-Ǝʼn+ƒƄƆƈƊƌšƏyƑƂƟƕƗĻ-ƤŪşť,ƱŗŬ}'),{v:{},gz:{},gs:{}},g)};compute(r,v,d){[['v',v.r.texture],['gz',this.g.size],['gs',1]].forEach(u=>{this.uniforms[u[0]].value=u[1]});cr(r,d,this.sc,this.ca)}};\nclass GradientOp extends SlabOpBase{constructor(g){super(de('uniform sampler2D p;ĀĂĄĆĈĊČĎĐwēāăą vec2 gzĞĕġfloatħs;void main(){ģĥ uv=gl_FragCoĄd.xy/ĨŒy,xo=Ł2(1.ŕzŒ,0.),yśŝ(Ŧ,ŠŢ.y);ŇʼnŋōoĮrŜĤ4(textureď(w,ń)ŗ-((.5ŕs)*ŬƁƃƅƇD(pƋv+Śƍx-ƙƄƆƈƟń-ƣŤƧƛƪƠ+ŪƤƦƂƨƜƞƠ-ƵŒ)ŨŮŠŴ}'),{p:{},w:{},gz:{},gs:{}},g)};compute(r,p,w,o){[['p',p.r.texture],['w',w.r.texture],['gz',this.g.size],['gs',1]].forEach(u=>{this.uniforms[u[0]].value=u[1]});cr(r,o,this.sc,this.ca)}}\nclass SplatOp extends SlabOpBase{constructor(g){super(de('uniform sampler2D r;ĀĂĄĆvec2 gzēāăą Ęc3 clğĕĢĤěpĪġĆfloatđd;ijĵķgs(ĭ p,ĻĶđ){return exp(-dot(Ńp)/r);}void main(ňgl_FragCoĴr=Ĥ4(tőŌŊď(r,(ŭůűųoĄd.xy/ĝƌy))Ƒz*.99+(Ĩ*ľřƑ-ƅŰŲŴƊƑ,Ɛx*rdƓ,1.ş}'),{r:{},gz:{},cl:{},p:{},rd:{}},g)};compute(r,i,c,p,o){[['gz',this.g.size],['r',i.r.texture],['cl',c],['p',p],['rd',1.5]].forEach(u=>{this.uniforms[u[0]].value=u[1]});cr(r,o,this.sc,this.ca)}}\nclass VorticityOp extends SlabOpBase{constructor(g){super(de('uniform sampler2D v;ĀĂĄĆvec2 gzēāăą floatĜs;void main(){ĘĚ uv=gl_FragCoĄd.xy/ĝʼny;ľŀłńoĥr=ĸ4((.5Ōs)*(textureď(v,Ļ+ĸ2(1.Ōzʼn,.0)).y-ŤŦŨŪDŬŮv-űųŵōxŹŻŽſƁŧũūŭůƊ0.,ŴŶžżʼn+ƓƃƖƇƉęŲƚƜƌŷyƠx),ƪƪŴ);}'),{v:{},gz:{},gs:{}},g)};compute(r,v,o){[['v',v.r.texture],['gz',this.g.size],['gs',1]].forEach(u=>{this.uniforms[u[0]].value=u[1]});cr(r,o,this.sc,this.ca)}}\nclass VorticityConfinementOp extends SlabOpBase{constructor(g){super(de('uniform sampler2D v;ĀĂĄĆĈĊČĎĐvoēāăąđec2 gzğĕĢfloatħsĪġĆĭįıtijĔĵ ķİ eĴĖģĥ c;ĝid main(){vĤĦuv=gl_FragCoĄd.xy/ĨŦy,xo=ŕĥ(1.ũzŦ,.0),yůű2(0.,ŴŶ.y)ʼnŖľ=(.5ũs)*ƀ(abs(textureď(ĝ,Ř+ž)Ŧ)-ƘƚƜƞƠƢDƤoƦv-Ʃƫ,ƮƛƝƟơƣƥƧŮƪxƬƽưǀƳƵƷ-DžƫƊf*=Őŕrsesqrt(Ŏx(e,doǞf,f)ǫ*c*NJƲǂƶŘdž;fƈǔ-Ŵ;śŝşšoĮrŰĤ4ƾƱǁƴvƷdžy+ƛs*Ǫ,ƃƅ.Ɗ}'),{v:{},vo:{},gz:{},gs:{},ts:{},e:{},c:{value:new _.Vector2()}},g)}compute(r,v,vo,o){[['v',v.r.texture],['vo',vo.r.texture],['gz',this.g.size],['gs',1],['ts',1],['e',2.4414e-4],['c',new _.Vector2(curl*1,curl*1)]].forEach(u=>{this.uniforms[u[0]].value=u[1]});cr(r,o,this.sc,this.ca)}}\nclass Slab{constructor(w,h){this.r=new _.WebGLRenderTarget(w,h,{magFilter:1003,minFilter:1003,type:1015,depthBuffer:0});this.w=this.r.clone();}swap(){var t=this.r;this.r=this.w;this.w=t}}\nclass Solver{constructor(g){var w=g.size.x,h=g.size.y;Object.assign(this,{g:g,v:new Slab(w,h),d:new Slab(w,h),vd:new Slab(w,h),vv:new Slab(w,h),p:new Slab(w,h),a:new AdvectOp(g),divergence:new DivergenceOp(g),ppe:new JacobiOp(g),gradient:new GradientOp(g),splat:new SplatOp(g),vorticity:new VorticityOp(g),vc:new VorticityConfinementOp(g),source:new _.Vector3(.5,.5,.5)})};step(r,m){let t=this.a.d,s=this;s.a.d=1;s.a.compute(r, s.v, s.v, s.v);s.a.d=t;s.a.compute(r,s.v,s.d,s.d);var p=new _.Vector2((m.position.x/s.g.size.x)*s.g.size.x,((s.g.size.y-m.position.y)/s.g.size.y)*s.g.size.y);s.splat.compute(r,s.v,new _.Vector3(m.velocity.x*.1,-m.velocity.y*.1,0),p,s.v);s.splat.compute(r,s.d,s.source,p,s.d);s.vorticity.compute(r,s.v,s.vv);s.vc.compute(r,s.v,s.vv,s.v);s.project(r);};project(r){let t=this;t.divergence.compute(r,t.v,t.vd);t.cs(r,t.p);t.ppe.alpha=-t.g.scale*t.g.scale;t.ppe.compute(r,t.p,t.vd,t.p);t.gradient.compute(r,t.p,t.v,t.v);};cs(r,s){r.setRenderTarget(s.w);r.clear(1,0,0);r.setRenderTarget(r.getRenderTarget());s.swap();}}\nclass Display extends _.WebGLRenderTarget{constructor(w,h,fs){super(w,h,{wrapS:1002,wrapT:1002});Object.assign(this,{m:new _.ShaderMaterial({uniforms:{},vertexShader:passthrough,fragmentShader:fs,depthWrite:0,depthTest:0}),c:new _.OrthographicCamera(-1,1,1,-1,0,1),s:new _.Scene()});this.s.add(new _.Mesh(new _.PlaneGeometry(2,2),this.m))}render(rr,r){this.m.uniforms={r:{value:r.texture}};rr.setRenderTarget(this);rr.render(this.s,this.c);rr.setRenderTarget(null);}}\nclass Fluid{constructor(w,h,r){let t=this,s=Math.min(512,w),g={size:new _.Vector2(s,s)};t.r=r;t.s=s/w;t.motion={position:{x:0,y:0},velocity:{x:0,y:0}};t.op=new _.Vector2();t.sol=new Solver(g,new _.Vector2(s,s));t.velocityRT=new Display(s,s,'uniform sampler2D r;varying vec2 vUv;void main(){gl_FragColor=vec4(texture2D(r,vUv).xyz+.5,1.);}',r);t.densityRT=new Display(s,s,'uniform sampler2D r;varying vec2 vUv;void main(){gl_FragColor=vec4(vec3(dot((texture2D(r,vUv).xxx*vec3(vUv,1.)),vec3(.299,.587,.114))),1.);}',r);}updatePosition(p){let t=this;p.x*=t.s;p.y*=t.s;t.motion={position:{x:p.x,y:p.y},velocity:new _.Vector2(p.x-t.op.x,p.y-t.op.y)};t.op.set(p.x,p.y)}step(){let t=this;t.sol.step(t.r,t.motion);t.velocityRT.render(t.r,t.sol.v.r);t.densityRT.render(t.r,t.sol.d.r)}}\nclass FSQ{constructor(m){this.material=m;let g=new _.BufferGeometry();g.setAttribute('position',new _.Float32BufferAttribute([-1,3,0,-1,-1,0,3,-1,0],3));g.setAttribute('uv',new _.Float32BufferAttribute([0,2,0,0,2,0],2));this.m=new _.Mesh(g,m);};render(r){r.render(this.m,new _.OrthographicCamera(-1,1,1,-1,0,1));}};\nclass AfterimagePass{constructor(d){this.needsSwap=1;this.u=_.UniformsUtils.clone({'d':{value:d},'o':{value:0},'n':{value:0}});let p={minFilter:1006,magFilter:1003,format:1023};this.a=new _.WebGLRenderTarget(1,1,p);this.b=new _.WebGLRenderTarget(1,1,p);this.c=new FSQ(new _.ShaderMaterial({uniforms:this.u,vertexShader:passthrough,fragmentShader:de('uniform float d;ĀĂĄĆsampler2D oďāăą ĔĖĘĚĜn;varying vec2IJUvĪoid maį(){ijc4 to=textureě(o,vĸ);ʼn*=d*Ŀx(sign(ʼn-.1),0.řgl_FragCoĉr=ŠŧōŏőœnŖŘ,ʼnř}')}));this.d=new FSQ(new _.MeshBasicMaterial());};render(r,w,b){this.u.o.value=this.b.texture;this.u.n.value=b.texture;r.setRenderTarget(this.a);this.c.render(r);this.d.material.map=this.a.texture;r.setRenderTarget(w);this.d.render(r);let t=this.b;this.b=this.a;this.a=t;};setSize(w,h){this.a.setSize(w,h);this.b.setSize(w,h);}};\nclass RenderPass{constructor(s,c){this.s=s;this.c=c;};render(r,_,b){let oldAutoClear=r.autoClear;r.autoClear=0;r.setRenderTarget(b);r.clear(r.autoClearColor,r.autoClearDepth,r.autoClearStencil);r.render(this.s,this.c);r.autoClear=oldAutoClear;};setSize(){}};class EffectComposer{constructor(r){this.r=r;let s=r.getSize(new _.Vector2());this.p=r.getPixelRatio();this.w=s.width;this.h=s.height;let t=new _.WebGLRenderTarget(this.w*this.p,this.h*this.p,{minFilter:1006,magFilter:1006,format:1023});this.u=t;this.v=t.clone();this.b=this.u;this.readBuffer=this.v;this.renderToScreen=1;this.t=[];this.c=new _.Clock();}sb(){let tmp=this.readBuffer;this.readBuffer=this.b;this.b=tmp;}addPass(p){this.t.push(p);p.setSize(this.w*this.p,this.h*this.p);}lp(p){for(let i=p+1;i<this.t.length;i++)if(this.t[i].enabled)return 0;return 1;}render(){let d=this.c.getDelta(),c=this.r.getRenderTarget();this.t.forEach(p=>{p.renderToScreen=this.renderToScreen&&this.lp(i);p.render(this.r,this.b,this.readBuffer,d,0);if(p.needsSwap)this.sb();});this.r.setRenderTarget(c);};setSize(w,h){this.w=w;this.h=h;let x=this.w*this.p,y=this.h*this.p;this.u.setSize(x,y);this.v.setSize(x,y);this.t.forEach(p=>p.setSize(x,y)); }};\nclass Particles extends EffectComposer{constructor(w,h,r,rf){super(r);let t=this,sz=1024,s=new _.Scene(),c=new _.OrthographicCamera(),ps=[],ds=[];t.bgp=new _.Mesh(new _.PlaneBufferGeometry(w,h),new _.MeshBasicMaterial({color:0x000000}));t.bgp.position.z=-1;s.add(t.bgp);for(var i=0;i<sz*sz;i++){ps.push((rn.r()-.5)*4,(rn.r()-0.5)*4,rn.r(),0);ds.push((i%sz)/sz,(Math.floor(i/sz))/sz,0,0);}let geo=new _.BufferGeometry();geo.setAttribute('position',new _.BufferAttribute(new Float32Array(ps),4));geo.setAttribute('particleData',new _.BufferAttribute(new Float32Array(ds),4));t.prts=new _.Points(geo,new _.ShaderMaterial({uniforms:{positionData:{value:null},dpr:{value:devicePixelRatio}},vertexShader:de('attribute vec4 particleDĀa;uniform sampĕr2DĎosiĒonėtęěĝğġfloĀ dpr;void main(){gl_PŃntSize=(ľr>1.)?4.:2.;ŎŐĬĮiİ=ĿojċįnMĀăx*modelViewŵĂiŸĊČ(Ƈ3(ćxtureĩ(pŪųIJa,ďđēĕƘ.xy)Ơy,0ş,Ş);}'),fragmentShader:'void main(){gl_FragColor=vec4(1.,1.,1.,smoothstep(.45,.75,1.-length(vec2(gl_PointCoord.x,gl_PointCoord.y)-vec2(.5))*2.));}',transparent:1,depthWrite:0,depthTest:0}));s.add(t.prts);t.gpC=new GPUComputationRenderer(sz,sz,r);let positionTex=t.gpC.t();positionTex.image.data=new Float32Array(ps);t.pVar=t.gpC.v('texturePosition',de('uniform float time;ĀĂĄĆsampler2D veĉcityTex;ġc3 pĜmute(ĬĮx){return mod(ņx*34.)+1Ō*x,289Ō;}ĈĊČsnĶec2ĠĺconsČĬ4 C=Ū(.211324865405187,.36602ź03784439,-.57735Ɔ69ž9626ƁƆƎ9ƢƏƥ9)īŠŢi=ŚĄĶ+dotĶ,C.yy)),x0Ů-iƲƴ(iƷ.xĹ,i1;Ǎ=(ƿlj>Ǔƻ?Ĭ2(ŏ,0Ō:Ǚ(Ǟ,ŏƩŪ x12=ǓxyǮ+ƸNJzz;ǩ2ljy-=ǍǏ=ŃŅLJŔŖǦŠĮp=İąijĵȊIJĴdžƹ+ķǢ.njŏyǤŌōiljȓȆȕȗljȚƼƪĭłǿaxŰ5-ȔƳƵƿƾ0ƽȰǒǪǹƾȸǮȵDžǷ.zwȺǸɁƼơƩmǿ*m;ɉmɋȦĸ=Ǹ*fracƵp*Ƹwɞ)-ŏɑ h=absǒɠƓɣoxƮĉưx+Ɠȅȧaǀx-ɮɍ*=ŏ79Ŕ42ƛŻ0159ƒ85ƊŊ7209ʎ14*(ɸ*ɸ+h*hɶĮg;gljɦǞňǭʝljőǞyʤƹzʧʱőȻzʫyzʵǸyw;ļľŀ ŴǞ*ȶm,gƩ}voidłaiŞĺǧpos=ĴxˁeĞ(˛˝P˘ĥiŦˉl_FɗgCoĄdǹ/rrǹƩ˗sǹ+˚ĩ˝˟ġģĥħĩ,(˸˺ǥ*ɵǹ̊0Ɔ;̇zǻ.̎ǎĂ̆˘ɀ<=ǞĺŚċ n1=ŝşš̘˹ň1ǣĎĐȥ̟Čnǫ̥ǡ̇y*̫Ṷ̑eȥ̇ǮʲȔ̸̢Ɠ,̲̓5ȤŘg˩˫a˭oĉrȉ˘Ř'),positionTex);t.pVar.m.uniforms={time:{value:0},velocityTex:{value:rf}};t.pVar.d=[t.pVar];t.gpC.i();t.addPass(new RenderPass(s,c));t.afterImagePass=new AfterimagePass(.97);t.addPass(t.afterImagePass);t.renderToScreen=0;t.prts.scale.set(w/2,h/2,1);Object.assign(c,{left:w/-2,right:w/2,top:h/2,bottom:h/-2});c.position.z=1;c.updateProjectionMatrix();t.setSize(w*devicePixelRatio,h*devicePixelRatio)};step(){this.prts.material.uniforms.positionData.value=this.gpC.g(this.pVar).texture;this.pVar.m.uniforms.time.value+=.01;this.gpC.c();this.render()}}\nclass Vol{constructor(x,y,d,c){var n=x*y*d;Object.assign(this,{rv:0,vv:0,sx:x,sy:y,d:d,w:zeros(n),dw:zeros(n)});for(var i=0;i<n;i++)this.w[i]=typeof c===un?this.gRnd()*Math.sqrt(1/(x*y*d)):c;}clone(){var V=new Vol(this.sx,this.sy,this.d,0);this.w.forEach((w,i)=>V.w[i]=w);return V;}gRnd(){if(this.rv){this.rv=0;return this.vv;}var u=2*rnd()-1,v=2*rnd()-1,r=u*u+v*v;if(r===0||r>1)return this.gRnd();var c=Math.sqrt((-2*Math.log(r))/r);this.vv=v*c;this.rv=1;return u*c;}fromJSON(j){this.sx=j.sx;this.sy=j.sy;this.d=j.depth;var n=this.sx*this.sy*this.d;this.w=zeros(n);this.dw=zeros(n);for(var i=0;i<n;i++){this.w[i]=j.w[i]}}}\nclass FullyConnLayer{constructor(o={}){this.out_depth=o.num_neurons||o.filters;this.l1_decay_mul=o.l1_decay_mul||0;this.l2_decay_mul=o.l2_decay_mul||1;this.num_inputs=o.in_sx*o.in_sy*o.in_depth;this.out_sx=1;this.out_sy=1;this.filters=[];for(var i=0;i<this.out_depth;i++){this.filters.push(new Vol(1,1,this.num_inputs));}this.bs=new Vol(1,1,this.out_depth,0);}forward(V){this.ia=V;var A=new Vol(1,1,this.out_depth,0);var Vw=V.w;for(var i=0;i<this.out_depth;i++){var a=0,wi=this.filters[i].w;for(var d=0;d<this.num_inputs;d++){a+=Vw[d]*wi[d];}a+=this.bs.w[i];A.w[i]=a;}this.out_act=A;return this.out_act;}backward(){var V=this.ia;V.dw=zeros(V.w.length);for(var i=0;i<this.out_depth;i++){var tfi=this.filters[i],cg=this.out_act.dw[i];for(var d=0;d<this.num_inputs;d++){V.dw[d]+=tfi.w[d]*cg;tfi.dw[d]+=V.w[d]*cg;}this.bs.dw[i]+=cg;}}getPrms(){var r=[];for(var i=0;i<this.out_depth;i++){r.push({params:this.filters[i].w,grads:this.filters[i].dw,l1_decay_mul:this.l1_decay_mul,l2_decay_mul:this.l2_decay_mul});};r.push({params:this.bs.w,grads:this.bs.dw,l1_decay_mul:0,l2_decay_mul:0});return r;}fromJSON(j){new Array('out_depth','out_sx','out_sy','num_inputs','l1_decay_mul','l2_decay_mul').forEach(d=>{this[d]=j[d]||1});this.filters=[];j.filters.forEach(f=>{var v=new Vol(0,0,0,0);v.fromJSON(f);this.filters.push(v);});this.bs=new Vol(0,0,0,0);this.bs.fromJSON(j.biases);}}\nclass InputLayer{constructor(o={}){this.out_depth=this.go(o,['out_depth','depth'],0);this.out_sx=this.go(o,['out_sx','sx','width'],1);this.out_sy=this.go(o,['out_sy','sy','height'],1)}go(o,f,d){var r=d;f.forEach(f=>{if(typeof o[f]!==un)r=o[f]});return r}forward(v){return v;}backward(){}getPrms(){return []}fromJSON(j){Object.keys(j).forEach(k=>this[k]=j[k])}}\nclass RegressionLayer{constructor(o={}){this.num_inputs=o.in_sx*o.in_sy*o.in_depth;this.out_depth=this.num_inputs;this.out_sx=1;this.out_sy=1}forward(V){this.ia=V;this.out_act=V;return V;}backward(y){var x=this.ia;x.dw=zeros(x.w.length);var l=0,i=y.dim,yi=y.val,dy=x.w[i]-yi;x.dw[i]=dy;l+=.5*dy*dy;return l;}getPrms(){return []}fromJSON(j){Object.keys(j).forEach(k=>this[k]=j[k])}}\nclass ReluLayer{constructor(opt={}){this.out_sx=opt.in_sx;this.out_sy=opt.in_sy;this.out_depth=opt.in_depth;}forward(V){this.ia=V;var V2=V.clone(),N=V.w.length,V2w=V2.w;for(var i=0;i<N;i++){if(V2w[i]<0)V2w[i]=0;}this.out_act=V2;return this.out_act;}backward(){var V=this.ia,V2=this.out_act,N=V.w.length;V.dw=zeros(N);for(var i=0;i<N;i++){if(V2.w[i]<=0)V.dw[i]=0;else V.dw[i]=V2.dw[i]}}getPrms(){return []}fromJSON(j){Object.keys(j).forEach(k=>this[k]=j[k])}}\nclass Net{constructor(){this.layers=[]}makeLayers(defs){var desugar=_=>{var new_defs=[];defs.forEach(def=>{if(def.type==='regression')new_defs.push({type:'fc',num_neurons:def.num_neurons});if((def.type==='fc')&&typeof (def.bias_pref)===un){def.bias_pref=(typeof def.activation!==un&&def.activation==='relu')?0.1:0;}new_defs.push(def);if(typeof def.activation!==un){if(def.activation==='relu'){new_defs.push({type:'relu'});}}});return new_defs;};defs = desugar(defs);this.layers=[];defs.forEach((def,i)=>{if(i>0){def.in_sx=this.layers[i-1].out_sx;def.in_sy=this.layers[i-1].out_sy;def.in_depth=this.layers[i-1].out_depth;}this.layers.push(this.getLayer(def.type,def))})}forward(V, t){if(typeof(t)===un)t=0;var act=this.layers[0].forward(V,t);for(var i=1;i<this.layers.length;i++){act=this.layers[i].forward(act,t);}return act;}backward(y){var N=this.layers.length,l=this.layers[N-1].backward(y);for(var i=N-2;i>=0;i--)this.layers[i].backward();return l;}getPrms(){var r=[];this.layers.forEach(l=>l.getPrms().forEach(p=>r.push(p)));return r;}getLayer(t,p){return new {input:InputLayer,relu:ReluLayer,regression:RegressionLayer,fc:FullyConnLayer}[t](p)}fromJSON(j){this.layers=[];j.layers.forEach(Lj=>{var L = this.getLayer( Lj.layer_type,undefined);L.fromJSON(Lj);this.layers.push(L);})}}\nclass Trainer{constructor(n){this.net=n;this.learning_rate=.001;this.l1_decay=0;this.l2_decay=.01;this.bs=64;this.k=0;}train(x,y){this.net.forward(x,1);var s=new Date().getTime(),e=new Date().getTime(),ft=e-s,s=new Date().getTime(),cl=this.net.backward(y),l2dl=0,l1dl=0,e=new Date().getTime(),bt=e-s;this.k++;if(this.k%this.bs===0){var pgl=this.net.getPrms();for(var i=0;i<pgl.length;i++){var pg=pgl[i],p=pg.params,g=pg.grads,l2dm=pg.l2_decay_mul||1,l1dm=pg.l1_decay_mul||1,l2d=this.l2_decay*l2dm,l1d=this.l1_decay*l1dm;for(var j=0;j<p.length;j++) {l2dl+=l2d*p[j]*p[j]/2;l1dl+=l1d*Math.abs(p[j]);p[j]+=-this.learning_rate*(((l2d*(p[j]))+(l1d*(p[j]>0?1:-1))+g[j])/this.bs);g[j]=0;}}}return {fwd_time:ft,bwd_time:bt,l2_decay_loss:l2dl,l1_decay_loss:l1dl,cost_loss:cl,softmax_loss:cl,loss:cl+l1dl+l2dl} }}\nclass Win{constructor(s,m){this.v=[];this.size=s;this.ms=m;this.sum=0;}add(x){this.v.push(x);this.sum+=x;if(this.v.length>this.size){this.sum-=this.v.shift();}}get_average(){if(this.v.length<this.ms)return -1;else return this.sum/this.v.length;}}\nclass Vec{constructor(x,y){this.x=x;this.y=y;}dist_from(v){return Math.sqrt(Math.pow(this.x-v.x,2)+Math.pow(this.y-v.y,2));}length(){return Math.sqrt(Math.pow(this.x,2)+Math.pow(this.y,2));}add(v){return new Vec(this.x+v.x,this.y+v.y);}sub(v){return new Vec(this.x-v.x,this.y-v.y);}rotate(a){return new Vec(this.x*Math.cos(a)+this.y*Math.sin(a),-this.x*Math.sin(a)+this.y*Math.cos(a));}scale(s){this.x*=s;this.y*=s;}normalize(){var d=this.length();this.scale(1.0/d);}}class Brain {constructor(ns,na,o){Object.assign(this,{ni:ns+na+ns,ns:ns,num_actions:na,s_w:[0,0],a_w:[0,0],r_w:[0,0],n_w:[0,0],xp:[],age:0,f_p:0,epsilon:1,latest_reward:0,last_input_array:[],average_reward_window:new Win(1000,10),average_loss_window:new Win(1000,10),learning:1});this.value_net=new Net();this.value_net.makeLayers(o.layer_defs);this.tdt=new Trainer(this.value_net);}ra(){return randi(0,this.num_actions);}policy(s){var svol=new Vol(1,1,this.ni);svol.w=s;var aw=this.value_net.forward(svol),maxk=0,maxval=aw.w[0];for(var k=1;k<this.num_actions;k++){if(aw.w[k]>maxval){maxk=k;maxval=aw.w[k];}}return {action:maxk,value:maxval};}getNetInput(xt){var w=[],n=2;w=w.concat(xt);w=w.concat(this.s_w[n-1]);var act=new Array(this.num_actions);for(var q=0;q<this.num_actions;q++)act[q]=0;act[this.a_w[n-1]]=1*this.ns;return w.concat(act);}forward(ia){this.f_p+=1;this.last_input_array=ia;var c;if(this.f_p>1){var ni=this.getNetInput(ia);this.epsilon=(this.learning)?Math.min(1,Math.max(.05,1-(this.age-3000)/(200000-3000))):.05;c=(randf(0,1)<this.epsilon)?this.ra():this.policy(ni).action;}else{var ni=[];c=this.ra();}this.n_w.shift();this.n_w.push(ni);this.s_w.shift();this.s_w.push(ia);this.a_w.shift();this.a_w.push(c);return c;}backward(r){this.latest_reward=r;this.average_reward_window.add(r);this.r_w.shift();this.r_w.push(r);if(!this.learning){return;}this.age+=1;if(this.f_p>1+1){var e={state0:this.n_w[0],state1:this.n_w[1],action0:this.a_w[0],reward0:this.r_w[0]};if(this.xp.length<30000)this.xp.push(e);else this.xp[randi(0,30000)]=e};if(this.xp.length>Math.floor(Math.min(30000*.1,1000))){var av=0;for(var k=0;k<this.tdt.bs;k++){var re=randi(0,this.xp.length),e=this.xp[re],x=new Vol(1,1,this.ni);x.w=e.state0;var maxact=this.policy(e.state1),r=e.reward0+.7*maxact.value,ystruct={dim:e.action0,val:r},loss=this.tdt.train(x,ystruct);av+=loss.loss;}av=av/this.tdt.bs;this.average_loss_window.add(av);}}}\nvar lint=(a,b,c,d)=>{var e=(d.y-c.y)*(b.x-a.x)-(d.x-c.x)*(b.y-a.y);if(e===0)return 0;var u=((d.x-c.x)*(a.y-c.y)-(d.y-c.y)*(a.x-c.x))/e,v=((b.x-a.x)*(a.y-c.y)-(b.y-a.y)*(a.x-c.x))/e;if(u>0&&u<1&&v>0&&v<1)return {ua:u,ub:v,up:new Vec(a.x+u*(b.x-a.x),a.y+u*(b.y-a.y))};return 0;},lpint=(a,b,c,r)=>{var v=new Vec(b.y-a.y,-(b.x-a.x)),d=Math.abs((b.x-a.x)*(a.y-c.y)-(a.x-c.x)*(b.y-a.y));d=d/v.length();if(d>r)return 0;v.normalize();v.scale(d);var v=c.add(v),u=(Math.abs(b.x-a.x)>Math.abs(b.y-a.y))?(v.x-a.x)/(b.x-a.x):(v.y-a.y)/(b.y-a.y);if(u>0&&u<1)return {ua:u,up:v};return 0;},box=(lst,x,y,w,h)=>{lst.push({p1:{x:x,y:y},p2:{x:x+w,y:y}},{p1:{x:x+w,y:y},p2:{x:x+w,y:y+h}},{p1:{x:x+w,y:y+h},p2:{x:x,y:y+h}},{p1:{x:x,y:y+h},p2:{x:x,y:y}})},gwlls=(w,h)=>{let l,x1,y1,x2,y2,p=50;if(rn.r()<.5){l=w*.4+(rn.r()*((w*.6)-p*2));x1=p+rn.r()*(w-l-p*2);x2=x1+l;y1=y2=p+rn.r()*(w-p*2);}else{l=h*.4+(rn.r()*((h*.6)-p*2));y1=p+rn.r()*(h-l-p*2);y2=y1+l;x1=x2=p+rn.r()*(h-p*2);};return {p1:{x:x1,y:y1},p2:{x:x2,y:y2}};}\nclass Agent{constructor(px=1,py=1,es=9,rng=85){this.p=new Vec(px,py);this.op=this.p;this.angle=0;this.actions=[[1,1],[0.8,1],[1,0.8],[0.5,0],[0,0.5]];this.rad=10;this.eyes=[];for(var k=0;k<es;k++){this.eyes.push({angle:(k-3)*0.25,max_range:rng,sensed_proximity:rng,sensed_type:-1});}var num_inputs=es*3,na=5,ns=num_inputs+na+num_inputs,ld=[{type:'input',out_sx:1,out_sy:1,out_depth:ns},{type:'fc',num_neurons:50,activation:'relu'},{type:'fc',num_neurons:50,activation:'relu'},{type:'regression',num_neurons:na}];this.brain=new Brain(num_inputs,na,{layer_defs:ld});this.ds=0;}forward(){var c=this.eyes.length,ia=new Array(c*3);for(var i=0;i<c;i++){var e=this.eyes[i];ia[i*3]=1;ia[i*3+1]=1;ia[i*3+2]=1;if(e.sensed_type !== -1) {ia[i*3 + e.sensed_type] = e.sensed_proximity/e.max_range;}}var x=this.brain.forward(ia),a=this.actions[x];this.actionix=x;this.rot1=a[0];this.rot2=a[1];}backward(){var rew=0;this.eyes.forEach(e=>{rew+=e.sensed_type===0?e.sensed_proximity/e.max_range:1;});rew=rew/this.eyes.length;rew=Math.min(1,rew*2);var fr=0;if(this.actionix===0&&rew>.75)fr=.1*rew;var d_r=this.ds;this.ds=0;this.brain.backward(rew+fr+d_r);}}\nclass World{constructor(w,h){Object.assign(this,{W:w,H:h,t:0,items:[],agent:new Agent(rn.r()*w,rn.r()*h,aes,esrng)});for(var k=0;k<30;k++)this.items.push({p:new Vec(randf(20,this.W-20),randf(20,this.H-20)),type:randi(1,3),rad:10,age:0,c:0});}genWalls(){this.walls=[];box(this.walls,1,1,this.W-2,this.H-2);for(var i=0;i<3;i++)this.walls.push(gwlls(this.W,this.H));return this.walls}collide_(p1,p2,cw,ci){var m=0;if(cw){this.walls.forEach( wl=>{let r=lint(p1,p2,wl.p1,wl.p2);if(r){r.type=0;if(!m){m=r;}else{if(r.ua<m.ua){m=r;}}}})}if(ci){this.items.forEach(it=>{let r=lpint(p1,p2,it.p,10);if(r){r.type=it.type;if(!m){m=r}else{if(r.ua<m.ua){m=r;}}}})}return m;}step(){this.t++;var a=this.agent,is=this.items;a.eyes.forEach(e=>{var r=this.collide_(a.p,new Vec(a.p.x+e.max_range*Math.sin(a.angle+e.angle),a.p.y+e.max_range*Math.cos(a.angle+e.angle)),1,1);e.sensed_proximity=(r)?r.up.dist_from(a.p):e.max_range;e.sensed_type=(r)?r.type:-1;});this.agent.forward();a.op=a.p;a.oangle=a.angle;var v=new Vec(0,10/2);v=v.rotate(a.angle+Math.PI/2);var k=a.p.add(v),h=a.p.sub(v),g=a.p.sub(h);g=g.rotate(-a.rot1);var q=a.p.sub(k);q=q.rotate(a.rot2);var o=h.add(g);o.scale(.5);var m=k.add(q);m.scale(.5);a.p=o.add(m);a.angle-=a.rot1;if(a.angle<0)a.angle+=2*Math.PI;a.angle+=a.rot2;if(a.angle>2*Math.PI)a.angle-=2*Math.PI;var res=this.collide_(a.op,a.p,1,0);if(res){a.p=a.op;}if(a.p.x<0)a.p.x=0;if(a.p.x>this.W)a.p.x=this.W;if(a.p.y<0)a.p.y=0;if(a.p.y>this.H)a.p.y=this.H;var u=0;for(var i=0,n=is.length;i<n;i++){var it=is[i];it.age+=1;var d=a.p.dist_from(it.p);if(d<20){if(!this.collide_(a.p, it.p, 1, 0)){if(it.type===1)a.ds+=5;if(it.type===2)a.ds+=-6;it.c=1;u=1;break;}};if(it.age>5000&&this.t%100===0&&randf(0,1)<.1){it.c=1;u=1;}}if(u){var nt=[];is.forEach(it=>{if(!it.c)nt.push(it);});this.items=nt;}if(is.length<30&&this.t%10===0&&randf(0,1)<.25){is.push({p:new Vec(randf(20,this.W-20),randf(20,this.H-20)),type:randi(1,3),rad:10,age:0,c:0});}this.agent.backward();}}\nclass Sim extends _.WebGLRenderTarget{constructor(w,h,r){super(w*2,h*2);Object.assign(this,{w:w,h:h,t:0,items:[],renderer:r,simspeed:2,world:new World(w,h),s:new _.Scene(),c:new _.OrthographicCamera(-w/2,w/2,h/2,-h/2,.01,1000),agent:new _.Object3D()});let t=this;t.agent.add(new _.Mesh(new _.SphereBufferGeometry(5),new _.MeshBasicMaterial({color:new _.Color(`rgb(${pal[0][0]},${pal[0][1]},${pal[0][2]})`)})));t.genWalls();t.world.agent.eyes.forEach(e=>{let sr=e.sensed_proximity,dir=new _.Vector3(t.world.agent.op.x+20*Math.sin(e.angle),t.world.agent.op.y+20*Math.cos(e.angle),0).sub(new _.Vector3(t.world.agent.op.x+sr*Math.sin(e.angle),t.world.agent.op.y+sr*Math.cos(e.angle),0)).normalize();t.agent.add(new _.ArrowHelper(dir,new _.Vector3(0,0,0),e.sensed_proximity/2,`rgb(${pal[0][0]},${pal[0][1]},${pal[0][2]})`,10,6));});t.items=new _.Object3D();for(var i=0;i<100;i++)t.items.add(new _.Mesh(new _.SphereBufferGeometry(5),new _.MeshBasicMaterial()));t.s.add(t.agent,t.items);t.c.position.z=100;t.c.updateProjectionMatrix()}genWalls(){if(this.walls)this.s.remove(this.walls);this.world.genWalls();let g=new _.BufferGeometry(),ws=[];this.world.walls.forEach(l=>ws.push( l.p1.x-this.w/2, -l.p1.y+this.h/2, 0, l.p2.x-this.w/2, -l.p2.y+this.h/2, 0 ));g.setAttribute('position', new _.BufferAttribute(new Float32Array(ws),3));this.walls =new _.LineSegments(g, new _.LineBasicMaterial({color:`rgb(${pal[0][0]},${pal[0][1]},${pal[0][2]})`}));this.s.add(this.walls);}loadnet(j){this.world.agent.brain.value_net.fromJSON(j);toggleLearn(0);this.simspeed=1}toggleLearn(v){this.world.agent.brain.learning = v;this.simspeed=(v)?2:1}step(){let t=this;for(var i=0;i<t.simspeed;i++)t.world.step();t.items.children.forEach(i=>{i.material.visible=0});t.agent.rotation.z=t.world.agent.oangle;t.world.items.forEach((it,i)=>{t.items.children[i].material.visible=1;t.items.children[i].position.set(it.p.x-t.w/2,-it.p.y+t.h/2);if(it.type==1)t.items.children[i].material.color=new _.Color(`rgb(${pal[1][0]},${pal[1][1]},${pal[1][2]})`);if(it.type==2)t.items.children[i].material.color=new _.Color(`rgb(${pal[2][0]},${pal[2][1]},${pal[2][2]})`);});t.agent.position.set(t.world.agent.op.x-t.w/2,-t.world.agent.op.y+t.h/2,0);t.renderer.setRenderTarget(this);t.renderer.render(t.s,t.c);t.renderer.setRenderTarget(null);}}class AppMain {\n constructor() {\n this.n = document.body\n this.n.appendChild( renderer.domElement )\n this.cameraTl = 0\n this.exposeTl = 0\n this.persp = 0\n this.expose = 0\n scene.add( this.windows = new _.Object3D() )\n scene.add( this.shadows = new _.Object3D() )\n \n let d = Math.min( ww * 0.7, wh * 0.7 )\n window.dims = new _.Vector2( d, d )\n this.sim = new Sim( dims.x, dims.y, renderer )\n\n this.simPlane = new _.Mesh( new _.PlaneBufferGeometry( dims.x, dims.y ), new _.MeshBasicMaterial( { map : this.sim.texture } ) )\n this.simPlane.position.z = -150\n scene.add( this.simPlane )\n\n this.isLearning = true\n \n this.fluid = new Fluid( dims.x, dims.y, renderer )\n this.particles = new Particles( dims.x, dims.y, renderer, this.fluid.sol.v.r.texture )\n this.text = new Text()\n this.text.update(this.sim)\n this.text.needsUpdate = true\n this.ascii = new Ascii( dims.x, dims.y, renderer )\n\n let l = new Array(3).fill().map((a, i) => a = i).sort(_ => rn.r() - 0.5);\n \n this.windows.add(\n new Window( l[0], this.fluid.velocityRT.texture, 0 ),\n new Window( l[1], this.fluid.densityRT.texture, 0 ),\n new Window( l[2], this.particles.readBuffer.texture, 0 ),\n new Window( 4, this.text, 1, undefined, undefined, this.text.ln * 5.15, undefined ),\n new Window( 3, this.ascii.texture, 0 )\n )\n\n this.windows.children.forEach( w=> {\n let s = new _.Mesh(\n new _.PlaneBufferGeometry(1,1), \n new _.ShaderMaterial( {\n uniforms : {\n dims : { value : 0 },\n op : { value : 1 }\n },\n vertexShader : `\n varying vec2 vUv;\n void main(){\n vUv = uv;\n gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);\n }\n `,\n fragmentShader : `\n varying vec2 vUv;\n uniform vec2 dims;\n uniform float op;\n float roundBox( vec2 c, vec2 s, float r ){ return length( max( abs( c )- s + r, 0.0 ) ) - r; }\n void main(){\n vec2 p = vUv * dims ;\n gl_FragColor = vec4( vec3(0.0), (op *((1.0 - smoothstep( -80.0, 0.0, (roundBox( p - dims / 2.0, dims / 2.0 , 80.0 )) ))*0.25))-(1.0 - smoothstep( -0.5, 0.5, (roundBox( p - dims / 2.0 , ( dims - vec2( 80.0 ) ) / 2.0 , 6.0 )) )) );\n }\n `,\n transparent : true\n } )\n )\n this.shadows.add(s)\n w.userData.s = s\n })\n\n this.raycaster = new _.Raycaster();\n this.pointer = null\n this.activeWindow = null\n this.oldMouse = null\n\n if(('ontouchstart' in window) || (navigator.maxTouchPoints > 0) || (navigator.msMaxTouchPoints > 0)) {\n document.querySelectorAll('.tggl')[0].style.display = 'none';\n document.addEventListener( 'touchstart', e => {this.persp = 1 - this.persp} )\n } else {\n document.addEventListener( 'mousemove', e => this.onMoueMove( e ) )\n document.addEventListener( 'mousedown', e => this.onMouseDown( e ) )\n document.addEventListener( 'mouseup', e => this.onMouseUp( e ) )\n document.addEventListener( 'keydown', e => {\n if(!e.repeat){\n let kc = e.keyCode;\n if( kc==84) {\n this.sim.toggleLearn( this.isLearning = !this.isLearning)\n this.text.update(this.isLearning)\n this.text.needsUpdate = true\n }\n if( kc==87) this.sim.genWalls()\n if( kc==80) {this.persp = 1 - this.persp}\n if( kc==69) {this.expose = 1 - this.expose}\n if( kc==67) {this.windows.children.forEach(w=>w.material.uniforms.ch.value =!w.material.uniforms.ch.value )}\n }\n } )\n }\n requestAnimationFrame(( t ) => this.step( t ) )\n window.addEventListener('resize', () => this.onResize() )\n this.onResize()\n }\n\n onMouseDown( e ){\n if(this.persp > 0)return;\n this.raycaster.setFromCamera( this.pointer, camera );\n const intersects = this.raycaster.intersectObjects( this.windows.children )\n if( intersects.length ){\n this.activeWindow = intersects[ 0 ].object\n if( this.activeWindow.d.y * ( 1 - intersects[ 0 ].uv.y ) < 24 ) this.activeWindow.drg = true\n if( 24 / this.activeWindow.d.y > intersects[ 0 ].uv.y ) this.activeWindow.rsy = true\n if( 24 / this.activeWindow.d.x > 1 - intersects[ 0 ].uv.x ) this.activeWindow.rsx = true\n this.oldMouse = new _.Vector2( e.clientX, e.clientY )\n this.windows.children.forEach( w => { if( w.zid > this.activeWindow.zid ) w.zid = w.zid - 1 } )\n this.activeWindow.zid = this.windows.children.length\n }\n }\n\n onMouseUp( e ){\n if( this.activeWindow ) this.activeWindow.drg = false \n if( this.activeWindow ) this.activeWindow.rsy = false \n if( this.activeWindow ) this.activeWindow.rsx = false \n this.activeWindow = null\n }\n\n onMoueMove( e ){\n this.pointer = new _.Vector2( ( e.clientX / this.n.offsetWidth ) * 2 - 1, -( e.clientY / this.n.offsetHeight ) * 2 + 1 )\n if( !this.activeWindow ) return\n let p = new _.Vector2( e.clientX, e.clientY ).sub( this.oldMouse )\n if( this.activeWindow && this.activeWindow.drg ) this.activeWindow.updatePosition( p )\n if( this.activeWindow && ( this.activeWindow.rsx || this.activeWindow.rsy ) ) this.activeWindow.updateDimensions( p )\n this.oldMouse = new _.Vector2( e.clientX, e.clientY )\n }\n\n onResize() {\n [ ww, wh ] = [ innerWidth, innerHeight ]\n renderer.setSize( ww, wh )\n renderer.setPixelRatio( window.devicePixelRatio * 2 )\n Object.assign( camera, { left: ww / -2, right: ww / 2, top: wh / 2, bottom: wh / -2, near : 0.02, far : 5000 } ).updateProjectionMatrix()\n camera.position.z = 1000\n }\n\n step(t) {\n requestAnimationFrame((t) => this.step(t))\n this.cameraTl += ( this.persp - this.cameraTl ) * 0.05\n this.exposeTl += ( this.expose - this.exposeTl ) * 0.05\n \n camera.position.x = -800 * this.cameraTl\n camera.position.y = -800 * this.cameraTl\n\n camera.up= new _.Vector3(0,1-this.cameraTl,this.cameraTl)\n camera.lookAt(new _.Vector3(0,0, 250 ))\n camera.zoom = 1 - 0.2 * this.cameraTl\n camera.updateProjectionMatrix()\n this.windows.children.forEach( c => c.step( this.exposeTl ) )\n this.sim.step( t )\n renderer.setClearColor( new _.Color(0x00000000));\n this.fluid.step( )\n renderer.setClearColor( new _.Color(`rgb(${pal[5][0]},${pal[5][1]},${pal[5][2]})`), 1 );\n this.fluid.updatePosition( new _.Vector2( this.sim.world.agent.op.x, this.sim.world.agent.op.y ) )\n this.particles.step( t )\n this.ascii.updatePosition( new _.Vector2( this.sim.world.agent.op.x, this.sim.world.agent.op.y ) )\n this.ascii.step( t )\n this.windows.children[2].material.uniforms.tex.value = this.particles.readBuffer.texture\n \n this.windows.children.forEach( w=> {\n w.renderOrder = w.zid\n w.userData.s.position.copy(w.position)\n w.userData.s.position.z = w.position.z + 10\n w.userData.s.scale.set(w.scale.x + 80, w.scale.y + 80, 1 )\n w.userData.s.material.uniforms.dims.value = new _.Vector2( w.scale.x + 80, w.scale.y + 80 ) \n w.userData.s.material.uniforms.op.value = 1 - this.cameraTl\n })\n renderer.render(scene, camera)\n }\n}\nwindow.main;\nwindow.onload=()=>{ main = new AppMain() }; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment