RenderManAPI  24.0
RixLPEInline.h
Go to the documentation of this file.
1 /*
2 # ------------------------------------------------------------------------------
3 #
4 # Copyright (c) 2020 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 #ifndef RixLPEInline_h
38 #define RixLPEInline_h
39 
40 #include <cstddef> // for NULL
41 #include <map> // for map, etc
42 #include <set> // for set
43 #include <utility> // for pair
44 #include <vector> // for vector
45 #include "RixBxdfLobe.h" // for RixBXLobeSampled, etc
46 #include "RixIntegrator.h" // for RixDisplayServices, etc
47 #include "RixInterfaces.h" // for RixLPEToken, RixCustomLPE
48 #include "RixShadingUtils.h" // for k_ZeroRGB, k_OneRGB
49 #include "prmanapi.h" // for PRMAN_INLINE
50 #include "RiTypesHelper.h" // for RtColorRGB
51 
52 class RixLPE;
53 class RixLPEState;
54 class RixShadingContext;
55 
56 // The number of scattering types: e.g., D1, D2, ..., S1, S2, ...
57 static const unsigned char k_numScatterTypes = k_RixBXMaxNumDiffuseLobes +
58  k_RixBXMaxNumSpecularLobes +
59  k_RixBXMaxNumUserLobes;
60 
61 // Offsets to start of each group
62 static const unsigned char k_diffStart = 0;
63 static const unsigned char k_specStart = k_diffStart + k_RixBXMaxNumDiffuseLobes;
64 static const unsigned char k_userStart = k_specStart + k_RixBXMaxNumSpecularLobes;
65 
70 {
71 public:
72  short getTransition(short state, RixLPEToken symbol)const
73  {
74  const State &mystate = m_states[state];
75  const Transition *begin = &m_trans[mystate.begin_trans];
76  const Transition *end = begin + mystate.ntrans;
77  while (begin < end) { // binary search
78  const Transition *middle = begin + ((end - begin)>>1);
79  if (symbol < middle->symbol)
80  end = middle;
81  else if (middle->symbol < symbol)
82  begin = middle + 1;
83  else // match
84  return middle->state;
85  }
86  return mystate.wildcard_trans;
87  }
88 
89  void * const * getRules(int state, int &count)const
90  {
91  count = m_states[state].nrules;
92  return &m_rules[m_states[state].begin_rules];
93  }
94 
95  struct State
96  {
97  unsigned int begin_trans;
98  unsigned int ntrans;
99  unsigned int begin_rules;
100  unsigned int nrules;
102  std::vector<int> customIdVec;
103  };
104  struct Transition
105  {
106  // we use this only for sorting
107  static bool trans_comp (const Transition &a, const Transition &b)
108  {
109  return a.symbol < b.symbol;
110  }
112  short state;
113  };
114  std::vector<Transition> m_trans;
115  std::vector<void *> m_rules;
116  std::vector<State> m_states;
117 };
118 
119 //
120 // class RixLPE inline method implementation
121 //
122 
123 // Convert an integer light group id to a LPE token.
126 {
127  // Offset the light group id by the number of built-in tokens.
128  if (lgtGrpId >= 0)
129  return lgtGrpId + k_baseLgtGrpTokenOffset;
130  else
131  return k_BLANK;
132 }
133 
134 // Return true if there are any light path expression AOVs.
135 PRMAN_INLINE bool
137 {
138  return m_anyLPEs;
139 }
140 
141 // Return true if there are any custom light path expressions.
142 PRMAN_INLINE bool
144 {
145  return m_anyCustomLPEs;
146 }
147 
148 // class RixLPEState implementation
149 
152  RixLPEAutomata const* automata, const int nautomata )
153  : m_automata( automata ), m_nautomata( nautomata )
154 {
155  Reset();
156 }
157 
160 {
161 }
162 
163 PRMAN_INLINE void
165 {
166  m_state.resize(m_nautomata);
167  std::fill(m_state.begin(), m_state.end(), 0);
168  m_thruput.One();
169 }
170 
171 PRMAN_INLINE std::vector<short>&
173 {
174  return m_state;
175 }
176 
177 PRMAN_INLINE const std::vector<short>&
179 {
180  return m_state;
181 }
182 
183 PRMAN_INLINE void
184 RixLPEState::SetState(const std::vector<short>& state)
185 {
186  m_state = state;
187 }
188 
189 PRMAN_INLINE bool
191 {
192  if( !m_automata ) return true;
193  for( int i = 0; i < m_nautomata; i++ ) if(m_state[i] >=0) return false;
194  return true;
195 }
196 
197 PRMAN_INLINE bool
199  const RixLPEToken custom)
200 {
201  std::vector<short> saveState = GetState();
202  move(dir, sca, custom);
203  bool active = !Broken();
204  SetState(saveState);
205  return active;
206 }
207 
210 {
211  return m_thruput;
212 }
213 
215 RixLPEState::GetAutomata(int& nautomata) const
216 {
217  nautomata = m_nautomata;
218  return m_automata;
219 }
220 
221 PRMAN_INLINE void
222 RixLPEState::MoveCamera(RixShadingContext const* sCtx, int sCtxIndex)
223 {
224  PIXAR_ARGUSED(sCtx);
225  PIXAR_ARGUSED(sCtxIndex);
227 }
228 
229 PRMAN_INLINE void
230 RixLPEState::MoveCamera(RixShadingContext const* sCtx, int sCtxIndex,
231  const RtColorRGB& thruput)
232 {
233  PIXAR_ARGUSED(sCtx);
234  PIXAR_ARGUSED(sCtxIndex);
236  m_thruput *= thruput;
237 }
238 
239 PRMAN_INLINE void
241  RixShadingContext const* sCtx,
242  int sCtxIndex,
243  RtColorRGB const& thruput,
244  RixLPEToken lpeGroupId)
245 {
246  PIXAR_ARGUSED(sCtx);
247  PIXAR_ARGUSED(sCtxIndex);
248  PIXAR_ARGUSED(thruput);
249  move( RixLPE::k_OBJECT, RixLPE::k_NONE, lpeGroupId );
250 }
251 
252 PRMAN_INLINE void
254  RixShadingContext const* sCtx,
255  int sCtxIndex,
256  RtColorRGB const& thruput,
257  RtColorRGB const* lightTrans,
258  bool firstContribution,
259  RixLPEToken lgtLpeToken)
260 {
261  PIXAR_ARGUSED(sCtx);
262  PIXAR_ARGUSED(sCtxIndex);
263  PIXAR_ARGUSED(thruput);
264  PIXAR_ARGUSED(lightTrans);
265  PIXAR_ARGUSED(firstContribution);
266  move( RixLPE::k_LIGHT, RixLPE::k_NONE, lgtLpeToken );
267 }
268 
269 PRMAN_INLINE void
271  RixShadingContext const* sCtx,
272  int sCtxIndex,
273  RixLPEScatterEvent const scatterEvent,
274  RixLPEToken lpeGroupId)
275 {
276  PIXAR_ARGUSED(sCtx);
277  PIXAR_ARGUSED(sCtxIndex);
278  if( scatterEvent.GetValid() )
279  {
280  RixLPEToken event = scatterEvent.GetEvent();
281  RixLPEToken scatt = scatterEvent.GetScatt();
282 
283  move( event, scatt, lpeGroupId );
284  }
285 }
286 
287 PRMAN_INLINE void
289  RixShadingContext const* sCtx,
290  int sCtxIndex,
291  RixLPEScatterEvent const scatterEvent,
292  const RtColorRGB& thruput,
293  RixLPEToken lpeGroupId,
294  bool doStateTransition)
295 {
296  PIXAR_ARGUSED(sCtx);
297  PIXAR_ARGUSED(sCtxIndex);
298  if( scatterEvent.GetValid() )
299  {
300  RixLPEToken event = scatterEvent.GetEvent();
301  RixLPEToken scatt = scatterEvent.GetScatt();
302 
303  if( doStateTransition )
304  {
305  move( event, scatt, lpeGroupId );
306  }
307 
308  m_thruput *= thruput;
309  }
310 }
311 
312 PRMAN_INLINE void
313 RixLPEState::move( const RixLPEToken event, const RixLPEToken scatt,
314  const RixLPEToken custom )
315 {
316  if( !m_automata )
317  return;
318 
319  for( int i = 0; i < m_nautomata; i++ )
320  {
321  if (m_state[i] >= 0)
322  m_state[i] = m_automata[i].getTransition(m_state[i], event);
323  if (m_state[i] >= 0)
324  m_state[i] = m_automata[i].getTransition(m_state[i], scatt);
325  if (m_state[i] >= 0)
326  m_state[i] = m_automata[i].getTransition(m_state[i], custom);
327  if (m_state[i] >= 0)
328  m_state[i] = m_automata[i].getTransition(m_state[i], RixLPE::k_STOP);
329  }
330 }
331 
332 
333 //
334 // class RixLPEScatterEvent implementation
335 //
336 
338 RixLPEScatterEvent::RixLPEScatterEvent(bool isReflect, bool isUser,
339  bool isSpecular, unsigned char lpeId)
340 {
341  m_isReflect = isReflect;
342  m_lpeId = lpeId;
343  if( isUser )
344  {
345  m_scatter = RixLPE::k_USER1 + m_lpeId;
346  m_lpeIndex = static_cast<unsigned char>(k_userStart + m_lpeId);
347  }
348  else if( isSpecular )
349  {
350  m_scatter = RixLPE::k_SPECULAR1 + m_lpeId;
351  m_lpeIndex = static_cast<unsigned char>(k_specStart + m_lpeId);
352  }
353  else
354  {
355  m_scatter = RixLPE::k_DIFFUSE1 + m_lpeId;
356  m_lpeIndex = static_cast<unsigned char>(k_diffStart + m_lpeId);
357  }
358 }
359 
362 {
363  m_isReflect = lobeSampled.GetReflect();
364  m_lpeId = lobeSampled.GetLpeId();
365 
366  if( !lobeSampled.GetValid() )
367  {
368  m_scatter = RixLPE::k_NONE;
369  m_lpeIndex = 0;
370  }
371  else if( lobeSampled.GetUser() )
372  {
373  m_scatter = RixLPE::k_USER1 + m_lpeId;
374  m_lpeIndex = static_cast<unsigned char>(k_userStart + m_lpeId);
375  }
376  else if( lobeSampled.GetSpecular() )
377  {
378  m_scatter = RixLPE::k_SPECULAR1 + m_lpeId;
379  m_lpeIndex = static_cast<unsigned char>(k_specStart + m_lpeId);
380  }
381  else
382  {
383  // Diffuse
384  m_scatter = RixLPE::k_DIFFUSE1 + m_lpeId;
385  m_lpeIndex = static_cast<unsigned char>(k_diffStart + m_lpeId);
386  }
387 }
388 
391 {
392  m_isReflect = traits.GetReflect();
393 
394  // Find the lpeId
395  unsigned short dl = traits.GetDiffuse();
396  unsigned short sl = traits.GetSpecular();
397 
398  // Only a maximum of one of these should be set
399  assert((dl && !sl) ||
400  (sl && !dl) ||
401  (!dl && !sl));
402 
403  if( (dl && sl) || (!dl && !sl) )
404  {
405  // Neither set is a supported case. We invalidate the scatter event.
406  // Both set is unsupported. Again we invalidate the scatter event.
407  m_scatter = RixLPE::k_NONE;
408  m_lpeId = m_lpeIndex = 0;
409  return;
410  }
411 
412  // An important point to consider here is that, due to the tests above,
413  // either dl or sl will be non-zero. As a consequence, the following sequence
414  // will never produce an undefined result for m_lpeId because the value
415  // passed to RixFindFirstSetBit will always be non-zero.
416  bool isDiffuse = (dl != 0);
417  if( isDiffuse )
418  m_lpeId = static_cast<unsigned char>(RixFindFirstSetBit(dl));
419  else
420  m_lpeId = static_cast<unsigned char>(RixFindFirstSetBit(sl));
421 
422  m_lpeIndex = isDiffuse ? k_diffStart : k_specStart;
423  m_lpeIndex = static_cast<unsigned char>(m_lpeIndex + m_lpeId);
424 
425  m_scatter = isDiffuse ? RixLPE::k_DIFFUSE1 : RixLPE::k_SPECULAR1;
426  m_scatter += m_lpeId;
427 }
428 
431 {
432  return !GetValid() ? RixLPE::k_NONE :
433  (m_isReflect ? RixLPE::k_REFLECT : RixLPE::k_TRANSMIT);
434 }
435 
438 {
439  return !GetValid() ? RixLPE::k_NONE : m_scatter;
440 }
441 
442 PRMAN_INLINE unsigned char
444 {
445  return !GetValid() ? 0 : m_lpeId;
446 }
447 
448 PRMAN_INLINE unsigned char
450 {
451  return !GetValid() ? 0 : m_lpeIndex;
452 }
453 
454 PRMAN_INLINE bool
456 {
457  return (m_scatter != RixLPE::k_NONE);
458 }
459 
460 //
461 // class RixLPE::SplatHelper inline method implementation
462 //
463 
466  RixDisplayServices* displaySvc,
467  int integratorCtxIdx,
468  RixLPE& rixLpe,
469  RixLPEState& state,
470  int depth,
471  RixLPEToken lgtLpeToken,
472  RixLPEToken lpeGrpId,
473  bool isReflect,
474  RtColorRGB const& eyeTrans,
475  RtColorRGB const& lgtTrans,
476  RixShadingContext const* sCtx,
477  int shadingCtxIdx,
478  bool writeOpacityAllowed)
479  : m_depth(depth),
480  m_lgtLpeToken(lgtLpeToken),
481  m_lpeGrpId(lpeGrpId),
482  m_isReflect(isReflect),
483  m_lgtTrans(lgtTrans),
484  m_displaySvc(displaySvc),
485  m_integratorCtxIdx(integratorCtxIdx),
486  m_rixLpe(rixLpe),
487  m_state(state),
488  m_sCtx(sCtx),
489  m_shadingCtxIdx(shadingCtxIdx),
490  m_writeOpacityAllowed(writeOpacityAllowed)
491 {
492  m_eyeTrans = eyeTrans;
493 }
494 
496 {
497 }
498 
499 PRMAN_INLINE void
501  RixBXActiveLobeWeights& activeLobes,
502  int weightIndex,
503  RtColorRGB const& thruput,
504  bool isFinite,
505  float clamp,
506  bool isHoldout)
507 {
508  // Obtain alpha and write Ci.
509  RixLPE const& rixLpe = m_rixLpe;
510 
511  // Splat LPEs before splat beauty
512  if (rixLpe.m_anyLPEs)
513  {
514  // Light path expressions.
515  bool isReflect = m_isReflect;
516  RixLPEToken lgtLpeToken = m_lgtLpeToken;
517 
518  bool firstContribution = true;
519 
520  // backup path state, try avoiding avoiding memory allocations
521  std::vector<short>& state = m_state.GetState();
522  size_t stateSize = state.size();
523  short stateBuffer[1<<16];
524 
525  short* stateBackup = stateBuffer;
526  if (stateSize > 1<<16)
527  // We seems to have a huge number of automatas, we resort to heap memory
528  stateBackup = (short*)malloc(stateSize*sizeof(short));
529 
530  memcpy(stateBackup, state.data(), stateSize*sizeof(short));
531 
532  // Add any non-blank diffuse lobes.
533  for (int i = 0; i < activeLobes.GetNumDiffuseLobes(); i++)
534  {
535  RtColorRGB const& diffuse =
536  activeLobes.GetDiffuseLobe(i)[weightIndex];
537 
538  firstContribution = false;
539 
540  unsigned char lpeId = activeLobes.GetDiffuseLpeId(i);
541  int diffLpeId = k_diffStart + lpeId;
542  RixLPEScatterEvent lpeEvent( isReflect, false, false, lpeId );
543  m_state.MoveVertex(
544  m_sCtx, m_shadingCtxIdx, lpeEvent,
545  m_lpeGrpId);
546  m_state.MoveLight(
547  m_sCtx, m_shadingCtxIdx, diffuse, &m_lgtTrans,
548  firstContribution, lgtLpeToken);
549  SplatLPE(
550  diffuse, &m_lgtTrans, isFinite, clamp, diffLpeId,
551  k_Overwrite, isHoldout);
552 
553  // Restore path state
554  memcpy(state.data(), stateBackup, stateSize*sizeof(short));
555  }
556 
557  // Add any non-blank specular lobes.
558  for (int i = 0; i < activeLobes.GetNumSpecularLobes(); i++)
559  {
560  RtColorRGB const& specular =
561  activeLobes.GetSpecularLobe(i)[weightIndex];
562 
563  firstContribution = false;
564 
565  unsigned char lpeId = activeLobes.GetSpecularLpeId(i);
566  int specLpeId = k_specStart + lpeId;
567  RixLPEScatterEvent lpeEvent( isReflect, false, true, lpeId );
568  m_state.MoveVertex(
569  m_sCtx, m_shadingCtxIdx, lpeEvent,
570  m_lpeGrpId);
571  m_state.MoveLight(
572  m_sCtx, m_shadingCtxIdx, specular, &m_lgtTrans,
573  firstContribution, lgtLpeToken);
574  SplatLPE(
575  specular, &m_lgtTrans, isFinite, clamp, specLpeId,
576  k_Overwrite, isHoldout);
577 
578  // Restore path state
579  memcpy(state.data(), stateBackup, stateSize*sizeof(short));
580  }
581 
582  // Add any non-blank user lobes.
583  for (int i = 0; i < activeLobes.GetNumUserLobes(); i++)
584  {
585  RtColorRGB const& user = activeLobes.GetUserLobe(i)[weightIndex];
586 
587  firstContribution = false;
588 
589  unsigned char lpeId = activeLobes.GetUserLpeId(i);
590  int userLpeId = k_userStart + lpeId;
591  RixLPEScatterEvent lpeEvent( isReflect, true, false, lpeId );
592  m_state.MoveVertex(
593  m_sCtx, m_shadingCtxIdx, lpeEvent,
594  m_lpeGrpId);
595  m_state.MoveLight(
596  m_sCtx, m_shadingCtxIdx, user, &m_lgtTrans, firstContribution,
597  lgtLpeToken);
598  SplatLPE(
599  user, &m_lgtTrans, isFinite, clamp, userLpeId, k_Overwrite,
600  isHoldout);
601 
602  // Restore path state
603  memcpy(state.data(), stateBackup, stateSize*sizeof(short));
604  }
605 
606  if (stateBackup != stateBuffer) free(stateBackup);
607  }
608 
609  // Beauty channel (Ci).
610  if (rixLpe.m_beautyChanId != k_InvalidChannelId)
611  {
612  if (!isHoldout)
613  {
614  RtColorRGB val = isFinite
615  ? activeLobes.SumAtIndex(weightIndex) * thruput * m_lgtTrans * clamp
616  : RixConstants::k_ZeroRGB;
617 
618  SplatBeauty(val, m_eyeTrans);
619  }
620  else if (m_writeOpacityAllowed && (m_depth == 0))
621  {
622  float trans1 = m_eyeTrans.ChannelAvg();
623  if (trans1 != 1.0f)
624  {
625  m_displaySvc->WriteOpacity(
626  m_rixLpe.m_beautyChanId, m_integratorCtxIdx, 1.0f - trans1);
627  }
628  }
629  }
630 }
631 
632 PRMAN_INLINE void
634  RtColorRGB const& emission,
635  RtColorRGB const& thruput,
636  bool isFinite,
637  float clamp,
638  bool isHoldout)
639 {
640  // Obtain alpha and write Ci.
641  RixLPE const& rixLpe = m_rixLpe;
642 
643  // Splat LPEs before splat beauty since we may have holdout LPE that will
644  // change the Beauty and alpha
645  if (rixLpe.m_anyLPEs)
646  {
647  // backup path state, try avoiding avoiding memory allocations
648  std::vector<short>& state = m_state.GetState();
649  size_t stateSize = state.size();
650  short stateBuffer[1<<16];
651 
652  short* stateBackup = stateBuffer;
653  if (stateSize > 1<<16)
654  // We seems to have a huge number of automatas, we resort to heap memory
655  stateBackup = (short*)malloc(stateSize*sizeof(short));
656 
657  memcpy(stateBackup, state.data(), stateSize*sizeof(short));
658 
659  m_state.MoveEmissiveObject(
660  m_sCtx, m_shadingCtxIdx, emission, m_lpeGrpId);
661  SplatLPE(
662  emission, 0, isFinite, clamp, -1, k_Accumulate,
663  isHoldout);
664 
665  // Restore path state
666  memcpy(state.data(), stateBackup, stateSize*sizeof(short));
667 
668  if (stateBackup != stateBuffer) free(stateBackup);
669  }
670 
671  // Beauty channel (Ci).
672  if (rixLpe.m_beautyChanId != k_InvalidChannelId)
673  {
674  if (!isHoldout)
675  {
676  SplatBeauty(
677  isFinite
678  ? (emission * thruput * m_lgtTrans * clamp)
679  : RixConstants::k_ZeroRGB,
680  m_eyeTrans);
681  }
682  else if (m_writeOpacityAllowed && (m_depth == 0))
683  {
684  float trans1 = m_eyeTrans.ChannelAvg();
685  if (trans1 != 1.0f)
686  {
687  m_displaySvc->WriteOpacity(
688  m_rixLpe.m_beautyChanId, m_integratorCtxIdx, 1.0f - trans1);
689  }
690  }
691  }
692 }
693 
694 PRMAN_INLINE void
696  RtColorRGB const& color,
697  bool isFinite,
698  float clamp)
699 {
700  // Splat LPEs before splat beauty since we may have holdout LPE that will
701  // change the Beauty's alpha
702 
703  if (m_rixLpe.m_anyLPEs)
704  {
705  SplatLPE(color, &m_lgtTrans, isFinite, clamp, -1);
706  }
707 
708  SplatBeauty(
709  isFinite
710  ? (color * m_lgtTrans * clamp)
711  : RixConstants::k_ZeroRGB,
712  m_eyeTrans);
713 }
714 
715 PRMAN_INLINE void
717 {
718  m_displaySvc->Splat(m_rixLpe.m_beautyChanId, m_integratorCtxIdx, val);
719 
720  float trans1 = trans.ChannelAvg();
721  if (m_writeOpacityAllowed && (m_depth == 0) && (trans1 != 1.0f))
722  {
723  m_displaySvc->WriteOpacity(
724  m_rixLpe.m_beautyChanId, m_integratorCtxIdx, 1.0f - trans1);
725  }
726 }
727 
728 PRMAN_INLINE void
730  RtColorRGB const& val,
731  RtColorRGB const* lgtTrans,
732  bool isFinite,
733  float clamp,
734  int lpeId,
735  OverwritePolicy overwritePolicy,
736  bool isHoldout)
737 {
738  PIXAR_ARGUSED(lpeId);
739  m_rixLpe.Splat( m_state, m_displaySvc, val,
740  m_integratorCtxIdx, lgtTrans,
741  clamp, isFinite, overwritePolicy, isHoldout );
742 }
743 
744 #endif
unsigned int begin_rules
Definition: RixLPEInline.h:99
PRMAN_INLINE bool GetReflect() const
Definition: RixBxdfLobe.h:680
void MoveLight(RixShadingContext const *sCtx, int sCtxIndex, RtColorRGB const &thruput, RtColorRGB const *lightTrans, bool firstContribution, RixLPEToken lgtLpeToken)
Call this method at a light event along a light transport path.
Definition: RixLPEInline.h:253
PRMAN_INLINE RixLPEToken GetEvent() const
Definition: RixLPEInline.h:430
RixShadingContext is analogous to a RenderMan grid - it is a group of 1 or more points that may be sh...
Definition: RixShading.h:663
Definition: RixLPE.h:148
Definition: RixBxdfLobe.h:332
PRMAN_INLINE RixLPEToken GetScatt() const
Definition: RixLPEInline.h:437
Definition: RixLPE.h:195
void SetState(const std::vector< short > &state)
Definition: RixLPEInline.h:184
~RixLPEState()
Definition: RixLPEInline.h:159
unsigned int nrules
Definition: RixLPEInline.h:100
PRMAN_INLINE unsigned char GetSpecularLpeId(int i) const
Definition: RixBxdfLobe.h:1470
PRMAN_INLINE unsigned char GetLpeIndex() const
Definition: RixLPEInline.h:449
Definition: RixLPE.h:194
void MoveCamera(RixShadingContext const *sCtx, int sCtxIndex)
Call this method at a camera event along a light transport path.
Definition: RixLPEInline.h:222
PRMAN_INLINE unsigned int RixFindFirstSetBit(unsigned long long v)
Definition: RixShadingUtils.h:110
static PRMAN_INLINE RixLPEToken LgtGrpIdToToken(int lightGroupId)
Convert an integer light group id to an LPE token.
Definition: RixLPEInline.h:125
std::vector< State > m_states
Definition: RixLPEInline.h:116
pxrcore::ColorRGB RtColorRGB
Definition: RiTypesHelper.h:520
Definition: RixLPEInline.h:95
PRMAN_INLINE RtColorRGB const * GetUserLobe(int i) const
Definition: RixBxdfLobe.h:1440
PRMAN_INLINE unsigned char GetNumDiffuseLobes() const
Definition: RixBxdfLobe.h:1410
Definition: RixLPE.h:137
bool m_anyCustomLPEs
Definition: RixLPE.h:256
PRMAN_INLINE bool GetValid() const
Definition: RixBxdfLobe.h:650
PRMAN_INLINE void SplatPerLobe(RixBXActiveLobeWeights &activeLobes, int weightIndex, RtColorRGB const &thruput, bool isFinite, float clamp=1.0f, bool isHoldout=false)
Definition: RixLPEInline.h:500
static const int k_baseLgtGrpTokenOffset
Definition: RixLPE.h:188
int RixLPEToken
Definition: RixInterfaces.h:977
OverwritePolicy
Definition: RixLPE.h:191
Definition: RixLPE.h:140
PRMAN_INLINE unsigned char GetDiffuseLpeId(int i) const
Definition: RixBxdfLobe.h:1464
PRMAN_INLINE SplatHelper(RixDisplayServices *displaySvc, int integratorCtxIndex, RixLPE &rixLpe, RixLPEState &state, int depth, RixLPEToken lightLpeToken, RixLPEToken lpeGroupId, bool isReflect, RtColorRGB const &eyeTrans, RtColorRGB const &lightTrans, RixShadingContext const *shadingCtx, int shadingCtxIndex, bool writeOpacityAllowed=true)
Definition: RixLPEInline.h:465
static bool trans_comp(const Transition &a, const Transition &b)
Definition: RixLPEInline.h:107
RixLPEToken symbol
Definition: RixLPEInline.h:111
bool m_anyLPEs
Definition: RixLPE.h:253
This struct represents the characteristics of just one lobe of a bxdf.
Definition: RixBxdfLobe.h:63
Definition: RixLPE.h:135
PRMAN_INLINE unsigned char GetNumUserLobes() const
Definition: RixBxdfLobe.h:1422
std::vector< int > customIdVec
Definition: RixLPEInline.h:102
std::vector< Transition > m_trans
Definition: RixLPEInline.h:114
Definition: RixLPE.h:144
Definition: RixLPE.h:138
void MoveVertex(RixShadingContext const *sCtx, int sCtxIndex, RixLPEScatterEvent const scatterEvent, RixLPEToken lpeGroupId=RixLPE::k_BLANK)
Invoke this method at an intermediate (non-camera/non-light) scattering event along a light transport...
Definition: RixLPEInline.h:270
PRMAN_INLINE bool GetUser() const
Definition: RixBxdfLobe.h:713
PRMAN_INLINE unsigned char GetLpeId() const
Definition: RixLPEInline.h:443
std::vector< void * > m_rules
Definition: RixLPEInline.h:115
void *const * getRules(int state, int &count) const
Definition: RixLPEInline.h:89
Definition: RixLPE.h:139
short wildcard_trans
Definition: RixLPEInline.h:101
bool Broken() const
Definition: RixLPEInline.h:190
const RixLPEAutomata * GetAutomata(int &nautomata) const
Definition: RixLPEInline.h:215
void Reset()
Definition: RixLPEInline.h:164
short getTransition(short state, RixLPEToken symbol) const
Definition: RixLPEInline.h:72
A compact deterministic finite automata class.
Definition: RixLPEInline.h:69
const RtColorRGB & GetThruput() const
Definition: RixLPEInline.h:209
PRMAN_INLINE bool AnyCustomLPEs() const
Definition: RixLPEInline.h:143
#define PRMAN_INLINE
Definition: prmanapi.h:99
Multiple methods of RixDisplayServices require similar parameters:
Definition: RixIntegrator.h:97
unsigned int begin_trans
Definition: RixLPEInline.h:97
PRMAN_INLINE unsigned char GetUserLpeId(int i) const
Definition: RixBxdfLobe.h:1476
PRMAN_INLINE RtColorRGB const * GetSpecularLobe(int i) const
Definition: RixBxdfLobe.h:1434
Definition: RixLPE.h:387
RtColorRGB m_eyeTrans
Definition: RixLPE.h:353
void MoveEmissiveObject(RixShadingContext const *sCtx, int sCtxIndex, RtColorRGB const &thruput, RixLPEToken lpeGroupId=RixLPE::k_BLANK)
Call this method at an emissive object event along a light transport path.
Definition: RixLPEInline.h:240
PRMAN_INLINE unsigned char GetNumSpecularLobes() const
Definition: RixBxdfLobe.h:1416
RixLPEState(RixLPEAutomata const *automata, const int nautomata)
Definition: RixLPEInline.h:151
PRMAN_INLINE void SplatBeauty(RtColorRGB const &val, RtColorRGB &trans) const
Definition: RixLPEInline.h:716
PRMAN_INLINE RixLPEScatterEvent(RixBXLobeSampled lobeSampled)
Definition: RixLPEInline.h:361
PRMAN_INLINE unsigned short GetSpecular() const
Definition: RixBxdfLobe.h:1016
Definition: RixLPE.h:136
PRMAN_INLINE unsigned short GetDiffuse() const
Definition: RixBxdfLobe.h:1010
Definition: RixLPE.h:127
PRMAN_INLINE bool GetValid() const
Definition: RixLPEInline.h:455
std::vector< short > & GetState()
Definition: RixLPEInline.h:172
Definition: RixLPE.h:156
PRMAN_INLINE ~SplatHelper()
Definition: RixLPEInline.h:495
unsigned int ntrans
Definition: RixLPEInline.h:98
RixChannelId m_beautyChanId
Definition: RixLPE.h:259
Represents the LPE system state of a light transport path.
Definition: RixLPE.h:439
PRMAN_INLINE void SplatValue(RtColorRGB const &color, bool isFinite, float clamp=1.0f)
Definition: RixLPEInline.h:695
This struct represents the characteristics of potentially several lobes of a bxdf in aggregate...
Definition: RixBxdfLobe.h:178
PRMAN_INLINE bool GetSpecular() const
Definition: RixBxdfLobe.h:674
PRMAN_INLINE RtColorRGB SumAtIndex(int index, bool includeUserLobes=false) const
Definition: RixBxdfLobe.h:1506
PRMAN_INLINE void SplatEmission(RtColorRGB const &emission, RtColorRGB const &thruput, bool isFinite, float clamp=1.0f, bool isHoldout=false)
Definition: RixLPEInline.h:633
PRMAN_INLINE bool GetReflect() const
Definition: RixBxdfLobe.h:992
bool Test(const RixLPEToken dir, const RixLPEToken sca, const RixLPEToken custom)
Definition: RixLPEInline.h:198
PRMAN_INLINE bool AnyLPEs() const
Definition: RixLPEInline.h:136
Definition: RixLPEInline.h:104
PRMAN_INLINE void SplatLPE(RtColorRGB const &val, RtColorRGB const *lightTrans, bool isFinite, float clamp, int lpeId=-1, OverwritePolicy overwritePolicy=k_Overwrite, bool isHoldout=false)
Definition: RixLPEInline.h:729
short state
Definition: RixLPEInline.h:112
Definition: RixLPE.h:134
Definition: RixLPE.h:141
PRMAN_INLINE unsigned char GetLpeId() const
Definition: RixBxdfLobe.h:719
#define PIXAR_ARGUSED(x)
Definition: prmanapi.h:170
PRMAN_INLINE RtColorRGB const * GetDiffuseLobe(int i) const
Definition: RixBxdfLobe.h:1428