Rookie Awards 2024 - Open for Entries!
Firework Particle Effect
Share

Firework Particle Effect

Alexandra Cuthbert
by BackgroundWhimsy on 15 Dec 2023

Project 1 of 3 for EAE 6350 - Tech Art I

0 166 0
Round of applause for our sponsors

Ever since I learned the basics of particle simulations back in my Visual Effects class at BYU, I can't help but look at fireworks and think about how I could recreate them as a particle effect. So, when I was given the opportunity to set my own project for Tech Art I, I knew exactly what I wanted to do.

As with any effect, I started with some studies of reference footage and the physics of real fireworks. I found some statistics about how high they go, how fast, and how wide the burst charge tends to be, and then used those numbers as the foundation of the effect in the Unity Engine to help keep everything to-scale. Up until now I'd only ever done particle effects in Houdini. Learning to build particle effects with the Unity Engine was an added challenge for this project.

At it's most basic, a firework is a rocket with two stages: a lift charge and a burst charge. The lift charge propels the firework into the air, at which point the burst charge explodes into a cloud of sparks. For this effect, the lift charge was modeled by a single particle that spawns more particles for the burst charge on death. Each of those particles can then spawn extra components of the effect, such as smoke or spark trails.

Unity has two separate systems for building particle effects like the kind I was after, and initially I started with the Particle System. I wanted an effect that could be placed anywhere in the scene and adjusted with just a few relevant parameters, where all the setup for the basic shape of the firework effect would be handled in the background by a script so artists and level designers wouldn't have to worry about the technical details. At the time I was most familiar with making interfaces like that by writing C# scripts. Unity's Particle System lent itself nicely to scripting, so I figured it was the best place to start.

I got about as far as setting up the controls for the lift charge before I decided to abandon that avenue and swap to Unity's other effects system. Providing parameters to control the Firework's lift velocity and detonation delay went smoothly enough, but scripting with the Particle System was more complicated than I expected and I wasn't seeing the options I needed to create the burst charge while looking through the documentation. It was easy enough to create a smoke trail for the single particle involved with the lift charge, but that particle would then need to spawn an entirely new set of particles to create the burst. I couldn't find a way to script the behavior on the death of the particle and I didn't have time to delve into the inner workings of the system and design it myself, so I needed to look elsewhere for a system that supported that function.

Unity's other effects system, VFX Graph, was just the system I was looking for. To start, the VFX Graph supports far more particles than the Particle System, and includes a quick and easy interface for spawning particles off of other particles. As a node-based system it was easier to pick up and start working with, and it allowed me to create the simple parameter-based interface I wanted for my users. It took me less than a day to replicate the effect it took me a week to figure out how to build with the Particle System script, and only a few hours more to get the burst charge working.

Once the basic shape of the firework was in place I was free to focus on setting up extra features and exposing parameters to provide artists with variations on the effect. In addition to specifying the lift velocity and detonation time, the user can also add a controlled amount of randomness to the firework's trajectory and detonation delay. Every part of the effect can be switched on or off depending on what the artist wants out of the firework, and those parts each have their own set of parameters for even finer control of the effect.

Even the sparks have some amount of variation. Rather than use a single sprite for every burst charge, I found multiple different star shapes I could use and randomized which spark was chosen for every firework.

I spent a lot of time fiddling with the default values of the firework to make it look as realistic as possible, especially the smoke trails. How long the smoke lingered, how it hung in the air and dispersed with the wind, what color and how big each particle was - getting the smoke right was very important to me, because it's practically half the effect. The colored sparks are pretty, but the smoke helps ground the firework in reality.

The pixie dust effect on the dying burst charge particles was one of the first things I thought of when I started brainstorming variations for this project, and one of the last things I added to the graph. The sparkly pixie dust fireworks are my favorite in real life, so of course I had to make them in the engine.

The biggest drawback of using the VFX Graph was the lack of encapsulation. It is possible to collapse a set of nodes into a subgraph, but it isn't currently possible to trigger those subgraphs with the GPU events that let particles spawn other particles. So, even if I were to separate the nodes for spark trails and smoke into smaller graphs, I still can't actually use those subgraphs to make the overall firework more efficient.

The highlighted sections of this early version of the graph are identical, since the smoke for  the lift charge  and the burst charge should be the same. Ideally, I would have been able to put those nodes into a subgraph to avoid copy-pasting the same chunk of code over and over in the graph, but it just wasn't possible with the current system.

Originally I'd wanted to provide multiple styles of burst charge, maybe even a way to randomize which burst would be chosen for any given firework, but without encapsulation it would've made the graph too unwieldy. A single burst charge needs about three or four systems to account for the burst itself and any extra parts of the effect, such as smoke, spark trails, or pixie dust, so having more than one burst charge in the same graph would've been an absolute mess of tediously repetitive copy-paste code.

Still, as evidenced by this footage from before I realized how big of a problem triggering subgraphs with GPU Events would be, it is possible to make multiple burst charges. I had fun setting up this rough version of a Saturn-shaped burst, though it needs more fine tuning before I'd be completely happy with it.

Despite those missing features, I'm pretty pleased with how this effect turned out. Maybe there's a way to trigger the subgraphs I need by combining the VFX Graph with a C# script, and I'll be able to add even more options for variation in the future. For now though, this project is complete.


Comments (0)

This project doesn't have any comments yet.