帧缓冲区和交换链到底是什么?
What exactly are framebuffers and swapchains?
所以我对帧缓冲区的概念有点困惑。我已经完成了研究,但总能找到不同的定义,通常是这两个:
帧缓冲区是多个不同图像的数组。但是这个定义,或者至少对我来说,听起来更像是交换链:一系列帧缓冲区。
帧缓冲区是形成单个图像的像素数组,有点像位图(但根据我的阅读,它可以包含比颜色更多的信息,如深度值和东西),当该位图被管道填充时,它会排队等待呈现。这对我来说更有意义,因为这样交换链也有意义:帧缓冲区的集合,所以可以有一个用作渲染目标,另一个用于呈现,在这种情况下双缓冲,交换链处理以正确的时间交换它们以提高帧率稳定性。
以下哪个是正确的?因为我厌倦了每次查找一点信息都会听到不同的声音。
请记住,我正在学习 Vulkan,完全没有图形经验(我知道不推荐这样做)所以我现在对概念比代码更感兴趣.
它在历史上是如何演变的有点问题。
从历史上看,帧缓冲区就是帧的一切,而且它在很大程度上是不透明的。这包括颜色缓冲区、深度缓冲区(以及 Vulkan 中的新功能:输入缓冲区)。
而且从历史上看,没有那么多的预处理和计算,而且一切都与屏幕相关联。因此与交换链的关联。但是 Vulkan 很容易成为无头的,所以这没有意义。
所以有时“帧缓冲区”可互换地用于“颜色缓冲区交换链图像”。但通常(特别是 Vulkan 对象)意味着“需要特别考虑的框架缓冲区”;不仅是颜色缓冲区,而且不管它们是否最终出现在屏幕上。
用 Vulkan 的说法,VkFramebuffer
是一个引用图像的容器,这些图像可用作渲染过程实例中的附件。渲染过程附件是渲染操作的目的地。因此,如果您想渲染特定图像,在某些时候,您需要将其推入 VkFramebuffer
并调用 vkCmdBeginRenderPass
.
交换链与帧缓冲区无关(技术上)。交换链是您 不拥有 的一系列图像。您可以要求显示引擎借用其中一张图像一段时间,在此期间您可以对其进行渲染或交换链允许您对其图像进行的任何其他操作。一段时间后,您可以告诉显示引擎将您使用过的图像显示给特定的显示器,之后您将无法使用该交换链图像,直到您再次借用它。
因此,虽然他们都有“一系列图像”,但他们绝无相似之处。帧缓冲区在渲染操作期间渲染所有图像(根据渲染通道的子通道附件用法)。您不需要同时借用 all 个交换链的图像。您一次只能借一个(每个显示表面一个)。
现在,由于交换链图像只能以显示引擎允许的方式使用,并且显示引擎需要允许您使用它的唯一方式是一个颜色附件,如果你真的想在显示设备上看到结果(Vulkan 不需要),来自交换链的图像将在某个时候以 VkFramebuffer
结束。
不久前我也在你现在的位置,所以也许我可以从菜鸟的角度解释一下。
当您准备使用 Vulkan 在 GPU 上渲染帧时,您需要将这些绘图操作执行到 GPU 上的某个内存块中。这些内存块称为图像。要在 GPU 上渲染事物,您可以使用着色器程序。这些着色器程序需要知道它们将绘制到哪个内存块中——换句话说,绘制到哪个图像中。着色器可以绘制到多个图像。在片段着色器中,它将类似于:
layout(location 0) out vec4 imgA;
layout(location 1) out vec4 imgB;
vec4
,在这种情况下,是图像的每个像素具有的通道数量(例如 RGBA)。因此,您将为每个像素写入 4 个分量。每个 location
表示不同的图像。
因此,每个(片段)着色器可以写入 1 个或多个图像。但是,着色器也可以从传递给它们的图像中读取。这对于将图像构建为一系列步骤非常有用,您稍后可以将它们组合在一起。想象一下像 Adobe Photoshop 图像这样的东西,它由一系列图层组成。不同的 Passes/Renderpasses/Subpasses kindof 代表一个新的图层或效果。如果片段着色器写入 1 个输出图像,则相当于 1 个新层。如果它写入 2 个输出图像,那么它就像那个着色器的 2 个层,依此类推。这些图像可以作为输入传递给同一帧内的后续着色器。在框架构建过程的最后一步,您抓取所有以前制作的图像并将它们组合成最终图像,并且(通常)通过将其写入交换链图像来将其显示在屏幕上。
因此,VkFramebuffer
是一个类似于列表的结构,用于组织我们将提供给着色器进行绘图操作的图像集。其中一些图像将用作输入,其他图像将用作输出等。
当你创建一个VkRenderpass
对象时,你告诉它会有X数量的输入图像、彩色图像、深度图像等。但你没有告诉它哪个 要使用的实际图像(例如,用于这些图像的实际 RAM)。 VkFramebuffer
是将实际图像 (Memory/RAM) 绑定到 VkRenderpass
.
的地方
因此,VkFramebuffer
是一种将实际图像绑定到 VkRenderpass
中的占位符的方法。
交换链是 GPU 上的一系列预制内存块(图像)。它具有特殊的品质,写入它就像直接写入 Window 表面(有点)。因为它们只是图像(虽然有特殊要求),它们可以绑定到 VkFramebuffers
,从而由着色器写入。
所以我对帧缓冲区的概念有点困惑。我已经完成了研究,但总能找到不同的定义,通常是这两个:
帧缓冲区是多个不同图像的数组。但是这个定义,或者至少对我来说,听起来更像是交换链:一系列帧缓冲区。
帧缓冲区是形成单个图像的像素数组,有点像位图(但根据我的阅读,它可以包含比颜色更多的信息,如深度值和东西),当该位图被管道填充时,它会排队等待呈现。这对我来说更有意义,因为这样交换链也有意义:帧缓冲区的集合,所以可以有一个用作渲染目标,另一个用于呈现,在这种情况下双缓冲,交换链处理以正确的时间交换它们以提高帧率稳定性。
以下哪个是正确的?因为我厌倦了每次查找一点信息都会听到不同的声音。
请记住,我正在学习 Vulkan,完全没有图形经验(我知道不推荐这样做)所以我现在对概念比代码更感兴趣.
它在历史上是如何演变的有点问题。
从历史上看,帧缓冲区就是帧的一切,而且它在很大程度上是不透明的。这包括颜色缓冲区、深度缓冲区(以及 Vulkan 中的新功能:输入缓冲区)。
而且从历史上看,没有那么多的预处理和计算,而且一切都与屏幕相关联。因此与交换链的关联。但是 Vulkan 很容易成为无头的,所以这没有意义。
所以有时“帧缓冲区”可互换地用于“颜色缓冲区交换链图像”。但通常(特别是 Vulkan 对象)意味着“需要特别考虑的框架缓冲区”;不仅是颜色缓冲区,而且不管它们是否最终出现在屏幕上。
用 Vulkan 的说法,VkFramebuffer
是一个引用图像的容器,这些图像可用作渲染过程实例中的附件。渲染过程附件是渲染操作的目的地。因此,如果您想渲染特定图像,在某些时候,您需要将其推入 VkFramebuffer
并调用 vkCmdBeginRenderPass
.
交换链与帧缓冲区无关(技术上)。交换链是您 不拥有 的一系列图像。您可以要求显示引擎借用其中一张图像一段时间,在此期间您可以对其进行渲染或交换链允许您对其图像进行的任何其他操作。一段时间后,您可以告诉显示引擎将您使用过的图像显示给特定的显示器,之后您将无法使用该交换链图像,直到您再次借用它。
因此,虽然他们都有“一系列图像”,但他们绝无相似之处。帧缓冲区在渲染操作期间渲染所有图像(根据渲染通道的子通道附件用法)。您不需要同时借用 all 个交换链的图像。您一次只能借一个(每个显示表面一个)。
现在,由于交换链图像只能以显示引擎允许的方式使用,并且显示引擎需要允许您使用它的唯一方式是一个颜色附件,如果你真的想在显示设备上看到结果(Vulkan 不需要),来自交换链的图像将在某个时候以 VkFramebuffer
结束。
不久前我也在你现在的位置,所以也许我可以从菜鸟的角度解释一下。
当您准备使用 Vulkan 在 GPU 上渲染帧时,您需要将这些绘图操作执行到 GPU 上的某个内存块中。这些内存块称为图像。要在 GPU 上渲染事物,您可以使用着色器程序。这些着色器程序需要知道它们将绘制到哪个内存块中——换句话说,绘制到哪个图像中。着色器可以绘制到多个图像。在片段着色器中,它将类似于:
layout(location 0) out vec4 imgA;
layout(location 1) out vec4 imgB;
vec4
,在这种情况下,是图像的每个像素具有的通道数量(例如 RGBA)。因此,您将为每个像素写入 4 个分量。每个 location
表示不同的图像。
因此,每个(片段)着色器可以写入 1 个或多个图像。但是,着色器也可以从传递给它们的图像中读取。这对于将图像构建为一系列步骤非常有用,您稍后可以将它们组合在一起。想象一下像 Adobe Photoshop 图像这样的东西,它由一系列图层组成。不同的 Passes/Renderpasses/Subpasses kindof 代表一个新的图层或效果。如果片段着色器写入 1 个输出图像,则相当于 1 个新层。如果它写入 2 个输出图像,那么它就像那个着色器的 2 个层,依此类推。这些图像可以作为输入传递给同一帧内的后续着色器。在框架构建过程的最后一步,您抓取所有以前制作的图像并将它们组合成最终图像,并且(通常)通过将其写入交换链图像来将其显示在屏幕上。
因此,VkFramebuffer
是一个类似于列表的结构,用于组织我们将提供给着色器进行绘图操作的图像集。其中一些图像将用作输入,其他图像将用作输出等。
当你创建一个VkRenderpass
对象时,你告诉它会有X数量的输入图像、彩色图像、深度图像等。但你没有告诉它哪个 要使用的实际图像(例如,用于这些图像的实际 RAM)。 VkFramebuffer
是将实际图像 (Memory/RAM) 绑定到 VkRenderpass
.
因此,VkFramebuffer
是一种将实际图像绑定到 VkRenderpass
中的占位符的方法。
交换链是 GPU 上的一系列预制内存块(图像)。它具有特殊的品质,写入它就像直接写入 Window 表面(有点)。因为它们只是图像(虽然有特殊要求),它们可以绑定到 VkFramebuffers
,从而由着色器写入。