这一节,我们钻进3D Tiles的“瓦片世界”——搞懂它如何把全球上亿栋建筑切成一块块小瓦片,按需流式加载,既不让 GPU 爆炸,又能保持画面精细。最后亲手加载一套本地瓦片,再用官方调试工具实时看帧率、看边界、看内存,做到“心中有数”。
一、3D Tiles 是什么?
一句话:海量 3D 地理数据的“流式渲染”规范。
把超大场景(全球建筑、倾斜摄影、点云)切成多级瓦片;
相机离得远 → 加载粗糙块;离得近 → 自动换高清块;
只加载屏幕里看得见的一小部分,显存/CPU 压力骤降。
官方规范仓库:
https://github.com/CesiumGS/3d-tiles/tree/main/specification
(前端无需生成,只需按规范消费数据即可)
二、根 tileset.json:瓦片的“目录树”
每个 3D Tiles 数据集都有一个入口文件tileset.json,作用类似“目录”:
告诉 Cesium 版本号、误差度量、包围盒、子瓦片地址;
后端提前算好几何误差、层级范围,前端拿来即用。
核心字段速览:
| 字段 | 含义 | 前端关注 |
|---|---|---|
geometricError | 几何误差(像素) | 决定“何时显示/隐藏” |
boundingVolume | 包围盒/区域 | 视锥体裁剪依据 |
refine | "REPLACE"或"ADD" | 子瓦片替换还是叠加 |
content.uri | 实际瓦片文件(.b3dm/.glb…) | 真正要加载的模型 |
三、几何误差:越小越精,越大越省
geometricError是“屏幕误差”阈值,值越大 → 瓦片越粗糙 → 离远看才显示;
值越小 → 瓦片越精细 → 放大才出现。
后端通常按“像素”计算,前端只需读懂数字:
240 → 离屏很远就加载;
0 → 必须贴脸才显示。
(不能 <0,只能 ≥0)
四、前端加载:四行代码搞定
/* 1. 新建 tileset 对象 */ const tileset = new Cesium.Cesium3DTileset({ url: "./Assets/city/tileset.json", // 指向根 tileset.json }); /* 2. 扔进场景 */ viewer.scene.primitives.add(tileset); /* 3. 加载完飞过去 */ tileset.readyPromise.then(() => { viewer.zoomTo(tileset); }); /* 4. 开启调试面板(可选) */ viewer.extend(Cesium.viewerCesium3DTilesInspectorMixin);运行后,城市建筑按需出现:拉远 → 块少面粗;拉近 → 细节逐层加载,帧率稳如老狗。
五、调试神器:Cesium3DTilesInspector
面板一键开,常用功能:
Show Stats:实时帧率、显存、加载瓦片数;
Show Bounding Volume:看包围盒,判断裁剪逻辑;
Geometric Error:手动改误差,实时感受“精细-卡顿”平衡;
Freeze Frame:冻结当前帧,抓出多余瓦片。
示例截图:
帧率 59 FPS / 内存 ≈16 MB → 说明误差设置合理,可再调大。
六、性能小贴士
误差别盲目调小,精细≠帧率;
相机高度决定加载量,远视角先给低清块;
同屏瓦片数 > 上限时,优先丢弃误差大的块;
移动端可把
maximumScreenSpaceError从 16 提到 32,帧率立刻+10。
七、小结 & 预告
3D Tiles = 瓦片目录树 + 几何误差 + 按需加载,专治“海量模型”。
前端只需
tileset.json路径,四行代码即可渲染。用 Inspector 看帧率、看包围盒,调误差心里有底。
下节课,我们冲进“珠江新城”,手把手改瓦片样式——换颜色、换高度、夜间发光,让 City 瞬间变 Cyber!