I am working on a 2d project with a Vulkan backend, and I had a setup working where I rendered sprites directly to the screen. These sprites had some pixels with an alpha of 0, and as expected, those areas weren’t drawn to the screen.
Now, I decided to switch the rendering model to render first to a fixed size attachment, then render that to the screen attachment in a later RenderPass, using a Combined Image Sampler Descriptor Set and a quad mapped to the four corners. As soon as I did that, the pixels in the sprites texture with alpha 0 started drawing as black pixels (as the actual rgba value there is [0, 0, 0, 0]) OVER the clear value, which it did not do before.
I’m stumped trying to fix this, as I use virtually the same code for creating the pipeline that renders to the new off-screen attachment. To be exact, the blend state is configured like this for both:
auto colorBlendAttachment = VkPipelineColorBlendAttachmentState{
.colorWriteMask = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT
| VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT,
.blendEnable = VK_TRUE,
.srcColorBlendFactor = VK_BLEND_FACTOR_SRC_ALPHA,
.dstColorBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA,
.colorBlendOp = VK_BLEND_OP_ADD,
.srcAlphaBlendFactor = VK_BLEND_FACTOR_ONE,
.dstAlphaBlendFactor = VK_BLEND_FACTOR_ZERO,
.alphaBlendOp = VK_BLEND_OP_ADD};
auto colorBlending = VkPipelineColorBlendStateCreateInfo{
.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,
.logicOpEnable = VK_FALSE,
.attachmentCount = 1,
.pAttachments = &colorBlendAttachment
};
The off-screen attachment is the same color format as the screen attachment: VK_FORMAT_B8G8R8A8_UNORM. In the subpass for the first RenderPass, the fixed size attachment goes from initial layout UNDEFINED, to final layout of SHADER_READ_ONLY_OPTIMAL, and is used in subpass where it’s rendered to as COLOR_ATTACHMENT_OPTIMAL, and it’s created with usage COLOR_ATTACHMENT and SAMPLED.
The LoadOp is Clear (to the red value [0.5, 0, 0, 1]) and the StoreOp is Store for drawing to the fixed size attachment.
I tried to see if the shaders even were getting the alpha data, so in the Fragment Shader for the pipeline rendering to the off-screen attachment I changed:
out_color = texture(in_texture, in_uv);
to
vec4 color = texture(in_texture, in_uv);
if (color.a == 0)
discard;
out_color = color;
and it discarded the otherwise black pixels (which makes sense, as they are [0, 0, 0, 0] in the texture).
I tried a similar route when rendering the off-screen attachment to the screen attachment
out_color = texture(in_texture, in_uv);
to
vec4 color = texture(in_texture, in_uv);
if (color.a == 0)
color = vec4(0.0, 1.0, 0.0, 1.0);
out_color = color;
and again, it now rendered the black, alpha == 0 pixels as green. So it seems that the alpha values are there, in both stages of rendering, but it’s just not blending.
Thanks for any insight and help, let me know if there’s any other information that is relevant I might have missed or forgotten!