RenderMan API  23.0
RixColorUtils.h
Go to the documentation of this file.
1 /*
2 # ------------------------------------------------------------------------------
3 #
4 # Copyright (c) 1986-2019 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 RixColorUtils_h
39 #define RixColorUtils_h
40 
41 #include "RixShadingUtils.h" // for PRMAN_INLINE
42 
43 #define F_LOGDOTFIVE (-0.30102999566f)
44 #define F_INVLOGDOTFIVE (-3.32192809489f)
45 
47 {
48  k_sRGB = 0,
57 };
58 
59 // NOTE: All matrices assume their default illuminant (usually D65)
60 
61 // clang-format off
62 static float s_RGBtoXYZ[][9] = {
63  // sRGB D65
64  { 0.4124564f, 0.3575761f, 0.1804375f,
65  0.2126729f, 0.7151522f, 0.0721750f,
66  0.0193339f, 0.1191920f, 0.9503041f
67  },
68  // Rec.709
69  { 0.4123866f, 0.3575915f, 0.1804505f,
70  0.2126368f, 0.7151830f, 0.0721802f,
71  0.0193306f, 0.1191972f, 0.9503726f
72  },
73  // Rec.2020
74  { 0.6369535f, 0.1446192f, 0.1688559f,
75  0.2626983f, 0.6780088f, 0.0592929f,
76  0.0000000f, 0.0280731f, 1.0608272f
77  },
78  // DCI-P3
79  { 4.45169816e-01f, 2.77134409e-01f, 1.72282670e-01f,
80  2.09491678e-01f, 7.21595254e-01f, 6.89130679e-02f,
81  -3.63410132e-17f, 4.70605601e-02f, 9.07355394e-01f
82  },
83  // Alexa Wide
84  { 0.638008f, 0.214704f, 0.097744f,
85  0.291954f, 0.823841f, -0.115795f,
86  0.002798f, -0.067034f, 1.153294f
87  },
88  // ACES cg
89  { 0.66245418f, 0.13400421f, 0.15618769f,
90  0.27222872f, 0.67408177f, 0.05368952f,
91  -0.00557465f, 0.00406073f, 1.0103391f
92  },
93  // Canon Cinema Gamut
94  {
95  0.71603649f, 0.12968185f, 0.10471021f,
96  0.26125656f, 0.86963121f, -0.13088776f,
97  -0.00967617f, -0.23647866f, 1.3350552f,
98  },
99  // old NTSC - for backward compatibility
100  { 1.909851f, -0.984623f, 0.058331f,
101  -0.532414f, 1.999082f, -0.118429f,
102  -0.288187f, -0.028307f, 0.897936f
103  }
104 };
105 // clang-format on
106 
107 // clang-format off
108 static float s_XYZtoRGB[][9] = {
109  // sRGB D65
110  { 3.2404542f, -1.5371385f, -0.4985314f,
111  -0.9692660f, 1.8760108f, 0.0415560f,
112  0.0556434f, -0.2040259f, 1.0572252f
113  },
114  // Rec.709 D65
115  { 3.24100326f, -1.53739899f, -0.49861587f,
116  -0.96922426f, 1.87592999f, 0.04155422f,
117  0.05563942f, -0.2040112f, 1.05714897f
118  },
119  // Rec.2020 D65
120  { 1.71666343f, -0.35567332f, -0.25336809f,
121  -0.66667384f, 1.61645574f, 0.0157683f,
122  0.01764248f, -0.04277698f, 0.94224328f
123  },
124  // DCI-P3
125  { 2.72539403f, -1.01800301f, -0.4401632f,
126  -0.79516803f, 1.68973205f, 0.02264719f,
127  0.04124189f, -0.08763902f, 1.10092938f
128  },
129  // Alexa Wide
130  { 1.78906454f, -0.48253382f, -0.20007503f,
131  -0.63984874f, 1.3964001f, 0.19443223f,
132  -0.04153097f, 0.08233496f, 0.87886816f
133  },
134  // ACES cg
135  { 1.64102338f, -0.32480329f, -0.2364247f,
136  -0.66366286f, 1.61533159f, 0.01675635f,
137  0.01172189f, -0.00828444f, 0.98839486f
138  },
139  // Canon Cinema Gamut
140  {
141  1.48984566f, -0.2609007f, -0.14242914f,
142  -0.45817234f, 1.26164365f, 0.15962564f,
143  -0.07035813f, 0.22158431f, 0.77627493f
144  },
145  // old NTSC - for backward compatibility
146  { 0.606937f, 0.298939f, 0.0f,
147  0.173509f, 0.586625f, 0.066099f,
148  0.200263f, 0.114436f, 1.115749f
149  }
150 };
151 // clang-format on
152 
153 /*
154  * RixHsvToRgb(hsv, rgb) converts a hue/saturation/value triple into an
155  * RGB triple.
156  * Based on the "hexcone" model. See A.R.Smith, Color Gamut Transform Pairs,
157  * Proc. Siggraph '78.
158  */
159 #define IFLOOR(x) (((x) < 0.0f && (x) != (int)(x)) ? (int)x - 1 : (int)x)
160 
161 PRMAN_INLINE void
163 {
164  float h, f;
165  float m, n, k;
166  int i;
167 
168  h = hsv.r;
169  h = h - static_cast<float>(static_cast<int>(h)) + (h < 0.0f ? 1.0f : 0.0f); /* h mod 1.0 */
170  h = h * 6.0f;
171  i = IFLOOR(h); /* integer part */
172  f = h - static_cast<float>(i); /* fractional part */
173  m = hsv.b * (1.0f - hsv.g);
174  n = hsv.b * (1.0f - (hsv.g * f));
175  k = hsv.b * (1.0f - (hsv.g * (1.0f - f)));
176 
177  switch (i)
178  { /* around the color wheel */
179  case 0:
180  default:
181  rgb.r = hsv.b;
182  rgb.g = k;
183  rgb.b = m;
184  break;
185  case 1:
186  rgb.r = n;
187  rgb.g = hsv.b;
188  rgb.b = m;
189  break;
190  case 2:
191  rgb.r = m;
192  rgb.g = hsv.b;
193  rgb.b = k;
194  break;
195  case 3:
196  rgb.r = m;
197  rgb.g = n;
198  rgb.b = hsv.b;
199  break;
200  case 4:
201  rgb.r = k;
202  rgb.g = m;
203  rgb.b = hsv.b;
204  break;
205  case 5:
206  rgb.r = hsv.b;
207  rgb.g = m;
208  rgb.b = n;
209  break;
210  }
211 }
212 
213 PRMAN_INLINE void
215 {
216  int spoke; /* part of color wheel it's in */
217  float h, s, v; /* hue, saturation & value components of HSV */
218  float x; /* smallest RGB component */
219 
220  /* set v to largest rgb component, x to smallest */
221  if (rgb.r > rgb.g)
222  {
223  if (rgb.r > rgb.b)
224  {
225  v = rgb.r;
226  spoke = 0;
227  }
228  else
229  {
230  v = rgb.b;
231  spoke = 4;
232  }
233  if (rgb.g < rgb.b)
234  {
235  x = rgb.g;
236  spoke++;
237  }
238  else
239  {
240  x = rgb.b;
241  }
242  }
243  else
244  {
245  if (rgb.g > rgb.b)
246  {
247  v = rgb.g;
248  spoke = 2;
249  }
250  else
251  {
252  v = rgb.b;
253  spoke = 4;
254  }
255  if (rgb.r < rgb.b)
256  {
257  x = rgb.r;
258  }
259  else
260  {
261  x = rgb.b;
262  spoke++;
263  }
264  }
265 
266  h = 0.0f; /* default hue is red */
267  s = 0.0f; /* default saturation is unsaturated (gray) */
268  if (v < 0.0001f) /* black */
269  goto done;
270 
271  s = (v - x) / v; /* actual saturation */
272  if (s < 0.0001f) /* gray */
273  goto done;
274 
275  /* now compute actual hue */
276  switch (spoke)
277  {
278  case 0: /* red largest, blue smallest */
279  h = 1.0f - (v - rgb.g) / (v - x);
280  break;
281 
282  case 1: /* red largest, green smallest */
283  h = 5.0f + (v - rgb.b) / (v - x);
284  break;
285 
286  case 2: /* green largest, red smallest */
287  h = 3.0f - (v - rgb.b) / (v - x);
288  break;
289 
290  case 3: /* green largest, blue smallest */
291  h = 1.0f + (v - rgb.r) / (v - x);
292  break;
293 
294  case 4: /* blue largest, red smallest */
295  h = 3.0f + (v - rgb.g) / (v - x);
296  break;
297 
298  case 5: /* blue largest, green smallest */
299  h = 5.0f - (v - rgb.r) / (v - x);
300  break;
301  }
302 done:
303  hsv.r = h * (1.0f / 6.0f);
304  hsv.g = s;
305  hsv.b = v;
306 }
307 
308 /*
309  * RixHslToRgb(hsl, rgb) converts a color in hue/saturation/lightness space into
310  * an RGB triple.
311  *
312  * Based on the HLS color model. See Foley and Van Dam, "Fundamentals of
313  * Interactive Computer Graphics", 1982.
314  *
315  * RixHslToRgb assumes h is in the range [0,1) instead of [0,360) as defined
316  * in Foley and Van Dam.
317  */
318 
319 // private function
320 PRMAN_INLINE float
321 rixValue(float n1, float n2, float hue)
322 {
323  /* hue = hue mod 1.0 */
324  hue = hue - (float)(int)hue + (hue < (float)0.0 ? (float)1.0 : (float)0.0);
325  if (hue < (float)0.16666667)
326  return (n1 + (n2 - n1) * hue * (float)6.0);
327  if (hue < (float)0.5)
328  return (n2);
329  if (hue < (float)0.66666667)
330  return (n1 + (n2 - n1) * ((float)4.0 - hue * (float)6.0));
331  return (n1);
332 }
333 
334 PRMAN_INLINE void
336 {
337  float h, s, l;
338  float m1, m2;
339 
340  h = hsl.r;
341  s = hsl.g;
342  l = hsl.b;
343 
344  if (s == 0.0f)
345  {
346  rgb.r = rgb.g = rgb.b = l;
347  return;
348  }
349 
350  if (l <= 0.5f)
351  m2 = l * (1.0f + s);
352  else
353  m2 = l + s - l * s;
354 
355  m1 = 2.0f * l - m2;
356 
357  rgb.r = rixValue(m1, m2, h + 0.33333333f);
358  rgb.g = rixValue(m1, m2, h);
359  rgb.b = rixValue(m1, m2, h - 0.33333333f);
360 }
361 
362 PRMAN_INLINE void
364 {
365  float maxi, mini, maxmin;
366  float rc, gc, bc, hue, sat, light;
367 
368  if (rgb.r < rgb.g)
369  {
370  mini = (rgb.r < rgb.b) ? rgb.r : rgb.b;
371  maxi = (rgb.g > rgb.b) ? rgb.g : rgb.b;
372  }
373  else
374  {
375  mini = (rgb.g < rgb.b) ? rgb.g : rgb.b;
376  maxi = (rgb.r > rgb.b) ? rgb.r : rgb.b;
377  }
378  light = (maxi + mini) / 2.0f;
379 
380  if (maxi == mini)
381  hsl.r = hsl.g = 0.0f;
382  else
383  {
384  if (light < 0.5f)
385  sat = (maxi - mini) / (maxi + mini);
386  else
387  sat = (maxi - mini) / (2.0f - maxi - mini);
388 
389  maxmin = 1.0f / (maxi - mini);
390  rc = (maxi - rgb.r) * maxmin;
391  gc = (maxi - rgb.g) * maxmin;
392  bc = (maxi - rgb.b) * maxmin;
393 
394  if (rgb.r == maxi)
395  hue = bc - gc;
396  else if (rgb.g == maxi)
397  hue = 2.0f + rc - bc;
398  else
399  hue = 4.0f + gc - rc;
400 
401  hue /= 6.0f;
402  if (hue < 0.0f)
403  hue = hue + 1.0f;
404 
405  hsl.r = hue;
406  hsl.g = sat;
407  }
408  hsl.b = light;
409 }
410 
411 /*
412  * RixXyzToRgb(xyz, rgb) converts a color in CIE xyz space into a RGB triple.
413  * The functions default to sRGB but other pre-defined color spaces are
414  * available.
415  * See RixColorSpace for a full list.
416  */
417 
418 // clang-format off
419 PRMAN_INLINE void
421 {
422  if (cs < 0 || cs >= k_numColorSpaces)
423  return;
424 
425  rgb.r = s_XYZtoRGB[cs][0] * xyz.r + s_XYZtoRGB[cs][1] * xyz.g + s_XYZtoRGB[cs][2] * xyz.b;
426  rgb.g = s_XYZtoRGB[cs][3] * xyz.r + s_XYZtoRGB[cs][4] * xyz.g + s_XYZtoRGB[cs][5] * xyz.b;
427  rgb.b = s_XYZtoRGB[cs][6] * xyz.r + s_XYZtoRGB[cs][7] * xyz.g + s_XYZtoRGB[cs][8] * xyz.b;
428 }
429 
430 PRMAN_INLINE void
432 {
433  if (cs < 0 || cs >= k_numColorSpaces)
434  return;
435 
436  xyz.r = s_RGBtoXYZ[cs][0] * rgb.r + s_RGBtoXYZ[cs][1] * rgb.g + s_RGBtoXYZ[cs][2] * rgb.b;
437  xyz.g = s_RGBtoXYZ[cs][3] * rgb.r + s_RGBtoXYZ[cs][4] * rgb.g + s_RGBtoXYZ[cs][5] * rgb.b;
438  xyz.b = s_RGBtoXYZ[cs][6] * rgb.r + s_RGBtoXYZ[cs][7] * rgb.g + s_RGBtoXYZ[cs][8] * rgb.b;
439 }
440 
451 RixInputRange(const RtFloat& f, const RtFloat& min, const RtFloat& max)
452 {
453  if (min == 0.f && max == 1.f)
454  return f;
455  if (min == max)
456  return ((f < min)? 0.f : 1.f);
457  return ((f - min) / (max - min));
458 }
459 
470 RixInputRange(const RtColorRGB& rgb, const RtFloat& min, const RtFloat& max)
471 {
472  RtColorRGB result;
473  for (int i=0; i<3; i++)
474  result[i] = RixInputRange(rgb[i], min, max);
475  return result;
476 }
477 
489 template <typename T>
491 RixInputRange(const RtColorRGB& rgb, const T& min, const T& max)
492 {
493  RtColorRGB result;
494  for (int i=0; i<3; i++)
495  result[i] = RixInputRange(rgb[i], min[i], max[i]);
496  return result;
497 }
498 
509 RixOutputRange(const RtFloat& f, const RtFloat& min, const RtFloat& max)
510 {
511  if (min == 0.f && max == 1.f)
512  return f;
513  return ((max - min) * f + min);
514 }
515 
526 RixOutputRange(const RtColorRGB& rgb, const RtFloat& min, const RtFloat& max)
527 {
528  RtColorRGB result;
529  for (int i=0; i<3; i++)
530  result[i] = RixOutputRange(rgb[i], min, max);
531  return result;
532 }
533 
545 template <typename T>
547 RixOutputRange(const RtColorRGB& rgb, const T& min, const T& max)
548 {
549  RtColorRGB result;
550  for (int i=0; i<3; i++)
551  result[i] = RixOutputRange(rgb[i], min[i], max[i]);
552  return result;
553 }
554 
564 RixExposure(RtFloat const& f, RtFloat const& e)
565 {
566  if (e != 0.0f)
567  return (f * powf(2.f, e));
568  return f;
569 }
570 
580 RixExposure(const RtColorRGB& rgb, const RtFloat& e)
581 {
582  RtColorRGB result = rgb;
583  if (e != 0.0f)
584  {
585  RtFloat exposure = powf(2.f, e);
586  result[0] *= exposure;
587  result[1] *= exposure;
588  result[2] *= exposure;
589  }
590  return result;
591 }
592 
603 template <typename T>
605 RixExposure(const RtColorRGB& rgb, const T& e)
606 {
607  RtColorRGB result;
608  result.r = RixExposure(rgb[0], e[0]);
609  result.g = RixExposure(rgb[1], e[1]);
610  result.b = RixExposure(rgb[2], e[2]);
611  return result;
612 }
613 
623 RixGamma(const RtFloat& f, const RtFloat& g)
624 {
625  if (g != 1.0f)
626  return powf(RixMax(f, 0.f), 1.f / RixMax(g, 1e-5f));
627  return f;
628 }
629 
639 RixGamma(const RtColorRGB& rgb, const RtFloat& g)
640 {
641  RtColorRGB result = rgb;
642  if (g != 1.0f)
643  {
644  RtFloat safe_g = 1.f/RixMax(g, 1e-5f);
645  result[0] = powf(rgb[0], safe_g);
646  result[1] = powf(rgb[1], safe_g);
647  result[2] = powf(rgb[2], safe_g);
648  }
649  return result;
650 }
651 
662 template <typename T>
664 RixGamma(const RtColorRGB& rgb, const T& g)
665 {
666  RtColorRGB result;
667  result[0] = RixGamma(rgb[0], g[0]);
668  result[1] = RixGamma(rgb[1], g[1]);
669  result[2] = RixGamma(rgb[2], g[2]);
670  return result;
671 }
672 
683 RixContrast(RtFloat f, RtFloat contrast, RtFloat pivot)
684 {
685  if (contrast == 0.f || f == pivot)
686  {
687  return f;
688  }
689 
690  RtFloat result = f;
691  RtFloat C = (RixClamp(contrast, -1.f, 1.f) * 0.5f) + 0.5f;
692  C = RixMin( C, 0.999f );
693  RtFloat power = logf(1.0f - C) / F_LOGDOTFIVE;
694  if ( f < pivot )
695  {
696  result = f / pivot;
697  result = powf(result, power);
698  result *= pivot;
699  }
700  else
701  {
702  result = (f - pivot) / (1.0f - pivot);
703  result = 1.0f - powf(1.0f - result, power);
704  result *= (1.0f - pivot) + pivot;
705  }
706  return result;
707 }
708 
720 template <typename T>
722 RixContrast(const RtColorRGB& rgb, const T& contrast, const T& pivot)
723 {
724  RtColorRGB result;
725  for (int i=0; i<3; i++)
726  result[i] = RixContrast(rgb[i], contrast[i], pivot[i]);
727  return result;
728 }
729 
742  const RtFloat& hue, const RtFloat& sat, const RtFloat& val)
743 {
744  RtColorRGB tmp, result;
745  RixRgbToHsv(rgb, tmp);
746  tmp[0] = RixFractional(tmp[0] + hue);
747  tmp[1] = RixClamp(tmp[1] * sat, 0.f, 1.f);
748  tmp[2] = RixClamp(tmp[2] * val, 0.f, 1.f);
749  RixHsvToRgb(tmp, result);
750  return result;
751 }
752 
764 template <typename T>
766 RixHsvCorrect(const RtColorRGB& rgb, const T& hsv)
767 {
768  RtColorRGB tmp, result;
769  RixRgbToHsv(rgb, tmp);
770  tmp[0] = RixFractional(tmp[0] + hsv[0]);
771  tmp[1] = RixClamp(tmp[1] * hsv[1], 0.f, 1.f);
772  tmp[2] = RixClamp(tmp[2] * hsv[2], 0.f, 1.f);
773  RixHsvToRgb(tmp, result);
774  return result;
775 }
776 
787 template <typename T>
789 RixHslCorrect(const RtColorRGB& rgb, const T& hsl)
790 {
791  RtColorRGB tmp, result;
792  RixRgbToHsl(rgb, tmp);
793  tmp[0] = RixFractional(tmp[0] + hsl[0]);
794  tmp[1] = RixClamp(tmp[1] * hsl[1], 0.f, 1.f);
795  tmp[2] = RixClamp(tmp[2] * hsl[2], 0.f, 1.f);
796  RixHslToRgb(tmp, result);
797  return result;
798 }
799 
811 template <typename T>
813 RixColorClamp(const RtColorRGB& rgb, const T& min, const T& max)
814 {
815  RtColorRGB result;
816  for (int i=0; i<3; i++)
817  result[i] = RixClamp(rgb[i], min[i], max[i]);
818  return result;
819 }
820 
833 RixSaturation(const RtColorRGB& rgb, const float saturation)
834 {
835  RtColorRGB result = rgb;
836  if (saturation != 1.f)
837  {
838  float middleGrey = (1.f - RixMax(0.f, saturation)) * rgb.Luminance();
839  result.r = RixMax(0.f, middleGrey + saturation * rgb.r);
840  result.g = RixMax(0.f, middleGrey + saturation * rgb.g);
841  result.b = RixMax(0.f, middleGrey + saturation * rgb.b);
842  }
843  return result;
844 }
845 
855 PRMAN_INLINE void
856 RixSaturation(RtColorRGB& rgb, const float saturation)
857 {
858  if (saturation != 1.f)
859  {
860  float middleGrey = (1.f - RixMax(0.f, saturation)) * rgb.Luminance();
861  rgb.r = RixMax(0.f, middleGrey + saturation * rgb.r);
862  rgb.g = RixMax(0.f, middleGrey + saturation * rgb.g);
863  rgb.b = RixMax(0.f, middleGrey + saturation * rgb.b);
864  }
865 }
866 
867 
868 // clang-format on
869 
870 #endif // RixColorUtils_h
PRMAN_INLINE RtColorRGB RixHsvCorrect(const RtColorRGB &rgb, const RtFloat &hue, const RtFloat &sat, const RtFloat &val)
HSV color correction.
pxrcore::ColorRGB RtColorRGB
#define IFLOOR(x)
PRMAN_INLINE float RixMax(float x, float y)
PRMAN_INLINE RtColorRGB RixSaturation(const RtColorRGB &rgb, const float saturation)
Return the saturation-adjusted color.
PRMAN_INLINE float RixFractional(float x)
float RtFloat
Definition: ri.h:54
PRMAN_INLINE RtColorRGB RixColorClamp(const RtColorRGB &rgb, const T &min, const T &max)
Clamp color : this an extensions of RixClamp.
PRMAN_INLINE void RixRgbToHsl(RtColorRGB const &rgb, RtColorRGB &hsl)
PRMAN_INLINE void RixXyzToRgb(RtColorRGB const &xyz, RtColorRGB &rgb, RixColorSpace cs=k_sRGB)
PRMAN_INLINE float RixClamp(float x, float min, float max)
PRMAN_INLINE void RixHslToRgb(RtColorRGB const &hsl, RtColorRGB &rgb)
PRMAN_INLINE RtFloat RixGamma(const RtFloat &f, const RtFloat &g)
Float gamma correction.
PRMAN_INLINE RtFloat RixContrast(RtFloat f, RtFloat contrast, RtFloat pivot)
Contrast float function.
#define F_LOGDOTFIVE
Definition: RixColorUtils.h:43
PRMAN_INLINE RtFloat RixExposure(RtFloat const &f, RtFloat const &e)
Float exposure function.
RixColorSpace
Definition: RixColorUtils.h:46
PRMAN_INLINE RtColorRGB RixHslCorrect(const RtColorRGB &rgb, const T &hsl)
HSL color correction.
PRMAN_INLINE float RixMin(float x, float y)
#define PRMAN_INLINE
Definition: prmanapi.h:86
PRMAN_INLINE RtFloat RixOutputRange(const RtFloat &f, const RtFloat &min, const RtFloat &max)
Remap a float from [0.0, 1.0] to [min, max].
PRMAN_INLINE void RixHsvToRgb(RtColorRGB const &hsv, RtColorRGB &rgb)
PRMAN_INLINE float rixValue(float n1, float n2, float hue)
PRMAN_INLINE RtFloat RixInputRange(const RtFloat &f, const RtFloat &min, const RtFloat &max)
Remap [min, max] to [0.0 to 1.0].
PRMAN_INLINE void RixRgbToHsv(RtColorRGB const &rgb, RtColorRGB &hsv)
PRMAN_INLINE void RixRgbToXyz(RtColorRGB const &rgb, RtColorRGB &xyz, RixColorSpace cs=k_sRGB)