Method

The raytracer used in the assignment is not my own, but Pharr&Humphrey's physically based raytracer pbrt. I opted to using theirs as opposed to my own, because that would provide me with a solid framework to try out some of the more advanced techniques for the next assignments.

Unfortunately, pbrt already has most of the well known sampling and reconstruction techniques implemented. Instead of rewriting my own versions of what was already implemented, I chose to implement some other techniques that may have inferior quality as more advanced ones, and try to find out in which cases they would break. In terms of other reconstruction techniques, I couldn't really find others in the literature, therefore I emphasize on implementing my own alternative sampling techniques, and discuss the influence of already-implemented reconstruction techniques on these.

Comparisons will be made on four basic scenes:

The first is a basic 'hard' case for aliasing effects when sampling and reconstructing pixel samples. The second scene observes the effect of sampling of refracted and reflected rays, especially at the borders of the spheres. Lastly, the two last scenes observe the effect of different techniques in choosing samples on the area lights.

Sampling techniques

Uniform, jittered, best-candidate and low-discrepancy sampling

For reference, I rendered the checkerboard scene with different sampling techniques and different parameters. I included some observations underneath each picture.

Reference image with a low discrepancy filter, 256 samples per pixel, 'ideal' case.

1 sample per pixel, uniform. Note the jaggies on the foreground edges, Also note that at the horizon, because of the high frequency of the edges relative to pixel distance, the sampling rate (below Nyquist frequency) isn't able to capture the frequency of the underlying function. Therefore, the error is turned into low-frequency error.

Still 1 sample per pixel, but jittered. This approach is able to turn the low-frequency error into noise that is less objectionable for the eye.

Supersampling. 4 jittered samples per pixel. This is an easy technique to achieve moderately good results. The combination of supersampling with jittering solves the problem that supersampling alone can never make up for the fact that the scene is not band-limited. Jittering will convert the unavoidable aliasing due to below-Nyquist sampling into noise better than uniform oversampling.

Low discrepancy supersampling, 4 samples per pixel. There is a slight improvement over the jittered supersampling above, because there is less clumping of samples.

Best candidate sampler, 1 sample per pixel. The difference with the 1-sample stratified sampler is subtle, but notice the slightly smoother edges in the foreground and the slightly higher, thus less distracting error frequency in the background.

Best candidate sampler, 4 samples per pixel.

 

n-dimensional Hammersley sampling

I implemented a new Sampler plugin for pbrt, called HammersleyLDSampler. This is a low-discrepancy sampler, which differs from pbrt's in that it doesn't use a scrambling technique to decorrelate the different 1- and 2-dimensional samples. Instead, for each pixel, the HammersleyLDSampler generates a sequence of pixelSamples n-dimensional samples from an n-dimensional Hammersley sequence x(i), for all n dimensions---image plane, time, lens and integration samples (area lights, etc..). Therefore, you guarantee that all n dimensions of the sample are decorrelated (pixelSamples is the number of necessary samples in a pixel) .

In the first attempt, I generated a new sequence of samples for each pixel, by increasing i by pixelSamples, hoping that this would yield decorrelated samples between the different pixels. I also experimented with regular and folded radical inverse functions, yielding so called Hammersley-Zaremba sequences. It turns out that the latter have slightly less discrepancy, as can be seen in the blowups below. The following renderings show that my Hammersley performs equally well as pbrt's built-in scrambled LDSampler for 2 and 4 times supersampling, and is already significantly superior to jittered supersampling at 2 samples per pixel.

PBRT's low discrepancy supersampling, 4 samples per pixel.

n-dimensional Hammersley sampler, 4 samples per pixel.

Jittered supersampling, 2 samples per pixel.

PBRT's low discrepancy supersampling, 2 samples per pixel.

n-dimensional Hammersley sampler, 2 samples per pixel, superior to jittered and similar to scrambled LDSampler.

PBRT's low discrepancy supersampling, 4 samples per pixel.

n-dimensional Hammersley sampler, 4 samples per pixel.

 

Once I tried out rendering some scenes involving area lights, I observed strange artifacts in the shadows, as can be observed in the following renderings:

Buddha with area light. 4 samples per pixel, 16 light samples.

Killeroo with area light. 4 samples per pixel, 16 light samples.

 

Dimensions 7 and 8 of the Halton sequence.

These artifacts encouraged me to do some googling, which led me to a paper by Alexander Keller: Strictly Deterministic Sampling Methods in Computer Graphics. The figure shows the interesting observation that in fact, the individual components in the n-dimensional Hammersley sequences are not decorrelated!

 

Buddha with point light. 2 samples per pixel.

First I didn't realize that this was the cause of the strange artifacts I had with the area lights and soft shadows, as the render of the same buddha scene with a point light doesn't show the same artefacts. Then, I realized that the samples assigned to the area light integrator in this particular scene correspond to the 8th and 9th component of the n-dimensional sample. Indeed, as the paper mentions, the correlation is only really apparent starting from the 7th component. Indeed, even if the Hammersley sequence guarantees that the components have low discrepancy in between components in the same sample, components between different samples can be highly correlated. Therefore, I had to come up with a way to decorrelate the components between samples.

 

