LOD(Level of Detail,细节层次)是 Cesium 中用于优化 3D 场景渲染性能的核心机制,其核心目标是根据相机与对象的距离 / 视角等条件,动态切换对象的细节精度,平衡渲染质量与性能:
- 近距高细节:相机靠近对象时,加载高精度模型 / 纹理 / 几何数据,保证视觉效果;
- 远距低细节:相机远离对象时,切换为低精度简化模型(甚至点 / 广告牌),减少三角面、纹理采样等渲染开销;
- 核心价值:避免远距离对象消耗大量 GPU/CPU 资源,提升大规模场景(如海量 3D 模型、地形、影像)的帧率和流畅度。
Cesium 的 LOD 覆盖多类对象:地形、影像、3D Tiles 模型、Primitive/Entity 几何等,不同对象的 LOD 实现逻辑略有差异,但核心思想一致。
一、LOD 系统的核心应用场景与原理
| 对象类型 | LOD 作用原理 |
|---|---|
| 地形(Terrain) | 根据相机高度切换地形瓦片的分辨率(高海拔用低精度瓦片,低海拔用高精度) |
| 影像(Imagery) | 按瓦片层级(Level)加载:远距加载低分辨率影像,近距加载高分辨率影像 |
| 3D Tiles | 基于瓦片的 LOD 树:根节点是低精度模型,子节点是高精度,根据距离切换节点 |
| 模型内置 LOD | glTF 模型内置 LOD |
| 自定义 Primitive | 通过LOD类手动定义多细节层级,指定距离阈值切换几何 / 外观 |
二、LOD 系统的具体使用方法
1. 地形 LOD(默认启用,可配置)
Cesium 的地形默认开启 LOD,可通过配置地形提供者的参数调整 LOD 策略:
// 加载Cesium World Terrain,并配置LOD相关参数
const viewer = new Cesium.Viewer("cesiumContainer", {
terrainProvider: Cesium.createWorldTerrain({
// 控制地形细节精度(值越大,细节越高,性能开销越大)
requestWaterMask: true, // 水掩码(可选,不影响LOD但影响视觉)
requestVertexNormals: true, // 法向量(可选)
}),
// 地形LOD的核心配置:控制瓦片加载的最大/最小层级
terrainOption: {
maximumLevel: 15, // 最大细节层级(近距)
minimumLevel: 0, // 最小细节层级(远距)
},
});
// 手动调整地形LOD的采样距离(全局)
viewer.scene.terrainSampleDistance = 1000; // 采样距离越小,细节越高
2. 影像 LOD(瓦片层级自动切换,可配置)
影像图层的 LOD 由瓦片层级(Level)决定,Cesium 自动根据相机距离加载对应层级,可通过参数限制层级范围:
// 添加影像图层并配置LOD层级
const imageryLayer = viewer.imageryLayers.addImageryProvider(
new Cesium.UrlTemplateImageryProvider({
url: "https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png",
maximumLevel: 19, // 最大加载层级(近距最高精度)
minimumLevel: 0, // 最小加载层级(远距最低精度)
rectangle: Cesium.Rectangle.fromDegrees(70, 15, 140, 55), // 限定范围
})
);
// 调整影像LOD的加载优先级(可选)
imageryLayer.maximumScreenSpaceError = 2; // 屏幕空间误差(值越小,细节越高)
3. 3D Tiles LOD(核心场景,自动 + 可配置)
3D Tiles 是 Cesium 针对海量 3D 模型的 LOD 解决方案,瓦片本身包含 LOD 层级,加载后自动切换:
(1)基础加载(自动 LOD)
// 加载3D Tiles集(自动启用LOD)
const tileset = viewer.scene.primitives.add(
new Cesium.Cesium3DTileset({
url: "./tileset.json", // 3D Tiles根文件
// LOD核心配置
maximumScreenSpaceError: 16, // 屏幕空间误差(值越小,细节越高,性能越低)
minimumScreenSpaceError: 0, // 最小误差(远距最低细节)
maximumMemoryUsage: 512, // 最大内存占用(MB),超出则卸载高精度瓦片
})
);
// 定位到3D Tiles
viewer.zoomTo(tileset);
(2)自定义 3D Tiles LOD 策略
// 监听LOD切换事件
tileset.tileLoad.addEventListener((tile) => {
console.log("加载瓦片层级:", tile.level);
});
// 动态调整LOD精度
document.getElementById("lod-slider").addEventListener("input", (e) => {
tileset.maximumScreenSpaceError = Number(e.target.value);
});
(3)模型构建与 LOD 配置
Cesium 对 LOD 的原生支持依赖3D Tiles规范(替代单文件 glTF 的 LOD),需先制作带 LOD 的矿山 3D Tiles 模型:
模型制作流程
建模工具:Blender/3ds Max/Civil 3D 制作矿山地形 + 道路基础模型;
LOD 分级:
LOD0(高精度):近距离显示,包含矿山纹理、道路细节、边坡等;
LOD1(中精度):简化纹理,合并面,保留道路轮廓;
LOD2(低精度):仅保留矿山整体轮廓,道路简化为线条;
格式转换:用cesium-native/3D Tiles Tools将分级模型转为 3D Tiles(.json+.b3dm),配置refine(ADD/REPLACE)和geometricError(LOD 切换阈值,单位米)。
加载 3D Tiles 模型
// 初始化Cesium Viewer
const viewer = new Cesium.Viewer('cesiumContainer', {
terrainProvider: Cesium.createWorldTerrain(), // 加载地形(可选)
baseLayerPicker: false
});
// 加载带LOD的矿山3D Tiles模型
const mineTileset = viewer.scene.primitives.add(
new Cesium.Cesium3DTileset({
url: './tileset.json', // 矿山3D Tiles根文件
maximumScreenSpaceError: 16, // 控制LOD切换精度(值越小越精细)
cullWithChildrenBounds: true, // 优化LOD裁剪
skipLevelOfDetail: false // 禁用手动跳过LOD
})
);
// 定位到矿山位置
mineTileset.readyPromise.then(() => {
viewer.zoomTo(mineTileset);
});
4、模型内置 LOD
核心前提:glTF 模型内置 LOD(最优方案)
Cesium 1.95 原生支持 glTF 2.0 标准的 EXT_meshopt_compression/KHR_lod 扩展(需模型本身包含 LOD 数据),这是最高效的方式,Cesium 会自动根据相机距离切换模型细节。
模型制作要求(Blender/3ds Max 等工具)
为模型创建多级别细节(如高模、中模、低模);
导出 glTF 时启用 KHR_lod 扩展(Blender 需安装 glTF 导出插件并配置 LOD 层级);
每个 LOD 层级需定义触发距离(如距离相机 <100m 显示高模,100-500m 显示中模,>500m 显示低模)。
Cesium 加载内置 LOD 的 glTF 模型
只需正常加载模型,Cesium 会自动解析并应用 LOD:
// 初始化Cesium Viewer
const viewer = new Cesium.Viewer("cesiumContainer", {
terrainProvider: Cesium.createWorldTerrain()
});
// 加载带内置LOD的glTF模型
const modelEntity = viewer.entities.add({
position: Cesium.Cartesian3.fromDegrees(116.403874, 39.914885, 10), // 北京坐标示例
model: {
uri: "./models/your_lod_model.gltf", // 含KHR_lod扩展的模型
minimumPixelSize: 128, // 可选:模型最小像素尺寸(防止过小时消失)
maximumScale: 20000, // 可选:最大缩放限制
}
});
// 聚焦到模型
viewer.zoomTo(modelEntity);
5. 手动 LOD 实现(手动定义多细节层级)
若模型本身无 LOD 数据,可通过监听相机距离手动切换不同细节的模型文件(高 / 中 / 低模分开导出),核心步骤:
准备多版本模型
导出 3 个版本的模型文件:
- high.gltf:高细节(面数多);
- medium.gltf:中细节(面数中等);
- low.gltf:低细节(面数少)。
手动 LOD 实现代码
对于自定义几何(如 Box、Sphere),可通过Cesium.LOD类手动创建多细节层级:
// 创建自定义LOD对象
const lod = new Cesium.LOD();
// 层级1:距离<1000米时,显示高精度模型(100个三角面)
lod.addLevel(
new Cesium.Primitive({
geometryInstances: new Cesium.GeometryInstance({
geometry: new Cesium.BoxGeometry({
dimensions: new Cesium.Cartesian3(100, 100, 100),
vertexFormat: Cesium.VertexFormat.POSITION_AND_NORMAL,
}),
}),
appearance: new Cesium.PerInstanceColorAppearance(),
}),
1000 // 距离阈值(米):相机距离<1000时显示该层级
);
// 层级2:距离1000~5000米时,显示中精度模型(10个三角面)
lod.addLevel(
new Cesium.Primitive({
geometryInstances: new Cesium.GeometryInstance({
geometry: new Cesium.BoxGeometry({
dimensions: new Cesium.Cartesian3(100, 100, 100),
vertexFormat: Cesium.VertexFormat.POSITION_ONLY, // 仅位置,简化
}),
}),
appearance: new Cesium.PerInstanceColorAppearance(),
}),
5000 // 距离阈值:1000<距离<5000时显示
);
// 层级3:距离>5000米时,显示广告牌(替代3D模型)
lod.addLevel(
new Cesium.BillboardCollection({
billboards: [
{
image: "./icon.png",
position: Cesium.Cartesian3.fromDegrees(116.40, 39.90, 50),
scale: 2,
},
],
}),
Infinity // 距离>5000时显示
);
// 设置LOD的位置
lod.position = Cesium.Cartesian3.fromDegrees(116.40, 39.90, 50);
// 添加到场景
viewer.scene.primitives.add(lod);
半手动:自己控制“显示/隐藏”
如果模型量不大,又不想走 3D-Tiles,可以准备高、中、低三个 glTF,然后:
const models = { // 三组实体
high: viewer.entities.add({ model: { uri: 'high.glb' }, show: false }),
mid : viewer.entities.add({ model: { uri: 'mid.glb' }, show: false }),
low : viewer.entities.add({ model: { uri: 'low.glb' }, show: true })
};
function updateLOD() {
const cam = viewer.camera;
const pos = models.high.position; // 模型中心
const dist = Cesium.Cartesian3.distance(cam.position, pos);
models.high.show = dist < 200;
models.mid.show = dist >= 200 && dist < 500;
models.low.show = dist >= 500;
}
viewer.scene.postRender.addEventListener(updateLOD);
这样每帧都会根据距离手动开关,内存里始终只保留一份顶点数据,简单场景足够用。
三、LOD 优化关键技巧
平衡精度与性能:
- 3D Tiles 的maximumScreenSpaceError建议设为 8~32(值越大,性能越好,细节越差);
- 地形 / 影像的最大层级根据场景范围调整(小范围场景可设更高层级)。
内存管控:
- 通过maximumMemoryUsage限制 3D Tiles 内存占用,避免内存溢出;
- 远离视口的对象主动卸载(Cesium 自动处理,也可手动调用tileset.unloadTiles())。
避免 LOD 切换闪烁:
- 调整screenSpaceError的过渡阈值,或启用preloadWhenHidden预加载相邻层级;
- 自定义 LOD 时,相邻层级的几何中心保持一致。
优先级控制:
- 对重要对象(如建筑地标)设置更低的maximumScreenSpaceError,保证细节;
- 对次要对象(如树木、路灯)设置更高的阈值,降低开销。
四、总结
Cesium 的 LOD 系统是大规模 3D 场景性能优化的核心,不同对象的 LOD 使用方式不同:
- 地形 / 影像:默认启用,通过层级 / 采样距离配置;
- 3D Tiles:自动 LOD,核心调整maximumScreenSpaceError;
- 自定义 Primitive:通过LOD类手动定义多细节层级。
核心原则是近精远简,通过合理配置 LOD 参数,在视觉效果可接受的前提下,最大化渲染性能。
1386

被折叠的 条评论
为什么被折叠?



