We just reached 30,000 articles on this wiki! 🥳
If you appreciate the work done within the wiki, please consider supporting The Cutting Room Floor on Patreon. Thanks for all your support!

Ghostbusters: Sanctum of Slime/Embedded Source Code

From The Cutting Room Floor
Jump to navigation Jump to search

This is a sub-page of Ghostbusters: Sanctum of Slime.

The following source code was found embedded inside the main Sanctum of Slime executable, from 0x4CD0B0 to 0x4F6365, in the PC (Steam) version of the game. This source code is not in the PS3 or Xbox 360 versions.

Hmmm...
To do:
Verify that it exists in non-Steam versions.
// Translate composite pixel options
//////////////////////////////////////
// MATRIX MULTIPLICATION
//////////////////////////////////////
float3 Transform(float3x3 mat, float3 v)
{
#if defined(_XENON)
	[isolate]
	{
		return mul(mat, v);
	}
#elif defined(_GCM)
	return mul(v, mat);
#else
	return mul(mat, v);
#endif
}

float4 Transform(float4x4 mat, float4 v)
{
#if defined(_XENON)
	[isolate]
	{
		return mul(mat, v);
	}
#elif defined(_GCM)
	return mul(v, mat);
#else
	return mul(mat, v);
#endif

}

float2 Transform(float2x2 mat, float2 v)
{
#if defined(_XENON)
	[isolate]
	{
		return mul(mat, v);
	}
#elif defined(_GCM)
	return mul(v, mat);
#else
	return mul(mat, v);
#endif

}

//this conversion will not deal with renormalizations because is a bad way to handle bad data passing to the shader.
//the main problem is that cg-compiler isn't as smart as hlsl-compiler dealing with already normalized vectors
float3x3 GetWorldToTangentMatrix(float3x3 worldmtx,float3 tangent, float3 normal)
{
	float3x3 worldToTangent = 0;
	worldToTangent[0] = normalize(Transform(worldmtx, tangent));
	worldToTangent[2] = normalize(Transform(worldmtx, normal));
	worldToTangent[1] = normalize(cross(worldToTangent[0], worldToTangent[2]));    

	return worldToTangent;
}

float4 TransformPlanarReflection(float4 inPos)
{
	float4x4	matTexScale = 0;

#if !defined(_GCM)
	matTexScale._m00 = 0.5f;
	matTexScale._m11 =  -.5f;
	matTexScale._m22 = 0.0f;
	matTexScale._m03 = 0.5f; 
	matTexScale._m13 = 0.5f;
	matTexScale._m23 = 1.0f; 
	matTexScale._m33 = 1.0f;
#else
	matTexScale._m00 = 0.5f;
	matTexScale._m11 = -0.5f;
	matTexScale._m22 = 0.0f;
	matTexScale._m30 = 0.5f; 
	matTexScale._m31 = 0.5f;
	matTexScale._m32 = 1.0f; 
	matTexScale._m33 = 1.0f;
#endif

	return Transform(matTexScale,inPos);
}

 
#define _COMPOSITE_CGFX

// In the case low, med or high shadows are used, we are using shadows!
#if defined (_SHADOW_LOW) || defined (_SHADOW_MED) || defined(_SHADOW_HI)
	#define __USE_SHADOWMAP
#endif

#ifndef _POINTSPRITE

#ifdef _PIXELOPTION0
	#define _COMPOSITE_LIGHTED
#endif

#ifdef _PIXELOPTION1
	#define _COMPOSITE_2LAYERS
#endif
	
#ifdef _PIXELOPTION2
	#define _COMPOSITE_L0_ADD
#endif
	
#ifdef _PIXELOPTION3
	#define _COMPOSITE_L0_MULTIPLY
#endif



// For comodity we define _COMPOSITE_2LAYERS if there is a layer1 operation
#if defined(_COMPOSITE_L1_ADD) || defined(_COMPOSITE_L1_MULTIPLY) || defined(_COMPOSITE_L1_MULTIPLY2X) || defined(_COMPOSITE_L1_REPLACE) || defined(_UV1_USESCHANNEL0) || defined(_UV1_USESCHANNEL1)
	#define _COMPOSITE_2LAYERS
#endif

//////////////////////////////////////
// SKINNING
//////////////////////////////////////

#if defined(_VERTEX_SHADER) && defined(_USE_SKINMATRIX)
uniform float4x4	g_skinMatrix[_MAXBONES];		///< 128 Registers for skin bones

struct SKINVERTEX
{
	float4 P;
	float3 N;
	float3 T;
};

SKINVERTEX SkinVertex(float3 p, float3 n, float3 t, float4 indices, float4 weights)
{
	SKINVERTEX Out = (SKINVERTEX) 0;
	for(int i = 0; i < 4; i++)
	{
		Out.P.xyz += Transform(g_skinMatrix[indices.x], float4(p,1)).xyz * weights.x;
		Out.N += (float3)(Transform((float3x3) g_skinMatrix[indices.x], n) * weights.x);

		#if !defined(SH_VERSION_SH1)
		Out.T += (float3)(Transform((float3x3) g_skinMatrix[indices.x], t) * weights.x);
		#endif

		indices.xyzw = indices.yzwx;
		weights.xyzw = weights.yzwx;
	}

	Out.P.w = 1;
	Out.N = (float3)normalize(Out.N);
	
	#if !defined(SH_VERSION_SH1)
	Out.T = (float3)normalize(Out.T);
	#endif

	return Out;
}

#endif

//////////////////////////////////////
// END SKINNING
//////////////////////////////////////


float GetRimFading(float3 CamPos,float3 FragmentWorldPos,float3 Normal,float InvThreshold)
{
	float3 nCminP = normalize(CamPos.xyz-FragmentWorldPos.xyz);
	float NdotCmP = dot(Normal,nCminP);
	return saturate(NdotCmP*InvThreshold);
}

void ComputeFog(inout float4 PixelColor,float3 FogColor,float DistancePixelToCamera,float MinDistanceToFog,float MaxMinusMinDistanceToFog)
{
#if defined(_PIXEL_FOG)
	float CamMinusFogMin = (DistancePixelToCamera-MinDistanceToFog);
	float FogFactor  = 1-saturate(CamMinusFogMin/MaxMinusMinDistanceToFog);
	#if !defined(_ADDITIVE_PIXEL_FOG)
		PixelColor.rgb = lerp(FogColor, PixelColor.rgb, FogFactor);
	#elif defined(_ADDITIVE_PIXEL_FOG)
		PixelColor.rgb*=FogFactor;
		clip(MaxMinusMinDistanceToFog-CamMinusFogMin);
	#endif
#endif
}

//////////////////////////////////////
// UV GENERATION
//////////////////////////////////////
#ifdef _VERTEX_SHADER

#if defined(_UV0_AUTO_SPHEREVIEW) || defined(_UV1_AUTO_SPHEREVIEW)
	float3x3 g_matView;
#endif

float3 GetUVCoordinate3L0(float3 position, float3 normal, float3 viewer)
{
	#ifdef _UV0_AUTO_POSITION
		return position;
	#elif defined(_UV0_AUTO_REFLECTION)
		return (2.f * dot(viewer,normal) * normal - viewer) * .5f + .5f;
	#elif defined(_UV0_AUTO_NORMAL)
		return normal;
	#elif defined(_UV0_AUTO_SPHERE)
		return normal * .5f + .5f;
	#elif defined(_UV0_AUTO_SPHEREVIEW)
		float3 normalViewSpace = Transform(g_matView, normal);
		return float3(normalViewSpace.x, -normalViewSpace.y, 1.0f) * .5f + .5f;
	#else
		return normal;
	#endif	
}

float3 GetUVCoordinate3L1(float3 position, float3 normal, float3 viewer)
{
	#ifdef _UV1_AUTO_POSITION
		return position;
	#elif defined(_UV1_AUTO_REFLECTION)
		return (2.f * dot(viewer,normal) * normal - viewer) * .5f + .5f;
	#elif defined(_UV1_AUTO_NORMAL)
		return normal;
	#elif defined(_UV1_AUTO_SPHERE)
		return normal * .5f + .5f;
	#elif defined(_UV1_AUTO_SPHEREVIEW)
		float3 normalViewSpace = Transform(g_matView, normal);
		return float3(normalViewSpace.x, -normalViewSpace.y, 1.0f) * .5f + .5f;
	#else
		return normal;
	#endif	
}

#endif
//////////////////////////////////////
// END UV GENERATION
//////////////////////////////////////


//////////////////////////////////////
// VERTEX SHADER INPUT
//////////////////////////////////////
#ifdef _VERTEX_SHADER

struct Composite_InputVS
{
	float3 pos		: POSITION;			///< Vertex position
	
#ifdef _USE_SKINMATRIX
	float4 weight	: BLENDWEIGHT;		///< Weight vector used for skinning ( how much each bone affects the vertex )
	float4 indices	: BLENDINDICES;		///< Index vector used for skinning ( the index of each bone )
#endif

#ifdef _HAS_NORMAL
	float3 normal	: NORMAL;			///< Vertex Normal
#endif

#ifdef _HAS_TANGENT3
	float3 tangent	: TANGENT;			///< Vertex tangent, for use to map to tangent space normal maps
#endif

#ifdef _HAS_TANGENT
	float4 tangent	: TANGENT;			///< Vertex tangent, for use to map to tangent space normal maps
#endif

#ifdef _HAS_COLOR
	float4 color    : COLOR0;			///< Diffuse color of the vertex
#endif
	
#ifdef _HAS_UV0
	float2 uv0		: TEXCOORD0;		///< UV Coordinates for layer 0
#endif
#ifdef _HAS_UV1
	float2 uv1		: TEXCOORD1;		///< UV Coordinates for layer 1
#endif
#ifdef _HAS_UV2
	float2 uv2		: TEXCOORD2;
#endif
};

#endif
//////////////////////////////////////
// END VERTEX SHADER INPUT
//////////////////////////////////////



//////////////////////////////////////
// LIGHTING
//////////////////////////////////////

//////////////////////////////////////
// LIGHTING INFO
#ifdef _COMPOSITE_LIGHTED

float4		g_lightDirection0;
float4		g_lightPosition0;
float4		g_lightColor0;
float4		g_lightSpecular0;

#if defined(_LIGHT1_POINT) || defined(_LIGHT1_DIRECTIONAL)
	float4		g_lightDirection1;
	float4		g_lightPosition1;
	float4		g_lightColor1;
	float4		g_lightSpecular1;
#endif

#endif //_COMPOSITE_LIGHTED

uniform float4 g_cameraPos, g_compositePixelOptions;
uniform float4 g_RimFading;

/// Tongas upload variables
float4		g_ambient;
float4		g_ambientColor;
float4		g_diffuseColor;
float4		g_emissiveColor;
float4		g_specularColor;

#define g_bloomFactor g_emissiveColor.a

///////////////////////////////////////
// FX INFO
uniform float4		g_zBlurOptions;

//////////////////////////////////////
// LIGHTING FUNCTIONS
/*
CalculateSpecularLighting
Calculates the specular lighting for an interest point
*/
float3 CalculateSpecularLighting(
			in float3 lightDirection,			///< Direction of the light MUST BE NORMALIZED!
			in float3 lightSpecularColor,		///< Specular color
			in float3 normalVector,				///< Normal vector of the intereset point
			in float3 viewVector				///< View vector of the interest point
			)
{
	float3 Half = normalize( lightDirection + viewVector);
	return lightSpecularColor.xyz * pow(saturate( dot( Half, normalVector) ), g_specularColor.a);
}

/*
CalculatePointLightAttenuation
Calculates the attenuation of a point light on a surface point
*/
float CalculatePointLightAttenuation(
	 in float3	iLightDirection,			///< Direction NOT NORMALIZED, from the point to the light position	 
	 float		iLightInverseRange			///< Inverse range (1/r) of the point light	 
	 )
{
	float3 attenuatedLightDirection = iLightDirection * iLightInverseRange;
	return saturate ( 1.0f - dot (attenuatedLightDirection, attenuatedLightDirection));
}
	 


void LightSpot_VS(float3 iDir, float invRange, out float3 oDir, out float oFactor)
{
	oDir.xyz = iDir;
	//oFactor = length(iDir);
	//oFactor = ( 1.0f - (oFactor  / Range) );	
	oFactor = saturate ( 1.0f - dot (iDir * invRange, iDir * invRange));					
}

void LightSpot_PS(float3 iDir, float3 normal, float3 view, float Factor, float3 iD, float4 iS, inout float3 oD, inout float3 oS, sampler2D spotMap, float4 spotTex)
{
	float3 fvLightDir = iDir;
	float fNDotL = dot(normal, fvLightDir);		

	float3 lightColor = tex2Dproj(spotMap, spotTex).rgb;
	
	oD += lightColor * iD * saturate(fNDotL) * Factor;
	
	#ifndef _MATERIAL_NOSPECULAR
		float3 Half = normalize(fvLightDir+view);
		oS += Factor * lightColor * iS.xyz * pow(saturate(dot(Half,normal)), iS.a);
	#endif
}

/*
GetPointLightDirectionInTangentSpace
Retrieves the direction of a point light in tangent space
*/
float3 GetPointLightDirectionInTangentSpace( 
		float3 lightPosition,					///< Light position in world space
		float3 vertexPosition,					///< Vertex position in world space
		float3x3 worldToTangentTransform		///< World to Tangent space transformation
		)
{
	float3 lightDir = lightPosition - vertexPosition;
	lightDir = mul(worldToTangentTransform, lightDir);
	return lightDir;
}

/*
GetPointLightDirectionInWorldSpace
Calculates the point light direction in world space
*/
float3 GetPointLightDirectionInWorldSpace(
		float3 lightPosition,					///< Light position in world space
		float3 vertexPosition					//< Vertex position in world space
		)
{
	return lightPosition - vertexPosition;
}

void OutLightDirSpotPPL(float3 iDir, float invRange, float3x3 TBN, out float3 oDir, out float oFactor)
{
	oDir.xyz = iDir;
	//oFactor = length(iDir.xyz);
	//oFactor = ( 1.0f - (oFactor  * invRange) );	
	oDir.xyz = mul(TBN, oDir.xyz);	
	oFactor = saturate ( 1.0f - dot (iDir * invRange, iDir * invRange));
}

void OutLightDirSpotPVL(float3 iDir, float invRange, out float3 oDir, out float oFactor)
{
	oDir.xyz = iDir;
	//oFactor = length(iDir.xyz);
	//oFactor = ( 1.0f - (oFactor  / Range) );						
	oFactor = saturate ( 1.0f - dot (iDir * invRange, iDir * invRange));
}

void LightDirectional_PPL_PS(float3 iDir, float3 n, float3 v, float3 iD, float3 iS, inout float3 oD, inout float3 oS)
{
	float3 fvLightDir = normalize(iDir);
	float fNDotL = dot(n, fvLightDir);		
	oD += iD * saturate(fNDotL);

	#ifndef _MATERIAL_NOSPECULAR
		float3 Half = normalize(fvLightDir + v);
		oS.xyz += iS.xyz * pow(saturate(dot(Half, n)), g_specularColor.a);
	#endif
}

/*
AddPointLightContributionTangentSpace
Adds the contribution diffuse and specular lighting of a point light to a point of a surface
*/
void AddPointLightContributionTangentSpace(
	in float3		iLightDirectionTangentSpace,		///< Direction to the light from the 3d point in tangent space
	in float3		iLightPositionWorldSpace,			///< Position of the point light in world space
	in float		iLightInverseRange,					///< Inverse range of the point light (1/r)
	in float3		iLightDiffuseColor,					///< Diffuse color of the light
	in float3		iLightSpecularColor,				///< Specular color of the light
	in float3		iPointNormalTangentSpace,			///< Normal on the 3d point in tangent space
	in float3		iPointViewTangentSpace,				///< View vector on the 3d point in tangent space
	in float3		iPointPositionWorldSpace,			///< Position of the 3d point in world space
	inout float3	ioAcumulatedDiffuseLight,			///< Acumulated diffuse light
	inout float3	ioAcumulatedSpecularLight			///< Acumulated specular light
	)
{
	// Calculate attenuation of the spot light
	float lightAttenuation = CalculatePointLightAttenuation(iLightPositionWorldSpace - iPointPositionWorldSpace, iLightInverseRange );
	
	// Calculate diffuse lighting contribution
	float3 lightDirectionNormalized = normalize( iLightDirectionTangentSpace );
	float fNDotL = dot(iPointNormalTangentSpace, lightDirectionNormalized);		
	ioAcumulatedDiffuseLight += iLightDiffuseColor * saturate(fNDotL) * lightAttenuation;
	
	// Calculate specular lighting contribution
	#ifndef _MATERIAL_NOSPECULAR
		ioAcumulatedSpecularLight += lightAttenuation * 
			CalculateSpecularLighting(lightDirectionNormalized, iLightSpecularColor, iPointNormalTangentSpace, iPointViewTangentSpace );
	#endif
}

void LightPoint_PPL_PS(float3 iDir, float3 n, float3 v, float Factor, float3 iD, float4 iS, inout float3 oD, inout float3 oS)
{
	float3 fvLightDir = normalize(iDir);
	float fNDotL = dot(n, fvLightDir);		
	oD += iD * saturate(fNDotL) * Factor;
	
	#ifndef _MATERIAL_NOSPECULAR
		float3 Half = normalize(fvLightDir+v);
		oS.rgb += Factor * iS.xyz * pow(saturate( dot(Half,n) ), g_specularColor.a);
	#endif
}

void LightSpot_PPL_PS(float3 iDir, float3 normal, float3 view, float Factor, float3 iD, float4 iS, inout float3 oD, inout float3 oS, sampler2D spotMap, float4 spotTex)
{
	float3 fvLightDir = normalize(iDir);		
	float fNDotL = dot(normal, fvLightDir);		

	float3 lightColor = tex2Dproj(spotMap, spotTex).rgb;			
	oD += saturate( lightColor * iD * saturate(fNDotL) * Factor );
	
	#ifndef _MATERIAL_NOSPECULAR
		float3 Half = normalize(fvLightDir+view);
		oS += saturate( lightColor * Factor * iS.xyz * pow(saturate(dot(Half,normal)), g_specularColor.a) );
	#endif
}
	
void LightDirectional_PVL_PS(float3 iDir, float3 normal, float3 view, float3 iD, float  transColor,	float3 iS, inout float3 oD, inout float3 oS)
{
	
	float fNDotL = dot(normal, iDir);		
	oD += iD.rgb * saturate(fNDotL);
	
	#ifdef _TRANSLUCENCY
			float fNDotL2 = dot(-normal, iDir);		
			oD += iD.rgb * saturate(fNDotL2) * transColor;
	#endif
	
	#ifndef _MATERIAL_NOSPECULAR
		float3 Half = normalize(iDir + view);	
		oS += iS.xyz * pow( saturate(dot(Half,normal)), g_specularColor.a);
	#endif
}

/*
AddPointLightContributionWorldSpace
Adds the contribution diffuse and specular lighting of a point light to a point of a surface
*/
void AddPointLightContributionWorldSpace(
	in float3		iLightPosition,				///< Light position in world space
	in float		iLightInverseRange,			///< Inverse range of the point light (1/r)
	in float3		iLightDiffuseColor,			///< Diffuse color of the light
	in float3		iLightSpecularColor,		///< Specular color of the light
	in float3		iPointNormal,				///< Normal of the 3d point in world space
	in float3		iPointView,					///< View vector of the 3d point in world space
	in float3		iPointPosition,				///< Poisition of the 3d point in worls space
	inout float3	ioAcumulatedDiffuseLight,	///< Acumulated diffuse lighting
	inout float3	ioAcumulatedSpecularLight	///< Acumulated specular lighting
	)
{
	// Determiate the light direction, used for attenuation and light contribution
	float3 lightDirection = iLightPosition - iPointPosition;

	// Calculate attenuation of the spot light
	float lightAttenuation = CalculatePointLightAttenuation(lightDirection, iLightInverseRange);
	
	// Calculate diffuse lighting contribution
	lightDirection = normalize( lightDirection );
	float fNDotL = dot(iPointNormal, lightDirection);		
	ioAcumulatedDiffuseLight += iLightDiffuseColor * saturate(fNDotL) * lightAttenuation;
	
	// Calculate specular lighting contribution
	#ifndef _MATERIAL_NOSPECULAR
		ioAcumulatedSpecularLight += lightAttenuation * 
			CalculateSpecularLighting(lightDirection, iLightSpecularColor, iPointNormal, iPointView);
	#endif
}

void LightSpot_PVL_PS(float3 iDir, float3 normal, float3 view, float Factor, float3 iD, float4 iS, inout float3 oD, inout float3 oS, sampler2D spotMap, float4 spotTex)
{
	float3 fvLightDir = iDir;
	float fNDotL = dot(normal, fvLightDir);		

	float3 lightColor = tex2Dproj(spotMap, spotTex).rgb;			
	oD += lightColor * iD * saturate(fNDotL) * Factor;		
	
	#ifndef _MATERIAL_NOSPECULAR
		float3 Half = normalize(fvLightDir+view);
		oS += lightColor * Factor * iS.xyz * pow(saturate(dot(Half,normal)), g_specularColor.a);
	#endif
}


//////////////////////////////////////
// END LIGHTING
//////////////////////////////////////


//////////////////////////////////////
// VERTEX SHADER OUTPUT
//////////////////////////////////////
struct Composite_OutputVS
{
	float4 hpos			: POSITION;		///< Clip space transformed vertex position
	float4 color		: COLOR0;		///< Vertex color

	float3 uv0			: TEXCOORD0;	///< UV Coordinates used by layer 1
	float3 uv1			: TEXCOORD1;	///< UV Coordinates used by layer 2

	float4 vpos			: TEXCOORD2;	///< Position of the vertex in world space, and shadowprojection distance

	float4 lightfactors	: COLOR1;		///< Light factos used for point lights
	float3  normal		: TEXCOORD3;	///< Vertex normal
	float3  view			: TEXCOORD4;	///< View direction to the vertex

	float4 lightDir0	: TEXCOORD5;	///< Direction of light 0

#ifdef _LIGHT0_SPOT
	float4 spotProjection1	: TEXCOORD6;	///< spot projection
#endif

#if defined(__USE_SHADOWMAP) && (defined(_LIGHT0_DIRECTIONAL) || defined(_LIGHT0_SPOT))
	float4 shadowProjection : TEXCOORD7;	///< Shadow map projection
#endif

#ifdef _PS3_VSCLIPPLANE0
	float oClip0      	: CLP0;
#endif
};
//////////////////////////////////////
// END VERTEX SHADER OUTPUT
//////////////////////////////////////


//////////////////////////////////////
// SHADOWMAPPING
//////////////////////////////////////
#ifndef _COMPOSITE_LIGHTED
	#undef __USE_SHADOWMAP
#endif

#ifdef __USE_SHADOWMAP

uniform float4x4	g_matTextureProjection;
uniform float4		g_shadowmapOptions;
uniform float4		g_texelSize89;

#define 	g_ShadowmapFactor	(1-g_shadowmapOptions.x)	/// default 0.0
#define 	g_ShadowmapZBias	(g_shadowmapOptions.y)		/// default -0.001

uniform sampler2D	g_shadowMap			: register(s9);
uniform samplerCUBE	g_shadowCubeMap		: register(s9);

////////////////////////////////////
// DIRECTIONAL
float SampleShadowTest(float4 ShadowTexC)
{	
	#if defined(_XENON) || defined(_SHADOWMAP_FLOAT)	//Xenon & ATI
		return tex2D(g_shadowMap, ShadowTexC.xy).r >= ShadowTexC.z;		
	#else	//nVidia
		return tex2Dproj(g_shadowMap, ShadowTexC).r;
	#endif	
}

float GetShadowDirectional(float4 TexCoords)
{
	float4 ShadowTexC = TexCoords;
	ShadowTexC.xy = 0.5 * TexCoords.xy + float2( 0.5, 0.5 );
	ShadowTexC.y = 1.f - ShadowTexC.y;

#ifdef _PS3
	ShadowTexC.z = ShadowTexC.z * .5f + .5f;
#endif

#ifdef _XENON
	ShadowTexC.xyz = ShadowTexC.xyz / ShadowTexC.w;
	
	// [BP] On xbox360 we are getting projected distances that are higher than 1
	// as they are not being cut by the far plane of the light frustum
	// still we need to study more this effect, even check if it can be done on vertex
	// shader stage to save gpu process
	ShadowTexC.z = min(1,ShadowTexC.z); 	// Check that z the minimum value to 1
#endif
	
#ifdef _DEBUG_SHADOWMAPS	
	//Dark regions out of shadow projection
	if(ShadowTexC.x < 0 ||
		ShadowTexC.y < 0 ||
		ShadowTexC.x > 1 ||
		ShadowTexC.y > 1)
		return 0;
#endif
	
	ShadowTexC.z += g_ShadowmapZBias;
	ShadowTexC.w = 1;
			
	#if defined(SH_VERSION_SH2) || defined(_SHADOW_LOW)
		return saturate(SampleShadowTest(ShadowTexC) + g_ShadowmapFactor);
	#else

		float4 tX = float4(g_texelSize89.z, 0, 0, 0) * 2;
		float4 tY = float4(0, g_texelSize89.w, 0, 0) * 2;
		float accum = 0;
 
		#if defined(_SHADOW_MED)
			accum += SampleShadowTest(ShadowTexC + tX * -.5 + tY * -.5);
			accum += SampleShadowTest(ShadowTexC + tX *  .5 + tY * -.5);
			accum += SampleShadowTest(ShadowTexC + tX * -.5 + tY *  .5);
			accum += SampleShadowTest(ShadowTexC + tX *  .5 + tY *  .5);
			return saturate((accum/4.f) + g_ShadowmapFactor);
		#elif defined(_SHADOW_HI)
			accum += SampleShadowTest(ShadowTexC + tX * -1 + tY * -1);
			accum += SampleShadowTest(ShadowTexC + tX *  0 + tY * -1);
			accum += SampleShadowTest(ShadowTexC + tX *  1 + tY * -1);
			accum += SampleShadowTest(ShadowTexC + tX * -1 + tY *  0);
			accum += SampleShadowTest(ShadowTexC + tX *  0 + tY *  0);
			accum += SampleShadowTest(ShadowTexC + tX *  1 + tY *  0);
			accum += SampleShadowTest(ShadowTexC + tX * -1 + tY *  1);
			accum += SampleShadowTest(ShadowTexC + tX *  0 + tY *  1);
			accum += SampleShadowTest(ShadowTexC + tX *  1 + tY *  1);	
			return saturate((accum/9.f) + g_ShadowmapFactor);
		#else
			return 1;
		#endif
	#endif	
}

/////////////////////////////////
// SPOT
//[VC]: why this is just a copy paste from spotdirectional???
float GetShadowSpotSample(float4 ShadowTexC)
{
	float shadow;

#if defined(_XENON) || defined(_SHADOWMAP_FLOAT)	//Xenon & ATI

	float a = tex2D(g_shadowMap, ShadowTexC.xy).r > ShadowTexC.z;
	float b = tex2D(g_shadowMap, ShadowTexC.xy + float2(g_texelSize89.z, 0)).r > ShadowTexC.z;
	float c = tex2D(g_shadowMap, ShadowTexC.xy + float2(0, g_texelSize89.w)).r > ShadowTexC.z;
	float d = tex2D(g_shadowMap, ShadowTexC.xy + float2(g_texelSize89.z, g_texelSize89.w)).r > ShadowTexC.z;

#if defined(SH_VERSION_SH2)
	return a;
#endif
	
    // transform to texel space
    float2 texelpos = (1.f/g_texelSize89.zw) * ShadowTexC;
    
    // Determine the lerp amounts           
    float2 lerps = frac( texelpos );

    // lerp between the shadow values to calculate our light amount
    shadow = lerp( lerp( a, b, lerps.x ),
                   lerp( c, d, lerps.x ),
                   lerps.y );		
	return shadow;

#else	//nVidia

	shadow = tex2Dproj(g_shadowMap, ShadowTexC).r;

#endif
	
	return shadow;
}

