原理:shadow map過程
- 要建立一張 紋理。
- 把錄影機放在光源的位置
- 把渲染結果綁定在紋理上(RTT)
- 把要産生陰影的物體渲染一邊,隻渲染深度資訊,不渲染顔色資訊。
- 有兩種辦法
- 把需要接受陰影的物體傳進這種紋理。渲染的時候加一段判斷代碼
- 做個貼花
如果地面要接受陰影,必須得改。不然就隻能貼花,貼花有個問題,一塊一塊地做decal影響效率啊,主要原因是decal緊貼地形表面,需要有擷取地形高度的回調函數。
可以看看這個:Theory裡有詳細的介紹
http://devmaster.net/posts/shader-effects-shadow-mapping
隻是viewport大小就很不錯了,再配上高斯模糊。我簡單說一下
黑色是地形,紅色是個球,黃色是光源。我們要在地形上畫陰影。那就需要在 frag_shader 裡知道每個像素點,哪個地方是被擋住的。如果被擋住,這個點就畫成 最終輸出顔色 = 陰影顔色*90% + 原本的顔色*10%(随便寫個公式)。關鍵是如何判斷被擋住。
圖解

用深度資訊來判斷:
首先我們要在 光源的視角畫出這個地形的深度資訊,然後把 這個深度資訊 z 和 之前準備的深度圖同一個位置的 z 做比較:
if ( 地形像素z > 深度圖z ){
說明,有一個物體的z 比地形的z小,說明這個物體把地形擋住了,是以地形上這個像素應該有陰影;
}
else{
如果沒有被擋住,說明 地形像素的z 是離光源最近,且未被遮擋的
}
是以我們要把所有 産生陰影的 物體畫在深度圖上
深綠色 是那個光源位置 看到的球 , z比較小。
淺綠色是地形的z,比較大, 其他白色區域表示 z最大。(如果地形不産生陰影,其實把全部地形産生陰影,速度不快,對現在來說沒必要!!淺綠色就應該是白色的,也就是最大的z),完成。物體要接受陰影,得改物體渲染,地形要有陰影,地形渲染就得改。深度圖不難畫,難在怎麼渲染陰影上,因為不改的話,用固定管線我不會做。
例子
以畫地形為例,也就是用光源視角總深度圖A ,和地形的深度圖B。
AB的 view_matrix 都是光源的,通過 AB 比較判斷陰影區域,最後畫在畫面上的地形是 C, C是就是普通渲染。 用的 view_matrix 是camera的。
A要先畫一邊,把所有dem,模型都畫上,畫在一張圖檔上。畫的方式得新寫,因為渲染隻寫入深度資訊, 輸出是 32位float,不是rgb。BC同時進行。畫出B後直接跟A(通過一張紋理傳入)比較。用原來的辦法話C,然後得到結果,通過結果來計算C。C老的渲染方式來渲得到的結果 是rgb,再通過陰影的參數做些變化,最終輸出顔色。
http://www.gamerendering.com/category/shadows/shadow-mapping/