I have a WebGL deferred rendering pipeline, where I'm rendering shadow map with VSM technique. The goal is that the scene, or model, is hovering in space, and in addition to casting shadow on itself, it has to cast a shadow on invisible plane below it.

Now my current setup involves a finite plane geometry, but it's rather complicated.

I realized that since I only need the plane's depth, I could model the plane directly in the shadow map fragment shader with signed distance function. The idea seems to work, but I'm having trouble transforming the plane using my view & projection matrices (the renderer doesn't need any model matrix).

float sdPlane(vec3 p, vec4 n) {
    // n must be normalized
    return dot(p,n.xyz) + n.w;

void main(){
    vec2 uv = gl_FragCoord.xy/viewport;

    vec4 eye_data = vec4(
        texture2D(eye_normal, uv).rgb,
        unpack16f(texture2D(eye_depth, uv).rg));
    vec4 eye_data_floor = vec4(
        texture2D(eye_normal_floor, uv).rgb,
        unpack16f(texture2D(eye_depth_floor, uv).rg));

    if (eye_data.w == 0.0) {
      // some big enough constant because the depth clearing value can only
      // be in 0-1 range
      eye_data.w = 1000.0;

    vec3 normal = eye_data.xyz;
    float depth = eye_data.w;

    // clipping planes scaling
    float cps = 1.0 / (far - near);

    float floor_depth = sdPlane(
        (inv_eye_proj * vec4(clip, cps, 1.0)).xyz,
        eye_view * vec4(0.0, 1.0, 0.0, 0.0)
    floor_depth = floor_depth / cps;

    depth = min(depth, floor_depth);

    if (depth == floor_depth) {
        normal = vec3(0.0, 1.0, 0.0);

    depth = near + (depth * (far - near));

    vec4 ro = inv_eye_proj * vec4(clip, 1.0, 1.0);
    vec3 rd = normalize(ro.xyz);
    vec3 eye_p = depth * rd;
    vec3 p = (inv_eye_view * vec4(eye_p, 1.0)).xyz;

    float occlusion = OcclusionVSM(p, normal);
    float lambert = clamp((light_rot * normal).z, 0.0, 1.0);
    float intensity = (occlusion*0.8+0.2) * lambert;

    gl_FragColor = vec4(vec3(intensity), occlusion);

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.