Is there a way to draw an array of vertices/traingles directly from code, above 65k verts? I looked at Graphics class but it can only render a Mesh object.


1 Answer 1


Yes. I'll go through different methods on drawing with unity to explain them a little bit.

Drawing meshes larger than 65k vertices requires you to split the mesh in multiple pieces. There is no way around that in Unity. The 65k limit comes from the hard coded index buffer being 16 bit unsigned integer type. The maximum 16 bit integer value is 65536 and Unity has hard limited the value to that.

If you want to dynamically draw shapes that change all the time, you have to modify the mesh data every frame. Also whenever you want to draw generated meshes, you need to use the mesh class. There are faster and slower ways to do that, but that's outside the scope of this question. The basic way to do that is to have some arrays of different vertex data and then set all that to the unity Mesh data. A basic example:

Mesh mesh; // Generated somewhere

public void UploadMesh(Vector3[] pos, Vector3[] norm, Vector2[] uv, int[] indices)
    mesh.vertices = pos;
    mesh.normals = norm;
    mesh.uv = uv;
    mesh.triangles = indices;
    // Now when the mesh is drawn the next time, the data gets uploaded to the GPU memory
    // If you want the data to be uploaded immediately, uncomment the next line:
    //Mesh.UploadMeshData(true); // True means the CPU-memory of the mesh data is cleared, making the mesh data not readable any more

In this case you first have the vertices stored in managed memory and transfer them to the unmanaged memory of Unity by assigning them to the properties of the mesh object. When the mesh is drawn or UploadMeshData() gets called the data is transferred from the unmanaged memory to GPU memory. This is how I have seen Unity to work previously and by design it seems the mesh data gets stored twice in the CPU memory if you are keeping it in managed memory for speed reasons.

You can also get a native GPU memory pointers for the mesh by calling Mesh.GetNativeIndexBufferPtr and Mesh.GetNativeVertexBufferPtr, and upload the vertices to the GPU by hand, but that is very advanced and generally not needed feature. Usually this is used for large and frequently (like, every frame) changing meshes, like Sprites or particles. Uploading the vertex data to the GPU memory this way skips the memory being transferred to unmanaged side of Unity. This does not help with the 65k vertex limit.

In older deprecated version of OpenGL (I'm not sure about DirectX, never used it that much) you could send vertices to the GPU one by one. This was very slow and horrible way to draw stuff on screen and is nowdays used mostly just for backwards compatibility and not used at all in "newer" (10+years old) engines. It was called immediate mode. This was replaced by vertex arrays; mesh data stored in GPU memory. A mesh object in unity and in multiple other engines is a wrapper for GPU memory block holding the vertex data used for drawing your meshes. That's why it exists.

To draw without the mesh class you need to use the low-level GL API of Unity to do that. Note that as the manual says, using meshes is in almost all cases more efficient than using the low-level immediate mode and thus not recommended. Also note that this old immediate mode behaviour is just emulated and it does not actually work as it used to work in the older OpenGL implementations. There is an example in the manual page of GL API I linked. I am not sure if this helps with the 65k vertex limit, but I would assume so. I have never used this method myself as it is the least performant way to draw things on screen.

In addition to that, you could always write your own plug-in to use the graphics context by yourself, but that's a lot more work. You are usually better off using Graphics class to draw commands or CommandBuffer.


You must log in to answer this question.

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