Массив структур в Compute Shader

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

Я хочу передать моему вычислительному шейдеру массив структур colourStruct для окрашивания выходной текстуры.

Я хотел бы иметь красное изображение, когда "wantedColor" = 0 в моем вычислительном шейдере, и зеленое изображение "wantedColor" = 1, синий для 2.

Но у меня на самом деле есть только красный, когда "wantedColor" = 1 или 2 или 3 и черный, когда "wantedColor" > 2...

Если у кого-то есть идея, или, может быть, я не понял идеи ввода вычислительных шейдеров.

Спасибо за вашу помощь, вот интересная часть моего кода.

Мой вычислительный шейдер:

 #version 430 compatibility

layout(std430, binding=4) buffer Couleureuh
{
  vec3 Coul[3]; // array of structures
};

layout(local_size_x = 1, local_size_y = 1) in;
layout(rgba32f, binding = 0) uniform image2D img_output;

void main() {

  // base pixel colour for image
  vec4 pixel = vec4(0.0, 0.0, 0.0, 1.0);

  // get index in global work group i.e x,y, position
  ivec2 pixel_coords = ivec2(gl_GlobalInvocationID.xy);
  ivec2 dims = imageSize (img_output);


  int colorWanted = 0;
  pixel = vec4(Coul[colorWanted], 1.0);

  // output to a secific pixel in the image
  imageStore (img_output, pixel_coords, pixel);

}

Вычислить шейдер и инициализацию SSBO:

    GLuint structBuffer;
    glGenBuffers(1, &structBuffer);
    glBindBuffer(GL_SHADER_STORAGE_BUFFER, structBuffer);
    glBufferData(GL_SHADER_STORAGE_BUFFER, 3*sizeof(colorStruct), NULL, GL_STATIC_DRAW);

        GLint bufMask = GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT; // invalidate makes a ig difference when re-writting

    colorStruct *coul;
    coul = (colorStruct *) glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, 3*sizeof(colorStruct), bufMask);


    coul[0].r = 1.0f;
    coul[0].g = 0.0f;
    coul[0].b = 0.0f;

    coul[1].r = 0.0f;
    coul[1].g = 1.0f;
    coul[1].b = 0.0f;

    coul[2].r = 0.0f;
    coul[2].g = 0.0f;
    coul[2].b = 1.0f;

    glUnmapBuffer(GL_SHADER_STORAGE_BUFFER);

    glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 4, structBuffer);

    m_out_texture.bindImage();

    // Launch compute shader
    m_shader.use();

    glDispatchCompute(m_tex_w, m_tex_h, 1);

    // Prevent samplign before all writes to image are done
    glMemoryBarrier(GL_SHADER_IMAGE_ACCESS_BARRIER_BIT);

1 ответ

Решение

vec3 всегда выровнены по 16 байтов. Таким образом, когда они находятся в массиве, они действуют как vec4 s. Даже с std430 раскладка.

Никогда не используйте vec3 в интерфейсных блоках. Вы должны либо использовать массив float s (индивидуальный доступ к 3 элементам, которые вы хотите) или массив vec4 (с неиспользованным элементом).

Другие вопросы по тегам