备注: 以下写法为vue3 ts Cesium1.132.0
1. 初始化Cesium
var viewer = new Cesium.Viewer('cesiumContainer', {
// 去掉对话框警告
infoBox: false,
// 是否显示查询按钮
geocoder: false,
// 不显示home按钮
homeButton: true,
// 控制查看器的显示模式(3D、2.5D、2D是否显示)
sceneModePicker: true,
// 是否显示图层选择
baseLayerPicker: true,
// 是否显示帮助按钮
navigationHelpButton: false,
// 是否显示播放动画、计时
animation: false,
// 是否显示时间轴
timeline: false,
// 是否显示全屏按钮
fullscreenButton: true,
// 使用具有 tile availability 的全球地形,供 sampleTerrainMostDetailed 使用
terrain: Cesium.Terrain.fromWorldTerrain(),
})
terrain: Cesium.Terrain.fromWorldTerrain()配置后地图会出现高度,可以适配3D模型.
2. 引入3D模型
// 创建3D Tileset
const tileset = await Cesium.Cesium3DTileset.fromUrl(url, {
heightReference: Cesium.HeightReference.RELATIVE_TO_GROUND,
// 性能优化参数
maximumScreenSpaceError: 1, // 最大屏幕空间误差(越小越精细)
// LOD 控制
skipLevelOfDetail: true, // 是否跳过细节层次
baseScreenSpaceError: 1024, // 基础屏幕空间误差
skipScreenSpaceErrorFactor: 16, // 跳过屏幕空间误差因子
skipLevels: 1, // 跳过的层级数
immediatelyLoadDesiredLevelOfDetail: false, // 是否立即加载所需LOD
loadSiblings: false, // 是否加载兄弟节点
// 动态屏幕空间误差
dynamicScreenSpaceError: true, // 启用动态屏幕空间误差
dynamicScreenSpaceErrorDensity: 0.00278,
dynamicScreenSpaceErrorFactor: 4.0,
dynamicScreenSpaceErrorHeightFalloff: 0.25,
// 渲染选项
progressiveResolutionHeightFraction: 0.3, // 渐进式分辨率高度分数
foveatedScreenSpaceError: true, // 中心视野优化
foveatedConeSize: 0.1, // 视野锥体大小
foveatedMinimumScreenSpaceErrorRelaxation: 0.0, // 最小屏幕误差松弛
})
url为3D资源的路径 格式为:"....../tileset.json"
maximumScreenSpaceError的配置是重点 为3D模型的渲染精细化程度 数字越小模型越清晰精细相对应的性能消耗越大.
3. 调整3D模型的高度
由于3D模型会出现偏移,远离地图的情况,所以需要调整高度(z轴),贴近地面
方法一 : terrain未配置Cesium.Terrain.fromWorldTerrain()
// 创建 ENU 到 ECEF 的变换矩阵
const enuMatrix = Cesium.Transforms.eastNorthUpToFixedFrame(center)
// 创建平移矩阵
const translation = new Cesium.Cartesian3(offsetEast, offsetNorth, offsetHeight)
const translationMatrix = Cesium.Matrix4.fromTranslation(translation)
// 合成变换矩阵
const transform = new Cesium.Matrix4()
Cesium.Matrix4.multiply(enuMatrix, translationMatrix, transform)
Cesium.Matrix4.multiply(
transform,
Cesium.Matrix4.inverse(enuMatrix, new Cesium.Matrix4()),
transform,
)
// 应用变换
tileset.modelMatrix = Cesium.Matrix4.multiply(
tileset.modelMatrix,
transform,
new Cesium.Matrix4(),
)
地图为3D球,且terrain未配置Cesium.Terrain.fromWorldTerrain()地图无高度起伏,无法是完美适配3D模型,必须创建变换矩阵,否则会出现X,Y,Z三个轴不同程度偏移.且此方法最好手动调整offsetHeight.
方法二 : terrain配置Cesium.Terrain.fromWorldTerrain()
// 获取 tileset 中心点
const center = tileset.boundingSphere.center
// 获取该点的地形高度
const cartographic = Cesium.Cartographic.fromCartesian(center)
let terrainHeight = cartographic.height
try {
const updated = await Cesium.sampleTerrainMostDetailed(viewer.terrainProvider, [cartographic])
terrainHeight = updated && updated[0] ? updated[0].height : cartographic.height
} catch (err) {
console.warn('sampleTerrainMostDetailed not available; using original height.', err)
}
// 计算需要的调整高度
const heightOffset = terrainHeight - cartographic.height
const enuMatrix = Cesium.Transforms.eastNorthUpToFixedFrame(center)
const offset = new Cesium.Cartesian3(0, 0, heightOffset)
const worldOffset = new Cesium.Cartesian3()
Cesium.Matrix4.multiplyByPointAsVector(enuMatrix, offset, worldOffset)
const transform = Cesium.Matrix4.fromTranslation(worldOffset)
tileset.modelMatrix = Cesium.Matrix4.multiply(
tileset.modelMatrix,
transform,
new Cesium.Matrix4(),
)
此方法动态设置了需要调整的高度,但由于3D地图高度有起伏,模型贴近地面会有轻微穿模情况.

6732

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



