上一节课,我们初步认识了 Cesium 的图元(Primitive),当时只放了一个几何体。
其实,一个 Primitive 可以同时塞进多个几何实例(GeometryInstance) 。
这样做的好处很明显:
-
一次合并,一次绘制调用,性能更高;
-
每个实例还能单独改颜色、显隐,灵活性不减。
今天就把"多实例"和"动态改色"两件事一次讲透。
一、一个图元,多个实例
需求:把"矩形"和"椭球"一起塞进同一个 Primitive,一次搞定。
-
先保留上节的矩形实例(instance)。
-
再新建一个椭球实例,给它的 radii、位置、颜色都安排上。
-
最后把两个实例用数组形式丢进 Primitive。
代码如下,每一步都写了注释,照着抄就能跑。
/* 1. 椭球几何实例:长半轴 5 km,短半轴 5 km,高 10 km */
const ellipsoidInstance = new Cesium.GeometryInstance({
geometry: new Cesium.EllipsoidGeometry({
radii: new Cesium.Cartesian3(5000.0, 5000.0, 10000.0), // 三轴半径
vertexFormat: Cesium.VertexFormat.POSITION_AND_NORMAL // 只要位置和法线,省内存
}),
/* 2. 把椭球放到东经 114°、北纬 23.03883°、离地 5 km 的位置 */
modelMatrix: Cesium.Matrix4.multiplyByTranslation(
Cesium.Transforms.eastNorthUpToFixedFrame(
Cesium.Cartesian3.fromDegrees(114, 23.03883)
),
new Cesium.Cartesian3(0.0, 0.0, 5000.0),
new Cesium.Matrix4()
),
id: 'ellipsoid', // 给实例起个名字,后面改色要用
attributes: {
color: Cesium.ColorGeometryInstanceAttribute.fromColor(
Cesium.Color.RED) // 初始红色
}
});
/* 3. 把两个实例一起塞进同一个图元 */
const rectPrimitive = new Cesium.Primitive({
geometryInstances: [instance, ellipsoidInstance], // 数组形式,想塞几个塞几个
appearance: appearance // 仍用之前的 PerInstanceColorAppearance
});
/* 4. 加入场景 */
viewer.scene.primitives.add(rectPrimitive);
刷新页面,你会看到:
-
绿色矩形------上一节留下的;
-
红色椭球------刚加的;
-
它们同属一个 Primitive,却保持各自颜色、各自位置。

二、运行中随时改颜色
想让椭球每 2 秒随机换个颜色?
只要抓住"实例属性"这把钥匙,一行代码就能改,不需要重新创建 Primitive。
套路分两步:
-
用
getGeometryInstanceAttributes('id')拿到对应实例的属性包; -
直接改属性包里的
color,Cesium 下一帧就会自动生效。/* 每 2 秒给椭球随机换一个半透明颜色 */
setInterval(() => {
rectPrimitive
.getGeometryInstanceAttributes('ellipsoid') // 通过 id 找到椭球
.color = Cesium.ColorGeometryInstanceAttribute.toValue(
Cesium.Color.fromRandom({ alpha: 0.5 }) // 随机颜色,固定 0.5 透明度
);
}, 2000);
注意:
-
改色只改"属性",不动"几何",所以性能开销极小。
-
如果想改矩形颜色,同理给它也起个 id,再用同样套路即可。
三、小结
-
一个 Primitive ≈ 一个"合并批次",里面可放任意数量实例。
-
实例各自带 id、颜色、矩阵,后期想改就改,灵活又高效。
-
今天只演示了"改颜色",其实改显隐、改矩阵、换材质也一样,套路都是"先拿属性包,再改字段"。
把这套组合拳吃透,后面做海量建筑、批量模型、动态高亮,就能既流畅又省事。