Place paticle at specific position !

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!

You probably want buffer, but your description is very general, so it’s hard to say where is your bottleneck.

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 :slight_smile:

You can find some info here: https://discussions.unity.com/t/862147
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?

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 :slight_smile:

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.

In reality currently I launch 30/40 raycast per frame at most (It is a “weapon” that shoots at very high speed)

So how managed to spawn 30 particles with single event during one frame?

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

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.

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 Imgur: The magic of the Internet 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.

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):

// Some other script call this
public void ScheduleEvent(Vector3 position)
{
    // Add spawn position to the list
    data.Add(position);
}

void LateUpdate()
{
    if (data.Count == 0)
    {
        // There is no data, so nothing to spawn this frame
        return;
    }
    // Resize buffer when needed
    EnsureBufferCapacity(ref graphicsBuffer, data.Count, BUFFER_STRIDE, visualEffect, VfxBufferProperty);
    // Set data from this frame
    graphicsBuffer.SetData(data);
    // Set how many elements of buffer are actually used
    visualEffect.SetInt("ElementsInBuffer", data.Count);
    // Send default event or custom one visualEffect.SendEvent(...);
    visualEffect.Play();
    // Remove old data to start collecting new data again
    data.Clear();
}

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.

Maybe your particle system capacity is still too low, but hard to say.

I don’t know exactly what the problem is, I admit.
I currently use like this: Imgur: The magic of the Internet

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.

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.

Indeed it works much better haha! Everything looks good! Thank you very much for your time! I would never have made it without you :slight_smile: