Search Unity

  1. Unity 6 Preview is now available. To find out what's new, have a look at our Unity 6 Preview blog post.
    Dismiss Notice
  2. Unity is excited to announce that we will be collaborating with TheXPlace for a summer game jam from June 13 - June 19. Learn more.
    Dismiss Notice
  3. Dismiss Notice

Question Pointer math on Compute Buffers to split 1 buffer into many?

Discussion in 'Shaders' started by UCrowds, Jan 4, 2022.

  1. UCrowds


    Jan 18, 2019
    I am using compute shaders to calculate, among others, positions for my agents in a simulation. All data on all agents is stored in compute buffers based on type (one compute buffer for all positions, another for velocity, basically a DOD). This cannot be changed. I also use the GPUInstancer from GurBu Technologies. This requires different meshes to have their data in different compute buffers (one compute buffer for positions for each mesh used). This can also not be changed (as far as I know at least). The data in the input positions is not sorted on meshes, so the order is completely random.

    Because of this, I need to split the compute buffers after the calculations in the compute shaders, before it is send to the GPUInstancer. I had 2 ideas for this:

    1. Create a compute shader that loops over the input position array and based on a agent-to-mesh array, copy the data to the correct output array. This should work fairly easy, but there are some problems. First, as you can't really pass an buffer of compute buffers, you need to hardcode how many output compute buffers you have, therefore hardcoding the number of meshes that can be used. Second, you need to copy the data while it is already on the GPU, just not in the right form. Also, because the order in which the output arrays need to be written needs to be deterministic, you can't use the multiple threads of the GPU. Basically, it works, but is not optimal.

    2. Sort the input array based on mesh in a compute shader. Then find the start of each of the different meshes in the position array and get the pointer for this. Then I want to use this pointer to trick the GPUInstancer to see this one compute buffer as a N different compute buffers. This would make ensure that no extra copy is needed, but again, there are problems. First, I haven't been able to find the pointer of compute buffers, like you can for an array. The only thing I have found is ComputeBuffer.GetNativeBufferPtr, but that seems to be very platform specific and with so little documentation, that I have no idea if it would work. Second, I haven't found a way to initialize a compute buffer using a pointer and size (like you can with NativeArrayUnsafeUtility). It should work faster, but I can't figure out if/how it is possible.

    So what my best option? If possible I would like to do option 2, so does anyone know how to do this? If not, is there a way to make option 1 more performant? Or is there a third option I don't know about?