

void instancing_vp(uniform float3x4   worldMatrix3x4Array[80], float4 position : POSITION,
						float3 normal : NORMAL,
						float2 uv : TEXCOORD0,
						float index : TEXCOORD1,
						uniform float4x4 viewProjectionMatrix,
						uniform float4 lightPos,
						uniform float4 ambient,
						uniform float4 lightDiffuseColour,
						out float4 oPosition : POSITION,
						out float2 oUv : TEXCOORD0,
						out float4 Color : COLOR )
{
	// transform by indexed matrix
	float4 transformedPos = float4(mul(worldMatrix3x4Array[index], position).xyz, 1.0);
	
	// view / projection
	oPosition = mul(viewProjectionMatrix, transformedPos);
	oUv = uv;

	float3 norm = mul((float3x3)worldMatrix3x4Array[index], normal);
	
	float3 lightDir = 	normalize(
		lightPos.xyz -  (transformedPos.xyz * lightPos.w));

	Color = ambient + saturate(dot(lightDir, norm)) * lightDiffuseColour;
	
	
}

/*
  Instancing shadow-caster pass
*/
void instancingCaster_vp(
	float4 position : POSITION,
	float3 normal   : NORMAL,
	float index     : TEXCOORD1,

	out float4 oPosition : POSITION,
	out float4 colour    : COLOR,
	// Support up to 80 bones of float3x4
	uniform float3x4   worldMatrix3x4Array[80],
	uniform float4x4 viewProjectionMatrix,
	uniform float4   ambient)
{
	// transform by indexed matrix
	float4 transformedPos = float4(mul(worldMatrix3x4Array[index], position).xyz, 1.0);

	// view / projection
	oPosition = mul(viewProjectionMatrix, transformedPos);
	
	colour = ambient;
	
}
void crowd_vp(
	float4 position : POSITION,
	float3 normal   : NORMAL,
	float2 uv       : TEXCOORD0,
	float4  blendIdx : BLENDINDICES,
	float4	blendWgt : BLENDWEIGHT,
	float   index : TEXCOORD1,

	out float4 oPosition : POSITION,
	out float2 oUv       : TEXCOORD0,
	out float4 colour           : COLOR,
	// Support up to 20 bones of float3x4
	// vs_2_0 only supports 256 params so more than this is not feasible
	uniform float4x4 viewProjectionMatrix,
	uniform float numBones,
	uniform float3x4   worldMatrix3x4Array[80],
	uniform float4 lightDiffuseColour,
	uniform float4 ambient,
	uniform float4 lightPos)
{
	// transform by indexed matrix
	float4 blendPos = float4(0,0,0,0);
	int i;
	for (i = 0; i < 4; ++i)
	{
		blendPos += float4(mul(worldMatrix3x4Array[index*numBones+blendIdx[i]], position).xyz, 1.0) * blendWgt[i];
	}
	// view / projection
	oPosition = mul(viewProjectionMatrix, blendPos);
	oUv = uv;
	float3 norm = float3(0,0,0);
	for (i = 0; i < 4; ++i)
	{
		norm += mul((float3x3)worldMatrix3x4Array[index*numBones+blendIdx[i]], normal)* blendWgt[i];
	}
	float3 lightDir = 	normalize(
		lightPos.xyz -  (blendPos.xyz * lightPos.w));

	colour = ambient + saturate(dot(lightDir, norm)) * lightDiffuseColour;

	
}

/*
  Single-weight-per-vertex hardware skinning, shadow-caster pass
*/
void crowdCaster_vp(
	float4 position : POSITION,
	float3 normal   : NORMAL,
	float  blendIdx : BLENDINDICES,
	float index     : TEXCOORD1,

	out float4 oPosition : POSITION,
	out float4 colour    : COLOR,
	// Support up to 24 bones of float3x4
	// vs_1_1 only supports 96 params so more than this is not feasible
	uniform float3x4   worldMatrix3x4Array[80],
	uniform float4x4 viewProjectionMatrix,
	uniform float numBones,
	uniform float4   ambient)
{
	// transform by indexed matrix
	float4 blendPos = float4(mul(worldMatrix3x4Array[index*numBones+blendIdx], position).xyz, 1.0);

	// view / projection
	oPosition = mul(viewProjectionMatrix, blendPos);
	
	colour = ambient;
	
}	
