Fast approximation to acos?

Anyone have any fast approximations to acos()?

Fast as in faster than doing a 1D texture lookup.

You could always use a partially expanded infinite series, but then again the built-in function may be doing just that.

http://functions.wolfram.com/ElementaryFunctions/ArcCos/06/01/01/0001/MainEq1.gif

Several Pade approximations are given to arcsin if you follow the link below. You could use one of those with arccos = pi/2 - arcsin.

http://math.fullerton.edu/mathews/n2003/PadeApproximationMod.html

I really doubt it will be faster then texture lookup…

The simplest way to find a fast approximation is to compile that shader with cgc:


varying float x;
void main (void){
        gl_FragColor = acos(x);
        }


cgc acos.frag -oglsl -profile glslf
(or use a profile like fp30 that is better readable) The algoritn requires round about 11 instructions and it looks like a polynom is used for the approximation.

Thanks for the links everyone.

I’m going to have to profile this to find out for sure, but I suspect you might be right on that…

Another option would be to store the coeffecients of 4 cubics in a 4x4 matrix. The cubics could be fit to acos on intervals spanning [0,1], and you could use acos(-x) = -acos(x)+pi for [-1,0]. You could also have the knots of the polynomials distributed cubically so the higher curvature near 1 would be fit to a polynomial with a smaller interval. The function that converts a point in the domain to an index could reuse the evaluation of xxx for the polynomial. Something like this where mat contains the polynomial coeffecients:

sgn = sign(x);
x = abs(x);
x2 = xx;
x3 = x
x2;
t = {1, x, x2, x3};
i = floor(4*x3);
arccos = dot(mat(i), t);
return sgn * arccos - min(0, sgn * PI);

I don’t know how it would compare to texture lookup, but at least no division is required as in the Pade approximation.

This topic was automatically closed 183 days after the last reply. New replies are no longer allowed.