PDA

View Full Version : Poor performance in custom particle system (using LibGDX / LWJGL)



unlogical
05-16-2016, 09:12 AM
I'm using a custom particle system for my LibGDX / Java based game project (because I used Slick2D earlier on, need more parameters so I made my own and then ported). The system is fairly standard as far as I'm concerned, uses particle pooling (each emitter has its own fixed size particle pool) and renders each particle in a batch and uses one single (2048x1028) packed texture with all particle textures on it. Here is how I render the particles in semi-pseudo-code (because the entire code isn't relevant):

//ParticleSystem class
//Note: ExtendedBatch is my custom sprite batch implementation, largely just the normal SpriteBatch with two additional vertices for grayscale factor and additive tinting
void renderEmitter(ParticleEmitter emitter, ExtendedBatch batch)
{
ParticlePool pool = particlePools.get(emitter);

if (emitter.shouldScissor)
Renderer.pushScissor(emitter.scissor);

for (Particle particle : pool.particles)
{
if (particle.inUse)
particle.render(batch);
}

if (emitter.shouldScissor)
Renderer.popScissor();
}

//Particle class
void render(ExtendedBatch batch)
{
relativeX = getRelativeX();
relativeY = getRelativeY();

if (isInScreenBounds(relativeX, relativeY))
{
batch.setColor(myColor);
batch.draw(myTexture, position, origin, size, scale, rotation);
}
}


Now for some reason with only around 300 particles (split up into 10 emitters with varying sizes) the performance drops to awful ~30FPS on my notebook's integrated GPU (Intel HD 4400) when I need / want 60FPS at all times. I know iGPUs aren't great, but that one is one of the better ones out there and games like Ori or Braid which have thousands of similar particles run without any problems at 60FPS on that very chip. I also doubt (and hope) that it's not just Java vs C++ which is causing this huge performance drop here. Also, the same chip and computer can manage 25 thousand particles in the LibGDX particle editor, so there must be something else I'm doing very wrong.

Looking at in-game profiling data (I would include a picture but I'm apparently not allowed to post more URLs), the data however shows a few things: Particles aren't really taking that long to render and there is a *lot* of idle time. To me, that doesn't really make much sense. It looks like there would be enough resources to easily render everything at 200FPS or more, but it is stuck at a horrible 30FPS.

For the record, I took a CPU sample over 2 minutes with VisualVM (Again, I would include the link but I can't), showing that most of the time used is spent in glSwapBuffer calls.

There are a lot of things I already tried that didn't help:


Packing all particle textures into one (which is 2048x1024)
Batching all particle draw calls
Profiling to find out the cause (see above)
VisualVM to find potential memory issues, didn't help



There must be something I'm doing horribly wrong and I also want / need more particles than just 300 so I definitely have to fix this - but I don't know how. Thanks very much in advance!

Cornix
05-16-2016, 09:24 AM
You didnt really show us anything related to OpenGL. From what I can see from your code you are not using OpenGL directly but an intermediate library. Perhaps the problem comes from a poor usage of LibGDX. I would suggest you try their support forum first.

Alternatively you could use a profiler and measure actual performance of different pieces of your code. Maybe this information can be useful to figure out the problem.
Besides that: Correct me if I am wrong but I believe libGDX already has a built in particle system. Why are you not using that? Since it is also open source you might want to take a look how it is implemented. Perhaps this will help you too.

unlogical
05-16-2016, 10:01 AM
Thanks a lot for your reply.

I did measure the performance using basic in-game profiling and more advanced VisualVM sampling & profiling, but unfortunately that didn't help me much.

And yes, it indeed has it's own particle system, but I originally wrote this in Slick2D and needed more features than their particle system provided so I wrote my own, largely based on theirs, then ported to LibGDX. My problem is that my rendering code is almost the same as theirs and mine performs much worse and I have no idea why.

But yeah you're right, I will try it on the LibGDX forums. I originally thought that this was more of an OpenGL issue, but you're probably right. Thanks regardless!