首页 > 解决方案 > 如何在 Vulkan 中将 ImGui 帧与场景渲染“混合”

问题描述

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

标签: vulkanimgui

解决方案


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

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

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

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;
...

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

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


推荐阅读