第七章 图形管线
在本章你将学到
图形管线是什么样子的
如何创建图形管线对象
如何使用Vulkan绘制图元
或许Vulkan最常被当作图形管线API来使用。图形是Vulkan和驱动最基础的功能,是任何视觉效果程序的核心。Vulkan中图形处理可以被看作是管线,管线接受多个贯穿多个阶段图形命令,并在显示器上产生图像。本章将覆盖Vulkan中图形管线的基础并介绍第一个管线的例子。
7.1 逻辑图形管线
Vulkan中图形管线可被看作为一条生产线,命令进入管线的前端,在多个阶段中被处理。每一个阶段执行一种转变,接受命令和它们关联的数据并把它们转化为其他的东西。在管线的末端,命令经过转换变位多彩的像素组成了最终输出的图片。
图形管线的很多部分是可选的,可以被禁用,甚至不被Vulkan实现所支持。管线中只有一个部分必须要在应用程序中开启的 顶点着色器。完整的Vulkan图形管线在Figure 7.1中展示了。然而,不要惊慌,我们在本章中慢慢的介绍每一个阶段,在本书的后续部分再深入的挖掘更多细节。
Figure 7.1: The Full Vulkan Graphics Pipeline
下面是管线的每一个管线的简单介绍和它所做的工作
• 绘制:这是命令进入Vulkan图形管线的地方。通常,Vulkan设备里一个很小的处理器或者专用的硬件对命令缓冲区中的命令做解释,并直接和硬件交互来完成工作
• 输入组装:这个阶段读取索引缓冲区和顶点缓冲区,它俩包含了组成你想要绘制的图形的顶点信息。
• 顶点着色器:这是顶点着色器执行的地方。它接受作为输入的属性顶点,并为下一级准备变换和处理的顶点数据。
• 细分控制着色器:这个可编程的着色阶段负责生产细分因子,和被固定细分管线引擎使用的其他per-patch数据。
• 细分图元生成:在Figure 7.1中没有展示,这个固定功能管线使用在锌粉控制着色器产生的细分因子来吧 patch图元分解成许多更小的,简单的图元以供细分求值着色器使用。
• 细分其中着色器:这个着色器阶段在细分图元生成器产生的每一个顶点上工作。它和顶点着色器的操作类似--除了顶点来自生成的而非内存。
• 几何着色器:这个着色阶段在所有的图元上运行。图元可能是:点,直线或者三角形,或它们的变种(在周围有附件顶点)。这个阶段也有改变图元类型的能力。
• 图元组装:这个阶段把顶点、细分或几何阶段的顶点分组,组成图元以供光栅化。它也剔除或剪裁图元并把图元变形到合适的视口。
• 裁剪和提出:这个固定功能阶段决定了图元的那一部分可能组成输出图像的一部分并抛弃那些不组成图像的部分,把可见的图元发送给光栅器。
• 光栅器:光栅器是Vulkan所有的图形的基础核心。光栅器接受被组装的图元(仍然用一系列顶点表示),并把它们变成单独的片元,片元将变成组装图像的像素。
• 片元操作:在计算之前一旦片元的位置被知晓,就可以在它上面进行好几个操作。这些操作包括深度和stencil测试(当开启了这两个测试时)。
• 片元组装:在图中并没有展示,片元组装接受光栅器的输出的逐片元的数据,形成一组,向片元着色阶段传递。
• 片元着色器:这个阶段在管线的最后运行,负责计算最终将送往最后固定功能处理阶段的数据。
• 后片元操作:在一些环境中,片元着色器将修改进入片元操作之前的数据。这些情况下,这些操作转移到后片元阶段并在此执行。
• 颜色混合:颜色操作接收片元着色器和后片元操作的结果,并把它们更新到framebuffer。颜色操作包括混合与逻辑操作。
如你所知, 在图形管线中有很多关联的阶段。不像第六章“着色器与管线”所介绍的计算管线,图形管线不仅包含很大一部分固定管线的配置,也包括最到五个着色器阶段。更有,取决于Vulkan实现,一些逻辑上的固定功能阶段实际上被驱动生成的着色器代码所示现。
在Vulkan中把图形管线当作一个对象的目的是给Vulkan实现提供尽量多的信息把固定管线的部分转移到可编程管线着色器核心。如果在同一个对象中这些信息无法提供,就表示一个Vulkan实现也许需要根据可配置状态重新编译着色器。包含在图形管线中的状态的集合已经被仔细的选择出来防止这样的状况,让状态的切换尽量的快。
Vulkan中绘制的基础单元是顶点。顶点可以组成图元并被Vulkan管线处理。Vulkan中最简单的绘制命令是vkCmdDraw(),原型如下:
void vkCmdDraw (
VkCommandBuffer commandBuffer,
uint32_t vertexCount,
uint32_t instanceCount,
uint32_t firstVertex,
uint32_t firstInstance);
就像其他的Vulkan命令,vkCmdDraw()在即将被设备执行的命令缓冲区后面追加一个命令。这个被追加的命令缓冲区通过commandBuffer指定。附加到管线的顶点的数量通过vertexCount指定。如果你想要一遍又一遍的重复绘制一个集合的顶点,只有一些参数稍稍不同,你可通过instanceCount指定实例的个数。这就是几何体实例化,我们在本章后面讲解。现在,我们把它设置为1即可。也可以从非0的顶点或者实例开始绘制。要想这样,需要使用firstVertex 和firstInstance。同样,在后面讲解。现在,把这两个参数都设置为0.
在绘制任何东西之前,你必须要把一个管线绑定到命令缓冲区,在此之前,你需要创建管线。如果没有绑定管线就试图绘制,会产生未知的后果(通常是糟糕的后果)。
当你调用vkCmdDraw()时,vertexCount数量的顶点被产生并送入当前的Vulkan绘制管线。对于每一个顶点,在顶点着色器之前都执行输入组装。Declaring inputs beyond what is provided for you by Vulkan is optional, but having a vertex
shader is not.故,最简单的图形管线只有顶点着色器即可。