Metal by Tutorials qustion

Doctor Caroline:
I read resource of pdf you give me carefully. I do not think I can understand what " [[ attribute(0) ]] " is meaning absolutely. I read your book and code resource in chapter 3 PipleLine again and again. So would u please give me answers?

There are a number of things that all tie together here. You don’t have to use attributes at all.

You can define your vertex function input parameter for the vertex buffer with a struct:

struct VertexIn {
  float4 position;
  float3 normal;
}

vertex float4 vertex_main(VertexIn *buffer [[buffer(0)]],
                          uint id [[vertex_id]]) { 
  VertexIn in = buffer[id];
  ....

You also need to get the id of the specific vertex and extract it out of the buffer.

On the Swift side, you’d have to match the struct exactly. If your data comes in using a float3 for position, then you’d have to change the shader type.

Alternatively, you can set up a vertex descriptor on the Swift side so that you don’t have to worry so much about exact formats of floats.

The vertex descriptor in Chapter 3, is created by Model I/O when it reads in the mesh. You don’t have to know the exact float format of the elements, and indeed you can miss elements altogether by constructing your own vertex descriptor, which you will do in later chapters.

A vertex descriptor contains an array of attributes. You might create your vertex descriptor as Attribute 0 being position of float3, and attribute 1 being normal of float3. Model I/O will then use this vertex descriptor to read the file, and construct a buffer of this format.

In the shader, you match position with attribute 0 and normal with attribute 1 like this:

struct VertexIn {
  float4 position [[attribute(0)]];
  float3 normal [[attribute(1)]];
}

vertex float4 vertex_main(VertexIn in [[stage_in]]) { 
  ...

Notice the parameter for the vertex function when you use this. The attribute is [[stage_in]].

This signals the vertex function to use the attributes set up originally by the vertex descriptor. You don’t have to use a vertex id to get the correct vertex.
Also note that you can use a float4 as input to the shader function, although you used float3 in the vertex descriptor.

Metal is very difficult to learn, mostly because there are a lot of new and complex topics all intertwined. Sometimes it’s best to forge ahead without entirely understanding a process. Just take it on trust. After using it for a while, then return to earlier chapters to try and understand what you had taken on trust earlier.

I’d recommend finishing Chapter 4, where you create a buffer of points early in the chapter, and Chapter 5, where you deal with normals in the vertex descriptor, then return to trying to understand this topic.

2 Likes