ND-Buffer和G-Buffer之间有什么区别?

7
我在WebGL方面是个新手。我在几篇文章中读到关于ND-Buffers和G-Buffers的内容,似乎这是WebGL开发的战略选择。
ND-Buffers和G-Buffers与渲染管道有什么关系?ND-Buffers只用于前向渲染,而G-Buffers只用于延迟渲染吗?
提供一个JavaScript代码示例来实现两者的区别对我理解会很有帮助。

你能分享帖子的链接吗? - Kirill Dmitrenko
这里有一个很棒的资源:(http://upcommons.upc.edu/bitstream/handle/2117/82591/114624.pdf) - deblocker
3个回答

10

G缓冲区只是通常在延迟渲染中使用的一组缓冲区。

维基百科提供了一个很好的例子,展示了通常在g-buffer中找到的数据类型。

漫反射颜色信息。

Diffuse color

世界空间或屏幕空间法线

World space normals

深度缓冲区 / Z-缓冲区

Depth buffer

这三个缓冲区的组合被称为“g-buffer”。从几何和材料数据生成这三个缓冲区,然后可以运行着色器将它们组合以生成最终图像。

Final image

实际上,g-buffer 中包含的内容取决于特定引擎/渲染器。例如,Unity3D 延迟渲染 之一包含漫反射颜色、遮挡、高光颜色、粗糙度、法线、深度、模板、发射、光照、光照贴图和反射概率。

ND 缓冲区只是“法线深度缓冲区”的简称,它是通常在典型 g-buffer 中找到的内容的子集。

至于一个样例,可能对 SO 来说有点大,但这里有 一篇关于 WebGL 中延迟渲染的文章(MDN)


4
选择渲染路径是3D渲染器的一个重要架构决策,无论使用哪种API。该选择严重依赖于渲染器必须支持的功能集和其性能要求。
其中相当一部分功能集包括所谓的屏幕空间特效。这意味着我们将有关屏幕每个像素的一些关键数据渲染到一组渲染缓冲区中,然后使用该数据(而不是几何形状)来计算帧所需的一些新数据。环境光遮蔽就是这样一个很好的例子。基于像素的某些空间值,我们计算出一个“掩码”,以后可以用来适当地着色每个像素。
此外,还有一个渲染过程几乎完全依赖于屏幕空间计算,那就是延迟着色。这就是G-buffer的用处。所有计算像素颜色所需的数据都被渲染到G-buffer中:一组存储该数据的渲染缓冲区。数据本身(因此G-buffer的渲染缓冲区的含义)可能不同:漫反射分量,高光分量,亮度,法向量,位置,深度等。作为渲染帧的一部分,现代延迟着色引擎使用屏幕空间环境光遮蔽(SSAO),它使用来自多个G-buffer的渲染缓冲区的数据(通常,它们是位置、法向量和深度)。
关于ND-buffer。在我看来,这不是一个广泛使用的术语(谷歌除了这个问题之外没有找到任何相关信息)。我认为ND代表法线-深度。它们只是特定算法和效果(在论文中是SSAO)的G-buffer的特例。
因此,使用G-buffer(和ND-buffer作为G-buffer的子集)取决于您正在实现的着色算法和效果。但所有的屏幕空间计算都需要某种形式的G-buffer。

P.S. 你提供的论文存在一个错误。作者将在GLES 2.0上实现ND缓冲区的能力列为该方法的优点。然而,这实际上是不可能的,因为GLES 2.0没有深度纹理(它们已添加到OES_depth_texture扩展中)。


我认为说GLES 2.0支持这个功能并不准确。就所有实际目的而言,大多数支持GLES 2.0的设备都支持所有必需的扩展。也许他应该更清楚地说GLES 2.0与该扩展一起使用,但我怀疑他有意忘记提到这一点。 - gman
OES_depth_texture确实可以使开发变得更简单,但是D缓冲器也可以通过写入RGB纹理附件来重建,尽管这需要进行一些额外的计算来完成相同的工作。也许唯一有点困惑的是,并没有类似于“OES_normal_texture”扩展来证明ND-buffer的存在?顺便说一句,我的意图并不是要批评这样一个美妙而热情的工作,这只是一个例子 :-) - deblocker
@deblocker 然而,可以将深度写入某些颜色附件,但GLES 2.0没有扩展最多只有8位RGBA,即4个值的32位(深度和三维法线)。这可能会导致渲染结果不佳。 - Kirill Dmitrenko

1
我希望在之前的回答中增加一些信息。
我在几篇关于WebGL开发的帖子中看到了对ND-Buffers和G-Buffers的讨论,似乎这是一种战略性的选择。
延迟渲染最重要的部分之一是平台是否支持MRT(多重渲染目标)。如果不支持MRT,您将无法在每次渲染之间共享着色器中的部分计算,并且还会强制您运行与"层"数量相同的渲染次数(在Unity 3D的情况下,可能高达11次?)。这可能会大大减慢程序的运行速度。
请查看以下问题以了解更多信息:Is deferred rendering/shading possible with OpenGL ES 2.0 ? WebGL不支持MRT,但它有扩展:https://www.khronos.org/registry/webgl/extensions/WEBGL_draw_buffers/

还有一个深度纹理的扩展: https://www.khronos.org/registry/webgl/extensions/WEBGL_depth_texture/

因此,使用延迟渲染技术是可能的,但其速度很难估计。


我会把这视为对我的关于移动设备的次要问题的明确回答。谢谢。 - deblocker

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接