Search code examples
opengl-esshaderdrawuniformopengl-es-3.0

Is it faster to use multiple shader programs or a single program with uniform uploads in OpenGL ES 3.0?


I have a setup where I use the same shader source for multiple objects rendered via VBOs and indices through glDrawElements(). I was wondering whether it's faster to create multiple GL shader programs and switch between them or use a single program and keep uploading the uniforms to the GPU before every draw call? I'm using OpenGL ES 3.0.

I'm mainly asking because I know that uploads to the GPU are considered expensive, but so are GL shader program switches.


Solution

  • It depends on your GPU vendor, your GPU, your driver version, and a lot of other factors. The best way to know which one is faster on the systems you're targeting is to measure.

    My bet is that changing a program is pretty slow in comparison to changing a couple of uniforms. There is an Nvidia presentation that compares the relative cost of different state changes (page 48), but it's almost 10 years old and it doesn't show actual numbers.

    If you want to lower the cost of uniform changes, you could use uniform buffer objects, because it's more efficient to send all uniforms to the VRAM once, instead of sending individual uniforms one by one (though the driver might be smart enough to optimize it). Another way could be using instanced (glDrawArraysInstanced) or multi-draw indirect (glMultiDrawElementsIndirect) rendering, but it's a bit more advanced topic.