#ifdef GL_ES
precision mediump float;
precision mediump int;
#endif

uniform float time;
uniform sampler2D tex;
uniform vec4 resolution;
uniform float chromaStrength;
uniform float hueShift;
uniform float saturation;

uniform sampler2D logo;
uniform sampler2D credits;
uniform sampler2D message;
uniform sampler2D greets;
uniform sampler2D title;
uniform float showlogo;
uniform float showcredits;
uniform float showmessage;
uniform float showgreets;
uniform float showtitle;
uniform float textxor;

const float Gamma = 2.2;
//const float chromaStrength = 1.0;

float hash(vec3 p3){
    p3 = fract(p3*.1031);
	p3 += dot(p3,p3.yzx+19.19);
    return fract((p3.x+p3.y)*p3.z);
}

vec3 shiftHue(vec3 color, float hueAdjust){
    const vec3  kRGBToYPrime = vec3 (0.299, 0.587, 0.114);
    const vec3  kRGBToI      = vec3 (0.596, -0.275, -0.321);
    const vec3  kRGBToQ      = vec3 (0.212, -0.523, 0.311);
    const vec3  kYIQToR     = vec3 (1.0, 0.956, 0.621);
    const vec3  kYIQToG     = vec3 (1.0, -0.272, -0.647);
    const vec3  kYIQToB     = vec3 (1.0, -1.107, 1.704);
    float   YPrime  = dot (color, kRGBToYPrime);
    float   I       = dot (color, kRGBToI);
    float   Q       = dot (color, kRGBToQ);
    float   hue     = atan (Q, I);
    float   chroma  = sqrt (I * I + Q * Q);
    hue += hueAdjust;
    Q = chroma * sin (hue);
    I = chroma * cos (hue);
    vec3 yIQ = vec3 (YPrime, I, Q);
    return vec3(dot (yIQ, kYIQToR), dot (yIQ, kYIQToG), dot (yIQ, kYIQToB));
}

const int N = 16;
vec3 chromab(vec2 UV){
	vec2 uv = 1.0 - 2.0 * UV;
	vec3 c = vec3(0);
	float rf = 1.0;
	float gf = 1.0;
    float bf = 1.0;
	float f = 1.0/float(N);
	for(int i = 0; i < N; ++i){
		c.r += f*pow(texture2D(tex, 0.5-0.5*(uv*rf) ).r, Gamma);
		c.g += f*pow(texture2D(tex, 0.5-0.5*(uv*gf) ).g, Gamma);
		c.b += f*pow(texture2D(tex, 0.5-0.5*(uv*bf) ).b, Gamma);
		bf *= mix(1.0, 0.98, chromaStrength);
		gf *= mix(1.0, 0.99, chromaStrength);
        rf *= mix(1.0, 0.995, chromaStrength);
	}
	return c;
}

void main() {
	vec2 uv = gl_FragCoord.xy/resolution.xy;
	vec3 col = chromab(uv);
	col *= 1.0+0.25*(-1.0+2.0*hash(vec3(gl_FragCoord.xy, time)));
	col = shiftHue(col, hueShift);
	col = mix(col, vec3(length(col)), saturation);
	col = pow(col, vec3(1.05, 1.02, 0.96));
	col += mix(vec3(0), texture2D(logo, vec2(uv.x, 1.0-uv.y) ).rgb, showlogo*(1.0-textxor));
	col += mix(vec3(0), texture2D(credits, vec2(uv.x, 1.0-uv.y) ).rgb, showcredits*(1.0-textxor) );
	col += mix(vec3(0), texture2D(greets, vec2(uv.x, 1.0-uv.y) ).rgb, showgreets*(1.0-textxor) );
	col += mix(vec3(0), texture2D(title, vec2(uv.x, 1.0-uv.y) ).rgb, showtitle*(1.0-textxor) );
	col += mix(vec3(0), texture2D(message, vec2(uv.x, 1.0-uv.y) ).rgb, showmessage);
	gl_FragColor.rgb = pow(col, vec3(1.0/Gamma));
	gl_FragColor.a = 1.0;
}