Sign in to follow this  

Basic Shadow Mapping

This topic is 1110 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I've implemented shadow mapping in my WebGL application based on WebGL Programming Guide by Matsuda et al. The shadow mapping is generally working, but when my depth bias is lower than 0.005 I get this weird black box:

 

h81qaAX.jpg

 

CQD6Wiq.jpg

 

Additionally, without a depth bias you'd expect shadow acne, but in this case I just get a more exaggerated black box covering more of the area.

 

Depth map generation fragment shader:

precision mediump float;

vec4 pack_float(float value)
{
    const vec4 bit_shift = vec4(256.0*256.0*256.0, 256.0*256.0, 256.0, 1.0);
    const vec4 bit_mask  = vec4(0.0, 1.0/256.0, 1.0/256.0, 1.0/256.0);
    vec4 res = fract(value * bit_shift);
    res -= res.xxyz * bit_mask;
    return res;
}

void main() {
    gl_FragColor = pack_float(gl_FragCoord.z);
}

Shadow receiver fragment shader:

precision mediump float;

uniform sampler2D u_Texture0;
uniform sampler2D u_ShadowMap;
uniform vec3 u_LightDirection;

varying vec4 v_PositionFromLight;
varying vec2 v_TexCoord0;
varying vec4 v_Color;
varying vec3 v_Normal;

float unpack_float(vec4 rgba_value)
{
    const vec4 bit_shift = vec4(1.0/(256.0*256.0*256.0), 1.0/(256.0*256.0), 1.0/256.0, 1.0);
    float value = dot(rgba_value, bit_shift);
    return value;
}

float getVisibility(sampler2D shadowMap, vec3 normalizedProjectedPosition)
{
    const int sampleRadius = 1;
    const vec2 shadowMapStep = vec2(1.0 / 2048.0, 1.0 / 2048.0);
    vec2 shadowMapTexCoord = normalizedProjectedPosition.xy;

    float visibility = 0.0, sample;
    for (int y = -sampleRadius; y <= sampleRadius; y++) {
        for (int x = -sampleRadius; x <= sampleRadius; x++) {
            sample = unpack_float(texture2D(shadowMap, shadowMapTexCoord + vec2(x, y) * shadowMapStep));
            if (normalizedProjectedPosition.z > sample + 0.00015)
                visibility += 1.0;
        }
    }
    return 1.0 - visibility / pow(float(sampleRadius) * 2.0 + 1.0, 2.0);
}

void main (void) {
    vec4 lightColor = vec4(vec3(0.8), 1.0);
    float dotp = max(dot(-u_LightDirection, v_Normal), 0.0);
    float visibility = dotp;

    vec3 shadowCoord = (v_PositionFromLight.xyz / v_PositionFromLight.w) / 2.0 + 0.5;
    if (shadowCoord.x >= 0.0 && shadowCoord.x <= 1.0 &&
        shadowCoord.y >= 0.0 && shadowCoord.y <= 1.0) {
        float visibility = getVisibility(u_ShadowMap, shadowCoord);
        dotp *= visibility;
    }

    dotp = max(dotp, 0.2);

    vec4 texel = texture2D(u_Texture0, v_TexCoord0) * v_Color;

    gl_FragColor = vec4(texel.xyz * dotp, texel.w) * lightColor;
}

Shadow matrices:

var cameraPos = Controllers.camera;
var lightNormal = ProcForest.Settings.Lighting.directionalLight.direction;
var lightPos = Math.vecSum(cameraPos, Math.vecMultiply(lightNormal, -1));
shadowModelViewMatrix = new Matrix4();
shadowModelViewMatrix.lookAt(lightPos.x, lightPos.y, lightPos.z, cameraPos.x, cameraPos.y, cameraPos.z, 0, 1, 0);

shadowProjectionMatrix = new Matrix4();
var volumeSize = ProcForest.Settings.maxTreeViewDist * 0.8;
shadowProjectionMatrix.setOrtho(-volumeSize, volumeSize, -volumeSize, volumeSize, -volumeSize, volumeSize); 

Any ideas on why this is happening? If I leave the bias at 0.005 things look alright, but I want to avoid peter panning. The black box tends to be centered at the camera's position, which is where the shadow map is being projected from.

Edited by tylercamp

Share this post


Link to post
Share on other sites

This topic is 1110 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this