0

As per the specification Variables declared inside a Uniform Buffer must be properly aligned.

I have the following GLM variables in my structure:

struct UniformBufferObject_PointLights {
    glm::f32 constant[64]{};
    glm::f32 linear[64]{};
    glm::f32 quadratic[64]{};

    glm::vec3 position[64]{};

    glm::vec3 ambient[64]{};
    glm::vec3 diffuse[64]{};

    glm::int32 count{};
};
  • Attempting to access any of the variables from within the shader acts as if their values are all 0. The issue is centered around the glm::f32 and glm::uint32 declarations.

The glm::vec3's are all accessible by simply declaring them above the glm::f32's and glm::uint32, however, the glm::uint32 and glm::f32's are still inaccessible. At this point I figure it must be an alignment issue.

//  After rearrangement.
struct UniformBufferObject_PointLights {
    glm::vec3 position[64]{};

    glm::vec3 ambient[64]{};
    glm::vec3 diffuse[64]{};

    glm::f32 constant[64]{};
    glm::f32 linear[64]{};
    glm::f32 quadratic[64]{};

    glm::uint32 count{};
};
  • position,ambient, and diffuse are all accessible after moving them to the top of the struct.

I have set #define GLM_FORCE_DEFAULT_ALIGNED_GENTYPES but it doesn't appear to work for glm::f32 and glm::uint32 and probably others. What do I need to do to get these variables working in my uniform buffer? I've tried placing alignas(4),alignas(8),alignas(16), and alignas(32) before their declarations but no combination works.

KKlouzal
  • 732
  • 9
  • 32

1 Answers1

0

Arrays in uniform buffers must be aligned as per std140 which basically states vec4 alignment.

That means your uniform buffer is too small. As for the shader the float foo[64] is actually the same size as vec4 foo[64]. alignas qualifier won't allow you to change that.

Either use storage buffers, which could be slower, or just use vec4's in arrays.

sharpneli
  • 1,601
  • 10
  • 9
  • SSBOs wouldn't help; `vec3`s are always 16-byte aligned, even in std430 layout. – Nicol Bolas Nov 28 '19 at 12:35
  • That is true. But scalars are tightly packed. Vec3 is pretty much never tightly packed in any API. The overhead to just promote them to vec4 is also way smaller than with scalars. EDIT: The closing of this question is not that good as it's not just about vec3, but also scalar arrays being vec4 that the supposed duplicate does not address. – sharpneli Nov 28 '19 at 12:43