Niagara Overview

This page gives an overview of the Niagara VFX system in Unreal Engine 5.

Choose your operating system:

Windows

macOS

Linux

Niagara is Unreal Engine's next-generation VFX system. With Niagara, the technical artist has the ability to create additional functionality on their own, without the assistance of a programmer. The system is adaptable and flexible. Beginners can start out by modifying templates or behavior examples, and advanced users can create their own custom modules.

Core Niagara Components

In the Niagara VFX system, there are four core components:

  • Systems

  • Emitters

  • Modules

  • Parameters

Systems

A Niagara system is a container for everything you will need to build that effect. Inside that system, you may have different building blocks that stack up to help you produce the overall effect.

You can modify some system-level behaviors that will then apply to everything in that effect.

Niagara System Settings

The Timeline panel in the System Editor shows which emitters are contained in the system, and can be used to manage those emitters.

Emitters

Emitters are where particles are generated in a Niagara system. An emitter controls how particles are born, what happens to that particles as they age, and how the particles look and behave.

The emitter is organized in a stack. Inside that stack is several groups, inside which you can put modules that accomplish individual tasks. The groups are as follows.

Emitter Groups

  1. Emitter Spawn

    This group defines what happns when an emitter is first created on the CPU. Use this group to define initial setups and defaults.

  2. Emitter Update

    This group defines emitter-level modules that occur every frame on the CPU. Use this group to define spawning of particles when you want them to continue spawning on every frame.

  3. Particle Spawn

    This group is called once per particle, when that particle is first born. This is where you will want to define the initialization details of the particles, such as the location where they are born, what color they are, their size, and more.

  4. Particle Update

    This group is called per particle on each frame. You will want to define here anything that needs to change frame-by-frame as the particles age. For example, if the color of the particles is changing over time. Or, if the particles are affected by forces like gravity, curl noise, or point attraction. You may even want the particles to change size over time.

  5. Event Handler

    In the Event Handler group, you can create Generate events in one or more emitters that define certain data. Then you can create Listening events in other emitters which trigger a behavior in reaction to that generated event.

  6. Render

    The last group is the Render group. This is where you define the display of the particle and set up one or more renderers for your particles. You may want to use a Mesh renderer if you want to define a 3D model as the basis of your particles, upon which you could apply a material. Or, you may want to use a sprite renderer and define your particles as 2D sprites. There are many different renderers to choose from and experiment with.

Modules

Modules are the basic building blocks of effects in Niagara. You add modules to groups to make a stack. Modules are processed sequentially from top to bottom.

Emitter Modules

You can think of a module as a container for doing some math. You pass some data into the module, then inside the module you do some math on that data, and then you write that data back out at the end of the module.

Modules are built using High-Level Shading Language (HLSL), but can be built visually in a Graph using nodes. You can create functions, include inputs, or write to a value or parameter map. You can even write HLSL code inline, using the CustomHLSL node in the Graph.

You can double-click any module from an emitter in Niagara to take a look at the math that's happening inside. You can even copy and create your own modules. For example, if you double-click on the Add Velocity module to take a look inside, you can inspect the data flow.

Click image for full size.

The script starts by retrieving inputs - the velocity input and the coordinate space. It then gets the current velocity of the particles, as well as an inputted scaling factor. Then, the input velocity is scaled, transformed in the correct coordinate space, and added to the current velocity of the particles. Once that work is complete, the new particle velocity is written back out so that any modules that need velocity information further on down the stack can retrieve it.

All modules are built with that basic methodology, though for some the internal math may be more complex.

Parameters and Parameter Types

Parameters are an abstraction of data in a Niagara simulation. Parameter types are assigned to a parameter to define the data that parameter represents. There are four types of parameters:

  • Primitive: This type of parameter defines numeric data of varying precision and channel widths.

  • Enum: This type of parameter defines a fixed set of named values, and assumes one of the named values.

  • Struct: This type of parameter defines a combined set of Primitive and Enum types.

  • Data Interfaces: This type of parameter defines functions that provide data from external data sources. This can be data from other parts of UE4, or data from an outside application.

Parameters

You can add a custom parameter module to an emitter by clicking the Plus sign icon (+) and selecting Set new or existing parameter directly. This adds a Set Parameter module to the stack. Click the Plus sign icon (+) on the Set Parameter module and select Add Parameter to set an existing parameter, or Create New Parameter to set a new parameter.

Templates, Wizards, and Behavior Examples

When you first create a Niagara emitter or Niagara system, a dialog displays offering several options for what kind of emitter or system you want to create.

You can change any of the parameters in the template. You can add, modify or delete any of the modules. In a system template, you can also add, modify or delete any of the emitters. Templates are just there to jumpstart your creativity and give you something that you can work with immediately.

System Wizard

To create a new Niagara system, right-click in the Content Browser and locate FX > Niagara System.

Click image for full size.

The System Wizard offers the following options for creating a new system:

  • New system from selected emitters: If you select this option and click Next, a list of available emitters displays. This list includes both existing emitters in your project and template emitters. Select the emitters you want to include in the new system, and click the green Plus sign icon (+) to add them. Then click Finish to create the system. If you choose an existing emitter, the system will inherit from those emitters. If you choose a template emitter, the system will have no inheritances. Also, the template emitter is an instance that can either be strictly local to that system, or you can save it as a separate emitter asset.

    Click image for full size.

  • New system from a template or behavior example: If you select this option and click Next, you can choose from a list of templates or behavior examples that represent several commonly used effect systems. As with emitter templates, this list can be curated by art leads or creative directors. If you are new to UE, this option will give you an example of how FX systems are built in Niagara. Behavior Examples are simple examples designed to feature one, isolated aspect of the Niagara system you can examine to help demystify that behavior.

    Click image for full size.

  • Copy existing system: If you select this option and click Next, a list of existing systems displays. Choose one of them to copy, then click Finish.

    Click image for full size.

  • Create empty system: If you select this option, your system contains no emitters or emitter templates. This option is useful if you want to create a system that is totally different from your other systems.

    Click image for full size.

