数字孪生大屏必看:Cesium 3D 模型选中交互,3 种高亮效果拿来就用!
接前文,3D模型加载到页面以后肯定要执行各种各样的操作,模型在大屏上的主要作用是执行相应的建筑物交互。
问题
这里需要注意3D模型的加载仍然存在一些问题。
首先是如果你使用的GLTF文件,在某些特殊情况下可能导致模型的网格加载异常,会出现无法选中的情况。
这一点我目前没发现有什么太好的解决方案,所以这里采用GLB文件规避掉了这个问题。
![]()
如果你手里只有GLTF文件,可以考虑使用 Blender 进行一下转换。
另外模型本身离地高度都是 0 的话可能存在无法选中的问题,所以这里建议背景设置离地高度为 -0.5,普通模型正常为 0。
还有就是模型选中以后的显示问题。
解决方案
模型无法选中和选择错误的问题通过两个方案进行规避,一个是height离地高度,一个是pickable拾取。
首先设置背景的离地高度为 -0.5,普通可以选中的模型离地高度为 0。
![]()
另外设置一下 pickPriority拾取优先级 和 pickable是否可拾取。
最后就是设置模型的选中效果,这里我简单写了三种效果给大家选择,可以自行决定。
实际代码
模型添加的时候增加拾取优先级参数:
const buildingEntity = viewer.entities.add({
id: options.id, // 唯一ID,点击交互时识别核心
name: options.properties.name || options.id, // 建筑名称(可选)
position: position,
orientation: orientation, // 控制模型朝向
pickPriority: options.pickPriority, // (核心)添加拾取优先级
pickable: options.pickable, // (核心)允许拾取
model: {
uri: options.modelUrl, // glTF/glb 模型路径
scale: options.scale || 1.0, // 保证模型真实比例(建模时单位为米)
minimumPixelSize: 0, // 取消最小像素限制,模型随地图缩放正常变化
maximumScale: 20000, // 最大缩放限制
runAnimations: false, // 静态建筑关闭动画(节省性能)
clampToGround: true, // 贴地(自动适配地形高度,可选)
},
properties: options.properties || {}, // 绑定自定义属性(如状态接口)
});
这里的参数其实在模型选择那里可以再增加一层判断。
模型选中方法主要有三种:
// 1. 轮廓线方案
/**
* 选中指定模型
* @param {Cesium.Entity} entity 要选中的模型实体
* @param {Function} onSelect 选中回调(如展示状态弹窗)
* @param {Function} onUnselect 取消选中回调(用于先取消之前的选中)
*/
const selectModel = (entity, onSelect, onUnselect) => {
// 取消之前的选中状态(包括回调执行)
if (selectedEntity) {
unselectModel(onUnselect);
}
// 校验是否为模型实体
if (!entity || !entity.model) {
console.warn('❌ 选中的不是模型实体');
return;
}
// 标记为当前选中实体
selectedEntity = entity;
// 轮廓线高亮(更醒目,性能略高,需 Cesium 1.90+)
entity.model.outlineColor = Cesium.Color.RED;
entity.model.outlineWidth = 2;
entity.model.outline = true;
// 执行选中回调(绑定业务逻辑)
if (typeof onSelect === 'function') {
onSelect(entity);
}
};
如果没有特殊要求,轮廓线方案其实非常简单实用。
// 2. 颜色高亮,修改模型材质
originalModelMaterial = entity.model.color || Cesium.Color.WHITE.clone();
entity.model.color = Cesium.Color.fromCssColorString('#fb0528').withAlpha(0.8);
// 强制刷新
viewer.scene.requestRender();
这里需要注意,修改模型材质一定要执行强制刷新。
// 3. 模型遮罩效果
viewer.entities.add({
position: entity.position,
orientation: entity.orientation,
model: {
uri: entity.model.uri, // 复用同一个模型文件
scale: 0.35, // 稍微大一点
color: Cesium.Color.fromCssColorString('#409EFF').withAlpha(0.5), // 半透明蓝
silhouetteColor: Cesium.Color.BLUE, // 可选:配合轮廓
silhouetteSize: 2.0
}
});
这种效果也非常不错,复用模型文件稍大一号,让他完美的遮住原始模型,给出一个透明色作为材质,显得很有科技感。
总结
模型设计的时候推荐大家优先使用 GLB 格式替代 GLTF 规避网格加载异常问题,
另外通过pickPriority(拾取优先级)和pickable(是否可拾取)参数,从逻辑层面控制模型的交互规则,彻底解决 点错模型、点不到模型 的问题。
后续增加相关图标的单击和操作,实现小型设备的交互。