Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/constants.js
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,7 @@ export const NoColorSpace = '';
export const SRGBColorSpace = 'srgb';
export const LinearSRGBColorSpace = 'srgb-linear';
export const DisplayP3ColorSpace = 'display-p3';
export const LinearP3ColorSpace = 'p3-linear';

export const ZeroStencilOp = 0;
export const KeepStencilOp = 7680;
Expand Down
38 changes: 19 additions & 19 deletions src/math/ColorManagement.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { SRGBColorSpace, LinearSRGBColorSpace, DisplayP3ColorSpace, } from '../constants.js';
import { SRGBColorSpace, LinearSRGBColorSpace, DisplayP3ColorSpace, LinearP3ColorSpace } from '../constants.js';
import { Matrix3 } from './Matrix3.js';
import { Vector3 } from './Vector3.js';

Expand Down Expand Up @@ -27,50 +27,50 @@ export function LinearToSRGB( c ) {
* - http://www.russellcottrell.com/photo/matrixCalculator.htm
*/

const LINEAR_SRGB_TO_LINEAR_DISPLAY_P3 = new Matrix3().fromArray( [
const LINEAR_REC709_TO_LINEAR_P3 = 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 = new Matrix3().fromArray( [
const LINEAR_P3_TO_LINEAR_REC709 = new Matrix3().fromArray( [
1.2249401, - 0.0420569, - 0.0196376,
- 0.2249404, 1.0420571, - 0.0786361,
0.0000001, 0.0000000, 1.0982735
] );

const _vector = new Vector3();

function DisplayP3ToLinearSRGB( color ) {
function LinearP3ToLinearRec709( color ) {

color.convertSRGBToLinear();

_vector.set( color.r, color.g, color.b ).applyMatrix3( LINEAR_DISPLAY_P3_TO_LINEAR_SRGB );
_vector.set( color.r, color.g, color.b ).applyMatrix3( LINEAR_P3_TO_LINEAR_REC709 );

return color.setRGB( _vector.x, _vector.y, _vector.z );

}

function LinearSRGBToDisplayP3( color ) {
function LinearRec709ToLinearP3( color ) {

_vector.set( color.r, color.g, color.b ).applyMatrix3( LINEAR_SRGB_TO_LINEAR_DISPLAY_P3 );
_vector.set( color.r, color.g, color.b ).applyMatrix3( LINEAR_REC709_TO_LINEAR_P3 );

return color.setRGB( _vector.x, _vector.y, _vector.z ).convertLinearToSRGB();
return color.setRGB( _vector.x, _vector.y, _vector.z );

}

// Conversions from <source> to Linear-sRGB reference space.
const TO_LINEAR = {
const TO_REFERENCE = {
[ LinearSRGBColorSpace ]: ( color ) => color,
[ SRGBColorSpace ]: ( color ) => color.convertSRGBToLinear(),
[ DisplayP3ColorSpace ]: DisplayP3ToLinearSRGB,
[ LinearP3ColorSpace ]: ( color ) => LinearP3ToLinearRec709( color ),
[ DisplayP3ColorSpace ]: ( color ) => LinearP3ToLinearRec709( color.convertSRGBToLinear() ),
};

// Conversions to <target> from Linear-sRGB reference space.
const FROM_LINEAR = {
// Conversions from Linear-sRGB reference space to <target>.
const FROM_REFERENCE = {
[ LinearSRGBColorSpace ]: ( color ) => color,
[ SRGBColorSpace ]: ( color ) => color.convertLinearToSRGB(),
[ DisplayP3ColorSpace ]: LinearSRGBToDisplayP3,
[ LinearP3ColorSpace ]: ( color ) => LinearRec709ToLinearP3( color ),
[ DisplayP3ColorSpace ]: ( color ) => LinearRec709ToLinearP3( color ).convertLinearToSRGB(),
};

export const ColorManagement = {
Expand Down Expand Up @@ -113,16 +113,16 @@ export const ColorManagement = {

}

const sourceToLinear = TO_LINEAR[ sourceColorSpace ];
const targetFromLinear = FROM_LINEAR[ targetColorSpace ];
const sourceToReference = TO_REFERENCE[ sourceColorSpace ];
const referenceToTarget = FROM_REFERENCE[ targetColorSpace ];

if ( sourceToLinear === undefined || targetFromLinear === undefined ) {
if ( sourceToReference === undefined || referenceToTarget === undefined ) {

throw new Error( `Unsupported color space conversion, "${ sourceColorSpace }" to "${ targetColorSpace }".` );

}

return targetFromLinear( sourceToLinear( color ) );
return referenceToTarget( sourceToReference( color ) );

},

Expand Down
8 changes: 7 additions & 1 deletion test/unit/src/math/Color.tests.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { Color } from '../../../../src/math/Color.js';
import { ColorManagement } from '../../../../src/math/ColorManagement.js';
import { eps } from '../../utils/math-constants.js';
import { CONSOLE_LEVEL } from '../../utils/console-wrapper.js';
import { DisplayP3ColorSpace, SRGBColorSpace } from '../../../../src/constants.js';
import { DisplayP3ColorSpace, SRGBColorSpace, LinearP3ColorSpace } from '../../../../src/constants.js';

export default QUnit.module( 'Maths', () => {

Expand Down Expand Up @@ -308,6 +308,12 @@ export default QUnit.module( 'Maths', () => {
assert.equal( t.g.toFixed( 3 ), 0.637, 'g (display-p3)' );
assert.equal( t.b.toFixed( 3 ), 0.852, 'b (display-p3)' );

c.getRGB( t, LinearP3ColorSpace );

assert.equal( t.r.toFixed( 3 ), 0.657, 'r (p3-linear)' );
assert.equal( t.g.toFixed( 3 ), 0.364, 'g (p3-linear)' );
assert.equal( t.b.toFixed( 3 ), 0.696, 'b (p3-linear)' );

} );

QUnit.test( 'getStyle', ( assert ) => {
Expand Down