Assignment 3: Importance Sampling From an HDR Light Source

Due: Tuesday, Apr 15 2008 at 11:59pm


Physically based rendering often uses High Dynamic Range (HDR) textured light sources to create photorealistic rendering effects. This requires computing an integral over the light source, and the integral is numerically evaluated using Monte Carlo sampling. If the light source is uniform, a simple uniform (area-preserving) sampling on the light source is good enough. However, when HDR textures are used, the simple uniform sampling is no longer efficient -- it converges very slowly and requires a lot of samples to produce a noise-free image. In this case, you will need to implement importance sampling, which can significantly reduce the variance of the estimate and improve rendering quality.

As we discussed in class, importance sampling is implemeted by drawing samples that are distributed according to an importance function. The importance function typically comes from one or more components in the rendering equation. The closer the importance function is to the underlying function being integrated, the smaller variance you will get in rendering. Unfortunately not all functions can be importance sampled, especially those that have no analytic integrals, which is often the case we care about.

In this assignment, you will experiment with a simple method to importance sample according to the light source itself. Here the light source is a rectangular area light, the radiance of which is defined by an HDR texture. A naive implementation is provided to you already, which draws uniform samples from the rectangle. This ignores the spatially varying radiance and produces images that are extremely noisy. Your task is to implement an importance sampling scheme to draws samples in proportion to the radiance defined by the light source texture. This way, regions of the light source that have high radiance (hence contribute most to the illumination) will get more samples statistically. The result is significantly reduced noise and faster convergence speed.

In addition, from this assignment you will learn to create an HDR image of your own, and use it in rendering.

Step 1: Download the starter code and scenes

Click the link below to download a zip file containing the starter code, several test scene files and textures:

You should unzip and copy the source code to their corresponding folders in your pbrt path .

Understanding the starter code

Look through the files and make sure you understand the basic code structure and interface functions. Two new plugins are added. The first plugin is a RectangleShape class (rectangle.cpp), which defines a rectangle shape of size width x height. It is always centered at the origin with a normal pointing upward (0, 0, 1), but in the scene file you can define arbitrary transformation to move it around. You shouldn't need to modify this part of the code.

The second plugin is a RectimageLight class (rectimage.cpp) which defines a rectangular, textured light source. It takes the following parameters from the scene file:

  • nsamples: The number of stochastic samples used to sample the light source. This is the same to any other light source.
  • width, height: The physical size of the light source. In CreateLight function, these two parameters are used to construct a rectangle shape representing the light source.
  • mapname: Specifies an .exr image texture file that defines the radiance of the light source.

You only need to make changes to rectimage.cpp. Just so you know, the coding work for this assignment is significantly shorter than previous assignments. If you do it correctly, you shouldn't need to write more than 50 lines of code.

Running the Test Scenes

A naive implementation is provided to you: it draws uniform samples (in terms of area) on the rectangle. Compile the programs and run pbrt on the test scene killeroo-fake.pbrt. You will notice that it actually does a pretty good job already. The reason is because the radiance texture fake.exr is already fairly smooth, so a uniform sampling scheme is good enough. Now, run the program on any of the other test scenes, notice how noisy the renderings become. By default, all scenes use 8 pixel samples and 8 light source samples. In order to produce noise-free images with the naive implementation, you will need a lot of samples. However, once you have importance sampling implemented, the image quality will be substantially improved under the same number of samples. The following compares the two:

killeroo_IS.jpg killeroo_IS.jpg killeroo_IS.jpg killeroo_IS.jpg

naive (8 pixelsamples)  importance (8 pixelsamples)  naive (8 pixelsamples)  importance (8 pixelsamples)

Step 2: Implementation

