Странная проблема с порядком в буфере хранения шейдеров

Я пишу фрагмент кода, который будет проверять все точки данных на объем столкновения, используя вычислительный шейдер. Если точка находится внутри объема столкновения, она меняет метку на 1, в противном случае она остается равной 0.

Мой подход состоит в том, чтобы иметь два буфера, один из которых содержит все вершины, а другой буфер содержит все метки в порядке вершин. Затем в каждой рабочей группе вычислительный шейдер будет обрабатывать точку с индексом X и соответствующим образом устанавливать метку с индексом X.

Однако результат странный, он изменил некоторые метки на 1, но не те, которые находятся внутри поля столкновения, он разбросан вокруг каждой части целых точек данных... Я почти уверен, что обнаружение столкновения и ограничивающие поля переданы в с шейдерами все в порядке, они работают во всех других частях программы с тем же форматом точек, может ли это быть из-за того, что порядок выполнения рабочей группы вычислительных шейдеров совершенно случайный?

Я очень благодарен всем, кто может взглянуть на это... это был мой кошмар последние 3 дня...

Сначала в моем коде C++ я выделял и назначал буферы следующим образом:

    glGenVertexArrays(1, &vao);
    glGenBuffers(1, &vbo);   // vertices
    glGenBuffers(1, &cbo);   // colors
    glGenBuffers(1, &lbo);   // labels
    glGenBuffers(1, &ssvbo); // shader storage vbo for compute shader
    glGenBuffers(1, &sslbo); // shader storage lbo for compute shader

    glBindBuffer(GL_SHADER_STORAGE_BUFFER, ssvbo);
    glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(float) * vertices.size() * 3, &vertices[0], GL_STATIC_DRAW); 

    glBindBuffer(GL_SHADER_STORAGE_BUFFER, sslbo);
    glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(int) * labels.size(), &labels[0], GL_STATIC_DRAW);

    glBindVertexArray(vao);

    // Vertices
    glBindBuffer(GL_ARRAY_BUFFER, vbo);
    glBufferData(GL_ARRAY_BUFFER, sizeof(float) * vertices.size() * 3, &vertices[0], GL_STATIC_DRAW); // xyz

    // set attribute for the first argument
    glEnableVertexAttribArray(0);
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), (GLvoid*)0); // pos
    glBindBuffer(GL_ARRAY_BUFFER, cbo);
    glBufferData(GL_ARRAY_BUFFER, sizeof(float) * colors.size() * 3, &colors[0], GL_STATIC_DRAW); // rgb

    glEnableVertexAttribArray(1);
    glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), (GLvoid*)0); //color
    glBindBuffer(GL_ARRAY_BUFFER, lbo);
    glBufferData(GL_ARRAY_BUFFER, sizeof(int) * labels.size(), &labels[0], GL_STATIC_DRAW);

    glEnableVertexAttribArray(2);
    glVertexAttribPointer(2, 1, GL_INT, GL_FALSE, sizeof(GLint), (GLvoid*)0); // label

    // illustration : 1 1 1 1 1 1  1
    // name:          |pos | clr | label
    // location:      | 0  |  1  | 2

    glBindBuffer(GL_ARRAY_BUFFER, 0);
    glBindVertexArray(0);

    glDisableVertexAttribArray(0);

И вот как я запускаю программу вычислительного шейдера,

    glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 4, m->ssvbo);
    glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 5, m->sslbo);

    glUseProgram(compute_label_program);

    GLint vNormals = glGetUniformLocation(compute_label_program, "normals");
    GLint vPts = glGetUniformLocation(compute_label_program, "pts");

    glUniform3fv(vNormals, 6, &norms[0].x);
    glUniform3fv(vPts, 8, &pt[0].x);


    glDispatchCompute(static_cast<int>(m->vertices.size()) / WORK_GROUP_SZ + 1, 1, 1);
    glMemoryBarrier(GL_SHADER_STORAGE_BARRIER_BIT);

    // now, assume the above code changed the labels in sslbo, copy the sslbo,ssvbo values back to client
    glBindBuffer(GL_SHADER_STORAGE_BUFFER, m->sslbo);
    m->labels.clear();
    m->labels.resize(m->vertices.size());
    glGetBufferSubData(GL_SHADER_STORAGE_BUFFER, 0, sizeof(int) * m->vertices.size(), &m->labels[0]);
    glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0);

    glBindBuffer(GL_SHADER_STORAGE_BUFFER, m->ssvbo);
    m->vertices.clear();
    m->vertices.resize(m->labels.size());
    glGetBufferSubData(GL_SHADER_STORAGE_BUFFER, 0, sizeof(point) * m->vertices.size(), &m->vertices[0]);
    glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0);


    // re-upload labels buffer
    m->UpdateBuffers();

А это код вычислительного шейдера,

#version 430 compatibility
#extension GL_ARB_compute_shader : enable
#extension GL_ARB_shader_storage_buffer_object : enable

layout (std140, binding = 4) readonly buffer Position
{
    vec3 pos[];
};

layout (std140, binding = 5) writeonly buffer Label
{
    int label[];
};

layout (local_size_x = 128, local_size_y = 1, local_size_z = 1) in;

uniform vec3 normals[6];
uniform vec3 pts[8];


bool Oobb(in vec3 norms[6], in vec3 pt[8], in vec3 po)
{
  // some collision checking code
}


void main()
{
  uint gid = gl_GlobalInvocationID.x;

  if(Oobb(normals, pts, pos[gid].xyz))
          label[gid] = 1;
}


person Zhou Zhi Hua    schedule 20.05.2020    source источник
comment
@Rabbid76, ты спас мой проект, спасибо!   -  person Zhou Zhi Hua    schedule 20.05.2020