1. 程式人生 > >陰影演算法

陰影演算法

陰影演算法,在3D渲染中是很重要的一部分。陰影演算法大致可以分為以下三類:基於ray tracing,基於shadow volume,基於shadow map(Z buffer).

    Ray tracing可以很自然地實現shadow,不需要特殊處理,但是ray tracing一般都用於離線渲染。Shadow Volume在實時渲染中也有應用,但是Shadow Volume依賴於geometry,而且Volume的生成是比較麻煩的事情。因此在實時渲染中,還是簡單的Shadow map運用得最多,基於Shadow Map的論文也是層出不窮。

Shadow Map分為兩個pass:

(1) 以燈光的位置作為視點,渲染整個場景,把深度值(Z值)寫到一張texture(shadow map)中。

(2)以相機所在的位置作為視點,渲染整個場景,在PS中把每個象素P(x,y,z)轉換到燈光所在的視空間中對應P`(x`,y`,z`),用(x`,y`)作為uv去取樣shadow map中此點的z值Zmap,在與z`比較,如果z` > Zmap,此畫素便在陰影中,如果z` < Zmap此畫素便不在陰影中。

Shadow Map優點是簡單,易於實現。但是Shadow map有alias(走樣、鋸齒)的問題。為了解決這個問題,很多人提出了很多改進的辦法。

1、Percentage-Closer Filtering:

Percentage-Closer Filtering出自論文“Rendering Antialiased Shadows with Depth Maps”,NV的Sample 裡面也有,該文采用”Percentage-closer filtering”的濾波方法來解決Shaodow map的走樣問題。

其思想很簡單,拿文章裡的一個圖為例,假如某畫素轉換到燈光檢視空間中的Z值為49.8,把這個值與在Shadow Map中3X3的區域的Z值比較,如果49.8小於在Shadow map中對應的Z值,則記為0,表示不在陰影中,反之則記為1。這樣得到了右邊所示的3X3區域大小的9個值,在對這9個值取平均,得到0.55,以這個值作為在pixel shader中的陰影權值。此方法能夠在一定程度上解決alias的問題,而且有軟陰影效果。

2、Perspective Shadow Maps

  Perspective Shadow Maps來自論文:“Perspective Shadow Maps,SIGGRAPH 2002 by Stamminger and Drettakis”。

該論文把Shadow map的alias問題分為兩類:Perspective alias和Project alias. Project alias是因為當燈光照射方向與物體表面夾角比較小時,使得多個pixel對應Shadow map中一個texel,產生alias問題,可以增大shadow map來解決此問題。Perspective alias產生的原因是因為透視透影會產生近大遠小的效果,這使得近處的物體有可能多個pixel對應著Shadow map中一個texel, 產生alias問題。Perspective
Shadow map就是用於解決這一問題。

Perspective Shadow Maps其實思想還是比較容易理解的。在生成shadow map時,首先將物體以及燈光變換到perspective space中,在perspective space中,整個空間是一個長方體,沒有了近大遠小的問題,在這個空間中,再以常規方法,以燈光作為視點,生成shadow map.

Perspective Shadow Maps有很多侷限性,對光源的位置和型別都有要求,很多情況需要特殊處理,源文中列了一些需要特殊處理的情況。正因為這些限制,使得實現起來比較複雜。但是此論文開了解決Perspective alias的先河,有不少後續文章都是借鑑了此文思想。

3  Light Space Perspective Shadow Maps

該文出自論文:“Light Space Perspective Shadow Maps”,這篇論文是以Perspective Shadow Maps為基礎的,是對其的改進。

“Light Space Perspective Shadow Maps”與Perspective Shadow maps的區別是,它在產生shadow map之前,不是先以Camera的View Frustrum作透視投影,而是在和燈光方向垂直的方向構建View Frustrum,以此View Frustrum把燈光和場景轉換到Perspective space中,再計算Shadow map.這樣的好處在於,平行光源轉換後依然是平行光,點光源被轉換成了平行光源,克服了Perspective Shadow Maps中的一些問題。

4  Parallel-Split Shadow Maps for Large-scale Virtual Environments

    該方法出自論文:” Parallel-Split Shadow Maps for Large-scale Virtual Environments”,

附件: PSSM.jpg

  如上圖示,Parallel-Split Shadow Maps把View Frustrum按照Z的範圍分成三個部份,再分別為這三個部分各自生成Shaodw Map。假如光源不是平行光,可先用Light space Shadow Map的方法轉換到Light Space,此時光源便是平行光了。Parallex-Split Shadow Maps是關鍵在於如何對View Frustrum作合理的切分。

5  Variance Shadow Maps.

Variance Shadow Maps,來自William Donnelly和Andrew Lauritzen的“Variance Shadow Maps”。該方法利用概率論中的期望值、方差和切比雪夫不等式,實在是巧妙。

在前面的Percentage closer filter方法中,我們不能用紋理過濾方法(如高期濾波等)對Shadow Map進行預處理,因為預處理之後結果就會變得不正確,不能反映畫素是否在陰影之中,因此只能取樣一定範圍取差值求平均。而Variance Shadow Maps就沒有這個限制。它的方法其實很簡單,分為如下幾步:

(1)              像生成一般shadow map一樣渲染,但是除了把每個畫素的深度值d,以及深度的平主 d2記錄下來。

(2)              利用一種慮波方法對Shadow map進行處理。

(3)              從相機處渲染場景,在PS中把每個象素P(x,y,z)轉換到燈光所在的視空間中對應P`(x`,y`,z`),用(x`,y`)作為uv去取樣shadow map中此點的z值和z2記為D和F,取樣時可以採用硬體支援的Blinear或Trilinear和AF去採,此時:

期望值E(z) = D,E(z2)=F

那麼方差就等於: variance = E(z2) - E(z)2 = F – D2

再根據切比雪夫不等式,計算出陰影引數即可,具體的公式可查閱論文或Nvida對應的Sample。(