How to avoid duplicate shader code?

Hey.

I’m using 3 shaders in a application currently. They all are affecting 3d Objects in my world,
but on different ways (actually the vertex shader is always the same, only the fragment shader changes).
Now i wanted to implement a light shader.

But how can i apply the light calculations to any texels, without copying the light code in every of the 3 shaders?
I mean, What an ugly code:


shader1
light....
.....
.....
....
....
light end
specific calculations


shader2
light....
.....
.....
....
....
light end
specific calculations

and so on.
So, how could i avoid this, and which approaches are there maybe to reuse parts of shaders or something like that?..

Another example: If you have one shader supporting textures, and one without them. U need both of them in the scene, but both
need lighning code…

Thank you for ideas or suggestions!

I’ve seen people on the forum add lines that say [icode]#include “someLightShader”[/icode] and then just insert the code from that file as they read line by line.

+1 for CopyableCougar4’s solution.

Alternatively as I understand it you can attach as many shaders as you like to a program provided there’s only 1 main()… so correct me if I’m wrong here but you could stick your computation functions into “library” shader functions and just call into them.

Cas :slight_smile:

For different permutations I like to just use simple #defines. Easy to code and maintain. Code is in one place and can also be edited in 3rd party ide without your engine.(shader profilers, debuggers)

i don’t understood this part… what do you mean with insert the code? I thought you would add the “include” in the shader?
But what is someLightShader? Shader Programs have Id’s, no names :stuck_out_tongue:

You have 2 mains attaching one fragment and one vertex shader, have’nt you?

Could you explain that a bit more? I did’nt understand how i can use this now to achieve shader code reusing…

Clarification: one main() per shader type. So one main() in the total vertex shaders, and one main() in the fragment shaders.

Cas :slight_smile:

They whisper that attaching multiple shaders of the same type to a program results in a degraded optimisation capability. :persecutioncomplex: I never tried it, so YMMV.

It used to be completely broken in some drivers. No idea about the current state.

Let us assume for now that it simply crashes Intel drivers, unexpectedly produces working results on Nvidia drivers despite incorrect inputs and assumptions, and doesn’t work on AMD because of correctly implemented specifications which state “unspecified behaviour” in cases where Nvidia picked a sensible fallback.

Cas :slight_smile:

Following is in the docs:
(https://www.opengl.org/sdk/docs/man/html/glAttachShader.xhtml)

[quote]It is permissible to attach multiple shader objects of the same type because each may contain a portion of the complete shader
[/quote]
.

skys0ldier: Let us assume that you have method for reading a shader into a string. As you read each line, you check if the line starts with #include. If it does, then you parse out the requested shader and read the shader source from the referenced file and append the source to your shader as you read it.

aahh you mean on cpu side ^^
Okay, now it’s clear. Of course, this is a nice option.

Thank you :slight_smile:

Okay, it works now with attaching a shader to many programs.
I still have to put the prototypes of the functions, but i think this is a
good thing to keep track of the shader structure.

I’ll probably implement the method described by Copyable, if this
does’nt work an all gpu’s.

Thank you all :slight_smile: