Vulkan Cookbook 第六章 6 为几何渲染和后处理准备渲染过程subpasses

在开发应用程序时,常需绘制几何图形并应用后处理图像效果。本文介绍为几何渲染和后处理准备渲染过程subpasses的方法,包括创建附件描述、子过程参数和子过程依赖关系等,还说明了如何使用这些变量创建渲染过程。

为几何渲染和后处理准备渲染过程subpasses

译者注:示例代码点击此处

在开发应用程序(如游戏或CAD工具)时,通常需要绘制几何图形,然后在渲染整个场景时,应用称为后处理的其他图像效果。

在本节中,我们将看到如何准备一个渲染过程,其中我们将有两个subpasses。第一个subpasses呈现为两个附件——颜色和深度。第二个subpasses从第一个颜色附件读取数据并渲染到另一个颜色附件中——一个swapchain图像,在渲染通过后可以显示(显示在屏幕上)。

做好准备...

要简化需要提供的参数数量,我们使用SubpassParameters类型的自定义结构(请参阅指定子过程描述内容)。。

怎么做...

1.创建一个名为attachments_descriptions的std::vector<VkAttachmentDescription>类型变量。attachments_descriptions向量添加第一个颜色附件的附件描述。 使用以下值初始化描述:
    ·flags为0
    ·format为VK_FORMAT_R8G8B8A8_UNORM
    ·samples为VK_SAMPLE_COUNT_1_BIT
    ·loadOp为VK_ATTACHMENT_LOAD_OP_CLEAR
    ·storeOp为VK_ATTACHMENT_STORE_OP_DONT_CARE
    ·stencilLoadOp为VK_ATTACHMENT_LOAD_OP_DONT_CARE
    ·stencilStoreOp为VK_ATTACHMENT_STORE_OP_DONT_CARE
    ·initialLayout为VK_IMAGE_LAYOUT_UNDEFINED
    ·finalLayout为VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL
2.将另一个元素添加到attachments_descriptions向量,该向量指定深度/模板附件。 使用以下值初始化其成员:
    ·flags为0
    ·format为VK_FORMAT_D16_UNORM
    ·samples为VK_SAMPLE_COUNT_1_BIT
    ·loadOp为VK_ATTACHMENT_LOAD_OP_CLEAR
    ·storeOp为VK_ATTACHMENT_STORE_OP_DONT_CARE
    ·stencilLoadOp为VK_ATTACHMENT_LOAD_OP_DONT_CARE
    ·stencilStoreOp为VK_ATTACHMENT_STORE_OP_DONT_CARE
    ·initialLayout为VK_IMAGE_LAYOUT_UNDEFINED
    ·finalLayout为VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL
3.将第三个元素添加到attachments_descriptions向量中。 这次它将指定另一种颜色附件。 使用以下值初始化它:
    ·flags为0
    ·format为VK_FORMAT_R8G8B8A8_UNORM
    ·samples为VK_SAMPLE_COUNT_1_BIT
    ·loadOp为VK_ATTACHMENT_LOAD_OP_CLEAR
    ·storeOp为VK_ATTACHMENT_STORE_OP_STORE
    ·stencilLoadOp为VK_ATTACHMENT_LOAD_OP_DONT_CARE
    ·stencilStoreOp为VK_ATTACHMENT_STORE_OP_DONT_CARE
    ·initialLayout为VK_IMAGE_LAYOUT_UNDEFINED
    ·finalLayout为VK_IMAGE_LAYOUT_PRESENT_SRC_KHR
4.创建一个名为depth_stencil_attachment的VkAttachmentReference类型变量,并使用以下值对其进行初始化:
    ·attachment为1
    ·layout为VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL
5.创建一个名为subpass_parameters的std::vector<SubpassParameters>类型变量,并将一个具有以下值的元素添加到此向量:
    ·PipelineType为VK_PIPELINE_BIND_POINT_GRAPHICS
    ·InputAttachment为一个空向量
    ·ColorAttachments为包含一个元素和以下值的向量:
        ·attachment为0
       ·layout为VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL
    ·ResolveAttachments为一个空向量
    ·DepthStencilAttachment为指向depth_stencil_attachment的指针
    ·PreserveAttachments为一个空向量
6.将第二个元素添加到描述第二个子过程的subpass_parameters。 使用以下值初始化其成员:
    ·PipelineType为VK_PIPELINE_BIND_POINT_GRAPHICS
    ·InputAttachments为具有以下值的一个元素的向量:
        ·attachment为0
        ·layout为VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL
    ·ColorAttachments为具有以下值的一个元素的向量:
        ·attachment为2
        ·layout为VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL
    ·ResolveAttachments为一个空向量
    ·DepthStencilAttachment为nullptr
    ·PreserveAttachments为一个空向量
7.创建一个名为subpass_dependencies的std::vector<VkSubpassDependency>类型变量,并将一个具有以下值的元素添加到此向量:
    ·srcSubpass为0
    ·dstSubpass为1
    ·srcStageMask为VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT
    ·dstStageMask为VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT
    ·srcAccessMask为VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT
    ·dstAccessMask为VK_ACCESS_INPUT_ATTACHMENT_READ_BIT
    ·dependencyFlags为VK_DEPENDENCY_BY_REGION_BIT
8.使用attachments_descriptions,subpass_parameters和subpass_dependencies变量创建渲染过程。 将其句柄存储在名为render_pass的VkRenderPass类型变量中(请参阅本章中的创建渲染过程内容)。

这个怎么运作...

在本节中,我们使用三个附件创建一个渲染过程。 它们的具体规定如下:

