Cesium中級教程8 - Introduction to Particle Systems 粒子系統入門

Cesium中文網:http://cesiumcn.org/ | 國內快速訪問:http://cesium.coinidea.com/

What is a particle system? 什么是粒子系統?

image

粒子系統是一種圖形技術,可以模擬復雜的物理效果。粒子系統是小圖像的集合,當它們一起觀看時,會形成一個更復雜的“模糊”物體,如火、煙、天氣或煙花fireworkds。通過使用諸如初始位置、速度和壽命等屬性指定單個粒子的行為,可以控制這些復雜的效果。

粒子系統效應在電影和電子游戲中很常見。例如,為了表示飛機的損壞,技術藝術家可以使用粒子系統來表示飛機引擎上的爆炸,然后渲染不同的粒子系統,表示飛機墜毀時的煙霧軌跡。

Particle system basics 粒子系統基礎

請看下面基礎粒子系統的代碼:

var particleSystem = viewer.scene.primitives.add(new Cesium.ParticleSystem({
    image : '../../SampleData/smoke.png',
    imageSize : new Cesium.Cartesian2(20, 20),
    startScale : 1.0,
    endScale : 4.0,
    particleLife : 1.0,
    speed : 5.0,
    emitter : new Cesium.CircleEmitter(0.5),
    emissionRate : 5.0,
    modelMatrix : entity.computeModelMatrix(viewer.clock.startTime, new Cesium.Matrix4()),
    lifetime : 16.0
}));
image.png

上面的代碼創建了一個ParticleSystem,一個參數化的對象,用于控制單個粒子對象Particle隨時間的外觀和行為。粒子由粒子發射器產生,有一個位置和類型,存活一段時間,然后消亡。

其中一些屬性是動態的。請注意,這里沒有使用可用的單色屬性scale,而是有一個startScaleendScale。這些允許您指定在粒子的壽命過程中,粒子大小在開始和結束比例之間的轉換。startColorendColor的工作原理相似。

影響視覺輸出的其他方法包括最大和最小屬性。對于具有最大和最小輸入的每個變量,粒子上該變量的實際值將隨機分配到最大和最小輸入之間,并在粒子的整個生命周期內靜態保持該值。例如,使用最小速度和最大速度作為每個粒子隨機選擇的速度的界限。允許像這樣更改的屬性包括imageSizespeedlifeparticleLife

Emitters 發射器

當粒子誕生時,其初始位置和速度矢量由ParticleEmitter控制。發射器將每秒生成一些粒子,由emissionRate參數指定,根據發射器類型用隨機速度初始化。

Cesium有各種各樣的粒子發射器,你可以開箱即用。

BoxEmitter 盒形發射器

BoxEmitter在一個盒子內隨機取樣的位置初始化粒子,并將它們從六個盒子表面中的一個引導出來。它接受Cartesian3參數,該參數指定框的寬度、高度和深度尺寸。

var particleSystem = scene.primitives.add(new Cesium.ParticleSystem({
    image : '../../SampleData/smoke.png',
    color: Cesium.Color.MAGENTA,
    emissionRate: 5.0,
    emitter: new Cesium.BoxEmitter(new Cesium.Cartesian3(5.0, 5.0, 5.0)),
    imageSize : new Cesium.Cartesian2(25.0, 25.0),
    modelMatrix : entity.computeModelMatrix(viewer.clock.startTime, new Cesium.Matrix4()),
    lifetime : 16.0
}));
image

CircleEmitter 圓形發射器

CircleEmitter在發射器上軸線方向上的圓形內的隨機采樣位置初始化粒子。它接受一個指定圓半徑的浮點參數。

var particleSystem = scene.primitives.add(new Cesium.ParticleSystem({
    image : '../../SampleData/smoke.png',
    color: Cesium.Color.MAGENTA,
    emissionRate: 5.0,
    emitter: new Cesium.CircleEmitter(5.0),
    imageSize : new Cesium.Cartesian2(25.0, 25.0),
    modelMatrix : entity.computeModelMatrix(viewer.clock.startTime, new Cesium.Matrix4()),
    lifetime : 16.0
}));
image

如果發射器未指定,CircleEmitter將作為默認發射器。

ConeEmitter 錐形發射器

