Talk:Uniform Buffer Object

From OpenGL Wiki
Jump to navigation Jump to search

Gotcha?[edit]

I removed this:

When uploading matrices into your UBO, if your layout is std140, your matrix rows might need to be padded to a specific size, just like how vec3s might need to be be padded to vec4s. For example, when uploading a mat3, send a mat4 and let your shader cast it back to a mat3 in the uniform block declaration.

This is not true. This may be in reference to some driver bug that someone encountered. If so, then it should be explicitly marked as such, with a driver version and the hardware it affects (NVIDIA/ATI/etc).

OpenGL is very clear on how std140 works. There is no ambiguity on the matter; there is no "might" anything. That's the whole point: to know up-front how big stuff is. This page is for describing how OpenGL works. Alfonse 11:24, 7 December 2011 (PST)

Hi Alfonse, thanks for your response. I used "might" in the context of "this might be your problem." I agree it was a poor choice of words. Maybe you can help me clarify what the Red Book says about matrices in std140?:
Stored as an array of C vectors each with R components, and potentially padded like other arrays. If the variable is an array of M column-major matrices, it is stored as an array of M C vectors each with R components (and potentially padded).
Does this mean that a mat3 is treated as an array of vec3s, and is therefore padded like vec3s are padded to vec4s? Thanks in advance for clearing this up. Amoffat 16:17, 7 December 2011 (PST)
The best place to learn how std140 works is to look at the actual specification. The pertinent rules are:
3. If the member is a three-component vector with components consuming N basic machine units, the base alignment is 4N.
4. 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.
5. 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 compo-nents each, according to rule (4).
So a mat3, under std140, will effectively use a vec4 for each column. But so will a mat2, since it rounds the alignment and stride up to that of a vec4.
Ok that makes sense and is consistent with the problem I was encountering. Basically I had a UBO delcaration of mat4, mat4, mat3 in my shader. I was using glm::mats on my client code and uploading data to my UBO with glm::value_ptr() and glBufferSubData with the correct offsets. The first two mat4s got to the shader just fine, however, the mat3 was giving me problems. I was uploading it with the offset sizeof(glm::mat4) * 2, and with a size sizeof(glm::mat3). But it was never right in the shader. After days of debugging and verifying that the matrix was correct, I tried sending it as a mat4, but leaving the mat3 declaration in the shader. This worked, which seems consistent with what you're saying about how opengl treats matrices in std140. So I have 2 questions then: 1) Do you think the behavior of an incorrect mat3 is a driver bug? and 2) Is there anywhere more appropriate where I can list this difficulty I ran into to hopefully save others some time? Thanks Alfonse Amoffat 11:35, 8 December 2011 (PST)