Ogre材質腳本


材質與材質腳本
基本概念
Ogre的材質(Material) 
    爲了優化渲染,必須把渲染狀態的變化減少到最小。而最頻繁的渲染狀態改變是材料的變化(大多是紋理的變化)。
Ogre的Material類封裝了物體的所有材料屬性,類似於3D Studio中material的概念。平時不被認爲是屬於材料的屬性,像culling模式和深度緩存設置等,也被Material包含近來了。因爲這些屬性同樣影響了物體的外觀,把它們放到Material類裏可以集中設置所有影響物體的屬性。這和D3D中只保存顏色組件而沒有紋理映射的Material有明顯不同。Ogre的Material可以被認爲是’Shader’的等同物。
Material類包括如下幾類屬性:
1、 基本的表面材質屬性,如對不同顏色的反射率、Shininess等等:
2、 組成Material的紋理層
3、 紋理之間的混合(Blend)方式
4、 深度緩衝設置
5、 Culling模式 
6、 紋理過濾方式(三線性過濾、雙線性過濾)
7、 是否受光照影響
8、 Shading選項
9、 霧化
 其中第二條的紋理層可以有多個,Ogre在Material類的內部定義了TextureLayer類。
紋理層(TextureLayer)
 一個紋理層可以是一幅靜止的圖像,也可以是一幅以某種方式運動的圖像,還可以是由多幅圖像組成的動畫。它可以實現多種紋理特效,如BUMPMAP、環境帖圖、運動的紋理。
材質管理器(MaterialManager)
MaterialManager類負責管理Material庫。和材質相關的類圖如下:
  
 MaterialManager還負責分析Material腳本(Material Script),從而初始化Material的屬性。下面我們來分析一下Ogre提供的材質腳本語言。
Ogre的材質腳本
Ogre提供的材質腳本可以幫助開發者簡單的設置又酷又眩的材質特效,而不用重新編譯。當然你也可以用Material和TextureLayer類提供的諸多成員函數來做到,但這就有點不太實用了。
Ogre材質腳本的默認擴展名爲.material,你也可以通過 MaterialManager類的parseAllSources方法來規定新的擴展名。系統初始化時會自動分析所有的材質腳本文件,並設置材質的屬性。注意,這裏只設置材質的屬性,並不會將材質的紋理調入內存,因爲那樣會招致極大的內存消耗!
示例一:環境帖圖
 在場景中顯示一個OGRE頭,並設置其表面材質爲環境帖圖,該環境帖圖的屬性在Example.material中設置。我們先看一下createScene()函數的代碼:
    void createScene(void)
    {
        //設置環境光
        mSceneMgr->setAmbientLight(ColourValue(0.5, 0.5, 0.5));

  //創建一個實體(OGRE頭)
        Entity *ent = mSceneMgr->createEntity("head", "ogrehead.mesh");

        //設置實體的材質
        ent->setMaterialName("Examples/EnvMappedRustySteel");

        // 將實體附屬到場景根結點上
        mSceneMgr->getRootSceneNode()->createChild()->attachObject(ent);
}
 在這裏,Entity的成員函數setMaterialName是關鍵,字符串類型的參數對應材質腳本中的材質名。"Examples/EnvMappedRustySteel"就是材質名,它在Example.material文件中定義了環境帖圖,腳本代碼如下:
 //材質名
Examples/EnvMappedRustySteel
{
 //環境光
  ambient 1.0, 1.0, 1.0 
  //散射光
  diffuse 1.0, 1.0, 1.0
 shading phong
  //紋理層0
 {
  //紋理圖象文件
   texture RustySteel.jpg
 }
  //紋理層1
 {
  //紋理圖象文件
   texture spheremap.png
   //紋理層之間的顏色累加
   colour_op add
   //指定環境帖圖的方式
  env_map spherical
  }
}
從這個例子中我們可以發現使用腳本來定義材質非常方便。首先,腳本採用類C++的語法,以{}作爲分隔符,以//作爲註釋符。每一個Material必須有一個名字,在這個例子中就是Examples/EnvMappedRustySteel,它對應一個材質。腳本規定一個命令佔一行,不可以串行。
Ogre爲其材質腳本定義了許多關鍵字(命令),用來設置材質屬性。如上例中的“ambient”與“diffuse”就是關健字,分別設置材質對環境光和散射光的反射率。在Material定義中嵌套一個“{}”,就代表一個紋理層,你可以在大括號中定義紋理層的屬性,上例中有兩層紋理,下層簡單的顯示了一幅名爲“RustySteel.jpg”的圖像 ,上層紋理採用了環境帖圖並設定了兩層紋理的混合方式爲顏色相加。
材質腳本的關健字有很多,具體請參考Ogre Tutorials的“Material Script”一節。
示例二:Example.material
 分析並嘗試更改Ogre運行環境中的Example.material文件,並在Ogre提供的演示TextureFx.exe中觀察效果。下面列出的是TextureFx.exe中用到的三個材質的定義:
