Browse Source

nodematerial es6 modules

sunag 7 years ago
parent
commit
c591a16226
87 changed files with 3649 additions and 3029 deletions
  1. 0 97
      examples/js/nodes/NodeMaterialSource.js
  2. 105 0
      examples/js/nodes/Nodes.js
  3. 203 0
      examples/js/nodes/THREE.Nodes.js
  4. 71 49
      examples/js/nodes/accessors/CameraNode.js
  5. 19 18
      examples/js/nodes/accessors/ColorsNode.js
  6. 15 11
      examples/js/nodes/accessors/LightNode.js
  7. 47 26
      examples/js/nodes/accessors/NormalNode.js
  8. 54 34
      examples/js/nodes/accessors/PositionNode.js
  9. 48 34
      examples/js/nodes/accessors/ReflectNode.js
  10. 53 0
      examples/js/nodes/accessors/ResolutionNode.js
  11. 15 11
      examples/js/nodes/accessors/ScreenUVNode.js
  12. 31 18
      examples/js/nodes/accessors/UVNode.js
  13. 50 0
      examples/js/nodes/bsdfs/BlinnExponentToRoughnessNode.js
  14. 31 0
      examples/js/nodes/bsdfs/BlinnShininessExponentNode.js
  15. 91 0
      examples/js/nodes/bsdfs/RoughnessToBlinnExponentNode.js
  16. 20 13
      examples/js/nodes/core/AttributeNode.js
  17. 25 21
      examples/js/nodes/core/ConstNode.js
  18. 16 12
      examples/js/nodes/core/FunctionCallNode.js
  19. 33 27
      examples/js/nodes/core/FunctionNode.js
  20. 95 92
      examples/js/nodes/core/GLNode.js
  21. 17 16
      examples/js/nodes/core/InputNode.js
  22. 618 48
      examples/js/nodes/core/NodeBuilder.js
  23. 20 12
      examples/js/nodes/core/NodeFrame.js
  24. 3 1
      examples/js/nodes/core/NodeLib.js
  25. 0 737
      examples/js/nodes/core/NodeMaterial.js
  26. 9 2
      examples/js/nodes/core/NodeUniform.js
  27. 75 0
      examples/js/nodes/core/NodeUtils.js
  28. 0 61
      examples/js/nodes/core/RawNode.js
  29. 20 15
      examples/js/nodes/core/StructNode.js
  30. 28 29
      examples/js/nodes/core/TempNode.js
  31. 16 12
      examples/js/nodes/core/VarNode.js
  32. 168 0
      examples/js/nodes/effects/BlurNode.js
  33. 136 0
      examples/js/nodes/effects/ColorAdjustmentNode.js
  34. 73 0
      examples/js/nodes/effects/LuminanceNode.js
  35. 15 10
      examples/js/nodes/inputs/ColorNode.js
  36. 19 14
      examples/js/nodes/inputs/CubeTextureNode.js
  37. 13 9
      examples/js/nodes/inputs/FloatNode.js
  38. 13 9
      examples/js/nodes/inputs/IntNode.js
  39. 14 10
      examples/js/nodes/inputs/Matrix3Node.js
  40. 14 10
      examples/js/nodes/inputs/Matrix4Node.js
  41. 29 19
      examples/js/nodes/inputs/ReflectorNode.js
  42. 13 8
      examples/js/nodes/inputs/ScreenNode.js
  43. 20 14
      examples/js/nodes/inputs/TextureNode.js
  44. 15 10
      examples/js/nodes/inputs/Vector2Node.js
  45. 15 10
      examples/js/nodes/inputs/Vector3Node.js
  46. 15 10
      examples/js/nodes/inputs/Vector4Node.js
  47. 0 156
      examples/js/nodes/libs/common.js
  48. 0 53
      examples/js/nodes/libs/keywords.js
  49. 0 77
      examples/js/nodes/materials/MeshStandardNode.js
  50. 12 20
      examples/js/nodes/materials/MeshStandardNodeMaterial.js
  51. 201 0
      examples/js/nodes/materials/NodeMaterial.js
  52. 12 6
      examples/js/nodes/materials/PhongNodeMaterial.js
  53. 12 6
      examples/js/nodes/materials/SpriteNodeMaterial.js
  54. 12 6
      examples/js/nodes/materials/StandardNodeMaterial.js
  55. 87 0
      examples/js/nodes/materials/nodes/MeshStandardNode.js
  56. 27 22
      examples/js/nodes/materials/nodes/PhongNode.js
  57. 62 0
      examples/js/nodes/materials/nodes/RawNode.js
  58. 15 10
      examples/js/nodes/materials/nodes/SpriteNode.js
  59. 36 33
      examples/js/nodes/materials/nodes/StandardNode.js
  60. 53 45
      examples/js/nodes/math/Math1Node.js
  61. 49 37
      examples/js/nodes/math/Math2Node.js
  62. 39 25
      examples/js/nodes/math/Math3Node.js
  63. 25 23
      examples/js/nodes/math/OperatorNode.js
  64. 166 0
      examples/js/nodes/misc/BumpMapNode.js
  65. 119 0
      examples/js/nodes/misc/NormalMapNode.js
  66. 18 15
      examples/js/nodes/misc/TextureCubeNode.js
  67. 66 49
      examples/js/nodes/misc/TextureCubeUVNode.js
  68. 15 9
      examples/js/nodes/postprocessing/NodePass.js
  69. 69 0
      examples/js/nodes/procedural/NoiseNode.js
  70. 0 45
      examples/js/nodes/utils/BlinnExponentToRoughnessNode.js
  71. 0 27
      examples/js/nodes/utils/BlinnShininessExponentNode.js
  72. 0 152
      examples/js/nodes/utils/BlurNode.js
  73. 0 95
      examples/js/nodes/utils/BumpMapNode.js
  74. 16 14
      examples/js/nodes/utils/BypassNode.js
  75. 0 99
      examples/js/nodes/utils/ColorAdjustmentNode.js
  76. 24 24
      examples/js/nodes/utils/JoinNode.js
  77. 0 47
      examples/js/nodes/utils/LuminanceNode.js
  78. 16 8
      examples/js/nodes/utils/MaxMIPLevelNode.js
  79. 0 47
      examples/js/nodes/utils/NoiseNode.js
  80. 0 70
      examples/js/nodes/utils/NormalMapNode.js
  81. 0 49
      examples/js/nodes/utils/ResolutionNode.js
  82. 0 79
      examples/js/nodes/utils/RoughnessToBlinnExponentNode.js
  83. 19 16
      examples/js/nodes/utils/SwitchNode.js
  84. 29 18
      examples/js/nodes/utils/TimerNode.js
  85. 19 13
      examples/js/nodes/utils/UVTransformNode.js
  86. 17 13
      examples/js/nodes/utils/VelocityNode.js
  87. 14 92
      examples/webgl_materials_nodes.html

+ 0 - 97
examples/js/nodes/NodeMaterialSource.js

@@ -1,97 +0,0 @@
-/**
- * @author sunag / http://www.sunag.com.br/
- */
-
-( function () {
-	
-	function loadScript( path ) {
-
-		var js = document.createElement("script");
-		js.type = 'text/javascript';
-		js.src = path;
-
-		document.body.appendChild( js );
-
-	}
-	
-	function loadScripts( path, scripts ) {
-
-		for(var i = 0; i < scripts.length; i++) {
-			
-			loadScript( path + scripts[i] );
-			
-		}
-
-	}
-	
-	loadScripts( "js/nodes/", [
-		// NodeLibrary
-		"core/GLNode.js",
-		"core/RawNode.js",
-		"core/BypassNode.js",
-		"core/TempNode.js",
-		"core/InputNode.js",
-		"core/ConstNode.js",
-		"core/VarNode.js",
-		"core/StructNode.js",
-		"core/FunctionNode.js",
-		"core/FunctionCallNode.js",
-		"core/AttributeNode.js",
-		"core/NodeUniform.js",
-		"core/NodeBuilder.js",
-		"core/NodeLib.js",
-		"core/NodeFrame.js",
-		"core/NodeMaterial.js",
-		// Library
-		"libs/common.js",
-		"libs/keywords.js",
-		// Accessors
-		"accessors/PositionNode.js",
-		"accessors/NormalNode.js",
-		"accessors/UVNode.js",
-		"accessors/ScreenUVNode.js",
-		"accessors/ColorsNode.js",
-		"accessors/CameraNode.js",
-		"accessors/ReflectNode.js",
-		"accessors/LightNode.js",
-		// Inputs
-		"inputs/IntNode.js",
-		"inputs/FloatNode.js",
-		"inputs/ColorNode.js",
-		"inputs/Vector2Node.js",
-		"inputs/Vector3Node.js",
-		"inputs/Vector4Node.js",
-		"inputs/TextureNode.js",
-		"inputs/Matrix3Node.js",
-		"inputs/Matrix4Node.js",
-		"inputs/CubeTextureNode.js",
-		// Math
-		"math/Math1Node.js",
-		"math/Math2Node.js",
-		"math/Math3Node.js",
-		"math/OperatorNode.js",
-		// Utils
-		"utils/SwitchNode.js",
-		"utils/JoinNode.js",
-		"utils/TimerNode.js",
-		"utils/RoughnessToBlinnExponentNode.js",
-		"utils/BlinnShininessExponentNode.js",
-		"utils/VelocityNode.js",
-		"utils/LuminanceNode.js",
-		"utils/ColorAdjustmentNode.js",
-		"utils/NoiseNode.js",
-		"utils/ResolutionNode.js",
-		"utils/BumpMapNode.js",
-		"utils/BlurNode.js",
-		"utils/UVTransformNode.js",
-		"utils/MaxMIPLevelNode.js",
-		"utils/NormalMapNode.js",
-		// Phong Material
-		"materials/PhongNode.js",
-		"materials/PhongNodeMaterial.js",
-		// Standard Material
-		"materials/StandardNode.js",
-		"materials/StandardNodeMaterial.js"
-	]);
-	
-}() );

+ 105 - 0
examples/js/nodes/Nodes.js

@@ -0,0 +1,105 @@
+// TODO: all nodes
+
+// core
+
+export { GLNode } from './core/GLNode.js';
+export { TempNode } from './core/TempNode.js';
+export { InputNode } from './core/InputNode.js';
+export { ConstNode } from './core/ConstNode.js';
+export { VarNode } from './core/VarNode.js';
+export { StructNode } from './core/StructNode.js';
+export { AttributeNode } from './core/AttributeNode.js';
+export { FunctionNode } from './core/FunctionNode.js';
+export { FunctionCallNode } from './core/FunctionCallNode.js';
+export { NodeLib } from './core/NodeLib.js';
+export { NodeUtils } from './core/NodeUtils.js';
+export { NodeFrame } from './core/NodeFrame.js';
+export { NodeUniform } from './core/NodeUniform.js';
+export { NodeBuilder } from './core/NodeBuilder.js';
+
+// inputs
+
+export { IntNode } from './inputs/IntNode.js';
+export { FloatNode } from './inputs/FloatNode.js';
+export { Vector2Node } from './inputs/Vector2Node.js';
+export { Vector3Node } from './inputs/Vector3Node.js';
+export { Vector4Node } from './inputs/Vector4Node.js';
+export { ColorNode } from './inputs/ColorNode.js';
+export { Matrix3Node } from './inputs/Matrix3Node.js';
+export { Matrix4Node } from './inputs/Matrix4Node.js';
+export { TextureNode } from './inputs/TextureNode.js';
+export { CubeTextureNode } from './inputs/CubeTextureNode.js';
+export { ScreenNode } from './inputs/ScreenNode.js';
+export { ReflectorNode } from './inputs/ReflectorNode.js';
+
+// accessors
+
+export { UVNode } from './accessors/UVNode.js';
+export { ColorsNode } from './accessors/ColorsNode.js';
+export { PositionNode } from './accessors/PositionNode.js';
+export { NormalNode } from './accessors/NormalNode.js';
+export { CameraNode } from './accessors/CameraNode.js';
+export { LightNode } from './accessors/LightNode.js';
+export { ReflectNode } from './accessors/ReflectNode.js';
+export { ScreenUVNode } from './accessors/ScreenUVNode.js';
+export { ResolutionNode } from './accessors/ResolutionNode.js';
+
+// math
+
+export { Math1Node } from './math/Math1Node.js';
+export { Math2Node } from './math/Math2Node.js';
+export { Math3Node } from './math/Math3Node.js';
+export { OperatorNode } from './math/OperatorNode.js';
+
+// procedural
+
+export { NoiseNode } from './procedural/NoiseNode.js';
+
+// bsdfs
+
+export { BlinnShininessExponentNode } from './bsdfs/BlinnShininessExponentNode.js';
+export { BlinnExponentToRoughnessNode } from './bsdfs/BlinnExponentToRoughnessNode.js';
+export { RoughnessToBlinnExponentNode } from './bsdfs/RoughnessToBlinnExponentNode.js';
+
+// misc
+
+export { TextureCubeUVNode } from './misc/TextureCubeUVNode.js';
+export { TextureCubeNode } from './misc/TextureCubeNode.js';
+export { NormalMapNode } from './misc/NormalMapNode.js';
+export { BumpMapNode } from './misc/BumpMapNode.js';
+
+// utils
+
+export { BypassNode } from './utils/BypassNode.js';
+export { JoinNode } from './utils/JoinNode.js';
+export { SwitchNode } from './utils/SwitchNode.js';
+export { TimerNode } from './utils/TimerNode.js';
+export { VelocityNode } from './utils/VelocityNode.js';
+export { UVTransformNode } from './utils/UVTransformNode.js';
+export { MaxMIPLevelNode } from './utils/MaxMIPLevelNode.js';
+
+// effects
+
+export { BlurNode } from './effects/BlurNode.js';
+export { ColorAdjustmentNode } from './effects/ColorAdjustmentNode.js';
+export { LuminanceNode } from './effects/LuminanceNode.js';
+
+// material nodes
+
+export { RawNode } from './materials/nodes/RawNode.js';
+export { SpriteNode } from './materials/nodes/SpriteNode.js';
+export { PhongNode } from './materials/nodes/PhongNode.js';
+export { StandardNode } from './materials/nodes/StandardNode.js';
+export { MeshStandardNode } from './materials/nodes/MeshStandardNode.js';
+
+// materials
+
+export { NodeMaterial } from './materials/NodeMaterial.js';
+export { SpriteNodeMaterial } from './materials/SpriteNodeMaterial.js';
+export { PhongNodeMaterial } from './materials/PhongNodeMaterial.js';
+export { StandardNodeMaterial } from './materials/StandardNodeMaterial.js';
+export { MeshStandardNodeMaterial } from './materials/MeshStandardNodeMaterial.js';
+
+// postprocessing
+
+//export { NodePass } from './postprocessing/NodePass.js';

+ 203 - 0
examples/js/nodes/THREE.Nodes.js

@@ -0,0 +1,203 @@
+import { 
+
+	// core
+	
+	GLNode,
+	TempNode,
+	InputNode,
+	ConstNode,
+	VarNode,
+	StructNode,
+	AttributeNode,
+	FunctionNode,
+	FunctionCallNode,
+	NodeLib,
+	NodeUtils,
+	NodeFrame,
+	NodeUniform,
+	NodeBuilder,
+	
+	// inputs
+	
+	IntNode,
+	FloatNode,
+	Vector2Node,
+	Vector3Node,
+	Vector4Node,
+	ColorNode,
+	Matrix3Node,
+	Matrix4Node,
+	TextureNode,
+	CubeTextureNode,
+	ScreenNode,
+	ReflectorNode,
+	
+	// accessors
+	
+	UVNode,
+	ColorsNode,
+	PositionNode,
+	NormalNode,
+	CameraNode,
+	LightNode,
+	ReflectNode,
+	ScreenUVNode,
+	ResolutionNode,
+	
+	// math
+	
+	Math1Node,
+	Math2Node,
+	Math3Node,
+	OperatorNode,
+	
+	// procedural
+	
+	NoiseNode,
+	
+	// bsdfs
+	
+	BlinnShininessExponentNode,
+	BlinnExponentToRoughnessNode,
+	RoughnessToBlinnExponentNode,
+	
+	// misc
+	
+	TextureCubeUVNode,
+	TextureCubeNode,
+	NormalMapNode,
+	BumpMapNode,
+	
+	// utils
+	
+	BypassNode,
+	JoinNode,
+	SwitchNode,
+	TimerNode,
+	VelocityNode,
+	UVTransformNode,
+	MaxMIPLevelNode,
+	
+	// effects
+	
+	BlurNode,
+	ColorAdjustmentNode,
+	LuminanceNode,
+
+	// material nodes
+	
+	RawNode,
+	SpriteNode,
+	PhongNode,
+	StandardNode,
+	MeshStandardNode,
+	
+	// utils
+	
+	NodeMaterial,
+	SpriteNodeMaterial,
+	PhongNodeMaterial,
+	StandardNodeMaterial,
+	MeshStandardNodeMaterial
+	
+} from './Nodes.js';
+
+// core
+
+THREE.GLNode = GLNode;
+THREE.TempNode = TempNode;
+THREE.InputNode = InputNode;
+THREE.ConstNode = ConstNode;
+THREE.VarNode = VarNode;
+THREE.StructNode = StructNode;
+THREE.AttributeNode = AttributeNode;
+THREE.FunctionNode = FunctionNode;
+THREE.FunctionCallNode = FunctionCallNode;
+THREE.NodeLib = NodeLib;
+THREE.NodeUtils = NodeUtils;
+THREE.NodeFrame = NodeFrame;
+THREE.NodeUniform = NodeUniform;
+THREE.NodeBuilder = NodeBuilder;
+
+// inputs
+
+THREE.IntNode = IntNode;
+THREE.FloatNode = FloatNode;
+THREE.Vector2Node = Vector2Node;
+THREE.Vector3Node = Vector3Node;
+THREE.Vector4Node = Vector4Node;
+THREE.ColorNode = ColorNode;
+THREE.Matrix3Node = Matrix3Node;
+THREE.Matrix4Node = Matrix4Node;
+THREE.TextureNode = TextureNode;
+THREE.CubeTextureNode = CubeTextureNode;
+THREE.ScreenNode = ScreenNode;
+THREE.ReflectorNode = ReflectorNode;
+
+// accessors
+
+THREE.UVNode = UVNode;
+THREE.ColorsNode = ColorsNode;
+THREE.PositionNode = PositionNode;
+THREE.NormalNode = NormalNode;
+THREE.CameraNode = CameraNode;
+THREE.LightNode = LightNode;
+THREE.ReflectNode = ReflectNode;
+THREE.ScreenUVNode = ScreenUVNode;
+THREE.ResolutionNode = ResolutionNode;
+
+// math
+
+THREE.Math1Node = Math1Node;
+THREE.Math2Node = Math2Node;
+THREE.Math3Node = Math3Node;
+THREE.OperatorNode = OperatorNode;
+
+// procedural
+
+THREE.NoiseNode = NoiseNode;
+
+// bsdfs
+
+THREE.BlinnShininessExponentNode = BlinnShininessExponentNode;
+THREE.BlinnExponentToRoughnessNode = BlinnExponentToRoughnessNode;
+THREE.RoughnessToBlinnExponentNode = RoughnessToBlinnExponentNode;
+
+// misc
+
+THREE.TextureCubeUVNode = TextureCubeUVNode;
+THREE.TextureCubeNode = TextureCubeNode;
+THREE.NormalMapNode = NormalMapNode;
+THREE.BumpMapNode = BumpMapNode;
+
+// utils
+
+THREE.BypassNode = BypassNode;
+THREE.JoinNode = JoinNode;
+THREE.SwitchNode = SwitchNode;
+THREE.TimerNode = TimerNode;
+THREE.VelocityNode = VelocityNode;
+THREE.UVTransformNode = UVTransformNode;
+THREE.MaxMIPLevelNode = MaxMIPLevelNode;
+
+// effects
+
+THREE.BlurNode = BlurNode;
+THREE.ColorAdjustmentNode = ColorAdjustmentNode;
+THREE.LuminanceNode = LuminanceNode;
+
+// material nodes
+
+THREE.RawNode = RawNode;
+THREE.SpriteNode = SpriteNode;
+THREE.PhongNode = PhongNode;
+THREE.StandardNode = StandardNode;
+THREE.MeshStandardNode = MeshStandardNode;
+
+// materials
+
+THREE.NodeMaterial = NodeMaterial;
+THREE.SpriteNodeMaterial = SpriteNodeMaterial;
+THREE.PhongNodeMaterial = PhongNodeMaterial;
+THREE.StandardNodeMaterial = StandardNodeMaterial;
+THREE.MeshStandardNodeMaterial = MeshStandardNodeMaterial;

+ 71 - 49
examples/js/nodes/accessors/CameraNode.js

@@ -2,46 +2,66 @@
  * @author sunag / http://www.sunag.com.br/
  */
 
-THREE.CameraNode = function ( scope, camera ) {
+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 ) {
 
-	THREE.TempNode.call( this, 'v3' );
+	TempNode.call( this, 'v3' );
 
-	this.setScope( scope || THREE.CameraNode.POSITION );
+	this.setScope( scope || CameraNode.POSITION );
 	this.setCamera( camera );
 
 };
 
-THREE.CameraNode.fDepthColor = new THREE.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" ) );
+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
+	};
+	
+})();
 
-THREE.CameraNode.POSITION = 'position';
-THREE.CameraNode.DEPTH = 'depth';
-THREE.CameraNode.TO_VERTEX = 'toVertex';
+CameraNode.POSITION = 'position';
+CameraNode.DEPTH = 'depth';
+CameraNode.TO_VERTEX = 'toVertex';
 
-THREE.CameraNode.prototype = Object.create( THREE.TempNode.prototype );
-THREE.CameraNode.prototype.constructor = THREE.CameraNode;
-THREE.CameraNode.prototype.nodeType = "Camera";
+CameraNode.prototype = Object.create( TempNode.prototype );
+CameraNode.prototype.constructor = CameraNode;
+CameraNode.prototype.nodeType = "Camera";
 
