cesiumjs-models-particles

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

CesiumJS Models, glTF & Particle Effects

CesiumJS 模型、glTF 与粒子效果

Version baseline: CesiumJS v1.143.
版本基线:CesiumJS v1.143.

Quick Reference

快速参考

ClassPurpose
Model
Low-level glTF/GLB primitive; positioned via
modelMatrix
ModelAnimation
Active animation instance on a model
ModelAnimationCollection
Collection at
model.activeAnimations
ModelNode
Named node with modifiable transform
ModelFeature
Per-feature styling/picking for feature-ID models
EdgeDisplayMode
Controls draft glTF edge-visibility rendering on Model/Cesium3DTileset
ParticleSystem
Billboard-based particle manager (fire, smoke, rain)
Particle
Single particle with position, velocity, life
ParticleBurst
Scheduled burst of particles
BoxEmitter
/
CircleEmitter
Emit within box volume / flat disk
ConeEmitter
/
SphereEmitter
Emit from cone tip / within sphere
The Entity API exposes models through
ModelGraphics
(see cesiumjs-entities). The Primitive API uses
Model.fromGltfAsync
for full control over
modelMatrix
, animations, and node transforms.

用途
Model
底层glTF/GLB图元;通过
modelMatrix
定位
ModelAnimation
模型上的活跃动画实例
ModelAnimationCollection
存储于
model.activeAnimations
的动画集合
ModelNode
可修改变换的命名节点
ModelFeature
支持Feature-ID模型的逐要素样式设置/拾取
EdgeDisplayMode
控制Model/Cesium3DTileset的草案glTF边缘可见性渲染
ParticleSystem
基于公告板的粒子管理器(用于火焰、烟雾、雨水等效果)
Particle
包含位置、速度、生命周期的单个粒子
ParticleBurst
按计划触发的粒子爆发效果
BoxEmitter
/
CircleEmitter
在立方体空间/平面圆盘内发射粒子
ConeEmitter
/
SphereEmitter
从圆锥尖端/球体内部发射粒子
Entity API 通过
ModelGraphics
暴露模型(详见cesiumjs-entities)。Primitive API 使用
Model.fromGltfAsync
以完全控制
modelMatrix
、动画和节点变换。

Loading a glTF/GLB Model

加载glTF/GLB模型

Always use the async factory -- never call the constructor directly.
js
import { Model, Cartesian3, Transforms, HeadingPitchRoll, Math as CesiumMath } from "cesium";

const model = await Model.fromGltfAsync({ url: "path/to/model.glb" });
viewer.scene.primitives.add(model);
CesiumJS 1.143 decodes
KHR_meshopt_compression
automatically, including the v1 attribute codec and
COLOR
filter. Do not import a decoder or private loader helper. When loading compressed glTF, CAD-style lines/points/edges, or constant-LOD textures, read REFERENCE.md for the complete support and authoring matrix. The same loader behavior applies to glTF content inside 3D Tiles.
务必使用异步工厂方法——切勿直接调用构造函数。
js
import { Model, Cartesian3, Transforms, HeadingPitchRoll, Math as CesiumMath } from "cesium";

const model = await Model.fromGltfAsync({ url: "path/to/model.glb" });
viewer.scene.primitives.add(model);
CesiumJS 1.143会自动解码
KHR_meshopt_compression
,包括v1属性编解码器和
COLOR
过滤器。无需导入解码器或私有加载器工具。加载压缩glTF、CAD风格线/点/边或恒定LOD纹理时,请阅读REFERENCE.md获取完整的支持和创作矩阵。相同的加载器行为适用于3D Tiles内的glTF内容。

Positioned Model with Heading

设置朝向的定位模型

js
const position = Cartesian3.fromDegrees(-123.074, 44.050, 5000);
const hpr = new HeadingPitchRoll(CesiumMath.toRadians(135), 0, 0);