// 流動的水的特效
Examples/TextureEffect3
{
 ambient 0.2 0.2 0.2

 // 關閉硬件揀選與軟件揀選,即雙面渲染
 // 硬件揀選,由硬件渲染器負責。基於畫三角形的方式(順時針,逆時針)。<clockwise|anitclockwise|none> 
 // 軟件揀選,在前幾個信息改善到硬件器之前,進行揀選。基於三角形的前和後(由三角形的向量決定)。
 cull_hardware none
 cull_software none
 
 // 水用了兩層紋理
 // 紋理層0
 {
  texture Water01.jpg
  scroll_anim -0.25 0.1
 }
 // 紋理層1
 {
  texture Water01.jpg
  scroll_anim -0.1 0.25
  // 紋理層1與紋理層2之間的混合方式,add代表兩層顏色相加。
  colour_op add
 }
}

// 大小正弦波影響的特效
Examples/TextureEffect1
{
 ambient 0.75 0.75 0.75

 // 關閉硬件揀選與軟件揀選,即雙面渲染
 // 硬件揀選,由硬件渲染器負責。基於畫三角形的方式(順時針,逆時針)。 
 // 軟件揀選,在前幾何信息改善到硬件器之前,進行揀選。基於三角形的前和後(由三角形的向量決定)。
 cull_hardware none
 cull_software none

 // 紋理層0
 {
  // 紋理圖的文件名
  texture BumpyMetal.jpg

  // wave_xform指定一個波形函數,來對指定的紋理層屬性(scale或scroll或rotate)產生影響
  // wave_xform <紋理層的某個屬性> <波形> <base> <頻率> <相位> <振幅>
  // 下面這句可以解釋成:紋理的寬度值 = 紋理的寬度值 * 正弦波當前時間的值(base+sine)
  wave_xform scale_x sine 0 0.1 0 5

  // 旋轉速率 = 旋轉速率 + 正弦波當前的值
  // wave_xform rotate sine 0.1 0.1 0 5    
 }
}


// 紋理流動的管道
Examples/TextureEffect2
{
 scene_blend add
 {
  texture Water02.jpg
  scroll_anim 0.5 0
 }
}

材質腳本關健字說明
ambient設置材質的環境光反射屬性
格式: ambient <red> <green> <blue>
正確的參數在0.0和1.0之間取值。直接影響物體材質對環境光反射能力。默認值爲白色(1.0 1.0 1.0)。
diffuse設置材質的漫反射屬性
格式: diffuse <red> <green> <blue>
正確的參數在0.0和1.0之間取值。直接影響物體材質對漫射光的反射屬性。默認值爲白色(1.0 1.0 1.0)。
specular設置材質的鏡面反射屬性
格式: specular <red> <green> <blue> <shininess>
正確的顏色參數在0.0和1.0之間取值,shininess屬性可以是任何正數。直接影響物體材質的鏡面反射屬性。默認值爲無鏡面反射(0.0 0.0 0.0 0.0)。
emissive設置材質本身的發光程度
格式: emissive <red> <green> <blue> 
正確的顏色參數在0.0和1.0之間取值。 如果一個物體自發光,它將不需要外界的照明,但是,值得注意的是這不表明這個物體將會成爲一個光源:它只會照亮自己。默認是黑色(0.0 0.0 0.0)。
scene_blend 設置與場景的混合方式,有兩種形式
格式1: scene_blend <add|modulate|alpha_blend>
這個格式比較簡單常用一些,參數意義如下:

 

 

add

渲染的結果將被以相加的方式加入場景之中,與scene_blend one one等價。對爆炸,火焰,光照,幽靈等效果比較好。

