Cesium WebGL 三维地下空间可视化实战指南:4 步让地表"看穿",露出地下结构
【免费下载链接】cesiumAn open-source JavaScript library for world-class 3D globes and maps :earth_americas:项目地址: https://gitcode.com/GitHub_Trending/ce/cesium
想在一场地铁规划会或地质课堂上,把地表之下的管线、隧道和分层结构摆到所有人面前——2D 地图做不到,而一个没有真实地理坐标的三维引擎,画出来的"地下"和真实经纬度对不上号。开源的 Cesium 库恰好卡在两者之间:它用 WebGL 渲染一颗真实 WGS84 的地球,你既可以把地表透明度调低,又能让相机潜入地下,实现 WebGL 三维地下空间可视化,而不需要自己拼凑坐标系。
能力速览:它对地下场景做了什么
在动手之前,先说清楚它替你解决了什么:
- 真实坐标系打底:地下模型与地表共享同一套 WGS84 坐标,管线埋在哪条经线下,它就出现在哪里,不用手动换算。
- 地表可以"调暗曝光":
Globe实例上的translucency对象负责降低地表不透明度,支持整球生效,也可以只圈一个矩形区域生效。 - 相机能下潜:关掉碰撞检测后,视点可以穿过地表进入地下自由漫游,配合自动保留的地表背面,从内侧往外看也是完整的。
- 3D Tiles 承载大体量数据:城市级地下设施、点云、BIM 模型都可以按 3D Tiles 流式分块加载,而不是一次性塞进显存。
适合谁?做地质分层展示、城市地下管网管理、隧道施工协同、灾害推演的团队,都能直接套这套流程。
原理拆解:透明地表的 3 个关键点
调低地表曝光:translucency 如何"抠"掉地表
把地表变透明的原理,类似拍照时调低曝光——不是把地表删掉,而是降低它的不透明度,让后面的东西透出来。Cesium 里这件事由globe.translucency对象接管:它先决定"要不要透明"(enabled),再决定"透明多少"(frontFaceAlpha,取值 0 到 1),还能用一个矩形限制"在哪里透明"(rectangle)。
矩形掩码的好处在于对比:左侧正常地表,右侧半透明区域,一眼就能看出地下结构和地面的对应关系。
地下结构怎么表达:从椭球到 3D Tiles
地下内容从简到繁有三档可选:
- 基本图元:用
viewer.entities.add加一个椭球、盒子或墙体,适合"地核、地幔、管线走向"这类示意性结构,代码量最小。 - glTF/GLB 模型:把精细的地下设施(泵站、变电站)做成三维模型加载进来,支持贴图和动画。
- 3D Tiles 瓦片集:城市级的地下空间数据,按空间分块、按视距裁剪,相机靠近哪块才加载哪块,是处理大规模场景的主力。
如果同一种小构件(阀门、支架)要铺几千个,别逐个建实体——用几何实例化,一份几何描述配多份变换矩阵,绘制调用直接省掉一个数量级。
相机入地:关掉一个开关的事
默认情况下,拖拽时相机会被地形"弹回来",这是ScreenSpaceCameraController的碰撞检测在工作。地下漫游只需要把它关掉,一行代码的事。而更妙的是:当相机真正位于地下、或者透明化已开启时,Cesium 会自动保留地表的背面渲染,所以你从地心往外看,依然能看到完整的球体轮廓,而不是黑屏。
上手搭建:4 步跑通第一个地下 demo
第 1 步:克隆仓库并启动开发服务
git clone https://gitcode.com/GitHub_Trending/ce/cesium cd cesium && npm install npm start浏览器打开本地服务地址,你会看到一个可交互的地球沙盒页面。
第 2 步:初始化 Viewer 并允许相机入地
这两行代码解决"相机能进地下"的前置问题:
const viewer = new Cesium.Viewer("cesiumContainer", { orderIndependentTranslucency: false, }); // 允许相机穿过地表 viewer.scene.screenSpaceCameraController.enableCollisionDetection = false;改完后往下拖视角,相机不再被地表弹回,而是直接沉进去。
第 3 步:3 行让地表变透明
下面这段代码只对指定矩形区域生效,其余地方保持正常,方便你做前后对比:
const globe = viewer.scene.globe; globe.showGroundAtmosphere = false; globe.baseColor = Cesium.Color.TRANSPARENT; globe.translucency.enabled = true; globe.translucency.frontFaceAlpha = 0.25; globe.translucency.rectangle = Cesium.Rectangle.fromDegrees(-120, 0, -30, 45);渲染一帧后,矩形内的地表变成半透明"磨砂玻璃",遮挡感大幅减弱。
第 4 步:添加地下椭球结构
用一个居中的椭球模拟"地核",位置直接写地球中心,坐标自动落到地心:
viewer.entities.add({ position: Cesium.Cartesian3.ZERO, ellipsoid: { radii: new Cesium.Cartesian3(3450000, 3450000, 3450000), material: Cesium.Color.ORANGE, }, });此时把相机飞进地下再拉远,你会看到橙色椭球悬浮在透明的地球内部——第一个地下可视化 demo 就跑通了。官方示例目录在 packages/sandcastle/gallery/globe-interior/,它额外演示了地核、外核、地幔三层切换,值得对照读一遍。
效果进阶:4 个让画面更像地下的手段
加一层雾,把深度感做出来
地下环境最缺的是"远近参考物",雾正好补这个位。它按距离衰减画面亮度,越深的结构越暗,空间层次立刻有了:
viewer.scene.fog.enabled = true; viewer.scene.fog.density = 0.0002; viewer.scene.fog.color = Cesium.Color.BLACK;density从 0.0001 往上调,直到远处结构开始"没入"黑暗即可。调雾效果的完整参数面板可参考示例 packages/sandcastle/gallery/fog/。
用 undergroundColor 做距离渐变
Globe上的undergroundColor负责渲染地表"内侧"的颜色,默认是黑色。配合undergroundColorAlphaByDistance(一个近大远小的渐变标量),可以让相机贴近地表时看到真实地形、拉远后过渡为深色背景,比硬切一个颜色自然得多。相关实现就在 packages/engine/Source/Scene/Globe.js。
光照往地下场景靠
默认的光照是"太阳在天上",相机下潜后整个地下世界偏暗。打开globe.enableLighting并调整光源方向,或者干脆给地下区域配一盏随相机走的灯,模型的凹凸和边缘才看得见。光照与阴影的调参示例在 packages/sandcastle/gallery/lighting/。
大体量数据交给 3D Tiles 分级
地下数据动辄上千个构件,正确姿势是离线转成 3D Tiles 瓦片集:空间上分块、精度上分档,Cesium 按视锥和屏幕误差自动决定加载哪块、加载多精。再配合视锥剔除,只有当前视口里的结构参与绘制,帧率才能稳住。数据组织和加载逻辑的源码入口在 packages/engine/Source/Scene/。
避坑笔记:相机入地前先看这 3 个
现象:透明开了,地表还是挡得严严实实
原因:translucency只调低地形表面本身的不透明度,底图图层是独立绘制在地表之上的,海面、陆地影像纹丝不动,照样挡住视线。
处理:用底图图层的colorToAlpha把特定颜色"抠"成透明(比如把海洋蓝抠掉),或直接把该图层alpha调低,让影像和地形一起变透。
现象:相机贴着地表就停,死活进不去
原因:碰撞检测默认开着,控制器认为"钻进地形"是非法移动,会把你顶回表面。
处理:设enableCollisionDetection = false。代价是相机可能钻进实体建筑内部,生产环境建议在出地表后自动恢复检测。
现象:相机在地下,看到的地球背面是黑的
原因:背面保留渲染只在"相机位于地下"或"透明化已启用"时生效。如果你的相机高度仍在地形之上(地形起伏比椭球高),系统认为你还没进地下。
处理:用globe.getHeight(camera.positionCartographic)核实地形实际高度,把相机真正压到该值以下,或直接启用translucency兜底。
对坐标仍拿不准时,用DebugModelMatrixPrimitive在模型处画出 XYZ 轴,哪根轴歪了一眼就能看出来,这类调试工具说明见 Documentation/Contributors/DocumentationGuide/。
你可以现在就去试的 4 件事
- 打开官方内置示例 packages/sandcastle/gallery/globe-interior/,把
frontFaceAlpha从 0.25 改到 0.05,感受透明度差一档的观感变化。 - 在矩形掩码基础上叠加
colorToAlpha,实现"只抠海洋、保留陆地"的半透明地球,对比效果更接近真实剖切。 - 把地核椭球换成自己的 GLB 管线模型试试,模型矩阵对不上时先用调试轴原语定位。
- 通读 packages/engine/Source/Scene/Globe.js 中
translucency与undergroundColor两段的 JSDoc,把参数默认值和生效条件摸清楚。
Cesium 把"看穿地球"拆成了透明化、坐标对齐、相机漫游三件独立的事,每件都有现成 API。按本文顺序把 4 步 demo 跑通后,剩下的就是把你的地下数据换成 3D Tiles——原理不变,只是内容更真实。
【免费下载链接】cesiumAn open-source JavaScript library for world-class 3D globes and maps :earth_americas:项目地址: https://gitcode.com/GitHub_Trending/ce/cesium
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考