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

时间:2012-12-01 17:48:20

标签: c++ opengl shader

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

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

2 个答案:

答案 0 :(得分:8)

是的,虽然这取决于您的硬件。所有这些机制都需要能够符合GL 3.x或更高版本的硬件。

转换反馈

这允许您在一个或多个缓冲区对象中捕获vertex processing的结果。

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

您可以使用geometry shader来增加一些阅读和写作能力;反馈发生在VS或GS之后。

渲染到缓冲区对象

Buffer textures是使用缓冲区对象进行存储的纹理。他们喜欢非常大的一维纹理。

作为纹理,您可以attach them自由地Framebuffer Object并渲染它。

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

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

图片加载/存储

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

除了硬件要求之外,最大的缺点是没有免费的午餐。通过使用Image Load Store,您可以有效地放弃所有OpenGL' automatic memory synchronization systems。因此,您必须执行all synchronizations manually进行写入和读取。这是一个巨大的痛苦,你可以很容易搞砸它并获得未定义的行为,而不知道为什么。它可以在一个平台上运行,但不能在用户的机器上运行。

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

着色器存储缓冲区对象

Shader storage buffer objects实际上只是来自缓冲区纹理的图像加载/存储,只有much nicer interface。它就像定义结构并只是访问它们一样。

与图像加载/存储相同的缺点适用。此外,SSBO 真的新;只有NVIDIA实现它,即便如此,只有beta版驱动程序。

答案 1 :(得分:1)

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

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