Modulate

渲染的結果與場景相乘。對煙、玻璃杯和單個的透明物效果較好。與scene_blend src_colour one_minus_src_colour等價。

alpha_blend

渲染結果中的Alpha成員將被用作遮罩。與scene_blend src_alpha one_minus_src_alpha等價。

 

格式2: scene_blend <src_factor> <dest_factor>
這個格式比較麻煩,但是比較完善。結果的計算公式爲(texture * sourceFactor) + (scene_pixel * destFactor)其中sourceFactor destFactor如下:

 

One

常數1.0

Zero

常數0.0

dest_colour

當前點的顏色

src_colour

紋理對應點的顏色

one_minus_dest_colour

1 - (dest_colour)

one_minus_src_colour

1 - (src_colour)

dest_alpha

當前點的Alpha

src_alpha

紋理對應點的Alpha

one_minus_dest_alpha

1 - (dest_alpha)

one_minus_src_alpha

1 - (src_alpha)

 

默認值: scene_blend one zero (不透明)

depth_check是否開深度測試

格式: depth_check <on|off>
默認打開深度緩存。有助於判斷兩個點的遮擋關係和前後關係,體現三維立體感。

depth_write是否允許對已經存在的深度緩存進行寫操作

格式: depth_write <on|off>

默認允許,關掉的話,則被關的Material會一直浮動在所有物體前面。

depth_func當深度緩存打開的時候,挑選一個比較函數

格式: depth_func <func>

 

always_fail

從不比較

always_pass

總是用新的換掉舊的

less

新的比舊的小就換掉

Less_equal

新的小於等於舊的就換掉

equal

等於就換掉

not_equal

不等於就換掉

greater_equal

新的大於等於舊的就換掉

greater

新的比舊的大就換掉

 

默認爲:小於等於就換掉 depth_func less_equal

cull_hardware設置硬件Cull模式

格式: cull_hardware <clockwise|anitclockwise|none>

默認順時針Cull。這與OpenGL的默認是一樣的,但和D3D的默認相反。(因爲Ogre用的是OpenGL採用的右手座標系)

cull_software設置軟件Cull模式

格式: cull_software <back|front|none>

默認背面。相當於硬件Cull模式的順時針。

lighting光照

設置動態光照是否爲此材質打開。如果關掉,將使材質本身的所有的ambient, diffuse, specular, emissiveshading屬性無效,僅僅與外界的光照有關。

格式: lighting <on|off>

默認: lighting on

shading陰影模式

格式: shading <flat|gouraud|phong>

 

Flat

每個表面僅僅用一個顏色填充

gouraud

線性過渡表面顏色

phong

並非所有的硬件都支持,這種模式測定每一個頂點的顏色。

 

默認: shading gouraud

 


filtering設置紋理過濾方式


格式: filtering <none|bilinear|trilinear>
默認是雙線性(bilinear)
Texture Layer專用屬性
texture設置紋理要使用的圖名
格式: texture <texturename>
無默認值,必須指定一個紋理名。
anim_texture動畫紋理
設置動畫紋理使用的圖片文件名。
格式1 (短的): anim_texture <base_name> <num_frames> <duration>
指定一個圖片名稱,以這個名稱後綴_1、_2一直到_num(由num_frames指定),duration指定間隔時間。
格式2 (長的): anim_texture <frame1> <frame2> ... <duration>
一個一個指定圖片名稱,duration指定間隔時間。
無默認值


texture terr_rock6.jpg

tex_address_mode border

tex_border_color 0.0 0.0 1.0

scroll 0.8 0.8    //紋理滾動到0.8,0.8作爲起點

scroll_anim 0.01 0.01   //紋理動畫,0.01指速度

可見,值不一定是一個數,可能是多個數。

補充:材質繼承時,如果僅僅修改某個紋理對象,需要給父紋理單元起個名字,以便知道在子材質中修改原來父材質裏的那個紋理單元的紋理對象,用法如下:set_texture_alias texture1 Water02.jpg,其中texture1 是父材質某個紋理單元名字,此時子材質依然有紋理單元texture1 ,但“設置紋理另一個名字Water02.jpg”,只此單元此時使用紋理Water02.jpg了。


發佈了24 篇原創文章 · 獲贊 12 · 訪問量 18萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章