Skip to content

天气粒子系统 ​

WeatherEffects 是 BMapViewer 的屏幕空间天气模块。它基于 Cesium PostProcessStage 在场景渲染完成后合成天气画面,不需要为每个粒子创建 Entity,适合大范围地图中的雨、雪、雾、沙尘、云层和闪电表现。

打开在线天气示例

天气实验室中的六个效果统一使用 ArcGIS World Imagery 作为演示底图,便于在全球影像场景中观察降水、能见度和光照变化。

天气案例目录 ​

效果实现类重点能力文档与实时案例
降雨RainEffect方向、速度、密度、粗细和风偏查看降雨
降雪SnowEffect多尺度雪花、飘移和粒径查看降雪
距离雾FogEffect深度距离、能见度和雾色查看距离雾
沙尘SandstormEffect暖色颗粒、扰动和低能见度查看沙尘
体积云CloudEffect世界空间云壳、视差、云量和风场查看体积云
雷雨闪电RainEffect细雨与程序化闪电组合查看雷雨闪电

快速开始 ​

使用 WeatherSystem 管理一个活动天气效果。调用 switch 时,当前效果会先被销毁,因此不会产生重复叠加。

js
import { WeatherEffects } from 'b-map-viewer'

const weather = new WeatherEffects.WeatherSystem(viewer, {
  type: 'rain',
  intensity: 0.5,
  density: 1,
  speed: 1,
  size: 1,
  angle: -22.9183,
  wind: 0,
  color: '#99b3ccff',
  lightning: true,
  lightningMixFactor: 0.35,
  lightningFallInterval: 0.8,
})

weather.switch('snow', {
  intensity: 0.5,
  density: 1,
  speed: 1,
  size: 1,
  angle: 18.4349,
  drift: 1,
})

// 页面卸载时释放后处理阶段
weather.destroy()

独立效果类 ​

需要单独控制效果,或希望同时组合多个天气阶段时,可以直接实例化效果类:

js
const fog = new WeatherEffects.FogEffect(viewer, {
  mode: 'depth',
  intensity: 0.5,
  depthStart: 0.22,
  depthRange: 0.2,
  density: 0.65,
  skyAmount: 0.55,
  color: '#ccccccff',
})

fog.hide()
fog.show()
fog.setOptions({ depthStart: 0.26, density: 0.8 })
fog.destroy()

模块提供以下类:

类型类主要参数说明
rainRainEffectintensity、density、speed、size、angle、wind、lightning、color可调整方向、粗细和风偏,并可启用闪电的透视雨线
snowSnowEffectintensity、density、speed、angle、size、drift、color多尺度飘雪与横向漂移
fogFogEffectintensity、depthStart、depthRange、density、skyAmount、color按深度阈值混合雾色,并兼容旧版米制距离模式
sandstormSandstormEffectintensity、density、speed、wind、color暖色颗粒、扰动与低能见度合成
cloudCloudEffectcoverage、baseHeight、topHeight、scale、speed、windDirection、steps世界空间光线步进生成具有视差的体积云
lightningLightningEffectintensity、frequency、brightness、width、color随机闪光和分叉闪电纹理

createWeatherEffect(viewer, type, options) 也可以按类型创建效果;sand 是 sandstorm 的别名。

js
const effect = WeatherEffects.createWeatherEffect(viewer, 'cloud', {
  coverage: 0.58,
  speed: 0.14,
})

雨雪方向、大小、速度与密度 ​

雨和雪的方向参数使用角度制,运行期间可以通过 setOptions 即时调整,不需要重新创建后处理阶段。默认值对应参考文件中原来写死的着色器常量:

效果默认值与原始常量的对应关系
雨angle: -22.9183 对应 -0.4 弧度;density: 1 对应 uv.x * 100;size: 1 对应阈值 0.95;intensity: 0.5 对应混合比例 0.5
雪density: 1 保留 10/8/6/5 四层尺度;angle: 18.4349 对应原始 (1, 3) 位移方向;size: 1 保留原始粒径;intensity: 0.5 对应混合比例 0.5
js
const rain = new WeatherEffects.RainEffect(viewer)

