My program doesn't contain many vertices (about 200 vertices total, and all are animated), and I was wondering if it would be worth it to create two different sets of fragment and vertex shaders -- one for vertices that all share a color, and another for vertices that all have different colors. The problem is that I can't determine whether or not this would be a good idea if I have no idea what the typical cost off glAttachShader() and alUseProgram() is across devices. I know that the program I'm using currently practically doesn't use the GPU, but I find that this information is still very useful to know (and why not optimize anyways?).

  • 2
    \$\begingroup\$ Why would you need to use glAttachShader more than 4 times (Twice per color)? \$\endgroup\$
    – Bálint
    Commented Nov 18, 2017 at 17:37
  • \$\begingroup\$ @Bálint Once for the fragment shader, and once for the vertex shader. \$\endgroup\$
    – cpp plus 1
    Commented Nov 18, 2017 at 17:44
  • 2
    \$\begingroup\$ Yes, but that's still only 4 calls to it during the whole runtime of the program, it won't be the one causing the problems if there are any. \$\endgroup\$
    – Bálint
    Commented Nov 18, 2017 at 17:49

2 Answers 2


(and why not optimize anyways?)

Because when you actually have a performance issue, the answer is going to depend on the specifics of the situation. So premature optimization could lead you to the wrong answer.

But generally speaking, re-compiling shader programs is very slow. Switching shaders is also slow. For your situation, I'd guess that using a single shader would be almost guaranteed to be faster.

  • \$\begingroup\$ Would the single-shader approach be faster even if I have to make a switch-case statement and switch on a uniform? \$\endgroup\$
    – cpp plus 1
    Commented Nov 18, 2017 at 18:28
  • 1
    \$\begingroup\$ typically for different colors, you just pass the color as the uniform and set it directly instead of a switch and do e.g. uniform vec4 color; glFragColor = color; \$\endgroup\$
    – Jimmy
    Commented Nov 18, 2017 at 18:47

I profiled the efficiency of glUseProgram() by calling it multiple times in a loop, while drawing about 24 vertices (that each use 2 draw calls, in order to see if lag occurs) per frame.

I then ran the program with varying numbers of glUseProgram() calls per frame until I got a number that visibly produced occasional lag in drawing. I then subtracted 5,000 from this number (getting 75,000), in order to make sure that I was not missing any millisecond-long lag spikes (I repeated multiple times with that number of calls to make sure that the number I got was not just due to some random CPU speed-up), and deemed this to be the number of glUseProgramCalls() in a frame in order for the time of all the calls put together to take longer than a sixtieth of a second (which I'm guessing was the frame rate).

I was not multithreading and the speed of the phone gpu I was using was 1.4GHz. I divided 1.4 by 60 to get 23,333,333.3333 clock cycles per frame (or sixtieth of a second), and then divided that number by 75,000, to get (roughly) 311.1111 clock cycles per glUseProgram() call. What's even more astonishing is that 75,000 calls to glUniform(this, specifically: glUniform2fv(translateHandle, 1, (const GLfloat[2]) { .0F, .0F }) actually caused a considerable amount of lag (significantly more lag than even calling glUseProgram 90,000 times per frame).

I used an ASUS Zenfone 3 for this test, so this applies to recent devices.


You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .