实现一个Cesium近地天空盒
最近实验室实现火星科技的近地天空盒,简单来说其效果就是当相机距离地面较近的时候天空盒可以变成自己想要的样子,远离的时候恢复成默认的天空盒。
我在其上面增加一些改进,其中包括有切换天空盒,最终效果如图所示:
当摄影机离地面超过2500m的时候,天空盒切换为默认情况,效果图如下:
当然还可以进行切换天空盒,如点击蓝天按钮将天空盒切换为蓝天:
将天空盒切换为星空:
实现的细节在于:
this.map.scene.postRender.addEventListener(() => {
let e = this.map.camera.position;
if(Cartographic.fromCartesian(e).height < 2500) {
// 显示自定义的天空盒
this.map.scene.skyBox = this.current;
this.map.scene.skyAtmosphere.show = false;
}else {
this.map.scene.skyBox = this.defaultSkyBox;
this.map.scene.skyAtmosphere.show = true;
}
});
实际上是增加了一个实时渲染监听事件,当高度小于2500的时候,viewer.scene.skyBox就为current(自己定义的变量)。并将skyAtmosphere关闭,当高度大于2500的时候,viewer.scene.skyBox就为默认的天空盒,并将skyAtmosphere打开。
但是,如果仅仅新建一个skyBox类的时候,会发现渲染的天空盒是倾斜的,具体如图所示:
有两个方法可以对近地天空盒进行改进:
1.修改skyBox类的源码
2.引进新的类
虽然原理差不多,但更推荐使用第二种方法,在这里新建skyBoxOnGround.js,其内容如下:
//以下代码复制自Cesium源码的SkyBox,然后做了一点点修改。
//SkyBoxOnGround.js
(function() {
const Cesium = window.Cesium;
const BoxGeometry = Cesium.BoxGeometry;
const Cartesian3 = Cesium.Cartesian3;
const defaultValue = Cesium.defaultValue;
const defined = Cesium.defined;
const destroyObject = Cesium.destroyObject;
const DeveloperError = Cesium.DeveloperError;
const GeometryPipeline = Cesium.GeometryPipeline;
const Matrix3 = Cesium.Matrix3;
const Matrix4 = Cesium.Matrix4;
const Transforms = Cesium.Transforms;
const VertexFormat = Cesium.VertexFormat;
const BufferUsage = Cesium.BufferUsage;
const