我在将 GPU 缓冲区传输到 CPU 以执行排序操作时遇到了一些问题。缓冲区GL_SHADER_STORAGE_BUFFER由 300.000 个浮点值组成。传输操作 withglGetBufferSubData大约需要 10ms,而 withglMapBufferRange则需要超过 100 ms。
我使用的代码如下:
std::vector<GLfloat> viewRow;
unsigned int viewRowBuffer = -1;
int length = -1;
void bindRowBuffer(unsigned int buffer){
glBindBuffer(GL_SHADER_STORAGE_BUFFER, buffer);
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 3, buffer);
}
void initRowBuffer(unsigned int &buffer, std::vector<GLfloat> &row, int lengthIn){
// Generate and initialize buffer
length = lengthIn;
row.resize(length);
memset(&row[0], 0, length*sizeof(float));
glGenBuffers(1, &buffer);
bindRowBuffer(buffer);
glBufferStorage(GL_SHADER_STORAGE_BUFFER, row.size() * sizeof(float), &row[0], GL_DYNAMIC_STORAGE_BIT | GL_MAP_READ_BIT | GL_MAP_WRITE_BIT);
glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0);
}
void cleanRowBuffer(unsigned int buffer) …Run Code Online (Sandbox Code Playgroud) 我有兴趣将可变长度数组(附加 SSBO)传递给函数,即:
layout(std430) buffer ssbo {
type buffer[];
};
void func(buffer) {
buffer[...]
}
func(buffer);
Run Code Online (Sandbox Code Playgroud)
编辑:扩展规范明确指出这是不受支持的(问题#2 - https://www.opengl.org/registry/specs/ARB/shader_storage_buffer_object.txt)。因此,欢迎采取变通办法。
我正在尝试使用着色器存储缓冲区对象(又名缓冲区块),但有些事情我还没有完全掌握。我想做的是在其中存储不确定数量的灯光的(简化)数据n,以便我的着色器可以遍历它们并执行计算。
首先,我说我得到了正确的结果,并且OpenGL没有错误。然而,困扰我不知道为什么它是工作。
因此,在我的着色器中,我得到了以下内容:
struct PointLight {
vec3 pos;
float intensity;
};
layout (std430, binding = 0) buffer PointLights {
PointLight pointLights[];
};
void main() {
PointLight light;
for (int i = 0; i < pointLights.length(); i++) {
light = pointLights[i];
// etc
}
}
Run Code Online (Sandbox Code Playgroud)
在我的应用程序中:
struct PointLightData {
glm::vec3 pos;
float intensity;
};
class PointLight {
// ...
PointLightData data;
// ...
};
std::vector<PointLight*> pointLights;
glGenBuffers(1, &BBO);
glBindBuffer(GL_SHADER_STORAGE_BUFFER, BBO);
glNamedBufferStorage(BBO, n * sizeof(PointLightData), NULL, GL_DYNAMIC_STORAGE_BIT);
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, …Run Code Online (Sandbox Code Playgroud) 我试图在sampler2D不使用统一变量的情况下将类型变量放入我的着色器中。
相反,我想使用着色器存储缓冲区对象 (SSBO) 来移交它。必须在结构中声明什么类型的变量才能移交?我怎样才能sampler2D在着色器中投射这种类型?
我不确定哪种结构布局最适合我的应用程序:shared、packed、std140、std430。我并不是要对每一个进行解释,这些信息很容易找到,只是很难弄清楚每个对供应商兼容性/性能的影响。如果shared是默认值,我怀疑这是一个很好的起点。
据我所知,我必须在使用sharedor时查询对齐/偏移量packed,因为它是特定于实现的。
用于查询它的 API 是什么?glGetShaderiv在绑定计算着色器时,我是否传递了一些参数,让我找出对齐方式?