Niagara — GPU Compute & Simulation Stages
Niagara as a GPU Compute PlatformNiagara 作为 GPU 计算平台
While Niagara is primarily known as a visual effects system, its true power for engineers is that it exposes a node-graph programmable GPU Compute pipeline without requiring raw HLSL shader code. Think of Niagara as a high-level interface to GPU Compute shaders — you define the GPU work via visual scripting graphs and Data Interfaces, and Niagara compiles them to efficient Compute dispatches.
虽然 Niagara 主要以视觉效果系统著称,但对工程师来说,其真正的强大之处在于它无需原始 HLSL 着色器代码就能暴露节点图可编程 GPU 计算管线。将 Niagara 视为 GPU Compute 着色器的高级接口——通过可视化脚本图和数据接口定义 GPU 工作,Niagara 将其编译为高效的 Compute 分发。
System Architecture系统架构
Simulation Stages — Custom GPU Iteration仿真阶段 — 自定义 GPU 迭代
Simulation Stages (introduced in UE 4.26) are the key feature that makes Niagara useful for non-particle GPU work. They allow you to define additional Compute passes that run as part of the particle system tick, but instead of iterating over particles, they can iterate over:
仿真阶段(UE 4.26 引入)是使 Niagara 用于非粒子 GPU 工作的关键特性。它们允许定义额外的计算通道,作为粒子系统 Tick 的一部分运行,但不是遍历粒子,而是可以遍历:
- Particles: Standard particle iteration (Spawn/Update equivalent)
- 粒子:标准粒子迭代(等同于 Spawn/Update)
- Grid 2D Collection: Iterate over all cells in a 2D grid texture (e.g., fluid simulation, density field)
- Grid 2D Collection:遍历 2D 网格纹理中的所有单元格(例如流体仿真、密度场)
- Grid 3D Collection: Iterate over all cells in a 3D volume (e.g., 3D fluid, volumetric physics)
- Grid 3D Collection:遍历 3D 体积中的所有单元格(例如 3D 流体、体积物理)
- Neighbor Grid 3D: A sparse spatial hash grid for O(1) neighbor lookups in crowd or SPH simulations
- Neighbor Grid 3D:稀疏空间哈希网格,用于群体或 SPH 仿真中的 O(1) 邻域查找
// UNiagaraSimulationStageBase (NiagaraSimulationStageBase.h) // Key properties: UPROPERTY() FNiagaraVariableBase IterationSource; // What to iterate over (particles/grid/etc.) UPROPERTY() int32 NumIterations = 1; // How many times to run this stage per tick UPROPERTY() bool bSpawnOnly = false; // Only runs on particle spawn frames // At runtime: each enabled simulation stage compiles to one Compute dispatch // Stages execute in order: Spawn → [CustomStage0] → Update → [CustomStage1] → ...
Data Interfaces — Bridging C++ and GPU Scripts数据接口 — 桥接 C++ 和 GPU 脚本
Data Interfaces (DI) are the mechanism Niagara uses to give GPU scripts access to external data: scene textures, physics, skeletal meshes, custom C++ data. Each DI provides:
数据接口(DI)是 Niagara 用来让 GPU 脚本访问外部数据的机制:场景纹理、物理、骨骼网格、自定义 C++ 数据。每个 DI 提供:
- GPU functions: HLSL functions exposed as graph nodes that the Niagara compiler embeds into the generated Compute shader
- GPU 函数:Niagara 编译器将其嵌入生成的 Compute 着色器的 HLSL 函数(以图节点形式暴露)
- CPU bindings: C++ code that uploads DI parameters to GPU buffers before the Compute dispatch
- CPU 绑定:在 Compute 分发前将 DI 参数上传到 GPU 缓冲区的 C++ 代码
- Shader include files: HLSL files in
Plugins/FX/Niagara/Shaders/Private/that implement the DI's GPU-side functions - 着色器包含文件:实现 DI GPU 侧函数的 HLSL 文件(位于
Plugins/FX/Niagara/Shaders/Private/)
Grid2D/3D — GPU Simulation Without ParticlesGrid2D/3D — 无粒子的 GPU 仿真
The Grid2D and Grid3D Data Interfaces are the most powerful for custom simulation. They expose persistent GPU textures (float, float4, float vectors) that retain their values between frames — enabling iterative simulations like Navier-Stokes fluid, SPH, heat diffusion, etc.
Grid2D 和 Grid3D 数据接口是自定义仿真中最强大的。它们暴露持久 GPU 纹理(float、float4、float 向量),在帧之间保留其值——实现像 Navier-Stokes 流体、SPH、热扩散等迭代仿真。
// Example: 2D fluid simulation setup in Niagara // // System has NO particles. Instead it uses Simulation Stages over Grid2D: // // Stage 0: "Advect" — for each (x,y) in 128×128 grid // → Read velocity from Grid2D_Velocity // → Sample density at advected position // → Write new density to Grid2D_Density // // Stage 1: "Divergence" — Compute divergence for pressure solve // → Read velocity field // → Write divergence to Grid2D_Divergence // // Stage 2: "Pressure Jacobi" (repeated N times) — pressure solve // → Iterative Jacobi relaxation over Grid2D_Pressure // // Stage 3: "Projection" — subtract pressure gradient from velocity // → Makes velocity field divergence-free // // Result: a real-time 2D fluid simulation entirely on GPU, // visualized by sampling Grid2D_Density in a material
GPU Particle ReadbackGPU 粒子回读
Reading particle data back from GPU to CPU is expensive (stalls the pipeline). Niagara provides two mechanisms:
从 GPU 读回粒子数据到 CPU 很昂贵(会停滞管线)。Niagara 提供两种机制:
- Async readback (recommended):
FNiagaraDataSet::CopyFromGPU+ async fence — data available 1–2 frames later - 异步回读(推荐):
FNiagaraDataSet::CopyFromGPU+ 异步 fence——数据在 1–2 帧后可用 - GPU Messaging: Niagara's built-in GPUMessaging system allows GPU→CPU communication via small typed messages, useful for events (particle collisions, zone triggers) without full buffer readback
- GPU 消息传递:Niagara 内置的 GPUMessaging 系统允许通过小型类型化消息进行 GPU→CPU 通信,适用于事件(粒子碰撞、区域触发),无需完整缓冲区回读
Custom Data Interface — C++ Side自定义数据接口 — C++ 侧
// Creating a custom Data Interface that exposes your compute data to Niagara: UCLASS() class UMyCustomNiagaraDI : public UNiagaraDataInterface { GENERATED_BODY() public: // 1. Declare the HLSL functions this DI provides to scripts virtual void GetFunctions(TArray<FNiagaraFunctionSignature>& OutFunctions) override; // 2. Generate HLSL code that implements those functions virtual bool GetFunctionHLSL(const FNiagaraDataInterfaceGPUParamInfo& ParamInfo, const FNiagaraDataInterfaceGeneratedFunction& FunctionInfo, int FunctionInstanceIndex, FString& OutHLSL) override; // 3. Bind GPU parameters (buffers, textures) before each Compute dispatch virtual bool CopyToInternal(UNiagaraDataInterface* Destination) const override; // C++ data: UPROPERTY(EditAnywhere) float MyParameter = 1.0f; };
Use Cases: Fluids, Crowds, Physics使用场景:流体、群体、物理
| Use Case使用场景 | Niagara FeatureNiagara 特性 | Notes说明 |
|---|---|---|
| 2D/3D fluid2D/3D 流体 | Simulation Stage + Grid2D/3D | Navier-Stokes, smoke, fire — fully GPU-residentNavier-Stokes、烟雾、火焰——完全 GPU 驻留 |
| Crowd simulation群体仿真 | Neighbor Grid 3D + particle update | SPH-based steering, separation forces, 100K+ agents基于 SPH 的转向、分离力,10 万以上角色 |
| GPU physics debrisGPU 物理碎片 | Particle Simulation Stage | Verlet integration, collision response with GBuffer depthVerlet 积分,与 GBuffer 深度的碰撞响应 |
| Procedural animation程序化动画 | Grid3D + skeletal mesh DI | GPU-driven clothing, tentacles, vinesGPU 驱动的布料、触手、藤蔓 |
| Custom VFX data自定义特效数据 | Custom Data Interface | Expose game state to Niagara scripts (HP bars, team data)向 Niagara 脚本暴露游戏状态(血条、队伍数据) |
Source Navigation源码导航
- Niagara/Private/NiagaraSimulationStageBase.cppSimulation Stage runtime, iteration source handling仿真阶段运行时,迭代源处理
- Niagara/Public/NiagaraDataInterface.hDI base class — GPU function declaration, HLSL generation interfaceDI 基类 — GPU 函数声明、HLSL 生成接口
- Niagara/Private/NiagaraSystemSimulation.cppGPU particle simulation tick, RDG Compute dispatchGPU 粒子仿真 Tick,RDG Compute 分发
- Niagara/Shaders/Private/NiagaraGPUInstanceCountManager.usfGPU particle count management compute shaderGPU 粒子数量管理计算着色器
- Niagara/Shaders/Private/NiagaraDataInterfaceGrid2D.ushGrid2D HLSL implementationGrid2D HLSL 实现
- Niagara/Shaders/Private/NiagaraDataInterfaceGrid3D.ushGrid3D HLSL implementationGrid3D HLSL 实现