#ifdef GL_ES precision mediump int; precision highp float; #endif #define USE_OGRE_FROM_FUTURE #include SAMPLER2D(shadowMap0, 0); SAMPLER2D(shadowMap1, 1); SAMPLER2D(shadowMap2, 2); OGRE_UNIFORMS( uniform vec4 materialColor; uniform vec4 invShadowMapSize0; uniform vec4 invShadowMapSize1; uniform vec4 invShadowMapSize2; uniform vec4 lightPosition[6]; uniform vec4 spotlight[6]; uniform vec4 spotDir[6]; uniform vec4 lightAtt[6]; uniform vec4 lightDiff[6]; uniform vec4 fogParams; uniform vec4 slicePlane; uniform vec4 pssmSplitPoints; ) vec2 lightAttribution(vec3 wp, vec3 normal, int id) { if ((lightAtt[id].x == 0.0) && (lightAtt[id].y == 1.0) && (lightAtt[id].z == 0.0) && (lightAtt[id].w == 0.0)) return vec2(0.0, 0.0); vec3 ld = normalize(lightPosition[id].xyz - (vec3_splat(lightPosition[id].w) * wp.xyz)); float diffFactor = (lightDiff[id].x + lightDiff[id].y + lightDiff[id].z) * 0.333333333; // attenuation if(lightAtt[id].w > 0.0) { float lightDist = length(lightPosition[id].xyz - wp.xyz); if (lightDist > lightAtt[id].x) return vec2(0.0, 0.0); float la = 1.0 / (lightAtt[id].y + lightAtt[id].z * lightDist + lightAtt[id].w * lightDist * lightDist); float spot = (spotlight[id].w == 0.0) ? 1.0 : saturate((dot(-normalize(spotDir[id].xyz - (vec3_splat(spotDir[id].w) * wp.xyz)), ld) - spotlight[id].y) / (spotlight[id].x - spotlight[id].y)); float cb = saturate(saturate(dot(normal, ld)) * spot * la * diffFactor); return vec2(cb, cb); } else { return vec2(saturate(dot(normal, ld) * diffFactor), 0.0); } } float shadowFiltering(sampler2D shadowMap, vec4 shadowUV, vec2 invShadowMapSize) { shadowUV = shadowUV / shadowUV.w; vec2 centerdepth = texture2D(shadowMap, shadowUV.xy).xy; // gradient calculation vec2 s1 = texture2D(shadowMap, shadowUV.xy + vec2(-invShadowMapSize.x, 0.0)).xy; vec2 s2 = texture2D(shadowMap, shadowUV.xy + vec2(+invShadowMapSize.x, 0.0)).xy; vec2 s3 = texture2D(shadowMap, shadowUV.xy + vec2(0.0, -invShadowMapSize.y)).xy; vec2 s4 = texture2D(shadowMap, shadowUV.xy + vec2(0.0, +invShadowMapSize.y)).xy; float final = (centerdepth.x > shadowUV.z) ? 0.0 : centerdepth.y; final += (s1.x > shadowUV.z) ? 0.0 : s1.y; final += (s2.x > shadowUV.z) ? 0.0 : s2.y; final += (s3.x > shadowUV.z) ? 0.0 : s3.y; final += (s4.x > shadowUV.z) ? 0.0 : s4.y; final *= 0.2; return final; } MAIN_PARAMETERS IN(vec3 oUv, TEXCOORD0) IN(vec3 oNormal, TEXCOORD1) IN(vec3 oWp, TEXCOORD2) IN(vec4 oLightPosition0, TEXCOORD3) IN(vec4 oLightPosition1, TEXCOORD4) IN(vec4 oLightPosition2, TEXCOORD5) MAIN_DECLARATION { if(((slicePlane.x + slicePlane.y + slicePlane.z) != 0.0) && (slicePlane.x * oWp.x + slicePlane.y * oWp.y + slicePlane.z * oWp.z + slicePlane.w > 0.0)) discard; // get alpha float alpha = materialColor.a; vec2 ld0 = lightAttribution(oWp, oNormal, 0); vec2 ld1 = lightAttribution(oWp, oNormal, 1); vec2 ld2 = lightAttribution(oWp, oNormal, 2); vec2 ld3 = lightAttribution(oWp, oNormal, 3); vec2 ld4 = lightAttribution(oWp, oNormal, 4); vec2 ld5 = lightAttribution(oWp, oNormal, 5); float ld = saturate(ld0.x - saturate(ld1.y + ld2.y + ld3.y + ld4.y + ld5.y)); // calculate shadow float shadow = 0.0; //vec4 splitColour; if (oUv.z <= pssmSplitPoints.y) { //splitColour = vec4(1.0, 0.0, 0.0, 1.0); shadow = shadowFiltering(shadowMap0, oLightPosition0, invShadowMapSize0.xy); } else if (oUv.z <= pssmSplitPoints.z) { //splitColour = vec4(0, 1.0, 0.0, 1.0); shadow = shadowFiltering(shadowMap1, oLightPosition1, invShadowMapSize1.xy); } else { //splitColour = vec4(1.0, 1.0, 0.0, 1.0); shadow = shadowFiltering(shadowMap2, oLightPosition2, invShadowMapSize2.xy); } float fog = saturate((fogParams.z - oUv.z) * fogParams.w); shadow *= fog * ld * alpha; // Calculate total pixel brightness vec3 brightness = vec3_splat(1.0 - shadow); gl_FragColor = vec4(brightness, shadow); }