texture vd_srctexture;
float4 vd_texsize;

float Threshold1 <
	bool vd_tunable = true;
	float vd_tunablemin = 1.0f;
	float vd_tunablemax = 50.0f;
> = 7.0f;

sampler src = sampler_state {
	Texture = <vd_srctexture>;
	AddressU = clamp;
	AddressV = clamp;
	MinFilter = Linear;
	MagFilter = Linear;
	MipFilter = None;
};

float2 taps[24]={
	{ -2, -2 },
	{ -1, -2 },
	{  0, -2 },
	{  1, -2 },
	{  2, -2 },
	{ -2, -1 },
	{ -1, -1 },
	{  0, -1 },
	{  1, -1 },
	{  2, -1 },
	{ -2,  0 },
	{ -1,  0 },
	{  1,  0 },
	{  2,  0 },
	{ -2,  1 },
	{ -1,  1 },
	{  0,  1 },
	{  1,  1 },
	{  2,  1 },
	{ -2,  2 },
	{ -1,  2 },
	{  0,  2 },
	{  1,  2 },
	{  2,  2 },
};

void VS(
	float4 pos : POSITION,
	float2 t0 : TEXCOORD0,
	out float4 oPos : POSITION,
	out float2 oT0 : TEXCOORD0
)
{
	oPos = pos;
	oT0 = t0;
}
 
float getweight(float3 diff, float f) {
//	return saturate(1.0 - 200.0*dot(diff, diff));
//	return saturate(1.0 - 50.0*dot(diff, diff));
	return saturate(1.0 - Threshold1/rsqrt(0.00001f + dot(diff, diff))*f);
}

float4 PS(
	float2 t0 : TEXCOORD0,
	float2 t1 : TEXCOORD1,
	float2 t2 : TEXCOORD2,
	float2 t3 : TEXCOORD3,
	float2 t4 : TEXCOORD4
) : COLOR0
{
	float3 p0 = tex2D(src, t0).xyz;
	float3 sum = 0;
	float3 sumsq = 0;
	float3 sumx = 0;
	float3 sumy = 0;

	for(int y=-3; y<=3; ++y) {
		for(int x=-3; x<=3; ++x) {
			float3 p = tex2D(src, t0 + float2(x, y)*vd_texsize.wz).xyz;

			sum += p;
			sumsq += p*p;
			sumx += p*x;
			sumy += p*y;
		}
	}

	float3 dcdx = sumx / (7*28);
	float3 dcdy = sumy / (7*28);

	float4 fsum = 0;
	for(int y=-3; y<=3; ++y) {
		for(int x=-3; x<=3; ++x) {
			float4 p = float4(tex2D(src, t0 + float2(x, y)*vd_texsize.wz).xyz, 1);
			float4 d = getweight(p0 + x*dcdx + y*dcdy - p.xyz, 1);

			fsum += p*d;
			sumsq += p.xyz*p.xyz;
		}
	}

	return fsum / fsum.a;
}

technique {
	pass {
		VertexShader = compile vs_3_0 VS();
		PixelShader = compile ps_3_0 PS();
	}
}
