首页 > 解决方案 > 存储缓冲区和错误对齐的数据

问题描述

我正在为我的存储缓冲区提供一些材质,以便我的着色器可以拥有我试图绘制的对象的材质,但颜色不对应,我认为这是由于内存对齐,但我是 opengl 的新手所以我没有找到错误

struct Material
{
    Color diffuse;
    Color specular;
    Color emission;
    float ns;

    Material( ) : diffuse(0.8f, 0.8f, 0.8f), specular(Black()), emission(), ns(0) {}
};
struct Color
{
    float r, g, b, a;
};

和我的片段着色器

struct Material
{
    vec4 diffuse;
    vec4 specular;
    vec4 emission;
    float ns;
};

layout(binding=1) readonly buffer IndexBlock{
    uint color_indices[];
};

layout(binding=2) readonly buffer MaterialBlock {
    Material materials[];
};

主要是:

uint color_index = color_indices[gl_PrimitiveID];
vec3 frag_color = materials[color_index].diffuse.xyz;

标签: openglglsl

解决方案


我建议使用std140or std430 layout qualifier

请参阅OpenGL 4.6 API 核心配置文件规范;7.6.2.2 标准统一块布局

[...]

  1. 如果成员是一个结构,则结构的基本对齐为 N,其中 N 是其任何成员的最大基本对齐值,[...]
  2. 如果成员是 S 结构的数组,则数组的 S 元素按照规则 (9) 按顺序排列。

您可以向 c++ 结构添加 3 个浮点数。但最好使用alignas 说明符并将结构对齐到 16 个字节:

struct alignas(16) Material
{
    Color    diffuse;
    Color    specular;
    Color    emission;
    float    ns;

    // [...]
}

着色器:

struct Material
{
    vec4 diffuse;
    vec4 specular;
    vec4 emission;
    float ns;
};

layout(binding=1, std430) readonly buffer IndexBlock{
    uint color_indices[];
};

layout(binding=2, std430) readonly buffer MaterialBlock {
    Material materials[];
};

std140和之间的区别在于std430,对于std140标量和向量数组以及结构的基本对齐方式和步幅,四舍五入到 a 的基本对齐方式的倍数vec4。情况并非如此std430


推荐阅读