### Shadow map PCF vs. Variance filter

PCF(Percentage closer filer): Because texture precision is not enough to confirm lossless. Therefore, we can reference the neighbor pattern. I use four corner texel( left-top, right-top, left-bottom, right-bottom) and the current texel.

float2 texCoord;

float4 p;

texCoord.x = shadowPos.x + 1/shadowMapSize;

texCoord.y = shadowPos.y - 1/shadowMapSize;

p.x = tex( sm, texCoord ); // left-top

texCoord.xy = shadowPos.xy + 1/shadowMapSize;

p.y = tex( sm, texCoord ); // right-top

texCoord.xy = shadowPos.xy - 1/shadowMapSize;

p.z = tex( sm, texCoord ); // left-bottom

texCoord.x = shadowPos.x + 1/shadowMapSize;

texCoord.y = shadowPos.y - 1/shadowMapSize;

p.w = tex( sm, texCoord ); // right-bottom

float4 resultCorn = ( shadow.z > p ) ? 1 : 0;

float2 result;

result.x = dotProduct4( result, 0.25 );

texCoord.xy = shadowPos.xy;

p.x = tex( sm, texCoord ); // center

result.y = ( shadow.z > p.x ) ? 1 : 0;

float finalResult = dotProduct( result.xxyy, 0.25 );

Variance: We need two shadow map, individually they are record clip-depth and square of clip-depth.

float2 texCoord;

float4 p;

texCoord.x = shadowPos.x + 1/shadowMapSize;

texCoord.y = shadowPos.y - 1/shadowMapSize;

p.x = tex( sm, texCoord ); // left-top

texCoord.xy = shadowPos.xy + 1/shadowMapSize;

p.y = tex( sm, texCoord ); // right-top

texCoord.xy = shadowPos.xy - 1/shadowMapSize;

p.z = tex( sm, texCoord ); // left-bottom

texCoord.x = shadowPos.x + 1/shadowMapSize;

texCoord.y = shadowPos.y - 1/shadowMapSize;

p.w = tex( sm, texCoord ); // right-bottom

float4 resultCorn = ( shadow.z > p ) ? 1 : 0;

float2 result;

result.x = dotProduct4( result, 0.25 );

texCoord.xy = shadowPos.xy;

p.x = tex( sm, texCoord ); // center

result.y = ( shadow.z > p.x ) ? 1 : 0;

float finalResult = dotProduct( result.xxyy, 0.25 );

Variance: We need two shadow map, individually they are record clip-depth and square of clip-depth.

## Comments

## Post a Comment