const float pi=acos(-1.);
float t=0.0,d=0.0;

vec3 rep(vec3 p, float r) { return mod(p,r)-.5*r; }

float grid(vec3 p) {
  float d=1000.;
  float w=.4+.2*sin(t*2.5);
  p=rep(p,1.);
  d=min(d,length(p.xy)-w);
  d=min(d,length(p.xz)-w);
  d=min(d,length(p.yz)-w);
  return d;
}

vec3 fold(vec3 p) {
  float a=3.0;
  for(int i=0; i<5; i++) {
    p = 2.*clamp(p,-vec3(a),vec3(a))-p;
    a*=.2+(.1*sin(t*2.));
  }
  return p;
}

float scene(vec3 p) {
  p=fold(p);
  return grid(p);
}

vec3 norm(vec3 p) {
  vec2 e=vec2(.001,0);
  return normalize(scene(p)-vec3(scene(p-e.xyy),scene(p-e.yxy),scene(p-e.yyx)));
}

vec2 proj(vec3 p, vec3 n) {
  n = pow(abs(n),vec3(2.));
  return (n.x*p.zy+n.y*p.xz+n.z*p.xy)/(n.x+n.y+n.z);
}

float tex( vec2 uv )
{
  float o=0.;
  uv.y-=2.665;
  for(float i=1.; i<41.; i++) {
    uv.y+=.13+.3*sin(uv.x+i+t);
    uv.x+=.13*sin(uv.y+i+t);
    o+=1./((100.+80.*sin(uv.x+t*20.))*abs(uv.y));
  }
  return o;
}

void mainImage( out vec4 fragColor, in vec2 fragCoord )
{
    vec2 uv = (fragCoord/iResolution.xy-.5)/vec2(iResolution.y/iResolution.x, 1);
    
    t = 3.55+.5*mod(iTime, 20.*pi);

  	if(abs(uv.y)+.05*cos(uv.x*2.)>.45) return;
  	uv/=1.-length(uv)*3.;
  	vec3 o=vec3(sin(t),sin(sin(t)),cos(t));
  	vec3 tg=.5*vec3(cos(t),cos(sin(t)),sin(t));
 	vec3 f=normalize(tg-o);
  	vec3 s=normalize(cross(vec3(.4*sin(t),1,0),f));
  	vec3 u=normalize(cross(f,s));
  	vec3 dir=normalize(f*.6+uv.x*s+uv.y*u);
  
  	vec3 col=vec3(0),p=o;
  	for(int i=0;i<200;i++) {
    	float h=scene(p)*.85;
    	if(abs(h)<.01) {
      		vec2 tuv = proj(p,norm(p));
      		vec3 tint=acos(normalize(dir-p))*vec3(.5,.5,1);
      		col = clamp(.4*tex(tuv)*tint, 0.,1.);
      		float den=40.+2.*sin(t*10.+p.z*5.);
      		col*=pow(float(i)/den, 5.);
      		break;
    	}
    	if(d>11.) break;
    	d+=h;
    	p+=dir*h;
  	}
    
    fragColor = vec4(col,1.0);
}
