mat2 rot(float a)
{
  float ca = cos(a); float sa = sin(a);
  return mat2(ca,-sa,sa,ca);
}

float sdBox(vec3 p)
{
  p = abs(p);
  return max(p.x, max(p.y, p.z)) - 1.;
}

#define time (iTime * .25 - .25)

float mat = 0.;
#define PI 3.14159

float tesseract(vec3 p, float t)
{
  float dist = 10000.;

  for(float i = 0.; i <= 6.; ++i)
  {
    p.x -= .15 + (sin(t * .6) * .5 + .5) * .13;
    
    p.xy *= rot(t * 1.);
    p.xz *= rot(t * .5 );
    p.zy *= rot(t * .25);

    p.z -= .5;

    p = abs(p);
    
    if(i > 0.)
    {
		dist = min(dist, sdBox(p));
    }
      
    if(dist < .01)
    {
      mat = i;
      break;
    }
  }
	return dist;    
}

float map(vec3 p)
{
  vec3 cp = p;


  float dist = 10000.;

  p.yz *= rot(time);
  p.xy *= rot(time * .8);

  float ti = time * 4.;


  float frti = sin(fract(ti) * PI - PI * .5) * .5 + .5;
  ti = floor(ti) + frti * frti * frti;

	dist = tesseract(p, ti);

    float room = tesseract(cp * .125, 0.);
//    dist = max(10., );
    
    dist = tesseract(p, ti);
  	return dist;
}

void mainImage( out vec4 fragColor, in vec2 fragCoord )
{
  vec2 uv = vec2(fragCoord.x / iResolution.x, fragCoord.y / iResolution.y);
  uv -= 0.5;
  uv /= vec2(iResolution.y / iResolution.x, 1);

  vec3 ro = vec3(0.,0.,-10.);
  vec3 rd = normalize(vec3(uv, 1.));
  vec3 cp = ro;

  float cd = 0.; float st = 0.;

  for(; st < 1.; st += 1. / 128.)
  {
    cd = map(cp);
    if(cd < .01) break;
    cp += rd * cd;
  }

  fragColor = mix(vec4(.4,.1,.9,0.) * .25,vec4(.99), length(uv) * 1.);

  if(cd < .01)
  {

  fragColor = vec4(0.);
    vec3 col = vec3(1.,0.,0.);
    
    col.rg *= rot(float(mat));
    col.br *= rot(iTime * .5);
	col = abs(col * 5.);

    fragColor = mix(fragColor, col.rgbb, st   );
  }
}
