glslshader

How to wrap a value between boundaries?


How can I wrap a value around arbitrary boundaries? I want to avoid if checks, so I have come up with this that works for a low boundary using step:

float check = step(-1, val)*2.0-1.0;
val *= check;

This will output whatever value the vector val has when it is greater than -1, and wrap around, and jump to 1 when it exceeds it.

My goal is that when a value exceeds a certain threshold, it "wraps" up and starts back from the opposite side of the screen. So, if a moving dot for example exceeds 1, then it will re-appear in the screen in the -1 position, and keep on moving from there on.

On the other hand if is below -1, it will appear in position 1 and keep moving from there.


Solution

  • float check = step(-1, val)*2.0-1.0;
    

    This will effectively output whatever value the vector val has in its components whenever that value is greater than -1, and wrap around and jump to 1 when it exceeds it.

    No. The result of the function step() is either 0.0 or 1.0, in any case. So the result of step(-1, val)*2.0-1.0 is either -1.0 or 1.0.


    My goal is that when a value exceeds a certain threshold, it "wraps" up and starts back from the opposite side of the screen. So, if a moving dot for example exceeds 1, then it will re-appear in the screen in the -1 position,

    What you want to do can be achieved by the function mod(x, y), which returns the rest of the division of x by y:

    y = mod(x - min, max - min) + min
    

    For an ascent from -1 to +1 this results in

    y = mod(x + 1.0, 2.0) - 1.0 
    

    Independent on the value of x has, the result of the function is always in the range [-1, 1]. If the upper limit 1 is reached the immediately following result is -1:

    Note, the function uses mod() support genType. This means x and y can even be of type vec2, vec3 or vec4. Of course x and y have to be of the same type.