区块链技术博客
www.b2bchain.cn

使用渲染管道渲染图元求职学习资料

本文介绍了使用渲染管道渲染图元求职学习资料,有助于帮助完成毕业设计以及求职,是一篇很好的资料。

对技术面试,学习经验等有一些体会,在此分享。

Using a Render Pipeline to Render Primitives | Apple Developer Documentation

渲染一个简单的2D三角形。

绘制一个彩色渐变三角形。本文除了如何实现该示例,还详细介绍了渲染管线中的各个步骤及其原理。

翻译术语表

概述

在《Using Metal to Draw a View’s Contents》中,学习了如何设置一个MTKView对象,并通过渲染改变视图的内容。那个示例只是简单地将视图的内容擦拭成背景色。在这个示例中向你展示了如何配置渲染管线,并将其作为渲染通道的一部分,在视图绘制一个简单的2D彩色三角形。该示例为每个顶点提供了一个位置和颜色,渲染管线使用这些数据来渲染三角形,并在三角形顶点颜色值之间插值形成渐变色。

使用渲染管道渲染图元

Xcode项目包含了在macOS、iOS和tvOS上运行示例的代码。

理解Metal渲染管线

渲染管线(render pipeline)处理绘图命令,并将数据写入渲染通道的目标(target)。渲染管线有多个阶段,有些阶段使用着色器编程,有些阶段具有固定或可配置的行为。本示例主要介绍管线的三个主要阶段:顶点阶段、光栅化阶段和片元阶段。顶点阶段和片元阶段是可编程的,所以你可以用Metal着色器语言(MSL)为它们编写函数。光栅化阶段不可自定义。

图1 Metal图像渲染管线的主要阶段

使用渲染管道渲染图元

渲染从一个渲染命令开始,其中包含了顶点数量和要渲染的图元类型。如下是这个示例中的绘图命令:

// Draw the triangle. [renderEncoder drawPrimitives:MTLPrimitiveTypeTriangle                   vertexStart:0                   vertexCount:3];

顶点阶段为每个顶点提供数据,当处理了足够多的顶点后,渲染管线会对图元进行光栅化,确定渲染目标中哪些像素位于图元的边界内。片元阶段决定要写入渲染目标的像素值。

在本示例剩余部分,你将看到如何编写顶点和片元函数,如何创建渲染管线状态对象,以及最后如何编码使用该管线的绘制命令。

决定自定义渲染管线如何处理数据

顶点函数为单个顶点生成数据,片元函数为单个片元(译者注:像素)生成数据,但如何工作是你决定的。在配置渲染管线的各个阶段都要一个目标,也就是说你要知道让管线生成什么,以及它如何生成这些结果。

决定哪些数据要传入渲染管线,哪些数据要传给管线后期阶段。通常有三个地方会这样做:

  • 管线的输入,由你的应用程序提供,并传递给顶点阶段。
  • 顶点阶段的输出,它被传递到光栅化阶段。
  • 片元阶段的输入,由app提供或由光栅化阶段生成(译者注:包含了传递到光栅化阶段的顶点函数的输出)。

这个示例中,管线的输入数据是顶点的位置以及颜色。为了演示通常在顶点函数中执行的转换,输入坐标是在自定义坐标空间中定义的,以视图中心的像素为单位进行测量计算(measured)。这些坐标需要被转换到Metal坐标系中。

声明一个AAPLVertex结构体,使用SIMD向量类型来保存顶点位置和颜色信息。为了共享该结构体(确保在内存中是唯一的定义),在一个通用头文件中声明该结构体,并在Metal着色器和应用程序中导入它。

typedef struct {     vector_float2 position;     vector_float4 color; } AAPLVertex;

SIMD类型在Metal着色器语言中很常见,你也应在app使用simd库表达数据结构。SIMD类型包含一个特定数据类型的多个通道,因此把顶点位置声明一个vector_float2意味着它包含两个32为浮点值(x、y坐标)。颜色使用vector_float4存储,因此它们有四个通道——红、绿、蓝和alpha。

