1

I want to render a volume(VERSION combined with programmable pipeline and fixed pipeline) using only programmable pipeline (no fixed pipeline) which using glsl. To achieve this, I need multipass the renderer which means render different scene with different shaders in a sequential order. There are three methods come to my mind:

  1. using one shader program and detach shader -> attach shader -> recompile program whenever rendering new scene.
  2. using one shader program per pass, then there exits multiple shader programs.
  3. using subroutines in glsl to choose different subroutines when render different pass.

I wonder when should I use the 1st method? 2ed method? etc. can any experienced developer help?

Community
  • 1
  • 1
toolchainX
  • 1,998
  • 3
  • 27
  • 43

1 Answers1

1

Many problems can be solved without multiple passes. Just try to make a technique without them. If nothing else works use method 3.

My thoughts about this:

  • Method 1 is very slow and unuseable.
  • Method 2 is much work but if done well it is "fast".
  • Method 3 is easy and elegant but has a additional processing overhead. You may render your object several times and pass your current pass number to your shader.

Example for method 3:

uniform int currentPass;

/* OTHER UNIFORMS */

void main()
{
    if(currentPass == 1)
    {
         /* DO SOMETHING */
    }
    else if(currentPass == 2)
    {
         /* DO SOMETHING */
    }
    else if(...) { ... }
}

On my mind the best approach is to use only very few shaders (maybe one material shader, one post processing shader, etc.), so your method 3 is nearly perfect.

Ever thought about uber-shaders? They are something "like" your method 3. Google it :) I recommend also this question.

Also be careful, the if-statements may weaken your performance very much.

Community
  • 1
  • 1
pearcoding
  • 1,149
  • 1
  • 9
  • 28
  • I searched the uber-shaders. but it seems that uber-shaders use something like `#ifdef` and `#endif` macro in the shader files. How can I choose the different snippets of shader files in shader files on the runtime by using `#ifdef` and `#endif`? can I set the define macro in my OpenGL program in the `render()` function? – toolchainX May 16 '12 at 02:50
  • No, there is no preprocessor to do something like this. You must use tools/libraries like [Boost::Wave](http://www.boost.org/doc/libs/1_49_0/libs/wave/index.html) to preprocess the code first. After that you can compile/execute the shader. – pearcoding May 16 '12 at 13:41
  • But maybe this will help you: [externally-define-preprocessor-macros-in-glsl](http://stackoverflow.com/questions/2378448/externally-define-preprocessor-macros-in-glsl) – pearcoding May 16 '12 at 13:57
  • 1
    I search the Internet and found a good solution by using a new feature `subroutine` in glsl 4.0. here is some [infomation](http://www.packtpub.com/article/opengl-glsl-4-using-subroutines-select-shader-functionality) – toolchainX May 17 '12 at 00:57
  • This is a really great feature! Thanks for sharing... :) – pearcoding May 17 '12 at 09:18