Unfortunately, I’ve been having rather more trouble with the Particle Systems API (PAPI) than I was expecting. As such I’ve given up on that particular avenue of investigation. It would be different if it was under active development, but as the website doesn’t seem to have been updated in 4 years, I don’t think I’m gaining enough to keep on with the library.
Having said that, not everything is a loss. I mean, I have written a (small) particle system before, but I definitely think I’ve learned from prying into PAPI. Hopefully I can make a better system now than I did a couple of years ago.
So, what was the problem with PAPI? It seems like only yesterday I wrote about it. Am I giving up on it too soon?
Woh. What’s with all the questions? Right, so. It wasn’t yesterday, it was actually exactly a week ago I wrote about it, but I’ve actually been wrestling with some of the PAPI stuff for a few days before I wrote anything. As such, I think I’ve given it more than enough time and it’s come up with a lot of little perculiarities which caused problems.
The main problem is one I’m going to have to overcome at some point myself. I’m not saying the solution that PAPI had was incorrect, but it definitely wasn’t suited to what I want to do. The problem is that each particle is it’s own entity. It has it’s own age, mass, velocity, position. That’s all absolutely correct. It makes perfect sense to bundle these up together, in a struct for example. But then, when you get around to render them, you don’t need all this information. All you need is the position. In fact, to do the fastest rendering, you need all of the positions in one big array which you can pass to the GPU.
The way that the PAPI examples worked is that they just gave an array of Particle structs to the GPU and then used the stride to skip the bits that it didn’t need. I checked the size of these structs, 144 bytes. A position is 3 floats. 4 bytes each. Assuming a particle system of, let’s say 1000 particles, that works out at a little over 140kilobytes for the array in place of a little under 11kilobytes. Now, I haven’t checked whether OpenGL is clever enough that, when you give it a vertex array, tell it that you’re using floats, but give it a stride of 144, it would not send the data that isn’t needed to the GPU. If it does that, I’m impressed, but even then, it’s probably extra overhead, having to seek. Either way, I don’t like it.
I said that it’s the main problem even though I don’t know if it actually caused any problems. The reason for that is quite simple. I spent a while looking into the code and, much as I understand roughly how the system works, a lot of it just seems to spring out of nowhere. Like the vertex array, it took me a little while to figure out why the stride was 144, for example. Hopefully, if I try and write one from the engine side, rather than writing a system from the particle side and trying to make it generic, it might be clearer, at least in the context of Maratis. A particle system isn’t overly hard to write, after all.
So, if I’m going to start writing this myself, how am I going to start? Gah. To be honest, I have no idea. I’ve been looking into different things and trying to decide what the best plan of attack is. As I’ve mentioned in the previous post, I would like the posibility of moving the bulk of the calculations onto the GPU at some point, if they become too heavy. I haven’t done any GPU programming yet though. I also like the idea of potentially tying it in with Bullet. Although that would probably remove all chances of GPU work.
I have yet to do a little more planning on this before I get started, but, so far, my proposed plan of attack is to read up on the GPU stuff, but not intend to implement anything at this stage. With some extra knowledge, I should be able to write it in a way that leaves it open for that later. I can then start working on a simple particle system, just working with some simple trivial physics calculations. At that stage, I should be able to assess performance and what has the greatest potential. I expect, what I would probably end up doing is to add some very basic physics shapes as particle blockers of some form. Probably even keeping them axis aligned. Then they can be added to objects in the world that particles are meant to interact with. In that way, I don’t rely on the whole Bullet collision system, and I’ve got some physics to get some collision objects that I can have particles interact with.
I don’t suppose anyone has any experience with this at all? I’d love to hear what you’ve got to say about any of this.
More updates once I’ve done some more planning.