matrix World;
matrix View;
matrix Projection;

struct vsInput
{
	float4 Pos 	: POSITION;
	float2 Tex 	: TEXCOORD;
};

struct psInput
{
	float4 Pos 		: SV_POSITION;
	float4 Tex		: TEXCOORD0;
};

Texture2D InputTexture;

SamplerState PointSampler
{
	Filter = MIN_MAG_MIP_POINT;
	AddressU = Clamp;
	AddressV = Clamp;
};

float4 offset = float4(0.f, 0.f, 1.f  / 1280.f, -1.f / 720.f);
float2 right = float2(1.f / 1280.f, 0.f);
float2 up = float2(0.f, 1.f / 720.f);

//=============================================================================

psInput vShader(vsInput input)
{
	psInput output;
	
	output.Pos = mul(input.Pos, World);
	output.Pos = mul(output.Pos, View);
	output.Pos = mul(output.Pos, Projection);
	output.Tex = input.Tex.xyxy + offset;

	return output;
}

//=============================================================================

float color_thresh = 0.25f;
float depth_thresh = 0.00001f;

float GetSum(float3 col)
{
    return dot(col, float3(1.f, 1.f, 1.f));
}

float4 pShader(psInput input) : SV_Target
{
	float4 psout = 0.f;
	float4 c, u, r;

	c = InputTexture.Sample(PointSampler, input.Tex.xy);
	u = InputTexture.Sample(PointSampler, input.Tex.xw);
	r = InputTexture.Sample(PointSampler, input.Tex.zy);

	float lum = GetSum(c.rgb);
	float lumr = GetSum(r.rgb);
	float lumu = GetSum(u.rgb);

	// Detect edge to the right and edge above
	// Color
	psout.rg = float2(lum - lumr, lum - lumu);
	psout.rg = (psout.rg * psout.rg) >= color_thresh;
	
	// Depth
	float2 delta_d = float2(c.a - r.a, c.a - u.a);
	delta_d = (delta_d * delta_d) >= depth_thresh;
	
	psout.rg += delta_d;

	float2 d = float2(ddx(psout.r), ddy(psout.g));
	psout.ba = d != 0.f;

	clip(dot(psout, float4(1.f, 1.f, 1.f, 1.f)) - 1.f);
	
	return psout;
}

DepthStencilState NoDepthStencilEdge
{
	DepthEnable = false;

	StencilEnable = true;
	StencilReadMask  = 0;
	StencilWriteMask = 0xFFFFFFFF;

	BackFaceStencilFunc = Always;
    	BackFaceStencilPass = Replace;
};

technique10 Default
{
	pass P0
	{
		SetVertexShader(CompileShader(vs_4_0, vShader()));
		SetGeometryShader(NULL);
		SetPixelShader(CompileShader(ps_4_0, pShader()));
		SetDepthStencilState(NoDepthStencilEdge, 1);
	}
}

//=============================================================================