OpenGL ES 2.0——简单粒子系统的最佳路径

Posted

技术标签:

【中文标题】OpenGL ES 2.0——简单粒子系统的最佳路径【英文标题】:OpenGL ES 2.0 -- Best route for simple particle systems 【发布时间】:2011-11-12 14:39:36 【问题描述】:

我正在尝试为使用 OpenGL ES 2.0 的 android 应用程序创建一个非常简单的粒子系统。基本上它只适用于背景中的线性移动云。在开始之前我的第一个想法是使用点精灵,这就是我一直在尝试做的事情。让这个工作对我来说非常困难,但抛开这些问题不谈,点精灵真的是解决这个问题的方法吗?

我在搜索中阅读了很多关于它们的相互矛盾的东西来解决我的错误,如果这不是我应该的解决方案,我不想投入大量时间来让它一切正常首先去。与仅使用三角形相比,人们会发布各种问题,例如剪裁,甚至性能下降。我希望有经验的用户能够深入了解点精灵适合的位置以及何时应该使用它们,包括在像我这样的情况下,屏幕上最多不会超过几十个“粒子”。

【问题讨论】:

【参考方案1】:

请记住,点精灵有严格的尺寸限制,尺寸越大,性能越慢。如果您的目标是只有 12 个“粒子”,我认为您应该将它们渲染为四边形。另一方面,如果你的目标是让 12 朵云由很多很多“云粒子”组成,每个都给它们一个动画效果,那么是的,你应该使用点精灵。

瓶颈将是填充率,尤其是因为您可能会使用混合。

如果您有 100 多个云,是否使用点精灵的问题就变得更加相关。要为它们设置动画,您要么必须向 opengl 每帧发送一个新缓冲区(方法 1),要么使用不同的变换矩阵在单独的调用中渲染每个云(方法 2)。后者很可能是最慢的,但前者要求您为每个云发送 4 个新顶点(假设索引渲染),而如果您使用点精灵(方法 3),则每个云只需发送 1 个新顶点。

此时很容易粗略计算出最快的速度。方法2表示16*4*num_clouds字节数据每帧传输到gpu,方法1是d*4*num_clouds,而方法3是d*num_clouds,其中d是2或3取决于你是否需要z。

另外值得注意的是方法一和方法三是分批发送数据,而方法二是一次发送16*4字节。

由于您使用的是 GL ES 2,您可以跳过方法 2 中的矩阵,只将翻译作为向量发送,但您仍然会受到非批量数据传输和为每个实例设置统一成本的影响。

编辑: 实际上,在有许多粒子的情况下,你会做的是设置一个统一的时间,并将云的速度作为静态属性,然后在着色器中通过将速度与时间相乘来为它们设置动画,并确保它们必要时环绕边缘。因此,您只需每帧传输 4 个字节即可获得完全动画的云场景。

【讨论】:

Point Sprites 似乎仍然是我要走的路,所以我想我会继续努力并尝试让它们工作。非常感谢您提供的有用信息。然而,我对他们还有另一个担忧。我已经读到某些设备根本不显示它们,我想知道这是否是较旧的 Android 手机(使用 OpenGL ES 1.1 时)而不是像我的应用程序将运行的更现代的手机的问题? 【参考方案2】:

推荐你阅读《iPhone 3D 编程》的粒子文章。

iPhone 3D Programming - Rendering Confetti, Fireworks, and More: Point Sprites

这本书的标题包括“iPhone”,但是这本书对 OpenGL ES 1.1/2.0 进行了一般性的解释。因此,您可以将本书中的知识用于 Android 或 Android NDK。

【讨论】:

感谢 Kazuki 的链接,因为我现在正在学习 OpenGL ES 2.0,看起来这对我来说是一本好书。 :)

以上是关于OpenGL ES 2.0——简单粒子系统的最佳路径的主要内容,如果未能解决你的问题,请参考以下文章

如何在Android上使用OpenGL ES 2.0绘制点

在创建 2D OpenGL-ES 2.0 游戏的基本、简单的方法中寻求帮助

OpenGL ES 性能 2.0 与 1.1 (iPad)

OpenGL ES 2.0:非常不一致的帧率

在 Android 上的 OpenGL ES 2.0 中使用 VBO/IBO

OpenGL ES - 如何批量渲染 500 多个带有不同 alpha、旋转和缩放的粒子?