在缓冲区对象上运行并通过着色器更改其数据?
Run on buffer object and change it's data by shader?
有没有一种方法可以在缓冲区对象上运行着色器,并使用着色器用其他数据修改它?
换句话说:有没有一种方法可以在着色器中创建统一的全局变量并进行修改?
是的,但这取决于您的硬件。所有这些机制都需要具备GL 3.x或更高版本的硬件。
变换反馈
这允许您在一个或多个缓冲区对象中捕获顶点处理的结果。
这是最粗糙的机制,因为每个顶点着色器只能访问作为输入提供的顶点数据,并且只能写入输出顶点。因此着色器无法访问顶点之前或之后的顶点。此外,输出量非常有限,通常只有4个GL 3.x类硬件的输出值。
你可以使用几何着色器来提高你的一些阅读和写作能力;反馈发生在VS或GS.之后
渲染到缓冲区对象
缓冲区纹理是使用缓冲区对象进行存储的纹理。它们就像非常大的1D纹理。
作为一个纹理,您可以自由地将它们附加到帧缓冲区对象并对其进行渲染。
这种技术的缺点是,除了渲染到具有1像素高度的图像的困难之外,还需要处理光栅化器。这并不完全准确。您可以使用gl_FragCoord
来知道您在片段中的位置,但如果您想将明显不同的数据写入图像的不同区域,可能会遇到困难。
另一个问题是FBO的大小受到视口尺寸的限制,通常在8192到16384之间。这没有太多的写作空间;最多可以写入65536个单独的浮点(如果缓冲区纹理使用GL_RGBA32F
格式)。因此,您在实际写入的数据量方面受到很大限制。
图像加载/存储
GL 4.2中的核心ARB_shader_image_load_store表示着色器任意读取和写入图像数据的能力。结合缓冲区纹理(使用缓冲区对象作为存储的纹理),可以任意读取和写入缓冲区对象。
除了硬件要求之外,最大的缺点是没有免费的午餐。通过使用图像加载存储,您可以有效地放弃OpenGL的所有自动内存同步系统。因此,对于写入和读取,您必须手动执行所有同步操作。这是一个巨大的痛苦,你很容易把它搞砸,得到不明确的行为,而不知道为什么。它可能在一个平台上工作,但不能在用户的机器上工作。
你必须非常小心处理这些东西。
着色器存储缓冲区对象
着色器存储缓冲区对象实际上只是缓冲区纹理中的图像加载/存储,只有更好的界面。这就像定义结构并访问它们。
适用与图像加载/存储相同的缺点。此外,SSBO是真正的新;只有NVIDIA实现了它,即使在那时,也只能在测试版驱动程序中实现。
我不太了解它是如何完成的,但我知道从着色器修改VBO称为"变换反馈"。您将需要OpenGL>=3.0,或带有NV_transform_feedback
或EXT_transform_feedback
扩展名的OpenGL>=2.0。
如果你需要更通用的计算能力,你可以尝试做一些OpenCL/ONGGLinterop。。。
- 如何在没有数据拷贝的情况下从指针创建一个Eigen VectorXd对象
- 如何使用数据对象上的常量指针初始化类
- int数据类型的指针指向的是什么,如果是一个类的私有数据成员,我们创建了该类的两个对象?
- 使用指针访问数组中的对象数据成员
- 使用对象文件读取三角形数据网格
- 访问数据成员(本身是对象)的数据成员,就好像它们是类成员一样
- 如何在新的派生对象中获取基本对象的数据?
- 如何从 CSV 获取数据并将其存储在 C++ 中的表对象中
- 类对象在 c++ 中是否具有数据类型?
- 有没有办法在C++中循环访问对象的不同数据成员
- C++ 在节点内存储对数据对象的引用,而不复制数据
- 带有 std::map 的 c++ 结构是拥有动态数据对象的好设计吗?
- 将任意的JavaScript数据对象传递到Node.js C 插件
- Vtk检查多数据对象是否相交
- 如何处理类结构的变化,并与使用 boost 序列化的数据/对象向后兼容
- 如何处理错误“vtkTrivialProducer :此数据对象不包含请求的范围”
- 如何在不复制数据和不公开指针的情况下向用户检索数据对象
- 如何赋值具有const成员的数据对象
- 对于普通数据对象,多态的正确方式是什么?
- 为什么这会创建两次数据对象