#define time iTime
#define rez iResolution
vec3 mcol=vec3(0.0),blm=vec3(0.0);
float dL=1000.,tim;
float DE(vec3 p0){
  vec4 p=vec4(abs(mod(p0,4.)-2.)-1.,1.1);
  vec2 c=vec2(-.4,-.76);
  for(int n=0;n<4;n++){
    p.xy=abs(p.xy+1.0)-1.0;
    p*=2.0/clamp(dot(p.xyz,p.xyz),0.25,1.0);
    if(p.y>p.z)p.yz=p.zy;
    if(p.x>p.y)p.xy=p.yx;
    p.yz+=c;
    if(n==2){
      float d=length(p.xyz/p.w);
      if(d<dL)dL=d;
      blm+=abs(sin(p0))/(1.+dL*dL*20000.);
    }
    if(n==3 && mcol.x>0.0)mcol+=vec3(1.)+30.*abs(p.xyz)/p.w;
  }
  return (abs(p.z)-1.0)/p.w;
}
float DEL(vec3 p0){
  vec4 p=vec4(abs(mod(p0,4.)-2.)-1.,1.1);
  vec2 c=vec2(-.4,-.76);
  for(int n=0;n<3;n++){
    p.xy=abs(p.xy+1.0)-1.0;
    p*=2.0/clamp(dot(p.xyz,p.xyz),0.25,1.0);
    if(p.y>p.z)p.yz=p.zy;
    if(p.x>p.y)p.xy=p.yx;
    p.yz+=c;
  }
  return length((p.xyz+sin(p0+vec3(tim,.8*tim+1.,.3*tim+2.))*2.)/p.w);
}
vec3 normal(vec3 p, float d){//from dr2
  vec2 e=vec2(d,-d);vec4 v=vec4(DE(p+e.xxx),DE(p+e.xyy),DE(p+e.yxy),DE(p+e.yyx));
  return normalize(2.*v.yzw+vec3(v.x-v.y-v.z-v.w));
}
vec3 lightDir(vec3 p, float d){//modified dr2 for light direction
  vec2 e=vec2(d,-d);vec4 v=vec4(DEL(p+e.xxx),DEL(p+e.xyy),DEL(p+e.yxy),DEL(p+e.yyx));
  return -normalize(2.*v.yzw+vec3(v.x-v.y-v.z-v.w));
}
vec3 sky(vec3 rd, vec3 L){
  return rd*.1+0.4*dot(rd,L)+0.6;
}
float rnd;
void randomize(in vec2 p){rnd=fract(float(time)+sin(dot(p,vec2(13.3145,117.7391)))*42317.7654321);}

float ShadAO(in vec3 ro, in vec3 rd,in float dL){
 float t=0.01*rnd,s=1.0,d,mn=0.01;
 for(int i=0;i<12;i++){
  d=max(DE(ro+rd*t)*1.5,mn);
  s=min(s,d/t+t*0.5);
  t+=d;
  if(d>dL)break;
 }
 return s;
}
vec3 scene(vec3 ro, vec3 rd){
  float t=DE(ro),d,px=clamp(cos(iTime*.5)*50.,.5,50.)/rez.x;
  t=min(t,dL)*rnd;
  for(int i=0;i<64;i++){
    t+=d=DE(ro+rd*t);
    if(t>50.0 || d<px*t)break;
  }
  vec3 L=normalize(vec3(0.4,0.025,0.5));
  vec3 col=sky(rd,L);
  if(d<px*t*5.0){
    mcol=vec3(0.001);
    vec3 so=ro+rd*t;
    vec3 N=normal(so,d);
    vec3 scol=mcol*0.25;
    d=DEL(so);
    L=lightDir(so,d);
    float dif=0.5+0.5*dot(N,L);
    float vis=clamp(dot(N,-rd),0.05,1.0);
    float fr=pow(1.-vis,5.0);
    float shad=ShadAO(so,L,d*.5);
    col=(scol*dif/(1.+dL*dL)+fr*sky(reflect(rd,N),L))*shad;
  }
  return (col+blm)/t;
}
mat3 lookat(vec3 fw){vec3 up=vec3(0.0,1.0,0.0),rt=-normalize(cross(fw,up));return mat3(rt,normalize(cross(rt,fw)),fw);}
vec3 path(float t){t*=.5;
  return vec3(t,sin(t*5.)*.1,cos(t)*5.);
}
void mainImage( out vec4 fragColor, in vec2 fragCoord ) {
 randomize(fragCoord);tim=time*5.;
 vec3 ro=path(iTime),fw=normalize(path(iTime+0.001)+vec3(0,.002,0)-ro);
 vec3 rd=lookat(fw)*normalize(vec3((iResolution.xy-2.0*fragCoord)/iResolution.y,1.0));
 fragColor=vec4(scene(ro,rd),1.0);
}