Your task is to implement an importance sampling scheme that draw samples in proportion to the radiance L(u,v) (more precisely, the luminance of L(u,v)) defined by the radiance texture. In this case, the luminance of L(u,v) acts as an importance function: more samples will be distributed where L(u,v) is higher, and less samples are distributed where it's lower.


  1. pbrt uses the Spectrum class to represent RGB color. The member function Spectrum::y() returns the luminance of the color.
  2. Read Section 15.6 of the book, and look at other light source classes (such as area.cpp or infinitesample.cpp) to understand the interface functions such as Sample_L (there are several versions, but you only need to work on one of them, as indicated in the code).
  3. infinitesample.cpp has already implemented an importance sampling scheme for spherical environment map. This is very similar to what you need to do here. As a result, you can reuse portions of the data structure and code from that file.
  4. As a sanity check, your sampling scheme should fall back to area uniform sampling when the light source texture is constant. In particular, if you use killeroo-fake.pbrt as a test scene, the importance sampled rendering should look similar to the naive implementation. If it's rather worse, something is wrong with your code.
  5. The probability that a sample appears at (u,v) should obviously be proportional to L(u,v).
  6. Pay special attention to the probabilities (pdf) that you return. Incorrectly calculated probabilities will cause large errors in rendering.
  7. Some lighting textures (like stpeters.exr) have very strong radiance contrast that can cause trouble in rendering. This is because a few pixels may have such high radiance values that all stochastic samples tend to go over there. To avoid the problem, try to use a blurred version of L(u,v) (for example, with a box filter) as importance function, to filter out anomaly pixels.

Step 3: Make Your Own HDR Texture!

Isn't it fun to create your own HDR texture and use it in rendering? With proper tools, such as HDRShop it is quite easy to do so (the latest version of Adobe Photoshop also supports creating HDR images). The basic procedure involves taking a series of pictures, each with a different shutter speed, and composite them into a single floating point image.

As a second part of the assignment is, you are to create at least one HDR image of your own and apply it in your rendering. You will need a camera to take still images toward the same scene. The scene should have interesting high dynamic range effects. So point your camera at a window where there are outdoor lights, or an indoor scene with some strong lights included. To avoid camera shaking, you probably need a tripod, or fix the camera on a stable table top. Next, adjust the shutter speed (at 1 or 2 stops interval) and take a sequence of pictures. You need to take enough pictures such that both the brightest and darkest parts of your scene are correctly exposed in at least one pictures that you've taken. Usually you need at least 5 images to cover the entire range of radiance.

Once you've taken the images, you can use HDRShop to assemble them into a single HDR. First go to and download the free version (v1) of the software (Note: this software is for Windows only), then follow the instructions (Step 1-3 on the "Tutorials" page) to learn how to make an HDR. There is no need to apply any image transformation (like what Step 4 discusses about).

The next step is to save the HDR you created into .hdr format and use it in rendering. Since pbrt only supports .exr format, you will need a converter. If you don't have a proper converter, search for "hdr to exr" in google and find a free tool to use. Finally, open any pbrt test scenes included in this assignment, and substitute the .exr file on the line where the light source is defined with your own .exr file. Render it and see how the result looks!

This part is worth 1 point of the grading.

Useful Resources


For this assignment, you should pack the following files in a single .zip file and email it to

  1. Your modified rectimage.cpp.
  2. One image (in EXR format) for each of the 6 scene provided. In testing your code, you can use the default settings (8 pixelsamples); however, you must submit final quality renderings, by using the number of pixelsamples indicated in each scene file.
  3. An HDR image that you've created (in EXR format), along with an image rendered using the HDR as the image-based light source (pick any available scene you like).

There is no 691MM only portion for this assignment.


This assignment will be graded on a 0-4 scale. Partial grades (such as 3.5) will be given based on partially complete implementation.

  • 0: Little or no work was done.
  • 1: Significant effort was put into the assignment, but the importance sampling scheme does not work or produces images that are wrong or significantly noiser than even the naive implementation.
  • 2: The importance sampling scheme largely works; most part of the rendering is smooth, but there are considerable amount of very bright, noisy pixels.
  • 3: All requirements met. Images are smooth and significantly better than the naive implementation, no or very few noticeable bright pixels.

  • 4: Made an HDR image of your own, and produced a rendering using it. This 1 point is separate from the above, so even if your important sampling completely does not work, you can still secure 1 point if you've completed this step.

Topic revision: r4 - 2008-04-07 - RuiwanG
This site is powered by the TWiki collaboration platform Powered by PerlCopyright © 2008-2018 by the contributing authors. All material on this collaboration platform is the property of the contributing authors.
Ideas, requests, problems regarding UMass CS EdLab? Send feedback

mersin escort adana escort izmir escort gaziantep escort