Radiosity Engine

An experimental engine by Jawed Karim

The radiosity method is an object space algorithm, solving for the intensity at discrete points or surface patches within an environment and not for pixels in an image plane projection. The solution is thus independent of viewer position.
Radiosity is defined as the enery per unit area leaving a surface patch per unit time and is the sum of the emitted and the reflected energy.

Output produced by my radiosity engine for a simple scene containing 600 polygons.
The white patches are lightsources.

Form Factors

The first step towards the final solution is to determine the form factors for the scene, that is the geometric visibility relationship between all pairs of surfaces. The form factor F(i,j) is defined as the radiative energy leaving surface Ai that strikes Aj directly divided by the radiative energy leaving surface Ai in all directions in the hemispherical space surrounding Ai [2].

I am using a numerical method of evaluating form factors, called the hemicube method. A hemicube is used to approximate the hemisphere because flat projection planes are computationally less expensive. The hemicube is constructed around the center of each patch with the hemicube Z axis and the patch normal coincident. Every other patch in the environment is projected onto this hemicube. Each 'pixel' on the hemicube can then be considered as a small patch and a differential to finite area form factor, known as a delta form factor, defined for each pixel [2]. Since these delta form factors can be precomputed, a lookup table can be used in order to speed up the calculations. The sum of the delta form factors corresponding to each pixel on the hemicube then yields the final form factor:

where q is that set of pixels onto which a patch Aj projects.

The Radiosity Equation

Every surface in an environment is illuminated by a combination of direct light and reflected light. The direct light is light energy which comes directly from a light source or light sources, attenuated only by some participating media (smoke, fog, dust). The reflected light is light energy which, after being emitted from a light source or light sources, is reflected off of one or more surfaces of the environment. [L]
This relationship can be expressed in N simultaneous equations, where N is the number of patches within the scene:

The quantities E and R are already known for each patch. These respresent the reflectivity and light emission values for each patch. E is non-zero if the patch is a light source. The equations can be expressed in matrix-form and solved by an iterative method, until the solution converges.
After rearranging, it can be written as follows:

This format has two interesting properties: it is diagonally dominant and is therefore guaranteed to converge when using Gauss-Seidel iteration, and the upper right of the matrix is computable from the lower left. Note that the diagonal terms reduce to 1.0, because F(i,i)=0.0. A patch cannot see itsself. [L]

Implementation Specifics

My implementation is currently rather slow. Computing the form factors for the scene above took approximately three hours. Solving the system of equations afterwards was quick, and only took a few minutes. I'm currently using OpenGL to render the scene from each viewpoint of the hemicube and then subsequently count the number of visible pixels. A much better way to do this is of course is to assign a unique color to each patch, so that the color can be used as an index into the patch list. However, since my Voodoo3 doesn't actually render 32bit color, this doesn't work. Rendering with default settings dithers all of the colors, and when specifying GL_NO_DITHER it sure enough doesn't dither, but different colors show up up with the same exact RGB values.

Books used

Back to software page