# GLSL get min/max index of vec3

I have written a function in GLSL that returns the min index (index 0 is the x component, 1 is the y component, and 2 is the z component) of a vec3 variable.

uint getMinIndex(vec3 vector)
{
float minValue = min(min(vector.x, vector.y), vector.z);
if(vector.x == minValue)
return 0;
if(vector.y == minValue)
return 1;
return 2;
}


As you can see, this function causes branching and slows down the whole shader.... Is there already such a function in GLSL? Or is there a better way to do this without branching?

No, but the way this is written has a min of 3 branch's and max of 4. It would be better off with the plain old (x<y)&&(x<z) return 0, y<z return 1, return 2.

You could also do a pure logic op approach:

int mx = (y<z)&&(y<x);
int mz = (((z<y) && (z<x))*2;
return mx + mz; // both are false if x is min value and sum is zero


which would turn into this:

uint MinIndex( float x, float y, float z )
{
return ((y<z)&&(y<x)) + ((((z<y)&&(z<x))*2);
}


If y,z could be equal and less then x then an extra + ((y==z)&&(x<y)) would be needed which would return 1.

There may be some clever way to reduce this down to less operations but it's not popping into my head... at any rate logic operations are often fast but ugly to look at.

You might also try the mix function, something along the lines of...

uint MinIndex(float x, float y, float z)
{
float YltX = float(y < x);
float ZltX = float(z < x);

return uint(mix(YltX, 2.0 * ZltX, ZltX+float(y==z)));
}


I haven't checked this one for accuracy but using mix also tends to be rather speedy.

• Wow that's very creative =) Aug 26 at 18:44