uniform float iGlobalTime;
uniform vec3 iResolution;
uniform vec2 iMouse;
//uniform samplerCube iChannel1;

uniform sampler2D iChannel2;
uniform sampler2D iChannel3;



vec4 cubic(vec4 p[4], float x)
{
    return p[1] + 0.5 * x*(p[2] - p[0] + x*(2.0*p[0] - 5.0*p[1] + 4.0*p[2] - p[3] + x*(3.0*(p[1] - p[2]) + p[3] - p[0])));
}

vec4 sample(vec2 uv)
{
    //vec2 coorddiv = vec2(256.0, 64.0);
    //vec2 picdiv = vec2(6.0, 1.0);
    vec2 coorddiv = vec2(128.0, 128.0);
    vec2 picdiv = vec2(1.0, 1.0);

    vec2 multuv = uv * coorddiv / picdiv;
    
    vec2 uv2;
    uv2 = floor(multuv);
    
    vec4 cols1[4];
    vec4 cols2[4];
    vec4 cols3[4];
    vec4 cols4[4];
    
    
    cols1[0] = texture2D(iChannel3, (uv2 + vec2(-1.0, -1.0)) / coorddiv);
    cols1[1] = texture2D(iChannel3, (uv2 + vec2(0.0, -1.0)) / coorddiv);
    cols1[2] = texture2D(iChannel3, (uv2 + vec2(1.0, -1.0)) / coorddiv);
    cols1[3] = texture2D(iChannel3, (uv2 + vec2(2.0, -1.0)) / coorddiv);

    cols2[0] = texture2D(iChannel3, (uv2 + vec2(-1.0, 0.0)) / coorddiv);
    cols2[1] = texture2D(iChannel3, (uv2 + vec2(0.0, 0.0)) / coorddiv);
    cols2[2] = texture2D(iChannel3, (uv2 + vec2(1.0, 0.0)) / coorddiv);
    cols2[3] = texture2D(iChannel3, (uv2 + vec2(2.0, 0.0)) / coorddiv);

    cols3[0] = texture2D(iChannel3, (uv2 + vec2(-1.0, 1.0)) / coorddiv);
    cols3[1] = texture2D(iChannel3, (uv2 + vec2(0.0, 1.0)) / coorddiv);
    cols3[2] = texture2D(iChannel3, (uv2 + vec2(1.0, 1.0)) / coorddiv);
    cols3[3] = texture2D(iChannel3, (uv2 + vec2(2.0, 1.0)) / coorddiv);

    cols4[0] = texture2D(iChannel3, (uv2 + vec2(-1.0, 2.0)) / coorddiv);
    cols4[1] = texture2D(iChannel3, (uv2 + vec2(0.0, 2.0)) / coorddiv);
    cols4[2] = texture2D(iChannel3, (uv2 + vec2(1.0, 2.0)) / coorddiv);
    cols4[3] = texture2D(iChannel3, (uv2 + vec2(2.0, 2.0)) / coorddiv);

    vec4 outcol;
    
    vec2 f = fract(multuv);
    
    vec4 rows[4];
    
    rows[0] = cubic(cols1, f.x);
    rows[1] = cubic(cols2, f.x);
    rows[2] = cubic(cols3, f.x);
    rows[3] = cubic(cols4, f.x);
    
    outcol = cubic(rows, f.y);
    
  //  outcol = mod(outcol, vec4(1.0));
    
    //outcol = texture2D(iChannel0, uv);
    
    return outcol;
}



float rand(float x)
{
 return fract(sin(x) * 43758.5453);
}


void main(void)
{
	vec2 uv = gl_FragCoord.xy / iResolution.xy;

	vec2 uv2;

	uv2 = uv - vec2(0.5);
    
    float curvature = 0.8;

	float dist = length(uv2 * vec2(1.0, 0.7)) + curvature;
	uv2 *= pow(dist, 0.5) * 0.9;

	vec2 uv_vid = uv2;

	float heightmul = max(1.0, 200.0 - pow(iGlobalTime, 1.5) * 200.0);
	heightmul += sin(iGlobalTime * 10.0) * max(0.0, 0.5 - pow(iGlobalTime, 4.0) * 0.2);
	uv_vid.y *= heightmul;

    float widthmul = max(1.0, 200.0 - pow(iGlobalTime, 1.5) * 500.0);
    widthmul += sin(iGlobalTime * 10.0) * max(0.0, 0.5 - pow(iGlobalTime, 4.0) * 0.9);
    uv_vid.x *= widthmul;

//    uv_vid *= 1000.0;

	uv_vid += vec2(0.5);

    float warmup_darkness = min(1.0, iGlobalTime * 0.3);
    float warmup_darkness_tube = min(1.0, iGlobalTime * 1.0);

    vec2 uv_b = uv2 + vec2(0.5);

    uv2.x *= iResolution.z;

	uv2 += vec2(0.5);

	//uv.y = 1.0 - uv.y;

	// shadowmask is 84x49

	vec4 filter;
/*
	vec2 comp = fract(uv2 * vec2(300.0, 200.0));
	comp.y = fract(comp.y + floor(uv2.x*50.0) * 0.4);
	vec4 filter = vec4(0.0);
	filter.r = pow(1.0-length(comp-vec2(0.22, 0.5)), 4.0) * 3.0;
	filter.g = pow(1.0-length(comp-vec2(0.55, 0.5)), 4.0) * 3.0;
	filter.b = pow(1.0-length(comp-vec2(0.77, 0.5)), 3.0) * 3.0;
*/

	float gridsize = 200.0 / 8.0;
	filter = texture2D(iChannel3, uv2 * vec2(1.0, 84.0/49.0) * gridsize);
//	filter = sample(uv2 * vec2(1.0, 84.0/49.0) * gridsize);

//	filter.rgb = clamp(filter.rgb, vec3(0.2), vec3(1.0));
	//filter = vec4(1.0);

	float tvborder = 1.0;
	tvborder = min(tvborder, uv_b.x * 30.0);
	tvborder = min(tvborder, uv_b.y * 30.0);
	tvborder = min(tvborder, (1.0-uv_b.x) * 30.0);
	tvborder = min(tvborder, (1.0-uv_b.y) * 30.0);
	tvborder = pow(max(tvborder, 0.0),2.0);
    tvborder *= 1.5 - pow(dist, 5.0) * 0.2;

    float signalborder = 1.0;
    signalborder = min(signalborder, uv_vid.x * 30.0);
    signalborder = min(signalborder, uv_vid.y * 30.0);
    signalborder = min(signalborder, (1.0-uv_vid.x) * 30.0);
    signalborder = min(signalborder, (1.0-uv_vid.y) * 30.0);
    signalborder = pow(max(signalborder, 0.0),2.0);
    signalborder *= 1.5 - pow(dist, 5.0) * 0.2;

//    tvborder *= pow(2.1 - dist, 5.0) * 0.4 + 0.5;


	filter.rgb *= vec3(tvborder);

	vec4 imp = texture2D(iChannel2, uv_vid) * signalborder;
    imp *= 0.8 + pow(sin(uv2.y * 9.0 + iGlobalTime * 3.0) * 0.5 + 0.5, 2.0) * 0.4;
    imp *= rand(iGlobalTime * 4.0) * 0.2 + 0.8;
    
    imp *= warmup_darkness;

    imp += vec4(0.15) * warmup_darkness_tube;

    imp = clamp(imp, vec4(0.0), vec4(1.0));

    
	//imp = vec4(1.0);
    gl_FragColor = imp * filter;
}