基于GPU的游戏粒子系统设计摘要:在MMORPG游戏中经常出现同屏显示成千上万的粒子特效,传统引擎虽然使用多线程来计算粒子的运动,但是也很难应付大规模的计算量(考虑到一般配置),更何况MMORPG中还空出许多CPU去处理逻辑。提出基于GPU进行粒子计算的粒子系统,利用GPU的并行计算多个对象,实现并行化高效的粒子系统。关键词:粒子系统;GPU;并行计算1系统原理在游戏设计中,基于粒子系统可以实现火、爆炸、烟、云、雾等效果。粒子系统主要用来解决由大量按一定规则运动(变化)的微小物质组成的大物质在计算机上的生成与显示的问题。经常使用粒子系统模拟的现象有火、爆炸、烟、水流、火花、落叶、云、雾、雪、尘、流星尾迹或者象发光轨迹这样的抽象视觉效果等。粒子系统的实现:①每个粒子是一个带纹理的三角形/多边形,粒子系统由多个粒子组成;②粒子按一定规则运动;③每个粒子有自己的属性,如位置、速度、质量、尺寸、年龄、运动轨迹斜率、颜色等;④粒子系统更新循环划分为两个不同的阶段:参数更新/模拟阶段以及渲染阶段;⑤参数更新/模拟阶段根据粒子系统信息更新每个粒子的速度、位置、尺寸、颜色等信息;⑥渲染阶段根据粒子属性重新绘制粒子;⑦每个粒子都有自己的生命,年龄超过最大年龄的粒子会被销毁,系统会生成新的粒子。2系统设计2.1框架分析ParticleFactory是粒子工厂类,负责创建和销毁粒子,同时管理了当前创建的粒子。Iparticle为粒子的接口类,所有粒子都从它派生出来,它定义了粒子的基本接口:Play、Stop、GetProperty和SetProperty。MMO_Particle表示使用MMO_计算的最终生成面片的粒子,MMO_MeshParticle表示使用MMO_计算的基于网格的粒子。BaseGpuParticle表示使用GPU计算和更新粒子。每一个粒子对象都有一个指向ParticleProperty类的指针。ParticleProperty保存了粒子的属性参数,包括基本的颜色、大小、旋转角度等,还有受力、发射器。多个粒子对象可以指向同一个ParticleProperty对象。ParticleController是粒子控制器,它管理了引擎中众多的粒子控制器,同时提供与外部交互的接口以用于实现某些特殊的效果,比如武器划动的轨迹效果等。2.2CPUvsGPU传统游戏引擎提供的是基于CPU的粒子系统,但是考虑到MMORPG中有可能同屏显示成千上万的粒子特效,效率问题不能不考虑。引擎中虽然使用多线程来计算粒子的运动,但是也很难应付大规模的计算量(考虑到一般配置)。更何况MMORPG中还有空出许多CPU去处理逻辑。于是笔者想到了用GPU进行粒子计算。肯定许多人会问,用GPU不是比CPU更复杂吗?其实恰恰相反,GPU的粒子比CPU简单得多。引擎中的粒子必须要有模拟器、发射器、力、控制器还需要多线程调度任务,可谓庞大复杂。而GPU粒子只需要一个MMO_SingleShaderMaterial和一个MMO_Mesh,不必担心GPU粒子的灵活性,笔者实现了3种GPU粒子效果:烟雾、火焰和龙卷风。每一种都开放了大量可控参数,比如烟雾就有浮力、重力、风力、速度、扩散值、原始大小、目标大小、原始颜色、目标颜色还有纹理,其中纹理可包含多帧。如此多的参数,是否需要很复杂的GPU程序呢?其实不然,在笔者的实现中,vertexshader的HLSL代码只有20行,pixelshader代码有4行。Vertexshader使用vs1.1版本即可。为什么代码会这么少?这是因为GPU编程与CPU编程是不同的,CPU通常逐个计算单一对象,而GPU则是并行的流式计算多个对象。当使用CPU编程时,总是想到建立一个缓冲然后创建粒子,保存属性,每帧更新,删除粒子等。而GPU编程完全不同,它没有创建删除粒子,保存其状态的概念,也不能够创建缓冲来保存粒子的属性等。在GPU编程中,处理好一个粒子就等于处理好多个粒子了。但是GPU也并非没有缺点,比如GPU实现的粒子是很难互相访问数据的。在游戏开发中,我们常常要在性能与效果上做出取舍。笔者认为对于大部分常见的效果用GPU粒子就能做到简单高效,对于少部分特殊效果可以用的CPU模拟计算的粒子实现。因此在粒子系统中,提供了BaseGpuParticle类,用于实现GPU模拟计算的粒子。2.3粒子的属性无论是CPU粒子还是GPU粒子,都可以有大量的属性参数,这些属性参数实际上不需要每个实例都保存一份,...