opengl - 使用 std430 限定符进行内存分配

标签 opengl glsl

我正在使用与 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/

相关文章:

java - opengl y轴不随x或z缩放

c++ - 为什么我的三角形是白色的?

math - 为什么我的 GLSL 着色器灯光会随着它所照射的对象在场景中移动?

opengl - 使用 GLSL 着色器进行图像处理?

opengl - ssh opengl错误:X错误的错误请求BadRequest

java - 处理 2.0b8/处置 PGraphics 对象和内存管理

android - fwidth() tegra 3 glsl

javascript - 用于平移和旋转的 WebGl 位置

debugging - 你们如何调试 GLSL?

opengl - 根据 2D 纹理的值对 1D 纹理进行采样