varying vec2 		texcoord;
varying vec2 		texcoord1;

uniform sampler2D 	bg,
					bmp,
					tex,
					depthBG;
uniform samplerCube	ambientCube;

varying vec4 		pos;
varying vec4		eyepos;
uniform vec2		density;
uniform vec3		refrColor;
uniform vec3		diffuseColor;
uniform vec3		ambientColor;
uniform float		transparency;

#ifdef BUMP2

	varying vec2 		texcoord2;
	uniform sampler2D 	bmp1;

#endif

#ifdef PSYSTEM

	varying float 	life;

#else

	// SHADOWMAP PARAMS
	uniform sampler2DShadow 	shadowmap;
	uniform sampler2DShadow 	shadowmap2;
	uniform sampler2DShadow 	shadowmap4;
	uniform sampler2DShadow 	shadowmap8;

	uniform float 		lightrange;
	uniform float 		lightrange2;
	uniform float 		lightrange4;
	uniform float 		lightrange8;
		
	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;
	//////////////////////////////////////////

	uniform vec3		lightDir;
	uniform float		lightscale;
	uniform vec3		lightcolor;

	#ifdef CUBEREFL
		uniform samplerCube	reflCube;
		uniform float		reflScale;
	#endif

	varying vec3		w0,
						w1,
						w2;
	varying vec3		viewDir;
	
	uniform vec2 		spec;
	uniform vec2		fresnel;

#endif

///////// LIGHTS ////////////////////////
uniform float light0;
uniform vec3 lightpos0;
uniform vec3 lightColor0;
uniform float lightRange0;

uniform float light1;
uniform vec3 lightpos1;
uniform vec3 lightColor1;
uniform float lightRange1;
///////////////////////////////////////////

/*vec3 ComputeSunLight(vec3 N, vec3 vdir, vec3 ldir)
{
	#ifdef PSYSTEM
	#else
	
		vec3 diffuse=vec3(0.0,0.0,0.0);

		// SHADOW MAP CODE
		vec4	XYproj;	
		float shadowOcc=1.0;
		vec3 projcoords;
				
		if( -eyepos.z/lightrange <= 1 )
		{
			// 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.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);

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

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

			shadowcoords.xy=projcoords.xy+vec2(-dOfs,-dOfs);
			shadowOcc+=shadow2D(shadowmap,shadowcoords);
			
			shadowOcc *= 0.25;
		}
		else
		{	
			if( -eyepos.z/lightrange2 <= 1 )
			{
				// COMPUTE LIGHT TEXTURE PROJECTION + ATTENUATION
				XYproj.x = dot(eyepos,LTM0b);
				XYproj.y = dot(eyepos,LTM1b);
				XYproj.z = dot(eyepos,LTM2b);
				XYproj.w = dot(eyepos,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);

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

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

				shadowcoords.xy=projcoords.xy+vec2(-dOfs,-dOfs);
				shadowOcc+=shadow2D(shadowmap2,shadowcoords);
				
				shadowOcc *= 0.25;
			}
			else
			{
				if( -eyepos.z/lightrange4 <= 1 )
				{
					// COMPUTE LIGHT TEXTURE PROJECTION + ATTENUATION
					XYproj.x = dot(eyepos,LTM0c);
					XYproj.y = dot(eyepos,LTM1c);
					XYproj.z = dot(eyepos,LTM2c);
					XYproj.w = dot(eyepos,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);

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

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

					shadowcoords.xy=projcoords.xy+vec2(-dOfs,-dOfs);
					shadowOcc+=shadow2D(shadowmap4,shadowcoords);
				
					shadowOcc *= 0.25;
				}
				else
				{
					if( -eyepos.z/lightrange8 <= 1 )
					{
						// COMPUTE LIGHT TEXTURE PROJECTION + ATTENUATION
						XYproj.x = dot(eyepos,LTM0d);
						XYproj.y = dot(eyepos,LTM1d);
						XYproj.z = dot(eyepos,LTM2d);
						XYproj.w = dot(eyepos,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);

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

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

						shadowcoords.xy=projcoords.xy+vec2(-dOfs,-dOfs);
						shadowOcc+=shadow2D(shadowmap8,shadowcoords);
				
						shadowOcc *= 0.25;
							
						float lrangeMin=lightrange8-1000.0;
						shadowOcc=lerp(shadowOcc,1.0,( clamp( (-pos.z-lrangeMin)/(lightrange8-lrangeMin),0.0,1.0) ));
					}
				}
			}
		}
		////////////////////////////////////////
		
		float specular=0;
			
		if( -eyepos.z < 4000.0 )	
		{
			if( -eyepos.z < 2000.0 )
			{
				if(shadowOcc>0.0)
				{
					vec3 halfv = normalize(ldir+vdir);
					specular = clamp(dot(halfv, N.xyz),0.0,1.0);
					specular = pow(specular,spec.x)*spec.y;
										
					if(scatter>0.0)
					{
						float NLwrap=(dot(ldir,N)+scatter)/(1+scatter);
						diffuse = max(NLwrap,0.0);
						float fScatter = smoothstep(0.0, 0.5, NLwrap) * smoothstep(1.0, 0.5,NLwrap);
						diffuse = diffuseColor*((scatter*vec4(0.15, 0.0, 0.0, 1.0))+diffuse); 
					}
					else
						diffuse = clamp(dot(N,ldir),0.0,1.0)*diffuseColor;
				}
			}
			else
				diffuse = clamp(dot(N,ldir),0.0,1.0)*diffuseColor;
		}
		else
			diffuse = diffuseColor;
								
		return (diffuse+specular)*lightcolor*lightscale*shadowOcc*texColor.rgb;
		
	#endif
}*/

