我的着色器源是这一个:
#version 330
uniform mat4 camera;
struct S {
vec2 v;
mat2 m;
};
layout(std140) uniform SS {
S s[2];
};
in vec2 v;
void main () {
gl_Position = camera * vec4(v.x + s[0].m[0][0], v.y, 0.0, 1.0);
}
当我问我的制服块有多大时,GL回答96
。但是,如果我假设mat2
是4个浮点数,vec2
是2个浮点数,我有两个浮点数,而float
是4个字节,那么:
(4 + 2) * 2 * 4 = 48
我发现48
个字节......为什么这么多?
也许它来自我的结构的对齐到4个字节。在我的vec2
:
(4 + 2 + 2) * 2 * 4 = 64
这是64
,不是 96
。那我在哪里错了?事实上,我非常确定我的浮点数是4个字节,因为我可以在它们相互跟随时检索它们......
答案 0 :(得分:3)
信不信由你,这对于std140
布局来说是正常的。要了解原因,您需要阅读下面列出的对齐规则:
规则(4):
如果成员是标量或向量的数组,则根据规则(1),将基本对齐和数组步幅设置为与单个数组元素的基本对齐匹配(2),(3), 向上舍入到
vec4
的基本对齐方式。阵列末端可能有填充;数组后面的成员的基本偏移量向上舍入到基本对齐的下一个倍数。规则(5):
如果成员是具有 C 列和 R 行的列主矩阵,则矩阵与 C 数组的存储方式相同根据规则(4),每个 R 组件的列向量。
我已经重新编写了您的数据结构,以便从std140
对齐的角度说明它的外观:
struct S {
vec2 v;
vec2 v_padding; // NEW (satisfies rule 4 -- mat2 has base alignment 4N)
//mat2 m; // ORIGINAL (re-written below for alignment -- see rule 5)
vec2 m0;
vec2 m0_padding; // NEW (satisfies rule 4 -- column vectors are aligned to 4N)
vec2 m1;
vec2 m1_padding; // NEW (satisfies rule 4 -- column vectors are aligned to 4N)
};
vec2 v
- > 2N + 2N mat2 m
- > 2N + 2N + 2N + 2N 总结构尺寸(以机器为单位):4N + 8N = 12N
S s [2]
:12N * 2 = 24N * 4 / N = 96
这里最大的问题是使用mat
类型。
矩阵被视为向量数组,这会增加额外的对齐奇数。在某些情况下,你可以通过使用行主矩阵解决这些奇怪的问题,但是因为这是一个方形矩阵,不会有任何帮助。
我建议您将数据打包到mat2
,而不是vec4
。
struct S {
vec2 v; // 2N + 2N (padding)
vec4 m; // 4N
}; // 8N
2N + 2N + 4N = 8N * 2 * 4 / N = 64字节
如果您的着色器中确实需要vec4
,则可以编写一些额外的代码将mat2
解压缩到mat2
变量中。