Browse Source

temporal blur

sunag 7 years ago
parent
commit
cc6b589501

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

@@ -72,7 +72,7 @@ ReflectNode.prototype.generate = function ( builder, output ) {
 
 
 		}
 		}
 
 
-		return builder.format( result, this.getType( this.type ), output );
+		return builder.format( result, this.getType( builder ), output );
 	
 	
 	} else {
 	} else {
 		
 		

+ 3 - 5
examples/js/nodes/accessors/ResolutionNode.js

@@ -4,12 +4,10 @@
 
 
 import { Vector2Node } from '../inputs/Vector2Node.js';
 import { Vector2Node } from '../inputs/Vector2Node.js';
  
  
-function ResolutionNode( renderer ) {
+function ResolutionNode() {
 
 
 	Vector2Node.call( this );
 	Vector2Node.call( this );
 
 
-	this.renderer = renderer;
-
 };
 };
 
 
 ResolutionNode.prototype = Object.create( Vector2Node.prototype );
 ResolutionNode.prototype = Object.create( Vector2Node.prototype );
@@ -18,8 +16,8 @@ ResolutionNode.prototype.nodeType = "Resolution";
 
 
 ResolutionNode.prototype.updateFrame = function ( frame ) {
 ResolutionNode.prototype.updateFrame = function ( frame ) {
 
 
-	var size = this.renderer.getSize(),
-		pixelRatio = this.renderer.getPixelRatio();
+	var size = frame.renderer.getSize(),
+		pixelRatio = frame.renderer.getPixelRatio();
 
 
 	this.x = size.width * pixelRatio;
 	this.x = size.width * pixelRatio;
 	this.y = size.height * pixelRatio;
 	this.y = size.height * pixelRatio;

+ 2 - 1
examples/js/nodes/accessors/ScreenUVNode.js

@@ -3,12 +3,13 @@
  */
  */
 
 
 import { TempNode } from '../core/TempNode.js';
 import { TempNode } from '../core/TempNode.js';
+import { ResolutionNode } from './ResolutionNode.js';
  
  
 function ScreenUVNode( resolution ) {
 function ScreenUVNode( resolution ) {
 
 
 	TempNode.call( this, 'v2' );
 	TempNode.call( this, 'v2' );
 
 
-	this.resolution = resolution;
+	this.resolution = resolution || new ResolutionNode();
 
 
 };
 };
 
 

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

@@ -6,7 +6,7 @@ function NodeFrame( time ) {
 
 
 	this.time = time !== undefined ? time : 0;
 	this.time = time !== undefined ? time : 0;
 
 
-	this.frameId = 0;
+	this.id = 0;
 
 
 };
 };
 
 
@@ -16,7 +16,7 @@ NodeFrame.prototype = {
 
 
 	update: function ( delta ) {
 	update: function ( delta ) {
 
 
-		++this.frameId;
+		++this.id;
 
 
 		this.time += delta;
 		this.time += delta;
 		this.delta = delta;
 		this.delta = delta;
@@ -35,11 +35,11 @@ NodeFrame.prototype = {
 	
 	
 	updateNode: function ( node ) {
 	updateNode: function ( node ) {
 
 
-		if ( node.frameId === this.frameId ) return this;
+		if ( node.frameId === this.id ) return this;
 
 
 		node.updateFrame( this );
 		node.updateFrame( this );
 
 
-		node.frameId = this.frameId;
+		node.frameId = this.id;
 
 
 		return this;
 		return this;
 
 

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

@@ -35,15 +35,16 @@ TempNode.prototype.build = function ( builder, output, uuid, ns ) {
 
 
 		uuid = builder.getUuid( uuid || this.getUuid(), ! isUnique );
 		uuid = builder.getUuid( uuid || this.getUuid(), ! isUnique );
 
 
-		var data = builder.getNodeData( uuid );
+		var data = builder.getNodeData( uuid ),
+			type = data.output || this.getType( builder );
 
 
 		if ( builder.parsing ) {
 		if ( builder.parsing ) {
 
 
-			if ( data.deps || 0 > 0 ) {
+			if ( ( data.deps || 0 ) > 0 ) {
 
 
 				this.appendDepsNode( builder, data, output );
 				this.appendDepsNode( builder, data, output );
 
 
-				return this.generate( builder, type, uuid );
+				return this.generate( builder, output, uuid );
 
 
 			}
 			}
 
 
@@ -55,7 +56,7 @@ TempNode.prototype.build = function ( builder, output, uuid, ns ) {
 
 
 			return data.name;
 			return data.name;
 
 
-		} else if ( ! builder.optimize || data.deps == 1 ) {
+		} else if ( !this.isShared( builder, type ) || ( ! builder.optimize || data.deps == 1 ) ) {
 
 
 			return Node.prototype.build.call( this, builder, output, uuid );
 			return Node.prototype.build.call( this, builder, output, uuid );
 
 
@@ -63,9 +64,8 @@ TempNode.prototype.build = function ( builder, output, uuid, ns ) {
 
 
 		uuid = this.getUuid( false );
 		uuid = this.getUuid( false );
 
 
-		var name = this.getTemp( builder, uuid ),
-			type = data.output || this.getType( builder );
-
+		var name = this.getTemp( builder, uuid );
+		
 		if ( name ) {
 		if ( name ) {
 
 
 			return builder.format( name, type, output );
 			return builder.format( name, type, output );

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

@@ -40,7 +40,7 @@ BlurNode.Nodes = (function() {
 		"	sum += texture2D( texture, vec2( uv.x + 2.0 * s, uv.y ) ) * 0.12245;",
 		"	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 + 3.0 * s, uv.y ) ) * 0.0918;",
 		"	sum += texture2D( texture, vec2( uv.x + 4.0 * s, uv.y ) ) * 0.051;",
 		"	sum += texture2D( texture, vec2( uv.x + 4.0 * s, uv.y ) ) * 0.051;",
-		"	return sum;",
+		"	return sum * .667;",
 		"}"
 		"}"
 	].join( "\n" ) );
 	].join( "\n" ) );
 	
 	
@@ -56,7 +56,7 @@ BlurNode.Nodes = (function() {
 		"	sum += texture2D( texture, vec2( uv.x, uv.y + 2.0 * s ) ) * 0.12245;",
 		"	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 + 3.0 * s ) ) * 0.0918;",
 		"	sum += texture2D( texture, vec2( uv.x, uv.y + 4.0 * s ) ) * 0.051;",
 		"	sum += texture2D( texture, vec2( uv.x, uv.y + 4.0 * s ) ) * 0.051;",
-		"	return sum;",
+		"	return sum * .667;",
 		"}"
 		"}"
 	].join( "\n" ) );
 	].join( "\n" ) );
 	
 	
@@ -111,7 +111,7 @@ BlurNode.prototype.generate = function ( builder, output ) {
 
 
 		}
 		}
 
 
-		if ( blurCode.length == 2 ) code = '( ' + blurCode.join( ' + ' ) + '/ 2.0 )';
+		if ( blurCode.length == 2 ) code = '( ' + blurCode.join( ' + ' ) + ' / 2.0 )';
 		else if ( blurCode.length ) code = '( ' + blurCode[ 0 ] + ' )';
 		else if ( blurCode.length ) code = '( ' + blurCode[ 0 ] + ' )';
 		else code = 'vec4( 0.0 )';
 		else code = 'vec4( 0.0 )';
 
 

+ 72 - 6
examples/js/nodes/inputs/RTTNode.js

@@ -8,11 +8,13 @@ import { TextureNode } from './TextureNode.js';
 
 
 function RTTNode( width, height, input, options ) {
 function RTTNode( width, height, input, options ) {
 
 
+	options = options || {};
+
 	this.input = input;
 	this.input = input;
 	
 	
-	this.clear = true;
+	this.clear = options.clear !== undefined ? options.clear : true;
 	
 	
-	this.rtt = new THREE.WebGLRenderTarget( width, height, options );
+	this.renderTarget = new THREE.WebGLRenderTarget( width, height, options );
 	
 	
 	this.material = new THREE.NodeMaterial();
 	this.material = new THREE.NodeMaterial();
 	
 	
@@ -23,7 +25,9 @@ function RTTNode( width, height, input, options ) {
 	this.quad.frustumCulled = false; // Avoid getting clipped
 	this.quad.frustumCulled = false; // Avoid getting clipped
 	this.scene.add( this.quad );
 	this.scene.add( this.quad );
 
 
-	TextureNode.call( this, this.rtt.texture );
+	this.render = true;
+	
+	TextureNode.call( this, this.renderTarget.texture );
 
 
 };
 };
 
 
@@ -31,18 +35,56 @@ RTTNode.prototype = Object.create( TextureNode.prototype );
 RTTNode.prototype.constructor = RTTNode;
 RTTNode.prototype.constructor = RTTNode;
 RTTNode.prototype.nodeType = "RTT";
 RTTNode.prototype.nodeType = "RTT";
 
 
-RTTNode.prototype.generate = function ( builder, output ) {
+RTTNode.prototype.build = function ( builder, output, uuid ) {
+	
+	var rttBuilder = new THREE.NodeBuilder();
+	rttBuilder.nodes = builder.nodes;
+	rttBuilder.updaters = builder.updaters;
 	
 	
 	this.material.fragment.value = this.input;
 	this.material.fragment.value = this.input;
+	this.material.build( { builder: rttBuilder } );
 	
 	
-	return TextureNode.prototype.generate.call( this, builder, output );
+	return TextureNode.prototype.build.call( this, builder, output, uuid );
 };
 };
 
 
 RTTNode.prototype.updateFrame = function ( frame ) {
 RTTNode.prototype.updateFrame = function ( frame ) {
 	
 	
 	if ( frame.renderer ) {
 	if ( frame.renderer ) {
 		
 		
-		frame.renderer.render( this.scene, this.camera, this.rtt, this.clear );
+		if (this.render) {
+			
+			frame.renderer.render( this.scene, this.camera, this.renderTarget, this.clear );
+			
+		}
+		
+		if (this.saveToRTT) {
+			
+			this.saveToRTT.render = false;
+			
+			if (this.saveToRTT !== this.saveToRTTCurrent) {
+				
+				if (this.saveToRTTMaterial) this.saveToRTTMaterial.dispose();
+				
+				var material = new THREE.NodeMaterial();
+				material.fragment.value = this;
+				material.build();
+				
+				var scene = new THREE.Scene();
+				
+				var quad = new THREE.Mesh( new THREE.PlaneBufferGeometry( 2, 2 ), material );
+				quad.frustumCulled = false; // Avoid getting clipped
+				scene.add( quad );
+				
+				this.saveToRTTScene = scene;
+				this.saveToRTTMaterial = material;
+				
+			}
+			
+			this.saveToRTTCurrent = this.saveToRTT;
+
+			frame.renderer.render( this.saveToRTTScene, this.camera, this.saveToRTT.renderTarget, this.saveToRTT.clear );
+			
+		}
 		
 		
 	} else {
 	} else {
 		
 		
@@ -52,4 +94,28 @@ RTTNode.prototype.updateFrame = function ( frame ) {
 	
 	
 };
 };
 
 
+RTTNode.prototype.copy = function ( source ) {
+			
+	TextureNode.prototype.copy.call( this, source );
+	
+	this.saveToRTT = source.saveToRTT;
+	
+};
+
+RTTNode.prototype.toJSON = function ( meta ) {
+
+	var data = this.getJSONNode( meta );
+
+	if ( ! data ) {
+		
+		data = THREE.TextureNode.prototype.toJSON.call( this, meta );
+
+		if (this.saveToRTT) data.saveToRTT = this.saveToRTT.toJSON( meta ).uuid;
+
+	}
+
+	return data;
+
+};
+
 export { RTTNode };
 export { RTTNode };

+ 45 - 1
examples/webgl_materials_nodes.html

@@ -186,6 +186,7 @@
 				'adv / wave': 'wave',
 				'adv / wave': 'wave',
 				'adv / triangle-blur': 'triangle-blur',
 				'adv / triangle-blur': 'triangle-blur',
 				'adv / render-to-texture': 'rtt',
 				'adv / render-to-texture': 'rtt',
+				'adv / temporal-blur': 'temporal-blur',
 				'adv / conditional': 'conditional',
 				'adv / conditional': 'conditional',
 				'adv / expression': 'expression',
 				'adv / expression': 'expression',
 				'adv / sss': 'sss',
 				'adv / sss': 'sss',
@@ -2173,6 +2174,49 @@
 					
 					
 					break;
 					break;
 				
 				
+				case 'temporal-blur':
+
+					// MATERIAL
+
+					mtl = new THREE.PhongNodeMaterial();
+
+					var texture = new THREE.TextureNode( getTexture( "brick" ) );
+					
+					var rttStore = new THREE.RTTNode( 512, 512, texture );
+					var blur = new THREE.BlurNode( rttStore );
+					
+					var timer = new THREE.TimerNode( .01, THREE.TimerNode.LOCAL );
+					
+					var color = new THREE.Math3Node(
+						rttStore,
+						blur,
+						new THREE.FloatNode( .6 ),
+						THREE.Math3Node.MIX
+					);
+					
+					blur.horizontal = blur.vertical = timer;
+					
+					var rttSave = new THREE.RTTNode( 512, 512, color );
+					rttSave.saveToRTT = rttStore;
+					
+					mtl.color = rttSave;
+
+					// GUI
+					
+					addGui( 'click to reset', false, function ( val ) {
+
+						// render a single time
+						
+						rttStore.render = true;
+						
+						// reset time blur
+						
+						timer.value = 0;
+
+					} );
+					
+					break;
+				
 				case 'readonly':
 				case 'readonly':
 
 
 					// MATERIAL
 					// MATERIAL
@@ -2353,7 +2397,7 @@
 
 
 					mtl = new THREE.StandardNodeMaterial();
 					mtl = new THREE.StandardNodeMaterial();
 
 
-					var backSideDepth = new THREE.TextureNode( rtTexture.texture, new THREE.ScreenUVNode( new THREE.ResolutionNode( renderer ) ) );
+					var backSideDepth = new THREE.TextureNode( rtTexture.texture, new THREE.ScreenUVNode() );
 
 
 					var difference = new THREE.OperatorNode(
 					var difference = new THREE.OperatorNode(
 						objectDepth,
 						objectDepth,