varying vec2 		texcoord,
					alphacoord;

uniform sampler2D 	dif0,
					bmp0;
uniform vec2		fresnel0,
					spec0;
uniform vec4		dcolor0,
					scolor0;
uniform vec2		dscale0,
					bscale0;
uniform float 		scatterlevel;
uniform vec2		dofs0,
					bofs0;
uniform vec4 		colorMod;	// a = decal life
varying float		fadeAlpha;
				
varying mat3		TBN;

uniform float		matID;
uniform float		metal0;
uniform sampler2D 	lmask;
		
#ifdef LAYER1
	uniform float		metal1;
	uniform sampler2D 	dif1,
						bmp1;
	uniform vec2		fresnel1,
						spec1;
	uniform vec4		dcolor1,
						scolor1;
	uniform vec2		dscale1,
						bscale1;
	uniform vec2		dofs1,
						bofs1;
	uniform vec3		maskMul;
	
	#ifdef LAYER2
		uniform float		metal2;
		uniform sampler2D 	dif2,
							bmp2;
		uniform vec2		fresnel2,
							spec2;
		uniform vec4		dcolor2,
							scolor2;
		uniform vec2		dscale2,
							bscale2;	
		uniform vec2		dofs2,
							bofs2;							
							
		#ifdef LAYER3
			uniform float		metal3;	
			uniform sampler2D 	dif3,
								bmp3;
			uniform vec2		fresnel3,
								spec3;
			uniform vec4		dcolor3,
								scolor3;
			uniform vec2		dscale3,
								bscale3;
			uniform vec2		dofs3,
								bofs3;
		#endif

	#endif

#else
	#ifdef _HEIGHTMAP_
		//uniform sampler2D 	lmask;
		uniform vec3		maskMul;
	#endif
	
#endif

#ifdef _HEIGHTMAP_

	uniform sampler2D	heightmap;
	uniform sampler2D	cmask;
	uniform float 		bumpScale;
	uniform vec2		invHeightmapSize;

#endif

#ifdef MACROBUMP
uniform vec2 		addBaseNormal;
#endif

#ifdef MACRODIFFUSE
uniform float		mulBaseDiffuse;
#endif

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

vec3 blend3D(vec4 tex1, vec4 tex2, float alpha)
{
	float depth=0.2;
	float ma=max(tex1.a+(1.0-alpha),tex2.a+alpha)-depth;
	
	float b1=max(tex1.a + (1.0-alpha) - ma,0.0);
	float b2=max(tex2.a + alpha - ma,0.0);
	
	return (tex1.rgb*b1 + tex2.rgb*b2)/(b1+b2);
}

vec2 blend2D(vec2 tex1, vec2 tex2, float a1, float a2, float alpha)
{
	float depth=0.2;
	float ma=max(a1+(1.0-alpha),a2+alpha)-depth;
	
	float b1=max(a1 + (1.0-alpha) - ma,0.0);
	float b2=max(a2 + alpha - ma,0.0);
	
	return (tex1*b1 + tex2*b2)/(b1+b2);
	//return (a1+(1.0-alpha)) > (a2+alpha) ? tex1 : tex2;
}

float blend1D(float f1, float f2, float a1, float a2, float alpha)
{
	float depth=0.2;
	float ma=max(a1+(1.0-alpha),a2+alpha)-depth;
	
	float b1=max(a1 + (1.0-alpha) - ma,0.0);
	float b2=max(a2 + alpha - ma,0.0);
	
	return (f1*b1 + f2*b2)/(b1+b2);
	//return (a1+(1.0-alpha)) > (a2+alpha) ? f1 : f2;
}

