着色器存储缓冲区的所有值在几何着色器中均为 0

All values of the Shader Storage Buffer are 0 in Geometry Shader

本文关键字:何着色 存储 缓冲区      更新时间:2023-10-16

在我的应用程序中,着色器存储缓冲区的所有值似乎都0在几何着色器中。

这是我测试值的简单几何着色器

#version 430
#extension GL_ARB_shader_storage_buffer_object : enable
layout (points) in;
layout(invocations = 20) in;
layout (points, max_vertices = 256) out;
uniform mat4x4 matModel;
uniform mat4x4 matView;
uniform mat4x4 matProjection;
uniform mat4x4 matLightView;

struct Info {  
  vec4 position;
  vec4 normal;
  vec4 color;
};
layout(std430, binding=0) buffer pointData 
{
    Info pointElements[];
};
void main() {
  if( pointElements[0].position.x == 0 ) {
    gl_Position =  matProjection * matView * matModel *  gl_in[0].gl_Position;
    EmitVertex();
  }
  EndPrimitive();
}

仅渲染点pointElements[0].position.x == 0pointElements[0].position.x > 0不渲染任何内容)。缓冲区的设置是这样完成的:

struct PointData {
  float px, py, pz, pw;
  float nx, ny, nz, nw;
  float r, g, b, a;
}

void setupSSBO() {
  std::vector<PointData> data;
  int count = 15;
  for (int x = 0; x< count; x++) {
    for (int y = 0; y< count; y++) {
      PointData pt;
      pt.px = 1;
      pt.py = 2;
      pt.pz = 3;
      pt.pw = 4;
      pt.nx = 5;
      pt.ny = 6;
      pt.nz = 7;
      pt.nw = 8;
      pt.r = 9;
      pt.g = 10;
      pt.b = 11;
      pt.a = 12;
      data.push_back(pt);
    }
  }
  GLuint ssbo = 0;
  std::cout << "errors bnefore: " << glGetError() << std::endl;
  glGenBuffers(1, &m_pointData);
  std::cout << "glGenBuffers: " << m_pointData  << " " << glGetError() << std::endl;
  glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_pointData);
  std::cout << "glBindBuffer: " << glGetError() << std::endl;
  glBufferData(GL_SHADER_STORAGE_BUFFER, data.size()*sizeof(PointData), NULL, GL_STATIC_DRAW/*GL_DYNAMIC_COPY*/);
  std::cout << "glBufferData: " << glGetError() << std::endl;
  glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0);
  std::cout << "glBindBuffer: " << glGetError() << std::endl;

  glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_pointData);
  PointData* p = (PointData*)glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, data.size() *sizeof(PointData), GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT);
  std::cout << "glMapBufferRange: " << glGetError() << std::endl;
  memcpy(p, &data[0], data.size()*sizeof(PointData));
  glUnmapBuffer(GL_SHADER_STORAGE_BUFFER);
  std::cout << "glUnmapBuffer: " << glGetError() << std::endl;
  glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0);
  std::cout << "glBindBuffer: " << glGetError() << std::endl;
}

与着色器的绑定是这样完成的:

GLuint block_index = glGetProgramResourceIndex(progamId, GL_SHADER_STORAGE_BLOCK, "pointData");
glShaderStorageBlockBinding(progamId, block_index, m_pointData);

glGetError()调用不会返回错误。并且执行着色器是因为我在测试pointElements[0].position.x == 0时看到点。值保持0的原因可能是什么?(问题也在于xyw以及normalcolor

问题似乎是

glShaderStorageBlockBinding(progamId, block_index, m_pointData);

当我将其替换为时,一切正常:

glBindBufferBase(GL_SHADER_STORAGE_BUFFER, block_index, m_pointData);

编辑

根据我的观察和再次阅读规格后,glGetProgramResourceIndexglBindBufferBase的组合也是不正确的。将glBindBufferBase与用layout(std430, binding=0)定义的绑定一起使用是正确的,但glGetProgramResourceIndex不会返回该绑定,而是返回资源索引。