Browse Source

Merge pull request #13250 from sunag/90dev-root

InputNode readonly option
Mr.doob 7 năm trước cách đây
mục cha
commit
4ef0d67dd7

+ 7 - 0
examples/js/loaders/NodeMaterialLoader.js

@@ -125,8 +125,15 @@ Object.assign( THREE.NodeMaterialLoader.prototype, {
 
 				this.names[ object.name ] = object;
 
+			} else {
+
+				// ignore "uniform" shader input ( for optimization )
+				object.readonly = true;
+
 			}
 
+			if ( node.readonly !== undefined ) object.readonly = node.readonly;
+
 			this.nodes[ uuid ] = object;
 
 		}

+ 28 - 11
examples/js/nodes/InputNode.js

@@ -9,11 +9,19 @@ THREE.InputNode = function ( type, params ) {
 
 	THREE.TempNode.call( this, type, params );
 
+	this.readonly = false;
+
 };
 
 THREE.InputNode.prototype = Object.create( THREE.TempNode.prototype );
 THREE.InputNode.prototype.constructor = THREE.InputNode;
 
+THREE.InputNode.prototype.isReadonly = function ( builder ) {
+
+	return this.readonly;
+
+};
+
 THREE.InputNode.prototype.generate = function ( builder, output, uuid, type, ns, needsUpdate ) {
 
 	var material = builder.material;
@@ -21,27 +29,36 @@ THREE.InputNode.prototype.generate = function ( builder, output, uuid, type, ns,
 	uuid = builder.getUuid( uuid || this.getUuid() );
 	type = type || this.getType( builder );
 
-	var data = material.getDataNode( uuid );
+	var data = material.getDataNode( uuid ),
+		readonly = this.isReadonly( builder ) && this.generateReadonly !== undefined;
 
-	if ( builder.isShader( 'vertex' ) ) {
+	if ( readonly ) {
 
-		if ( ! data.vertex ) {
+		return this.generateReadonly( builder, output, uuid, type, ns, needsUpdate );
 
-			data.vertex = material.createVertexUniform( type, this.value, ns, needsUpdate );
+	} else {
 
-		}
+		if ( builder.isShader( 'vertex' ) ) {
 
-		return builder.format( data.vertex.name, type, output );
+			if ( ! data.vertex ) {
 
-	} else {
+				data.vertex = material.createVertexUniform( type, this.value, ns, needsUpdate );
 
-		if ( ! data.fragment ) {
+			}
 
-			data.fragment = material.createFragmentUniform( type, this.value, ns, needsUpdate );
+			return builder.format( data.vertex.name, type, output );
 
-		}
+		} else {
+
+			if ( ! data.fragment ) {
+
+				data.fragment = material.createFragmentUniform( type, this.value, ns, needsUpdate );
 
-		return builder.format( data.fragment.name, type, output );
+			}
+
+			return builder.format( data.fragment.name, type, output );
+
+		}
 
 	}
 

+ 1 - 1
examples/js/nodes/NodeFrame.js

@@ -21,7 +21,7 @@ THREE.NodeFrame.prototype.update = function ( delta ) {
 
 };
 
-THREE.NodeFrame.prototype.updateFrame = function ( node ) {
+THREE.NodeFrame.prototype.updateNode = function ( node ) {
 
 	if ( node.frameId === this.frameId ) return this;
 

+ 1 - 1
examples/js/nodes/NodeMaterial.js

@@ -72,7 +72,7 @@ THREE.NodeMaterial.prototype.updateFrame = function ( frame ) {
 
 	for ( var i = 0; i < this.updaters.length; ++ i ) {
 
-		frame.updateFrame( this.updaters[ i ] );
+		frame.updateNode( this.updaters[ i ] );
 
 	}
 

+ 8 - 0
examples/js/nodes/inputs/ColorNode.js

@@ -16,6 +16,12 @@ THREE.ColorNode.prototype.nodeType = "Color";
 
 THREE.NodeMaterial.addShortcuts( THREE.ColorNode.prototype, 'value', [ 'r', 'g', 'b' ] );
 
+THREE.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.toJSON = function ( meta ) {
 
 	var data = this.getJSONNode( meta );
@@ -28,6 +34,8 @@ THREE.ColorNode.prototype.toJSON = function ( meta ) {
 		data.g = this.g;
 		data.b = this.b;
 
+		if ( this.readonly === true ) data.readonly = true;
+
 	}
 
 	return data;

+ 10 - 0
examples/js/nodes/inputs/FloatNode.js

@@ -29,6 +29,14 @@ Object.defineProperties( THREE.FloatNode.prototype, {
 	}
 } );
 
+THREE.FloatNode.prototype.generateReadonly = function ( builder, output, uuid, type, ns, needsUpdate ) {
+
+	var value = this.number;
+
+	return builder.format( Math.floor( value ) !== value ? value : value + ".0", type, output );
+
+};
+
 THREE.FloatNode.prototype.toJSON = function ( meta ) {
 
 	var data = this.getJSONNode( meta );
@@ -39,6 +47,8 @@ THREE.FloatNode.prototype.toJSON = function ( meta ) {
 
 		data.number = this.number;
 
+		if ( this.readonly === true ) data.readonly = true;
+
 	}
 
 	return data;

+ 8 - 0
examples/js/nodes/inputs/IntNode.js

@@ -29,6 +29,12 @@ Object.defineProperties( THREE.IntNode.prototype, {
 	}
 } );
 
+THREE.IntNode.prototype.generateReadonly = function ( builder, output, uuid, type, ns, needsUpdate ) {
+
+	return builder.format( this.number, type, output );
+
+};
+
 THREE.IntNode.prototype.toJSON = function ( meta ) {
 
 	var data = this.getJSONNode( meta );
@@ -39,6 +45,8 @@ THREE.IntNode.prototype.toJSON = function ( meta ) {
 
 		data.number = this.number;
 
+		if ( this.readonly === true ) data.readonly = true;
+
 	}
 
 	return data;

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

@@ -14,6 +14,12 @@ THREE.Matrix3Node.prototype = Object.create( THREE.InputNode.prototype );
 THREE.Matrix3Node.prototype.constructor = THREE.Matrix3Node;
 THREE.Matrix3Node.prototype.nodeType = "Matrix3";
 
+THREE.Matrix3Node.prototype.generateReadonly = function ( builder, output, uuid, type, ns, needsUpdate ) {
+
+	return builder.format( "mat3( " + this.value.elements.join( ", " ) + " )", type, output );
+
+};
+
 THREE.Matrix3Node.prototype.toJSON = function ( meta ) {
 
 	var data = this.getJSONNode( meta );
@@ -24,6 +30,8 @@ THREE.Matrix3Node.prototype.toJSON = function ( meta ) {
 
 		data.elements = this.value.elements.concat();
 
+		if ( this.readonly === true ) data.readonly = true;
+
 	}
 
 	return data;

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

@@ -14,6 +14,12 @@ THREE.Matrix4Node.prototype = Object.create( THREE.InputNode.prototype );
 THREE.Matrix4Node.prototype.constructor = THREE.Matrix4Node;
 THREE.Matrix4Node.prototype.nodeType = "Matrix4";
 
+THREE.Matrix4Node.prototype.generateReadonly = function ( builder, output, uuid, type, ns, needsUpdate ) {
+
+	return builder.format( "mat4( " + this.value.elements.join( ", " ) + " )", type, output );
+
+};
+
 THREE.Matrix4Node.prototype.toJSON = function ( meta ) {
 
 	var data = this.getJSONNode( meta );
@@ -24,6 +30,8 @@ THREE.Matrix4Node.prototype.toJSON = function ( meta ) {
 
 		data.elements = this.value.elements.concat();
 
+		if ( this.readonly === true ) data.readonly = true;
+
 	}
 
 	return data;

+ 8 - 0
examples/js/nodes/inputs/Vector2Node.js

@@ -16,6 +16,12 @@ THREE.Vector2Node.prototype.nodeType = "Vector2";
 
 THREE.NodeMaterial.addShortcuts( THREE.Vector2Node.prototype, 'value', [ 'x', 'y' ] );
 
+THREE.Vector2Node.prototype.generateReadonly = function ( builder, output, uuid, type, ns, needsUpdate ) {
+
+	return builder.format( "vec2( " + this.x + ", " + this.y + " )", type, output );
+
+};
+
 THREE.Vector2Node.prototype.toJSON = function ( meta ) {
 
 	var data = this.getJSONNode( meta );
@@ -27,6 +33,8 @@ THREE.Vector2Node.prototype.toJSON = function ( meta ) {
 		data.x = this.x;
 		data.y = this.y;
 
+		if ( this.readonly === true ) data.readonly = true;
+
 	}
 
 	return data;

+ 8 - 0
examples/js/nodes/inputs/Vector3Node.js

@@ -17,6 +17,12 @@ THREE.Vector3Node.prototype.nodeType = "Vector3";
 
 THREE.NodeMaterial.addShortcuts( THREE.Vector3Node.prototype, 'value', [ 'x', 'y', 'z' ] );
 
+THREE.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.toJSON = function ( meta ) {
 
 	var data = this.getJSONNode( meta );
@@ -29,6 +35,8 @@ THREE.Vector3Node.prototype.toJSON = function ( meta ) {
 		data.y = this.y;
 		data.z = this.z;
 
+		if ( this.readonly === true ) data.readonly = true;
+
 	}
 
 	return data;

+ 8 - 0
examples/js/nodes/inputs/Vector4Node.js

@@ -16,6 +16,12 @@ THREE.Vector4Node.prototype.nodeType = "Vector4";
 
 THREE.NodeMaterial.addShortcuts( THREE.Vector4Node.prototype, 'value', [ 'x', 'y', 'z', 'w' ] );
 
+THREE.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.toJSON = function ( meta ) {
 
 	var data = this.getJSONNode( meta );
@@ -29,6 +35,8 @@ THREE.Vector4Node.prototype.toJSON = function ( meta ) {
 		data.z = this.z;
 		data.w = this.w;
 
+		if ( this.readonly === true ) data.readonly = true;
+
 	}
 
 	return data;

+ 23 - 5
examples/js/nodes/utils/TimerNode.js

@@ -2,12 +2,14 @@
  * @author sunag / http://www.sunag.com.br/
  */
 
-THREE.TimerNode = function ( scope, scale ) {
+THREE.TimerNode = function ( scale, scope ) {
 
 	THREE.FloatNode.call( this );
 
-	this.scope = scope || THREE.TimerNode.GLOBAL;
 	this.scale = scale !== undefined ? scale : 1;
+	this.scope = scope || THREE.TimerNode.GLOBAL;
+
+	this.timeScale = this.scale !== 1;
 
 };
 
@@ -19,25 +21,40 @@ THREE.TimerNode.prototype = Object.create( THREE.FloatNode.prototype );
 THREE.TimerNode.prototype.constructor = THREE.TimerNode;
 THREE.TimerNode.prototype.nodeType = "Timer";
 
+THREE.TimerNode.prototype.isReadonly = function ( builder ) {
+
+	return false;
+
+};
+
+THREE.TimerNode.prototype.isUnique = function ( builder ) {
+
+	// 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 );
+
+};
+
 THREE.TimerNode.prototype.updateFrame = function ( frame ) {
 
+	var scale = this.timeScale ? this.scale : 1;
+
 	switch( this.scope ) {
 
 		case THREE.TimerNode.LOCAL:
 
-			this.number += frame.delta * this.scale;
+			this.number += frame.delta * scale;
 
 			break;
 
 		case THREE.TimerNode.DELTA:
 
-			this.number = frame.delta * this.scale;
+			this.number = frame.delta * scale;
 
 			break;
 
 		default:
 
-			this.number = frame.time * this.scale;
+			this.number = frame.time * scale;
 
 	}
 
@@ -53,6 +70,7 @@ THREE.TimerNode.prototype.toJSON = function ( meta ) {
 
 		data.scope = this.scope;
 		data.scale = this.scale;
+		data.timeScale = this.timeScale;
 
 	}
 

+ 6 - 0
examples/js/nodes/utils/VelocityNode.js

@@ -19,6 +19,12 @@ THREE.VelocityNode.prototype = Object.create( THREE.Vector3Node.prototype );
 THREE.VelocityNode.prototype.constructor = THREE.VelocityNode;
 THREE.VelocityNode.prototype.nodeType = "Velocity";
 
+THREE.VelocityNode.prototype.isReadonly = function ( builder ) {
+
+	return false;
+
+};
+
 THREE.VelocityNode.prototype.setParams = function ( params ) {
 
 	switch ( this.params.type ) {

+ 18 - 10
examples/webgl_loader_nodes.html

@@ -224,7 +224,7 @@
 
 		}
 
-		
+
 		function updateMaterial() {
 
 			if ( mesh.material ) mesh.material.dispose();
@@ -234,23 +234,31 @@
 			var url = "nodes/" + param.load + ".json";
 
 			var library = {
-				"cloud" : cloud
+				"cloud": cloud
 			};
 
 			var loader = new THREE.NodeMaterialLoader( undefined, library ).load( url, function () {
 
-				var time = loader.getObjectByName("time");
-			
-				if (time) {
-				
+				var time = loader.getObjectByName( "time" );
+
+				if ( time ) {
+
+					// enable time scale
+
+					time.timeScale = true;
+
+					loader.material.build();
+
+					// gui
+
 					addGui( 'timeScale', time.scale, function ( val ) {
 
 						time.scale = val;
 
-					}, false, -2, 2 );
-				
+					}, false, - 2, 2 );
+
 				}
-			
+
 				// set material
 				mesh.material = loader.material;
 
@@ -274,7 +282,7 @@
 			var delta = clock.getDelta();
 
 			// update material animation and/or gpu calcs (pre-renderer)
-			if ( mesh.material instanceof THREE.NodeMaterial ) frame.update( delta ).updateFrame( mesh.material );
+			if ( mesh.material instanceof THREE.NodeMaterial ) frame.update( delta ).updateNode( mesh.material );
 
 			renderer.render( scene, camera );
 

+ 20 - 1
examples/webgl_materials_nodes.html

@@ -256,6 +256,7 @@
 				'misc / firefly': 'firefly',
 				'misc / reserved-keywords': 'reserved-keywords',
 				'misc / varying': 'varying',
+				'misc / readonly': 'readonly',
 				'misc / custom-attribute': 'custom-attribute'
 			} ).onFinishChange( function () {
 
@@ -2019,6 +2020,24 @@
 
 					break;
 
+				case 'readonly':
+
+					// MATERIAL
+
+					mtl = new THREE.PhongNodeMaterial();
+
+					mtl.color = new THREE.ColorNode( 0xFFFFFF );
+					mtl.specular = new THREE.FloatNode( .5 );
+					mtl.shininess = new THREE.FloatNode( 15 );
+
+					// not use "uniform" input ( for optimization ) 
+					// instead use explicit declaration, for example: 
+					// vec3( 1.0, 1.0, 1.0 ) instead "uniform vec3"
+					// if readonly is true not allow change the value after build the shader material
+					mtl.color.readonly = mtl.specular.readonly = mtl.shininess.readonly = true;
+
+					break;
+
 				case 'triangle-blur':
 
 					// MATERIAL
@@ -2374,7 +2393,7 @@
 			//mesh.rotation.z += .01;
 
 			// update material animation and/or gpu calcs (pre-renderer)
-			frame.update( delta ).updateFrame( mesh.material );
+			frame.update( delta ).updateNode( mesh.material );
 
 			// render to texture for sss/translucent material only
 			if ( rtTexture ) {

+ 1 - 1
examples/webgl_mirror_nodes.html

@@ -327,7 +327,7 @@
 			smallSphere.rotation.y = ( Math.PI / 2 ) - timer * 0.1;
 			smallSphere.rotation.z = timer * 0.8;
 
-			frame.update( delta ).updateFrame( groundMirrorMaterial );
+			frame.update( delta ).updateNode( groundMirrorMaterial );
 
 			render();
 

+ 1 - 1
examples/webgl_postprocessing_nodes.html

@@ -591,7 +591,7 @@
 				object.rotation.x += 0.005;
 				object.rotation.y += 0.01;
 
-				frame.update( delta ).updateFrame( nodepass.node );
+				frame.update( delta ).updateNode( nodepass.node );
 
 				composer.render();
 

+ 4 - 4
examples/webgl_sprites_nodes.html

@@ -215,7 +215,7 @@
 			// horizontal zigzag sprite
 			sprite2.material.transform = new THREE.OperatorNode(
 				new THREE.OperatorNode(
-					new THREE.Math1Node( new THREE.TimerNode( 0, 3 ), THREE.Math1Node.SIN ), // 3 is speed (time scale)
+					new THREE.Math1Node( new THREE.TimerNode( 3 ), THREE.Math1Node.SIN ), // 3 is speed (time scale)
 					new THREE.Vector2Node( .3, 0 ), // horizontal scale (position)
 					THREE.OperatorNode.MUL
 				),
@@ -302,9 +302,9 @@
 
 			// update material animation and/or gpu calcs (pre-renderer)
 			frame.update( delta )
-				.updateFrame( sprite1.material )
-				.updateFrame( sprite2.material )
-				.updateFrame( sprite3.material );
+				.updateNode( sprite1.material )
+				.updateNode( sprite2.material )
+				.updateNode( sprite3.material );
 
 			// rotate sprite
 			sprite3.rotation.z -= Math.PI * .005;