第16章 - 粒子系统与特效
第16章:粒子系统与特效
16.1 粒子系统基础
16.1.1 ParticleSystem 概述
// 创建基本粒子系统
const particleSystem = new Cesium.ParticleSystem({
image: 'particle.png',
// 发射器
emitter: new Cesium.CircleEmitter(2.0),
// 发射速率
emissionRate: 50,
// 粒子属性
startScale: 1.0,
endScale: 4.0,
startColor: Cesium.Color.RED.withAlpha(0.7),
endColor: Cesium.Color.YELLOW.withAlpha(0.0),
// 速度
speed: 5.0,
// 生命周期
lifetime: 1.6,
// 模型矩阵
modelMatrix: Cesium.Transforms.eastNorthUpToFixedFrame(
Cesium.Cartesian3.fromDegrees(116.4, 39.9, 100)
)
});
viewer.scene.primitives.add(particleSystem);
16.1.2 发射器类型
// 圆形发射器
new Cesium.CircleEmitter(radius)
// 球形发射器
new Cesium.SphereEmitter(radius)
// 盒子发射器
new Cesium.BoxEmitter(new Cesium.Cartesian3(width, height, depth))
// 锥形发射器
new Cesium.ConeEmitter(angle)
16.2 常见特效实现
16.2.1 火焰效果
function createFireEffect(viewer, position) {
const particleSystem = new Cesium.ParticleSystem({
image: getFireParticle(),
startScale: 1.0,
endScale: 4.0,
particleLife: 1.5,
speed: 5.0,
emitter: new Cesium.ConeEmitter(Cesium.Math.toRadians(30)),
emissionRate: 30.0,
startColor: new Cesium.Color(1, 1, 0, 0.7),
endColor: new Cesium.Color(1, 0, 0, 0.0),
imageSize: new Cesium.Cartesian2(25, 25),
modelMatrix: Cesium.Transforms.eastNorthUpToFixedFrame(
Cesium.Cartesian3.fromDegrees(position.lon, position.lat, position.height)
),
lifetime: 16.0,
loop: true
});
viewer.scene.primitives.add(particleSystem);
return particleSystem;
}
function getFireParticle() {
const canvas = document.createElement('canvas');
canvas.width = 64;
canvas.height = 64;
const ctx = canvas.getContext('2d');
const gradient = ctx.createRadialGradient(32, 32, 0, 32, 32, 32);
gradient.addColorStop(0, 'rgba(255, 255, 200, 1)');
gradient.addColorStop(0.3, 'rgba(255, 200, 0, 0.8)');
gradient.addColorStop(1, 'rgba(255, 100, 0, 0)');
ctx.fillStyle = gradient;
ctx.fillRect(0, 0, 64, 64);
return canvas;
}
16.2.2 烟雾效果
function createSmokeEffect(viewer, position) {
return new Cesium.ParticleSystem({
image: getSmokeParticle(),
startScale: 1.0,
endScale: 8.0,
particleLife: 4.0,
speed: 3.0,
emitter: new Cesium.CircleEmitter(5.0),
emissionRate: 10.0,
startColor: new Cesium.Color(0.5, 0.5, 0.5, 0.5),
endColor: new Cesium.Color(0.8, 0.8, 0.8, 0.0),
imageSize: new Cesium.Cartesian2(30, 30),
modelMatrix: Cesium.Transforms.eastNorthUpToFixedFrame(
Cesium.Cartesian3.fromDegrees(position.lon, position.lat, position.height)
),
lifetime: 16.0,
loop: true
});
}
16.2.3 雨雪效果
// 雨效果
function createRainEffect(viewer) {
const rainParticle = createRainParticle();
const particleSystem = new Cesium.ParticleSystem({
image: rainParticle,
startScale: 1.0,
endScale: 1.0,
particleLife: 1.5,
emitter: new Cesium.BoxEmitter(new Cesium.Cartesian3(1000, 1000, 50)),
emissionRate: 2000,
startColor: Cesium.Color.WHITE.withAlpha(0.5),
endColor: Cesium.Color.WHITE.withAlpha(0.3),
imageSize: new Cesium.Cartesian2(2, 20),
gravity: new Cesium.Cartesian3(0, 0, -9.8),
lifetime: 16.0,
loop: true,
modelMatrix: computeRainMatrix()
});
viewer.scene.primitives.add(particleSystem);
// 跟随相机
viewer.scene.preRender.addEventListener(function() {
particleSystem.modelMatrix = computeRainMatrix();
});
return particleSystem;
}
function computeRainMatrix() {
const camera = viewer.camera;
const offset = Cesium.Cartesian3.multiplyByScalar(
camera.direction, 500, new Cesium.Cartesian3()
);
const position = Cesium.Cartesian3.add(camera.position, offset, new Cesium.Cartesian3());
return Cesium.Transforms.eastNorthUpToFixedFrame(position);
}
// 雪效果
function createSnowEffect(viewer) {
const particleSystem = new Cesium.ParticleSystem({
image: getSnowParticle(),
startScale: 1.0,
endScale: 1.0,
particleLife: 6.0,
emitter: new Cesium.BoxEmitter(new Cesium.Cartesian3(1000, 1000, 50)),
emissionRate: 500,
startColor: Cesium.Color.WHITE,
endColor: Cesium.Color.WHITE.withAlpha(0.0),
imageSize: new Cesium.Cartesian2(8, 8),
gravity: new Cesium.Cartesian3(0, 0, -1),
lifetime: 16.0,
loop: true
});
viewer.scene.primitives.add(particleSystem);
return particleSystem;
}
16.3 动态线效果
// 流动线效果
class FlowingLineMaterial {
constructor(options = {}) {
this.color = options.color || Cesium.Color.CYAN;
this.speed = options.speed || 5.0;
this.percent = options.percent || 0.1;
this.gradient = options.gradient || 0.05;
}
getMaterial() {
return new Cesium.Material({
fabric: {
type: 'FlowingLine',
uniforms: {
color: this.color,
speed: this.speed,
percent: this.percent,
gradient: this.gradient
},
source: `
uniform vec4 color;
uniform float speed;
uniform float percent;
uniform float gradient;
czm_material czm_getMaterial(czm_materialInput materialInput) {
czm_material material = czm_getDefaultMaterial(materialInput);
vec2 st = materialInput.st;
float t = fract(czm_frameNumber * speed / 1000.0);
t *= (1.0 + percent);
float alpha = smoothstep(t - percent, t, st.s) * step(-t, -st.s);
alpha += gradient;
material.diffuse = color.rgb;
material.alpha = alpha * color.a;
return material;
}
`
}
});
}
}
// 使用
const flowingMaterial = new FlowingLineMaterial({
color: Cesium.Color.CYAN,
speed: 10.0
});
viewer.entities.add({
polyline: {
positions: Cesium.Cartesian3.fromDegreesArray([116, 39, 117, 40]),
width: 5,
material: flowingMaterial.getMaterial()
}
});
16.4 本章小结
本章介绍了粒子系统与特效:
- 粒子系统:ParticleSystem、发射器类型
- 火焰烟雾:火焰、烟雾效果实现
- 天气效果:雨、雪效果
- 动态线:流动线效果
在下一章中,我们将详细介绍性能优化与最佳实践。
16.5 思考与练习
- 实现爆炸效果。
- 创建喷泉效果。
- 开发雾效天气。
- 实现光束扫描效果。
- 创建轨迹拖尾效果。

浙公网安备 33010602011771号