Homework Assignment 2: Precomputed Radiance Transfer

By Fu-Chung Huang


In this assignment, I implemented the PRT technique described in the paper “All-Frequency Shadows Using Non-Linear Wavelet Lighting Approximation.” In particular, I have the geometry relighting part for diffuse surface using rasterization as demo.

The input scene is a dancing figure with about 10K vertices, and ground plane with about 23K vertices. The ray traced cube map has resolution of 6x32x32.

Here is the result image and two accompany video, all using 200 wavelet coefficients


Video Link 1 (Environment Lighting)

Video Link 2 (3 Circle Area Lighting )


The program works as followed:

1.      Load the input transport data for vertices, and transform them into wavelet coefficients

2.      At runtime, project the environment map on a unit cube map around the center of the scene. HDR texture is supported with GL_RGB16F_ARB extension. The HDR texture is crucial to show the all-frequency effects; otherwise I get very diffuse result from 8bit texture.

3.      Transform the lighting unit cube map in wavelet representation. On the wavelet coefficients I performed the sorting with different configuration based on ‘un-weighted selection’, ‘transport weighted’, and ‘area-weighted’. After the sorting I preserve a pre-specified number of coefficients and stored them using sparse representation.

4.      At OpenGL drawing loops, I specified the colors of vertices by computing the dot product from two coefficient vector: vertex-cubemap and lighting-cubemap.


As the paper suggests that we could try quantization and dithering, I have tried some naïve integer arithmetic trick, but that leads to some artifact (due to overflow from HDR light?) But performance improves a bit. I didn’t try the acceleration by dividing matrix into block, so now everything is just floating point with sparse vector multiplication (sparsity from the lighting).

The most interesting result I have is from weighted lighting selection. For the number of lighting coefficients goes over 200, there will be no visually big difference between weighting strategies. However if I drop the number down to, says, 30 or 40 then weighting definitely has obvious advantage.


For un-weighted selection, the light jumps and flickers annoyingly. In particular, there is significant incoherence in color channels. This can be describe by the fact that sometimes we pick lighting coefficients below the ground, so for the upper hemisphere we are left with fewer coefficients for certain color channel.


The first improvement is to use transport weighted lighting selection. If I use weighting selection in very low number of coefficients, then lights on the upper hemisphere tends to be picked, but there seems some ghosting effects when I rotate the lighting, as can be seen in accompanying video.


Finally as the paper suggested, the area-weight selection can resolve diffuse effect more aggressively. In addition, I also try to combine these two, but the result isn’t better, as shown in the figure. It would be interesting to investigate why the combined strategy doesn’t work that well!













Un-weighted Selection

Transport Energy Weighted

Wavelet Area Weighted

Combined Weighted


By fixing the view and lighting, here is the video for comparing 4 different strategies: Comparing_DIVX.avi, in the order of Unweighted, Transport Energy Weighted, Wavelet-Area Weighted, and Combined Weighted.