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. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice

Question Place paticle at specific position !

Discussion in 'Visual Effect Graph' started by Maxoumi, Aug 18, 2022.

  1. Maxoumi

    Maxoumi

    Joined:
    Nov 12, 2020
    Posts:
    14
    Good morning ! Here I am working on a project where I need to place a lot of particles in raycast.

    I currently use a simple position and a play() function, it works quite well but consumes a lot of performance, I stay beyond 60/100 fps but the GPU is used at 90/100%.

    I saw some technique with textures but no way to make it work!

    Thank you in advance for your help and sorry for my English it's not my native language!
     
  2. Qriva

    Qriva

    Joined:
    Jun 30, 2019
    Posts:
    1,123
    You probably want buffer, but your description is very general, so it's hard to say where is your bottleneck.
     
  3. Maxoumi

    Maxoumi

    Joined:
    Nov 12, 2020
    Posts:
    14
    Ok I see, could you tell me a bit more about the buffer?

    Otherwise when in my project I use raycast to shoot with a gun and at the "impact" I put a particle. So I use the hit.point to get the position and send it to my vfx to spawn a particle there.

    Thanks for your help :)
     
  4. Qriva

    Qriva

    Joined:
    Jun 30, 2019
    Posts:
    1,123
    You can find some info here: https://forum.unity.com/threads/vfx-graph-siggraph-2021-video.1198156/
    However "spawn particle" is very wide term. Do you spawn by them by running Play() every time you hit or you spawn whole new vfx graph in hit position?
     
  5. Maxoumi

    Maxoumi

    Joined:
    Nov 12, 2020
    Posts:
    14
    I use only one vfx (Several in reality but I create a new one when the cap of 1M is reached but it's very long) and at each play() I create a particle at the place of the raycast

    I do not create vfx at each iteration!

    And thanks for the link I'll see if it can help me :)
     
  6. Qriva

    Qriva

    Joined:
    Jun 30, 2019
    Posts:
    1,123
    Then I assume you raycast once per frame as event can be called only once per frame.
    If so, then I can't see bottleneck and buffer will not help you I guess.
     
  7. Maxoumi

    Maxoumi

    Joined:
    Nov 12, 2020
    Posts:
    14
    In reality currently I launch 30/40 raycast per frame at most (It is a "weapon" that shoots at very high speed)
     
  8. Qriva

    Qriva

    Joined:
    Jun 30, 2019
    Posts:
    1,123
    So how managed to spawn 30 particles with single event during one frame?
     
  9. Maxoumi

    Maxoumi

    Joined:
    Nov 12, 2020
    Posts:
    14
    Ah yes, I had indeed forgotten that detail. Currently I create 40 different default vfx and each raycast retrieves the correct vfx according to the attack id with a loop.

    But the goal is to have only one vfx available and create others if they reach the limit, because that's mainly what uses a lot of performance.

    That's why I need to send all positions to the vfx rather than sending each time to a vfx (which is my limit for now)

    But I haven't really found a way to tell him to spawn at a specific location and especially with a long "list" of position
     
  10. Qriva

    Qriva

    Joined:
    Jun 30, 2019
    Posts:
    1,123
    I get it, so you are pooling objects with VFX to desired positions. In this case buffer is perfect solution for you, you can create some singleton like object to call it every time you need to spawn that effect. You add record to the list and if it's not empty at the end of frame you fill buffer with data (and data count) and play event once. Next, in the graph you read buffer and you spawn particles accordingly. In the link I posted before there is simple example posted by me in the last post - it's stripped version of controller I made and it had exactly the same task.
    One note - remember about bounds as the effect should probably stay in world origin and just spawn particles in world space, but it must be visible to camera.
     
  11. Maxoumi

    Maxoumi

    Joined:
    Nov 12, 2020
    Posts:
    14
    I think I understood how it works and the purpose. Thank you for your help ! However, I can't get it to work properly.

    I have a few questions if you don't mind.
    1. Given the number of sends that I do, I must put what capacity my buffer has (And stride)
    2. I get an error https://i.imgur.com/GXYMzu1.png I think it comes from the fact that there are too many objects in my list, right? If so, I don't know how to do better.

    Apart from that I have the impression that it works the first few particles after that I have the error more said above.
     
  12. Qriva

    Qriva

    Joined:
    Jun 30, 2019
    Posts:
    1,123
    If you want single graph (what would be the best), then you need to estimate total particle system capacity so it display properly.
    Buffer capacity is just length of buffer, you can't send more data than capacity, for example you can't put 10 elements into buffer with capacity 5. When you sample buffer you want to spawn only desired amount of elements, so you need to set in graph, also the number of positions to be spawned, so it reads only part of buffer you want.
    Buffer stride is how big memory chunk is (for single element) and it depends on what data you send to graph. In addition you must remember to set proper data type in Sample Buffer node.

    To ensure there is no problem with capacity you can find in my example method
    EnsureBufferCapacity
    , it's called before buffer is set - it allocates new one, big enough. In your case you want to add element to the list every time you want to spawn something, but set buffer and send event only once at the end of frame as you don't know how many elements you want to send to GPU before that. Following my example it would be something like this (not tested obviously):
    Code (CSharp):
    1. // Some other script call this
    2. public void ScheduleEvent(Vector3 position)
    3. {
    4.     // Add spawn position to the list
    5.     data.Add(position);
    6. }
    7.  
    8. void LateUpdate()
    9. {
    10.     if (data.Count == 0)
    11.     {
    12.         // There is no data, so nothing to spawn this frame
    13.         return;
    14.     }
    15.     // Resize buffer when needed
    16.     EnsureBufferCapacity(ref graphicsBuffer, data.Count, BUFFER_STRIDE, visualEffect, VfxBufferProperty);
    17.     // Set data from this frame
    18.     graphicsBuffer.SetData(data);
    19.     // Set how many elements of buffer are actually used
    20.     visualEffect.SetInt("ElementsInBuffer", data.Count);
    21.     // Send default event or custom one visualEffect.SendEvent(...);
    22.     visualEffect.Play();
    23.     // Remove old data to start collecting new data again
    24.     data.Clear();
    25. }
     
  13. Maxoumi

    Maxoumi

    Joined:
    Nov 12, 2020
    Posts:
    14
    Thanks for your help it works quite well. There is one last little problem that I don't quite understand.

    The first frame creates 40 particles well, but the following ones create about 5/10 of them for me (quite random), I don't know what is causing this problem.
     
  14. Qriva

    Qriva

    Joined:
    Jun 30, 2019
    Posts:
    1,123
    Maybe your particle system capacity is still too low, but hard to say.
     
  15. Maxoumi

    Maxoumi

    Joined:
    Nov 12, 2020
    Posts:
    14
    I don't know exactly what the problem is, I admit.
    I currently use like this: https://i.imgur.com/bjtz3PK.png

    There is normally enough capacity for a while, everything else is more or less the same as your scripts. And even playing with the initial capacity of the buffer/data does not change anything.
     
  16. Qriva

    Qriva

    Joined:
    Jun 30, 2019
    Posts:
    1,123
    You are using particle id as index, so it's clamped by buffer sampler and all of them spawn in the same position I guess. Use spawnIndex instead.
     
  17. Maxoumi

    Maxoumi

    Joined:
    Nov 12, 2020
    Posts:
    14
    Indeed it works much better haha! Everything looks good! Thank you very much for your time! I would never have made it without you :)