Evsm artifacts - light bleeding after shadow's preblur

The andreyp

Newcomer
hey guys - i use standart code from INTEL:

shadow generation

Code:
static const float2 g_EVSMExponents = float2(
     // 20.0f, 10.0f
      40.0f, 20.0f
      );

// Convert depth to EVSM coefficients
// Input depth should be in [0, 1]
float2 WarpDepth(float depth, float2 exponents)
{
    // Rescale depth into [-1, 1]
    depth = 2.0f * depth - 1.0f;
    float pos =  exp( exponents.x * depth);
    float neg = -exp(-exponents.y * depth);
    return float2(pos, neg);
}

// Convert depth value to EVSM representation
float4 ShadowDepthToEVSM(float depth)
{
float2 exponents = g_EVSMExponents;
float2 warpedDepth = WarpDepth(depth, exponents);
return  float4(warpedDepth.xy, warpedDepth.xy * warpedDepth.xy);
}
lighting:

Code:
float ChebyshevUpperBound(float2 moments, float mean, float minVariance)
{
    // Compute variance
    float variance = moments.y - (moments.x * moments.x);
    variance = max(variance, minVariance);
  
    // Compute probabilistic upper bound
    float d = mean - moments.x;
    float pMax = variance / (variance + (d * d));
  
    // One-tailed Chebyshev
    return (mean <= moments.x ? 1.0f : pMax);
}

static const float2 g_EVSMExponents = float2(
      40.0f, 20.0f
      //20.0f, 10.0f
      );

static const float g_EVSM_Derivation =
     //0.0001f
     0.00001f
     ;

// Convert depth to EVSM coefficients
// Input depth should be in [0, 1]
float2 WarpDepth(float depth, float2 exponents)
{
    // Rescale depth into [-1, 1]
    depth = 2.0f * depth - 1.0f;
    float pos =  exp( exponents.x * depth);
    float neg = -exp(-exponents.y * depth);
    return float2(pos, neg);
}

float EVSM(float2 uv,float depth)
{
//    if(uv.x>1||uv.y>1||uv.x<0||uv.y<0) return 0; // discard fragments outside spot projector

    float2 exponents = g_EVSMExponents;
    float2 warpedDepth = WarpDepth(depth, exponents);

// Perform the linear filtering
float4 occluder = texture2D(advancedShadowMap, uv);

// Derivative of warping at depth
    float2 depthScale = g_EVSM_Derivation * exponents * warpedDepth;
    float2 minVariance = depthScale * depthScale;

// Compute the upper bounds of the visibility function both for x and y
    float posContrib = ChebyshevUpperBound(occluder.xz, warpedDepth.x, minVariance.x);
    float negContrib = ChebyshevUpperBound(occluder.yw, warpedDepth.y, minVariance.y);

    return min(posContrib, negContrib);
}
https://dl.dropbox.com/u/5862637/shadowsSHITZ/Новая папка/R.f.d000.jpg

https://dl.dropbox.com/u/5862637/shadowsSHITZ/Новая папка/R.f.d001.jpg

https://dl.dropbox.com/u/5862637/shadowsSHITZ/Новая папка/R.f.d002.jpg

when i use that without any preblur - it is ok, but after blurring i get this shit - it looks like light bleeding - i guess....... what is wrong ? i can give you additive info if u do wish
 
Something is definitely going wrong... your blur kernel seems to be a bit off for starters (you should never see "blocky" gradients like you do there). Regarding the bleeding, what's your depth function? You should be constraining it so that at the very least [0,1] only covers the portion of the light's frustum that intersects the camera frustum (or relevant cascade of it). Even better, SDSM will tighten it up further. Then you clamp anything <0 to zero.

It's very important for any shadow mapping algorithm that you have a good, tight depth function, but it's critically important for filtered shadows where every bit matters (in this case, the EVSM exponent can only go as high/sharp as your depth function and 32-bit floats allow).
 
Back
Top