Vulkan:从屏幕外缓冲区呈现给交换链
Vulkan: Present to Swapchain from Offscreen Buffer
我正在尝试在 Vulkan 中制作延迟渲染器,因此我需要将延迟渲染帧缓冲区的结果图像呈现到屏幕上,但我不知道具体如何。
我的想法是:
在我的帧缓冲区的末尾添加从交换链获取的图像,并添加一个子通道来渲染最终结果。
但是,我应该创建我的帧缓冲区的多个副本(每个交换链图像一个副本),还是删除帧缓冲区和渲染通道并在每一帧重新创建它们,同时将最后一个图像设置为交换链的图像。
还有其他方法吗?
我是否应该制作另一组管道、渲染通道和帧缓冲区以将结果复制到交换链的图像?
我试着查看 SaschaWillems 的示例,我认为他正在使用双渲染通道方法,但我想知道是否有其他方法可以做到这一点。
如果你想考虑额外的副本,有多个选项,但假设你想将最终图像直接渲染到交换链中,image,有两个基本选项。
首先,如果您不想使用多个子通道,则在每一帧上您将为每个通道使用一个帧缓冲区。最终的帧缓冲区将使用该帧的交换链图像作为其颜色附件。对于每个帧缓冲区,您将使用不同的渲染通道,因为帧缓冲区附件 counts/formats/etc。可能会有所不同。您可以预先创建所有渲染通道和非交换链帧缓冲区,并在每个帧上重复使用它们。
对于交换链帧缓冲区,在您第一次创建交换链时为每个交换链图像创建一个,然后在每个帧上使用与该帧的交换链图像匹配的帧缓冲区。尽量避免一直销毁和重建对象;取而代之的是缓存和重用它们——它们是不同对象的原因是允许您在多次使用中分摊创建成本。 (单子通道渲染通道的创建成本应该很低,但至少在一种架构上,帧缓冲区的创建成本很高,而多子通道渲染通道在某些架构上也可能很昂贵。)
其次,如果您想将整个事情作为具有多个子通道的单个渲染通道来完成,以利用某些 GPU 上的图块内存,则过程非常相似。您将有一个渲染通道,但每个子通道对应于第一个选项中的一个渲染通道,并且将使用类似的附件。因为您只有一个渲染通道,所以每帧也只有一个帧缓冲区。但是,由于最终的子通道将写入交换链图像,因此您需要为每个交换链图像创建一个单独的帧缓冲区对象;除了交换链图像附件外,所有这些帧缓冲区都是相同的。
我正在尝试在 Vulkan 中制作延迟渲染器,因此我需要将延迟渲染帧缓冲区的结果图像呈现到屏幕上,但我不知道具体如何。
我的想法是: 在我的帧缓冲区的末尾添加从交换链获取的图像,并添加一个子通道来渲染最终结果。 但是,我应该创建我的帧缓冲区的多个副本(每个交换链图像一个副本),还是删除帧缓冲区和渲染通道并在每一帧重新创建它们,同时将最后一个图像设置为交换链的图像。
还有其他方法吗?
我是否应该制作另一组管道、渲染通道和帧缓冲区以将结果复制到交换链的图像?
我试着查看 SaschaWillems 的示例,我认为他正在使用双渲染通道方法,但我想知道是否有其他方法可以做到这一点。
如果你想考虑额外的副本,有多个选项,但假设你想将最终图像直接渲染到交换链中,image,有两个基本选项。
首先,如果您不想使用多个子通道,则在每一帧上您将为每个通道使用一个帧缓冲区。最终的帧缓冲区将使用该帧的交换链图像作为其颜色附件。对于每个帧缓冲区,您将使用不同的渲染通道,因为帧缓冲区附件 counts/formats/etc。可能会有所不同。您可以预先创建所有渲染通道和非交换链帧缓冲区,并在每个帧上重复使用它们。
对于交换链帧缓冲区,在您第一次创建交换链时为每个交换链图像创建一个,然后在每个帧上使用与该帧的交换链图像匹配的帧缓冲区。尽量避免一直销毁和重建对象;取而代之的是缓存和重用它们——它们是不同对象的原因是允许您在多次使用中分摊创建成本。 (单子通道渲染通道的创建成本应该很低,但至少在一种架构上,帧缓冲区的创建成本很高,而多子通道渲染通道在某些架构上也可能很昂贵。)
其次,如果您想将整个事情作为具有多个子通道的单个渲染通道来完成,以利用某些 GPU 上的图块内存,则过程非常相似。您将有一个渲染通道,但每个子通道对应于第一个选项中的一个渲染通道,并且将使用类似的附件。因为您只有一个渲染通道,所以每帧也只有一个帧缓冲区。但是,由于最终的子通道将写入交换链图像,因此您需要为每个交换链图像创建一个单独的帧缓冲区对象;除了交换链图像附件外,所有这些帧缓冲区都是相同的。