Search code examples
glslshader

GLSL: How to do switch-like statement


I would like to dynamically invoke an easing based on the data passed into the shader. So in pseudocode:

var easing = easings[easingId]
var value = easing(point)

I'm wondering the best way to accomplish this in GLSL. I could use a switch statement in some way, or could perhaps put the easings into an array and use them like that. Or maybe there is a way to create a hashtable and use it like the above example.

easingsArray = [
  cubicIn,
  cubicOut,
  ...
]

uniform easingId

main() {
  easing = easingsArray[easingId]
  value = easing(point)
}

That would be the potential array approach. Another approach is the switch statement. Maybe there are others. Wondering what the recommended way is of doing this. Maybe I could use a struct somehow...


Solution

  • If you need conditional branching in GLSL (in your case for selecting an easing function based on a variable) you'll need to use if or switch statements.

    For example

    if (easingId == 0) {
        result = cubicIn();
    } else if (easingId == 1) {
        result = cubicOut();
    }
    

    or

    switch (easingId) {
    case 0:
        result = cubicIn();
        break;
    case 1:
        result = cubicOut();
        break;
    }
    

    GLSL has no support for function pointers, so the kind of dynamic dispatch solutions you are considering (tables of function pointers etc.) will unfortunately not be possible.

    Whilst your question was explicitly about data being passed into the shader, I would also like to point out that if the value controlling the branch is being passed into the shader as a uniform, then you could instead compile multiple variants of your shader, and then dynamically select the right one (i.e. the one using the right easing function) from the application itself. This would save the cost of branching in the shader.