从顶点着色器中修改着色器存储缓冲区对象

Posted

技术标签:

【中文标题】从顶点着色器中修改着色器存储缓冲区对象【英文标题】:Modifying a Shader Storage Buffer Object from within a Vertex Shader 【发布时间】:2016-08-31 14:21:52 【问题描述】:

在我的基础程序 (C++/OpenGL 4.5) 中,我已将 Vertex Buffer 的内容复制到 Shader Storage Buffer (SSBO):

float* buffer = (float*) glMapBuffer(GL_ARRAY_BUFFER, GL_READ_ONLY);
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 3, ssbo[2]);

glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(GLfloat)*size,buffer, GL_DYNAMIC_DRAW);

glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 3, 0);
glUnmapBuffer(GL_ARRAY_BUFFER);

顶点着色器中,这个数据被绑定到一个数组中:

#version 430
#extension GL_ARB_shader_storage_buffer_object : require

layout(shared, binding = 3) buffer storage

    float array[];

但是当我试图覆盖 main 函数中的数组条目时,如下所示:

array[index_in_bounds] = 4.2;

什么都没有发生。

我做错了什么?我可以从顶点着色器中更改缓冲区吗?这只能在几何着色器中实现吗?我是否必须使用转换反馈(我以前从未使用过)来执行此操作?

编辑: 我在我的主程序中映射缓冲区用于测试目的,只是为了查看数据是否更改:

float* buffer = (float*) glMapBuffer(GL_ARRAY_BUFFER, GL_READ_ONLY);
float* ssbo = (float*) glMapNamedBuffer(3, GL_READ_ONLY);

for(int i = 0; i < SIZE_OF_BUFFERS; i++)
    printf("% 5f | % 5f\n", ssbo[i], buffer[i]);

glUnmapNamedBuffer(3);
glUnmapBuffer(GL_ARRAY_BUFFER);

【问题讨论】:

定义“什么都没有发生”。显示您检测是否发生某事的代码。 很明显,因为我正在使用数组进行转换。我已经添加了调试输出代码。 请发minimal reproducible example。 【参考方案1】:

好的,我使用红皮书发现了问题。我没有正确绑定缓冲区并且绑定缓冲区基础必须发生在缓冲数据之后

float* buffer = (float*) glMapBuffer(GL_ARRAY_BUFFER, GL_READ_ONLY);
glBindBuffer(GL_SHADER_STORAGE_BUFFER, &ssbo); // bind buffer

// switched these two:
glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(GLfloat)*size,buffer, GL_DYNAMIC_DRAW);
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 3, &ssbo);

glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0); // unbind buffer
glUnmapBuffer(GL_ARRAY_BUFFER);

【讨论】:

以上是关于从顶点着色器中修改着色器存储缓冲区对象的主要内容,如果未能解决你的问题,请参考以下文章

在 GLSL 顶点着色器中,您可以访问索引缓冲区中顶点的索引,而不仅仅是顶点缓冲区吗?

着色器存储缓冲区中的 OpenGL 顶点

打开 gl 计算着色器和帧缓冲区

是否可以从顶点着色器读取数据?

最小保证着色器存储块大小是多少?

带着色器的顶点缓冲区对象/顶点数组对象