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:
What did I do wrong?
CodePudding user response:
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 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, ...
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