Skip to content

Commit

Permalink
TSL: Support defined color spaces in ColorSpaceNode (#29694)
Browse files Browse the repository at this point in the history
* TSL: Support defined color spaces in ColorSpaceNode

* TSL: Add .convertColorNode()

* fix circular dependency

* remove chaining method

---------
  • Loading branch information
donmccurdy authored Oct 20, 2024
1 parent 84183ce commit cb29f6f
Show file tree
Hide file tree
Showing 6 changed files with 32 additions and 74 deletions.
1 change: 0 additions & 1 deletion src/math/ColorManagement.js
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,6 @@ export const ColorManagement = {

};


export function SRGBToLinear( c ) {

return ( c < 0.04045 ) ? c * 0.0773993808 : Math.pow( c * 0.9478672986 + 0.0521327014, 2.4 );
Expand Down
10 changes: 5 additions & 5 deletions src/nodes/display/ColorSpaceFunctions.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { mix } from '../math/MathNode.js';
import { Fn } from '../tsl/TSLBase.js';
import { Fn } from '../tsl/TSLCore.js';

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

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

} ).setLayout( {
name: 'sRGBToLinearSRGB',
name: 'sRGBTransferEOTF',
type: 'vec3',
inputs: [
{ name: 'color', type: 'vec3' }
]
} );

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

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

} ).setLayout( {
name: 'linearSRGBTosRGB',
name: 'sRGBTransferOETF',
type: 'vec3',
inputs: [
{ name: 'color', type: 'vec3' }
Expand Down
66 changes: 27 additions & 39 deletions src/nodes/display/ColorSpaceNode.js
Original file line number Diff line number Diff line change
@@ -1,36 +1,14 @@
import TempNode from '../core/TempNode.js';
import { addMethodChaining, nodeObject, vec4 } from '../tsl/TSLCore.js';
import { addMethodChaining, mat3, nodeObject, vec4 } from '../tsl/TSLCore.js';

import { LinearSRGBColorSpace, SRGBColorSpace } from '../../constants.js';
import { SRGBTransfer } from '../../constants.js';
import { ColorManagement } from '../../math/ColorManagement.js';
import { sRGBTransferEOTF, sRGBTransferOETF } from './ColorSpaceFunctions.js';
import { Matrix3 } from '../../math/Matrix3.js';

const WORKING_COLOR_SPACE = 'WorkingColorSpace';
const OUTPUT_COLOR_SPACE = 'OutputColorSpace';

function getColorSpaceName( colorSpace ) {

let method = null;

if ( colorSpace === LinearSRGBColorSpace ) {

method = 'Linear';

} else if ( colorSpace === SRGBColorSpace ) {

method = 'sRGB';

}

return method;

}

export function getColorSpaceMethod( source, target ) {

return getColorSpaceName( source ) + 'To' + getColorSpaceName( target );

}

class ColorSpaceNode extends TempNode {

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

}

getColorSpace( builder, colorSpace ) {
resolveColorSpace( builder, colorSpace ) {

if ( colorSpace === WORKING_COLOR_SPACE ) {

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

setup( builder ) {

const { renderer } = builder;
const { colorNode } = this;

const source = this.getColorSpace( builder, this.source );
const target = this.getColorSpace( builder, this.target );
const source = this.resolveColorSpace( builder, this.source );
const target = this.resolveColorSpace( builder, this.target );

if ( source === target ) return colorNode;
let outputNode = colorNode;

const colorSpace = getColorSpaceMethod( source, target );
if ( ColorManagement.enabled === false || source === target || ! source || ! target ) {

let outputNode = null;
return outputNode;

const colorSpaceFn = renderer.library.getColorSpaceFunction( colorSpace );
}

if ( colorSpaceFn !== null ) {
if ( ColorManagement.getTransfer( source ) === SRGBTransfer ) {

outputNode = vec4( colorSpaceFn( colorNode.rgb ), colorNode.a );
outputNode = vec4( sRGBTransferEOTF( outputNode.rgb ), outputNode.a );

} else {
}

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

outputNode = colorNode;
outputNode = vec4(
mat3( ColorManagement._getMatrix( new Matrix3(), source, target ) ).mul( outputNode.rgb ),
outputNode.a
);

}

if ( ColorManagement.getTransfer( target ) === SRGBTransfer ) {

outputNode = vec4( sRGBTransferOETF( outputNode.rgb ), outputNode.a );

}

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

export const convertColorSpace = ( node, sourceColorSpace, targetColorSpace ) => nodeObject( new ColorSpaceNode( nodeObject( node ), sourceColorSpace, targetColorSpace ) );

addMethodChaining( 'toOutputColorSpace', toOutputColorSpace );
addMethodChaining( 'toWorkingColorSpace', toWorkingColorSpace );

Expand Down
13 changes: 0 additions & 13 deletions src/renderers/common/nodes/NodeLibrary.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ class NodeLibrary {
this.lightNodes = new WeakMap();
this.materialNodes = new Map();
this.toneMappingNodes = new Map();
this.colorSpaceNodes = new Map();

}

Expand Down Expand Up @@ -33,18 +32,6 @@ class NodeLibrary {

}

addColorSpace( colorSpaceNode, colorSpace ) {

this.addType( colorSpaceNode, colorSpace, this.colorSpaceNodes );

}

getColorSpaceFunction( colorSpace ) {

return this.colorSpaceNodes.get( colorSpace ) || null;

}

addToneMapping( toneMappingNode, toneMapping ) {

this.addType( toneMappingNode, toneMapping, this.toneMappingNodes );
Expand Down
8 changes: 0 additions & 8 deletions src/renderers/webgpu/nodes/BasicNodeLibrary.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,6 @@ import { IESSpotLightNode } from '../../../nodes/Nodes.js';
import { LinearToneMapping, ReinhardToneMapping, CineonToneMapping, ACESFilmicToneMapping, AgXToneMapping, NeutralToneMapping } from '../../../constants.js';
import { linearToneMapping, reinhardToneMapping, cineonToneMapping, acesFilmicToneMapping, agxToneMapping, neutralToneMapping } from '../../../nodes/display/ToneMappingFunctions.js';

// Color Space
import { LinearSRGBColorSpace, SRGBColorSpace } from '../../../constants.js';
import { linearSRGBTosRGB, sRGBToLinearSRGB } from '../../../nodes/display/ColorSpaceFunctions.js';
import { getColorSpaceMethod } from '../../../nodes/display/ColorSpaceNode.js';

class BasicNodeLibrary extends NodeLibrary {

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

this.addColorSpace( linearSRGBTosRGB, getColorSpaceMethod( LinearSRGBColorSpace, SRGBColorSpace ) );
this.addColorSpace( sRGBToLinearSRGB, getColorSpaceMethod( SRGBColorSpace, LinearSRGBColorSpace ) );

}

}
Expand Down
8 changes: 0 additions & 8 deletions src/renderers/webgpu/nodes/StandardNodeLibrary.js
Original file line number Diff line number Diff line change
Expand Up @@ -54,11 +54,6 @@ import { IESSpotLightNode } from '../../../nodes/Nodes.js';
import { LinearToneMapping, ReinhardToneMapping, CineonToneMapping, ACESFilmicToneMapping, AgXToneMapping, NeutralToneMapping } from '../../../constants.js';
import { linearToneMapping, reinhardToneMapping, cineonToneMapping, acesFilmicToneMapping, agxToneMapping, neutralToneMapping } from '../../../nodes/display/ToneMappingFunctions.js';

// Color Space
import { LinearSRGBColorSpace, SRGBColorSpace } from '../../../constants.js';
import { linearSRGBTosRGB, sRGBToLinearSRGB } from '../../../nodes/display/ColorSpaceFunctions.js';
import { getColorSpaceMethod } from '../../../nodes/display/ColorSpaceNode.js';

class StandardNodeLibrary extends NodeLibrary {

constructor() {
Expand Down Expand Up @@ -95,9 +90,6 @@ class StandardNodeLibrary extends NodeLibrary {
this.addToneMapping( agxToneMapping, AgXToneMapping );
this.addToneMapping( neutralToneMapping, NeutralToneMapping );

this.addColorSpace( linearSRGBTosRGB, getColorSpaceMethod( LinearSRGBColorSpace, SRGBColorSpace ) );
this.addColorSpace( sRGBToLinearSRGB, getColorSpaceMethod( SRGBColorSpace, LinearSRGBColorSpace ) );

}

}
Expand Down

0 comments on commit cb29f6f

Please sign in to comment.