float GetShadowSpot(float4 TexCoords)
{
	float4 ShadowTexC = TexCoords;
	ShadowTexC.xy = 0.5 * TexCoords.xy / TexCoords.w + float2( 0.5, 0.5 );
	ShadowTexC.y = 1.0f - ShadowTexC.y;

	//not needed for spot lights
#ifdef _PS3
	//ShadowTexC.z = ShadowTexC.z * .5f + .5f;
#endif

#ifdef _DEBUG_SHADOWMAPS	
	//Dark regions out of shadow projection
	if(ShadowTexC.x < 0 ||
		ShadowTexC.y < 0 ||
		ShadowTexC.x > 1 ||
		ShadowTexC.y > 1)
		return 0;
#endif
		
	ShadowTexC.z += g_ShadowmapZBias;
	ShadowTexC.z /= ShadowTexC.w;

	ShadowTexC.w = 1;
			
#if defined(SH_VERSION_SH2) || defined(_SHADOW_LOW)

	return saturate(GetShadowSpotSample(ShadowTexC) + g_ShadowmapFactor);
	
#endif

	float4 tX = float4(g_texelSize89.z, 0, 0, 0) * 1;
	float4 tY = float4(0, g_texelSize89.w, 0, 0) * 1;

	float accum = 0;

#if defined(_SHADOW_MED)
	accum += GetShadowSpotSample(ShadowTexC + tX * -.5 + tY * -.5);
	accum += GetShadowSpotSample(ShadowTexC + tX *  .5 + tY * -.5);
	accum += GetShadowSpotSample(ShadowTexC + tX * -.5 + tY *  .5);
	accum += GetShadowSpotSample(ShadowTexC + tX *  .5 + tY *  .5);	
	return saturate((accum/4.f) + g_ShadowmapFactor);
#endif
	
#if defined(_SHADOW_HI)
	accum += GetShadowSpotSample(ShadowTexC + tX * -1 + tY * -1);
	accum += GetShadowSpotSample(ShadowTexC + tX *  0 + tY * -1);
	accum += GetShadowSpotSample(ShadowTexC + tX *  1 + tY * -1);
	accum += GetShadowSpotSample(ShadowTexC + tX * -1 + tY *  0);
	accum += GetShadowSpotSample(ShadowTexC + tX *  0 + tY *  0);
	accum += GetShadowSpotSample(ShadowTexC + tX *  1 + tY *  0);
	accum += GetShadowSpotSample(ShadowTexC + tX * -1 + tY *  1);
	accum += GetShadowSpotSample(ShadowTexC + tX *  0 + tY *  1);
	accum += GetShadowSpotSample(ShadowTexC + tX *  1 + tY *  1);
	return saturate((accum/9.f) + g_ShadowmapFactor);
#endif

	return 1;
}


/////////////////////////////////
// POINT

float GetShadowPointSample(float3 Pos)
{
	float shadow = 1;

#ifdef _LIGHT0_POINT
	shadow = texCUBE(g_shadowCubeMap, Pos.xyz-g_lightPosition0.xyz).r > (length(Pos.xyz-g_lightPosition0.xyz) * g_lightPosition0.w) + g_ShadowmapZBias;
#endif

	return shadow;
}

float GetShadowPoint(float3 Pos)
{
	return saturate(GetShadowPointSample(Pos) + g_ShadowmapFactor);
}

#endif
//////////////////////////////////////
// END SHADOWMAPPING
//////////////////////////////////////

	
//////////////////////////////////////
//VERTEX SHADER
//////////////////////////////////////

//////////////////////////////////////
// VERTEX SHADER CONSTANTS
#ifdef _VERTEX_SHADER
	float4x4 g_matWorld, g_matWorldView, g_matWorldViewProjection;

	float4 g_textureTransform0;
	float4 g_textureTransform1;

	float4 g_textureTransformExt0;
	float4 g_textureTransformExt1;

	#ifdef _LIGHT0_SPOT
		float4x4 g_matTexture2;
	#endif

#ifdef _PS3_VSCLIPPLANE0
	uniform float4	g_ps3ClipPlane0;
#endif
	
#endif

//////////////////////////////////////
// VERTEX SHADER
#ifdef _VERTEX_SHADER

void main_VS( Composite_InputVS inVertex, out Composite_OutputVS outResult )
{
	outResult = (Composite_OutputVS) 0;
	
	// Init Color
	#ifdef _HAS_COLOR
		outResult.color = inVertex.color;	
	#else
		outResult.color	= float4(1,1,1,1);
	#endif
	
	// Init normal
	#if defined(_COMPOSITE_LIGHTED) && defined(_HAS_NORMAL)
		float3 normal = normalize(inVertex.normal);
	#else
		float3 normal = float3(0,0,1);
	#endif
		
		
	float4 position;

	#ifdef _USE_SKINMATRIX	
		SKINVERTEX v = SkinVertex(float4(inVertex.pos, 1), normal,float3(1,0,0), inVertex.indices, inVertex.weight);

		position	= v.P;
		normal	= v.N;
	#else
		position	= float4(inVertex.pos, 1);
	#endif //_USE_SKINMATRIX

	

	/// Transform the position to clip space
	outResult.hpos	= Transform(g_matWorldViewProjection, position);
	outResult.vpos	= Transform(g_matWorld, position);
	
#ifdef _PS3_VSCLIPPLANE0
	outResult.oClip0	= dot(outResult.vpos, g_ps3ClipPlane0);
#endif
	
#ifdef _COMPOSITE_LIGHTED
	outResult.normal	= Transform((float3x3) g_matWorld, normal);			///< Normal in world space
#endif

#ifdef _HAS_UV0	
	outResult.uv0 = float3(inVertex.uv0, 1);
	outResult.uv1 = float3(inVertex.uv0, 1);
#endif

	/// Create parameters for autogenerated coordinates
	#if defined(_UV0_AUTO_POSITION) || defined(_UV0_AUTO_NORMAL) || defined(_UV0_AUTO_REFLECTION) || defined(_UV0_AUTO_SPHERE) || defined(_UV0_AUTO_SPHEREVIEW) || defined(_UV1_AUTO_POSITION) || defined(_UV1_AUTO_NORMAL) || defined(_UV1_AUTO_REFLECTION) || defined(_UV1_AUTO_SPHERE) || defined(_UV1_AUTO_SPHEREVIEW)
		float3 P		= Transform(g_matWorldView, position);							///< Vertex position in view space
		float3  N		= Transform((float3x3) g_matWorld, normal); 		///< Normal in world space
		float3 V		= normalize(g_cameraPos-P);									///< Viewer position
	#endif
	
	/// Calculate the uv transformations for the diffuse layer
	#if defined(_UV0_AUTO_POSITION) || defined(_UV0_AUTO_NORMAL) || defined(_UV0_AUTO_REFLECTION) || defined(_UV0_AUTO_SPHERE) || defined(_UV0_AUTO_SPHEREVIEW)
		outResult.uv0 = GetUVCoordinate3L0(P, N, V);		
	#endif
	
	/// Calculate the uv transformation for the enviromental layer
	#if defined(_UV1_AUTO_POSITION) || defined(_UV1_AUTO_NORMAL) || defined(_UV1_AUTO_REFLECTION) || defined(_UV1_AUTO_SPHERE) || defined(_UV1_AUTO_SPHEREVIEW)
		outResult.uv1 = GetUVCoordinate3L1(P, N, V);
	#elif defined(_HAS_UV1)
		#if !defined(_UV1_USESCHANNEL0) && defined(_COMPOSITE_2LAYERS)
			outResult.uv1.xy = inVertex.uv1;
		#endif
	#endif
	
	/// Finally transform the uv coordinates by the texture matrix transformations
	outResult.uv0.xy = outResult.uv0.xy * g_textureTransform0.xy + outResult.uv0.yx * g_textureTransformExt0.yx + g_textureTransform0.zw;
	outResult.uv1.xy = outResult.uv1.xy * g_textureTransform1.xy + outResult.uv1.yx * g_textureTransformExt1.yx + g_textureTransform1.zw;
	
	
#ifdef _COMPOSITE_LIGHTED
	
	/// The outResult.view vector is only used to calculate specular lighting, so if there is no specular dont calculate the view
	#ifndef _MATERIAL_NOSPECULAR
		float3 pWorld	= Transform(g_matWorld, position);					///< Vertex position in world space
		outResult.view		= normalize(g_cameraPos - pWorld);				///< View direction
	#endif

	
	#ifdef _LIGHT0_DIRECTIONAL		
		#ifdef __USE_SHADOWMAP
			outResult.shadowProjection = Transform(g_matTextureProjection, float4(position.xyz,1));
		#endif
	#endif

	#ifdef _LIGHT0_POINT
		outResult.lightfactors.x = length(g_lightPosition0.xyz - outResult.vpos);
		outResult.lightfactors.x = saturate(1.0f - (outResult.lightfactors.x  * g_lightPosition0.w));
	#endif
	
	#ifdef _LIGHT1_POINT
		outResult.lightfactors.y = length(g_lightPosition1.xyz - outResult.vpos);
		outResult.lightfactors.y = saturate(1.0f - (outResult.lightfactors.y  * g_lightPosition1.w));
	#endif

	#ifdef _LIGHT0_SPOT
		LightSpot_VS(g_lightPosition0.xyz - outResult.vpos.xyz, g_lightPosition0.w, outResult.lightDir0.xyz, outResult.lightDir0.w);

		outResult.spotProjection1 = Transform(g_matTexture2, position);
		

		#ifdef __USE_SHADOWMAP
			outResult.shadowProjection = Transform(g_matTextureProjection, float4(position.xyz,1));
		#endif
	#endif

#endif //_COMPOSITE_LIGHTED
}

#endif

//////////////////////////////////////
// END VERTEX SHADER
//////////////////////////////////////


//////////////////////////////////////
//PIXEL SHADERS
//////////////////////////////////////
#ifdef _PIXEL_SHADER

//////////////////////////////////////
// SAMPLERS
uniform sampler2D g_layer0	: register(s0);			///< First texture layer
uniform sampler2D g_layer1	: register(s1);			///< Second texture layer
uniform sampler2D g_spot1Map: register(s8);			///< Spot light proyection texture

#if defined(_MRT3) && !defined(_MRT2)
	#define _MRT2
#endif
#if defined(_MRT2) && !defined(_MRT1)
	#define _MRT1
#endif

struct Composite_OutputPS
{
#if !defined(_MRT)
	float4 color : COLOR0;
#else
	#if defined(_MRT_RT_0_1)
		float4 color : COLOR1;
	#elif defined(_MRT_RT_0_2)
		float4 color : COLOR2;
	#elif defined(_MRT_RT_0_3)
		float4 color : COLOR3;
	#else
		float4 color : COLOR0;
	#endif
	
	#if defined(_MRT1)
	#if defined(_MRT_RT_1_0)
		float4 color1 : COLOR0;
	#elif defined(_MRT_RT_1_2)
		float4 color1 : COLOR2;
	#elif defined(_MRT_RT_1_3)
		float4 color1 : COLOR3;
	#else
		float4 color1 : COLOR1;
	#endif
	#endif
	
	#if defined(_MRT2)
	#if defined(_MRT_RT_2_0)
		float4 color2 : COLOR0;
	#elif defined(_MRT_RT_2_1)
		float4 color2 : COLOR1;
	#elif defined(_MRT_RT_2_3)
		float4 color2 : COLOR3;
	#else
		float4 color2 : COLOR2;
	#endif
	#endif
	
	#if defined(_MRT3)
	#if defined(_MRT_RT_3_0)
		float4 color3 : COLOR0;
	#elif defined(_MRT_RT_3_1)
		float4 color3 : COLOR1;
	#elif defined(_MRT_RT_3_2)
		float4 color3 : COLOR2;
	#else
		float4 color3 : COLOR3;
	#endif
	#endif
#endif
};


//////////////////////////////////////
// FOG

#ifdef _VERTICAL_FOG
	float4		g_verticalFogColor;
	float4		g_verticalFogValues;
#endif

#ifdef _PIXEL_FOG
	float4		g_pixelFogColor;
	float4		g_pixelFogOptions;
#endif

#if defined(_ALPHA_TEST)
float4		g_PixelAlphaTesting;
#endif

#if defined(_MRT)
#define _MRT_DEFAULT_COLOR		float4(0,0,0,0)
#define _MRT_BLACK_COLOR		float4(0,0,0,1)

#ifndef _PIXEL_FOG
    float4		g_pixelFogOptions;
#endif

uniform float4		g_multilayerTextureOptions;

float4 getBloomOutput(float2 uvCoords,uniform sampler2D tex)
{
	float mulFactor = 0;

	if(g_emissiveColor.a>0)
		mulFactor = 1;

	#if !defined(_POINTSPRITE)
	float4  ret = float4(0,0,0,1);
	ret.g = g_emissiveColor.a;
	#else
	float4  ret = float4(0,1,0,1);
	#endif

	// Determinate the alpha color from the diffuse stage
	if (g_multilayerTextureOptions.x > 1)
	{
		/// Texture with additive blending
		float4 color = tex2D( tex, uvCoords );
		ret.a*= (color.r + color.g + color.b)*0.3333 * color.a;
	}	
	else if (g_multilayerTextureOptions.x > 0)
	{
		// Texture with alpha
		ret.a*= tex2D( tex, uvCoords ).a;
	}
	
	ret*=mulFactor;

	return ret;
}

#if !defined(_POINTSPRITE)
float4 getFocusBloomOutput(float opacity,float3 pos,float2 uvCoords,uniform sampler2D tex)
{
	float mulFactor = 0;

	if(g_emissiveColor.a>0)
		mulFactor = 1;
	if(opacity>=1)
		mulFactor = 1;

	float4  ret = float4(0,0,0,opacity);
	ret.g = g_emissiveColor.a*opacity;

	// Determinate the alpha color from the diffuse stage
	if (g_multilayerTextureOptions.x > 1)
	{
		/// Texture with additive blending
		float4 color = tex2D( tex, uvCoords );
		ret.a*= (color.r + color.g + color.b)*0.3333 * color.a;
	}	
	else if (g_multilayerTextureOptions.x > 0)
	{
		// Texture with alpha
		ret.a*= tex2D( tex, uvCoords ).a;
	}

	ret*=mulFactor;
    return ret;
}
#endif

#if defined(_MULTILAYER_CGFX)

//default output
float4 pso_MRT_default_output(MultilayerPPLSpot_OutputVS IN,float4 mainColor)
{
	return _MRT_DEFAULT_COLOR;
}

float4 pso_MRT_black_output(MultilayerPPLSpot_OutputVS IN,float4 mainColor)
{
	return _MRT_BLACK_COLOR;
}

float4 pso_MRT_blackBoolAlpha_output(MultilayerPPLSpot_OutputVS IN,float4 mainColor)
{
	return float4(_MRT_BLACK_COLOR.rgb,(mainColor.a>=1.0)?1.0:0.0);
}

float4 pso_MRT_default_output(MultilayerPPL_OutputVS IN,float4 mainColor)
{
	return _MRT_DEFAULT_COLOR;
}

float4 pso_MRT_black_output(MultilayerPPL_OutputVS IN,float4 mainColor)
{
	return _MRT_BLACK_COLOR;
}

float4 pso_MRT_blackBoolAlpha_output(MultilayerPPL_OutputVS IN,float4 mainColor)
{
	return float4(_MRT_BLACK_COLOR.rgb,(mainColor.a>=1.0)?1.0:0.0);
}

float4 pso_MRT_default_output(MultilayerPVLSpot_OuputVS IN,float4 mainColor)
{
	return _MRT_DEFAULT_COLOR;
}

float4 pso_MRT_black_output(MultilayerPVLSpot_OuputVS IN,float4 mainColor)
{
	return _MRT_BLACK_COLOR;
}

float4 pso_MRT_blackBoolAlpha_output(MultilayerPVLSpot_OuputVS IN,float4 mainColor)
{
	return float4(_MRT_BLACK_COLOR.rgb,(mainColor.a>=1.0)?1.0:0.0);
}

float4 pso_MRT_default_output(MultilayerPVL_OuputVS IN,float4 mainColor)
{
	return _MRT_DEFAULT_COLOR;
}

float4 pso_MRT_black_output(MultilayerPVL_OuputVS IN,float4 mainColor)
{
	return _MRT_BLACK_COLOR;
}

float4 pso_MRT_blackBoolAlpha_output(MultilayerPVL_OuputVS IN,float4 mainColor)
{
	return float4(_MRT_BLACK_COLOR.rgb,(mainColor.a>=1.0)?1.0:0.0);
}

float4 pso_MRT_focusBloom_output(MultilayerPPLSpot_OutputVS IN,float4 mainColor)
{
	#if !defined(_POINTSPRITE)
    return getFocusBloomOutput(mainColor.a,IN.vpos.xyz,IN.uv0.xy,g_diffuseMap);
	#else
	return getBloomOutput(IN.uv.xy,g_diffuseMap);
	#endif
}

float4 pso_MRT_focusBloom_output(MultilayerPPL_OutputVS IN,float4 mainColor)
{
    return getFocusBloomOutput(mainColor.a,IN.vpos.xyz,IN.uvcoords.xy,g_diffuseMap);
}

float4 pso_MRT_focusBloom_output(MultilayerPVLSpot_OuputVS IN,float4 mainColor)
{
    return getFocusBloomOutput(mainColor.a,IN.vpos.xyz,IN.uv0.xy,g_diffuseMap);
}

float4 pso_MRT_focusBloom_output(MultilayerPVL_OuputVS IN,float4 mainColor)
{
    return getFocusBloomOutput(mainColor.a,IN.vpos.xyz,IN.uv0.xy,g_diffuseMap);
}

#endif

//default output
#if defined(_COMPOSITE_CGFX)
#ifndef _POINTSPRITE
float4 pso_MRT_default_output(Composite_OutputVS IN,float4 mainColor)
{
	return _MRT_DEFAULT_COLOR;
}

float4 pso_MRT_black_output(Composite_OutputVS IN,float4 mainColor)
{
	return _MRT_BLACK_COLOR;
}

float4 pso_MRT_blackBoolAlpha_output(Composite_OutputVS IN,float4 mainColor)
{
	return float4(_MRT_BLACK_COLOR.rgb,(mainColor.a>=1.0)?1.0:0.0);
}

float4 pso_MRT_focusBloom_output(Composite_OutputVS IN,float4 mainColor)
{
    return getFocusBloomOutput(mainColor.a,IN.vpos.xyz,IN.uv0.xy,g_layer0);
}

#else
float4 pso_MRT_default_output(CompositeSprite_InputPS IN,float4 mainColor)
{
	return _MRT_DEFAULT_COLOR;
}

float4 pso_MRT_black_output(CompositeSprite_InputPS IN,float4 mainColor)
{
	return _MRT_BLACK_COLOR;
}

float4 pso_MRT_blackBoolAlpha_output(CompositeSprite_InputPS IN,float4 mainColor)
{
	return float4(_MRT_BLACK_COLOR.rgb,(mainColor.a>=1.0)?1.0:0.0);
}

float4 pso_MRT_focusBloom_output(CompositeSprite_InputPS IN,float4 mainColor)
{
	return getBloomOutput(IN.uv.xy,g_layer0);
}
#endif
#endif

#if defined(_MRT3) && !defined(_MRT2)
#define _MRT2
#endif

#if defined(_MRT2) && !defined(_MRT1)
#define _MRT1
#endif

#if defined(_MRT1) && !defined(_MRT1_OUTMETHOD)
	#define _MRT1_OUTMETHOD		pso_MRT_default_output
#endif

#if defined(_MRT2) && !defined(_MRT2_OUTMETHOD)
	#define _MRT2_OUTMETHOD		pso_MRT_default_output
#endif

#if defined(_MRT3) && !defined(_MRT3_OUTMETHOD)
	#define _MRT3_OUTMETHOD		pso_MRT_default_output
#endif
#endif

void Composite_MainPS(Composite_OutputVS IN,out float4 OUT);

void main_PS( Composite_OutputVS inData, out Composite_OutputPS outResult	)
{
	float4 color;
	Composite_MainPS(inData,color);

	outResult.color = color;

    #if defined(_MRT1)
		outResult.color1 = _MRT1_OUTMETHOD(inData, outResult.color);
	#endif

	#if defined(_MRT2)
		outResult.color2 = _MRT2_OUTMETHOD(inData, outResult.color);
	#endif

	#if defined(_MRT3)
		outResult.color3 = _MRT3_OUTMETHOD(inData,outResult.color);
	#endif
	
	#if defined(_ALPHA_TEST)
		clip(outResult.color.a-g_PixelAlphaTesting.x);
	#endif	
}


void Composite_MainPS( Composite_OutputVS inData, out float4 outResult)
{
	outResult = inData.color;
	outResult.a = 1;
	
#ifdef _COMPOSITE_LIGHTED
	float3 normal = normalize(inData.normal);
	
	/// Calculate lighting
	float	fNDotL		= 0;
	float3	myLight		= 0;
	float3	fvLightDir	= 0;

	float3	Half		= 0;
	float3	mySpecular	= 0;
	float3	view		= normalize(inData.view);
	
	/// Calculate directional lighting		
	#ifdef _LIGHT0_DIRECTIONAL
		fNDotL		= dot(normal, -g_lightDirection0);		
		myLight		+= g_lightColor0.rgb * saturate(max(0, fNDotL));
		
		#ifndef _MATERIAL_NOSPECULAR
			Half = normalize(-g_lightDirection0 + view);	
			mySpecular	+= g_lightSpecular0 * pow(max(0, dot(Half,normal)), g_specularColor.a);
		#endif
		

		#ifdef __USE_SHADOWMAP
			float shadow = GetShadowDirectional(inData.shadowProjection);
			myLight *= shadow;
		
			#ifndef _MATERIAL_NOSPECULAR
				mySpecular *= shadow;
			#endif
		#endif
		
	#endif
	
	#ifdef _LIGHT1_DIRECTIONAL
		fNDotL		= dot(normal, -g_lightDirection1);		
		myLight		+= g_lightColor1.rgb * saturate(max(0, fNDotL));
		
		#ifndef _MATERIAL_NOSPECULAR
			Half = normalize(-g_lightDirection1 + view);	
			mySpecular	+= g_lightSpecular1.rgb * pow(max(0, dot(Half,normal)) ,g_specularColor.a);
		#endif
	#endif
	
	/// Calculate point lights
	#ifdef _LIGHT0_POINT
		fvLightDir = normalize(g_lightPosition0.xyz - inData.vpos);		
		fNDotL = dot(normal, fvLightDir);		
		myLight += g_lightColor0.rgb * saturate(max(0, fNDotL)) * inData.lightfactors.x;				
		
		#ifndef _MATERIAL_NOSPECULAR
			Half = normalize(fvLightDir+view);
			mySpecular	+= inData.lightfactors.x * g_lightSpecular0 * pow(max(0, dot(Half,normal)), g_specularColor.a);
		#endif
		

		#ifdef __USE_SHADOWMAP
			float shadow = GetShadowPointSample(inData.vpos);
			myLight *= shadow;
		
			#ifndef _MATERIAL_NOSPECULAR
				mySpecular *= shadow;
			#endif
		#endif
		
	#endif
	
	#ifdef _LIGHT1_POINT
		fvLightDir	= normalize(g_lightPosition1.xyz - inData.vpos);		
		fNDotL		= dot(normal, fvLightDir);		
		myLight	+= g_lightColor1.rgb * saturate(max(0, fNDotL)) * inData.lightfactors.y;				

		#ifndef _MATERIAL_NOSPECULAR
			Half = normalize(fvLightDir+view);
			mySpecular += inData.lightfactors.y * g_lightSpecular1 * pow(max(0, dot(Half,normal)), g_specularColor.a);
		#endif
	#endif
	
	#ifdef _LIGHT0_SPOT
		fvLightDir = g_lightPosition0.xyz - inData.vpos;
		if(dot(normalize(fvLightDir),-g_lightDirection0.xyz)>0)
			LightSpot_PS(normalize(inData.lightDir0.xyz), inData.normal, inData.view, inData.lightDir0.w, g_lightColor0.xyz, float4(g_lightSpecular0.xyz,g_specularColor.w), myLight, mySpecular, g_spot1Map, inData.spotProjection1);
		#ifdef __USE_SHADOWMAP
			float shadow = GetShadowSpot(inData.shadowProjection);
			myLight *= shadow;
		
			#ifndef _MATERIAL_NOSPECULAR
				mySpecular *= shadow;
			#endif
		#endif
		
	#endif	

	float3 ambient = 0;
	#ifndef _LIGHT0_SPOT
		ambient = g_ambient.rgb * g_ambientColor.rgb;
	#endif
	
	outResult.rgb *= myLight * g_diffuseColor.rgb + ambient;
	
#else
	// No Lighting
	outResult.rgb *= g_diffuseColor.rgb;	
#endif

	
	{
		float4 Layer0 = g_diffuseColor;

#ifdef _MAP_DIFFUSE
		if (g_compositePixelOptions[2] == 0)
			Layer0 = tex2D( g_layer0, inData.uv0.xy);
#endif

		#ifdef _COMPOSITE_L0_ADD
			outResult += Layer0;
		#endif
		#ifdef _COMPOSITE_L0_MULTIPLY
			outResult *= Layer0;
		#endif
		#ifdef _COMPOSITE_L0_MULTIPLY2X
			outResult *= 2.f * Layer0;
		#endif
		#ifdef _COMPOSITE_L0_REPLACE
			outResult = Layer0;
		#endif
		
	}
	
#ifdef _COMPOSITE_2LAYERS	
	{
		float4 Layer1 = g_diffuseColor;
	
		if (g_compositePixelOptions[3] == 0)
			Layer1 = tex2D( g_layer1, inData.uv1.xy);
		
		#ifdef _COMPOSITE_L1_ADD
			outResult.rgb += Layer1.rgb;
		#endif
		#ifdef _COMPOSITE_L1_MULTIPLY
			outResult.rgb *= Layer1.rgb;
		#endif
		#ifdef _COMPOSITE_L1_MULTIPLY2X
			outResult.rgb *= 2.0f * Layer1.rgb;
		#endif
		#ifdef _COMPOSITE_L1_REPLACE
			outResult.rgb = Layer1.rgb;
		#endif
	}
#endif

#ifdef _COMPOSITE_LIGHTED
	#ifndef _MATERIAL_NOSPECULAR
		outResult.rgb += mySpecular * g_specularColor.rgb;
	#endif
#endif

	
	float fogValue;
	#ifdef _VERTICAL_FOG
		fogValue = saturate( (inData.vpos.y - g_verticalFogValues.x) / g_verticalFogValues.z);
		outResult.rgb =	lerp(g_verticalFogColor.rgb, outResult.rgb, fogValue);
	#endif
	
	#ifdef _PIXEL_FOG
		ComputeFog(outResult,g_pixelFogColor.rgb,distance(g_cameraPos.xyz, inData.vpos.xyz),g_pixelFogOptions.x,g_pixelFogOptions.z);
	#endif
	
	/// Apply alpha from the material diffuse color
	float alphaValue = inData.color.a * g_diffuseColor.a;
	
	#ifdef _PIXELOPTION4
		float invAlphaValue = 1 - alphaValue;
		if (outResult.a < invAlphaValue)
		{			
			outResult.a = 0;
		}
		else if (outResult.a < invAlphaValue + 0.1)
		{	
			//outResult.rgb = 1;
			float factor = outResult.a -invAlphaValue;
			factor *= 10;
			outResult.a *=factor;
			//outResult.a -= invAlphaValue;
			//outResult.a /=  0.1;	
			//outResult.rgb  = outResult.a;
			//outResult.a = 1;		
		}
	#else
		outResult.a *= alphaValue;
	#endif

	outResult = saturate(outResult);

    #if defined(_RIM_FADING)
		outResult.a*=GetRimFading(g_cameraPos.xyz,inData.vpos.xyz,inData.normal,g_RimFading.y);
    #endif
}

#endif

#else //POINTSPRITES
//PointSprites code
struct CompositeSprite_InputVS
{
	float4 pos		: POSITION;
	float4 color    : COLOR0;	
	float2 size		: TEXCOORD0;
};

