将SSBO绑定到片段着色器

Dom*_*yre 3 opengl glsl compute-shader fragment-shader

我有一个SSBO,它为屏幕上的每个像素存储vec4颜色值,并在主循环之前通过计算着色器预先填充值.

我现在正试图在屏幕上获取这些数据,我猜这涉及到使用片段着色器(虽然如果你知道一个更好的方法,我可以接受建议)

所以我试图将缓冲区或至少其中的数据添加到片段着色器中,以便我可以将每个片段的颜色设置为缓冲区中的相应值,但我找不到任何方法这样做?

有人告诉我,我可以将SSBO绑定到片段着色器,但我不知道该怎么做?我的其他想法是以某种方式将数据从SSBO移动到纹理,但我也无法解决这个问题

更新:

作为回应thokra的优秀答案和以下评论是设置我的缓冲区的代码:

//Create the buffer
GLuint pixelBufferID;
glGenBuffers(1, &pixelBufferID);

//Bind it
glBindBuffer(GL_SHADER_STORAGE_BUFFER, pixelBufferID);

//Set the data of the buffer
glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(vec4) * window.getNumberOfPixels, new vec4[window.getNumberOfPixels], GL_DYNAMIC_DRAW);

//Bind the buffer to the correct interface block number
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, pixelBufferID);
Run Code Online (Sandbox Code Playgroud)

然后我调用计算着色器,这部分工作,我检查数据是否已正确填充.然后在我的片段着色器中,就像测试一样:

layout(std430, binding=0) buffer PixelBuffer
{
    vec4 data[];
} pixelBuffer

void main()
{
    gl_FragColor = pixelBuffer.data[660000];
}
Run Code Online (Sandbox Code Playgroud)

我注意到的是,它似乎需要越来越长的索引越高,因此在660000它实际上并没有崩溃,只是花了很多时间.

tho*_*kra 11

存储缓冲区的工作方式与统一缓冲区的工 为了得到这些工作,我怎么建议是这样的感觉这样.主要区别在于存储缓冲区可以容纳更多的数据,您可以随机读取和写入数据.

有多种工作角度,但我会从最基本的角度开始 - 着色器中的界面块.我将仅描述使用接口块时可能性的一部分,但它应该足以让您入门.

与"普通"变量相比,您无法buffer在全局范围中指定变量.您需要按照第4.3.7节 - GLSL 4.40规范使用接口块(第4.3.9节 - GLSL 4.40规范):

缓冲区限定符可用于声明接口块(第4.3.9节"接口块"),然后将其称为着色器存储块.在全局范围(块外)声明缓冲区变量是编译时错误.

请注意,上述部分与ARB扩展略有不同.

因此,要访问存储缓冲区中的内容,您需要在片段着色器(或任何其他适用的阶段)中定义buffer 接口块:

layout (binding = 0) buffer BlockName
{
  float values[]; // just as an example
}; 
Run Code Online (Sandbox Code Playgroud)

与没有实例名称的任何其他块一样,您将引用缓冲区存储,就像values在全局范围内一样,例如:

void main()
{
  // ...

  values[0] = 1.f;

  // ...
}    
Run Code Online (Sandbox Code Playgroud)

在应用程序级别,您现在唯一需要知道的是,在程序成功链接后,buffer接口块BlockName具有绑定0.

使用应用程序创建存储缓冲区对象后,首先将缓冲区绑定到您为相应接口块指定的绑定

glBindBufferBase(GLenum target?, GLuint index?, GLuint buffer?);
Run Code Online (Sandbox Code Playgroud)

用于将完整缓冲区绑定到索引

glBindBufferRange(GLenum target?, GLuint index?, GLuint buffer?, GLintptr offset?, GLsizeiptr size?);
Run Code Online (Sandbox Code Playgroud)

用于将由偏移量和缓冲区数量指定的子集绑定到索引.

注意,index指的是binding您指定layout的相应接口块.

这基本上就是它.请注意,存储缓冲区大小,绑定点数,最大存储块大小等存在某些限制.我将向您介绍GL和GLSL规范中的相应部分.

此外,ARB扩展中还有一个最小的例子.阅读扩展的问题部分还经常提供对暴露的功能及其背后的基本原理的进一步了解.我建议你仔细阅读.

如果遇到问题,请发表评论.