Gentle Introduction to Realtime Fluid Simulation for Programmers and Technical Artists

Properties of Fluids

Video -1- Diffusion of soya sauce in water
Figure -1- Defining a body of water as series of fields on a cell
AmountOfSomethingInThisCell = What was spread from neighbouring cells + what was carried over from elsewhere due to the motion of the water + what was added in that frame by the user to that cell
FluidStateForFieldX = Diffusion_of_X + Advection_of_X + X_Added_by_the_user

Naïve Implementation, Diffusion

Figure -2- Grid A, field marked x is the cell currently being processed
d_X= d0_X + diffusionFactor * deltaTime (d0_01 + d0_02+ d0_03 + d0_04 -4*d0_X)

Naïve Implementation, Advection

Field_amount_for_target[cellPosition + current_cell_velocity * timestep] = field_amount_for_current_cell
Figure -3- Advection

Implementation, User Input

Amount_of_field_X += user_input_for_this_cell

What’s So Naïve About This?

Flaw One, Compressible Fluids?

Figure -4- Water molecules getting compressed
Figure -5- substance being constantly carried away from a point
Figure -6- fluid moving to where it can because it cant get compressed

Flaw Two: Bad For GPU Implementation

Flaw Three: Instability

Figure -7- Too large delta time lead to values blowing up. Each step has a local error which compounds over time to very large values

Projection

velocity_field + velocity_due_to_pressure_difference = new_velocity_with_no_pressure_differencevelocity_field = new_velocity_with_no_pressure_difference - velocity_due_to_pressure_difference
Difference_In_Pressure = -velocity_due_to_pressure_difference
velocity_field = new_velocity_with_no_pressure_difference + Difference_In_Pressure
velocity_field = Difference_In_Pressure + divergence_free_velocitydivergence_free_velocity = velocity_field -Difference_In_Pressure
Figure -8- different scenarios and how they lead to pressure or lack of
Figure -9- graphics and explanation to the Divergence operator
Figure -10- Pressure Field around cell 11
1/4 * (p[10] + p[01] + p[12] + p[21]) = p[11]p[10] + p[01] + p[12] + p[21] = 4 * p[11]
(p[10] + p[01] + p[12] + p[21])- 4 * p[11]
Figure -11- Gradient Operator, calculating the pressure gradient / difference in each dimension
velocity_field = Difference_In_Pressure + divergence_free_velocity
velocity_field = Gradient(Pressure) + divergence_free_velocity
Divergence(velocity_field) = Divergence(Gradient(Pressure)) + Divergence(divergence_free_velocity)
Divergence(Gradient(Pressure)) = Divergence(velocity_field)(p[10] + p[01] + p[12] + p[21])- 4 * p[11] = Divergence(velocity_field)
(p[10] + p[01] + p[12] + p[21])- 4 * p[11] = Divergence(velocity_field)

Solvers

Equation 1) y = x  + 1Equation 2) y = 5x - 2
Equation 2) y = (x  + 1) = 5x - 2 <= since y is also x +1
=> x - 5x = -2 -1 = -3
=> x = -3/-4 = 3/4
Insert back in Equation 1)
y = 3/4 + 1 = 7/4
X = 3/4 = 0.75, y = 7/4 = 1.75
Equation 1) y = x  + 1Equation 2) x = y/5 + 2/5 
Equation 1) y = 0  + 1 = 1Equation 2) x = 0/5 + 2/5 = 2/5 = 0.4
Equation 1) y = 0.4  + 1 = 1.4Equation 2) x = 1/5 + 2/5 = 3/5 = 0.6
Step 0) Input (X, y) = (0, 0), output = (0.4, 1)
Step 1) In(0.4, 1), out(0.6, 1.4)
Step 2) In(0.6, 1.4), out((1.4 + 2)/5 , 0.6 + 1 ) = (0.68, 1.6)
Step 3) In(0.68, 1.6), out((1.6 + 2)/5 , 0.68 + 1 ) = (0.72, 1.68)
Step 4) In(0.72, 1.68), out((1.68+ 2)/5 , 0.72 + 1 ) = (0.736, 1.72)
Equation 1) y = x  + 1Equation 2) y = 5x - 2
Figure -12- Graphical representation of solvers.
Figure -13- Solvers in the Nth step, always coming closer to the answer but never reaching it
Solve(Velocity_Divergence)
{
p_new[i, j] =((p[i+1,j] + p[i,j+1] + p[i-1,j] + p[i,j-1]) - Velocity_Divergence[i, j])/4
}
CopyOldToNew()
{
p[i, j] = p_new[i, j]
}
Velocity_Div_field = Divergence(velocity_field); 
for(int i = 0; i < 30; i++)
{
Solve(Velocity_Div_field);
CopyOldToNew();
}
deltaP = Gradient(p);
new_divergent_free_velocity = velocity_field - deltaP;

