Vulkan粒子系统透明度异常问题排查求助
粒子系统透明度异常问题排查求助
我正在修改同事开发的粒子系统,原本通过计算管线手动混合/设置像素进行渲染,现改为2D图形渲染方式,但遇到了奇怪的透明度问题:当粒子alpha值高于约0.2时,图像渲染正常;但低于该值时,粒子会显示为纯白色。
我已排查了多数可能的错误来源——确认已启用混合功能,混合操作配置如下:
VkPipelineColorBlendAttachmentState colorBlendAttachment{}; colorBlendAttachment.colorWriteMask = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT; colorBlendAttachment.blendEnable = VK_TRUE; colorBlendAttachment.srcColorBlendFactor = VK_BLEND_FACTOR_SRC_ALPHA; colorBlendAttachment.dstColorBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA; colorBlendAttachment.colorBlendOp = VK_BLEND_OP_ADD; colorBlendAttachment.srcAlphaBlendFactor = VK_BLEND_FACTOR_ONE; colorBlendAttachment.dstAlphaBlendFactor = VK_BLEND_FACTOR_ZERO; colorBlendAttachment.alphaBlendOp = VK_BLEND_OP_ADD;
渲染后的异常效果:
粒子纹理在GIMP中显示正常,调整片段着色器以显示alpha值时,结果符合预期:
顶点着色器和片段着色器代码如下:
#version 450 layout(binding = 0) uniform UniformBufferObject { mat4 proj; } ubo; layout(location = 0) in vec2 inPosition; layout(location = 1) in vec2 inTexCoord; layout(location = 2) in vec4 inColor; layout(location = 0) out vec4 fragColor; layout(location = 1) out vec2 fragTexCoord; void main() { gl_Position = ubo.proj * vec4(inPosition, 0.0, 1.0); fragColor = inColor; fragTexCoord = inTexCoord; } //---------------------------------------- #version 450 layout(binding = 1) uniform sampler2D texSampler; layout(location = 0) in vec4 fragColor; layout(location = 1) in vec2 fragTexCoord; layout(location = 0) out vec4 outColor; void main() { outColor = texture(texSampler, fragTexCoord); }
渲染代码片段:
CommandBufferBeginInfo const beginInfo{}; VK_CHECK_RESULT(vkBeginCommandBuffer(vkCommandBuffer_, &beginInfo)); RenderPassBeginInfo renderPassInfo{}; renderPassInfo.renderPass = *renderPass_; renderPassInfo.framebuffer = framebuffer_->getVulkanFramebuffer(); renderPassInfo.renderArea.offset = { 0, 0 }; renderPassInfo.renderArea.extent.width = uint32_t(windowSize_.x); renderPassInfo.renderArea.extent.height = uint32_t(windowSize_.y); constexpr VkClearValue clearColor = { {{0.0f, 0.0f, 0.0f, 1.0f}} }; renderPassInfo.clearValueCount = 1; renderPassInfo.pClearValues = &clearColor; vkCmdBeginRenderPass(vkCommandBuffer_, &renderPassInfo, VK_SUBPASS_CONTENTS_INLINE); vkCmdBindPipeline(vkCommandBuffer_, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipeline_); const VkBuffer vertexBuffers[] = { backgroundVertexBuffer_->getVulkanBuffer(), particleVertexBuffer_->getVulkanBuffer() }; const VkDescriptorSet descriptorSets[] = { *backgroundDescriptorSet_, *particleDescriptorSet_ }; constexpr VkDeviceSize offsets[] = { 0 }; vkCmdBindIndexBuffer(vkCommandBuffer_, indexBuffer_->getVulkanBuffer(), 0, VK_INDEX_TYPE_UINT16); // Draw Background vkCmdBindVertexBuffers(vkCommandBuffer_, 0, 1, &vertexBuffers[0], offsets); vkCmdBindDescriptorSets(vkCommandBuffer_, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipelineLayout_, 0, 1, &descriptorSets[0], 0, nullptr); vkCmdDrawIndexed(vkCommandBuffer_, uint32_t(std::size(Quad::indices)), 1, 0, 0, 0); // Draw particles. vkCmdBindVertexBuffers(vkCommandBuffer_, 0, 1, &vertexBuffers[1], offsets); vkCmdBindDescriptorSets(vkCommandBuffer_, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipelineLayout_, 0, 1, &descriptorSets[1], 0, nullptr); for (auto i = 0u; i < effect_->getParticleCount(); ++i) { vkCmdDrawIndexed(vkCommandBuffer_, uint32_t(std::size(Quad::indices)), 1, 0, int32_t(i) * 4, 0); } vkCmdEndRenderPass(vkCommandBuffer_); VK_CHECK_RESULT(vkEndCommandBuffer(vkCommandBuffer_));
当前没有使用深度缓冲,也没有深度子通道,但这似乎无法解释我看到的现象。不确定还有哪些可能的原因,恳请提供排查建议。
内容的提问来源于stack exchange,提问作者jg_at_pharos
相关产品推荐
相关产品推荐

