Browse Source

Merge pull request #9918 from takahirox/ChainableEffect

Chain-able OutlineEffect
Mr.doob 8 years ago
parent
commit
9984ce8caa

+ 78 - 7
examples/js/effects/OutlineEffect.js

@@ -26,11 +26,9 @@
 
 THREE.OutlineEffect = function ( renderer, parameters ) {
 
-	var _this = this;
-
 	parameters = parameters || {};
 
-	this.autoClear = parameters.autoClear !== undefined ? parameters.autoClear : true;
+	this.enabled = true;
 
 	var defaultThickness = parameters.defaultThickness !== undefined ? parameters.defaultThickness : 0.003;
 	var defaultColor = parameters.defaultColor !== undefined ? parameters.defaultColor : new THREE.Color( 0x000000 );
@@ -427,13 +425,14 @@ THREE.OutlineEffect = function ( renderer, parameters ) {
 
 	}
 
-	this.setSize = function ( width, height ) {
+	this.render = function ( scene, camera, renderTarget, forceClear ) {
 
-		renderer.setSize( width, height );
+		if ( this.enabled === false ) {
 
-	};
+			renderer.render( scene, camera, renderTarget, forceClear );
+			return;
 
-	this.render = function ( scene, camera, renderTarget, forceClear ) {
+		}
 
 		var currentAutoClear = renderer.autoClear;
 		renderer.autoClear = this.autoClear;
@@ -466,4 +465,76 @@ THREE.OutlineEffect = function ( renderer, parameters ) {
 
 	};
 
+	/*
+	 * See #9918
+	 *
+	 * The following property copies and wrapper methods enable
+	 * THREE.OutlineEffect to be called from other *Effect, like
+	 *
+	 * effect = new THREE.VREffect( new THREE.OutlineEffect( renderer ) );
+	 *
+	 * function render () {
+	 *
+ 	 * 	effect.render( scene, camera );
+	 *
+	 * }
+	 */
+	this.autoClear = renderer.autoClear;
+	this.domElement = renderer.domElement;
+	this.shadowMap = renderer.shadowMap;
+
+	this.clear = function ( color, depth, stencil ) {
+
+		renderer.clear( color, depth, stencil );
+
+	};
+
+	this.getPixelRatio = function () {
+
+		return renderer.getPixelRatio();
+
+	};
+
+	this.setPixelRatio = function ( value ) {
+
+		renderer.setPixelRatio( value );
+
+	};
+
+	this.getSize = function () {
+
+		return renderer.getSize();
+
+	};
+
+	this.setSize = function ( width, height, updateStyle ) {
+
+		renderer.setSize( width, height, updateStyle );
+
+	};
+
+	this.setViewport = function ( x, y, width, height ) {
+
+		renderer.setViewport( x, y, width, height );
+
+	};
+
+	this.setScissor = function ( x, y, width, height ) {
+
+		renderer.setScissor( x, y, width, height );
+
+	};
+
+	this.setScissorTest = function ( boolean ) {
+
+		renderer.setScissorTest( boolean );
+
+	};
+
+	this.setRenderTarget = function ( renderTarget ) {
+
+		renderer.setRenderTarget( renderTarget );
+
+	};
+
 };

+ 3 - 170
examples/js/loaders/MMDLoader.js

@@ -1293,6 +1293,7 @@ THREE.MMDLoader.prototype.createMesh = function ( model, texturePath, onProgress
 
 				}
 
+				// parameters for OutlineEffect
 				m.outlineParameters = {
 					thickness: p2.edgeFlag === 1 ? 0.003 : 0.0,
 					color: new THREE.Color( 0.0, 0.0, 0.0 ),
@@ -1307,6 +1308,7 @@ THREE.MMDLoader.prototype.createMesh = function ( model, texturePath, onProgress
 
 			} else {
 
+				// parameters for OutlineEffect
 				m.outlineParameters = {
 					thickness: p2.edgeSize / 300,
 					color: new THREE.Color( p2.edgeColor[ 0 ], p2.edgeColor[ 1 ], p2.edgeColor[ 2 ] ),
@@ -2131,15 +2133,7 @@ THREE.MMDGrantSolver.prototype = {
 
 };
 
-THREE.MMDHelper = function ( renderer ) {
-
-	this.renderer = renderer;
-
-	this.outlineEffect = null;
-
-	this.effect = null;
-
-	this.autoClear = true;
+THREE.MMDHelper = function () {
 
 	this.meshes = [];
 
@@ -2147,7 +2141,6 @@ THREE.MMDHelper = function ( renderer ) {
 	this.doIk = true;
 	this.doGrant = true;
 	this.doPhysics = true;
-	this.doOutlineDrawing = true;
 	this.doCameraAnimation = true;
 
 	this.sharedPhysics = false;
@@ -2156,23 +2149,12 @@ THREE.MMDHelper = function ( renderer ) {
 	this.audioManager = null;
 	this.camera = null;
 
-	this.init();
-
 };
 
 THREE.MMDHelper.prototype = {
 
 	constructor: THREE.MMDHelper,
 
-	init: function () {
-
-		this.outlineEffect = new THREE.OutlineEffect( this.renderer );
-
-		var size = this.renderer.getSize();
-		this.setSize( size.width, size.height );
-
-	},
-
 	add: function ( mesh ) {
 
 		if ( ! ( mesh instanceof THREE.SkinnedMesh ) ) {
@@ -2194,23 +2176,6 @@ THREE.MMDHelper.prototype = {
 
 	},
 
-	setSize: function ( width, height ) {
-
-		this.outlineEffect.setSize( width, height );
-
-	},
-
-	/*
-	 * Note: There may be a possibility that Outline wouldn't work well with Effect.
-	 *       In such a case, try to set doOutlineDrawing = false or
-	 *       manually comment out renderer.clear() in *Effect.render().
-	 */
-	setEffect: function ( effect ) {
-
-		this.effect = effect;
-
-	},
-
 	setAudio: function ( audio, listener, params ) {
 
 		this.audioManager = new THREE.MMDAudioManager( audio, listener, params );
@@ -2661,138 +2626,6 @@ THREE.MMDHelper.prototype = {
 
 	},
 
-	render: function ( scene, camera ) {
-
-		if ( this.effect === null ) {
-
-			if ( this.doOutlineDrawing ) {
-
-				this.outlineEffect.autoClear = this.autoClear;
-				this.outlineEffect.render( scene, camera );
-
-			} else {
-
-				var currentAutoClear = this.renderer.autoClear;
-				this.renderer.autoClear = this.autoClear;
-				this.renderer.render( scene, camera );
-				this.renderer.autoClear = currentAutoClear;
-
-			}
-
-		} else {
-
-			var currentAutoClear = this.renderer.autoClear;
-			this.renderer.autoClear = this.autoClear;
-
-			if ( this.doOutlineDrawing ) {
-
-				this.renderWithEffectAndOutline( scene, camera );
-
-			} else {
-
-				this.effect.render( scene, camera );
-
-			}
-
-			this.renderer.autoClear = currentAutoClear;
-
-		}
-
-	},
-
-	/*
-	 * Currently(r82 dev) there's no way to render with two Effects
-	 * then attempt to get them to coordinately run by myself.
-	 *
-	 * What this method does
-	 * 1. let OutlineEffect make outline materials (only once)
-	 * 2. render normally with effect
-	 * 3. set outline materials
-	 * 4. render outline with effect
-	 * 5. restore original materials
-	 */
-	renderWithEffectAndOutline: function ( scene, camera ) {
-
-		var hasOutlineMaterial = false;
-
-		function checkIfObjectHasOutlineMaterial ( object ) {
-
-			if ( object.material === undefined ) return;
-
-			if ( object.userData.outlineMaterial !== undefined ) hasOutlineMaterial = true;
-
-		}
-
-		function setOutlineMaterial ( object ) {
-
-			if ( object.material === undefined ) return;
-
-			if ( object.userData.outlineMaterial === undefined ) return;
-
-			object.userData.originalMaterial = object.material;
-
-			object.material = object.userData.outlineMaterial;
-
-		}
-
-		function restoreOriginalMaterial ( object ) {
-
-			if ( object.material === undefined ) return;
-
-			if ( object.userData.originalMaterial === undefined ) return;
-
-			object.material = object.userData.originalMaterial;
-
-		}
-
-		return function renderWithEffectAndOutline( scene, camera ) {
-
-			hasOutlineMaterial = false;
-
-			var forceClear = false;
-
-			scene.traverse( checkIfObjectHasOutlineMaterial );
-
-			if ( ! hasOutlineMaterial ) {
-
-				this.outlineEffect.render( scene, camera );
-
-				forceClear = true;
-
-				scene.traverse( checkIfObjectHasOutlineMaterial );
-
-			}
-
-			if ( hasOutlineMaterial ) {
-
-				this.renderer.autoClear = this.autoClear || forceClear;
-
-				this.effect.render( scene, camera );
-
-				scene.traverse( setOutlineMaterial );
-
-				var currentShadowMapEnabled = this.renderer.shadowMap.enabled;
-
-				this.renderer.autoClear = false;
-				this.renderer.shadowMap.enabled = false;
-
-				this.effect.render( scene, camera );
-
-				this.renderer.shadowMap.enabled = currentShadowMapEnabled;
-
-				scene.traverse( restoreOriginalMaterial );
-
-			} else {
-
-				this.outlineEffect.autoClear = this.autoClear || forceClear;
-				this.outlineEffect.render( scene, camera );
-
-			}
-
-		}
-
-	}(),
-
 	poseAsVpd: function ( mesh, vpd, params ) {
 
 		if ( params === undefined ) params = {};

+ 10 - 16
examples/webgl_loader_mmd.html

@@ -54,7 +54,7 @@
 
 			var container, stats;
 
-			var mesh, camera, scene, renderer;
+			var mesh, camera, scene, renderer, effect;
 			var helper, ikHelper, physicsHelper;
 
 			var mouseX = 0, mouseY = 0;
@@ -98,6 +98,8 @@
 				renderer.setClearColor( new THREE.Color( 0xffffff ) );
 				container.appendChild( renderer.domElement );
 
+				effect = new THREE.OutlineEffect( renderer );
+
 				// STATS
 
 				stats = new Stats();
@@ -118,7 +120,7 @@
 				var modelFile = 'models/mmd/miku/miku_v2.pmd';
 				var vmdFiles = [ 'models/mmd/vmds/wavefile_v2.vmd' ];
 
-				helper = new THREE.MMDHelper( renderer );
+				helper = new THREE.MMDHelper();
 
 				var loader = new THREE.MMDLoader();
 
@@ -219,7 +221,7 @@
 					} );
 
 					gui.add( api, 'outline' ).onChange( function () {
-						helper.doOutlineDrawing = api[ 'outline' ];
+						effect.enabled = api[ 'outline' ];
 					} );
 
 					gui.add( api, 'physics' ).onChange( function () {
@@ -246,7 +248,7 @@
 				camera.aspect = window.innerWidth / window.innerHeight;
 				camera.updateProjectionMatrix();
 
-				helper.setSize( window.innerWidth, window.innerHeight );
+				effect.setSize( window.innerWidth, window.innerHeight );
 
 			}
 
@@ -264,18 +266,10 @@
 
 			function render() {
 
-				if ( mesh ) {
-
-					helper.animate( clock.getDelta() );
-					if ( physicsHelper.visible ) physicsHelper.update();
-					if ( ikHelper.visible ) ikHelper.update();
-					helper.render( scene, camera );
-
-				} else {
-
-					renderer.render( scene, camera );
-
-				}
+				helper.animate( clock.getDelta() );
+				if ( physicsHelper !== undefined && physicsHelper.visible ) physicsHelper.update();
+				if ( ikHelper !== undefined && ikHelper.visible ) ikHelper.update();
+				effect.render( scene, camera );
 
 			}
 

+ 8 - 10
examples/webgl_loader_mmd_audio.html

@@ -53,7 +53,7 @@
 
 			var container, stats;
 
-			var mesh, camera, scene, renderer;
+			var mesh, camera, scene, renderer, effect;
 			var helper;
 
 			var ready = false;
@@ -96,6 +96,8 @@
 				renderer.setClearColor( new THREE.Color( 0xffffff ) );
 				container.appendChild( renderer.domElement );
 
+				effect = new THREE.OutlineEffect( renderer );
+
 				// model
 
 				var onProgress = function ( xhr ) {
@@ -114,7 +116,7 @@
 				var audioFile = 'models/mmd/audios/wavefile_short.mp3';
 				var audioParams = { delayTime: 160 * 1 / 30 };
 
-				helper = new THREE.MMDHelper( renderer );
+				helper = new THREE.MMDHelper();
 
 				var loader = new THREE.MMDLoader();
 
@@ -173,7 +175,7 @@
 				camera.aspect = window.innerWidth / window.innerHeight;
 				camera.updateProjectionMatrix();
 
-				helper.setSize( window.innerWidth, window.innerHeight );
+				effect.setSize( window.innerWidth, window.innerHeight );
 
 			}
 
@@ -197,16 +199,12 @@
 
 				if ( ready ) {
 
-					var delta = clock.getDelta();
-					helper.animate( delta );
-					helper.render( scene, camera );
-
-				} else {
-
-					renderer.render( scene, camera );
+					helper.animate( clock.getDelta() );
 
 				}
 
+				effect.render( scene, camera );
+
 			}
 
 		</script>

+ 6 - 14
examples/webgl_loader_mmd_pose.html

@@ -52,7 +52,7 @@
 
 			var container, stats;
 
-			var camera, scene, renderer;
+			var camera, scene, renderer, effect;
 			var helper;
 
 			var vpds = [];
@@ -96,6 +96,8 @@
 				renderer.setClearColor( new THREE.Color( 0xffffff ) );
 				container.appendChild( renderer.domElement );
 
+				effect = new THREE.OutlineEffect( renderer );
+
 				// model
 
 				var onProgress = function ( xhr ) {
@@ -123,7 +125,7 @@
 					'models/mmd/vpds/11.vpd'
 				];
 
-				helper = new THREE.MMDHelper( renderer );
+				helper = new THREE.MMDHelper();
 
 				var loader = new THREE.MMDLoader();
 
@@ -133,8 +135,6 @@
 
 					mesh.position.y = -10;
 
-					helper.add( mesh );
-
 					scene.add( mesh );
 
 					var vpdIndex = 0;
@@ -294,7 +294,7 @@
 				camera.aspect = window.innerWidth / window.innerHeight;
 				camera.updateProjectionMatrix();
 
-				helper.setSize( window.innerWidth, window.innerHeight );
+				effect.setSize( window.innerWidth, window.innerHeight );
 
 			}
 
@@ -321,15 +321,7 @@
 
 				camera.lookAt( scene.position );
 */
-				if ( ready ) {
-
-					helper.render( scene, camera );
-
-				} else {
-
-					renderer.render( scene, camera );
-
-				}
+				effect.render( scene, camera );
 
 			}