Vulkan 实例化渲染奇怪的深度缓冲行为

时间:2021-04-12 08:23:37

标签: vulkan depth-buffer depth-testing

我正在渲染一个包含 8000 个立方体、1 个猴子和 1 个平面的单个网格测试对象。我检查了法线和绕组顺序。对于网格来说,一切似乎都是正确的。

如果我渲染单个实例,深度缓冲区工作正常。如果我在即时数字增加深度缓冲区无法正常工作时使用实例化进行渲染。

//Depth Attachment
        //Create Depth Image
        depthImage = new Image(
            physicalDevice_,
            logicalDevice_,
            VK_IMAGE_TYPE_2D,
            depthFormat,
            VK_IMAGE_TILING_OPTIMAL,
            swapChainExtent.width,
            swapChainExtent.height,
            1,
            sampleCount_, //do we really need to sample depth????
            VK_IMAGE_LAYOUT_UNDEFINED,
            VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT,
            VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);

        depthImageView = new ImageView(
            logicalDevice_,
            VK_IMAGE_VIEW_TYPE_2D,
            depthImage->handle,
            depthFormat,
            1,
            VK_IMAGE_ASPECT_DEPTH_BIT);

//Render pass Depth Attachment
        VkAttachmentDescription depthAttachment{};
        depthAttachment.format = depthFormat;
        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_UNDEFINED;
        depthAttachment.finalLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;

//Graphics Pipeline 
        VkPipelineDepthStencilStateCreateInfo depthStencil{};
        depthStencil.sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO;
        depthStencil.depthTestEnable = VK_TRUE;
        depthStencil.depthWriteEnable = VK_TRUE;
        depthStencil.depthCompareOp = VK_COMPARE_OP_LESS;
        depthStencil.depthBoundsTestEnable = VK_FALSE;
        depthStencil.minDepthBounds = 0.0f; // Optional
        depthStencil.maxDepthBounds = 1.0f; // Optional
        depthStencil.stencilTestEnable = VK_FALSE;
        depthStencil.front = {}; // Optional
        depthStencil.back = {};  // Optional


屏幕下方是该网格的第 100 个实例的视图。 实例编号越高,深度缓冲区的恶化程度就越大。 如果我使用不同的模型,结果仍然相同。

我错过了什么?

结果: Result 深度缓冲: Depth Buffer

1 个答案:

答案 0 :(得分:0)

对于那些可能遇到类似问题的人。我找到了解决方案。

实际上,这个问题与实例化没有直接关系,但随着实例索引的增加,这个有点混乱的问题变得明显。

原因是投影矩阵 z-near 值太小了。

...
fieldOfView = 65.0f;
znear = 0.001f;       // ! this much small value cause this problem
zfar = 5000.0f;
...

将 z-near 更改为可接受的值。问题解决了。

...
fieldOfView = 65.0f;
znear = 0.1f;       
zfar = 5000.0f;
...
相关问题