在开发专注于海上探索的游戏《Around The World》时,Thomas ten Cate 一直在完善天空和云朵的视觉保真度。一个主要的挑战在于模拟光线与云层的交互。最初使用来自 Povray 渲染器的查找表(LUT)时,ten Cate 发现云层底部缺乏适当的亮度。他怀疑 Povray 没有模拟多重散射——即光线在粒子之间多次反弹——并通过使用 Rust 编写自定义的多线程递归蒙特卡罗射线追踪器确认了这一点。新数据表明,通过多重散射,光线分布更加均匀,消除了“金属感”,并使云底看起来明显更亮且更柔和。

使用旧查找表渲染的云层,呈现出金属感。
使用原始查找表渲染的云层,由于缺乏适当的多重散射而效果欠佳。frozenfractal.com

这张图片展示了最初的挑战:由于缺乏多重散射模拟,云层缺乏适当的亮度且具有“金属感”。

使用更新后的照明数据在游戏引擎中渲染的云层。
使用新数据渲染的云层,显示出更均匀的光分布和更柔和的底部。frozenfractal.com

这张图片展示了在实现自定义多线程递归蒙特卡罗射线追踪器以模拟多重散射后的改进效果。

为了实现真实的着色,ten Cate 处理了云层如何接收来自周围天空的间接光的问题。在 Godot 游戏引擎中,间接光通常根据表面的法线从环境立方图中采样。然而,对于云层,向下指向的法线(指向地面)会导致底部几乎没有间接光。通过调整法线使其向上指向天空,云层开始吸收大气中的蓝色调。这同时也改善了日落的渲染效果:通过将红色的直接阳光与蓝色的间接天空光混合,云层呈现出粉红色调,更准确地反映了现实世界的大气状况。

为了修正渲染伪影,还采用了几种技术上的“技巧”。为了修复由于射线步进(raymarch)中的操作顺序(即在应用入散射之前先应用出散射)导致的异常黄色地平线,ten Cate 反转了序列以减少过度衰减。此外,由于游戏中的行星比地球小 75 倍,地平线弯曲更剧烈,导致天空着色器在大气密度似乎向行星中心增加的地方产生一条暗带。他通过在重新归一化之前,给全局视角向量的垂直分量添加一个微小值来修正这一问题,有效地将天空“拉低”以与物理地平线对齐。最后,他实现了一个白点为 2.0 的 Filmic 色调映射器来管理高动态范围(HDR)数值,确保云朵平滑地融入远方而不会过度饱和。

蓝色的天空在靠近地平线处褪色成明显的黄色带。
由于射线步进操作顺序错误导致的异常黄色地平线示例。frozenfractal.com

这张图片描绘了在射线步进序列中先应用出散射而非入散射所导致的渲染伪影。

蓝色的天空在靠近地平线处褪色成白色调。
反转射线步进序列以减少过度衰减后修正的地平线。frozenfractal.com

这张图片展示了通过调整射线步进中的操作顺序来修复黄色地平线伪影的方案。

太阳低垂在天空中的场景,天空有一块固定的淡黄色区域。
在实施 Filmic 色调映射器之前的场景。frozenfractal.com

这张图片展示了在应用 Filmic 色调映射器管理 HDR 数值之前的动态范围问题。

太阳低垂在天空中的场景,地平线附近有平滑的渐变。
使用 Filmic 色调映射器确保远方平滑过渡的最终结果。frozenfractal.com

这张图片展示了 Filmic 色调映射器的最终效果,确保云朵平滑褪色且不会过度饱和。