struct CompositeSprite_OutputVS
{
	float4 hpos			: POSITION;
	float4 color		: COLOR0;
	float  pointSize	: PSIZE;
};

struct CompositeSprite_InputPS
{	
	float4 color		: COLOR0;
#ifdef _XENON
	float2 t			: SPRITETEXCOORD;
#else
	float4 t			: TEXCOORD0;
#endif
};

#if defined(_MRT3) && !defined(_MRT2)
	#define _MRT2
#endif
#if defined(_MRT2) && !defined(_MRT1)
	#define _MRT1
#endif

struct Composite_OutputPS
{
#if !defined(_MRT)
	float4 color : COLOR0;
#else
	#if defined(_MRT_RT_0_1)
		float4 color : COLOR1;
	#elif defined(_MRT_RT_0_2)
		float4 color : COLOR2;
	#elif defined(_MRT_RT_0_3)
		float4 color : COLOR3;
	#else
		float4 color : COLOR0;
	#endif
	
	#if defined(_MRT1)
	#if defined(_MRT_RT_1_0)
		float4 color1 : COLOR0;
	#elif defined(_MRT_RT_1_2)
		float4 color1 : COLOR2;
	#elif defined(_MRT_RT_1_3)
		float4 color1 : COLOR3;
	#else
		float4 color1 : COLOR1;
	#endif
	#endif
	
	#if defined(_MRT2)
	#if defined(_MRT_RT_2_0)
		float4 color2 : COLOR0;
	#elif defined(_MRT_RT_2_1)
		float4 color2 : COLOR1;
	#elif defined(_MRT_RT_2_3)
		float4 color2 : COLOR3;
	#else
		float4 color2 : COLOR2;
	#endif
	#endif
	
	#if defined(_MRT3)
	#if defined(_MRT_RT_3_0)
		float4 color3 : COLOR0;
	#elif defined(_MRT_RT_3_1)
		float4 color3 : COLOR1;
	#elif defined(_MRT_RT_3_2)
		float4 color3 : COLOR2;
	#else
		float4 color3 : COLOR3;
	#endif
	#endif
#endif
};

sampler		g_layer0:register(s0);
sampler		g_layer1:register(s0);

float4		g_diffuseColor;
float4		g_ambientColor;
float4		g_emissiveColor;
float4		g_specularColor;

float4x4	g_matWorldViewProjection;
float4x4	g_matWorldView;
float4		g_cameraPos;
float4		g_screenSize;

#define g_bloomFactor g_emissiveColor.a

#if defined(_ALPHA_TEST)
float4		g_PixelAlphaTesting;
#endif

void main_VS( CompositeSprite_InputVS inVertex, out CompositeSprite_OutputVS outResult )
{
	outResult.color		= inVertex.color;

	/// Transform position from object to projection
	outResult.hpos		= Transform( g_matWorldViewProjection, inVertex.pos);
	
	float d = distance(inVertex.pos.xyz, g_cameraPos.xyz);
	outResult.pointSize	= inVertex.size.x / d;
	outResult.pointSize *= g_screenSize.x;
}

#if defined(_MRT)
#define _MRT_DEFAULT_COLOR		float4(0,0,0,0)
#define _MRT_BLACK_COLOR		float4(0,0,0,1)

#ifndef _PIXEL_FOG
    float4		g_pixelFogOptions;
#endif

uniform float4		g_multilayerTextureOptions;

float4 getBloomOutput(float2 uvCoords,uniform sampler2D tex)
{
	float mulFactor = 0;

	if(g_emissiveColor.a>0)
		mulFactor = 1;

	#if !defined(_POINTSPRITE)
	float4  ret = float4(0,0,0,1);
	ret.g = g_emissiveColor.a;
	#else
	float4  ret = float4(0,1,0,1);
	#endif

	// Determinate the alpha color from the diffuse stage
	if (g_multilayerTextureOptions.x > 1)
	{
		/// Texture with additive blending
		float4 color = tex2D( tex, uvCoords );
		ret.a*= (color.r + color.g + color.b)*0.3333 * color.a;
	}	
	else if (g_multilayerTextureOptions.x > 0)
	{
		// Texture with alpha
		ret.a*= tex2D( tex, uvCoords ).a;
	}
	
	ret*=mulFactor;

	return ret;
}

#if !defined(_POINTSPRITE)
float4 getFocusBloomOutput(float opacity,float3 pos,float2 uvCoords,uniform sampler2D tex)
{
	float mulFactor = 0;

	if(g_emissiveColor.a>0)
		mulFactor = 1;
	if(opacity>=1)
		mulFactor = 1;

	float4  ret = float4(0,0,0,opacity);
	ret.g = g_emissiveColor.a*opacity;

	// Determinate the alpha color from the diffuse stage
	if (g_multilayerTextureOptions.x > 1)
	{
		/// Texture with additive blending
		float4 color = tex2D( tex, uvCoords );
		ret.a*= (color.r + color.g + color.b)*0.3333 * color.a;
	}	
	else if (g_multilayerTextureOptions.x > 0)
	{
		// Texture with alpha
		ret.a*= tex2D( tex, uvCoords ).a;
	}

	ret*=mulFactor;
    return ret;
}
#endif

#if defined(_MULTILAYER_CGFX)

//default output
float4 pso_MRT_default_output(MultilayerPPLSpot_OutputVS IN,float4 mainColor)
{
	return _MRT_DEFAULT_COLOR;
}

float4 pso_MRT_black_output(MultilayerPPLSpot_OutputVS IN,float4 mainColor)
{
	return _MRT_BLACK_COLOR;
}

float4 pso_MRT_blackBoolAlpha_output(MultilayerPPLSpot_OutputVS IN,float4 mainColor)
{
	return float4(_MRT_BLACK_COLOR.rgb,(mainColor.a>=1.0)?1.0:0.0);
}

float4 pso_MRT_default_output(MultilayerPPL_OutputVS IN,float4 mainColor)
{
	return _MRT_DEFAULT_COLOR;
}

float4 pso_MRT_black_output(MultilayerPPL_OutputVS IN,float4 mainColor)
{
	return _MRT_BLACK_COLOR;
}

float4 pso_MRT_blackBoolAlpha_output(MultilayerPPL_OutputVS IN,float4 mainColor)
{
	return float4(_MRT_BLACK_COLOR.rgb,(mainColor.a>=1.0)?1.0:0.0);
}

float4 pso_MRT_default_output(MultilayerPVLSpot_OuputVS IN,float4 mainColor)
{
	return _MRT_DEFAULT_COLOR;
}

float4 pso_MRT_black_output(MultilayerPVLSpot_OuputVS IN,float4 mainColor)
{
	return _MRT_BLACK_COLOR;
}

float4 pso_MRT_blackBoolAlpha_output(MultilayerPVLSpot_OuputVS IN,float4 mainColor)
{
	return float4(_MRT_BLACK_COLOR.rgb,(mainColor.a>=1.0)?1.0:0.0);
}

float4 pso_MRT_default_output(MultilayerPVL_OuputVS IN,float4 mainColor)
{
	return _MRT_DEFAULT_COLOR;
}

float4 pso_MRT_black_output(MultilayerPVL_OuputVS IN,float4 mainColor)
{
	return _MRT_BLACK_COLOR;
}

float4 pso_MRT_blackBoolAlpha_output(MultilayerPVL_OuputVS IN,float4 mainColor)
{
	return float4(_MRT_BLACK_COLOR.rgb,(mainColor.a>=1.0)?1.0:0.0);
}

float4 pso_MRT_focusBloom_output(MultilayerPPLSpot_OutputVS IN,float4 mainColor)
{
	#if !defined(_POINTSPRITE)
    return getFocusBloomOutput(mainColor.a,IN.vpos.xyz,IN.uv0.xy,g_diffuseMap);
	#else
	return getBloomOutput(IN.uv.xy,g_diffuseMap);
	#endif
}

float4 pso_MRT_focusBloom_output(MultilayerPPL_OutputVS IN,float4 mainColor)
{
    return getFocusBloomOutput(mainColor.a,IN.vpos.xyz,IN.uvcoords.xy,g_diffuseMap);
}

float4 pso_MRT_focusBloom_output(MultilayerPVLSpot_OuputVS IN,float4 mainColor)
{
    return getFocusBloomOutput(mainColor.a,IN.vpos.xyz,IN.uv0.xy,g_diffuseMap);
}

float4 pso_MRT_focusBloom_output(MultilayerPVL_OuputVS IN,float4 mainColor)
{
    return getFocusBloomOutput(mainColor.a,IN.vpos.xyz,IN.uv0.xy,g_diffuseMap);
}

#endif

//default output
#if defined(_COMPOSITE_CGFX)
#ifndef _POINTSPRITE
float4 pso_MRT_default_output(Composite_OutputVS IN,float4 mainColor)
{
	return _MRT_DEFAULT_COLOR;
}

float4 pso_MRT_black_output(Composite_OutputVS IN,float4 mainColor)
{
	return _MRT_BLACK_COLOR;
}

float4 pso_MRT_blackBoolAlpha_output(Composite_OutputVS IN,float4 mainColor)
{
	return float4(_MRT_BLACK_COLOR.rgb,(mainColor.a>=1.0)?1.0:0.0);
}

float4 pso_MRT_focusBloom_output(Composite_OutputVS IN,float4 mainColor)
{
    return getFocusBloomOutput(mainColor.a,IN.vpos.xyz,IN.uv0.xy,g_layer0);
}

#else
float4 pso_MRT_default_output(CompositeSprite_InputPS IN,float4 mainColor)
{
	return _MRT_DEFAULT_COLOR;
}

float4 pso_MRT_black_output(CompositeSprite_InputPS IN,float4 mainColor)
{
	return _MRT_BLACK_COLOR;
}

float4 pso_MRT_blackBoolAlpha_output(CompositeSprite_InputPS IN,float4 mainColor)
{
	return float4(_MRT_BLACK_COLOR.rgb,(mainColor.a>=1.0)?1.0:0.0);
}

float4 pso_MRT_focusBloom_output(CompositeSprite_InputPS IN,float4 mainColor)
{
	return getBloomOutput(IN.uv.xy,g_layer0);
}
#endif
#endif

#if defined(_MRT3) && !defined(_MRT2)
#define _MRT2
#endif

#if defined(_MRT2) && !defined(_MRT1)
#define _MRT1
#endif

#if defined(_MRT1) && !defined(_MRT1_OUTMETHOD)
	#define _MRT1_OUTMETHOD		pso_MRT_default_output
#endif

#if defined(_MRT2) && !defined(_MRT2_OUTMETHOD)
	#define _MRT2_OUTMETHOD		pso_MRT_default_output
#endif

#if defined(_MRT3) && !defined(_MRT3_OUTMETHOD)
	#define _MRT3_OUTMETHOD		pso_MRT_default_output
#endif
#endif

void main_PS( CompositeSprite_InputPS inData, out Composite_OutputPS outResult )
{	
	outResult.color.rgb = inData.color.rgb * g_diffuseColor.rgb;
	outResult.color.a = inData.color.a * g_diffuseColor.a;
	
	float2 uv = inData.t;
	
	float4 texColor = tex2D( g_layer0, uv);
	
		#ifdef _PIXELOPTION2
			outResult.color.rgb += texColor.rgb;
		#endif
		#ifdef _PIXELOPTION3
			outResult.color *= texColor;
		#endif
		#ifdef _COMPOSITE_L0_MULTIPLY2X
			outResult.color *= 2 * texColor;
		#endif
		#ifdef _COMPOSITE_L0_REPLACE
			outResult.color = texColor;
		#endif
	
	/*
	/// Apply emissive material color
	/// Then saturate the color
	OUT.color.rgb += g_emissiveColor.rgb;
	OUT.color.rgb = saturate(OUT.color.rgb);
	
	#if defined (_VERTICAL_FOG ) || defined (_PIXEL_FOG)
		OUT.color.rgb =	lerp(IN.fog, OUT.color.rgb, IN.fog.a);
	#endif
	*/

	#if defined(_MRT1)
		outResult.color1 = _MRT1_OUTMETHOD(inData,OUT.color);
	#endif

	#if defined(_MRT2)
		outResult.color2 = _MRT2_OUTMETHOD(inData,OUT.color);
	#endif

	#if defined(_MRT3)
		outResult.color3 = _MRT3_OUTMETHOD(inData,OUT.color);
	#endif
	
	#if defined(_ALPHA_TEST)
		clip(g_PixelAlphaTesting.x - outResult.color.a);
	#endif	
}

#endif

// If the use os axis aligned box for a light has been defined, but not the type of light we asume that it corresponds to an ambient light
#define _MULTILAYER_CGFX
 
 
// In the case low, med or high shadows are used, we are using shadows!
#if defined (_SHADOW_LOW) || defined (_SHADOW_MED) || defined(_SHADOW_HI)
	#define __USE_SHADOWMAP
#endif

#ifdef _PIXELOPTION3 
	#define BLEND_DIFFUSE2_WITH_LIGHTMAPALPHA
#endif
  
//////////////////////////////////////
// VERTEX SHADER CONSTANTS
#ifdef _VERTEX_SHADER
	uniform float4x4	g_matWorld, g_matWorldView, g_matWorldViewProjection;

	float4 g_textureTransform0;
	float4 g_textureTransform1;

	float4 g_textureTransformExt0;
	float4 g_textureTransformExt1;

	#ifdef _LIGHT0_SPOT	
		float4x4 g_matTexture2;
	#endif

	#ifdef _LIGHT1_SPOT	
		float4x4 g_matTexture3;
	#endif

	#if defined(_UV0_AUTO_SPHEREVIEW) || defined(_UV1_AUTO_SPHEREVIEW)
		float3x3 g_matView;
	#endif

	#if defined(_USE_TAPER)
		uniform float4x4 g_matViewProjection;
	#endif

#elif defined(_MAP_EMISSIVE) || defined(_EMISSIVE_FLIPBOOK)
	float4 g_textureTransform5;
#endif

uniform float4		g_cameraPos;

#ifdef _PS3_VSCLIPPLANE0
	uniform float4	g_ps3ClipPlane0;
#endif

#ifdef _POINTSPRITE
	float4		g_screenSize;
#endif

////////////////////////////////////////
// MATERIAL INFO
uniform float4		g_diffuseColor;
uniform float4		g_ambientColor;
uniform float4		g_emissiveColor;
uniform float4		g_specularColor;
uniform float4		g_enviromentColor;

#define g_bloomFactor				g_emissiveColor.a

///////////////////////////////////////
// FX INFO
uniform float4		g_zBlurOptions;

//////////////////////////////////////
// LIGHTING
//////////////////////////////////////

//////////////////////////////////////
// LIGHTING INFO
float4		g_ambient;

#if defined(_LIGHT0_POINT) || defined(_LIGHT0_DIRECTIONAL) || defined(_LIGHT0_SPOT)
uniform float4		g_lightDirection0;
uniform float4		g_lightPosition0;
uniform float4		g_lightColor0;
uniform float4		g_lightSpecular0;
#endif

#if defined(_LIGHT1_POINT) || defined(_LIGHT1_DIRECTIONAL) || defined(_LIGHT1_SPOT)
uniform float4		g_lightDirection1;
uniform float4		g_lightPosition1;
uniform float4		g_lightColor1;
uniform float4		g_lightSpecular1;
#endif

#if defined(_LIGHT2_POINT) || defined(_LIGHT2_DIRECTIONAL)
uniform float4		g_lightDirection2;
uniform float4		g_lightPosition2;
uniform float4		g_lightColor2;
uniform float4		g_lightSpecular2;
#endif

#if defined(_LIGHT3_POINT) || defined(_LIGHT3_DIRECTIONAL)
uniform float4		g_lightDirection3;
uniform float4		g_lightPosition3;
uniform float4		g_lightColor3;
uniform float4		g_lightSpecular3;
#endif

#if defined(_RIM_FADING)
uniform float4		g_RimFading;
#endif

#if defined(_USE_TAPER)
uniform float4		g_TaperOrigin;
uniform float4		g_TaperDir;

//Returns tapered pos
float3 TaperVert(float3 worldPos)
{
	float3 taperOrigin = g_TaperOrigin.xyz;	
	float3 taperDir = g_TaperDir.xyz;
	float taperMaxDist = g_TaperOrigin.w;
	float taperFactor = g_TaperDir.w;

	float3 from = worldPos-taperOrigin;
	float proj = dot(from,taperDir);
	if (proj <= 0)
		return taperOrigin;
	float3 projVec = proj*taperDir;
	float3 delta = (from-projVec);
	float len = length(delta);
	
	float3 newDelta = delta - lerp(0,len,saturate(taperFactor*(taperMaxDist-proj)))*delta/len;
	float3 newPos = taperOrigin+projVec+newDelta;
	return newPos;
}
#endif

//////////////////////////////////////
// MATRIX MULTIPLICATION
//////////////////////////////////////
float3 Transform(float3x3 mat, float3 v)
{
#if defined(_XENON)
	[isolate]
	{
		return mul(mat, v);
	}
#elif defined(_GCM)
	return mul(v, mat);
#else
	return mul(mat, v);
#endif
}

float4 Transform(float4x4 mat, float4 v)
{
#if defined(_XENON)
	[isolate]
	{
		return mul(mat, v);
	}
#elif defined(_GCM)
	return mul(v, mat);
#else
	return mul(mat, v);
#endif

}

float2 Transform(float2x2 mat, float2 v)
{
#if defined(_XENON)
	[isolate]
	{
		return mul(mat, v);
	}
#elif defined(_GCM)
	return mul(v, mat);
#else
	return mul(mat, v);
#endif

}

//this conversion will not deal with renormalizations because is a bad way to handle bad data passing to the shader.
//the main problem is that cg-compiler isn't as smart as hlsl-compiler dealing with already normalized vectors
float3x3 GetWorldToTangentMatrix(float3x3 worldmtx,float3 tangent, float3 normal)
{
	float3x3 worldToTangent = 0;
	worldToTangent[0] = normalize(Transform(worldmtx, tangent));
	worldToTangent[2] = normalize(Transform(worldmtx, normal));
	worldToTangent[1] = normalize(cross(worldToTangent[0], worldToTangent[2]));    

	return worldToTangent;
}

float4 TransformPlanarReflection(float4 inPos)
{
	float4x4	matTexScale = 0;

#if !defined(_GCM)
	matTexScale._m00 = 0.5f;
	matTexScale._m11 =  -.5f;
	matTexScale._m22 = 0.0f;
	matTexScale._m03 = 0.5f; 
	matTexScale._m13 = 0.5f;
	matTexScale._m23 = 1.0f; 
	matTexScale._m33 = 1.0f;
#else
	matTexScale._m00 = 0.5f;
	matTexScale._m11 = -0.5f;
	matTexScale._m22 = 0.0f;
	matTexScale._m30 = 0.5f; 
	matTexScale._m31 = 0.5f;
	matTexScale._m32 = 1.0f; 
	matTexScale._m33 = 1.0f;
#endif

	return Transform(matTexScale,inPos);
}


//////////////////////////////////////
// SKINNING
//////////////////////////////////////

#if defined(_VERTEX_SHADER) && defined(_USE_SKINMATRIX)
uniform float4x4	g_skinMatrix[_MAXBONES];		///< 128 Registers for skin bones

struct SKINVERTEX
{
	float4 P;
	float3 N;
	float3 T;
};

SKINVERTEX SkinVertex(float3 p, float3 n, float3 t, float4 indices, float4 weights)
{
	SKINVERTEX Out = (SKINVERTEX) 0;
	for(int i = 0; i < 4; i++)
	{
		Out.P.xyz += Transform(g_skinMatrix[indices.x], float4(p,1)).xyz * weights.x;
		Out.N += (float3)(Transform((float3x3) g_skinMatrix[indices.x], n) * weights.x);

		#if !defined(SH_VERSION_SH1)
		Out.T += (float3)(Transform((float3x3) g_skinMatrix[indices.x], t) * weights.x);
		#endif

		indices.xyzw = indices.yzwx;
		weights.xyzw = weights.yzwx;
	}

	Out.P.w = 1;
	Out.N = (float3)normalize(Out.N);
	
	#if !defined(SH_VERSION_SH1)
	Out.T = (float3)normalize(Out.T);
	#endif

	return Out;
}

#endif

//////////////////////////////////////
// END SKINNING
//////////////////////////////////////

#ifdef _VERTEX_SHADER

float3 GetUVCoordinate3L0(float3 position, float3 normal, float3 viewer)
{
	#ifdef _UV0_AUTO_POSITION
		return position;
	#elif defined(_UV0_AUTO_REFLECTION)
		return (2.f * dot(viewer,normal) * normal - viewer) * .5f + .5f;
	#elif defined(_UV0_AUTO_NORMAL)
		return normal;
	#elif defined(_UV0_AUTO_SPHERE)
		return normal * .5f + .5f;
	#elif defined(_UV0_AUTO_SPHEREVIEW)
		float3 normalViewSpace = Transform(g_matView, normal);
		return float3(normalViewSpace.x, -normalViewSpace.y, 1.0f) * .5f + .5f;
	#else
		return normal;
	#endif	
}

float3 GetUVCoordinate3L1(float3 position, float3 normal, float3 viewer)
{
	#ifdef _UV1_AUTO_POSITION
		return position;
	#elif defined(_UV1_AUTO_REFLECTION)
		return (2.f * dot(viewer,normal) * normal - viewer) * .5f + .5f;
	#elif defined(_UV1_AUTO_NORMAL)
		return normal;
	#elif defined(_UV1_AUTO_SPHERE)
		return normal * .5f + .5f;
	#elif defined(_UV1_AUTO_SPHEREVIEW)
		float3 normalViewSpace = Transform(g_matView, normal);
		return float3(normalViewSpace.x, -normalViewSpace.y, 1.0f) * .5f + .5f;
	#else
		return normal;
	#endif	
}

#endif

#ifdef _VERTEX_SHADER

/// FOR PER VERTEX SHADERS
struct Multilayer_InputVS
{
	float4 pos		: POSITION;			///< Vertex position
	
#ifdef _USE_SKINMATRIX
	float4 weight	: BLENDWEIGHT;		///< Weights values for skinning
	float4 indices	: BLENDINDICES;		///< Index of bones for skinning
#endif

#ifdef _HAS_NORMAL
	float3 normal	: NORMAL;			///< Vertex Normal
#endif

#ifdef _HAS_TANGENT3
	float3 tangent	: TANGENT;			///< Vertex tangent, for use to map to tangent space normal maps
#endif

#ifdef _HAS_TANGENT
	float4 tangent	: TANGENT;			///< Vertex tangent, for use to map to tangent space normal maps
#endif

#ifdef _HAS_COLOR
	float4 color    : COLOR0;			///< Diffuse color of the vertex
#endif

#ifdef _HAS_UV0
	float2 uv0		: TEXCOORD0;		///< UV Coordinates for diffuse, enviroment and normal map
#endif

#ifdef _HAS_UV1
	float2 uv1		: TEXCOORD1;		///< UV Coordinates for light map
#endif

#ifdef _HAS_UV2
	float2 uv2		: TEXCOORD2;
#endif
};

#endif


struct MultilayerPVL_OuputVS
{
	float4 hpos			: POSITION;		///< Clip space transformed vertex position
	float4 color		: COLOR0;		///< Vertex color
	
#ifndef _POINTSPRITE		
	float4 vpos			: TEXCOORD0;	///< Position of the vertex in world space, and shadowprojection distance
	float3 uv0			: TEXCOORD1;	///< UV Coordinates used by the diffuse texture, enviroment mask, and the normal map
	float3 uv1			: TEXCOORD2;	///< UV Coordinates used by the enviroment map
	float2 uv2			: TEXCOORD3;	///< UV Coordinates used by the light map	
	float3  normal		: TEXCOORD4;	///< Vertex normal
	float3  view			: TEXCOORD5;	///< View direction to the vertex

	#ifdef __USE_SHADOWMAP
		float4 shadowProjection : TEXCOORD6;	///< Shadow map projection
	#endif

	#ifdef _PS3_VSCLIPPLANE0
		float oClip0      	: CLP0;
	#endif

#else //POINTSPRITE code
	float	pointSize	: PSIZE;
#endif
};

struct MultilayerPVLSpot_OuputVS
{
	float4 hpos				: POSITION;		///< Clip space trasnformed vertex
	float4 color			: COLOR0;		///< Vertex color	
	float3 uv0				: TEXCOORD0;	///< UV Coordinates used by the diffuse texture, enviroment mask, and the normal map
	float3  normal			: TEXCOORD1;	///< Vertex normal
	float3  view				: TEXCOORD2;	///< View direction to the vertex
	float3 vpos				: TEXCOORD3;	///< Position of the vertex in world space	
	float4 lightDir0		: TEXCOORD4;	///< Direction of light 0

	#ifdef _LIGHT0_SPOT
		float4 spotProjection1	: TEXCOORD5;	///< Shadow map projection
	#endif

	#ifdef _LIGHT1_SPOT
	#undef __USE_SHADOWMAP						// [BP] 2 spot lights do not allow the use of shadow maps (Using texcoord7)
		float4 lightDir1		: TEXCOORD6;	///< Direction of light 1
		float4 spotProjection2	: TEXCOORD7;	///< Shadow map projection
	#endif

	#if defined(__USE_SHADOWMAP)
		float4 shadowProjection : TEXCOORD7;	///< Shadow map projection
	#endif

	#ifdef _PS3_VSCLIPPLANE0
		float oClip0      		: CLP0;
	#endif
};

struct MultilayerPPL_OutputVS
{
	float4 hpos			: POSITION;		///< Clip space transformed vertex position
	float4 color		: COLOR0;		///< Diffuse color
	float4 uvcoords		: TEXCOORD0;	///< Uv coordinates of diffuse and enviroment maps
	float4 vpos			: TEXCOORD1;	///< Position in world space and lightspace depth
	float4 lightDir0	: TEXCOORD2;	///< Direction of light 0
	float4 lightDir1	: TEXCOORD3;	///< Direction of light 1
	float4 lightDir2	: TEXCOORD4;	///< Direction of light 2 
	float4 lightDir3	: TEXCOORD5;	///< Direction of light 3
	float3  viewDir		: TEXCOORD6;	///< View direction to the vertex (tangent space)

	#if defined(__USE_SHADOWMAP)
		float4 shadowProjection : TEXCOORD7;	///< Shadow map projection
	#endif

	#ifdef _PS3_VSCLIPPLANE0
		float oClip0      	: CLP0;
	#endif
};

struct MultilayerPPLSpot_OutputVS
{
	float4 hpos				: POSITION;	
	float4 color			: COLOR0;
	
	float3 uv0				: TEXCOORD0;		///< UV Coordinates used by the diffuse texture, enviroment mask, and the normal map
	float3 vpos				: TEXCOORD1;		///< Position in world space of the vertex
	
	float4 lightDir0		: TEXCOORD2;		///< Direction of light 0
#ifdef _LIGHT0_SPOT
	float4 spotProjection1	: TEXCOORD3;		///< Shadow map projection
#endif
#ifdef _LIGHT1_SPOT
#undef __USE_SHADOWMAP
	float4 lightDir1		: TEXCOORD4;		///< Direction of light 1
	float4 spotProjection2	: TEXCOORD5;		///< Shadow map projection
#endif

	float3  view				: TEXCOORD6;		///< Vire direction vector

#if defined(__USE_SHADOWMAP)
	float4 shadowProjection : TEXCOORD7;	///< Shadow map projection
#endif

#ifdef _PS3_VSCLIPPLANE0
	float oClip0      		: CLP0;
#endif
};

struct MultilayerPVL_OutputPS
{
#if !defined(_MRT)
	float4 color : COLOR0;
#else
	#if defined(_MRT_RT_0_1)
		float4 color : COLOR1;
	#elif defined(_MRT_RT_0_2)
		float4 color : COLOR2;
	#elif defined(_MRT_RT_0_3)
		float4 color : COLOR3;
	#else
		float4 color : COLOR0;
	#endif
	
