±*#ifdef GL_ES
precision mediump float; 
precision lowp int;
#endif
attribute vec4 pos;
attribute vec4 texcoord;
attribute vec4 normal;
attribute vec4 tangent;
attribute vec4 texcoord1;

uniform mat4 Alice_Matrix_M;
uniform mat4 Alice_Matrix_V;
uniform mat4 Alice_Matrix_P;
uniform mat4 Alice_Matrix_IT_M;
uniform mat4 Alice_Matrix_MainLightProjection;
uniform mat4 Alice_Matrix_MainLightView;

varying vec4 V_Texcoord;
varying vec4 V_Color;
varying vec4 V_Normal;
varying vec4 V_FragWorldPos;
varying vec4 V_LightSpaceFragPos;

vec4 GetNormal(){
	return Alice_Matrix_IT_M*normal;
}
void main()
{
	vec4 world_pos=Alice_Matrix_M*pos;
	V_Texcoord=texcoord;
	V_Color=texcoord1;
	V_FragWorldPos=world_pos;
	V_LightSpaceFragPos=Alice_Matrix_MainLightProjection*Alice_Matrix_MainLightView*Alice_Matrix_M*pos;
	V_Normal=GetNormal();
	gl_Position=Alice_Matrix_P*Alice_Matrix_V*world_pos;
}##ifdef GL_ES
precision mediump float; 
precision lowp int;
#endif
uniform sampler2D Alice_AmbientTexture;//illuminancećemission
uniform sampler2D Alice_DiffuseTexture;//specular texture
uniform sampler2D Alice_SpecularTexture;//specular texture
uniform sampler2D Alice_DepthMap;
uniform vec4 Alice_FragMixSetting;
//----------current world camera pos
uniform vec4 Alice_CameraWorldPos;
//----------param for object-------
uniform vec4 Alice_AmbientMaterial; 
uniform vec4 Alice_DiffuseMaterial;
uniform vec4 Alice_SpecularMaterial;
//----------param for object------
//----------param for light-------
uniform int Alice_LightEnabled[8];
uniform vec4 Alice_LightPos[8];
uniform vec4 Alice_LightAmbient[8];
uniform vec4 Alice_LightDiffuse[8];
//if point light,x(0.0) y(constant) z(linear) w(quadric)
//if spot light,x(exponent) y(constant) z(linear) w(quadric)
uniform vec4 Alice_LightSetting[8];
//if spot light,this is direction(x,y,z), w(specular pow factor)
uniform vec4 Alice_LightSetting1[8];
//----------param for light-------
varying vec4 V_Texcoord;//texcoord
varying vec4 V_Color;//texcoord1
varying vec4 V_Normal;//when not use normal map,this is translated normal
varying vec4 V_FragWorldPos;
varying vec4 V_LightSpaceFragPos;

float CalculateShadow()
{
	vec3 fragPos=V_LightSpaceFragPos.xyz/V_LightSpaceFragPos.w;
	fragPos=fragPos*0.5+vec3(0.5);

	float depthInShadowMap=texture2D(Alice_DepthMap,fragPos.xy).r;
	float currentDepth=fragPos.z;
	vec2 texelSize=vec2(1.0/1280.0,1.0/720.0);//textureSize(Alice_DepthMap,0);
	float shadow=0.0;
	for(int y=-1;y<1;++y)
	{
		for(int x=-1;x<1;++x)
		{
			float pcfDepth=texture2D(Alice_DepthMap,fragPos.xy+texelSize*vec2(x,y)).r;
			shadow+=(currentDepth-0.001)>pcfDepth?1.0:0.0;
		}
	}
	shadow/=9.0;
	return shadow*1.2;
}

vec4 GetAmbientColor(){
	return Alice_AmbientMaterial;
}
vec4 GetDiffuseColor(){
	vec2 texcoord=V_Texcoord.xy;
	texcoord.x=mod(texcoord.x,4.0)/4.0;
	texcoord.y=mod(texcoord.y,4.0)/4.0;
	return texture2D(Alice_DiffuseTexture,texcoord);
}
vec4 GetLightColorOf(int index,vec3 world_pos,vec3 n){
	vec4 lightPos=Alice_LightPos[index];
	vec4 lightAmbient=Alice_LightAmbient[index];
	vec4 lightDiffuse=Alice_LightDiffuse[index];
	vec4 lightSetting=Alice_LightSetting[index];
	vec4 lightSetting1=Alice_LightSetting1[index];
	//ambient light
	vec4 ambientColor=lightAmbient*GetAmbientColor();
	float attenuation=1.0;
	vec3 obj2LightVec3=vec3(0.0,1.0,0.0);
	//check light type
	if(lightPos.w==0.0){//direction light
		obj2LightVec3=lightPos.xyz;
	}else{//point light or spot light
		obj2LightVec3=lightPos.xyz-world_pos;
		float obj2light_distance=length(obj2LightVec3);
		float constant=lightSetting.y;
		float linear=lightSetting.z;
		float quadric=lightSetting.w;
		attenuation=1.0/(constant+linear*obj2light_distance+quadric*quadric*obj2light_distance);
	}
	obj2LightVec3=normalize(obj2LightVec3);
	float diffuseIntensity=0.0;
	diffuseIntensity=max(0.0,dot(obj2LightVec3,n));
	if(lightPos.w!=1.0&&lightPos.w!=0.0){//this is spot light
		if(diffuseIntensity>0.0){//is not dark
			vec3 spot_direction=normalize(lightSetting1.xyz);
			float currentCosThta=max(0.0,dot(-obj2LightVec3,spot_direction));
			float radianCutoff=lightPos.w*3.14/180.0;
			float cosThta=cos(radianCutoff);
			if(currentCosThta>cosThta){//inside cutoff range
				diffuseIntensity=pow(currentCosThta,lightSetting.x);
			}else{
				diffuseIntensity=0.0;
			}
		}
	}
	//diffuse light
	vec4 diffuseColor=lightDiffuse*diffuseIntensity*attenuation;
	return ambientColor+diffuseColor;
}
vec4 GetLightColor(vec3 world_pos,vec3 normal)
{
	vec4 color=vec4(0.0,0.0,0.0,0.0);
	for(int i=0;i<8;i++){
		if(Alice_LightEnabled[i]==1){
			color=color+GetLightColorOf(i,world_pos,normal);
		}
	}
	return color;
}

vec3 GetNormal()
{
	return normalize(V_Normal.xyz);
}

void main()
{
    vec4 color=vec4(0.0,0.0,0.0,0.0);
	
	vec2 texcoord=V_Texcoord.xy;
	texcoord.x=mod(texcoord.x,4.0)/4.0;
	texcoord.y=mod(texcoord.y,4.0)/4.0;
	vec4 stoneColor=texture2D(Alice_AmbientTexture,texcoord);
	vec4 roadColor=texture2D(Alice_SpecularTexture,V_Texcoord.ba);
	color=GetLightColor(V_FragWorldPos.xyz,GetNormal())*GetDiffuseColor()*(1.0-roadColor.r)+stoneColor*roadColor.r;
	
    if(Alice_FragMixSetting.y==1.0){//receive shadow
        float shadow=1.0-CalculateShadow();
        color=color*vec4(shadow,shadow,shadow,1.0);
    }
    gl_FragColor=color;
} c4d0470f98eb11e7acdffcaa14d464d5