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

标签 c++ opengl shader

<分区>

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

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

最佳答案

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

转换反馈

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

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

你可以使用 geometry shader提高你的一些阅读和写作能力;反馈发生在 VS 或 GS​​ 之后。

渲染到缓冲对象

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

作为纹理,你可以自由attach themFramebuffer 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/

相关文章:

c++ - QPixmaps 中的 QCursor 重建是否会泄漏内存?

c++ - 如何重载 = 运算符以在 C++ 中通过引用进行复制?

c++ - 使用深度缓冲区 : horribly inaccurate? 进行光线拾取

c++ - 如何使用 Freetype 沿基线对齐字形?

opengl - OpenGL中Framebuffer和Renderbuffer的概念和区别是什么?

c++ - 对 VBO 中的特定三角形使用不同的纹理

c++ - 矩阵 vector 乘法 (cublasDgemv) 返回零

c++ - 我将如何删除此类对象? (C++)

javascript - WebGL 着色器根据鼠标位置为纹理着色

c++ - 向着色器添加线不会画任何东西