Vulkan Cookbook 第六章 6 为几何渲染和后处理准备渲染过程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;

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值