const model = await Model.fromGltfAsync({
  url: "CesiumAir.glb",
  modelMatrix: Transforms.headingPitchRollToFixedFrame(position, hpr),
  minimumPixelSize: 128,  // never smaller than 128 px on screen
  maximumScale: 20000,    // cap for minimumPixelSize enlargement
  scale: 2.0,             // uniform scale multiplier
});
viewer.scene.primitives.add(model);
js
const position = Cartesian3.fromDegrees(-123.074, 44.050, 5000);
const hpr = new HeadingPitchRoll(CesiumMath.toRadians(135), 0, 0);

const model = await Model.fromGltfAsync({
  url: "CesiumAir.glb",
  modelMatrix: Transforms.headingPitchRollToFixedFrame(position, hpr),
  minimumPixelSize: 128,  // 屏幕上永不小于128像素
  maximumScale: 20000,    // 限制minimumPixelSize的放大上限
  scale: 2.0,             // 统一缩放倍数
});
viewer.scene.primitives.add(model);

Key
Model.fromGltfAsync
Options

Model.fromGltfAsync
关键选项

OptionTypeDefault
url
string|Resource
required
modelMatrix
Matrix4
IDENTITY
scale
number
1.0
minimumPixelSize
number
0.0
maximumScale
number
--
show
boolean
true
color
/
colorBlendMode
/
colorBlendAmount
Color
/
ColorBlendMode
/
number
-- /
HIGHLIGHT
/
0.5
edgeDisplayMode
EdgeDisplayMode
SURFACES_ONLY
silhouetteColor
/
silhouetteSize
Color
/
number
RED
/
0.0
shadows
ShadowMode
ENABLED
heightReference
HeightReference
NONE
customShader
CustomShader
--
id
any
--
allowPicking
boolean
true

选项类型默认值
url
string|Resource
必填
modelMatrix
Matrix4
IDENTITY
scale
number
1.0
minimumPixelSize
number
0.0
maximumScale
number
--
show
boolean
true
color
/
colorBlendMode
/
colorBlendAmount
Color
/
ColorBlendMode
/
number
-- /
HIGHLIGHT
/
0.5
edgeDisplayMode
EdgeDisplayMode
SURFACES_ONLY
silhouetteColor
/
silhouetteSize
Color
/
number
RED
/
0.0
shadows
ShadowMode
ENABLED
heightReference
HeightReference
NONE
customShader
CustomShader
--
id
any
--
allowPicking
boolean
true

Readiness and Lifecycle

就绪状态与生命周期

fromGltfAsync
resolves once glTF JSON is parsed, but WebGL resources may still load. Wait for
readyEvent
before accessing animations, nodes, or
boundingSphere
.
js
const model = await Model.fromGltfAsync({ url: "robot.glb" });
viewer.scene.primitives.add(model);

model.readyEvent.addEventListener(() => {
  console.log("Bounding sphere:", model.boundingSphere);
});
js
// Synchronous check
if (model.ready) { const bs = model.boundingSphere; }

fromGltfAsync
在glTF JSON解析完成后即返回,但WebGL资源可能仍在加载中。访问动画、节点或
boundingSphere
前,请等待
readyEvent
触发。
js
const model = await Model.fromGltfAsync({ url: "robot.glb" });
viewer.scene.primitives.add(model);

model.readyEvent.addEventListener(() => {
  console.log("包围球:", model.boundingSphere);
});
js
// 同步检查
if (model.ready) { const bs = model.boundingSphere; }

Animations

动画

Managed through
model.activeAnimations
(
ModelAnimationCollection
).
通过
model.activeAnimations
ModelAnimationCollection
)管理动画。

Play by Name / Play All

按名称播放/播放全部

