Do I need MTLVertexAttributeDescriptors? What are they needed for?

I study Metal for iOS / OSX, and I started with the Ray Wenderlich tutorial ( https://www.raywenderlich.com/146414/metal-tutorial-swift-3-part-1-getting-started ). This tutorial works fine, but it does not mention MTLVertexAttributeDescriptors.

Now, when I develop my own application, I get weird crashes, and I am wondering if this could be related to the fact that I am not using MTLVertexAttributeDescriptors.

Who cares? I was able to make various shaders with different vertex structures, and I did not even know about these things.

I know that you use them to describe the layout of vertex components for use in a shader. For example, a shader can use this structure for vertices, and it will be set in the 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 installing MTLVertexDescriptor, the shader can already access the vertex buffer and the position / texCoord components of the vertices in the array. By simply setting the vertex buffer, the shader has access to all components. So what does a descriptor do well?

+4
source share
1 answer

There are, of course, several ways to do something. The vertex descriptor is used only for one of them.

For example, a vertex function can be declared as follows:

vertex MyVertexOut vertex_func(device const float3 *positions [[buffer(0)]],
                               device const float2 *texCoords [[buffer(1)]],
                               uint vid [[vertex_id]])
{
    // use positions[vid] and texCoords[vid] to fill in and return a MyVertexOut structure
}

, , .

:

struct MyVertexIn
{
    float3 position;
    float2 texCoord;
};
vertex MyVertexOut vertex_func(device const MyVertexIn *vertexes [[buffer(0)]],
                               uint vid [[vertex_id]])
{
    // use vertexes[vid].position and vertexes[vid].texCoord to fill in and return a MyVertexOut structure
}

, , MyVertexIn.

. .

:

struct MyVertexIn
{
    float3 position [[attribute(0)]];
    float2 texCoord [[attribute(1)]];
};
vertex MyVertexOut vertex_func(MyVertexIn vertex [[stage_in]])
{
    // use vertex.position and vertex.texCoord to fill in and return a MyVertexOut structure
}

attribute(n) stage_in. , . , . . , , position float3, ( ) half3 ( ), Metal .

, , . , , ( , ), , ( ). Etc.

, . , .

+4

Source: https://habr.com/ru/post/1688483/


All Articles