uniform sampler2D Texture; uniform sampler2D NormalMap; uniform int NormalMapExists; uniform float FogBeginDistance; uniform float FogEndDistance; uniform vec4 FogColor; varying vec2 texCoord; varying vec3 camVec; varying vec3 lightVec; varying vec3 vertexPos; //For shadows uniform sampler2D ShadowMapGlobal; uniform sampler2D ShadowMapLocal; uniform float ShadowClampValue; varying vec4 vPos; varying vec4 gPos; float CalcPCFGlobal(vec4 shadowCoord); float CalcPCFLocal(vec4 shadowCoord); vec2 myrand2(vec2 co) { return vec2(fract(sin(dot(co.xy ,vec2(12.9898,78.233))) * 43758.5453), fract(sin(dot(vec2(1-co.y,1-co.x) ,vec2(12.9898,78.233))) * 43758.5453)); } float shadowCoef() { vec4 shadow_coord = gl_TextureMatrix[3]*vPos; float shadow_d; float pcf; if (shadow_coord.x < 0.0 || shadow_coord.x > 1.0 || shadow_coord.y < 0.0 || shadow_coord.y > 1.0) { shadow_coord = gl_TextureMatrix[2]*vPos; shadow_coord.w = shadow_coord.z; pcf = CalcPCFGlobal(shadow_coord); } else { shadow_coord.w = shadow_coord.z; pcf = CalcPCFLocal(shadow_coord); } return clamp(1.0 - pcf, ShadowClampValue, 1.0); } float CalcPCFGlobal(vec4 shadowCoord) { float diff; float shadow_d; vec3 shadow_coord = shadowCoord.xyz; shadow_d = texture2D(ShadowMapGlobal, shadow_coord.xy).x; diff = clamp(60000*(shadow_d - shadow_coord.z+0.004), 0.0, 1.0); shadow_coord.x += 0.001; shadow_d = texture2D(ShadowMapGlobal, shadow_coord.xy).x; diff += clamp(60000*(shadow_d - shadow_coord.z+0.004), 0.0, 1.0); shadow_coord.xy = shadowCoord.xy; shadow_coord.x -= 0.001; shadow_d = texture2D(ShadowMapGlobal, shadow_coord.xy).x; diff += clamp(60000*(shadow_d - shadow_coord.z+0.004), 0.0, 1.0); shadow_coord.xy = shadowCoord.xy; shadow_coord.y += 0.001; shadow_d = texture2D(ShadowMapGlobal, shadow_coord.xy).x; diff += clamp(60000*(shadow_d - shadow_coord.z+0.004), 0.0, 1.0); shadow_coord.xy = shadowCoord.xy; shadow_coord.y -= 0.001; shadow_d = texture2D(ShadowMapGlobal, shadow_coord.xy).x; diff += clamp(60000*(shadow_d - shadow_coord.z+0.004), 0.0, 1.0); return diff*0.2; } float CalcPCFLocal(vec4 shadowCoord) { float diff; float shadow_d; vec3 shadow_coord; shadow_coord = shadowCoord.xyz; shadow_d = texture2D(ShadowMapLocal, shadow_coord.xy).x; diff = clamp(60000*(shadow_d - shadow_coord.z+0.004), 0.0, 1.0); shadow_coord.xy = shadowCoord.xy; shadow_coord.x += 0.001; shadow_coord.xy = shadow_coord.xy + myrand2(shadow_coord.xy)*0.004; shadow_d = texture2D(ShadowMapLocal, shadow_coord.xy).x; diff += clamp(60000*(shadow_d - shadow_coord.z+0.004), 0.0, 1.0); shadow_coord.xy = shadowCoord.xy; shadow_coord.x -= 0.001; shadow_coord.xy = shadow_coord.xy + myrand2(shadow_coord.xy)*0.004; shadow_d = texture2D(ShadowMapLocal, shadow_coord.xy).x; diff += clamp(60000*(shadow_d - shadow_coord.z+0.004), 0.0, 1.0); shadow_coord.xy = shadowCoord.xy; shadow_coord.y += 0.001; shadow_coord.xy = shadow_coord.xy + myrand2(shadow_coord.xy)*0.004; shadow_d = texture2D(ShadowMapLocal, shadow_coord.xy).x; diff += clamp(60000*(shadow_d - shadow_coord.z+0.004), 0.0, 1.0); shadow_coord.xy = shadowCoord.xy; shadow_coord.y -= 0.001; shadow_coord.xy = shadow_coord.xy + myrand2(shadow_coord.xy)*0.004; shadow_d = texture2D(ShadowMapLocal, shadow_coord.xy).x; diff += clamp(60000*(shadow_d - shadow_coord.z+0.004), 0.0, 1.0); shadow_coord.xy = shadowCoord.xy; shadow_coord.x += 0.001; shadow_coord.y += 0.001; shadow_coord.xy = shadow_coord.xy + myrand2(shadow_coord.xy)*0.004; shadow_d = texture2D(ShadowMapLocal, shadow_coord.xy).x; diff += clamp(60000*(shadow_d - shadow_coord.z+0.004), 0.0, 1.0); shadow_coord.xy = shadowCoord.xy; shadow_coord.x -= 0.001; shadow_coord.y += 0.001; shadow_coord.xy = shadow_coord.xy + myrand2(shadow_coord.xy)*0.004; shadow_d = texture2D(ShadowMapLocal, shadow_coord.xy).x; diff += clamp(60000*(shadow_d - shadow_coord.z+0.004), 0.0, 1.0); shadow_coord.xy = shadowCoord.xy; shadow_coord.x += 0.001; shadow_coord.y -= 0.001; shadow_coord.xy = shadow_coord.xy + myrand2(shadow_coord.xy)*0.004; shadow_d = texture2D(ShadowMapLocal, shadow_coord.xy).x; diff += clamp(60000*(shadow_d - shadow_coord.z+0.004), 0.0, 1.0); shadow_coord.xy = shadowCoord.xy; shadow_coord.x -= 0.001; shadow_coord.y -= 0.001; shadow_coord.xy = shadow_coord.xy + myrand2(shadow_coord.xy)*0.004; shadow_d = texture2D(ShadowMapLocal, shadow_coord.xy).x; diff += clamp(60000*(shadow_d - shadow_coord.z+0.004), 0.0, 1.0); return diff*0.11; } void main() { vec3 lVec = lightVec; vec3 cVec = normalize(camVec); float parallax = 0.035; //double refinement float height; float offset; vec2 parallaxTexCoord; if (NormalMapExists != 0) { height = texture2D(NormalMap, texCoord.xy).a; offset = parallax * (2.0 * height - 1.0); parallaxTexCoord = texCoord.xy + offset * cVec.xy; height += texture2D(NormalMap, parallaxTexCoord).a; offset = parallax * (height - 1.0); parallaxTexCoord = texCoord.xy + offset * cVec.xy; } else { parallaxTexCoord = texCoord.xy; } //go-go-go vec3 TexRGB = texture2D(Texture, parallaxTexCoord).xyz; vec3 norm; norm = (1-NormalMapExists) * vec3(0.0,0.0,1.0) + NormalMapExists*(texture2D(NormalMap, parallaxTexCoord).xyz * 2.0 - 1.0); float shineFactor = 15.0 * pow(max(dot(cVec, norm),0.0),gl_FrontMaterial.shininess) / (129.0 - gl_FrontMaterial.shininess); float light_coef; if (lightVec.z <= 0.2) { light_coef = 1.0; } else { light_coef = 1.0 - shadowCoef(); } vec4 ambient = gl_LightSource[0].ambient; vec4 diffuse = gl_FrontMaterial.diffuse * gl_LightSource[0].diffuse * min( max(dot(lVec,norm),0.0), light_coef); vec4 specular = gl_LightSource[0].specular * min(shineFactor, light_coef); float fogFactor = min(max(max(abs(vertexPos.x)-FogBeginDistance, abs(vertexPos.z)-FogBeginDistance),0.0)/(FogEndDistance - FogBeginDistance),1.0); gl_FragColor = mix(vec4(TexRGB,1.0)*ambient+(vec4(TexRGB,1.0)*diffuse+specular), FogColor, fogFactor); }