Page tree

Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

There are six different functions to generate samples: GenerateSample1D 

  • GenerateSample1D()

...

  • GenerateSample2D()

...

  • GenerateSample3D()

...

  • DrawSample1D()

...

  • DrawSample2D()

...

  • DrawSample3D()

The .  The Generate functions increment the sample context sampleid; Draw functions do not.

...

There are also six multipoint functions that generate samples for all points in a RixRNG:

  • GenerateSamples1D()

...

  • GenerateSamples2D()

...

  • GenerateSamples3D()

...

  • DrawSamples1D()

...

  • DrawSamples2D()

...

  • DrawSamples3D()

...


Example:  Bxdf GenerateSample() functions need 2D samples to generate sample directions.  The GenerateSample() functions have a RixRNG input parameter (often called "rng") for this purpose.  The RixRNG's sampleCtxArray contains numPts sample contexts, where numPts is the number of shading points to generate sample directions for.  Each sample context keeps track of the patternid and sampleid for that shading point.  In order to get a 2D sample for each shading point, a single call to DrawSamples2D() is sufficient:

...

A common – equally good – alternative is called "Shirley remapping".  It does not rely on 3D stratification.  Instead, get a 2D sample and first use one of the coordinates of the sample to select the sub-domain, and then map the sample within that selected domain (based on the probability) back to the unit square domain.  A figure provides a more intuitive explanation:

TO DO:  Figure of samples before and after remapping?  

Splitting

Splitting was mentioned above.

Intuition: 1 cam ray x 4 diff rays should give same diffuse directions as 4 cam rays x 1 diff ray.  Figure?

TO DO?:  When to use splitting and when not.

Uniform random samples

Non-stratified samples similar to e.g. drand48() can be obtained by calling the HashToRandom() function.  It computes a repeatable random float between 0 and 1 given two unsigned int inputs.  The function is repeatable (ie. the same two inputs always give the same output), and has no multi-threaded contention (whereas drand48() has notoriously bad locking, hampering multi-treaded threaded performance).

Advanced topic: Details of PMJ table lookup implementation

...

For example, for debugging purposes it can be useful to have all samples generated by drand48().  (Note that drand48() is very bad for regular use: convergence is slow since its values are not stratified, and it has a lock on access to its internal state, which slows down multithreaded multi-threaded executions.)  Here is a snippet of code from a Generator that calls drand48():

...