Reputation: 414
I'm currently planning out a renderer and I have 2 different ways I could handle shaders. I've written pseduo-code for them:
Example A
for all models {
bind all vertex data for the model
for each shader on this model {
set shader
upload uniforms
draw indicies for this shader
}
}
Example B
for all models {
collect geometry and seperate it by shader
}
sort geometry by shader into groups
for all shaders {
set shader
upload uniforms
draw geometry group for this shader
}
The advantage of Example A is that we only have to upload the vertex data one time and it's shared for all the geometry. The downside of this is I have to constantly change the shader and upload uniforms to it.
The advantage of Example B is that I can sort all the geometry in the entire scene by shader so I only have to apply each shader 1 time for the whole draw. This also means that I will have more on the draw stack at any given time so there is less "idle" time after a drawing for a shader is finished.
Which way would end up being better on performance? Based on what I've read I'm leaning towards Example B but I'd like to learn a little more about it.
Upvotes: 3
Views: 1019
Reputation: 162164
Like so often with OpenGL it depends on the implementation (=driver) in question.
For example early NVidia drivers were prone for complete shader recompilation when Uniform values changed (so changing a uniform could be much more expensive than switching a texture or shader). Later this bottleneck was removed and changing a uniform value became a rather cheap operation (cheaper than switching a texture or a shader).
As with all performance related questions: You have to profile your program and test out your options.
Upvotes: 3