Demo.
This is a fluid simulation written in C++ and made available on the web via Google's Native Client. I originally wrote up an implementation of the paper "Particle-based viscoelastic fluid simulation" just to get my feet a little wet with Native Client. I ended up revisiting it with the intention of just working on optimizing that implementation but ended up rewriting it and going with a different methodology after going through the fluid simulation rabbit hole a bit.
Rather than produce yet another explanation of Navier-Stokes and all the bits of math behind fluid simulation I will just link to a few different resources I found useful:
- Fluid Simulation for Computer Graphics
- Jim Van Verth - Fluids Techniques
- Wikipedia Entry on Navier-Stokes
- Intel Fluid Simulation for Video Games Series
- Analysis and Reduction of Quadrature Errors in the Material Point Method (MPM)
- A Semi-Lagrangian CIP Fluid Solver without Dimensional Splitting
- Grant Kot's Fluid Demo
My simulation is to a large extent based off the work in the last few links; I started down this path after seeing Grant Kot's fantastic demo and fluid sim videos (which does a bit more than what I am doing here). The simulation works by tracking individual particles within the context of a fixed grid and "spreading" the particle values into the grid using a biquadratic interpolation scheme. From the grid I can then easily calculate my fluid forces and use these to then update the individual particles in the simulation. It is much faster than what I was doing before and works pretty well - although the fluid does end up compressing more than it should and the gridding seems to end up making things a bit more viscous. To be sure, I am not really going so much for accuracy here as something believeable and that could be dropped into a game to have some fun with.
As for the actual simulation steps they proceed roughly as follows:
Beyond that I also "cheat" a little and introduce a bit of a force near collision surfaces to push particles away.
- Clear all grid cells
- For each particle
- Determine grid cell and the 8 surrounding cells
- Calculate weights for biquadratic interpolation at particle position
- Add particle mass and velocity to surrounding grid cells based on interpolation weights
- For each particle
- Calculate interpolated mass and velocity gradients at particle position
- Use calculated mass and velocity gradient to determine pressure and viscosity forces
- Add these forces back into the grid cells
- For each particle
- Calculate interpolated acceleration at particle position
- Add acceleration due to gravity
- Update particle velocity
- Add particle velocity back into the grid cells
- For each particle
- Calculate interpolated velocity at particle position
- Update particle position and velocity with interpolated velocity
For more detail you can check out the source code I have made available here.