<分区>
有没有办法在 Buffer 对象上运行着色器并使用着色器用其他数据修改它?
换句话说:有没有办法在着色器中创建统一的全局变量并可修改?
<分区>
有没有办法在 Buffer 对象上运行着色器并使用着色器用其他数据修改它?
换句话说:有没有办法在着色器中创建统一的全局变量并可修改?
最佳答案
是的,不过这取决于您的硬件。所有这些机制都需要支持 GL 3.x 或更高版本的硬件。
转换反馈
这允许您捕获 vertex processing 的结果在一个或多个缓冲区对象中。
这是最粗糙的机制,因为每个顶点着色器只能访问作为输入给定的顶点数据,并且只能写入输出顶点。所以着色器无法访问它之前或之后的顶点。此外,输出量非常有限,通常只有 4 个 GL 3.x 级硬件的输出值。
你可以使用 geometry shader提高你的一些阅读和写作能力;反馈发生在 VS 或 GS 之后。
渲染到缓冲对象
Buffer textures是使用缓冲区对象进行存储的纹理。它们就像非常大的一维纹理。
作为纹理,你可以自由attach them到 Framebuffer Object并呈现给它。
这种技术的缺点,除了难以渲染为 1 像素高度的图像之外,还在于您要处理光栅器。这并不完全准确。您可以使用 gl_FragCoord
来了解您在片段中的位置,但是如果您想要将截然不同的数据写入图像的不同区域,可能会有困难。
另一个问题是 FBO 大小受视口(viewport)尺寸的限制,通常在 8192 到 16384 之间。充其量,您可以编写 65536 个单独的 float (如果缓冲区纹理使用 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 实现了它,即便如此,也仅在测试版驱动程序中实现。
关于c++ - 在缓冲区对象上运行并通过着色器更改它的数据?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13662005/