Shadow mapping with deferred renderer (OpenGL 4.1, GLSL)

I read several articles here in stackoverflow and in some books. But I can not find the error in my code. I have a deferred render and saved albedo, depth and normals (including spec) inside the g-buffer. In addition, a shadow map was created from a light source on top of the scene.

It looks like this:

Albedo (R8G8B8A8): Albedo

Normal (R8G8B8A8): Normal

Linear Depth (F32): enter image description here

Shadow map from a light source (linear depth) (500 meters above the camera): enter image description here

Ok My shadow shader deferred code looks like this: I loaded the basic row matrices.

Vertex Shader:

layout(row_major) uniform UVSViewMatrix
{
    mat4 m_ScreenMatrix;
};

layout(location = 0) in vec3 VertexPosition;

smooth out vec2 PSTexCoord;

void main()
{
    vec4 Position = vec4(VertexPosition.xyz, 1.0f);

    PSTexCoord = Position.xy;

    gl_Position = Position * m_ScreenMatrix;
}

Fragment Shader:

#version 410

// -----------------------------------------------------------------------------
// Input from engine
// -----------------------------------------------------------------------------
layout(row_major) uniform UPSCameraProperties
{
    mat4 m_ProjectionMatrix;
    mat4 m_CameraView;
    vec3 m_CameraPosition;
    vec3 m_CameraDirection;
};

layout(row_major) uniform UPSLightProperties
{
    mat4 m_LightProjection;
    mat4 m_LightView;
    vec4 m_LightPosition;
    vec4 m_LightAmbientIntensity;
    vec4 m_LightDiffuseIntensity;
    vec4 m_LightSpecularIntensity;
};

uniform sampler2D PSTextureAlbedo;
uniform sampler2D PSTextureNormalSpecular;
uniform sampler2D PSTextureDepth;
uniform sampler2D PSTextureShadowMap;

// -----------------------------------------------------------------------------
// Input from vertex shader
// ----------------------------------------------------------------- ------------
smooth in vec2 PSTexCoord;

// -----------------------------------------------------------------------------
// Output to systembuffer
// -----------------------------------------------------------------------------
layout (location = 0) out vec4 PSOutput;

// -----------------------------------------------------------------------------
// Functions
// -----------------------------------------------------------------------------
vec3 GetViewSpacePositionFromDepth(float _Depth, vec2 _ScreenPosition, mat4 _InvertedProjectionMatrix)
{
    // -----------------------------------------------------------------------------
    // Information from:
    // http://mynameismjp.wordpress.com/2009/03/10/reconstructing-position-from-depth/
    // -----------------------------------------------------------------------------
    vec4 ScreenPosition;

    ScreenPosition.x = _ScreenPosition.x * 2.0f - 1.0f;
    ScreenPosition.y = _ScreenPosition.y * 2.0f - 1.0f;
    ScreenPosition.z = _Depth * 2.0f - 1.0f;
    ScreenPosition.w = 1.0f;

    // -----------------------------------------------------------------------------
    // Transform by the inverse projection matrix
    // -----------------------------------------------------------------------------
    vec4 VSPosition = ScreenPosition * _InvertedProjectionMatrix;

    // -----------------------------------------------------------------------------
    // Divide by w to get the view-space position
    // -----------------------------------------------------------------------------
    return (VSPosition.xyz / VSPosition.w);
}

// -----------------------------------------------------------------------------

float GetShadowAtPosition(vec3 _WSPosition)
{
    // -----------------------------------------------------------------------------
    // Set worls space coord into light projection by multiply with light
    // view and projection matrix;
    // -----------------------------------------------------------------------------
    vec4 LSPosition = vec4(_WSPosition, 1.0f) * m_LightView * m_LightProjection;

    // -----------------------------------------------------------------------------
    // Divide xyz by w to get the position in light view clip space.
    // -----------------------------------------------------------------------------
    LSPosition.xyz /= LSPosition.w;

    // -----------------------------------------------------------------------------
    // Get uv texcoords for this position
    // -----------------------------------------------------------------------------
    vec3 ShadowCoord = LSPosition.xyz * 0.5f + 0.5f;

    // -----------------------------------------------------------------------------
    // Get final depth at this texcoord and compare it with the real
    // position z value (do a manual depth test)
    // -----------------------------------------------------------------------------
    float DepthValue = texture( PSTextureShadowMap, vec2(ShadowCoord.x, ShadowCoord.y) ).r;

    float Shadow = 1.0f;

    if (ShadowCoord.z > DepthValue)
    {
        Shadow = 0.3f;
    }

    return Shadow;
}