	#if defined(_MRT1)
	#if defined(_MRT_RT_1_0)
		float4 color1 : COLOR0;
	#elif defined(_MRT_RT_1_2)
		float4 color1 : COLOR2;
	#elif defined(_MRT_RT_1_3)
		float4 color1 : COLOR3;
	#else
		float4 color1 : COLOR1;
	#endif
	#endif
	
	#if defined(_MRT2)
	#if defined(_MRT_RT_2_0)
		float4 color2 : COLOR0;
	#elif defined(_MRT_RT_2_1)
		float4 color2 : COLOR1;
	#elif defined(_MRT_RT_2_3)
		float4 color2 : COLOR3;
	#else
		float4 color2 : COLOR2;
	#endif
	#endif
	
	#if defined(_MRT3)
	#if defined(_MRT_RT_3_0)
		float4 color3 : COLOR0;
	#elif defined(_MRT_RT_3_1)
		float4 color3 : COLOR1;
	#elif defined(_MRT_RT_3_2)
		float4 color3 : COLOR2;
	#else
		float4 color3 : COLOR3;
	#endif
	#endif
#endif
};

//////////////////////////////////////
// LIGHTING FUNCTIONS
//////////////////////////////////////
/*
CalculateSpecularLighting
Calculates the specular lighting for an interest point
*/
float3 CalculateSpecularLighting(
			in float3 lightDirection,			///< Direction of the light MUST BE NORMALIZED!
			in float3 lightSpecularColor,		///< Specular color
			in float3 normalVector,				///< Normal vector of the intereset point
			in float3 viewVector				///< View vector of the interest point
			)
{
	float3 Half = normalize( lightDirection + viewVector);
	return lightSpecularColor.xyz * pow(saturate( dot( Half, normalVector) ), g_specularColor.a);
}

/*
CalculatePointLightAttenuation
Calculates the attenuation of a point light on a surface point
*/
float CalculatePointLightAttenuation(
	 in float3	iLightDirection,			///< Direction NOT NORMALIZED, from the point to the light position	 
	 float		iLightInverseRange			///< Inverse range (1/r) of the point light	 
	 )
{
	float3 attenuatedLightDirection = iLightDirection * iLightInverseRange;
	return saturate ( 1.0f - dot (attenuatedLightDirection, attenuatedLightDirection));
}
	 


void LightSpot_VS(float3 iDir, float invRange, out float3 oDir, out float oFactor)
{
	oDir.xyz = iDir;
	//oFactor = length(iDir);
	//oFactor = ( 1.0f - (oFactor  / Range) );	
	oFactor = saturate ( 1.0f - dot (iDir * invRange, iDir * invRange));					
}

void LightSpot_PS(float3 iDir, float3 normal, float3 view, float Factor, float3 iD, float4 iS, inout float3 oD, inout float3 oS, sampler2D spotMap, float4 spotTex)
{
	float3 fvLightDir = iDir;
	float fNDotL = dot(normal, fvLightDir);		

	float3 lightColor = tex2Dproj(spotMap, spotTex).rgb;
	
	oD += lightColor * iD * saturate(fNDotL) * Factor;
	
	#ifndef _MATERIAL_NOSPECULAR
		float3 Half = normalize(fvLightDir+view);
		oS += Factor * lightColor * iS.xyz * pow(saturate(dot(Half,normal)), iS.a);
	#endif
}

/*
GetPointLightDirectionInTangentSpace
Retrieves the direction of a point light in tangent space
*/
float3 GetPointLightDirectionInTangentSpace( 
		float3 lightPosition,					///< Light position in world space
		float3 vertexPosition,					///< Vertex position in world space
		float3x3 worldToTangentTransform		///< World to Tangent space transformation
		)
{
	float3 lightDir = lightPosition - vertexPosition;
	lightDir = mul(worldToTangentTransform, lightDir);
	return lightDir;
}

/*
GetPointLightDirectionInWorldSpace
Calculates the point light direction in world space
*/
float3 GetPointLightDirectionInWorldSpace(
		float3 lightPosition,					///< Light position in world space
		float3 vertexPosition					//< Vertex position in world space
		)
{
	return lightPosition - vertexPosition;
}

void OutLightDirSpotPPL(float3 iDir, float invRange, float3x3 TBN, out float3 oDir, out float oFactor)
{
	oDir.xyz = iDir;
	//oFactor = length(iDir.xyz);
	//oFactor = ( 1.0f - (oFactor  * invRange) );	
	oDir.xyz = mul(TBN, oDir.xyz);	
	oFactor = saturate ( 1.0f - dot (iDir * invRange, iDir * invRange));
}

void OutLightDirSpotPVL(float3 iDir, float invRange, out float3 oDir, out float oFactor)
{
	oDir.xyz = iDir;
	//oFactor = length(iDir.xyz);
	//oFactor = ( 1.0f - (oFactor  / Range) );						
	oFactor = saturate ( 1.0f - dot (iDir * invRange, iDir * invRange));
}

void LightDirectional_PPL_PS(float3 iDir, float3 n, float3 v, float3 iD, float3 iS, inout float3 oD, inout float3 oS)
{
	float3 fvLightDir = normalize(iDir);
	float fNDotL = dot(n, fvLightDir);		
	oD += iD * saturate(fNDotL);

	#ifndef _MATERIAL_NOSPECULAR
		float3 Half = normalize(fvLightDir + v);
		oS.xyz += iS.xyz * pow(saturate(dot(Half, n)), g_specularColor.a);
	#endif
}

/*
AddPointLightContributionTangentSpace
Adds the contribution diffuse and specular lighting of a point light to a point of a surface
*/
void AddPointLightContributionTangentSpace(
	in float3		iLightDirectionTangentSpace,		///< Direction to the light from the 3d point in tangent space
	in float3		iLightPositionWorldSpace,			///< Position of the point light in world space
	in float		iLightInverseRange,					///< Inverse range of the point light (1/r)
	in float3		iLightDiffuseColor,					///< Diffuse color of the light
	in float3		iLightSpecularColor,				///< Specular color of the light
	in float3		iPointNormalTangentSpace,			///< Normal on the 3d point in tangent space
	in float3		iPointViewTangentSpace,				///< View vector on the 3d point in tangent space
	in float3		iPointPositionWorldSpace,			///< Position of the 3d point in world space
	inout float3	ioAcumulatedDiffuseLight,			///< Acumulated diffuse light
	inout float3	ioAcumulatedSpecularLight			///< Acumulated specular light
	)
{
	// Calculate attenuation of the spot light
	float lightAttenuation = CalculatePointLightAttenuation(iLightPositionWorldSpace - iPointPositionWorldSpace, iLightInverseRange );
	
	// Calculate diffuse lighting contribution
	float3 lightDirectionNormalized = normalize( iLightDirectionTangentSpace );
	float fNDotL = dot(iPointNormalTangentSpace, lightDirectionNormalized);		
	ioAcumulatedDiffuseLight += iLightDiffuseColor * saturate(fNDotL) * lightAttenuation;
	
	// Calculate specular lighting contribution
	#ifndef _MATERIAL_NOSPECULAR
		ioAcumulatedSpecularLight += lightAttenuation * 
			CalculateSpecularLighting(lightDirectionNormalized, iLightSpecularColor, iPointNormalTangentSpace, iPointViewTangentSpace );
	#endif
}

void LightPoint_PPL_PS(float3 iDir, float3 n, float3 v, float Factor, float3 iD, float4 iS, inout float3 oD, inout float3 oS)
{
	float3 fvLightDir = normalize(iDir);
	float fNDotL = dot(n, fvLightDir);		
	oD += iD * saturate(fNDotL) * Factor;
	
	#ifndef _MATERIAL_NOSPECULAR
		float3 Half = normalize(fvLightDir+v);
		oS.rgb += Factor * iS.xyz * pow(saturate( dot(Half,n) ), g_specularColor.a);
	#endif
}

void LightSpot_PPL_PS(float3 iDir, float3 normal, float3 view, float Factor, float3 iD, float4 iS, inout float3 oD, inout float3 oS, sampler2D spotMap, float4 spotTex)
{
	float3 fvLightDir = normalize(iDir);		
	float fNDotL = dot(normal, fvLightDir);		

	float3 lightColor = tex2Dproj(spotMap, spotTex).rgb;			
	oD += saturate( lightColor * iD * saturate(fNDotL) * Factor );
	
	#ifndef _MATERIAL_NOSPECULAR
		float3 Half = normalize(fvLightDir+view);
		oS += saturate( lightColor * Factor * iS.xyz * pow(saturate(dot(Half,normal)), g_specularColor.a) );
	#endif
}
	
void LightDirectional_PVL_PS(float3 iDir, float3 normal, float3 view, float3 iD, float  transColor,	float3 iS, inout float3 oD, inout float3 oS)
{
	
	float fNDotL = dot(normal, iDir);		
	oD += iD.rgb * saturate(fNDotL);
	
	#ifdef _TRANSLUCENCY
			float fNDotL2 = dot(-normal, iDir);		
			oD += iD.rgb * saturate(fNDotL2) * transColor;
	#endif
	
	#ifndef _MATERIAL_NOSPECULAR
		float3 Half = normalize(iDir + view);	
		oS += iS.xyz * pow( saturate(dot(Half,normal)), g_specularColor.a);
	#endif
}

/*
AddPointLightContributionWorldSpace
Adds the contribution diffuse and specular lighting of a point light to a point of a surface
*/
void AddPointLightContributionWorldSpace(
	in float3		iLightPosition,				///< Light position in world space
	in float		iLightInverseRange,			///< Inverse range of the point light (1/r)
	in float3		iLightDiffuseColor,			///< Diffuse color of the light
	in float3		iLightSpecularColor,		///< Specular color of the light
	in float3		iPointNormal,				///< Normal of the 3d point in world space
	in float3		iPointView,					///< View vector of the 3d point in world space
	in float3		iPointPosition,				///< Poisition of the 3d point in worls space
	inout float3	ioAcumulatedDiffuseLight,	///< Acumulated diffuse lighting
	inout float3	ioAcumulatedSpecularLight	///< Acumulated specular lighting
	)
{
	// Determiate the light direction, used for attenuation and light contribution
	float3 lightDirection = iLightPosition - iPointPosition;

	// Calculate attenuation of the spot light
	float lightAttenuation = CalculatePointLightAttenuation(lightDirection, iLightInverseRange);
	
	// Calculate diffuse lighting contribution
	lightDirection = normalize( lightDirection );
	float fNDotL = dot(iPointNormal, lightDirection);		
	ioAcumulatedDiffuseLight += iLightDiffuseColor * saturate(fNDotL) * lightAttenuation;
	
	// Calculate specular lighting contribution
	#ifndef _MATERIAL_NOSPECULAR
		ioAcumulatedSpecularLight += lightAttenuation * 
			CalculateSpecularLighting(lightDirection, iLightSpecularColor, iPointNormal, iPointView);
	#endif
}

void LightSpot_PVL_PS(float3 iDir, float3 normal, float3 view, float Factor, float3 iD, float4 iS, inout float3 oD, inout float3 oS, sampler2D spotMap, float4 spotTex)
{
	float3 fvLightDir = iDir;
	float fNDotL = dot(normal, fvLightDir);		

	float3 lightColor = tex2Dproj(spotMap, spotTex).rgb;			
	oD += lightColor * iD * saturate(fNDotL) * Factor;		
	
	#ifndef _MATERIAL_NOSPECULAR
		float3 Half = normalize(fvLightDir+view);
		oS += lightColor * Factor * iS.xyz * pow(saturate(dot(Half,normal)), g_specularColor.a);
	#endif
}


//////////////////////////////////////
// END LIGHTING
//////////////////////////////////////

//////////////////////////////////////
// SHADOWMAPPING
//////////////////////////////////////
#ifdef __USE_SHADOWMAP

uniform float4x4	g_matTextureProjection;
uniform float4		g_shadowmapOptions;
uniform float4		g_texelSize89;

#define 	g_ShadowmapFactor	(1-g_shadowmapOptions.x)	/// default 0.0
#define 	g_ShadowmapZBias	(g_shadowmapOptions.y)		/// default -0.001

uniform sampler2D	g_shadowMap			: register(s9);
uniform samplerCUBE	g_shadowCubeMap		: register(s9);

////////////////////////////////////
// DIRECTIONAL
float SampleShadowTest(float4 ShadowTexC)
{	
	#if defined(_XENON) || defined(_SHADOWMAP_FLOAT)	//Xenon & ATI
		return tex2D(g_shadowMap, ShadowTexC.xy).r >= ShadowTexC.z;		
	#else	//nVidia
		return tex2Dproj(g_shadowMap, ShadowTexC).r;
	#endif	
}

float GetShadowDirectional(float4 TexCoords)
{
	float4 ShadowTexC = TexCoords;
	ShadowTexC.xy = 0.5 * TexCoords.xy + float2( 0.5, 0.5 );
	ShadowTexC.y = 1.f - ShadowTexC.y;

#ifdef _PS3
	ShadowTexC.z = ShadowTexC.z * .5f + .5f;
#endif

#ifdef _XENON
	ShadowTexC.xyz = ShadowTexC.xyz / ShadowTexC.w;
	
	// [BP] On xbox360 we are getting projected distances that are higher than 1
	// as they are not being cut by the far plane of the light frustum
	// still we need to study more this effect, even check if it can be done on vertex
	// shader stage to save gpu process
	ShadowTexC.z = min(1,ShadowTexC.z); 	// Check that z the minimum value to 1
#endif
	
#ifdef _DEBUG_SHADOWMAPS	
	//Dark regions out of shadow projection
	if(ShadowTexC.x < 0 ||
		ShadowTexC.y < 0 ||
		ShadowTexC.x > 1 ||
		ShadowTexC.y > 1)
		return 0;
#endif
	
	ShadowTexC.z += g_ShadowmapZBias;
	ShadowTexC.w = 1;
			
	#if defined(SH_VERSION_SH2) || defined(_SHADOW_LOW)
		return saturate(SampleShadowTest(ShadowTexC) + g_ShadowmapFactor);
	#else

		float4 tX = float4(g_texelSize89.z, 0, 0, 0) * 2;
		float4 tY = float4(0, g_texelSize89.w, 0, 0) * 2;
		float accum = 0;
 
		#if defined(_SHADOW_MED)
			accum += SampleShadowTest(ShadowTexC + tX * -.5 + tY * -.5);
			accum += SampleShadowTest(ShadowTexC + tX *  .5 + tY * -.5);
			accum += SampleShadowTest(ShadowTexC + tX * -.5 + tY *  .5);
			accum += SampleShadowTest(ShadowTexC + tX *  .5 + tY *  .5);
			return saturate((accum/4.f) + g_ShadowmapFactor);
		#elif defined(_SHADOW_HI)
			accum += SampleShadowTest(ShadowTexC + tX * -1 + tY * -1);
			accum += SampleShadowTest(ShadowTexC + tX *  0 + tY * -1);
			accum += SampleShadowTest(ShadowTexC + tX *  1 + tY * -1);
			accum += SampleShadowTest(ShadowTexC + tX * -1 + tY *  0);
			accum += SampleShadowTest(ShadowTexC + tX *  0 + tY *  0);
			accum += SampleShadowTest(ShadowTexC + tX *  1 + tY *  0);
			accum += SampleShadowTest(ShadowTexC + tX * -1 + tY *  1);
			accum += SampleShadowTest(ShadowTexC + tX *  0 + tY *  1);
			accum += SampleShadowTest(ShadowTexC + tX *  1 + tY *  1);	
			return saturate((accum/9.f) + g_ShadowmapFactor);
		#else
			return 1;
		#endif
	#endif	
}

/////////////////////////////////
// SPOT
//[VC]: why this is just a copy paste from spotdirectional???
float GetShadowSpotSample(float4 ShadowTexC)
{
	float shadow;

#if defined(_XENON) || defined(_SHADOWMAP_FLOAT)	//Xenon & ATI

	float a = tex2D(g_shadowMap, ShadowTexC.xy).r > ShadowTexC.z;
	float b = tex2D(g_shadowMap, ShadowTexC.xy + float2(g_texelSize89.z, 0)).r > ShadowTexC.z;
	float c = tex2D(g_shadowMap, ShadowTexC.xy + float2(0, g_texelSize89.w)).r > ShadowTexC.z;
	float d = tex2D(g_shadowMap, ShadowTexC.xy + float2(g_texelSize89.z, g_texelSize89.w)).r > ShadowTexC.z;

#if defined(SH_VERSION_SH2)
	return a;
#endif
	
    // transform to texel space
    float2 texelpos = (1.f/g_texelSize89.zw) * ShadowTexC;
    
    // Determine the lerp amounts           
    float2 lerps = frac( texelpos );

    // lerp between the shadow values to calculate our light amount
    shadow = lerp( lerp( a, b, lerps.x ),
                   lerp( c, d, lerps.x ),
                   lerps.y );		
	return shadow;

#else	//nVidia

	shadow = tex2Dproj(g_shadowMap, ShadowTexC).r;

#endif
	
	return shadow;
}

float GetShadowSpot(float4 TexCoords)
{
	float4 ShadowTexC = TexCoords;
	ShadowTexC.xy = 0.5 * TexCoords.xy / TexCoords.w + float2( 0.5, 0.5 );
	ShadowTexC.y = 1.0f - ShadowTexC.y;

	//not needed for spot lights
#ifdef _PS3
	//ShadowTexC.z = ShadowTexC.z * .5f + .5f;
#endif

#ifdef _DEBUG_SHADOWMAPS	
	//Dark regions out of shadow projection
	if(ShadowTexC.x < 0 ||
		ShadowTexC.y < 0 ||
		ShadowTexC.x > 1 ||
		ShadowTexC.y > 1)
		return 0;
#endif
		
	ShadowTexC.z += g_ShadowmapZBias;
	ShadowTexC.z /= ShadowTexC.w;

	ShadowTexC.w = 1;
			
#if defined(SH_VERSION_SH2) || defined(_SHADOW_LOW)

	return saturate(GetShadowSpotSample(ShadowTexC) + g_ShadowmapFactor);
	
#endif

	float4 tX = float4(g_texelSize89.z, 0, 0, 0) * 1;
	float4 tY = float4(0, g_texelSize89.w, 0, 0) * 1;

	float accum = 0;

#if defined(_SHADOW_MED)
	accum += GetShadowSpotSample(ShadowTexC + tX * -.5 + tY * -.5);
	accum += GetShadowSpotSample(ShadowTexC + tX *  .5 + tY * -.5);
	accum += GetShadowSpotSample(ShadowTexC + tX * -.5 + tY *  .5);
	accum += GetShadowSpotSample(ShadowTexC + tX *  .5 + tY *  .5);	
	return saturate((accum/4.f) + g_ShadowmapFactor);
#endif
	
#if defined(_SHADOW_HI)
	accum += GetShadowSpotSample(ShadowTexC + tX * -1 + tY * -1);
	accum += GetShadowSpotSample(ShadowTexC + tX *  0 + tY * -1);
	accum += GetShadowSpotSample(ShadowTexC + tX *  1 + tY * -1);
	accum += GetShadowSpotSample(ShadowTexC + tX * -1 + tY *  0);
	accum += GetShadowSpotSample(ShadowTexC + tX *  0 + tY *  0);
	accum += GetShadowSpotSample(ShadowTexC + tX *  1 + tY *  0);
	accum += GetShadowSpotSample(ShadowTexC + tX * -1 + tY *  1);
	accum += GetShadowSpotSample(ShadowTexC + tX *  0 + tY *  1);
	accum += GetShadowSpotSample(ShadowTexC + tX *  1 + tY *  1);
	return saturate((accum/9.f) + g_ShadowmapFactor);
#endif

	return 1;
}


/////////////////////////////////
// POINT

float GetShadowPointSample(float3 Pos)
{
	float shadow = 1;

#ifdef _LIGHT0_POINT
	shadow = texCUBE(g_shadowCubeMap, Pos.xyz-g_lightPosition0.xyz).r > (length(Pos.xyz-g_lightPosition0.xyz) * g_lightPosition0.w) + g_ShadowmapZBias;
#endif

	return shadow;
}

float GetShadowPoint(float3 Pos)
{
	return saturate(GetShadowPointSample(Pos) + g_ShadowmapFactor);
}

#endif
//////////////////////////////////////
// END SHADOWMAPPING
//////////////////////////////////////


float GetRimFading(float3 CamPos,float3 FragmentWorldPos,float3 Normal,float InvThreshold)
{
	float3 nCminP = normalize(CamPos.xyz-FragmentWorldPos.xyz);
	float NdotCmP = dot(Normal,nCminP);
	return saturate(NdotCmP*InvThreshold);
}

void ComputeFog(inout float4 PixelColor,float3 FogColor,float DistancePixelToCamera,float MinDistanceToFog,float MaxMinusMinDistanceToFog)
{
#if defined(_PIXEL_FOG)
	float CamMinusFogMin = (DistancePixelToCamera-MinDistanceToFog);
	float FogFactor  = 1-saturate(CamMinusFogMin/MaxMinusMinDistanceToFog);
	#if !defined(_ADDITIVE_PIXEL_FOG)
		PixelColor.rgb = lerp(FogColor, PixelColor.rgb, FogFactor);
	#elif defined(_ADDITIVE_PIXEL_FOG)
		PixelColor.rgb*=FogFactor;
		clip(MaxMinusMinDistanceToFog-CamMinusFogMin);
	#endif
#endif
}


///////////////////////////////////////////////////////////////
//VERTEX SHADERS
///////////////////////////////////////////////////////////////
#ifdef _VERTEX_SHADER


#ifdef _PERPIXEL_LIGHTING
	#ifdef _LIGHT0_SPOT
		#define	MULTILAYER_OUTPUT_VS		MultilayerPPLSpot_OutputVS
		#define MULTILAYER_MAIN_VS		MultilayerPPLSpot_MainVS
	#else
		#define	MULTILAYER_OUTPUT_VS		MultilayerPPL_OutputVS
		#define MULTILAYER_MAIN_VS		MultilayerPPL_MainVS
	#endif
#else
	#ifdef _LIGHT0_SPOT
		#define	MULTILAYER_OUTPUT_VS		MultilayerPVLSpot_OuputVS
		#define MULTILAYER_MAIN_VS		MultilayerPVLSpot_MainVS
	#else
		#define	MULTILAYER_OUTPUT_VS		MultilayerPVL_OuputVS
		#define MULTILAYER_MAIN_VS		MultilayerPVL_MainVS
	#endif
#endif

void MultilayerPPL_MainVS(			Multilayer_InputVS	inVertex,out	MultilayerPPL_OutputVS		outResult);
void MultilayerPPLSpot_MainVS(		Multilayer_InputVS	inVertex,out	MultilayerPPLSpot_OutputVS	outResult);
void MultilayerPVL_MainVS(			Multilayer_InputVS	inVertex,out	MultilayerPVL_OuputVS		outResult);
void MultilayerPVLSpot_MainVS(		Multilayer_InputVS	inVertex,out	MultilayerPVLSpot_OuputVS	outResult);

void main_VS( Multilayer_InputVS inVertex, out MULTILAYER_OUTPUT_VS outResult )
{
	MULTILAYER_MAIN_VS(inVertex, outResult);
}

///////////////////////////////////////////////
// Omni & Direct Per Pixel Vertex Shader
///////////////////////////////////////////////
void MultilayerPPL_MainVS( Multilayer_InputVS inVertex, out MultilayerPPL_OutputVS outResult)
{
	outResult = (MultilayerPPL_OutputVS) 0;
		
	#ifdef _HAS_NORMAL
		float3 tempNormal = normalize(inVertex.normal.xyz);
	#else 
		float3 tempNormal = float3(0,0,1);
	#endif
	
	#if defined(_HAS_TANGENT3) || defined(_HAS_TANGENT)
		float3 tempTangent = normalize(inVertex.tangent.xyz);
	#else
		float3 tempTangent = float3(1,0,0);
	#endif
	
	#ifdef _HAS_COLOR
		outResult.color	= inVertex.color;
	#else
		outResult.color	= float4(1,1,1,1);
	#endif

	/// Determinate the vertex position, normal and tangent from skinning
#ifdef _USE_SKINMATRIX	
	SKINVERTEX v = SkinVertex(inVertex.pos.xyz, tempNormal, tempTangent, inVertex.indices, inVertex.weight);	
	float4 position	= v.P;
	float3 normal	= v.N;
	float3 tangent	= v.T;	
#else
	float4 position	= float4(inVertex.pos.xyz,1);
	float3 normal	= tempNormal; 
	float3 tangent	= tempTangent;
#endif


	/// Transform the position and the normal to projection space
	outResult.vpos	= Transform(g_matWorld, position);
#if defined (_USE_TAPER)
	outResult.vpos	= float4(TaperVert(outResult.vpos.xyz),1);
	outResult.hpos  = Transform(g_matViewProjection, outResult.vpos);
#else
	outResult.hpos	= Transform(g_matWorldViewProjection, position);
#endif
		

#ifdef _PS3_VSCLIPPLANE0
	outResult.oClip0	= dot(outResult.vpos, g_ps3ClipPlane0);
#endif

	/// Compute the tangent transformation matrix
	float3x3 worldToTangent = GetWorldToTangentMatrix((float3x3)g_matWorld,tangent,normal);

#ifdef _HAS_TANGENT
	worldToTangent[1] *= inVertex.tangent.w;
#endif
	

	/// Calculate lighting for directional lights, these must be transformed into tangent space
	#ifdef _LIGHT0_DIRECTIONAL		
		outResult.lightDir0.xyz = -mul(worldToTangent, g_lightDirection0.xyz);
		#ifdef __USE_SHADOWMAP
			outResult.shadowProjection = Transform(g_matTextureProjection, position);
		#endif
	#endif
	
	#ifdef _LIGHT1_DIRECTIONAL		
		outResult.lightDir1.xyz = -mul(worldToTangent, g_lightDirection1.xyz);
	#endif
	
	#ifdef _LIGHT2_DIRECTIONAL		
		outResult.lightDir2.xyz = -mul(worldToTangent, g_lightDirection2.xyz);
	#endif
	
	#ifdef _LIGHT3_DIRECTIONAL		
		outResult.lightDir3.xyz = -mul(worldToTangent, g_lightDirection3.xyz);
	#endif
	
	/// Calculate lighting for point lights
	#ifdef _LIGHT0_POINT
		outResult.lightDir0.xyz = GetPointLightDirectionInTangentSpace(g_lightPosition0.xyz, outResult.vpos.xyz, worldToTangent);		
	#endif
		
	#ifdef _LIGHT1_POINT
		outResult.lightDir1.xyz = GetPointLightDirectionInTangentSpace(g_lightPosition1.xyz, outResult.vpos.xyz, worldToTangent);				
	#endif
	
	#ifdef _LIGHT2_POINT
		outResult.lightDir2.xyz = GetPointLightDirectionInTangentSpace(g_lightPosition2.xyz, outResult.vpos.xyz, worldToTangent);				
	#endif
	
	#ifdef _LIGHT3_POINT
		outResult.lightDir3.xyz = GetPointLightDirectionInTangentSpace(g_lightPosition3.xyz, outResult.vpos.xyz, worldToTangent);						
	#endif
	
	/// Calculate the view space normal, vertex position and viewer position
	/// This are going to be used to calculate the vertex uv
	/// Create parameters for autogenerated coordinates
	#if defined(_UV0_AUTO_POSITION) || defined(_UV0_AUTO_NORMAL) || defined(_UV0_AUTO_REFLECTION) || defined(_UV0_AUTO_SPHERE) || defined(_UV0_AUTO_SPHEREVIEW) || defined(_UV1_AUTO_POSITION) || defined(_UV1_AUTO_NORMAL) || defined(_UV1_AUTO_REFLECTION)  || defined(_UV1_AUTO_SPHERE)  || defined(_UV1_AUTO_SPHEREVIEW) 
		float3 P		= outResult.vpos.xyz;									///< Vertex position in world space
		float3  N		= Transform((float3x3) g_matWorld, normal); 		///< Normal in world space
		float3  V		= normalize(P-g_cameraPos.xyz);				///< Viewer position
		N				= normalize(N);
	#endif
	
	/// Calculate the uv transformations for the diffuse layer
	#if defined(_UV0_AUTO_POSITION) || defined(_UV0_AUTO_NORMAL) || defined(_UV0_AUTO_REFLECTION) || defined(_UV0_AUTO_SPHERE) || defined(_UV0_AUTO_SPHEREVIEW)
		outResult.uvcoords.xy = GetUVCoordinate3L0(P, N, V);		
	#elif defined(_HAS_UV0)
		outResult.uvcoords.xy = inVertex.uv0;		
	#endif
	
	float3 env = 0;
	#ifndef _MAP_PLANAR_REFLECTION
		#if defined(_UV1_AUTO_POSITION) || defined(_UV1_AUTO_NORMAL) || defined(_UV1_AUTO_REFLECTION) || defined(_UV1_AUTO_SPHERE) || defined(_UV1_AUTO_SPHEREVIEW)
			#ifdef _MAP_ENVIROMENT_CUBE
				env = GetUVCoordinate3L1(P, N, V);
			#else
				env.xy = GetUVCoordinate3L1(P, N, V);
			#endif
		#elif defined(_HAS_UV0)
			env.xy 	= inVertex.uv0;
			env.z 	= 1;
		#endif
	#endif
		
	/// Finally transform the uv coordinates by the texture matrix transformations
	float3 uv3;
	uv3.xy = outResult.uvcoords.xy;
	uv3.z = 1;

	outResult.uvcoords.xy = outResult.uvcoords.xy * g_textureTransform0.xy + outResult.uvcoords.yx * g_textureTransformExt0.yx + g_textureTransform0.zw;

	#ifndef _MAP_ENVIROMENT_CUBE
		env.xy = env.xy * g_textureTransform1.xy + env.yx * g_textureTransformExt1.yx + g_textureTransform1.zw;
	#endif
	
	#if !defined(_MAP_PLANAR_REFLECTION)
		outResult.uvcoords.zw = env.xy;
		outResult.vpos.w = env.z;
	#else
		float4 ScreenSpace = TransformPlanarReflection(outResult.hpos);
		outResult.uvcoords.zw = ScreenSpace.xy;
		outResult.vpos.w = ScreenSpace.z;
	#endif
	
	/// Write the UV used for the lightmap
	#ifdef _HAS_UV1
		outResult.lightDir0.w = inVertex.uv1.x;	
		outResult.lightDir1.w = inVertex.uv1.y;	
	#elif defined(_HAS_UV0)
		outResult.lightDir0.w = inVertex.uv0.x;	
		outResult.lightDir1.w = inVertex.uv0.y;	
	#endif

	/// Write the view direction in tangent space	
	//< Vertex position in world space
//#if !defined(_MATERIAL_NOSPECULAR) || defined(_PARALLAX)
	outResult.viewDir.xyz	= g_cameraPos.xyz - outResult.vpos.xyz;
	outResult.viewDir.xyz	= mul(worldToTangent, outResult.viewDir.xyz);
	outResult.viewDir.xyz = normalize(outResult.viewDir.xyz);
//#endif
}

