like this : https://threejs.org/examples/?q=fire#webgl_fire
Hi,
Here is an old demo I wrote for wildfire display:
// ***** WiledFire Drewing
var wildFirePostion = new Cesium.Cartesian3.fromDegrees(35.0304, 32.5637, 109.996);
var eventTime = 320.0; // how long it will burn in secounds - loop shoud change to false
var loopEventTime = new Boolean(true);
var wildFireActiveRadius = 5; // in meters: min=1 Max=30
var wildFireEmission = 30.0;
var fireStartScale = wildFireActiveRadius / 20;
var fireEndScale = wildFireActiveRadius / 2;
var smokeMaxParticalLife = (wildFireActiveRadius / 2) + 10.25;
var smokeEndScale = (wildFireActiveRadius / 2) + 2.0;
var smokeDensity = 1.0;
var wildFireDisplayDistance = (wildFireActiveRadius * 100) + 8000;
if (wildFireDisplayDistance < 8000) { wildFireDisplayDistance = 8000 };
var wildFireChange = new Boolean(false);
var drewWIldFireCondtions = function (wildFireChange) {
map.camera.changed.addEventListener(function () {
var cameraDistance = Cesium.Cartesian3.distance(map.scene.camera.position, wildFirePostion);
if (cameraDistance < wildFireDisplayDistance && wildFireChange == false) {
// *** Parameters that control the wild-fire and Smoke
var emitterModelMatrix = new Cesium.Matrix4();
var translation = new Cesium.Cartesian3();
var rotation = new Cesium.Quaternion();
var hpr = new Cesium.HeadingPitchRoll();
var trs = new Cesium.TranslationRotationScale();
var wildFireHeading = 0.0; // 0.0 vertical to ground
var wildFirePitch = -50.0; // -50.0 vertical to ground
var wildFireRoll = -30.0; // -30.0 vertical to ground
/* ** heading, Pitch and Roll to North, South, East and west directions **
* wind: Light Medium Strong *
* North: 0 , -20 , -20 0 , 0 , 0 0 , 10 , 10 *
* *
* South: 0, 280, -40 0, 260, -40 0, 230, -30 *
* *
* East: 0, -50, -60 0, -50, -80 -10, -50, -80 *
* *
* West: 10, 110,200 20, 110, 200 20, 110, 180 *
* *
* *************************************************************************/
var wildFiretransX = 0.0;
var wildFiretransY = 0.0;
var wildFiretransZ = 2.5; // center of image above elevation point defult 2.0
var sizeFactor = 1.0;
var wildfireGravity = 1.0; // 0.0 defult - impact the ratio beween air and parcticle weight
function wildFireApplyGravity(particle, dt) {
var gravityVector = Cesium.Cartesian3.normalize(particle.position, new Cesium.Cartesian3());
Cesium.Cartesian3.multiplyByScalar(gravityVector, wildfireGravity * dt, gravityVector);
particle.velocity = Cesium.Cartesian3.add(particle.velocity, gravityVector, particle.velocity);
var displayDistance = Cesium.Cartesian3.distance(map.scene.camera.position, wildFirePostion);
newSize = sizeFactor*(wildFireDisplayDistance / displayDistance);
particle.imageSize = new Cesium.Cartesian2(newSize, newSize);
};
function computeEmitterModelMatrix(wildFireHeading, wildFirePitch, wildFireRoll, wildFiretransX, wildFiretransY, wildFiretransZ) {
hpr = Cesium.HeadingPitchRoll.fromDegrees(wildFireHeading, wildFirePitch, wildFireRoll, hpr);
trs.translation = Cesium.Cartesian3.fromElements(wildFiretransX, wildFiretransY, wildFiretransZ, translation);
trs.rotation = Cesium.Quaternion.fromHeadingPitchRoll(Cesium.HeadingPitchRoll.fromDegrees(wildFireHeading, wildFirePitch, wildFireRoll), rotation);
return Cesium.Matrix4.fromTranslationRotationScale(trs, emitterModelMatrix);
};
// ********************************************
wildFire = new Cesium.ParticleSystem({
modelMatrix: new Cesium.Matrix4.fromTranslation(wildFirePostion),
minimumSpeed: 0.1,
maximumSpeed: 1.0,
minimumParticleLife: 0.1,
maximumParticleLife: 1.0,
lifetime: eventTime,
loop: loopEventTime, // if false the fire will burn according to lifetime value.
emitter: new Cesium.CircleEmitter(wildFireActiveRadius),
emitterModelMatrix: computeEmitterModelMatrix(wildFireHeading, wildFirePitch, wildFireRoll, wildFiretransX, wildFiretransY, wildFiretransZ),
startScale: fireStartScale,
endScale: fireEndScale,
image: 'images/fire.png',
emissionRate: wildFireEmission,
startColor: Cesium.Color.RED.withAlpha(0.6),
endColor: Cesium.Color.YELLOW.withAlpha(0.1),
bursts: [
new Cesium.ParticleBurst({ time: 1.0, minimum: 10, maximum: 50 }),
// new Cesium.ParticleBurst({ time: 3.0, minimum: 30, maximum: 100 }),
// new Cesium.ParticleBurst({ time: 5.0, minimum: 50, maximum: 150 })
],
updateCallback: wildFireApplyGravity,
});
map.scene.primitives.add(wildFire);
smoke = new Cesium.ParticleSystem({
modelMatrix: new Cesium.Matrix4.fromTranslation(wildFirePostion),
minimumSpeed: 2.0,
maximumSpeed: 4.0,
minimumParticleLife: 0.5,
maximumParticleLife: smokeMaxParticalLife, // increase the smoke height (5-30)
lifetime: eventTime,
loop: loopEventTime,
//emitter: new Cesium.CircleEmitter(wildFireActiveRadius),
emitter: new Cesium.ConeEmitter(Cesium.Math.toRadians(45.0)),
emitterModelMatrix: computeEmitterModelMatrix(wildFireHeading, wildFirePitch, wildFireRoll, wildFiretransX, wildFiretransY, wildFiretransZ),
startScale: 0.01,
endScale: smokeEndScale,
image: 'images/smoke.png',
emissionRate: wildFireEmission*smokeDensity, // increase smoke density (10-120) shloud be sync with maximumParticleLife
startColor: Cesium.Color.GREY.withAlpha(0.2),
endColor: Cesium.Color.GAINSBORO.withAlpha(0.01),
bursts: [
new Cesium.ParticleBurst({ time: 5.0, minimum: 20, maximum: 80 }),
// new Cesium.ParticleBurst({ time: 15.0, minimum: 60, maximum: 200 }),
// new Cesium.ParticleBurst({ time: 30.0, minimum: 100, maximum: 300 })
],
updateCallback: wildFireApplyGravity
});
map.scene.primitives.add(smoke);
wildFireChange = true;
wildFire.show = true;
smoke.show = true;
} else if (cameraDistance > wildFireDisplayDistance && wildFireChange == true) {
wildFireChange = false;
wildFire.show = false;
smoke.show = false;
}
});
};
drewWIldFireCondtions(wildFireChange);