Live demo (see requirements below)

Simple,
real-time 3D graphics applications typically use a lighting model like
the default one provided by OpenGL, which includes only local
illumination effects. (The Phong lighting equation is one such model.)
This fails to account for many important lighting effects, such as
shadows, ambient illumination, and color bleeding. My project is an
implementation of the radiosity method, which precomputes global
illumination for a static scene, allowing it to be rendered at
interactive frame rates inside a WebGL-compliant web browser.

This
project is broken into three components. The first is a straightforward
plugin for Blender, a popular open source 3D modeling application,
which exports a polygonal scene to a simple plain text format. The
second component is a standalone C++ program which reads this scene
file, performs the radiosity computations, and generates as output a
version of the scene with colors at each vertex containing the global
illumination values. The final piece of the project is a simple
JavaScript application that loads this model and displays it from a
moving viewpoint.

The radiosity
algorithm is well-known in the graphics community: it was originally
developed in the 1950s for simulating radiative heat transfer in space
probes (Sillion) and subsequently applied to global illumination in the
1980s. (Goral) It involves dividing the scene up into discrete patches
and computing the illumination by solving a system of linear equations.
In my implementation, each triangle in the scene is one patch.

Explicitly
creating this system of equations requires computing a form factor for
each pair of patches. Not only is this prohibitive for large scenes, but
numerically computing the form factor even for a single pair of
polygons is non-trivial. (Closed form solutions exist for certain
special cases, e.g. in the absence of occlusion. (Schroder))

For
my implementation, I used the "stochastic relaxation radiosity" method
of (Dutre), described in section . Instead of explicitly computing form
factors, this algorithm finds an approximate solution to the system of
equations by shooting rays through the scene. Since the probability of a
randomly-emitted ray from one patch hitting another patch is equal to
the form factor between the two patches, this provides an unbiased
estimate of the true solution, with progressively decreasing noise as
more iterations are computed.

The solver first performs a
fast initial approximation using the "incremental power shooting"
variant of the algorithm. It then performs repeated iterations of the
"regular power shooting" algorithm and averages them together. Because
this second phase is incremental, the program can run indefinitely,
producing more and more accurate approximations. To accelerate the
ray-triangle intersection calculations, polygons are stored in a BSP
tree.

The scene viewer component of this
project is a simple JavaScript application that uses the HTML5 canvas
element and its associated WebGL API to render the illuminated scene
from a moving viewpoint. The model's data is loaded into a series of
buffer objects on the GPU, and a single API call renders the entire
model.

The WebGL specification is, at the time of writing,
only a draft standard. Recent developer preview versions of Google
Chrome and Mozilla Firefox implement the current version of the spec,
but since it is still experimental it needs to be manually enabled:

- For
Google Chrome "dev channel" builds (version 5.0.366 and up) and
corresponding versions of the Chromium open source browser, start the
browser with the "
**--enable-webgl**" command line option. - For
Mozilla Firefox (version 3.7 alpha 2 and up), type "about:config" into
the address bar and set the "webgl.enabled_for_all_sites" preference to
**true**.

Note
that the WebGL specification is defined as a wrapper around OpenGL ES
2.0, which is a subset of the full OpenGL 2.0 API. In particular, it is
not supported by certain low-end integrated graphics chips, which
typically only support OpenGL 1.3. Although the functionality required
for this demo is very simple and could easily be designed to run on
older graphics chips, OpenGL ES provides no mechanism for accessing the
deprecated fixed-function pipeline.

- It only applies to static scenes in which all surfaces are have a diffuse Lambertian BRDF. In other words, view-dependent effects such as specular reflection are not supported. These effects could be added using other techniques such as photon mapping, at the cost of additional computation and complexity.
- High-frequency effects are limited by the size of the patches. Effects like sharp shadows from point lights are hard to represent without an excessively fine-grained model. For simplicity, I did not attempt any kind of automatic subdivision; I rely on the modeler to set the polygon size appropriately.

My
implementation has the following additional limitations:

- All lights are polygonal area lights. (In fact, lights are just polygons with a non-zero emissivity coefficient.)
- Objects are limited to polygonal models with a solid color for each face.
- One problem with the "shooting" radiosity method is that smaller patches will be hit less frequently by rays, and therefore will have more noise than large patches. This can be alleviated by simply running the algorithm for more iterations.
- Only one CPU core is used. Parallelizing the algorithm would probably yield large performance improvements on multicore systems.

[1] Dutré, P., K. Bala, and P.
Bekaert (2006). *Advanced Global Illumination, 2nd edition*.
Wellesley, MA, USA: A K Peters Ltd.

[2] Goral, C. M., K. E. Torrance, D. P. Greenberg, and B. Battaile (1984, July). Modeling the interaction of light between diffuse surfaces. In

[3] Schroder, P. and P. Hanrahan (1993). On the form factor between two polygons. In

[4] Sillion, F. X. and C. Puech (1994).