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

Use*_*ted 4 c++ opengl shader

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

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

Nic*_*las 8

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

转换反馈

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

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

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

渲染到缓冲区对象

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

作为纹理,您可以自由地将它们附加Framebuffer对象并渲染到它.

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

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

图像加载/存储

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

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

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

着色器存储缓冲区对象

着色器存储缓冲区对象其实只是图片的加载/从缓冲纹理存储,只能用一个更好的接口.这就像定义结构并只是访问它们一样.

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