Skip to main content
added 489 characters in body
Source Link
Irbis
  • 614
  • 7
  • 22

EditEdit1: Calculating minVariance this way:

gives better results but light bleeding is still quite visible.

Edit2: Light bleeding: EVSM with minVariance which is calculated as above gives better result than VSM without standard light bleeding fix, but to get the best result I also use standard light bleeding fix with EVSM. A light bleeding fix is performed in Chebyshev function but maybe I should add it after following calculation: shadow = min(posResult, negResult) ?

EVSM causes small artifacts on the illuminated side of the objects so I add some glPolygonOffset when saving EVSM depth.

Edit: Calculating minVariance this way:

gives better results but light bleeding is still quite visible.

Edit1: Calculating minVariance this way:

gives better results but light bleeding is still quite visible.

Edit2: Light bleeding: EVSM with minVariance which is calculated as above gives better result than VSM without standard light bleeding fix, but to get the best result I also use standard light bleeding fix with EVSM. A light bleeding fix is performed in Chebyshev function but maybe I should add it after following calculation: shadow = min(posResult, negResult) ?

EVSM causes small artifacts on the illuminated side of the objects so I add some glPolygonOffset when saving EVSM depth.

added 483 characters in body
Source Link
Irbis
  • 614
  • 7
  • 22
float positiveExponent = 40.0f;
float negativeExponent = 5.0f;
 
