// Created by inigo quilez - iq/2014
// License Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License.

// Gathering pixels along the direction perpendicular to the gradient
// of an image. See also: https://www.shadertoy.com/view/Md23zz

#define ISOLINES

vec4 texture0( in vec2 x )
{
    //return texture( iChannel0, x );
    vec2 res = iChannelResolution[0].xy;
    vec2 u = x*res - 0.5;
    vec2 p = floor(u);
    vec2 f = fract(u);
    f = f*f*(3.0-2.0*f);    
    vec4 a = texture( iChannel0, (p+vec2(0.5,0.5))/res, -64.0 );
	vec4 b = texture( iChannel0, (p+vec2(1.5,0.5))/res, -64.0 );
	vec4 c = texture( iChannel0, (p+vec2(0.5,1.5))/res, -64.0 );
	vec4 d = texture( iChannel0, (p+vec2(1.5,1.5))/res, -64.0 );
    return mix(mix(a,b,f.x), mix(c,d,f.x),f.y);
}
   

vec2 flow( vec2 uv )
{
	vec2 e = 1.0/iChannelResolution[0].xy;
    
    float time = 5.0 * mod( iTime, 12.0 );
    
	for( int i=0; i<50; i++ )
	{
		float h0 = texture0( uv              ).x;
		float h1 = texture0( uv+vec2(e.x,0.0)).x;
		float h2 = texture0( uv+vec2(0.0,e.y)).x;
        
        #ifdef ISOLINES
        // tangent
		vec2 f = vec2( h2-h0, h0-h1 )/(255.0*e);
        #else
        // gradient
        vec2 f = vec2( h1-h0, h2-h0 )/(255.0*e);
        #endif
        
        // move        
        uv += 0.0015*f   *clamp( (time-float(i)), 0.0, 1.0 );
	}
    
    return uv;
}

void mainImage( out vec4 fragColor, in vec2 fragCoord )
{
    vec2 p = fragCoord.xy / iResolution.xy;

    // orbit, distance and distance gradient
    vec2 uva = 0.05*(p + vec2(1.0,0.0)/iResolution.xy);
	vec2 uvb = 0.05*(p + vec2(0.0,1.0)/iResolution.xy);
	vec2 uvc = 0.05*p;
	vec2 nuva = flow( uva  );
	vec2 nuvb = flow( uvb );
	vec2 nuvc = flow( uvc );
    float fa = length(nuva-uva)*64.0;
    float fb = length(nuvb-uvb)*64.0;
    float fc = length(nuvc-uvc)*64.0;
    vec3 nor = normalize( vec3((fa-fc)*iResolution.x,1.0,(fb-fc)*iResolution.y ) );

    // color
  	vec3 col = texture(iChannel1, 4.0*nuvc).xyz;
    // ilumination
    vec3 lig = normalize( vec3( 1.0,1.0,-0.4 ) );
    col *= vec3(0.5,0.6,0.7) + vec3(1.0,0.9,0.8) * clamp( dot(nor,lig), 0.0, 1.0 );
    col *= sqrt(fc);
    // postprocess    
    col = 1.2*pow( col, vec3(0.8,0.8,0.7) );
    col *= 0.75 + 0.25*sqrt( 16.0*p.x*p.y*(1.0-p.x)*(1.0-p.y) );
    
	fragColor = vec4( col, 1.0 );
}
