#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); SAMPLER2D(shadowMap3, 3); OGRE_UNIFORMS( uniform vec4 materialColor; uniform vec4 invShadowMapSize0; uniform vec4 invShadowMapSize1; uniform vec4 invShadowMapSize2; uniform vec4 invShadowMapSize3; 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; ) float shadowFiltering(sampler2D shadowMap, vec4 slightPosition, vec4 invShadowMapSize) { vec3 shadowUV = slightPosition.xyz / vec3_splat(slightPosition.w); vec2 centerdepth = texture2D(shadowMap, shadowUV.xy).xy; 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 shadow = (centerdepth.x > shadowUV.z) ? 0.0 : centerdepth.y; shadow += (s1.x > shadowUV.z) ? 0.0 : s1.y; shadow += (s2.x > shadowUV.z) ? 0.0 : s2.y; shadow += (s3.x > shadowUV.z) ? 0.0 : s3.y; shadow += (s4.x > shadowUV.z) ? 0.0 : s4.y; shadow *= 0.2; return shadow; } 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); } } MAIN_PARAMETERS IN(vec3 oWp, TEXCOORD0) IN(vec3 oNormal, TEXCOORD1) IN(vec3 oUv, TEXCOORD2) IN(vec4 oLightPosition0, TEXCOORD3) IN(vec4 oLightPosition1, TEXCOORD4) IN(vec4 oLightPosition2, TEXCOORD5) IN(vec4 oLightPosition3, TEXCOORD6) 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; float fog = saturate((fogParams.z - oUv.z) * fogParams.w); // get alpha float alpha = materialColor.a * fog; // calculate lights vec2 la0 = lightAttribution(oWp, oNormal, 0); vec2 la1 = lightAttribution(oWp, oNormal, 1); vec2 la2 = lightAttribution(oWp, oNormal, 2); vec2 la3 = lightAttribution(oWp, oNormal, 3); vec2 la4 = lightAttribution(oWp, oNormal, 4); vec2 la5 = lightAttribution(oWp, oNormal, 5); //remove shadow when other lights overlap float lc0 = saturate(la0.x - saturate(la1.y + la2.y + la3.y + la4.y + la5.y)); float lc1 = saturate(la1.x - saturate(la0.y + la2.y + la3.y + la4.y + la5.y)); float lc2 = saturate(la2.x - saturate(la0.y + la1.y + la3.y + la4.y + la5.y)); float lc3 = saturate(la3.x - saturate(la0.y + la1.y + la2.y + la4.y + la5.y)); // calculate shadow float shadow = shadowFiltering(shadowMap0, oLightPosition0, invShadowMapSize0) * lc0; shadow += shadowFiltering(shadowMap1, oLightPosition1, invShadowMapSize1) * lc1; shadow += shadowFiltering(shadowMap2, oLightPosition2, invShadowMapSize2) * lc2; shadow += shadowFiltering(shadowMap3, oLightPosition3, invShadowMapSize3) * lc3; shadow = saturate(shadow) * alpha; // Calculate total pixel brightness vec3 brightness = vec3_splat(1.0 - shadow); gl_FragColor = vec4(brightness, shadow); }