ConeEmitter在圓錐體的頂端初始化粒子,并以隨機的角度引導它們離開圓錐體。它使用一個指定圓錐體角度的浮點參數。圓錐體沿發射器的上軸定向。

var particleSystem = scene.primitives.add(new Cesium.ParticleSystem({
    image : '../../SampleData/smoke.png',
    color: Cesium.Color.MAGENTA,
    emissionRate: 5.0,
    emitter: new Cesium.ConeEmitter(Cesium.Math.toRadians(30.0)),
    imageSize : new Cesium.Cartesian2(25.0, 25.0),
    modelMatrix : entity.computeModelMatrix(viewer.clock.startTime, new Cesium.Matrix4()),
    lifetime : 16.0
}));
image

SphereEmitter 球形發射器

SphereEmitter在球體內隨機取樣的位置初始化粒子,并將它們從球體中心向外引導。它使用一個指定球體半徑的浮點參數。

var particleSystem = scene.primitives.add(new Cesium.ParticleSystem({
    image : '../../SampleData/smoke.png',
    color: Cesium.Color.MAGENTA,
    emissionRate: 5.0,
    emitter: new Cesium.SphereEmitter(5.0),
    imageSize : new Cesium.Cartesian2(25.0, 25.0),
    modelMatrix : entity.computeModelMatrix(viewer.clock.startTime, new Cesium.Matrix4()),
    lifetime : 16.0
}));
image

Configuring particle systems 配置粒子系統

Particle emission rate 粒子發射率

emissionRate控制每秒發射多少粒子,這會改變系統中粒子的密度。
指定一組突burst以在指定時間發射粒子burst(如上面的動畫所示)。這會增加粒子系統的多樣性或爆炸性。

將該屬性添加到您的particleSystem

bursts : [
    new Cesium.ParticleBurst({time : 5.0, minimum : 300, maximum : 500}),
    new Cesium.ParticleBurst({time : 10.0, minimum : 50, maximum : 100}),
    new Cesium.ParticleBurst({time : 15.0, minimum : 200, maximum : 300})
]

在給定的時間,這些爆發將在最小和最大粒子之間發射。

Life of the particle and life of the system 粒子壽命和系統壽命

默認情況下,粒子系統將永遠運行。要使粒子系統以設定的持續時間運行,請使用lifetime以秒為單位指定持續時間,并將loop設置為false

lifetime : 16.0,
loop: false

particleLife設置為5.0將使系統中的每個粒子都具有該particleLife值。要隨機化每個粒子的輸出,請使用變量minimumParticleLifemaximumArticleLife

minimumParticleLife: 5.0,
maximumParticleLife: 10.0

Styling particles 樣式化粒子

Color 顏色

粒子的樣式是使用imagecolor指定的紋理,這些紋理可以在粒子的生命周期中更改以創建動態效果。
下面的代碼使煙霧粒子從綠色過渡到白色。

startColor : Cesium.Color.LIGHTSEAGREEN.withAlpha(0.7),
endColor : Cesium.Color.WHITE.withAlpha(0.0),

Size 大小

粒子的大小由imageSize控制。要隨機化大小,請使用minimumImageSize.xmaximumImageSize.x控制寬度(以像素為單位),并使用minimumImageSize.ymaximumImageSize.y控制高度(以像素為單位)。
下列代碼創建方形粒子在30到60像素之間:

minimumImageSize : new Cesium.Cartesian2(30.0, 30.0),
maximumImageSize : new Cesium.Cartesian2(60.0, 60.0)

粒子的大小可以通過startScaleendscale屬性在其生命周期中進行調整,以使粒子隨時間增長或收縮。

startScale: 1.0,
endScale: 4.0

Speed 速度

速度由speedminimumSpeedmaximumSpeed控制。

minimumSpeed: 5.0,
maximumSpeed: 10.0

UpdateCallback 更新回調

通過應用更新函數,可以進一步自定義粒子系統。對于重力、風或顏色更改等效果,它充當每個粒子的手動更新程序。

項目系統有一個updateCallback,它在模擬過程中修改粒子的屬性。此函數采用粒子和模擬時間步驟。大多數基于物理的效果將修改速度矢量以改變方向或速度。下面是一個讓粒子對重力作出反應的例子:

