//#define INSTANCED

// transformations
float4x4 ViewProj;
float4x4 AlphaLightMatrix;
float4x4 InvViewProj;

float3 CamPos;

float2 TexScale;

#ifndef INSTANCED
float4x4 World;
float4 LightTransform;
#endif

struct dcLightData{
	float4 Data[5];

	float4x4 World;
	float4 LightTransform;
};

struct VS_OUTPUT{
    float4 Pos				: POSITION;
#ifdef PROJECTED
	float4 Tex				: TEXCOORD0;
#else
	float2 Tex				: TEXCOORD0;
#endif
	float3 ViewDir			: TEXCOORD1;

#ifdef INSTANCED
	float4 Instance[5]		: TEXCOORD2;
#endif
};

struct VS_INPUT{
    float3 Pos				: POSITION;

#ifdef INSTANCED
	dcLightData	LightData	: TEXCOORD0;
#endif
};

float3 GetVirtualPos(float2 ScreenPos){
	float Depth = 0.5f;

	float4 Pos;
	Pos.xy = ScreenPos;
	Pos.z = Depth;
	Pos.w = 1;
	
	Pos = mul(Pos, InvViewProj);
	return Pos.xyz / Pos.w;
}

VS_OUTPUT main(const VS_INPUT Input){
#ifdef INSTANCED
	float4x4 World = Input.LightData.World;
	float4 LightTransform = Input.LightData.LightTransform;
#endif

#ifdef PROJECTED
	float3 Pos = Input.Pos * LightTransform.xyz;
	Pos.z += LightTransform.w;
	
#ifdef SPOTLIGHT
	Pos.xy *= Pos.z;
#endif

	Pos = mul(float4(Pos, 1), World);
	
	VS_OUTPUT Out;
    Out.Pos = mul(float4(Pos, 1), ViewProj);
#else
	VS_OUTPUT Out;
    Out.Pos = float4(Input.Pos, 1);
	
#endif
	Out.Tex = mul(Out.Pos, AlphaLightMatrix);
	
#ifdef PROJECTED
	float3 VirtualPos = Pos;
#else
	float3 VirtualPos = GetVirtualPos(Out.Pos.xy);
#endif
    Out.ViewDir = VirtualPos - CamPos;
    Out.Tex *= float4(TexScale, 1, 1);
   
    
#ifdef INSTANCED
	Out.Instance = Input.LightData.Data;
#endif


	return Out;
}