Skip to content

Instantly share code, notes, and snippets.

@ryley-o
Created February 15, 2023 02:21
Show Gist options
  • Save ryley-o/8b9fb20eba19484024f03b48d4648113 to your computer and use it in GitHub Desktop.
Save ryley-o/8b9fb20eba19484024f03b48d4648113 to your computer and use it in GitHub Desktop.
Script for project 412
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µŽÄ=îîî','..5SNNSˆNSNNˆNˆÿÿÿ','\u001d\u0019\b¶L|‹\u0016Ó½&ak°ŒZ‘l%Êš','ûñÇûñÇÌ$\u001d˜—\u001aי!E…ˆ±b†hj|od','..5SNNSˆNSNNˆNˆÿÿÿ','\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ô_˜à$ú„\u0019eÿô_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]üc†B@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