///////////////////////////////////////////////
// Spot Per Pixel Vertex Shader
///////////////////////////////////////////////
void MultilayerPPLSpot_MainVS( Multilayer_InputVS inVertex,out MultilayerPPLSpot_OutputVS outResult)
{
	outResult = (MultilayerPPLSpot_OutputVS) 0;
	float3 tempNormal = float3(0,0,1);
	float3 tempTangent = float3(1,0,0);
	outResult.color	= float4(1,1,1,1);

	#ifdef _HAS_NORMAL
		tempNormal = normalize(inVertex.normal);
	#endif
	
	#if defined(_HAS_TANGENT3) || defined(_HAS_TANGENT)
		tempTangent = normalize(inVertex.tangent);
	#endif

	#ifdef _HAS_COLOR
		outResult.color	= inVertex.color;
	#endif

#ifdef _USE_SKINMATRIX	
	SKINVERTEX v = SkinVertex(inVertex.pos.xyz, tempNormal, tempTangent, inVertex.indices, inVertex.weight);
	float4 position	= v.P;
	float3 normal	= v.N;
	float3 tangent	= v.T;	
#else
	float4 position	= float4(inVertex.pos.xyz,1);
	float3 normal	= normalize(tempNormal); 
	float3 tangent	= normalize(tempTangent);
#endif

	/// Transform the position and the normal to projection space
	outResult.vpos	= Transform(g_matWorld, position);
#if defined (_USE_TAPER)
	outResult.vpos	= TaperVert(outResult.vpos.xyz);
	outResult.hpos    = Transform(g_matViewProjection, float4(outResult.vpos.xyz,1));
#else
	outResult.hpos	= Transform(g_matWorldViewProjection, position);
#endif

#ifdef _PS3_VSCLIPPLANE0
	outResult.oClip0	= dot(outResult.vpos, g_ps3ClipPlane0);
#endif
	
	/// Compute the tangent transformation matrix
	float3x3 worldToTangent = GetWorldToTangentMatrix((float3x3)g_matWorld, tangent,normal);	

#ifdef _HAS_TANGENT
	worldToTangent[1] *= inVertex.tangent.w;
#endif
	
	
	/// Determinate the view vector
#if !defined(_MATERIAL_NOSPECULAR) && defined(_PARALLAX)
	float3	view = g_cameraPos.xyz - outResult.vpos.xyz;
	outResult.view.xyz = Transform(worldToTangent, view);
	outResult.view.xyz = normalize(outResult.view.xyz);
#endif		
		
	/// Calculate the view space normal, vertex position and viewer position
	/// This are going to be used to calculate the vertex uv
	
	/// Create parameters for autogenerated coordinates
	#if defined(_UV0_AUTO_POSITION) || defined(_UV0_AUTO_NORMAL) || defined(_UV0_AUTO_REFLECTION)  || defined(_UV0_AUTO_SPHERE)  || defined(_UV0_AUTO_SPHEREVIEW) 
		float3 P		= outResult.vpos.xyz;									///< Vertex position in world space
		float3  N		= Transform((float3x3) g_matWorld, normal); 		///< Normal in world space
		float3  V		= -normalize(P-g_cameraPos);				///< Viewer position
		N				= normalize(N);
	#endif
		
	/// Calculate the uv transformations for the diffuse layer
	#if defined(_UV0_AUTO_POSITION) || defined(_UV0_AUTO_NORMAL) || defined(_UV0_AUTO_REFLECTION) || defined(_UV0_AUTO_SPHERE) || defined(_UV0_AUTO_SPHEREVIEW)
		outResult.uv0 = GetUVCoordinate3L0(P, N, V);		
	#elif defined(_HAS_UV0)		
		outResult.uv0.xy	= inVertex.uv0;
		outResult.uv0.z	= 1;
	#endif
	
	
	/// Finally transform the uv coordinates by the texture matrix transformations
	outResult.uv0.xy = outResult.uv0.xy * g_textureTransform0.xy + outResult.uv0.yx * g_textureTransformExt0.yx + g_textureTransform0.zw;
	
		
	/// Calculate spot light lightining attributes
	float	factor;
	float	fNDotLSpot;
	#ifdef _LIGHT0_SPOT
		OutLightDirSpotPPL(g_lightPosition0.xyz - outResult.vpos.xyz, g_lightPosition0.w, worldToTangent, outResult.lightDir0.xyz, outResult.lightDir0.w);
		
		#ifdef __USE_SHADOWMAP
			outResult.shadowProjection = Transform(g_matTextureProjection, position);
		#endif

		outResult.spotProjection1 = Transform(g_matTexture2, position);
	#endif
	
	#ifdef _LIGHT1_SPOT
		OutLightDirSpotPPL(g_lightPosition1.xyz - outResult.vpos.xyz, g_lightPosition1.w, worldToTangent, outResult.lightDir1.xyz, outResult.lightDir1.w);
		outResult.spotProjection2 = Transform(g_matTexture3, position);
	#endif
}




///////////////////////////////////////////////
// Omni & Direct Vertex Shader
///////////////////////////////////////////////
void MultilayerPVL_MainVS( Multilayer_InputVS inVertex,out	MultilayerPVL_OuputVS outResult)
{
	outResult = (MultilayerPVL_OuputVS) 0;
#ifndef _POINTSPRITE	
	outResult.normal = float3(0,0,1);
	outResult.color = float4(1,1,1,1);
	
	#ifdef _HAS_NORMAL
		outResult.normal = normalize(inVertex.normal);
	#endif
	
	#ifdef _HAS_COLOR
		outResult.color	= inVertex.color;
	#endif
		
#ifdef _USE_SKINMATRIX	
	SKINVERTEX v = SkinVertex(inVertex.pos.xyz, outResult.normal, float3(1,0,0), inVertex.indices, inVertex.weight);
	float4 position	= v.P;
	float3 normal	= v.N;
#else
	float4 position	= float4(inVertex.pos.xyz,1);
	float3 normal	= outResult.normal; 
#endif

	/// Transform the position to clip space
	outResult.vpos	= Transform(g_matWorld, position);
#if defined (_USE_TAPER)
	outResult.vpos	= float4(TaperVert(outResult.vpos.xyz),1);
	outResult.hpos    = Transform(g_matViewProjection, outResult.vpos);
#else
	outResult.hpos	= Transform(g_matWorldViewProjection, position);
#endif
	outResult.normal	= Transform ((float3x3) g_matWorld, normal);			///< Normal in world space
#ifdef _PS3_VSCLIPPLANE0
	outResult.oClip0	= dot(outResult.vpos, g_ps3ClipPlane0);
#endif
	
	/// Create parameters for autogenerated coordinates
	#if defined(_UV0_AUTO_POSITION) || defined(_UV0_AUTO_NORMAL) || defined(_UV0_AUTO_REFLECTION) || defined(_UV0_AUTO_SPHERE) || defined(_UV0_AUTO_SPHEREVIEW) || defined(_UV1_AUTO_POSITION) || defined(_UV1_AUTO_NORMAL) || defined(_UV1_AUTO_REFLECTION)  || defined(_UV1_AUTO_SPHERE) || defined(_UV1_AUTO_SPHEREVIEW)
		float3 P		= outResult.vpos.xyz;									///< Vertex position in world space
		float3  N		= Transform((float3x3) g_matWorld, normal);	///< Normal in world space
		float3  V		= normalize(P-g_cameraPos);				///< Viewer position
		N				= normalize(N);
	#endif
	
	/// Calculate the uv transformations for the diffuse layer
	#if defined(_UV0_AUTO_POSITION) || defined(_UV0_AUTO_NORMAL) || defined(_UV0_AUTO_REFLECTION) || defined(_UV0_AUTO_SPHERE) || defined(_UV0_AUTO_SPHEREVIEW)
		outResult.uv0.xy = GetUVCoordinate3L0(P, N, V);		
	#elif defined(_HAS_UV0)		
		outResult.uv0.xy	= inVertex.uv0;
		outResult.uv0.z	= 1;
	#endif
	
	float3 env = 0;
	/// Calculate the uv transformation for the enviromental layer
	#if defined(_UV1_AUTO_POSITION) || defined(_UV1_AUTO_NORMAL) || defined(_UV1_AUTO_REFLECTION) || defined(_UV1_AUTO_SPHERE) || defined(_UV1_AUTO_SPHEREVIEW)
		#ifdef _MAP_ENVIROMENT_CUBE
			env = GetUVCoordinate3L1(P, N, V);
		#else
			env.xy = GetUVCoordinate3L1(P, N, V);
		#endif
		
		#if defined(_MAP_PLANAR_REFLECTION) || defined(_MAP_ENVIROMENT)
			outResult.uv1 = env;
		#endif
	#elif defined(_HAS_UV0)
		#if defined(_MAP_PLANAR_REFLECTION) || defined(_MAP_ENVIROMENT)
			outResult.uv1.xy	= inVertex.uv0;
			outResult.uv1.z	= 1;		
		#endif
	#endif

	/// Finally transform the uv coordinates by the texture matrix transformations
	outResult.uv0.xy = outResult.uv0.xy * g_textureTransform0.xy + outResult.uv0.yx * g_textureTransformExt0.yx + g_textureTransform0.zw;

	#ifndef _MAP_ENVIROMENT_CUBE
		#if defined(_MAP_PLANAR_REFLECTION) || defined(_MAP_ENVIROMENT)
			outResult.uv1.xy = outResult.uv1.xy * g_textureTransform1.xy + outResult.uv1.yx * g_textureTransformExt1.yx + g_textureTransform1.zw;
		#endif
	#endif
	
	/// Write the UV used for the lightmap
	#ifdef _HAS_UV1
		outResult.uv2 = inVertex.uv1;
	#elif defined(_HAS_UV0)
		outResult.uv2 = inVertex.uv0;
	#endif
	
	
	/// The outResult.view vector is only used to calculate specular lighting, so if there is no specular
	/// dont calculate the view
	#ifndef _MATERIAL_NOSPECULAR
		float3 pWorld	= Transform(g_matWorld, position);					///< Vertex position in world space
		outResult.view		= normalize(g_cameraPos - pWorld);				///< View direction
	#endif
	
	#ifdef _MAP_PLANAR_REFLECTION
		float4 ScreenSpace = TransformPlanarReflection(outResult.hpos);
		outResult.uv1.xyz = ScreenSpace.xyz;
	#endif
		
	#ifdef _LIGHT0_DIRECTIONAL
		#ifdef __USE_SHADOWMAP
			outResult.shadowProjection = Transform(g_matTextureProjection, position);
		#endif
	#endif

	/// Calculate lighting for point lights
	/*
	float3 lightDir;
	#ifdef _LIGHT0_POINT
		OutLightDirPointPVL(g_lightPosition0.xyz - outResult.vpos, g_lightPosition0.w, lightDir, outResult.lightfactors.x);
	#endif
	
	#ifdef _LIGHT1_POINT
		OutLightDirPointPVL(g_lightPosition1.xyz - outResult.vpos, g_lightPosition1.w, lightDir, outResult.lightfactors.y);
	#endif
	
	#ifdef _LIGHT2_POINT
		OutLightDirPointPVL(g_lightPosition2.xyz - outResult.vpos, g_lightPosition2.w, lightDir, outResult.lightfactors.z);
	#endif
	
	#ifdef _LIGHT3_POINT
		OutLightDirPointPVL(g_lightPosition3.xyz - outResult.vpos, g_lightPosition3.w, lightDir, outResult.lightfactors.w);
	#endif
	*/
	
#else//POINTSPRITE
	outResult.color		= inVertex.color;
	outResult.hpos		= Transform( g_matWorldViewProjection, inVertex.pos);
	float d			= distance(inVertex.pos.xyz, g_cameraPos.xyz);
	
	outResult.pointSize	= inVertex.uv0.x / d;
	outResult.pointSize *= g_screenSize.x;
#endif	
}

///////////////////////////////////////////////
// Spot Vertex Shader
///////////////////////////////////////////////
void MultilayerPVLSpot_MainVS( Multilayer_InputVS inVertex,out MultilayerPVLSpot_OuputVS outResult)
{
	outResult = (MultilayerPVLSpot_OuputVS) 0;
	outResult.normal = float3(0,0,1);
	outResult.color = float4(1,1,1,1);
	
	#ifdef _HAS_NORMAL
		outResult.normal = normalize(inVertex.normal);
	#endif
	
	#ifdef _HAS_COLOR
		outResult.color	= inVertex.color;
	#endif
		
#ifdef _USE_SKINMATRIX	
	SKINVERTEX v = SkinVertex(inVertex.pos.xyz, outResult.normal, float3(1,0,0), inVertex.indices, inVertex.weight);
	float4 position	= v.P;
	float3 normal	= v.N;
#else
	float4 position	= float4(inVertex.pos.xyz,1);
	float3 normal	= outResult.normal; 
#endif

	/// Transform the position to clip space
	outResult.vpos	= Transform(g_matWorld, position);
#if defined (_USE_TAPER)
	outResult.vpos	= TaperVert(outResult.vpos.xyz);
	outResult.hpos    = Transform(g_matViewProjection, float4(outResult.vpos.xyz,1));
#else
	outResult.hpos	= Transform(g_matWorldViewProjection, position);
#endif
	outResult.normal	= Transform ((float3x3) g_matWorld, normal);			///< Normal in world space
	
#ifdef _PS3_VSCLIPPLANE0
	outResult.oClip0	= dot(outResult.vpos, g_ps3ClipPlane0);
#endif
	
	/// Create parameters for autogenerated coordinates
	#if defined(_UV0_AUTO_POSITION) || defined(_UV0_AUTO_NORMAL) || defined(_UV0_AUTO_REFLECTION) || defined(_UV0_AUTO_SPHERE) || defined(_UV0_AUTO_SPHEREVIEW) || defined(_UV1_AUTO_POSITION) || defined(_UV1_AUTO_NORMAL) || defined(_UV1_AUTO_REFLECTION)  || defined(_UV1_AUTO_SPHERE) || defined(_UV1_AUTO_SPHEREVIEW)
		float3 P		= outResult.vpos.xyz;									///< Vertex position in world space
		float3  N		= Transform((float3x3) g_matWorld, normal); 		///< Normal in world space
		float3  V		= -normalize(P-g_cameraPos);				///< Viewer position
		N				= normalize(N);
	#endif
	
	/// Calculate the uv transformations for the diffuse layer
	#if defined(_UV0_AUTO_POSITION) || defined(_UV0_AUTO_NORMAL) || defined(_UV0_AUTO_REFLECTION) || defined(_UV0_AUTO_SPHERE) || defined(_UV0_AUTO_SPHEREVIEW)
		outResult.uv0 = GetUVCoordinate3L0(P, N, V);		
	#elif defined(_HAS_UV0)		
		outResult.uv0.xy	= inVertex.uv0;
		outResult.uv0.z	= 1;
	#endif
	
	/// Finally transform the uv coordinates by the texture matrix transformations
	outResult.uv0.xy = outResult.uv0.xy * g_textureTransform0.xy + outResult.uv0.yx * g_textureTransformExt0.yx + g_textureTransform0.zw;

	/// Calculate spot light lightining attributes
	float	factor;
	float	fNDotLSpot;
	#ifdef _LIGHT0_SPOT
		outResult.spotProjection1 = Transform(g_matTexture2, position);

		OutLightDirSpotPVL(g_lightPosition0.xyz - outResult.vpos.xyz, g_lightPosition0.w, outResult.lightDir0.xyz, outResult.lightDir0.w);

		#ifdef __USE_SHADOWMAP
			outResult.shadowProjection = Transform(g_matTextureProjection, position);
		#endif
	#endif
	
	#ifdef _LIGHT1_SPOT
		outResult.spotProjection2 = Transform(g_matTexture3, position);
	
		OutLightDirSpotPVL(g_lightPosition1.xyz - outResult.vpos.xyz, g_lightPosition1.w, outResult.lightDir1.xyz, outResult.lightDir1.w);
	#endif
	
	/// The outResult.view vector is only used to calculate specular lighting, so if there is no specular
	/// dont calculate the view
	#ifndef _MATERIAL_NOSPECULAR
		float3 pWorld	= Transform(g_matWorld, position);					///< Vertex position in world space
		outResult.view		= g_cameraPos.xyz - pWorld;							///< View direction
	#endif
}

#endif

///////////////////////////////////////////////////////////////
//PIXEL SHADERS
///////////////////////////////////////////////////////////////
#if defined(_PIXEL_SHADER)



#ifdef _PERPIXEL_LIGHTING
	#ifdef _LIGHT0_SPOT
		#define	MULTILAYER_OUTPUT_PS		MultilayerPVL_OutputPS
		#define MULTILAYER_INPUT_PS			MultilayerPPLSpot_OutputVS
		#define MULTILAYER_MAIN_PS			MultilayerPPLSpot_MainPS
	#else
		#define	MULTILAYER_OUTPUT_PS		MultilayerPVL_OutputPS
		#define MULTILAYER_INPUT_PS			MultilayerPPL_OutputVS
		#define MULTILAYER_MAIN_PS			MultilayerPPL_MainPS
	#endif
#else
	#ifdef _LIGHT0_SPOT
		#define	MULTILAYER_OUTPUT_PS		MultilayerPVL_OutputPS
		#define MULTILAYER_INPUT_PS			MultilayerPVLSpot_OuputVS
		#define MULTILAYER_MAIN_PS			MultilayerPVLSpot_MainPS
	#else
		#define	MULTILAYER_OUTPUT_PS		MultilayerPVL_OutputPS
		#define MULTILAYER_INPUT_PS			MultilayerPVL_OuputVS
		#define MULTILAYER_MAIN_PS			MultilayerPVL_MainPS
	#endif
#endif

void MultilayerPPL_MainPS(MultilayerPPL_OutputVS inData			,	out MultilayerPVL_OutputPS outResult);
void MultilayerPPLSpot_MainPS(MultilayerPPLSpot_OutputVS inData,	out MultilayerPVL_OutputPS outResult);
void MultilayerPVL_MainPS(MultilayerPVL_OuputVS inData			,	out MultilayerPVL_OutputPS outResult);
void MultilayerPVLSpot_MainPS(MultilayerPVLSpot_OuputVS inData	,	out MultilayerPVL_OutputPS outResult);

uniform sampler2D g_diffuseMap			: register(s0);
#ifdef _MAP_ENVIROMENT_CUBE
	uniform samplerCUBE	g_enviromentMap	: register(s1);
#else
	uniform sampler2D	g_enviromentMap	: register(s1);
#endif
uniform sampler2D g_glossMap			: register(s2);
uniform sampler2D g_lightMap			: register(s3);
uniform sampler2D g_specularMap			: register(s4);
uniform sampler2D g_emissiveMap			: register(s5);
uniform sampler2D g_normalMap			: register(s6);
uniform sampler2D g_planarReflection	: register(s7);
uniform sampler2D g_spot1Map			: register(s8);
uniform sampler2D g_spot2Map			: register(s9);
uniform sampler2D g_diffuse2Map			: register(s10);

/// Tongas upload variables
#ifdef _VERTICAL_FOG
	float4		g_verticalFogColor;
	float4		g_verticalFogValues;
#endif

#ifdef _PIXEL_FOG
	float4		g_pixelFogColor;
	float4		g_pixelFogOptions;
#endif

#ifdef _PARALLAX
	float		g_fParallaxScale;
#endif

#if defined(_CAMERA_LIGHT) || defined(_RIM_FADING)
	float4		g_cameraDir;
	float4		g_cameraLightColor;
#endif

float4 g_lightMapColor;

#if defined(_MRT)
#define _MRT_DEFAULT_COLOR		float4(0,0,0,0)
#define _MRT_BLACK_COLOR		float4(0,0,0,1)

#ifndef _PIXEL_FOG
    float4		g_pixelFogOptions;
#endif

uniform float4		g_multilayerTextureOptions;

float4 getBloomOutput(float2 uvCoords,uniform sampler2D tex)
{
	float mulFactor = 0;

	if(g_emissiveColor.a>0)
		mulFactor = 1;

	#if !defined(_POINTSPRITE)
	float4  ret = float4(0,0,0,1);
	ret.g = g_emissiveColor.a;
	#else
	float4  ret = float4(0,1,0,1);
	#endif

	// Determinate the alpha color from the diffuse stage
	if (g_multilayerTextureOptions.x > 1)
	{
		/// Texture with additive blending
		float4 color = tex2D( tex, uvCoords );
		ret.a*= (color.r + color.g + color.b)*0.3333 * color.a;
	}	
	else if (g_multilayerTextureOptions.x > 0)
	{
		// Texture with alpha
		ret.a*= tex2D( tex, uvCoords ).a;
	}
	
	ret*=mulFactor;

	return ret;
}

#if !defined(_POINTSPRITE)
float4 getFocusBloomOutput(float opacity,float3 pos,float2 uvCoords,uniform sampler2D tex)
{
	float mulFactor = 0;

	if(g_emissiveColor.a>0)
		mulFactor = 1;
	if(opacity>=1)
		mulFactor = 1;

	float4  ret = float4(0,0,0,opacity);
	ret.g = g_emissiveColor.a*opacity;

	// Determinate the alpha color from the diffuse stage
	if (g_multilayerTextureOptions.x > 1)
	{
		/// Texture with additive blending
		float4 color = tex2D( tex, uvCoords );
		ret.a*= (color.r + color.g + color.b)*0.3333 * color.a;
	}	
	else if (g_multilayerTextureOptions.x > 0)
	{
		// Texture with alpha
		ret.a*= tex2D( tex, uvCoords ).a;
	}

	ret*=mulFactor;
    return ret;
}
#endif

#if defined(_MULTILAYER_CGFX)

//default output
float4 pso_MRT_default_output(MultilayerPPLSpot_OutputVS IN,float4 mainColor)
{
	return _MRT_DEFAULT_COLOR;
}

float4 pso_MRT_black_output(MultilayerPPLSpot_OutputVS IN,float4 mainColor)
{
	return _MRT_BLACK_COLOR;
}

float4 pso_MRT_blackBoolAlpha_output(MultilayerPPLSpot_OutputVS IN,float4 mainColor)
{
	return float4(_MRT_BLACK_COLOR.rgb,(mainColor.a>=1.0)?1.0:0.0);
}

float4 pso_MRT_default_output(MultilayerPPL_OutputVS IN,float4 mainColor)
{
	return _MRT_DEFAULT_COLOR;
}

float4 pso_MRT_black_output(MultilayerPPL_OutputVS IN,float4 mainColor)
{
	return _MRT_BLACK_COLOR;
}

float4 pso_MRT_blackBoolAlpha_output(MultilayerPPL_OutputVS IN,float4 mainColor)
{
	return float4(_MRT_BLACK_COLOR.rgb,(mainColor.a>=1.0)?1.0:0.0);
}

float4 pso_MRT_default_output(MultilayerPVLSpot_OuputVS IN,float4 mainColor)
{
	return _MRT_DEFAULT_COLOR;
}

float4 pso_MRT_black_output(MultilayerPVLSpot_OuputVS IN,float4 mainColor)
{
	return _MRT_BLACK_COLOR;
}

float4 pso_MRT_blackBoolAlpha_output(MultilayerPVLSpot_OuputVS IN,float4 mainColor)
{
	return float4(_MRT_BLACK_COLOR.rgb,(mainColor.a>=1.0)?1.0:0.0);
}

float4 pso_MRT_default_output(MultilayerPVL_OuputVS IN,float4 mainColor)
{
	return _MRT_DEFAULT_COLOR;
}

float4 pso_MRT_black_output(MultilayerPVL_OuputVS IN,float4 mainColor)
{
	return _MRT_BLACK_COLOR;
}

float4 pso_MRT_blackBoolAlpha_output(MultilayerPVL_OuputVS IN,float4 mainColor)
{
	return float4(_MRT_BLACK_COLOR.rgb,(mainColor.a>=1.0)?1.0:0.0);
}

float4 pso_MRT_focusBloom_output(MultilayerPPLSpot_OutputVS IN,float4 mainColor)
{
	#if !defined(_POINTSPRITE)
    return getFocusBloomOutput(mainColor.a,IN.vpos.xyz,IN.uv0.xy,g_diffuseMap);
	#else
	return getBloomOutput(IN.uv.xy,g_diffuseMap);
	#endif
}

float4 pso_MRT_focusBloom_output(MultilayerPPL_OutputVS IN,float4 mainColor)
{
    return getFocusBloomOutput(mainColor.a,IN.vpos.xyz,IN.uvcoords.xy,g_diffuseMap);
}

float4 pso_MRT_focusBloom_output(MultilayerPVLSpot_OuputVS IN,float4 mainColor)
{
    return getFocusBloomOutput(mainColor.a,IN.vpos.xyz,IN.uv0.xy,g_diffuseMap);
}

float4 pso_MRT_focusBloom_output(MultilayerPVL_OuputVS IN,float4 mainColor)
{
    return getFocusBloomOutput(mainColor.a,IN.vpos.xyz,IN.uv0.xy,g_diffuseMap);
}

#endif

//default output
#if defined(_COMPOSITE_CGFX)
#ifndef _POINTSPRITE
float4 pso_MRT_default_output(Composite_OutputVS IN,float4 mainColor)
{
	return _MRT_DEFAULT_COLOR;
}