Emitter Wizard

To create a new emitter, right-click in the Content Browser and select FX > Niagara Emitter.

Click image for full size.

The Emitter Wizard offers the following options for creating a new emitter:

  • New emitter from a template: If you select this option, you can choose from a list of templates that present several types of commonly used effects. In a large development studio, art leads or creative directors can curate the list of templates, ensuring that the company's best practices are baked into the templates. These templates also offer a great starting place if you are new to UE.

    Click image for full size.

  • Inherit from an existing emitter: If you select this option, you can create a new emitter that inherits properties from an existing emitter. This option makes the new emitter a child of the existing emitter you selected. If you need many emitters that all have certain properties in common, this is a good option to choose. You can make changes to the parent emitter, and all child emitters will reflect those changes. Select from a parent emitter to use this option.

    Click image for full size.

  • Copy existing emitter: If you select this option, you can create a new emitter that is a copy of an emitter you already created. This can be useful if you need to create several similar emitters. Click Next after selecting this option, and a list of available emitters displays. You can then choose which one you want to copy.

    Click image for full size.

Niagara VFX Workflow

Create Systems

First create a Niagara System in which you can add one or more emitters. You can then set up the properties of each emitter.

Create or Add Emitters

In the Niagara Editor, you can adjust your emitter by changing the properties of the modules already in it, or add new modules for the desired effect. You can also copy emitters and add multiple emitters into a single Niagara system. For an example of this, see the Sparks tutorial.

Create or Add Modules

In your emitter, you can add existing modules from Niagara by clicking on the Plus (+) of the group where you want to add the module. Niagara comes with a lot of pre-existing modules, and for the majority of circumstances you will be able to create your effects without needing to do any custom module design.

However, if you want to create your own modules, it can be helpful to understand how the data flows through a module.

Data flow through a module. Click image for full size.

  • Modules accumulate to a temporary namespace, then you can stack more modules together. As long as they contribute to the same attribute, the modules will stack and accumulate properly.

  • When writing a module, there are many functions available for you to use:

    • Boolean operators

    • Math expressions

    • Trigonometry expressions

    • Customized functions

    • Nodes that make boilerplate functions easier

  • Once you create a module, anyone else can use it.

  • Modules all use HLSL. The logic flow is as follows:

    HLSL logic flow. Click image for full size.

Remember that each module, emitter and system you create uses resources. To conserve resources and improve performance, look through the modules already included in Niagara to see if you can accomplish your goal without creating a new module. Dynamic Inputs can be used to great effect here.

Niagara Paradigms

Inheritance

  • With a flat hierarchy, you cannot effectively locate and use the assets you already have in your library, which leads to people recreating those assets. Duplication of effort lowers efficiency and increases costs.

  • Hierarchical inheritance increases discoverability and enables effective reuse of existing assets.

  • Anything inherited can be overridden for a child emitter in a system.

  • Modules can be added, or can be reverted back to the parent value.

  • This is also true with emitter-level behaviors such as spawning, lifetime, looping, bursts, and so on.

Dynamic Inputs

  • Dynamic inputs are built the same way modules are built.

  • Dynamic inputs give users infinite extensibility for inheritance.

  • Instead of acting on a parameter map, dynamic inputs act on a value type.

  • Any value can be driven by Graph logic and user-facing values.

  • Dynamic inputs have almost the same power as creating modules, but can be selected and dropped into the stack without actually creating new modules.

  • Existing modules can be modified and customized in many ways by using and chaining Dynamic Inputs; this can reduce module bloat and improve performance.

Micro Expressions

  • Any inline value can be converted into an HLSL expression snippet.

  • Users can access any variable in the particle, emitter, or system, as well as any HLSL or VM function.

  • This works well for small, one-off features that do not need a new module.

Events

  • Events are a way to communicate between elements (such as particles, emitters, and systems).

  • Events can be any kind of data, packed into a payload (such as a struct) and sent. Then anything else can listen for that event and take action.

  • Options you can use:

    • Run the event directly on a particle by using Particle.ID.

    • Run the event on every particle in a System.

    • Set particles to spawn in response to the event, then take some action on those particles.

  • Events are a special node in the graph (structs). How to use the Event node:

    • Name the event.

    • Add whatever data you want to it.

    • Add an Event Handler into the Emitter stack.

    • Set the options for the Event Handler.

  • There is a separate execution stack for events.

    • You can put elaborate graph logic into Event Handlers.

    • You can have a whole particle system set up, with complex logic, and then have a whole separate set of behaviors that occur when the event triggers.

Data Interfaces

  • There is an extensible system to allow access to arbitrary data.

  • Arbitrary data includes mesh data, audio, external DDC information, code objects, and text containers.

  • Data interfaces can be written as plugins for greater extensibility moving forward.

  • Users can get any data associated with a skeletal mesh by using a skeletal mesh data interface.

Houdini

  • Using Houdini, you can calculate split points, spawn locations, impact positions, impact velocity, normals and so on.

  • You can then export that data from Houdini to a common container format (CSV).

  • You can import that CSV into Niagara in your UE4 project.