2013-10-22 103 views
1

我想在opengl中實現陰影映射。它正在工作,但是鋸齒是可見的,所以我決定在shadow2D中使用sampler2Dshadow,因爲我已經讀過它作爲簡單的抗鋸齒解決方案。但是一旦我使用它,就會在整個場景中產生非常顯着的陰影痤瘡。請注意,使用sample2D與texture2D時,沒有。 這是打算?如果是這樣,我該如何解決它?Opengl使用shadow2D時的陰影痤瘡

這是在使用sampler2DShadow它的外觀: 1

這是處理陰影片段着色器的一部分:

float theta = clamp(dot(normalize(lightVector), normalize(vertNormal)), 0, 1); 
    float bias = 0.005*tan(acos(theta)); 
    float visibility = 1.0; 
    if (shadow2D(shadowTex, shadowCoord).z < shadowCoord.z - bias){ 
     visibility = 0.5; 
    } 
    color = vec4(color.xyz * visibility, 1); 
+0

你的問題令人困惑,你談論很多事情,而標題很好,只是離開了。請寫一些更多的信息,顯示一些代碼,代碼中有什麼問題等等? – Vallentin

+1

試圖增加你的偏差值 – Benlitz

+0

我試過了,當偏差值爲1時停止:/ – user1760770

回答

8

爲什麼你的偏見基於光與面之間的夾角?這就是造成這些奇怪的莫爾條紋的原因。通常情況下,如果你想在角度上對深度進行偏置(將它想象爲陰影貼圖的各向異性偏置),則在創建陰影貼圖時使用glPolygonOffset (...),在着色器中使用恆定偏移或偏差隨着距離(但不是角度)。

但是,多邊形偏移的問題在於,它將在啓用時禁用分層Z緩衝(因此陰影貼圖構建填充率理論上會下降)。發生偏移原始組件。這不是一個完美的解決方案,但絕對比你現在擁有的更好。

通過稍微偏置W座標,您可能能夠在陰影貼圖頂點着色器中實現基於斜率的偏置,這將允許使用原始組裝階段的結果提前Z拒絕...但它很難找到一個很好的價值,以用於W.


...所以我決定用sampler2Dshadow與shadow2D,因爲我讀過它作爲簡單的抗鋸齒解決方案。

至於sampler2Dsampler2DShadow之間的差,(在舊版本GLSL的shadow2D (...))一個sampler2DShadow具有啓用將產生一個二進制結果質地比較在呼叫用於texture (...)時 - 1.0如果它通過測試功能,0.0如果它失敗。考慮到你的片段着色器已經執行了比較,並且期望採樣器返回的值是深度,而不是通過/失敗結果應該使用sampler2D - 在這種情況下忽略sampler2DShadow的存在。

                                                                            enter image description here

我不知道你用的是什麼版本的GLSL的,因爲你使用的shadow2D (...),這早已被棄用。但是,如果您看一下GLSL specification for version 440,頁碼。 153(8.9-紋理函數)它會將您引用到上面包含的表格中。

對於陰影形式(採樣參數是陰影型),如在章節8.22中的OpenGL圖形系統規範的「紋理比較模式」中描述的在結合至採樣器的深度紋理深度比較查找完成。請參閱下表,瞭解哪些組件指定D 參考號。綁定到採樣器的紋理必須是深度紋理,否則結果未定義。如果對採樣器進行了非陰影紋理調用,該採樣器表示深度比較處於打開狀態的深度紋理,則結果未定義。如果對採樣器進行陰影紋理調用,該採樣器表示深度比較關閉的深度紋理,則結果未定義。如果對不表示深度紋理的採樣器進行陰影紋理調用,則結果未定義。

有效sampler2DShadow將減少混疊,但這僅僅是因爲它正好產生兩個結果:1.00.0和這些結果的平均值比所述平均深度更有意義的(如我將在下面解釋)。所以這個陳述有一些事實,但是你認爲它是在我認爲不合情理的情況下被採納的。

實際上,如果你想減少陰影混疊,你應該做的是取N多深度測試的平均值。使用線性濾波通常是減少傳統紋理中的混疊的有效方法,但對於深度紋理,存儲在紋理中的值實際上是,假設將用於比較目的。如果您要使用線性過濾和,GPU會收集陰影貼圖中最近的4個深度,對它們進行平均,然後對平均深度執行一次合格/不合格測試。這實際上沒有任何用處,因爲你的片段仍然通過或失敗。

你想要做的是收集4個最近的深度,單獨測試它們,然後平均通過/失敗結果。然後,而不是每個片段通過或失敗,你可能天真地有0%,25%,50%,75%或100%的障礙 - 實際上,平均值可以通過每個樣本距樣本座標的距離加權。這被稱爲百分比更接近濾波(PCF),shadow2D (...)sampler2DShadow實際上,如果您對某些驅動程序啓用線性濾波,則可以實現此功能。他們不是取樣取樣深度的平均值,而是測試取樣深度,然後對所有測試的結果進行平均。

實際上是其中sampler2DShadow抗鋸齒性能從何而來,但你必須要採用正確的GLSL着色器來利用它。你可以很容易地(更便攜)樣品4點自己使用了NEAREST濾波器sampler2D並執行測試和平均自己......


另外,儘量不要看z深度紋理的組成部分。幸運的是,對於GLSL> = 130的版本,採樣深度紋理產生結果:vec4 (r, r, r, 1.0),但在舊版本的GLSL中,行爲取決於稱爲深度紋理模式的東西。 z同樣可能是0.0,或者完全未定義的pre-GL3。您應該閱讀rx,因爲深度紋理本質上是單組分的。上表甚至表明 - 計算結果存儲在r中,而不是b