RixLighting.h Source File

RixLighting.h
1 #ifndef RixLighting_h
2 #define RixLighting_h
3 /* $Revision: #2 $ $Date: 2015/07/06 $
4 # ------------------------------------------------------------------------------
5 #
6 # Copyright (c) 2013-2015 Pixar Animation Studios. All rights reserved.
7 #
8 # The information in this file (the "Software") is provided for the
9 # exclusive use of the software licensees of Pixar. Licensees have
10 # the right to incorporate the Software into other products for use
11 # by other authorized software licensees of Pixar, without fee.
12 # Except as expressly permitted herein, the Software may not be
13 # disclosed to third parties, copied or duplicated in any form, in
14 # whole or in part, without the prior written permission of
15 # Pixar Animation Studios.
16 #
17 # The copyright notices in the Software and this entire statement,
18 # including the above license grant, this restriction and the
19 # following disclaimer, must be included in all copies of the
20 # Software, in whole or in part, and all permitted derivative works of
21 # the Software, unless such copies or derivative works are solely
22 # in the form of machine-executable object code generated by a
23 # source language processor.
24 #
25 # PIXAR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
26 # ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT
27 # SHALL PIXAR BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES
28 # OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
29 # WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
30 # ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
31 # SOFTWARE.
32 #
33 # Pixar
34 # 1200 Park Ave
35 # Emeryville CA 94608
36 #
37 # ------------------------------------------------------------------------------
38 */
39 
40 #include "RixShading.h"
41 #include "RixBxdf.h"
42 
43 /* RixLightingServices
44  *
45  * RIS usage: when RixLightingServices is obtained via RixIntegratorCtx
46  *
47  * For Unidirectional integrators:
48  *
49  * Begin(shadingCtx, ...) // for direct lighting to RixShadingContext
50  * GenerateSamples()
51  * EvaluateSamples()
52  * End()
53  *
54  * For Bidirectional integrators:
55  *
56  * BeginEmission() // for "photon" generation
57  * GenerateEmission()
58  * End()
59  *
60  * Begin(shadingCtx) // for direct lighting to RixShadingContext
61  * GenerateSamples()
62  * EvaluateSamples()
63  * End()
64  *
65  * Random number contexts:
66  *
67  * When creating an RNG for use by GenerateSamples, either pass
68  * the inherited (passed-in) RNG or make a new one with NewDomain(),
69  * selecting ONE sample. The LightingServices implementation will derive
70  * the appropriate number of samples from it internally.
71  *
72  * Fixed sample count lights:
73  *
74  * Individual lights may be configured to have a fixed sample count in which
75  * case their sample budget is fixed and not statistically chosen from the
76  * global count. In order to support this, k_RespectFixedSampleCount should
77  * be passed to the Begin() method. In addition, caller must provide a
78  * handle into which we return the total required number of fixed samples.
79  *
80  * Subsequent lighting services calls should be invoked with at least
81  * that number of samples in order for the fixed sample count requests
82  * to be satisfied. If the number of samples is smaller that the fixed
83  * sample requirement then we fall back to statistical (globally-budgeted)
84  * sampling.
85  *
86  * In order for MIS weights to be correctly computed, the evaluation
87  * of material samples needs to be aware of whether fixed sample counts
88  * were satisfied or not. This guarantee is provided to Begin().
89  * Passing k_IgnoreFixedSampleCount permits sample counts to be
90  * tailored down as the trace depth increases.
91  *
92  * Note: passing k_RespectFixedSampleCount to the BeginEmission() method
93  * does not dictate sample counts but rather indicates that the count would
94  * have / will be respected for the GenerateSamples calls that will be made
95  * in subsequent Begin(RixShadingContext) / End() pairs. The information
96  * returned by BeginEmission() indicates the fixed sampling requests to
97  * expect for subsequent non global Begin()s, and is not an indication to
98  * pass at least that many samples to GenerateEmission().
99  *
100  * Bidirectional variants:
101  *
102  * Two versions of GenerateSamples() and EvaluateSamples() are provided.
103  * One has additional outputs and will compute pdfs and other entities
104  * relevant for bidirectional transport. To use them, the integrator must
105  * specify bidirectional requirements when it configures itself.
106  *
107  * GenerateSamples can trigger evaluation of the Bxdf:
108  *
109  * Optional arguments can be provided for GenerateSamples() which match
110  * those traditionally passed to RixBxdf::EvaluateSample(). When provided,
111  * we take over the task of invoking the bxdf to evaluate the light samples
112  * and will pass back the same results that would have been handeled by a
113  * loop over Bxdf::EvaluateSample(). By doing so the per-lightsample bxdf
114  * weights can be known by lighting services. This information can be used
115  * to reduce the shadowing computations, therfore it is strongly advised
116  * that integrators allow lighting services to perform the bxdf evaluation.
117  * This behavior is requested by passing non-NULL values for these parameters:
118  *
119  * evaluatedMaterialWeights, evaluatedMaterialFPdf,
120  * evaluatedMaterialRPdf (for bidirectional),
121  * lobesEvaluated
122  *
123  * The evaluatedMaterial arrays must have space for nsamples * npoints,
124  * whilst the lobesWanted array should contain space for npoints values.
125  *
126  */
127 
129 {
130 public:
131 
133  RixInterface(1),
134  shadingCtx(NULL),
135  domain(k_RixBXBoth)
136  {}
137 
138  // Local lighting (shading context aware and importance sampled)
139  enum IntegratorIntent
140  {
141  k_LightSamples,
142  k_MaterialSamples,
143  k_MaterialAndLightSamples
144  };
145 
146  enum Mode
147  {
148  k_IgnoreFixedSampleCount = 0,
149  k_RespectFixedSampleCount = 1,
150  k_ReducedFixedSampleCount = 2
151  };
152 
153  class SampleMode {
154  public:
155  unsigned SaveSamples:1; // Whether or not to save current samples for reuse
156  unsigned RestoreSamples:1; // Whether or not to restore from saved samples
157  unsigned RESERVED:30;
158  SampleMode():
159  SaveSamples(0), // Don't save by default, most don't want to
160  RestoreSamples(1) // Restore for compatibility with those that save
161  {};
162  };
163 
164  // Begin for a Rix shading context (RIS usage)
165  virtual void Begin(RixShadingContext const *sCtx,
166  RixRNG *rng, // arraylength: npoints
167  RixBXEvaluateDomain dom,
168  IntegratorIntent f,
169  Mode m, SampleMode sm,
170  RtInt *fixedSampleCount = NULL,
171  int depth = 0,
172  int parentIndirectCount = 1) = 0;
173 
174  // GenerateSamples for unidirectional integrators
175  virtual void GenerateSamples(RtInt numSamples,
176  RixRNG *rng, // size of internal array should be npoints
177  // outputs
178  RtInt *lightGrpIds,
179  RtVector3 *toLight,
180  RtFloat *dist,
181  RixBXLobeWeights *contribution,
182  RtColorRGB *trans, // pass NULL if shadowing not required
183  RtFloat *lightPdfIllum,
184 
185  // the following outputs may be NULL if evaluation
186  // against the bxdf is not required, sizes are
187  // expected to be either npoints (#1) or
188  // npoints * numSamples (#2)
189  RixBXLobeTraits *lobesWanted, // #1
190  RixBXLobeWeights *evaluatedMaterialWeights, // #2
191  RtFloat *evaluatedMaterialFPdf, // #2
192  RtFloat *evaluatedMaterialRPdf, // #2
193  RixBXLobeTraits *lobesEvaluated, // #2
194  // optional input throughput will be used to
195  // help cull shadow rays based on path throughput
196  RtColorRGB *throughput = NULL // #1
197  ) = 0;
198 
199  // GenerateSamples for bidirectional integrators
200  virtual void GenerateSamples(RtInt numSamples,
201  RixRNG *rng, // size of internal array should be npoints
202  // outputs
203  RtInt *lightGrpIds,
204  RtVector3 *toLight,
205  RtFloat *dist,
206  RixBXLobeWeights *contribution,
207  RtColorRGB *trans, // pass NULL if shadowing not required
208  RtFloat *lightPdfIllum,
209  RtFloat *lightPdfEmit,
210  RtFloat *dirPdf, // FLT_MAX for infinite/distantlight/env
211  RtFloat *solidAngToArea, // 1.0f for infinite/distant/env
212 
213  // the following outputs may be NULL if evaluation
214  // against the bxdf is not required, sizes are
215  // expected to be either npoints (#1) or
216  // npoints * numSamples (#2)
217  RixBXLobeTraits *lobesWanted, // #1
218  RixBXLobeWeights *evaluatedMaterialWeights, // #2
219  RtFloat *evaluatedMaterialFPdf, // #2
220  RtFloat *evaluatedMaterialRPdf, // #2
221  RixBXLobeTraits *lobesEvaluated, // #2
222  // optional input throughput will be used to
223  // help cull shadow rays based on path throughput
224  RtColorRGB *throughput = NULL, // #1
225 
226  // Following parameters are currently unused and
227  // reserved for possible future use
228  RtFloat * volForwardPdf = NULL,
229  RtFloat * volReversePdf = NULL,
230  RtFloat * volCrossPdf = NULL
231  ) = 0;
232 
233  // EvaluateSamples for unidirectional integrators
234  virtual void EvaluateSamples(RtInt numSamples,
235  RixRNG *rng, // size of internal array should be npoints
236  RtVector3 *toLight,
237  RtFloat *dist, // (modified - input and output)
238  RtFloat *matPdf,
239  RixBXLobeWeights *weights,
240  RixBXLobeSampled *lobeSampled,
241  // outputs
242  RtInt *lightGrpIds,
243  RixBXLobeWeights *contribution,
244  RtColorRGB *trans,// pass NULL if shadowing not required
245  RtFloat *lightPdfIllum,
246  // optional input throughput will be used to
247  // help cull shadow rays based on path throughput
248  RtColorRGB *throughput = NULL // #1
249  ) = 0;
250 
251  // Bidirectional
252  virtual void EvaluateSamples(RtInt numSamples,
253  RixRNG *rng, // size of internal array should be npoints
254  RtVector3 *toLight,
255  RtFloat *dist, // (modified - input and output)
256  RtFloat *matPdf,
257  RixBXLobeWeights *weights,
258  RixBXLobeSampled *lobeSampled,
259  // outputs
260  RtInt *lightGrpIds,
261  RixBXLobeWeights *contribution,
262  RtColorRGB *trans, // pass NULL if shadowing not required
263  RtFloat *lightPdfIllum,
264  RtFloat *lightPdfEmit,
265  RtFloat *dirPdf, // FLT_MAX for infinite/distantlight/env
266  RtFloat *solidAngToArea, // 1.0f for infinite/distantlight/env
267  // optional input throughput will be used to
268  // help cull shadow rays based on path throughput
269  RtColorRGB *throughput = NULL, // #1
270 
271  // Following parameters are currently unused and
272  // reserved for possible future use
273  RtFloat * volForwardPdf = NULL,
274  RtFloat * volReversePdf = NULL,
275  RtFloat * volCrossPdf = NULL
276  ) = 0;
277 
278  // Global lighting / emission for "photons"
279  virtual void BeginEmission(Mode m, RtInt *fixedSampleCount = NULL) = 0;
280 
281  // GenerateEmission returns the RxiShadingContexts hit by each sample
282  // separately, such that sample 0 is returned into shadeCtxs[0], sample
283  // 1 into shadeCtxs[1] and so on. each index of shadeCtxs must point to
284  // a RixShadingContext** which is of length numPts.
285  //
286  // Similarly the caller must pass an array of nsamples size to numGrps.
287  // numGrps[0] describes the count of unique shading contexts in shadeCtxs[0]
288  // and numGrps[1] the count of shadeCtxs[1] and so on.
289  //
290  // Caller is responsible for freeing ShadingContexts produced by
291  // GenerateEmission via: RixIntegratorContext::ReleaseShadingContexts.
292 
293  virtual void GenerateEmission(RtInt numPts,
294  RtInt *integratorCtxIds,
295  RtInt *rayIds,
296  RtInt numSamples,
297  RixRNG *rng, // length should be numPts
298  // outputs
299  RtInt *lightGrpIds,
300  RixBXLobeWeights *contribution,
301  RtColorRGB *trans,
302  RtInt *numGrps,
303  RixShadingContext const***shadeCtxs,
304  RtPoint3 *lightPos,
305  RtVector3 *lightNorm,
306  RtFloat *dist,
307  RtFloat *lightPdfIllum,
308  RtFloat *lightPdfEmit,
309  RtVector3 *dir,
310  RtFloat *fDir,
311  RtFloat *dirPdf, // FLT_MAX for infinite/distantlight/env
312  RtFloat *solidAngToArea, // 1.0f for infinite/distantlight/env
313  RtInt *directIllumDisabled = NULL,
314  // values of 1 in this array indicate
315  // the light was disabled via illuminate
316  // or subsets for direct illumination
317  // but may still want to be bounced
318 
319  // Following parameters are currently
320  // unused and reserved for possible
321  // future use
322  RtFloat * volForwardPdf = NULL,
323  RtFloat * volReversePdf = NULL,
324  RtFloat * volCrossPdf = NULL
325  ) = 0;
326 
327  virtual void End() = 0;
328 
329  // All callable _after_ integrator::Begin
330 
331  virtual int GetNumLightGroups() = 0;
332  virtual int GetLightGroup(const char *name) = 0;
333  virtual const char *GetLightGroupName(int i) = 0;
334  virtual int GetTotalFixedSamples() = 0;
335 
336 protected:
337  virtual ~RixLightingServices() {}
338  RixShadingContext const *shadingCtx;
339  RixBXEvaluateDomain domain;
340 };
341 
342 #endif