4

有没有办法在缓冲区对象上运行着色器并使用着色器使用其他一些数据对其进行修改?

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

4

2 回答 2

8

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

变换反馈

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

这是最粗略的机制,因为每个顶点着色器只能访问它作为输入给出的顶点数据,并且只能写入输出顶点。所以着色器不能访问它之前或之后的顶点。此外,输出量非常有限,GL 3.x 级硬件通常只有 4 个输出值。

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

渲染到缓冲区对象

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

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

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

另一个问题是 FBO 大小受视口尺寸的限制,通常在 8192 到 16384 左右。充其量,您可以编写 65536 个单独的浮点数(如果缓冲区纹理使用该GL_RGBA32F格式)。因此,您实际上可以写入的数据量非常有限。

图像加载/存储

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

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

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

着色器存储缓冲区对象

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

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

于 2012-12-01T18:45:33.187 回答
1

我不太了解它是如何完成的,但我知道从着色器修改 VBO 称为Transform Feedback。您需要 OpenGL >=3.0 或 OpenGL >= 2.0 并带有NV_transform_feedbackorEXT_transform_feedback扩展名。

如果您需要更通用的计算能力,您可以尝试做一些OpenCL/OpenGL 互操作...

于 2012-12-01T17:52:38.190 回答