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:

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:

  • 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
Beyond that I also "cheat" a little and introduce a bit of a force near collision surfaces to push particles away.

For more detail you can check out the source code I have made available here.