Snow Globe 2 (3D Fluid and Particle Snow in a Globe)
|None (Personal project)||None||Summer 2015 (ongoing)||C++||No||Github Repo - particle sim|
This simulator has a spherical collider, particle-based snowflakes and an Eulerian 3D grid-based fluid solver, inspired by Jos Stam's GDC paper Real Time Fluid Dynamics for Games. Anyone who wishes to build a fluid simulation should start with this paper. It is very simple to understand and provides almost all the code required to implement the simulation in 2D, along with explanations as to what is the code is doing as well as an overview of the underlying physics being simulated.
The stability of such a simulation comes from the fact that it utilizes implicit integration, which is unconditionally stable since it is "prognosticating" in a sense, yielding stable results by projecting future results back in time, and in this implementation it incorporates two different integration mechanisms acting at different stages of the simulation.
Implicit solvers normally involve inverting a large matrix, which is computationally expensive, but many mechanisms exist for approximating the inverse of a matrix, often via iterative means. For the diffusion stage, the implicit calculation is accomplished via just such an iterative method called Gauss-Seidel.
For the advection stage we use a semi-lagrangian backstep mechanism, finding the locations of where the fluid quantity (density, velocity) we are solving for would begin from so that it would end up in the center of each cell. We then assign to this cell the old value at this derived location via linear interpolation.
For my simulator, to achieve the nice circular boundary of the collider, I set the fluid velocity to reflect across the internally-pointing normal, and for each particle, I interpolate the fluid velocity in the neighboring grid cells based on the particle's location within a particular cell to then apply to each particle, which is then integrated via RK4 to provide a position and velocity for each particle.
To generate turbulence I add force to the fluid in the sphere by dragging the mouse, as if the snow globe was moved in the direction of mouse motion, and the walls of the globe were "pushing" on the fluid with the mouse drag "force" projected along the mesh's surface.
Recently I revisited this solver to improve the behavior. One of the limitations of grid based solvers is numerical dissipation. Swirly motion (called vorticity) near the scale of a grid cell is lost due to the nature of the solver. This vorticity can be added back into the results using a mechansim from Computational Fluid Dynamics called Vorticity Confinement that was introduced to the graphics community first by Fedkiw, Stam and Jensen's paper Visual Simulation of Smoke. By first calculating the curl of the velocity field we can derive the vorticity field, and then calculating the normalized gradient field of this vorticity (pointing from lower to higher vorticities), we can derive a suitable value that we can add back into the fluid to preserve these vorticities (by replacing what was responsible for them that might have been lost). While the original vorticity confinement algorithm is intended for near-inviscid flow (like air or smoke), it works reasonably well with the fluid here (I use a very small non-zero viscosity value), although it would be insufficient to model turbulence, since it can only add vorticity that is already present. The method introduced by A Vortex Particle Method for Smoke, Water and Explosions is more appropriate for this, and I intend to upgrade my simulation to include this mechanism as well next.
Below are videos of the snow globe in action (with links if the videos don't play automatically) :
|Snow Globe With Basic Stable Solver|
|Snow Globe With Vorticity Confinement - note that the snowflakes maintain their distinctness, and don't clump as much.|