Mage小組 著
Email: norman_chen@163.com
renwind@163.com
QQ: 18725262
http://www.173d8.com
http://blog.csdn.net/pizi0475
粒子系統及粒子指令碼
粒子系統在三維顯示中佔有很重要的地位,如3D中的雨,雪,噴泉,爆炸效果等都是粒子系統神奇魅力的表現。
我們可以用程式的方式虛擬美國哥倫比亞號太空梭在太空中爆炸的情境:大大小小的片段向四處飛濺,耀眼的火花,滾滾的濃煙,在這其中多數元素都是混亂的。從技術的角度講本情境中的大多數效果得益於一個優秀的粒子系統。煙,火花,這些3D中的效果通常使用粒子系統來建立的。
基本概念
粒
子是用四邊形來表示的。它有長寬,和其方向,有數量和材質,還有重量。這些屬性封在粒子屬性變換器(Affector)中,Affector中包含顏色衰
退變換器(¬ColourFaderAffector)和線形影響變換器(LinearForceAffector)。粒子的產生由粒子發生器
(Emmiter)產生。它包含有盒狀粒子發生器(BoxEmmitter)和點狀粒子發生器(
¬PointEmmiter),由這些組成粒子指令檔,以.particle為其副檔名。點狀粒子發生器隨機地從單一的點發射粒子;盒狀粒子發生器隨機
的從一個地區發射粒子。通過建立Plugins你可以向ogre裡增加一個新的發射器。當前ogre只支援點狀粒子發生器和盒狀粒子發射器。
當粒子發生器不停的噴發出大量粒子時,就可以形成煙、火和爆炸等效果。
粒子系統結構圖:
粒子系統指令碼
OGRE提供了粒子系統指令碼語言,可以在指令碼中設定粒子的各種屬性,而不用重新編譯器。這樣給使用者帶來了方便。需要注意的粒子系統指令檔有自己的文法,類似C++:注釋用“//”,用“{ }”來區分界限。但不支援在代碼後跟注釋。
粒子系統在指令碼中是以模板的形式定義的,你可以在程式運行期建立多個執行個體。
載入粒子指令碼
粒
子系統指令碼是在系統初始化的時候載入的,預設情況下系統在公用資源路徑(Root::addResourceLocation函數指定)下尋找所有副檔名
為“.particle”的檔案並解析它們。如果你想指定其它副檔名可使用
ParticleSystemManager::getSingleton().parseAllSources方法,如果想解析單個的粒子系統指令檔
可使用ParticleSystemManager::getSingleton().parseScript方法。
一旦粒子系統指令碼被載入,你
可以使用ParticleSystemManager::getSingleton().createSystem()方法來建立一個執行個體化的粒子系統,
該方法接收兩個參數,一個該粒子系統的名稱,而另外一個參數是要參照的模板名稱(也就是指令碼中定義過的模板名稱。
格式
可以在一個指令檔中定義多個粒子系統模板。
以下是一個典型的粒子指令碼,該指令碼包含三個粒子系統模板,它被用於OGRE的粒子DEMO中,你可以運行該DEMO來查看實際效果。當然你也可以修改這些屬性來改變效果。
// 粒子系統模板名
// Exudes greeny particles which float upwards
Examples/GreenyNimbus
{
// 粒子的Material
material Examples/Flare
// 粒子的寬度
particle_width 30
// 粒子的高度
particle_height 30
// 粒子的裁剪模式:整體包圍盒裁剪或單個粒子裁剪。
cull_each false
// 粒子數目
quota 10000
// 公告板的類型:point指代表粒子的四邊形總是面向攝像機。
billboard_type point
// 盒狀粒子發射器
emitter Box
{
// 粒子發射時偏離direction的最大角度
angle 30
// 發射速率(個/秒)
emission_rate 30
// 粒子存留時間(秒)
time_to_live 50
// 粒子的發射方向
direction 0 1 0
// 速率
velocity 10
// 顏色起始值
colour_range_start 1 1 0
// 顏色結束值(在起始值和結束值之間取隨機數)
colour_range_end 0.3 1 0.3
// 定義粒子發射器BOX的大小
width 60
height 60
depth 60
}
// LinearForce:對運動中的粒子的加上一個外力,影響其運動軌跡。
// Make em float upwards
affector LinearForce
{
// 指定外力的影響(用向量表示)
force_vector 0 100 0
// add:粒子的運動向量加上外力的向量。效果:勻加速運動。
force_application add
}
// ColourFader:影響粒子中的顏色
// Fader
affector ColourFader
{
// 每秒衰減0.25
red -0.25
green -0.25
blue -0.25
}
}
// A sparkly purple fountain
Examples/PurpleFountain
{
material Examples/Flare2
particle_width 20
particle_height 20
cull_each false
quota 10000
billboard_type oriented_self
// Area emitter
emitter Point
{
angle 15
emission_rate 75
time_to_live 3
direction 0 1 0
velocity_min 250
velocity_max 300
//顏色變換上下限
colour_range_start 0 0 0
colour_range_end 1 1 1
}
// Gravity
affector LinearForce
{
force_vector 0 -100 0
force_application add
}
// Fader
affector ColourFader
{
red -0.25
green -0.25
blue -0.25
}
}
// A downpour
Examples/Rain
{
material Examples/Droplet
particle_width 50
particle_height 100
cull_each true
quota 10000
// Make common direction straight down (faster than self oriented)
billboard_type oriented_common
common_direction 0 -1 0
// Area emitter
emitter Box
{
angle 0
emission_rate 100
time_to_live 5
direction 0 -1 0
velocity 50
colour_range_start 0.3 1 0.3
colour_range_end 0.7 1 0.7
width 1000
height 1000
depth 0
}
// Gravity
affector LinearForce
{
force_vector 0 -200 0
force_application add
}
}
指令碼中的每一個粒子系統模板都必須有一個名字,且必須是在“{”前的第一行。這個名稱必須是唯一的。名字中可以包含“/”來構成路徑,但OGRE引擎只把它當成字串看待,並不真正來分析這個路徑,它僅僅方便程式員來區分層次。
一個粒子系統可以設定一些上層屬性,如:quota 表示允許的最大粒子個數。除了基本屬性外,還必須在一個粒子系統模板內嵌套定義發射器Emitters和屬性變換器affectors。它們內部的屬性與它們的類型有關。
粒子系統指令碼的屬性較多,請參考OGRE Tutorial中的Particle Scripts部分。
樣本一
開啟OGRE DEMO中Emample.particle試著改變粒子發射器(emitter Box和emitter
Point)和粒子的發射速率(比如將emission_rate 100改為emission_rate
30),粒子存留時間(秒)(time_to_live
)等等,注意區分大小寫,存檔,然後再運行Demo_ParticleFX.exe看看效果。
樣本二
開啟OGRE中的Demo_ParticleFX工程,查看其中的代碼,理解粒子系統的調用方法。
該程式在運行時,情境中有一個食人魔,頭上冒著綠色的煙霧(粒子系統),旁邊有兩個運動的粒子發生器噴發著五顏六色光點(還是粒子系統)。
OGRE引擎在初始化的時候會自動載入粒子系統指令檔,我們不用管它。
在
程式的createScene函數裡,通過ParticleSystem* pSys1 =
ParticleSystemManager::getSingleton().createSystem("Nimbus",
"Examples/GreenyNimbus");建立出一個實際的粒子系統Nimbus,它採用的模板"Examples
/GreenyNimbus"就是在粒子系統指令碼中定義的。
本程式共有三個粒子系統,建立方法都一樣,只不過採用的模板不同。
粒子系統被建立好後,可以將其attach到情境節點上去,便於運動控制。代碼如下:
mSceneMgr->getRootSceneNode()->createChild()->attachObject(pSys1);
一旦粒子系統被attach到情境節點上,就可以通過FrameListener的frameStarted方法來控制節點運動,當然粒子也就邊運動邊噴發了。