Are MTLVertexAttributeDescriptors necessary? Why are they needed?

后端 未结 1 1234
难免孤独
难免孤独 2020-12-31 03:25

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 MTLVertexAttributeDes

相关标签:
1条回答
  • 2020-12-31 04:10

    There are, of course, multiple ways of doing things. The vertex descriptor is only used for one of them.

    For example, a vertex function might be declared like this:

    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
    }
    

    This dictates that the vertex attributes be supplied in separate buffers, each of a specific layout.

    You could also do:

    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
    }
    

    This dictates that the vertex attributes be supplied in a single buffer of structs matching the layout of MyVertexIn.

    Neither of the above require or make use of the vertex descriptor. It's completely irrelevant.

    However, you can also do this:

    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
    }
    

    Note the use of the attribute(n) and stage_in attributes. This does not dictate how the vertex attributes are supplied. Rather, the vertex descriptor describes a mapping from one or more buffers to the vertex attributes. The mapping can also perform conversions and expansions. For example, the shader code above specifies that the position field is a float3 but the buffers may contain (and be described as containing) half3 values (or various other types) and Metal will do the conversion automatically.

    The same shader can be used with different vertex descriptors and, thus, different distribution of vertex attributes across buffers. That provides flexibility for different scenarios, some where the vertex attributes are separated out into different buffers (similar to the first example I gave) and others where they're interleaved in the same buffer (similar to the second example). Etc.

    If you don't need that flexibility and the extra level of abstraction, then you don't need to deal with vertex descriptors. They're there for those who do need them.

    0 讨论(0)
提交回复
热议问题