Different shader(programs) for different animations

Hello,

I’m currently experimenting with shader-based animation of 2D-objects. One of that objects is supposed to have multiple animation-options with the possbility to switch between them on runtime. Thats all fine and stuff my question now is:

Does it make sense (in consideration of performance and code-design) to wirte a sperate shader-pair (vert & frag) for each animation in constrast to writing a single shaderprogram and abstract the uniforms/attribs to a higher level (so they fit for all the different animations).
Note that in my case no textures are involved. Procedural only!

With my limited experiance I see these points on each side:
Single program:

  • no switching between programs (performance?)
  • less efforts client-sided due to standardized structures for uniforms/attribs
  • (significant) more complex and confusing shader-code
  • possibly unnecessary uniforms/attribs (certain animations might not need all the “space”)

Multiple programs:

  • clean shader-code
  • less uniforms/attribs in each shader
  • switching between programs necessary
  • possibly more efforts on client-side needed

What do you think?
greenOwl

Switching between programs is not a problem at all when considering performance. Seeing as that is the cleanest and easiest-to-maintain way, I say go for that.

Always go with the cleanest solutions until you begin noticing performance problems.

an easy way not to have to write thousends of lines of shader code which are all nearly the same you can use “interfaces”.

When you create a shader you can pass a String[] to the gl call. what this does is just appending the strings inside the array. So you can do something like this

new String[]
{
“float animate(float time, float start, float stop)
{
return (stop-start)*time+start;
}”,

"uniform float time;

void main()
{
gl_Position = new vec4(animate(time, 2, 10));
}"
}

then you can put your main shader code in one file and create for each animation style another. And runtime you then can create a shader programm for each file in your animation dir for example.

Binding a new shader is about expensive as binding a texture. Depending on gpu thought. But sending lot of uniforms is not cheap either. So profiling is only way so know which one is better.

But keep in mind that making multiple shaders that share some amount of duplicate code is maintenance hell. Every time you fix a bug you need to remember fix it from multiple different shaders same with adding new stuff. So if you plan to make many animation shaders I do not recommend this approach.
So after certain complexity data driven systems start to excel. Shaders can be optimized with ifdefs or shader generation if you need to strip away nonused features.

The “interface”-thingy danny02 suggested sounds quite nice. The downside I see with his solution is a lot of shader-initialization (glShaderSource - … - glLinkProgram) calls each time I want to change the animation and have to remove, attach and recompile the shader. I dont know for certain, but I belive that this is not quite the optimum concerning performance and such.

@pitbuller
Yes thats why I really don’t want to an entire shader for each animation. What do you suggest instead? 1000+ lines per file seem really uncomfortable as well.
That do you mean with “data driven systems”?

Exactly what are these “animations”? To me, “to animate” just means to switch between different textures. I don’t see where shaders come in there, and even less why you need multiple shaders for it.

Then again, I agree with ra4king. If it works at the moment, just leave it as it is. Exactly how many sprites or objects are we talking about?

I work completely without textures. Some expamples of animations I wrote already:

Change coordiantes of vertices to create all kinds of animation based on modifying the shape of my entity (e.g. modify the coordinates in a circular motion to create a wobbly-effect of my entity.
Use procedural methods in the fragment shader (e.g. noise, gradient-fills, shapes, …)

Currently I’m just fiddling around with opengl and shaders. I could imagine a total of ~100 objects not counting particles and other effects.