我正在使用与 SSAO 绑定(bind)的计算着色器。我在计算着色器中使用以下结构:
struct Particle
{
vec4 pAnds;
vec3 velocity;
float lifespan;
float age;
};
layout (std430, binding = 0) buffer members_in
{
Particle particle[];
} input_data;
但是,为每个数据结构分配的内存块似乎不等于 (4 + 3 + 1 + 1) * 4。我还尝试了另一个:
struct Particle
{
vec4 pAnds;
vec3 velocity;
float lifespan;
};
这次效果很好。我想知道如何使用 std430 限定符分配内存。如何使我的第一个数据结构像第二个一样工作?
更新: 我将其更改为以下形式:
struct Particle
{
float px, py, pz, s;
float vx, vy, vz;
float lifespan;
float age;
};
这次工作正常,但我仍然不知道为什么使用 vec4/vec3 会出现问题。
最佳答案
来自 std430 布局规则:
Structure alignment is the same as the alignment for the biggest structure member, where three-component vectors are not rounded up to the size of four-component vectors. Each structure will start on this alignment, and its size will be the space needed by its members, according to the previous rules, rounded up to a multiple of the structure alignment.
vec4 的对齐方式是 float 大小的四倍。
来源:OpenGL 编程指南,第 8 版
<小时/>第一个例子:
struct Particle {
vec4 pAnds; // 4 * 4 bytes
vec3 velocity; // 3 * 4 bytes
float lifespan; // 1 * 4 bytes
float age; // 1 * 4 bytes
};
该结构体中最大的成员是vec4 pAnds
,它具有16字节对齐。因此,结构的对齐也是 16 字节,这意味着,在数组内部,每个结构都必须从 16 倍的位置开始。为了满足这一点,将在每个结构的末尾附加 12 字节的填充。
第二个例子:
struct Particle {
vec4 pAnds; // 4 * 4 bytes
vec3 velocity; // 3 * 4 bytes
float lifespan; // 1 * 4 bytes
};
该结构的对齐方式为 16 字节,并且结构的大小恰好适合结构对齐方式的 2 倍。
<小时/>第三个例子:
struct Particle {
float px, py, pz, s;
float vx, vy, vz;
float lifespan;
float age;
};
该结构体中没有任何大于 float 大小的元素,因此该结构体的对齐方式仅为 4 个字节。
<小时/>解决方法可能是插入一个 float 组作为显式填充,或者尝试将数据紧密打包到结构对齐的大小倍数中。
关于opengl - 使用 std430 限定符进行内存分配,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29531237/