目錄
- Shadow Mapping
- shadowMapping的問題
- shadow mapping背后的數學
- PCF(Percentage Closer Filtering)
- PCSS(Percentage closer soft shadows)
- VSSM(Variance Soft Shadow Mapping)
- 優化步驟3
- 優化步驟1
- SAT(Summed Area Tables)
- VSSM的問題
- Moment Shadow Mapping
- Distance Field Soft Shadows
GitHub主頁:https://github.com/sdpyy1
作業實現:https://github.com/sdpyy1/CppLearn/tree/main/games202
Shadow Mapping
這塊東西在我OpenGL學習筆記中有詳細介紹
https://blog.csdn.net/lzh804121985/article/details/147256140?spm=1001.2014.3001.5502
shadowMapping的問題
陰影痤瘡(Shadow Acne)、或者叫自陰影
出現該問題的原因可以看下圖,光源視角下的一個像素內高度認為是同一個,下一個像素的位置,會被認為比前一個Z值更遠,所以平坦的地板會交替出現高低不平的地方,這樣就會出現陰影
簡單解決就是認為z插值在一個范圍內就不算在陰影中,雖然能解決這個問題,但是引入了新的問題,陰影發生了偏移。如果bias設置的過大,在靠近腳的地方,就不會出現陰影。在工業界稱為“彼得潘效應"(Peter Panning)
對于這種不接觸的陰影,解決方法是shadowmapping中不僅存最小深度的表面,還存儲第二小深度的表面
另外陰影還有走樣問題,畢竟陰影計算就是一個像素一個像素來做的
shadow mapping背后的數學
在實時渲染中,經常會用到一些不等式,但人們更多關注的是不等式相等時成立的條件,也就是說,不等式在什么條件下近似相等。實時渲染中,經常用到的一個約等如下:
滿足下列兩個條件之一時,實時渲染領域認為他們近似相等:
當g(x)滿足:
- g(x)積分域足夠小
- g(x)足夠smooth,g(x)值變化不大,比較平坦
下面來到渲染方程
根據上邊的不等式,就可以把最后一項(V)提出來
這樣變換后,渲染方程就變成了正常做shading之后,再乘以一個表示可見不可見的項
這時的G(x)就是渲染方程的被積函數
PCF(Percentage Closer Filtering)
以點P為例,并不只找shadowmap中對應的一個像素,而是找一圈的像素,與這些像素都進行比較,最后將比較結果進行平均
比較結果就是一個全是1,0的矩陣,最終得到的數就不是非0即1的數了
PCSS(Percentage closer soft shadows)
PCF它原本是用來解決陰影的走樣問題的,后來人們又發現它可以用來生成軟陰影,就是PCSS
首先來回顧一下軟陰影和硬陰影
到這里就可以理解軟陰影在陰影不同位置有不同的軟硬程度就可以通過PCF的濾波核的大小來控制,越大越模糊,越小越硬
w(半影)與光源大小、物體位置之間呈現相似三角形的關系,w就可以用來表示軟硬程度。半影舉例越大,濾波核尺寸就應該設計的更大,讓陰影更軟
總結PCSS的算法流程:1. 在一個范圍搜索遮擋物,并計算平均深度。2. 用平均深度求出半影距離3. 在對應的濾波核尺寸下進行PCF
上邊的步驟1需要選取一個合適的范圍,下圖就展示了如何選取一個范圍來進行遮擋物搜素,假設了ShadowMap在近平面,用光源的大小來決定搜素范圍
在PCSS第一步和第三步中,為了計算一個像素點的著色,需要考慮多個紋素,從而導致速度慢。如果采用稀疏采樣,又會有噪點產生
VSSM(Variance Soft Shadow Mapping)
針對PCSS效率問題,提出VSSM
優化步驟3
PCF和PCSS的 PC(percentage closer)的理解就是在深度紋理的一片區域內,有多少比例的紋素比著色點深度小
這就相當于看多少人比我考試分數高,就需要遍歷所有同學的成績
VSSM的解決方案就是用成績分布(正態分布)來估計(??VSSM并沒有用正態分布,這里這樣說只是方便理解,后邊提到切比雪夫不等式就好理解了)
定義一個正態分布需要均值和方差,這個可以快速計算
均值可以通過mipmap(因為上一級map到下一級map就是把相鄰的正方形進行平均,到最后就整合為了一個平均值)、SAT(是一種用于高效計算矩形區域內元素總和的數據結構)來求,方差則是用一個概率論公式來求
得到正態分布分布后,求小于著色點深度的紋素百分比,其實就是陰影部分的線下面積
下來VASS還對這種計算進行了簡化。直接使用不等式來近似
只要給定均值、方差、和要比較的位置t,就有下面的不等式成立 ,在渲染中就直接用方差、期望、t來估計紅色部分的面積,然后馬上就能得出剩余部分的面積(t必須大于中間線才好使)
至此,對PCSS步驟三的優化結束,在生成shadowMap時,為了計算方差,還需要額外生成一張平方shadowMap,總體來說甚至都不需要進行loop就可以知道一片區域有多少紋素深度小于著色點深度
優化步驟1
為了設置合理大小的過濾核,對一個區域內遮擋物的深度進行平均,需要遍歷紋素,效率并不高
例如下圖,如果著色點的深度為7,那么這些紋素的深度只有藍色的是遮擋物,就需要平均他們,而紅色不參與計算
對藍色部分和紅色部分求均值后,滿足下式
這里求N1/N就可以直接用剛才步驟三的不等式(用方差、均值、t來估計大于t的比例),之后1減去它就是N2/N。
但我們還不知道紅色部分的均值,在VSSM中直接假設紅色部分均值就是t(大膽的假設,假設的依據是陰影位置大概率是個平面)
VSSM的效果
另外課程還提到目前PCSS是壓過VSSM的,因為人們對噪聲的容忍度越來越高,在圖像層面進行降噪手段變強了
SAT(Summed Area Tables)
SAT是給一片區域立刻得到它的均值的一種數據結構
SAT是對原數據的預處理得到的數據,在一維場景下,每個index記錄都是前綴和(提前記錄好),現在要求中間某一段的和,就直接拿出SAT在范圍查詢邊界(左邊是邊界-1)的數據相減就行了
在二維情況下藍色的范圍查詢,可以轉化為左上角都是(0,0)的框加減操作
VSSM的問題
VSSM中作了很多假設,有一個就是假設一片區域紋素是符合正態分布的
例如右圖深度只有3個峰值,不符合正態分布
下圖就是說本來只有一小部分沒遮住,但是假設為正態分布變成了很大一部分,就會讓陰影邊白
有一些地方變白了
Moment Shadow Mapping
為了解決VSSM分布描述不準確的問題,提出MSM,使用更高階矩來描述分布
大概意思就是用數據的高階來更好的擬合PCF的效果,下圖表明用4階矩下的分布就很好的達到了PCF的效果
缺點很明顯空間很大
Distance Field Soft Shadows
首先看一下Distance functions是什么,它描述了空間中任意一點到物體表面的最小距離,離得越遠值越小,表示到圖上就是變白
在任何一個點上,以它記錄的值為半徑畫圓,都不可能碰到物體,如果做光線追蹤,那可以直接移動到圓的表面上去,這就是SFD的一個應用
下來用它來生成軟陰影是它的另外一個陰影
用SDF可以大概描述多大的范圍被物體擋住了,圓圈內為安全距離,不會有物體擋住,用這個圈的大小來定義visbility的大小,從而實現軟陰影
在不同的位置找圓做切線,最小的切線就是需要的安全距離
求角度是一個acrsin的計算,比較慢,人們用一個替代來簡化
其中根據不同的k值來達到不同的效果
顯而易見的優缺點 空間換時間,但這是不考慮生成距離場的時間