Cesium官方教程9--粒子系統

原文地址:https://cesiumjs.org/tutorials/Particle-Systems-Tutorial/

粒子系統介紹
這篇教程帶你學習Cesium的粒子相關API,比如如何在你的項目裏添加煙,火,火花等特效。
Cesium官方教程9--粒子系統
什麼是粒子系統?
粒子系統是一種圖形學技術,用來模擬複雜的物理效果。粒子系統是由一堆很小的圖片組成,看起來就像一些複雜的“含糊不清(fuzzy)”對象,就像火、煙、天氣、或者 ×××。這些複雜效果其實是通過控制每一個獨立的粒子的初始位置、速度、生命週期等屬性來完成。
粒子系統通常在電影和遊戲中應用廣泛。比如,用來表示飛機的損傷過程,藝術家或者開發人員先用粒子系統來展示飛機引擎的爆炸效果,然後在用另一個粒子系統表示飛機墜毀過程中的煙霧軌跡。
粒子系統基本概念
先通過代碼看下基本的粒子系統:
Cesium官方教程9--粒子系統
效果是這樣的:
Cesium官方教程9--粒子系統最終效果

上述代碼裏創建了 ParticleSystem類的對象, 傳遞了一個對象參數,來控制每個獨立粒子 Particle 的外觀 。粒子從 ParticleEmitter中生成,它有一個位置和類型、生存一段時間後,就消亡。
部分屬性可以是動態的。注意示例代碼裏並非用了一個color屬性,而是用了startColor 和endColor兩個顏色屬性。在粒子的整個時間中,根據時間在兩個顏色之間做插值。startScale和endScale屬性也是類似。
其他影響粒子系統效果的是maximum和minimum 屬性。對於每個有最小和最大參數配置的屬性,在粒子的初始化過程中會在這個最小最大值範圍內隨機,然後整個粒子的生存週期內都不會變化。比如,設定粒子的初始運行速度,可以直接設置 speed變量,也可以設置 minimumSpeed 和 maximumSpeed 變量做爲隨機速度的上下邊界。允許類似設置的屬性包括:imageSize, speed, life, 和particleLife。
通過這些參數可以創建很多很多種粒子效果,具體可以試下Sandcastle的粒子系統示例。
掌握Cesium的粒子系統,等同於對這些不同參數非常熟悉。我們討論一些屬性的細節。
發射器( Emitters)
ParticleEmitter控制了粒子產生時候的位置以及初始速度方向。發射器依據 emissionRate來決定每秒產生多少粒子,根據發射器類型不同決定了粒子的隨機速度方向。
Cesium內置了各種粒子發射器。
BoxEmitter
BoxEmitter 類在盒子裏(box)裏隨機一個位置,沿着盒子的6個面的法向量向外運動。它接受一個Cartesian3 參數,定義了盒子的長寬高。

Cesium官方教程9--粒子系統
Cesium官方教程9--粒子系統
CircleEmitter
圓形發射器使用CircleEmitter類在圓形面上隨機一個位置,粒子方向是發射器的向上向量。它接受一個float參數指定了圓的半徑。
Cesium官方教程9--粒子系統
Cesium官方教程9--粒子系統
circleemitter

如果沒有指定發射器,默認使用圓形發射器。
ConeEmitter
錐形發射器類使用ConeEmitter在椎體頂點產生粒子,粒子方向在椎體內隨機一個角度向外。它接受一個float參數,制定了錐角。椎的方向沿着向上軸。
The ConeEmitter class initializes particles at the tip of a cone and directs them at random angles out of the cone. It takes a single float parameter specifying the angle of the cone. The cone is oriented along the up axis of the emitter.
Cesium官方教程9--粒子系統
Cesium官方教程9--粒子系統
SphereEmitter
球形發射器使用SphereEmitter類在球體內隨機產生粒子,初始速度是沿着秋心向外。它接受一個float參數指定了球體半徑。
Cesium官方教程9--粒子系統
配置粒子系統
Cesium有很多選項來調整粒子效果。

粒子發射速率
emissionRate 屬性控制每秒生成多少個粒子,用來調整粒子密度。
可以設定一個爆炸對象的數組,用來控制在某個特定時刻產生爆炸效果。這是添加各種爆炸效果的最好方法。

給粒子增加下面的屬性:
Cesium官方教程9--粒子系統
在給定時刻,這些爆炸效果會產生隨機個粒子,在設定最少和最多值之間。

