Kim Asendorf &
Leander
Herzog
CHROME ,
collection of
128 channels,
2023
On-Chain
multi-channel
real-time
animation
JavaScript,
GLSL, variable
dimensions
Ethereum smart
contract
View
the
collection
on
OpenSea .
Click for
fullscreen
PRE-SALE 28 Feb, 6 PM CET:
Ξ0.5
PUBLIC MINT 1 March, 6 PM CET:
Ξ0.5
Mint Single
Mint Pair
Mint Set
Chrome plays with the potential of contemporary
software and hardware, from generative realtime
graphics and custom smart contracts, to displays
with ever increasing resolution and quality. The
onchain software work responds to screen size
and builds directly on the pixels of the
specific display it runs on.
Chrome is a 128 channel realtime animation,
coordinated by universal time (UTC ). It emerges from a continuous linear motion,
interrupted by a choreography between rhythm and
random. Every channel is offset one additional
second into the future, based on the token id
assigned by the custom smart contract. This
relation becomes visible when multiple channels
are running in a shared space. Compositions
emerge and evolve at various regular intervals,
without ever repeating.
Once per hour the synchronization stops
and all channels act individually,
before they transition back to coordination.
On March 1, 6PM CET , the 128
channels of Chrome can be minted,
in sets of 8 channels (consecutive
token ids), in pairs of 2, or as single
channel .
A 24h pre-sale starts 28 Feb 6PM CET,
for collectors on the allowlist.
A "set" is 8 tokens with consecutive ids and
time offsets. A pair is 2 tokens with
consecutive ids and time offsets. Collectors of
multiple channels can display them together and
see the time difference, the synchronization and
the choreography that emerges between them.
The custom
smart contract
stores the 15kb code of the work on the ethereum
blockchain. It also enables minting sets with
consecutive token ids in a single transaction.
Check out the collection
on OpenSea .
<!DOCTYPE HTML><html><head><meta name='viewport' content='width=device-width,user-scalable=no,minimum-scale=1.0,maximum-scale=2.0'></head><body><script>let tId=1;let GL=()=>{let cv,gl,vSh,fSh,gSh,mSh,vBf,fPr,gPr,mPr,gFbo,fFbos,fFboId=0,fX,fY,fW,fH,bAr,bxs,imgTx,imgFrmL=0,imgFrmC=0,cBx,bCl,tOf,gri=16,gPx=0,gCl=[255,255,255],gVs=true,eAr=[],eL=[1800,7200,300,3600,7200,14400],eId=-1,eT=-1;let dcd=decodeURIComponent;let{floor,max,pow,random}=Math;let shAr=a=>{a.sort(()=>random()-.5)};let swIt=a=>{let i1=floor(random()*a.length);let i2=floor(random()*a.length);let i=a[i1];a[i1]=a[i2];a[i2]=i};let getTOf=()=>{let d=new Date;let da=d.getDate();let m=d.getMonth();let y=d.getFullYear();let f=new Date(y,m,da,0,0,0,0);return d.getTime()-f.getTime()};let ini=async()=>{tOf=getTOf()-(tId-1)*1e3;vSh='in vec3 pos;out vec2 vUv;void main(){gl_Position=vec4(pos,1.);vUv=.5*(pos.xy+1.);}';fSh='uniform sampler2D bfr,img;uniform vec2 res;uniform float t;uniform vec4[8] bxs;in vec2 vUv;out vec4 frag;float ib(vec2 v,vec2 bl,vec2 tr){vec2 s=step(bl,v)-step(tr,v);return s.x*s.y;}float rand(vec2 co){return fract(sin(dot(co.xy,vec2(12.9898,78.233)))*43758.5453);}float oscSin(float x){return sin(x*.1)*.4;}float oscSqr(float x){return mod((x*.025),1.)<.5?-.5:.5;}float oscTri(float x){return abs(mod((x*.03),(.5*2.))-.5);}float hash(float n){return fract(sin(n)*1e4);}float noise(vec3 x){const vec3 step=vec3(110,241,171);vec3 i=floor(x);vec3 f=fract(x);float n=dot(i,step);vec3 u=f*f*(3.-2.*f);return mix(mix(mix(hash(n+dot(step,vec3(0,0,0))),hash(n+dot(step,vec3(1,0,0))),u.x),mix(hash(n+dot(step,vec3(0,1,0))),hash(n+dot(step,vec3(1,1,0))),u.x),u.y),mix(mix(hash(n+dot(step,vec3(0,0,1))),hash(n+dot(step,vec3(1,0,1))),u.x),mix(hash(n+dot(step,vec3(0,1,1))),hash(n+dot(step,vec3(1,1,1))),u.x),u.y),u.z);}void main(){vec3 col=texture(bfr,vUv).rgb;vec2 pos=floor(vUv*res);if(pos.x==0.){col=texture(img,vUv).rgb;}if(ib(pos,vec2(bxs[0].x,bxs[0].y),vec2(bxs[0].x+bxs[0].z,bxs[0].y+bxs[0].w))>=1.){float y=(noise(vec3(vUv.x*.048,vUv.y*64.,t*1.6))-.5)*2.;vec2 of=vec2(1./res.x,1./res.y*y);col=texture(bfr,vUv-of).rgb;}if(ib(pos,vec2(bxs[1].x,bxs[1].y),vec2(bxs[1].x+bxs[1].z,bxs[1].y+bxs[1].w))>=1.){float x=oscSqr(pos.y)*2.;float y=mod(oscSin(t*2.4+pos.y*2.)*1.,2.)-1.;vec2 of=vec2(1./res.x*x,1./res.y*y);col=texture(bfr,vUv-of).rgb;}if(ib(pos,vec2(bxs[2].x,bxs[2].y),vec2(bxs[2].x+bxs[2].z,bxs[2].y+bxs[2].w))>=1.){float y=0.;if(mod(pos.x,floor(t))<=4.){y+=1.;}if(mod(pos.y*10.,floor(t))<=4.){y-=1.;}vec2 of=vec2(1./res.x,1./res.y*y);col=texture(bfr,vUv-of).rgb;}if(ib(pos,vec2(bxs[3].x,bxs[3].y),vec2(bxs[3].x+bxs[3].z,bxs[3].y+bxs[3].w))>=1.){vec2 of=vec2(1./res.x,0.);col=vec3(1.,1.,1.)-texture(bfr,vUv-of).rgb;}if(ib(pos,vec2(bxs[4].x,bxs[4].y),vec2(bxs[4].x+bxs[4].z,bxs[4].y+bxs[4].w))>=1.){vec2 of=vec2(1./res.x,(noise(vec3(vUv.xx,t*10.))-.5)*2./res.y);col=texture(bfr,vUv-of).rgb;}if(ib(pos,vec2(bxs[5].x,bxs[5].y),vec2(bxs[5].x+bxs[5].z,bxs[5].y+bxs[5].w))>=1.){vec2 of=vec2(1./res.x,0.);col=texture(bfr,vUv-of).rgb;if(rand(pos+t)<.004){col+=vec3(1.,1.,1.);}else{col=vec3(1.,1.,1.)-col;}}if(ib(pos,vec2(bxs[6].x,bxs[6].y),vec2(bxs[6].x+bxs[6].z,bxs[6].y+bxs[6].w))>=1.){vec2 of=vec2(1./res.x,1./res.y*(oscTri(t*8.)-.25)*3.);col=texture(bfr,vUv-of).rgb;}if(ib(pos,vec2(bxs[7].x,bxs[7].y),vec2(bxs[7].x+bxs[7].z,bxs[7].y+bxs[7].w))>=1.){float dy=mod(pos.y,32.)<16.?10.:-10.;vec2 of=vec2(1./res.x,1./res.y*dy);col=texture(bfr,vUv-of).rgb;}frag=vec4(col,1.);}';gSh='uniform vec2 res;uniform float t;in vec2 vUv;out vec4 frag;vec3 mod289(vec3 x){return x-floor(x*(1./289.))*289.;}vec4 mod289(vec4 x){return x-floor(x*(1./289.))*289.;}vec4 permute(vec4 x){return mod289(((x*34.)+1.)*x);}vec4 tInvSqrt(vec4 r){return 1.79284291400159-0.85373472095314*r;}vec3 fade(vec3 t){return t*t*t*(t*(t*6.-15.)+10.);}/*Classic Perlin noise,Copyright(c)2011 Stefan Gustavson.All rights reserved.https://github.com/ashima/webgl-noise*/float pnoise(vec3 P,vec3 rep){vec3 Pi0=mod(floor(P),rep);vec3 Pi1=mod(Pi0+vec3(1.),rep);Pi0=mod289(Pi0);Pi1=mod289(Pi1);vec3 Pf0=fract(P);vec3 Pf1=Pf0-vec3(1.);vec4 ix=vec4(Pi0.x,Pi1.x,Pi0.x,Pi1.x);vec4 iy=vec4(Pi0.yy,Pi1.yy);vec4 iz0=Pi0.zzzz;vec4 iz1=Pi1.zzzz;vec4 ixy=permute(permute(ix)+iy);vec4 ixy0=permute(ixy+iz0);vec4 ixy1=permute(ixy+iz1);vec4 gx0=ixy0*(1./7.);vec4 gy0=fract(floor(gx0)*(1./7.))-.5;gx0=fract(gx0);vec4 gz0=vec4(.5)-abs(gx0)-abs(gy0);vec4 sz0=step(gz0,vec4(0.));gx0-=sz0*(step(0.,gx0)-.5);gy0-=sz0*(step(0.,gy0)-.5);vec4 gx1=ixy1*(1./7.);vec4 gy1=fract(floor(gx1)*(1./7.))-.5;gx1=fract(gx1);vec4 gz1=vec4(.5)-abs(gx1)-abs(gy1);vec4 sz1=step(gz1,vec4(0.));gx1-=sz1*(step(0.,gx1)-.5);gy1-=sz1*(step(0.,gy1)-.5);vec3 g000=vec3(gx0.x,gy0.x,gz0.x);vec3 g100=vec3(gx0.y,gy0.y,gz0.y);vec3 g010=vec3(gx0.z,gy0.z,gz0.z);vec3 g110=vec3(gx0.w,gy0.w,gz0.w);vec3 g001=vec3(gx1.x,gy1.x,gz1.x);vec3 g101=vec3(gx1.y,gy1.y,gz1.y);vec3 g011=vec3(gx1.z,gy1.z,gz1.z);vec3 g111=vec3(gx1.w,gy1.w,gz1.w);vec4 norm0=tInvSqrt(vec4(dot(g000,g000),dot(g010,g010),dot(g100,g100),dot(g110,g110)));g000*=norm0.x;g010*=norm0.y;g100*=norm0.z;g110*=norm0.w;vec4 norm1=tInvSqrt(vec4(dot(g001,g001),dot(g011,g011),dot(g101,g101),dot(g111,g111)));g001*=norm1.x;g011*=norm1.y;g101*=norm1.z;g111*=norm1.w;float n000=dot(g000,Pf0);float n100=dot(g100,vec3(Pf1.x,Pf0.yz));float n010=dot(g010,vec3(Pf0.x,Pf1.y,Pf0.z));float n110=dot(g110,vec3(Pf1.xy,Pf0.z));float n001=dot(g001,vec3(Pf0.xy,Pf1.z));float n101=dot(g101,vec3(Pf1.x,Pf0.y,Pf1.z));float n011=dot(g011,vec3(Pf0.x,Pf1.yz));float n111=dot(g111,Pf1);vec3 fade_xyz=fade(Pf0);vec4 n_z=mix(vec4(n000,n100,n010,n110),vec4(n001,n101,n011,n111),fade_xyz.z);vec2 n_yz=mix(n_z.xy,n_z.zw,fade_xyz.y);float n_xyz=mix(n_yz.x,n_yz.y,fade_xyz.x);return 2.2*n_xyz;}void main(){vec2 rel=vec2(max(res.xy/res.yx,vec2(1.)));float r=pnoise(vec3(vUv*rel*1.7,t*.04),vec3(141.,50.2,455.3));float g=pnoise(vec3(vUv*rel*1.6,t*.041),vec3(25.,1.,333.3));float b=pnoise(vec3(vUv*rel*1.5,t*.042),vec3(100.1,644.,23.23));vec3 col=vec3(r,g,b)*2.;if(g>b){discard;}frag=vec4(col,1.);}';mSh='uniform float grid;uniform vec2 res;uniform sampler2D fb,gd;uniform vec4 fBox,cBx;uniform vec3 bCl,gCl;uniform bool gVs;in vec2 vUv;out vec4 frag;float ib(vec2 v,vec2 bl,vec2 tr){vec2 s=step(bl,v)-step(tr,v);return s.x*s.y;}void main(){vec4 col=texture(gd,vUv);vec2 pos=floor(vec2(vUv.x*res.x,(1.-vUv.y)*res.y));frag=texture(gd,vUv);if(ib(pos,vec2(cBx.x,cBx.y),vec2(cBx.x+cBx.z,cBx.y+cBx.w))>=1.){frag=vec4(bCl,1.);}if(gVs){if(mod(pos.x,grid)==0.&&mod(pos.y,grid)==0.){frag=vec4(gCl,1.);}}if(ib(pos,vec2(fBox.x,fBox.y),vec2(fBox.x+fBox.z,fBox.y+fBox.w))>=1.){vec2 fUv=(pos-fBox.xy)/(fBox.zw-vec2(1.,1.));frag=texture(fb,fUv);}}';cv=document.createElement('canvas');cv.style.width=cv.style.height='100%';cv.style.verticalAlign='bottom';document.body.append(cv);gl=cv.getContext('webgl2',{antialias:true,preserveDrawingBuffer:true,willReadFrequently:true});gl.blendFunc(gl.ONE,gl.ONE_MINUS_SRC_ALPHA);gl.disable(gl.BLEND);gl.disable(gl.DEPTH_TEST);gl.clearColor(0,0,0,1);vBf=crBf([-1,1,0,-1,-1,0,1,1,0,1,-1,0]);fPr=crPr(vSh,fSh);gPr=crPr(vSh,gSh);mPr=crPr(vSh,mSh);return gl};let seClFs=(w,h,c)=>{cBx=[0,0,w,h];bCl=c;gCl=[255-c[0],255-c[1],255-c[2]]};let rsClFs=()=>{cBx=[0,0,0,0];bCl=[0,0,0];gCl=[255,255,255]};let upClFs=()=>{if(eT%8==0){bCl=[255,0,0];gCl=[0,0,255]}else{bCl=[0,0,255];gCl=[255,0,0]}};let seFbLay=(w,h)=>{let gR=floor(h/gPx);fW=w;fX=0;let lm=(tId-1)%8;switch(lm){case 0:fH=gPx*1;fY=gPx*gR-fH;break;case 1:fH=gPx*2;fY=gPx*gR-fH;break;case 2:fH=gPx*3;fY=gPx*gR-fH;break;case 3:fH=gPx*1;fY=gPx*floor(gR/2);break;case 4:fH=gPx*2;fY=fY=gPx*floor(gR/2)-gPx;break;case 5:fH=gPx*3;fY=0;break;case 6:fH=gPx*2;fY=0;break;case 7:fH=gPx*1;fY=0;break;default:break}};let setFbFs=(w,h)=>{fX=fY=0;fW=w;fH=h};let seFbBxs=(w,h)=>{bAr=[];let v=Array.from({length:7},()=>floor(random()*w));v.sort((a,b)=>{return a-b});let x=1;for(let i=0;i<v.length;i++){bAr.push([x,0,v[i]-x,h]);x=v[i]}bAr.push([x,0,w-x,h]);shAr(bAr);bxs=bAr.flat()};let seFbBx=(w,h)=>{bAr=Array(8).fill([0,0,0,0]);bAr[floor(random()*8)]=[1,0,w,h];bxs=bAr.flat()};let seDbFbBx=(w,h)=>{let i=[...Array(8).keys()];shAr(i);let s=floor(random()*w);bAr=Array(8).fill([0,0,0,0]);bAr[i[0]]=[1,0,s,h];bAr[i[1]]=[s,0,w-s,h];bxs=bAr.flat()};let isCa=false;let caId=0;let caT=0;let setCa=()=>{caT=0;isCa=true};let upCa=(w,h)=>{if(caT<=0){eAr[caId].r(w,h);caId=floor(random()*5);eAr[caId].s(w,h);caT=60+floor(random()*240)}else{eAr[caId].u(w,h)}caT--};let rsCa=(w,h)=>{eAr[caId].r(w,h);isCa=false};let seFb=(w,h)=>{imgTx=crTx(1,h,crPx(1,h));for(let f in fFbos){gl.deleteFramebuffer(f.fbo);gl.deleteTexture(f.tx)}fFbos=[];fFbos.push(crFbo(w,h,null));fFbos.push(crFbo(w,h,null));fFboId=0};let se=(w,h,s)=>{if(max(w/h,1)==1){gPx=floor(w/gri)}else{gPx=floor(h/gri)}cBx=[0,0,0,0];bCl=[0,0,0];seFbLay(w,h);seFbBxs(fW,fH);seFb(fW,fH);if(gFbo){gl.deleteFramebuffer(gFbo.fbo);gl.deleteTexture(gFbo.tx)}gFbo=crFbo(w*s,h*s,null)};let rz=s=>{if(cv.width!=cv.clientWidth*s||cv.height!=cv.clientHeight*s){cv.width=cv.clientWidth*s;cv.height=cv.clientHeight*s;return[cv.width/s,cv.height/s]}return false};eAr[0]={s:(w,h)=>{seClFs(w,h,[0,0,0])},u:()=>{},r:rsClFs};eAr[1]={s:(w,h)=>{seClFs(w,h,[255,255,255])},u:()=>{},r:rsClFs};eAr[2]={s:(w,h)=>{seClFs(w,h,[0,0,255])},u:upClFs,r:rsClFs};eAr[3]={s:(w,h)=>{setFbFs(w,h);let id=floor(random()*3);switch(id){case 0:seFbBxs(fW,fH);break;case 1:seFbBx(fW,fH);break;case 2:seDbFbBx(fW,fH);break;default:break}seFb(fW,fH)},u:()=>{},r:(w,h)=>{seFbLay(w,h);seFbBxs(fW,fH);seFb(fW,fH)}};eAr[4]={s:()=>{setFbFs(0,0);gVs=false},u:()=>{},r:(w,h)=>{seFbLay(w,h);seFbBxs(fW,fH);seFb(fW,fH);gVs=true}};eAr[5]={s:setCa,u:upCa,r:rsCa};let upEv=(w,h)=>{let ms=getTOf()-(tId-1)*200;let s=floor(ms/1e3);let m=floor(s/60);if(!isCa&&m%60==0&&s%60==0){eId=5;eAr[eId].s(w,h);eT=eL[eId]}if(eT<=0){if(eT==0){eAr[eId].r(w,h);eId=-1}else{if(m%33==0&&s%60==0){eId=0}else if(m%33==16&&s%60==0){eId=1}else if(m%19==0&&s%60==0){eId=4}else if(m%5==0&&s%60==47){eId=3}else if(m%3==0&&s%60==23){eId=2}if(eId>=0){eAr[eId].s(w,h);eT=eL[eId]}}}else if(eT>0){eAr[eId].u(w,h)}eT--};let upImgTx=h=>{if(imgFrmL==imgFrmC){imgTx=crTx(1,h,crPx(1,h));imgFrmL=pow(2,4+floor(random()*4));imgFrmC=0}imgFrmC++};let rn=(w,h,s,t)=>{upEv(w,h);if(random()<.01){swIt(bAr);bxs=bAr.flat()}upImgTx(fH);rnF(fW,fH,t);rnG(w,h,s,t);rnM(w,h,s)};let sePr=p=>{gl.useProgram(p);p.vertexPosAttrib=gl.getAttribLocation(p,'pos');gl.enableVertexAttribArray(p.vertexPosAttrib);gl.bindBuffer(gl.ARRAY_BUFFER,vBf);gl.vertexAttribPointer(p.vertexPosAttrib,3,gl.FLOAT,false,0,0)};let rnF=(w,h,t)=>{let pId=fFboId;let cId=fFboId^=1;sePr(fPr);gl.bindFramebuffer(gl.FRAMEBUFFER,fFbos[cId].fbo);gl.viewport(0,0,w,h);gl.clear(gl.COLOR_BUFFER_BIT|gl.DEPTH_BUFFER_BIT);gl.activeTexture(gl.TEXTURE0+pId);gl.bindTexture(gl.TEXTURE_2D,fFbos[pId].tx);gl.activeTexture(gl.TEXTURE0+2);gl.bindTexture(gl.TEXTURE_2D,imgTx);gl.uniform1f(gl.getUniformLocation(fPr,'t'),t/1e3);gl.uniform4fv(gl.getUniformLocation(fPr,'bxs'),bxs);gl.uniform2f(gl.getUniformLocation(fPr,'res'),w,h);gl.uniform1i(gl.getUniformLocation(fPr,'bfr'),pId);gl.uniform1i(gl.getUniformLocation(fPr,'img'),2);gl.drawArrays(gl.TRIANGLE_STRIP,0,4)};let rnG=(w,h,s,t)=>{sePr(gPr);gl.bindFramebuffer(gl.FRAMEBUFFER,gFbo.fbo);gl.viewport(0,0,w*s,h*s);gl.uniform1f(gl.getUniformLocation(gPr,'t'),(t+tOf)/1e3);gl.uniform2f(gl.getUniformLocation(gPr,'res'),w,h);gl.drawArrays(gl.TRIANGLE_STRIP,0,4)};let rnM=(w,h,s)=>{sePr(mPr);gl.bindFramebuffer(gl.FRAMEBUFFER,null);gl.viewport(0,0,w*s,h*s);gl.clear(gl.COLOR_BUFFER_BIT|gl.DEPTH_BUFFER_BIT);gl.activeTexture(gl.TEXTURE0+fFboId);gl.bindTexture(gl.TEXTURE_2D,fFbos[fFboId].tx);gl.activeTexture(gl.TEXTURE0+2);gl.bindTexture(gl.TEXTURE_2D,gFbo.tx);gl.uniform2f(gl.getUniformLocation(mPr,'res'),w,h);gl.uniform1f(gl.getUniformLocation(mPr,'grid'),gPx);gl.uniform4fv(gl.getUniformLocation(mPr,'fBox'),[fX,fY,fW,fH]);gl.uniform4fv(gl.getUniformLocation(mPr,'cBx'),cBx);gl.uniform3fv(gl.getUniformLocation(mPr,'bCl'),bCl);gl.uniform3fv(gl.getUniformLocation(mPr,'gCl'),gCl);gl.uniform1i(gl.getUniformLocation(mPr,'gVs'),gVs);gl.uniform1i(gl.getUniformLocation(mPr,'fb'),fFboId);gl.uniform1i(gl.getUniformLocation(mPr,'gd'),2);gl.drawArrays(gl.TRIANGLE_STRIP,0,4)};let crPr=(v,f)=>{let p=gl.createProgram();let vs=crSh(dcd('%23version 300 es%0A')+v,gl.VERTEX_SHADER);let fs=crSh(dcd('%23version 300 es%0Aprecision highp float;')+f,gl.FRAGMENT_SHADER);gl.attachShader(p,vs);gl.attachShader(p,fs);gl.linkProgram(p);return p};let crSh=(sr,tp)=>{let s=gl.createShader(tp);gl.shaderSource(s,sr);gl.compileShader(s);return s};let crFbo=(w,h,p)=>{let f=gl.createFramebuffer();let t=crTx(w,h,p);gl.bindFramebuffer(gl.FRAMEBUFFER,f);gl.framebufferTexture2D(gl.FRAMEBUFFER,gl.COLOR_ATTACHMENT0,gl.TEXTURE_2D,t,0);return{fbo:f,tx:t}};let crTx=(w,h,p)=>{let t=gl.createTexture();gl.bindTexture(gl.TEXTURE_2D,t);gl.texParameteri(gl.TEXTURE_2D,gl.TEXTURE_MAG_FILTER,gl.NEAREST);gl.texParameteri(gl.TEXTURE_2D,gl.TEXTURE_MIN_FILTER,gl.NEAREST);gl.texParameteri(gl.TEXTURE_2D,gl.TEXTURE_WRAP_S,gl.CLAMP_TO_EDGE);gl.texParameteri(gl.TEXTURE_2D,gl.TEXTURE_WRAP_T,gl.CLAMP_TO_EDGE);gl.texImage2D(gl.TEXTURE_2D,0,gl.RGBA,w,h,0,gl.RGBA,gl.UNSIGNED_BYTE,p);return t};let crBf=d=>{let b=gl.createBuffer();gl.bindBuffer(gl.ARRAY_BUFFER,b);gl.bufferData(gl.ARRAY_BUFFER,new Float32Array(d),gl.STATIC_DRAW);return b};let crPx=(w,h)=>{let b=pow(2,1+floor(random()*4));let u=new Uint8Array(w*h*4);for(let i=0;i<w*h;i++){let c=i%b==0?255:0;u[i*4]=u[i*4+1]=u[i*4+2]=c;u[i*4+3]=255;if(random()<.1)b=pow(2,1+floor(random()*4))}return u};return{ini:ini,se:se,rn:rn,rz:rz}};let Bdl=()=>{let gl,scl,dims;let ini=async()=>{document.querySelector('html').style.height='100%';let bs=document.body.style;bs.margin=0;bs.height='100%';bs.overflow='hidden';bs.background='black';gl=GL();let glCtx=await gl.ini();scl=Math.min(window.devicePixelRatio,2);dims=gl.rz(scl);set();ani(0);document.addEventListener('visibilitychange',async()=>{if(!document.hidden){if(glCtx.isContextLost()){location.reload()}}})};let set=()=>{gl.se(dims[0],dims[1],scl)};let ani=time=>{let resized=gl.rz(scl);if(resized){scl=Math.min(window.devicePixelRatio,2);dims=resized;set()}gl.rn(dims[0],dims[1],scl,time);requestAnimationFrame(ani)};return{ini:ini}};let b=Bdl();b.ini();</script></body></html>
From Feb 1 to Feb 28, Chrome is presented as a
site specific installation. A stack of 8 displays shows the first 8 of 128
Chrome channels, visualizing the 1 second
offsets as 1 meter offsets in physical space.
For collectors of multiple Chrome channels:
Chrome channels are coordinated by universal
time (UTC ). To show them together, machines should have
accurate time:
Under reasonable operating conditions,
systems can be configured to maintain
1ms (millisecond) accuracy or better
(with respect to UTC).
Configuring Systems for High
Accuracy
You can have the date and time set
automatically using a network time
server.
Set the date and time on your Mac
Thank you to Ernst-Hermann Asendorf for helping with craft, Thomas Brüggemann and Danny Franzreb for photography and videography, and to our friends and family for feedback and support.