Why more than a shader?

What’s the utility of having more than two, say vertex or fragment, shaders linked on a program?

You can’t attach more than one of each vertex and fragment shader to each program object since it wouldn’t make much sense to do so.

Fron the orange book, Chapter 7.3, page 164:
“There is no inherent limit on the number of shader objects that can be attached to a program object.”

GLSL does allow you to attach multiple shader objects to a program object and I find it very useful. I put common functions into their own shader object and then attach the ones needed to a program object to make up a particular shader to acheive a specific effect. This way I don’t have to duplicate the common functions in every shader source. Functions that I seperate into their own shader object are routines that calculate specular, diffuse, noise, etc.

For the shader object that contains void main(), the function prototypes for the external functions (located in another shader object) are declared in the source. Its a great way to modularize a shader library and save on cutting and pasting text.

It works well on ATI cards with the Catalyst 4.8 driver.

It does not work on NVidia cards with the 61.77 driver. NVidia’s compiler complains that a main entry point is not found in the source for shader objects not having a main function. So it seems that NVidias compiler wants to find a main function in every shader object. The spec clearly states that only one shader object of a particular shader type(vertex, fragment) has to have a main() function. The program object linking stage resolves external function references. The compiler also complains about shader objects that call an external function since only the function prototype is found in the source. Growing pains for sure with 61.77 release.

But anyway, multiple shader objects can be attached to a program object. Remember though that there can only be one vertex main() and one fragment main() declaration. Some will find it hard getting used to using multiple shader objects since traditionaly you had one vertex and one fragment program that worked together. As vertex and fragment programs get larger it makes sense to break them up into functions located in seperate shader objects that other shader object can access.

Originally posted by Humus:
You can’t attach more than one of each vertex and fragment shader to each program object since it wouldn’t make much sense to do so.
Nope, nfz is right. You are able to attach more than one shader object to a program object. I tried this out some time ago and it works on ATI (don’t know about NVidia):

<<Vertex Shader #1>>

vec4 MyVertexTransformFunction();

void main()
{
gl_Position = MyVertexTransformFunction();
}

<<Vertex Shader #2>>

vec4 MyVertexTransformFunction()
{
return ftransform();
}

Thanks you all you the answers. I’ll try it with my Nvidia card under linux to see if it works.

Hmm, seems I’ve missed that. Didn’t know you could compile partial shaders like that and link it all together. That could indeed be useful sometimes. :slight_smile: Attaching several complete shaders wouldn’t make sense though, and while I haven’t checked this against the spec I would assume that would return an error.

nfz, The next public release of NVIDIA’s driver will largely fix the problems with using multiple shader objects.

I have no doubt that they will.

This topic was automatically closed 183 days after the last reply. New replies are no longer allowed.