opengl - 存储缓冲区和错误对齐的数据
问题描述
我正在为我的存储缓冲区提供一些材质,以便我的着色器可以拥有我试图绘制的对象的材质,但颜色不对应,我认为这是由于内存对齐,但我是 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;
解决方案
我建议使用std140
or std430
layout qualifier。
请参阅OpenGL 4.6 API 核心配置文件规范;7.6.2.2 标准统一块布局:
[...]
- 如果成员是一个结构,则结构的基本对齐为 N,其中 N 是其任何成员的最大基本对齐值,[...]
- 如果成员是 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
。
推荐阅读
- android - 如何在 FirestoreRecyclerAdapter 中添加 2 个不同的查询?
- javascript - 单击一个按钮会折叠所有 div 而不是它所属的 div
- php - Laravel 5.6 - 雄辩的多对多错误1066
- swift - 是否可以让枚举类型将它们存储在 Swift 4 的集合中?
- javascript - html复选框取消单击隐藏函数变量
- react-native - 如何在 React Native Text 元素的文本中放置颜色?
- django - 在Django的另一个for循环中循环for循环
- javascript - ember.js 如何插入新记录?
- azure - 如何在 azure applications 洞察力中执行不同的声明?
- sql - 使用 shell 脚本创建了一个数据库,但是不允许用户登录