基于GPU加速的油田井口事故火焰实时仿真
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
基于GPU加速的油田井口事故火焰实时仿真
刘贤梅;王伟;薛继伟
【摘要】针对基于CPU并利用粒子系统实现火焰模拟中出现粒子计算时间长、渲染效果不真实等现象,提出一种基于图形处理器(GPU)加速的油田井口事故火焰模拟方案.将火焰粒子的属性存储到纹理中,在GPU中对火焰的粒子属性进行初始化,并更新粒子的属性.分析火焰的模型,并对火焰的内焰和外焰分别进行贴图.最后使用渲染到顶点缓冲区的方法实现粒子的绘制.仿真试验结果表明,利用该方案能大幅增加场景绘制的粒子数,使火焰模拟的实时性和逼真度得到增强.
【期刊名称】《长江大学学报(自然版)理工卷》
【年(卷),期】2011(008)002
【总页数】3页(P73-75)
【关键词】图形处理器;粒子系统;火焰模拟;虚拟现实
【作者】刘贤梅;王伟;薛继伟
【作者单位】东北石油大学计算机与信息技术学院,黑龙江大庆163318;东北石油大学计算机与信息技术学院,黑龙江大庆163318;东北石油大学计算机与信息技术学院,黑龙江大庆163318
【正文语种】中文
【中图分类】TP391.41
对火焰等景物进行仿真模拟一直是计算机图形学研究中的热点课题[1]。
由于这些形状不规则物体都具有实时变化的特征,并且含有丰富的细节,因此很难用传统的
造型方法来表现。
粒子系统是模拟复杂的、运动的、不规则物体非常有效的一种图形生成技术[2]。
以往的粒子系统的计算完全是在CPU上完成的。
由于CPU的任务繁多,因此在实际运算的时候常常出现显卡等待CPU数据的情况,影响了绘制速度[3]。
针对以上问题,笔者在进行油田井口事故火焰实时仿真时将粒子系统的所有计算完全放入GPU中,在GPU中完成粒子属性的更新和绘制,不需要每次更新时从CPU中读取粒子数据进行绘制。
因此,减少了粒子系统更新中GPU和CPU之间的频繁通信、系统内存和显存间的频繁数据传送,降低CPU的负担,使粒子系统达到更高的实时性和高仿真性。
1.1 粒子的基本定义
为每个粒子定义一个顶点,目的是可以在屏幕上显示粒子的属性值,从而实现火焰的模拟。
顶点结构定义如下:
Struct Vertex
{
D3DXVECTOR3 Postion;
D3DXVECTOR2 Coords;
};
Postion是顶点最终绘制在屏幕上的位置,在Vertex Shader中对其进行赋值。
Coords是顶点所对应的属性纹理的纹理坐标。
在CPU上二维网格表现为一个数组,而在GPU中二维网格则表现为一张纹理,纹理具有GRBA 4个通道,提供了一个天然的数据结构。
最基本的运算是二维网格上数据的读取,在GPU中使用纹理查询来完成。
CPU中数组的偏移对应GPU 中纹理的纹理坐标。
根据以上分析,把粒子属性数据存储到纹理中。
油田井口事故火焰粒子中最重要的
属性是位置和速度。
由于速度精度低,使用16位的浮点格式纹理存储速度;位置的精度相对比较高,使用32位浮点格式纹理存储位置数据。
火焰粒子的其他属性如生命值、颜色值、透明度都使用16位的浮点格式纹理存储。
由于受当前图形硬件的限制,同一个纹理不能同时被写入和读出,因而更新后的属性不能存储到原有纹理中。
要解决上述问题,需要引入双缓存技术。
每个属性都需要2张具有相同大小和格式的纹理。
首先将其中一块作为输入,另一块作为输出。
在下一帧的计算中,输入缓冲区变为输出,输出缓冲区变为输入。
存储方式如图1所示。
为了计算火焰粒子运动,对每个粒子定义如下属性纹理:①2张16位的浮点格式速度纹理VelTex:分别存储前一帧和下一帧粒子的速度。
② 2张32位浮点格式
位置纹理PosTex:分别存储前一帧和下一帧粒子的位置。
③2张16位的浮点格
式生命纹理AgeTex:分别存储前一帧和下一帧粒子的生命值。
④2张16位的浮
点格式颜色纹理ColTex:分别存储前一帧和下一帧粒子的颜色值。
⑤2张16位的浮点格式透明度纹理tranTex:分别存储前一帧和下一帧粒子的透明度。
⑥1张初始位置纹理InitPosTex,存储每个粒子的初始位置。
⑦1张初始速度纹理InitVelTex,存储每个粒子的初始速度。
1.2 火焰粒子系统模型
着火极限、着火温度和燃烧速度,常统称为火焰3要素。
油田井口发生火灾具有
燃烧速度快、火焰温度高、易发生爆炸和火势极易蔓延的特点。
因此,用粒子系统模拟油田井口事故火焰时应突出上述特点。
1)火焰粒子的产生油田井口事故火焰粒子系统产生粒子的过程即对新粒子的属性
进行初始化。
在该系统中,由于火焰是从井口中产生的。
井口相当是一个圆柱体,采用了一种新的方法实现粒子的发射源,即用Y值确定井口的高度,用θ和X轴
之间的夹角确定井口表面的任何一点作为粒子的发射器。
如图2所示。
Velocity为粒子的速度值,f为粒子速度的大小。
火焰粒子发射速度的3个分量为:①粒子沿X轴、Y轴和Z轴方向的速度值分别为Velocity.x=f*cosθ、Velocity.y=f和 Veloc ity.z= f*sinθ。
2)火焰粒子的初始位置及速度火焰粒子的初始位置及速度是实现动态火焰必不可
少的因素。
Centerpos、VarPos、Velocity和VarSpeed是粒子系统中的4个系
统参数,分别表示粒子的火焰燃烧的中心位置、位置变化范围、粒子的平均速度和速度变化范围。
初始位置和速度的设置分别如下:
Initialposition=Centerpos+Rand()×VarPos
InitialSpeed= Velocity +Rand()×VarSpeed
3)火焰粒子的贴图粒子的贴图对火焰的外观极为重要。
石油着火焰色反应表现为
火焰中外焰温度最高显红火黄色,内焰温度稍低显黄色并有一定的透明度。
由于外焰和内焰的颜色不一样,因而通过着色语言对所属范围的粒子颜色属性和透明度属性做不同的赋值。
着色语言如下:
对粒子的颜色和透明度进行设置:
Out.color=float4(Color.r,Color.g.Color.b.Transparent);
对粒子进行贴图:
Texture[0]=<Tex>;
为了尽量使模拟的火焰逼真,采用真实的油田井口事故火焰的照片并进行处理,截取火焰的内焰和外焰的贴图,对火焰粒子的所属内焰和外焰分别进行贴图,以达到最佳火焰模拟效果。
火焰粒子内焰和外焰的贴图分别如图3和图4所示。
4)火焰粒子大小粒子的大小决定了火焰模拟的精细程度。
粒子过大,火焰失真;
反之,系统的实时性较差。
采用四边形面片表示火焰粒子,当绘制离井口中心较远的火焰时,使用较大的粒子;当绘制离井口中心较近的火焰时,使用较小的粒子。
粒子大小定义如下:
Size=AveArea×Rand() (其中AveArea为粒子的平均大小)。
5)火焰粒子数量粒子的数量决定了火焰的密度,由于油田井口事故火焰的火势比较凶猛,因此模拟火焰需要大量的粒子才能达到更加逼真的效果。
根据屏幕上每单位区域产生粒子数目的平均值(AveNumber)和显示区域(Area)粒子大小(Size),确定初始时刻产生的粒子数量(Number):
Number=AveNumber×(Area/Size)
6)粒子属性数据的更新火焰粒子属性的更新可以通过编写像素着色器实现。
根据分析油田井口事故火焰粒子的运动模型,通过shader编程完成粒子速度、位置的更新计算,最后将计算的结果以输出流的形式渲染到输出纹理缓冲区中。
用粒子的当前速度v(t)和时间增量(Δt)来确定粒子一帧经过的距离。
该距离加上粒子的当前位置p(t)可得出其下一个位置p(t+Δt)。
通过将当前加速度值a(t)加上当前速度
v(t) 可将粒子的速度更新。
火焰粒子的位置、速度、加速度的计算公式分别为:p(t+Δt)=p(t)+v(t)×Δt
v(t+Δt)=v(t)+a(t)×Δt
a(t+Δt)=(v(t)- v(t-Δt))/Δt
7)粒子的消亡油田井口事故火焰的高度由粒子的生命决定,因而赋给粒子生命值(Life)一个初始值,把Life值存储到纹理中的a通道中,随着粒子的运动,Life值不断减小。
当减小到值等于零时,将该粒子设定为死亡。
如果从a通道取出的生命值是负数,可将生命值截取为0,如果生命值大于1,截取为1。
用all函数判断life值是否为零,若life值为零,则粒子消亡:
isdead=all(saturate(tex2D(SamPrePosition,t0).a))。
使用渲染到顶点缓冲区的方法实现粒子的绘制[6]。
纹理中的像素和顶点数据都以数组的形式存储在显存中。
纹理中的像素数据是按照纹理的形式存储的二维数组,而顶点数据是按照顶点的形式存储的一维数据。
Render to vertex buffer原理就
是清除纹理中像素的固有解释方式,以顶点的形式重新解释这些数据,使GPU可以直接从渲染目标(纹理)中读取顶点数据,用于渲染[6]。
该试验使用的显卡为NVIDIA GeForce GT 240M,显卡显存512MB,开发工具为Virtools,试验结果截图如图4所示,图4显示火焰效果逼真。
对基于CPU和基于GPU 2种算法的帧率进行比较(见表1)。
从表1可以看出,当粒子数比较少的时候,2种算法的帧率没有太大区别;当粒子数逐渐增多的时候,2种算法的帧率则产生明显区别。
如当粒子数为160000时,基于CPU算法的帧
率为4帧/s,而基于GPU算法的帧率为90帧/s,其模拟火焰的效果逼真,能满
足人们正常的视觉效果。
笔者提出了一种基于GPU和粒子系统实现油田井口事故火焰的模拟方法。
该方法具有较高的计算速度,能够进行大规模火焰的绘制,且模拟火焰的效果逼真。
但该方法也有需要完善之处,即进一步优化GPU算法和实现火焰粒子间碰撞检测算法。
【相关文献】
[1]金小进,马尧海.基于粒子系统的火焰模拟与优化[J].计算机工程与设计,2010,31(5):1118-1120.
[2]Akeninemoller T,Haines E,Hoffman N.Real-time
Rendering[M].2thed.Wellesley.Massachusetts:A.KPETERSLtd,2002.
[3]许楠,郝爱民,王莉莉.一种基于GPU的粒子系统[J].计算机工程与应用,2009,42(19):77-79.。