Once we have a point in space mapped to a pixel, one of the most common tasks is to approximate the color and lighting at that point. These include BRDFs for when light doesn’t move inside the object and BSDFs when it does. There are many such models known; here we describe only some of the best known named approximations of BRDFs.
Easily-computed BRDFs generally break light into three parts: ambient, diffuse, and specular.
For each part, the object’s material may have a color 1\vec m_a, \vec m_d, and \vec m_s, and those could differ: for example, a white shine spot on a red apple suggest \vec m_d is red but \vec m_s is white. In addition, there are various models for deciding how intense the illumination from a given type of light is, the scalars l_a, l_d, and l_s, with various formulae for computing each given in the sections below. And each light in the set of all lights L has a color \vec l_c which also contributes to the overall color of the object.
Each of these will generate a color vector for each light source; these color vectors are then multiplied element-wise2 by the color of the object. which may be different for each type of light: \left(\vec m_a \otimes \sum_{l \in L} l_a \vec l_c\right) + \left(\vec m_d \otimes \sum_{l \in L} l_d \vec l_c\right) + \left(\vec m_s \otimes \sum_{l \in L} l_s \vec l_c\right)
The remainder of this page defines various forumalae for the l_a, l_d, and l_s terms above. It uses the following notation:
In all cases the discussion below assumes no attenuation of light with distance or angle; to add attenuation, simply multiply the results below by an attenuation factor (ex: since point light falls with the square of the distance, we would simply multiply all the results below by \frac{1}{d^2} to model its attenuation).
It is important that lighting all happen in one coordinate space. The most common graphics pipline uses five coordiante spaces, of which two are suitable for lighting:
You can light in world coordinates or in view coordiantes, but cannot mix and match the two.
In world coordiantes, the surface normal is the value found in the attribute buffer times a model matrix (M \vec n), interpolated to each fragment and normalized.
In view coordinates, the surface normal is the value found in the attribute buffer times a modelview matrix (V M \vec n), interpolated to each fragment and normalized.
In world coordinates, the Blinn approximation of the direction to the eye is (center − eye) from the view matrix creation function, or equivalently the third row of the view matrix.
In view coordinates, the Blinn approximation of the direction to the eye is the vecor (0,0,\pm 1) – whether + or − depends on how you made the projection matrix.
In world coordiantes, the Phong approximation of the direction to the eye is (interpolated world-space position of vertices − eye location).
In view coordiantes, the Phong approximation of the direction to the eye is (− interpolated view-space position of vertices).
In world coordiantes, the direction to a sun-like light is a constant vector.
In view coordiantes, the direction to a sun-like light is the view matrix times a constant vector.
In world coordiantes, the direction to a point light is (light position − interplated world-space vertex position).
In view coordiantes, the direction to a point light is ((view matrix times light position) − interplated view-space vertex position).
Ambient light is assumed to come from everywhere and reach everywhere equally. Thus, the ambient light color is independent of the object; l_a is simply a constant. There is no ambient light in the real world; instead, it is a substitute for tracing light that reaches an object by first bouncing off other objects. In general, keep the ambient light small, no more than 20% of the total light possible.
Diffuse light is the main component we think of when considering a matte object. There are several different models for generating it.
In the Lambert model, \gdef\ffloor#1{\left[\!\left[#1\right]\!\right]}l_d = \ffloor{\vec n \cdot \vec \ell}. This is what would happen if every photon bounced in a completely random direction on a smooth surface.
The Minnaert model extends the Lambert model by biasing the light to bounce away from the surface; the bias is given by a constant k \in [0,1], and the formula is \gdef\ffloor#1{\left[\!\left[#1\right]\!\right]}l_d = \ffloor{\vec n \cdot \vec l}^k \ffloor{\vec n \cdot \vec e}^{1-k}. This was created to model the appearance of the moon; the lower k the brighter the edges of an object will appear.
The Oren-Nayer models assumes an object is made out of a sub-pixel-resolution bumps and crevices. It is quite complicated, but very close to what real-world objects look like. Let \sigma \in [0,1] be the roughness of the surface. Then the Oren-Nayer model is
\gdef\ffloor#1{\left[\!\left[#1\right]\!\right]}\begin{split} \vec f_e &= \frac{\vec e - (\vec e \cdot \vec n) \vec n}{\left\|\vec e - (\vec e \cdot \vec n) \vec n\right\|}\qquad \vec f_\ell= \frac{\vec \ell - (\vec \ell \cdot \vec n) \vec n}{\left\|\vec \ell - (\vec \ell \cdot \vec n) \vec n\right\|}\\ \theta_e &= \cos^{-1}(\vec e \cdot \vec n)\qquad\quad\, \theta_\ell = \cos^{-1}(\vec \ell \cdot \vec n)\\ \alpha &= 0.45\frac{\sigma^2}{\sigma^2+0.09}\sin(\max(\theta_\ell,\theta_e))\tan(\min(\theta_\ell,\theta_e))\\ l_d &= \ffloor{\vec n \cdot \vec \ell} \left(1 - 0.5\frac{\sigma^2}{\sigma^2+0.33} + \alpha\ffloor{\vec f_e \cdot \vec f_l} \right) \end{split}
Any of these can be turned into a toon shader by simply picking a cutoff value of l_d and clamping numbers above it to 1, numbers below it to 0.
The specular highlight of an object (shiny spot) has even more versions than does diffuse lighting. Most of versions rely on a hardness number n \ge 1 which makes the shine spot small, on the reflection of the light off the surface \vec r = 2(\vec n \cdot \vec \ell)\vec n - \vec \ell, and/or on the vector halfway between the light and the eye \vec h = \frac{\vec \ell + \vec e}{\left\|\vec \ell + \vec e\right\|}.
The Phong model is \gdef\ffloor#1{\left[\!\left[#1\right]\!\right]}l_s
= \ffloor{\vec r \cdot \vec e}^n and the Blinn-Phong is \gdef\ffloor#1{\left[\!\left[#1\right]\!\right]}l_s
= \ffloor{\vec h \cdot \vec n}^n.
They are similar in look and are easy to compute; generally Blinn-Phong
is used in conjunction with a single approximate \vec e and \vec
\ell while Phong is used if \vec
\ell and/or \vec e vary across
the scene.
The Gaussian model is more accurate, but likewise more expensive to compute: \gdef\ffloor#1{\left[\!\left[#1\right]\!\right]}l_s = e^{-m\cos^{-2}\ffloor{\vec n \cdot \vec h}} (note e is Euler’s number, \vec e is the vector to the eye). Better and more expensive is the Beckmann distribution \gdef\ffloor#1{\left[\!\left[#1\right]\!\right]}l_s = \frac{m}{\ffloor{\vec n \cdot \vec h}^4}e^{-m\tan^2(\cos^{-1}\ffloor{\vec n \cdot \vec h})}.
Fresnel’s law specifies how much light penetrates a transparent object; this can be combined with the Beckmann distribution to get the Cook-Torrance model. Let \lambda be the Fresnel factor and \beta the computed Beckmann distribution; then Cook-Torrance gives \gdef\ffloor#1{\left[\!\left[#1\right]\!\right]}l_s = \beta \frac{(1+\ffloor{\vec e \cdot \vec n})^\lambda}{\ffloor{\vec e \cdot \vec n}} \min\left(1, \frac{2\left(\vec h \cdot \vec n\right)2\left(\vec e \cdot \vec n\right)}{\vec e \cdot \vec h}, \frac{2\left(\vec h \cdot \vec n\right)2\left(\vec \ell \cdot \vec n\right)}{\vec e \cdot \vec h}\right).
GGX lighting is an alternative to Beckman that is empirically closer to how specular highlighting looks than Beckman, and can be combined with the Fresnel effect directly. Let \sigma \in [0,1] be the roughness of the surface and f be the F0 value representing how much light is refelected at a 0° incidence angle; then GGX is expressed as \gdef\ffloor#1{\left[\!\left[#1\right]\!\right]} \frac{ \ffloor{\vec n \cdot \vec \ell} \sigma^2 \left(f + (1-f)\left(1-\ffloor{\vec \ell \cdot \vec h}\right)^5\right) }{ \pi \left(\ffloor{\vec n \cdot \vec h}^2 (\sigma^2-1) + 1\right)^2 \left( \ffloor{\vec \ell \cdot \vec h}^2 (1-0.25\sigma^4) + (0.5 \sigma^2) \right) }
There are also a variety of anisotropic models (notably Heidrich-Seidel and Ward) which depend additionally upon the principle tangent vector of the surface and can give the appearance of brushed metal, hair, and the like, but which are beyond the scope of this document.