std::vector<VkAttachmentDescription> attachments_descriptions = { 
  { 
    0, 
    VK_FORMAT_R8G8B8A8_UNORM, 
    VK_SAMPLE_COUNT_1_BIT, 
    VK_ATTACHMENT_LOAD_OP_CLEAR, 
    VK_ATTACHMENT_STORE_OP_DONT_CARE, 
    VK_ATTACHMENT_LOAD_OP_DONT_CARE, 
    VK_ATTACHMENT_STORE_OP_DONT_CARE, 
    VK_IMAGE_LAYOUT_UNDEFINED, 
    VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, 
  }, 
  { 
    0, 
    VK_FORMAT_D16_UNORM, 
    VK_SAMPLE_COUNT_1_BIT, 
    VK_ATTACHMENT_LOAD_OP_CLEAR, 
    VK_ATTACHMENT_STORE_OP_DONT_CARE, 
    VK_ATTACHMENT_LOAD_OP_DONT_CARE, 
    VK_ATTACHMENT_STORE_OP_DONT_CARE, 
    VK_IMAGE_LAYOUT_UNDEFINED, 
    VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, 
  }, 
  { 
    0, 
    VK_FORMAT_R8G8B8A8_UNORM, 
    VK_SAMPLE_COUNT_1_BIT, 
    VK_ATTACHMENT_LOAD_OP_CLEAR, 
    VK_ATTACHMENT_STORE_OP_STORE, 
    VK_ATTACHMENT_LOAD_OP_DONT_CARE, 
    VK_ATTACHMENT_STORE_OP_DONT_CARE, 
    VK_IMAGE_LAYOUT_UNDEFINED, 
    VK_IMAGE_LAYOUT_PRESENT_SRC_KHR, 
  }, 
};

首先,我们在第一个子过程中渲染一个颜色附件,我们在第二个附件中读取的颜色附件用于深度数据; 第三个是我们在第二个子过程中渲染的另一种颜色附件。 因为我们在渲染过程之后不需要第一个和第二个附件的内容(我们只需要第二个子过程中的第一个附件的内容),它们的存储操作的值。 我们也不需要在渲染过程开始时使用它们的内容,因此我们指定了UNDEFINED初始布局。 还清除了所有三个附件。

接下来我们定义两个子过程(subpasses):

VkAttachmentReference depth_stencil_attachment = { 
  1, 
  VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, 
}; 
std::vector<SubpassParameters> subpass_parameters = { 
  // #0 subpass 
  { 
    VK_PIPELINE_BIND_POINT_GRAPHICS, 
    {}, 
    { 
      { 
        0, 
        VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL 
      } 
    }, 
    {}, 
    &depth_stencil_attachment, 
    {} 
  }, 
  // #1 subpass 
  { 
    VK_PIPELINE_BIND_POINT_GRAPHICS, 
    { 
      { 
        0, 
        VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL 
      } 
    }, 
    { 
      { 
        2, 
        VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL 
      } 
    }, 
    {}, 
    nullptr, 
    {} 
  } 
};

第一个子过程使用颜色附件和深度附件。 第二个子过程从第一个附件读取(此处用作输入附件)并呈现到第三个附件中。

最后一件事是为第一个附件定义两个子过程之间的依赖关系,它之前是一个颜色附件(我们向它写入数据)和一个输入附件(我们从中读取数据)。 之后我们可以像这样创建渲染过程:

std::vector<VkSubpassDependency> subpass_dependencies = {
  { 
    0, 
    1, 
    VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, 
    VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, 
    VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, 
    VK_ACCESS_INPUT_ATTACHMENT_READ_BIT, 
    VK_DEPENDENCY_BY_REGION_BIT 
  } 
}; 

if( !CreateRenderPass( logical_device, attachments_descriptions, subpass_parameters, subpass_dependencies, render_pass ) ) {
  return false;
}
return true;

 

Computer graphics have a very long and interesting history. Many APIs or custom approaches to the generation of 2D or 3D images have come and gone. A landmark in this history was the invention of OpenGL, one of the first graphics libraries, which allowed us to create real-time, high-performance 3D graphics, and which was available for everyone on multiple operating systems. It is still developed and widely used even today. And this year we can celebrate its 25th birthday! But many things have changed since OpenGL was created. The graphics hardware industry is evolving very quickly. And recently, to accommodate these changes, a new approach to 3D graphics rendering was presented. It took the form of a low-level access to the graphics hardware. OpenGL was designed as a high-level API, which allows users to easily render images on screen. But this high-level approach, convenient for users, is difficult for graphics drivers to handle. This is one of the main reasons for restricting the hardware to show its full potential. The new approach tries to overcome these struggles–it gives users much more control over the hardware, but also many more responsibilities. This way application developers can release the full potential of the graphics hardware, because the drivers no longer block them. Low-level access allows drivers to be much smaller, much thinner. But these benefits come at the expense of much more work that needs to done by the developers. The first evangelist of the new approach to graphics rendering was a Mantle API designed by AMD. When it proved that low-level access can give considerable performance benefits, other companies started working on their own graphics libraries. One of the most notable representatives of the new trend were Metal API, designed by Apple, and DirectX 12, developed by Microsoft. But all of the above libraries were developed with specific operating systems and/or hardware in mind. There was no open and multiplatform standard such as OpenGL. Until last year. Year 2016 saw the release of the Vulkan API, developed by Khronos consortium, which maintains the OpenGL library. Vulkan also represents the new approach, a low-level access to the graphics hardware, but unlike the other libraries it is available for everyone on multiple operating systems and hardware platforms–from high-performance desktop computers with Windows or Linux operating systems, to mobile devices with Android OS. And as it is still being very new, there are few resources teaching developers how to use it. This book tries to fill this gap.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值