OpenGL 规范是谎言(或者这是一个错误?)...参考 std140 的布局,具有共享的统一缓冲区,它指出:
“GLSL 编译器使用表 L-1 中显示的规则集来
std140 合格的统一块中的布局成员。的偏移量
块中的成员根据块的大小进行累积
块中的先前成员(在变量之前声明的成员)
问题)和起始偏移量。第一个的起始偏移量
成员始终为零。
标量变量类型(bool、int、uint、float) - 标量的大小
基本机器类型"
(http://www.opengl-redbook.com/appendices/AppL.pdf)
因此,有了这些信息,我在着色器中设置了一个统一块,如下所示:
// Spotlight.
layout (std140) uniform Spotlight
{
float Light_Intensity;
vec4 Light_Ambient;
vec3 Light_Position;
};
...只是发现它不适用于我在 CPU 端设置的后续 std140 布局。也就是说,前 4 个字节是 float(GLfloat 的机器标量类型的大小),接下来的 16 个字节是 vec4,接下来的 12 个字节是 vec3(最后剩下 4 个字节以考虑规则) vec3 实际上是 vec4)。
当我更改 CPU 端以将浮点指定为与 vec4 大小相同(即 16 字节)并执行此假设的偏移量和缓冲区大小时,着色器将按预期工作。
因此,要么是规范错误,要么是我误解了“标量”在这种情况下的含义,或者 ATI 有驱动程序错误。谁能解开这个谜团?
您链接到的 PDF 是not the OpenGL规范。我不知道你从哪里得到的,但这肯定不是full规则列表。经常检查你的消息来源;该规范并不像许多人声称的那样难以阅读。
是的size基本类型变量的大小与基本机器类型相同(即:4 个字节)。但大小本身并不能决定position变量的。
每种类型都有一个基本对齐方式,无论该类型在统一块中的何处找到,它都是整体字节偏移量must适合该对齐方式。 a 的基本对齐方式vec4
是 4 * 其基本类型(即:float)的对齐方式。所以 a 的碱基对齐vec4
is 16.
Because Light_Intensity
在 4 个字节后结束,编译器必须插入 12 个字节的填充,因为Light_Ambient
cannot位于 4 字节边界上。它必须位于 16 字节边界上,因此编译器使用 12 字节的空白空间。
ATI 确实在 std140 布局方面存在一些驱动程序错误,但这不是其中之一。
作为一般规则,我喜欢明确地将填充放入我的结构中,并且我避免vec3
(因为它有 16 字节对齐)。这样做通常会减少编译器错误以及对事物的去向和实际占用的空间的意外误解。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)