uniform sampler2D 			colorTex,
							normalTex,
							matTex,
							posTex;
uniform sampler2DShadow 	shadowmap;
uniform sampler2DShadow 	shadowmap2;
uniform sampler2DShadow 	shadowmap4;
uniform sampler2DShadow 	shadowmap8;

varying vec2 		texcoord;
uniform vec3		lightcolor;
uniform vec3		lightdir;
uniform float 		lightrange;
uniform float 		lightrange2;
uniform float 		lightrange4;
uniform float 		lightrange8;
uniform float		lightscale;
uniform float		cOfs;

uniform vec4		LTM0,
					LTM1,
					LTM2,
					LTM3;

uniform vec4		LTM0b,
					LTM1b,
					LTM2b,
					LTM3b;

uniform vec4		LTM0c,
					LTM1c,
					LTM2c,
					LTM3c;

uniform vec4		LTM0d,
					LTM1d,
					LTM2d,
					LTM3d;

varying vec2		VPOS;

#ifdef ALPHABLEND

	uniform sampler2D 	bgTex;

#endif

void main()
{
	vec2	Zproj;
	vec4	XYproj;	

	vec4 color = texture2D(colorTex,texcoord.st);
	vec4 normal = texture2D(normalTex,texcoord.st);
	vec4 pos = texture2D(posTex,texcoord.st);
	vec4 mat = texture2D(matTex,texcoord.st);
	mat.y=pow(2.0,(10.0*mat.y+1.0))-2.0;

	float scatter=floor(pos.a)/256.0;	//1/256.0;
	float scatterRed=pos.a-floor(pos.a);
	normal.xyz=normalize(normal.xyz);	// normal.a = scatter level

	pos.xy=VPOS.xy*-pos.z;
	pos.w=1.0;

	float shadowOcc=1.0;

#ifdef SHADOWS

	vec3 projcoords;
	if( -pos.z/lightrange <= 1.0 )
	{
		// COMPUTE LIGHT TEXTURE PROJECTION + ATTENUATION
		XYproj.x = dot(pos,LTM0);
		XYproj.y = dot(pos,LTM1);
		XYproj.z = dot(pos,LTM2);
		XYproj.w = dot(pos,LTM3);

		projcoords.xy=XYproj.xy;
		projcoords.z=XYproj.z-0.00005;
		///////////////////////////////////

		float dOfs = cOfs*0.5;
		shadowOcc=0.0;

		vec3 shadowcoords;
		shadowcoords.z=projcoords.z;

		shadowcoords.xy=projcoords.xy+vec2(-dOfs,dOfs);
		shadowOcc+=shadow2D(shadowmap,shadowcoords).r;

		shadowcoords.xy=projcoords.xy+vec2(dOfs,dOfs);
		shadowOcc+=shadow2D(shadowmap,shadowcoords).r;

		shadowcoords.xy=projcoords.xy+vec2(dOfs,-dOfs);
		shadowOcc+=shadow2D(shadowmap,shadowcoords).r;

		shadowcoords.xy=projcoords.xy+vec2(-dOfs,-dOfs);
		shadowOcc+=shadow2D(shadowmap,shadowcoords).r;
	
		shadowOcc *= 0.25;
	}
	else
	{	
		if( -pos.z/lightrange2 <= 1.0 )
		{
			// COMPUTE LIGHT TEXTURE PROJECTION + ATTENUATION
			XYproj.x = dot(pos,LTM0b);
			XYproj.y = dot(pos,LTM1b);
			XYproj.z = dot(pos,LTM2b);
			XYproj.w = dot(pos,LTM3b);

			projcoords.xy=XYproj.xy;
			projcoords.z=XYproj.z-0.0004;
			///////////////////////////////////

			float dOfs = cOfs*0.5;
			shadowOcc=0.0;

			vec3 shadowcoords;
			shadowcoords.z=projcoords.z;

			shadowcoords.xy=projcoords.xy+vec2(-dOfs,dOfs);
			shadowOcc+=shadow2D(shadowmap2,shadowcoords).r;

			shadowcoords.xy=projcoords.xy+vec2(dOfs,dOfs);
			shadowOcc+=shadow2D(shadowmap2,shadowcoords).r;

			shadowcoords.xy=projcoords.xy+vec2(dOfs,-dOfs);
			shadowOcc+=shadow2D(shadowmap2,shadowcoords).r;

			shadowcoords.xy=projcoords.xy+vec2(-dOfs,-dOfs);
			shadowOcc+=shadow2D(shadowmap2,shadowcoords).r;
	
			shadowOcc *= 0.25;
		}
		else
		{
			if( -pos.z/lightrange4 <= 1.0 )
			{
				// COMPUTE LIGHT TEXTURE PROJECTION + ATTENUATION
				XYproj.x = dot(pos,LTM0c);
				XYproj.y = dot(pos,LTM1c);
				XYproj.z = dot(pos,LTM2c);
				XYproj.w = dot(pos,LTM3c);

				projcoords.xy=XYproj.xy;
				projcoords.z=XYproj.z-0.0006;
				///////////////////////////////////

				float dOfs = cOfs*0.5;
				shadowOcc=0.0;

				vec3 shadowcoords;
				shadowcoords.z=projcoords.z;

				shadowcoords.xy=projcoords.xy+vec2(-dOfs,dOfs);
				shadowOcc+=shadow2D(shadowmap4,shadowcoords).r;

				shadowcoords.xy=projcoords.xy+vec2(dOfs,dOfs);
				shadowOcc+=shadow2D(shadowmap4,shadowcoords).r;

				shadowcoords.xy=projcoords.xy+vec2(dOfs,-dOfs);
				shadowOcc+=shadow2D(shadowmap4,shadowcoords).r;

				shadowcoords.xy=projcoords.xy+vec2(-dOfs,-dOfs);
				shadowOcc+=shadow2D(shadowmap4,shadowcoords).r;
	
				shadowOcc *= 0.25;
			}
			else
			{
				if( -pos.z/lightrange8 <= 1.0 )
				{
					// COMPUTE LIGHT TEXTURE PROJECTION + ATTENUATION
					XYproj.x = dot(pos,LTM0d);
					XYproj.y = dot(pos,LTM1d);
					XYproj.z = dot(pos,LTM2d);
					XYproj.w = dot(pos,LTM3d);

					projcoords.xy=XYproj.xy;
					projcoords.z=XYproj.z-0.002;
					///////////////////////////////////

					float dOfs = cOfs*0.5;
					shadowOcc=0.0;

					vec3 shadowcoords;
					shadowcoords.z=projcoords.z;

					shadowcoords.xy=projcoords.xy+vec2(-dOfs,dOfs);
					shadowOcc+=shadow2D(shadowmap8,shadowcoords).r;

					shadowcoords.xy=projcoords.xy+vec2(dOfs,dOfs);
					shadowOcc+=shadow2D(shadowmap8,shadowcoords).r;

					shadowcoords.xy=projcoords.xy+vec2(dOfs,-dOfs);
					shadowOcc+=shadow2D(shadowmap8,shadowcoords).r;

					shadowcoords.xy=projcoords.xy+vec2(-dOfs,-dOfs);
					shadowOcc+=shadow2D(shadowmap8,shadowcoords).r;
	
					shadowOcc *= 0.25;
					
					float lrangeMin=lightrange8-1000.0;
					shadowOcc=mix(shadowOcc,1.0,( clamp( (-pos.z-lrangeMin)/(lightrange8-lrangeMin),0.0,1.0) ));
				}
			}
		}
	}

#endif
	//shadowOcc=clamp(shadowOcc + floor(-pos.z/lightrange),0.0,1.0);

	vec4 finalcolor=color;
	
	if(shadowOcc>0.0)
	{
	//	if( -pos.z < 8000.0 )
	//	{	
			vec3 ldir=lightdir;
			
			if(scatter>0.0)
			{
				// scatter width=0.3
				float NLwrap=(dot(ldir,normal.xyz)+scatter)/(1.0+scatter);
				float diffuse = max(NLwrap,0.0);
				float fScatter = smoothstep(0.0, /*0.5 scatterWidth*/0.5, NLwrap) * smoothstep(/*1.0 ScatterWidth*2.0 */1.0, /*scatterWidth*/0.5,NLwrap);
				finalcolor *= ((fScatter*vec4(scatterRed, scatterRed*0.1, scatterRed*0.05, 1.0))+diffuse); 
			}
			else
			{
				float diffuse = max(dot(ldir,normal.xyz),0.0);
				finalcolor *= diffuse;
			}
		
			if( -pos.z < 4000.0 )
			{
				vec3 vdir=-pos.xyz;
				vdir=normalize(vdir);
				if(mat.y>0.0)
				{
					vec3 halfv = ldir+vdir;
					halfv=normalize(halfv);
					float spec = clamp(dot(halfv, normal.xyz),0.0,1.0);
					spec = pow(spec,mat.x)*mat.y;
					finalcolor += spec;
				}
				if( -pos.z < 2000.0 )
				{
					float fresnelres=pow(1.0-clamp(dot(normal.xyz,vdir),0.0,1.0),mat.w);
					finalcolor += (fresnelres * mat.z);
				}
			}
	//	}
		#ifdef ALPHABLEND
			vec4 dest=texture2D(bgTex,texcoord.st);
			finalcolor.xyz = dest.xyz + (finalcolor.xyz*lightcolor.xyz)*lightscale*shadowOcc*color.a;
			gl_FragColor.xyz=max(finalcolor.xyz,0.0);
		#else	
			gl_FragColor.xyz=max((finalcolor.xyz*lightcolor.xyz)*lightscale*shadowOcc,0.0);
		#endif
	}
	else
	{
		#ifdef ALPHABLEND
			vec4 dest=texture2D(bgTex,texcoord.st);
			gl_FragColor.xyz=max(dest.xyz,0.0);
		#else	
			discard;
				//gl_FragColor.xyz=vec3(0.0,0.0,0.0);
		#endif
	}
	gl_FragColor.a=0.0;
}
