我正在使用与SSAO绑定的计算着色器.我在计算着色器中使用以下结构:
struct Particle
{
vec4 pAnds;
vec3 velocity;
float lifespan;
float age;
};
layout (std430, binding = 0) buffer members_in
{
Particle particle[];
} input_data;
Run Code Online (Sandbox Code Playgroud)
但似乎为这些数据结构中的每一个分配的内存块不等于(4 + 3 + 1 + 1)*4.我还尝试了另一个:
struct Particle
{
vec4 pAnds;
vec3 velocity;
float lifespan;
};
Run Code Online (Sandbox Code Playgroud)
这次它工作得很好.我想知道如何使用std430限定符分配内存.如何使我的第一个数据结构像第二个一样工作?
更新:我将其更改为以下形式:
struct Particle
{
float px, py, pz, s;
float vx, vy, vz;
float lifespan;
float age;
};
Run Code Online (Sandbox Code Playgroud)
这次它工作正常,但我仍然不知道为什么使用vec4/vec3有问题.
从std430布局规则:
结构对齐与最大结构成员的对齐相同,其中三分量向量不会四舍五入到四分量向量的大小.每个结构都将从此对齐开始,其大小将是其成员所需的空间,根据之前的规则,四舍五入到结构对齐的倍数.
vec4的对齐是浮点数的四倍.
资料来源:OpenGL编程指南,第8版
第一个例子:
struct Particle {
vec4 pAnds; // 4 * 4 bytes
vec3 velocity; // 3 * 4 bytes
float lifespan; // 1 * 4 bytes
float age; // 1 * 4 bytes
};
Run Code Online (Sandbox Code Playgroud)
该结构的最大成员是vec4 pAnds
16字节对齐.因此,结构的对齐也是16个字节,这意味着,在数组内部,每个结构必须从16的位置开始.为了满足这一要求,将在每个结构的末尾附加12字节填充.
第二个例子:
struct Particle {
vec4 pAnds; // 4 * 4 bytes
vec3 velocity; // 3 * 4 bytes
float lifespan; // 1 * 4 bytes
};
Run Code Online (Sandbox Code Playgroud)
该结构具有16个字节的对齐,并且结构的大小很好地适合结构对齐的2倍.
第三个例子:
struct Particle {
float px, py, pz, s;
float vx, vy, vz;
float lifespan;
float age;
};
Run Code Online (Sandbox Code Playgroud)
该结构没有任何大于一个浮点大小的元素,因此结构的对齐只有4个字节.
解决方法可能是插入一个浮点数组作为显式填充或尝试将数据紧密地打包到结构对齐的大小倍数.