varying vec2 		texcoord;
uniform sampler2D 	tex;
uniform sampler2D 	noiseTex;
varying vec4		diffuse;		// diffuse color * material color
uniform vec4		ambientColor;	// ambient  * material color
	
varying vec3 	Lin;
varying vec3 	Fex;

// shadows data
uniform sampler2DShadow 	shadowmap;
uniform float 				lightrange;
varying vec4				eyepos;
uniform vec4				LTM0,
							LTM1,
							LTM2,
							LTM3;
							
varying float		alphaFade;
uniform float 		maxDist;

#ifdef _HEIGHTMAP_

	uniform sampler2D	cmask;	
	varying vec2 		texcoord2;
	
#endif

varying vec3 localLightsDiffuse;

float ComputeShadowOcclusion()
{
	// SHADOW MAP CODE
	vec4	XYproj;	
	float 	shadowOcc=1.0;
	vec3 	projcoords;
			
	if( -eyepos.z/lightrange <= 1.0 )
	{
		// COMPUTE LIGHT TEXTURE PROJECTION + ATTENUATION
		XYproj.x = dot(eyepos,LTM0);
		XYproj.y = dot(eyepos,LTM1);
		XYproj.z = dot(eyepos,LTM2);
		XYproj.w = dot(eyepos,LTM3);

		projcoords.xy=XYproj.xy;
		projcoords.z=XYproj.z-0.001;
		
		///////////////////////////////////
		shadowOcc=min(shadow2D(shadowmap,projcoords).r,1.0);
	}
	////////////////////////////////////////
	
	return shadowOcc;
}

void main()
{
	if(-eyepos.z<=maxDist)
	{
		vec4 color=texture2D(tex,texcoord.st);
		
		// convert normal to eye space
		float occlusion=ComputeShadowOcclusion();
		
		#ifdef _HEIGHTMAP_
			
			vec3 one=vec3(1.0,1.0,1.0);
			vec3 maskColor=texture2D(cmask,texcoord2.st).rgb;
			vec3 rmul=color.rgb*maskColor;
			vec3 rscr=one-((one-maskColor)*(one-color.rgb));
			color.rgb=color.rgb*rscr+(one-color.rgb)*rmul;
			color.a=1.0;
		#else
			float alpha=texture2D(noiseTex,texcoord.st).r;
			if(alpha>alphaFade)
				discard;
		#endif
		
		//gl_FragColor.xyz=mix(fog.rgb,color.xyz*ambientColor.xyz + color.xyz*diffuse.xyz,fog.a);
		vec3 ambient=color.xyz*ambientColor.xyz;
		vec3 finalColor=(diffuse.xyz*vec3(occlusion)+localLightsDiffuse)*color.xyz+ambient;
		
		gl_FragColor.xyz=Lin+(Fex*finalColor);/*Lin+(Fex*diffuse.xyz*color.xyz)*/;
		gl_FragColor.a=color.a;
	}
}
