RenderManAPI  24.0
RixRNG.h
Go to the documentation of this file.
1 /*
2 # ------------------------------------------------------------------------------
3 #
4 # Copyright (c) 2021 Pixar. All rights reserved.
5 #
6 # The information in this file (the "Software") is provided for the exclusive
7 # use of the software licensees of Pixar ("Licensees"). Licensees have the
8 # right to incorporate the Software into other products for use by other
9 # authorized software licensees of Pixar, without fee. Except as expressly
10 # permitted herein, the Software may not be disclosed to third parties, copied
11 # or duplicated in any form, in whole or in part, without the prior written
12 # permission of Pixar.
13 #
14 # The copyright notices in the Software and this entire statement, including the
15 # above license grant, this restriction and the following disclaimer, must be
16 # included in all copies of the Software, in whole or in part, and all permitted
17 # derivative works of the Software, unless such copies or derivative works are
18 # solely in the form of machine-executable object code generated by a source
19 # language processor.
20 #
21 # PIXAR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
22 # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL PIXAR BE
23 # LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
24 # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
25 # OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
26 # CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. IN NO CASE WILL
27 # PIXAR'S TOTAL LIABILITY FOR ALL DAMAGES ARISING OUT OF OR IN CONNECTION WITH
28 # THE USE OR PERFORMANCE OF THIS SOFTWARE EXCEED $50.
29 #
30 # Pixar
31 # 1200 Park Ave
32 # Emeryville CA 94608
33 #
34 # ------------------------------------------------------------------------------
35 */
36 
37 
38 #ifndef RixRNG_h
39 #define RixRNG_h
40 
41 #include <cassert> // for assert
42 #include "prmanapi.h" // IWYU pragma: keep // for PRMAN_INLINE
43 #include "RiTypesHelper.h" // for RtFloat2, RtFloat3
44 
56 
57 #include "RixRNGInline.h" // IWYU pragma: export
58 
59 class RixRNG
60 {
61 public:
62 
63  // A bit pattern used to create new RixRNG domains. An empty scoped enum
64  // is used to make this distinct from unsigned int for type-safety.
65  // Use an explicit cast to create a value of this type, e.g.:
66  // static_cast<RixRNG::Scramble>(0xfa1afe1)
67  enum class Scramble : unsigned {};
68 
76  struct SampleCtx
77  {
78  unsigned patternid; // bit pattern used to select a sample sequence
79  unsigned patternidEmit; // bit pattern used to select a sample sequence for photon emission
80  unsigned sampleid; // sample number
81 
89  SampleCtx NewDomain(Scramble scramble) const
90  {
91  const unsigned oldPatternid = patternid;
92  SampleCtx newd = *this;
93  newd.patternid =
94  RixRNGUtils::shufflePattern(oldPatternid + static_cast<unsigned>(scramble));
95  newd.patternid = (oldPatternid & 0xffff0000) | (newd.patternid & 0xffff); // keep top 16 bits
96  // Handle the rare case (1 out of 65,536) that the new patternid is the same as the old
97  if (newd.patternid == oldPatternid)
98  {
99  newd.patternid = (oldPatternid & 0xffff0000) | ((newd.patternid + 19) & 0xffff);
100  }
101  assert(newd.patternid != oldPatternid);
102  return newd;
103  }
104 
118  SampleCtx NewDomainDistrib(Scramble scramble, unsigned newsampleid) const
119  {
120  const unsigned oldPatternid = patternid;
121  SampleCtx newd;
122  newd.patternid =
123  RixRNGUtils::shufflePattern(oldPatternid + static_cast<unsigned>(scramble), sampleid);
124  newd.patternid = (oldPatternid & 0xffff0000) | (newd.patternid & 0xffff); // keep top 16 bits
125  // Handle the rare case (1 out of 65,536) that the new patternid is the same as the old
126  if (newd.patternid == oldPatternid)
127  {
128  newd.patternid = (oldPatternid & 0xffff0000) | ((newd.patternid + 19) & 0xffff);
129  }
130  newd.sampleid = newsampleid;
131  return newd;
132  }
133 
145  SampleCtx NewDomainSplit(Scramble scramble, unsigned newnumsamples) const
146  {
147  const unsigned oldPatternid = patternid;
148  SampleCtx newd = *this;
149  newd.patternid =
150  RixRNGUtils::shufflePattern(oldPatternid + static_cast<unsigned>(scramble));
151  newd.patternid = (oldPatternid & 0xffff0000) | (newd.patternid & 0xffff); // keep top 16 bits
152  // Handle the rare case (1 out of 65,536) that the new patternid is the same as the old
153  if (newd.patternid == oldPatternid)
154  {
155  newd.patternid = (oldPatternid & 0xffff0000) | ((newd.patternid + 19) & 0xffff);
156  }
157  newd.sampleid *= newnumsamples;
158  return newd;
159  }
160  }; // end of struct SampleCtx
161 
162  // Overrideable implementation
163  class Generator
164  {
165  public:
167  virtual ~Generator() {}
168 
169  // Generator functions to draw a single sample from a sequence.
170  // The parameter 'i' is for sample generators that need the shading context index
171  // to keep track of internal data. (The default PMJ Generator does not need it.)
172  virtual float Sample1D(const SampleCtx& rCtx, unsigned i) const = 0;
173  virtual RtFloat2 Sample2D(const SampleCtx& rCtx, unsigned i) const = 0;
174  virtual RtFloat2 ScrambledSample2D(const SampleCtx& rCtx, unsigned i) const = 0;
175  virtual RtFloat3 Sample3D(const SampleCtx& rCtx, unsigned i) const = 0;
176 
177  // Generator functions to draw multiple samples, each from a different sequence
178  virtual void MultiSample1D(
179  unsigned n,
180  const SampleCtx* rCtx,
181  float* xis) const = 0;
182  virtual void MultiSample2D(
183  unsigned n,
184  const SampleCtx* rCtx,
185  RtFloat2* xis) const = 0;
186  virtual void MultiScrambledSample2D(
187  unsigned n,
188  const SampleCtx* rCtx,
189  RtFloat2* xis) const = 0;
190  virtual void MultiSample3D(
191  unsigned n,
192  const SampleCtx* rCtx,
193  RtFloat3* xis) const = 0;
194  };
195 
196 // Default implementation
197 #include "RixRNGProgressive.h" // IWYU pragma: export
198 
199 public:
200 
201  // RixRNG constructors
202 
203  RixRNG(Generator const *imp, unsigned scaSize = 0)
204  : numPts(scaSize), sampleCtxArray(0), impl(imp)
205  {
206  }
207 
208  // Construct a new RixRNG, with specified number of points and SampleCtx
209  // memory block.
210  RixRNG(Generator const *imp, unsigned scaSize, SampleCtx* sca)
211  : numPts(scaSize), sampleCtxArray(sca), impl(imp)
212  {
213  }
214 
215  // Construct a RixRNG based on another, but with a new number of points
216  // and SampleCtx memory block.
217  RixRNG(RixRNG const* parent, unsigned scaSize, SampleCtx* sca)
218  : numPts(scaSize), sampleCtxArray(sca), impl(parent->impl)
219  {
220  }
221 
222  // Construct a RixRNG based on another, but with a new SampleCtx memory block.
223  // (Same as constructor above, except parameter order.)
224  RixRNG(RixRNG const* parent, SampleCtx* sca, unsigned scaSize)
225  : numPts(scaSize), sampleCtxArray(sca), impl(parent->impl)
226  {
227  }
228 
229  // Construct a RixRNG based on another, but with a new SampleCtx memory
230  // block. Derivation of the new SampleCtx domain uses NewDomains(), ie.
231  // no trajectory splitting and no independent distribution.
232  // WARNING: if your parent RNG is of a different size, do not use
233  // this routine.
234  RixRNG(RixRNG const* parent, SampleCtx* sca, unsigned scaSize, Scramble scramble)
235  : numPts(scaSize), sampleCtxArray(sca), impl(parent->impl)
236  {
237  // Ensure that the new RixRNG isn't larger than the parent.
238  // If the new one is larger we'll read uninitialized memory in NewDomains().
239  assert(scaSize <= parent->numPts);
240 
241  parent->NewDomains(scramble, this);
242  }
243 
244  // Construct a RixRNG based on another, but with a new SampleCtx memory
245  // block. Derivation of the new SampleCtx domain uses trajectory splitting
246  // by calling NewDomainsSplit(). If nsamps=1 then there is no
247  // actual splitting; in that case, it's the same as calling the function
248  // above.
249  // WARNING: if your parent RNG is of a different size, do not use
250  // this routine.
251  RixRNG(RixRNG const* parent, SampleCtx* sca, unsigned scaSize, Scramble scramble, unsigned nsamps)
252  : numPts(scaSize), sampleCtxArray(sca), impl(parent->impl)
253  {
254  // Ensure that the new RixRNG isn't larger than the parent.
255  // If the new one is larger we'll read uninitialized memory in NewDomainsSplit().
256  assert(scaSize <= parent->numPts);
257 
258  parent->NewDomainsSplit(scramble, nsamps, this);
259  }
260 
261  // Construct a RixRNG based on another, but with a new SampleCtx memory
262  // block. Derivation of the new SampleCtx domain generates a new distribution
263  // if doDistrib = true, and ordinary path tracing if false.
264  // WARNING: if your parent RNG is of a different size, do not use
265  // this routine.
267  RixRNG const* parent,
268  SampleCtx* sca, // sample context array
269  unsigned scaSize, // size of sample context array
270  Scramble scramble,
271  unsigned sampleid, // only used if doDistrib is true
272  bool doDistrib)
273  : numPts(scaSize), sampleCtxArray(sca), impl(parent->impl)
274  {
275  // Ensure that the new RixRNG isn't larger than the parent.
276  // If the new one is larger we'll read uninitialized memory in NewDomains().
277  assert(scaSize <= parent->numPts);
278 
279  if (doDistrib) {
280  parent->NewDomainsDistrib(scramble, sampleid, this);
281  } else {
282  parent->NewDomains(scramble, this);
283  }
284  }
285 
286  // Construct a single-element RNG based on another, need new SampleCtx
287  // memory and an offset into parent's sample array.
288  RixRNG GetSlice(SampleCtx* sca, unsigned index) const
289  {
290  RixRNG result(this->impl);
291  result.numPts = 1;
292  result.sampleCtxArray = sca;
293  result.sampleCtxArray[0] = this->sampleCtxArray[index];
294  return result;
295  }
296 
297  virtual ~RixRNG() {}
298 
299  unsigned numPts; // number of elements in sampleCtxArray[]
300  SampleCtx* sampleCtxArray; // sample contexts: pattern ids and sample ids
301  Generator const *impl; // implementation of sample generator
302 
303  SampleCtx& GetSampleCtx(unsigned i) { return sampleCtxArray[i]; }
304 
305  // The 'Generate' family of interfaces assumes caller will generate
306  // a sequence of samples based on a SampleCtx obtained from the
307  // renderer. Generate functions increment the sampleid; Draw functions
308  // do not.
309 
310  // Generate a sample from the sequence and increment sample id
311  float GenerateSample1D(unsigned i) const
312  {
313  float f = impl->Sample1D(sampleCtxArray[i], i); // second param is ignored for PMJ
315  return f;
316  }
317 
318  RtFloat2 GenerateSample2D(unsigned i) const
319  {
320  RtFloat2 f2 = impl->Sample2D(sampleCtxArray[i], i); // second param is ignored for PMJ
322  return f2;
323  }
324 
326  {
327  RtFloat2 f2 = impl->ScrambledSample2D(sampleCtxArray[i], i); // second param is ignored for PMJ
329  return f2;
330  }
331 
332  RtFloat3 GenerateSample3D(unsigned i) const
333  {
334  RtFloat3 f3 = impl->Sample3D(sampleCtxArray[i], i); // second param is ignored for PMJ
336  return f3;
337  }
338 
339  // Generate a sample from the sequence and increment sample id
340  float GenerateSample1D(SampleCtx& c, unsigned i) const
341  {
342  float f = impl->Sample1D(c, i); // second param is ignored for PMJ
343  c.sampleid++;
344  return f;
345  }
346 
347  RtFloat2 GenerateSample2D(SampleCtx& c, unsigned i) const
348  {
349  RtFloat2 f2 = impl->Sample2D(c, i); // second param is ignored for PMJ
350  c.sampleid++;
351  return f2;
352  }
353 
355  {
356  RtFloat2 f2 = impl->ScrambledSample2D(c, i); // second param is ignored for PMJ
357  c.sampleid++;
358  return f2;
359  }
360 
361  RtFloat3 GenerateSample3D(SampleCtx& c, unsigned i) const
362  {
363  RtFloat3 f3 = impl->Sample3D(c, i); // second param is ignored for PMJ
364  c.sampleid++;
365  return f3;
366  }
367 
368  // Generate numPts samples (each from a different sequence) and increment sample ids
369  void GenerateSamples1D(float* xis) const
370  {
373  }
374 
375  void GenerateSamples2D(RtFloat2* xis) const
376  {
379  }
380 
382  {
385  }
386 
387  void GenerateSamples3D(RtFloat3* xis) const
388  {
391  }
392 
393  // Draw a sample from the sequence
394  float DrawSample1D(unsigned i) const
395  {
396  return impl->Sample1D(sampleCtxArray[i], i); // second param is ignored for PMJ
397  }
398 
399  RtFloat2 DrawSample2D(unsigned i) const
400  {
401  return impl->Sample2D(sampleCtxArray[i], i); // second param is ignored for PMJ
402  }
403 
404  RtFloat2 DrawScrambledSample2D(unsigned i) const
405  {
406  return impl->ScrambledSample2D(sampleCtxArray[i], i); // second param is ignored for PMJ
407  }
408 
409  RtFloat3 DrawSample3D(unsigned i) const
410  {
411  return impl->Sample3D(sampleCtxArray[i], i); // second param is ignored for PMJ
412  }
413 
414  // Draw a sample from the sequence
415  float DrawSample1D(const SampleCtx& c, unsigned i) const
416  {
417  return impl->Sample1D(c, i); // second param is ignored for PMJ
418  }
419 
420  RtFloat2 DrawSample2D(const SampleCtx& c, unsigned i) const
421  {
422  return impl->Sample2D(c, i); // second param is ignored for PMJ
423  }
424 
425  RtFloat2 DrawScrambledSample2D(const SampleCtx& c, unsigned i) const
426  {
427  return impl->ScrambledSample2D(c, i); // second param is ignored for PMJ
428  }
429 
430  RtFloat3 DrawSample3D(const SampleCtx& c, unsigned i) const
431  {
432  return impl->Sample3D(c, i); // second param is ignored for PMJ
433  }
434 
435  // Draw numPts samples (each from a different sequence)
436  void DrawSamples1D(float* xis) const
437  {
439  }
440 
441  void DrawSamples2D(RtFloat2* xis) const
442  {
444  }
445 
446  void DrawSamples3D(RtFloat3* xis) const
447  {
449  }
450 
451  // Increment all sampleids
452  void IncrementSampleIds() const
453  {
454  for (unsigned i = 0; i < numPts; ++i)
455  sampleCtxArray[i].sampleid++;
456  }
457 
458  // Setting up new random domains
459  SampleCtx NewDomain(unsigned i, Scramble scramble) const
460  {
461  return sampleCtxArray[i].NewDomain(scramble);
462  }
463 
464  SampleCtx NewDomainDistrib(unsigned i, Scramble scramble,
465  unsigned newsampleid) const
466  {
467  return sampleCtxArray[i].NewDomainDistrib(scramble, newsampleid);
468  }
469 
470  SampleCtx NewDomainSplit(unsigned i, Scramble scramble,
471  unsigned newnumsamples) const
472  {
473  return sampleCtxArray[i].NewDomainSplit(scramble, newnumsamples);
474  }
475 
476  // Multi-point versions of NewDomain() functions.
477  // Setting up new random domains for all sampleCtxs.
478  // These generate new patternids in-place.
479  void NewDomains(Scramble scramble) const
480  {
481  for (unsigned i = 0; i < numPts; i++) {
482  sampleCtxArray[i] = sampleCtxArray[i].NewDomain(scramble);
483  }
484  }
485 
486  void NewDomainsDistrib(Scramble scramble, unsigned newsampleid) const
487  {
488  for (unsigned i = 0; i < numPts; i++) {
489  sampleCtxArray[i] =
490  sampleCtxArray[i].NewDomainDistrib(scramble, newsampleid);
491  }
492  }
493 
494  void NewDomainsSplit(Scramble scramble, unsigned newnumsamples) const
495  {
496  for (unsigned i = 0; i < numPts; i++) {
497  sampleCtxArray[i] =
498  sampleCtxArray[i].NewDomainSplit(scramble, newnumsamples);
499  }
500  }
501 
502  // More multi-point versions of NewDomain() functions.
503  // Setting up new random domains for all sampleCtxs.
504  // (To facilitate future more efficient simd implementations.)
505  // These ones require the new RixRNG to have a size smaller or equal to the
506  // current ("parent") one.
507  void NewDomains(Scramble scramble, RixRNG *newRng) const
508  {
509  unsigned minNumPts = newRng->numPts < numPts ? newRng->numPts : numPts;
510  for (unsigned i = 0; i < minNumPts; i++) {
511  newRng->sampleCtxArray[i] = sampleCtxArray[i].NewDomain(scramble);
512  }
513  newRng->numPts = minNumPts;
514  }
515 
516  void NewDomainsDistrib(Scramble scramble, unsigned newsampleid,
517  RixRNG *newRng) const
518  {
519  unsigned minNumPts = newRng->numPts < numPts ? newRng->numPts : numPts;
520  for (unsigned i = 0; i < minNumPts; i++) {
521  newRng->sampleCtxArray[i] =
522  sampleCtxArray[i].NewDomainDistrib(scramble, newsampleid);
523  }
524  newRng->numPts = minNumPts;
525  }
526 
527  void NewDomainsSplit(Scramble scramble, unsigned newnumsamples,
528  RixRNG *newRng) const
529  {
530  unsigned minNumPts = newRng->numPts < numPts ? newRng->numPts : numPts;
531  for (unsigned i = 0; i < minNumPts; i++) {
532  newRng->sampleCtxArray[i] =
533  sampleCtxArray[i].NewDomainSplit(scramble, newnumsamples);
534  }
535  newRng->numPts = minNumPts;
536  }
538 };
539 
540 #endif
All-inlined interface for generating sample points for use by Monte Carlo integration and multiple-im...
Definition: RixRNG.h:59
void GenerateScrambledSamples2D(RtFloat2 *xis) const
Definition: RixRNG.h:381
SampleCtx NewDomainSplit(unsigned i, Scramble scramble, unsigned newnumsamples) const
Definition: RixRNG.h:470
SampleCtx & GetSampleCtx(unsigned i)
Definition: RixRNG.h:303
void NewDomains(Scramble scramble, RixRNG *newRng) const
Definition: RixRNG.h:507
void NewDomainsSplit(Scramble scramble, unsigned newnumsamples) const
Definition: RixRNG.h:494
RixRNG GetSlice(SampleCtx *sca, unsigned index) const
Definition: RixRNG.h:288
void GenerateSamples2D(RtFloat2 *xis) const
Definition: RixRNG.h:375
virtual void MultiSample2D(unsigned n, const SampleCtx *rCtx, RtFloat2 *xis) const =0
void DrawSamples3D(RtFloat3 *xis) const
Definition: RixRNG.h:446
SampleCtx identifies a sample domain (an index into an arbitrary scheme of sample points)...
Definition: RixRNG.h:76
void NewDomainsDistrib(Scramble scramble, unsigned newsampleid) const
Definition: RixRNG.h:486
float DrawSample1D(const SampleCtx &c, unsigned i) const
Definition: RixRNG.h:415
RtFloat2 DrawSample2D(const SampleCtx &c, unsigned i) const
Definition: RixRNG.h:420
float GenerateSample1D(unsigned i) const
Definition: RixRNG.h:311
virtual void MultiSample3D(unsigned n, const SampleCtx *rCtx, RtFloat3 *xis) const =0
SampleCtx NewDomainDistrib(unsigned i, Scramble scramble, unsigned newsampleid) const
Definition: RixRNG.h:464
virtual void MultiScrambledSample2D(unsigned n, const SampleCtx *rCtx, RtFloat2 *xis) const =0
virtual float Sample1D(const SampleCtx &rCtx, unsigned i) const =0
Definition: RixRNG.h:163
virtual RtFloat3 Sample3D(const SampleCtx &rCtx, unsigned i) const =0
unsigned patternidEmit
Definition: RixRNG.h:79
RtFloat2 GenerateSample2D(SampleCtx &c, unsigned i) const
Definition: RixRNG.h:347
RtFloat2 GenerateScrambledSample2D(SampleCtx &c, unsigned i) const
Definition: RixRNG.h:354
SampleCtx * sampleCtxArray
Definition: RixRNG.h:300
SampleCtx NewDomainSplit(Scramble scramble, unsigned newnumsamples) const
Return a new SampleCtx domain based on this one, but with a scrambled pattern id based on the &#39;scramb...
Definition: RixRNG.h:145
unsigned numPts
Definition: RixRNG.h:299
Scramble
Definition: RixRNG.h:67
RtFloat3 GenerateSample3D(unsigned i) const
Definition: RixRNG.h:332
virtual void MultiSample1D(unsigned n, const SampleCtx *rCtx, float *xis) const =0
Definition: RiTypesHelper.h:82
Generator()
Definition: RixRNG.h:166
pxrcore::Float3 RtFloat3
Definition: RiTypesHelper.h:69
void GenerateSamples1D(float *xis) const
Definition: RixRNG.h:369
RixRNG(RixRNG const *parent, SampleCtx *sca, unsigned scaSize)
Definition: RixRNG.h:224
RtFloat2 GenerateScrambledSample2D(unsigned i) const
Definition: RixRNG.h:325
SampleCtx NewDomain(unsigned i, Scramble scramble) const
Definition: RixRNG.h:459
virtual ~RixRNG()
Definition: RixRNG.h:297
void DrawSamples1D(float *xis) const
Definition: RixRNG.h:436
float DrawSample1D(unsigned i) const
Definition: RixRNG.h:394
SampleCtx NewDomain(Scramble scramble) const
Return a new SampleCtx domain based on this one, but with a scrambled pattern id based on the &#39;scramb...
Definition: RixRNG.h:89
RixRNG(Generator const *imp, unsigned scaSize=0)
Definition: RixRNG.h:203
virtual RtFloat2 Sample2D(const SampleCtx &rCtx, unsigned i) const =0
RtFloat3 DrawSample3D(const SampleCtx &c, unsigned i) const
Definition: RixRNG.h:430
RtFloat2 GenerateSample2D(unsigned i) const
Definition: RixRNG.h:318
RtFloat2 DrawSample2D(unsigned i) const
Definition: RixRNG.h:399
SampleCtx NewDomainDistrib(Scramble scramble, unsigned newsampleid) const
Return a new SampleCtx domain based on this one, but with a scrambled pattern id based on the &#39;scramb...
Definition: RixRNG.h:118
RixRNG(RixRNG const *parent, SampleCtx *sca, unsigned scaSize, Scramble scramble, unsigned sampleid, bool doDistrib)
Definition: RixRNG.h:266
virtual ~Generator()
Definition: RixRNG.h:167
void GenerateSamples3D(RtFloat3 *xis) const
Definition: RixRNG.h:387
RtFloat2 DrawScrambledSample2D(unsigned i) const
Definition: RixRNG.h:404
RixRNG(RixRNG const *parent, SampleCtx *sca, unsigned scaSize, Scramble scramble, unsigned nsamps)
Definition: RixRNG.h:251
void IncrementSampleIds() const
Definition: RixRNG.h:452
void NewDomains(Scramble scramble) const
Definition: RixRNG.h:479
RixRNG(Generator const *imp, unsigned scaSize, SampleCtx *sca)
Definition: RixRNG.h:210
unsigned sampleid
Definition: RixRNG.h:80
Generator const * impl
Definition: RixRNG.h:301
RixRNG(RixRNG const *parent, unsigned scaSize, SampleCtx *sca)
Definition: RixRNG.h:217
RtFloat3 GenerateSample3D(SampleCtx &c, unsigned i) const
Definition: RixRNG.h:361
RtFloat2 DrawScrambledSample2D(const SampleCtx &c, unsigned i) const
Definition: RixRNG.h:425
void DrawSamples2D(RtFloat2 *xis) const
Definition: RixRNG.h:441
RtFloat3 DrawSample3D(unsigned i) const
Definition: RixRNG.h:409
float GenerateSample1D(SampleCtx &c, unsigned i) const
Definition: RixRNG.h:340
virtual RtFloat2 ScrambledSample2D(const SampleCtx &rCtx, unsigned i) const =0
RixRNG(RixRNG const *parent, SampleCtx *sca, unsigned scaSize, Scramble scramble)
Definition: RixRNG.h:234
PRMAN_INLINE unsigned shufflePattern(const unsigned pattern, const unsigned scramble1=0xb2182ef5, const unsigned scramble2=0x1e1897a7)
Definition: RixRNGInline.h:66
void NewDomainsSplit(Scramble scramble, unsigned newnumsamples, RixRNG *newRng) const
Definition: RixRNG.h:527
unsigned patternid
Definition: RixRNG.h:78