ColorManagement.js 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  1. import { SRGBColorSpace, LinearSRGBColorSpace, DisplayP3ColorSpace, LinearDisplayP3ColorSpace, Rec709Primaries, P3Primaries, SRGBTransfer, LinearTransfer, NoColorSpace, } from '../constants.js';
  2. import { Matrix3 } from './Matrix3.js';
  3. /**
  4. * Matrices converting P3 <-> Rec. 709 primaries, without gamut mapping
  5. * or clipping. Based on W3C specifications for sRGB and Display P3,
  6. * and ICC specifications for the D50 connection space. Values in/out
  7. * are _linear_ sRGB and _linear_ Display P3.
  8. *
  9. * Note that both sRGB and Display P3 use the sRGB transfer functions.
  10. *
  11. * Reference:
  12. * - http://www.russellcottrell.com/photo/matrixCalculator.htm
  13. */
  14. const LINEAR_SRGB_TO_LINEAR_DISPLAY_P3 = /*@__PURE__*/ new Matrix3().set(
  15. 0.8224621, 0.177538, 0.0,
  16. 0.0331941, 0.9668058, 0.0,
  17. 0.0170827, 0.0723974, 0.9105199,
  18. );
  19. const LINEAR_DISPLAY_P3_TO_LINEAR_SRGB = /*@__PURE__*/ new Matrix3().set(
  20. 1.2249401, - 0.2249404, 0.0,
  21. - 0.0420569, 1.0420571, 0.0,
  22. - 0.0196376, - 0.0786361, 1.0982735
  23. );
  24. /**
  25. * Defines supported color spaces by transfer function and primaries,
  26. * and provides conversions to/from the Linear-sRGB reference space.
  27. */
  28. const COLOR_SPACES = {
  29. [ LinearSRGBColorSpace ]: {
  30. transfer: LinearTransfer,
  31. primaries: Rec709Primaries,
  32. toReference: ( color ) => color,
  33. fromReference: ( color ) => color,
  34. },
  35. [ SRGBColorSpace ]: {
  36. transfer: SRGBTransfer,
  37. primaries: Rec709Primaries,
  38. toReference: ( color ) => color.convertSRGBToLinear(),
  39. fromReference: ( color ) => color.convertLinearToSRGB(),
  40. },
  41. [ LinearDisplayP3ColorSpace ]: {
  42. transfer: LinearTransfer,
  43. primaries: P3Primaries,
  44. toReference: ( color ) => color.applyMatrix3( LINEAR_DISPLAY_P3_TO_LINEAR_SRGB ),
  45. fromReference: ( color ) => color.applyMatrix3( LINEAR_SRGB_TO_LINEAR_DISPLAY_P3 ),
  46. },
  47. [ DisplayP3ColorSpace ]: {
  48. transfer: SRGBTransfer,
  49. primaries: P3Primaries,
  50. toReference: ( color ) => color.convertSRGBToLinear().applyMatrix3( LINEAR_DISPLAY_P3_TO_LINEAR_SRGB ),
  51. fromReference: ( color ) => color.applyMatrix3( LINEAR_SRGB_TO_LINEAR_DISPLAY_P3 ).convertLinearToSRGB(),
  52. },
  53. };
  54. const SUPPORTED_WORKING_COLOR_SPACES = new Set( [ LinearSRGBColorSpace, LinearDisplayP3ColorSpace ] );
  55. export const ColorManagement = {
  56. enabled: true,
  57. _workingColorSpace: LinearSRGBColorSpace,
  58. get workingColorSpace() {
  59. return this._workingColorSpace;
  60. },
  61. set workingColorSpace( colorSpace ) {
  62. if ( ! SUPPORTED_WORKING_COLOR_SPACES.has( colorSpace ) ) {
  63. throw new Error( `Unsupported working color space, "${ colorSpace }".` );
  64. }
  65. this._workingColorSpace = colorSpace;
  66. },
  67. convert: function ( color, sourceColorSpace, targetColorSpace ) {
  68. if ( this.enabled === false || sourceColorSpace === targetColorSpace || ! sourceColorSpace || ! targetColorSpace ) {
  69. return color;
  70. }
  71. const sourceToReference = COLOR_SPACES[ sourceColorSpace ].toReference;
  72. const targetFromReference = COLOR_SPACES[ targetColorSpace ].fromReference;
  73. return targetFromReference( sourceToReference( color ) );
  74. },
  75. fromWorkingColorSpace: function ( color, targetColorSpace ) {
  76. return this.convert( color, this._workingColorSpace, targetColorSpace );
  77. },
  78. toWorkingColorSpace: function ( color, sourceColorSpace ) {
  79. return this.convert( color, sourceColorSpace, this._workingColorSpace );
  80. },
  81. getPrimaries: function ( colorSpace ) {
  82. return COLOR_SPACES[ colorSpace ].primaries;
  83. },
  84. getTransfer: function ( colorSpace ) {
  85. if ( colorSpace === NoColorSpace ) return LinearTransfer;
  86. return COLOR_SPACES[ colorSpace ].transfer;
  87. },
  88. };
  89. export function SRGBToLinear( c ) {
  90. return ( c < 0.04045 ) ? c * 0.0773993808 : Math.pow( c * 0.9478672986 + 0.0521327014, 2.4 );
  91. }
  92. export function LinearToSRGB( c ) {
  93. return ( c < 0.0031308 ) ? c * 12.92 : 1.055 * ( Math.pow( c, 0.41666 ) ) - 0.055;
  94. }
粤ICP备19079148号