Как я могу использовать несколько неизменяемых семплеров в vulkan?
Я хочу использовать несколько неизменяемых семплеров в одной команде рендеринга в vulkan, но я не знаю, как выбрать их во фрагментном шейдере. Чтобы понять, чего я хочу и что я имею в виду, я начинаю с объяснения рабочей версии.
Я написал конвейер рендеринга для нескольких текстур, используя vulkan. Первая версия, которая поддерживала только текстуры ARGB (VK_FORMAT_R8G8B8A8_UNORM), работает нормально.
Для записи буфера команд я сделал следующее:
- vkBeginCommandBuffer
- vkCmdBeginRenderPass
- vkCmdBindPipeline
- для каждой текстуры
- vkCmdBindVertexBuffers
- vkCmdBindIndexBuffer
- vkCmdBindDescriptorSets (устанавливает два ubos и вид изображения)
- vkCmdDrawIndexed
- vkCmdEndRenderPass
- vkEndCommandBuffer
Каждая текстура нарисована правильно, потому что в 4.3. Я привязал его изображение к фрагментному шейдеру, который включал семплер текстуры.
Итак, теперь о части, с которой я борюсь:
Использование текстур ARGB очень неэффективно, если они часто обновляются. Поэтому я попытался использовать текстуры YCbCr, такие как I420, непосредственно в шейдере. Разобравшись, как их настроить, я заметил, что они должны использоваться в качестве неизменяемых семплеров (VkDescriptorSetLayoutBinding pImmutableSamplers), которые могут быть привязаны статически только при определении макета набора дескрипторов (vkCreateDescriptorSetLayout). Это означает, что использование одного макета набора дескрипторов снова и снова больше не работает. Верный?
Чтобы исправить это, я предоставил несколько макетов набора дескрипторов (vkCreatePipelineLayout) для графического конвейера (vkCreateGraphicsPipelines). Теперь я могу иметь одну привязку для каждой текстуры к конвейеру, что означает, что я могу иметь несколько неизменяемых семплеров, статически привязанных, без обмена. Пока все хорошо, но мой фрагментный шейдер использует только первый сэмплер (точнее, первый набор дескрипторов) для рендеринга вывода. Сначала я думал, что набор дескрипторов будет взят из vkCmdBindDescriptorSets, но ошибался.
Вот мой фрагментный шейдер:
#extension GL_ARB_separate_shader_objects : enable
layout(binding = 1) uniform sampler2DArray texSampler;
layout(binding = 2) uniform UniformBufferObject {
float alpha;
uint layer;
} ubo;
layout(location = 0) in vec2 fragTexCoord;
layout(location = 0) out vec4 outColor;
void main() {
vec4 color = texture(texSampler, vec3(fragTexCoord, ubo.layer));
outColor = vec4(color.rgb, color[3] * ubo.alpha);
}
Я уже понял, что можно предоставить набор для макета шейдера (например, layout (set=1, binding=1)), но мне нужно обновить этот набор в задаче рендеринга (для каждой текстуры), как я сделал со всеми другими привязками перед рисованием.
Какие-либо предложения? Какое здесь рекомендуемое решение?