#version 330 core

// uniforms expected by the host
uniform vec3 iResolution;
uniform float iTime;
uniform float uAlpha;

out vec4 FragColor;

#define T iTime
#define PI 3.141596
#define S smoothstep

mat2 rotate(float a){
  float s = sin(a);
  float c = cos(a);
  return mat2(c,-s,s,c);
}


void mainImage(out vec4 O, in vec2 I){
  vec2 R = iResolution.xy;
  vec2 uv = (I*2.0 - R)/R.y;

  O.rgb = vec3(0.0);
  O.a = 1.0;

  vec3 ro = vec3(0.0, 0.0, -10.0);
  vec3 rd = normalize(vec3(uv, 1.0));

  float z = 0.0;
  float d = 1e10;

  for(float i = 0.0; i < 100.0; i++){
    vec3 p = ro + rd * z;

    p.xy *= rotate(p.z * 0.1);

    float s = 5.0;
    vec2 id = round(p.xy / s);
    id = clamp(id, -1.0, 1.0);

    for(float x = -1.0; x <= 1.0; x++){
      for(float y = -1.0; y <= 1.0; y++){
        vec2 q = p.xy - s * (id + vec2(x, y));
        float d1 = length(q - vec2(1.0)) - (sin(p.z + T * 4.0) * 0.3 + 0.4);
        d1 = max(0.001, d1);
        d = min(d, d1);
      }
    }

    O.rgb += (1.1 + sin(vec3(3.0,2.0,1.0) + (p.z) * 0.2 + (id.x + id.y))) / d;
    z += d;

    if(z > 50.0 || d < 1e-3) break;
  }

  O.rgb = tanh(O.rgb / 1e5);
}

void main()
{
    vec2 fragCoord = gl_FragCoord.xy;
    vec4 col;
    mainImage(col, fragCoord);
    col.a *= uAlpha;
    FragColor = col;
}
