|
|
@@ -1,182 +1,190 @@
|
|
|
import { SRGBColorSpace, LinearSRGBColorSpace, SRGBTransfer, LinearTransfer, NoColorSpace } from '../constants.js';
|
|
|
import { Matrix3 } from './Matrix3.js';
|
|
|
|
|
|
-export const ColorManagement = {
|
|
|
-
|
|
|
- enabled: true,
|
|
|
-
|
|
|
- workingColorSpace: LinearSRGBColorSpace,
|
|
|
-
|
|
|
- /**
|
|
|
- * Implementations of supported color spaces.
|
|
|
- *
|
|
|
- * Required:
|
|
|
- * - primaries: chromaticity coordinates [ rx ry gx gy bx by ]
|
|
|
- * - whitePoint: reference white [ x y ]
|
|
|
- * - transfer: transfer function (pre-defined)
|
|
|
- * - toXYZ: Matrix3 RGB to XYZ transform
|
|
|
- * - fromXYZ: Matrix3 XYZ to RGB transform
|
|
|
- * - luminanceCoefficients: RGB luminance coefficients
|
|
|
- *
|
|
|
- * Optional:
|
|
|
- * - outputColorSpaceConfig: { drawingBufferColorSpace: ColorSpace }
|
|
|
- * - workingColorSpaceConfig: { unpackColorSpace: ColorSpace }
|
|
|
- *
|
|
|
- * Reference:
|
|
|
- * - https://www.russellcottrell.com/photo/matrixCalculator.htm
|
|
|
- */
|
|
|
- spaces: {},
|
|
|
+const LINEAR_REC709_TO_XYZ = /*@__PURE__*/ new Matrix3().set(
|
|
|
+ 0.4123908, 0.3575843, 0.1804808,
|
|
|
+ 0.2126390, 0.7151687, 0.0721923,
|
|
|
+ 0.0193308, 0.1191948, 0.9505322
|
|
|
+);
|
|
|
|
|
|
- convert: function ( color, sourceColorSpace, targetColorSpace ) {
|
|
|
+const XYZ_TO_LINEAR_REC709 = /*@__PURE__*/ new Matrix3().set(
|
|
|
+ 3.2409699, - 1.5373832, - 0.4986108,
|
|
|
+ - 0.9692436, 1.8759675, 0.0415551,
|
|
|
+ 0.0556301, - 0.2039770, 1.0569715
|
|
|
+);
|
|
|
|
|
|
- if ( this.enabled === false || sourceColorSpace === targetColorSpace || ! sourceColorSpace || ! targetColorSpace ) {
|
|
|
+function createColorManagement() {
|
|
|
|
|
|
- return color;
|
|
|
+ const ColorManagement = {
|
|
|
|
|
|
- }
|
|
|
+ enabled: true,
|
|
|
|
|
|
- if ( this.spaces[ sourceColorSpace ].transfer === SRGBTransfer ) {
|
|
|
+ workingColorSpace: LinearSRGBColorSpace,
|
|
|
|
|
|
- color.r = SRGBToLinear( color.r );
|
|
|
- color.g = SRGBToLinear( color.g );
|
|
|
- color.b = SRGBToLinear( color.b );
|
|
|
+ /**
|
|
|
+ * Implementations of supported color spaces.
|
|
|
+ *
|
|
|
+ * Required:
|
|
|
+ * - primaries: chromaticity coordinates [ rx ry gx gy bx by ]
|
|
|
+ * - whitePoint: reference white [ x y ]
|
|
|
+ * - transfer: transfer function (pre-defined)
|
|
|
+ * - toXYZ: Matrix3 RGB to XYZ transform
|
|
|
+ * - fromXYZ: Matrix3 XYZ to RGB transform
|
|
|
+ * - luminanceCoefficients: RGB luminance coefficients
|
|
|
+ *
|
|
|
+ * Optional:
|
|
|
+ * - outputColorSpaceConfig: { drawingBufferColorSpace: ColorSpace }
|
|
|
+ * - workingColorSpaceConfig: { unpackColorSpace: ColorSpace }
|
|
|
+ *
|
|
|
+ * Reference:
|
|
|
+ * - https://www.russellcottrell.com/photo/matrixCalculator.htm
|
|
|
+ */
|
|
|
+ spaces: {},
|
|
|
|
|
|
- }
|
|
|
+ convert: function ( color, sourceColorSpace, targetColorSpace ) {
|
|
|
|
|
|
- if ( this.spaces[ sourceColorSpace ].primaries !== this.spaces[ targetColorSpace ].primaries ) {
|
|
|
+ if ( this.enabled === false || sourceColorSpace === targetColorSpace || ! sourceColorSpace || ! targetColorSpace ) {
|
|
|
|
|
|
- color.applyMatrix3( this.spaces[ sourceColorSpace ].toXYZ );
|
|
|
- color.applyMatrix3( this.spaces[ targetColorSpace ].fromXYZ );
|
|
|
+ return color;
|
|
|
|
|
|
- }
|
|
|
+ }
|
|
|
|
|
|
- if ( this.spaces[ targetColorSpace ].transfer === SRGBTransfer ) {
|
|
|
+ if ( this.spaces[ sourceColorSpace ].transfer === SRGBTransfer ) {
|
|
|
|
|
|
- color.r = LinearToSRGB( color.r );
|
|
|
- color.g = LinearToSRGB( color.g );
|
|
|
- color.b = LinearToSRGB( color.b );
|
|
|
+ color.r = SRGBToLinear( color.r );
|
|
|
+ color.g = SRGBToLinear( color.g );
|
|
|
+ color.b = SRGBToLinear( color.b );
|
|
|
|
|
|
- }
|
|
|
+ }
|
|
|
|
|
|
- return color;
|
|
|
+ if ( this.spaces[ sourceColorSpace ].primaries !== this.spaces[ targetColorSpace ].primaries ) {
|
|
|
|
|
|
- },
|
|
|
+ color.applyMatrix3( this.spaces[ sourceColorSpace ].toXYZ );
|
|
|
+ color.applyMatrix3( this.spaces[ targetColorSpace ].fromXYZ );
|
|
|
|
|
|
- fromWorkingColorSpace: function ( color, targetColorSpace ) {
|
|
|
+ }
|
|
|
|
|
|
- return this.convert( color, this.workingColorSpace, targetColorSpace );
|
|
|
+ if ( this.spaces[ targetColorSpace ].transfer === SRGBTransfer ) {
|
|
|
|
|
|
- },
|
|
|
+ color.r = LinearToSRGB( color.r );
|
|
|
+ color.g = LinearToSRGB( color.g );
|
|
|
+ color.b = LinearToSRGB( color.b );
|
|
|
|
|
|
- toWorkingColorSpace: function ( color, sourceColorSpace ) {
|
|
|
+ }
|
|
|
|
|
|
- return this.convert( color, sourceColorSpace, this.workingColorSpace );
|
|
|
+ return color;
|
|
|
|
|
|
- },
|
|
|
+ },
|
|
|
|
|
|
- getPrimaries: function ( colorSpace ) {
|
|
|
+ fromWorkingColorSpace: function ( color, targetColorSpace ) {
|
|
|
|
|
|
- return this.spaces[ colorSpace ].primaries;
|
|
|
+ return this.convert( color, this.workingColorSpace, targetColorSpace );
|
|
|
|
|
|
- },
|
|
|
+ },
|
|
|
|
|
|
- getTransfer: function ( colorSpace ) {
|
|
|
+ toWorkingColorSpace: function ( color, sourceColorSpace ) {
|
|
|
|
|
|
- if ( colorSpace === NoColorSpace ) return LinearTransfer;
|
|
|
+ return this.convert( color, sourceColorSpace, this.workingColorSpace );
|
|
|
|
|
|
- return this.spaces[ colorSpace ].transfer;
|
|
|
+ },
|
|
|
|
|
|
- },
|
|
|
+ getPrimaries: function ( colorSpace ) {
|
|
|
|
|
|
- getLuminanceCoefficients: function ( target, colorSpace = this.workingColorSpace ) {
|
|
|
+ return this.spaces[ colorSpace ].primaries;
|
|
|
|
|
|
- return target.fromArray( this.spaces[ colorSpace ].luminanceCoefficients );
|
|
|
+ },
|
|
|
|
|
|
- },
|
|
|
+ getTransfer: function ( colorSpace ) {
|
|
|
|
|
|
- define: function ( colorSpaces ) {
|
|
|
+ if ( colorSpace === NoColorSpace ) return LinearTransfer;
|
|
|
|
|
|
- Object.assign( this.spaces, colorSpaces );
|
|
|
+ return this.spaces[ colorSpace ].transfer;
|
|
|
|
|
|
- },
|
|
|
+ },
|
|
|
|
|
|
- // Internal APIs
|
|
|
+ getLuminanceCoefficients: function ( target, colorSpace = this.workingColorSpace ) {
|
|
|
|
|
|
- _getMatrix: function ( targetMatrix, sourceColorSpace, targetColorSpace ) {
|
|
|
+ return target.fromArray( this.spaces[ colorSpace ].luminanceCoefficients );
|
|
|
|
|
|
- return targetMatrix
|
|
|
- .copy( this.spaces[ sourceColorSpace ].toXYZ )
|
|
|
- .multiply( this.spaces[ targetColorSpace ].fromXYZ );
|
|
|
+ },
|
|
|
|
|
|
- },
|
|
|
+ define: function ( colorSpaces ) {
|
|
|
|
|
|
- _getDrawingBufferColorSpace: function ( colorSpace ) {
|
|
|
+ Object.assign( this.spaces, colorSpaces );
|
|
|
|
|
|
- return this.spaces[ colorSpace ].outputColorSpaceConfig.drawingBufferColorSpace;
|
|
|
+ },
|
|
|
|
|
|
- },
|
|
|
+ // Internal APIs
|
|
|
|
|
|
- _getUnpackColorSpace: function ( colorSpace = this.workingColorSpace ) {
|
|
|
+ _getMatrix: function ( targetMatrix, sourceColorSpace, targetColorSpace ) {
|
|
|
|
|
|
- return this.spaces[ colorSpace ].workingColorSpaceConfig.unpackColorSpace;
|
|
|
+ return targetMatrix
|
|
|
+ .copy( this.spaces[ sourceColorSpace ].toXYZ )
|
|
|
+ .multiply( this.spaces[ targetColorSpace ].fromXYZ );
|
|
|
|
|
|
- }
|
|
|
+ },
|
|
|
|
|
|
-};
|
|
|
+ _getDrawingBufferColorSpace: function ( colorSpace ) {
|
|
|
|
|
|
-export function SRGBToLinear( c ) {
|
|
|
+ return this.spaces[ colorSpace ].outputColorSpaceConfig.drawingBufferColorSpace;
|
|
|
|
|
|
- return ( c < 0.04045 ) ? c * 0.0773993808 : Math.pow( c * 0.9478672986 + 0.0521327014, 2.4 );
|
|
|
+ },
|
|
|
|
|
|
-}
|
|
|
+ _getUnpackColorSpace: function ( colorSpace = this.workingColorSpace ) {
|
|
|
|
|
|
-export function LinearToSRGB( c ) {
|
|
|
+ return this.spaces[ colorSpace ].workingColorSpaceConfig.unpackColorSpace;
|
|
|
|
|
|
- return ( c < 0.0031308 ) ? c * 12.92 : 1.055 * ( Math.pow( c, 0.41666 ) ) - 0.055;
|
|
|
+ }
|
|
|
+
|
|
|
+ };
|
|
|
+
|
|
|
+ /******************************************************************************
|
|
|
+ * sRGB definitions
|
|
|
+ */
|
|
|
+
|
|
|
+ const REC709_PRIMARIES = [ 0.640, 0.330, 0.300, 0.600, 0.150, 0.060 ];
|
|
|
+ const REC709_LUMINANCE_COEFFICIENTS = [ 0.2126, 0.7152, 0.0722 ];
|
|
|
+ const D65 = [ 0.3127, 0.3290 ];
|
|
|
+
|
|
|
+ ColorManagement.define( {
|
|
|
+
|
|
|
+ [ LinearSRGBColorSpace ]: {
|
|
|
+ primaries: REC709_PRIMARIES,
|
|
|
+ whitePoint: D65,
|
|
|
+ transfer: LinearTransfer,
|
|
|
+ toXYZ: LINEAR_REC709_TO_XYZ,
|
|
|
+ fromXYZ: XYZ_TO_LINEAR_REC709,
|
|
|
+ luminanceCoefficients: REC709_LUMINANCE_COEFFICIENTS,
|
|
|
+ workingColorSpaceConfig: { unpackColorSpace: SRGBColorSpace },
|
|
|
+ outputColorSpaceConfig: { drawingBufferColorSpace: SRGBColorSpace }
|
|
|
+ },
|
|
|
+
|
|
|
+ [ SRGBColorSpace ]: {
|
|
|
+ primaries: REC709_PRIMARIES,
|
|
|
+ whitePoint: D65,
|
|
|
+ transfer: SRGBTransfer,
|
|
|
+ toXYZ: LINEAR_REC709_TO_XYZ,
|
|
|
+ fromXYZ: XYZ_TO_LINEAR_REC709,
|
|
|
+ luminanceCoefficients: REC709_LUMINANCE_COEFFICIENTS,
|
|
|
+ outputColorSpaceConfig: { drawingBufferColorSpace: SRGBColorSpace }
|
|
|
+ },
|
|
|
+
|
|
|
+ } );
|
|
|
+
|
|
|
+ return ColorManagement;
|
|
|
|
|
|
}
|
|
|
|
|
|
-/******************************************************************************
|
|
|
- * sRGB definitions
|
|
|
- */
|
|
|
+export const ColorManagement = /*@__PURE__*/ createColorManagement();
|
|
|
|
|
|
-const REC709_PRIMARIES = [ 0.640, 0.330, 0.300, 0.600, 0.150, 0.060 ];
|
|
|
-const REC709_LUMINANCE_COEFFICIENTS = [ 0.2126, 0.7152, 0.0722 ];
|
|
|
-const D65 = [ 0.3127, 0.3290 ];
|
|
|
+export function SRGBToLinear( c ) {
|
|
|
|
|
|
-const LINEAR_REC709_TO_XYZ = /*@__PURE__*/ new Matrix3().set(
|
|
|
- 0.4123908, 0.3575843, 0.1804808,
|
|
|
- 0.2126390, 0.7151687, 0.0721923,
|
|
|
- 0.0193308, 0.1191948, 0.9505322
|
|
|
-);
|
|
|
+ return ( c < 0.04045 ) ? c * 0.0773993808 : Math.pow( c * 0.9478672986 + 0.0521327014, 2.4 );
|
|
|
|
|
|
-const XYZ_TO_LINEAR_REC709 = /*@__PURE__*/ new Matrix3().set(
|
|
|
- 3.2409699, - 1.5373832, - 0.4986108,
|
|
|
- - 0.9692436, 1.8759675, 0.0415551,
|
|
|
- 0.0556301, - 0.2039770, 1.0569715
|
|
|
-);
|
|
|
+}
|
|
|
|
|
|
-ColorManagement.define( {
|
|
|
-
|
|
|
- [ LinearSRGBColorSpace ]: {
|
|
|
- primaries: REC709_PRIMARIES,
|
|
|
- whitePoint: D65,
|
|
|
- transfer: LinearTransfer,
|
|
|
- toXYZ: LINEAR_REC709_TO_XYZ,
|
|
|
- fromXYZ: XYZ_TO_LINEAR_REC709,
|
|
|
- luminanceCoefficients: REC709_LUMINANCE_COEFFICIENTS,
|
|
|
- workingColorSpaceConfig: { unpackColorSpace: SRGBColorSpace },
|
|
|
- outputColorSpaceConfig: { drawingBufferColorSpace: SRGBColorSpace }
|
|
|
- },
|
|
|
-
|
|
|
- [ SRGBColorSpace ]: {
|
|
|
- primaries: REC709_PRIMARIES,
|
|
|
- whitePoint: D65,
|
|
|
- transfer: SRGBTransfer,
|
|
|
- toXYZ: LINEAR_REC709_TO_XYZ,
|
|
|
- fromXYZ: XYZ_TO_LINEAR_REC709,
|
|
|
- luminanceCoefficients: REC709_LUMINANCE_COEFFICIENTS,
|
|
|
- outputColorSpaceConfig: { drawingBufferColorSpace: SRGBColorSpace }
|
|
|
- },
|
|
|
-
|
|
|
-} );
|
|
|
+export function LinearToSRGB( c ) {
|
|
|
+
|
|
|
+ return ( c < 0.0031308 ) ? c * 12.92 : 1.055 * ( Math.pow( c, 0.41666 ) ) - 0.055;
|
|
|
+
|
|
|
+}
|