Graphics 帧缓冲区和交换链到底是什么?

Graphics 帧缓冲区和交换链到底是什么?,graphics,3d,vulkan,Graphics,3d,Vulkan,所以我对帧缓冲区的概念有点困惑。我做过研究,但我总是发现不同的定义,通常有以下两种: 帧缓冲区是多个不同图像的数组。但这个定义,或者至少对我来说,听起来更像swapchain是什么:一系列帧缓冲区 帧缓冲区是构成单个图像的像素数组,有点像位图(但从我读到的内容来看,它可以包含比颜色更多的信息,比如深度值和内容),当位图被管道填充时,它会排队等待显示。这对我来说更有意义,因为swapchain也有意义:帧缓冲区的集合,因此可以有一个用作渲染目标,另一个用于表示,在双缓冲的情况下,swapcha

所以我对帧缓冲区的概念有点困惑。我做过研究,但我总是发现不同的定义,通常有以下两种:

  • 帧缓冲区是多个不同图像的数组。但这个定义,或者至少对我来说,听起来更像swapchain是什么:一系列帧缓冲区

  • 帧缓冲区是构成单个图像的像素数组,有点像位图(但从我读到的内容来看,它可以包含比颜色更多的信息,比如深度值和内容),当位图被管道填充时,它会排队等待显示。这对我来说更有意义,因为swapchain也有意义:帧缓冲区的集合,因此可以有一个用作渲染目标,另一个用于表示,在双缓冲的情况下,swapchain使用正确的时间来处理swapchain,以提高帧速率稳定性

以下哪项是正确的?因为我厌倦了每次我寻找一点信息时听到不同的东西


请记住,我正在学习的Vulkan完全没有图形过期功能(我知道不推荐使用)因此,我现在对这些概念比代码更感兴趣

它的历史演变有点问题

从历史上看,帧缓冲区是一个帧的一切,它在很大程度上是不透明的。这包括颜色缓冲区、深度缓冲区(,以及Vulkan中新出现的输入缓冲区)

历史上也没有太多的预处理和计算,事情都被绑定到一个屏幕上。因此与swapchain有联系。但是Vulkan很容易无头,所以这是没有意义的


因此,有时“帧缓冲区”可交换地用于“颜色缓冲区交换链图像”。但通常(特别是Vulkan对象)表示“需要特别考虑的帧缓冲区”;不仅是颜色缓冲区,而且如果它们最终出现在屏幕上或不在屏幕上,则不受影响。

在Vulkan的说法中,
VkFramebuffer
是一个容器,它引用可以用作渲染过程实例中附件的图像。渲染过程附件是渲染操作的目标。因此,如果要渲染到特定的图像,在某个时刻,需要将其放入
VkFramebuffer
并调用
vkCmdBeginRenderPass

交换链与帧缓冲区无关(技术上)。交换链是一系列您不拥有的图像。您可以要求显示引擎借用其中一个图像一段时间,在此期间,您可以对其进行渲染或swapchain允许您对其图像执行的任何其他操作。一段时间后,您可以告诉显示引擎显示您在特定显示器上使用过的图像,在此之后,除非再次借用该交换链图像,否则您将无法使用该图像

因此,尽管他们都有“一系列的图像”,但他们一点也不相似。帧缓冲区在渲染操作期间渲染到其所有图像(符合渲染过程的子过程附件用法)。您不需要同时借用swapchain的所有图像。一次只能借用一个(每个显示曲面一个)


现在,由于swapchain图像只能以显示引擎允许的方式使用,并且显示引擎允许您使用它的唯一方式是作为颜色附件,如果您确实希望在显示设备中看到结果(Vulkan不需要),swapchain中的图像将在某个时刻被放入
VkFramebuffer

不久前,我就在你现在的位置,所以也许我可以从noob的角度来解释它

当您准备使用Vulkan在GPU上渲染帧时,需要在GPU上的某个内存块中执行这些绘制操作。这些内存块称为图像。要在GPU上渲染,可以使用着色器程序。这些着色器程序需要知道它们将绘制到哪个内存块中——换句话说,绘制到哪个图像中。着色器可以绘制多个图像。在片段着色器中,它类似于:

layout(location 0) out vec4 imgA;
layout(location 1) out vec4 imgB;
vec4
,在这种情况下,是图像的每个像素具有的通道数量(例如,RGBA)。因此,您将向每个像素写入4个组件。每个
位置
表示不同的图像

因此,每个(片段)着色器可以写入一个或多个图像。但是,着色器也可以读取传递给它们的图像。通常将图像构建为一系列步骤,然后将这些步骤合成在一起。想象一下Adobe Photoshop图像,它由一系列层组成。不同的过程/渲染过程/子过程表示新的层或效果。如果片段着色器写入1个输出图像,则这就像1个新层。如果它写入2个输出图像,那么它就像该着色器的2个层,依此类推。这些图像可以作为输入传递给同一帧内的后续着色器。在框架构建过程的最后一步,您将获取所有先前生成的图像,并将它们合并为最终图像,然后(通常)通过将其写入交换链图像来将其显示到屏幕上

因此,
VkFramebuffer
是一种类似于列表的结构,用于组织我们将提供给着色器用于其绘制操作的图像集。其中一些图像将用作输入,其他图像将用作输出,等等

当您创建
VkRenderpass
对象时,您告诉它将有X个数量的输入图像、彩色图像、深度图像等,但您不告诉它要使用哪些实际图像(例如,用于这些图像的实际RAM)。
VkFramebuffer
是将实际图像(内存/RAM)绑定到
VkRenderpass
的地方

因此,
VkFramebuffer
是一种将实际图像绑定到