C++ 统一缓冲区对象未对齐。GLSL访问中断
使用GLFW、GLEW(尽管这不重要) 将结构传递给片段着色器时,会观察到意外行为: 如果我直接传递环境光颜色:C++ 统一缓冲区对象未对齐。GLSL访问中断,c++,opengl,glsl,C++,Opengl,Glsl,使用GLFW、GLEW(尽管这不重要) 将结构传递给片段着色器时,会观察到意外行为: 如果我直接传递环境光颜色: out vec3 color ... color = MaterialCols.ambient 一切正常。通过漫反射时,其偏移量为1(即绿色通道为红色,蓝色通道为绿色) 通过“镜面反射”时,第一个值是上一个vec3(漫反射)的绿色通道 我认为这是一个一致性问题。似乎GLSL只想在特定的对齐方式上访问VEC3组件,或者C++代码添加一些填充(原因不明)。 这是数据分配。它作为统一缓冲
out vec3 color
...
color = MaterialCols.ambient
一切正常。通过漫反射时,其偏移量为1(即绿色通道为红色,蓝色通道为绿色)
通过“镜面反射”时,第一个值是上一个vec3(漫反射)的绿色通道
我认为这是一个一致性问题。似乎GLSL只想在特定的对齐方式上访问VEC3组件,或者C++代码添加一些填充(原因不明)。
这是数据分配。它作为统一缓冲区对象传递。如果需要,我可以添加使用的代码
C++:
GLSL:
根据derhass的评论,以及OpenGL 3.2核心规范中标题为“统一变量”的相关第2.11.4节: 三,。如果成员为三分量向量,且分量消耗N个基本机器单元,则基本对齐为4N
这样,通过使用第一个VEC3之后的浮点填充C++结构,将扩散带对齐。 C++
UBO有非常清晰的对齐规则(当使用一个标准布局时,或者如果您不这样做,实现可能会强加它自己的规则)。看看有没有类似的问题。你完全正确。如果我早点发现这些规则,我就不会问这个毫无意义的问题了。非常感谢。嗯,这部分是正确的(
diffuse
现在已对齐)。。。但是,如果您打算使用镜面反射,也会出现错位。我还建议您在统一块声明中添加layout(std140)
,以保证这种行为。这些规则适用于std140
,这不是默认布局,默认情况下,统一缓冲区以实现定义的方式打包,您应该查询偏移量。在这里您可能会很幸运,您的实现正在为其实现定义的打包选择std140
规则,但您不能依赖于此。我添加了布局(std140)。这仍然意味着我必须走对吗?它只是确保所需的对齐是标准的,使其能够跨平台移植?
typedef struct material_colors{
glm::vec3 ambient;
glm::vec3 diffuse;
glm::vec3 specular;
}material_cols;
uniform MaterialColors {
vec3 ambient;
vec3 diffuse;
vec3 specular;
} MaterialCols;
typedef struct material_colors{
glm::vec3 ambient;
float padding;
glm::vec3 diffuse;
glm::vec3 specular;
}material_cols;