129 lines
		
	
	
		
			3.2 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
		
		
			
		
	
	
			129 lines
		
	
	
		
			3.2 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
| 
								 | 
							
								import TempNode from '../core/TempNode.js';
							 | 
						||
| 
								 | 
							
								import { /*mix, step,*/ EPSILON } from '../math/MathNode.js';
							 | 
						||
| 
								 | 
							
								import { addNodeClass } from '../core/Node.js';
							 | 
						||
| 
								 | 
							
								import { addNodeElement, tslFn, nodeProxy, vec3 } from '../shadernode/ShaderNode.js';
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								export const BurnNode = tslFn( ( { base, blend } ) => {
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									const fn = ( c ) => blend[ c ].lessThan( EPSILON ).cond( blend[ c ], base[ c ].oneMinus().div( blend[ c ] ).oneMinus().max( 0 ) );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									return vec3( fn( 'x' ), fn( 'y' ), fn( 'z' ) );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								} ).setLayout( {
							 | 
						||
| 
								 | 
							
									name: 'burnColor',
							 | 
						||
| 
								 | 
							
									type: 'vec3',
							 | 
						||
| 
								 | 
							
									inputs: [
							 | 
						||
| 
								 | 
							
										{ name: 'base', type: 'vec3' },
							 | 
						||
| 
								 | 
							
										{ name: 'blend', type: 'vec3' }
							 | 
						||
| 
								 | 
							
									]
							 | 
						||
| 
								 | 
							
								} );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								export const DodgeNode = tslFn( ( { base, blend } ) => {
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									const fn = ( c ) => blend[ c ].equal( 1.0 ).cond( blend[ c ], base[ c ].div( blend[ c ].oneMinus() ).max( 0 ) );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									return vec3( fn( 'x' ), fn( 'y' ), fn( 'z' ) );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								} ).setLayout( {
							 | 
						||
| 
								 | 
							
									name: 'dodgeColor',
							 | 
						||
| 
								 | 
							
									type: 'vec3',
							 | 
						||
| 
								 | 
							
									inputs: [
							 | 
						||
| 
								 | 
							
										{ name: 'base', type: 'vec3' },
							 | 
						||
| 
								 | 
							
										{ name: 'blend', type: 'vec3' }
							 | 
						||
| 
								 | 
							
									]
							 | 
						||
| 
								 | 
							
								} );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								export const ScreenNode = tslFn( ( { base, blend } ) => {
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									const fn = ( c ) => base[ c ].oneMinus().mul( blend[ c ].oneMinus() ).oneMinus();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									return vec3( fn( 'x' ), fn( 'y' ), fn( 'z' ) );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								} ).setLayout( {
							 | 
						||
| 
								 | 
							
									name: 'screenColor',
							 | 
						||
| 
								 | 
							
									type: 'vec3',
							 | 
						||
| 
								 | 
							
									inputs: [
							 | 
						||
| 
								 | 
							
										{ name: 'base', type: 'vec3' },
							 | 
						||
| 
								 | 
							
										{ name: 'blend', type: 'vec3' }
							 | 
						||
| 
								 | 
							
									]
							 | 
						||
| 
								 | 
							
								} );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								export const OverlayNode = tslFn( ( { base, blend } ) => {
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									const fn = ( c ) => base[ c ].lessThan( 0.5 ).cond( base[ c ].mul( blend[ c ], 2.0 ), base[ c ].oneMinus().mul( blend[ c ].oneMinus() ).oneMinus() );
							 | 
						||
| 
								 | 
							
									//const fn = ( c ) => mix( base[ c ].oneMinus().mul( blend[ c ].oneMinus() ).oneMinus(), base[ c ].mul( blend[ c ], 2.0 ), step( base[ c ], 0.5 ) );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									return vec3( fn( 'x' ), fn( 'y' ), fn( 'z' ) );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								} ).setLayout( {
							 | 
						||
| 
								 | 
							
									name: 'overlayColor',
							 | 
						||
| 
								 | 
							
									type: 'vec3',
							 | 
						||
| 
								 | 
							
									inputs: [
							 | 
						||
| 
								 | 
							
										{ name: 'base', type: 'vec3' },
							 | 
						||
| 
								 | 
							
										{ name: 'blend', type: 'vec3' }
							 | 
						||
| 
								 | 
							
									]
							 | 
						||
| 
								 | 
							
								} );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								class BlendModeNode extends TempNode {
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									constructor( blendMode, baseNode, blendNode ) {
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										super();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										this.blendMode = blendMode;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										this.baseNode = baseNode;
							 | 
						||
| 
								 | 
							
										this.blendNode = blendNode;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									setup() {
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										const { blendMode, baseNode, blendNode } = this;
							 | 
						||
| 
								 | 
							
										const params = { base: baseNode, blend: blendNode };
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										let outputNode = null;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										if ( blendMode === BlendModeNode.BURN ) {
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											outputNode = BurnNode( params );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										} else if ( blendMode === BlendModeNode.DODGE ) {
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											outputNode = DodgeNode( params );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										} else if ( blendMode === BlendModeNode.SCREEN ) {
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											outputNode = ScreenNode( params );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										} else if ( blendMode === BlendModeNode.OVERLAY ) {
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											outputNode = OverlayNode( params );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										return outputNode;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								BlendModeNode.BURN = 'burn';
							 | 
						||
| 
								 | 
							
								BlendModeNode.DODGE = 'dodge';
							 | 
						||
| 
								 | 
							
								BlendModeNode.SCREEN = 'screen';
							 | 
						||
| 
								 | 
							
								BlendModeNode.OVERLAY = 'overlay';
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								export default BlendModeNode;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								export const burn = nodeProxy( BlendModeNode, BlendModeNode.BURN );
							 | 
						||
| 
								 | 
							
								export const dodge = nodeProxy( BlendModeNode, BlendModeNode.DODGE );
							 | 
						||
| 
								 | 
							
								export const overlay = nodeProxy( BlendModeNode, BlendModeNode.OVERLAY );
							 | 
						||
| 
								 | 
							
								export const screen = nodeProxy( BlendModeNode, BlendModeNode.SCREEN );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								addNodeElement( 'burn', burn );
							 | 
						||
| 
								 | 
							
								addNodeElement( 'dodge', dodge );
							 | 
						||
| 
								 | 
							
								addNodeElement( 'overlay', overlay );
							 | 
						||
| 
								 | 
							
								addNodeElement( 'screen', screen );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								addNodeClass( 'BlendModeNode', BlendModeNode );
							 |