123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387 |
- // core nodes
- import PropertyNode from './core/PropertyNode.js';
- import VarNode from './core/VarNode.js';
- import AttributeNode from './core/AttributeNode.js';
- import ConstNode from './core/ConstNode.js';
- import UniformNode from './core/UniformNode.js';
- // accessor nodes
- import BufferNode from './accessors/BufferNode.js';
- import PositionNode from './accessors/PositionNode.js';
- import NormalNode from './accessors/NormalNode.js';
- import TextureNode from './accessors/TextureNode.js';
- import UVNode from './accessors/UVNode.js';
- // math nodes
- import OperatorNode from './math/OperatorNode.js';
- import CondNode from './math/CondNode.js';
- import MathNode from './math/MathNode.js';
- // util nodes
- import ArrayElementNode from './utils/ArrayElementNode.js';
- import ConvertNode from './utils/ConvertNode.js';
- import JoinNode from './utils/JoinNode.js';
- import SplitNode from './utils/SplitNode.js';
- // core
- import { Vector2, Vector3, Vector4, Matrix3, Matrix4, Color } from 'three';
- const NodeHandler = {
- construct( NodeClosure, params ) {
- const inputs = params.shift();
- return NodeClosure( new ShaderNodeObjects( inputs ), ...params );
- },
- get: function ( node, prop ) {
- if ( typeof prop === 'string' && node[ prop ] === undefined ) {
- if ( /^[xyzwrgbastpq]{1,4}$/.test( prop ) === true ) {
- // accessing properties ( swizzle )
- prop = prop
- .replace( /r|s/g, 'x' )
- .replace( /g|t/g, 'y' )
- .replace( /b|p/g, 'z' )
- .replace( /a|q/g, 'w' );
- return new ShaderNodeObject( new SplitNode( node, prop ) );
- } else if ( /^\d+$/.test( prop ) === true ) {
- // accessing array
- return new ShaderNodeObject( new ArrayElementNode( node, new ConstNode( Number( prop ), 'uint' ) ) );
- }
- }
- return node[ prop ];
- }
- };
- const nodeObjects = new WeakMap();
- const ShaderNodeObject = function( obj ) {
- const type = typeof obj;
- if ( ( type === 'number' ) || ( type === 'boolean' ) ) {
- return new ShaderNodeObject( new ConstNode( obj ) );
- } else if ( type === 'object' ) {
- if ( obj.isNode === true ) {
- let nodeObject = nodeObjects.get( obj );
- if ( nodeObject === undefined ) {
- nodeObject = new Proxy( obj, NodeHandler );
- nodeObjects.set( obj, nodeObject );
- nodeObjects.set( nodeObject, nodeObject );
- }
- return nodeObject;
- }
- }
- return obj;
- };
- const ShaderNodeObjects = function( objects ) {
- for ( const name in objects ) {
- objects[ name ] = new ShaderNodeObject( objects[ name ] );
- }
- return objects;
- };
- const getShaderNodeArray = ( array ) => {
- const len = array.length;
- for ( let i = 0; i < len; i ++ ) {
- array[ i ] = new ShaderNodeObject( array[ i ] );
- }
- return array;
- };
- const ShaderNodeProxy = function( NodeClass, scope = null, factor = null ) {
- if ( scope === null ) {
- return ( ...params ) => {
- return new ShaderNodeObject( new NodeClass( ...getShaderNodeArray( params ) ) );
- };
- } else if ( factor === null ) {
- return ( ...params ) => {
- return new ShaderNodeObject( new NodeClass( scope, ...getShaderNodeArray( params ) ) );
- };
- } else {
- factor = new ShaderNodeObject( factor );
- return ( ...params ) => {
- return new ShaderNodeObject( new NodeClass( scope, ...getShaderNodeArray( params ), factor ) );
- };
- }
- };
- const ShaderNodeScript = function ( jsFunc ) {
- return ( inputs, builder ) => {
- new ShaderNodeObjects( inputs );
- return new ShaderNodeObject( jsFunc( inputs, builder ) );
- };
- };
- export const ShaderNode = new Proxy( ShaderNodeScript, NodeHandler );
- //
- // Node Material Shader Syntax
- //
- export const nodeObject = ( val ) => {
- return new ShaderNodeObject( val );
- };
- export const uniform = ( constNode ) => {
- return nodeObject( new UniformNode( constNode.value, constNode.nodeType ) );
- };
- export const label = ( node, name ) => {
- node = nodeObject( node );
- if ( node.isVarNode === true ) {
- node.name = name;
- return node;
- }
- return nodeObject( new VarNode( node, name ) );
- };
- export const temp = ( node ) => nodeObject( new VarNode( nodeObject( node ) ) );
- const ConvertType = function ( type, valueClass = null, valueComponents = 1 ) {
- return ( ...params ) => {
- if ( params[ 0 ]?.isNode === true ) {
- return nodeObject( new ConvertNode( params[ 0 ], type ) );
- }
- if ( ( params.length === 1 ) && ( valueComponents !== 1 ) ) {
- // Providing one scalar value: This value is used for all components
- for ( let i = 1; i < valueComponents; i ++ ) {
- params[ i ] = params [ 0 ];
- }
- }
- const val = ( ( valueClass === null ) || ( params[ 0 ] instanceof valueClass ) ) ? params[ 0 ] : new valueClass().set( ...params );
- return nodeObject( new ConstNode( val, type ) );
- };
- };
- export const float = new ConvertType( 'float' );
- export const int = new ConvertType( 'int' );
- export const uint = new ConvertType( 'uint' );
- export const bool = new ConvertType( 'bool' );
- export const color = new ConvertType( 'color', Color );
- export const vec2 = new ConvertType( 'vec2', Vector2, 2 );
- export const ivec2 = new ConvertType( 'ivec2', Vector2, 2 );
- export const uvec2 = new ConvertType( 'uvec2', Vector2, 2 );
- export const bvec2 = new ConvertType( 'bvec2', Vector2, 2 );
- export const vec3 = new ConvertType( 'vec3', Vector3, 3 );
- export const ivec3 = new ConvertType( 'ivec3', Vector3, 3 );
- export const uvec3 = new ConvertType( 'uvec3', Vector3, 3 );
- export const bvec3 = new ConvertType( 'bvec3', Vector3, 3 );
- export const vec4 = new ConvertType( 'vec4', Vector4, 4 );
- export const ivec4 = new ConvertType( 'ivec4', Vector4, 4 );
- export const uvec4 = new ConvertType( 'uvec4', Vector4, 4 );
- export const bvec4 = new ConvertType( 'bvec4', Vector4, 4 );
- export const mat3 = new ConvertType( 'mat3', Matrix3 );
- export const imat3 = new ConvertType( 'imat3', Matrix3 );
- export const umat3 = new ConvertType( 'umat3', Matrix3 );
- export const bmat3 = new ConvertType( 'bmat3', Matrix3 );
- export const mat4 = new ConvertType( 'mat4', Matrix4 );
- export const imat4 = new ConvertType( 'imat4', Matrix4 );
- export const umat4 = new ConvertType( 'umat4', Matrix4 );
- export const bmat4 = new ConvertType( 'bmat4', Matrix4 );
- export const join = ( ...params ) => {
- return nodeObject( new JoinNode( getShaderNodeArray( params ) ) );
- };
- export const uv = ( ...params ) => nodeObject( new UVNode( ...params ) );
- export const attribute = ( ...params ) => nodeObject( new AttributeNode( ...params ) );
- export const buffer = ( ...params ) => nodeObject( new BufferNode( ...params ) );
- export const texture = ( ...params ) => nodeObject( new TextureNode( ...params ) );
- export const cond = ( ...params ) => {
- return nodeObject( new CondNode( ...getShaderNodeArray( params ) ) );
- };
- export const addTo = ( varNode, ...params ) => {
- varNode.node = add( varNode.node, ...getShaderNodeArray( params ) );
- return nodeObject( varNode );
- };
- export const add = new ShaderNodeProxy( OperatorNode, '+' );
- export const sub = new ShaderNodeProxy( OperatorNode, '-' );
- export const mul = new ShaderNodeProxy( OperatorNode, '*' );
- export const div = new ShaderNodeProxy( OperatorNode, '/' );
- export const remainder = new ShaderNodeProxy( OperatorNode, '%' );
- export const equal = new ShaderNodeProxy( OperatorNode, '==' );
- export const assign = new ShaderNodeProxy( OperatorNode, '=' );
- export const lessThan = new ShaderNodeProxy( OperatorNode, '<' );
- export const greaterThan = new ShaderNodeProxy( OperatorNode, '>' );
- export const lessThanEqual = new ShaderNodeProxy( OperatorNode, '<=' );
- export const greaterThanEqual = new ShaderNodeProxy( OperatorNode, '>=' );
- export const and = new ShaderNodeProxy( OperatorNode, '&&' );
- export const or = new ShaderNodeProxy( OperatorNode, '||' );
- export const xor = new ShaderNodeProxy( OperatorNode, '^^' );
- export const bitAnd = new ShaderNodeProxy( OperatorNode, '&' );
- export const bitOr = new ShaderNodeProxy( OperatorNode, '|' );
- export const bitXor = new ShaderNodeProxy( OperatorNode, '^' );
- export const shiftLeft = new ShaderNodeProxy( OperatorNode, '<<' );
- export const shiftRight = new ShaderNodeProxy( OperatorNode, '>>' );
- export const element = new ShaderNodeProxy( ArrayElementNode );
- export const normalGeometry = new ShaderNodeObject( new NormalNode( NormalNode.GEOMETRY ) );
- export const normalLocal = new ShaderNodeObject( new NormalNode( NormalNode.LOCAL ) );
- export const normalWorld = new ShaderNodeObject( new NormalNode( NormalNode.WORLD ) );
- export const normalView = new ShaderNodeObject( new NormalNode( NormalNode.VIEW ) );
- export const transformedNormalView = new ShaderNodeObject( new VarNode( new NormalNode( NormalNode.VIEW ), 'TransformedNormalView', 'vec3' ) );
- export const positionLocal = new ShaderNodeObject( new PositionNode( PositionNode.LOCAL ) );
- export const positionWorld = new ShaderNodeObject( new PositionNode( PositionNode.WORLD ) );
- export const positionView = new ShaderNodeObject( new PositionNode( PositionNode.VIEW ) );
- export const positionViewDirection = new ShaderNodeObject( new PositionNode( PositionNode.VIEW_DIRECTION ) );
- export const PI = float( 3.141592653589793 );
- export const PI2 = float( 6.283185307179586 );
- export const PI_HALF = float( 1.5707963267948966 );
- export const RECIPROCAL_PI = float( 0.3183098861837907 );
- export const RECIPROCAL_PI2 = float( 0.15915494309189535 );
- export const EPSILON = float( 1e-6 );
- export const diffuseColor = new ShaderNodeObject( new PropertyNode( 'DiffuseColor', 'vec4' ) );
- export const roughness = new ShaderNodeObject( new PropertyNode( 'Roughness', 'float' ) );
- export const metalness = new ShaderNodeObject( new PropertyNode( 'Metalness', 'float' ) );
- export const alphaTest = new ShaderNodeObject( new PropertyNode( 'AlphaTest', 'float' ) );
- export const specularColor = new ShaderNodeObject( new PropertyNode( 'SpecularColor', 'color' ) );
- export const abs = new ShaderNodeProxy( MathNode, 'abs' );
- export const acos = new ShaderNodeProxy( MathNode, 'acos' );
- export const asin = new ShaderNodeProxy( MathNode, 'asin' );
- export const atan = new ShaderNodeProxy( MathNode, 'atan' );
- export const ceil = new ShaderNodeProxy( MathNode, 'ceil' );
- export const clamp = new ShaderNodeProxy( MathNode, 'clamp' );
- export const cos = new ShaderNodeProxy( MathNode, 'cos' );
- export const cross = new ShaderNodeProxy( MathNode, 'cross' );
- export const degrees = new ShaderNodeProxy( MathNode, 'degrees' );
- export const dFdx = new ShaderNodeProxy( MathNode, 'dFdx' );
- export const dFdy = new ShaderNodeProxy( MathNode, 'dFdy' );
- export const distance = new ShaderNodeProxy( MathNode, 'distance' );
- export const dot = new ShaderNodeProxy( MathNode, 'dot' );
- export const exp = new ShaderNodeProxy( MathNode, 'exp' );
- export const exp2 = new ShaderNodeProxy( MathNode, 'exp2' );
- export const faceforward = new ShaderNodeProxy( MathNode, 'faceforward' );
- export const floor = new ShaderNodeProxy( MathNode, 'floor' );
- export const fract = new ShaderNodeProxy( MathNode, 'fract' );
- export const invert = new ShaderNodeProxy( MathNode, 'invert' );
- export const inversesqrt = new ShaderNodeProxy( MathNode, 'inversesqrt' );
- export const length = new ShaderNodeProxy( MathNode, 'length' );
- export const log = new ShaderNodeProxy( MathNode, 'log' );
- export const log2 = new ShaderNodeProxy( MathNode, 'log2' );
- export const max = new ShaderNodeProxy( MathNode, 'max' );
- export const min = new ShaderNodeProxy( MathNode, 'min' );
- export const mix = new ShaderNodeProxy( MathNode, 'mix' );
- export const mod = new ShaderNodeProxy( MathNode, 'mod' );
- export const negate = new ShaderNodeProxy( MathNode, 'negate' );
- export const normalize = new ShaderNodeProxy( MathNode, 'normalize' );
- export const pow = new ShaderNodeProxy( MathNode, 'pow' );
- export const pow2 = new ShaderNodeProxy( MathNode, 'pow', 2 );
- export const pow3 = new ShaderNodeProxy( MathNode, 'pow', 3 );
- export const pow4 = new ShaderNodeProxy( MathNode, 'pow', 4 );
- export const radians = new ShaderNodeProxy( MathNode, 'radians' );
- export const reflect = new ShaderNodeProxy( MathNode, 'reflect' );
- export const refract = new ShaderNodeProxy( MathNode, 'refract' );
- export const round = new ShaderNodeProxy( MathNode, 'round' );
- export const saturate = new ShaderNodeProxy( MathNode, 'saturate' );
- export const sign = new ShaderNodeProxy( MathNode, 'sign' );
- export const sin = new ShaderNodeProxy( MathNode, 'sin' );
- export const smoothstep = new ShaderNodeProxy( MathNode, 'smoothstep' );
- export const sqrt = new ShaderNodeProxy( MathNode, 'sqrt' );
- export const step = new ShaderNodeProxy( MathNode, 'step' );
- export const tan = new ShaderNodeProxy( MathNode, 'tan' );
- export const transformDirection = new ShaderNodeProxy( MathNode, 'transformDirection' );
|