关键词 粒子系统;GPU;实时;喷泉模拟
自然景物的模拟一直是计算机图形学的研究热点之一。粒子系统被公认为是模拟自然景物中运动模糊物体非常有效的一种图形生成算法。目前,在这一领域已经有较多的算法和理论,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所示,均以Texture的形式存储在显存中,Texture是由Pixel组成的矩阵,每个Pixel由RGRB四个浮点数分量组成,GPU处理数据时,一次可以输入一个或多个Texture,处理后输出一个Texture,结合硬件的特点,便于并行处理,我们把这三组数据保存在不同的Texture中,就有了图2所示的三组Texture。每组两个Texture,循环的用做输入和输出,称之为双缓存。
2.2 喷泉粒子的产生
在GPU编程中,存储空间的分配和回收不如CPU对内存的管理那么方便,不太适合动态分配,因此创建固定大小的Texture,比如1024 * 256个像素,先在内存中建立一个索引表,为Texture的每一个Pixel设置一个标志,表示这个Pixel是否保存有效的粒子信息。这个索引表的初始值全部为零,表示场景中没有任何粒子,分配新粒子时,从索引表中找到为零的值,然后设置各个Texture对应的Pixel的值,再把索引标志的值设为1。
产生新粒子时,按预先设置的产生粒子的速度和与上次产生粒子的时间间隔,可计算出本次应该产生的粒子数。
2.3 喷泉粒子的初始化

如图3所示,喷泉从P1喷出,初始的方向是指向P2的,为了让喷泉看起来更真实,我们在设置初始的速度时,让P2在一个以R为直径的球内随机分布,这样的喷泉看起来是一个水柱而不是一条线。在运行过程中,要受到重力等力的作用,方向会不断改变,最后到达P3的位置。
喷泉粒子的初始方向Direction为:
Direction.j = (P2.j – P1.j) / ( );
j = x, y, z.
喷泉粒子的初始速度为:
Velocity = Direction * Speed
其中Speed 为喷泉粒子运动的速率,可以让它在一定范围内波动,以增加喷泉的动感。
由于一次要产生多个粒子,因此,这些粒子的初始位置是:
Position = P1 + Rand(0, t) * Velocity
其中,t为两次产生粒子的间隔时间。这样才能确保喷泉的连续。
喷泉粒子是白色水珠,并且通过喷泉还能看到后面的物体,因此把初始色彩设置为白色,透明度设置为半透明。如果设为其它的值,则可以制作彩色喷泉。
喷泉粒子的生命周期设置一个平均值T,再设置一个波动的区间t,生命周期为: