diff --git a/examples/js/materials/nodes/BuilderNode.js b/examples/js/materials/nodes/BuilderNode.js index 5872c444740ea07d81152f69aecf8d4cb1993f63..01349b2eee8ec87a24f9392fc4642aeebe44780c 100644 --- a/examples/js/materials/nodes/BuilderNode.js +++ b/examples/js/materials/nodes/BuilderNode.js @@ -3,122 +3,122 @@ */ THREE.BuilderNode = function( material ) { - + this.material = material; - + this.require = {}; this.isVerify = false; this.cache = ''; - + }; THREE.BuilderNode.prototype = { constructor: THREE.BuilderNode, - include : function ( func ) { - + include : function( func ) { + this.material.include( this.shader, func ); }, - - getFormatConstructor : function ( len ) { - - return THREE.BuilderNode.constructors[len-1]; - + + getFormatConstructor : function( len ) { + + return THREE.BuilderNode.constructors[ len - 1 ]; + }, - - getFormat : function ( format ) { - - return format.replace('c','v3').replace(/fv1|iv1/, 'v1'); - + + getFormat : function( format ) { + + return format.replace( 'c', 'v3' ).replace( /fv1|iv1/, 'v1' ); + }, - - getFormatLength : function ( format ) { - - return parseInt( this.getFormat(format).substr(1) ); - + + getFormatLength : function( format ) { + + return parseInt( this.getFormat( format ).substr( 1 ) ); + }, - - getFormatByLength : function ( len ) { - - if (len == 1) return 'fv1'; - + + getFormatByLength : function( len ) { + + if ( len == 1 ) return 'fv1'; + return 'v' + len; - + }, - - format : function ( code, from, to ) { - - var format = this.getFormat(from + '=' + to); - + + format : function( code, from, to ) { + + var format = this.getFormat( from + '=' + to ); + switch ( format ) { case 'v1=v2': return 'vec2(' + code + ')'; case 'v1=v3': return 'vec3(' + code + ')'; case 'v1=v4': return 'vec4(' + code + ')'; - + case 'v2=v1': return code + '.x'; case 'v2=v3': return 'vec3(' + code + ',0.0)'; case 'v2=v4': return 'vec4(' + code + ',0.0,0.0)'; - + case 'v3=v1': return code + '.x'; case 'v3=v2': return code + '.xy'; case 'v3=v4': return 'vec4(' + code + ',0.0)'; - + case 'v4=v1': return code + '.x'; case 'v4=v2': return code + '.xy'; case 'v4=v3': return code + '.xyz'; } - + return code; - + }, - - getType : function ( format ) { - + + getType : function( format ) { + return THREE.BuilderNode.type[ format ]; - + }, - - getUuid : function ( uuid, useCache ) { - + + getUuid : function( uuid, useCache ) { + useCache = useCache !== undefined ? useCache : true; - - if (useCache && this.cache) uuid = this.cache + '-' + uuid; - + + if ( useCache && this.cache ) uuid = this.cache + '-' + uuid; + return uuid; }, - - setCache : function ( name ) { - + + setCache : function( name ) { + this.cache = name || ''; - + return this; }, - - getElementByIndex : function ( index ) { - + + getElementByIndex : function( index ) { + return THREE.BuilderNode.elements[ index ]; - + }, - - getElementIndex : function ( elm ) { - + + getElementIndex : function( elm ) { + return THREE.BuilderNode.elements.indexOf( elm ); - + }, - - isShader : function ( shader ) { - + + isShader : function( shader ) { + return this.shader == shader || this.isVerify; }, - - setShader : function ( shader ) { - + + setShader : function( shader ) { + this.shader = shader; - + return this; } @@ -132,15 +132,15 @@ THREE.BuilderNode.type = { }; THREE.BuilderNode.constructors = [ - '', - 'vec2', - 'vec3', + '', + 'vec2', + 'vec3', 'vec4' ]; THREE.BuilderNode.elements = [ - 'x', - 'y', - 'z', + 'x', + 'y', + 'z', 'w' -]; \ No newline at end of file +]; diff --git a/examples/js/materials/nodes/ConstNode.js b/examples/js/materials/nodes/ConstNode.js index cfe8d55d2d60dbf92be2f51561031b39f6ee809e..3b30d417149d8ea805a0b8947196bba7ea2460d6 100644 --- a/examples/js/materials/nodes/ConstNode.js +++ b/examples/js/materials/nodes/ConstNode.js @@ -2,37 +2,37 @@ * @author sunag / http://www.sunag.com.br/ */ -THREE.ConstNode = function(name, useDefine) { - +THREE.ConstNode = function( name, useDefine ) { + name = name || THREE.ConstNode.PI; - + var rDeclaration = /^([a-z_0-9]+)\s([a-z_0-9]+)\s?\=(.*?)\;/i; var type = 'fv1'; - + var match = name.match( rDeclaration ); - - if (match && match.length > 1) { - - type = match[1]; - name = match[2]; - - if (useDefine) { - - this.src = '#define ' + name + ' ' + match[3]; - + + if ( match && match.length > 1 ) { + + type = match[ 1 ]; + name = match[ 2 ]; + + if ( useDefine ) { + + this.src = '#define ' + name + ' ' + match[ 3 ]; + } else { - - this.src = 'const ' + type + ' ' + name + ' = ' + match[3] + ';'; - + + this.src = 'const ' + type + ' ' + name + ' = ' + match[ 3 ] + ';'; + } - + } - + this.name = name; - + THREE.TempNode.call( this, type ); - + }; THREE.ConstNode.prototype = Object.create( THREE.TempNode.prototype ); @@ -46,7 +46,7 @@ THREE.ConstNode.LOG2 = 'LOG2'; THREE.ConstNode.EPSILON = 'EPSILON'; THREE.ConstNode.prototype.generate = function( builder, output ) { - + return builder.format( this.name, this.getType( builder ), output ); -}; \ No newline at end of file +}; diff --git a/examples/js/materials/nodes/FunctionCallNode.js b/examples/js/materials/nodes/FunctionCallNode.js index 97b5389697d4bc2844bc6f04513df4715ee019c4..89f070d8a3008be255abf811be935585d425c762 100644 --- a/examples/js/materials/nodes/FunctionCallNode.js +++ b/examples/js/materials/nodes/FunctionCallNode.js @@ -3,58 +3,58 @@ */ THREE.FunctionCallNode = function( value ) { - + THREE.TempNode.call( this ); - + this.setFunction( value ); - + }; THREE.FunctionCallNode.prototype = Object.create( THREE.TempNode.prototype ); THREE.FunctionCallNode.prototype.constructor = THREE.FunctionCallNode; -THREE.FunctionCallNode.prototype.setFunction = function(val) { - +THREE.FunctionCallNode.prototype.setFunction = function( val ) { + this.input = []; this.value = val; - + }; THREE.FunctionCallNode.prototype.getFunction = function() { - + return this.value; - + }; THREE.FunctionCallNode.prototype.getType = function( builder ) { - + return this.value.getType( builder ); - + }; THREE.FunctionCallNode.prototype.generate = function( builder, output ) { - + var material = builder.material; - + var type = this.getType( builder ); var func = this.value; - + builder.include( func ); - + var code = func.name + '('; var params = []; - - for(var i = 0; i < func.input.length; i++) { - - var inpt = func.input[i]; - var param = this.input[i] || this.input[inpt.name]; - + + for ( var i = 0; i < func.input.length; i ++ ) { + + var inpt = func.input[ i ]; + var param = this.input[ i ] || this.input[ inpt.name ]; + params.push( param.build( builder, builder.getType( inpt.type ) ) ); - + } - - code += params.join(',') + ')'; - + + code += params.join( ',' ) + ')'; + return builder.format( code, type, output ); }; diff --git a/examples/js/materials/nodes/FunctionNode.js b/examples/js/materials/nodes/FunctionNode.js index cf6768a1a027fb7d53c735c7e10821a3c8f460ab..d1342d7ccf68598300357a63dc75d57d994e6485 100644 --- a/examples/js/materials/nodes/FunctionNode.js +++ b/examples/js/materials/nodes/FunctionNode.js @@ -4,21 +4,21 @@ */ THREE.FunctionNode = function( src, includes, extensions ) { - + THREE.GLNode.call( this ); - + this.parse( src || '', includes, extensions ); - + }; THREE.FunctionNode.prototype = Object.create( THREE.GLNode.prototype ); THREE.FunctionNode.prototype.constructor = THREE.FunctionNode; THREE.FunctionNode.prototype.parseReference = function( name ) { - - switch(name) { + + switch ( name ) { case 'uv': return new THREE.UVNode().name; - case 'uv2': return new THREE.UVNode(1).name; + case 'uv2': return new THREE.UVNode( 1 ).name; case 'position': return new THREE.PositionNode().name; case 'worldPosition': return new THREE.PositionNode( THREE.PositionNode.WORLD ).name; case 'normal': return new THREE.NormalNode().name; @@ -26,9 +26,9 @@ THREE.FunctionNode.prototype.parseReference = function( name ) { case 'viewPosition': return new THREE.PositionNode( THREE.NormalNode.VIEW ).name; case 'viewNormal': return new THREE.NormalNode( THREE.NormalNode.VIEW ).name; } - + return name; - + }; THREE.FunctionNode.prototype.getTypeNode = function( builder, type ) { @@ -38,120 +38,122 @@ THREE.FunctionNode.prototype.getTypeNode = function( builder, type ) { }; THREE.FunctionNode.prototype.getInputByName = function( name ) { - + var i = this.input.length; - - while(i--) { - - if (this.input[i].name === name) - return this.input[i]; - + + while ( i -- ) { + + if ( this.input[ i ].name === name ) + return this.input[ i ]; + } - + }; THREE.FunctionNode.prototype.getType = function( builder ) { - + return this.getTypeNode( builder, this.type ); - + }; THREE.FunctionNode.prototype.getInclude = function( name ) { - + var i = this.includes.length; - - while(i--) { - - if (this.includes[i].name === name) - return this.includes[i]; - + + while ( i -- ) { + + if ( this.includes[ i ].name === name ) + return this.includes[ i ]; + } - + return undefined; - + }; THREE.FunctionNode.prototype.parse = function( src, includes, extensions ) { - + var rDeclaration = /^([a-z_0-9]+)\s([a-z_0-9]+)\s?\((.*?)\)/i; var rProperties = /[a-z_0-9]+/ig; - + this.includes = includes || []; this.extensions = extensions || {}; - + var match = src.match( rDeclaration ); - + this.input = []; - - if (match && match.length == 4) { - - this.type = match[1]; - this.name = match[2]; - - var inputs = match[3].match( rProperties ); - - if (inputs) { - + + if ( match && match.length == 4 ) { + + this.type = match[ 1 ]; + this.name = match[ 2 ]; + + var inputs = match[ 3 ].match( rProperties ); + + if ( inputs ) { + var i = 0; - - while(i < inputs.length) { - - var qualifier = inputs[i++]; + + while ( i < inputs.length ) { + + var qualifier = inputs[ i ++ ]; var type, name; - - if (qualifier == 'in' || qualifier == 'out' || qualifier == 'inout') { - - type = inputs[i++]; - + + if ( qualifier == 'in' || qualifier == 'out' || qualifier == 'inout' ) { + + type = inputs[ i ++ ]; + } else { - + type = qualifier; qualifier = ''; - + } - - name = inputs[i++]; - - this.input.push({ + + name = inputs[ i ++ ]; + + this.input.push( { name : name, type : type, qualifier : qualifier - }); + } ); + } - + } var match, offset = 0; - - while (match = rProperties.exec(src)) { - - var prop = match[0]; + + while ( match = rProperties.exec( src ) ) { + + var prop = match[ 0 ]; var reference = this.parseReference( prop ); - - if (prop != reference) { - - src = src.substring( 0, match.index + offset ) + reference + src.substring( match.index + prop.length + offset ); - + + if ( prop != reference ) { + + src = src.substring( 0, match.index + offset ) + reference + src.substring( match.index + prop.length + offset ); + offset += reference.length - prop.length; - + } - - if (this.getInclude(reference) === undefined && THREE.LibNode.contains(reference)) { - - this.includes.push( THREE.LibNode.get(reference) ); - + + if ( this.getInclude( reference ) === undefined && THREE.LibNode.contains( reference ) ) { + + this.includes.push( THREE.LibNode.get( reference ) ); + } - + } - + this.src = src; } else { - + this.type = ''; this.name = ''; - + } -}; \ No newline at end of file + +}; diff --git a/examples/js/materials/nodes/GLNode.js b/examples/js/materials/nodes/GLNode.js index 8462fb6ce2c3c8441f9d4977adfd84cbf3fbe17a..7591ae2b96d96cc8613f7e5347b6c47677799b2b 100644 --- a/examples/js/materials/nodes/GLNode.js +++ b/examples/js/materials/nodes/GLNode.js @@ -3,66 +3,66 @@ */ THREE.GLNode = function( type ) { - + this.uuid = THREE.Math.generateUUID(); - + this.allow = {}; this.requestUpdate = false; - + this.type = type; - + }; THREE.GLNode.prototype.verify = function( builder ) { - + builder.isVerify = true; - + var material = builder.material; - + this.build( builder, 'v4' ); - + material.clearVertexNode(); material.clearFragmentNode(); - + builder.setCache(); // reset cache - + builder.isVerify = false; }; THREE.GLNode.prototype.verifyAndBuildCode = function( builder, output, cache ) { - - this.verify( builder.setCache(cache) ); - - return this.buildCode( builder.setCache(cache), output ); - + + this.verify( builder.setCache( cache ) ); + + return this.buildCode( builder.setCache( cache ), output ); + }; THREE.GLNode.prototype.buildCode = function( builder, output, uuid ) { - + var material = builder.material; var data = { result : this.build( builder, output, uuid ) }; - - if (builder.isShader('vertex')) data.code = material.clearVertexNode(); + + if ( builder.isShader( 'vertex' ) ) data.code = material.clearVertexNode(); else data.code = material.clearFragmentNode(); - + builder.setCache(); // reset cache - + return data; }; THREE.GLNode.prototype.verifyDepsNode = function( builder, data, output ) { - - data.deps = (data.deps || 0) + 1; - + + data.deps = ( data.deps || 0 ) + 1; + var outputLen = builder.getFormatLength( output ); - - if (outputLen > data.outputMax || this.getType( builder )) { - + + if ( outputLen > data.outputMax || this.getType( builder ) ) { + data.outputMax = outputLen; data.output = output; - + } }; @@ -71,24 +71,28 @@ THREE.GLNode.prototype.build = function( builder, output, uuid ) { var material = builder.material; var data = material.getDataNode( uuid || this.uuid ); - - if (builder.isShader('verify')) this.verifyDepsNode( builder, data, output ); - - if (this.allow[builder.shader] === false) { + + if ( builder.isShader( 'verify' ) ) this.verifyDepsNode( builder, data, output ); + + if ( this.allow[ builder.shader ] === false ) { + throw new Error( 'Shader ' + shader + ' is not compatible with this node.' ); + } - - if (this.requestUpdate && !data.requestUpdate) { + + if ( this.requestUpdate && ! data.requestUpdate ) { + material.requestUpdate.push( this ); data.requestUpdate = true; + } - + return this.generate( builder, output, uuid ); - + }; THREE.GLNode.prototype.getType = function( builder ) { return this.type; - -}; \ No newline at end of file + +}; diff --git a/examples/js/materials/nodes/InputNode.js b/examples/js/materials/nodes/InputNode.js index c3ad3c6d0d6d2cef74ef74cc8bf39673ade0c6ae..79f02be4a6824c7342542ee8e943b9ebdef420fb 100644 --- a/examples/js/materials/nodes/InputNode.js +++ b/examples/js/materials/nodes/InputNode.js @@ -2,10 +2,10 @@ * @author sunag / http://www.sunag.com.br/ */ -THREE.InputNode = function(type, params) { - +THREE.InputNode = function( type, params ) { + THREE.TempNode.call( this, type, params ); - + }; THREE.InputNode.prototype = Object.create( THREE.TempNode.prototype ); @@ -17,28 +17,30 @@ THREE.InputNode.prototype.generate = function( builder, output, uuid, type ) { uuid = builder.getUuid( uuid || this.uuid ); type = type || this.type; - + var data = material.getDataNode( uuid ); - - if (builder.isShader('vertex')) { - - if (!data.vertex) { - + + if ( builder.isShader( 'vertex' ) ) { + + if ( ! data.vertex ) { + data.vertex = material.getVertexUniform( this.value, type ); - + } - + return builder.format( data.vertex.name, type, output ); + } else { - - if (!data.fragment) { - + + if ( ! data.fragment ) { + data.fragment = material.getFragmentUniform( this.value, type ); - + } - + return builder.format( data.fragment.name, type, output ); + } -}; \ No newline at end of file +}; diff --git a/examples/js/materials/nodes/LibNode.js b/examples/js/materials/nodes/LibNode.js index 7af93fe79af02b9ffa3b40b5b46091095ce0db53..a4bf8648edfb24f64bf53e862147f1cbfc488b0d 100644 --- a/examples/js/materials/nodes/LibNode.js +++ b/examples/js/materials/nodes/LibNode.js @@ -3,18 +3,26 @@ */ THREE.LibNode = { - nodes:{}, - add:function(node) { - this.nodes[node.name] = node; + nodes: {}, + add: function( node ) { + + this.nodes[ node.name ] = node; + }, - remove:function(node) { - delete this.nodes[node.name]; + remove: function( node ) { + + delete this.nodes[ node.name ]; + }, - get:function(name) { - return this.nodes[name]; + get: function( name ) { + + return this.nodes[ name ]; + }, - contains:function(name) { - return this.nodes[name] != undefined; + contains: function( name ) { + + return this.nodes[ name ] != undefined; + } }; @@ -22,13 +30,13 @@ THREE.LibNode = { // Luma // -THREE.LibNode.add(new THREE.ConstNode("vec3 LUMA = vec3(0.2125, 0.7154, 0.0721);") ); +THREE.LibNode.add( new THREE.ConstNode( "vec3 LUMA = vec3(0.2125, 0.7154, 0.0721);" ) ); // // DepthColor // - -THREE.LibNode.add(new THREE.FunctionNode([ + +THREE.LibNode.add( new THREE.FunctionNode( [ "float depthcolor( float mNear, float mFar ) {", "#ifdef USE_LOGDEPTHBUF_EXT", @@ -36,16 +44,16 @@ THREE.LibNode.add(new THREE.FunctionNode([ "#else", "float depth = gl_FragCoord.z / gl_FragCoord.w;", "#endif", - + "return 1.0 - smoothstep( mNear, mFar, depth );", "}" -].join( "\n" ))); +].join( "\n" ) ) ); // // NormalMap // - -THREE.LibNode.add(new THREE.FunctionNode([ + +THREE.LibNode.add( new THREE.FunctionNode( [ // Per-Pixel Tangent Space Normal Mapping // http://hacksoflife.blogspot.ch/2009/11/per-pixel-tangent-space-normal-mapping.html "vec3 perturbNormal2Arb( vec3 eye_pos, vec3 surf_norm, vec3 map, vec2 mUv, float scale ) {", @@ -61,27 +69,27 @@ THREE.LibNode.add(new THREE.FunctionNode([ "mat3 tsn = mat3( S, T, N );", "return normalize( tsn * mapN );", "}" -].join( "\n" ), null, {derivatives:true})); +].join( "\n" ), null, { derivatives: true } ) ); // // Saturation // -THREE.LibNode.add(new THREE.FunctionNode([ +THREE.LibNode.add( new THREE.FunctionNode( [ // Algorithm from Chapter 16 of OpenGL Shading Language "vec3 saturation_rgb(vec3 rgb, float adjustment) {", "vec3 intensity = vec3(dot(rgb, LUMA));", "return mix(intensity, rgb, adjustment);", "}" -].join( "\n" ))); +].join( "\n" ) ) ); // // Luminance // -THREE.LibNode.add(new THREE.FunctionNode([ +THREE.LibNode.add( new THREE.FunctionNode( [ // Algorithm from Chapter 10 of Graphics Shaders. "float luminance_rgb(vec3 rgb) {", "return dot(rgb, LUMA);", "}" -].join( "\n" ))); \ No newline at end of file +].join( "\n" ) ) ); diff --git a/examples/js/materials/nodes/NodeMaterial.js b/examples/js/materials/nodes/NodeMaterial.js index d06080869187732f3efec95b98ad02eea8e9752e..e2622c29102fa3ba4dca12bb9f044d47b7c67652 100644 --- a/examples/js/materials/nodes/NodeMaterial.js +++ b/examples/js/materials/nodes/NodeMaterial.js @@ -3,12 +3,12 @@ */ THREE.NodeMaterial = function( vertex, fragment ) { - + THREE.ShaderMaterial.call( this ); - + this.vertex = vertex || new THREE.RawNode( new THREE.PositionNode( THREE.PositionNode.PROJECTION ) ); this.fragment = fragment || new THREE.RawNode( new THREE.ColorNode( 0xFF0000 ) ); - + }; THREE.NodeMaterial.prototype = Object.create( THREE.ShaderMaterial.prototype ); @@ -27,168 +27,176 @@ THREE.NodeMaterial.Type = { }; THREE.NodeMaterial.GetShortcuts = function( prop, name ) { - + return { - get: function () { return this[prop][name]; }, - set: function ( val ) { this[prop][name] = val; } + get: function() { + + return this[ prop ][ name ]; + + }, + set: function( val ) { + + this[ prop ][ name ] = val; + + } }; }; THREE.NodeMaterial.Shortcuts = function( proto, prop, list ) { - + var shortcuts = {}; - - for(var i = 0; i < list.length; ++i) { - - var name = list[i]; - - shortcuts[name] = this.GetShortcuts( prop, name ); - + + for ( var i = 0; i < list.length; ++ i ) { + + var name = list[ i ]; + + shortcuts[ name ] = this.GetShortcuts( prop, name ); + } - + Object.defineProperties( proto, shortcuts ); }; THREE.NodeMaterial.prototype.updateAnimation = function( delta ) { - - for(var i = 0; i < this.requestUpdate.length; ++i) { - this.requestUpdate[i].updateAnimation( delta ); - + for ( var i = 0; i < this.requestUpdate.length; ++ i ) { + + this.requestUpdate[ i ].updateAnimation( delta ); + } - + }; THREE.NodeMaterial.prototype.build = function() { - + var vertex, fragment; - + this.defines = {}; - this.uniforms = {}; - - this.nodeData = {}; - + this.uniforms = {}; + + this.nodeData = {}; + this.vertexUniform = []; this.fragmentUniform = []; - + this.vertexTemps = []; this.fragmentTemps = []; - + this.uniformList = []; - + this.consts = []; this.functions = []; - + this.requestUpdate = []; - + this.requestAttrib = { - uv:[], - color:[] + uv: [], + color: [] }; - + this.needsColor = false; this.needsLight = false; this.needsPosition = false; this.needsTransparent = false; - + this.vertexPars = ''; this.fragmentPars = ''; - + this.vertexCode = ''; this.fragmentCode = ''; - + this.vertexNode = ''; this.fragmentNode = ''; - - var builder = new THREE.BuilderNode(this); - - vertex = this.vertex.build( builder.setShader('vertex'), 'v4' ); - fragment = this.fragment.build( builder.setShader('fragment'), 'v4' ); - - if (this.requestAttrib.uv[0]) { - + + var builder = new THREE.BuilderNode( this ); + + vertex = this.vertex.build( builder.setShader( 'vertex' ), 'v4' ); + fragment = this.fragment.build( builder.setShader( 'fragment' ), 'v4' ); + + if ( this.requestAttrib.uv[ 0 ] ) { + this.addVertexPars( 'varying vec2 vUv;' ); this.addFragmentPars( 'varying vec2 vUv;' ); - + this.addVertexCode( 'vUv = uv;' ); - + } - - if (this.requestAttrib.uv[1]) { - + + if ( this.requestAttrib.uv[ 1 ] ) { + this.addVertexPars( 'varying vec2 vUv2; attribute vec2 uv2;' ); this.addFragmentPars( 'varying vec2 vUv2;' ); - + this.addVertexCode( 'vUv2 = uv2;' ); - + } - - if (this.requestAttrib.color[0]) { + + if ( this.requestAttrib.color[ 0 ] ) { this.addVertexPars( 'varying vec4 vColor; attribute vec4 color;' ); this.addFragmentPars( 'varying vec4 vColor;' ); - + this.addVertexCode( 'vColor = color;' ); - + } - - if (this.requestAttrib.color[1]) { + + if ( this.requestAttrib.color[ 1 ] ) { this.addVertexPars( 'varying vec4 vColor2; attribute vec4 color2;' ); this.addFragmentPars( 'varying vec4 vColor2;' ); - + this.addVertexCode( 'vColor2 = color2;' ); - + } - - if (this.requestAttrib.position) { + + if ( this.requestAttrib.position ) { this.addVertexPars( 'varying vec3 vPosition;' ); this.addFragmentPars( 'varying vec3 vPosition;' ); - + this.addVertexCode( 'vPosition = transformed;' ); - + } - - if (this.requestAttrib.worldPosition) { - + + if ( this.requestAttrib.worldPosition ) { + // for future update replace from the native "varying vec3 vWorldPosition" for optimization - + this.addVertexPars( 'varying vec3 vWPosition;' ); this.addFragmentPars( 'varying vec3 vWPosition;' ); - + this.addVertexCode( 'vWPosition = worldPosition.xyz;' ); } - - if (this.requestAttrib.normal) { + + if ( this.requestAttrib.normal ) { this.addVertexPars( 'varying vec3 vObjectNormal;' ); this.addFragmentPars( 'varying vec3 vObjectNormal;' ); - + this.addVertexCode( 'vObjectNormal = normal;' ); - + } - - if (this.requestAttrib.worldNormal) { + + if ( this.requestAttrib.worldNormal ) { this.addVertexPars( 'varying vec3 vWNormal;' ); this.addFragmentPars( 'varying vec3 vWNormal;' ); - + this.addVertexCode( 'vWNormal = ( modelMatrix * vec4( objectNormal, 0.0 ) ).xyz;' ); - + } - + this.lights = this.needsLight; this.transparent = this.needsTransparent; - + this.vertexShader = [ this.vertexPars, this.getCodePars( this.vertexUniform, 'uniform' ), - this.getIncludes(this.consts['vertex']), - this.getIncludes(this.functions['vertex']), + this.getIncludes( this.consts[ 'vertex' ] ), + this.getIncludes( this.functions[ 'vertex' ] ), 'void main(){', this.getCodePars( this.vertexTemps ), vertex, @@ -199,115 +207,120 @@ THREE.NodeMaterial.prototype.build = function() { this.fragmentShader = [ this.fragmentPars, this.getCodePars( this.fragmentUniform, 'uniform' ), - this.getIncludes(this.consts['fragment']), - this.getIncludes(this.functions['fragment']), + this.getIncludes( this.consts[ 'fragment' ] ), + this.getIncludes( this.functions[ 'fragment' ] ), 'void main(){', this.getCodePars( this.fragmentTemps ), this.fragmentCode, fragment, '}' ].join( "\n" ); - + this.needsUpdate = true; this.dispose(); // force update - + return this; + }; -THREE.NodeMaterial.prototype.define = function(name, value) { +THREE.NodeMaterial.prototype.define = function( name, value ) { - this.defines[name] = value == undefined ? 1 : value; + this.defines[ name ] = value == undefined ? 1 : value; }; -THREE.NodeMaterial.prototype.isDefined = function(name) { +THREE.NodeMaterial.prototype.isDefined = function( name ) { - return this.defines[name] != undefined; + return this.defines[ name ] != undefined; }; THREE.NodeMaterial.prototype.mergeUniform = function( uniforms ) { - - for (var name in uniforms) { - + + for ( var name in uniforms ) { + this.uniforms[ name ] = uniforms[ name ]; - + } - + }; THREE.NodeMaterial.prototype.createUniform = function( value, type, needsUpdate ) { - + var index = this.uniformList.length; - + var uniform = { type : type, value : value, needsUpdate : needsUpdate, name : 'nVu' + index }; - - this.uniformList.push(uniform); - + + this.uniformList.push( uniform ); + return uniform; - + }; THREE.NodeMaterial.prototype.getVertexTemp = function( uuid, type ) { - - if (!this.vertexTemps[ uuid ]) { - + + if ( ! this.vertexTemps[ uuid ] ) { + var index = this.vertexTemps.length, name = 'nVt' + index, data = { name : name, type : type }; - + this.vertexTemps.push( data ); - this.vertexTemps[uuid] = data; - + this.vertexTemps[ uuid ] = data; + } - - return this.vertexTemps[uuid]; - + + return this.vertexTemps[ uuid ]; + }; THREE.NodeMaterial.prototype.getIncludes = function( incs ) { - - function sortByPosition(a, b){ + + function sortByPosition( a, b ) { + return b.deps - a.deps; + } - + return function( incs ) { - - if (!incs) return ''; - + + if ( ! incs ) return ''; + var code = ''; - var incs = incs.sort(sortByPosition); - - for(var i = 0; i < incs.length; i++) { - - code += incs[i].node.src + '\n'; - + var incs = incs.sort( sortByPosition ); + + for ( var i = 0; i < incs.length; i ++ ) { + + code += incs[ i ].node.src + '\n'; + } - + return code; + } + }(); THREE.NodeMaterial.prototype.getFragmentTemp = function( uuid, type ) { - - if (!this.fragmentTemps[ uuid ]) { - + + if ( ! this.fragmentTemps[ uuid ] ) { + var index = this.fragmentTemps.length, name = 'nVt' + index, data = { name : name, type : type }; - + this.fragmentTemps.push( data ); - this.fragmentTemps[uuid] = data; - + this.fragmentTemps[ uuid ] = data; + } - - return this.fragmentTemps[uuid]; - + + return this.fragmentTemps[ uuid ]; + }; THREE.NodeMaterial.prototype.addVertexPars = function( code ) { @@ -343,9 +356,9 @@ THREE.NodeMaterial.prototype.addVertexNode = function( code ) { THREE.NodeMaterial.prototype.clearVertexNode = function() { var code = this.fragmentNode; - + this.fragmentNode = ''; - + return code; }; @@ -359,9 +372,9 @@ THREE.NodeMaterial.prototype.addFragmentNode = function( code ) { THREE.NodeMaterial.prototype.clearFragmentNode = function() { var code = this.fragmentNode; - + this.fragmentNode = ''; - + return code; }; @@ -371,20 +384,21 @@ THREE.NodeMaterial.prototype.getCodePars = function( pars, prefix ) { prefix = prefix || ''; var code = ''; - - for (var i = 0, l = pars.length; i < l; ++i) { - - var parsType = pars[i].type; - var parsName = pars[i].name; - var parsValue = pars[i].value; - - if (parsType == 't' && parsValue instanceof THREE.CubeTexture) parsType = 'tc'; - + + for ( var i = 0, l = pars.length; i < l; ++ i ) { + + var parsType = pars[ i ].type; + var parsName = pars[ i ].name; + var parsValue = pars[ i ].value; + + if ( parsType == 't' && parsValue instanceof THREE.CubeTexture ) parsType = 'tc'; + var type = THREE.NodeMaterial.Type[ parsType ]; - - if (type == undefined) throw new Error( "Node pars " + parsType + " not found." ); - + + if ( type == undefined ) throw new Error( "Node pars " + parsType + " not found." ); + code += prefix + ' ' + type + ' ' + parsName + ';\n'; + } return code; @@ -394,12 +408,12 @@ THREE.NodeMaterial.prototype.getCodePars = function( pars, prefix ) { THREE.NodeMaterial.prototype.getVertexUniform = function( value, type, needsUpdate ) { var uniform = this.createUniform( value, type, needsUpdate ); - - this.vertexUniform.push(uniform); - this.vertexUniform[uniform.name] = uniform; - + + this.vertexUniform.push( uniform ); + this.vertexUniform[ uniform.name ] = uniform; + this.uniforms[ uniform.name ] = uniform; - + return uniform; }; @@ -407,61 +421,61 @@ THREE.NodeMaterial.prototype.getVertexUniform = function( value, type, needsUpda THREE.NodeMaterial.prototype.getFragmentUniform = function( value, type, needsUpdate ) { var uniform = this.createUniform( value, type, needsUpdate ); - - this.fragmentUniform.push(uniform); - this.fragmentUniform[uniform.name] = uniform; - + + this.fragmentUniform.push( uniform ); + this.fragmentUniform[ uniform.name ] = uniform; + this.uniforms[ uniform.name ] = uniform; - + return uniform; }; THREE.NodeMaterial.prototype.getDataNode = function( uuid ) { - return this.nodeData[uuid] = this.nodeData[uuid] || {}; + return this.nodeData[ uuid ] = this.nodeData[ uuid ] || {}; }; THREE.NodeMaterial.prototype.include = function( shader, node ) { - + var includes; - - node = typeof node === 'string' ? THREE.LibNode.get(node) : node; - - if (node instanceof THREE.FunctionNode) { - - for (var i = 0; i < node.includes.length; i++) { - - this.include( shader, node.includes[i] ); - + + node = typeof node === 'string' ? THREE.LibNode.get( node ) : node; + + if ( node instanceof THREE.FunctionNode ) { + + for ( var i = 0; i < node.includes.length; i ++ ) { + + this.include( shader, node.includes[ i ] ); + } - - includes = this.functions[shader] = this.functions[shader] || []; - + + includes = this.functions[ shader ] = this.functions[ shader ] || []; + } - else if (node instanceof THREE.ConstNode) { - - includes = this.consts[shader] = this.consts[shader] || []; - + else if ( node instanceof THREE.ConstNode ) { + + includes = this.consts[ shader ] = this.consts[ shader ] || []; + } - - if (includes[node.name] === undefined) { - - for (var ext in node.extensions) { - - this.extensions[ext] = true; - + + if ( includes[ node.name ] === undefined ) { + + for ( var ext in node.extensions ) { + + this.extensions[ ext ] = true; + } - - includes[node.name] = { + + includes[ node.name ] = { node : node, deps : 1 }; - - includes.push(includes[node.name]); - + + includes.push( includes[ node.name ] ); + } - else ++includes[node.name].deps; + else ++ includes[ node.name ].deps; -}; \ No newline at end of file +}; diff --git a/examples/js/materials/nodes/RawNode.js b/examples/js/materials/nodes/RawNode.js index 099bac4c29617cece58acf120646638d51b6c574..74d08e6b0802d3b5dd8899770284fff34f119c91 100644 --- a/examples/js/materials/nodes/RawNode.js +++ b/examples/js/materials/nodes/RawNode.js @@ -3,35 +3,35 @@ */ THREE.RawNode = function( value ) { - + THREE.GLNode.call( this, 'v4' ); - + this.value = value; - + }; THREE.RawNode.prototype = Object.create( THREE.GLNode.prototype ); THREE.RawNode.prototype.constructor = THREE.RawNode; THREE.GLNode.prototype.generate = function( builder ) { - + var material = builder.material; - + var data = this.value.verifyAndBuildCode( builder, this.type ); - + var code = data.code + '\n'; - - if (builder.shader == 'vertex') { - + + if ( builder.shader == 'vertex' ) { + code += 'gl_Position = ' + data.result + ';'; - + } else { - + code += 'gl_FragColor = ' + data.result + ';'; - + } - + return code; -}; \ No newline at end of file +}; diff --git a/examples/js/materials/nodes/TempNode.js b/examples/js/materials/nodes/TempNode.js index 299f0e7f1e89ab2aa27e85d1bd38dfc6c6c343a9..cb6f976d6b6813eda0c36c2eeac55aa256a96bb9 100644 --- a/examples/js/materials/nodes/TempNode.js +++ b/examples/js/materials/nodes/TempNode.js @@ -4,113 +4,115 @@ */ THREE.TempNode = function( type, params ) { - + THREE.GLNode.call( this, type ); - + params = params || {}; - + this.shared = params.shared !== undefined ? params.shared : true; this.unique = params.unique !== undefined ? params.unique : false; - + }; THREE.TempNode.prototype = Object.create( THREE.GLNode.prototype ); THREE.TempNode.prototype.constructor = THREE.TempNode; THREE.TempNode.prototype.build = function( builder, output, uuid ) { - + var material = builder.material; - - if (this.isShared()) { - + + if ( this.isShared() ) { + var isUnique = this.isUnique(); - - if (isUnique && this.constructor.uuid === undefined) { - + + if ( isUnique && this.constructor.uuid === undefined ) { + this.constructor.uuid = THREE.Math.generateUUID(); - + } - - uuid = builder.getUuid( uuid || this.constructor.uuid || this.uuid, !isUnique ); - + + uuid = builder.getUuid( uuid || this.constructor.uuid || this.uuid, ! isUnique ); + var data = material.getDataNode( uuid ); - - if (builder.isShader('verify')) { - - if (data.deps || 0 > 0) { + + if ( builder.isShader( 'verify' ) ) { + + if ( data.deps || 0 > 0 ) { + this.verifyDepsNode( builder, data, output ); return ''; + } - + return THREE.GLNode.prototype.build.call( this, builder, output, uuid ); - + } - else if (data.deps == 1) { - + else if ( data.deps == 1 ) { + return THREE.GLNode.prototype.build.call( this, builder, output, uuid ); - + } - + var name = this.getTemp( builder, uuid ); var type = data.output || this.getType( builder ); - - if (name) { - + + if ( name ) { + return builder.format( name, type, output ); - + } else { - + name = THREE.TempNode.prototype.generate.call( this, builder, output, uuid, data.output ); - + var code = this.generate( builder, type, uuid ); - - if (builder.isShader('vertex')) material.addVertexNode(name + '=' + code + ';'); - else material.addFragmentNode(name + '=' + code + ';'); - + + if ( builder.isShader( 'vertex' ) ) material.addVertexNode( name + '=' + code + ';' ); + else material.addFragmentNode( name + '=' + code + ';' ); + return builder.format( name, type, output ); - + } - + } else { - + return builder.format( this.generate( builder, this.getType( builder ), uuid ), type, output ); - + } - + }; THREE.TempNode.prototype.isShared = function() { - + return this.shared; - + }; THREE.TempNode.prototype.isUnique = function() { - + return this.unique; - + }; THREE.TempNode.prototype.getTemp = function( builder, uuid ) { - + uuid = uuid || this.uuid; - + var material = builder.material; - - if (builder.isShader('vertex') && material.vertexTemps[ uuid ]) return material.vertexTemps[ uuid ].name; - else if (material.fragmentTemps[ uuid ]) return material.fragmentTemps[ uuid ].name; + + if ( builder.isShader( 'vertex' ) && material.vertexTemps[ uuid ] ) return material.vertexTemps[ uuid ].name; + else if ( material.fragmentTemps[ uuid ] ) return material.fragmentTemps[ uuid ].name; }; THREE.TempNode.prototype.generate = function( builder, output, uuid, type ) { - - if (!this.isShared()) console.error("THREE.TempNode is not shared!"); - + + if ( ! this.isShared() ) console.error( "THREE.TempNode is not shared!" ); + uuid = uuid || this.uuid; - - if (builder.isShader('vertex')) return builder.material.getVertexTemp( uuid, type || this.getType( builder ) ).name; + + if ( builder.isShader( 'vertex' ) ) return builder.material.getVertexTemp( uuid, type || this.getType( builder ) ).name; else return builder.material.getFragmentTemp( uuid, type || this.getType( builder ) ).name; -}; \ No newline at end of file +}; diff --git a/examples/js/materials/nodes/accessors/CameraNode.js b/examples/js/materials/nodes/accessors/CameraNode.js index d1b457b44c495f5674e384df2ed5b157cfb98990..d3e7133b0401ccbd7a235ab905829f30b36689ce 100644 --- a/examples/js/materials/nodes/accessors/CameraNode.js +++ b/examples/js/materials/nodes/accessors/CameraNode.js @@ -3,25 +3,25 @@ */ THREE.CameraNode = function( scope, camera ) { - + THREE.TempNode.call( this, 'v3' ); - + this.scope = scope || THREE.CameraNode.POSITION; this.camera = camera; - - switch(scope) { - + + switch ( scope ) { + case THREE.CameraNode.DEPTH: - - this.near = new THREE.FloatNode( camera ? camera.near : 1); - this.far = new THREE.FloatNode(camera ? camera.far : 1200); - + + this.near = new THREE.FloatNode( camera ? camera.near : 1 ); + this.far = new THREE.FloatNode( camera ? camera.far : 1200 ); + break; - + } - + this.requestUpdate = this.camera !== undefined; - + }; THREE.CameraNode.prototype = Object.create( THREE.TempNode.prototype ); @@ -31,76 +31,76 @@ THREE.CameraNode.POSITION = 'position'; THREE.CameraNode.DEPTH = 'depth'; THREE.CameraNode.prototype.getType = function( builder ) { - - switch(this.scope) { + + switch ( this.scope ) { case THREE.CameraNode.DEPTH: return 'fv1'; } - + return this.type; - + }; THREE.CameraNode.prototype.isUnique = function( builder ) { - - switch(this.scope) { + + switch ( this.scope ) { case THREE.CameraNode.DEPTH: return true; } - + return false; - + }; THREE.CameraNode.prototype.isShared = function( builder ) { - - switch(this.scope) { + + switch ( this.scope ) { case THREE.CameraNode.POSITION: return false; } - + return true; - + }; THREE.CameraNode.prototype.generate = function( builder, output ) { - + var material = builder.material; var result; - - switch (this.scope) { - + + switch ( this.scope ) { + case THREE.CameraNode.POSITION: - + result = 'cameraPosition'; - + break; - + case THREE.CameraNode.DEPTH: - - builder.include('depthcolor'); - + + builder.include( 'depthcolor' ); + result = 'depthcolor(' + this.near.build( builder, 'fv1' ) + ',' + this.far.build( builder, 'fv1' ) + ')'; - + break; - + } - + return builder.format( result, this.getType( builder ), output ); }; THREE.CameraNode.prototype.updateAnimation = function( delta ) { - - switch(this.scope) { - + + switch ( this.scope ) { + case THREE.CameraNode.DEPTH: - + this.near.number = camera.near; this.far.number = camera.far; - + break; - + } - -}; \ No newline at end of file + +}; diff --git a/examples/js/materials/nodes/accessors/ColorsNode.js b/examples/js/materials/nodes/accessors/ColorsNode.js index 85ba67004afafdc971fd5c6e41cdccf3a799121a..1371270c76d13feae7f7c51b3459087471a3135d 100644 --- a/examples/js/materials/nodes/accessors/ColorsNode.js +++ b/examples/js/materials/nodes/accessors/ColorsNode.js @@ -3,29 +3,29 @@ */ THREE.ColorsNode = function( index ) { - - THREE.TempNode.call( this, 'v4', {share:false} ); - + + THREE.TempNode.call( this, 'v4', { share: false } ); + this.index = index || 0; - + }; THREE.ColorsNode.prototype = Object.create( THREE.TempNode.prototype ); THREE.ColorsNode.prototype.constructor = THREE.ColorsNode; -THREE.ColorsNode.vertexDict = ['color', 'color2']; -THREE.ColorsNode.fragmentDict = ['vColor', 'vColor2']; +THREE.ColorsNode.vertexDict = [ 'color', 'color2' ]; +THREE.ColorsNode.fragmentDict = [ 'vColor', 'vColor2' ]; THREE.ColorsNode.prototype.generate = function( builder, output ) { - + var material = builder.material; var result; - - material.requestAttrib.color[this.index] = true; - - if (builder.isShader('vertex')) result = THREE.ColorsNode.vertexDict[this.index]; - else result = THREE.ColorsNode.fragmentDict[this.index]; - + + material.requestAttrib.color[ this.index ] = true; + + if ( builder.isShader( 'vertex' ) ) result = THREE.ColorsNode.vertexDict[ this.index ]; + else result = THREE.ColorsNode.fragmentDict[ this.index ]; + return builder.format( result, this.getType( builder ), output ); }; diff --git a/examples/js/materials/nodes/accessors/NormalNode.js b/examples/js/materials/nodes/accessors/NormalNode.js index fea28cbb07020ff37ddea383292ff00da7cdb4a7..6183bd26346d0ea3b43ab85a19a79a57e019e32e 100644 --- a/examples/js/materials/nodes/accessors/NormalNode.js +++ b/examples/js/materials/nodes/accessors/NormalNode.js @@ -3,11 +3,11 @@ */ THREE.NormalNode = function( scope ) { - + THREE.TempNode.call( this, 'v3' ); - + this.scope = scope || THREE.NormalNode.LOCAL; - + }; THREE.NormalNode.prototype = Object.create( THREE.TempNode.prototype ); @@ -18,49 +18,49 @@ THREE.NormalNode.WORLD = 'world'; THREE.NormalNode.VIEW = 'view'; THREE.NormalNode.prototype.isShared = function( builder ) { - - switch(this.method) { + + switch ( this.method ) { case THREE.NormalNode.WORLD: return true; } - + return false; - + }; THREE.NormalNode.prototype.generate = function( builder, output ) { - + var material = builder.material; var result; - - switch (this.scope) { - + + switch ( this.scope ) { + case THREE.NormalNode.LOCAL: - + material.requestAttrib.normal = true; - - if (builder.isShader('vertex')) result = 'normal'; + + if ( builder.isShader( 'vertex' ) ) result = 'normal'; else result = 'vObjectNormal'; - + break; - + case THREE.NormalNode.WORLD: - + material.requestAttrib.worldNormal = true; - - if (builder.isShader('vertex')) result = '( modelMatrix * vec4( objectNormal, 0.0 ) ).xyz'; + + if ( builder.isShader( 'vertex' ) ) result = '( modelMatrix * vec4( objectNormal, 0.0 ) ).xyz'; else result = 'vWNormal'; - + break; - + case THREE.NormalNode.VIEW: - + result = 'vNormal'; - + break; - + } - + return builder.format( result, this.getType( builder ), output ); }; diff --git a/examples/js/materials/nodes/accessors/PositionNode.js b/examples/js/materials/nodes/accessors/PositionNode.js index b23d1d7b8052a32a3708c5a5f55ea03b4c09a0d6..8b3d20d615d238b6cd73dc61f40cade5a624b28e 100644 --- a/examples/js/materials/nodes/accessors/PositionNode.js +++ b/examples/js/materials/nodes/accessors/PositionNode.js @@ -3,11 +3,11 @@ */ THREE.PositionNode = function( scope ) { - + THREE.TempNode.call( this, 'v3' ); - + this.scope = scope || THREE.PositionNode.LOCAL; - + }; THREE.PositionNode.prototype = Object.create( THREE.TempNode.prototype ); @@ -19,69 +19,69 @@ THREE.PositionNode.VIEW = 'view'; THREE.PositionNode.PROJECTION = 'projection'; THREE.PositionNode.prototype.getType = function( builder ) { - - switch(this.method) { + + switch ( this.method ) { case THREE.PositionNode.PROJECTION: return 'v4'; } - + return this.type; - + }; THREE.PositionNode.prototype.isShared = function( builder ) { - - switch(this.method) { + + switch ( this.method ) { case THREE.PositionNode.LOCAL: case THREE.PositionNode.WORLD: return false; } - + return true; - + }; THREE.PositionNode.prototype.generate = function( builder, output ) { - + var material = builder.material; var result; - - switch (this.scope) { - + + switch ( this.scope ) { + case THREE.PositionNode.LOCAL: - + material.requestAttrib.position = true; - - if (builder.isShader('vertex')) result = 'transformed'; + + if ( builder.isShader( 'vertex' ) ) result = 'transformed'; else result = 'vPosition'; - + break; - + case THREE.PositionNode.WORLD: - + material.requestAttrib.worldPosition = true; - - if (builder.isShader('vertex')) result = 'vWPosition'; + + if ( builder.isShader( 'vertex' ) ) result = 'vWPosition'; else result = 'vWPosition'; - + break; - + case THREE.PositionNode.VIEW: - - if (builder.isShader('vertex')) result = '-mvPosition.xyz'; + + if ( builder.isShader( 'vertex' ) ) result = '-mvPosition.xyz'; else result = 'vViewPosition'; - + break; - + case THREE.PositionNode.PROJECTION: - - if (builder.isShader('vertex')) result = '(projectionMatrix * modelViewMatrix * vec4( position, 1.0 ))'; + + if ( builder.isShader( 'vertex' ) ) result = '(projectionMatrix * modelViewMatrix * vec4( position, 1.0 ))'; else result = 'vec4( 0.0 )'; - + break; - + } - + return builder.format( result, this.getType( builder ), output ); -}; \ No newline at end of file +}; diff --git a/examples/js/materials/nodes/accessors/ReflectNode.js b/examples/js/materials/nodes/accessors/ReflectNode.js index b48206c8339c92035e7944aacade63f46a894b57..af8c0d9c7f5266c72ab55eb1b44cb2136d261930 100644 --- a/examples/js/materials/nodes/accessors/ReflectNode.js +++ b/examples/js/materials/nodes/accessors/ReflectNode.js @@ -3,37 +3,37 @@ */ THREE.ReflectNode = function() { - - THREE.TempNode.call( this, 'v3', {unique:true} ); - + + THREE.TempNode.call( this, 'v3', { unique: true } ); + this.worldPosition = new THREE.PositionNode( THREE.PositionNode.WORLD ); - + }; THREE.ReflectNode.prototype = Object.create( THREE.TempNode.prototype ); THREE.ReflectNode.prototype.constructor = THREE.ReflectNode; THREE.ReflectNode.prototype.generate = function( builder, output ) { - + var material = builder.material; - - if (builder.isShader('fragment')) { - + + if ( builder.isShader( 'fragment' ) ) { + material.addFragmentNode( [ - 'vec3 cameraToVertex = normalize( ' + this.worldPosition.build( builder, 'v3' ) + ' - cameraPosition );', + 'vec3 cameraToVertex = normalize( ' + this.worldPosition.build( builder, 'v3' ) + ' - cameraPosition );', 'vec3 worldNormal = inverseTransformDirection( normal, viewMatrix );', 'vec3 vReflect = reflect( cameraToVertex, worldNormal );' ].join( "\n" ) ); - + return builder.format( 'vReflect', this.type, output ); - + } else { - - console.warn("THREE.ReflectNode is not compatible with " + builder.shader + " shader"); - + + console.warn( "THREE.ReflectNode is not compatible with " + builder.shader + " shader" ); + return builder.format( 'vec3( 0.0 )', this.type, output ); - + } -}; \ No newline at end of file +}; diff --git a/examples/js/materials/nodes/accessors/UVNode.js b/examples/js/materials/nodes/accessors/UVNode.js index b2131759ca145960d66497e000a583a8113b6f50..eedee4e607cd16e16f22fc21d93b2d4deff596a9 100644 --- a/examples/js/materials/nodes/accessors/UVNode.js +++ b/examples/js/materials/nodes/accessors/UVNode.js @@ -3,29 +3,29 @@ */ THREE.UVNode = function( index ) { - - THREE.TempNode.call( this, 'v2', {shared:false} ); - + + THREE.TempNode.call( this, 'v2', { shared: false } ); + this.index = index || 0; - + }; THREE.UVNode.prototype = Object.create( THREE.TempNode.prototype ); THREE.UVNode.prototype.constructor = THREE.UVNode; -THREE.UVNode.vertexDict = ['uv', 'uv2']; -THREE.UVNode.fragmentDict = ['vUv', 'vUv2']; +THREE.UVNode.vertexDict = [ 'uv', 'uv2' ]; +THREE.UVNode.fragmentDict = [ 'vUv', 'vUv2' ]; THREE.UVNode.prototype.generate = function( builder, output ) { - + var material = builder.material; var result; - - material.requestAttrib.uv[this.index] = true; - - if (builder.isShader('vertex')) result = THREE.UVNode.vertexDict[this.index]; - else result = THREE.UVNode.fragmentDict[this.index]; - + + material.requestAttrib.uv[ this.index ] = true; + + if ( builder.isShader( 'vertex' ) ) result = THREE.UVNode.vertexDict[ this.index ]; + else result = THREE.UVNode.fragmentDict[ this.index ]; + return builder.format( result, this.getType( builder ), output ); }; diff --git a/examples/js/materials/nodes/extras/VelocityNode.js b/examples/js/materials/nodes/extras/VelocityNode.js index c4cc1f09fd6e02abdc02435f983341cfda3710e1..c4cc13fd6988634654f2b14e2b213931762c6d66 100644 --- a/examples/js/materials/nodes/extras/VelocityNode.js +++ b/examples/js/materials/nodes/extras/VelocityNode.js @@ -3,38 +3,38 @@ */ THREE.VelocityNode = function( target, params ) { - + THREE.Vector3Node.call( this ); - + this.requestUpdate = true; - + this.target = target; - + this.position = this.target.position.clone(); this.velocity = new THREE.Vector3(); this.moment = new THREE.Vector3(); - + this.params = params || {}; - + }; THREE.VelocityNode.prototype = Object.create( THREE.Vector3Node.prototype ); THREE.VelocityNode.prototype.constructor = THREE.VelocityNode; THREE.VelocityNode.prototype.updateAnimation = function( delta ) { - + this.velocity.subVectors( this.target.position, this.position ); this.position.copy( this.target.position ); - - switch(this.params.type) { - + + switch ( this.params.type ) { + case "elastic": - + delta *= this.params.fps || 60; - + var spring = Math.pow( this.params.spring, delta ); var friction = Math.pow( this.params.friction, delta ); - + // spring this.moment.x += this.velocity.x * spring; this.moment.y += this.velocity.y * spring; @@ -46,14 +46,14 @@ THREE.VelocityNode.prototype.updateAnimation = function( delta ) { this.moment.z *= friction; this.value.copy( this.moment ); - + break; - + default: - + this.value.copy( this.velocity ); - + break; } - -}; \ No newline at end of file + +}; diff --git a/examples/js/materials/nodes/inputs/ColorNode.js b/examples/js/materials/nodes/inputs/ColorNode.js index 4e98dc5a7b082a0a335f3a7a4e956e0d380b6250..0174002507782698d83caec60b31a56eda1a6e66 100644 --- a/examples/js/materials/nodes/inputs/ColorNode.js +++ b/examples/js/materials/nodes/inputs/ColorNode.js @@ -3,14 +3,14 @@ */ THREE.ColorNode = function( color ) { - - THREE.InputNode.call( this, 'c', {share:false} ); - + + THREE.InputNode.call( this, 'c', { share: false } ); + this.value = new THREE.Color( color || 0 ); - + }; THREE.ColorNode.prototype = Object.create( THREE.InputNode.prototype ); THREE.ColorNode.prototype.constructor = THREE.ColorNode; -THREE.NodeMaterial.Shortcuts( THREE.ColorNode.prototype, 'value', [ 'r', 'g', 'b' ] ); \ No newline at end of file +THREE.NodeMaterial.Shortcuts( THREE.ColorNode.prototype, 'value', [ 'r', 'g', 'b' ] ); diff --git a/examples/js/materials/nodes/inputs/CubeTextureNode.js b/examples/js/materials/nodes/inputs/CubeTextureNode.js index 13abc61778d3676b0e078508861446d9746e5061..10150fa30b3a16ba2c9ddc085c8c5d81c5020b96 100644 --- a/examples/js/materials/nodes/inputs/CubeTextureNode.js +++ b/examples/js/materials/nodes/inputs/CubeTextureNode.js @@ -3,13 +3,13 @@ */ THREE.CubeTextureNode = function( value, coord, bias ) { - + THREE.InputNode.call( this, 'v4' ); this.value = value; this.coord = coord || new THREE.ReflectNode(); this.bias = bias; - + }; THREE.CubeTextureNode.prototype = Object.create( THREE.InputNode.prototype ); @@ -20,18 +20,18 @@ THREE.CubeTextureNode.prototype.generate = function( builder, output ) { var cubetex = THREE.InputNode.prototype.generate.call( this, builder, output, this.value.uuid, 't' ); var coord = this.coord.build( builder, 'v3' ); var bias = this.bias ? this.bias.build( builder, 'fv1' ) : undefined;; - - if (bias == undefined && builder.require.cubeTextureBias) { - + + if ( bias == undefined && builder.require.cubeTextureBias ) { + bias = builder.require.cubeTextureBias.build( builder, 'fv1' ); - + } - + var code; - if (bias) code = 'textureCube(' + cubetex + ',' + coord + ',' + bias + ')'; + if ( bias ) code = 'textureCube(' + cubetex + ',' + coord + ',' + bias + ')'; else code = 'textureCube(' + cubetex + ',' + coord + ')'; - - return builder.format(code, this.type, output ); -}; \ No newline at end of file + return builder.format( code, this.type, output ); + +}; diff --git a/examples/js/materials/nodes/inputs/FloatNode.js b/examples/js/materials/nodes/inputs/FloatNode.js index cca162d1a7af239649f12238a6ba4aa866bdf3a4..48e6386661544014af034a1171d5876fbe35ad05 100644 --- a/examples/js/materials/nodes/inputs/FloatNode.js +++ b/examples/js/materials/nodes/inputs/FloatNode.js @@ -3,11 +3,11 @@ */ THREE.FloatNode = function( value ) { - - THREE.InputNode.call( this, 'fv1', {share:false} ); - + + THREE.InputNode.call( this, 'fv1', { share: false } ); + this.value = [ value || 0 ]; - + }; THREE.FloatNode.prototype = Object.create( THREE.InputNode.prototype ); @@ -15,7 +15,15 @@ THREE.FloatNode.prototype.constructor = THREE.FloatNode; Object.defineProperties( THREE.FloatNode.prototype, { number: { - get: function () { return this.value[0]; }, - set: function ( val ) { this.value[0] = val; } + get: function() { + + return this.value[ 0 ]; + + }, + set: function( val ) { + + this.value[ 0 ] = val; + + } } -}); \ No newline at end of file +} ); diff --git a/examples/js/materials/nodes/inputs/IntNode.js b/examples/js/materials/nodes/inputs/IntNode.js index 3ac7d464ff37d5d587524a09e4d7717d33d0729a..b016a788f25793cef82fbb0a064cdbf37ca75ce4 100644 --- a/examples/js/materials/nodes/inputs/IntNode.js +++ b/examples/js/materials/nodes/inputs/IntNode.js @@ -3,11 +3,11 @@ */ THREE.IntNode = function( value ) { - - THREE.InputNode.call( this, 'fv1', {share:false} ); - - this.value = [ Math.floor(value || 0) ]; - + + THREE.InputNode.call( this, 'fv1', { share: false } ); + + this.value = [ Math.floor( value || 0 ) ]; + }; THREE.IntNode.prototype = Object.create( THREE.InputNode.prototype ); @@ -15,7 +15,15 @@ THREE.IntNode.prototype.constructor = THREE.IntNode; Object.defineProperties( THREE.IntNode.prototype, { number: { - get: function () { return this.value[0]; }, - set: function ( val ) { this.value[0] = Math.floor(val); } + get: function() { + + return this.value[ 0 ]; + + }, + set: function( val ) { + + this.value[ 0 ] = Math.floor( val ); + + } } -}); +} ); diff --git a/examples/js/materials/nodes/inputs/TextureNode.js b/examples/js/materials/nodes/inputs/TextureNode.js index 53355b87388e49b3a3b4b13feb2753ad75a594d0..a5767b3aba5f0fb7213a48ce624ea07eba079538 100644 --- a/examples/js/materials/nodes/inputs/TextureNode.js +++ b/examples/js/materials/nodes/inputs/TextureNode.js @@ -3,13 +3,13 @@ */ THREE.TextureNode = function( value, coord, bias ) { - + THREE.InputNode.call( this, 'v4' ); - + this.value = value; this.coord = coord || new THREE.UVNode(); this.bias = bias; - + }; THREE.TextureNode.prototype = Object.create( THREE.InputNode.prototype ); @@ -20,12 +20,12 @@ THREE.TextureNode.prototype.generate = function( builder, output ) { var tex = THREE.InputNode.prototype.generate.call( this, builder, output, this.value.uuid, 't' ); var coord = this.coord.build( builder, 'v2' ); var bias = this.bias ? this.bias.build( builder, 'fv1' ) : undefined; - + var code; - if (bias) code = 'texture2D(' + tex + ',' + coord + ',' + bias + ')'; + if ( bias ) code = 'texture2D(' + tex + ',' + coord + ',' + bias + ')'; else code = 'texture2D(' + tex + ',' + coord + ')'; - - return builder.format(code, this.type, output ); + + return builder.format( code, this.type, output ); }; diff --git a/examples/js/materials/nodes/inputs/Vector2Node.js b/examples/js/materials/nodes/inputs/Vector2Node.js index 5242a15a50ab674820419fbd37dc081f0b4d96e0..2e6458b3ec5f039d0f5beb6b799604a30ef74260 100644 --- a/examples/js/materials/nodes/inputs/Vector2Node.js +++ b/examples/js/materials/nodes/inputs/Vector2Node.js @@ -3,14 +3,14 @@ */ THREE.Vector2Node = function( x, y ) { - - THREE.InputNode.call( this, 'v2', {share:false} ); - + + THREE.InputNode.call( this, 'v2', { share: false } ); + this.value = new THREE.Vector2( x, y ); - + }; THREE.Vector2Node.prototype = Object.create( THREE.InputNode.prototype ); THREE.Vector2Node.prototype.constructor = THREE.Vector2Node; -THREE.NodeMaterial.Shortcuts( THREE.Vector2Node.prototype, 'value', [ 'x', 'y' ] ); \ No newline at end of file +THREE.NodeMaterial.Shortcuts( THREE.Vector2Node.prototype, 'value', [ 'x', 'y' ] ); diff --git a/examples/js/materials/nodes/inputs/Vector3Node.js b/examples/js/materials/nodes/inputs/Vector3Node.js index b10aa3d2b20e85729dd2516a37189c17d5576a6d..c252b7c49c30f7a28d8e08c125648011028ff066 100644 --- a/examples/js/materials/nodes/inputs/Vector3Node.js +++ b/examples/js/materials/nodes/inputs/Vector3Node.js @@ -3,15 +3,15 @@ */ THREE.Vector3Node = function( x, y, z ) { - - THREE.InputNode.call( this, 'v3', {share:false} ); - + + THREE.InputNode.call( this, 'v3', { share: false } ); + this.type = 'v3'; this.value = new THREE.Vector3( x, y, z ); - + }; THREE.Vector3Node.prototype = Object.create( THREE.InputNode.prototype ); THREE.Vector3Node.prototype.constructor = THREE.Vector3Node; -THREE.NodeMaterial.Shortcuts( THREE.Vector3Node.prototype, 'value', [ 'x', 'y', 'z' ] ); \ No newline at end of file +THREE.NodeMaterial.Shortcuts( THREE.Vector3Node.prototype, 'value', [ 'x', 'y', 'z' ] ); diff --git a/examples/js/materials/nodes/inputs/Vector4Node.js b/examples/js/materials/nodes/inputs/Vector4Node.js index aa89530825028fedbe73ca21e206bd6793b6f2c5..7d1da9c4fa5e8915ac8f4370a4fc5358c8981c6a 100644 --- a/examples/js/materials/nodes/inputs/Vector4Node.js +++ b/examples/js/materials/nodes/inputs/Vector4Node.js @@ -3,14 +3,14 @@ */ THREE.Vector4Node = function( x, y, z, w ) { - - THREE.InputNode.call( this, 'v4', {share:false} ); - + + THREE.InputNode.call( this, 'v4', { share: false } ); + this.value = new THREE.Vector4( x, y, z, w ); - + }; THREE.Vector4Node.prototype = Object.create( THREE.InputNode.prototype ); THREE.Vector4Node.prototype.constructor = THREE.Vector4Node; -THREE.NodeMaterial.Shortcuts( THREE.Vector4Node.prototype, 'value', [ 'x', 'y', 'z', 'w' ] ); \ No newline at end of file +THREE.NodeMaterial.Shortcuts( THREE.Vector4Node.prototype, 'value', [ 'x', 'y', 'z', 'w' ] ); diff --git a/examples/js/materials/nodes/interfaces/PhongNode.js b/examples/js/materials/nodes/interfaces/PhongNode.js index b06f1b415a9b6358b04e900c9f839de566a84feb..b952678624a50cc09c1538ef5cc719323c2e6c5d 100644 --- a/examples/js/materials/nodes/interfaces/PhongNode.js +++ b/examples/js/materials/nodes/interfaces/PhongNode.js @@ -3,32 +3,32 @@ */ THREE.PhongNode = function() { - + THREE.GLNode.call( this ); - + this.color = new THREE.ColorNode( 0xEEEEEE ); this.specular = new THREE.ColorNode( 0x111111 ); this.shininess = new THREE.FloatNode( 30 ); - + }; THREE.PhongNode.prototype = Object.create( THREE.GLNode.prototype ); THREE.PhongNode.prototype.constructor = THREE.PhongNode; THREE.PhongNode.prototype.build = function( builder ) { - + var material = builder.material; var code; - + material.define( 'PHONG' ); material.define( 'ALPHATEST', '0.0' ); - + material.needsLight = true; - - if (builder.isShader('vertex')) { - + + if ( builder.isShader( 'vertex' ) ) { + var transform = this.transform ? this.transform.verifyAndBuildCode( builder, 'v3' ) : undefined; - + material.mergeUniform( THREE.UniformsUtils.merge( [ THREE.UniformsLib[ "fog" ], @@ -36,7 +36,7 @@ THREE.PhongNode.prototype.build = function( builder ) { THREE.UniformsLib[ "shadowmap" ] ] ) ); - + material.addVertexPars( [ "varying vec3 vViewPosition;", @@ -54,7 +54,7 @@ THREE.PhongNode.prototype.build = function( builder ) { THREE.ShaderChunk[ "logdepthbuf_pars_vertex" ] ].join( "\n" ) ); - + var output = [ THREE.ShaderChunk[ "beginnormal_vertex" ], THREE.ShaderChunk[ "morphnormal_vertex" ], @@ -70,12 +70,14 @@ THREE.PhongNode.prototype.build = function( builder ) { THREE.ShaderChunk[ "begin_vertex" ] ]; - + if ( transform ) { + output.push( transform.code ); output.push( "transformed = " + transform.result + ";" ); + } - + output.push( THREE.ShaderChunk[ "morphtarget_vertex" ], THREE.ShaderChunk[ "skinning_vertex" ], @@ -88,52 +90,52 @@ THREE.PhongNode.prototype.build = function( builder ) { THREE.ShaderChunk[ "lights_phong_vertex" ], THREE.ShaderChunk[ "shadowmap_vertex" ] ); - + code = output.join( "\n" ); - + } else { - + // verify all nodes to reuse generate codes - + this.color.verify( builder ); this.specular.verify( builder ); this.shininess.verify( builder ); - - if (this.alpha) this.alpha.verify( builder ); - - if (this.ao) this.ao.verify( builder ); - if (this.ambient) this.ambient.verify( builder ); - if (this.shadow) this.shadow.verify( builder ); - if (this.emissive) this.emissive.verify( builder ); - - if (this.normal) this.normal.verify( builder ); - if (this.normalScale && this.normal) this.normalScale.verify( builder ); - - if (this.environment) this.environment.verify( builder ); - if (this.reflectivity && this.environment) this.reflectivity.verify( builder ); - + + if ( this.alpha ) this.alpha.verify( builder ); + + if ( this.ao ) this.ao.verify( builder ); + if ( this.ambient ) this.ambient.verify( builder ); + if ( this.shadow ) this.shadow.verify( builder ); + if ( this.emissive ) this.emissive.verify( builder ); + + if ( this.normal ) this.normal.verify( builder ); + if ( this.normalScale && this.normal ) this.normalScale.verify( builder ); + + if ( this.environment ) this.environment.verify( builder ); + if ( this.reflectivity && this.environment ) this.reflectivity.verify( builder ); + // build code - + var color = this.color.buildCode( builder, 'v4' ); var specular = this.specular.buildCode( builder, 'c' ); var shininess = this.shininess.buildCode( builder, 'fv1' ); - + var alpha = this.alpha ? this.alpha.buildCode( builder, 'fv1' ) : undefined; - + var ao = this.ao ? this.ao.buildCode( builder, 'c' ) : undefined; var ambient = this.ambient ? this.ambient.buildCode( builder, 'c' ) : undefined; var shadow = this.shadow ? this.shadow.buildCode( builder, 'c' ) : undefined; var emissive = this.emissive ? this.emissive.buildCode( builder, 'c' ) : undefined; - + var normal = this.normal ? this.normal.buildCode( builder, 'v3' ) : undefined; var normalScale = this.normalScale && this.normal ? this.normalScale.buildCode( builder, 'fv1' ) : undefined; - - var environment = this.environment ? this.environment.buildCode( builder.setCache('env'), 'c' ) : undefined; + + var environment = this.environment ? this.environment.buildCode( builder.setCache( 'env' ), 'c' ) : undefined; var reflectivity = this.reflectivity && this.environment ? this.reflectivity.buildCode( builder, 'fv1' ) : undefined; - + material.needsTransparent = alpha != undefined; - + material.addFragmentPars( [ THREE.ShaderChunk[ "common" ], THREE.ShaderChunk[ "fog_pars_fragment" ], @@ -143,115 +145,130 @@ THREE.PhongNode.prototype.build = function( builder ) { THREE.ShaderChunk[ "shadowmap_pars_fragment" ], THREE.ShaderChunk[ "logdepthbuf_pars_fragment" ] ].join( "\n" ) ); - + var output = [ // prevent undeclared normal THREE.ShaderChunk[ "normal_fragment" ], - + color.code, " vec4 diffuseColor = " + color.result + ";", " ReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );", - + THREE.ShaderChunk[ "logdepthbuf_fragment" ], - + specular.code, " vec3 specular = " + specular.result + ";", - + shininess.code, " float shininess = max(0.0001," + shininess.result + ");", - + " float specularStrength = 1.0;" // Ignored in MaterialNode ( replace to specular ) - ]; - - if (alpha) { - - output.push( + ]; + + if ( alpha ) { + + output.push( alpha.code, 'if ( ' + alpha.result + ' <= ALPHATEST ) discard;' ); - + } - - if (normal) { - + + if ( normal ) { + builder.include( 'perturbNormal2Arb' ); - - output.push(normal.code); - - if (normalScale) output.push(normalScale.code); - + + output.push( normal.code ); + + if ( normalScale ) output.push( normalScale.code ); + output.push( 'normal = perturbNormal2Arb(-vViewPosition,normal,' + normal.result + ',' + new THREE.UVNode().build( builder, 'v2' ) + ',' + - (normalScale ? normalScale.result : '1.0') + ');' + ( normalScale ? normalScale.result : '1.0' ) + ');' ); } output.push( THREE.ShaderChunk[ "shadowmap_fragment" ], - + // accumulation THREE.ShaderChunk[ "lights_phong_fragment" ], THREE.ShaderChunk[ "lights_template" ] ); - - if (ao) { + + if ( ao ) { + output.push( ao.code ); output.push( "reflectedLight.indirectDiffuse *= " + ao.result + ";" ); + } - - if (ambient) { + + if ( ambient ) { + output.push( ambient.code ); output.push( "reflectedLight.indirectDiffuse += " + ambient.result + ";" ); + } - - if (shadow) { + + if ( shadow ) { + output.push( shadow.code ); output.push( "reflectedLight.directDiffuse *= " + shadow.result + ";" ); output.push( "reflectedLight.directSpecular *= " + shadow.result + ";" ); + } - - if (emissive) { + + if ( emissive ) { + output.push( emissive.code ); output.push( "reflectedLight.directDiffuse += " + emissive.result + ";" ); + } - - output.push("vec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + reflectedLight.directSpecular + reflectedLight.indirectSpecular;"); - - if (environment) { + + output.push( "vec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + reflectedLight.directSpecular + reflectedLight.indirectSpecular;" ); + + if ( environment ) { + output.push( environment.code ); - - if (reflectivity) { - + + if ( reflectivity ) { + output.push( reflectivity.code ); - + output.push( "outgoingLight = mix(" + 'outgoingLight' + "," + environment.result + "," + reflectivity.result + ");" ); - + } else { - + output.push( "outgoingLight = " + environment.result + ";" ); + } + } - + output.push( THREE.ShaderChunk[ "linear_to_gamma_fragment" ], THREE.ShaderChunk[ "fog_fragment" ] ); - - if (alpha) { + + if ( alpha ) { + output.push( "gl_FragColor = vec4( outgoingLight, " + alpha.result + " );" ); + } else { + output.push( "gl_FragColor = vec4( outgoingLight, 1.0 );" ); + } - + code = output.join( "\n" ); - + } - + return code; -}; \ No newline at end of file +}; diff --git a/examples/js/materials/nodes/interfaces/PhongNodeMaterial.js b/examples/js/materials/nodes/interfaces/PhongNodeMaterial.js index 388971a34cda9df751dc4fef31350606e0fb8fd4..13822bd0e91f9acd325dbdb23049d90b5a12c2eb 100644 --- a/examples/js/materials/nodes/interfaces/PhongNodeMaterial.js +++ b/examples/js/materials/nodes/interfaces/PhongNodeMaterial.js @@ -3,15 +3,15 @@ */ THREE.PhongNodeMaterial = function() { - + this.node = new THREE.PhongNode(); - + THREE.NodeMaterial.call( this, this.node, this.node ); - + }; THREE.PhongNodeMaterial.prototype = Object.create( THREE.NodeMaterial.prototype ); THREE.PhongNodeMaterial.prototype.constructor = THREE.PhongNodeMaterial; -THREE.NodeMaterial.Shortcuts( THREE.PhongNodeMaterial.prototype, 'node', -[ 'color', 'alpha', 'specular', 'shininess', 'normal', 'normalScale', 'emissive', 'ambient', 'shadow', 'ao', 'environment', 'reflectivity', 'transform' ] ); \ No newline at end of file +THREE.NodeMaterial.Shortcuts( THREE.PhongNodeMaterial.prototype, 'node', +[ 'color', 'alpha', 'specular', 'shininess', 'normal', 'normalScale', 'emissive', 'ambient', 'shadow', 'ao', 'environment', 'reflectivity', 'transform' ] ); diff --git a/examples/js/materials/nodes/interfaces/StandardNode.js b/examples/js/materials/nodes/interfaces/StandardNode.js index b859624bbb9889e9fd9031740eba2b8e34e9580f..7835c26ce2c12d3475b9f9672615d22f296c5c5a 100644 --- a/examples/js/materials/nodes/interfaces/StandardNode.js +++ b/examples/js/materials/nodes/interfaces/StandardNode.js @@ -3,32 +3,32 @@ */ THREE.StandardNode = function() { - + THREE.GLNode.call( this ); - + this.color = new THREE.ColorNode( 0xEEEEEE ); this.roughness = new THREE.FloatNode( 0.5 ); this.metalness = new THREE.FloatNode( 0.5 ); - + }; THREE.StandardNode.prototype = Object.create( THREE.GLNode.prototype ); THREE.StandardNode.prototype.constructor = THREE.StandardNode; THREE.StandardNode.prototype.build = function( builder ) { - + var material = builder.material; var code; - + material.define( 'STANDARD' ); material.define( 'ALPHATEST', '0.0' ); - + material.needsLight = true; - - if (builder.isShader('vertex')) { - + + if ( builder.isShader( 'vertex' ) ) { + var transform = this.transform ? this.transform.verifyAndBuildCode( builder, 'v3' ) : undefined; - + material.mergeUniform( THREE.UniformsUtils.merge( [ THREE.UniformsLib[ "fog" ], @@ -36,7 +36,7 @@ THREE.StandardNode.prototype.build = function( builder ) { THREE.UniformsLib[ "shadowmap" ] ] ) ); - + material.addVertexPars( [ "varying vec3 vViewPosition;", @@ -54,7 +54,7 @@ THREE.StandardNode.prototype.build = function( builder ) { THREE.ShaderChunk[ "logdepthbuf_pars_vertex" ] ].join( "\n" ) ); - + var output = [ THREE.ShaderChunk[ "beginnormal_vertex" ], THREE.ShaderChunk[ "morphnormal_vertex" ], @@ -70,12 +70,14 @@ THREE.StandardNode.prototype.build = function( builder ) { THREE.ShaderChunk[ "begin_vertex" ] ]; - + if ( transform ) { + output.push( transform.code ); output.push( "transformed = " + transform.result + ";" ); + } - + output.push( THREE.ShaderChunk[ "morphtarget_vertex" ], THREE.ShaderChunk[ "skinning_vertex" ], @@ -88,66 +90,66 @@ THREE.StandardNode.prototype.build = function( builder ) { THREE.ShaderChunk[ "lights_phong_vertex" ], THREE.ShaderChunk[ "shadowmap_vertex" ] ); - + code = output.join( "\n" ); - + } else { - + // CubeMap blur effect (PBR) - + builder.require.cubeTextureBias = builder.require.cubeTextureBias || new THREE.RoughnessToBlinnExponentNode(); - + // verify all nodes to reuse generate codes - + this.color.verify( builder ); this.roughness.verify( builder ); this.metalness.verify( builder ); - - if (this.alpha) this.alpha.verify( builder ); - - if (this.ao) this.ao.verify( builder ); - if (this.ambient) this.ambient.verify( builder ); - if (this.shadow) this.shadow.verify( builder ); - if (this.emissive) this.emissive.verify( builder ); - - if (this.normal) this.normal.verify( builder ); - if (this.normalScale && this.normal) this.normalScale.verify( builder ); - - if (this.environment) this.environment.verify( builder.setCache('env') ); // isolate environment from others inputs ( see TextureNode, CubeTextureNode ) - if (this.reflectivity && this.environment) this.reflectivity.verify( builder ); - + + if ( this.alpha ) this.alpha.verify( builder ); + + if ( this.ao ) this.ao.verify( builder ); + if ( this.ambient ) this.ambient.verify( builder ); + if ( this.shadow ) this.shadow.verify( builder ); + if ( this.emissive ) this.emissive.verify( builder ); + + if ( this.normal ) this.normal.verify( builder ); + if ( this.normalScale && this.normal ) this.normalScale.verify( builder ); + + if ( this.environment ) this.environment.verify( builder.setCache( 'env' ) ); // isolate environment from others inputs ( see TextureNode, CubeTextureNode ) + if ( this.reflectivity && this.environment ) this.reflectivity.verify( builder ); + // build code - + var color = this.color.buildCode( builder, 'v4' ); var roughness = this.roughness.buildCode( builder, 'fv1' ); var metalness = this.metalness.buildCode( builder, 'fv1' ); - + var alpha = this.alpha ? this.alpha.buildCode( builder, 'fv1' ) : undefined; - + var ao = this.ao ? this.ao.buildCode( builder, 'c' ) : undefined; var ambient = this.ambient ? this.ambient.buildCode( builder, 'c' ) : undefined; var shadow = this.shadow ? this.shadow.buildCode( builder, 'c' ) : undefined; var emissive = this.emissive ? this.emissive.buildCode( builder, 'c' ) : undefined; - + var normal = this.normal ? this.normal.buildCode( builder, 'v3' ) : undefined; var normalScale = this.normalScale && this.normal ? this.normalScale.buildCode( builder, 'fv1' ) : undefined; - - var environment = this.environment ? this.environment.buildCode( builder.setCache('env'), 'c' ) : undefined; + + var environment = this.environment ? this.environment.buildCode( builder.setCache( 'env' ), 'c' ) : undefined; var reflectivity = this.reflectivity && this.environment ? this.reflectivity.buildCode( builder, 'fv1' ) : undefined; - + material.needsTransparent = alpha != undefined; - + material.addFragmentPars( [ - + "varying vec3 vViewPosition;", - + "#ifndef FLAT_SHADED", " varying vec3 vNormal;", "#endif", - + THREE.ShaderChunk[ "common" ], THREE.ShaderChunk[ "fog_pars_fragment" ], THREE.ShaderChunk[ "bsdfs" ], @@ -156,113 +158,129 @@ THREE.StandardNode.prototype.build = function( builder ) { THREE.ShaderChunk[ "shadowmap_pars_fragment" ], THREE.ShaderChunk[ "logdepthbuf_pars_fragment" ], ].join( "\n" ) ); - + var output = [ // prevent undeclared normal THREE.ShaderChunk[ "normal_fragment" ], - + // prevent undeclared material " StandardMaterial material;", - + color.code, " vec4 diffuseColor = " + color.result + ";", " ReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );", - + THREE.ShaderChunk[ "logdepthbuf_fragment" ], - + roughness.code, " float roughnessFactor = " + roughness.result + ";", - + metalness.code, " float metalnessFactor = " + metalness.result + ";" - ]; - - if (alpha) { - - output.push( + ]; + + if ( alpha ) { + + output.push( alpha.code, 'if ( ' + alpha.result + ' <= ALPHATEST ) discard;' ); - + } - - if (normal) { - + + if ( normal ) { + builder.include( 'perturbNormal2Arb' ); - - output.push(normal.code); - - if (normalScale) output.push(normalScale.code); - + + output.push( normal.code ); + + if ( normalScale ) output.push( normalScale.code ); + output.push( 'normal = perturbNormal2Arb(-vViewPosition,normal,' + normal.result + ',' + new THREE.UVNode().build( builder, 'v2' ) + ',' + - (normalScale ? normalScale.result : '1.0') + ');' + ( normalScale ? normalScale.result : '1.0' ) + ');' ); } output.push( THREE.ShaderChunk[ "shadowmap_fragment" ], - + // accumulation 'material.diffuseColor = diffuseColor.rgb * ( 1.0 - metalnessFactor );', 'material.specularRoughness = clamp( roughnessFactor, 0.001, 1.0 );', // disney's remapping of [ 0, 1 ] roughness to [ 0.001, 1 ] 'material.specularColor = mix( vec3( 0.04 ), diffuseColor.rgb, metalnessFactor );', - + THREE.ShaderChunk[ "lights_template" ] ); - - if (ao) { + + if ( ao ) { + output.push( ao.code ); output.push( "reflectedLight.indirectDiffuse *= " + ao.result + ";" ); + } - - if (ambient) { + + if ( ambient ) { + output.push( ambient.code ); output.push( "reflectedLight.indirectDiffuse += " + ambient.result + ";" ); + } - - if (shadow) { + + if ( shadow ) { + output.push( shadow.code ); output.push( "reflectedLight.directDiffuse *= " + shadow.result + ";" ); output.push( "reflectedLight.directSpecular *= " + shadow.result + ";" ); + } - - if (emissive) { + + if ( emissive ) { + output.push( emissive.code ); output.push( "reflectedLight.directDiffuse += " + emissive.result + ";" ); + } - - if (environment) { + + if ( environment ) { + output.push( environment.code ); output.push( "RE_IndirectSpecular(" + environment.result + ", geometry, material, reflectedLight );" ); + } - - if (reflectivity) { + + if ( reflectivity ) { + output.push( reflectivity.code ); output.push( "reflectedLight.indirectSpecular *= " + reflectivity.result + ";" ); + } - - output.push("vec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + reflectedLight.directSpecular + reflectedLight.indirectSpecular;"); - + + output.push( "vec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + reflectedLight.directSpecular + reflectedLight.indirectSpecular;" ); + output.push( THREE.ShaderChunk[ "linear_to_gamma_fragment" ], THREE.ShaderChunk[ "fog_fragment" ] ); - - if (alpha) { + + if ( alpha ) { + output.push( "gl_FragColor = vec4( outgoingLight, " + alpha.result + " );" ); + } else { + output.push( "gl_FragColor = vec4( outgoingLight, 1.0 );" ); + } - + code = output.join( "\n" ); - + } - + return code; -}; \ No newline at end of file +}; diff --git a/examples/js/materials/nodes/interfaces/StandardNodeMaterial.js b/examples/js/materials/nodes/interfaces/StandardNodeMaterial.js index 809a914bd883528414c6d4cdcb9737100c0e8bb5..ad932382ec6f588c1f04d8186f2c0c1d853b8dcb 100644 --- a/examples/js/materials/nodes/interfaces/StandardNodeMaterial.js +++ b/examples/js/materials/nodes/interfaces/StandardNodeMaterial.js @@ -3,15 +3,15 @@ */ THREE.StandardNodeMaterial = function() { - + this.node = new THREE.StandardNode(); - + THREE.NodeMaterial.call( this, this.node, this.node ); - + }; THREE.StandardNodeMaterial.prototype = Object.create( THREE.NodeMaterial.prototype ); THREE.StandardNodeMaterial.prototype.constructor = THREE.StandardNodeMaterial; -THREE.NodeMaterial.Shortcuts( THREE.StandardNodeMaterial.prototype, 'node', -[ 'color', 'alpha', 'roughness', 'metalness', 'normal', 'normalScale', 'emissive', 'ambient', 'shadow', 'ao', 'environment', 'reflectivity', 'transform' ] ); \ No newline at end of file +THREE.NodeMaterial.Shortcuts( THREE.StandardNodeMaterial.prototype, 'node', +[ 'color', 'alpha', 'roughness', 'metalness', 'normal', 'normalScale', 'emissive', 'ambient', 'shadow', 'ao', 'environment', 'reflectivity', 'transform' ] ); diff --git a/examples/js/materials/nodes/math/Math1Node.js b/examples/js/materials/nodes/math/Math1Node.js index 5be0a56df356b4dec3a177910446e620ee2d6f7d..55ae7f8bb2d93c01a5f69052918ba4275b19daf9 100644 --- a/examples/js/materials/nodes/math/Math1Node.js +++ b/examples/js/materials/nodes/math/Math1Node.js @@ -3,13 +3,13 @@ */ THREE.Math1Node = function( a, method ) { - + THREE.TempNode.call( this ); - + this.a = a; - + this.method = method || THREE.Math1Node.SIN; - + }; THREE.Math1Node.prototype = Object.create( THREE.TempNode.prototype ); @@ -40,39 +40,39 @@ THREE.Math1Node.NEGATE = 'negate'; THREE.Math1Node.INVERT = 'invert'; THREE.Math1Node.prototype.getType = function( builder ) { - - switch(this.method) { + + switch ( this.method ) { case THREE.Math1Node.DISTANCE: return 'fv1'; } - + return this.a.getType( builder ); - + }; THREE.Math1Node.prototype.generate = function( builder, output ) { - + var material = builder.material; - + var type = this.getType( builder ); - + var result = this.a.build( builder, type ); - - switch(this.method) { - + + switch ( this.method ) { + case THREE.Math1Node.NEGATE: result = '(-' + result + ')'; break; - + case THREE.Math1Node.INVERT: result = '(1.0-' + result + ')'; break; - + default: result = this.method + '(' + result + ')'; break; } - + return builder.format( result, type, output ); -}; \ No newline at end of file +}; diff --git a/examples/js/materials/nodes/math/Math2Node.js b/examples/js/materials/nodes/math/Math2Node.js index 17c8a4ebab769f0a41268a0e6523adef14f5329e..cd675d3d118689d161aba0fab25e462d963fdb12 100644 --- a/examples/js/materials/nodes/math/Math2Node.js +++ b/examples/js/materials/nodes/math/Math2Node.js @@ -3,14 +3,14 @@ */ THREE.Math2Node = function( a, b, method ) { - + THREE.TempNode.call( this ); - + this.a = a; this.b = b; - + this.method = method || THREE.Math2Node.DISTANCE; - + }; THREE.Math2Node.prototype = Object.create( THREE.TempNode.prototype ); @@ -27,67 +27,70 @@ THREE.Math2Node.CROSS = 'cross'; THREE.Math2Node.POW = 'pow'; THREE.Math2Node.prototype.getInputType = function( builder ) { - + // use the greater length vector - if (builder.getFormatLength( this.b.getType( builder ) ) > builder.getFormatLength( this.a.getType( builder ) )) { + if ( builder.getFormatLength( this.b.getType( builder ) ) > builder.getFormatLength( this.a.getType( builder ) ) ) { + return this.b.getType( builder ); + } - + return this.a.getType( builder ); - + }; THREE.Math2Node.prototype.getType = function( builder ) { - - switch(this.method) { + + switch ( this.method ) { case THREE.Math2Node.DISTANCE: case THREE.Math2Node.DOT: return 'fv1'; - + case THREE.Math2Node.CROSS: return 'v3'; } - + return this.getInputType( builder ); + }; THREE.Math2Node.prototype.generate = function( builder, output ) { - + var material = builder.material; - + var type = this.getInputType( builder ); - - var a, b, + + var a, b, al = builder.getFormatLength( this.a.getType( builder ) ), bl = builder.getFormatLength( this.b.getType( builder ) ); - + // optimzer - - switch(this.method) { + + switch ( this.method ) { case THREE.Math2Node.CROSS: a = this.a.build( builder, 'v3' ); b = this.b.build( builder, 'v3' ); break; - + case THREE.Math2Node.STEP: a = this.a.build( builder, al == 1 ? 'fv1' : type ); b = this.b.build( builder, type ); break; - + case THREE.Math2Node.MIN: case THREE.Math2Node.MAX: case THREE.Math2Node.MODULO: a = this.a.build( builder, type ); b = this.b.build( builder, bl == 1 ? 'fv1' : type ); break; - + default: a = this.a.build( builder, type ); b = this.b.build( builder, type ); break; - + } - + return builder.format( this.method + '(' + a + ',' + b + ')', this.getType( builder ), output ); -}; \ No newline at end of file +}; diff --git a/examples/js/materials/nodes/math/Math3Node.js b/examples/js/materials/nodes/math/Math3Node.js index 2bd40c614407cfe12bf5dc922c756f9d2b4bc81f..73ec97cf34ef2ca3c24a13a5705dc85bcfd1af0c 100644 --- a/examples/js/materials/nodes/math/Math3Node.js +++ b/examples/js/materials/nodes/math/Math3Node.js @@ -3,15 +3,15 @@ */ THREE.Math3Node = function( a, b, c, method ) { - + THREE.TempNode.call( this ); - + this.a = a; this.b = b; this.c = c; - + this.method = method || THREE.Math3Node.MIX; - + }; THREE.Math3Node.prototype = Object.create( THREE.TempNode.prototype ); @@ -23,58 +23,62 @@ THREE.Math3Node.SMOOTHSTEP = 'smoothstep'; THREE.Math3Node.FACEFORWARD = 'faceforward'; THREE.Math3Node.prototype.getType = function( builder ) { - + var a = builder.getFormatLength( this.a.getType( builder ) ); var b = builder.getFormatLength( this.b.getType( builder ) ); var c = builder.getFormatLength( this.c.getType( builder ) ); - - if (a > b) { - if (a > c) return this.a.getType( builder ); + + if ( a > b ) { + + if ( a > c ) return this.a.getType( builder ); return this.c.getType( builder ); - } + + } else { - if (b > c) return this.b.getType( builder ); - + + if ( b > c ) return this.b.getType( builder ); + return this.c.getType( builder ); + } - + }; THREE.Math3Node.prototype.generate = function( builder, output ) { - + var material = builder.material; - + var type = this.getType( builder ); - + var a, b, c, al = builder.getFormatLength( this.a.getType( builder ) ), bl = builder.getFormatLength( this.b.getType( builder ) ), cl = builder.getFormatLength( this.c.getType( builder ) ) - + // optimzer - - switch(this.method) { + + switch ( this.method ) { case THREE.Math3Node.REFRACT: a = this.a.build( builder, type ); b = this.b.build( builder, type ); c = this.c.build( builder, 'fv1' ); break; - + case THREE.Math3Node.MIX: case THREE.Math3Node.SMOOTHSTEP: a = this.a.build( builder, type ); b = this.b.build( builder, type ); c = this.c.build( builder, cl == 1 ? 'fv1' : type ); break; - + default: a = this.a.build( builder, type ); b = this.b.build( builder, type ); c = this.c.build( builder, type ); break; - + } - + return builder.format( this.method + '(' + a + ',' + b + ',' + c + ')', type, output ); -}; \ No newline at end of file +}; diff --git a/examples/js/materials/nodes/math/OperatorNode.js b/examples/js/materials/nodes/math/OperatorNode.js index 0b86c85d3fe3912c5feef02dbc153c5c1310990b..623073c72239fc9f8b7c51c8f0d4c9be88a6153a 100644 --- a/examples/js/materials/nodes/math/OperatorNode.js +++ b/examples/js/materials/nodes/math/OperatorNode.js @@ -1,16 +1,16 @@ /** * @author sunag / http://www.sunag.com.br/ */ - + THREE.OperatorNode = function( a, b, op ) { - + THREE.TempNode.call( this ); - + this.op = op || THREE.OperatorNode.ADD; - + this.a = a; this.b = b; - + }; THREE.OperatorNode.prototype = Object.create( THREE.TempNode.prototype ); @@ -22,24 +22,26 @@ THREE.OperatorNode.MUL = '*'; THREE.OperatorNode.DIV = '/'; THREE.OperatorNode.prototype.getType = function( builder ) { - + // use the greater length vector - if (builder.getFormatLength( this.b.getType( builder ) ) > builder.getFormatLength( this.a.getType( builder ) )) { + if ( builder.getFormatLength( this.b.getType( builder ) ) > builder.getFormatLength( this.a.getType( builder ) ) ) { + return this.b.getType( builder ); + } - + return this.a.getType( builder ); }; THREE.OperatorNode.prototype.generate = function( builder, output ) { - + var material = builder.material; var data = material.getDataNode( this.uuid ); - + var a = this.a.build( builder, output ); var b = this.b.build( builder, output ); - + return '(' + a + this.op + b + ')'; -}; \ No newline at end of file +}; diff --git a/examples/js/materials/nodes/utils/JoinNode.js b/examples/js/materials/nodes/utils/JoinNode.js index 93487fbb79d142f4072a2d182b2033b512260e6d..4a1b12d0b6098c9d40f0b0b9357a526f6b05d6cd 100644 --- a/examples/js/materials/nodes/utils/JoinNode.js +++ b/examples/js/materials/nodes/utils/JoinNode.js @@ -3,63 +3,67 @@ */ THREE.JoinNode = function( x, y, z, w ) { - + THREE.GLNode.call( this, 'fv1' ); - + this.x = x; this.y = y; this.z = z; this.w = w; - + }; THREE.JoinNode.prototype = Object.create( THREE.GLNode.prototype ); THREE.JoinNode.prototype.constructor = THREE.JoinNode; -THREE.JoinNode.inputs = ['x','y','z','w']; +THREE.JoinNode.inputs = [ 'x', 'y', 'z', 'w' ]; THREE.JoinNode.prototype.getNumElements = function() { - + var inputs = THREE.JoinNode.inputs; var i = inputs.length; - - while (i--) { - if ( this[ inputs[i] ] !== undefined ) { - ++i; + + while ( i -- ) { + + if ( this[ inputs[ i ] ] !== undefined ) { + + ++ i; break; + } + } - - return Math.max(i, 2); - + + return Math.max( i, 2 ); + }; THREE.JoinNode.prototype.getType = function( builder ) { - + return builder.getFormatByLength( this.getNumElements() ); - + }; THREE.JoinNode.prototype.generate = function( builder, output ) { - + var material = builder.material; - + var type = this.getType( builder ); var length = this.getNumElements(); - + var inputs = THREE.JoinNode.inputs; var outputs = []; - - for(var i = 0; i < length; i++) { - - var elm = this[inputs[i]]; - + + for ( var i = 0; i < length; i ++ ) { + + var elm = this[ inputs[ i ]]; + outputs.push( elm ? elm.build( builder, 'fv1' ) : '0.' ); - + } - - var code = builder.getFormatConstructor(length) + '(' + outputs.join(',') + ')'; - + + var code = builder.getFormatConstructor( length ) + '(' + outputs.join( ',' ) + ')'; + return builder.format( code, type, output ); -}; \ No newline at end of file +}; diff --git a/examples/js/materials/nodes/utils/RoughnessToBlinnExponentNode.js b/examples/js/materials/nodes/utils/RoughnessToBlinnExponentNode.js index b7dd1128f8fa6a5af9e9493325322cafac8cd47b..5982f614d9b3215296d3da5353b42d00c7a0ed6e 100644 --- a/examples/js/materials/nodes/utils/RoughnessToBlinnExponentNode.js +++ b/examples/js/materials/nodes/utils/RoughnessToBlinnExponentNode.js @@ -3,42 +3,42 @@ */ THREE.RoughnessToBlinnExponentNode = function() { - - THREE.TempNode.call( this, 'fv1', {unique:true} ); - + + THREE.TempNode.call( this, 'fv1', { unique: true } ); + }; THREE.RoughnessToBlinnExponentNode.prototype = Object.create( THREE.TempNode.prototype ); THREE.RoughnessToBlinnExponentNode.prototype.constructor = THREE.RoughnessToBlinnExponentNode; THREE.RoughnessToBlinnExponentNode.prototype.generate = function( builder, output ) { - + var material = builder.material; - - if (builder.isShader('fragment')) { - - if (material.isDefined('STANDARD')) { - - material.addFragmentNode('float specularMIPLevel = GGXRoughnessToBlinnExponent( 1.0 - material.specularRoughness );'); - + + if ( builder.isShader( 'fragment' ) ) { + + if ( material.isDefined( 'STANDARD' ) ) { + + material.addFragmentNode( 'float specularMIPLevel = GGXRoughnessToBlinnExponent( 1.0 - material.specularRoughness );' ); + } else { - - console.warn("THREE.RoughnessToBlinnExponentNode is compatible with StandardMaterial only"); - - material.addFragmentNode('float specularMIPLevel = 0.0;'); - + + console.warn( "THREE.RoughnessToBlinnExponentNode is compatible with StandardMaterial only" ); + + material.addFragmentNode( 'float specularMIPLevel = 0.0;' ); + } - + return builder.format( 'specularMIPLevel', this.type, output ); - + } else { - - console.warn("THREE.RoughnessToBlinnExponentNode is not compatible with " + builder.shader + " shader"); - + + console.warn( "THREE.RoughnessToBlinnExponentNode is not compatible with " + builder.shader + " shader" ); + return builder.format( '0.0', this.type, output ); - + } -}; \ No newline at end of file +}; diff --git a/examples/js/materials/nodes/utils/SwitchNode.js b/examples/js/materials/nodes/utils/SwitchNode.js index a6b91815f394675eab0e1c8d312a825a9de1a8d0..7f620b41c21bf37d27a877ef520dbbb688ec5e0f 100644 --- a/examples/js/materials/nodes/utils/SwitchNode.js +++ b/examples/js/materials/nodes/utils/SwitchNode.js @@ -3,64 +3,66 @@ */ THREE.SwitchNode = function( a, component ) { - + THREE.GLNode.call( this, 'fv1' ); - + this.component = component || 'x'; - + this.a = a; - + }; THREE.SwitchNode.prototype = Object.create( THREE.GLNode.prototype ); THREE.SwitchNode.prototype.constructor = THREE.SwitchNode; THREE.SwitchNode.prototype.getType = function( builder ) { - + return builder.getFormatByLength( this.component.length ); - + }; THREE.SwitchNode.prototype.generate = function( builder, output ) { - + var type = this.a.getType( builder ); var inputLength = builder.getFormatLength( type ) - 1; - + var a = this.a.build( builder, type ); - + var outputLength = 0; - + var i, len = this.component.length; - + // get max length - - for (i = 0; i < len; i++) { - - outputLength = Math.max( outputLength, builder.getElementIndex( this.component.charAt(i) ) ); - + + for ( i = 0; i < len; i ++ ) { + + outputLength = Math.max( outputLength, builder.getElementIndex( this.component.charAt( i ) ) ); + } - - if (outputLength > inputLength) outputLength = inputLength; - + + if ( outputLength > inputLength ) outputLength = inputLength; + // build switch - + a += '.'; - - for (i = 0; i < len; i++) { - - var elm = this.component.charAt(i); - var idx = builder.getElementIndex( this.component.charAt(i) ); - - if (idx > outputLength) idx = outputLength; - - if (builder.getElementByIndex( idx ) == undefined) { + + for ( i = 0; i < len; i ++ ) { + + var elm = this.component.charAt( i ); + var idx = builder.getElementIndex( this.component.charAt( i ) ); + + if ( idx > outputLength ) idx = outputLength; + + if ( builder.getElementByIndex( idx ) == undefined ) { + console.log( builder.getElementByIndex( idx ) ); + } - + a += builder.getElementByIndex( idx ); - + } - + return builder.format( a, this.type, output ); -}; \ No newline at end of file +}; diff --git a/examples/js/materials/nodes/utils/TimeNode.js b/examples/js/materials/nodes/utils/TimeNode.js index 376d77555d8014c347d2c8fb009a7025aef4724b..7ab6763aa4cbcee3fb12f818e7eb9ae53f7de64f 100644 --- a/examples/js/materials/nodes/utils/TimeNode.js +++ b/examples/js/materials/nodes/utils/TimeNode.js @@ -3,18 +3,18 @@ */ THREE.TimeNode = function( value ) { - + THREE.FloatNode.call( this, value ); - + this.requestUpdate = true; - + }; THREE.TimeNode.prototype = Object.create( THREE.FloatNode.prototype ); THREE.TimeNode.prototype.constructor = THREE.TimeNode; THREE.TimeNode.prototype.updateAnimation = function( delta ) { - + this.number += delta; - -}; \ No newline at end of file + +}; diff --git a/examples/webgl_materials_nodes.html b/examples/webgl_materials_nodes.html index 31793bf29a3c3b12bf194b0bfe45669bd97e6556..c8e3508a25a9231464dd718def63d652f202a978 100644 --- a/examples/webgl_materials_nodes.html +++ b/examples/webgl_materials_nodes.html @@ -99,23 +99,23 @@ var controls; var move = false; var gui, guiElements = []; - + var param = { example: 'standard' }; var brick = new THREE.TextureLoader().load( 'textures/brick_diffuse.jpg' ); var grass = new THREE.TextureLoader().load( 'textures/terrain/grasslight-big.jpg' ); var grassNormal = new THREE.TextureLoader().load( 'textures/terrain/grasslight-big-nm.jpg' ); - + var decalDiffuse = new THREE.TextureLoader().load( 'textures/decal/decal-diffuse.png' ); decalDiffuse.wrapS = decalDiffuse.wrapT = THREE.RepeatWrapping; - + var decalNormal = new THREE.TextureLoader().load( 'textures/decal/decal-normal.jpg' ); - + var cloud = new THREE.TextureLoader().load( 'textures/lava/cloud.png' ); cloud.wrapS = cloud.wrapT = THREE.RepeatWrapping; - + var cubemap = function() { - + var path = "textures/cube/Park2/"; var format = '.jpg'; var urls = [ @@ -123,14 +123,14 @@ path + 'posy' + format, path + 'negy' + format, path + 'posz' + format, path + 'negz' + format ]; - + var textureCube = new THREE.CubeTextureLoader().load( urls ); textureCube.format = THREE.RGBFormat; - + return textureCube; - + }() - + window.addEventListener( 'load', init ); function init() { @@ -144,7 +144,7 @@ camera = new THREE.PerspectiveCamera( fov, window.innerWidth / window.innerHeight, 1, 1000 ); camera.position.x = 50; - camera.position.z = -50; + camera.position.z = - 50; camera.position.y = 30; camera.target = new THREE.Vector3(); @@ -159,34 +159,34 @@ scene.add( light ); var light = new THREE.DirectionalLight( 0xccccff, 1 ); - light.position.set( -1, 0.75, -0.5 ); + light.position.set( - 1, 0.75, - 0.5 ); scene.add( light ); teapot = new THREE.TeapotBufferGeometry( 15, 18 ); - + mesh = new THREE.Mesh( teapot ); scene.add( mesh ); - + window.addEventListener( 'resize', onWindowResize, false ); updateMaterial(); - + onWindowResize(); animate(); } - + function clearGui() { - - if (gui) gui.destroy(); - + + if ( gui ) gui.destroy(); + gui = new dat.GUI(); - - var example = gui.add( param, 'example', { + + var example = gui.add( param, 'example', { 'basic / standard (PBR)': 'standard', 'basic / phong': 'phong', 'basic / layers': 'layers', - 'basic / rim': 'rim', + 'basic / rim': 'rim', 'adv / fresnel': 'fresnel', 'adv / saturation': 'saturation', 'adv / top-bottom': 'top-bottom', @@ -197,64 +197,64 @@ 'adv / wave': 'wave', 'misc / smoke' : 'smoke', 'misc / firefly' : 'firefly' - } ).onFinishChange(function() { - + } ).onFinishChange( function() { + updateMaterial(); - + } ); - + gui.open(); - + } - + function addGui( name, value, callback, isColor, min, max ) { - + var node; - - param[name] = value; - - if (isColor) { - - node = gui.addColor( param, name ).onChange(function() { - - callback( param[name] ); - + + param[ name ] = value; + + if ( isColor ) { + + node = gui.addColor( param, name ).onChange( function() { + + callback( param[ name ] ); + } ); - + } else { - - node = gui.add( param, name, min, max ).onChange(function() { - - callback( param[name] ); - + + node = gui.add( param, name, min, max ).onChange( function() { + + callback( param[ name ] ); + } ); - + } - + return node; - + } function updateMaterial() { - + move = false; - - if (mesh.material) mesh.material.dispose(); - + + if ( mesh.material ) mesh.material.dispose(); + var name = param.example; - var mtl; - + var mtl; + clearGui(); - - switch( name ) { - + + switch ( name ) { + case 'phong': - + // MATERIAL - + mtl = new THREE.PhongNodeMaterial(); - + //mtl.color = // albedo color //mtl.alpha = // opacity (0 at 1) //mtl.specular = // specular color @@ -268,25 +268,25 @@ //mtl.environment = // reflection map (CubeMap recommended) //mtl.reflectivity = // environment intensity //mtl.transform = // vertex transformation - - var mask = new THREE.SwitchNode(new THREE.TextureNode(decalDiffuse), 'w'); - - mtl.color = new THREE.TextureNode(grass); - mtl.specular = new THREE.FloatNode(.5); - mtl.shininess = new THREE.FloatNode(15); - mtl.environment = new THREE.CubeTextureNode(cubemap); + + var mask = new THREE.SwitchNode( new THREE.TextureNode( decalDiffuse ), 'w' ); + + mtl.color = new THREE.TextureNode( grass ); + mtl.specular = new THREE.FloatNode( .5 ); + mtl.shininess = new THREE.FloatNode( 15 ); + mtl.environment = new THREE.CubeTextureNode( cubemap ); mtl.reflectivity = mask; - mtl.normal = new THREE.TextureNode(grassNormal); - mtl.normalScale = new THREE.Math1Node( mask, THREE.Math1Node.INVERT ); - + mtl.normal = new THREE.TextureNode( grassNormal ); + mtl.normalScale = new THREE.Math1Node( mask, THREE.Math1Node.INVERT ); + break; - + case 'standard': - + // MATERIAL - + mtl = new THREE.StandardNodeMaterial(); - + //mtl.color = // albedo color //mtl.alpha = // opacity (0 at 1) //mtl.roughness = // roughness (float) @@ -300,680 +300,680 @@ //mtl.environment = // reflection map (CubeMap recommended) //mtl.reflectivity = // environment intensity //mtl.transform = // vertex transformation - - var mask = new THREE.SwitchNode(new THREE.TextureNode(decalDiffuse), 'w'); - - var normalScale = new THREE.FloatNode(.3); - - var roughnessA = new THREE.FloatNode(.5); - var metalnessA = new THREE.FloatNode(.5); - - var roughnessB = new THREE.FloatNode(0); - var metalnessB = new THREE.FloatNode(1); + + var mask = new THREE.SwitchNode( new THREE.TextureNode( decalDiffuse ), 'w' ); + + var normalScale = new THREE.FloatNode( .3 ); + + var roughnessA = new THREE.FloatNode( .5 ); + var metalnessA = new THREE.FloatNode( .5 ); + + var roughnessB = new THREE.FloatNode( 0 ); + var metalnessB = new THREE.FloatNode( 1 ); var roughness = new THREE.Math3Node( roughnessA, roughnessB, mask, THREE.Math3Node.MIX - ); - + ); + var metalness = new THREE.Math3Node( metalnessA, metalnessB, mask, THREE.Math3Node.MIX ); - + var normalMask = new THREE.OperatorNode( new THREE.Math1Node( mask, THREE.Math1Node.INVERT ), normalScale, THREE.OperatorNode.MUL ); - - mtl.color = new THREE.ColorNode(0xFFFFFF); + + mtl.color = new THREE.ColorNode( 0xFFFFFF ); mtl.roughness = roughness; mtl.metalness = metalness; - mtl.environment = new THREE.CubeTextureNode(cubemap); - mtl.normal = new THREE.TextureNode(grassNormal); + mtl.environment = new THREE.CubeTextureNode( cubemap ); + mtl.normal = new THREE.TextureNode( grassNormal ); mtl.normalScale = normalMask; - + // GUI - + addGui( 'color', mtl.color.value.getHex(), function( val ) { - + mtl.color.value.setHex( val ); - + }, true ); - + addGui( 'roughnessA', roughnessA.number, function( val ) { - + roughnessA.number = val; }, false, 0, 1 ); - + addGui( 'metalnessA', metalnessA.number, function( val ) { - + metalnessA.number = val; }, false, 0, 1 ); - + addGui( 'roughnessB', roughnessB.number, function( val ) { - + roughnessB.number = val; }, false, 0, 1 ); - + addGui( 'metalnessB', metalnessB.number, function( val ) { - + metalnessB.number = val; }, false, 0, 1 ); - + addGui( 'normalScale', normalScale.number, function( val ) { - + normalScale.number = val; }, false, 0, 1 ); - + break; - + case 'wave': - + // MATERIAL - + mtl = new THREE.PhongNodeMaterial(); - + var time = new THREE.TimeNode(); - var speed = new THREE.FloatNode(5); - var scale = new THREE.FloatNode(1); - var worldScale = new THREE.FloatNode(.4); - var colorA = new THREE.ColorNode(0xFFFFFF); - var colorB = new THREE.ColorNode(0x0054df); - + var speed = new THREE.FloatNode( 5 ); + var scale = new THREE.FloatNode( 1 ); + var worldScale = new THREE.FloatNode( .4 ); + var colorA = new THREE.ColorNode( 0xFFFFFF ); + var colorB = new THREE.ColorNode( 0x0054df ); + var uv = new THREE.UVNode(); - + var timeScale = new THREE.OperatorNode( time, speed, THREE.OperatorNode.MUL ); - + var worldScl = new THREE.OperatorNode( new THREE.PositionNode(), worldScale, THREE.OperatorNode.MUL ); - + var posContinuous = new THREE.OperatorNode( worldScl, timeScale, THREE.OperatorNode.ADD ); - - var wave = new THREE.Math1Node(posContinuous, THREE.Math1Node.SIN); - wave = new THREE.SwitchNode(wave, 'x'); - + + var wave = new THREE.Math1Node( posContinuous, THREE.Math1Node.SIN ); + wave = new THREE.SwitchNode( wave, 'x' ); + var waveScale = new THREE.OperatorNode( wave, scale, THREE.OperatorNode.MUL ); - + var displaceY = new THREE.JoinNode( new THREE.FloatNode(), waveScale, new THREE.FloatNode() ); - + var displace = new THREE.OperatorNode( new THREE.NormalNode(), displaceY, THREE.OperatorNode.MUL ); - + var blend = new THREE.OperatorNode( new THREE.PositionNode(), displaceY, THREE.OperatorNode.ADD ); - + var color = new THREE.Math3Node( colorB, colorA, wave, THREE.Math3Node.MIX ); - + mtl.color = color; mtl.transform = blend; // GUI - + addGui( 'speed', speed.number, function( val ) { - + speed.number = val; }, false, 0, 10 ); - + addGui( 'scale', scale.number, function( val ) { - + scale.number = val; }, false, 0, 3 ); - + addGui( 'worldScale', worldScale.number, function( val ) { - + worldScale.number = val; }, false, 0, 1 ); - + addGui( 'colorA', colorA.value.getHex(), function( val ) { - + colorA.value.setHex( val ); - + }, true ); - + addGui( 'colorB', colorB.value.getHex(), function( val ) { - + colorB.value.setHex( val ); - + }, true ); - + addGui( 'useNormals', false, function( val ) { - + blend.b = val ? displace : displaceY; - + mtl.build(); - + } ); - + break; - + case 'rim': - + // MATERIAL - + mtl = new THREE.PhongNodeMaterial(); - + var intensity = 1.3; - var power = new THREE.FloatNode(3); - var color = new THREE.ColorNode(0xFFFFFF); - + var power = new THREE.FloatNode( 3 ); + var color = new THREE.ColorNode( 0xFFFFFF ); + var viewZ = new THREE.Math2Node( - new THREE.NormalNode( THREE.NormalNode.VIEW ), - new THREE.Vector3Node(0, 0, -intensity), + new THREE.NormalNode( THREE.NormalNode.VIEW ), + new THREE.Vector3Node( 0, 0, - intensity ), THREE.Math2Node.DOT ); - + var rim = new THREE.OperatorNode( viewZ, - new THREE.FloatNode(intensity), + new THREE.FloatNode( intensity ), THREE.OperatorNode.ADD ); - + var rimPower = new THREE.Math2Node( - rim, - power, + rim, + power, THREE.Math2Node.POW ); - + var rimColor = new THREE.OperatorNode( rimPower, color, THREE.OperatorNode.MUL ); - - mtl.color = new THREE.ColorNode(0x111111); - mtl.emissive = rimColor; - + + mtl.color = new THREE.ColorNode( 0x111111 ); + mtl.emissive = rimColor; + // GUI - + addGui( 'color', color.value.getHex(), function( val ) { - + color.value.setHex( val ); - + }, true ); - + addGui( 'intensity', intensity, function( val ) { - + intensity = val; - - viewZ.b.z = -intensity; + + viewZ.b.z = - intensity; rim.b.number = intensity; - - + + }, false, 0, 3 ); - + addGui( 'power', power.number, function( val ) { - + power.number = val; - + }, false, 0, 6 ); - + addGui( 'xray', false, function( val ) { - - if (val) { - - mtl.emissive = color; - mtl.alpha = rimPower; + + if ( val ) { + + mtl.emissive = color; + mtl.alpha = rimPower; mtl.blending = THREE.AdditiveBlending; mtl.depthWrite = false; - + } else { - - mtl.emissive = rimColor; + + mtl.emissive = rimColor; mtl.alpha = null; mtl.blending = THREE.NormalBlending; mtl.depthWrite = true; - + } - + mtl.build(); - + } ); - + break; - + case 'fresnel': - + // MATERIAL - + mtl = new THREE.PhongNodeMaterial(); - - var reflectance = new THREE.FloatNode(1.3); - var power = new THREE.FloatNode(1); - var color = new THREE.CubeTextureNode(cubemap); - + + var reflectance = new THREE.FloatNode( 1.3 ); + var power = new THREE.FloatNode( 1 ); + var color = new THREE.CubeTextureNode( cubemap ); + var viewZ = new THREE.Math2Node( - new THREE.NormalNode( THREE.NormalNode.VIEW ), - new THREE.Vector3Node(0, 0, -1), + new THREE.NormalNode( THREE.NormalNode.VIEW ), + new THREE.Vector3Node( 0, 0, - 1 ), THREE.Math2Node.DOT ); - + var theta = new THREE.OperatorNode( viewZ, - new THREE.FloatNode(1), + new THREE.FloatNode( 1 ), THREE.OperatorNode.ADD ); - + var thetaPower = new THREE.Math2Node( - theta, - power, + theta, + power, THREE.Math2Node.POW ); - + var fresnel = new THREE.OperatorNode( reflectance, thetaPower, THREE.OperatorNode.MUL ); - - mtl.color = new THREE.ColorNode(0x3399FF); + + mtl.color = new THREE.ColorNode( 0x3399FF ); mtl.environment = color; mtl.reflectivity = new THREE.Math1Node( fresnel, THREE.Math1Node.SAT ); - + // GUI - + addGui( 'reflectance', reflectance.number, function( val ) { - + reflectance.number = val; }, false, 0, 3 ); - + addGui( 'power', power.number, function( val ) { - + power.number = val; }, false, 0, 5 ); - + break; - + case 'layers': - + // MATERIAL - + mtl = new THREE.PhongNodeMaterial(); - - var tex1 = new THREE.TextureNode(grass); - var tex2 = new THREE.TextureNode(brick); - - var offset = new THREE.FloatNode(0); - var scale = new THREE.FloatNode(1); + + var tex1 = new THREE.TextureNode( grass ); + var tex2 = new THREE.TextureNode( brick ); + + var offset = new THREE.FloatNode( 0 ); + var scale = new THREE.FloatNode( 1 ); var uv = new THREE.UVNode(); - + var uvOffset = new THREE.OperatorNode( offset, uv, THREE.OperatorNode.ADD ); - + var uvScale = new THREE.OperatorNode( uvOffset, scale, THREE.OperatorNode.MUL ); - - var mask = new THREE.TextureNode(decalDiffuse, uvScale); - var maskAlphaChannel = new THREE.SwitchNode(mask, 'w'); - + + var mask = new THREE.TextureNode( decalDiffuse, uvScale ); + var maskAlphaChannel = new THREE.SwitchNode( mask, 'w' ); + var blend = new THREE.Math3Node( tex1, tex2, maskAlphaChannel, THREE.Math3Node.MIX ); - + mtl.color = blend; - + // GUI - + addGui( 'offset', offset.number, function( val ) { - + offset.number = val; }, false, 0, 1 ); - + addGui( 'scale', scale.number, function( val ) { - + scale.number = val; }, false, 0, 10 ); - + break; - + case 'saturation': - + // MATERIAL - + mtl = new THREE.StandardNodeMaterial(); - - var tex = new THREE.TextureNode(brick); - var sat = new THREE.FloatNode(0); - - var satrgb = new THREE.FunctionNode([ + + var tex = new THREE.TextureNode( brick ); + var sat = new THREE.FloatNode( 0 ); + + var satrgb = new THREE.FunctionNode( [ "vec3 satrgb(vec3 rgb, float adjustment) {", //"const vec3 W = vec3(0.2125, 0.7154, 0.0721);", // LUMA "vec3 intensity = vec3(dot(rgb, LUMA));", "return mix(intensity, rgb, adjustment);", "}" - ].join( "\n" )); - - var saturation = new THREE.FunctionCallNode(satrgb); + ].join( "\n" ) ); + + var saturation = new THREE.FunctionCallNode( satrgb ); saturation.input.rgb = tex; saturation.input.adjustment = sat; - + // or try - + //saturation.input[0] = tex; //saturation.input[1] = sat; - + mtl.color = saturation; - mtl.environment = new THREE.CubeTextureNode(cubemap); // optional - + mtl.environment = new THREE.CubeTextureNode( cubemap ); // optional + // GUI - + addGui( 'saturation', sat.number, function( val ) { - + sat.number = val; }, false, 0, 2 ); - + break; - + case 'top-bottom': - + // MATERIAL - + mtl = new THREE.PhongNodeMaterial(); - - var top = new THREE.TextureNode(grass); - var bottom = new THREE.TextureNode(brick); - + + var top = new THREE.TextureNode( grass ); + var bottom = new THREE.TextureNode( brick ); + var normal = new THREE.NormalNode( THREE.NormalNode.WORLD ); - var normalY = new THREE.SwitchNode(normal, 'y'); - - var hard = new THREE.FloatNode(9); - var offset = new THREE.FloatNode(-2.5); - + var normalY = new THREE.SwitchNode( normal, 'y' ); + + var hard = new THREE.FloatNode( 9 ); + var offset = new THREE.FloatNode( - 2.5 ); + var hardClamp = new THREE.OperatorNode( normalY, hard, THREE.OperatorNode.MUL ); - + var offsetClamp = new THREE.OperatorNode( hardClamp, offset, THREE.OperatorNode.ADD ); - + var clamp0at1 = new THREE.Math1Node( offsetClamp, THREE.Math1Node.SAT ); - - var blend = new THREE.Math3Node(top,bottom,clamp0at1,THREE.Math3Node.MIX); - + + var blend = new THREE.Math3Node( top, bottom, clamp0at1, THREE.Math3Node.MIX ); + mtl.color = blend; - + // GUI - + addGui( 'hard', hard.number, function( val ) { - + hard.number = val; }, false, 0, 20 ); - + addGui( 'offset', offset.number, function( val ) { - + offset.number = val; - }, false, -10, 10 ); - + }, false, - 10, 10 ); + break; - + case 'displace': - + // MATERIAL - + mtl = new THREE.PhongNodeMaterial(); - + var time = new THREE.TimeNode(); - var scale = new THREE.FloatNode(2); - var speed = new THREE.FloatNode(.2); - var colorA = new THREE.ColorNode(0xFFFFFF); - var colorB = new THREE.ColorNode(0x0054df); - + var scale = new THREE.FloatNode( 2 ); + var speed = new THREE.FloatNode( .2 ); + var colorA = new THREE.ColorNode( 0xFFFFFF ); + var colorB = new THREE.ColorNode( 0x0054df ); + var uv = new THREE.UVNode(); - + var timeScl = new THREE.OperatorNode( time, speed, THREE.OperatorNode.MUL ); - + var displaceOffset = new THREE.OperatorNode( timeScl, uv, THREE.OperatorNode.ADD ); - - var tex = new THREE.TextureNode(cloud, displaceOffset); - var texArea = new THREE.SwitchNode(tex, 'w'); - + + var tex = new THREE.TextureNode( cloud, displaceOffset ); + var texArea = new THREE.SwitchNode( tex, 'w' ); + var displace = new THREE.OperatorNode( new THREE.NormalNode(), texArea, THREE.OperatorNode.MUL ); - + var displaceScale = new THREE.OperatorNode( displace, scale, THREE.OperatorNode.MUL ); - + var blend = new THREE.OperatorNode( new THREE.PositionNode(), displaceScale, THREE.OperatorNode.ADD ); - + var color = new THREE.Math3Node( colorB, colorA, texArea, THREE.Math3Node.MIX ); - - mtl.color = mtl.specular = new THREE.ColorNode(0); + + mtl.color = mtl.specular = new THREE.ColorNode( 0 ); mtl.emissive = color; mtl.transform = blend; - + // GUI - + addGui( 'speed', speed.number, function( val ) { - + speed.number = val; }, false, 0, 1 ); - + addGui( 'scale', scale.number, function( val ) { - + scale.number = val; }, false, 0, 10 ); - + addGui( 'colorA', colorA.value.getHex(), function( val ) { - + colorA.value.setHex( val ); - + }, true ); - + addGui( 'colorB', colorB.value.getHex(), function( val ) { - + colorB.value.setHex( val ); - + }, true ); - + break; - + case 'smoke': - + // MATERIAL - + mtl = new THREE.PhongNodeMaterial(); - + var time = new THREE.TimeNode(); var uv = new THREE.UVNode(); - + var timeSpeedA = new THREE.OperatorNode( time, - new THREE.Vector2Node(0.3, 0.1), + new THREE.Vector2Node( 0.3, 0.1 ), THREE.OperatorNode.MUL ); - + var timeSpeedB = new THREE.OperatorNode( time, - new THREE.Vector2Node(0.15, 0.4), + new THREE.Vector2Node( 0.15, 0.4 ), THREE.OperatorNode.MUL ); - + var uvOffsetA = new THREE.OperatorNode( timeSpeedA, uv, THREE.OperatorNode.ADD ); - + var uvOffsetB = new THREE.OperatorNode( timeSpeedB, uv, THREE.OperatorNode.ADD ); - - var cloudA = new THREE.TextureNode(cloud, uvOffsetA); - var cloudB = new THREE.TextureNode(cloud, uvOffsetB); - + + var cloudA = new THREE.TextureNode( cloud, uvOffsetA ); + var cloudB = new THREE.TextureNode( cloud, uvOffsetB ); + var clouds = new THREE.OperatorNode( cloudA, cloudB, THREE.OperatorNode.ADD ); - - mtl.environment = new THREE.ColorNode(0xFFFFFF); + + mtl.environment = new THREE.ColorNode( 0xFFFFFF ); mtl.alpha = clouds; - + // GUI - + addGui( 'color', mtl.environment.value.getHex(), function( val ) { - + mtl.environment.value.setHex( val ); }, true ); - + break; - + case 'camera-depth': - + // MATERIAL - - var colorA = new THREE.ColorNode(0xFFFFFF); - var colorB = new THREE.ColorNode(0x0054df); - + + var colorA = new THREE.ColorNode( 0xFFFFFF ); + var colorB = new THREE.ColorNode( 0x0054df ); + var depth = new THREE.CameraNode( THREE.CameraNode.DEPTH ); depth.near.number = 1; depth.far.number = 200; - + var colors = new THREE.Math3Node( colorB, colorA, depth, THREE.Math3Node.MIX ); - + mtl = new THREE.PhongNodeMaterial(); mtl.color = colors; - + // GUI - + addGui( 'near', depth.near.number, function( val ) { - + depth.near.number = val; }, false, 1, 1200 ); - + addGui( 'far', depth.far.number, function( val ) { - + depth.far.number = val; }, false, 1, 1200 ); - + addGui( 'nearColor', colorA.value.getHex(), function( val ) { - + colorA.value.setHex( val ); - + }, true ); - + addGui( 'farColor', colorB.value.getHex(), function( val ) { - + colorB.value.setHex( val ); - + }, true ); - + break; - + case 'caustic': - + // MATERIAL - + mtl = new THREE.StandardNodeMaterial(); - - var hash2 = new THREE.FunctionNode([ + + var hash2 = new THREE.FunctionNode( [ "vec2 hash2(vec2 p) {", "return fract(sin(vec2(dot(p, vec2(123.4, 748.6)), dot(p, vec2(547.3, 659.3))))*5232.85324);", "}" - ].join( "\n" )); - - var voronoi = new THREE.FunctionNode([ + ].join( "\n" ) ); + + var voronoi = new THREE.FunctionNode( [ // Based off of iq's described here: http://www.iquilezles.org/www/articles/voronoili "float voronoi(vec2 p, in float time) {", "vec2 n = floor(p);", @@ -995,9 +995,9 @@ "}", "return md;", "}" - ].join( "\n" ), [hash2]); // define hash2 as dependencies - - var voronoiLayers = new THREE.FunctionNode([ + ].join( "\n" ), [ hash2 ] ); // define hash2 as dependencies + + var voronoiLayers = new THREE.FunctionNode( [ // based on https://www.shadertoy.com/view/4tXSDf "float voronoiLayers(vec2 p, in float time) {", "float v = 0.0;", @@ -1009,267 +1009,267 @@ "}", "return v;", "}" - ].join( "\n" ), [voronoi]); // define voronoi as dependencies + ].join( "\n" ), [ voronoi ] ); // define voronoi as dependencies var time = new THREE.TimeNode(); - var timeScale = new THREE.FloatNode(2); - - var alpha = new THREE.FloatNode(1); - var scale = new THREE.FloatNode(.1); - var intensity = new THREE.FloatNode(1.5); - - var color = new THREE.ColorNode(0xFFFFFF); - var colorA = new THREE.ColorNode(0xFFFFFF); - var colorB = new THREE.ColorNode(0x0054df); - + var timeScale = new THREE.FloatNode( 2 ); + + var alpha = new THREE.FloatNode( 1 ); + var scale = new THREE.FloatNode( .1 ); + var intensity = new THREE.FloatNode( 1.5 ); + + var color = new THREE.ColorNode( 0xFFFFFF ); + var colorA = new THREE.ColorNode( 0xFFFFFF ); + var colorB = new THREE.ColorNode( 0x0054df ); + var worldPos = new THREE.PositionNode( THREE.PositionNode.WORLD ); - var worldPosTop = new THREE.SwitchNode(worldPos, 'xz'); - + var worldPosTop = new THREE.SwitchNode( worldPos, 'xz' ); + var pos = new THREE.PositionNode( THREE.PositionNode.WORLD ); - var posNorm = new THREE.Math1Node(pos, THREE.Math1Node.NORMALIZE); - - var mask = new THREE.SwitchNode(posNorm, 'y'); - + var posNorm = new THREE.Math1Node( pos, THREE.Math1Node.NORMALIZE ); + + var mask = new THREE.SwitchNode( posNorm, 'y' ); + // clamp0at1 mask = new THREE.Math1Node( mask, THREE.Math1Node.SAT ); - + var timeOffset = new THREE.OperatorNode( time, timeScale, THREE.OperatorNode.MUL - ); - + ); + var uvPos = new THREE.OperatorNode( worldPosTop, scale, THREE.OperatorNode.MUL - ); - - var voronoi = new THREE.FunctionCallNode(voronoiLayers); + ); + + var voronoi = new THREE.FunctionCallNode( voronoiLayers ); voronoi.input.p = uvPos; voronoi.input.time = timeOffset; - + var maskCaustic = new THREE.OperatorNode( alpha, mask, THREE.OperatorNode.MUL - ); - + ); + var voronoiIntensity = new THREE.OperatorNode( voronoi, intensity, THREE.OperatorNode.MUL - ); - + ); + var voronoiColors = new THREE.Math3Node( colorB, colorA, new THREE.Math1Node( voronoiIntensity, THREE.Math1Node.SAT ), // mix needs clamp THREE.Math3Node.MIX ); - + var caustic = new THREE.Math3Node( color, voronoiColors, maskCaustic, THREE.Math3Node.MIX ); - + var causticLights = new THREE.OperatorNode( voronoiIntensity, maskCaustic, THREE.OperatorNode.MUL ); - + mtl.color = caustic; mtl.ambient = causticLights; - + // GUI - + addGui( 'timeScale', timeScale.number, function( val ) { - + timeScale.number = val; }, false, 0, 5 ); - + addGui( 'intensity', intensity.number, function( val ) { - + intensity.number = val; }, false, 0, 3 ); - + addGui( 'scale', scale.number, function( val ) { - + scale.number = val; }, false, 0, 1 ); - + addGui( 'alpha', alpha.number, function( val ) { - + alpha.number = val; }, false, 0, 1 ); - + addGui( 'color', color.value.getHex(), function( val ) { - + color.value.setHex( val ); - + }, true ); - + addGui( 'colorA', colorA.value.getHex(), function( val ) { - + colorA.value.setHex( val ); - + }, true ); - + addGui( 'colorB', colorB.value.getHex(), function( val ) { - + colorB.value.setHex( val ); - + }, true ); - + break; - + case 'soft-body': - + // MATERIAL - + move = true; - + mtl = new THREE.StandardNodeMaterial(); - - var scale = new THREE.FloatNode(2); - var colorA = new THREE.ColorNode(0xFF6633); - var colorB = new THREE.ColorNode(0x3366FF); - + + var scale = new THREE.FloatNode( 2 ); + var colorA = new THREE.ColorNode( 0xFF6633 ); + var colorB = new THREE.ColorNode( 0x3366FF ); + var pos = new THREE.PositionNode(); - var posNorm = new THREE.Math1Node(pos, THREE.Math1Node.NORMALIZE); - - var mask = new THREE.SwitchNode(posNorm, 'y'); - + var posNorm = new THREE.Math1Node( pos, THREE.Math1Node.NORMALIZE ); + + var mask = new THREE.SwitchNode( posNorm, 'y' ); + var velocity = new THREE.VelocityNode( mesh, { - type:'elastic', - spring:.8, - friction:.9 + type: 'elastic', + spring: .8, + friction: .9 } ); - + var velocityArea = new THREE.OperatorNode( mask, scale, THREE.OperatorNode.MUL ); - + var softVelocity = new THREE.OperatorNode( velocity, velocityArea, THREE.OperatorNode.MUL ); - + var softPosition = new THREE.OperatorNode( new THREE.PositionNode(), softVelocity, THREE.OperatorNode.ADD ); - + var colors = new THREE.Math3Node( colorB, colorA, mask, THREE.Math3Node.MIX ); - + mtl.color = colors; mtl.transform = softPosition; - + // GUI - + addGui( 'spring', velocity.params.spring, function( val ) { - + velocity.params.spring = val; }, false, 0, .9 ); - + addGui( 'friction', velocity.params.friction, function( val ) { - + velocity.params.friction = val; }, false, 0, .9 ); - + addGui( 'scale', scale.number, function( val ) { - + scale.number = val; }, false, 0, 3 ); - + addGui( 'softBody', colorA.value.getHex(), function( val ) { - + colorA.value.setHex( val ); - + }, true ); - + addGui( 'hardBody', colorB.value.getHex(), function( val ) { - + colorB.value.setHex( val ); - + }, true ); - + break; - + case 'firefly': - + // MATERIAL - + mtl = new THREE.PhongNodeMaterial(); - + var time = new THREE.TimeNode(); - var speed = new THREE.FloatNode(.5); - - var color = new THREE.ColorNode(0x98ff00); - + var speed = new THREE.FloatNode( .5 ); + + var color = new THREE.ColorNode( 0x98ff00 ); + var timeSpeed = new THREE.OperatorNode( time, speed, THREE.OperatorNode.MUL ); - + var sinCycleInSecs = new THREE.OperatorNode( - timeSpeed, + timeSpeed, new THREE.ConstNode( THREE.ConstNode.PI2 ), THREE.OperatorNode.MUL ); - - var cycle = new THREE.Math1Node(sinCycleInSecs, THREE.Math1Node.SIN); - + + var cycle = new THREE.Math1Node( sinCycleInSecs, THREE.Math1Node.SIN ); + var cycleColor = new THREE.OperatorNode( cycle, color, THREE.OperatorNode.MUL ); - - var cos = new THREE.Math1Node(cycleColor, THREE.Math1Node.SIN); - - mtl.color = new THREE.ColorNode(0); + + var cos = new THREE.Math1Node( cycleColor, THREE.Math1Node.SIN ); + + mtl.color = new THREE.ColorNode( 0 ); mtl.emissive = cos; - + // GUI - + addGui( 'speed', speed.number, function( val ) { - + speed.number = val; }, false, 0, 3 ); - + break; } - + // build shader mtl.build(); - + // set material mesh.material = mtl; - + } - + function onWindowResize() { camera.aspect = window.innerWidth / window.innerHeight; @@ -1282,28 +1282,28 @@ function animate() { var delta = clock.getDelta(); - - if (move) { - + + if ( move ) { + var time = Date.now() * 0.005; - + mesh.position.z = Math.cos( time ) * 10; mesh.position.y = Math.sin( time ) * 10; - + } else { - + mesh.position.z = mesh.position.y = 0; - + } - + //mesh.rotation.z += .01; - + // update material animation and/or gpu calcs (pre-renderer) mesh.material.updateAnimation( delta ); - + renderer.render( scene, camera ); - + requestAnimationFrame( animate ); }