vec2 warpDepth(float depth)
{
    vec2 exponents = vec2(positiveExponent, negativeExponent);

vec2 warpDepth(float depth)
{
    depth = 2.0f * depth - 1.0f;
    float pos = exp(exponents.x * depth);
    float neg = -exp(-exponents.y * depth);
    vec2 wDepth = vec2(pos, neg);
    return wDepth;
}

float Chebyshev(vec2 moments, float mean, float minVariance)
{
    float shadow = 1.0f;
    if(mean <= moments.x)
    {
        shadow = 1.0f;
        return shadow;
    }
    else
    {
        float variance = moments.y - (moments.x * moments.x);
        variance = max(variance, minVariance);
        float d = mean - moments.x;
        shadow = variance / (variance + (d * d));
        return shadow;
    }
}

vec4 shadowCoord = shadowMatrix * vec4(viewSpacePosition, 1.0f);
vec4 moments = texture(ShadowMap, shadowCoord.xy).xyzw;
vec2 posMoments = vec2(moments.x, moments.z);
vec2 negMoments = vec2(moments.y, moments.w);
vec2 wDepth = warpDepth(shadowCoord.z);
//float minVariance = 0.000001f;
//Edit
vec2 depthScale = 0.0001f * exponents * wDepth;
vec2 minVariance = depthScale * depthScale;
float posResult = Chebyshev(posMoments, wDepth.x, minVariance.x);
float negResult = Chebyshev(negMoments, wDepth.y, minVariance.y);
shadow = min(posResult, negResult);

Unfortunately it doesn't remove light bleeding. Did I do something wrong ? Maybe I should calculate two different minVariance based on the positive and negative exponents ?

Edit: Calculating minVariance this way:

vec2 depthScale = 0.0001f * exponents * wDepth;
vec2 minVariance = depthScale * depthScale;
float posResult = Chebyshev(posMoments, wDepth.x, minVariance.x);
float negResult = Chebyshev(negMoments, wDepth.y, minVariance.y);

gives better results but light bleeding is still quite visible.

float positiveExponent = 40.0f;
float negativeExponent = 5.0f;
 
vec2 warpDepth(float depth)
{
    vec2 exponents = vec2(positiveExponent, negativeExponent);
    depth = 2.0f * depth - 1.0f;
    float pos = exp(exponents.x * depth);
    float neg = -exp(-exponents.y * depth);
    vec2 wDepth = vec2(pos, neg);
    return wDepth;
}

float Chebyshev(vec2 moments, float mean, float minVariance)
{
    float shadow = 1.0f;
    if(mean <= moments.x)
    {
        shadow = 1.0f;
        return shadow;
    }
    else
    {
        float variance = moments.y - (moments.x * moments.x);
        variance = max(variance, minVariance);
        float d = mean - moments.x;
        shadow = variance / (variance + (d * d));
        return shadow;
    }
}

vec4 shadowCoord = shadowMatrix * vec4(viewSpacePosition, 1.0f);
vec4 moments = texture(ShadowMap, shadowCoord.xy).xyzw;
vec2 posMoments = vec2(moments.x, moments.z);
vec2 negMoments = vec2(moments.y, moments.w);
vec2 wDepth = warpDepth(shadowCoord.z);
float minVariance = 0.000001f;
float posResult = Chebyshev(posMoments, wDepth.x, minVariance);
float negResult = Chebyshev(negMoments, wDepth.y, minVariance);
shadow = min(posResult, negResult);

Unfortunately it doesn't remove light bleeding. Did I do something wrong ? Maybe I should calculate two different minVariance based on the positive and negative exponents ?

float positiveExponent = 40.0f;
float negativeExponent = 5.0f;
vec2 exponents = vec2(positiveExponent, negativeExponent);

vec2 warpDepth(float depth)
{
    depth = 2.0f * depth - 1.0f;
    float pos = exp(exponents.x * depth);
    float neg = -exp(-exponents.y * depth);
    vec2 wDepth = vec2(pos, neg);
    return wDepth;
}

float Chebyshev(vec2 moments, float mean, float minVariance)
{
    float shadow = 1.0f;
    if(mean <= moments.x)
    {
        shadow = 1.0f;
        return shadow;
    }
    else
    {
        float variance = moments.y - (moments.x * moments.x);
        variance = max(variance, minVariance);
        float d = mean - moments.x;
        shadow = variance / (variance + (d * d));
        return shadow;
    }
}

vec4 shadowCoord = shadowMatrix * vec4(viewSpacePosition, 1.0f);
vec4 moments = texture(ShadowMap, shadowCoord.xy).xyzw;
vec2 posMoments = vec2(moments.x, moments.z);
vec2 negMoments = vec2(moments.y, moments.w);
vec2 wDepth = warpDepth(shadowCoord.z);
//float minVariance = 0.000001f;
//Edit
vec2 depthScale = 0.0001f * exponents * wDepth;
vec2 minVariance = depthScale * depthScale;
float posResult = Chebyshev(posMoments, wDepth.x, minVariance.x);
float negResult = Chebyshev(negMoments, wDepth.y, minVariance.y);
shadow = min(posResult, negResult);

Unfortunately it doesn't remove light bleeding. Did I do something wrong ? Maybe I should calculate two different minVariance based on the positive and negative exponents ?

Edit: Calculating minVariance this way:

vec2 depthScale = 0.0001f * exponents * wDepth;
vec2 minVariance = depthScale * depthScale;
float posResult = Chebyshev(posMoments, wDepth.x, minVariance.x);
float negResult = Chebyshev(negMoments, wDepth.y, minVariance.y);

gives better results but light bleeding is still quite visible.

Tweeted twitter.com/#!/StackGameDev/status/402680776720150528
added 2071 characters in body
Source Link
Irbis
  • 614
  • 7
  • 22

I use a variance shadow mapping with a "standard" light bleeding fix in my graphics engine which is based on deferred rendering.. I have a single shadow map for a directional light beacause a test scene is relatively small. Saving depth looks like this:

Then I perform a separable gaussian blur on that texture.

iffloat Chebyshev(shadowCoordvec2 moments, float mean, float minVariance)
{
    float shadow = 1.z0f;
    if(mean <= moments.x)
    {
        shadow = 1.0;0f;
        return shadow;
    }
    else
    {
        float variance = moments.y - (moments.x * moments.x);
        variance = max(variance, 0.000001minVariance);
        float d = shadowCoord.zmean - moments.x;
        shadow = variance / (variance + (d * d));
        float amount = 0.3;3f;
        shadow =  clamp((shadow - amount) / (1.00f - amount), 0.00f, 1.00f); // standard light bleeding fix
        return shadow;
    }
}

vec4 shadowCoord = shadowMatrix * vec4(viewSpacePosition, 1.0f); 
vec2 moments = texture(ShadowMap, shadowCoord.xy).xy;
float minVariance = 0.000001f;
float shadow = Chebyshev(moments, shadowCoord.z, minVariance);

How to implement a shadow test for that technique ? Can I additionaly use a "standard"Here is my attempt:

float positiveExponent = 40.0f;
float negativeExponent = 5.0f;

vec2 warpDepth(float depth)
{
    vec2 exponents = vec2(positiveExponent, negativeExponent);
    depth = 2.0f * depth - 1.0f;
    float pos = exp(exponents.x * depth);
    float neg = -exp(-exponents.y * depth);
    vec2 wDepth = vec2(pos, neg);
    return wDepth;
}

float Chebyshev(vec2 moments, float mean, float minVariance)
{
    float shadow = 1.0f;
    if(mean <= moments.x)
    {
        shadow = 1.0f;
        return shadow;
    }
    else
    {
        float variance = moments.y - (moments.x * moments.x);
        variance = max(variance, minVariance);
        float d = mean - moments.x;
        shadow = variance / (variance + (d * d));
        return shadow;
    }
}

vec4 shadowCoord = shadowMatrix * vec4(viewSpacePosition, 1.0f);
vec4 moments = texture(ShadowMap, shadowCoord.xy).xyzw;
vec2 posMoments = vec2(moments.x, moments.z);
vec2 negMoments = vec2(moments.y, moments.w);
vec2 wDepth = warpDepth(shadowCoord.z);
float minVariance = 0.000001f;
float posResult = Chebyshev(posMoments, wDepth.x, minVariance);
float negResult = Chebyshev(negMoments, wDepth.y, minVariance);
shadow = min(posResult, negResult);

Unfortunately it doesn't remove light bleeding fix with. Did I do something wrong ? Maybe I should calculate two different minVariance based on the new codepositive and negative exponents ?

I use a variance shadow mapping with a "standard" light bleeding fix. I have a single shadow map for a directional light beacause a test scene is relatively small. Saving depth looks like this:

if(shadowCoord.z <= moments.x)
{
     shadow = 1.0;
}
else
{
     float variance = moments.y - (moments.x * moments.x);
     variance = max(variance, 0.000001);
     float d = shadowCoord.z - moments.x;
     shadow = variance / (variance + (d * d));
     float amount = 0.3;
     shadow =  clamp((shadow - amount) / (1.0 - amount), 0.0, 1.0); // standard light bleeding fix
}

How to implement a shadow test for that technique ? Can I additionaly use a "standard" light bleeding fix with the new code ?

I use a variance shadow mapping with a "standard" light bleeding fix in my graphics engine which is based on deferred rendering.. I have a single shadow map for a directional light beacause a test scene is relatively small. Saving depth looks like this:

Then I perform a separable gaussian blur on that texture.

float Chebyshev(vec2 moments, float mean, float minVariance)
{
    float shadow = 1.0f;
    if(mean <= moments.x)
    {
        shadow = 1.0f;
        return shadow;
    }
    else
    {
        float variance = moments.y - (moments.x * moments.x);
        variance = max(variance, minVariance);
        float d = mean - moments.x;
        shadow = variance / (variance + (d * d));
        float amount = 0.3f;
        shadow =  clamp((shadow - amount) / (1.0f - amount), 0.0f, 1.0f); // standard light bleeding fix
        return shadow;
    }
}

vec4 shadowCoord = shadowMatrix * vec4(viewSpacePosition, 1.0f); 
vec2 moments = texture(ShadowMap, shadowCoord.xy).xy;
float minVariance = 0.000001f;
float shadow = Chebyshev(moments, shadowCoord.z, minVariance);

How to implement a shadow test for that technique ? Here is my attempt:

float positiveExponent = 40.0f;
float negativeExponent = 5.0f;

vec2 warpDepth(float depth)
{
    vec2 exponents = vec2(positiveExponent, negativeExponent);
    depth = 2.0f * depth - 1.0f;
    float pos = exp(exponents.x * depth);
    float neg = -exp(-exponents.y * depth);
    vec2 wDepth = vec2(pos, neg);
    return wDepth;
}

float Chebyshev(vec2 moments, float mean, float minVariance)
{
    float shadow = 1.0f;
    if(mean <= moments.x)
    {
        shadow = 1.0f;
        return shadow;
    }
    else
    {
        float variance = moments.y - (moments.x * moments.x);
        variance = max(variance, minVariance);
        float d = mean - moments.x;
        shadow = variance / (variance + (d * d));
        return shadow;
    }
}

vec4 shadowCoord = shadowMatrix * vec4(viewSpacePosition, 1.0f);
vec4 moments = texture(ShadowMap, shadowCoord.xy).xyzw;
vec2 posMoments = vec2(moments.x, moments.z);
vec2 negMoments = vec2(moments.y, moments.w);
vec2 wDepth = warpDepth(shadowCoord.z);
float minVariance = 0.000001f;
float posResult = Chebyshev(posMoments, wDepth.x, minVariance);
float negResult = Chebyshev(negMoments, wDepth.y, minVariance);
shadow = min(posResult, negResult);

Unfortunately it doesn't remove light bleeding. Did I do something wrong ? Maybe I should calculate two different minVariance based on the positive and negative exponents ?

Source Link
Irbis
  • 614
  • 7
  • 22
Loading