Jose Moreno Profile picture
Oct 15 26 tweets 8 min read
It's time to solve some fluid dynamics equations! These are the well-known Navier-Stokes Equations which describe the motion of a viscous fluid. #ue5 #niagara #gamedev #techart #houdini #math
Image
There are three or four unknows in this system of equations, depending on whether we are in 2D or 3D case. The main unknows are: the velocity (two or three components) and the pressure.
The first equations, one for each component of the velocity, are called "momentum equations" and are basically Newton's F=ma applied to a little fluid element. The last equation is the "continuity equation" and it means that the flow is incompressible, i.e., density constant.
The "velocity" is a vector field that represents how fast and in which direction the fluid moves through the space. The "pressure" is related with the force exerted by the fluid at any point inside it.
These equations need one more thing to "close" the system: a boundary condition. Usually, we don't solve the fluid equations in all (infinite) space. We restrict the equations to a finite region.
Given that our equations may vary in time and space we need to say something about the equations at some initial time (at every point in the space) and what happen at the "boundary" (in every moment).
For viscous fluids this reduces to: all velocity components equal zero at boundary region and initial velocity arrows inside our region (maybe zero too). Image
When we solve numerically this system of equations we obtain simulations like the one in the gif (thanks @keenanisalive).
This is all the fluid dynamics knowledge we need to know before we start. There are infinite books/blogs/papers about this topic but I would hightlight Joe Stam's Stable Fluids paper d2f99xq7vri1nk.cloudfront.net/legacy_app_fil… and the NVIDIA GPU Gems blog developer.nvidia.com/gpugems/gpugem…
Ok, now (really) we are going to solve (numerically) the Navier-Stokes equations. But...how? What means "solve" in this context? Let's start with something simpler.
I'm going to introduce two "simplifications" of the Navier-Stokes: one is Laplace-Poisson equation and the other is the heat equation. It can be observed, that both equations can be obtained when some of the terms of the Navier-Stokes equations vanish. Image
Solve numerically these equations consists in finding a finite set of values that (almost) satisfy the equations. The most common strategy is discretize the region of values that varies (i.e. space; and time, in heat eqn.).
Math says that in "the limit" of subdivision of our region, the numerical solution "converges" to the "real" or continuum one.
In the picture we have a visualization of "discretization". All figures represent the same function, u(x,y) = x^2-y^2 (that satisfy Laplace eqn.), with differents "levels" os discretization. Image
But here, we are only taking a known function and evaluating in our discrete region. Let's think in the other way: what conditions must satisfy our discrete points to solve Laplace eqn? Well, basically the expression in the picture. Image
If you have some math background, you'd know that these derivatives can be aproximated using some finite differences, so the last relation can be written as the picture below (we are taking f=0). We use "h" as the uniform distance between (x.y) points in the grid. Image
This is an interesting expression. It tells us that the value of a function that satisfy Laplace eqn. in a specific point is the average of the function evaluated in the adjacent points. This is called "Mean Value Property" of Laplace eqn.
Doing the same thing for the heat equation (using finite differences for time derivative) we get the expression in the picture below. In this case we use "Delta x" to mean the same as "h" and "Delta t" the subdivision in time dimension. Image
So, we have numerical "schemes" for our problem! In the second one is easy to see that we can "leave alone" the value with uppper script "n+1", that is the value of the function in (i,j) point in space and (n+1) in time. We use the "old" (time n) values to reach the next.
But, in the scheme for Laplace equation, we don't have time. The values at the left and the right of the equal sign have the same priority. For these cases, we have "iterative methods" like Jacobi or Gauss-Seidel that try to reach the solution bit a bit.
The scheme using this method reads as follows. Image
We are going to prototype this iterative method in Houdini (suited for nice visualization). We'll use u(x,y)=x^2-y^2 in the boundary to compare our last example. The pictures show the Laplace eqn implementation. ImageImage
Here the solver over different size grids.
The solver for heat equation works (very) similarly. All the things we are been doing in this thread is the "core" of the fluid dynamics simulation that we are going to implement in Niagara, as we'll see soon.
Sorry for the long thread mixing, maybe, too hard or too easy concepts. But I think is good to see this kind of things (maybe in messy way) and take some time to think about how and why the things work. I think is good point to stop.
PD: In the visualization of the solver we are seeing the solver (with different grid sizes) versus its analytical solution u(x,y)=x^2-y^2. That is, evaluate the (x,y) point in the functions directly.

