2018-11月份寫的陰影技術(shù)總結(jié)
背景
陰影在游戲的表現(xiàn)上的重要性無需多言轰豆,本文主要介紹及實現(xiàn)一些常用的陰影繪制技巧狐蜕。
原理
平面陰影
平面陰影(Planar Shadow)原理為將模型上所有頂點投射到投影面上(如地面),由于只需計算將模型頂點投影到投影面上的投影矩陣,無需另外的rt消耗,所以很多手游使用此方法來繪制陰影,如王者的角色陰影:
陰影貼圖投射
平面陰影雖然實現(xiàn)簡單虫蝶,但有一個表現(xiàn)上的問題,就是無法在曲面上顯示陰影倦西,如王者的人物在凸起的石頭上沒有陰影能真。
一種修復(fù)這種缺陷的最簡單的辦法就是將人物的陰影渲染出一張貼圖,然后將這張貼圖“投射”到物體中扰柠,原理如下圖:
第1個pass是先在光源空間(light space)渲染出一張陰影貼圖粉铐,第2個pass是在主視角空間渲染時,將要渲染的像素世界坐標(biāo)轉(zhuǎn)成光源空間下的裁剪坐標(biāo)卤档,然后通過該坐標(biāo)的xy讀取陰影貼圖蝙泼,所得的值即陰影顏色,將陰影顏色與原來的接收陰影的物體(Receiver)顏色疊加即可劝枣。
在游戲中也有很多應(yīng)用汤踏,比如某手游的云陰影的渲染就是將用這種方法將貼圖“投射”到地面上和其他物體上。
Shadow Map
Shadow Map是在光源空間下利用深度緩沖得出一張深度貼圖舔腾,如下圖(左)溪胶,在渲染某個像素時,先獲取該像素在光源空間下的深度值稳诚,這個像素的深度值如果比對應(yīng)在深度圖的深度值大哗脖,就說明該像素在陰影內(nèi),如下圖(右)扳还。
受限于貼圖的精度才避,有時候多個片元可能從深度貼圖的同一個值中去采樣,這個時候需要增加陰影偏移(shadow bias)來處理
具體ps()的shader偽代碼如下:
PCF
PCF(Percentage-Closer Filtering)是一種基于Shadow Map的陰影繪制方法普办,它是為了解決Shadow Map繪制陰影時在邊緣有軟化的效果工扎,同時也起到一種抗鋸齒的效果。
PCF的原理也比較簡單衔蹲,就是不直接讀深度圖的深度值,而是將統(tǒng)計該像素周圍的NN的深度值并取其均值作為最終的深度值呈础。如下圖為77的情況舆驶。
PCF相對于普通Shadow Map,主要開銷在于采樣(Sample)的次數(shù)而钞。在《Gpu Gems 1-Chapter 11. Shadow Map Antialiasing》介紹了一種用在16個像素中挑4個像素采樣這種部分采樣的方式沙廉,來替代4*4的方式。仿照書中的代碼實現(xiàn)的效果如下:
可以看到臼节,雖然采樣數(shù)一樣撬陵,但PCF 4 Sample效果也未必優(yōu)于PCF 22Sample珊皿,而44方式也相較于其他陰影效果更加柔和,所以要用多少個采樣數(shù)要具體情況具體分析巨税。
VSM
由于PCF的采樣開銷是一個費時又費力的過程蟋定,而通過VSM(Variance Shadow Maps)可以大大減少采樣次數(shù)所帶來的消耗。
VSM背后有一個概率學(xué)原理:切比雪夫不等式
PSSM
PSSM(Parallel-Split Shadow Maps)是在Shadow Map的基礎(chǔ)上驶兜,將攝像機(jī)視錐體切分開n子視錐體,這樣就得到n個深度圖远寸,并且通過用物體包圍盒的方式將計算出一個CropMatrix抄淑,然后通過lightViewMatrix * lightProjMatrix * cropMatrix的方式將渲染像素轉(zhuǎn)到光源空間,這個目的是為了增加精度驰后,在計算陰影的時候通過這n個深度圖分別計算陰影肆资。如圖是n=3的情況。
增加多個深度圖的好處增大了采樣的精度灶芝,由于多個深度圖是相互獨立郑原,所以可以配合GPU進(jìn)行并行采樣。
原因如下圖所示监署,對于ds*ds的像素颤专,即陰影圖的最小分辨率,所對應(yīng)的視平面區(qū)域dp包含多個像素點钠乏,那么這些像素點就都會取相同的值栖秕,這樣就產(chǎn)生了鋸齒狀的陰影邊界,對于走樣的度量可以定義為dp/ds:
而PSSM的子視錐體要怎么分割晓避,《GPU Gems 3》推薦的做法是用均分+對數(shù)的方式來分割簇捍,具體原因為一系列數(shù)學(xué)推導(dǎo),大致思路就是使[圖片上傳失敗...(image-e4244f-1572685793501)] 盡可能的小俏拱。
在Unity中的Cascade Shadow就是通過PSSM來實現(xiàn)暑塑,默認(rèn)視錐體分割大小為4。
PCSS
上述介紹的PCF和VSM雖然能使陰影邊緣有模糊的效果锅必,但因為它們都是通過類似濾波的方式來處理陰影邊緣事格,都不是真正意義上的軟陰影。真正的軟陰影應(yīng)考慮光源區(qū)域和以及如何渲染半影(Penumbra)搞隐。
PCSS(Percentage-Closer Soft Shadows)是一種基于Shadow Map以及光源區(qū)域的思想來實現(xiàn)繪制軟陰影的算法驹愚。繪制過程共需要2個pass,在第1個pass得到Shadow Map劣纲,第2個pass獲得一個區(qū)域大小并通過PCF獲得陰影值逢捺,后者主要步驟分為三步:
下圖為通過PCSS實現(xiàn)的陰影效果,在邊緣處理上比PCF癞季、VSM的方式更加柔和劫瞳。
技術(shù)缺陷
關(guān)于技術(shù)缺陷倘潜,其實在上面的介紹有提及一些,
下面主要羅列一些其他沒提及的問題:
1.VSM的光滲現(xiàn)象(light bleeding)
此現(xiàn)象主要源于式(2.2)中[圖片上傳失敗...(image-308da0-1572685793501)] 永遠(yuǎn)非負(fù)志于,導(dǎo)致式右端永遠(yuǎn)不可能為0涮因,表現(xiàn)上就是在一些被完全遮擋的物體中有可能會有光滲出的情況。
2.近平面鋸齒問題
大部分基于光源空間的陰影繪制在近平面都可能有陰影鋸齒嚴(yán)重的情況恨憎,原因是dp/ds與z成反比蕊退,[圖片上傳失敗...(image-293aca-1572685793501)] 越小,就代表鋸齒越嚴(yán)重憔恳。
3.PCSS的Zavg不準(zhǔn)確問題
性能
手游對于陰影的表現(xiàn)優(yōu)先級一般不是很高瓤荔,大部分只要做到有就行,比如最簡單的點陰影钥组。而實時陰影输硝,大部分都是通過平面陰影和曲面陰影投射的方式得出,而對于一些手游上的建筑程梦,很多都是靜態(tài)陰影+AO的方式繪制点把。
雖然深度檢測在移動端也是個很費時的過程,但一些RPG游戲中為在曲面上有好的陰影效果也會結(jié)合深度圖做一些陰影的繪制屿附,如楚留香在人物陰影的繪制有用到Shadow Map及一些軟陰影的繪制抹竹。
而對于上述介紹的算法柱彻,除了平面陰影,其他都需要額外的一張貼圖。而PCF的采樣由于消耗比較大宛琅,《Real Time Shadow》介紹了一種用對數(shù)在(0,1)區(qū)間內(nèi)模擬生成過度自然的陰影值的方法办龄,即用Log2(shade)來代替shade 醇王。
而對于PSSM猎贴,由于視錐體的分割,會生成n張貼圖各聘,rt的來回切換和SetTex在移動端吃不消揣非,一種省內(nèi)存的做法是將n張貼圖合在一張中。
在很久之前崩壞3中關(guān)于角色渲染的分享躲因,也提及到上述講述的PSSM,VSM,PCSS:)
參考
1.《GPU Gem》
2.《Real-Time Shadow》