APP下载

基于OpenGL细分着色器的实时爆炸模拟

2018-11-20全伟衡

现代计算机 2018年30期
关键词:球面球体视线

全伟衡

(四川大学计算机学院,成都 610065)

0 引言

现今,无论是在游戏场景还是影视特技等领域中,爆炸特效无疑增强了其视觉效果。而在爆炸过程中,爆炸球体的不规则性以及爆炸之后所产生的烟雾的离散性都增加了模拟工作的难度。

爆炸特效的模拟可视为一种特殊的流体模拟,目前爆炸模拟方法主要有以下三个:数字物理模拟[10-11]、粒子系统模拟[6-7]、过程纹理模拟[8-9]。其中数字物理模拟方法主要是通过求解Navier-Stokes方程来得到所需数据,该方法模拟过程复杂且计算量大;粒子系统模拟是利用大量的粒子模拟爆炸特效状态,但这种方法在摄像机漫游的场景中很难得到真实立体的爆炸效果。过程纹理模拟是一种从爆炸特效的外观和人类视觉角度分析、简化的快速算法,此方法的最大缺陷在于对于每一种新的纹理都需要大量时间去调参来获得合适的函数。

而在GPU PRO6一书中由Alex[1]提出了一种基于DirectX以及体积渲染技术的实时爆炸模拟。但文中重点强调的是爆炸球体的产生及色彩模拟,而在虚拟战场中的爆炸需要的是一个完整的爆炸过程:球体由小变大至最激烈时刻爆炸,之后球体破散成烟雾状消散。Alex所提出的方法虽然能比较真实地模拟球体表面随局部爆炸剧烈变化的效果,但此方法所模拟出来的烟雾难以形成爆炸后的烟雾消散的状态。

通过研究,充分结合了过程纹理与Alex所提出的体积化渲染方法,实现了对虚拟战场有一定应用价值的爆炸模拟。

1 爆炸模拟概述

对于爆炸模拟的整体流程,此次共分为三个部分:产生爆炸球体、为球体着色,以及产生爆炸烟雾。此节给出了每个阶段的算法思路。

1.1 生成爆炸球体

现实的爆炸瞬间所产生的体积形状类似球体,其表面并不像普通球面那么光滑,而是会有一些凹凸,从而形成爆炸的层次感。

此阶段产生爆炸球体是利用OpenGL中的细分着色器的特性来产生一系列顶点,而不需要额外的外部顶点输入,接着用球面坐标系的特性将所生成的一系列的顶点映射到虚拟的单位球面,这样即可产生一个光滑的球面。

有了球面之后则只需要将其表面制造凹凸感,以使球体更贴近现实中爆炸球体。生成爆炸球体所用的方法为利用噪声函数为每一个顶点生成一个噪声值,之后将顶点沿着顶点到球心的方向偏移一段距离,此段距离受上述的噪声值影响,从而形成球面凹凸的效果。

1.2 球体着色

爆炸球体的着色大致可分为三个阶段。第一个阶段时,爆炸球体为炙白高亮,并且球体慢慢增大;第二个阶段时,爆炸球体为白、黄、红的混合色,并会出现刺眼的黄或红色;第三个阶段时,爆炸球体为黄、红、灰的混合色,且颜色会向全灰色转变,接着会出现球体的破散从而形成烟雾。

由于爆炸整个过程,每个顶点或是整个球体,其颜色的混合并不是固定的。因此在渲染爆炸球体颜色的时候,为球体着色采用噪声来影响颜色梯度纹理采样坐标,从而使得球体表面颜色能够随时间不断变化,由此来体现不同的爆炸阶段。

1.3 生成爆炸消散效果

现实中的爆炸,在球体高亮之后将转为灰色,并且球体将会随机破散,最终形成离散的烟雾。烟雾离散的特性可以借助OpenGL中Shader的特有变量来进行实现。

2 生成爆炸球体

