Here are the shader replacements. It produces a much faster, slightly more accurate shadow/self-shadow map by removing all of the multisample comparisons and border checks… this leaves a lot of room for border blurring and cleanup.

EDIT: Added a quick edit to PostShadow.frag to knock out noise… left the original line commented above the edit.

Here are the shaders…

PreShadow.vert:

[java]attribute vec4 inPosition;

attribute vec2 inTexCoord;

uniform mat4 g_WorldViewProjectionMatrix;

uniform mat4 g_WorldViewMatrix;

varying vec2 texCoord;

varying vec4 v_position;

void main(){

gl_Position = g_WorldViewProjectionMatrix * inPosition;

texCoord = inTexCoord;

v_position = gl_Position;

}[/java]

PreShadow.frag

[java]varying vec4 v_position;

void main() {

float depth = v_position.z / v_position.w ;

depth = depth * 0.5 + 0.5;

float moment1 = depth;

float moment2 = depth * depth;

float dx = dFdx(depth);

float dy = dFdy(depth);

moment2 += 0.25*(dx*dx+dy*dy) ;

gl_FragColor = vec4( moment1,moment2, 0.0, 0.0 );

}[/java]

PostShadow.vert - don’t think this one changed

[java]uniform mat4 m_LightViewProjectionMatrix;

uniform mat4 g_WorldViewProjectionMatrix;

uniform mat4 g_WorldMatrix;

varying vec4 projCoord;

attribute vec3 inPosition;

const mat4 biasMat = mat4(0.5, 0.0, 0.0, 0.0,

0.0, 0.5, 0.0, 0.0,

0.0, 0.0, 0.5, 0.0,

0.5, 0.5, 0.5, 1.0);

void main(){

gl_Position = g_WorldViewProjectionMatrix * vec4(inPosition, 1.0);

vec4 worldPos = g_WorldMatrix * vec4(inPosition, 1.0);

vec4 coord = m_LightViewProjectionMatrix * worldPos;

projCoord = biasMat * coord;

}[/java]

PostShadow.frag

[java]uniform sampler2D m_ShadowMap;

varying vec4 projCoord;

varying vec4 color;

vec4 ShadowCoordPostW;

float chebyshevUpperBound(in float dist) {

float blur = 0.000175;

vec2 moments = texture2D(m_ShadowMap,ShadowCoordPostW.xy).rg;

if (dist <= moments.x)

return 1.0 ;

float variance = moments.y - (moments.x*moments.x);
variance = max(variance,0.002);
float d = dist - moments.x;
// float p_max = variance / (variance + d*d);

// Quick edit to knock out noise

float p_max = smoothstep(0.0,0.99999999,(variance / (variance + d*d)));

return p_max;

}

void main()

{

ShadowCoordPostW = projCoord / projCoord.w;

float shadow = chebyshevUpperBound(ShadowCoordPostW.z);

if (shadow < 1.0) shadow *= 0.75;

// for solid shadows use: if (shadow < 1.0) shadow = 0.75;

gl_FragColor = vec4(vec3(shadow),1.0);

}[/java]

You can see that the post shadow frag has no need for Shadow.glsl and is incredibly simplified all the way around producing better results only taking one sample.