用于制服和变化的OpenGL和GLSL内存对齐
我想到了一些令我困惑的东西,我无法找到答案。当我写的着色器是这样的:用于制服和变化的OpenGL和GLSL内存对齐
layout (location = 0) in vec3 inPosition; layout (location = 1) in vec3 inNormal;
layout (location = 2) in vec2 inTexCoords;
我知道VEC3的不对齐,许多vec4的是,或SIMD兼容的数据类型的16字节。我知道这(我想),因为我在我的C++代码数据是:
struct Vertex {
vec3 position;
vec3 normal;
vec2 texCoords;
};
每个矢量彼此位于紧贴地,无填料,尺寸为8 *的sizeof(浮动),32个字节。我把它传递给制服,着色器读取它很好,所以我知道它们都是对齐的。
但是,当涉及到在GLSL均匀块,与例如std140标准一个VEC3必须用一个额外的4个字节填充添加另一VEC3或vec4之前:
- 如果构件是与耗时N基本机器单元部件三个成分的矢量,基座对准为4N
但是也可以存储在VEC3和下一VEC3之间的四字节int或四字节布尔压实尺寸。那么这是否意味着顶点布局的attrib指针值不遵循std140布局?另外,如果我在我的C++代码中使用SIMD 16字节对齐的向量,这是否意味着我将不能再将attrib指针值设置为vec3,vec3,vec2,而是拥有所有vec4的?
而且我看到的文件上以下警告:
警告:实现有时得到std140布局错 VEC3组件。建议您手动填充 结构/阵列,并避免使用vec3。
这里说的是避免使用vec3,但我认为这是一个聪明的节省空间的技术,在vec3之后打包一个四字节的int或bool。
回答:
std140布局仅适用于interface blocks,而不适用于接口块外的缓冲区或属性的内容。由于接口块不能用作顶点着色器的输入或来自片段着色器的输出,因此std140不会以任何方式影响如何设置glVertexAttribPointer
或顶点数据如何存储。
关于警告:是的,使用vec3之后的空间来存储和int/float/bool是一个聪明的技巧。但正如警告所述,驱动程序的实现有时会出错。所以如果你想确保你的代码在任何地方都能可靠地运行,你要么测试很多,要么根本不使用vec3。再次请注意,这只在接口块的情况下才有意义。普通的vec3制服不会被这个感动。
你可以做的是打包存储3个浮点数和一个int在你的C++端,但通过接口块中的vec4访问它。您可以使用floatBitsToInt(myBlock.myVec4.w)
来检索整数。
以上是 用于制服和变化的OpenGL和GLSL内存对齐 的全部内容, 来源链接: utcz.com/qa/259791.html