varying vec2 		texcoord;
uniform sampler2D 	dif0;

#ifdef _HEIGHTMAP_
	uniform sampler2D	bmp0;
#endif
//					noisemap;
					
uniform float		metal0;
uniform vec2		fresnel0,
					spec0;
uniform vec4		dcolor0,
					scolor0;
uniform vec2		dscale0,
					bscale0;
uniform vec2		dofs0,
					bofs0;
uniform vec2 		scatterlevel;
uniform float 		scatterRed;
uniform float 		backScatter;
uniform float		wFar;
uniform float		matID;

#ifdef VEGETATION
	#ifndef BSET
		#ifndef MSET
			varying vec3	vgColor;
		#endif
	#endif
#endif
	
#ifdef LAYER1
	
	uniform sampler2D 	lmask;
	varying vec3		vertColor;
	uniform float		metal1;
	uniform vec2		fresnel1;
	uniform vec3		maskMul;
	
#endif 	
	
#ifdef ALPHATEST

	uniform float 		alphalevel;
	varying float		alphaFade;
	
#endif

#ifdef PSYSTEM

	varying float 	life;
	varying float	cosa,
			sina;
	uniform vec4 		particleFade;
			
#else

	#ifdef BSET

		varying vec4 pnormal;
		varying vec4 pcolor;

	#else
	
		#ifdef MSET
		varying vec4 pcolor;
		uniform float terrainColorAmount;
		#else
			varying float occlusion; 
		#endif
		
		varying mat3	TBN;
		
	#endif
		
#endif				


#ifdef _HEIGHTMAP_

	uniform sampler2D	baseTex;
	uniform sampler2D	cmask;
	varying float	vSlope;
	varying vec2 	baseCoords;
	
#endif

varying vec4 		curpos;
//#ifdef _HEIGHTMAP_
	varying vec4 	pos;
//#endif
					//prev;
uniform float		vScale;
uniform float 		fade;

varying vec2 	depth;
varying float	scatterMask;

vec2 encode(vec3 n)
{
	n=normalize(n);
    float f = sqrt(8.0*n.z+8.0);
    return n.xy / f + 0.5;
}

// NOISE ----------------------------------------------------
float bayer2(vec2 a){
    a = floor(a);
    return fract( dot(a, vec2(.5, a.y * .75)) );
}

#define bayer4(a)   (bayer2( .5*(a))*.25+bayer2(a))
#define bayer8(a)   (bayer4( .5*(a))*.25+bayer2(a))
#define bayer16(a)  (bayer8( .5*(a))*.25+bayer2(a))
#define bayer32(a)  (bayer16(.5*(a))*.25+bayer2(a))
#define bayer64(a)  (bayer32(.5*(a))*.25+bayer2(a))
#define bayer128(a) (bayer64(.5*(a))*.25+bayer2(a))
// -----------------------------------------------------------

