
#ifdef VS

float4x4 mWorldView : register(c0);
float4x4 mProj : register(c4);

float4 gLightCounts : register(c23);
float4x4 gSLightMatrices[4] : register(c24); /* :c39 */

void main
(
	float4 ipos : POSITION0,
	float3 inrm : NORMAL0,
	float4 itan : TANGENT0,
	float4 icol : COLOR0,
	float4 itex0 : TEXCOORD0,
	float4 itex1 : TEXCOORD1,
	out float4 opos : POSITION0,
	out float4 otfpos : TEXCOORD4,
	out float4 oT : TEXCOORD6,
	out float3 oN : TEXCOORD7,
	out float4 oshpos0 : TEXCOORD8,
	out float4 oshpos1 : TEXCOORD9,
	out float4 oshpos2 : TEXCOORD10,
	out float4 oshpos3 : TEXCOORD11,
	out float4 ocol : COLOR0,
	out float4 otex0 : TEXCOORD0,
	out float4 otex1 : TEXCOORD1
)
{
	float4 viewPos = mul( mWorldView, ipos );
	opos = mul( mProj, viewPos );
	otfpos = viewPos;
	oT = float4( mul( mWorldView, float4( itan.xyz, 0 ) ).xyz, itan.w );
	oN = mul( mWorldView, float4( inrm, 0 ) ).xyz;
	ocol = icol;
	otex0 = itex0;
	otex1 = itex1;
	
	oshpos0 = mul( gSLightMatrices[0], ipos );
	oshpos1 = mul( gSLightMatrices[1], ipos );
	oshpos2 = mul( gSLightMatrices[2], ipos );
	oshpos3 = mul( gSLightMatrices[3], ipos );
}

#elif defined(PS)

sampler2D Tex0 : register(s0);
sampler2D Tex1 : register(s1);
sampler2D Tex2 : register(s2);
sampler2D Tex3 : register(s3);
sampler2D Tex4 : register(s4);
sampler2D Tex5 : register(s5);
sampler2D Tex6 : register(s6);
sampler2D Tex7 : register(s7);
samplerCUBE InstTex0 : register(s8);
samplerCUBE InstTex1 : register(s9);
samplerCUBE InstTex2 : register(s10);
samplerCUBE InstTex3 : register(s11);

sampler2D SpotLightTextures[8] : register(s8);

float4x4 mInvView : register(c0);
float4x4 mProj : register(c4);
float3 gAmbLightColor : register(c20);
float3 gDirLightDir : register(c21);
float3 gDirLightColor : register(c22);
struct SpotLight /* size: 4c */
{
	float4 vposrad;
	float4 colpow;
	float4 vdirang;
	float4 shminfo;
};
float4 gLightCounts : register(c23);
SpotLight gSLights[4] : register(c24); /* :c39 */

float4 gInstanceData[16] : register(c100); /* :c115 */

void main
(
	float4 inViewPos : TEXCOORD4,
	float4 inTangentSign : TEXCOORD6,
	float3 inNormal : TEXCOORD7,
	float4 inSLPPos0 : TEXCOORD8,
	float4 inSLPPos1 : TEXCOORD9,
	float4 inSLPPos2 : TEXCOORD10,
	float4 inSLPPos3 : TEXCOORD11,
	float4 icol : COLOR0,
	float4 inTex0 : TEXCOORD0,
	float4 inTex1 : TEXCOORD1,
	out float4 _outColor0 : COLOR0,
	out float4 _outColor1 : COLOR1
)
{
	float RdotV, specAmount;
	
	float3 viewPos = inViewPos.xyz;
	float4 projPos = mul( mProj, inViewPos );
	float3 viewDir = normalize( viewPos );
	
	float3 T = inTangentSign.xyz;
	float3 B = cross( inNormal, inTangentSign.xyz ) * inTangentSign.w;
	float3 N = inNormal;
	
	float3x3 TBN = float3x3( T, B, N );
	
	float3 outDiffuseColor = float3( 0.7, 0.7, 0.7 );
	float outOpacity = 1.0;
	float3 outSpecularColor = float3( 0.3, 0.3, 0.3 );
	float outSpecularPower = 32;
	float3 outNormal = inNormal;
	float2 outDistortion = float2( 0, 0 );
	float3 outAmbientDiffuseLight = float3( 0, 0, 0 );
	float3 outAmbientSpecularLight = float3( 0, 0, 0 );
	float3 outEmissiveLight = float3( 0, 0, 0 );
	{
__CODE__
	}
	
	float3 totalDiffuse = float3(0,0,0);
	float3 totalSpecular = float3(0,0,0);
	
	float4 SLPositions[ 4 ] = { inSLPPos0, inSLPPos1, inSLPPos2, inSLPPos3 };
	
	/* SPOT LIGHTS */
	for( int i = 0; i < gLightCounts.y; ++i )
	{
		SpotLight SL = gSLights[ i ];
		float3 lightViewPos = SL.vposrad.xyz;
		float3 lightDir = lightViewPos - viewPos;
		float lightDist = length( lightDir );
		lightDir /= lightDist;
		float3 lightColor = SL.colpow.rgb;
		
		float3 slpos = SLPositions[ i ].xyz / SLPositions[ i ].w;
		if( dot(step(-(abs( slpos ) -1),0),1) <= 0 )
		{
			float2 sltex = slpos.xy * float2(0.5,-0.5) + 0.5;
			float3 cookieSample = tex2Dlod( SpotLightTextures[ i * 2 ], float4( sltex, 0, 0 ) );
			
			float4 sizeinfo = SL.shminfo;
			float2 coord = sltex * sizeinfo.xy;
			float2 fv = frac( coord );
			sampler2D shmap = SpotLightTextures[ i * 2 + 1 ];
			float coord0x = floor( coord.x ) * sizeinfo.z;
			float coord1x = ceil( coord.x ) * sizeinfo.z;
			float coord0y = floor( coord.y ) * sizeinfo.w;
			float coord1y = ceil( coord.y ) * sizeinfo.w;
			float s00 = step( slpos.z, tex2Dlod( shmap, float4( coord0x, coord0y, 0, 0 ) ).r );
			float s10 = step( slpos.z, tex2Dlod( shmap, float4( coord1x, coord0y, 0, 0 ) ).r );
			float s01 = step( slpos.z, tex2Dlod( shmap, float4( coord0x, coord1y, 0, 0 ) ).r );
			float s11 = step( slpos.z, tex2Dlod( shmap, float4( coord1x, coord1y, 0, 0 ) ).r );
			float smix = lerp( lerp( s00, s10, fv.x ), lerp( s01, s11, fv.x ), fv.y );
			
			lightColor *= cookieSample * smix;
			
			float distFactor = pow( 1 - saturate( lightDist / SL.vposrad.w ), SL.colpow.w );
			float NdotL = saturate( dot( outNormal, lightDir ) );
			
			RdotV = saturate( dot( reflect( lightDir, outNormal ), viewDir ) );
			specAmount = pow( RdotV, outSpecularPower ) * sqrt( outSpecularPower );
			
			totalDiffuse += lightColor * NdotL * distFactor;
			totalSpecular += lightColor * specAmount;
		}
	}
	clip( totalDiffuse + totalSpecular );
	
	_outColor0 = float4( totalDiffuse * outDiffuseColor + totalSpecular * outSpecularColor, outOpacity );
	_outColor1 = float4( 0, 0, 0, 0 );
}

#endif

