Metal 加载顶点数量多的图形渲染技巧

Metal 加载顶点有两种方式。
第一种是使用CPU,适合少于4KB顶点数据的情况。
第二种是使用GPU,通过创建MTLBuffer对象把顶点数据存储到顶点缓冲区让GPU直接访问。

苹果官方说明中setVertexBytes(_:length:index:) 方法只能针对小于4KB(即4096字节)的一次性数据。对于大于4KB顶点数据的情况,我们需要创建一个MTLBuffer对象,把顶点数据存储到顶点缓冲区,让GPU可以直接访问该缓存区获取顶点数据。传递到着色函数时需要通过setVertexBuffer: offset: atIndex:函数。

第二种创建MTLBuffer对象在Metal实现特点
Render渲染循环类:大批量顶点数据数据的存储及传递
metal文件:顶点坐标数据需要归一处理。

vertex RasterizerData
vertexShader(uint vertexID [[vertex_id]],
             constant CJLVertex *vertices [[buffer(CJLVertexInputIndexVertices)]],
             constant vector_uint2 *viewportSizePointer [[buffer(CJLVertexInputIndexViewportSize)]])
{
        /*
        处理顶点数据:
           1) 执行坐标系转换,将生成的顶点剪辑空间写入到返回值中.
           2) 将顶点颜色值传递给返回值
        */
       
//    1、定义out
    RasterizerData out;
    
//    2、初始化输出剪辑空间位置,将w改为2.0,实际运行结果比1.0小一倍
    out.clipSpacePosition = vector_float4(0.0, 0.0, 0.0, 1.0);
    
//    3、获取当前顶点坐标的xy,因为是2D图形
    // 索引到我们的数组位置以获得当前顶点
    // 我们的位置是在像素维度中指定的.
    float2 pixelSpacePosition = vertices[vertexID].position.xy;
    
    //将vierportSizePointer 从verctor_uint2 转换为vector_float2 类型
    vector_float2 viewportSize = vector_float2(*viewportSizePointer);
    
//    4、顶点坐标归一化处理
    //每个顶点着色器的输出位置在剪辑空间中(也称为归一化设备坐标空间,NDC),剪辑空间中的(-1,-1)表示视口的左下角,而(1,1)表示视口的右上角.
    //计算和写入 XY值到我们的剪辑空间的位置.为了从像素空间中的位置转换到剪辑空间的位置,我们将像素坐标除以视口的大小的一半.
    //如果是1倍,除以1.0,如果是3倍
    //可以使用一行代码同时分割两个通道。执行除法,然后将结果放入输出位置的x和y通道中
    out.clipSpacePosition.xy = pixelSpacePosition / (viewportSize / 2.0);
    
//    5、颜色原样输出
    //把我们输入的颜色直接赋值给输出颜色. 这个值将于构成三角形的顶点的其他颜色值插值,从而为我们片段着色器中的每个片段生成颜色值.
    out.color = vertices[vertexID].color;
    
    
    //完成! 将结构体传递到管道中下一个阶段:
    return out;
    
}

你可能感兴趣的:(Metal 加载顶点数量多的图形渲染技巧)