Page tree

Versions Compared

Key

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

...

By convention, Bxdfs call the DrawSamples?DDrawSamples1D(), DrawSamples2D(), and/or DrawSamples3D() functions.  These functions do not increment the sampleids.  This means that an Integrator calling a Bxdf has to do this incrementing after the Bxdf call – otherwise multiple bxdf samples will be the same sample value, ie. the same direction.  Similar for light sampling and indirect illumination sampling: the Integrator has to increment the sampleids after the samples have been used.  This is easily done by looping over all the sample contexts in a RixRNG like this:

...

Code Block
  SampleCtx* samplectxarray = new SampleCtx[numPts];
  RixRNG rng(parentRng, samplectxarray, numPts);
  RixRNG::Scramble scramble = static_cast<RixRNG::Scramble>(0x8732f9a1)
  for (int pt = 0; pt < numPts; pt++)
  {
    int index = shadingContext->integratorCtxIndex[pt];
    samplectxarray[pt] = parentRng→NewDomainsplitparentRng→NewDomainSplit(index, scramble, 4);
  }

Here the scramble bit-pattern is 0x8732f9a1 and the splitting factor is 4.

...

Another practical detail is that even though PMJ sequences theoretically have infinitely many samples, in practice we limit each PMJ table to 4096 samples to keep memory use reasonable.  When more than 4096 samples per pixel are used – i.e. sampleid values higher than 4096 – we look up from the beginning of another PMJ table (also with 4096 samples).  So the samples beyond 4096 are still stratified, just not quite as well stratified with respect to the first 4096 samples as if we had had larger tables.  For more than 8188 samples per pixel we move to yet another table, and so on.  In the unlikely case that more than 196608 samples per pixel are used, we run out of tables – in this case the samples revert to unstratified, uniform (but deterministic) pseudorandom samples generated with the HashToRandom() function described above.

Advanced topic: Overriding the RixRNG implementation

It is possible to override the default PMJ samples if other sample sequences are desired.  This is scary stuff, but can be useful for experimenting with e.g. primary-space Metropolis rendering algorithms or adaptive progressive photon mapping.  The Generator class provides a way to intercept sample generation: when a custom Generator has been specified, it automatically gets called when e.g. a Bxdf or light sampling calls one of the GenerateSample*() or DrawSample*() functions.  Some of the RixRNG constructors can be passed an explicit pointer to a Generator.

...