Part of the Khronos Group
OpenGL.org

The Industry's Foundation for High Performance Graphics

from games to virtual reality, mobile phones to supercomputers

Results 1 to 4 of 4

Thread: Is uber shader with if statements still bad practice?

  1. #1
    Junior Member Newbie glnoob's Avatar
    Join Date
    Sep 2010
    Posts
    19

    Is uber shader with if statements still bad practice?

    Back in the day, if statements for expensive routines or texture lookups were considered bad practice because some GPUs would execute both code paths. I've switched over to clustered forward rendering, which uses a ton of conditional statements and variable-length for loops, so I was wondering if this is still the case.

    Right now I have a sort of uber shader using macros like this:
    Code :
    #ifdef TEXTURE_DIFFUSE
        outcolor *= texture(texture0, texcoords0);
    #endif
    With all the variations of what textures and settings may be present, that gives me about 64 possible ways a shader can be loaded. This gets ugly when I try to support user-made custom shaders and shader reloading while the game is running.

    Am I just making things needlessly complicated? Is this okay to do nowadays?:
    Code :
    if (texturePresent[0] > 0) outcolor *= texture(texture0, texcoords0);

  2. #2
    Senior Member OpenGL Guru
    Join Date
    Jun 2013
    Posts
    2,975
    Modern hardware uses actual branches for conditions which are dynamically uniform, i.e. where the result is the same for all shader invocations which are executed in parallel.

    On hardware lacking branch instructions, the driver would typically convert uniform if/else conditions to #if/#else, compiling separate variants of the shader for each combination and selecting the appropriate variant for each draw call. So it shouldn't be necessary to manually create and select variants, although collating draw calls which use the same variant may be advantageous.

    Non-uniform control flow (i.e. where the condition can vary between shader invocations executed in parallel) still requires executing both branches on all hardware.

  3. #3
    Senior Member OpenGL Lord
    Join Date
    May 2009
    Posts
    6,055
    Quote Originally Posted by GClements View Post
    Non-uniform control flow (i.e. where the condition can vary between shader invocations executed in parallel) still requires executing both branches on all hardware.
    That's not quite correct for modern hardware. If the condition is the same for all invocations in a particular wavefront (even if it could be different, the condition doesn't have to be different all the time), then the hardware can execute a single branch just fine. And if it isn't the same, then whether both branches are executed will depend on the compiler. If the two branches are long, it may be cheaper to break up the wavefront dynamically than to execute both.

    But overall, either way there will be pain.

  4. #4
    Junior Member Newbie glnoob's Avatar
    Join Date
    Sep 2010
    Posts
    19
    The condition is a boolean uniform that is set once before all objects using this material are drawn.

    Minimum hardware support is OpenGL 4.0.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •