刘芮,张建伟,谭诗瀚
(四川大学视觉合成图形图像技术国防重点学科实验室,成都610065)
自然环境复杂多变,对于自然环境的模拟一直是虚拟现实中实现的难点之一,在各自然环境的模拟中,云层的绘制最为困难,首先,云是由大气中的水汽、凝露等经过液化形成,在天空中随处可见,形成过程随机,模拟困难;其次,云是没有颜色的,由于云是由大量水滴组成,光照射进云层时会发生各种散射和吸收,最后汇成云的常见色:白色,而随着云层加厚,云层的透射率降低,所以穿出云层的光照减少,会呈现灰色;同时云本身也有各种种类,积雨云、层云、卷云等,云层种类不同所处大气层中的高度也不尽相同;最后,云在空中不是一层不变的,它会随着比如风的吹动而移动,也会随着时间早上至晚上的形状不一颜色不一,运动轨迹难以揣测。由上可知,云层的模拟是虚拟场景模拟的一大难点。
本文的目的是研究并实现一种实时呈现逼真的云技术,在实时的场景下,快速生成大量的云层,噪音是生成随机物体的一种方式,而云是大自然中随机生成的物质,可二者结合,在模拟过程中,使用噪音算法建立云的模型。同时为了模拟真实的光照,使用光线行进算法对模拟的噪音云层进行采样,累积颜色值,绘制在视线前,如此也可实现较为真实的穿云效果。
根据以上分析,对于云的模拟有三个大点,一是云的建模,二是云的光照模式,三是云层的移动。最初对于云建模的研究是平面绘制,适用于远距离观察,如今发展中分为了两种主要方法,物理方法和非物理方法。
2000 年Dobashi 等人使用元胞自动机绘制云,给云添加三种属性:湿度、是否存在云和是否云有变形,该方法是很有效的物理方法[1];2003 年Harris 等人是基于体素模型上模拟云,通过求解物理方程流体力学、热力学、浮力和云变形的偏微分方程模拟云[2];2013 年唐勇等人通过温度计算热浮力模拟云,使用Navier-Stokes 方程表示云的聚散和运动[3];2017 年Duarte 和Gomes 使用SkewT/LogP 图模拟云,只计算云的热力学,不求解云运动的微分方程[4]。
1983 年Perlin 提出了使用Perlin 噪音模拟云[5];1985 年Gardner 等人用空心椭圆体结合纹理模拟云[6];2016 年Schneider 等人结合Worley 噪音和Perlin 噪音,使用光线步进技术在动态光照下模拟云[7];2018 年柏靖云实现了球形粒子建模云和噪音纹理建模云,并进行对比和分析[8]。
云的光照模式也是影响云层真实度的重要元素,云的外观是由于水分子就会聚集在空气中的微尘周围,由此产生的水滴或冰晶将阳光散射到各个方向,所以云中存在单次散射和多次散射以及多重各向异性散射。
1982 年,Blinn 提出一个光的反射和投射的见到那模型,开始了研究云与光之间的相互作用[9];1984 年,Kajiya 等人提出了将单次散射和多次散射结合的方式模拟云的光照,进一步提升了真实度;2001 年Harris 等人提出各向异性散射,预处理这些散射,云层光照的模拟更加的有层次;2016 年Schneider 等人提出糖霜理论,云的边缘有暗色,就像糖堆在一起,云的自阴影使大规模云层的绘制更具真实性[7]。
云在形成过程中,首先在太阳的照射下,地面加热,然后空气加热,由于热浮力,会产生上升气流,接着会冷却,空气中的水蒸气便会凝结产生云。云在发生相变时,会产生额外的浮力,云便会随之运动,因此云的移动也是难以捉摸。通常使用Navier-Stokes 方程来描述烟和云等不可压缩的物体运动。
Dobashi 等人提出改变现有的演化规则,将变化沿着水平面的固定方向发展,模拟云的运动,同时引入消散变量等规则,模拟云的消散[10];Miyazaki 等人考虑了云的粘度和压力、水蒸气扩散、热浮力等因素的影响,利用CML 模拟云的运动。
大自然中的云都是随机生成的,为了模拟这种效果,大多采用Perlin 噪音算法进行模拟,可用于生成地形、水和云等效果。但在图形学的发展中,有学者提出Perlin 噪音的改进,使用单性的特性解决了Perlin 噪音的伪影问题,使其生成各种效果更加真实。二者皆是使用晶格噪音,但Simplex 噪音的优势便是在随着维度的增加顶点数只增加一个,所以Simplex 噪音大大降低了计算开销。
而其中云的建模使用的是Worley 噪音,依据的是空间分割理论,在空间中,随机防止若干的特征点,对任意输入的一点,计算其点到所有特征点的距离,而这个距离值的最小值便是最后的噪音值,在Worley 的优化下,将算法细化为六步,第一,确定任意输入一点所在晶胞;第二,对此晶胞生成可重复的随机数;第三,计算此晶胞中特征点的数量;第四,随机将30%左右的特征点输入到晶胞中;第五,计算输入点到其所有特征点的距离最小值;第六,查询并计算输入点到所在晶胞直接相邻晶胞特征点的距离最小值,与第五种对比返回最小值,使其更加的实用。
当光照照射到物体表面时,一些会被物体表面吸收,其他的会被反射,而对于透明的物体,还会有一些会穿过透明体产生透射光。其中只有反射光和透射光可以进入眼睛,产生视觉效果,所以物体表面光照颜色是由入射光、物体材质,以及材质和光的交互规律共同决定的。由此产生Lambert 模型,Phong 模以及Blinn-Phong 模型。
当一束光从云层的一端射入,也会发生吸收、反射,由于光是无数小水滴组成,还会发生散射、折射以及透射光,就会在云的另一端射出,在经过云层内部后,光的强度会有所减弱。为模拟这种现象,可使用Beer 定律来计算光通过一种材料的衰弱,根据光学厚度计算其透射率,用在云层中,便可沿着光线累积其光学厚度。
在大气层中,除开被吸收的光照,散射也有很多种,主要是瑞利散射,但云是由无数小水滴构成,其中存在最多的便是米氏散射,为方便计算可使用近似求解的Henyey-Greenstein 相位函数来模拟米氏散射前向散射的效果,同时计算难度对比米氏散射大大降低。
体积渲染可以计算真的光照模型,既可以提高云层模拟的真实性还可以提高其物理真实性[11]。当然体积渲染也是有很多种方法的,大多都是需要结合物体建模方法和光照模型。所以对于云这种异质介质,可以使用光线行进算法,对生成的3D 噪音进行采样,绘制在屏幕上,其核心思想是首先有一个体纹理,然后以视点方向发射出n 条射线向外以一个采样步长行进,当射线处在体纹理中时,每一个步长行进后计算颜色值,计算光照,最后将射线当前累积的颜色值累积,直到颜色值达到最大或光线到达云层边界。
本文实验使用设备是笔记本电脑,处理器Intel i5 9300H 2.40GHz,显卡是NVIDIA GeForce GTX1650,渲染环境是Unity3D 2019。
由以上理论结合,在场景中创建一个绘制云的长方体区域,使用Simplex 噪音算法生成一张噪音图以显示有无云区域,再采样Worley 噪音算法生成132×132×132 的3D 噪音图,其中RGBA 四个通道是不同频率的Worley 噪音,如图1 所示。
图1 132×132×132 3D噪音图
再从视点射出的射线判断与长方体的距离,计算是否处于区域内,在区域内可直接根据步长采样,不在区域内便求取与长方体的交点再根据步长采样,采样时为了模拟云层在自然中的自然生成和消散过程,在场景加载后随着时间改变采样值。最后在Ray-marching 算法采样过程中计算beer 定律和HG 相位函数模拟光照,累积获取最终颜色值,绘制在屏幕上,如图2所示。
图2 只有一张3D噪音绘制的云层
如此绘制出的云层边缘圆滑,而真实的云边缘会四散开来,于是再使用Worley 噪音算法生成64×64×64的3D 噪音图,RGB 三个通道是不同频率的Worley 噪音,如图3 所示,在采样132×132×132 的3D 噪音时减去64×64×64 的3D 噪音使生成的云层边缘四散,更加真实,如图4 所示。
图3 64×64×64 3D噪音图
图4 两张3D噪音绘制的云层
本文的目的是研究并实现一种实时呈现逼真的云技术,使用一张2D 噪音预计算云会出现得位置,再对3D 噪音采样累积颜色值进行云建模,然后使用raymarching 算法绘制真实的体积云,最后云的光照模型采用Mie 散射、HG 相位函数在ray-marching 算法中累积呈现。
在绘制云层上使用噪音生成随机物质的技术虽较为成熟,但是在云的光照模拟和云层在大气层的分布上存在不少还没有解决的问题,光照使用的都是类似函数,如果能计算米氏散射,云的真实性将更进一步提升,云在大气层中的分布除了高低区分还有形状区分,全都实时绘制也是一大难点,这些都还需要进一步的研究与探讨。