You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
85 lines
2.0 KiB
85 lines
2.0 KiB
import TempNode from '../core/Node.js';
|
|
import { ShaderNode, EPSILON, vec3, sub, mul, div, cond, lessThan, equal, max } from '../shadernode/ShaderNodeBaseElements.js';
|
|
|
|
export const BurnNode = new ShaderNode( ( { base, blend } ) => {
|
|
|
|
const fn = ( c ) => cond( lessThan( blend[ c ], EPSILON ), blend[ c ], max( sub( 1.0, div( sub( 1.0, base[ c ] ), blend[ c ] ) ), 0 ) );
|
|
|
|
return vec3( fn( 'x' ), fn( 'y' ), fn( 'z' ) );
|
|
|
|
} );
|
|
|
|
export const DodgeNode = new ShaderNode( ( { base, blend } ) => {
|
|
|
|
const fn = ( c ) => cond( equal( blend[ c ], 1.0 ), blend[ c ], max( div( base[ c ], sub( 1.0, blend[ c ] ) ), 0 ) );
|
|
|
|
return vec3( fn( 'x' ), fn( 'y' ), fn( 'z' ) );
|
|
|
|
} );
|
|
|
|
export const ScreenNode = new ShaderNode( ( { base, blend } ) => {
|
|
|
|
const fn = ( c ) => sub( 1.0, mul( sub( 1.0, base[ c ] ), sub( 1.0, blend[ c ] ) ) );
|
|
|
|
return vec3( fn( 'x' ), fn( 'y' ), fn( 'z' ) );
|
|
|
|
} );
|
|
|
|
export const OverlayNode = new ShaderNode( ( { base, blend } ) => {
|
|
|
|
const fn = ( c ) => cond( lessThan( base[ c ], 0.5 ), mul( 2.0, base[ c ], blend[ c ] ), sub( 1.0, mul( sub( 1.0, base[ c ] ), sub( 1.0, blend[ c ] ) ) ) );
|
|
|
|
return vec3( fn( 'x' ), fn( 'y' ), fn( 'z' ) );
|
|
|
|
} );
|
|
|
|
class BlendModeNode extends TempNode {
|
|
|
|
static BURN = 'burn';
|
|
static DODGE = 'dodge';
|
|
static SCREEN = 'screen';
|
|
static OVERLAY = 'overlay';
|
|
|
|
constructor( blendMode, baseNode, blendNode ) {
|
|
|
|
super();
|
|
|
|
this.blendMode = blendMode;
|
|
|
|
this.baseNode = baseNode;
|
|
this.blendNode = blendNode;
|
|
|
|
}
|
|
|
|
construct() {
|
|
|
|
const { blendMode, baseNode, blendNode } = this;
|
|
const params = { base: baseNode, blend: blendNode };
|
|
|
|
let outputNode = null;
|
|
|
|
if ( blendMode === BlendModeNode.BURN ) {
|
|
|
|
outputNode = BurnNode.call( params );
|
|
|
|
} else if ( blendMode === BlendModeNode.DODGE ) {
|
|
|
|
outputNode = DodgeNode.call( params );
|
|
|
|
} else if ( blendMode === BlendModeNode.SCREEN ) {
|
|
|
|
outputNode = ScreenNode.call( params );
|
|
|
|
} else if ( blendMode === BlendModeNode.OVERLAY ) {
|
|
|
|
outputNode = OverlayNode.call( params );
|
|
|
|
}
|
|
|
|
return outputNode;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
export default BlendModeNode;
|
|
|