TL;DR: Driver bugs.
In my tests as of today (Oct 2016) uniform buffers are not supported properly by most drivers out there.
Some don't respect glUniformBlockBinding some don't update the uniform data (glBufferSubData and glBufferData) properly, where the shaders' / GPU cached internal copies of said buffers are not kept coherent.
The way I understand it (and the way Nvidia also understands it)
- Bind/Map your Uniform Buffer Object to a global table shared by all shaders inside the OpenGL driver/GPU using
glBindBufferBaseorglBindBufferRange. - Map the shader's uniform buffer accesses to an entry into that global table using
glUniformBlockBinding(shader_id, shader_ubo_index, global_ubo_index);this setting is per shader program, not shared globally.
Note: global_ubo_index is NOT the name of the uniform buffer object but an index into that global table.
This "complexity" (which is a great feature to share UBOs between different shaders, such as lighting values) seem to be what most OpenGL drivers get wrong. To be fair the wording in the OpenGL documentation isn't the most unambiguous it could be either.
I had to resort back to using plain old uniforms for other drivers.
Both screenshots using uniform buffer objects, two different drivers:
