In  Walter, et. al. describe a method for rendering global illumination solutions which contain view-independent directionally variant lighting effects using the specular term in the OpenGL lighting model to approximate the directionally varying lighting information and the emissive term to approximate the directionally invariant illumination (i.e., diffuse illumination). In this method, a set of OpenGL lights are treated as a set of basis functions which are summed together while the object is rendered to yield a more general directional distribution. The OpenGL light parameters such as position or intensity coefficients have no relationship to the light sources in the original model, but instead serve as a compact representation for the directional illumination of an object. Each rendered object has its own set of lights which are called virtual lights.
The method works on a global illumination solution which stores a number of samples of the directionally varying illumination at each object vertex. The parameters for the virtual lights of a particular object are determined using a fitting procedure consisting of a number of heuristics. The main idea is to produce a set of solutions for a number of specular exponent values and then choose the exponent value which minimizes the mean-squared error using a least squares method. A solution at a given exponent value is determined as follows:
Once the lighting parameters have been determined the model is rendered using the glLight() and glMaterial() commands to set the directional light parameters and specular exponent for each object and the glMaterial() command to set the specular reflectance and and emitted intensity at each vertex. The rendering speed for the model is limited by the geometric complexity of the model and the ability of the OpenGL implementation to deal with multiple light sources and material changes at each vertex. Rendering performance may be improved by rendering in multiple passes to limit the number of active lights or the number of material parameter changes in each pass. For example, using glColorMaterial() and glColor() to change only the emitted intensity or specular reflectance in each pass and framebuffer blending to sum the results together.