共计 1875 个字符,预计需要花费 5 分钟才能阅读完成。
1. 3DTiles 与 GLB 的数据结构差异
3DTiles 是专为大规模 3D 地理空间数据设计的开放格式,采用分块(tile)和细节层次(LOD)结构,而 GLB 则是 glTF 的二进制版本,适合描述单个 3D 模型。两者核心差异在于:

- 组织方式 :3DTiles 通过空间索引树管理海量数据,GLB 是单体模型文件
- 坐标系 :3DTiles 使用 WGS84 地理坐标系,GLB 通常采用局部直角坐标系
- 纹理处理 :3DTiles 支持多分辨率纹理金字塔,GLB 需手动处理纹理压缩
2. 技术选型:Cesium 与 Three.js 协同方案
- Cesium 的优势
- 原生支持 3DTiles 加载与空间查询
- 内置地理坐标转换工具
-
完善的相机控制与地形适配
-
Three.js 的强项
- 轻量级 WebGL 渲染
- 成熟的 GLB 导出管线
- 丰富的后期处理效果
实际采用两者结合方案:用 Cesium 解析 3DTiles,通过中间格式转换后,由 Three.js 生成 GLB。
3. 核心实现步骤
3.1 数据解析阶段
// Cesium 加载 3DTiles 示例
const tileset = new Cesium.Cesium3DTileset({
url: './data/tileset.json',
dynamicScreenSpaceError: true
});
viewer.scene.primitives.add(tileset);
关键操作:
- 使用 Cesium3DTileset 加载器解析空间索引
- 监听 TILE_LOAD 事件获取几何数据
- 提取顶点、法线、UV 等基础属性
3.2 坐标转换
地理坐标转局部坐标的三步法:
- 将 WGS84 转 ECEF(地心坐标系)
- 计算相对于场景中心的偏移向量
- 应用矩阵变换到模型空间
function wgs84ToLocal(position, center) {
const cartesian = Cesium.Cartesian3.fromDegrees(
position.longitude,
position.latitude,
position.height
);
return Cesium.Cartesian3.subtract(cartesian, center, new Cesium.Cartesian3());
}
3.3 GLB 生成优化
- 几何压缩 :使用 Draco 压缩算法
- 纹理优化 :生成 BC7 压缩纹理
- 实例化处理 :对重复建筑模型进行实例化
4. 完整代码示例
// 核心转换流程
async function convertToGLB(tileset) {const threeObjects = [];
// 1. 遍历所有可见瓦片
tileset.tileVisible.addEventListener((tile) => {
const content = tile.content;
// 2. 提取几何数据
const geometries = parseCesiumGeometry(content);
// 3. 创建 Three.js 网格
const mesh = new THREE.Mesh(new THREE.BufferGeometry().fromDirectGeometry(geometries),
new THREE.MeshStandardMaterial());
threeObjects.push(mesh);
});
// 4. 导出 GLB
const exporter = new GLTFExporter();
return await exporter.parseAsync(threeObjects, {
binary: true,
dracoOptions: {compressionLevel: 7}
});
}
5. 性能优化实测
测试数据集:1km²城市区域(约 5 万栋建筑)
| 优化措施 | 内存占用 (MB) | 帧率 (FPS) |
|---|---|---|
| 原始数据 | 2100 | 12 |
| Draco 压缩后 | 870 | 28 |
| 实例化 + 纹理优化 | 420 | 45 |
关键优化技巧:
- 使用 Web Worker 进行后台转换
- 分帧处理避免主线程卡顿
- 实现 LRU 缓存策略
6. 生产环境问题解决
6.1 坐标系不一致
典型表现:模型位置偏移或旋转
解决方案:
- 统一使用 Cesium.Transforms.eastNorthUpToFixedFrame 作为基准
- 对每个瓦片应用局部变换矩阵
6.2 纹理丢失
排查路径:
- 检查纹理 URL 相对路径转换
- 验证 MIME 类型是否正确
- 测试纹理尺寸是否为 2 的幂次方
7. 延伸思考
本方案可进一步扩展:
- 结合 Progressive Loading 实现流式加载
- 使用 WebAssembly 加速几何处理
- 开发 Unity/Unreal 插件实现多端复用
实际应用时建议:先在小范围测试坐标系转换精度,再逐步扩大处理范围。对于超大规模数据,应考虑分布式转换方案。
正文完
发表至: 未分类
近三天内
