top of page
Particle Editor Tool
Specialization Project
What is this
What you see here is a particle editor tool that our technical artists have been using to create all the cool particle effects in our latest two games. It was developed inside of our own C++ DirectX11 game engine Firefly, using ImGui as the graphical user interface.
You can import a sprite to represent a particle in the system and tweak a bunch of values to tailor the particle system to your liking.
The tool was initially developed for our 6th project, Spite: Journey to the Top, and was also used in Zenith.
Background
During my time at The Game Assembly, tools has been my favourite thing to work on since I get to develop things for others to use and enjoy. I also get to put a lot of time and effort into making things that are simple and easy-to-use which helps me and my colleagues achieve our goals. I also believe that we make better games together as a result.
When given the opportunity to specialize and dedicate a few weeks to a project, I decided to further develop my favourite tool, the particle editor. The reason why it is my favourite tool is simply that I had such a blast making it. Firstly, I got to work closely with our creative technical artists, Henrik Lidén and Frida Hagelstam, that I really enjoyed working with. And secondly, I got to work with particle emission and all the fun math behind it.
Goal
The goal of this project was to allow the creation of mind-blowingly cool visual effects inside of the particle editor.
I wanted particles to emit from the surface of any mesh, static or animated, inspired by this video.
I also wanted to be able to run this on a stable framerate, by running the particles on compute shaders.
Week 1 - Static Meshes
During the first week of the project, I focused on emitting particles from the surface of static meshes.
Final result from week 1, particles emitting from static meshes
Random Triangles
Before vs After area compensation
Meshes are in essence just a collection of vertices in 3d, where trios of vertices make up triangles, that together make up the surface of the mesh. Therefore, to emit particles from the surface of a mesh, I had to generate a random point on a random triangle and spawn a particle there.
There is a slight problem with simply taking a random triangle, particles will spawn the same number of times on large triangles as on smaller ones. To solve this, I weighted the randomness to take area into account.
Random Point on Triangle
Now that I had a random triangle based on area, I also needed a random point on that triangle. I already knew how to get a random point on a parallelogram. You take the two vectors representing the base and the side and scale their length randomly from 0 to 1. This results in two new vectors that you can add together, and the result is a random point inside of the parallelogram.
Now it was time to find a random point on the random triangle. I did some research, and found out that I could use the same approach. What I could do was "flip" the result if the point was on the second half of the parallelogram.
Random point on triangle technique
At the end of the first week, particles could spawn evenly distributed on the surface of any mesh, which turned out quite nicely.
Week 2 - Animated Meshes
The second week of the project came around and it was time to make the particles emit from animated meshes.
Final result from week 2, particles emitting from animated meshes
Bug from Week 1
Before vs After bugfix, the monkey got his staff back
But first, it was time to fix a bug that I realized I had from week one, particles did not spawn on sub-meshes. It took some time to debug, but I finally found out why it didn’t work.
When I loaded the mesh for the particle editor to use, the vertices from all sub-meshes were placed in one long vector. However, the indices that refer to which vertices make up which triangles, obviously referred to the vertices of each sub-mesh, not considering that I stored them all in the same place. Now it worked wonderfully, even the monkey’s staff could have particles.
Animated Meshes
Now that every part of the static mesh emission worked, it was time for animated mesh emission. Animations are essentially a sequence of transformations made to a bone-hierarchy, or a skeleton. The vertices of the mesh then follow the bones according to some bone-weight.
The result of this process is a mesh that can move, and I needed the moved triangles of said mesh to generate my random points.
Player character from Zenith running
Animated Mesh Emission
Player character from The Morning of Bo dying
To get the moved triangles, I first needed to get the transformations from the current animation frame. I did this by fetching the resulting bone-hierachy from Fabian Randau's animation system.
Next, I had to move the vertices according to the bone-weights. This is usually done in shaders on the GPU, and in our engine, it’s no different.
However, I needed the vertex positions on the CPU. So I had to rewrite the shader code in C++, and while it did cost some performance, it worked. This could have been done on a compute shader to speed up the calculations, but this works for now.
My previous mesh emission code could now run on an animated mesh by dragging & dropping an animated mesh to the particle system in the editor, and it looks awesome.
Week 3 - Force Fields
For week 3, I initially planned on optimizing the rest of the project to expand my knowledge of compute shaders. Instead of following my initial plan, I ended up being inspired by this video and I wanted to start working on Force Fields right away.
Final result from week 3, particles affected by Force Fields
Point Fields
Although force fields look really neat and create complex visual effects, the math behind them isn’t all that complicated.
Firstly I check if the particle is within a certain range, and if it is, I apply a force to that particle towards the centre of the field. It’s very similar to gravity, where under the right circumstances, a particle can end up in orbit. The force can also be negative, pushing particles away from the centre instead.
Cube Fields
I also added a second type of force field that is formed like a cube. Instead of attracting particles towards a centre, the cube applies a force in just one direction. This can be used to simulate particles blowing in the wind for example.
Week 4&5 - Portfolio Website
The final two weeks did not consist of any work on the project, but rather full focus on the creation of this portfolio website and my CV.
Reflections
When looking back at the project, I am super happy about how it turned out. I think I really accomplished my goal of creating mind-blowing visual effects. I ended up not implementing compute shaders since well, it did not really need to be optimized, at least not right now. Instead, I focused on creating a second powerful visual effect in the form of Force Fields, and I am happy I did that.
I am also very excited to integrate this version of the particle editor into our 8th and final game project at TGA, and I cannot wait to see what our technical artists can do with the new features.
The scoping of the project turned out to be perfect, we had 5 weeks halftime to complete this specialization project, this portfolio website, and my CV. I only worked on the project during the first 3 weeks and I didn't come across any major issues. The last two weeks could be fully dedicated to creating this portfolio website and writing about everything I wanted to share with you.
bottom of page