UNPKG

three

Version:

JavaScript 3D library

188 lines (140 loc) 5.2 kB
import TempNode from '../core/TempNode.js'; import { addMethodChaining, mat3, nodeObject, vec4 } from '../tsl/TSLCore.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'; /** * This node represents a color space conversion. Meaning it converts * a color value from a source to a target color space. * * @augments TempNode */ class ColorSpaceNode extends TempNode { static get type() { return 'ColorSpaceNode'; } /** * Constructs a new color space node. * * @param {Node} colorNode - Represents the color to convert. * @param {string} source - The source color space. * @param {string} target - The target color space. */ constructor( colorNode, source, target ) { super( 'vec4' ); /** * Represents the color to convert. * * @type {Node} */ this.colorNode = colorNode; /** * The source color space. * * @type {string} */ this.source = source; /** * The target color space. * * @type {string} */ this.target = target; } /** * This method resolves the constants `WORKING_COLOR_SPACE` and * `OUTPUT_COLOR_SPACE` based on the current configuration of the * color management and renderer. * * @param {NodeBuilder} builder - The current node builder. * @param {string} colorSpace - The color space to resolve. * @return {string} The resolved color space. */ resolveColorSpace( builder, colorSpace ) { if ( colorSpace === WORKING_COLOR_SPACE ) { return ColorManagement.workingColorSpace; } else if ( colorSpace === OUTPUT_COLOR_SPACE ) { return builder.context.outputColorSpace || builder.renderer.outputColorSpace; } return colorSpace; } setup( builder ) { const { colorNode } = this; const source = this.resolveColorSpace( builder, this.source ); const target = this.resolveColorSpace( builder, this.target ); let outputNode = colorNode; if ( ColorManagement.enabled === false || source === target || ! source || ! target ) { return outputNode; } if ( ColorManagement.getTransfer( source ) === SRGBTransfer ) { outputNode = vec4( sRGBTransferEOTF( outputNode.rgb ), outputNode.a ); } if ( ColorManagement.getPrimaries( source ) !== ColorManagement.getPrimaries( target ) ) { 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 ); } return outputNode; } } export default ColorSpaceNode; /** * TSL function for converting a given color node to the current output color space. * * @tsl * @function * @param {Node} node - Represents the node to convert. * @returns {ColorSpaceNode} */ export const toOutputColorSpace = ( node ) => nodeObject( new ColorSpaceNode( nodeObject( node ), WORKING_COLOR_SPACE, OUTPUT_COLOR_SPACE ) ); /** * TSL function for converting a given color node to the current working color space. * * @tsl * @function * @param {Node} node - Represents the node to convert. * @returns {ColorSpaceNode} */ export const toWorkingColorSpace = ( node ) => nodeObject( new ColorSpaceNode( nodeObject( node ), OUTPUT_COLOR_SPACE, WORKING_COLOR_SPACE ) ); /** * TSL function for converting a given color node from the current working color space to the given color space. * * @tsl * @function * @param {Node} node - Represents the node to convert. * @param {string} colorSpace - The target color space. * @returns {ColorSpaceNode} */ export const workingToColorSpace = ( node, colorSpace ) => nodeObject( new ColorSpaceNode( nodeObject( node ), WORKING_COLOR_SPACE, colorSpace ) ); /** * TSL function for converting a given color node from the given color space to the current working color space. * * @tsl * @function * @param {Node} node - Represents the node to convert. * @param {string} colorSpace - The source color space. * @returns {ColorSpaceNode} */ export const colorSpaceToWorking = ( node, colorSpace ) => nodeObject( new ColorSpaceNode( nodeObject( node ), colorSpace, WORKING_COLOR_SPACE ) ); /** * TSL function for converting a given color node from one color space to another one. * * @tsl * @function * @param {Node} node - Represents the node to convert. * @param {string} sourceColorSpace - The source color space. * @param {string} targetColorSpace - The target color space. * @returns {ColorSpaceNode} */ export const convertColorSpace = ( node, sourceColorSpace, targetColorSpace ) => nodeObject( new ColorSpaceNode( nodeObject( node ), sourceColorSpace, targetColorSpace ) ); addMethodChaining( 'toOutputColorSpace', toOutputColorSpace ); addMethodChaining( 'toWorkingColorSpace', toWorkingColorSpace ); addMethodChaining( 'workingToColorSpace', workingToColorSpace ); addMethodChaining( 'colorSpaceToWorking', colorSpaceToWorking );