Particle GPUCompute Script

Particle GPUCompute Script 是 Emitter 的 HLSL 代码。

代码结构

1. 全局参数与数据结构

  • Engine & Emitter 变量:Engine_DeltaTime, Engine_Time, Emitter_Age 等内置系统变量及其前一帧的值(带 PREV_ 前缀)。
  • 外部常量缓冲区 (FNiagaraExternalParameters): 包含了用户自定义或暴露的外部参数,例如 User_WindDir(风向)和 Emitter_SpawnRate
  • 参数映射结构体 (FParamMap0 及其子结构): 这是 Niagara 的核心数据总线。它将图表中的所有变量(Local, User, Particles, Emitter, Engine 等)打包成结构体。
  • FSimulationContext: 模拟上下文结构体,它根据当前的 SimulationStageIndex 宏,包含对应阶段所需的 FParamMap0 数据。

2. Niagara 模块函数、节点函数定义

模块函数

这部分对应的是能直接添加到列表中的模块,如常见的Initialize ParticleShape LocationScratch Pad Module等,此外还有Custom HLSL,它们都以_Func_ 结尾。

节点函数

这部分对应的是模块中的节点,如 RT 的 Load Render Target Value、Grid2D 的

Set Float Value等。

3. 各个函数的实现

  • 模块函数:这部分函数会使用宏 #if ((SimulationStageIndex == ?)) 根据不同的阶段控制代码是否编译。
  • 阶段函数:同上
  • 节点函数:这部分没用使用宏控制,也就是说理论上是全局可见、可调用的。
  • 其他内置工具函数:同上

4. Compute Shader 主函数

包括一些初始化逻辑函数、数据传输与存储函数和一个名为SimulateMainComputeCS的主函数。

一些发现

节点函数 与 跨阶段调用

节点函数没用使用宏控制编译,也就是说理论上是全局可见、可调用的。例如,在阶段1中使用了节点A生成了函数A,那么就可以在阶段2中使用Custom HLSL直接调用函数A。参考

值得注意的是,一些与资源关联的函数,如 Grid2D 的 Set Float Value 节点,其生成的函数是直接硬编码了对应的 Grid2D 对象。此时若跨阶段调用,必须确保该阶段已将该对象传入,并进行了相应的读写操作。例如,在该阶段只对该 Grid2D 对象进行了读操作,那么就无法跨阶段调用 Set Float Value 节点的函数。 为什么呢?一些个人的猜想,未验证:虽然这些函数、资源声明都在同一个 HLSL 源码里,但是在 C++ 端绑定的资源不尽相同(

),若在阶段中对某资源进行了读操作则绑定SRV,进行了写操作则绑定UAV,然而,UE 无法识别通过 Custom HLSL 直接调用函数这种 Hack 操作,由此导致无法操作资源的情况。

版权声明

作者: Cheyne Xie

链接: https://chaim.eu.org/posts/16370d86/

许可证: CC BY-NC-SA 4.0

This work is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License. Please attribute the source, use non-commercially, and maintain the same license.

开始搜索

输入关键词搜索文章内容

↑↓
ESC
⌘K 快捷键