译者注:示例代码点击此处
在开发应用程序(如游戏或CAD工具)时,通常需要绘制几何图形,然后在渲染整个场景时,应用称为后处理的其他图像效果。
在本节中,我们将看到如何准备一个渲染过程,其中我们将有两个subpasses。第一个subpasses呈现为两个附件——颜色和深度。第二个subpasses从第一个颜色附件读取数据并渲染到另一个颜色附件中——一个swapchain图像,在渲染通过后可以显示(显示在屏幕上)。
要简化需要提供的参数数量,我们使用SubpassParameters类型的自定义结构(请参阅指定子过程描述内容)。。
1.创建一个名为attachments_descriptions的std::vector
·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
·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
·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 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 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 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;