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.
970 lines
16 KiB
970 lines
16 KiB
import {
|
|
CubeReflectionMapping,
|
|
CubeRefractionMapping,
|
|
CubeUVReflectionMapping,
|
|
CubeUVRefractionMapping,
|
|
LinearEncoding,
|
|
GammaEncoding
|
|
} from '../../../../build/three.module.js';
|
|
|
|
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 ' + formatType + ' 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 = GammaEncoding;
|
|
|
|
}
|
|
|
|
return encoding;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
function sortByPosition( a, b ) {
|
|
|
|
return a.deps.length - b.deps.length;
|
|
|
|
}
|
|
|
|
export { NodeBuilder };
|
|
|