浏览代码

mrdoob code style

sunag 7 年之前
父节点
当前提交
75985a1fcc
共有 82 个文件被更改,包括 3424 次插入3425 次删除
  1. 24 24
      examples/js/nodes/THREE.Nodes.js
  2. 22 22
      examples/js/nodes/accessors/CameraNode.js
  3. 7 8
      examples/js/nodes/accessors/ColorsNode.js
  4. 4 4
      examples/js/nodes/accessors/LightNode.js
  5. 6 6
      examples/js/nodes/accessors/NormalNode.js
  6. 8 8
      examples/js/nodes/accessors/PositionNode.js
  7. 5 5
      examples/js/nodes/accessors/ReflectNode.js
  8. 10 10
      examples/js/nodes/accessors/ResolutionNode.js
  9. 5 5
      examples/js/nodes/accessors/ScreenUVNode.js
  10. 6 6
      examples/js/nodes/accessors/UVNode.js
  11. 4 4
      examples/js/nodes/bsdfs/BlinnExponentToRoughnessNode.js
  12. 1 1
      examples/js/nodes/bsdfs/BlinnShininessExponentNode.js
  13. 10 10
      examples/js/nodes/bsdfs/RoughnessToBlinnExponentNode.js
  14. 5 5
      examples/js/nodes/core/AttributeNode.js
  15. 9 9
      examples/js/nodes/core/ConstNode.js
  16. 3 3
      examples/js/nodes/core/ExpressionNode.js
  17. 5 5
      examples/js/nodes/core/FunctionCallNode.js
  18. 10 10
      examples/js/nodes/core/FunctionNode.js
  19. 5 5
      examples/js/nodes/core/InputNode.js
  20. 34 34
      examples/js/nodes/core/Node.js
  21. 196 196
      examples/js/nodes/core/NodeBuilder.js
  22. 14 14
      examples/js/nodes/core/NodeFrame.js
  23. 6 6
      examples/js/nodes/core/NodeUniform.js
  24. 9 9
      examples/js/nodes/core/NodeUtils.js
  25. 20 21
      examples/js/nodes/core/StructNode.js
  26. 6 6
      examples/js/nodes/core/TempNode.js
  27. 6 6
      examples/js/nodes/core/VarNode.js
  28. 12 12
      examples/js/nodes/effects/BlurNode.js
  29. 24 24
      examples/js/nodes/effects/ColorAdjustmentNode.js
  30. 10 10
      examples/js/nodes/effects/LuminanceNode.js
  31. 4 4
      examples/js/nodes/inputs/ColorNode.js
  32. 9 9
      examples/js/nodes/inputs/CubeTextureNode.js
  33. 4 4
      examples/js/nodes/inputs/FloatNode.js
  34. 4 4
      examples/js/nodes/inputs/IntNode.js
  35. 8 8
      examples/js/nodes/inputs/Matrix3Node.js
  36. 8 8
      examples/js/nodes/inputs/Matrix4Node.js
  37. 9 9
      examples/js/nodes/inputs/PropertyNode.js
  38. 52 52
      examples/js/nodes/inputs/RTTNode.js
  39. 4 4
      examples/js/nodes/inputs/ReflectorNode.js
  40. 1 1
      examples/js/nodes/inputs/ScreenNode.js
  41. 8 9
      examples/js/nodes/inputs/TextureNode.js
  42. 3 3
      examples/js/nodes/inputs/Vector2Node.js
  43. 4 4
      examples/js/nodes/inputs/Vector3Node.js
  44. 3 3
      examples/js/nodes/inputs/Vector4Node.js
  45. 1 1
      examples/js/nodes/materials/MeshStandardNodeMaterial.js
  46. 26 26
      examples/js/nodes/materials/NodeMaterial.js
  47. 14 14
      examples/js/nodes/materials/PhongNodeMaterial.js
  48. 6 6
      examples/js/nodes/materials/SpriteNodeMaterial.js
  49. 17 17
      examples/js/nodes/materials/StandardNodeMaterial.js
  50. 22 22
      examples/js/nodes/materials/nodes/MeshStandardNode.js
  51. 15 15
      examples/js/nodes/materials/nodes/PhongNode.js
  52. 4 4
      examples/js/nodes/materials/nodes/RawNode.js
  53. 21 21
      examples/js/nodes/materials/nodes/SpriteNode.js
  54. 12 12
      examples/js/nodes/materials/nodes/StandardNode.js
  55. 11 11
      examples/js/nodes/math/CondNode.js
  56. 11 11
      examples/js/nodes/math/Math1Node.js
  57. 18 18
      examples/js/nodes/math/Math2Node.js
  58. 15 15
      examples/js/nodes/math/Math3Node.js
  59. 6 6
      examples/js/nodes/math/OperatorNode.js
  60. 31 31
      examples/js/nodes/misc/BumpMapNode.js
  61. 14 14
      examples/js/nodes/misc/NormalMapNode.js
  62. 4 4
      examples/js/nodes/misc/TextureCubeNode.js
  63. 26 26
      examples/js/nodes/misc/TextureCubeUVNode.js
  64. 3 3
      examples/js/nodes/postprocessing/NodePass.js
  65. 21 21
      examples/js/nodes/postprocessing/NodePostProcessing.js
  66. 12 12
      examples/js/nodes/procedural/CheckerNode.js
  67. 11 11
      examples/js/nodes/procedural/NoiseNode.js
  68. 19 19
      examples/js/nodes/utils/BypassNode.js
  69. 75 75
      examples/js/nodes/utils/ColorSpaceNode.js
  70. 7 7
      examples/js/nodes/utils/JoinNode.js
  71. 6 6
      examples/js/nodes/utils/MaxMIPLevelNode.js
  72. 5 5
      examples/js/nodes/utils/SwitchNode.js
  73. 9 9
      examples/js/nodes/utils/TimerNode.js
  74. 6 6
      examples/js/nodes/utils/UVTransformNode.js
  75. 7 7
      examples/js/nodes/utils/VelocityNode.js
  76. 106 106
      examples/webgl_loader_nodes.html
  77. 1787 1787
      examples/webgl_materials_nodes.html
  78. 206 207
      examples/webgl_mirror_nodes.html
  79. 53 53
      examples/webgl_performance_nodes.html
  80. 22 20
      examples/webgl_postprocessing_nodes.html
  81. 9 8
      examples/webgl_postprocessing_nodes_pass.html
  82. 179 179
      examples/webgl_sprites_nodes.html

+ 24 - 24
examples/js/nodes/THREE.Nodes.js

@@ -1,7 +1,7 @@
-import { 
+import {
 
 	// core
-	
+
 	Node,
 	TempNode,
 	InputNode,
@@ -17,9 +17,9 @@ import {
 	NodeFrame,
 	NodeUniform,
 	NodeBuilder,
-	
+
 	// inputs
-	
+
 	IntNode,
 	FloatNode,
 	Vector2Node,
@@ -34,9 +34,9 @@ import {
 	ReflectorNode,
 	PropertyNode,
 	RTTNode,
-	
+
 	// accessors
-	
+
 	UVNode,
 	ColorsNode,
 	PositionNode,
@@ -46,35 +46,35 @@ import {
 	ReflectNode,
 	ScreenUVNode,
 	ResolutionNode,
-	
+
 	// math
-	
+
 	Math1Node,
 	Math2Node,
 	Math3Node,
 	OperatorNode,
 	CondNode,
-	
+
 	// procedural
-	
+
 	NoiseNode,
 	CheckerNode,
-	
+
 	// bsdfs
-	
+
 	BlinnShininessExponentNode,
 	BlinnExponentToRoughnessNode,
 	RoughnessToBlinnExponentNode,
-	
+
 	// misc
-	
+
 	TextureCubeUVNode,
 	TextureCubeNode,
 	NormalMapNode,
 	BumpMapNode,
-	
+
 	// utils
-	
+
 	BypassNode,
 	JoinNode,
 	SwitchNode,
@@ -83,33 +83,33 @@ import {
 	UVTransformNode,
 	MaxMIPLevelNode,
 	ColorSpaceNode,
-	
+
 	// effects
-	
+
 	BlurNode,
 	ColorAdjustmentNode,
 	LuminanceNode,
 
 	// material nodes
-	
+
 	RawNode,
 	SpriteNode,
 	PhongNode,
 	StandardNode,
 	MeshStandardNode,
-	
+
 	// materials
-	
+
 	NodeMaterial,
 	SpriteNodeMaterial,
 	PhongNodeMaterial,
 	StandardNodeMaterial,
 	MeshStandardNodeMaterial,
-	
+
 	// post-processing
-	
+
 	NodePostProcessing
-	
+
 } from './Nodes.js';
 
 // core

+ 22 - 22
examples/js/nodes/accessors/CameraNode.js

@@ -6,7 +6,7 @@ import { TempNode } from '../core/TempNode.js';
 import { FunctionNode } from '../core/FunctionNode.js';
 import { FloatNode } from '../inputs/FloatNode.js';
 import { PositionNode } from '../accessors/PositionNode.js';
- 
+
 function CameraNode( scope, camera ) {
 
 	TempNode.call( this, 'v3' );
@@ -14,33 +14,33 @@ function CameraNode( scope, camera ) {
 	this.setScope( scope || CameraNode.POSITION );
 	this.setCamera( camera );
 
-};
+}
+
+CameraNode.Nodes = ( function () {
 
-CameraNode.Nodes = (function() {
-	
 	var depthColor = new FunctionNode( [
 		"float depthColor( float mNear, float mFar ) {",
-		
+
 		"	#ifdef USE_LOGDEPTHBUF_EXT",
-		
+
 		"		float depth = gl_FragDepthEXT / gl_FragCoord.w;",
-		
+
 		"	#else",
-		
+
 		"		float depth = gl_FragCoord.z / gl_FragCoord.w;",
-		
+
 		"	#endif",
-		
+
 		"	return 1.0 - smoothstep( mNear, mFar, depth );",
-		
+
 		"}"
 	].join( "\n" ) );
-	
+
 	return {
 		depthColor: depthColor
 	};
-	
-})();
+
+} )();
 
 CameraNode.POSITION = 'position';
 CameraNode.DEPTH = 'depth';
@@ -92,7 +92,7 @@ CameraNode.prototype.getType = function ( builder ) {
 	switch ( this.scope ) {
 
 		case CameraNode.DEPTH:
-		
+
 			return 'f';
 
 	}
@@ -107,7 +107,7 @@ CameraNode.prototype.isUnique = function ( builder ) {
 
 		case CameraNode.DEPTH:
 		case CameraNode.TO_VERTEX:
-		
+
 			return true;
 
 	}
@@ -121,7 +121,7 @@ CameraNode.prototype.isShared = function ( builder ) {
 	switch ( this.scope ) {
 
 		case CameraNode.POSITION:
-		
+
 			return false;
 
 	}
@@ -180,15 +180,15 @@ CameraNode.prototype.onUpdateFrame = function ( frame ) {
 };
 
 CameraNode.prototype.copy = function ( source ) {
-			
+
 	TempNode.prototype.copy.call( this, source );
-	
+
 	this.setScope( source.scope );
 
 	if ( source.camera ) {
-		
+
 		this.setCamera( source.camera );
-		
+
 	}
 
 	switch ( source.scope ) {
@@ -201,7 +201,7 @@ CameraNode.prototype.copy = function ( source ) {
 			break;
 
 	}
-	
+
 };
 
 CameraNode.prototype.toJSON = function ( meta ) {

+ 7 - 8
examples/js/nodes/accessors/ColorsNode.js

@@ -1,20 +1,19 @@
 /**
  * @author sunag / http://www.sunag.com.br/
  */
- 
+
 import { TempNode } from '../core/TempNode.js';
-import { NodeLib } from '../core/NodeLib.js';
- 
+
 var vertexDict = [ 'color', 'color2' ],
 	fragmentDict = [ 'vColor', 'vColor2' ];
- 
+
 function ColorsNode( index ) {
 
 	TempNode.call( this, 'v4', { shared: false } );
 
 	this.index = index || 0;
 
-};
+}
 
 ColorsNode.prototype = Object.create( TempNode.prototype );
 ColorsNode.prototype.constructor = ColorsNode;
@@ -30,11 +29,11 @@ ColorsNode.prototype.generate = function ( builder, output ) {
 };
 
 ColorsNode.prototype.copy = function ( source ) {
-			
+
 	TempNode.prototype.copy.call( this, source );
-	
+
 	this.index = source.index;
-	
+
 };
 
 ColorsNode.prototype.toJSON = function ( meta ) {

+ 4 - 4
examples/js/nodes/accessors/LightNode.js

@@ -10,7 +10,7 @@ function LightNode( scope ) {
 
 	this.scope = scope || LightNode.TOTAL;
 
-};
+}
 
 LightNode.TOTAL = 'total';
 
@@ -35,11 +35,11 @@ LightNode.prototype.generate = function ( builder, output ) {
 };
 
 LightNode.prototype.copy = function ( source ) {
-			
+
 	TempNode.prototype.copy.call( this, source );
-	
+
 	this.scope = source.scope;
-	
+
 };
 
 LightNode.prototype.toJSON = function ( meta ) {

+ 6 - 6
examples/js/nodes/accessors/NormalNode.js

@@ -4,14 +4,14 @@
 
 import { TempNode } from '../core/TempNode.js';
 import { NodeLib } from '../core/NodeLib.js';
- 
+
 function NormalNode( scope ) {
 
 	TempNode.call( this, 'v3' );
 
 	this.scope = scope || NormalNode.LOCAL;
 
-};
+}
 
 NormalNode.LOCAL = 'local';
 NormalNode.WORLD = 'world';
@@ -54,7 +54,7 @@ NormalNode.prototype.generate = function ( builder, output ) {
 			builder.requires.worldNormal = true;
 
 			result = builder.isShader( 'vertex' ) ? '( modelMatrix * vec4( objectNormal, 0.0 ) ).xyz' : 'vWNormal';
-			
+
 			break;
 
 		case NormalNode.VIEW:
@@ -70,11 +70,11 @@ NormalNode.prototype.generate = function ( builder, output ) {
 };
 
 NormalNode.prototype.copy = function ( source ) {
-	
+
 	TempNode.prototype.copy.call( this, source );
-	
+
 	this.scope = source.scope;
-	
+
 };
 
 NormalNode.prototype.toJSON = function ( meta ) {

+ 8 - 8
examples/js/nodes/accessors/PositionNode.js

@@ -4,14 +4,14 @@
 
 import { TempNode } from '../core/TempNode.js';
 import { NodeLib } from '../core/NodeLib.js';
- 
+
 function PositionNode( scope ) {
 
 	TempNode.call( this, 'v3' );
 
 	this.scope = scope || PositionNode.LOCAL;
 
-};
+}
 
 PositionNode.LOCAL = 'local';
 PositionNode.WORLD = 'world';
@@ -22,12 +22,12 @@ PositionNode.prototype = Object.create( TempNode.prototype );
 PositionNode.prototype.constructor = PositionNode;
 PositionNode.prototype.nodeType = "Position";
 
-PositionNode.prototype.getType = function ( builder ) {
+PositionNode.prototype.getType = function ( ) {
 
 	switch ( this.scope ) {
 
 		case PositionNode.PROJECTION:
-		
+
 			return 'v4';
 
 	}
@@ -42,7 +42,7 @@ PositionNode.prototype.isShared = function ( builder ) {
 
 		case PositionNode.LOCAL:
 		case PositionNode.WORLD:
-		
+
 			return false;
 
 	}
@@ -92,11 +92,11 @@ PositionNode.prototype.generate = function ( builder, output ) {
 };
 
 PositionNode.prototype.copy = function ( source ) {
-			
+
 	TempNode.prototype.copy.call( this, source );
-	
+
 	this.scope = source.scope;
-	
+
 };
 
 PositionNode.prototype.toJSON = function ( meta ) {

+ 5 - 5
examples/js/nodes/accessors/ReflectNode.js

@@ -10,7 +10,7 @@ function ReflectNode( scope ) {
 
 	this.scope = scope || ReflectNode.CUBE;
 
-};
+}
 
 ReflectNode.CUBE = 'cube';
 ReflectNode.SPHERE = 'sphere';
@@ -37,7 +37,7 @@ ReflectNode.prototype.getType = function ( builder ) {
 ReflectNode.prototype.generate = function ( builder, output ) {
 
 	if ( builder.isShader( 'fragment' ) ) {
-		
+
 		var result;
 
 		switch ( this.scope ) {
@@ -73,13 +73,13 @@ ReflectNode.prototype.generate = function ( builder, output ) {
 		}
 
 		return builder.format( result, this.getType( builder ), output );
-	
+
 	} else {
-		
+
 		console.warn( "THREE.ReflectNode is not compatible with " + builder.shader + " shader." );
 
 		return builder.format( 'vec3( 0.0 )', this.type, output );
-		
+
 	}
 
 };

+ 10 - 10
examples/js/nodes/accessors/ResolutionNode.js

@@ -3,12 +3,12 @@
  */
 
 import { Vector2Node } from '../inputs/Vector2Node.js';
- 
+
 function ResolutionNode() {
 
 	Vector2Node.call( this );
 
-};
+}
 
 ResolutionNode.prototype = Object.create( Vector2Node.prototype );
 ResolutionNode.prototype.constructor = ResolutionNode;
@@ -17,27 +17,27 @@ ResolutionNode.prototype.nodeType = "Resolution";
 ResolutionNode.prototype.updateFrame = function ( frame ) {
 
 	if ( frame.renderer ) {
-		
+
 		var size = frame.renderer.getSize(),
 			pixelRatio = frame.renderer.getPixelRatio();
 
 		this.x = size.width * pixelRatio;
 		this.y = size.height * pixelRatio;
-		
+
 	} else {
-		
-		console.warn("ResolutionNode need a renderer in NodeFrame");
-		
+
+		console.warn( "ResolutionNode need a renderer in NodeFrame" );
+
 	}
 
 };
 
 ResolutionNode.prototype.copy = function ( source ) {
-			
+
 	Vector2Node.prototype.copy.call( this, source );
-	
+
 	this.renderer = source.renderer;
-	
+
 };
 
 ResolutionNode.prototype.toJSON = function ( meta ) {

+ 5 - 5
examples/js/nodes/accessors/ScreenUVNode.js

@@ -4,14 +4,14 @@
 
 import { TempNode } from '../core/TempNode.js';
 import { ResolutionNode } from './ResolutionNode.js';
- 
+
 function ScreenUVNode( resolution ) {
 
 	TempNode.call( this, 'v2' );
 
 	this.resolution = resolution || new ResolutionNode();
 
-};
+}
 
 ScreenUVNode.prototype = Object.create( TempNode.prototype );
 ScreenUVNode.prototype.constructor = ScreenUVNode;
@@ -38,11 +38,11 @@ ScreenUVNode.prototype.generate = function ( builder, output ) {
 };
 
 ScreenUVNode.prototype.copy = function ( source ) {
-			
+
 	TempNode.prototype.copy.call( this, source );
-	
+
 	this.resolution = source.resolution;
-	
+
 };
 
 ScreenUVNode.prototype.toJSON = function ( meta ) {

+ 6 - 6
examples/js/nodes/accessors/UVNode.js

@@ -4,17 +4,17 @@
 
 import { TempNode } from '../core/TempNode.js';
 import { NodeLib } from '../core/NodeLib.js';
- 
+
 var vertexDict = [ 'uv', 'uv2' ],
 	fragmentDict = [ 'vUv', 'vUv2' ];
- 
+
 function UVNode( index ) {
 
 	TempNode.call( this, 'v2', { shared: false } );
 
 	this.index = index || 0;
 
-};
+}
 
 UVNode.prototype = Object.create( TempNode.prototype );
 UVNode.prototype.constructor = UVNode;
@@ -31,11 +31,11 @@ UVNode.prototype.generate = function ( builder, output ) {
 };
 
 UVNode.prototype.copy = function ( source ) {
-		
+
 	TempNode.prototype.copy.call( this, source );
-	
+
 	this.index = source.index;
-	
+
 };
 
 UVNode.prototype.toJSON = function ( meta ) {

+ 4 - 4
examples/js/nodes/bsdfs/BlinnExponentToRoughnessNode.js

@@ -11,7 +11,7 @@ function BlinnExponentToRoughnessNode( blinnExponent ) {
 
 	this.blinnExponent = blinnExponent || new BlinnShininessExponentNode();
 
-};
+}
 
 BlinnExponentToRoughnessNode.prototype = Object.create( TempNode.prototype );
 BlinnExponentToRoughnessNode.prototype.constructor = BlinnExponentToRoughnessNode;
@@ -24,11 +24,11 @@ BlinnExponentToRoughnessNode.prototype.generate = function ( builder, output ) {
 };
 
 BlinnExponentToRoughnessNode.prototype.copy = function ( source ) {
-			
+
 	TempNode.prototype.copy.call( this, source );
-	
+
 	this.blinnExponent = source.blinnExponent;
-	
+
 };
 
 BlinnExponentToRoughnessNode.prototype.toJSON = function ( meta ) {

+ 1 - 1
examples/js/nodes/bsdfs/BlinnShininessExponentNode.js

@@ -8,7 +8,7 @@ function BlinnShininessExponentNode() {
 
 	TempNode.call( this, 'f' );
 
-};
+}
 
 BlinnShininessExponentNode.prototype = Object.create( TempNode.prototype );
 BlinnShininessExponentNode.prototype.constructor = BlinnShininessExponentNode;

+ 10 - 10
examples/js/nodes/bsdfs/RoughnessToBlinnExponentNode.js

@@ -6,7 +6,7 @@ import { TempNode } from '../core/TempNode.js';
 import { FunctionNode } from '../core/FunctionNode.js';
 import { MaxMIPLevelNode } from '../utils/MaxMIPLevelNode.js';
 import { BlinnShininessExponentNode } from './BlinnShininessExponentNode.js';
- 
+
 function RoughnessToBlinnExponentNode( texture ) {
 
 	TempNode.call( this, 'f' );
@@ -16,9 +16,9 @@ function RoughnessToBlinnExponentNode( texture ) {
 	this.maxMIPLevel = new MaxMIPLevelNode( texture );
 	this.blinnShininessExponent = new BlinnShininessExponentNode();
 
-};
+}
 
-RoughnessToBlinnExponentNode.Nodes = (function() {
+RoughnessToBlinnExponentNode.Nodes = ( function () {
 
 	var getSpecularMIPLevel = new FunctionNode( [
 		// taken from here: http://casual-effects.blogspot.ca/2011/08/plausible-environment-lighting-in-two.html
@@ -34,12 +34,12 @@ RoughnessToBlinnExponentNode.Nodes = (function() {
 
 		"}"
 	].join( "\n" ) );
-	
+
 	return {
 		getSpecularMIPLevel: getSpecularMIPLevel
 	};
-	
-})();
+
+} )();
 
 RoughnessToBlinnExponentNode.prototype = Object.create( TempNode.prototype );
 RoughnessToBlinnExponentNode.prototype.constructor = RoughnessToBlinnExponentNode;
@@ -50,7 +50,7 @@ RoughnessToBlinnExponentNode.prototype.generate = function ( builder, output ) {
 	if ( builder.isShader( 'fragment' ) ) {
 
 		this.maxMIPLevel.texture = this.texture;
-	
+
 		var getSpecularMIPLevel = builder.include( RoughnessToBlinnExponentNode.Nodes.getSpecularMIPLevel );
 
 		return builder.format( getSpecularMIPLevel + '( ' + this.blinnShininessExponent.build( builder, 'f' ) + ', ' + this.maxMIPLevel.build( builder, 'f' ) + ' )', this.type, output );
@@ -66,11 +66,11 @@ RoughnessToBlinnExponentNode.prototype.generate = function ( builder, output ) {
 };
 
 RoughnessToBlinnExponentNode.prototype.copy = function ( source ) {
-			
+
 	TempNode.prototype.copy.call( this, source );
-	
+
 	this.texture = source.texture;
-	
+
 };
 
 RoughnessToBlinnExponentNode.prototype.toJSON = function ( meta ) {

+ 5 - 5
examples/js/nodes/core/AttributeNode.js

@@ -10,7 +10,7 @@ function AttributeNode( name, type ) {
 
 	this.name = name;
 
-};
+}
 
 AttributeNode.prototype = Object.create( Node.prototype );
 AttributeNode.prototype.constructor = AttributeNode;
@@ -38,17 +38,17 @@ AttributeNode.prototype.generate = function ( builder, output ) {
 		name = builder.isShader( 'vertex' ) ? this.name : attribute.varying.name;
 
 	console.log( attribute );
-		
+
 	return builder.format( name, this.getType( builder ), output );
 
 };
 
 AttributeNode.prototype.copy = function ( source ) {
-			
+
 	Node.prototype.copy.call( this, source );
-	
+
 	this.type = source.type;
-	
+
 };
 
 AttributeNode.prototype.toJSON = function ( meta ) {

+ 9 - 9
examples/js/nodes/core/ConstNode.js

@@ -12,7 +12,7 @@ function ConstNode( src, useDefine ) {
 
 	this.eval( src || ConstNode.PI, useDefine );
 
-};
+}
 
 ConstNode.PI = 'PI';
 ConstNode.PI2 = 'PI2';
@@ -39,7 +39,7 @@ ConstNode.prototype.eval = function ( src, useDefine ) {
 
 	var match = this.src.match( declarationRegexp );
 
-	this.useDefine = useDefine || this.src.charAt(0) === '#';
+	this.useDefine = useDefine || this.src.charAt( 0 ) === '#';
 
 	if ( match && match.length > 1 ) {
 
@@ -74,10 +74,10 @@ ConstNode.prototype.build = function ( builder, output ) {
 
 			return 'const ' + this.type + ' ' + this.name + ' = ' + this.value + ';';
 
-		} else if (this.useDefine) {
-		
+		} else if ( this.useDefine ) {
+
 			return this.src;
-			
+
 		}
 
 	} else {
@@ -97,11 +97,11 @@ ConstNode.prototype.generate = function ( builder, output ) {
 };
 
 ConstNode.prototype.copy = function ( source ) {
-	
+
 	TempNode.prototype.copy.call( this, source );
-	
-	this.eval( source.src, source.useDefine );	
-	
+
+	this.eval( source.src, source.useDefine );
+
 };
 
 ConstNode.prototype.toJSON = function ( meta ) {

+ 3 - 3
examples/js/nodes/core/ExpressionNode.js

@@ -6,9 +6,9 @@ import { FunctionNode } from './FunctionNode.js';
 
 function ExpressionNode( src, type, keywords, extensions, includes ) {
 
-	FunctionNode.call( this, src, includes, extensions, keywords, type  );
-	
-};
+	FunctionNode.call( this, src, includes, extensions, keywords, type );
+
+}
 
 ExpressionNode.prototype = Object.create( FunctionNode.prototype );
 ExpressionNode.prototype.constructor = ExpressionNode;

+ 5 - 5
examples/js/nodes/core/FunctionCallNode.js

@@ -3,14 +3,14 @@
  */
 
 import { TempNode } from './TempNode.js';
- 
+
 function FunctionCallNode( func, inputs ) {
 
 	TempNode.call( this );
 
 	this.setFunction( func, inputs );
 
-};
+}
 
 FunctionCallNode.prototype = Object.create( TempNode.prototype );
 FunctionCallNode.prototype.constructor = FunctionCallNode;
@@ -59,9 +59,9 @@ FunctionCallNode.prototype.generate = function ( builder, output ) {
 };
 
 FunctionCallNode.prototype.copy = function ( source ) {
-			
+
 	TempNode.prototype.copy.call( this, source );
-	
+
 	for ( var prop in source.inputs ) {
 
 		this.inputs[ prop ] = source.inputs[ prop ];
@@ -69,7 +69,7 @@ FunctionCallNode.prototype.copy = function ( source ) {
 	}
 
 	this.value = source.value;
-	
+
 };
 
 FunctionCallNode.prototype.toJSON = function ( meta ) {

+ 10 - 10
examples/js/nodes/core/FunctionNode.js

@@ -17,7 +17,7 @@ function FunctionNode( src, includes, extensions, keywords, type ) {
 
 	this.eval( src, includes, extensions, keywords );
 
-};
+}
 
 FunctionNode.prototype = Object.create( TempNode.prototype );
 FunctionNode.prototype.constructor = FunctionNode;
@@ -44,9 +44,9 @@ FunctionNode.prototype.getInputByName = function ( name ) {
 	while ( i -- ) {
 
 		if ( this.inputs[ i ].name === name ) {
-			
+
 			return this.inputs[ i ];
-			
+
 		}
 
 	}
@@ -60,9 +60,9 @@ FunctionNode.prototype.getIncludeByName = function ( name ) {
 	while ( i -- ) {
 
 		if ( this.includes[ i ].name === name ) {
-			
+
 			return this.includes[ i ];
-			
+
 		}
 
 	}
@@ -87,7 +87,7 @@ FunctionNode.prototype.generate = function ( builder, output ) {
 
 	while ( match = propertiesRegexp.exec( this.src ) ) {
 
-		var prop = match[ 0 ], 
+		var prop = match[ 0 ],
 			isGlobal = this.isMethod ? ! this.getInputByName( prop ) : true,
 			reference = prop;
 
@@ -210,16 +210,16 @@ FunctionNode.prototype.eval = function ( src, includes, extensions, keywords ) {
 };
 
 FunctionNode.prototype.copy = function ( source ) {
-			
+
 	TempNode.prototype.copy.call( this, source );
-	
+
 	this.isMethod = source.isMethod;
 	this.useKeywords = source.useKeywords;
-	
+
 	this.eval( source.src, source.includes, source.extensions, source.keywords );
 
 	if ( source.type !== undefined ) this.type = source.type;
-	
+
 };
 
 FunctionNode.prototype.toJSON = function ( meta ) {

+ 5 - 5
examples/js/nodes/core/InputNode.js

@@ -13,7 +13,7 @@ function InputNode( type, params ) {
 
 	this.readonly = false;
 
-};
+}
 
 InputNode.prototype = Object.create( TempNode.prototype );
 InputNode.prototype.constructor = InputNode;
@@ -25,17 +25,17 @@ InputNode.prototype.isReadonly = function ( builder ) {
 };
 
 InputNode.prototype.copy = function ( source ) {
-	
+
 	TempNode.prototype.copy.call( this, source );
-	
+
 	if ( source.readonly !== undefined ) this.readonly = source.readonly;
-	
+
 };
 
 InputNode.prototype.createJSONNode = function ( meta ) {
 
 	var data = TempNode.prototype.createJSONNode.call( this, meta );
-	
+
 	if ( this.readonly === true ) data.readonly = this.readonly;
 
 	return data;

+ 34 - 34
examples/js/nodes/core/Node.js

@@ -12,14 +12,14 @@ function Node( type ) {
 
 	this.userData = {};
 
-};
+}
 
 Node.prototype = {
 
 	constructor: Node,
-	
+
 	isNode: true,
-	
+
 	parse: function ( builder, settings ) {
 
 		settings = settings || {};
@@ -28,7 +28,7 @@ Node.prototype = {
 
 		this.build( builder.addFlow( settings.slot, settings.cache, settings.context ), 'v4' );
 
-		builder.clearVertexNodeCode()
+		builder.clearVertexNodeCode();
 		builder.clearFragmentNodeCode();
 
 		builder.removeFlow();
@@ -36,7 +36,7 @@ Node.prototype = {
 		builder.parsing = false;
 
 	},
-	
+
 	parseAndBuildCode: function ( builder, output, settings ) {
 
 		settings = settings || {};
@@ -44,9 +44,9 @@ Node.prototype = {
 		this.parse( builder, settings );
 
 		return this.buildCode( builder, output, settings );
-	
+
 	},
-	
+
 	buildCode: function ( builder, output, settings ) {
 
 		settings = settings || {};
@@ -58,7 +58,7 @@ Node.prototype = {
 		builder.removeFlow();
 
 		return data;
-	
+
 	},
 
 	build: function ( builder, output, uuid ) {
@@ -68,9 +68,9 @@ Node.prototype = {
 		var data = builder.getNodeData( uuid || this );
 
 		if ( builder.parsing ) {
-			
+
 			this.appendDepsNode( builder, data, output );
-			
+
 		}
 
 		if ( builder.nodes.indexOf( this ) === - 1 ) {
@@ -86,9 +86,9 @@ Node.prototype = {
 		}
 
 		return this.generate( builder, output, uuid );
-	
+
 	},
-	
+
 	appendDepsNode: function ( builder, data, output ) {
 
 		data.deps = ( data.deps || 0 ) + 1;
@@ -101,29 +101,29 @@ Node.prototype = {
 			data.output = output;
 
 		}
-	
+
 	},
-	
-	setName: function( name ) {
-		
+
+	setName: function ( name ) {
+
 		this.name = name;
-		
+
 		return this;
-		
+
 	},
-	
-	getName: function( builder ) {
-		
+
+	getName: function ( builder ) {
+
 		return this.name;
-		
+
 	},
-	
+
 	getType: function ( builder, output ) {
 
 		return output === 'sampler2D' || output === 'samplerCube' ? output : this.type;
-	
+
 	},
-	
+
 	getJSONNode: function ( meta ) {
 
 		var isRootObject = ( meta === undefined || typeof meta === 'string' );
@@ -133,17 +133,17 @@ Node.prototype = {
 			return meta.nodes[ this.uuid ];
 
 		}
-	
+
 	},
-	
+
 	copy: function ( source ) {
 
 		if ( source.name !== undefined ) this.name = source.name;
-	
+
 		if ( source.userData !== undefined ) this.userData = JSON.parse( JSON.stringify( source.userData ) );
-	
+
 	},
-	
+
 	createJSONNode: function ( meta ) {
 
 		var isRootObject = ( meta === undefined || typeof meta === 'string' );
@@ -166,15 +166,15 @@ Node.prototype = {
 		}
 
 		return data;
-	
+
 	},
-	
+
 	toJSON: function ( meta ) {
 
 		return this.getJSONNode( meta ) || this.createJSONNode( meta );
-	
+
 	}
-	
+
 };
 
 export { Node };

+ 196 - 196
examples/js/nodes/core/NodeBuilder.js

@@ -37,17 +37,17 @@ var elements = NodeUtils.elements,
 		m3: 'mat3',
 		m4: 'mat4'
 	};
- 
+
 function NodeBuilder() {
-	
+
 	this.slots = [];
 	this.caches = [];
 	this.contexts = [];
 
 	this.keywords = {};
-	
+
 	this.nodeData = {};
-	
+
 	this.requires = {
 		uv: [],
 		color: [],
@@ -60,9 +60,9 @@ function NodeBuilder() {
 		functions: [],
 		structs: []
 	};
-	
+
 	this.attributes = {};
-	
+
 	this.prefixCode = [
 		"#ifdef TEXTURE_LOD_EXT",
 
@@ -86,32 +86,32 @@ function NodeBuilder() {
 		"#include <common>"
 
 	].join( "\n" );
-	
+
 	this.parsCode = {
 		vertex: '',
 		fragment: ''
 	};
-	
+
 	this.code = {
 		vertex: '',
 		fragment: ''
 	};
-	
+
 	this.nodeCode = {
 		vertex: '',
 		fragment: ''
 	};
-	
+
 	this.resultCode = {
 		vertex: '',
 		fragment: ''
 	};
-	
+
 	this.finalCode = {
 		vertex: '',
 		fragment: ''
 	};
-	
+
 	this.inputs = {
 		uniforms: {
 			list: [],
@@ -124,43 +124,43 @@ function NodeBuilder() {
 			fragment: []
 		}
 	};
-	
+
 	// send to material
-	
+
 	this.defines = {};
-	
+
 	this.uniforms = {};
-	
+
 	this.extensions = {};
-	
+
 	this.updaters = [];
-	
+
 	this.nodes = [];
-	
+
 	// --
-	
+
 	this.parsing = false;
 	this.optimize = true;
 
-};
+}
 
 NodeBuilder.prototype = {
 
 	constructor: NodeBuilder,
 
-	build: function( vertex, fragment ) {
-		
+	build: function ( vertex, fragment ) {
+
 		this.buildShader( 'vertex', vertex );
 		this.buildShader( 'fragment', fragment );
-		
+
 		if ( this.requires.uv[ 0 ] ) {
 
 			this.addVaryCode( 'varying vec2 vUv;' );
-		
+
 			this.addVertexFinalCode( 'vUv = uv;' );
 
 		}
-		
+
 		if ( this.requires.uv[ 1 ] ) {
 
 			this.addVaryCode( 'varying vec2 vUv2;' );
@@ -169,7 +169,7 @@ NodeBuilder.prototype = {
 			this.addVertexFinalCode( 'vUv2 = uv2;' );
 
 		}
-		
+
 		if ( this.requires.color[ 0 ] ) {
 
 			this.addVaryCode( 'varying vec4 vColor;' );
@@ -178,7 +178,7 @@ NodeBuilder.prototype = {
 			this.addVertexFinalCode( 'vColor = color;' );
 
 		}
-		
+
 		if ( this.requires.color[ 1 ] ) {
 
 			this.addVaryCode( 'varying vec4 vColor2;' );
@@ -187,7 +187,7 @@ NodeBuilder.prototype = {
 			this.addVertexFinalCode( 'vColor2 = color2;' );
 
 		}
-		
+
 		if ( this.requires.position ) {
 
 			this.addVaryCode( 'varying vec3 vPosition;' );
@@ -195,15 +195,15 @@ NodeBuilder.prototype = {
 			this.addVertexFinalCode( 'vPosition = transformed;' );
 
 		}
-		
+
 		if ( this.requires.worldPosition ) {
 
 			this.addVaryCode( 'varying vec3 vWPosition;' );
-			
+
 			this.addVertexFinalCode( 'vWPosition = ( modelMatrix * vec4( transformed, 1.0 ) ).xyz;' );
 
 		}
-		
+
 		if ( this.requires.normal ) {
 
 			this.addVaryCode( 'varying vec3 vObjectNormal;' );
@@ -211,7 +211,7 @@ NodeBuilder.prototype = {
 			this.addVertexFinalCode( 'vObjectNormal = normal;' );
 
 		}
-		
+
 		if ( this.requires.worldNormal ) {
 
 			this.addVaryCode( 'varying vec3 vWNormal;' );
@@ -219,48 +219,48 @@ NodeBuilder.prototype = {
 			this.addVertexFinalCode( 'vWNormal = ( modelMatrix * vec4( objectNormal, 0.0 ) ).xyz;' );
 
 		}
-		
+
 		return this;
-		
+
 	},
-	
-	buildShader: function( shader, node ) {
-		
-		this.resultCode[shader] = node.build( this.setShader( shader ), 'v4' );
-		
+
+	buildShader: function ( shader, node ) {
+
+		this.resultCode[ shader ] = node.build( this.setShader( shader ), 'v4' );
+
 	},
-	
-	setMaterial: function( material, renderer ) {
-		
+
+	setMaterial: function ( material, renderer ) {
+
 		this.material = material;
 		this.renderer = renderer;
-		
+
 		this.requires.lights = material.lights;
 		this.requires.fog = material.fog;
-		
+
 		this.mergeDefines( material.defines );
-		
+
 		return this;
-		
+
 	},
-	
+
 	addFlow: function ( slot, cache, context ) {
-		
+
 		return this.addSlot( slot ).addCache( cache ).addContext( context );
-		
+
 	},
-	
+
 	removeFlow: function () {
-		
+
 		return this.removeSlot().removeCache().removeContext();
-		
+
 	},
-	
+
 	addCache: function ( name ) {
 
 		this.cache = name || '';
 		this.caches.push( this.cache );
-		
+
 		return this;
 
 	},
@@ -291,7 +291,7 @@ NodeBuilder.prototype = {
 		return this;
 
 	},
-	
+
 	addSlot: function ( name ) {
 
 		this.slot = name || '';
@@ -310,7 +310,7 @@ NodeBuilder.prototype = {
 
 	},
 
-	
+
 	addVertexCode: function ( code ) {
 
 		this.addCode( code, 'vertex' );
@@ -322,14 +322,14 @@ NodeBuilder.prototype = {
 		this.addCode( code, 'fragment' );
 
 	},
-	
+
 	addCode: function ( code, shader ) {
 
-		this.code[shader || this.shader] += code + '\n';
+		this.code[ shader || this.shader ] += code + '\n';
 
 	},
-	
-	
+
+
 	addVertexNodeCode: function ( code ) {
 
 		this.addNodeCode( code, 'vertex' );
@@ -341,37 +341,37 @@ NodeBuilder.prototype = {
 		this.addNodeCode( code, 'fragment' );
 
 	},
-	
+
 	addNodeCode: function ( code, shader ) {
 
-		this.nodeCode[shader || this.shader] += code + '\n';
+		this.nodeCode[ shader || this.shader ] += code + '\n';
 
 	},
-	
+
 	clearNodeCode: function ( shader ) {
 
 		shader = shader || this.shader;
-	
-		var code = this.nodeCode[shader];
-		
-		this.nodeCode[shader] = '';
+
+		var code = this.nodeCode[ shader ];
+
+		this.nodeCode[ shader ] = '';
 
 		return code;
-		
+
 	},
-	
-	clearVertexNodeCode: function (  ) {
+
+	clearVertexNodeCode: function ( ) {
 
 		return this.clearNodeCode( 'vertex' );
 
 	},
-	
-	clearFragmentNodeCode: function (  ) {
+
+	clearFragmentNodeCode: function ( ) {
 
 		return this.clearNodeCode( 'fragment' );
 
 	},
-	
+
 	addVertexFinalCode: function ( code ) {
 
 		this.addFinalCode( code, 'vertex' );
@@ -383,50 +383,50 @@ NodeBuilder.prototype = {
 		this.addFinalCode( code, 'fragment' );
 
 	},
-	
+
 	addFinalCode: function ( code, shader ) {
 
-		this.finalCode[shader || this.shader] += code + '\n';
+		this.finalCode[ shader || this.shader ] += code + '\n';
 
 	},
-	
-	
+
+
 	addVertexParsCode: function ( code ) {
 
 		this.addParsCode( code, 'vertex' );
 
 	},
-	
+
 	addFragmentParsCode: function ( code ) {
 
 		this.addParsCode( code, 'fragment' );
 
 	},
-	
+
 	addParsCode: function ( code, shader ) {
 
-		this.parsCode[shader || this.shader] += code + '\n';
+		this.parsCode[ shader || this.shader ] += code + '\n';
 
 	},
-	
-	
+
+
 	addVaryCode: function ( code ) {
 
 		this.addVertexParsCode( code );
 		this.addFragmentParsCode( code );
 
 	},
-	
-	
+
+
 	isCache: function ( name ) {
 
-		return this.caches.indexOf( name ) !== -1;
+		return this.caches.indexOf( name ) !== - 1;
 
 	},
 
 	isSlot: function ( name ) {
 
-		return this.slots.indexOf( name ) !== -1;
+		return this.slots.indexOf( name ) !== - 1;
 
 	},
 
@@ -435,7 +435,7 @@ NodeBuilder.prototype = {
 		this.defines[ name ] = value === undefined ? 1 : value;
 
 	},
-	
+
 	isDefined: function ( name ) {
 
 		return this.defines[ name ] !== undefined;
@@ -445,8 +445,8 @@ NodeBuilder.prototype = {
 	getVar: function ( uuid, type, ns, shader ) {
 
 		shader = shader || 'varying';
-	
-		var vars = this.getVars(shader),
+
+		var vars = this.getVars( shader ),
 			data = vars[ uuid ];
 
 		if ( ! data ) {
@@ -464,13 +464,13 @@ NodeBuilder.prototype = {
 		return data;
 
 	},
-	
+
 	getTempVar: function ( uuid, type, ns ) {
 
 		return this.getVar( uuid, type, ns, this.shader );
 
 	},
-	
+
 	getAttribute: function ( name, type ) {
 
 		if ( ! this.attributes[ name ] ) {
@@ -487,45 +487,45 @@ NodeBuilder.prototype = {
 		return this.attributes[ name ];
 
 	},
-	
-	getCode: function( shader ) {
-		
+
+	getCode: function ( shader ) {
+
 		return [
 			this.prefixCode,
 			this.parsCode[ shader ],
-			this.getVarListCode( this.getVars('varying'), 'varying' ),
-			this.getVarListCode( this.inputs.uniforms[shader], 'uniform' ),
+			this.getVarListCode( this.getVars( 'varying' ), 'varying' ),
+			this.getVarListCode( this.inputs.uniforms[ shader ], 'uniform' ),
 			this.getIncludesCode( 'consts', shader ),
 			this.getIncludesCode( 'structs', shader ),
 			this.getIncludesCode( 'functions', shader ),
 			'void main() {',
-				this.getVarListCode( this.getVars(shader) ),
-				this.code[ shader ], 
-				this.resultCode[ shader ],
-				this.finalCode[ shader ],
+			this.getVarListCode( this.getVars( shader ) ),
+			this.code[ shader ],
+			this.resultCode[ shader ],
+			this.finalCode[ shader ],
 			'}'
 		].join( "\n" );
-		
+
 	},
-	
+
 	getVarListCode: function ( vars, prefix ) {
 
 		prefix = prefix || '';
-	
+
 		var code = '';
 
 		for ( var i = 0, l = vars.length; i < l; ++ i ) {
 
-			var nVar = vars[i],
+			var nVar = vars[ i ],
 				type = nVar.type,
 				name = nVar.name;
-			
+
 			var formatType = this.getFormatByType( type );
 
 			if ( formatType === undefined ) {
-				
+
 				throw new Error( "Node pars " + formatType + " not found." );
-				
+
 			}
 
 			code += prefix + ' ' + formatType + ' ' + name + ';\n';
@@ -535,21 +535,21 @@ NodeBuilder.prototype = {
 		return code;
 
 	},
-	
+
 	getVars: function ( shader ) {
 
 		return this.inputs.vars[ shader || this.shader ];
 
 	},
-	
+
 	getNodeData: function ( node ) {
 
 		var uuid = node.isNode ? node.uuid : node;
-	
+
 		return this.nodeData[ uuid ] = this.nodeData[ uuid ] || {};
 
 	},
-	
+
 	createUniform: function ( shader, type, node, ns, needsUpdate ) {
 
 		var uniforms = this.inputs.uniforms,
@@ -564,40 +564,40 @@ NodeBuilder.prototype = {
 
 		uniforms.list.push( uniform );
 
-		uniforms[shader].push( uniform );
-		uniforms[shader][ uniform.name ] = uniform;
-		
+		uniforms[ shader ].push( uniform );
+		uniforms[ shader ][ uniform.name ] = uniform;
+
 		this.uniforms[ uniform.name ] = uniform;
-		
+
 		return uniform;
 
 	},
-	
+
 	createVertexUniform: function ( type, node, ns, needsUpdate ) {
 
 		return this.createUniform( 'vertex', type, node, ns, needsUpdate );
 
 	},
-	
+
 	createFragmentUniform: function ( type, node, ns, needsUpdate ) {
 
 		return this.createUniform( 'fragment', type, node, ns, needsUpdate );
 
 	},
-	
+
 	include: function ( node, parent, source ) {
 
 		var includesStruct;
 
 		node = typeof node === 'string' ? NodeLib.get( node ) : node;
 
-		if (this.context.include === false) {
-			
+		if ( this.context.include === false ) {
+
 			return node.name;
-			
-		} 
-		
-		
+
+		}
+
+
 		if ( node instanceof FunctionNode ) {
 
 			includesStruct = this.includes.functions;
@@ -605,17 +605,17 @@ NodeBuilder.prototype = {
 		} else if ( node instanceof ConstNode ) {
 
 			includesStruct = this.includes.consts;
-			
+
 		} else if ( node instanceof StructNode ) {
 
 			includesStruct = this.includes.structs;
 
 		}
-		
+
 		var includes = includesStruct[ this.shader ] = includesStruct[ this.shader ] || [];
 
-		if (node) {
-		
+		if ( node ) {
+
 			var included = includes[ node.name ];
 
 			if ( ! included ) {
@@ -654,13 +654,13 @@ NodeBuilder.prototype = {
 				included.src = source;
 
 			}
-			
+
 			return node.name;
-			
+
 		} else {
-			
-			throw new Error("Include not found.");
-			
+
+			throw new Error( "Include not found." );
+
 		}
 
 	},
@@ -670,7 +670,7 @@ NodeBuilder.prototype = {
 		return color.replace( 'r', 'x' ).replace( 'g', 'y' ).replace( 'b', 'z' ).replace( 'a', 'w' );
 
 	},
-	
+
 	colorToVector: function ( color ) {
 
 		return color.replace( /c/g, 'v3' );
@@ -679,10 +679,10 @@ NodeBuilder.prototype = {
 
 	getIncludes: function ( type, shader ) {
 
-		return this.includes[type][shader || this.shader];
+		return this.includes[ type ][ shader || this.shader ];
 
 	},
-	
+
 	getIncludesCode: function () {
 
 		function sortByPosition( a, b ) {
@@ -694,10 +694,10 @@ NodeBuilder.prototype = {
 		return function getIncludesCode( type, shader ) {
 
 			var includes = this.getIncludes( type, shader );
-	
+
 			if ( ! includes ) return '';
 
-			var code = '', 
+			var code = '',
 				includes = includes.sort( sortByPosition );
 
 			for ( var i = 0; i < includes.length; i ++ ) {
@@ -711,7 +711,7 @@ NodeBuilder.prototype = {
 		};
 
 	}(),
-	
+
 	getConstructorFromLength: function ( len ) {
 
 		return constructors[ len - 1 ];
@@ -727,7 +727,7 @@ NodeBuilder.prototype = {
 	getTypeLength: function ( type ) {
 
 		if ( type === 'f' ) return 1;
-	
+
 		return parseInt( this.colorToVector( type ).substr( 1 ) );
 
 	},
@@ -739,77 +739,77 @@ NodeBuilder.prototype = {
 		return 'v' + len;
 
 	},
-	
-	findNode: function() {
-		
-		for(var i = 0; i < arguments.length; i++) {
-			
-			var nodeCandidate = arguments[i];
-			
-			if (nodeCandidate !== undefined && nodeCandidate.isNode) {
-				
+
+	findNode: function () {
+
+		for ( var i = 0; i < arguments.length; i ++ ) {
+
+			var nodeCandidate = arguments[ i ];
+
+			if ( nodeCandidate !== undefined && nodeCandidate.isNode ) {
+
 				return nodeCandidate;
-				
+
 			}
-			
+
 		}
-		
-	},
-	
-	resolve: function() {
-		
-		for(var i = 0; i < arguments.length; i++) {
-			
-			var nodeCandidate = arguments[i];
-			
-			if (nodeCandidate !== undefined) {
-				
-				if (nodeCandidate.isNode) {
-				
+
+	},
+
+	resolve: function () {
+
+		for ( var i = 0; i < arguments.length; i ++ ) {
+
+			var nodeCandidate = arguments[ i ];
+
+			if ( nodeCandidate !== undefined ) {
+
+				if ( nodeCandidate.isNode ) {
+
 					return nodeCandidate;
-					
-				} else if (nodeCandidate.isTexture) {
-					
-					switch( nodeCandidate.mapping ) {
-					
+
+				} else if ( nodeCandidate.isTexture ) {
+
+					switch ( nodeCandidate.mapping ) {
+
 						case THREE.CubeReflectionMapping:
 						case THREE.CubeRefractionMapping:
 
 							return new CubeTextureNode( nodeCandidate );
 
 							break;
-						
+
 						case THREE.CubeUVReflectionMapping:
 						case THREE.CubeUVRefractionMapping:
 
 							return new TextureCubeNode( new TextureNode( nodeCandidate ) );
 
 							break;
-							
+
 						default:
-						
+
 							return new TextureNode( nodeCandidate );
-						
+
 					}
-					
-				} else if (nodeCandidate.isVector2) {
-					
+
+				} else if ( nodeCandidate.isVector2 ) {
+
 					return new Vector2Node( nodeCandidate );
-					
-				} else if (nodeCandidate.isVector3) {
-					
+
+				} else if ( nodeCandidate.isVector3 ) {
+
 					return new Vector3Node( nodeCandidate );
-					
-				} else if (nodeCandidate.isVector4) {
-					
+
+				} else if ( nodeCandidate.isVector4 ) {
+
 					return new Vector4Node( nodeCandidate );
-					
+
 				}
-				
+
 			}
-			
+
 		}
-		
+
 	},
 
 	format: function ( code, from, to ) {
@@ -821,7 +821,7 @@ NodeBuilder.prototype = {
 			case 'f <- v2' : return code + '.x';
 			case 'f <- v3' : return code + '.x';
 			case 'f <- v4' : return code + '.x';
-			case 'f <- i'  : return 'float( ' + code + ' )';
+			case 'f <- i' : return 'float( ' + code + ' )';
 
 			case 'v2 <- f' : return 'vec2( ' + code + ' )';
 			case 'v2 <- v3': return code + '.xy';
@@ -838,7 +838,7 @@ NodeBuilder.prototype = {
 			case 'v4 <- v3': return 'vec4( ' + code + ', 1.0 )';
 			case 'v4 <- i' : return 'vec4( float( ' + code + ' ) )';
 
-			case 'i <- f'  : return 'int( ' + code + ' )';
+			case 'i <- f' : return 'int( ' + code + ' )';
 			case 'i <- v2' : return 'int( ' + code + '.x )';
 			case 'i <- v3' : return 'int( ' + code + '.x )';
 			case 'i <- v4' : return 'int( ' + code + '.x )';
@@ -854,7 +854,7 @@ NodeBuilder.prototype = {
 		return convertFormatToType[ format ] || format;
 
 	},
-	
+
 	getFormatByType: function ( type ) {
 
 		return convertTypeToFormat[ type ] || type;
@@ -896,7 +896,7 @@ NodeBuilder.prototype = {
 		return this;
 
 	},
-	
+
 	mergeDefines: function ( defines ) {
 
 		for ( var name in defines ) {
@@ -904,11 +904,11 @@ NodeBuilder.prototype = {
 			this.defines[ name ] = defines[ name ];
 
 		}
-		
+
 		return this.defines;
 
 	},
-	
+
 	mergeUniform: function ( uniforms ) {
 
 		for ( var name in uniforms ) {
@@ -916,15 +916,15 @@ NodeBuilder.prototype = {
 			this.uniforms[ name ] = uniforms[ name ];
 
 		}
-		
+
 		return this.uniforms;
 
 	},
-	
+
 	getTextureEncodingFromMap: function ( map, gammaOverrideLinear ) {
 
 		gammaOverrideLinear = gammaOverrideLinear !== undefined ? gammaOverrideLinear : this.context.gamma && ( this.renderer ? this.renderer.gammaInput : false );
-	
+
 		var encoding;
 
 		if ( ! map ) {

+ 14 - 14
examples/js/nodes/core/NodeFrame.js

@@ -8,7 +8,7 @@ function NodeFrame( time ) {
 
 	this.id = 0;
 
-};
+}
 
 NodeFrame.prototype = {
 
@@ -16,7 +16,7 @@ NodeFrame.prototype = {
 
 	update: function ( delta ) {
 
-		++this.id;
+		++ this.id;
 
 		this.time += delta;
 		this.delta = delta;
@@ -24,23 +24,23 @@ NodeFrame.prototype = {
 		return this;
 
 	},
-	
-	setRenderer: function( renderer ) {
-		
+
+	setRenderer: function ( renderer ) {
+
 		this.renderer = renderer;
-		
+
 		return this;
-		
+
 	},
-	
-	setRenderTexture: function( renderTexture ) {
-		
+
+	setRenderTexture: function ( renderTexture ) {
+
 		this.renderTexture = renderTexture;
-		
+
 		return this;
-		
+
 	},
-	
+
 	updateNode: function ( node ) {
 
 		if ( node.frameId === this.id ) return this;
@@ -52,7 +52,7 @@ NodeFrame.prototype = {
 		return this;
 
 	}
-	
+
 };
 
 export { NodeFrame };

+ 6 - 6
examples/js/nodes/core/NodeUniform.js

@@ -11,26 +11,26 @@ function NodeUniform( params ) {
 	this.node = params.node;
 	this.needsUpdate = params.needsUpdate;
 
-};
+}
 
 Object.defineProperties( NodeUniform.prototype, {
-	
+
 	value: {
-		
+
 		get: function () {
 
 			return this.node.value;
 
 		},
-		
+
 		set: function ( val ) {
 
 			this.node.value = val;
 
 		}
-		
+
 	}
-	
+
 } );
 
 export { NodeUniform };

+ 9 - 9
examples/js/nodes/core/NodeUtils.js

@@ -13,37 +13,37 @@ var NodeUtils = {
 			if ( subProperty ) {
 
 				return {
-					
+
 					get: function () {
 
 						return this[ proxy ][ property ][ subProperty ];
 
 					},
-					
+
 					set: function ( val ) {
 
 						this[ proxy ][ property ][ subProperty ] = val;
 
 					}
-					
+
 				};
 
 			} else {
 
 				return {
-					
+
 					get: function () {
 
 						return this[ proxy ][ property ];
 
 					},
-					
+
 					set: function ( val ) {
 
 						this[ proxy ][ property ] = val;
 
 					}
-					
+
 				};
 
 			}
@@ -57,8 +57,8 @@ var NodeUtils = {
 			for ( var i = 0; i < list.length; ++ i ) {
 
 				var data = list[ i ].split( "." ),
-					property = data[0],
-					subProperty = data[1];
+					property = data[ 0 ],
+					subProperty = data[ 1 ];
 
 				shortcuts[ property ] = applyShortcut( proxy, property, subProperty );
 
@@ -69,7 +69,7 @@ var NodeUtils = {
 		};
 
 	}()
-	
+
 };
 
 export { NodeUtils };

+ 20 - 21
examples/js/nodes/core/StructNode.js

@@ -3,18 +3,17 @@
  */
 
 import { TempNode } from './TempNode.js';
-import { FunctionNode } from './FunctionNode.js';
 
 var declarationRegexp = /^struct\s*([a-z_0-9]+)\s*{\s*((.|\n)*?)}/img,
 	propertiesRegexp = /\s*(\w*?)\s*(\w*?)(\=|\;)/img;
 
 function StructNode( src ) {
 
-	TempNode.call( this);
+	TempNode.call( this );
 
 	this.eval( src );
 
-};
+}
 
 StructNode.prototype = Object.create( TempNode.prototype );
 StructNode.prototype.constructor = StructNode;
@@ -33,9 +32,9 @@ StructNode.prototype.getInputByName = function ( name ) {
 	while ( i -- ) {
 
 		if ( this.inputs[ i ].name === name ) {
-			
+
 			return this.inputs[ i ];
-			
+
 		}
 
 	}
@@ -59,32 +58,32 @@ StructNode.prototype.generate = function ( builder, output ) {
 StructNode.prototype.eval = function ( src ) {
 
 	this.src = src || '';
-	
+
 	this.inputs = [];
-	
+
 	var declaration = declarationRegexp.exec( this.src );
-	
-	if (declaration) {
-		
-		var properties = declaration[2], match;
-		
+
+	if ( declaration ) {
+
+		var properties = declaration[ 2 ], match;
+
 		while ( match = propertiesRegexp.exec( properties ) ) {
-			
+
 			this.inputs.push( {
-				type: match[1],
-				name: match[2]
+				type: match[ 1 ],
+				name: match[ 2 ]
 			} );
-			
+
 		}
-		
-		this.name = declaration[1];
+
+		this.name = declaration[ 1 ];
 
 	} else {
-		
+
 		this.name = '';
-		
+
 	}
-	
+
 	this.type = this.name;
 
 };

+ 6 - 6
examples/js/nodes/core/TempNode.js

@@ -14,7 +14,7 @@ function TempNode( type, params ) {
 	this.shared = params.shared !== undefined ? params.shared : true;
 	this.unique = params.unique !== undefined ? params.unique : false;
 
-};
+}
 
 TempNode.prototype = Object.create( Node.prototype );
 TempNode.prototype.constructor = TempNode;
@@ -56,7 +56,7 @@ TempNode.prototype.build = function ( builder, output, uuid, ns ) {
 
 			return data.name;
 
-		} else if ( !this.isShared( builder, type ) || ( ! builder.optimize || data.deps == 1 ) ) {
+		} else if ( ! this.isShared( builder, type ) || ( ! builder.optimize || data.deps == 1 ) ) {
 
 			return Node.prototype.build.call( this, builder, output, uuid );
 
@@ -65,7 +65,7 @@ TempNode.prototype.build = function ( builder, output, uuid, ns ) {
 		uuid = this.getUuid( false );
 
 		var name = this.getTemp( builder, uuid );
-		
+
 		if ( name ) {
 
 			return builder.format( name, type, output );
@@ -114,10 +114,10 @@ TempNode.prototype.getTemp = function ( builder, uuid ) {
 
 	uuid = uuid || this.uuid;
 
-	var tempVar = builder.getVars()[uuid]
-	
+	var tempVar = builder.getVars()[ uuid ];
+
 	return tempVar ? tempVar.name : undefined;
-	
+
 };
 
 TempNode.prototype.generate = function ( builder, output, uuid, type, ns ) {

+ 6 - 6
examples/js/nodes/core/VarNode.js

@@ -7,10 +7,10 @@ import { Node } from './Node.js';
 function VarNode( type, value ) {
 
 	Node.call( this, type );
-	
+
 	this.value = value;
 
-};
+}
 
 VarNode.prototype = Object.create( Node.prototype );
 VarNode.prototype.constructor = VarNode;
@@ -31,18 +31,18 @@ VarNode.prototype.generate = function ( builder, output ) {
 		builder.addNodeCode( varying.name + ' = ' + this.value.build( builder, this.getType( builder ) ) + ';' );
 
 	}
-	
+
 	return builder.format( varying.name, this.getType( builder ), output );
 
 };
 
 VarNode.prototype.copy = function ( source ) {
-	
+
 	Node.prototype.copy.call( this, source );
-	
+
 	this.type = source.type;
 	this.value = source.value;
-	
+
 };
 
 VarNode.prototype.toJSON = function ( meta ) {

+ 12 - 12
examples/js/nodes/effects/BlurNode.js

@@ -24,10 +24,10 @@ function BlurNode( value, uv, radius, size ) {
 	this.horizontal = new FloatNode( 1 / 64 );
 	this.vertical = new FloatNode( 1 / 64 );
 
-};
+}
+
+BlurNode.Nodes = ( function () {
 
-BlurNode.Nodes = (function() {
-	
 	var blurX = new FunctionNode( [
 		"vec4 blurX( sampler2D texture, vec2 uv, float s ) {",
 		"	vec4 sum = vec4( 0.0 );",
@@ -43,7 +43,7 @@ BlurNode.Nodes = (function() {
 		"	return sum * .667;",
 		"}"
 	].join( "\n" ) );
-	
+
 	var blurY = new FunctionNode( [
 		"vec4 blurY( sampler2D texture, vec2 uv, float s ) {",
 		"	vec4 sum = vec4( 0.0 );",
@@ -59,13 +59,13 @@ BlurNode.Nodes = (function() {
 		"	return sum * .667;",
 		"}"
 	].join( "\n" ) );
-	
+
 	return {
 		blurX: blurX,
 		blurY: blurY
 	};
-	
-})();
+
+} )();
 
 
 BlurNode.prototype = Object.create( TempNode.prototype );
@@ -98,7 +98,7 @@ BlurNode.prototype.generate = function ( builder, output ) {
 
 		var blurX = builder.include( BlurNode.Nodes.blurX ),
 			blurY = builder.include( BlurNode.Nodes.blurY );
-		
+
 		if ( this.blurX ) {
 
 			blurCode.push( blurX + '( ' + this.value.build( builder, 'sampler2D' ) + ', ' + this.uv.build( builder, 'v2' ) + ', ' + this.horizontal.build( builder, 'f' ) + ' )' );
@@ -128,9 +128,9 @@ BlurNode.prototype.generate = function ( builder, output ) {
 };
 
 BlurNode.prototype.copy = function ( source ) {
-			
+
 	TempNode.prototype.copy.call( this, source );
-	
+
 	this.value = source.value;
 	this.uv = source.uv;
 	this.radius = source.radius;
@@ -139,7 +139,7 @@ BlurNode.prototype.copy = function ( source ) {
 
 	this.blurX = source.blurX;
 	this.blurY = source.blurY;
-					
+
 };
 
 BlurNode.prototype.toJSON = function ( meta ) {
@@ -165,4 +165,4 @@ BlurNode.prototype.toJSON = function ( meta ) {
 
 };
 
-export { BlurNode };
+export { BlurNode };

+ 24 - 24
examples/js/nodes/effects/ColorAdjustmentNode.js

@@ -15,58 +15,58 @@ function ColorAdjustmentNode( rgb, adjustment, method ) {
 
 	this.method = method || ColorAdjustmentNode.SATURATION;
 
-};
+}
+
+ColorAdjustmentNode.Nodes = ( function () {
 
-ColorAdjustmentNode.Nodes = (function() {
-	
 	var hue = new FunctionNode( [
 		"vec3 hue(vec3 rgb, float adjustment) {",
-		
+
 		"	const mat3 RGBtoYIQ = mat3(0.299, 0.587, 0.114, 0.595716, -0.274453, -0.321263, 0.211456, -0.522591, 0.311135);",
 		"	const mat3 YIQtoRGB = mat3(1.0, 0.9563, 0.6210, 1.0, -0.2721, -0.6474, 1.0, -1.107, 1.7046);",
-		
+
 		"	vec3 yiq = RGBtoYIQ * rgb;",
-		
+
 		"	float hue = atan(yiq.z, yiq.y) + adjustment;",
 		"	float chroma = sqrt(yiq.z * yiq.z + yiq.y * yiq.y);",
-		
+
 		"	return YIQtoRGB * vec3(yiq.x, chroma * cos(hue), chroma * sin(hue));",
-		
+
 		"}"
 	].join( "\n" ) );
-	
+
 	var saturation = new FunctionNode( [
 		// Algorithm from Chapter 16 of OpenGL Shading Language
 		"vec3 saturation(vec3 rgb, float adjustment) {",
-		
+
 		"	vec3 intensity = vec3( luminance( rgb ) );",
-		
+
 		"	return mix( intensity, rgb, adjustment );",
-		
+
 		"}"
 	].join( "\n" ), [ LuminanceNode.Nodes.luminance ] ); // include LuminanceNode function
-	
+
 	var vibrance = new FunctionNode( [
 		// Shader by Evan Wallace adapted by @lo-th
 		"vec3 vibrance(vec3 rgb, float adjustment) {",
-		
+
 		"	float average = (rgb.r + rgb.g + rgb.b) / 3.0;",
-		
+
 		"	float mx = max(rgb.r, max(rgb.g, rgb.b));",
 		"	float amt = (mx - average) * (-3.0 * adjustment);",
-		
+
 		"	return mix(rgb.rgb, vec3(mx), amt);",
-		
+
 		"}"
 	].join( "\n" ) );
-	
+
 	return {
 		hue: hue,
 		saturation: saturation,
 		vibrance: vibrance
 	};
-	
-})();
+
+} )();
 
 ColorAdjustmentNode.SATURATION = 'saturation';
 ColorAdjustmentNode.HUE = 'hue';
@@ -99,16 +99,16 @@ ColorAdjustmentNode.prototype.generate = function ( builder, output ) {
 
 	}
 
-	var method = builder.include( ColorAdjustmentNode.Nodes[this.method] );
+	var method = builder.include( ColorAdjustmentNode.Nodes[ this.method ] );
 
 	return builder.format( method + '( ' + rgb + ', ' + adjustment + ' )', this.getType( builder ), output );
 
 };
 
 ColorAdjustmentNode.prototype.copy = function ( source ) {
-			
+
 	TempNode.prototype.copy.call( this, source );
-	
+
 	this.rgb = source.rgb;
 	this.adjustment = source.adjustment;
 	this.method = source.method;
@@ -133,4 +133,4 @@ ColorAdjustmentNode.prototype.toJSON = function ( meta ) {
 
 };
 
-export { ColorAdjustmentNode };
+export { ColorAdjustmentNode };

+ 10 - 10
examples/js/nodes/effects/LuminanceNode.js

@@ -12,18 +12,18 @@ function LuminanceNode( rgb ) {
 
 	this.rgb = rgb;
 
-};
+}
+
+LuminanceNode.Nodes = ( function () {
 
-LuminanceNode.Nodes = (function() {
-	
 	var LUMA = new ConstNode( "vec3 LUMA vec3( 0.2125, 0.7154, 0.0721 )" );
 
 	var luminance = new FunctionNode( [
 		// Algorithm from Chapter 10 of Graphics Shaders
 		"float luminance( vec3 rgb ) {",
-		
+
 		"	return dot( rgb, LUMA );",
-		
+
 		"}"
 	].join( "\n" ), [ LUMA ] );
 
@@ -31,8 +31,8 @@ LuminanceNode.Nodes = (function() {
 		LUMA: LUMA,
 		luminance: luminance
 	};
-	
-})();
+
+} )();
 
 LuminanceNode.prototype = Object.create( TempNode.prototype );
 LuminanceNode.prototype.constructor = LuminanceNode;
@@ -47,11 +47,11 @@ LuminanceNode.prototype.generate = function ( builder, output ) {
 };
 
 LuminanceNode.prototype.copy = function ( source ) {
-			
+
 	TempNode.prototype.copy.call( this, source );
-	
+
 	this.rgb = source.rgb;
-	
+
 };
 
 LuminanceNode.prototype.toJSON = function ( meta ) {

+ 4 - 4
examples/js/nodes/inputs/ColorNode.js

@@ -11,7 +11,7 @@ function ColorNode( color, g, b ) {
 
 	this.value = color instanceof THREE.Color ? color : new THREE.Color( color || 0, g, b );
 
-};
+}
 
 ColorNode.prototype = Object.create( InputNode.prototype );
 ColorNode.prototype.constructor = ColorNode;
@@ -26,11 +26,11 @@ ColorNode.prototype.generateReadonly = function ( builder, output, uuid, type, n
 };
 
 ColorNode.prototype.copy = function ( source ) {
-			
+
 	InputNode.prototype.copy.call( this, source );
-	
+
 	this.value.copy( source );
-	
+
 };
 
 ColorNode.prototype.toJSON = function ( meta ) {

+ 9 - 9
examples/js/nodes/inputs/CubeTextureNode.js

@@ -14,7 +14,7 @@ function CubeTextureNode( value, uv, bias ) {
 	this.uv = uv || new ReflectNode();
 	this.bias = bias;
 
-};
+}
 
 CubeTextureNode.prototype = Object.create( InputNode.prototype );
 CubeTextureNode.prototype.constructor = CubeTextureNode;
@@ -50,28 +50,28 @@ CubeTextureNode.prototype.generate = function ( builder, output ) {
 	else code = 'texCube( ' + cubetex + ', ' + uv + ' )';
 
 	// add this context to replace ColorSpaceNode.input to code
-	
-	builder.addContext( { input: code, encoding: builder.getTextureEncodingFromMap( this.value ), include: builder.isShader('vertex') } )
 
-	this.colorSpace = this.colorSpace || new ColorSpaceNode( this );	
+	builder.addContext( { input: code, encoding: builder.getTextureEncodingFromMap( this.value ), include: builder.isShader( 'vertex' ) } );
+
+	this.colorSpace = this.colorSpace || new ColorSpaceNode( this );
 	code = this.colorSpace.build( builder, this.type );
-	
+
 	builder.removeContext();
-	
+
 	return builder.format( code, this.type, output );
 
 };
 
 CubeTextureNode.prototype.copy = function ( source ) {
-			
+
 	InputNode.prototype.copy.call( this, source );
-	
+
 	if ( source.value ) this.value = source.value;
 
 	this.uv = source.uv;
 
 	if ( source.bias ) this.bias = source.bias;
-	
+
 };
 
 CubeTextureNode.prototype.toJSON = function ( meta ) {

+ 4 - 4
examples/js/nodes/inputs/FloatNode.js

@@ -10,7 +10,7 @@ function FloatNode( value ) {
 
 	this.value = value || 0;
 
-};
+}
 
 FloatNode.prototype = Object.create( InputNode.prototype );
 FloatNode.prototype.constructor = FloatNode;
@@ -23,11 +23,11 @@ FloatNode.prototype.generateReadonly = function ( builder, output, uuid, type, n
 };
 
 FloatNode.prototype.copy = function ( source ) {
-			
+
 	InputNode.prototype.copy.call( this, source );
-	
+
 	this.value = source.value;
-	
+
 };
 
 FloatNode.prototype.toJSON = function ( meta ) {

+ 4 - 4
examples/js/nodes/inputs/IntNode.js

@@ -10,7 +10,7 @@ function IntNode( value ) {
 
 	this.value = Math.floor( value || 0 );
 
-};
+}
 
 IntNode.prototype = Object.create( InputNode.prototype );
 IntNode.prototype.constructor = IntNode;
@@ -23,11 +23,11 @@ IntNode.prototype.generateReadonly = function ( builder, output, uuid, type, ns,
 };
 
 IntNode.prototype.copy = function ( source ) {
-			
+
 	InputNode.prototype.copy.call( this, source );
-	
+
 	this.value = source.value;
-	
+
 };
 
 IntNode.prototype.toJSON = function ( meta ) {

+ 8 - 8
examples/js/nodes/inputs/Matrix3Node.js

@@ -10,7 +10,7 @@ function Matrix3Node( matrix ) {
 
 	this.value = matrix || new THREE.Matrix3();
 
-};
+}
 
 Matrix3Node.prototype = Object.create( InputNode.prototype );
 Matrix3Node.prototype.constructor = Matrix3Node;
@@ -19,19 +19,19 @@ Matrix3Node.prototype.nodeType = "Matrix3";
 Object.defineProperties( Matrix3Node.prototype, {
 
 	elements: {
-		
-		set: function (val) {
+
+		set: function ( val ) {
 
 			this.value.elements = val;
 
 		},
-		
+
 		get: function () {
 
 			return this.value.elements;
 
 		}
-		
+
 	}
 
 } );
@@ -44,11 +44,11 @@ Matrix3Node.prototype.generateReadonly = function ( builder, output, uuid, type,
 
 
 Matrix3Node.prototype.copy = function ( source ) {
-			
+
 	InputNode.prototype.copy.call( this, source );
-	
+
 	this.value.fromArray( source.elements );
-	
+
 };
 
 Matrix3Node.prototype.toJSON = function ( meta ) {

+ 8 - 8
examples/js/nodes/inputs/Matrix4Node.js

@@ -10,7 +10,7 @@ function Matrix4Node( matrix ) {
 
 	this.value = matrix || new THREE.Matrix4();
 
-};
+}
 
 Matrix4Node.prototype = Object.create( InputNode.prototype );
 Matrix4Node.prototype.constructor = Matrix4Node;
@@ -19,19 +19,19 @@ Matrix4Node.prototype.nodeType = "Matrix4";
 Object.defineProperties( Matrix4Node.prototype, {
 
 	elements: {
-		
-		set: function (val) {
+
+		set: function ( val ) {
 
 			this.value.elements = val;
 
 		},
-		
+
 		get: function () {
 
 			return this.value.elements;
 
 		}
-		
+
 	}
 
 } );
@@ -43,11 +43,11 @@ Matrix4Node.prototype.generateReadonly = function ( builder, output, uuid, type,
 };
 
 Matrix4Node.prototype.copy = function ( source ) {
-			
+
 	InputNode.prototype.copy.call( this, source );
-	
+
 	this.scope.value.fromArray( source.elements );
-	
+
 };
 
 Matrix4Node.prototype.toJSON = function ( meta ) {

+ 9 - 9
examples/js/nodes/inputs/PropertyNode.js

@@ -3,15 +3,15 @@
  */
 
 import { InputNode } from '../core/InputNode.js';
- 
+
 function PropertyNode( object, property, type ) {
 
 	InputNode.call( this, type );
-	
+
 	this.object = object;
 	this.property = property;
 
-};
+}
 
 PropertyNode.prototype = Object.create( InputNode.prototype );
 PropertyNode.prototype.constructor = PropertyNode;
@@ -20,19 +20,19 @@ PropertyNode.prototype.nodeType = "Property";
 Object.defineProperties( PropertyNode.prototype, {
 
 	value: {
-		
+
 		get: function () {
 
 			return this.object[ this.property ];
 
 		},
-		
-		set: function ( val ) { 
-		
+
+		set: function ( val ) {
+
 			this.object[ this.property ] = val;
-		
+
 		}
-		
+
 	}
 
 } );

+ 52 - 52
examples/js/nodes/inputs/RTTNode.js

@@ -2,7 +2,6 @@
  * @author sunag / http://www.sunag.com.br/
  */
 
-import { InputNode } from '../core/InputNode.js';
 import { NodeMaterial } from '../materials/NodeMaterial.js';
 import { TextureNode } from './TextureNode.js';
 
@@ -11,13 +10,13 @@ function RTTNode( width, height, input, options ) {
 	options = options || {};
 
 	this.input = input;
-	
+
 	this.clear = options.clear !== undefined ? options.clear : true;
-	
+
 	this.renderTarget = new THREE.WebGLRenderTarget( width, height, options );
-	
-	this.material = new THREE.NodeMaterial();
-	
+
+	this.material = new NodeMaterial();
+
 	this.camera = new THREE.OrthographicCamera( - 1, 1, 1, - 1, 0, 1 );
 	this.scene = new THREE.Scene();
 
@@ -26,102 +25,103 @@ function RTTNode( width, height, input, options ) {
 	this.scene.add( this.quad );
 
 	this.render = true;
-	
+
 	TextureNode.call( this, this.renderTarget.texture );
 
-};
+}
 
 RTTNode.prototype = Object.create( TextureNode.prototype );
 RTTNode.prototype.constructor = RTTNode;
 RTTNode.prototype.nodeType = "RTT";
 
 RTTNode.prototype.build = function ( builder, output, uuid ) {
-	
+
 	var rttBuilder = new THREE.NodeBuilder();
 	rttBuilder.nodes = builder.nodes;
 	rttBuilder.updaters = builder.updaters;
-	
+
 	this.material.fragment.value = this.input;
 	this.material.build( { builder: rttBuilder } );
 
 	return TextureNode.prototype.build.call( this, builder, output, uuid );
+
 };
 
 RTTNode.prototype.updateFramesaveTo = function ( frame ) {
-	
+
 	this.saveTo.render = false;
-			
-	if (this.saveTo !== this.saveToCurrent) {
-		
-		if (this.saveToMaterial) this.saveToMaterial.dispose();
-		
-		var material = new THREE.NodeMaterial();
+
+	if ( this.saveTo !== this.saveToCurrent ) {
+
+		if ( this.saveToMaterial ) this.saveToMaterial.dispose();
+
+		var material = new NodeMaterial();
 		material.fragment.value = this;
 		material.build();
-		
+
 		var scene = new THREE.Scene();
-		
+
 		var quad = new THREE.Mesh( new THREE.PlaneBufferGeometry( 2, 2 ), material );
 		quad.frustumCulled = false; // Avoid getting clipped
 		scene.add( quad );
-		
+
 		this.saveToScene = scene;
 		this.saveToMaterial = material;
-		
+
 	}
-	
+
 	this.saveToCurrent = this.saveTo;
 
 	frame.renderer.render( this.saveToScene, this.camera, this.saveTo.renderTarget, this.saveTo.clear );
-	
+
 };
 
 RTTNode.prototype.updateFrame = function ( frame ) {
-	
+
 	if ( frame.renderer ) {
-		
+
 		// from the second frame
-		
-		if (this.saveTo && this.saveTo.render === false) {
-			
+
+		if ( this.saveTo && this.saveTo.render === false ) {
+
 			this.updateFramesaveTo( frame );
-			
+
 		}
-		
-		if (this.render) {
-			
-			if (this.material.uniforms.renderTexture) {
-			
+
+		if ( this.render ) {
+
+			if ( this.material.uniforms.renderTexture ) {
+
 				this.material.uniforms.renderTexture.value = frame.renderTexture;
-				
+
 			}
-			
+
 			frame.renderer.render( this.scene, this.camera, this.renderTarget, this.clear );
-			
+
 		}
-		
+
 		// first frame
-		
-		if (this.saveTo && this.saveTo.render === true) {
-			
+
+		if ( this.saveTo && this.saveTo.render === true ) {
+
 			this.updateFramesaveTo( frame );
-			
+
 		}
-		
+
 	} else {
-		
-		console.warn("RTTNode need a renderer in NodeFrame");
-		
+
+		console.warn( "RTTNode need a renderer in NodeFrame" );
+
 	}
-	
+
 };
 
 RTTNode.prototype.copy = function ( source ) {
-			
+
 	TextureNode.prototype.copy.call( this, source );
-	
+
 	this.saveTo = source.saveTo;
-	
+
 };
 
 RTTNode.prototype.toJSON = function ( meta ) {
@@ -129,10 +129,10 @@ RTTNode.prototype.toJSON = function ( meta ) {
 	var data = this.getJSONNode( meta );
 
 	if ( ! data ) {
-		
+
 		data = THREE.TextureNode.prototype.toJSON.call( this, meta );
 
-		if (this.saveTo) data.saveTo = this.saveTo.toJSON( meta ).uuid;
+		if ( this.saveTo ) data.saveTo = this.saveTo.toJSON( meta ).uuid;
 
 	}
 

+ 4 - 4
examples/js/nodes/inputs/ReflectorNode.js

@@ -14,7 +14,7 @@ function ReflectorNode( mirror ) {
 
 	if ( mirror ) this.setMirror( mirror );
 
-};
+}
 
 ReflectorNode.prototype = Object.create( TempNode.prototype );
 ReflectorNode.prototype.constructor = ReflectorNode;
@@ -36,7 +36,7 @@ ReflectorNode.prototype.setMirror = function ( mirror ) {
 };
 
 ReflectorNode.prototype.generate = function ( builder, output ) {
-	
+
 	if ( builder.isShader( 'fragment' ) ) {
 
 		this.uvResult.a = this.offset;
@@ -61,9 +61,9 @@ ReflectorNode.prototype.generate = function ( builder, output ) {
 };
 
 ReflectorNode.prototype.copy = function ( source ) {
-			
+
 	InputNode.prototype.copy.call( this, source );
-	
+
 	this.scope.mirror = source.mirror;
 
 };

+ 1 - 1
examples/js/nodes/inputs/ScreenNode.js

@@ -9,7 +9,7 @@ function ScreenNode( uv ) {
 
 	TextureNode.call( this, undefined, uv );
 
-};
+}
 
 ScreenNode.prototype = Object.create( TextureNode.prototype );
 ScreenNode.prototype.constructor = ScreenNode;

+ 8 - 9
examples/js/nodes/inputs/TextureNode.js

@@ -3,7 +3,6 @@
  */
 
 import { InputNode } from '../core/InputNode.js';
-import { NodeBuilder } from '../core/NodeBuilder.js';
 import { UVNode } from '../accessors/UVNode.js';
 import { ColorSpaceNode } from '../utils/ColorSpaceNode.js';
 
@@ -16,7 +15,7 @@ function TextureNode( value, uv, bias, project ) {
 	this.bias = bias;
 	this.project = project !== undefined ? project : false;
 
-};
+}
 
 TextureNode.prototype = Object.create( InputNode.prototype );
 TextureNode.prototype.constructor = TextureNode;
@@ -55,12 +54,12 @@ TextureNode.prototype.generate = function ( builder, output ) {
 	else code = method + '( ' + tex + ', ' + uv + ' )';
 
 	// add this context to replace ColorSpaceNode.input to code
-	
-	builder.addContext( { input: code, encoding: builder.getTextureEncodingFromMap( this.value ), include: builder.isShader('vertex') } )
 
-	this.colorSpace = this.colorSpace || new ColorSpaceNode( this );	
+	builder.addContext( { input: code, encoding: builder.getTextureEncodingFromMap( this.value ), include: builder.isShader( 'vertex' ) } );
+
+	this.colorSpace = this.colorSpace || new ColorSpaceNode( this );
 	code = this.colorSpace.build( builder, this.type );
-	
+
 	builder.removeContext();
 
 	return builder.format( code, this.type, output );
@@ -68,16 +67,16 @@ TextureNode.prototype.generate = function ( builder, output ) {
 };
 
 TextureNode.prototype.copy = function ( source ) {
-			
+
 	InputNode.prototype.copy.call( this, source );
-	
+
 	if ( source.value ) this.value = source.value;
 
 	this.uv = source.uv;
 
 	if ( source.bias ) this.bias = source.bias;
 	if ( source.project !== undefined ) this.project = source.project;
-	
+
 };
 
 TextureNode.prototype.toJSON = function ( meta ) {

+ 3 - 3
examples/js/nodes/inputs/Vector2Node.js

@@ -11,7 +11,7 @@ function Vector2Node( x, y ) {
 
 	this.value = x instanceof THREE.Vector2 ? x : new THREE.Vector2( x, y );
 
-};
+}
 
 Vector2Node.prototype = Object.create( InputNode.prototype );
 Vector2Node.prototype.constructor = Vector2Node;
@@ -26,9 +26,9 @@ Vector2Node.prototype.generateReadonly = function ( builder, output, uuid, type,
 };
 
 Vector2Node.prototype.copy = function ( source ) {
-			
+
 	InputNode.prototype.copy.call( this, source );
-	
+
 	this.value.copy( source );
 
 };

+ 4 - 4
examples/js/nodes/inputs/Vector3Node.js

@@ -11,7 +11,7 @@ function Vector3Node( x, y, z ) {
 
 	this.value = x instanceof THREE.Vector3 ? x : new THREE.Vector3( x, y, z );
 
-};
+}
 
 Vector3Node.prototype = Object.create( InputNode.prototype );
 Vector3Node.prototype.constructor = Vector3Node;
@@ -26,11 +26,11 @@ Vector3Node.prototype.generateReadonly = function ( builder, output, uuid, type,
 };
 
 Vector3Node.prototype.copy = function ( source ) {
-			
+
 	InputNode.prototype.copy.call( this, source );
-	
+
 	this.value.copy( source );
-	
+
 };
 
 Vector3Node.prototype.toJSON = function ( meta ) {

+ 3 - 3
examples/js/nodes/inputs/Vector4Node.js

@@ -11,7 +11,7 @@ function Vector4Node( x, y, z, w ) {
 
 	this.value = x instanceof THREE.Vector4 ? x : new THREE.Vector4( x, y, z, w );
 
-};
+}
 
 Vector4Node.prototype = Object.create( InputNode.prototype );
 Vector4Node.prototype.constructor = Vector4Node;
@@ -26,9 +26,9 @@ Vector4Node.prototype.generateReadonly = function ( builder, output, uuid, type,
 };
 
 Vector4Node.prototype.copy = function ( source ) {
-			
+
 	InputNode.prototype.copy.call( this, source );
-	
+
 	this.value.copy( source );
 
 };

+ 1 - 1
examples/js/nodes/materials/MeshStandardNodeMaterial.js

@@ -14,7 +14,7 @@ function MeshStandardNodeMaterial() {
 
 	this.type = "MeshStandardNodeMaterial";
 
-};
+}
 
 MeshStandardNodeMaterial.prototype = Object.create( NodeMaterial.prototype );
 MeshStandardNodeMaterial.prototype.constructor = MeshStandardNodeMaterial;

+ 26 - 26
examples/js/nodes/materials/NodeMaterial.js

@@ -6,7 +6,7 @@ import { NodeBuilder } from '../core/NodeBuilder.js';
 import { ColorNode } from '../inputs/ColorNode.js';
 import { PositionNode } from '../accessors/PositionNode.js';
 import { RawNode } from './nodes/RawNode.js';
- 
+
 function NodeMaterial( vertex, fragment ) {
 
 	THREE.ShaderMaterial.call( this );
@@ -16,7 +16,7 @@ function NodeMaterial( vertex, fragment ) {
 
 	this.updaters = [];
 
-};
+}
 
 NodeMaterial.prototype = Object.create( THREE.ShaderMaterial.prototype );
 NodeMaterial.prototype.constructor = NodeMaterial;
@@ -27,13 +27,13 @@ NodeMaterial.prototype.isNodeMaterial = true;
 Object.defineProperties( NodeMaterial.prototype, {
 
 	properties: {
-		
+
 		get: function () {
 
 			return this.fragment.properties;
 
 		}
-		
+
 	}
 
 } );
@@ -67,47 +67,47 @@ NodeMaterial.prototype.build = function ( params ) {
 	params = params || {};
 
 	var builder = params.builder || new NodeBuilder();
-	
+
 	builder.setMaterial( this, params.renderer );
 	builder.build( this.vertex, this.fragment );
-	
-	this.vertexShader = builder.getCode('vertex');
-	this.fragmentShader = builder.getCode('fragment');
-	
+
+	this.vertexShader = builder.getCode( 'vertex' );
+	this.fragmentShader = builder.getCode( 'fragment' );
+
 	this.defines = builder.defines;
 	this.uniforms = builder.uniforms;
 	this.extensions = builder.extensions;
 	this.updaters = builder.updaters;
-	
+
 	this.fog = builder.requires.fog;
 	this.lights = builder.requires.lights;
 
 	this.transparent = builder.requires.transparent || this.blending > THREE.NormalBlending;
 
 	this.needsUpdate = false;
-	
+
 	return this;
 
 };
 
 NodeMaterial.prototype.copy = function ( source ) {
-	
+
 	var uuid = this.uuid;
-	
-	for (var name in source) {
-		
-		this[name] = source[name];
-		
+
+	for ( var name in source ) {
+
+		this[ name ] = source[ name ];
+
 	}
-	
+
 	this.uuid = uuid;
-	
-	if ( source.userData !== undefined) {
-		
+
+	if ( source.userData !== undefined ) {
+
 		this.userData = JSON.parse( JSON.stringify( source.userData ) );
-		
+
 	}
-	
+
 };
 
 NodeMaterial.prototype.toJSON = function ( meta ) {
@@ -153,7 +153,7 @@ NodeMaterial.prototype.toJSON = function ( meta ) {
 		if ( this.scale !== undefined ) data.scale = this.scale;
 
 		if ( this.dithering === true ) data.dithering = true;
-		
+
 		if ( this.wireframe === true ) data.wireframe = this.wireframe;
 		if ( this.wireframeLinewidth > 1 ) data.wireframeLinewidth = this.wireframeLinewidth;
 		if ( this.wireframeLinecap !== 'round' ) data.wireframeLinecap = this.wireframeLinecap;
@@ -161,7 +161,7 @@ NodeMaterial.prototype.toJSON = function ( meta ) {
 
 		if ( this.alphaTest > 0 ) data.alphaTest = this.alphaTest;
 		if ( this.premultipliedAlpha === true ) data.premultipliedAlpha = this.premultipliedAlpha;
-		
+
 		if ( this.morphTargets === true ) data.morphTargets = true;
 		if ( this.skinning === true ) data.skinning = true;
 
@@ -170,7 +170,7 @@ NodeMaterial.prototype.toJSON = function ( meta ) {
 
 		data.fog = this.fog;
 		data.lights = this.lights;
-		
+
 		data.vertex = this.vertex.toJSON( meta ).uuid;
 		data.fragment = this.fragment.toJSON( meta ).uuid;
 

+ 14 - 14
examples/js/nodes/materials/PhongNodeMaterial.js

@@ -14,25 +14,25 @@ function PhongNodeMaterial() {
 
 	this.type = "PhongNodeMaterial";
 
-};
+}
 
 PhongNodeMaterial.prototype = Object.create( NodeMaterial.prototype );
 PhongNodeMaterial.prototype.constructor = PhongNodeMaterial;
 
-NodeUtils.addShortcuts( PhongNodeMaterial.prototype, 'fragment', [ 
-	'color', 
-	'alpha', 
-	'specular', 
-	'shininess', 
-	'normal', 
-	'emissive', 
-	'ambient', 
-	'light', 
-	'shadow', 
-	'ao', 
-	'environment', 
+NodeUtils.addShortcuts( PhongNodeMaterial.prototype, 'fragment', [
+	'color',
+	'alpha',
+	'specular',
+	'shininess',
+	'normal',
+	'emissive',
+	'ambient',
+	'light',
+	'shadow',
+	'ao',
+	'environment',
 	'environmentAlpha',
-	'position' 
+	'position'
 ] );
 
 export { PhongNodeMaterial };

+ 6 - 6
examples/js/nodes/materials/SpriteNodeMaterial.js

@@ -14,16 +14,16 @@ function SpriteNodeMaterial() {
 
 	this.type = "SpriteNodeMaterial";
 
-};
+}
 
 SpriteNodeMaterial.prototype = Object.create( NodeMaterial.prototype );
 SpriteNodeMaterial.prototype.constructor = SpriteNodeMaterial;
 
-NodeUtils.addShortcuts( SpriteNodeMaterial.prototype, 'fragment', [ 
-	'color', 
-	'alpha', 
-	'position', 
-	'spherical' 
+NodeUtils.addShortcuts( SpriteNodeMaterial.prototype, 'fragment', [
+	'color',
+	'alpha',
+	'position',
+	'spherical'
 ] );
 
 export { SpriteNodeMaterial };

+ 17 - 17
examples/js/nodes/materials/StandardNodeMaterial.js

@@ -14,27 +14,27 @@ function StandardNodeMaterial() {
 
 	this.type = "StandardNodeMaterial";
 
-};
+}
 
 StandardNodeMaterial.prototype = Object.create( NodeMaterial.prototype );
 StandardNodeMaterial.prototype.constructor = StandardNodeMaterial;
 
-NodeUtils.addShortcuts( StandardNodeMaterial.prototype, 'fragment', [ 
-	'color', 
-	'alpha', 
-	'roughness', 
-	'metalness', 
-	'reflectivity', 
-	'clearCoat', 
-	'clearCoatRoughness', 
-	'normal', 
-	'emissive', 
-	'ambient', 
-	'light', 
-	'shadow', 
-	'ao', 
-	'environment', 
-	'position' 
+NodeUtils.addShortcuts( StandardNodeMaterial.prototype, 'fragment', [
+	'color',
+	'alpha',
+	'roughness',
+	'metalness',
+	'reflectivity',
+	'clearCoat',
+	'clearCoatRoughness',
+	'normal',
+	'emissive',
+	'ambient',
+	'light',
+	'shadow',
+	'ao',
+	'environment',
+	'position'
 ] );
 
 export { StandardNodeMaterial };

+ 22 - 22
examples/js/nodes/materials/nodes/MeshStandardNode.js

@@ -18,7 +18,7 @@ function MeshStandardNode() {
 		metalness: 0.5,
 		normalScale: new THREE.Vector2( 1, 1 )
 	};
-	
+
 	this.inputs = {
 		color: new PropertyNode( this.properties, 'color', 'c' ),
 		roughness: new PropertyNode( this.properties, 'roughness', 'f' ),
@@ -26,7 +26,7 @@ function MeshStandardNode() {
 		normalScale: new PropertyNode( this.properties, 'normalScale', 'v2' )
 	};
 
-};
+}
 
 MeshStandardNode.prototype = Object.create( StandardNode.prototype );
 MeshStandardNode.prototype.constructor = MeshStandardNode;
@@ -37,57 +37,57 @@ MeshStandardNode.prototype.build = function ( builder ) {
 	var props = this.properties,
 		inputs = this.inputs;
 
-	if ( builder.isShader('fragment') ) {
-		
+	if ( builder.isShader( 'fragment' ) ) {
+
 		// slots
 		// * color
 		// * map
-		
+
 		var color = builder.findNode( props.color, inputs.color ),
 			map = builder.resolve( props.map );
-		
+
 		this.color = map ? new OperatorNode( color, map, OperatorNode.MUL ) : color;
-		
+
 		// slots
 		// * roughness
 		// * roughnessMap
-		
+
 		var roughness = builder.findNode( props.roughness, inputs.roughness ),
 			roughnessMap = builder.resolve( props.roughnessMap );
-		
+
 		this.roughness = roughnessMap ? new OperatorNode( roughness, new SwitchNode( roughnessMap, "g" ), OperatorNode.MUL ) : roughness;
-		
+
 		// slots
 		// * metalness
 		// * metalnessMap
-		
+
 		var metalness = builder.findNode( props.metalness, inputs.metalness ),
 			metalnessMap = builder.resolve( props.metalnessMap );
-		
+
 		this.metalness = metalnessMap ? new OperatorNode( metalness, new SwitchNode( metalnessMap, "b" ), OperatorNode.MUL ) : metalness;
 
 		// slots
 		// * normalMap
 		// * normalScale
-		
+
 		if ( props.normalMap ) {
-			
+
 			this.normal = new NormalMapNode( builder.resolve( props.normalMap ) );
 			this.normal.scale = builder.findNode( props.normalScale, inputs.normalScale );
 
 		} else {
-			
+
 			this.normal = undefined;
-			
+
 		}
 
 		// slots
 		// * envMap
-		
+
 		this.environment = builder.resolve( props.envMap );
-		
+
 	}
-	
+
 	// build code
 
 	return StandardNode.prototype.build.call( this, builder );
@@ -101,9 +101,9 @@ MeshStandardNode.prototype.toJSON = function ( meta ) {
 	if ( ! data ) {
 
 		data = this.createJSONNode( meta );
-		
-		console.warn(".toJSON not implemented in", this);
-		
+
+		console.warn( ".toJSON not implemented in", this );
+
 	}
 
 	return data;

+ 15 - 15
examples/js/nodes/materials/nodes/PhongNode.js

@@ -5,7 +5,7 @@
 import { Node } from '../../core/Node.js';
 import { ColorNode } from '../../inputs/ColorNode.js';
 import { FloatNode } from '../../inputs/FloatNode.js';
- 
+
 function PhongNode() {
 
 	Node.call( this );
@@ -14,7 +14,7 @@ function PhongNode() {
 	this.specular = new ColorNode( 0x111111 );
 	this.shininess = new FloatNode( 30 );
 
-};
+}
 
 PhongNode.prototype = Object.create( Node.prototype );
 PhongNode.prototype.constructor = PhongNode;
@@ -181,9 +181,9 @@ PhongNode.prototype.build = function ( builder ) {
 			output.push(
 				alpha.code,
 				'#ifdef ALPHATEST',
-				
-					'if ( ' + alpha.result + ' <= ALPHATEST ) discard;',
-					
+
+				'if ( ' + alpha.result + ' <= ALPHATEST ) discard;',
+
 				'#endif'
 			);
 
@@ -195,7 +195,7 @@ PhongNode.prototype.build = function ( builder ) {
 				normal.code,
 				'normal = ' + normal.result + ';'
 			);
-		
+
 		}
 
 		// optimization for now
@@ -285,19 +285,19 @@ PhongNode.prototype.build = function ( builder ) {
 			}
 
 		}
-/*
+		/*
 		switch( builder.material.combine ) {
 
 			case THREE.ENVMAP_BLENDING_MULTIPLY:
-				
+
 				//output.push( "vec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + reflectedLight.directSpecular + reflectedLight.indirectSpecular;" );
 				//outgoingLight = mix( outgoingLight, outgoingLight * envColor.xyz, specularStrength * reflectivity );
-				
+
 				break;
-			
-			
+
+
 		}
-	*/	
+	*/
 		if ( alpha ) {
 
 			output.push( "gl_FragColor = vec4( outgoingLight, " + alpha.result + " );" );
@@ -324,9 +324,9 @@ PhongNode.prototype.build = function ( builder ) {
 };
 
 PhongNode.prototype.copy = function ( source ) {
-			
+
 	Node.prototype.copy.call( this, source );
-	
+
 	// vertex
 
 	if ( source.position ) this.position = source.position;
@@ -345,7 +345,7 @@ PhongNode.prototype.copy = function ( source ) {
 	if ( source.shadow ) this.shadow = source.shadow;
 
 	if ( source.ao ) this.ao = source.ao;
-	
+
 	if ( source.emissive ) this.emissive = source.emissive;
 	if ( source.ambient ) this.ambient = source.ambient;
 

+ 4 - 4
examples/js/nodes/materials/nodes/RawNode.js

@@ -10,7 +10,7 @@ function RawNode( value ) {
 
 	this.value = value;
 
-};
+}
 
 RawNode.prototype = Object.create( Node.prototype );
 RawNode.prototype.constructor = RawNode;
@@ -36,11 +36,11 @@ RawNode.prototype.generate = function ( builder ) {
 };
 
 RawNode.prototype.copy = function ( source ) {
-	
+
 	Node.prototype.copy.call( this, source );
-	
+
 	this.value = source.value;
-	
+
 };
 
 RawNode.prototype.toJSON = function ( meta ) {

+ 21 - 21
examples/js/nodes/materials/nodes/SpriteNode.js

@@ -12,7 +12,7 @@ function SpriteNode() {
 	this.color = new ColorNode( 0xEEEEEE );
 	this.spherical = true;
 
-};
+}
 
 SpriteNode.prototype = Object.create( Node.prototype );
 SpriteNode.prototype.constructor = SpriteNode;
@@ -45,7 +45,7 @@ SpriteNode.prototype.build = function ( builder ) {
 			"#include <clipping_planes_fragment>",
 			"#include <begin_vertex>"
 		];
-		
+
 		if ( position ) {
 
 			output.push(
@@ -54,7 +54,7 @@ SpriteNode.prototype.build = function ( builder ) {
 			);
 
 		}
-		
+
 		output.push(
 			"#include <project_vertex>",
 			"#include <fog_vertex>",
@@ -83,7 +83,7 @@ SpriteNode.prototype.build = function ( builder ) {
 			'modelViewMtx[0][1] = 0.0;',
 			'modelViewMtx[0][2] = 0.0;'
 		);
-		
+
 		if ( this.spherical ) {
 
 			output.push(
@@ -94,7 +94,7 @@ SpriteNode.prototype.build = function ( builder ) {
 			);
 
 		}
-		
+
 		output.push(
 			// Thrid colunm.
 			'modelViewMtx[2][0] = 0.0;',
@@ -102,7 +102,7 @@ SpriteNode.prototype.build = function ( builder ) {
 			'modelViewMtx[2][2] = 1.0;',
 
 			"gl_Position = projectionMatrix * modelViewMtx * modelMtx * vec4( transformed, 1.0 );",
-			
+
 			"#include <logdepthbuf_vertex>",
 			"#include <clipping_planes_vertex>",
 			"#include <fog_vertex>"
@@ -120,11 +120,11 @@ SpriteNode.prototype.build = function ( builder ) {
 			"#include <clipping_planes_fragment>",
 			"#include <logdepthbuf_fragment>"
 		].join( "\n" ) );
-		
+
 		// parse all nodes to reuse generate codes
 
 		if ( this.alpha ) this.alpha.parse( builder );
-		
+
 		this.color.parse( builder, { slot: 'color' } );
 
 		// build code
@@ -137,9 +137,9 @@ SpriteNode.prototype.build = function ( builder ) {
 			output = [
 				alpha.code,
 				'#ifdef ALPHATEST',
-				
-					'if ( ' + alpha.result + ' <= ALPHATEST ) discard;',
-					
+
+				'if ( ' + alpha.result + ' <= ALPHATEST ) discard;',
+
 				'#endif',
 				color.code,
 				"gl_FragColor = vec4( " + color.result + ", " + alpha.result + " );"
@@ -154,10 +154,10 @@ SpriteNode.prototype.build = function ( builder ) {
 
 		}
 
-		output.push( 
+		output.push(
 			"#include <tonemapping_fragment>",
 			"#include <encodings_fragment>",
-			"#include <fog_fragment>" 
+			"#include <fog_fragment>"
 		);
 
 	}
@@ -167,19 +167,19 @@ SpriteNode.prototype.build = function ( builder ) {
 };
 
 SpriteNode.prototype.copy = function ( source ) {
-			
+
 	Node.prototype.copy.call( this, source );
-	
+
 	// vertex
-	
+
 	if ( source.position ) this.position = source.position;
-	
+
 	// fragment
-	
+
 	this.color = source.color;
-	
+
 	if ( source.spherical !== undefined ) this.spherical = source.spherical;
-	
+
 	if ( source.alpha ) this.alpha = source.alpha;
 
 };
@@ -199,7 +199,7 @@ SpriteNode.prototype.toJSON = function ( meta ) {
 		// fragment
 
 		data.color = this.color.toJSON( meta ).uuid;
-		
+
 		if ( this.spherical === false ) data.spherical = false;
 
 		if ( this.alpha ) data.alpha = this.alpha.toJSON( meta ).uuid;

+ 12 - 12
examples/js/nodes/materials/nodes/StandardNode.js

@@ -6,7 +6,7 @@ import { Node } from '../../core/Node.js';
 import { ColorNode } from '../../inputs/ColorNode.js';
 import { FloatNode } from '../../inputs/FloatNode.js';
 import { RoughnessToBlinnExponentNode } from '../../bsdfs/RoughnessToBlinnExponentNode.js';
- 
+
 function StandardNode() {
 
 	Node.call( this );
@@ -15,7 +15,7 @@ function StandardNode() {
 	this.roughness = new FloatNode( 0.5 );
 	this.metalness = new FloatNode( 0.5 );
 
-};
+}
 
 StandardNode.prototype = Object.create( Node.prototype );
 StandardNode.prototype.constructor = StandardNode;
@@ -191,7 +191,7 @@ StandardNode.prototype.build = function ( builder ) {
 
 		var output = [
 			"#include <clipping_planes_fragment>",
-		
+
 			// add before: prevent undeclared normal
 			"	#include <normal_fragment_begin>",
 
@@ -217,9 +217,9 @@ StandardNode.prototype.build = function ( builder ) {
 			output.push(
 				alpha.code,
 				'#ifdef ALPHATEST',
-				
-					'if ( ' + alpha.result + ' <= ALPHATEST ) discard;',
-					
+
+				'if ( ' + alpha.result + ' <= ALPHATEST ) discard;',
+
 				'#endif'
 			);
 
@@ -231,7 +231,7 @@ StandardNode.prototype.build = function ( builder ) {
 				normal.code,
 				'normal = ' + normal.result + ';'
 			);
-		
+
 		}
 
 		// optimization for now
@@ -359,7 +359,7 @@ StandardNode.prototype.build = function ( builder ) {
 			output.push( "radiance += " + environment.result + ";" );
 
 		}
-		
+
 		output.push(
 			"#include <lights_fragment_end>"
 		);
@@ -393,9 +393,9 @@ StandardNode.prototype.build = function ( builder ) {
 };
 
 StandardNode.prototype.copy = function ( source ) {
-			
+
 	Node.prototype.copy.call( this, source );
-	
+
 	// vertex
 
 	if ( source.position ) this.position = source.position;
@@ -419,7 +419,7 @@ StandardNode.prototype.copy = function ( source ) {
 	if ( source.shadow ) this.shadow = source.shadow;
 
 	if ( source.ao ) this.ao = source.ao;
-	
+
 	if ( source.emissive ) this.emissive = source.emissive;
 	if ( source.ambient ) this.ambient = source.ambient;
 
@@ -458,7 +458,7 @@ StandardNode.prototype.toJSON = function ( meta ) {
 		if ( this.shadow ) data.shadow = this.shadow.toJSON( meta ).uuid;
 
 		if ( this.ao ) data.ao = this.ao.toJSON( meta ).uuid;
-		
+
 		if ( this.emissive ) data.emissive = this.emissive.toJSON( meta ).uuid;
 		if ( this.ambient ) data.ambient = this.ambient.toJSON( meta ).uuid;
 

+ 11 - 11
examples/js/nodes/math/CondNode.js

@@ -1,7 +1,7 @@
 /**
  * @author sunag / http://www.sunag.com.br/
  */
- 
+
 import { TempNode } from '../core/TempNode.js';
 
 function CondNode( a, b, ifNode, elseNode, op ) {
@@ -10,13 +10,13 @@ function CondNode( a, b, ifNode, elseNode, op ) {
 
 	this.a = a;
 	this.b = b;
-	
+
 	this.ifNode = ifNode;
 	this.elseNode = elseNode;
 
 	this.op = op;
 
-};
+}
 
 CondNode.EQUAL = '==';
 CondNode.NOT_EQUAL = '!=';
@@ -61,25 +61,25 @@ CondNode.prototype.generate = function ( builder, output ) {
 		b = this.b.build( builder, condType ),
 		ifNode = this.ifNode.build( builder, type ),
 		elseNode = this.elseNode.build( builder, type );
-	
-	var code = '( ' + [ a, this.op, b, '?', ifNode, ':', elseNode ].join(' ') + ' )';
+
+	var code = '( ' + [ a, this.op, b, '?', ifNode, ':', elseNode ].join( ' ' ) + ' )';
 
 	return builder.format( code, this.getType( builder ), output );
 
 };
 
 CondNode.prototype.copy = function ( source ) {
-			
+
 	TempNode.prototype.copy.call( this, source );
-	
+
 	this.a = source.a;
 	this.b = source.b;
-	
+
 	this.ifNode = source.ifNode;
 	this.elseNode = source.elseNode;
-	
+
 	this.op = source.op;
-	
+
 };
 
 CondNode.prototype.toJSON = function ( meta ) {
@@ -92,7 +92,7 @@ CondNode.prototype.toJSON = function ( meta ) {
 
 		data.a = this.a.toJSON( meta ).uuid;
 		data.b = this.b.toJSON( meta ).uuid;
-		
+
 		data.ifNode = this.ifNode.toJSON( meta ).uuid;
 		data.elseNode = this.elseNode.toJSON( meta ).uuid;
 

+ 11 - 11
examples/js/nodes/math/Math1Node.js

@@ -12,7 +12,7 @@ function Math1Node( a, method ) {
 
 	this.method = method;
 
-};
+}
 
 Math1Node.RAD = 'radians';
 Math1Node.DEG = 'degrees';
@@ -48,7 +48,7 @@ Math1Node.prototype.getType = function ( builder ) {
 	switch ( this.method ) {
 
 		case Math1Node.LENGTH:
-		
+
 			return 'f';
 
 	}
@@ -65,21 +65,21 @@ Math1Node.prototype.generate = function ( builder, output ) {
 	switch ( this.method ) {
 
 		case Math1Node.NEGATE:
-		
+
 			result = '( -' + result + ' )';
-			
+
 			break;
 
 		case Math1Node.INVERT:
-		
+
 			result = '( 1.0 - ' + result + ' )';
-			
+
 			break;
 
 		default:
-		
+
 			result = this.method + '( ' + result + ' )';
-			
+
 			break;
 
 	}
@@ -89,12 +89,12 @@ Math1Node.prototype.generate = function ( builder, output ) {
 };
 
 Math1Node.prototype.copy = function ( source ) {
-			
+
 	TempNode.prototype.copy.call( this, source );
-	
+
 	this.a = source.a;
 	this.method = source.method;
-	
+
 };
 
 Math1Node.prototype.toJSON = function ( meta ) {

+ 18 - 18
examples/js/nodes/math/Math2Node.js

@@ -1,7 +1,7 @@
 /**
  * @author sunag / http://www.sunag.com.br/
  */
- 
+
 import { TempNode } from '../core/TempNode.js';
 
 function Math2Node( a, b, method ) {
@@ -13,7 +13,7 @@ function Math2Node( a, b, method ) {
 
 	this.method = method;
 
-};
+}
 
 Math2Node.MIN = 'min';
 Math2Node.MAX = 'max';
@@ -32,7 +32,7 @@ Math2Node.prototype.nodeType = "Math2";
 Math2Node.prototype.getInputType = function ( builder ) {
 
 	// use the greater length vector
-	
+
 	if ( builder.getTypeLength( this.b.getType( builder ) ) > builder.getTypeLength( this.a.getType( builder ) ) ) {
 
 		return this.b.getType( builder );
@@ -49,11 +49,11 @@ Math2Node.prototype.getType = function ( builder ) {
 
 		case Math2Node.DISTANCE:
 		case Math2Node.DOT:
-		
+
 			return 'f';
 
 		case Math2Node.CROSS:
-		
+
 			return 'v3';
 
 	}
@@ -64,43 +64,43 @@ Math2Node.prototype.getType = function ( builder ) {
 
 Math2Node.prototype.generate = function ( builder, output ) {
 
-	var a, b, 
+	var a, b,
 		type = this.getInputType( builder ),
 		al = builder.getTypeLength( this.a.getType( builder ) ),
 		bl = builder.getTypeLength( this.b.getType( builder ) );
-		
+
 	// optimzer
 
 	switch ( this.method ) {
 
 		case Math2Node.CROSS:
-		
+
 			a = this.a.build( builder, 'v3' );
 			b = this.b.build( builder, 'v3' );
-			
+
 			break;
 
 		case Math2Node.STEP:
-		
+
 			a = this.a.build( builder, al === 1 ? 'f' : type );
 			b = this.b.build( builder, type );
-			
+
 			break;
 
 		case Math2Node.MIN:
 		case Math2Node.MAX:
 		case Math2Node.MOD:
-		
+
 			a = this.a.build( builder, type );
 			b = this.b.build( builder, bl === 1 ? 'f' : type );
-			
+
 			break;
 
 		default:
-		
+
 			a = this.a.build( builder, type );
 			b = this.b.build( builder, type );
-			
+
 			break;
 
 	}
@@ -110,13 +110,13 @@ Math2Node.prototype.generate = function ( builder, output ) {
 };
 
 Math2Node.prototype.copy = function ( source ) {
-			
+
 	TempNode.prototype.copy.call( this, source );
-	
+
 	this.a = source.a;
 	this.b = source.b;
 	this.method = source.method;
-	
+
 };
 
 Math2Node.prototype.toJSON = function ( meta ) {

+ 15 - 15
examples/js/nodes/math/Math3Node.js

@@ -1,7 +1,7 @@
 /**
  * @author sunag / http://www.sunag.com.br/
  */
- 
+
 import { TempNode } from '../core/TempNode.js';
 
 function Math3Node( a, b, c, method ) {
@@ -14,7 +14,7 @@ function Math3Node( a, b, c, method ) {
 
 	this.method = method;
 
-};
+}
 
 Math3Node.MIX = 'mix';
 Math3Node.REFRACT = 'refract';
@@ -32,13 +32,13 @@ Math3Node.prototype.getType = function ( builder ) {
 	var c = builder.getTypeLength( this.c.getType( builder ) );
 
 	if ( a > b && a > c ) {
-		
+
 		return this.a.getType( builder );
-		
+
 	} else if ( b > c ) {
-		
+
 		return this.b.getType( builder );
-		
+
 	}
 
 	return this.c.getType( builder );
@@ -58,27 +58,27 @@ Math3Node.prototype.generate = function ( builder, output ) {
 	switch ( this.method ) {
 
 		case Math3Node.REFRACT:
-		
+
 			a = this.a.build( builder, type );
 			b = this.b.build( builder, type );
 			c = this.c.build( builder, 'f' );
-			
+
 			break;
 
 		case Math3Node.MIX:
-		
+
 			a = this.a.build( builder, type );
 			b = this.b.build( builder, type );
 			c = this.c.build( builder, cl === 1 ? 'f' : type );
-			
+
 			break;
 
 		default:
-		
+
 			a = this.a.build( builder, type );
 			b = this.b.build( builder, type );
 			c = this.c.build( builder, type );
-			
+
 			break;
 
 	}
@@ -88,14 +88,14 @@ Math3Node.prototype.generate = function ( builder, output ) {
 };
 
 Math3Node.prototype.copy = function ( source ) {
-			
+
 	TempNode.prototype.copy.call( this, source );
-	
+
 	this.a = source.a;
 	this.b = source.b;
 	this.c = source.c;
 	this.method = source.method;
-	
+
 };
 
 Math3Node.prototype.toJSON = function ( meta ) {

+ 6 - 6
examples/js/nodes/math/OperatorNode.js

@@ -3,7 +3,7 @@
  */
 
 import { TempNode } from '../core/TempNode.js';
- 
+
 function OperatorNode( a, b, op ) {
 
 	TempNode.call( this );
@@ -12,7 +12,7 @@ function OperatorNode( a, b, op ) {
 	this.b = b;
 	this.op = op;
 
-};
+}
 
 OperatorNode.ADD = '+';
 OperatorNode.SUB = '-';
@@ -52,18 +52,18 @@ OperatorNode.prototype.generate = function ( builder, output ) {
 	var a = this.a.build( builder, type ),
 		b = this.b.build( builder, type );
 
-	return builder.format( '( ' + a + ' ' +  this.op + ' '+ b + ' )', type, output );
+	return builder.format( '( ' + a + ' ' + this.op + ' ' + b + ' )', type, output );
 
 };
 
 OperatorNode.prototype.copy = function ( source ) {
-			
+
 	TempNode.prototype.copy.call( this, source );
-	
+
 	this.a = source.a;
 	this.b = source.b;
 	this.op = source.op;
-	
+
 };
 
 OperatorNode.prototype.toJSON = function ( meta ) {

+ 31 - 31
examples/js/nodes/misc/BumpMapNode.js

@@ -16,31 +16,31 @@ function BumpMapNode( value, scale ) {
 	this.scale = scale || new FloatNode( 1 );
 
 	this.toNormalMap = false;
-	
-};
 
-BumpMapNode.Nodes = (function() {
-	
+}
+
+BumpMapNode.Nodes = ( function () {
+
 	var dHdxy_fwd = new FunctionNode( [
 
 		// Bump Mapping Unparametrized Surfaces on the GPU by Morten S. Mikkelsen
 		// http://api.unrealengine.com/attachments/Engine/Rendering/LightingAndShadows/BumpMappingWithoutTangentSpace/mm_sfgrad_bump.pdf
-		
+
 		// Evaluate the derivative of the height w.r.t. screen-space using forward differencing (listing 2)
 
 		"vec2 dHdxy_fwd( sampler2D bumpMap, vec2 vUv, float bumpScale ) {",
 
 		// Workaround for Adreno 3XX dFd*( vec3 ) bug. See #9988
-		
+
 		"	vec2 dSTdx = dFdx( vUv );",
 		"	vec2 dSTdy = dFdy( vUv );",
-		
+
 		"	float Hll = bumpScale * texture2D( bumpMap, vUv ).x;",
 		"	float dBx = bumpScale * texture2D( bumpMap, vUv + dSTdx ).x - Hll;",
 		"	float dBy = bumpScale * texture2D( bumpMap, vUv + dSTdy ).x - Hll;",
-		
+
 		"	return vec2( dBx, dBy );",
-		
+
 		"}"
 
 	].join( "\n" ), null, { derivatives: true } );
@@ -50,20 +50,20 @@ BumpMapNode.Nodes = (function() {
 		"vec3 perturbNormalArb( vec3 surf_pos, vec3 surf_norm, vec2 dHdxy ) {",
 
 		// Workaround for Adreno 3XX dFd*( vec3 ) bug. See #9988
-		
+
 		"	vec3 vSigmaX = vec3( dFdx( surf_pos.x ), dFdx( surf_pos.y ), dFdx( surf_pos.z ) );",
 		"	vec3 vSigmaY = vec3( dFdy( surf_pos.x ), dFdy( surf_pos.y ), dFdy( surf_pos.z ) );",
 		"	vec3 vN = surf_norm;", // normalized
-		
+
 		"	vec3 R1 = cross( vSigmaY, vN );",
 		"	vec3 R2 = cross( vN, vSigmaX );",
 
 		"	float fDet = dot( vSigmaX, R1 );",
-		
+
 		"	fDet *= ( float( gl_FrontFacing ) * 2.0 - 1.0 );",
-		
+
 		"	vec3 vGrad = sign( fDet ) * ( dHdxy.x * R1 + dHdxy.y * R2 );",
-		
+
 		"	return normalize( abs( fDet ) * surf_norm - vGrad );",
 
 		"}"
@@ -72,26 +72,26 @@ BumpMapNode.Nodes = (function() {
 
 	var bumpToNormal = new FunctionNode( [
 		"vec3 bumpToNormal( sampler2D bumpMap, vec2 uv, float scale ) {",
-		
+
 		"	vec2 dSTdx = dFdx( uv );",
 		"	vec2 dSTdy = dFdy( uv );",
-		
+
 		"	float Hll = texture2D( bumpMap, uv ).x;",
 		"	float dBx = texture2D( bumpMap, uv + dSTdx ).x - Hll;",
 		"	float dBy = texture2D( bumpMap, uv + dSTdy ).x - Hll;",
-		
+
 		"	return vec3( .5 - ( dBx * scale ), .5 - ( dBy * scale ), 1.0 );",
-		
+
 		"}"
 	].join( "\n" ), null, { derivatives: true } );
-	
+
 	return {
 		dHdxy_fwd: dHdxy_fwd,
 		perturbNormalArb: perturbNormalArb,
 		bumpToNormal: bumpToNormal
 	};
-	
-})();
+
+} )();
 
 BumpMapNode.prototype = Object.create( TempNode.prototype );
 BumpMapNode.prototype.constructor = BumpMapNode;
@@ -102,21 +102,21 @@ BumpMapNode.prototype.generate = function ( builder, output ) {
 	if ( builder.isShader( 'fragment' ) ) {
 
 		if ( this.toNormalMap ) {
-	
+
 			var bumpToNormal = builder.include( BumpMapNode.Nodes.bumpToNormal );
-		
+
 			return builder.format( bumpToNormal + '( ' + this.value.build( builder, 'sampler2D' ) + ', ' +
 				this.value.uv.build( builder, 'v2' ) + ', ' +
 				this.scale.build( builder, 'f' ) + ' )', this.getType( builder ), output );
-				
+
 		} else {
-			
+
 			var derivativeHeight = builder.include( BumpMapNode.Nodes.dHdxy_fwd ),
 				perturbNormalArb = builder.include( BumpMapNode.Nodes.perturbNormalArb );
-		
+
 			this.normal = this.normal || new NormalNode( NormalNode.VIEW );
 			this.position = this.position || new PositionNode( PositionNode.VIEW );
-		
+
 			var derivativeHeightCode = derivativeHeight + '( ' + this.value.build( builder, 'sampler2D' ) + ', ' +
 				this.value.uv.build( builder, 'v2' ) + ', ' +
 				this.scale.build( builder, 'f' ) + ' )';
@@ -124,7 +124,7 @@ BumpMapNode.prototype.generate = function ( builder, output ) {
 			return builder.format( perturbNormalArb + '( -' + this.position.build( builder, 'v3' ) + ', ' +
 				this.normal.build( builder, 'v3' ) + ', ' +
 				derivativeHeightCode + ' )', this.getType( builder ), output );
-			
+
 		}
 
 	} else {
@@ -138,12 +138,12 @@ BumpMapNode.prototype.generate = function ( builder, output ) {
 };
 
 BumpMapNode.prototype.copy = function ( source ) {
-			
+
 	TempNode.prototype.copy.call( this, source );
-	
+
 	this.value = source.value;
 	this.scale = source.scale;
-					
+
 };
 
 BumpMapNode.prototype.toJSON = function ( meta ) {

+ 14 - 14
examples/js/nodes/misc/NormalMapNode.js

@@ -16,10 +16,10 @@ function NormalMapNode( value, scale ) {
 	this.value = value;
 	this.scale = scale || new Vector2Node( 1, 1 );
 
-};
+}
+
+NormalMapNode.Nodes = ( function () {
 
-NormalMapNode.Nodes = (function() {
-	
 	var perturbNormal2Arb = new FunctionNode( [
 
 		// Per-Pixel Tangent Space Normal Mapping
@@ -28,24 +28,24 @@ NormalMapNode.Nodes = (function() {
 		"vec3 perturbNormal2Arb( vec3 eye_pos, vec3 surf_norm, vec3 map, vec2 mUv, vec2 normalScale ) {",
 
 		// Workaround for Adreno 3XX dFd*( vec3 ) bug. See #9988
-		
+
 		"	vec3 q0 = vec3( dFdx( eye_pos.x ), dFdx( eye_pos.y ), dFdx( eye_pos.z ) );",
 		"	vec3 q1 = vec3( dFdy( eye_pos.x ), dFdy( eye_pos.y ), dFdy( eye_pos.z ) );",
 		"	vec2 st0 = dFdx( mUv.st );",
 		"	vec2 st1 = dFdy( mUv.st );",
-		
+
 		"	float scale = sign( st1.t * st0.s - st0.t * st1.s );", // we do not care about the magnitude
-		
+
 		"	vec3 S = normalize( ( q0 * st1.t - q1 * st0.t ) * scale );",
 		"	vec3 T = normalize( ( - q0 * st1.s + q1 * st0.s ) * scale );",
 		"	vec3 N = normalize( surf_norm );",
 		"	mat3 tsn = mat3( S, T, N );",
-		
+
 		"	vec3 mapN = map * 2.0 - 1.0;",
-		
+
 		"	mapN.xy *= normalScale;",
 		"	mapN.xy *= ( float( gl_FrontFacing ) * 2.0 - 1.0 );",
-		
+
 		"	return normalize( tsn * mapN );",
 
 		"}"
@@ -55,8 +55,8 @@ NormalMapNode.Nodes = (function() {
 	return {
 		perturbNormal2Arb: perturbNormal2Arb
 	};
-	
-})();
+
+} )();
 
 NormalMapNode.prototype = Object.create( TempNode.prototype );
 NormalMapNode.prototype.constructor = NormalMapNode;
@@ -89,12 +89,12 @@ NormalMapNode.prototype.generate = function ( builder, output ) {
 };
 
 NormalMapNode.prototype.copy = function ( source ) {
-			
+
 	TempNode.prototype.copy.call( this, source );
-	
+
 	this.value = source.value;
 	this.scale = source.scale;
-	
+
 };
 
 NormalMapNode.prototype.toJSON = function ( meta ) {

+ 4 - 4
examples/js/nodes/misc/TextureCubeNode.js

@@ -4,7 +4,7 @@
 
 import { TempNode } from '../core/TempNode.js';
 import { TextureCubeUVNode } from './TextureCubeUVNode.js';
- 
+
 function TextureCubeNode( value, uv ) {
 
 	TempNode.call( this, 'v4' );
@@ -12,7 +12,7 @@ function TextureCubeNode( value, uv ) {
 	this.value = value;
 	this.uv = uv || new TextureCubeUVNode();
 
-};
+}
 
 TextureCubeNode.prototype = Object.create( TempNode.prototype );
 TextureCubeNode.prototype.constructor = TextureCubeNode;
@@ -25,12 +25,12 @@ TextureCubeNode.prototype.generate = function ( builder, output ) {
 		var uv_10 = this.uv.build( builder ) + '.uv_10',
 			uv_20 = this.uv.build( builder ) + '.uv_20',
 			t = this.uv.build( builder ) + '.t';
-		
+
 		var color10 = builder.getTexelDecodingFunctionFromTexture( 'texture2D( ' + this.value.build( builder, 'sampler2D' ) + ', ' + uv_10 + ' )', this.value.value ),
 			color20 = builder.getTexelDecodingFunctionFromTexture( 'texture2D( ' + this.value.build( builder, 'sampler2D' ) + ', ' + uv_20 + ' )', this.value.value );
 
 		return builder.format( 'vec4( mix( ' + color10 + ', ' + color20 + ', ' + t + ' ).rgb, 1.0 )', this.getType( builder ), output );
-			
+
 	} else {
 
 		console.warn( "THREE.TextureCubeNode is not compatible with " + builder.shader + " shader." );

+ 26 - 26
examples/js/nodes/misc/TextureCubeUVNode.js

@@ -9,27 +9,27 @@ import { FunctionNode } from '../core/FunctionNode.js';
 import { ReflectNode } from '../accessors/ReflectNode.js';
 import { FloatNode } from '../inputs/FloatNode.js';
 import { BlinnExponentToRoughnessNode } from '../bsdfs/BlinnExponentToRoughnessNode.js';
- 
+
 function TextureCubeUVNode( uv, textureSize, blinnExponentToRoughness ) {
 
 	TempNode.call( this, 'TextureCubeUVData' ); // TextureCubeUVData is type as StructNode
 
 	this.uv = uv || new ReflectNode( ReflectNode.VECTOR );
 	this.textureSize = textureSize || new FloatNode( 1024 );
-	this.blinnExponentToRoughness = this.blinnExponentToRoughness || new BlinnExponentToRoughnessNode();
+	this.blinnExponentToRoughness = blinnExponentToRoughness || new BlinnExponentToRoughnessNode();
 
-};
+}
 
-TextureCubeUVNode.Nodes = (function() {
+TextureCubeUVNode.Nodes = ( function () {
 
-	var TextureCubeUVData = new StructNode([
+	var TextureCubeUVData = new StructNode( [
 		"struct TextureCubeUVData {",
 		"	vec2 uv_10;",
 		"	vec2 uv_20;",
 		"	float t;",
 		"}"
-	].join( "\n" ));
-	
+	].join( "\n" ) );
+
 	var getFaceFromDirection = new FunctionNode( [
 		"int getFaceFromDirection(vec3 direction) {",
 		"	vec3 absDirection = abs(direction);",
@@ -49,10 +49,10 @@ TextureCubeUVNode.Nodes = (function() {
 		"	return face;",
 		"}"
 	].join( "\n" ) );
-	
+
 	var cubeUV_maxLods1 = new ConstNode( "#define cubeUV_maxLods1 ( log2( cubeUV_textureSize * 0.25 ) - 1.0 )" );
 	var cubeUV_rangeClamp = new ConstNode( "#define cubeUV_rangeClamp ( exp2( ( 6.0 - 1.0 ) * 2.0 ) )" );
-	
+
 	var MipLevelInfo = new FunctionNode( [
 		"vec2 MipLevelInfo( vec3 vec, float roughnessLevel, float roughness, in float cubeUV_textureSize ) {",
 		"	float scale = exp2(cubeUV_maxLods1 - roughnessLevel);",
@@ -61,13 +61,13 @@ TextureCubeUVNode.Nodes = (function() {
 		"	vec3 dx = dFdx( vec * scale * dxRoughness );",
 		"	vec3 dy = dFdy( vec * scale * dyRoughness );",
 		"	float d = max( dot( dx, dx ), dot( dy, dy ) );",
-			// Clamp the value to the max mip level counts. hard coded to 6 mips"
+		// Clamp the value to the max mip level counts. hard coded to 6 mips"
 		"	d = clamp(d, 1.0, cubeUV_rangeClamp);",
 		"	float mipLevel = 0.5 * log2(d);",
 		"	return vec2(floor(mipLevel), fract(mipLevel));",
-		"}" 
+		"}"
 	].join( "\n" ), [ cubeUV_maxLods1, cubeUV_rangeClamp ], { derivatives: true } );
-	
+
 	var cubeUV_maxLods2 = new ConstNode( "#define cubeUV_maxLods2 ( log2( cubeUV_textureSize * 0.25 ) - 2.0 )" );
 	var cubeUV_rcpTextureSize = new ConstNode( "#define cubeUV_rcpTextureSize ( 1.0 / cubeUV_textureSize )" );
 
@@ -78,11 +78,11 @@ TextureCubeUVNode.Nodes = (function() {
 		"",
 		"	vec2 exp2_packed = exp2( vec2( roughnessLevel, mipLevel ) );",
 		"	vec2 rcp_exp2_packed = vec2( 1.0 ) / exp2_packed;",
-			// float powScale = exp2(roughnessLevel + mipLevel);"
+		// float powScale = exp2(roughnessLevel + mipLevel);"
 		"	float powScale = exp2_packed.x * exp2_packed.y;",
-			// float scale =  1.0 / exp2(roughnessLevel + 2.0 + mipLevel);"
+		// float scale =  1.0 / exp2(roughnessLevel + 2.0 + mipLevel);"
 		"	float scale = rcp_exp2_packed.x * rcp_exp2_packed.y * 0.25;",
-			// float mipOffset = 0.75*(1.0 - 1.0/exp2(mipLevel))/exp2(roughnessLevel);"
+		// float mipOffset = 0.75*(1.0 - 1.0/exp2(mipLevel))/exp2(roughnessLevel);"
 		"	float mipOffset = 0.75*(1.0 - rcp_exp2_packed.y) * rcp_exp2_packed.x;",
 		"",
 		"	bool bRes = mipLevel == 0.0;",
@@ -129,11 +129,11 @@ TextureCubeUVNode.Nodes = (function() {
 		"	vec2 s = ( r.yz / abs( r.x ) + vec2( 1.0 ) ) * 0.5;",
 		"	vec2 base = offset + vec2( texelOffset );",
 		"	return base + s * ( scale - 2.0 * texelOffset );",
-		"}" 
+		"}"
 	].join( "\n" ), [ cubeUV_maxLods2, cubeUV_rcpTextureSize, getFaceFromDirection ] );
-	
+
 	var cubeUV_maxLods3 = new ConstNode( "#define cubeUV_maxLods3 ( log2( cubeUV_textureSize * 0.25 ) - 3.0 )" );
-	
+
 	var textureCubeUV = new FunctionNode( [
 		"TextureCubeUVData textureCubeUV( vec3 reflectedDirection, float roughness, in float cubeUV_textureSize ) {",
 		"	float roughnessVal = roughness * cubeUV_maxLods3;",
@@ -146,23 +146,23 @@ TextureCubeUVNode.Nodes = (function() {
 		"	float level1 = level0 + 1.0;",
 		"	level1 = level1 > 5.0 ? 5.0 : level1;",
 		"",
-			// round to nearest mipmap if we are not interpolating."
+		// round to nearest mipmap if we are not interpolating."
 		"	level0 += min( floor( s + 0.5 ), 5.0 );",
 		"",
-			// Tri linear interpolation."
+		// Tri linear interpolation."
 		"	vec2 uv_10 = getCubeUV(reflectedDirection, r1, level0, cubeUV_textureSize);",
 		"	vec2 uv_20 = getCubeUV(reflectedDirection, r2, level0, cubeUV_textureSize);",
 		"",
 		"	return TextureCubeUVData(uv_10, uv_20, t);",
-		"}" 
+		"}"
 	].join( "\n" ), [ TextureCubeUVData, cubeUV_maxLods3, MipLevelInfo, getCubeUV ] );
-	
+
 	return {
 		TextureCubeUVData: TextureCubeUVData,
 		textureCubeUV: textureCubeUV
 	};
-	
-})();
+
+} )();
 
 TextureCubeUVNode.prototype = Object.create( TempNode.prototype );
 TextureCubeUVNode.prototype.constructor = TextureCubeUVNode;
@@ -173,11 +173,11 @@ TextureCubeUVNode.prototype.generate = function ( builder, output ) {
 	if ( builder.isShader( 'fragment' ) ) {
 
 		var textureCubeUV = builder.include( TextureCubeUVNode.Nodes.textureCubeUV );
-	
+
 		return builder.format( textureCubeUV + '( ' + this.uv.build( builder, 'v3' ) + ', ' +
 			this.blinnExponentToRoughness.build( builder, 'f' ) + ', ' +
 			this.textureSize.build( builder, 'f' ) + ' )', this.getType( builder ), output );
-			
+
 	} else {
 
 		console.warn( "THREE.TextureCubeUVNode is not compatible with " + builder.shader + " shader." );

+ 3 - 3
examples/js/nodes/postprocessing/NodePass.js

@@ -22,7 +22,7 @@ function NodePass() {
 
 	this.needsUpdate = true;
 
-};
+}
 
 NodePass.prototype = Object.create( THREE.ShaderPass.prototype );
 NodePass.prototype.constructor = NodePass;
@@ -46,9 +46,9 @@ NodePass.prototype.render = function () {
 };
 
 NodePass.prototype.copy = function ( source ) {
-	
+
 	this.input = source.input;
-	
+
 };
 
 NodePass.prototype.toJSON = function ( meta ) {

+ 21 - 21
examples/js/nodes/postprocessing/NodePostProcessing.js

@@ -20,7 +20,7 @@ function NodePostProcessing( renderer, renderTarget ) {
 		renderTarget = new THREE.WebGLRenderTarget( size.width, size.height, parameters );
 
 	}
-	
+
 	this.renderer = renderer;
 	this.renderTarget = renderTarget;
 
@@ -33,17 +33,17 @@ function NodePostProcessing( renderer, renderTarget ) {
 	this.quad = new THREE.Mesh( new THREE.PlaneBufferGeometry( 2, 2 ), this.material );
 	this.quad.frustumCulled = false; // Avoid getting clipped
 	this.scene.add( this.quad );
-	
+
 	this.needsUpdate = true;
 
-};
+}
 
 NodePostProcessing.prototype = {
 
 	constructor: NodePostProcessing,
 
 	render: function ( scene, camera, frame ) {
-		
+
 		if ( this.needsUpdate ) {
 
 			this.material.dispose();
@@ -51,10 +51,10 @@ NodePostProcessing.prototype = {
 			this.material.fragment.value = this.output;
 			this.material.build();
 
-			if (this.material.uniforms.renderTexture) {
-				
+			if ( this.material.uniforms.renderTexture ) {
+
 				this.material.uniforms.renderTexture.value = this.renderTarget.texture;
-				
+
 			}
 
 			this.needsUpdate = false;
@@ -63,31 +63,31 @@ NodePostProcessing.prototype = {
 
 		frame.setRenderer( this.renderer )
 			.setRenderTexture( this.renderTarget.texture );
-		
+
 		this.renderer.render( scene, camera, this.renderTarget );
 
 		frame.updateNode( this.material );
-		
+
 		this.renderer.render( this.scene, this.camera );
-		
+
 	},
-	
+
 	setSize: function ( width, height ) {
-		
+
 		this.renderTarget.setSize( width, height );
-	
+
 		this.renderer.setSize( width, height );
-		
+
 	},
-	
+
 	copy: function ( source ) {
-		
+
 		this.output = source.output;
-		
+
 	},
-	
+
 	toJSON: function ( meta ) {
-		
+
 		var isRootObject = ( meta === undefined || typeof meta === 'string' );
 
 		if ( isRootObject ) {
@@ -120,9 +120,9 @@ NodePostProcessing.prototype = {
 		meta.post = this.uuid;
 
 		return meta;
-		
+
 	}
-	
+
 };
 
 export { NodePostProcessing };

+ 12 - 12
examples/js/nodes/procedural/CheckerNode.js

@@ -12,33 +12,33 @@ function CheckerNode( uv ) {
 
 	this.uv = uv || new UVNode();
 
-};
+}
 
 CheckerNode.prototype = Object.create( TempNode.prototype );
 CheckerNode.prototype.constructor = CheckerNode;
 CheckerNode.prototype.nodeType = "Noise";
 
-CheckerNode.Nodes = (function() {
-	
+CheckerNode.Nodes = ( function () {
+
 	// https://github.com/mattdesl/glsl-checker/blob/master/index.glsl
-	
+
 	var checker = new FunctionNode( [
 		"float checker( vec2 uv ) {",
-		
+
 		"	float cx = floor( uv.x );",
 		"	float cy = floor( uv.y ); ",
 		"	float result = mod( cx + cy, 2.0 );",
 
 		"	return sign( result );",
-		
+
 		"}"
 	].join( "\n" ) );
 
 	return {
 		checker: checker
 	};
-	
-})();
+
+} )();
 
 CheckerNode.prototype.generate = function ( builder, output ) {
 
@@ -49,11 +49,11 @@ CheckerNode.prototype.generate = function ( builder, output ) {
 };
 
 CheckerNode.prototype.copy = function ( source ) {
-			
+
 	TempNode.prototype.copy.call( this, source );
-	
+
 	this.uv = source.uv;
-	
+
 };
 
 CheckerNode.prototype.toJSON = function ( meta ) {
@@ -72,4 +72,4 @@ CheckerNode.prototype.toJSON = function ( meta ) {
 
 };
 
-export { CheckerNode };
+export { CheckerNode };

+ 11 - 11
examples/js/nodes/procedural/NoiseNode.js

@@ -12,27 +12,27 @@ function NoiseNode( uv ) {
 
 	this.uv = uv || new UVNode();
 
-};
+}
 
 NoiseNode.prototype = Object.create( TempNode.prototype );
 NoiseNode.prototype.constructor = NoiseNode;
 NoiseNode.prototype.nodeType = "Noise";
 
-NoiseNode.Nodes = (function() {
-	
+NoiseNode.Nodes = ( function () {
+
 	var snoise = new FunctionNode( [
 		"float snoise(vec2 co) {",
-		
+
 		"	return fract( sin( dot( co.xy, vec2( 12.9898, 78.233 ) ) ) * 43758.5453 );",
-		
+
 		"}"
 	].join( "\n" ) );
 
 	return {
 		snoise: snoise
 	};
-	
-})();
+
+} )();
 
 NoiseNode.prototype.generate = function ( builder, output ) {
 
@@ -43,11 +43,11 @@ NoiseNode.prototype.generate = function ( builder, output ) {
 };
 
 NoiseNode.prototype.copy = function ( source ) {
-			
+
 	TempNode.prototype.copy.call( this, source );
-	
+
 	this.uv = source.uv;
-	
+
 };
 
 NoiseNode.prototype.toJSON = function ( meta ) {
@@ -66,4 +66,4 @@ NoiseNode.prototype.toJSON = function ( meta ) {
 
 };
 
-export { NoiseNode };
+export { NoiseNode };

+ 19 - 19
examples/js/nodes/utils/BypassNode.js

@@ -11,7 +11,7 @@ function BypassNode( code, value ) {
 	this.code = code;
 	this.value = value;
 
-};
+}
 
 BypassNode.prototype = Object.create( Node.prototype );
 BypassNode.prototype.constructor = BypassNode;
@@ -20,15 +20,15 @@ BypassNode.prototype.nodeType = "Bypass";
 BypassNode.prototype.getType = function ( builder ) {
 
 	if ( this.value ) {
-		
+
 		return this.value.getType( builder );
-		
-	} else if (builder.isShader( 'fragment' )) {
-		
+
+	} else if ( builder.isShader( 'fragment' ) ) {
+
 		return 'f';
-		
+
 	}
-	
+
 	return 'void';
 
 };
@@ -38,30 +38,30 @@ BypassNode.prototype.generate = function ( builder, output ) {
 	var code = this.code.build( builder, output ) + ';';
 
 	builder.addNodeCode( code );
-	
+
 	if ( builder.isShader( 'vertex' ) ) {
-		
-		if (this.value) {
-		
+
+		if ( this.value ) {
+
 			return this.value.build( builder, output );
-			
+
 		}
-		
+
 	} else {
-		
+
 		return this.value ? this.value.build( builder, output ) : builder.format( '0.0', 'f', output );
-		
+
 	}
 
 };
 
 BypassNode.prototype.copy = function ( source ) {
-	
+
 	Node.prototype.copy.call( this, source );
-	
+
 	this.code = source.code;
 	this.value = source.value;
-	
+
 };
 
 BypassNode.prototype.toJSON = function ( meta ) {
@@ -74,7 +74,7 @@ BypassNode.prototype.toJSON = function ( meta ) {
 
 		data.code = this.code.toJSON( meta ).uuid;
 
-		if (this.value) data.value = this.value.toJSON( meta ).uuid;
+		if ( this.value ) data.value = this.value.toJSON( meta ).uuid;
 
 	}
 

+ 75 - 75
examples/js/nodes/utils/ColorSpaceNode.js

@@ -14,123 +14,123 @@ function ColorSpaceNode( input, method ) {
 
 	this.method = method || ColorSpaceNode.LINEAR;
 
-};
+}
+
+ColorSpaceNode.Nodes = ( function () {
 
-ColorSpaceNode.Nodes = (function() {
-	
 	// For a discussion of what this is, please read this: http://lousodrome.net/blog/light/2013/05/26/gamma-correct-and-hdr-rendering-in-a-32-bits-buffer/
 
 	var LinearToLinear = new FunctionNode( [
 		"vec4 LinearToLinear( in vec4 value ) {",
-		
+
 		"	return value;",
 
 		"}"
 	].join( "\n" ) );
-	
+
 	var GammaToLinear = new FunctionNode( [
 		"vec4 GammaToLinear( in vec4 value, in float gammaFactor ) {",
-		
+
 		"	return vec4( pow( value.xyz, vec3( gammaFactor ) ), value.w );",
-		
+
 		"}"
-	].join( "\n" ));
-	
+	].join( "\n" ) );
+
 	var LinearToGamma = new FunctionNode( [
 		"vec4 LinearToGamma( in vec4 value, in float gammaFactor ) {",
-		
+
 		"	return vec4( pow( value.xyz, vec3( 1.0 / gammaFactor ) ), value.w );",
-		
+
 		"}"
-	].join( "\n" ));
-	
+	].join( "\n" ) );
+
 	var sRGBToLinear = new FunctionNode( [
 		"vec4 sRGBToLinear( in vec4 value ) {",
-		
+
 		"	return vec4( mix( pow( value.rgb * 0.9478672986 + vec3( 0.0521327014 ), vec3( 2.4 ) ), value.rgb * 0.0773993808, vec3( lessThanEqual( value.rgb, vec3( 0.04045 ) ) ) ), value.w );",
-		
+
 		"}"
-	].join( "\n" ));
-	
+	].join( "\n" ) );
+
 	var LinearTosRGB = new FunctionNode( [
 		"vec4 LinearTosRGB( in vec4 value ) {",
-		
+
 		"	return vec4( mix( pow( value.rgb, vec3( 0.41666 ) ) * 1.055 - vec3( 0.055 ), value.rgb * 12.92, vec3( lessThanEqual( value.rgb, vec3( 0.0031308 ) ) ) ), value.w );",
-		
+
 		"}"
-	].join( "\n" ));
-	
+	].join( "\n" ) );
+
 	var RGBEToLinear = new FunctionNode( [
 		"vec4 RGBEToLinear( in vec4 value ) {",
-		
+
 		"	return vec4( value.rgb * exp2( value.a * 255.0 - 128.0 ), 1.0 );",
-		
+
 		"}"
-	].join( "\n" ));
-	
+	].join( "\n" ) );
+
 	var LinearToRGBE = new FunctionNode( [
 		"vec4 LinearToRGBE( in vec4 value ) {",
-		
+
 		"	float maxComponent = max( max( value.r, value.g ), value.b );",
 		"	float fExp = clamp( ceil( log2( maxComponent ) ), -128.0, 127.0 );",
 		"	return vec4( value.rgb / exp2( fExp ), ( fExp + 128.0 ) / 255.0 );",
 		//  return vec4( value.brg, ( 3.0 + 128.0 ) / 256.0 );
-		
+
 		"}"
-	].join( "\n" ));
-	
+	].join( "\n" ) );
+
 	// reference: http://iwasbeingirony.blogspot.ca/2010/06/difference-between-rgbm-and-rgbd.html
-	
+
 	var RGBMToLinear = new FunctionNode( [
 		"vec3 RGBMToLinear( in vec4 value, in float maxRange ) {",
-		
+
 		"	return vec4( value.xyz * value.w * maxRange, 1.0 );",
-		
+
 		"}"
 	].join( "\n" ) );
-	
+
 	var LinearToRGBM = new FunctionNode( [
 		"vec3 LinearToRGBM( in vec4 value, in float maxRange ) {",
-		
+
 		"	float maxRGB = max( value.x, max( value.g, value.b ) );",
 		"	float M      = clamp( maxRGB / maxRange, 0.0, 1.0 );",
 		"	M            = ceil( M * 255.0 ) / 255.0;",
 		"	return vec4( value.rgb / ( M * maxRange ), M );",
-		
+
 		"}"
 	].join( "\n" ) );
-	
+
 	// reference: http://iwasbeingirony.blogspot.ca/2010/06/difference-between-rgbm-and-rgbd.html
-	
+
 	var RGBDToLinear = new FunctionNode( [
 		"vec3 RGBDToLinear( in vec4 value, in float maxRange ) {",
-		
+
 		"	return vec4( value.rgb * ( ( maxRange / 255.0 ) / value.a ), 1.0 );",
-		
+
 		"}"
 	].join( "\n" ) );
-	
-	
+
+
 	var LinearToRGBD = new FunctionNode( [
 		"vec3 LinearToRGBD( in vec4 value, in float maxRange ) {",
-		
+
 		"	float maxRGB = max( value.x, max( value.g, value.b ) );",
 		"	float D      = max( maxRange / maxRGB, 1.0 );",
 		"	D            = min( floor( D ) / 255.0, 1.0 );",
 		"	return vec4( value.rgb * ( D * ( 255.0 / maxRange ) ), D );",
-		
+
 		"}"
 	].join( "\n" ) );
-	
+
 	// LogLuv reference: http://graphicrants.blogspot.ca/2009/04/rgbm-color-encoding.html
 
 	// M matrix, for encoding
-	
-	var cLogLuvM = new ConstNode("const mat3 cLogLuvM = mat3( 0.2209, 0.3390, 0.4184, 0.1138, 0.6780, 0.7319, 0.0102, 0.1130, 0.2969 );");
-	
+
+	var cLogLuvM = new ConstNode( "const mat3 cLogLuvM = mat3( 0.2209, 0.3390, 0.4184, 0.1138, 0.6780, 0.7319, 0.0102, 0.1130, 0.2969 );" );
+
 	var LinearToLogLuv = new FunctionNode( [
 		"vec4 LinearToLogLuv( in vec4 value ) {",
-		
+
 		"	vec3 Xp_Y_XYZp = value.rgb * cLogLuvM;",
 		"	Xp_Y_XYZp = max(Xp_Y_XYZp, vec3(1e-6, 1e-6, 1e-6));",
 		"	vec4 vResult;",
@@ -139,17 +139,17 @@ ColorSpaceNode.Nodes = (function() {
 		"	vResult.w = fract(Le);",
 		"	vResult.z = (Le - (floor(vResult.w*255.0))/255.0)/255.0;",
 		"	return vResult;",
-		
+
 		"}"
 	].join( "\n" ), [ cLogLuvM ] );
-	
+
 	// Inverse M matrix, for decoding
-	
-	var cLogLuvInverseM = new ConstNode("const mat3 cLogLuvInverseM = mat3( 6.0014, -2.7008, -1.7996, -1.3320, 3.1029, -5.7721, 0.3008, -1.0882, 5.6268 );");
-	
+
+	var cLogLuvInverseM = new ConstNode( "const mat3 cLogLuvInverseM = mat3( 6.0014, -2.7008, -1.7996, -1.3320, 3.1029, -5.7721, 0.3008, -1.0882, 5.6268 );" );
+
 	var LogLuvToLinear = new FunctionNode( [
 		"vec4 LogLuvToLinear( in vec4 value ) {",
-		
+
 		"	float Le = value.z * 255.0 + value.w;",
 		"	vec3 Xp_Y_XYZp;",
 		"	Xp_Y_XYZp.y = exp2((Le - 127.0) / 2.0);",
@@ -157,10 +157,10 @@ ColorSpaceNode.Nodes = (function() {
 		"	Xp_Y_XYZp.x = value.x * Xp_Y_XYZp.z;",
 		"	vec3 vRGB = Xp_Y_XYZp.rgb * cLogLuvInverseM;",
 		"	return vec4( max(vRGB, 0.0), 1.0 );",
-		
+
 		"}"
 	].join( "\n" ), [ cLogLuvInverseM ] );
-	
+
 	return {
 		LinearToLinear: LinearToLinear,
 		GammaToLinear: GammaToLinear,
@@ -178,8 +178,8 @@ ColorSpaceNode.Nodes = (function() {
 		cLogLuvInverseM: cLogLuvInverseM,
 		LogLuvToLinear: LogLuvToLinear
 	};
-	
-})();
+
+} )();
 
 ColorSpaceNode.LINEAR_TO_LINEAR = 'LinearToLinear';
 
@@ -209,43 +209,43 @@ ColorSpaceNode.prototype.generate = function ( builder, output ) {
 
 	var input = builder.context.input || this.input.build( builder, 'v4' ),
 		encodingMethod = builder.context.encoding !== undefined ? this.getEncodingMethod( builder.context.encoding ) : [ this.method ],
-		factor = this.factor ? this.factor.build( builder, 'f' ) : encodingMethod[1];
-	
-	var method = builder.include( ColorSpaceNode.Nodes[encodingMethod[0]] );
-	
-	if (factor) {
-		
+		factor = this.factor ? this.factor.build( builder, 'f' ) : encodingMethod[ 1 ];
+
+	var method = builder.include( ColorSpaceNode.Nodes[ encodingMethod[ 0 ] ] );
+
+	if ( factor ) {
+
 		return builder.format( method + '( ' + input + ', ' + factor + ' )', this.getType( builder ), output );
-		
+
 	} else {
-		
+
 		return builder.format( method + '( ' + input + ' )', this.getType( builder ), output );
-		
+
 	}
 
 };
 
-ColorSpaceNode.prototype.getDecodingMethod = function( encoding ) {
+ColorSpaceNode.prototype.getDecodingMethod = function ( encoding ) {
 
 	var components = this.getEncodingComponents( encoding );
 
 	components[ 0 ] += 'ToLinear';
-	
+
 	return components;
 
 };
 
-ColorSpaceNode.prototype.getEncodingMethod = function( encoding ) {
+ColorSpaceNode.prototype.getEncodingMethod = function ( encoding ) {
 
 	var components = this.getEncodingComponents( encoding );
 
 	components[ 0 ] = 'LinearTo' + components[ 0 ];
-	
+
 	return components;
 
 };
 
-ColorSpaceNode.prototype.getEncodingComponents = function( encoding ) {
+ColorSpaceNode.prototype.getEncodingComponents = function ( encoding ) {
 
 	switch ( encoding ) {
 
@@ -269,9 +269,9 @@ ColorSpaceNode.prototype.getEncodingComponents = function( encoding ) {
 };
 
 ColorSpaceNode.prototype.copy = function ( source ) {
-			
+
 	TempNode.prototype.copy.call( this, source );
-	
+
 	this.input = source.input;
 	this.method = source.method;
 
@@ -294,4 +294,4 @@ ColorSpaceNode.prototype.toJSON = function ( meta ) {
 
 };
 
-export { ColorSpaceNode };
+export { ColorSpaceNode };

+ 7 - 7
examples/js/nodes/utils/JoinNode.js

@@ -4,9 +4,9 @@
 
 import { TempNode } from '../core/TempNode.js';
 import { NodeUtils } from '../core/NodeUtils.js';
- 
+
 var inputs = NodeUtils.elements;
- 
+
 function JoinNode( x, y, z, w ) {
 
 	TempNode.call( this, 'f' );
@@ -16,7 +16,7 @@ function JoinNode( x, y, z, w ) {
 	this.z = z;
 	this.w = w;
 
-};
+}
 
 JoinNode.prototype = Object.create( TempNode.prototype );
 JoinNode.prototype.constructor = JoinNode;
@@ -31,7 +31,7 @@ JoinNode.prototype.getNumElements = function () {
 		if ( this[ inputs[ i ] ] !== undefined ) {
 
 			++ i;
-			
+
 			break;
 
 		}
@@ -69,15 +69,15 @@ JoinNode.prototype.generate = function ( builder, output ) {
 };
 
 JoinNode.prototype.copy = function ( source ) {
-			
+
 	TempNode.prototype.copy.call( this, source );
-	
+
 	for ( var prop in source.inputs ) {
 
 		this[ prop ] = source.inputs[ prop ];
 
 	}
-	
+
 };
 
 JoinNode.prototype.toJSON = function ( meta ) {

+ 6 - 6
examples/js/nodes/utils/MaxMIPLevelNode.js

@@ -3,7 +3,7 @@
  */
 
 import { FloatNode } from '../inputs/FloatNode.js';
- 
+
 function MaxMIPLevelNode( texture ) {
 
 	FloatNode.call( this );
@@ -12,7 +12,7 @@ function MaxMIPLevelNode( texture ) {
 
 	this.maxMIPLevel = 0;
 
-};
+}
 
 MaxMIPLevelNode.prototype = Object.create( FloatNode.prototype );
 MaxMIPLevelNode.prototype.constructor = MaxMIPLevelNode;
@@ -21,12 +21,12 @@ MaxMIPLevelNode.prototype.nodeType = "MaxMIPLevel";
 Object.defineProperties( MaxMIPLevelNode.prototype, {
 
 	value: {
-		
+
 		get: function () {
 
 			if ( this.maxMIPLevel === 0 ) {
 
-				var image = this.texture.value.image ? this.texture.value.image[0] : undefined;
+				var image = this.texture.value.image ? this.texture.value.image[ 0 ] : undefined;
 
 				this.maxMIPLevel = image !== undefined ? Math.log( Math.max( image.width, image.height ) ) * Math.LOG2E : 0;
 
@@ -35,9 +35,9 @@ Object.defineProperties( MaxMIPLevelNode.prototype, {
 			return this.maxMIPLevel;
 
 		},
-		
+
 		set: function () { }
-		
+
 	}
 
 } );

+ 5 - 5
examples/js/nodes/utils/SwitchNode.js

@@ -3,7 +3,7 @@
  */
 
 import { Node } from '../core/Node.js';
- 
+
 function SwitchNode( node, components ) {
 
 	Node.call( this );
@@ -11,7 +11,7 @@ function SwitchNode( node, components ) {
 	this.node = node;
 	this.components = components || 'x';
 
-};
+}
 
 SwitchNode.prototype = Object.create( Node.prototype );
 SwitchNode.prototype.constructor = SwitchNode;
@@ -74,12 +74,12 @@ SwitchNode.prototype.generate = function ( builder, output ) {
 };
 
 SwitchNode.prototype.copy = function ( source ) {
-			
+
 	Node.prototype.copy.call( this, source );
-	
+
 	this.node = source.node;
 	this.components = source.components;
-	
+
 };
 
 SwitchNode.prototype.toJSON = function ( meta ) {

+ 9 - 9
examples/js/nodes/utils/TimerNode.js

@@ -4,7 +4,7 @@
 
 import { FloatNode } from '../inputs/FloatNode.js';
 import { NodeLib } from '../core/NodeLib.js';
- 
+
 function TimerNode( scale, scope, timeScale ) {
 
 	FloatNode.call( this );
@@ -14,7 +14,7 @@ function TimerNode( scale, scope, timeScale ) {
 
 	this.timeScale = timeScale !== undefined ? timeScale : this.scale !== 1;
 
-};
+}
 
 TimerNode.GLOBAL = 'global';
 TimerNode.LOCAL = 'local';
@@ -27,7 +27,7 @@ TimerNode.prototype.nodeType = "Timer";
 TimerNode.prototype.isReadonly = function () {
 
 	// never use TimerNode as readonly but aways as "uniform"
-	
+
 	return false;
 
 };
@@ -44,7 +44,7 @@ TimerNode.prototype.updateFrame = function ( frame ) {
 
 	var scale = this.timeScale ? this.scale : 1;
 
-	switch( this.scope ) {
+	switch ( this.scope ) {
 
 		case TimerNode.LOCAL:
 
@@ -67,14 +67,14 @@ TimerNode.prototype.updateFrame = function ( frame ) {
 };
 
 TimerNode.prototype.copy = function ( source ) {
-			
+
 	FloatNode.prototype.copy.call( this, source );
-	
+
 	this.scope = source.scope;
 	this.scale = source.scale;
-	
+
 	this.timeScale = source.timeScale;
-	
+
 };
 
 TimerNode.prototype.toJSON = function ( meta ) {
@@ -87,7 +87,7 @@ TimerNode.prototype.toJSON = function ( meta ) {
 
 		data.scope = this.scope;
 		data.scale = this.scale;
-		
+
 		data.timeScale = this.timeScale;
 
 	}

+ 6 - 6
examples/js/nodes/utils/UVTransformNode.js

@@ -5,7 +5,7 @@
 import { ExpressionNode } from '../core/ExpressionNode.js';
 import { Matrix3Node } from '../inputs/Matrix3Node.js';
 import { UVNode } from '../accessors/UVNode.js';
- 
+
 function UVTransformNode( uv, position ) {
 
 	ExpressionNode.call( this, "( uvTransform * vec3( uvNode, 1 ) ).xy", "vec2" );
@@ -13,7 +13,7 @@ function UVTransformNode( uv, position ) {
 	this.uv = uv || new UVNode();
 	this.position = position || new Matrix3Node();
 
-};
+}
 
 UVTransformNode.prototype = Object.create( ExpressionNode.prototype );
 UVTransformNode.prototype.constructor = UVTransformNode;
@@ -38,12 +38,12 @@ UVTransformNode.prototype.setUvTransform = function ( tx, ty, sx, sy, rotation,
 };
 
 UVTransformNode.prototype.copy = function ( source ) {
-			
+
 	ExpressionNode.prototype.copy.call( this, source );
-	
+
 	this.uv = source.uv;
 	this.position = source.position;
-					
+
 };
 
 UVTransformNode.prototype.toJSON = function ( meta ) {
@@ -63,4 +63,4 @@ UVTransformNode.prototype.toJSON = function ( meta ) {
 
 };
 
-export { UVTransformNode };
+export { UVTransformNode };

+ 7 - 7
examples/js/nodes/utils/VelocityNode.js

@@ -3,7 +3,7 @@
  */
 
 import { Vector3Node } from '../inputs/Vector3Node.js';
- 
+
 function VelocityNode( target, params ) {
 
 	Vector3Node.call( this );
@@ -15,7 +15,7 @@ function VelocityNode( target, params ) {
 	this.setTarget( target );
 	this.setParams( params );
 
-};
+}
 
 VelocityNode.prototype = Object.create( Vector3Node.prototype );
 VelocityNode.prototype.constructor = VelocityNode;
@@ -143,13 +143,13 @@ VelocityNode.prototype.updateFrame = function ( frame ) {
 };
 
 VelocityNode.prototype.copy = function ( source ) {
-			
+
 	Vector3Node.prototype.copy.call( this, source );
-	
+
 	if ( source.target ) object.setTarget( source.target );
-	
+
 	object.setParams( source.params );
-	
+
 };
 
 VelocityNode.prototype.toJSON = function ( meta ) {
@@ -171,4 +171,4 @@ VelocityNode.prototype.toJSON = function ( meta ) {
 
 };
 
-export { VelocityNode };
+export { VelocityNode };

+ 106 - 106
examples/webgl_loader_nodes.html

@@ -42,187 +42,187 @@
 
 		<script type="module">
 
-		import './js/nodes/THREE.Nodes.js';
-		import './js/loaders/NodeMaterialLoader.js';
+			import './js/nodes/THREE.Nodes.js';
+			import './js/loaders/NodeMaterialLoader.js';
 
-		var container = document.getElementById( 'container' );
+			var container = document.getElementById( 'container' );
 
-		var renderer, scene, camera, clock = new THREE.Clock(), fov = 50;
-		var frame = new THREE.NodeFrame();
-		var teapot, mesh, cloud;
-		var controls;
-		var gui;
+			var renderer, scene, camera, clock = new THREE.Clock(), fov = 50;
+			var frame = new THREE.NodeFrame();
+			var teapot, mesh, cloud;
+			var controls;
+			var gui;
 
-		var param = { load: 'caustic' };
+			var param = { load: 'caustic' };
 
-		window.addEventListener( 'load', init );
+			window.addEventListener( 'load', init );
 
-		function init() {
+			function init() {
 
-			renderer = new THREE.WebGLRenderer( { antialias: true } );
-			renderer.setPixelRatio( window.devicePixelRatio );
-			renderer.setSize( window.innerWidth, window.innerHeight );
-			container.appendChild( renderer.domElement );
+				renderer = new THREE.WebGLRenderer( { antialias: true } );
+				renderer.setPixelRatio( window.devicePixelRatio );
+				renderer.setSize( window.innerWidth, window.innerHeight );
+				container.appendChild( renderer.domElement );
 
-			scene = new THREE.Scene();
+				scene = new THREE.Scene();
 
-			camera = new THREE.PerspectiveCamera( fov, window.innerWidth / window.innerHeight, 1, 1000 );
-			camera.position.x = 50;
-			camera.position.z = - 50;
-			camera.position.y = 30;
-			camera.target = new THREE.Vector3();
+				camera = new THREE.PerspectiveCamera( fov, window.innerWidth / window.innerHeight, 1, 1000 );
+				camera.position.x = 50;
+				camera.position.z = - 50;
+				camera.position.y = 30;
+				camera.target = new THREE.Vector3();
 
-			cloud = new THREE.TextureLoader().load( 'textures/lava/cloud.png' );
-			cloud.wrapS = cloud.wrapT = THREE.RepeatWrapping;
+				cloud = new THREE.TextureLoader().load( 'textures/lava/cloud.png' );
+				cloud.wrapS = cloud.wrapT = THREE.RepeatWrapping;
 
-			controls = new THREE.OrbitControls( camera, renderer.domElement );
-			controls.minDistance = 50;
-			controls.maxDistance = 200;
+				controls = new THREE.OrbitControls( camera, renderer.domElement );
+				controls.minDistance = 50;
+				controls.maxDistance = 200;
 
-			scene.add( new THREE.AmbientLight( 0x464646 ) );
+				scene.add( new THREE.AmbientLight( 0x464646 ) );
 
-			var light = new THREE.DirectionalLight( 0xffddcc, 1 );
-			light.position.set( 1, 0.75, 0.5 );
-			scene.add( light );
+				var light = new THREE.DirectionalLight( 0xffddcc, 1 );
+				light.position.set( 1, 0.75, 0.5 );
+				scene.add( light );
 
-			var light = new THREE.DirectionalLight( 0xccccff, 1 );
-			light.position.set( - 1, 0.75, - 0.5 );
-			scene.add( light );
+				var light = new THREE.DirectionalLight( 0xccccff, 1 );
+				light.position.set( - 1, 0.75, - 0.5 );
+				scene.add( light );
 
-			teapot = new THREE.TeapotBufferGeometry( 15, 18 );
+				teapot = new THREE.TeapotBufferGeometry( 15, 18 );
 
-			mesh = new THREE.Mesh( teapot );
-			scene.add( mesh );
+				mesh = new THREE.Mesh( teapot );
+				scene.add( mesh );
 
-			window.addEventListener( 'resize', onWindowResize, false );
+				window.addEventListener( 'resize', onWindowResize, false );
 
-			updateMaterial();
+				updateMaterial();
 
-			onWindowResize();
-			animate();
+				onWindowResize();
+				animate();
 
-		}
+			}
 
-		function clearGui() {
+			function clearGui() {
 
-			if ( gui ) gui.destroy();
+				if ( gui ) gui.destroy();
 
-			gui = new dat.GUI();
+				gui = new dat.GUI();
 
-			var example = gui.add( param, 'load', {
-				'caustic': 'caustic',
-				'displace': 'displace',
-				'wave': 'wave',
-				'xray': 'xray'
-			} ).onFinishChange( function () {
+				var example = gui.add( param, 'load', {
+					'caustic': 'caustic',
+					'displace': 'displace',
+					'wave': 'wave',
+					'xray': 'xray'
+				} ).onFinishChange( function () {
 
-				updateMaterial();
+					updateMaterial();
 
-			} );
+				} );
 
-			gui.open();
+				gui.open();
 
-		}
+			}
 
-		function addGui( name, value, callback, isColor, min, max ) {
+			function addGui( name, value, callback, isColor, min, max ) {
 
-			var node;
+				var node;
 
-			param[ name ] = value;
+				param[ name ] = value;
 
-			if ( isColor ) {
+				if ( isColor ) {
 
-				node = gui.addColor( param, name ).onChange( function () {
+					node = gui.addColor( param, name ).onChange( function () {
 
-					callback( param[ name ] );
+						callback( param[ name ] );
 
-				} );
+					} );
 
-			} else if ( typeof value == 'object' ) {
+				} else if ( typeof value == 'object' ) {
 
-				node = gui.add( param, name, value ).onChange( function () {
+					node = gui.add( param, name, value ).onChange( function () {
 
-					callback( param[ name ] );
+						callback( param[ name ] );
 
-				} );
+					} );
 
-			} else {
+				} else {
 
-				node = gui.add( param, name, min, max ).onChange( function () {
+					node = gui.add( param, name, min, max ).onChange( function () {
 
-					callback( param[ name ] );
+						callback( param[ name ] );
 
-				} );
+					} );
 
-			}
+				}
 
-			return node;
+				return node;
 
-		}
+			}
 
 
-		function updateMaterial() {
+			function updateMaterial() {
 
-			if ( mesh.material ) mesh.material.dispose();
+				if ( mesh.material ) mesh.material.dispose();
 
-			clearGui();
+				clearGui();
 
-			var url = "nodes/" + param.load + ".json";
+				var url = "nodes/" + param.load + ".json";
 
-			var library = {
-				"cloud": cloud
-			};
+				var library = {
+					"cloud": cloud
+				};
 
-			var loader = new THREE.NodeMaterialLoader( undefined, library ).load( url, function () {
+				var loader = new THREE.NodeMaterialLoader( undefined, library ).load( url, function () {
 
-				var time = loader.getObjectByName( "time" );
+					var time = loader.getObjectByName( "time" );
 
-				if ( time ) {
+					if ( time ) {
 
-					// enable time scale
+						// enable time scale
 
-					time.timeScale = true;
+						time.timeScale = true;
 
-					// gui
+						// gui
 
-					addGui( 'timeScale', time.scale, function ( val ) {
+						addGui( 'timeScale', time.scale, function ( val ) {
 
-						time.scale = val;
+							time.scale = val;
 
-					}, false, - 2, 2 );
+						}, false, - 2, 2 );
 
-				}
+					}
 
-				// set material
-				mesh.material = loader.material;
+					// set material
+					mesh.material = loader.material;
 
-			} );
+				} );
 
-		}
+			}
 
-		function onWindowResize() {
+			function onWindowResize() {
 
-			var width = window.innerWidth, height = window.innerHeight;
+				var width = window.innerWidth, height = window.innerHeight;
 
-			camera.aspect = width / height;
-			camera.updateProjectionMatrix();
+				camera.aspect = width / height;
+				camera.updateProjectionMatrix();
 
-			renderer.setSize( width, height );
+				renderer.setSize( width, height );
 
-		}
+			}
 
-		function animate() {
+			function animate() {
 
-			var delta = clock.getDelta();
+				var delta = clock.getDelta();
 
-			// update material animation and/or gpu calcs (pre-renderer)
-			if ( mesh.material instanceof THREE.NodeMaterial ) frame.update( delta ).updateNode( mesh.material );
+				// update material animation and/or gpu calcs (pre-renderer)
+				if ( mesh.material instanceof THREE.NodeMaterial ) frame.update( delta ).updateNode( mesh.material );
 
-			renderer.render( scene, camera );
+				renderer.render( scene, camera );
 
-			requestAnimationFrame( animate );
+				requestAnimationFrame( animate );
 
-		}
+			}
 
 		</script>
 	</body>

+ 1787 - 1787
examples/webgl_materials_nodes.html

@@ -42,2611 +42,2611 @@
 		
 		<script type="module">
 
-		import './js/nodes/THREE.Nodes.js';
-		import './js/loaders/NodeMaterialLoader.js';
+			import './js/nodes/THREE.Nodes.js';
+			import './js/loaders/NodeMaterialLoader.js';
 
-		var container = document.getElementById( 'container' );
+			var container = document.getElementById( 'container' );
 
-		var renderer, scene, camera, clock = new THREE.Clock(), fov = 50;
-		var frame = new THREE.NodeFrame();
-		var teapot, mesh;
-		var controls;
-		var move = false;
-		var rtTexture, rtMaterial;
-		var gui, guiElements = [];
-		var library = {};
-		var serialized = false;
-		var textures = {
-			brick: { url: 'textures/brick_diffuse.jpg' },
-			grass: { url: 'textures/terrain/grasslight-big.jpg' },
-			grassNormal: { url: 'textures/terrain/grasslight-big-nm.jpg' },
-			decalDiffuse: { url: 'textures/decal/decal-diffuse.png' },
-			decalNormal: { url: 'textures/decal/decal-normal.jpg' },
-			cloud: { url: 'textures/lava/cloud.png' },
-			spherical: { url: 'textures/envmap.png' }
-		};
+			var renderer, scene, camera, clock = new THREE.Clock(), fov = 50;
+			var frame = new THREE.NodeFrame();
+			var teapot, mesh;
+			var controls;
+			var move = false;
+			var rtTexture, rtMaterial;
+			var gui;
+			var library = {};
+			var serialized = false;
+			var textures = {
+				brick: { url: 'textures/brick_diffuse.jpg' },
+				grass: { url: 'textures/terrain/grasslight-big.jpg' },
+				grassNormal: { url: 'textures/terrain/grasslight-big-nm.jpg' },
+				decalDiffuse: { url: 'textures/decal/decal-diffuse.png' },
+				decalNormal: { url: 'textures/decal/decal-normal.jpg' },
+				cloud: { url: 'textures/lava/cloud.png' },
+				spherical: { url: 'textures/envmap.png' }
+			};
 
-		var param = { example: new URL(window.location.href).searchParams.get('e') || 'mesh-standard' };
+			var param = { example: new URL( window.location.href ).searchParams.get( 'e' ) || 'mesh-standard' };
 
-		function getTexture( name ) {
+			function getTexture( name ) {
 
-			var texture = textures[ name ].texture;
+				var texture = textures[ name ].texture;
 
-			if ( ! texture ) {
+				if ( ! texture ) {
 
-				texture = textures[ name ].texture = new THREE.TextureLoader().load( textures[ name ].url );
-				texture.wrapS = texture.wrapT = THREE.RepeatWrapping;
+					texture = textures[ name ].texture = new THREE.TextureLoader().load( textures[ name ].url );
+					texture.wrapS = texture.wrapT = THREE.RepeatWrapping;
 
-				library[ texture.uuid ] = texture;
+					library[ texture.uuid ] = texture;
+
+				}
+
+				return texture;
 
 			}
 
-			return texture;
+			var cubemap = function () {
 
-		}
+				var path = "textures/cube/Park2/";
+				var format = '.jpg';
+				var urls = [
+					path + 'posx' + format, path + 'negx' + format,
+					path + 'posy' + format, path + 'negy' + format,
+					path + 'posz' + format, path + 'negz' + format
+				];
 
-		var cubemap = function () {
+				var textureCube = new THREE.CubeTextureLoader().load( urls );
+				textureCube.format = THREE.RGBFormat;
 
-			var path = "textures/cube/Park2/";
-			var format = '.jpg';
-			var urls = [
-				path + 'posx' + format, path + 'negx' + format,
-				path + 'posy' + format, path + 'negy' + format,
-				path + 'posz' + format, path + 'negz' + format
-			];
+				library[ textureCube.uuid ] = textureCube;
 
-			var textureCube = new THREE.CubeTextureLoader().load( urls );
-			textureCube.format = THREE.RGBFormat;
+				return textureCube;
 
-			library[ textureCube.uuid ] = textureCube;
-
-			return textureCube;
+			}();
 
-		}();
+			window.addEventListener( 'load', init );
 
-		window.addEventListener( 'load', init );
+			function init() {
 
-		function init() {
+				renderer = new THREE.WebGLRenderer( { antialias: true } );
+				renderer.setPixelRatio( window.devicePixelRatio );
+				renderer.setSize( window.innerWidth, window.innerHeight );
+				renderer.uuid = THREE.Math.generateUUID(); // generate to library
+				container.appendChild( renderer.domElement );
 
-			renderer = new THREE.WebGLRenderer( { antialias: true } );
-			renderer.setPixelRatio( window.devicePixelRatio );
-			renderer.setSize( window.innerWidth, window.innerHeight );
-			renderer.uuid = THREE.Math.generateUUID(); // generate to library
-			container.appendChild( renderer.domElement );
+				scene = new THREE.Scene();
 
-			scene = new THREE.Scene();
+				camera = new THREE.PerspectiveCamera( fov, window.innerWidth / window.innerHeight, 1, 1000 );
+				camera.position.x = 50;
+				camera.position.z = - 50;
+				camera.position.y = 30;
+				camera.target = new THREE.Vector3();
 
-			camera = new THREE.PerspectiveCamera( fov, window.innerWidth / window.innerHeight, 1, 1000 );
-			camera.position.x = 50;
-			camera.position.z = - 50;
-			camera.position.y = 30;
-			camera.target = new THREE.Vector3();
 
+				controls = new THREE.OrbitControls( camera, renderer.domElement );
+				controls.minDistance = 50;
+				controls.maxDistance = 200;
 
-			controls = new THREE.OrbitControls( camera, renderer.domElement );
-			controls.minDistance = 50;
-			controls.maxDistance = 200;
+				scene.add( new THREE.AmbientLight( 0x464646 ) );
 
-			scene.add( new THREE.AmbientLight( 0x464646 ) );
+				var light = new THREE.DirectionalLight( 0xffddcc, 1 );
+				light.position.set( 1, 0.75, 0.5 );
+				scene.add( light );
 
-			var light = new THREE.DirectionalLight( 0xffddcc, 1 );
-			light.position.set( 1, 0.75, 0.5 );
-			scene.add( light );
+				var light = new THREE.DirectionalLight( 0xccccff, 1 );
+				light.position.set( - 1, 0.75, - 0.5 );
+				scene.add( light );
 
-			var light = new THREE.DirectionalLight( 0xccccff, 1 );
-			light.position.set( - 1, 0.75, - 0.5 );
-			scene.add( light );
+				teapot = new THREE.TeapotBufferGeometry( 15, 18 );
 
-			teapot = new THREE.TeapotBufferGeometry( 15, 18 );
+				mesh = new THREE.Mesh( teapot );
+				scene.add( mesh );
 
-			mesh = new THREE.Mesh( teapot );
-			scene.add( mesh );
+				library[ renderer.uuid ] = renderer;
+				library[ camera.uuid ] = camera;
+				library[ mesh.uuid ] = mesh;
 
-			library[ renderer.uuid ] = renderer;
-			library[ camera.uuid ] = camera;
-			library[ mesh.uuid ] = mesh;
+				window.addEventListener( 'resize', onWindowResize, false );
 
-			window.addEventListener( 'resize', onWindowResize, false );
+				updateMaterial();
 
-			updateMaterial();
+				onWindowResize();
+				animate();
 
-			onWindowResize();
-			animate();
+			}
 
-		}
+			function clearGui() {
+
+				if ( gui ) gui.destroy();
+
+				gui = new dat.GUI();
+
+				var example = gui.add( param, 'example', {
+					'basic / mesh-standard': 'mesh-standard',
+					'basic / standard': 'standard',
+					'basic / physical': 'physical',
+					'basic / phong': 'phong',
+					'basic / layers': 'layers',
+					'basic / rim': 'rim',
+					'basic / color-adjustment': 'color-adjustment',
+					'basic / uv-transform': 'uv-transform',
+					'basic / bump': 'bump',
+					'basic / blur': 'blur',
+					'basic / spherical-reflection': 'spherical-reflection',
+					'adv / fresnel': 'fresnel',
+					'adv / saturation': 'saturation',
+					'adv / top-bottom': 'top-bottom',
+					'adv / skin': 'skin',
+					'adv / skin-phong': 'skin-phong',
+					'adv / caustic': 'caustic',
+					'adv / displace': 'displace',
+					'adv / plush': 'plush',
+					'adv / toon': 'toon',
+					'adv / camera-depth': 'camera-depth',
+					'adv / soft-body': 'soft-body',
+					'adv / wave': 'wave',
+					'adv / triangle-blur': 'triangle-blur',
+					'adv / render-to-texture': 'rtt',
+					'adv / temporal-blur': 'temporal-blur',
+					'adv / conditional': 'conditional',
+					'adv / expression': 'expression',
+					'adv / sss': 'sss',
+					'adv / translucent': 'translucent',
+					'misc / smoke': 'smoke',
+					'misc / firefly': 'firefly',
+					'misc / reserved-keywords': 'reserved-keywords',
+					'misc / varying': 'varying',
+					'misc / void-function': 'void-function',
+					'misc / readonly': 'readonly',
+					'misc / custom-attribute': 'custom-attribute'
+				} ).onFinishChange( function () {
+
+					updateMaterial();
 
-		function clearGui() {
+				} );
 
-			if ( gui ) gui.destroy();
+				gui.open();
 
-			gui = new dat.GUI();
+			}
 
-			var example = gui.add( param, 'example', {
-				'basic / mesh-standard': 'mesh-standard',
-				'basic / standard': 'standard',
-				'basic / physical': 'physical',
-				'basic / phong': 'phong',
-				'basic / layers': 'layers',
-				'basic / rim': 'rim',
-				'basic / color-adjustment': 'color-adjustment',
-				'basic / uv-transform': 'uv-transform',
-				'basic / bump': 'bump',
-				'basic / blur': 'blur',
-				'basic / spherical-reflection': 'spherical-reflection',
-				'adv / fresnel': 'fresnel',
-				'adv / saturation': 'saturation',
-				'adv / top-bottom': 'top-bottom',
-				'adv / skin': 'skin',
-				'adv / skin-phong': 'skin-phong',
-				'adv / caustic': 'caustic',
-				'adv / displace': 'displace',
-				'adv / plush': 'plush',
-				'adv / toon': 'toon',
-				'adv / camera-depth': 'camera-depth',
-				'adv / soft-body': 'soft-body',
-				'adv / wave': 'wave',
-				'adv / triangle-blur': 'triangle-blur',
-				'adv / render-to-texture': 'rtt',
-				'adv / temporal-blur': 'temporal-blur',
-				'adv / conditional': 'conditional',
-				'adv / expression': 'expression',
-				'adv / sss': 'sss',
-				'adv / translucent': 'translucent',
-				'misc / smoke': 'smoke',
-				'misc / firefly': 'firefly',
-				'misc / reserved-keywords': 'reserved-keywords',
-				'misc / varying': 'varying',
-				'misc / void-function': 'void-function',
-				'misc / readonly': 'readonly',
-				'misc / custom-attribute': 'custom-attribute'
-			} ).onFinishChange( function () {
+			function addGui( name, value, callback, isColor, min, max ) {
 
-				updateMaterial();
+				var node;
 
-			} );
+				param[ name ] = value;
 
-			gui.open();
+				if ( isColor ) {
 
-		}
+					node = gui.addColor( param, name ).onChange( function () {
 
-		function addGui( name, value, callback, isColor, min, max ) {
+						callback( param[ name ] );
 
-			var node;
+					} );
 
-			param[ name ] = value;
+				} else if ( typeof value == 'object' ) {
 
-			if ( isColor ) {
+					param[ name ] = value[ Object.keys( value )[ 0 ] ];
 
-				node = gui.addColor( param, name ).onChange( function () {
+					node = gui.add( param, name, value ).onChange( function () {
 
-					callback( param[ name ] );
+						callback( param[ name ] );
 
-				} );
+					} );
 
-			} else if ( typeof value == 'object' ) {
+				} else {
 
-				param[ name ] = value[ Object.keys( value )[ 0 ] ];
+					node = gui.add( param, name, min, max ).onChange( function () {
 
-				node = gui.add( param, name, value ).onChange( function () {
+						callback( param[ name ] );
 
-					callback( param[ name ] );
+					} );
 
-				} );
+				}
 
-			} else {
+				return node;
 
-				node = gui.add( param, name, min, max ).onChange( function () {
+			}
 
-					callback( param[ name ] );
+			function updateMaterial() {
 
-				} );
+				move = false;
 
-			}
+				if ( mesh.material ) mesh.material.dispose();
 
-			return node;
+				if ( rtTexture ) {
 
-		}
+					delete library[ rtTexture.texture.uuid ];
 
-		function updateMaterial() {
+					rtTexture.dispose();
+					rtTexture = null;
 
-			move = false;
+				}
 
-			if ( mesh.material ) mesh.material.dispose();
+				if ( rtMaterial ) {
 
-			if ( rtTexture ) {
+					rtMaterial.dispose();
+					rtMaterial = null;
 
-				delete library[ rtTexture.texture.uuid ];
+				}
 
-				rtTexture.dispose();
-				rtTexture = null;
+				var name = param.example;
+				var mtl;
 
-			}
+				clearGui();
 
-			if ( rtMaterial ) {
+				switch ( name ) {
 
-				rtMaterial.dispose();
-				rtMaterial = null;
+					case 'phong':
 
-			}
+						// MATERIAL
 
-			var name = param.example;
-			var mtl;
+						mtl = new THREE.PhongNodeMaterial();
 
-			clearGui();
+						//mtl.color = // albedo (vec3)
+						//mtl.alpha = // opacity (float)
+						//mtl.specular = // specular color (vec3)
+						//mtl.shininess = // shininess (float)
+						//mtl.normal = // normal (vec3)
+						//mtl.emissive = // emissive color (vec3)
+						//mtl.ambient = // ambient color (vec3)
+						//mtl.shadow = // shadowmap (vec3)
+						//mtl.light = // custom-light (vec3)
+						//mtl.ao = // ambient occlusion (float)
+						//mtl.light = // input/output light (vec3)
+						//mtl.environment = // reflection/refraction (vec3)
+						//mtl.environmentAlpha = // environment alpha (float)
+						//mtl.position = // vertex local position (vec3)
 
-			switch ( name ) {
+						var mask = new THREE.SwitchNode( new THREE.TextureNode( getTexture( "decalDiffuse" ) ), 'w' );
 
-				case 'phong':
+						mtl.color = new THREE.TextureNode( getTexture( "grass" ) );
+						mtl.specular = new THREE.FloatNode( .5 );
+						mtl.shininess = new THREE.FloatNode( 15 );
+						mtl.environment = new THREE.CubeTextureNode( cubemap );
+						mtl.environmentAlpha = mask;
+						mtl.normal = new THREE.NormalMapNode( new THREE.TextureNode( getTexture( "grassNormal" ) ) );
+						mtl.normal.scale = new THREE.Math1Node( mask, THREE.Math1Node.INVERT );
 
-					// MATERIAL
+						break;
 
-					mtl = new THREE.PhongNodeMaterial();
+					case 'standard':
 
-					//mtl.color = // albedo (vec3)
-					//mtl.alpha = // opacity (float)
-					//mtl.specular = // specular color (vec3)
-					//mtl.shininess = // shininess (float)
-					//mtl.normal = // normal (vec3)
-					//mtl.emissive = // emissive color (vec3)
-					//mtl.ambient = // ambient color (vec3)
-					//mtl.shadow = // shadowmap (vec3)
-					//mtl.light = // custom-light (vec3)
-					//mtl.ao = // ambient occlusion (float)
-					//mtl.light = // input/output light (vec3)
-					//mtl.environment = // reflection/refraction (vec3)
-					//mtl.environmentAlpha = // environment alpha (float)
-					//mtl.position = // vertex local position (vec3)
+						// MATERIAL
 
-					var mask = new THREE.SwitchNode( new THREE.TextureNode( getTexture( "decalDiffuse" ) ), 'w' );
+						mtl = new THREE.StandardNodeMaterial();
 
-					mtl.color = new THREE.TextureNode( getTexture( "grass" ) );
-					mtl.specular = new THREE.FloatNode( .5 );
-					mtl.shininess = new THREE.FloatNode( 15 );
-					mtl.environment = new THREE.CubeTextureNode( cubemap );
-					mtl.environmentAlpha = mask;
-					mtl.normal = new THREE.NormalMapNode( new THREE.TextureNode( getTexture( "grassNormal" ) ) );
-					mtl.normal.scale = new THREE.Math1Node( mask, THREE.Math1Node.INVERT );
+						//mtl.color = // albedo (vec3)
+						//mtl.alpha = // opacity (float)
+						//mtl.roughness = // roughness (float)
+						//mtl.metalness = // metalness (float)
+						//mtl.normal = // normal (vec3)
+						//mtl.emissive = // emissive color (vec3)
+						//mtl.ambient = // ambient color (vec3)
+						//mtl.shadow = // shadowmap (vec3)
+						//mtl.light = // custom-light (vec3)
+						//mtl.ao = // ambient occlusion (float)
+						//mtl.environment = // reflection/refraction (vec3)
+						//mtl.position = // vertex local position (vec3)
 
-					break;
+						var mask = new THREE.SwitchNode( new THREE.TextureNode( getTexture( "decalDiffuse" ) ), 'w' );
 
-				case 'standard':
+						var normalScale = new THREE.FloatNode( .3 );
 
-					// MATERIAL
+						var roughnessA = new THREE.FloatNode( .5 );
+						var metalnessA = new THREE.FloatNode( .5 );
 
-					mtl = new THREE.StandardNodeMaterial();
+						var roughnessB = new THREE.FloatNode( 0 );
+						var metalnessB = new THREE.FloatNode( 1 );
 
-					//mtl.color = // albedo (vec3)
-					//mtl.alpha = // opacity (float)
-					//mtl.roughness = // roughness (float)
-					//mtl.metalness = // metalness (float)
-					//mtl.normal = // normal (vec3)
-					//mtl.emissive = // emissive color (vec3)
-					//mtl.ambient = // ambient color (vec3)
-					//mtl.shadow = // shadowmap (vec3)
-					//mtl.light = // custom-light (vec3)
-					//mtl.ao = // ambient occlusion (float)
-					//mtl.environment = // reflection/refraction (vec3)
-					//mtl.position = // vertex local position (vec3)
+						var roughness = new THREE.Math3Node(
+							roughnessA,
+							roughnessB,
+							mask,
+							THREE.Math3Node.MIX
+						);
 
-					var mask = new THREE.SwitchNode( new THREE.TextureNode( getTexture( "decalDiffuse" ) ), 'w' );
+						var metalness = new THREE.Math3Node(
+							metalnessA,
+							metalnessB,
+							mask,
+							THREE.Math3Node.MIX
+						);
 
-					var normalScale = new THREE.FloatNode( .3 );
+						var normalMask = new THREE.OperatorNode(
+							new THREE.Math1Node( mask, THREE.Math1Node.INVERT ),
+							normalScale,
+							THREE.OperatorNode.MUL
+						);
 
-					var roughnessA = new THREE.FloatNode( .5 );
-					var metalnessA = new THREE.FloatNode( .5 );
+						mtl.color = new THREE.ColorNode( 0xEEEEEE );
+						mtl.roughness = roughness;
+						mtl.metalness = metalness;
+						mtl.environment = new THREE.CubeTextureNode( cubemap );
+						mtl.normal = new THREE.NormalMapNode( new THREE.TextureNode( getTexture( "grassNormal" ) ) );
+						mtl.normal.scale = normalMask;
 
-					var roughnessB = new THREE.FloatNode( 0 );
-					var metalnessB = new THREE.FloatNode( 1 );
+						// GUI
 
-					var roughness = new THREE.Math3Node(
-						roughnessA,
-						roughnessB,
-						mask,
-						THREE.Math3Node.MIX
-					);
+						addGui( 'color', mtl.color.value.getHex(), function ( val ) {
 
-					var metalness = new THREE.Math3Node(
-						metalnessA,
-						metalnessB,
-						mask,
-						THREE.Math3Node.MIX
-					);
+							mtl.color.value.setHex( val );
 
-					var normalMask = new THREE.OperatorNode(
-						new THREE.Math1Node( mask, THREE.Math1Node.INVERT ),
-						normalScale,
-						THREE.OperatorNode.MUL
-					);
+						}, true );
 
-					mtl.color = new THREE.ColorNode( 0xEEEEEE );
-					mtl.roughness = roughness;
-					mtl.metalness = metalness;
-					mtl.environment = new THREE.CubeTextureNode( cubemap );
-					mtl.normal = new THREE.NormalMapNode( new THREE.TextureNode( getTexture( "grassNormal" ) ) );
-					mtl.normal.scale = normalMask;
+						addGui( 'roughnessA', roughnessA.value, function ( val ) {
 
-					// GUI
+							roughnessA.value = val;
 
-					addGui( 'color', mtl.color.value.getHex(), function ( val ) {
+						}, false, 0, 1 );
 
-						mtl.color.value.setHex( val );
+						addGui( 'metalnessA', metalnessA.value, function ( val ) {
 
-					}, true );
+							metalnessA.value = val;
 
-					addGui( 'roughnessA', roughnessA.value, function ( val ) {
+						}, false, 0, 1 );
 
-						roughnessA.value = val;
+						addGui( 'roughnessB', roughnessB.value, function ( val ) {
 
-					}, false, 0, 1 );
-
-					addGui( 'metalnessA', metalnessA.value, function ( val ) {
-
-						metalnessA.value = val;
-
-					}, false, 0, 1 );
-
-					addGui( 'roughnessB', roughnessB.value, function ( val ) {
-
-						roughnessB.value = val;
+							roughnessB.value = val;
 
-					}, false, 0, 1 );
+						}, false, 0, 1 );
 
-					addGui( 'metalnessB', metalnessB.value, function ( val ) {
+						addGui( 'metalnessB', metalnessB.value, function ( val ) {
 
-						metalnessB.value = val;
+							metalnessB.value = val;
 
-					}, false, 0, 1 );
+						}, false, 0, 1 );
 
-					addGui( 'normalScale', normalScale.value, function ( val ) {
+						addGui( 'normalScale', normalScale.value, function ( val ) {
 
-						normalScale.value = val;
+							normalScale.value = val;
 
-					}, false, 0, 1 );
+						}, false, 0, 1 );
 
-					break;
+						break;
 
-				case 'mesh-standard':
+					case 'mesh-standard':
+
+						// MATERIAL
+
+						var sataturation = new THREE.FloatNode( 1 );
+
+						function updateMaterial( useNodeMaterial ) {
+
+							var oldMaterial = mtl;
+
+							if ( oldMaterial ) oldMaterial.dispose();
+
+							mtl = useNodeMaterial ? new THREE.MeshStandardNodeMaterial() : new THREE.MeshStandardMaterial();
+
+							// default syntax ( backward-compatible )
+
+							mtl.map = oldMaterial ? oldMaterial.map : getTexture( "brick" );
+
+							mtl.normalMap = oldMaterial ? oldMaterial.normalMap : getTexture( "decalNormal" );
+							mtl.normalScale = new THREE.Vector2( .5, .5 );
+
+							mtl.envMap = cubemap;
+
+							mtl.roughness = oldMaterial ? oldMaterial.roughness : .5;
+							mtl.metalness = oldMaterial ? oldMaterial.metalness : .5;
+
+							// extended syntax ( only for NodeMaterial )
+
+							if ( useNodeMaterial ) {
+
+								mtl.map = new THREE.ColorAdjustmentNode(
+									new THREE.TextureNode( mtl.map ),
+									sataturation,
+									THREE.ColorAdjustmentNode.SATURATION
+								);
+
+							}
+
+							// apply material
+
+							mtl.needsUpdate = true;
+
+							mesh.material = mtl;
 
-					// MATERIAL
-					
-					var sataturation = new THREE.FloatNode( 1 );
-					
-					function updateMaterial( useNodeMaterial ) {
-					
-						var oldMaterial = mtl;
-					
-						if (oldMaterial) oldMaterial.dispose();
-					
-						mtl = useNodeMaterial ? new THREE.MeshStandardNodeMaterial() : new THREE.MeshStandardMaterial();
-					
-						// default syntax ( backward-compatible )
-					
-						mtl.map = oldMaterial ? oldMaterial.map : getTexture( "brick" );
-						
-						mtl.normalMap = oldMaterial ? oldMaterial.normalMap : getTexture( "decalNormal" );
-						mtl.normalScale = new THREE.Vector2( .5, .5 );
-						
-						mtl.envMap = cubemap;
-						
-						mtl.roughness = oldMaterial ? oldMaterial.roughness : .5;
-						mtl.metalness = oldMaterial ? oldMaterial.metalness : .5;
-						
-						// extended syntax ( only for NodeMaterial )
-						
-						if (useNodeMaterial) {
-						
-							mtl.map = new THREE.ColorAdjustmentNode( 
-								new THREE.TextureNode( mtl.map ), 
-								sataturation, 
-								THREE.ColorAdjustmentNode.SATURATION 
-							);
-							
 						}
-						
-						// apply material
-					
-						mtl.needsUpdate = true;
-					
-						mesh.material = mtl;
 
-					}
+						updateMaterial( true );
 
-					updateMaterial( true );
-					
-					// GUI
-					
-					addGui( 'use node material', true, function ( val ) {
+						// GUI
 
-						updateMaterial( val );
+						addGui( 'use node material', true, function ( val ) {
 
-					} );
-					
-					addGui( 'roughness', mtl.roughness, function ( val ) {
+							updateMaterial( val );
 
-						mtl.roughness = val;
+						} );
 
-					}, false, 0, 1 );
+						addGui( 'roughness', mtl.roughness, function ( val ) {
 
-					addGui( 'metalness', mtl.roughness, function ( val ) {
+							mtl.roughness = val;
 
-						mtl.metalness = val;
+						}, false, 0, 1 );
 
-					}, false, 0, 1 );
-					
-					addGui( 'normalX', mtl.normalScale.x, function ( val ) {
+						addGui( 'metalness', mtl.roughness, function ( val ) {
 
-						mtl.normalScale.x = val;
+							mtl.metalness = val;
 
-					}, false, -1, 1 );
-					
-					addGui( 'normalY', mtl.normalScale.y, function ( val ) {
+						}, false, 0, 1 );
 
-						mtl.normalScale.y = val;
+						addGui( 'normalX', mtl.normalScale.x, function ( val ) {
 
-					}, false, -1, 1 );
-					
-					addGui( 'sat. (node)', sataturation.value, function ( val ) {
+							mtl.normalScale.x = val;
 
-						sataturation.value = val;
+						}, false, - 1, 1 );
 
-					}, false, 0, 2 );
-					
-					addGui( 'colors', true, function ( val ) {
+						addGui( 'normalY', mtl.normalScale.y, function ( val ) {
 
-						mtl.map = val ? getTexture( "brick" ) : undefined;
-						
-						mtl.needsUpdate = true;
+							mtl.normalScale.y = val;
 
-					}, false );
-					
-					addGui( 'normals', true, function ( val ) {
+						}, false, - 1, 1 );
 
-						mtl.normalMap = val ? getTexture( "decalNormal" ) : undefined;
-						
-						mtl.needsUpdate = true;
+						addGui( 'sat. (node)', sataturation.value, function ( val ) {
 
-					}, false );
-					
-					break;
-					
-				case 'physical':
+							sataturation.value = val;
 
-					// MATERIAL
+						}, false, 0, 2 );
 
-					mtl = new THREE.StandardNodeMaterial();
+						addGui( 'colors', true, function ( val ) {
 
-					//mtl.color = // albedo (vec3)
-					//mtl.alpha = // opacity (float)
-					//mtl.roughness = // roughness (float)
-					//mtl.metalness = // metalness (float)
-					//mtl.reflectivity = // reflectivity (float)
-					//mtl.clearCoat = // clearCoat (float)
-					//mtl.clearCoatRoughness = // clearCoatRoughness (float)
-					//mtl.normal = // normal (vec3)
-					//mtl.emissive = // emissive color (vec3)
-					//mtl.ambient = // ambient color (vec3)
-					//mtl.shadow = // shadowmap (vec3)
-					//mtl.light = // custom-light (vec3)
-					//mtl.ao = // ambient occlusion (float)
-					//mtl.environment = // reflection/refraction (vec3)
-					//mtl.position = // vertex local position (vec3)
+							mtl.map = val ? getTexture( "brick" ) : undefined;
 
-					var mask = new THREE.SwitchNode( new THREE.TextureNode( getTexture( "decalDiffuse" ) ), 'w' );
+							mtl.needsUpdate = true;
 
-					var normalScale = new THREE.FloatNode( .3 );
+						}, false );
 
-					var roughnessA = new THREE.FloatNode( .5 );
-					var metalnessA = new THREE.FloatNode( .5 );
+						addGui( 'normals', true, function ( val ) {
 
-					var roughnessB = new THREE.FloatNode( 0 );
-					var metalnessB = new THREE.FloatNode( 1 );
+							mtl.normalMap = val ? getTexture( "decalNormal" ) : undefined;
 
-					var reflectivity = new THREE.FloatNode( 0 );
-					var clearCoat = new THREE.FloatNode( 1 );
-					var clearCoatRoughness = new THREE.FloatNode( 1 );
+							mtl.needsUpdate = true;
 
-					var roughness = new THREE.Math3Node(
-						roughnessA,
-						roughnessB,
-						mask,
-						THREE.Math3Node.MIX
-					);
+						}, false );
 
-					var metalness = new THREE.Math3Node(
-						metalnessA,
-						metalnessB,
-						mask,
-						THREE.Math3Node.MIX
-					);
+						break;
 
-					var normalMask = new THREE.OperatorNode(
-						new THREE.Math1Node( mask, THREE.Math1Node.INVERT ),
-						normalScale,
-						THREE.OperatorNode.MUL
-					);
+					case 'physical':
 
-					mtl.color = new THREE.ColorNode( 0xEEEEEE );
-					mtl.roughness = roughness;
-					mtl.metalness = metalness;
-					mtl.reflectivity = reflectivity;
-					mtl.clearCoat = clearCoat;
-					mtl.clearCoatRoughness = clearCoatRoughness;
-					mtl.environment = new THREE.CubeTextureNode( cubemap );
-					mtl.normal = new THREE.NormalMapNode( new THREE.TextureNode( getTexture( "grassNormal" ) ) );
-					mtl.normal.scale = normalMask;
+						// MATERIAL
 
-					// GUI
+						mtl = new THREE.StandardNodeMaterial();
 
-					addGui( 'color', mtl.color.value.getHex(), function ( val ) {
+						//mtl.color = // albedo (vec3)
+						//mtl.alpha = // opacity (float)
+						//mtl.roughness = // roughness (float)
+						//mtl.metalness = // metalness (float)
+						//mtl.reflectivity = // reflectivity (float)
+						//mtl.clearCoat = // clearCoat (float)
+						//mtl.clearCoatRoughness = // clearCoatRoughness (float)
+						//mtl.normal = // normal (vec3)
+						//mtl.emissive = // emissive color (vec3)
+						//mtl.ambient = // ambient color (vec3)
+						//mtl.shadow = // shadowmap (vec3)
+						//mtl.light = // custom-light (vec3)
+						//mtl.ao = // ambient occlusion (float)
+						//mtl.environment = // reflection/refraction (vec3)
+						//mtl.position = // vertex local position (vec3)
 
-						mtl.color.value.setHex( val );
+						var mask = new THREE.SwitchNode( new THREE.TextureNode( getTexture( "decalDiffuse" ) ), 'w' );
 
-					}, true );
+						var normalScale = new THREE.FloatNode( .3 );
 
-					addGui( 'reflectivity', reflectivity.value, function ( val ) {
+						var roughnessA = new THREE.FloatNode( .5 );
+						var metalnessA = new THREE.FloatNode( .5 );
 
-						reflectivity.value = val;
+						var roughnessB = new THREE.FloatNode( 0 );
+						var metalnessB = new THREE.FloatNode( 1 );
 
-					}, false, 0, 1 );
+						var reflectivity = new THREE.FloatNode( 0 );
+						var clearCoat = new THREE.FloatNode( 1 );
+						var clearCoatRoughness = new THREE.FloatNode( 1 );
 
-					addGui( 'clearCoat', clearCoat.value, function ( val ) {
+						var roughness = new THREE.Math3Node(
+							roughnessA,
+							roughnessB,
+							mask,
+							THREE.Math3Node.MIX
+						);
 
-						clearCoat.value = val;
+						var metalness = new THREE.Math3Node(
+							metalnessA,
+							metalnessB,
+							mask,
+							THREE.Math3Node.MIX
+						);
 
-					}, false, 0, 1 );
+						var normalMask = new THREE.OperatorNode(
+							new THREE.Math1Node( mask, THREE.Math1Node.INVERT ),
+							normalScale,
+							THREE.OperatorNode.MUL
+						);
 
-					addGui( 'clearCoatRoughness', clearCoatRoughness.value, function ( val ) {
+						mtl.color = new THREE.ColorNode( 0xEEEEEE );
+						mtl.roughness = roughness;
+						mtl.metalness = metalness;
+						mtl.reflectivity = reflectivity;
+						mtl.clearCoat = clearCoat;
+						mtl.clearCoatRoughness = clearCoatRoughness;
+						mtl.environment = new THREE.CubeTextureNode( cubemap );
+						mtl.normal = new THREE.NormalMapNode( new THREE.TextureNode( getTexture( "grassNormal" ) ) );
+						mtl.normal.scale = normalMask;
 
-						clearCoatRoughness.value = val;
+						// GUI
 
-					}, false, 0, 1 );
+						addGui( 'color', mtl.color.value.getHex(), function ( val ) {
 
-					addGui( 'roughnessA', roughnessA.value, function ( val ) {
+							mtl.color.value.setHex( val );
 
-						roughnessA.value = val;
+						}, true );
 
-					}, false, 0, 1 );
+						addGui( 'reflectivity', reflectivity.value, function ( val ) {
 
-					addGui( 'metalnessA', metalnessA.value, function ( val ) {
+							reflectivity.value = val;
 
-						metalnessA.value = val;
+						}, false, 0, 1 );
 
-					}, false, 0, 1 );
+						addGui( 'clearCoat', clearCoat.value, function ( val ) {
 
-					addGui( 'roughnessB', roughnessB.value, function ( val ) {
+							clearCoat.value = val;
 
-						roughnessB.value = val;
+						}, false, 0, 1 );
 
-					}, false, 0, 1 );
+						addGui( 'clearCoatRoughness', clearCoatRoughness.value, function ( val ) {
 
-					addGui( 'metalnessB', metalnessB.value, function ( val ) {
+							clearCoatRoughness.value = val;
 
-						metalnessB.value = val;
+						}, false, 0, 1 );
 
-					}, false, 0, 1 );
+						addGui( 'roughnessA', roughnessA.value, function ( val ) {
 
-					addGui( 'normalScale', normalScale.value, function ( val ) {
+							roughnessA.value = val;
 
-						normalScale.value = val;
+						}, false, 0, 1 );
 
-					}, false, 0, 1 );
+						addGui( 'metalnessA', metalnessA.value, function ( val ) {
 
-					break;
+							metalnessA.value = val;
 
-				case 'wave':
+						}, false, 0, 1 );
 
-					// MATERIAL
+						addGui( 'roughnessB', roughnessB.value, function ( val ) {
 
-					mtl = new THREE.PhongNodeMaterial();
+							roughnessB.value = val;
 
-					var time = new THREE.TimerNode();
-					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 );
+						}, false, 0, 1 );
 
-					// used for serialization only
-					time.name = "time";
-					speed.name = "speed";
+						addGui( 'metalnessB', metalnessB.value, function ( val ) {
 
-					var timeScale = new THREE.OperatorNode(
-						time,
-						speed,
-						THREE.OperatorNode.MUL
-					);
+							metalnessB.value = val;
 
-					var worldScl = new THREE.OperatorNode(
-						new THREE.PositionNode(),
-						worldScale,
-						THREE.OperatorNode.MUL
-					);
+						}, false, 0, 1 );
 
-					var posContinuous = new THREE.OperatorNode(
-						worldScl,
-						timeScale,
-						THREE.OperatorNode.ADD
-					);
+						addGui( 'normalScale', normalScale.value, function ( val ) {
 
-					var wave = new THREE.Math1Node( posContinuous, THREE.Math1Node.SIN );
-					wave = new THREE.SwitchNode( wave, 'x' );
+							normalScale.value = val;
 
-					var waveScale = new THREE.OperatorNode(
-						wave,
-						scale,
-						THREE.OperatorNode.MUL
-					);
+						}, false, 0, 1 );
 
-					var displaceY = new THREE.JoinNode(
-						new THREE.FloatNode(),
-						waveScale,
-						new THREE.FloatNode()
-					);
+						break;
 
-					var displace = new THREE.OperatorNode(
-						new THREE.NormalNode(),
-						displaceY,
-						THREE.OperatorNode.MUL
-					);
+					case 'wave':
 
-					var blend = new THREE.OperatorNode(
-						new THREE.PositionNode(),
-						displaceY,
-						THREE.OperatorNode.ADD
-					);
+						// MATERIAL
 
-					var color = new THREE.Math3Node(
-						colorB,
-						colorA,
-						wave,
-						THREE.Math3Node.MIX
-					);
+						mtl = new THREE.PhongNodeMaterial();
 
-					mtl.color = color;
-					mtl.position = blend;
+						var time = new THREE.TimerNode();
+						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 );
 
-					// GUI
+						// used for serialization only
+						time.name = "time";
+						speed.name = "speed";
 
-					addGui( 'speed', speed.value, function ( val ) {
+						var timeScale = new THREE.OperatorNode(
+							time,
+							speed,
+							THREE.OperatorNode.MUL
+						);
 
-						speed.value = val;
+						var worldScl = new THREE.OperatorNode(
+							new THREE.PositionNode(),
+							worldScale,
+							THREE.OperatorNode.MUL
+						);
 
-					}, false, 0, 10 );
+						var posContinuous = new THREE.OperatorNode(
+							worldScl,
+							timeScale,
+							THREE.OperatorNode.ADD
+						);
 
-					addGui( 'scale', scale.value, function ( val ) {
+						var wave = new THREE.Math1Node( posContinuous, THREE.Math1Node.SIN );
+						wave = new THREE.SwitchNode( wave, 'x' );
 
-						scale.value = val;
+						var waveScale = new THREE.OperatorNode(
+							wave,
+							scale,
+							THREE.OperatorNode.MUL
+						);
 
-					}, false, 0, 3 );
+						var displaceY = new THREE.JoinNode(
+							new THREE.FloatNode(),
+							waveScale,
+							new THREE.FloatNode()
+						);
 
-					addGui( 'worldScale', worldScale.value, function ( val ) {
+						var displace = new THREE.OperatorNode(
+							new THREE.NormalNode(),
+							displaceY,
+							THREE.OperatorNode.MUL
+						);
 
-						worldScale.value = val;
+						var blend = new THREE.OperatorNode(
+							new THREE.PositionNode(),
+							displaceY,
+							THREE.OperatorNode.ADD
+						);
 
-					}, false, 0, 1 );
+						var color = new THREE.Math3Node(
+							colorB,
+							colorA,
+							wave,
+							THREE.Math3Node.MIX
+						);
 
-					addGui( 'colorA', colorA.value.getHex(), function ( val ) {
+						mtl.color = color;
+						mtl.position = blend;
 
-						colorA.value.setHex( val );
+						// GUI
 
-					}, true );
+						addGui( 'speed', speed.value, function ( val ) {
 
-					addGui( 'colorB', colorB.value.getHex(), function ( val ) {
+							speed.value = val;
 
-						colorB.value.setHex( val );
+						}, false, 0, 10 );
 
-					}, true );
+						addGui( 'scale', scale.value, function ( val ) {
 
-					addGui( 'useNormals', false, function ( val ) {
+							scale.value = val;
 
-						blend.b = val ? displace : displaceY;
+						}, false, 0, 3 );
 
-						mtl.needsUpdate = true;
+						addGui( 'worldScale', worldScale.value, function ( val ) {
 
-					} );
+							worldScale.value = val;
 
-					break;
+						}, false, 0, 1 );
 
-				case 'rim':
+						addGui( 'colorA', colorA.value.getHex(), function ( val ) {
 
-					// MATERIAL
+							colorA.value.setHex( val );
 
-					mtl = new THREE.PhongNodeMaterial();
+						}, true );
 
-					var intensity = 1.3;
-					var power = new THREE.FloatNode( 3 );
-					var color = new THREE.ColorNode( 0xFFFFFF );
+						addGui( 'colorB', colorB.value.getHex(), function ( val ) {
 
-					var viewZ = new THREE.Math2Node(
-						new THREE.NormalNode( THREE.NormalNode.VIEW ),
-						new THREE.Vector3Node( 0, 0, - intensity ),
-						THREE.Math2Node.DOT
-					);
+							colorB.value.setHex( val );
 
-					var rim = new THREE.OperatorNode(
-						viewZ,
-						new THREE.FloatNode( intensity ),
-						THREE.OperatorNode.ADD
-					);
+						}, true );
 
-					var rimPower = new THREE.Math2Node(
-						rim,
-						power,
-						THREE.Math2Node.POW
-					);
+						addGui( 'useNormals', false, function ( val ) {
 
-					var rimColor = new THREE.OperatorNode(
-						rimPower,
-						color,
-						THREE.OperatorNode.MUL
-					);
+							blend.b = val ? displace : displaceY;
 
-					mtl.color = new THREE.ColorNode( 0x111111 );
-					mtl.emissive = rimColor;
+							mtl.needsUpdate = true;
 
-					// GUI
+						} );
 
-					addGui( 'color', color.value.getHex(), function ( val ) {
+						break;
 
-						color.value.setHex( val );
+					case 'rim':
 
-					}, true );
+						// MATERIAL
 
-					addGui( 'intensity', intensity, function ( val ) {
+						mtl = new THREE.PhongNodeMaterial();
 
-						intensity = val;
+						var intensity = 1.3;
+						var power = new THREE.FloatNode( 3 );
+						var color = new THREE.ColorNode( 0xFFFFFF );
 
-						viewZ.b.z = - intensity;
-						rim.b.value = intensity;
+						var viewZ = new THREE.Math2Node(
+							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 ),
+							THREE.OperatorNode.ADD
+						);
 
-					}, false, 0, 3 );
+						var rimPower = new THREE.Math2Node(
+							rim,
+							power,
+							THREE.Math2Node.POW
+						);
 
-					addGui( 'power', power.value, function ( val ) {
+						var rimColor = new THREE.OperatorNode(
+							rimPower,
+							color,
+							THREE.OperatorNode.MUL
+						);
 
-						power.value = val;
+						mtl.color = new THREE.ColorNode( 0x111111 );
+						mtl.emissive = rimColor;
 
-					}, false, 0, 6 );
+						// GUI
 
-					addGui( 'xray', false, function ( val ) {
+						addGui( 'color', color.value.getHex(), function ( val ) {
 
-						if ( val ) {
+							color.value.setHex( val );
 
-							mtl.emissive = color;
-							mtl.alpha = rimPower;
-							mtl.blending = THREE.AdditiveBlending;
-							mtl.depthWrite = false;
+						}, true );
 
-						}				else {
+						addGui( 'intensity', intensity, function ( val ) {
 
-							mtl.emissive = rimColor;
-							mtl.alpha = null;
-							mtl.blending = THREE.NormalBlending;
-							mtl.depthWrite = true;
+							intensity = val;
 
-						}
+							viewZ.b.z = - intensity;
+							rim.b.value = intensity;
 
-						mtl.needsUpdate = true;
 
-					} );
+						}, false, 0, 3 );
 
-					break;
+						addGui( 'power', power.value, function ( val ) {
 
-				case 'color-adjustment':
+							power.value = val;
 
-					// MATERIAL
+						}, false, 0, 6 );
 
-					mtl = new THREE.PhongNodeMaterial();
+						addGui( 'xray', false, function ( val ) {
 
-					var texture = new THREE.TextureNode( getTexture( "brick" ) );
+							if ( val ) {
 
-					var hue = new THREE.FloatNode();
-					var sataturation = new THREE.FloatNode( 1 );
-					var vibrance = new THREE.FloatNode();
-					var brightness = new THREE.FloatNode( 0 );
-					var contrast = new THREE.FloatNode( 1 );
+								mtl.emissive = color;
+								mtl.alpha = rimPower;
+								mtl.blending = THREE.AdditiveBlending;
+								mtl.depthWrite = false;
 
-					var hueNode = new THREE.ColorAdjustmentNode( texture, hue, THREE.ColorAdjustmentNode.HUE );
-					var satNode = new THREE.ColorAdjustmentNode( hueNode, sataturation, THREE.ColorAdjustmentNode.SATURATION );
-					var vibranceNode = new THREE.ColorAdjustmentNode( satNode, vibrance, THREE.ColorAdjustmentNode.VIBRANCE );
-					var brightnessNode = new THREE.ColorAdjustmentNode( vibranceNode, brightness, THREE.ColorAdjustmentNode.BRIGHTNESS );
-					var contrastNode = new THREE.ColorAdjustmentNode( brightnessNode, contrast, THREE.ColorAdjustmentNode.CONTRAST );
+							}				else {
 
-					mtl.color = contrastNode;
+								mtl.emissive = rimColor;
+								mtl.alpha = null;
+								mtl.blending = THREE.NormalBlending;
+								mtl.depthWrite = true;
 
-					// GUI
+							}
 
-					addGui( 'hue', hue.value, function ( val ) {
+							mtl.needsUpdate = true;
 
-						hue.value = val;
+						} );
 
-					}, false, 0, Math.PI * 2 );
+						break;
 
-					addGui( 'saturation', sataturation.value, function ( val ) {
+					case 'color-adjustment':
 
-						sataturation.value = val;
+						// MATERIAL
 
-					}, false, 0, 2 );
+						mtl = new THREE.PhongNodeMaterial();
 
-					addGui( 'vibrance', vibrance.value, function ( val ) {
+						var texture = new THREE.TextureNode( getTexture( "brick" ) );
 
-						vibrance.value = val;
+						var hue = new THREE.FloatNode();
+						var sataturation = new THREE.FloatNode( 1 );
+						var vibrance = new THREE.FloatNode();
+						var brightness = new THREE.FloatNode( 0 );
+						var contrast = new THREE.FloatNode( 1 );
 
-					}, false, - 1, 1 );
+						var hueNode = new THREE.ColorAdjustmentNode( texture, hue, THREE.ColorAdjustmentNode.HUE );
+						var satNode = new THREE.ColorAdjustmentNode( hueNode, sataturation, THREE.ColorAdjustmentNode.SATURATION );
+						var vibranceNode = new THREE.ColorAdjustmentNode( satNode, vibrance, THREE.ColorAdjustmentNode.VIBRANCE );
+						var brightnessNode = new THREE.ColorAdjustmentNode( vibranceNode, brightness, THREE.ColorAdjustmentNode.BRIGHTNESS );
+						var contrastNode = new THREE.ColorAdjustmentNode( brightnessNode, contrast, THREE.ColorAdjustmentNode.CONTRAST );
 
-					addGui( 'brightness', brightness.value, function ( val ) {
+						mtl.color = contrastNode;
 
-						brightness.value = val;
+						// GUI
 
-					}, false, 0, .5 );
+						addGui( 'hue', hue.value, function ( val ) {
 
-					addGui( 'contrast', contrast.value, function ( val ) {
+							hue.value = val;
 
-						contrast.value = val;
+						}, false, 0, Math.PI * 2 );
 
-					}, false, 0, 2 );
+						addGui( 'saturation', sataturation.value, function ( val ) {
 
-					break;
+							sataturation.value = val;
 
-				case 'uv-transform':
+						}, false, 0, 2 );
 
-					// MATERIAL
+						addGui( 'vibrance', vibrance.value, function ( val ) {
 
-					mtl = new THREE.PhongNodeMaterial();
+							vibrance.value = val;
 
-					var translate = new THREE.Vector2();
-					var rotate = 0;
-					var scale = new THREE.Vector2( 1, 1 );
+						}, false, - 1, 1 );
 
-					var texture = new THREE.TextureNode( getTexture( "brick" ) );
-					texture.uv = new THREE.UVTransformNode();
-					//texture.uv.uv = new THREE.UVNode( 1 ); // uv2 for example
+						addGui( 'brightness', brightness.value, function ( val ) {
 
-					mtl.color = texture;
+							brightness.value = val;
 
-					// GUI
+						}, false, 0, .5 );
 
-					function updateUVTransform() {
+						addGui( 'contrast', contrast.value, function ( val ) {
 
-						texture.uv.setUvTransform( translate.x, translate.y, scale.x, scale.y, THREE.Math.degToRad( rotate ) );
+							contrast.value = val;
 
-					}
+						}, false, 0, 2 );
 
-					addGui( 'translateX', translate.x, function ( val ) {
+						break;
 
-						translate.x = val;
+					case 'uv-transform':
 
-						updateUVTransform();
+						// MATERIAL
 
-					}, false, 0, 10 );
+						mtl = new THREE.PhongNodeMaterial();
 
-					addGui( 'translateY', translate.y, function ( val ) {
+						var translate = new THREE.Vector2();
+						var rotate = 0;
+						var scale = new THREE.Vector2( 1, 1 );
 
-						translate.y = val;
+						var texture = new THREE.TextureNode( getTexture( "brick" ) );
+						texture.uv = new THREE.UVTransformNode();
+						//texture.uv.uv = new THREE.UVNode( 1 ); // uv2 for example
 
-						updateUVTransform();
+						mtl.color = texture;
 
-					}, false, 0, 10 );
+						// GUI
 
-					addGui( 'scaleX', scale.x, function ( val ) {
+						function updateUVTransform() {
 
-						scale.x = val;
+							texture.uv.setUvTransform( translate.x, translate.y, scale.x, scale.y, THREE.Math.degToRad( rotate ) );
 
-						updateUVTransform();
+						}
 
-					}, false, .1, 5 );
+						addGui( 'translateX', translate.x, function ( val ) {
 
-					addGui( 'scaleY', scale.y, function ( val ) {
+							translate.x = val;
 
-						scale.y = val;
+							updateUVTransform();
 
-						updateUVTransform();
+						}, false, 0, 10 );
 
-					}, false, .1, 5 );
+						addGui( 'translateY', translate.y, function ( val ) {
 
-					addGui( 'rotate', rotate, function ( val ) {
+							translate.y = val;
 
-						rotate = val;
+							updateUVTransform();
 
-						updateUVTransform();
+						}, false, 0, 10 );
 
-					}, false, 0, 360 );
+						addGui( 'scaleX', scale.x, function ( val ) {
 
-					break;
+							scale.x = val;
 
-				case 'bump':
+							updateUVTransform();
 
-					// MATERIAL
+						}, false, .1, 5 );
 
-					mtl = new THREE.PhongNodeMaterial();
+						addGui( 'scaleY', scale.y, function ( val ) {
 
-					var diffuse = new THREE.TextureNode( getTexture( "brick" ) );
+							scale.y = val;
 
-					var bumpMap = new THREE.BumpMapNode( new THREE.TextureNode( getTexture( "brick" ) ) );
-					bumpMap.scale = new THREE.FloatNode( .5 );
+							updateUVTransform();
 
-					mtl.color = diffuse;
-					mtl.normal = bumpMap;
+						}, false, .1, 5 );
 
-					// convert BumpMap to NormalMap
-					//bumpMap.toNormalMap = true;
-					//mtl.normal = new THREE.NormalMapNode( bumpMap );
-					
-					// GUI
+						addGui( 'rotate', rotate, function ( val ) {
 
-					addGui( 'scale', bumpMap.scale.value, function ( val ) {
+							rotate = val;
 
-						bumpMap.scale.value = val;
+							updateUVTransform();
 
-					}, false, - 2, 2 );
+						}, false, 0, 360 );
 
-					addGui( 'color', true, function ( val ) {
+						break;
 
-						mtl.color = val ? diffuse : new THREE.ColorNode( 0xEEEEEE );
+					case 'bump':
 
-						mtl.needsUpdate = true;
+						// MATERIAL
 
-					} );
+						mtl = new THREE.PhongNodeMaterial();
 
-					break;
+						var diffuse = new THREE.TextureNode( getTexture( "brick" ) );
 
-				case 'blur':
+						var bumpMap = new THREE.BumpMapNode( new THREE.TextureNode( getTexture( "brick" ) ) );
+						bumpMap.scale = new THREE.FloatNode( .5 );
 
-					// MATERIAL
+						mtl.color = diffuse;
+						mtl.normal = bumpMap;
 
-					mtl = new THREE.PhongNodeMaterial();
+						// convert BumpMap to NormalMap
+						//bumpMap.toNormalMap = true;
+						//mtl.normal = new THREE.NormalMapNode( bumpMap );
 
-					var diffuse = new THREE.TextureNode( getTexture( "brick" ) );
+						// GUI
 
-					var blur = new THREE.BlurNode( new THREE.TextureNode( getTexture( "brick" ) ) );
+						addGui( 'scale', bumpMap.scale.value, function ( val ) {
 
-					mtl.color = blur;
+							bumpMap.scale.value = val;
 
-					// GUI
+						}, false, - 2, 2 );
 
-					addGui( 'radiusX', blur.radius.x, function ( val ) {
+						addGui( 'color', true, function ( val ) {
 
-						blur.radius.x = val;
+							mtl.color = val ? diffuse : new THREE.ColorNode( 0xEEEEEE );
 
-					}, false, 0, 15 );
+							mtl.needsUpdate = true;
 
-					addGui( 'radiusY', blur.radius.y, function ( val ) {
+						} );
 
-						blur.radius.y = val;
+						break;
 
-					}, false, 0, 15 );
+					case 'blur':
 
-					break;
+						// MATERIAL
 
-				case 'spherical-reflection':
+						mtl = new THREE.PhongNodeMaterial();
 
-					// MATERIAL
+						var diffuse = new THREE.TextureNode( getTexture( "brick" ) );
 
-					mtl = new THREE.PhongNodeMaterial();
+						var blur = new THREE.BlurNode( new THREE.TextureNode( getTexture( "brick" ) ) );
 
-					mtl.environment = new THREE.TextureNode( getTexture( "spherical" ), new THREE.ReflectNode( THREE.ReflectNode.SPHERE ) );
+						mtl.color = blur;
 
-					break;
+						// GUI
 
-				case 'fresnel':
+						addGui( 'radiusX', blur.radius.x, function ( val ) {
 
-					// MATERIAL
+							blur.radius.x = val;
 
-					mtl = new THREE.PhongNodeMaterial();
+						}, false, 0, 15 );
 
-					var reflectance = new THREE.FloatNode( 1.3 );
-					var power = new THREE.FloatNode( 1 );
-					var color = new THREE.CubeTextureNode( cubemap );
+						addGui( 'radiusY', blur.radius.y, function ( val ) {
 
-					var viewZ = new THREE.Math2Node(
-						new THREE.NormalNode( THREE.NormalNode.VIEW ),
-						new THREE.Vector3Node( 0, 0, - 1 ),
-						THREE.Math2Node.DOT
-					);
+							blur.radius.y = val;
 
-					var theta = new THREE.OperatorNode(
-						viewZ,
-						new THREE.FloatNode( 1 ),
-						THREE.OperatorNode.ADD
-					);
+						}, false, 0, 15 );
 
-					var thetaPower = new THREE.Math2Node(
-						theta,
-						power,
-						THREE.Math2Node.POW
-					);
+						break;
 
-					var fresnel = new THREE.OperatorNode(
-						reflectance,
-						thetaPower,
-						THREE.OperatorNode.MUL
-					);
+					case 'spherical-reflection':
 
-					mtl.color = new THREE.ColorNode( 0x3399FF );
-					mtl.environment = color;
-					mtl.environmentAlpha = new THREE.Math1Node( fresnel, THREE.Math1Node.SAT );
+						// MATERIAL
 
-					// GUI
+						mtl = new THREE.PhongNodeMaterial();
 
-					addGui( 'reflectance', reflectance.value, function ( val ) {
+						mtl.environment = new THREE.TextureNode( getTexture( "spherical" ), new THREE.ReflectNode( THREE.ReflectNode.SPHERE ) );
 
-						reflectance.value = val;
+						break;
 
-					}, false, 0, 3 );
+					case 'fresnel':
 
-					addGui( 'power', power.value, function ( val ) {
+						// MATERIAL
 
-						power.value = val;
+						mtl = new THREE.PhongNodeMaterial();
 
-					}, false, 0, 5 );
+						var reflectance = new THREE.FloatNode( 1.3 );
+						var power = new THREE.FloatNode( 1 );
+						var color = new THREE.CubeTextureNode( cubemap );
 
-					break;
+						var viewZ = new THREE.Math2Node(
+							new THREE.NormalNode( THREE.NormalNode.VIEW ),
+							new THREE.Vector3Node( 0, 0, - 1 ),
+							THREE.Math2Node.DOT
+						);
 
-				case 'layers':
+						var theta = new THREE.OperatorNode(
+							viewZ,
+							new THREE.FloatNode( 1 ),
+							THREE.OperatorNode.ADD
+						);
 
-					// MATERIAL
+						var thetaPower = new THREE.Math2Node(
+							theta,
+							power,
+							THREE.Math2Node.POW
+						);
 
-					mtl = new THREE.PhongNodeMaterial();
+						var fresnel = new THREE.OperatorNode(
+							reflectance,
+							thetaPower,
+							THREE.OperatorNode.MUL
+						);
 
-					var tex1 = new THREE.TextureNode( getTexture( "grass" ) );
-					var tex2 = new THREE.TextureNode( getTexture( "brick" ) );
+						mtl.color = new THREE.ColorNode( 0x3399FF );
+						mtl.environment = color;
+						mtl.environmentAlpha = new THREE.Math1Node( fresnel, THREE.Math1Node.SAT );
 
-					var offset = new THREE.FloatNode( 0 );
-					var scale = new THREE.FloatNode( 1 );
-					var uv = new THREE.UVNode();
+						// GUI
 
-					var uvOffset = new THREE.OperatorNode(
-						offset,
-						uv,
-						THREE.OperatorNode.ADD
-					);
+						addGui( 'reflectance', reflectance.value, function ( val ) {
 
-					var uvScale = new THREE.OperatorNode(
-						uvOffset,
-						scale,
-						THREE.OperatorNode.MUL
-					);
+							reflectance.value = val;
 
-					var mask = new THREE.TextureNode( getTexture( "decalDiffuse" ), uvScale );
-					var maskAlphaChannel = new THREE.SwitchNode( mask, 'w' );
+						}, false, 0, 3 );
 
-					var blend = new THREE.Math3Node(
-						tex1,
-						tex2,
-						maskAlphaChannel,
-						THREE.Math3Node.MIX
-					);
+						addGui( 'power', power.value, function ( val ) {
 
-					mtl.color = blend;
+							power.value = val;
 
-					// GUI
+						}, false, 0, 5 );
 
-					addGui( 'offset', offset.value, function ( val ) {
+						break;
 
-						offset.value = val;
+					case 'layers':
 
-					}, false, 0, 1 );
+						// MATERIAL
 
-					addGui( 'scale', scale.value, function ( val ) {
+						mtl = new THREE.PhongNodeMaterial();
 
-						scale.value = val;
+						var tex1 = new THREE.TextureNode( getTexture( "grass" ) );
+						var tex2 = new THREE.TextureNode( getTexture( "brick" ) );
 
-					}, false, 0, 10 );
+						var offset = new THREE.FloatNode( 0 );
+						var scale = new THREE.FloatNode( 1 );
+						var uv = new THREE.UVNode();
 
-					break;
+						var uvOffset = new THREE.OperatorNode(
+							offset,
+							uv,
+							THREE.OperatorNode.ADD
+						);
 
-				case 'saturation':
+						var uvScale = new THREE.OperatorNode(
+							uvOffset,
+							scale,
+							THREE.OperatorNode.MUL
+						);
 
-					// MATERIAL
+						var mask = new THREE.TextureNode( getTexture( "decalDiffuse" ), uvScale );
+						var maskAlphaChannel = new THREE.SwitchNode( mask, 'w' );
 
-					mtl = new THREE.StandardNodeMaterial();
+						var blend = new THREE.Math3Node(
+							tex1,
+							tex2,
+							maskAlphaChannel,
+							THREE.Math3Node.MIX
+						);
 
-					var tex = new THREE.TextureNode( getTexture( "brick" ) );
-					var sat = new THREE.FloatNode( 0 );
+						mtl.color = blend;
 
-					var satrgb = new THREE.FunctionNode( [
-						"vec3 satrgb( vec3 rgb, float adjustment ) {",
-						// include luminance function from LuminanceNode
-						"	vec3 intensity = vec3( luminance( rgb ) );",
-						"	return mix( intensity, rgb, adjustment );",
-						"}"
-					].join( "\n" ), [ THREE.LuminanceNode.Nodes.luminance ] );
+						// GUI
 
-					var saturation = new THREE.FunctionCallNode( satrgb );
-					saturation.inputs.rgb = tex;
-					saturation.inputs.adjustment = sat;
+						addGui( 'offset', offset.value, function ( val ) {
 
-					// or try
+							offset.value = val;
 
-					//saturation.inputs[0] = tex;
-					//saturation.inputs[1] = sat;
+						}, false, 0, 1 );
 
-					mtl.color = saturation;
+						addGui( 'scale', scale.value, function ( val ) {
 
-					// GUI
+							scale.value = val;
 
-					addGui( 'saturation', sat.value, function ( val ) {
+						}, false, 0, 10 );
 
-						sat.value = val;
+						break;
 
-					}, false, 0, 2 );
+					case 'saturation':
 
-					break;
+						// MATERIAL
 
-				case 'top-bottom':
+						mtl = new THREE.StandardNodeMaterial();
 
-					// MATERIAL
+						var tex = new THREE.TextureNode( getTexture( "brick" ) );
+						var sat = new THREE.FloatNode( 0 );
 
-					mtl = new THREE.PhongNodeMaterial();
+						var satrgb = new THREE.FunctionNode( [
+							"vec3 satrgb( vec3 rgb, float adjustment ) {",
+							// include luminance function from LuminanceNode
+							"	vec3 intensity = vec3( luminance( rgb ) );",
+							"	return mix( intensity, rgb, adjustment );",
+							"}"
+						].join( "\n" ), [ THREE.LuminanceNode.Nodes.luminance ] );
 
-					var top = new THREE.TextureNode( getTexture( "grass" ) );
-					var bottom = new THREE.TextureNode( getTexture( "brick" ) );
+						var saturation = new THREE.FunctionCallNode( satrgb );
+						saturation.inputs.rgb = tex;
+						saturation.inputs.adjustment = sat;
 
-					var normal = new THREE.NormalNode( THREE.NormalNode.WORLD );
-					var normalY = new THREE.SwitchNode( normal, 'y' );
+						// or try
 
-					var hard = new THREE.FloatNode( 9 );
-					var offset = new THREE.FloatNode( - 2.5 );
+						//saturation.inputs[0] = tex;
+						//saturation.inputs[1] = sat;
 
-					var hardClamp = new THREE.OperatorNode(
-						normalY,
-						hard,
-						THREE.OperatorNode.MUL
-					);
+						mtl.color = saturation;
 
-					var offsetClamp = new THREE.OperatorNode(
-						hardClamp,
-						offset,
-						THREE.OperatorNode.ADD
-					);
+						// GUI
 
-					var clamp0at1 = new THREE.Math1Node( offsetClamp, THREE.Math1Node.SAT );
+						addGui( 'saturation', sat.value, function ( val ) {
 
-					var blend = new THREE.Math3Node( top, bottom, clamp0at1, THREE.Math3Node.MIX );
+							sat.value = val;
 
-					mtl.color = blend;
+						}, false, 0, 2 );
 
-					// GUI
+						break;
 
-					addGui( 'hard', hard.value, function ( val ) {
+					case 'top-bottom':
 
-						hard.value = val;
+						// MATERIAL
 
-					}, false, 0, 20 );
+						mtl = new THREE.PhongNodeMaterial();
 
-					addGui( 'offset', offset.value, function ( val ) {
+						var top = new THREE.TextureNode( getTexture( "grass" ) );
+						var bottom = new THREE.TextureNode( getTexture( "brick" ) );
 
-						offset.value = val;
+						var normal = new THREE.NormalNode( THREE.NormalNode.WORLD );
+						var normalY = new THREE.SwitchNode( normal, 'y' );
 
-					}, false, - 10, 10 );
+						var hard = new THREE.FloatNode( 9 );
+						var offset = new THREE.FloatNode( - 2.5 );
 
-					break;
+						var hardClamp = new THREE.OperatorNode(
+							normalY,
+							hard,
+							THREE.OperatorNode.MUL
+						);
 
-				case 'displace':
+						var offsetClamp = new THREE.OperatorNode(
+							hardClamp,
+							offset,
+							THREE.OperatorNode.ADD
+						);
 
-					// MATERIAL
+						var clamp0at1 = new THREE.Math1Node( offsetClamp, THREE.Math1Node.SAT );
 
-					mtl = new THREE.PhongNodeMaterial();
+						var blend = new THREE.Math3Node( top, bottom, clamp0at1, THREE.Math3Node.MIX );
 
-					var time = new THREE.TimerNode();
-					var scale = new THREE.FloatNode( 2 );
-					var speed = new THREE.FloatNode( .2 );
-					var colorA = new THREE.ColorNode( 0xFFFFFF );
-					var colorB = new THREE.ColorNode( 0x0054df );
+						mtl.color = blend;
 
-					// used for serialization only
-					time.name = "time";
-					speed.name = "speed";
+						// GUI
 
-					var uv = new THREE.UVNode();
+						addGui( 'hard', hard.value, function ( val ) {
 
-					var timeScl = new THREE.OperatorNode(
-						time,
-						speed,
-						THREE.OperatorNode.MUL
-					);
+							hard.value = val;
 
-					var displaceOffset = new THREE.OperatorNode(
-						timeScl,
-						uv,
-						THREE.OperatorNode.ADD
-					);
+						}, false, 0, 20 );
 
-					var tex = new THREE.TextureNode( getTexture( "cloud" ), displaceOffset );
-					var texArea = new THREE.SwitchNode( tex, 'w' );
+						addGui( 'offset', offset.value, function ( val ) {
 
-					var displace = new THREE.OperatorNode(
-						new THREE.NormalNode(),
-						texArea,
-						THREE.OperatorNode.MUL
-					);
+							offset.value = val;
 
-					var displaceScale = new THREE.OperatorNode(
-						displace,
-						scale,
-						THREE.OperatorNode.MUL
-					);
+						}, false, - 10, 10 );
 
-					var blend = new THREE.OperatorNode(
-						new THREE.PositionNode(),
-						displaceScale,
-						THREE.OperatorNode.ADD
-					);
+						break;
 
-					var color = new THREE.Math3Node(
-						colorB,
-						colorA,
-						texArea,
-						THREE.Math3Node.MIX
-					);
+					case 'displace':
 
-					mtl.color = mtl.specular = new THREE.ColorNode( 0 );
-					mtl.emissive = color;
-					mtl.position = blend;
+						// MATERIAL
 
-					// GUI
+						mtl = new THREE.PhongNodeMaterial();
 
-					addGui( 'speed', speed.value, function ( val ) {
+						var time = new THREE.TimerNode();
+						var scale = new THREE.FloatNode( 2 );
+						var speed = new THREE.FloatNode( .2 );
+						var colorA = new THREE.ColorNode( 0xFFFFFF );
+						var colorB = new THREE.ColorNode( 0x0054df );
 
-						speed.value = val;
+						// used for serialization only
+						time.name = "time";
+						speed.name = "speed";
 
-					}, false, 0, 1 );
+						var uv = new THREE.UVNode();
 
-					addGui( 'scale', scale.value, function ( val ) {
+						var timeScl = new THREE.OperatorNode(
+							time,
+							speed,
+							THREE.OperatorNode.MUL
+						);
 
-						scale.value = val;
+						var displaceOffset = new THREE.OperatorNode(
+							timeScl,
+							uv,
+							THREE.OperatorNode.ADD
+						);
 
-					}, false, 0, 10 );
+						var tex = new THREE.TextureNode( getTexture( "cloud" ), displaceOffset );
+						var texArea = new THREE.SwitchNode( tex, 'w' );
 
-					addGui( 'colorA', colorA.value.getHex(), function ( val ) {
+						var displace = new THREE.OperatorNode(
+							new THREE.NormalNode(),
+							texArea,
+							THREE.OperatorNode.MUL
+						);
 
-						colorA.value.setHex( val );
+						var displaceScale = new THREE.OperatorNode(
+							displace,
+							scale,
+							THREE.OperatorNode.MUL
+						);
 
-					}, true );
+						var blend = new THREE.OperatorNode(
+							new THREE.PositionNode(),
+							displaceScale,
+							THREE.OperatorNode.ADD
+						);
 
-					addGui( 'colorB', colorB.value.getHex(), function ( val ) {
+						var color = new THREE.Math3Node(
+							colorB,
+							colorA,
+							texArea,
+							THREE.Math3Node.MIX
+						);
 
-						colorB.value.setHex( val );
+						mtl.color = mtl.specular = new THREE.ColorNode( 0 );
+						mtl.emissive = color;
+						mtl.position = blend;
 
-					}, true );
+						// GUI
 
-					break;
+						addGui( 'speed', speed.value, function ( val ) {
 
-				case 'smoke':
+							speed.value = val;
 
-					// MATERIAL
+						}, false, 0, 1 );
 
-					mtl = new THREE.PhongNodeMaterial();
+						addGui( 'scale', scale.value, function ( val ) {
 
-					var time = new THREE.TimerNode();
-					var uv = new THREE.UVNode();
+							scale.value = val;
 
-					var timeSpeedA = new THREE.OperatorNode(
-						time,
-						new THREE.Vector2Node( 0.3, 0.1 ),
-						THREE.OperatorNode.MUL
-					);
+						}, false, 0, 10 );
 
-					var timeSpeedB = new THREE.OperatorNode(
-						time,
-						new THREE.Vector2Node( 0.15, 0.4 ),
-						THREE.OperatorNode.MUL
-					);
+						addGui( 'colorA', colorA.value.getHex(), function ( val ) {
 
-					var uvOffsetA = new THREE.OperatorNode(
-						timeSpeedA,
-						uv,
-						THREE.OperatorNode.ADD
-					);
+							colorA.value.setHex( val );
 
-					var uvOffsetB = new THREE.OperatorNode(
-						timeSpeedB,
-						uv,
-						THREE.OperatorNode.ADD
-					);
+						}, true );
 
-					var cloudA = new THREE.TextureNode( getTexture( "cloud" ), uvOffsetA );
-					var cloudB = new THREE.TextureNode( getTexture( "cloud" ), uvOffsetB );
+						addGui( 'colorB', colorB.value.getHex(), function ( val ) {
 
-					var clouds = new THREE.OperatorNode(
-						cloudA,
-						cloudB,
-						THREE.OperatorNode.ADD
-					);
+							colorB.value.setHex( val );
 
-					mtl.environment = new THREE.ColorNode( 0xFFFFFF );
-					mtl.alpha = clouds;
+						}, true );
 
-					// GUI
+						break;
 
-					addGui( 'color', mtl.environment.value.getHex(), function ( val ) {
+					case 'smoke':
 
-						mtl.environment.value.setHex( val );
+						// MATERIAL
 
-					}, true );
+						mtl = new THREE.PhongNodeMaterial();
 
-					break;
+						var time = new THREE.TimerNode();
+						var uv = new THREE.UVNode();
 
-				case 'camera-depth':
+						var timeSpeedA = new THREE.OperatorNode(
+							time,
+							new THREE.Vector2Node( 0.3, 0.1 ),
+							THREE.OperatorNode.MUL
+						);
 
-					// MATERIAL
+						var timeSpeedB = new THREE.OperatorNode(
+							time,
+							new THREE.Vector2Node( 0.15, 0.4 ),
+							THREE.OperatorNode.MUL
+						);
 
-					var colorA = new THREE.ColorNode( 0xFFFFFF );
-					var colorB = new THREE.ColorNode( 0x0054df );
+						var uvOffsetA = new THREE.OperatorNode(
+							timeSpeedA,
+							uv,
+							THREE.OperatorNode.ADD
+						);
 
-					var depth = new THREE.CameraNode( THREE.CameraNode.DEPTH );
-					depth.near.value = 1;
-					depth.far.value = 200;
+						var uvOffsetB = new THREE.OperatorNode(
+							timeSpeedB,
+							uv,
+							THREE.OperatorNode.ADD
+						);
 
-					var colors = new THREE.Math3Node(
-						colorB,
-						colorA,
-						depth,
-						THREE.Math3Node.MIX
-					);
+						var cloudA = new THREE.TextureNode( getTexture( "cloud" ), uvOffsetA );
+						var cloudB = new THREE.TextureNode( getTexture( "cloud" ), uvOffsetB );
 
-					mtl = new THREE.PhongNodeMaterial();
-					mtl.color = colors;
+						var clouds = new THREE.OperatorNode(
+							cloudA,
+							cloudB,
+							THREE.OperatorNode.ADD
+						);
 
-					// GUI
+						mtl.environment = new THREE.ColorNode( 0xFFFFFF );
+						mtl.alpha = clouds;
 
-					addGui( 'near', depth.near.value, function ( val ) {
+						// GUI
 
-						depth.near.value = val;
+						addGui( 'color', mtl.environment.value.getHex(), function ( val ) {
 
-					}, false, 1, 1200 );
+							mtl.environment.value.setHex( val );
 
-					addGui( 'far', depth.far.value, function ( val ) {
+						}, true );
 
-						depth.far.value = val;
+						break;
 
-					}, false, 1, 1200 );
+					case 'camera-depth':
 
-					addGui( 'nearColor', colorA.value.getHex(), function ( val ) {
+						// MATERIAL
 
-						colorA.value.setHex( val );
+						var colorA = new THREE.ColorNode( 0xFFFFFF );
+						var colorB = new THREE.ColorNode( 0x0054df );
 
-					}, true );
+						var depth = new THREE.CameraNode( THREE.CameraNode.DEPTH );
+						depth.near.value = 1;
+						depth.far.value = 200;
 
-					addGui( 'farColor', colorB.value.getHex(), function ( val ) {
+						var colors = new THREE.Math3Node(
+							colorB,
+							colorA,
+							depth,
+							THREE.Math3Node.MIX
+						);
 
-						colorB.value.setHex( val );
+						mtl = new THREE.PhongNodeMaterial();
+						mtl.color = colors;
 
-					}, true );
+						// GUI
 
-					break;
+						addGui( 'near', depth.near.value, function ( val ) {
 
-				case 'caustic':
+							depth.near.value = val;
 
-					// MATERIAL
+						}, false, 1, 1200 );
 
-					mtl = new THREE.StandardNodeMaterial();
+						addGui( 'far', depth.far.value, function ( val ) {
 
-					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" ) );
+							depth.far.value = val;
 
-					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);",
-						"	vec2 f = fract(p);",
-						"	float md = 5.0;",
-						"	vec2 m = vec2(0.0);",
-						"	for (int i = -1; i <= 1; i++) {",
-						"		for (int j = -1; j <= 1; j++) {",
-						"			vec2 g = vec2(i, j);",
-						"			vec2 o = hash2(n + g);",
-						"			o = 0.5 + 0.5 * sin(time + 5.038 * o);",
-						"			vec2 r = g + o - f;",
-						"			float d = dot(r, r);",
-						"			if (d < md) {",
-						"				md = d;",
-						"				m = n+g+o;",
-						"			}",
-						"		}",
-						"	}",
-						"	return md;",
-						"}"
-					].join( "\n" ), [ hash2 ] ); // define hash2 as dependencies
+						}, false, 1, 1200 );
 
-					var voronoiLayers = new THREE.FunctionNode( [
-						// based on https://www.shadertoy.com/view/4tXSDf
-						"float voronoiLayers(vec2 p, in float time) {",
-						"	float v = 0.0;",
-						"	float a = 0.4;",
-						"	for (int i = 0; i < 3; i++) {",
-						"		v += voronoi(p, time) * a;",
-						"		p *= 2.0;",
-						"		a *= 0.5;",
-						"	}",
-						"	return v;",
-						"}"
-					].join( "\n" ), [ voronoi ] ); // define voronoi as dependencies
+						addGui( 'nearColor', colorA.value.getHex(), function ( val ) {
 
-					var time = new THREE.TimerNode();
-					var timeScale = new THREE.FloatNode( 2 );
+							colorA.value.setHex( val );
 
-					// used for serialization only
-					time.name = "time";
-					timeScale.name = "speed";
+						}, true );
 
-					var alpha = new THREE.FloatNode( 1 );
-					var scale = new THREE.FloatNode( .1 );
-					var intensity = new THREE.FloatNode( 1.5 );
+						addGui( 'farColor', colorB.value.getHex(), function ( val ) {
 
-					var color = new THREE.ColorNode( 0xFFFFFF );
-					var colorA = new THREE.ColorNode( 0xFFFFFF );
-					var colorB = new THREE.ColorNode( 0x0054df );
+							colorB.value.setHex( val );
 
-					var worldPos = new THREE.PositionNode( THREE.PositionNode.WORLD );
-					var worldPosTop = new THREE.SwitchNode( worldPos, 'xz' );
+						}, true );
 
-					var worldNormal = new THREE.NormalNode( THREE.NormalNode.WORLD );
+						break;
 
-					var mask = new THREE.SwitchNode( worldNormal, 'y' );
+					case 'caustic':
 
-					// clamp0at1
-					mask = new THREE.Math1Node( mask, THREE.Math1Node.SAT );
+						// MATERIAL
 
-					var timeOffset = new THREE.OperatorNode(
-						time,
-						timeScale,
-						THREE.OperatorNode.MUL
-					);
+						mtl = new THREE.StandardNodeMaterial();
 
-					var uvPos = new THREE.OperatorNode(
-						worldPosTop,
-						scale,
-						THREE.OperatorNode.MUL
-					);
+						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.FunctionCallNode( voronoiLayers );
-					voronoi.inputs.p = uvPos;
-					voronoi.inputs.time = timeOffset;
+						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);",
+							"	vec2 f = fract(p);",
+							"	float md = 5.0;",
+							"	vec2 m = vec2(0.0);",
+							"	for (int i = -1; i <= 1; i++) {",
+							"		for (int j = -1; j <= 1; j++) {",
+							"			vec2 g = vec2(i, j);",
+							"			vec2 o = hash2(n + g);",
+							"			o = 0.5 + 0.5 * sin(time + 5.038 * o);",
+							"			vec2 r = g + o - f;",
+							"			float d = dot(r, r);",
+							"			if (d < md) {",
+							"				md = d;",
+							"				m = n+g+o;",
+							"			}",
+							"		}",
+							"	}",
+							"	return md;",
+							"}"
+						].join( "\n" ), [ hash2 ] ); // define hash2 as dependencies
 
-					var maskCaustic = new THREE.OperatorNode(
-						alpha,
-						mask,
-						THREE.OperatorNode.MUL
-					);
+						var voronoiLayers = new THREE.FunctionNode( [
+							// based on https://www.shadertoy.com/view/4tXSDf
+							"float voronoiLayers(vec2 p, in float time) {",
+							"	float v = 0.0;",
+							"	float a = 0.4;",
+							"	for (int i = 0; i < 3; i++) {",
+							"		v += voronoi(p, time) * a;",
+							"		p *= 2.0;",
+							"		a *= 0.5;",
+							"	}",
+							"	return v;",
+							"}"
+						].join( "\n" ), [ voronoi ] ); // define voronoi as dependencies
 
-					var voronoiIntensity = new THREE.OperatorNode(
-						voronoi,
-						intensity,
-						THREE.OperatorNode.MUL
-					);
+						var time = new THREE.TimerNode();
+						var timeScale = new THREE.FloatNode( 2 );
 
-					var voronoiColors = new THREE.Math3Node(
-						colorB,
-						colorA,
-						new THREE.Math1Node( voronoiIntensity, THREE.Math1Node.SAT ), // mix needs clamp
-						THREE.Math3Node.MIX
-					);
+						// used for serialization only
+						time.name = "time";
+						timeScale.name = "speed";
 
-					var caustic = new THREE.Math3Node(
-						color,
-						voronoiColors,
-						maskCaustic,
-						THREE.Math3Node.MIX
-					);
+						var alpha = new THREE.FloatNode( 1 );
+						var scale = new THREE.FloatNode( .1 );
+						var intensity = new THREE.FloatNode( 1.5 );
 
-					var causticLights = new THREE.OperatorNode(
-						voronoiIntensity,
-						maskCaustic,
-						THREE.OperatorNode.MUL
-					);
+						var color = new THREE.ColorNode( 0xFFFFFF );
+						var colorA = new THREE.ColorNode( 0xFFFFFF );
+						var colorB = new THREE.ColorNode( 0x0054df );
 
-					mtl.color = caustic;
-					mtl.ambient = causticLights;
+						var worldPos = new THREE.PositionNode( THREE.PositionNode.WORLD );
+						var worldPosTop = new THREE.SwitchNode( worldPos, 'xz' );
 
-					// GUI
+						var worldNormal = new THREE.NormalNode( THREE.NormalNode.WORLD );
 
-					addGui( 'timeScale', timeScale.value, function ( val ) {
+						var mask = new THREE.SwitchNode( worldNormal, 'y' );
 
-						timeScale.value = val;
+						// clamp0at1
+						mask = new THREE.Math1Node( mask, THREE.Math1Node.SAT );
 
-					}, false, 0, 5 );
+						var timeOffset = new THREE.OperatorNode(
+							time,
+							timeScale,
+							THREE.OperatorNode.MUL
+						);
 
-					addGui( 'intensity', intensity.value, function ( val ) {
+						var uvPos = new THREE.OperatorNode(
+							worldPosTop,
+							scale,
+							THREE.OperatorNode.MUL
+						);
 
-						intensity.value = val;
+						var voronoi = new THREE.FunctionCallNode( voronoiLayers );
+						voronoi.inputs.p = uvPos;
+						voronoi.inputs.time = timeOffset;
 
-					}, false, 0, 3 );
+						var maskCaustic = new THREE.OperatorNode(
+							alpha,
+							mask,
+							THREE.OperatorNode.MUL
+						);
 
-					addGui( 'scale', scale.value, function ( val ) {
+						var voronoiIntensity = new THREE.OperatorNode(
+							voronoi,
+							intensity,
+							THREE.OperatorNode.MUL
+						);
 
-						scale.value = val;
+						var voronoiColors = new THREE.Math3Node(
+							colorB,
+							colorA,
+							new THREE.Math1Node( voronoiIntensity, THREE.Math1Node.SAT ), // mix needs clamp
+							THREE.Math3Node.MIX
+						);
 
-					}, false, 0, 1 );
+						var caustic = new THREE.Math3Node(
+							color,
+							voronoiColors,
+							maskCaustic,
+							THREE.Math3Node.MIX
+						);
 
-					addGui( 'alpha', alpha.value, function ( val ) {
+						var causticLights = new THREE.OperatorNode(
+							voronoiIntensity,
+							maskCaustic,
+							THREE.OperatorNode.MUL
+						);
 
-						alpha.value = val;
+						mtl.color = caustic;
+						mtl.ambient = causticLights;
 
-					}, false, 0, 1 );
+						// GUI
 
-					addGui( 'color', color.value.getHex(), function ( val ) {
+						addGui( 'timeScale', timeScale.value, function ( val ) {
 
-						color.value.setHex( val );
+							timeScale.value = val;
 
-					}, true );
+						}, false, 0, 5 );
 
-					addGui( 'colorA', colorA.value.getHex(), function ( val ) {
+						addGui( 'intensity', intensity.value, function ( val ) {
 
-						colorA.value.setHex( val );
+							intensity.value = val;
 
-					}, true );
+						}, false, 0, 3 );
 
-					addGui( 'colorB', colorB.value.getHex(), function ( val ) {
+						addGui( 'scale', scale.value, function ( val ) {
 
-						colorB.value.setHex( val );
+							scale.value = val;
 
-					}, true );
+						}, false, 0, 1 );
 
-					break;
+						addGui( 'alpha', alpha.value, function ( val ) {
 
-				case 'soft-body':
+							alpha.value = val;
 
-					// MATERIAL
+						}, false, 0, 1 );
 
-					move = true;
+						addGui( 'color', color.value.getHex(), function ( val ) {
 
-					mtl = new THREE.StandardNodeMaterial();
+							color.value.setHex( val );
 
-					var scale = new THREE.FloatNode( 2 );
-					var colorA = new THREE.ColorNode( 0xFF6633 );
-					var colorB = new THREE.ColorNode( 0x3366FF );
+						}, true );
 
-					var pos = new THREE.PositionNode();
-					var posNorm = new THREE.Math1Node( pos, THREE.Math1Node.NORMALIZE );
+						addGui( 'colorA', colorA.value.getHex(), function ( val ) {
 
-					var mask = new THREE.SwitchNode( posNorm, 'y' );
+							colorA.value.setHex( val );
 
-					var velocity = new THREE.VelocityNode( mesh, {
-						type: 'elastic',
-						spring: .95,
-						damping: .95
-					} );
+						}, true );
 
-					var velocityArea = new THREE.OperatorNode(
-						mask,
-						scale,
-						THREE.OperatorNode.MUL
-					);
+						addGui( 'colorB', colorB.value.getHex(), function ( val ) {
 
-					var softVelocity = new THREE.OperatorNode(
-						velocity,
-						velocityArea,
-						THREE.OperatorNode.MUL
-					);
+							colorB.value.setHex( val );
 
-					var softPosition = new THREE.OperatorNode(
-						new THREE.PositionNode(),
-						softVelocity,
-						THREE.OperatorNode.ADD
-					);
+						}, true );
 
-					var colors = new THREE.Math3Node(
-						colorB,
-						colorA,
-						mask,
-						THREE.Math3Node.MIX
-					);
+						break;
 
-					mtl.color = colors;
-					mtl.position = softPosition;
+					case 'soft-body':
 
-					// GUI
+						// MATERIAL
 
-					addGui( 'spring', velocity.params.spring, function ( val ) {
+						move = true;
 
-						velocity.params.spring = val;
+						mtl = new THREE.StandardNodeMaterial();
 
-					}, false, 0, .95 );
+						var scale = new THREE.FloatNode( 2 );
+						var colorA = new THREE.ColorNode( 0xFF6633 );
+						var colorB = new THREE.ColorNode( 0x3366FF );
 
-					addGui( 'damping', velocity.params.damping, function ( val ) {
+						var pos = new THREE.PositionNode();
+						var posNorm = new THREE.Math1Node( pos, THREE.Math1Node.NORMALIZE );
 
-						velocity.params.damping = val;
+						var mask = new THREE.SwitchNode( posNorm, 'y' );
 
-					}, false, 0, .95 );
+						var velocity = new THREE.VelocityNode( mesh, {
+							type: 'elastic',
+							spring: .95,
+							damping: .95
+						} );
 
-					addGui( 'scale', scale.value, function ( val ) {
+						var velocityArea = new THREE.OperatorNode(
+							mask,
+							scale,
+							THREE.OperatorNode.MUL
+						);
 
-						scale.value = val;
+						var softVelocity = new THREE.OperatorNode(
+							velocity,
+							velocityArea,
+							THREE.OperatorNode.MUL
+						);
 
-					}, false, 0, 3 );
+						var softPosition = new THREE.OperatorNode(
+							new THREE.PositionNode(),
+							softVelocity,
+							THREE.OperatorNode.ADD
+						);
 
-					addGui( 'softBody', colorA.value.getHex(), function ( val ) {
+						var colors = new THREE.Math3Node(
+							colorB,
+							colorA,
+							mask,
+							THREE.Math3Node.MIX
+						);
 
-						colorA.value.setHex( val );
+						mtl.color = colors;
+						mtl.position = softPosition;
 
-					}, true );
+						// GUI
 
-					addGui( 'rigidBody', colorB.value.getHex(), function ( val ) {
+						addGui( 'spring', velocity.params.spring, function ( val ) {
 
-						colorB.value.setHex( val );
+							velocity.params.spring = val;
 
-					}, true );
+						}, false, 0, .95 );
 
-					break;
+						addGui( 'damping', velocity.params.damping, function ( val ) {
 
-				case 'plush':
+							velocity.params.damping = val;
 
-					// MATERIAL
+						}, false, 0, .95 );
 
-					mtl = new THREE.PhongNodeMaterial();
+						addGui( 'scale', scale.value, function ( val ) {
 
-					var color = new THREE.ColorNode( 0x8D8677 );
-					var mildness = new THREE.FloatNode( 1.6 );
-					var fur = new THREE.FloatNode( .5 );
+							scale.value = val;
 
-					var posDirection = new THREE.Math1Node( new THREE.PositionNode( THREE.PositionNode.VIEW ), THREE.Math1Node.NORMALIZE );
-					var norDirection = new THREE.Math1Node( new THREE.NormalNode( THREE.NormalNode.VIEW ), THREE.Math1Node.NORMALIZE );
+						}, false, 0, 3 );
 
-					var viewZ = new THREE.Math2Node(
-						posDirection,
-						norDirection,
-						THREE.Math2Node.DOT
-					);
+						addGui( 'softBody', colorA.value.getHex(), function ( val ) {
 
-					// without luma correction for now
-					var mildnessColor = new THREE.OperatorNode(
-						color,
-						mildness,
-						THREE.OperatorNode.MUL
-					);
+							colorA.value.setHex( val );
 
-					var furScale = new THREE.OperatorNode(
-						viewZ,
-						fur,
-						THREE.OperatorNode.MUL
-					);
+						}, true );
 
-					mtl.color = color;
-					mtl.normal = new THREE.NormalMapNode( new THREE.TextureNode( getTexture( "grassNormal" ) ) );
-					mtl.normal.scale = furScale;
-					mtl.environment = mildnessColor;
-					mtl.environmentAlpha = new THREE.Math1Node( viewZ, THREE.Math1Node.INVERT );
-					mtl.shininess = new THREE.FloatNode( 0 );
+						addGui( 'rigidBody', colorB.value.getHex(), function ( val ) {
 
-					// GUI
+							colorB.value.setHex( val );
 
-					addGui( 'color', color.value.getHex(), function ( val ) {
+						}, true );
 
-						color.value.setHex( val );
+						break;
 
-					}, true );
+					case 'plush':
 
-					addGui( 'mildness', mildness.value, function ( val ) {
+						// MATERIAL
 
-						mildness.value = val;
+						mtl = new THREE.PhongNodeMaterial();
 
-					}, false, 1, 2 );
+						var color = new THREE.ColorNode( 0x8D8677 );
+						var mildness = new THREE.FloatNode( 1.6 );
+						var fur = new THREE.FloatNode( .5 );
 
-					addGui( 'fur', fur.value, function ( val ) {
+						var posDirection = new THREE.Math1Node( new THREE.PositionNode( THREE.PositionNode.VIEW ), THREE.Math1Node.NORMALIZE );
+						var norDirection = new THREE.Math1Node( new THREE.NormalNode( THREE.NormalNode.VIEW ), THREE.Math1Node.NORMALIZE );
 
-						fur.value = val;
+						var viewZ = new THREE.Math2Node(
+							posDirection,
+							norDirection,
+							THREE.Math2Node.DOT
+						);
 
-					}, false, 0, 2 );
+						// without luma correction for now
+						var mildnessColor = new THREE.OperatorNode(
+							color,
+							mildness,
+							THREE.OperatorNode.MUL
+						);
 
-					break;
+						var furScale = new THREE.OperatorNode(
+							viewZ,
+							fur,
+							THREE.OperatorNode.MUL
+						);
 
-				case 'skin':
-				case 'skin-phong':
+						mtl.color = color;
+						mtl.normal = new THREE.NormalMapNode( new THREE.TextureNode( getTexture( "grassNormal" ) ) );
+						mtl.normal.scale = furScale;
+						mtl.environment = mildnessColor;
+						mtl.environmentAlpha = new THREE.Math1Node( viewZ, THREE.Math1Node.INVERT );
+						mtl.shininess = new THREE.FloatNode( 0 );
 
-					// MATERIAL
+						// GUI
 
-					mtl = name == 'skin' ? new THREE.StandardNodeMaterial() : new THREE.PhongNodeMaterial();
+						addGui( 'color', color.value.getHex(), function ( val ) {
 
-					var skinColor = new THREE.ColorNode( 0xFFC495 );
-					var bloodColor = new THREE.ColorNode( 0x6b0602 );
-					var wrapLight = new THREE.FloatNode( 1.5 );
-					var wrapShadow = new THREE.FloatNode( 0 );
+							color.value.setHex( val );
 
-					var directLight = new THREE.LightNode();
+						}, true );
 
-					var lightLuminance = new THREE.LuminanceNode( directLight );
+						addGui( 'mildness', mildness.value, function ( val ) {
 
-					var lightWrap = new THREE.Math3Node(
-						wrapShadow,
-						wrapLight,
-						lightLuminance,
-						THREE.Math3Node.SMOOTHSTEP
-					);
+							mildness.value = val;
 
-					var lightTransition = new THREE.OperatorNode(
-						lightWrap,
-						new THREE.ConstNode( THREE.ConstNode.PI2 ),
-						THREE.OperatorNode.MUL
-					);
+						}, false, 1, 2 );
 
-					var wrappedLight = new THREE.Math1Node( lightTransition, THREE.Math1Node.SIN );
+						addGui( 'fur', fur.value, function ( val ) {
 
-					var wrappedLightColor = new THREE.OperatorNode(
-						wrappedLight,
-						bloodColor,
-						THREE.OperatorNode.MUL
-					);
+							fur.value = val;
 
-					var bloodArea = new THREE.Math1Node( wrappedLightColor, THREE.Math1Node.SAT );
+						}, false, 0, 2 );
 
-					var totalLight = new THREE.OperatorNode(
-						directLight,
-						bloodArea,
-						THREE.OperatorNode.ADD
-					);
+						break;
 
-					mtl.color = skinColor;
-					mtl.light = totalLight;
+					case 'skin':
+					case 'skin-phong':
 
-					if ( name == 'skin' ) {
+						// MATERIAL
 
-						// StandardNodeMaterial
+						mtl = name == 'skin' ? new THREE.StandardNodeMaterial() : new THREE.PhongNodeMaterial();
 
-						mtl.metalness = new THREE.FloatNode( 0 );
-						mtl.roughness = new THREE.FloatNode( 1 );
-						mtl.reflectivity = new THREE.FloatNode( 0 );
-						mtl.clearCoat = new THREE.FloatNode( .2 );
-						mtl.clearCoatRoughness = new THREE.FloatNode( .3 );
-						mtl.environment = new THREE.CubeTextureNode( cubemap );
+						var skinColor = new THREE.ColorNode( 0xFFC495 );
+						var bloodColor = new THREE.ColorNode( 0x6b0602 );
+						var wrapLight = new THREE.FloatNode( 1.5 );
+						var wrapShadow = new THREE.FloatNode( 0 );
 
-					} else {
+						var directLight = new THREE.LightNode();
 
-						// PhongNodeMaterial
+						var lightLuminance = new THREE.LuminanceNode( directLight );
 
-						mtl.specular = new THREE.ColorNode( 0x2f2e2d );
-						mtl.shininess = new THREE.FloatNode( 15 );
+						var lightWrap = new THREE.Math3Node(
+							wrapShadow,
+							wrapLight,
+							lightLuminance,
+							THREE.Math3Node.SMOOTHSTEP
+						);
 
-					}
+						var lightTransition = new THREE.OperatorNode(
+							lightWrap,
+							new THREE.ConstNode( THREE.ConstNode.PI2 ),
+							THREE.OperatorNode.MUL
+						);
 
-					// GUI
+						var wrappedLight = new THREE.Math1Node( lightTransition, THREE.Math1Node.SIN );
 
-					addGui( 'skinColor', skinColor.value.getHex(), function ( val ) {
+						var wrappedLightColor = new THREE.OperatorNode(
+							wrappedLight,
+							bloodColor,
+							THREE.OperatorNode.MUL
+						);
 
-						skinColor.value.setHex( val );
+						var bloodArea = new THREE.Math1Node( wrappedLightColor, THREE.Math1Node.SAT );
 
-					}, true );
+						var totalLight = new THREE.OperatorNode(
+							directLight,
+							bloodArea,
+							THREE.OperatorNode.ADD
+						);
 
-					addGui( 'bloodColor', bloodColor.value.getHex(), function ( val ) {
+						mtl.color = skinColor;
+						mtl.light = totalLight;
 
-						bloodColor.value.setHex( val );
+						if ( name == 'skin' ) {
 
-					}, true );
+							// StandardNodeMaterial
 
-					addGui( 'wrapLight', wrapLight.value, function ( val ) {
+							mtl.metalness = new THREE.FloatNode( 0 );
+							mtl.roughness = new THREE.FloatNode( 1 );
+							mtl.reflectivity = new THREE.FloatNode( 0 );
+							mtl.clearCoat = new THREE.FloatNode( .2 );
+							mtl.clearCoatRoughness = new THREE.FloatNode( .3 );
+							mtl.environment = new THREE.CubeTextureNode( cubemap );
 
-						wrapLight.value = val;
+						} else {
 
-					}, false, 0, 3 );
+							// PhongNodeMaterial
 
-					addGui( 'wrapShadow', wrapShadow.value, function ( val ) {
+							mtl.specular = new THREE.ColorNode( 0x2f2e2d );
+							mtl.shininess = new THREE.FloatNode( 15 );
 
-						wrapShadow.value = val;
+						}
 
-					}, false, - 1, 0 );
+						// GUI
 
-					break;
+						addGui( 'skinColor', skinColor.value.getHex(), function ( val ) {
 
-				case 'toon':
+							skinColor.value.setHex( val );
 
-					// MATERIAL
+						}, true );
 
-					mtl = new THREE.PhongNodeMaterial();
+						addGui( 'bloodColor', bloodColor.value.getHex(), function ( val ) {
 
-					var count = new THREE.FloatNode( 3.43 );
-					var sceneDirectLight = new THREE.LightNode();
-					var color = new THREE.ColorNode( 0xAABBFF );
+							bloodColor.value.setHex( val );
 
-					var lineColor = new THREE.ColorNode( 0xFF0000 );
-					var lineSize = new THREE.FloatNode( 0.23 );
-					var lineInner = new THREE.FloatNode( 0 );
+						}, true );
 
-					// CEL
+						addGui( 'wrapLight', wrapLight.value, function ( val ) {
 
-					var lightLuminance = new THREE.LuminanceNode( sceneDirectLight );
+							wrapLight.value = val;
 
-					var preCelLight = new THREE.OperatorNode(
-						lightLuminance,
-						count,
-						THREE.OperatorNode.MUL
-					);
+						}, false, 0, 3 );
 
-					var celLight = new THREE.Math1Node(
-						preCelLight,
-						THREE.Math1Node.CEIL
-					);
+						addGui( 'wrapShadow', wrapShadow.value, function ( val ) {
 
-					var posCelLight = new THREE.OperatorNode(
-						celLight,
-						count,
-						THREE.OperatorNode.DIV
-					);
+							wrapShadow.value = val;
 
-					// LINE
+						}, false, - 1, 0 );
 
-					var posDirection = new THREE.Math1Node( new THREE.PositionNode( THREE.PositionNode.VIEW ), THREE.Math1Node.NORMALIZE );
-					var norDirection = new THREE.Math1Node( new THREE.NormalNode( THREE.NormalNode.VIEW ), THREE.Math1Node.NORMALIZE );
+						break;
 
-					var viewZ = new THREE.Math2Node(
-						posDirection,
-						norDirection,
-						THREE.Math2Node.DOT
-					);
+					case 'toon':
 
-					var lineOutside = new THREE.Math1Node(
-						viewZ,
-						THREE.Math1Node.ABS
-					);
+						// MATERIAL
 
-					var line = new THREE.OperatorNode(
-						lineOutside,
-						new THREE.FloatNode( 1 ),
-						THREE.OperatorNode.DIV
-					);
+						mtl = new THREE.PhongNodeMaterial();
 
-					var lineScaled = new THREE.Math3Node(
-						line,
-						lineSize,
-						lineInner,
-						THREE.Math3Node.SMOOTHSTEP
-					);
+						var count = new THREE.FloatNode( 3.43 );
+						var sceneDirectLight = new THREE.LightNode();
+						var color = new THREE.ColorNode( 0xAABBFF );
 
-					var innerContour = new THREE.Math1Node( new THREE.Math1Node( lineScaled, THREE.Math1Node.SAT ), THREE.Math1Node.INVERT );
+						var lineColor = new THREE.ColorNode( 0xFF0000 );
+						var lineSize = new THREE.FloatNode( 0.23 );
+						var lineInner = new THREE.FloatNode( 0 );
 
-					// APPLY
+						// CEL
 
-					mtl.color = color;
-					mtl.light = posCelLight;
-					mtl.shininess = new THREE.FloatNode( 0 );
+						var lightLuminance = new THREE.LuminanceNode( sceneDirectLight );
 
-					mtl.environment = lineColor;
-					mtl.environmentAlpha = innerContour;
+						var preCelLight = new THREE.OperatorNode(
+							lightLuminance,
+							count,
+							THREE.OperatorNode.MUL
+						);
 
-					// GUI
+						var celLight = new THREE.Math1Node(
+							preCelLight,
+							THREE.Math1Node.CEIL
+						);
 
-					addGui( 'color', color.value.getHex(), function ( val ) {
+						var posCelLight = new THREE.OperatorNode(
+							celLight,
+							count,
+							THREE.OperatorNode.DIV
+						);
 
-						color.value.setHex( val );
+						// LINE
 
-					}, true );
+						var posDirection = new THREE.Math1Node( new THREE.PositionNode( THREE.PositionNode.VIEW ), THREE.Math1Node.NORMALIZE );
+						var norDirection = new THREE.Math1Node( new THREE.NormalNode( THREE.NormalNode.VIEW ), THREE.Math1Node.NORMALIZE );
 
-					addGui( 'lineColor', lineColor.value.getHex(), function ( val ) {
+						var viewZ = new THREE.Math2Node(
+							posDirection,
+							norDirection,
+							THREE.Math2Node.DOT
+						);
 
-						lineColor.value.setHex( val );
+						var lineOutside = new THREE.Math1Node(
+							viewZ,
+							THREE.Math1Node.ABS
+						);
 
-					}, true );
+						var line = new THREE.OperatorNode(
+							lineOutside,
+							new THREE.FloatNode( 1 ),
+							THREE.OperatorNode.DIV
+						);
 
-					addGui( 'count', count.value, function ( val ) {
+						var lineScaled = new THREE.Math3Node(
+							line,
+							lineSize,
+							lineInner,
+							THREE.Math3Node.SMOOTHSTEP
+						);
 
-						count.value = val;
+						var innerContour = new THREE.Math1Node( new THREE.Math1Node( lineScaled, THREE.Math1Node.SAT ), THREE.Math1Node.INVERT );
 
-					}, false, 1, 8 );
+						// APPLY
 
-					addGui( 'lineSize', lineSize.value, function ( val ) {
+						mtl.color = color;
+						mtl.light = posCelLight;
+						mtl.shininess = new THREE.FloatNode( 0 );
 
-						lineSize.value = val;
+						mtl.environment = lineColor;
+						mtl.environmentAlpha = innerContour;
 
-					}, false, 0, 1 );
+						// GUI
 
-					addGui( 'lineInner', lineInner.value, function ( val ) {
+						addGui( 'color', color.value.getHex(), function ( val ) {
 
-						lineInner.value = val;
+							color.value.setHex( val );
 
-					}, false, 0, 1 );
+						}, true );
 
-					addGui( 'ignoreIndirectLight', false, function ( val ) {
+						addGui( 'lineColor', lineColor.value.getHex(), function ( val ) {
 
-						mtl.ao = val ? new THREE.FloatNode() : undefined;
+							lineColor.value.setHex( val );
 
-						mtl.needsUpdate = true;
+						}, true );
 
-					} );
+						addGui( 'count', count.value, function ( val ) {
 
-					break;
+							count.value = val;
 
-				case 'custom-attribute':
+						}, false, 1, 8 );
 
-					// GEOMETRY
+						addGui( 'lineSize', lineSize.value, function ( val ) {
 
-					// add "position" buffer to "custom" attribute
-					teapot.attributes[ 'custom' ] = teapot.attributes[ 'position' ];
+							lineSize.value = val;
 
-					// MATERIAL
+						}, false, 0, 1 );
 
-					mtl = new THREE.PhongNodeMaterial();
+						addGui( 'lineInner', lineInner.value, function ( val ) {
 
-					mtl.color = new THREE.AttributeNode( "custom", 3 );
+							lineInner.value = val;
 
-					// or
+						}, false, 0, 1 );
 
-					//mtl.color = new THREE.AttributeNode( "custom", "vec3" );
+						addGui( 'ignoreIndirectLight', false, function ( val ) {
 
-					break;
+							mtl.ao = val ? new THREE.FloatNode() : undefined;
 
-				case 'expression':
+							mtl.needsUpdate = true;
 
-					// MATERIAL
+						} );
 
-					mtl = new THREE.PhongNodeMaterial();
+						break;
 
-					var speed = new THREE.FloatNode( .5 );
+					case 'custom-attribute':
 
-					mtl.color = new THREE.ExpressionNode( "myCustomUv + (sin(time*speed)*.5) + (position * .05)", "vec3" );
-					mtl.color.keywords[ "speed" ] = speed;
+						// GEOMETRY
 
-					mtl.position = new THREE.ExpressionNode( "mod(time*speed,1.0) < 0.5 ? position + (worldNormal*(1.0+sin(time*speed*1.0))*3.0) : position + sin( position.x * sin(time*speed*2.0))", "vec3" );
-					mtl.position.keywords[ "speed" ] = speed;
+						// add "position" buffer to "custom" attribute
+						teapot.attributes[ 'custom' ] = teapot.attributes[ 'position' ];
 
-					// add global keyword ( variable or const )
-					THREE.NodeLib.addKeyword( 'myCustomUv', function ( builder ) {
+						// MATERIAL
 
-						return new THREE.ReflectNode();
+						mtl = new THREE.PhongNodeMaterial();
 
-					} );
+						mtl.color = new THREE.AttributeNode( "custom", 3 );
 
-					// GUI
+						// or
 
-					addGui( 'speed', speed.value, function ( val ) {
+						//mtl.color = new THREE.AttributeNode( "custom", "vec3" );
 
-						speed.value = val;
+						break;
 
-					}, false, 0, 1 );
+					case 'expression':
 
-					break;
+						// MATERIAL
 
-				case 'reserved-keywords':
+						mtl = new THREE.PhongNodeMaterial();
 
-					// MATERIAL
+						var speed = new THREE.FloatNode( .5 );
 
-					mtl = new THREE.PhongNodeMaterial();
+						mtl.color = new THREE.ExpressionNode( "myCustomUv + (sin(time*speed)*.5) + (position * .05)", "vec3" );
+						mtl.color.keywords[ "speed" ] = speed;
 
-					var keywordsexample = new THREE.FunctionNode( [
-						// use "uv" reserved keyword
-						"vec4 keywordsexample( sampler2D texture ) {",
-						"	return texture2D( texture, myUV ) + vec4( position * myAlpha, 0.0 );",
-						"}"
-					].join( "\n" ) );
+						mtl.position = new THREE.ExpressionNode( "mod(time*speed,1.0) < 0.5 ? position + (worldNormal*(1.0+sin(time*speed*1.0))*3.0) : position + sin( position.x * sin(time*speed*2.0))", "vec3" );
+						mtl.position.keywords[ "speed" ] = speed;
 
-					// add local keyword ( const only )
-					keywordsexample.keywords[ "myAlpha" ] = new THREE.ConstNode( "float myAlpha .05" );
+						// add global keyword ( variable or const )
+						THREE.NodeLib.addKeyword( 'myCustomUv', function ( builder ) {
 
-					// add global keyword ( const only )
-					THREE.NodeLib.addKeyword( 'myUV', function ( builder ) {
+							return new THREE.ReflectNode();
 
-						return new THREE.UVNode();
+						} );
 
-					} );
+						// GUI
 
-					// add global const or function
-					//THREE.NodeLib.add( new THREE.ConstNode("float MY_CONST .05") )
-
-					// reserved keywords
-					console.log( THREE.NodeLib.keywords );
-
-					// keywords conflit? use this to disable:
-					//blurtexture.useKeywords = false; // ( true is default )
-
-					mtl.color = new THREE.FunctionCallNode( keywordsexample, [ new THREE.TextureNode( getTexture( "brick" ) ) ] );
-
-					break;
-					
-				case 'varying':
-
-					// MATERIAL
-
-					mtl = new THREE.PhongNodeMaterial();
-
-					var varying = new THREE.VarNode( "vec3" );
-					varying.value = new THREE.NormalNode( THREE.NormalNode.VIEW );
-					
-					// using BypassNode the NormalNode not apply the value in .position slot
-					// but set the NormalNode value in VarNode
-					// it can be useful to send values between vertex to fragment shader
-					// without affect vertex shader
-					mtl.position = new THREE.BypassNode( varying );
-					mtl.color = varying;
-					
-					// you can also set a independent value in .position slot using BypassNode
-					// such this expression using ExpressionNode
-					mtl.position.value = new THREE.ExpressionNode("position * ( .1 + abs( sin( time ) ) )", "vec3");
-
-					break;
-					
-				case 'void-function':
-
-					// MATERIAL
-
-					mtl = new THREE.PhongNodeMaterial();
-
-					var varying = new THREE.VarNode( "vec3" );
-
-					// VERTEX
-					
-					var setMyVar = new THREE.FunctionNode( [
-						"void setMyVar( vec3 pos ) {",
-						// set "myVar" in vertex shader in this example,
-						// can be used in fragment shader too or in rest of the current shader
-						"	myVar = pos;",
-						
-						"}"
-					].join( "\n" ) );
-
-					// add keyword
-					setMyVar.keywords[ "myVar" ] = varying;
-
-					var position = new THREE.ExpressionNode( "setMyVar( position * .1 )", "vec3" );
-					position.includes = [ setMyVar ];
-					position.keywords[ "tex" ] = new THREE.TextureNode( getTexture( "brick" ) );
-
-					// use BypassNode to "void" functions
-					mtl.position = new THREE.BypassNode( position );
-					
-					// FRAGMENT
-					
-					var clipFromPos = new THREE.FunctionNode( [
-						"void clipFromPos( vec3 pos ) {",
-						
-						"	if ( pos.y < .0 ) discard;",
-						
-						"}"
-					].join( "\n" ) );
-					
-					var clipFromPosCall = new THREE.FunctionCallNode( clipFromPos, {
-						pos: varying
-					} );
-					
-					mtl.color = new THREE.BypassNode( clipFromPosCall, varying );
+						addGui( 'speed', speed.value, function ( val ) {
 
-					break;	
-				
-				case 'conditional':
+							speed.value = val;
 
-					// MATERIAL
+						}, false, 0, 1 );
 
-					mtl = new THREE.PhongNodeMaterial();
+						break;
 
-					var a = new THREE.FloatNode( 0 ),
-						b = new THREE.FloatNode( 0 ),
-						ifNode = new THREE.ColorNode( 0x0000FF ),
-						elseNode = new THREE.ColorNode( 0xFF0000 );
-					
-					var cond = new THREE.CondNode( a, b, ifNode, elseNode, THREE.CondNode.EQUAL );
-					
-					mtl.color = cond;
+					case 'reserved-keywords':
 
-					// GUI
-					
-					addGui( 'a', a.value, function ( val ) {
+						// MATERIAL
 
-						a.value = val;
+						mtl = new THREE.PhongNodeMaterial();
 
-					}, false, 0, 1 );
-					
-					addGui( 'b', b.value, function ( val ) {
+						var keywordsexample = new THREE.FunctionNode( [
+							// use "uv" reserved keyword
+							"vec4 keywordsexample( sampler2D texture ) {",
+							"	return texture2D( texture, myUV ) + vec4( position * myAlpha, 0.0 );",
+							"}"
+						].join( "\n" ) );
 
-						b.value = val;
+						// add local keyword ( const only )
+						keywordsexample.keywords[ "myAlpha" ] = new THREE.ConstNode( "float myAlpha .05" );
 
-					}, false, 0, 1 );
-					
-					addGui( 'a condition b', {
-						EQUAL: THREE.CondNode.EQUAL,
-						NOT_EQUAL: THREE.CondNode.NOT_EQUAL,
-						GREATER: THREE.CondNode.GREATER,
-						GREATER_EQUAL: THREE.CondNode.GREATER_EQUAL,
-						LESS: THREE.CondNode.LESS,
-						LESS_EQUAL: THREE.CondNode.LESS_EQUAL
-					}, function ( val ) {
+						// add global keyword ( const only )
+						THREE.NodeLib.addKeyword( 'myUV', function ( builder ) {
 
-						cond.op = val;
-						
-						mtl.needsUpdate = true;
+							return new THREE.UVNode();
 
-					} );
-					
-					addGui( 'if color', ifNode.value.getHex(), function ( val ) {
+						} );
 
-						ifNode.value.setHex( val );
+						// add global const or function
+						//THREE.NodeLib.add( new THREE.ConstNode("float MY_CONST .05") )
 
-					}, true );
+						// reserved keywords
+						console.log( THREE.NodeLib.keywords );
 
-					addGui( 'else color', elseNode.value.getHex(), function ( val ) {
+						// keywords conflit? use this to disable:
+						//blurtexture.useKeywords = false; // ( true is default )
 
-						elseNode.value.setHex( val );
+						mtl.color = new THREE.FunctionCallNode( keywordsexample, [ new THREE.TextureNode( getTexture( "brick" ) ) ] );
 
-					}, true );
-					
-					break;
-				
-				case 'rtt':
+						break;
 
-					// MATERIAL
+					case 'varying':
 
-					mtl = new THREE.PhongNodeMaterial();
+						// MATERIAL
 
-					var uvTransform = new THREE.UVTransformNode(),
-						checker = new THREE.CheckerNode( uvTransform );
-					
-					uvTransform.setUvTransform( 0, 0, 2, 2, 0 );
-					
-					var rtt = new THREE.RTTNode( 512, 512, checker ),
-						bumpMap = new THREE.BumpMapNode( rtt );
-					
-					bumpMap.scale.value = .1;
-					
-					mtl.color = checker;
-					mtl.normal = bumpMap;
-					
-					// GUI
-					
-					addGui( 'bump', bumpMap.scale.value, function ( val ) {
+						mtl = new THREE.PhongNodeMaterial();
 
-						bumpMap.scale.value = val;
+						var varying = new THREE.VarNode( "vec3" );
+						varying.value = new THREE.NormalNode( THREE.NormalNode.VIEW );
 
-					}, false, - .5, .5 );
-					
-					addGui( 'scale', 2, function ( val ) {
+						// using BypassNode the NormalNode not apply the value in .position slot
+						// but set the NormalNode value in VarNode
+						// it can be useful to send values between vertex to fragment shader
+						// without affect vertex shader
+						mtl.position = new THREE.BypassNode( varying );
+						mtl.color = varying;
 
-						uvTransform.setUvTransform( 0, 0, val, val, 0 );
+						// you can also set a independent value in .position slot using BypassNode
+						// such this expression using ExpressionNode
+						mtl.position.value = new THREE.ExpressionNode( "position * ( .1 + abs( sin( time ) ) )", "vec3" );
 
-					}, false, 0, 8 );
-					
-					addGui( 'ignoreColor', false, function ( val ) {
+						break;
 
-						mtl.color = val ? new THREE.ColorNode( 0xFFFFFF ) : checker;
+					case 'void-function':
 
-						mtl.needsUpdate = true;
+						// MATERIAL
 
-					} );
-					
-					break;
-				
-				case 'temporal-blur':
-
-					// MATERIAL
-
-					mtl = new THREE.PhongNodeMaterial();
-
-					var texture = new THREE.TextureNode( getTexture( "brick" ) );
-					
-					var rttStore = new THREE.RTTNode( 512, 512, texture );
-					var blur = new THREE.BlurNode( rttStore );
-					
-					var timer = new THREE.TimerNode( .01, THREE.TimerNode.LOCAL );
-					
-					var color = new THREE.Math3Node(
-						rttStore,
-						blur,
-						new THREE.FloatNode( .6 ),
-						THREE.Math3Node.MIX
-					);
-					
-					blur.horizontal = blur.vertical = timer;
-					
-					var rttSave = new THREE.RTTNode( 512, 512, color );
-					rttSave.saveTo = rttStore;
-					
-					mtl.color = rttSave;
-
-					// GUI
-					
-					addGui( 'click to reset', false, function ( val ) {
-
-						// render a single time
-						
-						rttStore.render = true;
-						
-						// reset time blur
-						
-						timer.value = 0;
+						mtl = new THREE.PhongNodeMaterial();
 
-					} );
-					
-					break;
-				
-				case 'readonly':
-
-					// MATERIAL
-
-					mtl = new THREE.PhongNodeMaterial();
-
-					mtl.color = new THREE.ColorNode( 0xFFFFFF );
-					mtl.specular = new THREE.FloatNode( .5 );
-					mtl.shininess = new THREE.FloatNode( 15 );
-
-					// not use "uniform" input ( for optimization ) 
-					// instead use explicit declaration, for example: 
-					// vec3( 1.0, 1.0, 1.0 ) instead "uniform vec3"
-					// if readonly is true not allow change the value after build the shader material
-					mtl.color.readonly = mtl.specular.readonly = mtl.shininess.readonly = true;
-
-					break;
-
-				case 'triangle-blur':
-
-					// MATERIAL
-
-					mtl = new THREE.PhongNodeMaterial();
-
-					var delta = new THREE.Vector2Node( .5, .25 );
-					var alpha = new THREE.FloatNode( 1 );
-
-					var blurtexture = new THREE.FunctionNode( [
-						// Reference: TriangleBlurShader.js
-						"vec4 blurtexture(sampler2D texture, vec2 uv, vec2 delta) {",
-						"	vec4 color = vec4( 0.0 );",
-						"	float total = 0.0;",
-						// randomize the lookup values to hide the fixed number of samples
-						"	float offset = rand( uv );",
-						"	for ( float t = -BLUR_ITERATIONS; t <= BLUR_ITERATIONS; t ++ ) {",
-						"		float percent = ( t + offset - 0.5 ) / BLUR_ITERATIONS;",
-						"		float weight = 1.0 - abs( percent );",
-						"		color += texture2D( texture, uv + delta * percent ) * weight;",
-						"		total += weight;",
-						"	}",
-						"	return color / total;",
-						"}"
-					].join( "\n" ), [ new THREE.ConstNode( "float BLUR_ITERATIONS 10.0" ) ] );
-
-					var blurredTexture = new THREE.FunctionCallNode( blurtexture, {
-						texture: new THREE.TextureNode( getTexture( "brick" ) ),
-						delta: delta,
-						uv: new THREE.UVNode()
-					} );
+						var varying = new THREE.VarNode( "vec3" );
 
-					var color = new THREE.Math3Node(
-						new THREE.TextureNode( getTexture( "brick" ) ),
-						blurredTexture,
-						alpha,
-						THREE.Math3Node.MIX
-					);
+						// VERTEX
 
-					mtl.color = color;
+						var setMyVar = new THREE.FunctionNode( [
+							"void setMyVar( vec3 pos ) {",
+							// set "myVar" in vertex shader in this example,
+							// can be used in fragment shader too or in rest of the current shader
+							"	myVar = pos;",
 
-					// GUI
+							"}"
+						].join( "\n" ) );
 
-					addGui( 'alpha', alpha.value, function ( val ) {
+						// add keyword
+						setMyVar.keywords[ "myVar" ] = varying;
 
-						alpha.value = val;
+						var position = new THREE.ExpressionNode( "setMyVar( position * .1 )", "vec3" );
+						position.includes = [ setMyVar ];
+						position.keywords[ "tex" ] = new THREE.TextureNode( getTexture( "brick" ) );
 
-					}, false, 0, 1 );
+						// use BypassNode to "void" functions
+						mtl.position = new THREE.BypassNode( position );
 
-					addGui( 'deltaX', delta.x, function ( val ) {
+						// FRAGMENT
 
-						delta.x = val;
+						var clipFromPos = new THREE.FunctionNode( [
+							"void clipFromPos( vec3 pos ) {",
 
-					}, false, 0, 1 );
+							"	if ( pos.y < .0 ) discard;",
 
-					addGui( 'deltaY', delta.x, function ( val ) {
+							"}"
+						].join( "\n" ) );
 
-						delta.y = val;
+						var clipFromPosCall = new THREE.FunctionCallNode( clipFromPos, {
+							pos: varying
+						} );
 
-					}, false, 0, 1 );
+						mtl.color = new THREE.BypassNode( clipFromPosCall, varying );
 
-					break;
+						break;
 
-				case 'firefly':
+					case 'conditional':
 
-					// MATERIAL
+						// MATERIAL
 
-					mtl = new THREE.PhongNodeMaterial();
+						mtl = new THREE.PhongNodeMaterial();
 
-					var time = new THREE.TimerNode();
-					var speed = new THREE.FloatNode( .5 );
+						var a = new THREE.FloatNode( 0 ),
+							b = new THREE.FloatNode( 0 ),
+							ifNode = new THREE.ColorNode( 0x0000FF ),
+							elseNode = new THREE.ColorNode( 0xFF0000 );
 
-					var color = new THREE.ColorNode( 0x98ff00 );
+						var cond = new THREE.CondNode( a, b, ifNode, elseNode, THREE.CondNode.EQUAL );
 
-					var timeSpeed = new THREE.OperatorNode(
-						time,
-						speed,
-						THREE.OperatorNode.MUL
-					);
+						mtl.color = cond;
 
-					var sinCycleInSecs = new THREE.OperatorNode(
-						timeSpeed,
-						new THREE.ConstNode( THREE.ConstNode.PI2 ),
-						THREE.OperatorNode.MUL
-					);
+						// GUI
 
-					var cycle = new THREE.Math1Node( sinCycleInSecs, THREE.Math1Node.SIN );
+						addGui( 'a', a.value, function ( val ) {
 
-					var cycleColor = new THREE.OperatorNode(
-						cycle,
-						color,
-						THREE.OperatorNode.MUL
-					);
+							a.value = val;
 
-					var cos = new THREE.Math1Node( cycleColor, THREE.Math1Node.SIN );
+						}, false, 0, 1 );
 
-					mtl.color = new THREE.ColorNode( 0 );
-					mtl.emissive = cos;
+						addGui( 'b', b.value, function ( val ) {
 
-					// GUI
+							b.value = val;
 
-					addGui( 'speed', speed.value, function ( val ) {
+						}, false, 0, 1 );
 
-						speed.value = val;
+						addGui( 'a condition b', {
+							EQUAL: THREE.CondNode.EQUAL,
+							NOT_EQUAL: THREE.CondNode.NOT_EQUAL,
+							GREATER: THREE.CondNode.GREATER,
+							GREATER_EQUAL: THREE.CondNode.GREATER_EQUAL,
+							LESS: THREE.CondNode.LESS,
+							LESS_EQUAL: THREE.CondNode.LESS_EQUAL
+						}, function ( val ) {
 
-					}, false, 0, 3 );
+							cond.op = val;
 
-					break;
+							mtl.needsUpdate = true;
 
-				case 'sss':
-				case 'translucent':
+						} );
 
-					// DISTANCE FORMULA
+						addGui( 'if color', ifNode.value.getHex(), function ( val ) {
 
-					var modelPos = new THREE.Vector3Node();
+							ifNode.value.setHex( val );
 
-					var viewPos = new THREE.PositionNode( THREE.PositionNode.VIEW );
-					var cameraPosition = new THREE.CameraNode( THREE.CameraNode.POSITION );
+						}, true );
 
-					var cameraDistance = new THREE.Math2Node(
-						modelPos,
-						cameraPosition,
-						THREE.Math2Node.DISTANCE
-					);
+						addGui( 'else color', elseNode.value.getHex(), function ( val ) {
 
-					var viewPosZ = new THREE.SwitchNode( viewPos, 'z' );
+							elseNode.value.setHex( val );
 
-					var distance = new THREE.OperatorNode(
-						cameraDistance,
-						viewPosZ,
-						THREE.OperatorNode.SUB
-					);
+						}, true );
 
-					var distanceRadius = new THREE.OperatorNode(
-						distance,
-						new THREE.FloatNode( 70 ),
-						THREE.OperatorNode.ADD
-					);
+						break;
 
-					var objectDepth = new THREE.Math3Node(
-						distanceRadius,
-						new THREE.FloatNode( 0 ),
-						new THREE.FloatNode( 50 ),
-						THREE.Math3Node.SMOOTHSTEP
-					);
+					case 'rtt':
 
-					// RTT ( get back distance )
+						// MATERIAL
 
-					rtTexture = new THREE.WebGLRenderTarget( window.innerWidth, window.innerHeight, { minFilter: THREE.LinearFilter, magFilter: THREE.NearestFilter, format: THREE.RGBFormat } );
+						mtl = new THREE.PhongNodeMaterial();
 
-					library[ rtTexture.texture.uuid ] = rtTexture.texture;
+						var uvTransform = new THREE.UVTransformNode(),
+							checker = new THREE.CheckerNode( uvTransform );
 
-					var distanceMtl = new THREE.PhongNodeMaterial();
-					distanceMtl.environment = objectDepth;
-					distanceMtl.side = THREE.BackSide;
+						uvTransform.setUvTransform( 0, 0, 2, 2, 0 );
 
-					rtMaterial = distanceMtl;
+						var rtt = new THREE.RTTNode( 512, 512, checker ),
+							bumpMap = new THREE.BumpMapNode( rtt );
 
-					// MATERIAL
+						bumpMap.scale.value = .1;
 
-					mtl = new THREE.StandardNodeMaterial();
+						mtl.color = checker;
+						mtl.normal = bumpMap;
 
-					var backSideDepth = new THREE.TextureNode( rtTexture.texture, new THREE.ScreenUVNode() );
+						// GUI
 
-					var difference = new THREE.OperatorNode(
-						objectDepth,
-						backSideDepth,
-						THREE.OperatorNode.SUB
-					);
+						addGui( 'bump', bumpMap.scale.value, function ( val ) {
 
-					var sss = new THREE.Math3Node(
-						new THREE.FloatNode( - .1 ),
-						new THREE.FloatNode( .5 ),
-						difference,
-						THREE.Math3Node.SMOOTHSTEP
-					);
+							bumpMap.scale.value = val;
 
-					var sssAlpha = new THREE.Math1Node( sss, THREE.Math1Node.SAT );
+						}, false, - .5, .5 );
 
-					var frontColor, backColor;
+						addGui( 'scale', 2, function ( val ) {
 
-					if ( name == 'sss' ) {
+							uvTransform.setUvTransform( 0, 0, val, val, 0 );
 
-						var sssOut = new THREE.Math2Node(
-							objectDepth,
-							sssAlpha,
-							THREE.Math2Node.MIN
-						);
+						}, false, 0, 8 );
+
+						addGui( 'ignoreColor', false, function ( val ) {
+
+							mtl.color = val ? new THREE.ColorNode( 0xFFFFFF ) : checker;
 
-						frontColor = new THREE.ColorNode( 0xd4cfbb );
-						backColor = new THREE.ColorNode( 0xd04327 );
+							mtl.needsUpdate = true;
+
+						} );
+
+						break;
+
+					case 'temporal-blur':
+
+						// MATERIAL
+
+						mtl = new THREE.PhongNodeMaterial();
+
+						var texture = new THREE.TextureNode( getTexture( "brick" ) );
+
+						var rttStore = new THREE.RTTNode( 512, 512, texture );
+						var blur = new THREE.BlurNode( rttStore );
+
+						var timer = new THREE.TimerNode( .01, THREE.TimerNode.LOCAL );
 
 						var color = new THREE.Math3Node(
-							backColor,
-							frontColor,
-							sssOut,
+							rttStore,
+							blur,
+							new THREE.FloatNode( .6 ),
 							THREE.Math3Node.MIX
 						);
 
-						var light = new THREE.OperatorNode(
-							new THREE.LightNode(),
-							color,
-							THREE.OperatorNode.ADD
-						);
+						blur.horizontal = blur.vertical = timer;
 
-						mtl.color = frontColor;
-						mtl.roughness = new THREE.FloatNode( .1 );
-						mtl.metalness = new THREE.FloatNode( .5 );
+						var rttSave = new THREE.RTTNode( 512, 512, color );
+						rttSave.saveTo = rttStore;
 
-						mtl.light = light;
-						mtl.environment = color;
+						mtl.color = rttSave;
+
+						// GUI
+
+						addGui( 'click to reset', false, function ( val ) {
+
+							// render a single time
+
+							rttStore.render = true;
+
+							// reset time blur
 
-					} else {
+							timer.value = 0;
 
-						frontColor = new THREE.ColorNode( 0xd04327 );
-						backColor = new THREE.ColorNode( 0x1a0e14 );
+						} );
+
+						break;
+
+					case 'readonly':
+
+						// MATERIAL
+
+						mtl = new THREE.PhongNodeMaterial();
+
+						mtl.color = new THREE.ColorNode( 0xFFFFFF );
+						mtl.specular = new THREE.FloatNode( .5 );
+						mtl.shininess = new THREE.FloatNode( 15 );
+
+						// not use "uniform" input ( for optimization )
+						// instead use explicit declaration, for example:
+						// vec3( 1.0, 1.0, 1.0 ) instead "uniform vec3"
+						// if readonly is true not allow change the value after build the shader material
+						mtl.color.readonly = mtl.specular.readonly = mtl.shininess.readonly = true;
+
+						break;
+
+					case 'triangle-blur':
+
+						// MATERIAL
+
+						mtl = new THREE.PhongNodeMaterial();
+
+						var delta = new THREE.Vector2Node( .5, .25 );
+						var alpha = new THREE.FloatNode( 1 );
+
+						var blurtexture = new THREE.FunctionNode( [
+							// Reference: TriangleBlurShader.js
+							"vec4 blurtexture(sampler2D texture, vec2 uv, vec2 delta) {",
+							"	vec4 color = vec4( 0.0 );",
+							"	float total = 0.0;",
+							// randomize the lookup values to hide the fixed number of samples
+							"	float offset = rand( uv );",
+							"	for ( float t = -BLUR_ITERATIONS; t <= BLUR_ITERATIONS; t ++ ) {",
+							"		float percent = ( t + offset - 0.5 ) / BLUR_ITERATIONS;",
+							"		float weight = 1.0 - abs( percent );",
+							"		color += texture2D( texture, uv + delta * percent ) * weight;",
+							"		total += weight;",
+							"	}",
+							"	return color / total;",
+							"}"
+						].join( "\n" ), [ new THREE.ConstNode( "float BLUR_ITERATIONS 10.0" ) ] );
+
+						var blurredTexture = new THREE.FunctionCallNode( blurtexture, {
+							texture: new THREE.TextureNode( getTexture( "brick" ) ),
+							delta: delta,
+							uv: new THREE.UVNode()
+						} );
 
 						var color = new THREE.Math3Node(
-							frontColor,
-							backColor,
-							sssAlpha,
+							new THREE.TextureNode( getTexture( "brick" ) ),
+							blurredTexture,
+							alpha,
 							THREE.Math3Node.MIX
 						);
 
-						var light = new THREE.OperatorNode(
-							new THREE.LightNode(),
+						mtl.color = color;
+
+						// GUI
+
+						addGui( 'alpha', alpha.value, function ( val ) {
+
+							alpha.value = val;
+
+						}, false, 0, 1 );
+
+						addGui( 'deltaX', delta.x, function ( val ) {
+
+							delta.x = val;
+
+						}, false, 0, 1 );
+
+						addGui( 'deltaY', delta.x, function ( val ) {
+
+							delta.y = val;
+
+						}, false, 0, 1 );
+
+						break;
+
+					case 'firefly':
+
+						// MATERIAL
+
+						mtl = new THREE.PhongNodeMaterial();
+
+						var time = new THREE.TimerNode();
+						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,
+							new THREE.ConstNode( THREE.ConstNode.PI2 ),
+							THREE.OperatorNode.MUL
+						);
+
+						var cycle = new THREE.Math1Node( sinCycleInSecs, THREE.Math1Node.SIN );
+
+						var cycleColor = new THREE.OperatorNode(
+							cycle,
 							color,
-							THREE.OperatorNode.ADD
+							THREE.OperatorNode.MUL
 						);
 
-						mtl.color = new THREE.ColorNode( 0xffffff );
-						mtl.roughness = new THREE.FloatNode( .1 );
-						mtl.metalness = new THREE.FloatNode( .5 );
+						var cos = new THREE.Math1Node( cycleColor, THREE.Math1Node.SIN );
 
-						mtl.light = light;
-						mtl.environment = color;
+						mtl.color = new THREE.ColorNode( 0 );
+						mtl.emissive = cos;
 
-					}
+						// GUI
 
-					// GUI
+						addGui( 'speed', speed.value, function ( val ) {
 
-					addGui( 'frontColor', frontColor.value.getHex(), function ( val ) {
+							speed.value = val;
 
-						frontColor.value.setHex( val );
+						}, false, 0, 3 );
 
-					}, true );
+						break;
 
-					addGui( 'backColor', backColor.value.getHex(), function ( val ) {
+					case 'sss':
+					case 'translucent':
 
-						backColor.value.setHex( val );
+						// DISTANCE FORMULA
 
-					}, true );
+						var modelPos = new THREE.Vector3Node();
 
-					addGui( 'area', sss.b.value, function ( val ) {
+						var viewPos = new THREE.PositionNode( THREE.PositionNode.VIEW );
+						var cameraPosition = new THREE.CameraNode( THREE.CameraNode.POSITION );
 
-						sss.b.value = val;
+						var cameraDistance = new THREE.Math2Node(
+							modelPos,
+							cameraPosition,
+							THREE.Math2Node.DISTANCE
+						);
 
-					}, false, 0, 1 );
+						var viewPosZ = new THREE.SwitchNode( viewPos, 'z' );
 
-					break;
+						var distance = new THREE.OperatorNode(
+							cameraDistance,
+							viewPosZ,
+							THREE.OperatorNode.SUB
+						);
 
-			}
+						var distanceRadius = new THREE.OperatorNode(
+							distance,
+							new THREE.FloatNode( 70 ),
+							THREE.OperatorNode.ADD
+						);
+
+						var objectDepth = new THREE.Math3Node(
+							distanceRadius,
+							new THREE.FloatNode( 0 ),
+							new THREE.FloatNode( 50 ),
+							THREE.Math3Node.SMOOTHSTEP
+						);
+
+						// RTT ( get back distance )
+
+						rtTexture = new THREE.WebGLRenderTarget( window.innerWidth, window.innerHeight, { minFilter: THREE.LinearFilter, magFilter: THREE.NearestFilter, format: THREE.RGBFormat } );
+
+						library[ rtTexture.texture.uuid ] = rtTexture.texture;
+
+						var distanceMtl = new THREE.PhongNodeMaterial();
+						distanceMtl.environment = objectDepth;
+						distanceMtl.side = THREE.BackSide;
+
+						rtMaterial = distanceMtl;
 
-			// set material
-			mesh.material = mtl;
+						// MATERIAL
 
-		}
+						mtl = new THREE.StandardNodeMaterial();
 
-		function onWindowResize() {
+						var backSideDepth = new THREE.TextureNode( rtTexture.texture, new THREE.ScreenUVNode() );
 
-			var width = window.innerWidth, height = window.innerHeight;
+						var difference = new THREE.OperatorNode(
+							objectDepth,
+							backSideDepth,
+							THREE.OperatorNode.SUB
+						);
 
-			camera.aspect = width / height;
-			camera.updateProjectionMatrix();
+						var sss = new THREE.Math3Node(
+							new THREE.FloatNode( - .1 ),
+							new THREE.FloatNode( .5 ),
+							difference,
+							THREE.Math3Node.SMOOTHSTEP
+						);
 
-			renderer.setSize( width, height );
+						var sssAlpha = new THREE.Math1Node( sss, THREE.Math1Node.SAT );
 
-			if ( rtTexture ) rtTexture.setSize( width, height );
+						var frontColor, backColor;
 
-		}
+						if ( name == 'sss' ) {
 
-		document.getElementById( 'serialize' ).addEventListener('click', function () {
+							var sssOut = new THREE.Math2Node(
+								objectDepth,
+								sssAlpha,
+								THREE.Math2Node.MIN
+							);
 
-			if ( serialized ) reset();
-			else serialize();
+							frontColor = new THREE.ColorNode( 0xd4cfbb );
+							backColor = new THREE.ColorNode( 0xd04327 );
 
-			serialized = ! serialized;
+							var color = new THREE.Math3Node(
+								backColor,
+								frontColor,
+								sssOut,
+								THREE.Math3Node.MIX
+							);
 
-		});
+							var light = new THREE.OperatorNode(
+								new THREE.LightNode(),
+								color,
+								THREE.OperatorNode.ADD
+							);
 
-		function reset() {
+							mtl.color = frontColor;
+							mtl.roughness = new THREE.FloatNode( .1 );
+							mtl.metalness = new THREE.FloatNode( .5 );
 
-			updateMaterial();
+							mtl.light = light;
+							mtl.environment = color;
 
-			// gui
+						} else {
 
-			var div = document.getElementById( 'serialize' );
-			div.textContent = "Serialize and apply";
+							frontColor = new THREE.ColorNode( 0xd04327 );
+							backColor = new THREE.ColorNode( 0x1a0e14 );
 
-		}
+							var color = new THREE.Math3Node(
+								frontColor,
+								backColor,
+								sssAlpha,
+								THREE.Math3Node.MIX
+							);
 
-		function serialize() {
+							var light = new THREE.OperatorNode(
+								new THREE.LightNode(),
+								color,
+								THREE.OperatorNode.ADD
+							);
 
-			var json = mesh.material.toJSON();
-				
-			// replace uuid to url (facilitates the load of textures using url otherside uuid) e.g:
+							mtl.color = new THREE.ColorNode( 0xffffff );
+							mtl.roughness = new THREE.FloatNode( .1 );
+							mtl.metalness = new THREE.FloatNode( .5 );
 
-			var cloud = getTexture( "cloud" );
-			
-			THREE.NodeMaterialLoaderUtils.replaceUUID( json, cloud, "cloud" );
+							mtl.light = light;
+							mtl.environment = color;
 
-			library[ "cloud" ] = cloud;
-			
-			// --
-			
-			var jsonStr = JSON.stringify( json );
-			
-			console.log( jsonStr );
-			
-			var loader = new THREE.NodeMaterialLoader( null, library ),
-				material = loader.parse( json );
-			
-			mesh.material.dispose();
-			
-			mesh.material = material;
-			
-			// gui
+						}
 
-			var div = document.getElementById( 'serialize' );
-			div.textContent = "Click to reset - JSON Generate: " + ( jsonStr.length / 1024 ).toFixed( 3 ) + "kB";
+						// GUI
 
-			if ( gui ) gui.destroy();
+						addGui( 'frontColor', frontColor.value.getHex(), function ( val ) {
 
-			gui = null;
+							frontColor.value.setHex( val );
 
-		}
+						}, true );
 
-		function animate() {
+						addGui( 'backColor', backColor.value.getHex(), function ( val ) {
 
-			var delta = clock.getDelta();
+							backColor.value.setHex( val );
 
-			if ( move ) {
+						}, true );
 
-				var time = Date.now() * 0.005;
+						addGui( 'area', sss.b.value, function ( val ) {
 
-				mesh.position.z = Math.cos( time ) * 10;
-				mesh.position.y = Math.sin( time ) * 10;
+							sss.b.value = val;
 
-			} else {
+						}, false, 0, 1 );
 
-				mesh.position.z = mesh.position.y = 0;
+						break;
+
+				}
+
+				// set material
+				mesh.material = mtl;
 
 			}
 
-			//mesh.rotation.z += .01;
+			function onWindowResize() {
+
+				var width = window.innerWidth, height = window.innerHeight;
+
+				camera.aspect = width / height;
+				camera.updateProjectionMatrix();
+
+				renderer.setSize( width, height );
+
+				if ( rtTexture ) rtTexture.setSize( width, height );
 
-			// update material animation and/or gpu calcs (pre-renderer)
-			
-			frame.update( delta ).setRenderer( renderer );
-			
-			if ( mesh.material instanceof THREE.NodeMaterial ) {
-			
-				frame.updateNode( mesh.material );
-				
 			}
 
-			// render to texture for sss/translucent material only
-			
-			if ( rtTexture ) {
+			document.getElementById( 'serialize' ).addEventListener( 'click', function () {
+
+				if ( serialized ) reset();
+				else serialize();
 
-				scene.overrideMaterial = rtMaterial;
+				serialized = ! serialized;
 
-				renderer.render( scene, camera, rtTexture, true );
+			} );
 
-				scene.overrideMaterial = null;
+			function reset() {
+
+				updateMaterial();
+
+				// gui
+
+				var div = document.getElementById( 'serialize' );
+				div.textContent = "Serialize and apply";
 
 			}
 
-			renderer.render( scene, camera );
+			function serialize() {
+
+				var json = mesh.material.toJSON();
+
+				// replace uuid to url (facilitates the load of textures using url otherside uuid) e.g:
+
+				var cloud = getTexture( "cloud" );
+
+				THREE.NodeMaterialLoaderUtils.replaceUUID( json, cloud, "cloud" );
+
+				library[ "cloud" ] = cloud;
 
-			requestAnimationFrame( animate );
+				// --
 
-		}
+				var jsonStr = JSON.stringify( json );
+
+				console.log( jsonStr );
+
+				var loader = new THREE.NodeMaterialLoader( null, library ),
+					material = loader.parse( json );
+
+				mesh.material.dispose();
+
+				mesh.material = material;
+
+				// gui
+
+				var div = document.getElementById( 'serialize' );
+				div.textContent = "Click to reset - JSON Generate: " + ( jsonStr.length / 1024 ).toFixed( 3 ) + "kB";
+
+				if ( gui ) gui.destroy();
+
+				gui = null;
+
+			}
+
+			function animate() {
+
+				var delta = clock.getDelta();
+
+				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)
+
+				frame.update( delta ).setRenderer( renderer );
+
+				if ( mesh.material instanceof THREE.NodeMaterial ) {
+
+					frame.updateNode( mesh.material );
+
+				}
+
+				// render to texture for sss/translucent material only
+
+				if ( rtTexture ) {
+
+					scene.overrideMaterial = rtMaterial;
+
+					renderer.render( scene, camera, rtTexture, true );
+
+					scene.overrideMaterial = null;
+
+				}
+
+				renderer.render( scene, camera );
+
+				requestAnimationFrame( animate );
+
+			}
 
 		</script>
 

+ 206 - 207
examples/webgl_mirror_nodes.html

@@ -42,243 +42,242 @@
 
 		<script type="module">
 
-		import './js/nodes/THREE.Nodes.js';
-		import './js/loaders/NodeMaterialLoader.js';
+			import './js/nodes/THREE.Nodes.js';
+			import './js/loaders/NodeMaterialLoader.js';
 
-		// scene size
-		var WIDTH = window.innerWidth;
-		var HEIGHT = window.innerHeight;
+			// scene size
+			var WIDTH = window.innerWidth;
+			var HEIGHT = window.innerHeight;
 
-		// camera
-		var VIEW_ANGLE = 45;
-		var ASPECT = WIDTH / HEIGHT;
-		var NEAR = 1;
-		var FAR = 500;
-
-		var decalNormal = new THREE.TextureLoader().load( 'textures/decal/decal-normal.jpg' );
-
-		var decalDiffuse = new THREE.TextureLoader().load( 'textures/decal/decal-diffuse.png' );
-		decalDiffuse.wrapS = decalDiffuse.wrapT = THREE.RepeatWrapping;
-
-		var camera, scene, renderer;
-		var clock = new THREE.Clock();
-
-		var cameraControls;
-
-		var gui = new dat.GUI();
-
-		var sphereGroup, smallSphere;
-		var groundMirrorMaterial;
-
-		var frame = new THREE.NodeFrame();
-
-		function init() {
-
-			// renderer
-			renderer = new THREE.WebGLRenderer();
-			renderer.setPixelRatio( window.devicePixelRatio );
-			renderer.setSize( WIDTH, HEIGHT );
+			// camera
+			var VIEW_ANGLE = 45;
+			var ASPECT = WIDTH / HEIGHT;
+			var NEAR = 1;
+			var FAR = 500;
 
-			// scene
-			scene = new THREE.Scene();
+			var decalNormal = new THREE.TextureLoader().load( 'textures/decal/decal-normal.jpg' );
 
-			// camera
-			camera = new THREE.PerspectiveCamera( VIEW_ANGLE, ASPECT, NEAR, FAR );
-			camera.position.set( 0, 75, 160 );
-
-			cameraControls = new THREE.OrbitControls( camera, renderer.domElement );
-			cameraControls.target.set( 0, 40, 0 );
-			cameraControls.maxDistance = 400;
-			cameraControls.minDistance = 10;
-			cameraControls.update();
-
-			var container = document.getElementById( 'container' );
-			container.appendChild( renderer.domElement );
-
-		}
-
-		function fillScene() {
-
-			var planeGeo = new THREE.PlaneBufferGeometry( 100.1, 100.1 );
-
-			// reflector/mirror plane
-			var geometry = new THREE.PlaneBufferGeometry( 100, 100 );
-			var groundMirror = new THREE.ReflectorRTT( geometry, { clipBias: 0.003, textureWidth: WIDTH, textureHeight: HEIGHT } );
-
-			var mask = new THREE.SwitchNode( new THREE.TextureNode( decalDiffuse ), 'w' );
-			var maskFlip = new THREE.Math1Node( mask, THREE.Math1Node.INVERT );
-
-			var mirror = new THREE.ReflectorNode( groundMirror );
-
-			var normalMap = new THREE.TextureNode( decalNormal );
-			var normalXY = new THREE.SwitchNode( normalMap, 'xy' );
-			var normalXYFlip = new THREE.Math1Node(
-				normalXY,
-				THREE.Math1Node.INVERT
-			);
-
-			var offsetNormal = new THREE.OperatorNode(
-				normalXYFlip,
-				new THREE.FloatNode( .5 ),
-				THREE.OperatorNode.SUB
-			);
-
-			mirror.offset = new THREE.OperatorNode(
-				offsetNormal, // normal
-				new THREE.FloatNode( 6 ), // scale
-				THREE.OperatorNode.MUL
-			);
-
-			var clr = new THREE.Math3Node(
-				mirror,
-				new THREE.ColorNode( 0xFFFFFF ),
-				mask,
-				THREE.Math3Node.MIX
-			);
-
-			var blurMirror = new THREE.BlurNode( mirror );
-			blurMirror.size = new THREE.Vector2( WIDTH, HEIGHT );
-			blurMirror.uv = new THREE.ExpressionNode( "projCoord.xyz / projCoord.q", "vec3" );
-			blurMirror.uv.keywords[ "projCoord" ] = new THREE.OperatorNode( mirror.offset, mirror.uv, THREE.OperatorNode.ADD );
-			blurMirror.radius.x = blurMirror.radius.y = 0;
-
-			gui.add( { blur: blurMirror.radius.x }, "blur", 0, 25 ).onChange( function ( v ) {
-
-				blurMirror.radius.x = blurMirror.radius.y = v;
-
-			} );
-
-			groundMirrorMaterial = new THREE.PhongNodeMaterial();
-			groundMirrorMaterial.environment = blurMirror; // or add "mirror" variable to disable blur
-			groundMirrorMaterial.environmentAlpha = mask;
-			groundMirrorMaterial.normal = new THREE.NormalMapNode( normalMap );
-			//groundMirrorMaterial.normalScale = new THREE.FloatNode( 1 );
-
-			// test serialization
-/*
-			var library = {};
-			library[ groundMirror.uuid ] = groundMirror;
-			library[ decalDiffuse.uuid ] = decalDiffuse;
-			library[ decalNormal.uuid ] = decalNormal;
-			library[ mirror.textureMatrix.uuid ] = mirror.textureMatrix; // use textureMatrix to projection
+			var decalDiffuse = new THREE.TextureLoader().load( 'textures/decal/decal-diffuse.png' );
+			decalDiffuse.wrapS = decalDiffuse.wrapT = THREE.RepeatWrapping;
 
-			var json = groundMirrorMaterial.toJSON();
-
-			groundMirrorMaterial = new THREE.NodeMaterialLoader( null, library ).parse( json );
-*/
-			//--
-
-			var mirrorMesh = new THREE.Mesh( planeGeo, groundMirrorMaterial );
-			// add all alternative mirror materials inside the ReflectorRTT to prevent:
-			// glDrawElements: Source and destination textures of the draw are the same.
-			groundMirror.add( mirrorMesh );
-			groundMirror.rotateX( - Math.PI / 2 );
-			scene.add( groundMirror );
+			var camera, scene, renderer;
+			var clock = new THREE.Clock();
 
-			sphereGroup = new THREE.Object3D();
-			scene.add( sphereGroup );
+			var cameraControls;
 
-			var geometry = new THREE.CylinderBufferGeometry( 0.1, 15 * Math.cos( Math.PI / 180 * 30 ), 0.1, 24, 1 );
-			var material = new THREE.MeshPhongMaterial( { color: 0xffffff, emissive: 0x444444 } );
-			var sphereCap = new THREE.Mesh( geometry, material );
-			sphereCap.position.y = - 15 * Math.sin( Math.PI / 180 * 30 ) - 0.05;
-			sphereCap.rotateX( - Math.PI );
+			var gui = new dat.GUI();
 
-			var geometry = new THREE.SphereBufferGeometry( 15, 24, 24, Math.PI / 2, Math.PI * 2, 0, Math.PI / 180 * 120 );
-			var halfSphere = new THREE.Mesh( geometry, material );
-			halfSphere.add( sphereCap );
-			halfSphere.rotateX( - Math.PI / 180 * 135 );
-			halfSphere.rotateZ( - Math.PI / 180 * 20 );
-			halfSphere.position.y = 7.5 + 15 * Math.sin( Math.PI / 180 * 30 );
+			var sphereGroup, smallSphere;
+			var groundMirrorMaterial;
 
-			sphereGroup.add( halfSphere );
+			var frame = new THREE.NodeFrame();
 
-			var geometry = new THREE.IcosahedronBufferGeometry( 5, 0 );
-			var material = new THREE.MeshPhongMaterial( { color: 0xffffff, emissive: 0x333333, flatShading: true } );
-			smallSphere = new THREE.Mesh( geometry, material );
-			scene.add( smallSphere );
+			function init() {
 
-			// walls
-			var planeTop = new THREE.Mesh( planeGeo, new THREE.MeshPhongMaterial( { color: 0xffffff } ) );
-			planeTop.position.y = 100;
-			planeTop.rotateX( Math.PI / 2 );
-			scene.add( planeTop );
-
-			var planeBack = new THREE.Mesh( planeGeo, new THREE.MeshPhongMaterial( { color: 0xffffff } ) );
-			planeBack.position.z = - 50;
-			planeBack.position.y = 50;
-			scene.add( planeBack );
-
-			var planeFront = new THREE.Mesh( planeGeo, new THREE.MeshPhongMaterial( { color: 0x7f7fff } ) );
-			planeFront.position.z = 50;
-			planeFront.position.y = 50;
-			planeFront.rotateY( Math.PI );
-			scene.add( planeFront );
-
-			var planeRight = new THREE.Mesh( planeGeo, new THREE.MeshPhongMaterial( { color: 0x00ff00 } ) );
-			planeRight.position.x = 50;
-			planeRight.position.y = 50;
-			planeRight.rotateY( - Math.PI / 2 );
-			scene.add( planeRight );
+				// renderer
+				renderer = new THREE.WebGLRenderer();
+				renderer.setPixelRatio( window.devicePixelRatio );
+				renderer.setSize( WIDTH, HEIGHT );
 
-			var planeLeft = new THREE.Mesh( planeGeo, new THREE.MeshPhongMaterial( { color: 0xff0000 } ) );
-			planeLeft.position.x = - 50;
-			planeLeft.position.y = 50;
-			planeLeft.rotateY( Math.PI / 2 );
-			scene.add( planeLeft );
+				// scene
+				scene = new THREE.Scene();
 
-			// lights
-			var mainLight = new THREE.PointLight( 0xcccccc, 1.5, 250 );
-			mainLight.position.y = 60;
-			scene.add( mainLight );
+				// camera
+				camera = new THREE.PerspectiveCamera( VIEW_ANGLE, ASPECT, NEAR, FAR );
+				camera.position.set( 0, 75, 160 );
 
-			var greenLight = new THREE.PointLight( 0x00ff00, 0.25, 1000 );
-			greenLight.position.set( 550, 50, 0 );
-			scene.add( greenLight );
+				cameraControls = new THREE.OrbitControls( camera, renderer.domElement );
+				cameraControls.target.set( 0, 40, 0 );
+				cameraControls.maxDistance = 400;
+				cameraControls.minDistance = 10;
+				cameraControls.update();
 
-			var redLight = new THREE.PointLight( 0xff0000, 0.25, 1000 );
-			redLight.position.set( - 550, 50, 0 );
-			scene.add( redLight );
+				var container = document.getElementById( 'container' );
+				container.appendChild( renderer.domElement );
 
-			var blueLight = new THREE.PointLight( 0x7f7fff, 0.25, 1000 );
-			blueLight.position.set( 0, 50, 550 );
-			scene.add( blueLight );
+			}
 
-		}
+			function fillScene() {
+
+				var planeGeo = new THREE.PlaneBufferGeometry( 100.1, 100.1 );
+
+				// reflector/mirror plane
+				var geometry = new THREE.PlaneBufferGeometry( 100, 100 );
+				var groundMirror = new THREE.ReflectorRTT( geometry, { clipBias: 0.003, textureWidth: WIDTH, textureHeight: HEIGHT } );
+
+				var mask = new THREE.SwitchNode( new THREE.TextureNode( decalDiffuse ), 'w' );
+				var maskFlip = new THREE.Math1Node( mask, THREE.Math1Node.INVERT );
+
+				var mirror = new THREE.ReflectorNode( groundMirror );
+
+				var normalMap = new THREE.TextureNode( decalNormal );
+				var normalXY = new THREE.SwitchNode( normalMap, 'xy' );
+				var normalXYFlip = new THREE.Math1Node(
+					normalXY,
+					THREE.Math1Node.INVERT
+				);
+
+				var offsetNormal = new THREE.OperatorNode(
+					normalXYFlip,
+					new THREE.FloatNode( .5 ),
+					THREE.OperatorNode.SUB
+				);
+
+				mirror.offset = new THREE.OperatorNode(
+					offsetNormal, // normal
+					new THREE.FloatNode( 6 ), // scale
+					THREE.OperatorNode.MUL
+				);
+
+				var clr = new THREE.Math3Node(
+					mirror,
+					new THREE.ColorNode( 0xFFFFFF ),
+					mask,
+					THREE.Math3Node.MIX
+				);
+
+				var blurMirror = new THREE.BlurNode( mirror );
+				blurMirror.size = new THREE.Vector2( WIDTH, HEIGHT );
+				blurMirror.uv = new THREE.ExpressionNode( "projCoord.xyz / projCoord.q", "vec3" );
+				blurMirror.uv.keywords[ "projCoord" ] = new THREE.OperatorNode( mirror.offset, mirror.uv, THREE.OperatorNode.ADD );
+				blurMirror.radius.x = blurMirror.radius.y = 0;
+
+				gui.add( { blur: blurMirror.radius.x }, "blur", 0, 25 ).onChange( function ( v ) {
+
+					blurMirror.radius.x = blurMirror.radius.y = v;
+
+				} );
+
+				groundMirrorMaterial = new THREE.PhongNodeMaterial();
+				groundMirrorMaterial.environment = blurMirror; // or add "mirror" variable to disable blur
+				groundMirrorMaterial.environmentAlpha = mask;
+				groundMirrorMaterial.normal = new THREE.NormalMapNode( normalMap );
+				//groundMirrorMaterial.normalScale = new THREE.FloatNode( 1 );
+
+				// test serialization
+				/*
+						var library = {};
+						library[ groundMirror.uuid ] = groundMirror;
+						library[ decalDiffuse.uuid ] = decalDiffuse;
+						library[ decalNormal.uuid ] = decalNormal;
+						library[ mirror.textureMatrix.uuid ] = mirror.textureMatrix; // use textureMatrix to projection
+
+						var json = groundMirrorMaterial.toJSON();
+
+						groundMirrorMaterial = new THREE.NodeMaterialLoader( null, library ).parse( json );
+					*/
+				//--
+
+				var mirrorMesh = new THREE.Mesh( planeGeo, groundMirrorMaterial );
+				// add all alternative mirror materials inside the ReflectorRTT to prevent:
+				// glDrawElements: Source and destination textures of the draw are the same.
+				groundMirror.add( mirrorMesh );
+				groundMirror.rotateX( - Math.PI / 2 );
+				scene.add( groundMirror );
+
+				sphereGroup = new THREE.Object3D();
+				scene.add( sphereGroup );
+
+				var geometry = new THREE.CylinderBufferGeometry( 0.1, 15 * Math.cos( Math.PI / 180 * 30 ), 0.1, 24, 1 );
+				var material = new THREE.MeshPhongMaterial( { color: 0xffffff, emissive: 0x444444 } );
+				var sphereCap = new THREE.Mesh( geometry, material );
+				sphereCap.position.y = - 15 * Math.sin( Math.PI / 180 * 30 ) - 0.05;
+				sphereCap.rotateX( - Math.PI );
+
+				var geometry = new THREE.SphereBufferGeometry( 15, 24, 24, Math.PI / 2, Math.PI * 2, 0, Math.PI / 180 * 120 );
+				var halfSphere = new THREE.Mesh( geometry, material );
+				halfSphere.add( sphereCap );
+				halfSphere.rotateX( - Math.PI / 180 * 135 );
+				halfSphere.rotateZ( - Math.PI / 180 * 20 );
+				halfSphere.position.y = 7.5 + 15 * Math.sin( Math.PI / 180 * 30 );
+
+				sphereGroup.add( halfSphere );
+
+				var geometry = new THREE.IcosahedronBufferGeometry( 5, 0 );
+				var material = new THREE.MeshPhongMaterial( { color: 0xffffff, emissive: 0x333333, flatShading: true } );
+				smallSphere = new THREE.Mesh( geometry, material );
+				scene.add( smallSphere );
+
+				// walls
+				var planeTop = new THREE.Mesh( planeGeo, new THREE.MeshPhongMaterial( { color: 0xffffff } ) );
+				planeTop.position.y = 100;
+				planeTop.rotateX( Math.PI / 2 );
+				scene.add( planeTop );
+
+				var planeBack = new THREE.Mesh( planeGeo, new THREE.MeshPhongMaterial( { color: 0xffffff } ) );
+				planeBack.position.z = - 50;
+				planeBack.position.y = 50;
+				scene.add( planeBack );
+
+				var planeFront = new THREE.Mesh( planeGeo, new THREE.MeshPhongMaterial( { color: 0x7f7fff } ) );
+				planeFront.position.z = 50;
+				planeFront.position.y = 50;
+				planeFront.rotateY( Math.PI );
+				scene.add( planeFront );
+
+				var planeRight = new THREE.Mesh( planeGeo, new THREE.MeshPhongMaterial( { color: 0x00ff00 } ) );
+				planeRight.position.x = 50;
+				planeRight.position.y = 50;
+				planeRight.rotateY( - Math.PI / 2 );
+				scene.add( planeRight );
+
+				var planeLeft = new THREE.Mesh( planeGeo, new THREE.MeshPhongMaterial( { color: 0xff0000 } ) );
+				planeLeft.position.x = - 50;
+				planeLeft.position.y = 50;
+				planeLeft.rotateY( Math.PI / 2 );
+				scene.add( planeLeft );
+
+				// lights
+				var mainLight = new THREE.PointLight( 0xcccccc, 1.5, 250 );
+				mainLight.position.y = 60;
+				scene.add( mainLight );
+
+				var greenLight = new THREE.PointLight( 0x00ff00, 0.25, 1000 );
+				greenLight.position.set( 550, 50, 0 );
+				scene.add( greenLight );
+
+				var redLight = new THREE.PointLight( 0xff0000, 0.25, 1000 );
+				redLight.position.set( - 550, 50, 0 );
+				scene.add( redLight );
+
+				var blueLight = new THREE.PointLight( 0x7f7fff, 0.25, 1000 );
+				blueLight.position.set( 0, 50, 550 );
+				scene.add( blueLight );
 
-		function render() {
+			}
 
-			renderer.render( scene, camera );
+			function render() {
 
-		}
+				renderer.render( scene, camera );
 
-		function update() {
+			}
 
-			requestAnimationFrame( update );
+			function update() {
 
-			var delta = clock.getDelta();
-			var timer = Date.now() * 0.01;
+				requestAnimationFrame( update );
 
-			sphereGroup.rotation.y -= 0.002;
+				var delta = clock.getDelta();
+				var timer = Date.now() * 0.01;
 
-			smallSphere.position.set(
-				Math.cos( timer * 0.1 ) * 30,
-				Math.abs( Math.cos( timer * 0.2 ) ) * 20 + 5,
-				Math.sin( timer * 0.1 ) * 30
-			);
-			smallSphere.rotation.y = ( Math.PI / 2 ) - timer * 0.1;
-			smallSphere.rotation.z = timer * 0.8;
+				sphereGroup.rotation.y -= 0.002;
 
-			frame.update( delta ).updateNode( groundMirrorMaterial );
+				smallSphere.position.set(
+					Math.cos( timer * 0.1 ) * 30,
+					Math.abs( Math.cos( timer * 0.2 ) ) * 20 + 5,
+					Math.sin( timer * 0.1 ) * 30
+				);
+				smallSphere.rotation.y = ( Math.PI / 2 ) - timer * 0.1;
+				smallSphere.rotation.z = timer * 0.8;
 
-			render();
+				frame.update( delta ).updateNode( groundMirrorMaterial );
 
-		}
+				render();
 
-		init();
-		fillScene();
-		update();
+			}
 
+			init();
+			fillScene();
+			update();
 
 		</script>
 	</body>

+ 53 - 53
examples/webgl_performance_nodes.html

@@ -68,7 +68,7 @@
 
 			var camera, scene, renderer;
 
-			var mesh, zmesh, lightMesh, geometry;
+			var geometry;
 			var meshes = [];
 
 			var mouseX = 0, mouseY = 0;
@@ -82,29 +82,29 @@
 			animate();
 
 			function createScene( MaterialClass, count ) {
-			
+
 				count = count !== undefined ? count : 70;
-			
+
 				var i = 0;
-				
+
 				for ( i = 0; i < meshes.length; i ++ ) {
-				
-					meshes[i].material.dispose();
-					
-					scene.remove( meshes[i] );
-				
+
+					meshes[ i ].material.dispose();
+
+					scene.remove( meshes[ i ] );
+
 				}
-				
+
 				meshes = [];
-			
+
 				for ( i = 0; i < 70; i ++ ) {
 
 					var material = new MaterialClass(),
 						color = 0xFFFFFF * Math.random();
-					
-					if (material.color.isNode) material.color.value.setHex( color );
+
+					if ( material.color.isNode ) material.color.value.setHex( color );
 					else material.color.setHex( color );
-					
+
 					// prevent share code
 					material.defines.UUID = material.uuid;
 
@@ -120,71 +120,71 @@
 					mesh.updateMatrix();
 
 					scene.add( mesh );
-					
+
 					meshes.push( mesh );
 
 				}
-				
+
 			}
-			
+
 			function benchmark() {
-			
+
 				var time, benchmarkTime;
 
 				// Stabilizes CPU
-				
+
 				createScene( THREE.MeshStandardMaterial, 10 );
-				
+
 				render();
-				
+
 				// Standard *Node* Material
-				
+
 				time = performance.now();
-				
+
 				createScene( THREE.StandardNodeMaterial );
-				
+
 				render();
-				
-				benchmarkTime = (performance.now() - time) / 1000;
 
-				document.getElementById( 'node' ).textContent = benchmarkTime.toFixed(3) + " seconds";
-				
+				benchmarkTime = ( performance.now() - time ) / 1000;
+
+				document.getElementById( 'node' ).textContent = benchmarkTime.toFixed( 3 ) + " seconds";
+
 				// Mesh Standard *Node* Material
-				
+
 				time = performance.now();
-				
+
 				createScene( THREE.MeshStandardNodeMaterial );
-				
+
 				render();
-				
-				benchmarkTime = (performance.now() - time) / 1000;
 
-				document.getElementById( 'nodeBased' ).textContent = benchmarkTime.toFixed(3) + " seconds";
-				
+				benchmarkTime = ( performance.now() - time ) / 1000;
+
+				document.getElementById( 'nodeBased' ).textContent = benchmarkTime.toFixed( 3 ) + " seconds";
+
 				// Mesh Standard Material
-				
+
 				time = performance.now();
-					
+
 				createScene( THREE.MeshStandardMaterial );
-				
+
 				render();
-				
-				benchmarkTime = (performance.now() - time) / 1000;
-				
-				document.getElementById( 'default' ).textContent = benchmarkTime.toFixed(3) + " seconds";
-			
+
+				benchmarkTime = ( performance.now() - time ) / 1000;
+
+				document.getElementById( 'default' ).textContent = benchmarkTime.toFixed( 3 ) + " seconds";
+
 			}
-			
-			document.getElementById( 'bench' ).addEventListener('click', function () {
 
-				if (geometry) {
-				
+			document.getElementById( 'bench' ).addEventListener( 'click', function () {
+
+				if ( geometry ) {
+
 					benchmark();
-					
+
 				}
-				
-			});
-			
+
+			} );
+
 			function init() {
 
 				container = document.createElement( 'div' );
@@ -201,7 +201,7 @@
 				loader.load( 'models/json/suzanne_buffergeometry.json', function ( geo ) {
 
 					geo.computeVertexNormals();
-					
+
 					geometry = geo;
 
 				} );
@@ -234,7 +234,7 @@
 
 			}
 
-			function onDocumentMouseMove(event) {
+			function onDocumentMouseMove( event ) {
 
 				mouseX = ( event.clientX - windowHalfX ) * 10;
 				mouseY = ( event.clientY - windowHalfY ) * 10;

+ 22 - 20
examples/webgl_postprocessing_nodes.html

@@ -41,12 +41,12 @@
 
 			var camera, scene, renderer;
 			var object, light, nodepost;
-			var gui, guiElements = [];
+			var gui;
 
 			var clock = new THREE.Clock();
 			var frame = new THREE.NodeFrame();
 
-			var param = { example: new URL(window.location.href).searchParams.get('e') || 'color-adjustment' };
+			var param = { example: new URL( window.location.href ).searchParams.get( 'e' ) || 'color-adjustment' };
 
 			var textureLoader = new THREE.TextureLoader();
 
@@ -134,7 +134,7 @@
 					case 'color-adjustment':
 
 						// POST
-					
+
 						var screen = new THREE.ScreenNode();
 
 						var hue = new THREE.FloatNode();
@@ -369,27 +369,27 @@
 					case 'motion-blur':
 
 						// POST
-					
+
 						var size = renderer.getDrawingBufferSize();
-						
+
 						var screen = new THREE.ScreenNode();
-						
+
 						var previousFrame = new THREE.RTTNode( size.width, size.height, screen );
-						
+
 						var motionBlur = new THREE.Math3Node(
 							previousFrame,
 							screen,
-							new THREE.FloatNode(.5),
+							new THREE.FloatNode( .5 ),
 							THREE.Math3Node.MIX
 						);
-						
+
 						var currentFrame = new THREE.RTTNode( size.width, size.height, motionBlur );
 						currentFrame.saveTo = previousFrame;
-						
+
 						nodepost.output = currentFrame;
-						
+
 						break;
-						
+
 					case 'mosaic':
 
 						// POST
@@ -480,15 +480,16 @@
 				nodepost.needsUpdate = true;
 
 				// test serialization
-/*
-				var library = {};
-				library[ lensflare2.uuid ] = lensflare2;
-				library[ decalNormal.uuid ] = decalNormal;
+				/*
+							var library = {};
+							library[ lensflare2.uuid ] = lensflare2;
+							library[ decalNormal.uuid ] = decalNormal;
 
-				var json = nodepost.toJSON();
+							var json = nodepost.toJSON();
+
+							nodepost.output = new THREE.NodeMaterialLoader( null, library ).parse( json ).value;
+						*/
 
-				nodepost.output = new THREE.NodeMaterialLoader( null, library ).parse( json ).value;
-*/
 			}
 
 			function init() {
@@ -558,11 +559,12 @@
 				object.rotation.y += 0.01;
 
 				frame.update( delta );
-				
+
 				nodepost.render( scene, camera, frame );
 
 			}
 
+
 		</script>
 
 	</body>

+ 9 - 8
examples/webgl_postprocessing_nodes_pass.html

@@ -49,7 +49,7 @@
 
 			var camera, scene, renderer, composer;
 			var object, light, nodepass;
-			var gui, guiElements = [];
+			var gui;
 
 			var clock = new THREE.Clock();
 			var frame = new THREE.NodeFrame();
@@ -461,15 +461,16 @@
 				nodepass.needsUpdate = true;
 
 				// test serialization
-/*
-				var library = {};
-				library[ lensflare2.uuid ] = lensflare2;
-				library[ decalNormal.uuid ] = decalNormal;
+				/*
+							var library = {};
+							library[ lensflare2.uuid ] = lensflare2;
+							library[ decalNormal.uuid ] = decalNormal;
 
-				var json = nodepass.toJSON();
+							var json = nodepass.toJSON();
+
+							nodepass.input = new THREE.NodeMaterialLoader( null, library ).parse( json ).value;
+						*/
 
-				nodepass.input = new THREE.NodeMaterialLoader( null, library ).parse( json ).value;
-*/
 			}
 
 			function init() {

+ 179 - 179
examples/webgl_sprites_nodes.html

@@ -41,215 +41,215 @@
 
 		<script type="module">
 
-		import './js/nodes/THREE.Nodes.js';
-		import './js/loaders/NodeMaterialLoader.js';
+			import './js/nodes/THREE.Nodes.js';
+			import './js/loaders/NodeMaterialLoader.js';
 
-		var container = document.getElementById( 'container' );
+			var container = document.getElementById( 'container' );
 
-		var renderer, scene, camera, clock = new THREE.Clock(), fov = 50;
-		var frame = new THREE.NodeFrame();
-		var plane, sprite1, sprite2, sprite3;
-		var walkingManTexture, walkingManTextureURL;
-		var library = {};
-		var controls;
-
-		window.addEventListener( 'load', init );
-
-		function init() {
-
-			//
-			// Renderer / Controls
-			//
-
-			renderer = new THREE.WebGLRenderer( { antialias: true } );
-			renderer.setPixelRatio( window.devicePixelRatio );
-			renderer.setSize( window.innerWidth, window.innerHeight );
-			container.appendChild( renderer.domElement );
-
-			scene = new THREE.Scene();
-			scene.fog = new THREE.Fog( 0x0000FF, 70, 150 );
-
-			camera = new THREE.PerspectiveCamera( fov, window.innerWidth / window.innerHeight, 1, 1000 );
-			camera.position.z = 100;
-			camera.target = new THREE.Vector3();
-
-			controls = new THREE.OrbitControls( camera, renderer.domElement );
-			controls.minDistance = 50;
-			controls.maxDistance = 200;
-
-			//
-			// SpriteNode
-			//
-
-			// https://openclipart.org/detail/239883/walking-man-sprite-sheet
-			walkingManTextureURL = "textures/WalkingManSpriteSheet.png";
-
-			walkingManTexture = new THREE.TextureLoader().load( walkingManTextureURL );
-			walkingManTexture.wrapS = walkingManTexture.wrapT = THREE.RepeatWrapping;
-
-			library[ walkingManTextureURL ] = walkingManTexture;
-
-			// horizontal sprite-sheet animator
-
-			function createHorizontalSpriteSheetNode( hCount, speed ) {
-
-				var speed = new THREE.Vector2Node( speed, 0 ); // frame per second
-				var scale = new THREE.Vector2Node( 1 / hCount, 1 ); // 8 horizontal images in sprite-sheet
-
-				var uvTimer = new THREE.OperatorNode(
-					new THREE.TimerNode(),
-					speed,
-					THREE.OperatorNode.MUL
-				);
-
-				var uvIntegerTimer = new THREE.Math1Node(
-					uvTimer,
-					THREE.Math1Node.FLOOR
-				);
-
-				var uvFrameOffset = new THREE.OperatorNode(
-					uvIntegerTimer,
-					scale,
-					THREE.OperatorNode.MUL
-				);
-
-				var uvScale = new THREE.OperatorNode(
-					new THREE.UVNode(),
-					scale,
-					THREE.OperatorNode.MUL
-				);
-
-				var uvFrame = new THREE.OperatorNode(
-					uvScale,
-					uvFrameOffset,
+			var renderer, scene, camera, clock = new THREE.Clock(), fov = 50;
+			var frame = new THREE.NodeFrame();
+			var sprite1, sprite2, sprite3;
+			var walkingManTexture, walkingManTextureURL;
+			var library = {};
+			var controls;
+
+			window.addEventListener( 'load', init );
+
+			function init() {
+
+				//
+				// Renderer / Controls
+				//
+
+				renderer = new THREE.WebGLRenderer( { antialias: true } );
+				renderer.setPixelRatio( window.devicePixelRatio );
+				renderer.setSize( window.innerWidth, window.innerHeight );
+				container.appendChild( renderer.domElement );
+
+				scene = new THREE.Scene();
+				scene.fog = new THREE.Fog( 0x0000FF, 70, 150 );
+
+				camera = new THREE.PerspectiveCamera( fov, window.innerWidth / window.innerHeight, 1, 1000 );
+				camera.position.z = 100;
+				camera.target = new THREE.Vector3();
+
+				controls = new THREE.OrbitControls( camera, renderer.domElement );
+				controls.minDistance = 50;
+				controls.maxDistance = 200;
+
+				//
+				// SpriteNode
+				//
+
+				// https://openclipart.org/detail/239883/walking-man-sprite-sheet
+				walkingManTextureURL = "textures/WalkingManSpriteSheet.png";
+
+				walkingManTexture = new THREE.TextureLoader().load( walkingManTextureURL );
+				walkingManTexture.wrapS = walkingManTexture.wrapT = THREE.RepeatWrapping;
+
+				library[ walkingManTextureURL ] = walkingManTexture;
+
+				// horizontal sprite-sheet animator
+
+				function createHorizontalSpriteSheetNode( hCount, speed ) {
+
+					var speed = new THREE.Vector2Node( speed, 0 ); // frame per second
+					var scale = new THREE.Vector2Node( 1 / hCount, 1 ); // 8 horizontal images in sprite-sheet
+
+					var uvTimer = new THREE.OperatorNode(
+						new THREE.TimerNode(),
+						speed,
+						THREE.OperatorNode.MUL
+					);
+
+					var uvIntegerTimer = new THREE.Math1Node(
+						uvTimer,
+						THREE.Math1Node.FLOOR
+					);
+
+					var uvFrameOffset = new THREE.OperatorNode(
+						uvIntegerTimer,
+						scale,
+						THREE.OperatorNode.MUL
+					);
+
+					var uvScale = new THREE.OperatorNode(
+						new THREE.UVNode(),
+						scale,
+						THREE.OperatorNode.MUL
+					);
+
+					var uvFrame = new THREE.OperatorNode(
+						uvScale,
+						uvFrameOffset,
+						THREE.OperatorNode.ADD
+					);
+
+					return uvFrame;
+
+				}
+
+				// sprites
+
+				var spriteWidth = 20,
+					spriteHeight = 20;
+
+				scene.add( sprite1 = new THREE.Sprite( new THREE.SpriteNodeMaterial() ) );
+				sprite1.scale.x = spriteWidth;
+				sprite1.scale.y = spriteHeight;
+				sprite1.material.color = new THREE.TextureNode( walkingManTexture );
+				sprite1.material.color.uv = createHorizontalSpriteSheetNode( 8, 10 );
+
+				scene.add( sprite2 = new THREE.Sprite( new THREE.SpriteNodeMaterial() ) );
+				sprite2.position.x = 30;
+				sprite2.scale.x = spriteWidth;
+				sprite2.scale.y = spriteHeight;
+				sprite2.material.color = new THREE.TextureNode( walkingManTexture );
+				sprite2.material.color.uv = createHorizontalSpriteSheetNode( 8, 30 );
+				sprite2.material.color = new THREE.Math1Node( sprite2.material.color, THREE.Math1Node.INVERT );
+				sprite2.material.spherical = false; // look at camera horizontally only, very used in vegetation
+				// horizontal zigzag sprite
+				sprite2.material.position = new THREE.OperatorNode(
+					new THREE.OperatorNode(
+						new THREE.Math1Node( new THREE.TimerNode( 3 ), THREE.Math1Node.SIN ), // 3 is speed (time scale)
+						new THREE.Vector2Node( .3, 0 ), // horizontal scale (position)
+						THREE.OperatorNode.MUL
+					),
+					new THREE.PositionNode(),
 					THREE.OperatorNode.ADD
 				);
 
-				return uvFrame;
+				var sineWaveFunction = new THREE.FunctionNode( [
+					// https://stackoverflow.com/questions/36174431/how-to-make-a-wave-warp-effect-in-shader
+					"vec2 sineWave(vec2 uv, vec2 phase) {",
+					// wave distortion
+					"	float x = sin( 25.0*uv.y + 30.0*uv.x + 6.28*phase.x) * 0.01;",
+					"	float y = sin( 25.0*uv.y + 30.0*uv.x + 6.28*phase.y) * 0.03;",
+					"	return vec2(uv.x+x, uv.y+y);",
+					"}"
+				].join( "\n" ) );
+
+				scene.add( sprite3 = new THREE.Sprite( new THREE.SpriteNodeMaterial() ) );
+				sprite3.position.x = - 30;
+				sprite3.scale.x = spriteWidth;
+				sprite3.scale.y = spriteHeight;
+				sprite3.material.color = new THREE.TextureNode( walkingManTexture );
+				sprite3.material.color.uv = new THREE.FunctionCallNode( sineWaveFunction, {
+					"uv": createHorizontalSpriteSheetNode( 8, 10 ),
+					"phase": new THREE.TimerNode()
+				} );
+				sprite3.material.fog = true;
+
+				//
+				//	Test serialization
+				//
+
+				spriteToJSON( sprite1 );
+				spriteToJSON( sprite2 );
+				spriteToJSON( sprite3 );
+
+				//
+				// Events
+				//
+
+				window.addEventListener( 'resize', onWindowResize, false );
+
+				onWindowResize();
+				animate();
 
 			}
 
-			// sprites
-
-			var spriteWidth = 20,
-				spriteHeight = 20;
-
-			scene.add( sprite1 = new THREE.Sprite( new THREE.SpriteNodeMaterial() ) );
-			sprite1.scale.x = spriteWidth;
-			sprite1.scale.y = spriteHeight;
-			sprite1.material.color = new THREE.TextureNode( walkingManTexture );
-			sprite1.material.color.uv = createHorizontalSpriteSheetNode( 8, 10 );
-
-			scene.add( sprite2 = new THREE.Sprite( new THREE.SpriteNodeMaterial() ) );
-			sprite2.position.x = 30;
-			sprite2.scale.x = spriteWidth;
-			sprite2.scale.y = spriteHeight;
-			sprite2.material.color = new THREE.TextureNode( walkingManTexture );
-			sprite2.material.color.uv = createHorizontalSpriteSheetNode( 8, 30 );
-			sprite2.material.color = new THREE.Math1Node( sprite2.material.color, THREE.Math1Node.INVERT );
-			sprite2.material.spherical = false; // look at camera horizontally only, very used in vegetation
-			// horizontal zigzag sprite
-			sprite2.material.position = new THREE.OperatorNode(
-				new THREE.OperatorNode(
-					new THREE.Math1Node( new THREE.TimerNode( 3 ), THREE.Math1Node.SIN ), // 3 is speed (time scale)
-					new THREE.Vector2Node( .3, 0 ), // horizontal scale (position)
-					THREE.OperatorNode.MUL
-				),
-				new THREE.PositionNode(),
-				THREE.OperatorNode.ADD
-			);
-
-			var sineWaveFunction = new THREE.FunctionNode( [
-				// https://stackoverflow.com/questions/36174431/how-to-make-a-wave-warp-effect-in-shader
-				"vec2 sineWave(vec2 uv, vec2 phase) {",
-				// wave distortion
-				"	float x = sin( 25.0*uv.y + 30.0*uv.x + 6.28*phase.x) * 0.01;",
-				"	float y = sin( 25.0*uv.y + 30.0*uv.x + 6.28*phase.y) * 0.03;",
-				"	return vec2(uv.x+x, uv.y+y);",
-				"}"
-			].join( "\n" ) );
-
-			scene.add( sprite3 = new THREE.Sprite( new THREE.SpriteNodeMaterial() ) );
-			sprite3.position.x = - 30;
-			sprite3.scale.x = spriteWidth;
-			sprite3.scale.y = spriteHeight;
-			sprite3.material.color = new THREE.TextureNode( walkingManTexture );
-			sprite3.material.color.uv = new THREE.FunctionCallNode( sineWaveFunction, {
-				"uv": createHorizontalSpriteSheetNode( 8, 10 ),
-				"phase": new THREE.TimerNode()
-			} );
-			sprite3.material.fog = true;
-
-			//
-			//	Test serialization
-			//
+			function spriteToJSON( sprite ) {
 
-			spriteToJSON( sprite1 );
-			spriteToJSON( sprite2 );
-			spriteToJSON( sprite3 );
+				// serialize
 
-			//
-			// Events
-			//
+				var json = sprite.material.toJSON();
 
-			window.addEventListener( 'resize', onWindowResize, false );
+				// replace uuid to url (facilitates the load of textures using url otherside uuid)
 
-			onWindowResize();
-			animate();
+				THREE.NodeMaterialLoaderUtils.replaceUUID( json, walkingManTexture, walkingManTextureURL );
 
-		}
+				// deserialize
 
-		function spriteToJSON( sprite ) {
+				var material = new THREE.NodeMaterialLoader( null, library ).parse( json );
 
-			// serialize
+				// replace material
 
-			var json = sprite.material.toJSON();
+				sprite.material.dispose();
 
-			// replace uuid to url (facilitates the load of textures using url otherside uuid)
+				sprite.material = material;
 
-			THREE.NodeMaterialLoaderUtils.replaceUUID( json, walkingManTexture, walkingManTextureURL );
-
-			// deserialize
-
-			var material = new THREE.NodeMaterialLoader( null, library ).parse( json );
-
-			// replace material
-
-			sprite.material.dispose();
-
-			sprite.material = material;
-
-		}
+			}
 
-		function onWindowResize() {
+			function onWindowResize() {
 
-			var width = window.innerWidth, height = window.innerHeight;
+				var width = window.innerWidth, height = window.innerHeight;
 
-			camera.aspect = width / height;
-			camera.updateProjectionMatrix();
+				camera.aspect = width / height;
+				camera.updateProjectionMatrix();
 
-			renderer.setSize( width, height );
+				renderer.setSize( width, height );
 
-		}
+			}
 
-		function animate() {
+			function animate() {
 
-			var delta = clock.getDelta();
+				var delta = clock.getDelta();
 
-			// update material animation and/or gpu calcs (pre-renderer)
-			frame.update( delta )
-				.updateNode( sprite1.material )
-				.updateNode( sprite2.material )
-				.updateNode( sprite3.material );
+				// update material animation and/or gpu calcs (pre-renderer)
+				frame.update( delta )
+					.updateNode( sprite1.material )
+					.updateNode( sprite2.material )
+					.updateNode( sprite3.material );
 
-			// rotate sprite
-			sprite3.rotation.z -= Math.PI * .005;
+				// rotate sprite
+				sprite3.rotation.z -= Math.PI * .005;
 
-			renderer.render( scene, camera );
+				renderer.render( scene, camera );
 
-			requestAnimationFrame( animate );
+				requestAnimationFrame( animate );
 
-		}
+			}
 
 		</script>