基于大规模粒子系统的实时喷泉模拟
来源:岁月联盟
时间:2010-08-30
0 引言
景物的模拟一直是计算机图形学的研究热点之一。粒子系统被公认为是模拟自然景物中运动模糊物体非常有效的一种图形生成算法。目前,在这一领域已经有较多的算法和理论,1983年,Reeves 首先提出了粒子系统为模糊物体建模的方法[1]。1990年,Karl Sims在超级计算机上实现了粒子系统的并行算法[2]。随着计算机图形硬件的快速,图形处理器(GPU)的计算能力大大增强,在GPU上进行大规模的并行计算成为可能[3]。 2004年,Lutz latta在个人计算机的GPU上实现了并行的粒子系统,能实时处理1,000,000个粒子,并首次提出了大规模粒子系统的概念[4,5]。 2006年,许楠等也在GPU上实现了大规模的粒子系统,用26万个粒子实现了对雨景的模拟[6]。 喷泉的模拟是粒子系统的典型应用,最近对喷泉的研究比较活跃,马骏等利用粒子系统,采用离线渲染的方法来模拟喷泉[7,8],赵静谧以粒子系统为基础,采用Line方式渲染粒子,结合纹理映射实现了喷泉的实时模拟,其实现的喷泉,粒子数量较小,速度只有20帧/秒[9]。方建文等利用了GPU的硬件加速功能,以CPU和GPU相结合,实现了对喷泉的实时模拟,在粒子规模小于10,000个的情况下能满足实时的要求[10]。 在做虚拟校园时,我们要模拟一个较大的喷泉,由三组喷泉组成,共72个水柱,为了逼真的模拟喷泉效果,本文采用完全基于GPU的大规模粒子系统,在普通的计算机上,用了大约76,500个粒子,利用GPU大规模并行计算的能力,实现了喷泉的实时模拟。1 粒子系统简介
1.1经典粒子系统介绍[1]
粒子系统的绘制包括以下几个步骤: (1)粒子的产生:产生新的粒子加入系统中; (2)粒子的初始化:设置每个粒子的属性,如初始位置、方向、颜色、透明度、生命周期等; (3)粒子的消亡:从系统中删除那些已经超过生命周期的粒子; (4)粒子的运动:按粒子的动态属性改变位置和其它属性; (5)粒子的绘制:绘制并显示由有生命的粒子组成的图形。 上述几个步骤不停循环,形成了物体动态变化过程。1.2 大规模粒子系统介绍
大规模粒子系统是相对经典的粒子系统而言,由于经典的粒子系统在数量上受到10,000个粒子的限制,而完全在图形硬件(GPU)上实现的粒子系统,在处理1,000,000个粒子的时候仍能满足实时的要求,这种完全在图形硬件上实现的粒子系统被称为大规模粒子系统。 大规模的粒子系统采用并行算法,提高了并行处理能力,主要在GPU上实现,减轻了CPU的负载,提高了GPU的利用率,大大减小了CPU到GPU的数据传输,从而极大的改善了粒子系统的实时性。下面详细介绍如何用大规模粒子系统来实时模拟一个真实的喷泉。2 喷泉的模拟
喷泉由多个水柱组成,每个水柱可看成由很多个小水珠组成,每个小水珠可由一个粒子来模拟,本文称之为喷泉粒子。喷泉的模拟按图1所示的步骤进行:图1 喷泉粒子处理流程图
2.1 喷泉粒子的属性和存储
喷泉粒子由位置(Position)、生存时间(Tol)、速度(Velocity)、颜色组成。2.2 喷泉粒子的产生
在GPU编程中,存储空间的分配和回收不如CPU对内存的管理那么方便,不太适合动态分配,因此创建固定大小的Texture,比如1024 * 256个像素,先在内存中建立一个索引表,为Texture的每一个Pixel设置一个标志,表示这个Pixel是否保存有效的粒子信息。这个索引表的初始值全部为零,表示场景中没有任何粒子,分配新粒子时,从索引表中找到为零的值,然后设置各个Texture对应的Pixel的值,再把索引标志的值设为1。 产生新粒子时,按预先设置的产生粒子的速度和与上次产生粒子的时间间隔,可计算出本次应该产生的粒子数。2.3 喷泉粒子的初始化
2.4 喷泉粒子的运动
2.4.1喷泉粒子的速度更新 为了让喷泉的运动轨迹看起来更真实,首先考虑它的受力模型,粒子一直受重力的吸引,因此一直会有一个向下的重力的加速度9.8。还可以考虑风力等,最终用运动方程合成一个最后的加速度。然后用下面的方程当前的速度: V = V0 + a.(t – t0) 其中,V指现在的速度,V0是上次更新时的速度,t是当前的时间,t0是上次更新时的时间。 喷泉粒子速度的更新方法与在CPU上更新不同,速度存储在Texture上,加速度和原来的速度的合成是在Pixel Shader编程中实现,执行时,把记录着粒子上次的速度的Texture作为输入,GPU对所有Pixel进行并行处理,输出到另一个Texture。下面的其它属性的更新方式与此相似。2.4.2喷泉粒子的位置和生命周期更新 两次喷泉粒子更新的时间间隔记为t, 喷泉粒子的生命周期为上次更新后的值,减去时间间隔。喷泉粒子的新的位置为:2.5 喷泉粒子的消亡
当粒子的生命周期小于或者等于零时,喷泉粒子应该从场景中移除。处理消亡的粒子,要做两方面的工作,一是从位置Textue中,把位置移到无限远处,在绘制时把此粒子裁剪掉。另一个工作就是要把索引表中对应的索引项的值设为0,以便分配新粒子用。2.6 喷泉的绘制
喷泉的粒子在绘制时,可以采用点绘制、三角形面片或多边形面片绘制,本文采用Dirext3D9的Point Sprite的方法来绘制粒子,这种方法提供一个顶点坐标,以给定的顶点为中心,进行纹理贴图,这样我们可以准备多种不同的水珠的图片,实现不同的喷泉效果,比用三角形或多边形绘制减少了需要的顶点数量和计算时间。 要完成点绘制,必须把顶点数据放在顶点缓存(Vertex Buffer)中。粒子属性的存储和处理都是在Texture中进行的,因此我们要通过编程把Texture中的属性值复制到Vertex Buffer中。喷泉粒子在转化为顶点信息后,通过普通的渲染过程绘制到帧缓存中即可。3 实验结果
根据上面所述算法,在普通计算机(P43.0G处理器, Geforce MX 6200显卡,512M内存)上进行实验。喷泉由72条水柱组成,约75600个粒子。我们对本算法在以下三种情况下进行了场景绘制时的帧率测试,测试结果如下:表1 场景绘制帧率测试结果场景内容 | 帧率FPS |
场景中公有喷泉 | 95 |
复杂的三维场景(不包括喷泉) | 85 |
复杂的三维场景 (包括喷泉) | 70 |