Tessellation阶段是OpenGL渲染管道中的顶点处理阶段,这个阶段由细分控制着色器和细分计算着色器及固定功能阶段组成。OpenGL中的细分着色器一般作用为:将一个图元,如三角形、线等的内部继续细分,增加其细节,使得其几何特性更加明显。例如:外部输入一条直线,通过细分着色器可以产生一系列的顶点并通过算法映射到所期望得到的曲线上,最终则可以将一条直线变成一条曲线。爆炸球体的形成,其球体表面顶点的计算即应用了细分着色器的这个特性。

在细分控制着色器中,通过设定gl_TessLevelOuter[4]、gl_TessLevelInner[2]的值来确定一个Patch输出的顶点数总量。细分级别来决定生成的顶点数量。

首先,细分控制着色器产生一个Patch如图1。接着将Patch上的每一个点与单位球体的球面上的点相对应。当细分着色器产生的顶点越多,则球面越光滑。如图2与图3所示,不同细分等级对于球面光滑度的影响。爆炸球体并不是纯粹的球体,从现实中的观察可以知道,在爆炸时期,其爆炸几何体边缘是不规则的,常出现一些类锯齿形状。因此需要将光滑的球体表面上的每个顶点分别进行一定的偏移,使其相对位置发生改变,从而让球体表面出现凹凸感。

Simplex Noise是Ken Perlin在2001年所设计的新的噪声函数。对于爆炸球体的模拟,应用噪声函数来使爆炸球体表面变得不规则是便捷的。

对于三维Simplex Noise函数,输入为三维坐标,输出为一个浮点数,值域为[0,1]。其结果具有一定随机性,因此可利用此特性来变化球体表面。其过程如下:

在CPU中应用Simplex Noise函数,将时间作为函数输入参数,之后运行函数并将结果储存到文本文件中。此步骤目的在于提前计算出一定数量噪声值,之后将这些数据生成3维纹理,从而在爆炸模拟中,每个顶点对应的噪声值只需要通过对3维纹理进行采样来获取,不再需要进行噪声函数的运算,提高计算的效率。其次,将噪声值用单独的工程独立生成一个文本,可以减少生成噪声与爆炸模拟两个工程之间的依赖性,方便在后续可以进行噪声的优化和替换工作。

图1 细分着色器Patch

图2 内外细分等级8

图3 内外细分等级16

3 爆炸球体着色

在现实中,人眼所看到爆炸球体的颜色并不仅仅是其表面的颜色。爆炸由内向外,最终人眼所见的颜色应该是视线与爆炸表面相交的两个交点之间区域上的颜色的混合体,如图4。

图4 视线与球体相交

图5 计算视线出点

图6 着色纹理

图中P1为视线入点,P2为视线出点。最终P1位置呈现到人眼中的颜色应该为P1到P2线上所有颜色的一种混合,这种着色的方法被称作Ray-Marching。

本文使用的Ray-Marching算法是以P1点为起点,P2点为终点,且每次行进的距离是一个固定值,称之为固定步长,其总步数即为P1到P2之间的距离与固定步长的商。最终颜色等于每一步颜色的权重和。

Ray-Marching方法关键在于找出视线与球体的出点和颜色的混合函数。

由于爆炸几何体并不是一个完全对称的球体,难以观察到一些有效的几何特征来辅助计算,即使在已知视点与爆炸体表面的一个顶点的情况下,求得视线与球体的精确出点仍然有难度。

因此在此阶段提出一个简便的、计算量小的估值方法如下:

在着色的计算阶段,随着视线的行进,其计算出来的颜色值对于最终的颜色值的贡献度将会越来越小,因此对于视线行进的后阶段可以选择性忽略,可以用视线与爆炸球体的入点(图5中的A点)到球心的向量在视线方向上的投影来替代入点到出点的距离。

图5中AC为AB向量在视线方向的投影,即以C点来替代视线的出点。对于每一次的行进所取得的颜色,本文采用的是结合颜色纹理与噪声函数的方法。目的是为了使得每个顶点在每个时刻所取得的灰度值具有一定随机性,以此来模拟爆炸球体色彩的多样性。