Hammersley sampling with Cranley-Patterson rotations

One way to decorrelate the high-dimension components between samples, inter-sequence samples is to scramble the components, as is done by the LDSampler. This paper by the same author gives highly optimized code for scrambling 1D and 2D samples with low discrepancy. As the HammersleyLDSampler deals with n-dimensional samples, I couldn't use this, so I chose another approach.

I opted to reuse the initial sequence of pixelSamples samples (n-dimensional) for all pixels, transforming the original sequence randomly for each pixel. I do this by so called Cranley-Patterson rotations. These rotations compute X'(i) = (X(i) + r(i)) mod 1 in each dimension, where X(i) is the sample value and r(i) is a random number between zero and one.

I thus added an option to switch between both methods in the HammersleyLDSampler plugin, and re-rendered the previous scenes with Cranley-Patterson rotations turned on. As can be observed from the next renderings, the artifacts have gone away. Another advantage of this approach is computation efficiency. The table below summarizes a few rendering times for the checkerboard and scene on my Centrino 1.7Ghz laptop, parameterized by function technique and number of pixel samples. Because I no longer compute pixelSamples Hammersley sequences for each pixel, but only once, the computation time is significantly reduced. The Cranley-Patterson rotations can be computed very efficiently as a 'wrapping' operation to confine the result of the sum between 0 and 1. Also note that non-folded radical inverse is computed slightly more efficiently.

600x6001px4px16px64px
PBRT's LDSampler 10.240.6 
Hammersley without rotation
(non-folded radical inverse)
6.627.051.0216.0
Hammersley without rotation
(folded radical inverse)
  36.0191.3
Hammersley with rotation2.39.036.0 

Rendering times, in seconds, of the checkerboard scene with resolution 600x600 pixels, in function of number of pixels per sample and sampling technique.

 

n-dimensional Hammersley with Cranley-Patterson rotations, 4 pixel supersampling.

n-dimensional Hammersley with Cranley-Patterson rotations, 4 pixel supersampling.

 

Here, I compare zooms of the shadows cast by the buddha figure, for the different sampling techniques so far, each with 16 light samples per pixel. It seems that the rotations are increasing the discrepancy of the samples in the pixels. Compared to the PBRT's samplers, mine seems to have a little more clumping artefacts here.

Jittered, 4 pixel supersampled.

PBRT's low discrepancy, 4 pixel supersampled.

Best candidate, 4 samples per pixel.

n-dimensional Hammersley (with rotations), 4 samples per pixel.

 

The last comparison shows that the HammersleyLDSampler ensures good distribution of samples over the pixel area over all dimensions. To see this, note from the renderings that equally good results are obtained weither we use a combination of 1 image sample per pixel and 16 light samples per pixel or 1 image sample per pixel and 16 light samples per pixel. This would not be the case for a jittered sampler, as is shown in figure 7.23 of Pharr and Humphrey's book.

n-dimensional Hammersley (with rotations), 1 image sample and 16 light samples per pixel

n-dimensional Hammersley (with rotations), 16 image samples and 1 light samples per pixel, equally good as the previous.

 

Larcher based scrambled sampling

While pbrt's LDSampler uses an efficient technique to generate a scrambled Sobol sample for 2D samplers (using bit-ops only), this paper also mentions an equally efficient technique by Larcher and Pillichshammer. I added an option to the LDSampler plugin to support that technique as well as the Sobol technique. My timings and the following renders point out that both are equally good and equally efficient (in fact, the only difference is that the AND operation is replaced by an OR operation).

With Sobol's algorithm, 4 pixel supersampled.

With Larcher and Pillichshammer's algorithm, 4 pixel supersampled.

With Sobol's algorithm, 16 pixel supersampled.

With Larcher and Pillichshammer's algorithm, 16 pixel supersampled.

 

Reconstruction methods

As mentioned in Pharr and Humphrey's book, the choice of reconstruction filter for low-discrepancy filters can have surprising effects. The low-discrepancy sampler LDSampler, unlike the best-candidate sampler, doesn't guarantee that samples in adjacent pixels are placed well distributed in regard to their neighbors. When used with a box filter, this sampling method works well, but when a filter that spans multiple pixels and isn't a constant value is used, it becomes less effective. The following renderings test how well my own HammersleyLDSampler with Cranley-Patterson rotations distributes samples in regard to neighboring pixels. All renderings use 1 image sample and 64 light samples per pixel. I expected that it would do a better job, because of the rotations, but I don't really believe it does. The rendering filtered with a 2-pixel wide Mitchell filter seems to be 'blurrier'.

n-dimensional Hammersley. Box filter.

n-dimensional Hammersley. Mitchell filter.

 

References and code

The code can be found here. It includes hammersley.cpp, and some additions to lowdiscrepancy.cpp aswell as to sampling.h. Also, I generated samplepat.cpp, a precomputed table of the first 1000 primes to generate the Hammersley sequences.
  1. Physically based rendering, Pharr and Humphrey's Morgan Kaufmann
  2. Strictly Deterministic Sampling Methods in Computer Graphics, Alexander Keller
  3. Efficient Multidimensional Sampling, Alexander Keller and Thomas Kollig