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

Kar*_*los 3 3d graphics vulkan

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

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

  • 帧缓冲区是形成单个图像的像素数组,有点像位图(但从我读到的内容来看,它可以包含比颜色更多的信息,例如深度值和其他内容),并且当该位图被填充时通过管道,它会排队等待呈现。这对我来说更有意义,因为交换链也有意义:一组帧缓冲区,因此可以有一个帧缓冲区用作渲染目标,另一个用于呈现(在双缓冲的情况下),并且交换链以正确的时间处理交换它们,以提高帧率稳定性

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

请记住,我正在学习 Vulkan,根本没有图形经验(我知道不推荐),所以我现在对概念比代码更感兴趣

Nic*_*las 6

用 Vulkan 的话说,aVkFramebuffer是一个引用图像的容器,这些图像可以用作渲染通道实例中的附件。渲染通道附件是渲染操作的目标。因此,如果您想渲染到特定图像,在某些时候,您需要将其推入 aVkFramebuffer并调用vkCmdBeginRenderPass.

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

因此,虽然他们都有“一系列图像”,但他们绝不相似。帧缓冲区在渲染操作期间渲染其所有图像(根据渲染通道的子通道附件用法)。您不需要同时借用交换链的所有图像。您一次只能借用一张(每个显示面一张)。

现在,由于交换链图像只能以显示引擎允许的方式使用,并且如果您确实想在显示中查看结果,则显示引擎允许使用它的唯一方式是作为颜色附件设备(Vulkan 不需要),来自交换链的图像将在VkFramebuffer某个时刻结束。


Des*_*ess 6

不久前我就在你现在的位置,所以也许我可以从菜鸟的角度解释一下。

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

layout(location 0) out vec4 imgA;
layout(location 1) out vec4 imgB;
Run Code Online (Sandbox Code Playgroud)

vec4在本例中, 是图像的每个像素具有的通道数(例如 RGBA)。因此,您需要向每个像素写入 4 个分量。每个都location意味着不同的图像。

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

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

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

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

交换链是 GPU 上一系列预制的内存块(图像)。它具有特殊的品质,写入它就像直接写入窗口表面(有点)。因为它们只是图像(尽管有特殊要求),所以它们可以绑定到VkFramebuffers,从而由着色器写入。