山海鲸可视化

GIS融合之路(六)Cesium的雨雪风雷电效果

终于来到系列第六篇了,也来到大家最喜闻乐见的天气效果。

系列传送门:
山海鲸可视化:GIS 融合之路(一)技术选型 CesiumJS/loaders.gl/iTowns?
山海鲸可视化:GIS 融合之路(二)CesiumJS 和 ThreeJS 深度缓冲区整合
山海鲸可视化:GIS 融合之路(三)CesiumJS 和 ThreeJS 相机同步
山海鲸可视化:GIS 融合之路(四)如何用 CesiumJS 做出 Cesium For Unreal 的效果
山海鲸可视化:GIS 融合之路(五)给 CesiumJS 加上体积云(Volumetric Cloud)和高度雾(Height Fog)

实际上山海鲸可视化中已经有了所有的雨雪风电效果,甚至可以直接绑定实时数据来展示天气,具体可以参照隔壁文章:山海鲸可视化:山海鲸如何实现动态天气

实际上雨雪雷电本身在 Cesium 上的直接展示基本不需要做任何的特殊处理,我们可以先看下效果:
文章1.webp
GIS 下雨效果

那么和 Cesium 的整合有什么特别之处吗?
实际上雨雪的效果就是一个粒子效果的叠加,这里并没有什么值得一提的。但 Cesium 本身并不支持法线贴图的输出,雪面的覆盖是需要当前的法线的,因为法线朝上的积雪的可能性是最高的。

那么 Cesium 中获取法线信息的方式有哪几种呢?

  1. 倾斜摄影中可以直接通过CustomShader,只要转出来的3dtiles的顶点上有法线信息,就可以直接获取;
  2. 对于底图和地形,需要改写 Cesium 的源码修改Shader

对于第 1 点来说,一方面要求倾斜摄影转换的时候带了法线信息,同时也只能应用在倾斜摄影中当中;
对于第 2 点来说,侵入性修改 Cesium 会导致后续的跟随升级将带来巨大的麻烦,那么剩下的选项就只有通过后处理方式获取法线了。我们现在有的信息一张 ColorMap,一张 DepthMap,那么留给我们的选项就只有通过 dFdx 和 dFdy 来将 DepthMap 转换为法线贴图。

这个过程相对简单,我们读取 depthmap 后直接通过以下 shader 代码进行处理:

1
vec3 vNormalW = normalize( cross(dFdy( positionW.xyz ),dFdx( positionW.xyz )) );

但由于直接的 dFdx 和 dFdy 方法输出的法线非常的闪烁,因此我们还需要在这个基础上做一次降噪让法线更加的平滑。由于我们只是用法线来做雪面覆盖,并不需要十分精确,因此我们选择采用联合双边滤波的形式来进行降噪处理,我们结合 color 和 depth 在两个维度来进行滤波,最终得到一个相对稳定的雪面覆盖结果:
文章2.webp
GIS 下雪效果