在Shader中,以其内置的纹理采样函数texture()对图6的颜色纹理进行采样。每次使用的采样坐标是Ray-Marching中每次行进的顶点坐标值所对应的噪声值。由此可以得到行进的每一步的灰度值。

之后Ray-Marching算法每行进一步其颜色权重减少为前一步的二分之一,即开始的一步的权重将会是最大,为0.5,之后的每一步的权重将会随步数的增加越来越小。选择此种方法来为每一步的颜色权重赋值的原因在于:Ray-Marching最开始的点,即面向人眼的半球球面上的点,其所具有的颜色是最先进入人眼,因此它的颜色对于最终的颜色的影响最大;而之后行进路线上所取得的灰度值对最终颜色的影响将会越来越小,最终效果也证明这种方法是可行的。

在得到最终着色的爆炸球体,还需要对每一个顶点所对应的噪声值进行一定处理来得到一个新的噪声值,以使每一个时刻顶点所对应的噪声值的宽度增加。因为噪声值实际上与颜色梯度图具有对应关系,当噪声值越大,所取得的灰度值将偏向图6中所示颜色梯度图的右侧的颜色,同理,当噪声值越小,其所对应的灰度值将偏向梯度图左侧的白色。故增加了噪声取值的宽度以适应颜色梯度,则可以使得在同一时刻的爆炸球面呈现出更多的颜色。

4 爆炸烟雾模拟

爆炸球体的消散效果可以借助OpenGL中Shader内置的变量gl_ClipDistance[]。

gl_ClipDistance变量是OpenGL用于向用户提供一个控制裁剪的接口,而不依赖于OpenGL的自动裁剪。gl_ClipDistance[i]指的是顶点到裁剪平面i的距离,而平面i的实例可由用户自己指定。其中距离为0.0表示顶点在平面上,距离值为正代表顶点位于裁剪平面内,距离值为负意味着顶点位于裁剪平面之外。在后续的渲染阶段,裁剪距离为负的顶点将会被裁剪,而距离大于或等于0的将会被保留。

在进行烟雾模拟时只需要控制每个顶点所对应的裁剪距离,即使用的是gl_ClipDistance[0]来控制每个顶点到裁剪平面的距离。

在默认情况下,将每个顶点所对应的gl_ClipDis⁃tance[0]设为顶点所对应的噪声值,由于噪声值范围为[0,1],因此在默认情况下,任何顶点都不会被裁剪。之后加入时间这一维度,以方便控制球体消散时刻。

5 程序运行效果

经过程序测试,在未增加任何后处理的情况下,爆炸模拟各阶段的如图7-图9。

运行程序的环境为:Intel i7 5700HQ处理器,NVIDIA GTX 980M显卡,16G内存。

当爆炸球体处于较小的状态时,调整细分等级处于较小的状态可有效提高帧率,这一阶段程序的帧率在400以上;爆炸时刻的球体色彩最多且所需顶点也较多,但此阶段平均帧率处于180以上;烟雾产生阶段其帧率会随着顶点被裁剪而逐渐增加,此阶段最低帧率在140以上。

为获得发光球体的光晕效果,在程序中加入了三次向下采样、四次高斯模糊、一次模糊图合成及一次模糊图与原图合成的后处理步骤,各阶段效率均仍在60帧以上,其效果如图10-图12。

由此可以说明所述的爆炸模拟完全满足实时渲染的要求,整个模拟包括爆炸的全过程且具有一定的真实性,完全可适用于虚拟战场中的炮弹爆炸及其他一些易爆物品的爆炸效果模拟。

图7 生成爆炸小球体

图8 生成爆炸球体

图9 爆炸球体消散

图10 后处理生成爆炸小球体

图11 后处理生成爆炸球体

图12 后处理爆炸球体消散

猜你喜欢

球面球体视线
要去就去视线尽头的山
中国“天眼”——500米口径球面射电望远镜
基于球面聚焦超声可燃工质空间定位着火研究
越来越圆的足球
计算机生成均值随机点推理三、四维球体公式和表面积公式
那座山
膜态沸腾球体水下运动减阻特性
球面距离的几种证明方法
当代视线
视线