color_space.inl 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  1. /// @ref gtx_color_space
  2. namespace glm
  3. {
  4. template<typename T, qualifier Q>
  5. GLM_FUNC_QUALIFIER vec<3, T, Q> rgbColor(const vec<3, T, Q>& hsvColor)
  6. {
  7. vec<3, T, Q> hsv = hsvColor;
  8. vec<3, T, Q> rgbColor;
  9. if(hsv.y == static_cast<T>(0))
  10. // achromatic (grey)
  11. rgbColor = vec<3, T, Q>(hsv.z);
  12. else
  13. {
  14. T sector = floor(hsv.x * (T(1) / T(60)));
  15. T frac = (hsv.x * (T(1) / T(60))) - sector;
  16. // factorial part of h
  17. T o = hsv.z * (T(1) - hsv.y);
  18. T p = hsv.z * (T(1) - hsv.y * frac);
  19. T q = hsv.z * (T(1) - hsv.y * (T(1) - frac));
  20. switch(int(sector))
  21. {
  22. default:
  23. case 0:
  24. rgbColor.r = hsv.z;
  25. rgbColor.g = q;
  26. rgbColor.b = o;
  27. break;
  28. case 1:
  29. rgbColor.r = p;
  30. rgbColor.g = hsv.z;
  31. rgbColor.b = o;
  32. break;
  33. case 2:
  34. rgbColor.r = o;
  35. rgbColor.g = hsv.z;
  36. rgbColor.b = q;
  37. break;
  38. case 3:
  39. rgbColor.r = o;
  40. rgbColor.g = p;
  41. rgbColor.b = hsv.z;
  42. break;
  43. case 4:
  44. rgbColor.r = q;
  45. rgbColor.g = o;
  46. rgbColor.b = hsv.z;
  47. break;
  48. case 5:
  49. rgbColor.r = hsv.z;
  50. rgbColor.g = o;
  51. rgbColor.b = p;
  52. break;
  53. }
  54. }
  55. return rgbColor;
  56. }
  57. template<typename T, qualifier Q>
  58. GLM_FUNC_QUALIFIER vec<3, T, Q> hsvColor(const vec<3, T, Q>& rgbColor)
  59. {
  60. vec<3, T, Q> hsv = rgbColor;
  61. float Min = min(min(rgbColor.r, rgbColor.g), rgbColor.b);
  62. float Max = max(max(rgbColor.r, rgbColor.g), rgbColor.b);
  63. float Delta = Max - Min;
  64. hsv.z = Max;
  65. if(Max != static_cast<T>(0))
  66. {
  67. hsv.y = Delta / hsv.z;
  68. T h = static_cast<T>(0);
  69. if(rgbColor.r == Max)
  70. // between yellow & magenta
  71. h = static_cast<T>(0) + T(60) * (rgbColor.g - rgbColor.b) / Delta;
  72. else if(rgbColor.g == Max)
  73. // between cyan & yellow
  74. h = static_cast<T>(120) + T(60) * (rgbColor.b - rgbColor.r) / Delta;
  75. else
  76. // between magenta & cyan
  77. h = static_cast<T>(240) + T(60) * (rgbColor.r - rgbColor.g) / Delta;
  78. if(h < T(0))
  79. hsv.x = h + T(360);
  80. else
  81. hsv.x = h;
  82. }
  83. else
  84. {
  85. // If r = g = b = 0 then s = 0, h is undefined
  86. hsv.y = static_cast<T>(0);
  87. hsv.x = static_cast<T>(0);
  88. }
  89. return hsv;
  90. }
  91. template<typename T>
  92. GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> saturation(T const s)
  93. {
  94. vec<3, T, defaultp> rgbw = vec<3, T, defaultp>(T(0.2126), T(0.7152), T(0.0722));
  95. vec<3, T, defaultp> const col((T(1) - s) * rgbw);
  96. mat<4, 4, T, defaultp> result(T(1));
  97. result[0][0] = col.x + s;
  98. result[0][1] = col.x;
  99. result[0][2] = col.x;
  100. result[1][0] = col.y;
  101. result[1][1] = col.y + s;
  102. result[1][2] = col.y;
  103. result[2][0] = col.z;
  104. result[2][1] = col.z;
  105. result[2][2] = col.z + s;
  106. return result;
  107. }
  108. template<typename T, qualifier Q>
  109. GLM_FUNC_QUALIFIER vec<3, T, Q> saturation(const T s, const vec<3, T, Q>& color)
  110. {
  111. return vec<3, T, Q>(saturation(s) * vec<4, T, Q>(color, T(0)));
  112. }
  113. template<typename T, qualifier Q>
  114. GLM_FUNC_QUALIFIER vec<4, T, Q> saturation(const T s, const vec<4, T, Q>& color)
  115. {
  116. return saturation(s) * color;
  117. }
  118. template<typename T, qualifier Q>
  119. GLM_FUNC_QUALIFIER T luminosity(const vec<3, T, Q>& color)
  120. {
  121. const vec<3, T, Q> tmp = vec<3, T, Q>(0.33, 0.59, 0.11);
  122. return dot(color, tmp);
  123. }
  124. }//namespace glm