## 8.4 Independent Sampler

The `IndependentSampler` is perhaps the simplest possible (correct)
implementation of the `Sampler` interface. It returns independent
uniform sample values for each sample request without making any further
effort to ensure the quality of the distribution of samples. The
`IndependentSampler` should never be used for rendering if image quality is a
concern, but it is useful for setting a baseline to compare against better
samplers.

Like many of the following samplers, `IndependentSampler` takes a seed to
use when initializing the pseudo-random number generator with which it
produces sample values. Setting different seeds makes it possible to
generate independent sets of samples across multiple runs of the renderer,
which can be useful when measuring the convergence of various sampling
algorithms.

An instance of the `RNG` class is used to generate sample coordinate
values.

So that the `IndependentSampler` always gives the same sample value for a
given pixel sample, it is important to reset the `RNG` to a
deterministic state rather than, for example, leaving it in whatever
state it was at the end of the last pixel sample it was used for. To do
so, we take advantage of the fact that the `RNG` in `pbrt` allows not
only for specifying one of sequences of pseudo-random values but
also for specifying an
offset in that sequence. The implementation below chooses a sequence
deterministically, based on the pixel coordinates and seed value. Then, an
initial offset into the sequence is found based on the index of the sample,
so that different samples in a pixel will start far apart in the sequence.
If a nonzero starting dimension is specified, it gives an additional
offset into the sequence that skips over earlier dimensions.

Given a seeded `RNG`, the implementations of the methods that return 1D
and 2D samples are trivial. Note that `Get2D()` uses C++’s uniform
initialization syntax, which ensures that the two calls to `Uniform()`
happen in a well-defined order, which in turn gives consistent results
across different compilers.

All the methods for analyzing sampling patterns from
Section 8.2 are in agreement about the
`IndependentSampler`: it is a terrible sampler. Independent uniform
samples contain all frequencies equally (they are the definition of white
noise), so they do not push aliasing out to higher frequencies. Further, the
discrepancy of uniform random samples is 1—the worst possible. (To see
why, consider the case of all sample dimensions either having the value 0
or 1.) This sampler’s only saving grace comes in the case of integrating a
function with a significant amount of energy in its high frequencies (with
respect to the sampling rate). In that case, it does about as well as any
of the more sophisticated samplers.