Browse Source

Merge branch 'texture_encoding' of [email protected]:bhouston/three.js.git into texture_encoding

Ben Houston 9 years ago
parent
commit
c1aa769353

+ 1 - 1
README.md

@@ -61,7 +61,7 @@ This code creates a scene, a camera, and a geometric cube, and it adds the cube
 
 
 </script>
 </script>
 ```
 ```
-If everything went well you should see [this](http://jsfiddle.net/f17Lz5ux/).
+If everything went well you should see [this](http://jsfiddle.net/hfj7gm6t/).
 
 
 ### Change log ###
 ### Change log ###
 
 

+ 1 - 1
docs/api/extras/geometries/TubeGeometry.html

@@ -51,7 +51,7 @@ var geometry = new THREE.TubeGeometry(
 		segments — [page:Integer] - The number of segments that make up the tube, default is 64<br />
 		segments — [page:Integer] - The number of segments that make up the tube, default is 64<br />
 		radius — [page:Float] - The radius of the tube, default is 1<br />
 		radius — [page:Float] - The radius of the tube, default is 1<br />
 		radiusSegments — [page:Integer] - The number of segments that make up the cross-section, default is 8 <br />
 		radiusSegments — [page:Integer] - The number of segments that make up the cross-section, default is 8 <br />
-		closed — [page:Float] Is the tube open or closed, default is false <br />
+		closed — [page:Boolean] Is the tube open or closed, default is false <br />
 		</div>
 		</div>
 
 
 
 

+ 5 - 0
docs/api/textures/Texture.html

@@ -128,6 +128,11 @@
 		False by default, which is the norm for PNG images. Set to true if the RGB values have been stored premultiplied by alpha.
 		False by default, which is the norm for PNG images. Set to true if the RGB values have been stored premultiplied by alpha.
 		</div>
 		</div>
 
 
+		<h3>[property:number encoding]</h3>
+		<div>
+		Set to THREE.LinearEncoding by default, but supports sRGB, RGBE, RGBM, RGBD, LogLuv and Gamma corrected encodings.  IMPORTANT: If this value is changed on a texture after the material has been used, it is necessary to trigger a Material.needsUpdate for this value to be realized in the shader.
+		</div>
+
 		<h3>[property:object onUpdate]</h3>
 		<h3>[property:object onUpdate]</h3>
 		<div>
 		<div>
 		A callback function, called when the texture is updated (e.g., when needsUpdate has been set to true and then the texture is used).
 		A callback function, called when the texture is updated (e.g., when needsUpdate has been set to true and then the texture is used).

+ 1 - 0
examples/files.js

@@ -181,6 +181,7 @@ var files = {
 		"webgl_postprocessing_nodes",
 		"webgl_postprocessing_nodes",
 		"webgl_postprocessing_smaa",
 		"webgl_postprocessing_smaa",
 		"webgl_postprocessing_ssao",
 		"webgl_postprocessing_ssao",
+		"webgl_postprocessing_taa",
 		"webgl_raycast_texture",
 		"webgl_raycast_texture",
 		"webgl_read_float_buffer",
 		"webgl_read_float_buffer",
 		"webgl_rtt",
 		"webgl_rtt",

+ 1 - 4
examples/index.html

@@ -276,10 +276,7 @@
 		button.textContent = 'View source';
 		button.textContent = 'View source';
 		button.addEventListener( 'click', function ( event ) {
 		button.addEventListener( 'click', function ( event ) {
 
 
-			var array = location.href.split( '/' );
-			array.pop();
-
-			window.open( 'view-source:' + array.join( '/' ) + '/' + selected + '.html' );
+			window.open( 'https://github.com/mrdoob/three.js/blob/master/examples/' + selected + '.html' );
 
 
 		}, false );
 		}, false );
 		button.style.display = 'none';
 		button.style.display = 'none';

+ 5 - 3
examples/js/effects/AnaglyphEffect.js

@@ -71,11 +71,13 @@ THREE.AnaglyphEffect = function ( renderer, width, height ) {
 
 
 	this.setSize = function ( width, height ) {
 	this.setSize = function ( width, height ) {
 
 
-		_renderTargetL.setSize( width, height );
-		_renderTargetR.setSize( width, height );
-
 		renderer.setSize( width, height );
 		renderer.setSize( width, height );
 
 
+		var pixelRatio = renderer.getPixelRatio();
+
+		_renderTargetL.setSize( width * pixelRatio, height * pixelRatio );
+		_renderTargetR.setSize( width * pixelRatio, height * pixelRatio );
+
 	};
 	};
 
 
 	this.render = function ( scene, camera ) {
 	this.render = function ( scene, camera ) {

+ 4 - 2
examples/js/effects/CardboardEffect.js

@@ -70,10 +70,12 @@ THREE.CardboardEffect = function ( renderer ) {
 
 
 	this.setSize = function ( width, height ) {
 	this.setSize = function ( width, height ) {
 
 
-		_renderTarget.setSize( width, height );
-
 		renderer.setSize( width, height );
 		renderer.setSize( width, height );
 
 
+		var pixelRatio = renderer.getPixelRatio();
+
+		_renderTarget.setSize( width * pixelRatio, height * pixelRatio );
+
 	};
 	};
 
 
 	this.render = function ( scene, camera ) {
 	this.render = function ( scene, camera ) {

+ 5 - 3
examples/js/effects/ParallaxBarrierEffect.js

@@ -70,11 +70,13 @@ THREE.ParallaxBarrierEffect = function ( renderer ) {
 
 
 	this.setSize = function ( width, height ) {
 	this.setSize = function ( width, height ) {
 
 
-		_renderTargetL.setSize( width, height );
-		_renderTargetR.setSize( width, height );
-
 		renderer.setSize( width, height );
 		renderer.setSize( width, height );
 
 
+		var pixelRatio = renderer.getPixelRatio();
+
+		_renderTargetL.setSize( width * pixelRatio, height * pixelRatio );
+		_renderTargetR.setSize( width * pixelRatio, height * pixelRatio );
+
 	};
 	};
 
 
 	this.render = function ( scene, camera ) {
 	this.render = function ( scene, camera ) {

+ 7 - 7
examples/js/loaders/VRMLLoader.js

@@ -582,7 +582,7 @@ THREE.VRMLLoader.prototype = {
 
 
 					if ( /USE/.exec( data ) ) {
 					if ( /USE/.exec( data ) ) {
 
 
-						var defineKey = /USE\s+?(\w+)/.exec( data )[ 1 ];
+						var defineKey = /USE\s+?([^\s]+)/.exec( data )[ 1 ];
 
 
 						if ( undefined == defines[ defineKey ] ) {
 						if ( undefined == defines[ defineKey ] ) {
 
 
@@ -629,7 +629,7 @@ THREE.VRMLLoader.prototype = {
 
 
 					if ( /DEF/.exec( data.string ) ) {
 					if ( /DEF/.exec( data.string ) ) {
 
 
-						object.name = /DEF\s+(\w+)/.exec( data.string )[ 1 ];
+						object.name = /DEF\s+([^\s]+)/.exec( data.string )[ 1 ];
 						defines[ object.name ] = object;
 						defines[ object.name ] = object;
 
 
 					}
 					}
@@ -666,7 +666,7 @@ THREE.VRMLLoader.prototype = {
 
 
 					if ( /DEF/.exec( data.string ) ) {
 					if ( /DEF/.exec( data.string ) ) {
 
 
-						object.name = /DEF\s+(\w+)/.exec( data.string )[ 1 ];
+						object.name = /DEF\s+([^\s]+)/.exec( data.string )[ 1 ];
 
 
 						defines[ object.name ] = object;
 						defines[ object.name ] = object;
 
 
@@ -772,7 +772,7 @@ THREE.VRMLLoader.prototype = {
 
 
 								if ( child.string.indexOf ( 'DEF' ) > -1 ) {
 								if ( child.string.indexOf ( 'DEF' ) > -1 ) {
 
 
-									var name = /DEF\s+(\w+)/.exec( child.string )[ 1 ];
+									var name = /DEF\s+([^\s]+)/.exec( child.string )[ 1 ];
 
 
 									defines[ name ] = geometry.vertices;
 									defines[ name ] = geometry.vertices;
 
 
@@ -780,7 +780,7 @@ THREE.VRMLLoader.prototype = {
 
 
 								if ( child.string.indexOf ( 'USE' ) > -1 ) {
 								if ( child.string.indexOf ( 'USE' ) > -1 ) {
 
 
-									var defineKey = /USE\s+(\w+)/.exec( child.string )[ 1 ];
+									var defineKey = /USE\s+([^\s]+)/.exec( child.string )[ 1 ];
 
 
 									geometry.vertices = defines[ defineKey ];
 									geometry.vertices = defines[ defineKey ];
 								}
 								}
@@ -862,7 +862,7 @@ THREE.VRMLLoader.prototype = {
 						// see if it's a define
 						// see if it's a define
 						if ( /DEF/.exec( data.string ) ) {
 						if ( /DEF/.exec( data.string ) ) {
 
 
-							geometry.name = /DEF (\w+)/.exec( data.string )[ 1 ];
+							geometry.name = /DEF ([^\s]+)/.exec( data.string )[ 1 ];
 							defines[ geometry.name ] = geometry;
 							defines[ geometry.name ] = geometry;
 
 
 						}
 						}
@@ -920,7 +920,7 @@ THREE.VRMLLoader.prototype = {
 
 
 							if ( /DEF/.exec( data.string ) ) {
 							if ( /DEF/.exec( data.string ) ) {
 
 
-								material.name = /DEF (\w+)/.exec( data.string )[ 1 ];
+								material.name = /DEF ([^\s]+)/.exec( data.string )[ 1 ];
 
 
 								defines[ material.name ] = material;
 								defines[ material.name ] = material;
 
 

+ 0 - 1
examples/js/modifiers/ExplodeModifier.js

@@ -38,6 +38,5 @@ THREE.ExplodeModifier.prototype.modify = function ( geometry ) {
 	}
 	}
 
 
 	geometry.vertices = vertices;
 	geometry.vertices = vertices;
-	delete geometry.__tmpVertices;
 
 
 };
 };

+ 0 - 2
examples/js/modifiers/SubdivisionModifier.js

@@ -31,8 +31,6 @@ THREE.SubdivisionModifier.prototype.modify = function ( geometry ) {
 
 
 	}
 	}
 
 
-	delete geometry.__tmpVertices;
-
 	geometry.computeFaceNormals();
 	geometry.computeFaceNormals();
 	geometry.computeVertexNormals();
 	geometry.computeVertexNormals();
 
 

+ 30 - 8
examples/js/postprocessing/ManualMSAARenderPass.js

@@ -1,6 +1,14 @@
 /**
 /**
- * @author bhouston / http://clara.io/ *
- */
+*
+* Manual Multi-Sample Anti-Aliasing Render Pass
+*
+* @author bhouston / http://clara.io/
+*
+* This manual approach to MSAA re-renders the scene ones for each sample with camera jitter and accumulates the results.
+*
+* References: https://en.wikipedia.org/wiki/Multisample_anti-aliasing
+*
+*/
 
 
 THREE.ManualMSAARenderPass = function ( scene, camera, params ) {
 THREE.ManualMSAARenderPass = function ( scene, camera, params ) {
 
 
@@ -18,22 +26,24 @@ THREE.ManualMSAARenderPass = function ( scene, camera, params ) {
 
 
 	if ( THREE.CompositeShader === undefined ) {
 	if ( THREE.CompositeShader === undefined ) {
 
 
-		console.error( "THREE.MSAAPass relies on THREE.CompositeShader" );
+		console.error( "THREE.ManualMSAARenderPass relies on THREE.CompositeShader" );
 
 
 	}
 	}
 
 
 	var compositeShader = THREE.CompositeShader;
 	var compositeShader = THREE.CompositeShader;
-	this.uniforms = THREE.UniformsUtils.clone( compositeShader.uniforms );
+	this.compositeUniforms = THREE.UniformsUtils.clone( compositeShader.uniforms );
 
 
 	this.materialComposite = new THREE.ShaderMaterial(	{
 	this.materialComposite = new THREE.ShaderMaterial(	{
 
 
-		uniforms: this.uniforms,
+		uniforms: this.compositeUniforms,
 		vertexShader: compositeShader.vertexShader,
 		vertexShader: compositeShader.vertexShader,
 		fragmentShader: compositeShader.fragmentShader,
 		fragmentShader: compositeShader.fragmentShader,
 		transparent: true,
 		transparent: true,
 		blending: THREE.CustomBlending,
 		blending: THREE.CustomBlending,
 		blendSrc: THREE.OneFactor,
 		blendSrc: THREE.OneFactor,
 		blendDst: THREE.OneFactor,
 		blendDst: THREE.OneFactor,
+		blendSrcAlpha: THREE.OneFactor,
+		blendDstAlpha: THREE.OneFactor,
 		blendEquation: THREE.AddEquation,
 		blendEquation: THREE.AddEquation,
 		depthTest: false,
 		depthTest: false,
 		depthWrite: false
 		depthWrite: false
@@ -49,6 +59,8 @@ THREE.ManualMSAARenderPass = function ( scene, camera, params ) {
 
 
 THREE.ManualMSAARenderPass.prototype = {
 THREE.ManualMSAARenderPass.prototype = {
 
 
+	constructor: THREE.ManualMSAARenderPass,
+
 	dispose: function() {
 	dispose: function() {
 
 
 		if ( this.sampleRenderTarget ) {
 		if ( this.sampleRenderTarget ) {
@@ -70,7 +82,7 @@ THREE.ManualMSAARenderPass.prototype = {
 	render: function ( renderer, writeBuffer, readBuffer, delta ) {
 	render: function ( renderer, writeBuffer, readBuffer, delta ) {
 
 
 		var camera = ( this.camera || this.scene.camera );
 		var camera = ( this.camera || this.scene.camera );
-		var jitterOffsets = THREE.ManualMSAARenderPass.JitterVectors[ Math.max( 0, Math.min( this.sampleLevel, 4 ) ) ];
+		var jitterOffsets = THREE.ManualMSAARenderPass.JitterVectors[ Math.max( 0, Math.min( this.sampleLevel, 5 ) ) ];
 
 
 		if( jitterOffsets.length === 1 ) {
 		if( jitterOffsets.length === 1 ) {
 
 
@@ -88,8 +100,8 @@ THREE.ManualMSAARenderPass.prototype = {
 		var autoClear = renderer.autoClear;
 		var autoClear = renderer.autoClear;
 		renderer.autoClear = false;
 		renderer.autoClear = false;
 
 
-		this.uniforms[ "scale" ].value = 1.0 / ( jitterOffsets.length );
-		this.uniforms[ "tForeground" ].value = this.sampleRenderTarget;
+		this.compositeUniforms[ "scale" ].value = 1.0 / ( jitterOffsets.length );
+		this.compositeUniforms[ "tForeground" ].value = this.sampleRenderTarget;
 
 
 		// render the scene multiple times, each slightly jitter offset from the last and accumulate the results.
 		// render the scene multiple times, each slightly jitter offset from the last and accumulate the results.
 		for ( var i = 0; i < jitterOffsets.length; i ++ ) {
 		for ( var i = 0; i < jitterOffsets.length; i ++ ) {
@@ -140,5 +152,15 @@ THREE.ManualMSAARenderPass.JitterVectors = [
 		[ - 5, - 2 ], [ 2, 5 ], [ 5, 3 ], [ 3, - 5 ],
 		[ - 5, - 2 ], [ 2, 5 ], [ 5, 3 ], [ 3, - 5 ],
 		[ - 2, 6 ], [ 0, - 7 ], [ - 4, - 6 ], [ - 6, 4 ],
 		[ - 2, 6 ], [ 0, - 7 ], [ - 4, - 6 ], [ - 6, 4 ],
 		[ - 8, 0 ], [ 7, - 4 ], [ 6, 7 ], [ - 7, - 8 ]
 		[ - 8, 0 ], [ 7, - 4 ], [ 6, 7 ], [ - 7, - 8 ]
+	],
+	[
+		[ - 4, - 7 ], [ - 7, - 5 ], [ - 3, - 5 ], [ - 5, - 4 ],
+		[ - 1, - 4 ], [ - 2, - 2 ], [ - 6, - 1 ], [ - 4, 0 ],
+		[ - 7, 1 ], [ - 1, 2 ], [ - 6, 3 ], [ - 3, 3 ],
+		[ - 7, 6 ], [ - 3, 6 ], [ - 5, 7 ], [ - 1, 7 ],
+		[ 5, - 7 ], [ 1, - 6 ], [ 6, - 5 ], [ 4, - 4 ],
+		[ 2, - 3 ], [ 7, - 2 ], [ 1, - 1 ], [ 4, - 1 ],
+		[ 2, 1 ], [ 6, 2 ], [ 0, 4 ], [ 4, 4 ],
+		[ 2, 5 ], [ 7, 5 ], [ 5, 6 ], [ 3, 7 ]
 	]
 	]
 ];
 ];

+ 121 - 0
examples/js/postprocessing/TAARenderPass.js

@@ -0,0 +1,121 @@
+/**
+ *
+ * Temporal Anti-Aliasing Render Pass
+ *
+ * @author bhouston / http://clara.io/
+ *
+ * When there is no motion in the scene, the TAA render pass accumulates jittered camera samples across frames to create a high quality anti-aliased result.
+ *
+ * References:
+ *
+ * TODO: Add support for motion vector pas so that accumulation of samples across frames can occur on dynamics scenes.
+ *
+ */
+
+THREE.TAARenderPass = function ( scene, camera, params ) {
+
+	if ( THREE.ManualMSAARenderPass === undefined ) {
+
+		console.error( "THREE.TAARenderPass relies on THREE.ManualMSAARenderPass" );
+
+	}
+	THREE.ManualMSAARenderPass.call( this, scene, camera, params );
+
+	this.sampleLevel = 0;
+	this.accumulate = false;
+	
+};
+
+THREE.TAARenderPass.prototype = Object.create( THREE.ManualMSAARenderPass.prototype );
+THREE.TAARenderPass.prototype.constructor = THREE.TAARenderPass;
+THREE.TAARenderPass.JitterVectors = THREE.ManualMSAARenderPass.JitterVectors;
+
+THREE.TAARenderPass.prototype.render = function ( renderer, writeBuffer, readBuffer, delta ) {
+
+	if( ! this.accumulate ) {
+
+			THREE.ManualMSAARenderPass.prototype.render.call( this, renderer, writeBuffer, readBuffer, delta );
+
+			this.accumulateIndex = -1;
+			return;
+
+	}
+
+	var jitterOffsets = THREE.TAARenderPass.JitterVectors[ 5 ];
+
+	var camera = ( this.camera || this.scene.camera );
+
+	if ( ! this.sampleRenderTarget ) {
+
+		this.sampleRenderTarget = new THREE.WebGLRenderTarget( readBuffer.width, readBuffer.height, this.params );
+
+	}
+
+	if ( ! this.holdRenderTarget ) {
+
+		this.holdRenderTarget = new THREE.WebGLRenderTarget( readBuffer.width, readBuffer.height, this.params );
+
+	}
+
+	if( this.accumulate && this.accumulateIndex === -1 ) {
+
+			THREE.ManualMSAARenderPass.prototype.render.call( this, renderer, this.holdRenderTarget, readBuffer, delta );
+
+			this.accumulateIndex = 0;
+
+	}
+
+	var autoClear = renderer.autoClear;
+	renderer.autoClear = false;
+
+	var sampleWeight = 1.0 / ( jitterOffsets.length );
+
+	if( this.accumulateIndex >= 0 && this.accumulateIndex < jitterOffsets.length ) {
+
+		this.compositeUniforms[ "scale" ].value = sampleWeight;
+		this.compositeUniforms[ "tForeground" ].value = writeBuffer;
+
+		// render the scene multiple times, each slightly jitter offset from the last and accumulate the results.
+		var numSamplesPerFrame = Math.pow( 2, this.sampleLevel );
+		for ( var i = 0; i < numSamplesPerFrame; i ++ ) {
+
+			var j = this.accumulateIndex;
+			// only jitters perspective cameras.	TODO: add support for jittering orthogonal cameras
+			var jitterOffset = jitterOffsets[j];
+			if ( camera.setViewOffset ) {
+				camera.setViewOffset( readBuffer.width, readBuffer.height,
+					jitterOffset[ 0 ] * 0.0625, jitterOffset[ 1 ] * 0.0625,   // 0.0625 = 1 / 16
+					readBuffer.width, readBuffer.height );
+			}
+
+			renderer.render( this.scene, this.camera, writeBuffer, true );
+
+			renderer.render( this.scene2, this.camera2, this.sampleRenderTarget, ( this.accumulateIndex == 0 ) );
+
+			this.accumulateIndex ++;
+			if( this.accumulateIndex >= jitterOffsets.length ) break;
+		}
+
+		// reset jitter to nothing.	TODO: add support for orthogonal cameras
+		if ( camera.setViewOffset ) camera.setViewOffset( undefined, undefined, undefined, undefined, undefined, undefined );
+
+	}
+
+	var accumulationWeight = this.accumulateIndex * sampleWeight;
+
+	if( accumulationWeight > 0 ) {
+		this.compositeUniforms[ "scale" ].value = 1.0;
+		this.compositeUniforms[ "tForeground" ].value = this.sampleRenderTarget;
+		renderer.render( this.scene2, this.camera2, writeBuffer, true );
+	}
+
+	if( accumulationWeight < 1.0 ) {
+		this.compositeUniforms[ "scale" ].value = 1.0 - accumulationWeight;
+		this.compositeUniforms[ "tForeground" ].value = this.holdRenderTarget;
+		renderer.render( this.scene2, this.camera2, writeBuffer, ( accumulationWeight === 0 ) );
+	}
+
+	renderer.autoClear = autoClear;
+
+
+}

+ 1 - 1
examples/webgl_effects_anaglyph.html

@@ -124,7 +124,7 @@
 
 
 				//
 				//
 
 
-				renderer = new THREE.WebGLRenderer();
+				renderer = new THREE.WebGLRenderer( { antialias: false } );
 				renderer.setPixelRatio( window.devicePixelRatio );
 				renderer.setPixelRatio( window.devicePixelRatio );
 				container.appendChild( renderer.domElement );
 				container.appendChild( renderer.domElement );
 
 

+ 25 - 3
examples/webgl_effects_cardboard.html

@@ -49,24 +49,46 @@
 				scene.add( mesh );
 				scene.add( mesh );
 
 
 				var light = new THREE.DirectionalLight( 0xffffff );
 				var light = new THREE.DirectionalLight( 0xffffff );
-				light.position.set( -1, 1.5, 0.5 );
+				light.position.set( - 1, 1.5, 0.5 );
 				light.castShadow = true;
 				light.castShadow = true;
 				scene.add( light );
 				scene.add( light );
 
 
 				var light = new THREE.DirectionalLight( 0xff0000, 1.5 );
 				var light = new THREE.DirectionalLight( 0xff0000, 1.5 );
-				light.position.set( 1, 1.5, -0.5 );
+				light.position.set( 1, 1.5, - 0.5 );
 				light.castShadow = true;
 				light.castShadow = true;
 				scene.add( light );
 				scene.add( light );
 
 
 				//
 				//
 
 
-				renderer = new THREE.WebGLRenderer();
+				renderer = new THREE.WebGLRenderer( { antialias: false } );
 				renderer.setClearColor( 0x101010 );
 				renderer.setClearColor( 0x101010 );
 				renderer.setPixelRatio( window.devicePixelRatio );
 				renderer.setPixelRatio( window.devicePixelRatio );
 				renderer.setSize( window.innerWidth, window.innerHeight );
 				renderer.setSize( window.innerWidth, window.innerHeight );
 				renderer.shadowMap.enabled = true;
 				renderer.shadowMap.enabled = true;
 				document.body.appendChild( renderer.domElement );
 				document.body.appendChild( renderer.domElement );
 
 
+				renderer.domElement.addEventListener( 'click', function () {
+
+					if ( this.requestFullscreen ) {
+
+						this.requestFullscreen();
+
+					} else if ( this.msRequestFullscreen ) {
+
+						this.msRequestFullscreen();
+
+					} else if ( this.mozRequestFullScreen ) {
+
+						this.mozRequestFullScreen();
+
+					} else if ( this.webkitRequestFullscreen ) {
+
+						this.webkitRequestFullscreen();
+
+					}
+
+				} );
+
 				//
 				//
 
 
 				effect = new THREE.CardboardEffect( renderer );
 				effect = new THREE.CardboardEffect( renderer );

+ 1 - 1
examples/webgl_effects_parallaxbarrier.html

@@ -201,7 +201,7 @@
 
 
 				//
 				//
 
 
-				renderer = new THREE.WebGLRenderer();
+				renderer = new THREE.WebGLRenderer( { antialias: false } );
 				renderer.setFaceCulling( THREE.CullFaceNone );
 				renderer.setFaceCulling( THREE.CullFaceNone );
 				renderer.setPixelRatio( window.devicePixelRatio );
 				renderer.setPixelRatio( window.devicePixelRatio );
 				container.appendChild( renderer.domElement );
 				container.appendChild( renderer.domElement );

+ 52 - 9
examples/webgl_materials_displacementmap.html

@@ -24,7 +24,6 @@
 				font-family:Monospace;
 				font-family:Monospace;
 				font-size:13px;
 				font-size:13px;
 				text-align:center;
 				text-align:center;
-				z-index:1000;
 			}
 			}
 
 
 			#vt { display:none }
 			#vt { display:none }
@@ -41,7 +40,7 @@
 	<body>
 	<body>
 
 
 		<div id="info">
 		<div id="info">
-			<a href="http://threejs.org" target="_blank">three.js</a> - (<span id="description">normal + ao + displacement + environment</span>) map demo.
+			<a href="http://threejs.org" target="_blank">three.js</a> - (<span id="description">normal + ao + displacement + environment</span>) map demo.<br />
 			ninja head from <a href="http://developer.amd.com/tools-and-sdks/archive/legacy-cpu-gpu-tools/amd-gpu-meshmapper/" target="_blank">AMD GPU MeshMapper</a>
 			ninja head from <a href="http://developer.amd.com/tools-and-sdks/archive/legacy-cpu-gpu-tools/amd-gpu-meshmapper/" target="_blank">AMD GPU MeshMapper</a>
 
 
 			<div id="vt">displacement mapping requires vertex textures</div>
 			<div id="vt">displacement mapping requires vertex textures</div>
@@ -55,6 +54,7 @@
 
 
 		<script src="js/Detector.js"></script>
 		<script src="js/Detector.js"></script>
 		<script src="js/libs/stats.min.js"></script>
 		<script src="js/libs/stats.min.js"></script>
+		<script src='js/libs/dat.gui.min.js'></script>
 
 
 		<script>
 		<script>
 
 
@@ -63,8 +63,15 @@
 			var stats, loader;
 			var stats, loader;
 
 
 			var camera, scene, renderer, controls;
 			var camera, scene, renderer, controls;
+			var settings = {
+				metalness: 1.0,
+				roughness: 0.4,
+				aoMapIntensity: 1.0,
+				displacementScale: 1.0,
+				normalScale: 1.0
+			};
 
 
-			var mesh;
+			var mesh, material;
 
 
 			var pointLight;
 			var pointLight;
 
 
@@ -80,6 +87,44 @@
 
 
 			init();
 			init();
 			animate();
 			animate();
+			initGui();
+
+			// Init gui
+			function initGui() {
+
+				var gui = new dat.GUI();
+				//var gui = gui.addFolder( "Material" );
+				gui.add( settings, "metalness" ).min( 0 ).max( 1 ).onChange( function( value ) {
+
+					material.metalness = value;
+
+				} );
+
+				gui.add( settings, "roughness" ).min( 0 ).max( 1 ).onChange( function( value ) {
+
+					material.roughness = value;
+
+				} );
+
+				gui.add( settings, "aoMapIntensity" ).min( 0 ).max( 1 ).onChange( function( value ) {
+
+					material.aoMapIntensity = value;
+
+				} );
+
+				gui.add( settings, "displacementScale" ).min( 0 ).max( 3.0 ).onChange( function( value ) {
+
+					material.displacementScale = value;
+
+				} );
+
+				gui.add( settings, "normalScale" ).min( - 1 ).max( 1 ).onChange( function( value ) {
+
+					material.normalScale = new THREE.Vector2( 1, - 1 ).multiplyScalar( value );
+
+				} );
+
+			}
 
 
 			function init() {
 			function init() {
 
 
@@ -148,11 +193,11 @@
 
 
 				// material
 				// material
 
 
-				var material = new THREE.MeshPhongMaterial( {
+				material = new THREE.MeshStandardMaterial( {
 
 
-					color: 0x0a0100,
-					specular: 0xffffff,
-					shininess: 10,
+					color: 0x888888,
+					roughness: settings.roughness,
+					metalness: settings.metalness,
 
 
 					normalMap: normalMap,
 					normalMap: normalMap,
 					normalScale: new THREE.Vector2( 1, - 1 ), // why does the normal map require negation in this case?
 					normalScale: new THREE.Vector2( 1, - 1 ), // why does the normal map require negation in this case?
@@ -165,8 +210,6 @@
 					displacementBias: - 0.428408,
 					displacementBias: - 0.428408,
 
 
 					envMap: reflectionCube,
 					envMap: reflectionCube,
-					combine: THREE.AddOperation,
-					reflectivity: 0.2,
 
 
 					side: THREE.DoubleSide
 					side: THREE.DoubleSide
 
 

+ 10 - 8
examples/webgl_postprocessing_msaa.html

@@ -29,6 +29,7 @@
 	<body>
 	<body>
 		<div id="info">
 		<div id="info">
 			<a href="http://threejs.org" target="_blank">three.js</a> - Manual Multi-Sample Anti-Aliasing (MSAA) pass by <a href="https://clara.io" target="_blank">Ben Houston</a><br/><br/>
 			<a href="http://threejs.org" target="_blank">three.js</a> - Manual Multi-Sample Anti-Aliasing (MSAA) pass by <a href="https://clara.io" target="_blank">Ben Houston</a><br/><br/>
+			This manual approach to MSAA re-renders the scene ones for each sample with camera jitter and accumulates the results.<br/><br/>
 			Texture interpolation, mipmapping and anistropic sampling is disabled to emphasize<br/> the effect MSAA levels have one the resulting render quality.
 			Texture interpolation, mipmapping and anistropic sampling is disabled to emphasize<br/> the effect MSAA levels have one the resulting render quality.
 		</div>
 		</div>
 
 
@@ -50,7 +51,7 @@
 
 
 		<script>
 		<script>
 
 
-			var camera, scene, renderer, composer, copyPass, manualMSAARenderPass;
+			var camera, scene, renderer, composer, copyPass, msaaRenderPass;
 			var gui, stats, texture;
 			var gui, stats, texture;
 
 
 			var param = { MSAASampleLevel: 2 };
 			var param = { MSAASampleLevel: 2 };
@@ -71,11 +72,12 @@
 					'Level 1: 2 Samples': 1,
 					'Level 1: 2 Samples': 1,
 					'Level 2: 4 Samples': 2,
 					'Level 2: 4 Samples': 2,
 					'Level 3: 8 Samples': 3,
 					'Level 3: 8 Samples': 3,
-					'Level 4: 16 Samples': 4
+					'Level 4: 16 Samples': 4,
+					'Level 5: 32 Samples': 5
 				} ).onFinishChange( function() {
 				} ).onFinishChange( function() {
 
 
-					if( manualMSAARenderPass ) {
-						manualMSAARenderPass.sampleLevel = param.MSAASampleLevel;
+					if( msaaRenderPass ) {
+						msaaRenderPass.sampleLevel = param.MSAASampleLevel;
 					}
 					}
 
 
 				} );
 				} );
@@ -128,9 +130,9 @@
 
 
 				composer = new THREE.EffectComposer( renderer );
 				composer = new THREE.EffectComposer( renderer );
 
 
-				manualMSAARenderPass = new THREE.ManualMSAARenderPass( scene, camera );
-				manualMSAARenderPass.sampleLevel = param.MSAASampleLevel;
-				composer.addPass( manualMSAARenderPass );
+				msaaRenderPass = new THREE.ManualMSAARenderPass( scene, camera );
+				msaaRenderPass.sampleLevel = param.MSAASampleLevel;
+				composer.addPass( msaaRenderPass );
 
 
 				copyPass = new THREE.ShaderPass( THREE.CopyShader );
 				copyPass = new THREE.ShaderPass( THREE.CopyShader );
 		    copyPass.renderToScreen = true;
 		    copyPass.renderToScreen = true;
@@ -154,7 +156,7 @@
 				var newWidth  = Math.floor( width / pixelRatio ) || 1;
 				var newWidth  = Math.floor( width / pixelRatio ) || 1;
 				var newHeight = Math.floor( height / pixelRatio ) || 1;
 				var newHeight = Math.floor( height / pixelRatio ) || 1;
 				composer.setSize( newWidth, newHeight );
 				composer.setSize( newWidth, newHeight );
-				msaaPass.setSize( newWidth, newHeight );
+				msaaRenderPass.setSize( newWidth, newHeight );
 
 
 			}
 			}
 
 

+ 214 - 0
examples/webgl_postprocessing_taa.html

@@ -0,0 +1,214 @@
+<!DOCTYPE html>
+<html lang="en">
+	<head>
+		<title>three.js webgl - postprocessing manual msaa</title>
+		<meta charset="utf-8">
+		<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
+		<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> - Temporal Anti-Aliasing (TAA) pass by <a href="https://clara.io" target="_blank">Ben Houston</a><br/><br/>
+			When there is no motion in the scene, the TAA render pass accumulates jittered camera samples<br/>
+			across frames to create a high quality anti-aliased result.<br/><br/>
+			Texture interpolation, mipmapping and anistropic sampling is disabled to emphasize<br/> the effect MSAA levels have one the resulting render quality.
+		</div>
+
+		<div id="container"></div>
+
+		<script src="../build/three.min.js"></script>
+		<script src="js/libs/stats.min.js"></script>
+		<script src="js/libs/dat.gui.min.js"></script>
+
+		<script src="js/postprocessing/ManualMSAARenderPass.js"></script>
+		<script src="js/postprocessing/TAARenderPass.js"></script>
+		<script src="js/shaders/CopyShader.js"></script>
+		<script src="js/shaders/CompositeShader.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>
+
+
+		<script>
+
+			var camera, scene, renderer, composer, copyPass, taaRenderPass, renderPass;
+			var gui, stats, texture;
+
+			var param = { TAAEnabled: "1", TAASampleLevel: 0 };
+
+			init();
+			animate();
+
+			clearGui();
+
+			function clearGui() {
+
+				if ( gui ) gui.destroy();
+
+				gui = new dat.GUI();
+
+				gui.add( param, 'TAAEnabled', {
+					'Disabled': '0',
+					'Enabled': '1'
+				} ).onFinishChange( function() {
+
+					if( taaRenderPass ) {
+
+						taaRenderPass.enabled = ( param.TAAEnabled === "1" );
+						renderPass.enabled = ( param.TAAEnabled !== "1" );
+
+					}
+
+				} );
+
+				gui.add( param, 'TAASampleLevel', {
+					'Level 0: 1 Sample': 0,
+					'Level 1: 2 Samples': 1,
+					'Level 2: 4 Samples': 2,
+					'Level 3: 8 Samples': 3,
+					'Level 4: 16 Samples': 4,
+					'Level 5: 32 Samples': 5
+				} ).onFinishChange( function() {
+
+					if( taaRenderPass ) {
+						taaRenderPass.sampleLevel = param.TAASampleLevel;
+					}
+
+				} );
+
+				gui.open();
+
+			}
+
+			function init() {
+
+				container = document.getElementById( "container" );
+
+				renderer = new THREE.WebGLRenderer( { antialias: false } );
+				renderer.setPixelRatio( window.devicePixelRatio );
+				renderer.setSize( window.innerWidth, window.innerHeight );
+				document.body.appendChild( renderer.domElement );
+
+				stats = new Stats();
+				stats.domElement.style.position = 'absolute';
+				stats.domElement.style.top = '0px';
+				container.appendChild( stats.domElement );
+
+				//
+
+				camera = new THREE.PerspectiveCamera( 70, window.innerWidth / window.innerHeight, 1, 1000 );
+				camera.position.z = 300;
+
+				scene = new THREE.Scene();
+
+				var geometry = new THREE.BoxGeometry( 120, 120, 120 );
+				var material = new THREE.MeshBasicMaterial( { color: 0xffffff, wireframe: true } );
+
+				var mesh = new THREE.Mesh( geometry, material );
+				mesh.position.x = - 100;
+				scene.add( mesh );
+
+				var texture = new THREE.TextureLoader().load( "textures/brick_diffuse.jpg" );
+				texture.minFilter = THREE.NearestFilter;
+				texture.magFilter = THREE.NearestFilter;
+				texture.anisotropy = 1;
+				texture.generateMipmaps = false;
+
+				var material = new THREE.MeshBasicMaterial( { map: texture } );
+
+				var mesh = new THREE.Mesh( geometry, material );
+				mesh.position.x = 100;
+				scene.add( mesh );
+
+				// postprocessing
+
+				composer = new THREE.EffectComposer( renderer );
+
+				taaRenderPass = new THREE.TAARenderPass( scene, camera );
+				composer.addPass( taaRenderPass );
+
+				renderPass = new THREE.RenderPass( scene, camera );
+				renderPass.enabled = false;
+				composer.addPass( renderPass );
+
+				copyPass = new THREE.ShaderPass( THREE.CopyShader );
+		    copyPass.renderToScreen = true;
+				composer.addPass( copyPass );
+
+				window.addEventListener( 'resize', onWindowResize, false );
+
+			}
+
+			function onWindowResize() {
+
+				var width = window.innerWidth;
+				var height = window.innerHeight;
+
+				camera.aspect = width / height;
+				camera.updateProjectionMatrix();
+
+				renderer.setSize( width, height );
+
+				var pixelRatio = renderer.getPixelRatio();
+				var newWidth  = Math.floor( width / pixelRatio ) || 1;
+				var newHeight = Math.floor( height / pixelRatio ) || 1;
+				composer.setSize( newWidth, newHeight );
+				taaRenderPass.setSize( newWidth, newHeight );
+
+			}
+
+			function animate() {
+
+				this.index = this.index || 0;
+
+				requestAnimationFrame( animate );
+
+				this.index ++;
+
+				if( Math.round( this.index / 200 ) % 2 === 0 ) {
+					for ( var i = 0; i < scene.children.length; i ++ ) {
+
+						var child = scene.children[ i ];
+
+						child.rotation.x += 0.005;
+						child.rotation.y += 0.01;
+
+					}
+					if( taaRenderPass ) taaRenderPass.accumulate = false;
+				}
+				else {
+					if( taaRenderPass ) taaRenderPass.accumulate = true;
+				}
+
+				composer.render();
+
+				stats.update();
+
+			}
+
+		</script>
+		<div>
+	</body>
+</html>

+ 2 - 0
src/core/BufferGeometry.js

@@ -142,6 +142,8 @@ THREE.BufferGeometry.prototype = {
 
 
 		}
 		}
 
 
+		return this;
+
 	},
 	},
 
 
 	rotateX: function () {
 	rotateX: function () {

+ 2 - 0
src/core/Geometry.js

@@ -87,6 +87,8 @@ THREE.Geometry.prototype = {
 		this.verticesNeedUpdate = true;
 		this.verticesNeedUpdate = true;
 		this.normalsNeedUpdate = true;
 		this.normalsNeedUpdate = true;
 
 
+		return this;
+
 	},
 	},
 
 
 	rotateX: function () {
 	rotateX: function () {

+ 2 - 2
src/renderers/shaders/ShaderChunk/encodings.glsl

@@ -22,10 +22,10 @@ vec4 LinearTosGamma( in vec4 value, in float gammaFactor ) {
 }
 }
 
 
 vec4 sRGBToLinear( in vec4 value ) {
 vec4 sRGBToLinear( in vec4 value ) {
-  return vec4( mix( pow( value.rgb * 0.9478672986 + vec3( 0.0521327014 ), vec3( 2.4 ) ), value.rgb * 0.0773993808, lessThanEqual( value.rgb, vec3( 0.04045 ) ) ), value.w );
+  return vec4( mix( pow( value.rgb * 0.9478672986 + vec3( 0.0521327014 ), vec3( 2.4 ) ), value.rgb * 0.0773993808, vec3( lessThanEqual( value.rgb, vec3( 0.04045 ) ) ) ), value.w );
 }
 }
 vec4 LinearTosRGB( in vec4 value ) {
 vec4 LinearTosRGB( in vec4 value ) {
-  return vec4( mix( pow( value.rgb, vec3( 0.41666 ) ) - vec3( 0.055 ), value.rgb * 12.92, lessThanEqual( value.rgb, vec3( 0.0031308 ) ) ), value.w );
+  return vec4( mix( pow( value.rgb, vec3( 0.41666 ) ) - vec3( 0.055 ), value.rgb * 12.92, vec3( lessThanEqual( value.rgb, vec3( 0.0031308 ) ) ) ), value.w );
 }
 }
 
 
 vec4 RGBEToLinear( in vec4 value ) {
 vec4 RGBEToLinear( in vec4 value ) {

+ 7 - 1
src/textures/Texture.js

@@ -36,7 +36,13 @@ THREE.Texture = function ( image, mapping, wrapS, wrapT, magFilter, minFilter, f
 	this.premultiplyAlpha = false;
 	this.premultiplyAlpha = false;
 	this.flipY = true;
 	this.flipY = true;
 	this.unpackAlignment = 4;	// valid values: 1, 2, 4, 8 (see http://www.khronos.org/opengles/sdk/docs/man/xhtml/glPixelStorei.xml)
 	this.unpackAlignment = 4;	// valid values: 1, 2, 4, 8 (see http://www.khronos.org/opengles/sdk/docs/man/xhtml/glPixelStorei.xml)
-	this.encoding = THREE.LinearEncoding;	// Values !== THREE.LinearEncoding only supported on map, envMap and emissiveMap (as these maps regularly have unbounded intensity values, i.e. via an *.hdr or *.exr image.)
+
+
+	// Values of encoding !== THREE.LinearEncoding only supported on map, envMap and emissiveMap.
+	//
+	// Also changing the encoding after already used by a Material will not automatically make the Material
+	// update.  You need to explicitly call Material.needsUpdate to trigger it to recompile.
+	this.encoding = THREE.LinearEncoding;
 
 
 	this.version = 0;
 	this.version = 0;
 	this.onUpdate = null;
 	this.onUpdate = null;

+ 15 - 1
utils/converters/fbx/README.md

@@ -48,8 +48,22 @@ Don't forget the visit the FBX SDK documentation website:
   http://docs.autodesk.com/FBX/2013/ENU/FBX-SDK-Documentation/cpp_ref/index.html
   http://docs.autodesk.com/FBX/2013/ENU/FBX-SDK-Documentation/cpp_ref/index.html
 ```
 ```
 
 
+*Note:* If you use the OSX installer, it will install the Python packages into the following folder.
+
+```
+/Applications/Autodesk/FBX Python SDK/[VERSION]/lib/
+```
+
+If the tool still can't find the FBX SDK, you may need to copy the `fbx.so`, `FbxCommon.py` and `sip.so` files into your site_packages folder. 
+
+If you don't know your site_packages folder, run `python` from shell and paste this:
+
+```py
+import site; site.getsitepackages()
+```
+
 ### Python
 ### Python
-* Requires Python 2.6 or 3.1 (The FBX SDK requires one of these versions)
+* Requires Python 2.6, 2.7 or 3.1 (The FBX SDK requires one of these versions)
 
 
 ``` bash
 ``` bash
 sudo apt-get install build-essential
 sudo apt-get install build-essential

+ 8 - 4
utils/exporters/maya/README.md

@@ -19,9 +19,9 @@ Exports Maya models to Three.js' JSON format.  Currently supports exporting the
 
 
 ## Installation
 ## Installation
 
 
-Install [pymel](http://download.autodesk.com/global/docs/maya2014/en_us/PyMel/install.html).
-Though the docs are way out of date, the process described still works as of
-2014.
+(Maya 2016 suggested)
+
+Install [pymel](http://download.autodesk.com/global/docs/maya2014/en_us/PyMel/install.html) if necessary – Maya 2015 and newer will already include this for you. If you need to install PyMel manually, you can clone the latest from the [LumaPictures/pymel](https://github.com/LumaPictures/pymel) repository.
 
 
 Copy the scripts and plug-ins folders to the appropriate maya folder, where `maya-version` is your current version of Maya (eg. 2013-x64).
 Copy the scripts and plug-ins folders to the appropriate maya folder, where `maya-version` is your current version of Maya (eg. 2013-x64).
 
 
@@ -29,7 +29,11 @@ Copy the scripts and plug-ins folders to the appropriate maya folder, where `may
 - OSX: `~/Library/Preferences/Autodesk/maya/maya-version`
 - OSX: `~/Library/Preferences/Autodesk/maya/maya-version`
 - Linux: `/usr/autodesk/userconfig/maya/maya-version`
 - Linux: `/usr/autodesk/userconfig/maya/maya-version`
 
 
-After that, you need to activate the plugin.  In Maya, open `Window > Settings/Preferences > Plug-in Manager` and enable the checkboxes next to `threeJsFileTranslator.py`.
+After that, you need to activate the plugin.  In Maya, open `Windows > Settings/Preferences > Plug-in Manager` and enable the checkboxes next to `threeJsFileTranslator.py`.
+
+![menu](http://i.imgur.com/XPsq77Q.png)
+
+![plugin](http://i.imgur.com/Bvlj8l6.png)
 
 
 ## Usage
 ## Usage