Convert Mesh.SetVertices() to Mesh.SetVertexBufferParams() and Mesh.SetVertexBufferData()

Viewed 49

I'm trying to improve the performance of some mesh generation, and so I'd like to change from using SetVertices() to the SetVertexBufferParam/Data pattern. This is what I have:

// verts is a NativeArray<float3>
// numVerts is the length of verts
Mesh mesh = new Mesh();

// this works and creates a series of flat faces
mesh.SetVertices(verts);

// this creates a mesh but it's very wrong
mesh.SetVertexBufferParams(numVerts,
  new VertexAttributeDescriptor(VertexAttribute.Position, VertexAttributeFormat.Float32, 3),
  new VertexAttributeDescriptor(VertexAttribute.Normal, VertexAttributeFormat.Float32, 3));
mesh.SetVertexBufferData(verts, 0, 0, numVerts);

// afterwards I set indices, norms, etc.

Desired result vs result using SetVertexBufferData:

Desired result

Result using SetVertexBufferData

What did I do wrong?

1 Answers

See Mesh.SetVertexBufferData and in particular also VertexAttributeDescriptor

Usually you use your own Vertex struct. You are passing a layout

new VertexAttributeDescriptor(VertexAttribute.Position, VertexAttributeFormat.Float32, 3),
new VertexAttributeDescriptor(VertexAttribute.Normal, VertexAttributeFormat.Float32, 3)

which would expect an input struct composed of 6 x Float32 like e.g.

[System.Runtime.InteropServices.StructLayout(System.Runtime.InteropServices.LayoutKind.Sequential)]
public struct YourVertex
{
    public Vector3 position;
    public Vector3 normal;
}

but actually you only provide the float3 data which is only enough for

new VertexAttributeDescriptor(VertexAttribute.Position, VertexAttributeFormat.Float32, 3)

In the native array you basically just get

float, float, float, float, float, float, float, float, float, float, ...

and it is the job of the layout do define how exactly those are supposed to be interpreted. So since you tell the layout to expect a 3 x Float32 position + a 3x Float32 normal it is trying to apply always 3 floats to the position and 3 floats to the normal

=> these 3 floats belonging actually to the next vertex get kinda "lost" / applied incorrectly as normal

Related