2017-03-08 96 views
-1

我試圖在延遲渲染管道中實現陰影貼圖,但是我遇到了幾個實際產生陰影貼圖的問題,然後對像素進行了陰影處理 - 我認爲這些像素應該只是陰影不是。陰影貼圖產生不正確的結果

我有一個單向燈,這是我的引擎中的'太陽'。我已經推遲渲染設置照明,到目前爲止正常工作。我再次渲染場景成深度僅FBO爲陰影圖,使用以下代碼來生成視圖矩陣:

glm::vec3 position = r->getCamera()->getCameraPosition(); // position of level camera 
glm::vec3 lightDir = this->sun->getDirection(); // sun direction vector 
glm::mat4 depthProjectionMatrix = glm::ortho<float>(-10,10,-10,10,-10,20); // ortho projection 
glm::mat4 depthViewMatrix = glm::lookAt(position + (lightDir * 20.f/2.f), -lightDir, glm::vec3(0,1,0)); 

glm::mat4 lightSpaceMatrix = depthProjectionMatrix * depthViewMatrix; 

然後,在我的照明着色器,我使用下面的代碼來確定是否一個像素在陰影中:

// lightSpaceMatrix is the same as above, FragWorldPos is world position of the texekl 
vec4 FragPosLightSpace = lightSpaceMatrix * vec4(FragWorldPos, 1.0f); 

// multiply non-ambient light values by ShadowCalculation(FragPosLightSpace) 
// ... do more stuff ... 

float ShadowCalculation(vec4 fragPosLightSpace) { 
    // perform perspective divide 
    vec3 projCoords = fragPosLightSpace.xyz/fragPosLightSpace.w; 
    // vec3 projCoords = fragPosLightSpace.xyz; 

    // Transform to [0,1] range 
    projCoords = projCoords * 0.5 + 0.5; 

    // Get closest depth value from light's perspective (using [0,1] range fragPosLight as coords) 
    float closestDepth = texture(gSunShadowMap, projCoords.xy).r; 

    // Get depth of current fragment from light's perspective 
    float currentDepth = projCoords.z; 

    // Check whether current frag pos is in shadow 
    float bias = 0.005; 
    float shadow = (currentDepth - bias) > closestDepth ? 1.0 : 0.0; 

    // Ensure that Z value is no larger than 1 
    if(projCoords.z > 1.0) { 
     shadow = 0.0; 
    } 

    return shadow; 
} 

但是,這並不真正讓我知道我在做什麼。這裏的遮蔽後的輸出的屏幕截圖,以及陰影映射半assedly在Photoshop轉換爲圖像:

Render Output 渲染輸出

Shadow Map 陰影圖

由於定向光在我的着色器中唯一的光,看起來陰影貼圖被正確渲染得非常接近,因爲透視圖/方向大致匹配。然而,我不明白的是爲什麼沒有一個茶壺真的最終會對其他人產生影子。

我很感謝任何關於我可能會做錯什麼的指針。我認爲我的問題在於計算光線空間矩陣(我不知道如何正確地計算出這個問題,給出一個移動的攝像頭,這樣就可以更新視圖中的東西),或者按照我確定的方式延遲渲染器的紋理是否在陰影中。 (FWIW,我從深度緩衝區確定世界位置,但我已經證明這個計算工作正常。)

感謝您的任何幫助。

回答

1

調試陰影問題可能會非常棘手。如果你看一下你的渲染觀察,你會真正看到在左上角盆的一個影子

  1. :讓我們開始的幾個點。

  2. 嘗試旋轉你的太陽,這通常有助於查看光轉換矩陣是否存在任何問題。從你的輸出中看來,太陽是非常水平的,可能不會在這個設置上投下陰影。 (另一個角度可能會顯示更多的陰影)

  3. 看起來好像您正在計算矩陣,但嘗試縮小glm :: ortho(-10,10,-10,10,-10,20)中的最大深度)緊緊地適合你的場景。如果深度過大,則會失去精度,陰影會產生僞影。

  4. 爲了形象問題的根源所在,從進一步的到來,嘗試從這裏outputing從陰影貼圖的查找結果:

closestDepth = texture(gSunShadowMap, projCoords.xy).r 

如果陰影貼圖被正確投影,那麼你知道你在深度比較中存在問題。希望這可以幫助!

+0

謝謝 - 事實證明,當我分配我的深度紋理用於陰影貼圖時,我將錯誤的值傳遞給OpenGL,導致着色器在讀取時錯誤地解釋貼圖。奇怪,但現在起作用。 –