Nested if statements in shaders?

laserpilot's icon

I am trying to modify a shader in the shaders ahoy package that does a half mirror effect (similar to the stock mirror shader). I have figured out all of the states I'm trying to use, but I'm not sure how to switch between them besides using a nested if statement and a 'mode' variable

Here is the chunk of the fragment shader that does the mirroring:

uniform sampler2DRect tex0;
uniform float mode;

varying vec2 texcoord0;
varying vec2 texdim0;

void main(void)
{
    vec4 input0 = texture2DRect(tex0, texcoord0);
    vec2 translate0 = texcoord0;
    if (translate0.y < texdim0.y/2.0) translate0.y = texdim0.y - translate0.y;
    gl_FragColor = texture2DRect(tex0, translate0);
}

I need to change the line:

if (translate0.y < texdim0.y/2.0) translate0.y = texdim0.y - translate0.y;

to be x values in one mode, and then change that less than to greater than for both x and y cases to get all 4 possible positions.

So my final idea of how it would look would be something like:

if (mode = 0) {
      if (translate0.y < texdim0.y/2.0) etc...
      }
else if (mode = 1) {
      if (translate0.y > texdim0.y/2.0) etc...
      }
else if (mode = 2) {
      if (translate0.x < texdim0.x/2.0) etc...
      }
else if (mode = 3) {
      if (translate0.x > texdim0.x/2.0) etc...
      }

Of course the problem is the syntax is different in glsl for if statements than what I'm used to. Is there a way to switch between these different methods easily, or should I just make 4 different shaders and do my switching in max?

Rob Ramirez's icon

the general rule is to avoid if blocks in shaders if at all possible.
so perhaps creating 4 separate shaders will be more efficient.
no way to know without testing.

Andrew Benson's icon

The thing about if statements in shaders is that there is no actual branching in the code execution. The GPU will always execute all the options regardless of the one that will be used. Using mix() statements is how I typically do if-like behavior in a shader. In this case, splitting off your code into different shaders makes sense.

laserpilot's icon

Thanks guys, that makes sense...I went the 4 shader route and it's fine. The mix route sounds like a good option too..but maybe once I get more advanced with these