GPU 模拟的能力边界

把发射器切到 GPU 模拟是提速的第一手段,但它不是"免费"的——有一批功能在 GPU 端不可用。先知道边界,再决定怎么切。

GPU 模拟不支持(或受限)的功能

功能 GPU 端状态 替代思路
蓝图 / C++ 逐粒子读写 ✗ 数据不出显存 改用 CPU 或事件传大致数据
Niagara Data Channel 双向通信 ✗ 用用户参数传汇总值
碰撞模块的部分模式 部分支持(距离场碰撞可用) 用距离场碰撞替代射线碰撞
部分老式渲染器组合 视版本 查录文档确认
Skeleton DI 的高级查询 受限 CPU 做主力,GPU 做表现

一个实战判断方法:切之前先打开"模拟目标"下拉框,如果切换后某些模块变灰,说明这些功能 GPU 不支持。这时有两个选择:为这些功能保留一个 CPU Emitter,或者重新设计行为。

什么量级才值得切 GPU

经验数值(中端 PC,仅作参考):

粒子量级 CPU 模拟开销 GPU 模拟开销 建议
< 300 / 发射器 可忽略 可忽略 + 调度开销 CPU
300~2000 有感知 很低 看总特效数决定
> 2000 / 发射器 明显 低 GPU

注意调度开销:GPU 模拟的"启动开销"不为零——每帧要提交 Compute Shader。发射器极多但粒子很少(例如 50 个发射器各 20 粒)反而可能更慢。这种场景下要么合并发射器,要么用 CPU。

GPU 侧的数据回读限制

GPU 模拟的数据正常情况下读不回主存,但引擎提供了有限的调试回读(NiagaraDebugUitilies,仅用于诊断,不能用于游戏逻辑)。所以"要读粒子的游戏"(每个粒子是一颗子弹、有命中判定)必须 CPU。

一个真实的混合案例

一个 BOSS 战场景:屏幕上同时有 3 万片"腐蚀 rain"。拆分方案:

  • 命中判定相关的 200 颗"腐蚀弹丸" → CPU Emitter(参与游戏逻辑);
  • 纯表现的 3 万片环境雨 → 单个 GPU Emitter;
  • 结果:逻辑可交互、表现拉满,GPU 模拟总开销约 1.5ms。

核心思想:模拟位置按"是否需要与逻辑交互"决定,而不是按"看起来酷不酷"决定。