void main()
{
	vec4 refl=vec4(0.0,0.0,0.0,0.0);
	vec3 litColor=vec3(0.0,0.0,0.0);
	vec3 diffuse=vec3(0.0,0.0,0.0);
	vec4 normalColor=texture2D(bmp,texcoord1.st);
	vec3 normal=(normalColor.xyz*2.0)-1.0;
	normalize(normal);
	vec4 texColor=texture2D(tex,texcoord.st);
	vec3 ambient=diffuseColor*ambientColor;

#ifdef BUMP2

	vec4 normalColor1=texture2D(bmp1,texcoord2.st);
	vec3 normal1=(normalColor1.xyz*2.0)-1.0;
	vec3 normal2=normal;
	normal=(normal2+normal1)*0.5;
	normalize(normal);

#endif

	vec2 UV=(pos.xy/pos.w)*0.5+0.5;
	float depth=texture2D(depthBG,UV).z;
	
	#ifdef PSYSTEM

		UV+=normal.xy*density.x*life;
		normalColor.a*=life;

	#else

		UV+=normal.xy*density.x;
		
		// SHADOW MAP CODE
		vec4	XYproj;	
		float shadowOcc=1.0;
		vec3 projcoords;
			
		if( -eyepos.z/lightrange <= 1 )
		{
			// 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.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);

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

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

			shadowcoords.xy=projcoords.xy+vec2(-dOfs,-dOfs);
			shadowOcc+=shadow2D(shadowmap,shadowcoords);
			
			shadowOcc *= 0.25;
		}
		else
		{	
			if( -eyepos.z/lightrange2 <= 1 )
			{
				// COMPUTE LIGHT TEXTURE PROJECTION + ATTENUATION
				XYproj.x = dot(eyepos,LTM0b);
				XYproj.y = dot(eyepos,LTM1b);
				XYproj.z = dot(eyepos,LTM2b);
				XYproj.w = dot(eyepos,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);

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

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

				shadowcoords.xy=projcoords.xy+vec2(-dOfs,-dOfs);
				shadowOcc+=shadow2D(shadowmap2,shadowcoords);
			
				shadowOcc *= 0.25;
			}
			else
			{
				if( -eyepos.z/lightrange4 <= 1 )
				{
					// COMPUTE LIGHT TEXTURE PROJECTION + ATTENUATION
					XYproj.x = dot(eyepos,LTM0c);
					XYproj.y = dot(eyepos,LTM1c);
					XYproj.z = dot(eyepos,LTM2c);
					XYproj.w = dot(eyepos,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);

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

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

					shadowcoords.xy=projcoords.xy+vec2(-dOfs,-dOfs);
					shadowOcc+=shadow2D(shadowmap4,shadowcoords);
			
					shadowOcc *= 0.25;
				}
				else
				{
					if( -eyepos.z/lightrange8 <= 1 )
					{
						// COMPUTE LIGHT TEXTURE PROJECTION + ATTENUATION
						XYproj.x = dot(eyepos,LTM0d);
						XYproj.y = dot(eyepos,LTM1d);
						XYproj.z = dot(eyepos,LTM2d);
						XYproj.w = dot(eyepos,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);

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

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

						shadowcoords.xy=projcoords.xy+vec2(-dOfs,-dOfs);
						shadowOcc+=shadow2D(shadowmap8,shadowcoords);
			
						shadowOcc *= 0.25;
						
						float lrangeMin=lightrange8-1000.0;
						shadowOcc=lerp(shadowOcc,1.0,( clamp( (-pos.z-lrangeMin)/(lightrange8-lrangeMin),0.0,1.0) ));
					}
				}
			}
		}
		////////////////////////////////////////
			
		vec3 N;
		vec3 vdir;
		float specular=0;
		
		if(-eyepos.z < 4000.0)
		{
			UV=clamp(UV,0.0,1.0);
			float dist=(clamp(abs(depth-eyepos.z)*density.y,0.0,1.0));
			ambient=ambient*( (1.0-dist)*texture2D(bg,UV*0.25).rgb + refrColor*dist );
				
			N.x=dot(w0,normal);
			N.y=dot(w1,normal);
			N.z=dot(w2,normal);
			
			vdir=normalize(viewDir);	
			#ifdef CUBEREFL
				
				vec3 reflection = reflect(vdir,N);
				refl=textureCube(reflCube,reflection.xyz)*reflScale;
				
			#endif
			
			if( -eyepos.z < 2000.0 )
			{
				ambient*=textureCube(ambientCube,N.xyz);
				#ifdef CUBEREFL
					refl+=pow(1.0-clamp(dot(N,vdir),0.0,1.0),fresnel.x)*fresnel.y;
				#endif
				
				if(shadowOcc>0.0)
				{
					diffuse = diffuseColor*transparency*clamp(dot(N,lightDir),0.0,1.0);
					vec3 halfv = normalize(lightDir+vdir);
					specular = clamp(dot(halfv, N.xyz),0.0,1.0);
					specular = pow(specular,spec.x)*spec.y;
				}
			}
			else
				diffuse = clamp(dot(N,lightDir),0.0,1.0)*diffuseColor*transparency;
			litColor= (diffuse+specular)*lightcolor*lightscale*shadowOcc;
		}
		
	#endif	
		
	vec3 finalColor=refl + litColor + ambient; 
	texColor.rgb=texColor.rgb*(ambientColor + diffuse);
	gl_FragColor.rgb=(finalColor*(1.0-texColor.a) + texColor.rgb*texColor.a);
}
