實時陰影渲染(一):PSSM平行分割陰影圖


PSSM(Parallel Split Shadow Map)平行分割陰影圖,是一種根據距離遠近采用多個深度紋理渲染陰影的方法

適合用於室外大場景中的平行光比如太陽形成的陰影

本系列需要讀者了解基本的深度陰影渲染方面的知識

 

1 視錐划分

如下圖,以采用三個划分為例:

這里將視錐體平行划分為3個區域,代號分別為1、2、3

這三個區域在渲染陰影的時候分別采用不同的陰影圖sm1、 sm2、sm3

這樣將1、2、3對應的距離數據打包為一個float3變量splits.xyz,傳入片段shader,然后通過以下的代碼實現陰影圖的選擇:

if (z <= splits.x)
{
    shadow = depthShadow(sm1,...);
}
else if (z <= splits.y)
{
    shadow = depthShadow(sm2,...);
}
else if (z <= splits.z)
{
    shadow = depthShadow(sm3,...);
}

這里z 、depthShadow函數和單個深度紋理陰影的實現類似,區別是相關參數都變成了三份

 

圖上的三個划分並沒有包含全部的渲染區域,因為沒有必要渲染特別遠的陰影

各個陰影區域的大小可以根據需要選擇合理的算法

根據實際情況也可以將陰影區域划分為兩個或者更多個

為了平滑 ,最后一級陰影(本例的3)可根據z值做線性淡入淡出

 

2 投影矩陣計算

渲染陰影前需要分別渲染三個深度紋理

對每一個陰影區域都需要計算對應的正投影矩陣

計算正投影矩陣可以理解為計算正投影相機的位置、投影大小和相機的up矢量

下面以單個投影區域為例說明如何計算這三個要素

 如上圖,彩色陰影部分為視錐體的單個划分區域

根據當前相機的位置、FOV、縱橫比和遠近截面距離可以算出該視錐體的八個頂點(這里為了簡化僅畫出四個)

根據光照方向可以用任一垂直矢量作為投影相機up矢量,不過不同的up矢量得到的投影體大小不同,你可以設計專門的算法計算最優的up矢量

然后再通過光照方向和up矢量的叉積計算出right矢量

任選一參照點(此例為左下的O點),通過up\right矢量和光照方向可以計算出其它7個點在投影相機空間相對於O點的最大、最小值也就是最小包圍盒

如圖所示,相機的位置應在AB的中點D所在的中心線上,其相對於D點的距離為AC的長度加上陰影可能的投影距離(視錐體外的物體投影)

投影體的長為AB的長度,寬為right方向得到的長度(此圖沒畫出來)

 

也可以將視錐體的八個頂點直接轉到相機空間計算軸對稱包圍盒、相機位置,然后再將相機位置變換回世界空間

不過當場景很大時,正反兩次變換造成的誤差會非常的大,直接在世界坐標系內計算則不會有這種問題


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM