经纬志
首页 / Cesium / 教程

3D Tiles 是什么,怎么用

先看结论

倾斜摄影、BIM、点云这些数据动辄几个 GB,一次性加载不可能。 3D Tiles 把它们切成小块,按视角远近决定加载哪一级细节。

最后验证 2026-11-03 · CesiumJS 1.121 · 3D Tiles 1.1 · 更新 2026-10-27 · 引用本文

它解决的是数据量问题

一个城市级的倾斜摄影模型,原始数据往往在几十 GB。浏览器不可能全部下载。 3D Tiles 的做法是把模型按空间切成瓦片树:根节点是最粗糙的整体轮廓, 越往下越精细。相机离得远就只取上层,拉近了才继续往下载。

这套机制和二维地图的瓦片金字塔是同一个思路,区别在于三维瓦片里的内容是 三角形网格、点云或者实例化模型,而不是图片。

tileset.json 长什么样

一个 3D Tiles 数据集入口是一个 tileset.json, 描述瓦片的层级关系、包围盒和每块的内容地址。

{
  "asset": { "version": "1.1" },
  "geometricError": 500,
  "root": {
    "boundingVolume": {
      "region": [-1.3197, 0.6989, -1.3196, 0.6990, 0, 400]
    },
    "geometricError": 200,
    "refine": "ADD",
    "content": { "uri": "tiles/0/0/0.b3dm" },
    "children": [
      {
        "boundingVolume": { "box": [0, 0, 0, 100, 0, 0, 0, 100, 0, 0, 0, 50] },
        "geometricError": 50,
        "content": { "uri": "tiles/1/0/0.b3dm" }
      }
    ]
  }
}

geometricError 是这个节点「简化程度」的度量,单位是米。 屏幕上的误差超过阈值时,Cesium 才会去加载子节点。 refine 决定子节点是替换(REPLACE)还是叠加(ADD)父节点。

字段作用
boundingVolume包围盒,用于视锥剔除和误差计算
geometricError该层级简化的最大误差,决定何时细分
refineREPLACE 或 ADD,决定父子叠加方式
content.uri瓦片内容,常见 b3dm、pnts、glb

加载一个 tileset

1.104 之后推荐用异步工厂方法,而不是直接 new Cesium3DTileset:

var tileset = await Cesium.Cesium3DTileset.fromUrl(
  'https://your-host/path/tileset.json',
  {
    maximumScreenSpaceError: 16,   // 数值越小越精细,也越吃性能
    maximumMemoryUsage: 512,       // 缓存上限,单位 MB
    skipLevelOfDetail: false       // 开启可加快首屏,但可能闪
  }
);

viewer.scene.primitives.add(tileset);
await viewer.zoomTo(tileset);

老写法 new Cesium.Cesium3DTileset({ url }) 仍然可用, 但它返回的是对象而非 Promise,拿不到加载完成的时机, 想在加载后做定位就得监听 tileset.readyPromise,比较别扭。

加载不出来时按这个顺序查

1. 控制台没有任何请求

URL 写错了,或者跨域被拦截。打开网络面板看 tileset.json 是否 404。 静态资源服务器要允许跨域,否则瓦片取不到。

2. JSON 加载成功,但模型不出现

多半是坐标系问题。tileset.json 如果没有 transform 字段, 内容会被当成以地心为原点的坐标,模型可能跑到地球内部或者体积为零。 用 tileset.root.transform 指定放置位置,或者确认建模时已经带上了正确的变换矩阵。

3. 模型出来了,但贴地穿模

没有地形时,模型按椭球面定位;有地形时,地面比椭球面高出几十到几百米。 开启 tileset.heightReference 或者在场景里加地形,两者要一致。

4. 首屏卡住十几秒

瓦片总量太大或网络带宽不足。先把 maximumScreenSpaceError 调大(比如从 16 调到 32), 减少同时请求的瓦片数;再用 maximumMemoryUsage 限制缓存,避免内存一路上涨。

和 glTF 的关系

单个模型用 glTF(或二进制的 glb)就够了。3D Tiles 是外层容器, 负责切片、层级和调度;瓦片内容本身可以是 b3dm(包一个 glTF)、 pnts(点云)或直接的 glb。做单个精细设备模型时用 glTF, 做城市级大范围模型时才需要切成 3D Tiles。

引用本文

经纬志(2026)。《3D Tiles 是什么,怎么用》。https://www.jingweizhi.com/cesium/tutorial/tileset-basics.html(访问日期 2026-11-03)。