Vulkan。在阴影图中通过时不会记录缓冲区深度

时间:2019-05-10 11:38:22

标签: c++ qt vulkan

我尝试使用此示例将阴影添加到项目中。 (https://github.com/SaschaWillems/Vulkan/tree/master/examples/shadowmapping) 不幸的是,它没有用。更准确地说,它可用于清理第一遍的缓冲区深度。但是过程本身不起作用,或者没有将深度缓冲区写入采样器,而我将其传递给第二遍。同时,用于清洁深度缓冲区的参数会影响采样器。我检查了从光源渲染时场景参数的传递,它们是正确的。我不知道该怎么想了。也许是我不理解的简单错误。

首过管道

VkPipeline MainRenderer::initShadowPipeline(const VKStr::Device & device, VkPipelineLayout pipelineLayout, VkRenderPass renderPass, std::string vShaderName)
{
    VkPipeline resultPipelineHandle = VK_NULL_HANDLE;

    std::vector<VkVertexInputBindingDescription> bindingDescription = GetVertexInputBindingDescriptions(0);
    std::vector<VkVertexInputAttributeDescription> attributeDescriptions = GetVertexInputAttributeDescriptions(0);

    VkPipelineVertexInputStateCreateInfo vertexInputStage = {};
    vertexInputStage.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO;
    vertexInputStage.vertexBindingDescriptionCount = (uint32_t)bindingDescription.size();
    vertexInputStage.pVertexBindingDescriptions = bindingDescription.data();
    vertexInputStage.vertexAttributeDescriptionCount = (uint32_t)attributeDescriptions.size();
    vertexInputStage.pVertexAttributeDescriptions = attributeDescriptions.data();

    VkPipelineInputAssemblyStateCreateInfo inputAssemblyStage = {};
    inputAssemblyStage.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO;
    inputAssemblyStage.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;          
    inputAssemblyStage.primitiveRestartEnable = VK_FALSE;                       

    std::vector<VkPipelineShaderStageCreateInfo> shaderStages = {
        {
            VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
            nullptr,
            0,
            VK_SHADER_STAGE_VERTEX_BIT,
            LoadSPIRVShader(vShaderName, device.logicalDevice),
            "main",
            nullptr
        }
    };

    VkViewport viewport = {};
    viewport.width = (float)shadowPass_.width;
    viewport.height = (float)shadowPass_.height;
    viewport.minDepth = 0.0f;
    viewport.maxDepth = 1.0f;

    VkRect2D scissor = {};
    scissor.offset = { 0, 0 };
    scissor.extent.width = shadowPass_.width;
    scissor.extent.height = shadowPass_.height;

    VkPipelineViewportStateCreateInfo viewportState = {};
    viewportState.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO;
    viewportState.viewportCount = 1;
    viewportState.pViewports = &viewport;
    viewportState.scissorCount = 1;
    viewportState.pScissors = &scissor;
    viewportState.flags = 0;

    VkPipelineRasterizationStateCreateInfo rasterizationStage = {};
    rasterizationStage.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO;
    rasterizationStage.depthClampEnable = VK_FALSE;                                 
    rasterizationStage.polygonMode = VK_POLYGON_MODE_FILL;            
    rasterizationStage.lineWidth = 1.0f;                              
    rasterizationStage.cullMode = VK_CULL_MODE_BACK_BIT;                
    rasterizationStage.frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE;
    rasterizationStage.depthBiasEnable = VK_TRUE;                     
    rasterizationStage.depthBiasConstantFactor = 1.25f;
    rasterizationStage.depthBiasClamp = 0.0f;
    rasterizationStage.depthBiasSlopeFactor = 1.75f;

    VkPipelineDepthStencilStateCreateInfo depthStencilStage = {};
    depthStencilStage.sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO;
    depthStencilStage.depthTestEnable = VK_TRUE;
    depthStencilStage.depthWriteEnable = VK_TRUE;
    depthStencilStage.depthCompareOp = VK_COMPARE_OP_LESS_OR_EQUAL;
    depthStencilStage.back.compareOp = VK_COMPARE_OP_ALWAYS;
    depthStencilStage.front = depthStencilStage.back;

    VkPipelineMultisampleStateCreateInfo multisamplingStage = {};
    multisamplingStage.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO;
    multisamplingStage.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT;  
    multisamplingStage.flags = 0;

    VkPipelineColorBlendAttachmentState colorBlendAttachment = {};
    colorBlendAttachment.colorWriteMask = 0xf;
    colorBlendAttachment.blendEnable = VK_FALSE;

    VkPipelineColorBlendStateCreateInfo colorBlendState = {};
    colorBlendState.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO;
    colorBlendState.attachmentCount = 0;
    colorBlendState.pAttachments = &colorBlendAttachment;

    std::vector<VkDynamicState> dynamicStateEnables = { VK_DYNAMIC_STATE_VIEWPORT, VK_DYNAMIC_STATE_SCISSOR };
    dynamicStateEnables.push_back(VK_DYNAMIC_STATE_DEPTH_BIAS);

    VkPipelineDynamicStateCreateInfo dynamicStateCI = {};
    dynamicStateCI.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO;
    dynamicStateCI.pDynamicStates = dynamicStateEnables.data();
    dynamicStateCI.dynamicStateCount = dynamicStateEnables.size();
    dynamicStateCI.flags = 0;

    VkGraphicsPipelineCreateInfo pipelineInfo = {};
    pipelineInfo.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
    pipelineInfo.stageCount = (uint32_t)shaderStages.size();    
    pipelineInfo.pStages = shaderStages.data();                
    pipelineInfo.pVertexInputState = &vertexInputStage;        
    pipelineInfo.pInputAssemblyState = &inputAssemblyStage;     
    pipelineInfo.pViewportState = &viewportState;               
    pipelineInfo.pRasterizationState = &rasterizationStage;    
    pipelineInfo.pDepthStencilState = &depthStencilStage;      
    pipelineInfo.pMultisampleState = &multisamplingStage;      
    pipelineInfo.pColorBlendState = &colorBlendState;           
    pipelineInfo.pDynamicState = &dynamicStateCI;
    pipelineInfo.layout = pipelineLayout;                      
    pipelineInfo.renderPass = renderPass;                       
    pipelineInfo.subpass = 0;      
    pipelineInfo.stageCount = 1;

    if (vkCreateGraphicsPipelines(device.logicalDevice, VK_NULL_HANDLE, 1, &pipelineInfo, nullptr, &resultPipelineHandle) != VK_SUCCESS) {
        throw std::runtime_error("Vulkan: Error while creating pipeline");
    }

    tools::LogMessage("Vulkan: Pipeline sucessfully initialized");

    for (VkPipelineShaderStageCreateInfo &shaderStageInfo : shaderStages) {
        vkDestroyShaderModule(device.logicalDevice, shaderStageInfo.module, nullptr);
    }

    return resultPipelineHandle;
}

第一遍renderPassage

VkRenderPass MainRenderer::initShadowRenderPassage(const VKStr::Device &device)
{

    std::vector<VkAttachmentDescription> attachments;

    VkAttachmentDescription depthStencilAttachment = {};
    depthStencilAttachment.format = shadowPass_.depthFormat;
    depthStencilAttachment.samples = VK_SAMPLE_COUNT_1_BIT;                                
    depthStencilAttachment.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;                           
    depthStencilAttachment.storeOp = VK_ATTACHMENT_STORE_OP_STORE;                    
    depthStencilAttachment.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;                
    depthStencilAttachment.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;              
    depthStencilAttachment.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;                      
    depthStencilAttachment.finalLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL; 
    attachments.push_back(depthStencilAttachment);

    VkAttachmentReference depthStencilAttachemntReference = {
        0,                                                           
        VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL             
    };

    VkSubpassDescription subpassDescription = {};
    subpassDescription.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
    subpassDescription.colorAttachmentCount = 0;  
    subpassDescription.pDepthStencilAttachment = &depthStencilAttachemntReference;         

    std::vector<VkSubpassDependency> dependencies = {
        {
            VK_SUBPASS_EXTERNAL,                                                      
            0,                                                                        
            VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,                                     
            VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT,                            
            VK_ACCESS_SHADER_READ_BIT,
            VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
            VK_DEPENDENCY_BY_REGION_BIT
        },
        {
            0,                                                                        
            VK_SUBPASS_EXTERNAL,                                                      
            VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,                            
            VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,                                     
            VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
            VK_ACCESS_SHADER_READ_BIT,
            VK_DEPENDENCY_BY_REGION_BIT
        }
    };


    VkRenderPassCreateInfo renderPassInfo = {};
    renderPassInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
    renderPassInfo.attachmentCount = 1;              
    renderPassInfo.pAttachments = attachments.data();                               
    renderPassInfo.subpassCount = 1;                                                
    renderPassInfo.pSubpasses = &subpassDescription;                                
    renderPassInfo.dependencyCount = (unsigned int)dependencies.size();            
    renderPassInfo.pDependencies = dependencies.data();                             

    VkRenderPass renderPass;
    if (vkCreateRenderPass(device.logicalDevice, &renderPassInfo, nullptr, &renderPass) != VK_SUCCESS) {
        throw std::runtime_error("Vulkan: Failed to create render passage");
    }

    tools::LogMessage("Vulkan: Render passage successfully initialized");

    return renderPass;
}

第一遍frameBuff

void MainRenderer::initShadowFrameBuffer(const VKStr::Device &device)
{
    this->shadowPass_.width = 4096;
    this->shadowPass_.height = 4096;

    VkImageCreateInfo image = {};
    image.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
    image.imageType = VK_IMAGE_TYPE_2D;
    image.extent.width = shadowPass_.width;
    image.extent.height = shadowPass_.height;
    image.extent.depth = 1;
    image.mipLevels = 1;
    image.arrayLayers = 1;
    image.samples = VK_SAMPLE_COUNT_1_BIT;
    image.tiling = VK_IMAGE_TILING_OPTIMAL;
    image.format = this->shadowPass_.depthFormat;                                                           
    image.usage = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT;     
    image.sharingMode = VK_SHARING_MODE_CONCURRENT;
    if (vkCreateImage(device.logicalDevice, &image, nullptr, &shadowPass_.depth.image) != VK_SUCCESS)
    {
        throw std::runtime_error("Vulkan: Error shadowImage create info");
    }

    VkMemoryAllocateInfo memAlloc{};
    memAlloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
    VkMemoryRequirements memReqs;
    vkGetImageMemoryRequirements(device.logicalDevice, shadowPass_.depth.image, &memReqs);
    memAlloc.allocationSize = memReqs.size;
    memAlloc.memoryTypeIndex = GetMemoryTypeIndex(device.physicalDevice, memReqs.memoryTypeBits, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);

    if (vkAllocateMemory(device.logicalDevice, &memAlloc, nullptr, &shadowPass_.depth.memory) != VK_SUCCESS)
    {
        throw std::runtime_error("Vulkan: Error Shadow AllocateMemory");
    }
    if (vkBindImageMemory(device.logicalDevice, shadowPass_.depth.image, shadowPass_.depth.memory, 0) != VK_SUCCESS)
    {
        throw std::runtime_error("Vulkan: Error shadow bindMemory");
    }

    VkImageViewCreateInfo depthStencilView = {};
    depthStencilView.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
    depthStencilView.viewType = VK_IMAGE_VIEW_TYPE_2D;
    depthStencilView.format = this->shadowPass_.depthFormat;
    depthStencilView.subresourceRange = {};
    depthStencilView.subresourceRange.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
    depthStencilView.subresourceRange.baseMipLevel = 0;
    depthStencilView.subresourceRange.levelCount = 1;
    depthStencilView.subresourceRange.baseArrayLayer = 0;
    depthStencilView.subresourceRange.layerCount = 1;
    depthStencilView.image = shadowPass_.depth.image;

    if (vkCreateImageView(device.logicalDevice, &depthStencilView, nullptr, &shadowPass_.depth.view) != VK_SUCCESS)
    {
        throw std::runtime_error("Vulkan: Error shadow createImageView");
    }


    VkFramebufferCreateInfo fbufCreateInfo = {};
    fbufCreateInfo.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO;
    fbufCreateInfo.renderPass = shadowPass_.renderPass;
    fbufCreateInfo.attachmentCount = 1;
    fbufCreateInfo.pAttachments = &shadowPass_.depth.view;
    fbufCreateInfo.width = shadowPass_.width;
    fbufCreateInfo.height = shadowPass_.height;
    fbufCreateInfo.layers = 1;

    if (vkCreateFramebuffer(device.logicalDevice, &fbufCreateInfo, nullptr, &shadowPass_.frameBuffer) != VK_SUCCESS)
    {
        throw std::runtime_error("Vulkan: Error shadow frameBuffer");
    }

    VkSamplerCreateInfo sampler = {};
    sampler.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO;
    sampler.magFilter = VK_FILTER_LINEAR;
    sampler.minFilter = VK_FILTER_LINEAR;
    sampler.mipmapMode = VK_SAMPLER_MIPMAP_MODE_LINEAR;
    sampler.addressModeU = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
    sampler.addressModeV = sampler.addressModeU;
    sampler.addressModeW = sampler.addressModeU;
    sampler.mipLodBias = 0.0f;
    sampler.maxAnisotropy = 1.0f;
    sampler.minLod = 0.0f;
    sampler.maxLod = 1.0f;
    sampler.borderColor = VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE;

    if (vkCreateSampler(device.logicalDevice, &sampler, nullptr, &shadowPass_.depthSampler) != VK_SUCCESS)
    {
        throw std::runtime_error("Vulkan: Error Shadow createSampler");
    }

}

commandBuff

void MainRenderer::PrepareDrawCommands(std::vector<VkCommandBuffer> commandBuffers, VkRenderPass renderPass, std::vector<VkPipelineLayout> pipelineLayout, VkDescriptorSet descriptorSetMain, VkDescriptorSet descriptorSetInfo, VkDescriptorSet descriptorSetVLight, const VKStr::Swapchain & swapchain, const std::vector<VKStr::Primitive>& primitives)
{
    VkCommandBufferBeginInfo cmdBufInfo = {};
    cmdBufInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
    cmdBufInfo.flags = VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT;
    cmdBufInfo.pNext = nullptr;

    std::vector<VkClearValue> clearValues(2);
    clearValues[0].color = { 0.0f, 0.0f, 0.0f, 1.0f };
    clearValues[1].depthStencil.depth = 1.0f;
    clearValues[1].depthStencil.stencil = 0;

    std::vector<VkClearValue> clearValuesShadow(1);
    clearValuesShadow[0].depthStencil = { 1.0f, 0 };
    for (unsigned int i = 0; i < commandBuffers.size(); ++i)
    {
        VkRenderPassBeginInfo renderPassBeginInfo = {};
        vkBeginCommandBuffer(commandBuffers[i], &cmdBufInfo);
        if (ShadowRender)
        {

            renderPassBeginInfo = {};
            renderPassBeginInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
            renderPassBeginInfo.pNext = nullptr;
            renderPassBeginInfo.renderPass = this->shadowPass_.renderPass;
            renderPassBeginInfo.renderArea.offset.x = 0;
            renderPassBeginInfo.renderArea.offset.y = 0;
            renderPassBeginInfo.renderArea.extent.width = this->shadowPass_.width;
            renderPassBeginInfo.renderArea.extent.height = this->shadowPass_.height;
            renderPassBeginInfo.clearValueCount = clearValuesShadow.size();
            renderPassBeginInfo.pClearValues = clearValuesShadow.data();

            renderPassBeginInfo.framebuffer = this->shadowPass_.frameBuffer;

            vkCmdBeginRenderPass(commandBuffers[i], &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);

            vkCmdSetDepthBias(
                commandBuffers[i],
                1.25f,
                0.0f,
                1.75f);

            if (!primitives.empty()) {
                for (unsigned int primitiveIndex = 0; primitiveIndex < primitives.size(); primitiveIndex++)
                {
                    vkCmdBindPipeline(commandBuffers[i], VK_PIPELINE_BIND_POINT_GRAPHICS, this->pipelines_[3]);

                    std::vector<uint32_t> dynamicOffsets = {
                        primitiveIndex * static_cast<uint32_t>(this->device_.GetDynamicAlignment<glm::mat4>())
                    };

                    if (primitives_[primitiveIndex].pipelineIndex == AREAN_SHADER_T_BASE)
                    {
                        std::vector<VkDescriptorSet> descriptorSets = {
                        this->descriptorSetShadow_
                        };


                        vkCmdBindDescriptorSets(
                            commandBuffers[i],
                            VK_PIPELINE_BIND_POINT_GRAPHICS,
                            pipelineLayout[2],
                            0,
                            (uint32_t)descriptorSets.size(),
                            descriptorSets.data(),
                            (uint32_t)dynamicOffsets.size(),
                            dynamicOffsets.data());


                        if (primitives[primitiveIndex].drawIndexed && primitives[primitiveIndex].indexBuffer.count > 0) {

                            VkDeviceSize offsets[1] = { 0 };
                            vkCmdBindVertexBuffers(commandBuffers[i], 0, 1, &(primitives[primitiveIndex].vertexBuffer.vkBuffer), offsets);


                            vkCmdBindIndexBuffer(commandBuffers[i], primitives[primitiveIndex].indexBuffer.vkBuffer, 0, VK_INDEX_TYPE_UINT32);


                            vkCmdDrawIndexed(commandBuffers[i], primitives[primitiveIndex].indexBuffer.count, 1, 0, 0, 0);
                        }

                        else {
                            VkDeviceSize offsets[1] = { 0 };
                            vkCmdBindVertexBuffers(commandBuffers[i], 0, 1, &(primitives[primitiveIndex].vertexBuffer.vkBuffer), offsets);

                            vkCmdDraw(commandBuffers[i], primitives[primitiveIndex].vertexBuffer.count, 1, 0, 0);
                        }

                    }
                }
            }

            vkCmdEndRenderPass(commandBuffers[i]);

        }

    /*VkImageSubresourceRange imageRes = {}; //i try it, but not affect.
            imageRes.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
            imageRes.baseMipLevel = 0;
            imageRes.levelCount = 1;
            imageRes.baseArrayLayer = 0;
            imageRes.layerCount = 1;

            VkImageMemoryBarrier imageMemoryBarrier = {};
                imageMemoryBarrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
                imageMemoryBarrier.pNext = NULL;
                imageMemoryBarrier.image = this->shadowPass_.depth.image;
                imageMemoryBarrier.subresourceRange = imageRes;
                imageMemoryBarrier.srcAccessMask = VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
                imageMemoryBarrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
                imageMemoryBarrier.oldLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
                imageMemoryBarrier.newLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;


                vkCmdPipelineBarrier(commandBuffers[i],
                    VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT |
                    VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT, // srcStageMask
                    VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, // dstStageMask
                    0,
                    0, nullptr,
                    0, nullptr,
                    1, // imageMemoryBarrierCount
                    &imageMemoryBarrier // pImageMemoryBarriers
                    );*/


            renderPassBeginInfo = {};
            renderPassBeginInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
            renderPassBeginInfo.pNext = nullptr;
            renderPassBeginInfo.renderPass = renderPass;
            renderPassBeginInfo.renderArea.offset.x = 0;
            renderPassBeginInfo.renderArea.offset.y = 0;
            renderPassBeginInfo.renderArea.extent.width = swapchain.imageExtent.width;
            renderPassBeginInfo.renderArea.extent.height = swapchain.imageExtent.height;
            renderPassBeginInfo.clearValueCount = (uint32_t)clearValues.size();
            renderPassBeginInfo.pClearValues = clearValues.data();  
            renderPassBeginInfo.framebuffer = swapchain.framebuffers[i];

            vkCmdBeginRenderPass(commandBuffers[i], &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);

            /*2 pass*/
    }
}

0 个答案:

没有答案