The main issue is that
(ONE3-b)/a may cause a division by zero. This causes the result to be NaN (Not A Number). In that case mix will also return NaN because pretty much anything done to a NaN gives back an NaN and
mix(a, b, i) internally does
a*(1-i) + b*i or
a + (b-a)*i.
mix( ONE3 - ((ONE3-b)/max(a, vec3(0.001, 0.001, 0.001))), ZERO3, step(a, ONE3-b) );
max(a, tiny_value ) prevents a division by zero.
?: avoids the NaN case completely.
And instead of
greaterThanEqual and a cast back to
vec3 you can use
step(edge, x) which returns 0 if x < edge and 1 otherwise without branching.
You should really profile your shaders on the target platform. Depending on the GPU and the operands used sometimes
?: will be faster.
Some GPUs (especially mobile GPUs) don't mind branches too much and may benefit from them if the calculation skipped is quite long.