Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

GLSL Problem: Multiple shaders in one program

I must have misunderstood something with shaders:

I thought that as you can attach multiple shaders to one program, you'd be able to simply attach more than one fragment shader, as an example: A crate texture rendered with a color modulation and refraction.

But apparently this is not the case, as you can have only one main function per program.

  • How can I work around the main function limit and allow for any dynamic combination of multiple fragment shaders which are in the same program and called after each other?
like image 357
Nightshade Avatar asked Aug 29 '11 21:08

Nightshade


People also ask

How many shaders can you have in OpenGL?

The OpenGL-required minimum is 1 for fragment shaders, 8 for compute shaders (note: possible spec typo), and again 0 for the rest. The maximum number of different shader storage blocks that a stage can use. For fragment and compute shaders, the OpenGL-required minimum is 8; for the rest, it is 0.

Can you use multiple shaders OpenGL?

Multiple shader objects of the same type may not be attached to a single program object. However, a single shader object may be attached to more than one program object. However, even in OpenGL, using multiple shaders of the same type does not work they way you outline it in your question.

Can you have multiple vertex shaders?

This allows you to actually have several different pixel and vertex shaders in the same file. The second way to reduce performance impact is to set the shader, render every object that uses that shader, then repeat. In other words, batching your rendering.

How do I optimize GLSL?

One way to speed up GLSL code, is by marking some variables constant at compile-time. This way the compiler may optimize code (e.g. unroll loops) and remove unused code (e.g. if hard shadows are disabled). The drawback is that changing these constant variables requires that the GLSL code is compiled again.


1 Answers

You can have a set of entry points pre-defined. Suppose you have a limited number of effects (diffuse, specular, environment, etc). None of them is applied at most once, so you just need to create a managing shader like that one:

void apply_diffuse();
void apply_specular();
void apply_environment();

void main(){ ...
     apply_diffuse();
     apply_specular();
     apply_environment();
...}

Then, when it's time to link the shader program you attach the corresponding implementations as separate GLSL objects. Some implementations may be dummies if you don't want the effect. This approach doesn't require source text parsing and has next to no performance penalty.

like image 89
kvark Avatar answered Sep 17 '22 07:09

kvark