Spherical Harmonic Lighting using OpenGL




Spherical Harmonics Lighting techniques and the code of this program are fully explained in this Game Institute course

Spherical Harmonics Lighting techniques are fully explained in my first book!!!


What is it?

Spherical Harmonic lighting is a real-time rendering technique that uses a pre-process step - the projection of the lights, of the model and of the transfer function onto the spherical harmonic basis - to render realistically scenes using any type of light source. It is primarily used to reproduce diffuse lighting. The basic idea is to try to evaluate an approximation of the rendering equation at each vertex of the geometry of the scene by projecting its different components onto the spherical harmonic basis during a pre-process step. The geometric term and the visibility function in the rendering equation can be simplified or approximated in three different ways.

It the first approximation, the geometric term is reduced to its simplest form: the cosine term or dot product between the surface's normal at the given vertex and the light's direction. This is exactly the same as standard diffuse lighting using Lambert's law. Only in this case, there is no need to manipulate the surface's normal as it is encoded in the spherical harmonic coefficients. This first technique is often referred to as SH Diffuse unshadowed lighting and can generate images such as this one.

In the second form, the visibility term is added to determine shadowing at a given vertex. This can be easily achieved by using a raytracer. This allows to easily generate realistic shadows for the same scene, at the cost of extra calculation time. This second technique is often referred to as SH Diffuse shadowed lighting and can generate images such as this one.

In the last approximation, lighting coming indirectly from the other objects in the scene is taken into account. The pre-process step in this case take into account direct and indirect lighting, thus providing a way of calculating the global illumination of the scene. This third technique is often referred to as SH Diffuse inter-reflected lighting.

Once all SH coefficients have been generated for the three modes, at runtime, the rendering equation can be reconstructed from these different SH coefficients by simply adding and multiplying them together. The outgoing radiance at each vertex can then be calculated. Using Gouraud shading (i.e.: interpolation of the color of a triangle based on the colors at each of it vertex), it is then easy and fast to render the full scene in real-time. The following image is a comparison between different lighting models applied to the same scene: standard OpenGL lighting (Phong shading), 3DS Max scanline rendering, SH diffuse unshadowed mode using an HDRI light probe from here, and SH diffuse shadowed mode using the same HDRI light probe:

By using the different HDRI light probe images from Paul Debevec's site, you can obtain interesting results such as the following ones:

Remember, all of this is rendered in real-time!!

You can download videos of the program running with differents scenes and light probes from here, here, here and here (XVID Codecs required).

Where is it?

HDRSHLighting for Windows (32-bit platform) is available here, and the Linux version (Intel) is available here. You will need to download HDRI light probe images from Paul Debevec's site (download the probes in spherical format, not in the Vertical Cross Cube Format). Also make sure to download the HDR light probes in .hdr format. I have put the GLUT DLL in the Windows version, but Linux users will need to install it on their own (RPMFind is a good place to look for it).

Also note that there seems to be a slight bug (a feature, rather!): the lighting seems to be coming from the side whereas it should be coming from above. I will investigate this soon.

What can I do with it?

The program takes a 3DS scene as an input as well as an HDRI light probe, it then calculates the SH coefficients, cache them to files and render the scene using OpenGL and SH Lighting (shadowed and unshadowed modes only). If you interrupt an SH calculation, delete the corresponding cache file for the current scene (.dsshc and .dushc files) otherwise the next time your run the program, it will try to read the cache file. Alternatively, use the appropriate command-line switch to force the program to re-calculate the SH coefficients (see below for more details). Note that the 3ds scene must have at least one camera. There are no restrictions concerning the lights, as they are not taken into account for rendering. Also note that the program hasn't been fully optimized yet. It uses a BHV (Bounding Hierarchy Volume) technique for the raytracing part, but it is still a slow technique.

The keyboard mapping and mouse usage of this program are summarized in the following tables:

Key

Description

f

Switch to full screen display

F

Switch to full screen display

n

Switch to windowed display

N

Switch to windowed display

D

Switch to the next rendering mode (order: GL, SH un-shadowed, SH shadowed)

d

Switch to the previous rendering mode (order: GL, SH shadowed , SH un-shadowed)

S

Scale up the lighting intensity

s

Scale down the lighting intensity

>

Toggle between the different cameras (forward)

<

Toggle between the different cameras (backward)

b/B

Capture the content of the window to a BMP file named HDRISHLightingXXXX.bmp

a/A

Toggle animation on/off

y/Y

Switch between the different display modes: point, triangle and fill

q/Q

Exit the program

Mouse Action

Description

Left click and Drag

Rotates the camera around the function, thus giving the impression of rotating the function

Right click

Toggles animation on/off

The program accepts different command-line parameters, all summarized in the following table:

Switch

Parameter(s)

Description

-s

integer

The size of the grid of stratified samples

--samples

integer

The size of the grid of stratified samples

-b

integer

The number of bands used to approximate the spherical function

--bands

integer

The number of bands used to approximate the spherical function

-h

integer

Height of the display window

--height

integer

Height of the display window

-w

integer

Width of the display window

--width

integer

Width of the display window

-hdr

filename

Name of the HDR light probe to load

--hdr

filename

Name of the HDR light probe to load

-3ds

filename

Name of the 3ds scene to load

--3ds

filename

Name of the 3ds scene probe to load

-hs

float

Scale the intensity of the input HDR image

--hdrscale

float

Scale the intensity of the input HDR image

-dm

none

Force direct mode rendering to allow contrast adjustment of the lighting intensity

--directmode

none

Force direct mode rendering to allow contrast adjustment of the lighting intensity

-nd

none

Only calculate SH coefficients (no display) and exit

--nodisplay

none

Only calculate SH coefficients (no display) and exit

-nc

none

Do not try to read cached SH coefficients from file, and force SH coefficients calculation

--nocache

none

Do not try to read cached SH coefficients from file, and force SH coefficients calculation

-v

none

Verbose mode

--verbose

none

Verbose mode

-?

None

Display a help message

--help

none

Display a help message

For example, to calculate the SH coefficients of a scene, cache them (i.e.: the next time you run the program, it will read the SH coefficients from a file, instead of re-calculating them) and render the scene, open a command-prompt (Windows) or a shell (Linux), and type the following (from the directory where you installed the program):

HDRISHLightingBSP -3ds plane.3ds -hdr grace_probe.hdr

To be able to adjust the light intensity while rendering the scene, type the following:

HDRISHLightingBSP -3ds test7.3ds -hdr rnl_probe.hdr -dm

To calculate the SH coefficients and cache them, without rendering the scene, type the following:

HDRISHLightingBSP -3ds bague.3ds -hdr rnl_probe.hdr -nd

To set the light scaling factor (for instance, to have a brighter or darker rendering of the scene) to a default value, type the following:

HDRISHLightingBSP -3ds plane.3ds -hdr rnl_probe.hdr -hs 1.6

Note that it is possible to mix the different command-line switches (for instance: -dm and -hs). Finally, under Windows, let's say you have a bunch of 3ds files in your current directory, you can calculate the SH coefficients for all of them using the following batch command (very usefull when going on a weekend and if your machine is not used!):

for %i in (*.3ds) do HDRISHLightingBSP -3ds %i -hdr rnl_probe.hdr -nd

Why did you do it?

This program is part of many other programs that I have written for the book called: Advanced Lighting and Materials with Shaders. I wrote this book with Kelly Dempski, the man behind this book and this book.

 

2000/2005 Emmanuel Viale