js
model.readyEvent.addEventListener(() => {
  // Single animation
  const anim = model.activeAnimations.add({
    name: "Walk",                          // glTF animation name
    loop: Cesium.ModelAnimationLoop.REPEAT, // NONE | REPEAT | MIRRORED_REPEAT
    multiplier: 1.0,                       // playback speed (must be > 0)
  });
  anim.start.addEventListener((m, a) => console.log(`Started: ${a.name}`));

  // Or play all animations at once
  model.activeAnimations.addAll({
    loop: Cesium.ModelAnimationLoop.REPEAT,
    multiplier: 0.5,
  });
});
Additional
add
options:
index
,
reverse
,
startTime
,
stopTime
,
delay
,
removeOnStop
,
animationTime
(custom time callback).
js
model.readyEvent.addEventListener(() => {
  // 单个动画
  const anim = model.activeAnimations.add({
    name: "Walk",                          // glTF动画名称
    loop: Cesium.ModelAnimationLoop.REPEAT, // NONE | REPEAT | MIRRORED_REPEAT
    multiplier: 1.0,                       // 播放速度(必须>0)
  });
  anim.start.addEventListener((m, a) => console.log(`已启动: ${a.name}`));

  // 或一次性播放所有动画
  model.activeAnimations.addAll({
    loop: Cesium.ModelAnimationLoop.REPEAT,
    multiplier: 0.5,
  });
});
add
方法的额外选项:
index
reverse
startTime
stopTime
delay
removeOnStop
animationTime
(自定义时间回调)。

Animation Events

动画事件

js
animation.start.addEventListener((model, animation) => { });
animation.update.addEventListener((model, animation, time) => { });
animation.stop.addEventListener((model, animation) => { });
// Collection-level
model.activeAnimations.animationAdded.addEventListener((model, anim) => { });
js
model.activeAnimations.remove(animation); // remove one
model.activeAnimations.removeAll();        // remove all

js
animation.start.addEventListener((model, animation) => { });
animation.update.addEventListener((model, animation, time) => { });
animation.stop.addEventListener((model, animation) => { });
// 集合级事件
model.activeAnimations.animationAdded.addEventListener((model, anim) => { });
js
model.activeAnimations.remove(animation); // 移除单个动画
model.activeAnimations.removeAll();        // 移除所有动画

Model Nodes

模型节点

Override named node transforms for procedural animation (e.g., turret rotation).
js
model.readyEvent.addEventListener(() => {
  const node = model.getNode("Turret");
  node.matrix = Cesium.Matrix4.fromScale(
    new Cesium.Cartesian3(5.0, 1.0, 1.0), node.matrix
  );
});
Properties:
name
(read-only),
id
(read-only index),
show
(boolean),
matrix
(Matrix4 -- set to
undefined
to restore original and re-enable glTF animations).

覆盖命名节点的变换,实现程序化动画(如炮塔旋转)。
js
model.readyEvent.addEventListener(() => {
  const node = model.getNode("Turret");
  node.matrix = Cesium.Matrix4.fromScale(
    new Cesium.Cartesian3(5.0, 1.0, 1.0), node.matrix
  );
});
属性:
name
(只读)、
id
(只读索引)、
show
(布尔值)、
matrix
(Matrix4——设置为
undefined
可恢复原始值并重新启用glTF动画)。

Coloring, Silhouettes, and Feature Picking

着色、轮廓与要素拾取

js
// Tint + silhouette
model.color = Cesium.Color.RED.withAlpha(0.5);
model.colorBlendMode = Cesium.ColorBlendMode.MIX;
model.colorBlendAmount = 0.5;
model.silhouetteColor = Cesium.Color.YELLOW;
model.silhouetteSize = 2.0;
js
// 着色+轮廓
model.color = Cesium.Color.RED.withAlpha(0.5);
model.colorBlendMode = Cesium.ColorBlendMode.MIX;
model.colorBlendAmount = 0.5;
model.silhouetteColor = Cesium.Color.YELLOW;
model.silhouetteSize = 2.0;

Edge Display Mode (Experimental, 1.142+)

边缘显示模式(实验性,1.142+)

For glTF assets using the draft
EXT_mesh_primitive_edge_visibility
extension,
EdgeDisplayMode
controls whether extension-provided edges are hidden, composited over surfaces, or rendered alone. Models without the extension are unaffected.
js
import { EdgeDisplayMode, Model } from "cesium";

const model = await Model.fromGltfAsync({
  url: "/models/cad-part.glb",
  edgeDisplayMode: EdgeDisplayMode.SURFACES_AND_EDGES,
});
viewer.scene.primitives.add(model);

