three
Version:
JavaScript 3D library
134 lines (83 loc) • 3.48 kB
JavaScript
import { SRGBColorSpace, LinearSRGBColorSpace, DisplayP3ColorSpace, } from '../constants.js';
import { Matrix3 } from './Matrix3.js';
export function SRGBToLinear( c ) {
return ( c < 0.04045 ) ? c * 0.0773993808 : Math.pow( c * 0.9478672986 + 0.0521327014, 2.4 );
}
export function LinearToSRGB( c ) {
return ( c < 0.0031308 ) ? c * 12.92 : 1.055 * ( Math.pow( c, 0.41666 ) ) - 0.055;
}
/**
* Matrices converting P3 <-> Rec. 709 primaries, without gamut mapping
* or clipping. Based on W3C specifications for sRGB and Display P3,
* and ICC specifications for the D50 connection space. Values in/out
* are _linear_ sRGB and _linear_ Display P3.
*
* Note that both sRGB and Display P3 use the sRGB transfer functions.
*
* Reference:
* - http://www.russellcottrell.com/photo/matrixCalculator.htm
*/
const LINEAR_SRGB_TO_LINEAR_DISPLAY_P3 = /*@__PURE__*/ new Matrix3().fromArray( [
0.8224621, 0.0331941, 0.0170827,
0.1775380, 0.9668058, 0.0723974,
- 0.0000001, 0.0000001, 0.9105199
] );
const LINEAR_DISPLAY_P3_TO_LINEAR_SRGB = /*@__PURE__*/ new Matrix3().fromArray( [
1.2249401, - 0.0420569, - 0.0196376,
- 0.2249404, 1.0420571, - 0.0786361,
0.0000001, 0.0000000, 1.0982735
] );
function DisplayP3ToLinearSRGB( color ) {
// Display P3 uses the sRGB transfer functions
return color.convertSRGBToLinear().applyMatrix3( LINEAR_DISPLAY_P3_TO_LINEAR_SRGB );
}
function LinearSRGBToDisplayP3( color ) {
// Display P3 uses the sRGB transfer functions
return color.applyMatrix3( LINEAR_SRGB_TO_LINEAR_DISPLAY_P3 ).convertLinearToSRGB();
}
// Conversions from <source> to Linear-sRGB reference space.
const TO_LINEAR = {
[ LinearSRGBColorSpace ]: ( color ) => color,
[ SRGBColorSpace ]: ( color ) => color.convertSRGBToLinear(),
[ DisplayP3ColorSpace ]: DisplayP3ToLinearSRGB,
};
// Conversions to <target> from Linear-sRGB reference space.
const FROM_LINEAR = {
[ LinearSRGBColorSpace ]: ( color ) => color,
[ SRGBColorSpace ]: ( color ) => color.convertLinearToSRGB(),
[ DisplayP3ColorSpace ]: LinearSRGBToDisplayP3,
};
export const ColorManagement = {
enabled: true,
get legacyMode() {
console.warn( 'THREE.ColorManagement: .legacyMode=false renamed to .enabled=true in r150.' );
return ! this.enabled;
},
set legacyMode( legacyMode ) {
console.warn( 'THREE.ColorManagement: .legacyMode=false renamed to .enabled=true in r150.' );
this.enabled = ! legacyMode;
},
get workingColorSpace() {
return LinearSRGBColorSpace;
},
set workingColorSpace( colorSpace ) {
console.warn( 'THREE.ColorManagement: .workingColorSpace is readonly.' );
},
convert: function ( color, sourceColorSpace, targetColorSpace ) {
if ( this.enabled === false || sourceColorSpace === targetColorSpace || ! sourceColorSpace || ! targetColorSpace ) {
return color;
}
const sourceToLinear = TO_LINEAR[ sourceColorSpace ];
const targetFromLinear = FROM_LINEAR[ targetColorSpace ];
if ( sourceToLinear === undefined || targetFromLinear === undefined ) {
throw new Error( `Unsupported color space conversion, "${ sourceColorSpace }" to "${ targetColorSpace }".` );
}
return targetFromLinear( sourceToLinear( color ) );
},
fromWorkingColorSpace: function ( color, targetColorSpace ) {
return this.convert( color, this.workingColorSpace, targetColorSpace );
},
toWorkingColorSpace: function ( color, sourceColorSpace ) {
return this.convert( color, sourceColorSpace, this.workingColorSpace );
},
};