const float tol = .31;
vec3 ro;


const float an = .001;
const float cw = cos(an);
const float sw = sin(an);


mat2 rot(float an) { float cc=cos(an),ss=sin(an); return mat2(cc,ss,-ss,cc); }

float wheel(vec3 p) {


    vec4 q = vec4(p , 15. );


    vec4 jc = q;

    float ww = 9.;


    float i=0.;
    float scale = 1.27;

    for (;i<11.;i++){

        if ( q.x > 1. )  q.x = 2. - q.x;
        else if ( q.x < -1.) q.x = -2. - q.x;

        if ( q.y > 1. )  q.y = 2. - q.y;
        else if ( q.y < -1.) q.y = -2. - q.y;

        if ( q.z > 1. )  q.z = 2. - q.z;
        else if ( q.z < -1.) q.z = -2. - q.z;

        if ( q.w > 1. )  q.w = 2. - q.w;
        else if ( q.w < -1.) q.w = -2. - q.w;

        float lz1 = length(q.xyz);

        float lzz1;

        float tt=iTime/4.;

        if ( lz1 < .66 ) { q.xyz *= 4.; ww *= 4.; q.xy = rot( tt )*q.xy; }
        else if ( lz1 < 1.6) { q.xyz = q.xyz/(lzz1=lz1*lz1); ww *= lzz1; q.xy = rot(-tt)*q.xy; }


        q = scale * q + jc/2.;

        ww *= scale;


    }

    return (length(q))/ ww;


}


vec2 scene(vec3 p) {

    return vec2(  max( wheel(p), -(length(p-ro)-1.48 ) ) ,  1.);
}


vec3 march( vec3 ro, vec3 rd) {

    float dist = 1e6,  totDist=0.,  distFac=1.;

    vec3 p = ro;

    vec3 color = vec3(0);

    for (float i=0.; i<10.; i++) {

        dist = scene(p).x;

        p += dist * rd;

        totDist += dist;

        color += vec3( dist, dist*dist/2.,0.) * exp(-totDist/i);

    }

    return color;
}



void mainImage0( out vec4 O, in vec2 U )
{

    U = (2.*U - iResolution.xy) / iResolution.y *2.;

    vec3 rd = normalize( vec3(U, 5.) );


    ro = vec3(0.,0., -3.98);

    vec3 color = march( ro, rd );


    O = vec4( pow(color,vec3(.5)), 1);

}


//thanks Faabrice
void mainImage(out vec4 O, vec2 U) {
    mainImage0(O,U);
    if ( fwidth(length(O)) > .01 ) {  // difference threshold between neighbor pixels
        vec4 o;
        for (int k=0; k < 9; k+= k==3?2:1 )
          { mainImage0(o,U+vec2(k%3-1,k/3-1)/3.); O += o; }
        O /= 9.;
      //O.r++;                        // uncomment to see where the oversampling occurs
    }
}