model.edgeDisplayMode = EdgeDisplayMode.EDGES_ONLY;       // CAD-style wireframe
model.edgeDisplayMode = EdgeDisplayMode.SURFACES_ONLY;    // default
When a glTF has
EXT_mesh_features
or
EXT_structural_metadata
, picking returns a
ModelFeature
:
js
const handler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas);
handler.setInputAction((movement) => {
  const picked = viewer.scene.pick(movement.endPosition);
  if (picked instanceof Cesium.ModelFeature) {
    picked.getPropertyIds().forEach((name) => {
      console.log(`${name}: ${picked.getProperty(name)}`);
    });
    picked.color = Cesium.Color.YELLOW;
  }
}, Cesium.ScreenSpaceEventType.MOUSE_MOVE);

对于使用草案
EXT_mesh_primitive_edge_visibility
扩展的glTF资源,
EdgeDisplayMode
控制扩展提供的边缘是隐藏、叠加在表面上还是单独渲染。不支持该扩展的模型不受影响。
js
import { EdgeDisplayMode, Model } from "cesium";

const model = await Model.fromGltfAsync({
  url: "/models/cad-part.glb",
  edgeDisplayMode: EdgeDisplayMode.SURFACES_AND_EDGES,
});
viewer.scene.primitives.add(model);

model.edgeDisplayMode = EdgeDisplayMode.EDGES_ONLY;       // CAD风格线框
model.edgeDisplayMode = EdgeDisplayMode.SURFACES_ONLY;    // 默认值
当glTF包含
EXT_mesh_features
EXT_structural_metadata
时,拾取操作会返回
ModelFeature
js
const handler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas);
handler.setInputAction((movement) => {
  const picked = viewer.scene.pick(movement.endPosition);
  if (picked instanceof Cesium.ModelFeature) {
    picked.getPropertyIds().forEach((name) => {
      console.log(`${name}: ${picked.getProperty(name)}`);
    });
    picked.color = Cesium.Color.YELLOW;
  }
}, Cesium.ScreenSpaceEventType.MOUSE_MOVE);

Height Reference

高度参考

js
// Primitive API -- scene is required for height reference
const model = await Model.fromGltfAsync({
  url: "truck.glb",
  heightReference: Cesium.HeightReference.CLAMP_TO_GROUND,
  scene: viewer.scene,
});

// Entity API
viewer.entities.add({
  position: Cartesian3.fromDegrees(-75.59, 40.03),
  model: { uri: "truck.glb", heightReference: Cesium.HeightReference.CLAMP_TO_GROUND },
});
Values:
NONE
,
CLAMP_TO_GROUND
,
RELATIVE_TO_GROUND
,
CLAMP_TO_TERRAIN
,
RELATIVE_TO_TERRAIN
,
CLAMP_TO_3D_TILE
,
RELATIVE_TO_3D_TILE
.

js
// Primitive API -- 高度参考需要场景实例
const model = await Model.fromGltfAsync({
  url: "truck.glb",
  heightReference: Cesium.HeightReference.CLAMP_TO_GROUND,
  scene: viewer.scene,
});

// Entity API
viewer.entities.add({
  position: Cartesian3.fromDegrees(-75.59, 40.03),
  model: { uri: "truck.glb", heightReference: Cesium.HeightReference.CLAMP_TO_GROUND },
});
可选值:
NONE
CLAMP_TO_GROUND
RELATIVE_TO_GROUND
CLAMP_TO_TERRAIN
RELATIVE_TO_TERRAIN
CLAMP_TO_3D_TILE
RELATIVE_TO_3D_TILE

Particle Systems

粒子系统

ParticleSystem
renders billboard-based effects. Position with
modelMatrix
(world) and
emitterModelMatrix
(local offset).
ParticleSystem
渲染基于公告板的特效。通过
modelMatrix
(世界空间)和
emitterModelMatrix
(本地偏移)定位。

Smoke Trail

烟雾轨迹

js
import { ParticleSystem, CircleEmitter, Color, Cartesian2, Transforms, Cartesian3 } from "cesium";

