uniform sampler2D color_lut;
uniform sampler2D distort_lut;
uniform sampler2D noise_lut;

uniform float lut_fade;
uniform vec3 distortParams; // freq, time, amount
uniform vec2 gammaParams; // exposure, gamma
uniform vec3 noiseParams; // offset.xy, amount
uniform vec2 invViewport;

vec2 distort_uv(in vec2 uv)
{
	vec2 offs;

	offs.x = textureLod(distort_lut, vec2(uv.y*distortParams.x + distortParams.y, 0.0), 0.0).x*distortParams.z;
	offs.x *= (sin(uv.y*3.14*distortParams.x + 3.14*distortParams.y)*2.0 - 1.0)*distortParams.z;
	offs.y = (sin(uv.x*3.14*distortParams.x + 3.14*distortParams.y)*2.0 - 1.0)*distortParams.z*0.01;

	return uv + offs;
}

// used by color_lookup()
vec4 color_correction(in vec4 color)
{
	color *= gammaParams.x;
	color.rgb = pow(color.rgb, gammaParams.yyy);
	return color;
}

// used by color_lookup()
float luminance(in vec3 color)
{
	return dot(color, vec3(0.299, 0.587, 0.114));
}


vec4 noise_lookup()
{
	vec2 uv = gl_FragCoord.xy * invViewport;
	float n = (texture(noise_lut, uv + noiseParams.xy).x*2.0 - 1.0)*noiseParams.z;
	return vec4(n, n, n, 1.0);
}


vec4 color_lookup(in vec4 color)
{
	float lum = luminance(color.rgb);
	vec4 lc = texture(color_lut, vec2(lum));
	vec4 c = mix(color, lc, lut_fade);
	vec4 final = color_correction(c) + noise_lookup();
	return final * color.a;
}
