A particle system is used in games to create effects for a lot of different events and actions, such as when a character is double
jumping or landing. Particles can also be used to mimic smoke, fire and other moving elements.
My goal was to create a particle editor that could be used in our own engine Metronome. When working with my team on previous projects I got requests that our current particle system should be able to spawn mesh particles. This made me really intrigued but due to shortage of time it was not possible to implement it at that occasion. With this in mind I chose to take the opportunity to fulfil their request during my specialisation. For this to be achievable, many particles had to be able to spawn without performance being impaired. Another challenge was to make the editor straightforward as well as easy to understand and use.
In order to use mesh particles in a game, they cannot be too draining on the performance. A good solution for this is using instanced rendering. This is a rendering technique used when rendering many instances of the same object. Instead of sending the data to render for each object to the graphics card it is sent only once along with all the transforms of the objects to be rendered, resulting in a single drawcall. To understand how instanced rendering works and how to implement it I read this post. It was useful and easy to follow which made the implementation go smoother than expected.
Since I finished instanced rendering faster than expected I used the spare time to learn compute shaders. One of the things I realised was how powerful a graphics card can be. The fact that I could choose how many separate threads my code could run on simultaneously was incredible. I got the compute shader to calculate simple operations on my particles, but in the end I took the decision not to use the compute shader. I took this decision since using instanced rendering gave me all the performance that I needed. I also discovered that it took a bit more time than just doing the calculations on the processor and writing compute shaders was not in my original planning.
This was the main focus of my specialisation since a particle system needs to have a great editor. The easier the particle editor is to work with, the faster you can make good looking effects. For this to be as user friendly as possible I used Unity's particle system editor as a reference for how my system editor should look and work. In the process of making the editor I asked for feedback and used this to make the tool as convenient as possible. The editor was made using Dear ImGui.
Asking others for their opinion on what features to implement I frequently got the answer curves so they could change speed and color over the lifetime of particles. This sounded like an excellent challenge and therefore I made this a priority. After a first assessment of my draft I got suggestions to display the curve editor in a different window. This made it easier to understand which parts belonged together and the whole editor seemed less clamped.
Emitting from shapes
Another highly requested feature was emitting particles from different shapes. At first I thought there would not be enough time to implement this, but as my specialisation began coming to an end there was some time that I could utilise. Initially my plan was to only make primitive shapes such as a sphere or box selectable as this seemed more doable. However, I later made it work with custom shapes and even got the particles to move in the direction of the normals of the shape.
When I was looking at Unity's particle system, one of the most interesting things I found was their callbacks. They allow different functions to be called on various events, for example when particles spawn or die. I would have loved to make it possible to call any function from the editor as can be done in Unity, although this seemed a bit out of the time frame. I decided to make it easy to play a sound or a spawn a new particle system on the events directly from the editor, and connect any function from code.