const smokeSystem = new ParticleSystem({
  image: "smoke.png",
  startColor: Color.LIGHTGRAY.withAlpha(0.7),
  endColor: Color.WHITE.withAlpha(0.0),
  startScale: 1.0,
  endScale: 5.0,
  emissionRate: 10,
  minimumSpeed: 1.0,
  maximumSpeed: 4.0,
  minimumParticleLife: 1.2,
  maximumParticleLife: 3.0,
  imageSize: new Cartesian2(25, 25), // pixel size
  emitter: new CircleEmitter(2.0),   // radius in meters
  modelMatrix: Transforms.eastNorthUpToFixedFrame(Cartesian3.fromDegrees(-75.157, 39.978)),
  lifetime: 16.0,
  loop: true,
});
viewer.scene.primitives.add(smokeSystem);
js
import { ParticleSystem, CircleEmitter, Color, Cartesian2, Transforms, Cartesian3 } from "cesium";

const smokeSystem = new ParticleSystem({
  image: "smoke.png",
  startColor: Color.LIGHTGRAY.withAlpha(0.7),
  endColor: Color.WHITE.withAlpha(0.0),
  startScale: 1.0,
  endScale: 5.0,
  emissionRate: 10,
  minimumSpeed: 1.0,
  maximumSpeed: 4.0,
  minimumParticleLife: 1.2,
  maximumParticleLife: 3.0,
  imageSize: new Cartesian2(25, 25), // 像素尺寸
  emitter: new CircleEmitter(2.0),   // 半径(米)
  modelMatrix: Transforms.eastNorthUpToFixedFrame(Cartesian3.fromDegrees(-75.157, 39.978)),
  lifetime: 16.0,
  loop: true,
});
viewer.scene.primitives.add(smokeSystem);

Emitter Types

发射器类型

js
import { BoxEmitter, CircleEmitter, ConeEmitter, SphereEmitter } from "cesium";

new BoxEmitter(new Cesium.Cartesian3(10, 10, 10));  // 3D box, velocity outward
new CircleEmitter(2.0);                              // flat disk, velocity +Z
new ConeEmitter(Cesium.Math.toRadians(30));          // cone tip, velocity toward base
new SphereEmitter(5.0);                              // sphere, velocity radiates out
js
import { BoxEmitter, CircleEmitter, ConeEmitter, SphereEmitter } from "cesium";

new BoxEmitter(new Cesium.Cartesian3(10, 10, 10));  // 3D立方体,向外发射
new CircleEmitter(2.0);                              // 平面圆盘,沿+Z方向发射
new ConeEmitter(Cesium.Math.toRadians(30));          // 圆锥尖端,朝向底部发射
new SphereEmitter(5.0);                              // 球体,向外辐射发射

Particle Bursts

粒子爆发

js
const firework = new ParticleSystem({
  image: getParticleCanvas(),
  startColor: Color.RED,
  endColor: Color.RED.withAlpha(0.0),
  particleLife: 1.0,
  speed: 100.0,
  imageSize: new Cartesian2(7, 7),
  emissionRate: 0,  // bursts only
  emitter: new SphereEmitter(0.1),
  bursts: [
    new Cesium.ParticleBurst({ time: 0.0, minimum: 100, maximum: 200 }),
    new Cesium.ParticleBurst({ time: 2.0, minimum: 50, maximum: 100 }),
    new Cesium.ParticleBurst({ time: 4.0, minimum: 200, maximum: 300 }),
  ],
  lifetime: 6.0,
  loop: false,
  modelMatrix: Transforms.eastNorthUpToFixedFrame(Cartesian3.fromDegrees(-75.597, 40.038)),
});
viewer.scene.primitives.add(firework);
js
const firework = new ParticleSystem({
  image: getParticleCanvas(),
  startColor: Color.RED,
  endColor: Color.RED.withAlpha(0.0),
  particleLife: 1.0,
  speed: 100.0,
  imageSize: new Cartesian2(7, 7),
  emissionRate: 0,  // 仅使用爆发效果
  emitter: new SphereEmitter(0.1),
  bursts: [
    new Cesium.ParticleBurst({ time: 0.0, minimum: 100, maximum: 200 }),
    new Cesium.ParticleBurst({ time: 2.0, minimum: 50, maximum: 100 }),
    new Cesium.ParticleBurst({ time: 4.0, minimum: 200, maximum: 300 }),
  ],
  lifetime: 6.0,
  loop: false,
  modelMatrix: Transforms.eastNorthUpToFixedFrame(Cartesian3.fromDegrees(-75.597, 40.038)),
});
viewer.scene.primitives.add(firework);

