4

私は、stackoverflow といくつかの本でいくつかの記事を読みました。しかし、コードにエラーが見つかりません。遅延レンダラーがあり、g バッファー内にアルベド、深度、および法線 (スペックを含む) を保存しました。さらに、シーンの上から光源からシャドウ マップを作成しました。

次のようになります。

アルベド (R8G8B8A8): アルベド

通常 (R8G8B8A8): 普通

直線深度 (F32): ここに画像の説明を入力

光源からのシャドウ マップ (線形深度) (カメラから 500 メートル上): ここに画像の説明を入力

Ok。シャドウ マッピングを使用した遅延のシェーダー コードは次のようになります。

頂点シェーダー:

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;
}

フラグメント シェーダー:

#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's 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);
}

最後に、私の結果は次のようになります。 結果は常に影付き

誰かが私の間違いを見ることができましたか?

いくつかの測定結果:

  • ShadowCoord.xy は常に 0.5、0.5 です。

  • ShadowCoord.z の継ぎ目が 1.0f になる

いくつかの変数値を次に示します。

   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 に答える 1

1

私が見ることができる 1 つの問題は、線形深度と双曲線深度の違いです。「Linear Depth (F32)」G バッファーの深さは実際には双曲線のように見えますが、これはコードがこれを予期しているため問題ありません。ただし、ライトの深さは実際には直線的ですが、遠近分割後のクリップ スペースの深さと比較されます。

ライト バッファーの深度を双曲線 ( gl_FragCoord.z) にするのがおそらく最も簡単ですが、目空間 Z と比較するように変更しても機能するはずです。

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

「ShadowCoord.xy は常に 0.5, 0.5 です」というビットは混乱を招きます。G-buffer texture coord が機能しているようです。影ではよくわかりませんが、照明の方程式は機能していますか? もしそうなら、おそらくマトリックスに何か問題がありますか?また、シェーダーでの計算に時間が費やされないように、マトリックスの逆数をユニフォームとして渡します。

于 2014-11-20T10:04:35.513 に答える