top of page


PARTICLE SYSTEM

Introduction

For our sixth game project at The Game Assembly, I started working on a data oriented Particle System accompanied with an Editor using Dear ImGui. Using Dear ImGui was the clear choice, since it was an easy and fast way to get a graphical user interface set up and we already had it implemented in our own custom engine. The main focus here was to get something up fast that we could use for the project and availible for anyone in the project to create various types of particles. The result can be seen in our project Spite - Infected Grounds.(link)

Later, for my specialization project, I decided to refactor the particle system to be more modular and get advantage of the current and much more developed state of our own custom engine and level editor, and add more interesting features. 

Implementation

We're using entity component systems in our engine that is well integrated with our level editor, so why not take advantage of that. The particle system component is merely a data structure, holding it's specific data for the emitter and particles to be emitted; everything from the necessities such as particle lifetime and spawn rate, to more complex data as color gradients, curves for size and even shapes that defines how particles are spawned. Textures and meshes are  cashed and their ID's held by a Material- respectively Model Component, which we use for everything that should use textures or meshes in our engine.

The system itself holds a list of entities with this component, making all the calculations to spawn and handle the particles. At the end of each frame it prepares a render command, another data structure, for each particle and sends to a drawer. These commands hold the final result for each particle every frame, based on the data originally from the particle system component, and rendered with alpha blending without writing depth in a mid-late render pass.

Features

Before development I gathered references and inspiration from different sources. Discussions with team members and teachers at The Game Assembly gave me some clear lines on expected and must-have features. Also by diving into Unity's particle system and Unreal Engine's Niagara added some features to the to-do list. Below are some of the more interesting features that I've implemented to the particle system and editor.

Shapes

One interesting feature I wanted to implement was one alike Unity's shape module, which Niagara of course have a contrary for​. I went for the common types: box, sphere and cone; along with static mesh. The module defines where a particles should spawn and its initial direction. The shape has its own transform that is relative to the entity's, which makes it possible to tweak its orientation as needed. The user can also randomize the resulting direction and position of the particles.

       Sphere

Having the sphere shape selected, the user can tweak the values displayed. The interesting parameters here are:​

  • Mode, how particles spawn along the defined arc.

    • Randomly​

    • Looping order

    • Oscillating order (ping pong)

  • Arc, 0-360 degrees of the sphere​

Even though the box type has the least parameters, it can be powerful.

       Box
  • Emit From, where the particles are emitting off the box.

    • Volume​
    • Face

    • Edge​

The shape can also be defined by a the vertices of a mesh, where I use the vertex position and normal for the particles initial position and direction.

       Mesh
  • Mode can be selected, spawning particles accordingly to the vertices.

    • Randomly​

    • Looping index order

    • Oscillating index order

Here I use the Model-ID from the Model Component to get the cached vertex data of that particular .fbx.

Properties Over Life

Being able to tweak how emitters and particles behave over their lifetime is another powerful  concept for the artist to work with. Here I'll demonstrate a few uses of a curves, gradients and UV offset and tiling. 

The curve is editable with our curve tool, inspired by r-lyeh(github). Applying the curve to a parameter is fairly simple: T value equal the instance's relative time divided by its full lifetime, then using it to interpolate between two values, such as min-max spawn rate or start-end size.

        Curves

While the same curve could be used the same way for color, i's quite a challenge for the artist to visualise in colors. Therefore I applied a gradient structure that, instead of holding 2d points, having colors, alpha values with 1d positions. Using the same T value as for curves, the gradient returns the combined interpolated color wtih alpha. Inspired by effekseer(github).

       Color Gradient
       Texture multiplication

Inspired by the visual effects created for Diablo 3, I decided to implement their base feature: texture multiplication. With a few textures UV scaled, tiled and panned over time, an artist can create effects on a whole different level.

 

The math for texture multiplication is simple and fairly cheap: multipying float4 componentwise.

This effect is made of 16 particles, randomly rotated, scaling over time and alpha fading in and out. On top of that it's two textures multiplied to get their result as color and alpha. 

Mask

V += 0.5/s

Alpha_Map_output.png
Player_RocketLauncher_LMB_Release.png
     Shaded Particles

For particles to fit more into the environment, shading them with surrounding light sources can be a powerful feature. Here is an attempt to make something inspired by Dead Space Remake with shaded smoke, as shown in this video.

With clustered shading recently set up in our engine, it is possible to evaluate the surrounding lights that should affect a particle. You can read my collegue's article about clustered shading over at george-chahine.net.

Gallery

Some of the effects the artists in the team and I have put together.

bottom of page