Update Callback (Gravity / Wind)

更新回调(重力/风力)

The
updateCallback
runs per-particle per-frame for forces like gravity.
js
const gravityScratch = new Cesium.Cartesian3();
function applyGravity(particle, dt) {
  Cesium.Cartesian3.normalize(particle.position, gravityScratch);
  Cesium.Cartesian3.multiplyByScalar(gravityScratch, -9.8 * dt, gravityScratch);
  particle.velocity = Cesium.Cartesian3.add(particle.velocity, gravityScratch, particle.velocity);
}

const system = new ParticleSystem({
  image: "smoke.png",
  emissionRate: 20,
  emitter: new ConeEmitter(Cesium.Math.toRadians(45)),
  updateCallback: applyGravity,
  modelMatrix: Transforms.eastNorthUpToFixedFrame(Cartesian3.fromDegrees(-105, 40, 1000)),
});
viewer.scene.primitives.add(system);

updateCallback
会在每帧对每个粒子执行,用于模拟重力等外力。
js
const gravityScratch = new Cesium.Cartesian3();
function applyGravity(particle, dt) {
  Cesium.Cartesian3.normalize(particle.position, gravityScratch);
  Cesium.Cartesian3.multiplyByScalar(gravityScratch, -9.8 * dt, gravityScratch);
  particle.velocity = Cesium.Cartesian3.add(particle.velocity, gravityScratch, particle.velocity);
}

const system = new ParticleSystem({
  image: "smoke.png",
  emissionRate: 20,
  emitter: new ConeEmitter(Cesium.Math.toRadians(45)),
  updateCallback: applyGravity,
  modelMatrix: Transforms.eastNorthUpToFixedFrame(Cartesian3.fromDegrees(-105, 40, 1000)),
});
viewer.scene.primitives.add(system);

Attaching Particles to a Moving Model

将粒子附加到移动模型

Sync
modelMatrix
each frame via
scene.preUpdate
. Use
emitterModelMatrix
for a local offset (e.g., exhaust pipe).
js
const entity = viewer.entities.add({
  position: sampledPosition,
  orientation: new Cesium.VelocityOrientationProperty(sampledPosition),
  model: { uri: "truck.glb", minimumPixelSize: 64 },
});

// Local offset to exhaust pipe
const trs = new Cesium.TranslationRotationScale();
trs.translation = new Cesium.Cartesian3(-4.0, 0.0, 1.4);
const emitterModelMatrix = Cesium.Matrix4.fromTranslationRotationScale(trs, new Cesium.Matrix4());

const exhaust = new ParticleSystem({
  image: "smoke.png",
  startColor: Color.GRAY.withAlpha(0.7),
  endColor: Color.TRANSPARENT,
  emissionRate: 8,
  speed: 2.0,
  particleLife: 1.5,
  imageSize: new Cartesian2(20, 20),
  emitter: new CircleEmitter(0.5),
  emitterModelMatrix: emitterModelMatrix,
});
viewer.scene.primitives.add(exhaust);

viewer.scene.preUpdate.addEventListener((scene, time) => {
  exhaust.modelMatrix = entity.computeModelMatrix(time, new Cesium.Matrix4());
});

通过
scene.preUpdate
逐帧同步
modelMatrix
。使用
emitterModelMatrix
设置本地偏移(如排气管位置)。
js
const entity = viewer.entities.add({
  position: sampledPosition,
  orientation: new Cesium.VelocityOrientationProperty(sampledPosition),
  model: { uri: "truck.glb", minimumPixelSize: 64 },
});

