Использование Vulkan + OpenXR, получение странных результатов прозрачности в квесте (отсутствует в PCVR)

Короче говоря, альфа-значения ведут себя очень странно: разумно переходят от 1,0 к 0,5, но от 0,5 до 0,0 переходят от полупрозрачности-{цвет} к непрозрачно-черному.

^ это мой модуль рендеринга шрифтов (снятый из квеста, переданного на iphone) с замененным шейдером. Вместо того, чтобы отображать шрифт, он должен отображать красные квадраты, постепенно увеличивая и уменьшая прозрачность в соответствии с грехом координаты x фрагмента. Понятия не имею, откуда взялось "черное". Вот шейдер:

       #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, одно и то же поколение конвейера и т. Д.)

1 ответ

Решение

В вашем colorWriteMask включено альфа-запись и уравнение смешения (1 * источник + 0 * назначение) для альфа-канала, поэтому вы перезаписываете альфа-канал фреймбуфера с непрозрачностью текста. Когда композитный альфа цепочки подкачки имеет значение VK_COMPOSITE_ALPHA_PRE/POST_MULTIPLIED_BIT_KHR, композитор смешивает изображения вашей цепочки подкачки с тем, что находится за поверхностью - и поскольку вы записываете альфа-канал ниже 1 в изображение, где должен быть текст, композитор считает эти области полупрозрачными. Вы должны отключить запись альфа-канала при рисовании изображений в цепочке подкачки, удалив альфа-бит из colorWriteMask в параметрах смешения или с помощью уравнения альфа-смешения (0 * источник + 1 * назначение),или используйте VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR swapchain CompositeAlpha, если VkSurfaceCapabilitiesKHR целевой поверхности объявляет о своей доступности (что также рекомендуется для потенциально более быстрой композиции).

Другие вопросы по тегам