UNPKG

three

Version:

JavaScript 3D library

97 lines (55 loc) 2.55 kB
import TempNode from '../core/TempNode.js'; import { dot, mix } from '../math/MathNode.js'; import { add } from '../math/OperatorNode.js'; import { addNodeClass } from '../core/Node.js'; import { addNodeElement, tslFn, nodeProxy, float, vec3 } from '../shadernode/ShaderNode.js'; const saturationNode = tslFn( ( { color, adjustment } ) => { return adjustment.mix( luminance( color.rgb ), color.rgb ); } ); const vibranceNode = tslFn( ( { color, adjustment } ) => { const average = add( color.r, color.g, color.b ).div( 3.0 ); const mx = color.r.max( color.g.max( color.b ) ); const amt = mx.sub( average ).mul( adjustment ).mul( - 3.0 ); return mix( color.rgb, mx, amt ); } ); const hueNode = tslFn( ( { color, adjustment } ) => { const k = vec3( 0.57735, 0.57735, 0.57735 ); const cosAngle = adjustment.cos(); return vec3( color.rgb.mul( cosAngle ).add( k.cross( color.rgb ).mul( adjustment.sin() ).add( k.mul( dot( k, color.rgb ).mul( cosAngle.oneMinus() ) ) ) ) ); } ); class ColorAdjustmentNode extends TempNode { constructor( method, colorNode, adjustmentNode = float( 1 ) ) { super( 'vec3' ); this.method = method; this.colorNode = colorNode; this.adjustmentNode = adjustmentNode; } setup() { const { method, colorNode, adjustmentNode } = this; const callParams = { color: colorNode, adjustment: adjustmentNode }; let outputNode = null; if ( method === ColorAdjustmentNode.SATURATION ) { outputNode = saturationNode( callParams ); } else if ( method === ColorAdjustmentNode.VIBRANCE ) { outputNode = vibranceNode( callParams ); } else if ( method === ColorAdjustmentNode.HUE ) { outputNode = hueNode( callParams ); } else { console.error( `${ this.type }: Method "${ this.method }" not supported!` ); } return outputNode; } } ColorAdjustmentNode.SATURATION = 'saturation'; ColorAdjustmentNode.VIBRANCE = 'vibrance'; ColorAdjustmentNode.HUE = 'hue'; export default ColorAdjustmentNode; export const saturation = nodeProxy( ColorAdjustmentNode, ColorAdjustmentNode.SATURATION ); export const vibrance = nodeProxy( ColorAdjustmentNode, ColorAdjustmentNode.VIBRANCE ); export const hue = nodeProxy( ColorAdjustmentNode, ColorAdjustmentNode.HUE ); export const lumaCoeffs = vec3( 0.2125, 0.7154, 0.0721 ); export const luminance = ( color, luma = lumaCoeffs ) => dot( color, luma ); addNodeElement( 'saturation', saturation ); addNodeElement( 'vibrance', vibrance ); addNodeElement( 'hue', hue ); addNodeClass( 'ColorAdjustmentNode', ColorAdjustmentNode );