# (R.V)^n in The Phong Lighting Model

by Fons Kuijk (fons@cwi.nl)
comp.graphics.research, 19 Sep 91
razdan@phx.mcd.mot.com (anshuman razdan) writes:
I am doing a class project that involves as a possible area of work - Phong Lighting Model. Since the legth and breadth of the project is not defined, i.e. supposed to experiment, I have decided to tinker with the specular part of the Phong model.

Now calculating reflection_vector.view_vector is one thing, calculating the power of it is another matter. Now, some work has been done to expand this as a taylor series. I intend to restrict value of n to a max of 5 and as we all know the value of R.V would vary between 0 and 1 (cos of an angle). So it is approximation of a 0<number<1 raised to power n where 2<=n<=5. So I think it becomes a kind of a special case and there might be a better way of approximating this value. I have a few ideas about interpolation, actually thought of fitting a cubic b spline surface. It is a good idea but computationally much more expensive than just finding power of a number (you know how theoretical discussion go).

We do it even less expensive. If alpha is the angle between the two vectors, the specular intensity is cos(alpha)^n. For this function I once found a most satisfying function of three quadratic sections. It is described in

"Faster Phong Shading via Angular Interpolation" Kuijk A.A.M. & Blake E.H. (1989) Computer Graphics Forum, Vol 8, No 4. pp. 315-324

The approximation of cos(alpha)^n is :

```f(alpha) = 0                              if alpha <= -b or b <= alpha
(alpha + b)^2 / (b * (b-a))    if -b < alpha < -a
1 - alpha^2 / (a * b)          if -a < alpha < a
(alpha - b)^2 / (b * (b-a))    if  a < alpha < b
```

This function is continuous, as well as its derivative. The two constants a and b are related to n in the following way:

```    a = (n + 5.6) / (n * (0.09 * n + 5.2))
b = (n + 65.0) / (5.0 * n + 31.7)
```

In the article mentioned above these two got mixed up unfortunately. Since they are constant, the function above can be rewritten in the form

```    r * alpha^2 + s * alpha + t
```
for all three sections, so there are no divisions involved.

We use this function, because we know how to relate the step per pixel to an increment in alpha. In that case forward differencing can be used and the cost per pixel is merely two additions!

As you can see, there is not limit on the value of n, in fact it does not have to be an integer! What you proposed, limiting n to 5 would result in rather dull looking surfaces. It begins to be interesting for values > 50. In fact we also use this function to calculate the diffuse term (n = 1). The advantage of doing this is that it avoids Mach bands at the point where the light vector and the surface normal are perpendicular.