22 comments

[ 2.6 ms ] story [ 51.0 ms ] thread
So once upon a time I stumbled upon simulating fluids in gamedev and I really wanted to learn how it works. Fast forward 2 months and I decided to write down everything I learned to hopefully make it easier for others in the future!
excellent article, great vulgarisation and human written !

Thank you

Great job. I have spent a lot of time working on fluid simulations (I still am). Glad to see more people still mesmerized. If you’re interested, this rabbit hole goes very deep.
This is really cool. I love how much detail you went into explaining the setup and walking through each piece of the simulation. Definitely bookmarking this to play around with later!
Nice writeup. One thing worth adding to the limitations: without vorticity confinement, the Gauss-Seidel projection step quietly dissipates the small-scale curl that makes smoke look like smoke.

The 2001 Fedkiw/Stam/Jensen "Visual Simulation of Smoke" paper added it back as a correction force for exactly this reason. At N=16 it doesn't matter much because the grid itself can't represent fine vortices, but the moment you crank N up the missing confinement becomes visible.

Thank you, that's good to know when I try to move this to a Compute Shader and try to make it part of a game in the future
Oh don't let us pinch zoom. That would be a disaster.
For anyone wanting to dive further, Fluid Simulation for Computer Graphics by Robert Bridson is the definitive textbook.
Did they test if it satisfies the relevant conservation laws?
This is great! When I have some leftover time I want to try copying this implementation for 3D. I reckon I could get away with minimal modifications to support the third axis...I think...

That'll perform even worse though, hopefully my CPU can handle it or I'm gonna need a lot of leftover time to make a shader

Yes, this should be relatively easy to extend to 3D. Performance might pose some issues so I advise to stick to a small grid, or look for optimizations like decreasing the amount of Gauss-Seidel loops etc. Moving this into a C++ library would also probably help a lot
Before you go adding vorticity confinement, consider performing a higher-order backward advection scheme (Runge-Kutta 2nd or similar), and using a higher-order interpolation method (triangle-shaped cloud instead of bilinear).

In my implementations I use 4th order for both and vortices stick around a lot longer.

If you implement this on the GPU, it's my understanding you can get the 4th-order interpolation quite cheaply exploiting the bilinear texture sampling hardware[1].

So instead of reading 16 grid values and combining them to get the interpolated sample value, you can fetch 4 bilinearly filtered samples and combine those. And thanks to the hardware filtering, those bilinear samples cost basically the same as reading an unfiltered value.

[1]: https://developer.nvidia.com/gpugems/gpugems2/part-iii-high-...

Yes, I do 4th order interpolation (M4') on the GPU. This paper is for 3rd order, though, but the methods may extend.

I suppose because the fetches are generally to similar memory regions, there may not be a substantial performance improvement due to L1 and L2 hits on recent GPUs.

I appreciate the AI disclosure, I hope that becomes normalized
I wonder how it'll read in 20 years. Like all the covid references in blog posts from 2020, or vague references to "the current political situation" from any point in the last 10 years or so.
Very cool. For your next project, how about a DIY 2D EM field solver? You've done a lot of the work already.