如何 "blend" ImGui frame with scene rendering in Vulkan

How to "blend" ImGui frame with scene rendering in Vulkan

我不是 Vulkan 专家。我想知道如何在常规场景渲染的顶部呈现 Vulkan Frame(提交每帧记录的特定 commandBuffer 以绘制 UI 更改)。所以在这种情况下,我有两个渲染通道,一个用于场景,另一个用于 ImGui,还有两个 commandBuffers。在尝试发送这两个 commandBuffers 时,只显示最后一个,因为它们使用的是交换链图像。 我错过了什么? imgui pass 中的 frameBuffer 视图附件应该是 swapchainImage 吗?

如果您将场景和 UI 渲染分成不同的不同渲染通道,您需要告诉第一个渲染通道的颜色附件保留内容,第二个 UI 渲染通道加载颜色附件帧缓冲区的内容。

根据您的描述判断,loadOp 的第二个渲染通道已正确设置为 VK_ATTACHMENT_LOAD_OP_CLEAR,这会导致在您开始第二个渲染通道后立即使用当前清晰颜色清除帧缓冲区。

因此,在您的场景中,您需要在第一遍中存储内容,以确保它们不会因优化而被丢弃:

std::array<VkAttachmentDescription, 2> attachments = {};
// Attachment 0 = Color attachment
attachments[0].storeOp = VK_ATTACHMENT_STORE_OP_STORE;
...

并且在您的第二个渲染过程中,您需要将其设置为加载之前的内容:

std::array<VkAttachmentDescription, 2> attachments = {};
// Attachment 0 = Color attachment
attachments[0].loadOp = VK_ATTACHMENT_LOAD_OP_LOAD;
...

如果您提交多个命令缓冲区,您还需要通过使用适当的同步原语(例如信号量或管道屏障)来确保正确的命令顺序(例如,通过 renderpass 的子通道隐式)。

另一种可能更简单的方法(取决于您的设置)是简单地将 UI 渲染添加到与场景渲染相同的命令缓冲区。这样,您只需在场景几何体的顶部渲染 UI,而无需同步。尽管这可能不是所有用例的选项。或者您可以使用子通道而不是(重)渲染通道。