#define pi acos(-1.)
#define tau pi*2.

precision highp float;
uniform vec2 resolution;
uniform float time;
uniform sampler2D backbuffer;
out vec4 outColor;

uint seed;
uint hashi( uint x) {
   x ^= x >> 16;
   x *= 0x7feb352dU;
   x ^= x >> 15;
   x *= 0x846ca68bU;
   x ^= x >> 16;
   return x;
}
uint wang(uint a) {
   a = (a ^ 61U) ^ (a >> 16U);
   a = a * 9U;
   a = a ^ (a >> 4);
   a = a * 0x27d4eb2dU;
   a = a ^ (a >> 15);
   return a;
}

#define hash_u_s(s)  ( ( hashi(uint(s)) ) )
#define hash_i_s(s)  ( int( hashi(uint(s)) ) )
#define hash_f_s(s)  ( float( hashi(uint(s)) ) / float( 0xffffffffU ) )
#define hash_v2_s(s)  vec2(hash_f_s(s),hash_f_s(s+12512))
#define hash_f()  ( float( seed = hashi(seed) ) / float( 0xffffffffU ) )
#define hash_v2()  vec2(hash_f(),hash_f())
#define hash_v3()  vec3(hash_f(),hash_f(),hash_f())
#define hash_v4()  vec3(hash_f(),hash_f(),hash_f(),hash_f())

#define hash_v3_s(s)  vec3(hash_f_s(s),hash_f_s(s + 1),hash_f_s(s + 2)

mat2 rot(float n){
 return mat2(cos(n),-sin(n),sin(n),cos(n));
}
float truchet(vec2 p){
   float width = .2;

   vec2 q = vec2(p.x,abs(p.y));
   q.y-=2./sqrt(3.);
   float arc = step(width,abs(length(q)-1./sqrt(3.)));
   float line = step(width, abs(p.y));
   return arc*line;
}
vec4 hexagon(vec2 p, float sca)
{
   p = p*sca;
   p.y /= sqrt(3.)/2.;
   float odd_rows = mod(floor(p.y),2.);
   p.x += odd_rows*.5;
   vec2 i_uv = floor(p),
        f_uv = fract(p)*2.-1.;

   vec2 q = (vec2(1)-abs(f_uv))*vec2(1.,sqrt(3.));

   if(q.x+q.y<.5){
       i_uv = i_uv+vec2(sign(f_uv.x)*.5-odd_rows+.5,sign(f_uv.y));
       f_uv = f_uv-2.*vec2(.5,1.)*sign(f_uv);
   }

   return vec4(i_uv, f_uv*vec2(1.,sqrt(3.)/2.));
}
vec3 samp(vec2 p){
 p=vec2(atan(p.y,p.x)/tau-length(p)*2.,length(p));
 float ay = p.y + pow(p.y,1.2);
 float by = log(p.y);
 p.y = mix(ay,by,sin(time)*.5+.5);
 p.y += time*.2 + 45.;

 vec2 i_hex = hexagon(p, 2.0).xy,
      f_hex = hexagon(p, 2.0).wz;
 i_hex.x = mod(i_hex.x,8.);

 float val = truchet(f_hex*rot(floor(hash_f_s(uint(i_hex.y*68387.+i_hex.x))*8.)*tau/6.));

 vec3 col = mix(vec3(0,.03,.01),vec3(.2,.1,.0),step(.5,val));

 return col;
}

void main(){
 vec2 r=resolution,
      p=gl_FragCoord.xy/r;p-=.5;p.x*=r.x/r.y;

 float ep = .85/r.y;
 int os = 2;
 vec3 col;
 for(int i=-os; i<=os; i++){
   for(int j=-os; j<=os; j++){
     vec2 off = vec2(i,j)*ep/float(os);
     col += samp(p+off);
   }
 }
 col/=float(os)*float(os);

 outColor = vec4(pow(max(col,0.),vec3(.454545)),1.);
}