在 Cesium 可视化开发中,当场景复杂度提升或有定制化或者较高的场景展示需求时,需要考虑的一些调整与优化点整理:
如果是内网部署项目,首先在
new Viewer时,设置imageryProvider: false, 并使用viewer.scene.globe.baseColor = Cesium.Color.fromCssColorString("#001d34")按需设置空地球颜色本地影像通过
nginx挂载后,通过UrlTemplateImageryProvider新建provider并添加到imageryLayers里Cesium的鼠标操作个人不是很习惯,并且鼠标中键控制pitch有一些不符合直觉,可以通过以下代码按需改动操作方式:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17// 以下设置为了使cesium地图鼠标控制符合mapbox习惯
// 关闭双击事件
viewer.cesiumWidget.screenSpaceEventHandler.removeInputAction(
Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK
);
// 鼠标右键旋转
viewer.scene.screenSpaceCameraController.tiltEventTypes = [
Cesium.CameraEventType.RIGHT_DRAG,
];
// 中键滚动缩放
viewer.scene.screenSpaceCameraController.zoomEventTypes = [
Cesium.CameraEventType.WHEEL,
];
// 鼠标左键平移
viewer.scene.screenSpaceCameraController.rotateEventTypes = [
Cesium.CameraEventType.LEFT_DRAG,
];有
3dtile加载需求时,异步加载3dtileconst tileset = await Cesium.Cesium3DTileset.fromUrl('/Tileset/tileset.json');4.1. 在之前项目中,可能是建模问题导致的切出来
3dtile默认加载高度不对,这时需要重新切或者前端处理一下:1
2
3
4
5
6
7const center = tileset.boundingSphere.center;
const heightOffset = -425.1; // 高度偏移量
const cartographic = Cesium.Cartographic.fromCartesian(center);
const surface = Cesium.Cartesian3.fromRadians(cartographic.longitude, cartographic.latitude, 0.0);
const offset = Cesium.Cartesian3.fromRadians(cartographic.longitude, cartographic.latitude, heightOffset);
const translation = Cesium.Cartesian3.subtract(offset, surface, new Cesium.Cartesian3());
tileset.modelMatrix = Cesium.Matrix4.fromTranslation(translation);4.2. 当模型材质的金属度太高,粗糙度太低,可能会导致模型反光,且背光面太暗,这时需要手动修改材质,或者提升光强度。经过对比,最终还是添加一个
3dtile全局的着色器效果比较好 - -1
2
3
4
5
6
7
8
9const unlitShader = new Cesium.CustomShader({
lightingModel: Cesium.LightingModel.UNLIT,
fragmentShaderText: `
void fragmentMain(FragmentInput fsInput, inout czm_modelMaterial material) {
material.diffuse = material.diffuse * 1.5;
}
`
});
tileset.customShader = unlitShader;Cesium场景加载后,为了提升展示效果,可以添加阴影和抗锯齿viewer.scene.shadowMap.softShadows = true // 更好效果的抗锯齿(比较吃配置)viewer.shadowMap.darkness = cesium_shadow_opacity // 透明度viewer.scene.shadowMap.size = cesium_shadow_size // 阴影大小 类似分辨率的概念viewer.scene.postProcessStages.fxaa.enabled = true需要实时调试参数看效果时,我个人一般在控制台操作
viewer, 修改可以实时生效1
2
3
4viewer.scene.light = new Cesium.DirectionalLight({
direction: new Cesium.Cartesian3(0.2, -1.2, -0.5),
intensity: 7,
})1
2
3
4
5
6
7
8
9
10viewer.scene.camera.flyTo({
// 经度 纬度 高度
destination: Cesium.Cartesian3.fromDegrees(114.136356, 30.473618, 10000),
// 朝向 仰角 倾斜
orientation: {
heading: Cesium.Math.toRadians(-90),
pitch: Cesium.Math.toRadians(-90),
roll: 0
}
})加载大量单体化模型
entity时,仅仅设置
模型distanceDisplayCondition: new Cesium.DistanceDisplayCondition(0, MAX_DISTANCE_FOR_MODELS)
point 点distanceDisplayCondition: new Cesium.DistanceDisplayCondition(MAX_DISTANCE_FOR_MODELS, Number.POSITIVE_INFINITY)
是不够的
因为虽然视角拉远不展示模型只展示点,但是本质上它还是entity; 还是需要根据level或者相机高度 删除掉全部实体,只添加PointPrimitiveCollection来替换entity, 这样做以后,在较高的相机地面距离来看,性能一般不会有瓶颈