#version 330 core

in vec2 vTexCoord;

uniform float uTime;
uniform vec2 uResolution;
uniform vec2 uMouse;

uniform sampler2D uTextureUnit;
uniform vec4 uColor;
uniform float uDepth;

out vec4 fragColor;
out float gl_FragDepth;

#ifdef GL_ES
precision mediump float;
#endif

// shadertoy emulation
#define iTime uTime
#define iResolution uResolution
#define iMouse uMouse

float tanh(float x) {
    float ex = exp(2.0 * x);
    return ((ex - 1.) / (ex + 1.));
}

vec3 tanh(vec3 x) {
    vec3 ex = exp(2.0 * x);
    return ((ex - 1.) / (ex + 1.));
}

// --------[ Original ShaderToy begins here ]---------- //


#define Frame float(iFrame)
#define Time iTime
#define PixelCount iResolution.xy
#define clamp01(x) clamp(x, 0.0, 1.0)
#define rsqrt inversesqrt

const float Pi = 3.14159265359;
const float Pi05 = Pi * 0.5;
const float Pi2  = Pi * 2.0;
const float RcpPi= 1.0 / Pi;

float Pow2(float x) {return x*x;}
float Pow3(float x) {return x*x*x;}
float Pow4(float x) {return Pow2(Pow2(x));}

float GammaEncode(float x) {return pow(x, 1.0 / 2.2);}
vec2 GammaEncode(vec2 x) {return pow(x, vec2(1.0 / 2.2));}
vec3 GammaEncode(vec3 x) {return pow(x, vec3(1.0 / 2.2));}
vec4 GammaEncode(vec4 x) {return pow(x, vec4(1.0 / 2.2));}

float ddxyLen(float v) { return length(vec2(dFdx(v), dFdy(v))); }
float ddxyRcpLen(float v) { return rsqrt( Pow2(dFdx(v)) + Pow2(dFdy(v)) ); }


float rescale(float v) { return v * ddxyRcpLen(v); }

float Graph(float f, float b)
{
    return clamp01(1.0 - (abs(rescale(f))-0.5-b)); 
}


float Line(float u, float b) { return Graph(u, b); }
float Lines(float u, float b) { return Graph(sin(u * Pi), b); }

float Grid(vec2 uv, float b)
{
    float xl = Lines(uv.x, b);    
    float yl = Lines(uv.y, b);

    return max(xl, yl);
}

float Cross(vec2 uv, float b)
{
    float xl = Line(uv.x, b);    
    float yl = Line(uv.y, b);

    return max(xl, yl);
}

float Dot(vec2 sp, vec2 dp, float dr)
{
    float v = length(sp - dp) - dr;
    
    if(v > dr) return 0.0;
    
    v *= ddxyRcpLen(v);
    v = 1.0 - clamp(v * 1.0, 0.0, 1.0);
    
    return v;
}



// Lincense: CC0 (https://creativecommons.org/publicdomain/zero/1.0/)

/*
	A soft clip that smoothly blends between the Reinhard tonemapping transfer function and a hard clip.
*/

float Reinhard(float x) { return x / (x + 1.0); }
float HardClip(float x) { return   min(x, 1.0); }

// x: [0, inf], s: (-1, 1] / (soft, hard]
float SoftClip(float x, float s)
{
    return (1.0 + x - sqrt(1.0 - 2.0*s*x + x*x)) / (1.0 + s);
}

void mainImage( out vec4 outCol, in vec2 uv0 )
{
	vec2 uv = uv0 - 0.5;
    uv0 += .0;
    
    vec2 tex = uv0;
    tex -= iResolution.xy * 0.125;
    tex /= iResolution.xx * 0.125;

    tex *= 0.25+0.0375;
    

    vec3 col = vec3(0.0);
    
	col = mix(vec3(1.0), vec3(0.9), Grid(tex.xy * 4.0, 0.0));        
	col = mix(col, vec3(0.5), Grid(tex.xy * 1.0, 0.0));        
	col = mix(col, vec3(0.125), Cross(tex.xy * 1.0, 0.)); 	
    
    
    // relevant plotting code:
    
    // black
    col = mix(col, vec3(0.), Graph(HardClip(tex.x) -tex.y, 1.));  
    col = mix(col, vec3(0.), Graph(Reinhard(tex.x) -tex.y, 1.));  
    
    // grey
    col = mix(col, vec3(0.5), Graph(SoftClip(tex.x, 0.0) -tex.y, 1.) * 0.5);  
    col = mix(col, vec3(0.5), Graph(SoftClip(tex.x, 0.55) -tex.y, 1.) * 0.5);  
    col = mix(col, vec3(0.5), Graph(SoftClip(tex.x, 0.85) -tex.y, 1.) * 0.5);  
    col = mix(col, vec3(0.5), Graph(SoftClip(tex.x, 0.9921875) -tex.y, 1.) * 0.5);
    
    // red
    col = mix(col, vec3(1.0, 0.0, 0.0), Graph(SoftClip(tex.x, max(-0.99, sin(iTime))) -tex.y, 1.));  

       
    
    #if 1
    vec2 s = (uv0/iResolution.xy*2.0-1.0);
    s.x = 1.0-Pow2(s.x);    s.y = 1.0-Pow2(s.y);
    col *= mix(1.0, 0.4, Pow2(1.0-sqrt(s.x*s.y)));
    #endif
    
    outCol = vec4(GammaEncode(clamp01(col)), 1.0);    

}

// --------[ Original ShaderToy ends here ]---------- //

void main(void)
{
    mainImage(fragColor, vec2(vTexCoord.x, 1.0 - vTexCoord.y) * uResolution);

    fragColor *= uColor;
    gl_FragDepth = uDepth;
}
