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".
At a single glance at the code (exactly where our scratch pad is defined) you'll see easily the correspondence between the scratch pad nodes and the HLSL code.
Let's see another example. We are going to "code" a simple blur effect. The algorithm is easy: in each step, take a cell and the adjacent ones, add up them and divide by the number of cells. After that, set the new value of the cell as the computed one.
Here a scratch pad that implements the algorithm. If we zoom in we can see the nodes used: basically a bunch of "GetPreviousFloatValue" node. No doubt: this is a hell. Both for read and edit.
We can see the blur effect in the next gif. It works as expected: in each frame we blur a bit the previous data in the Grid2D.
Only for completeness: the scratch pad used in the setup of the Grid2D.
If we take a look at the HLSL code of the Blur scratch pad generated, we'll see some repetitive structure. Furthermore, if we have some programming background, we know that we could code this as something like the second picture: a simple loop.
This the "why" part. Happily, the "how" part is built in Niagara and it is the node "Custom HLSL". In this node, we can write any custom HLSL routine, and even better, we can make use of functions owned by Niagara.
In the "old days", you had to dig in the engine code to know these Niagara functions (seem to remember) but nowadays it's simple as (right-) click in your object and select "Data Interface Function HLSL...". If you "Copy All" and paste in text editor you'd see the second picture.
Ok, having all this information, we're prepared to write the blur effect in a HLSL node. If you code it as the first picture you should see a generated code similar to the second and third picture. After code your node, Niagara do some "minor" modifications.
A very (very) similar way of doing this is the following. In the case we use "SetFloatValue" function (the same as the node) to update the value of the cell. In this case, you have to pass the "Context" through the "Custom HLSL" node creating a Niagara map at begin and at end.
Just one thing more about this node: the "out" variables created must not be declarated.
I'll end this thread talking about "Iterate a Simulation Stage". In some cases, like in a blur effect, we would like to repeat a whole simulation stage to make things happen faster. This is not (always) the same as duplicate a scratch pad.
Repetition can be achieved changing the "Num Iterations" parameter in the Simulation Stage parameters. In each iteration, some variables like Grid2D, write its new values and the old ones are available in nodes like "GetPreviousFloat" node. This not happen stacking scratch pads.
This is a good place to end this thread. In the next one, we'll start the fluid simulation implementation.
• • •
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.
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.
(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.
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.