上篇博客, 渲染了一个三角形. 但只有一个颜色太单调了. 我们来给他上点更丰富的颜色.

定义数据结构

我们来定义一个数据结构 Vertex, 用于向shader传递顶点数据.

1
2
3
4
struct Vertex {
    var position: vector_float4
    var color: vector_float4
}

Vertex的数据结构中包含了顶点的位置和对应的颜色.

生成顶点数据

我们需要改写vertexData的数据类型为 Vertex数组, 并且为其赋值.

1
2
3
vertexData = [Vertex(position: [   0,  0.7, 0, 1] , color: [1, 0, 0, 1]),
              Vertex(position: [-0.7, -0.7, 0, 1] , color: [0, 1, 0, 1]),
              Vertex(position: [ 0.7, -0.7, 0, 1] , color: [0, 0, 1, 1])]

同样在计算vertexData占用内存大小的时候, 注意需要计算Vertex的大小.

改变shader

shader中我们需要改变Vertex的定义, 增加一个color.

1
2
3
4
struct Vertex {
    float4 position [[position]];
    float4 color;
};

fragment function 我们需要返回Vertex对应的color.

1
2
3
fragment float4 fragment_func(Vertex vert [[stage_in]]) {
    return vert.color;
}

看看结果吧!

我们不需要再改变什么就能看到结果了.

/upload/2018-07/LearnMetal-04-A-Colored-Triangle.png

一点发现

我看metalkit.org的教程, 上面提到传递数据给shader的时候, 定义一个Vertex. 如果我们不定义又会怎样呢? 结果是没有区别.

1
2
3
vertexData = [   0,  0.7, 0, 1,  1, 0, 0, 1,
              -0.7, -0.7, 0, 1,  0, 1, 0, 1,
               0.7, -0.7, 0, 1,  0, 0, 1, 1]

vertexData依然保持Float类型, 依然是可以正确渲染的.

希望这点发现能帮助你理解顶点数据传输的本质.