NIAGARA Spawn burst per particle ID using Array of burst count per particle

Hello,

I am exploring spawning particles from secondary emitter where the spawn count of particles is per particle ID.
That said, the spawn count in secondary emitter per each particle is determined via custom array per particle id or index.
I was digging into module scripts and so on however, could not find or figure out a fore each loop function or similar.
So what I have done is mapped a custom integer array inside the module script using Get Int by Index.
Also tried get int by ID.

Is there a way to spawn particles count by particle ID?

Hmm… that does sound tricky.

Can you frame this problem as:

  1. Sum up the number of particles required by all particle IDs. Emit one burst of that size.
  2. In the Particle Spawn stage, move the required particles to the source particle’s location.

That’s how the Box Location emitter works – it has two stages: one in the Emitter Update, one in the Particle Spawn. It emits all the particles it needs in the Emitter, and then positions them in the Spawn.

If you need a for loop, there’s a “For Parameter” node available in modules as of 4.27. Or, you can implement one in HLSL.

1 Like

Thank you!
Yes I was thinking about doing that and proceeded buy getting the secondary particle count using the length function, then I got stuck on sorting the per-particle position update per particle ID.
I will look into the For Parameter node, but I am not familiar with it or the HLSL commands.
If I could only find an example or reference to this.
I will check the box location emitter.

Here is what I am trying to sort. Hope this helps explaining why I want to spawn particle count per particle ID.
Or like suggested, spawn the burst instantaneous count of 40. Then sort the particles B per Particles A position (in reference to ID’s). Only not sure how to approach this in the module script.


Right, that makes sense.

Have you looked at the “Niagara_Advanced” map in the ContentExamples 4.27? There are several demo setup which do similar things. For example, there’s a “Follow the leader” system which emits leader particles from one emitter, and then follower particles based on the position of the leader particles. If you modified that to create the number of particles in your table, that might be pretty close.

Niagara Array Data Visualization_v002_small.pdf (535.7 KB) I did this.

I couldn’t figure out how iterate over the 10 particles A original count.

Apologies for the rough example, but here’s how you iterate using Map For:

This is from the “AdvanceGroomState” node in “GroomSpringsSystem” in the Hair Strands plugin.

The key thing is the “IncrementStepIndex” function:

That’s how you get the loop index. The index increment needs to be in a function so it can read and write the parameters in the middle of a loop.

With that, you should be able to do a lookup into your table.

(Sorry, I’ll try to make a better example later, but maybe this will help get you going?)

1 Like

Hi, Thank you!
Apologies for the rough example?
I absolutely appreciate your effort, input and feedback to help and explain regardless of how rough any example is!

Regarding the examples shared, it seems I may have a lack of understanding of how to use transient parameters or attributes. This is definitely worth a try.

I was also looking into how to create my own spawn burst script. But for now I will work with this to see if I may succeed using this example.
Again Thank you!

If there is a per particle array of ids, and you want to emit in the secondary emitter a count that is the totol count of all of those ids, then you would need a way to add them all up in a parallel way and set an atribute on the emitter that it can use next frame. This is usually called a ‘reduction’ in compute language. I don’t think there is a native way to do that right now, but there might be a way to do it with simualtion stages with multiple iterations. the issue is that there is no way to programatically control the number of iterations of a simulation stage based on the count of the original particle system count (it would need to be log2 of the source particle count number of iterations to ‘reduce’ the id count in the arrays.

So I’m not sure if there is a way right now. But I hope the Niagara team would be interested in this kind of functionality in the future as its something I’ve though of as well (in my case calculating bounding box of particles).

It’s totally possible – there are looping constructs in Niagara: Map-For, or HLSL. They’re just not real easy to use. :slightly_smiling_face:

Also, I guess summing the values in a column if a table is technically a “reduce”; but it’s not a log2 operation – it’s just a linear sum. The issues with reduce usually happen in a map-reduce where every element is processed against other elements before being summed. Like convolution, for example.

I’ll make an example if I have time… at some point…

Yeah I suppose its a linear sum if you do it in the emitter stage and can access the particle data (isn’t that on the cpu? not even sure if emitter update can access particle data if its on the gpu).

Really interested to see what you come up with :slight_smile:

This is using two emitters – one generates particles from the other. So, in the Emitter Update stage of the second emitter, you sum up the total number of particles needed. Then, you position them in subsequent stages.

The emitter never needs to access the GPU data – creating the particles vs. moving them around are totally separate things. Creation happens on the CPU; moving them around happens on the GPU.

It’s definitely tricky stuff. I’m just kinda familiar with it because I spent the last month and a half trying to debug the Hair Strands system, which is based on Niagara. Does all sorts of crazy things; never did understand it entirely…

1 Like

Hi, Regarding the AdvanceGroomState,
where is the StepIndex original Emitter attribute is set?
Cheers

Agghh, sorry. I haven’t had time to make a demo.

The StepIndex is set inside the IncrementStepIndex function. That function is called inside the Map-For structure.

1 Like