Which is better ?
-
To have one shader program with a lot of uniforms specifying
lights to use, or mappings to do (e.g. I need one mesh to be parallax mapped, and another one parallax/specular mapped). I’d make a cached list of uniforms for lazy transfers, and just change a couple of uniforms for every next mesh if it needs to do so. -
To have a lot of shader programs for every needed case, each one with small amount of uniforms, and do the lazy bind with glUseProgram for every mesh if it needs to do so. Here I assume that meshes are properly batched, to avoid redundant switches.
Most modern engines I know have a “shader cache” and use the second option, because apparently it’s faster.
Also you can take a look at the ARB_shader_subroutine which allows dynamic linkage. But I think it’s only available on DX11 class hardware.