创建简单粒子效果的最快方法


12

我正在寻找创建真正简单的粒子效果的最快方法,该效果在游戏中会像地狱般被散布。

基本上,我的游戏看起来像是vectrex游戏,主要由线条组成...我想进行一些小爆炸,这确实很常见。

有什么比仅移动某些点并使用GL_Point渲染更快的方法吗?


+1仅用于Vectrex参考。80年代初,我小时候在Scramble和Tempest上度过了一些有趣的时光。没有这个,我今天可能不会成为游戏开发者。
Kylotan

是的,暴风雨很棒:D
加速器2010年

我怎么说都不正确?
加速器

Answers:


13

确实不需要为每个粒子存储内存并分别为每个粒子设置动画。您可以通过使用经典的物理方程式在绘制过程中重建粒子位置来程序上进行此操作。s = ut + 1 / 2.at ^ 2

一个简单的例子(没有恒定的粒子加速):


void drawExplosion(ExplosionParameters& s)
{
  Random rng;
  rng.seed(s.startSeed);
  glBegin(GL_POINTS);
  for (int i = 0; i < s.numParticles; i++)
  {
    vec3 vel = rng.getRandomVector(-1.0f, 1.0f) * s.explosionSpeed;
    float timeBias = rng.getRandom(0, s.particleTimeBias);
    vec3 pos = s.explosionCentre + (vel * (s.timeElapsed + timeBias));
    glPoint3fv(&pos);
  }
  glEnd();
}

然后,您只需在更新循环的每次迭代中增加s.timeElapsed。

它也完全可以在GPU上实现,从而使CPU免于执行任何工作。一个gpu实现可能看起来像这样:

void drawExplosion(ExplosionParameters& s)
{
    //bind Vertex Shader If Not Already Bound();
    ...
    // bindVertexBuffer of Zeroes If Not AlreadyBound();
    glVertexPointer(...)
    //uploadShaderUniformsForExplosion(s);
    glUniform3f(...)
    ...
    glDrawArrays(GL_POINTS, 0, s.numParticles);
} 

然后,GPU顶点着色器将通过物理方程式以及传递给它的均匀性/常量来重建粒子位置-就像CPU版本一样。

要增加一些差异,您可以使用更多同时爆炸的参数,这些参数略有不同,为颜色/ alpha设置动画,并选择不同的起始位置。等等


另外,您可以使用伪随机数的可预测性来生成所有粒子的初始向量,从而从几个int有价值的数据中创建数百个粒子。对于简单的粒子,使用GPU创建四边形是一个好主意。
Skizz 2010年

多年来,我一直以传统的方式使粒子系统具有一系列将粒子视为半智能实体的类,这似乎总是浪费和and肿。这种方法对于只在屏幕上喷射的基本粒子而言好得多。
Piku

7

我进行了几次测试,而最快的方式(不是最快的编码方式)是由GL_LINE组成的粒子,它们知道它们的位置和速度,并将其用作渲染时的点(因此,粒子走得越快,最“线”它变得越来越慢,变得很重要。

效果非常酷(观看任何几何图形战争视频都可以看到),而且效果也非常快。将废话踢出四边形(特别是因为四边形会使我需要计算两倍的顶点)

而且,它比使用已经完成的粒子系统更好,因为我想要一个特定的FAST效果,粒子系统通常支持许多功能,并且开销成比例。


2
+1可以解释您最终要做的事情,尽管我很想听听您测试的更多细节。=)
莱安德

顺便说一句:所有这些都是即时模式(这是我唯一会编码的东西,我昨天才知道这个名字...)
speeder 2010年

6

通常,我认为您会将粒子作为纹理映射的四边形。基本上将它们视为2D精灵,并随着时间的推移逐渐淡出,在不可见时将其破坏。更好的是,在制作新的时重用旧的,这样就不会浪费内存。

如果您在艺术作品上使用预乘alpha,那么除了通过一种类型的混合操作,您还可以轻松地支持灯光,火焰,烟雾等等。


哼...点比纹理还快吗?
加速器

2
图形硬件经过专门优化,可将纹理光栅化到帧缓冲区。如果点数更快,则其数量可能微不足道,并且您将失去纹理化所带来的所有可能性。
Kylotan'7

像什么?请注意,我不是一个功能齐全的粒子系统,它只是一种特定的效果(小的爆炸,主要是您击中某些东西所产生的游戏反馈)
加速

如果您只想使用点或线,那很好。我只能评论大多数人对粒子所做的事情。也许没有填充的三角形会形成一个不错的粒子。
Kylotan

4

使用OpenGL ES 2.0,带有扩展名的ES 1.X和OpenGL => 2.1,可以使用GL_POINT_SPRITES。GL_POINT_SPRITES就像总是在镜头前的四边形。

在片段着色器中,您可以:

  • 在顶点着色器中使用gl_PointSize定义精灵的大小
  • 在片段着色器中使用gl_PointCoord(uv坐标)

您可以使用带有alpha的纹理来绘制球形精灵。

点精灵教程


我避免使用扩展程序,因为引擎(我没有制造)已经使用了愚蠢的扩展程序,足以使几个人抱怨游戏无法运行……
speeder

1

我见过的大多数粒子效果系统都没有绘制大量的点,而是绘制相对较少数量的广告牌纹理,其中每个纹理看上去都像爆炸一样。除非您的艺术风格真正阻止了您,否则您可能会更乐于走这条路。它将最大程度地减少您需要单独进行动画处理和渲染的粒子的数量,同时仍具有出色的视觉效果。


1
的确如此,但是他的目标是Vectrex风格,在那里效果不佳。
Kaj 2010年

1
究竟是什么凯伊说......这将是毫无意义的,并会增加下载大小(我切换最图形我可以从精灵到真正的载体,这样我就可以减少文件大小)
调速装置

1

对于处理粒子的生成/删除/更新的一种巧妙的小方法,假设您有一个简单的粒子数组-Particles [MAX_PARTICLES]:

跟踪活动粒子(从NumActiveParticles = 0开始)

新粒子总是添加在数组的末尾:

pNewParticle = &Particles[NumActiveParticles++];

聪明的地方-移除“死”粒子时-将其与最后一个活动粒子交换,并递减NumActiveParticles:

if ( DeadParticle < NumActiveParticles-1 )
{
  Particles[ DeadParticle ] = Particles[ NumActiveParticles-1 ];
}
NumActiveParticles--;

这样可以避免在生成时搜索“未使用的粒子”,并且避免在不使用任何MAX_PARTICLES数组的情况下进行扫描。

请注意,这仅在更新/渲染顺序不重要的情况下才有效(许多粒子效果就是这种情况,它们使用加法混合)-因为这种删除粒子的方法会对数组重新排序


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.