Search Unity

Sampling a Texture in the Spawn context

Discussion in 'Visual Effect Graph' started by Aaron-Meyers, Feb 25, 2020.

  1. Aaron-Meyers

    Aaron-Meyers

    Joined:
    Dec 8, 2009
    Posts:
    297
    I'm using VFX Graph to render point clouds and I've got a Compute Shader that culls points before sending them on to the graph. The Compute Shader uses an append buffer and so I need to tell the VFX graph how many points to spawn. Initially I was calling GetData on a compute buffer that I used ComputeBuffer.CopyCount to read the count into. But even the tiniest (1 uint!) reads back from the GPU seem to incur too much of a hit (~5ms according to the profiler).

    So I wrote another compute shader kernel to copy the value from that buffer into the first index of a render texture, which I would in turn send to the VFX graph and read into the count input of the Spawn context.



    Unfortunately, as soon as I connected the input, the console spat out an exception and my graph stopped working :(

    Exception while compiling expression graph: System.InvalidOperationException: The expression UnityEditor.VFX.VFXExpressionCombine is not valid as it have the invalid flag: InvalidOnCPU

    My hunch is that sampling from Textures may not be supported in the Spawn context. Is this true? If so, can anyone suggest any other way to get this simple uint into my VFX graph without having to copy it back from the GPU?
     
  2. JulienF_Unity

    JulienF_Unity

    Unity Technologies

    Joined:
    Dec 17, 2015
    Posts:
    240
    Hi,

    Spawn is the only context in VFX Graph being executed on CPU so you cannot read texture data in it.

    There are 2 different solutions I see for what you want:
    • Use async GPU readback to read back your count on CPU and feed it to the VFX Graph once here. There will be a few frames of latency before the result is accessible but no stall. So it's a good solution if you can afford the latency.
    • Burst the maximum possible amount of particles in spawn (i.e. the capacity of the system) and use the alive attribute in the Init context to kill particles at birth by testing their spawnIndex attribute against the value in your texture.
    Hope this helps
     
  3. Aaron-Meyers

    Aaron-Meyers

    Joined:
    Dec 8, 2009
    Posts:
    297
    Thanks Julien that makes sense... latency is no good for this situation so I will try out option #2!
     
unityunity