A Shading Function

Shading is the computation used in 3D graphics to determine how a surface appears to one's eye, given surface properties and an incident lighting environment. Here is a sketch of a simple shader. It handles specular and diffuse shading, texture mapping, and a checker-board effect.

Shade computes how one point on a surface looks to an eye, given a lighting environment. Surface is a structure containing the surface properties, typically color, transparency, shininess, and a plastic/metal bit. S, t, and normal give the position and orientation of the surface point. Shade sums the contributions from each of the lights. Each light reflects proportionally to a power of the dot product of the eye and the reflected light.

Though this code is concise and very abstract, it is cluttered with vector arithmetic and structure references. The vector and color arithmetic is done with generic procedures gen-* and gen-+ that dynamically test the types of their arguments.

When rendering animation, eye, lights, and surface will be fixed for at least each complete frame. If we hold these arguments static and use RTCG, then a loop over the points on a surface can use this program instead:

All tests, loops, and indirect calls have been eliminated; the remaining code can be scheduled more easily and will run faster. Thus we can more than win back the time spent compiling it in a wide range of pixel resolutions, scene complexities, and numbers of frames.

But a lisp-generating extension for this shader would be much harder to write than the interpreter given above. If this were C/DCG instead of lisp, then the generating extension would be quite tricky for the programmer.