// -----------------------------------------------------------------------------
// Main
// -----------------------------------------------------------------------------
void main() 
{
    // -----------------------------------------------------------------------------
    // Get informations from g-buffer
    // -----------------------------------------------------------------------------
    vec2 TexCoord = vec2(PSTexCoord.s, 1.0f - PSTexCoord.t);

    vec4  AlbedoColor      = texture(PSTextureAlbedo        , TexCoord);
    vec4  NormalSpec       = texture(PSTextureNormalSpecular, TexCoord);
    float Depth            = texture(PSTextureDepth         , TexCoord).r;
    vec3  VSPosition       = GetViewSpacePositionFromDepth(Depth, TexCoord, inverse(m_ProjectionMatrix));
    vec3  Normal           = normalize(NormalSpec.xyz);
    float SpecularExponent = NormalSpec.w;

    vec4  WSPosition = vec4(VSPosition, 1.0f) * inverse(m_CameraView);

    // -----------------------------------------------------------------------------
    // Compute lighting (Light Accumulation)
    // -----------------------------------------------------------------------------
    vec3 CameraPosition  = m_CameraPosition.xyz;
    vec3 LightPosition   = m_LightPosition.xyz;
    vec3 EyeDirection    = WSPosition.xyz - CameraPosition;
    vec3 LightDirection  = normalize(LightPosition - WSPosition.xyz);
    vec3 LightReflection = normalize(-reflect(LightDirection, Normal));

    vec4 AmbientColor  = m_LightAmbientIntensity;
    vec4 DiffuseColor  = clamp(m_LightDiffuseIntensity * max(dot(Normal, LightDirection), 0.0f), 0.0f, 1.0f);
    vec4 SpecularColor = clamp(m_LightSpecularIntensity * pow(max(dot(LightReflection, EyeDirection), 0.0f), SpecularExponent), 0.0f, 1.0f);

    float Shadow = GetShadowAtPosition(WSPosition.xyz);

    // -----------------------------------------------------------------------------
    // Final result
    // -----------------------------------------------------------------------------
    PSOutput = vec4((AlbedoColor * (AmbientColor + DiffuseColor) * Shadow).xyz, 1.0f);
}

In the end, my result looks like this: Result always with shadow

Could anyone see my mistake?

Some measurement results:

  • ShadowCoord.xy is always 0.5, 0.5

  • ShadowCoord.z ​​ 1.0p

:

   LightProjection
    (
     1.29903805f, 0.0f,         0.0,          0.0f,
     0.0f,        1.73205066f,  0.0f,         0.0f,
     0.0f,        0.0f,        -1.00024426f, -1.0f,
     0.0f,        0.0f,        -1.00024426f,  0.0f
     );

   LightView
    (
     1.0f, 0.0f,     0.0f, 0.0f,
     0.0f, 1.0f,     0.0f, 0.0f,
     0.0f, 0.0f,     1.0f, 0.0f,
     0.0f, 0.0f, -1500.0f, 1.0f
     );

   CameraProjection
    (
     1.29903805f, 0.0f,         0.0f,         0.0f,
     0.0f,        1.73205066f,  0.0f,         0.0f,
     0.0f,        0.0f,        -1.00024426f, -1.0f,
     0.0f,        0.0f,        -1.00024426f,  0.0f
     );

   CameraView
    (
     1.0f, 0.0f,    0.0f, 0.0f,
     0.0f, 1.0f,    0.0f, 0.0f,
     0.0f, 0.0f,    1.0f, 0.0f,
     0.0f, 0.0f, -1000.0f, 1.0f
     );
+4
1

, , - . , " " (F32) " G- , , . , .

, (gl_FragCoord.z), Z :

float ShadowCoordZ = -(vec4(_WSPosition, 1.0f) * m_LightView).z;

"ShadowCoord.xy 0.5, 0.5" . , G- . , ? , - ? , .

+1

All Articles