var gravityVector = new Cesium.Cartesian3();
var gravity = -(9.8 * 9.8);
function applyGravity(p, dt) {
    // Compute a local up vector for each particle in geocentric space.
    var position = p.position;

    Cesium.Cartesian3.normalize(position, gravityVector);
    Cesium.Cartesian3.multiplyByScalar(gravityVector, gravity * dt, gravityVector);

    p.velocity = Cesium.Cartesian3.add(p.velocity, gravityVector, p.velocity);
}

該函數計算重力矢量,并使用重力加速度來改變粒子的速度。
將重力設置為粒子系統的updateFunction

updateCallback : applyGravity

Positioning 定位

使用兩個Matrix4變換矩陣定位粒子系統:

  • modelMatrix:將粒子系統從模型轉換為世界坐標。
  • emitterModelMatrix:在粒子系統的局部坐標系中變換粒子系統發射器。

您可以只使用這些轉換矩陣中的一個,而將另一個保留為標識矩陣,但為了方便起見,我們提供了這兩個矩陣。為了練習創建矩陣,讓我們將粒子發射器相對于另一個實體定位。

為我們的粒子系統創建一個著重的實體。打開Hello World Sandcastle示例并添加以下代碼以向viewer添加牛奶卡車模型:

var entity = viewer.entities.add({
    model : {
        uri : '../../SampleData/models/CesiumMilkTruck/CesiumMilkTruck-kmc.glb'
    },
    position : Cesium.Cartesian3.fromDegrees(-75.15787310614596, 39.97862668312678)
});
viewer.trackedEntity = entity;

我們想增加一個來自卡車后部的煙霧效果。創建一個模型矩陣,該模型矩陣將定位粒子系統并使其方向與牛奶卡車實體相同。

modelMatrix: entity.computeModelMatrix(time, new Cesium.Matrix4())

這將粒子系統放置在卡車的中心。為了把它放在卡車的后面,我們可以用平移來創建一個矩陣。

function computeEmitterModelMatrix() {
    hpr = Cesium.HeadingPitchRoll.fromDegrees(0.0, 0.0, 0.0, hpr);
    trs.translation = Cesium.Cartesian3.fromElements(-4.0, 0.0, 1.4, translation);
    trs.rotation = Cesium.Quaternion.fromHeadingPitchRoll(hpr, rotation);

    return Cesium.Matrix4.fromTranslationRotationScale(trs, emitterModelMatrix);
}

現在,添加粒子系統:

var particleSystem = viewer.scene.primitives.add(new Cesium.ParticleSystem({
    image : '../../SampleData/smoke.png',
    
    startColor : Cesium.Color.LIGHTSEAGREEN.withAlpha(0.7),
    endColor : Cesium.Color.WHITE.withAlpha(0.0),
    
    startScale : 1.0,
    endScale : 4.0,
    
    particleLife : 1.0,
    
    minimumSpeed : 1.0,
    maximumSpeed : 4.0
    
    imageSize : new Cesium.Cartesian2(25, 25),
    emissionRate : 5.0,
    lifetime : 16.0,
    
    modelMatrix : entity.computeModelMatrix(viewer.clock.startTime, new Cesium.Matrix4())
    emitterModelMatrix : computeEmitterModelMatrix()
}));
image

還要注意,我們可以隨時間更新模型或發射器矩陣。例如,如果我們想要在卡車上設置發射器位置的動畫,我們可以修改emitterModelMatrix,同時保持modelMatrix不變。

查看完整示例,請訪問Particle System demo

Learn more 更多知識

有關使用更高級技術的粒子系統達到更酷效果,請參見粒子系統更多效果教程。

fireworks.gif

更多示例代碼請參考:

Cesium中文網交流QQ群:807482793

Cesium中文網:http://cesiumcn.org/ | 國內快速訪問:http://cesium.coinidea.com/

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,238評論 6 531
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,430評論 3 415
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,134評論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,893評論 1 309
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,653評論 6 408
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,136評論 1 323
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,212評論 3 441
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,372評論 0 288
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,888評論 1 334
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,738評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,939評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,482評論 5 359
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,179評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,588評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,829評論 1 283
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,610評論 3 391
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,916評論 2 372

推薦閱讀更多精彩內容