Skip to content

Commit cb29f6f

Browse files
authored
TSL: Support defined color spaces in ColorSpaceNode (#29694)
* TSL: Support defined color spaces in ColorSpaceNode * TSL: Add .convertColorNode() * fix circular dependency * remove chaining method ---------
1 parent 84183ce commit cb29f6f

File tree

6 files changed

+32
-74
lines changed

6 files changed

+32
-74
lines changed

src/math/ColorManagement.js

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,6 @@ export const ColorManagement = {
124124

125125
};
126126

127-
128127
export function SRGBToLinear( c ) {
129128

130129
return ( c < 0.04045 ) ? c * 0.0773993808 : Math.pow( c * 0.9478672986 + 0.0521327014, 2.4 );

src/nodes/display/ColorSpaceFunctions.js

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { mix } from '../math/MathNode.js';
2-
import { Fn } from '../tsl/TSLBase.js';
2+
import { Fn } from '../tsl/TSLCore.js';
33

4-
export const sRGBToLinearSRGB = /*@__PURE__*/ Fn( ( [ color ] ) => {
4+
export const sRGBTransferEOTF = /*@__PURE__*/ Fn( ( [ color ] ) => {
55

66
const a = color.mul( 0.9478672986 ).add( 0.0521327014 ).pow( 2.4 );
77
const b = color.mul( 0.0773993808 );
@@ -12,14 +12,14 @@ export const sRGBToLinearSRGB = /*@__PURE__*/ Fn( ( [ color ] ) => {
1212
return rgbResult;
1313

1414
} ).setLayout( {
15-
name: 'sRGBToLinearSRGB',
15+
name: 'sRGBTransferEOTF',
1616
type: 'vec3',
1717
inputs: [
1818
{ name: 'color', type: 'vec3' }
1919
]
2020
} );
2121

22-
export const linearSRGBTosRGB = /*@__PURE__*/ Fn( ( [ color ] ) => {
22+
export const sRGBTransferOETF = /*@__PURE__*/ Fn( ( [ color ] ) => {
2323

2424
const a = color.pow( 0.41666 ).mul( 1.055 ).sub( 0.055 );
2525
const b = color.mul( 12.92 );
@@ -30,7 +30,7 @@ export const linearSRGBTosRGB = /*@__PURE__*/ Fn( ( [ color ] ) => {
3030
return rgbResult;
3131

3232
} ).setLayout( {
33-
name: 'linearSRGBTosRGB',
33+
name: 'sRGBTransferOETF',
3434
type: 'vec3',
3535
inputs: [
3636
{ name: 'color', type: 'vec3' }

src/nodes/display/ColorSpaceNode.js

Lines changed: 27 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,14 @@
11
import TempNode from '../core/TempNode.js';
2-
import { addMethodChaining, nodeObject, vec4 } from '../tsl/TSLCore.js';
2+
import { addMethodChaining, mat3, nodeObject, vec4 } from '../tsl/TSLCore.js';
33

4-
import { LinearSRGBColorSpace, SRGBColorSpace } from '../../constants.js';
4+
import { SRGBTransfer } from '../../constants.js';
55
import { ColorManagement } from '../../math/ColorManagement.js';
6+
import { sRGBTransferEOTF, sRGBTransferOETF } from './ColorSpaceFunctions.js';
7+
import { Matrix3 } from '../../math/Matrix3.js';
68

79
const WORKING_COLOR_SPACE = 'WorkingColorSpace';
810
const OUTPUT_COLOR_SPACE = 'OutputColorSpace';
911

10-
function getColorSpaceName( colorSpace ) {
11-
12-
let method = null;
13-
14-
if ( colorSpace === LinearSRGBColorSpace ) {
15-
16-
method = 'Linear';
17-
18-
} else if ( colorSpace === SRGBColorSpace ) {
19-
20-
method = 'sRGB';
21-
22-
}
23-
24-
return method;
25-
26-
}
27-
28-
export function getColorSpaceMethod( source, target ) {
29-
30-
return getColorSpaceName( source ) + 'To' + getColorSpaceName( target );
31-
32-
}
33-
3412
class ColorSpaceNode extends TempNode {
3513

3614
static get type() {
@@ -49,7 +27,7 @@ class ColorSpaceNode extends TempNode {
4927

5028
}
5129

52-
getColorSpace( builder, colorSpace ) {
30+
resolveColorSpace( builder, colorSpace ) {
5331

5432
if ( colorSpace === WORKING_COLOR_SPACE ) {
5533

@@ -67,29 +45,37 @@ class ColorSpaceNode extends TempNode {
6745

6846
setup( builder ) {
6947

70-
const { renderer } = builder;
7148
const { colorNode } = this;
7249

73-
const source = this.getColorSpace( builder, this.source );
74-
const target = this.getColorSpace( builder, this.target );
50+
const source = this.resolveColorSpace( builder, this.source );
51+
const target = this.resolveColorSpace( builder, this.target );
7552

76-
if ( source === target ) return colorNode;
53+
let outputNode = colorNode;
7754

78-
const colorSpace = getColorSpaceMethod( source, target );
55+
if ( ColorManagement.enabled === false || source === target || ! source || ! target ) {
7956

80-
let outputNode = null;
57+
return outputNode;
8158

82-
const colorSpaceFn = renderer.library.getColorSpaceFunction( colorSpace );
59+
}
8360

84-
if ( colorSpaceFn !== null ) {
61+
if ( ColorManagement.getTransfer( source ) === SRGBTransfer ) {
8562

86-
outputNode = vec4( colorSpaceFn( colorNode.rgb ), colorNode.a );
63+
outputNode = vec4( sRGBTransferEOTF( outputNode.rgb ), outputNode.a );
8764

88-
} else {
65+
}
8966

90-
console.error( 'ColorSpaceNode: Unsupported Color Space configuration.', colorSpace );
67+
if ( ColorManagement.getPrimaries( source ) !== ColorManagement.getPrimaries( target ) ) {
9168

92-
outputNode = colorNode;
69+
outputNode = vec4(
70+
mat3( ColorManagement._getMatrix( new Matrix3(), source, target ) ).mul( outputNode.rgb ),
71+
outputNode.a
72+
);
73+
74+
}
75+
76+
if ( ColorManagement.getTransfer( target ) === SRGBTransfer ) {
77+
78+
outputNode = vec4( sRGBTransferOETF( outputNode.rgb ), outputNode.a );
9379

9480
}
9581

@@ -107,6 +93,8 @@ export const toWorkingColorSpace = ( node ) => nodeObject( new ColorSpaceNode( n
10793
export const workingToColorSpace = ( node, colorSpace ) => nodeObject( new ColorSpaceNode( nodeObject( node ), WORKING_COLOR_SPACE, colorSpace ) );
10894
export const colorSpaceToWorking = ( node, colorSpace ) => nodeObject( new ColorSpaceNode( nodeObject( node ), colorSpace, WORKING_COLOR_SPACE ) );
10995

96+
export const convertColorSpace = ( node, sourceColorSpace, targetColorSpace ) => nodeObject( new ColorSpaceNode( nodeObject( node ), sourceColorSpace, targetColorSpace ) );
97+
11098
addMethodChaining( 'toOutputColorSpace', toOutputColorSpace );
11199
addMethodChaining( 'toWorkingColorSpace', toWorkingColorSpace );
112100

src/renderers/common/nodes/NodeLibrary.js

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ class NodeLibrary {
55
this.lightNodes = new WeakMap();
66
this.materialNodes = new Map();
77
this.toneMappingNodes = new Map();
8-
this.colorSpaceNodes = new Map();
98

109
}
1110

@@ -33,18 +32,6 @@ class NodeLibrary {
3332

3433
}
3534

36-
addColorSpace( colorSpaceNode, colorSpace ) {
37-
38-
this.addType( colorSpaceNode, colorSpace, this.colorSpaceNodes );
39-
40-
}
41-
42-
getColorSpaceFunction( colorSpace ) {
43-
44-
return this.colorSpaceNodes.get( colorSpace ) || null;
45-
46-
}
47-
4835
addToneMapping( toneMappingNode, toneMapping ) {
4936

5037
this.addType( toneMappingNode, toneMapping, this.toneMappingNodes );

src/renderers/webgpu/nodes/BasicNodeLibrary.js

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -22,11 +22,6 @@ import { IESSpotLightNode } from '../../../nodes/Nodes.js';
2222
import { LinearToneMapping, ReinhardToneMapping, CineonToneMapping, ACESFilmicToneMapping, AgXToneMapping, NeutralToneMapping } from '../../../constants.js';
2323
import { linearToneMapping, reinhardToneMapping, cineonToneMapping, acesFilmicToneMapping, agxToneMapping, neutralToneMapping } from '../../../nodes/display/ToneMappingFunctions.js';
2424

25-
// Color Space
26-
import { LinearSRGBColorSpace, SRGBColorSpace } from '../../../constants.js';
27-
import { linearSRGBTosRGB, sRGBToLinearSRGB } from '../../../nodes/display/ColorSpaceFunctions.js';
28-
import { getColorSpaceMethod } from '../../../nodes/display/ColorSpaceNode.js';
29-
3025
class BasicNodeLibrary extends NodeLibrary {
3126

3227
constructor() {
@@ -49,9 +44,6 @@ class BasicNodeLibrary extends NodeLibrary {
4944
this.addToneMapping( agxToneMapping, AgXToneMapping );
5045
this.addToneMapping( neutralToneMapping, NeutralToneMapping );
5146

52-
this.addColorSpace( linearSRGBTosRGB, getColorSpaceMethod( LinearSRGBColorSpace, SRGBColorSpace ) );
53-
this.addColorSpace( sRGBToLinearSRGB, getColorSpaceMethod( SRGBColorSpace, LinearSRGBColorSpace ) );
54-
5547
}
5648

5749
}

src/renderers/webgpu/nodes/StandardNodeLibrary.js

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -54,11 +54,6 @@ import { IESSpotLightNode } from '../../../nodes/Nodes.js';
5454
import { LinearToneMapping, ReinhardToneMapping, CineonToneMapping, ACESFilmicToneMapping, AgXToneMapping, NeutralToneMapping } from '../../../constants.js';
5555
import { linearToneMapping, reinhardToneMapping, cineonToneMapping, acesFilmicToneMapping, agxToneMapping, neutralToneMapping } from '../../../nodes/display/ToneMappingFunctions.js';
5656

57-
// Color Space
58-
import { LinearSRGBColorSpace, SRGBColorSpace } from '../../../constants.js';
59-
import { linearSRGBTosRGB, sRGBToLinearSRGB } from '../../../nodes/display/ColorSpaceFunctions.js';
60-
import { getColorSpaceMethod } from '../../../nodes/display/ColorSpaceNode.js';
61-
6257
class StandardNodeLibrary extends NodeLibrary {
6358

6459
constructor() {
@@ -95,9 +90,6 @@ class StandardNodeLibrary extends NodeLibrary {
9590
this.addToneMapping( agxToneMapping, AgXToneMapping );
9691
this.addToneMapping( neutralToneMapping, NeutralToneMapping );
9792

98-
this.addColorSpace( linearSRGBTosRGB, getColorSpaceMethod( LinearSRGBColorSpace, SRGBColorSpace ) );
99-
this.addColorSpace( sRGBToLinearSRGB, getColorSpaceMethod( SRGBColorSpace, LinearSRGBColorSpace ) );
100-
10193
}
10294

10395
}

0 commit comments

Comments
 (0)