//Complex terrain depth domain shader - calculates output and depth positions and performs displacement

Texture2D displacementMapTexture : register(t0);
SamplerState sampler0 : register(s0);

cbuffer MatrixBuffer : register(b0)
{
	matrix worldMatrix;
	matrix viewMatrix;
	matrix projectionMatrix;
};

struct ConstantOutputType
{
	float edges[4] : SV_TessFactor;
	float inside[2] : SV_InsideTessFactor;
};

struct InputType
{
	float4 position : POSITION;
	float2 tex : TEXCOORD0;
};

struct OutputType
{
	float4 position : SV_POSITION;
	float2 tex : TEXCOORD0;
	float4 depthPosition : TEXCOORD1;
};

float SampleDisplacementMap(float2 texCoords)
{
	//Sample the colour at the texCoords of the displacement map texture, return its scaled value
	float4 textureColour = displacementMapTexture.SampleLevel(sampler0, texCoords, 0);
	return (textureColour - 0.5f) * 150.0f;
}

//Plane uses quads, set domain to be quad
[domain("quad")]
OutputType main(ConstantOutputType input, float2 uvCoord : SV_DomainLocation, const OutputPatch<InputType, 4> patch)
{
	float3 vertexPosition;
	OutputType output;

	//Calculate the vertex position
	float3 v1 = lerp(patch[0].position, patch[1].position, uvCoord.y);
	float3 v2 = lerp(patch[3].position, patch[2].position, uvCoord.y);
	vertexPosition = lerp(v1, v2, uvCoord.x);

	//Calculate the texture coordinate
	float2 t1 = lerp(patch[0].tex, patch[1].tex, uvCoord.y);
	float2 t2 = lerp(patch[3].tex, patch[2].tex, uvCoord.y);
	output.tex = lerp(t1, t2, uvCoord.x);

	//Displace the vertex by sampling the map at the calculated texture coordinate
	vertexPosition.y += SampleDisplacementMap(output.tex);

	//Calculate the position of the new vertex against the world, view, and projection matrices.
	output.position = mul(float4(vertexPosition, 1.0f), worldMatrix);
	output.position = mul(output.position, viewMatrix);
	output.position = mul(output.position, projectionMatrix);

	//Store the position value for depth value calculations.
	output.depthPosition = output.position;

	return output;
}

