Posted 14 January 2013 - 03:37 PM
I'm wondering about the 4 * dot(n,l) * (n, v). It can become 0. Are you applieing some max(x, epsilon) on the individual dot products or on the whole term or something different?
It only becomes zero at a very grazing angle between the view vector (or light vector) and the surface, but in practice you'll probably want a few epsilons there just to guard against division by zero, since it'll mess up your entire pipeline if you end up with pixels with infinite brightness. I've seen a good shader implementation of Cook-Torrance someone on the internet which shows how to do those checks correctly and efficiently, though I can't find it right now.
Of course if you can cancel things out, make sure you do, as the safest and fastest operation is the one you never compute. You'll notice the dot(N, L) one is automatically cancelled out by the Lambertian cosine term, for instance.
The slowsort algorithm is a perfect illustration of the multiply and surrender paradigm, which is perhaps the single most important paradigm in the development of reluctant algorithms. The basic multiply and surrender strategy consists in replacing the problem at hand by two or more subproblems, each slightly simpler than the original, and continue multiplying subproblems and subsubproblems recursively in this fashion as long as possible. At some point the subproblems will all become so simple that their solution can no longer be postponed, and we will have to surrender. Experience shows that, in most cases, by the time this point is reached the total work will be substantially higher than what could have been wasted by a more direct approach.
- Pessimal Algorithms and Simplexity Analysis