介绍

之前我们使用顶点颜色来为几何图元进行着色,这样可以产生的效果相当有限。接下来我们将介绍使用纹理图像来为几何图元着色。在之后加载绘制简单的三维模型时,我们也会用纹理图像来对它进行着色。

在我们的程序中使用纹理,需要采取下面的步骤:

  • 创建设备内存(显存)支持的图像对象

  • 加载图像文件的像素数据

  • 创建图像采样器

  • 使用图像采样器描述符采样纹理数据

之前,我们对图像对象已经有所熟悉,我们的渲染操作是在我们获取的交换链图像上进行的,但我们还没有自己创建过图像对象。现在,我们将开始自己创建一个图像对象,这一过程有点类似顶点缓冲对象的创建。我们首先会创建一个暂存资源,然后使用像素数据填充它,接着将像素数据从暂存资源复制到我们用来渲染的图像对象。实际上也可以直接创建暂存图像来用于渲染,Vulkan允许我们直接从VkBuffer中复制像素数据到图像对象,并且在一些硬件平台这样做效率确实要高很多。我们首先创建缓冲然后填充像素数据,接着创建一个图像对象,将缓冲中的数据复制到图像对象。创建图像对象和创建缓冲的方式区别不大,需要我们查询内存需求,分配并绑定设备内存。

但创建图像对象还是有一些地方需要我们注意。图像的布局会影响它的像素数据在内存中的组织方式。一般而言,对于现在的硬件设备,直接将像素数据按行进行存储并不能得到最佳的性能表现。不同的图像布局对图像操作也有一定的影响。在之前的章节,我们已经了解了一些图像布局:

  • VK_IMAGE_LAYOUT_PRESENT_SRC_KHR:适合呈现操作

  • VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL:适合作为颜色附着,在片段着色器中写入颜色数据。

  • VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL:适合作为传输操作的数据来源,比如vkCmdCopyImageToBuffer

  • VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL:适合作为传输操作的目的位置,比如vkCmdCopyBufferToImage

  • VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL:适合在着色器中进行采样操作

最常用的变换图像布局的方式是使用管线屏障(pipeline barrier)。管线屏障(pipeline barrier)主要被用来同步资源访问,比如保证图像在被读取之前数据被写入。它也可以被用来变换图像布局。在本章节,我们使用它进行图像布局变换。如果队列的所有模式为VK_SHARING_MODE_EXCLUSIVE,管线屏障(pipeline barrier)还可以被用来传递队列所有权。