-THREE.CameraNode.prototype.setCamera = function ( camera ) {
+CameraNode.prototype.setCamera = function ( camera ) {
 
 	this.camera = camera;
 	this.updateFrame = camera !== undefined ? this.onUpdateFrame : undefined;
 
 };
 
-THREE.CameraNode.prototype.setScope = function ( scope ) {
+CameraNode.prototype.setScope = function ( scope ) {
 
 	switch ( this.scope ) {
 
-		case THREE.CameraNode.DEPTH:
+		case CameraNode.DEPTH:
 
 			delete this.near;
 			delete this.far;
@@ -54,12 +74,12 @@ THREE.CameraNode.prototype.setScope = function ( scope ) {
 
 	switch ( scope ) {
 
-		case THREE.CameraNode.DEPTH:
+		case CameraNode.DEPTH:
 
 			var camera = this.camera;
 
-			this.near = new THREE.FloatNode( camera ? camera.near : 1 );
-			this.far = new THREE.FloatNode( camera ? camera.far : 1200 );
+			this.near = new FloatNode( camera ? camera.near : 1 );
+			this.far = new FloatNode( camera ? camera.far : 1200 );
 
 			break;
 
@@ -67,11 +87,12 @@ THREE.CameraNode.prototype.setScope = function ( scope ) {
 
 };
 
-THREE.CameraNode.prototype.getType = function ( builder ) {
+CameraNode.prototype.getType = function ( builder ) {
 
 	switch ( this.scope ) {
 
-		case THREE.CameraNode.DEPTH:
+		case CameraNode.DEPTH:
+		
 			return 'fv1';
 
 	}
@@ -80,12 +101,13 @@ THREE.CameraNode.prototype.getType = function ( builder ) {
 
 };
 
-THREE.CameraNode.prototype.isUnique = function ( builder ) {
+CameraNode.prototype.isUnique = function ( builder ) {
 
 	switch ( this.scope ) {
 
-		case THREE.CameraNode.DEPTH:
-		case THREE.CameraNode.TO_VERTEX:
+		case CameraNode.DEPTH:
+		case CameraNode.TO_VERTEX:
+		
 			return true;
 
 	}
@@ -94,11 +116,12 @@ THREE.CameraNode.prototype.isUnique = function ( builder ) {
 
 };
 
-THREE.CameraNode.prototype.isShared = function ( builder ) {
+CameraNode.prototype.isShared = function ( builder ) {
 
 	switch ( this.scope ) {
 
-		case THREE.CameraNode.POSITION:
+		case CameraNode.POSITION:
+		
 			return false;
 
 	}
@@ -107,32 +130,29 @@ THREE.CameraNode.prototype.isShared = function ( builder ) {
 
 };
 
-THREE.CameraNode.prototype.generate = function ( builder, output ) {
+CameraNode.prototype.generate = function ( builder, output ) {
 
-	var material = builder.material;
 	var result;
 
 	switch ( this.scope ) {
 
-		case THREE.CameraNode.POSITION:
+		case CameraNode.POSITION:
 
 			result = 'cameraPosition';
 
 			break;
 
-		case THREE.CameraNode.DEPTH:
-
-			var func = THREE.CameraNode.fDepthColor;
+		case CameraNode.DEPTH:
 
-			builder.include( func );
+			var depthColor = builder.include( CameraNode.Nodes.depthColor );
 
-			result = func.name + '(' + this.near.build( builder, 'fv1' ) + ',' + this.far.build( builder, 'fv1' ) + ')';
+			result = depthColor + '( ' + this.near.build( builder, 'fv1' ) + ', ' + this.far.build( builder, 'fv1' ) + ' )';
 
 			break;
 
-		case THREE.CameraNode.TO_VERTEX:
+		case CameraNode.TO_VERTEX:
 
-			result = 'normalize( ' + new THREE.PositionNode( THREE.PositionNode.WORLD ).build( builder, 'v3' ) + ' - cameraPosition )';
+			result = 'normalize( ' + new PositionNode( PositionNode.WORLD ).build( builder, 'v3' ) + ' - cameraPosition )';
 
 			break;
 
@@ -142,11 +162,11 @@ THREE.CameraNode.prototype.generate = function ( builder, output ) {
 
 };
 
-THREE.CameraNode.prototype.onUpdateFrame = function ( frame ) {
+CameraNode.prototype.onUpdateFrame = function ( frame ) {
 
 	switch ( this.scope ) {
 
-		case THREE.CameraNode.DEPTH:
+		case CameraNode.DEPTH:
 
 			var camera = this.camera;
 
@@ -159,9 +179,9 @@ THREE.CameraNode.prototype.onUpdateFrame = function ( frame ) {
 
 };
 
-THREE.CameraNode.prototype.copy = function ( source ) {
+CameraNode.prototype.copy = function ( source ) {
 			
-	THREE.GLNode.prototype.copy.call( this, source );
+	TempNode.prototype.copy.call( this, source );
 	
 	this.setScope( source.scope );
 
@@ -173,7 +193,7 @@ THREE.CameraNode.prototype.copy = function ( source ) {
 
 	switch ( source.scope ) {
 
-		case THREE.CameraNode.DEPTH:
+		case CameraNode.DEPTH:
 
 			this.near.number = source.near;
 			this.far.number = source.far;
@@ -184,7 +204,7 @@ THREE.CameraNode.prototype.copy = function ( source ) {
 	
 };
 
-THREE.CameraNode.prototype.toJSON = function ( meta ) {
+CameraNode.prototype.toJSON = function ( meta ) {
 
 	var data = this.getJSONNode( meta );
 
@@ -198,7 +218,7 @@ THREE.CameraNode.prototype.toJSON = function ( meta ) {
 
 		switch ( this.scope ) {
 
-			case THREE.CameraNode.DEPTH:
+			case CameraNode.DEPTH:
 
 				data.near = this.near.value;
 				data.far = this.far.value;
@@ -212,3 +232,5 @@ THREE.CameraNode.prototype.toJSON = function ( meta ) {
 	return data;
 
 };
+
+export { CameraNode };

+ 19 - 18
examples/js/nodes/accessors/ColorsNode.js

@@ -1,44 +1,43 @@
 /**
  * @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 ) {
 
-THREE.ColorsNode = function ( index ) {
-
-	THREE.TempNode.call( this, 'v4', { shared: false } );
+	TempNode.call( this, 'v4', { shared: false } );
 
 	this.index = index || 0;
 
 };
 
-THREE.ColorsNode.vertexDict = [ 'color', 'color2' ];
-THREE.ColorsNode.fragmentDict = [ 'vColor', 'vColor2' ];
-
-THREE.ColorsNode.prototype = Object.create( THREE.TempNode.prototype );
-THREE.ColorsNode.prototype.constructor = THREE.ColorsNode;
+ColorsNode.prototype = Object.create( TempNode.prototype );
+ColorsNode.prototype.constructor = ColorsNode;
 
-THREE.ColorsNode.prototype.generate = function ( builder, output ) {
+ColorsNode.prototype.generate = function ( builder, output ) {
 
-	var material = builder.material;
-	var result;
+	builder.material.requires.color[ this.index ] = true;
 
-	material.requires.color[ this.index ] = true;
-
-	if ( builder.isShader( 'vertex' ) ) result = THREE.ColorsNode.vertexDict[ this.index ];
-	else result = THREE.ColorsNode.fragmentDict[ this.index ];
+	var result = builder.isShader( 'vertex' ) ? vertexDict[ this.index ] : fragmentDict[ this.index ];
 
 	return builder.format( result, this.getType( builder ), output );
 
 };
 
-THREE.ColorsNode.prototype.copy = function ( source ) {
+ColorsNode.prototype.copy = function ( source ) {
 			
-	THREE.GLNode.prototype.copy.call( this, source );
+	TempNode.prototype.copy.call( this, source );
 	
 	this.index = source.index;
 	
 };
 
-THREE.ColorsNode.prototype.toJSON = function ( meta ) {
+ColorsNode.prototype.toJSON = function ( meta ) {
 
 	var data = this.getJSONNode( meta );
 
@@ -53,3 +52,5 @@ THREE.ColorsNode.prototype.toJSON = function ( meta ) {
 	return data;
 
 };
+
+export { ColorsNode };

+ 15 - 11
examples/js/nodes/accessors/LightNode.js

@@ -2,21 +2,23 @@
  * @author sunag / http://www.sunag.com.br/
  */
 
-THREE.LightNode = function ( scope ) {
+import { TempNode } from '../core/TempNode.js';
 
-	THREE.TempNode.call( this, 'v3', { shared: false } );
+function LightNode( scope ) {
 
-	this.scope = scope || THREE.LightNode.TOTAL;
+	TempNode.call( this, 'v3', { shared: false } );
+
+	this.scope = scope || LightNode.TOTAL;
 
 };
 
-THREE.LightNode.TOTAL = 'total';
+LightNode.TOTAL = 'total';
 
-THREE.LightNode.prototype = Object.create( THREE.TempNode.prototype );
-THREE.LightNode.prototype.constructor = THREE.LightNode;
-THREE.LightNode.prototype.nodeType = "Light";
+LightNode.prototype = Object.create( TempNode.prototype );
+LightNode.prototype.constructor = LightNode;
+LightNode.prototype.nodeType = "Light";
 
-THREE.LightNode.prototype.generate = function ( builder, output ) {
+LightNode.prototype.generate = function ( builder, output ) {
 
 	if ( builder.isCache( 'light' ) ) {
 
@@ -32,15 +34,15 @@ THREE.LightNode.prototype.generate = function ( builder, output ) {
 
 };
 
-THREE.LightNode.prototype.copy = function ( source ) {
+LightNode.prototype.copy = function ( source ) {
 			
-	THREE.GLNode.prototype.copy.call( this, source );
+	TempNode.prototype.copy.call( this, source );
 	
 	this.scope = source.scope;
 	
 };
 
-THREE.LightNode.prototype.toJSON = function ( meta ) {
+LightNode.prototype.toJSON = function ( meta ) {
 
 	var data = this.getJSONNode( meta );
 
@@ -55,3 +57,5 @@ THREE.LightNode.prototype.toJSON = function ( meta ) {
 	return data;
 
 };
+
+export { LightNode };

+ 47 - 26
examples/js/nodes/accessors/NormalNode.js

@@ -2,27 +2,31 @@
  * @author sunag / http://www.sunag.com.br/
  */
 
-THREE.NormalNode = function ( scope ) {
+import { TempNode } from '../core/TempNode.js';
+import { NodeLib } from '../core/NodeLib.js';
+ 
+function NormalNode( scope ) {
 
-	THREE.TempNode.call( this, 'v3' );
+	TempNode.call( this, 'v3' );
 
-	this.scope = scope || THREE.NormalNode.LOCAL;
+	this.scope = scope || NormalNode.LOCAL;
 
 };
 
-THREE.NormalNode.LOCAL = 'local';
-THREE.NormalNode.WORLD = 'world';
-THREE.NormalNode.VIEW = 'view';
+NormalNode.LOCAL = 'local';
+NormalNode.WORLD = 'world';
+NormalNode.VIEW = 'view';
 
-THREE.NormalNode.prototype = Object.create( THREE.TempNode.prototype );
-THREE.NormalNode.prototype.constructor = THREE.NormalNode;
-THREE.NormalNode.prototype.nodeType = "Normal";
+NormalNode.prototype = Object.create( TempNode.prototype );
+NormalNode.prototype.constructor = NormalNode;
+NormalNode.prototype.nodeType = "Normal";
 
-THREE.NormalNode.prototype.isShared = function ( builder ) {
+NormalNode.prototype.isShared = function ( builder ) {
 
 	switch ( this.scope ) {
 
-		case THREE.NormalNode.WORLD:
+		case NormalNode.WORLD:
+
 			return true;
 
 	}
@@ -31,32 +35,29 @@ THREE.NormalNode.prototype.isShared = function ( builder ) {
 
 };
 
-THREE.NormalNode.prototype.generate = function ( builder, output ) {
+NormalNode.prototype.generate = function ( builder, output ) {
 
-	var material = builder.material;
 	var result;
 
 	switch ( this.scope ) {
 
-		case THREE.NormalNode.LOCAL:
+		case NormalNode.LOCAL:
 
-			material.requires.normal = true;
+			builder.requires.normal = true;
 
-			if ( builder.isShader( 'vertex' ) ) result = 'normal';
-			else result = 'vObjectNormal';
+			result = builder.isShader( 'vertex' ) ? 'normal' : 'vObjectNormal';
 
 			break;
 
-		case THREE.NormalNode.WORLD:
-
-			material.requires.worldNormal = true;
+		case NormalNode.WORLD:
 
-			if ( builder.isShader( 'vertex' ) ) result = '( modelMatrix * vec4( objectNormal, 0.0 ) ).xyz';
-			else result = 'vWNormal';
+			builder.requires.worldNormal = true;
 
+			result = builder.isShader( 'vertex' ) ? '( modelMatrix * vec4( objectNormal, 0.0 ) ).xyz' : 'vWNormal';
+			
 			break;
 
-		case THREE.NormalNode.VIEW:
+		case NormalNode.VIEW:
 
 			result = 'vNormal';
 
@@ -68,15 +69,15 @@ THREE.NormalNode.prototype.generate = function ( builder, output ) {
 
 };
 
-THREE.NormalNode.prototype.copy = function ( source ) {
+NormalNode.prototype.copy = function ( source ) {
 	
-	THREE.GLNode.prototype.copy.call( this, source );
+	TempNode.prototype.copy.call( this, source );
 	
 	this.scope = source.scope;
 	
 };
 
-THREE.NormalNode.prototype.toJSON = function ( meta ) {
+NormalNode.prototype.toJSON = function ( meta ) {
 
 	var data = this.getJSONNode( meta );
 
@@ -91,3 +92,23 @@ THREE.NormalNode.prototype.toJSON = function ( meta ) {
 	return data;
 
 };
+
+NodeLib.addKeyword( 'normal', function () {
+
+	return new NormalNode();
+
+} );
+
+NodeLib.addKeyword( 'worldNormal', function () {
+
+	return new NormalNode( NormalNode.WORLD );
+
+} );
+
+NodeLib.addKeyword( 'viewNormal', function () {
+
+	return new NormalNode( NormalNode.VIEW );
+
+} );
+
+export { NormalNode };

+ 54 - 34
examples/js/nodes/accessors/PositionNode.js

@@ -2,28 +2,32 @@
  * @author sunag / http://www.sunag.com.br/
  */
 
-THREE.PositionNode = function ( scope ) {
+import { TempNode } from '../core/TempNode.js';
+import { NodeLib } from '../core/NodeLib.js';
+ 
+function PositionNode( scope ) {
 
-	THREE.TempNode.call( this, 'v3' );
+	TempNode.call( this, 'v3' );
 
-	this.scope = scope || THREE.PositionNode.LOCAL;
+	this.scope = scope || PositionNode.LOCAL;
 
 };
 
-THREE.PositionNode.LOCAL = 'local';
-THREE.PositionNode.WORLD = 'world';
-THREE.PositionNode.VIEW = 'view';
-THREE.PositionNode.PROJECTION = 'projection';
+PositionNode.LOCAL = 'local';
+PositionNode.WORLD = 'world';
+PositionNode.VIEW = 'view';
+PositionNode.PROJECTION = 'projection';
 
-THREE.PositionNode.prototype = Object.create( THREE.TempNode.prototype );
-THREE.PositionNode.prototype.constructor = THREE.PositionNode;
-THREE.PositionNode.prototype.nodeType = "Position";
+PositionNode.prototype = Object.create( TempNode.prototype );
+PositionNode.prototype.constructor = PositionNode;
+PositionNode.prototype.nodeType = "Position";
 
-THREE.PositionNode.prototype.getType = function ( builder ) {
+PositionNode.prototype.getType = function ( builder ) {
 
 	switch ( this.scope ) {
 
-		case THREE.PositionNode.PROJECTION:
+		case PositionNode.PROJECTION:
+		
 			return 'v4';
 
 	}
@@ -32,12 +36,13 @@ THREE.PositionNode.prototype.getType = function ( builder ) {
 
 };
 
-THREE.PositionNode.prototype.isShared = function ( builder ) {
+PositionNode.prototype.isShared = function ( builder ) {
 
 	switch ( this.scope ) {
 
-		case THREE.PositionNode.LOCAL:
-		case THREE.PositionNode.WORLD:
+		case PositionNode.LOCAL:
+		case PositionNode.WORLD:
+		
 			return false;
 
 	}
@@ -46,42 +51,37 @@ THREE.PositionNode.prototype.isShared = function ( builder ) {
 
 };
 
-THREE.PositionNode.prototype.generate = function ( builder, output ) {
+PositionNode.prototype.generate = function ( builder, output ) {
 
-	var material = builder.material;
 	var result;
 
 	switch ( this.scope ) {
 
-		case THREE.PositionNode.LOCAL:
+		case PositionNode.LOCAL:
 
-			material.requires.position = true;
+			builder.requires.position = true;
 
-			if ( builder.isShader( 'vertex' ) ) result = 'transformed';
-			else result = 'vPosition';
+			result = builder.isShader( 'vertex' ) ? 'transformed' : 'vPosition';
 
 			break;
 
-		case THREE.PositionNode.WORLD:
+		case PositionNode.WORLD:
 
-			material.requires.worldPosition = true;
+			builder.requires.worldPosition = true;
 
-			if ( builder.isShader( 'vertex' ) ) result = 'vWPosition';
-			else result = 'vWPosition';
+			result = 'vWPosition';
 
 			break;
 
-		case THREE.PositionNode.VIEW:
+		case PositionNode.VIEW:
 
-			if ( builder.isShader( 'vertex' ) ) result = '-mvPosition.xyz';
-			else result = 'vViewPosition';
+			result = builder.isShader( 'vertex' ) ? '-mvPosition.xyz' : 'vViewPosition';
 
 			break;
 
-		case THREE.PositionNode.PROJECTION:
+		case PositionNode.PROJECTION:
 
-			if ( builder.isShader( 'vertex' ) ) result = '(projectionMatrix * modelViewMatrix * vec4( position, 1.0 ))';
-			else result = 'vec4( 0.0 )';
+			result = builder.isShader( 'vertex' ) ? '( projectionMatrix * modelViewMatrix * vec4( position, 1.0 ) )' : 'vec4( 0.0 )';
 
 			break;
 
@@ -91,15 +91,15 @@ THREE.PositionNode.prototype.generate = function ( builder, output ) {
 
 };
 
-THREE.PositionNode.prototype.copy = function ( source ) {
+PositionNode.prototype.copy = function ( source ) {
 			
-	THREE.GLNode.prototype.copy.call( this, source );
+	TempNode.prototype.copy.call( this, source );
 	
 	this.scope = source.scope;
 	
 };
 
-THREE.PositionNode.prototype.toJSON = function ( meta ) {
+PositionNode.prototype.toJSON = function ( meta ) {
 
 	var data = this.getJSONNode( meta );
 
@@ -114,3 +114,23 @@ THREE.PositionNode.prototype.toJSON = function ( meta ) {
 	return data;
 
 };
+
+NodeLib.addKeyword( 'position', function () {
+
+	return new PositionNode();
+
+} );
+
+NodeLib.addKeyword( 'worldPosition', function () {
+
+	return new PositionNode( PositionNode.WORLD );
+
+} );
+
+NodeLib.addKeyword( 'viewPosition', function () {
+
+	return new PositionNode( NormalNode.VIEW );
+
+} );
+
+export { PositionNode };

+ 48 - 34
examples/js/nodes/accessors/ReflectNode.js

@@ -2,27 +2,30 @@
  * @author sunag / http://www.sunag.com.br/
  */
 
-THREE.ReflectNode = function ( scope ) {
+import { TempNode } from '../core/TempNode.js';
 
-	THREE.TempNode.call( this, 'v3', { unique: true } );
+function ReflectNode( scope ) {
 
-	this.scope = scope || THREE.ReflectNode.CUBE;
+	TempNode.call( this, 'v3', { unique: true } );
+
+	this.scope = scope || ReflectNode.CUBE;
 
 };
 
-THREE.ReflectNode.CUBE = 'cube';
-THREE.ReflectNode.SPHERE = 'sphere';
-THREE.ReflectNode.VECTOR = 'vector';
+ReflectNode.CUBE = 'cube';
+ReflectNode.SPHERE = 'sphere';
+ReflectNode.VECTOR = 'vector';
 
-THREE.ReflectNode.prototype = Object.create( THREE.TempNode.prototype );
-THREE.ReflectNode.prototype.constructor = THREE.ReflectNode;
-THREE.ReflectNode.prototype.nodeType = "Reflect";
+ReflectNode.prototype = Object.create( TempNode.prototype );
+ReflectNode.prototype.constructor = ReflectNode;
+ReflectNode.prototype.nodeType = "Reflect";
 
-THREE.ReflectNode.prototype.getType = function ( builder ) {
+ReflectNode.prototype.getType = function ( builder ) {
 
 	switch ( this.scope ) {
 
-		case THREE.ReflectNode.SPHERE:
+		case ReflectNode.SPHERE:
+
 			return 'v2';
 
 	}
@@ -31,48 +34,57 @@ THREE.ReflectNode.prototype.getType = function ( builder ) {
 
 };
 
-THREE.ReflectNode.prototype.generate = function ( builder, output ) {
+ReflectNode.prototype.generate = function ( builder, output ) {
 
-	var result;
+	if ( builder.isShader( 'fragment' ) ) {
+		
+		var result;
 
-	switch ( this.scope ) {
+		switch ( this.scope ) {
 
-		case THREE.ReflectNode.VECTOR:
-//vec3 reflectVec = reflect( -geometry.viewDir, geometry.normal )
-			//builder.material.addFragmentNode( 'vec3 reflectVec = inverseTransformDirection( reflect( -geometry.viewDir, geometry.normal ), viewMatrix );' );
-			builder.material.addFragmentNode( 'vec3 reflectVec = inverseTransformDirection( reflect( -normalize( vViewPosition ), normal ), viewMatrix );' );
+			case ReflectNode.VECTOR:
 
-			result = 'reflectVec';
+				builder.addNodeCode( 'vec3 reflectVec = inverseTransformDirection( reflect( -normalize( vViewPosition ), normal ), viewMatrix );' );
 
-			break;
+				result = 'reflectVec';
 
-		case THREE.ReflectNode.CUBE:
+				break;
 
-			var reflectVec = new THREE.ReflectNode( THREE.ReflectNode.VECTOR ).build( builder, 'v3' );
-//flipEnvMap
-			builder.material.addFragmentNode( 'vec3 reflectCubeVec = vec3( -1.0 * ' + reflectVec + '.x, ' + reflectVec + '.yz );' );
+			case ReflectNode.CUBE:
 
-			result = 'reflectCubeVec';
+				var reflectVec = new ReflectNode( ReflectNode.VECTOR ).build( builder, 'v3' );
 
-			break;
+				builder.addNodeCode( 'vec3 reflectCubeVec = vec3( -1.0 * ' + reflectVec + '.x, ' + reflectVec + '.yz );' );
 
-		case THREE.ReflectNode.SPHERE:
+				result = 'reflectCubeVec';
 
-			var reflectVec = new THREE.ReflectNode( THREE.ReflectNode.VECTOR ).build( builder, 'v3' );
+				break;
 
-			builder.material.addFragmentNode( 'vec2 reflectSphereVec = normalize((viewMatrix * vec4(' + reflectVec + ', 0.0 )).xyz + vec3(0.0,0.0,1.0)).xy * 0.5 + 0.5;' );
+			case ReflectNode.SPHERE:
 
-			result = 'reflectSphereVec';
+				var reflectVec = new ReflectNode( ReflectNode.VECTOR ).build( builder, 'v3' );
 
-			break;
+				builder.addNodeCode( 'vec2 reflectSphereVec = normalize( ( viewMatrix * vec4( ' + reflectVec + ', 0.0 ) ).xyz + vec3( 0.0, 0.0, 1.0 ) ).xy * 0.5 + 0.5;' );
 
-	}
+				result = 'reflectSphereVec';
+
+				break;
 
-	return builder.format( result, this.getType( this.type ), output );
+		}
+
+		return builder.format( result, this.getType( this.type ), output );
+	
+	} else {
+		
+		console.warn( "THREE.ReflectNode is not compatible with " + builder.shader + " shader." );
+
+		return builder.format( 'vec3( 0.0 )', this.type, output );
+		
+	}
 
 };
 
-THREE.ReflectNode.prototype.toJSON = function ( meta ) {
+ReflectNode.prototype.toJSON = function ( meta ) {
 
 	var data = this.getJSONNode( meta );
 
@@ -87,3 +99,5 @@ THREE.ReflectNode.prototype.toJSON = function ( meta ) {
 	return data;
 
 };
+
+export { ReflectNode };

+ 53 - 0
examples/js/nodes/accessors/ResolutionNode.js

@@ -0,0 +1,53 @@
+/**
+ * @author sunag / http://www.sunag.com.br/
+ */
+
+import { Vector2Node } from '../inputs/Vector2Node.js';
+ 
+function ResolutionNode( renderer ) {
+
+	Vector2Node.call( this );
+
+	this.renderer = renderer;
+
+};
+
+ResolutionNode.prototype = Object.create( Vector2Node.prototype );
+ResolutionNode.prototype.constructor = ResolutionNode;
+ResolutionNode.prototype.nodeType = "Resolution";
+
+ResolutionNode.prototype.updateFrame = function ( frame ) {
+
+	var size = this.renderer.getSize(),
+		pixelRatio = this.renderer.getPixelRatio();
+
+	this.x = size.width * pixelRatio;
+	this.y = size.height * pixelRatio;
+
+};
+
+ResolutionNode.prototype.copy = function ( source ) {
+			
+	Vector2Node.prototype.copy.call( this, source );
+	
+	this.renderer = source.renderer;
+	
+};
+
+ResolutionNode.prototype.toJSON = function ( meta ) {
+
+	var data = this.getJSONNode( meta );
+
+	if ( ! data ) {
+
+		data = this.createJSONNode( meta );
+
+		data.renderer = this.renderer.uuid;
+
+	}
+
+	return data;
+
+};
+
+export { ResolutionNode };

+ 15 - 11
examples/js/nodes/accessors/ScreenUVNode.js

@@ -2,26 +2,27 @@
  * @author sunag / http://www.sunag.com.br/
  */
 
-THREE.ScreenUVNode = function ( resolution ) {
+import { TempNode } from '../core/TempNode.js';
+ 
+function ScreenUVNode( resolution ) {
 
-	THREE.TempNode.call( this, 'v2' );
+	TempNode.call( this, 'v2' );
 
 	this.resolution = resolution;
 
 };
 
-THREE.ScreenUVNode.prototype = Object.create( THREE.TempNode.prototype );
-THREE.ScreenUVNode.prototype.constructor = THREE.ScreenUVNode;
-THREE.ScreenUVNode.prototype.nodeType = "ScreenUV";
+ScreenUVNode.prototype = Object.create( TempNode.prototype );
+ScreenUVNode.prototype.constructor = ScreenUVNode;
+ScreenUVNode.prototype.nodeType = "ScreenUV";
 
-THREE.ScreenUVNode.prototype.generate = function ( builder, output ) {
+ScreenUVNode.prototype.generate = function ( builder, output ) {
 
-	var material = builder.material;
 	var result;
 
 	if ( builder.isShader( 'fragment' ) ) {
 
-		result = '(gl_FragCoord.xy/' + this.resolution.build( builder, 'v2' ) + ')';
+		result = '( gl_FragCoord.xy / ' + this.resolution.build( builder, 'v2' ) + ')';
 
 	} else {
 
@@ -35,15 +36,15 @@ THREE.ScreenUVNode.prototype.generate = function ( builder, output ) {
 
 };
 
-THREE.ScreenUVNode.prototype.copy = function ( source ) {
+ScreenUVNode.prototype.copy = function ( source ) {
 			
-	THREE.GLNode.prototype.copy.call( this, source );
+	TempNode.prototype.copy.call( this, source );
 	
 	this.resolution = source.resolution;
 	
 };
 
-THREE.ScreenUVNode.prototype.toJSON = function ( meta ) {
+ScreenUVNode.prototype.toJSON = function ( meta ) {
 
 	var data = this.getJSONNode( meta );
 
@@ -58,3 +59,6 @@ THREE.ScreenUVNode.prototype.toJSON = function ( meta ) {
 	return data;
 
 };
+
+export { ScreenUVNode };
+

+ 31 - 18
examples/js/nodes/accessors/UVNode.js

@@ -2,44 +2,43 @@
  * @author sunag / http://www.sunag.com.br/
  */
 
-THREE.UVNode = function ( index ) {
+import { TempNode } from '../core/TempNode.js';
+import { NodeLib } from '../core/NodeLib.js';
+ 
+var vertexDict = [ 'uv', 'uv2' ],
+	fragmentDict = [ 'vUv', 'vUv2' ];
+ 
+function UVNode( index ) {
 
-	THREE.TempNode.call( this, 'v2', { shared: false } );
+	TempNode.call( this, 'v2', { shared: false } );
 
 	this.index = index || 0;
 
 };
 
-THREE.UVNode.vertexDict = [ 'uv', 'uv2' ];
-THREE.UVNode.fragmentDict = [ 'vUv', 'vUv2' ];
+UVNode.prototype = Object.create( TempNode.prototype );
+UVNode.prototype.constructor = UVNode;
+UVNode.prototype.nodeType = "UV";
 
-THREE.UVNode.prototype = Object.create( THREE.TempNode.prototype );
-THREE.UVNode.prototype.constructor = THREE.UVNode;
-THREE.UVNode.prototype.nodeType = "UV";
+UVNode.prototype.generate = function ( builder, output ) {
 
-THREE.UVNode.prototype.generate = function ( builder, output ) {
+	builder.requires.uv[ this.index ] = true;
 
-	var material = builder.material;
-	var result;
-
-	material.requires.uv[ this.index ] = true;
-
-	if ( builder.isShader( 'vertex' ) ) result = THREE.UVNode.vertexDict[ this.index ];
-	else result = THREE.UVNode.fragmentDict[ this.index ];
+	var result = builder.isShader( 'vertex' ) ? vertexDict[ this.index ] : fragmentDict[ this.index ];
 
 	return builder.format( result, this.getType( builder ), output );
 
 };
 
-THREE.UVNode.prototype.copy = function ( source ) {
+UVNode.prototype.copy = function ( source ) {
 		
-	THREE.GLNode.prototype.copy.call( this, source );
+	TempNode.prototype.copy.call( this, source );
 	
 	this.index = source.index;
 	
 };
 
-THREE.UVNode.prototype.toJSON = function ( meta ) {
+UVNode.prototype.toJSON = function ( meta ) {
 
 	var data = this.getJSONNode( meta );
 
@@ -54,3 +53,17 @@ THREE.UVNode.prototype.toJSON = function ( meta ) {
 	return data;
 
 };
+
+NodeLib.addKeyword( 'uv', function () {
+
+	return new UVNode();
+
+} );
+
+NodeLib.addKeyword( 'uv2', function () {
+
+	return new UVNode( 1 );
+
+} );
+
+export { UVNode };

+ 50 - 0
examples/js/nodes/bsdfs/BlinnExponentToRoughnessNode.js

@@ -0,0 +1,50 @@
+/**
+ * @author sunag / http://www.sunag.com.br/
+ */
+
+import { TempNode } from '../core/TempNode.js';
+import { BlinnShininessExponentNode } from './BlinnShininessExponentNode.js';
+
+function BlinnExponentToRoughnessNode( blinnExponent ) {
+
+	TempNode.call( this, 'fv1' );
+
+	this.blinnExponent = blinnExponent || new BlinnShininessExponentNode();
+
+};
+
+BlinnExponentToRoughnessNode.prototype = Object.create( TempNode.prototype );
+BlinnExponentToRoughnessNode.prototype.constructor = BlinnExponentToRoughnessNode;
+BlinnExponentToRoughnessNode.prototype.nodeType = "BlinnExponentToRoughness";
+
+BlinnExponentToRoughnessNode.prototype.generate = function ( builder, output ) {
+
+	return builder.format( 'BlinnExponentToGGXRoughness( ' + this.blinnExponent.build( builder, 'fv1' ) + ' )', this.type, output );
+
+};
+
+BlinnExponentToRoughnessNode.prototype.copy = function ( source ) {
+			
+	TempNode.prototype.copy.call( this, source );
+	
+	this.blinnExponent = source.blinnExponent;
+	
+};
+
+BlinnExponentToRoughnessNode.prototype.toJSON = function ( meta ) {
+
+	var data = this.getJSONNode( meta );
+
+	if ( ! data ) {
+
+		data = this.createJSONNode( meta );
+
+		data.blinnExponent = this.blinnExponent;
+
+	}
+
+	return data;
+
+};
+
+export { BlinnExponentToRoughnessNode };

+ 31 - 0
examples/js/nodes/bsdfs/BlinnShininessExponentNode.js

@@ -0,0 +1,31 @@
+/**
+ * @author sunag / http://www.sunag.com.br/
+ */
+
+import { TempNode } from '../core/TempNode.js';
+
+function BlinnShininessExponentNode() {
+
+	TempNode.call( this, 'fv1' );
+
+};
+
+BlinnShininessExponentNode.prototype = Object.create( TempNode.prototype );
+BlinnShininessExponentNode.prototype.constructor = BlinnShininessExponentNode;
+BlinnShininessExponentNode.prototype.nodeType = "BlinnShininessExponent";
+
+BlinnShininessExponentNode.prototype.generate = function ( builder, output ) {
+
+	if ( builder.isCache( 'clearCoat' ) ) {
+
+		return builder.format( 'Material_ClearCoat_BlinnShininessExponent( material )', this.type, output );
+
+	} else {
+
+		return builder.format( 'Material_BlinnShininessExponent( material )', this.type, output );
+
+	}
+
+};
+
+export { BlinnShininessExponentNode };

+ 91 - 0
examples/js/nodes/bsdfs/RoughnessToBlinnExponentNode.js

@@ -0,0 +1,91 @@
+/**
+ * @author sunag / http://www.sunag.com.br/
+ */
+
+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, 'fv1' );
+
+	this.texture = texture;
+
+	this.maxMIPLevel = new MaxMIPLevelNode( texture );
+	this.blinnShininessExponent = new BlinnShininessExponentNode();
+
+};
+
+RoughnessToBlinnExponentNode.Nodes = (function() {
+
+	var getSpecularMIPLevel = new FunctionNode( [
+		// taken from here: http://casual-effects.blogspot.ca/2011/08/plausible-environment-lighting-in-two.html
+		"float getSpecularMIPLevel( const in float blinnShininessExponent, const in float maxMIPLevelScalar ) {",
+
+		//	float envMapWidth = pow( 2.0, maxMIPLevelScalar );
+		//	float desiredMIPLevel = log2( envMapWidth * sqrt( 3.0 ) ) - 0.5 * log2( pow2( blinnShininessExponent ) + 1.0 );
+
+		"	float desiredMIPLevel = maxMIPLevelScalar - 0.79248 - 0.5 * log2( pow2( blinnShininessExponent ) + 1.0 );",
+
+		// clamp to allowable LOD ranges.
+		"	return clamp( desiredMIPLevel, 0.0, maxMIPLevelScalar );",
+		"}"
+	].join( "\n" ) );
+	
+	return {
+		getSpecularMIPLevel: getSpecularMIPLevel
+	};
+	
+})();
+
+RoughnessToBlinnExponentNode.prototype = Object.create( TempNode.prototype );
+RoughnessToBlinnExponentNode.prototype.constructor = RoughnessToBlinnExponentNode;
+RoughnessToBlinnExponentNode.prototype.nodeType = "RoughnessToBlinnExponent";
+
+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, 'fv1' ) + ', ' + this.maxMIPLevel.build( builder, 'fv1' ) + ' )', this.type, output );
+
+	} else {
+
+		console.warn( "THREE.RoughnessToBlinnExponentNode is not compatible with " + builder.shader + " shader." );
+
+		return builder.format( '0.0', this.type, output );
+
+	}
+
+};
+
+RoughnessToBlinnExponentNode.prototype.copy = function ( source ) {
+			
+	TempNode.prototype.copy.call( this, source );
+	
+	this.texture = source.texture;
+	
+};
+
+RoughnessToBlinnExponentNode.prototype.toJSON = function ( meta ) {
+
+	var data = this.getJSONNode( meta );
+
+	if ( ! data ) {
+
+		data = this.createJSONNode( meta );
+
+		data.texture = this.texture;
+
+	}
+
+	return data;
+
+};
+
+export { RoughnessToBlinnExponentNode };

+ 20 - 13
examples/js/nodes/core/AttributeNode.js

@@ -2,25 +2,27 @@
  * @author sunag / http://www.sunag.com.br/
  */
 
-THREE.AttributeNode = function ( name, type ) {
+import { GLNode } from './GLNode.js';
 
-	THREE.GLNode.call( this, type );
+function AttributeNode( name, type ) {
+
+	GLNode.call( this, type );
 
 	this.name = name;
 
 };
 
-THREE.AttributeNode.prototype = Object.create( THREE.GLNode.prototype );
-THREE.AttributeNode.prototype.constructor = THREE.AttributeNode;
-THREE.AttributeNode.prototype.nodeType = "Attribute";
+AttributeNode.prototype = Object.create( GLNode.prototype );
+AttributeNode.prototype.constructor = AttributeNode;
+AttributeNode.prototype.nodeType = "Attribute";
 
-THREE.AttributeNode.prototype.getAttributeType = function ( builder ) {
+AttributeNode.prototype.getAttributeType = function ( builder ) {
 
 	return typeof this.type === 'number' ? builder.getConstructorFromLength( this.type ) : this.type;
 
 };
 
-THREE.AttributeNode.prototype.getType = function ( builder ) {
+AttributeNode.prototype.getType = function ( builder ) {
 
 	var type = this.getAttributeType( builder );
 
@@ -28,25 +30,28 @@ THREE.AttributeNode.prototype.getType = function ( builder ) {
 
 };
 
-THREE.AttributeNode.prototype.generate = function ( builder, output ) {
+AttributeNode.prototype.generate = function ( builder, output ) {
 
 	var type = this.getAttributeType( builder );
 
-	var attribute = builder.material.getAttribute( this.name, type );
+	var attribute = builder.getAttribute( this.name, type ),
+		name = builder.isShader( 'vertex' ) ? this.name : attribute.varying.name;
 
-	return builder.format( builder.isShader( 'vertex' ) ? this.name : attribute.varying.name, this.getType( builder ), output );
+	console.log( attribute );
+		
+	return builder.format( name, this.getType( builder ), output );
 
 };
 
-THREE.AttributeNode.prototype.copy = function ( source ) {
+AttributeNode.prototype.copy = function ( source ) {
 			
-	THREE.GLNode.prototype.copy.call( this, source );
+	GLNode.prototype.copy.call( this, source );
 	
 	this.type = source.type;
 	
 };
 
-THREE.AttributeNode.prototype.toJSON = function ( meta ) {
+AttributeNode.prototype.toJSON = function ( meta ) {
 
 	var data = this.getJSONNode( meta );
 
@@ -61,3 +66,5 @@ THREE.AttributeNode.prototype.toJSON = function ( meta ) {
 	return data;
 
 };
+
+export { AttributeNode };

+ 25 - 21
examples/js/nodes/core/ConstNode.js

@@ -2,40 +2,42 @@
  * @author sunag / http://www.sunag.com.br/
  */
 
-THREE.ConstNode = function ( src, useDefine ) {
+import { TempNode } from './TempNode.js';
 
-	THREE.TempNode.call( this );
+function ConstNode( src, useDefine ) {
 
-	this.eval( src || THREE.ConstNode.PI, useDefine );
+	TempNode.call( this );
+
+	this.eval( src || ConstNode.PI, useDefine );
 
 };
 
-THREE.ConstNode.PI = 'PI';
-THREE.ConstNode.PI2 = 'PI2';
-THREE.ConstNode.RECIPROCAL_PI = 'RECIPROCAL_PI';
-THREE.ConstNode.RECIPROCAL_PI2 = 'RECIPROCAL_PI2';
-THREE.ConstNode.LOG2 = 'LOG2';
-THREE.ConstNode.EPSILON = 'EPSILON';
+ConstNode.PI = 'PI';
+ConstNode.PI2 = 'PI2';
+ConstNode.RECIPROCAL_PI = 'RECIPROCAL_PI';
+ConstNode.RECIPROCAL_PI2 = 'RECIPROCAL_PI2';
+ConstNode.LOG2 = 'LOG2';
+ConstNode.EPSILON = 'EPSILON';
 
-THREE.ConstNode.rDeclaration = /^([a-z_0-9]+)\s([a-z_0-9]+)\s?\=?\s?(.*?)(\;|$)/i;
+ConstNode.rDeclaration = /^([a-z_0-9]+)\s([a-z_0-9]+)\s?\=?\s?(.*?)(\;|$)/i;
 
-THREE.ConstNode.prototype = Object.create( THREE.TempNode.prototype );
-THREE.ConstNode.prototype.constructor = THREE.ConstNode;
-THREE.ConstNode.prototype.nodeType = "Const";
+ConstNode.prototype = Object.create( TempNode.prototype );
+ConstNode.prototype.constructor = ConstNode;
+ConstNode.prototype.nodeType = "Const";
 
-THREE.ConstNode.prototype.getType = function ( builder ) {
+ConstNode.prototype.getType = function ( builder ) {
 
 	return builder.getTypeByFormat( this.type );
 
 };
 
-THREE.ConstNode.prototype.eval = function ( src, useDefine ) {
+ConstNode.prototype.eval = function ( src, useDefine ) {
 
 	this.src = src || '';
 
 	var name, type, value = "";
 
-	var match = this.src.match( THREE.ConstNode.rDeclaration );
+	var match = this.src.match( ConstNode.rDeclaration );
 
 	this.useDefine = useDefine || this.src.charAt(0) === '#';
 
@@ -58,7 +60,7 @@ THREE.ConstNode.prototype.eval = function ( src, useDefine ) {
 
 };
 
-THREE.ConstNode.prototype.build = function ( builder, output ) {
+ConstNode.prototype.build = function ( builder, output ) {
 
 	if ( output === 'source' ) {
 
@@ -88,21 +90,21 @@ THREE.ConstNode.prototype.build = function ( builder, output ) {
 
 };
 
-THREE.ConstNode.prototype.generate = function ( builder, output ) {
+ConstNode.prototype.generate = function ( builder, output ) {
 
 	return builder.format( this.name, this.getType( builder ), output );
 
 };
 
-THREE.ConstNode.prototype.copy = function ( source ) {
+ConstNode.prototype.copy = function ( source ) {
 	
-	THREE.GLNode.prototype.copy.call( this, source );
+	TempNode.prototype.copy.call( this, source );
 	
 	this.eval( source.src, source.useDefine );	
 	
 };
 
-THREE.ConstNode.prototype.toJSON = function ( meta ) {
+ConstNode.prototype.toJSON = function ( meta ) {
 
 	var data = this.getJSONNode( meta );
 
@@ -119,3 +121,5 @@ THREE.ConstNode.prototype.toJSON = function ( meta ) {
 	return data;
 
 };
+
+export { ConstNode };

+ 16 - 12
examples/js/nodes/core/FunctionCallNode.js

@@ -2,38 +2,40 @@
  * @author sunag / http://www.sunag.com.br/
  */
 
-THREE.FunctionCallNode = function ( func, inputs ) {
+import { TempNode } from './TempNode.js';
+ 
+function FunctionCallNode( func, inputs ) {
 
-	THREE.TempNode.call( this );
+	TempNode.call( this );
 
 	this.setFunction( func, inputs );
 
 };
 
-THREE.FunctionCallNode.prototype = Object.create( THREE.TempNode.prototype );
-THREE.FunctionCallNode.prototype.constructor = THREE.FunctionCallNode;
-THREE.FunctionCallNode.prototype.nodeType = "FunctionCall";
+FunctionCallNode.prototype = Object.create( TempNode.prototype );
+FunctionCallNode.prototype.constructor = FunctionCallNode;
+FunctionCallNode.prototype.nodeType = "FunctionCall";
 
-THREE.FunctionCallNode.prototype.setFunction = function ( func, inputs ) {
+FunctionCallNode.prototype.setFunction = function ( func, inputs ) {
 
 	this.value = func;
 	this.inputs = inputs || [];
 
 };
 
-THREE.FunctionCallNode.prototype.getFunction = function () {
+FunctionCallNode.prototype.getFunction = function () {
 
 	return this.value;
 
 };
 
-THREE.FunctionCallNode.prototype.getType = function ( builder ) {
+FunctionCallNode.prototype.getType = function ( builder ) {
 
 	return this.value.getType( builder );
 
 };
 
-THREE.FunctionCallNode.prototype.generate = function ( builder, output ) {
+FunctionCallNode.prototype.generate = function ( builder, output ) {
 
 	var material = builder.material;
 
@@ -58,9 +60,9 @@ THREE.FunctionCallNode.prototype.generate = function ( builder, output ) {
 
 };
 
-THREE.FunctionCallNode.prototype.copy = function ( source ) {
+FunctionCallNode.prototype.copy = function ( source ) {
 			
-	THREE.GLNode.prototype.copy.call( this, source );
+	TempNode.prototype.copy.call( this, source );
 	
 	for ( var prop in source.inputs ) {
 
@@ -72,7 +74,7 @@ THREE.FunctionCallNode.prototype.copy = function ( source ) {
 	
 };
 
-THREE.FunctionCallNode.prototype.toJSON = function ( meta ) {
+FunctionCallNode.prototype.toJSON = function ( meta ) {
 
 	var data = this.getJSONNode( meta );
 
@@ -104,3 +106,5 @@ THREE.FunctionCallNode.prototype.toJSON = function ( meta ) {
 	return data;
 
 };
+
+export { FunctionCallNode };

+ 33 - 27
examples/js/nodes/core/FunctionNode.js

@@ -3,12 +3,15 @@
  * @thanks bhouston / https://clara.io/
  */
 
-THREE.FunctionNode = function ( src, includesOrType, extensionsOrKeywords, keywordsOrExtensions, includes ) {
+import { TempNode } from './TempNode.js';
+import { NodeLib } from './NodeLib.js';
+
+function FunctionNode( src, includesOrType, extensionsOrKeywords, keywordsOrExtensions, includes ) {
 
 	this.isMethod = typeof includesOrType !== "string";
 	this.useKeywords = true;
 
-	THREE.TempNode.call( this, this.isMethod ? null : includesOrType );
+	TempNode.call( this, this.isMethod ? null : includesOrType );
 
 	if ( this.isMethod ) {
 		
@@ -22,26 +25,26 @@ THREE.FunctionNode = function ( src, includesOrType, extensionsOrKeywords, keywo
 
 };
 
-THREE.FunctionNode.rDeclaration = /^([a-z_0-9]+)\s([a-z_0-9]+)\s*\((.*?)\)/i;
-THREE.FunctionNode.rProperties = /[a-z_0-9]+/ig;
+FunctionNode.rDeclaration = /^([a-z_0-9]+)\s([a-z_0-9]+)\s*\((.*?)\)/i;
+FunctionNode.rProperties = /[a-z_0-9]+/ig;
 
-THREE.FunctionNode.prototype = Object.create( THREE.TempNode.prototype );
-THREE.FunctionNode.prototype.constructor = THREE.FunctionNode;
-THREE.FunctionNode.prototype.nodeType = "Function";
+FunctionNode.prototype = Object.create( TempNode.prototype );
+FunctionNode.prototype.constructor = FunctionNode;
+FunctionNode.prototype.nodeType = "Function";
 
-THREE.FunctionNode.prototype.isShared = function ( builder, output ) {
+FunctionNode.prototype.isShared = function ( builder, output ) {
 
 	return ! this.isMethod;
 
 };
 
-THREE.FunctionNode.prototype.getType = function ( builder ) {
+FunctionNode.prototype.getType = function ( builder ) {
 
 	return builder.getTypeByFormat( this.type );
 
 };
 
-THREE.FunctionNode.prototype.getInputByName = function ( name ) {
+FunctionNode.prototype.getInputByName = function ( name ) {
 
 	var i = this.inputs.length;
 
@@ -54,7 +57,7 @@ THREE.FunctionNode.prototype.getInputByName = function ( name ) {
 
 };
 
-THREE.FunctionNode.prototype.getIncludeByName = function ( name ) {
+FunctionNode.prototype.getIncludeByName = function ( name ) {
 
 	var i = this.includes.length;
 
@@ -67,7 +70,7 @@ THREE.FunctionNode.prototype.getIncludeByName = function ( name ) {
 
 };
 
-THREE.FunctionNode.prototype.generate = function ( builder, output ) {
+FunctionNode.prototype.generate = function ( builder, output ) {
 
 	var match, offset = 0, src = this.src;
 
@@ -79,26 +82,27 @@ THREE.FunctionNode.prototype.generate = function ( builder, output ) {
 
 	for ( var ext in this.extensions ) {
 
-		builder.material.extensions[ ext ] = true;
+		builder.extensions[ ext ] = true;
 
 	}
 
-	while ( match = THREE.FunctionNode.rProperties.exec( this.src ) ) {
+	while ( match = FunctionNode.rProperties.exec( this.src ) ) {
 
-		var prop = match[ 0 ], isGlobal = this.isMethod ? ! this.getInputByName( prop ) : true;
-		var reference = prop;
+		var prop = match[ 0 ], 
+			isGlobal = this.isMethod ? ! this.getInputByName( prop ) : true,
+			reference = prop;
 
-		if ( this.keywords[ prop ] || ( this.useKeywords && isGlobal && THREE.NodeLib.containsKeyword( prop ) ) ) {
+		if ( this.keywords[ prop ] || ( this.useKeywords && isGlobal && NodeLib.containsKeyword( prop ) ) ) {
 
 			var node = this.keywords[ prop ];
 
 			if ( ! node ) {
 
-				var keyword = THREE.NodeLib.getKeywordData( prop );
+				var keyword = NodeLib.getKeywordData( prop );
 
 				if ( keyword.cache ) node = builder.keywords[ prop ];
 
-				node = node || THREE.NodeLib.getKeyword( prop, builder );
+				node = node || NodeLib.getKeyword( prop, builder );
 
 				if ( keyword.cache ) builder.keywords[ prop ] = node;
 
@@ -116,9 +120,9 @@ THREE.FunctionNode.prototype.generate = function ( builder, output ) {
 
 		}
 
-		if ( this.getIncludeByName( reference ) === undefined && THREE.NodeLib.contains( reference ) ) {
+		if ( this.getIncludeByName( reference ) === undefined && NodeLib.contains( reference ) ) {
 
-			builder.include( THREE.NodeLib.get( reference ) );
+			builder.include( NodeLib.get( reference ) );
 
 		}
 
@@ -142,7 +146,7 @@ THREE.FunctionNode.prototype.generate = function ( builder, output ) {
 
 };
 
-THREE.FunctionNode.prototype.eval = function ( src, includes, extensions, keywords ) {
+FunctionNode.prototype.eval = function ( src, includes, extensions, keywords ) {
 
 	this.src = src || '';
 
@@ -152,7 +156,7 @@ THREE.FunctionNode.prototype.eval = function ( src, includes, extensions, keywor
 
 	if ( this.isMethod ) {
 
-		var match = this.src.match( THREE.FunctionNode.rDeclaration );
+		var match = this.src.match( FunctionNode.rDeclaration );
 
 		this.inputs = [];
 
@@ -161,7 +165,7 @@ THREE.FunctionNode.prototype.eval = function ( src, includes, extensions, keywor
 			this.type = match[ 1 ];
 			this.name = match[ 2 ];
 
-			var inputs = match[ 3 ].match( THREE.FunctionNode.rProperties );
+			var inputs = match[ 3 ].match( FunctionNode.rProperties );
 
 			if ( inputs ) {
 
@@ -206,9 +210,9 @@ THREE.FunctionNode.prototype.eval = function ( src, includes, extensions, keywor
 
 };
 
-THREE.FunctionNode.prototype.copy = function ( source ) {
+FunctionNode.prototype.copy = function ( source ) {
 			
-	THREE.GLNode.prototype.copy.call( this, source );
+	TempNode.prototype.copy.call( this, source );
 	
 	this.isMethod = source.isMethod;
 	this.useKeywords = source.useKeywords;
@@ -219,7 +223,7 @@ THREE.FunctionNode.prototype.copy = function ( source ) {
 	
 };
 
-THREE.FunctionNode.prototype.toJSON = function ( meta ) {
+FunctionNode.prototype.toJSON = function ( meta ) {
 
 	var data = this.getJSONNode( meta );
 
@@ -259,3 +263,5 @@ THREE.FunctionNode.prototype.toJSON = function ( meta ) {
 	return data;
 
 };
+
+export { FunctionNode };

+ 95 - 92
examples/js/nodes/core/GLNode.js

@@ -2,7 +2,7 @@
  * @author sunag / http://www.sunag.com.br/
  */
 
-THREE.GLNode = function ( type ) {
+function GLNode( type ) {
 
 	this.uuid = THREE.Math.generateUUID();
 
@@ -14,146 +14,149 @@ THREE.GLNode = function ( type ) {
 
 };
 
-THREE.GLNode.prototype.isNode = true;
+GLNode.prototype = {
 
-THREE.GLNode.prototype.parse = function ( builder, context ) {
-
-	context = context || {};
-
-	builder.parsing = true;
-
-	var material = builder.material;
-
-	this.build( builder.addCache( context.cache, context.requires ).addSlot( context.slot ), 'v4' );
-
-	material.clearVertexNode();
-	material.clearFragmentNode();
-
-	builder.removeCache().removeSlot();
-
-	builder.parsing = false;
-
-};
-
-THREE.GLNode.prototype.parseAndBuildCode = function ( builder, output, context ) {
-
-	context = context || {};
-
-	this.parse( builder, context );
-
-	return this.buildCode( builder, output, context );
-
-};
-
-THREE.GLNode.prototype.buildCode = function ( builder, output, context ) {
+	constructor: GLNode,
+	
+	isNode: true,
+	
+	parse: function ( builder, settings ) {
 
-	context = context || {};
+		settings = settings || {};
 
-	var material = builder.material;
+		builder.parsing = true;
 
-	var data = { result: this.build( builder.addCache( context.cache, context.requires ).addSlot( context.slot ), output ) };
+		this.build( builder.addCache( settings.cache, settings.requires ).addSlot( settings.slot ), 'v4' );
 
-	if ( builder.isShader( 'vertex' ) ) data.code = material.clearVertexNode();
-	else data.code = material.clearFragmentNode();
+		builder.clearVertexNodeCode()
+		builder.clearFragmentNodeCode();
 
-	builder.removeCache().removeSlot();
+		builder.removeCache().removeSlot();
 
-	return data;
+		builder.parsing = false;
 
-};
+	},
+	
+	parseAndBuildCode: function ( builder, output, settings ) {
 
-THREE.GLNode.prototype.build = function ( builder, output, uuid ) {
+		settings = settings || {};
 
-	output = output || this.getType( builder, output );
+		this.parse( builder, settings );
 
-	var material = builder.material, data = material.getDataNode( uuid || this.uuid );
+		return this.buildCode( builder, output, settings );
+	
+	},
+	
+	buildCode: function ( builder, output, settings ) {
 
-	if ( builder.parsing ) this.appendDepsNode( builder, data, output );
+		settings = settings || {};
 
-	if ( material.nodes.indexOf( this ) === - 1 ) {
+		var data = { result: this.build( builder.addCache( settings.cache, settings.context ).addSlot( settings.slot ), output ) };
 
-		material.nodes.push( this );
+		data.code = builder.clearNodeCode();
 
-	}
+		builder.removeCache().removeSlot();
 
-	if ( this.updateFrame !== undefined && material.updaters.indexOf( this ) === - 1 ) {
+		return data;
+	
+	},
 
-		material.updaters.push( this );
+	build: function ( builder, output, uuid ) {
 
-	}
+		output = output || this.getType( builder, output );
 
-	return this.generate( builder, output, uuid );
+		var data = builder.getNodeData( uuid || this );
 
-};
+		if ( builder.parsing ) this.appendDepsNode( builder, data, output );
 
-THREE.GLNode.prototype.appendDepsNode = function ( builder, data, output ) {
+		if ( builder.nodes.indexOf( this ) === - 1 ) {
 
-	data.deps = ( data.deps || 0 ) + 1;
+			builder.nodes.push( this );
 
-	var outputLen = builder.getFormatLength( output );
+		}
 
-	if ( outputLen > ( data.outputMax || 0 ) || this.getType( builder, output ) ) {
+		if ( this.updateFrame !== undefined && builder.updaters.indexOf( this ) === - 1 ) {
 
-		data.outputMax = outputLen;
-		data.output = output;
+			builder.updaters.push( this );
 
-	}
+		}
 
-};
-
-THREE.GLNode.prototype.getType = function ( builder, output ) {
+		return this.generate( builder, output, uuid );
+	
+	},
+	
+	appendDepsNode: function ( builder, data, output ) {
 
-	return output === 'sampler2D' || output === 'samplerCube' ? output : this.type;
+		data.deps = ( data.deps || 0 ) + 1;
 
-};
+		var outputLen = builder.getFormatLength( output );
 
-THREE.GLNode.prototype.getJSONNode = function ( meta ) {
+		if ( outputLen > ( data.outputMax || 0 ) || this.getType( builder, output ) ) {
 
-	var isRootObject = ( meta === undefined || typeof meta === 'string' );
+			data.outputMax = outputLen;
+			data.output = output;
 
-	if ( ! isRootObject && meta.nodes[ this.uuid ] !== undefined ) {
+		}
+	
+	},
+	
+	getType: function ( builder, output ) {
 
-		return meta.nodes[ this.uuid ];
+		return output === 'sampler2D' || output === 'samplerCube' ? output : this.type;
+	
+	},
+	
+	getJSONNode: function ( meta ) {
 
-	}
+		var isRootObject = ( meta === undefined || typeof meta === 'string' );
 
-};
+		if ( ! isRootObject && meta.nodes[ this.uuid ] !== undefined ) {
 
-THREE.GLNode.prototype.copy = function ( source ) {
+			return meta.nodes[ this.uuid ];
 
-	if ( source.name !== undefined ) this.name = source.name;
+		}
 	
-	if ( source.userData !== undefined ) this.userData = JSON.parse( JSON.stringify( source.userData ) );
-
-};
+	},
+	
+	copy: function ( source ) {
 
-THREE.GLNode.prototype.createJSONNode = function ( meta ) {
+		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' );
+		var isRootObject = ( meta === undefined || typeof meta === 'string' );
 
-	var data = {};
+		var data = {};
 
-	if ( typeof this.nodeType !== "string" ) throw new Error( "Node does not allow serialization." );
+		if ( typeof this.nodeType !== "string" ) throw new Error( "Node does not allow serialization." );
 
-	data.uuid = this.uuid;
-	data.nodeType = this.nodeType;
+		data.uuid = this.uuid;
+		data.nodeType = this.nodeType;
 
-	if ( this.name !== "" ) data.name = this.name;
+		if ( this.name !== "" ) data.name = this.name;
 
-	if ( JSON.stringify( this.userData ) !== '{}' ) data.userData = this.userData;
+		if ( JSON.stringify( this.userData ) !== '{}' ) data.userData = this.userData;
 
-	if ( ! isRootObject ) {
+		if ( ! isRootObject ) {
 
-		meta.nodes[ this.uuid ] = data;
+			meta.nodes[ this.uuid ] = data;
 
-	}
+		}
 
-	return data;
+		return data;
+	
+	},
+	
+	toJSON: function ( meta ) {
 
+		return this.getJSONNode( meta ) || this.createJSONNode( meta );
+	
+	},
+	
 };
 
-THREE.GLNode.prototype.toJSON = function ( meta ) {
-
-	return this.getJSONNode( meta ) || this.createJSONNode( meta );
-
-};
+export { GLNode };

+ 17 - 16
examples/js/nodes/core/InputNode.js

@@ -2,38 +2,39 @@
  * @author sunag / http://www.sunag.com.br/
  */
 
-THREE.InputNode = function ( type, params ) {
+import { TempNode } from './TempNode.js';
+
+function InputNode( type, params ) {
 
 	params = params || {};
 	params.shared = params.shared !== undefined ? params.shared : false;
 
-	THREE.TempNode.call( this, type, params );
+	TempNode.call( this, type, params );
 
 	this.readonly = false;
 
 };
 
-THREE.InputNode.prototype = Object.create( THREE.TempNode.prototype );
-THREE.InputNode.prototype.constructor = THREE.InputNode;
+InputNode.prototype = Object.create( TempNode.prototype );
+InputNode.prototype.constructor = InputNode;
 
-THREE.InputNode.prototype.isReadonly = function ( builder ) {
+InputNode.prototype.isReadonly = function ( builder ) {
 
 	return this.readonly;
 
 };
 
-
-THREE.InputNode.prototype.copy = function ( source ) {
+InputNode.prototype.copy = function ( source ) {
 	
-	THREE.GLNode.prototype.copy.call( this, source );
+	TempNode.prototype.copy.call( this, source );
 	
 	if ( source.readonly !== undefined ) this.readonly = source.readonly;
 	
 };
 
-THREE.InputNode.prototype.createJSONNode = function ( meta ) {
+InputNode.prototype.createJSONNode = function ( meta ) {
 
-	var data = THREE.GLNode.prototype.createJSONNode.call( this, meta );
+	var data = TempNode.prototype.createJSONNode.call( this, meta );
 	
 	if ( this.readonly === true ) data.readonly = this.readonly;
 
@@ -41,14 +42,12 @@ THREE.InputNode.prototype.createJSONNode = function ( meta ) {
 
 };
 
-THREE.InputNode.prototype.generate = function ( builder, output, uuid, type, ns, needsUpdate ) {
-
-	var material = builder.material;
+InputNode.prototype.generate = function ( builder, output, uuid, type, ns, needsUpdate ) {
 
 	uuid = builder.getUuid( uuid || this.getUuid() );
 	type = type || this.getType( builder );
 
-	var data = material.getDataNode( uuid ),
+	var data = builder.getNodeData( uuid ),
 		readonly = this.isReadonly( builder ) && this.generateReadonly !== undefined;
 
 	if ( readonly ) {
@@ -61,7 +60,7 @@ THREE.InputNode.prototype.generate = function ( builder, output, uuid, type, ns,
 
 			if ( ! data.vertex ) {
 
-				data.vertex = material.createVertexUniform( type, this, ns, needsUpdate );
+				data.vertex = builder.createVertexUniform( type, this, ns, needsUpdate );
 
 			}
 
@@ -71,7 +70,7 @@ THREE.InputNode.prototype.generate = function ( builder, output, uuid, type, ns,
 
 			if ( ! data.fragment ) {
 
-				data.fragment = material.createFragmentUniform( type, this, ns, needsUpdate );
+				data.fragment = builder.createFragmentUniform( type, this, ns, needsUpdate );
 
 			}
 
@@ -82,3 +81,5 @@ THREE.InputNode.prototype.generate = function ( builder, output, uuid, type, ns,
 	}
 
 };
+
+export { InputNode };

+ 618 - 48
examples/js/nodes/core/NodeBuilder.js

@@ -2,16 +2,142 @@
  * @author sunag / http://www.sunag.com.br/
  */
 
-THREE.NodeBuilder = function ( material, renderer ) {
-
-	this.material = material;
-	this.renderer = renderer;
+import { NodeUniform } from './NodeUniform.js';
+import { NodeUtils } from './NodeUtils.js';
+import { NodeLib } from './NodeLib.js';
+import { FunctionNode } from './FunctionNode.js';
+import { ConstNode } from './ConstNode.js';
+import { StructNode } from './StructNode.js';
+import { Vector2Node } from '../inputs/Vector2Node.js';
+import { Vector3Node } from '../inputs/Vector3Node.js';
+import { Vector4Node } from '../inputs/Vector4Node.js';
+import { TextureNode } from '../inputs/TextureNode.js';
+import { CubeTextureNode } from '../inputs/CubeTextureNode.js';
+
+ 
+var elements = NodeUtils.elements,
+	constructors = [ 'float', 'vec2', 'vec3', 'vec4' ],
+	formatToType = {
+		float: 'fv1',
+		vec2: 'v2',
+		vec3: 'v3',
+		vec4: 'v4',
+		mat4: 'v4',
+		int: 'iv1'
+	},
+	typeToFormat = {
+		t: 'sampler2D',
+		tc: 'samplerCube',
+		bv1: 'bool',
+		iv1: 'int',
+		fv1: 'float',
+		c: 'vec3',
+		v2: 'vec2',
+		v3: 'vec3',
+		v4: 'vec4',
+		m3: 'mat3',
+		m4: 'mat4'
+	};
+ 
+function NodeBuilder() {
 
 	this.caches = [];
 	this.slots = [];
 
 	this.keywords = {};
+	
+	this.nodeData = {};
+	
+	this.requires = {
+		uv: [],
+		color: [],
+		lights: false,
+		fog: false
+	};
+
+	this.includes = {
+		consts: [],
+		functions: [],
+		structs: []
+	};
+	
+	this.attributes = {};
+	
+	this.prefixCode = [
+		"#ifdef GL_EXT_shader_texture_lod",
+
+		"	#define texCube(a, b) textureCube(a, b)",
+		"	#define texCubeBias(a, b, c) textureCubeLodEXT(a, b, c)",
+
+		"	#define tex2D(a, b) texture2D(a, b)",
+		"	#define tex2DBias(a, b, c) texture2DLodEXT(a, b, c)",
+
+		"#else",
+
+		"	#define texCube(a, b) textureCube(a, b)",
+		"	#define texCubeBias(a, b, c) textureCube(a, b, c)",
 
+		"	#define tex2D(a, b) texture2D(a, b)",
+		"	#define tex2DBias(a, b, c) texture2D(a, b, c)",
+
+		"#endif",
+
+		"#include <packing>"
+
+	].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: [],
+			vertex: [],
+			fragment: []
+		},
+		vars: {
+			varying: [],
+			vertex: [],
+			fragment: []
+		}
+	};
+	
+	// send to material
+	
+	this.defines = {};
+	
+	this.uniforms = {};
+	
+	this.extensions = {};
+	
+	this.nodes = [];
+	
+	this.updaters = [];
+	
+	// --
+	
 	this.parsing = false;
 	this.optimize = true;
 
@@ -19,38 +145,109 @@ THREE.NodeBuilder = function ( material, renderer ) {
 
 };
 
-THREE.NodeBuilder.type = {
-	float: 'fv1',
-	vec2: 'v2',
-	vec3: 'v3',
-	vec4: 'v4',
-	mat4: 'v4',
-	int: 'iv1'
-};
+NodeBuilder.prototype = {
+
+	constructor: NodeBuilder,
+
+	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 ] ) {
 
-THREE.NodeBuilder.constructors = [
-	'float',
-	'vec2',
-	'vec3',
-	'vec4'
-];
+			this.addVaryCode( 'varying vec2 vUv2;' );
+			this.addVertexParsCode( 'attribute vec2 uv2;' );
 
-THREE.NodeBuilder.elements = [
-	'x',
-	'y',
-	'z',
-	'w'
-];
+			this.addVertexFinalCode( 'vUv2 = uv2;' );
 
-THREE.NodeBuilder.prototype = {
+		}
+		
+		if ( this.requires.color[ 0 ] ) {
+
+			this.addVaryCode( 'varying vec4 vColor;' );
+			this.addVertexParsCode( 'attribute vec4 color;' );
+
+			this.addVertexFinalCode( 'vColor = color;' );
+
+		}
+		
+		if ( this.requires.color[ 1 ] ) {
+
+			this.addVaryCode( 'varying vec4 vColor2;' );
+			this.addVertexParsCode( 'attribute vec4 color2;' );
+
+			this.addVertexFinalCode( 'vColor2 = color2;' );
+
+		}
+		
+		if ( this.requires.position ) {
+
+			this.addVaryCode( 'varying vec3 vPosition;' );
+
+			this.addVertexFinalCode( 'vPosition = transformed;' );
+
+		}
+		
+		if ( this.requires.worldPosition ) {
+
+			this.addVaryCode( 'varying vec3 vWPosition;' );
+			
+			this.addVertexFinalCode( 'vWPosition = ( modelMatrix * vec4( transformed, 1.0 ) ).xyz;' );
 
-	constructor: THREE.NodeBuilder,
+		}
+		
+		if ( this.requires.normal ) {
+
+			this.addVaryCode( 'varying vec3 vObjectNormal;' );
+
+			this.addVertexFinalCode( 'vObjectNormal = normal;' );
+
+		}
+		
+		if ( this.requires.worldNormal ) {
+
+			this.addVaryCode( 'varying vec3 vWNormal;' );
 
-	addCache: function ( name, requires ) {
+			this.addVertexFinalCode( 'vWNormal = ( modelMatrix * vec4( objectNormal, 0.0 ) ).xyz;' );
+
+		}
+		
+		return this;
+		
+	},
+	
+	buildShader: function( shader, node ) {
+		
+		this.resultCode[shader] = node.build( this.setShader( shader ), 'v4' );
+		
+	},
+	
+	setMaterial: function( material, renderer ) {
+		
+		//this.material = material;
+		this.renderer = renderer;
+		
+		this.requires.lights = material.lights;
+		this.requires.fog = material.fog;
+		
+		return this;
+		
+	},
+	
+	addCache: function ( name, context ) {
 
 		this.caches.push( {
 			name: name || '',
-			requires: requires || {}
+			context: context || {}
 		} );
 
 		return this.update();
@@ -83,13 +280,121 @@ THREE.NodeBuilder.prototype = {
 
 	},
 
+	
+	addVertexCode: function ( code ) {
+
+		this.addCode( code, 'vertex' );
+
+	},
+
+	addFragmentCode: function ( code ) {
+
+		this.addCode( code, 'fragment' );
+
+	},
+	
+	addCode: function ( code, shader ) {
+
+		this.code[shader || this.shader] += code + '\n';
+
+	},
+	
+	
+	addVertexNodeCode: function ( code ) {
+
+		this.addNodeCode( code, 'vertex' );
+
+	},
+
+	addFragmentNodeCode: function ( code ) {
+
+		this.addNodeCode( code, 'fragment' );
+
+	},
+	
+	addNodeCode: function ( code, shader ) {
+
+		this.nodeCode[shader || this.shader] += code + '\n';
+
+	},
+	
+	clearNodeCode: function ( shader ) {
+
+		shader = shader || this.shader;
+	
+		var code = this.nodeCode[shader];
+		
+		this.nodeCode[shader] = '';
+
+		return code;
+		
+	},
+	
+	clearVertexNodeCode: function (  ) {
+
+		return this.clearNodeCode( 'vertex' );
+
+	},
+	
+	clearFragmentNodeCode: function (  ) {
+
+		return this.clearNodeCode( 'fragment' );
+
+	},
+	
+	addVertexFinalCode: function ( code ) {
+
+		this.addFinalCode( code, 'vertex' );
+
+	},
+
+	addFragmentFinalCode: function ( code ) {
+
+		this.addFinalCode( code, 'fragment' );
+
+	},
+	
+	addFinalCode: function ( code, shader ) {
+
+		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';
+
+	},
+	
+	
+	addVaryCode: function ( code ) {
+
+		this.addVertexParsCode( code );
+		this.addFragmentParsCode( code );
+
+	},
+	
+	
 	isCache: function ( name ) {
 
 		var i = this.caches.length;
 
 		while ( i -- ) {
 
-			if ( this.caches[ i ].name == name ) return true;
+			if ( this.caches[ i ].name === name ) return true;
 
 		}
 
@@ -103,7 +408,7 @@ THREE.NodeBuilder.prototype = {
 
 		while ( i -- ) {
 
-			if ( this.slots[ i ].name == name ) return true;
+			if ( this.slots[ i ].name === name ) return true;
 
 		}
 
@@ -118,25 +423,237 @@ THREE.NodeBuilder.prototype = {
 
 		this.slot = slot ? slot.name : '';
 		this.cache = cache ? cache.name : '';
-		this.requires = cache ? cache.requires : {};
+		this.context = cache ? cache.context : {};
 
 		return this;
 
 	},
 
-	require: function ( name, node ) {
+	define: function ( name, value ) {
 
-		this.requires[ name ] = node;
+		this.defines[ name ] = value === undefined ? 1 : value;
 
-		return this;
+	},
+	
+	isDefined: function ( name ) {
+
+		return this.defines[ name ] !== undefined;
+
+	},
+
+	getVar: function ( uuid, type, ns, shader ) {
+
+		shader = shader || 'varying';
+	
+		var vars = this.getVars(shader),
+			data = vars[ uuid ];
+
+		if ( ! data ) {
+
+			var index = vars.length,
+				name = ns ? ns : 'nVv' + index;
+
+			data = { name: name, type: type };
+
+			vars.push( data );
+			vars[ uuid ] = data;
+
+		}
+
+		return data;
+
+	},
+	
+	getTempVar: function ( uuid, type, ns ) {
+
+		return this.getVar( uuid, type, ns, this.shader );
+
+	},
+	
+	getAttribute: function ( name, type ) {
+
+		if ( ! this.attributes[ name ] ) {
+
+			var varying = this.getVar( name, type );
+
+			this.addVertexParsCode( 'attribute ' + type + ' ' + name + ';' );
+			this.addVertexFinalCode( varying.name + ' = ' + name + ';' );
+
+			this.attributes[ name ] = { varying: varying, name: name, type: type };
+
+		}
+
+		return this.attributes[ name ];
+
+	},
+	
+	getCode: function( shader ) {
+		
+		return [
+			this.prefixCode,
+			this.parsCode[ shader ],
+			this.getVarListCode( this.getVars('varying'), 'varying' ),
+			this.getVarListCode( this.inputs.uniforms[shader], 'uniform' ),
+			this.getIncludesCode( 'consts', shader ),
+			this.getIncludesCode( 'structs', shader ),
+			this.getIncludesCode( 'functions', shader ),
+			'void main() {',
+				this.getVarListCode( this.getVars(shader) ),
+				this.code[ shader ], 
+				this.resultCode[ shader ],
+				this.finalCode[ shader ],
+			'}'
+		].join( "\n" );
+		
+	},
+	
+	getVarListCode: function ( vars, prefix ) {
+
+		prefix = prefix || '';
+	
+		var code = '';
+
+		for ( var i = 0, l = vars.length; i < l; ++ 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';
+
+		}
+
+		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,
+			index = uniforms.list.length;
+
+		var uniform = new NodeUniform( {
+			type: type,
+			name: ns ? ns : 'nVu' + index + '_' + THREE.Math.generateUUID().substr(0, 8),
+			node: node,
+			needsUpdate: needsUpdate
+		} );
+
+		uniforms.list.push( uniform );
+
+		uniforms[shader].push( uniform );
+		uniforms[shader][ uniform.name ] = uniform;
+		
+		this.uniforms[ uniform.name ] = uniform;
+		
+		return uniform;
+
+	},
+	
+	createVertexUniform: 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 ) {
 
-		this.material.include( this, node, parent, source );
+		var includesStruct;
 
-		return this;
+		node = typeof node === 'string' ? NodeLib.get( node ) : node;
+
+		if ( node instanceof FunctionNode ) {
+
+			includesStruct = this.includes.functions;
+
+		} else if ( node instanceof ConstNode ) {
+
+			includesStruct = this.includes.consts;
+			
+		} else if ( node instanceof StructNode ) {
+
+			includesStruct = this.includes.structs;
+
+		}
+		
+		var includes = includesStruct[ this.shader ] = includesStruct[ this.shader ] || [];
+
+		if (node) {
+		
+			var included = includes[ node.name ];
+
+			if ( ! included ) {
+
+				included = includes[ node.name ] = {
+					node: node,
+					deps: []
+				};
+
+				includes.push( included );
+
+				included.src = node.build( this, 'source' );
+
+			}
+
+			if ( node instanceof FunctionNode && parent && includes[ parent.name ] && includes[ parent.name ].deps.indexOf( node ) == - 1 ) {
+
+				includes[ parent.name ].deps.push( node );
+
+				if ( node.includes && node.includes.length ) {
+
+					var i = 0;
+
+					do {
+
+						this.include( node.includes[ i ++ ], parent );
+
+					} while ( i < node.includes.length );
+
+				}
+
+			}
+
+			if ( source ) {
+
+				included.src = source;
+
+			}
+			
+			return node.name;
+			
+		} else {
+			
+			throw new Error("Include not found.");
+			
+		}
 
 	},
 
@@ -146,9 +663,44 @@ THREE.NodeBuilder.prototype = {
 
 	},
 
+	getIncludes: function ( type, shader ) {
+
+		return this.includes[type][shader || this.shader];
+
+	},
+	
+	getIncludesCode: function () {
+
+		function sortByPosition( a, b ) {
+
+			return a.deps.length - b.deps.length;
+
+		}
+
+		return function getIncludesCode( type, shader ) {
+
+			var includes = this.getIncludes( type, shader );
+	
+			if ( ! includes ) return '';
+
+			var code = '', 
+				includes = includes.sort( sortByPosition );
+
+			for ( var i = 0; i < includes.length; i ++ ) {
+
+				if ( includes[ i ].src ) code += includes[ i ].src + '\n';
+
+			}
+
+			return code;
+
+		};
+
+	}(),
+	
 	getConstructorFromLength: function ( len ) {
 
-		return THREE.NodeBuilder.constructors[ len - 1 ];
+		return constructors[ len - 1 ];
 
 	},
 
@@ -172,7 +724,7 @@ THREE.NodeBuilder.prototype = {
 
 	getFormatFromLength: function ( len ) {
 
-		if ( len == 1 ) return 'fv1';
+		if ( len === 1 ) return 'fv1';
 
 		return 'v' + len;
 
@@ -197,34 +749,34 @@ THREE.NodeBuilder.prototype = {
 						case THREE.CubeReflectionMapping:
 						case THREE.CubeRefractionMapping:
 
-							return new THREE.CubeTextureNode( nodeCandidate );
+							return new CubeTextureNode( nodeCandidate );
 
 							break;
 						
 						case THREE.CubeUVReflectionMapping:
 						case THREE.CubeUVRefractionMapping:
 
-							return new THREE.TextureCubeNode( new THREE.TextureNode( nodeCandidate ) );
+							return new TextureCubeNode( new TextureNode( nodeCandidate ) );
 
 							break;
 							
 						default:
 						
-							return new THREE.TextureNode( nodeCandidate );
+							return new TextureNode( nodeCandidate );
 						
 					}
 					
 				} else if (nodeCandidate.isVector2) {
 					
-					return new THREE.Vector2Node( nodeCandidate );
+					return new Vector2Node( nodeCandidate );
 					
 				} else if (nodeCandidate.isVector3) {
 					
-					return new THREE.Vector3Node( nodeCandidate );
+					return new Vector3Node( nodeCandidate );
 					
 				} else if (nodeCandidate.isVector4) {
 					
-					return new THREE.Vector4Node( nodeCandidate );
+					return new Vector4Node( nodeCandidate );
 					
 				}
 				
@@ -273,7 +825,13 @@ THREE.NodeBuilder.prototype = {
 
 	getTypeByFormat: function ( format ) {
 
-		return THREE.NodeBuilder.type[ format ] || format;
+		return formatToType[ format ] || format;
+
+	},
+	
+	getFormatByType: function ( type ) {
+
+		return typeToFormat[ type ] || type;
 
 	},
 
@@ -289,13 +847,13 @@ THREE.NodeBuilder.prototype = {
 
 	getElementByIndex: function ( index ) {
 
-		return THREE.NodeBuilder.elements[ index ];
+		return elements[ index ];
 
 	},
 
 	getIndexByElement: function ( elm ) {
 
-		return THREE.NodeBuilder.elements.indexOf( elm );
+		return elements.indexOf( elm );
 
 	},
 
@@ -312,10 +870,20 @@ THREE.NodeBuilder.prototype = {
 		return this;
 
 	},
+	
+	mergeUniform: function ( uniforms ) {
+
+		for ( var name in uniforms ) {
+
+			this.uniforms[ name ] = uniforms[ name ];
+
+		}
+
+	},
 
 	getTexelDecodingFunctionFromTexture: function( code, texture ) {
 
-		var gammaOverrideLinear = this.getTextureEncodingFromMap( texture, this.requires.gamma && ( this.renderer ? this.renderer.gammaInput : false ) )
+		var gammaOverrideLinear = this.getTextureEncodingFromMap( texture, this.context.gamma && ( this.renderer ? this.renderer.gammaInput : false ) )
 
 		return this.getTexelDecodingFunction( code, gammaOverrideLinear );
 
@@ -418,3 +986,5 @@ THREE.NodeBuilder.prototype = {
 	}
 
 };
+
+export { NodeBuilder };

+ 20 - 12
examples/js/nodes/core/NodeFrame.js

@@ -2,7 +2,7 @@
  * @author sunag / http://www.sunag.com.br/
  */
 
-THREE.NodeFrame = function ( time ) {
+function NodeFrame( time ) {
 
 	this.time = time !== undefined ? time : 0;
 
@@ -10,25 +10,33 @@ THREE.NodeFrame = function ( time ) {
 
 };
 
-THREE.NodeFrame.prototype.update = function ( delta ) {
+NodeFrame.prototype = {
 
-	++this.frameId;
+	constructor: NodeFrame,
 
-	this.time += delta;
-	this.delta = delta;
+	update: function ( delta ) {
 
-	return this;
+		++this.frameId;
 
-};
+		this.time += delta;
+		this.delta = delta;
+
+		return this;
 
-THREE.NodeFrame.prototype.updateNode = function ( node ) {
+	},
+	
+	updateNode: function ( node ) {
 
-	if ( node.frameId === this.frameId ) return this;
+		if ( node.frameId === this.frameId ) return this;
 
-	node.updateFrame( this );
+		node.updateFrame( this );
 
-	node.frameId = this.frameId;
+		node.frameId = this.frameId;
 
-	return this;
+		return this;
 
+	}
+	
 };
+
+export { NodeFrame };

+ 3 - 1
examples/js/nodes/core/NodeLib.js

@@ -2,7 +2,7 @@
  * @author sunag / http://www.sunag.com.br/
  */
 
-THREE.NodeLib = {
+var NodeLib = {
 
 	nodes: {},
 	keywords: {},
@@ -64,3 +64,5 @@ THREE.NodeLib = {
 	}
 
 };
+
+export { NodeLib };

+ 0 - 737
examples/js/nodes/core/NodeMaterial.js

@@ -1,737 +0,0 @@
-/**
- * @author sunag / http://www.sunag.com.br/
- */
-
-THREE.NodeMaterial = function ( vertex, fragment ) {
-
-	THREE.ShaderMaterial.call( this );
-
-	this.defines.UUID = this.uuid;
-
-	this.vertex = vertex || new THREE.RawNode( new THREE.PositionNode( THREE.PositionNode.PROJECTION ) );
-	this.fragment = fragment || new THREE.RawNode( new THREE.ColorNode( 0xFF0000 ) );
-
-	this.updaters = [];
-
-};
-
-THREE.NodeMaterial.types = {
-	t: 'sampler2D',
-	tc: 'samplerCube',
-	bv1: 'bool',
-	iv1: 'int',
-	fv1: 'float',
-	c: 'vec3',
-	v2: 'vec2',
-	v3: 'vec3',
-	v4: 'vec4',
-	m3: 'mat3',
-	m4: 'mat4'
-};
-
-THREE.NodeMaterial.addShortcuts = function () {
-
-	function applyShortcut( proxy, property, subProperty ) {
-
-		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;
-
-				}
-				
-			};
-
-		}
-
-	}
-
-	return function addShortcuts( proto, proxy, list ) {
-
-		var shortcuts = {};
-
-		for ( var i = 0; i < list.length; ++ i ) {
-
-			var data = list[ i ].split( "." ),
-				property = data[0],
-				subProperty = data[1];
-
-			shortcuts[ property ] = applyShortcut( proxy, property, subProperty );
-
-		}
-
-		Object.defineProperties( proto, shortcuts );
-
-	};
-
-}();
-
-THREE.NodeMaterial.prototype = Object.create( THREE.ShaderMaterial.prototype );
-THREE.NodeMaterial.prototype.constructor = THREE.NodeMaterial;
-THREE.NodeMaterial.prototype.type = "NodeMaterial";
-
-THREE.NodeMaterial.prototype.isNodeMaterial = true;
-
-THREE.NodeMaterial.prototype.updateFrame = function ( frame ) {
-
-	for ( var i = 0; i < this.updaters.length; ++ i ) {
-
-		frame.updateNode( this.updaters[ i ] );
-
-	}
-
-};
-
-THREE.NodeMaterial.prototype.onBeforeCompile = function ( shader, renderer ) {
-
-	if ( this.needsUpdate ) {
-
-		this.build( { dispose: false, renderer: renderer } );
-
-		shader.uniforms = this.uniforms;
-		shader.vertexShader = this.vertexShader;
-		shader.fragmentShader = this.fragmentShader;
-
-	}
-
-};
-
-THREE.NodeMaterial.prototype.build = function ( params ) {
-
-	params = params || {};
-	params.dispose = params.dispose !== undefined ? params.dispose : true;
-
-	var vertex, fragment;
-
-	this.nodes = [];
-
-	this.defines = { UUID: this.uuid };
-	this.uniforms = {};
-	this.attributes = {};
-
-	this.extensions = {};
-
-	this.nodeData = {};
-
-	this.vertexUniform = [];
-	this.fragmentUniform = [];
-
-	this.vars = [];
-	this.vertexTemps = [];
-	this.fragmentTemps = [];
-
-	this.uniformList = [];
-
-	this.consts = [];
-	this.functions = [];
-	this.structs = [];
-
-	this.updaters = [];
-
-	this.requires = {
-		uv: [],
-		color: [],
-		lights: this.lights,
-		fog: this.fog
-	};
-
-	this.vertexPars = '';
-	this.fragmentPars = '';
-
-	this.vertexCode = '';
-	this.fragmentCode = '';
-
-	this.vertexNode = '';
-	this.fragmentNode = '';
-
-	this.prefixCode = [
-		"#ifdef GL_EXT_shader_texture_lod",
-
-		"	#define texCube(a, b) textureCube(a, b)",
-		"	#define texCubeBias(a, b, c) textureCubeLodEXT(a, b, c)",
-
-		"	#define tex2D(a, b) texture2D(a, b)",
-		"	#define tex2DBias(a, b, c) texture2DLodEXT(a, b, c)",
-
-		"#else",
-
-		"	#define texCube(a, b) textureCube(a, b)",
-		"	#define texCubeBias(a, b, c) textureCube(a, b, c)",
-
-		"	#define tex2D(a, b) texture2D(a, b)",
-		"	#define tex2DBias(a, b, c) texture2D(a, b, c)",
-
-		"#endif",
-
-		"#include <packing>"
-
-	].join( "\n" );
-
-	var builder = new THREE.NodeBuilder( this, params.renderer );
-
-	vertex = this.vertex.build( builder.setShader( 'vertex' ), 'v4' );
-	fragment = this.fragment.build( builder.setShader( 'fragment' ), 'v4' );
-
-	if ( this.requires.uv[ 0 ] ) {
-
-		this.addVertexPars( 'varying vec2 vUv;' );
-		this.addFragmentPars( 'varying vec2 vUv;' );
-
-		this.addVertexCode( 'vUv = uv;' );
-
-	}
-
-	if ( this.requires.uv[ 1 ] ) {
-
-		this.addVertexPars( 'varying vec2 vUv2; attribute vec2 uv2;' );
-		this.addFragmentPars( 'varying vec2 vUv2;' );
-
-		this.addVertexCode( 'vUv2 = uv2;' );
-
-	}
-
-	if ( this.requires.color[ 0 ] ) {
-
-		this.addVertexPars( 'varying vec4 vColor; attribute vec4 color;' );
-		this.addFragmentPars( 'varying vec4 vColor;' );
-
-		this.addVertexCode( 'vColor = color;' );
-
-	}
-
-	if ( this.requires.color[ 1 ] ) {
-
-		this.addVertexPars( 'varying vec4 vColor2; attribute vec4 color2;' );
-		this.addFragmentPars( 'varying vec4 vColor2;' );
-
-		this.addVertexCode( 'vColor2 = color2;' );
-
-	}
-
-	if ( this.requires.position ) {
-
-		this.addVertexPars( 'varying vec3 vPosition;' );
-		this.addFragmentPars( 'varying vec3 vPosition;' );
-
-		this.addVertexCode( 'vPosition = transformed;' );
-
-	}
-
-	if ( this.requires.worldPosition ) {
-
-		this.addVertexPars( 'varying vec3 vWPosition;' );
-		this.addFragmentPars( 'varying vec3 vWPosition;' );
-
-		this.addVertexCode( 'vWPosition = ( modelMatrix * vec4( transformed, 1.0 ) ).xyz;' );
-
-	}
-
-	if ( this.requires.normal ) {
-
-		this.addVertexPars( 'varying vec3 vObjectNormal;' );
-		this.addFragmentPars( 'varying vec3 vObjectNormal;' );
-
-		this.addVertexCode( 'vObjectNormal = normal;' );
-
-	}
-
-	if ( this.requires.worldNormal ) {
-
-		this.addVertexPars( 'varying vec3 vWNormal;' );
-		this.addFragmentPars( 'varying vec3 vWNormal;' );
-
-		this.addVertexCode( 'vWNormal = ( modelMatrix * vec4( objectNormal, 0.0 ) ).xyz;' );
-
-	}
-
-	this.fog = this.requires.fog;
-	this.lights = this.requires.lights;
-
-	this.transparent = this.requires.transparent || this.blending > THREE.NormalBlending;
-
-	this.vertexShader = [
-		this.prefixCode,
-		this.vertexPars,
-		this.getCodePars( this.vertexUniform, 'uniform' ),
-		this.getIncludes( this.consts[ 'vertex' ] ),
-		this.getIncludes( this.structs[ 'vertex' ] ),
-		this.getIncludes( this.functions[ 'vertex' ] ),
-		'void main() {',
-		this.getCodePars( this.vertexTemps ),
-		vertex,
-		this.vertexCode,
-		'}'
-	].join( "\n" );
-
-	this.fragmentShader = [
-		this.prefixCode,
-		this.fragmentPars,
-		this.getCodePars( this.fragmentUniform, 'uniform' ),
-		this.getIncludes( this.consts[ 'fragment' ] ),
-		this.getIncludes( this.structs[ 'fragment' ] ),
-		this.getIncludes( this.functions[ 'fragment' ] ),
-		'void main() {',
-		this.getCodePars( this.fragmentTemps ),
-		this.fragmentCode,
-		fragment,
-		'}'
-	].join( "\n" );
- 
-	if ( params.dispose ) {
-
-		// force update
-
-		this.dispose();
-
-	}
-
-	return this;
-
-};
-
-THREE.NodeMaterial.prototype.define = function ( name, value ) {
-
-	this.defines[ name ] = value == undefined ? 1 : value;
-
-};
-
-THREE.NodeMaterial.prototype.isDefined = function ( name ) {
-
-	return this.defines[ name ] != undefined;
-
-};
-
-THREE.NodeMaterial.prototype.mergeUniform = function ( uniforms ) {
-
-	for ( var name in uniforms ) {
-
-		this.uniforms[ name ] = uniforms[ name ];
-
-	}
-
-};
-
-THREE.NodeMaterial.prototype.createUniform = function ( type, node, ns, needsUpdate ) {
-
-	var index = this.uniformList.length;
-
-	var uniform = new THREE.NodeUniform( {
-		type: type,
-		name: ns ? ns : 'nVu' + index + '_' + THREE.Math.generateUUID().substr(0, 8),
-		node: node,
-		needsUpdate: needsUpdate
-	} );
-
-	this.uniformList.push( uniform );
-
-	return uniform;
-
-};
-
-THREE.NodeMaterial.prototype.getVertexTemp = function ( uuid, type, ns ) {
-
-	var data = this.vertexTemps[ uuid ];
-
-	if ( ! data ) {
-
-		var index = this.vertexTemps.length,
-			name = ns ? ns : 'nVt' + index;
-
-		data = { name: name, type: type };
-
-		this.vertexTemps.push( data );
-		this.vertexTemps[ uuid ] = data;
-
-	}
-
-	return data;
-
-};
-
-THREE.NodeMaterial.prototype.getFragmentTemp = function ( uuid, type, ns ) {
-
-	var data = this.fragmentTemps[ uuid ];
-
-	if ( ! data ) {
-
-		var index = this.fragmentTemps.length,
-			name = ns ? ns : 'nVt' + index;
-
-		data = { name: name, type: type };
-
-		this.fragmentTemps.push( data );
-		this.fragmentTemps[ uuid ] = data;
-
-	}
-
-	return data;
-
-};
-
-THREE.NodeMaterial.prototype.getVar = function ( uuid, type, ns ) {
-
-	var data = this.vars[ uuid ];
-
-	if ( ! data ) {
-
-		var index = this.vars.length,
-			name = ns ? ns : 'nVv' + index;
-
-		data = { name: name, type: type };
-
-		this.vars.push( data );
-		this.vars[ uuid ] = data;
-
-		this.addVertexPars( 'varying ' + type + ' ' + name + ';' );
-		this.addFragmentPars( 'varying ' + type + ' ' + name + ';' );
-
-	}
-
-	return data;
-
-};
-
-THREE.NodeMaterial.prototype.getAttribute = function ( name, type ) {
-
-	if ( ! this.attributes[ name ] ) {
-
-		var varying = this.getVar( name, type );
-
-		this.addVertexPars( 'attribute ' + type + ' ' + name + ';' );
-		this.addVertexCode( varying.name + ' = ' + name + ';' );
-
-		this.attributes[ name ] = { varying: varying, name: name, type: type };
-
-	}
-
-	return this.attributes[ name ];
-
-};
-
-THREE.NodeMaterial.prototype.getIncludes = function () {
-
-	function sortByPosition( a, b ) {
-
-		return a.deps.length - b.deps.length;
-
-	}
-
-	return function ( incs ) {
-
-		if ( ! incs ) return '';
-
-		var code = '', incs = incs.sort( sortByPosition );
-
-		for ( var i = 0; i < incs.length; i ++ ) {
-
-			if ( incs[ i ].src ) code += incs[ i ].src + '\n';
-
-		}
-
-		return code;
-
-	};
-
-}();
-
-THREE.NodeMaterial.prototype.addVertexPars = function ( code ) {
-
-	this.vertexPars += code + '\n';
-
-};
-
-THREE.NodeMaterial.prototype.addFragmentPars = function ( code ) {
-
-	this.fragmentPars += code + '\n';
-
-};
-
-THREE.NodeMaterial.prototype.addVertexCode = function ( code ) {
-
-	this.vertexCode += code + '\n';
-
-};
-
-THREE.NodeMaterial.prototype.addFragmentCode = function ( code ) {
-
-	this.fragmentCode += code + '\n';
-
-};
-
-THREE.NodeMaterial.prototype.addVertexNode = function ( code ) {
-
-	this.vertexNode += code + '\n';
-
-};
-
-THREE.NodeMaterial.prototype.clearVertexNode = function () {
-
-	var code = this.vertexNode;
-
-	this.vertexNode = '';
-
-	return code;
-
-};
-
-THREE.NodeMaterial.prototype.addFragmentNode = function ( code ) {
-
-	this.fragmentNode += code + '\n';
-
-};
-
-THREE.NodeMaterial.prototype.clearFragmentNode = function () {
-
-	var code = this.fragmentNode;
-
-	this.fragmentNode = '';
-
-	return code;
-
-};
-
-THREE.NodeMaterial.prototype.getCodePars = function ( pars, prefix ) {
-
-	prefix = prefix || '';
-
-	var code = '';
-
-	for ( var i = 0, l = pars.length; i < l; ++ i ) {
-
-		var parsType = pars[ i ].type;
-		var parsName = pars[ i ].name;
-		var parsValue = pars[ i ].value;
-
-		if ( parsType === 't' && parsValue instanceof THREE.CubeTexture ) parsType = 'tc';
-
-		var type = THREE.NodeMaterial.types[ parsType ] || parsType;
-
-		if ( type === undefined ) throw new Error( "Node pars " + parsType + " not found." );
-
-		code += prefix + ' ' + type + ' ' + parsName + ';\n';
-
-	}
-
-	return code;
-
-};
-
-THREE.NodeMaterial.prototype.createVertexUniform = function ( type, node, ns, needsUpdate ) {
-
-	var uniform = this.createUniform( type, node, ns, needsUpdate );
-
-	this.vertexUniform.push( uniform );
-	this.vertexUniform[ uniform.name ] = uniform;
-
-	this.uniforms[ uniform.name ] = uniform;
-
-	return uniform;
-
-};
-
-THREE.NodeMaterial.prototype.createFragmentUniform = function ( type, node, ns, needsUpdate ) {
-
-	var uniform = this.createUniform( type, node, ns, needsUpdate );
-
-	this.fragmentUniform.push( uniform );
-	this.fragmentUniform[ uniform.name ] = uniform;
-
-	this.uniforms[ uniform.name ] = uniform;
-
-	return uniform;
-
-};
-
-THREE.NodeMaterial.prototype.getDataNode = function ( uuid ) {
-
-	return this.nodeData[ uuid ] = this.nodeData[ uuid ] || {};
-
-};
-
-THREE.NodeMaterial.prototype.include = function ( builder, node, parent, source ) {
-
-	var includes;
-
-	node = typeof node === 'string' ? THREE.NodeLib.get( node ) : node;
-
-	if ( node instanceof THREE.FunctionNode ) {
-
-		includes = this.functions[ builder.shader ] = this.functions[ builder.shader ] || [];
-
-	} else if ( node instanceof THREE.ConstNode ) {
-
-		includes = this.consts[ builder.shader ] = this.consts[ builder.shader ] || [];
-
-	} else if ( node instanceof THREE.StructNode ) {
-
-		includes = this.structs[ builder.shader ] = this.structs[ builder.shader ] || [];
-
-	}
-
-	if (node) {
-	
-		var included = includes[ node.name ];
-
-		if ( ! included ) {
-
-			included = includes[ node.name ] = {
-				node: node,
-				deps: []
-			};
-
-			includes.push( included );
-
-			included.src = node.build( builder, 'source' );
-
-		}
-
-		if ( node instanceof THREE.FunctionNode && parent && includes[ parent.name ] && includes[ parent.name ].deps.indexOf( node ) == - 1 ) {
-
-			includes[ parent.name ].deps.push( node );
-
-			if ( node.includes && node.includes.length ) {
-
-				var i = 0;
-
-				do {
-
-					this.include( builder, node.includes[ i ++ ], parent );
-
-				} while ( i < node.includes.length );
-
-			}
-
-		}
-
-		if ( source ) {
-
-			included.src = source;
-
-		}
-		
-	} else {
-		
-		throw new Error("Include not found.");
-		
-	}
-
-};
-
-THREE.NodeMaterial.prototype.copy = function ( source ) {
-	
-	var uuid = this.uuid;
-	
-	for (var name in source) {
-		
-		this[name] = source[name];
-		
-	}
-	
-	this.uuid = uuid;
-	
-	if ( source.userData !== undefined) {
-		
-		this.userData = JSON.parse( JSON.stringify( source.userData ) );
-		
-	}
-	
-};
-
-THREE.NodeMaterial.prototype.toJSON = function ( meta ) {
-
-	var isRootObject = ( meta === undefined || typeof meta === 'string' );
-
-	if ( isRootObject ) {
-
-		meta = {
-			nodes: {}
-		};
-
-	}
-
-	if ( meta && ! meta.materials ) meta.materials = {};
-
-	if ( ! meta.materials[ this.uuid ] ) {
-
-		var data = {};
-
-		data.uuid = this.uuid;
-		data.type = this.type;
-
-		meta.materials[ data.uuid ] = data;
-
-		if ( this.name !== "" ) data.name = this.name;
-
-		if ( this.size !== undefined ) data.size = this.size;
-		if ( this.sizeAttenuation !== undefined ) data.sizeAttenuation = this.sizeAttenuation;
-
-		if ( this.blending !== THREE.NormalBlending ) data.blending = this.blending;
-		if ( this.flatShading === true ) data.flatShading = this.flatShading;
-		if ( this.side !== THREE.FrontSide ) data.side = this.side;
-		if ( this.vertexColors !== THREE.NoColors ) data.vertexColors = this.vertexColors;
-
-		if ( this.depthFunc !== THREE.LessEqualDepth ) data.depthFunc = this.depthFunc;
-		if ( this.depthTest === false ) data.depthTest = this.depthTest;
-		if ( this.depthWrite === false ) data.depthWrite = this.depthWrite;
-
-		if ( this.linewidth !== 1 ) data.linewidth = this.linewidth;
-		if ( this.dashSize !== undefined ) data.dashSize = this.dashSize;
-		if ( this.gapSize !== undefined ) data.gapSize = this.gapSize;
-		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;
-		if ( this.wireframeLinejoin !== 'round' ) data.wireframeLinejoin = this.wireframeLinejoin;
-
-		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;
-
-		if ( this.visible === false ) data.visible = false;
-		if ( JSON.stringify( this.userData ) !== '{}' ) data.userData = this.userData;
-
-		data.fog = this.fog;
-		data.lights = this.lights;
-		
-		data.vertex = this.vertex.toJSON( meta ).uuid;
-		data.fragment = this.fragment.toJSON( meta ).uuid;
-
-	}
-
-	meta.material = this.uuid;
-
-	return meta;
-
-};

+ 9 - 2
examples/js/nodes/core/NodeUniform.js

@@ -2,7 +2,7 @@
  * @author sunag / http://www.sunag.com.br/
  */
 
-THREE.NodeUniform = function ( params ) {
+function NodeUniform( params ) {
 
 	params = params || {};
 
@@ -13,17 +13,24 @@ THREE.NodeUniform = function ( params ) {
 
 };
 
-Object.defineProperties( THREE.NodeUniform.prototype, {
+Object.defineProperties( NodeUniform.prototype, {
+	
 	value: {
+		
 		get: function () {
 
 			return this.node.value;
 
 		},
+		
 		set: function ( val ) {
 
 			this.node.value = val;
 
 		}
+		
 	}
+	
 } );
+
+export { NodeUniform };

+ 75 - 0
examples/js/nodes/core/NodeUtils.js

@@ -0,0 +1,75 @@
+/**
+ * @author sunag / http://www.sunag.com.br/
+ */
+
+var NodeUtils = {
+
+	elements: [ 'x', 'y', 'z', 'w' ],
+
+	addShortcuts: function () {
+
+		function applyShortcut( proxy, property, subProperty ) {
+
+			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;
+
+					}
+					
+				};
+
+			}
+
+		}
+
+		return function addShortcuts( proto, proxy, list ) {
+
+			var shortcuts = {};
+
+			for ( var i = 0; i < list.length; ++ i ) {
+
+				var data = list[ i ].split( "." ),
+					property = data[0],
+					subProperty = data[1];
+
+				shortcuts[ property ] = applyShortcut( proxy, property, subProperty );
+
+			}
+
+			Object.defineProperties( proto, shortcuts );
+
+		};
+
+	}()
+	
+};
+
+export { NodeUtils };

+ 0 - 61
examples/js/nodes/core/RawNode.js

@@ -1,61 +0,0 @@
-/**
- * @author sunag / http://www.sunag.com.br/
- */
-
-THREE.RawNode = function ( value ) {
-
-	THREE.GLNode.call( this, 'v4' );
-
-	this.value = value;
-
-};
-
-THREE.RawNode.prototype = Object.create( THREE.GLNode.prototype );
-THREE.RawNode.prototype.constructor = THREE.RawNode;
-THREE.RawNode.prototype.nodeType = "Raw";
-
-THREE.RawNode.prototype.generate = function ( builder ) {
-
-	var material = builder.material;
-
-	var data = this.value.parseAndBuildCode( builder, this.type );
-
-	var code = data.code + '\n';
-
-	if ( builder.isShader( 'vertex' ) ) {
-
-		code += 'gl_Position = ' + data.result + ';';
-
-	} else {
-
-		code += 'gl_FragColor = ' + data.result + ';';
-
-	}
-
-	return code;
-
-};
-
-THREE.RawNode.prototype.copy = function ( source ) {
-	
-	THREE.GLNode.prototype.copy.call( this, source );
-	
-	this.value = source.value;
-	
-};
-
-THREE.RawNode.prototype.toJSON = function ( meta ) {
-
-	var data = this.getJSONNode( meta );
-
-	if ( ! data ) {
-
-		data = this.createJSONNode( meta );
-
-		data.value = this.value.toJSON( meta ).uuid;
-
-	}
-
-	return data;
-
-};

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

@@ -2,28 +2,31 @@
  * @author sunag / http://www.sunag.com.br/
  */
 
-THREE.StructNode = function ( src ) {
+import { TempNode } from './TempNode.js';
+import { FunctionNode } from './FunctionNode.js';
 
-	THREE.TempNode.call( this);
+function StructNode( src ) {
+
+	TempNode.call( this);
 
 	this.eval( src );
 
 };
 
-THREE.StructNode.rDeclaration = /^struct\s*([a-z_0-9]+)\s*{\s*((.|\n)*?)}/img;
-THREE.StructNode.rProperties = /\s*(\w*?)\s*(\w*?)(\=|\;)/img;
+StructNode.rDeclaration = /^struct\s*([a-z_0-9]+)\s*{\s*((.|\n)*?)}/img;
+StructNode.rProperties = /\s*(\w*?)\s*(\w*?)(\=|\;)/img;
 
-THREE.StructNode.prototype = Object.create( THREE.TempNode.prototype );
-THREE.StructNode.prototype.constructor = THREE.StructNode;
-THREE.StructNode.prototype.nodeType = "Struct";
+StructNode.prototype = Object.create( TempNode.prototype );
+StructNode.prototype.constructor = StructNode;
+StructNode.prototype.nodeType = "Struct";
 
-THREE.StructNode.prototype.getType = function ( builder ) {
+StructNode.prototype.getType = function ( builder ) {
 
 	return builder.getTypeByFormat( this.name );
 
 };
 
-THREE.StructNode.prototype.getInputByName = function ( name ) {
+StructNode.prototype.getInputByName = function ( name ) {
 
 	var i = this.inputs.length;
 
@@ -36,7 +39,7 @@ THREE.StructNode.prototype.getInputByName = function ( name ) {
 
 };
 
-THREE.StructNode.prototype.generate = function ( builder, output ) {
+StructNode.prototype.generate = function ( builder, output ) {
 
 	if ( output === 'source' ) {
 
@@ -50,21 +53,21 @@ THREE.StructNode.prototype.generate = function ( builder, output ) {
 
 };
 
-THREE.StructNode.prototype.eval = function ( src ) {
+StructNode.prototype.eval = function ( src ) {
 
 	this.src = src || '';
 	
 	this.inputs = [];
 	
-	var declaration = THREE.StructNode.rDeclaration.exec( this.src );
+	var declaration = StructNode.rDeclaration.exec( this.src );
 	
 	if (declaration) {
 		
 		var properties = declaration[2], matchType, matchName;
 		
-		while ( matchType = THREE.FunctionNode.rProperties.exec( properties ) ) {
+		while ( matchType = FunctionNode.rProperties.exec( properties ) ) {
 			
-			matchName = THREE.FunctionNode.rProperties.exec( properties )[0];
+			matchName = FunctionNode.rProperties.exec( properties )[0];
 			
 			this.inputs.push( {
 				name: matchName,
@@ -85,7 +88,7 @@ THREE.StructNode.prototype.eval = function ( src ) {
 
 };
 
-THREE.StructNode.prototype.toJSON = function ( meta ) {
+StructNode.prototype.toJSON = function ( meta ) {
 
 	var data = this.getJSONNode( meta );
 
@@ -100,3 +103,5 @@ THREE.StructNode.prototype.toJSON = function ( meta ) {
 	return data;
 
 };
+
+export { StructNode };

+ 28 - 29
examples/js/nodes/core/TempNode.js

@@ -3,9 +3,11 @@
  * @author sunag / http://www.sunag.com.br/
  */
 
-THREE.TempNode = function ( type, params ) {
+import { GLNode } from './GLNode.js';
 
-	THREE.GLNode.call( this, type );
+function TempNode( type, params ) {
+
+	GLNode.call( this, type );
 
 	params = params || {};
 
@@ -14,15 +16,13 @@ THREE.TempNode = function ( type, params ) {
 
 };
 
-THREE.TempNode.prototype = Object.create( THREE.GLNode.prototype );
-THREE.TempNode.prototype.constructor = THREE.TempNode;
+TempNode.prototype = Object.create( GLNode.prototype );
+TempNode.prototype.constructor = TempNode;
 
-THREE.TempNode.prototype.build = function ( builder, output, uuid, ns ) {
+TempNode.prototype.build = function ( builder, output, uuid, ns ) {
 
 	output = output || this.getType( builder );
 
-	var material = builder.material;
-
 	if ( this.isShared( builder, output ) ) {
 
 		var isUnique = this.isUnique( builder, output );
@@ -35,7 +35,7 @@ THREE.TempNode.prototype.build = function ( builder, output, uuid, ns ) {
 
 		uuid = builder.getUuid( uuid || this.getUuid(), ! isUnique );
 
-		var data = material.getDataNode( uuid );
+		var data = builder.getNodeData( uuid );
 
 		if ( builder.parsing ) {
 
@@ -47,24 +47,24 @@ THREE.TempNode.prototype.build = function ( builder, output, uuid, ns ) {
 
 			}
 
-			return THREE.GLNode.prototype.build.call( this, builder, output, uuid );
+			return GLNode.prototype.build.call( this, builder, output, uuid );
 
 		} else if ( isUnique ) {
 
-			data.name = data.name || THREE.GLNode.prototype.build.call( this, builder, output, uuid );
+			data.name = data.name || GLNode.prototype.build.call( this, builder, output, uuid );
 
 			return data.name;
 
 		} else if ( ! builder.optimize || data.deps == 1 ) {
 
-			return THREE.GLNode.prototype.build.call( this, builder, output, uuid );
+			return GLNode.prototype.build.call( this, builder, output, uuid );
 
 		}
 
 		uuid = this.getUuid( false );
 
-		var name = this.getTemp( builder, uuid );
-		var type = data.output || this.getType( builder );
+		var name = this.getTemp( builder, uuid ),
+			type = data.output || this.getType( builder );
 
 		if ( name ) {
 
@@ -72,12 +72,11 @@ THREE.TempNode.prototype.build = function ( builder, output, uuid, ns ) {
 
 		} else {
 
-			name = THREE.TempNode.prototype.generate.call( this, builder, output, uuid, data.output, ns );
+			name = TempNode.prototype.generate.call( this, builder, output, uuid, data.output, ns );
 
 			var code = this.generate( builder, type, uuid );
 
-			if ( builder.isShader( 'vertex' ) ) material.addVertexNode( name + ' = ' + code + ';' );
-			else material.addFragmentNode( name + ' = ' + code + ';' );
+			builder.addNodeCode( name + ' = ' + code + ';' );
 
 			return builder.format( name, type, output );
 
@@ -85,23 +84,23 @@ THREE.TempNode.prototype.build = function ( builder, output, uuid, ns ) {
 
 	}
 
-	return THREE.GLNode.prototype.build.call( this, builder, output, uuid );
+	return GLNode.prototype.build.call( this, builder, output, uuid );
 
 };
 
-THREE.TempNode.prototype.isShared = function ( builder, output ) {
+TempNode.prototype.isShared = function ( builder, output ) {
 
 	return output !== 'sampler2D' && output !== 'samplerCube' && this.shared;
 
 };
 
-THREE.TempNode.prototype.isUnique = function ( builder, output ) {
+TempNode.prototype.isUnique = function ( builder, output ) {
 
 	return this.unique;
 
 };
 
-THREE.TempNode.prototype.getUuid = function ( unique ) {
+TempNode.prototype.getUuid = function ( unique ) {
 
 	var uuid = unique || unique == undefined ? this.constructor.uuid || this.uuid : this.uuid;
 
@@ -111,24 +110,24 @@ THREE.TempNode.prototype.getUuid = function ( unique ) {
 
 };
 
-THREE.TempNode.prototype.getTemp = function ( builder, uuid ) {
+TempNode.prototype.getTemp = function ( builder, uuid ) {
 
 	uuid = uuid || this.uuid;
 
-	var material = builder.material;
-
-	if ( builder.isShader( 'vertex' ) && material.vertexTemps[ uuid ] ) return material.vertexTemps[ uuid ].name;
-	else if ( material.fragmentTemps[ uuid ] ) return material.fragmentTemps[ uuid ].name;
-
+	var tempVar = builder.getVars()[uuid]
+	
+	return tempVar ? tempVar.name : undefined;
+	
 };
 
-THREE.TempNode.prototype.generate = function ( builder, output, uuid, type, ns ) {
+TempNode.prototype.generate = function ( builder, output, uuid, type, ns ) {
 
 	if ( ! this.isShared( builder, output ) ) console.error( "THREE.TempNode is not shared!" );
 
 	uuid = uuid || this.uuid;
 
-	if ( builder.isShader( 'vertex' ) ) return builder.material.getVertexTemp( uuid, type || this.getType( builder ), ns ).name;
-	else return builder.material.getFragmentTemp( uuid, type || this.getType( builder ), ns ).name;
+	return builder.getTempVar( uuid, type || this.getType( builder ), ns ).name;
 
 };
+
+export { TempNode };

+ 16 - 12
examples/js/nodes/core/VarNode.js

@@ -2,31 +2,33 @@
  * @author sunag / http://www.sunag.com.br/
  */
 
-THREE.VarNode = function ( type, value ) {
+import { GLNode } from './GLNode.js';
 
-	THREE.GLNode.call( this, type );
+function VarNode( type, value ) {
+
+	GLNode.call( this, type );
 	
 	this.value = value;
 
 };
 
-THREE.VarNode.prototype = Object.create( THREE.GLNode.prototype );
-THREE.VarNode.prototype.constructor = THREE.VarNode;
-THREE.VarNode.prototype.nodeType = "Var";
+VarNode.prototype = Object.create( GLNode.prototype );
+VarNode.prototype.constructor = VarNode;
+VarNode.prototype.nodeType = "Var";
 
-THREE.VarNode.prototype.getType = function ( builder ) {
+VarNode.prototype.getType = function ( builder ) {
 
 	return builder.getTypeByFormat( this.type );
 
 };
 
-THREE.VarNode.prototype.generate = function ( builder, output ) {
+VarNode.prototype.generate = function ( builder, output ) {
 
-	var varying = builder.material.getVar( this.uuid, this.type );
+	var varying = builder.getVar( this.uuid, this.type );
 
 	if ( this.value && builder.isShader( 'vertex' ) ) {
 
-		builder.material.addVertexNode( varying.name + ' = ' + this.value.build( builder, this.getType( builder ) ) + ';' );
+		builder.addNodeCode( varying.name + ' = ' + this.value.build( builder, this.getType( builder ) ) + ';' );
 
 	}
 	
@@ -34,16 +36,16 @@ THREE.VarNode.prototype.generate = function ( builder, output ) {
 
 };
 
-THREE.VarNode.prototype.copy = function ( source ) {
+VarNode.prototype.copy = function ( source ) {
 	
-	THREE.GLNode.prototype.copy.call( this, source );
+	GLNode.prototype.copy.call( this, source );
 	
 	this.type = source.type;
 	this.value = source.value;
 	
 };
 
-THREE.VarNode.prototype.toJSON = function ( meta ) {
+VarNode.prototype.toJSON = function ( meta ) {
 
 	var data = this.getJSONNode( meta );
 
@@ -60,3 +62,5 @@ THREE.VarNode.prototype.toJSON = function ( meta ) {
 	return data;
 
 };
+
+export { VarNode };

+ 168 - 0
examples/js/nodes/effects/BlurNode.js

@@ -0,0 +1,168 @@
+/**
+ * @author sunag / http://www.sunag.com.br/
+ */
+
+import { TempNode } from '../core/TempNode.js';
+import { FunctionNode } from '../core/FunctionNode.js';
+import { FloatNode } from '../inputs/FloatNode.js';
+import { Vector2Node } from '../inputs/Vector2Node.js';
+import { UVNode } from '../accessors/UVNode.js';
+
+function BlurNode( value, coord, radius, size ) {
+
+	TempNode.call( this, 'v4' );
+
+	this.value = value;
+	this.coord = coord || new UVNode();
+	this.radius = new Vector2Node( 1, 1 );
+
+	this.size = size;
+
+	this.blurX = true;
+	this.blurY = true;
+
+	this.horizontal = new FloatNode( 1 / 64 );
+	this.vertical = new FloatNode( 1 / 64 );
+
+};
+
+BlurNode.Nodes = (function() {
+	
+	var blurX = new FunctionNode( [
+		"vec4 blurX( sampler2D texture, vec2 uv, float s ) {",
+		"	vec4 sum = vec4( 0.0 );",
+		"	sum += texture2D( texture, vec2( uv.x - 4.0 * s, uv.y ) ) * 0.051;",
+		"	sum += texture2D( texture, vec2( uv.x - 3.0 * s, uv.y ) ) * 0.0918;",
+		"	sum += texture2D( texture, vec2( uv.x - 2.0 * s, uv.y ) ) * 0.12245;",
+		"	sum += texture2D( texture, vec2( uv.x - 1.0 * s, uv.y ) ) * 0.1531;",
+		"	sum += texture2D( texture, vec2( uv.x, uv.y ) ) * 0.1633;",
+		"	sum += texture2D( texture, vec2( uv.x + 1.0 * s, uv.y ) ) * 0.1531;",
+		"	sum += texture2D( texture, vec2( uv.x + 2.0 * s, uv.y ) ) * 0.12245;",
+		"	sum += texture2D( texture, vec2( uv.x + 3.0 * s, uv.y ) ) * 0.0918;",
+		"	sum += texture2D( texture, vec2( uv.x + 4.0 * s, uv.y ) ) * 0.051;",
+		"	return sum;",
+		"}"
+	].join( "\n" ) );
+	
+	var blurY = new FunctionNode( [
+		"vec4 blurY( sampler2D texture, vec2 uv, float s ) {",
+		"	vec4 sum = vec4( 0.0 );",
+		"	sum += texture2D( texture, vec2( uv.x, uv.y - 4.0 * s ) ) * 0.051;",
+		"	sum += texture2D( texture, vec2( uv.x, uv.y - 3.0 * s ) ) * 0.0918;",
+		"	sum += texture2D( texture, vec2( uv.x, uv.y - 2.0 * s ) ) * 0.12245;",
+		"	sum += texture2D( texture, vec2( uv.x, uv.y - 1.0 * s ) ) * 0.1531;",
+		"	sum += texture2D( texture, vec2( uv.x, uv.y ) ) * 0.1633;",
+		"	sum += texture2D( texture, vec2( uv.x, uv.y + 1.0 * s ) ) * 0.1531;",
+		"	sum += texture2D( texture, vec2( uv.x, uv.y + 2.0 * s ) ) * 0.12245;",
+		"	sum += texture2D( texture, vec2( uv.x, uv.y + 3.0 * s ) ) * 0.0918;",
+		"	sum += texture2D( texture, vec2( uv.x, uv.y + 4.0 * s ) ) * 0.051;",
+		"	return sum;",
+		"}"
+	].join( "\n" ) );
+	
+	return {
+		blurX: blurX,
+		blurY: blurY
+	};
+	
+})();
+
+
+BlurNode.prototype = Object.create( TempNode.prototype );
+BlurNode.prototype.constructor = BlurNode;
+BlurNode.prototype.nodeType = "Blur";
+
+BlurNode.prototype.updateFrame = function ( frame ) {
+
+	if ( this.size ) {
+
+		this.horizontal.value = this.radius.x / this.size.x;
+		this.vertical.value = this.radius.y / this.size.y;
+
+	} else if ( this.value.value && this.value.value.image ) {
+
+		var image = this.value.value.image;
+
+		this.horizontal.value = this.radius.x / image.width;
+		this.vertical.value = this.radius.y / image.height;
+
+	}
+
+};
+
+BlurNode.prototype.generate = function ( builder, output ) {
+
+	if ( builder.isShader( 'fragment' ) ) {
+
+		var blurCode = [], code;
+
+		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.coord.build( builder, 'v2' ) + ', ' + this.horizontal.build( builder, 'fv1' ) + ' )' );
+
+		}
+
+		if ( this.blurY ) {
+
+			blurCode.push( blurY + '( ' + this.value.build( builder, 'sampler2D' ) + ', ' + this.coord.build( builder, 'v2' ) + ', ' + this.vertical.build( builder, 'fv1' ) + ' )' );
+
+		}
+
+		if ( blurCode.length == 2 ) code = '( ' + blurCode.join( ' + ' ) + '/ 2.0 )';
+		else if ( blurCode.length ) code = '( ' + blurCode[ 0 ] + ' )';
+		else code = 'vec4( 0.0 )';
+
+		return builder.format( code, this.getType( builder ), output );
+
+	} else {
+
+		console.warn( "THREE.BlurNode is not compatible with " + builder.shader + " shader." );
+
+		return builder.format( 'vec4( 0.0 )', this.getType( builder ), output );
+
+	}
+
+};
+
+BlurNode.prototype.copy = function ( source ) {
+			
+	TempNode.prototype.copy.call( this, source );
+	
+	this.value = source.value;
+	this.coord = source.coord;
+	this.radius = source.radius;
+
+	if ( source.size !== undefined ) this.size = new THREE.Vector2( source.size.x, source.size.y );
+
+	this.blurX = source.blurX;
+	this.blurY = source.blurY;
+					
+};
+
+BlurNode.prototype.toJSON = function ( meta ) {
+
+	var data = this.getJSONNode( meta );
+
+	if ( ! data ) {
+
+		data = this.createJSONNode( meta );
+
+		data.value = this.value.toJSON( meta ).uuid;
+		data.coord = this.coord.toJSON( meta ).uuid;
+		data.radius = this.radius.toJSON( meta ).uuid;
+
+		if ( this.size ) data.size = { x: this.size.x, y: this.size.y };
+
+		data.blurX = this.blurX;
+		data.blurY = this.blurY;
+
+	}
+
+	return data;
+
+};
+
+export { BlurNode };

+ 136 - 0
examples/js/nodes/effects/ColorAdjustmentNode.js

@@ -0,0 +1,136 @@
+/**
+ * @author sunag / http://www.sunag.com.br/
+ */
+
+import { TempNode } from '../core/TempNode.js';
+import { FunctionNode } from '../core/FunctionNode.js';
+import { LuminanceNode } from './LuminanceNode.js';
+
+function ColorAdjustmentNode( rgb, adjustment, method ) {
+
+	TempNode.call( this, 'v3' );
+
+	this.rgb = rgb;
+	this.adjustment = adjustment;
+
+	this.method = method || ColorAdjustmentNode.SATURATION;
+
+};
+
+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';
+ColorAdjustmentNode.VIBRANCE = 'vibrance';
+ColorAdjustmentNode.BRIGHTNESS = 'brightness';
+ColorAdjustmentNode.CONTRAST = 'contrast';
+
+ColorAdjustmentNode.prototype = Object.create( TempNode.prototype );
+ColorAdjustmentNode.prototype.constructor = ColorAdjustmentNode;
+ColorAdjustmentNode.prototype.nodeType = "ColorAdjustment";
+
+ColorAdjustmentNode.prototype.generate = function ( builder, output ) {
+
+	var rgb = this.rgb.build( builder, 'v3' ),
+		adjustment = this.adjustment.build( builder, 'fv1' );
+
+	switch ( this.method ) {
+
+		case ColorAdjustmentNode.BRIGHTNESS:
+
+			return builder.format( '( ' + rgb + ' + ' + adjustment + ' )', this.getType( builder ), output );
+
+			break;
+
+		case ColorAdjustmentNode.CONTRAST:
+
+			return builder.format( '( ' + rgb + ' * ' + adjustment + ' )', this.getType( builder ), output );
+
+			break;
+
+	}
+
+	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;
+
+};
+
+ColorAdjustmentNode.prototype.toJSON = function ( meta ) {
+
+	var data = this.getJSONNode( meta );
+
+	if ( ! data ) {
+
+		data = this.createJSONNode( meta );
+
+		data.rgb = this.rgb.toJSON( meta ).uuid;
+		data.adjustment = this.adjustment.toJSON( meta ).uuid;
+		data.method = this.method;
+
+	}
+
+	return data;
+
+};
+
+export { ColorAdjustmentNode };

+ 73 - 0
examples/js/nodes/effects/LuminanceNode.js

@@ -0,0 +1,73 @@
+/**
+ * @author sunag / http://www.sunag.com.br/
+ */
+
+import { TempNode } from '../core/TempNode.js';
+import { ConstNode } from '../core/ConstNode.js';
+import { FunctionNode } from '../core/FunctionNode.js';
+
+function LuminanceNode( rgb ) {
+
+	TempNode.call( this, 'fv1' );
+
+	this.rgb = rgb;
+
+};
+
+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 ] );
+
+	return {
+		LUMA: LUMA,
+		luminance: luminance
+	};
+	
+})();
+
+LuminanceNode.prototype = Object.create( TempNode.prototype );
+LuminanceNode.prototype.constructor = LuminanceNode;
+LuminanceNode.prototype.nodeType = "Luminance";
+
+LuminanceNode.prototype.generate = function ( builder, output ) {
+
+	var luminance = builder.include( LuminanceNode.Nodes.luminance );
+
+	return builder.format( luminance + '( ' + this.rgb.build( builder, 'v3' ) + ' )', this.getType( builder ), output );
+
+};
+
+LuminanceNode.prototype.copy = function ( source ) {
+			
+	TempNode.prototype.copy.call( this, source );
+	
+	this.rgb = source.rgb;
+	
+};
+
+LuminanceNode.prototype.toJSON = function ( meta ) {
+
+	var data = this.getJSONNode( meta );
+
+	if ( ! data ) {
+
+		data = this.createJSONNode( meta );
+
+		data.rgb = this.rgb.toJSON( meta ).uuid;
+
+	}
+
+	return data;
+
+};
+
+export { LuminanceNode };

+ 15 - 10
examples/js/nodes/inputs/ColorNode.js

@@ -2,35 +2,38 @@
  * @author sunag / http://www.sunag.com.br/
  */
 
-THREE.ColorNode = function ( color, g, b ) {
+import { InputNode } from '../core/InputNode.js';
+import { NodeUtils } from '../core/NodeUtils.js';
 
-	THREE.InputNode.call( this, 'c' );
+function ColorNode( color, g, b ) {
+
+	InputNode.call( this, 'c' );
 
 	this.value = color instanceof THREE.Color ? color : new THREE.Color( color || 0, g, b );
 
 };
 
-THREE.ColorNode.prototype = Object.create( THREE.InputNode.prototype );
-THREE.ColorNode.prototype.constructor = THREE.ColorNode;
-THREE.ColorNode.prototype.nodeType = "Color";
+ColorNode.prototype = Object.create( InputNode.prototype );
+ColorNode.prototype.constructor = ColorNode;
+ColorNode.prototype.nodeType = "Color";
 
-THREE.NodeMaterial.addShortcuts( THREE.ColorNode.prototype, 'value', [ 'r', 'g', 'b' ] );
+NodeUtils.addShortcuts( ColorNode.prototype, 'value', [ 'r', 'g', 'b' ] );
 
-THREE.ColorNode.prototype.generateReadonly = function ( builder, output, uuid, type, ns, needsUpdate ) {
+ColorNode.prototype.generateReadonly = function ( builder, output, uuid, type, ns, needsUpdate ) {
 
 	return builder.format( "vec3( " + this.r + ", " + this.g + ", " + this.b + " )", type, output );
 
 };
 
-THREE.ColorNode.prototype.copy = function ( source ) {
+ColorNode.prototype.copy = function ( source ) {
 			
-	THREE.InputNode.prototype.copy.call( this, source );
+	InputNode.prototype.copy.call( this, source );
 	
 	this.value.copy( source );
 	
 };
 
-THREE.ColorNode.prototype.toJSON = function ( meta ) {
+ColorNode.prototype.toJSON = function ( meta ) {
 
 	var data = this.getJSONNode( meta );
 
@@ -49,3 +52,5 @@ THREE.ColorNode.prototype.toJSON = function ( meta ) {
 	return data;
 
 };
+
+export { ColorNode };

+ 19 - 14
examples/js/nodes/inputs/CubeTextureNode.js

@@ -2,27 +2,30 @@
  * @author sunag / http://www.sunag.com.br/
  */
 
-THREE.CubeTextureNode = function ( value, coord, bias ) {
+import { InputNode } from '../core/InputNode.js';
+import { ReflectNode } from '../accessors/ReflectNode.js';
 
-	THREE.InputNode.call( this, 'v4', { shared: true } );
+function CubeTextureNode( value, coord, bias ) {
+
+	InputNode.call( this, 'v4', { shared: true } );
 
 	this.value = value;
-	this.coord = coord || new THREE.ReflectNode();
+	this.coord = coord || new ReflectNode();
 	this.bias = bias;
 
 };
 
-THREE.CubeTextureNode.prototype = Object.create( THREE.InputNode.prototype );
-THREE.CubeTextureNode.prototype.constructor = THREE.CubeTextureNode;
-THREE.CubeTextureNode.prototype.nodeType = "CubeTexture";
+CubeTextureNode.prototype = Object.create( InputNode.prototype );
+CubeTextureNode.prototype.constructor = CubeTextureNode;
+CubeTextureNode.prototype.nodeType = "CubeTexture";
 
-THREE.CubeTextureNode.prototype.getTexture = function ( builder, output ) {
+CubeTextureNode.prototype.getTexture = function ( builder, output ) {
 
-	return THREE.InputNode.prototype.generate.call( this, builder, output, this.value.uuid, 't' );
+	return InputNode.prototype.generate.call( this, builder, output, this.value.uuid, 'tc' );
 
 };
 
-THREE.CubeTextureNode.prototype.generate = function ( builder, output ) {
+CubeTextureNode.prototype.generate = function ( builder, output ) {
 
 	if ( output === 'samplerCube' ) {
 
@@ -34,9 +37,9 @@ THREE.CubeTextureNode.prototype.generate = function ( builder, output ) {
 	var coord = this.coord.build( builder, 'v3' );
 	var bias = this.bias ? this.bias.build( builder, 'fv1' ) : undefined;
 
-	if ( bias === undefined && builder.requires.bias ) {
+	if ( bias === undefined && builder.context.bias ) {
 
-		bias = new builder.requires.bias( this ).build( builder, 'fv1' );
+		bias = new builder.context.bias( this ).build( builder, 'fv1' );
 
 	}
 
@@ -51,9 +54,9 @@ THREE.CubeTextureNode.prototype.generate = function ( builder, output ) {
 
 };
 
-THREE.CubeTextureNode.prototype.copy = function ( source ) {
+CubeTextureNode.prototype.copy = function ( source ) {
 			
-	THREE.GLNode.prototype.copy.call( this, source );
+	InputNode.prototype.copy.call( this, source );
 	
 	if ( source.value ) this.value = source.value;
 
@@ -63,7 +66,7 @@ THREE.CubeTextureNode.prototype.copy = function ( source ) {
 	
 };
 
-THREE.CubeTextureNode.prototype.toJSON = function ( meta ) {
+CubeTextureNode.prototype.toJSON = function ( meta ) {
 
 	var data = this.getJSONNode( meta );
 
@@ -81,3 +84,5 @@ THREE.CubeTextureNode.prototype.toJSON = function ( meta ) {
 	return data;
 
 };
+
+export { CubeTextureNode };

+ 13 - 9
examples/js/nodes/inputs/FloatNode.js

@@ -2,33 +2,35 @@
  * @author sunag / http://www.sunag.com.br/
  */
 
-THREE.FloatNode = function ( value ) {
+import { InputNode } from '../core/InputNode.js';
 
-	THREE.InputNode.call( this, 'fv1' );
+function FloatNode( value ) {
+
+	InputNode.call( this, 'fv1' );
 
 	this.value = value || 0;
 
 };
 
-THREE.FloatNode.prototype = Object.create( THREE.InputNode.prototype );
-THREE.FloatNode.prototype.constructor = THREE.FloatNode;
-THREE.FloatNode.prototype.nodeType = "Float";
+FloatNode.prototype = Object.create( InputNode.prototype );
+FloatNode.prototype.constructor = FloatNode;
+FloatNode.prototype.nodeType = "Float";
 
-THREE.FloatNode.prototype.generateReadonly = function ( builder, output, uuid, type, ns, needsUpdate ) {
+FloatNode.prototype.generateReadonly = function ( builder, output, uuid, type, ns, needsUpdate ) {
 
 	return builder.format( this.value + ( this.value % 1 ? '' : '.0' ), type, output );
 
 };
 
-THREE.FloatNode.prototype.copy = function ( source ) {
+FloatNode.prototype.copy = function ( source ) {
 			
-	THREE.InputNode.prototype.copy.call( this, source );
+	InputNode.prototype.copy.call( this, source );
 	
 	this.value = source.value;
 	
 };
 
-THREE.FloatNode.prototype.toJSON = function ( meta ) {
+FloatNode.prototype.toJSON = function ( meta ) {
 
 	var data = this.getJSONNode( meta );
 
@@ -45,3 +47,5 @@ THREE.FloatNode.prototype.toJSON = function ( meta ) {
 	return data;
 
 };
+
+export { FloatNode };

+ 13 - 9
examples/js/nodes/inputs/IntNode.js

@@ -2,33 +2,35 @@
  * @author sunag / http://www.sunag.com.br/
  */
 
-THREE.IntNode = function ( value ) {
+import { InputNode } from '../core/InputNode.js';
 
-	THREE.InputNode.call( this, 'iv1' );
+function IntNode( value ) {
+
+	InputNode.call( this, 'iv1' );
 
 	this.value = Math.floor( value || 0 );
 
 };
 
-THREE.IntNode.prototype = Object.create( THREE.InputNode.prototype );
-THREE.IntNode.prototype.constructor = THREE.IntNode;
-THREE.IntNode.prototype.nodeType = "Int";
+IntNode.prototype = Object.create( InputNode.prototype );
+IntNode.prototype.constructor = IntNode;
+IntNode.prototype.nodeType = "Int";
 
-THREE.IntNode.prototype.generateReadonly = function ( builder, output, uuid, type, ns, needsUpdate ) {
+IntNode.prototype.generateReadonly = function ( builder, output, uuid, type, ns, needsUpdate ) {
 
 	return builder.format( this.value, type, output );
 
 };
 
-THREE.IntNode.prototype.copy = function ( source ) {
+IntNode.prototype.copy = function ( source ) {
 			
-	THREE.InputNode.prototype.copy.call( this, source );
+	InputNode.prototype.copy.call( this, source );
 	
 	this.value = source.value;
 	
 };
 
-THREE.IntNode.prototype.toJSON = function ( meta ) {
+IntNode.prototype.toJSON = function ( meta ) {
 
 	var data = this.getJSONNode( meta );
 
@@ -45,3 +47,5 @@ THREE.IntNode.prototype.toJSON = function ( meta ) {
 	return data;
 
 };
+
+export { IntNode };

+ 14 - 10
examples/js/nodes/inputs/Matrix3Node.js

@@ -2,19 +2,21 @@
  * @author sunag / http://www.sunag.com.br/
  */
 
-THREE.Matrix3Node = function ( matrix ) {
+import { InputNode } from '../core/InputNode.js';
 
-	THREE.InputNode.call( this, 'm3' );
+function Matrix3Node( matrix ) {
+
+	InputNode.call( this, 'm3' );
 
 	this.value = matrix || new THREE.Matrix3();
 
 };
 
-THREE.Matrix3Node.prototype = Object.create( THREE.InputNode.prototype );
-THREE.Matrix3Node.prototype.constructor = THREE.Matrix3Node;
-THREE.Matrix3Node.prototype.nodeType = "Matrix3";
+Matrix3Node.prototype = Object.create( InputNode.prototype );
+Matrix3Node.prototype.constructor = Matrix3Node;
+Matrix3Node.prototype.nodeType = "Matrix3";
 
-Object.defineProperties( THREE.Matrix3Node.prototype, {
+Object.defineProperties( Matrix3Node.prototype, {
 
 	elements: {
 		
@@ -34,22 +36,22 @@ Object.defineProperties( THREE.Matrix3Node.prototype, {
 
 } );
 
-THREE.Matrix3Node.prototype.generateReadonly = function ( builder, output, uuid, type, ns, needsUpdate ) {
+Matrix3Node.prototype.generateReadonly = function ( builder, output, uuid, type, ns, needsUpdate ) {
 
 	return builder.format( "mat3( " + this.value.elements.join( ", " ) + " )", type, output );
 
 };
 
 
-THREE.Matrix3Node.prototype.copy = function ( source ) {
+Matrix3Node.prototype.copy = function ( source ) {
 			
-	THREE.InputNode.prototype.copy.call( this, source );
+	InputNode.prototype.copy.call( this, source );
 	
 	this.value.fromArray( source.elements );
 	
 };
 
-THREE.Matrix3Node.prototype.toJSON = function ( meta ) {
+Matrix3Node.prototype.toJSON = function ( meta ) {
 
 	var data = this.getJSONNode( meta );
 
@@ -64,3 +66,5 @@ THREE.Matrix3Node.prototype.toJSON = function ( meta ) {
 	return data;
 
 };
+
+export { Matrix3Node };

+ 14 - 10
examples/js/nodes/inputs/Matrix4Node.js

@@ -2,19 +2,21 @@
  * @author sunag / http://www.sunag.com.br/
  */
 
-THREE.Matrix4Node = function ( matrix ) {
+import { InputNode } from '../core/InputNode.js';
 
-	THREE.InputNode.call( this, 'm4' );
+function Matrix4Node( matrix ) {
+
+	InputNode.call( this, 'm4' );
 
 	this.value = matrix || new THREE.Matrix4();
 
 };
 
-THREE.Matrix4Node.prototype = Object.create( THREE.InputNode.prototype );
-THREE.Matrix4Node.prototype.constructor = THREE.Matrix4Node;
-THREE.Matrix4Node.prototype.nodeType = "Matrix4";
+Matrix4Node.prototype = Object.create( InputNode.prototype );
+Matrix4Node.prototype.constructor = Matrix4Node;
+Matrix4Node.prototype.nodeType = "Matrix4";
 
-Object.defineProperties( THREE.Matrix4Node.prototype, {
+Object.defineProperties( Matrix4Node.prototype, {
 
 	elements: {
 		
@@ -34,21 +36,21 @@ Object.defineProperties( THREE.Matrix4Node.prototype, {
 
 } );
 
-THREE.Matrix4Node.prototype.generateReadonly = function ( builder, output, uuid, type, ns, needsUpdate ) {
+Matrix4Node.prototype.generateReadonly = function ( builder, output, uuid, type, ns, needsUpdate ) {
 
 	return builder.format( "mat4( " + this.value.elements.join( ", " ) + " )", type, output );
 
 };
 
-THREE.Matrix4Node.prototype.copy = function ( source ) {
+Matrix4Node.prototype.copy = function ( source ) {
 			
-	THREE.InputNode.prototype.copy.call( this, source );
+	InputNode.prototype.copy.call( this, source );
 	
 	this.scope.value.fromArray( source.elements );
 	
 };
 
-THREE.Matrix4Node.prototype.toJSON = function ( meta ) {
+Matrix4Node.prototype.toJSON = function ( meta ) {
 
 	var data = this.getJSONNode( meta );
 
@@ -63,3 +65,5 @@ THREE.Matrix4Node.prototype.toJSON = function ( meta ) {
 	return data;
 
 };
+
+export { Matrix4Node };

+ 29 - 19
examples/js/nodes/inputs/ReflectorNode.js

@@ -1,34 +1,42 @@
-THREE.ReflectorNode = function ( mirror ) {
+/**
+ * @author sunag / http://www.sunag.com.br/
+ */
 
-	THREE.TempNode.call( this, 'v4' );
+import { TempNode } from '../core/TempNode.js';
+import { PositionNode } from '../accessors/PositionNode.js';
+import { OperatorNode } from '../math/OperatorNode.js';
+import { TextureNode } from './TextureNode.js';
+import { Matrix4Node } from './Matrix4Node.js';
+
+function ReflectorNode( mirror ) {
+
+	TempNode.call( this, 'v4' );
 
 	if ( mirror ) this.setMirror( mirror );
 
 };
 
-THREE.ReflectorNode.prototype = Object.create( THREE.TempNode.prototype );
-THREE.ReflectorNode.prototype.constructor = THREE.ReflectorNode;
-THREE.ReflectorNode.prototype.nodeType = "Reflector";
+ReflectorNode.prototype = Object.create( TempNode.prototype );
+ReflectorNode.prototype.constructor = ReflectorNode;
+ReflectorNode.prototype.nodeType = "Reflector";
 
-THREE.ReflectorNode.prototype.setMirror = function ( mirror ) {
+ReflectorNode.prototype.setMirror = function ( mirror ) {
 
 	this.mirror = mirror;
 
-	this.textureMatrix = new THREE.Matrix4Node( this.mirror.material.uniforms.textureMatrix.value );
+	this.textureMatrix = new Matrix4Node( this.mirror.material.uniforms.textureMatrix.value );
 
-	this.localPosition = new THREE.PositionNode( THREE.PositionNode.LOCAL );
+	this.localPosition = new PositionNode( PositionNode.LOCAL );
 
-	this.coord = new THREE.OperatorNode( this.textureMatrix, this.localPosition, THREE.OperatorNode.MUL );
-	this.coordResult = new THREE.OperatorNode( null, this.coord, THREE.OperatorNode.ADD );
+	this.coord = new OperatorNode( this.textureMatrix, this.localPosition, OperatorNode.MUL );
+	this.coordResult = new OperatorNode( null, this.coord, OperatorNode.ADD );
 
-	this.texture = new THREE.TextureNode( this.mirror.material.uniforms.tDiffuse.value, this.coord, null, true );
+	this.texture = new TextureNode( this.mirror.material.uniforms.tDiffuse.value, this.coord, null, true );
 
 };
 
-THREE.ReflectorNode.prototype.generate = function ( builder, output ) {
-
-	var material = builder.material;
-
+ReflectorNode.prototype.generate = function ( builder, output ) {
+	
 	if ( builder.isShader( 'fragment' ) ) {
 
 		this.coordResult.a = this.offset;
@@ -46,21 +54,21 @@ THREE.ReflectorNode.prototype.generate = function ( builder, output ) {
 
 		console.warn( "THREE.ReflectorNode is not compatible with " + builder.shader + " shader." );
 
-		return builder.format( 'vec4(0.0)', this.type, output );
+		return builder.format( 'vec4( 0.0 )', this.type, output );
 
 	}
 
 };
 
-THREE.ReflectorNode.prototype.copy = function ( source ) {
+ReflectorNode.prototype.copy = function ( source ) {
 			
-	THREE.InputNode.prototype.copy.call( this, source );
+	InputNode.prototype.copy.call( this, source );
 	
 	this.scope.mirror = source.mirror;
 
 };
 
-THREE.ReflectorNode.prototype.toJSON = function ( meta ) {
+ReflectorNode.prototype.toJSON = function ( meta ) {
 
 	var data = this.getJSONNode( meta );
 
@@ -77,3 +85,5 @@ THREE.ReflectorNode.prototype.toJSON = function ( meta ) {
 	return data;
 
 };
+
+export { ReflectorNode };

+ 13 - 8
examples/js/nodes/inputs/ScreenNode.js

@@ -2,24 +2,29 @@
  * @author sunag / http://www.sunag.com.br/
  */
 
-THREE.ScreenNode = function ( coord ) {
+import { InputNode } from '../core/InputNode.js';
+import { TextureNode } from './TextureNode.js';
 
-	THREE.TextureNode.call( this, undefined, coord );
+function ScreenNode( coord ) {
+
+	TextureNode.call( this, undefined, coord );
 
 };
 
-THREE.ScreenNode.prototype = Object.create( THREE.TextureNode.prototype );
-THREE.ScreenNode.prototype.constructor = THREE.ScreenNode;
-THREE.ScreenNode.prototype.nodeType = "Screen";
+ScreenNode.prototype = Object.create( TextureNode.prototype );
+ScreenNode.prototype.constructor = ScreenNode;
+ScreenNode.prototype.nodeType = "Screen";
 
-THREE.ScreenNode.prototype.isUnique = function () {
+ScreenNode.prototype.isUnique = function () {
 
 	return true;
 
 };
 
-THREE.ScreenNode.prototype.getTexture = function ( builder, output ) {
+ScreenNode.prototype.getTexture = function ( builder, output ) {
 
-	return THREE.InputNode.prototype.generate.call( this, builder, output, this.getUuid(), 't', 'renderTexture' );
+	return InputNode.prototype.generate.call( this, builder, output, this.getUuid(), 't', 'renderTexture' );
 
 };
+
+export { ScreenNode };

+ 20 - 14
examples/js/nodes/inputs/TextureNode.js

@@ -2,28 +2,32 @@
  * @author sunag / http://www.sunag.com.br/
  */
 
-THREE.TextureNode = function ( value, coord, bias, project ) {
+import { InputNode } from '../core/InputNode.js';
+import { NodeBuilder } from '../core/NodeBuilder.js';
+import { UVNode } from '../accessors/UVNode.js';
 
-	THREE.InputNode.call( this, 'v4', { shared: true } );
+function TextureNode( value, coord, bias, project ) {
+
+	InputNode.call( this, 'v4', { shared: true } );
 
 	this.value = value;
-	this.coord = coord || new THREE.UVNode();
+	this.coord = coord || new UVNode();
 	this.bias = bias;
 	this.project = project !== undefined ? project : false;
 
 };
 
-THREE.TextureNode.prototype = Object.create( THREE.InputNode.prototype );
-THREE.TextureNode.prototype.constructor = THREE.TextureNode;
-THREE.TextureNode.prototype.nodeType = "Texture";
+TextureNode.prototype = Object.create( InputNode.prototype );
+TextureNode.prototype.constructor = TextureNode;
+TextureNode.prototype.nodeType = "Texture";
 
-THREE.TextureNode.prototype.getTexture = function ( builder, output ) {
+TextureNode.prototype.getTexture = function ( builder, output ) {
 
-	return THREE.InputNode.prototype.generate.call( this, builder, output, this.value.uuid, 't' );
+	return InputNode.prototype.generate.call( this, builder, output, this.value.uuid, 't' );
 
 };
 
-THREE.TextureNode.prototype.generate = function ( builder, output ) {
+TextureNode.prototype.generate = function ( builder, output ) {
 
 	if ( output === 'sampler2D' ) {
 
@@ -35,9 +39,9 @@ THREE.TextureNode.prototype.generate = function ( builder, output ) {
 	var coord = this.coord.build( builder, this.project ? 'v4' : 'v2' );
 	var bias = this.bias ? this.bias.build( builder, 'fv1' ) : undefined;
 
-	if ( bias == undefined && builder.requires.bias ) {
+	if ( bias == undefined && builder.context.bias ) {
 
-		bias = new builder.requires.bias( this ).build( builder, 'fv1' );
+		bias = new builder.context.bias( this ).build( builder, 'fv1' );
 
 	}
 
@@ -55,9 +59,9 @@ THREE.TextureNode.prototype.generate = function ( builder, output ) {
 
 };
 
-THREE.TextureNode.prototype.copy = function ( source ) {
+TextureNode.prototype.copy = function ( source ) {
 			
-	THREE.GLNode.prototype.copy.call( this, source );
+	InputNode.prototype.copy.call( this, source );
 	
 	if ( source.value ) this.value = source.value;
 
@@ -68,7 +72,7 @@ THREE.TextureNode.prototype.copy = function ( source ) {
 	
 };
 
-THREE.TextureNode.prototype.toJSON = function ( meta ) {
+TextureNode.prototype.toJSON = function ( meta ) {
 
 	var data = this.getJSONNode( meta );
 
@@ -88,3 +92,5 @@ THREE.TextureNode.prototype.toJSON = function ( meta ) {
 	return data;
 
 };
+
+export { TextureNode };

+ 15 - 10
examples/js/nodes/inputs/Vector2Node.js

@@ -2,35 +2,38 @@
  * @author sunag / http://www.sunag.com.br/
  */
 
-THREE.Vector2Node = function ( x, y ) {
+import { InputNode } from '../core/InputNode.js';
+import { NodeUtils } from '../core/NodeUtils.js';
 
-	THREE.InputNode.call( this, 'v2' );
+function Vector2Node( x, y ) {
+
+	InputNode.call( this, 'v2' );
 
 	this.value = x instanceof THREE.Vector2 ? x : new THREE.Vector2( x, y );
 
 };
 
-THREE.Vector2Node.prototype = Object.create( THREE.InputNode.prototype );
-THREE.Vector2Node.prototype.constructor = THREE.Vector2Node;
-THREE.Vector2Node.prototype.nodeType = "Vector2";
+Vector2Node.prototype = Object.create( InputNode.prototype );
+Vector2Node.prototype.constructor = Vector2Node;
+Vector2Node.prototype.nodeType = "Vector2";
 
-THREE.NodeMaterial.addShortcuts( THREE.Vector2Node.prototype, 'value', [ 'x', 'y' ] );
+NodeUtils.addShortcuts( Vector2Node.prototype, 'value', [ 'x', 'y' ] );
 
-THREE.Vector2Node.prototype.generateReadonly = function ( builder, output, uuid, type, ns, needsUpdate ) {
+Vector2Node.prototype.generateReadonly = function ( builder, output, uuid, type, ns, needsUpdate ) {
 
 	return builder.format( "vec2( " + this.x + ", " + this.y + " )", type, output );
 
 };
 
-THREE.Vector2Node.prototype.copy = function ( source ) {
+Vector2Node.prototype.copy = function ( source ) {
 			
-	THREE.InputNode.prototype.copy.call( this, source );
+	InputNode.prototype.copy.call( this, source );
 	
 	this.value.copy( source );
 
 };
 
-THREE.Vector2Node.prototype.toJSON = function ( meta ) {
+Vector2Node.prototype.toJSON = function ( meta ) {
 
 	var data = this.getJSONNode( meta );
 
@@ -48,3 +51,5 @@ THREE.Vector2Node.prototype.toJSON = function ( meta ) {
 	return data;
 
 };
+
+export { Vector2Node };

+ 15 - 10
examples/js/nodes/inputs/Vector3Node.js

@@ -2,35 +2,38 @@
  * @author sunag / http://www.sunag.com.br/
  */
 
-THREE.Vector3Node = function ( x, y, z ) {
+import { InputNode } from '../core/InputNode.js';
+import { NodeUtils } from '../core/NodeUtils.js';
 
-	THREE.InputNode.call( this, 'v3' );
+function Vector3Node( x, y, z ) {
+
+	InputNode.call( this, 'v3' );
 
 	this.value = x instanceof THREE.Vector3 ? x : new THREE.Vector3( x, y, z );
 
 };
 
-THREE.Vector3Node.prototype = Object.create( THREE.InputNode.prototype );
-THREE.Vector3Node.prototype.constructor = THREE.Vector3Node;
-THREE.Vector3Node.prototype.nodeType = "Vector3";
+Vector3Node.prototype = Object.create( InputNode.prototype );
+Vector3Node.prototype.constructor = Vector3Node;
+Vector3Node.prototype.nodeType = "Vector3";
 
-THREE.NodeMaterial.addShortcuts( THREE.Vector3Node.prototype, 'value', [ 'x', 'y', 'z' ] );
+NodeUtils.addShortcuts( Vector3Node.prototype, 'value', [ 'x', 'y', 'z' ] );
 
-THREE.Vector3Node.prototype.generateReadonly = function ( builder, output, uuid, type, ns, needsUpdate ) {
+Vector3Node.prototype.generateReadonly = function ( builder, output, uuid, type, ns, needsUpdate ) {
 
 	return builder.format( "vec3( " + this.x + ", " + this.y + ", " + this.z + " )", type, output );
 
 };
 
-THREE.Vector3Node.prototype.copy = function ( source ) {
+Vector3Node.prototype.copy = function ( source ) {
 			
-	THREE.InputNode.prototype.copy.call( this, source );
+	InputNode.prototype.copy.call( this, source );
 	
 	this.value.copy( source );
 	
 };
 
-THREE.Vector3Node.prototype.toJSON = function ( meta ) {
+Vector3Node.prototype.toJSON = function ( meta ) {
 
 	var data = this.getJSONNode( meta );
 
@@ -49,3 +52,5 @@ THREE.Vector3Node.prototype.toJSON = function ( meta ) {
 	return data;
 
 };
+
+export { Vector3Node };

+ 15 - 10
examples/js/nodes/inputs/Vector4Node.js

@@ -2,35 +2,38 @@
  * @author sunag / http://www.sunag.com.br/
  */
 
-THREE.Vector4Node = function ( x, y, z, w ) {
+import { InputNode } from '../core/InputNode.js';
+import { NodeUtils } from '../core/NodeUtils.js';
 
-	THREE.InputNode.call( this, 'v4' );
+function Vector4Node( x, y, z, w ) {
+
+	InputNode.call( this, 'v4' );
 
 	this.value = x instanceof THREE.Vector4 ? x : new THREE.Vector4( x, y, z, w );
 
 };
 
-THREE.Vector4Node.prototype = Object.create( THREE.InputNode.prototype );
-THREE.Vector4Node.prototype.constructor = THREE.Vector4Node;
-THREE.Vector4Node.prototype.nodeType = "Vector4";
+Vector4Node.prototype = Object.create( InputNode.prototype );
+Vector4Node.prototype.constructor = Vector4Node;
+Vector4Node.prototype.nodeType = "Vector4";
 
-THREE.NodeMaterial.addShortcuts( THREE.Vector4Node.prototype, 'value', [ 'x', 'y', 'z', 'w' ] );
+NodeUtils.addShortcuts( Vector4Node.prototype, 'value', [ 'x', 'y', 'z', 'w' ] );
 
-THREE.Vector4Node.prototype.generateReadonly = function ( builder, output, uuid, type, ns, needsUpdate ) {
+Vector4Node.prototype.generateReadonly = function ( builder, output, uuid, type, ns, needsUpdate ) {
 
 	return builder.format( "vec4( " + this.x + ", " + this.y + ", " + this.z + ", " + this.w + " )", type, output );
 
 };
 
-THREE.Vector4Node.prototype.copy = function ( source ) {
+Vector4Node.prototype.copy = function ( source ) {
 			
-	THREE.InputNode.prototype.copy.call( this, source );
+	InputNode.prototype.copy.call( this, source );
 	
 	this.value.copy( source );
 
 };
 
-THREE.Vector4Node.prototype.toJSON = function ( meta ) {
+Vector4Node.prototype.toJSON = function ( meta ) {
 
 	var data = this.getJSONNode( meta );
 
@@ -50,3 +53,5 @@ THREE.Vector4Node.prototype.toJSON = function ( meta ) {
 	return data;
 
 };
+
+export { Vector4Node };

+ 0 - 156
examples/js/nodes/libs/common.js

@@ -1,156 +0,0 @@
-//
-//	Luma
-//
-
-THREE.NodeLib.add( new THREE.ConstNode( "vec3 LUMA vec3(0.2125, 0.7154, 0.0721)" ) );
-
-//
-//	NormalMap
-//
-
-THREE.NodeLib.add( new THREE.FunctionNode( [
-
-	// Per-Pixel Tangent Space Normal Mapping
-	// http://hacksoflife.blogspot.ch/2009/11/per-pixel-tangent-space-normal-mapping.html
-
-	"vec3 perturbNormal2Arb( vec3 eye_pos, vec3 surf_norm, vec3 map, vec2 mUv, 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 );",
-
-	"}"
-
-].join( "\n" ), null, { derivatives: true } ) );
-
-//
-//	BumpMap
-//
-
-THREE.NodeLib.add( new THREE.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 } ) );
-
-THREE.NodeLib.add( new THREE.FunctionNode( [
-
-	"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 );",
-
-	"}"
-
-].join( "\n" ), null, { derivatives: true } ) );
-
-//
-//	Noise
-//
-
-THREE.NodeLib.add( new THREE.FunctionNode( [
-	"float snoise(vec2 co) {",
-	"	return fract( sin( dot(co.xy, vec2(12.9898,78.233) ) ) * 43758.5453 );",
-	"}"
-].join( "\n" ) ) );
-
-//
-//	Hue
-//
-
-THREE.NodeLib.add( new THREE.FunctionNode( [
-	"vec3 hue_rgb(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" ) ) );
-
-//
-//	Saturation
-//
-
-THREE.NodeLib.add( new THREE.FunctionNode( [
-// Algorithm from Chapter 16 of OpenGL Shading Language
-	"vec3 saturation_rgb(vec3 rgb, float adjustment) {",
-	"	vec3 intensity = vec3(dot(rgb, LUMA));",
-	"	return mix(intensity, rgb, adjustment);",
-	"}"
-].join( "\n" ) ) );
-
-//
-//	Luminance
-//
-
-THREE.NodeLib.add( new THREE.FunctionNode( [
-// Algorithm from Chapter 10 of Graphics Shaders
-	"float luminance_rgb(vec3 rgb) {",
-	"	return dot(rgb, LUMA);",
-	"}"
-].join( "\n" ) ) );
-
-//
-//	Vibrance
-//
-
-THREE.NodeLib.add( new THREE.FunctionNode( [
-// Shader by Evan Wallace adapted by @lo-th
-	"vec3 vibrance_rgb(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" ) ) );

+ 0 - 53
examples/js/nodes/libs/keywords.js

@@ -1,53 +0,0 @@
-THREE.NodeLib.addKeyword( 'uv', function () {
-
-	return new THREE.UVNode();
-
-} );
-
-THREE.NodeLib.addKeyword( 'uv2', function () {
-
-	return new THREE.UVNode( 1 );
-
-} );
-
-THREE.NodeLib.addKeyword( 'position', function () {
-
-	return new THREE.PositionNode();
-
-} );
-
-THREE.NodeLib.addKeyword( 'worldPosition', function () {
-
-	return new THREE.PositionNode( THREE.PositionNode.WORLD );
-
-} );
-
-THREE.NodeLib.addKeyword( 'normal', function () {
-
-	return new THREE.NormalNode();
-
-} );
-
-THREE.NodeLib.addKeyword( 'worldNormal', function () {
-
-	return new THREE.NormalNode( THREE.NormalNode.WORLD );
-
-} );
-
-THREE.NodeLib.addKeyword( 'viewPosition', function () {
-
-	return new THREE.PositionNode( THREE.NormalNode.VIEW );
-
-} );
-
-THREE.NodeLib.addKeyword( 'viewNormal', function () {
-
-	return new THREE.NormalNode( THREE.NormalNode.VIEW );
-
-} );
-
-THREE.NodeLib.addKeyword( 'time', function () {
-
-	return new THREE.TimerNode();
-
-} );

+ 0 - 77
examples/js/nodes/materials/MeshStandardNode.js

@@ -1,77 +0,0 @@
-/**
- * @author sunag / http://www.sunag.com.br/
- */
-
-THREE.MeshStandardNode = function () {
-
-	THREE.StandardNode.call( this );
-
-	this.properties = {
-		color: new THREE.ColorNode( 0xffffff ),
-		roughness: new THREE.FloatNode( 0.5 ),
-		metalness: new THREE.FloatNode( 0.5 ),
-		normalScale: new THREE.Vector2Node( 1, 1 )
-	};
-
-};
-
-THREE.MeshStandardNode.prototype = Object.create( THREE.StandardNode.prototype );
-THREE.MeshStandardNode.prototype.constructor = THREE.MeshStandardNode;
-
-THREE.MeshStandardNode.prototype.build = function ( builder ) {
-
-	var material = builder.material,
-		props = this.properties;
-
-	if ( builder.isShader('fragment') ) {
-		
-		// slots
-		// * color
-		// * map
-		
-		var color = builder.resolve( props.color.value, props.color ),
-			map = builder.resolve( props.map );
-		
-		this.color = map ? new THREE.OperatorNode( color, map, THREE.OperatorNode.MUL ) : color;
-		
-		// slots
-		// * roughness
-		// * roughnessMap
-		
-		var roughness = builder.resolve( props.roughness.value, props.roughness ),
-			roughnessMap = builder.resolve( props.roughnessMap );
-		
-		this.roughness = roughnessMap ? new THREE.OperatorNode( roughness, new THREE.SwitchNode( roughnessMap, "g" ), THREE.OperatorNode.MUL ) : roughness;
-		
-		// slots
-		// * metalness
-		// * metalnessMap
-		
-		var metalness = builder.resolve( props.metalness.value, props.metalness ),
-			metalnessMap = builder.resolve( props.metalnessMap );
-		
-		this.metalness = metalnessMap ? new THREE.OperatorNode( metalness, new THREE.SwitchNode( metalnessMap, "b" ), THREE.OperatorNode.MUL ) : metalness;
-
-		// slots
-		// * normalMap
-		// * normalScale
-		
-		if ( props.normalMap ) {
-			
-			this.normal = new THREE.NormalMapNode( builder.resolve( props.normalMap ) );
-			this.normal.scale = builder.resolve( props.normalScale );
-
-		}
-
-		// slots
-		// * envMap
-		
-		this.environment = builder.resolve( props.envMap );
-		
-	}
-	
-	// build code
-
-	return THREE.StandardNode.prototype.build.call( this, builder );
-
-};

+ 12 - 20
examples/js/nodes/materials/MeshStandardNodeMaterial.js

@@ -2,34 +2,24 @@
  * @author sunag / http://www.sunag.com.br/
  */
 
-THREE.MeshStandardNodeMaterial = function () {
+import { MeshStandardNode } from './nodes/MeshStandardNode.js';
+import { NodeMaterial } from './NodeMaterial.js';
+import { NodeUtils } from '../core/NodeUtils.js';
 
-	var node = new THREE.MeshStandardNode();
+function MeshStandardNodeMaterial() {
 
-	THREE.NodeMaterial.call( this, node, node );
+	var node = new MeshStandardNode();
+
+	NodeMaterial.call( this, node, node );
 
 	this.type = "MeshStandardNodeMaterial";
 
 };
 
-THREE.MeshStandardNodeMaterial.prototype = Object.create( THREE.NodeMaterial.prototype );
-THREE.MeshStandardNodeMaterial.prototype.constructor = THREE.StandardNodeMaterial;
-
-Object.defineProperties( THREE.MeshStandardNodeMaterial.prototype, {
-
-	properties: {
-		
-		get: function () {
-
-			return this.fragment.properties;
+MeshStandardNodeMaterial.prototype = Object.create( NodeMaterial.prototype );
+MeshStandardNodeMaterial.prototype.constructor = MeshStandardNodeMaterial;
 
-		}
-		
-	}
-
-} );
-
-THREE.NodeMaterial.addShortcuts( THREE.MeshStandardNodeMaterial.prototype, 'properties', [
+NodeUtils.addShortcuts( MeshStandardNodeMaterial.prototype, 'properties', [
 	"color.value",
 	"roughness.value",
 	"metalness.value",
@@ -40,3 +30,5 @@ THREE.NodeMaterial.addShortcuts( THREE.MeshStandardNodeMaterial.prototype, 'prop
 	"roughnessMap",
 	"envMap"
 ] );
+
+export { MeshStandardNodeMaterial };

+ 201 - 0
examples/js/nodes/materials/NodeMaterial.js

@@ -0,0 +1,201 @@
+/**
+ * @author sunag / http://www.sunag.com.br/
+ */
+
+import { NodeBuilder } from '../core/NodeBuilder.js';
+import { NodeUniform } from '../core/NodeUniform.js';
+import { NodeLib } from '../core/NodeLib.js';
+import { FunctionNode } from '../core/FunctionNode.js';
+import { ConstNode } from '../core/ConstNode.js';
+import { StructNode } from '../core/StructNode.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 );
+
+	// prevent code share conflict, remove in future
+	
+	this.defines.UUID = this.uuid;
+
+	this.vertex = vertex || new RawNode( new PositionNode( PositionNode.PROJECTION ) );
+	this.fragment = fragment || new RawNode( new ColorNode( 0xFF0000 ) );
+
+	this.updaters = [];
+
+};
+
+NodeMaterial.prototype = Object.create( THREE.ShaderMaterial.prototype );
+NodeMaterial.prototype.constructor = NodeMaterial;
+NodeMaterial.prototype.type = "NodeMaterial";
+
+NodeMaterial.prototype.isNodeMaterial = true;
+
+Object.defineProperties( NodeMaterial.prototype, {
+
+	properties: {
+		
+		get: function () {
+
+			return this.fragment.properties;
+
+		}
+		
+	}
+
+} );
+
+NodeMaterial.prototype.updateFrame = function ( frame ) {
+
+	for ( var i = 0; i < this.updaters.length; ++ i ) {
+
+		frame.updateNode( this.updaters[ i ] );
+
+	}
+
+};
+
+NodeMaterial.prototype.onBeforeCompile = function ( shader, renderer ) {
+
+	if ( this.needsUpdate ) {
+
+		this.build( { dispose: false, renderer: renderer } );
+
+		shader.uniforms = this.uniforms;
+		shader.vertexShader = this.vertexShader;
+		shader.fragmentShader = this.fragmentShader;
+
+	}
+
+};
+
+NodeMaterial.prototype.build = function ( params ) {
+
+	params = params || {};
+	params.dispose = params.dispose !== undefined ? params.dispose : true;
+
+	var builder = new NodeBuilder().setMaterial( this, params.renderer );
+	
+	builder.build( this.vertex, this.fragment );
+	
+	this.vertexShader = builder.getCode('vertex');
+	this.fragmentShader = builder.getCode('fragment');
+	
+	this.defines = builder.defines;
+	this.uniforms = builder.uniforms;
+	this.extensions = builder.extensions;
+	this.nodes = builder.nodes;
+	this.updaters = builder.updaters;
+	
+	this.fog = builder.requires.fog;
+	this.lights = builder.requires.lights;
+
+	this.transparent = builder.requires.transparent || this.blending > THREE.NormalBlending;
+
+	if ( params.dispose ) {
+
+		// force update
+
+		this.dispose();
+
+	}
+
+	return this;
+
+};
+
+NodeMaterial.prototype.copy = function ( source ) {
+	
+	var uuid = this.uuid;
+	
+	for (var name in source) {
+		
+		this[name] = source[name];
+		
+	}
+	
+	this.uuid = uuid;
+	
+	if ( source.userData !== undefined) {
+		
+		this.userData = JSON.parse( JSON.stringify( source.userData ) );
+		
+	}
+	
+};
+
+NodeMaterial.prototype.toJSON = function ( meta ) {
+
+	var isRootObject = ( meta === undefined || typeof meta === 'string' );
+
+	if ( isRootObject ) {
+
+		meta = {
+			nodes: {}
+		};
+
+	}
+
+	if ( meta && ! meta.materials ) meta.materials = {};
+
+	if ( ! meta.materials[ this.uuid ] ) {
+
+		var data = {};
+
+		data.uuid = this.uuid;
+		data.type = this.type;
+
+		meta.materials[ data.uuid ] = data;
+
+		if ( this.name !== "" ) data.name = this.name;
+
+		if ( this.size !== undefined ) data.size = this.size;
+		if ( this.sizeAttenuation !== undefined ) data.sizeAttenuation = this.sizeAttenuation;
+
+		if ( this.blending !== THREE.NormalBlending ) data.blending = this.blending;
+		if ( this.flatShading === true ) data.flatShading = this.flatShading;
+		if ( this.side !== THREE.FrontSide ) data.side = this.side;
+		if ( this.vertexColors !== THREE.NoColors ) data.vertexColors = this.vertexColors;
+
+		if ( this.depthFunc !== THREE.LessEqualDepth ) data.depthFunc = this.depthFunc;
+		if ( this.depthTest === false ) data.depthTest = this.depthTest;
+		if ( this.depthWrite === false ) data.depthWrite = this.depthWrite;
+
+		if ( this.linewidth !== 1 ) data.linewidth = this.linewidth;
+		if ( this.dashSize !== undefined ) data.dashSize = this.dashSize;
+		if ( this.gapSize !== undefined ) data.gapSize = this.gapSize;
+		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;
+		if ( this.wireframeLinejoin !== 'round' ) data.wireframeLinejoin = this.wireframeLinejoin;
+
+		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;
+
+		if ( this.visible === false ) data.visible = false;
+		if ( JSON.stringify( this.userData ) !== '{}' ) data.userData = this.userData;
+
+		data.fog = this.fog;
+		data.lights = this.lights;
+		
+		data.vertex = this.vertex.toJSON( meta ).uuid;
+		data.fragment = this.fragment.toJSON( meta ).uuid;
+
+	}
+
+	meta.material = this.uuid;
+
+	return meta;
+
+};
+
+export { NodeMaterial };

+ 12 - 6
examples/js/nodes/materials/PhongNodeMaterial.js

@@ -2,20 +2,24 @@
  * @author sunag / http://www.sunag.com.br/
  */
 
-THREE.PhongNodeMaterial = function () {
+import { PhongNode } from './nodes/PhongNode.js';
+import { NodeMaterial } from './NodeMaterial.js';
+import { NodeUtils } from '../core/NodeUtils.js';
 
-	var node = new THREE.PhongNode();
+function PhongNodeMaterial() {
 
-	THREE.NodeMaterial.call( this, node, node );
+	var node = new PhongNode();
+
+	NodeMaterial.call( this, node, node );
 
 	this.type = "PhongNodeMaterial";
 
 };
 
-THREE.PhongNodeMaterial.prototype = Object.create( THREE.NodeMaterial.prototype );
-THREE.PhongNodeMaterial.prototype.constructor = THREE.PhongNodeMaterial;
+PhongNodeMaterial.prototype = Object.create( NodeMaterial.prototype );
+PhongNodeMaterial.prototype.constructor = PhongNodeMaterial;
 
-THREE.NodeMaterial.addShortcuts( THREE.PhongNodeMaterial.prototype, 'fragment', [ 
+NodeUtils.addShortcuts( PhongNodeMaterial.prototype, 'fragment', [ 
 	'color', 
 	'alpha', 
 	'specular', 
@@ -30,3 +34,5 @@ THREE.NodeMaterial.addShortcuts( THREE.PhongNodeMaterial.prototype, 'fragment',
 	'environmentAlpha',
 	'transform' 
 ] );
+
+export { PhongNodeMaterial };

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

@@ -2,22 +2,28 @@
  * @author sunag / http://www.sunag.com.br/
  */
 
-THREE.SpriteNodeMaterial = function () {
+import { SpriteNode } from './nodes/SpriteNode.js';
+import { NodeMaterial } from './NodeMaterial.js';
+import { NodeUtils } from '../core/NodeUtils.js';
 
-	var node = new THREE.SpriteNode();
+function SpriteNodeMaterial() {
 
-	THREE.NodeMaterial.call( this, node, node );
+	var node = new SpriteNode();
+
+	NodeMaterial.call( this, node, node );
 
 	this.type = "SpriteNodeMaterial";
 
 };
 
-THREE.SpriteNodeMaterial.prototype = Object.create( THREE.NodeMaterial.prototype );
-THREE.SpriteNodeMaterial.prototype.constructor = THREE.SpriteNodeMaterial;
+SpriteNodeMaterial.prototype = Object.create( NodeMaterial.prototype );
+SpriteNodeMaterial.prototype.constructor = SpriteNodeMaterial;
 
-THREE.NodeMaterial.addShortcuts( THREE.SpriteNodeMaterial.prototype, 'fragment', [ 
+NodeUtils.addShortcuts( SpriteNodeMaterial.prototype, 'fragment', [ 
 	'color', 
 	'alpha', 
 	'transform', 
 	'spherical' 
 ] );
+
+export { SpriteNodeMaterial };

+ 12 - 6
examples/js/nodes/materials/StandardNodeMaterial.js

@@ -2,20 +2,24 @@
  * @author sunag / http://www.sunag.com.br/
  */
 
-THREE.StandardNodeMaterial = function () {
+import { StandardNode } from './nodes/StandardNode.js';
+import { NodeMaterial } from './NodeMaterial.js';
+import { NodeUtils } from '../core/NodeUtils.js';
 
-	this.node = new THREE.StandardNode();
+function StandardNodeMaterial() {
 
-	THREE.NodeMaterial.call( this, this.node, this.node );
+	var node = new StandardNode();
+
+	NodeMaterial.call( this, node, node );
 
 	this.type = "StandardNodeMaterial";
 
 };
 
-THREE.StandardNodeMaterial.prototype = Object.create( THREE.NodeMaterial.prototype );
-THREE.StandardNodeMaterial.prototype.constructor = THREE.StandardNodeMaterial;
+StandardNodeMaterial.prototype = Object.create( NodeMaterial.prototype );
+StandardNodeMaterial.prototype.constructor = StandardNodeMaterial;
 
-THREE.NodeMaterial.addShortcuts( THREE.StandardNodeMaterial.prototype, 'node', [ 
+NodeUtils.addShortcuts( StandardNodeMaterial.prototype, 'fragment', [ 
 	'color', 
 	'alpha', 
 	'roughness', 
@@ -32,3 +36,5 @@ THREE.NodeMaterial.addShortcuts( THREE.StandardNodeMaterial.prototype, 'node', [
 	'environment', 
 	'transform' 
 ] );
+
+export { StandardNodeMaterial };

+ 87 - 0
examples/js/nodes/materials/nodes/MeshStandardNode.js

@@ -0,0 +1,87 @@
+/**
+ * @author sunag / http://www.sunag.com.br/
+ */
+
+import { StandardNode } from './StandardNode.js';
+import { FloatNode } from '../../inputs/FloatNode.js';
+import { ColorNode } from '../../inputs/ColorNode.js';
+import { Vector2Node } from '../../inputs/Vector2Node.js';
+import { OperatorNode } from '../../math/OperatorNode.js';
+import { SwitchNode } from '../../utils/SwitchNode.js';
+import { NormalMapNode } from '../../misc/NormalMapNode.js';
+
+function MeshStandardNode() {
+
+	StandardNode.call( this );
+
+	this.properties = {
+		color: new ColorNode( 0xffffff ),
+		roughness: new FloatNode( 0.5 ),
+		metalness: new FloatNode( 0.5 ),
+		normalScale: new Vector2Node( 1, 1 )
+	};
+
+};
+
+MeshStandardNode.prototype = Object.create( StandardNode.prototype );
+MeshStandardNode.prototype.constructor = MeshStandardNode;
+
+MeshStandardNode.prototype.build = function ( builder ) {
+
+	var material = builder.material,
+		props = this.properties;
+
+	if ( builder.isShader('fragment') ) {
+		
+		// slots
+		// * color
+		// * map
+		
+		var color = builder.resolve( props.color.value, props.color ),
+			map = builder.resolve( props.map );
+		
+		this.color = map ? new OperatorNode( color, map, OperatorNode.MUL ) : color;
+		
+		// slots
+		// * roughness
+		// * roughnessMap
+		
+		var roughness = builder.resolve( props.roughness.value, props.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.resolve( props.metalness.value, props.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.resolve( props.normalScale );
+
+		}
+
+		// slots
+		// * envMap
+		
+		this.environment = builder.resolve( props.envMap );
+		
+	}
+	
+	// build code
+
+	return StandardNode.prototype.build.call( this, builder );
+
+};
+
+export { MeshStandardNode };

+ 27 - 22
examples/js/nodes/materials/PhongNode.js → examples/js/nodes/materials/nodes/PhongNode.js

@@ -2,42 +2,45 @@
  * @author sunag / http://www.sunag.com.br/
  */
 
-THREE.PhongNode = function () {
+import { GLNode } from '../../core/GLNode.js';
+import { ColorNode } from '../../inputs/ColorNode.js';
+import { FloatNode } from '../../inputs/FloatNode.js';
+ 
+function PhongNode() {
 
-	THREE.GLNode.call( this );
+	GLNode.call( this );
 
-	this.color = new THREE.ColorNode( 0xEEEEEE );
-	this.specular = new THREE.ColorNode( 0x111111 );
-	this.shininess = new THREE.FloatNode( 30 );
+	this.color = new ColorNode( 0xEEEEEE );
+	this.specular = new ColorNode( 0x111111 );
+	this.shininess = new FloatNode( 30 );
 
 };
 
-THREE.PhongNode.prototype = Object.create( THREE.GLNode.prototype );
-THREE.PhongNode.prototype.constructor = THREE.PhongNode;
-THREE.PhongNode.prototype.nodeType = "Phong";
+PhongNode.prototype = Object.create( GLNode.prototype );
+PhongNode.prototype.constructor = PhongNode;
+PhongNode.prototype.nodeType = "Phong";
 
-THREE.PhongNode.prototype.build = function ( builder ) {
+PhongNode.prototype.build = function ( builder ) {
 
-	var material = builder.material;
 	var code;
 
-	material.define( 'PHONG' );
-	material.define( 'ALPHATEST', '0.0' );
+	builder.define( 'PHONG' );
+	builder.define( 'ALPHATEST', '0.0' );
 
-	material.requires.lights = true;
+	builder.requires.lights = true;
 
 	if ( builder.isShader( 'vertex' ) ) {
 
 		var transform = this.transform ? this.transform.parseAndBuildCode( builder, 'v3', { cache: 'transform' } ) : undefined;
 
-		material.mergeUniform( THREE.UniformsUtils.merge( [
+		builder.mergeUniform( THREE.UniformsUtils.merge( [
 
 			THREE.UniformsLib[ "fog" ],
 			THREE.UniformsLib[ "lights" ]
 
 		] ) );
 
-		material.addVertexPars( [
+		builder.addParsCode( [
 			"varying vec3 vViewPosition;",
 
 			"#ifndef FLAT_SHADED",
@@ -139,9 +142,9 @@ THREE.PhongNode.prototype.build = function ( builder ) {
 		var environment = this.environment ? this.environment.buildCode( builder, 'c', { slot: 'environment' } ) : undefined;
 		var environmentAlpha = this.environmentAlpha && this.environment ? this.environmentAlpha.buildCode( builder, 'fv1' ) : undefined;
 
-		material.requires.transparent = alpha != undefined;
+		builder.requires.transparent = alpha != undefined;
 
-		material.addFragmentPars( [
+		builder.addParsCode( [
 			"#include <common>",
 			"#include <fog_pars_fragment>",
 			"#include <bsdfs>",
@@ -278,7 +281,7 @@ THREE.PhongNode.prototype.build = function ( builder ) {
 			}
 
 		}
-
+/*
 		switch( builder.material.combine ) {
 
 			case THREE.ENVMAP_BLENDING_MULTIPLY:
@@ -290,7 +293,7 @@ THREE.PhongNode.prototype.build = function ( builder ) {
 			
 			
 		}
-		
+	*/	
 		if ( alpha ) {
 
 			output.push( "gl_FragColor = vec4( outgoingLight, " + alpha.result + " );" );
@@ -316,9 +319,9 @@ THREE.PhongNode.prototype.build = function ( builder ) {
 
 };
 
-THREE.PhongNode.prototype.copy = function ( source ) {
+PhongNode.prototype.copy = function ( source ) {
 			
-	THREE.GLNode.prototype.copy.call( this, source );
+	GLNode.prototype.copy.call( this, source );
 	
 	// vertex
 
@@ -347,7 +350,7 @@ THREE.PhongNode.prototype.copy = function ( source ) {
 
 };
 
-THREE.PhongNode.prototype.toJSON = function ( meta ) {
+PhongNode.prototype.toJSON = function ( meta ) {
 
 	var data = this.getJSONNode( meta );
 
@@ -384,3 +387,5 @@ THREE.PhongNode.prototype.toJSON = function ( meta ) {
 	return data;
 
 };
+
+export { PhongNode };

+ 62 - 0
examples/js/nodes/materials/nodes/RawNode.js

@@ -0,0 +1,62 @@
+/**
+ * @author sunag / http://www.sunag.com.br/
+ */
+
+import { GLNode } from '../../core/GLNode.js';
+
+function RawNode( value ) {
+
+	GLNode.call( this, 'v4' );
+
+	this.value = value;
+
+};
+
+RawNode.prototype = Object.create( GLNode.prototype );
+RawNode.prototype.constructor = RawNode;
+RawNode.prototype.nodeType = "Raw";
+
+RawNode.prototype.generate = function ( builder ) {
+
+	var data = this.value.parseAndBuildCode( builder, this.type ),
+		code = data.code + '\n';
+
+	if ( builder.isShader( 'vertex' ) ) {
+
+		code += 'gl_Position = ' + data.result + ';';
+
+	} else {
+
+		code += 'gl_FragColor = ' + data.result + ';';
+
+	}
+
+	return code;
+
+};
+
+RawNode.prototype.copy = function ( source ) {
+	
+	GLNode.prototype.copy.call( this, source );
+	
+	this.value = source.value;
+	
+};
+
+RawNode.prototype.toJSON = function ( meta ) {
+
+	var data = this.getJSONNode( meta );
+
+	if ( ! data ) {
+
+		data = this.createJSONNode( meta );
+
+		data.value = this.value.toJSON( meta ).uuid;
+
+	}
+
+	return data;
+
+};
+
+export { RawNode };

+ 15 - 10
examples/js/nodes/materials/SpriteNode.js → examples/js/nodes/materials/nodes/SpriteNode.js

@@ -2,20 +2,23 @@
  * @author sunag / http://www.sunag.com.br/
  */
 
-THREE.SpriteNode = function () {
+import { GLNode } from '../../core/GLNode.js';
+import { ColorNode } from '../../inputs/ColorNode.js';
 
-	THREE.GLNode.call( this );
+function SpriteNode() {
 
-	this.color = new THREE.ColorNode( 0xEEEEEE );
+	GLNode.call( this );
+
+	this.color = new ColorNode( 0xEEEEEE );
 	this.spherical = true;
 
 };
 
-THREE.SpriteNode.prototype = Object.create( THREE.GLNode.prototype );
-THREE.SpriteNode.prototype.constructor = THREE.SpriteNode;
-THREE.SpriteNode.prototype.nodeType = "Sprite";
+SpriteNode.prototype = Object.create( GLNode.prototype );
+SpriteNode.prototype.constructor = SpriteNode;
+SpriteNode.prototype.nodeType = "Sprite";
 
-THREE.SpriteNode.prototype.build = function ( builder ) {
+SpriteNode.prototype.build = function ( builder ) {
 
 	var material = builder.material;
 	var output, code;
@@ -139,9 +142,9 @@ THREE.SpriteNode.prototype.build = function ( builder ) {
 
 };
 
-THREE.SpriteNode.prototype.copy = function ( source ) {
+SpriteNode.prototype.copy = function ( source ) {
 			
-	THREE.GLNode.prototype.copy.call( this, source );
+	GLNode.prototype.copy.call( this, source );
 	
 	// vertex
 	
@@ -157,7 +160,7 @@ THREE.SpriteNode.prototype.copy = function ( source ) {
 
 };
 
-THREE.SpriteNode.prototype.toJSON = function ( meta ) {
+SpriteNode.prototype.toJSON = function ( meta ) {
 
 	var data = this.getJSONNode( meta );
 
@@ -182,3 +185,5 @@ THREE.SpriteNode.prototype.toJSON = function ( meta ) {
 	return data;
 
 };
+
+export { SpriteNode };

+ 36 - 33
examples/js/nodes/materials/StandardNode.js → examples/js/nodes/materials/nodes/StandardNode.js

@@ -2,45 +2,48 @@
  * @author sunag / http://www.sunag.com.br/
  */
 
-THREE.StandardNode = function () {
+import { GLNode } from '../../core/GLNode.js';
+import { ColorNode } from '../../inputs/ColorNode.js';
+import { FloatNode } from '../../inputs/FloatNode.js';
+import { RoughnessToBlinnExponentNode } from '../../bsdfs/RoughnessToBlinnExponentNode.js';
+ 
+function StandardNode() {
 
-	THREE.GLNode.call( this );
+	GLNode.call( this );
 
-	this.color = new THREE.ColorNode( 0xEEEEEE );
-	this.roughness = new THREE.FloatNode( 0.5 );
-	this.metalness = new THREE.FloatNode( 0.5 );
+	this.color = new ColorNode( 0xEEEEEE );
+	this.roughness = new FloatNode( 0.5 );
+	this.metalness = new FloatNode( 0.5 );
 
 };
 
-THREE.StandardNode.prototype = Object.create( THREE.GLNode.prototype );
-THREE.StandardNode.prototype.constructor = THREE.StandardNode;
-THREE.StandardNode.prototype.nodeType = "Standard";
+StandardNode.prototype = Object.create( GLNode.prototype );
+StandardNode.prototype.constructor = StandardNode;
+StandardNode.prototype.nodeType = "Standard";
 
-THREE.StandardNode.prototype.build = function ( builder ) {
+StandardNode.prototype.build = function ( builder ) {
 
-	var material = builder.material;
 	var code;
 
-	material.define( this.clearCoat || this.clearCoatRoughness ? 'PHYSICAL' : 'STANDARD' );
+	builder.define( this.clearCoat || this.clearCoatRoughness ? 'PHYSICAL' : 'STANDARD' );
+	builder.define( 'ALPHATEST', '0.0' );
 
-	material.define( 'ALPHATEST', '0.0' );
+	builder.requires.lights = true;
 
-	material.requires.lights = true;
-
-	material.extensions.shaderTextureLOD = true;
+	builder.extensions.shaderTextureLOD = true;
 
 	if ( builder.isShader( 'vertex' ) ) {
 
 		var transform = this.transform ? this.transform.parseAndBuildCode( builder, 'v3', { cache: 'transform' } ) : undefined;
 
-		material.mergeUniform( THREE.UniformsUtils.merge( [
+		builder.mergeUniform( THREE.UniformsUtils.merge( [
 
 			THREE.UniformsLib[ "fog" ],
 			THREE.UniformsLib[ "lights" ]
 
 		] ) );
 
-		material.addVertexPars( [
+		builder.addVertexParsCode( [
 			"varying vec3 vViewPosition;",
 
 			"#ifndef FLAT_SHADED",
@@ -104,22 +107,20 @@ THREE.StandardNode.prototype.build = function ( builder ) {
 
 	} else {
 
-		// blur textures for PBR effect
-
-		var requiresEnvironment = {
-			bias: THREE.RoughnessToBlinnExponentNode,
+		var contextEnvironment = {
+			bias: RoughnessToBlinnExponentNode,
 			gamma: true
 		};
 
-		var requiresGamma = {
+		var contextGammaOnly = {
 			gamma: true
 		};
 
-		var useClearCoat = ! material.isDefined( 'STANDARD' );
+		var useClearCoat = ! builder.isDefined( 'STANDARD' );
 
 		// parse all nodes to reuse generate codes
 
-		this.color.parse( builder, { slot: 'color', requires: requiresGamma } );
+		this.color.parse( builder, { slot: 'color', context: contextGammaOnly } );
 		this.roughness.parse( builder );
 		this.metalness.parse( builder );
 
@@ -140,11 +141,11 @@ THREE.StandardNode.prototype.build = function ( builder ) {
 		if ( this.shadow ) this.shadow.parse( builder );
 		if ( this.emissive ) this.emissive.parse( builder, { slot: 'emissive' } );
 
-		if ( this.environment ) this.environment.parse( builder, { cache: 'env', requires: requiresEnvironment, slot: 'environment' } ); // isolate environment from others inputs ( see TextureNode, CubeTextureNode )
+		if ( this.environment ) this.environment.parse( builder, { cache: 'env', context: contextEnvironment, slot: 'environment' } ); // isolate environment from others inputs ( see TextureNode, CubeTextureNode )
 
 		// build code
 
-		var color = this.color.buildCode( builder, 'c', { slot: 'color', requires: requiresGamma } );
+		var color = this.color.buildCode( builder, 'c', { slot: 'color', context: contextGammaOnly } );
 		var roughness = this.roughness.buildCode( builder, 'fv1' );
 		var metalness = this.metalness.buildCode( builder, 'fv1' );
 
@@ -165,13 +166,13 @@ THREE.StandardNode.prototype.build = function ( builder ) {
 		var shadow = this.shadow ? this.shadow.buildCode( builder, 'c' ) : undefined;
 		var emissive = this.emissive ? this.emissive.buildCode( builder, 'c', { slot: 'emissive' } ) : undefined;
 
-		var environment = this.environment ? this.environment.buildCode( builder, 'c', { cache: 'env', requires: requiresEnvironment, slot: 'environment' } ) : undefined;
+		var environment = this.environment ? this.environment.buildCode( builder, 'c', { cache: 'env', context: contextEnvironment, slot: 'environment' } ) : undefined;
 
-		var clearCoatEnv = useClearCoat && environment ? this.environment.buildCode( builder, 'c', { cache: 'clearCoat', requires: requiresEnvironment, slot: 'environment' } ) : undefined;
+		var clearCoatEnv = useClearCoat && environment ? this.environment.buildCode( builder, 'c', { cache: 'clearCoat', context: contextEnvironment, slot: 'environment' } ) : undefined;
 
-		material.requires.transparent = alpha != undefined;
+		builder.requires.transparent = alpha != undefined;
 
-		material.addFragmentPars( [
+		builder.addFragmentParsCode( [
 
 			"varying vec3 vViewPosition;",
 
@@ -389,9 +390,9 @@ THREE.StandardNode.prototype.build = function ( builder ) {
 
 };
 
-THREE.StandardNode.prototype.copy = function ( source ) {
+StandardNode.prototype.copy = function ( source ) {
 			
-	THREE.GLNode.prototype.copy.call( this, source );
+	GLNode.prototype.copy.call( this, source );
 	
 	// vertex
 
@@ -424,7 +425,7 @@ THREE.StandardNode.prototype.copy = function ( source ) {
 
 };
 
-THREE.StandardNode.prototype.toJSON = function ( meta ) {
+StandardNode.prototype.toJSON = function ( meta ) {
 
 	var data = this.getJSONNode( meta );
 
@@ -466,3 +467,5 @@ THREE.StandardNode.prototype.toJSON = function ( meta ) {
 	return data;
 
 };
+
+export { StandardNode };

+ 53 - 45
examples/js/nodes/math/Math1Node.js

@@ -2,50 +2,53 @@
  * @author sunag / http://www.sunag.com.br/
  */
 
-THREE.Math1Node = function ( a, method ) {
+import { TempNode } from '../core/TempNode.js';
 
-	THREE.TempNode.call( this );
+function Math1Node( a, method ) {
+
+	TempNode.call( this );
 
 	this.a = a;
 
-	this.method = method || THREE.Math1Node.SIN;
+	this.method = method || Math1Node.SIN;
 
 };
 
-THREE.Math1Node.RAD = 'radians';
-THREE.Math1Node.DEG = 'degrees';
-THREE.Math1Node.EXP = 'exp';
-THREE.Math1Node.EXP2 = 'exp2';
-THREE.Math1Node.LOG = 'log';
-THREE.Math1Node.LOG2 = 'log2';
-THREE.Math1Node.SQRT = 'sqrt';
-THREE.Math1Node.INV_SQRT = 'inversesqrt';
-THREE.Math1Node.FLOOR = 'floor';
-THREE.Math1Node.CEIL = 'ceil';
-THREE.Math1Node.NORMALIZE = 'normalize';
-THREE.Math1Node.FRACT = 'fract';
-THREE.Math1Node.SAT = 'saturate';
-THREE.Math1Node.SIN = 'sin';
-THREE.Math1Node.COS = 'cos';
-THREE.Math1Node.TAN = 'tan';
-THREE.Math1Node.ASIN = 'asin';
-THREE.Math1Node.ACOS = 'acos';
-THREE.Math1Node.ARCTAN = 'atan';
-THREE.Math1Node.ABS = 'abs';
-THREE.Math1Node.SIGN = 'sign';
-THREE.Math1Node.LENGTH = 'length';
-THREE.Math1Node.NEGATE = 'negate';
-THREE.Math1Node.INVERT = 'invert';
-
-THREE.Math1Node.prototype = Object.create( THREE.TempNode.prototype );
-THREE.Math1Node.prototype.constructor = THREE.Math1Node;
-THREE.Math1Node.prototype.nodeType = "Math1";
-
-THREE.Math1Node.prototype.getType = function ( builder ) {
+Math1Node.RAD = 'radians';
+Math1Node.DEG = 'degrees';
+Math1Node.EXP = 'exp';
+Math1Node.EXP2 = 'exp2';
+Math1Node.LOG = 'log';
+Math1Node.LOG2 = 'log2';
+Math1Node.SQRT = 'sqrt';
+Math1Node.INV_SQRT = 'inversesqrt';
+Math1Node.FLOOR = 'floor';
+Math1Node.CEIL = 'ceil';
+Math1Node.NORMALIZE = 'normalize';
+Math1Node.FRACT = 'fract';
+Math1Node.SAT = 'saturate';
+Math1Node.SIN = 'sin';
+Math1Node.COS = 'cos';
+Math1Node.TAN = 'tan';
+Math1Node.ASIN = 'asin';
+Math1Node.ACOS = 'acos';
+Math1Node.ARCTAN = 'atan';
+Math1Node.ABS = 'abs';
+Math1Node.SIGN = 'sign';
+Math1Node.LENGTH = 'length';
+Math1Node.NEGATE = 'negate';
+Math1Node.INVERT = 'invert';
+
+Math1Node.prototype = Object.create( TempNode.prototype );
+Math1Node.prototype.constructor = Math1Node;
+Math1Node.prototype.nodeType = "Math1";
+
+Math1Node.prototype.getType = function ( builder ) {
 
 	switch ( this.method ) {
 
-		case THREE.Math1Node.LENGTH:
+		case Math1Node.LENGTH:
+		
 			return 'fv1';
 
 	}
@@ -54,26 +57,29 @@ THREE.Math1Node.prototype.getType = function ( builder ) {
 
 };
 
-THREE.Math1Node.prototype.generate = function ( builder, output ) {
-
-	var material = builder.material;
+Math1Node.prototype.generate = function ( builder, output ) {
 
-	var type = this.getType( builder );
-
-	var result = this.a.build( builder, type );
+	var type = this.getType( builder ),
+		result = this.a.build( builder, type );
 
 	switch ( this.method ) {
 
-		case THREE.Math1Node.NEGATE:
+		case Math1Node.NEGATE:
+		
 			result = '( -' + result + ' )';
+			
 			break;
 
-		case THREE.Math1Node.INVERT:
+		case Math1Node.INVERT:
+		
 			result = '( 1.0 - ' + result + ' )';
+			
 			break;
 
 		default:
+		
 			result = this.method + '( ' + result + ' )';
+			
 			break;
 
 	}
@@ -82,16 +88,16 @@ THREE.Math1Node.prototype.generate = function ( builder, output ) {
 
 };
 
-THREE.Math1Node.prototype.copy = function ( source ) {
+Math1Node.prototype.copy = function ( source ) {
 			
-	THREE.GLNode.prototype.copy.call( this, source );
+	TempNode.prototype.copy.call( this, source );
 	
 	this.a = source.a;
 	this.method = source.method;
 	
 };
 
-THREE.Math1Node.prototype.toJSON = function ( meta ) {
+Math1Node.prototype.toJSON = function ( meta ) {
 
 	var data = this.getJSONNode( meta );
 
@@ -107,3 +113,5 @@ THREE.Math1Node.prototype.toJSON = function ( meta ) {
 	return data;
 
 };
+
+export { Math1Node };

+ 49 - 37
examples/js/nodes/math/Math2Node.js

@@ -1,35 +1,38 @@
 /**
  * @author sunag / http://www.sunag.com.br/
  */
+ 
+import { TempNode } from '../core/TempNode.js';
 
-THREE.Math2Node = function ( a, b, method ) {
+function Math2Node( a, b, method ) {
 
-	THREE.TempNode.call( this );
+	TempNode.call( this );
 
 	this.a = a;
 	this.b = b;
 
-	this.method = method || THREE.Math2Node.DISTANCE;
+	this.method = method || Math2Node.DISTANCE;
 
 };
 
-THREE.Math2Node.MIN = 'min';
-THREE.Math2Node.MAX = 'max';
-THREE.Math2Node.MOD = 'mod';
-THREE.Math2Node.STEP = 'step';
-THREE.Math2Node.REFLECT = 'reflect';
-THREE.Math2Node.DISTANCE = 'distance';
-THREE.Math2Node.DOT = 'dot';
-THREE.Math2Node.CROSS = 'cross';
-THREE.Math2Node.POW = 'pow';
+Math2Node.MIN = 'min';
+Math2Node.MAX = 'max';
+Math2Node.MOD = 'mod';
+Math2Node.STEP = 'step';
+Math2Node.REFLECT = 'reflect';
+Math2Node.DISTANCE = 'distance';
+Math2Node.DOT = 'dot';
+Math2Node.CROSS = 'cross';
+Math2Node.POW = 'pow';
 
-THREE.Math2Node.prototype = Object.create( THREE.TempNode.prototype );
-THREE.Math2Node.prototype.constructor = THREE.Math2Node;
-THREE.Math2Node.prototype.nodeType = "Math2";
+Math2Node.prototype = Object.create( TempNode.prototype );
+Math2Node.prototype.constructor = Math2Node;
+Math2Node.prototype.nodeType = "Math2";
 
-THREE.Math2Node.prototype.getInputType = function ( builder ) {
+Math2Node.prototype.getInputType = function ( builder ) {
 
 	// use the greater length vector
+	
 	if ( builder.getFormatLength( this.b.getType( builder ) ) > builder.getFormatLength( this.a.getType( builder ) ) ) {
 
 		return this.b.getType( builder );
@@ -40,15 +43,17 @@ THREE.Math2Node.prototype.getInputType = function ( builder ) {
 
 };
 
-THREE.Math2Node.prototype.getType = function ( builder ) {
+Math2Node.prototype.getType = function ( builder ) {
 
 	switch ( this.method ) {
 
-		case THREE.Math2Node.DISTANCE:
-		case THREE.Math2Node.DOT:
+		case Math2Node.DISTANCE:
+		case Math2Node.DOT:
+		
 			return 'fv1';
 
-		case THREE.Math2Node.CROSS:
+		case Math2Node.CROSS:
+		
 			return 'v3';
 
 	}
@@ -57,40 +62,45 @@ THREE.Math2Node.prototype.getType = function ( builder ) {
 
 };
 
-THREE.Math2Node.prototype.generate = function ( builder, output ) {
-
-	var material = builder.material;
-
-	var type = this.getInputType( builder );
+Math2Node.prototype.generate = function ( builder, output ) {
 
-	var a, b,
+	var a, b, 
+		type = this.getInputType( builder ),
 		al = builder.getFormatLength( this.a.getType( builder ) ),
 		bl = builder.getFormatLength( this.b.getType( builder ) );
-
+		
 	// optimzer
 
 	switch ( this.method ) {
 
-		case THREE.Math2Node.CROSS:
+		case Math2Node.CROSS:
+		
 			a = this.a.build( builder, 'v3' );
 			b = this.b.build( builder, 'v3' );
+			
 			break;
 
-		case THREE.Math2Node.STEP:
-			a = this.a.build( builder, al == 1 ? 'fv1' : type );
+		case Math2Node.STEP:
+		
+			a = this.a.build( builder, al === 1 ? 'fv1' : type );
 			b = this.b.build( builder, type );
+			
 			break;
 
-		case THREE.Math2Node.MIN:
-		case THREE.Math2Node.MAX:
-		case THREE.Math2Node.MOD:
+		case Math2Node.MIN:
+		case Math2Node.MAX:
+		case Math2Node.MOD:
+		
 			a = this.a.build( builder, type );
-			b = this.b.build( builder, bl == 1 ? 'fv1' : type );
+			b = this.b.build( builder, bl === 1 ? 'fv1' : type );
+			
 			break;
 
 		default:
+		
 			a = this.a.build( builder, type );
 			b = this.b.build( builder, type );
+			
 			break;
 
 	}
@@ -99,9 +109,9 @@ THREE.Math2Node.prototype.generate = function ( builder, output ) {
 
 };
 
-THREE.Math2Node.prototype.copy = function ( source ) {
+Math2Node.prototype.copy = function ( source ) {
 			
-	THREE.GLNode.prototype.copy.call( this, source );
+	TempNode.prototype.copy.call( this, source );
 	
 	this.a = source.a;
 	this.b = source.b;
@@ -109,7 +119,7 @@ THREE.Math2Node.prototype.copy = function ( source ) {
 	
 };
 
-THREE.Math2Node.prototype.toJSON = function ( meta ) {
+Math2Node.prototype.toJSON = function ( meta ) {
 
 	var data = this.getJSONNode( meta );
 
@@ -126,3 +136,5 @@ THREE.Math2Node.prototype.toJSON = function ( meta ) {
 	return data;
 
 };
+
+export { Math2Node };

+ 39 - 25
examples/js/nodes/math/Math3Node.js

@@ -1,72 +1,84 @@
 /**
  * @author sunag / http://www.sunag.com.br/
  */
+ 
+import { TempNode } from '../core/TempNode.js';
 
-THREE.Math3Node = function ( a, b, c, method ) {
+function Math3Node( a, b, c, method ) {
 
-	THREE.TempNode.call( this );
+	TempNode.call( this );
 
 	this.a = a;
 	this.b = b;
 	this.c = c;
 
-	this.method = method || THREE.Math3Node.MIX;
+	this.method = method || Math3Node.MIX;
 
 };
 
-THREE.Math3Node.MIX = 'mix';
-THREE.Math3Node.REFRACT = 'refract';
-THREE.Math3Node.SMOOTHSTEP = 'smoothstep';
-THREE.Math3Node.FACEFORWARD = 'faceforward';
+Math3Node.MIX = 'mix';
+Math3Node.REFRACT = 'refract';
+Math3Node.SMOOTHSTEP = 'smoothstep';
+Math3Node.FACEFORWARD = 'faceforward';
 
-THREE.Math3Node.prototype = Object.create( THREE.TempNode.prototype );
-THREE.Math3Node.prototype.constructor = THREE.Math3Node;
-THREE.Math3Node.prototype.nodeType = "Math3";
+Math3Node.prototype = Object.create( TempNode.prototype );
+Math3Node.prototype.constructor = Math3Node;
+Math3Node.prototype.nodeType = "Math3";
 
-THREE.Math3Node.prototype.getType = function ( builder ) {
+Math3Node.prototype.getType = function ( builder ) {
 
 	var a = builder.getFormatLength( this.a.getType( builder ) );
 	var b = builder.getFormatLength( this.b.getType( builder ) );
 	var c = builder.getFormatLength( this.c.getType( builder ) );
 
-	if ( a > b && a > c ) return this.a.getType( builder );
-	else if ( b > c ) return this.b.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 );
 
 };
 
-THREE.Math3Node.prototype.generate = function ( builder, output ) {
-
-	var material = builder.material;
-
-	var type = this.getType( builder );
+Math3Node.prototype.generate = function ( builder, output ) {
 
 	var a, b, c,
 		al = builder.getFormatLength( this.a.getType( builder ) ),
 		bl = builder.getFormatLength( this.b.getType( builder ) ),
-		cl = builder.getFormatLength( this.c.getType( builder ) );
+		cl = builder.getFormatLength( this.c.getType( builder ) ),
+		type = this.getType( builder );
 
 	// optimzer
 
 	switch ( this.method ) {
 
-		case THREE.Math3Node.REFRACT:
+		case Math3Node.REFRACT:
+		
 			a = this.a.build( builder, type );
 			b = this.b.build( builder, type );
 			c = this.c.build( builder, 'fv1' );
+			
 			break;
 
-		case THREE.Math3Node.MIX:
+		case Math3Node.MIX:
+		
 			a = this.a.build( builder, type );
 			b = this.b.build( builder, type );
-			c = this.c.build( builder, cl == 1 ? 'fv1' : type );
+			c = this.c.build( builder, cl === 1 ? 'fv1' : type );
+			
 			break;
 
 		default:
+		
 			a = this.a.build( builder, type );
 			b = this.b.build( builder, type );
 			c = this.c.build( builder, type );
+			
 			break;
 
 	}
@@ -75,9 +87,9 @@ THREE.Math3Node.prototype.generate = function ( builder, output ) {
 
 };
 
-THREE.Math3Node.prototype.copy = function ( source ) {
+Math3Node.prototype.copy = function ( source ) {
 			
-	THREE.GLNode.prototype.copy.call( this, source );
+	TempNode.prototype.copy.call( this, source );
 	
 	this.a = source.a;
 	this.b = source.b;
@@ -86,7 +98,7 @@ THREE.Math3Node.prototype.copy = function ( source ) {
 	
 };
 
-THREE.Math3Node.prototype.toJSON = function ( meta ) {
+Math3Node.prototype.toJSON = function ( meta ) {
 
 	var data = this.getJSONNode( meta );
 
@@ -104,3 +116,5 @@ THREE.Math3Node.prototype.toJSON = function ( meta ) {
 	return data;
 
 };
+
+export { Math3Node };

+ 25 - 23
examples/js/nodes/math/OperatorNode.js

@@ -2,29 +2,31 @@
  * @author sunag / http://www.sunag.com.br/
  */
 
-THREE.OperatorNode = function ( a, b, op ) {
+import { TempNode } from '../core/TempNode.js';
+ 
+function OperatorNode( a, b, op ) {
 
-	THREE.TempNode.call( this );
+	TempNode.call( this );
 
 	this.a = a;
 	this.b = b;
-	this.op = op || THREE.OperatorNode.ADD;
+	this.op = op || OperatorNode.ADD;
 
 };
 
-THREE.OperatorNode.ADD = '+';
-THREE.OperatorNode.SUB = '-';
-THREE.OperatorNode.MUL = '*';
-THREE.OperatorNode.DIV = '/';
+OperatorNode.ADD = '+';
+OperatorNode.SUB = '-';
+OperatorNode.MUL = '*';
+OperatorNode.DIV = '/';
 
-THREE.OperatorNode.prototype = Object.create( THREE.TempNode.prototype );
-THREE.OperatorNode.prototype.constructor = THREE.OperatorNode;
-THREE.OperatorNode.prototype.nodeType = "Operator";
+OperatorNode.prototype = Object.create( TempNode.prototype );
+OperatorNode.prototype.constructor = OperatorNode;
+OperatorNode.prototype.nodeType = "Operator";
 
-THREE.OperatorNode.prototype.getType = function ( builder ) {
+OperatorNode.prototype.getType = function ( builder ) {
 
-	var a = this.a.getType( builder );
-	var b = this.b.getType( builder );
+	var a = this.a.getType( builder ),
+		b = this.b.getType( builder );
 
 	if ( builder.isFormatMatrix( a ) ) {
 
@@ -42,23 +44,21 @@ THREE.OperatorNode.prototype.getType = function ( builder ) {
 
 };
 
-THREE.OperatorNode.prototype.generate = function ( builder, output ) {
+OperatorNode.prototype.generate = function ( builder, output ) {
 
-	var material = builder.material,
-		data = material.getDataNode( this.uuid );
+	var data = builder.getNodeData( this ),
+		type = this.getType( builder );
 
-	var type = this.getType( builder );
-
-	var a = this.a.build( builder, type );
-	var b = this.b.build( builder, type );
+	var a = this.a.build( builder, type ),
+		b = this.b.build( builder, type );
 
 	return builder.format( '( ' + a + ' ' +  this.op + ' '+ b + ' )', type, output );
 
 };
 
-THREE.OperatorNode.prototype.copy = function ( source ) {
+OperatorNode.prototype.copy = function ( source ) {
 			
-	THREE.GLNode.prototype.copy.call( this, source );
+	TempNode.prototype.copy.call( this, source );
 	
 	this.a = source.a;
 	this.b = source.b;
@@ -66,7 +66,7 @@ THREE.OperatorNode.prototype.copy = function ( source ) {
 	
 };
 
-THREE.OperatorNode.prototype.toJSON = function ( meta ) {
+OperatorNode.prototype.toJSON = function ( meta ) {
 
 	var data = this.getJSONNode( meta );
 
@@ -83,3 +83,5 @@ THREE.OperatorNode.prototype.toJSON = function ( meta ) {
 	return data;
 
 };
+
+export { OperatorNode };

+ 166 - 0
examples/js/nodes/misc/BumpMapNode.js

@@ -0,0 +1,166 @@
+/**
+ * @author sunag / http://www.sunag.com.br/
+ */
+
+import { TempNode } from '../core/TempNode.js';
+import { FloatNode } from '../inputs/FloatNode.js';
+import { FunctionNode } from '../core/FunctionNode.js';
+import { NormalNode } from '../accessors/NormalNode.js';
+import { PositionNode } from '../accessors/PositionNode.js';
+
+function BumpMapNode( value, scale ) {
+
+	TempNode.call( this, 'v3' );
+
+	this.value = value;
+	this.scale = scale || new FloatNode( 1 );
+
+	this.toNormalMap = false;
+	
+};
+
+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 } );
+
+	var perturbNormalArb = new FunctionNode( [
+
+		"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 );",
+
+		"}"
+
+	].join( "\n" ), [ dHdxy_fwd ], { derivatives: true } );
+
+	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;
+BumpMapNode.prototype.nodeType = "BumpMap";
+
+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.coord.build( builder, 'v2' ) + ', ' +
+				this.scale.build( builder, 'fv1' ) + ' )', 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.coord.build( builder, 'v2' ) + ', ' +
+				this.scale.build( builder, 'fv1' ) + ' )';
+
+			return builder.format( perturbNormalArb + '( -' + this.position.build( builder, 'v3' ) + ', ' +
+				this.normal.build( builder, 'v3' ) + ', ' +
+				derivativeHeightCode + ' )', this.getType( builder ), output );
+			
+		}
+
+	} else {
+
+		console.warn( "THREE.BumpMapNode is not compatible with " + builder.shader + " shader." );
+
+		return builder.format( 'vec3( 0.0 )', this.getType( 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 ) {
+
+	var data = this.getJSONNode( meta );
+
+	if ( ! data ) {
+
+		data = this.createJSONNode( meta );
+
+		data.value = this.value.toJSON( meta ).uuid;
+		data.scale = this.scale.toJSON( meta ).uuid;
+
+	}
+
+	return data;
+
+};
+
+export { BumpMapNode };

+ 119 - 0
examples/js/nodes/misc/NormalMapNode.js

@@ -0,0 +1,119 @@
+/**
+ * @author sunag / http://www.sunag.com.br/
+ */
+
+import { TempNode } from '../core/TempNode.js';
+import { Vector2Node } from '../inputs/Vector2Node.js';
+import { FunctionNode } from '../core/FunctionNode.js';
+import { UVNode } from '../accessors/UVNode.js';
+import { NormalNode } from '../accessors/NormalNode.js';
+import { PositionNode } from '../accessors/PositionNode.js';
+
+function NormalMapNode( value, scale ) {
+
+	TempNode.call( this, 'v3' );
+
+	this.value = value;
+	this.scale = scale || new Vector2Node( 1, 1 );
+
+};
+
+NormalMapNode.Nodes = (function() {
+	
+	var perturbNormal2Arb = new FunctionNode( [
+
+		// Per-Pixel Tangent Space Normal Mapping
+		// http://hacksoflife.blogspot.ch/2009/11/per-pixel-tangent-space-normal-mapping.html
+
+		"vec3 perturbNormal2Arb( vec3 eye_pos, vec3 surf_norm, vec3 map, vec2 mUv, 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 );",
+
+		"}"
+
+	].join( "\n" ), null, { derivatives: true } );
+
+	return {
+		perturbNormal2Arb: perturbNormal2Arb
+	};
+	
+})();
+
+NormalMapNode.prototype = Object.create( TempNode.prototype );
+NormalMapNode.prototype.constructor = NormalMapNode;
+NormalMapNode.prototype.nodeType = "NormalMap";
+
+NormalMapNode.prototype.generate = function ( builder, output ) {
+
+	var material = builder.material;
+
+	if ( builder.isShader( 'fragment' ) ) {
+
+		var perturbNormal2Arb = builder.include( NormalMapNode.Nodes.perturbNormal2Arb );
+
+		this.normal = this.normal || new NormalNode( NormalNode.VIEW );
+		this.position = this.position || new PositionNode( PositionNode.VIEW );
+		this.uv = this.uv || new UVNode();
+
+		return builder.format( perturbNormal2Arb + '( -' + this.position.build( builder, 'v3' ) + ', ' +
+			this.normal.build( builder, 'v3' ) + ', ' +
+			this.value.build( builder, 'v3' ) + ', ' +
+			this.uv.build( builder, 'v2' ) + ', ' +
+			this.scale.build( builder, 'v2' ) + ' )', this.getType( builder ), output );
+
+	} else {
+
+		console.warn( "THREE.NormalMapNode is not compatible with " + builder.shader + " shader." );
+
+		return builder.format( 'vec3( 0.0 )', this.getType( 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 ) {
+
+	var data = this.getJSONNode( meta );
+
+	if ( ! data ) {
+
+		data = this.createJSONNode( meta );
+
+		data.value = this.value.toJSON( meta ).uuid;
+		data.scale = this.scale.toJSON( meta ).uuid;
+
+	}
+
+	return data;
+
+};
+
+export { NormalMapNode };

+ 18 - 15
examples/js/nodes/utils/TextureCubeNode.js → examples/js/nodes/misc/TextureCubeNode.js

@@ -2,31 +2,32 @@
  * @author sunag / http://www.sunag.com.br/
  */
 
-THREE.TextureCubeNode = function ( value, coord ) {
+import { TempNode } from '../core/TempNode.js';
+import { TextureCubeUVNode } from './TextureCubeUVNode.js';
+ 
+function TextureCubeNode( value, coord ) {
 
-	THREE.TempNode.call( this, 'v4' );
+	TempNode.call( this, 'v4' );
 
 	this.value = value;
-	this.coord = coord || new THREE.TextureCubeUVNode();
+	this.coord = coord || new TextureCubeUVNode();
 
 };
 
-THREE.TextureCubeNode.prototype = Object.create( THREE.TempNode.prototype );
-THREE.TextureCubeNode.prototype.constructor = THREE.TextureCubeNode;
-THREE.TextureCubeNode.prototype.nodeType = "TextureCube";
+TextureCubeNode.prototype = Object.create( TempNode.prototype );
+TextureCubeNode.prototype.constructor = TextureCubeNode;
+TextureCubeNode.prototype.nodeType = "TextureCube";
 
-THREE.TextureCubeNode.prototype.generate = function ( builder, output ) {
-
-	var material = builder.material;
+TextureCubeNode.prototype.generate = function ( builder, output ) {
 
 	if ( builder.isShader( 'fragment' ) ) {
 
-		var uv_10 = this.coord.build( builder ) + '.uv_10';
-		var uv_20 = this.coord.build( builder ) + '.uv_20';
-		var t = this.coord.build( builder ) + '.t';
+		var uv_10 = this.coord.build( builder ) + '.uv_10',
+			uv_20 = this.coord.build( builder ) + '.uv_20',
+			t = this.coord.build( builder ) + '.t';
 		
-		var color10 = builder.getTexelDecodingFunctionFromTexture( 'texture2D( ' + this.value.build( builder, 'sampler2D' ) + ', ' + uv_10 + ' )', this.value.value );
-		var color20 = builder.getTexelDecodingFunctionFromTexture( 'texture2D( ' + this.value.build( builder, 'sampler2D' ) + ', ' + uv_20 + ' )', this.value.value );
+		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 );
 			
@@ -40,7 +41,7 @@ THREE.TextureCubeNode.prototype.generate = function ( builder, output ) {
 
 };
 
-THREE.TextureCubeNode.prototype.toJSON = function ( meta ) {
+TextureCubeNode.prototype.toJSON = function ( meta ) {
 
 	var data = this.getJSONNode( meta );
 
@@ -59,3 +60,5 @@ THREE.TextureCubeNode.prototype.toJSON = function ( meta ) {
 	return data;
 
 };
+
+export { TextureCubeNode };

+ 66 - 49
examples/js/nodes/utils/TextureCubeUVNode.js → examples/js/nodes/misc/TextureCubeUVNode.js

@@ -2,27 +2,35 @@
  * @author sunag / http://www.sunag.com.br/
  */
 
-THREE.TextureCubeUVNode = function ( coord, textureSize, blinnExponentToRoughness ) {
-
-	THREE.TempNode.call( this, THREE.TextureCubeUVNode.fTextureCubeUVOutput.type );
-
-	this.coord = coord || new THREE.ReflectNode( THREE.ReflectNode.VECTOR );
-	this.textureSize = textureSize || new THREE.FloatNode( 1024 );
-	this.blinnExponentToRoughness = this.blinnExponentToRoughness || new THREE.BlinnExponentToRoughnessNode();
+import { TempNode } from '../core/TempNode.js';
+import { ConstNode } from '../core/ConstNode.js';
+import { StructNode } from '../core/StructNode.js';
+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( coord, textureSize, blinnExponentToRoughness ) {
+
+	TempNode.call( this, 'TextureCubeUVData' ); // TextureCubeUVData is type as StructNode
+
+	this.coord = coord || new ReflectNode( ReflectNode.VECTOR );
+	this.textureSize = textureSize || new FloatNode( 1024 );
+	this.blinnExponentToRoughness = this.blinnExponentToRoughness || new BlinnExponentToRoughnessNode();
 
 };
 
-THREE.TextureCubeUVNode.fTextureCubeUVOutput = new THREE.StructNode([
-"struct TextureCubeUVData {",
-"	vec2 uv_10;",
-"	vec2 uv_20;",
-"	float t;",
-"}"
-].join( "\n" ));
-
-THREE.TextureCubeUVNode.fTextureCubeUV = ( function () {
-
-	var getFaceFromDirection = new THREE.FunctionNode( [
+TextureCubeUVNode.Nodes = (function() {
+
+	var TextureCubeUVData = new StructNode([
+		"struct TextureCubeUVData {",
+		"	vec2 uv_10;",
+		"	vec2 uv_20;",
+		"	float t;",
+		"}"
+	].join( "\n" ));
+	
+	var getFaceFromDirection = new FunctionNode( [
 		"int getFaceFromDirection(vec3 direction) {",
 		"	vec3 absDirection = abs(direction);",
 		"	int face = -1;",
@@ -39,12 +47,13 @@ THREE.TextureCubeUVNode.fTextureCubeUV = ( function () {
 		"			face = direction.y > 0.0 ? 1 : 4;",
 		"	}",
 		"	return face;",
-		"}" ].join( "\n" ) );
-
-	var cubeUV_maxLods1 = new THREE.ConstNode( "#define cubeUV_maxLods1 ( log2( cubeUV_textureSize * 0.25 ) - 1.0 )" );
-	var cubeUV_rangeClamp = new THREE.ConstNode( "#define cubeUV_rangeClamp ( exp2( ( 6.0 - 1.0 ) * 2.0 ) )" );
-
-	var MipLevelInfo = new THREE.FunctionNode( [
+		"}"
+	].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);",
 		"	float dxRoughness = dFdx(roughness);",
@@ -56,12 +65,13 @@ THREE.TextureCubeUVNode.fTextureCubeUV = ( function () {
 		"	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 } );
+		"}" 
+	].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 )" );
 
-	var cubeUV_maxLods2 = new THREE.ConstNode( "#define cubeUV_maxLods2 ( log2( cubeUV_textureSize * 0.25 ) - 2.0 )" );
-	var cubeUV_rcpTextureSize = new THREE.ConstNode( "#define cubeUV_rcpTextureSize ( 1.0 / cubeUV_textureSize )" );
-
-	var getCubeUV = new THREE.FunctionNode( [
+	var getCubeUV = new FunctionNode( [
 		"vec2 getCubeUV( vec3 direction, float roughnessLevel, float mipLevel, in float cubeUV_textureSize ) {",
 		"	mipLevel = roughnessLevel > cubeUV_maxLods2 - 3.0 ? 0.0 : mipLevel;",
 		"	float a = 16.0 * cubeUV_rcpTextureSize;",
@@ -119,11 +129,12 @@ THREE.TextureCubeUVNode.fTextureCubeUV = ( 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 THREE.ConstNode( "#define cubeUV_maxLods3 ( log2( cubeUV_textureSize * 0.25 ) - 3.0 )" );
-
-	return new THREE.FunctionNode( [
+		"}" 
+	].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;",
 		"	float r1 = floor(roughnessVal);",
@@ -143,23 +154,27 @@ THREE.TextureCubeUVNode.fTextureCubeUV = ( function () {
 		"	vec2 uv_20 = getCubeUV(reflectedDirection, r2, level0, cubeUV_textureSize);",
 		"",
 		"	return TextureCubeUVData(uv_10, uv_20, t);",
-		"}" ].join( "\n" ), [ THREE.TextureCubeUVNode.fTextureCubeUVOutput, cubeUV_maxLods3, MipLevelInfo, getCubeUV ] );
-
-} )();
-
-THREE.TextureCubeUVNode.prototype = Object.create( THREE.TempNode.prototype );
-THREE.TextureCubeUVNode.prototype.constructor = THREE.TextureCubeUVNode;
-THREE.TextureCubeUVNode.prototype.nodeType = "TextureCubeUV";
-
-THREE.TextureCubeUVNode.prototype.generate = function ( builder, output ) {
-
-	var material = builder.material, func = THREE.TextureCubeUVNode.fTextureCubeUV;
-
-	builder.include( func );
+		"}" 
+	].join( "\n" ), [ TextureCubeUVData, cubeUV_maxLods3, MipLevelInfo, getCubeUV ] );
+	
+	return {
+		TextureCubeUVData: TextureCubeUVData,
+		textureCubeUV: textureCubeUV
+	};
+	
+})();
+
+TextureCubeUVNode.prototype = Object.create( TempNode.prototype );
+TextureCubeUVNode.prototype.constructor = TextureCubeUVNode;
+TextureCubeUVNode.prototype.nodeType = "TextureCubeUV";
+
+TextureCubeUVNode.prototype.generate = function ( builder, output ) {
 
 	if ( builder.isShader( 'fragment' ) ) {
 
-		return builder.format( func.name + '( ' + this.coord.build( builder, 'v3' ) + ', ' +
+		var textureCubeUV = builder.include( TextureCubeUVNode.Nodes.textureCubeUV );
+	
+		return builder.format( textureCubeUV + '( ' + this.coord.build( builder, 'v3' ) + ', ' +
 			this.blinnExponentToRoughness.build( builder, 'fv1' ) + ', ' +
 			this.textureSize.build( builder, 'fv1' ) + ' )', this.getType( builder ), output );
 			
@@ -173,7 +188,7 @@ THREE.TextureCubeUVNode.prototype.generate = function ( builder, output ) {
 
 };
 
-THREE.TextureCubeUVNode.prototype.toJSON = function ( meta ) {
+TextureCubeUVNode.prototype.toJSON = function ( meta ) {
 
 	var data = this.getJSONNode( meta );
 
@@ -190,3 +205,5 @@ THREE.TextureCubeUVNode.prototype.toJSON = function ( meta ) {
 	return data;
 
 };
+
+export { TextureCubeUVNode };

+ 15 - 9
examples/js/nodes/postprocessing/NodePass.js

@@ -2,7 +2,11 @@
  * @author sunag / http://www.sunag.com.br/
  */
 
-THREE.NodePass = function () {
+import { NodeMaterial } from '../materials/NodeMaterial.js';
+import { RawNode } from '../materials/nodes/RawNode.js';
+import { ScreenNode } from '../inputs/ScreenNode.js';
+
+function NodePass() {
 
 	THREE.ShaderPass.call( this );
 
@@ -13,21 +17,21 @@ THREE.NodePass = function () {
 
 	this.textureID = 'renderTexture';
 
-	this.fragment = new THREE.RawNode( new THREE.ScreenNode() );
+	this.fragment = new RawNode( new ScreenNode() );
 
-	this.node = new THREE.NodeMaterial();
+	this.node = new NodeMaterial();
 	this.node.fragment = this.fragment;
 
 	this.needsUpdate = true;
 
 };
 
-THREE.NodePass.prototype = Object.create( THREE.ShaderPass.prototype );
-THREE.NodePass.prototype.constructor = THREE.NodePass;
+NodePass.prototype = Object.create( THREE.ShaderPass.prototype );
+NodePass.prototype.constructor = NodePass;
 
-THREE.NodeMaterial.addShortcuts( THREE.NodePass.prototype, 'fragment', [ 'value' ] );
+NodeMaterial.addShortcuts( NodePass.prototype, 'fragment', [ 'value' ] );
 
-THREE.NodePass.prototype.render = function () {
+NodePass.prototype.render = function () {
 
 	if ( this.needsUpdate ) {
 
@@ -44,13 +48,13 @@ THREE.NodePass.prototype.render = function () {
 
 };
 
-THREE.NodePass.prototype.copy = function ( source ) {
+NodePass.prototype.copy = function ( source ) {
 	
 	this.value = source.value;
 	
 };
 
-THREE.NodePass.prototype.toJSON = function ( meta ) {
+NodePass.prototype.toJSON = function ( meta ) {
 
 	var isRootObject = ( meta === undefined || typeof meta === 'string' );
 
@@ -86,3 +90,5 @@ THREE.NodePass.prototype.toJSON = function ( meta ) {
 	return meta;
 
 };
+
+export { NodePass };

+ 69 - 0
examples/js/nodes/procedural/NoiseNode.js

@@ -0,0 +1,69 @@
+/**
+ * @author sunag / http://www.sunag.com.br/
+ */
+
+import { TempNode } from '../core/TempNode.js';
+import { FunctionNode } from '../core/FunctionNode.js';
+import { UVNode } from '../accessors/UVNode.js';
+
+function NoiseNode( coord ) {
+
+	TempNode.call( this, 'fv1' );
+
+	this.coord = coord || new UVNode();
+
+};
+
+NoiseNode.prototype = Object.create( TempNode.prototype );
+NoiseNode.prototype.constructor = NoiseNode;
+NoiseNode.prototype.nodeType = "Noise";
+
+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 ) {
+
+	var snoise = builder.include( NoiseNode.Nodes.snoise );
+
+	return builder.format( snoise + '( ' + this.coord.build( builder, 'v2' ) + ' )', this.getType( builder ), output );
+
+};
+
+NoiseNode.prototype.copy = function ( source ) {
+			
+	TempNode.prototype.copy.call( this, source );
+	
+	this.coord = source.coord;
+	
+};
+
+NoiseNode.prototype.toJSON = function ( meta ) {
+
+	var data = this.getJSONNode( meta );
+
+	if ( ! data ) {
+
+		data = this.createJSONNode( meta );
+
+		data.coord = this.coord.toJSON( meta ).uuid;
+
+	}
+
+	return data;
+
+};
+
+export { NoiseNode };

+ 0 - 45
examples/js/nodes/utils/BlinnExponentToRoughnessNode.js

@@ -1,45 +0,0 @@
-/**
- * @author sunag / http://www.sunag.com.br/
- */
-
-THREE.BlinnExponentToRoughnessNode = function ( blinnExponent ) {
-
-	THREE.TempNode.call( this, 'fv1' );
-
-	this.blinnExponent = blinnExponent || new THREE.BlinnShininessExponentNode();
-
-};
-
-THREE.BlinnExponentToRoughnessNode.prototype = Object.create( THREE.TempNode.prototype );
-THREE.BlinnExponentToRoughnessNode.prototype.constructor = THREE.BlinnExponentToRoughnessNode;
-THREE.BlinnExponentToRoughnessNode.prototype.nodeType = "BlinnExponentToRoughness";
-
-THREE.BlinnExponentToRoughnessNode.prototype.generate = function ( builder, output ) {
-
-	return builder.format( 'BlinnExponentToGGXRoughness( ' + this.blinnExponent.build( builder, 'fv1' ) + ' )', this.type, output );
-
-};
-
-THREE.BlinnExponentToRoughnessNode.prototype.copy = function ( source ) {
-			
-	THREE.GLNode.prototype.copy.call( this, source );
-	
-	this.blinnExponent = source.blinnExponent;
-	
-};
-
-THREE.BlinnExponentToRoughnessNode.prototype.toJSON = function ( meta ) {
-
-	var data = this.getJSONNode( meta );
-
-	if ( ! data ) {
-
-		data = this.createJSONNode( meta );
-
-		data.blinnExponent = this.blinnExponent;
-
-	}
-
-	return data;
-
-};

+ 0 - 27
examples/js/nodes/utils/BlinnShininessExponentNode.js

@@ -1,27 +0,0 @@
-/**
- * @author sunag / http://www.sunag.com.br/
- */
-
-THREE.BlinnShininessExponentNode = function () {
-
-	THREE.TempNode.call( this, 'fv1' );
-
-};
-
-THREE.BlinnShininessExponentNode.prototype = Object.create( THREE.TempNode.prototype );
-THREE.BlinnShininessExponentNode.prototype.constructor = THREE.BlinnShininessExponentNode;
-THREE.BlinnShininessExponentNode.prototype.nodeType = "BlinnShininessExponent";
-
-THREE.BlinnShininessExponentNode.prototype.generate = function ( builder, output ) {
-
-	if ( builder.isCache( 'clearCoat' ) ) {
-
-		return builder.format( 'Material_ClearCoat_BlinnShininessExponent( material )', this.type, output );
-
-	} else {
-
-		return builder.format( 'Material_BlinnShininessExponent( material )', this.type, output );
-
-	}
-
-};

+ 0 - 152
examples/js/nodes/utils/BlurNode.js

@@ -1,152 +0,0 @@
-/**
- * @author sunag / http://www.sunag.com.br/
- */
-
-THREE.BlurNode = function ( value, coord, radius, size ) {
-
-	THREE.TempNode.call( this, 'v4' );
-
-	this.value = value;
-	this.coord = coord || new THREE.UVNode();
-	this.radius = new THREE.Vector2Node( 1, 1 );
-
-	this.size = size;
-
-	this.blurX = true;
-	this.blurY = true;
-
-	this.horizontal = new THREE.FloatNode( 1 / 64 );
-	this.vertical = new THREE.FloatNode( 1 / 64 );
-
-};
-
-THREE.BlurNode.fBlurX = new THREE.FunctionNode( [
-	"vec4 blurX( sampler2D texture, vec2 uv, float s ) {",
-	"	vec4 sum = vec4( 0.0 );",
-	"	sum += texture2D( texture, vec2( uv.x - 4.0 * s, uv.y ) ) * 0.051;",
-	"	sum += texture2D( texture, vec2( uv.x - 3.0 * s, uv.y ) ) * 0.0918;",
-	"	sum += texture2D( texture, vec2( uv.x - 2.0 * s, uv.y ) ) * 0.12245;",
-	"	sum += texture2D( texture, vec2( uv.x - 1.0 * s, uv.y ) ) * 0.1531;",
-	"	sum += texture2D( texture, vec2( uv.x, uv.y ) ) * 0.1633;",
-	"	sum += texture2D( texture, vec2( uv.x + 1.0 * s, uv.y ) ) * 0.1531;",
-	"	sum += texture2D( texture, vec2( uv.x + 2.0 * s, uv.y ) ) * 0.12245;",
-	"	sum += texture2D( texture, vec2( uv.x + 3.0 * s, uv.y ) ) * 0.0918;",
-	"	sum += texture2D( texture, vec2( uv.x + 4.0 * s, uv.y ) ) * 0.051;",
-	"	return sum;",
-	"}"
-].join( "\n" ) );
-
-THREE.BlurNode.fBlurY = new THREE.FunctionNode( [
-	"vec4 blurY( sampler2D texture, vec2 uv, float s ) {",
-	"	vec4 sum = vec4( 0.0 );",
-	"	sum += texture2D( texture, vec2( uv.x, uv.y - 4.0 * s ) ) * 0.051;",
-	"	sum += texture2D( texture, vec2( uv.x, uv.y - 3.0 * s ) ) * 0.0918;",
-	"	sum += texture2D( texture, vec2( uv.x, uv.y - 2.0 * s ) ) * 0.12245;",
-	"	sum += texture2D( texture, vec2( uv.x, uv.y - 1.0 * s ) ) * 0.1531;",
-	"	sum += texture2D( texture, vec2( uv.x, uv.y ) ) * 0.1633;",
-	"	sum += texture2D( texture, vec2( uv.x, uv.y + 1.0 * s ) ) * 0.1531;",
-	"	sum += texture2D( texture, vec2( uv.x, uv.y + 2.0 * s ) ) * 0.12245;",
-	"	sum += texture2D( texture, vec2( uv.x, uv.y + 3.0 * s ) ) * 0.0918;",
-	"	sum += texture2D( texture, vec2( uv.x, uv.y + 4.0 * s ) ) * 0.051;",
-	"	return sum;",
-	"}"
-].join( "\n" ) );
-
-THREE.BlurNode.prototype = Object.create( THREE.TempNode.prototype );
-THREE.BlurNode.prototype.constructor = THREE.BlurNode;
-THREE.BlurNode.prototype.nodeType = "Blur";
-
-THREE.BlurNode.prototype.updateFrame = function ( frame ) {
-
-	if ( this.size ) {
-
-		this.horizontal.value = this.radius.x / this.size.x;
-		this.vertical.value = this.radius.y / this.size.y;
-
-	} else if ( this.value.value && this.value.value.image ) {
-
-		var image = this.value.value.image;
-
-		this.horizontal.value = this.radius.x / image.width;
-		this.vertical.value = this.radius.y / image.height;
-
-	}
-
-};
-
-THREE.BlurNode.prototype.generate = function ( builder, output ) {
-
-	var material = builder.material, blurX = THREE.BlurNode.fBlurX, blurY = THREE.BlurNode.fBlurY;
-
-	builder.include( blurX );
-	builder.include( blurY );
-
-	if ( builder.isShader( 'fragment' ) ) {
-
-		var blurCode = [], code;
-
-		if ( this.blurX ) {
-
-			blurCode.push( blurX.name + '( ' + this.value.build( builder, 'sampler2D' ) + ', ' + this.coord.build( builder, 'v2' ) + ', ' + this.horizontal.build( builder, 'fv1' ) + ' )' );
-
-		}
-
-		if ( this.blurY ) {
-
-			blurCode.push( blurY.name + '( ' + this.value.build( builder, 'sampler2D' ) + ', ' + this.coord.build( builder, 'v2' ) + ', ' + this.vertical.build( builder, 'fv1' ) + ' )' );
-
-		}
-
-		if ( blurCode.length == 2 ) code = '( ' + blurCode.join( ' + ' ) + '/ 2.0 )';
-		else if ( blurCode.length ) code = '( ' + blurCode[ 0 ] + ' )';
-		else code = 'vec4( 0.0 )';
-
-		return builder.format( code, this.getType( builder ), output );
-
-	} else {
-
-		console.warn( "THREE.BlurNode is not compatible with " + builder.shader + " shader." );
-
-		return builder.format( 'vec4( 0.0 )', this.getType( builder ), output );
-
-	}
-
-};
-
-THREE.BlurNode.prototype.copy = function ( source ) {
-			
-	THREE.GLNode.prototype.copy.call( this, source );
-	
-	this.value = source.value;
-	this.coord = source.coord;
-	this.radius = source.radius;
-
-	if ( source.size !== undefined ) this.size = new THREE.Vector2( source.size.x, source.size.y );
-
-	this.blurX = source.blurX;
-	this.blurY = source.blurY;
-					
-};
-
-THREE.BlurNode.prototype.toJSON = function ( meta ) {
-
-	var data = this.getJSONNode( meta );
-
-	if ( ! data ) {
-
-		data = this.createJSONNode( meta );
-
-		data.value = this.value.toJSON( meta ).uuid;
-		data.coord = this.coord.toJSON( meta ).uuid;
-		data.radius = this.radius.toJSON( meta ).uuid;
-
-		if ( this.size ) data.size = { x: this.size.x, y: this.size.y };
-
-		data.blurX = this.blurX;
-		data.blurY = this.blurY;
-
-	}
-
-	return data;
-
-};

+ 0 - 95
examples/js/nodes/utils/BumpMapNode.js

@@ -1,95 +0,0 @@
-/**
- * @author sunag / http://www.sunag.com.br/
- */
-
-THREE.BumpMapNode = function ( value, scale ) {
-
-	THREE.TempNode.call( this, 'v3' );
-
-	this.value = value;
-	this.scale = scale || new THREE.FloatNode( 1 );
-
-	this.toNormalMap = false;
-	
-};
-
-THREE.BumpMapNode.fBumpToNormal = new THREE.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 } );
-
-THREE.BumpMapNode.prototype = Object.create( THREE.TempNode.prototype );
-THREE.BumpMapNode.prototype.constructor = THREE.BumpMapNode;
-THREE.BumpMapNode.prototype.nodeType = "BumpMap";
-
-THREE.BumpMapNode.prototype.generate = function ( builder, output ) {
-
-	if ( builder.isShader( 'fragment' ) ) {
-
-		if ( this.toNormalMap ) {
-	
-			builder.include( THREE.BumpMapNode.fBumpToNormal );
-		
-			return builder.format( THREE.BumpMapNode.fBumpToNormal.name + '( ' + this.value.build( builder, 'sampler2D' ) + ', ' +
-				this.value.coord.build( builder, 'v2' ) + ', ' +
-				this.scale.build( builder, 'fv1' ) + ' )', this.getType( builder ), output );
-				
-		} else {
-			
-			builder.include( 'dHdxy_fwd' );
-			builder.include( 'perturbNormalArb' );
-		
-			this.normal = this.normal || new THREE.NormalNode( THREE.NormalNode.VIEW );
-			this.position = this.position || new THREE.PositionNode( THREE.NormalNode.VIEW );
-		
-			var derivativeOfHeightCode = 'dHdxy_fwd( ' + this.value.build( builder, 'sampler2D' ) + ', ' +
-				this.value.coord.build( builder, 'v2' ) + ', ' +
-				this.scale.build( builder, 'fv1' ) + ' )';
-
-			return builder.format( 'perturbNormalArb( -' + this.position.build( builder, 'v3' ) + ', ' +
-				this.normal.build( builder, 'v3' ) + ', ' +
-				derivativeOfHeightCode + ' )', this.getType( builder ), output );
-			
-		}
-
-	} else {
-
-		console.warn( "THREE.BumpMapNode is not compatible with " + builder.shader + " shader." );
-
-		return builder.format( 'vec3( 0.0 )', this.getType( builder ), output );
-
-	}
-
-};
-
-THREE.BumpMapNode.prototype.copy = function ( source ) {
-			
-	THREE.GLNode.prototype.copy.call( this, source );
-	
-	this.value = source.value;
-	this.scale = source.scale;
-					
-};
-
-THREE.BumpMapNode.prototype.toJSON = function ( meta ) {
-
-	var data = this.getJSONNode( meta );
-
-	if ( ! data ) {
-
-		data = this.createJSONNode( meta );
-
-		data.value = this.value.toJSON( meta ).uuid;
-		data.scale = this.scale.toJSON( meta ).uuid;
-
-	}
-
-	return data;
-
-};

+ 16 - 14
examples/js/nodes/core/BypassNode.js → examples/js/nodes/utils/BypassNode.js

@@ -2,20 +2,22 @@
  * @author sunag / http://www.sunag.com.br/
  */
 
-THREE.BypassNode = function ( code, value ) {
+import { GLNode } from '../core/GLNode.js';
 
-	THREE.GLNode.call( this );
+function BypassNode( code, value ) {
+
+	GLNode.call( this );
 
 	this.code = code;
 	this.value = value;
 
 };
 
-THREE.BypassNode.prototype = Object.create( THREE.GLNode.prototype );
-THREE.BypassNode.prototype.constructor = THREE.BypassNode;
-THREE.BypassNode.prototype.nodeType = "Bypass";
+BypassNode.prototype = Object.create( GLNode.prototype );
+BypassNode.prototype.constructor = BypassNode;
+BypassNode.prototype.nodeType = "Bypass";
 
-THREE.BypassNode.prototype.getType = function ( builder ) {
+BypassNode.prototype.getType = function ( builder ) {
 
 	if ( this.value ) {
 		
@@ -31,14 +33,14 @@ THREE.BypassNode.prototype.getType = function ( builder ) {
 
 };
 
-THREE.BypassNode.prototype.generate = function ( builder, output ) {
+BypassNode.prototype.generate = function ( builder, output ) {
 
 	var code = this.code.build( builder, output ) + ';';
 
+	builder.addNodeCode( code );
+	
 	if ( builder.isShader( 'vertex' ) ) {
 		
-		builder.material.addVertexNode( code );
-		
 		if (this.value) {
 		
 			return this.value.build( builder, output );
@@ -47,24 +49,22 @@ THREE.BypassNode.prototype.generate = function ( builder, output ) {
 		
 	} else {
 		
-		builder.material.addFragmentNode( code );
-		
 		return this.value ? this.value.build( builder, output ) : builder.format( '0.0', 'fv1', output );
 		
 	}
 
 };
 
-THREE.BypassNode.prototype.copy = function ( source ) {
+BypassNode.prototype.copy = function ( source ) {
 	
-	THREE.GLNode.prototype.copy.call( this, source );
+	GLNode.prototype.copy.call( this, source );
 	
 	this.code = source.code;
 	this.value = source.value;
 	
 };
 
-THREE.BypassNode.prototype.toJSON = function ( meta ) {
+BypassNode.prototype.toJSON = function ( meta ) {
 
 	var data = this.getJSONNode( meta );
 
@@ -81,3 +81,5 @@ THREE.BypassNode.prototype.toJSON = function ( meta ) {
 	return data;
 
 };
+
+export { BypassNode };

+ 0 - 99
examples/js/nodes/utils/ColorAdjustmentNode.js

@@ -1,99 +0,0 @@
-/**
- * @author sunag / http://www.sunag.com.br/
- */
-
-THREE.ColorAdjustmentNode = function ( rgb, adjustment, method ) {
-
-	THREE.TempNode.call( this, 'v3' );
-
-	this.rgb = rgb;
-	this.adjustment = adjustment;
-
-	this.method = method || THREE.ColorAdjustmentNode.SATURATION;
-
-};
-
-THREE.ColorAdjustmentNode.SATURATION = 'saturation';
-THREE.ColorAdjustmentNode.HUE = 'hue';
-THREE.ColorAdjustmentNode.VIBRANCE = 'vibrance';
-THREE.ColorAdjustmentNode.BRIGHTNESS = 'brightness';
-THREE.ColorAdjustmentNode.CONTRAST = 'contrast';
-
-THREE.ColorAdjustmentNode.prototype = Object.create( THREE.TempNode.prototype );
-THREE.ColorAdjustmentNode.prototype.constructor = THREE.ColorAdjustmentNode;
-THREE.ColorAdjustmentNode.prototype.nodeType = "ColorAdjustment";
-
-THREE.ColorAdjustmentNode.prototype.generate = function ( builder, output ) {
-
-	var rgb = this.rgb.build( builder, 'v3' );
-	var adjustment = this.adjustment.build( builder, 'fv1' );
-
-	var name;
-
-	switch ( this.method ) {
-
-		case THREE.ColorAdjustmentNode.SATURATION:
-
-			name = 'saturation_rgb';
-
-			break;
-
-		case THREE.ColorAdjustmentNode.HUE:
-
-			name = 'hue_rgb';
-
-			break;
-
-		case THREE.ColorAdjustmentNode.VIBRANCE:
-
-			name = 'vibrance_rgb';
-
-			break;
-
-		case THREE.ColorAdjustmentNode.BRIGHTNESS:
-
-			return builder.format( '(' + rgb + '+' + adjustment + ')', this.getType( builder ), output );
-
-			break;
-
-		case THREE.ColorAdjustmentNode.CONTRAST:
-
-			return builder.format( '(' + rgb + '*' + adjustment + ')', this.getType( builder ), output );
-
-			break;
-
-	}
-
-	builder.include( name );
-
-	return builder.format( name + '(' + rgb + ',' + adjustment + ')', this.getType( builder ), output );
-
-};
-
-THREE.ColorAdjustmentNode.prototype.copy = function ( source ) {
-			
-	THREE.GLNode.prototype.copy.call( this, source );
-	
-	this.rgb = source.rgb;
-	this.adjustment = source.adjustment;
-	this.method = source.method;
-					
-};
-
-THREE.ColorAdjustmentNode.prototype.toJSON = function ( meta ) {
-
-	var data = this.getJSONNode( meta );
-
-	if ( ! data ) {
-
-		data = this.createJSONNode( meta );
-
-		data.rgb = this.rgb.toJSON( meta ).uuid;
-		data.adjustment = this.adjustment.toJSON( meta ).uuid;
-		data.method = this.method;
-
-	}
-
-	return data;
-
-};

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

@@ -2,9 +2,14 @@
  * @author sunag / http://www.sunag.com.br/
  */
 
-THREE.JoinNode = function ( x, y, z, w ) {
+import { TempNode } from '../core/TempNode.js';
+import { NodeUtils } from '../core/NodeUtils.js';
+ 
+var inputs = NodeUtils.elements;
+ 
+function JoinNode( x, y, z, w ) {
 
-	THREE.TempNode.call( this, 'fv1' );
+	TempNode.call( this, 'fv1' );
 
 	this.x = x;
 	this.y = y;
@@ -13,15 +18,12 @@ THREE.JoinNode = function ( x, y, z, w ) {
 
 };
 
-THREE.JoinNode.inputs = [ 'x', 'y', 'z', 'w' ];
+JoinNode.prototype = Object.create( TempNode.prototype );
+JoinNode.prototype.constructor = JoinNode;
+JoinNode.prototype.nodeType = "Join";
 
-THREE.JoinNode.prototype = Object.create( THREE.TempNode.prototype );
-THREE.JoinNode.prototype.constructor = THREE.JoinNode;
-THREE.JoinNode.prototype.nodeType = "Join";
+JoinNode.prototype.getNumElements = function () {
 
-THREE.JoinNode.prototype.getNumElements = function () {
-
-	var inputs = THREE.JoinNode.inputs;
 	var i = inputs.length;
 
 	while ( i -- ) {
@@ -29,6 +31,7 @@ THREE.JoinNode.prototype.getNumElements = function () {
 		if ( this[ inputs[ i ] ] !== undefined ) {
 
 			++ i;
+			
 			break;
 
 		}
@@ -39,39 +42,35 @@ THREE.JoinNode.prototype.getNumElements = function () {
 
 };
 
-THREE.JoinNode.prototype.getType = function ( builder ) {
+JoinNode.prototype.getType = function ( builder ) {
 
 	return builder.getFormatFromLength( this.getNumElements() );
 
 };
 
-THREE.JoinNode.prototype.generate = function ( builder, output ) {
-
-	var material = builder.material;
+JoinNode.prototype.generate = function ( builder, output ) {
 
-	var type = this.getType( builder );
-	var length = this.getNumElements();
-
-	var inputs = THREE.JoinNode.inputs;
-	var outputs = [];
+	var type = this.getType( builder ),
+		length = this.getNumElements(),
+		outputs = [];
 
 	for ( var i = 0; i < length; i ++ ) {
 
 		var elm = this[ inputs[ i ] ];
 
-		outputs.push( elm ? elm.build( builder, 'fv1' ) : '0.' );
+		outputs.push( elm ? elm.build( builder, 'fv1' ) : '0.0' );
 
 	}
 
-	var code = ( length > 1 ? builder.getConstructorFromLength( length ) : '' ) + '(' + outputs.join( ',' ) + ')';
+	var code = ( length > 1 ? builder.getConstructorFromLength( length ) : '' ) + '( ' + outputs.join( ', ' ) + ' )';
 
 	return builder.format( code, type, output );
 
 };
 
-THREE.JoinNode.prototype.copy = function ( source ) {
+JoinNode.prototype.copy = function ( source ) {
 			
-	THREE.GLNode.prototype.copy.call( this, source );
+	GLNode.prototype.copy.call( this, source );
 	
 	for ( var prop in source.inputs ) {
 
@@ -81,7 +80,7 @@ THREE.JoinNode.prototype.copy = function ( source ) {
 	
 };
 
-THREE.JoinNode.prototype.toJSON = function ( meta ) {
+JoinNode.prototype.toJSON = function ( meta ) {
 
 	var data = this.getJSONNode( meta );
 
@@ -92,7 +91,6 @@ THREE.JoinNode.prototype.toJSON = function ( meta ) {
 		data.inputs = {};
 
 		var length = this.getNumElements();
-		var inputs = THREE.JoinNode.inputs;
 
 		for ( var i = 0; i < length; i ++ ) {
 
@@ -112,3 +110,5 @@ THREE.JoinNode.prototype.toJSON = function ( meta ) {
 	return data;
 
 };
+
+export { JoinNode };

+ 0 - 47
examples/js/nodes/utils/LuminanceNode.js

@@ -1,47 +0,0 @@
-/**
- * @author sunag / http://www.sunag.com.br/
- */
-
-THREE.LuminanceNode = function ( rgb ) {
-
-	THREE.TempNode.call( this, 'fv1' );
-
-	this.rgb = rgb;
-
-};
-
-THREE.LuminanceNode.prototype = Object.create( THREE.TempNode.prototype );
-THREE.LuminanceNode.prototype.constructor = THREE.LuminanceNode;
-THREE.LuminanceNode.prototype.nodeType = "Luminance";
-
-THREE.LuminanceNode.prototype.generate = function ( builder, output ) {
-
-	builder.include( 'luminance_rgb' );
-
-	return builder.format( 'luminance_rgb(' + this.rgb.build( builder, 'v3' ) + ')', this.getType( builder ), output );
-
-};
-
-THREE.LuminanceNode.prototype.copy = function ( source ) {
-			
-	THREE.GLNode.prototype.copy.call( this, source );
-	
-	this.rgb = source.rgb;
-	
-};
-
-THREE.LuminanceNode.prototype.toJSON = function ( meta ) {
-
-	var data = this.getJSONNode( meta );
-
-	if ( ! data ) {
-
-		data = this.createJSONNode( meta );
-
-		data.rgb = this.rgb.toJSON( meta ).uuid;
-
-	}
-
-	return data;
-
-};

+ 16 - 8
examples/js/nodes/utils/MaxMIPLevelNode.js

@@ -2,9 +2,11 @@
  * @author sunag / http://www.sunag.com.br/
  */
 
-THREE.MaxMIPLevelNode = function ( texture ) {
+import { FloatNode } from '../inputs/FloatNode.js';
+ 
+function MaxMIPLevelNode( texture ) {
 
-	THREE.FloatNode.call( this );
+	FloatNode.call( this );
 
 	this.texture = texture;
 
@@ -12,13 +14,14 @@ THREE.MaxMIPLevelNode = function ( texture ) {
 
 };
 
-THREE.MaxMIPLevelNode.prototype = Object.create( THREE.FloatNode.prototype );
-THREE.MaxMIPLevelNode.prototype.constructor = THREE.MaxMIPLevelNode;
-THREE.MaxMIPLevelNode.prototype.nodeType = "MaxMIPLevel";
+MaxMIPLevelNode.prototype = Object.create( FloatNode.prototype );
+MaxMIPLevelNode.prototype.constructor = MaxMIPLevelNode;
+MaxMIPLevelNode.prototype.nodeType = "MaxMIPLevel";
 
-Object.defineProperties( THREE.MaxMIPLevelNode.prototype, {
+Object.defineProperties( MaxMIPLevelNode.prototype, {
 
 	value: {
+		
 		get: function () {
 
 			if ( this.maxMIPLevel === 0 ) {
@@ -31,12 +34,15 @@ Object.defineProperties( THREE.MaxMIPLevelNode.prototype, {
 
 			return this.maxMIPLevel;
 
-		}
+		},
+		
+		set: function () { }
+		
 	}
 
 } );
 
-THREE.MaxMIPLevelNode.prototype.toJSON = function ( meta ) {
+MaxMIPLevelNode.prototype.toJSON = function ( meta ) {
 
 	var data = this.getJSONNode( meta );
 
@@ -51,3 +57,5 @@ THREE.MaxMIPLevelNode.prototype.toJSON = function ( meta ) {
 	return data;
 
 };
+
+export { MaxMIPLevelNode };

+ 0 - 47
examples/js/nodes/utils/NoiseNode.js

@@ -1,47 +0,0 @@
-/**
- * @author sunag / http://www.sunag.com.br/
- */
-
-THREE.NoiseNode = function ( coord ) {
-
-	THREE.TempNode.call( this, 'fv1' );
-
-	this.coord = coord;
-
-};
-
-THREE.NoiseNode.prototype = Object.create( THREE.TempNode.prototype );
-THREE.NoiseNode.prototype.constructor = THREE.NoiseNode;
-THREE.NoiseNode.prototype.nodeType = "Noise";
-
-THREE.NoiseNode.prototype.generate = function ( builder, output ) {
-
-	builder.include( 'snoise' );
-
-	return builder.format( 'snoise(' + this.coord.build( builder, 'v2' ) + ')', this.getType( builder ), output );
-
-};
-
-THREE.NoiseNode.prototype.copy = function ( source ) {
-			
-	THREE.GLNode.prototype.copy.call( this, source );
-	
-	this.coord = source.coord;
-	
-};
-
-THREE.NoiseNode.prototype.toJSON = function ( meta ) {
-
-	var data = this.getJSONNode( meta );
-
-	if ( ! data ) {
-
-		data = this.createJSONNode( meta );
-
-		data.coord = this.coord.toJSON( meta ).uuid;
-
-	}
-
-	return data;
-
-};

+ 0 - 70
examples/js/nodes/utils/NormalMapNode.js

@@ -1,70 +0,0 @@
-/**
- * @author sunag / http://www.sunag.com.br/
- */
-
-THREE.NormalMapNode = function ( value, scale ) {
-
-	THREE.TempNode.call( this, 'v3' );
-
-	this.value = value;
-	this.scale = scale || new THREE.Vector2Node( 1, 1 );
-
-};
-
-THREE.NormalMapNode.prototype = Object.create( THREE.TempNode.prototype );
-THREE.NormalMapNode.prototype.constructor = THREE.NormalMapNode;
-THREE.NormalMapNode.prototype.nodeType = "NormalMap";
-
-THREE.NormalMapNode.prototype.generate = function ( builder, output ) {
-
-	var material = builder.material;
-
-	if ( builder.isShader( 'fragment' ) ) {
-
-		builder.include( 'perturbNormal2Arb' );
-
-		this.normal = this.normal || new THREE.NormalNode( THREE.NormalNode.VIEW );
-		this.position = this.position || new THREE.PositionNode( THREE.NormalNode.VIEW );
-		this.uv = this.uv || new THREE.UVNode();
-
-		return builder.format( 'perturbNormal2Arb( -' + this.position.build( builder, 'v3' ) + ', ' +
-			this.normal.build( builder, 'v3' ) + ', ' +
-			this.value.build( builder, 'v3' ) + ', ' +
-			this.uv.build( builder, 'v2' ) + ', ' +
-			this.scale.build( builder, 'v2' ) + ' )', this.getType( builder ), output );
-
-	} else {
-
-		console.warn( "THREE.NormalMapNode is not compatible with " + builder.shader + " shader." );
-
-		return builder.format( 'vec3( 0.0 )', this.getType( builder ), output );
-
-	}
-
-};
-
-THREE.NormalMapNode.prototype.copy = function ( source ) {
-			
-	THREE.GLNode.prototype.copy.call( this, source );
-	
-	this.value = source.value;
-	this.scale = source.scale;
-	
-};
-
-THREE.NormalMapNode.prototype.toJSON = function ( meta ) {
-
-	var data = this.getJSONNode( meta );
-
-	if ( ! data ) {
-
-		data = this.createJSONNode( meta );
-
-		data.value = this.value.toJSON( meta ).uuid;
-		data.scale = this.scale.toJSON( meta ).uuid;
-
-	}
-
-	return data;
-
-};

+ 0 - 49
examples/js/nodes/utils/ResolutionNode.js

@@ -1,49 +0,0 @@
-/**
- * @author sunag / http://www.sunag.com.br/
- */
-
-THREE.ResolutionNode = function ( renderer ) {
-
-	THREE.Vector2Node.call( this );
-
-	this.renderer = renderer;
-
-};
-
-THREE.ResolutionNode.prototype = Object.create( THREE.Vector2Node.prototype );
-THREE.ResolutionNode.prototype.constructor = THREE.ResolutionNode;
-THREE.ResolutionNode.prototype.nodeType = "Resolution";
-
-THREE.ResolutionNode.prototype.updateFrame = function ( frame ) {
-
-	var size = this.renderer.getSize(),
-		pixelRatio = this.renderer.getPixelRatio();
-
-	this.x = size.width * pixelRatio;
-	this.y = size.height * pixelRatio;
-
-};
-
-THREE.ResolutionNode.prototype.copy = function ( source ) {
-			
-	THREE.GLNode.prototype.copy.call( this, source );
-	
-	this.renderer = source.renderer;
-	
-};
-
-THREE.ResolutionNode.prototype.toJSON = function ( meta ) {
-
-	var data = this.getJSONNode( meta );
-
-	if ( ! data ) {
-
-		data = this.createJSONNode( meta );
-
-		data.renderer = this.renderer.uuid;
-
-	}
-
-	return data;
-
-};

+ 0 - 79
examples/js/nodes/utils/RoughnessToBlinnExponentNode.js

@@ -1,79 +0,0 @@
-/**
- * @author sunag / http://www.sunag.com.br/
- */
-
-THREE.RoughnessToBlinnExponentNode = function ( texture ) {
-
-	THREE.TempNode.call( this, 'fv1' );
-
-	this.texture = texture;
-
-	this.maxMIPLevel = new THREE.MaxMIPLevelNode( texture );
-	this.blinnShininessExponent = new THREE.BlinnShininessExponentNode();
-
-};
-
-THREE.RoughnessToBlinnExponentNode.getSpecularMIPLevel = new THREE.FunctionNode( [
-	// taken from here: http://casual-effects.blogspot.ca/2011/08/plausible-environment-lighting-in-two.html
-	"float getSpecularMIPLevel( const in float blinnShininessExponent, const in float maxMIPLevelScalar ) {",
-
-	//	float envMapWidth = pow( 2.0, maxMIPLevelScalar );
-	//	float desiredMIPLevel = log2( envMapWidth * sqrt( 3.0 ) ) - 0.5 * log2( pow2( blinnShininessExponent ) + 1.0 );
-
-	"	float desiredMIPLevel = maxMIPLevelScalar - 0.79248 - 0.5 * log2( pow2( blinnShininessExponent ) + 1.0 );",
-
-	// clamp to allowable LOD ranges.
-	"	return clamp( desiredMIPLevel, 0.0, maxMIPLevelScalar );",
-	"}"
-].join( "\n" ) );
-
-THREE.RoughnessToBlinnExponentNode.prototype = Object.create( THREE.TempNode.prototype );
-THREE.RoughnessToBlinnExponentNode.prototype.constructor = THREE.RoughnessToBlinnExponentNode;
-THREE.RoughnessToBlinnExponentNode.prototype.nodeType = "RoughnessToBlinnExponent";
-
-THREE.RoughnessToBlinnExponentNode.prototype.generate = function ( builder, output ) {
-
-	var material = builder.material;
-
-	if ( builder.isShader( 'fragment' ) ) {
-
-		builder.include( THREE.RoughnessToBlinnExponentNode.getSpecularMIPLevel );
-
-		this.maxMIPLevel.texture = this.texture;
-		
-		return builder.format( 'getSpecularMIPLevel( ' + this.blinnShininessExponent.build( builder, 'fv1' ) + ', ' + this.maxMIPLevel.build( builder, 'fv1' ) + ' )', this.type, output );
-
-	} else {
-
-		console.warn( "THREE.RoughnessToBlinnExponentNode is not compatible with " + builder.shader + " shader." );
-
-		return builder.format( '0.0', this.type, output );
-
-	}
-
-};
-
-THREE.RoughnessToBlinnExponentNode.prototype.copy = function ( source ) {
-			
-	THREE.GLNode.prototype.copy.call( this, source );
-	
-	this.texture = source.texture;
-	
-};
-
-THREE.RoughnessToBlinnExponentNode.prototype.toJSON = function ( meta ) {
-
-	var data = this.getJSONNode( meta );
-
-	if ( ! data ) {
-
-		data = this.createJSONNode( meta );
-
-		data.texture = this.texture;
-
-	}
-
-	return data;
-
-};
-

+ 19 - 16
examples/js/nodes/utils/SwitchNode.js

@@ -2,38 +2,39 @@
  * @author sunag / http://www.sunag.com.br/
  */
 
-THREE.SwitchNode = function ( node, components ) {
+import { GLNode } from '../core/GLNode.js';
+ 
+function SwitchNode( node, components ) {
 
-	THREE.GLNode.call( this );
+	GLNode.call( this );
 
 	this.node = node;
 	this.components = components || 'x';
 
 };
 
-THREE.SwitchNode.prototype = Object.create( THREE.GLNode.prototype );
-THREE.SwitchNode.prototype.constructor = THREE.SwitchNode;
-THREE.SwitchNode.prototype.nodeType = "Switch";
+SwitchNode.prototype = Object.create( GLNode.prototype );
+SwitchNode.prototype.constructor = SwitchNode;
+SwitchNode.prototype.nodeType = "Switch";
 
-THREE.SwitchNode.prototype.getType = function ( builder ) {
+SwitchNode.prototype.getType = function ( builder ) {
 
 	return builder.getFormatFromLength( this.components.length );
 
 };
 
-THREE.SwitchNode.prototype.generate = function ( builder, output ) {
+SwitchNode.prototype.generate = function ( builder, output ) {
 
-	var type = this.node.getType( builder );
-	var inputLength = builder.getFormatLength( type ) - 1;
-
-	var node = this.node.build( builder, type );
+	var type = this.node.getType( builder ),
+		node = this.node.build( builder, type ),
+		inputLength = builder.getFormatLength( type ) - 1;
 
 	if ( inputLength > 0 ) {
 
 		// get max length
 
-		var outputLength = 0;
-		var components = builder.colorToVector( this.components );
+		var outputLength = 0,
+			components = builder.colorToVector( this.components );
 
 		var i, len = components.length;
 
@@ -72,16 +73,16 @@ THREE.SwitchNode.prototype.generate = function ( builder, output ) {
 
 };
 
-THREE.SwitchNode.prototype.copy = function ( source ) {
+SwitchNode.prototype.copy = function ( source ) {
 			
-	THREE.GLNode.prototype.copy.call( this, source );
+	GLNode.prototype.copy.call( this, source );
 	
 	this.node = source.node;
 	this.components = source.components;
 	
 };
 
-THREE.SwitchNode.prototype.toJSON = function ( meta ) {
+SwitchNode.prototype.toJSON = function ( meta ) {
 
 	var data = this.getJSONNode( meta );
 
@@ -97,3 +98,5 @@ THREE.SwitchNode.prototype.toJSON = function ( meta ) {
 	return data;
 
 };
+
+export { SwitchNode };

+ 29 - 18
examples/js/nodes/utils/TimerNode.js

@@ -2,51 +2,54 @@
  * @author sunag / http://www.sunag.com.br/
  */
 
-THREE.TimerNode = function ( scale, scope, useTimeScale ) {
+import { FloatNode } from '../inputs/FloatNode.js';
+import { NodeLib } from '../core/NodeLib.js';
+ 
+function TimerNode( scale, scope, useTimeScale ) {
 
-	THREE.FloatNode.call( this );
+	FloatNode.call( this );
 
 	this.scale = scale !== undefined ? scale : 1;
-	this.scope = scope || THREE.TimerNode.GLOBAL;
+	this.scope = scope || TimerNode.GLOBAL;
 
 	this.useTimeScale = useTimeScale !== undefined ? useTimeScale : this.scale !== 1;
 
 };
 
-THREE.TimerNode.GLOBAL = 'global';
-THREE.TimerNode.LOCAL = 'local';
-THREE.TimerNode.DELTA = 'delta';
+TimerNode.GLOBAL = 'global';
+TimerNode.LOCAL = 'local';
+TimerNode.DELTA = 'delta';
 
-THREE.TimerNode.prototype = Object.create( THREE.FloatNode.prototype );
-THREE.TimerNode.prototype.constructor = THREE.TimerNode;
-THREE.TimerNode.prototype.nodeType = "Timer";
+TimerNode.prototype = Object.create( FloatNode.prototype );
+TimerNode.prototype.constructor = TimerNode;
+TimerNode.prototype.nodeType = "Timer";
 
-THREE.TimerNode.prototype.isReadonly = function ( builder ) {
+TimerNode.prototype.isReadonly = function () {
 
 	return false;
 
 };
 
-THREE.TimerNode.prototype.isUnique = function ( builder ) {
+TimerNode.prototype.isUnique = function () {
 
 	// share TimerNode "uniform" input if is used on more time with others TimerNode
-	return this.timeScale && ( this.scope === THREE.TimerNode.GLOBAL || this.scope === THREE.TimerNode.DELTA );
+	return this.timeScale && ( this.scope === TimerNode.GLOBAL || this.scope === TimerNode.DELTA );
 
 };
 
-THREE.TimerNode.prototype.updateFrame = function ( frame ) {
+TimerNode.prototype.updateFrame = function ( frame ) {
 
 	var scale = this.timeScale ? this.scale : 1;
 
 	switch( this.scope ) {
 
-		case THREE.TimerNode.LOCAL:
+		case TimerNode.LOCAL:
 
 			this.value += frame.delta * scale;
 
 			break;
 
-		case THREE.TimerNode.DELTA:
+		case TimerNode.DELTA:
 
 			this.value = frame.delta * scale;
 
@@ -60,9 +63,9 @@ THREE.TimerNode.prototype.updateFrame = function ( frame ) {
 
 };
 
-THREE.TimerNode.prototype.copy = function ( source ) {
+TimerNode.prototype.copy = function ( source ) {
 			
-	THREE.GLNode.prototype.copy.call( this, source );
+	FloatNode.prototype.copy.call( this, source );
 	
 	this.scope = source.scope;
 	this.scale = source.scale;
@@ -71,7 +74,7 @@ THREE.TimerNode.prototype.copy = function ( source ) {
 	
 };
 
-THREE.TimerNode.prototype.toJSON = function ( meta ) {
+TimerNode.prototype.toJSON = function ( meta ) {
 
 	var data = this.getJSONNode( meta );
 
@@ -89,3 +92,11 @@ THREE.TimerNode.prototype.toJSON = function ( meta ) {
 	return data;
 
 };
+
+NodeLib.addKeyword( 'time', function () {
+
+	return new TimerNode();
+
+} );
+
+export { TimerNode };

+ 19 - 13
examples/js/nodes/utils/UVTransformNode.js

@@ -2,29 +2,33 @@
  * @author sunag / http://www.sunag.com.br/
  */
 
-THREE.UVTransformNode = function ( uv, transform ) {
+import { FunctionNode } from '../core/FunctionNode.js';
+import { Matrix3Node } from '../inputs/Matrix3Node.js';
+import { UVNode } from '../accessors/UVNode.js';
+ 
+function UVTransformNode( uv, transform ) {
 
-	THREE.FunctionNode.call( this, "( uvTransform * vec3( uvNode, 1 ) ).xy", "vec2" );
+	FunctionNode.call( this, "( uvTransform * vec3( uvNode, 1 ) ).xy", "vec2" );
 
-	this.uv = uv || new THREE.UVNode();
-	this.transform = transform || new THREE.Matrix3Node();
+	this.uv = uv || new UVNode();
+	this.transform = transform || new Matrix3Node();
 
 };
 
-THREE.UVTransformNode.prototype = Object.create( THREE.FunctionNode.prototype );
-THREE.UVTransformNode.prototype.constructor = THREE.UVTransformNode;
-THREE.UVTransformNode.prototype.nodeType = "UVTransform";
+UVTransformNode.prototype = Object.create( FunctionNode.prototype );
+UVTransformNode.prototype.constructor = UVTransformNode;
+UVTransformNode.prototype.nodeType = "UVTransform";
 
-THREE.UVTransformNode.prototype.generate = function ( builder, output ) {
+UVTransformNode.prototype.generate = function ( builder, output ) {
 
 	this.keywords[ "uvNode" ] = this.uv;
 	this.keywords[ "uvTransform" ] = this.transform;
 
-	return THREE.FunctionNode.prototype.generate.call( this, builder, output );
+	return FunctionNode.prototype.generate.call( this, builder, output );
 
 };
 
-THREE.UVTransformNode.prototype.setUvTransform = function ( tx, ty, sx, sy, rotation, cx, cy ) {
+UVTransformNode.prototype.setUvTransform = function ( tx, ty, sx, sy, rotation, cx, cy ) {
 
 	cx = cx !== undefined ? cx : .5;
 	cy = cy !== undefined ? cy : .5;
@@ -33,16 +37,16 @@ THREE.UVTransformNode.prototype.setUvTransform = function ( tx, ty, sx, sy, rota
 
 };
 
-THREE.UVTransformNode.prototype.copy = function ( source ) {
+UVTransformNode.prototype.copy = function ( source ) {
 			
-	THREE.GLNode.prototype.copy.call( this, source );
+	FunctionNode.prototype.copy.call( this, source );
 	
 	this.uv = source.uv;
 	this.transform = source.transform;
 					
 };
 
-THREE.UVTransformNode.prototype.toJSON = function ( meta ) {
+UVTransformNode.prototype.toJSON = function ( meta ) {
 
 	var data = this.getJSONNode( meta );
 
@@ -58,3 +62,5 @@ THREE.UVTransformNode.prototype.toJSON = function ( meta ) {
 	return data;
 
 };
+
+export { UVTransformNode };

+ 17 - 13
examples/js/nodes/utils/VelocityNode.js

@@ -2,9 +2,11 @@
  * @author sunag / http://www.sunag.com.br/
  */
 
-THREE.VelocityNode = function ( target, params ) {
+import { Vector3Node } from '../inputs/Vector3Node.js';
+ 
+function VelocityNode( target, params ) {
 
-	THREE.Vector3Node.call( this );
+	Vector3Node.call( this );
 
 	this.params = {};
 
@@ -15,17 +17,17 @@ THREE.VelocityNode = function ( target, params ) {
 
 };
 
-THREE.VelocityNode.prototype = Object.create( THREE.Vector3Node.prototype );
-THREE.VelocityNode.prototype.constructor = THREE.VelocityNode;
-THREE.VelocityNode.prototype.nodeType = "Velocity";
+VelocityNode.prototype = Object.create( Vector3Node.prototype );
+VelocityNode.prototype.constructor = VelocityNode;
+VelocityNode.prototype.nodeType = "Velocity";
 
-THREE.VelocityNode.prototype.isReadonly = function ( builder ) {
+VelocityNode.prototype.isReadonly = function ( builder ) {
 
 	return false;
 
 };
 
-THREE.VelocityNode.prototype.setParams = function ( params ) {
+VelocityNode.prototype.setParams = function ( params ) {
 
 	switch ( this.params.type ) {
 
@@ -61,7 +63,7 @@ THREE.VelocityNode.prototype.setParams = function ( params ) {
 
 };
 
-THREE.VelocityNode.prototype.setTarget = function ( target ) {
+VelocityNode.prototype.setTarget = function ( target ) {
 
 	if ( this.target ) {
 
@@ -81,7 +83,7 @@ THREE.VelocityNode.prototype.setTarget = function ( target ) {
 
 };
 
-THREE.VelocityNode.prototype.updateFrameVelocity = function ( frame ) {
+VelocityNode.prototype.updateFrameVelocity = function ( frame ) {
 
 	if ( this.target ) {
 
@@ -93,7 +95,7 @@ THREE.VelocityNode.prototype.updateFrameVelocity = function ( frame ) {
 
 };
 
-THREE.VelocityNode.prototype.updateFrame = function ( frame ) {
+VelocityNode.prototype.updateFrame = function ( frame ) {
 
 	this.updateFrameVelocity( frame );
 
@@ -140,9 +142,9 @@ THREE.VelocityNode.prototype.updateFrame = function ( frame ) {
 
 };
 
-THREE.VelocityNode.prototype.copy = function ( source ) {
+VelocityNode.prototype.copy = function ( source ) {
 			
-	THREE.GLNode.prototype.copy.call( this, source );
+	Vector3Node.prototype.copy.call( this, source );
 	
 	if ( source.target ) object.setTarget( source.target );
 	
@@ -150,7 +152,7 @@ THREE.VelocityNode.prototype.copy = function ( source ) {
 	
 };
 
-THREE.VelocityNode.prototype.toJSON = function ( meta ) {
+VelocityNode.prototype.toJSON = function ( meta ) {
 
 	var data = this.getJSONNode( meta );
 
@@ -168,3 +170,5 @@ THREE.VelocityNode.prototype.toJSON = function ( meta ) {
 	return data;
 
 };
+
+export { VelocityNode };

+ 14 - 92
examples/webgl_materials_nodes.html

@@ -39,91 +39,11 @@
 		<script src='js/geometries/TeapotBufferGeometry.js'></script>
 		<script src="js/controls/OrbitControls.js"></script>
 		<script src="js/libs/dat.gui.min.js"></script>
-
-		<!-- NodeLibrary -->
-		<script src="js/nodes/core/GLNode.js"></script>
-		<script src="js/nodes/core/RawNode.js"></script>
-		<script src="js/nodes/core/BypassNode.js"></script>
-		<script src="js/nodes/core/TempNode.js"></script>
-		<script src="js/nodes/core/InputNode.js"></script>
-		<script src="js/nodes/core/ConstNode.js"></script>
-		<script src="js/nodes/core/VarNode.js"></script>
-		<script src="js/nodes/core/StructNode.js"></script>
-		<script src="js/nodes/core/FunctionNode.js"></script>
-		<script src="js/nodes/core/FunctionCallNode.js"></script>
-		<script src="js/nodes/core/AttributeNode.js"></script>
-		<script src="js/nodes/core/NodeUniform.js"></script>
-		<script src="js/nodes/core/NodeBuilder.js"></script>
-		<script src="js/nodes/core/NodeLib.js"></script>
-		<script src="js/nodes/core/NodeFrame.js"></script>
-		<script src="js/nodes/core/NodeMaterial.js"></script>
-
-		<!-- Library -->
-		<script src="js/nodes/libs/common.js"></script>
-		<script src="js/nodes/libs/keywords.js"></script>
-		
-		<!-- Accessors -->
-		<script src="js/nodes/accessors/PositionNode.js"></script>
-		<script src="js/nodes/accessors/NormalNode.js"></script>
-		<script src="js/nodes/accessors/UVNode.js"></script>
-		<script src="js/nodes/accessors/ScreenUVNode.js"></script>
-		<script src="js/nodes/accessors/ColorsNode.js"></script>
-		<script src="js/nodes/accessors/CameraNode.js"></script>
-		<script src="js/nodes/accessors/ReflectNode.js"></script>
-		<script src="js/nodes/accessors/LightNode.js"></script>
-
-		<!-- Inputs -->
-		<script src="js/nodes/inputs/IntNode.js"></script>
-		<script src="js/nodes/inputs/FloatNode.js"></script>
-		<script src="js/nodes/inputs/ColorNode.js"></script>
-		<script src="js/nodes/inputs/Vector2Node.js"></script>
-		<script src="js/nodes/inputs/Vector3Node.js"></script>
-		<script src="js/nodes/inputs/Vector4Node.js"></script>
-		<script src="js/nodes/inputs/TextureNode.js"></script>
-		<script src="js/nodes/inputs/Matrix3Node.js"></script>
-		<script src="js/nodes/inputs/Matrix4Node.js"></script>
-		<script src="js/nodes/inputs/CubeTextureNode.js"></script>
-		
-		<!-- Math -->
-		<script src="js/nodes/math/Math1Node.js"></script>
-		<script src="js/nodes/math/Math2Node.js"></script>
-		<script src="js/nodes/math/Math3Node.js"></script>
-		<script src="js/nodes/math/OperatorNode.js"></script>
-
-		<!-- Utils -->
-		<script src="js/nodes/utils/SwitchNode.js"></script>
-		<script src="js/nodes/utils/JoinNode.js"></script>
-		<script src="js/nodes/utils/TimerNode.js"></script>
-		<script src="js/nodes/utils/RoughnessToBlinnExponentNode.js"></script>
-		<script src="js/nodes/utils/BlinnShininessExponentNode.js"></script>
-		<script src="js/nodes/utils/VelocityNode.js"></script>
-		<script src="js/nodes/utils/LuminanceNode.js"></script>
-		<script src="js/nodes/utils/ColorAdjustmentNode.js"></script>
-		<script src="js/nodes/utils/NoiseNode.js"></script>
-		<script src="js/nodes/utils/ResolutionNode.js"></script>
-		<script src="js/nodes/utils/BumpMapNode.js"></script>
-		<script src="js/nodes/utils/BlurNode.js"></script>
-		<script src="js/nodes/utils/UVTransformNode.js"></script>
-		<script src="js/nodes/utils/MaxMIPLevelNode.js"></script>
-		<script src="js/nodes/utils/NormalMapNode.js"></script>
-
-		<!-- Phong Material -->
-		<script src="js/nodes/materials/PhongNode.js"></script>
-		<script src="js/nodes/materials/PhongNodeMaterial.js"></script>
-
-		<!-- Standard Material -->
-		<script src="js/nodes/materials/StandardNode.js"></script>
-		<script src="js/nodes/materials/StandardNodeMaterial.js"></script>
-
-		<!-- Extended Materials -->
-		<script src="js/nodes/materials/MeshStandardNode.js"></script>
-		<script src="js/nodes/materials/MeshStandardNodeMaterial.js"></script>
 		
-		<!-- NodeMaterial Loader -->
-		<script src="js/loaders/NodeMaterialLoader.js"></script>
-
-		<script>
+		<script type="module">
 
+		import './js/nodes/THREE.Nodes.js';
+		
 		var container = document.getElementById( 'container' );
 
 		var renderer, scene, camera, clock = new THREE.Clock(), fov = 50;
@@ -548,7 +468,7 @@
 
 					}, false, 0, 1 );
 					
-					addGui( 'sat. (only node)', sataturation.value, function ( val ) {
+					addGui( 'sat. (node)', sataturation.value, function ( val ) {
 
 						sataturation.value = val;
 
@@ -1192,12 +1112,12 @@
 					var sat = new THREE.FloatNode( 0 );
 
 					var satrgb = new THREE.FunctionNode( [
-						"vec3 satrgb(vec3 rgb, float adjustment) {",
-						//"	const vec3 W = vec3(0.2125, 0.7154, 0.0721);", // LUMA
-						"	vec3 intensity = vec3(dot(rgb, LUMA));",
-						"	return mix(intensity, rgb, adjustment);",
+						"vec3 satrgb( vec3 rgb, float adjustment ) {",
+						// include luminance function from LuminanceNode
+						"	vec3 intensity = vec3( luminance( rgb ) );",
+						"	return mix( intensity, rgb, adjustment );",
 						"}"
-					].join( "\n" ) );
+					].join( "\n" ), [ THREE.LuminanceNode.Nodes.luminance ] );
 
 					var saturation = new THREE.FunctionCallNode( satrgb );
 					saturation.inputs.rgb = tex;
@@ -1946,7 +1866,7 @@
 					// APPLY
 
 					mtl.color = color;
-					mtl.light = posCelLight;
+					mtl.light = new THREE.LightNode();
 					mtl.shininess = new THREE.FloatNode( 0 );
 
 					mtl.environment = lineColor;
@@ -2092,11 +2012,13 @@
 					// using BypassNode the NormalNode not apply the value in .transform 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.transform = new THREE.BypassNode( varying );
 					mtl.color = varying;
 					
-					// you can also set a value in .transform slot, such this expression using FunctionNode
-					mtl.transform = new THREE.BypassNode( varying, new THREE.FunctionNode("position * ( .1 + abs( sin( time ) ) )", "vec3") );
+					// you can also set a independent value in .transform slot using BypassNode
+					// such this expression using FunctionNode
+					mtl.transform.value = new THREE.FunctionNode("position * ( .1 + abs( sin( time ) ) )", "vec3");
 
 					break;