在缓冲区对象上运行并通过着色器更改其数据?

Run on buffer object and change it's data by shader?

本文关键字:数据 对象 缓冲区 运行      更新时间:2023-10-16

有没有一种方法可以在缓冲区对象上运行着色器,并使用着色器用其他数据修改它?

换句话说:有没有一种方法可以在着色器中创建统一的全局变量并进行修改?

是的,但这取决于您的硬件。所有这些机制都需要具备GL 3.x或更高版本的硬件。

变换反馈

这允许您在一个或多个缓冲区对象中捕获顶点处理的结果。

这是最粗糙的机制,因为每个顶点着色器只能访问作为输入提供的顶点数据,并且只能写入输出顶点。因此着色器无法访问顶点之前或之后的顶点。此外,输出量非常有限,通常只有4个GL 3.x类硬件的输出值。

你可以使用几何着色器来提高你的一些阅读和写作能力;反馈发生在VS或GS.之后

渲染到缓冲区对象

缓冲区纹理是使用缓冲区对象进行存储的纹理。它们就像非常大的1D纹理。

作为一个纹理,您可以自由地将它们附加到帧缓冲区对象并对其进行渲染。

这种技术的缺点是,除了渲染到具有1像素高度的图像的困难之外,还需要处理光栅化器。这并不完全准确。您可以使用gl_FragCoord来知道您在片段中的位置,但如果您想将明显不同的数据写入图像的不同区域,可能会遇到困难。

另一个问题是FBO的大小受到视口尺寸的限制,通常在8192到16384之间。这没有太多的写作空间;最多可以写入65536个单独的浮点(如果缓冲区纹理使用GL_RGBA32F格式)。因此,您在实际写入的数据量方面受到很大限制。

图像加载/存储

GL 4.2中的核心ARB_shader_image_load_store表示着色器任意读取和写入图像数据的能力。结合缓冲区纹理(使用缓冲区对象作为存储的纹理),可以任意读取和写入缓冲区对象。

除了硬件要求之外,最大的缺点是没有免费的午餐。通过使用图像加载存储,您可以有效地放弃OpenGL的所有自动内存同步系统。因此,对于写入和读取,您必须手动执行所有同步操作。这是一个巨大的痛苦,你很容易把它搞砸,得到不明确的行为,而不知道为什么。它可能在一个平台上工作,但不能在用户的机器上工作。

你必须非常小心处理这些东西。

着色器存储缓冲区对象

着色器存储缓冲区对象实际上只是缓冲区纹理中的图像加载/存储,只有更好的界面。这就像定义结构并访问它们。

适用与图像加载/存储相同的缺点。此外,SSBO是真正的新;只有NVIDIA实现了它,即使在那时,也只能在测试版驱动程序中实现。

我不太了解它是如何完成的,但我知道从着色器修改VBO称为"变换反馈"。您将需要OpenGL>=3.0,或带有NV_transform_feedbackEXT_transform_feedback扩展名的OpenGL>=2.0。

如果你需要更通用的计算能力,你可以尝试做一些OpenCL/ONGGLinterop。。。