SamplerState sm:register(s1);
Texture2D input:register(t0);

cbuffer c : register(b1)
{
	float exposure; // adjust initial brightness, default: 0.5
	float saturation; // desaturate, or color boost, applied before colorization, default: 0.5
	float vignette; // vignette, focus center, default: 0.0
	float grain; // film grain, kills noise, default: 0.5;

	float red; // amplify red, default:.5
	float green; // amplify green, default:.5
	float blue; // amplify blue, default:.5
	float tonemap; // darken bright spots so it doesn't overflow, default:.5

	float red_offset; // add or remove red color, default:.5
	float green_offset; // add or remove green color, default:.5
	float blue_offset; // add or remove blue color, default:.5
	float contrast; // if too dark, adjust contrast at the end, default:.5

	float flash;
	float glitch0;
	float glitch1;
	float glitch2;
}


float hash(float2 t, float3 c) {
	float s = dot(frac(t.xyx*1132.914), frac(c.xyz*0.495));
	s = frac(s*45.723 + t.x*t.y*11.951312 + 11.8231);
	s = frac(s*11.423 + s*t.y*511.451312 + 1.5231);
	s = frac(s*11.423 + t.x*s*511.451312 + 1.5231);
	return s;
}

float4 getColorSample(float2 t){
	//here we glitch
	float voffset = glitch0*glitch0*4.0;
	float2 uv = frac(t*float2(1.0, 1.0 + glitch0) + float2((t.y + sin(t.y*4.0)*.1 + 1.0 / frac(t.y + voffset))*glitch0, voffset));
		float h = frac(abs(sin(sin(uv.y*865.341)*14.125)*64.12)*12.315);
	uv.x += glitch1 * h*h*h*h*2.0;
	uv += frac(input.Sample(sm, uv).xy*85.123)*glitch2;
	return input.Sample(sm, uv);
}

float4 main(float4 PositionSS : SV_Position, float2 t : TEXCOORD) : SV_TARGET0
{
	float4 c = getColorSample(t);
	float gr = grain; gr -= .5; gr = gr*gr*gr;
	c += hash(t,c.xyz)*gr*.25; c = max(c,.0);
	float exp = exposure; exp = exp*2.0; exp -= 1.0; exp *= 8.0;	c *= pow(2.0,exp);
	float w = dot(c.rgb,float3(.3,.5,.2)); float3 gray = w; c.xyz = lerp(c.xyz,gray,1.0 - 2.0*saturation);
	c.xyz += (float3(red_offset, green_offset, blue_offset) - .5)*.30;
	c *= pow(2.0,length(t - .5)*(-16.0*vignette));
	c += hash(t,c.xyz)*gr*.25; c = max(c,.0);
	c = (c*float4(red,green,blue,0.5)*2.0) / (1.0 + c*tonemap*2.0);
	c *= pow(2.0,contrast*4.0 - 1.0);
	c += float4(1, 1, 1, 0)*flash*flash;
	//c=pow(c,(1.0/2.2)); //inverse gamma
	return c;
}