在app中,输入数据使用一个常量数组指定。

static const AAPLVertex triangleVertices[] = {     // 2D positions,    RGBA colors     { {  250,  -250 }, { 1, 0, 0, 1 } },     { { -250,  -250 }, { 0, 1, 0, 1 } },     { {    0,   250 }, { 0, 0, 1, 1 } }, };

顶点阶段为一个顶点生成数据,所以它需要提供一个颜色和一个变换过的顶点位置。声明一个RasterizerData结构体,包含一个顶点位置和一个颜色值,同样使用SIMD类型。

struct RasterizerData {     // The [[position]] attribute of this member indicates that this value     // is the clip space position of the vertex when this structure is     // returned from the vertex function.     float4 position [[position]];      // Since this member does not have a special attribute, the rasterizer     // interpolates its value with the values of the other triangle vertices     // and then passes the interpolated value to the fragment shader for each     // fragment in the triangle.     float4 color; };

输出顶点位置(在下面详细描述),必须定义为一个vector_float4。颜色是按照输入数据结构体中的颜色来声明的。

你需要告诉Metal光栅化数据中的哪个字段提供了顶点位置信息,因为Metal并没有为结构体中的字段执行任何特定的命名约定。用[[position]]属性限定符来修饰position字段,以声明这个字段持有输入的顶点位置。

片元函数只是把光栅化阶段的数据传递给后面的阶段,所以它不需要任何额外的参数。

声明顶点函数

声明顶点函数,包括它的输入参数和输出的数据。就像计算型函数用kernel关键字声明的一样,用vertex关键字声明顶点函数。

vertex RasterizerData vertexShader(uint vertexID [[vertex_id]],              constant AAPLVertex *vertices [[buffer(AAPLVertexInputIndexVertices)]],              constant vector_uint2 *viewportSizePointer [[buffer(AAPLVertexInputIndexViewportSize)]])

第一个参数,vertexID,使用[[vertex_id]]属性限定符,这是另一个Metal关键字。当你执行渲染命令时,GPU会多次调用你的顶点函数,为每个顶点生成一个唯一值。

第二个参数,vertices,是一个包含顶点数据的数组,使用之前定义的AAPLVertex结构体。

为了将位置转换为Metal坐标,函数需要绘制三角形的视口大小(以像素为单位),存储在viewportSizePointer参数中。

第二和第三个参数使用[[buffer(n)]]属性限定符修饰。默认情况下,Metal会在参数表中自动为每个参数分配槽位。当你把[[buffer(n)]]限定符添加到一个缓冲区参数时,需要明确告诉Metal要使用哪个槽位。显式(explicitly)声明槽位可以让你更容易修改你的着色器,而不需要同时改变你的app代码。所以这里在共享头文件中塞声明了两个槽位索引的常量。

该函数的输出是一个RasterizerData结构体。

编写顶点函数

你的顶点函数必须生成输出结构体的两个字段。使用vertexID参数,索引到vertices数组,并读取顶点的输入数据。同时,检索视口尺寸。

float2 pixelSpacePosition = vertices[vertexID].position.xy;  // Get the viewport size and cast to float. vector_float2 viewportSize = vector_float2(*viewportSizePointer);

顶点函数必须提供裁剪空间坐标(clip-space coordinates)的顶点位置数据,这些数据是使用四维齐次向量(x,y,z,w)指定的三维点。光栅化阶段输出顶点位置,并将x、y和z坐标除以w,以生成一个归一化设备坐标(normalized device coordinates)的三维点。归一化设备坐标与视口大小无关。

图2 归一化/标准设备坐标系统

使用渲染管道渲染图元

归一化设备坐标使用左手坐标系,并映射到视口中的位置。图元被裁剪到此坐标系中的一个框中,然后进行光栅化。裁剪框的左下角位于(x,y)坐标的(-1.0,-1.0)处,左上角位于处(1.0,1.0)。正z值指向原理摄像机(进入屏幕)的方向。坐标的可见部分在0.0(近裁剪平面)和1.0(远裁剪平面)之间。

Using a Render Pipeline to Render Primitives | Apple Developer Documentation

渲染一个简单的2D三角形。

绘制一个彩色渐变三角形。本文除了如何实现该示例,还详细介绍了渲染管线中的各个步骤及其原理。

翻译术语表

概述

在《Using Metal to Draw a View’s Contents》中,学习了如何设置一个MTKView对象,并通过渲染改变视图的内容。那个示例只是简单地将视图的内容擦拭成背景色。在这个示例中向你展示了如何配置渲染管线,并将其作为渲染通道的一部分,在视图绘制一个简单的2D彩色三角形。该示例为每个顶点提供了一个位置和颜色,渲染管线使用这些数据来渲染三角形,并在三角形顶点颜色值之间插值形成渐变色。

使用渲染管道渲染图元

Xcode项目包含了在macOS、iOS和tvOS上运行示例的代码。

理解Metal渲染管线

渲染管线(render pipeline)处理绘图命令,并将数据写入渲染通道的目标(target)。渲染管线有多个阶段,有些阶段使用着色器编程,有些阶段具有固定或可配置的行为。本示例主要介绍管线的三个主要阶段:顶点阶段、光栅化阶段和片元阶段。顶点阶段和片元阶段是可编程的,所以你可以用Metal着色器语言(MSL)为它们编写函数。光栅化阶段不可自定义。

图1 Metal图像渲染管线的主要阶段

使用渲染管道渲染图元

渲染从一个渲染命令开始,其中包含了顶点数量和要渲染的图元类型。如下是这个示例中的绘图命令:

// Draw the triangle. [renderEncoder drawPrimitives:MTLPrimitiveTypeTriangle                   vertexStart:0                   vertexCount:3];

顶点阶段为每个顶点提供数据,当处理了足够多的顶点后,渲染管线会对图元进行光栅化,确定渲染目标中哪些像素位于图元的边界内。片元阶段决定要写入渲染目标的像素值。

在本示例剩余部分,你将看到如何编写顶点和片元函数,如何创建渲染管线状态对象,以及最后如何编码使用该管线的绘制命令。

决定自定义渲染管线如何处理数据

顶点函数为单个顶点生成数据,片元函数为单个片元(译者注:像素)生成数据,但如何工作是你决定的。在配置渲染管线的各个阶段都要一个目标,也就是说你要知道让管线生成什么,以及它如何生成这些结果。

决定哪些数据要传入渲染管线,哪些数据要传给管线后期阶段。通常有三个地方会这样做:

  • 管线的输入,由你的应用程序提供,并传递给顶点阶段。
  • 顶点阶段的输出,它被传递到光栅化阶段。
  • 片元阶段的输入,由app提供或由光栅化阶段生成(译者注:包含了传递到光栅化阶段的顶点函数的输出)。

这个示例中,管线的输入数据是顶点的位置以及颜色。为了演示通常在顶点函数中执行的转换,输入坐标是在自定义坐标空间中定义的,以视图中心的像素为单位进行测量计算(measured)。这些坐标需要被转换到Metal坐标系中。

声明一个AAPLVertex结构体,使用SIMD向量类型来保存顶点位置和颜色信息。为了共享该结构体(确保在内存中是唯一的定义),在一个通用头文件中声明该结构体,并在Metal着色器和应用程序中导入它。

typedef struct {     vector_float2 position;     vector_float4 color; } AAPLVertex;

SIMD类型在Metal着色器语言中很常见,你也应在app使用simd库表达数据结构。SIMD类型包含一个特定数据类型的多个通道,因此把顶点位置声明一个vector_float2意味着它包含两个32为浮点值(x、y坐标)。颜色使用vector_float4存储,因此它们有四个通道——红、绿、蓝和alpha。

在app中,输入数据使用一个常量数组指定。

static const AAPLVertex triangleVertices[] = {     // 2D positions,    RGBA colors     { {  250,  -250 }, { 1, 0, 0, 1 } },     { { -250,  -250 }, { 0, 1, 0, 1 } },     { {    0,   250 }, { 0, 0, 1, 1 } }, };

顶点阶段为一个顶点生成数据,所以它需要提供一个颜色和一个变换过的顶点位置。声明一个RasterizerData结构体,包含一个顶点位置和一个颜色值,同样使用SIMD类型。

struct RasterizerData {     // The [[position]] attribute of this member indicates that this value     // is the clip space position of the vertex when this structure is     // returned from the vertex function.     float4 position [[position]];      // Since this member does not have a special attribute, the rasterizer     // interpolates its value with the values of the other triangle vertices     // and then passes the interpolated value to the fragment shader for each     // fragment in the triangle.     float4 color; };

输出顶点位置(在下面详细描述),必须定义为一个vector_float4。颜色是按照输入数据结构体中的颜色来声明的。

你需要告诉Metal光栅化数据中的哪个字段提供了顶点位置信息,因为Metal并没有为结构体中的字段执行任何特定的命名约定。用[[position]]属性限定符来修饰position字段,以声明这个字段持有输入的顶点位置。

片元函数只是把光栅化阶段的数据传递给后面的阶段,所以它不需要任何额外的参数。

声明顶点函数

声明顶点函数,包括它的输入参数和输出的数据。就像计算型函数用kernel关键字声明的一样,用vertex关键字声明顶点函数。

vertex RasterizerData vertexShader(uint vertexID [[vertex_id]],              constant AAPLVertex *vertices [[buffer(AAPLVertexInputIndexVertices)]],              constant vector_uint2 *viewportSizePointer [[buffer(AAPLVertexInputIndexViewportSize)]])

第一个参数,vertexID,使用[[vertex_id]]属性限定符,这是另一个Metal关键字。当你执行渲染命令时,GPU会多次调用你的顶点函数,为每个顶点生成一个唯一值。

第二个参数,vertices,是一个包含顶点数据的数组,使用之前定义的AAPLVertex结构体。

为了将位置转换为Metal坐标,函数需要绘制三角形的视口大小(以像素为单位),存储在viewportSizePointer参数中。

第二和第三个参数使用[[buffer(n)]]属性限定符修饰。默认情况下,Metal会在参数表中自动为每个参数分配槽位。当你把[[buffer(n)]]限定符添加到一个缓冲区参数时,需要明确告诉Metal要使用哪个槽位。显式(explicitly)声明槽位可以让你更容易修改你的着色器,而不需要同时改变你的app代码。所以这里在共享头文件中塞声明了两个槽位索引的常量。

该函数的输出是一个RasterizerData结构体。

编写顶点函数

你的顶点函数必须生成输出结构体的两个字段。使用vertexID参数,索引到vertices数组,并读取顶点的输入数据。同时,检索视口尺寸。

float2 pixelSpacePosition = vertices[vertexID].position.xy;  // Get the viewport size and cast to float. vector_float2 viewportSize = vector_float2(*viewportSizePointer);

顶点函数必须提供裁剪空间坐标(clip-space coordinates)的顶点位置数据,这些数据是使用四维齐次向量(x,y,z,w)指定的三维点。光栅化阶段输出顶点位置,并将x、y和z坐标除以w,以生成一个归一化设备坐标(normalized device coordinates)的三维点。归一化设备坐标与视口大小无关。

图2 归一化/标准设备坐标系统

使用渲染管道渲染图元

归一化设备坐标使用左手坐标系,并映射到视口中的位置。图元被裁剪到此坐标系中的一个框中,然后进行光栅化。裁剪框的左下角位于(x,y)坐标的(-1.0,-1.0)处,左上角位于处(1.0,1.0)。正z值指向原理摄像机(进入屏幕)的方向。坐标的可见部分在0.0(近裁剪平面)和1.0(远裁剪平面)之间。

Using a Render Pipeline to Render Primitives | Apple Developer Documentation

渲染一个简单的2D三角形。

绘制一个彩色渐变三角形。本文除了如何实现该示例,还详细介绍了渲染管线中的各个步骤及其原理。

翻译术语表

概述

在《Using Metal to Draw a View’s Contents》中,学习了如何设置一个MTKView对象,并通过渲染改变视图的内容。那个示例只是简单地将视图的内容擦拭成背景色。在这个示例中向你展示了如何配置渲染管线,并将其作为渲染通道的一部分,在视图绘制一个简单的2D彩色三角形。该示例为每个顶点提供了一个位置和颜色,渲染管线使用这些数据来渲染三角形,并在三角形顶点颜色值之间插值形成渐变色。

使用渲染管道渲染图元

Xcode项目包含了在macOS、iOS和tvOS上运行示例的代码。

理解Metal渲染管线

渲染管线(render pipeline)处理绘图命令,并将数据写入渲染通道的目标(target)。渲染管线有多个阶段,有些阶段使用着色器编程,有些阶段具有固定或可配置的行为。本示例主要介绍管线的三个主要阶段:顶点阶段、光栅化阶段和片元阶段。顶点阶段和片元阶段是可编程的,所以你可以用Metal着色器语言(MSL)为它们编写函数。光栅化阶段不可自定义。

图1 Metal图像渲染管线的主要阶段

使用渲染管道渲染图元

渲染从一个渲染命令开始,其中包含了顶点数量和要渲染的图元类型。如下是这个示例中的绘图命令:

// Draw the triangle. [renderEncoder drawPrimitives:MTLPrimitiveTypeTriangle                   vertexStart:0                   vertexCount:3];

顶点阶段为每个顶点提供数据,当处理了足够多的顶点后,渲染管线会对图元进行光栅化,确定渲染目标中哪些像素位于图元的边界内。片元阶段决定要写入渲染目标的像素值。

在本示例剩余部分,你将看到如何编写顶点和片元函数,如何创建渲染管线状态对象,以及最后如何编码使用该管线的绘制命令。

决定自定义渲染管线如何处理数据

顶点函数为单个顶点生成数据,片元函数为单个片元(译者注:像素)生成数据,但如何工作是你决定的。在配置渲染管线的各个阶段都要一个目标,也就是说你要知道让管线生成什么,以及它如何生成这些结果。

决定哪些数据要传入渲染管线,哪些数据要传给管线后期阶段。通常有三个地方会这样做:

  • 管线的输入,由你的应用程序提供,并传递给顶点阶段。
  • 顶点阶段的输出,它被传递到光栅化阶段。
  • 片元阶段的输入,由app提供或由光栅化阶段生成(译者注:包含了传递到光栅化阶段的顶点函数的输出)。

这个示例中,管线的输入数据是顶点的位置以及颜色。为了演示通常在顶点函数中执行的转换,输入坐标是在自定义坐标空间中定义的,以视图中心的像素为单位进行测量计算(measured)。这些坐标需要被转换到Metal坐标系中。

声明一个AAPLVertex结构体,使用SIMD向量类型来保存顶点位置和颜色信息。为了共享该结构体(确保在内存中是唯一的定义),在一个通用头文件中声明该结构体,并在Metal着色器和应用程序中导入它。

typedef struct {     vector_float2 position;     vector_float4 color; } AAPLVertex;

SIMD类型在Metal着色器语言中很常见,你也应在app使用simd库表达数据结构。SIMD类型包含一个特定数据类型的多个通道,因此把顶点位置声明一个vector_float2意味着它包含两个32为浮点值(x、y坐标)。颜色使用vector_float4存储,因此它们有四个通道——红、绿、蓝和alpha。

在app中,输入数据使用一个常量数组指定。

static const AAPLVertex triangleVertices[] = {     // 2D positions,    RGBA colors     { {  250,  -250 }, { 1, 0, 0, 1 } },     { { -250,  -250 }, { 0, 1, 0, 1 } },     { {    0,   250 }, { 0, 0, 1, 1 } }, };

顶点阶段为一个顶点生成数据,所以它需要提供一个颜色和一个变换过的顶点位置。声明一个RasterizerData结构体,包含一个顶点位置和一个颜色值,同样使用SIMD类型。

struct RasterizerData {     // The [[position]] attribute of this member indicates that this value     // is the clip space position of the vertex when this structure is     // returned from the vertex function.     float4 position [[position]];      // Since this member does not have a special attribute, the rasterizer     // interpolates its value with the values of the other triangle vertices     // and then passes the interpolated value to the fragment shader for each     // fragment in the triangle.     float4 color; };

输出顶点位置(在下面详细描述),必须定义为一个vector_float4。颜色是按照输入数据结构体中的颜色来声明的。

你需要告诉Metal光栅化数据中的哪个字段提供了顶点位置信息,因为Metal并没有为结构体中的字段执行任何特定的命名约定。用[[position]]属性限定符来修饰position字段,以声明这个字段持有输入的顶点位置。

片元函数只是把光栅化阶段的数据传递给后面的阶段,所以它不需要任何额外的参数。

声明顶点函数

声明顶点函数,包括它的输入参数和输出的数据。就像计算型函数用kernel关键字声明的一样,用vertex关键字声明顶点函数。

vertex RasterizerData vertexShader(uint vertexID [[vertex_id]],              constant AAPLVertex *vertices [[buffer(AAPLVertexInputIndexVertices)]],              constant vector_uint2 *viewportSizePointer [[buffer(AAPLVertexInputIndexViewportSize)]])

第一个参数,vertexID,使用[[vertex_id]]属性限定符,这是另一个Metal关键字。当你执行渲染命令时,GPU会多次调用你的顶点函数,为每个顶点生成一个唯一值。

第二个参数,vertices,是一个包含顶点数据的数组,使用之前定义的AAPLVertex结构体。

为了将位置转换为Metal坐标,函数需要绘制三角形的视口大小(以像素为单位),存储在viewportSizePointer参数中。

第二和第三个参数使用[[buffer(n)]]属性限定符修饰。默认情况下,Metal会在参数表中自动为每个参数分配槽位。当你把[[buffer(n)]]限定符添加到一个缓冲区参数时,需要明确告诉Metal要使用哪个槽位。显式(explicitly)声明槽位可以让你更容易修改你的着色器,而不需要同时改变你的app代码。所以这里在共享头文件中塞声明了两个槽位索引的常量。

该函数的输出是一个RasterizerData结构体。

编写顶点函数

你的顶点函数必须生成输出结构体的两个字段。使用vertexID参数,索引到vertices数组,并读取顶点的输入数据。同时,检索视口尺寸。

float2 pixelSpacePosition = vertices[vertexID].position.xy;  // Get the viewport size and cast to float. vector_float2 viewportSize = vector_float2(*viewportSizePointer);

顶点函数必须提供裁剪空间坐标(clip-space coordinates)的顶点位置数据,这些数据是使用四维齐次向量(x,y,z,w)指定的三维点。光栅化阶段输出顶点位置,并将x、y和z坐标除以w,以生成一个归一化设备坐标(normalized device coordinates)的三维点。归一化设备坐标与视口大小无关。

图2 归一化/标准设备坐标系统

使用渲染管道渲染图元

归一化设备坐标使用左手坐标系,并映射到视口中的位置。图元被裁剪到此坐标系中的一个框中,然后进行光栅化。裁剪框的左下角位于(x,y)坐标的(-1.0,-1.0)处,左上角位于处(1.0,1.0)。正z值指向原理摄像机(进入屏幕)的方向。坐标的可见部分在0.0(近裁剪平面)和1.0(远裁剪平面)之间。

部分转自互联网,侵权删除联系

赞(0) 打赏
部分文章转自网络,侵权联系删除b2bchain区块链学习技术社区 » 使用渲染管道渲染图元求职学习资料
分享到: 更多 (0)

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址

b2b链

联系我们联系我们