float4 pso_MRT_black_output(Composite_OutputVS IN,float4 mainColor)
{
	return _MRT_BLACK_COLOR;
}

float4 pso_MRT_blackBoolAlpha_output(Composite_OutputVS IN,float4 mainColor)
{
	return float4(_MRT_BLACK_COLOR.rgb,(mainColor.a>=1.0)?1.0:0.0);
}

float4 pso_MRT_focusBloom_output(Composite_OutputVS IN,float4 mainColor)
{
    return getFocusBloomOutput(mainColor.a,IN.vpos.xyz,IN.uv0.xy,g_layer0);
}

#else
float4 pso_MRT_default_output(CompositeSprite_InputPS IN,float4 mainColor)
{
	return _MRT_DEFAULT_COLOR;
}

float4 pso_MRT_black_output(CompositeSprite_InputPS IN,float4 mainColor)
{
	return _MRT_BLACK_COLOR;
}

float4 pso_MRT_blackBoolAlpha_output(CompositeSprite_InputPS IN,float4 mainColor)
{
	return float4(_MRT_BLACK_COLOR.rgb,(mainColor.a>=1.0)?1.0:0.0);
}

float4 pso_MRT_focusBloom_output(CompositeSprite_InputPS IN,float4 mainColor)
{
	return getBloomOutput(IN.uv.xy,g_layer0);
}
#endif
#endif

#if defined(_MRT3) && !defined(_MRT2)
#define _MRT2
#endif

#if defined(_MRT2) && !defined(_MRT1)
#define _MRT1
#endif

#if defined(_MRT1) && !defined(_MRT1_OUTMETHOD)
	#define _MRT1_OUTMETHOD		pso_MRT_default_output
#endif

#if defined(_MRT2) && !defined(_MRT2_OUTMETHOD)
	#define _MRT2_OUTMETHOD		pso_MRT_default_output
#endif

#if defined(_MRT3) && !defined(_MRT3_OUTMETHOD)
	#define _MRT3_OUTMETHOD		pso_MRT_default_output
#endif
#endif

#if defined(_ALPHA_TEST)
float4		g_PixelAlphaTesting;
#endif

void main_PS(	MULTILAYER_INPUT_PS inData,out MULTILAYER_OUTPUT_PS outResult)
{
	MULTILAYER_MAIN_PS(inData,outResult);
    
	#if defined(_MRT1)
		outResult.color1 = _MRT1_OUTMETHOD(inData,outResult.color);
	#endif

	#if defined(_MRT2)
		outResult.color2 = _MRT2_OUTMETHOD(inData,outResult.color);
	#endif

	#if defined(_MRT3)
		outResult.color3 = _MRT3_OUTMETHOD(inData,outResult.color);
	#endif
	
	#if defined(_ALPHA_TEST)
		clip(outResult.color.a-g_PixelAlphaTesting.x);
	#endif
}

///////////////////////////////////////////////
// Omni & Direct Per Pixel PixelShader
///////////////////////////////////////////////
void MultilayerPPL_MainPS( MultilayerPPL_OutputVS inData,out MultilayerPVL_OutputPS outResult)
{
	outResult = (MultilayerPVL_OutputPS) 0;

	float3	view = normalize(inData.viewDir.xyz);
	
	#ifdef _PARALLAX
		inData.uvcoords.xy += (tex2D(g_normalMap, inData.uvcoords.xy).a * g_fParallaxScale - g_fParallaxScale*.5f ) * view;
	#endif
	
	// As the usage of the second diffuse is encoded on the lightmap, must retrieve that first
	#if defined (_MAP_LIGHTMAP) || defined (BLEND_DIFFUSE2_WITH_LIGHTMAPALPHA)
		float4 lightMapColor;
		float2 luv;
		luv.x = inData.lightDir0.w;
		luv.y = inData.lightDir1.w;
		lightMapColor = tex2D( g_lightMap, luv);
		lightMapColor.rgb *= g_lightMapColor.rgb;
		lightMapColor.rgb *= g_lightMapColor.a;
	#endif // _MAP_LIGHTMAP
	
	// Calculate the albedo color
	// Start with the vertex color, separate color from alpha for best processing
	// BLEND_DIFFUSE2_WITH_LIGHTMAPALPHA means that we merge to diffuse textures with the lighmap alpha color
	float3 albedo	= inData.color.rgb;
	float opacity 	= inData.color.a;
	
	#ifdef _MAP_DIFFUSE
		#ifdef BLEND_DIFFUSE2_WITH_LIGHTMAPALPHA
			// Merge both diffuse maps with the alpha color of the lightmap
			float4 albedoTexture = lerp(	tex2D( g_diffuseMap, inData.uvcoords.xy ), 
											tex2D( g_diffuse2Map, inData.uvcoords.xy ), 
											lightMapColor.a);
		#else
			float4 albedoTexture = tex2D( g_diffuseMap, inData.uvcoords.xy );
		#endif
		
		albedo*=albedoTexture.rgb;
				
		#if !defined(_ALPHACAMERALIGHTMASK) && !defined(_TRANSLUCENCY) && !defined(_ALPHAENVIROMENTMASK)
			opacity*=albedoTexture.a;
		#endif
	#endif
	
	/// Retrieve the normal for the model, this is in normal texture space
	float3 normal =  normalize( 2.0 * tex2D( g_normalMap, inData.uvcoords.xy ).rgb - 1.0 );	

	/// Calculate lighting	-----------------------------------------------------------------------
		
	// If we have a light with a shadowmap, lets retrieve it early for different objectives
	#ifdef __USE_SHADOWMAP
		#if defined (_LIGHT0_DIRECTIONAL)
			float shadow = GetShadowDirectional(inData.shadowProjection);		
		#elif defined ( _LIGHT0_POINT )
			float shadow = GetShadowPoint(inData.vpos.xyz);
		#endif
	#endif
	
	// Check for static lighting conditions (lightmap)
	// In the case of not having lightmaps, start with black
	#ifdef _MAP_LIGHTMAP
		outResult.color.rgb = 2.0f * albedo * lightMapColor.rgb;
		
		// Check if we must apply the shadow on the lightmap
		#ifdef _SHADOWLIGHTMAP
			outResult.color.rgb*=shadow;
		#endif
	#else
		outResult.color.rgb = 0;
	#endif
	
	/// Now proceed with dynamic lighting	
	float	fNDotL;					///< Auxiliary to calculate how does the light affects the surface
	float3	fvLightDir;				///< Auxiliary for the light direction
	float3	myLight		= 0;		///< This will acumulate the diffuse lighting	
	float3	mySpecular	= 0;		///< This will acumulate the specular lighting

	/// Calculate directional lighting		
	#if defined (_LIGHT0_DIRECTIONAL) && !defined(_ONLYSHADOW)
			LightDirectional_PPL_PS(inData.lightDir0.xyz, normal, view, g_lightColor0.xyz, g_lightSpecular0.xyz, myLight, mySpecular);
		#ifdef __USE_SHADOWMAP			
			myLight *= shadow;
			#ifndef _MATERIAL_NOSPECULAR
				mySpecular *= shadow;
			#endif
		#endif
	#endif
	
	#ifdef _LIGHT1_DIRECTIONAL		
		LightDirectional_PPL_PS(inData.lightDir1.xyz, normal, view, g_lightColor1.xyz, g_lightSpecular1.xyz, myLight, mySpecular);		
	#endif
	
	#ifdef _LIGHT2_DIRECTIONAL		
		LightDirectional_PPL_PS(inData.lightDir2.xyz, normal, view, g_lightColor2.xyz, g_lightSpecular2.xyz, myLight, mySpecular);
		
	#endif
	
	#ifdef _LIGHT3_DIRECTIONAL		
		LightDirectional_PPL_PS(inData.lightDir3.xyz, normal, view, g_lightColor3.xyz, g_lightSpecular3.xyz, myLight, mySpecular);		
	#endif
	
	
	#define myAmbientLight g_ambient.rgb
		
	/// Calculate point lights
	#if defined (_LIGHT0_POINT) && !defined(_ONLYSHADOW)	
		AddPointLightContributionTangentSpace(inData.lightDir0.xyz, g_lightPosition0.xyz, g_lightPosition0.w, g_lightColor0.rgb, g_lightSpecular0.rgb, 
												normal, view, inData.vpos, myLight, mySpecular);
		#ifdef __USE_SHADOWMAP		
			myLight *= shadow;
			#ifndef _MATERIAL_NOSPECULAR
				mySpecular *= shadow;
			#endif
		#endif
	#endif	
	
	#ifdef _LIGHT1_POINT
		AddPointLightContributionTangentSpace(inData.lightDir1.xyz, g_lightPosition1.xyz, g_lightPosition1.w, g_lightColor1.rgb, g_lightSpecular1.rgb, 
												normal, view, inData.vpos, myLight, mySpecular);
	#endif	
	
	#ifdef _LIGHT2_POINT
		AddPointLightContributionTangentSpace(inData.lightDir2.xyz, g_lightPosition2.xyz, g_lightPosition2.w, g_lightColor2.rgb, g_lightSpecular2.rgb, 
												normal, view, inData.vpos, myLight, mySpecular);
	#endif	
	
	#ifdef _LIGHT3_POINT
		AddPointLightContributionTangentSpace(inData.lightDir3.xyz, g_lightPosition3.xyz, g_lightPosition3.w, g_lightColor3.rgb, g_lightSpecular3.rgb, 
												normal, view, inData.vpos, myLight, mySpecular);
	#endif	
	
	#ifdef _NON_LIGHTED
		myLight = 1;
	#endif

	/// Apply the directional lighting to the output color
	outResult.color.rgb += albedo * (myLight * g_diffuseColor.rgb + myAmbientLight * g_ambientColor.rgb);

	/// If we got a specular map then proceed to get the specular color from it			
	#ifndef _MATERIAL_NOSPECULAR
		float3 mySpecularColor = g_specularColor.rgb;
		#ifdef _MAP_SPECULAR
			mySpecularColor	*= tex2D(g_specularMap,inData.uvcoords.xy ).rgb;
		#endif
		outResult.color.rgb += mySpecular * mySpecularColor;
	#endif
				
	/// Apply the enviromental using the gloss map
	#ifdef _MAP_PLANAR_REFLECTION
		float2 refCoords = inData.uvcoords.zw/inData.vpos.w;
		
		#ifdef _PARALLAX
			refCoords += normal * g_fParallaxScale;
		#else
			refCoords += normal * .01f;
		#endif

		float3 reflection = tex2D(g_planarReflection, refCoords);

		#ifdef _MAP_ENVIROMENTGLOSS
			reflection *= tex2D( g_glossMap, inData.uvcoords.xy );
		#endif
		
		outResult.color.rgb += reflection;
	#else
		#ifdef _MAP_ENVIROMENT
			#ifdef _MAP_ENVIROMENT_CUBE
				float3 enviroment = texCUBE( g_enviromentMap, float3(inData.uvcoords.zw, inData.vpos.w) ).rgb;
			#else
				float3 enviroment = tex2D( g_enviromentMap, inData.uvcoords.zw ).rgb;
			#endif
			
			#ifdef _MAP_ENVIROMENTGLOSS
				enviroment.rgb *= tex2D( g_glossMap, inData.uvcoords.xy ).rgb;
			#endif
			
			outResult.color.rgb += enviroment.rgb * g_enviromentColor.rgb;
		#endif
	#endif
		
	
	
	/// Apply emissive material color and map
	/// Then saturate the color
	outResult.color.rgb += g_emissiveColor.rgb;
	#ifdef _MAP_EMISSIVE
		#ifdef _EMISSIVE_FLIPBOOK
			inData.uvcoords.z = 1;
			float2 euv = inData.uvcoords.xy * g_textureTransform5.xy + g_textureTransform5.zw;
			outResult.color.rgb+= tex2D( g_emissiveMap, euv).rgb;
		#else
			outResult.color.rgb+= tex2D( g_emissiveMap, inData.uvcoords.xy).rgb;
		#endif
	#endif
	
	float fogValue;
	#ifdef _VERTICAL_FOG
		fogValue = saturate( (inData.vpos.y - g_verticalFogValues.x) / g_verticalFogValues.z);
		outResult.color.rgb =	lerp(g_verticalFogColor.rgb, outResult.color.rgb, fogValue);
	#endif

	#ifdef _PIXEL_FOG
		ComputeFog(outResult.color,g_pixelFogColor.rgb,distance(g_cameraPos.xyz, inData.vpos.xyz),g_pixelFogOptions.x,g_pixelFogOptions.z);
	#endif
	
	// Calculate the output alpha from the calculated opacity and from the material diffuse color
	outResult.color.a = opacity * g_diffuseColor.a;

	#ifdef _CAMERA_LIGHT
		float vdn = abs(dot(view,normal));
		vdn = saturate(vdn);
		vdn = 1 - vdn;
		vdn *= vdn;
		#ifdef _ALPHACAMERALIGHTMASK
		 vdn*=albedoTexture.a;
		#endif
		outResult.color.rgb += vdn * g_cameraLightColor.rgb;
	#endif

    #if defined(_RIM_FADING)
		outResult.color.a*=GetRimFading(g_cameraPos.xyz,inData.vpos.xyz,normal,g_RimFading.y);
    #endif
}

///////////////////////////////////////////////
// Spot Per Pixel PixelShader
///////////////////////////////////////////////
void MultilayerPPLSpot_MainPS( MultilayerPPLSpot_OutputVS inData,out MultilayerPVL_OutputPS outResult)
{	
	outResult = (MultilayerPVL_OutputPS)1;

	#ifdef _PARALLAX
		inData.uv0.xy += (tex2D(g_normalMap, inData.uv0.xy).a * g_fParallaxScale - g_fParallaxScale*.5f ) * normalize(inData.view);
	#endif
	
	float4 diffuseColor = tex2D( g_diffuseMap, inData.uv0.xy );
	
	/// Retrieve the normal for the model, this is in normal texture space
	float3 normal =  normalize( 2.0 * tex2D( g_normalMap, inData.uv0.xy ).rgb - 1.0 );	

	/// Calculate lighting		
	float	fNDotL;
	float	fNDotLSpot;
	float3	myLight		= 0;
	float3	fvLightDir;
	float4  lightColor;
	float	factor;
	float3	mySpecular	= 0;
	float3	Half;
	float3	view = 0;
	
	#if !defined(_MATERIAL_NOSPECULAR)
		view = normalize(inData.view.xyz);
	#endif
	
	#ifdef _LIGHT0_SPOT
		fvLightDir = g_lightPosition0.xyz - inData.vpos;
		LightSpot_PPL_PS(inData.lightDir0.xyz, normal, view, (dot(normalize(fvLightDir),-g_lightDirection0.xyz)>0) * inData.lightDir0.w, g_lightColor0, g_lightSpecular0, myLight, mySpecular, g_spot1Map, inData.spotProjection1);
		#ifdef __USE_SHADOWMAP
			float shadow = GetShadowSpot(inData.shadowProjection);
			myLight *= shadow;	
			#ifndef _MATERIAL_NOSPECULAR
				mySpecular *= shadow;
			#endif
		#endif
	#endif	
	
	#ifdef _LIGHT1_SPOT		
		fvLightDir = g_lightPosition1.xyz - inData.vpos;
		LightSpot_PPL_PS(inData.lightDir1.xyz, normal, view, (dot(normalize(fvLightDir),-g_lightDirection1.xyz)>0) * inData.lightDir1.w, g_lightColor1, g_lightSpecular1, myLight, mySpecular, g_spot2Map, inData.spotProjection2);
	#endif
		
	outResult.color.rgb = myLight * saturate(diffuseColor.rgb) * g_diffuseColor.rgb;

	#ifndef _MATERIAL_NOSPECULAR
		float3 mySpecularColor = g_specularColor.rgb;
		#ifdef _MAP_SPECULAR
			mySpecular *= tex2D(g_specularMap,inData.uv0.xy ).rgb;
		#endif
		outResult.color.rgb += mySpecular * mySpecularColor;
	#endif
	
	/// Apply alpha from the material diffuse color
	outResult.color.a = inData.color.a * g_diffuseColor.a * diffuseColor.a;

    #if defined(_RIM_FADING)
		outResult.color.a*=GetRimFading(g_cameraPos.xyz,inData.vpos.xyz,normal,g_RimFading.y);
    #endif
}

///////////////////////////////////////////////
// Omni & Direct Per Vertex PixelShader
///////////////////////////////////////////////
void MultilayerPVL_MainPS( MultilayerPVL_OuputVS inData,out MultilayerPVL_OutputPS outResult)
{
	outResult = (MultilayerPVL_OutputPS) 0;

	/// Determinate the surface diffuse color
	outResult.color = inData.color;
	
#ifndef _POINTSPRITE
	// Retrieve the albedo texture
	
	// As the usage of the second diffuse is encoded on the lightmap, must retrieve that first
	#if defined (_MAP_LIGHTMAP) || defined (BLEND_DIFFUSE2_WITH_LIGHTMAPALPHA)
		float4 lightMapColor;
		lightMapColor = tex2D( g_lightMap, inData.uv2);	
		lightMapColor.rgb *= g_lightMapColor.rgb;	
		lightMapColor.rgb *= g_lightMapColor.a;	
	#endif // _MAP_LIGHTMAP
	
	// Calculate the albedo color
	// Start with the vertex color, separate color from alpha for best processing
	// BLEND_DIFFUSE2_WITH_LIGHTMAPALPHA means that we merge to diffuse textures with the lighmap alpha color
	float3 albedo	= inData.color.rgb;
	float opacity 	= inData.color.a;
	
	#ifdef _MAP_DIFFUSE
		#if defined(BLEND_DIFFUSE2_WITH_LIGHTMAPALPHA)
			float4 albedoTexture = lerp(	tex2D( g_diffuseMap, inData.uv0.xy ), 
											tex2D( g_diffuse2Map, inData.uv0.xy ), 
											lightMapColor.a);
		#else
			float4 albedoTexture = tex2D( g_diffuseMap, inData.uv0.xy );
		#endif
		
		albedo*=albedoTexture.rgb;
				
		#if !defined(_ALPHACAMERALIGHTMASK) && !defined(_TRANSLUCENCY) && !defined(_ALPHAENVIROMENTMASK)
			opacity*=albedoTexture.a;
		#endif	
	#endif
	
	#if defined(_MAP_DIFFUSE) && defined( _TRANSLUCENCY)
		#define translucencyColor albedoTexture.a
	#else
		float translucencyColor = 0;
	#endif
	
	float3  normal = normalize(inData.normal);
	
	/// Calculate lighting
	// First we proceed with static lighting (lightmaps)
	
	// For the case of having a directional light with shadow, we
	// need the shadow value to apply it to the light map, before applying the ligh
	#ifdef __USE_SHADOWMAP 
		#if defined ( _LIGHT0_DIRECTIONAL )
			float shadow = GetShadowDirectional(inData.shadowProjection);	
		#elif defined (_LIGHT0_POINT )
			float shadow = GetShadowPoint(inData.vpos.xyz);
		#endif
	#endif
	
	/// First apply the light from the lightmap
	#ifdef _MAP_LIGHTMAP
		outResult.color.rgb = 2.0f * albedo * lightMapColor.rgb;
		#ifdef _SHADOWLIGHTMAP
			outResult.color.rgb*=shadow;
		#endif
	#else
		outResult.color.rgb = 0;
	#endif
	
	// Now proceed with dynamic lighting
	// We will acumulate the diffuse light on myLight and the specular light on mySpecular
	float	fNDotL		= 0;
	float3	myLight		= 0;
	float3	fvLightDir	= 0;
	float3	mySpecular	= 0;
	float3	view		= 0;
	
	#if !defined(_MATERIAL_NOSPECULAR)
		view = normalize(inData.view);
	#endif
	
	/// Calculate directional lighting		
	#if defined (_LIGHT0_DIRECTIONAL) && !defined(_ONLYSHADOW)
		LightDirectional_PVL_PS(-g_lightDirection0.xyz, normal, view, g_lightColor0.xyz, translucencyColor, g_lightSpecular0.xyz, myLight, mySpecular);
		
		#ifdef __USE_SHADOWMAP		
			myLight *= shadow;
			#ifndef _MATERIAL_NOSPECULAR
				mySpecular *= shadow;
			#endif
		#endif

	#endif
	
	#ifdef _LIGHT1_DIRECTIONAL		
		LightDirectional_PVL_PS(-g_lightDirection1.xyz, normal, view, g_lightColor1.xyz, translucencyColor, g_lightSpecular1.xyz, myLight, mySpecular);		
	#endif

	#ifdef _LIGHT2_DIRECTIONAL
		LightDirectional_PVL_PS(-g_lightDirection2.xyz, normal, view, g_lightColor2.xyz, translucencyColor, g_lightSpecular2.xyz, myLight, mySpecular);
	#endif

	#ifdef _LIGHT3_DIRECTIONAL
		LightDirectional_PVL_PS(-g_lightDirection3.xyz, normal, view, g_lightColor3.xyz, translucencyColor, g_lightSpecular3.xyz, myLight, mySpecular);		
	#endif
	
	#define myAmbientLight g_ambient.rgb	
	
	/// Calculate point lights
	#if defined (_LIGHT0_POINT) && !defined(_ONLYSHADOW)
		AddPointLightContributionWorldSpace(g_lightPosition0.xyz, g_lightPosition0.w, g_lightColor0.rgb, g_lightSpecular0.rgb,
											normal, view, inData.vpos.xyz, myLight, mySpecular );
		#ifdef __USE_SHADOWMAP
			myLight *= shadow;
			#ifndef _MATERIAL_NOSPECULAR
				mySpecular *= shadow;
			#endif
		#endif
	#endif
	
	#ifdef _LIGHT1_POINT
		AddPointLightContributionWorldSpace(g_lightPosition1.xyz, g_lightPosition1.w, g_lightColor1.rgb, g_lightSpecular1.rgb,
											normal, view, inData.vpos.xyz, myLight, mySpecular );
	#endif
	
	#ifdef _LIGHT2_POINT
		AddPointLightContributionWorldSpace(g_lightPosition2.xyz, g_lightPosition2.w, g_lightColor2.rgb, g_lightSpecular2.rgb,
											normal, view, inData.vpos.xyz, myLight, mySpecular );
	#endif

	#ifdef _LIGHT3_POINT
		AddPointLightContributionWorldSpace(g_lightPosition3.xyz, g_lightPosition3.w, g_lightColor3.rgb, g_lightSpecular3.rgb,
											normal, view, inData.vpos.xyz, myLight, mySpecular );		
	#endif

	#ifdef _NON_LIGHTED
		myLight = 1;
	#endif

	outResult.color.rgb += albedo * (myLight * g_diffuseColor.rgb + myAmbientLight * g_ambientColor.rgb);
		
	/// If we got a specular map then proceed to get the specular color from it	
	#ifndef _MATERIAL_NOSPECULAR
		float3 mySpecularColor = g_specularColor.rgb;
		#ifdef _MAP_SPECULAR
			mySpecularColor	*= tex2D(g_specularMap,inData.uv0.xy ).rgb;
		#endif
		outResult.color.rgb+= mySpecular * mySpecularColor;
	#endif
	
	
	/// Apply the enviromental using the gloss map
	#ifdef _MAP_PLANAR_REFLECTION
		float3 reflection = tex2D(g_planarReflection, inData.uv1.xy/inData.uv1.z);

		#ifdef _MAP_ENVIROMENTGLOSS
			reflection *= tex2D( g_glossMap, inData.uv0.xy );
		#endif
		
		outResult.color.rgb += reflection;
	#else
		#ifdef _MAP_ENVIROMENT
			#ifdef _MAP_ENVIROMENT_CUBE
				float3 enviroment = texCUBE( g_enviromentMap, inData.uv1.xyz );
			#else
				float3 enviroment = tex2D( g_enviromentMap, inData.uv1.xy );
			#endif
		
			#ifdef _MAP_ENVIROMENTGLOSS
				enviroment *= tex2D( g_glossMap, inData.uv0.xy );
			#endif
		
			outResult.color.rgb += enviroment * g_enviromentColor.rgb;
		#endif
	#endif

	
	/// Apply emissive material color and map
	/// Then saturate the color
	outResult.color.rgb +=g_emissiveColor.rgb;
	#ifdef _MAP_EMISSIVE
		#ifdef _EMISSIVE_FLIPBOOK
			float2 euv = inData.uv0.xy * g_textureTransform5.xy + g_textureTransform5.zw;
			outResult.color.rgb+= tex2D( g_emissiveMap, euv).rgb;
		#else
			outResult.color.rgb+= tex2D( g_emissiveMap, inData.uv0.xy).rgb;
		#endif
	#endif

	float fogValue;
	#ifdef _VERTICAL_FOG
		fogValue = saturate( (inData.vpos.y - g_verticalFogValues.x) / g_verticalFogValues.z);
		outResult.color.rgb =	lerp(g_verticalFogColor.rgb, outResult.color.rgb, fogValue);
	#endif
	
	#ifdef _PIXEL_FOG
		ComputeFog(outResult.color,g_pixelFogColor.rgb,distance(g_cameraPos.xyz, inData.vpos.xyz),g_pixelFogOptions.x,g_pixelFogOptions.z);
	#endif
	
	// Calculate the output alpha from the calculated opacity and from the material diffuse color
	outResult.color.a = opacity * g_diffuseColor.a;
	
	#ifdef _CAMERA_LIGHT
		float vdn = abs(dot(g_cameraDir,normal));
		vdn = saturate(vdn);
		vdn = 1 - vdn;
		vdn *= vdn;
		#ifdef _ALPHACAMERALIGHTMASK
			vdn *= albedoTexture.a;		
		#endif
		outResult.color.rgb += vdn * g_cameraLightColor.rgb;
	#endif

    #if defined(_RIM_FADING)
		outResult.color.a*=GetRimFading(g_cameraPos.xyz,inData.vpos.xyz,normal,g_RimFading.y);
    #endif

#else//POINTSPRITE
	
	float2 uv = inData.uv;
	outResult.color = tex2D( g_diffuseMap, uv);

#endif
}

///////////////////////////////////////////////
// Spot Per Vertex PixelShader
///////////////////////////////////////////////
void MultilayerPVLSpot_MainPS( MultilayerPVLSpot_OuputVS inData,out MultilayerPVL_OutputPS outResult)
{	
	outResult = (MultilayerPVL_OutputPS)0;

	outResult.color = inData.color;
	float4 diffuseColor = tex2D( g_diffuseMap, inData.uv0.xy );
	
	///////	Calculate lighting
	float	fNDotL;
	float	fNDotLSpot;
	float3	myLight = 0;
	float3	fvLightDir;
	float	factor;
	float4	lightColor;
	float3	Half;
	float3	mySpecular	= 0;

	float3 view = 0;
	
	#if !defined(_MATERIAL_NOSPECULAR)
		view	= normalize(inData.view);
	#endif
	
	inData.normal	= normalize(inData.normal);
	
	#ifdef _LIGHT0_SPOT
		fvLightDir = g_lightPosition0.xyz - inData.vpos;
		if(dot(normalize(fvLightDir),-g_lightDirection0.xyz)>0)
			LightSpot_PVL_PS(normalize(inData.lightDir0.xyz), inData.normal, view, inData.lightDir0.w, g_lightColor0, g_lightSpecular0, myLight, mySpecular, g_spot1Map, inData.spotProjection1);
		
		#ifdef __USE_SHADOWMAP
			float shadow = GetShadowSpot(inData.shadowProjection);
			myLight *= shadow;
		
			#ifndef _MATERIAL_NOSPECULAR
				mySpecular *= shadow;
			#endif
		#endif
	#endif	
	
	#ifdef _LIGHT1_SPOT
		fvLightDir = g_lightPosition1.xyz - inData.vpos;
		if(dot(normalize(fvLightDir),-g_lightDirection1.xyz)>0)
			LightSpot_PVL_PS(normalize(inData.lightDir1.xyz), inData.normal, view, inData.lightDir1.w, g_lightColor1, g_lightSpecular1, myLight, mySpecular, g_spot2Map, inData.spotProjection2);
	#endif	
	
	outResult.color.rgb = myLight * diffuseColor.rgb * g_diffuseColor.rgb;

	/// If we got a specular map then proceed to get the specular color from it	
	#ifndef _MATERIAL_NOSPECULAR
		#ifdef _MAP_SPECULAR
			mySpecular	*= tex2D(g_specularMap,inData.uv0.xy ).rgb;
		#endif
		outResult.color.rgb += mySpecular;
	#endif
	
	/// Apply alpha from the material diffuse color
	outResult.color.a = inData.color.a * g_diffuseColor.a * diffuseColor.a;

    #if defined(_RIM_FADING)
		outResult.color.a*=GetRimFading(g_cameraPos.xyz,inData.vpos.xyz,inData.normal,g_RimFading.y);
    #endif
}

