Преглед изворни кода

TSL: Support defined color spaces in ColorSpaceNode (#29694)

* TSL: Support defined color spaces in ColorSpaceNode

* TSL: Add .convertColorNode()

* fix circular dependency

* remove chaining method

---------
Don McCurdy пре 1 година
родитељ
комит
cb29f6f17e

+ 0 - 1
src/math/ColorManagement.js

@@ -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 );

+ 5 - 5
src/nodes/display/ColorSpaceFunctions.js

@@ -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 );
@@ -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 );
@@ -30,7 +30,7 @@ export const linearSRGBTosRGB = /*@__PURE__*/ Fn( ( [ color ] ) => {
 	return rgbResult;
 
 } ).setLayout( {
-	name: 'linearSRGBTosRGB',
+	name: 'sRGBTransferOETF',
 	type: 'vec3',
 	inputs: [
 		{ name: 'color', type: 'vec3' }

+ 27 - 39
src/nodes/display/ColorSpaceNode.js

@@ -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() {
@@ -49,7 +27,7 @@ class ColorSpaceNode extends TempNode {
 
 	}
 
-	getColorSpace( builder, colorSpace ) {
+	resolveColorSpace( builder, colorSpace ) {
 
 		if ( colorSpace === WORKING_COLOR_SPACE ) {
 
@@ -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 );
 
 		}
 
@@ -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 );
 

+ 0 - 13
src/renderers/common/nodes/NodeLibrary.js

@@ -5,7 +5,6 @@ class NodeLibrary {
 		this.lightNodes = new WeakMap();
 		this.materialNodes = new Map();
 		this.toneMappingNodes = new Map();
-		this.colorSpaceNodes = new Map();
 
 	}
 
@@ -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 );

+ 0 - 8
src/renderers/webgpu/nodes/BasicNodeLibrary.js

@@ -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() {
@@ -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 ) );
-
 	}
 
 }

+ 0 - 8
src/renderers/webgpu/nodes/StandardNodeLibrary.js

@@ -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() {
@@ -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 ) );
-
 	}
 
 }

粤ICP备19079148号