Niagara / unreal GDC



We’ve made a lot of changes post this build to get rotations to work better. At the build you have I think that we were still on axis-angle for mesh orientation. It is now a quarternion with several well tested functions around quats.


Just starting to Learn Unreal VFX and saw this. Is it worth going through the Cascade Intro for v4.2, or should I wait? Thx


@ShaunKime Thanks, I’ll grab latest from Dev-Niagara and try again.

A couple more questions if you’re willing to entertain:

  1. Can you create arbitrary namespaces? Or can you only add arbitrary values to existing namespaces? I’ve defined a bunch of values under Emitter that are picked up in Particles. I would like to clump them all together under one arbitrary namespace that is visible farther down the stack.
  2. Is there a way to get real-time feedback in the viewport when I drag a slider? Or am I not getting real-time feedback because I’ve defined values in emitter spawn scripts and it has to recompile/reload it every time?


You can create arbitrary namespaces, but they are “temporary”, meaning they only have meaning for the script type that you are on. The values are scoped to that update, spawn or event and are not persisted in any way. We use Physics.Force for this. It is set to zero by default at the beginning of the update script, a bunch of force modules go in and accumulate their forces for the frame, and then the SolveForcesAndVelocity module resolves those into changes to Particles.Velocity and Particles.Position. Anything you create will follow that same paradigm. However, you can create sub-namespaces within the supported ones. So Particles.Cannabis. is a perfectly valid namespace to organize all your custom stuff into, which I think gets you most of what you want.

We reset the sim when you change values for now as we don’t know if the change is cosmetic or functional and just opted for the safest. If paused, we re-sim up to that point, but that may be flakey in the build you are using.


I was never a big fan of Cascade. I always felt it was cumbersome to use and not easily extensible. Niagara changes all that. So far, I think Niagara is a very well designed and intuitive system.

In 2 days of Niagara, I (roughly) got working what took me 2 weeks in C++. I think I’ve found a new home. The more I learn about Niagara, the more it keeps blowing my mind.

@ShaunKime Thanks again.


We’re trying hard to make it easy for people with Cascade knowledge to jump in and use Niagara, so your efforts in Cascade should still pay off. Watch the video mentioned above to help prep for what’s coming, but you should still be able to get a lot accomplished within Cascade.


Wow… we love to hear that!


As with any tool, once we release Niagara, evaluate both and see which one best meets the needs of you and your team.


Great thanks! Will there be tutorial videos as well to walkthrough it?


It will take us some time, but you can expect a lot of doc/videos/training info to help people transition over.


@ShaunKime I see data interfaces for:

  • Curl noise
  • Spline
  • Static Mesh
  • Parameter binding

I understand future interfaces will surface over time. I’m just curious to know what interfaces (if any) are queued in your backlog. Or have you deferred implementation of data interfaces to subsystem owners (ie. audio).


Looks like an amazing architecture guys, really well thought out, can’t wait!


Another presentation that just popped up in my feed:


MeshOrientation and real-time update (of slider changes) are indeed working in latest. So much fun…

Can I set keyframes for my value changes in Sequencer yet?


I never thought a stupid table would blow my mind, but it actually did.


Grid distribution…

@ShaunKime I got really tripped up when I re-defined the parameter map. In an emitter script I defined Foo.Bar as a float. In a particle script, I also had Foo.Bar defined as a float. Back in my emitter script, I realized I actually wanted an int32, so I changed the type and moved on. I forgot to change Foo.Bar in the other script to an int32 as well. So I started playing VM in my head, running the update script through the range of inputs because it wasn’t working properly. Okay, my math is wrong. Clearly. (99% of the time it is.) Double check…oh there is a bug in my code. Fix. Still doesn’t work. Hrm. Rinse and repeat for WAY too long until I’m convinced it’s not my code. I start looking elsewhere and Capture shows Foo.Bar is always 0. No matter what value I set Foo.Bar with, it’s always 0. What the…why? Oh, there are two Foo.Bars defined in the parameter map! One of type int32 and one of type float. And that’s the problem. I was setting the int32 version of Foo.Bar and the script was using the float version of Foo.Bar. Because the float value is never set, the input is always 0. Clear as mud?

I guess the name isn’t used as a hash into the map? Or I’m dealing with different maps in different scopes? Or is this a feature where you can define the same variable name multiple times, each holding different types?


We have a long list, but likely won’t have a chance to get to them before we have to ship 4.20. The great thing about the new architecture is that anyone can add new ones and put them on the marketplace to share.


If you expose them as user namespaces variables you can animate within the level using sequencer.


Yeah, we need to catch that as an error when compiling. If you mix types and the same names, we probably don’t properly hook up the tweaked constants and the shader code.


This one is a Copy module. In the example video, it duplicates the linear dist module higher up in the stack. And of course, all changes update across all copies.