Best way to organize GLSL programs?

Hi! I’m new to GLSL and overall to shader development, so I wanted to ask a design question:

First of all, imagine I want to write all the shading of my game project by hand (as in, not use the fixed pipeline). Is there any gain in this? or using the fixed pipeline will be always faster/slower?

Second, how are shader programs organized? I can see you have functions and conditionals, is it better to have only one shader with many functions/conditionals, and depending material/texture properties, do something or something else with a conditional?
Or should I focus on make a small, separate shaders for every specific thing?

Third and last. I’m not sure wether it is possible to feed custom data arrays. Say I want to do skeletal animation with skinning, for example, I’d need to pass weights and matrices to the vertex program for that, is this a good idea?


On current cards the fixed functionality will mostly be emulated via shaders internally. You can most likely get better performance with shaders when you tailor them to your specific need.

Yes, you can have functions and conditionals. You could even compile different shader source files and link them together just like in C/C++. But generally it is better to just have a single shader source file as the linking of multiple shader object files made some problems with drivers.

Functions are there to structure your source code and reduce code duplication. You can do ifs and also loops but in OpenGL GLSL it is hard to check wheter a given shader will run in shader model 2.0 or even requires 3.0 or more. This is a real problem with OpenGL GLSL since you can not easily tell wheter a software fallback will be used in such cases. You would have to test.

Writing a single uber shader with many conditionals depending on various variables/properties of materials or whatever is generally not a too good idea especially on SM 2.0 cards where you will run out of instructions soon. And even with SM 3.0 which has conditional branching a specialized shader will most likely be faster that a big uber shader. But you may want to have a look at how Half Life 2 shading works. They basically have a large uber shader where it’s features can be toggles wia constant boolean or integer variables. ifs on constant values will be evaluated at compile time and no extra checking cost will be generated. For rendering with different materials they generate the correct shader permutation and use that for rendering.

You can pass custom data arrays with glVertexAttribPointer. And you can matrices for skinning as uniform parameters.

[ | vector_math (3d math library) | software renderer ]