A Fast Power Function

When porting Angel to the Playstation 2, one of the big problems was that the Pow() function was taking up most of the CPU time. That's right - more time was being spend on the specular highlight calcultion than than all of the geometry and shading!

To speed up the calculation of specular hightlights I wrote a fast power function that could run on the PS2 Vector units. Unfortunatly the vector units lack most of the instructions which would be usefull in performing such an operation, so I had to get a bit creative.

Pow is basically implemented using log's: pow(a,b)=x(logx(a)*b). so we need a fast log and fast exponent - it doesnt' matter what x is so we use 2. The trick is that a floating point number is already in a log style format:
a=M*2E
Taking the log of both sides gives:
log2(a)=log2(M)+E
or more simply:
log2(a)~=E
In other words if we take the floating point representation of a number, and extract the Exponent we've got something that's a good starting point as its log. It turns out that when we do this by massaging the bit patterns, the Mantissa ends up giving a good approximation to the error, and it works pretty well.

This should be good enough for simple lighting calculations, but if you need something better, you can then extract the Mantissa, and use that to calculate aquadratic correction factor which is pretty accurate.

I wrote a Reference Implementation in C. I then ported it to PS2 VU Assembly Code. The PS2 Version includes both the full version with quadratic correction, and a super fast version which is less accurate. The code's also been ported to SSE.

The code is further described in Production Rendering.

Ian Stephenson.
DCT Systems
NCCA, Bournemouth University