【问题标题】:Spawning GPU Particles生成 GPU 粒子
【发布时间】:2016-07-09 19:38:24
【问题描述】:

我正在开发我的第一个游戏引擎,并尝试实现一个 GPU 粒子系统。我以前在 CPU 上实现过一个,但现在我正试图让它更高效。具体来说,我的问题是在一生中产生粒子。

由于我正在为粒子引擎处理帧缓冲区纹理,因此它非常并行,但代价是无法返回 CPU,对吗?我首先绘制了一个处理该特定粒子系统计算的四边形(为了排序可能必须有第二个四边形),然后我运行 glDrawArraysInstanced

我的一个想法是在需要创建粒子时使用布尔值或整数值,表示需要创建粒子或生成粒子的数量,两者均由 CPU 初始化。因此,如果我发现一个粒子(像素)的生命周期(假设第一个 fbo 纹理的 alpha 值)小于零,并且我知道我应该创建它,我该如何禁用其余部分的创建粒子,还是减少要爆炸的粒子数?我听说过诸如变换反馈之类的东西,但我不知道这是否是最好的方法。无状态粒子声音限制 - 并非所有粒子都有 1:1 的生成率。

简单重复一下这个问题:生成 GPU 粒子的最佳方式是什么?

如果我能知道 CPU 上的粒子数量,顺便说一下,我可以在 glDrawArraysInstanced 中设置要绘制的数量,所以如果你能在答案中包含它,我将不胜感激。

【问题讨论】:

  • “我正在开发我的第一个游戏引擎” - Write Games, Not Engines
  • 我以前做过游戏。厌倦了使用其他人的引擎,不想为每个游戏编写一个全新的代码库。我已经在渲染、物理、照明、输入和大量其他系统方面做了大量工作。现在停止听起来不是一个好主意。
  • 哦,还有@JesperJuhl - 我刚刚读了这篇文章。我已经计划了几个游戏创意,并且代码中的每个系统都计划在不同类型的游戏中工作。如果我编写一个游戏,它就不会很灵活。例如,我的输入系统兼容 Linux 和 Windows,很快就会兼容 Mac,并且设计为具有各种输入和功能,易于使用和灵活。所以感谢你的爱,但我真的不需要它——我只需要找出解决这个问题的最佳(也是最灵活)的方法。

标签: c++ opengl glsl framebuffer particle-system


【解决方案1】:

我去试试……

CPU 应该知道最大粒子数是多少(这将是池大小)和当前“活”粒子数。第一个数字用于初始化或调整粒子状态 VBO 的大小,不应经常更改。如果您愿意,第二个可以逐帧更改。

单个粒子的寿命应作为 VBO 值的一部分存储。大概您使用计数器或时间值来确定位置、颜色等,当该计数器达到最大值时,您“杀死”粒子并重新分配。通过改变初始计数器值,粒子不必都以相同的方式启动和更新。

对于更新粒子状态,是的,您需要变换反馈。您将拥有一个“顶点着色器”,它从旧粒子计算每个粒子的新值并将这些值写入另一个 VBO。有关详细信息和示例代码,请参阅 OpenGL SuperBible。我只是在两个 VBO 之间打乒乓球,一个用于旧值,一个用于新值,但您也可能决定使用纹理缓冲区对象,它们是可以在着色器中写入的大型数组(比统一大得多)。每次更新的粒子数由 CPU 实时计数器控制。

希望这会有所帮助。

【讨论】:

  • 感谢您的回答,但是当我考虑使用 VBO 时,我决定不这样做。我认为纹理(例如 nullprogram.com/blog/2014/06/29 )对于大量粒子来说是一个更好的解决方案。我的粒子目前有一个循环生命周期,但我希望它们能够“死”一段时间,这是我的问题。我不会单独在 GPU 上创建一个新粒子。
  • 如果你想做高效的并行处理,不要考虑控制单个粒子。您需要适用于大量数字的算法。通过减少 glDrawArraysInstanced 中使用的活动计数或其他任何方法,或者允许粒子具有负年龄并且在年龄> 0 之前不可见,单个粒子可以“死亡”一段时间
  • 这正是我的计划,我的问题在于实施。由于粒子的随机生命周期,gldrawarrayinstanced 很难控制存活的粒子数量。如果我有在 GPU 上递增和递减的粒子数,我可以解决这个问题。
猜你喜欢
  • 2011-02-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-07-27
相关资源
最近更新 更多