浏览代码

NodeMaterial rev 4 + Post-Processing Nodes

SUNAG 9 年之前
父节点
当前提交
fc173677c7
共有 43 个文件被更改,包括 785 次插入137 次删除
  1. 1 0
      examples/index.html
  2. 0 0
      examples/js/shaders/nodes/BuilderNode.js
  3. 0 0
      examples/js/shaders/nodes/ConstNode.js
  4. 0 0
      examples/js/shaders/nodes/FunctionCallNode.js
  5. 0 0
      examples/js/shaders/nodes/FunctionNode.js
  6. 0 0
      examples/js/shaders/nodes/GLNode.js
  7. 3 3
      examples/js/shaders/nodes/InputNode.js
  8. 0 0
      examples/js/shaders/nodes/LibNode.js
  9. 28 33
      examples/js/shaders/nodes/NodeMaterial.js
  10. 0 0
      examples/js/shaders/nodes/RawNode.js
  11. 13 7
      examples/js/shaders/nodes/TempNode.js
  12. 0 0
      examples/js/shaders/nodes/accessors/CameraNode.js
  13. 0 0
      examples/js/shaders/nodes/accessors/ColorsNode.js
  14. 1 1
      examples/js/shaders/nodes/accessors/NormalNode.js
  15. 6 6
      examples/js/shaders/nodes/accessors/PositionNode.js
  16. 0 0
      examples/js/shaders/nodes/accessors/ReflectNode.js
  17. 0 0
      examples/js/shaders/nodes/accessors/UVNode.js
  18. 0 0
      examples/js/shaders/nodes/inputs/ColorNode.js
  19. 7 1
      examples/js/shaders/nodes/inputs/CubeTextureNode.js
  20. 0 0
      examples/js/shaders/nodes/inputs/FloatNode.js
  21. 0 0
      examples/js/shaders/nodes/inputs/IntNode.js
  22. 24 0
      examples/js/shaders/nodes/inputs/ScreenNode.js
  23. 7 1
      examples/js/shaders/nodes/inputs/TextureNode.js
  24. 0 0
      examples/js/shaders/nodes/inputs/Vector2Node.js
  25. 0 0
      examples/js/shaders/nodes/inputs/Vector3Node.js
  26. 0 0
      examples/js/shaders/nodes/inputs/Vector4Node.js
  27. 2 2
      examples/js/shaders/nodes/materials/PhongNode.js
  28. 0 0
      examples/js/shaders/nodes/materials/PhongNodeMaterial.js
  29. 2 2
      examples/js/shaders/nodes/materials/StandardNode.js
  30. 0 0
      examples/js/shaders/nodes/materials/StandardNodeMaterial.js
  31. 0 0
      examples/js/shaders/nodes/math/Math1Node.js
  32. 0 0
      examples/js/shaders/nodes/math/Math2Node.js
  33. 3 3
      examples/js/shaders/nodes/math/Math3Node.js
  34. 0 0
      examples/js/shaders/nodes/math/OperatorNode.js
  35. 33 0
      examples/js/shaders/nodes/postprocessing/NodePass.js
  36. 0 0
      examples/js/shaders/nodes/utils/JoinNode.js
  37. 43 0
      examples/js/shaders/nodes/utils/NormalMapNode.js
  38. 0 0
      examples/js/shaders/nodes/utils/RoughnessToBlinnExponentNode.js
  39. 1 1
      examples/js/shaders/nodes/utils/SwitchNode.js
  40. 0 0
      examples/js/shaders/nodes/utils/TimeNode.js
  41. 0 0
      examples/js/shaders/nodes/utils/VelocityNode.js
  42. 84 77
      examples/webgl_materials_nodes.html
  43. 527 0
      examples/webgl_postprocessing_nodes.html

+ 1 - 0
examples/index.html

@@ -359,6 +359,7 @@
 				"webgl_postprocessing_dof2",
 				"webgl_postprocessing_dof2",
 				"webgl_postprocessing_glitch",
 				"webgl_postprocessing_glitch",
 				"webgl_postprocessing_godrays",
 				"webgl_postprocessing_godrays",
+				"webgl_postprocessing_nodes",
 				"webgl_postprocessing_ssao",
 				"webgl_postprocessing_ssao",
 				"webgl_raycast_texture",
 				"webgl_raycast_texture",
 				"webgl_read_float_buffer",
 				"webgl_read_float_buffer",

+ 0 - 0
examples/js/materials/nodes/BuilderNode.js → examples/js/shaders/nodes/BuilderNode.js


+ 0 - 0
examples/js/materials/nodes/ConstNode.js → examples/js/shaders/nodes/ConstNode.js


+ 0 - 0
examples/js/materials/nodes/FunctionCallNode.js → examples/js/shaders/nodes/FunctionCallNode.js


+ 0 - 0
examples/js/materials/nodes/FunctionNode.js → examples/js/shaders/nodes/FunctionNode.js


+ 0 - 0
examples/js/materials/nodes/GLNode.js → examples/js/shaders/nodes/GLNode.js


+ 3 - 3
examples/js/materials/nodes/InputNode.js → examples/js/shaders/nodes/InputNode.js

