前言用户要自己上传GLB 文件看效果不经过打包目录一个 GLB 已经放好了要在它上面再叠一层GLB比如先放主体建筑再放设备层 / 管线层点击某个模型要能变半透明 / 恢复不透明做内部透视、叠加查看。这三件事本篇一次性解决全部基于 Entity 原生 Cesium不引第三方。一、核心 API 认知先搞懂再写码表格需求用到的 API说明本地上传URL.createObjectURL(file)把本地文件转成可加载的 blob 地址加载 GLBentities.add({ model: { uri } })Entity 方式uri 可以是 blob 地址叠加第二层相同经纬度 model.height/heading 微调多层模型同位置叠放拾取scene.pick(windowPosition)拿到点击的 Entity控制透明entity.model.color Color.WHITE.withAlpha(a)alpha1 不透明越小越透明高亮选中color.getResult()保留原色与透明互斥⚠️ 关键点控制 GLB 透明度改的不是model.opacity而是model.color。设置 color 后模型整体会乘以该颜色用withAlpha()就能实现半透明。模型自带材质会被乘掉颜色所以要么整体透明、要么先保留原色再改 alpha。二、第一步本地文件上传 GLB2.1 上传 input 组件template label classupload-btn 选择GLB文件 input typefile accept.glb,.gltf changeonUploadModel hidden / /label /template2.2 处理上传并加载import * as Cesium from cesium // 当前已加载的模型引用 const modelEntities [] /** * 本地上传GLB并加载到指定坐标 * param {Event} e input change事件 */ const onUploadModel (e) { const file e.target.files[0] if (!file) return // 本地文件转blob地址Cesium可以直接加载 const url URL.createObjectURL(file) const entity addModel(url, 108.94, 34.27, 0, { name: file.name, scale: 1 }) modelEntities.push(entity) // 选完重置input方便重复上传同一文件 e.target.value console.log(已加载模型, file.name) } /** * 添加模型封装uri支持线上地址或本地blob */ const addModel (uri, lng, lat, height 0, opts {}) { return viewer.entities.add({ position: Cesium.Cartesian3.fromDegrees(lng, lat, height), model: { uri, scale: opts.scale ?? 1, minimumPixelSize: opts.minimumPixelSize ?? 32, maximumScale: opts.maximumScale ?? 20000, runAnimations: opts.runAnimations ?? true, clampToGround: opts.clampToGround ?? false }, name: opts.name ?? 模型, // 存一个自定义属性方便后面识别“可点击控制” _clickable: true }) }注意Entity 的model.uri支持 blob 地址所以本地上传不需要后端。用完后建议URL.revokeObjectURL(url)释放内存在删除实体时做。三、第二步在 GLB 上叠加另一层 GLB核心思想两个模型使用相同经纬度靠 height或 heading 偏转区分层次。/** * 在指定位置叠加第二层GLB用于分层建模 * param {string} uri * param {number} lng,lat 基准坐标 * param {number} baseHeight 第一层所在高度 * param {number} layerHeight 第二层相对抬升高度 */ const addLayerModel (uri, lng, lat, baseHeight 0, layerHeight 5, opts {}) { // 第二层在baseHeight基础上抬升形成叠加效果 return addModel(uri, lng, lat, baseHeight layerHeight, { name: opts.name ?? 上层模型, scale: opts.scale ?? 1, // 可稍微偏转角度错开看清叠放 heading: opts.heading ?? 0 }) } // 使用示例先放主体再放设备层 const baseEntity addModel(/models/building.glb, 108.94, 34.27, 0, { name: 主体 }) const topEntity addLayerModel(/models/equipment.glb, 108.94, 34.27, 0, 8, { name: 设备层 })若模型本身带了平移position高度叠加可能不明显此时改用模型内部 origin 平移更可控但简单场景height叠加够用。四、第三步点击拾取 控制透明度核心4.1 开启点击拾取监听let selectedEntity null // 当前选中/透明的模型 const setupPickHandler () { // 监听鼠标左键点击 const handler new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas) handler.setInputAction((movement) { const picked viewer.scene.pick(movement.position) if (!Cesium.defined(picked) || !Cesium.defined(picked.id)) { // 点空了清除上一个高亮 resetTransparency() return } const entity picked.id // 只处理我们标记为可点击的模型 if (entity?._clickable) { toggleTransparency(entity) } }, Cesium.ScreenSpaceEventType.LEFT_CLICK) }4.2 透明度控制核心函数let transparentEntity null // 当前处于半透明的模型 /** * 切换模型透明度半透明 ⇄ 不透明 * param {Cesium.Entity} entity */ const toggleTransparency (entity) { // 先恢复之前透明的那个 if (transparentEntity transparentEntity ! entity) { setOpacity(transparentEntity, 1) } if (transparentEntity entity) { // 再次点击同一个恢复不透明 setOpacity(entity, 1) transparentEntity null console.log(已恢复不透明) } else { // 设为半透明 setOpacity(entity, 0.3) transparentEntity entity console.log(已半透明 0.3) } } /** * 设置模型透明度 * param {Cesium.Entity} entity * param {number} alpha 0~11为不透明 */ const setOpacity (entity, alpha) { if (!entity?.model) return // 保留原色模型默认白色直接乘alpha entity.model.color Cesium.Color.WHITE.withAlpha(alpha) // 关键半透明后开启深度测试穿透否则会被其他模型挡住看不见 entity.model.disableDepthTestDistance Number.POSITIVE_INFINITY } /** * 一键恢复所有模型不透明 */ const resetTransparency () { if (transparentEntity) { setOpacity(transparentEntity, 1) transparentEntity null } }4.3 半透明 保留原色的进阶写法如果想让模型半透明时还保留大致颜色不要直接用纯白const setOpacityKeepColor (entity, alpha) { // 先取模型当前基色这里用白色alpha即可或记录原color const baseColor entity._originColor ?? Cesium.Color.WHITE entity._originColor baseColor entity.model.color baseColor.withAlpha(alpha) entity.model.disableDepthTestDistance Number.POSITIVE_INFINITY }说明disableDepthTestDistance设为无穷大半透明模型才不会因为深度测试被后层模型遮挡到看不见这是透明控制最常见的坑。五、完整可运行示例合并版template CesiumMap refmapRef / div classpanel label classbtn 上传GLB input typefile accept.glb,.gltf changeonUpload hidden / /label button classbtn clickonAddLayer叠加一层GLB/button button classbtn clickonReset全部恢复不透明/button p classtip点击场景中的模型可切换半透明/p /div /template script setup import { ref, onMounted, onBeforeUnmount } from vue import * as Cesium from cesium import CesiumMap from ./CesiumMap.vue const mapRef ref(null) let viewer null let handler null let modelEntities [] let transparentEntity null onMounted(() { viewer mapRef.value.viewer setupPickHandler() }) onBeforeUnmount(() { handler?.destroy() viewer?.destroy() }) // ---------- 加载模型 ---------- const addModel (uri, lng, lat, height 0, opts {}) { const entity viewer.entities.add({ position: Cesium.Cartesian3.fromDegrees(lng, lat, height), model: { uri, scale: opts.scale ?? 1, minimumPixelSize: 32, maximumScale: 20000, runAnimations: true, clampToGround: false }, name: opts.name ?? 模型, _clickable: true }) modelEntities.push(entity) return entity } // ---------- 上传 ---------- const onUpload (e) { const file e.target.files[0] if (!file) return const url URL.createObjectURL(file) addModel(url, 108.94, 34.27, 0, { name: file.name }) e.target.value } // ---------- 叠加一层 ---------- const onAddLayer () { addModel(/models/equipment.glb, 108.94, 34.27, 8, { name: 设备层, scale: 0.5 }) } // ---------- 点击拾取 ---------- const setupPickHandler () { handler new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas) handler.setInputAction((movement) { const picked viewer.scene.pick(movement.position) if (!Cesium.defined(picked) || !Cesium.defined(picked.id)) { resetTransparency() return } if (picked.id?._clickable) toggleTransparency(picked.id) }, Cesium.ScreenSpaceEventType.LEFT_CLICK) } // ---------- 透明度控制 ---------- const setOpacity (entity, alpha) { if (!entity?.model) return entity.model.color Cesium.Color.WHITE.withAlpha(alpha) entity.model.disableDepthTestDistance Number.POSITIVE_INFINITY } const toggleTransparency (entity) { if (transparentEntity transparentEntity ! entity) { setOpacity(transparentEntity, 1) } if (transparentEntity entity) { setOpacity(entity, 1) transparentEntity null } else { setOpacity(entity, 0.3) transparentEntity entity } } const onReset () { modelEntities.forEach((en) setOpacity(en, 1)) transparentEntity null } /script六、踩坑记录重点透明不生效改的不是model.opacity必须用model.color.withAlpha()半透明模型看不见被其他模型深度测试遮挡加disableDepthTestDistance Infinity上传后加载失败blob 地址要URL.createObjectURL跨域场景优先转成 DataURL 或走后端叠加两层看不到第二层height 不够或者两个模型 scale 太大互相重叠检查scale和高度重复点击混乱维护一个transparentEntity单例引用先恢复旧的再切换模型自带动画被 color 影响半透明对动画材质如闪动可能异常必要时用Primitive方案销毁释放内存删除模型时记得URL.revokeObjectURL(url)viewer.entities.remove(entity)七、扩展方向博客结尾点击模型弹出属性面板名称、坐标、所属图层多选模型批量调透明度 / 隐藏Primitive 方式加载高性能模型海量模型拖拽、旋转、贴地贴合分层模型联动点击某层其余半透明总结这篇覆盖了三个高频能力本地上传 GLB、GLB 上叠 GLB、点击控制透明度。核心就一句 —— 透明度改model.color.withAlpha()穿透加disableDepthTestDistance。配合前面几篇的useCesiumGis封装日常数字孪生 / 设备模型叠加场景基本够用。
企业数字化 ERP 产品动态
相关推荐
脑科学前沿 | 聚焦:脑结构图谱与脑功能解码(大样本影像、记忆重放、脑深部核团、BCI 解码) 脑科学前沿 | 今日速览 2026.10.10 今日收录:10篇| 聚焦:脑结构图谱与脑功能解码(大样本影像、记忆重放、脑深部核团、BCI 解码) 情报周期:2026.10.07 – 2026.10.10(72小时) 今日推荐… · 2026/11/3 19:24:22
【Java】线程概念 1.Thread 类中 start() 和 run() 的区别方法本身区别(1)start()a)是启动线程的方法,属于Thread的原生方法。b)调用后会向操作系统申请创建一个新的独立线程,由 JVM 自动调用该线程的run()方法。c࿰… · 2026/11/3 19:24:22
全网都在扒“作者是谁“,没人关心它干了啥:百度这个开源OCR,被一段八卦盖住了真本事 全网都在扒"作者是谁",没人关心它干了啥:百度这个开源OCR,被一段八卦盖住了真本事 【免费下载链接】Unlimited-OCR-2 项目地址: https://ai.gitcode.com/hf_mirrors/baidu/Unlimited-OCR-2
今年6月,百度在GitHu… · 2026/11/3 19:23:22
前端图片上传0KB问题解析与解决方案 1. 前端图片上传0KB问题深度解析最近在VueElementUI项目中处理图片上传时,遇到了一个典型问题:部分用户上传的图片在服务器端显示为0KB的破损文件。这个问题看似简单,实则涉及前端文件处理机制、浏览器API使用规范、前后端交互协议等多个技术… · 2026/11/3 20:02:38
用ping二分法快速定位MTU故障:原理、参数与上线自检清单 1. MTU配错到底会怎样:从三个真实症状说起MTU 这个词听起来很基础,但真正在现网里遇到它的时候,往往已经是半夜被告警叫醒的状态了。我先说三个我自己碰到过的场景,你对号入座一下,看看是不是眼熟。第一个场景… · 2026/11/3 20:02:38
Ansible Playbook进阶实战:生产级自动化技巧 1. Ansible Playbook进阶实战:从基础到生产级自动化(开头部分)
第一次接触Ansible Playbook时,我被它简洁的YAML语法和声明式编程模式深深吸引。但真正在生产环境大规模使用时,才发现那些基础教程里没讲的细节才是决定… · 2026/11/3 20:02:38
SURPAC地质建模规范:数据表、ID编号与文件命名避坑指南 简介:这份文档面向地质勘探、矿产资源评价及环境监测领域的建模初学者与技术人员,系统梳理了 SURPAC 软件建模的核心知识点,帮助读者建立从数据组织到解译建模的完整认知框架。压缩包内为 1 个 docx 文件,约 17KB,内容… · 2026/11/3 20:02:38
RTDE 实时数据交换:125Hz 上限、两阶段设计与避坑指南 简介:面向UR(优遨)机器人开发者与自动化集成工程师的RTDE接口技术手册,聚焦如何通过标准TCP/IP连接将外部程序与UR控制器同步,同时不破坏控制器实时属性,适用于现场总线驱动交互、机器人I/O操作与轨迹状态绘… · 2026/11/3 20:02:38
Firefox中文语言包安装与失效排查:版本匹配与多平台配置 帮别人装浏览器这种事我干过不少回,最常被追问的一句话就是——为什么装完之后界面还是英文的?Firefox 中文语言包的安装方法看着简单,真动手的时候却总在几个地方卡住:语言包版本差一位装不上、xpi 文件拖进去没反应、装完重启还… · 2026/11/3 20:01:37
双极步进电机控制实战:DRV8818PWPR与PIC18F86K22驱动调试 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/2 13:10:28
STM32F207ZG + DRV8818PWPR 步进电机驱动实战解析 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/3 6:04:24
DRV8818PWPR+dsPIC30F4013工业级双极步进电机控制方案 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/3 5:52:46
STM32F411RE与MAX14431实现SPI隔离:工业现场抗共模干扰实战 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/3 1:01:59
ESP32+大模型AI硬件开发:从Demo到产品的8个工程问题 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/3 1:01:59
基于MAX14431BAEE+与PIC18F85J10的SPI隔离方案设计与实践 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/3 1:01:59
双极步进电机控制实战:DRV8818PWPR与PIC18F86K22驱动调试 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/2 13:10:28
STM32F207ZG + DRV8818PWPR 步进电机驱动实战解析 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/3 6:04:24
DRV8818PWPR+dsPIC30F4013工业级双极步进电机控制方案 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/3 5:52:46