Best Practices for Niagara Systems to handle both Software and Hardware Raytracing workflows

Hello,

We are doing some experiments with hardware raytracing, and we are trying to figure out the workflow to create and maintain Niagara Particle Systems that would work for both Software and Hardware Raytracing.

For the context:

We would like to support both Software and Hardware Raytracing.

To save some memory, we would not use the Global Signed Distance Field when Hardware Raytracing is enabled (r.DistanceFields.SupportEvenIfHardwareRayTracingSupported=0).

We are trying to convert some of our existing Niagara Particle Systems to have a fallback when Global Distance Field is not available (either using Raytracing for Depth Buffer depending on the case).

And we are trying to avoid as much as possible to duplicate content (in the ideal scenario, we would have 1 particle system that would work for both cases).

If we take as example the “GPU Collision” module from Niagara plugin:

  • We would like to use the “GPU Distance Fields” variation when Raytracing is disabled;
  • We would like to use the “GPU Ray Traces” variation (using the AsyncGPUTrace) when Raytracing is enabled.

The selection being driven by a static switch, the particle systems need to know before execution which version to run.

So far we tested a couple of ways to create / setup the particle systems:

First option is to have 2 separate Niagara Systems (one using GSDF and one using HWRT).

But that’s not great because it means more work to maintain the particles systems. And it makes the setup more complex too because we need extra logic to decide which version of the Niagara System to spawn.

Second option is to use the “Cvar Conditions” from the Niagara Scalability settings.

If we create 1 Niagara system with 2 emitters in it, and set one emitter to run when cvar is “r.Raytracing.Enable 0” and the other is “r.Raytracing.Enable 1” it kinda works.

We have only 1 Niagara System so it simplifies the scene setup, but we still have to duplicate the emitter logic.

And if I’m not mistaken “Cvar Conditions” only affects the rendering part of the particle system and not the entire particle system (so we still pay the cost for the particle spawn, particle update and other logic for both emitters).

[Image Removed]

Third option is to use different NiagaraSimulationStage for HWRT and GSDF logic, and use the “Enabled Binding” to control if the simulation stage should be run or not (with NiagaraParameterCollection we should be able to control most of our particle systems).

That way we can have 1 Niagara System with 1 Emitter (so no duplication).

As a prototype it seems to work fine but I’m not sure if it’s the best solution for all cases and if it would scale well (as example in the case of collisions since simulation stages are executed after the Particle Update we need to computes Forces multiple times).

[Image Removed]

We are wondering if there is some recommendations from Epic on how to manage assets for both Software and Hardware Raytracing?

Or if we missed something obvious on how to setup multiple variations of a Niagara System? (Niagara Scripts controlled by Static Switches are not specific to Raytracing so there might be a way to do it?)

Thanks in advance.

[Attachment Removed]

Hi, thanks for the details you included with your question!

We don’t have a strongly recommended best practice for this situation (we don’t use HWRT for VFX in Fortnite, so we don’t deal much with switching between HWRT and SWRT in most of our use cases). Collision is a known part of this issue, though.

It sounds like that last Sim Stage option is working for you so far; we don’t have a specific recommendation against it. If you haven’t already, I’d suggest running a perf test at your maximum VFX usage to compare the cost between the last approach and the dual-emitter approach for your content.

If the Sim Stage approach doesn’t turn out to be the right solution here, you could revisit the dual-emitter approach. Rather than setting up two separate emitters within a Niagara System that need to both be managed in-step, though, you could instead create a separate Niagara Emitter asset and apply that twice within a Niagara system (each with the relevant HWRT/SWRT changes needed). This would keep the external emitter as the single source of truth for VFX development (so you wouldn’t need to make all your changes twice), and the applied instances of that emitter would differ only in the HW/SW elements. This might be easier to manage.

Just a heads-up: Epic will be on break starting today through July 13th. I’ll check back on this thread as soon as I’ve returned to my work desk, and would be happy to dig into this further with you as needed. Apologies in advance for the delay, and thanks for your patience.

[Attachment Removed]