想要在場景中產生陰影,其中之一個方法是shadow map,另一個方法是shadow volumn,先瞭解兩者的原理、優缺點與差異,有助於我實做前者shadow map。目前知道shadow map適用於靜態場景(物體與光源相對位置不變),而shadow volumn則適用在動態場景,當然靜態場景也沒問題。實做上前者易於後者,能在現今的shader發揮潛能。
Shadow mapping 的原理:
一個物體之所以會處在陰影當中,是由於在它和光源之間存在著遮蔽物,或者說遮蔽物離光源的距離比物體要近,這就是 shadow mapping 算法的基本原理。
Pass1: 以光源為視點,或者說在光源坐標系下面對整個場景進行渲染,目的是要得到一副所有物體相對於光源的 depth map (也就是我們所說的 shadow map ) , 也就是這副圖像中每個像素的值代表著場景裡面離光源最近的 fragment 的深度值。由於這個 pass 中我們感興趣的只是像素的深度值,所以可以把所有的光照計算關掉,打開 z-test 和 z-write 的 render state 。
Pass2: 將視點恢復到原來的正常位置,渲染整個場景,對每個像素計算它和光源的距離,然後將這個值和 depth map 中相應的值比較,以確定這個像素點是否處在陰影當中。然後根據比較的結果,對 shadowed fragment 和 lighted fragment 分別進行不同的光照計算,這樣就可以得到陰影的效果了。
若場景中有一光源、一相機、一物體,分別對光源所見和相機所見繪出影像,先由前者(shadow map)紀錄影像pixel光源打到場景vertex的深度值DL,再由後者紀錄影像pixel中對應場景vertex其與光源的距離值DC,比較兩者的值,若DL<DC,則表示該場景vertex在陰影中,否則表示該場景vertex不在陰影中。
其實shadow map概念很簡單,以光源的角度來看場景,光源看不到的地方都在陰影之中。
以上圖來自OpenGL SuperBible, 4th ed,第五版已刪。




Comments on: "Shadow mapping 原理" (6)
想請問一下
depth map也是最後畫面的一種,只是每個像素的值不是顏色值而是深度值嗎?
camera和light角度所渲染出的畫面如果不一樣,為什麼可以拿來比較呢?這部分
我不是很了解
讚讚
嗨~你好,可以先參考我這篇GLSL Shadow Map:http://wp.me/p1my2P-rD
裡頭有更多的圖示,幫你瞭解其原理喔! 😀
讚讚
Shadow mapping也可以用在動態場景吧?
把場景針對Light Camera重新畫在depth buffer上面即可…
light map才是給靜態場景吧!
通常都會用blender等等先把光的貢獻算成貼圖(light baking)
讚讚
您的文章真的是超棒的 而且圖文並茂 !
讚讚
謝謝,有幫助到你:)
讚讚
[…] 上一篇「Shadow Mapping 原理」只有理論,這一篇用圖片來說明Shadow Map的概念,另有我實做的結果。 […]
讚讚