// This file contains a simple vertex and pixel shader used to render a terrain-type mesh that
// blends two textures together based on the alpha value of the vertex colour.

// This is a constant buffer that will be set by the engine for each rendering pass.
// It is required that you provide this cbuffer with all your shaders.
cbuffer MatrixBuffer : register(b0) {	// The global MatrixBuffer cbuffer always uses register b0. Any custom cbuffers will use register b1..b15 (per shader) in order.
	float4x4 View;
	float4x4 Projection;
	float4x4 ViewProj;					// Precomputed on a per-frame basis
};

// Textures / samplers.
// If you have more than one texture on a mesh they are provided as an array to the shader like this.
Texture2D Map[2];
// Likewise you can have an array of up to 8 sampler states here as well, but we only need one for
// our purposes so we declare a single one (which will correspond to sampler state 0 for the object / limb).
sampler MapSampler;


// A special StructuredBuffer bound to register t24 is used to identify per-instance indexable transform matrices.
// This buffer is created, maintained and updated automatically by the Ziggurat engine and will take things such 
// as culling, exclusion and instance ordering into account.
struct sInstanceTransform {
	float4x4 World;
	float4x4 WorldViewProjection;
};

StructuredBuffer<sInstanceTransform> Transform : register(t24);


// Vertex input structure.
// It is vital that this one corresponds directly to the vertex layout of the object you are rendering using 
// this shader.
// Also note the SV_INSTANCEID semantic; this will contain the current instance ID being rendered and is 
// used to index into the Transform buffer declared above. This allows us to use separate world matrces for
// individual instances.
// The instance id field is NOT part of your vertex layout, but rather is a system value that is added to the 
// vertex data by the input assembler stage if you specify any vertex shader input using the SV_INSTANCEID 
// semantic.
struct vs_in {
	/* These correspond directly to the vertex layout the objects / limbs using this shader use */
	float4		pos			: POSITION;
	float4		colour		: COLOR;
	float2		texcoord	: TEXCOORD;

	/* This is a system value added by the input assembler stage on request; it should NOT be included in your vertex layout */
	uint		iId			: SV_INSTANCEID;
};

// Output from the vertex shader / input to the pixel shader
struct vs_out {
	float4		pos			: SV_POSITION;
	float4		colour		: COLOR;
	float2		texcoord	: TEXCOORD;
};



// Actual vertex shader - the function name here is the one you should provide to DX11 LOAD VERTEX SHADER
// along with the filename of this file.
vs_out VS(vs_in IN) {
	vs_out OUT;

	// Apply the instance's world view projection transform to the output position
	OUT.pos = mul(IN.pos, Transform[IN.iId].WorldViewProjection);
	// Just copy the rest of the input data to make it available to the pixel shader
	OUT.colour		= IN.colour;
	OUT.texcoord	= IN.texcoord;

	return OUT;
}


// Actual pixel shader - the function name here is the one you should provide to DX11 LOAD PIXEL SHADER
// along with the filename of this file.
float4 PS(vs_out IN) : SV_TARGET {
	// Sample both textures
	float4 diffuse[2];
	diffuse[0] = Map[0].Sample(MapSampler, IN.texcoord);
	diffuse[1] = Map[1].Sample(MapSampler, IN.texcoord);

	// Blend the textures together based on the alpha value of the vertex colour at this fragment
	return float4(saturate(1.4 * (diffuse[0].xyz - (diffuse[1].xyz * IN.colour.a * 0.8))), 1.0);
}
