[Solved] Weird append buffer sizes

I have a compute shader that generates voxels and mesh data for voxel terrain chunks.

I have a flattened 3D array holding the voxels and an AppendStructuredBuffer holding structures that define the mesh data for a each face to be displayed.

My problem is : once I’ve run my compute shader to generate the mesh, I’m getting wrong sizes for the append buffer. These values are not completely random. For example, I can get like 157, 348, 409, 245, etc… when I’m expecting 256 (for example). I’m not getting crazy values like 1423751, 752554, 12175, etc… The values seem rather “close” to what is expected, but they are just wrong.

I made a temporary modification to the function that generates the voxels so that I getting a perfectly flat terrain, i.e voxels for which y > 0 are air, and others are not. This should result in CHUNK_SIZE * CHUNK_SIZE faces per chunk, for chunks that contain the ground level. This is how I am sure that I’m getting wrong values, because I should always get the same sizes for the append buffer.

I tried two different ways to count the face mesh data structures I’m appending to the append buffer :

  1. Using the HLSL function InterlockedAdd() ;
  2. Using the Unity function ComputeShader.CopyCount().

In both cases I’m getting weird results, which lets me think that I’m doing something wrong somewhere, but can’t see what it is.

So my question : would you have any idea what could be causing these append buffer size issues ?

Below is a piece of my shader :

RWStructuredBuffer<int> faceMeshDataCount;
AppendStructuredBuffer<FaceMeshData> faceMeshDataArray;

// ETC...

[numthreads(2, 2, 2 * 6)]
void GenerateMeshData(uint3 id : SV_DispatchThreadID)
{
    const int x = id.x;
    const int y = id.y;
    const int z = id.z / FACES_PER_CUBE;

    const int index = Flatten3DIndex(x, y, z, CHUNK_SIZE);
    const int type = GetVoxel(index);

    if (type == 0)
    {
        return;
    }

    const int face = id.z % FACES_PER_CUBE;

    const float cubePosX = x + 0.5;
    const float cubePosY = y + 0.5;
    const float cubePosZ = z + 0.5;

    FaceMeshData faceMeshData;

    faceMeshData.type = type;

    switch (face)
    {
    case 0:
        if (GetVoxelAdj(1 + x - 1, 1 + y - 0, 1 + z - 0) == 0)
        {
            faceMeshData.vertex0 = float3(cubePosX - 0.5, cubePosY - 0.5, cubePosZ - 0.5) * INVERSE_CHUNK_SIZE;
            faceMeshData.vertex1 = float3(cubePosX - 0.5, cubePosY - 0.5, cubePosZ + 0.5) * INVERSE_CHUNK_SIZE;
            faceMeshData.vertex2 = float3(cubePosX - 0.5, cubePosY + 0.5, cubePosZ - 0.5) * INVERSE_CHUNK_SIZE;
            faceMeshData.vertex3 = float3(cubePosX - 0.5, cubePosY + 0.5, cubePosZ + 0.5) * INVERSE_CHUNK_SIZE;

            faceMeshData.triangleVertexIndex0 = 0;
            faceMeshData.triangleVertexIndex1 = 1;
            faceMeshData.triangleVertexIndex2 = 2;
            faceMeshData.triangleVertexIndex3 = 1;
            faceMeshData.triangleVertexIndex4 = 3;
            faceMeshData.triangleVertexIndex5 = 2;

            faceMeshData.uv0 = float2(0, 0);
            faceMeshData.uv1 = float2(0, 0.5);
            faceMeshData.uv2 = float2(0.5, 0);
            faceMeshData.uv3 = float2(1, 1);

            faceMeshDataArray.Append(faceMeshData);
            //InterlockedAdd(faceMeshDataCount[0], 1);
        }
        break;

            // ETC...

And here is a piece of the C# code supposed to retrieve the size of the append buffer :

            int[] temp = new int[1];
            temp[0] = 0;

            faceMeshDataCountCBuf.SetData(temp);
            faceMeshDataArrayCBuf.SetCounterValue(0);

            // Generate the mesh data.
            computeShader.Dispatch(generateMeshDataKernel, Constants.ChunkSize / 2, Constants.ChunkSize / 2, Constants.ChunkSize / 2);

            ComputeBuffer.CopyCount(faceMeshDataArrayCBuf, faceMeshDataCountCBuf, 0);
            faceMeshDataCountCBuf.GetData(temp);
            int faceCount = temp[0];
            faceMeshDataArrayCBuf.GetData(faceMeshDataArray, 0, 0, faceCount);

Where is your
BufferName = new ComputeBuffer(Array.Length, sizeof(float)); // or int, or struct etc
This is where you set size of buffer and I don`t see it in script.

Sorry, here is it, I just wanted to put the most relevant pieces of code :

            faceMeshDataCountCBuf = new ComputeBuffer(1, sizeof(int), ComputeBufferType.Raw);
            faceMeshDataArrayCBuf = new ComputeBuffer(Constants.VoxelCount * Constants.FacesPerVoxel, UnsafeUtility.SizeOf(typeof(FaceMeshData)), ComputeBufferType.Append);

Basically it can hold as many faces as there can possible be, and probably twice that actually. I need to optimize the size to avoid wasting memory, but right now I’d rather use too much memory than introducising new problems into my code.

Okay I found the problem.
Actually, what I was doing with the append buffer was perfectly right. My problem came from my array of voxels which did not have the proper content due to wrong index computations.
I was really confident about this code because I have reworked the way I coded my voxel terrain several times, so I did not expect the error to be there.
Thanks for the help anyway.