# Variance Shadow Mapping (Shadow occurs when normal vector is close to light direction)

I am implementing Variance Shadow Mapping from Nvidia GPU Gems 3 Chapter 8: Summed-Area Variance Shadow Maps

There they are talking about clamping the minimum variance to a very small value. I did that and depending on that value I can decide between two different errors.

But first, here is the fragment shader for creating the shadow map:

varying vec4 positionLightSpace;
vec2 computeMoments(float distToLight)
{
vec2 moments;
moments.x = distToLight;
float dx = dFdx(distToLight);
float dy = dFdy(distToLight);
moments.y = distToLight * distToLight + 0.25 * (dx * dx + dy * dy);
return moments;
}

void main()
{
//convert length to [m]. otherwise the derivatives (dFdx, dFdy) are 0
float distToLight = length(1.0e3 * positionLightSpace.xyz);
gl_FragColor = vec4(computeMoments(distToLight), 0.0, 1.0);
}


After creating this shadow map, the shadow map will be blurred by a gaussian 3x3 filter to smooth the edges.

And this is the fragment shader to check whether there is shadow or not:

float chebyshevUpperBound(sampler2D shadowTex, vec4 shadowCoord, float depth)
{
//One-tailed inequality valid if distance > moments.x
float p = (depth <= moments.x) ? 1.0 : 0.0;
//Compute variance
float minVariance = 1.0e-7; // <=== this is the value I am talking about ===
float variance = moments.y - (moments.x * moments.x);
variance = max(variance, minVariance);
//Compute probabilistic upper bound
float deltaDepth = depth - moments.x;
//clamp pMax in order to reduce light bleeding
float minVal = 0.1;
float maxVal = 1.0;
pMax = smoothstep(minVal, maxVal, pMax);
return max(p, pMax);
}


When setting minVariance to value 1.0e-7, the shadow looks like this:

Here the black dots (1) occur when surface normal vector points close towards the light direction (not good). Light bleeding (3) occurs at some regions (not good). but the shadows starts even for small distance differences (2)(very good). So the shadow touches the geometry, which I prefer.

When setting minVariance to value 1.0e-2, the shadow looks like this:

Here the black dots (1) have disappeared (very good). Light bleeding (3) has gone as well (very good). But the shadows starts at far distance (2) (not good).

I tested to set the minVariance to values between 1.0e-7 and 1.0e-2. But no setting fulfills the aspect to cancel "light bleeding" and the black dots and start shadow at small distances. How can I achieve that?

BTW: The shadow texture has format: RGB32F.

• mainly I figured out, that the biggest problems are the black dots which appear when surface normal is pointing in light direction. Does someone has an idea how to fix that? May 5, 2022 at 14:13