0

我想在 vulkan 的一个渲染命令中使用多个不可变采样器,但我不知道如何在片段着色器中选择它们。要了解我想要什么以及我的意思,我首先要解释工作版本。

我使用 vulkan 为多个纹理编写了一个渲染管道。第一个版本只支持 ARGB (VK_FORMAT_R8G8B8A8_UNORM) 纹理,工作正常。

为了记录命令缓冲区,我执行了以下操作:

  1. vkBeginCommandBuffer
  2. vkCmdBeginRenderPass
  3. vkCmdBindPipeline
  4. 对于每个纹理
    1. vkCmdBindVertexBuffers
    2. vkCmdBindIndexBuffer
    3. vkCmdBindDescriptorSets(设置两个 ubos 和图像视图)
    4. vkCmdDrawIndexed
  5. vkCmdEndRenderPass
  6. vkEndCommandBuffer

每个纹理都被正确绘制,因为在 4.3 中。我将它的图像视图绑定到包含纹理采样器的片段着色器。

所以现在到我正在努力的部分:

如果频繁更新,ARGB 纹理的使用效率非常低。所以我尝试直接在着色器中使用像 I420 这样的 YCbCr 纹理。在弄清楚如何设置它们之后,我注意到它们必须用作不可变采样器(VkDescriptorSetLayoutBinding pImmutableSamplers),只能在定义描述符集布局时静态绑定(vkCreateDescriptorSetLayout)。这意味着一遍又一遍地使用一个描述符集布局不​​再起作用。正确的?

为了解决这个问题,我为图形管道 (vkCreateGraphicsPipelines) 提供了多个描述符集布局 (vkCreatePipelineLayout)。现在,我能够将每个纹理绑定到管道,这意味着,我可以将多个不可变采样器静态绑定,从不交换。到目前为止一切都很好,但我的片段着色器只使用第一个采样器(准确地说,第一个描述符集)来渲染输出。起初我以为描述符集会取自 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)),但我需要在渲染任务中更新这个集合(每个纹理),就像我在绘制之前对所有其他绑定所做的那样。

有什么建议么?这里推荐的解决方案是什么?

4

0 回答 0