• • •

Missing some Tweet in this thread? You can try to force a refresh
 

Keep Current with Jose Moreno

Jose Moreno Profile picture

Stay in touch and get notified when new unrolls are available from this author!

Read all threads

This Thread may be Removed Anytime!

PDF

Twitter may remove this content at anytime! Save it as PDF for later use!

Try unrolling a thread yourself!

how to unroll video
  1. Follow @ThreadReaderApp to mention us!

  2. From a Twitter thread mention us with a keyword "unroll"
@threadreaderapp unroll

Practice here first or read more on our help page!

More from @jose_morval

Oct 24
In this thread we are going, finally, to implement Navier-Stokes simulation in Niagara. We should obtain something like in the gif below. #ue5 #niagara #vfx #gamedev #math
Following the steps in Stam's Stable Fluids paper, let's split our original problem into smaller ones. Basically, we solve the momentum equation (apply forces, advect velocity and diffuse it) and after that we force that computed velocity to be divergence-free using the pressure. Image
We know how to solve (from the previous thread...more or less) all the elements of last picture, except maybe the "advection" step. Luckily, it can easily solve using a method called "Semi-Lagrangian scheme". Again, I recommend you take a look to @nvidia GPU Gems blog. Image
Read 17 tweets
Oct 12
Before getting into the fluid simulation thing we are going to talk about "programming" in a simulation stage and why do this. #ue5 #niagara
Let's suppose we have a scratch pad like the one in the first picture. As we know, this scratch pad runs for every cell in the Grid2D. But, what is it exactly "running"? Image
Every scratch pad, when we are in "GPU mode", is translated to HLSL code. Fortunately, Niagara can show us this translation. If you select your emitter (and you are in the "Generated Code tab") you should be able to choose "Particle GPUCompute Script". Image
Read 17 tweets
Oct 1
At the end of the last thread, we painted a moving circle in our Grid2D. Let's take a big leap transforming this circle into a simple "trace effect".
To do this, we're going to create a new Niagara system in world space that renders a single sprite, parallel to the ground, with a material that reads a texture (with the trace) created in Niagara. It's the perfect effect to learn a few things.
Formerly, this kind of effect was created using some render targets, a material and a blueprint. Now, is the same, but all inside Niagara and, in my opinion, in a more "natural" way.
Read 19 tweets
Sep 28
At the end of the first thread, we set the same value for all cells in the Grid2D. Now we are going to make something more interesting. #ue5 #niagara
(2/13) Let's create a scratch pad in the Simulation Stage. In this one, we are going to use the node "Execution Index", that assigns an integer for each cell, and set as the value of the cell. Previously, we normalize it using the dimensions of our Grid2D. Image
(3/13) For debugging tasks, it is useful ticking the "Preview Attributes" flag in the Grid2D definition. When you enable it, you should see something like the second image. In this case, I've chosen a low number cells so that we can see clearly the differences between cells. ImageImage
Read 13 tweets
Sep 26
I'm going to write a few shorts threads for those who are starting in the wonderful world of simulation stages in #ue5 #niagara. The ultimate goal is code a (simple) fluid solver in 2D/3D that allow us, for example, driving particles by fluid simulation in a similar way as games
(2/15) like Returnal or God of War does.
(3/15) As (I hope) you know, Niagara is a highly customizable particle system framework. You can put logic on every step: when the emitter spawn, when it updates, when a particle spawn and when it updates. Furthermore, you can add new attributes to particles to play with.
Read 15 tweets

Did Thread Reader help you today?

Support us! We are indie developers!


This site is made by just two indie developers on a laptop doing marketing, support and development! Read more about the story.

Become a Premium Member ($3/month or $30/year) and get exclusive features!

Become Premium

Don't want to be a Premium member but still want to support us?

Make a small donation by buying us coffee ($5) or help with server cost ($10)

Donate via Paypal

Or Donate anonymously using crypto!

Ethereum

0xfe58350B80634f60Fa6Dc149a72b4DFbc17D341E copy

Bitcoin

3ATGMxNzCUFzxpMCHL5sWSt4DVtS8UqXpi copy

Thank you for your support!

Follow Us on Twitter!

:(