我是 WebGL 的菜鸟。我读了几篇关于 ND-Buffers 和 G-Buffers 的文章,好像它是 WebGL 开发的战略选择。
ND-Buffers 和 G-Buffers 与渲染管线有何关系?ND-Buffers 仅用于前向渲染,G-Buffers 仅用于延迟渲染吗?
如何实现两者的 JavaScript 代码示例对我理解差异很有用。
我是 WebGL 的菜鸟。我读了几篇关于 ND-Buffers 和 G-Buffers 的文章,好像它是 WebGL 开发的战略选择。
ND-Buffers 和 G-Buffers 与渲染管线有何关系?ND-Buffers 仅用于前向渲染,G-Buffers 仅用于延迟渲染吗?
如何实现两者的 JavaScript 代码示例对我理解差异很有用。
G-Buffers 只是一组通常用于延迟渲染的缓冲区。
Wikipedia给出了一个很好的例子,说明了 g-buffer 中经常发现的那种数据
漫反射颜色信息
世界空间或屏幕空间法线
深度缓冲区/Z-缓冲区
这 3 个缓冲区的组合称为“g 缓冲区”
从几何体和材质数据生成这 3 个缓冲区,然后您可以运行着色器来组合它们以生成最终图像。
实际进入 g 缓冲区的内容取决于特定的引擎/渲染器。例如,Unity3D 的延迟渲染之一包含漫反射颜色、遮挡、镜面反射颜色、粗糙度、法线、深度、模板、发射、光照、光照贴图、反射概率。
ND 缓冲区仅代表“正常深度缓冲区”,这使其成为典型 g 缓冲区中通常发现的内容的子集。
至于一个对于 SO 来说可能太大的示例,但是在 MDN 上有一篇关于 WebGL 中的延迟渲染的文章
选择渲染路径是 3D 渲染器的主要架构决策,无论它使用什么 API。该选择很大程度上取决于渲染器必须支持的功能集及其性能要求。
大量所述特征由所谓的屏幕空间效果组成。如果意味着我们将有关屏幕每个像素的一些关键数据渲染到一组渲染缓冲区,然后使用该数据(而不是几何图形)来计算一帧所需的一些新数据。环境光遮蔽就是这种效果的一个很好的例子。基于像素的一些空间值,我们计算一个“掩码”,我们以后可以使用它来正确地对每个像素进行着色。
此外,还有一个渲染通道几乎完全依赖于屏幕空间计算。而且确实是延迟着色。这就是 G 缓冲区的用武之地。计算像素颜色所需的所有数据都被渲染到 G 缓冲区:一组存储该数据的渲染缓冲区。它本身的数据(以及因此 G-buffer 的渲染缓冲区的含义)可以是不同的:漫反射分量、镜面反射分量、光泽度、法线、位置、深度等。作为帧渲染的一部分,当代延迟着色引擎使用屏幕空间环境光遮蔽 (SSAO),它使用来自多个 G-buffer 渲染缓冲区的数据(通常是位置、法线和深度)。
关于 ND 缓冲区。在我看来,这不是一个广泛使用的术语(除了这个问题,谷歌没有找到任何相关信息)。我相信 ND 代表 Normal-Depth。它们只是特定算法和效果的 G 缓冲区的一个特定案例(在论文中它是 SSAO)。
因此,使用 G-buffers(和 ND-buffers 作为 G-buffers 的子集)并取决于您正在实现的着色算法和效果。但是所有的屏幕空间计算都需要某种形式的 G 缓冲区。
PS您链接的论文包含不准确之处。作者列出了在 GLES 2.0 上实现 ND 缓冲区的能力,作为该方法的优势。然而这实际上是不可能的,因为 GLES 2.0 没有深度纹理(它们已被添加到OES_depth_texture
扩展中)。
我想在以前的答案中添加更多信息。
我读了几篇关于 ND-Buffers 和 G-Buffers 的文章,好像它是 WebGL 开发的战略选择。
延迟渲染最重要的部分之一是,如果给定平台支持 MRT(多个渲染目标)。如果没有,您将无法在每次渲染之间共享着色器中的部分计算,并且它还会强制您运行渲染次数与“图层”一样多(在统一 3D 的情况下,它可能高达 11 次?)。这可能会大大降低您的程序速度。
在这个问题中阅读更多信息 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/
所以应该可以使用延迟渲染技术,但是它的速度很难猜。