Background
The OpenGL Particle System was created as a final project for my Intermediate Graphics Programming course. It was developed by Yuuki Endo, Issac Lovy and myself over the course of two weeks. I was primarily responsible for implementing the skybox and translation of visual scripting to GLSL. Work on the primary shader files was distributed across the team
This system is based on a presentation given by Ben Cloward, product owner of the Unity Shader graph, at GDC 2024. The original approach was created by Ryan Brucks at Epic Games and showcased at a 2019 GDC talk.
Demo
What and Why?
What you’re seeing is a particle system built entirely within a vertex and fragment shader in OpenGL. Using Ben Cloward’s in-engine shaders as a base we successfully translated the system into our own custom built OpenGL game engine.
As for why you might take this approach in an actual game setting, frankly it’s just a lot cheaper than most in-engine particle systems. Since most of the processes are running in the vertex shader, most of the operations are running on the GPU, making it faster than traditional systems. It’s also a lot more flexible than built-in systems, allowing you to control what features you do or don’t want.
How the system works
1.) We start by importing a mesh made up of 100 planes and using their bounding box to assign them a single 8-bit float vertex color attribute per plane
2.) Using that unique float attribute as a seed in a noise generator, we are able to assign each of them randomized vector 3 attribute (represented as vertex color). This random vector 3 value allows us to assign each planes different position offsets, scales, lifetimes, etc…
3.) We also billboard the planes to face the camera and use a flipbook and rotator function to animate the textures using UVs attributes
4.) In the fragment shader we are controlling the color, opacity and alpha clipping of the texture. Using the lifetime variable we can create color and opacity variations over the particles lifetime
Translating visual scripting to GLSL
Although we had examples from Ben Cloward that we could work from with a completed shader, all of them were created in existing game engines with visual scripting.
This meant that our first step was translating this plate of spaghetti into readable shader code. Our main resources were Unity’s Shader Graph documentation, which includes HLSL code for most of the nodes. Any node that wasn’t covered there was either created from scratch or based on a solution we found online.
Limitations
Our particles are not lit and do not cast shadows. We also did not have time to implement a depth fade function which would have allowed us to blend particles into the ground better. There’s several more features that could be added that we did not have time to, but the system is fairly scalable. And yes coding in OpenGL is more difficult than just using a visual scripting program.
Additional Functionality
We opted to use shader include files which allowed us to work in parallel and reduced the overall shader code complexity. Along with this we also implemented a skybox to better show off our work.
Project Sources
– Unity Shader Graph Node Library
– GDC Talk