目前至少有兩種廣泛採用的實時陰影發生技術。一種是shadowvolume,還有一種就是shadowmap。
shadowvolume基於的是幾何體演算法,通過延伸光照輪廓區域進行正反面兩次渲染在螢幕的模板緩衝區內分離出陰影區域(本站中有z-fail陰影的演算法要點)。shadowvolume能夠得到十分精確的陰影區域,畫質較好,而且渲染流程十分簡單,缺點是建立光照輪廓延伸體十分費時費資源,另外陰影邊緣視覺上比較「硬」。
shadowmap基於的是shader技術,通過建立z深度圖、逐畫素比較深度得到陰影區域。該方法形成陰影速度非常快,對於一些固定的建築物之類的圖素形成陰影尤其出色,對於一些運動物體的陰影最多隻需渲染兩次物體即可形成陰影(筆者的配置為ati9550、celerond2.4g,shadowmap陰影基本上對速度沒有影響,而生成shadowvolume則每幀繪圖時間增加了2個毫秒);缺點是需要顯示卡有對vs、ps的支援,而且記憶體消耗較大,同時只能生成平行光下的陰影,而且無法做到將陰影投影到所有的物體。
所以,兩種陰影互為優缺點,採用何種陰影方式需要按照自己的需求來。下面是自投影shadowmap的d3d8實現要點(可同時參考d3d9的例子,因為筆者覺得d3d9速度比d3d8慢故採用了d3d8)。
1、建立lookup紋理(2048 * 1),這個紋理是深度值的索引。所謂深度,指的是螢幕z值。紋理每乙個畫素點的rgba = ( 畫素點橫座標 & 0xff, ( 畫素點橫座標 & 0xff00 ) >> 3, 0, 0 ),比如畫素橫座標為xp=256,則畫素rgba = ( 255, 32, 0, 0 )。這個紋理很重要,以後紋理的顏色值就可以代表z值。
2、設定lookup紋理;設定lightviewproj:將眼睛移至光源處,觀察方向為光源照射方向,螢幕的投影矩陣設為正交(d3dxmatrixortholh);然後渲染物體到一張紋理,建立深度圖。此處的要點是vertexshader,渲染的時候只對定點做位置變換即可,然後把變換後的頂點z值寫入ot0進行儲存(mov ot0, r0.z)。此時的紋理就叫做depthtexture,每個畫素的顏色值就儲存著z值。
3、恢復視角到原正常觀察位置,設定depthtexture紋理,再次渲染物體,分別儲存每個頂點在lvp空間(lightviewproj)下的實際深度和lvp下該頂點對應受光面頂點的深度到ot1和ot2。
如何找到每個畫素對應的lvp空間的受光面畫素呢?可以在vs進行頂點渲染的時候將每個頂點對應到lightviewproj的受光面,則經過插值得到的畫素也一一對應到了lvp空間。頂點對應的lvp頂點計算方法為:頂點 * 頂點變換矩陣 * lvp_view矩陣 * lvp_proj矩陣。同時通過對齊depthtexture將lvp下受光面上對應頂點的深度儲存下來,也就是lvp頂點貼圖座標要與depthtexture對齊,此時該頂點的紋理顏色值 = lvp空間下受光面的z值(參看要點2的最後一句話)。然後儲存lvp空間下該頂點的實際深度用於在ps中進行深度比較。
4、將螢幕上的每個畫素在lvp下的深度與lvp下的受光面畫素逐一比較深度(z值),z值大的就在陰影區,需要將該畫素設定為陰影顏色,z值小於等於的則在照亮區域,顏色不變。在ps中將每個畫素對應的depthtexture顏色值進行如下操作:
mov_d8 r2.r, r2.r//r2.r值右移3位
add r2.r, r2.r, r2.g//累加r2.r與r2.g值,得到對應於lvp空間受光面畫素深度值
將此深度值與實際的深度值(r1)進行sub、cmp操作比較即可得出是否在受光面,如果是陰影區就將該畫素(r0)染黑一點即可。
ShadowMap渲染陰影方法及問題
shadowmap基於的原理 sm演算法是乙個2 pass繪製演算法,第一pass從光源視點繪製場景,生成sm紋理,第2pass從視點檢視按常規方法繪製場景 從光源的位置觀察場景,這時候我們看不到的地方就是該有陰影的地方,於是可以使用比較畫素到光源距離的方法來確定某個畫素是否在陰影之中。於是我們需要...
ShadowMap實現軟陰影,使用整數紋理
陰影貼圖技術一般都是使用浮點紋理,這樣有足夠的精度來儲存深度值,不過,為了在不支援浮點紋理的顯示卡上使用陰影貼圖 比如很多整合顯示卡 就只好使用整數紋理,對效果的影響不是很大.於是,使用a8r8g8b8格式的紋理來儲存深度值,將深度值壓縮進rgba通道,方法如下 float4 floor fdept...
遊戲裡的動態陰影 ShadowMap實現原理
shadowmap是比較流行的實時陰影實現方案,原理比較簡單,但真正實現起來還是會遇到很多問題的,我這裡主要記錄下實現方式 先看效果 實現原理 shadowmap技術是從燈光空間用相機渲染一張rendertexture,把深度值寫入其中所以稱之為深度圖,在把接受陰影的物體從模型空間轉換到燈光空間中,...