Fog 雾效
🎽

Fog 雾效

notion image

Depth Fog

notion image
从眼睛看过去,随距离,透明度下降。
一般设一个起始点,一开始没有 fog,一定远 fog 到达最大值。实际上大家喜欢用二阶指数型 fog。
这是最简单的模型,现在商用引擎雾效默认的大多都是这个模型。
但这个 fog 对世界表达力还是有限的,因为真实世界 fog 是有高度的,例如气溶胶。

Height Fog

notion image
气溶胶有时候会沉淀在靠近地面的地方,特别是爬山,山脚有 fog,山顶没有。
例如恐怖的场景,下面有毒雾。
fog 是有最大值。当 fog 高度低于某个高度的时候,都是这个最大值。高于的时候,我们认为 fog 强度是以指数在递减。
💡
当人站在特定高度,假如比 fog 高度高一点,看 fog 里面的东西,那么看到的 fog 强度应该是多少?
这个问题不简单,是因为不是简单算物体那一点的 fog 是多少就能算出来的,因为 fog 在某一个高度之后距离人越近强度越低。因此它不是一个简单的云质的 fog。
前面讲天空和大气的时候,就提到只能 ray marching 进行积分。
我们以前的时候不能在 pixel shader 一点一点积分,太耗了。大家后来发现 fog 透明度是线性相关的,因此可以沿着路径,只对浓度进行线性积分,算出浓度值,估算透明度。
如果一个函数都是 e 的自然对数函数,进行积分求导的时候,可以求出它的解析解。真实计算的时候,我们只需要将解析解代进去即可。
一些数学细节:眼睛在 fog 的高面以下和以上,物体在 fog 的高面以下和以上都是有区别的,fog 给的颜色在这个过程中也是一个积分值。

Voxel-based Volumetric Fog

十年前的游戏 Depth fog、Height Fog 够用了。
但现代多用这种体素化的 fog。
notion image
当一道光射出来的时候,我能看到一束束光射出来。
这种效果 Depth fog、Height Fog 是实现不了的,其实是根据相机空间进行 voxelize,这种 voxelize 和均匀的体素化不太一样。从人眼看过去,近处的精度不够的,颗粒度太大;远处的时候,颗粒度又太细,产生不了想要的效果。因此人们想到根据近平面远平面,用视锥进行切分。上图左上可以看到,离眼睛近的地方切的非常密,远的地方切的非常疏。
因此就是在这种不规则的 Grid 里面进行 ray marching 等计算,这种计算和我们上节课讲的云、Sky 的方法是大同小异的。只要把上节课怎么算大气的部分看明白了,就知道 Fog 怎么算了。
在实际的工程中,我们会构建一个 3D 的 Texture,去存所有的中间计算的结果。
上图上中部分,显示这个 3D Texture 的分辨率是横 160 竖 90 深度 64/128。这个横竖实际上是 16:9 是屏幕的分辨率比例。这样我们尽量保证对屏幕的一个像素块的采样是一致的,这样采样出的线条或结构才比较好看。