GIS融合之路(五)给CesiumJS加上体积云(Volumetric Cloud)和高度雾(Height Fog)

发布时间 2023-07-06 14:28:35作者: 山海鲸可视化

同样在这篇文章开始前重申一下,山海鲸并没有使用ThreeJS引擎。但由于ThreeJS引擎使用广泛,下文中直接用ThreeJS同CesiumJS的整合方案代替山海鲸中3D引擎和CesiumJS整合。

系列传送门:

同样在这篇文章开始前重申一下,山海鲸并没有使用ThreeJS引擎。但由于ThreeJS引擎使用广泛,下文中直接用ThreeJS同CesiumJS的整合方案代替山海鲸中3D引擎和CesiumJS整合。

系列传送门:

山海鲸可视化:GIS融合之路(一)技术选型CesiumJS/loaders.gl/iTowns?

山海鲸可视化:GIS融合之路(二)CesiumJS和ThreeJS深度缓冲区整合

山海鲸可视化:GIS融合之路(三)CesiumJS和ThreeJS相机同步

山海鲸可视化:GIS融合之路(四)如何用CesiumJS做出Cesium For Unreal的效果

上一篇文章我们已经将大气散射和空气透视的效果整合到了CesiumJS之上,不过真实感渲染除了大气部分,还有体积云和高度雾。照例我们先看下山海鲸中的效果图

山海鲸体积云效果

山海鲸高度雾效果

具体山海鲸中的效果和设置教程可以移步这个的视频教程的前半部分的内容:

https://www.bilibili.com/video/BV1es4y1r7L1/

感兴趣朋友也欢迎下载软件试一试:山海鲸可视化-一站式数字孪生开发平台-海量数据可视化大屏模板

相比于大气散射来说,体积云可以说要复杂的多,主要复杂在以下几个方面:

1.体积云包含建模和光照两个方面。

2.体积云需要和大气散射,空气透视,高度雾进行融合。

3.由于云的多样性,因此体积云需要同时考虑易用性和灵活性。

4.体积云由于性能问题,需要大量的性能优化方案。

实际上,体积云也已经有了海量的文章在解释如果去建模和光照了,我也大体给大家总结一下方案的脉络。

体积云目前的方案主要是由地平线最先提出,后期经过寒霜,荒野大镖客等引擎或3A游戏的进一步完善,逐渐形成了一套标准的方案。就是通过Worley-Perlin噪声贴图进行建模,同时使用太阳和大气对体积云进行光照计算。

除了几篇英文的ppt分享外,比较推荐大家去看网易这篇分享文章,基本综述了当前的体积云算法,同时也非常全面,我就不再重复技术细节了:

网易游戏雷火事业群:体积云效果的实现,游戏世界的云合雾集

这套基本的逻辑还是比较容易实现了,我们看下山海鲸中体积云的建模效果和光照效果:

山海鲸中体积云效果

补充一下在山海鲸中体积云的实现的一些具体的要点:

1.首先同样如上一篇系列教程提到的,由于Webgl中不支持ComputeShader,由于体积云采用Temporal Reprojection和Bilateral Upsample,因此过程中需要大量用到ComputeShader,此处在webgl上都得用ScreenViewQuad进行代替。

2.云影的实现;大部分文章并没有提及云影。不过这块实现相对简单,只需要采用太阳光的角度再渲染一张正交投影的深度贴图,渲染过程中值得注意的是要设定好合适的贴图分辨率和渲染的空间范围。另外在体积云建模过程中,需要注意调低步进次数,只需保证大体的质量即可。

3.体积云实时反射;参考云影的实现,由于山海鲸数字孪生项目中大部分有玻璃和水面都需要去反射天空和体积云,因此仅使用平面反射是不够的。同时需要参考UE中的实时天光抓取,因此山海鲸中的天空和体积云的实时反射是直接抓取天空的Cubemap之后再做实时滤波去计算漫反射部分的光照。这样反射虽然需要渲染6次,但可以作为多个不同物体以及不同角度的反射,同时还可以直接获取天光作为场景中的环境光补充。

4.关于云的环境光照部分,Unity中是直接抓取环境的球谐并采样顶底颜色,这样处理之后云底颜色过于受到地面的影响。因此我们采用UE中两个环境光照中相对简单的方案,就是只要采用海拔6km处积分结果的distantskylut中的颜色直接作为环境光照。

说完了体积云之后,我们看下指数高度雾。上一篇文章已经提到过了,大气散射已经是高度指数雾了,无论是瑞丽散射和米氏散射的密度分布都是高度指数递减的,为什么我们还要再加上高度指数雾呢?实际上因为两点:

1.可以增加复杂的密度分布函数,目前山海鲸和UE一样,提供了两级高度雾,在叠加大气散射中的米氏分布函数,可以提供很复杂的密度分布函数。更容易模拟山间的云雾密度。

2.可以增加颜色的更灵活的设置,高度雾的颜色默认也是使用DistantSkyLut中的颜色进行动态光照的,但可以对每一级的雾的inscattering的颜色进行单独设置,实现更加灵活的雾的色彩控制。

OK,我们将体积云和高度雾实现了之后,同样和上一篇文章一样,我们叠加到CesiumJS中只需要使用Cesium Color Texture和Cesium Depth Texture两张贴图即可实现体积云和高度雾的叠加。

到这一步位置,我们基本上将天空部分的效果整合完毕了,下一步我们就看一下如何结合天空来实现Cesium中的雨雪效果和雨雪覆盖。