Texture2D gTexture;
Texture2D gDepth;

float gThreshold = 0.000005f;

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

/// Create Depth Stencil State
DepthStencilState DepthEnabled
{
	DepthEnable = TRUE;
	DepthWriteMask = 1;
};

/// Create Rasterizer State 
RasterizerState BackfaceCulling
{
	CullMode = BACK;
};

struct VS_INPUT_STRUCT
{
    float3 Pos : POSITION;
	float2 TexCoord : TEXCOORD0;

};
struct PS_INPUT_STRUCT
{
    float4 Pos : SV_POSITION;
	float2 TexCoord : TEXCOORD1;
};

PS_INPUT_STRUCT VS(VS_INPUT_STRUCT input)
{
	PS_INPUT_STRUCT output = (PS_INPUT_STRUCT)0;
	// Set the Position
	output.Pos = float4(input.Pos, 1.0f);
	// Set the Text coord
	output.TexCoord = input.TexCoord;
	return output;
}

float4 PS(PS_INPUT_STRUCT input):SV_TARGET
{
	float width, height;
	gDepth.GetDimensions(width, height);
	float dx = 1.0f / width;
	float dy = 1.0f / height;

	float sum;
	for (int x = -1; x<= 1; ++x)
	{
		for (int y = -1; y<= 1; ++y)
		{
			float2 sampleTexCoord = input.TexCoord + float2(x * dx, y * dy);
			float sample = gDepth.Sample(samLinear, sampleTexCoord).r;
			sum += sample;
		}
	}

	sum /= 9.0f;

	float3 outline_rgb = float3(1, 1, 1);	
	float depthSample = gDepth.Sample(samLinear, input.TexCoord).r;
	if(abs(depthSample - sum) > gThreshold){
		outline_rgb = float3(0, 0, 0);
	}

	float4 diffuseColor = gTexture.Sample(samLinear, input.TexCoord);

	float3 result;
	result = diffuseColor.rgb * outline_rgb;
	return float4(result, 1.0f);
}

technique11 EdgeDetection
{
    pass P0
    {
		SetDepthStencilState(DepthEnabled, 0);
		SetRasterizerState(BackfaceCulling);
        SetVertexShader( CompileShader( vs_4_0, VS() ) );
        SetGeometryShader( NULL );
        SetPixelShader( CompileShader( ps_4_0, PS() ) );
    }
}