OpenGL ES 2.0——简单粒子系统的最佳途径
我正在尝试使用 OpenGL ES 2.0 为 Android 应用程序创建一个非常简单的粒子系统。基本上它仅适用于背景中线性移动的云。在开始之前,我的第一个想法是使用点精灵,这就是我一直在尝试做的事情。对我来说,要让这个工作正常进行是相当困难的,但除了这些问题之外,点精灵真的是解决这个问题的方法吗?
我在搜索中读到了很多关于它们的相互矛盾的内容来解决我的错误,如果这不是我应该寻求的解决方案,我不想投入大量时间来使其一切正常工作第一名。人们提出了各种使用它们的问题,例如裁剪,甚至与仅使用三角形相比性能下降。我希望有经验的用户能够深入了解点精灵适合的位置以及何时使用它们,包括在像我这样的情况下,它们在屏幕上最多不会超过几十个“粒子”。
I am attempting to create a very simplistic particle system for an Android application using OpenGL ES 2.0. Basically it is just for linear moving clouds in the background. My first thought before starting this was to work with point sprites, and that is what I have been trying to do. It's been pretty difficult for me to get this working, but those problems aside, are point sprites really the way to go for this?
I have read quite a few conflicting things about them in my searches to solve my bugs, and I don't want to invest a great deal of my time into making it all work right if it is not the solution I should be going for in the first place. People post all kinds of troubles with them such as clipping, and even performance dips in comparison to just using triangles. I would like an experienced users insight into where point sprites fit in and when they should be used, including in situations like mine where they will not be more than a few dozen "particles" on the screen at very most.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
请记住,点精灵有严格的大小限制,大小越大,性能越慢。如果您的目标是只有 12 个“粒子”,我认为您应该将它们渲染为四边形。另一方面,如果您的目标是拥有 12 个由许多“云粒子”组成的云,每个云都赋予它们动画效果,那么您应该使用点精灵。
瓶颈将是填充率,特别是因为您可能会使用混合。
如果您有 100 多个云,是否使用点精灵的问题就变得更加相关。要为它们设置动画,您必须每帧向 opengl 发送一个新缓冲区(方法 1),或者使用不同的变换矩阵在单独的调用中渲染每个云(方法 2)。后者很可能是最慢的,但前者要求您为每个云发送 4 个新顶点(假设索引渲染),而如果您使用点精灵(方法 3),则每个云只需发送 1 个新顶点。
此时,很容易粗略地计算出最快的速度。方法2表示每帧传输到GPU的
16*4*num_clouds
字节数据,方法1为d*4*num_clouds
,而方法3为d*num_clouds
,其中 d 是 2 或 3,具体取决于您是否需要 z。另外值得注意的是,方法1和3是批量发送数据,而方法2是一次发送16*4字节。
由于您使用的是 GL ES 2,您可以跳过方法 2 中的矩阵,只将翻译作为向量发送,但您仍然会遭受非批量数据传输以及为每个实例设置统一的成本。
编辑:
实际上,在有许多粒子的情况下,您要做的就是设置一个统一的时间,并将云的速度作为静态属性,然后通过将速度乘以时间来在着色器中对它们进行动画处理,并确保它们如有必要,环绕边缘。因此,对于完全动画的云场景,每帧只需传输 4 个字节。
Keep in mind that there are hard size limits for point sprites, and the bigger size, the slower performance. If your goal is to have only 12 "particles", I think you should render them as quads. On the other hand, if your goal is to have 12 clouds consisting of many, many "cloud particles" each to give them an animated effect, then yes you should go with point sprites.
The bottleneck will be the fill rate, especially since you will probably use blending.
If you have 100+ clouds, the question whether to use point sprites or not becomes more relevant. To animate them, you either have to send a new buffer to opengl each frame (method 1), or render each cloud in a separate call with a different transformation matrix (method 2). The latter will most likely be the slowest, but the former requires you to send 4 new vertices per cloud (assuming indexed rendering) compared to just 1 new vertex per cloud if you used point sprites (method 3).
At this point it's very easy to roughly calculate what will be the fastest. Method 2 means
16*4*num_clouds
bytes of data transferred to the gpu each frame, method 1 isd*4*num_clouds
, while method 3d*num_clouds
, where d is 2 or 3 depending on whether you need z.Worth noting is also that method 1 and 3 send the data in one batch, while method 2 sends 16*4 bytes at a time.
Since you are using GL ES 2 you could skip the matrix in method 2 and just send the translation as a vector, but you will still suffer from non-batched data transfer and the cost of setting a uniform per instance.
EDIT:
Actually, what you would do in the case of many particles would be to set a uniform time, and have a velocity for the clouds as static attributes, and then animate them in the shader by multiplying the velocity with the time, and making sure they wrap around the edge if necessary. So you would only need to transfer 4 bytes per frame for a fully animated cloud scene.
推荐你阅读《iPhone 3D编程》的粒子文章。
本书包括“iPhone”,但本书一般性地解释了OpenGL ES 1.1/2.0。因此,您可以将本书中的知识用于 Android 或 Android NDK。
I recommend you to read the particle article of "iPhone 3D Programming".
The title of this book includes 'iPhone', but this book explains OpenGL ES 1.1/2.0 generally. Thus you can use the knowledge from this book for Android or Android NDK.