CS184 Spring 2026 Final Project

Worst Birthday Party Simulator

Names: Joshua Almario, Darren Ting, Cesar Garcia Santana, Ethan Ye

Link to webpage: https://cal-cs184-student.github.io/hw-webpages-veryspook/final-proj/final.html
Link to slideshow: https://docs.google.com/presentation/d/1QggFj0ua8ASPdhdrpTU8eDtUMwkxxGI65E8DnNJskkw/edit?usp=sharing
Link to video: https://drive.google.com/file/d/1qDuhHWTvNVGovq8kJF-AwNyAdjS3OISw/view?usp=sharing

Abstract

For many developers, smoke is rendered in the Unity engine using native particle systems. However, there is currently no support within the engine for dynamic 3D smoke simulations that accurately depict the behavior of smoke in the real world, such as the cases where smoke fills a room or when a window is opened in a smoke-filled room. With our project, we created a realistic depiction of smoke within Unity by treating it as an incompressible fluid and applying the Navier-Stokes equations to simulate its behavior in various scenes. With this approach, we found a way to accurately simulate smoke in a performance-friendly manner.

Technical Approach

We took inspiration from the implementation detailed by Jos Stam’s papers “Smoke and Fire in Real Time” and "Real-Time Fluid Dynamics for Games" to simulate smoke. Our implementation follows the Stam paper and runs a velocity step, density step, and additional temperature step to diffuse smoke densities between neighboring grid cells and ensure the velocity and densities are mass conserving. The main formulas involved are solving a Poisson equation to ensure the density is stable, and a linear backtrace to find the velocity at a previous timestep to ensure the velocities remain stable. We also add vorticity containment by calculating the curl of the velocity field, taking the curl magnitude, and extracting a force that we readd to the velocity field. This has the effect of reintroducing the swirl effect in smoke, which gets reduced by the algorithm's numerical approximations.

The primary difference between our implementation and the code snippets included in Stam’s papers is the dimensionality. The code extrapolated the original code into a 3D space by storing 3D arrays of fluid values, along with altering the substeps within the iteration. An example of this alteration lies in the density and velocity values, where the fluid density is stored in the middle of each cubic cell, while velocity changes are stored on the faces between each cubic cell.

Thanks to the Unity Engine, we can also use a 3D smoke texture using Unity’s Shader Graphs within the engine to visually represent the fluid. After creating the shader to render the smoke, we attached it to a volumetric fog object to allow the player to walk inside of the smoke. This allows for us to represent the scenes that we had planned, including the interactive candle on a birthday cake scene.

Problems and Lessons

We faced some issues with performance early on, where the smoke that we rendered would result in 4-6 FPS on our laptops. To fix this, we found many parts of our simulation code that we could parallelize using a variation of the Gauss-Seidel method. The variation that we used is the Red-Black Gauss-Seidel method, which involves calculating cell values in alternating fashion, much like a checkerboard. Additionally, the behavior of our smoke differed slightly from its real-life counterpart, so we added some extra conditions to our smoke such as temperature and vorticity, which readds the swirliness of the smoke. We learned through these improvements that iterating upon our simulation by incorporating new strategies and parameters that further control behavior aids the accuracy and efficiency of our smoke overall, which encompasses our primary goals for the simulation.

We also had difficulties visualizing the smoke itself. After much trial and error with rendering a texture onto a cube, we came up with the solution of creating a texture that we pass through a Unity shader, which is able to convincingly render the smoke in 3D.

Results

The following GIFs showcase our smoke simulation and its many components.
Low emitter rate
Medium emitter rate
High emitter rate
Early image of our smoke emitter utilizing Unity's volumetric fog component within the HDRP rendering pipeline
Low vorticity
Medium vorticity
Smoke with wind force
Smoke with stronger wind force
A preview of the asphyxiation simulation

References

Real-Time Fluid Dynamics for Games
Stable Fluids
Volumetric Fog in Unity
Simulating Smoke by Sebastian Lague

Contributions

Josh - Deliverable submissions, Unity project setup, movement & UI, Unity scene composition
Darren - Set up volumetric fog, Unity scene composition
Cesar - Implemented Jos Stam simulation and solver, created 3D texture
Ethan - Implemented Jos Stam simulation and solver, created external force support