问题:让光源绕球体旋转即可,关键在于计算实时的光源位置,光源位置的变化由时间决定。
Cesium中,可以通过viewer.scene.light来创建点光源,设置其位置(x,y,z)及光强。
viewer.scene.light = new Cesium.DirectionalLight({
color:new Cesium.Color (1.0, 1.0, 1.0, 0.5),
direction:direction,
})
1. 背景知识
火星基本参数:
参数 | 值 | 参数 | 值 |
直径/km | 6779 | 自转周期 | 24小时37分22秒 24.62278 h |
距离太阳平均距离/km | 2.29亿 | 倾角 | 25.19度 |
公转/天 | 687 | 自转方向 | 自西向东 |
地球基本参数:
参数 | 值 | 参数 | 值 |
直径/km | 12742 | 自转周期 | 23小时56分4秒 23.93444 h |
距离太阳平均距离/km | 1.5 亿 | 倾角 | 23.44度 |
公转/天 | 365 | 自转方向 | 自西向东 |
2. 原理
关键在于计算太阳直射点的经纬度的变化。
其中,tilt为球体倾角,k为每秒的公转的角度,687对应公转周期,t为距离上一次直射(0°,0°)(类似地球的春分点)的时差,246.2对应每自转1度需要的秒数,
太阳直射点纬度变化图如下所示:
然而,改变光源位置,需要让光源反向于球体自转方向旋转。
longitude = 0 - difference / 246.6 latitude = 0 - 25.19 * Math.sin(6.28/(687*24*3600) * difference)
3. 核心代码
viewerRef.current = new Cesium.Viewer('cesiumContainer',{
animation: true,
shouldAnimate:true,
baseLayerPicker: true,
fullscreenButton: false,
vrButton: false,
geocoder: false,
homeButton: true,
infoBox: true,
sceneModePicker: false,
selectionIndicator: true,
timeline: false,
navigationHelpButton: false,
navigationInstructionsInitiallyVisible: false,
});
var viewer = viewerRef.current
viewer._cesiumWidget._creditContainer.style.display = "none";
viewer.scene.moon.show = false;
viewer.scene.fog.enabled = false;
viewer.scene.sun.show = false;
viewer.scene.skyBox.show = false;
viewer.imageryLayers.removeAll();
viewer.scene.globe.enableLighting = true;// 开启全球光照
viewer.shadows = true
var longitude
var latitude
// 火星的春分点
var startTime = '2022-12-26T00:00:00Z';
startTime = Cesium.JulianDate.fromIso8601(startTime);
var direction
//实时计算新的太阳直射点,difference为与春分时间的时差
viewer.clock.onTick.addEventListener(function(clock) {
var currentTime = clock.currentTime;
var difference = Cesium.JulianDate.secondsDifference(currentTime, startTime);
longitude = 0 - difference / 246.6
latitude = 0 - 25.19 * Math.sin(6.28/(687*24*3600) * difference)
direction = new Cesium.Cartesian3.fromDegrees(longitude,latitude,2.29e11)
viewer.scene.light = new Cesium.DirectionalLight({
color:new Cesium.Color (1.0, 1.0, 1.0, 0.5),
direction:direction,
})
});
)
viewer.camera.setView({
destination:Cesium.Cartesian3.fromDegrees(120,0,20000000.0), // 经纬度和高度
});
// 添加火星图层
var marsUrl = 'https://planetarymaps.usgs.gov/cgi-bin/mapserv?map=/maps/mars/mars_simp_cyl.map&service=WMS';
const marsLayer = new Cesium.ImageryLayer(
new Cesium.WebMapServiceImageryProvider({
url: marsUrl,
layers:'MDIM21_color',
}),
);
marsLayer.name = 'Mars'
viewer.imageryLayers.add(marsLayer);
4. 实现效果
对比地球时间的同一时刻Cesium自带的地球昼夜阴影和本文实现的火星昼夜阴影,用同一个图层,便于观察阴影的差异,如下图:
地球昼夜阴影(左图)与火星昼夜阴影(右图)
演示视频:
火星昼夜变化-阴影