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)
  vec2 moments = texture2D(shadowTex, shadowCoord.xy).xy;
  //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;
  float pMax = variance / (variance + deltaDepth * deltaDepth);
  //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:

enter image description here

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:

enter image description here

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.

  • $\begingroup$ 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? $\endgroup$
    – Thomas
    May 5, 2022 at 14:13


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Browse other questions tagged or ask your own question.