Megafunk / MassSample

My understanding of Unreal Engine 5's experimental ECS plugin with a small sample project.
MIT License
681 stars 112 forks source link

Niagara example index values skip & repeat leading to flickering particles #48

Closed GrahamMueller closed 1 year ago

GrahamMueller commented 1 year ago

[Tested in 5.1, not tested in 5.0]

Mass entities can use Niagara for rendering. Every frame Mass creates an array of all entity positions and gives it to a Niagara particle system. Niagara moves particles to the positions in this array where they will be rendered. Niagara uses 'Exec Index' to assign each particle a position from the array. This value is assumed to assign a unique value to each particle every frame, so all values from the Positions array are accessed.

The problem is newly spawned particles reset Exec Index after 'Particle Spawn' block. Newly spawned particles use Exec Index [0, 1, 2…] and existing particles also use [0, 1, 2…] instead of the expected [3, 4, 5 … ].
This causes some particle positions to be rendered twice, and some particle positions not to be accessed at all. Visually this can lead to invisible or flickering particles.

Setup : Every frame I spawn 5 new Mass Entities which are rendered using Niagara. 'c_execIter' is assigned Exec Index on particle spawn and update. b_frame_index is a value I assign every frame that works on CPU but not GPU. Can be ignored for this example. Frame 0 : No entities spawned. Frame 1 : 5 entities spawned. All index positions rendered once. image Frame 2 : 5 entities spawned. Index positions [0, 1, 2, 3, 4] used twice. Index positions [5, 6, 7, 8, 9] not referenced. image Frame 3 : 5 entities spawned. Index positions [0, 1, 2, 3, 4] used twice. Index positions [10, 11, 12, 13, 14] not referenced. image

Some particle settings I tried Sim Target - GPU - No difference Exec index has same behavior and can still result in flickering. GPU does not seem to spawn particles instantly ; this can lead to 400 positions but only 398 particles. GPU particles use the same Exec Index as they would in CPU, just in different order due to parallel work.
I have only tested on a single GPU. Multiple GPUs might act different with exec index? Would be very visibly obvious if they do.

Interpolated Spawning OFF - no difference Particles are spawned and ran run 'Particle Spawn' but NOT particle update. Existing particle exec still ends early.

Combine Event Spawn OFF - no difference Particles are spawned one by one, always resetting exec index to 0. Existing particle exec still ends early.

Require Persistent IDs - no difference This creates unique index values for each particle. Not useful as an index.

Replicating This can be observed in the editor with both CPU and GPU based particles using the Tools->Debug->Niagara Debugger->FX Outliner. This will allow you to capture a live particle system and display individual particle values for that frame.

You should see Exec Index repeated values during frames that spawn particles.
You will not see Exec Index repeated values during frames that reduce particles.

Megafunk commented 1 year ago

Amazing issue post!! You didn't leave anything out!

My first attempt is going to be trying a simulation stage. These seem to give you more control over iteration? image

Megafunk commented 1 year ago

Seems to Just Work ™ after moving the module to a new simulation stage with no other changes? I may still be missing something here..

Megafunk commented 1 year ago

Seems to work so I am going to close this for now, if it persists after the sim stage let me know