|
@@ -1,970 +0,0 @@
|
|
|
-import {
|
|
|
- CubeReflectionMapping,
|
|
|
- CubeRefractionMapping,
|
|
|
- CubeUVReflectionMapping,
|
|
|
- CubeUVRefractionMapping,
|
|
|
- LinearEncoding,
|
|
|
- sRGBEncoding
|
|
|
-} from 'three';
|
|
|
-
|
|
|
-import { NodeUniform } from './NodeUniform.js';
|
|
|
-import { NodeUtils } from './NodeUtils.js';
|
|
|
-import { NodeLib } from './NodeLib.js';
|
|
|
-import { FunctionNode } from './FunctionNode.js';
|
|
|
-import { ConstNode } from './ConstNode.js';
|
|
|
-import { StructNode } from './StructNode.js';
|
|
|
-import { Vector2Node } from '../inputs/Vector2Node.js';
|
|
|
-import { Vector3Node } from '../inputs/Vector3Node.js';
|
|
|
-import { Vector4Node } from '../inputs/Vector4Node.js';
|
|
|
-import { TextureNode } from '../inputs/TextureNode.js';
|
|
|
-import { CubeTextureNode } from '../inputs/CubeTextureNode.js';
|
|
|
-import { TextureCubeNode } from '../misc/TextureCubeNode.js';
|
|
|
-
|
|
|
-
|
|
|
-const elements = NodeUtils.elements,
|
|
|
- constructors = [ 'float', 'vec2', 'vec3', 'vec4' ],
|
|
|
- convertFormatToType = {
|
|
|
- float: 'f',
|
|
|
- vec2: 'v2',
|
|
|
- vec3: 'v3',
|
|
|
- vec4: 'v4',
|
|
|
- mat4: 'v4',
|
|
|
- int: 'i',
|
|
|
- bool: 'b'
|
|
|
- },
|
|
|
- convertTypeToFormat = {
|
|
|
- t: 'sampler2D',
|
|
|
- tc: 'samplerCube',
|
|
|
- b: 'bool',
|
|
|
- i: 'int',
|
|
|
- f: 'float',
|
|
|
- c: 'vec3',
|
|
|
- v2: 'vec2',
|
|
|
- v3: 'vec3',
|
|
|
- v4: 'vec4',
|
|
|
- m3: 'mat3',
|
|
|
- m4: 'mat4'
|
|
|
- };
|
|
|
-
|
|
|
-class NodeBuilder {
|
|
|
-
|
|
|
- constructor() {
|
|
|
-
|
|
|
- this.slots = [];
|
|
|
- this.caches = [];
|
|
|
- this.contexts = [];
|
|
|
-
|
|
|
- this.keywords = {};
|
|
|
-
|
|
|
- this.nodeData = {};
|
|
|
-
|
|
|
- this.requires = {
|
|
|
- uv: [],
|
|
|
- color: [],
|
|
|
- lights: false,
|
|
|
- fog: false,
|
|
|
- transparent: false,
|
|
|
- irradiance: false
|
|
|
- };
|
|
|
-
|
|
|
- this.includes = {
|
|
|
- consts: [],
|
|
|
- functions: [],
|
|
|
- structs: []
|
|
|
- };
|
|
|
-
|
|
|
- this.attributes = {};
|
|
|
-
|
|
|
- this.prefixCode = /* glsl */`
|
|
|
- #ifdef TEXTURE_LOD_EXT
|
|
|
-
|
|
|
- #define texCube(a, b) textureCube(a, b)
|
|
|
- #define texCubeBias(a, b, c) textureCubeLodEXT(a, b, c)
|
|
|
-
|
|
|
- #define tex2D(a, b) texture2D(a, b)
|
|
|
- #define tex2DBias(a, b, c) texture2DLodEXT(a, b, c)
|
|
|
-
|
|
|
- #else
|
|
|
-
|
|
|
- #define texCube(a, b) textureCube(a, b)
|
|
|
- #define texCubeBias(a, b, c) textureCube(a, b, c)
|
|
|
-
|
|
|
- #define tex2D(a, b) texture2D(a, b)
|
|
|
- #define tex2DBias(a, b, c) texture2D(a, b, c)
|
|
|
-
|
|
|
- #endif
|
|
|
-
|
|
|
- #include <packing>
|
|
|
- #include <common>`;
|
|
|
-
|
|
|
- this.parsCode = {
|
|
|
- vertex: '',
|
|
|
- fragment: ''
|
|
|
- };
|
|
|
-
|
|
|
- this.code = {
|
|
|
- vertex: '',
|
|
|
- fragment: ''
|
|
|
- };
|
|
|
-
|
|
|
- this.nodeCode = {
|
|
|
- vertex: '',
|
|
|
- fragment: ''
|
|
|
- };
|
|
|
-
|
|
|
- this.resultCode = {
|
|
|
- vertex: '',
|
|
|
- fragment: ''
|
|
|
- };
|
|
|
-
|
|
|
- this.finalCode = {
|
|
|
- vertex: '',
|
|
|
- fragment: ''
|
|
|
- };
|
|
|
-
|
|
|
- this.inputs = {
|
|
|
- uniforms: {
|
|
|
- list: [],
|
|
|
- vertex: [],
|
|
|
- fragment: []
|
|
|
- },
|
|
|
- vars: {
|
|
|
- varying: [],
|
|
|
- vertex: [],
|
|
|
- fragment: []
|
|
|
- }
|
|
|
- };
|
|
|
-
|
|
|
- // send to material
|
|
|
-
|
|
|
- this.defines = {};
|
|
|
-
|
|
|
- this.uniforms = {};
|
|
|
-
|
|
|
- this.extensions = {};
|
|
|
-
|
|
|
- this.updaters = [];
|
|
|
-
|
|
|
- this.nodes = [];
|
|
|
-
|
|
|
- // --
|
|
|
-
|
|
|
- this.analyzing = false;
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- build( vertex, fragment ) {
|
|
|
-
|
|
|
- this.buildShader( 'vertex', vertex );
|
|
|
- this.buildShader( 'fragment', fragment );
|
|
|
-
|
|
|
- for ( let i = 0; i < this.requires.uv.length; i ++ ) {
|
|
|
-
|
|
|
- if ( this.requires.uv[ i ] ) {
|
|
|
-
|
|
|
- const uvIndex = i > 0 ? i + 1 : '';
|
|
|
-
|
|
|
- this.addVaryCode( 'varying vec2 vUv' + uvIndex + ';' );
|
|
|
-
|
|
|
- if ( i > 0 ) {
|
|
|
-
|
|
|
- this.addVertexParsCode( 'attribute vec2 uv' + uvIndex + ';' );
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- this.addVertexFinalCode( 'vUv' + uvIndex + ' = uv' + uvIndex + ';' );
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- if ( this.requires.color[ 0 ] ) {
|
|
|
-
|
|
|
- this.addVaryCode( 'varying vec4 vColor;' );
|
|
|
- this.addVertexParsCode( 'attribute vec4 color;' );
|
|
|
-
|
|
|
- this.addVertexFinalCode( 'vColor = color;' );
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- if ( this.requires.color[ 1 ] ) {
|
|
|
-
|
|
|
- this.addVaryCode( 'varying vec4 vColor2;' );
|
|
|
- this.addVertexParsCode( 'attribute vec4 color2;' );
|
|
|
-
|
|
|
- this.addVertexFinalCode( 'vColor2 = color2;' );
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- if ( this.requires.position ) {
|
|
|
-
|
|
|
- this.addVaryCode( 'varying vec3 vPosition;' );
|
|
|
-
|
|
|
- this.addVertexFinalCode( 'vPosition = transformed;' );
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- if ( this.requires.worldPosition ) {
|
|
|
-
|
|
|
- this.addVaryCode( 'varying vec3 vWPosition;' );
|
|
|
-
|
|
|
- this.addVertexFinalCode( 'vWPosition = ( modelMatrix * vec4( transformed, 1.0 ) ).xyz;' );
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- if ( this.requires.normal ) {
|
|
|
-
|
|
|
- this.addVaryCode( 'varying vec3 vObjectNormal;' );
|
|
|
-
|
|
|
- this.addVertexFinalCode( 'vObjectNormal = normal;' );
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- if ( this.requires.worldNormal ) {
|
|
|
-
|
|
|
- this.addVaryCode( 'varying vec3 vWNormal;' );
|
|
|
-
|
|
|
- this.addVertexFinalCode( 'vWNormal = inverseTransformDirection( transformedNormal, viewMatrix ).xyz;' );
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- return this;
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- buildShader( shader, node ) {
|
|
|
-
|
|
|
- this.resultCode[ shader ] = node.build( this.setShader( shader ), 'v4' );
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- setMaterial( material, renderer ) {
|
|
|
-
|
|
|
- this.material = material;
|
|
|
- this.renderer = renderer;
|
|
|
-
|
|
|
- this.requires.lights = material.lights;
|
|
|
- this.requires.fog = material.fog;
|
|
|
-
|
|
|
- this.mergeDefines( material.defines );
|
|
|
-
|
|
|
- return this;
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- addFlow( slot, cache, context ) {
|
|
|
-
|
|
|
- return this.addSlot( slot ).addCache( cache ).addContext( context );
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- removeFlow() {
|
|
|
-
|
|
|
- return this.removeSlot().removeCache().removeContext();
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- addCache( name ) {
|
|
|
-
|
|
|
- this.cache = name || '';
|
|
|
- this.caches.push( this.cache );
|
|
|
-
|
|
|
- return this;
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- removeCache() {
|
|
|
-
|
|
|
- this.caches.pop();
|
|
|
- this.cache = this.caches[ this.caches.length - 1 ] || '';
|
|
|
-
|
|
|
- return this;
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- addContext( context ) {
|
|
|
-
|
|
|
- this.context = Object.assign( {}, this.context, context );
|
|
|
- this.context.extra = this.context.extra || {};
|
|
|
-
|
|
|
- this.contexts.push( this.context );
|
|
|
-
|
|
|
- return this;
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- removeContext() {
|
|
|
-
|
|
|
- this.contexts.pop();
|
|
|
- this.context = this.contexts[ this.contexts.length - 1 ] || {};
|
|
|
-
|
|
|
- return this;
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- addSlot( name = '' ) {
|
|
|
-
|
|
|
- this.slot = name;
|
|
|
- this.slots.push( this.slot );
|
|
|
-
|
|
|
- return this;
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- removeSlot() {
|
|
|
-
|
|
|
- this.slots.pop();
|
|
|
- this.slot = this.slots[ this.slots.length - 1 ] || '';
|
|
|
-
|
|
|
- return this;
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- addVertexCode( code ) {
|
|
|
-
|
|
|
- this.addCode( code, 'vertex' );
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- addFragmentCode( code ) {
|
|
|
-
|
|
|
- this.addCode( code, 'fragment' );
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- addCode( code, shader ) {
|
|
|
-
|
|
|
- this.code[ shader || this.shader ] += code + '\n';
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- addVertexNodeCode( code ) {
|
|
|
-
|
|
|
- this.addNodeCode( code, 'vertex' );
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- addFragmentNodeCode( code ) {
|
|
|
-
|
|
|
- this.addNodeCode( code, 'fragment' );
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- addNodeCode( code, shader ) {
|
|
|
-
|
|
|
- this.nodeCode[ shader || this.shader ] += code + '\n';
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- clearNodeCode( shader ) {
|
|
|
-
|
|
|
- shader = shader || this.shader;
|
|
|
-
|
|
|
- const code = this.nodeCode[ shader ];
|
|
|
-
|
|
|
- this.nodeCode[ shader ] = '';
|
|
|
-
|
|
|
- return code;
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- clearVertexNodeCode( ) {
|
|
|
-
|
|
|
- return this.clearNodeCode( 'vertex' );
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- clearFragmentNodeCode( ) {
|
|
|
-
|
|
|
- return this.clearNodeCode( 'fragment' );
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- addVertexFinalCode( code ) {
|
|
|
-
|
|
|
- this.addFinalCode( code, 'vertex' );
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- addFragmentFinalCode( code ) {
|
|
|
-
|
|
|
- this.addFinalCode( code, 'fragment' );
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- addFinalCode( code, shader ) {
|
|
|
-
|
|
|
- this.finalCode[ shader || this.shader ] += code + '\n';
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- addVertexParsCode( code ) {
|
|
|
-
|
|
|
- this.addParsCode( code, 'vertex' );
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- addFragmentParsCode( code ) {
|
|
|
-
|
|
|
- this.addParsCode( code, 'fragment' );
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- addParsCode( code, shader ) {
|
|
|
-
|
|
|
- this.parsCode[ shader || this.shader ] += code + '\n';
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- addVaryCode( code ) {
|
|
|
-
|
|
|
- this.addVertexParsCode( code );
|
|
|
- this.addFragmentParsCode( code );
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- isCache( name ) {
|
|
|
-
|
|
|
- return this.caches.indexOf( name ) !== - 1;
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- isSlot( name ) {
|
|
|
-
|
|
|
- return this.slots.indexOf( name ) !== - 1;
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- define( name, value ) {
|
|
|
-
|
|
|
- this.defines[ name ] = value === undefined ? 1 : value;
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- require( name ) {
|
|
|
-
|
|
|
- this.requires[ name ] = true;
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- isDefined( name ) {
|
|
|
-
|
|
|
- return this.defines[ name ] !== undefined;
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- getVar( uuid, type, ns, shader = 'varying', prefix = 'V', label = '' ) {
|
|
|
-
|
|
|
- const vars = this.getVars( shader );
|
|
|
- let data = vars[ uuid ];
|
|
|
-
|
|
|
- if ( ! data ) {
|
|
|
-
|
|
|
- const index = vars.length,
|
|
|
- name = ns ? ns : 'node' + prefix + index + ( label ? '_' + label : '' );
|
|
|
-
|
|
|
- data = { name: name, type: type };
|
|
|
-
|
|
|
- vars.push( data );
|
|
|
- vars[ uuid ] = data;
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- return data;
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- getTempVar( uuid, type, ns, label ) {
|
|
|
-
|
|
|
- return this.getVar( uuid, type, ns, this.shader, 'T', label );
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- getAttribute( name, type ) {
|
|
|
-
|
|
|
- if ( ! this.attributes[ name ] ) {
|
|
|
-
|
|
|
- const varying = this.getVar( name, type );
|
|
|
-
|
|
|
- this.addVertexParsCode( 'attribute ' + type + ' ' + name + ';' );
|
|
|
- this.addVertexFinalCode( varying.name + ' = ' + name + ';' );
|
|
|
-
|
|
|
- this.attributes[ name ] = { varying: varying, name: name, type: type };
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- return this.attributes[ name ];
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- getCode( shader ) {
|
|
|
-
|
|
|
- return [
|
|
|
- this.prefixCode,
|
|
|
- this.parsCode[ shader ],
|
|
|
- this.getVarListCode( this.getVars( 'varying' ), 'varying' ),
|
|
|
- this.getVarListCode( this.inputs.uniforms[ shader ], 'uniform' ),
|
|
|
- this.getIncludesCode( 'consts', shader ),
|
|
|
- this.getIncludesCode( 'structs', shader ),
|
|
|
- this.getIncludesCode( 'functions', shader ),
|
|
|
- 'void main() {',
|
|
|
- this.getVarListCode( this.getVars( shader ) ),
|
|
|
- this.code[ shader ],
|
|
|
- this.resultCode[ shader ],
|
|
|
- this.finalCode[ shader ],
|
|
|
- '}'
|
|
|
- ].join( '\n' );
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- getVarListCode( vars, prefix = '' ) {
|
|
|
-
|
|
|
- let code = '';
|
|
|
-
|
|
|
- for ( let i = 0, l = vars.length; i < l; ++ i ) {
|
|
|
-
|
|
|
- const nVar = vars[ i ],
|
|
|
- type = nVar.type,
|
|
|
- name = nVar.name;
|
|
|
-
|
|
|
- const formatType = this.getFormatByType( type );
|
|
|
-
|
|
|
- if ( formatType === undefined ) {
|
|
|
-
|
|
|
- throw new Error( 'Node pars not found.' );
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- code += prefix + ' ' + formatType + ' ' + name + ';\n';
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- return code;
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- getVars( shader ) {
|
|
|
-
|
|
|
- return this.inputs.vars[ shader || this.shader ];
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- getNodeData( node ) {
|
|
|
-
|
|
|
- const uuid = node.isNode ? node.uuid : node;
|
|
|
-
|
|
|
- return this.nodeData[ uuid ] = this.nodeData[ uuid ] || {};
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- createUniform( shader, type, node, ns, needsUpdate, label ) {
|
|
|
-
|
|
|
- const uniforms = this.inputs.uniforms,
|
|
|
- index = uniforms.list.length;
|
|
|
-
|
|
|
- const uniform = new NodeUniform( {
|
|
|
- type: type,
|
|
|
- name: ns ? ns : 'nodeU' + index + ( label ? '_' + label : '' ),
|
|
|
- node: node,
|
|
|
- needsUpdate: needsUpdate
|
|
|
- } );
|
|
|
-
|
|
|
- uniforms.list.push( uniform );
|
|
|
-
|
|
|
- uniforms[ shader ].push( uniform );
|
|
|
- uniforms[ shader ][ uniform.name ] = uniform;
|
|
|
-
|
|
|
- this.uniforms[ uniform.name ] = uniform;
|
|
|
-
|
|
|
- return uniform;
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- createVertexUniform( type, node, ns, needsUpdate, label ) {
|
|
|
-
|
|
|
- return this.createUniform( 'vertex', type, node, ns, needsUpdate, label );
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- createFragmentUniform( type, node, ns, needsUpdate, label ) {
|
|
|
-
|
|
|
- return this.createUniform( 'fragment', type, node, ns, needsUpdate, label );
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- include( node, parent, source ) {
|
|
|
-
|
|
|
- let includesStruct;
|
|
|
-
|
|
|
- node = typeof node === 'string' ? NodeLib.get( node ) : node;
|
|
|
-
|
|
|
- if ( this.context.include === false ) {
|
|
|
-
|
|
|
- return node.name;
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
- if ( node instanceof FunctionNode ) {
|
|
|
-
|
|
|
- includesStruct = this.includes.functions;
|
|
|
-
|
|
|
- } else if ( node instanceof ConstNode ) {
|
|
|
-
|
|
|
- includesStruct = this.includes.consts;
|
|
|
-
|
|
|
- } else if ( node instanceof StructNode ) {
|
|
|
-
|
|
|
- includesStruct = this.includes.structs;
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- const includes = includesStruct[ this.shader ] = includesStruct[ this.shader ] || [];
|
|
|
-
|
|
|
- if ( node ) {
|
|
|
-
|
|
|
- let included = includes[ node.name ];
|
|
|
-
|
|
|
- if ( ! included ) {
|
|
|
-
|
|
|
- included = includes[ node.name ] = {
|
|
|
- node: node,
|
|
|
- deps: []
|
|
|
- };
|
|
|
-
|
|
|
- includes.push( included );
|
|
|
-
|
|
|
- included.src = node.build( this, 'source' );
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- if ( node instanceof FunctionNode && parent && includes[ parent.name ] && includes[ parent.name ].deps.indexOf( node ) == - 1 ) {
|
|
|
-
|
|
|
- includes[ parent.name ].deps.push( node );
|
|
|
-
|
|
|
- if ( node.includes && node.includes.length ) {
|
|
|
-
|
|
|
- let i = 0;
|
|
|
-
|
|
|
- do {
|
|
|
-
|
|
|
- this.include( node.includes[ i ++ ], parent );
|
|
|
-
|
|
|
- } while ( i < node.includes.length );
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- if ( source ) {
|
|
|
-
|
|
|
- included.src = source;
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- return node.name;
|
|
|
-
|
|
|
- } else {
|
|
|
-
|
|
|
- throw new Error( 'Include not found.' );
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- colorToVectorProperties( color ) {
|
|
|
-
|
|
|
- return color.replace( 'r', 'x' ).replace( 'g', 'y' ).replace( 'b', 'z' ).replace( 'a', 'w' );
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- colorToVector( color ) {
|
|
|
-
|
|
|
- return color.replace( /c/g, 'v3' );
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- getIncludes( type, shader ) {
|
|
|
-
|
|
|
- return this.includes[ type ][ shader || this.shader ];
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- getIncludesCode( type, shader ) {
|
|
|
-
|
|
|
- let includes = this.getIncludes( type, shader );
|
|
|
-
|
|
|
- if ( ! includes ) return '';
|
|
|
-
|
|
|
- let code = '';
|
|
|
-
|
|
|
- includes = includes.sort( sortByPosition );
|
|
|
-
|
|
|
- for ( let i = 0; i < includes.length; i ++ ) {
|
|
|
-
|
|
|
- if ( includes[ i ].src ) code += includes[ i ].src + '\n';
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- return code;
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- getConstructorFromLength( len ) {
|
|
|
-
|
|
|
- return constructors[ len - 1 ];
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- isTypeMatrix( format ) {
|
|
|
-
|
|
|
- return /^m/.test( format );
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- getTypeLength( type ) {
|
|
|
-
|
|
|
- if ( type === 'f' ) return 1;
|
|
|
-
|
|
|
- return parseInt( this.colorToVector( type ).substr( 1 ) );
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- getTypeFromLength( len ) {
|
|
|
-
|
|
|
- if ( len === 1 ) return 'f';
|
|
|
-
|
|
|
- return 'v' + len;
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- findNode() {
|
|
|
-
|
|
|
- for ( let i = 0; i < arguments.length; i ++ ) {
|
|
|
-
|
|
|
- const nodeCandidate = arguments[ i ];
|
|
|
-
|
|
|
- if ( nodeCandidate !== undefined && nodeCandidate.isNode ) {
|
|
|
-
|
|
|
- return nodeCandidate;
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- resolve() {
|
|
|
-
|
|
|
- for ( let i = 0; i < arguments.length; i ++ ) {
|
|
|
-
|
|
|
- const nodeCandidate = arguments[ i ];
|
|
|
-
|
|
|
- if ( nodeCandidate !== undefined ) {
|
|
|
-
|
|
|
- if ( nodeCandidate.isNode ) {
|
|
|
-
|
|
|
- return nodeCandidate;
|
|
|
-
|
|
|
- } else if ( nodeCandidate.isTexture ) {
|
|
|
-
|
|
|
- switch ( nodeCandidate.mapping ) {
|
|
|
-
|
|
|
- case CubeReflectionMapping:
|
|
|
- case CubeRefractionMapping:
|
|
|
-
|
|
|
- return new CubeTextureNode( nodeCandidate );
|
|
|
-
|
|
|
- break;
|
|
|
-
|
|
|
- case CubeUVReflectionMapping:
|
|
|
- case CubeUVRefractionMapping:
|
|
|
-
|
|
|
- return new TextureCubeNode( new TextureNode( nodeCandidate ) );
|
|
|
-
|
|
|
- break;
|
|
|
-
|
|
|
- default:
|
|
|
-
|
|
|
- return new TextureNode( nodeCandidate );
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- } else if ( nodeCandidate.isVector2 ) {
|
|
|
-
|
|
|
- return new Vector2Node( nodeCandidate );
|
|
|
-
|
|
|
- } else if ( nodeCandidate.isVector3 ) {
|
|
|
-
|
|
|
- return new Vector3Node( nodeCandidate );
|
|
|
-
|
|
|
- } else if ( nodeCandidate.isVector4 ) {
|
|
|
-
|
|
|
- return new Vector4Node( nodeCandidate );
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- format( code, from, to ) {
|
|
|
-
|
|
|
- const typeToType = this.colorToVector( to + ' <- ' + from );
|
|
|
-
|
|
|
- switch ( typeToType ) {
|
|
|
-
|
|
|
- case 'f <- v2' : return code + '.x';
|
|
|
- case 'f <- v3' : return code + '.x';
|
|
|
- case 'f <- v4' : return code + '.x';
|
|
|
- case 'f <- i' :
|
|
|
- case 'f <- b' : return 'float( ' + code + ' )';
|
|
|
-
|
|
|
- case 'v2 <- f' : return 'vec2( ' + code + ' )';
|
|
|
- case 'v2 <- v3': return code + '.xy';
|
|
|
- case 'v2 <- v4': return code + '.xy';
|
|
|
- case 'v2 <- i' :
|
|
|
- case 'v2 <- b' : return 'vec2( float( ' + code + ' ) )';
|
|
|
-
|
|
|
- case 'v3 <- f' : return 'vec3( ' + code + ' )';
|
|
|
- case 'v3 <- v2': return 'vec3( ' + code + ', 0.0 )';
|
|
|
- case 'v3 <- v4': return code + '.xyz';
|
|
|
- case 'v3 <- i' :
|
|
|
- case 'v3 <- b' : return 'vec2( float( ' + code + ' ) )';
|
|
|
-
|
|
|
- case 'v4 <- f' : return 'vec4( ' + code + ' )';
|
|
|
- case 'v4 <- v2': return 'vec4( ' + code + ', 0.0, 1.0 )';
|
|
|
- case 'v4 <- v3': return 'vec4( ' + code + ', 1.0 )';
|
|
|
- case 'v4 <- i' :
|
|
|
- case 'v4 <- b' : return 'vec4( float( ' + code + ' ) )';
|
|
|
-
|
|
|
- case 'i <- f' :
|
|
|
- case 'i <- b' : return 'int( ' + code + ' )';
|
|
|
- case 'i <- v2' : return 'int( ' + code + '.x )';
|
|
|
- case 'i <- v3' : return 'int( ' + code + '.x )';
|
|
|
- case 'i <- v4' : return 'int( ' + code + '.x )';
|
|
|
-
|
|
|
- case 'b <- f' : return '( ' + code + ' != 0.0 )';
|
|
|
- case 'b <- v2' : return '( ' + code + ' != vec2( 0.0 ) )';
|
|
|
- case 'b <- v3' : return '( ' + code + ' != vec3( 0.0 ) )';
|
|
|
- case 'b <- v4' : return '( ' + code + ' != vec4( 0.0 ) )';
|
|
|
- case 'b <- i' : return '( ' + code + ' != 0 )';
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- return code;
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- getTypeByFormat( format ) {
|
|
|
-
|
|
|
- return convertFormatToType[ format ] || format;
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- getFormatByType( type ) {
|
|
|
-
|
|
|
- return convertTypeToFormat[ type ] || type;
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- getUuid( uuid, useCache ) {
|
|
|
-
|
|
|
- useCache = useCache !== undefined ? useCache : true;
|
|
|
-
|
|
|
- if ( useCache && this.cache ) uuid = this.cache + '-' + uuid;
|
|
|
-
|
|
|
- return uuid;
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- getElementByIndex( index ) {
|
|
|
-
|
|
|
- return elements[ index ];
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- getIndexByElement( elm ) {
|
|
|
-
|
|
|
- return elements.indexOf( elm );
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- isShader( shader ) {
|
|
|
-
|
|
|
- return this.shader === shader;
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- setShader( shader ) {
|
|
|
-
|
|
|
- this.shader = shader;
|
|
|
-
|
|
|
- return this;
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- mergeDefines( defines ) {
|
|
|
-
|
|
|
- for ( const name in defines ) {
|
|
|
-
|
|
|
- this.defines[ name ] = defines[ name ];
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- return this.defines;
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- mergeUniform( uniforms ) {
|
|
|
-
|
|
|
- for ( const name in uniforms ) {
|
|
|
-
|
|
|
- this.uniforms[ name ] = uniforms[ name ];
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- return this.uniforms;
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- getTextureEncodingFromMap( map ) {
|
|
|
-
|
|
|
- let encoding;
|
|
|
-
|
|
|
- if ( ! map ) {
|
|
|
-
|
|
|
- encoding = LinearEncoding;
|
|
|
-
|
|
|
- } else if ( map.isTexture ) {
|
|
|
-
|
|
|
- encoding = map.encoding;
|
|
|
-
|
|
|
- } else if ( map.isWebGLRenderTarget ) {
|
|
|
-
|
|
|
- console.warn( 'THREE.WebGLPrograms.getTextureEncodingFromMap: don\'t use render targets as textures. Use their .texture property instead.' );
|
|
|
- encoding = map.texture.encoding;
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- if ( encoding === LinearEncoding && this.context.gamma ) {
|
|
|
-
|
|
|
- encoding = sRGBEncoding;
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- return encoding;
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
-}
|
|
|
-
|
|
|
-function sortByPosition( a, b ) {
|
|
|
-
|
|
|
- return a.deps.length - b.deps.length;
|
|
|
-
|
|
|
-}
|
|
|
-
|
|
|
-export { NodeBuilder };
|