粒子系統(tǒng)(Particle System)
粒子系統(tǒng)表示三維計算機圖形學(xué)中模擬一些特定的模糊現(xiàn)象的技術(shù),而這些現(xiàn)象用其它傳統(tǒng)的渲染技術(shù)難以實現(xiàn)的真實感的游戲圖形。經(jīng)常使用粒子系統(tǒng)模擬的現(xiàn)象,有火神妹、爆炸、煙、水流对省、火花、落葉浙宜、云、霧蛹磺、雪粟瞬、塵、流星尾跡或者象發(fā)光軌跡這樣的抽象視覺效果等等萤捆。
粒子系統(tǒng)的特點
- 整個現(xiàn)象都是由很多個獨立的圖像效果組成裙品,這些圖像效果都有自己的位置、移動軌跡等特點;
- 這些獨立的圖像效果組合或者疊加起來俗或,就形成了要模擬的現(xiàn)象;
- 獨立的圖像效果經(jīng)過一段生命周期之后會從屏幕上消失市怎,進而可以將其狀態(tài)重置并重新利用;
粒子系統(tǒng)的組成
- 粒子類:每個單獨的粒子是整個粒子特效的一個基本組成部分,每個粒子都具有大量屬性辛慰,比如粒子圖片区匠、生命時長、方向、速度驰弄、加速度等麻汰,這些屬性能夠決定粒子的外觀及行為表現(xiàn)。
- 粒子發(fā)射器:實際上是所有粒子的管理者戚篙,是用來進行粒子生成五鲫、粒子控制、回收粒子的管理器類岔擂。
屬性設(shè)置
粒子系統(tǒng)中可以設(shè)置的屬性如下所示位喂,不同平臺可能略有差異,但所遵守的標(biāo)準(zhǔn)相同乱灵,所以基本大同小異塑崖。
Cocos
使用OpenGL
混合原理對圖形進行渲染繪制±龋混合就是指把兩種顏色混在一起弃舒,具體一點就是把某一像素位置原來的顏色和將要畫上去的顏色,通過某種方式混在一起状原,從而實現(xiàn)特殊的效果聋呢。它是一種常用的技巧,通车咔可以用來實現(xiàn)半透明削锰,你也可以通過不同的設(shè)置得到不同的混合結(jié)果,產(chǎn)生一些有趣或者奇怪的圖象毕莱。具體可以參考:
https://www.andersriggelsen.dk/glblendfunc.php器贩,下面是混合的集中模式,可以作用于src,
BlendFactor
枚舉類型及其作用朋截。
含義 | 作用 |
---|---|
ONE | 全部使用 |
ZERO | 全部不用 |
SRC_ALPHA | 使用源顏色的透明度 |
SRC_COLOR | 使用源顏色 |
DST_ALPHA | 使用目標(biāo)顏色的透明度 |
DST_COLOR | 使用目標(biāo)顏色 |
ONE_MINUS_SRC_ALPHA | 減去源顏色的透明度 |
ONE_MINUS_SRC_COLOR | 減去源顏色 |
ONE_MINUS_DST_ALPHA | 減去目標(biāo)顏色的透明度 |
ONE_MINUS_DST_COLOR | 減去目標(biāo)顏色 |
關(guān)于粒子在cocos中的使用蛹稍。
cocos create
中提供了界面友好的工具供我們使用,粒子的簡單使用可以參考: https://docs.cocos.com/creator/manual/zh/asset-workflow/particle.html
我們可以在cocos中編輯這些粒子效果部服,在編輯的過程中可以預(yù)覽到粒子的實時效果唆姐,粒子相關(guān)的特性基本在plist
中聲明即可。
如果我們需要在cocos中通過代碼的形式控制到粒子動畫的播放和停止的話廓八,可以resetSystem()
來控制器展現(xiàn)奉芦,利用stopSystem
控制其隱藏。示例代碼如下:
//mA 表示要控制的粒子 剧蹂,即 mA: cc.ParticleSystem;
if(this.mA.active) {
this.mA.stopSystem();
} else {
this.mA.resetSystem();
}
關(guān)于顏色計算
關(guān)于cocos源碼的實現(xiàn)
ParticleTest
測試類入口声功。
CCParticleExamples
測試主體類,主要在這里實現(xiàn)宠叼。
CCParticleSystem
是粒子系統(tǒng)的基類先巴,提供對粒子的創(chuàng)建和更新管理。
ParticleSystemQuad
是CCParticleSystem
的子類,實現(xiàn)不需要批次結(jié)點時也能夠?qū)崿F(xiàn)粒子系統(tǒng)的OPENGL頂點和索引緩沖的創(chuàng)建和渲染.
CCParticleBatchNode
粒子系統(tǒng)的批次節(jié)點筹裕,用于將使用相同紋理的粒子系統(tǒng)進行同批次渲染優(yōu)化處理醋闭。
粒子系統(tǒng)實現(xiàn)類在CCParticleSystem
中,其中包含了粒子系統(tǒng)的大部分實現(xiàn)朝卒,下面是粒子系統(tǒng)中的幾個重要方法實現(xiàn)证逻。
將粒子添加到粒子系統(tǒng)的實現(xiàn)(*)
這個是整個粒子系統(tǒng)運行的必要條件,想要粒子系統(tǒng)運行起來抗斤,必須得先將粒子加入到粒子系統(tǒng)中囚企。相關(guān)代碼也比較復(fù)雜,比較多瑞眼。
這里就不貼出具體的代碼龙宏,只給出關(guān)鍵的代碼:
void ParticleSystem::addParticles(int count)
{
//life
//position
//color
//size
// rotation
// position
// Mode Gravity:
針對上面的屬性做賦值處理
}
粒子更新的實現(xiàn)
// ParticleSystem - MainLoop
void ParticleSystem::update(float dt)
{
// 省略了一些屬性的設(shè)置調(diào)整。
// 需要被重載的更新粒子的對應(yīng)矩形頂點緩沖信息塊的虛函數(shù),在這里進行界面更新
updateParticleQuads();
_transformSystemDirty = false;
if (_visible && ! _batchNode)
{
postStep();
}
}
粒子的屬性的動態(tài)設(shè)置都會在update中來完成伤疙,然后利用updateParticleQuads
來更新指定粒子的頂點緩沖中的位置數(shù)據(jù)银酗,他的具體實現(xiàn)在CCParticleSystemQuad
壘中,那么postStep
做了什么呢徒像,我們來看他的實現(xiàn)黍特,同樣,他的實現(xiàn)也在CCParticleSystemQuad
中锯蛀,
//針對不使用批次結(jié)點時的VBO頂點緩沖的更新灭衷。
void ParticleSystemQuad::postStep()
{
//綁定頂點緩沖區(qū)對象。
glBindBuffer(GL_ARRAY_BUFFER, _buffersVBO[0]);
//用_quads中數(shù)據(jù)更新綁定的緩沖區(qū)數(shù)據(jù)旁涤。
// Option 1: Sub Data
glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(_quads[0])*_totalParticles, _quads);
// Option 2: Data
// glBufferData(GL_ARRAY_BUFFER, sizeof(quads_[0]) * particleCount, quads_, GL_DYNAMIC_DRAW);
// Option 3: Orphaning + glMapBuffer
// glBufferData(GL_ARRAY_BUFFER, sizeof(_quads[0])*_totalParticles, nullptr, GL_STREAM_DRAW);
// void *buf = glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY);
// memcpy(buf, _quads, sizeof(_quads[0])*_totalParticles);
// glUnmapBuffer(GL_ARRAY_BUFFER);
//取消綁定緩沖區(qū)對象翔曲。
glBindBuffer(GL_ARRAY_BUFFER, 0);
CHECK_GL_ERROR_DEBUG();
}
停止粒子系統(tǒng)的實現(xiàn)
這個實現(xiàn)就很簡單了,主要把_isActive
設(shè)置為false
即可劈愚。把開始到當(dāng)前的運行秒數(shù)_elapsed
用_duration
賦值瞳遍, 然后把每秒發(fā)射的粒子數(shù)_elapsed
置為0,代碼如下:
void ParticleSystem::stopSystem()
{
_isActive = false;
_elapsed = _duration;
_emitCounter = 0;
}
粒子重新啟動的實現(xiàn)
粒子系統(tǒng)重新啟動的實現(xiàn)也很簡單,主要是把所有的粒子的生命值置為0菌羽。
void ParticleSystem::resetSystem()
{
_isActive = true;
_elapsed = 0;
for (int i = 0; i < _particleCount; ++i)
{
_particleData.timeToLive[i] = 0.0f;
}
}
關(guān)于粒子系統(tǒng)屬性的設(shè)置
cocos 支持兩種方式的屬性設(shè)置掠械,一種是通過字典,一種是通過plist文件算凿。
通過字典的方式份蝴,就是手動去將元素的值賦值給字典犁功,然后通過initWithDictionary
方法來實現(xiàn)賦值氓轰,這種方式比較麻煩,而且也比較容易遺漏浸卦,所以我們一般采用第二種方式署鸡,即通過plist
文件的形式來賦值。我們可以借助其他工具,生成plist文件靴庆,然后通過ParticleSystem::initWithFile
來讀取這個文件时捌,進行賦值。
術(shù)語
混合
就是把兩種顏色混在一起炉抒。
具體一點奢讨,就是把某一像素位置原來的顏色和將要畫上去的顏色,通過某種方式混在一起焰薄,從而實現(xiàn)特殊的效果拿诸。
假設(shè)我們需要繪制這樣一個場景:透過紅色的玻璃去看綠色的物體,那么可以先繪制綠色的物體塞茅,再繪制紅色玻璃亩码。在繪制紅色玻璃的時候,利用“混合”功能野瘦,把將要繪制上去的紅色和原來的綠色進行混合描沟,于是得到一種新的顏色,看上去就好像玻璃是半透明的鞭光。
前面我們已經(jīng)提到吏廉,混合需要把原來的顏色和將要畫上去的顏色找出來,經(jīng)過某種方式處理后得到一種新的顏色衰猛。這里把將要畫上去的顏色稱為“源顏色”迟蜜,如上例中的紅色;把原來的顏色稱為“目標(biāo)顏色”啡省,如上例中的綠色娜睛。
目的顏色:先畫上的顏色(相當(dāng)于內(nèi)容)。
源顏色: 后畫上去的顏色(相當(dāng)于背景)卦睹。
VAO 用于存儲頂點數(shù)據(jù)畦戒,包括頂點顏色、坐標(biāo)结序、法線障斋,以及頂點的indices。
VBO 用于存儲圖形處理器將怎么使用VBO里面的數(shù)據(jù)徐鹤,及頂點數(shù)據(jù)中哪些是坐標(biāo)垃环、哪些是顏色、哪些是法線等信息返敬。