在使用Cesium进行三维地理可视化时,经常需要根据时间变化来调整场景的渲染效果,例如模拟一天的白天和黑夜。这个过程不仅能让场景的光照效果更真实,还能提供动态的视觉体验。本文将通过一个示例代码,讲解如何在Cesium中实现动态渲染白天与黑夜,并根据一天不同时间调整曝光值,模拟白天和夜晚的不同光照效果。
背景
在Cesium中,场景的渲染可以通过“后处理阶段”(Post-Process Stages)来调整。曝光(exposure)是影响光照和画面亮度的重要参数。白天和夜晚的曝光差异较大:白天时阳光强烈,曝光值应较高;而在夜晚,曝光值应较低,甚至接近零。
核心思路
我们将通过监听时间的变化,根据当前时间动态调整Cesium中的曝光值,从而模拟一天中的不同光照变化。具体来说,白天(9:00 AM 到 3:00 PM)的曝光值较高,而在傍晚(3:00 PM 到 7:00 PM)时,曝光值逐渐过渡到夜晚(7:00 PM 到 6:00 AM)的低曝光值。
示例代码讲解
以下是实现动态曝光调整的代码示例:
javascript
// 曝光控制
viewer.scene.postProcessStages.exposure = 1.0;
gui.add(viewer.scene.postProcessStages, 'exposure', 0.0, 3.0).step(0.01).name('曝光');
// 设置时间为每秒钟模拟3600秒(即1小时)
viewer.clock.multiplier = 3600;
viewer.clock.shouldAnimate = true;
// 每次时间更新时触发
viewer.clock.onTick.addEventListener((clock) => {
// 当前时间
const currentTime = viewer.clock.currentTime;
const h = Cesium.JulianDate.toDate(currentTime).getHours();
const m = Cesium.JulianDate.toDate(currentTime).getMinutes();
let hour = h + m / 60;
// 设置曝光值,根据时间调整:白天曝光较高,晚上曝光较低
if (hour >= 9 && hour <= 15) {
// 白天时(9:00 AM 到 3:00 PM),曝光较高
viewer.scene.postProcessStages.exposure = 2.0;
} else if (hour > 15 && hour < 19) {
// 傍晚时(3:00 PM 到 7:00 PM),曝光逐渐降低
let exposure = Cesium.Math.lerp(2.0, 0.01, (hour - 15) / 4);
viewer.scene.postProcessStages.exposure = exposure;
} else if (hour < 9 && hour > 6) {
// 早晨时(6:00 AM 到 9:00 AM),曝光逐渐增高
let exposure = Cesium.Math.lerp(0.01, 2.0, (hour - 6) / 3);
viewer.scene.postProcessStages.exposure = exposure;
} else {
// 夜晚时(7:00 PM 到 6:00 AM),曝光较低
viewer.scene.postProcessStages.exposure = 0.01;
}
});
javascript
代码解释
1. 曝光控制
javascript
viewer.scene.postProcessStages.exposure = 1.0;
gui.add(viewer.scene.postProcessStages, 'exposure', 0.0, 3.0).step(0.01).name('曝光');
- 通过
viewer.scene.postProcessStages.exposure
来控制曝光值的初始状态。默认曝光值为1.0。 - 通过
gui.add()
方法,允许我们在调试面板中手动调整曝光值范围,便于测试不同的曝光效果。
2. 设置时间速率
viewer.clock.multiplier = 3600;
viewer.clock.shouldAnimate = true;
viewer.clock.multiplier = 3600
将时间速率设定为每秒钟模拟1小时。这意味着每1秒钟的实际时间,场景中时间会推进1小时。viewer.clock.shouldAnimate = true
启用动画,使得场景会根据时间的变化自动更新。
3. 时间更新与曝光调整
】
viewer.clock.onTick.addEventListener((clock) => {
const currentTime = viewer.clock.currentTime;
const h = Cesium.JulianDate.toDate(currentTime).getHours();
const m = Cesium.JulianDate.toDate(currentTime).getMinutes();
let hour = h + m / 60;
- 每当时间更新时,
onTick
事件触发,我们获取当前的时间,并将其转换为小时(hour
)。 - 使用
Cesium.JulianDate.toDate()
方法将Cesium的时间格式转换为JavaScript的Date
对象,从而获取小时和分钟。
4. 根据时间动态调整曝光
if (hour >= 9 && hour <= 15) {
viewer.scene.postProcessStages.exposure = 2.0;
} else if (hour > 15 && hour < 19) {
let exposure = Cesium.Math.lerp(2.0, 0.01, (hour - 15) / 4);
viewer.scene.postProcessStages.exposure = exposure;
} else if (hour < 9 && hour > 6) {
let exposure = Cesium.Math.lerp(0.01, 2.0, (hour - 6) / 3);
viewer.scene.postProcessStages.exposure = exposure;
} else {
viewer.scene.postProcessStages.exposure = 0.01;
}
- 白天(9:00 AM 到 3:00 PM):曝光值为2.0,模拟强烈的阳光。
- 傍晚(3:00 PM 到 7:00 PM):使用线性插值
Cesium.Math.lerp()
逐渐降低曝光值,从2.0降到0.01。 - 早晨(6:00 AM 到 9:00 AM):曝光值逐渐增高,从0.01增至2.0,模拟太阳升起的过程。
- 夜晚(7:00 PM 到 6:00 AM):曝光值保持在最低,模拟夜晚或无光照的情况。
结论
通过上述代码实现,我们能够根据一天内的时间变化,动态地调整Cesium中的曝光值,从而模拟白天与夜晚的光照效果。这种方式可以增强三维场景的真实感,尤其在需要动态显示全天候变化的地理信息系统(GIS)应用中非常有用。
随着时间的推移,我们可以继续优化和扩展这个基础,实现更多的效果,如太阳高度角变化、天气变化等,进一步提升可视化的真实性和互动性。
声明:本站资源是网友搜集整理而成,(除广告页面及原创教程)版权均归原作者所有。本站仅提供一个观摩学习的环境,将不对任何资源负法律责任。本站为纯属分享资源站点,网站内所有资源仅供学习交流之用,请勿用作商业用途(CC协议除外),并请于下载后24小时内删除,谢谢。若无意中侵犯到您的版权利益,请来信联系我们,我们会在收到信息后会尽快给予处理!