#endif

#define _SIMPLE_CGFX

// In the case low, med or high shadows are used, we are using shadows!
#if defined (_SHADOW_LOW) || defined (_SHADOW_MED) || defined(_SHADOW_HI)
	#define __USE_SHADOWMAP
#endif



//////////////////////////////////////
// MATRIX MULTIPLICATION
//////////////////////////////////////
float3 Transform(float3x3 mat, float3 v)
{
#if defined(_XENON)
	[isolate]
	{
		return mul(mat, v);
	}
#elif defined(_GCM)
	return mul(v, mat);
#else
	return mul(mat, v);
#endif
}

float4 Transform(float4x4 mat, float4 v)
{
#if defined(_XENON)
	[isolate]
	{
		return mul(mat, v);
	}
#elif defined(_GCM)
	return mul(v, mat);
#else
	return mul(mat, v);
#endif

}

float2 Transform(float2x2 mat, float2 v)
{
#if defined(_XENON)
	[isolate]
	{
		return mul(mat, v);
	}
#elif defined(_GCM)
	return mul(v, mat);
#else
	return mul(mat, v);
#endif

}

//this conversion will not deal with renormalizations because is a bad way to handle bad data passing to the shader.
//the main problem is that cg-compiler isn't as smart as hlsl-compiler dealing with already normalized vectors
float3x3 GetWorldToTangentMatrix(float3x3 worldmtx,float3 tangent, float3 normal)
{
	float3x3 worldToTangent = 0;
	worldToTangent[0] = normalize(Transform(worldmtx, tangent));
	worldToTangent[2] = normalize(Transform(worldmtx, normal));
	worldToTangent[1] = normalize(cross(worldToTangent[0], worldToTangent[2]));    

	return worldToTangent;
}

float4 TransformPlanarReflection(float4 inPos)
{
	float4x4	matTexScale = 0;

#if !defined(_GCM)
	matTexScale._m00 = 0.5f;
	matTexScale._m11 =  -.5f;
	matTexScale._m22 = 0.0f;
	matTexScale._m03 = 0.5f; 
	matTexScale._m13 = 0.5f;
	matTexScale._m23 = 1.0f; 
	matTexScale._m33 = 1.0f;
#else
	matTexScale._m00 = 0.5f;
	matTexScale._m11 = -0.5f;
	matTexScale._m22 = 0.0f;
	matTexScale._m30 = 0.5f; 
	matTexScale._m31 = 0.5f;
	matTexScale._m32 = 1.0f; 
	matTexScale._m33 = 1.0f;
#endif

	return Transform(matTexScale,inPos);
}

uniform float4x4	g_skinMatrix[_MAXBONES];		///< 128 Registers for skin bones

struct SKINVERTEX
{
	float4 P;
	float3 N;
	float3 T;
};

SKINVERTEX SkinVertex(float3 p, float3 n, float3 t, float4 indices, float4 weights)
{
	SKINVERTEX Out = (SKINVERTEX) 0;
	for(int i = 0; i < 4; i++)
	{
		Out.P.xyz += Transform(g_skinMatrix[indices.x], float4(p,1)).xyz * weights.x;
		Out.N += (float3)(Transform((float3x3) g_skinMatrix[indices.x], n) * weights.x);

		#if !defined(SH_VERSION_SH1)
		Out.T += (float3)(Transform((float3x3) g_skinMatrix[indices.x], t) * weights.x);
		#endif

		indices.xyzw = indices.yzwx;
		weights.xyzw = weights.yzwx;
	}

	Out.P.w = 1;
	Out.N = (float3)normalize(Out.N);
	
	#if !defined(SH_VERSION_SH1)
	Out.T = (float3)normalize(Out.T);
	#endif

	return Out;
}


//////////////////////////////////////
// VERTEX SHADER INPUT
//////////////////////////////////////
struct VSINPUT
{
	float4 pos		: POSITION;			///< Vertex position
	
#ifdef _USE_SKINMATRIX
	float4 weight	: BLENDWEIGHT;
	float4 indices	: BLENDINDICES;
#endif

#ifdef _HAS_NORMAL
	float3 normal	: NORMAL;			///< Vertex Normal
#endif

#ifdef _HAS_COLOR
	float4 color    : COLOR0;			///< Diffuse color of the vertex
#endif
	
	float2 uv0		: TEXCOORD0;		///< UV Coordinates for diffuse, enviroment and normal map

	#ifdef _HAS_UV1
		float2 uv1		: TEXCOORD1;		///< UV Coordinates
	#endif
};
//////////////////////////////////////
// END VERTEX SHADER INPUT
//////////////////////////////////////

//////////////////////////////////////
// VERTEX SHADER OUTPUT
//////////////////////////////////////
struct VSOUTPUT
{
	float4 hpos			: POSITION;		///< Clip space transformed vertex position
	float4 color		: COLOR0;		///< Vertex color
	float4 specular		: COLOR1;

#ifdef _PS3
	float3 uv0			: TEXCOORD0;	///< UV Coordinates used by the diffuse texture
#else
	float3 uv0			: TEXCOORD0_centroid;	///< UV Coordinates used by the diffuse texture
#endif
	float3 uv1			: TEXCOORD1;
#ifdef _PS3
	float4 vpos			: TEXCOORD2;	///< Position of the vertex in world space, and shadowprojection distance
#else
	float4 vpos			: TEXCOORD2_centroid;	///< Position of the vertex in world space, and shadowprojection distance
#endif

#ifdef _LIGHT0_SPOT
	float4 spot1Projection	: TEXCOORD3;	///< Shadow map projection
#endif

#ifdef _LIGHT1_SPOT
	float4 spot2Projection	: TEXCOORD4;	///< Shadow map projection
	float4 color2			: TEXCOORD5;		
	float4 specular2		: TEXCOORD6;		
#endif
	
#if defined(__USE_SHADOWMAP) && (defined(_LIGHT0_DIRECTIONAL) || defined(_LIGHT0_SPOT))
#ifdef _PS3
	float4 shadowProjection : TEXCOORD4;	///< Shadow map projection
#else
	float4 shadowProjection : TEXCOORD4_centroid;	///< Shadow map projection
#endif
#endif

	float4 refl		: TEXCOORD7;		///< UV Coordinates
};
//////////////////////////////////////
// END VERTEX SHADER OUTPUT
//////////////////////////////////////


//////////////////////////////////////
// LIGHTING
//////////////////////////////////////

/// Tongas upload variables
float4		g_ambient;
float4		g_ambientColor;
float4		g_diffuseColor;
float4		g_emissiveColor;
float4		g_specularColor;


//////////////////////////////////////
// LIGHTING INFO
float4		g_lightDirection0;
float4		g_lightPosition0;
float4		g_lightColor0;
float4		g_lightSpecular0;

#if defined(_LIGHT1_POINT) || defined(_LIGHT1_DIRECTIONAL) || defined(_LIGHT1_SPOT)
	float4		g_lightDirection1;
	float4		g_lightPosition1;
	float4		g_lightColor1;
	float4		g_lightSpecular1;
#endif


//////////////////////////////////////
// LIGHTING FUNCTIONS
void LightSpot_VS(float3 iDir, float Range, float3 normal, float3 view, float3 iD, float4 iS, inout float3 oD, inout float3 oS)
{
	float3 Factor = length(iDir.xyz);
	Factor = ( 1.0f - (Factor  / Range) );						

	float3 fvLightDir = normalize(iDir);
	float fNDotL = dot(normal, fvLightDir);		

	oD += iD * saturate(fNDotL) * Factor;
	
	#ifndef _MATERIAL_NOSPECULAR
		float3 Half = normalize(fvLightDir+view);
		oS += Factor * iS.xyz * pow(saturate(dot(Half,normal)), g_specularColor.a);
	#endif	
}

//////////////////////////////////////
// END LIGHTING
//////////////////////////////////////


uniform float4x4	g_matTextureProjection;
uniform float4		g_shadowmapOptions;
uniform float4		g_texelSize89;

#define 	g_ShadowmapFactor	(1-g_shadowmapOptions.x)	/// default 0.0
#define 	g_ShadowmapZBias	(g_shadowmapOptions.y)		/// default -0.001

uniform sampler2D	g_shadowMap			: register(s9);
uniform samplerCUBE	g_shadowCubeMap		: register(s9);

////////////////////////////////////
// DIRECTIONAL
float SampleShadowTest(float4 ShadowTexC)
{	
	#if defined(_XENON) || defined(_SHADOWMAP_FLOAT)	//Xenon & ATI
		return tex2D(g_shadowMap, ShadowTexC.xy).r >= ShadowTexC.z;		
	#else	//nVidia
		return tex2Dproj(g_shadowMap, ShadowTexC).r;
	#endif	
}

float GetShadowDirectional(float4 TexCoords)
{
	float4 ShadowTexC = TexCoords;
	ShadowTexC.xy = 0.5 * TexCoords.xy + float2( 0.5, 0.5 );
	ShadowTexC.y = 1.f - ShadowTexC.y;

#ifdef _PS3
	ShadowTexC.z = ShadowTexC.z * .5f + .5f;
#endif

#ifdef _XENON
	ShadowTexC.xyz = ShadowTexC.xyz / ShadowTexC.w;
	
	// [BP] On xbox360 we are getting projected distances that are higher than 1
	// as they are not being cut by the far plane of the light frustum
	// still we need to study more this effect, even check if it can be done on vertex
	// shader stage to save gpu process
	ShadowTexC.z = min(1,ShadowTexC.z); 	// Check that z the minimum value to 1
#endif
	
#ifdef _DEBUG_SHADOWMAPS	
	//Dark regions out of shadow projection
	if(ShadowTexC.x < 0 ||
		ShadowTexC.y < 0 ||
		ShadowTexC.x > 1 ||
		ShadowTexC.y > 1)
		return 0;
#endif
	
	ShadowTexC.z += g_ShadowmapZBias;
	ShadowTexC.w = 1;
			
	#if defined(SH_VERSION_SH2) || defined(_SHADOW_LOW)
		return saturate(SampleShadowTest(ShadowTexC) + g_ShadowmapFactor);
	#else

		float4 tX = float4(g_texelSize89.z, 0, 0, 0) * 2;
		float4 tY = float4(0, g_texelSize89.w, 0, 0) * 2;
		float accum = 0;
 
		#if defined(_SHADOW_MED)
			accum += SampleShadowTest(ShadowTexC + tX * -.5 + tY * -.5);
			accum += SampleShadowTest(ShadowTexC + tX *  .5 + tY * -.5);
			accum += SampleShadowTest(ShadowTexC + tX * -.5 + tY *  .5);
			accum += SampleShadowTest(ShadowTexC + tX *  .5 + tY *  .5);
			return saturate((accum/4.f) + g_ShadowmapFactor);
		#elif defined(_SHADOW_HI)
			accum += SampleShadowTest(ShadowTexC + tX * -1 + tY * -1);
			accum += SampleShadowTest(ShadowTexC + tX *  0 + tY * -1);
			accum += SampleShadowTest(ShadowTexC + tX *  1 + tY * -1);
			accum += SampleShadowTest(ShadowTexC + tX * -1 + tY *  0);
			accum += SampleShadowTest(ShadowTexC + tX *  0 + tY *  0);
			accum += SampleShadowTest(ShadowTexC + tX *  1 + tY *  0);
			accum += SampleShadowTest(ShadowTexC + tX * -1 + tY *  1);
			accum += SampleShadowTest(ShadowTexC + tX *  0 + tY *  1);
			accum += SampleShadowTest(ShadowTexC + tX *  1 + tY *  1);	
			return saturate((accum/9.f) + g_ShadowmapFactor);
		#else
			return 1;
		#endif
	#endif	
}

/////////////////////////////////
// SPOT
//[VC]: why this is just a copy paste from spotdirectional???
float GetShadowSpotSample(float4 ShadowTexC)
{
	float shadow;

#if defined(_XENON) || defined(_SHADOWMAP_FLOAT)	//Xenon & ATI

	float a = tex2D(g_shadowMap, ShadowTexC.xy).r > ShadowTexC.z;
	float b = tex2D(g_shadowMap, ShadowTexC.xy + float2(g_texelSize89.z, 0)).r > ShadowTexC.z;
	float c = tex2D(g_shadowMap, ShadowTexC.xy + float2(0, g_texelSize89.w)).r > ShadowTexC.z;
	float d = tex2D(g_shadowMap, ShadowTexC.xy + float2(g_texelSize89.z, g_texelSize89.w)).r > ShadowTexC.z;

#if defined(SH_VERSION_SH2)
	return a;
#endif
	
    // transform to texel space
    float2 texelpos = (1.f/g_texelSize89.zw) * ShadowTexC;
    
    // Determine the lerp amounts           
    float2 lerps = frac( texelpos );

    // lerp between the shadow values to calculate our light amount
    shadow = lerp( lerp( a, b, lerps.x ),
                   lerp( c, d, lerps.x ),
                   lerps.y );		
	return shadow;

#else	//nVidia

	shadow = tex2Dproj(g_shadowMap, ShadowTexC).r;

#endif
	
	return shadow;
}

float GetShadowSpot(float4 TexCoords)
{
	float4 ShadowTexC = TexCoords;
	ShadowTexC.xy = 0.5 * TexCoords.xy / TexCoords.w + float2( 0.5, 0.5 );
	ShadowTexC.y = 1.0f - ShadowTexC.y;

	//not needed for spot lights
#ifdef _PS3
	//ShadowTexC.z = ShadowTexC.z * .5f + .5f;
#endif

#ifdef _DEBUG_SHADOWMAPS	
	//Dark regions out of shadow projection
	if(ShadowTexC.x < 0 ||
		ShadowTexC.y < 0 ||
		ShadowTexC.x > 1 ||
		ShadowTexC.y > 1)
		return 0;
#endif
		
	ShadowTexC.z += g_ShadowmapZBias;
	ShadowTexC.z /= ShadowTexC.w;

	ShadowTexC.w = 1;
			
#if defined(SH_VERSION_SH2) || defined(_SHADOW_LOW)

	return saturate(GetShadowSpotSample(ShadowTexC) + g_ShadowmapFactor);
	
#endif

	float4 tX = float4(g_texelSize89.z, 0, 0, 0) * 1;
	float4 tY = float4(0, g_texelSize89.w, 0, 0) * 1;

	float accum = 0;

#if defined(_SHADOW_MED)
	accum += GetShadowSpotSample(ShadowTexC + tX * -.5 + tY * -.5);
	accum += GetShadowSpotSample(ShadowTexC + tX *  .5 + tY * -.5);
	accum += GetShadowSpotSample(ShadowTexC + tX * -.5 + tY *  .5);
	accum += GetShadowSpotSample(ShadowTexC + tX *  .5 + tY *  .5);	
	return saturate((accum/4.f) + g_ShadowmapFactor);
#endif
	
#if defined(_SHADOW_HI)
	accum += GetShadowSpotSample(ShadowTexC + tX * -1 + tY * -1);
	accum += GetShadowSpotSample(ShadowTexC + tX *  0 + tY * -1);
	accum += GetShadowSpotSample(ShadowTexC + tX *  1 + tY * -1);
	accum += GetShadowSpotSample(ShadowTexC + tX * -1 + tY *  0);
	accum += GetShadowSpotSample(ShadowTexC + tX *  0 + tY *  0);
	accum += GetShadowSpotSample(ShadowTexC + tX *  1 + tY *  0);
	accum += GetShadowSpotSample(ShadowTexC + tX * -1 + tY *  1);
	accum += GetShadowSpotSample(ShadowTexC + tX *  0 + tY *  1);
	accum += GetShadowSpotSample(ShadowTexC + tX *  1 + tY *  1);
	return saturate((accum/9.f) + g_ShadowmapFactor);
#endif

	return 1;
}


/////////////////////////////////
// POINT

float GetShadowPointSample(float3 Pos)
{
	float shadow = 1;

#ifdef _LIGHT0_POINT
	shadow = texCUBE(g_shadowCubeMap, Pos.xyz-g_lightPosition0.xyz).r > (length(Pos.xyz-g_lightPosition0.xyz) * g_lightPosition0.w) + g_ShadowmapZBias;
#endif

	return shadow;
}

float GetShadowPoint(float3 Pos)
{
	return saturate(GetShadowPointSample(Pos) + g_ShadowmapFactor);
}


//////////////////////////////////////
//VERTEX SHADER
//////////////////////////////////////

//////////////////////////////////////
// VERTEX SHADER CONSTANTS
//float4x4	g_matWorld, g_matWorldTR, g_matWorldView, g_matWorldViewIT, g_matWorldViewProjection;
float4x4	g_matWorld, g_matWorldView, g_matWorldViewProjection;
float4x4	g_matTexture0, g_matTexture1, g_matTexture2, g_matTexture3;
float4		g_cameraPos;



//////////////////////////////////////
// VERTEX SHADER
VSOUTPUT main_VS(VSINPUT IN)
{
	VSOUTPUT OUT = (VSOUTPUT) 0;
	
	OUT.color	= float4(1,1,1,1);
	float3 normal = float3(0,0,1);
		
	#ifdef _HAS_NORMAL
		normal = normalize(IN.normal);
	#endif
		
	#ifdef _HAS_COLOR
		OUT.color	= IN.color;
	#endif
	
	
	#ifdef _USE_SKINMATRIX	
		SKINVERTEX v = SkinVertex(IN.pos, normal,0, IN.indices, IN.weight);

		float4 position	= v.P;
		normal = v.N;
	#else
		float4 position	= IN.pos;
	#endif //_USE_SKINMATRIX

	
	/// Transform the position to clip space
	OUT.hpos	= Transform(g_matWorldViewProjection, position);
	OUT.vpos	= Transform(g_matWorld, position);
	
	OUT.uv0 = float3(IN.uv0, 1);
	OUT.uv1 = float3(IN.uv0, 1);

	#ifdef _HAS_UV1
		OUT.uv1 = float3(IN.uv1, 1);
	#endif

#ifndef _NON_LIGHTED

	float	fNDotL		= 0;
	float3	myLight		= 0;
	float3	fvLightDir	= 0;
	float	lightFactor	= 0;

	float3	Half		= 0;
	float3	mySpecular	= 0;
	float3	view		= -normalize(OUT.vpos-g_cameraPos);

	
	#ifdef _LIGHT0_DIRECTIONAL		
		fNDotL		= dot(normal, -g_lightDirection0);		
		myLight		+= g_lightColor0.rgb * saturate(max(0, fNDotL));
		
		#ifndef _MATERIAL_NOSPECULAR
			Half = normalize(-g_lightDirection0 + view);	
			mySpecular	+= g_lightSpecular0 * pow(max(0, dot(Half,normal)), g_specularColor.a);
		#endif
	
		#ifdef __USE_SHADOWMAP
			OUT.shadowProjection = Transform(g_matTextureProjection, float4(position.xyz,1));
		#endif
	#endif

	#ifdef _LIGHT1_DIRECTIONAL		
		fNDotL		= dot(normal, -g_lightDirection1);		
		myLight		+= g_lightColor1.rgb * saturate(max(0, fNDotL));
		
		#ifndef _MATERIAL_NOSPECULAR
			Half = normalize(-g_lightDirection1 + view);	
			mySpecular	+= g_lightSpecular1 * pow(max(0, dot(Half,normal)), g_specularColor.a);
		#endif
		
	#endif
	
	#ifdef _LIGHT0_POINT
		lightFactor = length(g_lightPosition0.xyz - OUT.vpos);
		lightFactor = saturate(1.0f - (lightFactor  / g_lightPosition0.w));
		
		fvLightDir = normalize(g_lightPosition0.xyz - OUT.vpos);		
		fNDotL = dot(normal, fvLightDir);		
		myLight += g_lightColor0.rgb * saturate(max(0, fNDotL)) * lightFactor;				
		
		#ifndef _MATERIAL_NOSPECULAR
			Half = normalize(fvLightDir+view);
			mySpecular	+= lightFactor * g_lightSpecular0 * pow(max(0, dot(Half,normal)), g_specularColor.a);
		#endif

	#endif
	
	#ifdef _LIGHT1_POINT
		lightFactor = length(g_lightPosition1.xyz - OUT.vpos);
		lightFactor = saturate(1.0f - (lightFactor  / g_lightPosition1.w));

		fvLightDir	= normalize(g_lightPosition1.xyz - OUT.vpos);		
		fNDotL		= dot(normal, fvLightDir);		
		myLight	+= g_lightColor1.rgb * saturate(max(0, fNDotL)) * lightFactor;				

		#ifndef _MATERIAL_NOSPECULAR
			Half = normalize(fvLightDir+view);
			mySpecular += lightFactor * g_lightSpecular1 * pow(max(0, dot(Half,normal)), g_specularColor.a);
		#endif
	#endif


	#ifdef _LIGHT0_SPOT
		OUT.color.xyz = OUT.specular.xyz = 0;
		
		LightSpot_VS(g_lightPosition0.xyz - OUT.vpos.xyz, g_lightPosition0.w, normal, view, g_lightColor0.rgb, g_lightSpecular0, OUT.color.xyz, OUT.specular.xyz);

		OUT.spot1Projection = Transform(g_matTexture2, float4(position.xyz,1));

		OUT.color *= g_diffuseColor;
		OUT.specular *= g_specularColor;

		#ifdef __USE_SHADOWMAP
			OUT.shadowProjection = Transform(g_matTextureProjection, float4(position.xyz,1));
		#endif
	#endif

	#ifdef _LIGHT1_SPOT
		OUT.color2.xyz = OUT.specular2.xyz = 0;
		
		LightSpot_VS(g_lightPosition1.xyz - OUT.vpos.xyz, g_lightPosition1.w, normal, view, g_lightColor1.rgb, g_lightSpecular0, OUT.color2.xyz, OUT.specular2.xyz);

		OUT.spot2Projection = Transform(g_matTexture3, float4(position.xyz,1));
		
		OUT.color2 *= g_diffuseColor;
		OUT.specular2 *= g_specularColor;
	#endif
	
	#ifndef _LIGHT0_SPOT
		OUT.color.rgb *= myLight * g_diffuseColor;
	
		#ifndef _MATERIAL_NOSPECULAR
			OUT.specular.rgb = mySpecular * g_specularColor.rgb;
		#endif
	#endif
	
#else
	
	OUT.color.rgb = g_diffuseColor;
	
#endif //_NON_LIGHTED

	OUT.color.a = g_diffuseColor.a;
	
	return( OUT );
}

//////////////////////////////////////
// END VERTEX SHADER
//////////////////////////////////////


//////////////////////////////////////
//PIXEL SHADERS
//////////////////////////////////////

//////////////////////////////////////
// SAMPLERS
sampler		g_layer0			: register(s0);
sampler		g_spotMap1			: register(s8);
sampler		g_spotMap2			: register(s9);


///////////////////////////////////////////////
// PIXEL SHADER
///////////////////////////////////////////////
float4 main_PS( VSOUTPUT IN
				#if defined(_MRT1)
				,out float4 oColor1 : COLOR1
				#endif
				#if defined(_MRT2)
				,out float4 oColor2 : COLOR2
				#endif
				#if defined(_MRT3)
				,out float4 oColor3 : COLOR3
				#endif
			   )	: COLOR0
{
	float3 shadow = 1;
	
	float4 OUT = 0;

	float4 Layer0 = tex2D(g_layer0, IN.uv0);
	
	OUT.a = IN.color.a * Layer0.a;
	
	#ifndef _LIGHT0_SPOT

		OUT.rgb = IN.color * Layer0;

		#ifndef _MATERIAL_NOSPECULAR
			OUT.rgb += IN.specular.xyz;
		#endif
		
		#ifdef __USE_SHADOWMAP

			#ifdef _LIGHT0_DIRECTIONAL
				shadow = GetShadowDirectional(IN.shadowProjection);
			#endif

			#ifdef _LIGHT0_POINT
				shadow = GetShadowPoint(IN.vpos.xyz);
			#endif			
			
		#endif
	#endif

	#ifdef _LIGHT0_SPOT
		
		float3 spot1 = tex2Dproj(g_spotMap1, IN.spot1Projection);
		OUT.rgb = IN.color * spot1 * Layer0;

		#ifndef _MATERIAL_NOSPECULAR
			OUT.rgb += IN.specular.xyz * spot1;
		#endif

		#ifdef __USE_SHADOWMAP
			shadow = GetShadowSpot(IN.shadowProjection);
		#endif

	#endif

	#ifdef _LIGHT1_SPOT

		float3 spot2 = tex2Dproj(g_spotMap2, IN.spot2Projection);
		
		OUT.rgb += IN.color2 * spot2 * Layer0;

		#ifndef _MATERIAL_NOSPECULAR
			OUT.rgb += IN.specular2.xyz * spot2;
		#endif

	#endif
	
	#ifdef __USE_SHADOWMAP
	
		#ifndef _LIGHT0_SPOT
			shadow += Layer0 * g_ambient.rgb * g_ambientColor;
		#endif
		
		OUT.rgb *= shadow;
		
	#elif !defined(_LIGHT0_SPOT)
		
		OUT.rgb += Layer0 * g_ambient.rgb * g_ambientColor;
		
	#endif

	return OUT;
}

struct VSI_SCREEN
{
	float4 pos		: POSITION;
	float4 color    : COLOR0;
	float2 uv		: TEXCOORD0;
};

struct VSO_SCREEN
{
	float4 pos		: POSITION;
#ifdef _PS3
	float2 uv		: TEXCOORD0;
#else
	float2 uv		: TEXCOORD0_centroid;
#endif
};


////////////////////////////////////////////////////
// bloom3_filterScreen
////////////////////////////////////////////////////
sampler sceneTexture			: register(s0);
sampler brightTexture			: register(s1);

#ifndef _GCM
float4 g_screenFilterValues[9];	///< 9 tap distance filter values
#else
DECLARE_GCM_FILTERVALUES9
#endif
float4 g_bloomBrightness;		///< Brightness fitering options
float4 g_texelSize01;

VSO_SCREEN vsFilterScreen( VSI_SCREEN IN )
{
	VSO_SCREEN OUT	= (VSO_SCREEN) 0;        
    OUT.pos			= IN.pos;
	OUT.uv			= IN.uv;
	return OUT;
}

float4 psFilterScreen( VSO_SCREEN IN
						#if defined(_MRT1)
						,out float4 oColor1 : COLOR1
						#endif
						#if defined(_MRT2)
						,out float4 oColor2 : COLOR2
						#endif
						#if defined(_MRT3)
						,out float4 oColor3 : COLOR3
						#endif
					  ) : color
{
	#ifdef _GCM
	INIT_GCM_FILTERVALUES9
	#endif
	float4	color = { 0.0f, 0.0f, 0.0f, 0.0f };
	float2 uv;
	
	/// Compine the textures in a 9 tap distance filter
	//float totalLum = 0;
	for( int i = 0; i < 9; i++ )
	{
		uv = IN.uv + g_screenFilterValues[i].xy * 2 + 2 *g_texelSize01.xy;
		color += tex2D( sceneTexture,  uv) *
				 tex2D( brightTexture, uv).g;				 
	//	totalLum +=(color.r+color.g+color.b) *0.33;	
	}
	
	color /= 9; //totalLum; //9.0f;
	/// Determine the brightness of this particular pixel. 
	float luminance = dot( color.rgb, g_bloomBrightness.rgb);
	
	/// If this pixel satisfies the bright pass threshold it will
	/// be > 0.0 after this operation
	luminance = max( 0.0f, luminance - g_bloomBrightness.w);
	
	/// Muliply by the above predicate, use the sign() intrinsic
	/// to make sure that luminance is either 0.0 or 1.0, thus not
	/// scaling any bright pixels that are needed.
	color.rgb *= sign( luminance );
	
	/// Write the colour to the bright-pass render target
	color.a = 1.0f;
	
	return color;
}



