2
\$\begingroup\$

I am using Unity to send two types of data to the Compute Shader:

A struct:

struct Flock
{
    public Vector3 position;   
    public Vector3 velocity;   
}

And an Array of the above struct.

C# Code:

Flock[] ComputeFlock()
{
    Flock[] output = new Flock[Amount];

    int kernel = FlockComputeShader.FindKernel("MoveFlock");

    // Flock struct
    int size = sizeof(float) * 3 + sizeof(float) * 3;
    ComputeBuffer buffer = new ComputeBuffer(_flockAI.Length, size);
    buffer.SetData(_flockAI);

    FlockComputeShader.SetBuffer(kernel, "dataBuffer", buffer);

    // Flock array
    ComputeBuffer neighboursBuffer = new ComputeBuffer(_flockAI.Length, size * _flockAI.Length);
    neighboursBuffer.SetData(_flockAI);
    FlockComputeShader.SetBuffer(kernel, "neighbours", neighboursBuffer);

    FlockComputeShader.Dispatch(kernel, _flockAI.Length / 16, 1, 1);
    buffer.GetData(output);
    buffer.Dispose();

    return output;
}
                 

Compute Shader:

#pragma kernel MoveFlock

struct FlockVec3Float
{
    float3 position;
    float3 velocity;
};

RWStructuredBuffer<FlockVec3Float> dataBuffer;

StructuredBuffer<FlockVec3Float> neighbours[1024];

[numthreads(16,1,1)]
void MoveFlock(uint3 id : SV_DispatchThreadID)
{
    for (uint i = 0; i < 1024; i++) {
        dataBuffer[id.x].position.xyz = dataBuffer[id.x].position.xyz + neighbours[i].position.xyz;
    }
}

I am trying to implemented a form of boids algorithm in the compute shader. The struct is the boid and the array of structs is to identify positions of it's neighbours. What I can't figure out is how I can send the full array of struct to the shader and have it iterate over it.

I can send the struct and have the shader read and write to it without any issues. Can someone point out what I might be doing wrong? I am wondering if it is something to do with the stride in the buffer. Thanks!

\$\endgroup\$
3
  • \$\begingroup\$ As far as I can tell, your code is already sending the array correctly in the buffer.SetData(_flockAI) line. Could you elaborate as to what specific problem you are having? Also, I am curious as to why you are putting the same data into two separate buffers. That is, you could just iterate over the dataBuffer inside of the compute shader, as long as you are only writing into a single position from each thread. \$\endgroup\$
    – PepeOjeda
    Commented Jun 26, 2022 at 19:10
  • \$\begingroup\$ @PepeOjeda Thank you, that makes a lot of sense. I didn't realize I could just iterate over the array buffer. \$\endgroup\$
    – Aaron Z
    Commented Jun 27, 2022 at 20:31
  • \$\begingroup\$ Hey, for some reason this popped up in my head while doing dishes today and I realized that I lied to you. Using two buffers (what you were initially doing) is actually correct. Using a single buffer causes a race condition, as you are reading a value that might or might not already have been modified by another thread. In fairness, this is not too important for something like Boids, as changes from one frame to the next are going to be small, but it is still wrong. Sorry! \$\endgroup\$
    – PepeOjeda
    Commented Jul 2, 2022 at 16:42

1 Answer 1

0
\$\begingroup\$

For anyone that might have a similar question, here's how I iterate over the buffer:

uint _length;
uint _stride;

Buffer.GetDimensions(_length, _stride);

for (uint i = 0; i < _length; i++)
{
    Buffer[i];
}
```
\$\endgroup\$
1
  • \$\begingroup\$ If this solved your problem, be sure to click the checkmark icon on the left to mark it as "Accepted". \$\endgroup\$
    – DMGregory
    Commented Jul 27, 2022 at 22:42

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .