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.
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 Spawn
This group defines what happns when an emitter is first created on the CPU. Use this group to define initial setups and defaults.
-
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.
-
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.
-
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.
-
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.
-
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.
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.
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.
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 and Behavior Examples
Niagara Asset Browser Window
When you first create a Niagara emitter or Niagara system, an asset browser window displays the available Niagara systems and emitters in your project. You can filter the available assets by type or by categories. You can also create custom categories for filtering purposes.
To create a new Niagara system, right-click in the Content Browser and click FX > Niagara System.
The Niagara Asset Browser window will open and display all available systems in the project. The window consists of the following sections:
1. Content Area
The content area displays the systems and emitters available based on the selected category and filters.
2. Categories
The categories section displays all available categories in the project. Select any of the categories to see the systems and emitters available.
3. Toolbar
The toolbar has the following options available:
Filter
The filter button displays a dropdown with the available FX and Niagara filters. Select the Niagara Emitter filter to display the available emitters in the content area.
You can click on the filter button to enable and disable the filter.
Search
The search bar is used to search for systems and emitters by name. In the example below we searched for fire to see all the systems that contain that word in their name.
If the systems above are not available in your project, go to the Plugins window and enable the Niagara Fluids plugin.
4. Details
The details section displays information about the selected system or emitter.
In the above example an emitter is selected and you can see the asset’s description, primary tags (category), whether the emitter is inherited from another asset, and whether it runs on the CPU or GPU.
Add your own categories
The Niagara asset browser uses tags to organize the Niagara systems and emitters inside the window. The tags are visualized as a folder hierarchy on the left-hand side of the window, as shown below.
Each asset has a corresponding Primary Tag which is used to place it in the correct category. In the example below, the system Grid2D_Gas_Color has the Primary Tag 2D Gas, which corresponds to the 2D Gas category on the left-hand side.
You can create your own tags and assign them to your assets inside the Content Browser. This, in turn, creates custom categories in the Asset Browser.
For this example, we created three Niagara emitters named NE_Hit_Concrete, NE_Hit_Glass, and NE_Hit_Wood to represent different hit effects.
To create custom tags follow these steps:
-
Right click in the Content Browser and click FX > Advanced > Niagara Asset Tag Definitions. Name the asset NAD_HitEffects.
-
Double click NAD_HitEffects to open it. Enter a Display Name and Description. This will be used in the categories view inside the Asset Browser.
-
Click the + sign next to Tag Definitions to add a new tag. Expand Index [0] and enter Hit_Glass as the Asset Tag and select Emitters as the Asset Flags.
-
Follow the previous step and add two additional tags: Hit_Concrete and Hit_Wood.
-
Right-click NE_Hit_Concrete and click Manage Tags > Hit_Concrete. This will add the Hit_Concrete tag to the asset.
-
Add the Hit_Glass and Hit_Wood tags to the NE_Hit_Glass and NE_Hit_Wood emitters, respectively.
-
Right-click in the Content Browser and click FX > Niagara System to open the Asset Browser. Click the Hit Effects category to see the emitters with tags that are part of that Asset Tag Definition.
-
Now click the Hit_Glass category to see the emitter with the Hit Glass tag.
-
You can create as many Asset Tag Definitions as you want for your project. In the example below we created another definition with the name Splash Effects and two tags: Splash_Clear and Splash_Mud.
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.
- 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:
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.