Niagara Mesh Particle Stretch Effect: How Does It Work? Help Please

00
01

Hello, while watching tuatara’s youtube video I noticed the interesting and seemingly simple technique you see above (It’s not simple). I want to understand the technical working principle, please help with this by answering the questions I ask.

(Writing about the screenshot above) The material looks simple. We subtract the Particle position from the XYZ position (XYZ = 0 in Dynamic Parameter), add a mask so that the bottom part is pulled by UV at the beginning, followed by the top part.

This material does not work without the following specific Niagara system settings.

  1. Interpolate Over Time module with the Input Position: (Particles: Position)

As I understand it, the Interpolate Over Time module makes a smooth transition between digital values. (Not 0 → 1, but 0 → 0.1 → 0.2 → 0.3 etc), where smoothness of transition depends on Rate Of Сhange item.

Target Vector Value - This is the target we want to move towards (In our case dynamically updated Niagara position on the scene)

Conversion Operation: Passthrough as a Non-Large World Vector - Treats values as vectors (directions), not positions. It doesn’t tell where to come (position), it just shows which direction to go and how fast.

4_lossy
View of effect when Rate of change = 0.5


A new Vector 4 parameter is created. For Vector RGB, the following is selected:
(Particles, Interpolate Over Time, Interpolate Over Time V3: Moving Average).
For the Float (Alpha), nothing is added.

The Dynamic Material Binding is changed to our new Vector 4.

At the same time, the value of Float (Alpha) works as the alpha of our material (responsible for the mask’s intensity). If Dynamic Param Alpha in the material is disabled, then Float Alpha will not affect the emitter either.


Inherit Source Movement is a module in Niagara that allows particles to inherit Niagara System Actor object on the scene. Does the same thing as Local Space (If Local Space is switched off)

The Dynamic Parameter module is not essential (without it, everything works), but in practice, changing its parameters has no visual effect. Specifically, WPOIntensity (Dynamic Param Alpha) doesn’t work in the Dynamic Material Parameters module. Instead of that the Float in the new Vector 4 module does what Dynamic Material Parameters → WPO Intensity should do.

Here’s how it works. Please answer the questions:

  1. Why do we set the start position in the material as a Dynamic Parameter (split via Make Float to XYZ)? Can we use something else? For example Object Position, etc. What exactly happens when we subtract Particle Position from Dynamic Parameter (split via Make Float to XYZ)? Why does everything work with it?

  2. Why is it that if you turn off the Dynamic Material Parameters module, nothing changes, but if you turn it off in Material (as coordinates), the effect is broken? Why does Float in the new Vector 4 module does what Dynamic Material Parameters → WPO Intensity should do? Why doesn’t WPO Intensity itself work? Why if I change XYZ no matter where: in the Niagara module in Dynamic Param, or inside the Dynamic Param in material = nothing changes on the stage? (It changes only visually in the Niagara viewport)

  3. Why is a new vector 4 module created? Why is Moving Average inserted into it in Vector RGB? Why is a new parameter inserted in Dynamic Material Binding?

Below is the result when I reverted the Vector RGB to the default values of 1 1 1, or just turned off the new V4 parameter
8

  1. Why does the stretching effect not work when the Inherit Source Movement module is not active?
    Below is an example of what the system looks like with Lifetime/LoopDuration = 0.2
    UnrealEditor_XwIUET0NQC_lossy

  2. I.e. in general why are these three modules used for correct operation? (Interpolate Over Time, New V4 Param, Inherit Source Movement)

I deeply appreciate your time in responding and thank you in advance to anyone who deigns to help. While I was writing this, I was thinking how hard it was to do VFX 10-15 years ago, when artists had to find the answers to these questions themselves and it’s not clear where, because the information was probably not even in the documentation.

The clear answers that ChatGPT has given (your help is still needed):

    • Why use Dynamic Parameter?
  • Dynamic Parameter allows the material to receive real-time data from Niagara. Here, it’s used to set a reference position (XYZ = 0 in Dynamic Parameter) to control how particles behave relative to it.

  • Why subtract Particle Position from Dynamic Parameter?

  • By subtracting the Particle Position from this reference position, you’re calculating the distance between the particle and that reference.

  1. Why if I disable Dyn Par in Emitter nothing changes?
  • Dynamic Material Parameters in Niagara:

  • This module acts as a bridge, sending data to the material. If you disable it in Niagara, the material still remembers the last received values, so it doesn’t break immediately. However, if you disable it in the Material, the material no longer knows where to get the data.

6 Likes

I have done something similar a few times in the past. I did it with just velocity and the WPO function.

In your case:
1: * Why use Dynamic Parameter?
In Niagara, you are calculating the moving average with interpolating over time. Then compare it with the current particle position in a shader. You could do both in Niagara but this seems a bit less hassle to setup. You could do the same thing in Niagara and just send it to the shader through dynamic param. But you can’t interpolate over time inside the shader, that’s why dynamic parameter Is essential for this to work. Material shader can’t do that complex interpolation over time since it’s just computing the present frame. Pixel and vertex shaders are not designed to do that, you do that stuff in compute shaders. You can view Niagara as a compute shader in a way. I suggest researching the topic of different shaders online, to understand how pixel, vertex and compute shaders operate.

2: Why if I disable Dyn Par in Emitter nothing changes?
You did a binding inside a renderer to send that value to the shader, so now you don’t need a module in your particle update. Binding will send that attribute directly without a need for a module in particle update.

  1. Why is a new vector 4 module created? Why is Moving Average inserted into it in Vector RGB? Why is a new parameter inserted in Dynamic Material Binding?

Dynamic Parameter is vector4 by default, and it’s passed to the shader by code in the background, i guess you could not assign vector3 to vector4. It could be done differently, I was splitting it into 3 separated float values and assigning it in the dynamic parameter module. But this seems a bit more efficient.

Cheers,
Jovan

Hi Jovan,

Thank you so much for your detailed explanation! It really helped me understand the technical principles behind this setup. I also appreciate your note about the differences between pixel, vertex, and compute shaders, it’s very interesting.

1 Like