I'm trying to create a compute shader that will generate and manage the movement of a point cloud.
The shader needs several thousand points to work on and I want to pull back the first dozen or so.
Currently I'm trying to crate a minimal working example, where the compute shader populates a buffer of ~8k values and I read the first 10 back.
Compute Shader:
RWStructuredBuffer<float3> starLocationBuffer;
[numthreads(64, 1, 1)]
void BuildStars(uint id : SV_GroupIndex) {
starLocationBuffer[id] = float3(id, 1, 1);
}
Calling class:
private ComputeBuffer starLocations;
private int numStars = 8192;
private int numLocations = 10;
private void Build() {
starLocations = new ComputeBuffer(
numStars,
Marshal.SizeOf(typeof(Vector3)),
ComputeBufferType.Default,
ComputeBufferMode.Dynamic);
mapComputeShader.SetBuffer(Kernel("BuildStars"), "starLocationBuffer", starLocations);
int y = (int)(Mathf.Ceil(numStars / 64f));
Debug.LogFormat("Building star map [64, {0}, 1] for a total of {1:#,0}", y, y * 64);
mapComputeShader.Dispatch(Kernel("BuildStars"), 64, y, 1);
}
private void Read() {
var locs = new Vector3[numLocations];
starLocations.GetData(locs, 0, 0, numLocations);
Debug.Log(String.Join(", ", locs.Select(x => x.ToString())));
}
I'd expect that to return an array of Vector3 with values (0,0,0)
, (1,0,0)
, (2,0,0)
, etc...
What I actually get back varies. Initially, I was getting mostly-zero values with some unusual values thrown in (NaN and large numbers). Now, I get consistent zeros.
I'd assume this was an issue with the array being uninitialised, however, the compute shader is supposed to write every value before I go and look at the data.
My next thought is that there may be a race condition... Perhaps the compute shader hadn't had time to write those values before I went looking, however, this post by a Unity engineer indicates it enforces sequential execution.
What am I missing?