简介
在接下来的几章中,我们将设置一个配置为绘制我们第一个三角形的图形管线。图形管线是一系列操作,它将网格的顶点和纹理一直带到渲染目标中的像素。下面显示了一个简化的概述
输入汇编器从您指定的缓冲区收集原始顶点数据,并且还可以使用索引缓冲区来重复某些元素,而无需复制顶点数据本身。
顶点着色器为每个顶点运行,通常应用变换将顶点位置从模型空间转换为屏幕空间。它还将每个顶点的数据传递到管线中。
细分着色器允许您根据某些规则细分几何图形以提高网格质量。这通常用于使附近的砖墙和楼梯等表面看起来不那么平坦。
几何着色器在每个图元(三角形、直线、点)上运行,可以丢弃它或输出比输入更多的图元。这与细分着色器类似,但更加灵活。但是,它在当今的应用程序中使用不多,因为除了英特尔的集成 GPU 外,大多数图形卡的性能都不是很好。
光栅化阶段将图元离散化为片段。这些是它们在帧缓冲上填充的像素元素。落在屏幕外的任何片段都会被丢弃,并且顶点着色器输出的属性会在片段之间进行插值,如图所示。通常,由于深度测试,此处也会丢弃其他图元片段后面的片段。
片段着色器为每个幸存的片段调用,并确定将片段写入哪个(哪些)帧缓冲区,以及使用哪个颜色和深度值。它可以使用来自顶点着色器的插值数据来做到这一点,其中可以包括纹理坐标和用于照明的法线等内容。
颜色混合阶段应用操作来混合映射到帧缓冲区中同一像素的不同片段。片段可以简单地相互覆盖、相加或基于透明度进行混合。
颜色为绿色的阶段称为固定功能阶段。这些阶段允许您使用参数调整其操作,但它们的工作方式是预定义的。
另一方面,颜色为橙色的阶段是可编程
的,这意味着您可以将自己的代码上传到图形卡以精确应用您想要的操作。这使您可以使用片段着色器,例如,实现从纹理和照明到光线追踪器的任何功能。这些程序在许多 GPU 内核上同时运行,以并行处理许多对象,如顶点和片段。
如果您以前使用过 OpenGL 和 Direct3D 等较旧的 API,那么您将习惯于使用诸如 glBlendFunc
和 OMSetBlendState
之类的调用随意更改任何管线设置。Vulkan 中的图形管线几乎完全不可变,因此如果您想更改着色器、绑定不同的帧缓冲区或更改混合功能,则必须从头开始重新创建管线。缺点是您必须创建许多代表您希望在渲染操作中使用的所有不同状态组合的管线。但是,由于您将在管线中执行的所有操作都是预先知道的,因此驱动程序可以更好地对其进行优化。
某些可编程阶段是可选的,具体取决于您打算执行的操作。例如,如果您只是绘制简单的几何图形,则可以禁用细分和几何阶段。如果您只对深度值感兴趣,则可以禁用片段着色器阶段,这对于阴影贴图生成很有用。
在下一章中,我们将首先创建将三角形放到屏幕上所需的两个可编程阶段:顶点着色器和片段着色器。固定功能配置(如混合模式、视口、光栅化)将在下一章中设置。在 Vulkan 中设置图形管线的最后一部分涉及输入和输出帧缓冲区的规范。
创建一个 createGraphicsPipeline
函数,该函数在 initVulkan
中的 createImageViews
之后立即调用。我们将在以下章节中处理此函数。
void initVulkan() {
createInstance();
setupDebugMessenger();
createSurface();
pickPhysicalDevice();
createLogicalDevice();
createSwapChain();
createImageViews();
createGraphicsPipeline();
}
...
void createGraphicsPipeline() {
}
下一章将讨论在屏幕上实际显示内容所需的着色器模块。