Round with glsl

Hi,

I know there is no round in glsl with a given number and if statements are time intensive. So, here is my solution.

round up:


  number=sign(number)*ceil(abs(number));



round down:


  number=sign(number)*floor(abs(number));



round:


  signum=sign(number);//1
  number=abs(number);//2
  number2=fract(number);//3
  number=floor(number);//4
  number2=ceil((sign(number2-0.5)+1.0)*0.5);//5
  number=(number+number2)*signum;//6



signum, number and number2 can be float, vec2, vec3 or vec4.
Examples for round:
1. Example:

number=-3.1
=> signum=-1  //1
number=3.1  //2
number2=0.1;  //3
number=3;  //4
signum(0.1-0.5)=-1 //5
(-1+1)*0.5=0
=>number2=0
number=(3+0)*(-1)//6
=-3

2. Example
number=4.6
=>signum=1  //1
number=4.6  //2
number2=0.6  //3
number=4  //4
signum(0.6-0.5)=1 //5
(1+1)*0.5=1
=>number2=1
number=(4+1)*(1)//6
=5

3. Example

number=-5.5
=>signum=-1  //1
number=5.5  //2
number2=0.5  //3
number=5  //4
signum(0.5-0.5)=0 //5
(0+1)*0.5=0.5
ceil(0.5)=1
=>number2=1
number=(5+1)*(-1)//6
=-6

Best,
Andreas

No, you cann't cast like in Java. If you use

number=float(int(number+0.5))

, it's working like floor. So, if you want to round, you can write

number=sign(number)*float(int(abs(number)+0.5))

. But, that's more complicated. In GLSL, you only have 16 bits integers, but floats with a 23 bits mantissa. So, better use floats, only.



Best,

Andreas

round can be done like this too


  number=sign(number)*floor(abs(number)+0.5);

Yes, that's easier  :)!!! Thx.

shouldn't this work?


 number = (int)(number+0.5);

Ok, then you speak about I do realise that's how I have been doing all casts in the shaders. (like a = vec4(1.0))