Cesium中1万个实体如何不通过循环批量修改PolylineGlow材质属性
Cesium批量修改10000个线实体发光材质的实现方案
Cesium本身没有内置跳过遍历直接批量修改所有实体材质的API,但可以通过以下两种方案实现接近零开销的材质更新,不需要承担10000次循环的性能负担:
方案1:提前复用共享材质实例(完全不需要遍历,最优方案)
如果你的实体还没初始化,或者可以调整初始化逻辑,直接给所有同规则的线实体复用同一个材质实例即可,后续修改只需要改一次实例属性,所有关联实体会自动同步更新:
// 初始化阶段创建全局共享的发光材质实例 const sharedGlowMaterial = new Cesium.PolylineGlowMaterialProperty({ glowPower: 0.15, color: Cesium.Color.fromCssColorString("rgba(42,92,170, 0.15)") }); // 创建10000个线实体时,全部复用同一个材质实例 for (let i = 0; i < 10000; i++) { viewer.entities.add({ polyline: { positions: [/* 你的线节点坐标 */], material: sharedGlowMaterial // 直接引用共享实例,不要单独新建 } }) } // 需要修改材质时,直接修改共享实例的属性即可,不需要遍历任何实体 sharedGlowMaterial.glowPower = 0.3; sharedGlowMaterial.color = Cesium.Color.fromCssColorString("rgba(255,255,255, 0.15)");
该方案的性能开销和实体数量无关,相当于只修改1个对象的属性,所有实体的渲染效果会自动同步。
方案2:已单独创建材质的优化遍历方案
如果你的实体已经初始化完成,每个实体都单独创建了材质实例,可通过暂停实体事件通知的方式避免遍历过程中的重复渲染,10000个实体的遍历耗时可以忽略:
// 暂停实体集合的事件通知,遍历过程中不会触发中间态渲染 viewer.entities.suspendEvents(); // 遍历修改所有符合条件的材质属性 viewer.entities.values.forEach(entity => { const material = entity.polyline?.material; if (material instanceof Cesium.PolylineGlowMaterialProperty) { material.glowPower = 0.3; material.color = Cesium.Color.fromCssColorString("rgba(255,255,255, 0.15)"); } }) // 恢复事件通知,一次性触发全量渲染更新 viewer.entities.resumeEvents();
注意不要在遍历中每次都新建
PolylineGlowMaterialProperty实例,直接修改原有实例的属性即可,避免产生不必要的GC开销。
内容的提问来源于stack exchange,提问作者selverg
相关产品推荐
相关产品推荐

