
#define BAILOUT    (512.)
#define BAILOUT2   (BAILOUT*BAILOUT)


#define PI (3.14159265359)

// https://www.shadertoy.com/view/4djSRW
//----------------------------------------------------------------------------------------
///  2 out, 3 in...
#define HASHSCALE3 vec3(.1031, .1030, .0973)
vec2 hash23(vec3 p3)
{
	p3 = fract(p3 * HASHSCALE3);
    p3 += dot(p3, p3.yzx+19.19);
    return fract(vec2((p3.x + p3.y)*p3.z, (p3.x+p3.z)*p3.y));
}
//----------------------------------------------------------------------------------------
//  1 out, 3 in...
#define HASHSCALE1 .1031
float hash13(vec3 p3)
{
	p3  = fract(p3 * HASHSCALE1);
    p3 += dot(p3, p3.yzx + 19.19);
    return fract((p3.x + p3.y) * p3.z);
}


float smoooth(float x){
    return 0.5 - 0.5*cos(x*PI);
}

vec4 mandelbrot( in vec2 fragCoord )
{
    vec2 p = -1.0 + 2.0 * fragCoord.xy / iResolution.xy;
    p.x *= iResolution.x/iResolution.y;


    float tz = 0.5 - 0.5*cos(0.225*iTime);
    float tz2 = 0.5 + 0.5*sin(0.225*iTime*.5);
    float zoo = pow( 0.5, 14.*tz-.5 );
    float a = iTime/6.;

	vec2 c;

    c = vec2( -1.94048654605392405406751569047147 , 0.000458638111963617712593673719675 );
    zoo = 0.001;

    c = vec2(-.5,.0);
    zoo = 1.0;

    c.x = 0.3756184895833333538771574983;
    c.y = 0.3697482638888889011567870542;
    zoo = 1e-3;

    c.x = -1.408116319444444495405409975;
    c.y = -0.136393229166666686457873824;
    zoo = 3e-3;

    c.x = -1.7836303710937500721257024917;
    c.y = -0.0000054253472222246051329553;
    zoo = 4e-4*(1.1-tz)*100.;

    float zoo1 = 4e-4;
    float zoo2 = 1.3;
    float zoomTransition = 0.5 - 0.5*cos(iTime*PI/48.);
    if(iMouse.z > .5)
    {
        zoomTransition = iMouse.x/iResolution.x;
    }

    zoo = mix(
          log(zoo1)
        , log(zoo2)
        , zoomTransition
    );
    zoo = exp(zoo);

    int ITERATIONS = 800;

    c += p*zoo;
    //c += (-1.0 + 2.0 * fragCoord.xy / iResolution.y - vec2(.8,.0))*zoo;

    // iterate
    vec2 z  = vec2(0.0);
    float m2 = 0.0;
    vec2 dz = vec2(0.0);
    int iter = 0;
    for( int i=0; i<ITERATIONS; i++ )
    {
        if( m2>BAILOUT2 ) continue;

		// Z' -> 2Â·ZÂ·Z' + 1
        dz = 2.0*vec2(z.x*dz.x-z.y*dz.y, z.x*dz.y + z.y*dz.x) + vec2(1.0,0.0);

        // Z -> ZÂ² + c
        z = vec2( z.x*z.x - z.y*z.y, 2.0*z.x*z.y ) + c;

        m2 = dot(z,z);
        iter = i;
    }

    // distance
	// d(c) = |Z|Â·log|Z|/|Z'|
	float d = 0.5*sqrt(dot(z,z)/dot(dz,dz))*log(dot(z,z));
	float potential = float(iter) - log( log(length(z)) / log(BAILOUT) )/log(2.);


    // do some soft coloring based on distance
	//d = clamp( 2.0*d/zoo, 0.0, 1.0 );
	//d = pow( d, 0.25 );

    bool inside = iter == ITERATIONS-1;

    return vec4( inside ? 0. : (d/zoo) , potential , iter , inside );

}



void drawNormalMandelbrot( out vec4 color, in vec2 coord )
{
    vec4 i;

    i = mandelbrot(coord);
    // inside mandelbrot is black
    i.rg *= i.a > 0. ? 0. : 1.;

    float gradientSmooth = 2.;
    float t = iTime/2.;
    color = vec4(
        cos(log(i.r)*PI/gradientSmooth+t)
      , cos(log(i.r)*PI/gradientSmooth*.445487-t)
      , cos(log(i.r)*PI/gradientSmooth*.8978412)
      , .0
    )*.5+.5;
    color *= sin(
        -log(i.r)*10.
        //i.g*2.
        -t*PI*3.3)*.5+.55;
    color = tanh(color*5.);


    float limitBlack = 5e-3;
    color *= smoooth(clamp(i.r/limitBlack,.0,1.));

    /*float limitWhite = 1e-5;
    color = mix(
          vec4(1.)
        , color
        , smoooth(clamp(i.r/limitWhite,.0,1.))
    );*/
    if(i.r == .0)
    {
        color = vec4(.0,.0,.15,1.);
    }
}


void mainImage( out vec4 color, in vec2 coord )
{
    color = texture(iChannel0,coord/iResolution.xy);

    drawNormalMandelbrot(color,coord);
}
