(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.
(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.
(4/13) If we add a second float value to the Grid2D, leaving the debug mode on we have another "minitexture" that shows the value of the variable declared as "Second Value".
(5/13) We've used an useful node called "Execution Index to Grid Index" which converts from Linear Index (cell 0, 1, 2, ..., 63) to Grid Index or "matrix index" ([0,0], [0,1], ..., [8,8]). This conversion is essential when you need some kind of spatial relation between the cells.
(6/13) Later, we'll add to the Grid2D other types of variables as Vector2 or Vector4. For these cases, you'll visualize each "float channel", what it tells us (maybe) something about how Niagara works under the hood: non-float variables are just for us, insignificant humans.
(7/13) Following "the drawing examples", we are tryiing to draw a moving circle in the Grid2D. This is very similar as you would do in a material: you take the UV's of your square, substract (0.5,0.5) to center, compute the length and a little "step" and...voilà!
(8/13) Ah, ok! I move the circle adding a small "circular motion offset" (cos(t), sin(t)). Furthermore, I've used a new node called "Execution Index to Unit" which converts from Linear Index to UV (basically what we did in the previous example).
(9/13) We should see something like the following gif. At first, we have a resolution for the Grid2D of 8x8. Later, 128x128. I forgot to metion that I muted "My Pad" scratch pad, so there is only one (float) channel in the grid (and in the debug).
(10/13) At this point, your body asks you (maybe) for some "persistence" or trace effect in the last dynamics. So, it's time to introduce other member of our node's family: GetPreviousFloat node which gathers the previous (in this case float) variable of our grid.
(11/13) If we add the previous value of our grid, scaled down a little bit, to the current value we should see something like the gif.
(12/13) The scratch pad looks like the images. This is very much like at what you'd do in material.
(13/13) This is the end of our second thread :)
• • •
Missing some Tweet in this thread? You can try to
force a refresh
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.
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.
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
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.
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"?
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".
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.
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.