38 #ifndef RixColorUtils_h 39 #define RixColorUtils_h 43 #define F_LOGDOTFIVE (-0.30102999566f) 44 #define F_INVLOGDOTFIVE (-3.32192809489f) 62 static float s_RGBtoXYZ[][9] = {
64 { 0.4124564f, 0.3575761f, 0.1804375f,
65 0.2126729f, 0.7151522f, 0.0721750f,
66 0.0193339f, 0.1191920f, 0.9503041f
69 { 0.4123866f, 0.3575915f, 0.1804505f,
70 0.2126368f, 0.7151830f, 0.0721802f,
71 0.0193306f, 0.1191972f, 0.9503726f
74 { 0.6369535f, 0.1446192f, 0.1688559f,
75 0.2626983f, 0.6780088f, 0.0592929f,
76 0.0000000f, 0.0280731f, 1.0608272f
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
84 { 0.638008f, 0.214704f, 0.097744f,
85 0.291954f, 0.823841f, -0.115795f,
86 0.002798f, -0.067034f, 1.153294f
89 { 0.66245418f, 0.13400421f, 0.15618769f,
90 0.27222872f, 0.67408177f, 0.05368952f,
91 -0.00557465f, 0.00406073f, 1.0103391f
95 0.71603649f, 0.12968185f, 0.10471021f,
96 0.26125656f, 0.86963121f, -0.13088776f,
97 -0.00967617f, -0.23647866f, 1.3350552f,
100 { 1.909851f, -0.984623f, 0.058331f,
101 -0.532414f, 1.999082f, -0.118429f,
102 -0.288187f, -0.028307f, 0.897936f
108 static float s_XYZtoRGB[][9] = {
110 { 3.2404542f, -1.5371385f, -0.4985314f,
111 -0.9692660f, 1.8760108f, 0.0415560f,
112 0.0556434f, -0.2040259f, 1.0572252f
115 { 3.24100326f, -1.53739899f, -0.49861587f,
116 -0.96922426f, 1.87592999f, 0.04155422f,
117 0.05563942f, -0.2040112f, 1.05714897f
120 { 1.71666343f, -0.35567332f, -0.25336809f,
121 -0.66667384f, 1.61645574f, 0.0157683f,
122 0.01764248f, -0.04277698f, 0.94224328f
125 { 2.72539403f, -1.01800301f, -0.4401632f,
126 -0.79516803f, 1.68973205f, 0.02264719f,
127 0.04124189f, -0.08763902f, 1.10092938f
130 { 1.78906454f, -0.48253382f, -0.20007503f,
131 -0.63984874f, 1.3964001f, 0.19443223f,
132 -0.04153097f, 0.08233496f, 0.87886816f
135 { 1.64102338f, -0.32480329f, -0.2364247f,
136 -0.66366286f, 1.61533159f, 0.01675635f,
137 0.01172189f, -0.00828444f, 0.98839486f
141 1.48984566f, -0.2609007f, -0.14242914f,
142 -0.45817234f, 1.26164365f, 0.15962564f,
143 -0.07035813f, 0.22158431f, 0.77627493f
146 { 0.606937f, 0.298939f, 0.0f,
147 0.173509f, 0.586625f, 0.066099f,
148 0.200263f, 0.114436f, 1.115749f
159 #define IFLOOR(x) (((x) < 0.0f && (x) != (int)(x)) ? (int)x - 1 : (int)x) 169 h = h -
static_cast<float>(
static_cast<int>(h)) + (h < 0.0f ? 1.0f : 0.0f);
172 f = h -
static_cast<float>(i);
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)));
279 h = 1.0f - (v - rgb.g) / (v - x);
283 h = 5.0f + (v - rgb.b) / (v - x);
287 h = 3.0f - (v - rgb.b) / (v - x);
291 h = 1.0f + (v - rgb.r) / (v - x);
295 h = 3.0f + (v - rgb.g) / (v - x);
299 h = 5.0f - (v - rgb.r) / (v - x);
303 hsv.r = h * (1.0f / 6.0f);
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)
329 if (hue < (
float)0.66666667)
330 return (n1 + (n2 - n1) * ((
float)4.0 - hue * (
float)6.0));
346 rgb.r = rgb.g = rgb.b = l;
357 rgb.r =
rixValue(m1, m2, h + 0.33333333f);
359 rgb.b =
rixValue(m1, m2, h - 0.33333333f);
365 float maxi, mini, maxmin;
366 float rc, gc, bc, hue, sat, light;
370 mini = (rgb.r < rgb.b) ? rgb.r : rgb.b;
371 maxi = (rgb.g > rgb.b) ? rgb.g : rgb.b;
375 mini = (rgb.g < rgb.b) ? rgb.g : rgb.b;
376 maxi = (rgb.r > rgb.b) ? rgb.r : rgb.b;
378 light = (maxi + mini) / 2.0f;
381 hsl.r = hsl.g = 0.0f;
385 sat = (maxi - mini) / (maxi + mini);
387 sat = (maxi - mini) / (2.0f - maxi - mini);
389 maxmin = 1.0f / (maxi - mini);
390 rc = (maxi - rgb.r) * maxmin;
391 gc = (maxi - rgb.g) * maxmin;
392 bc = (maxi - rgb.b) * maxmin;
396 else if (rgb.g == maxi)
397 hue = 2.0f + rc - bc;
399 hue = 4.0f + gc - rc;
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;
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;
453 if (min == 0.f && max == 1.f)
456 return ((f < min)? 0.f : 1.f);
457 return ((f - min) / (max - min));
473 for (
int i=0; i<3; i++)
489 template <
typename T>
494 for (
int i=0; i<3; i++)
511 if (min == 0.f && max == 1.f)
513 return ((max - min) * f + min);
529 for (
int i=0; i<3; i++)
545 template <
typename T>
550 for (
int i=0; i<3; i++)
567 return (f * powf(2.f, e));
585 RtFloat exposure = powf(2.f, e);
586 result[0] *= exposure;
587 result[1] *= exposure;
588 result[2] *= exposure;
603 template <
typename T>
645 result[0] = powf(rgb[0], safe_g);
646 result[1] = powf(rgb[1], safe_g);
647 result[2] = powf(rgb[2], safe_g);
662 template <
typename T>
685 if (contrast == 0.f || f == pivot)
697 result = powf(result, power);
702 result = (f - pivot) / (1.0f - pivot);
703 result = 1.0f - powf(1.0f - result, power);
704 result *= (1.0f - pivot) + pivot;
720 template <
typename T>
725 for (
int i=0; i<3; i++)
726 result[i] =
RixContrast(rgb[i], contrast[i], pivot[i]);
747 tmp[1] =
RixClamp(tmp[1] * sat, 0.f, 1.f);
748 tmp[2] =
RixClamp(tmp[2] * val, 0.f, 1.f);
764 template <
typename T>
771 tmp[1] =
RixClamp(tmp[1] * hsv[1], 0.f, 1.f);
772 tmp[2] =
RixClamp(tmp[2] * hsv[2], 0.f, 1.f);
787 template <
typename T>
794 tmp[1] =
RixClamp(tmp[1] * hsl[1], 0.f, 1.f);
795 tmp[2] =
RixClamp(tmp[2] * hsl[2], 0.f, 1.f);
811 template <
typename T>
816 for (
int i=0; i<3; i++)
817 result[i] =
RixClamp(rgb[i], min[i], max[i]);
836 if (saturation != 1.f)
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);
858 if (saturation != 1.f)
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);
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
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)
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.
PRMAN_INLINE RtFloat RixExposure(RtFloat const &f, RtFloat const &e)
Float exposure function.
PRMAN_INLINE RtColorRGB RixHslCorrect(const RtColorRGB &rgb, const T &hsl)
HSL color correction.
PRMAN_INLINE float RixMin(float x, float y)
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)