根据规范,在统一缓冲区内声明的变量必须正确对齐。
我的结构中有以下 GLM 变量:
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{};
};
- 尝试从着色器中访问任何变量的行为 好像它们的值都是 0。问题集中在
glm::f32
和glm::uint32
声明。
glm::vec3
都可以通过简单地在glm::f32
和glm::uint32
上方声明它们来访问,但是,glm::uint32
和glm::f32
仍然无法访问。在这一点上,我认为这一定是一个对齐问题。
// 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
和diffuse
在移动后都可以访问 它们到结构的顶部。
我已经设置了#define GLM_FORCE_DEFAULT_ALIGNED_GENTYPES
但它似乎不适用于glm::f32
和glm::uint32
,可能也适用于其他人。我需要做什么才能让这些变量在我的统一缓冲区中工作?我尝试在声明之前放置alignas(4)
、alignas(8)
、alignas(16)
和alignas(32)
,但没有组合工作。
统一缓冲区中的数组必须按照 std140 对齐,这基本上是 vec4 对齐的。
这意味着您的均匀缓冲区太小。至于着色器,浮点 foo[64] 实际上与 vec4 foo[64] 的大小相同。Alignas 限定符不允许您更改它。
要么使用存储缓冲区,这可能更慢,要么只在数组中使用 vec4。