varying vec2 		texcoord;

uniform sampler2D 	dif0,
					bmp0,
					noisemap;
uniform sampler2D	thickness;
uniform vec2		fresnel0,
					spec0;
uniform vec4		dcolor0,
					scolor0;
uniform vec2		dscale0,
					bscale0;
uniform vec2		dofs0,
					bofs0;
uniform float 		scatterlevel;
uniform float 		scatterRed;
uniform float 		backScatter;
uniform float		wFar;

uniform float 		reflMul;

uniform float		matID;
	
#ifdef ALPHATEST

	uniform float 		alphalevel;
	varying float		alphaFade;
	
#endif

#ifdef PSYSTEM

	varying float 	life;
	varying float	cosa,
			sina;
					
#else

	#ifdef BSET

		varying vec4 pnormal;
		varying vec4 pcolor;

	#else
	
		varying mat3	TBN;
		
		#ifdef MSET
		#else
			varying float occlusion; 
		#endif
		
	#endif
		
#endif				


#ifdef LAYER1

	uniform vec3		maskMul;

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

	#endif

#endif


#ifdef _HEIGHTMAP_

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

varying vec4 		curpos,pos,prev;
uniform float		vScale;

uniform float 		fade;

varying vec2 depth;

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

/*half3 decode (half4 enc, float3 view)
{
    half2 fenc = enc*4-2;
    half f = dot(fenc,fenc);
    half g = sqrt(1-f/4);
    half3 n;
    n.xy = fenc*g;
    n.z = 1-f/2;
    return n;
}*/

