- 13 November 2019
- Benjamin Anuworakarn
It’s time for another article in our ongoing series of posts about getting the most of your PowerVR device when creating graphics applications. This time we’ll be taking a look at particle systems.
This series is based on tips in our extensive PowerVR Performance Recommendations found on our documentation website. We’ve already covered a wide range of topics including:
- Using shader branching and flow control without harming performance too much
- Eliminating performance bottlenecks by balancing workload across multiple elements of the GPU
- Why mipmapping is so important for graphics applications
- Sorting objects on PowerVR hardware
Let’s find out what particle systems are and how they can affect performance.
Introduction
From the smoke floating across war-torn battlefields to torches on the walls of the darkest dungeons, particle effects are everywhere in games. When used right they can greatly add to the realism of a scene and help a game seem like a living, breathing world. However, as with most in-game systems, they can have a major performance impact when not used carefully.
For those of you who are unaware, particles systems are a graphical technique that is used to simulate “fuzzy” physical effects, such as fire, dust, magical effects, and weather. Particle effects are made up of many small, independent objects (particles!) each with their own properties like position, velocity, and acceleration. Once a particle is created, its properties usually evolve according to the rules of a physics engine, for example falling under gravity.
A typical implementation for a particle is a tiny 2D quad that is fixed to face the camera (billboard). These simple quads sample a particle effect texture to determine their colour. Particle systems consist of hundreds or thousands of these tiny 2D quads. All of the particles are usually composited using alpha blending.
If you want to learn more about how a simple particle system can be implemented in OpenGL® ES and Vulkan™, take a look at our SDK example, ParticleSystem.
The problem with particle systems
Using alpha-blended quads can be a simple and effective solution for implementing many particle effects, but unfortunately, it does have some drawbacks.
Lots of alpha-blended particles can lead to a huge amount of overdraw. This is because in order to render an alpha-blended (partially transparent) particle the GPU has to take into account any fragments behind the particle. This means it has to potentially rasterise many more fragments for each pixel than normal, leading to a lot more work. This could be a problem even for relatively small numbers of particles if their on-screen size is large. This is a particular problem for PowerVR and its dedicated Hidden Surface Removal (HSR).
As mentioned before in one of these blogs, HSR gets rid of a lot of overdraw by discarding any fragments which are occluded by some other fragment in the foreground. In the case of alpha blending, HSR can’t do this. This eliminates one of the key benefits of a deferred renderer and increases overdraw.
So, how do you tell that your particle effects are causing an overdraw problem? Well, it’s PVRTune to the rescue again!
The Overdraw GPU counter in PVRTune (highlighted in the image below) measures how often a pixel is shaded. In an ideal application, the overdraw value should be around 1.0. This Overdraw value implies every pixel on screen has been shaded just once, in other words no overdraw. This usually isn’t practically possible because there is always going to be some overdraw. However, if the Overdraw counter is consistently higher than 2.0 then it may start affecting performance.
Improving Performance on PowerVR
Ok, you’ve identified that your particles are causing too much overdraw and it’s starting to affect application performance. What next?
The good news is you don’t have to get rid of all of the fancy particle effects in your applications. Instead, we’ve got a couple of small suggestions which might help reduce their performance impact:
- Use meshes for particles that closely follow the opaque-transparent edges within the texture used, such as a circular mesh for a puff of smoke. This means that completely transparent parts will not cause unnecessary overdraw. This will increase the number of vertices required per-particles, however, unless your application is vertex-limited this should be an acceptable trade-off.
- Disable anisotropic filtering. For most particles, it may not be as important as to have crisp textures in the distance.
And finally, if you’ve tried every else:
- Reduce the number of particles
Yes I know it’s painful, but ultimately a user is going to notice performance dips more than slightly fewer particles.
And there we have it. Make sure to regularly check the Imagination Technologies blog for more posts in this series.
Want to hear more?
Our documentation site isn’t just for performance recommendations. We’ve got OpenGL ES and Vulkan getting started guides, documents on implementing advanced graphics techniques like physically-based rendering, the user manuals for our suite of powerful developers tools, and much much more.