Search Unity

Question GetParticleSystemInfo latency

Discussion in 'Visual Effect Graph' started by MrMuise, Feb 20, 2022.

  1. MrMuise

    MrMuise

    Joined:
    Jun 11, 2020
    Posts:
    3
    It looks like GetParticleSystemInfo, specifically aliveCount, gets updated roughly every 1000ms with correct information at the time of the update. is there a way to increase how often this happens or manually trigger an update?

    I've tried adjusting everything timing related in project settings and manually simulating several steps every frame, but GetParticleSystemInfo seems to update at a fixed rate, about once every 1000ms, both in editor and in builds. It also appears to be the same rate across different versions, projects and computers no matter how many particles are simulated or the speed that they're simulated at.

    I tested this by just moving a Kill (AA Box) via script and outputting aliveCount and Time.time to the console every frame, then just advancing each frame manually and comparing the Time.time from when the particle is visibly killed to when aliveCount gets updated.

    The first update to aliveCount can vary wildly, I've seen +- 500ms in my quick tests, but every time the count is updated after the first returns roughly every 1000ms. Again, these times are the same across different settings, versions and computers.

    Am I missing something obvious or is this just some internal logic I don't have access to?
     
  2. PaulDemeulenaere

    PaulDemeulenaere

    Unity Technologies

    Joined:
    Sep 29, 2016
    Posts:
    154
    Hello,

    I don't think you missed anything and this behavior relies on internal logic.

    There are two things responsible of the latency:
    - VFXParticleSystemInfo.aliveCount internally uses AsyncGPUReadbackRequest which is involving a few frames of latency.
    - For performance reasons, the readback request is only pushed every 60 frames which corresponds to your observed behavior and contributes to the most of the latency.

    This 60 frame period isn't configurable so far.

    The aliveCount's main purpose is debug information but it's also a simple way to detect if a GameObject can be released (in case of simple effects only played once).

    What is the kind of scenario where you need to minimize the latency of the aliveCount update ?
     
  3. MrMuise

    MrMuise

    Joined:
    Jun 11, 2020
    Posts:
    3
    Since aliceCount can reference a specific system in the VFX graph it can be used to trigger code when a change is detected in that specific system.

    I'm using it as a way to get information out of the VFX graph beyond it's initial burst spawn, specifically if particles are being killed then play a sound based on amount killed.
     
  4. PaulDemeulenaere

    PaulDemeulenaere

    Unity Technologies

    Joined:
    Sep 29, 2016
    Posts:
    154
    Thanks for the clarification. I'm afraid with current feature set, you won't be allowed to do this with a minimum latency.

    This kind of feature is on the roadmap but I can't provide any ETA yet, feel free to comment and vote, we are consedering every feedbacks (and I'm registering this thread as reference).

    Meanwhile, you can potentially use an output event plugged into the last spawn context, or alternatively, analyse the state of your input spawn context using GetSpawnSystemInfo. Then, deduce how much and when particles have been spawned and compute when they will be killed. However, this kind of synchronisation isn't really convinient and it doesn't work if lifetime is random and/or relies on collision.
     
  5. MrMuise

    MrMuise

    Joined:
    Jun 11, 2020
    Posts:
    3
    In my case I have a single VFX Graph spawning particles that are destroyed via collision, those spawn other particles for controlling smoke, fire and debris. All those those are spawned using GPU Events, which I don't think GetSpawnSystemInfo can interact with.

    To get around this I just split any GPU Events off to also create a single particle of a specific color that lives for one frame out of the level bounds. I can then use a camera that renders to a texture which can then be read to trigger code based on RGB values of individual pixels as well as that pixels location.
     
  6. PaulDemeulenaere

    PaulDemeulenaere

    Unity Technologies

    Joined:
    Sep 29, 2016
    Posts:
    154
    Hello,

    I was inspired by your suggestion and really curious about the possible setup:

    There is an orthographic camera below the keys, it clips every objects above the piano and only the depth buffer is captured.

    If you are planning to readback a render texture from the GPU, I can suggest to reduce the bandwidth usage from GPU to CPU using an intermediate compute shader. In this quick sample, I'm storing the count of pixels matching each key inside a ByteAddressBuffer, these eight integers is the only content read from the GPU.

    However, this workaround seems pretty convoluted and I won't recommend it for the general purpose. It's pretty easy to miss a collision and it only works with planar primitive. An alternative would be using a GPU Event to "splat" the collision data into a texture assuming these hidden decals are only visible by a specific offscreen camera, this is also what you early suggested :
    As mentioned before, if possible, it's probably simpler to synchronize sound objects and VFX events, if the timing can't be deduced from the input event then you can use a roundabout way like this but I also recommend to vote on the roadmap.

    N.B.: The sound part implementation of this project is probably wrong, that's not my area of expertise.

    Bonus:

     

    Attached Files:

    Last edited: Feb 27, 2022
    VladVNeykov likes this.