什么是深度帧缓冲区?

Posted

技术标签:

【中文标题】什么是深度帧缓冲区?【英文标题】:What is a deep frame buffer? 【发布时间】:2013-12-28 22:48:32 【问题描述】:

在实时图形应用程序中,我认为帧缓冲区是保存将在单个帧中显示的最终光栅化图像的内存。

对深度帧缓冲区的引用似乎暗示正在进行一些缓存(顶点和材质信息),但尚不清楚这些数据的用途或方式。

相对于标准帧缓冲区,深度帧缓冲区具体是什么?它的用途是什么?

谢谢。

【问题讨论】:

【参考方案1】:

Google 是你的朋友。

这可能意味着两件事:

    您存储的不仅仅是每个像素的 RGBA。例如,您可能要存储法线或其他光照信息,以便稍后重新光照。

    Interactive Cinematic Relighting with Global Illumination Deep Image Compositing

    每个像素存储了多个颜色和深度值。例如,这对于支持与订单无关的透明度很有用。

【讨论】:

非常感谢您简洁明了的回复。实际上,我确实为它做了相当长的网络搜索;我登陆了您建议的第一个站点,它谈到了一些关于深度帧缓冲区的内容,但并没有真正解释它们是什么。另外,这是我第一次听说“深度图像”,所以你的第二个建议可能特别有用。【参考方案2】:

z 缓冲区类似于颜色缓冲区,通常用于存储 3D 场景的“图像”,但它不是存储颜色信息(以 rgb 像素的 2D 数组的形式),而是存储距离相机到通过帧缓冲区的每个像素可见的对象。

传统上,z-buffer 只计算帧中任何给定像素的相机到 3D 中最近对象的距离。这种技术的好处是,如果 2 个图像已经用它们的 z 缓冲区渲染,那么它们可以使用 2D 程序重新组合,但是图像 A 中的像素位于来自图像 A 的像素“前面”图像“B”将在重新合成的图像之上合成。要确定这些像素是否在前面,我们可以使用存储在图像各自 z 缓冲区中的信息。例如,假设我们想在像素坐标 (100, 100) 处组合图像 A 和 B 的像素。如果存储在 z 缓冲区中坐标 (100, 100) 的距离(z 值)对于图像 A 是 9.13,对于图像 B 是 5.64,那么在重构的图像 C 中,在像素坐标 (100, 100) 处,我们将把来自图像 B 的像素(因为它对应于 3D 场景中的表面,该表面位于对象前面,通过图像 A 中的像素可见)。

现在这在对象不透明时效果很好,但在它们透明时效果不佳。因此,当对象是透明的(例如当我们渲染体积、云或透明表面层时),我们需要存储多个 z 值。另请注意,“不透明度”会随着体积对象的密度或透明层数的增加而变化。无论如何,只是说 deep imagedeep buffer 在技术上就像一个 z-buffer,但不是只存储一个深度或 z 值,它存储的不仅仅是一个深度值,但也存储对象在这些深度值中的每一个的不透明度。

一旦我们存储了这些信息,就可以在后期制作中正确(即准确地)重新组合 2 张或更多图像以及透明胶片。例如,如果您渲染 2 个云并且这些云在深度上重叠,那么它们的可见性将被正确地重新组合,就好像它们在同一个场景中一起渲染一样。

我们为什么要使用这种技术?通常是因为渲染包含体积元素的场景通常很慢。因此,最好将它们与场景中的其他对象分开渲染,这样如果您需要对实体对象进行调整,则无需再次重新渲染体积元素。

这种技术主要是由 Pixar 在他们开发和销售的渲染器 (Prman) 中流行起来的。 《阿凡达》(新西兰的 Weta Digital)是第一部大量使用深度合成的电影。

见:http://renderman.pixar.com/resources/current/rps/deepCompositing.html

这种技术的缺点:深度图像非常重。它需要为每个像素存储许多深度值(并且这些值存储为浮点数)。根据图像分辨率和场景深度复杂性,此类图像大于几百到几千兆字节的情况并不少见。您也可以正确地重新组合体积对象,但它们不会相互投射阴影,如果您在同一场景中一起渲染对象,您会得到这种阴影。这使得场景管理比平时稍微复杂一些,......但这通常会得到妥善处理。

很多此类信息都可以在scratchapixel.com 上找到(供将来参考)。

【讨论】:

哇,说的很详细,谢谢!我什至没有想过如何在 offline 渲染中使用帧缓冲区。所以我猜一个深帧缓冲区就像一个普通的缓冲区,但是在它的 z 缓冲区中存储了额外的信息(比如不透明度)? 我会要求从头开始的团队为此写一堂课。深度帧缓冲区确实类似于 z 缓冲区,但您存储了超过 1 个深度值,其中每个深度值“沿”像素存储,对应于该像素的相机光线从相机 (z = 0) 到相交的对象。在本周末查看他们的网站,您会看到有关此主题的课程(ps:如果您喜欢答案,请不要忘记投票;-)

以上是关于什么是深度帧缓冲区?的主要内容,如果未能解决你的问题,请参考以下文章

如何调试默认帧和深度缓冲区?

使用帧缓冲区将深度缓冲区渲染到纹理中

延迟渲染:在默认帧缓冲区中使用来自 Gbuffer 的深度缓冲区

WebGL:在带有深度模板纹理附件的帧缓冲区上未清除颜色

帧缓冲

在 OpenGL ES 中为帧缓冲区使用深度和模板渲染缓冲区附件