////////////////////////////////////////////////////
// bloom3_gaussian
////////////////////////////////////////////////////
struct VS_OUTPUT
{
    float4	pos			: POSITION;
	float2	uv			: TEXCOORD0;
};

sampler tex0 : register( s0 );          ///< Whatever texture is set using IDirect3DDevice9::SetTexture( 0, ... )

// -------------------------------------------------------------
// vertex shader function (input channels)
// -------------------------------------------------------------
VS_OUTPUT vsGaussianBlur(float4 pos : POSITION, float2 uv : TEXCOORD0)
{
    VS_OUTPUT Out;
    Out.pos.xy	= pos.xy;
	Out.pos.z	= 0.5f;
	Out.pos.w	= 1.0f;
	Out.uv		= uv;
    return Out;
}

float4 psGaussianBlur( in float2 t : TEXCOORD0 
						#if defined(_MRT1)
						,out float4 oColor1 : COLOR1
						#endif
						#if defined(_MRT2)
						,out float4 oColor2 : COLOR2
						#endif
						#if defined(_MRT3)
						,out float4 oColor3 : COLOR3
						#endif
					  ) : COLOR
{
	#ifdef _GCM
	INIT_GCM_FILTERVALUES9
	#endif
	
    float4 color = { 0.0f, 0.0f, 0.0f, 0.0f };  
    
    //float2 of = float2(g_texelSize01.x, - 1 * g_texelSize01.y);
       
	float fc = 0;
    float2 offset;
    /*
    for( int i = 0; i <3; i++ )
    {
		of.x = -1 * g_texelSize01.x;
    //    color += tex2D( tex0, float2(t.x,t.y) + tc + float2( g_screenFilterValues[i].x, g_screenFilterValues[i].y ) ) ; g_screenFilterValues[i].z;
		for (int j= 0; j < 3; j++)
		{
			of.x+= g_texelSize01.x;
			offset = of*5;
			color += tex2D( tex0, t + offset  + float2(g_texelSize01.x*2, g_texelSize01.y*2)); 
	
		}
		of.y +=g_texelSize01.y;
    }       
    
    
    /*
    float2 circle[9] = {
    float2 (-1,-1),
    float2 (0,-1),
    float2 (1, -1),
    float2 (-1,0),
    float2 (0,0),
    float2 (1, 0),
    float2 (-1,1),
    float2 (0,1),
    float2 (1, 1)
    };
    
    float factor[9] = {
    3,9,3,
    9,1,9,
    3,9,3
    };
    /**/
    
    float2 of = float2(g_texelSize01.x, 1 * g_texelSize01.y);
    
    for( int i = 0; i <9; i++ )
    {
		//color += tex2D( tex0, t + of * g_screenFilterValues[i].xy * g_screenFilterValues[i].w + float2(g_texelSize01.x*2, g_texelSize01.y*2)) * g_screenFilterValues[i].z; 
		color += tex2D( tex0, t + of * g_screenFilterValues[i].xy * g_screenFilterValues[i].w + 2 * g_texelSize01.xy) * g_screenFilterValues[i].z; 
		//color += tex2D( tex0, t + of * circle[i]* 2 + float2(g_texelSize01.x*2, g_texelSize01.y*2)) * factor[i]; 
		fc+=g_screenFilterValues[i].z;
		//fc+=factor[i];
	}
	
	color/=fc;
    color.a = 1;
    return color;
}
    


////////////////////////////////////////////////////
// bloom3_render
////////////////////////////////////////////////////
sampler bloom				: register(s0);
sampler original_scene		: register(s1);
sampler blur				: register(s2);
sampler focusBlur			: register(s3);
float4	g_bloomRenderOptions;
float4 g_auxiliary0;

#define g_exposure		g_bloomRenderOptions.x
#define g_blendFactor	g_bloomRenderOptions.y
#define g_doBlur		g_bloomRenderOptions.z
#define g_blurEffect	g_bloomRenderOptions.w

VSO_SCREEN vsRenderBloom( VSI_SCREEN IN )
{
	VSO_SCREEN OUT = (VSO_SCREEN) 0;        
    OUT.pos		= IN.pos;
    OUT.pos.z	= 0.5f;
    OUT.pos.w	= 1;
    OUT.uv = IN.uv;
	return OUT;
}

float4 g_kernelValues;
//float4 g_texelSize01;

float4 psRenderBloom( in float2 t : TEXCOORD0
					 	#if defined(_MRT1)
						,out float4 oColor1 : COLOR1
						#endif
						#if defined(_MRT2)
						,out float4 oColor2 : COLOR2
						#endif
						#if defined(_MRT3)
						,out float4 oColor3 : COLOR3
						#endif
						) : COLOR0
{
	t.x+=sin(g_kernelValues.y+t.x*16) * g_texelSize01.z * 4 * g_blurEffect;
	t.y+=cos(g_kernelValues.y+t.y*16) * g_texelSize01.w * 4 * g_blurEffect;
	float4 c = tex2D( original_scene, t );	
	
	/// Apply focus blur effect
	if (g_doBlur > 0)
	{
		float blurV = tex2D(focusBlur,t).r;		
		if (blurV > 0)
		{ 
			//blurV = blurV;
			c = lerp(c,tex2D(blur,t),blurV);		
		}
		
	}	
	
	c = c * g_exposure + g_blendFactor * tex2D( bloom, t);			
	/*
	c.r += sin(g_kernelValues.y*1.5) *0.5f * g_blurEffect;
	c.g += cos(g_kernelValues.y*2+23) * 0.5f * g_blurEffect;
	c.b += sin(g_kernelValues.y*1-15) * 0.5f * g_blurEffect;	
	/**/
	
	/**/
	c.r = lerp(c.r,1 - c.r,g_auxiliary0.x*0.5);	
	c.g = lerp(c.g,1 - c.g,g_auxiliary0.y*0.5);
	c.b = lerp(c.b,1 - c.b,g_auxiliary0.z*0.5);
	/**/
	
	
	c.a = 1.0f;		
	return c;
}


struct VSI_SCREEN
{
	float4 pos		: POSITION;
	float4 color    : COLOR0;
	float2 uv		: TEXCOORD0;
};

struct VSO_SCREEN
{
	float4 pos		: POSITION;
	float2 uv		: TEXCOORD0;
};


////////////////////////////////////////////////////
// Vertex Shaders
////////////////////////////////////////////////////
float4	g_bloomBrightness;

float4 g_texelSize01;

void main_VS(float4 iPos : POSITION,
		  float2 iTC : TEXCOORD0,
		  out float4 oPos : POSITION,
		  out float2 oTC[4] : TEXCOORD0)
{
	oPos = iPos;

	float2 texelSize = g_texelSize01.xy;

	float2 u = float2(1.f, 0) * g_bloomBrightness.w;
	float2 v = float2(0, 1.f) * g_bloomBrightness.w;	

	oTC[0] = (iTC - u - v) + texelSize.xy;
	oTC[1] = (iTC - u + v) + texelSize.xy;
	oTC[2] = (iTC + u - v) + texelSize.xy;
	oTC[3] = (iTC + u + v) + texelSize.xy;
}


void BrightPass_VS(float4 iPos : POSITION,
		  float2 iTC : TEXCOORD0,
		  out float4 oPos : POSITION,
		  out float2 oTC[2] : TEXCOORD0)
{
	oPos = iPos;

	float2 texelSize = g_texelSize01.xy;

	float2 u = float2(1.f, 0) * g_bloomBrightness.w;
	float2 v = float2(0, 1.f) * g_bloomBrightness.w;	

	oTC[0] = (iTC - u - v) + texelSize.xy;
	oTC[1] = (iTC - u + v) + texelSize.xy;	
}

void mainFinal_VS(float4 iPos : POSITION,
		  float2 iTC : TEXCOORD0,
		  out float4 oPos : POSITION,
		  out float2 oTC : TEXCOORD0,
		  out float2 oTC1 : TEXCOORD1)
{
	oPos = iPos;
	
	oTC = iTC + (g_texelSize01.xy * .5f);
	oTC1 = iTC + (g_texelSize01.zw * .5f);
}



////////////////////////////////////////////////////
// Pixel Shaders
////////////////////////////////////////////////////
sampler Tex				: register(s0);
sampler Bloom			: register(s1);

float4 main_PS(		float2 iTC[4] : TEXCOORD0
					#if defined(_MRT1)
					,out float4 oColor1 : COLOR1
					#endif
					#if defined(_MRT2)
					,out float4 oColor2 : COLOR2
					#endif
					#if defined(_MRT3)
					,out float4 oColor3 : COLOR3
					#endif
			   ) : COLOR0
{
	float3 colorSum = 0;
	
	for(int i = 0; i < 4; i++)
		colorSum += tex2D(Tex, iTC[i]).xyz * .25f;
	
	return float4(colorSum, 1);
}

float4 BrightPass_PS(float2 tc : TEXCOORD0,
					 float2 tc1 : TEXCOORD1
					#if defined(_MRT1)
					,out float4 oColor1 : COLOR1
					#endif
					#if defined(_MRT2)
					,out float4 oColor2 : COLOR2
					#endif
					#if defined(_MRT3)
					,out float4 oColor3 : COLOR3
					#endif
					 ) : COLOR0
{
	float3 c = tex2D(Tex, tc);
	
	if(dot(c, float3(.33,.33,.33)) < g_bloomBrightness.x)
		c = 0;
		
	return float4(c,1);
}

float4 FinalPass_PS(	float2 tc : TEXCOORD0,
						float2 tc1 : TEXCOORD1
						#if defined(_MRT1)
						,out float4 oColor1 : COLOR1
						#endif
						#if defined(_MRT2)
						,out float4 oColor2 : COLOR2
						#endif
						#if defined(_MRT3)
						,out float4 oColor3 : COLOR3
						#endif
				 ) : COLOR0
{
	float3 b = tex2D(Bloom, tc1).rgb * g_bloomBrightness.y;

	return float4(b,1);
}


float4 g_texelSize01;

void main_VS(float3 iPos : POSITION,
		  float2 iTC : TEXCOORD0,
		  out float4 oPos : POSITION,
		  out float2 oTC : TEXCOORD0)
{
	oPos = float4(iPos.xyz, 1);
	oTC = iTC + g_texelSize01.xy * .5f;
}


sampler2D tex	: register(s0);
float4 g_specialVector1;

float4 main_PS( float2 tc : TEXCOORD0
				#if defined(_MRT1)
				,out float4 oColor1 : COLOR1
				#endif
				#if defined(_MRT2)
				,out float4 oColor2 : COLOR2
				#endif
				#if defined(_MRT3)
				,out float4 oColor3 : COLOR3
				#endif
			   ) : COLOR
{
	return float4(tex2D(tex, tc).xyz, g_specialVector1.w);
}

#define _DEPTH_OF_FIELD_CGFX

//////////////////////////////////////
// MATRIX MULTIPLICATION
//////////////////////////////////////
float3 Transform(float3x3 mat, float3 v)
{
#if defined(_XENON)
	[isolate]
	{
		return mul(mat, v);
	}
#elif defined(_GCM)
	return mul(v, mat);
#else
	return mul(mat, v);
#endif
}

float4 Transform(float4x4 mat, float4 v)
{
#if defined(_XENON)
	[isolate]
	{
		return mul(mat, v);
	}
#elif defined(_GCM)
	return mul(v, mat);
#else
	return mul(mat, v);
#endif

}

float2 Transform(float2x2 mat, float2 v)
{
#if defined(_XENON)
	[isolate]
	{
		return mul(mat, v);
	}
#elif defined(_GCM)
	return mul(v, mat);
#else
	return mul(mat, v);
#endif

}

//this conversion will not deal with renormalizations because is a bad way to handle bad data passing to the shader.
//the main problem is that cg-compiler isn't as smart as hlsl-compiler dealing with already normalized vectors
float3x3 GetWorldToTangentMatrix(float3x3 worldmtx,float3 tangent, float3 normal)
{
	float3x3 worldToTangent = 0;
	worldToTangent[0] = normalize(Transform(worldmtx, tangent));
	worldToTangent[2] = normalize(Transform(worldmtx, normal));
	worldToTangent[1] = normalize(cross(worldToTangent[0], worldToTangent[2]));    

	return worldToTangent;
}

float4 TransformPlanarReflection(float4 inPos)
{
	float4x4	matTexScale = 0;

#if !defined(_GCM)
	matTexScale._m00 = 0.5f;
	matTexScale._m11 =  -.5f;
	matTexScale._m22 = 0.0f;
	matTexScale._m03 = 0.5f; 
	matTexScale._m13 = 0.5f;
	matTexScale._m23 = 1.0f; 
	matTexScale._m33 = 1.0f;
#else
	matTexScale._m00 = 0.5f;
	matTexScale._m11 = -0.5f;
	matTexScale._m22 = 0.0f;
	matTexScale._m30 = 0.5f; 
	matTexScale._m31 = 0.5f;
	matTexScale._m32 = 1.0f; 
	matTexScale._m33 = 1.0f;
#endif

	return Transform(matTexScale,inPos);
}

uniform float4x4	g_skinMatrix[_MAXBONES];		///< 128 Registers for skin bones

struct SKINVERTEX
{
	float4 P;
	float3 N;
	float3 T;
};

SKINVERTEX SkinVertex(float3 p, float3 n, float3 t, float4 indices, float4 weights)
{
	SKINVERTEX Out = (SKINVERTEX) 0;
	for(int i = 0; i < 4; i++)
	{
		Out.P.xyz += Transform(g_skinMatrix[indices.x], float4(p,1)).xyz * weights.x;
		Out.N += (float3)(Transform((float3x3) g_skinMatrix[indices.x], n) * weights.x);

		#if !defined(SH_VERSION_SH1)
		Out.T += (float3)(Transform((float3x3) g_skinMatrix[indices.x], t) * weights.x);
		#endif

		indices.xyzw = indices.yzwx;
		weights.xyzw = weights.yzwx;
	}

	Out.P.w = 1;
	Out.N = (float3)normalize(Out.N);
	
	#if !defined(SH_VERSION_SH1)
	Out.T = (float3)normalize(Out.T);
	#endif

	return Out;
}


////////////////////////////////////////////////////
// Vertex Shaders
////////////////////////////////////////////////////
float4	FocusZ	: register(c0);

float4 g_texelSize01, g_texelSize23;

void DOF_VS(float4 iPos : POSITION,
		  float2 iTC : TEXCOORD0,
		  out float4 oPos : POSITION,
		  out float2 oTC : TEXCOORD0)
{
	oPos = iPos;

	oTC = iTC;
}

float4x4	g_matWorldViewProjection, g_matWorldView;
float3x3	g_matWorld;

float4		g_kernelValues;

static float4 vFocalPlane = float4(0,0,1,1);
static float fHyperfocalDistance = 0.1f;
static float MaxBlurFactor = 3.0f / 4.0f;

void Object_VS(float4 iPos : POSITION,
#ifdef _USE_SKINMATRIX
			   float4 Indices : BLENDINDICES,
			   float4 Weights : BLENDWEIGHT,
#endif
			   out float4 oPos : POSITION,
			   out float oTC : TEXCOORD0)
{
#ifdef _USE_SKINMATRIX
	SKINVERTEX v = SkinVertex(iPos, 0, 0, Indices, Weights);
	iPos = v.P;
#endif

	oPos = Transform(g_matWorldViewProjection, iPos);

    float3 vViewPosition = Transform(g_matWorldView, iPos);
    
    vFocalPlane.w = -abs( sin( g_kernelValues.y * .1f ) ) * 70;
    
    float fBlurFactor = dot(float4(vViewPosition, 1.0), vFocalPlane) * fHyperfocalDistance;
    oTC = pow(fBlurFactor, 2);
}



////////////////////////////////////////////////////
// Pixel Shaders
////////////////////////////////////////////////////
sampler Original_Image	: register(s0);
sampler Depth_Image		: register(s1);
sampler Blur_Image		: register(s2);

float4 DOF_PS(float2 iTC : TEXCOORD0
			#if defined(_MRT1)
			,out float4 oColor1 : COLOR1
			#endif
			#if defined(_MRT2)
			,out float4 oColor2 : COLOR2
			#endif
			#if defined(_MRT3)
			,out float4 oColor3 : COLOR3
			#endif
			  ) : COLOR0
{
	float3 original = tex2D(Original_Image, iTC + g_texelSize01.xy * .5f);

	float d = 0;
	{
		float x = g_texelSize01.z*2;
		float y = g_texelSize01.w*2;
		d += tex2D(Depth_Image, iTC + float2(-x,-y)).r;
		d += tex2D(Depth_Image, iTC + float2(x,-y)).r;
		d += tex2D(Depth_Image, iTC + float2(-x,y)).r;
		d += tex2D(Depth_Image, iTC + float2(x,y)).r;
		
		d /= 4;
	}
	
	float3 blur = 0;
	{
		float x = g_texelSize23.x;
		float y = g_texelSize23.y;

		blur += tex2D(Blur_Image, iTC + float2(-x, -y) * 1);
		blur += tex2D(Blur_Image, iTC + float2(x, -y) * 1);
		blur += tex2D(Blur_Image, iTC + float2(-x, y) * 1);
		blur += tex2D(Blur_Image, iTC + float2(x, y) * 1);
	
		blur /= 4;
	}	
	
	return float4(original * (1-d) + blur * (d), 1);
}


float4 Object_PS(float iTC : TEXCOORD0
				#if defined(_MRT1)
				,out float4 oColor1 : COLOR1
				#endif
				#if defined(_MRT2)
				,out float4 oColor2 : COLOR2
				#endif
				#if defined(_MRT3)
				,out float4 oColor3 : COLOR3
				#endif				 
				 ) : COLOR0
{
	float d = iTC.x;
	return float4(d, d, d, d);
}

#ifdef _VERTEX_SHADER

#define _SHADOWMAP_CGFX

//////////////////////////////////////
// MATRIX MULTIPLICATION
//////////////////////////////////////
float3 Transform(float3x3 mat, float3 v)
{
#if defined(_XENON)
	[isolate]
	{
		return mul(mat, v);
	}
#elif defined(_GCM)
	return mul(v, mat);
#else
	return mul(mat, v);
#endif
}

float4 Transform(float4x4 mat, float4 v)
{
#if defined(_XENON)
	[isolate]
	{
		return mul(mat, v);
	}
#elif defined(_GCM)
	return mul(v, mat);
#else
	return mul(mat, v);
#endif

}

float2 Transform(float2x2 mat, float2 v)
{
#if defined(_XENON)
	[isolate]
	{
		return mul(mat, v);
	}
#elif defined(_GCM)
	return mul(v, mat);
#else
	return mul(mat, v);
#endif

}

//this conversion will not deal with renormalizations because is a bad way to handle bad data passing to the shader.
//the main problem is that cg-compiler isn't as smart as hlsl-compiler dealing with already normalized vectors
float3x3 GetWorldToTangentMatrix(float3x3 worldmtx,float3 tangent, float3 normal)
{
	float3x3 worldToTangent = 0;
	worldToTangent[0] = normalize(Transform(worldmtx, tangent));
	worldToTangent[2] = normalize(Transform(worldmtx, normal));
	worldToTangent[1] = normalize(cross(worldToTangent[0], worldToTangent[2]));    

	return worldToTangent;
}

float4 TransformPlanarReflection(float4 inPos)
{
	float4x4	matTexScale = 0;

#if !defined(_GCM)
	matTexScale._m00 = 0.5f;
	matTexScale._m11 =  -.5f;
	matTexScale._m22 = 0.0f;
	matTexScale._m03 = 0.5f; 
	matTexScale._m13 = 0.5f;
	matTexScale._m23 = 1.0f; 
	matTexScale._m33 = 1.0f;
#else
	matTexScale._m00 = 0.5f;
	matTexScale._m11 = -0.5f;
	matTexScale._m22 = 0.0f;
	matTexScale._m30 = 0.5f; 
	matTexScale._m31 = 0.5f;
	matTexScale._m32 = 1.0f; 
	matTexScale._m33 = 1.0f;
#endif

	return Transform(matTexScale,inPos);
}

uniform float4x4	g_skinMatrix[_MAXBONES];		///< 128 Registers for skin bones

struct SKINVERTEX
{
	float4 P;
	float3 N;
	float3 T;
};

SKINVERTEX SkinVertex(float3 p, float3 n, float3 t, float4 indices, float4 weights)
{
	SKINVERTEX Out = (SKINVERTEX) 0;
	for(int i = 0; i < 4; i++)
	{
		Out.P.xyz += Transform(g_skinMatrix[indices.x], float4(p,1)).xyz * weights.x;
		Out.N += (float3)(Transform((float3x3) g_skinMatrix[indices.x], n) * weights.x);

		#if !defined(SH_VERSION_SH1)
		Out.T += (float3)(Transform((float3x3) g_skinMatrix[indices.x], t) * weights.x);
		#endif

		indices.xyzw = indices.yzwx;
		weights.xyzw = weights.yzwx;
	}

	Out.P.w = 1;
	Out.N = (float3)normalize(Out.N);
	
	#if !defined(SH_VERSION_SH1)
	Out.T = (float3)normalize(Out.T);
	#endif

	return Out;
}


////////////////////////////////////////////////////
// Vertex Shaders
////////////////////////////////////////////////////

#ifdef _LIGHT0_POINT
	float4x4	g_matWorld;
#endif

float4x4	g_matWorldViewProjection;
float4x4	g_matTextureProjection;


void Object_VS(

				float3 inPos				: POSITION,			///< Untransformed vertex position
				#ifdef _USE_SKINMATRIX
					float4 inSkinIndices	: BLENDINDICES,		///< Skin vertex indices
					float4 inSkinWeights	: BLENDWEIGHT,		///< Skin vertex weights
				#endif
				#ifdef _MAP_DIFFUSE
					float2 inUV				: TEXCOORD0,		///< Vertex uv coordinates
				#endif
			   
			   out float4 outHPos	: POSITION,		///< Transformed vertex position
			   out float4 outVPos	: TEXCOORD0		///< Position of the vertex
			   #ifdef _MAP_DIFFUSE
				,out float2 outUV	: TEXCOORD1		///< UV coordinate for albedo Albedo
			   #endif
			   
			   )
{
	// Apply Skin to the Vertex
	#ifdef _USE_SKINMATRIX
		SKINVERTEX skin = SkinVertex(inPos.xyz,0,0, inSkinIndices, inSkinWeights);
		float4 nPos = skin.P;
	#else
		float4 nPos = float4(inPos, 1);		
	#endif

	// The matTextureProjection has the transformation (view and projection) of the light camera	
	outHPos = Transform(g_matTextureProjection, nPos);
    
	#ifdef _LIGHT0_POINT
		outVPos = Transform(g_matWorld, nPos);
	#else
		outVPos = outHPos;
	#endif

	// Copy the uv mapping, this is used to check for pixels with transparency
	#ifdef _MAP_DIFFUSE
		outUV.xy = inUV;
	#endif
}

#else // End of Vertex Shader


////////////////////////////////////////////////////
// Pixel Shaders
////////////////////////////////////////////////////

#ifdef _LIGHT0_POINT
	float4		g_lightPosition0;
#endif

#ifdef _MAP_DIFFUSE
	uniform sampler2D sDiffuse : register(s0);
#endif

float4 Object_PS(
			float4 inVertexPos : TEXCOORD0
			#ifdef _MAP_DIFFUSE
			   ,float2 inVertexUV : TEXCOORD1
			#endif
			#if defined(_MRT1)
			,out float4 oColor1 : COLOR1
			#endif
			#if defined(_MRT2)
			,out float4 oColor2 : COLOR2
			#endif
			#if defined(_MRT3)
			,out float4 oColor3 : COLOR3
			#endif
				) : COLOR0
{
	float4 Out = 1;
	
	// Read the albedo texture to check for transparency
	#ifdef _MAP_DIFFUSE
		Out.a = tex2D(sDiffuse, inVertexUV.xy).a;
	#endif
	
	#ifdef _LIGHT0_DIRECTIONAL
		Out.r = inVertexPos.z;
	#endif

	#ifdef _LIGHT0_SPOT
		Out.r = inVertexPos.z / inVertexPos.w;		
	#endif

	#ifdef _LIGHT0_POINT
		Out.r = length(inVertexPos.xyz - g_lightPosition0.xyz) * g_lightPosition0.w;
	#endif

	return Out;
}

#endif



struct VSI_SCREEN
{
	float4 pos		: POSITION;
	float4 color    : COLOR0;
	float2 uv		: TEXCOORD0;
};

struct VSO_SCREEN
{
	float4 pos		: POSITION;
	float2 uv		: TEXCOORD0_centroid;
};


////////////////////////////////////////////////////
// Vertex Shaders
////////////////////////////////////////////////////
float4 g_texelSize01;
float4 g_texelSize89;

void main_VS(float4 iPos : POSITION,
		  float2 iTC : TEXCOORD0,
		  out float4 oPos : POSITION,
		  out float2 oTC : TEXCOORD0)
{
	oPos = iPos;

#ifndef _XENON
	oTC = iTC + g_texelSize89.xy * .5f;
#else
	oTC = iTC;// + g_texelSize89.xy * .5f;
#endif
}

////////////////////////////////////////////////////
// Pixel Shaders
////////////////////////////////////////////////////
sampler2D sTex			: register(s0);
sampler2D DepthTex		: register(s9);


float4 main_PS(float2 iTC : TEXCOORD0
				#if defined(_MRT1)
				,out float4 oColor1 : COLOR1
				#endif
				#if defined(_MRT2)
				,out float4 oColor2 : COLOR2
				#endif
				#if defined(_MRT3)
				,out float4 oColor3 : COLOR3
				#endif
			   ) : COLOR0
{
	return float4(tex2Dproj(DepthTex, float4(iTC.xy, .9, 1)).rgb, 1);
}

float4 main_copy_PS(float2 iTC : TEXCOORD0_centroid
					#if defined(_MRT1)
					,out float4 oColor1 : COLOR1
					#endif
					#if defined(_MRT2)
					,out float4 oColor2 : COLOR2
					#endif
					#if defined(_MRT3)
					,out float4 oColor3 : COLOR3
					#endif
					) : COLOR0
{
	return float4(tex2D(DepthTex, iTC.xy).rgb,1);
}

float4 frustum_PS(float2 iTC : TEXCOORD0
					#if defined(_MRT1)
					,out float4 oColor1 : COLOR1
					#endif
					#if defined(_MRT2)
					,out float4 oColor2 : COLOR2
					#endif
					#if defined(_MRT3)
					,out float4 oColor3 : COLOR3
					#endif
				  ) : COLOR0
{
	return float4(1,1,0,1);
}
// now this shader program has become an official 'render a whatever-you-want squad' program

float4 g_specialVector1;	// adjust factors for texture coordinates
float4 g_specialVector2;	// adjust factors for screen space position


void main_VS(float3 iPos : POSITION,
		  float2 iTC : TEXCOORD0,
		  out float4 oPos : POSITION,
		  out float2 oTC : TEXCOORD0)
{
	oPos = float4(	iPos.x * g_specialVector2.x + g_specialVector2.y, 
					iPos.y * g_specialVector2.z + g_specialVector2.w, 
					iPos.z, 
					1.f
					);
	
	oTC = float2(	iTC.x * g_specialVector1.x + g_specialVector1.y, 
					iTC.y * g_specialVector1.z + g_specialVector1.w
					);
}


sampler2D tex	: register(s0);


float4 main_PS( float2 tc : TEXCOORD0
				#if defined(_MRT1)
				,out float4 oColor1 : COLOR1
				#endif
				#if defined(_MRT2)
				,out float4 oColor2 : COLOR2
				#endif
				#if defined(_MRT3)
				,out float4 oColor3 : COLOR3
				#endif
			   ) : COLOR
{
	//return float4(tex2D(tex, tc).xyz, 1.f);
	return tex2D(tex, tc);
}