3

チュートリアルに従って、Minecraft のようなクローンにリアルタイム シャドウ マッピングを追加しようとしています。

最初に何が起こるか:

ここに画像の説明を入力 ここに画像の説明を入力

私が知る限り、シャドウ マップは正しくレンダリングされていますか? 問題は最終パス中にあるようです。

深度テクスチャを作成します。

glGenFramebuffers(1, &m_frameBufferId);
glBindFramebuffer(GL_FRAMEBUFFER, m_frameBufferId);
glGenTextures(1, &m_depthTexture);
glBindTexture(GL_TEXTURE_2D, m_depthTexture);
glTexImage2D(GL_TEXTURE_2D, 0,GL_DEPTH_COMPONENT16, 1024, 1024, 0,GL_DEPTH_COMPONENT, GL_FLOAT, 0);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_NONE);

glFramebufferTexture(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, m_depthTexture, 0);
glDrawBuffer(GL_NONE);

注: シェーダーで sampler2DShadow を使用して GL_COMPARE_R_TO_TEXTURE も使用してみました。同じ結果です。

次に、両方のパスを実行します。

// ====================    Shadow    =====================
glBindFramebuffer(GL_FRAMEBUFFER, m_frameBufferId);
glViewport(0, 0, 1024, 1024);

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

ShadowShader->Bind();
VCSceneGraph::Instance->RenderGraph();


// ====================    Final    =======================
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glViewport(0, 0, 1280, 800);

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

VoxelShader->Bind();
VCSceneGraph::Instance->RenderGraph();

シャドウ シェーダー コード:

// ====================    Vert    =====================
#version 330 core\n

in vec4 vertexPosition_modelspace;
uniform mat4 depthMVP;

void main()
{
    gl_Position =  depthMVP * vertexPosition_modelspace;
}

// ====================    Frag    =====================
#version 330 core\n

out float fragmentdepth;

void main()
{
    fragmentdepth = gl_FragCoord.z;
}

Final-Pass (ボクセル シェーダー) コード:

// ====================    Vert    =====================
#version 330 core\n

in vec3 position;
in int normal;
in vec4 color;

out vec4 colorVarying;
out vec4 ShadowCoord;

uniform mat4 modelViewProjectionMatrix;
uniform mat4 DepthBiasMVP;

void main()
{
    gl_Position =  modelViewProjectionMatrix * vec4(position, 1);
    ShadowCoord = DepthBiasMVP * vec4(position, 1);
    colorVarying = color;
}

// ====================    Frag    =====================
#version 330 core\n

in vec4 colorVarying;
in vec4 ShadowCoord;

out vec4 color;

uniform sampler2D  shadowMap;

void main()
{
    float visibility = 1.0;

    if ( texture(shadowMap, ShadowCoord.xy).z  <  ShadowCoord.z)
    {
        visibility = 0.5;
    }

    color.xyz = colorVarying.xyz * visibility;
    color.w = colorVarying.w;
}

私の問題は、最終パスのユニフォームを更新したコードにあると思われます。

// Re-create the exact same MVP matrix that was used for the shadow pass
glm::mat4 depthProjectionMatrix = glm::ortho<float>( -30, 30, -30, 30, -100, 100);
glm::mat4 depthViewMatrix = glm::lookAt(glm::vec3(0.5f, 2, 2), glm::vec3(0,0,0), glm::vec3(0,1,0));
depthViewMatrix = glm::translate(depthViewMatrix, -15.0f, 30.0f, 0.0f);
glm::mat4 depthMVP = depthProjectionMatrix * depthViewMatrix;// * modelMatrix;

// Multiply it be the bias matrix
glm::mat4 biasMatrix
(
    0.5, 0.0, 0.0, 0.0,
    0.0, 0.5, 0.0, 0.0,
    0.0, 0.0, 0.5, 0.0,
    0.5, 0.5, 0.5, 1.0
);

glm::mat4 depthBiasMVP = biasMatrix * depthMVP;

// Create Camera's MVP
VCCamera* currentCamera = VCSceneGraph::Instance->CurrentRenderingCamera;
glm::mat4 ProjectionMatrix = currentCamera->ProjectionMatrix;
glm::mat4 ViewMatrix = currentCamera->ViewMatrix;
glm::mat4 MVP = ProjectionMatrix * ViewMatrix;// * modelMatrix;

// Update uniforms
glUniformMatrix4fv(m_unifMVP, 1, GL_FALSE, &MVP[0][0]);
glUniformMatrix4fv(m_unifDepthMVP, 1, GL_FALSE, &depthBiasMVP[0][0]);

編集:

シャドウ テクスチャをウィンドウと同じ解像度にすることで問題を解決しました。ただし、これで問題が解決する理由を説明することはできません。他の誰かがそれにひびを入れたいなら、私はあなたの答えを受け入れます。予想される出力は次のとおりです。 ここに画像の説明を入力

完全なソースはGitHubで入手できることにも注意してください。

4

1 に答える 1

1

あなたと私の影を比較して、sampler2DShadow代わりに を使うことをお勧めしますsampler2D。このサンプラーは影専用で、影の投影用の関数がいくつかあります (shadow2DProj など)。こんな感じで使えます。

in vec4 colorVarying;
varying vec4 ShadowCoord;

out vec4 color;

uniform sampler2DShadow shadowMap;

float offset_lookup(sampler2DShadow map, vec4 loc, vec2 offset) {
    //Texture size (1024 x 1024)
    vec2 texmapscale = vec2(1.0/1024.0, 1.0/1024.0);
    //Set bias as you need (it corrects shadow acne)
    float bias = 0.001;
    vec4 result = shadow2DProj(map, vec4(loc.xy + offset * texmapscale * loc.w, loc.z, loc.w));
    if (loc.z > result.z + bias) {
        return 0.5;
    } else {
        return 1.0;
    }
}

void main() {
    float shadowFactor;
    shadowFactor = offset_lookup(shadowMap, ShadowCoord, vec2(0, 0));
    color = colorVarying * shadowFactor;
}

最後のパラメーター オフセットとは何ですか? 影をぼかすことができます。3x3 シャドウ ブラー:

//3x3 blur
    for (y = -1.5; y <= 1.5; y += 1.0)
        for (x = -1.5; x <= 1.5; x += 1.0)
            sum += offset_lookup(shadowMap, ShadowCoord, vec2(x, y));
    //I am no sure why 16 (insted of 9) but I use this and it works :D
    float shadeFactor = sum / 16.0;

試してみてください。たぶん、結果はまさにあなたが期待するものになるでしょう。

PS: 私の英語で申し訳ありません。

于 2013-10-20T11:24:45.763 に答える