通用更新技巧
-
部分属性更新(如颜色):
const attributes = primitive.getGeometryInstanceAttributes(instance); attributes.color = newColorValue; -
完全替换几何体(如位置/形状变化):
- 重新创建
GeometryInstance并赋值给primitive.geometryInstances。
- 重新创建
-
批量更新(多个实例):
const instances = [instance1, instance2]; primitive.geometryInstances = instances; // 一次性更新所有实例
1. Primitive 数据加载
基本步骤:
// 创建几何实例(GeometryInstance)
const instance = new Cesium.GeometryInstance({
geometry: new Cesium.RectangleGeometry({
rectangle: Cesium.Rectangle.fromDegrees(-120.0, 30.0, -100.0, 40.0),
vertexFormat: Cesium.PerInstanceColorAppearance.VERTEX_FORMAT
}),
id: 'dynamicRect', // 唯一标识符(用于后续更新)
attributes: {
color: new Cesium.ColorGeometryInstanceAttribute(1.0, 0.0, 0.0, 1.0) // 红色
}
});
// 创建 Primitive 并添加到场景
const primitive = new Cesium.Primitive({
geometryInstances: instance,
appearance: new Cesium.PerInstanceColorAppearance()
});
viewer.scene.primitives.add(primitive);
支持的数据类型:
- 内置几何:
RectangleGeometry,PolygonGeometry,EllipseGeometry,BoxGeometry,SphereGeometry等 - 自定义几何:通过
Geometry和GeometryAttribute构建 - 3D 模型:使用
Model类(非 Primitive,但可单独加载)
2. 位置信息动态更新
方法 1:直接更新模型矩阵(推荐)
// 获取 Primitive 中的实例属性
const attributes = primitive.getGeometryInstanceAttributes('dynamicRect');
// 创建新位置(示例:移动矩形)
const newRectangle = Cesium.Rectangle.fromDegrees(-110.0, 35.0, -90.0, 45.0);
// 计算新位置的模型矩阵
const modelMatrix = Cesium.Matrix4.fromTranslation(
Cesium.Cartesian3.fromDegrees(-100.0, 35.0, 0), // 中心点
new Cesium.Matrix4()
);
// 更新模型矩阵并标记需要刷新
attributes.modelMatrix = modelMatrix;
attributes.modelMatrix.needsUpdate = true; // 关键步骤!
方法 2:重建 GeometryInstance(简单但性能较低)
// 移除旧 Primitive
viewer.scene.primitives.remove(primitive);
// 创建新实例
const newInstance = new Cesium.GeometryInstance({
geometry: new Cesium.RectangleGeometry({
rectangle: Cesium.Rectangle.fromDegrees(-115.0, 32.0, -95.0, 42.0),
vertexFormat: Cesium.PerInstanceColorAppearance.VERTEX_FORMAT
}),
attributes: {
color: new Cesium.ColorGeometryInstanceAttribute(0.0, 0.0, 1.0, 1.0) // 蓝色
}
});
// 重新创建 Primitive
primitive = new Cesium.Primitive({
geometryInstances: newInstance,
appearance: new Cesium.PerInstanceColorAppearance()
});
viewer.scene.primitives.add(primitive);
3. 动态更新其他属性
更新属性
// 更新颜色
const attributes = pointPrimitive.getGeometryInstanceAttributes(instance);
attributes.color = Cesium.ColorGeometryInstanceAttribute.toValue(Cesium.Color.BLUE);
// 更新位置(需重新创建实例)
primitive.geometryInstances = new Cesium.GeometryInstance({
geometry: new Cesium.PointGeometry({
position: Cesium.Cartesian3.fromDegrees(-75.0, 40.5),
pointSize: 15
}),
attributes: { color: attributes.color } // 保留原颜色
});
修改颜色:
const attributes = primitive.getGeometryInstanceAttributes('dynamicRect');
attributes.color = [0, 1, 0, 1]; // RGBA 绿色
attributes.color.needsUpdate = true;
显示/隐藏:
attributes.show = 0; // 0=隐藏, 1=显示
attributes.show.needsUpdate = true;
4. 性能优化技巧
-
批量更新:对多个实例使用
PrimitiveCollectionconst collection = new Cesium.PrimitiveCollection(); collection.add(primitive1); collection.add(primitive2); // 添加/移除元素 viewer.scene.primitives.add(collection); viewer.scene.primitives.remove(collection);或 批量渲染:将多个几何实例合并到一个
Primitive中。const primitive = new Cesium.Primitive({ geometryInstances: [pointInstance, polylineInstance], // 批量添加 appearance: /* 统一外观 */ }); -
避免频繁更新:静态数据优先使用
GroundPrimitive或Entity。 -
复用 Primitive:优先更新
modelMatrix而非重建 -
使用 WebWorker:复杂计算在后台线程进行
const worker = new Worker('computeWorker.js'); worker.postMessage(positions); worker.onmessage = updatePrimitive; -
按需更新:通过
show属性控制可见性,减少渲染负担 -
销毁对象:
viewer.scene.primitives.remove(primitive);
primitive.destroy(); // 释放内存
- 共享外观提升性能
const sharedAppearance = new Cesium.PerInstanceColorAppearance();
const primitive1 = new Cesium.Primitive({
geometryInstances: [...],
appearance: sharedAppearance
});
const primitive2 = new Cesium.Primitive({
geometryInstances: [...],
appearance: sharedAppearance
});
5. 常见问题解决
-
更新无效? 确认已设置
needsUpdate = true -
闪烁问题? 使用
requestAnimationFrame确保在渲染前完成更新Cesium.requestAnimationFrame(() => { attributes.modelMatrix = updatedMatrix; attributes.modelMatrix.needsUpdate = true; }); -
性能瓶颈? 减少不必要的属性更新,合并几何实例
示例:动态移动矩形
let angle = 0;
function updatePosition() {
angle += 0.02;
// 计算新中心点(圆形轨迹)
const x = -100 + 10 * Math.cos(angle);
const y = 35 + 10 * Math.sin(angle);
const center = Cesium.Cartesian3.fromDegrees(x, y);
// 更新模型矩阵
const attributes = primitive.getGeometryInstanceAttributes('dynamicRect');
attributes.modelMatrix = Cesium.Matrix4.fromTranslation(center, new Cesium.Matrix4());
attributes.modelMatrix.needsUpdate = true;
requestAnimationFrame(updatePosition);
}
updatePosition();
提示:对于复杂场景(如数千个动态对象),考虑使用 CustomShader 或 GeometryUpdater 获得更高性能。
对比 Entity API
| 特性 | Primitive API | Entity API |
|---|---|---|
| 性能 | ⭐⭐⭐⭐ 高(直接控制渲染) | ⭐⭐ 中(通过DataSource抽象) |
| 灵活性 | ⭐⭐⭐⭐⭐ 完全自定义 | ⭐⭐⭐ 声明式,易用 |
| 动态更新复杂度 | ⭐⭐ 需手动管理 | ⭐⭐⭐⭐ 自动更新 |
| 适用场景 | 大量动态图形、自定义Shader、高性能需求 | 常规实体、数据绑定 |
通过 Primitive API 可直接控制底层渲染细节,适合高性能场景,但需要手动管理更新。对于简单应用,推荐使用更易用的 Entity API。