1. 程式人生 > >一個基於Ogre,適合2.5D遊戲比較完美的陰影解決方案

一個基於Ogre,適合2.5D遊戲比較完美的陰影解決方案

這是我以前升級Ogre引擎,實現的一個方案,願意拿出來分享下經驗。

每個精通Ogre的程式設計師,都會對Ogre自帶的陰影方案感到失望,不管是模板陰影,還是投影陰影,都是固定渲染管線的陰影,效果都不好。

暢遊《天龍八部》都升級到3了,還採用以前的陰影方案,說明要找個理想的方案替換以前的真是很難。

天龍的方案是,人物用模板陰影,場景用靜態烘培的陰影貼圖貼地形上。效果一般般,這是以前很多遊戲的做法。由於模板陰影是基於模型頂點的,沒法支援alpha test。

那麼樹葉這種帶有alpha test的模型的陰影用不了。而靜態烘培的光照圖,精度決定了用在樹木這種模型上的效果很不好,而且都不支援自投影,

而投影陰影,本身有3個缺陷,比如反向投影,無自投影,和地形穿插的投影有穿幫等bug,也不太實用,很早就被天龍拋棄了。

固定管線的陰影方案遲早都要被淘汰,而基於shader實現的shadow map陰影技術是比較主流的高階陰影技術。

shadow map的技術分支,就太多了,幾十種都有,但每種技術都是不完美的,也有各種各樣的問題。國外次世代遊戲多用VSM和CSM這種。

我要考慮的前提效率。 效率必須是第一位,在國內開發引擎,任何NB的效果,如果效率有問題,就沒任何適用價值。

權衡一下,結合了自己2.5D鎖視角遊戲的實際情況,我選擇了傳統的depth shawow map。

傳統的陰影很多問題,需要很多技術來改進才有實用價值。

比如陰影精度問題,邊緣鋸齒,某些視角陰影自走樣等等。

改進質量的方法:

1)攝像機聚焦到可視區域,提高陰影的精度。

2)陰影紋理大小採用1024或2048來提高陰影的精度。

3)由於看不到很遠的地方,可以控制陰影距離,再次提高陰影精度,如果是純3D遊戲大場景,能看很遠,就需要換成PSSM技術。

4)4X4的PCF濾波來實現簡單的軟陰影,消除生硬的邊緣。

5)採用基於梯度的深度偏移減少自投影走樣

改進效率的方法:

1)只支援單光源的陰影,那麼就不需要迭代每個光源,陰影貼花的時候採用modulate的方式,而不是add,這樣只需增加一個紋理單元,而不會增加渲染pass

,由於一個pass,那麼陰影和霧也可以完美結合。

其他要解決的問題

1)樹木這種alpha test的模型的投射和接受陰影。

效果圖



陰影質量令人滿意,且支援自投影,alpha test的竹子,也支援陰影。以上效果都在我筆記本上用地形編輯器測試的

效率方面,和傳統的投影陰影相比,也是渲染一張陰影圖,在貼花方面並沒有增加渲染批次,材質指令碼也簡單

// 2012.12.5 luoyinan 

// 陰影投射材質 浮點紋理
material Ogre/DepthShadowmap/Caster/Float
{
    technique
    {
		scheme shadow_map
		
        pass 
        {
			fog_override true none
			
            vertex_program_ref Ogre/DepthShadowmap/CasterVP
            {
            }
            fragment_program_ref Ogre/DepthShadowmap/CasterFP
            {
            }
        }
    }
}
 
// 基本的自投影材質
material Ogre/DepthShadowmap/BasicTemplateMaterial
{
    technique
    {
		scheme shadow_map
		
        pass 
        {
            // Vertex program reference
            vertex_program_ref Ogre/DepthShadowmap/ReceiverVP_Entity
            {
            }
 
            // Fragment program
            fragment_program_ref Ogre/DepthShadowmap/ReceiverFP_Entity
            {
            }
 
            texture_unit
            {
                content_type shadow
                tex_address_mode border  
				tex_border_colour 1 1 1
            }
			
			texture_unit
            {
                texture_alias <baseTexture>
            }
        }
    }
	
	technique
    {
        pass 
        {
			diffuse vertexcolour
            texture_unit
            {
                texture_alias <baseTexture>
            }
        }
	}
}

// 支援alpha test和雙面的 陰影自投影材質,
material Ogre/DepthShadowmap/AlphaTestTemplateMaterial
{
	technique
    {
		scheme shadow_map
		
			
        pass 
        {
			alpha_rejection greater 128
			cull_hardware none
		
            // Vertex program reference
            vertex_program_ref Ogre/DepthShadowmap/ReceiverVP_Entity
            {
            }
 
            // Fragment program
            fragment_program_ref Ogre/DepthShadowmap/ReceiverFP_Entity
            {
            }
 
            texture_unit
            {
                content_type shadow
                tex_address_mode border  
				tex_border_colour 1 1 1
            }
			
			texture_unit
            {
                texture_alias <baseTexture>
            }
        }
    }
	
	technique
    {
        pass 
        {
			diffuse vertexcolour
			alpha_rejection greater 128
			cull_hardware none
            texture_unit
            {
                texture_alias <baseTexture>
            }
        }
	}
}

cg檔案暫時保密。