void main()
{
	#ifdef PSYSTEM
	
		if(life<=0.0)
		discard;
			
	#endif

	vec4 	fdcolor,
			fbcolor;
	vec3	fnormal;
	vec2	fspec,
			ffresnel;
			
	#ifndef _HEIGHTMAP_		
		#ifdef MACRODIFFUSE	
			vec4 baseColor=texture2D(dif0,texcoord.st*dscale0+dofs0)*dcolor0;
			fdcolor=vec4(1.0,1.0,1.0,0.0);
		#else
			fdcolor=texture2D(dif0,texcoord.st*dscale0+dofs0)*dcolor0;
		#endif
	#endif
	
	#ifdef ALPHATEST

		#ifdef PSYSTEM
			float alpha=fdcolor.a*life;
			if(alpha<=alphalevel)
				discard;
		#else
			#ifdef BSET
				float alpha=texture2D(noisemap,texcoord.st).r;
				if(alpha>pcolor.w)
					discard;
			#else
				#ifdef MSET
					float alpha=texture2D(noisemap,texcoord.st*5.0).r;
					if(alpha>fade)
						discard;
				#else
					#ifdef _HEIGHTMAP_
					#else
						#ifdef SKINNING
						#else
							#ifndef _NOT_INSTANCED_
								float alpha=texture2D(noisemap,texcoord.st*5.0).r;
								if(alpha>alphaFade)
									discard;
							#else
								float alpha=texture2D(noisemap,texcoord.st*5.0).r;
								if(alpha>fade)
									discard;
							#endif
						#endif
					#endif
				#endif
			#endif
			
			if(fdcolor.a<=alphalevel)
				discard;
		#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);
	//	fspec.x=0.0;
	//	ffresnel.x=0.0;
		//float basefresnel=fresnel0.y*baseNormal.z;
		ffresnel.y=fresnel0.y*baseNormal.z;//1.0;//basefresnel;
		baseNormal.z=sqrt(1.0-baseNormal.x*baseNormal.x-baseNormal.y*baseNormal.y);
		
	#else

		#ifdef BSET
		
		#else
			fbcolor=texture2D(bmp0,texcoord.st*bscale0+bofs0);
			fnormal.xy=(fbcolor.xy*2.0-1.0);

		#endif

		//ffresnel.x=fresnel0.x;
		ffresnel.y=fresnel0.y*fbcolor.z;

	#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=texture2D(dif0,texcoord.st*8.0);
		
		//float invSlope=1.0-vSlope;
		fbcolor.xyz=vec3(0.0,0.0,1.0);//normalize(fbcolor.xyz+vec3(0.0,0.0,2.0));
		fnormal=mix(normalize(fnormal),fbcolor.xyz,vSlope);//fbcolor.xyz*vSlope + invSlope*fnormal;
		
		fdcolor=texture2D(dif0,texcoord.st*dscale0+dofs0)*dcolor0;
		fdcolor=fdcolor*(1.0-t)+f0*t;
		
		vec4 baseColor=texture2D(baseTex,baseCoords);
		fdcolor.xyz=mix(fdcolor.xyz,baseColor.xyz,vSlope);//baseColor.xyz*vSlope + invSlope*fdcolor.xyz;	
		ffresnel.y=mix(ffresnel.y,baseColor.a,vSlope);//baseColor.a*vSlope+invSlope*ffresnel.y;
				
	#endif

	#ifdef LAYER1

//	#ifdef _HEIGHTMAP_
		if(-pos.z<10000.0)
		{
		//	float fade=1.0-clamp( (-pos.z-9000.0)/1000.0,0.0,1.0);
//	#endif
			vec3 	mask=clamp(texture2D(lmask,texcoord.st).rgb*maskMul,vec3(0.0),vec3(1.0));
			
//		#ifdef _HEIGHTMAP_
			
			//float rangeMin=10000.0;//15000.0-5000.0;
			mask.rgb=mix(mask,vec3(0.0,0.0,0.0),( clamp( (-pos.z-7000.0/*rangeMin*/)/(3000.0/*15000.0-rangeMin*/),0.0,1.0) ));
			
//		#endif
			
			vec3	compMask=vec3(1.0,1.0,1.0)-mask;
						
			/*float dist=(-pos.z-fade*0.8)/(fade*0.2);
			float fadeAlpha=(1.0 - (clamp(dist,0.0,1.0)));*/
			
			fdcolor=mix(fdcolor,texture2D(dif1,texcoord.st*dscale1+dofs1)*dcolor1,mask.r);//texture2D(dif1,texcoord.st*dscale1+dofs1)*dcolor1*mask.r + (compMask.r)*fdcolor;	
			fbcolor=texture2D(bmp1,texcoord.st*bscale1+bofs1);
			fnormal.xy=(fbcolor.xy*2.0-1.0)*mask.r + (compMask.r)*fnormal.xy;
			ffresnel.y=fresnel1.y*fbcolor.z*mask.r + (compMask.r)*ffresnel.y;
			//ffresnel.x=fresnel1.x*mask.r + (compMask.r)*ffresnel.x;
				
				#ifdef _HEIGHTMAP_
				#endif
				
			#ifdef LAYER2
			
				fdcolor=mix(fdcolor,texture2D(dif2,texcoord.st*dscale2+dofs2)*dcolor2,mask.g);//texture2D(dif2,texcoord.st*dscale2+dofs2)*dcolor2*mask.g + (compMask.g)*fdcolor;	
				fbcolor=texture2D(bmp2,texcoord.st*bscale2+bofs2);
				fnormal.xy=(fbcolor.xy*2.0-1.0)*mask.g + (compMask.g)*fnormal.xy;
				ffresnel.y=fresnel2.y*fbcolor.z*mask.g + (compMask.g)*ffresnel.y;
				//ffresnel.x=fresnel2.x*mask.g + (compMask.g)*ffresnel.x;
				
				#ifdef LAYER3
				
					fdcolor=mix(fdcolor,texture2D(dif3,texcoord.st*dscale3+dofs3)*dcolor3,mask.b);//texture2D(dif3,texcoord.st*dscale3+dofs3)*dcolor3*mask.b + (compMask.b)*fdcolor;	
					fbcolor=texture2D(bmp3,texcoord.st*bscale3+bofs3);
					fnormal.xy=(fbcolor.xy*2.0-1.0)*mask.b + (compMask.b)*fnormal.xy;
					ffresnel.y=fresnel3.y*fbcolor.z*mask.b + (compMask.b)*ffresnel.y;
					//ffresnel.x=fresnel3.x*mask.g + (compMask.g)*ffresnel.x;
					
				#endif

			#endif
			
//	#ifdef _HEIGHTMAP_
		}
//	#endif
		
	#endif

	#ifdef MACROBUMP

		fnormal.z=0.0;
		fnormal=baseNormal.xyz+fnormal;
		normalize(fnormal);
		//ffresnel.y*=basefresnel;
		
	#else
	
		// normalize resultant normal
		fnormal.z=sqrt(1.0-fnormal.x*fnormal.x-fnormal.y*fnormal.y);
	//	normalize(fnormal);
	
	#endif
	
	#ifdef MACRODIFFUSE	
		fdcolor=baseColor*fdcolor;
	#endif

	
	#ifdef _HEIGHTMAP_

		vec3 one=vec3(1.0,1.0,1.0);
		vec4 maskColor=texture2D(cmask,texcoord.st);
		vec3 rmul=fdcolor.rgb*maskColor.rgb;
		vec3 rscr=one-((one-maskColor.rgb)*(one-fdcolor.rgb));
		fdcolor.rgb=fdcolor.rgb*rscr+(one-fdcolor.rgb)*rmul;
		//fdcolor.rgb*=maskColor.a;	// occlusion
		
		//fdcolor.rgb*=maskColor;//vColor;
		
	#endif

	float scatterMask=texture2D(thickness,texcoord).r;
	
	fdcolor.a=scatterlevel*scatterMask;
	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[0].xyz = max(gl_FragData[0].xyz*pcolor.xyz,0.0);
			gl_FragData[1].xy = encode(pnormal.xyz);
			
		#else
		
			// normal
			gl_FragData[1].xy=encode(TBN*fnormal.xyz);
			
			#ifdef MSET
			#else
				#ifdef SKINNING
				#else
					#ifdef _HEIGHTMAP_
					#else
						gl_FragData[0]*=occlusion; 
					#endif
				#endif
			#endif
			
		#endif
			
	#endif
	
	gl_FragData[1].z=reflMul*0.0625;// /16.0;
	gl_FragData[1].a=backScatter;//*scatterMask;
	
	// pos
	vec2 vel=((curpos.xy/curpos.w)-(prev.xy/prev.w))*vScale;///*0.05*/*vScale;
	
	// material params
	gl_FragData[2].r=matID;//scatterlevel*scatterMask; //COSINE POWER (SHININESS) //(floor(glossPow)*32.0 + floor(fspec.y));//fspec.x;	GlossScale=[0...32]
	gl_FragData[2].g=ffresnel.y*0.00390625; //1.0/256.0; //Fresnel (SPECULAR REFLECTANCE)//0.0;//fspec.y;
	gl_FragData[2].ba=(vel*vec2(0.5))+vec2(0.5);//0.0;//floor(fresnPow)*32.0 + floor((ffresnel.y/4.0)*32.0);//);//fspec.x;	fresnScale=[0...32]
	//gl_FragData[2].a=0.0;//ffresnel.x;
	
	/*gl_FragData[1].xy = vel;
	gl_FragData[1].z = pos.z;//wFar;
	
	// scatter
	gl_FragData[1].a=0.0;//scatterlevel;//floor(scatterlevel*256.0)+scatterRed;*/
}