Diffusion Implementation

d_X= d0_X + diffusionFactor * deltaTime *(d0_01 + d0_02+ d0_03 + d0_04 -4*d0_X)
d0_X = d_X - diffusionFactor * deltaTime * (d_01 + d_02+ d_03 + d_04 -4*d_X)
d_X = (d0_X + diffusionFactor * deltaTime * (d_01 + d_02+ d_03 + d_04)) / (1 + 4 * diffusionFactor * deltaTime)
By changing _rDiagonal and _centerFactor and switching _b_buffer to be divergnece(velocity) in one and d_x0 in the other, I can use the same solver for both equations

Advection Implementation

Figure -14- Notice how this compares to the figure for a scattering version. quantities are always added to the cell that is being calculated and not carried off to some other location

Some Last Points

Final set up for a simple 2D simulation

Boundaries and Arbitrary Boundaries

Figure -15- GPU Gems chapter 38, the interior and boundaries cells
Boundary handling on the four corners.
Figure -16- Arbitrary normals boundaries diagram from An Improved Study of Real-Time
Fluid Simulation on GPU, Enhua Wu et al.
Arbitrary boundaries, the code includes the baking of the look up table as well as the actual shaders

Fake 3D Simulation

Lighting

  1. Specular lighting from directional light
  2. Refraction (for which I am simply garbing the texture behind the water and showing it with distortion/ displacement based on the movement on the surface of the water)
  3. Reflection

Reflection

Figure -18- The planar reflection alone is not enough for extreme displacement

Caustics

Fish Animation

Micro Details

Further Development?

Beauty Shots from the demo scene

Resources

  1. Stam 1999 Paper on stable fluid Dynamic, this is pretty much the god father of this method in compute graphics: https://www.researchgate.net/publication/2486965_Stable_Fluids
  2. GPU Gems entry on Fluid Simulation: https://developer.download.nvidia.com/books/HTML/gpugems/gpugems_ch38.html
  3. Harris, Fast Fluid Dynamics Simulation 2004 in GPU gems 3, chapter 38, it is the adoptation of the Stam 1999 paper with a Jacobi solver on the GPU: https://developer.download.nvidia.com/books/HTML/gpugems/gpugems_ch38.html
  4. Stam 2003 Real Time Fluid Dynamics for Games. Not sure what the difference between this one and 1999 paper is beside the solver being a Gauss Seidel relaxation solver. The 2003 kind of glosses over the projection method, but seems to use the same Poisson equation with pressure: https://www.researchgate.net/publication/2560062_Real-Time_Fluid_Dynamics_for_Games
  5. Adoption of the Stam 2003 for 3D and exploring rendering methods by Mike Ash: https://mikeash.com/pyblog/fluid-simulation-for-dummies.html
  6. Amador et al 2012, Linear Solvers for Stable Fluids: GPU vs CPU, discussion around the linear solvers available for GPU architecture: https://www.it.ubi.pt/17epcg/Actas/artigos/17epcg_submission_39.pdf
  7. Fedkiw et al. 2001 Visual Simulation of Smoke, method of bringing back vortices through vortices confinement which are lost in the simulation: https://www.researchgate.net/publication/2390581_Visual_Simulation_of_Smoke
  8. Ďurikovič 2017, Real-Time Watercolor Simulation with Fluid Vorticity Within Brush Stroke: https://www.researchgate.net/publication/321112340_Real-Time_Watercolor_Simulation_with_Fluid_Vorticity_Within_Brush_Stroke
  9. Curtis et al. 1997 Computer-Generated Watercolor: https://www.researchgate.net/publication/2917328_Computer-Generated_Watercolor
  10. Enhua Wu et al. 2004, An Improved Study of Real-Time Fluid Simulation on GPU: http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.99.7898&rep=rep1&type=pdf
  11. Thread discussing solvers: https://twitter.com/vassvik/status/1422115054980370438?s=20
  12. Rendering water as post process: https://www.gamedev.net/articles/programming/graphics/rendering-water-as-a-post-process-effect-r2642/
  13. Resource used for lighting the water, learn open gl: https://learnopengl.com/PBR/Lighting
  14. Catlike coding on water shading: https://catlikecoding.com/unity/tutorials/flow/looking-through-water/
  15. Realtime realsitic occean lighting https://hal.inria.fr/inria-00443630/file/article-1.pdf
  16. Wikipedia article on explicit and implicit numeric methods and stability: https://en.wikipedia.org/wiki/Explicit_and_implicit_methods
  17. Arbitrary boundaries, An Improved Study of Real-Time
    Fluid Simulation on GPU, Enhua Wu et al. : http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.99.7898&rep=rep1&type=pdf

--

--

Technical Artist

Love podcasts or audiobooks? Learn on the go with our new app.

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store