前言
大家好,我是一牛。今天我想和大家分享的是使用Metal 绘制三角形。绘制三角形是图形学的基础,打好基础是我们通向图形学世界关键所在。本文将介绍如何构建一个渲染管线来绘制三角形。
什么是渲染管线
渲染管线(Render Pipeline) 指的是图形渲染的一个整体过程,负责定义从顶点数据到像素输出的完整流程,包括顶点着色,光栅化,片元着色等。它规定了数据如何从输入的顶点、纹理和其他资源流经一系列固定和可编程阶段,最终生成屏幕上的像素。在Metal中 顶点着色和片元着色是可编程阶段。
顶点阶段
struct RasterizerData {
float4 position [[position]];
float4 color;
};
struct Vertex {
float4 position;
float4 color;
};
vertex RasterizerData vertexShader(uint vertexID [[vertex_id]],
constant Vertex *vertices [[buffer(0)]]) {
RasterizerData out;
out.position = vertices[vertexID].position;
out.color = vertices[vertexID].color;
return out;
}
[[vertext_id]] 是Metal的关键字,通过它我们获取到对应的输入的顶点坐标。[[buffer(0)]]表示我们将在插槽0处传入数据,例子中是顶点数组。
在Metal中,顶点着色器需要提供在裁剪空间中的齐次坐标(x, y, z, w),我们需要使用关键字[[position]]来表示,在随后的光栅化阶段通过 x/w, y/w, z/w 得到三维归一化坐标。因为我们绘制的是2D图形, 为了方便,我们可以将输入的顶点的齐次坐标w设为 1,z分量设置为0.
let vertices = [
//左下角
Vertex(position: [-1.0, -1.0, 0.0, 1.0], color: [1.0, 0.0, 0.0, 1.0]),
//正上方
Vertex(position: [ 0.0, 1.0, 0.0, 1.0], color: [1.0, 0.5, 0.0, 1.0]),
//右下角
Vertex(position: [ 1.0, -1.0, 0.0, 1.0], color: [0.0, 1.0, 0.0, 1.0]),
]
对应屏幕的坐标系如下
片元阶段
顶点着色器的输出是光栅化阶段的输入, 光栅化阶段会将顶点坐标映射到屏幕坐标并生成片元。关键字
[[stage_in]]表明片元函数的输入是光栅化的输出,这里我们直接返回输入的颜色值。
fragment float4 fragmentShader(RasterizerData in [[stage_in]]) {
return in.color;
}
创建渲染管线
let library = device.makeDefaultLibrary()
let vertextFunc = library?.makeFunction(name: "vertexShader")
let fragmentFunc = library?.makeFunction(name: "fragmentShader")
let pipelineDescriptor = MTLRenderPipelineDescriptor()
pipelineDescriptor.vertexFunction = vertextFunc
pipelineDescriptor.fragmentFunction = fragmentFunc
pipelineDescriptor.colorAttachments[0].pixelFormat = mtkView.colorPixelFormat;
do {
pipelineState = try device.makeRenderPipelineState(descriptor: pipelineDescriptor)
} catch {
fatalError("fail to create pipelineState")
}
创建好顶点函数和片元函数后,我们需要使用将它们绑定到MTLRenderPipelineDescriptor 并创建渲染管线
编码绘制命令
commanderEncoder?.drawPrimitives(type: .triangle, vertexStart: 0, vertexCount: vertices.count)
总结
通过本文,我们学习了如何使用 Metal 绘制一个简单的三角形。从构建渲染管线到编写顶点和片元着色器,再到将绘制命令编码到命令缓冲区,每一步都为实现图形渲染奠定了基础。其中掌握图形渲染管线是重中之重。
图形学的世界广阔无边,从 Metal 入门绘制三角形开始,一步步深入探索,最终实现更加精美复杂的图形渲染!