Currently I am using a niagara system with a Custom HLSL node to simulate a Rope. In the distance constraint I get the position of the previous and next particles by using the attribute Particles.UniqueID. This works perfectly fine, but when there are more than 64 particles the system breaks. My guess is that the particles are simulated in GPU in batches of 64 and you cannot access a particle position that is not in your batch? If so how can I handle this? Is there any other I can safely access neighbour particle positions?
ParticleAttributeReader.GetPositionByIndex<Attribute="Position">(UniqueID - 1, bIsValid, OtherParticlePosition);
ParticleAttributeReader.GetPositionByIndex<Attribute="Position">(UniqueID + 1, bIsValid, OtherParticlePosition);
[Attachment Removed]
Hi Juan,
Although particles are simulated in batches on the GPU, their data is stored in a shared buffer which can be accessed by any particle, so this is not really the problem in your case.
What is happening there is that the UniqueID you are using is not guaranteed to match the particle indices required to access the data buffer. Moreover, they are not guaranteed to form a contiguous sequence of numbers starting from 0 or any specific value and following without holes in the numbering.
Note that particle Indices are also not guaranteed to be stable during multiple frames of a GPU simulation, so you cannot work directly with indices to find the previous and next one by subtracting and adding one. The ordering on one frame might not be the same as the ordering on the following frame.
To achieve what you want, the recommended approach is to spawn the particles in a burst, then use a spawn script to query each particle’s “ExecutionIndex”. At that specific moment, you can subtract and add one to that index to establish an ordering between the particles which you will use later. But you should pass the (index-1) and (index+1) values to the function GetIDAtSpawnIndex() to get the stable ID for those neighboring particles, and store that instead. So, each particle will store the stable ID of its previous and next particle along the rope.
You can find an example of this technique on the ContentExamples project. Open map “Niagara_Advanced_Particles” and look for the display named “Iterative Constraints”, which showcases a chain hanging from a point. The corresponding Niagara System is at “Niagara/AttributeReader/Constraints/Chain_SimulationStages”. Look inside module “Particle Spawn -- Initialize Chain Constraint” and examine the part that sets “Particles.ChainLinkBehind” and “Particles.ChainLinkAhead” (screenshot below). Then look inside module “Solve Chain Constraint -- Solve Chain Constraint” to see the usage of nodes “GetPositionByID”.
[Image Removed]I hope this is helpful. If you still have any questions, don’t hesitate to ask!
Best regards,
Vitor
[Attachment Removed]