倾斜摄影成果交付时通常是 OSGB 分块数据加一份 metadata.xml。在桌面软件里流畅的数据,转成 3D Tiles 放进浏览器后出现首屏慢、漫游卡、内存持续上涨,原因几乎都能在瓦片树参数里找到。
加载机制:屏幕空间误差决定加载哪一层 #
3D Tiles 用瓦片树组织数据,每个瓦片带一个 geometricError(几何误差,单位米),表示“如果不加载它的子瓦片,渲染结果的误差有多大”。客户端把它换算成屏幕上的像素误差:
SSE = geometricError × screenHeight ÷ (2 × distance × tan(fovy ÷ 2))当 SSE 大于阈值时,客户端继续细化,加载子瓦片。CesiumJS 中这个阈值是 maximumScreenSpaceError,默认 16 像素。
由此可以得到两个直接结论:
- geometricError 设得过大,远处的瓦片也会被判定为“误差太大”,导致远景加载高精度数据,首屏慢、请求多;
- 设得过小,近处迟迟不细化,画面模糊。
合理的做法是让各层 geometricError 随层级递减,与该层实际的几何简化程度对应,而不是统一写一个值。
单瓦片体积与几何简化 #
OSGB 原始分块的层级与 Web 端加载需求往往不一致。转换时应重新组织瓦片树:
- 粗层级做网格抽稀,保留轮廓;近景层级保留原始精度;
- 单瓦片体积过大时拆分,过碎时合并。经验上把单瓦片控制在数百 KB 到 1–2 MB 之间,请求数和单次传输量比较均衡;
- 几何数据可使用 Draco(KHR_draco_mesh_compression)压缩,显著减小传输体积,代价是客户端解码耗时。
纹理:体积和内存的大头 #
倾斜摄影的纹理通常占数据量的大部分,也是浏览器内存上涨、移动端崩溃的主因。
| 手段 | 作用 | 注意 |
|---|---|---|
| 限制单张纹理尺寸 | 降低显存占用 | 近景层级保留足够分辨率 |
| 远景层级降分辨率 | 与几何简化同步 | 按层级逐级减半较常见 |
| KTX2 / Basis Universal 压缩纹理 | GPU 可直接使用压缩格式,显存占用远低于解压后的 PNG / JPEG | 需要客户端支持转码 |
| 合并小纹理 | 减少请求与绘制调用 | 避免图集过大 |
OSGB 的坐标:SRS 与原点 #
metadata.xml 中的 SRS 指明投影坐标系(例如 EPSG:4549,即 CGCS2000 / 3-degree Gauss-Kruger CM 120E),SRSOrigin 是局部坐标原点。模型顶点坐标是相对原点的局部坐标。
转换时最常见的错误:
- 只读取了原点、忽略 SRS,导致模型落在错误的投影带上,偏移数十到数百公里;
- 中央经线判断错误,模型整体旋转或偏移;
- 高程按正常高写入,而三维引擎使用椭球高,模型整体浮空或下沉。高程异常在国内多数地区为数米到数十米,详见坐标系与高程基准常见问题。
模型看起来“加载很慢”,有时其实是相机落在了错误位置。先做落位检查,再调性能。
传输与部署 #
- 服务端开启 HTTP/2 或 HTTP/3 与 gzip / Brotli 压缩,对
.b3dm、.glb、tileset.json设置长缓存; - 内网项目把三维数据与应用部署在同一网段,避免跨网关转发;
- 大场景按区域拆分多个 tileset,按需加载。
验收指标 #
| 指标 | 测量方法 |
|---|---|
| 首屏时间 | 打开页面到主体模型可见,固定相机位置测 3 次取平均 |
| 漫游帧率 | 固定路径漫游,记录平均与最低帧率 |
| 峰值内存 | 浏览器任务管理器中标签页的最大内存 |
| 数据体积比 | 转换后总体积 / 原始 OSGB 体积 |
| 落位误差 | 与影像、矢量控制点套合的平面与高程偏差 |
建议在项目开始时选一小片区域做样例转换,用这组指标确定参数,再批量处理全部数据。我们的星火 3D Tiles 模型转换工具支持倾斜摄影与 BIM 的批量转换,管线数据可用星火管网智绘平台生成 3D Tiles,三者可在同一场景中加载。