粒子的生命週期和粒子系統的生命週期
一些參數控制了粒子系統的生命週期,默認粒子系統一直運行。
設置lifetime屬性控制粒子的持續時間,同時需要設置loop屬性爲false。比如設定一個粒子系統運行5秒:
Cesium官方教程9--粒子系統
設置particleLife 屬性爲5.0 表示設置每個粒子的生命週期是5秒。爲了每個粒子都有一個隨機生命週期,我們可以設置 minimumParticleLife 和 maximumParticleLife。比如下面的代碼設置了粒子生命週期在5秒和10秒之間:
Cesium官方教程9--粒子系統
粒子樣式
顏色(Color)
除了設定image屬性來控制粒子的紋理外,還可以設定一個顏色值,這個值可以在粒子的生命週期內變化。這個在創建動態變化效果非常有用。
比如,下面代碼使火焰粒子產生的時候是淡紅色,消亡的時候是半透明×××。
Cesium官方教程9--粒子系統
大小(Size)
通常粒子大小通過imageSize屬性控制。如果想設置一個隨機大小,每個粒子的寬度在minimumImageSize.x 和 maximumImageSize.x 之間隨機,高度在minimumImageSize.y 和 maximumImageSize.y之間隨機,單位爲像素。
下面代碼創建了像素大小在30~60之間的粒子:
Cesium官方教程9--粒子系統
和顏色一樣,粒子大小的倍率在粒子整個生命週期內,會在startScale 和 endScale屬性之間插值。這個會導致你的粒子隨着時間變大或者縮小。
下面代碼使粒子逐漸變化到初始大小的4倍:
Cesium官方教程9--粒子系統
運行速度Speed
發射器控制了粒子的位置和方向,速度通過speed參數或者minimumSpeed和maximumSpeed 參數來控制。下面代碼讓粒子每秒運行5~10米:
Cesium官方教程9--粒子系統
更新回調(UpdateCallback)
爲了提升仿真效果,粒子系統有一個更新函數。這個是個手動更新器,比如對每個粒子模擬重力或者風力的影響,或者除了線性插值之外的顏色插值方式等等。
每個粒子系統在仿真過程種,都會調用更新回調函數來修改粒子的屬性。回調函數傳過兩個參數,一個是粒子本身,另一個是仿真時間步長。大部分物理效果都會修改速率向量來改變方向或者速度。下面是一個粒子響應重力的示例代碼:
var gravityScratch = new Cesium.Cartesian3();
function applyGravity(p, dt) {
// 計算每個粒子的向上向量(相對地心)
var position = p.position;

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

p.velocity = Cesium.Cartesian3.add(p.velocity, gravityScratch, p.velocity);

}
這個函數計算了一個重力方向,然後使用重力加速度(-9.8米每秒平方)去修改粒子的速度方向。 .
然後設置粒子系統的更新函數:
Cesium官方教程9--粒子系統
位置
粒子系統使用兩個轉換矩陣來定位:

modelMatrix : 把粒子系統從模型座標系轉到世界座標系。

emitterModelMatrix : 在粒子系統的局部座標系內變換粒子發射器。
我們提供兩個屬性也是爲了方便,當然可以僅僅設置一個,把另一個設置爲單位矩陣。爲了學習創建這個矩陣,我們嘗試把我們的粒子系統相對另一個entity。
首先創建一個entity。打開Sandcastle 的 Hello World示例,敲入下面的代碼:
Cesium官方教程9--粒子系統
在viewer裏創建了一個飛機模型。
下來,我們如何在場景種擺放我們的粒子系統。我們先給飛機的一個引擎上放一團火。首先給粒子系統創建一個模型矩陣,這個矩陣和飛機的位置和朝向完全相同。意思就是飛機的模型矩陣也要做爲粒子系統的矩陣,這麼設置modelMatrix:
function computeModelMatrix(entity, time) {
var position = Cesium.Property.getValueOrUndefined(entity.position, time, new Cesium.Cartesian3());
if (!Cesium.defined(position)) {
return undefined;
}
var orientation = Cesium.Property.getValueOrUndefined(entity.orientation, time, new Cesium.Quaternion());
if (!Cesium.defined(orientation)) {
var modelMatrix = Cesium.Transforms.eastNorthUpToFixedFrame(position, undefined, new Cesium.Matrix4());
} else {
modelMatrix = Cesium.Matrix4.fromRotationTranslation(Cesium.Matrix3.fromQuaternion(orientation, new Cesium.Matrix3()), position, new Cesium.Matrix4());
}
return modelMatrix;
}
現在這個矩陣已經把粒子放到了飛機中心位置。可是我們想讓粒子在飛機的一個引擎上產生,所以我們再創建一個在模型座標系的平移矩陣。這麼計算:
function computeEmitterModelMatrix() {Cesium官方教程9--粒子系統
hpr = Cesium.HeadingPitchRoll.fromDegrees(0.0, 0.0, 0.0, new Cesium.HeadingPitchRoll());
var trs = new Cesium.TranslationRotationScale();
trs.translation = Cesium.Cartesian3.fromElements(2.5, 4.0, 1.0, new Cesium.Cartesian3());
trs.rotation = Cesium.Quaternion.fromHeadingPitchRoll(hpr, new Cesium.Quaternion());
return Cesium.Matrix4.fromTranslationRotationScale(trs, new Cesium.Matrix4());
}

現在就可以去計算偏移矩陣了,我們先用一些基本參數創建粒子系統,代碼如下:
Cesium官方教程9--粒子系統

這就做到了前面示例裏描述的效果,把粒子特效放到了飛機的引擎上。
Cesium官方教程9--粒子系統
最終效果
注意我們可以隨時更改模型或者發射器矩陣。比如,我們想通過通過去更改粒子發射器相對飛機的位置,我們只需要修改emitterModelMatrix,而保持 modelMatrix 不變。這樣就非常容易的在模型空間重新定位了。
這種定位方式並非直接設定一個position屬性,而是提供了一種有效的,靈活的矩陣變換方式,適應更多效果要求。
這就是粒子系統的基礎知識,很期待看到你用他們做出來的效果。
更多粒子系統特效,以及更高級的技術,請看更多粒子特效教程 。
Cesium官方教程9--粒子系統
更多示例代碼:

粒子系統示例
粒子系統×××示例
Cesium官方教程9--粒子系統

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章