如何在Vulkan中渲染为纹理?

时间:2019-12-14 17:14:24

标签: c++ vulkan

我需要在项目中渲染到textrue。

Pass1:绘制一个颜色为(0.5,0.5,0.5,1.0)的颜色正方形,并且渲染目标为纹理。

Pass2:绘制一个使用pass1的纹理的正方形并渲染目标为表面。

预期结果:

enter image description here

但是我得到如下奇怪的结果:

enter image description here

使用以下方法创建图像:

  VkImage hImageTexture = VK_NULL_HANDLE;
  VkImageCreateInfo imageCreateInfo = {0};
  imageCreateInfo.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
  imageCreateInfo.pNext = nullptr;
  imageCreateInfo.flags = 0;
  imageCreateInfo.imageType = VK_IMAGE_TYPE_2D;
  imageCreateInfo.format = VK_FORMAT_B8G8R8A8_UNORM;
  imageCreateInfo.extent.width = width;
  imageCreateInfo.extent.height = height;
  imageCreateInfo.extent.depth = 1;
  imageCreateInfo.mipLevels = 1;
  imageCreateInfo.arrayLayers = 1;
  imageCreateInfo.samples = VK_SAMPLE_COUNT_1_BIT;
  imageCreateInfo.tiling = VK_IMAGE_TILING_OPTIMAL;
  imageCreateInfo.usage =
    VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT |
    VK_IMAGE_USAGE_TRANSFER_DST_BIT |
    VK_IMAGE_USAGE_SAMPLED_BIT;
  imageCreateInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
  imageCreateInfo.queueFamilyIndexCount = 0;
  imageCreateInfo.pQueueFamilyIndices = nullptr;
  imageCreateInfo.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
  //
  VkResult res = vkCreateImage(hDevice , &imageCreateInfo , nullptr , &hImageTexture);

使用以下方法创建图像视图:

  VkImageView hImageViewTexture = VK_NULL_HANDLE;
  VkImageViewCreateInfo imageViewCreateInfo = {0};
  imageViewCreateInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
  imageViewCreateInfo.pNext = nullptr;
  imageViewCreateInfo.flags = 0;
  imageViewCreateInfo.image = hImageTexture;
  imageViewCreateInfo.viewType = VK_IMAGE_VIEW_TYPE_2D;
  imageViewCreateInfo.format = VK_FORMAT_B8G8R8A8_UNORM;
  imageViewCreateInfo.components.r = VK_COMPONENT_SWIZZLE_R;
  imageViewCreateInfo.components.g = VK_COMPONENT_SWIZZLE_G;
  imageViewCreateInfo.components.b = VK_COMPONENT_SWIZZLE_B;
  imageViewCreateInfo.components.a = VK_COMPONENT_SWIZZLE_A;
  imageViewCreateInfo.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
  imageViewCreateInfo.subresourceRange.baseMipLevel = 0;
  imageViewCreateInfo.subresourceRange.levelCount = 1;
  imageViewCreateInfo.subresourceRange.baseArrayLayer = 0;
  imageViewCreateInfo.subresourceRange.layerCount = 1;
  VkResult res=vkCreateImageView(
    hDevice,
    &imageViewCreateInfo,
    NULL,
    &hImageViewTexture);

