#define rot(a) mat2(cos(a),-sin(a),sin(a),cos(a))
#define SQR(v) ( (v) * (v) )
#define T(U) texture(iChannel0,U)

void mainImage( out vec4 O, vec2 U )
{
    vec2 R = iResolution.xy;
    U =  1.2* (U+U-R)/R.y;
    O -= O;

    vec2  r = vec2(.5,.3);              // base ellipse aspect ration
    float a = -3.14/2.,                 // ellipse angle tilt per scaling length
          va, d, l = 1.,                // scaling length
          e = (iMouse.z<=0.) ? .3 : .1, // thickness of each ellipse
          show = ( 15. + floor(15.*cos(.5*iTime)) ) * sign(iMouse.z);

    for (float l = .1,n=1.; l<3.; l+= .1,n++) {
     // r = .5*vec2( 1., .6+.4* (l/3.) );     // morphing to circle outside
        vec2 V = 1./vec2(r) * ( rot(a+a*l)* U ) ;
        d = dot (V, V ); // quadratic form of the ellipsoid U.R⁻¹.(1/d²).R.U = l²
        va = iTime*(1.5/l-0.);                // in galaxies, tangential velocity is constant !
        vec4 C = T( rot(va+n) * .5*V/l );     // noise in ellipse frame
        O += smoothstep(e,0.,abs(sqrt(d)-l) ) // ellipse shape
        //  * C*C / l;                        // noise + fading
            * ( n==show ? vec4(1,0,0,0) : C*C ) / l;  // or show ellipse
    }
    //O = vec4(1.-d);
}




/** // --- try loopless by inversion of U*Quad(a*l)*U = l² : not trivial !

    float A = SQR(U.x/r.x) + SQR(U.y/r.y),              // cos(a*l)^2
          B = SQR(U.y/r.x) + SQR(U.x/r.y),              // sin(a*l)^2
          C = 2.*U.x*U.y* (-1./SQR(r.x)+1./SQR(r.y) ),  // cos(a*l)*sin(a*l)
          D = 0.;                                       // 1 ( indeed, l² )
    A += -B; D += B;                                    // S² = 1-C²
    float a = A*A+C*C;
    // in fact invariance of a is in r⁴ but not directly length⁴
    O = .16*vec4(a/SQR(dot(U,U)/dot(r,r))); // a = k(r⁴)*||U||⁴  .019/U⁴ .16*r⁴/U⁴

/**/
