系列传送门:
山海鲸可视化:GIS 融合之路(一)技术选型 CesiumJS/loaders.gl/iTowns?
山海鲸可视化:GIS 融合之路(二)CesiumJS 和 ThreeJS 深度缓冲区整合
山海鲸可视化:GIS 融合之路(三)CesiumJS 和 ThreeJS 相机同步
山海鲸可视化:GIS 融合之路(四)如何用 CesiumJS 做出 Cesium For Unreal 的效果
山海鲸可视化:GIS 融合之路(五)给 CesiumJS 加上体积云(Volumetric Cloud)和高度雾(Height Fog)
山海鲸可视化:GIS 融合之路(六)-Cesium 的雨雪风雷电效果
本来没打算写到第七篇,但最近山海鲸的 GIS 夜景被同事们吐槽的厉害,说 GIS 白天很不错,但是夜景效果很一般。人嘛,一定要知耻而后勇。在严词拒绝了同事们升级夜空的诉求之后,便默默地开始了夜空渲染的研究。
开始之前我们还是有必要先回顾一下山海鲸中 Cesium 整合天空各个元素的效果:
白天效果
夕阳效果
要知道,山海鲸是完全基于 WebGL 的渲染引擎,特效全靠手搓,而目前白天完全可以比肩游戏引擎的视觉能力了(这里必须吐槽一下那些套壳 UE 的同行,明明底层就用 UE,竟然好意思说自己比 UE 好)。
好了,咱们正式进入正文,话说在之前的技术调研中,写白天大气散射和体积云渲染的文章可以说是多如牛毛,具体可以参考我前面的系列文章,但写夜空渲染的文章竟然一个没有。同时 UE 和 Unity 似乎也对夜空渲染不感兴趣,在官方的天空中都没有整合夜空的逻辑。UE 新版大气散射的介绍视频中倒是提了一句“如果要做夜空只需要整合一张星空贴图即可”,Unity 的官方 Roadmap 中也有提到说很难用基于物理的方式来实现夜空,因此打算提供一些艺术家向的设置来实现夜空的渲染。真正有意义的也只有几篇关于夜空渲染的论文,却也没有见到什么像样的代码实现。
在开始之前,我们先讨论一个问题,为什么夜空的渲染文章这么少呢?我想主要有以下几个方面的原因:
也就是说费劲巴拉的真的按照物理方式去渲染夜空可能还不如改改艺术向设置让人觉得真实,还更卡。这里也可见计算机图形学第一定律在发挥作用了:如果它看上去是对的,那么它就是对的。
那山海鲸还做不做夜空渲染呢?那肯定还是要做的。我们的产品理念是要帮用户把复杂的技术细节屏蔽掉,我们的用户和游戏引擎的用户不一样,游戏引擎可以要求用户去改亮度,改大气散射粒子浓度,而山海鲸则希望客户什么都不改就能用。因此我们还是得从目前仅有的论文开始看起:
对于渲染来说,最重要的是光源。那么我们先看下夜晚的光源都有些什么,这里我们贴一下论文中的天空光源强度和光源类型:
从左至右分别是黄道光、星光和气辉
可以看到,满月相对其他夜空光源来说是具有统治地位的,而黄道光、星光和气辉逐步降低,再往后我都不知道是啥了。这里我们要发挥一下图形学神功的精髓——大胆而无耻的假设,除了月光,其他就先当做不存在。
好了做完的这个假设,问题变的简单了。夜空和日空是很类似的,单光源结合大气散射即可,是不是可以直接复用日空的代码,把亮度调小 10 的六次方即可呢?显然这里还有两个细节问题值得探讨:
做了这么多无耻的假设,我们终于可以用极小的成本适配夜空了。但目前做的本质上和艺术向的设置没有区别,只是调暗主光源光强即可,当然我们需要同步适配大气散射和高度雾的光强。调完之后,我们看下现在的效果:
看着还算可以接受夜空效果
我们把体积云也调整好光强后叠加上来:
加上体积云的夜空
现在的夜空基本已经到了可以勉强接受的范围,但没有月亮和星星的夜空是没有灵魂的,那么我们先参照 UE 视频中的说法:在夜空的基础上叠加星空 Cubemap,同时我们用一个remap 函数来控制星空的稠密程度:
1 | nightLuminance += smoothstep(vec3(1. - starry),vec3(1.),starLuminance); |
叠加后的效果如下:
叠加星空后的效果
最后我们再实现月亮,月光的光照其实就是一个简单的球体,如下:
我们这里为了整合在天空中一起渲染,因此不能单独用一个球来贴图。我们通过RayIntercept 函数来处理球体的渲染:具体是先计算好 Ray 和月球的交点后,再用交点计算当前点位的法线,最后通过控制 incoming light 的方向来实现月相效果。为了能让大家更好的观察月亮,我们还提供了一个放大月球的功能,效果如下:
月亮升起
月相变化
月球放大,可以看到通过法线实现的环形山效果
到这一步,夜空基本就已经实现完了。最后还有一个小细节,那就是实际上在夕阳的时候,我们就已经能够看到星空了,不是一定要等到晚上才有。因此我们在太阳接近落山的时候,就选择开始叠加星空贴图:
这样可以进一步增强清晨和黄昏的视觉层次感。到此,整个山海鲸的夜空实现就已经全部完成了,而空气透视和 Cesium 系统已经自动叠加,因此不需要再做更多的处理就可以很好的和GIS 系统融合在了一起。
当然还有很多工作值得进一步来做,例如: