3D Tiles 之 Geometry Error 介绍
在 3D Tiles 数据格式中,几何错误(Geometry Error) 是指由于几何体简化或分块(tiles)处理过程中,产生的可视差异。简而言之,几何错误是表示某个 Tile 的简化几何体与其源几何体之间的偏差,这种偏差通常会影响渲染效果。本文将重点介绍其中一个重要的几何错误度量:屏幕空间误差(Screen-Space Error, SSE)。
TilesBuilder : TilesBuilder提供一个高效、兼容、优化的数据转换工具,一站式完成数据转换、数据发布、数据预览操作。
什么是屏幕空间误差(SSE)?
屏幕空间误差(SSE)是一种评估和度量3D Tiles 中几何简化的有效性和准确性的方法。它描述的是,简化后的 Tile 在屏幕上呈现时,与其完整(原始)几何体相比,可能会出现的视觉差异。
具体来说,SSE 衡量的是一个 Tile 在被简化并呈现时,其简化几何体与完整几何体之间的差距,在屏幕像素级别的误差。简化几何体的表现通常是通过减少顶点数、减少三角形数量等方式来优化性能,但这种简化也可能导致一定的视觉失真。
如何计算 SSE?
SSE 的计算依赖于几个因素,包括简化后的几何体与原始几何体之间的差距、视角、摄像机距离等。一般来说,SSE 计算可以通过以下步骤进行:
-
简化几何体:首先对原始几何体进行简化,生成一个简化版本的几何体。简化的程度通常由细节层次(Level of Detail, LOD)控制,LOD 越低,几何简化程度越高,误差也可能越大。
-
渲染简化几何体:将简化后的几何体与原始几何体一起进行渲染,计算每个像素的差异。
-
误差计算:对于每个像素,计算简化几何体和原始几何体之间的差异,并汇总所有像素的误差,得到一个总的 SSE 值。
使用 Cesium API 计算 SSE
在 Cesium 中,计算 SSE 需要借助 Cesium3DTileFeature
类中的相关 API,通过对比简化后的 Tile 和原始几何体的差异来估算 SSE。下面是一个计算 SSE 的简单示例:
javascript
// 初始化Cesium Viewer
const viewer = new Cesium.Viewer('cesiumContainer');
// 加载3D Tiles模型
const tileset = viewer.scene.primitives.add(new Cesium.Cesium3DTileset({
url: 'path_to_3d_tiles/tileset.json'
}));
// 定义计算SSE的函数
function calculateSSE(tileset) {
const tile = tileset._root; // 获取最根部的Tile
const boundingVolume = tile.boundingVolume; // 获取Tile的包围体
// 获取摄像机位置
const camera = viewer.camera;
const cameraPosition = camera.positionWC;
// 计算Tile与摄像机之间的距离
const distance = Cesium.Cartesian3.distance(cameraPosition, boundingVolume.center);
// 获取Tile的屏幕空间大小
const screenSpaceSize = tile._contentBoundingVolume.boundingVolume.boundingVolume.boundingVolume.radius;
// 使用SSE公式估算误差
const SSE = screenSpaceSize / distance;
console.log(`SSE: ${SSE}`);
return SSE;
}
// 监听tileset加载完成
tileset.readyPromise.then(function() {
// 在Tileset加载完成后,计算SSE
calculateSSE(tileset);
});
示例 tileset.json
在 Cesium 中,tileset.json
是一个 3D Tiles 数据集的根配置文件,定义了整个 tileset 的结构、位置、细节层次(LOD)等信息。以下是一个简单的 tileset.json
示例,展示了如何定义一个基本的 3D Tiles 数据集。
json
{
"asset": {
"version": "1.0",
"generator": "3D Tiles Tools"
},
"tilesetVersion": "1.0",
"root": {
"boundingVolume": {
"region": [
-1.31968, // 西经
0.69887, // 南纬
-1.31965, // 东经
0.69891, // 北纬
0, // 最低海拔
1000 // 最高海拔
]
},
"geometricError": 500, // 根节点几何误差
"refine": "REPLACE",
"content": {
"url": "tile0.b3dm"
},
"children": [
{
"boundingVolume": {
"box": [
-1.31966, // 西经
0.69888, // 南纬
-1.31964, // 东经
0.69890, // 北纬
0, // 最低海拔
500 // 最高海拔
]
},
"geometricError": 250,
"content": {
"url": "tile1.b3dm"
}
},
{
"boundingVolume": {
"box": [
-1.31965, // 西经
0.69889, // 南纬
-1.31963, // 东经
0.69892, // 北纬
0, // 最低海拔
500 // 最高海拔
]
},
"geometricError": 250,
"content": {
"url": "tile2.b3dm"
}
}
]
}
}
在这个 tileset.json
文件中:
-
asset
部分定义了文件的版本和生成工具。 -
root
定义了根节点的信息,包括该 Tile 的包围体、几何误差、内容和子 Tile。 -
boundingVolume
用于定义 Tile 的包围体(可以是region
或box
等)。 -
geometricError
控制了 Tile 的简化程度,也影响 SSE 的计算。 -
content
指向该 Tile 对应的.b3dm
文件,存储了 3D 模型的二进制数据。TilesBuilder : TilesBuilder提供一个高效、兼容、优化的数据转换工具,一站式完成数据转换、数据发布、数据预览操作。
SSE 的意义
SSE 的意义在于,它帮助开发者平衡性能和视觉效果。在 3D Tiles 数据中,Tile 是用于管理大规模场景的一个重要单位,通过将模型分割成多个 Tile,可以有效地提高渲染性能,尤其是在地理信息系统(GIS)和城市建模等领域中。
-
简化与细节的权衡:当 Tile 被简化时,虽然可以减少渲染的计算量,提升性能,但简化过度可能会导致 Tile 的视觉效果变差,影响最终用户的体验。SSE 作为一种度量标准,帮助开发者确定简化的程度是否合适,是否会产生不必要的视觉误差。
-
Level of Detail(LOD)控制:通过设置合适的 SSE 阈值,开发者可以控制每个 Tile 在不同距离下的简化程度。例如,在远距离观察时,可以允许更大的误差,以提高性能;而在近距离时,则需要尽量保留更精确的几何体来避免影响视觉效果。
SSE 在 3D Tiles 中的应用
在 3D Tiles 中,SSE 被广泛应用于优化 Tile 的显示性能。例如,在一个大型城市的 3D 建模场景中,可能会有数以万计的建筑物,每个建筑物都有多个 Tile。当用户从远处查看整个城市时,只需要渲染较为粗略的几何体,而当用户靠近某个建筑时,系统会自动加载更高细节的 Tile。这种基于 SSE 的动态 LOD 策略,可以大幅度提高性能,同时保证视觉质量。
结论
屏幕空间误差(SSE) 是一种重要的几何简化度量工具,广泛应用于 3D Tiles 的优化过程中。通过合理的 SSE 计算和控制,开发者能够在性能与视觉效果之间找到最佳平衡点,特别是在大规模场景渲染中。它使得开发者能够在优化渲染效率的同时,确保用户体验不受显著影响。随着 3D Tiles 和相关技术的不断发展,SSE 将继续扮演着至关重要的角色。
TilesBuilder : TilesBuilder提供一个高效、兼容、优化的数据转换工具,一站式完成数据转换、数据发布、数据预览操作。