Search Unity

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

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

  1. UCrowds

    UCrowds

    Joined:
    Jan 18, 2019
    Posts:
    1
    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?