Search code examples
c#unity-game-enginebuffermeshcompute-shader

Compute Shaders - Integers >= 65535 Issue?


I'm not very experienced with compute shaders but right now I'm having to write some for the sake of performance. I've got a simple kernel method in my compute shader here that just reinterprets a buffer of structs into several buffers for use with a Unity mesh (I know that triData_out is pretty pointless, it's a relic from earlier in development and I want to resolve this before removing it):

#define THREADS_X 64
#define THREADS_Y 1
#define THREADS_Z 1

[numthreads(THREADS_X, THREADS_Y, THREADS_Z)]
void MMMesh(uint3 id : SV_DispatchThreadID)
{
    int index = id.x + (id.y * THREADS_X) + (id.z * THREADS_Y * THREADS_X);
    
    if (index >= allTrisCount)
        return;

    int destIndex = index * 3;
    MMTriangle srcTri = triData_in[index];

    vertData[destIndex] = srcTri.vertA.pos;
    vertData[destIndex + 1] = srcTri.vertB.pos;
    vertData[destIndex + 2] = srcTri.vertC.pos;

    uvData[destIndex] = srcTri.vertA.uv;
    uvData[destIndex + 1] = srcTri.vertB.uv;
    uvData[destIndex + 2] = srcTri.vertC.uv;

    triData_out[destIndex] = destIndex;
    triData_out[destIndex + 1] = destIndex + 1;
    triData_out[destIndex + 2] = destIndex + 2;
}

This method works great when my .Dispatch() call looks like .Dispatch(allTrisCount,1,1), however once destIndex >= 65535 all of a sudden the Unity mesh begins to corrupt with tris going all over the place (not sure if this is coincidence with the per-dimension .Dispatch() dimension size limit also being 65535 but the dimension itself would only be at minimum 65535/3 on a .Dispatch() call where destIndex >= 65535).

I never had this problem before I wrote this as a compute shader since this used to be multithreaded Unity Jobs code, so I can isolate the issue to this kernel method. What's the problem?


Solution

  • Not sure if related to the shader code.

    It is probably rather your Mesh.indexFormat => by default meshes in Unity are limited to 65536 (=> max index 65535) vertices.

    Index buffer can either be 16 bit (supports up to 65536 vertices in a mesh), or 32 bit (supports up to 4 billion vertices). Default index format is 16 bit, since that takes less memory and bandwidth.

    Note that GPU support for 32 bit indices is not guaranteed on all platforms; for example Android devices with Mali-400 GPU do not support them. When using 32 bit indices on such a platform, a warning message will be logged and mesh will not render.