AppendStructuredBuffer count is the same as allocated amount for the mirroring computebuffer while I append less times.

Hi all,

I am using a computeshader to populate a unityterrain with trees. However, I am facing issues with the AppendStructuredBuffer. What I want to do, is let a probability check determine if a tree should be spawned or not. If not, then I return, otherwise I append to the buffer.

If I don’t filter (i.e. probability is 100%), everything goes well, all trees look correct. However, if I filter, I get artifacts (in this case on the height). Upon closer inspection it seems that the count reflects the maximum amount of elements I expect (allocated in the C# ComputeBuffer), however this should not be the case…
I use the SetCounterValue(0) to properly set the counter for the buffer.

  1. Am I wrong to assume that the count of the ComputeBuffer should be the amount of appended elements instead of the total allocated elements?
  2. If so, how can I find the latter?
  3. If I am correct, does anyone see why I would get the incorrect count?

Compute Shader:
AppendStructuredBuffer Result;

struct TreeInstance
{
   float3 position;
   float widthScale;
   float heightScale;
   float rotation;
   int color;
   int lightmapColor;
   int prototypeIndex;
   float temporaryDistance;
};

[NUMTHREADS]
void CSMain(uint3 id : SV_DispatchThreadID)
{
  // random function is functioning as it should.
   if (random(id.xy) > globalProbability)
   { return; }
   TreeInstance tree;
   // some code that initializes the TreeInstance values.
   Result.Append(tree);
}

relevant C# code:

    ComputeBuffer treeInstances =
        new ComputeBuffer(total, Marshal.SizeOf<TreeInstance>(), ComputeBufferType.Append);
    treeInstances.SetCounterValue(0);
    treeInstances.GetData(someInitializedArray,0,0,treeInstances.count);
    treeInstances.Release();

Thanks for your time :slight_smile:

ComputeBuffer.count is always the size of the buffer, not how many elements were appended. It’s a bit confusing because both are called “count”. As far as I know, the only way to get the number of appended elements is to use the CopyCount method to copy it to another buffer and then read from that buffer:

uint GetCount(ComputeBuffer appendBuffer) {
	var countBuffer = new ComputeBuffer(1, 4, ComputeBufferType.Raw);
	var data = new uint[1];
	
	ComputeBuffer.CopyCount(appendBuffer, countBuffer, 0);
	countBuffer.GetData(data);
	countBuffer.Release();

	return data[0];
}

Note that reading from the GPU can be bad for performance. If you do this frequently, it’s better to keep the data on the GPU if possible or use AsyncGPUReadback.