I'm trying to render a mesh with an additional attribute present in the vertex data, but I'm noticing that the offset value I've set in the vertex descriptor for this attribute doesn't seem to be respected. It's acting like the offset is zero, thus pulling in vertex values instead of the data I'm looking for.
My vertex data is defined like so:
vertices metadata
0, 1, 0, 1, 1, 0,
0, 1, 0, 0, 4, 0,
In the shader, I pull this in like so:
typedef struct {
float4 data [[attribute(0)]];
float2 index [[attribute(1)]];
} Vertex;
vertex ColorInOut vertexShader(Vertex in [[stage_in]],
constant VertexShaderUniforms & u [[ buffer(2) ]]) {...}
I'm then setting up the vertex descriptor to handle this format:
auto _mtlVertexDescriptor = [[MTLVertexDescriptor alloc] init];
_mtlVertexDescriptor.attributes[0].format = MTLVertexFormatFloat4;
_mtlVertexDescriptor.attributes[0].offset = 0;
_mtlVertexDescriptor.attributes[0].bufferIndex = 0;
_mtlVertexDescriptor.attributes[1].format = MTLVertexFormatFloat2;
_mtlVertexDescriptor.attributes[1].offset = sizeof(vector_float4);
_mtlVertexDescriptor.attributes[1].bufferIndex = 0;
_mtlVertexDescriptor.layouts[0].stepFunction = MTLVertexStepFunctionPerVertex;
_mtlVertexDescriptor.layouts[0].stepRate = 1;
_mtlVertexDescriptor.layouts[0].stride = sizeof(vector_float4) + sizeof(vector_float2);
In the Metal debugger, I'm noticing that instead of the data entries above, I'm seeing the following output in the Geometry viewer:
vertices metadata
0, 1, 0, 1, 0, 1,
0, 1, 0, 0, 0, 1,
As it might be important to this situation, I should point out that I load my models manually as I'm plugging this in as an extra render option to my application, I'm doing this in the following way:
std::vector<float> vertices = {...};
auto allocator = [[MTKMeshBufferAllocator alloc] initWithDevice:device];
auto vertexData = [NSData dataWithBytes: vertices.data() length:vertices.size() * sizeof(float)];
auto vertexBuffer = [allocator newBufferWithData:vertexData type:MDLMeshBufferTypeVertex];
auto mdlVertexDescriptor = MTKModelIOVertexDescriptorFromMetal(vertexDescriptor);
// For this particlular example, `row_size` is 6, corresponding to the number of values in each vertex
auto mdlMesh = [[MDLMesh alloc] initWithVertexBuffer:vertexBuffer vertexCount:vertices.size() / row_size descriptor:mdlVertexDescriptor submeshes:@[]];
mdlMesh.vertexDescriptor = mdlVertexDescriptor;
NSError* error = nil;
auto m = [[MTKMesh alloc] initWithMesh:mdlMesh
device:device
error:&error];
Is there any magic invocation I'm missing to get the offset applying properly?
[edit]
I've verified that the same issue is present in the vertex buffer object itself. I've confirmed that the vertex descriptor being passed into the MTKModelIOVertexDescriptorFromMetal
call is the expected descriptor, and I've also confirmed that the raw data in the NSData object is identical to the std::vector values, so the issue may lie in how I'm interacting with MDLMesh
.