// 排气管的本地偏移
const trs = new Cesium.TranslationRotationScale();
trs.translation = new Cesium.Cartesian3(-4.0, 0.0, 1.4);
const emitterModelMatrix = Cesium.Matrix4.fromTranslationRotationScale(trs, new Cesium.Matrix4());

const exhaust = new ParticleSystem({
  image: "smoke.png",
  startColor: Color.GRAY.withAlpha(0.7),
  endColor: Color.TRANSPARENT,
  emissionRate: 8,
  speed: 2.0,
  particleLife: 1.5,
  imageSize: new Cartesian2(20, 20),
  emitter: new CircleEmitter(0.5),
  emitterModelMatrix: emitterModelMatrix,
});
viewer.scene.primitives.add(exhaust);

viewer.scene.preUpdate.addEventListener((scene, time) => {
  exhaust.modelMatrix = entity.computeModelMatrix(time, new Cesium.Matrix4());
});

Canvas-Based Particle Images

基于Canvas的粒子图像

Generate particle textures dynamically instead of loading image files.
js
function createCircleImage() {
  const c = document.createElement("canvas");
  c.width = c.height = 20;
  const ctx = c.getContext("2d");
  ctx.beginPath();
  ctx.arc(10, 10, 10, 0, Math.PI * 2);
  ctx.fillStyle = "#fff";
  ctx.fill();
  return c;
}

// Pass canvas directly as image
new ParticleSystem({ image: createCircleImage(), /* ...other options */ });

动态生成粒子纹理,而非加载图像文件。
js
function createCircleImage() {
  const c = document.createElement("canvas");
  c.width = c.height = 20;
  const ctx = c.getContext("2d");
  ctx.beginPath();
  ctx.arc(10, 10, 10, 0, Math.PI * 2);
  ctx.fillStyle = "#fff";
  ctx.fill();
  return c;
}

// 直接传入canvas作为图像
new ParticleSystem({ image: createCircleImage(), /* ...其他选项 */ });

Entity API Model (ModelGraphics)

Entity API 模型(ModelGraphics)

For simpler use cases, add a model through the Entity API (see cesiumjs-entities for full coverage).
js
const entity = viewer.entities.add({
  name: "Aircraft",
  position: Cartesian3.fromDegrees(-123.074, 44.050, 5000),
  orientation: Cesium.Transforms.headingPitchRollQuaternion(
    Cartesian3.fromDegrees(-123.074, 44.050, 5000),
    new Cesium.HeadingPitchRoll(Cesium.Math.toRadians(135), 0, 0)
  ),
  model: {
    uri: "CesiumAir.glb",
    minimumPixelSize: 128,
    maximumScale: 20000,
    silhouetteColor: Color.RED,
    silhouetteSize: 2.0,
  },
});
viewer.trackedEntity = entity;

对于简单场景,可通过Entity API添加模型(完整说明详见cesiumjs-entities)。
js
const entity = viewer.entities.add({
  name: "飞行器",
  position: Cartesian3.fromDegrees(-123.074, 44.050, 5000),
  orientation: Cesium.Transforms.headingPitchRollQuaternion(
    Cartesian3.fromDegrees(-123.074, 44.050, 5000),
    new Cesium.HeadingPitchRoll(Cesium.Math.toRadians(135), 0, 0)
  ),
  model: {
    uri: "CesiumAir.glb",
    minimumPixelSize: 128,
    maximumScale: 20000,
    silhouetteColor: Color.RED,
    silhouetteSize: 2.0,
  },
});
viewer.trackedEntity = entity;

GPM Extension (NGA_gpm_local)

GPM扩展(NGA_gpm_local)

CesiumJS experimentally supports the NGA Geospatial Positioning Metadata glTF extension. Types:
AnchorPointDirect
,
AnchorPointIndirect
,
CorrelationGroup
,
GltfGpmLocal
,
Spdcf
. Parsed automatically when loading a glTF with
NGA_gpm_local
-- the API is experimental and subject to change.

