The layer graph describes the interactions between layers. It provides a high-level view of an effect and helps to quickly understand the effect layout:
It is read from left to right and shows the execution flow inside the effect.
The wires carry events, which in turn trigger the nodes.
Events are instantaneous “pulses” which are passed from one node to another along the wires.
They can be multiplied, delayed, divided, or generally modified by layers & event helpers, in order to create the final effect.
They are a key feature of PopcornFX v2.
- Event wires are represented as dotted lines. Wider lines means more events are currently flowing through the wire. This allows to see in a very visual way which parts of the effect are actively pulsing events, and which parts are dormant.
Events are not particles, but they can:
- Carry data (payloads)
- Trigger layers (spawn particles)
For example: an event triggering a particle layer will spawn one particle from that layer.
An event wire along which events are flowing at a rate of 100 events/second will cause the end layer to spawn 100 particles/second.
Every event comes from a root track (see Timeline): an effect is the combination of multiple tracks. All tracks start playing when the effect is instantiated ingame. All effects have a default Root track:
Most effects only need that single Root entry point. Other tracks can be created in the timeline to easily sequence layers.
For each keyframe in a track, an event will be pulsed out of the track’s event start node.
By default, there is a single keyframe at time=0 in the default track, therefore a single output event will be pulsed, which can be passed down to other layers, or event manipulation templates:
- An output event can be split and routed to multiple nodes at the same time
- Nodes can be triggered by multiple event sources
- Layer nodes, those contain particle graphs, and will spawn a new particle when triggered by an event.
- Event manipulation templates
Event manipulation templates are not built-in nodes, they all are templates contained in core template files we provide. Most of them are stored in Library/PopcornFXCore/Templates/Events.pkfx. You shouldn’t modify that file directly as we apply upgrades on core libraries, and your modifications will be discarded.
Those templates can be seen in more detail in the Node Reference.
To better understand, let’s take a look at an effect created from the FX_Simple effect template:
- When the effect is played, a single event is pulsed out from the Root track node
- That event is passed down into the EventMultiplier node
- From that single one-time input event, this EventMultiplier node will generate 10 events per second, over 10 seconds. (you can change those values in the node properties)
- 10 events per second are pulsed out.
- Those events are passed down into a Layer node, meaning 10 particles per second will be generated, and execute the particle graph of the layer.
Each event carries a payload. The payload of an event contains custom data elements. They can be added/extracted/removed and they allow to transfer important information between layers/templates. Payloads can be viewed by hovering event links:
- This track’s output events carry no data
- The EventMultiplier node appends (adds) two payloads (here, EmittedCount and SpawnCount), those payloads are passed down to the Parent Particles layer
- The “Parent Particles” layer emits trails, and appends other payloads to the outgoing trail events.
Payloads can be extracted inside particle graphs. In this example, the Trails layer can extract Velocity, Size, Color from the payload of the parent event.
At its core, a raw event is “dry”: it carries no data.
An event has a non-empty payload only if a layer (or a track) explicitly adds payloads.
When the PopcornFX runtime compiles the final effect during the baking phase, it will automatically remove any unused payload. The editor will always show the original, unoptimized payloads.
You can use default templates provided in the core template library or create custom event templates. As an example, here are the contents of an EventMultiplier node:
(To open this graph just double-click on any multiplier node)
- Input “Spawn” event
- Multiplier Layer (particle graph)
- Output events
Open the Multiplier layer to see its particle graph, which contains all the actual logic of the event multiplication:
- Layer inputs
- Main behavior: handles spawning based on spawn metric, duration, ..
- Payloads: Append EmittedCount and SpawnCount payloads to output event
- Output events
This particle graph is handling event generation for various spawn modes and metrics.
To sum up how the event multiplier node works:
- The input “Spawn” event triggers that Multiplier layer, spawning a single particle.
- The single particle executes its node graph, computing the correct spawn count, duration, etc
- All those mandatory informations are then transferred to the EventGenerator, a special node handling event generation and sub frame emission (see node reference), which pulses out the desired events.
- Payloads are then added to each output event from the EventGenerator node
- Final events and all their payloads are then exported out of the layer back into the layergraph.
You can create your own layer templates the same way.
Events can not only be transferred to other templates or layers, but also exported to the game engine. This means any particle can export an event with custom payloads (Velocity/Color/..), that the game engine intercepts to trigger some gameplay data. Here is an example setup:
- Effect interface panel, displays all attributes, attribute samplers, exported events. This panel displays everything visible to the game engine once that effect is imported.
- Output node, of “event” type. Once that node is properly setup and named, the event exported will be visible in the Effect interface
Here, we plugged the “EventCollide” output event, but you can export any event.
It is also possible to use particle graph nodes in the layer graph, to do custom computations and feed them in data input pins exposed by layers or templates.
Here is an example, that reproduces PopcornFX v1’s FluxFactorExpression behavior:
- SpawnCountMultiplier attribute, exposed to the game engine (ExecRate of node set to Full rate so it is evaluated each frame by the multiplier node)
- Base spawn count
Increasing/Decreasing SpawnCountMultiplier will have an instant impact over the particle spawn count, as this attribute is evaluated each frame (Full execution rate).
Important: Those data nodes are not evaluated in the layergraph, they are silently by all layers they are plugged in. This means special care must be taken when using particle graph nodes in the layer graph, specifically regarding Execution rates.
This means a non-deterministic node such as a random value node, if plugged into 4 different layers, will produce 4 different values inside each layer.