@@ -11,7 +11,7 @@ THREE.InputNode = function( type, params ) {
 THREE.InputNode.prototype = Object.create( THREE.TempNode.prototype );
 THREE.InputNode.prototype = Object.create( THREE.TempNode.prototype );
 THREE.InputNode.prototype.constructor = THREE.InputNode;
 THREE.InputNode.prototype.constructor = THREE.InputNode;
 
 
-THREE.InputNode.prototype.generate = function( builder, output, uuid, type ) {
+THREE.InputNode.prototype.generate = function( builder, output, uuid, type, ns, needsUpdate ) {
 
 
 	var material = builder.material;
 	var material = builder.material;
 
 
@@ -24,7 +24,7 @@ THREE.InputNode.prototype.generate = function( builder, output, uuid, type ) {
 
 
 		if ( ! data.vertex ) {
 		if ( ! data.vertex ) {
 
 
-			data.vertex = material.getVertexUniform( this.value, type );
+			data.vertex = material.getVertexUniform( this.value, type, ns, needsUpdate );
 
 
 		}
 		}
 
 
@@ -35,7 +35,7 @@ THREE.InputNode.prototype.generate = function( builder, output, uuid, type ) {
 
 
 		if ( ! data.fragment ) {
 		if ( ! data.fragment ) {
 
 
-			data.fragment = material.getFragmentUniform( this.value, type );
+			data.fragment = material.getFragmentUniform( this.value, type, ns, needsUpdate );
 
 
 		}
 		}
 
 

+ 0 - 0
examples/js/materials/nodes/LibNode.js → examples/js/shaders/nodes/LibNode.js


+ 28 - 33
examples/js/materials/nodes/NodeMaterial.js → examples/js/shaders/nodes/NodeMaterial.js

@@ -96,11 +96,6 @@ THREE.NodeMaterial.prototype.build = function() {
 		color: []
 		color: []
 	};
 	};
 
 
-	this.needsColor = false;
-	this.needsLight = false;
-	this.needsPosition = false;
-	this.needsTransparent = false;
-
 	this.vertexPars = '';
 	this.vertexPars = '';
 	this.fragmentPars = '';
 	this.fragmentPars = '';
 
 
@@ -189,8 +184,8 @@ THREE.NodeMaterial.prototype.build = function() {
 
 
 	}
 	}
 
 
-	this.lights = this.needsLight;
-	this.transparent = this.needsTransparent;
+	this.lights = this.requestAttrib.light;
+	this.transparent = this.requestAttrib.transparent;
 
 
 	this.vertexShader = [
 	this.vertexShader = [
 		this.vertexPars,
 		this.vertexPars,
@@ -245,15 +240,15 @@ THREE.NodeMaterial.prototype.mergeUniform = function( uniforms ) {
 
 
 };
 };
 
 
-THREE.NodeMaterial.prototype.createUniform = function( value, type, needsUpdate ) {
+THREE.NodeMaterial.prototype.createUniform = function( value, type, ns, needsUpdate ) {
 
 
 	var index = this.uniformList.length;
 	var index = this.uniformList.length;
 
 
 	var uniform = {
 	var uniform = {
 		type : type,
 		type : type,
 		value : value,
 		value : value,
-		needsUpdate : needsUpdate,
-		name : 'nVu' + index
+		name : ns ? ns : 'nVu' + index,
+		needsUpdate : needsUpdate
 	};
 	};
 
 
 	this.uniformList.push( uniform );
 	this.uniformList.push( uniform );
@@ -262,12 +257,12 @@ THREE.NodeMaterial.prototype.createUniform = function( value, type, needsUpdate
 
 
 };
 };
 
 
-THREE.NodeMaterial.prototype.getVertexTemp = function( uuid, type ) {
+THREE.NodeMaterial.prototype.getVertexTemp = function( uuid, type, ns ) {
 
 
 	if ( ! this.vertexTemps[ uuid ] ) {
 	if ( ! this.vertexTemps[ uuid ] ) {
 
 
 		var index = this.vertexTemps.length,
 		var index = this.vertexTemps.length,
-			name = 'nVt' + index,
+			name = ns ? ns : 'nVt' + index,
 			data = { name : name, type : type };
 			data = { name : name, type : type };
 
 
 		this.vertexTemps.push( data );
 		this.vertexTemps.push( data );
@@ -279,6 +274,23 @@ THREE.NodeMaterial.prototype.getVertexTemp = function( uuid, type ) {
 
 
 };
 };
 
 
+THREE.NodeMaterial.prototype.getFragmentTemp = function( uuid, type, ns ) {
+
+	if ( ! this.fragmentTemps[ uuid ] ) {
+
+		var index = this.fragmentTemps.length,
+			name = ns ? ns : 'nVt' + index,
+			data = { name : name, type : type };
+
+		this.fragmentTemps.push( data );
+		this.fragmentTemps[ uuid ] = data;
+
+	}
+
+	return this.fragmentTemps[ uuid ];
+
+};
+
 THREE.NodeMaterial.prototype.getIncludes = function( incs ) {
 THREE.NodeMaterial.prototype.getIncludes = function( incs ) {
 
 
 	function sortByPosition( a, b ) {
 	function sortByPosition( a, b ) {
@@ -306,23 +318,6 @@ THREE.NodeMaterial.prototype.getIncludes = function( incs ) {
 
 
 }();
 }();
 
 
-THREE.NodeMaterial.prototype.getFragmentTemp = function( uuid, type ) {
-
-	if ( ! this.fragmentTemps[ uuid ] ) {
-
-		var index = this.fragmentTemps.length,
-			name = 'nVt' + index,
-			data = { name : name, type : type };
-
-		this.fragmentTemps.push( data );
-		this.fragmentTemps[ uuid ] = data;
-
-	}
-
-	return this.fragmentTemps[ uuid ];
-
-};
-
 THREE.NodeMaterial.prototype.addVertexPars = function( code ) {
 THREE.NodeMaterial.prototype.addVertexPars = function( code ) {
 
 
 	this.vertexPars += code + '\n';
 	this.vertexPars += code + '\n';
@@ -405,9 +400,9 @@ THREE.NodeMaterial.prototype.getCodePars = function( pars, prefix ) {
 
 
 };
 };
 
 
-THREE.NodeMaterial.prototype.getVertexUniform = function( value, type, needsUpdate ) {
+THREE.NodeMaterial.prototype.getVertexUniform = function( value, type, ns, needsUpdate ) {
 
 
-	var uniform = this.createUniform( value, type, needsUpdate );
+	var uniform = this.createUniform( value, type, ns, needsUpdate );
 
 
 	this.vertexUniform.push( uniform );
 	this.vertexUniform.push( uniform );
 	this.vertexUniform[ uniform.name ] = uniform;
 	this.vertexUniform[ uniform.name ] = uniform;
@@ -418,9 +413,9 @@ THREE.NodeMaterial.prototype.getVertexUniform = function( value, type, needsUpda
 
 
 };
 };
 
 
-THREE.NodeMaterial.prototype.getFragmentUniform = function( value, type, needsUpdate ) {
+THREE.NodeMaterial.prototype.getFragmentUniform = function( value, type, ns, needsUpdate ) {
 
 
-	var uniform = this.createUniform( value, type, needsUpdate );
+	var uniform = this.createUniform( value, type, ns, needsUpdate );
 
 
 	this.fragmentUniform.push( uniform );
 	this.fragmentUniform.push( uniform );
 	this.fragmentUniform[ uniform.name ] = uniform;
 	this.fragmentUniform[ uniform.name ] = uniform;

+ 0 - 0
examples/js/materials/nodes/RawNode.js → examples/js/shaders/nodes/RawNode.js


+ 13 - 7
examples/js/materials/nodes/TempNode.js → examples/js/shaders/nodes/TempNode.js

@@ -17,7 +17,7 @@ THREE.TempNode = function( type, params ) {
 THREE.TempNode.prototype = Object.create( THREE.GLNode.prototype );
 THREE.TempNode.prototype = Object.create( THREE.GLNode.prototype );
 THREE.TempNode.prototype.constructor = THREE.TempNode;
 THREE.TempNode.prototype.constructor = THREE.TempNode;
 
 
-THREE.TempNode.prototype.build = function( builder, output, uuid ) {
+THREE.TempNode.prototype.build = function( builder, output, uuid, ns ) {
 
 
 	var material = builder.material;
 	var material = builder.material;
 
 
@@ -31,7 +31,7 @@ THREE.TempNode.prototype.build = function( builder, output, uuid ) {
 
 
 		}
 		}
 
 
-		uuid = builder.getUuid( uuid || this.constructor.uuid || this.uuid, ! isUnique );
+		uuid = builder.getUuid( uuid || this.getUuid(), ! isUnique );
 
 
 		var data = material.getDataNode( uuid );
 		var data = material.getDataNode( uuid );
 
 
@@ -63,7 +63,7 @@ THREE.TempNode.prototype.build = function( builder, output, uuid ) {
 		}
 		}
 		else {
 		else {
 
 
-			name = THREE.TempNode.prototype.generate.call( this, builder, output, uuid, data.output );
+			name = THREE.TempNode.prototype.generate.call( this, builder, output, uuid, data.output, ns );
 
 
 			var code = this.generate( builder, type, uuid );
 			var code = this.generate( builder, type, uuid );
 
 
@@ -77,7 +77,7 @@ THREE.TempNode.prototype.build = function( builder, output, uuid ) {
 	}
 	}
 	else {
 	else {
 
 
-		return builder.format( this.generate( builder, this.getType( builder ), uuid ), type, output );
+		return builder.format( this.generate( builder, this.getType( builder ), uuid ), this.getType( builder ), output );
 
 
 	}
 	}
 
 
@@ -95,6 +95,12 @@ THREE.TempNode.prototype.isUnique = function() {
 
 
 };
 };
 
 
+THREE.TempNode.prototype.getUuid = function() {
+
+	return this.constructor.uuid || this.uuid;
+
+};
+
 THREE.TempNode.prototype.getTemp = function( builder, uuid ) {
 THREE.TempNode.prototype.getTemp = function( builder, uuid ) {
 
 
 	uuid = uuid || this.uuid;
 	uuid = uuid || this.uuid;
@@ -106,13 +112,13 @@ THREE.TempNode.prototype.getTemp = function( builder, uuid ) {
 
 
 };
 };
 
 
-THREE.TempNode.prototype.generate = function( builder, output, uuid, type ) {
+THREE.TempNode.prototype.generate = function( builder, output, uuid, type, ns ) {
 
 
 	if ( ! this.isShared() ) console.error( "THREE.TempNode is not shared!" );
 	if ( ! this.isShared() ) console.error( "THREE.TempNode is not shared!" );
 
 
 	uuid = uuid || this.uuid;
 	uuid = uuid || this.uuid;
 
 
-	if ( builder.isShader( 'vertex' ) ) return builder.material.getVertexTemp( uuid, type || this.getType( builder ) ).name;
-	else return builder.material.getFragmentTemp( uuid, type || this.getType( builder ) ).name;
+	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;
 
 
 };
 };

+ 0 - 0
examples/js/materials/nodes/accessors/CameraNode.js → examples/js/shaders/nodes/accessors/CameraNode.js


+ 0 - 0
examples/js/materials/nodes/accessors/ColorsNode.js → examples/js/shaders/nodes/accessors/ColorsNode.js


+ 1 - 1
examples/js/materials/nodes/accessors/NormalNode.js → examples/js/shaders/nodes/accessors/NormalNode.js

@@ -19,7 +19,7 @@ THREE.NormalNode.VIEW = 'view';
 
 
 THREE.NormalNode.prototype.isShared = function( builder ) {
 THREE.NormalNode.prototype.isShared = function( builder ) {
 
 
-	switch ( this.method ) {
+	switch ( this.scope ) {
 		case THREE.NormalNode.WORLD:
 		case THREE.NormalNode.WORLD:
 			return true;
 			return true;
 	}
 	}

+ 6 - 6
examples/js/materials/nodes/accessors/PositionNode.js → examples/js/shaders/nodes/accessors/PositionNode.js

@@ -20,7 +20,7 @@ THREE.PositionNode.PROJECTION = 'projection';
 
 
 THREE.PositionNode.prototype.getType = function( builder ) {
 THREE.PositionNode.prototype.getType = function( builder ) {
 
 
-	switch ( this.method ) {
+	switch ( this.scope ) {
 		case THREE.PositionNode.PROJECTION:
 		case THREE.PositionNode.PROJECTION:
 			return 'v4';
 			return 'v4';
 	}
 	}
@@ -31,7 +31,7 @@ THREE.PositionNode.prototype.getType = function( builder ) {
 
 
 THREE.PositionNode.prototype.isShared = function( builder ) {
 THREE.PositionNode.prototype.isShared = function( builder ) {
 
 
-	switch ( this.method ) {
+	switch ( this.scope ) {
 		case THREE.PositionNode.LOCAL:
 		case THREE.PositionNode.LOCAL:
 		case THREE.PositionNode.WORLD:
 		case THREE.PositionNode.WORLD:
 			return false;
 			return false;
@@ -55,7 +55,7 @@ THREE.PositionNode.prototype.generate = function( builder, output ) {
 			if ( builder.isShader( 'vertex' ) ) result = 'transformed';
 			if ( builder.isShader( 'vertex' ) ) result = 'transformed';
 			else result = 'vPosition';
 			else result = 'vPosition';
 
 
-			break;
+		break;
 
 
 		case THREE.PositionNode.WORLD:
 		case THREE.PositionNode.WORLD:
 
 
@@ -64,21 +64,21 @@ THREE.PositionNode.prototype.generate = function( builder, output ) {
 			if ( builder.isShader( 'vertex' ) ) result = 'vWPosition';
 			if ( builder.isShader( 'vertex' ) ) result = 'vWPosition';
 			else result = 'vWPosition';
 			else result = 'vWPosition';
 
 
-			break;
+		break;
 
 
 		case THREE.PositionNode.VIEW:
 		case THREE.PositionNode.VIEW:
 
 
 			if ( builder.isShader( 'vertex' ) ) result = '-mvPosition.xyz';
 			if ( builder.isShader( 'vertex' ) ) result = '-mvPosition.xyz';
 			else result = 'vViewPosition';
 			else result = 'vViewPosition';
 
 
-			break;
+		break;
 
 
 		case THREE.PositionNode.PROJECTION:
 		case THREE.PositionNode.PROJECTION:
 
 
 			if ( builder.isShader( 'vertex' ) ) result = '(projectionMatrix * modelViewMatrix * vec4( position, 1.0 ))';
 			if ( builder.isShader( 'vertex' ) ) result = '(projectionMatrix * modelViewMatrix * vec4( position, 1.0 ))';
 			else result = 'vec4( 0.0 )';
 			else result = 'vec4( 0.0 )';
 
 
-			break;
+		break;
 
 
 	}
 	}
 
 

+ 0 - 0
examples/js/materials/nodes/accessors/ReflectNode.js → examples/js/shaders/nodes/accessors/ReflectNode.js


+ 0 - 0
examples/js/materials/nodes/accessors/UVNode.js → examples/js/shaders/nodes/accessors/UVNode.js


+ 0 - 0
examples/js/materials/nodes/inputs/ColorNode.js → examples/js/shaders/nodes/inputs/ColorNode.js


+ 7 - 1
examples/js/materials/nodes/inputs/CubeTextureNode.js → examples/js/shaders/nodes/inputs/CubeTextureNode.js

@@ -15,9 +15,15 @@ THREE.CubeTextureNode = function( value, coord, bias ) {
 THREE.CubeTextureNode.prototype = Object.create( THREE.InputNode.prototype );
 THREE.CubeTextureNode.prototype = Object.create( THREE.InputNode.prototype );
 THREE.CubeTextureNode.prototype.constructor = THREE.CubeTextureNode;
 THREE.CubeTextureNode.prototype.constructor = THREE.CubeTextureNode;
 
 
+THREE.CubeTextureNode.prototype.getTexture = function( builder, output ) {
+
+	return THREE.InputNode.prototype.generate.call( this, builder, output, this.value.uuid, 't' );
+
+};
+
 THREE.CubeTextureNode.prototype.generate = function( builder, output ) {
 THREE.CubeTextureNode.prototype.generate = function( builder, output ) {
 
 
-	var cubetex = THREE.InputNode.prototype.generate.call( this, builder, output, this.value.uuid, 't' );
+	var cubetex = this.getTexture( builder, output );
 	var coord = this.coord.build( builder, 'v3' );
 	var coord = this.coord.build( builder, 'v3' );
 	var bias = this.bias ? this.bias.build( builder, 'fv1' ) : undefined;;
 	var bias = this.bias ? this.bias.build( builder, 'fv1' ) : undefined;;
 
 

+ 0 - 0
examples/js/materials/nodes/inputs/FloatNode.js → examples/js/shaders/nodes/inputs/FloatNode.js


+ 0 - 0
examples/js/materials/nodes/inputs/IntNode.js → examples/js/shaders/nodes/inputs/IntNode.js


+ 24 - 0
examples/js/shaders/nodes/inputs/ScreenNode.js

@@ -0,0 +1,24 @@
+/**
+ * @author sunag / http://www.sunag.com.br/
+ */
+
+THREE.ScreenNode = function( coord ) {
+
+	THREE.TextureNode.call( this, undefined, coord );
+
+};
+
+THREE.ScreenNode.prototype = Object.create( THREE.TextureNode.prototype );
+THREE.ScreenNode.prototype.constructor = THREE.ScreenNode;
+
+THREE.ScreenNode.prototype.isUnique = function() {
+
+	return true;
+
+};
+
+THREE.ScreenNode.prototype.getTexture = function( builder, output ) {
+
+	return THREE.InputNode.prototype.generate.call( this, builder, output, this.getUuid(), 't', 'renderTexture' );
+
+};

+ 7 - 1
examples/js/materials/nodes/inputs/TextureNode.js → examples/js/shaders/nodes/inputs/TextureNode.js

@@ -15,9 +15,15 @@ THREE.TextureNode = function( value, coord, bias ) {
 THREE.TextureNode.prototype = Object.create( THREE.InputNode.prototype );
 THREE.TextureNode.prototype = Object.create( THREE.InputNode.prototype );
 THREE.TextureNode.prototype.constructor = THREE.TextureNode;
 THREE.TextureNode.prototype.constructor = THREE.TextureNode;
 
 
+THREE.TextureNode.prototype.getTexture = function( builder, output ) {
+
+	return THREE.InputNode.prototype.generate.call( this, builder, output, this.value.uuid, 't' );
+
+};
+
 THREE.TextureNode.prototype.generate = function( builder, output ) {
 THREE.TextureNode.prototype.generate = function( builder, output ) {
 
 
-	var tex = THREE.InputNode.prototype.generate.call( this, builder, output, this.value.uuid, 't' );
+	var tex = this.getTexture( builder, output );
 	var coord = this.coord.build( builder, 'v2' );
 	var coord = this.coord.build( builder, 'v2' );
 	var bias = this.bias ? this.bias.build( builder, 'fv1' ) : undefined;
 	var bias = this.bias ? this.bias.build( builder, 'fv1' ) : undefined;
 
 

+ 0 - 0
examples/js/materials/nodes/inputs/Vector2Node.js → examples/js/shaders/nodes/inputs/Vector2Node.js


+ 0 - 0
examples/js/materials/nodes/inputs/Vector3Node.js → examples/js/shaders/nodes/inputs/Vector3Node.js


+ 0 - 0
examples/js/materials/nodes/inputs/Vector4Node.js → examples/js/shaders/nodes/inputs/Vector4Node.js


+ 2 - 2
examples/js/materials/nodes/interfaces/PhongNode.js → examples/js/shaders/nodes/materials/PhongNode.js

@@ -23,7 +23,7 @@ THREE.PhongNode.prototype.build = function( builder ) {
 	material.define( 'PHONG' );
 	material.define( 'PHONG' );
 	material.define( 'ALPHATEST', '0.0' );
 	material.define( 'ALPHATEST', '0.0' );
 
 
-	material.needsLight = true;
+	material.requestAttrib.light = true;
 
 
 	if ( builder.isShader( 'vertex' ) ) {
 	if ( builder.isShader( 'vertex' ) ) {
 
 
@@ -134,7 +134,7 @@ THREE.PhongNode.prototype.build = function( builder ) {
 		var environment = this.environment ? this.environment.buildCode( builder.setCache( 'env' ), 'c' ) : undefined;
 		var environment = this.environment ? this.environment.buildCode( builder.setCache( 'env' ), 'c' ) : undefined;
 		var reflectivity = this.reflectivity && this.environment ? this.reflectivity.buildCode( builder, 'fv1' ) : undefined;
 		var reflectivity = this.reflectivity && this.environment ? this.reflectivity.buildCode( builder, 'fv1' ) : undefined;
 
 
-		material.needsTransparent = alpha != undefined;
+		material.requestAttrib.transparent = alpha != undefined;
 
 
 		material.addFragmentPars( [
 		material.addFragmentPars( [
 			THREE.ShaderChunk[ "common" ],
 			THREE.ShaderChunk[ "common" ],

+ 0 - 0
examples/js/materials/nodes/interfaces/PhongNodeMaterial.js → examples/js/shaders/nodes/materials/PhongNodeMaterial.js


+ 2 - 2
examples/js/materials/nodes/interfaces/StandardNode.js → examples/js/shaders/nodes/materials/StandardNode.js

@@ -23,7 +23,7 @@ THREE.StandardNode.prototype.build = function( builder ) {
 	material.define( 'STANDARD' );
 	material.define( 'STANDARD' );
 	material.define( 'ALPHATEST', '0.0' );
 	material.define( 'ALPHATEST', '0.0' );
 
 
-	material.needsLight = true;
+	material.requestAttrib.light = true;
 
 
 	if ( builder.isShader( 'vertex' ) ) {
 	if ( builder.isShader( 'vertex' ) ) {
 
 
@@ -138,7 +138,7 @@ THREE.StandardNode.prototype.build = function( builder ) {
 		var environment = this.environment ? this.environment.buildCode( builder.setCache( 'env' ), 'c' ) : undefined;
 		var environment = this.environment ? this.environment.buildCode( builder.setCache( 'env' ), 'c' ) : undefined;
 		var reflectivity = this.reflectivity && this.environment ? this.reflectivity.buildCode( builder, 'fv1' ) : undefined;
 		var reflectivity = this.reflectivity && this.environment ? this.reflectivity.buildCode( builder, 'fv1' ) : undefined;
 
 
-		material.needsTransparent = alpha != undefined;
+		material.requestAttrib.transparent = alpha != undefined;
 
 
 		material.addFragmentPars( [
 		material.addFragmentPars( [
 
 

+ 0 - 0
examples/js/materials/nodes/interfaces/StandardNodeMaterial.js → examples/js/shaders/nodes/materials/StandardNodeMaterial.js


+ 0 - 0
examples/js/materials/nodes/math/Math1Node.js → examples/js/shaders/nodes/math/Math1Node.js


+ 0 - 0
examples/js/materials/nodes/math/Math2Node.js → examples/js/shaders/nodes/math/Math2Node.js


+ 3 - 3
examples/js/materials/nodes/math/Math3Node.js → examples/js/shaders/nodes/math/Math3Node.js

@@ -62,20 +62,20 @@ THREE.Math3Node.prototype.generate = function( builder, output ) {
 			a = this.a.build( builder, type );
 			a = this.a.build( builder, type );
 			b = this.b.build( builder, type );
 			b = this.b.build( builder, type );
 			c = this.c.build( builder, 'fv1' );
 			c = this.c.build( builder, 'fv1' );
-			break;
+		break;
 
 
 		case THREE.Math3Node.MIX:
 		case THREE.Math3Node.MIX:
 		case THREE.Math3Node.SMOOTHSTEP:
 		case THREE.Math3Node.SMOOTHSTEP:
 			a = this.a.build( builder, type );
 			a = this.a.build( builder, type );
 			b = this.b.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;
+		break;
 
 
 		default:
 		default:
 			a = this.a.build( builder, type );
 			a = this.a.build( builder, type );
 			b = this.b.build( builder, type );
 			b = this.b.build( builder, type );
 			c = this.c.build( builder, type );
 			c = this.c.build( builder, type );
-			break;
+		break;
 
 
 	}
 	}
 
 

+ 0 - 0
examples/js/materials/nodes/math/OperatorNode.js → examples/js/shaders/nodes/math/OperatorNode.js


+ 33 - 0
examples/js/shaders/nodes/postprocessing/NodePass.js

@@ -0,0 +1,33 @@
+/**
+ * @author sunag / http://www.sunag.com.br/
+ */
+
+THREE.NodePass = function() {
+
+	THREE.ShaderPass.call( this );
+
+	this.fragment = new THREE.RawNode( new THREE.ScreenNode() );
+
+	this.node = new THREE.NodeMaterial();
+	this.node.fragment = this.fragment;
+
+	this.build();
+
+	this.textureID = 'renderTexture';
+
+};
+
+THREE.NodePass.prototype = Object.create( THREE.ShaderPass.prototype );
+THREE.NodePass.prototype.constructor = THREE.NodePass;
+
+THREE.NodePass.prototype.build = function() {
+
+	this.node.build();
+
+	this.uniforms = this.node.uniforms;
+	this.material = this.node;
+
+};
+
+THREE.NodeMaterial.Shortcuts( THREE.NodePass.prototype, 'fragment',
+[ 'value' ] );

+ 0 - 0
examples/js/materials/nodes/utils/JoinNode.js → examples/js/shaders/nodes/utils/JoinNode.js


+ 43 - 0
examples/js/shaders/nodes/utils/NormalMapNode.js

@@ -0,0 +1,43 @@
+/**
+ * @author sunag / http://www.sunag.com.br/
+ */
+
+THREE.NormalMapNode = function( value, uv, scale, normal, position ) {
+
+	THREE.TempNode.call( this, 'v3' );
+
+	this.value = value;
+	this.scale = scale || new THREE.FloatNode( 1 );
+
+	this.normal = normal || new THREE.NormalNode( THREE.NormalNode.LOCAL );
+	this.position = position || new THREE.PositionNode( THREE.NormalNode.VIEW );
+
+};
+
+THREE.NormalMapNode.prototype = Object.create( THREE.TempNode.prototype );
+THREE.NormalMapNode.prototype.constructor = THREE.NormalMapNode;
+
+THREE.NormalMapNode.prototype.generate = function( builder, output ) {
+
+	var material = builder.material;
+
+	builder.include( 'perturbNormal2Arb' );
+
+	if ( builder.isShader( 'fragment' ) ) {
+
+		return builder.format( 'perturbNormal2Arb(-' + this.position.build( builder, 'v3' ) + ',' +
+			this.normal.build( builder, 'v3' ) + ',' +
+			this.value.build( builder, 'v3' ) + ',' +
+			this.value.coord.build( builder, 'v2' ) + ',' +
+			this.scale.build( builder, 'fv1' ) + ')', this.type, output );
+
+	}
+	else {
+
+		console.warn( "THREE.NormalMap is not compatible with " + builder.shader + " shader" );
+
+		return builder.format( 'vec3( 0.0 )', this.type, output );
+
+	}
+
+};

+ 0 - 0
examples/js/materials/nodes/utils/RoughnessToBlinnExponentNode.js → examples/js/shaders/nodes/utils/RoughnessToBlinnExponentNode.js


+ 1 - 1
examples/js/materials/nodes/utils/SwitchNode.js → examples/js/shaders/nodes/utils/SwitchNode.js

@@ -63,6 +63,6 @@ THREE.SwitchNode.prototype.generate = function( builder, output ) {
 
 
 	}
 	}
 
 
-	return builder.format( a, this.type, output );
+	return builder.format( a, this.getType( builder ), output );
 
 
 };
 };

+ 0 - 0
examples/js/materials/nodes/utils/TimeNode.js → examples/js/shaders/nodes/utils/TimeNode.js


+ 0 - 0
examples/js/materials/nodes/extras/VelocityNode.js → examples/js/shaders/nodes/utils/VelocityNode.js


+ 84 - 77
examples/webgl_materials_nodes.html

@@ -34,62 +34,62 @@
 		</div>
 		</div>
 
 
 		<script src="../build/three.min.js"></script>
 		<script src="../build/three.min.js"></script>
-		
+
 		<script src='js/geometries/TeapotBufferGeometry.js'></script>
 		<script src='js/geometries/TeapotBufferGeometry.js'></script>
 		<script src="js/controls/OrbitControls.js"></script>
 		<script src="js/controls/OrbitControls.js"></script>
 		<script src="js/libs/dat.gui.min.js"></script>
 		<script src="js/libs/dat.gui.min.js"></script>
-		
-		<!-- NodeMaterial Base -->
-		<script src="js/materials/nodes/GLNode.js"></script>
-		<script src="js/materials/nodes/RawNode.js"></script>
-		<script src="js/materials/nodes/TempNode.js"></script>
-		<script src="js/materials/nodes/InputNode.js"></script>
-		<script src="js/materials/nodes/ConstNode.js"></script>
-		<script src="js/materials/nodes/FunctionNode.js"></script>
-		<script src="js/materials/nodes/FunctionCallNode.js"></script>
-		<script src="js/materials/nodes/BuilderNode.js"></script>
-		<script src="js/materials/nodes/LibNode.js"></script>
-		<script src="js/materials/nodes/NodeMaterial.js"></script>
-		
+
+		<!-- NodeLibrary -->
+		<script src="js/shaders/nodes/GLNode.js"></script>
+		<script src="js/shaders/nodes/RawNode.js"></script>
+		<script src="js/shaders/nodes/TempNode.js"></script>
+		<script src="js/shaders/nodes/InputNode.js"></script>
+		<script src="js/shaders/nodes/ConstNode.js"></script>
+		<script src="js/shaders/nodes/FunctionNode.js"></script>
+		<script src="js/shaders/nodes/FunctionCallNode.js"></script>
+		<script src="js/shaders/nodes/BuilderNode.js"></script>
+		<script src="js/shaders/nodes/LibNode.js"></script>
+		<script src="js/shaders/nodes/NodeMaterial.js"></script>
+
 		<!-- Accessors -->
 		<!-- Accessors -->
-		<script src="js/materials/nodes/accessors/PositionNode.js"></script>
-		<script src="js/materials/nodes/accessors/NormalNode.js"></script>
-		<script src="js/materials/nodes/accessors/UVNode.js"></script>
-		<script src="js/materials/nodes/accessors/ColorsNode.js"></script>
-		<script src="js/materials/nodes/accessors/CameraNode.js"></script>
-		<script src="js/materials/nodes/accessors/ReflectNode.js"></script>
-		
+		<script src="js/shaders/nodes/accessors/PositionNode.js"></script>
+		<script src="js/shaders/nodes/accessors/NormalNode.js"></script>
+		<script src="js/shaders/nodes/accessors/UVNode.js"></script>
+		<script src="js/shaders/nodes/accessors/ColorsNode.js"></script>
+		<script src="js/shaders/nodes/accessors/CameraNode.js"></script>
+		<script src="js/shaders/nodes/accessors/ReflectNode.js"></script>
+
 		<!-- Inputs -->
 		<!-- Inputs -->
-		<script src="js/materials/nodes/inputs/IntNode.js"></script>
-		<script src="js/materials/nodes/inputs/FloatNode.js"></script>
-		<script src="js/materials/nodes/inputs/ColorNode.js"></script>
-		<script src="js/materials/nodes/inputs/Vector2Node.js"></script>
-		<script src="js/materials/nodes/inputs/Vector3Node.js"></script>
-		<script src="js/materials/nodes/inputs/Vector4Node.js"></script>
-		<script src="js/materials/nodes/inputs/TextureNode.js"></script>
-		<script src="js/materials/nodes/inputs/CubeTextureNode.js"></script>
-		
+		<script src="js/shaders/nodes/inputs/IntNode.js"></script>
+		<script src="js/shaders/nodes/inputs/FloatNode.js"></script>
+		<script src="js/shaders/nodes/inputs/ColorNode.js"></script>
+		<script src="js/shaders/nodes/inputs/Vector2Node.js"></script>
+		<script src="js/shaders/nodes/inputs/Vector3Node.js"></script>
+		<script src="js/shaders/nodes/inputs/Vector4Node.js"></script>
+		<script src="js/shaders/nodes/inputs/TextureNode.js"></script>
+		<script src="js/shaders/nodes/inputs/CubeTextureNode.js"></script>
+
 		<!-- Math -->
 		<!-- Math -->
-		<script src="js/materials/nodes/math/Math1Node.js"></script>
-		<script src="js/materials/nodes/math/Math2Node.js"></script>
-		<script src="js/materials/nodes/math/Math3Node.js"></script>
-		<script src="js/materials/nodes/math/OperatorNode.js"></script>
-		
+		<script src="js/shaders/nodes/math/Math1Node.js"></script>
+		<script src="js/shaders/nodes/math/Math2Node.js"></script>
+		<script src="js/shaders/nodes/math/Math3Node.js"></script>
+		<script src="js/shaders/nodes/math/OperatorNode.js"></script>
+
 		<!-- Utils -->
 		<!-- Utils -->
-		<script src="js/materials/nodes/utils/SwitchNode.js"></script>
-		<script src="js/materials/nodes/utils/JoinNode.js"></script>
-		<script src="js/materials/nodes/utils/TimeNode.js"></script>
-		<script src="js/materials/nodes/utils/RoughnessToBlinnExponentNode.js"></script>
-		
-		<!-- Interfaces -->
-		<script src="js/materials/nodes/interfaces/PhongNode.js"></script>
-		<script src="js/materials/nodes/interfaces/PhongNodeMaterial.js"></script>
-		<script src="js/materials/nodes/interfaces/StandardNode.js"></script>
-		<script src="js/materials/nodes/interfaces/StandardNodeMaterial.js"></script>
-		
-		<!-- Extras -->
-		<script src="js/materials/nodes/extras/VelocityNode.js"></script>
-		
+		<script src="js/shaders/nodes/utils/SwitchNode.js"></script>
+		<script src="js/shaders/nodes/utils/JoinNode.js"></script>
+		<script src="js/shaders/nodes/utils/TimeNode.js"></script>
+		<script src="js/shaders/nodes/utils/RoughnessToBlinnExponentNode.js"></script>
+		<script src="js/shaders/nodes/utils/VelocityNode.js"></script>
+
+		<!-- Phong Material -->
+		<script src="js/shaders/nodes/materials/PhongNode.js"></script>
+		<script src="js/shaders/nodes/materials/PhongNodeMaterial.js"></script>
+
+		<!-- Standard Material -->
+		<script src="js/shaders/nodes/materials/StandardNode.js"></script>
+		<script src="js/shaders/nodes/materials/StandardNodeMaterial.js"></script>
+
 		<script>
 		<script>
 
 
 		var container = document.getElementById( 'container' );
 		var container = document.getElementById( 'container' );
@@ -109,8 +109,6 @@
 		var decalDiffuse = new THREE.TextureLoader().load( 'textures/decal/decal-diffuse.png' );
 		var decalDiffuse = new THREE.TextureLoader().load( 'textures/decal/decal-diffuse.png' );
 		decalDiffuse.wrapS = decalDiffuse.wrapT = THREE.RepeatWrapping;
 		decalDiffuse.wrapS = decalDiffuse.wrapT = THREE.RepeatWrapping;
 
 
-		var decalNormal = new THREE.TextureLoader().load( 'textures/decal/decal-normal.jpg' );
-
 		var cloud = new THREE.TextureLoader().load( 'textures/lava/cloud.png' );
 		var cloud = new THREE.TextureLoader().load( 'textures/lava/cloud.png' );
 		cloud.wrapS = cloud.wrapT = THREE.RepeatWrapping;
 		cloud.wrapS = cloud.wrapT = THREE.RepeatWrapping;
 
 
@@ -221,6 +219,15 @@
 
 
 				} );
 				} );
 
 
+			}
+			else if (typeof value == 'object') {
+
+				node = gui.add( param, name, value ).onChange( function() {
+
+					callback( param[ name ] );
+
+				} );
+
 			}
 			}
 			else {
 			else {
 
 
@@ -251,7 +258,7 @@
 
 
 				case 'phong':
 				case 'phong':
 
 
-					//	MATERIAL
+					// MATERIAL
 
 
 					mtl = new THREE.PhongNodeMaterial();
 					mtl = new THREE.PhongNodeMaterial();
 
 
@@ -283,7 +290,7 @@
 
 
 				case 'standard':
 				case 'standard':
 
 
-					//	MATERIAL
+					// MATERIAL
 
 
 					mtl = new THREE.StandardNodeMaterial();
 					mtl = new THREE.StandardNodeMaterial();
 
 
@@ -380,7 +387,7 @@
 
 
 				case 'wave':
 				case 'wave':
 
 
-					//	MATERIAL
+					// MATERIAL
 
 
 					mtl = new THREE.PhongNodeMaterial();
 					mtl = new THREE.PhongNodeMaterial();
 
 
@@ -448,7 +455,7 @@
 					mtl.color = color;
 					mtl.color = color;
 					mtl.transform = blend;
 					mtl.transform = blend;
 
 
-					//	GUI
+					// GUI
 
 
 					addGui( 'speed', speed.number, function( val ) {
 					addGui( 'speed', speed.number, function( val ) {
 
 
@@ -492,7 +499,7 @@
 
 
 				case 'rim':
 				case 'rim':
 
 
-					//	MATERIAL
+					// MATERIAL
 
 
 					mtl = new THREE.PhongNodeMaterial();
 					mtl = new THREE.PhongNodeMaterial();
 
 
@@ -527,7 +534,7 @@
 					mtl.color = new THREE.ColorNode( 0x111111 );
 					mtl.color = new THREE.ColorNode( 0x111111 );
 					mtl.emissive = rimColor;
 					mtl.emissive = rimColor;
 
 
-					//	GUI
+					// GUI
 
 
 					addGui( 'color', color.value.getHex(), function( val ) {
 					addGui( 'color', color.value.getHex(), function( val ) {
 
 
@@ -578,7 +585,7 @@
 
 
 				case 'fresnel':
 				case 'fresnel':
 
 
-					//	MATERIAL
+					// MATERIAL
 
 
 					mtl = new THREE.PhongNodeMaterial();
 					mtl = new THREE.PhongNodeMaterial();
 
 
@@ -614,7 +621,7 @@
 					mtl.environment = color;
 					mtl.environment = color;
 					mtl.reflectivity = new THREE.Math1Node( fresnel, THREE.Math1Node.SAT );
 					mtl.reflectivity = new THREE.Math1Node( fresnel, THREE.Math1Node.SAT );
 
 
-					//	GUI
+					// GUI
 
 
 					addGui( 'reflectance', reflectance.number, function( val ) {
 					addGui( 'reflectance', reflectance.number, function( val ) {
 
 
@@ -632,7 +639,7 @@
 
 
 				case 'layers':
 				case 'layers':
 
 
-					//	MATERIAL
+					// MATERIAL
 
 
 					mtl = new THREE.PhongNodeMaterial();
 					mtl = new THREE.PhongNodeMaterial();
 
 
@@ -667,7 +674,7 @@
 
 
 					mtl.color = blend;
 					mtl.color = blend;
 
 
-					//	GUI
+					// GUI
 
 
 					addGui( 'offset', offset.number, function( val ) {
 					addGui( 'offset', offset.number, function( val ) {
 
 
@@ -685,7 +692,7 @@
 
 
 				case 'saturation':
 				case 'saturation':
 
 
-					//	MATERIAL
+					// MATERIAL
 
 
 					mtl = new THREE.StandardNodeMaterial();
 					mtl = new THREE.StandardNodeMaterial();
 
 
@@ -712,7 +719,7 @@
 					mtl.color = saturation;
 					mtl.color = saturation;
 					mtl.environment = new THREE.CubeTextureNode( cubemap ); // optional
 					mtl.environment = new THREE.CubeTextureNode( cubemap ); // optional
 
 
-					//	GUI
+					// GUI
 
 
 					addGui( 'saturation', sat.number, function( val ) {
 					addGui( 'saturation', sat.number, function( val ) {
 
 
@@ -724,7 +731,7 @@
 
 
 				case 'top-bottom':
 				case 'top-bottom':
 
 
-					//	MATERIAL
+					// MATERIAL
 
 
 					mtl = new THREE.PhongNodeMaterial();
 					mtl = new THREE.PhongNodeMaterial();
 
 
@@ -755,7 +762,7 @@
 
 
 					mtl.color = blend;
 					mtl.color = blend;
 
 
-					//	GUI
+					// GUI
 
 
 					addGui( 'hard', hard.number, function( val ) {
 					addGui( 'hard', hard.number, function( val ) {
 
 
@@ -773,7 +780,7 @@
 
 
 				case 'displace':
 				case 'displace':
 
 
-					//	MATERIAL
+					// MATERIAL
 
 
 					mtl = new THREE.PhongNodeMaterial();
 					mtl = new THREE.PhongNodeMaterial();
 
 
@@ -829,7 +836,7 @@
 					mtl.emissive = color;
 					mtl.emissive = color;
 					mtl.transform = blend;
 					mtl.transform = blend;
 
 
-					//	GUI
+					// GUI
 
 
 					addGui( 'speed', speed.number, function( val ) {
 					addGui( 'speed', speed.number, function( val ) {
 
 
@@ -859,7 +866,7 @@
 
 
 				case 'smoke':
 				case 'smoke':
 
 
-					//	MATERIAL
+					// MATERIAL
 
 
 					mtl = new THREE.PhongNodeMaterial();
 					mtl = new THREE.PhongNodeMaterial();
 
 
@@ -902,7 +909,7 @@
 					mtl.environment = new THREE.ColorNode( 0xFFFFFF );
 					mtl.environment = new THREE.ColorNode( 0xFFFFFF );
 					mtl.alpha = clouds;
 					mtl.alpha = clouds;
 
 
-					//	GUI
+					// GUI
 
 
 					addGui( 'color', mtl.environment.value.getHex(), function( val ) {
 					addGui( 'color', mtl.environment.value.getHex(), function( val ) {
 
 
@@ -914,7 +921,7 @@
 
 
 				case 'camera-depth':
 				case 'camera-depth':
 
 
-					//	MATERIAL
+					// MATERIAL
 
 
 					var colorA = new THREE.ColorNode( 0xFFFFFF );
 					var colorA = new THREE.ColorNode( 0xFFFFFF );
 					var colorB = new THREE.ColorNode( 0x0054df );
 					var colorB = new THREE.ColorNode( 0x0054df );
@@ -933,7 +940,7 @@
 					mtl = new THREE.PhongNodeMaterial();
 					mtl = new THREE.PhongNodeMaterial();
 					mtl.color = colors;
 					mtl.color = colors;
 
 
-					//	GUI
+					// GUI
 
 
 					addGui( 'near', depth.near.number, function( val ) {
 					addGui( 'near', depth.near.number, function( val ) {
 
 
@@ -963,7 +970,7 @@
 
 
 				case 'caustic':
 				case 'caustic':
 
 
-					//	MATERIAL
+					// MATERIAL
 
 
 					mtl = new THREE.StandardNodeMaterial();
 					mtl = new THREE.StandardNodeMaterial();
 
 
@@ -1083,7 +1090,7 @@
 					mtl.color = caustic;
 					mtl.color = caustic;
 					mtl.ambient = causticLights;
 					mtl.ambient = causticLights;
 
 
-					//	GUI
+					// GUI
 
 
 					addGui( 'timeScale', timeScale.number, function( val ) {
 					addGui( 'timeScale', timeScale.number, function( val ) {
 
 
@@ -1131,7 +1138,7 @@
 
 
 				case 'soft-body':
 				case 'soft-body':
 
 
-					//	MATERIAL
+					// MATERIAL
 
 
 					move = true;
 					move = true;
 
 
@@ -1180,7 +1187,7 @@
 					mtl.color = colors;
 					mtl.color = colors;
 					mtl.transform = softPosition;
 					mtl.transform = softPosition;
 
 
-					//	GUI
+					// GUI
 
 
 					addGui( 'spring', velocity.params.spring, function( val ) {
 					addGui( 'spring', velocity.params.spring, function( val ) {
 
 
@@ -1216,7 +1223,7 @@
 
 
 				case 'firefly':
 				case 'firefly':
 
 
-					//	MATERIAL
+					// MATERIAL
 
 
 					mtl = new THREE.PhongNodeMaterial();
 					mtl = new THREE.PhongNodeMaterial();
 
 
@@ -1250,7 +1257,7 @@
 					mtl.color = new THREE.ColorNode( 0 );
 					mtl.color = new THREE.ColorNode( 0 );
 					mtl.emissive = cos;
 					mtl.emissive = cos;
 
 
-					//	GUI
+					// GUI
 
 
 					addGui( 'speed', speed.number, function( val ) {
 					addGui( 'speed', speed.number, function( val ) {
 
 

+ 527 - 0
examples/webgl_postprocessing_nodes.html

@@ -0,0 +1,527 @@
+<!DOCTYPE html>
+<html lang="en">
+	<head>
+		<title>three.js webgl - postprocessing</title>
+		<meta charset="utf-8">
+		<style>
+			body {
+				margin: 0px;
+				background-color: #000;
+				overflow: hidden;
+				font-family:Monospace;
+				font-size:13px;
+				margin: 0px;
+				text-align:center;
+				overflow: hidden;
+			}
+			
+			#info {
+				color: #fff;
+				position: absolute;
+				top: 10px;
+				width: 100%;
+				text-align: center;
+				display:block;
+			}
+		</style>
+	</head>
+	<body>
+		<div id="info">
+			<a href="http://threejs.org" target="_blank">three.js</a> - Node-Based Post-Processing
+		</div>
+	
+		<script src="../build/three.min.js"></script>
+		<script src="js/libs/dat.gui.min.js"></script>
+
+		<script src="js/shaders/CopyShader.js"></script>
+
+		<script src="js/postprocessing/EffectComposer.js"></script>
+		<script src="js/postprocessing/RenderPass.js"></script>
+		<script src="js/postprocessing/MaskPass.js"></script>
+		<script src="js/postprocessing/ShaderPass.js"></script>
+
+		<!-- NodeLibrary -->
+		<script src="js/shaders/nodes/GLNode.js"></script>
+		<script src="js/shaders/nodes/RawNode.js"></script>
+		<script src="js/shaders/nodes/TempNode.js"></script>
+		<script src="js/shaders/nodes/InputNode.js"></script>
+		<script src="js/shaders/nodes/ConstNode.js"></script>
+		<script src="js/shaders/nodes/FunctionNode.js"></script>
+		<script src="js/shaders/nodes/FunctionCallNode.js"></script>
+		<script src="js/shaders/nodes/BuilderNode.js"></script>
+		<script src="js/shaders/nodes/LibNode.js"></script>
+		<script src="js/shaders/nodes/NodeMaterial.js"></script>
+
+		<!-- Accessors -->
+		<script src="js/shaders/nodes/accessors/PositionNode.js"></script>
+		<script src="js/shaders/nodes/accessors/NormalNode.js"></script>
+		<script src="js/shaders/nodes/accessors/UVNode.js"></script>
+		<script src="js/shaders/nodes/accessors/ColorsNode.js"></script>
+
+		<!-- Inputs -->
+		<script src="js/shaders/nodes/inputs/IntNode.js"></script>
+		<script src="js/shaders/nodes/inputs/FloatNode.js"></script>
+		<script src="js/shaders/nodes/inputs/ColorNode.js"></script>
+		<script src="js/shaders/nodes/inputs/Vector2Node.js"></script>
+		<script src="js/shaders/nodes/inputs/Vector3Node.js"></script>
+		<script src="js/shaders/nodes/inputs/Vector4Node.js"></script>
+		<script src="js/shaders/nodes/inputs/TextureNode.js"></script>
+		<script src="js/shaders/nodes/inputs/CubeTextureNode.js"></script>
+		<script src="js/shaders/nodes/inputs/ScreenNode.js"></script>
+
+		<!-- Math -->
+		<script src="js/shaders/nodes/math/Math1Node.js"></script>
+		<script src="js/shaders/nodes/math/Math2Node.js"></script>
+		<script src="js/shaders/nodes/math/Math3Node.js"></script>
+		<script src="js/shaders/nodes/math/OperatorNode.js"></script>
+
+		<!-- Utils -->
+		<script src="js/shaders/nodes/utils/SwitchNode.js"></script>
+		<script src="js/shaders/nodes/utils/JoinNode.js"></script>
+		<script src="js/shaders/nodes/utils/TimeNode.js"></script>
+		<script src="js/shaders/nodes/utils/NormalMapNode.js"></script>
+
+		<!-- Post-Processing -->
+		<script src="js/shaders/nodes/postprocessing/NodePass.js"></script>
+
+		<script>
+
+			var camera, scene, renderer, composer;
+			var object, light, nodepass;
+			var gui, guiElements = [];
+
+			var param = { example: 'brightness' };
+
+			var lensflare2 = new THREE.TextureLoader().load( 'textures/lensflare2.jpg' );
+			lensflare2.wrapS = lensflare2.wrapT = THREE.RepeatWrapping;
+
+			var decalNormal = new THREE.TextureLoader().load( 'textures/decal/decal-normal.jpg' );
+			decalNormal.wrapS = decalNormal.wrapT = THREE.RepeatWrapping;
+
+			init();
+			animate();
+
+			function clearGui() {
+
+				if ( gui ) gui.destroy();
+
+				gui = new dat.GUI();
+
+				var example = gui.add( param, 'example', {
+					'basic / Brightness': 'brightness',
+					'basic / Blends': 'blends',
+					'basic / Fade': 'fade',
+					'basic / Invert': 'invert',
+					'adv / Saturation': 'saturation',
+					'adv / Mosaic': 'mosaic',
+				} ).onFinishChange( function() {
+
+					updateMaterial();
+
+				} );
+
+				gui.open();
+
+			}
+
+			function addGui( name, value, callback, isColor, min, max ) {
+
+				var node;
+
+				param[ name ] = value;
+
+				if ( isColor ) {
+
+					node = gui.addColor( param, name ).onChange( function() {
+
+						callback( param[ name ] );
+
+					} );
+
+				}
+				else if ( typeof value == 'object' ) {
+
+					node = gui.add( param, name, value ).onChange( function() {
+
+						callback( param[ name ] );
+
+					} );
+
+				}
+				else {
+
+					node = gui.add( param, name, min, max ).onChange( function() {
+
+						callback( param[ name ] );
+
+					} );
+
+				}
+
+				return node;
+
+			}
+
+			function updateMaterial() {
+
+				var name = param.example;
+
+				clearGui();
+
+				switch ( name ) {
+
+					case 'brightness':
+
+						var screen = new THREE.ScreenNode();
+
+						var brightness = new THREE.FloatNode( - 1 );
+						var contrast = new THREE.FloatNode( 3 );
+
+						var contrastResult = new THREE.OperatorNode(
+							screen,
+							contrast,
+							THREE.OperatorNode.MUL
+						);
+
+						var brightnessResult = new THREE.OperatorNode(
+							contrastResult,
+							brightness,
+							THREE.OperatorNode.ADD
+						);
+
+						nodepass.value = brightnessResult;
+
+						// GUI
+
+						addGui( 'brightness', brightness.number, function( val ) {
+
+							brightness.number = val;
+
+						}, false, - 1, 2 );
+
+						addGui( 'contrast', contrast.number, function( val ) {
+
+							contrast.number = val;
+
+						}, false, 0, 4 );
+
+					break;
+
+					case 'fade':
+
+						// PASS
+
+						var color = new THREE.ColorNode( 0xFFFFFF );
+						var percent = new THREE.FloatNode( .5 );
+
+						var fade = new THREE.Math3Node(
+							new THREE.ScreenNode(),
+							color,
+							percent,
+							THREE.Math3Node.MIX
+						);
+
+						nodepass.value = fade;
+
+						// GUI
+
+						addGui( 'color', color.value.getHex(), function( val ) {
+
+							color.value.setHex( val );
+
+						}, true );
+
+						addGui( 'fade', percent.number, function( val ) {
+
+							percent.number = val;
+
+						}, false, 0, 1 );
+
+					break;
+
+					case 'invert':
+
+						// PASS
+
+						var alpha = new THREE.FloatNode( 1 );
+
+						var screen = new THREE.ScreenNode();
+						var inverted = new THREE.Math1Node( screen, THREE.Math1Node.INVERT );
+
+						var fade = new THREE.Math3Node(
+							screen,
+							inverted,
+							alpha,
+							THREE.Math3Node.MIX
+						);
+
+						nodepass.value = fade;
+
+						// GUI
+
+						addGui( 'alpha', alpha.number, function( val ) {
+
+							alpha.number = val;
+
+						}, false, 0, 1 );
+
+					break;
+
+					case 'blends':
+
+						// PASS
+
+						var multiply = new THREE.OperatorNode(
+							new THREE.ScreenNode(),
+							new THREE.TextureNode( lensflare2 ),
+							THREE.OperatorNode.ADD
+						);
+
+						nodepass.value = multiply;
+
+						// GUI
+
+						addGui( 'blend', {
+							'addition' : THREE.OperatorNode.ADD,
+							'subtract' : THREE.OperatorNode.SUB,
+							'multiply' : THREE.OperatorNode.MUL,
+							'division' : THREE.OperatorNode.DIV
+						}, function( val ) {
+
+							multiply.op = val;
+
+							nodepass.build();
+
+						} );
+
+					break;
+
+					case 'saturation':
+
+						// PASS
+
+						var screen = new THREE.ScreenNode();
+						var sat = new THREE.FloatNode( 0 );
+
+						var satrgb = new THREE.FunctionNode( [
+						"vec3 satrgb(vec3 rgb, float adjustment) {",
+							//"const vec3 W = vec3(0.2125, 0.7154, 0.0721);", // LUMA
+							"vec3 intensity = vec3(dot(rgb, LUMA));",
+							"return mix(intensity, rgb, adjustment);",
+						"}"
+						].join( "\n" ) );
+
+						var saturation = new THREE.FunctionCallNode( satrgb );
+						saturation.input.rgb = screen;
+						saturation.input.adjustment = sat;
+
+						nodepass.value = saturation;
+
+						// GUI
+
+						addGui( 'saturation', sat.number, function( val ) {
+
+							sat.number = val;
+
+						}, false, 0, 2 );
+
+					break;
+
+					case 'refraction':
+
+						// PASS
+
+						var normal = new THREE.TextureNode( decalNormal );
+						var normalY = new THREE.SwitchNode( normal, 'y' );
+
+						var offsetNormal = new THREE.OperatorNode(
+							normalY,
+							new THREE.FloatNode( .5 ),
+							THREE.OperatorNode.ADD
+						);
+
+						var scale = new THREE.FloatNode( .5 );
+
+						var scaleNormal = new THREE.Math3Node(
+							new THREE.FloatNode( 1 ),
+							offsetNormal,
+							scale,
+							THREE.Math3Node.MIX
+						);
+
+						var offsetCoord = new THREE.OperatorNode(
+							new THREE.UVNode(),
+							scaleNormal,
+							THREE.OperatorNode.MUL
+						);
+
+						var screen = new THREE.ScreenNode( offsetCoord );
+
+						nodepass.value = screen;
+
+						// GUI
+
+						addGui( 'scale', scale.number, function( val ) {
+
+							scale.number = val;
+
+						}, false, 0, 1 );
+
+					break;
+
+					case 'mosaic':
+
+						// PASS
+
+						var scale = new THREE.FloatNode( 128 );
+						var fade = new THREE.FloatNode( 1 );
+						var uv = new THREE.UVNode();
+						var tex = new THREE.TextureNode( lensflare2 );
+
+						var mask = new THREE.Math1Node( new THREE.SwitchNode( tex, 'x' ), THREE.Math1Node.INVERT );
+
+						var blocks = new THREE.OperatorNode(
+							uv,
+							scale,
+							THREE.OperatorNode.MUL
+						);
+
+						var blocksSize = new THREE.Math1Node(
+							blocks,
+							THREE.Math1Node.FLOOR
+						);
+
+						var coord = new THREE.OperatorNode(
+							blocksSize,
+							scale,
+							THREE.OperatorNode.DIV
+						);
+
+						var maskAlpha = new THREE.OperatorNode(
+							mask,
+							fade,
+							THREE.OperatorNode.MUL
+						);
+
+						var fadeCoord = new THREE.Math3Node(
+							uv,
+							coord,
+							maskAlpha,
+							THREE.Math3Node.MIX
+						);
+
+						var screen = new THREE.ScreenNode( fadeCoord );
+
+						nodepass.value = screen;
+
+						// GUI
+
+						addGui( 'scale', scale.number, function( val ) {
+
+							scale.number = val;
+
+						}, false, 16, 1024 );
+
+						addGui( 'fade', fade.number, function( val ) {
+
+							fade.number = val;
+
+						}, false, 0, 1 );
+
+						addGui( 'mask', true, function( val ) {
+
+							fadeCoord.c = val ? maskAlpha : fade;
+
+							nodepass.build();
+
+						}, false, 0, 1 );
+
+					break;
+
+				}
+
+				nodepass.build();
+
+			}
+
+			function init() {
+
+				renderer = new THREE.WebGLRenderer();
+				renderer.setPixelRatio( window.devicePixelRatio );
+				renderer.setSize( window.innerWidth, window.innerHeight );
+				document.body.appendChild( renderer.domElement );
+
+				//
+
+				camera = new THREE.PerspectiveCamera( 70, window.innerWidth / window.innerHeight, 1, 1000 );
+				camera.position.z = 400;
+
+				scene = new THREE.Scene();
+				scene.fog = new THREE.Fog( 0x0066FF, 1, 1000 );
+
+				object = new THREE.Object3D();
+				scene.add( object );
+
+				var geometry = new THREE.SphereGeometry( 1, 4, 4 );
+
+				for ( var i = 0; i < 100; i ++ ) {
+
+					var material = new THREE.MeshPhongMaterial( { color: 0x888888 + ( Math.random() * 0x888888 ), shading: THREE.FlatShading } );
+					var mesh = new THREE.Mesh( geometry, material );
+					mesh.position.set( Math.random() - 0.5, Math.random() - 0.5, Math.random() - 0.5 ).normalize();
+					mesh.position.multiplyScalar( Math.random() * 400 );
+					mesh.rotation.set( Math.random() * 2, Math.random() * 2, Math.random() * 2 );
+					mesh.scale.x = mesh.scale.y = mesh.scale.z = 10 + ( Math.random() * 40 );
+					object.add( mesh );
+
+				}
+
+				scene.add( new THREE.AmbientLight( 0x999999 ) );
+
+				light = new THREE.DirectionalLight( 0xffffff );
+				light.position.set( 1, 1, 1 );
+				scene.add( light );
+
+				// postprocessing
+
+				composer = new THREE.EffectComposer( renderer );
+				composer.addPass( new THREE.RenderPass( scene, camera ) );
+
+				nodepass = new THREE.NodePass();
+				nodepass.renderToScreen = true;
+
+				composer.addPass( nodepass );
+
+				//
+
+				updateMaterial();
+
+				window.addEventListener( 'resize', onWindowResize, false );
+
+			}
+
+			function onWindowResize() {
+
+				camera.aspect = window.innerWidth / window.innerHeight;
+				camera.updateProjectionMatrix();
+
+				renderer.setSize( window.innerWidth, window.innerHeight );
+				composer.setSize( window.innerWidth, window.innerHeight );
+
+			}
+
+			function animate() {
+
+				requestAnimationFrame( animate );
+
+				object.rotation.x += 0.005;
+				object.rotation.y += 0.01;
+
+				composer.render();
+
+			}
+
+		</script>
+
+	</body>
+</html>