void main()
{

	vec4 	texcolor;
	vec4 	fdcolor,
			fbcolor;
	vec3	fnormal;
	vec2	fspec,
			ffresnel;
			
	fdcolor=texture2D(dif0,texcoord.st*dscale0+dofs0);
	fdcolor.rgb=pow(fdcolor.rgb,vec3(2.2))*dcolor0.rgb;
	
	#ifndef LAYER1
		#ifndef _HEIGHTMAP_
			float alpha=clamp(texture2D(lmask,alphacoord.st).a*fadeAlpha,0.0,1.0);//alphalevel*colorMod.a;
			alpha=blend1D(0.0, 1.0, 0.8, fdcolor.a, alpha);
		#endif
	#endif
	
	#ifdef MACROBUMP
		
		vec4 baseNormal=texture2D(bmp0,texcoord.st*bscale0+bofs0);
		baseNormal.xy=baseNormal.xy*2.0-1.0;
		fnormal=vec3(0,0,0);
		ffresnel.y=fresnel0.y*baseNormal.z;
		ffresnel.x=fresnel0.x;//*baseNormal.a;
		baseNormal.z=sqrt(1.0-baseNormal.x*baseNormal.x-baseNormal.y*baseNormal.y);
		vec2 baseFresnel=ffresnel;
		
	#else

		fbcolor=texture2D(bmp0,texcoord.st*bscale0+bofs0);
		fnormal.xy=(fbcolor.xy*2.0-1.0);
		ffresnel.x=fresnel0.x;//*fbcolor.a;
		ffresnel.y=fresnel0.y*fbcolor.z;

	#endif
	
	#ifdef _HEIGHTMAP_
	
	/* PROVA NORMAL COMPUTATION */
		float 	h00,
				h10,
				h01;
		h00=texture2D(heightmap,texcoord.st).r;
		h10=texture2D(heightmap,texcoord.st+vec2(invHeightmapSize.x,0.0)).r;
		h01=texture2D(heightmap,texcoord.st+vec2(0.0,invHeightmapSize.y)).r;
		
		vec3 binormal3=(vec3(0.0,0.0,h00)-vec3(invHeightmapSize.x*bumpScale,0.0,h10));
		vec3 tangent3=(vec3(0.0,0.0,h00)-vec3(0.0,invHeightmapSize.y*bumpScale,h01));
		vec3 normal3=normalize(cross(binormal3,tangent3));
		normal3.y=-normal3.y;
		
	#endif

	#ifdef LAYER1

		vec4 	mask=clamp(texture2D(lmask,texcoord.st)*vec4(maskMul,1.0),0.0,1.0);
		float 	alpha=mask.a*fadeAlpha;
		float 	sum=fdcolor.a;
					
		texcolor=texture2D(dif1,texcoord.st*dscale1+dofs1);
		texcolor.rgb=pow(texcolor.rgb,vec3(2.2));
		fdcolor.xyz=blend3D(fdcolor,texcolor*dcolor1,mask.r);
		fbcolor=texture2D(bmp1,texcoord.st*bscale1+bofs1);
		fnormal.xy=blend2D(fnormal.xy,(fbcolor.xy*2.0-1.0),fdcolor.a,texcolor.a,mask.r);
		ffresnel.y=blend1D(ffresnel.y,fresnel1.y*fbcolor.z,fdcolor.a,texcolor.a,mask.r);
		ffresnel.x=blend1D(ffresnel.x,fresnel1.x/*fbcolor.a*/,fdcolor.a,texcolor.a,mask.r);			
		sum += mask.r*texcolor.a;
		
		#ifdef LAYER2
		
			texcolor=texture2D(dif2,texcoord.st*dscale2+dofs2);
			texcolor.rgb=pow(texcolor.rgb,vec3(2.2));
			fdcolor.xyz=blend3D(fdcolor,texcolor*dcolor2,mask.g);		
			fbcolor=texture2D(bmp2,texcoord.st*bscale2+bofs2);
			fnormal.xy=blend2D(fnormal.xy,(fbcolor.xy*2.0-1.0),fdcolor.a,texcolor.a,mask.g);
			ffresnel.y=blend1D(ffresnel.y,fresnel2.y*fbcolor.z,fdcolor.a,texcolor.a,mask.g);
			ffresnel.x=blend1D(ffresnel.x,fresnel2.x/*fbcolor.a*/,fdcolor.a,texcolor.a,mask.g);			
			sum += mask.g*texcolor.a;
			
			#ifdef LAYER3
			
				texcolor=texture2D(dif3,texcoord.st*dscale3+dofs3);
				texcolor.rgb=pow(texcolor.rgb,vec3(2.2));
				fdcolor.xyz=blend3D(fdcolor,texcolor*dcolor3,mask.b);					
				fbcolor=texture2D(bmp3,texcoord.st*bscale3+bofs3);
				fnormal.xy=blend2D(fnormal.xy,(fbcolor.xy*2.0-1.0),fdcolor.a,texcolor.a,mask.b);
				ffresnel.y=blend1D(ffresnel.y,fresnel3.y*fbcolor.z,fdcolor.a,texcolor.a,mask.b);
				ffresnel.x=blend1D(ffresnel.x,fresnel3.x/*fbcolor.a*/,fdcolor.a,texcolor.a,mask.b);		
				sum += mask.b*texcolor.a;
				
			#endif

		#endif
		
		sum = min(sum, 1.0);
		alpha=blend1D(0.0, 1.0, 0.8, sum, alpha);
		
	#else
		#ifdef _HEIGHTMAP_
			vec4 	mask=clamp(texture2D(lmask,texcoord.st)*vec4(maskMul,1.0),0.0,1.0);
			float 	alpha=mask.a*fadeAlpha;
			alpha=blend1D(0.0, 1.0, 0.8, fdcolor.a, alpha);
		#endif
	#endif

	#ifdef MACROBUMP

		fnormal.z=0.0;
		fnormal=baseNormal+fnormal;
		normalize(fnormal);
		ffresnel = mix(ffresnel,baseFresnel,vec2(addBaseNormal.y));
	
	#else
	
		fnormal.z=sqrt(1.0-fnormal.x*fnormal.x-fnormal.y*fnormal.y);
	
	#endif
	
	#ifdef _HEIGHTMAP_

		vec3 one=vec3(1.0,1.0,1.0);
		vec3 two=vec3(2.0,2.0,2.0);
		vec3 mid=vec3(0.5,0.5,0.5);
		vec3 textureColor=pow(texture2D(cmask,texcoord.st).rgb,vec3(2.2));
		
		vec3 maskColor=textureColor;
		
		vec3 rmul=fdcolor.rgb*maskColor.rgb;
		vec3 rscr=one-((one-maskColor.rgb)*(one-fdcolor.rgb));
		fdcolor.rgb=fdcolor.rgb*rscr+(one-fdcolor.rgb)*rmul;
		
		fnormal=normalize(normal3+vec3(fnormal.x,fnormal.y,0.0));//*4.0);
				
	#endif
	
	gl_FragData[0]=max(vec4(fdcolor.xyz*alpha,alpha),0.0);
	
	// normal
	gl_FragData[1].xy=encode(TBN*(fnormal/*+vec3(0.0,0.0,20.0)*/))*alpha;
	gl_FragData[1].z=ffresnel.x*alpha;						// specularity
	gl_FragData[1].a=alpha;//fdcolor.a;//*alphalevel;
		
	// material params
	gl_FragData[2].r=0.0;//matID*alpha;//(floor(glossPow)*32.0 + floor(fspec.y));//fspec.x;
	gl_FragData[2].g=ffresnel.y*alpha;//fspec.y;
	gl_FragData[2].b=0.0;
	gl_FragData[2].a=alpha;//fdcolor.a;//0.0;//*alphalevel;
}
