2016-08-15 232 views
4

所以我一直試圖圍繞過去一週的OpenGL中的陰影貼圖進行環繞,而且它並沒有那麼棒。所以我希望有人能幫助我。 我一直在學習從LearnOpenGL的陰影映射教程中使用前向渲染和從我收集的陰影映射,它似乎像陰影映射與延遲有點不同。 對於初學者來說,這裏是我的陰影貼圖:使用延遲渲染(OpenGL)進行陰影貼圖

Shadow map picture

它是紅色的出於某種原因,但顯然的是,根據一個朋友是可以的。但我仍然覺得我已經在做錯了什麼。但是假設它不是,陰影貼圖被正確渲染並且到達延遲渲染的光照通道而沒有任何問題。我還發送了一個緩衝區,其中包含我使用輕空間轉換矩陣轉換的光空間中的所有碎片。

//Create LSMatrix 
    GLfloat near_plane = 1.0f; 
    GLfloat far_plane = 10.0f; 
    glm::mat4 lightProjMat = glm::ortho(-10.0f, 10.0f, -10.0f, 10.0f, near_plane, far_plane); 
    glm::mat4 lightPerspective = glm::lookAt(glm::vec3(-2.0f, 6.0f, -1.0f), 
               glm::vec3(0.0f, 0.0f, 0.0f), 
               glm::vec3(0.0f, 1.0f, 0.0f)); 

    shadowBuf.lightSpaceMat = lightProjMat * lightPerspective; 

我現在沒有定向燈,只有兩個點燈。所以使用正投影和所有這些都會給我一個不正確的影子。但是,儘管如此,仍然存在影子現在影子從何而來並不重要,我只是想學習。那麼我可以擔心如何讓它與光源相匹配。

這裏它正用在幾何通道的GLSL頂點着色器中。 (LSMat)

void main() 
{ 
    gl_Position = vec4(position, 1.0f); 
    vs_out.uv = uv; 
    vs_out.normal = normal; 
    vs_out.FragPos = vec3(model * vec4(position, 1.0f)); 
    vs_out.FragPosLS = LSMat * vec4(vs_out.FragPos, 1.0f); //Fragment position in light space 
} 

然後在片段着色器中將其保存到紋理併發送到光照通道。

因此,現在我擁有了我需要在我的照明通道中進行陰影計算的所有內容。 (希望至少)

這裏是在光我的片段着色器的所述部分通過在那裏我做陰影計算:

float shadowCalc() 
{ 
    vec4 fragPosLS = texture(gFragPosLS, uvs); //Fetch the lightspace frag pos from the texture 

    vec3 projCoords = fragPosLS.xyz/fragPosLS.w; //Manually do perspective divison 
    projCoords = projCoords * 0.5 + 0.5; //Get the pos in [0,1] range 

    float closestDepth = texture(shadowMap, projCoords.xy).r; 
    float currentDepth = projCoords.z; 

    float shadow = currentDepth > closestDepth ? 1.0 : 0.0; 

    return shadow; 
} 

最後,我在我的漫反射和鏡面值使用此陰影值:

float shadowValue = shadowCalc(); 
    diffuse = diffuse * (1.0 - shadowValue); 
    specular = specular * (1.0 - shadowValue); 

    return ((diffuse * vec4(gColor, 1.0f)) + specular + ambient); 

然後我輸出像往常一樣,並將結果所得到的顏色是這樣的:

Picture of the result

糟糕的紋理只是我現在沒有在Maya中煩惱紫外線地圖的結果。但除此之外,你可以清楚地看到它是各種各樣的混亂。我甚至嘗試禁用其中一個燈,以確保它不會破壞,因爲我有兩個燈做shadowCalc函數,但事實並非如此。但我不是100%確定的。

如果任何人有任何想法,爲什麼發生這種情況,那麼我都耳熟能詳。這讓我困惑了一個星期,似乎無法弄清楚爲什麼會發生這種情況。我只知道,當我使用陰影偏差時,地面上的條紋會消失,但金字塔後面的巨大陰影仍然存在。它不僅看起來不好,它還指向完全錯誤的方向,如果將它與陰影貼圖的渲染角度進行比較,那麼它必須與座標有關。我讀了一些關於延遲渲染如何要求你做某些事情的不同方法,但我還沒有設法得到正確的答案。

這已經是相當龐大的帖子,但如果我忘記顯示任何可能會清理的東西,那麼請告訴。

+1

[* Grimm * Shado](https://www.penny-arcade.com/comic/2009/01/19/further-songs-of-sorcelation-part-two)wmapping [?](http://stackoverflow.com/revisions/38961661/2) – genpfault

+1

沒有關於你的位置紋理(你應該考慮在未來通過使用重建進行優化)的編碼進行編碼。您已將用於對深度紋理進行採樣的紋理座標縮放到[0.0,1.0],但我不知道您的位置緩衝區。除非它是浮點數,否則你的位置既不正常也不能保證爲正數,這可能是一個非常大的問題。 –

+1

您只讀取深度圖中的紅色值,您確定在深度通道中正確地將值寫入紅色組件?並且您正在從z組件讀取currentDepth,是否可以發佈這些代碼以便我們可以檢查代碼的其餘部分。否則,對我來說似乎很好 – codetiger

回答

0

只是在黑暗中刺傷:我遇到了陰影貼圖和延遲渲染相結合的問題,它與您在屏幕截圖中顯示的內容非常相似。在我的情況下,我錯誤地從深度紋理中讀取Z值。在深度紋理中的值與

gl.texImage2D(gl.TEXTURE_2D, 0, gl.DEPTH_COMPONENT16, 2048, 2048, 0, gl.DEPTH_COMPONENT, gl.UNSIGNED_SHORT, null);

創建標準化到(-1;+1)所以我不得不修改它們早在

texture(shadowMap, projCoords.xy).r - .5) * 2.

能見度計算正在爲:

float bias = .01; 
float visibility = (texture(shadowMap, projCoords.xy).r - .5) * 2. < projCoords.z - bias ? 0.1: 1.0;