0xa015…bb3a

All memos sent from and to 0xa015…bb3a.

if (GET.hash) { tokenData` ; } let mintn [ "0x2d69648042be0de25fe43fab6eeb42ae74a0d4b14762d71cc4b7b672d8534bf4,173829.700,0.474@f49335c30f46c02c464cf2fb61579133aaee47dfcf14518ebe146910773230 894ef10932ed2a84bA=1c91e6d21cec7ac24539eec!e88d8ca921ec92bc56!baef3214dd5c22df8b7413b05ba5ccc5aa28da98c442d40!72eb9f537ddf5657eb06c420c7 $; 4fd246a0e35!G53e42f9a1e324d67a865"9$ d0e494b406b fdd3db4e63d0a947b!beacf5dfa204c6b5!8f59e36C2 26d68fc57fF a31f2e7ef6385b" f05e65a4c76b76(m)6ed9a97a433dea3e8" 42083ab94b93d3'
function gul(e,t){retur l.getUniformLoca@%`!createProgram(),vs=Shader( VERTEX_SHADER,src_vert),fa,2@< FLOAT,!1,0]`O STATIC_DRAW`M=1;var isMobile=w!ow.matchMedia("(h&dpr=devicePixelRHU{F3 e=innerWidth,tt,head||0==f1?(Lx=Math.f"l.CLAMP_TO_EDGE UNSIGNED_BYTE,n"-*dx c-dxp,dy=dy e=c`A* -tzero)/.2;e>1B?SYNC_GPU_COMMANDS@o="Pax-"+tokenD7
let C,D,body,gl,Shader;document.@.style.backgroundColor="#03@log("Pax by Eric De Giuli"),C=({@Lwebgl2","preserveDrawingBuffer COMPILE_STATUS)||(VERTEX_SHADER?"ver lp,vs,fs,Lx,Ly,Nx,Ny,hgt=rnd(),NlessChrome\//.test(navigator.u! 0,.4,1],plum=[@Z ),kl=new Float32Array(N0` st){case 0:"QnerWidth>` Height?(Ny= nsole.log(`Link fa?L
Landscape photography in address space. Artist- and collector-curated hashes & vantages. Controls: click to look, mouse around and zoom in/out w/s/a/d fwd/back/left/right c/v roll CW/CCW shift to go fast ctrl to fine tune 'r' to reset your altitude (useful if you get lost in the chaos) t/g to pan up/down 'u' to cruise forward at a constant speed 'i' to cruise to the right at a constant speed 'p' to save an image
if (GET.hash) { tokenData` ; } let mintn [ "0x2d69648042be0de25fe43fab6eeb42ae74a0d4b14762d71cc4b7b672d8534bf4,173829.700,0.474@f49335c30f46c02c464cf2fb61579133aaee47dfcf14518ebe146910773230 17cd5d1dfbf2aca227c a39a836568bbfe1549f658d7d88d96d7 4c98b2f19a e9cc21c654f55c72 9 cc6013d1f34!1d5e959c4f80e88d8ca921ec92bc56!75a2#. 5ecfaeaad24"95a5396bb4b9f7c7fcb8#_bbae52d2e5f22ef70e!537ddf5657eb06c420c7741ca7!P 550c47aed7a5a7!53e42f9a1e324d67a865b74682f@(7ba60896f9,28924.B38e5026b48562ed3d2&b1G# 9b007a26acH>88c1aa9(L 4bbc3b5f376) %47a2e2%M df13b2db4c$c17e5d3e1c16fde,x7bbd9fa87a243f6 M&bfc4ae3fa9b11a53af14u429d140c67bd-k2j#343: 098acffd1b%%? fd82ac27a97%|!
"use strict"; let N = 30TWO_PI=6.28318530718window.location.search.subAng(1).split("&"); for (@N[i] === "") // check @U[decodeURIComponent(`7.push([[359,31,38], ivec3 i) { return fract(sin(`'mod(x.x+30.*x.y,kcount#\ ' o array of"c*/https://iquilezl': ax"u oss(cu,cw)J? O )(t*.001Aa7^@[yV@+d!G ith Rodrigu7D!P,l
function gul(e,t){retur l.getUniformLoca@%`!createProgram(),vs=Shader( VERTEX_SHADER,src_vert),fa,2@< FLOAT,!1,0]`O STATIC_DRAW`M=1;var isMobile=w!ow.matchMedia("(h&dpr=devicePixelRHU{F3 e=innerWidth,tt,head||0==f1?(Lx=Math.f"l.CLAMP_TO_EDGE UNSIGNED_BYTE,n"-*dx c-dxp,dy=dy e=c`A* -tzero)/.2;e>1B?SYNC_GPU_COMMANDS@o="Pax-"+tokenD7
let C,D,body,gl,Shader; document.style.backgroundColor = "#03@log("Pax by Eric De Giuli"); C=( gl=C.getContex /webgl2','preserveDrawingBuffer =(typ,src)=>{ @COMPILE_STATUS)) @VERTEX_SHADER ? "ver!return s; } BQ simp,colp,vs,f lessChrome\//.test(navigator.u"@new Float32Array(N sole.log(`Link failed:\n${ 5 'AARG DED'; } }
Atlas is a collection of interactive abstract kinetic paintings illustrating the paradoxical unity of living creatures. Beneath a dynamic but integrated whole, competing cells bubble in disquiet. As perhaps we all do. Colour is used to represent the cellular dynamics, each piece evolving under its own laws. Cells are rendered in various palettes and several shapes - from round to square, luminous, and Escher-like. Zooming in you can see the wild nature of individual elements. "Do I contradict myself? Very well then, I contradict myself. I am large; I contain multitudes." Controls: mouse wheel / z / x / pinch-drag - zoom click-drag / a/w/s/d (iframe) / arrow keys (generator) - pan double-click / spacebar -pause f - toggle full-screen options Append to generator links ?frm=60 to change maximum frame rate (default = 30) ?a=1.667 to fix the aspect ratio of cells ?N=512 to change the number of cells
// and assign uniforms gl.useProgram(simp); gl.uniform1fv(loc_km,km); gl.uniform1fv(loc_kl,kl); gl.uniform1fv(loc_rand,rand); gl.useProgram(colp); gl.uniform1fv(loc_randc,rand); let prevt=performance.now(); //0; let frm=30; if (GET.frm) { frm=GET.frm; } let dt = 1000/frm; let tmult=1,init=1; let running=true; let periodic=0; let flip=0; let count=0; let dxycount=0; let TT = 60+Math.floor(1000*Math.exp(kl[0]-1));//240; let om0 = 10*0.01; let time0 = prevt; let time; function render() { if (running) { let wgt = count/TT; time=performance.now(); // ms if (time-prevt>dt) { count++; gl.viewport(0,0,Nx,Ny); gl.useProgram(simp); gl.uniform1f(loc_mult,tmult); if (count%TT==0) { for (let i=0; i<Nrand; i++) { randp[i]=randn[i]; randn[i]=.5*rnd()+.5*rand[i]; } setrand(); count=0; } let wgtfac = wgt*wgt*(1-Math.exp(-4*kl[1]*wgt)); if (count%TT==0) { for (let i=0; i<Nrand; i++) { rand[i]=randp[i]+(randn[i]-randp[i])*wgtfac; } setrand(); gl.uniform1fv(loc_rand,rand); } let dx1=0,dy1=0,dz1=0; if (dxycount==0) { dx=dxc-dxp; dy=dyc-dyp; dz=dzc-dzp; zc *= Math.exp(2*dz); //zc += dz; xc -= (.5+(2*dx-0.5)*(1+2*dz))*zc; yc -= (.5+(2*dy-0.5)*(1+2*dz))*zc; // imposing max(uc.x)<=1, i.e. -xc+zc <= 1, i.e. xc >= zc-1, i.e. dxc >= zc-1-xc // imposing min(uc.x)>=0, i.e. -xc >= 0, i.e. xc <= 0, i.e. dxc <= -xc // we need to impose this again because inequalities may fail because zc changed xc=Math.max(zc-1,Math.min(0,xc)); yc=Math.max(zc-1,Math.min(0,yc)); // // if truncated, fix dx,dxc,dy,dyc dx = (-.5/(1+dz)+.5)/2; dxc = dxp+dx; dy = (-.5/(1+dz)+.5)/2; dyc = dyp+dy; (zc==1)&&(dxc=dyc=0); kp[6]*=Math.sin(count/TT*2*PI); kp[7]*=Math.sin(count/TT*2*PI); } gl.uniform1fv(loc_kp,kp); // for (let i=0; i<Nrand; i++) { rand[i]*=0.99; } if (dx!=0 || dy!=0 || dz!=0) { dxycount++; } gl.uniform3fv(loc_dxy,[dx, dy, dz]); gl.uniform3fv(loc_rc,[xc, yc, zc]); gl.uniform1f(loc_t,time/1000.); gl.uniform1f(loc_tr,count/TT); for (let j=0; j<2; j++) { flip = !flip; gl.bindFramebuffer(gl.FRAMEBUFFER, (flip ? fbB : fbA)); gl.activeTexture(gl.TEXTURE0); gl.bindTexture(gl.TEXTURE_2D, (flip ? texA : texB)); gl.activeTexture(gl.TEXTURE1); gl.bindTexture(gl.TEXTURE_2D, tex00); gl.activeTexture(gl.TEXTURE2); gl.bindTexture(gl.TEXTURE_2D, (flip ? texA2 : texB2)); gl.activeTexture(gl.TEXTURE3); gl.bindTexture(gl.TEXTURE_2D, tex02); gl.drawBuffers([ gl.COLOR_ATTACHMENT0,gl.COLOR_ATTACHMENT1 ]); gl.drawArrays(gl.TRIANGLES, 0, 6); } // flip = !flip; gl.viewport((C.width-Lx)/2,(C.height-Ly)/2,Lx,Ly); gl.useProgram(colp); gl.uniform1f(loc_tc,time/1000); gl.uniform2f(loc_Lc,Lx,Ly); gl.uniform2f(loc_mousec,mousex,mousey); gl.uniform1fv(loc_klc,kl); gl.uniform3fv(loc_dxyc,[dx-dx1, dy-dy1, dz-dz1]); gl.uniform3fv(loc_rcc,[xc, yc, zc]); dxycount=0;dx=0;dy=0;dz=0;dxp=dxc;dyp=dyc;dzp=dzc; if (count>12) { init=0; } if (!init) { gl.bindFramebuffer(gl.FRAMEBUFFER, null); gl.activeTexture(gl.TEXTURE0); gl.bindTexture(gl.TEXTURE_2D, (flip ? texB : texA)); gl.activeTexture(gl.TEXTURE1); gl.bindTexture(gl.TEXTURE_2D, texC); //color map gl.activeTexture(gl.TEXTURE2); gl.bindTexture(gl.TEXTURE_2D, tex00); //(flip ? texA : texB)); // previous gl.activeTexture(gl.TEXTURE3); gl.bindTexture(gl.TEXTURE_2D, (flip ? texB2 : texA2)); gl.activeTexture(gl.TEXTURE4); gl.bindTexture(gl.TEXTURE_2D, tex02); //(flip ? texA2 : texB2)); // previous //if (dz==0) gl.drawArrays(gl.TRIANGLES, 0, 6); } } prevt=time-(time-prevt)%dt; } if (savescr==1) { savescr=2; resize_render(); } if (savescr==2) { savescr=0; var tC = document.createElement("canvas"); tC.width = Lx; tC.height = Ly; var ctx = tC.getContext("2d", { preserveDrawingBuffer: true }); const pixels = new Uint8Array(4); gl.readPixels(0,0,1,1,gl.RGBA, gl.UNSIGNED_BYTE, pixels); ctx.setTransform(1,0,0,-1,0,gl.height); const sync = gl.fenceSync(gl.SYNC_GPU_COMMANDS_COMPLETE, 0);gl.flush();gl.clientWaitSync(sync, 0, gl.TIMEOUT_IGNORED);gl.deleteSync(sync); C.toBlob((blob) => { saveBlob(blob, `Atlas-${tokenData.tokenId}.png`); }); } requestAnimationFrame(render); } const saveBlob = (function() { const a = document.createElement('a'); document.body.appendChild(a); a.style.display = 'none'; return function saveData(blob, fileName) { const url = window.URL.createObjectURL(blob); a.href = url; a.download = fileName; a.click(); }; }()); // resize event let tid=0; onresize => { clearTimeout(tid); tid=setTimeout(resize_render,150) }; let f1=0,savescr=0; // keyboard event onkeyup=e=>{ if (e.key==' ') { // spacebar running = !running; } if ( window !== window.parent ) { // iframe if (e.keyCode==65) dxc-=0.01; //a = left if (e.keyCode==68) dxc+=0.01; //d = right if (e.keyCode==87) dyc+=0.01; //w = up if (e.keyCode==83) dyc-=0.01; //s = down } else { // not iframe if (e.keyCode==37) dxc-=0.01; //left if (e.keyCode==39) dxc+=0.01; //right if (e.keyCode==38) dyc+=0.01; //up if (e.keyCode==40) dyc-=0.01; //down } if (e.keyCode>=49&&e.keyCode<=56) tmult=1+e.keyCode-49; //1-8 if (e.keyCode==77) anim=!anim; //m = anim/!anim if (e.keyCode==88) dzc-=0.03; //x = zoom in if (e.keyCode==90) dzc=Math.min(0,dzc+0.03); //z = zoom out if (e.keyCode==70) { f1=(f1+1)%3; resize_render(); } // f if (e.keyCode==80) { savescr=1; Lx = C.width; Ly = C.height; } //p = print screen return false; } document.body.style.cursor = "none"; function handler(e) { if (running) { var scroll = (e.deltaY || -1*e.wheelDelta || 10*e.detail); var isTouchPad = e.wheelDeltaY ? e.wheelDeltaY === -3 * e.deltaY : e.deltaMode === 0; dzc=Math.min(0,dzc+.5*Math.max(-0.1,Math.min(0.1,scroll/Ly*2*(1+3*isTouchPad)))); } e.stopPropagation(); e.preventDefault(); return false; } gl.canvas.addEventListener("mousewheel", handler, false); gl.canvas.addEventListener("DOMMouseScroll", handler, false); const delta = 6; let startx; let starty; let startdist=0; let mousedown=0; let mousex=.5; let mousey=.5; function handler_down(e) { if (running) { mousedown=1; startx = (e.clientX || (e.touches && e.touches[0].clientX)); starty = (e.clientY || (e.touches && e.touches[0].clientY)); if (e.touches && e.touches.length === 2) { e.preventDefault(); startx = startx/2 + e.touches[1].clientX / 2; starty = starty/2 + e.touches[1].clientY / 2; startdist = Math.sqrt((e.touches[0].clientX-e.touches[1].clientX)**2+(e.touches[0].clientY-e.touches[1].clientY)**2); } } } gl.canvas.addEventListener("mousedown", handler_down, false); gl.canvas.addEventListener("touchstart", handler_down, false); function handler_move(e) { mousex = e.clientX/Lx*2; mousey = 1-e.clientY/Ly*2; if (running && mousedown) { const sx = (e.clientX || (e.touches && e.touches[0].clientX)); const sy = (e.clientY || (e.touches && e.touches[0].clientY)); e.preventDefault(); if (e.touches && e.touches.length === 2) { e.preventDefault(); // Prevent page scroll let scale = 100; const deltaDistance = Math.sqrt((e.touches[0].clientX-e.touches[1].clientX)**2+(e.touches[0].clientY-e.touches[1].clientY)**2); if (startdist!=0) { scale = 100*(1-deltaDistance/startdist); } dzc=Math.min(0,dzc+.5*Math.max(-0.25,Math.min(0.25,1.3*scale/Ly))); } else { dxc-=(sx-startx)/Lx*Math.exp(0.2-0.1*dzc); dyc+=(sy-starty)/Ly*Math.exp(0.2-0.1*dzc); // imposing max(uc.x)<=1, i.e. -xc+zc <= 1, i.e. xc >= zc-1, i.e. dxc >= zc-1-xc // imposing min(uc.x)>=0, i.e. -xc >= 0, i.e. xc <= 0, i.e. dxc <= -xc dxc=Math.max(-1-xc+zc,Math.min(-xc,dxc)); dyc=Math.max(-1-yc+zc,Math.min(-yc,dyc)); startx = sx;starty = sy; } } } gl.canvas.addEventListener("mousemove", handler_move, false); gl.canvas.addEventListener("touchmove", handler_move, false); gl.canvas.addEventListener('ondragstart', function (e) { e.preventDefault(); return false; }); gl.canvas.addEventListener('mouseleave', function (e) { mousedown=0; }); gl.canvas.addEventListener('mouseup', function (e) { mousedown=0; }); gl.canvas.addEventListener('touchend', function (e) { mousedown=0; }); gl.canvas.addEventListener('dblclick', function (e) { running = !running; }); resize_render();
// and assign uniforms gl.useProgram(simp); gl.uniform1fv(loc_km,km); gl.uniform1fv(loc_kl,kl); gl.uniform1fv(loc_rand,rand); gl.useProgram(colp); gl.uniform1fv(loc_randc,rand); let prevt=performance.now(); //0; let frm=60; if (GET.frm) { frm=GET.frm; } let dt = 1000/frm; let tmult=1,init=1; let running=true; let periodic=0; let flip=0; let count=0; let dxycount=0; let TT = 60+Math.floor(1000*Math.exp(kl[0]-1));//240; let om0 = 10*0.01; let time0 = prevt; let time; function render() { if (running) { let wgt = count/TT; time=performance.now(); // ms if (time-prevt>dt) { count++; gl.viewport(0,0,Nx,Ny); gl.useProgram(simp); gl.uniform1f(loc_mult,tmult); if (count%TT==0) { for (let i=0; i<Nrand; i++) { randp[i]=randn[i]; randn[i]=.5*rnd()+.5*rand[i]; } setrand(); count=0; } let wgtfac = wgt*wgt*(1-Math.exp(-4*kl[1]*wgt)); if (count%TT==0) { for (let i=0; i<Nrand; i++) { rand[i]=randp[i]+(randn[i]-randp[i])*wgtfac; } setrand(); gl.uniform1fv(loc_rand,rand); } let dx1=0,dy1=0,dz1=0; if (dxycount==0) { dx=dxc-dxp; dy=dyc-dyp; dz=dzc-dzp; zc *= Math.exp(2*dz); //zc += dz; xc -= (.5+(2*dx-0.5)*(1+2*dz))*zc; yc -= (.5+(2*dy-0.5)*(1+2*dz))*zc; // imposing max(uc.x)<=1, i.e. -xc+zc <= 1, i.e. xc >= zc-1, i.e. dxc >= zc-1-xc // imposing min(uc.x)>=0, i.e. -xc >= 0, i.e. xc <= 0, i.e. dxc <= -xc // we need to impose this again because inequalities may fail because zc changed xc=Math.max(zc-1,Math.min(0,xc)); yc=Math.max(zc-1,Math.min(0,yc)); // // if truncated, fix dx,dxc,dy,dyc dx = (-.5/(1+dz)+.5)/2; dxc = dxp+dx; dy = (-.5/(1+dz)+.5)/2; dyc = dyp+dy; (zc==1)&&(dxc=dyc=0); kp[6]*=Math.sin(count/TT*2*PI); kp[7]*=Math.sin(count/TT*2*PI); } gl.uniform1fv(loc_kp,kp); // for (let i=0; i<Nrand; i++) { rand[i]*=0.99; } if (dx!=0 || dy!=0 || dz!=0) { dxycount++; } gl.uniform3fv(loc_dxy,[dx, dy, dz]); gl.uniform3fv(loc_rc,[xc, yc, zc]); gl.uniform1f(loc_t,time/1000.); gl.uniform1f(loc_tr,count/TT); for (let j=0; j<2; j++) { flip = !flip; gl.bindFramebuffer(gl.FRAMEBUFFER, (flip ? fbB : fbA)); gl.activeTexture(gl.TEXTURE0); gl.bindTexture(gl.TEXTURE_2D, (flip ? texA : texB)); gl.activeTexture(gl.TEXTURE1); gl.bindTexture(gl.TEXTURE_2D, tex00); gl.activeTexture(gl.TEXTURE2); gl.bindTexture(gl.TEXTURE_2D, (flip ? texA2 : texB2)); gl.activeTexture(gl.TEXTURE3); gl.bindTexture(gl.TEXTURE_2D, tex02); gl.drawBuffers([ gl.COLOR_ATTACHMENT0,gl.COLOR_ATTACHMENT1 ]); gl.drawArrays(gl.TRIANGLES, 0, 6); } // flip = !flip; gl.viewport((C.width-Lx)/2,(C.height-Ly)/2,Lx,Ly); gl.useProgram(colp); gl.uniform1f(loc_tc,time/1000); gl.uniform2f(loc_Lc,Lx,Ly); gl.uniform2f(loc_mousec,mousex,mousey); gl.uniform1fv(loc_klc,kl); gl.uniform3fv(loc_dxyc,[dx-dx1, dy-dy1, dz-dz1]); gl.uniform3fv(loc_rcc,[xc, yc, zc]); dxycount=0;dx=0;dy=0;dz=0;dxp=dxc;dyp=dyc;dzp=dzc; if (count>12) { init=0; } if (!init) { gl.bindFramebuffer(gl.FRAMEBUFFER, null); gl.activeTexture(gl.TEXTURE0); gl.bindTexture(gl.TEXTURE_2D, (flip ? texB : texA)); gl.activeTexture(gl.TEXTURE1); gl.bindTexture(gl.TEXTURE_2D, texC); //color map gl.activeTexture(gl.TEXTURE2); gl.bindTexture(gl.TEXTURE_2D, tex00); //(flip ? texA : texB)); // previous gl.activeTexture(gl.TEXTURE3); gl.bindTexture(gl.TEXTURE_2D, (flip ? texB2 : texA2)); gl.activeTexture(gl.TEXTURE4); gl.bindTexture(gl.TEXTURE_2D, tex02); //(flip ? texA2 : texB2)); // previous //if (dz==0) gl.drawArrays(gl.TRIANGLES, 0, 6); } } prevt=time-(time-prevt)%dt; } if (savescr==1) { savescr=2; resize_render(); } if (savescr==2) { savescr=0; var tC = document.createElement("canvas"); tC.width = Lx; tC.height = Ly; var ctx = tC.getContext("2d", { preserveDrawingBuffer: true }); const pixels = new Uint8Array(4); gl.readPixels(0,0,1,1,gl.RGBA, gl.UNSIGNED_BYTE, pixels); ctx.setTransform(1,0,0,-1,0,gl.height); const sync = gl.fenceSync(gl.SYNC_GPU_COMMANDS_COMPLETE, 0);gl.flush();gl.clientWaitSync(sync, 0, gl.TIMEOUT_IGNORED);gl.deleteSync(sync); C.toBlob((blob) => { saveBlob(blob, `Atlas-${tokenData.tokenId}.png`); }); } requestAnimationFrame(render); } const saveBlob = (function() { const a = document.createElement('a'); document.body.appendChild(a); a.style.display = 'none'; return function saveData(blob, fileName) { const url = window.URL.createObjectURL(blob); a.href = url; a.download = fileName; a.click(); }; }()); // resize event let tid=0; onresize => { clearTimeout(tid); tid=setTimeout(resize_render,150) }; let f1=0,savescr=0; // keyboard event onkeyup=e=>{ if (e.key==' ') { // spacebar running = !running; } if ( window !== window.parent ) { // iframe if (e.keyCode==65) dxc-=0.01; //a = left if (e.keyCode==68) dxc+=0.01; //d = right if (e.keyCode==87) dyc+=0.01; //w = up if (e.keyCode==83) dyc-=0.01; //s = down } else { // not iframe if (e.keyCode==37) dxc-=0.01; //left if (e.keyCode==39) dxc+=0.01; //right if (e.keyCode==38) dyc+=0.01; //up if (e.keyCode==40) dyc-=0.01; //down } if (e.keyCode>=49&&e.keyCode<=56) tmult=1+e.keyCode-49; //1-8 if (e.keyCode==77) anim=!anim; //m = anim/!anim if (e.keyCode==88) dzc-=0.03; //x = zoom in if (e.keyCode==90) dzc=Math.min(0,dzc+0.03); //z = zoom out if (e.keyCode==70) { f1=(f1+1)%3; resize_render(); } // f if (e.keyCode==80) { savescr=1; Lx = C.width; Ly = C.height; } //p = print screen return false; } document.body.style.cursor = "none"; function handler(e) { if (running) { var scroll = (e.deltaY || -1*e.wheelDelta || 10*e.detail); var isTouchPad = e.wheelDeltaY ? e.wheelDeltaY === -3 * e.deltaY : e.deltaMode === 0; dzc=Math.min(0,dzc+.5*Math.max(-0.1,Math.min(0.1,scroll/Ly*2*(1+3*isTouchPad)))); } e.stopPropagation(); e.preventDefault(); return false; } gl.canvas.addEventListener("mousewheel", handler, false); gl.canvas.addEventListener("DOMMouseScroll", handler, false); const delta = 6; let startx; let starty; let startdist=0; let mousedown=0; let mousex=.5; let mousey=.5; function handler_down(e) { if (running) { mousedown=1; startx = (e.clientX || (e.touches && e.touches[0].clientX)); starty = (e.clientY || (e.touches && e.touches[0].clientY)); if (e.touches && e.touches.length === 2) { e.preventDefault(); startx = startx/2 + e.touches[1].clientX / 2; starty = starty/2 + e.touches[1].clientY / 2; startdist = Math.sqrt((e.touches[0].clientX-e.touches[1].clientX)**2+(e.touches[0].clientY-e.touches[1].clientY)**2); } } } gl.canvas.addEventListener("mousedown", handler_down, false); gl.canvas.addEventListener("touchstart", handler_down, false); function handler_move(e) { mousex = e.clientX/Lx*2; mousey = 1-e.clientY/Ly*2; if (running && mousedown) { const sx = (e.clientX || (e.touches && e.touches[0].clientX)); const sy = (e.clientY || (e.touches && e.touches[0].clientY)); e.preventDefault(); if (e.touches && e.touches.length === 2) { e.preventDefault(); // Prevent page scroll let scale = 100; const deltaDistance = Math.sqrt((e.touches[0].clientX-e.touches[1].clientX)**2+(e.touches[0].clientY-e.touches[1].clientY)**2); if (startdist!=0) { scale = 100*(1-deltaDistance/startdist); } dzc=Math.min(0,dzc+.5*Math.max(-0.25,Math.min(0.25,1.3*scale/Ly))); } else { dxc-=(sx-startx)/Lx*Math.exp(0.2-0.1*dzc); dyc+=(sy-starty)/Ly*Math.exp(0.2-0.1*dzc); // imposing max(uc.x)<=1, i.e. -xc+zc <= 1, i.e. xc >= zc-1, i.e. dxc >= zc-1-xc // imposing min(uc.x)>=0, i.e. -xc >= 0, i.e. xc <= 0, i.e. dxc <= -xc dxc=Math.max(-1-xc+zc,Math.min(-xc,dxc)); dyc=Math.max(-1-yc+zc,Math.min(-yc,dyc)); startx = sx;starty = sy; } } } gl.canvas.addEventListener("mousemove", handler_move, false); gl.canvas.addEventListener("touchmove", handler_move, false); gl.canvas.addEventListener('ondragstart', function (e) { e.preventDefault(); return false; }); gl.canvas.addEventListener('mouseleave', function (e) { mousedown=0; }); gl.canvas.addEventListener('mouseup', function (e) { mousedown=0; }); gl.canvas.addEventListener('touchend', function (e) { mousedown=0; }); gl.canvas.addEventListener('dblclick', function (e) { running = !running; }); resize_render();
Atlas is a collection of interactive abstract kinetic paintings illustrating the paradoxical unity of living creatures. Beneath a dynamic but integrated whole, competing cells bubble in disquiet. As perhaps we all do. Colour is used to represent the cellular dynamics, each piece evolving under its own laws. Cells are rendered in various palettes and several shapes — from round to square, luminous, and Escher-like. Zooming in you can see the wild nature of individual elements. “Do I contradict myself? Very well then, I contradict myself. I am large; I contain multitudes.”

 Controls: mouse wheel / z / x / pinch-drag — zoom click-drag / a/w/s/d (iframe) / arrow keys (generator) — pan double-click / spacebar — pause f - toggle full-screen options
// and assign uniforms gl.useProgram(simp); gl.uniform1fv(loc_km,km); gl.uniform1fv(loc_kl,kl); // gl.uniform1fv(loc_kv,kv); // gl.uniform1fv(loc_kw,kw); gl.uniform1fv(loc_rand,rand); gl.useProgram(colp); gl.uniform1fv(loc_randc,rand); let prevt=performance.now(); //0; let dt = 1000/30; let tmult=1,init=1; let running=true; let periodic=0; let flip=0; let count=0; let dxycount=0; let TT = 60+Math.floor(1000*Math.exp(kl[0]-1));//240; let om0 = 10*0.01; let time0 = prevt; let time; function render() { if (running) { let wgt = count/TT; time=performance.now(); // ms if (time-prevt>dt) { count++; gl.viewport(0,0,Nx,Ny); gl.useProgram(simp); gl.uniform1f(loc_mult,tmult); if (count%TT==0) { for (let i=0; i<Nrand; i++) { randp[i]=randn[i]; randn[i]=.5*rnd()+.5*rand[i]; } setrand(); count=0; } let wgtfac = wgt*wgt*(1-Math.exp(-4*kl[1]*wgt)); if (count%TT==0) { for (let i=0; i<Nrand; i++) { rand[i]=randp[i]+(randn[i]-randp[i])*wgtfac; } setrand(); gl.uniform1fv(loc_rand,rand); } let dx1=0,dy1=0,dz1=0; if (dxycount==0) { dx=dxc-dxp; dy=dyc-dyp; dz=dzc-dzp; zc *= Math.exp(2*dz); //zc += dz; xc -= (.5+(2*dx-0.5)*(1+2*dz))*zc; yc -= (.5+(2*dy-0.5)*(1+2*dz))*zc; // imposing max(uc.x)<=1, i.e. -xc+zc <= 1, i.e. xc >= zc-1, i.e. dxc >= zc-1-xc // imposing min(uc.x)>=0, i.e. -xc >= 0, i.e. xc <= 0, i.e. dxc <= -xc // we need to impose this again because inequalities may fail because zc changed xc=Math.max(zc-1,Math.min(0,xc)); yc=Math.max(zc-1,Math.min(0,yc)); // // if truncated, fix dx,dxc,dy,dyc dx = (-.5/(1+dz)+.5)/2; dxc = dxp+dx; dy = (-.5/(1+dz)+.5)/2; dyc = dyp+dy; (zc==1)&&(dxc=dyc=0); kp[6]*=Math.sin(count/TT*2*PI); kp[7]*=Math.sin(count/TT*2*PI); } gl.uniform1fv(loc_kp,kp); // for (let i=0; i<Nrand; i++) { rand[i]*=0.99; } if (dx!=0 || dy!=0 || dz!=0) { dxycount++; } gl.uniform3fv(loc_dxy,[dx, dy, dz]); gl.uniform3fv(loc_rc,[xc, yc, zc]); gl.uniform1f(loc_t,time/1000.); gl.uniform1f(loc_tr,count/TT); for (let j=0; j<2; j++) { flip = !flip; gl.bindFramebuffer(gl.FRAMEBUFFER, (flip ? fbB : fbA)); gl.activeTexture(gl.TEXTURE0); gl.bindTexture(gl.TEXTURE_2D, (flip ? texA : texB)); gl.activeTexture(gl.TEXTURE1); gl.bindTexture(gl.TEXTURE_2D, tex00); gl.activeTexture(gl.TEXTURE2); gl.bindTexture(gl.TEXTURE_2D, (flip ? texA2 : texB2)); gl.activeTexture(gl.TEXTURE3); gl.bindTexture(gl.TEXTURE_2D, tex02); gl.drawBuffers([ gl.COLOR_ATTACHMENT0,gl.COLOR_ATTACHMENT1 ]); gl.drawArrays(gl.TRIANGLES, 0, 6); } // flip = !flip; gl.viewport((C.width-Lx)/2,(C.height-Ly)/2,Lx,Ly); gl.useProgram(colp); gl.uniform1f(loc_tc,time/1000); gl.uniform2f(loc_Lc,Lx,Ly); gl.uniform2f(loc_mousec,mousex,mousey); gl.uniform1fv(loc_klc,kl); gl.uniform3fv(loc_dxyc,[dx-dx1, dy-dy1, dz-dz1]); gl.uniform3fv(loc_rcc,[xc, yc, zc]); dxycount=0;dx=0;dy=0;dz=0;dxp=dxc;dyp=dyc;dzp=dzc; if (count>12) { init=0; } if (!init) { gl.bindFramebuffer(gl.FRAMEBUFFER, null); gl.activeTexture(gl.TEXTURE0); gl.bindTexture(gl.TEXTURE_2D, (flip ? texB : texA)); gl.activeTexture(gl.TEXTURE1); gl.bindTexture(gl.TEXTURE_2D, texC); //color map gl.activeTexture(gl.TEXTURE2); gl.bindTexture(gl.TEXTURE_2D, tex00); //(flip ? texA : texB)); // previous gl.activeTexture(gl.TEXTURE3); gl.bindTexture(gl.TEXTURE_2D, (flip ? texB2 : texA2)); gl.activeTexture(gl.TEXTURE4); gl.bindTexture(gl.TEXTURE_2D, tex02); //(flip ? texA2 : texB2)); // previous //if (dz==0) gl.drawArrays(gl.TRIANGLES, 0, 6); } } prevt=time-(time-prevt)%dt; } if (savescr==1) { savescr=2; resize_render(); } if (savescr==2) { savescr=0; var tC = document.createElement("canvas"); tC.width = Lx; tC.height = Ly; var ctx = tC.getContext("2d", { preserveDrawingBuffer: true }); const pixels = new Uint8Array(4); gl.readPixels(0,0,1,1,gl.RGBA, gl.UNSIGNED_BYTE, pixels); ctx.setTransform(1,0,0,-1,0,gl.height); const sync = gl.fenceSync(gl.SYNC_GPU_COMMANDS_COMPLETE, 0);gl.flush();gl.clientWaitSync(sync, 0, gl.TIMEOUT_IGNORED);gl.deleteSync(sync); C.toBlob((blob) => { saveBlob(blob, `Atlas-${tokenData.tokenId}.png`); }); } requestAnimationFrame(render); } const saveBlob = (function() { const a = document.createElement('a'); document.body.appendChild(a); a.style.display = 'none'; return function saveData(blob, fileName) { const url = window.URL.createObjectURL(blob); a.href = url; a.download = fileName; a.click(); }; }()); // resize event let tid=0; onresize => { clearTimeout(tid); tid=setTimeout(resize_render,150) }; let f1=0,savescr=0; // keyboard event onkeyup=e=>{ if (e.key==' ') { // spacebar running = !running; } if ( window !== window.parent ) { // iframe if (e.keyCode==65) dxc-=0.01; //a = left if (e.keyCode==68) dxc+=0.01; //d = right if (e.keyCode==87) dyc+=0.01; //w = up if (e.keyCode==83) dyc-=0.01; //s = down } else { // not iframe if (e.keyCode==37) dxc-=0.01; //left if (e.keyCode==39) dxc+=0.01; //right if (e.keyCode==38) dyc+=0.01; //up if (e.keyCode==40) dyc-=0.01; //down } if (e.keyCode>=49&&e.keyCode<=56) tmult=1+e.keyCode-49; //1-8 if (e.keyCode==77) anim=!anim; //m = anim/!anim if (e.keyCode==88) dzc-=0.03; //x = zoom in if (e.keyCode==90) dzc=Math.min(0,dzc+0.03); //z = zoom out if (e.keyCode==70) { f1=(f1+1)%3; resize_render(); } // f if (e.keyCode==80) { savescr=1; Lx = C.width; Ly = C.height; } //p = print screen return false; } document.body.style.cursor = "none"; function handler(e) { if (running) { var scroll = (e.deltaY || -1*e.wheelDelta || 10*e.detail); var isTouchPad = e.wheelDeltaY ? e.wheelDeltaY === -3 * e.deltaY : e.deltaMode === 0; dzc=Math.min(0,dzc+.5*Math.max(-0.1,Math.min(0.1,scroll/Ly*2*(1+3*isTouchPad)))); } e.stopPropagation(); e.preventDefault(); return false; } gl.canvas.addEventListener("mousewheel", handler, false); gl.canvas.addEventListener("DOMMouseScroll", handler, false); const delta = 6; let startx; let starty; let startdist=0; let mousedown=0; let mousex=.5; let mousey=.5; function handler_down(e) { if (running) { mousedown=1; startx = (e.clientX || (e.touches && e.touches[0].clientX)); starty = (e.clientY || (e.touches && e.touches[0].clientY)); if (e.touches && e.touches.length === 2) { e.preventDefault(); startx = startx/2 + e.touches[1].clientX / 2; starty = starty/2 + e.touches[1].clientY / 2; startdist = Math.sqrt((e.touches[0].clientX-e.touches[1].clientX)**2+(e.touches[0].clientY-e.touches[1].clientY)**2); } } } gl.canvas.addEventListener("mousedown", handler_down, false); gl.canvas.addEventListener("touchstart", handler_down, false); function handler_move(e) { mousex = e.clientX/Lx*2; mousey = 1-e.clientY/Ly*2; if (running && mousedown) { const sx = (e.clientX || (e.touches && e.touches[0].clientX)); const sy = (e.clientY || (e.touches && e.touches[0].clientY)); e.preventDefault(); if (e.touches && e.touches.length === 2) { e.preventDefault(); // Prevent page scroll let scale = 100; const deltaDistance = Math.sqrt((e.touches[0].clientX-e.touches[1].clientX)**2+(e.touches[0].clientY-e.touches[1].clientY)**2); if (startdist!=0) { scale = 100*(1-deltaDistance/startdist); } dzc=Math.min(0,dzc+.5*Math.max(-0.25,Math.min(0.25,1.3*scale/Ly))); } else { dxc-=(sx-startx)/Lx*Math.exp(0.2-0.1*dzc); dyc+=(sy-starty)/Ly*Math.exp(0.2-0.1*dzc); // imposing max(uc.x)<=1, i.e. -xc+zc <= 1, i.e. xc >= zc-1, i.e. dxc >= zc-1-xc // imposing min(uc.x)>=0, i.e. -xc >= 0, i.e. xc <= 0, i.e. dxc <= -xc dxc=Math.max(-1-xc+zc,Math.min(-xc,dxc)); dyc=Math.max(-1-yc+zc,Math.min(-yc,dyc)); startx = sx;starty = sy; } } } gl.canvas.addEventListener("mousemove", handler_move, false); gl.canvas.addEventListener("touchmove", handler_move, false); gl.canvas.addEventListener('ondragstart', function (e) { e.preventDefault(); return false; }); gl.canvas.addEventListener('mouseleave', function (e) { mousedown=0; }); gl.canvas.addEventListener('mouseup', function (e) { mousedown=0; }); gl.canvas.addEventListener('touchend', function (e) { mousedown=0; }); gl.canvas.addEventListener('dblclick', function (e) { running = !running; }); resize_render();
let useA,prngA,prngB; class Random { constructor() { useA = false; let sfc32 = function (uint128Hex) { let a = parseInt(uint128Hex.substr(0, 8), 16); let b = parseInt(uint128Hex.substr(8, 8), 16); let c = parseInt(uint128Hex.substr(16, 8), 16); let d = parseInt(uint128Hex.substr(24, 8), 16); return function () { 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; }; }; prngA = new sfc32(tokenData.hash.substr(2, 32)); prngB = new sfc32(tokenData.hash.substr(34, 32)); for (let i = 0; i < 1e6; i += 2) { prngA(); prngB(); } } random_dec() { useA = !useA; return useA ? prngA() : prngB(); } } function rnd() { return R.random_dec() } function vecscl(v,k) { let w=[]; for (let i=0; i<v.length; i++) { w[i] = v[i]*k; } return w } function clamp(x) { return Math.max(0,Math.min(1,x)); } function dot2(x,y) { return x[0]*y[0]+x[1]*y[1]; } if (GET.hash) { tokenData.hash = GET.hash; } let mintn = tokenData.tokenId%1000000; let hashlist = [ "0xa13b49485299cc1d0a337166703adaa84d16afdd7f967817d97cb12a12261002", "0x646d6cae9d01d922825bd8f5f40fdb820299b3582fedac9b4a540972ef885f44", "0x3f4f04b90d31bee7e4750fda24cecbb9c674344aaddcf2de91e4e1a377ba35f1", "0x90b70525cb642187a6e0f56018a42ec3f419b2f7c544a12184c331b2797812de", "0x26e0b3f96a81f1c56858d6011a8f60681498cffda232093f4dc1b24ae80d01ec", "0x49abdd5f90e662835b83e7eb4fe993de9866a0d0b4d9f701fff94338a0489d49", "0x1a9f7d7cb6ca528846d9b6387a8988d8f67b5d36de0a991a36cb9292672294b7", "0x22c5d01cd9df91ebe1aaaadb92facd9bbb618625e963da7c1c3ec6c862b19955", "0x6b8bfb011ceaf50891a20ed882870f0d49d53c8e633a4f546e14e844ab993bc1", "0x2296bca26af467663a989ab9d733d90f22f8994bc72ec46801128fe77ae8722d" ]; (mintn>0)&&(mintn<11)&&(tokenData.hash=hashlist[mintn-1]); R = new Random(); let C,D,body,gl,Shader; document.body.style.backgroundColor = "#030303"; console.log("Atlas by Eric De Giuli"); C=({body}=D=document).createElement('canvas'); body.appendChild(C); gl=C.getContext('webgl2'); Shader=(typ,src)=>{ const s =gl.createShader(typ); gl.shaderSource(s,src); gl.compileShader(s); if (!gl.getShaderParameter(s, gl.COMPILE_STATUS)) { console.error(`Error compiling ${typ === gl.VERTEX_SHADER ? "vertex" : "fragment"} shader "${src}":`); console.log(gl.getShaderInfoLog(s)); } return s; } let simp,colp,vs,fs; let Lx,Ly,Nx,Ny; let hgt = rnd(); let Nm = (hgt<.15) ? 30 : (hgt<0.4) ? 60 : (hgt<0.6) ? 90 : (hgt<0.75) ? 120 : 240; const head = /\bHeadlessChrome\//.test(navigator.userAgent); let PI = 3.1415926; let pal,pj; let palp = [11,4,8,3,4,3,4,4,3,3,6,2,4,3,6,10,6,5,5,3]; const pinv = [0.7,1,1,1,0,1,0,1,1,1,1,1,0,1,0.5,0.5,0.5,0,0.4,1]; // prob of inv const plum = [0,0,1,0.4,0,1,0,1,0,0,0.4,1,0,0.4,0,0,0.4,0,0.4,1]; // prob of lum palp = vecscl(palp,1/97); let cumpal = []; cumpal[0]=0; for (let i=1; i<palp.length; i++) { cumpal[i]=cumpal[i-1]+palp[i-1]; } let st = 1; pj=1; let palr = rnd(); while (st<palp.length && cumpal[st]<palr) { st++; } st--; let pj2 = Math.floor(11*rnd()); let kl = new Float32Array(N); for (let i=0; i<N; i++) { kl[i]=rnd(); } kl[7]*=kl[7]*(3-2*kl[7]); kl[19]*=kl[19];//*(3-2*kl[19]); kl[28]*=kl[28]*(2-kl[28]); kl[29]*=kl[29]*(3-2*kl[29]); kl[5] = 1-kl[5]*kl[5]; kl[15]=1.-kl[15]*kl[15];//*kl[15]; let lum=0,inv=0,sqr = 0; let starch = 1; let rcorr = rnd(); sqr=rnd();sqr*=sqr; let horiz = (rnd()<.2) ? 1 : 0; let eclipa = rnd()<0.2 ? 0.1*Math.exp(rnd()) : 0; let eclipt = 6.2*rnd(); let cres = 1; eclipa = Math.max(0.1,eclipa); eclipa*=3; let anim=0; let esc = rnd()<.22 ? 1 : 0; inv = rnd()<pinv[st] ? 1 : 0; lum = rnd()<plum[st] ? 1 : 0; kl[9]=0.9; kl[11]=0.9;//+.1; kl[10]=0.9;//-.1; switch(st) { case 0: pj=6;pj2=7; horiz=0; (!inv)&&(kl[7]=-1-.5*kl[7]); kl[29]=.5; break; case 1: pj=11;pj2=7; kl[10]-=.4; kl[7]*=-2/3; Nm*=2; Nm=Math.min(240,Nm); break; case 2: pj=1;pj2=5; kl[10]-=.1; kl[7]/=3; (kl[0]<.2)&&(Nm=15); break; case 3: pj=1;pj2=0; kl[9]-=.1; kl[10]-=.15; kl[29]*=.5; Nm=Math.max(90,Nm); horiz=0; kl[7]*=-1; kl[2]*=2;kl[3]*=2;kl[4]*=2; break; case 4: pj=3;pj2=9; kl[29]*=.5; kl[7]=-1; kl[3]=.95; Nm=Math.min(120,Nm); horiz=0; break; case 5: pj=6;pj2=0; kl[9]-=.2; kl[29]*=.5; kl[7]=inv ? 0 : -1; esc=1; Nm*=2; break; case 6: pj=4;pj2=7; sqr=0; Nm/=2; Nm=Math.max(30,Nm); kl[19]=1.5; kl[29]=1; horiz=0; break; // nocturne case 7: pj=11;pj2=5; kl[10]-=.1; kl[7]=0; break; case 8: pj=11;pj2=4; kl[9]-=.2;kl[10]-=.2;kl[11]-=.2;kl[7]=-1; sqr*=sqr; horiz=0; Nm=Math.max(Nm/2,30); break; case 9: pj=11;pj2=0; kl[10]-=.2; sqr = 1-sqr*sqr; kl[7]=-1; Nm=Math.min(Nm,90); break; case 10: pj=0;pj2=0; Nm=Math.max(90,Nm); horiz=0; kl[29]= lum ? 0 : .5; break; case 11: pj=3;pj2=3; horiz=1; kl[3]=.97; kl[5]=0.1; kl[7]=1; rcorr=0; break; case 12: pj=2;pj2=3; kl[7]=1; horiz=0; break; case 13: pj=2;pj2=10; sqr/=2; kl[7]*=-1; kl[29]=.5; Nm = Math.min(90,Nm); horiz=0; break; case 14: pj=10;pj2=8; kl[9]-=.1*(1-2*inv); kl[10]-=.1; kl[7]*=-.8; horiz=0; break; case 15: pj=10;pj2=4; sqr/=2; kl[2]=1-kl[2]*kl[2]; (!inv)&&(kl[19]=2); (inv==1)&&(Nm=Math.max(60,Nm)); horiz=0; kl[29]*=0.5; break; case 16: pj=6;pj2=10; (!inv)&&(lum=0); (lum)&&(kl[29]=0); break; case 17: pj=7;pj2=12; kl[10]-=.2; kl[4]=0; kl[13]=1; kl[7]=-0.2; kl[19]=1; Nm=Math.max(30,Nm/2); break; case 18: pj=12;pj2=3; kl[29]=.5; esc=0; (inv)&&(lum=horiz=0); break; case 19: pj=12;pj2=6; kl[29]*=.5; esc=1; lum=1;kl[7]=0;horiz=0; Nm=Math.max(Nm,90); } (!lum)&&(esc=0); (esc)&&(Nm=Math.max(15,Nm/2)); (Nm<=20)&&(horiz=sqr=0); (starch==0)&&(lum=1); (lum==1)&&(rcorr=1-rcorr*rcorr*rcorr); (lum)&&(horiz=sqr=0); (horiz)&&(kl[21]=kl[29]=.5); (kl[15]<.3)&&(kl[29]=0.5); (lum&&Nm>100)&&(Nm/=2); if (GET.N) { Nm=GET.N; } if (innerWidth>innerHeight) { Ny = Nm; Nx = Math.floor(Nm*innerWidth/innerHeight); } else { Nx = Nm; Ny = Math.floor(Nm*innerHeight/innerWidth); } if (GET.a) { Ny=Nm;Nx=Math.floor(GET.a*Ny); } pal = new Uint8Array(10*4*2); for (let k=0; k<11; k++) { // which colour in palette for (let k2=0; k2<2; k2++) { // which palette let pp = (k2==0) ? pj : pj2; let kk = Math.min(k,pals[pp].length-1); pal[3*k+3*10*k2] = pals[pp][kk][0]; pal[3*k+3*10*k2+1] = pals[pp][kk][1]; pal[3*k+3*10*k2+2] = pals[pp][kk][2]; if (inv) { pal[3*k+3*10*k2] = (pal[3*k+3*10*k2]+180)%360; } //invert colour } } let kp,km,rand,randp,randn; rand = []; for (let i=0; i<Nrand; i++) { rand[i]=rnd(); } randp = []; for (let i=0; i<Nrand; i++) { randp[i]=rnd(); } randn = []; for (let i=0; i<Nrand; i++) { randn[i]=rnd(); } let k0=1; kp = new Float32Array(N); km = new Float32Array(N); for (let i=0; i<N; i++) { kp[i]=k0*rnd(); } kp[11]*=kp[11]; for (let i=0; i<N; i++) { km[i]=k0*rnd(); } let bg_h = (lum*.5+ pal[0]/255)%1; let bg_s = .5;//.65; //pal[1]/255*1.2; let bg_l = Math.pow(pal[2]/255,.75); let bg_r = Math.max(0,Math.min(1, Math.abs(bg_h*6.0-3.0)-1.0)); let bg_g = Math.max(0,Math.min(1, Math.abs((bg_h*6.0+4.0)%6-3.0)-1.0)); let bg_b = Math.max(0,Math.min(1, Math.abs((bg_h*6.0+2.0)%6-3.0)-1.0)); bg_r = bg_l + bg_s*(bg_r-.5)*(1-Math.abs(2.0*bg_l-1.0)); bg_g = bg_l + bg_s*(bg_g-.5)*(1-Math.abs(2.0*bg_l-1.0)); bg_b = bg_l + bg_s*(bg_b-.5)*(1-Math.abs(2.0*bg_l-1.0)); bg_b = Math.pow(bg_b,.4+.3*kp[0]); function setrand() { rand[0] = km[16]*3; rand[2] = km[17]*3; rand[37] = km[0]; rand[38] = kp[4]; rand[39] = bg_r; rand[40] = bg_g; rand[41] = bg_b; rand[42] = km[5] < .77 ? 1 : 0; rand[43] = km[6]; rand[44] = km[7]; rand[45] = lum; rand[46] = sqr; rand[47] = rcorr; rand[48] = horiz; rand[67] = eclipa; rand[68] = eclipt; rand[69] = cres; rand[88] = esc; } setrand(); let nx = 2+Math.floor(3*rnd()); let ny = 2+Math.floor(3*rnd()); let rr = rnd(); let n4 = Math.floor(Math.exp(4*rnd())); let rbg = Math.floor(19*rnd()); let rbgarr = [0,1,2,3,4,6,6,7,8,8,9,9,11,12,13,14,15,15,16]; rbg=rbgarr[rbg]; (rbg==1)&&(Nm=Math.min(60,Nm)); function ff1(x,r) { return r*2*kl[20]*2*Math.sin(x*rr*2*PI+kl[0])*Math.sin(x*rr*2*PI+kl[0]); } function ff2(x,r) { return r*2*kl[21]*2*Math.cos(x*rr*2*PI+kl[1])*Math.cos(x*rr*2*PI+kl[1]); } // initial conditions const tex0 = new Uint8Array(Nx*Ny*4); let th; for (let x = 0; x < Nx; x++) { for (let y = 0; y < Ny; y++) { let i = x+Nx*y; let r2 = (x-Nx/2)**2+(y-Ny/2)**2; r2/=(Nx*Nx+Ny*Ny)/4; switch(rbg) { case 0: r2 = Math.sin(x/nx)*Math.sin(y/ny)*Math.sin(25*r2)>.1+.5*rr; break; case 1: r2 = .25*Math.sin(2*x/Nx*nx*PI)*Math.sin(2*y/Ny*ny*PI)*Math.sin(25*r2)-0.5*rr; break; case 2: r2 = Math.sin(y*x/Nx*nx*PI)*Math.sin(y/Ny*ny*PI)*Math.sin(25*r2)-0.5*rr; break; case 3: r2 = Math.sin(y*x/Nx*nx*PI)*Math.sin(y/Ny*ny*PI)*Math.sin(2*(x-Nx/2)/(y-Ny/2)+1*(y-Ny/2)/(x-Nx/2))>0.5*rr; break; case 4: r2 = 1+Math.sin(Math.sin(x/Nx*n4)*y/Ny*nx*PI)*Math.sin(y/Ny*ny*PI)*Math.sin(2*(x-Nx/2)/(y-Ny/2)+1*(y-Ny/2)/(x-Nx/2))-0.5*rr; (r2!=r2)&&(r2=1); break; case 5: r2 = Math.sin(Math.sin(x/Nx*n4*PI)*y/Ny*(1-y/Ny)*ny*PI)*Math.sin(x/Nx*nx*PI)-0.6*rr; break; case 6: r2 = Math.sin(Math.sin(y/Ny*n4*PI)*x/Nx*(1-x/Nx)*nx*PI)*Math.sin(y/Ny*ny*PI)-0.6*rr; break; case 7: r2 = Math.sin(30*x/Nx*nx*PI)*Math.sin(x/Nx*nx*PI)>0.6*rr; break; case 8: r2 = Math.sin(30*x/Nx*nx*PI)*Math.sin(y/Ny*ny*PI)>0.6*rr; break; case 9: r2 *= .7*(Math.sin(20*(x/Nx-0.5)*nx)+Math.sin(2*(y/Ny-0.5))); break; case 10: r2 = 1+r2*Math.sin(20*r2*nx)-.3*rr; break; case 11: r2 = -1+Math.sin(r2*nx*Math.tan(n4*x/Nx+9*y/Ny))-.6*rr; break; case 12: th = Math.atan2(y-Ny/2,x-Nx/2); r2*=1+0.2*Math.cos(nx*th)*(1+0.6*Math.sin(nx/ny+3*nx*th)*(1+0.6*Math.cos(5*nx*th))); r2*=.72; break; case 14: r2=0.2+.8*rr; break; case 15: r2 = 10*Math.max(x/Nx/3,(1-x/Nx)/3); break; case 16: r2 = 10*Math.max(y/Ny/3,(1-y/Ny)/3); break; } tex0[4*i] = Math.floor(255*ff1(r2,rnd())); tex0[4*i+1] = Math.floor(255*ff2(r2,rnd()) ); tex0[4*i+2] = Math.floor(255*ff2(r2,rnd()) ); tex0[4*i+3] = Math.floor(255*ff1(r2,rnd()) ); } } dzp=dzc; let loc_a,loc_ac,loc_img,loc_img00,loc_img2,loc_img02,loc_res,loc_t,loc_tr,loc_rand,loc_palc,loc_kp,loc_km,loc_kl,loc_klc,loc_kv,loc_kw,loc_imgc,loc_imgc2,loc_imgcp,loc_imgc2p,loc_resc,loc_Lc,loc_tc,loc_randc,loc_aavg,loc_bavg,loc_dxy,loc_dxyc,loc_rc,loc_rcc; function thrower(prog) { if (!gl.getProgramParameter(prog, gl.LINK_STATUS)) { console.log(`Link failed:\n${gl.getProgramInfoLog(prog)}`); console.log(`VS LOG:\n${gl.getShaderInfoLog(vs)}`); console.log(`FS LOG:\n${gl.getShaderInfoLog(fs)}`); throw 'AARG DED'; } } simp = gl.createProgram(); // simulation program vs = Shader(gl.VERTEX_SHADER, src_vert); fs = Shader(gl.FRAGMENT_SHADER, src_simp); gl.attachShader(simp, vs); gl.attachShader(simp, fs); gl.linkProgram(simp); gl.useProgram(simp); thrower(simp); function gul(pr,lab) { return gl.getUniformLocation(pr,lab); } loc_img=gul(simp,'img'); loc_img00=gul(simp,'img00'); loc_img2=gul(simp,'img2'); loc_img02=gul(simp,'img02'); loc_res=gul(simp,'res'); loc_t =gul(simp,'t'); loc_tr =gul(simp,'tr'); loc_rand =gul(simp,'rand'); loc_kp =gul(simp,'kp'); loc_km =gul(simp,'km'); loc_kl =gul(simp,'kl'); loc_dxy =gul(simp,'dxy'); loc_rc =gul(simp,'rc'); let loc_mult =gul(simp,'mult'); gl.uniform1i(loc_img,0); gl.uniform1i(loc_img00,1); gl.uniform1i(loc_img2,2); gl.uniform1i(loc_img02,3); gl.uniform2f(loc_res,Nx,Ny); loc_a = gl.getAttribLocation(simp, "a"); gl.activeTexture(gl.TEXTURE0); gl.vertexAttribPointer(loc_a, 2, gl.FLOAT, false, 0, 0); gl.enableVertexAttribArray(loc_a); colp = gl.createProgram(); // colour program vs = Shader(gl.VERTEX_SHADER, src_vert); fs = Shader(gl.FRAGMENT_SHADER, src_colp); gl.attachShader(colp, vs); gl.attachShader(colp, fs); gl.linkProgram(colp); gl.useProgram(colp); thrower(colp); loc_imgc=gul(colp,'img'); loc_imgcp=gul(colp,'imgp'); loc_imgc2=gul(colp,'img2'); loc_imgc2p=gul(colp,'img2p'); loc_palc=gul(colp,'pal'); loc_resc=gul(colp,'res'); loc_Lc=gul(colp,'L'); loc_tc =gul(colp,'t'); loc_randc =gul(colp,'rand'); loc_dxyc =gul(colp,'dxy'); loc_rcc =gul(colp,'rc'); loc_klc =gul(colp,'kl'); let loc_mousec=gul(colp,'mouse'); gl.bindBuffer(gl.ARRAY_BUFFER, gl.createBuffer()); gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([-1.0, 1.0, 1.0, 1.0, 1.0, -1.0, -1.0, 1.0, 1.0, -1.0, -1.0, -1.0]),gl.STATIC_DRAW); gl.uniform1i(loc_imgc,0); gl.uniform1i(loc_imgcp,2); gl.uniform1i(loc_imgc2,3); gl.uniform1i(loc_imgc2p,4); gl.uniform2f(loc_resc,Nx,Ny); loc_ac = gl.getAttribLocation(colp, "a"); //'a'); gl.activeTexture(gl.TEXTURE0); gl.vertexAttribPointer(loc_ac, 2, gl.FLOAT, false, 0, 0); gl.enableVertexAttribArray(loc_ac); let M=1; var isMobile = window.matchMedia("(hover: none)").matches; // no hovering let dpr=1; function resize_render() { let w=innerWidth, h=innerHeight, dpr=devicePixelRatio; C.width = M*w*dpr|0; C.height = M*h*dpr|0; if (head || f1==0) { Lx = Math.floor(C.width); Ly = Math.floor(C.height); } else {//if (f1==1 || isMobile) { C.requestFullscreen(); Lx = C.width; Ly=C.height; } C.style.width = w+'px'; C.style.height = h+'px'; gl.viewport((C.width-Lx)/2,(C.height-Ly)/2,Lx,Ly); render(); } function texset(wrap=gl.CLAMP_TO_EDGE,fil=gl.NEAREST) { //NEAREST) { gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, wrap); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, wrap); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, fil); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, fil); } let tex00,tex02,texA,texB,texA2,texB2,texC,fbA,fbB; tex00 = gl.createTexture(); gl.bindTexture(gl.TEXTURE_2D, tex00); gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, Nx, Ny, 0, gl.RGBA, gl.UNSIGNED_BYTE, tex0.subarray(0, Nx*Ny*4)); texset(gl.REPEAT,gl.LINEAR); tex02 = gl.createTexture(); gl.bindTexture(gl.TEXTURE_2D, tex02); gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, Nx, Ny, 0, gl.RGBA, gl.UNSIGNED_BYTE, 255-tex0.subarray(0, Nx*Ny*4)); texset(gl.REPEAT,gl.LINEAR); texA = gl.createTexture(); gl.bindTexture(gl.TEXTURE_2D, texA); gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, Nx, Ny, 0, gl.RGBA, gl.UNSIGNED_BYTE, tex0.subarray(0, Nx*Ny*4)); fbA = gl.createFramebuffer(); gl.bindFramebuffer(gl.FRAMEBUFFER, fbA); gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texA, 0); texset(); texB = gl.createTexture(); gl.bindTexture(gl.TEXTURE_2D, texB); gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, Nx, Ny, 0, gl.RGBA, gl.UNSIGNED_BYTE, null); fbB = gl.createFramebuffer(); gl.bindFramebuffer(gl.FRAMEBUFFER, fbB); gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texB, 0); texset(); texA2 = gl.createTexture(); gl.bindTexture(gl.TEXTURE_2D, texA2); gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, Nx, Ny, 0, gl.RGBA, gl.UNSIGNED_BYTE, 255-tex0.subarray(0, Nx*Ny*4)); gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT1, gl.TEXTURE_2D, texA2, 0); texset(); texB2 = gl.createTexture(); gl.bindTexture(gl.TEXTURE_2D, texB2); gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, Nx, Ny, 0, gl.RGBA, gl.UNSIGNED_BYTE, null); gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT1, gl.TEXTURE_2D, texB2, 0); texset(); texC = gl.createTexture(); //colormap gl.bindTexture(gl.TEXTURE_2D, texC); gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB, 10, 2, 0, gl.RGB, gl.UNSIGNED_BYTE, pal); texset(gl.REPEAT,gl.LINEAR); //texset(gl.CLAMP_TO_EDGE,gl.LINEAR); gl.useProgram(colp); gl.uniform1i(loc_palc, 1); //texture 1
"use strict"; let N = 30; let Nrand = 100; let R; let dx=0.0,dy=0.0,dz=0.0; let dxc=0.0,dyc=0.0,dzc=0.0; let dxp=0.0,dyp=0.0,dzp=0.0; let xc=0,yc=0,zc=1; let TWO_PI=6.28318530718; let feat=[]; var GET = {}; var query = window.location.search.substring(1).split("&"); for (var i = 0, max = query.length; i < max; i++) { if (query[i] === "") continue; var param = query[i].split("="); GET[decodeURIComponent(param[0])] = decodeURIComponent(param[1] || ""); } let pals = []; pals.push([[359,31,38],[353,19,66],[6,20,65],[22,21,63],[20,16,67],[28,21,67],[6,20,65],[347,13,65]]); pals.push([[208,49,37],[205,41,57],[192,29,44],[190,14,62],[220,9,76],[12,4,44],[167,16,79],[180,7,98]]); pals.push([[222,86,28],[208,88,36],[203,61,72],[215,49,94],[211,68,118],[236,100,30],[195,85,57]]); pals.push([[4,100,29],[1,96,73],[26,92,82],[34,58,77],[48,100,86],[21,100,73],[8,100,14]]); pals.push([[43,35,24],[46,39,37],[41,27,80],[39,46,43],[39,83,80],[46,6,85],[46,15,86]]); pals.push([[209,92,20],[197,98,32],[195,79,50],[190,42,87],[189,62,122]]); pals.push([[331,21,35],[265,23,45],[335,26,86],[163,32,24],[210,24,32],[180,31,110],[49,30,71],[180,23,102],[170,13,54]]); pals.push([[26,81,10],[26,78,28],[42,68,73],[40,46,73],[42,76,90],[37,62,90]]); pals.push([[102,41,54],[123,37,61],[94,27,63],[121,30,67],[91,26,65],[125,37,61]]); pals.push([[115,52,22],[98,51,53],[78,58,72],[91,67,112],[6,54,51]]); pals.push([[349,83,61],[250,44,58],[191,44,58],[27,82,64],[45,85,62],[0,100,70]]); pals.push([[221,20,18],[199,26,33],[190,10,70],[220,0,87],[190,0,87],[205,30,37],[183,20,87],[215,43,31],[185,0,87],[200,0,87]]); pals.push([[0,0,20],[0,0,15],[0,0,10],[210,20,20],[210,20,30],[90,50,40],[120,50,50],[180,50,75],[180,70,90],[210,70,95]]); pals.push([[140,60,20],[140,60,30],[140,60,40],[140,60,50],[140,60,60],[220,50,70],[200,60,75],[200,60,85],[210,60,50],[220,60,35]]); let header = `#version 300 es precision highp float;`; var src_vert = header+` in vec2 a; out vec2 u; void main() { gl_Position = vec4(a,0.,1.); u = a/2. +vec2(.5,.5); }`; var src_simp = header+` const int N = 30; const float Nf =20.; const int Nrand =100; const float Nrandf =100.; const float dn =0.1; const int Nx =512; const float Nxf =512.; const float PI =3.1415926; const int numOctaves = 9; in vec2 u; layout(location = 0) out vec4 cout; layout(location = 1) out vec4 cout2; uniform vec2 res; uniform float t; // frame number uniform float tr; // relative frame number wrt period \in [0,1] uniform highp sampler2D img; uniform highp sampler2D img00; uniform highp sampler2D img2; uniform highp sampler2D img02; uniform float kp[N]; uniform float kl[N]; uniform float rand[Nrand]; uniform vec3 dxy; uniform vec3 rc; uniform float mult; vec2 hash2( in vec2 x ) { int ii = int(mod(x.x+res.x*x.y,Nrandf)); //counter into array of random #s int i2 = int(mod(x.y-res.y*x.x,Nrandf)); //counter into array of random #s return vec2(rand[ii],rand[i2]); } float ddot ( in vec2 x, in vec2 y ) { return x.x+y.x + x.y*y.y; } vec3 noise( in vec2 p ) { vec2 i = floor( p ); vec2 f = fract( p ); vec2 u = f*f*f*(f*(f*6.0-15.0)+10.0); vec2 du = 30.0*f*f*(f*(f-2.0)+1.0); vec2 ga = hash2( i + vec2(0.0,0.0) ); vec2 gb = hash2( i + vec2(1.0,0.0) ); vec2 gc = hash2( i + vec2(0.0,1.0) ); vec2 gd = hash2( i + vec2(1.0,1.0) ); float va = ddot( ga, f ); float vb = ddot( gb, f - vec2(1.0,0.0) ); float vc = ddot( gc, f - vec2(0.0,1.0) ); float vd = ddot( gd, f - vec2(1.0,1.0) ); return vec3( va + u.x*(vb-va) + u.y*(vc-va) + u.x*u.y*(va-vb-vc+vd), // value ga + u.x*(gb-ga) + u.y*(gc-ga) + u.x*u.y*(ga-gb-gc+gd) + // derivatives du * (u.yx*(va-vb-vc+vd) + vec2(vb,vc) - va)); } vec3 fbm( in vec2 x, in float H, in int numoct ) { float G = exp(-2.*H);float f = 1.0;float a = 1.0;vec3 t = vec3(0.); for( int i=0; i<numoct; i++ ) { t += a*noise(f*x);f *= 2.0;a *= G; } return t; } vec4 laplacian(in sampler2D img, in vec2 uv, in float dx, in vec2 dt) { vec4 rg = texture(img, uv + vec2(-1., -1.)*dt)*(0.05+dx); rg += texture(img, uv + vec2(0., -1.)*dt)*(0.2-dx); rg += texture(img, uv + vec2(1., -1.)*dt)*(0.05+dx); rg += texture(img, uv + vec2(-1., 0.)*dt)*(0.2-dx); rg -= texture(img, uv + vec2(0., 0.)*dt); rg += texture(img, uv + vec2(1., 0.)*dt)*(0.2-dx); rg += texture(img, uv + vec2(-1., 1.)*dt)*(0.05+dx); rg += texture(img, uv + vec2(0., 1.)*dt)*(0.2-dx); rg += texture(img, uv + vec2(1., 1.)*dt)*(0.05+dx); return rg; } void main(void) //( out vec4 fragColor, in vec2 fragCoord ) { float sin1 = rand[42]; vec2 dt = 1./res; //rc.z/res; float tfac = exp(1.+kl[6]*sin(t*kp[13])); vec2 uc = -rc.xy + u*rc.z; // world space uc = u; // always simulate the entire world vec2 uv = u; // no resampling vec2 uc2 = uc; uc2.x*=1.+sin1*(40.*kl[14]-1.); uc2.y*=1.+(1.-sin1)*(40.*kl[15]-1.); vec3 ff = 1.9*(0.4+0.6*kp[9])*fbm(-(.3+.4*kl[11])*uc2+kl[16]+t/16.*vec2(kl[16]-.5,kl[17]-.5)+kl[18]*fbm((.3+.5*kl[12])*uc2,.7,4).yz,0.5,4); vec3 f2 = 1.1*(0.4+0.6*kp[10])*fbm(uc2+fbm(-0.6*uc2,0.7,5).yz,0.7,4); sin1 = .5+clamp(kl[16]*200.*ff.y,-.5,.5); float cos1 = 1.-sin1; float sin2 = .5+clamp(100.*ff.z+40.*(kl[8]-.5),-.5,.5); float sss = -1.+2.*round(fract(uc.y*res.y/8.)); float sss2 = -1.+2.*round(fract(uc.x*res.x/19./(.3+kl[2]))); sss = sin2*sss+(1.-sin2)*sss2; uv.x+=.2*(1.+2.*kp[16])*cos1*(.3*tr*(1.-tr)*(1.-tr)*(ff.x*ff.x) + (1.-tr)*(1.-tr)*1.*(kl[0]-.5))*rand[0]*sss*17./res.x/2.*(round(fract(uc.y*res.y/2.))-.5); uv.y+=.2*(1.+2.*kp[17])*sin1*(.3*tr*(1.-tr)*(1.-tr)*(ff.x*ff.x) + (1.-tr)*(1.-tr)*1.*(kl[0]-.5))*rand[0]*sss*17./res.y/2.*(round(fract(uc.x*res.x/2.))-.5); float r2 = (uc.x-.5)*(uc.x-.5)+(uc.y-.5)*(uc.y-.5); float sx = cos((uc.x-.5)*kl[7]*2.+kl[9]); float sy = cos((uc.y-.5)*kl[8]/2.+kl[10]); float x0 = .5+.5*cos(t/3.2321); float y0 = .5+.5*sin(t/2.); float rfac = (uc.x-x0)*(uc.x-x0)+(uc.y-y0)*(uc.y-y0); rfac = exp(kp[17]*sin(5.*kp[18]*rfac)); vec4 cc,cc2; vec4 lp,lpb,cv,cu,cvb,cub; vec4 lp2,lpb2,cv2,cu2,cvb2,cub2; float aa,bb,aa2,bb2; vec2 ex = vec2(1.,0.); vec2 ey = vec2(0.,1.); cc = texture(img,uv); aa = cc.x/256. + cc.y; bb = cc.z/256. + cc.w; lp = laplacian(img,uv,(kp[0]*2.-1.)*f2.x*(1.-aa),dt); lpb = laplacian(img,uv,(kp[1]*2.-1.)*ff.x*bb,dt); cv= texture(img, uv + ey*dt); cu= texture(img, uv + ex*dt); cvb= texture(img, uv - ey*dt); cub= texture(img, uv - ex*dt); cc2 = texture(img2,uv); aa2 = cc2.x/256. + cc2.y; bb2 = cc2.z/256. + cc2.w; lp2 = laplacian(img2,uv,(kp[0]*2.-1.)*f2.x*(1.-aa2),dt); lpb2 = laplacian(img2,uv,(kp[1]*2.-1.)*ff.x*bb2,dt); cv2= texture(img2, uv + ey*dt); cu2= texture(img2, uv + ex*dt); cvb2= texture(img2, uv - ey*dt); cub2= texture(img2, uv - ex*dt); float da = rfac*(1.-aa)*(1.-bb)*(lp.x+256.*lp.y)/256. + (1.+2.*kp[11])*( -aa*bb*bb + kl[10]*aa2*aa + 0.015*(1.+kp[17])*(1.-aa))*ff.x*ff.x ; float db = rfac*(1.+kp[7])*(0.02+ff.x*ff.x)*aa*0.5*(lpb.z+256.*lpb.w)/256. + (1.+2.*kp[11])*( aa*bb*bb - 0.04*(1.+1.*kp[6])*bb)*ff.x*ff.x; float da2 = 1.2*(1.-kp[17])*(1.+kp[7])*(0.02+f2.x*f2.x)*bb2*0.5*(lpb2.x+256.*lpb2.y)/256. + 3.*( bb*aa2*aa2 - 0.04*(1.+1.*kp[8])*aa2)*f2.x*f2.x; float db2 = 1.2*(1.-kp[18])*(1.+kp[7])*(0.02+f2.x*f2.x)*aa2*0.5*(lpb2.z+256.*lpb2.w)/256. + 3.*( kl[10]*aa2*aa + 0.*aa2*bb2*bb2 - 0.04*(1.+1.*kp[9])*bb2)*f2.x*f2.x; float dda=sin(3.*(1.+kp[2]*(ff.x-1.))*aa*1.57)*kp[15]*0.18*((cu.x/256.+cu.y-cub.x/256.-cub.y)*ff.y + (cv.x/256.+cv.y-cvb.x/256.-cvb.y)*ff.z); float ddb=sin(3.*(1.+kp[3]*(f2.x-1.))*bb*1.57)*kp[16]*0.18*((cu.z/256.+cu.w-cub.z/256.-cub.w)*f2.y + (cv.z/256.+cv.w-cvb.z/256.-cvb.w)*f2.z); float dda2=sin(5.*(1.+kp[2]*(ff.x-1.))*aa2*1.57)*kp[15]*0.18*((cu2.x/256.+cu2.y-cub2.x/256.-cub2.y)*ff.y + (cv2.x/256.+cv2.y-cvb2.x/256.-cvb2.y)*ff.z); float ddb2=sin(5.*(1.+kp[3]*(f2.x-1.))*bb2*1.57)*kp[16]*0.18*((cu2.z/256.+cu2.w-cub2.z/256.-cub2.w)*f2.y + (cv2.z/256.+cv2.w-cvb2.z/256.-cvb2.w)*f2.z); da += tfac*dda; db += tfac*ddb; da2 += tfac*dda2*(1.-dda2); db2 += tfac*ddb2*(1.-ddb2); vec2 dtt = vec2((2.*kl[28]-1.)*sy,sx); da*= (1.+kl[17])*2000.*dtt.x/mult; db*= (1.+kl[17])*2000.*dtt.x/mult; da2*= 800.*dtt.y/mult; db2*= 800.*dtt.y/mult; da+=aa*256.*256.; db+=bb*256.*256.; da2+=aa2*256.*256.; db2+=bb2*256.*256.; float yn = floor(da/256.); // get leading part of da and rescale float xn = (da-yn*256.); float wn = floor(db/256.); float zn = (db-wn*256.); float yn2 = floor(da2/256.); float xn2 = (da2-yn2*256.); float wn2 = floor(db2/256.); float zn2 = (db2-wn2*256.); cout = vec4(xn,yn,zn,wn)/256.; cout2 = vec4(xn2,yn2,zn2,wn2)/256.; uc.x += 10.*ff.y*ff.z*uc.y; cout*= 1.-kl[16]*.2*exp(-100.*(uc.x-.2-.6*kp[16])*(uc.x-.2-.6*kp[16]))-kl[17]*.2*exp(-100.*(uc.x-.2-.6*kp[17])*(uc.x-.2-.6*kp[17]))-kl[18]*.2*exp(-100.*(uc.x-.2-.6*kp[18])*(uc.x-.2-.6*kp[18]))-kl[19]*.2*exp(-100.*(uc.x-.2-.6*kp[19])*(uc.x-.2-.6*kp[19])); }`; var src_colp = header+` const int N = 30; const float Nf =20.; const int Nrand =100; const float Nrandf =100.; const float dn =0.1; const int Nx =512; const float Nxf =512.; const float PI =3.1415926; const int numOctaves = 4; //8; in vec2 u; out vec4 cc; uniform vec2 res; uniform vec2 L; uniform float t; // frame number uniform highp sampler2D img; uniform highp sampler2D img2; uniform highp sampler2D imgp; uniform highp sampler2D img2p; uniform highp sampler2D pal; uniform float rand[Nrand]; uniform vec2 mouse; uniform vec3 dxy; uniform vec3 rc; uniform float kl[N]; vec2 hash2( in vec2 x ) { int ii = int(mod(x.x+res.x*x.y,Nrandf)); //counter into array of random #s int i2 = int(mod(x.y-res.y*x.x,Nrandf)); return vec2(rand[ii],rand[i2]); } float ddot ( in vec2 x, in vec2 y ) { return x.x+y.x + x.y*y.y; } vec3 noise( in vec2 p ) { vec2 i = floor( p ); vec2 f = fract( p ); vec2 u = f*f*f*(f*(f*6.0-15.0)+10.0); vec2 du = 30.0*f*f*(f*(f-2.0)+1.0); vec2 ga = hash2( i + vec2(0.0,0.0) ); vec2 gb = hash2( i + vec2(1.0,0.0) ); vec2 gc = hash2( i + vec2(0.0,1.0) ); vec2 gd = hash2( i + vec2(1.0,1.0) ); float va = ddot( ga, f - vec2(0.0,0.0) ); float vb = ddot( gb, f - vec2(1.0,0.0) ); float vc = ddot( gc, f - vec2(0.0,1.0) ); float vd = ddot( gd, f - vec2(1.0,1.0) ); return vec3( va + u.x*(vb-va) + u.y*(vc-va) + u.x*u.y*(va-vb-vc+vd), // value ga + u.x*(gb-ga) + u.y*(gc-ga) + u.x*u.y*(ga-gb-gc+gd) + // derivatives du * (u.yx*(va-vb-vc+vd) + vec2(vb,vc) - va)); } vec3 fbm( in vec2 x, in float H) { float G = exp(-2.*H); float f = 1.0; float a = 1.0; vec3 t = vec3(0.0); for( int i=0; i<numOctaves; i++ ) { t += a*noise(f*x); f *= 2.0; a *= G; } return t; } vec4 laplacian(in sampler2D img, in vec2 uv, in float dx) { vec2 dt = 1./res; vec4 rg = texture(img, uv + vec2(-1., -1.)*dt)*(0.05+dx); rg += texture(img, uv + vec2(0., -1.)*dt)*(0.2-dx); rg += texture(img, uv + vec2(1., -1.)*dt)*(0.05+dx); rg += texture(img, uv + vec2(-1., 0.)*dt)*(0.2-dx); rg -= texture(img, uv + vec2(0., 0.)*dt); rg += texture(img, uv + vec2(1., 0.)*dt)*(0.2-dx); rg += texture(img, uv + vec2(-1., 1.)*dt)*(0.05+dx); rg += texture(img, uv + vec2(0., 1.)*dt)*(0.2-dx); rg += texture(img, uv + vec2(1., 1.)*dt)*(0.05+dx); return rg; } void main(void) //( out vec4 fragColor, in vec2 fragCoord ) { float lum = rand[45]; float sqr = rand[46]; sqr=1.-rc.z*(1.-sqr); float horiz = rand[48]; float eclipa = rand[67]; float eclipt = rand[68]; float cres = rand[69]; float esc = rand[88]; float x0 = (1.+eclipa*cos(eclipt+t*0.02))/2.; float y0 = (1.+eclipa*sin(eclipt+t*0.02))/2.; float sin1 = rand[42]; vec2 uv = (u+dxy.xy-vec2(0.5))*(1.+dxy.z)+vec2(0.5); // screen space vec2 uc = -rc.xy + u*rc.z; // world space float RR0,r2; if (esc>0.) { vec4 lpo = laplacian(imgp,uc+kl[28]*.5/res,0.); vec2 uc0 = uc + 2.*kl[6]*0.06*lpo.yw; //+dxy.xy-vec2(0.5))*(1.+dxy.z)+vec2(0.5); // mouse in screen space vec2 mmouse = uc0; // + mouse; r2 = (uc.x-uc0.x)*(uc.x-uc0.x)*L.x*L.x+(uc.y-uc0.y)*(uc.y-uc0.y)*L.y*L.y; RR0 = .2*L.y; float lam = sqrt(r2)/RR0; vec2 u2 = uc + (uc-mmouse)*clamp(0.3*1./(1.-lam),-100.,100.); u2 = (u2+rc.xy)/rc.z; uv = (u2+dxy.xy-vec2(0.5))*(1.+dxy.z)+vec2(0.5); // screen space uc = -rc.xy + u2*rc.z; // world space } float fx = .5+(fract(uc.x*res.x)-.5)*1.43; float fy = .5+(fract(uc.y*res.y)-.5)*1.43; fx += horiz*(.5-fx); float fxn = (fx-.5)*.7 + .5; //properly normalized to [0,1] float fyn = (fy-.5)*.7 + .5; float sss = 1.; cc = texture(img,uc); // in [0,1] vec4 cco = texture(imgp,uc); vec4 cc2 = texture(img2,uc); vec4 cco2 = texture(img2p,uc); vec4 ccx = texture(img,uc+1.*vec2(1./res.x,0.)); vec4 ccy = texture(img,uc+1.*vec2(0.,1./res.y)); float aa = (cc.x+256.*cc.y)/256.; float bb = (cc.z+256.*cc.w)/256.; float aao = (cco.x+256.*cco.y)/256.; float bbo = (cco.z+256.*cco.w)/256.; float aa2 = (cc2.x+256.*cc2.y)/256.; float bb2 = (cc2.z+256.*cc2.w)/256.; float hyp = sqrt(.01 + (ccx.z/256.+ccx.w-bb)*(ccx.z/256.+ccx.w-bb) + (ccy.z/256.+ccy.w-bb)*(ccy.z/256.+ccy.w-bb)); float ct = (ccx.z/256.+ccx.w-bb)/hyp; float st = (ccy.z/256.+ccy.w-bb)/hyp; float fx2 = x0+(fx-x0)*ct+(fy-y0)*st; float fy2 = y0-(fx-x0)*st+(fy-y0)*ct; float r22 = (fx2-x0)*(fx2-x0)+(fy2-y0)*(fy2-y0)-0.2; float rxmy = abs((fx-.5)*ct+(fy-.5)*st)-0.1;//*ff.x; hyp = sqrt(.01 + (ccx.z/256.+ccx.w-bbo)*(ccx.z/256.+ccx.w-bbo) + (ccy.z/256.+ccy.w-bbo)*(ccy.z/256.+ccy.w-bbo)); float cto = (ccx.z/256.+ccx.w-bbo)/hyp; float sto = (ccy.z/256.+ccy.w-bbo)/hyp; float rx = abs(fx-x0); float ry = abs(fy-y0); vec2 dx = floor(3.*vec2(kl[22],kl[23]))/res; vec4 ccu = texture(img,uc+dx); vec4 ccd = texture(img,uc-dx); float rxn = abs(fxn-.5); float ryn = abs(fyn-.5); // add curvature vec2 duc = 3.*(1.-rand[45])*(1.-rand[46])*vec2((kl[21]-.5)*fxn*(1.-fxn)*((fyn-.5)*(fyn-.5)), (kl[22]-.5)*fyn*(1.-fyn)*((fxn-.5)*(fxn-.5))); uc+=duc/res; vec2 uc2 = uc; uc2.x*=1.+sin1*(40.*kl[14]-1.); uc2.y*=1.+(1.-sin1)*(40.*kl[15]-1.); vec3 ff = .5*fbm(-(.3+.4*kl[11])*uc2+kl[16]+t/16.*vec2(kl[16]-.5,kl[17]-.5)+fbm((.3+.5*kl[12])*uc2,.7).yz,0.5); vec3 f2 = fbm(uc2+fbm(-0.6*uc2,0.7).yz,0.5); r2 = 1.1*sqrt((fx-.5)*(fx-.5)+(fy-.5)*(fy-.5))-.42*(1.-(1.-lum)*(1.-horiz)*(.2-.3*aa*aa)); float drr = clamp((min(abs(rx-rx),abs(rx+ry))-.1*ff.x)*20.,0.,1.); // rounded squares float drrmix = clamp(mix(1.-aa-ff.y-bb,3.*(bb+aa-ff.x),rand[40]),0.,1.); drrmix*=4.*(1.-drrmix); drr += .7*(1.-drr); vec4 lp = laplacian(img,uc,0.9*ff.x*aa); vec4 lp2= laplacian(img2,uc,0.9*ff.x*aa2); aao=0.12*(lp.x+lp.y*256.); bbo=0.12*(lp.z+lp.w*256.); float aao2=0.12*(lp2[0]+lp2[1]*256.); float bbo2=0.12*(lp2[2]+lp2[3]*256.); ff.z *= 1. + 3.*uc.x*(1.-uc.x); ff.y *= 1. + 3.*uc.x*(1.-uc.x); float px = 20.*bb*aa+1.4*(aa)*ff.x+1.4*(bb)*f2.x; float pxo = 20.*bbo*aao+1.4*(aao)*ff.x+1.4*(bbo)*f2.x; vec4 cc_hsl = texture(pal,vec2(5.*px*px,kl[5]*uc.y+ff.z*bb)); vec4 cco_hsl = texture(pal,vec2(5.*pxo*pxo,kl[5]*uc.y+ff.z*bbo)); vec4 cc2_hsl = texture(pal,vec2(1.-2.*bb2*aa2-0.4*(aa2)*ff.x-0.4*(bb2)*f2.x,1.-ff.y*bb)); vec4 cco2_hsl = texture(pal,vec2(1.-2.*bbo2*aao2-0.4*(aao2)*ff.x-0.4*(bbo2)*f2.x,1.-ff.y*bbo)); cc_hsl.z = pow(cc_hsl.z,1.7); cco_hsl.z = pow(cco_hsl.z,1.4); cc_hsl.rgb -= (.1+.7*kl[13])*(cc_hsl.rgb-cco_hsl.rgb); cc_hsl.x += .15*drrmix; cc_hsl.x *= 1.+(cc_hsl.x-1.)*kl[7]; // colour modulation cc_hsl.x += 0.1*((fx-.5)*aa2+(fy-.5)*bb2); cc_hsl.x = fract(cc_hsl.x); cc_hsl.z *= 0.9+3.*bb+kl[4]*aa*aa2+kl[2]*bb2/(1.+bb2)+kl[3]*aa*bb; // multiply lightness by particle number cc_hsl.y *= (1.15-.1*ff.x*ff.x*bb); //*(1.-f2.x*f2.x); // multiply sat by 1-particle number cc_hsl.y = pow(cc_hsl.y,.7); cc_hsl.z*=1.4 - 0.3*rand[45]-2.*kl[4]*uc.x*(2.-3.*uc.x)*(x0-rx)*(y0-ry); cc_hsl=clamp(cc_hsl,0.01,1.); // hsl to rgb: vec3 rgb = clamp( abs(mod(cc_hsl.x*6.0+vec3(0.0,4.0,2.0),6.0)-3.0)-1.0, 0.0, 1.0 ); rgb = cc_hsl.z + cc_hsl.y * (rgb-0.5)*(1.0-abs(2.0*cc_hsl.z-1.0)); cc = vec4(pow(rgb.r,(kl[9]-.1*lum-.4*bbo2)*.6),pow(rgb.g,(kl[11]-.1*lum-.3*aao2)*.6),pow(rgb.b,(kl[10]-.1*lum-.1*aa*bb)*.6),1.); cc.rgb=clamp(cc.rgb,0.01,1.); cc.rgb *= cc.rgb*(3.-2.*cc.rgb); cc.rgb *= .6+.4*cc.rgb*(3.-2.*cc.rgb); cc.xyz*=exp(-.3*abs(st*cto-sto*ct)); vec4 ccoo = vec4(cc.bgr,1.); cc = mix(cc,ccoo,clamp(20.*(0.1+0.3*ff.x*ff.x)*0.03*(aao*aao*bbo*bbo),0.001,0.99)); r2 += lum*((2.*kl[7]-1.)*r2*r2*r2-r2); // very trippy r2 *= 1.+rand[46]*(r2-1.); // round squares r2+=1.; r2*= 4.*r2*r2-6.*r2+3.; r2-=1.3; cc.rgb = 1.-cc.rgb; // = kl[19]*(1.-cc.rgb) + (1.-kl[19])*cc.rgb; drr *= (1.-rand[47]) + rand[47]*r2*.5; // rand[47] = rcorr vec3 cc_bg = vec3(rand[39],rand[40],rand[41]); cc_bg *= 1.-.05*drr*(rx+ry-.67+.3*f2.y)*(1.+cc.rgb)*(1.+lum); cc_bg *= .7+.3*sqrt(rc.z); //rc.z; aa = sin(10.*fx*aao*kl[27]); bb = sin(10.*fy*bbo*kl[28]); fx2 += kl[3]*(fx-fx2); fy2 += kl[4]*(fy-fy2); RR0 = .8-kl[2]*.4; //.7; //.95/2.; float rfac = 1. + (kl[29]-.5)*(-.2+.4*clamp(0.5+(1.-2.*cres)*(RR0*RR0-(fx2-aa*x0)*(fx2-aa*x0)-(fy2-bb*y0)*(fy2-bb*y0))/(0.01*0.05*(1.+9.*eclipa/0.02)), .5-.25*cres, 1.)); cc.r *= rfac*(1.-2.*kl[19])+2.*kl[19]; cc.g *= kl[19] + rfac*(1.-kl[19]); cc.b *= rfac; cc.rgb = mix(cc.rgb, cc_bg, clamp(clamp(1.-rc.z,.6,1.)*drr*r2,-0.5,1.)); //.-r2)); // glow: cc.rgb *= 1.+0.2*(1.-lum)*(1.-sqr)*(-0.7+pow(max(.32,(fxn-.5)*(fxn-.5)+(fyn-.5)*(fyn-.5)),2.)); cc=clamp(cc,0.001,.999); }`;
cathedral study is a series of experimental, generative, living paintings. Continually evolving pixelated landscapes evoke ruins, fantastical cityscapes, and cathedrals. Best viewed running in real-time on a large screen. Press ‘f’ to cycle through full-screen options.
function vecscl(e,l){let r=[];for(let a=0;a<e.length;a++)r[a]=e[a]*l;return r}function clamp(e){return Math.max(0,Math.min(1,e))}function dot2(e,l){return e[0]*l[0]+e[1]*l[1]}function unit(e){return vecscl(e,1/norm3(e))}function norm3(e){return Math.sqrt(e[0]*e[0]+e[1]*e[1]+e[2]*e[2])}let C,D,body,gl,Shader,simp,colp,pap,vs,fs,Lx,Ly,Nx,Ny;GET.hash&&(tokenData.hash=GET.hash),R=new Random,document.body.style.backgroundColor="#030303",console.log("cathedral study by Eric De Giuli"),C=({body:body}=D=document).createElement("canvas"),body.appendChild(C),gl=C.getContext("webgl2"),"drawingBufferColorSpace"in gl&&(gl.drawingBufferColorSpace="display-p3"),Shader=(e,l)=>{const r=gl.createShader(e);return gl.shaderSource(r,l),gl.compileShader(r),gl.getShaderParameter(r,gl.COMPILE_STATUS)||(console.error(`Error compiling ${e===gl.VERTEX_SHADER?"vertex":"fragment"} shader "${l}":`),console.log(gl.getShaderInfoLog(r))),r};let pal,pj,inv,hgt=rnd(),Nm=hgt<.15?60:hgt<.4?120:hgt<.8?240:hgt<.93?360:512;GET.N&&(Nm=GET.N),innerWidth>innerHeight?(Ny=Nm,Nx=Math.floor(Nm*innerWidth/innerHeight)):(Nx=Nm,Ny=Math.floor(Nm*innerHeight/innerWidth));let palp=[16,3,10,7,4,0,10,13,10,13,1,1,1,2,7,12];palp=vecscl(palp,1/110);let cumpal=[];cumpal[0]=0;for(let e=1;e<palp.length;e++)cumpal[e]=cumpal[e-1]+palp[e-1];let st=1;pj=1;let palr=rnd();for(;st<palp.length&&cumpal[st]<palr;)st++;st--;let mm,nn,ri,zh,zh2,zh3,zr,a,ct,dc,archdepth,night,rlight,wf0,rain,st0,scalefac,infrac,Pcir,lgfac,famp,kkx,kky,hx,lo,sparkle,speckle,skeleton,bubbly,wobble,narch,y0,stt,rr0,nt,refl,dt,phase,clarity,gfac,kgx,kgy,melt,wild,eye,sphsh,a1,a2,xe0,ye0,ze0,kz,kx,ky,om,ox,oy,col,c1,s1,c2,s2,xe,ye,ze,pj2=0;switch(inv=0,st){case 0:pj=6,pj2=7;break;case 1:pj=11,pj2=7;break;case 2:pj=1,pj2=5;break;case 3:pj=1,pj2=0;break;case 4:pj=3,pj2=9;break;case 5:pj=6,pj2=0;break;case 6:pj=5,pj2=7;break;case 7:pj=11,pj2=5;break;case 8:pj=11,pj2=4;break;case 9:pj=11,pj2=0;break;case 10:pj=0,pj2=0,inv=1;break;case 11:pj=3,pj2=3,inv=1;break;case 12:pj=2,pj2=0;break;case 13:pj=2,pj2=10;break;case 14:pj=10,pj2=8;break;case 15:pj=10,pj2=4}pal=new Uint8Array(80);for(let e=0;e<11;e++)for(let l=0;l<2;l++){let r=0==l?pj:pj2,a=Math.min(e,pals[r].length-1);pal[3*e+30*l]=pals[r][a][0],pal[3*e+30*l+1]=pals[r][a][1],pal[3*e+30*l+2]=pals[r][a][2],inv&&(pal[3*e+30*l]=(pal[3*e+30*l]+180)%360)}let rndth=-PI/4+PI/2*rnd();c1=Math.cos(rndth),s1=Math.sin(rndth),c2=-.7,s2=.7,ze0=-(.8+1.5*rnd()),xe0=.05*(2*rnd()-1),ye0=-1/4,kz=1,rnd()<.1&&(kz=2),kx=1,rnd()<.1&&(kx=2),ky=1,rnd()<.1&&(ky=2);let azz=Math.floor(Math.exp(rnd()*Math.log(.95/.1)));azz>=4&&azz<=6&&(azz=1),hx=360*rnd(),sparkle=0,rnd()<.5&&(sparkle=1),lo=0,rnd()<.4&&(lo=1),speckle=0,famp=3*rnd(),rnd()<.4&&(famp=0),kkx=6*rnd(),kky=6*rnd(),rr0=.6,stt=0,lo=1,eye=0,skeleton=0,bubbly=1+Math.floor(4*rnd()),rnd<.1&&(bubbly=0),refl=1,rnd()<.3&&(refl=0),refl&&(rr0*=.9),inv=0,rnd()<.2&&(inv=1),rnd()<.7&&(wobble=1),azz<7&&(wobble=0),phase=0,rnd()<.6&&(phase=-PI/3+PI/6*rnd()),dt=.1+1.2*rnd(),clarity=0,rnd()<.5&&(clarity=.7*rnd()),kgx=5+7*rnd(),kgy=5+7*rnd(),gfac=.5+rnd(),Nrad0*=gfac,melt=0,rnd()<.4&&azz>5&&(melt=1),wild=1,rnd()<.2&&(wild=0),a1=rnd(),a2=rnd();let miny=1,maxy=-1,v2=[];ze=ze0,xe=xe0,ye=ye0,stt=1,rnd()<.7&&(stt=2),st0=stt,sparkle=0;let gothic=rnd()<.3?1:0;refl=0,rnd()<.8&&(refl=1),rain=0,(rnd()<.3||gothic)&&(rain=rnd()),lo&&(Nrad0*=.7);let Nc=5*gothic+6+Math.floor(10*rnd()),Nb=Math.floor(Nc/2+3*Nc*rnd());dc=.008;let colht=8-4*gothic;ct=1.5*dc;let locrnd=rnd()<.3?0:rnd();a=[];for(let e=0;e<Nc;e++){let l=[];l.x=[],l.y=[],l.z=[],l.vx=[],l.vy=[],l.vz=[],l.x[0]=.07+.85*(e/Nc+.1*locrnd*rnd()),l.z[0]=.2*rnd(),l.y[0]=0,l.vx[0]=0,l.vy[0]=1,l.vz[0]=0;for(let e=1;e<colht+1;e++)l.x[e]=l.x[0],l.y[e]=l.y[0]+dc*e,l.z[e]=l.z[0],l.vx[e]=0,l.vy[e]=1,l.vz[e]=0;l.arch=0,l.maxy=l.y[colht-1]+dc,l.maxx=l.x[colht-1],l.maxz=l.z[0],l.open=1,a.push(l)}narch=0;let nopen=Nc;for(;narch<Nb&&nopen>2;){let e=Math.floor(rnd()*a.length),l=Math.floor(rnd()*a.length);if(e!=l&&1==a[e].open&&1==a[l].open){a[e].open=0,a[l].open=0,nopen-=2;let r=a[e].maxy,t=a[l].maxy;r>t&&([e,l]=[l,e]),r=a[e].maxy,t=a[l].maxy;let c=a[e].maxx,o=a[l].maxx,n=a[e].maxz,g=a[l].maxz,i=[];i.x=[],i.y=[],i.z=[];let d=1+Math.floor((t-r)/dc+1e-4);a[e].arch;i.vx=[],i.vy=[],i.vz=[];for(let l=0;l<d;l++)i.x[l]=a[e].maxx,i.y[l]=a[e].maxy+(t-r)*l/d,i.z[l]=n,i.vx[l]=0,i.vy[l]=1,i.vz[l]=0;let p=Math.abs(o-c)/2,x=Math.max(6,1.2*PI*(p-dc)/dc),s=PI/(x-1),f=0;c<o&&(f=PI,s*=-1),y0=d>0?i.y[d-1]:a[e].maxy;for(let e=0;e<x;e++){gothic?(i.x[d+e]=(a1*c+(1-a1)*o)/2+1.1*(a1*c-(1-a1)*o)/2+1.1*(e+.5)/x*((1-a1)*o-a1*c),i.y[d+e]=y0+3*p*Math.max(0,(.5-Math.abs(e/x-.5))*(.5-Math.abs(e/x-.5)))):(i.x[d+e]=(c+o)/2+p*Math.cos(f+s*(e+1)),i.y[d+e]=y0+Math.max(0,p*Math.sin(f+s*(e+1)))),i.z[d+e]=n+(g-n)*(e+1)/x;let l=unit([Math.cos(f+s*(e+1))-Math.cos(f+s*e),Math.sin(f+s*(e+1))-Math.sin(f+s*e),0]);i.vx[d+e]=l[0],i.vy[d+e]=l[1],i.vz[d+e]=l[2]}i.maxx=(c+o)/2,i.maxy=t+p+ct/2,i.maxz=(n+g)/2,i.arch=Math.sign(o-c),i.open=1,nopen++,a.push(i),narch++}}let Nfinal=a.length,sortr=rnd();sortr>.1&&a.sort((function(e,l){return sortr<.8?parseFloat(l.maxz)-parseFloat(e.maxz):parseFloat(l.maxy)-parseFloat(e.maxy)})),maxy=0;for(let e=0;e<Nfinal;e++)maxy=Math.max(maxy,a[e].maxy);scalefac=.7/(maxy-0),ox=.5-xe0,oy=.5-ye0,oy=.93,rlight=[4*rnd()-2,4*rnd()-2,4*rnd()-2],night=0,rnd()<.3&&(night=1),(6==st||7==st||15==st)&&(night=0),wf0=.7*Math.exp(.3*rnd()),ze=ze0+.2,xe=.5+.2*rnd()-.1,ye=0,Pcir=.05+.04*Math.exp(rnd()),lgfac=rnd();let kp,km,kl,rand,aa=[],ax=[],ay=[],az=[],vx=[],vy=[],vz=[];for(let e=0;e<Nfinal;e++)for(ax.push(...a[e].x),ay.push(...a[e].y),az.push(...a[e].z),vx.push(...a[e].vx),vy.push(...a[e].vy),vz.push(...a[e].vz);ax.length>LL;){let e=[];e.x=ax.slice(0,LL),e.y=ay.slice(0,LL),e.z=az.slice(0,LL),e.vx=vx.slice(0,LL),e.vy=vy.slice(0,LL),e.vz=vz.slice(0,LL),aa.push(e),ax=ax.slice(LL),ay=ay.slice(LL),az=az.slice(LL),vx=vx.slice(LL),vy=vy.slice(LL),vz=vz.slice(LL)}Nfinal=aa.length,ax=[],ay=[],az=[],vx=[],vy=[],vz=[],rand=[];for(let e=0;e<Nrand;e++)rand[e]=rnd();let kl0=.001;switch(kp=new Float32Array(N),km=new Float32Array(N),kl=new Float32Array(N),kl[0]=c1,kl[1]=s1,kl[2]=xe,kl[3]=ye,kl[4]=ze,kl[6]=Nrad0,kl[7]=clarity,kl[8]=wf0,kl[9]=rr0,kl[10]=lgfac,kl[11]=wild,kl[12]=rlight[0],kl[13]=rlight[1],kl[14]=rlight[2],kl[15]=inv,kl[16]=night,kl[17]=lo,kl[18]=phase,kl[19]=rain,kl[20]=famp,kl[21]=kkx,kl[22]=kky,kl[23]=scalefac,kl[24]=ox,kl[25]=oy,st){case 0:kp=[.66,.95,.94,.037,.89,.26,.9,.94,.65,.76,.54,.11,.5,.66,.96,.74,.91,.33,.15,.85];break;case 1:kp=[.97,.01,.89,.08,.78,.98,.16,.8,.53,.91,.4,.54,.84,.44,.14,.75,.45,.33,.47,.95];break;case 2:kp=[.72,.85,.51,.08,.98,.29,.91,.19,.69,.24,.99,.32,.84,.03,.97,.14,.09,.04,.08,.26];break;case 3:kp=[.14,.95,.24,.09,.05,.18,.96,.04,.47,.18,.13,.38,.21,.85,.66,.05,.15,.23,.25,.48];break;case 4:kp=[.58,.02,.03,.84,.43,.4,.95,.76,.15,.55,.04,.49,.49,.55,.52,.07,.22,.16,.31,.37];break;case 5:kp=[.21,.1,.21,.13,.07,.42,.26,.77,.28,.67,.79,.1,.28,.2,.04,.21,.35,.125,.75,.87];break;case 6:kp=[.4,.28,.88,.36,.92,.96,.79,.24,.99,.73,.68,.03,.09,.52,.11,.29,.95,.01,.01,.62];break;case 7:kp=[.1,.27,.31,.05,.4,.24,.67,0,.02,.92,.75,.11,.4,.55,.97,.45,.12,.15,.54,.56];break;case 8:kp=[.17,.81,.64,.19,.52,.27,.59,.11,.65,.87,.36,.17,.66,.1,.95,.08,.5,.43,.92,.13];break;case 9:kp=[.59,.56,.03,.14,.58,.05,.8,0,.09,.75,.8,.55,.07,.27,.46,.08,.35,.01,.17,.63];break;case 10:kp=[.021,.68,.2,.04,.46,.4,.3,.76,.19,.2,.78,.5,.1,.58,.61,.13,.25,.39,.63,.38];break;case 11:kp=[.11,.18,.02,.15,.49,.9,.73,.77,.69,.93,.95,.76,.78,.32,.13,.7,.07,.04,.3,.76];break;case 12:kp=[.15,.27,.17,.11,.61,.44,.65,.21,.82,.79,.4,.33,.43,.22,.02,.07,.5,.13,.95,.34];break;case 13:kp=[.89,.46,.48,.3,.38,.18,.13,.68,.2,.87,.92,.56,.06,.25,.32,.1,.05,.11,.31,.55];break;case 14:kp=[.9,.025,.064,.439,.208,.154,.261,.085,.268,.917,.78,.709,.087,.068,.684,.057,.48,.282,.174,.819];break;case 15:kp=[.81,.79,.38,.8,.19,.22,.39,.047,.82,.98,.9,.28,.12,.24,.12,.69,.62,.2,.99,.71]}kp[4]=Math.exp(rnd()-1)-Math.exp(-1),kp[5]=Math.exp(rnd()-1)-Math.exp(-1);for(let e=0;e<N;e++)km[e]=rnd();function setrand(){rand[37]=km[0],rand[38]=kp[4],rand[39]=km[2],rand[40]=km[3],rand[41]=km[4],rand[42]=km[5],rand[43]=km[6],rand[44]=km[7]}km[0]<.15&&10!=st&&3!=st&&1!=st&&(kp[15]=.69,kp[16]=1.34),setrand();let nx=2+Math.floor(8*rnd()),ny=2+Math.floor(8*rnd()),rr=rnd(),n4=Math.floor(Math.exp(4*rnd()));const tex0=new Uint8Array(Nx*Ny*4);let th,loc_a,loc_L,loc_ac,loc_img,loc_img00,loc_res,loc_t,loc_rand,loc_pal,loc_kp,loc_km,loc_kl,loc_kv,loc_kw,loc_imgc,loc_imgc2,loc_resc,loc_Lc,loc_tc,loc_randc,loc_aavg,loc_bavg,loc_dxy,loc_dxyc,loc_rc,loc_rcc,loc_ax,loc_ay,loc_az,loc_v,loc_klc,loc_kpc,loc_palc,loc_img00c,loc_resp,loc_imgp,loc_randp,loc_kpp,loc_ap,loc_Lp;for(let e=0;e<Nx;e++)for(let l=0;l<Ny;l++){let r=e+Nx*l,a=.1+(.4+.5*a2)*rr;tex0[4*r]=Math.floor(255*rnd()*a),tex0[4*r+1]=Math.floor(255*rnd()*(1-a)),tex0[4*r+2]=Math.floor(255*rnd()*(1-a)),tex0[4*r+3]=255}function thrower(e){if(!gl.getProgramParameter(e,gl.LINK_STATUS))throw console.log(`Link failed:\n${gl.getProgramInfoLog(e)}`),console.log(`VS LOG:\n${gl.getShaderInfoLog(vs)}`),console.log(`FS LOG:\n${gl.getShaderInfoLog(fs)}`),"AARG DED"}function gul(e,l){return gl.getUniformLocation(e,l)}dzc=0,dzp=dzc,simp=gl.createProgram(),vs=Shader(gl.VERTEX_SHADER,src_vert),fs=Shader(gl.FRAGMENT_SHADER,src_simp),gl.attachShader(simp,vs),gl.attachShader(simp,fs),gl.linkProgram(simp),gl.useProgram(simp),thrower(simp),loc_res=gul(simp,"res"),loc_L=gul(simp,"L"),loc_t=gul(simp,"t"),loc_img=gul(simp,"img"),loc_img00=gul(simp,"img00"),loc_kp=gul(simp,"kp"),loc_rand=gul(simp,"rand"),loc_dxy=gul(simp,"dxy"),loc_rc=gul(simp,"rc"),gl.uniform1i(loc_img,0),gl.uniform1i(loc_img00,1),loc_a=gl.getAttribLocation(simp,"a"),gl.activeTexture(gl.TEXTURE0),gl.vertexAttribPointer(loc_a,2,gl.FLOAT,!1,0,0),gl.enableVertexAttribArray(loc_a),pap=gl.createProgram(),vs=Shader(gl.VERTEX_SHADER,src_vert),fs=Shader(gl.FRAGMENT_SHADER,src_pap),gl.attachShader(pap,vs),gl.attachShader(pap,fs),gl.linkProgram(pap),gl.useProgram(pap),thrower(pap),loc_Lp=gul(pap,"L"),loc_imgp=gul(pap,"img"),loc_randp=gul(pap,"rand"),loc_kl=gul(pap,"kl"),loc_ax=gul(pap,"ax"),loc_ay=gul(pap,"ay"),loc_az=gul(pap,"az"),loc_v=gul(pap,"v"),gl.uniform1i(loc_imgp,0),gl.bindBuffer(gl.ARRAY_BUFFER,gl.createBuffer()),gl.bufferData(gl.ARRAY_BUFFER,new Float32Array([-1,1,1,1,1,-1,-1,1,1,-1,-1,-1]),gl.STATIC_DRAW),loc_ap=gl.getAttribLocation(pap,"a"),gl.activeTexture(gl.TEXTURE0),gl.vertexAttribPointer(loc_ap,2,gl.FLOAT,!1,0,0),gl.enableVertexAttribArray(loc_ap),colp=gl.createProgram(),vs=Shader(gl.VERTEX_SHADER,src_vert),fs=Shader(gl.FRAGMENT_SHADER,src_colp),gl.attachShader(colp,vs),gl.attachShader(colp,fs),gl.linkProgram(colp),gl.useProgram(colp),thrower(colp),loc_imgc=gul(colp,"img"),loc_imgc2=gul(colp,"img2"),loc_img00c=gul(colp,"img00"),loc_palc=gul(colp,"pal"),loc_resc=gul(colp,"res"),loc_Lc=gul(colp,"L"),loc_tc=gul(colp,"t"),loc_randc=gul(colp,"rand"),loc_dxyc=gul(colp,"dxy"),loc_rcc=gul(colp,"rc"),loc_klc=gul(colp,"kl"),gl.bindBuffer(gl.ARRAY_BUFFER,gl.createBuffer()),gl.bufferData(gl.ARRAY_BUFFER,new Float32Array([-1,1,1,1,1,-1,-1,1,1,-1,-1,-1]),gl.STATIC_DRAW),gl.uniform1i(loc_imgc,0),gl.uniform1i(loc_imgc2,1),gl.uniform1i(loc_palc,2),gl.uniform1i(loc_img00c,3),loc_ac=gl.getAttribLocation(colp,"a"),gl.activeTexture(gl.TEXTURE0),gl.vertexAttribPointer(loc_ac,2,gl.FLOAT,!1,0,0),gl.enableVertexAttribArray(loc_ac);let M=1,f1=0;var isMobile=window.matchMedia("(hover: none)").matches;function resize_render(){let e=innerWidth,l=innerHeight,r=devicePixelRatio;C.width=M*e*r|0,C.height=M*l*r|0,head||0==f1?(Lx=2*Math.floor(.97*C.width/2),Ly=2*Math.floor(C.height/2-.015*C.width)):(C.requestFullscreen(),Lx=C.width,Ly=C.height),C.style.width=e+"px",C.style.height=l+"px",gl.viewport((C.width-Lx)/2,(C.height-Ly)/2,Lx,Ly),render()}function texset(e=gl.CLAMP_TO_EDGE,l=gl.NEAREST){gl.texParameteri(gl.TEXTURE_2D,gl.TEXTURE_WRAP_S,e),gl.texParameteri(gl.TEXTURE_2D,gl.TEXTURE_WRAP_T,e),gl.texParameteri(gl.TEXTURE_2D,gl.TEXTURE_MIN_FILTER,l),gl.texParameteri(gl.TEXTURE_2D,gl.TEXTURE_MAG_FILTER,l)}let tex00,tex02,texA,texB,texC,fbA,fbB,fb00,fb02;tex00=gl.createTexture(),gl.bindTexture(gl.TEXTURE_2D,tex00),gl.texImage2D(gl.TEXTURE_2D,0,gl.RGBA,Nx,Ny,0,gl.RGBA,gl.UNSIGNED_BYTE,null),texset(),fb00=gl.createFramebuffer(),gl.bindFramebuffer(gl.FRAMEBUFFER,fb00),gl.framebufferTexture2D(gl.FRAMEBUFFER,gl.COLOR_ATTACHMENT0,gl.TEXTURE_2D,tex00,0),tex02=gl.createTexture(),gl.bindTexture(gl.TEXTURE_2D,tex02),gl.texImage2D(gl.TEXTURE_2D,0,gl.RGBA,Nx,Ny,0,gl.RGBA,gl.UNSIGNED_BYTE,null),texset(),fb02=gl.createFramebuffer(),gl.bindFramebuffer(gl.FRAMEBUFFER,fb02),gl.framebufferTexture2D(gl.FRAMEBUFFER,gl.COLOR_ATTACHMENT0,gl.TEXTURE_2D,tex02,0),texA=gl.createTexture(),gl.bindTexture(gl.TEXTURE_2D,texA),gl.texImage2D(gl.TEXTURE_2D,0,gl.RGBA,Nx,Ny,0,gl.RGBA,gl.UNSIGNED_BYTE,tex0.subarray(0,Nx*Ny*4)),texset(),fbA=gl.createFramebuffer(),gl.bindFramebuffer(gl.FRAMEBUFFER,fbA),gl.framebufferTexture2D(gl.FRAMEBUFFER,gl.COLOR_ATTACHMENT0,gl.TEXTURE_2D,texA,0),texB=gl.createTexture(),gl.bindTexture(gl.TEXTURE_2D,texB),gl.texImage2D(gl.TEXTURE_2D,0,gl.RGBA,Nx,Ny,0,gl.RGBA,gl.UNSIGNED_BYTE,null),texset(),fbB=gl.createFramebuffer(),gl.bindFramebuffer(gl.FRAMEBUFFER,fbB),gl.framebufferTexture2D(gl.FRAMEBUFFER,gl.COLOR_ATTACHMENT0,gl.TEXTURE_2D,texB,0),texC=gl.createTexture(),gl.bindTexture(gl.TEXTURE_2D,texC),gl.texImage2D(gl.TEXTURE_2D,0,gl.RGB,10,2,0,gl.RGB,gl.UNSIGNED_BYTE,pal),texset(gl.REPEAT,gl.LINEAR),gl.useProgram(simp),gl.uniform1fv(loc_rand,rand),gl.uniform1fv(loc_kp,kp),gl.useProgram(pap),gl.uniform1fv(loc_randp,rand),gl.uniform1fv(loc_kl,kl),gl.useProgram(colp),gl.uniform1fv(loc_randc,rand),gl.uniform1fv(loc_klc,kl);let time,prevt=performance.now(),dtime=20,dtt=1,running=!0,periodic=0,anim=0,flip=0,count=0,dxycount=0,TT=120*(5-2*night),om0=.01,A=.002,time0=prevt,ai=0,AA=[],tik=0;function render(){if(running){if(time=performance.now(),time-prevt>dtime){tik%E==0&&(ai==Nfinal&&(ai=0),AA=[],AA=aa[ai],ai++,ax=AA.x,ay=AA.y,az=AA.z,vx=AA.vx,vy=AA.vy,vz=AA.vz,count++,tik=0),gl.viewport(0,0,Nx,Ny),gl.useProgram(pap),gl.uniform2f(loc_Lp,Lx,Ly),gl.uniform1fv(loc_randp,rand),gl.uniform1fv(loc_ax,ax),gl.uniform1fv(loc_ay,ay),gl.uniform1fv(loc_az,az),gl.uniform3fv(loc_v,[vx[0],vy[0],vz[0]]),kl[4]=ze*(1+.5*Math.cos(time/1e3)),kl[5]=LL,kl[26]=rnd(),kl[27]=kp[18],kl[27]=(time-prevt)/1e3*10,kl[28]=kp[19],kl[28]=tik/(E+1)*(1-tik/(E+1))*2,kl[29]=count/TT,gl.uniform1fv(loc_kl,kl);for(let e=0;e<2;e++)flip=!flip,gl.bindFramebuffer(gl.FRAMEBUFFER,flip?fb02:fb00),gl.activeTexture(gl.TEXTURE0),gl.bindTexture(gl.TEXTURE_2D,flip?tex00:tex02),gl.drawArrays(gl.TRIANGLES,0,6);if(gl.viewport(0,0,Nx,Ny),gl.useProgram(simp),tik++,count%TT==0){count=0;for(let e=0;e<Nrand;e++)rand[e]=.7*rnd()+.3*rand[e];setrand(),gl.uniform1fv(loc_rand,rand)}if(0==dxycount){dx=dxc-dxp,dy=dyc-dyp,dz=dzc-dzp,zc*=1+2*dz,xc-=(.5+(2*dx-.5)*(1+2*dz))*zc,yc-=(.5+(2*dy-.5)*(1+2*dz))*zc,kp[0]+=dx/3,kp[1]+=dy/3;let e=count/TT*2;e<1?(kp[18]=6*e*(1-e)*Math.exp(-e),kp[19]=0):(e-=1,kp[18]=0,kp[19]=6*e*(1-e)*Math.exp(-e)),kp[4]=dtt*(1-count/TT)*(1-count/TT),kp[15]*=Math.exp(dx/3),kp[16]*=Math.exp(dy/3)}gl.uniform1fv(loc_kp,kp),0==dx&&0==dy&&0==dz||dxycount++,gl.uniform3fv(loc_dxy,[dx,dy,dz]),gl.uniform3fv(loc_rc,[xc,yc,zc]),gl.uniform1f(loc_t,time),gl.uniform2f(loc_L,Lx,Ly),gl.uniform2f(loc_res,Nx,Ny);for(let e=0;e<2;e++)flip=!flip,gl.bindFramebuffer(gl.FRAMEBUFFER,flip?fbB:fbA),gl.activeTexture(gl.TEXTURE0),gl.bindTexture(gl.TEXTURE_2D,flip?texA:texB),gl.activeTexture(gl.TEXTURE1),gl.bindTexture(gl.TEXTURE_2D,tex00),gl.drawArrays(gl.TRIANGLES,0,6);gl.viewport((C.width-Lx)/2,(C.height-Ly)/2,Lx,Ly),gl.useProgram(colp),gl.uniform1f(loc_tc,time),gl.uniform2f(loc_Lc,Lx,Ly),gl.uniform2f(loc_resc,Nx,Ny),gl.uniform3fv(loc_dxyc,[dx,dy,dz]),gl.uniform3fv(loc_rcc,[xc,yc,zc]),dxycount>=1&&(dxycount=0,dx=0,dy=0,dz=0,dxp=dxc,dyp=dyc,dzp=dzc),gl.bindFramebuffer(gl.FRAMEBUFFER,null),gl.activeTexture(gl.TEXTURE0),gl.bindTexture(gl.TEXTURE_2D,flip?texB:texA),gl.activeTexture(gl.TEXTURE1),gl.bindTexture(gl.TEXTURE_2D,flip?texA:texB),gl.activeTexture(gl.TEXTURE2),gl.bindTexture(gl.TEXTURE_2D,texC),gl.activeTexture(gl.TEXTURE3),gl.bindTexture(gl.TEXTURE_2D,tex00),0==dz&&gl.drawArrays(gl.TRIANGLES,0,6)}prevt=time-(time-prevt)%dtime}if(1==savescr&&(savescr=2,render()),2==savescr){savescr=0;var e=document.createElement("canvas");e.width=Lx,e.height=Ly;var l=e.getContext("2d");l.setTransform(1,0,0,-1,0,gl.height),l.drawImage(C,-(C.width-Lx)/2,-(C.height-Ly)/2),e.toBlob((e=>{saveBlob(e,`cathedral_study-${tokenData.tokenId}.png`)}))}requestAnimationFrame(render)}const saveBlob=function(){const e=document.createElement("a");return document.body.appendChild(e),e.style.display="none",function(l,r){const a=window.URL.createObjectURL(l);e.href=a,e.download=r,e.click()}}();let tid=0,savescr=0;onkeyup=e=>(" "==e.key&&(running=!running),window!==window.parent?(65==e.keyCode&&(dxc-=.01),68==e.keyCode&&(dxc+=.01),87==e.keyCode&&(dyc+=.01),83==e.keyCode&&(dyc-=.01)):(37==e.keyCode&&(dxc-=.01),39==e.keyCode&&(dxc+=.01),38==e.keyCode&&(dyc+=.01),40==e.keyCode&&(dyc-=.01)),88==e.keyCode&&(dzc-=.03),90==e.keyCode&&(dzc=Math.min(0,dzc+.03)),70==e.keyCode&&(f1=(f1+1)%2,resize_render()),80==e.keyCode&&(savescr=1),!1);const delta=6;let startx,starty,startdist,mousedown=0;gl.canvas.addEventListener("dblclick",(function(e){running=!running})),resize_render();
"use strict";let R,N=30,Nrand=100,dx=0,dy=0,dz=0,dxc=0,dyc=0,dzc=0,dxp=0,dyp=0,dzp=0,xc=0,yc=0,zc=1,TWO_PI=6.28318530718,Nrad0=5,E=4,LL=10;const head=/\bHeadlessChrome\//.test(navigator.userAgent);let PI=3.1415926;for(var GET={},query=window.location.search.substring(1).split("&"),i=0,max=query.length;i<max;i++)if(""!==query[i]){var param=query[i].split("=");GET[decodeURIComponent(param[0])]=decodeURIComponent(param[1]||"")}let pals=[];pals.push([[359,31,56],[353,19,97],[6,20,96],[22,21,92],[20,16,98],[28,21,99],[6,20,96],[347,13,96]]),pals.push([[208,49,38],[205,41,59],[192,29,45],[190,14,64],[220,9,78],[12,4,45],[167,16,81],[180,7,100]]),pals.push([[222,86,22],[208,88,29],[203,61,57],[215,49,74],[211,68,93],[236,100,24],[195,85,45]]),pals.push([[4,100,34],[1,96,84],[26,92,94],[34,58,89],[48,100,99],[21,100,84],[8,100,17]]),pals.push([[43,35,28],[46,39,42],[41,27,90],[39,46,49],[39,83,90],[46,6,96],[46,15,97]]),pals.push([[209,92,15],[197,98,24],[195,79,37],[190,42,64],[189,62,90]]),pals.push([[331,21,31],[265,23,40],[335,26,76],[163,32,22],[210,24,29],[180,31,97],[49,30,63],[180,23,90],[170,13,48]]),pals.push([[26,71,17],[26,78,23],[42,68,60],[40,46,60],[42,76,74],[37,62,74]]),pals.push([[102,41,55],[123,37,63],[94,27,65],[121,30,69],[91,26,67],[125,37,63]]),pals.push([[115,52,17],[98,51,40],[78,58,54],[91,67,84],[6,54,38]]),pals.push([[349,83,69],[250,44,66],[191,44,66],[27,82,72],[45,85,70],[0,100,79]]),pals.push([[221,20,21],[199,26,38],[190,10,81],[220,0,100],[190,0,100],[205,30,43],[183,20,100],[215,43,36],[185,0,100],[200,0,100]]);let header="#version 300 es\nprecision highp float;\nprecision highp int;";var src_vert=header+"\nin vec2 a;\nout vec2 u;\nvoid main() {\n gl_Position = vec4(a,0.,1.);\n u = a/2. +vec2(.5,.5);\n}",src_pap=header+"\nconst int N = 30;\nconst int LL = 10;\nconst float Nf =20.;\nconst int Nrand =100;\nconst float Nrandf =100.;\nconst float PI =3.1415926;\n\nin vec2 u;\nout vec4 cout;\n\nuniform vec2 L;\nuniform highp sampler2D img;\nuniform float rand[Nrand];\n\nuniform float kl[N];\nuniform float ax[LL];\nuniform float ay[LL];\nuniform float az[LL];\nuniform vec3 v;\n\nfloat s1,c1,xe,ye,ze,Nrad,clarity,wf0,rr00,lgfac,wild,inv,night,lo,phase,rain,famp,kkx,kky,scalefac,ox,oy,rv;\nint nn; vec3 rlight;\n\nvec2 proj( in vec3 v, in vec3 ve, in vec2 tt) {\n float c = ve.z/(ve.z+v.z);\n return vec2((v.x-ve.x + tt[0]*v.z)*c, (v.y-ve.y + tt[1]*v.z)*c);\n}\nfloat dot3( in vec3 v, in vec3 w) { return v[0]*w[0] + v[1]*w[1] + v[2]*w[2]; }\nvec3 rot3d( in vec3 v, in vec3 k, in float theta) { // rotation of vector v about axis k, angle t with Rodrigues formula:\n return v*cos(theta)+cross(k,v)*sin(theta)+k*dot3(k,v)*(1.-cos(theta));\n}\nfloat norm3( in vec3 v) { return sqrt(dot3(v,v)); }\nvec3 flow( in vec3 r, in vec3 p) {\n return r + vec3(sin(2.*PI*rand[0]+3.*p[0]*r.x),sin(2.*PI*rand[1]+2.*p[1]*r.y),0.)*p[2]/200.;\n}\n\nvec2 ccircle(in vec2 uv, in float x, in float y, in float D, in float t1, in float t2) {\n float dx = x-uv.x; float dy = y-uv.y;\n float d = (dx*dx+dy*dy)/(D*D/4.);\nreturn .07*exp(-d*D*D)*float(dy>0.&&dx*dx<.001)*rain+exp(-(2.+6.*kl[0])*d)*vec2(1.,0.);\n}\n\nvoid main(void) {\n c1 = kl[0];\n s1 = kl[1];\n xe = kl[2];\n ye = kl[3];\n ze = kl[4];\n nn = int(kl[5]);\n Nrad = kl[6];\n clarity = kl[7];\n wf0 = kl[8];\n rr00 = kl[9];\n lgfac = kl[10];\n wild = kl[11];\n rlight = vec3(kl[12],kl[13],kl[14]);\n inv = kl[15];\n night = kl[16];\n lo = kl[17];\n phase = kl[18];\n rain = kl[19];\n famp = kl[20];\n kkx = kl[21];\n kky = kl[22];\n scalefac = kl[23];\n ox = kl[24];\n oy = kl[25];\n rv= kl[26];\nfloat mel1 = kl[27];\nfloat mel2 = kl[28];\nfloat count = kl[29];\n\nvec2 uv = u;\nvec2 uc = u;\n\nvec4 cc = texture(img,uc);\n\nif (L.x<L.y) {\n uv.y = 0.5 + (L.y/L.x)*(uv.y-0.5);\n uc.y = 0.5 + (L.y/L.x)*(uc.y-0.5);\n} else {\n uv.x = 0.5 + (L.x/L.y)*(uv.x-0.5);\n uc.x = 0.5 + (L.x/L.y)*(uc.x-0.5);\n}\n\ncout = cc;\n//cout.xy*=1. - .02*rain-.02*night;\n\nfloat dtt = 1.0;\n\nvec3 ve = vec3(xe,ye,ze);\nvec3 param = vec3(kkx,kky,famp);\nvec2 tt = vec2(c1,s1);\nfloat st=0.;\nfloat cnt=0.;\nint thmax = int(Nrad);\nfor( int j=0; j<nn; j++ ) {\n vec3 p = vec3(ax[j],ay[j],az[j]);\n float wf = wf0*(10.+min(240.,2./(0.005+ay[j])));\n for ( int th=0; th<thmax; th++) {\n cnt++;\n vec3 v1 = rot3d(vec3(1.,0.,0.),vec3(v[0],v[1],v[2]),(rv+2.*mel1+cnt/Nrad)*2.*PI);\n float ri = clarity + (1.-clarity)*(0.2+0.8*rand[int(mod(cnt,Nrandf))]);\n float ri0 = ri;\n float ri2 = fract(237.*ri);\n float ri3 = fract(191.*ri);\n float ri4 = fract(257.*ri);\n float fac = 1.;\n vec3 pr = flow(p+v1*1./200.*fac*ri*wf,param);\n //vec3 pr = p + .4*v1/200.*fac*wf*ri;\n vec2 p1 = proj(pr,ve,tt);\n float rr = 3.*wf0*(2.-clarity)*rr00*3.; //*ri;\n float aaa = 3.2/Nrad;\n aaa *= 2./(2.-clarity);\n //rr*=1.-count;\n float rref = rr;\n float aref = aaa;\n //aaa *= 1.-4.*az[j];\naaa*=2.;\n vec3 dr = rlight + vec3(xe,ye,ze) - pr;\n float xx = dot3(v1,dr)/length(dr);\n float axx = abs(xx); //axx=min(1.,max(0.,axx));\n dr-= .1*vec3(rand[11],rand[12],rand[13]);//.02*ff.yzx;\n float xx2 = dot3(v1,dr)/length(dr);\n\n vec2 hsb = vec2(axx,xx2);\n if (xx<0.) {\n hsb*=0.;\n aaa=1.;\n }\n float vv = min(.27,3.*(hsb.x+hsb.y));\n vv *= 1. + 0.25/rr/rr;\n float dt = 0.01*(1.+3.*ri4);\n fac = exp(ri3*2.);\n rr *= .45*fac;\n aaa*= 1.1/fac;\n vv*= 1.-.2*night;\n vv*= 1.-abs(sin(ri));\n vec2 v2 = proj(v1,ve,tt);\n float t1 = phase + 0.1 + .8*atan(v2.y,v2.x);\n if (xx<0.) { t1 += PI; }\n float t2 = t1 + dt;\n t1 -= dt;\n vv*=2.;\n vec4 cc_rgb = vec4(hsb.xy*vv,1.,min(1.,aaa));\n// vec4 cc_line = vec4(0.9,0.2,1.,.2*aaa);\n // if (rain>0. && xx>0. && st>0.) {rr*=exp(2.*ri4);}\n vec2 cd = ccircle(uc,ox+scalefac*p1.x,1.-oy+scalefac*p1.y,rr/200.,t1,t2);\n cout = mix(cout, cc_rgb, mel1*cc_rgb.w*cd[0]);\n pr = flow(vec3(p.x,-p.y,p.z)+v1/200.*fac*ri*wf,param);\n p1 = proj(pr,ve,tt);\n cd = ccircle(uc,ox+scalefac*p1.x,1.-oy+scalefac*p1.y,rr/200.,t1,t2);\n cout = mix(cout, cc_rgb, mel1*cc_rgb.w*cd[0]);\n }\n}\n}",src_simp=header+"\nconst int N = 30;\nconst int LL = 10;\nconst float Nf =20.;\nconst int Nrand =100;\nconst float Nrandf =100.;\nconst float dn =0.1;\nconst int Nx =512;\nconst float Nxf =512.;\nconst float PI =3.1415926;\nconst int numOctaves = 8;//9;\n//const float TT = 120.;\n\nin vec2 u;\nout vec4 cout;\n\nuniform vec2 res;\nuniform vec2 L;\nuniform float t; // frame number\nuniform highp sampler2D img;\nuniform highp sampler2D img00;\nuniform float kp[N];\nuniform float rand[Nrand];\nuniform vec3 dxy;\nuniform vec3 rc;\n\nvec2 hash2( in vec2 x ) {\n int ii = int(mod(x.x+res.x*x.y,Nrandf)); //counter into array of random #s\n int i2 = int(mod(x.y-res.y*x.x,Nrandf)); //counter into array of random #s\n return vec2(rand[ii],rand[i2]);\n}\nfloat ddot ( in vec2 x, in vec2 y ) { return x.x+y.x + x.y*y.y; }\nvec3 noise( in vec2 p ) {\n vec2 i = floor( p );\n vec2 f = fract( p );\n\n vec2 u = f*f*f*(f*(f*6.0-15.0)+10.0);\n vec2 du = 30.0*f*f*(f*(f-2.0)+1.0);\n\n vec2 ga = hash2( i + vec2(0.0,0.0) );\n vec2 gb = hash2( i + vec2(1.0,0.0) );\n vec2 gc = hash2( i + vec2(0.0,1.0) );\n vec2 gd = hash2( i + vec2(1.0,1.0) );\n\n float va = ddot( ga, f - vec2(0.0,0.0) );\n float vb = ddot( gb, f - vec2(1.0,0.0) );\n float vc = ddot( gc, f - vec2(0.0,1.0) );\n float vd = ddot( gd, f - vec2(1.0,1.0) );\n return vec3( va + u.x*(vb-va) + u.y*(vc-va) + u.x*u.y*(va-vb-vc+vd), // value\n ga + u.x*(gb-ga) + u.y*(gc-ga) + u.x*u.y*(ga-gb-gc+gd) + // derivatives\n du * (u.yx*(va-vb-vc+vd) + vec2(vb,vc) - va));\n}\n\nvec3 fbm( in vec2 x, in float H )\n{\n float G = exp(-2.*H);\n float f = 1.0;\n float a = 1.0;\n vec3 t = vec3(0.);\n for( int i=0; i<numOctaves; i++ )\n {\n t += a*noise(f*x);\n f *= 2.0;\n a *= G;\n }\n return t;\n}\n\nvec4 laplacian(in sampler2D img, in vec2 uv, in float dx) {\n vec2 dt = 1./res;\n vec4 rg = texture(img, uv + vec2(0, 0)*dt) * -1.;\n rg += texture(img, uv + vec2(-1, -1)*dt)*(0.05+dx);\n rg += texture(img, uv + vec2(-0, -1)*dt)* (0.2-dx);\n rg += texture(img, uv + vec2(1, -1)*dt)* (0.05+dx);\n rg += texture(img, uv + vec2(-1, 0)*dt) * (0.2-dx);\n rg += texture(img, uv + vec2(1, 0)*dt) * (0.2-dx);\n rg += texture(img, uv + vec2(-1, 1)*dt) * (0.05+dx);\n rg += texture(img, uv + vec2(0, 1)*dt) * (0.2-dx);\n rg += texture(img, uv + vec2(1, 1)*dt) * (0.05+dx);\n\n return rg;\n}\nvec2 proj( in vec3 v, in vec3 ve, in vec2 tt) {\n float c = ve.z/(ve.z+v.z);\n return vec2((v.x-ve.x + tt[0]*v.z)*c, (v.y-ve.y + tt[1]*v.z)*c);\n}\nfloat dot3( in vec3 v, in vec3 w) { return v[0]*w[0] + v[1]*w[1] + v[2]*w[2]; }\nvec3 rot3d( in vec3 v, in vec3 k, in float theta) { // rotation of vector v about axis k, angle t with Rodrigues formula:\n return v*cos(theta)+cross(k,v)*sin(theta)+k*dot3(k,v)*(1.-cos(theta));\n}\nfloat norm3( in vec3 v) { return sqrt(dot3(v,v)); }\nvec3 flow( in vec3 r, in vec3 p) {\n return r + vec3(sin(2.*PI*rand[0]+3.*p[0]*r.x),sin(2.*PI*rand[1]+2.*p[1]*r.y),0.)*p[2]/200.;\n}\n\nvoid main(void) {\n vec2 dt = rc.z/res;\n vec2 uv = (u+dxy.xy-vec2(0.5))*(1.+dxy.z)+vec2(0.5);\n vec2 uc = -rc.xy + (u)*rc.z; // global coords\n vec3 ff = (0.4+0.6*kp[9])*fbm(uc+fbm(uc,1.).yz,0.4+.4*kp[0]);\n vec3 f2 = (0.4+0.6*kp[10])*fbm(-11.*kp[11]*uc+fbm(-17.*kp[10]*uc,0.7).yz,0.7-.4*kp[1]);\n\nvec4 lp,lp2,cv,cu,cv2,cu2;\nfloat aa,bb;\n\nuc=uv;\n\nvec4 cc0 = texture(img00,uv);\n\nuc.y += kp[0]*0.2*rand[3]*ff.z*f2.x*cc0.x;//*mel1;\nuc.x += kp[1]*0.2*rand[3]*ff.y*f2.x*cc0.y;//*mel1;\n\nvec4 cc = texture(img,uc);\n\nff.x += .1*cc0.x;\nf2.x += .1*cc0.y;\n\nfloat th = ff.x;\nfloat dtt = 1.;\n\nvec2 dist = .5*dtt*0.01*(cc.x-cc.w)*vec2(kp[18]*cos(th)*(ff.y+kp[4]*ff.z),kp[19]*sin(th)*(ff.z-kp[4]*ff.y));\ndist.xy += rand[42]*(dist.yx-dist.xy);\nuc+=dist;\n\n aa = cc.x/256. + cc.y;\n bb = cc.z/256. + cc.w;\n lp = laplacian(img,uc,(kp[0]*2.-1.)*f2.x*(1.-aa));\n lp2 = laplacian(img,uc,(kp[1]*2.-1.)*ff.x*bb);\n\n uc.x += dtt*0.1*(lp.x-lp.w)*cos(th)*(ff.y+kp[4]*ff.x);\n uc.y += dtt*0.1*(lp.x-lp.w)*sin(th)*(ff.x-kp[4]*ff.y);\n uc.x += dtt*0.1*(cc.x-cc.w)*cos(th)*(ff.y+kp[4]*ff.x);\n uc.y += dtt*0.1*(cc.x-cc.w)*sin(th)*(ff.x-kp[4]*ff.y);\n\n cv= texture(img, uc + vec2(0, 1)*dt);\n cu= texture(img, uc + vec2(1, 0)*dt);\n cv2= texture(img, uc + vec2(0, -1)*dt);\n cu2= texture(img, uc + vec2(-1, 0)*dt);\n\nfloat da = .4*(1.-kp[15])*(1.-bb)*(lp.x+256.*lp.y)/256. + 3.*( -aa*bb*bb + 0.015*(1.+kp[17])*(1.-aa))*ff.x*ff.x ;\nfloat db = .4*(1.-kp[16])*(1.+kp[7])*(0.02+ff.x*ff.x)*aa*0.5*(lp2.z+256.*lp2.w)/256. + 3.*( aa*bb*bb - 0.04*(1.+1.*kp[6])*bb)*ff.x*ff.x;\n\nfloat dda=kp[15]*0.18*((cu.x/256.+cu.y-cu2.x/256.-cu2.y)*ff.y*kp[18] + (cv.x/256.+cv.y-cv2.x/256.-cv2.y)*ff.z*kp[19]);\nfloat ddb=kp[16]*0.18*((cu.z/256.+cu.w-cu2.z/256.-cu2.w)*f2.y*kp[18] + (cv.z/256.+cv.w-cv2.z/256.-cv2.w)*f2.z*kp[19]);\n\nda -= .3*cc0.x*cc0.x*ff.x;\ndb += .3*cc0.y;\n\ndda*=dda*6.*dtt;\nddb*=ddb*6.*dtt;\nda += dda;//*(1.-dda);\ndb += ddb;//*(1.-ddb);\n\nda*= 46000.;\ndb*= 46000.;\n\n da+=aa*256.*256.*.99;\n db+=bb*256.*256.*.99;\n\nfloat yn = floor(da/256.); // get leading part of da and rescale\nfloat xn = (da-yn*256.);\nfloat wn = floor(db/256.); // get leading part of da and rescale\nfloat zn = (db-wn*256.);\n\ncout = vec4(xn,yn,zn,wn)/256.;\n}",src_colp=header+"\nconst int N = 30;\nconst float Nf =20.;\nconst int Nrand =100;\nconst float Nrandf =100.;\nconst float dn =0.1;\nconst int Nx =512;\nconst float Nxf = .25*512.;\nconst float PI =3.1415926;\nconst int numOctaves = 8;\n\nin vec2 u;\nout vec4 cc;\n\nuniform vec2 res;\nuniform vec2 L;\nuniform float t; // frame number\nuniform highp sampler2D img;\nuniform highp sampler2D img2;\nuniform highp sampler2D img00;\nuniform highp sampler2D pal; // palette\nuniform float rand[Nrand];\nuniform vec3 dxy;\nuniform vec3 rc;\nuniform float kl[N];\n\nvec2 hash2( in vec2 x ) {\n int ii = int(mod(x.x+res.x*x.y,Nrandf)); //counter into array of random #s\n int i2 = int(mod(x.y-res.y*x.x,Nrandf)); //counter into array of random #s\n return vec2(rand[ii],rand[i2]);\n}\nfloat ddot ( in vec2 x, in vec2 y ) { return x.x+y.x + x.y*y.y; }\nvec3 noise( in vec2 p ) {\n vec2 i = floor( p );\n vec2 f = fract( p );\n\n vec2 u = f*f*f*(f*(f*6.0-15.0)+10.0);\n vec2 du = 30.0*f*f*(f*(f-2.0)+1.0);\n\n vec2 ga = hash2( i + vec2(0.0,0.0) );\n vec2 gb = hash2( i + vec2(1.0,0.0) );\n vec2 gc = hash2( i + vec2(0.0,1.0) );\n vec2 gd = hash2( i + vec2(1.0,1.0) );\n\n float va = ddot( ga, f - vec2(0.0,0.0) );\n float vb = ddot( gb, f - vec2(1.0,0.0) );\n float vc = ddot( gc, f - vec2(0.0,1.0) );\n float vd = ddot( gd, f - vec2(1.0,1.0) );\n\n return vec3( va + u.x*(vb-va) + u.y*(vc-va) + u.x*u.y*(va-vb-vc+vd), // value\n ga + u.x*(gb-ga) + u.y*(gc-ga) + u.x*u.y*(ga-gb-gc+gd) + // derivatives\n du * (u.yx*(va-vb-vc+vd) + vec2(vb,vc) - va));\n}\n\nvec3 fbm( in vec2 x, in float H )\n{\n float G = exp(-2.*H);\n float f = 1.0;\n float a = 1.0;\n vec3 t = vec3(0.0);\n for( int i=0; i<numOctaves; i++ )\n {\n t += a*noise(f*x);\n f *= 2.0;\n a *= G;\n }\n return t;\n}\n\nvec4 laplacian(in sampler2D img, in vec2 uv, in float dx) {\n vec2 dt = 1./res;\n vec4 rg = texture(img, uv + vec2(-1, -1)*dt)*(0.05+dx);\n rg += texture(img, uv + vec2(-0, -1)*dt)* (0.2-dx);\n rg += texture(img, uv + vec2(1, -1)*dt)* (0.05+dx);\n rg += texture(img, uv + vec2(-1, 0)*dt) * (0.2-dx);\n rg += texture(img, uv + vec2(0, 0)*dt) * -1.;\n rg += texture(img, uv + vec2(1, 0)*dt) * (0.2-dx);\n rg += texture(img, uv + vec2(-1, 1)*dt) * (0.05+dx);\n rg += texture(img, uv + vec2(0, 1)*dt) * (0.2-dx);\n rg += texture(img, uv + vec2(1, 1)*dt) * (0.05+dx);\n\n return rg;\n}\n\nfloat dot3( in vec3 v, in vec3 w) { return v[0]*w[0] + v[1]*w[1] + v[2]*w[2]; }\nvec3 rot3d( in vec3 v, in vec3 k, in float theta) { // rotation of vector v about axis k, angle t with Rodrigues formula:\n return v*cos(theta)+cross(k,v)*sin(theta)+k*dot3(k,v)*(1.-cos(theta));\n}\n\nvoid main(void) //( out vec4 fragColor, in vec2 fragCoord )\n{\nvec2 uv = (u+dxy.xy)*(1.+dxy.z);\nvec2 uc = -rc.xy + u*rc.z;\n\ncc = texture(img,uv); // in [0,1]\nvec4 cco = texture(img2,uv); // in [0,1]\nvec4 cc00 = texture(img00,uv); // in [0,1]\n\nvec3 ff = cc00.xyz;\nvec3 f2 = cc00.yxz;\n\n float aa = (cc.x+256.*cc.y)/256.;\n float bb = (cc.z+256.*cc.w)/256.;\nfloat aao = (cco.x+256.*cco.y)/256.;\nfloat bbo = (cco.z+256.*cco.w)/256.;\n\nvec4 lpo = laplacian(img2,uv,0.9*ff.x*(aao));\nvec4 lp = laplacian(img,uv,0.9*ff.x*(aa));\n\naao=4.*0.03*(lp[0]+lp[1]*256.-lpo[0]-lpo[1]*256.);\nbbo=4.*0.03*(lp[2]+lp[3]*256.-lpo[2]-lpo[3]*256.);\n\nvec4 cc_hsl = texture(pal,vec2(2.*bb*aa+0.4*aa*cc00.x+0.4*bb*cc00.y,ff.xy*bb)); //+ff.yx*aa));\nvec4 cco_hsl = texture(pal,vec2(2.*bbo*aao+0.4*aao*cc00.x+0.4*bbo*cc00.y,ff.xy*bbo)); //+ff.yx*aao));\n\ncc_hsl -= (0.3+.6*rand[37])*(cc_hsl-cco_hsl);\n\n//cc_hsl.x += .3*cc00.x*cc00.x*(3.-2.*cc00.z);\ncc_hsl.x += .5*cc00.x*cc00.z*rand[44];\n\ncc_hsl.x += 0.03*f2.x*bb + rc.x*rc.y; // shift hue\ncc_hsl.x = mod(cc_hsl.x,1.);\n//cc_hsl.z *= 0.2+(3.*bb+6.*aa*bb); // multiply lightness by particle number\ncc_hsl.z *= 0.3+rand[43]*(4.*bb*cc00.z+cc00.x)+(1.-rand[43])*(3.*bb+6.*aa*bb); // multiply lightness by particle number\n\ncc_hsl.y *= 1.0*(1.1-ff.x*bb)*(1.-f2.x*f2.x); // multiply sat by 1-particle number\n\nvec3 rgb = clamp( abs(mod(cc_hsl.x*6.0+vec3(0.0,4.0,2.0),6.0)-3.0)-1.0, 0.0, 1.0 );\nrgb = cc_hsl.z + cc_hsl.y * (rgb-0.5)*(1.0-abs(2.0*cc_hsl.z-1.0));\n\nrgb += rand[39]*(cc_hsl.bgr-rgb);\n\n//rgb += rand[38]*rand[38]*(1.-rgb);\n\nrgb *= rgb*(3.-2.*rgb);\n//rgb *= 1.+cc00.z*(rgb*(3.-2.*rgb)-1.);\nrgb *= .7+.36*rgb*(3.-2.*rgb); //increase contrast, but not too much\n\ncc = vec4(rgb,1.);\n\nvec4 ccoo = vec4(.4+.3*aao-f2.x,.1*(aao+bbo),1.-bbo,1.);\nccoo = mix(ccoo,ccoo.zyxw,1.-ff.y); // change to blue highlights\n\ncc = mix(cc,ccoo,clamp(2.*ff.x*aao,-1.,1.));\ncc=clamp(cc,0.,1.);\n\nfloat fx = fract(uc.x*res.x);//-3.*ff.y);\nfloat fy = fract(uc.y*res.y);//-3.*ff.z);\nfloat r2 = (fx-.5)*(fx-.5)+(fy-.5)*(fy-.5)-0.2*(1.+0.6*kl[16]*cc00.z);\nfloat drr = clamp((r2+.1)*18.,0.,1.);\ncc.rgb *= drr*.5*cc00.z + (1.-drr)*(.8-2.*r2);\n}";let useA,prngA,prngB;class Random{constructor(){useA=!1;let n=function(n){let c=parseInt(n.substr(0,8),16),t=parseInt(n.substr(8,8),16),a=parseInt(n.substr(16,8),16),e=parseInt(n.substr(24,8),16);return function(){c|=0,t|=0,a|=0,e|=0;let n=(c+t|0)+e|0;return e=e+1|0,c=t^t>>>9,t=a+(a<<3)|0,a=a<<21|a>>>11,a=a+n|0,(n>>>0)/4294967296}};prngA=new n(tokenData.hash.substr(2,32)),prngB=new n(tokenData.hash.substr(34,32));for(let n=0;n<1e6;n+=2)prngA(),prngB()}random_dec(){return useA=!useA,useA?prngA():prngB()}}function rnd(){return R.random_dec()}
let M=1; var isMobile = window.matchMedia("(hover: none)").matches; // no hovering function resize_render() { let w=innerWidth, h=innerHeight, dpr=devicePixelRatio; C.width = M*w*dpr|0; C.height = M*h*dpr|0; if (head || f1==1) { Lx = Math.min(C.width,C.height); Ly=Lx; } else if (f1==2 || isMobile) { Lx = C.width; Ly=C.height; if (Lx>Ly) { Lx=Math.min(Lx,2.5*Ly); } if (Ly>Lx) { Ly=Math.min(Ly,2.5*Lx); } } else { Lx = Math.min(3*Nx,C.width); Ly = Math.min(3*Ny,C.height); } C.style.width = w+'px'; C.style.height = h+'px'; gl.viewport((C.width-Lx)/2,(C.height-Ly)/2,Lx,Ly); render(); } function texset(wrap) { gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, wrap); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, wrap); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR); } let tex00,texA,texB,texC,fbA,fbB; let wrap = gl.REPEAT; tex00 = gl.createTexture(); gl.bindTexture(gl.TEXTURE_2D, tex00); gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, Nx, Ny, 0, gl.RGBA, gl.UNSIGNED_BYTE, tex0.subarray(0, Nx*Ny*4)); texset(wrap); texA = gl.createTexture(); gl.bindTexture(gl.TEXTURE_2D, texA); gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, Nx, Ny, 0, gl.RGBA, gl.UNSIGNED_BYTE, tex0.subarray(0, Nx*Ny*4)); fbA = gl.createFramebuffer(); gl.bindFramebuffer(gl.FRAMEBUFFER, fbA); gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texA, 0); texset(wrap); texB = gl.createTexture(); gl.bindTexture(gl.TEXTURE_2D, texB); gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, Nx, Ny, 0, gl.RGBA, gl.UNSIGNED_BYTE, null); fbB = gl.createFramebuffer(); gl.bindFramebuffer(gl.FRAMEBUFFER, fbB); gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texB, 0); texset(wrap); texC = gl.createTexture(); //colormap gl.bindTexture(gl.TEXTURE_2D, texC); gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB, 10, 2, 0, gl.RGB, gl.UNSIGNED_BYTE, pal); texset(wrap); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAX_LEVEL, 0); gl.useProgram(colp); gl.uniform1i(loc_palc, 1); //texture 1 // and assign uniforms gl.useProgram(simp); gl.uniform1fv(loc_km,km); gl.uniform1fv(loc_kl,kl); gl.uniform1fv(loc_rand,rand); gl.useProgram(colp); gl.uniform1fv(loc_randc,rand); let prevt=performance.now(); let dt = 1000/60; let running=true; let periodic=0; let anim=0; let flip=0; let count=0; let dxycount=0; let TT = 120; let om0 = 0.01, A=0.002; function render() { if (running) { count++; let time=performance.now(); if (time-prevt>dt) { gl.viewport(0,0,Nx,Ny); gl.useProgram(simp); if (count%TT==0) { for (let i=0; i<Nrand; i++) { rand[i]=.7*rnd()+.3*rand[i]; } gl.uniform1fv(loc_rand,rand); } if (dxycount==0) { dx=dxc-dxp; dy=dyc-dyp; dz=dzc-dzp; zc *= 1+2*dz; xc -= (.5+(2*dx-0.5)*(1+2*dz))*zc; yc -= (.5+(2*dy-0.5)*(1+2*dz))*zc; kp[0]+= dx/3; kp[1]+= dy/3; kp[15]*=Math.exp(dx/3); kp[16]*=Math.exp(dy/3); } gl.uniform1fv(loc_kp,kp); if (dx!=0 || dy!=0 || dz!=0) { dxycount++; } gl.uniform3fv(loc_dxy,[dx, dy, dz]); gl.uniform3fv(loc_rc,[xc, yc, zc]); gl.uniform1i(loc_t,time); for (let j=0; j<2; j++) { flip = !flip; gl.bindFramebuffer(gl.FRAMEBUFFER, (flip ? fbB : fbA)); gl.activeTexture(gl.TEXTURE0); gl.bindTexture(gl.TEXTURE_2D, (flip ? texA : texB)); gl.activeTexture(gl.TEXTURE1); gl.bindTexture(gl.TEXTURE_2D, tex00); gl.drawArrays(gl.TRIANGLES, 0, 6); } gl.viewport((C.width-Lx)/2,(C.height-Ly)/2,Lx,Ly); gl.useProgram(colp); gl.uniform1i(loc_tc,time); gl.uniform2f(loc_Lc,Lx,Ly); gl.uniform3fv(loc_dxyc,[dx, dy, dz]); gl.uniform3fv(loc_rcc,[xc, yc, zc]); if (dxycount>=1) { dxycount=0; dx=0;dy=0;dz=0; dxp=dxc;dyp=dyc;dzp=dzc; } gl.bindFramebuffer(gl.FRAMEBUFFER, null); gl.activeTexture(gl.TEXTURE0); gl.bindTexture(gl.TEXTURE_2D, (flip ? texB : texA)); gl.activeTexture(gl.TEXTURE1); gl.bindTexture(gl.TEXTURE_2D, texC); //color map gl.activeTexture(gl.TEXTURE2); gl.bindTexture(gl.TEXTURE_2D, (flip ? texA : texB)); if (dz==0) gl.drawArrays(gl.TRIANGLES, 0, 6); } prevt=time-(time-prevt)%dt; } // requestAnimationFrame(render.bind()); if (savescr==1) { savescr=2; resize_render(); } if (savescr==2) { savescr=0; var tC = document.createElement("canvas"); tC.width = Lx; tC.height = Ly; var ctx = tC.getContext("2d"); ctx.setTransform(1,0,0,-1,0,gl.height); ctx.drawImage(C,-(C.width-Lx)/2,-(C.height-Ly)/2); tC.toBlob((blob) => { saveBlob(blob, `Calian-${tokenData.tokenId}.png`); }); } requestAnimationFrame(render); } const saveBlob = (function() { const a = document.createElement('a'); document.body.appendChild(a); a.style.display = 'none'; return function saveData(blob, fileName) { const url = window.URL.createObjectURL(blob); a.href = url; a.download = fileName; a.click(); }; }()); // resize event let tid=0; onresize => { clearTimeout(tid); tid=setTimeout(resize_render,150) }; let f1=0,savescr=0; // keyboard event onkeyup=e=>{ if (e.key==' ') { // spacebar running = !running; } if ( window !== window.parent ) { // iframe if (e.keyCode==65) dxc-=0.01; //a = left if (e.keyCode==68) dxc+=0.01; //d = right if (e.keyCode==87) dyc+=0.01; //w = up if (e.keyCode==83) dyc-=0.01; //s = down } else { // not iframe if (e.keyCode==37) dxc-=0.01; //left if (e.keyCode==39) dxc+=0.01; //right if (e.keyCode==38) dyc+=0.01; //up if (e.keyCode==40) dyc-=0.01; //down } if (e.keyCode==88) dzc-=0.03; //x = in if (e.keyCode==90) dzc=Math.min(0,dzc+0.03); //z = out if (e.keyCode==70) { f1=(f1+1)%3; resize_render(); } // f if (e.keyCode==80) { savescr=1; Lx = Ly = min(C.width,C.height); } //p = print screen // dzc+=e.deltaY/Ly; return false; //e.stopPropagation(); e.preventDefault(); } function handler(e) { var scroll = (e.deltaY || -1*e.wheelDelta || 10*e.detail); var isTouchPad = e.wheelDeltaY ? e.wheelDeltaY === -3 * e.deltaY : e.deltaMode === 0; dzc=Math.min(0,dzc+.5*Math.max(-0.03,Math.min(0.03,scroll/Ly*(1+3*isTouchPad)))); e.stopPropagation(); e.preventDefault(); return false; } gl.canvas.addEventListener("mousewheel", handler, false); gl.canvas.addEventListener("DOMMouseScroll", handler, false); const delta = 6; let startx; let starty; let startdist; let mousedown=0; function handler_down(e) { if (running) { mousedown=1; startx = (e.clientX || (e.touches && e.touches[0].clientX)); starty = (e.clientY || (e.touches && e.touches[0].clientY)); if (e.touches && e.touches.length === 2) { e.preventDefault(); startx = startx/2 + e.touches[1].clientX / 2; starty = starty/2 + e.touches[1].clientY / 2; startdist = (e.touches[0].clientX-e.touches[1].clientX)**2+(e.touches[0].clientY-e.touches[1].clientY)**2; } } } gl.canvas.addEventListener("mousedown", handler_down, false); gl.canvas.addEventListener("touchstart", handler_down, false); function handler_move(e) { if (running && mousedown) { const sx = (e.clientX || (e.touches && e.touches[0].clientX)); const sy = (e.clientY || (e.touches && e.touches[0].clientY)); e.preventDefault(); if (e.touches && e.touches.length === 2) { e.preventDefault(); // Prevent page scroll let scale; const deltaDistance = (e.touches[0].clientX-e.touches[1].clientX)**2+(e.touches[0].clientY-e.touches[1].clientY)**2; scale = -100*(deltaDistance / startdist-1); dzc=Math.min(0,dzc+.5*Math.max(-0.05,Math.min(0.05,scale/Ly))); } else { dxc-=(sx-startx)/Lx*Math.exp(-0.1*dzc); dyc+=(sy-starty)/Ly*Math.exp(-0.1*dzc); startx = sx; starty = sy; } } }gl.canvas.addEventListener("mousemove", handler_move, false); gl.canvas.addEventListener("touchmove", handler_move, false); gl.canvas.addEventListener('mouseleave', function (e) { mousedown=0; }); gl.canvas.addEventListener('mouseup', function (e) { mousedown=0; }); gl.canvas.addEventListener('touchend', function (e) { mousedown=0; }); gl.canvas.addEventListener('dblclick', function (e) { running = !running; }); resize_render();
let M=1; var isMobile = window.matchMedia("(hover: none)").matches; // no hovering function resize_render() { let w=innerWidth, h=innerHeight, dpr=devicePixelRatio; C.width = M*w*dpr|0; C.height = M*h*dpr|0; if (head || f1==1) { Lx = Math.min(C.width,C.height); Ly=Lx; } else if (f1==2 || isMobile) { Lx = C.width; Ly=C.height; if (Lx>Ly) { Lx=Math.min(Lx,2.5*Ly); } if (Ly>Lx) { Ly=Math.min(Ly,2.5*Lx); } } else { Lx = Math.min(3*Nx,C.width); Ly = Math.min(3*Ny,C.height); } C.style.width = w+'px'; C.style.height = h+'px'; gl.viewport((C.width-Lx)/2,(C.height-Ly)/2,Lx,Ly); render(); } function texset(wrap) { gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, wrap); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, wrap); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR); } let tex00,texA,texB,texC,fbA,fbB; let wrap = gl.REPEAT; tex00 = gl.createTexture(); gl.bindTexture(gl.TEXTURE_2D, tex00); gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, Nx, Ny, 0, gl.RGBA, gl.UNSIGNED_BYTE, tex0.subarray(0, Nx*Ny*4)); texset(wrap); texA = gl.createTexture(); gl.bindTexture(gl.TEXTURE_2D, texA); gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, Nx, Ny, 0, gl.RGBA, gl.UNSIGNED_BYTE, tex0.subarray(0, Nx*Ny*4)); fbA = gl.createFramebuffer(); gl.bindFramebuffer(gl.FRAMEBUFFER, fbA); gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texA, 0); texset(wrap); texB = gl.createTexture(); gl.bindTexture(gl.TEXTURE_2D, texB); gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, Nx, Ny, 0, gl.RGBA, gl.UNSIGNED_BYTE, null); fbB = gl.createFramebuffer(); gl.bindFramebuffer(gl.FRAMEBUFFER, fbB); gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texB, 0); texset(wrap); texC = gl.createTexture(); //colormap gl.bindTexture(gl.TEXTURE_2D, texC); gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB, 10, 2, 0, gl.RGB, gl.UNSIGNED_BYTE, pal); texset(wrap); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAX_LEVEL, 0); gl.useProgram(colp); gl.uniform1i(loc_palc, 1); //texture 1 // and assign uniforms gl.useProgram(simp); gl.uniform1fv(loc_km,km); gl.uniform1fv(loc_kl,kl); gl.uniform1fv(loc_rand,rand); gl.useProgram(colp); gl.uniform1fv(loc_randc,rand); let prevt=performance.now(); let dt = 1000/60; let running=true; let periodic=0; let anim=0; let flip=0; let count=0; let dxycount=0; let TT = 120; let om0 = 0.01, A=0.002; function render() { if (running) { count++; let time=performance.now(); if (time-prevt>dt) { gl.viewport(0,0,Nx,Ny); gl.useProgram(simp); if (count%TT==0) { for (let i=0; i<Nrand; i++) { rand[i]=.7*rnd()+.3*rand[i]; } gl.uniform1fv(loc_rand,rand); } if (dxycount==0) { dx=dxc-dxp; dy=dyc-dyp; dz=dzc-dzp; zc *= 1+2*dz; xc -= (.5+(2*dx-0.5)*(1+2*dz))*zc; yc -= (.5+(2*dy-0.5)*(1+2*dz))*zc; kp[0]+= dx/3; kp[1]+= dy/3; kp[15]*=Math.exp(dx/3); kp[16]*=Math.exp(dy/3); } gl.uniform1fv(loc_kp,kp); if (dx!=0 || dy!=0 || dz!=0) { dxycount++; } gl.uniform3fv(loc_dxy,[dx, dy, dz]); gl.uniform3fv(loc_rc,[xc, yc, zc]); gl.uniform1i(loc_t,time); for (let j=0; j<2; j++) { flip = !flip; gl.bindFramebuffer(gl.FRAMEBUFFER, (flip ? fbB : fbA)); gl.activeTexture(gl.TEXTURE0); gl.bindTexture(gl.TEXTURE_2D, (flip ? texA : texB)); gl.activeTexture(gl.TEXTURE1); gl.bindTexture(gl.TEXTURE_2D, tex00); gl.drawArrays(gl.TRIANGLES, 0, 6); } gl.viewport((C.width-Lx)/2,(C.height-Ly)/2,Lx,Ly); gl.useProgram(colp); gl.uniform1i(loc_tc,time); gl.uniform2f(loc_Lc,Lx,Ly); gl.uniform3fv(loc_dxyc,[dx, dy, dz]); gl.uniform3fv(loc_rcc,[xc, yc, zc]); if (dxycount>=1) { dxycount=0; dx=0;dy=0;dz=0; dxp=dxc;dyp=dyc;dzp=dzc; } gl.bindFramebuffer(gl.FRAMEBUFFER, null); gl.activeTexture(gl.TEXTURE0); gl.bindTexture(gl.TEXTURE_2D, (flip ? texB : texA)); gl.activeTexture(gl.TEXTURE1); gl.bindTexture(gl.TEXTURE_2D, texC); //color map gl.activeTexture(gl.TEXTURE2); gl.bindTexture(gl.TEXTURE_2D, (flip ? texA : texB)); if (dz==0) gl.drawArrays(gl.TRIANGLES, 0, 6); } prevt=time-(time-prevt)%dt; } // requestAnimationFrame(render.bind()); if (savescr==1) { savescr=2; resize_render(); } if (savescr==2) { savescr=0; var tC = document.createElement("canvas"); tC.width = Lx; tC.height = Ly; var ctx = tC.getContext("2d"); ctx.setTransform(1,0,0,-1,0,gl.height); ctx.drawImage(C,-(C.width-Lx)/2,-(C.height-Ly)/2); tC.toBlob((blob) => { saveBlob(blob, `Calian-${tokenData.tokenId}.png`); }); } requestAnimationFrame(render); } const saveBlob = (function() { const a = document.createElement('a'); document.body.appendChild(a); a.style.display = 'none'; return function saveData(blob, fileName) { const url = window.URL.createObjectURL(blob); a.href = url; a.download = fileName; a.click(); }; }()); // resize event let tid=0; onresize => { clearTimeout(tid); tid=setTimeout(resize_render,150) }; let f1=0,savescr=0; // keyboard event onkeyup=e=>{ if (e.key==' ') { // spacebar running = !running; } if ( window !== window.parent ) { // iframe if (e.keyCode==65) dxc-=0.01; //a = left if (e.keyCode==68) dxc+=0.01; //d = right if (e.keyCode==87) dyc+=0.01; //w = up if (e.keyCode==83) dyc-=0.01; //s = down } else { // not iframe if (e.keyCode==37) dxc-=0.01; //left if (e.keyCode==39) dxc+=0.01; //right if (e.keyCode==38) dyc+=0.01; //up if (e.keyCode==40) dyc-=0.01; //down } if (e.keyCode==88) dzc-=0.03; //x = in if (e.keyCode==90) dzc=Math.min(0,dzc+0.03); //z = out if (e.keyCode==70) { f1=(f1+1)%3; resize_render(); } // f if (e.keyCode==80) { savescr=1; Lx = Ly = min(C.width,C.height); } //p = print screen // dzc+=e.deltaY/Ly; return false; //e.stopPropagation(); e.preventDefault(); } function handler(e) { var scroll = (e.deltaY || -1*e.wheelDelta || 10*e.detail); var isTouchPad = e.wheelDeltaY ? e.wheelDeltaY === -3 * e.deltaY : e.deltaMode === 0; dzc=Math.min(0,dzc+.5*Math.max(-0.03,Math.min(0.03,scroll/Ly*(1+3*isTouchPad)))); e.stopPropagation(); e.preventDefault(); return false; } gl.canvas.addEventListener("mousewheel", handler, false); gl.canvas.addEventListener("DOMMouseScroll", handler, false); const delta = 6; let startx; let starty; let mousedown=0; function handler_down(e) { if (running) { mousedown=1; startx = (e.clientX || (e.touches && e.touches[0].clientX)); starty = (e.clientY || (e.touches && e.touches[0].clientY)); } } gl.canvas.addEventListener("mousedown", handler_down, false); gl.canvas.addEventListener("touchstart", handler_down, false); function handler_move(e) { if (running && mousedown) { const sx = (e.clientX || (e.touches && e.touches[0].clientX)); const sy = (e.clientY || (e.touches && e.touches[0].clientY)); dxc-=(sx-startx)/Lx*Math.exp(-0.1*dzc); dyc+=(sy-starty)/Ly*Math.exp(-0.1*dzc); startx = sx; starty = sy; e.preventDefault(); } } gl.canvas.addEventListener("mousemove", handler_move, false); gl.canvas.addEventListener("touchmove", handler_move, false); gl.canvas.addEventListener('mouseleave', function (e) { mousedown=0; }); gl.canvas.addEventListener('mouseup', function (e) { mousedown=0; }); gl.canvas.addEventListener('touchend', function (e) { mousedown=0; }); gl.canvas.addEventListener('dblclick', function (e) { running = !running; }); resize_render();
let useA,prngA,prngB; class Random { constructor() { useA = false; let sfc32 = function (uint128Hex) { let a = parseInt(uint128Hex.substr(0, 8), 16); let b = parseInt(uint128Hex.substr(8, 8), 16); let c = parseInt(uint128Hex.substr(16, 8), 16); let d = parseInt(uint128Hex.substr(24, 8), 16); return function () { 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; }; }; // seed prngA with first half of tokenData.hash prngA = new sfc32(tokenData.hash.substr(2, 32)); // seed prngB with second half of tokenData.hash prngB = new sfc32(tokenData.hash.substr(34, 32)); for (let i = 0; i < 1e6; i += 2) { prngA(); prngB(); } } random_dec() { useA = !useA; return useA ? prngA() : prngB(); } } function rnd() { return R.random_dec() } function vecscl(v,k) { let w=[]; for (let i=0; i<v.length; i++) { w[i] = v[i]*k; } return w } function clamp(x) { return Math.max(0,Math.min(1,x)); } function dot2(x,y) { return x[0]*y[0]+x[1]*y[1]; } R = new Random(); let C,D,body,gl,Shader; document.body.style.backgroundColor = "#030303"; console.log("Calian by Eric De Giuli"); C=({body}=D=document).createElement('canvas'); body.appendChild(C); gl=C.getContext('webgl2'); Shader=(typ,src)=>{ const s =gl.createShader(typ); gl.shaderSource(s,src); gl.compileShader(s); if (!gl.getShaderParameter(s, gl.COMPILE_STATUS)) { console.error(`Error compiling ${typ === gl.VERTEX_SHADER ? "vertex" : "fragment"} shader "${src}":`); console.log(gl.getShaderInfoLog(s)); } return s; } var GET = {}; var query = window.location.search.substring(1).split("&"); for (var i = 0, max = query.length; i < max; i++) { if (query[i] === "") continue; var param = query[i].split("="); GET[decodeURIComponent(param[0])] = decodeURIComponent(param[1] || ""); } let simp,colp,vs,fs; let Lx,Ly,Nx,Ny; Nx = 512;if (GET.N) { Nx=GET.N; } Ny=Nx; const head = /\bHeadlessChrome\//.test(navigator.userAgent); let PI = 3.1415926; let pal,pj,inv; let palp = [3,5,3,4,1,2,4,4,1,3,2,2,4,2,3,3]; palp = vecscl(palp,1/46); let cumpal = []; cumpal[0]=0; for (let i=1; i<palp.length; i++) { cumpal[i]=cumpal[i-1]+palp[i-1]; } let st = 1; pj=1; let palr = rnd(); while (st<palp.length && cumpal[st]<palr) { st++; } st--; let pj2 = Math.floor(11*rnd()); (tokenData.tokenId%1000000==0)&&(st=1); inv=0; switch(st) { case 0: pj=6;pj2=7; break; // embers in half light case 1: pj=11;pj2=7; break; // liquid circuit case 2: pj=1;pj2=5; break; // alpenglow case 3: pj=1;pj2=0; break; // zabriskie point case 4: pj=3;pj2=9; break; // aurum case 5: pj=6;pj2=0; break; // tunguska case 6: pj=5;pj2=7; break; // nocturne case 7: pj=11;pj2=5; break; // kind of blue case 8: pj=11;pj2=4; break; // inferno case 9: pj=11;pj2=0; break; // constellation case 10: pj=0;pj2=0;inv=1; break; // white heat case 11: pj=3;pj2=3;inv=1; break; // calanque case 12: pj=2;pj2=0; break; // bouquet case 13: pj=2;pj2=10; break; // spectral case 14: pj=10;pj2=8; break; // the forest path to the spring case 15: pj=10;pj2=4; break; // abalone } pal = new Uint8Array(10*4*2); for (let k=0; k<11; k++) { // which colour in palette for (let k2=0; k2<2; k2++) { // which palette let pp = (k2==0) ? pj : pj2; let kk = Math.min(k,pals[pp].length-1); pal[3*k+3*10*k2] = pals[pp][kk][0]; pal[3*k+3*10*k2+1] = pals[pp][kk][1]; pal[3*k+3*10*k2+2] = pals[pp][kk][2]; if (inv) { pal[3*k+3*10*k2] = (pal[3*k+3*10*k2]+180)%360; } //invert colour } } let kp,km,kv,kw,kl,rand; rand = []; for (let i=0; i<Nrand; i++) { rand[i]=rnd(); } let k0=1; let kl0=0.001; kp = new Float32Array(N); km = new Float32Array(N); kl = new Float32Array(N); switch(st) { case 0: kp = [0.66, 0.95, 0.94, 0.037, 0.89, 0.26, 0.90, 0.94, 0.65, 0.76, 0.54, 0.11, 0.50, 0.66, 0.96, 0.74, 0.91, 0.33, 0.15, 0.85]; break; case 1: kp = [0.97, 0.01, 0.89, 0.08, 0.78, 0.98, 0.16, 0.80, 0.53, 0.91, 0.40, 0.54, 0.84, 0.44, 0.14, 0.75, 0.45, 0.33, 0.47, 0.95]; break; case 2: kp = [0.72, 0.85, 0.51, 0.08, 0.98, 0.29, 0.91, 0.19, 0.69, 0.24, 0.99, 0.32, 0.84, 0.03, 0.97, 0.14, 0.09, 0.04, 0.08, 0.26]; break; case 3: kp = [0.14, 0.95, 0.24, 0.09, 0.05, 0.18, 0.96, 0.04, 0.47, 0.18, 0.13, 0.38, 0.21, 0.85, 0.66, 0.05, 0.15, 0.23, 0.25, 0.48]; break; case 4: kp = [0.58, 0.02, 0.03, 0.84, 0.43, 0.40, 0.95, 0.76, 0.15, 0.55, 0.04, 0.49, 0.49, 0.55, 0.52, 0.07, 0.22, 0.16, 0.31, 0.37]; break; case 5: kp = [0.21, 0.10, 0.21, 0.13, 0.07, 0.42, 0.26, 0.77, 0.28, 0.67, 0.79, 0.10, 0.28, 0.20, 0.04, 0.21, 0.35, 0.125, 0.75, 0.87]; break; case 6: kp = [0.40, 0.28, 0.88, 0.36, 0.92, 0.96, 0.79, 0.24, 0.99, 0.73, 0.68, 0.03, 0.09, 0.52, 0.11, 0.29, 0.95, 0.01, 0.01, 0.62]; break; case 7: kp = [0.10, 0.27, 0.31, 0.05, 0.40, 0.24, 0.67, 0.00, 0.02, 0.92, 0.75, 0.11, 0.40, 0.55, 0.97, 0.45, 0.12, 0.15, 0.54, 0.56]; break; case 8: kp = [0.17, 0.81, 0.64, 0.19, 0.52, 0.27, 0.59, 0.11, 0.65, 0.87, 0.36, 0.17, 0.66, 0.10, 0.95, 0.08, 0.50, 0.43, 0.92, 0.13]; break; case 9: kp = [0.59, 0.56, 0.03, 0.14, 0.58, 0.05, 0.80, 0.00, 0.09, 0.75, 0.80, 0.55, 0.07, 0.27, 0.46, 0.08, 0.35, 0.01, 0.17, 0.63]; break; case 10: kp = [0.021, 0.68, 0.20, 0.04, 0.46, 0.40, 0.30, 0.76, 0.19, 0.20, 0.78, 0.50, 0.10, 0.58, 0.61, 0.13, 0.25, 0.39, 0.63, 0.38]; break; case 11: kp = [0.11, 0.18, 0.02, 0.15, 0.49, 0.90, 0.73, 0.77, 0.69, 0.93, 0.95, 0.76, 0.78, 0.32, 0.13, 0.70, 0.07, 0.04, 0.30, 0.76]; break; case 12: kp = [0.15, 0.27, 0.17, 0.11, 0.61, 0.44, 0.65, 0.21, 0.82, 0.79, 0.40, 0.33, 0.43, 0.22, 0.02, 0.07, 0.50, 0.13, 0.95, 0.34]; break; case 13: kp = [0.89, 0.46, 0.48, 0.30, 0.38, 0.18, 0.13, 0.68, 0.20, 0.87, 0.92, 0.56, 0.06, 0.25, 0.32, 0.10, 0.05, 0.11, 0.31, 0.55]; break; case 14: kp = [0.90, 0.025, 0.064, 0.439, 0.208, 0.154, 0.261, 0.085, 0.268, 0.917, 0.780, 0.709, 0.087, 0.068, 0.684, 0.057, 0.480, 0.282, 0.174, 0.819]; break; case 15: kp = [0.81, 0.79, 0.38, 0.80, 0.19, 0.22, 0.39, 0.047, 0.82, 0.98, 0.90, 0.28, 0.12, 0.24, 0.12, 0.69, 0.62, 0.20, 0.99, 0.71]; break; } for (let i=0; i<N; i++) { km[i]=k0*rnd(); } for (let i=0; i<N; i++) { kl[i]=kl0*rnd(); } if (km[0]<0.15*k0 && st!=10 && st!=3 && st!=1) { kp[15]=0.69;kp[16]=1.34; } let nx = 2+Math.floor(8*rnd()); let ny = 2+Math.floor(8*rnd()); let rr = rnd(); let n4 = Math.floor(Math.exp(4*rnd())); let rbg = Math.floor(15*rnd()); // initial conditions const tex0 = new Uint8Array(Nx*Ny*4); let th; for (let x = 0; x < Nx; x++) { for (let y = 0; y < Ny; y++) { let i = x+Nx*y; let r2 = (x-Nx/2)**2+(y-Ny/2)**2; r2/=(Nx*Nx+Ny*Ny)/4; switch(rbg) { case 0: r2 = Math.sin(x/nx)*Math.sin(y/ny)*Math.sin(25*r2)>.1+.5*rr; break; case 1: r2 = Math.sin(x/Nx*nx*PI)*Math.sin(y/Ny*ny*PI)*Math.sin(25*r2)>0.5*rr; break; case 2: r2 = Math.sin(y*x/Nx*nx*PI)*Math.sin(y/Ny*ny*PI)*Math.sin(25*r2)>0.5*rr; break; case 3: r2 = Math.sin(y*x/Nx*nx*PI)*Math.sin(y/Ny*ny*PI)*Math.sin(2*(x-Nx/2)/(y-Ny/2)+1*(y-Ny/2)/(x-Nx/2))>0.5*rr; break; case 4: r2 = Math.sin(Math.sin(x/Nx*n4)*y/Ny*nx*PI)*Math.sin(y/Ny*ny*PI)*Math.sin(2*(x-Nx/2)/(y-Ny/2)+1*(y-Ny/2)/(x-Nx/2))>0.5*rr; break; case 5: r2 = Math.sin(Math.sin(x/Nx*n4*PI)*y/Ny*(1-y/Ny)*ny*PI)*Math.sin(x/Nx*nx*PI)>0.6*rr; break; case 6: r2 = Math.sin(Math.sin(y/Ny*n4*PI)*x/Nx*(1-x/Nx)*nx*PI)*Math.sin(y/Ny*ny*PI)>0.6*rr; break; case 7: r2 = Math.sin(30*x/Nx*nx*PI)*Math.sin(x/Nx*nx*PI)>0.6*rr; break; case 8: r2 = Math.sin(30*x/Nx*nx*PI)*Math.sin(y/Ny*ny*PI)>0.6*rr; break; case 9: r2 *= .7*(Math.sin(20*(x/Nx-0.5)*nx)+Math.sin(2*(y/Ny-0.5))); break; case 10: r2 = r2*Math.sin(20*r2*nx)>.3*rr; break; case 11: r2 = Math.sin(r2*nx*Math.tan(n4*x/Nx+9*y/Ny))>.6*rr; break; case 12: th = Math.atan2(y-Ny/2,x-Nx/2); r2*=1+0.2*Math.cos(nx*th)*(1+0.6*Math.sin(nx/ny+3*nx*th)*(1+0.6*Math.cos(5*nx*th))); r2*=.72; break; case 13: th = Math.atan2(y+(.3+.4*km[3])*Ny,x-.5*Nx); r2 = Math.sin(10*nx*(x-y)/Nx*PI)*Math.sin((y+x)/Ny*ny*PI+th*ny*nx)>(.2+km[2]*.8)*rr; break; case 14: r2=0.6+.4*rr; } tex0[4*i] = Math.floor(rnd()*255*(r2)); tex0[4*i+1] = Math.floor(rnd()*255*(1-r2) ); tex0[4*i+2] = Math.floor(rnd()*255*(1-r2) ); tex0[4*i+3] = Math.floor(rnd()*255*(r2) ); } } dzc=0; dzp=dzc; let loc_a,loc_ac,loc_img,loc_img00,loc_res,loc_t,loc_rand,loc_palc,loc_kp,loc_km,loc_kl,loc_kv,loc_kw,loc_imgc,loc_imgc2,loc_resc,loc_Lc,loc_tc,loc_randc,loc_aavg,loc_bavg,loc_dxy,loc_dxyc,loc_rc,loc_rcc; function thrower(prog) { if (!gl.getProgramParameter(prog, gl.LINK_STATUS)) { console.log(`Link failed:\n${gl.getProgramInfoLog(prog)}`); console.log(`VS LOG:\n${gl.getShaderInfoLog(vs)}`); console.log(`FS LOG:\n${gl.getShaderInfoLog(fs)}`); throw 'AARG DED'; } } simp = gl.createProgram(); // simulation program vs = Shader(gl.VERTEX_SHADER, src_vert); fs = Shader(gl.FRAGMENT_SHADER, src_simp); gl.attachShader(simp, vs); gl.attachShader(simp, fs); gl.linkProgram(simp); gl.useProgram(simp); thrower(simp); function gul(pr,lab) { return gl.getUniformLocation(pr,lab); } loc_img=gul(simp,'img'); loc_img00=gul(simp,'img00'); loc_res=gul(simp,'res'); loc_t =gul(simp,'t'); loc_rand =gul(simp,'rand'); loc_kp =gul(simp,'kp'); loc_km =gul(simp,'km'); loc_kl =gul(simp,'kl'); loc_dxy =gul(simp,'dxy'); loc_rc =gul(simp,'rc'); gl.uniform1i(loc_img,0); gl.uniform1i(loc_img00,1); gl.uniform2f(loc_res,Nx,Ny); loc_a = gl.getAttribLocation(simp, "a"); gl.activeTexture(gl.TEXTURE0); gl.vertexAttribPointer(loc_a, 2, gl.FLOAT, false, 0, 0); gl.enableVertexAttribArray(loc_a); colp = gl.createProgram(); // colour program vs = Shader(gl.VERTEX_SHADER, src_vert); fs = Shader(gl.FRAGMENT_SHADER, src_colp); gl.attachShader(colp, vs); gl.attachShader(colp, fs); gl.linkProgram(colp); gl.useProgram(colp); thrower(colp); loc_imgc=gul(colp,'img'); loc_imgc2=gul(colp,'img2'); loc_palc=gul(colp,'pal'); loc_resc=gul(colp,'res'); loc_Lc=gul(colp,'L'); loc_tc =gul(colp,'t'); loc_randc =gul(colp,'rand'); loc_dxyc =gul(colp,'dxy'); loc_rcc =gul(colp,'rc'); gl.bindBuffer(gl.ARRAY_BUFFER, gl.createBuffer()); gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([-1.0, 1.0, 1.0, 1.0, 1.0, -1.0, -1.0, 1.0, 1.0, -1.0, -1.0, -1.0]),gl.STATIC_DRAW); gl.uniform1i(loc_imgc,0); gl.uniform1i(loc_imgc2,2); gl.uniform2f(loc_resc,Nx,Ny); loc_ac = gl.getAttribLocation(colp, "a"); //'a'); gl.activeTexture(gl.TEXTURE0); gl.vertexAttribPointer(loc_ac, 2, gl.FLOAT, false, 0, 0); gl.enableVertexAttribArray(loc_ac);
let useA,prngA,prngB; class Random { constructor() { useA = false; let sfc32 = function (uint128Hex) { let a = parseInt(uint128Hex.substr(0, 8), 16); let b = parseInt(uint128Hex.substr(8, 8), 16); let c = parseInt(uint128Hex.substr(16, 8), 16); let d = parseInt(uint128Hex.substr(24, 8), 16); return function () { 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; }; }; // seed prngA with first half of tokenData.hash prngA = new sfc32(tokenData.hash.substr(2, 32)); // seed prngB with second half of tokenData.hash prngB = new sfc32(tokenData.hash.substr(34, 32)); for (let i = 0; i < 1e6; i += 2) { prngA(); prngB(); } } random_dec() { useA = !useA; return useA ? prngA() : prngB(); } } function rnd() { return R.random_dec() } function vecscl(v,k) { let w=[]; for (let i=0; i<v.length; i++) { w[i] = v[i]*k; } return w } function clamp(x) { return Math.max(0,Math.min(1,x)); } function dot2(x,y) { return x[0]*y[0]+x[1]*y[1]; } R = new Random(); let C,D,body,gl,Shader; document.body.style.backgroundColor = "#030303"; console.log("Calian by Eric De Giuli"); C=({body}=D=document).createElement('canvas'); body.appendChild(C); gl=C.getContext('webgl2'); Shader=(typ,src)=>{ const s =gl.createShader(typ); gl.shaderSource(s,src); gl.compileShader(s); if (!gl.getShaderParameter(s, gl.COMPILE_STATUS)) { console.error(`Error compiling ${typ === gl.VERTEX_SHADER ? "vertex" : "fragment"} shader "${src}":`); console.log(gl.getShaderInfoLog(s)); } return s; } var GET = {}; var query = window.location.search.substring(1).split("&"); for (var i = 0, max = query.length; i < max; i++) { if (query[i] === "") continue; var param = query[i].split("="); GET[decodeURIComponent(param[0])] = decodeURIComponent(param[1] || ""); } let simp,colp,vs,fs; let Lx,Ly,Nx,Ny; Nx = 512;if (GET.N) { Nx=GET.N; } Ny=Nx; const head = /\bHeadlessChrome\//.test(navigator.userAgent); let PI = 3.1415926; let pal,pj,inv; let palp = [3,5,3,4,1,2,4,4,1,3,2,2,4,2,3,3]; palp = vecscl(palp,1/46); let cumpal = []; cumpal[0]=0; for (let i=1; i<palp.length; i++) { cumpal[i]=cumpal[i-1]+palp[i-1]; } let st = 1; pj=1; let palr = rnd(); while (st<palp.length && cumpal[st]<palr) { st++; } st--; let pj2 = Math.floor(11*rnd()); inv=0; switch(st) { case 0: pj=6;pj2=7; break; // embers in half light case 1: pj=11;pj2=7; break; // liquid circuit case 2: pj=1;pj2=5; break; // alpenglow case 3: pj=1;pj2=0; break; // zabriskie point case 4: pj=3;pj2=9; break; // aurum case 5: pj=6;pj2=0; break; // tunguska case 6: pj=5;pj2=7; break; // nocturne case 7: pj=11;pj2=5; break; // kind of blue case 8: pj=11;pj2=4; break; // inferno case 9: pj=11;pj2=0; break; // constellation case 10: pj=0;pj2=0;inv=1; break; // white heat case 11: pj=3;pj2=3;inv=1; break; // calanque case 12: pj=2;pj2=0; break; // bouquet case 13: pj=2;pj2=10; break; // spectral case 14: pj=10;pj2=8; break; // the forest path to the spring case 15: pj=10;pj2=4; break; // abalone } pal = new Uint8Array(10*4*2); for (let k=0; k<11; k++) { // which colour in palette for (let k2=0; k2<2; k2++) { // which palette let pp = (k2==0) ? pj : pj2; let kk = Math.min(k,pals[pp].length-1); pal[3*k+3*10*k2] = pals[pp][kk][0]; pal[3*k+3*10*k2+1] = pals[pp][kk][1]; pal[3*k+3*10*k2+2] = pals[pp][kk][2]; if (inv) { pal[3*k+3*10*k2] = (pal[3*k+3*10*k2]+180)%360; } //invert colour } } let kp,km,kv,kw,kl,rand; rand = []; for (let i=0; i<Nrand; i++) { rand[i]=rnd(); } let k0=1; let kl0=0.001; kp = new Float32Array(N); km = new Float32Array(N); kl = new Float32Array(N); switch(st) { case 0: kp = [0.66, 0.95, 0.94, 0.037, 0.89, 0.26, 0.90, 0.94, 0.65, 0.76, 0.54, 0.11, 0.50, 0.66, 0.96, 0.74, 0.91, 0.33, 0.15, 0.85]; break; case 1: kp = [0.97, 0.01, 0.89, 0.08, 0.78, 0.98, 0.16, 0.80, 0.53, 0.91, 0.40, 0.54, 0.84, 0.44, 0.14, 0.75, 0.45, 0.33, 0.47, 0.95]; break; case 2: kp = [0.72, 0.85, 0.51, 0.08, 0.98, 0.29, 0.91, 0.19, 0.69, 0.24, 0.99, 0.32, 0.84, 0.03, 0.97, 0.14, 0.09, 0.04, 0.08, 0.26]; break; case 3: kp = [0.14, 0.95, 0.24, 0.09, 0.05, 0.18, 0.96, 0.04, 0.47, 0.18, 0.13, 0.38, 0.21, 0.85, 0.66, 0.05, 0.15, 0.23, 0.25, 0.48]; break; case 4: kp = [0.58, 0.02, 0.03, 0.84, 0.43, 0.40, 0.95, 0.76, 0.15, 0.55, 0.04, 0.49, 0.49, 0.55, 0.52, 0.07, 0.22, 0.16, 0.31, 0.37]; break; case 5: kp = [0.21, 0.10, 0.21, 0.13, 0.07, 0.42, 0.26, 0.77, 0.28, 0.67, 0.79, 0.10, 0.28, 0.20, 0.04, 0.21, 0.35, 0.125, 0.75, 0.87]; break; case 6: kp = [0.40, 0.28, 0.88, 0.36, 0.92, 0.96, 0.79, 0.24, 0.99, 0.73, 0.68, 0.03, 0.09, 0.52, 0.11, 0.29, 0.95, 0.01, 0.01, 0.62]; break; case 7: kp = [0.10, 0.27, 0.31, 0.05, 0.40, 0.24, 0.67, 0.00, 0.02, 0.92, 0.75, 0.11, 0.40, 0.55, 0.97, 0.45, 0.12, 0.15, 0.54, 0.56]; break; case 8: kp = [0.17, 0.81, 0.64, 0.19, 0.52, 0.27, 0.59, 0.11, 0.65, 0.87, 0.36, 0.17, 0.66, 0.10, 0.95, 0.08, 0.50, 0.43, 0.92, 0.13]; break; case 9: kp = [0.59, 0.56, 0.03, 0.14, 0.58, 0.05, 0.80, 0.00, 0.09, 0.75, 0.80, 0.55, 0.07, 0.27, 0.46, 0.08, 0.35, 0.01, 0.17, 0.63]; break; case 10: kp = [0.021, 0.68, 0.20, 0.04, 0.46, 0.40, 0.30, 0.76, 0.19, 0.20, 0.78, 0.50, 0.10, 0.58, 0.61, 0.13, 0.25, 0.39, 0.63, 0.38]; break; case 11: kp = [0.11, 0.18, 0.02, 0.15, 0.49, 0.90, 0.73, 0.77, 0.69, 0.93, 0.95, 0.76, 0.78, 0.32, 0.13, 0.70, 0.07, 0.04, 0.30, 0.76]; break; case 12: kp = [0.15, 0.27, 0.17, 0.11, 0.61, 0.44, 0.65, 0.21, 0.82, 0.79, 0.40, 0.33, 0.43, 0.22, 0.02, 0.07, 0.50, 0.13, 0.95, 0.34]; break; case 13: kp = [0.89, 0.46, 0.48, 0.30, 0.38, 0.18, 0.13, 0.68, 0.20, 0.87, 0.92, 0.56, 0.06, 0.25, 0.32, 0.10, 0.05, 0.11, 0.31, 0.55]; break; case 14: kp = [0.90, 0.025, 0.064, 0.439, 0.208, 0.154, 0.261, 0.085, 0.268, 0.917, 0.780, 0.709, 0.087, 0.068, 0.684, 0.057, 0.480, 0.282, 0.174, 0.819]; break; case 15: kp = [0.81, 0.79, 0.38, 0.80, 0.19, 0.22, 0.39, 0.047, 0.82, 0.98, 0.90, 0.28, 0.12, 0.24, 0.12, 0.69, 0.62, 0.20, 0.99, 0.71]; break; } for (let i=0; i<N; i++) { km[i]=k0*rnd(); } for (let i=0; i<N; i++) { kl[i]=kl0*rnd(); } if (km[0]<0.15*k0 && st!=10 && st!=3 && st!=1) { kp[15]=0.69;kp[16]=1.34; } let nx = 2+Math.floor(8*rnd()); let ny = 2+Math.floor(8*rnd()); let rr = rnd(); let n4 = Math.floor(Math.exp(4*rnd())); let rbg = Math.floor(15*rnd()); // initial conditions const tex0 = new Uint8Array(Nx*Ny*4); let th; for (let x = 0; x < Nx; x++) { for (let y = 0; y < Ny; y++) { let i = x+Nx*y; let r2 = (x-Nx/2)**2+(y-Ny/2)**2; r2/=(Nx*Nx+Ny*Ny)/4; switch(rbg) { case 0: r2 = Math.sin(x/nx)*Math.sin(y/ny)*Math.sin(25*r2)>.1+.5*rr; break; case 1: r2 = Math.sin(x/Nx*nx*PI)*Math.sin(y/Ny*ny*PI)*Math.sin(25*r2)>0.5*rr; break; case 2: r2 = Math.sin(y*x/Nx*nx*PI)*Math.sin(y/Ny*ny*PI)*Math.sin(25*r2)>0.5*rr; break; case 3: r2 = Math.sin(y*x/Nx*nx*PI)*Math.sin(y/Ny*ny*PI)*Math.sin(2*(x-Nx/2)/(y-Ny/2)+1*(y-Ny/2)/(x-Nx/2))>0.5*rr; break; case 4: r2 = Math.sin(Math.sin(x/Nx*n4)*y/Ny*nx*PI)*Math.sin(y/Ny*ny*PI)*Math.sin(2*(x-Nx/2)/(y-Ny/2)+1*(y-Ny/2)/(x-Nx/2))>0.5*rr; break; case 5: r2 = Math.sin(Math.sin(x/Nx*n4*PI)*y/Ny*(1-y/Ny)*ny*PI)*Math.sin(x/Nx*nx*PI)>0.6*rr; break; case 6: r2 = Math.sin(Math.sin(y/Ny*n4*PI)*x/Nx*(1-x/Nx)*nx*PI)*Math.sin(y/Ny*ny*PI)>0.6*rr; break; case 7: r2 = Math.sin(30*x/Nx*nx*PI)*Math.sin(x/Nx*nx*PI)>0.6*rr; break; case 8: r2 = Math.sin(30*x/Nx*nx*PI)*Math.sin(y/Ny*ny*PI)>0.6*rr; break; case 9: r2 *= .7*(Math.sin(20*(x/Nx-0.5)*nx)+Math.sin(2*(y/Ny-0.5))); break; case 10: r2 = r2*Math.sin(20*r2*nx)>.3*rr; break; case 11: r2 = Math.sin(r2*nx*Math.tan(n4*x/Nx+9*y/Ny))>.6*rr; break; case 12: th = Math.atan2(y-Ny/2,x-Nx/2); r2*=1+0.2*Math.cos(nx*th)*(1+0.6*Math.sin(nx/ny+3*nx*th)*(1+0.6*Math.cos(5*nx*th))); r2*=.72; break; case 13: th = Math.atan2(y+(.3+.4*km[3])*Ny,x-.5*Nx); r2 = Math.sin(10*nx*(x-y)/Nx*PI)*Math.sin((y+x)/Ny*ny*PI+th*ny*nx)>(.2+km[2]*.8)*rr; break; case 14: r2=0.6+.4*rr; } tex0[4*i] = Math.floor(rnd()*255*(r2)); tex0[4*i+1] = Math.floor(rnd()*255*(1-r2) ); tex0[4*i+2] = Math.floor(rnd()*255*(1-r2) ); tex0[4*i+3] = Math.floor(rnd()*255*(r2) ); } } dzc=0; dzp=dzc; let loc_a,loc_ac,loc_img,loc_img00,loc_res,loc_t,loc_rand,loc_palc,loc_kp,loc_km,loc_kl,loc_kv,loc_kw,loc_imgc,loc_imgc2,loc_resc,loc_Lc,loc_tc,loc_randc,loc_aavg,loc_bavg,loc_dxy,loc_dxyc,loc_rc,loc_rcc; function thrower(prog) { if (!gl.getProgramParameter(prog, gl.LINK_STATUS)) { console.log(`Link failed:\n${gl.getProgramInfoLog(prog)}`); console.log(`VS LOG:\n${gl.getShaderInfoLog(vs)}`); console.log(`FS LOG:\n${gl.getShaderInfoLog(fs)}`); throw 'AARG DED'; } } simp = gl.createProgram(); // simulation program vs = Shader(gl.VERTEX_SHADER, src_vert); fs = Shader(gl.FRAGMENT_SHADER, src_simp); gl.attachShader(simp, vs); gl.attachShader(simp, fs); gl.linkProgram(simp); gl.useProgram(simp); thrower(simp); function gul(pr,lab) { return gl.getUniformLocation(pr,lab); } loc_img=gul(simp,'img'); loc_img00=gul(simp,'img00'); loc_res=gul(simp,'res'); loc_t =gul(simp,'t'); loc_rand =gul(simp,'rand'); loc_kp =gul(simp,'kp'); loc_km =gul(simp,'km'); loc_kl =gul(simp,'kl'); loc_dxy =gul(simp,'dxy'); loc_rc =gul(simp,'rc'); gl.uniform1i(loc_img,0); gl.uniform1i(loc_img00,1); gl.uniform2f(loc_res,Nx,Ny); loc_a = gl.getAttribLocation(simp, "a"); gl.activeTexture(gl.TEXTURE0); gl.vertexAttribPointer(loc_a, 2, gl.FLOAT, false, 0, 0); gl.enableVertexAttribArray(loc_a); colp = gl.createProgram(); // colour program vs = Shader(gl.VERTEX_SHADER, src_vert); fs = Shader(gl.FRAGMENT_SHADER, src_colp); gl.attachShader(colp, vs); gl.attachShader(colp, fs); gl.linkProgram(colp); gl.useProgram(colp); thrower(colp); loc_imgc=gul(colp,'img'); loc_imgc2=gul(colp,'img2'); loc_palc=gul(colp,'pal'); loc_resc=gul(colp,'res'); loc_Lc=gul(colp,'L'); loc_tc =gul(colp,'t'); loc_randc =gul(colp,'rand'); loc_dxyc =gul(colp,'dxy'); loc_rcc =gul(colp,'rc'); gl.bindBuffer(gl.ARRAY_BUFFER, gl.createBuffer()); gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([-1.0, 1.0, 1.0, 1.0, 1.0, -1.0, -1.0, 1.0, 1.0, -1.0, -1.0, -1.0]),gl.STATIC_DRAW); gl.uniform1i(loc_imgc,0); gl.uniform1i(loc_imgc2,2); gl.uniform2f(loc_resc,Nx,Ny); loc_ac = gl.getAttribLocation(colp, "a"); //'a'); gl.activeTexture(gl.TEXTURE0); gl.vertexAttribPointer(loc_ac, 2, gl.FLOAT, false, 0, 0); gl.enableVertexAttribArray(loc_ac);
let M=1; var isMobile = window.matchMedia("(hover: none)").matches; // no hovering function resize_render() { let w=innerWidth, h=innerHeight, dpr=devicePixelRatio; C.width = M*w*dpr|0; C.height = M*h*dpr|0; if (head || f1==1) { Lx = Math.min(C.width,C.height); Ly=Lx; } else if (f1==2 || isMobile) { Lx = C.width; Ly=C.height; if (Lx>Ly) { Lx=Math.min(Lx,2.5*Ly); } if (Ly>Lx) { Ly=Math.min(Ly,2.5*Lx); } } else { Lx = Math.min(3*Nx,C.width); Ly = Math.min(3*Ny,C.height); } C.style.width = w+'px'; C.style.height = h+'px'; gl.viewport((C.width-Lx)/2,(C.height-Ly)/2,Lx,Ly); render(); } function texset(wrap) { gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, wrap); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, wrap); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR); } let tex00,texA,texB,texC,fbA,fbB; let wrap = gl.REPEAT; tex00 = gl.createTexture(); gl.bindTexture(gl.TEXTURE_2D, tex00); gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, Nx, Ny, 0, gl.RGBA, gl.UNSIGNED_BYTE, tex0.subarray(0, Nx*Ny*4)); texset(wrap); texA = gl.createTexture(); gl.bindTexture(gl.TEXTURE_2D, texA); gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, Nx, Ny, 0, gl.RGBA, gl.UNSIGNED_BYTE, tex0.subarray(0, Nx*Ny*4)); fbA = gl.createFramebuffer(); gl.bindFramebuffer(gl.FRAMEBUFFER, fbA); gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texA, 0); texset(wrap); texB = gl.createTexture(); gl.bindTexture(gl.TEXTURE_2D, texB); gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, Nx, Ny, 0, gl.RGBA, gl.UNSIGNED_BYTE, null); fbB = gl.createFramebuffer(); gl.bindFramebuffer(gl.FRAMEBUFFER, fbB); gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texB, 0); texset(wrap); texC = gl.createTexture(); //colormap gl.bindTexture(gl.TEXTURE_2D, texC); gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB, 10, 2, 0, gl.RGB, gl.UNSIGNED_BYTE, pal); texset(wrap); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAX_LEVEL, 0); gl.useProgram(colp); gl.uniform1i(loc_palc, 1); //texture 1 // and assign uniforms gl.useProgram(simp); gl.uniform1fv(loc_km,km); gl.uniform1fv(loc_kl,kl); gl.uniform1fv(loc_rand,rand); gl.useProgram(colp); gl.uniform1fv(loc_randc,rand); let prevt=performance.now(); let dt = 1000/60; let running=true; let periodic=0; let anim=0; let flip=0; let count=0; let dxycount=0; let TT = 120; let om0 = 0.01, A=0.002; function render() { if (running) { count++; let time=performance.now(); if (time-prevt>dt) { gl.viewport(0,0,Nx,Ny); gl.useProgram(simp); if (count%TT==0) { for (let i=0; i<Nrand; i++) { rand[i]=.7*rnd()+.3*rand[i]; } gl.uniform1fv(loc_rand,rand); } if (dxycount==0) { dx=dxc-dxp; dy=dyc-dyp; dz=dzc-dzp; zc *= 1+2*dz; xc -= (.5+(2*dx-0.5)*(1+2*dz))*zc; yc -= (.5+(2*dy-0.5)*(1+2*dz))*zc; kp[0]+= dx/3; kp[1]+= dy/3; kp[15]*=Math.exp(dx/3); kp[16]*=Math.exp(dy/3); } gl.uniform1fv(loc_kp,kp); if (dx!=0 || dy!=0 || dz!=0) { dxycount++; } gl.uniform3fv(loc_dxy,[dx, dy, dz]); gl.uniform3fv(loc_rc,[xc, yc, zc]); gl.uniform1i(loc_t,time); for (let j=0; j<2; j++) { flip = !flip; gl.bindFramebuffer(gl.FRAMEBUFFER, (flip ? fbB : fbA)); gl.activeTexture(gl.TEXTURE0); gl.bindTexture(gl.TEXTURE_2D, (flip ? texA : texB)); gl.activeTexture(gl.TEXTURE1); gl.bindTexture(gl.TEXTURE_2D, tex00); gl.drawArrays(gl.TRIANGLES, 0, 6); } gl.viewport((C.width-Lx)/2,(C.height-Ly)/2,Lx,Ly); gl.useProgram(colp); gl.uniform1i(loc_tc,time); gl.uniform2f(loc_Lc,Lx,Ly); gl.uniform3fv(loc_dxyc,[dx, dy, dz]); gl.uniform3fv(loc_rcc,[xc, yc, zc]); if (dxycount>=1) { dxycount=0; dx=0;dy=0;dz=0; dxp=dxc;dyp=dyc;dzp=dzc; } gl.bindFramebuffer(gl.FRAMEBUFFER, null); gl.activeTexture(gl.TEXTURE0); gl.bindTexture(gl.TEXTURE_2D, (flip ? texB : texA)); gl.activeTexture(gl.TEXTURE1); gl.bindTexture(gl.TEXTURE_2D, texC); //color map gl.activeTexture(gl.TEXTURE2); gl.bindTexture(gl.TEXTURE_2D, (flip ? texA : texB)); if (dz==0) gl.drawArrays(gl.TRIANGLES, 0, 6); } prevt=time-(time-prevt)%dt; } // requestAnimationFrame(render.bind()); if (savescr==1) { savescr=2; resize_render(); } if (savescr==2) { savescr=0; var tC = document.createElement("canvas"); tC.width = Lx; tC.height = Ly; var ctx = tC.getContext("2d"); ctx.setTransform(1,0,0,-1,0,gl.height); ctx.drawImage(C,-(C.width-Lx)/2,-(C.height-Ly)/2); tC.toBlob((blob) => { saveBlob(blob, `Calian-${tokenData.tokenId}.png`); }); } requestAnimationFrame(render); } const saveBlob = (function() { const a = document.createElement('a'); document.body.appendChild(a); a.style.display = 'none'; return function saveData(blob, fileName) { const url = window.URL.createObjectURL(blob); a.href = url; a.download = fileName; a.click(); }; }()); // resize event let tid=0; onresize => { clearTimeout(tid); tid=setTimeout(resize_render,150) }; let f1=0,savescr=0; // keyboard event onkeyup=e=>{ if (e.key==' ') { // spacebar running = !running; } if ( window !== window.parent ) { // iframe if (e.keyCode==65) dxc-=0.01; //a = left if (e.keyCode==68) dxc+=0.01; //d = right if (e.keyCode==87) dyc+=0.01; //w = up if (e.keyCode==83) dyc-=0.01; //s = down } else { // not iframe if (e.keyCode==37) dxc-=0.01; //left if (e.keyCode==39) dxc+=0.01; //right if (e.keyCode==38) dyc+=0.01; //up if (e.keyCode==40) dyc-=0.01; //down } if (e.keyCode==88) dzc-=0.03; //x = in if (e.keyCode==90) dzc=Math.min(0,dzc+0.03); //z = out if (e.keyCode==70) { f1=(f1+1)%3; resize_render(); } // f if (e.keyCode==80) { savescr=1; Lx = Ly = min(C.width,C.height); } //p = print screen // dzc+=e.deltaY/Ly; return false; //e.stopPropagation(); e.preventDefault(); } function handler(e) { var scroll = (e.deltaY || -1*e.wheelDelta || 10*e.detail); var isTouchPad = e.wheelDeltaY ? e.wheelDeltaY === -3 * e.deltaY : e.deltaMode === 0; //if ( window == window.parent ) dzc=Math.min(0,dzc+Math.max(-0.03,Math.min(0.03,e.deltaY/Ly*(1+3*isTouchPad)))); dzc=Math.min(0,dzc+.5*Math.max(-0.03,Math.min(0.03,scroll/Ly*(1+3*isTouchPad)))); e.stopPropagation(); e.preventDefault(); return false; } gl.canvas.addEventListener("mousewheel", handler, false); gl.canvas.addEventListener("DOMMouseScroll", handler, false); const delta = 6; let startx; let starty; let mousedown=0; gl.canvas.addEventListener('mousedown', function (e) { mousedown=1; startx = e.clientX; starty = e.clientY; }); gl.canvas.addEventListener('mousemove', function (e) { if (mousedown) { dxc-=.5*(e.clientX-startx)/Lx*Math.exp(-0.1*dzc); dyc+=.5*(e.clientY-starty)/Ly*Math.exp(-0.1*dzc); startx = e.clientX; starty = e.clientY; } }); gl.canvas.addEventListener('mouseleave', function (e) { mousedown=0; }); gl.canvas.addEventListener('mouseup', function (e) { mousedown=0; }); gl.canvas.addEventListener('dblclick', function (e) { running = !running; }); resize_render();
let M=1; var isMobile = window.matchMedia("(hover: none)").matches; // no hovering function resize_render() { let w=innerWidth, h=innerHeight, dpr=devicePixelRatio; C.width = M*w*dpr|0; C.height = M*h*dpr|0; if (head || f1==1) { Lx = Math.min(C.width,C.height); Ly=Lx; } else if (f1==2 || isMobile) { Lx = C.width; Ly=C.height; if (Lx>Ly) { Lx=Math.min(Lx,2.5*Ly); } if (Ly>Lx) { Ly=Math.min(Ly,2.5*Lx); } } else { Lx = Math.min(3*Nx,C.width); Ly = Math.min(3*Ny,C.height); } C.style.width = w+'px'; C.style.height = h+'px'; gl.viewport((C.width-Lx)/2,(C.height-Ly)/2,Lx,Ly); render(); } function texset(wrap) { gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, wrap); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, wrap); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR); } let tex00,texA,texB,texC,fbA,fbB; let wrap = gl.REPEAT; tex00 = gl.createTexture(); gl.bindTexture(gl.TEXTURE_2D, tex00); gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, Nx, Ny, 0, gl.RGBA, gl.UNSIGNED_BYTE, tex0.subarray(0, Nx*Ny*4)); texset(wrap); texA = gl.createTexture(); gl.bindTexture(gl.TEXTURE_2D, texA); gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, Nx, Ny, 0, gl.RGBA, gl.UNSIGNED_BYTE, tex0.subarray(0, Nx*Ny*4)); fbA = gl.createFramebuffer(); gl.bindFramebuffer(gl.FRAMEBUFFER, fbA); gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texA, 0); texset(wrap); texB = gl.createTexture(); gl.bindTexture(gl.TEXTURE_2D, texB); gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, Nx, Ny, 0, gl.RGBA, gl.UNSIGNED_BYTE, null); fbB = gl.createFramebuffer(); gl.bindFramebuffer(gl.FRAMEBUFFER, fbB); gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texB, 0); texset(wrap); texC = gl.createTexture(); //colormap gl.bindTexture(gl.TEXTURE_2D, texC); gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB, 10, 2, 0, gl.RGB, gl.UNSIGNED_BYTE, pal); texset(wrap); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAX_LEVEL, 0); gl.useProgram(colp); gl.uniform1i(loc_palc, 1); //texture 1 // and assign uniforms gl.useProgram(simp); gl.uniform1fv(loc_km,km); gl.uniform1fv(loc_kl,kl); gl.uniform1fv(loc_rand,rand); gl.useProgram(colp); gl.uniform1fv(loc_randc,rand); let prevt=performance.now(); let dt = 1000/60; let running=true; let periodic=0; let anim=0; let flip=0; let count=0; let dxycount=0; let TT = 120; let om0 = 0.01, A=0.002; function render() { if (running) { count++; let time=performance.now(); if (time-prevt>dt) { gl.viewport(0,0,Nx,Ny); gl.useProgram(simp); if (count%TT==0) { for (let i=0; i<Nrand; i++) { rand[i]=.7*rnd()+.3*rand[i]; } gl.uniform1fv(loc_rand,rand); } if (dxycount==0) { dx=dxc-dxp; dy=dyc-dyp; dz=dzc-dzp; zc *= 1+2*dz; xc -= (.5+(2*dx-0.5)*(1+2*dz))*zc; yc -= (.5+(2*dy-0.5)*(1+2*dz))*zc; kp[0]+= dx/3; kp[1]+= dy/3; kp[15]*=Math.exp(dx/3); kp[16]*=Math.exp(dy/3); } gl.uniform1fv(loc_kp,kp); if (dx!=0 || dy!=0 || dz!=0) { dxycount++; } gl.uniform3fv(loc_dxy,[dx, dy, dz]); gl.uniform3fv(loc_rc,[xc, yc, zc]); gl.uniform1i(loc_t,time); for (let j=0; j<2; j++) { flip = !flip; gl.bindFramebuffer(gl.FRAMEBUFFER, (flip ? fbB : fbA)); gl.activeTexture(gl.TEXTURE0); gl.bindTexture(gl.TEXTURE_2D, (flip ? texA : texB)); gl.activeTexture(gl.TEXTURE1); gl.bindTexture(gl.TEXTURE_2D, tex00); gl.drawArrays(gl.TRIANGLES, 0, 6); } gl.viewport((C.width-Lx)/2,(C.height-Ly)/2,Lx,Ly); gl.useProgram(colp); gl.uniform1i(loc_tc,time); gl.uniform2f(loc_Lc,Lx,Ly); gl.uniform3fv(loc_dxyc,[dx, dy, dz]); gl.uniform3fv(loc_rcc,[xc, yc, zc]); if (dxycount>=1) { dxycount=0; dx=0;dy=0;dz=0; dxp=dxc;dyp=dyc;dzp=dzc; } gl.bindFramebuffer(gl.FRAMEBUFFER, null); gl.activeTexture(gl.TEXTURE0); gl.bindTexture(gl.TEXTURE_2D, (flip ? texB : texA)); gl.activeTexture(gl.TEXTURE1); gl.bindTexture(gl.TEXTURE_2D, texC); //color map gl.activeTexture(gl.TEXTURE2); gl.bindTexture(gl.TEXTURE_2D, (flip ? texA : texB)); if (dz==0) gl.drawArrays(gl.TRIANGLES, 0, 6); } prevt=time-(time-prevt)%dt; } // requestAnimationFrame(render.bind()); if (savescr==1) { savescr=2; resize_render(); } if (savescr==2) { savescr=0; var tC = document.createElement("canvas"); tC.width = Lx; tC.height = Ly; var ctx = tC.getContext("2d"); ctx.setTransform(1,0,0,-1,0,gl.height); ctx.drawImage(C,-(C.width-Lx)/2,-(C.height-Ly)/2); tC.toBlob((blob) => { saveBlob(blob, `Calian-${tokenData.tokenId}.png`); }); } requestAnimationFrame(render); } const saveBlob = (function() { const a = document.createElement('a'); document.body.appendChild(a); a.style.display = 'none'; return function saveData(blob, fileName) { const url = window.URL.createObjectURL(blob); a.href = url; a.download = fileName; a.click(); }; }()); // resize event let tid=0; onresize => { clearTimeout(tid); tid=setTimeout(resize_render,150) }; let f1=0,savescr=0; // keyboard event onkeyup=e=>{ if (e.key==' ') { // spacebar running = !running; } if ( window !== window.parent ) { // iframe if (e.keyCode==65) dxc-=0.01; //a = left if (e.keyCode==68) dxc+=0.01; //d = right if (e.keyCode==87) dyc+=0.01; //w = up if (e.keyCode==83) dyc-=0.01; //s = down } else { // not iframe if (e.keyCode==37) dxc-=0.01; //left if (e.keyCode==39) dxc+=0.01; //right if (e.keyCode==38) dyc+=0.01; //up if (e.keyCode==40) dyc-=0.01; //down } if (e.keyCode==88) dzc-=0.03; //x = in if (e.keyCode==90) dzc=Math.min(0,dzc+0.03); //z = out if (e.keyCode==70) { f1=(f1+1)%3; resize_render(); } // f if (e.keyCode==80) { savescr=1; Lx = Ly = min(C.width,C.height); } //p = print screen // dzc+=e.deltaY/Ly; return false; //e.stopPropagation(); e.preventDefault(); } function handler(e) { var isTouchPad = e.wheelDeltaY ? e.wheelDeltaY === -3 * e.deltaY : e.deltaMode === 0; //if ( window == window.parent ) dzc=Math.min(0,dzc+Math.max(-0.03,Math.min(0.03,e.deltaY/Ly*(1+3*isTouchPad)))); dzc=Math.min(0,dzc+.5*Math.max(-0.03,Math.min(0.03,e.deltaY/Ly*(1+3*isTouchPad)))); e.stopPropagation(); e.preventDefault(); return false; } gl.canvas.addEventListener("mousewheel", handler, false); gl.canvas.addEventListener("DOMMouseScroll", handler, false); const delta = 6; let startx; let starty; let mousedown=0; gl.canvas.addEventListener('mousedown', function (e) { mousedown=1; startx = e.clientX; starty = e.clientY; }); gl.canvas.addEventListener('mousemove', function (e) { if (mousedown) { dxc-=.5*(e.clientX-startx)/Lx*Math.exp(-0.1*dzc); dyc+=.5*(e.clientY-starty)/Ly*Math.exp(-0.1*dzc); startx = e.clientX; starty = e.clientY; } }); gl.canvas.addEventListener('mouseleave', function (e) { mousedown=0; }); gl.canvas.addEventListener('mouseup', function (e) { mousedown=0; }); gl.canvas.addEventListener('dblclick', function (e) { running = !running; }); resize_render();
let M=1; var isMobile = window.matchMedia("(hover: none)").matches; // no hovering function resize_render() { let w=innerWidth, h=innerHeight, dpr=devicePixelRatio; C.width = M*w*dpr|0; C.height = M*h*dpr|0; if (head || f1==1) { Lx = Math.min(C.width,C.height); Ly=Lx; } else if (f1==2 || isMobile) { Lx = C.width; Ly=C.height; if (Lx>Ly) { Lx=Math.min(Lx,2.5*Ly); } if (Ly>Lx) { Ly=Math.min(Ly,2.5*Lx); } } else { Lx = Math.min(3*Nx,C.width); Ly = Math.min(3*Ny,C.height); } C.style.width = w+'px'; C.style.height = h+'px'; gl.viewport((C.width-Lx)/2,(C.height-Ly)/2,Lx,Ly); render(); } function texset(wrap) { gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, wrap); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, wrap); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR); } let tex00,texA,texB,texC,fbA,fbB; let wrap = gl.REPEAT; tex00 = gl.createTexture(); gl.bindTexture(gl.TEXTURE_2D, tex00); gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, Nx, Ny, 0, gl.RGBA, gl.UNSIGNED_BYTE, tex0.subarray(0, Nx*Ny*4)); texset(wrap); texA = gl.createTexture(); gl.bindTexture(gl.TEXTURE_2D, texA); gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, Nx, Ny, 0, gl.RGBA, gl.UNSIGNED_BYTE, tex0.subarray(0, Nx*Ny*4)); fbA = gl.createFramebuffer(); gl.bindFramebuffer(gl.FRAMEBUFFER, fbA); gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texA, 0); texset(wrap); texB = gl.createTexture(); gl.bindTexture(gl.TEXTURE_2D, texB); gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, Nx, Ny, 0, gl.RGBA, gl.UNSIGNED_BYTE, null); fbB = gl.createFramebuffer(); gl.bindFramebuffer(gl.FRAMEBUFFER, fbB); gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texB, 0); texset(wrap); texC = gl.createTexture(); //colormap gl.bindTexture(gl.TEXTURE_2D, texC); gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB, 10, 2, 0, gl.RGB, gl.UNSIGNED_BYTE, pal); texset(wrap); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAX_LEVEL, 0); gl.useProgram(colp); gl.uniform1i(loc_palc, 1); //texture 1 // and assign uniforms gl.useProgram(simp); gl.uniform1fv(loc_km,km); gl.uniform1fv(loc_kl,kl); gl.uniform1fv(loc_rand,rand); gl.useProgram(colp); gl.uniform1fv(loc_randc,rand); let prevt=performance.now(); let dt = 1000/60; let running=true; let periodic=0; let anim=0; let flip=0; let count=0; let dxycount=0; let TT = 120; let om0 = 0.01, A=0.002; function render() { if (running) { count++; let time=performance.now(); if (time-prevt>dt) { gl.viewport(0,0,Nx,Ny); gl.useProgram(simp); if (count%TT==0) { for (let i=0; i<Nrand; i++) { rand[i]=.7*rnd()+.3*rand[i]; } gl.uniform1fv(loc_rand,rand); } if (dxycount==0) { dx=dxc-dxp; dy=dyc-dyp; dz=dzc-dzp; zc *= 1+2*dz; xc -= (.5+(2*dx-0.5)*(1+2*dz))*zc; yc -= (.5+(2*dy-0.5)*(1+2*dz))*zc; kp[0]+= dx/3; kp[1]+= dy/3; kp[15]*=Math.exp(dx/3); kp[16]*=Math.exp(dy/3); } gl.uniform1fv(loc_kp,kp); if (dx!=0 || dy!=0 || dz!=0) { dxycount++; } gl.uniform3fv(loc_dxy,[dx, dy, dz]); gl.uniform3fv(loc_rc,[xc, yc, zc]); gl.uniform1i(loc_t,time); flip = !flip; gl.bindFramebuffer(gl.FRAMEBUFFER, (flip ? fbB : fbA)); gl.activeTexture(gl.TEXTURE0); gl.bindTexture(gl.TEXTURE_2D, (flip ? texA : texB)); gl.activeTexture(gl.TEXTURE1); gl.bindTexture(gl.TEXTURE_2D, tex00); gl.drawArrays(gl.TRIANGLES, 0, 6); gl.viewport((C.width-Lx)/2,(C.height-Ly)/2,Lx,Ly); gl.useProgram(colp); gl.uniform1i(loc_tc,time); gl.uniform2f(loc_Lc,Lx,Ly); gl.uniform3fv(loc_dxyc,[dx, dy, dz]); gl.uniform3fv(loc_rcc,[xc, yc, zc]); if (dxycount>=2) { dxycount=0; dx=0;dy=0;dz=0; dxp=dxc;dyp=dyc;dzp=dzc; } gl.bindFramebuffer(gl.FRAMEBUFFER, null); gl.activeTexture(gl.TEXTURE0); gl.bindTexture(gl.TEXTURE_2D, (flip ? texB : texA)); gl.activeTexture(gl.TEXTURE1); gl.bindTexture(gl.TEXTURE_2D, texC); //color map gl.activeTexture(gl.TEXTURE2); gl.bindTexture(gl.TEXTURE_2D, (flip ? texA : texB)); if (dz==0) gl.drawArrays(gl.TRIANGLES, 0, 6); } prevt=time-(time-prevt)%dt; } // requestAnimationFrame(render.bind()); if (savescr==1) { savescr=2; resize_render(); } if (savescr==2) { savescr=0; var tC = document.createElement("canvas"); tC.width = Lx; tC.height = Ly; var ctx = tC.getContext("2d"); ctx.setTransform(1,0,0,-1,0,gl.height); ctx.drawImage(C,-(C.width-Lx)/2,-(C.height-Ly)/2); tC.toBlob((blob) => { saveBlob(blob, `Calian-${tokenData.tokenId}.png`); }); } requestAnimationFrame(render); } const saveBlob = (function() { const a = document.createElement('a'); document.body.appendChild(a); a.style.display = 'none'; return function saveData(blob, fileName) { const url = window.URL.createObjectURL(blob); a.href = url; a.download = fileName; a.click(); }; }()); // resize event let tid=0; onresize => { clearTimeout(tid); tid=setTimeout(resize_render,150) }; let f1=0,savescr=0; // keyboard event onkeyup=e=>{ if (e.key==' ') { // spacebar running = !running; } if ( window !== window.parent ) { // iframe if (e.keyCode==65) dxc-=0.01; //a = left if (e.keyCode==68) dxc+=0.01; //d = right if (e.keyCode==87) dyc+=0.01; //w = up if (e.keyCode==83) dyc-=0.01; //s = down } else { // not iframe if (e.keyCode==37) dxc-=0.01; //left if (e.keyCode==39) dxc+=0.01; //right if (e.keyCode==38) dyc+=0.01; //up if (e.keyCode==40) dyc-=0.01; //down } if (e.keyCode==88) dzc-=0.03; //x = in if (e.keyCode==90) dzc=Math.min(0,dzc+0.03); //z = out if (e.keyCode==70) { f1=(f1+1)%3; resize_render(); } // f if (e.keyCode==80) { savescr=1; Lx = Ly = min(C.width,C.height); } //p = print screen // dzc+=e.deltaY/Ly; return false; //e.stopPropagation(); e.preventDefault(); } function handler(e) { var isTouchPad = e.wheelDeltaY ? e.wheelDeltaY === -3 * e.deltaY : e.deltaMode === 0; //if ( window == window.parent ) dzc=Math.min(0,dzc+Math.max(-0.03,Math.min(0.03,e.deltaY/Ly*(1+3*isTouchPad)))); dzc=Math.min(0,dzc+Math.max(-0.03,Math.min(0.03,e.deltaY/Ly*(1+3*isTouchPad)))); e.stopPropagation(); e.preventDefault(); return false; } gl.canvas.addEventListener("mousewheel", handler, false); gl.canvas.addEventListener("DOMMouseScroll", handler, false); const delta = 6; let startx; let starty; let mousedown=0; gl.canvas.addEventListener('mousedown', function (e) { mousedown=1; startx = e.clientX; starty = e.clientY; }); gl.canvas.addEventListener('mousemove', function (e) { if (mousedown) { dxc-=(e.clientX-startx)/Lx*Math.exp(-0.1*dzc); dyc+=(e.clientY-starty)/Ly*Math.exp(-0.1*dzc); startx = e.clientX; starty = e.clientY; } }); gl.canvas.addEventListener('mouseleave', function (e) { mousedown=0; }); gl.canvas.addEventListener('mouseup', function (e) { mousedown=0; }); gl.canvas.addEventListener('dblclick', function (e) { running = !running; }); resize_render();
let M=1; var isMobile = window.matchMedia("(hover: none)").matches; // no hovering function resize_render() { let w=innerWidth, h=innerHeight, dpr=devicePixelRatio; C.width = M*w*dpr|0; C.height = M*h*dpr|0; if (head || f1==1) { Lx = Math.min(C.width,C.height); Ly=Lx; } else if (f1==2 || isMobile) { Lx = C.width; Ly=C.height; if (Lx>Ly) { Lx=Math.min(Lx,2.5*Ly); } if (Ly>Lx) { Ly=Math.min(Ly,2.5*Lx); } } else { Lx = Math.min(3*Nx,C.width); Ly = Math.min(3*Ny,C.height); } C.style.width = w+'px'; C.style.height = h+'px'; gl.viewport((C.width-Lx)/2,(C.height-Ly)/2,Lx,Ly); render(); } function texset(wrap) { gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, wrap); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, wrap); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR); } let tex00,texA,texB,texC,fbA,fbB; let wrap = gl.REPEAT; tex00 = gl.createTexture(); gl.bindTexture(gl.TEXTURE_2D, tex00); gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, Nx, Ny, 0, gl.RGBA, gl.UNSIGNED_BYTE, tex0.subarray(0, Nx*Ny*4)); texset(wrap); texA = gl.createTexture(); gl.bindTexture(gl.TEXTURE_2D, texA); gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, Nx, Ny, 0, gl.RGBA, gl.UNSIGNED_BYTE, tex0.subarray(0, Nx*Ny*4)); fbA = gl.createFramebuffer(); gl.bindFramebuffer(gl.FRAMEBUFFER, fbA); gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texA, 0); texset(wrap); texB = gl.createTexture(); gl.bindTexture(gl.TEXTURE_2D, texB); gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, Nx, Ny, 0, gl.RGBA, gl.UNSIGNED_BYTE, null); fbB = gl.createFramebuffer(); gl.bindFramebuffer(gl.FRAMEBUFFER, fbB); gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texB, 0); texset(wrap); texC = gl.createTexture(); //colormap gl.bindTexture(gl.TEXTURE_2D, texC); gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB, 10, 2, 0, gl.RGB, gl.UNSIGNED_BYTE, pal); texset(wrap); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAX_LEVEL, 0); gl.useProgram(colp); gl.uniform1i(loc_palc, 1); //texture 1 // and assign uniforms gl.useProgram(simp); gl.uniform1fv(loc_km,km); gl.uniform1fv(loc_kl,kl); gl.uniform1fv(loc_rand,rand); gl.useProgram(colp); gl.uniform1fv(loc_randc,rand); let prevt=performance.now(); let dt = 1000/60; let running=true; let periodic=0; let anim=0; let flip=0; let count=0; let dxycount=0; let TT = 120; let om0 = 0.01, A=0.002; function render() { if (running) { count++; let time=performance.now(); if (time-prevt>dt) { gl.viewport(0,0,Nx,Ny); gl.useProgram(simp); if (count%TT==0) { for (let i=0; i<Nrand; i++) { rand[i]=.7*rnd()+.3*rand[i]; } gl.uniform1fv(loc_rand,rand); } if (dxycount==0) { dx=dxc-dxp; dy=dyc-dyp; dz=dzc-dzp; zc *= 1+2*dz; xc -= (.5+(2*dx-0.5)*(1+2*dz))*zc; yc -= (.5+(2*dy-0.5)*(1+2*dz))*zc; kp[0]+= dx/3; kp[1]+= dy/3; kp[15]*=Math.exp(dx/3); kp[16]*=Math.exp(dy/3); } gl.uniform1fv(loc_kp,kp); if (dx!=0 || dy!=0 || dz!=0) { dxycount++; } gl.uniform3fv(loc_dxy,[dx, dy, dz]); gl.uniform3fv(loc_rc,[xc, yc, zc]); gl.uniform1i(loc_t,time); flip = !flip; gl.bindFramebuffer(gl.FRAMEBUFFER, (flip ? fbB : fbA)); gl.activeTexture(gl.TEXTURE0); gl.bindTexture(gl.TEXTURE_2D, (flip ? texA : texB)); gl.activeTexture(gl.TEXTURE1); gl.bindTexture(gl.TEXTURE_2D, tex00); gl.drawArrays(gl.TRIANGLES, 0, 6); gl.viewport((C.width-Lx)/2,(C.height-Ly)/2,Lx,Ly); gl.useProgram(colp); gl.uniform1i(loc_tc,time); gl.uniform2f(loc_Lc,Lx,Ly); gl.uniform3fv(loc_dxyc,[dx, dy, dz]); gl.uniform3fv(loc_rcc,[xc, yc, zc]); if (dxycount>=2) { dxycount=0; dx=0;dy=0;dz=0; dxp=dxc;dyp=dyc;dzp=dzc; } gl.bindFramebuffer(gl.FRAMEBUFFER, null); gl.activeTexture(gl.TEXTURE0); gl.bindTexture(gl.TEXTURE_2D, (flip ? texB : texA)); gl.activeTexture(gl.TEXTURE1); gl.bindTexture(gl.TEXTURE_2D, texC); //color map gl.activeTexture(gl.TEXTURE2); gl.bindTexture(gl.TEXTURE_2D, (flip ? texA : texB)); if (dz==0) gl.drawArrays(gl.TRIANGLES, 0, 6); } prevt=time-(time-prevt)%dt; } // requestAnimationFrame(render.bind()); if (savescr==1) { savescr=2; resize_render(); } if (savescr==2) { savescr=0; var tC = document.createElement("canvas"); tC.width = Lx; tC.height = Ly; var ctx = tC.getContext("2d"); ctx.setTransform(1,0,0,-1,0,gl.height); ctx.drawImage(C,-(C.width-Lx)/2,-(C.height-Ly)/2); tC.toBlob((blob) => { saveBlob(blob, `Calian-${tokenData.tokenId}.png`); }); } requestAnimationFrame(render); } const saveBlob = (function() { const a = document.createElement('a'); document.body.appendChild(a); a.style.display = 'none'; return function saveData(blob, fileName) { const url = window.URL.createObjectURL(blob); a.href = url; a.download = fileName; a.click(); }; }()); // resize event let tid=0; onresize => { clearTimeout(tid); tid=setTimeout(resize_render,150) }; let f1=0,savescr=0; // keyboard event onkeyup=e=>{ if (e.key==' ') { // spacebar running = !running; } if ( window !== window.parent ) { // iframe if (e.keyCode==65) dxc-=0.01; //a = left if (e.keyCode==68) dxc+=0.01; //d = right if (e.keyCode==87) dyc+=0.01; //w = up if (e.keyCode==83) dyc-=0.01; //s = down } else { // not iframe if (e.keyCode==37) dxc-=0.01; //left if (e.keyCode==39) dxc+=0.01; //right if (e.keyCode==38) dyc+=0.01; //up if (e.keyCode==40) dyc-=0.01; //down } if (e.keyCode==88) dzc-=0.03; //x = in if (e.keyCode==90) dzc=Math.min(0,dzc+0.03); //z = out if (e.keyCode==70) { f1=(f1+1)%3; resize_render(); } // f if (e.keyCode==80) { savescr=1; Lx = Ly = min(C.width,C.height); } //p = print screen // dzc+=e.deltaY/Ly; return false; //e.stopPropagation(); e.preventDefault(); } function handler(e) { var isTouchPad = e.wheelDeltaY ? e.wheelDeltaY === -3 * e.deltaY : e.deltaMode === 0; if ( window == window.parent ) dzc=Math.min(0,dzc+Math.max(-0.03,Math.min(0.03,e.deltaY/Ly*(1+3*isTouchPad)))); e.preventDefault(); return false; } gl.canvas.addEventListener("mousewheel", handler, false); gl.canvas.addEventListener("DOMMouseScroll", handler, false); const delta = 6; let startx; let starty; let mousedown=0; gl.canvas.addEventListener('mousedown', function (e) { mousedown=1; startx = e.clientX; starty = e.clientY; }); gl.canvas.addEventListener('mousemove', function (e) { if (mousedown) { dxc-=(e.clientX-startx)/Lx*Math.exp(-0.1*dzc); dyc+=(e.clientY-starty)/Ly*Math.exp(-0.1*dzc); startx = e.clientX; starty = e.clientY; } }); gl.canvas.addEventListener('mouseleave', function (e) { mousedown=0; }); gl.canvas.addEventListener('mouseup', function (e) { mousedown=0; }); gl.canvas.addEventListener('dblclick', function (e) { running = !running; }); resize_render();
let useA,prngA,prngB; class Random { constructor() { useA = false; let sfc32 = function (uint128Hex) { let a = parseInt(uint128Hex.substr(0, 8), 16); let b = parseInt(uint128Hex.substr(8, 8), 16); let c = parseInt(uint128Hex.substr(16, 8), 16); let d = parseInt(uint128Hex.substr(24, 8), 16); return function () { 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; }; }; // seed prngA with first half of tokenData.hash prngA = new sfc32(tokenData.hash.substr(2, 32)); // seed prngB with second half of tokenData.hash prngB = new sfc32(tokenData.hash.substr(34, 32)); for (let i = 0; i < 1e6; i += 2) { prngA(); prngB(); } } random_dec() { useA = !useA; return useA ? prngA() : prngB(); } } function rnd() { return R.random_dec() } function vecscl(v,k) { let w=[]; for (let i=0; i<v.length; i++) { w[i] = v[i]*k; } return w } function clamp(x) { return Math.max(0,Math.min(1,x)); } function dot2(x,y) { return x[0]*y[0]+x[1]*y[1]; } R = new Random(); let C,D,body,gl,Shader; document.body.style.backgroundColor = "#030303"; console.log("Calian by Eric De Giuli"); C=({body}=D=document).createElement('canvas'); body.appendChild(C); gl=C.getContext('webgl2'); Shader=(typ,src)=>{ const s =gl.createShader(typ); gl.shaderSource(s,src); gl.compileShader(s); if (!gl.getShaderParameter(s, gl.COMPILE_STATUS)) { console.error(`Error compiling ${typ === gl.VERTEX_SHADER ? "vertex" : "fragment"} shader "${src}":`); console.log(gl.getShaderInfoLog(s)); } return s; } var GET = {}; var query = window.location.search.substring(1).split("&"); for (var i = 0, max = query.length; i < max; i++) { if (query[i] === "") continue; var param = query[i].split("="); GET[decodeURIComponent(param[0])] = decodeURIComponent(param[1] || ""); } let simp,colp,vs,fs; let Lx,Ly,Nx,Ny; Nx = 512;if (GET.N) { Nx=GET.N; } Ny=Nx; const head = /\bHeadlessChrome\//.test(navigator.userAgent); let PI = 3.1415926; let pal,pj,inv; let palp = [3,5,3,4,1,2,4,4,1,3,2,2,4,2,3,3]; palp = vecscl(palp,1/46); let cumpal = []; cumpal[0]=0; for (let i=1; i<palp.length; i++) { cumpal[i]=cumpal[i-1]+palp[i-1]; } let st = 1; pj=1; let palr = rnd(); while (st<palp.length && cumpal[st]<palr) { st++; } st--; let pj2 = Math.floor(11*rnd()); inv=0; switch(st) { case 0: pj=6;pj2=7; break; // embers in half light case 1: pj=11;pj2=7; break; // liquid circuit case 2: pj=1;pj2=5; break; // alpenglow case 3: pj=1;pj2=0; break; // zabriskie point case 4: pj=3;pj2=9; break; // aurum case 5: pj=6;pj2=0; break; // tunguska case 6: pj=5;pj2=7; break; // nocturne case 7: pj=11;pj2=5; break; // kind of blue case 8: pj=11;pj2=4; break; // inferno case 9: pj=11;pj2=0; break; // constellation case 10: pj=0;pj2=0;inv=1; break; // white heat case 11: pj=3;pj2=3;inv=1; break; // calanque case 12: pj=2;pj2=0; break; // bouquet case 13: pj=2;pj2=10; break; // spectral case 14: pj=10;pj2=8; break; // the forest path to the spring case 15: pj=10;pj2=4; break; // abalone } pal = new Uint8Array(10*4*2); for (let k=0; k<11; k++) { // which colour in palette for (let k2=0; k2<2; k2++) { // which palette let pp = (k2==0) ? pj : pj2; let kk = Math.min(k,pals[pp].length-1); pal[3*k+3*10*k2] = pals[pp][kk][0]; pal[3*k+3*10*k2+1] = pals[pp][kk][1]; pal[3*k+3*10*k2+2] = pals[pp][kk][2]; if (inv) { pal[3*k+3*10*k2] = (pal[3*k+3*10*k2]+180)%360; } //invert colour } } let kp,km,kv,kw,kl,rand; rand = []; for (let i=0; i<Nrand; i++) { rand[i]=rnd(); } let k0=1; let kl0=0.001; kp = new Float32Array(N); km = new Float32Array(N); kl = new Float32Array(N); switch(st) { case 0: kp = [0.66, 0.95, 0.94, 0.037, 0.89, 0.26, 0.90, 0.94, 0.65, 0.76, 0.54, 0.11, 0.50, 0.66, 0.96, 0.74, 0.91, 0.33, 0.15, 0.85]; break; case 1: kp = [0.97, 0.01, 0.89, 0.08, 0.78, 0.98, 0.16, 0.80, 0.53, 0.91, 0.40, 0.54, 0.84, 0.44, 0.14, 0.75, 0.45, 0.33, 0.47, 0.95]; break; case 2: kp = [0.72, 0.85, 0.51, 0.08, 0.98, 0.29, 0.91, 0.19, 0.69, 0.24, 0.99, 0.32, 0.84, 0.03, 0.97, 0.14, 0.09, 0.04, 0.08, 0.26]; break; case 3: kp = [0.14, 0.95, 0.24, 0.09, 0.05, 0.18, 0.96, 0.04, 0.47, 0.18, 0.13, 0.38, 0.21, 0.85, 0.66, 0.05, 0.15, 0.23, 0.25, 0.48]; break; case 4: kp = [0.58, 0.02, 0.03, 0.84, 0.43, 0.40, 0.95, 0.76, 0.15, 0.55, 0.04, 0.49, 0.49, 0.55, 0.52, 0.07, 0.22, 0.16, 0.31, 0.37]; break; case 5: kp = [0.21, 0.10, 0.21, 0.13, 0.07, 0.42, 0.26, 0.77, 0.28, 0.67, 0.79, 0.10, 0.28, 0.20, 0.04, 0.21, 0.35, 0.125, 0.75, 0.87]; break; case 6: kp = [0.40, 0.28, 0.88, 0.36, 0.92, 0.96, 0.79, 0.24, 0.99, 0.73, 0.68, 0.03, 0.09, 0.52, 0.11, 0.29, 0.95, 0.01, 0.01, 0.62]; break; case 7: kp = [0.10, 0.27, 0.31, 0.05, 0.40, 0.24, 0.67, 0.00, 0.02, 0.92, 0.75, 0.11, 0.40, 0.55, 0.97, 0.45, 0.12, 0.15, 0.54, 0.56]; break; case 8: kp = [0.17, 0.81, 0.64, 0.19, 0.52, 0.27, 0.59, 0.11, 0.65, 0.87, 0.36, 0.17, 0.66, 0.10, 0.95, 0.08, 0.50, 0.43, 0.92, 0.13]; break; case 9: kp = [0.59, 0.56, 0.03, 0.14, 0.58, 0.05, 0.80, 0.00, 0.09, 0.75, 0.80, 0.55, 0.07, 0.27, 0.46, 0.08, 0.35, 0.01, 0.17, 0.63]; break; case 10: kp = [0.021, 0.68, 0.20, 0.04, 0.46, 0.40, 0.30, 0.76, 0.19, 0.20, 0.78, 0.50, 0.10, 0.58, 0.61, 0.13, 0.25, 0.39, 0.63, 0.38]; break; case 11: kp = [0.11, 0.18, 0.02, 0.15, 0.49, 0.90, 0.73, 0.77, 0.69, 0.93, 0.95, 0.76, 0.78, 0.32, 0.13, 0.70, 0.07, 0.04, 0.30, 0.76]; break; case 12: kp = [0.15, 0.27, 0.17, 0.11, 0.61, 0.44, 0.65, 0.21, 0.82, 0.79, 0.40, 0.33, 0.43, 0.22, 0.02, 0.07, 0.50, 0.13, 0.95, 0.34]; break; case 13: kp = [0.89, 0.46, 0.48, 0.30, 0.38, 0.18, 0.13, 0.68, 0.20, 0.87, 0.92, 0.56, 0.06, 0.25, 0.32, 0.10, 0.05, 0.11, 0.31, 0.55]; break; case 14: kp = [0.90, 0.025, 0.064, 0.439, 0.208, 0.154, 0.261, 0.085, 0.268, 0.917, 0.780, 0.709, 0.087, 0.068, 0.684, 0.057, 0.480, 0.282, 0.174, 0.819]; break; case 15: kp = [0.81, 0.79, 0.38, 0.80, 0.19, 0.22, 0.39, 0.047, 0.82, 0.98, 0.90, 0.28, 0.12, 0.24, 0.12, 0.69, 0.62, 0.20, 0.99, 0.71]; break; } for (let i=0; i<N; i++) { km[i]=k0*rnd(); } for (let i=0; i<N; i++) { kl[i]=kl0*rnd(); } if (km[0]<0.07*k0 && st!=10 && st!=3 && st!=1) { kp[15]=0.69;kp[16]=1.34; } let nx = 2+Math.floor(8*rnd()); let ny = 2+Math.floor(8*rnd()); let rr = rnd(); let n4 = Math.floor(Math.exp(4*rnd())); let rbg = Math.floor(14*rnd()); // initial conditions const tex0 = new Uint8Array(Nx*Ny*4); let th; for (let x = 0; x < Nx; x++) { for (let y = 0; y < Ny; y++) { let i = x+Nx*y; let r2 = (x-Nx/2)**2+(y-Ny/2)**2; r2/=(Nx*Nx+Ny*Ny)/4; switch(rbg) { case 0: r2 = Math.sin(x/nx)*Math.sin(y/ny)*Math.sin(25*r2)>.1+.5*rr; break; case 1: r2 = Math.sin(x/Nx*nx*PI)*Math.sin(y/Ny*ny*PI)*Math.sin(25*r2)>0.5*rr; break; case 2: r2 = Math.sin(y*x/Nx*nx*PI)*Math.sin(y/Ny*ny*PI)*Math.sin(25*r2)>0.5*rr; break; case 3: r2 = Math.sin(y*x/Nx*nx*PI)*Math.sin(y/Ny*ny*PI)*Math.sin(2*(x-Nx/2)/(y-Ny/2)+1*(y-Ny/2)/(x-Nx/2))>0.5*rr; break; case 4: r2 = Math.sin(Math.sin(x/Nx*n4)*y/Ny*nx*PI)*Math.sin(y/Ny*ny*PI)*Math.sin(2*(x-Nx/2)/(y-Ny/2)+1*(y-Ny/2)/(x-Nx/2))>0.5*rr; break; case 5: r2 = Math.sin(Math.sin(x/Nx*n4*PI)*y/Ny*(1-y/Ny)*ny*PI)*Math.sin(x/Nx*nx*PI)>0.6*rr; break; case 6: r2 = Math.sin(Math.sin(y/Ny*n4*PI)*x/Nx*(1-x/Nx)*nx*PI)*Math.sin(y/Ny*ny*PI)>0.6*rr; break; case 7: r2 = Math.sin(30*x/Nx*nx*PI)*Math.sin(x/Nx*nx*PI)>0.6*rr; break; case 8: r2 = Math.sin(30*x/Nx*nx*PI)*Math.sin(y/Ny*ny*PI)>0.6*rr; break; case 9: r2 *= .7*(Math.sin(20*(x/Nx-0.5)*nx)+Math.sin(2*(y/Ny-0.5))); break; case 10: r2 = r2*Math.sin(20*r2*nx)>.3*rr; break; case 11: r2 = Math.sin(r2*nx*Math.tan(n4*x/Nx+9*y/Ny))>.6*rr; break; case 12: th = Math.atan2(y-Ny/2,x-Nx/2); r2*=1+0.2*Math.cos(nx*th)*(1+0.6*Math.sin(nx/ny+3*nx*th)*(1+0.6*Math.cos(5*nx*th))); r2*=.72; break; case 13: th = Math.atan2(y+(.3+.4*km[3])*Ny,x-.5*Nx); r2 = Math.sin(10*nx*(x-y)/Nx*PI)*Math.sin((y+x)/Ny*ny*PI+th*ny*nx)>(.2+km[2]*.8)*rr; break; } tex0[4*i] = Math.floor(rnd()*255*(r2)); tex0[4*i+1] = Math.floor(rnd()*255*(1-r2) ); tex0[4*i+2] = Math.floor(rnd()*255*(1-r2) ); tex0[4*i+3] = Math.floor(rnd()*255*(r2) ); } } dzc=0; dzp=dzc; let loc_a,loc_ac,loc_img,loc_img00,loc_res,loc_t,loc_rand,loc_palc,loc_kp,loc_km,loc_kl,loc_kv,loc_kw,loc_imgc,loc_imgc2,loc_resc,loc_Lc,loc_tc,loc_randc,loc_aavg,loc_bavg,loc_dxy,loc_dxyc,loc_rc,loc_rcc; function thrower(prog) { if (!gl.getProgramParameter(prog, gl.LINK_STATUS)) { console.log(`Link failed:\n${gl.getProgramInfoLog(prog)}`); console.log(`VS LOG:\n${gl.getShaderInfoLog(vs)}`); console.log(`FS LOG:\n${gl.getShaderInfoLog(fs)}`); throw 'AARG DED'; } } simp = gl.createProgram(); // simulation program vs = Shader(gl.VERTEX_SHADER, src_vert); fs = Shader(gl.FRAGMENT_SHADER, src_simp); gl.attachShader(simp, vs); gl.attachShader(simp, fs); gl.linkProgram(simp); gl.useProgram(simp); thrower(simp); function gul(pr,lab) { return gl.getUniformLocation(pr,lab); } loc_img=gul(simp,'img'); loc_img00=gul(simp,'img00'); loc_res=gul(simp,'res'); loc_t =gul(simp,'t'); loc_rand =gul(simp,'rand'); loc_kp =gul(simp,'kp'); loc_km =gul(simp,'km'); loc_kl =gul(simp,'kl'); loc_dxy =gul(simp,'dxy'); loc_rc =gul(simp,'rc'); gl.uniform1i(loc_img,0); gl.uniform1i(loc_img00,1); gl.uniform2f(loc_res,Nx,Ny); loc_a = gl.getAttribLocation(simp, "a"); gl.activeTexture(gl.TEXTURE0); gl.vertexAttribPointer(loc_a, 2, gl.FLOAT, false, 0, 0); gl.enableVertexAttribArray(loc_a); colp = gl.createProgram(); // colour program vs = Shader(gl.VERTEX_SHADER, src_vert); fs = Shader(gl.FRAGMENT_SHADER, src_colp); gl.attachShader(colp, vs); gl.attachShader(colp, fs); gl.linkProgram(colp); gl.useProgram(colp); thrower(colp); loc_imgc=gul(colp,'img'); loc_imgc2=gul(colp,'img2'); loc_palc=gul(colp,'pal'); loc_resc=gul(colp,'res'); loc_Lc=gul(colp,'L'); loc_tc =gul(colp,'t'); loc_randc =gul(colp,'rand'); loc_dxyc =gul(colp,'dxy'); loc_rcc =gul(colp,'rc'); gl.bindBuffer(gl.ARRAY_BUFFER, gl.createBuffer()); gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([-1.0, 1.0, 1.0, 1.0, 1.0, -1.0, -1.0, 1.0, 1.0, -1.0, -1.0, -1.0]),gl.STATIC_DRAW); gl.uniform1i(loc_imgc,0); gl.uniform1i(loc_imgc2,2); gl.uniform2f(loc_resc,Nx,Ny); loc_ac = gl.getAttribLocation(colp, "a"); //'a'); gl.activeTexture(gl.TEXTURE0); gl.vertexAttribPointer(loc_ac, 2, gl.FLOAT, false, 0, 0); gl.enableVertexAttribArray(loc_ac);
//"use strict"; let N = 20; let Nrand = 100; let R; let dx=0.0,dy=0.0,dz=0.0; let dxc=0.0,dyc=0.0,dzc=0.0; let dxp=0.0,dyp=0.0,dzp=0.0; let xc=0,yc=0,zc=1; let TWO_PI=6.28318530718; let pals = []; pals.push([[359, 31, 56], [353, 19, 97], [6,20,96], [22, 21, 92], [20, 16, 98], [28, 21, 99], [6,20,96], [347,13,96]]); pals.push([[208,49,38], [205,41,59], [192,29,45], [190,14,64], [220, 9, 78], [12, 4, 45], [167,16,81], [180,7,100]]); pals.push([[222,86,22], [208,88,29], [203,61,57], [215, 49, 74], [211,68, 93], [236,100,24], [195,85,45]]); pals.push([[4,100,34],[1,96,84],[26,92,94],[34,58,89],[48,100,99],[21,100,84],[8,100,17]]); pals.push([[43,35,28],[46,39,42],[41,27,90],[39,46,49],[39,83,90],[46,6,96],[46,15,97]]); pals.push([[209, 92, 15], [197, 98, 24], [195, 79, 37], [190, 42, 64], [189, 62, 90]]); pals.push([[331,21,31], [265,23,40], [335,26,76], [163,32,22], [210, 24, 29], [180,31, 97], [49,30,63], [180,23,90], [170,13,48]]); pals.push([[26, 71, 17],[26, 78, 23],[42, 68, 60], [40, 46, 60], [42, 76, 74], [37, 62, 74]]); pals.push([[102,41,55], [123,37,63], [94,27,65], [121,30,69], [91, 26, 67], [125,37, 63]]); pals.push([[115,52,17], [98,51,40],[78,58,54],[91,67,84],[6,54,38]]); pals.push([[349, 83, 69],[250, 44, 66],[191, 44, 66],[27, 82, 72],[45, 85, 70],[0, 100, 79]]) pals.push([[221, 20, 21],[199, 26, 38],[190, 10, 81],[220, 0, 100],[190, 0, 100],[205, 30, 43],[183, 20, 100],[215, 43, 36],[185, 0, 100],[200, 0, 100]]) let header = `#version 300 es precision highp float;`; var src_vert = header+` in vec2 a; out vec2 u; void main() { gl_Position = vec4(a,0.,1.); u = a/2. +vec2(.5,.5); }`; var src_simp = header+` const int N =20; const float Nf =20.; const int Nrand =100; const float Nrandf =100.; const float dn =0.1; const int Nx =512; const float Nxf =512.; const float PI =3.1415926; const int numOctaves =8; in vec2 u; out vec4 cout; uniform vec2 res; uniform int t; // frame number uniform highp sampler2D img; uniform highp sampler2D img00; uniform float kp[N]; uniform float rand[Nrand]; uniform vec3 dxy; uniform vec3 rc; vec2 hash2( in vec2 x ) { int ii = int(mod(x.x+res.x*x.y,Nrandf)); //counter into array of random #s int i2 = int(mod(x.y-res.y*x.x,Nrandf)); //counter into array of random #s return vec2(rand[ii],rand[i2]); } float ddot ( in vec2 x, in vec2 y ) { return x.x+y.x + x.y*y.y; } // returns 3D value noise (in .x) and its derivatives (in .yz) vec3 noise( in vec2 p ) { vec2 i = floor( p ); vec2 f = fract( p ); vec2 u = f*f*f*(f*(f*6.0-15.0)+10.0); vec2 du = 30.0*f*f*(f*(f-2.0)+1.0); vec2 ga = hash2( i + vec2(0.0,0.0) ); vec2 gb = hash2( i + vec2(1.0,0.0) ); vec2 gc = hash2( i + vec2(0.0,1.0) ); vec2 gd = hash2( i + vec2(1.0,1.0) ); float va = ddot( ga, f - vec2(0.0,0.0) ); float vb = ddot( gb, f - vec2(1.0,0.0) ); float vc = ddot( gc, f - vec2(0.0,1.0) ); float vd = ddot( gd, f - vec2(1.0,1.0) ); return vec3( va + u.x*(vb-va) + u.y*(vc-va) + u.x*u.y*(va-vb-vc+vd), // value ga + u.x*(gb-ga) + u.y*(gc-ga) + u.x*u.y*(ga-gb-gc+gd) + // derivatives du * (u.yx*(va-vb-vc+vd) + vec2(vb,vc) - va)); } vec3 fbm( in vec2 x, in float H ) { float G = exp(-2.*H);float f = 1.0;float a = 1.0;vec3 t = vec3(0.); for( int i=0; i<numOctaves; i++ ) { t += a*noise(f*x);f *= 2.0;a *= G; } return t; } vec4 laplacian(in sampler2D img, in vec2 uv, in float dx) { vec2 dt = 1./res; vec4 rg = texture(img, uv + vec2(-1., -1.)*dt)*(0.05+dx); rg += texture(img, uv + vec2(0., -1.)*dt)*(0.2-dx); rg += texture(img, uv + vec2(1., -1.)*dt)*(0.05+dx); rg += texture(img, uv + vec2(-1., 0.)*dt)*(0.2-dx); rg -= texture(img, uv + vec2(0., 0.)*dt); rg += texture(img, uv + vec2(1., 0.)*dt)*(0.2-dx); rg += texture(img, uv + vec2(-1., 1.)*dt)*(0.05+dx); rg += texture(img, uv + vec2(0., 1.)*dt)*(0.2-dx); rg += texture(img, uv + vec2(1., 1.)*dt)*(0.05+dx); return rg; } void main(void) //( out vec4 fragColor, in vec2 fragCoord ) { vec2 dt = rc.z/res; vec2 uv = (u+dxy.xy-vec2(0.5))*(1.+dxy.z)+vec2(0.5); vec2 uc = -rc.xy + u*rc.z; // global coords vec3 ff = (0.4+0.6*kp[9])*fbm(uc+fbm(0.8*uc,0.7).yz,0.7); vec3 f2 = (0.4+0.6*kp[10])*fbm(-uc+fbm(-0.8*uc,0.7).yz,0.7); vec4 cc; vec4 lp,lp2,cv,cu,cv2,cu2; float aa,bb; if ((uv.x>1. || uv.x<0. || uv.y>1. || uv.y<0.)) { cc = texture(img00,uc); aa = cc.x/256. + cc.y; bb = cc.z/256. + cc.w; lp = laplacian(img00,uc,(kp[0]*2.-1.)*f2.x*(1.-aa)); lp2 = laplacian(img00,uc,(kp[1]*2.-1.)*ff.x*bb); cv= texture(img00, uc + vec2(0., 1.)*dt); cu= texture(img00, uc + vec2(1., 0.)*dt); cv2= texture(img00, uc + vec2(0., -1.)*dt); cu2= texture(img00, uc + vec2(-1., 0.)*dt); } else { uc=uv; cc = texture(img,uc); aa = cc.x/256. + cc.y; bb = cc.z/256. + cc.w; lp = laplacian(img,uc,(kp[0]*2.-1.)*f2.x*(1.-aa)); lp2 = laplacian(img,uc,(kp[1]*2.-1.)*ff.x*bb); cv= texture(img, uc + vec2(0., 1.)*dt); cu= texture(img, uc + vec2(1., 0.)*dt); cv2= texture(img, uc + vec2(0., -1.)*dt); cu2= texture(img, uc + vec2(-1., 0.)*dt); } float da = 1.2*(1.-kp[15])*(1.-bb)*(lp.x+256.*lp.y)/256. + 3.*( -aa*bb*bb + 0.015*(1.+kp[17])*(1.-aa))*ff.x*ff.x ; float db = 1.2*(1.-kp[16])*(1.+kp[7])*(0.02+ff.x*ff.x)*aa*0.5*(lp2.z+256.*lp2.w)/256. + 3.*( aa*bb*bb - 0.04*(1.+1.*kp[6])*bb)*ff.x*ff.x; float dda=sin(3.*(1.+kp[2]*(ff.x-1.))*aa*1.57)*kp[15]*0.18*((cu.x/256.+cu.y-cu2.x/256.-cu2.y)*ff.y + (cv.x/256.+cv.y-cv2.x/256.-cv2.y)*ff.z); float ddb=sin(3.*(1.+kp[3]*(f2.x-1.))*bb*1.57)*kp[16]*0.18*((cu.z/256.+cu.w-cu2.z/256.-cu2.w)*f2.y + (cv.z/256.+cv.w-cv2.z/256.-cv2.w)*f2.z); uv += 2.*f2.yz; float uv2 = .003+uv.x*uv.x+uv.y*uv.y; uv2 = (cu.x/256.+cu.y-cu2.x/256.-cu2.y)*uv.y/uv2 - (cv.x/256.+cv.y-cv2.x/256.-cv2.y)*uv.x/uv2; dda += kp[12]*0.04*uv2; ddb += kp[13]*0.04*uv2; da += dda*(1.-dda); db += ddb*(1.-ddb); da*=46000.; db*=46000.; da+=aa*256.*256.; db+=bb*256.*256.; float yn = floor(da/256.); float xn = (da-yn*256.); float wn = floor(db/256.); float zn = (db-wn*256.); cout = vec4(xn,yn,zn,wn)/256.; }`; var src_colp = header+` const int N =20; const float Nf =20.; const int Nrand =100; const float Nrandf =100.; const float dn =0.1; const int Nx =512; const float Nxf =512.; const float PI =3.1415926; const int numOctaves =8; in vec2 u; out vec4 cc; uniform vec2 res; uniform vec2 L; uniform int t; // frame number uniform highp sampler2D img; uniform highp sampler2D img2; uniform sampler2D pal; // palette uniform float rand[Nrand]; uniform vec3 dxy; uniform vec3 rc; vec2 hash2( in vec2 x ) { int ii = int(mod(x.x+res.x*x.y,Nrandf)); int i2 = int(mod(x.y-res.y*x.x,Nrandf)); return vec2(rand[ii],rand[i2]); } float ddot ( in vec2 x, in vec2 y ) { return x.x+y.x + x.y*y.y; } // returns 3D value noise (in .x) and its derivatives (in .yz) vec3 noise( in vec2 p ) { vec2 i = floor( p ); vec2 f = fract( p ); vec2 u = f*f*f*(f*(f*6.0-15.0)+10.0); vec2 du = 30.0*f*f*(f*(f-2.0)+1.0); vec2 ga = hash2( i + vec2(0.0,0.0) ); vec2 gb = hash2( i + vec2(1.0,0.0) ); vec2 gc = hash2( i + vec2(0.0,1.0) ); vec2 gd = hash2( i + vec2(1.0,1.0) ); float va = ddot( ga, f - vec2(0.0,0.0) ); float vb = ddot( gb, f - vec2(1.0,0.0) ); float vc = ddot( gc, f - vec2(0.0,1.0) ); float vd = ddot( gd, f - vec2(1.0,1.0) ); return vec3( va + u.x*(vb-va) + u.y*(vc-va) + u.x*u.y*(va-vb-vc+vd), // value ga + u.x*(gb-ga) + u.y*(gc-ga) + u.x*u.y*(ga-gb-gc+gd) + // derivatives du * (u.yx*(va-vb-vc+vd) + vec2(vb,vc) - va)); } vec3 fbm( in vec2 x, in float H ) { float G = exp(-2.*H);float f = 1.0;float a = 1.0;vec3 t = vec3(0.); for( int i=0; i<numOctaves; i++ ) { t += a*noise(f*x);f *= 2.0;a *= G; } return t; } vec4 laplacian(in sampler2D img, in vec2 uv, in float dx) { vec2 dt = 1./res; vec4 rg = texture(img, uv + vec2(-1., -1.)*dt)*(0.05+dx); rg += texture(img, uv + vec2(0., -1.)*dt)*(0.2-dx); rg += texture(img, uv + vec2(1., -1.)*dt)*(0.05+dx); rg += texture(img, uv + vec2(-1., 0.)*dt)*(0.2-dx); rg -= texture(img, uv + vec2(0., 0.)*dt); rg += texture(img, uv + vec2(1., 0.)*dt)*(0.2-dx); rg += texture(img, uv + vec2(-1., 1.)*dt)*(0.05+dx); rg += texture(img, uv + vec2(0., 1.)*dt)*(0.2-dx); rg += texture(img, uv + vec2(1., 1.)*dt)*(0.05+dx); return rg; } // from http://www.java-gaming.org/index.php?topic=35123.0 vec4 cubic(float v){ vec4 n = vec4(1.0, 2.0, 3.0, 4.0) - v; vec4 s = n*n*n; float x = s.x; float y = s.y - 4.0 * s.x; float z = s.z - 4.0 * s.y + 6.0 * s.x; float w = 6.0 - x - y - z; return vec4(x, y, z, w)*(1./6.); } vec4 textureBicubic(in sampler2D img, in vec2 uv){ vec2 dt = 1./res; uv = uv/dt - 0.5; vec2 fxy = fract(uv); uv -= fxy; vec4 xc = cubic(fxy.x); vec4 yc = cubic(fxy.y); vec4 c = uv.xxyy + vec2 (-0.5, +1.5).xyxy; vec4 s = vec4(xc.xz + xc.yw, yc.xz + yc.yw); vec4 offset = c + vec4 (xc.yw, yc.yw) / s; offset *= dt.xxyy; vec4 sample0 = vec4(texture(img, offset.xz)); vec4 sample1 = vec4(texture(img, offset.yz)); vec4 sample2 = vec4(texture(img, offset.xw)); vec4 sample3 = vec4(texture(img, offset.yw)); float sx = s.x / (s.x + s.y); float sy = s.z / (s.z + s.w); return mix(mix(sample3, sample2, sx), mix(sample1, sample0, sx), sy); } void main(void) { vec2 uv = (u+dxy.xy)*(1.+dxy.z); //vTexCoord.xy; vec2 uc = -rc.xy + u*rc.z; if (L.x>L.y) { uv.y = 0.5 + (L.y/L.x)*(uv.y-0.5); uc.y = 0.5 + (L.y/L.x)*(uc.y-0.5); } else { uv.x = 0.5 + (L.x/L.y)*(uv.x-0.5); uc.x = 0.5 + (L.x/L.y)*(uc.x-0.5); } vec3 ff = .5*fbm(uc+fbm(0.8*uc,0.7).yz,0.7); vec3 f2 = fbm(-uc+fbm(-0.8*uc,0.7).yz,0.7); cc = textureBicubic(img,uv); vec4 cco = textureBicubic(img2,uv); float aa = (cc.x+256.*cc.y)/256.; float bb = (cc.z+256.*cc.w)/256.; float aao = (cco.x+256.*cco.y)/256.; float bbo = (cco.z+256.*cco.w)/256.; vec4 lpo = laplacian(img2,uv,3.*0.3*ff.x*aao); vec4 lp = laplacian(img,uv,3.*0.3*ff.x*aa); aao=4.*0.03*(lp[0]+lp[1]*256.-lpo[0]-lpo[1]*256.); bbo=4.*0.03*(lp[2]+lp[3]*256.-lpo[2]-lpo[3]*256.); vec4 cc_hsl = texture(pal,vec2(clamp(2.*bb*aa+0.4*(aa)*ff.x+0.4*(bb)*f2.x,0.,1.),clamp(ff*bb,0.,1.))); vec4 cco_hsl = texture(pal,vec2(clamp(2.*bbo*aao+0.4*(aao)*ff.x+0.4*(bbo)*f2.x,0.,1.),clamp(ff*bbo,0.,1.))); cc_hsl -= 0.5*(cc_hsl-cco_hsl); cc_hsl.x += 0.3*ff.x*(1.-f2.x) + 0.01*f2.x*bb + rc.x*rc.y; cc_hsl.x = mod(cc_hsl.x,1.); cc_hsl.z *= 0.2+(3.*bb+6.*aa*bb); cc_hsl.y *= (1.1-ff.x*bb)*(1.-f2.x*f2.x); vec3 rgb = clamp( abs(mod(cc_hsl.x*6.0+vec3(0.0,4.0,2.0),6.0)-3.0)-1.0, 0.0, 1.0 ); rgb = cc_hsl.z + cc_hsl.y * (rgb-0.5)*(1.0-abs(2.0*cc_hsl.z-1.0)); rgb *= .75+.32*rgb*(3.-2.*rgb); cc = vec4(pow(rgb[0],0.9), pow(rgb[1],0.9), pow(rgb[2],0.85), 1.); vec4 ccoo = vec4(.4+.3*aao-f2.x,.1*(aao+bbo),1.-bbo,1.); cc = mix(cc,ccoo,clamp(2.*ff.x*bbo*aao,-0.5,1.)); cc=clamp(cc,0.,1.); }`;
The contemporary moment is defined by the appearance of artificial systems that mimic intelligent behaviours with uncanny skill: bots that you can converse with, machines that can act as pets, and even the algorithms that recommend ads to you. At times they appear as strange beings; alive. To make sense of this phenomenon, we are forced to reconsider our notion of the living state beyond what we are familiar with on Earth. Calian is an infinitely zoomable and scrollable exploration of lifelike behaviour. It exhibits ambiguous natural-digital forms in a dynamic rendering. Species grow and compete; they get carried by the elements; they face boom, bust, and echo. What makes something alive? To go beyond recognition of terrestrial biology we need to delineate general principles and apply them to new intelligent systems. Calian uses the fruits of my research into the origin of life to create persistent, complex systems that we can experience and study (*). We can identify properties of living matter but these fall short of a satisfactory and succinct criterion. When does agency begin? Or identity? Calian asks you to ponder this as you wander through its ecosystems. Feel free to explore but be careful: although life is pervasive, living things are delicate. Your interactions affect the ecosystem, obliquely. Calian continues a thread of my work probing deep scientific questions with artistic means. It furthermore connects to my previous Artblocks projects Mazinaw and Glass through the theme of ambiguity: while Mazinaw suggested the hand of an unknown creator, and Glass visualized the intrinsic ambiguity of our quantum mechanical universe, Calian's amorphous forms bear characteristics both of familiar organic matter and digital technology. Interactive features allow you to explore each ecosystem, infinitely, both in depth and in scope. As you wander, the shader repopulates the world from its initial condition, while the physical laws governing the dynamics themselves evolve. See Display Notes for Controls. (*) For more on Calian's dynamics and its grounding in my research, see the Calian page on my website.
let loading=1,sq=1;p5.disableFriendlyErrors=!0;const head=/\bHeadlessChrome/.test(navigator.userAgent);let pd,Lx,Ly,Lxb,Lyb,dx,Lyp,CCC,T,rndv;const NRND=200;var resizing=0,rsz_time=0,rsz_delay=500;let R,t0,MM,ox,oy,col,dox,doy,c1,s1,c2,s2,xe,ye,ze,pc,ob,buf,e,f,b,pj,pal,JJ,tt0,ll,rndi1,rndi2,rndph,rndi3,dgrid,PLx,PLy,mm,nn,ri,zh,zh2,zh3,zr,a,ct,dc,night,rlight,rain,st0,scx,scy,infrac,Pcir,lgfac,hx,lo,rr0,Nrad0,nt,inv,dt,phase,clarity,gfac,kgx,kgy,melt,wild,eye,sphsh,a1,a2,xe0,ye0,ze0,kz,kx,az,ax,ay,ky,om,nbr,tik,dlum,drfa,rad,coltik,rcfac,lnwght,ang,circo,bsat,invscl,sincol,ealph,ne,echo,mono,brr,lam,lightness,miny,maxy,minx,maxx,focus,outline,bw,out,clean,pblk,rndp,fade,step,step0,NA,aa0,flow,ds,es,rbow,pinch,atten,cerp,hatchn,lfac,lamr,hex,contr_x,v0,vred,zigzag,tphase,JN,emboss_amp,distx,dist,kblk,kand,blsh,emboss,x00,y00,Ni,Nj,N,Nrad,A,kspr,invgamma,R00,Rmax,layer1,ac,bc,na,nb,contr,fh,aspect0=.8,aspect=aspect0,keyst=0,dpx=0,xb=.2,pals=[];function setup(){document.body.style.backgroundColor="#2D3033",console.log("Glass by EDG"),console.log("https://twitter.com/eeedg__"),dox=0,doy=0,doz=0,init()}function init(){R=new Random,Lx=window.innerWidth,Ly=window.innerHeight,pd=pixelDensity(),sq&&(Lx=min(Lx,Ly*aspect),Ly=Lx/aspect),aspect=Lx/Ly,Lxb=pd*Lx*(1+2*xb),Lyb=pd*Ly*(1+2*xb),CCC=createCanvas(Lx,Ly),ob=createGraphics(Lxb,Lyb),pc=createGraphics(Lxb,Lyb),CCC.id("canv"),frameRate(60),Lyp=Ly/Lx,dx=min(Lx,Ly)/200;let n=[14,15,0,22,4,24,10,14,0,10,0,20];n=vecscl(n,1/133);let e=[];e[0]=0;for(let a=1;a<n.length;a++)e[a]=e[a-1]+n[a-1];pj=1;let t=rnd();for(;pj<n.length&&e[pj]<t;)pj++;pj--;inv=0,rnd()<[0,.2,0,0,0,0,0,.3,0,.3,0,0][pj]&&(inv=1),pal=[],JJ=pals[pj].length;for(let n=0;n<JJ;n++)pal[n]=pals[pj][n].slice(),inv&&(pal[n][0]=(pal[n][0]+180)%360);rndv=[];for(let n=0;n<200;n++)rndv[n]=rnd();let r=-PI/4+PI/2*rnd();c1=Math.cos(r),s1=Math.sin(r),c2=-.7,s2=.7,ze0=-2,xe0=0,ye0=-1/3,rnd()<.2&&(ze0=rnd()<.4?.3:.9),lo=1,rr0=1,Nrad0=7,phase=PI/2,rnd()<.3&&(phase-=PI),rnd()<.3&&(phase-=PI/2,rnd()<.5&&(phase+=PI)),rnd()<.3&&(phase+=-PI/12+PI/6*rnd()),dt=.1+1.2*rnd(),clarity=0,wild=1,a1=rnd(),a2=rnd(),miny=1,maxy=-1;sphsh=.5*(1-rnd()*rnd()),rain=0,rnd()<.2&&(rain=1);let s=1;rnd()<.3&&(s=rnd()),dc=.75*dx/Lx;let d=.5*(.1+.2*rnd());ds=4*Math.exp(rnd())*dc;ds*=2;let l=.5*(1+rnd());rnd();rlight=[4*rnd()-2,4*rnd()-2,4*rnd()-2],ze=ze0-1,xe=0,ye=0,Pcir=0;let o=[0,200,240,140,0,200,65,190,200,0,100,180,200,0,200,240,0,50,75,120,0,260,50,138],i=pj+inv*pals.length;hx=o[i]+([360,290,350,320,360,360,105,360,270,60,140,280,360,360,320,400,80,275,200,180,360,580,190,478][i]-o[i])*rnd(),hx=mod(hx,360),dlum=.2*.1*rnd(),drfa=3*rnd(),ne=floor(Math.exp(1.3*rnd())),coltik=.2*(1+.5*rnd()),lgfac=1,lnwght=.7,ang=.26*Math.exp(.3*rnd()),drfa<1&&(ang=PI/4),circo=.9*Math.exp(.5*rnd()),invscl=.9*Math.exp(.5*rnd());let p=2;mono=0,11==pj&&rnd()<.2&&(mono=3/2),echo=1,rnd()<.04&&(echo=0);let c=rnd();echo||(c*=.5);rnd();lam=.6+.4*rnd(),sincol=1,ealph=.3+.3*rnd(),cerp=0,brr=3;let h=Math.exp(2*rnd())+20;h=20;let x=3*floor(80+100*rnd()),b=4*(12+5*rnd());ct=1.5*dc;rnd()<.3||rnd();b*=1.3*Math.exp(-1.3*rnd()),popen=rnd();rnd();let m=.8+.2*rnd(),f=1;f=1-.02*rnd(),loopang=PI/2*rnd(),circ=1,rnd()<.2&&(circ=0,m/=3),flow=0,rnd()<.7&&(flow=1,rnd()<.3&&(flow=2)),flow*=3,es=0,rnd()<.3&&(es=rnd()<.8?.4*(20+x):floor(.1*(x+20)*rnd())),atten=rnd()<.3?1:round(10*rnd())/10,na=2+ceil(5*rnd()),nb=2+ceil(5*rnd()),ac=[],bc=[];for(let n=0;n<na;n++)ac[n]=[],ac[n][0]=rnd(),ac[n][1]=rnd();for(let n=0;n<nb;n++)bc[n]=[],bc[n][0]=rnd(),bc[n][1]=rnd();vecscl([-.5+rnd(),-.5+rnd(),-.5+rnd()],.03);let y=1-.3*rnd(),g=(rnd(),rnd()<.8?0:.8);aa0=3.2,hatch=0,rnd()<.07&&(hatch=1),pinch=0,rnd()<.4&&(pinch=.1,rnd()<.2&&(pinch=1)),hatch*=pinch,hatch=1,hatchn=2,hatchn=6,clean=0,rnd()<.2&&(clean=1),emboss=0,(rnd()<.5||flow>0)&&(emboss=1),emboss_amp=1,blsh=1,rnd()<.7&&(blsh=.2,rnd()<.6&&(blsh=.6));hex=rnd()<.25?1:0;kand=0;let u="None";dist=rnd()<.35?1:0,dist&rnd()<.5&&(blsh=.4),distx=1,abs(mod(phase,PI)-PI/2)<PI/4&&(distx=0),dist&&(u="Pressure");let j=.5;dist&&rnd()<.6&&(distx=1-distx,j/=2,u="Shear");let L=0;dist&&g>0&&(L=1,u="Superposition");let k=TWO_PI*rnd(),z=3+4*rnd();dist>0&&(emboss=1,flow/=3),focus=0,0==dist&&rnd()<.15&&(focus=1);pblk=0,y=0,rbow=1-Math.exp(.2*rnd());bw=0,aa0*=1+bw,outline=rnd()<.06?1:0,night=0,fade=1,lightness=10,contr=1,vred=1,contr_x=0,v0=102,bsat=20;let w=rnd();10!=pj&&w<.15&&(bsat=4,lightness+=20,2==pj&&(bsat=20)),11==pj&&(contr_x=1,v0=10,kand=0,echo=0,bw=0,pblk=0,bsat=2,lightness+=20,es=0,fade=0),0!=pj||inv||(contr_x=1,v0=10,aa0*=1.6,bsat=4,lightness+=20,fade=.1),3==pj&&(contr_x=1,contr=0),3==pj&&inv&&(outline=1,mono=1,fade=.3),4!=pj||inv||(bsat=5,lightness+=10,es=0,night=.2,fade=0),4==pj&&inv&&(contr_x=1,v0=10,bsat=4,lightness=40,night=.2),9==pj&&(vred=0,mono=1,clean=1,fade=2,es=0,aa0*=1.6),inv||8!=pj||(outline=1,bsat=25,lightness=0),6!=pj||inv||(contr_x=1,v0=10,bsat=4,lightness=15,es=0,es=0,fade=2),6==pj&&inv&&(bsat=4,lightness=25,es=0),7!=pj||inv||(v0=120,vred=0,bsat=4,lightness=25,es=0,night=.2,fade=0),7==pj&&inv&&(clean=1,fade=.7),2!=pj||inv||(outline=1,mono=1,es=0,sincol=0,fade=.7),2==pj&&inv&&(mono=1,es=0),10==pj&&(mono=1,fade=2,lightness=2,night=.2,p=2),1==pj&&(v0=3,contr_x=1,fade=2,es=0),5==pj&&(vred=0,clean=1,bsat=20),0==es&&(atten=0); kblk=1-kand,outline=0,es=0,bsat=20,clean||(night=pblk,bsat*=0+.9*pblk),fade=0,bsat=2,lightness*=1-bw,bsat=8,11==pj&&(bsat=2); 6==pj&&(bsat=20,flow/=3,contr=1,emboss=0); 4==pj&&(mono=+3/2); 1==pj&&inv&&(bsat=20,emboss=0,contr=1); 4==pj&&inv&&(bsat=20),lfac=.8+.4*min(0,max(4,bsat)-20)/16,dlum*=-1,d=0,out=rnd()<.5?0:1,hoop=rnd()<.3?0:1,zigzag=0,hoop=0,dt=.1,A=[],JN=rnd()<.1?2:20,tphase=TWO_PI*rnd(),Nsph=20+floor(20*rnd()),Nsph<20&&(hex=0),Nsph*=max(1.25*aspect,.8/aspect),!emboss&&(Nsph+=10),0!=pj&&1!=pj&&6!=pj||(aa0*=1.6),11==pj&&(aa0*=1.3),R00=1/Nsph,Ni=1/R00/2,Nj=1/R00/2/aspect,Rmax=1.62*R00*1.2;let P=[],I=1;for(let n=0;n<Ni;n++){P[n]=[];for(let a=0;a<Nj;a++)if(P[n][a]=rnd()<1?I:0,P[n][a]){let e=[];I++,e.R=R00*(.9-.2*hex)*(.2+1.6*rnd()),e.F=[0,0],e.r=[],e.r[0]=n/Ni+a%2*R00*.87,e.r[1]=a/Nj,e.nb=[],e.lnk=[],A.push(e)}}let _=[-1,0,1,-1,0,1,2,-2,-1,1,2,-1,0,1,2,-1,0,1],M=[-1,0,1,-2,-1,0,1,-2,-1,1,2,-2,-1,0,1,-1,0,1],C=[2,2,2,1,1,1,1,0,0,0,0,-1,-1,-1,-1,-2,-2,-2];N=A.length;for(let n=0;n<Ni;n++)for(let a=0;a<Nj;a++){let e=round(-1+P[n][a]);if(e>-1){let t=0;for(let r=0;r<C.length;r++){let s=C[r],d=round(mod(n+(a%2>0?_[r]:M[r]),Ni)),l=round(mod(a+s,Nj)),o=-1+P[d][l];o>-1&&(A[e].nb.push(o),t++)}A[e].z=t}}kspr=1,invgamma=1;for(let n=0;n<1e3;n++){for(let n=0;n<N;n++){let a=[0,0],e=0;for(let t=0;t<A[n].z;t++){let r=A[n].nb[t],s=[A[r].r[0]-A[n].r[0],1/aspect*(A[r].r[1]-A[n].r[1])];for(let n=0;n<3;n++)s[0]>.8&&(s[0]-=1),s[0]<-.8&&(s[0]+=1),s[1]>.8&&(s[1]-=1),s[1]<-.8&&(s[1]+=1);let d=Math.sqrt(s[0]**2+s[1]**2),l=-d+A[n].R+A[r].R;d>0&&l>0&&(e+=l,a[0]+=-kspr*l*s[0]/d,a[1]+=-kspr*l*s[1]/d)}A[n].F=[a[0],a[1]],A[n].cf=e}for(let n=0;n<N;n++)A[n].r[0]+=dt*invgamma*A[n].F[0],A[n].r[1]+=dt*invgamma*A[n].F[1],A[n].r[0]=mod(A[n].r[0],1),A[n].r[1]=mod(A[n].r[1],1)}a=[];let J=phase+PI/2-ang;for(let n=0;n<N;n++){let e=[];e.x=[],e.y=[],e.z=[],e.v=[],e.RR=[],e.s=0;let t=.3*rnd(),r=unit([0,1,0]),s=2*b*20/Nsph*A[n].R/R00+1;for(let a=0;a<s;a++)e.x[a]=A[n].r[0]+cos(J+TWO_PI/s*a)*A[n].R,e.y[a]=A[n].r[1]+sin(J+TWO_PI/s*a)*Lx/Ly*A[n].R,e.z[a]=t,e.v[a]=r,e.RR[a]=rezeta([e.x[a],e.y[a]]);e.xav=A[n].r[0],e.yav=A[n].r[1],e.zav=e.z[floor(s/2)],e.id=n,e.open=0,e.R=l*(1+rnd());let d=phase,o=str(e.xav),i=str(e.yav);e.s=-sin(d)*i-cos(d)*o,A[n].s=e.s,a.push(e)}NA=a.length,echo=0,maxy=-1,miny=1,maxx=-1,minx=1,xav=0;let D=[],F=[];for(let n=0;n<NA;n++)xav+=a[n].xav,a[n].yav&&(p1=[a[n].xav,a[n].yav],D.push(p1[0]),F.push(p1[1]),maxy=max(maxy,p1[1]),miny=min(miny,p1[1]),maxx=max(maxx,p1[0]),minx=min(minx,p1[0]));xav/=a.length,D.sort((function(n,a){return n-a})),F.sort((function(n,a){return n-a})),minx=D[floor(NA/7)],maxx=D[floor(6*NA/7)],miny=F[floor(NA/7)],maxy=F[floor(6*NA/7)],x00=.3,y00=.3;for(let n=0;n<NA;n++){a[n].gp=[];for(let e=0;e<a[n].x.length;e++)a[n].z[e]+=imzeta([a[n].x[e],a[n].y[e]])/10,a[n].gp[e]=gradimzeta([a[n].x[e]-x00,a[n].y[e]-y00])}if(dist){let n=3;for(let e=0;e<a.length;e++){let t=distx?A[e].r[0]:A[e].r[1];L&&(t=A[e].r[0]*A[e].r[1]);let r=j*sin(cos(z*sin(t)+k)*n);A[e].r[0]+=-.2*r*cos(phase),A[e].r[1]+=.2*r*sin(phase);for(let r=0;r<a[e].x.length;r++){t=distx?a[e].x[r]:a[e].y[r],L&&(t=a[e].x[r]*a[e].y[r]);let s=j*sin(cos(z*sin(t)+k)*n);a[e].x[r]+=-.2*s*cos(phase),a[e].y[r]+=.2*s*sin(phase)}}}let T=0;for(let n=0;n<a.length;n++){a[n].t1=[],a[n].t2=[],a[n].t1[0]=0;for(let e=1;e<a[n].x.length;e++)a[n].t1[e]=atan2(a[n].y[e]-a[n].y[e-1],a[n].x[e]-a[n].x[e-1])-PI/2,a[n].t2[e-1]=a[n].t1[e];T+=a[n].x.length}A.sort(((n,a)=>a.s-n.s)),a.sort(((n,a)=>a.s-n.s)),fac=1.8/(maxy-miny),scx=.5;let W=cos((1-pinch)*phase),E=sin((1-pinch)*phase);W=0,E=0,scx=1/(maxx-minx),scy=1/(maxy-miny),scx=max(scx,scy),scy=scx,ox=1-scx*maxx,oy=1-scy*maxy;for(let n=0;n<NA;n++)a[n].bdy=inbdy(mod(a[n].xav,1),mod(a[n].yav,1));doz=0,blendMode(BLEND),ob.blendMode(BLEND),bg(),step0=floor(.8*max(30,NA-es)),step=1,step0=NA-es,loading||(step0=1)}function begin(n,a){background(0,0,0,1),fill(n,a,bfac*(1-kand)*100),rect(0,0,Lx,Ly),ob.background(0,0,0,1),ob.fill(n,a,bfac*(1-night)*100),ob.rect(0,0,Lxb,Lyb),fill((180+n)%360,3*a,50),pc.fill(200/JN*(1-kand)+255*kand),pc.rect(0,0,Lxb,Lyb)}function fblend(n){return n*n*(3-2*n)}pals.push([[359,31,56],[353,19,97],[6,20,96],[22,21,92],[20,16,98],[28,21,99],[6,20,96],[347,13,96]]),pals.push([[208,49,38],[205,41,59],[192,29,45],[190,14,64],[220,9,78],[12,4,45],[167,16,81],[180,7,100]]),pals.push([[222,86,22],[208,88,29],[203,61,57],[215,49,74],[211,68,93],[236,100,24],[195,85,45]]),pals.push([[4,100,34],[1,96,84],[26,92,94],[34,58,89],[48,100,99],[21,100,84],[8,100,17]]),pals.push([[43,35,28],[46,39,42],[41,27,90],[39,46,49],[39,83,90],[46,6,96],[46,15,97]]),pals.push([[209,92,15],[197,98,24],[195,79,37],[190,42,64],[189,62,90]]),pals.push([[331,21,31],[265,23,40],[335,26,76],[163,32,22],[210,24,29],[180,31,97],[49,30,63],[180,23,90],[170,13,48]]),pals.push([[26,71,17],[26,78,23],[42,68,60],[40,46,60],[42,76,74],[37,62,74]]),pals.push([[102,41,55],[123,37,63],[94,27,65],[121,30,69],[91,26,67],[125,37,63]]),pals.push([[115,52,17],[98,51,40],[78,58,54],[91,67,84],[6,54,38]]),pals.push([[349,83,69],[250,44,66],[191,44,66],[27,82,72],[45,85,70],[0,100,79]]),pals.push([[221,20,21],[199,26,38],[190,10,81],[220,0,100],[190,0,100],[205,30,43],[183,20,100],[215,43,36],[185,0,100],[200,0,100]]);let bfac=1;
function draw(){if(tik>0&&tik<NA-es-1){let e=buf?ob:this,t=tik%NA,n=[A[t].r[0],A[t].r[1]];e.fill(0,0,100,1),e.blendMode(ADD),pc.blendMode(BLEND);let l=255*clamp(Math.exp(10/JN*log(.85))*(1-kblk)+.2*clamp((n[0]-.5)*(n[0]-.5)-(n[1]-.5)*(n[1]-.5),0,1),0,1);pc.fill(l),pc.stroke(l),pc.strokeWeight(.6),0&&e.circle(1.1*Lx*A[t].r[0]-.05,1.1*Ly*A[t].r[1]-.05,2*Lx*A[t].R*1);let o=[a[t].x[a[t].x.length-1],a[t].y[a[t].x.length-1]];o=sumArrays(vecscl(n,1-lamr),vecscl(o,lamr));if(dist)for(let e=0;e<a[t].x.length;e++){let l=mod(e,a[t].x.length);let poo=[a[t].x[l],a[t].y[l]];poo=sumArrays(vecscl(n,1-lamr),vecscl(poo,lamr));pc.triangle(Lx*str(ox+scx*n[0]),Ly*str(oy+scy*n[1]),Lx*str(ox+scx*o[0]),Ly*str(oy+scy*o[1]),Lx*str(ox+scx*poo[0]),Ly*str(oy+scy*poo[1]));o=poo}else pc.circle(Lx*str(ox+scx*n[0]),Ly*str(oy+scy*n[1]),lamr*.99*scx*Lx*2*A[t].R);if(outline){e.noFill(),e.stroke(0,0,100*(1-night),1);let n=.5*dc*.5/2/tan(ang);e.strokeWeight(Lx*min(max(.2*dc,scx*n),.6*dc)),e.beginShape();let l,o,r,s,i=[],c=1;for(let n=0;n<a[t].x.length;n++)i=[a[t].x[n],a[t].y[n]],l=ox+scx*i[0],o=oy+scy*i[1],r=10*floor(l)+floor(o),n>0&&r!=s&&(e.endShape(),e.beginShape(),c=0),s=r,c&&l<2&&l>-2&&o<2&&o>-2&&e.curveVertex(Lx*l,Ly*o);e.endShape()}e.blendMode(BLEND)}let e=0;for(;tik<NA-es&&e<step;)drawk(tik),tik++,e++;if(buf){let e=tik/step0*TWO_PI;fill(360*e/TWO_PI,90,100),circle(Lx/2+60*dx*cos(e),Ly/2+60*dx*sin(e),3*dx)}if(buf&&tik>=step0&&(image(ob,0,0,Lx,Ly,Lx*xb/3,Ly*xb/3,Lx,Ly),t0=millis(),step=1,buf=0),tik>=NA-es&&(1==kand||emboss)){image(ob,0,0,Lx,Ly,Lx*xb/3,Ly*xb/3,Lx,Ly);let e=JN;JN>2&&(e+=6*kand);let t=tphase+(millis()-t0)/3e5*PI;let ct=cos(t);ct*=ct;if(kand)for(let n=1;n<e;n++)blend(pc,blsh*Lx*xb/3*n/e*ct,blsh*Ly*xb/3*n/e*(1-ct),Lx,Ly,0,0,Lx,Ly,MULTIPLY);else for(let n=1;n<e;n++)blend(pc,blsh*Lx*xb/3*n/e*ct,blsh*Ly*xb/3*n/e*(1-ct),Lx,Ly,0,0,Lx,Ly,SCREEN);if(vred||(fill(hx,bsat,255,.1),rect(0,0,Lx,Ly)),!kand&&contr){loadPixels();let e=4*(width*pd)*(height*pd);for(let t=0;t<e;t+=4){let e=[pixels[t],pixels[t+1],pixels[t+2]],n=color(e[0],e[1],e[2]),l=brightness(n)/100,o=1.2*(.4+.6*fblend(l*l));contr_x>0&&(o*=1.4*o);let r=1+vred*(l-1);pixels[t+0]=r*(o*(e[0]-128)+v0),pixels[t+1]=r*(o*(e[1]-128)+v0),pixels[t+2]=r*(o*(e[2]-128)+v0)}updatePixels()}}tik>=NA-es&&(tik++,bor&&drawbord(),head&&noLoop())}function drawk(e){let t=max(.01,1-e/(.1+NA-atten*es)),n=dx/Lx,l=mod(hx+5*(e-NA)*coltik,360),o=(2-bsat/20)*t*.1*rndv[e%NRND]/2,r=buf?ob:this;if(e%20==0&&(r.blendMode(SCREEN),r.fill(l,bsat,100-3*(2*t-1)*1.5*(1+fade)*dlum,1*(1+fade)*max(0,o)),r.rect(0,0,Lxb,Lyb),r.blendMode(BLEND)),e<NA){let l=rlight.slice();l=rot3d(l,[0,0,1],t*PI);let o=[120,30,10];col=[];let s=0,i=1,c=pal[pal.length-1][0],x=0,d=0;for(let p=0;p<a[e].x.length;p++){let y=1,h=(dx,5*(2+fade)*min(.1,1.3*y)*pd/2/2*.1*lnwght);x=0,d=0,lo=1,lo*=lsw,h*=1+4*bw,lo?r.stroke(c,100,.2*lightness,h):r.noStroke();let b=1.3*max(.1,1.3*y)*2/pd*dx/14;r.strokeWeight(b);let f=[a[e].x[p],a[e].y[p],a[e].z[p]],u=.6*a[e].R,L=a[e].v[0];i*=y;let m,k,g,w,D,M,N,v=rr0;for(let c=0;c<Nrad0;c++){s++,i=min(.15*n,i),i=max(.7*n,i);let y=pinch*a[e].t1[p];hatch&&(y=floor(y*hatchn/TWO_PI)*TWO_PI/hatchn),y=phase,y+=flow*a[e].RR[p]/2;let b=rot3d([cos(y),sin(y),0],a[e].v[p],c/Nrad0*TWO_PI),P=sumArrays(vecscl(b,1-lam),vecscl(L,lam));L=P,k=clarity+(1-clarity)*(.2+.8*rndv[mod(s,NRND)]),g=k;let R=mod(237*k,1),S=mod(191*k,1),z=mod(257*k,1);fac=.01*brr*Math.exp(R)*Math.exp(a[e].RR[p]);let I=sumArrays(f,vecscl(b,i*n*fac*k*u));xxx=f[0],yyy=f[1],xxx=ox+scx*f[0],yyy=oy+scy*f[1];let _=scx*a[e].R*2*(2-clarity)*v*k,B=4*aa0/Nrad0/(1+2*lgfac*(.05+S)*_);if(_>5&&(B=min(B,.1)),M=_,N=B,wild){let e=2.5*mod(57*g,1);_*=.5*Math.exp(e),B*=2*Math.exp(-1.5*e)}w=sumArrays(l,[xe,ye,ze],neg(I)),D=.39+dot(P,w)/norm3(w)/norm3(P)-.03+.03*Math.exp(2*z),focus&&(D+=phase+atan2(a[e].x[p]-.4-.2*rndv[0],a[e].y[p]-.4-.2*rndv[1])),D-=rbow*a[e].RR[p],D+=300*A[e].cf,D=sin(D*PI),D!=D&&(D=0);let J=abs(D);J=clamp(J,.001,.999);let E=pallerp(J);o=[0,0,100],E&&(o=E.slice()),D<0&&(o[0]=(o[0]-120*mono+180-50+100*g)%360,o[1]*=.4+S,o[2]*=.9+.2*z,B*=.5),B*=1+min(3,(1/_)**2),x>Nrad0/4*min(1,_)&&lo&&(lo=0,d=0),d>8*(1+echo)*lfac&&!lo&&(lo=1,x=0),x++,d++,dt=ang,_=min(_,1/n/7),m=4*o[2],vred&&(m*=m/100),lo&&(m*=1.1,B*=.6),m=min(100,m),lightness=m/2;let W=0;W=y+dt,y-=dt,rain&&D>0&&(_*=Math.exp(z));let q=clamp(1-10*a[e].z[p],-3,3);_*=Math.exp(2*clamp(a[e].z[p],-2,2)),q=0;let T=(1-buf)*Lx/2,O=(1-buf)*Ly/2;T=0,O=0,!clean&&t>.6&&1==a[e].open&&p==a[e].x.length-1&&(_=1*Lx/dx,R<pblk?(B=1,m=0):(B=.8,o[1]=0,m=100*(1-night)),r.noStroke()),xxx=str(floor(1e3*xxx)/1e3),yyy=str(floor(1e3*yyy)/1e3),r.fill(o[0],min(100,.95*(1-bw)*o[1]),bfac*m,2*min(1,B));let C=T/Lx+xxx,H=O/Ly+yyy;r.noStroke();let j=max(.8,dx*_);ccircle(Lx*C,Ly*H,j,y,W,q,r),r.stroke(mod(180+o[0],360),2*o[1],.5*o[2],1.4*1.4*h),j*=1.4,r.line(Lx*C,Ly*H,Lx*C+j*cos(y),Ly*H+j*sin(y)),r.line(Lx*C,Ly*H,Lx*C+j*cos(W),Ly*H+j*sin(W))}}}}function str(e){return(1+2*xb)*e}function inscr(e,t){return e>-0&&e<1&&t>-0&&t<1}function inbdy(e,t){return e>-.1&&e<.2||e>.8&&e<1.1||t>-.1&&t<.2||t<1.1&&t>.8}function clamp(e,t,n){return Math.max(t,Math.min(n,e))}let SQ3=Math.sqrt(3);function ccircle(e,t,n,l,o,r,s){let a=1.4*n;s.triangle(e,t,e+a*Math.cos(l),t+a*Math.sin(l),e+a*Math.cos(o),t+a*Math.sin(o))}function proj(e){let t=e[0],n=e[1],l=e[2];return[(t-xe+c1*l)*ze/(ze+l),(n-ye+s1*l)*ze/(ze+l)]}function norm3(e){return Math.sqrt(e[0]*e[0]+e[1]*e[1]+e[2]*e[2])}function vecscl(e,t){let n=[];for(let l=0;l<e.length;l++)n[l]=e[l]*t;return n}function neg(e){return vecscl(e,-1)}function cross(e,t){let n=[];return n[0]=e[1]*t[2]-t[1]*e[2],n[1]=e[2]*t[0]-t[2]*e[0],n[2]=e[0]*t[1]-t[0]*e[1],n}function dot(e,t){return e[0]*t[0]+e[1]*t[1]+e[2]*t[2]}function rot3d(e,t,n){return sumArrays(vecscl(e,Math.cos(n)),vecscl(cross(t,e),sin(n)),vecscl(t,dot(t,e)*(1-Math.cos(n))))}function sumArrays(...e){const t=e.reduce(((e,t)=>Math.max(e,t.length)),0);return Array.from({length:t}).map(((t,n)=>e.map((e=>e[n]||0)).reduce(((e,t)=>e+t),0)))}function mod(e,t){return(e%t+t)%t}function rnd(){return R.random_dec()}function pallerp(e){let t=floor(e*JJ),n=e*JJ-t;return sincol&&(n=fblend(n)),sumArrays(vecscl(pal[t],n),vecscl(pal[mod(t+1,JJ)],1-n))}function unit(e){return vecscl(e,1/norm3(e))}function hlp(e){let t=sqrt(e[0]*e[0]+e[1]*e[1]),n=atan2(e[1],e[0]),l=[ac[0][0]*t,ac[0][1]*t];for(let e=1;e<na;e++)l[0]+=pow(t,e)*(ac[e][0]*cos(e*n)-ac[e][1]*sin(e*n)),l[1]+=pow(t,e)*(ac[e][0]*sin(e*n)+ac[e][1]*cos(e*n));let o=[bc[0][0]*t,bc[0][1]*t];for(let e=1;e<nb;e++)o[0]+=pow(t,e)*(bc[e][0]*cos(e*n)-bc[e][1]*sin(e*n)),o[1]+=pow(t,e)*(bc[e][0]*sin(e*n)+bc[e][1]*cos(e*n));return[t,n,l,o]}function imzeta(e){let t,n,l,o;[t,n,l,o]=hlp(e);let r=o[0]*o[0]+o[1]*o[1];return atan2((l[1]*o[0]-l[0]*o[1])/r,(l[0]*o[0]+l[1]*o[1])/r)}function rezeta(e){let t,n,l,o;[t,n,l,o]=hlp(e);o[0],o[0],o[1],o[1];return.5*log((l[0]*l[0]+l[1]*l[1])/(o[0]*o[0]+o[1]*o[1]))}function gradimzeta(e){let t,n,l,o;[t,n,l,o]=hlp(e);let r=[0,0];for(let e=1;e<na;e++)r[0]+=e*pow(t,e-1)*(ac[e][0]*cos(e*n-n)-ac[e][1]*sin(e*n-n)),r[1]+=e*pow(t,e-1)*(ac[e][0]*sin(e*n-n)+ac[e][1]*cos(e*n-n));let s=[0,0];for(let e=1;e<nb;e++)s[0]+=e*pow(t,e-1)*(bc[e][0]*cos(e*n-n)-bc[e][1]*sin(e*n-n)),s[1]+=e*pow(t,e-1)*(bc[e][0]*sin(e*n-n)+bc[e][1]*cos(e*n-n));let a=o[0]*o[0]+o[1]*o[1],i=l[0]*l[0]+l[1]*l[1];return 0==i&&(i=.001),0==a&&(a=.001),[(r[1]*l[0]-r[0]*l[1])/i-(s[1]*o[0]-s[0]*o[1])/a,(r[0]*l[0]+r[1]*l[1])/i-(s[0]*o[0]+s[1]*o[1])/a]}function windowResized(){resizing=1,rsz_time=millis(),!head&&loop(),0!=dpx&&(pixelDensity(max(1,pd+dpx)),ob.pixelDensity(max(1,pd+dpx)),pc.pixelDensity(max(1,pd+dpx))),dpx=0,!head&&init()}function bg(){(lamr=1-0.2*kand*(hex==0)),colorMode(HSB),angleMode(RADIANS),noStroke(),ob.colorMode(HSB),ob.angleMode(RADIANS),ob.noStroke(),begin(hx,bsat),tik=0,loop(),buf=1}function PD(e){pixelDensity(e),ob.pixelDensity(e),pc.pixelDensity(e),pd=pixelDensity(),bg()}function drawbord(){let e=min(Lx,Ly)/40;noStroke(),fill(0,0,100*(1-kand),.85);let t=-Lx/2,n=-Ly/2;t=0,n=0,rect(0,0,e,Ly),rect(0+Lx-e,0,e,Ly),rect(0+e,0,Lx-2*e,e),rect(0+e,0+Ly-e,Lx-2*e,e),fill(0,0,100*(1-kand),1),e/=4,rect(0,0,e,Ly),rect(0+Lx-e,0,e,Ly),rect(0+e,0,Lx-2*e,e),rect(0+e,0+Ly-e,Lx-2*e,e),blendMode(BLEND)}let lsw=1,bor=1;function keyPressed(){"1"==key&&PD(1),"2"==key&&PD(2),"3"==key&&PD(3),"4"==key&&PD(4),"5"==key&&PD(5),"6"==key&&PD(6),"7"==key&&PD(7),"8"==key&&PD(8),"9"==key&&PD(9),"+"==key&&PD(pd+1),"-"==key&&PD(max(1,pd-1)),"f"==key&&(sq=!sq,sq&&(aspect=aspect0),windowResized()),"b"==key&&(bor=!bor,image(ob,0,0,Lx,Ly,Lx*xb/3,Ly*xb/3,Lx,Ly),bor&&drawbord()),"s"==key&&saveCanvas("Glass_"+tokenData.hash+".png"),"n"==key&&(kand=1-kand,kblk=1-kand,bor=0,bg()),"o"==key&&(outline=1-outline,bg()),32==keyCode&&(keyst=!keyst,keyst?noLoop():loop()),0==tik&&bg()}class Random{constructor(){this.useA=!1;let e=function(e){let t=parseInt(e.substr(0,8),16),n=parseInt(e.substr(8,8),16),l=parseInt(e.substr(16,8),16),o=parseInt(e.substr(24,8),16);return function(){t|=0,n|=0,l|=0,o|=0;let e=(t+n|0)+o|0;return o=o+1|0,t=n^n>>>9,n=l+(l<<3)|0,l=l<<21|l>>>11,l=l+e|0,(e>>>0)/4294967296}};this.prngA=new e(tokenData.hash.substr(2,32)),this.prngB=new e(tokenData.hash.substr(34,32));for(let e=0;e<1e6;e+=2)this.prngA(),this.prngB()}random_dec(){return this.useA=!this.useA,this.useA?this.prngA():this.prngB()}}
function draw(){if(tik>0&&tik<NA-es-1){let e=buf?ob:this,t=tik%NA,n=[A[t].r[0],A[t].r[1]];e.fill(0,0,100,1),e.blendMode(ADD),pc.blendMode(BLEND);let l=255*clamp(Math.exp(10/JN*log(.85))*(1-kblk)+.3*clamp((n[0]-.5)*(n[0]-.5)-(n[1]-.5)*(n[1]-.5),0,1),0,1);pc.fill(l),pc.stroke(l),pc.strokeWeight(.6),0&&e.circle(1.1*Lx*A[t].r[0]-.05,1.1*Ly*A[t].r[1]-.05,2*Lx*A[t].R*1);let o=[a[t].x[a[t].x.length-1],a[t].y[a[t].x.length-1]];o=sumArrays(vecscl(n,1-lamr),vecscl(o,lamr));if(dist)for(let e=0;e<a[t].x.length;e++){let l=mod(e,a[t].x.length);let poo=[a[t].x[l],a[t].y[l]];poo=sumArrays(vecscl(n,1-lamr),vecscl(poo,lamr));pc.triangle(Lx*str(ox+scx*n[0]),Ly*str(oy+scy*n[1]),Lx*str(ox+scx*o[0]),Ly*str(oy+scy*o[1]),Lx*str(ox+scx*poo[0]),Ly*str(oy+scy*poo[1]));o=poo}else pc.circle(Lx*str(ox+scx*n[0]),Ly*str(oy+scy*n[1]),lamr*.99*scx*Lx*2*A[t].R);if(outline){e.noFill(),e.stroke(0,0,100*(1-night),1);let n=.5*dc*.5/2/tan(ang);e.strokeWeight(Lx*min(max(.2*dc,scx*n),.6*dc)),e.beginShape();let l,o,r,s,i=[],c=1;for(let n=0;n<a[t].x.length;n++)i=[a[t].x[n],a[t].y[n]],l=ox+scx*i[0],o=oy+scy*i[1],r=10*floor(l)+floor(o),n>0&&r!=s&&(e.endShape(),e.beginShape(),c=0),s=r,c&&l<2&&l>-2&&o<2&&o>-2&&e.curveVertex(Lx*l,Ly*o);e.endShape()}e.blendMode(BLEND)}let e=0;for(;tik<NA-es&&e<step;)drawk(tik),tik++,e++;if(buf){let e=tik/step0*TWO_PI;fill(360*e/TWO_PI,90,100),circle(Lx/2+60*dx*cos(e),Ly/2+60*dx*sin(e),3*dx)}if(buf&&tik>=step0&&(image(ob,0,0,Lx,Ly,Lx*xb/3,Ly*xb/3,Lx,Ly),t0=millis(),step=1,buf=0),tik>=NA-es&&(1==kand||emboss)){image(ob,0,0,Lx,Ly,Lx*xb/3,Ly*xb/3,Lx,Ly);let e=JN;JN>2&&(e+=6*kand);let t=tphase+(millis()-t0)/3e5*PI;if(kand)for(let n=1;n<e;n++)blend(pc,blsh*Lx*xb/3*n/e*cos(t),blsh*Ly*xb/3*n/e*sin(t),width*pd,height*pd,0,0,width*pd,height*pd,MULTIPLY);else for(let n=1;n<e;n++)blend(pc,blsh*Lx*xb/3*n/e*cos(t),blsh*Ly*xb/3*n/e*sin(t),width*pd,height*pd,0,0,width*pd,height*pd,SCREEN);if(vred||(fill(hx,bsat,255,.1),rect(0,0,Lx,Ly)),!kand&&contr){loadPixels();let e=4*(width*pd)*(height*pd);for(let t=0;t<e;t+=4){let e=[pixels[t],pixels[t+1],pixels[t+2]],n=color(e[0],e[1],e[2]),l=brightness(n)/100,o=1.2*(.4+.6*fblend(l*l));contr_x>0&&(o*=1.4*o);let r=1+vred*(l-1);pixels[t+0]=r*(o*(e[0]-128)+v0),pixels[t+1]=r*(o*(e[1]-128)+v0),pixels[t+2]=r*(o*(e[2]-128)+v0)}updatePixels()}}tik>=NA-es&&(tik++,bor&&drawbord(),head&&noLoop())}function drawk(e){let t=max(.01,1-e/(.1+NA-atten*es)),n=dx/Lx,l=mod(hx+5*(e-NA)*coltik,360),o=(2-bsat/20)*t*.1*rndv[e%NRND]/2,r=buf?ob:this;if(e%20==0&&(r.blendMode(SCREEN),r.fill(l,bsat,100-3*(2*t-1)*1.5*(1+fade)*dlum,1*(1+fade)*max(0,o)),r.rect(0,0,Lxb,Lyb),r.blendMode(BLEND)),e<NA){let l=rlight.slice();l=rot3d(l,[0,0,1],t*PI);let o=[120,30,10];col=[];let s=0,i=1,c=pal[pal.length-1][0],x=0,d=0;for(let p=0;p<a[e].x.length;p++){let y=1,h=(dx,5*(2+fade)*min(.1,1.3*y)*pd/2/2*.1*lnwght);x=0,d=0,lo=1,lo*=lsw,h*=1+4*bw,lo?r.stroke(c,100,.2*lightness,h):r.noStroke();let b=1.3*max(.1,1.3*y)*2/pd*dx/14;r.strokeWeight(b);let f=[a[e].x[p],a[e].y[p],a[e].z[p]],u=.6*a[e].R,L=a[e].v[0];i*=y;let m,k,g,w,D,M,N,v=rr0;for(let c=0;c<Nrad0;c++){s++,i=min(.15*n,i),i=max(.7*n,i);let y=pinch*a[e].t1[p];hatch&&(y=floor(y*hatchn/TWO_PI)*TWO_PI/hatchn),y=phase,y+=flow*a[e].RR[p]/2;let b=rot3d([cos(y),sin(y),0],a[e].v[p],c/Nrad0*TWO_PI),P=sumArrays(vecscl(b,1-lam),vecscl(L,lam));L=P,k=clarity+(1-clarity)*(.2+.8*rndv[mod(s,NRND)]),g=k;let R=mod(237*k,1),S=mod(191*k,1),z=mod(257*k,1);fac=.01*brr*Math.exp(R)*Math.exp(a[e].RR[p]);let I=sumArrays(f,vecscl(b,i*n*fac*k*u));xxx=f[0],yyy=f[1],xxx=ox+scx*f[0],yyy=oy+scy*f[1];let _=scx*a[e].R*2*(2-clarity)*v*k,B=4*aa0/Nrad0/(1+2*lgfac*(.05+S)*_);if(_>5&&(B=min(B,.1)),M=_,N=B,wild){let e=2.5*mod(57*g,1);_*=.5*Math.exp(e),B*=2*Math.exp(-1.5*e)}w=sumArrays(l,[xe,ye,ze],neg(I)),D=.39+dot(P,w)/norm3(w)/norm3(P)-.03+.03*Math.exp(2*z),focus&&(D+=phase+atan2(a[e].x[p]-.4-.2*rndv[0],a[e].y[p]-.4-.2*rndv[1])),D-=rbow*a[e].RR[p],D+=300*A[e].cf,D=sin(D*PI),D!=D&&(D=0);let J=abs(D);J=clamp(J,.001,.999);let E=pallerp(J);o=[0,0,100],E&&(o=E.slice()),D<0&&(o[0]=(o[0]-120*mono+180-50+100*g)%360,o[1]*=.4+S,o[2]*=.9+.2*z,B*=.5),B*=1+min(3,(1/_)**2),x>Nrad0/4*min(1,_)&&lo&&(lo=0,d=0),d>8*(1+echo)*lfac&&!lo&&(lo=1,x=0),x++,d++,dt=ang,_=min(_,1/n/7),m=4*o[2],vred&&(m*=m/100),lo&&(m*=1.1,B*=.6),m=min(100,m),lightness=m/2;let W=0;W=y+dt,y-=dt,rain&&D>0&&(_*=Math.exp(z));let q=clamp(1-10*a[e].z[p],-3,3);_*=Math.exp(2*clamp(a[e].z[p],-2,2)),q=0;let T=(1-buf)*Lx/2,O=(1-buf)*Ly/2;T=0,O=0,!clean&&t>.6&&1==a[e].open&&p==a[e].x.length-1&&(_=1*Lx/dx,R<pblk?(B=1,m=0):(B=.8,o[1]=0,m=100*(1-night)),r.noStroke()),xxx=str(floor(1e3*xxx)/1e3),yyy=str(floor(1e3*yyy)/1e3),r.fill(o[0],min(100,.95*(1-bw)*o[1]),bfac*m,2*min(1,B));let C=T/Lx+xxx,H=O/Ly+yyy;r.noStroke();let j=max(.8,dx*_);ccircle(Lx*C,Ly*H,j,y,W,q,r),r.stroke(mod(180+o[0],360),2*o[1],.5*o[2],1.4*1.4*h),j*=1.4,r.line(Lx*C,Ly*H,Lx*C+j*cos(y),Ly*H+j*sin(y)),r.line(Lx*C,Ly*H,Lx*C+j*cos(W),Ly*H+j*sin(W))}}}}function str(e){return(1+2*xb)*e}function inscr(e,t){return e>-0&&e<1&&t>-0&&t<1}function inbdy(e,t){return e>-.1&&e<.2||e>.8&&e<1.1||t>-.1&&t<.2||t<1.1&&t>.8}function clamp(e,t,n){return Math.max(t,Math.min(n,e))}let SQ3=Math.sqrt(3);function ccircle(e,t,n,l,o,r,s){let a=1.4*n;s.triangle(e,t,e+a*Math.cos(l),t+a*Math.sin(l),e+a*Math.cos(o),t+a*Math.sin(o))}function proj(e){let t=e[0],n=e[1],l=e[2];return[(t-xe+c1*l)*ze/(ze+l),(n-ye+s1*l)*ze/(ze+l)]}function norm3(e){return Math.sqrt(e[0]*e[0]+e[1]*e[1]+e[2]*e[2])}function vecscl(e,t){let n=[];for(let l=0;l<e.length;l++)n[l]=e[l]*t;return n}function neg(e){return vecscl(e,-1)}function cross(e,t){let n=[];return n[0]=e[1]*t[2]-t[1]*e[2],n[1]=e[2]*t[0]-t[2]*e[0],n[2]=e[0]*t[1]-t[0]*e[1],n}function dot(e,t){return e[0]*t[0]+e[1]*t[1]+e[2]*t[2]}function rot3d(e,t,n){return sumArrays(vecscl(e,Math.cos(n)),vecscl(cross(t,e),sin(n)),vecscl(t,dot(t,e)*(1-Math.cos(n))))}function sumArrays(...e){const t=e.reduce(((e,t)=>Math.max(e,t.length)),0);return Array.from({length:t}).map(((t,n)=>e.map((e=>e[n]||0)).reduce(((e,t)=>e+t),0)))}function mod(e,t){return(e%t+t)%t}function rnd(){return R.random_dec()}function pallerp(e){let t=floor(e*JJ),n=e*JJ-t;return sincol&&(n=fblend(n)),sumArrays(vecscl(pal[t],n),vecscl(pal[mod(t+1,JJ)],1-n))}function unit(e){return vecscl(e,1/norm3(e))}function hlp(e){let t=sqrt(e[0]*e[0]+e[1]*e[1]),n=atan2(e[1],e[0]),l=[ac[0][0]*t,ac[0][1]*t];for(let e=1;e<na;e++)l[0]+=pow(t,e)*(ac[e][0]*cos(e*n)-ac[e][1]*sin(e*n)),l[1]+=pow(t,e)*(ac[e][0]*sin(e*n)+ac[e][1]*cos(e*n));let o=[bc[0][0]*t,bc[0][1]*t];for(let e=1;e<nb;e++)o[0]+=pow(t,e)*(bc[e][0]*cos(e*n)-bc[e][1]*sin(e*n)),o[1]+=pow(t,e)*(bc[e][0]*sin(e*n)+bc[e][1]*cos(e*n));return[t,n,l,o]}function imzeta(e){let t,n,l,o;[t,n,l,o]=hlp(e);let r=o[0]*o[0]+o[1]*o[1];return atan2((l[1]*o[0]-l[0]*o[1])/r,(l[0]*o[0]+l[1]*o[1])/r)}function rezeta(e){let t,n,l,o;[t,n,l,o]=hlp(e);o[0],o[0],o[1],o[1];return.5*log((l[0]*l[0]+l[1]*l[1])/(o[0]*o[0]+o[1]*o[1]))}function gradimzeta(e){let t,n,l,o;[t,n,l,o]=hlp(e);let r=[0,0];for(let e=1;e<na;e++)r[0]+=e*pow(t,e-1)*(ac[e][0]*cos(e*n-n)-ac[e][1]*sin(e*n-n)),r[1]+=e*pow(t,e-1)*(ac[e][0]*sin(e*n-n)+ac[e][1]*cos(e*n-n));let s=[0,0];for(let e=1;e<nb;e++)s[0]+=e*pow(t,e-1)*(bc[e][0]*cos(e*n-n)-bc[e][1]*sin(e*n-n)),s[1]+=e*pow(t,e-1)*(bc[e][0]*sin(e*n-n)+bc[e][1]*cos(e*n-n));let a=o[0]*o[0]+o[1]*o[1],i=l[0]*l[0]+l[1]*l[1];return 0==i&&(i=.001),0==a&&(a=.001),[(r[1]*l[0]-r[0]*l[1])/i-(s[1]*o[0]-s[0]*o[1])/a,(r[0]*l[0]+r[1]*l[1])/i-(s[0]*o[0]+s[1]*o[1])/a]}function windowResized(){resizing=1,rsz_time=millis(),!head&&loop(),0!=dpx&&(pixelDensity(max(1,pd+dpx)),ob.pixelDensity(max(1,pd+dpx)),pc.pixelDensity(max(1,pd+dpx))),dpx=0,!head&&init()}function bg(){(lamr=1-0.2*kand*(hex==0)),colorMode(HSB),angleMode(RADIANS),noStroke(),ob.colorMode(HSB),ob.angleMode(RADIANS),ob.noStroke(),begin(hx,bsat),tik=0,loop(),buf=1}function PD(e){pixelDensity(e),ob.pixelDensity(e),pc.pixelDensity(e),bg()}function drawbord(){let e=min(Lx,Ly)/40;noStroke(),fill(0,0,100*(1-kand),.85);let t=-Lx/2,n=-Ly/2;t=0,n=0,rect(0,0,e,Ly),rect(0+Lx-e,0,e,Ly),rect(0+e,0,Lx-2*e,e),rect(0+e,0+Ly-e,Lx-2*e,e),fill(0,0,100*(1-kand),1),e/=4,rect(0,0,e,Ly),rect(0+Lx-e,0,e,Ly),rect(0+e,0,Lx-2*e,e),rect(0+e,0+Ly-e,Lx-2*e,e),blendMode(BLEND)}let lsw=1,bor=1;function keyPressed(){"1"==key&&PD(1),"2"==key&&PD(2),"3"==key&&PD(3),"4"==key&&PD(4),"5"==key&&PD(5),"6"==key&&PD(6),"7"==key&&PD(7),"8"==key&&PD(8),"9"==key&&PD(9),"+"==key&&PD(pd+1),"-"==key&&PD(max(1,pd-1)),"f"==key&&(sq=!sq,sq&&(aspect=aspect0),windowResized()),"b"==key&&(bor=!bor,image(ob,0,0,Lx,Ly,Lx*xb/3,Ly*xb/3,Lx,Ly),bor&&drawbord()),"s"==key&&saveCanvas("Glass_"+tokenData.hash+".png"),"n"==key&&(kand=1-kand,kblk=1-kand,bor=0,bg()),"o"==key&&(outline=1-outline,bg()),32==keyCode&&(keyst=!keyst,keyst?noLoop():loop()),0==tik&&bg()}class Random{constructor(){this.useA=!1;let e=function(e){let t=parseInt(e.substr(0,8),16),n=parseInt(e.substr(8,8),16),l=parseInt(e.substr(16,8),16),o=parseInt(e.substr(24,8),16);return function(){t|=0,n|=0,l|=0,o|=0;let e=(t+n|0)+o|0;return o=o+1|0,t=n^n>>>9,n=l+(l<<3)|0,l=l<<21|l>>>11,l=l+e|0,(e>>>0)/4294967296}};this.prngA=new e(tokenData.hash.substr(2,32)),this.prngB=new e(tokenData.hash.substr(34,32));for(let e=0;e<1e6;e+=2)this.prngA(),this.prngB()}random_dec(){return this.useA=!this.useA,this.useA?this.prngA():this.prngB()}}
function draw(){if(tik>0&&tik<NA-es-1){let e=buf?ob:this,t=tik%NA,n=[A[t].r[0],A[t].r[1]];e.fill(0,0,100,1),e.blendMode(ADD),pc.blendMode(BLEND);let l=255*clamp(Math.exp(10/JN*log(.85))*(1-kblk)+.3*clamp((n[0]-.5)*(n[0]-.5)-(n[1]-.5)*(n[1]-.5),0,1),0,1);pc.fill(l),pc.stroke(l),pc.strokeWeight(.6),0&&e.circle(1.1*Lx*A[t].r[0]-.05,1.1*Ly*A[t].r[1]-.05,2*Lx*A[t].R*1);let o=[a[t].x[a[t].x.length-1],a[t].y[a[t].x.length-1]];o=sumArrays(vecscl(n,1-lamr),vecscl(o,lamr));if(dist)for(let e=0;e<a[t].x.length;e++){let poo=[a[t].x[l],a[t].y[l]];poo=sumArrays(vecscl(n,1-lamr),vecscl(poo,lamr));let l=mod(e,a[t].x.length);pc.triangle(Lx*str(ox+scx*n[0]),Ly*str(oy+scy*n[1]),Lx*str(ox+scx*o[0]),Ly*str(oy+scy*o[1]),Lx*str(ox+scx*poo[0]),Ly*str(oy+scy*poo[1]));o=poo}else pc.circle(Lx*str(ox+scx*n[0]),Ly*str(oy+scy*n[1]),lamr*.99*scx*Lx*2*A[t].R);if(outline){e.noFill(),e.stroke(0,0,100*(1-night),1);let n=.5*dc*.5/2/tan(ang);e.strokeWeight(Lx*min(max(.2*dc,scx*n),.6*dc)),e.beginShape();let l,o,r,s,i=[],c=1;for(let n=0;n<a[t].x.length;n++)i=[a[t].x[n],a[t].y[n]],l=ox+scx*i[0],o=oy+scy*i[1],r=10*floor(l)+floor(o),n>0&&r!=s&&(e.endShape(),e.beginShape(),c=0),s=r,c&&l<2&&l>-2&&o<2&&o>-2&&e.curveVertex(Lx*l,Ly*o);e.endShape()}e.blendMode(BLEND)}let e=0;for(;tik<NA-es&&e<step;)drawk(tik),tik++,e++;if(buf){let e=tik/step0*TWO_PI;fill(360*e/TWO_PI,90,100),circle(Lx/2+60*dx*cos(e),Ly/2+60*dx*sin(e),3*dx)}if(buf&&tik>=step0&&(image(ob,0,0,Lx,Ly,Lx*xb/3,Ly*xb/3,Lx,Ly),t0=millis(),step=1,buf=0),tik>=NA-es&&(1==kand||emboss)){image(ob,0,0,Lx,Ly,Lx*xb/3,Ly*xb/3,Lx,Ly);let e=JN;JN>2&&(e+=6*kand);let t=tphase+(millis()-t0)/3e5*PI;if(kand)for(let n=1;n<e;n++)blend(pc,blsh*Lx*xb/3*n/e*cos(t),blsh*Ly*xb/3*n/e*sin(t),width*pd,height*pd,0,0,width*pd,height*pd,MULTIPLY);else for(let n=1;n<e;n++)blend(pc,blsh*Lx*xb/3*n/e*cos(t),blsh*Ly*xb/3*n/e*sin(t),width*pd,height*pd,0,0,width*pd,height*pd,SCREEN);if(vred||(fill(hx,bsat,255,.1),rect(0,0,Lx,Ly)),!kand&&contr){loadPixels();let e=4*(width*pd)*(height*pd);for(let t=0;t<e;t+=4){let e=[pixels[t],pixels[t+1],pixels[t+2]],n=color(e[0],e[1],e[2]),l=brightness(n)/100,o=1.2*(.4+.6*fblend(l*l));contr_x>0&&(o*=1.4*o);let r=1+vred*(l-1);pixels[t+0]=r*(o*(e[0]-128)+v0),pixels[t+1]=r*(o*(e[1]-128)+v0),pixels[t+2]=r*(o*(e[2]-128)+v0)}updatePixels()}}tik>=NA-es&&(tik++,bor&&drawbord(),head&&noLoop())}function drawk(e){let t=max(.01,1-e/(.1+NA-atten*es)),n=dx/Lx,l=mod(hx+5*(e-NA)*coltik,360),o=(2-bsat/20)*t*.1*rndv[e%NRND]/2,r=buf?ob:this;if(e%20==0&&(r.blendMode(SCREEN),r.fill(l,bsat,100-3*(2*t-1)*1.5*(1+fade)*dlum,1*(1+fade)*max(0,o)),r.rect(0,0,Lxb,Lyb),r.blendMode(BLEND)),e<NA){let l=rlight.slice();l=rot3d(l,[0,0,1],t*PI);let o=[120,30,10];col=[];let s=0,i=1,c=pal[pal.length-1][0],x=0,d=0;for(let p=0;p<a[e].x.length;p++){let y=1,h=(dx,5*(2+fade)*min(.1,1.3*y)*pd/2/2*.1*lnwght);x=0,d=0,lo=1,lo*=lsw,h*=1+4*bw,lo?r.stroke(c,100,.2*lightness,h):r.noStroke();let b=1.3*max(.1,1.3*y)*2/pd*dx/14;r.strokeWeight(b);let f=[a[e].x[p],a[e].y[p],a[e].z[p]],u=.6*a[e].R,L=a[e].v[0];i*=y;let m,k,g,w,D,M,N,v=rr0;for(let c=0;c<Nrad0;c++){s++,i=min(.15*n,i),i=max(.7*n,i);let y=pinch*a[e].t1[p];hatch&&(y=floor(y*hatchn/TWO_PI)*TWO_PI/hatchn),y=phase,y+=flow*a[e].RR[p]/2;let b=rot3d([cos(y),sin(y),0],a[e].v[p],c/Nrad0*TWO_PI),P=sumArrays(vecscl(b,1-lam),vecscl(L,lam));L=P,k=clarity+(1-clarity)*(.2+.8*rndv[mod(s,NRND)]),g=k;let R=mod(237*k,1),S=mod(191*k,1),z=mod(257*k,1);fac=.01*brr*Math.exp(R)*Math.exp(a[e].RR[p]);let I=sumArrays(f,vecscl(b,i*n*fac*k*u));xxx=f[0],yyy=f[1],xxx=ox+scx*f[0],yyy=oy+scy*f[1];let _=scx*a[e].R*2*(2-clarity)*v*k,B=4*aa0/Nrad0/(1+2*lgfac*(.05+S)*_);if(_>5&&(B=min(B,.1)),M=_,N=B,wild){let e=2.5*mod(57*g,1);_*=.5*Math.exp(e),B*=2*Math.exp(-1.5*e)}w=sumArrays(l,[xe,ye,ze],neg(I)),D=.39+dot(P,w)/norm3(w)/norm3(P)-.03+.03*Math.exp(2*z),focus&&(D+=phase+atan2(a[e].x[p]-.4-.2*rndv[0],a[e].y[p]-.4-.2*rndv[1])),D-=rbow*a[e].RR[p],D+=300*A[e].cf,D=sin(D*PI),D!=D&&(D=0);let J=abs(D);J=clamp(J,.001,.999);let E=pallerp(J);o=[0,0,100],E&&(o=E.slice()),D<0&&(o[0]=(o[0]-120*mono+180-50+100*g)%360,o[1]*=.4+S,o[2]*=.9+.2*z,B*=.5),B*=1+min(3,(1/_)**2),x>Nrad0/4*min(1,_)&&lo&&(lo=0,d=0),d>8*(1+echo)*lfac&&!lo&&(lo=1,x=0),x++,d++,dt=ang,_=min(_,1/n/7),m=4*o[2],vred&&(m*=m/100),lo&&(m*=1.1,B*=.6),m=min(100,m),lightness=m/2;let W=0;W=y+dt,y-=dt,rain&&D>0&&(_*=Math.exp(z));let q=clamp(1-10*a[e].z[p],-3,3);_*=Math.exp(2*clamp(a[e].z[p],-2,2)),q=0;let T=(1-buf)*Lx/2,O=(1-buf)*Ly/2;T=0,O=0,!clean&&t>.6&&1==a[e].open&&p==a[e].x.length-1&&(_=1*Lx/dx,R<pblk?(B=1,m=0):(B=.8,o[1]=0,m=100*(1-night)),r.noStroke()),xxx=str(floor(1e3*xxx)/1e3),yyy=str(floor(1e3*yyy)/1e3),r.fill(o[0],min(100,.95*(1-bw)*o[1]),bfac*m,2*min(1,B));let C=T/Lx+xxx,H=O/Ly+yyy;r.noStroke();let j=max(.8,dx*_);ccircle(Lx*C,Ly*H,j,y,W,q,r),r.stroke(mod(180+o[0],360),2*o[1],.5*o[2],1.4*1.4*h),j*=1.4,r.line(Lx*C,Ly*H,Lx*C+j*cos(y),Ly*H+j*sin(y)),r.line(Lx*C,Ly*H,Lx*C+j*cos(W),Ly*H+j*sin(W))}}}}function str(e){return(1+2*xb)*e}function inscr(e,t){return e>-0&&e<1&&t>-0&&t<1}function inbdy(e,t){return e>-.1&&e<.2||e>.8&&e<1.1||t>-.1&&t<.2||t<1.1&&t>.8}function clamp(e,t,n){return Math.max(t,Math.min(n,e))}let SQ3=Math.sqrt(3);function ccircle(e,t,n,l,o,r,s){let a=1.4*n;s.triangle(e,t,e+a*Math.cos(l),t+a*Math.sin(l),e+a*Math.cos(o),t+a*Math.sin(o))}function proj(e){let t=e[0],n=e[1],l=e[2];return[(t-xe+c1*l)*ze/(ze+l),(n-ye+s1*l)*ze/(ze+l)]}function norm3(e){return Math.sqrt(e[0]*e[0]+e[1]*e[1]+e[2]*e[2])}function vecscl(e,t){let n=[];for(let l=0;l<e.length;l++)n[l]=e[l]*t;return n}function neg(e){return vecscl(e,-1)}function cross(e,t){let n=[];return n[0]=e[1]*t[2]-t[1]*e[2],n[1]=e[2]*t[0]-t[2]*e[0],n[2]=e[0]*t[1]-t[0]*e[1],n}function dot(e,t){return e[0]*t[0]+e[1]*t[1]+e[2]*t[2]}function rot3d(e,t,n){return sumArrays(vecscl(e,Math.cos(n)),vecscl(cross(t,e),sin(n)),vecscl(t,dot(t,e)*(1-Math.cos(n))))}function sumArrays(...e){const t=e.reduce(((e,t)=>Math.max(e,t.length)),0);return Array.from({length:t}).map(((t,n)=>e.map((e=>e[n]||0)).reduce(((e,t)=>e+t),0)))}function mod(e,t){return(e%t+t)%t}function rnd(){return R.random_dec()}function pallerp(e){let t=floor(e*JJ),n=e*JJ-t;return sincol&&(n=fblend(n)),sumArrays(vecscl(pal[t],n),vecscl(pal[mod(t+1,JJ)],1-n))}function unit(e){return vecscl(e,1/norm3(e))}function hlp(e){let t=sqrt(e[0]*e[0]+e[1]*e[1]),n=atan2(e[1],e[0]),l=[ac[0][0]*t,ac[0][1]*t];for(let e=1;e<na;e++)l[0]+=pow(t,e)*(ac[e][0]*cos(e*n)-ac[e][1]*sin(e*n)),l[1]+=pow(t,e)*(ac[e][0]*sin(e*n)+ac[e][1]*cos(e*n));let o=[bc[0][0]*t,bc[0][1]*t];for(let e=1;e<nb;e++)o[0]+=pow(t,e)*(bc[e][0]*cos(e*n)-bc[e][1]*sin(e*n)),o[1]+=pow(t,e)*(bc[e][0]*sin(e*n)+bc[e][1]*cos(e*n));return[t,n,l,o]}function imzeta(e){let t,n,l,o;[t,n,l,o]=hlp(e);let r=o[0]*o[0]+o[1]*o[1];return atan2((l[1]*o[0]-l[0]*o[1])/r,(l[0]*o[0]+l[1]*o[1])/r)}function rezeta(e){let t,n,l,o;[t,n,l,o]=hlp(e);o[0],o[0],o[1],o[1];return.5*log((l[0]*l[0]+l[1]*l[1])/(o[0]*o[0]+o[1]*o[1]))}function gradimzeta(e){let t,n,l,o;[t,n,l,o]=hlp(e);let r=[0,0];for(let e=1;e<na;e++)r[0]+=e*pow(t,e-1)*(ac[e][0]*cos(e*n-n)-ac[e][1]*sin(e*n-n)),r[1]+=e*pow(t,e-1)*(ac[e][0]*sin(e*n-n)+ac[e][1]*cos(e*n-n));let s=[0,0];for(let e=1;e<nb;e++)s[0]+=e*pow(t,e-1)*(bc[e][0]*cos(e*n-n)-bc[e][1]*sin(e*n-n)),s[1]+=e*pow(t,e-1)*(bc[e][0]*sin(e*n-n)+bc[e][1]*cos(e*n-n));let a=o[0]*o[0]+o[1]*o[1],i=l[0]*l[0]+l[1]*l[1];return 0==i&&(i=.001),0==a&&(a=.001),[(r[1]*l[0]-r[0]*l[1])/i-(s[1]*o[0]-s[0]*o[1])/a,(r[0]*l[0]+r[1]*l[1])/i-(s[0]*o[0]+s[1]*o[1])/a]}function windowResized(){resizing=1,rsz_time=millis(),!head&&loop(),0!=dpx&&(pixelDensity(max(1,pd+dpx)),ob.pixelDensity(max(1,pd+dpx)),pc.pixelDensity(max(1,pd+dpx))),dpx=0,!head&&init()}function bg(){(lamr=1-0.2*kand*(hex==0)),colorMode(HSB),angleMode(RADIANS),noStroke(),ob.colorMode(HSB),ob.angleMode(RADIANS),ob.noStroke(),begin(hx,bsat),tik=0,loop(),buf=1}function PD(e){pixelDensity(e),ob.pixelDensity(e),pc.pixelDensity(e),bg()}function drawbord(){let e=min(Lx,Ly)/40;noStroke(),fill(0,0,100*(1-kand),.85);let t=-Lx/2,n=-Ly/2;t=0,n=0,rect(0,0,e,Ly),rect(0+Lx-e,0,e,Ly),rect(0+e,0,Lx-2*e,e),rect(0+e,0+Ly-e,Lx-2*e,e),fill(0,0,100*(1-kand),1),e/=4,rect(0,0,e,Ly),rect(0+Lx-e,0,e,Ly),rect(0+e,0,Lx-2*e,e),rect(0+e,0+Ly-e,Lx-2*e,e),blendMode(BLEND)}let lsw=1,bor=1;function keyPressed(){"1"==key&&PD(1),"2"==key&&PD(2),"3"==key&&PD(3),"4"==key&&PD(4),"5"==key&&PD(5),"6"==key&&PD(6),"7"==key&&PD(7),"8"==key&&PD(8),"9"==key&&PD(9),"+"==key&&PD(pd+1),"-"==key&&PD(max(1,pd-1)),"f"==key&&(sq=!sq,sq&&(aspect=aspect0),windowResized()),"b"==key&&(bor=!bor,image(ob,0,0,Lx,Ly,Lx*xb/3,Ly*xb/3,Lx,Ly),bor&&drawbord()),"s"==key&&saveCanvas("Glass_"+tokenData.hash+".png"),"n"==key&&(kand=1-kand,kblk=1-kand,bor=0,bg()),"o"==key&&(outline=1-outline,bg()),32==keyCode&&(keyst=!keyst,keyst?noLoop():loop()),0==tik&&bg()}class Random{constructor(){this.useA=!1;let e=function(e){let t=parseInt(e.substr(0,8),16),n=parseInt(e.substr(8,8),16),l=parseInt(e.substr(16,8),16),o=parseInt(e.substr(24,8),16);return function(){t|=0,n|=0,l|=0,o|=0;let e=(t+n|0)+o|0;return o=o+1|0,t=n^n>>>9,n=l+(l<<3)|0,l=l<<21|l>>>11,l=l+e|0,(e>>>0)/4294967296}};this.prngA=new e(tokenData.hash.substr(2,32)),this.prngB=new e(tokenData.hash.substr(34,32));for(let e=0;e<1e6;e+=2)this.prngA(),this.prngB()}random_dec(){return this.useA=!this.useA,this.useA?this.prngA():this.prngB()}}
function draw(){if(tik>0&&tik<NA-es-1){let e=buf?ob:this,t=tik%NA,n=[A[t].r[0],A[t].r[1]];e.fill(0,0,100,1),e.blendMode(ADD),pc.blendMode(BLEND);let l=255*clamp(Math.exp(10/JN*log(.85))*(1-kblk)+.3*clamp((n[0]-.5)*(n[0]-.5)-(n[1]-.5)*(n[1]-.5),0,1),0,1);pc.fill(l),pc.stroke(l),pc.strokeWeight(.6),0&&e.circle(1.1*Lx*A[t].r[0]-.05,1.1*Ly*A[t].r[1]-.05,2*Lx*A[t].R*1);let o=[a[t].x[a[t].x.length-1],a[t].y[a[t].x.length-1]];o=sumArrays(vecscl(n,1-lamr),vecscl(o,lamr));if(dist)for(let e=0;e<a[t].x.length;e++){let l=mod(e,a[t].x.length);pc.triangle(Lx*str(ox+scx*n[0]),Ly*str(oy+scy*n[1]),Lx*str(ox+scx*o[0]),Ly*str(oy+scy*o[1]),Lx*str(ox+scx*a[t].x[l]),Ly*str(oy+scy*a[t].y[l])),o=[a[t].x[l],a[t].y[l]],o=sumArrays(vecscl(n,1-lamr),vecscl(o,lamr))}else pc.circle(Lx*str(ox+scx*n[0]),Ly*str(oy+scy*n[1]),lamr*.99*scx*Lx*2*A[t].R);if(outline){e.noFill(),e.stroke(0,0,100*(1-night),1);let n=.5*dc*.5/2/tan(ang);e.strokeWeight(Lx*min(max(.2*dc,scx*n),.6*dc)),e.beginShape();let l,o,r,s,i=[],c=1;for(let n=0;n<a[t].x.length;n++)i=[a[t].x[n],a[t].y[n]],l=ox+scx*i[0],o=oy+scy*i[1],r=10*floor(l)+floor(o),n>0&&r!=s&&(e.endShape(),e.beginShape(),c=0),s=r,c&&l<2&&l>-2&&o<2&&o>-2&&e.curveVertex(Lx*l,Ly*o);e.endShape()}e.blendMode(BLEND)}let e=0;for(;tik<NA-es&&e<step;)drawk(tik),tik++,e++;if(buf){let e=tik/step0*TWO_PI;fill(360*e/TWO_PI,90,100),circle(Lx/2+60*dx*cos(e),Ly/2+60*dx*sin(e),3*dx)}if(buf&&tik>=step0&&(image(ob,0,0,Lx,Ly,Lx*xb/3,Ly*xb/3,Lx,Ly),t0=millis(),step=1,buf=0),tik>=NA-es&&(1==kand||emboss)){image(ob,0,0,Lx,Ly,Lx*xb/3,Ly*xb/3,Lx,Ly);let e=JN;JN>2&&(e+=6*kand);let t=tphase+(millis()-t0)/3e5*PI;if(kand)for(let n=1;n<e;n++)blend(pc,blsh*Lx*xb/3*n/e*cos(t),blsh*Ly*xb/3*n/e*sin(t),width*pd,height*pd,0,0,width*pd,height*pd,MULTIPLY);else for(let n=1;n<e;n++)blend(pc,blsh*Lx*xb/3*n/e*cos(t),blsh*Ly*xb/3*n/e*sin(t),width*pd,height*pd,0,0,width*pd,height*pd,SCREEN);if(vred||(fill(hx,bsat,255,.1),rect(0,0,Lx,Ly)),!kand&&contr){loadPixels();let e=4*(width*pd)*(height*pd);for(let t=0;t<e;t+=4){let e=[pixels[t],pixels[t+1],pixels[t+2]],n=color(e[0],e[1],e[2]),l=brightness(n)/100,o=1.2*(.4+.6*fblend(l*l));contr_x>0&&(o*=1.4*o);let r=1+vred*(l-1);pixels[t+0]=r*(o*(e[0]-128)+v0),pixels[t+1]=r*(o*(e[1]-128)+v0),pixels[t+2]=r*(o*(e[2]-128)+v0)}updatePixels()}}tik>=NA-es&&(tik++,bor&&drawbord(),head&&noLoop())}function drawk(e){let t=max(.01,1-e/(.1+NA-atten*es)),n=dx/Lx,l=mod(hx+5*(e-NA)*coltik,360),o=(2-bsat/20)*t*.1*rndv[e%NRND]/2,r=buf?ob:this;if(e%20==0&&(r.blendMode(SCREEN),r.fill(l,bsat,100-3*(2*t-1)*1.5*(1+fade)*dlum,1*(1+fade)*max(0,o)),r.rect(0,0,Lxb,Lyb),r.blendMode(BLEND)),e<NA){let l=rlight.slice();l=rot3d(l,[0,0,1],t*PI);let o=[120,30,10];col=[];let s=0,i=1,c=pal[pal.length-1][0],x=0,d=0;for(let p=0;p<a[e].x.length;p++){let y=1,h=(dx,5*(2+fade)*min(.1,1.3*y)*pd/2/2*.1*lnwght);x=0,d=0,lo=1,lo*=lsw,h*=1+4*bw,lo?r.stroke(c,100,.2*lightness,h):r.noStroke();let b=1.3*max(.1,1.3*y)*2/pd*dx/14;r.strokeWeight(b);let f=[a[e].x[p],a[e].y[p],a[e].z[p]],u=.6*a[e].R,L=a[e].v[0];i*=y;let m,k,g,w,D,M,N,v=rr0;for(let c=0;c<Nrad0;c++){s++,i=min(.15*n,i),i=max(.7*n,i);let y=pinch*a[e].t1[p];hatch&&(y=floor(y*hatchn/TWO_PI)*TWO_PI/hatchn),y=phase,y+=flow*a[e].RR[p]/2;let b=rot3d([cos(y),sin(y),0],a[e].v[p],c/Nrad0*TWO_PI),P=sumArrays(vecscl(b,1-lam),vecscl(L,lam));L=P,k=clarity+(1-clarity)*(.2+.8*rndv[mod(s,NRND)]),g=k;let R=mod(237*k,1),S=mod(191*k,1),z=mod(257*k,1);fac=.01*brr*Math.exp(R)*Math.exp(a[e].RR[p]);let I=sumArrays(f,vecscl(b,i*n*fac*k*u));xxx=f[0],yyy=f[1],xxx=ox+scx*f[0],yyy=oy+scy*f[1];let _=scx*a[e].R*2*(2-clarity)*v*k,B=4*aa0/Nrad0/(1+2*lgfac*(.05+S)*_);if(_>5&&(B=min(B,.1)),M=_,N=B,wild){let e=2.5*mod(57*g,1);_*=.5*Math.exp(e),B*=2*Math.exp(-1.5*e)}w=sumArrays(l,[xe,ye,ze],neg(I)),D=.39+dot(P,w)/norm3(w)/norm3(P)-.03+.03*Math.exp(2*z),focus&&(D+=phase+atan2(a[e].x[p]-.4-.2*rndv[0],a[e].y[p]-.4-.2*rndv[1])),D-=rbow*a[e].RR[p],D+=300*A[e].cf,D=sin(D*PI),D!=D&&(D=0);let J=abs(D);J=clamp(J,.001,.999);let E=pallerp(J);o=[0,0,100],E&&(o=E.slice()),D<0&&(o[0]=(o[0]-120*mono+180-50+100*g)%360,o[1]*=.4+S,o[2]*=.9+.2*z,B*=.5),B*=1+min(3,(1/_)**2),x>Nrad0/4*min(1,_)&&lo&&(lo=0,d=0),d>8*(1+echo)*lfac&&!lo&&(lo=1,x=0),x++,d++,dt=ang,_=min(_,1/n/7),m=4*o[2],vred&&(m*=m/100),lo&&(m*=1.1,B*=.6),m=min(100,m),lightness=m/2;let W=0;W=y+dt,y-=dt,rain&&D>0&&(_*=Math.exp(z));let q=clamp(1-10*a[e].z[p],-3,3);_*=Math.exp(2*clamp(a[e].z[p],-2,2)),q=0;let T=(1-buf)*Lx/2,O=(1-buf)*Ly/2;T=0,O=0,!clean&&t>.6&&1==a[e].open&&p==a[e].x.length-1&&(_=1*Lx/dx,R<pblk?(B=1,m=0):(B=.8,o[1]=0,m=100*(1-night)),r.noStroke()),xxx=str(floor(1e3*xxx)/1e3),yyy=str(floor(1e3*yyy)/1e3),r.fill(o[0],min(100,.95*(1-bw)*o[1]),bfac*m,2*min(1,B));let C=T/Lx+xxx,H=O/Ly+yyy;r.noStroke();let j=max(.8,dx*_);ccircle(Lx*C,Ly*H,j,y,W,q,r),r.stroke(mod(180+o[0],360),2*o[1],.5*o[2],1.4*1.4*h),j*=1.4,r.line(Lx*C,Ly*H,Lx*C+j*cos(y),Ly*H+j*sin(y)),r.line(Lx*C,Ly*H,Lx*C+j*cos(W),Ly*H+j*sin(W))}}}}function str(e){return(1+2*xb)*e}function inscr(e,t){return e>-0&&e<1&&t>-0&&t<1}function inbdy(e,t){return e>-.1&&e<.2||e>.8&&e<1.1||t>-.1&&t<.2||t<1.1&&t>.8}function clamp(e,t,n){return Math.max(t,Math.min(n,e))}let SQ3=Math.sqrt(3);function ccircle(e,t,n,l,o,r,s){let a=1.4*n;s.triangle(e,t,e+a*Math.cos(l),t+a*Math.sin(l),e+a*Math.cos(o),t+a*Math.sin(o))}function proj(e){let t=e[0],n=e[1],l=e[2];return[(t-xe+c1*l)*ze/(ze+l),(n-ye+s1*l)*ze/(ze+l)]}function norm3(e){return Math.sqrt(e[0]*e[0]+e[1]*e[1]+e[2]*e[2])}function vecscl(e,t){let n=[];for(let l=0;l<e.length;l++)n[l]=e[l]*t;return n}function neg(e){return vecscl(e,-1)}function cross(e,t){let n=[];return n[0]=e[1]*t[2]-t[1]*e[2],n[1]=e[2]*t[0]-t[2]*e[0],n[2]=e[0]*t[1]-t[0]*e[1],n}function dot(e,t){return e[0]*t[0]+e[1]*t[1]+e[2]*t[2]}function rot3d(e,t,n){return sumArrays(vecscl(e,Math.cos(n)),vecscl(cross(t,e),sin(n)),vecscl(t,dot(t,e)*(1-Math.cos(n))))}function sumArrays(...e){const t=e.reduce(((e,t)=>Math.max(e,t.length)),0);return Array.from({length:t}).map(((t,n)=>e.map((e=>e[n]||0)).reduce(((e,t)=>e+t),0)))}function mod(e,t){return(e%t+t)%t}function rnd(){return R.random_dec()}function pallerp(e){let t=floor(e*JJ),n=e*JJ-t;return sincol&&(n=fblend(n)),sumArrays(vecscl(pal[t],n),vecscl(pal[mod(t+1,JJ)],1-n))}function unit(e){return vecscl(e,1/norm3(e))}function hlp(e){let t=sqrt(e[0]*e[0]+e[1]*e[1]),n=atan2(e[1],e[0]),l=[ac[0][0]*t,ac[0][1]*t];for(let e=1;e<na;e++)l[0]+=pow(t,e)*(ac[e][0]*cos(e*n)-ac[e][1]*sin(e*n)),l[1]+=pow(t,e)*(ac[e][0]*sin(e*n)+ac[e][1]*cos(e*n));let o=[bc[0][0]*t,bc[0][1]*t];for(let e=1;e<nb;e++)o[0]+=pow(t,e)*(bc[e][0]*cos(e*n)-bc[e][1]*sin(e*n)),o[1]+=pow(t,e)*(bc[e][0]*sin(e*n)+bc[e][1]*cos(e*n));return[t,n,l,o]}function imzeta(e){let t,n,l,o;[t,n,l,o]=hlp(e);let r=o[0]*o[0]+o[1]*o[1];return atan2((l[1]*o[0]-l[0]*o[1])/r,(l[0]*o[0]+l[1]*o[1])/r)}function rezeta(e){let t,n,l,o;[t,n,l,o]=hlp(e);o[0],o[0],o[1],o[1];return.5*log((l[0]*l[0]+l[1]*l[1])/(o[0]*o[0]+o[1]*o[1]))}function gradimzeta(e){let t,n,l,o;[t,n,l,o]=hlp(e);let r=[0,0];for(let e=1;e<na;e++)r[0]+=e*pow(t,e-1)*(ac[e][0]*cos(e*n-n)-ac[e][1]*sin(e*n-n)),r[1]+=e*pow(t,e-1)*(ac[e][0]*sin(e*n-n)+ac[e][1]*cos(e*n-n));let s=[0,0];for(let e=1;e<nb;e++)s[0]+=e*pow(t,e-1)*(bc[e][0]*cos(e*n-n)-bc[e][1]*sin(e*n-n)),s[1]+=e*pow(t,e-1)*(bc[e][0]*sin(e*n-n)+bc[e][1]*cos(e*n-n));let a=o[0]*o[0]+o[1]*o[1],i=l[0]*l[0]+l[1]*l[1];return 0==i&&(i=.001),0==a&&(a=.001),[(r[1]*l[0]-r[0]*l[1])/i-(s[1]*o[0]-s[0]*o[1])/a,(r[0]*l[0]+r[1]*l[1])/i-(s[0]*o[0]+s[1]*o[1])/a]}function windowResized(){resizing=1,rsz_time=millis(),!head&&loop(),0!=dpx&&(pixelDensity(max(1,pd+dpx)),ob.pixelDensity(max(1,pd+dpx)),pc.pixelDensity(max(1,pd+dpx))),dpx=0,!head&&init()}function bg(){(lamr=1-0.2*kand*(hex==0)),colorMode(HSB),angleMode(RADIANS),noStroke(),ob.colorMode(HSB),ob.angleMode(RADIANS),ob.noStroke(),begin(hx,bsat),tik=0,loop(),buf=1}function PD(e){pixelDensity(e),ob.pixelDensity(e),pc.pixelDensity(e),bg()}function drawbord(){let e=min(Lx,Ly)/40;noStroke(),fill(0,0,100*(1-kand),.85);let t=-Lx/2,n=-Ly/2;t=0,n=0,rect(0,0,e,Ly),rect(0+Lx-e,0,e,Ly),rect(0+e,0,Lx-2*e,e),rect(0+e,0+Ly-e,Lx-2*e,e),fill(0,0,100*(1-kand),1),e/=4,rect(0,0,e,Ly),rect(0+Lx-e,0,e,Ly),rect(0+e,0,Lx-2*e,e),rect(0+e,0+Ly-e,Lx-2*e,e),blendMode(BLEND)}let lsw=1,bor=1;function keyPressed(){"1"==key&&PD(1),"2"==key&&PD(2),"3"==key&&PD(3),"4"==key&&PD(4),"5"==key&&PD(5),"6"==key&&PD(6),"7"==key&&PD(7),"8"==key&&PD(8),"9"==key&&PD(9),"+"==key&&PD(pd+1),"-"==key&&PD(max(1,pd-1)),"f"==key&&(sq=!sq,sq&&(aspect=aspect0),windowResized()),"b"==key&&(bor=!bor,image(ob,0,0,Lx,Ly,Lx*xb/3,Ly*xb/3,Lx,Ly),bor&&drawbord()),"s"==key&&saveCanvas("Glass_"+tokenData.hash+".png"),"n"==key&&(kand=1-kand,kblk=1-kand,bor=0,bg()),"o"==key&&(outline=1-outline,bg()),32==keyCode&&(keyst=!keyst,keyst?noLoop():loop()),0==tik&&bg()}class Random{constructor(){this.useA=!1;let e=function(e){let t=parseInt(e.substr(0,8),16),n=parseInt(e.substr(8,8),16),l=parseInt(e.substr(16,8),16),o=parseInt(e.substr(24,8),16);return function(){t|=0,n|=0,l|=0,o|=0;let e=(t+n|0)+o|0;return o=o+1|0,t=n^n>>>9,n=l+(l<<3)|0,l=l<<21|l>>>11,l=l+e|0,(e>>>0)/4294967296}};this.prngA=new e(tokenData.hash.substr(2,32)),this.prngB=new e(tokenData.hash.substr(34,32));for(let e=0;e<1e6;e+=2)this.prngA(),this.prngB()}random_dec(){return this.useA=!this.useA,this.useA?this.prngA():this.prngB()}}
let loading=1,sq=1;p5.disableFriendlyErrors=!0;const head=/\bHeadlessChrome/.test(navigator.userAgent);let pd,Lx,Ly,Lxb,Lyb,dx,Lyp,CCC,T,rndv;const NRND=200;var resizing=0,rsz_time=0,rsz_delay=500;let R,t0,MM,ox,oy,col,dox,doy,c1,s1,c2,s2,xe,ye,ze,pc,ob,buf,e,f,b,pj,pal,JJ,tt0,ll,rndi1,rndi2,rndph,rndi3,dgrid,PLx,PLy,mm,nn,ri,zh,zh2,zh3,zr,a,ct,dc,night,rlight,rain,st0,scx,scy,infrac,Pcir,lgfac,hx,lo,rr0,Nrad0,nt,inv,dt,phase,clarity,gfac,kgx,kgy,melt,wild,eye,sphsh,a1,a2,xe0,ye0,ze0,kz,kx,az,ax,ay,ky,om,nbr,tik,dlum,drfa,rad,coltik,rcfac,lnwght,ang,circo,bsat,invscl,sincol,ealph,ne,echo,mono,brr,lam,lightness,miny,maxy,minx,maxx,focus,outline,bw,out,clean,pblk,rndp,fade,step,step0,NA,aa0,flow,ds,es,rbow,pinch,atten,cerp,hatchn,lfac,lamr,hex,contr_x,v0,vred,zigzag,tphase,JN,emboss_amp,distx,dist,kblk,kand,blsh,emboss,x00,y00,Ni,Nj,N,Nrad,A,kspr,invgamma,R00,Rmax,layer1,ac,bc,na,nb,contr,fh,aspect0=.8,aspect=aspect0,keyst=0,dpx=0,xb=.2,pals=[];function setup(){document.body.style.backgroundColor="#2D3033",console.log("Glass by EDG"),console.log("https://twitter.com/eeedg__"),dox=0,doy=0,doz=0,init()}function init(){R=new Random,Lx=window.innerWidth,Ly=window.innerHeight,pd=pixelDensity(),sq&&(Lx=min(Lx,Ly*aspect),Ly=Lx/aspect),aspect=Lx/Ly,Lxb=Lx*(1+4*xb),Lyb=Ly*(1+4*xb),CCC=createCanvas(Lx,Ly),ob=createGraphics(Lxb,Lyb),pc=createGraphics(Lxb,Lyb),CCC.id("canv"),frameRate(60),Lyp=Ly/Lx,dx=min(Lx,Ly)/200;let n=[14,15,0,22,4,24,10,14,0,10,0,20];n=vecscl(n,1/133);let e=[];e[0]=0;for(let a=1;a<n.length;a++)e[a]=e[a-1]+n[a-1];pj=1;let t=rnd();for(;pj<n.length&&e[pj]<t;)pj++;pj--;inv=0,rnd()<[0,.2,0,0,0,0,0,.3,0,.3,0,0][pj]&&(inv=1),pal=[],JJ=pals[pj].length;for(let n=0;n<JJ;n++)pal[n]=pals[pj][n].slice(),inv&&(pal[n][0]=(pal[n][0]+180)%360);rndv=[];for(let n=0;n<200;n++)rndv[n]=rnd();let r=-PI/4+PI/2*rnd();c1=Math.cos(r),s1=Math.sin(r),c2=-.7,s2=.7,ze0=-2,xe0=0,ye0=-1/3,rnd()<.2&&(ze0=rnd()<.4?.3:.9),lo=1,rr0=1,Nrad0=7,phase=PI/2,rnd()<.3&&(phase-=PI),rnd()<.3&&(phase-=PI/2,rnd()<.5&&(phase+=PI)),rnd()<.3&&(phase+=-PI/12+PI/6*rnd()),dt=.1+1.2*rnd(),clarity=0,wild=1,a1=rnd(),a2=rnd(),miny=1,maxy=-1;sphsh=.5*(1-rnd()*rnd()),rain=0,rnd()<.2&&(rain=1);let s=1;rnd()<.3&&(s=rnd()),dc=.75*dx/Lx;let d=.5*(.1+.2*rnd());ds=4*Math.exp(rnd())*dc;ds*=2;let l=.5*(1+rnd());rnd();rlight=[4*rnd()-2,4*rnd()-2,4*rnd()-2],ze=ze0-1,xe=0,ye=0,Pcir=0;let o=[0,200,240,140,0,200,65,190,200,0,100,180,200,0,200,240,0,50,75,120,0,260,50,138],i=pj+inv*pals.length;hx=o[i]+([360,290,350,320,360,360,105,360,270,60,140,280,360,360,320,400,80,275,200,180,360,580,190,478][i]-o[i])*rnd(),hx=mod(hx,360),dlum=.2*.1*rnd(),drfa=3*rnd(),ne=floor(Math.exp(1.3*rnd())),coltik=.2*(1+.5*rnd()),lgfac=1,lnwght=.7,ang=.26*Math.exp(.3*rnd()),drfa<1&&(ang=PI/4),circo=.9*Math.exp(.5*rnd()),invscl=.9*Math.exp(.5*rnd());let p=2;mono=0,11==pj&&rnd()<.2&&(mono=3/2),echo=1,rnd()<.04&&(echo=0);let c=rnd();echo||(c*=.5);rnd();lam=.6+.4*rnd(),sincol=1,ealph=.3+.3*rnd(),cerp=0,brr=3;let h=Math.exp(2*rnd())+20;h=20;let x=3*floor(80+100*rnd()),b=4*(12+5*rnd());ct=1.5*dc;rnd()<.3||rnd();b*=1.3*Math.exp(-1.3*rnd()),popen=rnd();rnd();let m=.8+.2*rnd(),f=1;f=1-.02*rnd(),loopang=PI/2*rnd(),circ=1,rnd()<.2&&(circ=0,m/=3),flow=0,rnd()<.7&&(flow=1,rnd()<.3&&(flow=2)),flow*=3,es=0,rnd()<.3&&(es=rnd()<.8?.4*(20+x):floor(.1*(x+20)*rnd())),atten=rnd()<.3?1:round(10*rnd())/10,na=2+ceil(5*rnd()),nb=2+ceil(5*rnd()),ac=[],bc=[];for(let n=0;n<na;n++)ac[n]=[],ac[n][0]=rnd(),ac[n][1]=rnd();for(let n=0;n<nb;n++)bc[n]=[],bc[n][0]=rnd(),bc[n][1]=rnd();vecscl([-.5+rnd(),-.5+rnd(),-.5+rnd()],.03);let y=1-.3*rnd(),g=(rnd(),rnd()<.8?0:.8);aa0=3.2,hatch=0,rnd()<.07&&(hatch=1),pinch=0,rnd()<.4&&(pinch=.1,rnd()<.2&&(pinch=1)),hatch*=pinch,hatch=1,hatchn=2,hatchn=6,clean=0,rnd()<.2&&(clean=1),emboss=0,(rnd()<.5||flow>0)&&(emboss=1),emboss_amp=1,blsh=1,rnd()<.7&&(blsh=.2,rnd()<.6&&(blsh=.6));hex=rnd()<.25?1:0;kand=0;let u="None";dist=rnd()<.35?1:0,dist&rnd()<.5&&(blsh=.4),distx=1,abs(mod(phase,PI)-PI/2)<PI/4&&(distx=0),dist&&(u="Pressure");let j=.5;dist&&rnd()<.6&&(distx=1-distx,j/=2,u="Shear");let L=0;dist&&g>0&&(L=1,u="Superposition");let k=TWO_PI*rnd(),z=3+4*rnd();dist>0&&(emboss=1,flow/=3),focus=0,0==dist&&rnd()<.15&&(focus=1);pblk=0,y=0,rbow=1-Math.exp(.2*rnd());bw=0,aa0*=1+bw,outline=rnd()<.06?1:0,night=0,fade=1,lightness=10,contr=1,vred=1,contr_x=0,v0=102,bsat=20;let w=rnd();10!=pj&&w<.15&&(bsat=4,lightness+=20,2==pj&&(bsat=20)),11==pj&&(contr_x=1,v0=10,kand=0,echo=0,bw=0,pblk=0,bsat=2,lightness+=20,es=0,fade=0),0!=pj||inv||(contr_x=1,v0=10,aa0*=1.6,bsat=4,lightness+=20,fade=.1),3==pj&&(contr_x=1,contr=0),3==pj&&inv&&(outline=1,mono=1,fade=.3),4!=pj||inv||(bsat=5,lightness+=10,es=0,night=.2,fade=0),4==pj&&inv&&(contr_x=1,v0=10,bsat=4,lightness=40,night=.2),9==pj&&(vred=0,mono=1,clean=1,fade=2,es=0,aa0*=1.6),inv||8!=pj||(outline=1,bsat=25,lightness=0),6!=pj||inv||(contr_x=1,v0=10,bsat=4,lightness=15,es=0,es=0,fade=2),6==pj&&inv&&(bsat=4,lightness=25,es=0),7!=pj||inv||(v0=120,vred=0,bsat=4,lightness=25,es=0,night=.2,fade=0),7==pj&&inv&&(clean=1,fade=.7),2!=pj||inv||(outline=1,mono=1,es=0,sincol=0,fade=.7),2==pj&&inv&&(mono=1,es=0),10==pj&&(mono=1,fade=2,lightness=2,night=.2,p=2),1==pj&&(v0=3,contr_x=1,fade=2,es=0),5==pj&&(vred=0,clean=1,bsat=20),0==es&&(atten=0); kblk=1-kand,outline=0,es=0,bsat=20,clean||(night=pblk,bsat*=0+.9*pblk),fade=0,bsat=2,lightness*=1-bw,bsat=8,11==pj&&(bsat=2); 6==pj&&(bsat=20,flow/=3,contr=1,emboss=0); 4==pj&&(mono=+3/2); 1==pj&&inv&&(bsat=20,emboss=0,contr=1); 4==pj&&inv&&(bsat=20),lfac=.8+.4*min(0,max(4,bsat)-20)/16,dlum*=-1,d=0,out=rnd()<.5?0:1,hoop=rnd()<.3?0:1,zigzag=0,hoop=0,dt=.1,A=[],JN=rnd()<.1?2:20,tphase=TWO_PI*rnd(),Nsph=20+floor(20*rnd()),Nsph<20&&(hex=0),Nsph*=max(1.25*aspect,.8/aspect),!emboss&&(Nsph+=10),0!=pj&&1!=pj&&6!=pj||(aa0*=1.6),11==pj&&(aa0*=1.3),R00=1/Nsph,Ni=1/R00/2,Nj=1/R00/2/aspect,Rmax=1.62*R00*1.2;let P=[],I=1;for(let n=0;n<Ni;n++){P[n]=[];for(let a=0;a<Nj;a++)if(P[n][a]=rnd()<1?I:0,P[n][a]){let e=[];I++,e.R=R00*(.9-.2*hex)*(.2+1.6*rnd()),e.F=[0,0],e.r=[],e.r[0]=n/Ni+a%2*R00*.87,e.r[1]=a/Nj,e.nb=[],e.lnk=[],A.push(e)}}let _=[-1,0,1,-1,0,1,2,-2,-1,1,2,-1,0,1,2,-1,0,1],M=[-1,0,1,-2,-1,0,1,-2,-1,1,2,-2,-1,0,1,-1,0,1],C=[2,2,2,1,1,1,1,0,0,0,0,-1,-1,-1,-1,-2,-2,-2];N=A.length;for(let n=0;n<Ni;n++)for(let a=0;a<Nj;a++){let e=round(-1+P[n][a]);if(e>-1){let t=0;for(let r=0;r<C.length;r++){let s=C[r],d=round(mod(n+(a%2>0?_[r]:M[r]),Ni)),l=round(mod(a+s,Nj)),o=-1+P[d][l];o>-1&&(A[e].nb.push(o),t++)}A[e].z=t}}kspr=1,invgamma=1;for(let n=0;n<1e3;n++){for(let n=0;n<N;n++){let a=[0,0],e=0;for(let t=0;t<A[n].z;t++){let r=A[n].nb[t],s=[A[r].r[0]-A[n].r[0],1/aspect*(A[r].r[1]-A[n].r[1])];for(let n=0;n<3;n++)s[0]>.8&&(s[0]-=1),s[0]<-.8&&(s[0]+=1),s[1]>.8&&(s[1]-=1),s[1]<-.8&&(s[1]+=1);let d=Math.sqrt(s[0]**2+s[1]**2),l=-d+A[n].R+A[r].R;d>0&&l>0&&(e+=l,a[0]+=-kspr*l*s[0]/d,a[1]+=-kspr*l*s[1]/d)}A[n].F=[a[0],a[1]],A[n].cf=e}for(let n=0;n<N;n++)A[n].r[0]+=dt*invgamma*A[n].F[0],A[n].r[1]+=dt*invgamma*A[n].F[1],A[n].r[0]=mod(A[n].r[0],1),A[n].r[1]=mod(A[n].r[1],1)}a=[];let J=phase+PI/2-ang;for(let n=0;n<N;n++){let e=[];e.x=[],e.y=[],e.z=[],e.v=[],e.RR=[],e.s=0;let t=.3*rnd(),r=unit([0,1,0]),s=2*b*20/Nsph*A[n].R/R00+1;for(let a=0;a<s;a++)e.x[a]=A[n].r[0]+cos(J+TWO_PI/s*a)*A[n].R,e.y[a]=A[n].r[1]+sin(J+TWO_PI/s*a)*Lx/Ly*A[n].R,e.z[a]=t,e.v[a]=r,e.RR[a]=rezeta([e.x[a],e.y[a]]);e.xav=A[n].r[0],e.yav=A[n].r[1],e.zav=e.z[floor(s/2)],e.id=n,e.open=0,e.R=l*(1+rnd());let d=phase,o=str(e.xav),i=str(e.yav);e.s=-sin(d)*i-cos(d)*o,A[n].s=e.s,a.push(e)}NA=a.length,echo=0,maxy=-1,miny=1,maxx=-1,minx=1,xav=0;let D=[],F=[];for(let n=0;n<NA;n++)xav+=a[n].xav,a[n].yav&&(p1=[a[n].xav,a[n].yav],D.push(p1[0]),F.push(p1[1]),maxy=max(maxy,p1[1]),miny=min(miny,p1[1]),maxx=max(maxx,p1[0]),minx=min(minx,p1[0]));xav/=a.length,D.sort((function(n,a){return n-a})),F.sort((function(n,a){return n-a})),minx=D[floor(NA/7)],maxx=D[floor(6*NA/7)],miny=F[floor(NA/7)],maxy=F[floor(6*NA/7)],x00=.3,y00=.3;for(let n=0;n<NA;n++){a[n].gp=[];for(let e=0;e<a[n].x.length;e++)a[n].z[e]+=imzeta([a[n].x[e],a[n].y[e]])/10,a[n].gp[e]=gradimzeta([a[n].x[e]-x00,a[n].y[e]-y00])}if(dist){let n=3;for(let e=0;e<a.length;e++){let t=distx?A[e].r[0]:A[e].r[1];L&&(t=A[e].r[0]*A[e].r[1]);let r=j*sin(cos(z*sin(t)+k)*n);A[e].r[0]+=-.2*r*cos(phase),A[e].r[1]+=.2*r*sin(phase);for(let r=0;r<a[e].x.length;r++){t=distx?a[e].x[r]:a[e].y[r],L&&(t=a[e].x[r]*a[e].y[r]);let s=j*sin(cos(z*sin(t)+k)*n);a[e].x[r]+=-.2*s*cos(phase),a[e].y[r]+=.2*s*sin(phase)}}}let T=0;for(let n=0;n<a.length;n++){a[n].t1=[],a[n].t2=[],a[n].t1[0]=0;for(let e=1;e<a[n].x.length;e++)a[n].t1[e]=atan2(a[n].y[e]-a[n].y[e-1],a[n].x[e]-a[n].x[e-1])-PI/2,a[n].t2[e-1]=a[n].t1[e];T+=a[n].x.length}A.sort(((n,a)=>a.s-n.s)),a.sort(((n,a)=>a.s-n.s)),fac=1.8/(maxy-miny),scx=.5;let W=cos((1-pinch)*phase),E=sin((1-pinch)*phase);W=0,E=0,scx=1/(maxx-minx),scy=1/(maxy-miny),scx=max(scx,scy),scy=scx,ox=1-scx*maxx,oy=1-scy*maxy;for(let n=0;n<NA;n++)a[n].bdy=inbdy(mod(a[n].xav,1),mod(a[n].yav,1));doz=0,blendMode(BLEND),ob.blendMode(BLEND),bg(),step0=floor(.8*max(30,NA-es)),step=1,step0=NA-es,loading||(step0=1)}function begin(n,a){background(0,0,0,1),fill(n,a,bfac*(1-kand)*100),rect(0,0,Lx,Ly),ob.background(0,0,0,1),ob.fill(n,a,bfac*(1-night)*100),ob.rect(0,0,Lxb,Lyb),fill((180+n)%360,3*a,50),pc.fill(200/JN*(1-kand)+255*kand),pc.rect(0,0,Lxb,Lyb)}function fblend(n){return n*n*(3-2*n)}pals.push([[359,31,56],[353,19,97],[6,20,96],[22,21,92],[20,16,98],[28,21,99],[6,20,96],[347,13,96]]),pals.push([[208,49,38],[205,41,59],[192,29,45],[190,14,64],[220,9,78],[12,4,45],[167,16,81],[180,7,100]]),pals.push([[222,86,22],[208,88,29],[203,61,57],[215,49,74],[211,68,93],[236,100,24],[195,85,45]]),pals.push([[4,100,34],[1,96,84],[26,92,94],[34,58,89],[48,100,99],[21,100,84],[8,100,17]]),pals.push([[43,35,28],[46,39,42],[41,27,90],[39,46,49],[39,83,90],[46,6,96],[46,15,97]]),pals.push([[209,92,15],[197,98,24],[195,79,37],[190,42,64],[189,62,90]]),pals.push([[331,21,31],[265,23,40],[335,26,76],[163,32,22],[210,24,29],[180,31,97],[49,30,63],[180,23,90],[170,13,48]]),pals.push([[26,71,17],[26,78,23],[42,68,60],[40,46,60],[42,76,74],[37,62,74]]),pals.push([[102,41,55],[123,37,63],[94,27,65],[121,30,69],[91,26,67],[125,37,63]]),pals.push([[115,52,17],[98,51,40],[78,58,54],[91,67,84],[6,54,38]]),pals.push([[349,83,69],[250,44,66],[191,44,66],[27,82,72],[45,85,70],[0,100,79]]),pals.push([[221,20,21],[199,26,38],[190,10,81],[220,0,100],[190,0,100],[205,30,43],[183,20,100],[215,43,36],[185,0,100],[200,0,100]]);let bfac=1;
1-50 of 68