Salier-Hellendag, Mar, Lee, Kurnia 2
We then proceeded to gut and rebuild the raytracer from Assignment 4 into a raytracer optimizedfor NPR rendering, throwing out the old code for calculating Phong shading, reflections, andshadows. There were three things that needed to be done: 1) the NPR shader to produce the"cartoonish" cel-shaded look, 2) post-process edge detection for the contour outlining, and 3) anew acceleration structure to cut down on render time.
The NPR Renderer
Commonly found in comic books and hand-drawn animations, cel-shading -- or "toon" shading -- is a form of shading intended to make objects look hand-drawn. As with our Phong shadedraytracer, we would calculate the following for each eye ray (in our case, 1280 x 720 = ~920,000 rays to produce an HD-valid resolution):
The closest possible polygon intersection, using hierarchical bounding boxes to acceleratetracing
The normalized direction vectors to light sources from that point (note: we opted to use asingle white point light source for our scene)
The diffuse RGB value (Kd) at the intersection point
The surface normal of the intersected polygonAs we would when calculating the diffuse component for Phong shading, we need the dotproduct of the light vector and the surface normal to obtain the cosine of the angle between thetwo, a value between 0 and 1. At this point, we depart from Phong shading.Instead of using the cosine value itself, we use an array of 16 grayscale values. In our case, weused values recommended by a cel-shading article on GameDev.net:Three grayscale values are used: 0.5, 0.75, 1.0. Our polygon's diffuse material value, Kd, will bemultiplied by one of these values. Determining which is simple:
int P_grayscale = int ((l * n) * 16)
Then the cel-shaded value is simply:
vec3 cel = Kd * grayscaleArray[P_grayscale]
Note that given the grayscale array described above, this means that any cosine value greaterthan 0.5 would result in the pixel being colored with cel-shading equal to Kd, since the grayscalevalue would be 1.0.