void main()
{
	#ifdef PSYSTEM
	
	if(life<=0.0)
		discard;
			
	#endif
	
	//vec2 screenCoords=curpos.xy*0.5+0.5;

	vec4 	fdcolor,
			fbcolor;
	vec3	fnormal;
	vec2	fspec,
			ffresnel;
	float 	metal=metal0;	
			
	#ifdef LAYER1
	
		vec3 mask=vec3(0.0,0.0,0.0);
		
		//vec3 	fadedmask;
		float rangeMin=scatterlevel.y-3000.0;
		if(-pos.z<scatterlevel.y)
		{
			mask=texture2D(lmask,texcoord.st).rgb*maskMul;
			mask.r=min(1.0,mask.r+mask.g+mask.b);
			mask.r=mix(mask.r,0.0,( clamp( (-pos.z-rangeMin)/3000.0,0.0,1.0) ));
		}
		
	#endif
			
	#ifndef _HEIGHTMAP_		
		fdcolor=texture2D(dif0,texcoord.st*dscale0+dofs0);
		fdcolor.rgb=pow(fdcolor.rgb,vec3(2.2))*dcolor0.rgb;
	#endif
	
	#ifdef ALPHATEST

		#ifdef PSYSTEM
			float alpha=fdcolor.a*life;
			if(alpha<=alphalevel)
				discard;
		#else
			#ifdef BSET
				float alpha=bayer4(gl_FragCoord.st);//texture2D(noisemap,screenCoords.st*10.0).r;
				if(alpha>pcolor.w)
					discard;
			#else
				#ifdef MSET
					float alpha=bayer4(gl_FragCoord.st);//texture2D(noisemap,screenCoords.st*10.0).r;
					if(alpha>fade)
						discard;
				#else
					#ifdef _HEIGHTMAP_
					#else
						#ifdef SKINNING
						#else
							#ifndef _NOT_INSTANCED_
								float alpha=bayer4(gl_FragCoord.st);//texture2D(noisemap,screenCoords.st*10.0).r;
								if(alpha>alphaFade)
									discard;
							#else
								float alpha=bayer4(gl_FragCoord.st);//texture2D(noisemap,screenCoords.st*10.0).r;
								if(alpha>fade)
									discard;
							#endif
						#endif
					#endif
				#endif
			#endif
			
			#ifdef BSET
				if(fdcolor.a<=alphalevel)
					discard;
			#else
				if(fdcolor.a<=mix(alphalevel,alphalevel*0.8,clamp(curpos.z*25000.0-4500.0,0.0,1.0)))
					discard;
			#endif
		#endif
		
	#endif

	#ifdef BSET
	
	#else
		#ifdef _HEIGHTMAP_
			fbcolor=texture2D(bmp0,texcoord.st*bscale0+bofs0);
			fnormal.xy=(fbcolor.xy*2.0-1.0);
			ffresnel.y=fresnel0.y*fbcolor.z;
			ffresnel.x=1.0;
		#else
			fnormal.xyz=vec3(0.0,0.0,1.0);
			ffresnel.xy=fresnel0.xy;//*vec2(min(1.0,dot(fdcolor.xyz,vec3(0.27, 0.67, 0.06))*2.0));//	0.5;
		#endif
	#endif

	#ifdef _HEIGHTMAP_
	
		float t=clamp(-pos.z*0.000025,0.0,1.0);
		fbcolor=texture2D(bmp0,texcoord.st*8.0);
		fbcolor.xy=(fbcolor.xy*2.0-1.0);
		fbcolor.z=sqrt(1.0-fbcolor.x*fbcolor.x-fbcolor.y*fbcolor.y);
		fnormal.z=sqrt(1.0-fnormal.x*fnormal.x-fnormal.y*fnormal.y);
		fnormal=fbcolor.xyz + fnormal;
		vec4 f0=pow(texture2D(dif0,texcoord.st*8.0),vec4(2.2));
		
		fbcolor.xyz=vec3(0.0,0.0,1.0);
		fnormal=mix(normalize(fnormal),fbcolor.xyz,vSlope);
		
		fdcolor=texture2D(dif0,texcoord.st*dscale0+dofs0);
		fdcolor.rgb=pow(fdcolor.rgb,vec3(2.2))*dcolor0.rgb;
		fdcolor=fdcolor*(1.0-t)+f0*t;
		
		vec4 baseColor=texture2D(baseTex,baseCoords);
		baseColor.rgb=pow(baseColor.rgb,vec3(2.2));
		fdcolor.xyz=mix(fdcolor.xyz,baseColor.xyz,vSlope);
		ffresnel.y=mix(ffresnel.y,baseColor.a,vSlope);
		
		// normalize resultant normal
		fnormal.z=sqrt(1.0-fnormal.x*fnormal.x-fnormal.y*fnormal.y);	
	
		vec3 one=vec3(1.0,1.0,1.0);
		vec3 maskColor=pow(texture2D(cmask,texcoord.st).rgb,vec3(2.2));
		vec3 rmul=fdcolor.rgb*maskColor;
		vec3 rscr=one-((one-maskColor)*(one-fdcolor.rgb));
		fdcolor.rgb=fdcolor.rgb*rscr+(one-fdcolor.rgb)*rmul;
		
	#endif

	#ifdef LAYER1
		
		fdcolor.xyz=mix(fdcolor.xyz,((vertColor.xyz*0.5)/*+fdcolor.xyz*/)*0.5,mask.r);
		ffresnel.xy=max(ffresnel.xy,fresnel1.xy*vec2(mask.r));//fresnel0.xy*vec2(min(1.0,dot(fdcolor.xyz,vec3(0.27, 0.67, 0.06))*2.0));//	0.5;
		metal=max(metal,mask.r*metal1);
	#endif
	
	fdcolor.a=scatterlevel.x*scatterMask;
	
	#ifdef VEGETATION
		#ifndef BSET
			#ifndef MSET
				vec3 one=vec3(1.0,1.0,1.0);
				vec3 rmul=fdcolor.rgb*vgColor.xyz;
				vec3 rscr=one-((one-vgColor.xyz)*(one-fdcolor.rgb));
				fdcolor.rgb=fdcolor.rgb*rscr+(one-fdcolor.rgb)*rmul;
			#endif
		#endif
	#endif
	
	float isNotMetal=step(metal,0.0); // if metal > 0 then isNotMetal = 0 else isNotMetal=1
	fdcolor.a*=isNotMetal;	
	gl_FragData[0]=fdcolor;

	#ifdef PSYSTEM
			
		gl_FragData[1].xy=encode(vec3((fnormal.x*cosa)+(fnormal.y*sina),(fnormal.x*sina)-(fnormal.y*cosa),fnormal.z));
			
	#else
		
		#ifdef BSET
			
			vec3 one=vec3(1.0,1.0,1.0);
			vec3 rmul=gl_FragData[0].rgb*pcolor.xyz;
			vec3 rscr=one-((one-pcolor.xyz)*(one-gl_FragData[0].rgb));
			gl_FragData[0].rgb=gl_FragData[0].rgb*rscr+(one-gl_FragData[0].rgb)*rmul;
			gl_FragData[1].xy = encode(pnormal.xyz);
			
		#else
		
			#ifdef MSET
			vec3 one=vec3(1.0,1.0,1.0);
			vec3 rmul=gl_FragData[0].rgb*pcolor.xyz;
			vec3 rscr=one-((one-pcolor.xyz)*(one-gl_FragData[0].rgb));
			//gl_FragData[0].rgb=gl_FragData[0].rgb*rscr+(one-gl_FragData[0].rgb)*rmul;
			gl_FragData[0].rgb=mix(gl_FragData[0].rgb,gl_FragData[0].rgb*rscr+(one-gl_FragData[0].rgb)*rmul,terrainColorAmount);
			#else
				#ifdef SKINNING
				#else
					#ifdef _HEIGHTMAP_
					#else
						gl_FragData[0]*=occlusion; 
					#endif
				#endif
			#endif
		
			// normal
			gl_FragData[1].xy=encode(TBN*fnormal.xyz);
			
		#endif
			
	#endif
	
	//float lum=dot(fdcolor,vec3(0.27, 0.67, 0.06));
	
	gl_FragData[1].z=ffresnel.x;//*0.0625;
	gl_FragData[1].a=backScatter;//*scatterMask;
	
	// pos
	//vec2 vel=((curpos.xy/curpos.w)-(prev.xy/prev.w))*vScale;
	
	// material params
//	float M=mix(metal,matID,isNotMetal); // matID if isNotMetal=1 else metal
	gl_FragData[2].r=matID;//M;//scatterlevel*scatterMask; 
	gl_FragData[2].g=ffresnel.y;///256;//*0.25; 
	//gl_FragData[2].ba=(vel*vec2(0.5))+vec2(0.5);
}
