Improve the performance of ParticleEmitters

As a Roblox developer, it is currently too hard to rely on particle emitters widely, even for simple static particles, because they perform poorly compared to alternatives.

If Roblox is able to address this issue, it would improve my development experience because it would allow me to utilize particle emitters in more places without making performance sacrifices.

This post is probably overly long, it can more or less be summarized as “billboards seem to perform hundreds of times better than particles and that seems a bit much.”

Relevantly, compared to other engines & games, Roblox particle emitters also appear to across the board perform worse in practice. I didn’t get specific numbers on this or do concrete tests though, it’s mostly just based on anecdotal observations and ballpark numbers, and it all makes me believe that there is maybe something going on with Roblox’s particles specifically that is unusual.

Details, tests, & Comparisons

The problem

Currently, ParticleEmitters perform unexpectedly poorly based on a bit of rough empirical testing.

Emitting only a few hundred static particles at the same time (no animations, just permanent or semi-permanent particles emulating the behaviour of a BillboardGui) can bring client performance to a crawl (<1 FPS) on mid-tier hardware.

On other hardware, just asking for information from a variety of players, the observed difference in framerates was sometimes even larger than I observed on my hardware. Further, the range that the particles can be viewed at is incredibly small compared to alternatives which perform substantially better even on decent hardware, which makes them even less ideal for a lot of use cases.

What might be going wrong?

I believe based on somewhat weak evidence that this is a consequence of overdraw on the GPU, e.g. possibly due to particle draws not being z-sorted like billboards and resulting in lots of redraws and recomputations, but this is a guess mostly based on how extreme the observed difference in performance is between particles and billboards and I don’t have clear direct evidence of this being the case.

What are my expectations & why do I think something is wrong?

My expectations are that BillboardGuis and ParticleEmitters should behave and perform roughly the same in practice, and I would put a loose expectation that particles could reasonably perform maybe 10-20x worse in a less-than-ideal scenario, but not 100-200x worse on mid-tier hardware as I observe below. This is just based on the work that I believe particle emitters may have to do, and based on the assumption that that work would perform better or equivalently compared to a luau implementation.

I believe that the extreme difference is an indicator of a problem in the particle implementation rather than a true limitation in the implementation (e.g. I don’t think it’s things like lighting computations being that much more expensive, or things like skewing playing a major role)

Comparison between BillboardGuis & ParticleEmitters

The numbers below are pretty rough estimates. The tests I did involved spawning coin images around a point, each being an equivalent size of 1x1 studs in world space. These were done with a Ryzen 3 3200G CPU (an okay mid-tier CPU released in 2019) and an AMD RX 570 (decent mid-tier card released in 2017 capable of rendering most Roblox games above 240 FPS) on a Windows 10 machine.

For the billboard test I used invisible & non-collideable 1x1x1 spheres to contain billboard GUIs, cloning and pivoting the pre-prepared spheres into position.

For the ParticleEmitter test I did the same, but instead of cloning, I set the lifetime of the particles to a large value, set the rate to 0, moved the sphere into position, and called :Emit() to create a particle. I repeated the test with a version where I cloned the sphere to make sure that there was no degradation from using a single ParticleEmitter instance and didn’t observe any change in performance between the two particle tests. I additionally did tests to see if I could identify any effect from the Rate being 0 or the lifetime being large and also didn’t observe any differences in that case either.

BillboardGui results

BillboardGuis with a single ImageLabel appear to perform substantially better (in the range of 100-200x) when compared to static particle emitters despite appearing identical. Even when implementing luau code to update the locations of billboards in the world every frame with math similar to the math that would be implemented for particles does not make a significant performance impact when compared to ParticleEmitters.

ParticleEmitter results

My system was able to handle approximately 30k billboard GUIs on screen before hitting 30 FPS. When emitting static particles from an emitter using :Emit() and doing no additional work it took roughly only 200-300 particles to bring system performance below 10 FPS, quickly reaching unplayable sub-1 framerates.

15 Likes

vouch

  1. spam a particle emitter for an aura effect (or use a high detail image for particle texture, give it like 120 rate and a high lifetime)
  2. when you get your camera close to the emitters, you get fps drops (from my experience, this can look like 240 → 60)
  3. when you get your camera away, suddenly it performs ok-ish
1 Like

I appreciate the time you did to test this. Do you have any screenshots to go along with it. Seems the staff likes as much data (visual or text) as possible.

On a side note, I am curious. Where you running these test with Automatic Detail settings or do you have it manually maxed for the test?

1 Like

Particle Emitters, Smoke and fire are old classes. ROBLOX need to rewrite these classes and add collision to particle emitters as well

3 Likes

I totally support this feature request. First of all, to be honest, BillboardGui itself doesn’t have the best performance either. It also has its own sets of performance issues and its performance can definitely and should be improved as much as possible. However, even with that, it still performs way better than ParticleEmitter.

I know a few Roblox games that use BillboardGui instead of ParticleEmitter for this reason. Additionally, I have also noticed that for some games that does use ParticleEmitter like MTC4, when the particles appear, the FPS really get tanked to the bottom, even for only a few particles that aren’t that much detailed or high quality. It seems that the horrible performance of ParticleEmitter is consistent access all games and uses. This makes using ParticleEmitters unfeasible, so I hope that Roblox takes this into consideration and works on improving the performance of ParticleEmitter and actually make them usable. Same thing for BillboardGui, though as I’ve noted and as the OP did, it does perform better than ParticleEmitter.

Can you share some data on this? I can’t really replicate your results, and in my testing ParticleEmitters are significantly faster, 12-15k BillboardGUIs is completely unusable because of the UI rasterization step that happens if the Billboards move or the camera angle changes, which easily jumps my CPU render time to 60-100ms depending on transparency, and with the 25k drawcalls (each image label is 2 draw calls), even a stationary camera is pretty slow. Additionally, that many BillboardGUIs was using like 4.5 gigs of RAM.


(Edit: I retested with all of them larger and overlapping like I did below, didn’t get a screenshot but the result was significantly worse at about 200ms CPU render time.)

I then spawned as many ParticleEmitters as Roblox would let me, about 90 parts with a rate of 240, 1 second lifetime, before it started capping out, and my framerate remains at 120-144, going down to about 60-70 if I increase the sizes and overlap all of them causing heavy overdraw, the CPU render time is still abysmal but this is about 20k particles running way faster than the billboards and with significantly less RAM usage.


(Edit: Replaced the image with the worst-case scenario large particles with maximum possible amount of them overlapping)

Either way, I am all for feature requests to improve performance of systems, and there are things that can be done here with both of these situations (GPU particles & UI Rasterization would be a step in the right direction). But I don’t think BillboardGUIs are simply “faster” as you’ve said.

(I am on an i7-7700K and a GTX 1080Ti)

1 Like