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.

```(define (pass-checks? freq s t)
(odd? (xor (mod (* s freq) 1))
(mod (* t freq) 1)))

(define (shade eye lights surface s t normal)
(let ((k (dot-product eye (reflect (direction light) normal)))
(exp (roughness->exponent (roughness surface)))
(diffuse-color
(cond ((texture? surface) ...)
((and (checked? surface)
(pass-checks? (check-frequency surface)
s t))
(check-color surface))
(else (diffuse-color surface)))))
(gen-* (color light)
(gen-+ (gen-* (power exp k)
(specular-color surface))
(gen-* k diffuse-color)))))
(gen-+ (ambient surface) ; maybe inside lights?
```

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:

```(define (shade-specialized s t normal)
(let* ((t0 (reflect constant-direction0 normal))
(t1 (reflect constant-direction1 normal))
(k (+ (* eye_0 t0_0) (* eye_1 t0_1) (* eye_2 t0_2)))
(k2 (* k k)) (k4 (* k2 k2))
(k8 (* k4 k4)) (k16 (* k8 k8))
(k20 (* k16 k4))
(m (+ (* eye_0 t1_0) (* eye_1 t1_1) (* eye_2 t1_2)))
(m2 (* m m)) (m4 (* m2 m2))
(m8 (* m4 m4)) (m16 (* m8 m8))
(m20 (* m16 m4)))

(color (+ a_0
(* Cl0_0 (+ (* k20 Cs_0) (* k d_0)))
(* Cl1_0 (+ (* m20 Cs_0) (* m d_0))))
(+ a_1
(* Cl0_1 (+ (* k20 Cs_1) (* k d_1)))
(* Cl1_1 (+ (* m20 Cs_1) (* m d_1))))
(+ a_2
(* Cl0_2 (+ (* k20 Cs_2) (* k d_2)))
(* Cl1_2 (+ (* m20 Cs_2) (* m d_2)))))))
```

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.