Буфер глубины Vulkan равен либо 0, либо 1. Никогда не находится между ними

#c #3d #vulkan #glm-math #renderdoc

#c #3D #vulkan #glm-математика #renderdoc

Вопрос:

У меня возникла проблема с тем, что буфер глубины / тест не работает. Когда я проверяю с помощью RenderDoc, я вижу, что буфер глубины всегда равен только 1, где был отрисован объект: depth_example . Я ожидаю своего рода плавного градиента между черным и белым.

Редактировать: GIF проблемы

Я пытаюсь исправить эту проблему со вчерашнего дня и перепробовал множество способов, таких как: изменение настроек конвейера, изменение настроек renderpass, проверка настройки текстуры фреймбуфера и глубины и даже изменение матриц проекции / просмотра.

Уровни проверки не выдавали никаких ошибок, и я использовал RenderDoc для тестирования / отладки.

Я сохранил и загрузил запись RenderDoc приложения в том состоянии, в котором оно было до того, как я попытался внести изменения, если кто-нибудь захочет посмотреть: RenderDoc Capture

Ниже я опубликую часть кода, который, по моему мнению, имеет отношение к делу, но перед этим я должен упомянуть, что я использую GLM для создания матрицы рендеринга с GLM_FORCE_DEPTH_ZERO_TO_ONE помощью GLM_FORCE_LEFT_HANDED defines .

 rasterizerState.depthClampEnable = false;
rasterizerState.rasterizerDiscardEnable = false;
rasterizerState.polygonMode = vk::PolygonMode::eFill;
rasterizerState.lineWidth = 1.0f;
rasterizerState.cullMode = vk::CullModeFlagBits::eBack;
rasterizerState.frontFace = vk::FrontFace::eCounterClockwise;
rasterizerState.depthBiasEnable = false;

depthStencilState.depthTestEnable = true;
depthStencilState.depthWriteEnable = true;
depthStencilState.depthCompareOp = vk::CompareOp::eLess;
depthStencilState.depthBoundsTestEnable = false;
depthStencilState.stencilTestEnable = false;
 
 vk::ImageCreateInfo imageInfo{};
imageInfo.imageType = vk::ImageType::e2D;
imageInfo.format = depthFormat;
imageInfo.extent.width = m_swapchainWidth;
imageInfo.extent.height = m_swapchainHeight;
imageInfo.extent.depth = 1.0f;
imageInfo.mipLevels = 1;
imageInfo.arrayLayers = 1;
imageInfo.samples = vk::SampleCountFlagBits::e1;
imageInfo.tiling = vk::ImageTiling::eOptimal;
imageInfo.usage = vk::ImageUsageFlagBits::eDepthStencilAttachment | vk::ImageUsageFlagBits::eTransferSrc;

allocator.Allocate(imageInfo, VMA_MEMORY_USAGE_GPU_ONLY, amp;m_depthStencil.Image, amp;m_depthStencil.Allocation);

vk::ImageViewCreateInfo imageViewInfo{};
imageViewInfo.viewType = vk::ImageViewType::e2D;
imageViewInfo.image = m_depthStencil.Image;
imageViewInfo.format = depthFormat;
imageViewInfo.subresourceRange.baseMipLevel = 0;
imageViewInfo.subresourceRange.levelCount = 1;
imageViewInfo.subresourceRange.baseArrayLayer = 0;
imageViewInfo.subresourceRange.layerCount = 1;
imageViewInfo.subresourceRange.aspectMask = vk::ImageAspectFlagBits::eDepth;
if (depthFormat >= vk::Format::eD16UnormS8Uint)
{
    imageViewInfo.subresourceRange.aspectMask |= vk::ImageAspectFlagBits::eStencil;
}
 
 vk::AttachmentDescription depthAttachment{};
depthAttachment.format = m_context->GetDepthFormat();
depthAttachment.samples = vk::SampleCountFlagBits::e1;
depthAttachment.loadOp = vk::AttachmentLoadOp::eClear;
depthAttachment.storeOp = vk::AttachmentStoreOp::eDontCare;
depthAttachment.stencilLoadOp = vk::AttachmentLoadOp::eDontCare;
depthAttachment.stencilStoreOp = vk::AttachmentStoreOp::eDontCare;
depthAttachment.initialLayout = vk::ImageLayout::eUndefined;
depthAttachment.finalLayout = vk::ImageLayout::eDepthStencilAttachmentOptimal;

vk::AttachmentReference depthAttachmentRef{};
depthAttachmentRef.attachment = 1;
depthAttachmentRef.layout = vk::ImageLayout::eDepthStencilAttachmentOptimal;

vk::SubpassDependency dependency{};
dependency.srcSubpass = VK_SUBPASS_EXTERNAL;
dependency.dstSubpass = 0;
dependency.srcStageMask = vk::PipelineStageFlagBits::eColorAttachmentOutput;
dependency.dstStageMask = vk::PipelineStageFlagBits::eColorAttachmentOutput;
dependency.srcAccessMask = {};
dependency.dstAccessMask = vk::AccessFlagBits::eColorAttachmentWrite;
renderPassInfo.dependencyCount = 1;
renderPassInfo.pDependencies = amp;dependency;
 
 auto TransformComponent::GetTransform() const -> glm::mat4
{
    auto rot = glm::eulerAngleXYZ(Rotation.x, Rotation.y, Rotation.z);
    return glm::translate(glm::mat4(1.0f), Position) * rot * glm::scale(glm::mat4(1.0f), Scale);
}
auto TransformComponent::GetView() const -> glm::mat4
{
    auto transform = glm::translate(glm::mat4(1.0f), Position);
    transform = glm::rotate(transform, glm::radians(Rotation.y), { 0, 1.0f, 0 });
    transform = glm::rotate(transform, glm::radians(Rotation.x), { 1.0f, 0, 0 });
    return glm::inverse(transform);
}
auto CameraComponent::GetProj() const -> glm::mat4
{
    auto windowSize = Application::Get()->GetWindow()->GetSize();
    auto proj = glm::perspective(glm::radians(FieldOfView), windowSize.x / (float)windowSize.y, Near, Far);
    proj[1][1] *= -1.0f;
    return proj;
}
 

Комментарии:

1. Не связано, но в чем смысл синтаксиса auto CameraComponent::GetProj() const -> glm::mat4 , когда у вас уже был glm::mat4 CameraComponent::GetProj() const со времен C?

2. Имея auto в начале и возвращаемый тип в конце, он сохраняет имена функций / методов в ряд. Я думаю, что это делает код немного более аккуратным.

3. Но это одни и те же возвращаемые значения, они будут выстроены в любом случае.

4. Это просто стало привычкой.

5. Вы minDepth правильно и правильно настраиваете область просмотра maxDepth ?