大白话聊体积云——软光栅下体积云理论与实现(一)

Yuri
发布于

故乡的云

我喜欢在游戏里面看夕阳。

残阳如血,看云卷云舒,特别减压。


来自利维亚某不知名的名侦探


未来如果真的有元宇宙,希望能在遥远的异乡戴上VR看一下午故乡的云,希望这云能来带故乡泥土的芬芳。


学习过games104之后,也听说了许许多多的现有方案:片面云、体积云、模型云等等,抛去这些术语,回到初始的目标:云要怎么渲染呢?


云有特别的视觉表现,与金属、木头等等固体的渲染表现差距很大,直觉上来看与使用Blinn-Phong、Mircrofact这样的表面反射模型来描述的材质有很大差距。

云有“气体”的感觉,我们似乎需要一种新的模型,能够像描述塑料或金属那样,对“云”这种材质进行描述。


王希老师说“凡事不定上拟合”,那么要拟合出云的材质就需要先解决一个问题:云 是什么?是什么样的内部结构构成了这种材质?


材质建模

高中物理书上说 “云是空气中凝结的水滴集合体”。

云中包括了水滴、冰晶、各种气溶胶

内部结构明确了,现在来看只要能拟合出光线在云内部这些水滴中是怎么传递的,就能拿到成像效果。


“拟合光照怎么在水滴中传递” 这话听起来好像,说了很多,又似乎好像什么都没说。

拆一下句子。

谓语是“传递”,光会反射、折射、透射、散射... 这该怎么确定呢?


状语是 “在水滴中”,这问题就更大了:

  1. 水滴有多少个?
  2. 水滴有多大?
  3. 什么时候在水滴中?什么时候不在?


一片云有多少水就像人有多少头发一样,怎么可能精确的知道?

每个水滴可大可小,还和温度相关,这又怎么可能知道?

气体边界模糊多变,这又双叒叕怎么可能知道?


王希老师曾经说非常羡慕老天爷有无穷的算力无穷的内存,不仅如此老天爷还有无穷的精度。

上面的问题对于人力全是问题,对于老天爷都有确定精确的数据,全都不是问题。


精度不够,统计来凑。图形学里处处都有approximation。


统计方法下的云

第一个问题:云里面有多少水滴?

云里面的水滴必然是无序的分布在整个云中的,当视线进入云的大致范围后,可能会碰到可能碰不到,由于没办法真的去模拟光线在分子中的交互行为。但是我们知道视线总是能碰到水滴的,不如就分而治之把一大块云拆成特别小的立方体,在这个小立方体中,视线总是有概率能碰到水滴的。

虽然切成了立方体,看起来对的那就是对的


这个概率可以描述为:当视线作为射线传播了足够多的单位时间t 后,一定会碰到一次水分子。那么每次单位时间都有1/t的概率能碰到。

只要前进的次数够多,总能碰到的


采用概率统计的方法我们就可以绕过复杂的分子结构,不用陷入定义具体分子位置的泥沼中,反正我们知道了一条视线穿过,总能碰到若干个分子,所有的光线加起来也就是云里面有多少水滴了。


第二个问题:水滴有多大

在上面我们已经把云拆成了一个个的小立方体,为了后续方便说明,我们就叫小立方体体素吧(Voxel)因为立方体就像三维的像素一样,通过离散的堆叠形成了一个物体。

类似三维的像素的感觉


在每个体素中,已经有一个隐含的假设,即每个体素的碰撞水分子概率是相同的,每个体素中的水滴都是相同大小。这都是approximation的处理之一,当然也可以有一张表记录每个体素的具体概率,这里先按下不表。


第三个问题:水滴的边界

这里设想一种极端情况,这个云特别乖,就是一个正方体,所有的体素都会规规矩矩的排列成一个正方体的样子,这样就可以用描述固体金属一类的方法来描述云,它有一个几何形状是一个cube,外表材质是完全的透明的,所有的视线都会正常的穿过,没有任何折射率。


终于我们完成了 云 这个材质的基本定义,解决了怎么描述“在云中”的问题,还有一个遗留问题:光线碰到云中的水滴之后,会发生什么?


散射效果


在聊光线碰到水分子这种复杂话题之前,我们可以先聊一个更加通用的话题,光线碰到金属会怎么样?

物理课上老师说过:

“金属的原子排列紧密有序,包围着许多电子,自由电子活动非常活跃”

电子非常活跃就会导致光线刚与金属表面发生交互,就会立刻被电子排斥,大部分光线立刻被电子反射或者吸收,只有极小部分能再继续前进一点。

所以金属这类材质只需要考虑反射的光照模型就足够了,其他的效果可以小到忽略不计,在材质实现上使用BRDF描述就足够。

来自点石渲染器

但是云完全不是这样,水分子中的电子相对金属更为稳定,并不能完全阻挡光线,虽然也能吸收一些光线能量但也不多,所以对于水这样的液体,相对于镜面反射更多会向各个方向反射,所以至少存在两种光照模型,反射与透射,统称为散射,在材质实现上使用BSDF描述。

水的散射并不像金属那么镜面


那么光会在云中怎么散射呢?天上的云形态各异,抽象来说有四种情况:


  1. Absorption

乌云的效果。

阳光发出了光线,但是并没有照亮云,反而形成了黑色的乌云,是云中的分子吸收了很多光线的能量(转换为了热能等其他能量),所以到达人眼的时候能量很少,于是就是黑色。


d是光线传播的方向 x为云中水滴,下同

一块只有absorption的云


2. Emssion

因为温度等条件的变化,物体也会释放自身的能量,会像光源一样照亮其他物体


热烟毕竟也算是一种云


  1. in-scatter 、outscattering

阳光洒在云上,让整个云变亮,光线穿过一些分子后也会碰到其他 的分子会进行反射,向整个云的各个方向进行反射。同样对于其他的分子,也有其他分子反射过来的光会与其相交,最终让达到的能量更多一些。



一块只有scattering效果的云。in-scattering还是out-scattering 多取决于方向


这样我们就完成了材质的边界、交互方式的定义,看起来可以开始实现 “云”了。

后面还会遇到哪些未曾设想的问题?如何把想法集成到Picoolo引擎的系统?

本周内更新。 欢迎大家点赞催更。


如有错误之处,恳请大家批评指正,学习交流。


---

第二部分更新:  大白话聊体积云——软光栅下体积云理论与实现(二)

第三部分更新: 大白话聊体积云——软光栅下体积云理论与实现(三)

已完结。

10
评论 1
收藏 3
  • MR7
    MR7
    好棒!期待更新~