rain.setOptions({
  angle: -38,   // 屏幕空间方向,单位:度
  speed: 1.8,   // 动画速度倍率
  density: 1.2, // 粒子密度
  size: 0.65,   // 雨线粗细,小于 1 时比默认更细
  wind: 0.55,   // 雨线随时间产生的横向风偏
  lightning: true,
  lightningMixFactor: 0.35,
  lightningFallInterval: 0.8,
})
参数雨雪说明
angle-180~180-180~180降水在屏幕空间中的旋转角度
speed0.05~50.05~5时间推进倍率,数值越大下落越快
density0.1~30.1~3雨线列数或雪花网格密度,1 为原始配置
wind / drift-2~2-2~2横向漂移幅度
size0.1~30.1~3雨线粗细或雪花粒径倍率,1 为原始配置

降雨中的闪电 ​

RainEffect 内部按“雨效 → 闪电”的顺序组合后处理阶段。闪电默认关闭;将 lightning 设置为 true 后启用,运行期间也可以直接切换,不需要重新创建雨效。

天气实验室中的“降雨”案例只展示纯降雨;“闪电”案例则创建同一个 RainEffect,并通过 lightning: true 展示完整雷雨效果。

js
const rain = new WeatherEffects.RainEffect(viewer, {
  lightning: true,
  lightningMixFactor: 0.35,
  lightningFallInterval: 0.8,
})

rain.setOptions({ lightning: false }) // 关闭闪电,仅保留降雨
rain.setOptions({ lightning: true })  // 再次开启闪电
参数默认值说明
lightningfalse是否启用雨中的闪电后处理阶段
lightningMixFactor0.35闪电画面与雨景的混合比例,范围 0~1
lightningFallInterval0.8闪电事件的时间推进间隔,范围 0.01~1

闪电部分保留了参考算法的两层哈希噪声、8 次 FBM、100 段电弧路径和蓝色云层闪光,并适配为 Cesium 1.118 使用的 WebGL 2 后处理语法。

雾使用 near 和 far 控制相机距离范围:near 之前不混合雾色,接近 far 时达到主要雾化区间。旧版 visibility 参数仍作为 far 的兼容别名。

公共生命周期 ​

所有效果类都遵循相同的 SDK 生命周期:

方法返回值说明
load(options?)PostProcessStage重新创建并加载效果阶段
setOptions(options)当前实例运行时更新参数,无需重建阶段
getOptions()object获取当前配置副本
getStage()PostProcessStage获取 Cesium 后处理阶段
show() / start()当前实例启用效果
hide() / stop()当前实例暂停效果但保留阶段
remove()-从 Viewer 中移除阶段,实例仍可再次 load
destroy()-永久销毁实例并释放引用
isDestroyed()boolean判断实例是否已销毁

WeatherSystem API ​

js
const system = new WeatherEffects.WeatherSystem(viewer)

system.load('rain', options)
system.switch('fog', options)
system.setOptions({ density: 0.5 })
system.hide()
system.show()
system.remove()
system.destroy()

WeatherSystem 只管理一个活动效果。如果需要雨雾叠加,请分别创建 RainEffect 和 FogEffect,并在页面卸载时逐一销毁。

使用建议 ​

  • 强度、密度等数值会在 SDK 内部限制到安全范围,编辑示例时仍建议逐步调整。
  • 雾效果会读取深度纹理;浏览器和显卡需要支持 Cesium WebGL 深度纹理能力。
  • 天气属于全屏后处理。叠加多个高密度效果会增加片元着色开销,移动设备建议同时启用不超过两个效果。
  • 颜色支持 CSS 色值和带透明度的十六进制色值,例如 #99b3ccff。
  • Vue 组件应在 onBeforeUnmount 中调用 destroy(),避免路由切换后保留后处理阶段。

天气实验室为每种效果提供可编辑代码。左侧展开代码面板后,可直接修改参数并使用 Ctrl + Enter 重新运行。六类案例统一采用低空斜视镜头,并保留地平线以上的天空区域,便于同时观察天气效果、空间纵深和地表底图。

雨、雪、雾的着色器结构参考并扩展自 Cesium-Examples weatherEffects.js:保留屏幕空间雨线、多尺度雪层和深度雾的思路,同时适配 Cesium 1.118 的 WebGL 2 后处理语法,并将固定常量改为可更新的 uniform。

基于 Apache-2.0 许可发布