使用 Vulkan + OpenXR,在任务中得到奇怪的透明度结果(PCVR 中不存在)

Using Vulkan + OpenXR, getting strange transparency results on quest (not present in PCVR)

长话短说,alpha 值的行为非常奇怪:在 1.0 到 0.5 之间合理过渡,但从 0.5 到 0.0 从半不透明-{color} 过渡到不透明-黑色。

^ 这是我的字体渲染器(从传送到 iphone 的任务中捕获),替换了着色器。它 应该 显示红色四边形,而不是显示字体,根据片段 x 坐标的 sin 淡入和淡出透明度。我不知道“黑色”是从哪里来的。这是着色器:

#version 450
#extension GL_KHR_vulkan_glsl : enable
#extension GL_ARB_separate_shader_objects : enable
#extension GL_EXT_multiview : enable
layout(set = 0, binding = 2) uniform sampler2D colorSampler;
layout(location = 0) in vec2 fragUV;
layout(location = 0) out vec4 outColor;
void main()
{
  float x = (sin(gl_FragCoord.x/20.0)+1.0)/2.0;
  outColor = vec4(1.0,0.0,0.0,x)
}

我的管道混合配置是:

VkPipelineColorBlendAttachmentState colorBlendAttachment = {};
  //alpha blend
  colorBlendAttachment.colorWriteMask =
    VK_COLOR_COMPONENT_R_BIT |
    VK_COLOR_COMPONENT_G_BIT |
    VK_COLOR_COMPONENT_B_BIT |
    VK_COLOR_COMPONENT_A_BIT |
    0;
  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;

VkPipelineColorBlendStateCreateInfo colorBlendInfo = {};

  colorBlendInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO;
  colorBlendInfo.logicOpEnable = VK_FALSE;
  colorBlendInfo.logicOp = VK_LOGIC_OP_COPY;
  colorBlendInfo.attachmentCount = 1;
  colorBlendInfo.pAttachments = &colorBlendAttachment;
  colorBlendInfo.blendConstants[0] = 0.0f;
  colorBlendInfo.blendConstants[1] = 0.0f;
  colorBlendInfo.blendConstants[2] = 0.0f;
  colorBlendInfo.blendConstants[3] = 0.0f;

最古怪的一点是,当来自 pcvr 的 运行 时,这完美地(如预期的那样)工作(两者之间的代码路径没有重大差异:相同的 spirv,相同的管道生成等...)

您在 colorWriteMask 中启用了 alpha 写入,并且 (1 * source + 0 * destination) alpha 混合方程,因此您要用文本不透明度覆盖帧缓冲区的 alpha。交换链的 compositeAlpha 为 VK_COMPOSITE_ALPHA_PRE/POST_MULTIPLIED_BIT_KHR,合成器将你的交换链图像与表面背后的内容混合——并且由于你将低于 1 的 alpha 写入文本应该位于的图像,合成器认为这些区域是半透明的。通过从混合参数中的 colorWriteMask 中删除 alpha 位,或通过 (0 * source + 1 * destination) alpha 混合方程,或使用 VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR swapchain compositeAlpha,您应该在绘制到交换链图像时禁用写入 alpha 通道如果目标表面的 VkSurfaceCapabilitiesKHR 声明其可用性(这也被推荐用于可能更快的合成)。