I have several shaders with uniform variables, which have the same names in all shaders. What is the best way to update uniforms with same names in all shaders at once? I consider the following approaches:

1) Just store locations of that uniform for each program and update it just after the program is assigned as "used" program (glUseProgram).

Disadvantages: All "shared" uniform variables will be updated after each glUseProgram call. Moreover, if a program is being used not for the first time during the current frame, all glUniform* calls will be redundant. Alternatively there should be a set of flags which will tell if the program is used for the first time or not. "Unused" flags should be reset every frame.

2) Use uniform buffers and shared (or even std140) layout. In this approach we can set an uniform at once and then change shader programs without updating buffers. But what if there is a bunch of simple shaders, where the only shared variable is transformation matrix? Is it okay to use uniform buffers for such a small amount of memory? In some forum discussions I've read that

glBindBuffer(GL_UNIFORM_BUFFER,buf);
glBufferSubData(/*just 16 floats*/);
glBindBuffer(GL_UNIFORM_BUFFER,0);

is much slower than glUniform* call. Here we can notice, that the choice between first and second approach depends on the following conditions:

  • How often will the shaders change per frame and how often will they repeat?
  • How many "shared" uniforms are there?
  • What amount of data should be passed to shader program in each frame?

Is there any compromise design pattern which will have good performance regardless of answers for these three questions?

3) Use ubershader. Mentioned here in the second paragraph: opengl architecture glsl

Edit
Report