Vulkan 深度缓冲区为 0 或 1。绝不会介于两者之间

问题描述 投票:0回答:2

我遇到深度缓冲区/测试不起作用的问题。当我检查 RenderDoc 时,我发现渲染对象时深度缓冲区始终为 1:depth_example。我期待黑色和白色之间有一种平滑的渐变。

编辑:GIF of problem

从昨天开始我一直在尝试解决这个问题,已经尝试了很多事情,例如:更改管道设置,更改渲染通道设置,检查帧缓冲区和深度纹理设置,甚至更改投影/视图矩阵。

验证层没有抛出任何错误,我一直在使用RenderDoc来测试/调试。

我已经保存并上传了应用程序的 RenderDoc 捕获,其状态保持在我尝试进行更改之前的状态(如果有人想查看):RenderDoc Capture

我将在下面发布一些我认为相关的代码,但在此之前我应该提到我正在使用 GLM 来创建具有

GLM_FORCE_DEPTH_ZERO_TO_ONE
+
GLM_FORCE_LEFT_HANDED
定义的渲染矩阵。

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, &m_depthStencil.Image, &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 = &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;
}
c++ 3d vulkan glm-math renderdoc
2个回答
0
投票

我也遇到了这个问题,并按照上面评论中@pezcode的建议设置视口 minDepth 和 maxDepth 修复了它。


0
投票

我遇到了完全相同的症状的问题,但我的问题出在我的透视矩阵的近和远参数上。 我遇到了这个导致问题的原因...

projection_ = glm::perspective(glm::radians(70.0f), static_cast<float>(windowWidth_) / static_cast<float>(windowHeight_), 0.0f, 1.0f);

用这个修复它...

projection_ = glm::perspective(glm::radians(70.0f), static_cast<float>(windowWidth_) / static_cast<float>(windowHeight_), 0.1f, 10.0f);

我猜 0.0f 近平面参数是问题所在。也许除以零或其他什么,仍然需要更多地研究才能更好地理解,但问题已经解决了。

© www.soinside.com 2019 - 2024. All rights reserved.