CesiumJS实验性支持NGA地理空间定位元数据glTF扩展。类型包括:
AnchorPointDirect
AnchorPointIndirect
CorrelationGroup
GltfGpmLocal
Spdcf
。加载包含
NGA_gpm_local
的glTF时会自动解析——该API为实验性,可能随时变更。

Performance Tips

性能优化技巧

  1. Use
    .glb
    over
    .gltf
    -- binary format avoids extra HTTP requests and is smaller on the wire.
  2. Enable Draco compression (
    KHR_draco_mesh_compression
    ) for 80-90% smaller meshes.
  3. Use KTX2/Basis textures (
    KHR_texture_basisu
    ) for GPU-compressed textures; keep dimensions power-of-two.
  4. Set
    minimumPixelSize
    carefully
    -- large values force enlargement of distant models, increasing draw cost.
  5. Limit silhouettes -- extra rendering pass per silhouetted model; more than 256 may cause stencil artifacts.
  6. Reuse scratch
    Matrix4
    objects
    -- avoid allocating every frame when syncing particle systems to moving entities.
  7. Keep emission rates low -- each particle is a billboard; rates above 200/s can hurt frame rate. Use bursts for short effects.
  8. Prefer pixel-sized particles (
    sizeInMeters: false
    , default) -- meter-sized particles are expensive at close range.
  9. Set finite
    lifetime
    on particle systems --
    Number.MAX_VALUE
    (default) prevents pool cleanup.
  10. Disable picking for decorations --
    allowPicking: false
    saves GPU memory on models that need no interaction.
  11. Destroy when done --
    viewer.scene.primitives.remove(model)
    then
    model.destroy()
    to free WebGL resources.

  1. 优先使用
    .glb
    而非
    .gltf
    ——二进制格式避免额外HTTP请求,传输体积更小。
  2. 启用Draco压缩
    KHR_draco_mesh_compression
    )可使网格体积缩小80-90%。
  3. 使用KTX2/Basis纹理
    KHR_texture_basisu
    )实现GPU压缩纹理;保持尺寸为2的幂次。
  4. 谨慎设置
    minimumPixelSize
    ——过大的值会强制放大远处模型,增加绘制成本。
  5. 限制轮廓数量——每个带轮廓的模型会增加一次渲染通道;超过256个可能导致模板缓存 artifacts。
  6. 复用临时
    Matrix4
    对象
    ——同步粒子系统与移动实体时,避免每帧分配新对象。
  7. 降低发射速率——每个粒子都是一个公告板;速率超过200/秒会影响帧率。短效果使用爆发模式。
  8. 优先使用像素尺寸粒子
    sizeInMeters: false
    ,默认值)——米级粒子在近距离时性能开销大。
  9. 为粒子系统设置有限
    lifetime
    ——默认值
    Number.MAX_VALUE
    会阻止对象池清理。
  10. 禁用装饰性模型的拾取——
    allowPicking: false
    可节省无需交互的模型的GPU内存。
  11. 使用完毕后销毁——调用
    viewer.scene.primitives.remove(model)
    后再执行
    model.destroy()
    以释放WebGL资源。

See Also

相关链接

  • cesiumjs-custom-shader -- GLSL authoring for
    Model.customShader
    (struct reference, feature IDs, metadata, vertex displacement)
  • cesiumjs-materials-shaders -- ImageBasedLighting, post-processing stages for models
  • cesiumjs-entities -- Entity API ModelGraphics, data sources, time-dynamic properties
  • cesiumjs-3d-tiles -- Cesium3DTileset (uses Model internally), clipping, styling
  • cesiumjs-custom-shader——为
    Model.customShader
    编写GLSL代码(结构体参考、要素ID、元数据、顶点位移)
  • cesiumjs-materials-shaders——模型的基于图像的光照、后处理阶段
  • cesiumjs-entities——Entity API的ModelGraphics、数据源、时间动态属性
  • cesiumjs-3d-tiles——Cesium3DTileset(内部使用Model)、裁剪、样式设置