渲染循环如下:

  //Pass1
  //Clear texture  color
  vkCmdPipelineBarrier();//Transition layout to VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL
  vkCmdClearColorImage();//Clear color(0.0 , 0.0 ,0.0 , 1.0)
  vkCmdPipelineBarrier();//Transition layout to VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL
  //Change texture's barrier
  VkImageMemoryBarrier imageMemoryBarrierForOutput = {0};
  imageMemoryBarrierForOutput.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
  imageMemoryBarrierForOutput.pNext = nullptr;
  imageMemoryBarrierForOutput.srcAccessMask = 0;
  imageMemoryBarrierForOutput.dstAccessMask = 
    VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
  imageMemoryBarrierForOutput.oldLayout = VK_IMAGE_LAYOUT_UNDEFINED;
  imageMemoryBarrierForOutput.newLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
  imageMemoryBarrierForOutput.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
  imageMemoryBarrierForOutput.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
  imageMemoryBarrierForOutput.image = hImageTexture;
  imageMemoryBarrierForOutput.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
  imageMemoryBarrierForOutput.subresourceRange.baseMipLevel = 0;
  imageMemoryBarrierForOutput.subresourceRange.levelCount = 1;
  imageMemoryBarrierForOutput.subresourceRange.baseArrayLayer = 0;
  imageMemoryBarrierForOutput.subresourceRange.layerCount = 1;
  vkCmdPipelineBarrier(
    hCommandBuffer,
    VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
    VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT,
    0,
    0,
    nullptr,
    0,
    nullptr,
    1,
    &imageMemoryBarrierForOutput);
  //draw
  vkCmdBeginRenderPass();
  vkCmdSetViewport();
  vkCmdSetScissor();
  vkCmdBindPipeline();
  vkCmdBindDescriptorSets();
  vkCmdBindVertexBuffers();
  vkCmdBindIndexBuffer();
  vkCmdDrawIndexed();
  vkCmdEndRenderPass();
  //
  //Pass2
  //Clear surface color
  vkCmdPipelineBarrier();//Transition layout to VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL
  vkCmdClearColorImage();//Clear color(0.5 , 0.5 ,1.0 , 1.0)
  vkCmdPipelineBarrier();//Transition layout to VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL
  //Change texture's barrier
  VkImageMemoryBarrier imageMemoryBarrierForInput = {0};
  imageMemoryBarrierForInput.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
  imageMemoryBarrierForInput.pNext = nullptr;
  imageMemoryBarrierForInput.srcAccessMask = 0;
  imageMemoryBarrierForInput.dstAccessMask = 
    VK_ACCESS_SHADER_READ_BIT |
    VK_ACCESS_INPUT_ATTACHMENT_READ_BIT;
  imageMemoryBarrierForInput.oldLayout = VK_IMAGE_LAYOUT_UNDEFINED;
  imageMemoryBarrierForInput.newLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
  imageMemoryBarrierForInput.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
  imageMemoryBarrierForInput.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
  imageMemoryBarrierForInput.image = hImageTexture;
  imageMemoryBarrierForInput.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
  imageMemoryBarrierForInput.subresourceRange.baseMipLevel = 0;
  imageMemoryBarrierForInput.subresourceRange.levelCount = 1;
  imageMemoryBarrierForInput.subresourceRange.baseArrayLayer = 0;
  imageMemoryBarrierForInput.subresourceRange.layerCount = 1;
  vkCmdPipelineBarrier(
    hCommandBuffer,
    VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
    VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT,
    0,
    0,
    nullptr,
    0,
    nullptr,
    1,
    &imageMemoryBarrierForInput);
  //draw
  vkCmdBeginRenderPass();
  vkCmdSetViewport();
  vkCmdSetScissor();
  vkCmdBindPipeline();
  vkCmdBindDescriptorSets();
  vkCmdBindVertexBuffers();
  vkCmdBindIndexBuffer();
  vkCmdDrawIndexed();
  vkCmdEndRenderPass();

Pass1顶点着色器:

#version 450

layout (location=0) in vec4 inPos;
layout (location=0) out vec4 outPos;

void main(void)
{
  outPos = float4(inPos.xy , 0.0 , 1.0);  
  gl_Position = outPos;
}

Pass1片段着色器:

#version 450

layout (location=0) in vec4 inPos;
layout (location=0) out vec4 outColor;

void main(void)
{
  outColor = float4(0.5 , 0.5 , 0.5 , 1.0);    
}

Pass2顶点着色器:

#version 450

layout (location=0) in vec4 inPos;
layout (location=1) in vec2 inUV;
//
layout (location=0) out vec4 outPos;
layout (location=1) out vec2 outUV;
//
void main(void)
{
  outPos = inPos;
  outUV = inUV;
  //
  gl_Position=outPos;
}

Pass2片段着色器:

#version 450
//
layout (location=0) in vec4 inPos;
layout (location=1) in vec2 inUV;
//
layout (binding=1) uniform sampler2D inTex;
layout (location=0) out vec4 outColor;
void main(void)
{
  outColor = texture(inTex , inUV);
}

如果将图像拼贴更改为VK_IMAGE_TILING_LINEAR,则会得到以下信息:

enter image description here

如果将图像拼贴更改为VK_IMAGE_TILING_LINEAR却没有清除(pass1的清除),则结果是正确的!

我犯了什么错误?

编辑: 我添加了一些代码,如何在渲染循环中更改纹理的障碍。

编辑: 我在创建渲染过程时设置依赖项,如下所示

  VkSubpassDependency subpassDependency[2];
  subpassDependency[0].srcSubpass = VK_SUBPASS_EXTERNAL;
  subpassDependency[0].dstSubpass = 0;
  subpassDependency[0].srcStageMask = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;
  subpassDependency[0].dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
  subpassDependency[0].srcAccessMask = VK_ACCESS_SHADER_READ_BIT;
  subpassDependency[0].dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
  subpassDependency[0].dependencyFlags = VK_DEPENDENCY_BY_REGION_BIT;
  //
  subpassDependency[1].srcSubpass = 0;
  subpassDependency[1].dstSubpass = VK_SUBPASS_EXTERNAL;
  subpassDependency[1].srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
  subpassDependency[1].dstStageMask = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;
  subpassDependency[1].srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
  subpassDependency[1].dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
  subpassDependency[1].dependencyFlags = VK_DEPENDENCY_BY_REGION_BIT;

但没有任何改变。

0 个答案:

没有答案