我的着色器有一个统一的 block :
layout (std140) uniform LightSourceBlock
{
vec3 test;
vec3 color;
} LightSources;
这个 block 的数据应该来自一个像这样创建的缓冲区对象:
GLuint buffer;
glGenBuffers(1,&buffer);
GLfloat data[6] = {
0,0,0,
0,0,1
};
glBindBuffer(GL_UNIFORM_BUFFER,buffer);
glBufferData(GL_UNIFORM_BUFFER,sizeof(data),&data[0],GL_DYNAMIC_DRAW);
缓冲区在渲染前链接到统一 block :
unsigned int locLightSourceBlock = glGetUniformBlockIndex(program,"LightSourceBlock");
glUniformBlockBinding(program,locLightSourceBlock,8);
glBindBufferBase(GL_UNIFORM_BUFFER,8,buffer);
根据我的理解,这应该是将着色器中 block 内的“颜色”设置为 (0,0,1),但我得到的值是 (0,1,0)。
如果我从 block 中删除“测试”变量并且只将三个 float (0,0,1) 绑定(bind)到着色器,它会按预期工作。
这是怎么回事?
最佳答案
因为您确实为您的 UBO 指定了 layout (std140)
,所以您必须遵守此处定义的对齐规则。该布局首先在 OpenGL 3.2 core spec 中指定(在核心中) ,“标准统一 block 布局”小节中的第 2.11.4 节“统一变量”:
- If the member is a scalar consuming N basic machine units, the base alignment is N.
- If the member is a two- or four-component vector with components consuming N basic machine units, the base alignment is 2N or 4N, respectively.
- If the member is a three-component vector with components consuming N basic machine units, the base alignment is 4N.
- If the member is an array of scalars or vectors, the base alignment and array stride are set to match the base alignment of a single array element, according to rules (1), (2), and (3), and rounded up to the base alignment of a vec4. The array may have padding at the end; the base offset of the member following the array is rounded up to the next multiple of the base alignment.
- If the member is a column-major matrix with C columns and R rows, the matrix is stored identically to an array of C column vectors with R components each, according to rule (4).
- If the member is an array of S column-major matrices with C columns and R rows, the matrix is stored identically to a row of S C column vectors with R components each, according to rule (4).
- If the member is a row-major matrix with C columns and R rows, the matrix is stored identically to an array of R row vectors with C components each, according to rule (4).
- If the member is an array of S row-major matrices with C columns and R rows, the matrix is stored identically to a row of S R row vectors with C components each, according to rule (4).
- If the member is a structure, the base alignment of the structure is N, where N is the largest base alignment value of any of its members, and rounded up to the base alignment of a vec4. The individual members of this substructure are then assigned offsets by applying this set of rules recursively, where the base offset of the first member of the sub-structure is equal to the aligned offset of the structure. The structure may have padding at the end; the base offset of the member following the sub-structure is rounded up to the next multiple of the base alignment of the structure.
- If the member is an array of S structures, the S elements of the array are laid out in order, according to rule (9).
对于您的情况,第 3 点适用。因此,您需要在第二个 vector 开始之前填充另一个 float 。
关于c++ - OpenGL/GLSL - 统一 block 数据值不正确,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20807797/