Vulkan API — урок 56. Доработки имеющегося под третью координату

Render pass

Сейчас нужно включить вложение глубины (depth attachment) в  createRenderPass. Для начала определим VkAttachementDescription.

format должен быть аналогичен самому изображению. На этот раз мы не заботимся о хранении данных глубины (storeOp), потому как они не будут использоваться после того, как отрисовка будет закончена. Это позволяет железу выполнять дополнительные оптимизации. Макет изображения не изменится во время рендеринга, потому initialLayout и finalLayout идентичны:

VkAttachmentDescription depthAttachment = {};
depthAttachment.format = findDepthFormat();
depthAttachment.samples = VK_SAMPLE_COUNT_1_BIT;
depthAttachment.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
depthAttachment.storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
depthAttachment.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
depthAttachment.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
depthAttachment.initialLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
depthAttachment.finalLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;

Добавим ссылку для первого (и единственного) подпрохода:

VkAttachmentReference depthAttachmentRef = {};
depthAttachmentRef.attachment = 1;
depthAttachmentRef.layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;

VkSubpassDescription subpass = {};
subpass.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
subpass.colorAttachmentCount = 1;
subpass.pColorAttachments = &colorAttachmentRef;
subpass.pDepthStencilAttachment = &depthAttachmentRef;

В отличии от вложения цвета, подпроход может использовать только одно вложение глубины (+stencil). Но оно и не имеет смысла делать тесты глубины для нескольких буферов.

Ну и напоследок обновим структуру, включив в неё оба вложения:

std::array<VkAttachmentDescription, 2> attachments = {colorAttachment, depthAttachment};
VkRenderPassCreateInfo renderPassInfo = {};
renderPassInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
renderPassInfo.attachmentCount = attachments.size();
renderPassInfo.pAttachments = attachments.data();
renderPassInfo.subpassCount = 1;
renderPassInfo.pSubpasses = &subpass;
renderPassInfo.dependencyCount = 1;
renderPassInfo.pDependencies = &dependency;

Framebuffer

Далее модифицируем создание буфера кадров, что бы связать глубинное изображение с вложением глубины. Переходим к createFramebuffers и указываем depth image view в качестве второго вложения:

std::array<VkImageView, 2> attachments = {
    swapChainImageViews[i],
    depthImageView
};

VkFramebufferCreateInfo framebufferInfo = {};
framebufferInfo.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO;
framebufferInfo.renderPass = renderPass;
framebufferInfo.attachmentCount = attachments.size();
framebufferInfo.pAttachments = attachments.data();
framebufferInfo.width = swapChainExtent.width;
framebufferInfo.height = swapChainExtent.height;
framebufferInfo.layers = 1;

Так же следует убедиться, что вызов этой функции идет после создания глубинного изображения:

void initVulkan() {
    ...
    createDepthResources();
    createFramebuffers();
    ...
}

Clear values

Так как мы теперь имеем множественные вложения с VK_ATTACHMENT_LOAD_OP_CLEAR, то нужно определить несколько значений очистки. Перейдем в createCommandBuffers и создадим массив структур VkClearValue:

std::array<VkClearValue, 2> clearValues = {};
clearValues[0].color = {0.0f, 0.0f, 0.0f, 1.0f};
clearValues[1].depthStencil = {1.0f, 0};

renderPassInfo.clearValueCount = clearValues.size();
renderPassInfo.pClearValues = clearValues.data();

Диапазон глубины в буфере 0.0 — 1.0 , как упоминалось ранее, где 1.0 лежит в дальней плоскости и 0.0 в ближней. Начальное значение, соответственно, находится в самой дальней точке.

Main Admin

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *