I've been learning Metal for iOS / OSX, and I began by following a Ray Wenderlich tutorial. This tutorial works fine but it makes no mention of MTLVertexAttributeDescriptors
.
Now that I'm developing my own app, I'm getting weird glitches and I'm wondering if the fact that I don't use MTLVertexAttributeDescriptors
may be related to the problem.
What difference do they make? I've been able to make a variety of shaders with varying vertex structures and I never even knew about these things.
I know you use them to describe the layout of vertex components for use in a shader. For example a shader might use this structure for vertices, and it would be set up in a vertex descriptor in the function below.
typedef struct
{
float3 position [[attribute(T_VertexAttributePosition)]];
float2 texCoord [[attribute(T_VertexAttributeTexcoord)]];
} Vertex;
class func buildMetalVertexDescriptor() -> MTLVertexDescriptor {
let mtlVertexDescriptor = MTLVertexDescriptor()
mtlVertexDescriptor.attributes[T_VertexAttribute.position.rawValue].format = MTLVertexFormat.float3
mtlVertexDescriptor.attributes[T_VertexAttribute.position.rawValue].offset = 0
mtlVertexDescriptor.attributes[T_VertexAttribute.position.rawValue].bufferIndex = T_BufferIndex.meshPositions.rawValue
mtlVertexDescriptor.attributes[T_VertexAttribute.texcoord.rawValue].format = MTLVertexFormat.float2
mtlVertexDescriptor.attributes[T_VertexAttribute.texcoord.rawValue].offset = 0
mtlVertexDescriptor.attributes[T_VertexAttribute.texcoord.rawValue].bufferIndex = T_BufferIndex.meshGenerics.rawValue
mtlVertexDescriptor.layouts[T_BufferIndex.meshPositions.rawValue].stride = 12
mtlVertexDescriptor.layouts[T_BufferIndex.meshPositions.rawValue].stepRate = 1
mtlVertexDescriptor.layouts[T_BufferIndex.meshPositions.rawValue].stepFunction = MTLVertexStepFunction.perVertex
mtlVertexDescriptor.layouts[T_BufferIndex.meshGenerics.rawValue].stride = 8
mtlVertexDescriptor.layouts[T_BufferIndex.meshGenerics.rawValue].stepRate = 1
mtlVertexDescriptor.layouts[T_BufferIndex.meshGenerics.rawValue].stepFunction = MTLVertexStepFunction.perVertex
return mtlVertexDescriptor
}
But even without the MTLVertexDescriptor
setup, the shader can already access the vertex buffer and the position / texCoord
components of vertices in the array. Just by setting the vertex buffer, the shader has access to all of the components. So what good does the descriptor do?