Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Question VFX Graph projectile position update from CPU collection

Discussion in 'Visual Effect Graph' started by MrBigly, Aug 15, 2023.

  1. MrBigly

    MrBigly

    Joined:
    Oct 30, 2017
    Posts:
    218
    I have a VFX graph of simple (prototype) projectiles shot out of a gun rendering simple particle Quad outputs.

    I have one instance of VFX graph to handle the flight of all projectiles.

    I have a collection of projectile positions that I periodically update with each FixedUpdate() by the CPU.

    I don't have any GameObjects representing projectiles, just data -- position Vector3 structures and corresponding velocity Vector3 structures.

    My first incarnation has the CPU updating the position structures and the VFX graph updating the particle positions with the same velocity vectors. But I want only one calculation by the CPU to update both the CPU projectile position structures and the GPU particle positions.

    What is the best practice to updating the particle positions with the position structures updated by the CPU?

    I looked at using Set Position in the VFX graph Update section, but i don't see how to get the latest position information passed to the particle. And I don't see how to match each position update with their corresponding particle.

    I have been looking all day and haven't found any clarity on this issue. Any help would be greatly appreciated.
     
  2. PaulDemeulenaere

    PaulDemeulenaere

    Unity Technologies

    Joined:
    Sep 29, 2016
    Posts:
    134
    Hello,

    Your particle simulation is running on CPU and the VFX is only displaying a bunch of particles, do I understand correctly?

    In that case, I would recommend the usage of an exposed Graphics Buffer updated every frame, the VFX will use a Sample Buffer based on particleId attribute to retrieve updated position from the CPU. In that case, the Update Context is optional and the position fetching can be done in Output Context.

    However, this approach only works for a reasonable amount of particles, doing a lot of upload of GPU data every frame isn't generally recommended for real-time application.

    Side note: if you want a fine control on your spawn event, you can also directly send data to the initialize context using direct link. It can be an alternative approach where your initial particle position and velocity on GPU are matching your CPU simulation, assuming your physic integration is equivalent, both particles on CPU and GPU should have the same behavior.

    I hope it will help you.
     
    AlexAdach and MrBigly like this.
  3. MrBigly

    MrBigly

    Joined:
    Oct 30, 2017
    Posts:
    218
    The ceiling for the number of concurrent rounds in flight would be 4k (all 80 players shooting a 50 round clip simultaneously in full auto mode). The typical would be around 50..100. Each position is represented in a Vector4 in their raw collection for 16 byte alignment already. Let me know what you think about these numbers even if only in the general sense.

    I wouldn't mind keeping two simultaneous simulations of the flight path, but I am not sure the VFX system could handle the following scenarios:

    1) know when to stop a projectile upon impact of a target or hard surface
    2) know when and to what values to alter the velocity (direction and speed) upon ricochet off a surface
    3) know when to slow a projectile upon entering water (due to drag)

    Where could I find a simple example (sample code?) of implementing the Graphics Buffer approach?
     
  4. Qriva

    Qriva

    Joined:
    Jun 30, 2019
    Posts:
    1,108
  5. AlexAdach

    AlexAdach

    Joined:
    Jan 25, 2023
    Posts:
    24
    after struggling with this for a few days. I'd recommend looking into the sample project linked in this thread.
    You can see what the script/vfx graph setup looks like. I just got a real basic setup working.
     
  6. MrBigly

    MrBigly

    Joined:
    Oct 30, 2017
    Posts:
    218
    Actually I got a variant of the sample working already. The only thing that I see failing is that in a burst fire, say 8 rounds, I see all the rounds moving away from the gun as they should (slow velocity looks dope), and they all disappear after they reach the end of their life (say 2 secs), except the last one. I haven't had a chance to look into why, but I suspect the VFX object itself stopped and didn't finish destroying the last round. Not sure if that is even close, like I said I haven't investigated it. But it is coming along fine at this point.

    shout out to Qriva for the samples that were straight forward and the blog that talked about it some.
     
  7. MrBigly

    MrBigly

    Joined:
    Oct 30, 2017
    Posts:
    218
    Ok, so I am back on this particular section of my game and I came across an issue and I think I know generally why it is happening, but I don't know how to solve it. My solution is based upon the code Qriva offered for a sample to start with. In my solution, I can spawn particles to represent projectiles and position them in real time. That works. I can shoot, for example, 3 projectiles over 9 frames, thus 1 projectile every 3 frames. In the VFX graph I pass an array of positions with the first three elements for those three particles. The positions are in the form of Vector4, with the fourth member, w, counting down to 0 to denote end of life.

    Once the three projectiles die, I then send another three. They take the Position array indices of 0, 1, and 2. But I think these don't match to the newly spawned particles in the VFX. It seems that though the particles from the first burst of 3 projectiles should have destroyed, I think they still linger invisible and inactive. I think that the array indices no longer match to the particle id values.

    There is a bigger picture to this problem. How would I ever be able to specify which particle has which id value? It seems to be implied for me, which is what I am struggling with I believe. If I cannot free up a particle with a specific id value, then I cannot reuse the array index matching it. But when it does free up, it seems that all the particles in the system automatically shift down to match those lower id values?!?
     
    Last edited: Sep 14, 2023
  8. MrBigly

    MrBigly

    Joined:
    Oct 30, 2017
    Posts:
    218
    So I think I solved the issue I was having with not matching up the particle identifier with the indices in my array. I was using the particleId built in attribute, and I honestly believe it floats (changes) as the total number of particles changes. Instead, I used a custom event ID attribute. The challenge was finding a way to associate it with the update group, and by switching to Current, it works just fine.



    Code (CSharp):
    1.  
    2.             VFXEventAttribute EventSettings = VFX.CreateVFXEventAttribute();
    3.             EventSettings.SetInt("ID", unitid);
    4.             EventSettings.SetVector3("VelocityN", Velocity * 10);
    5.             VFX.SendEvent("FireProjectile", EventSettings);
    6.  

    upload_2023-9-14_11-11-44.png
     
    Last edited: Sep 14, 2023