2
0
Эх сурвалжийг харах

Merge pull request #3 from mrdoob/dev

Update THREE JS fork
Temdog007 6 жил өмнө
parent
commit
97f90bb0e7
100 өөрчлөгдсөн 1766 нэмэгдсэн , 1913 устгасан
  1. 1 1
      .github/ISSUE_TEMPLATE.md
  2. 1 1
      README.md
  3. 74 48
      build/three.js
  4. 337 336
      build/three.min.js
  5. 74 48
      build/three.module.js
  6. 2 2
      docs/api/zh/renderers/WebGLRenderer.html
  7. 2 1
      docs/list.js
  8. 1 0
      docs/manual/en/introduction/Loading-3D-models.html
  9. 7 7
      docs/manual/en/introduction/Matrix-transformations.html
  10. 2 2
      docs/manual/zh/introduction/How-to-dispose-of-objects.html
  11. 7 7
      docs/manual/zh/introduction/Matrix-transformations.html
  12. 0 2
      editor/examples/arkanoid.app.json
  13. 0 2
      editor/examples/camera.app.json
  14. 0 2
      editor/examples/particles.app.json
  15. 0 2
      editor/examples/pong.app.json
  16. 0 2
      editor/examples/shaders.app.json
  17. 0 2
      editor/js/Config.js
  18. 11 9
      editor/js/Editor.js
  19. 3 1
      editor/js/Loader.js
  20. 1 1
      editor/js/Menubar.Edit.js
  21. 1 1
      editor/js/Sidebar.Geometry.BufferGeometry.js
  22. 1 1
      editor/js/Sidebar.Geometry.Geometry.js
  23. 1 1
      editor/js/Sidebar.Geometry.Modifiers.js
  24. 1 1
      editor/js/Sidebar.Geometry.js
  25. 3 3
      editor/js/Sidebar.Material.js
  26. 2 2
      editor/js/Sidebar.Object.js
  27. 5 28
      editor/js/Sidebar.Project.js
  28. 3 3
      editor/js/Sidebar.Scene.js
  29. 0 4
      editor/js/Strings.js
  30. 3 3
      editor/js/Viewport.Info.js
  31. 4 3
      editor/js/Viewport.js
  32. 1 2
      editor/js/libs/app.js
  33. 200 64
      examples/js/MarchingCubes.js
  34. 2 2
      examples/js/loaders/ColladaLoader.js
  35. 22 7
      examples/js/loaders/FBXLoader.js
  36. 205 432
      examples/js/loaders/GLTFLoader.js
  37. 29 11
      examples/js/loaders/VRMLLoader.js
  38. 1 1
      examples/js/nodes/core/StructNode.js
  39. 23 23
      examples/js/postprocessing/AdaptiveToneMappingPass.js
  40. 2 2
      examples/js/postprocessing/AfterimagePass.js
  41. 2 2
      examples/js/postprocessing/BloomPass.js
  42. 1 1
      examples/js/postprocessing/BokehPass.js
  43. 1 1
      examples/js/postprocessing/DotScreenPass.js
  44. 1 1
      examples/js/postprocessing/FilmPass.js
  45. 3 3
      examples/js/postprocessing/GlitchPass.js
  46. 3 3
      examples/js/postprocessing/HalftonePass.js
  47. 1 1
      examples/js/postprocessing/MaskPass.js
  48. 4 1
      examples/js/postprocessing/RenderPass.js
  49. 1 1
      examples/js/postprocessing/SAOPass.js
  50. 3 1
      examples/js/postprocessing/SMAAPass.js
  51. 1 1
      examples/js/postprocessing/SSAARenderPass.js
  52. 1 1
      examples/js/postprocessing/SSAOPass.js
  53. 3 2
      examples/js/postprocessing/ShaderPass.js
  54. 1 1
      examples/js/postprocessing/TAARenderPass.js
  55. 1 1
      examples/js/postprocessing/TexturePass.js
  56. 15 13
      examples/js/renderers/WebGLDeferredRenderer.js
  57. 2 1
      examples/js/utils/BufferGeometryUtils.js
  58. BIN
      examples/models/gltf/Flamingo.glb
  59. BIN
      examples/models/gltf/Horse.glb
  60. BIN
      examples/models/gltf/Parrot.glb
  61. BIN
      examples/models/gltf/Stork.glb
  62. BIN
      examples/textures/tri_pattern.jpg
  63. 1 1
      examples/webgl_animation_skinning_morph.html
  64. 0 1
      examples/webgl_depth_texture.html
  65. 21 21
      examples/webgl_gpgpu_birds.html
  66. 28 18
      examples/webgl_loader_gltf.html
  67. 41 46
      examples/webgl_loader_gltf_extensions.html
  68. 10 10
      examples/webgl_loader_pcd.html
  69. 97 213
      examples/webgl_marchingcubes.html
  70. 47 61
      examples/webgl_materials_cars.html
  71. 10 19
      examples/webgl_materials_standard.html
  72. 4 0
      examples/webgl_morphtargets_horse.html
  73. 4 3
      examples/webgl_panorama_equirectangular.html
  74. 1 0
      examples/webgl_performance_static.html
  75. 9 0
      examples/webgl_postprocessing_dof2.html
  76. 3 1
      examples/webgl_shadowmap.html
  77. 117 123
      package-lock.json
  78. 6 6
      package.json
  79. 167 153
      src/Three.d.ts
  80. 1 2
      src/cameras/CubeCamera.js
  81. 6 6
      src/cameras/PerspectiveCamera.js
  82. 1 1
      src/constants.js
  83. 10 10
      src/extras/curves/Curves.d.ts
  84. 22 43
      src/geometries/Geometries.d.ts
  85. 1 1
      src/loaders/LoadingManager.d.ts
  86. 18 18
      src/materials/Materials.d.ts
  87. 1 1
      src/objects/Line.d.ts
  88. 3 0
      src/objects/LineLoop.d.ts
  89. 3 0
      src/objects/LineSegments.d.ts
  90. 1 1
      src/polyfills.d.ts
  91. 4 6
      src/renderers/WebGLRenderer.d.ts
  92. 4 9
      src/renderers/WebGLRenderer.js
  93. 3 0
      src/renderers/webgl/WebGLBackground.js
  94. 1 1
      src/renderers/webgl/WebGLPrograms.js
  95. 3 1
      src/renderers/webgl/WebGLTextures.js
  96. 1 1
      src/renderers/webgl/WebGLUniforms.js
  97. 3 3
      src/renderers/webvr/WebVRManager.js
  98. 3 1
      src/renderers/webvr/WebXRManager.js
  99. 18 14
      src/scenes/Fog.js
  100. 17 13
      src/scenes/FogExp2.js

+ 1 - 1
.github/ISSUE_TEMPLATE.md

@@ -19,7 +19,7 @@ Please also include a live example if possible. You can start from these templat
 ##### Three.js version
 
 - [ ] Dev
-- [ ] r101
+- [ ] r102
 - [ ] ...
 
 ##### Browser

+ 1 - 1
README.md

@@ -10,7 +10,7 @@ three.js
 
 #### JavaScript 3D library ####
 
-The aim of the project is to create an easy to use, lightweight, 3D library. The library provides Canvas 2D, SVG, CSS3D and WebGL renderers.
+The aim of the project is to create an easy to use, lightweight, 3D library with a default WebGL renderer. The library also provides Canvas 2D, SVG and CSS3D renderers in the examples.
 
 [Examples](http://threejs.org/examples/) —
 [Documentation](http://threejs.org/docs/) —

+ 74 - 48
build/three.js

@@ -185,7 +185,7 @@
 
 	} );
 
-	var REVISION = '102dev';
+	var REVISION = '103dev';
 	var MOUSE = { LEFT: 0, MIDDLE: 1, RIGHT: 2 };
 	var CullFaceNone = 0;
 	var CullFaceBack = 1;
@@ -16351,7 +16351,7 @@
 			case 0x8b5c: return setValue4fm; // _MAT4
 
 			case 0x8b5e: case 0x8d66: return setValueT1; // SAMPLER_2D, SAMPLER_EXTERNAL_OES
-			case 0x8B5F: return setValueT3D1; // SAMPLER_3D
+			case 0x8b5f: return setValueT3D1; // SAMPLER_3D
 			case 0x8b60: return setValueT6; // SAMPLER_CUBE
 
 			case 0x1404: case 0x8b56: return setValue1i; // INT, BOOL
@@ -17693,7 +17693,7 @@
 
 				combine: material.combine,
 
-				vertexTangents: material.vertexTangents,
+				vertexTangents: ( material.normalMap && material.vertexTangents ),
 				vertexColors: material.vertexColors,
 
 				fog: !! fog,
@@ -20138,7 +20138,9 @@
 
 				// only perform resize for certain image types
 
-				if ( image instanceof ImageBitmap || image instanceof HTMLImageElement || image instanceof HTMLCanvasElement ) {
+				if ( ( typeof HTMLImageElement !== 'undefined' && image instanceof HTMLImageElement ) ||
+					( typeof HTMLCanvasElement !== 'undefined' && image instanceof HTMLCanvasElement ) ||
+					( typeof ImageBitmap !== 'undefined' && image instanceof ImageBitmap ) ) {
 
 					var floor = needsPowerOfTwo ? _Math.floorPowerOfTwo : Math.floor;
 
@@ -21540,17 +21542,17 @@
 		 *   var fullHeight = h * 2;
 		 *
 		 *   --A--
-		 *   camera.setOffset( fullWidth, fullHeight, w * 0, h * 0, w, h );
+		 *   camera.setViewOffset( fullWidth, fullHeight, w * 0, h * 0, w, h );
 		 *   --B--
-		 *   camera.setOffset( fullWidth, fullHeight, w * 1, h * 0, w, h );
+		 *   camera.setViewOffset( fullWidth, fullHeight, w * 1, h * 0, w, h );
 		 *   --C--
-		 *   camera.setOffset( fullWidth, fullHeight, w * 2, h * 0, w, h );
+		 *   camera.setViewOffset( fullWidth, fullHeight, w * 2, h * 0, w, h );
 		 *   --D--
-		 *   camera.setOffset( fullWidth, fullHeight, w * 0, h * 1, w, h );
+		 *   camera.setViewOffset( fullWidth, fullHeight, w * 0, h * 1, w, h );
 		 *   --E--
-		 *   camera.setOffset( fullWidth, fullHeight, w * 1, h * 1, w, h );
+		 *   camera.setViewOffset( fullWidth, fullHeight, w * 1, h * 1, w, h );
 		 *   --F--
-		 *   camera.setOffset( fullWidth, fullHeight, w * 2, h * 1, w, h );
+		 *   camera.setViewOffset( fullWidth, fullHeight, w * 2, h * 1, w, h );
 		 *
 		 *   Note there is no reason monitors have to be the same size or in a grid.
 		 */
@@ -21958,9 +21960,11 @@
 
 			var userHeight = frameOfReferenceType === 'stage' ? 1.6 : 0;
 
-			if ( device === null ) {
+			if ( isPresenting() === false ) {
 
 				camera.position.set( 0, userHeight, 0 );
+				camera.rotation.set( 0, 0, 0 );
+
 				return camera;
 
 			}
@@ -22014,8 +22018,6 @@
 
 			poseObject.updateMatrixWorld();
 
-			if ( device.isPresenting === false ) return camera;
-
 			//
 
 			cameraL.near = camera.near;
@@ -22211,6 +22213,7 @@
 		function onSessionEnd() {
 
 			renderer.setFramebuffer( null );
+			renderer.setRenderTarget( renderer.getRenderTarget() ); // Hack #15830
 			animation.stop();
 
 		}
@@ -22420,7 +22423,7 @@
 		this.getStandingMatrix = function () {
 
 			console.warn( 'THREE.WebXRManager: getStandingMatrix() is no longer needed.' );
-			return new THREE.Matrix4();
+			return new Matrix4();
 
 		};
 
@@ -23090,7 +23093,7 @@
 
 		this.renderBufferDirect = function ( camera, fog, geometry, material, object, group ) {
 
-			var frontFaceCW = ( object.isMesh && object.normalMatrix.determinant() < 0 );
+			var frontFaceCW = ( object.isMesh && object.matrixWorld.determinant() < 0 );
 
 			state.setMaterial( material, frontFaceCW );
 
@@ -24846,16 +24849,11 @@
 
 		}() );
 
-		this.setTexture3D = ( function () {
-
-			// backwards compatibility: peel texture.texture
-			return function setTexture3D( texture, slot ) {
-
-				textures.setTexture3D( texture, slot );
+		this.setTexture3D = function ( texture, slot ) {
 
-			};
+			textures.setTexture3D( texture, slot );
 
-		}() );
+		};
 
 		this.setTexture = ( function () {
 
@@ -25120,23 +25118,27 @@
 
 	}
 
-	FogExp2.prototype.isFogExp2 = true;
+	Object.assign( FogExp2.prototype, {
 
-	FogExp2.prototype.clone = function () {
+		isFogExp2: true,
 
-		return new FogExp2( this.color, this.density );
+		clone: function () {
 
-	};
+			return new FogExp2( this.color, this.density );
 
-	FogExp2.prototype.toJSON = function ( /* meta */ ) {
+		},
 
-		return {
-			type: 'FogExp2',
-			color: this.color.getHex(),
-			density: this.density
-		};
+		toJSON: function ( /* meta */ ) {
 
-	};
+			return {
+				type: 'FogExp2',
+				color: this.color.getHex(),
+				density: this.density
+			};
+
+		}
+
+	} );
 
 	/**
 	 * @author mrdoob / http://mrdoob.com/
@@ -25154,24 +25156,28 @@
 
 	}
 
-	Fog.prototype.isFog = true;
+	Object.assign( Fog.prototype, {
 
-	Fog.prototype.clone = function () {
+		isFog: true,
 
-		return new Fog( this.color, this.near, this.far );
+		clone: function () {
 
-	};
+			return new Fog( this.color, this.near, this.far );
 
-	Fog.prototype.toJSON = function ( /* meta */ ) {
+		},
 
-		return {
-			type: 'Fog',
-			color: this.color.getHex(),
-			near: this.near,
-			far: this.far
-		};
+		toJSON: function ( /* meta */ ) {
 
-	};
+			return {
+				type: 'Fog',
+				color: this.color.getHex(),
+				near: this.near,
+				far: this.far
+			};
+
+		}
+
+	} );
 
 	/**
 	 * @author mrdoob / http://mrdoob.com/
@@ -40181,8 +40187,7 @@
 
 			for ( var i = 0; i < 6; i ++ ) {
 
-				renderTarget.activeCubeFace = i;
-				renderer.setRenderTarget( renderTarget );
+				renderer.setRenderTarget( renderTarget, i );
 
 				renderer.clear( color, depth, stencil );
 
@@ -47567,6 +47572,27 @@
 
 	//
 
+	Object.defineProperties( WebGLRenderTargetCube.prototype, {
+
+		activeCubeFace: {
+			set: function ( /* value */ ) {
+
+				console.warn( 'THREE.WebGLRenderTargetCube: .activeCubeFace has been removed. It is now the second parameter of WebGLRenderer.setRenderTarget().' );
+
+			}
+		},
+		activeMipMapLevel: {
+			set: function ( /* value */ ) {
+
+				console.warn( 'THREE.WebGLRenderTargetCube: .activeMipMapLevel has been removed. It is now the third parameter of WebGLRenderer.setRenderTarget().' );
+
+			}
+		}
+
+	} );
+
+	//
+
 	Object.defineProperties( WebGLRenderTarget.prototype, {
 
 		wrapS: {

Файлын зөрүү хэтэрхий том тул дарагдсан байна
+ 337 - 336
build/three.min.js


+ 74 - 48
build/three.module.js

@@ -179,7 +179,7 @@ Object.assign( EventDispatcher.prototype, {
 
 } );
 
-var REVISION = '102dev';
+var REVISION = '103dev';
 var MOUSE = { LEFT: 0, MIDDLE: 1, RIGHT: 2 };
 var CullFaceNone = 0;
 var CullFaceBack = 1;
@@ -16345,7 +16345,7 @@ function getSingularSetter( type ) {
 		case 0x8b5c: return setValue4fm; // _MAT4
 
 		case 0x8b5e: case 0x8d66: return setValueT1; // SAMPLER_2D, SAMPLER_EXTERNAL_OES
-		case 0x8B5F: return setValueT3D1; // SAMPLER_3D
+		case 0x8b5f: return setValueT3D1; // SAMPLER_3D
 		case 0x8b60: return setValueT6; // SAMPLER_CUBE
 
 		case 0x1404: case 0x8b56: return setValue1i; // INT, BOOL
@@ -17687,7 +17687,7 @@ function WebGLPrograms( renderer, extensions, capabilities ) {
 
 			combine: material.combine,
 
-			vertexTangents: material.vertexTangents,
+			vertexTangents: ( material.normalMap && material.vertexTangents ),
 			vertexColors: material.vertexColors,
 
 			fog: !! fog,
@@ -20132,7 +20132,9 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils,
 
 			// only perform resize for certain image types
 
-			if ( image instanceof ImageBitmap || image instanceof HTMLImageElement || image instanceof HTMLCanvasElement ) {
+			if ( ( typeof HTMLImageElement !== 'undefined' && image instanceof HTMLImageElement ) ||
+				( typeof HTMLCanvasElement !== 'undefined' && image instanceof HTMLCanvasElement ) ||
+				( typeof ImageBitmap !== 'undefined' && image instanceof ImageBitmap ) ) {
 
 				var floor = needsPowerOfTwo ? _Math.floorPowerOfTwo : Math.floor;
 
@@ -21534,17 +21536,17 @@ PerspectiveCamera.prototype = Object.assign( Object.create( Camera.prototype ),
 	 *   var fullHeight = h * 2;
 	 *
 	 *   --A--
-	 *   camera.setOffset( fullWidth, fullHeight, w * 0, h * 0, w, h );
+	 *   camera.setViewOffset( fullWidth, fullHeight, w * 0, h * 0, w, h );
 	 *   --B--
-	 *   camera.setOffset( fullWidth, fullHeight, w * 1, h * 0, w, h );
+	 *   camera.setViewOffset( fullWidth, fullHeight, w * 1, h * 0, w, h );
 	 *   --C--
-	 *   camera.setOffset( fullWidth, fullHeight, w * 2, h * 0, w, h );
+	 *   camera.setViewOffset( fullWidth, fullHeight, w * 2, h * 0, w, h );
 	 *   --D--
-	 *   camera.setOffset( fullWidth, fullHeight, w * 0, h * 1, w, h );
+	 *   camera.setViewOffset( fullWidth, fullHeight, w * 0, h * 1, w, h );
 	 *   --E--
-	 *   camera.setOffset( fullWidth, fullHeight, w * 1, h * 1, w, h );
+	 *   camera.setViewOffset( fullWidth, fullHeight, w * 1, h * 1, w, h );
 	 *   --F--
-	 *   camera.setOffset( fullWidth, fullHeight, w * 2, h * 1, w, h );
+	 *   camera.setViewOffset( fullWidth, fullHeight, w * 2, h * 1, w, h );
 	 *
 	 *   Note there is no reason monitors have to be the same size or in a grid.
 	 */
@@ -21952,9 +21954,11 @@ function WebVRManager( renderer ) {
 
 		var userHeight = frameOfReferenceType === 'stage' ? 1.6 : 0;
 
-		if ( device === null ) {
+		if ( isPresenting() === false ) {
 
 			camera.position.set( 0, userHeight, 0 );
+			camera.rotation.set( 0, 0, 0 );
+
 			return camera;
 
 		}
@@ -22008,8 +22012,6 @@ function WebVRManager( renderer ) {
 
 		poseObject.updateMatrixWorld();
 
-		if ( device.isPresenting === false ) return camera;
-
 		//
 
 		cameraL.near = camera.near;
@@ -22205,6 +22207,7 @@ function WebXRManager( renderer ) {
 	function onSessionEnd() {
 
 		renderer.setFramebuffer( null );
+		renderer.setRenderTarget( renderer.getRenderTarget() ); // Hack #15830
 		animation.stop();
 
 	}
@@ -22414,7 +22417,7 @@ function WebXRManager( renderer ) {
 	this.getStandingMatrix = function () {
 
 		console.warn( 'THREE.WebXRManager: getStandingMatrix() is no longer needed.' );
-		return new THREE.Matrix4();
+		return new Matrix4();
 
 	};
 
@@ -23084,7 +23087,7 @@ function WebGLRenderer( parameters ) {
 
 	this.renderBufferDirect = function ( camera, fog, geometry, material, object, group ) {
 
-		var frontFaceCW = ( object.isMesh && object.normalMatrix.determinant() < 0 );
+		var frontFaceCW = ( object.isMesh && object.matrixWorld.determinant() < 0 );
 
 		state.setMaterial( material, frontFaceCW );
 
@@ -24840,16 +24843,11 @@ function WebGLRenderer( parameters ) {
 
 	}() );
 
-	this.setTexture3D = ( function () {
-
-		// backwards compatibility: peel texture.texture
-		return function setTexture3D( texture, slot ) {
-
-			textures.setTexture3D( texture, slot );
+	this.setTexture3D = function ( texture, slot ) {
 
-		};
+		textures.setTexture3D( texture, slot );
 
-	}() );
+	};
 
 	this.setTexture = ( function () {
 
@@ -25114,23 +25112,27 @@ function FogExp2( color, density ) {
 
 }
 
-FogExp2.prototype.isFogExp2 = true;
+Object.assign( FogExp2.prototype, {
 
-FogExp2.prototype.clone = function () {
+	isFogExp2: true,
 
-	return new FogExp2( this.color, this.density );
+	clone: function () {
 
-};
+		return new FogExp2( this.color, this.density );
 
-FogExp2.prototype.toJSON = function ( /* meta */ ) {
+	},
 
-	return {
-		type: 'FogExp2',
-		color: this.color.getHex(),
-		density: this.density
-	};
+	toJSON: function ( /* meta */ ) {
 
-};
+		return {
+			type: 'FogExp2',
+			color: this.color.getHex(),
+			density: this.density
+		};
+
+	}
+
+} );
 
 /**
  * @author mrdoob / http://mrdoob.com/
@@ -25148,24 +25150,28 @@ function Fog( color, near, far ) {
 
 }
 
-Fog.prototype.isFog = true;
+Object.assign( Fog.prototype, {
 
-Fog.prototype.clone = function () {
+	isFog: true,
 
-	return new Fog( this.color, this.near, this.far );
+	clone: function () {
 
-};
+		return new Fog( this.color, this.near, this.far );
 
-Fog.prototype.toJSON = function ( /* meta */ ) {
+	},
 
-	return {
-		type: 'Fog',
-		color: this.color.getHex(),
-		near: this.near,
-		far: this.far
-	};
+	toJSON: function ( /* meta */ ) {
 
-};
+		return {
+			type: 'Fog',
+			color: this.color.getHex(),
+			near: this.near,
+			far: this.far
+		};
+
+	}
+
+} );
 
 /**
  * @author mrdoob / http://mrdoob.com/
@@ -40175,8 +40181,7 @@ function CubeCamera( near, far, cubeResolution, options ) {
 
 		for ( var i = 0; i < 6; i ++ ) {
 
-			renderTarget.activeCubeFace = i;
-			renderer.setRenderTarget( renderTarget );
+			renderer.setRenderTarget( renderTarget, i );
 
 			renderer.clear( color, depth, stencil );
 
@@ -47561,6 +47566,27 @@ Object.defineProperties( WebGLShadowMap.prototype, {
 
 //
 
+Object.defineProperties( WebGLRenderTargetCube.prototype, {
+
+	activeCubeFace: {
+		set: function ( /* value */ ) {
+
+			console.warn( 'THREE.WebGLRenderTargetCube: .activeCubeFace has been removed. It is now the second parameter of WebGLRenderer.setRenderTarget().' );
+
+		}
+	},
+	activeMipMapLevel: {
+		set: function ( /* value */ ) {
+
+			console.warn( 'THREE.WebGLRenderTargetCube: .activeMipMapLevel has been removed. It is now the third parameter of WebGLRenderer.setRenderTarget().' );
+
+		}
+	}
+
+} );
+
+//
+
 Object.defineProperties( WebGLRenderTarget.prototype, {
 
 	wrapS: {

+ 2 - 2
docs/api/zh/renderers/WebGLRenderer.html

@@ -348,7 +348,7 @@
 		<p>将GL状态重置为默认值。WebGL环境丢失时会内部调用</p>
 
 		<h3>[method:null readRenderTargetPixels]( [param:WebGLRenderTarget renderTarget], [param:Float x], [param:Float y], [param:Float width], [param:Float height], buffer )</h3>
-		<p>将enderTarget中的像素数据读取到传入的缓冲区中。这是link:https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext/readPixels WebGLRenderingContext.readPixels]()的包装器<br />
+		<p>将enderTarget中的像素数据读取到传入的缓冲区中。这是[link:https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext/readPixels WebGLRenderingContext.readPixels]()的包装器<br />
 		示例:[example:webgl_interactive_cubes_gpu interactive / cubes / gpu]
 		</p>
 
@@ -376,7 +376,7 @@
 
 		<h3>[method:null setAnimationLoop]( [param:Function callback] )</h3>
 		<p>[page:Function callback] — 每个可用帧都会调用的函数。 如果传入‘null’,所有正在进行的动画都会停止。</p>
-		<p>可用来代替[link:https://developer.mozilla.org/en-US/docs/Web/API/window/requestAnimationFrame requestAnimationFrame]的内置函数. 对于WebVR想谬,必须使用此功能</p>
+		<p>可用来代替[link:https://developer.mozilla.org/en-US/docs/Web/API/window/requestAnimationFrame requestAnimationFrame]的内置函数. 对于WebVR项目,必须使用此函数。</p>
 
 		<h3>[method:null setClearAlpha]( [param:Float alpha] )</h3>
 		<p>设置alpha。合法参数是一个*0.0*到 *1.0*之间的浮点数</p>

+ 2 - 1
docs/list.js

@@ -382,7 +382,8 @@ var list = {
 
 			"Exporters": {
 				"GLTFExporter": "examples/exporters/GLTFExporter",
-				"PLYExporter": "examples/exporters/PLYExporter"
+				"PLYExporter": "examples/exporters/PLYExporter",
+				"ColladaExporter": "examples/exporters/ColladaExporter"
 			},
 
 			"Plugins": {

+ 1 - 0
docs/manual/en/introduction/Loading-3D-models.html

@@ -63,6 +63,7 @@
 		<li><a href="https://www.foundry.com/products/modo" target="_blank" rel="noopener">Modo</a> by Foundry</li>
 		<li><a href="https://www.marmoset.co/toolbag/" target="_blank" rel="noopener">Toolbag</a> by Marmoset</li>
 		<li><a href="https://www.sidefx.com/products/houdini/" target="_blank" rel="noopener">Houdini</a> by SideFX</li>
+		<li><a href="https://labs.maxon.net/?p=3360" target="_blank" rel="noopener">Cinema 4D</a> by MAXON</li>
 		<li>&hellip;and <a href="https://github.com/khronosgroup/gltf#gltf-tools" target="_blank" rel="noopener">many more</a></li>
 	</ul>
 

+ 7 - 7
docs/manual/en/introduction/Matrix-transformations.html

@@ -22,25 +22,25 @@
 				Modify the object's *position*, *quaternion*, and *scale* properties, and let three.js recompute
 				the object's matrix from these properties:
 				<code>
-				object.position.copy(start_position);
-				object.quaternion.copy(quaternion);
+object.position.copy( start_position );
+object.quaternion.copy( quaternion );
 				</code>
 				By default, the *matrixAutoUpdate* property is set true, and the matrix will be automatically recalculated.
 				If the object is static, or you wish to manually control when recalculation occurs, better performance can be obtained by setting the property false:
 				<code>
-				object.matrixAutoUpdate = false;
+object.matrixAutoUpdate = false;
 				</code>
 				And after changing any properties, manually update the matrix:
 				<code>
-				object.updateMatrix();
+object.updateMatrix();
 				</code>
 			</li>
 			<li>
 				Modify the object's matrix directly. The [page:Matrix4] class has various methods for modifying the matrix:
 				<code>
-				object.matrix.setRotationFromQuaternion(quaternion);
-				object.matrix.setPosition(start_position);
-				object.matrixAutoUpdate = false;
+object.matrix.setRotationFromQuaternion( quaternion );
+object.matrix.setPosition( start_position );
+object.matrixAutoUpdate = false;
 				</code>
 				Note that *matrixAutoUpdate* <em>must</em> be set to *false* in this case, and you should make sure <em>not</em> to call *updateMatrix*. Calling *updateMatrix* will clobber the manual changes made to the matrix, recalculating the matrix from *position*, *scale*, and so on.
 			</li>

+ 2 - 2
docs/manual/zh/introduction/How-to-dispose-of-objects.html

@@ -58,7 +58,7 @@
 
 	<p>
 		有一些来自examples目录的类,例如控制器或者后期处理过程,提供了*dispose()*方法以用于移除内部事件监听器或渲染目标。
-		通常来讲,非常建议查阅类的API或者文档,并注意*dispose()*。如果存在的话,你应当在清理时使用它。
+		通常来讲,非常建议查阅类的API或者文档,并注意*dispose()*函数。如果该函数存在的话,你应当在清理时使用它。
 	</p>
 
 	<h2>常见问题</h2>
@@ -75,7 +75,7 @@
 
 	<p>
 		并不会,你必须通过*dispose()*来明确地废置geometry(几何体)或material(材质)。
-		请记住,eometry(几何体)或material(材质)可以在3D物体之间(例如mesh(网格))被共享。
+		请记住,geometry(几何体)或material(材质)可以在3D物体之间(例如mesh(网格))被共享。
 	</p>
 
 	<h3>*three.js*是否会提供被缓存对象数量的相关信息?</h3>

+ 7 - 7
docs/manual/zh/introduction/Matrix-transformations.html

@@ -22,25 +22,25 @@
 			<li>
 				修改对象的*position*,*quaternion*和*scale*属性,让three.js重新计算来自这些属性的对象矩阵:
 				<code>
-				object.position.copy(start_position);
-				object.quaternion.copy(quaternion);
+object.position.copy( start_position );
+object.quaternion.copy( quaternion );
 				</code>
 				默认情况下,*matrixAutoUpdate*属性设置为true,并且将自动重新计算矩阵。
 如果对象是静态的,或者您希望在重新计算时手动控制,则可以通过将属性设置为false来获得更好的性能:
 				<code>
-				object.matrixAutoUpdate = false;
+object.matrixAutoUpdate = false;
 				</code>
 				更改任何属性后,手动更新矩阵:
 				<code>
-				object.updateMatrix();
+object.updateMatrix();
 				</code>
 			</li>
 			<li>
 				直接修改对象的矩阵。 [page:Matrix4]类有各种修改矩阵的方法:
 				<code>
-				object.matrix.setRotationFromQuaternion(quaternion);
-				object.matrix.setPosition(start_position);
-				object.matrixAutoUpdate = false;
+object.matrix.setRotationFromQuaternion( quaternion );
+object.matrix.setPosition( start_position );
+object.matrixAutoUpdate = false;
 				</code>
 				请注意,在这种情况下,*matrixAutoUpdate* <em> 必须 </em>设置为*false*,并且您应该确保<em> 不 </em>调用*updateMatrix*。
 				调用*updateMatrix*将破坏对矩阵所做的手动更改,从*position*,*scale*重新计算矩阵,依此类推。

+ 0 - 2
editor/examples/arkanoid.app.json

@@ -3,8 +3,6 @@
 		"type": "App"
 	},
 	"project": {
-		"gammaInput": true,
-		"gammaOutput": true,
 		"shadows": true,
 		"vr": false
 	},

+ 0 - 2
editor/examples/camera.app.json

@@ -3,8 +3,6 @@
 		"type": "App"
 	},
 	"project": {
-		"gammaInput": true,
-		"gammaOutput": true,
 		"shadows": true,
 		"vr": false
 	},

+ 0 - 2
editor/examples/particles.app.json

@@ -3,8 +3,6 @@
 		"type": "App"
 	},
 	"project": {
-		"gammaInput": true,
-		"gammaOutput": true,
 		"shadows": true,
 		"vr": false
 	},

+ 0 - 2
editor/examples/pong.app.json

@@ -3,8 +3,6 @@
 		"type": "App"
 	},
 	"project": {
-		"gammaInput": true,
-		"gammaOutput": true,
 		"shadows": true,
 		"vr": false
 	},

+ 0 - 2
editor/examples/shaders.app.json

@@ -3,8 +3,6 @@
 		"type": "App"
 	},
 	"project": {
-		"gammaInput": true,
-		"gammaOutput": true,
 		"shadows": true,
 		"vr": false
 	},

+ 0 - 2
editor/js/Config.js

@@ -17,8 +17,6 @@ var Config = function () {
 
 		'project/renderer': 'WebGLRenderer',
 		'project/renderer/antialias': true,
-		'project/renderer/gammaInput': false,
-		'project/renderer/gammaOutput': false,
 		'project/renderer/shadows': true,
 
 		'project/vr': false,

+ 11 - 9
editor/js/Editor.js

@@ -244,7 +244,11 @@ Editor.prototype = {
 
 	addAnimation: function ( object, animations ) {
 
-		this.animations[ object.uuid ] = animations;
+		if ( animations.length > 0 ) {
+
+			this.animations[ object.uuid ] = animations;
+
+		}
 
 	},
 
@@ -259,27 +263,27 @@ Editor.prototype = {
 
 			var helper;
 
-			if ( object instanceof THREE.Camera ) {
+			if ( object.isCamera ) {
 
 				helper = new THREE.CameraHelper( object, 1 );
 
-			} else if ( object instanceof THREE.PointLight ) {
+			} else if ( object.isPointLight ) {
 
 				helper = new THREE.PointLightHelper( object, 1 );
 
-			} else if ( object instanceof THREE.DirectionalLight ) {
+			} else if ( object.isDirectionalLight ) {
 
 				helper = new THREE.DirectionalLightHelper( object, 1 );
 
-			} else if ( object instanceof THREE.SpotLight ) {
+			} else if ( object.isSpotLight ) {
 
 				helper = new THREE.SpotLightHelper( object, 1 );
 
-			} else if ( object instanceof THREE.HemisphereLight ) {
+			} else if ( object.isHemisphereLight ) {
 
 				helper = new THREE.HemisphereLightHelper( object, 1 );
 
-			} else if ( object instanceof THREE.SkinnedMesh ) {
+			} else if ( object.isSkinnedMesh ) {
 
 				helper = new THREE.SkeletonHelper( object );
 
@@ -531,8 +535,6 @@ Editor.prototype = {
 
 			metadata: {},
 			project: {
-				gammaInput: this.config.getKey( 'project/renderer/gammaInput' ),
-				gammaOutput: this.config.getKey( 'project/renderer/gammaOutput' ),
 				shadows: this.config.getKey( 'project/renderer/shadows' ),
 				vr: this.config.getKey( 'project/vr' )
 			},

+ 3 - 1
editor/js/Loader.js

@@ -180,6 +180,7 @@ var Loader = function ( editor ) {
 
 					collada.scene.name = filename;
 
+					editor.addAnimation( collada.scene, collada.animations );
 					editor.execute( new AddObjectCommand( collada.scene ) );
 
 				}, false );
@@ -196,6 +197,7 @@ var Loader = function ( editor ) {
 					var loader = new THREE.FBXLoader( manager );
 					var object = loader.parse( contents );
 
+					editor.addAnimation( object, object.animations );
 					editor.execute( new AddObjectCommand( object ) );
 
 				}, false );
@@ -594,7 +596,7 @@ var Loader = function ( editor ) {
 
 				var result = loader.parse( data );
 
-				if ( result instanceof THREE.Scene ) {
+				if ( result.isScene ) {
 
 					editor.execute( new SetSceneCommand( result ) );
 

+ 1 - 1
editor/js/Menubar.Edit.js

@@ -151,7 +151,7 @@ Menubar.Edit = function ( editor ) {
 
 			var material = object.material;
 
-			if ( material instanceof THREE.ShaderMaterial ) {
+			if ( material.isShaderMaterial ) {
 
 				try {
 

+ 1 - 1
editor/js/Sidebar.Geometry.BufferGeometry.js

@@ -17,7 +17,7 @@ Sidebar.Geometry.BufferGeometry = function ( editor ) {
 
 		var geometry = object.geometry;
 
-		if ( geometry instanceof THREE.BufferGeometry ) {
+		if ( geometry && geometry.isBufferGeometry ) {
 
 			container.clear();
 			container.setDisplay( 'block' );

+ 1 - 1
editor/js/Sidebar.Geometry.Geometry.js

@@ -39,7 +39,7 @@ Sidebar.Geometry.Geometry = function ( editor ) {
 
 		var geometry = object.geometry;
 
-		if ( geometry instanceof THREE.Geometry ) {
+		if ( geometry && geometry.isGeometry ) {
 
 			container.setDisplay( 'block' );
 

+ 1 - 1
editor/js/Sidebar.Geometry.Modifiers.js

@@ -17,7 +17,7 @@ Sidebar.Geometry.Modifiers = function ( editor, object ) {
 
 		geometry.computeVertexNormals();
 
-		if ( geometry instanceof THREE.BufferGeometry ) {
+		if ( geometry.isBufferGeometry ) {
 
 			geometry.attributes.normal.needsUpdate = true;
 

+ 1 - 1
editor/js/Sidebar.Geometry.js

@@ -55,7 +55,7 @@ Sidebar.Geometry = function ( editor ) {
 
 			case 'Convert':
 
-				if ( geometry instanceof THREE.Geometry ) {
+				if ( geometry && geometry.isGeometry ) {
 
 					editor.execute( new SetGeometryCommand( object, new THREE.BufferGeometry().fromGeometry( geometry ) ) );
 

+ 3 - 3
editor/js/Sidebar.Material.js

@@ -525,9 +525,9 @@ Sidebar.Material = function ( editor ) {
 		var textureWarning = false;
 		var objectHasUvs = false;
 
-		if ( object instanceof THREE.Sprite ) objectHasUvs = true;
-		if ( geometry instanceof THREE.Geometry && geometry.faceVertexUvs[ 0 ].length > 0 ) objectHasUvs = true;
-		if ( geometry instanceof THREE.BufferGeometry && geometry.attributes.uv !== undefined ) objectHasUvs = true;
+		if ( object.isSprite ) objectHasUvs = true;
+		if ( geometry.isGeometry && geometry.faceVertexUvs[ 0 ].length > 0 ) objectHasUvs = true;
+		if ( geometry.isBufferGeometry && geometry.attributes.uv !== undefined ) objectHasUvs = true;
 
 		if ( material ) {
 

+ 2 - 2
editor/js/Sidebar.Object.js

@@ -542,8 +542,8 @@ Sidebar.Object = function ( editor ) {
 
 	function updateTransformRows( object ) {
 
-		if ( object instanceof THREE.Light ||
-		   ( object instanceof THREE.Object3D && object.userData.targetInverse ) ) {
+		if ( object.isLight ||
+		   ( object.isObject3D && object.userData.targetInverse ) ) {
 
 			objectRotationRow.setDisplay( 'none' );
 			objectScaleRow.setDisplay( 'none' );

+ 5 - 28
editor/js/Sidebar.Project.js

@@ -119,45 +119,22 @@ Sidebar.Project = function ( editor ) {
 	} );
 	rendererPropertiesRow.add( rendererShadows );
 
-	rendererPropertiesRow.add( new UI.Break() );
-
-	// Renderer / Gamma input
-
-	var rendererGammaInput = new UI.THREE.Boolean( config.getKey( 'project/renderer/gammaInput' ), strings.getKey( 'sidebar/project/gammainput' ) ).onChange( function () {
-
-		config.setKey( 'project/renderer/gammaInput', this.getValue() );
-		updateRenderer();
-
-	} );
-	rendererPropertiesRow.add( rendererGammaInput );
-
-	// Renderer / Gamma output
-
-	var rendererGammaOutput = new UI.THREE.Boolean( config.getKey( 'project/renderer/gammaOutput' ), strings.getKey( 'sidebar/project/gammaoutput' ) ).onChange( function () {
-
-		config.setKey( 'project/renderer/gammaOutput', this.getValue() );
-		updateRenderer();
-
-	} );
-	rendererPropertiesRow.add( rendererGammaOutput );
-
 	container.add( rendererPropertiesRow );
 
 	//
 
 	function updateRenderer() {
 
-		createRenderer( rendererType.getValue(), rendererAntialias.getValue(), rendererShadows.getValue(), rendererGammaInput.getValue(), rendererGammaOutput.getValue() );
+		createRenderer( rendererType.getValue(), rendererAntialias.getValue() );
 
 	}
 
-	function createRenderer( type, antialias, shadows, gammaIn, gammaOut ) {
+	function createRenderer( type, antialias, shadows ) {
 
 		rendererPropertiesRow.setDisplay( type === 'WebGLRenderer' ? '' : 'none' );
 
-		var renderer = new rendererTypes[ type ]( { antialias: antialias} );
-		renderer.gammaInput = gammaIn;
-		renderer.gammaOutput = gammaOut;
+		var renderer = new rendererTypes[ type ]( { antialias: antialias } );
+
 		if ( shadows && renderer.shadowMap ) {
 
 			renderer.shadowMap.enabled = true;
@@ -169,7 +146,7 @@ Sidebar.Project = function ( editor ) {
 
 	}
 
-	createRenderer( config.getKey( 'project/renderer' ), config.getKey( 'project/renderer/antialias' ), config.getKey( 'project/renderer/shadows' ), config.getKey( 'project/renderer/gammaInput' ), config.getKey( 'project/renderer/gammaOutput' ) );
+	createRenderer( config.getKey( 'project/renderer' ), config.getKey( 'project/renderer/antialias' ), config.getKey( 'project/renderer/shadows' ) );
 
 	return container;
 

+ 3 - 3
editor/js/Sidebar.Scene.js

@@ -59,7 +59,7 @@ Sidebar.Scene = function ( editor ) {
 
 		var html = '<span class="type ' + object.type + '"></span> ' + escapeHTML( object.name );
 
-		if ( object instanceof THREE.Mesh ) {
+		if ( object.isMesh ) {
 
 			var geometry = object.geometry;
 			var material = object.material;
@@ -231,13 +231,13 @@ Sidebar.Scene = function ( editor ) {
 
 			fogColor.setHexValue( scene.fog.color.getHex() );
 
-			if ( scene.fog instanceof THREE.Fog ) {
+			if ( scene.fog.isFog ) {
 
 				fogType.setValue( "Fog" );
 				fogNear.setValue( scene.fog.near );
 				fogFar.setValue( scene.fog.far );
 
-			} else if ( scene.fog instanceof THREE.FogExp2 ) {
+			} else if ( scene.fog.isFogExp2 ) {
 
 				fogType.setValue( "FogExp2" );
 				fogDensity.setValue( scene.fog.density );

+ 0 - 4
editor/js/Strings.js

@@ -236,8 +236,6 @@ var Strings = function ( config ) {
 			'sidebar/project/renderer': 'Renderer',
 			'sidebar/project/antialias': 'antialias',
 			'sidebar/project/shadows': 'shadows',
-			'sidebar/project/gammainput': 'γ input',
-			'sidebar/project/gammaoutput': 'γ output',
 
 			'sidebar/settings': 'Settings',
 			'sidebar/settings/language': 'Language',
@@ -485,8 +483,6 @@ var Strings = function ( config ) {
 			'sidebar/project/renderer': '渲染器',
 			'sidebar/project/antialias': '抗锯齿',
 			'sidebar/project/shadows': '阴影',
-			'sidebar/project/gammainput': 'γ输入',
-			'sidebar/project/gammaoutput': 'γ输出',
 
 			'sidebar/settings': '设置',
 			'sidebar/settings/language': '语言',

+ 3 - 3
editor/js/Viewport.Info.js

@@ -46,16 +46,16 @@ Viewport.Info = function ( editor ) {
 
 				objects ++;
 
-				if ( object instanceof THREE.Mesh ) {
+				if ( object.isMesh ) {
 
 					var geometry = object.geometry;
 
-					if ( geometry instanceof THREE.Geometry ) {
+					if ( geometry.isGeometry ) {
 
 						vertices += geometry.vertices.length;
 						triangles += geometry.faces.length;
 
-					} else if ( geometry instanceof THREE.BufferGeometry ) {
+					} else if ( geometry.isBufferGeometry ) {
 
 						vertices += geometry.attributes.position.count;
 

+ 4 - 3
editor/js/Viewport.js

@@ -312,6 +312,7 @@ var Viewport = function ( editor ) {
 
 		renderer.autoClear = false;
 		renderer.autoUpdateScene = false;
+		renderer.gammaOutput = true;
 		renderer.setPixelRatio( window.devicePixelRatio );
 		renderer.setSize( container.dom.offsetWidth, container.dom.offsetHeight );
 
@@ -393,7 +394,7 @@ var Viewport = function ( editor ) {
 
 		}
 
-		if ( object instanceof THREE.PerspectiveCamera ) {
+		if ( object.isPerspectiveCamera ) {
 
 			object.updateProjectionMatrix();
 
@@ -477,13 +478,13 @@ var Viewport = function ( editor ) {
 
 		}
 
-		if ( scene.fog instanceof THREE.Fog ) {
+		if ( scene.fog.isFog ) {
 
 			scene.fog.color.setHex( fogColor );
 			scene.fog.near = fogNear;
 			scene.fog.far = fogFar;
 
-		} else if ( scene.fog instanceof THREE.FogExp2 ) {
+		} else if ( scene.fog.isFogExp2 ) {
 
 			scene.fog.color.setHex( fogColor );
 			scene.fog.density = fogDensity;

+ 1 - 2
editor/js/libs/app.js

@@ -21,13 +21,12 @@ var APP = {
 		this.load = function ( json ) {
 
 			renderer = new THREE.WebGLRenderer( { antialias: true } );
+			renderer.gammaOutput = true;
 			renderer.setClearColor( 0x000000 );
 			renderer.setPixelRatio( window.devicePixelRatio );
 
 			var project = json.project;
 
-			if ( project.gammaInput ) renderer.gammaInput = true;
-			if ( project.gammaOutput ) renderer.gammaOutput = true;
 			if ( project.shadows ) renderer.shadowMap.enabled = true;
 			if ( project.vr ) renderer.vr.enabled = true;
 

+ 200 - 64
examples/js/MarchingCubes.js

@@ -1,6 +1,7 @@
 /**
  * @author alteredq / http://alteredqualia.com/
  * @author mrdoob / http://mrdoob.com
+ * @author chaht01 / http://hyuntak.com
  * Port of http://webglsamples.org/blob/blob.html
  */
 
@@ -14,6 +15,7 @@ THREE.MarchingCubes = function ( resolution, material, enableUvs, enableColors )
 
 	var vlist = new Float32Array( 12 * 3 );
 	var nlist = new Float32Array( 12 * 3 );
+	var clist = new Float32Array( 12 * 3 );
 
 	this.enableUvs = enableUvs !== undefined ? enableUvs : false;
 	this.enableColors = enableColors !== undefined ? enableColors : false;
@@ -45,6 +47,7 @@ THREE.MarchingCubes = function ( resolution, material, enableUvs, enableColors )
 
 		this.field = new Float32Array( this.size3 );
 		this.normal_cache = new Float32Array( this.size3 * 3 );
+		this.palette = new Float32Array( this.size3 * 3 );
 
 		// immediate render mode simulator
 
@@ -83,7 +86,7 @@ THREE.MarchingCubes = function ( resolution, material, enableUvs, enableColors )
 
 	}
 
-	function VIntX( q, offset, isol, x, y, z, valp1, valp2 ) {
+	function VIntX( q, offset, isol, x, y, z, valp1, valp2, c_offset1, c_offset2 ) {
 
 		var mu = ( isol - valp1 ) / ( valp2 - valp1 ),
 			nc = scope.normal_cache;
@@ -96,9 +99,13 @@ THREE.MarchingCubes = function ( resolution, material, enableUvs, enableColors )
 		nlist[ offset + 1 ] = lerp( nc[ q + 1 ], nc[ q + 4 ], mu );
 		nlist[ offset + 2 ] = lerp( nc[ q + 2 ], nc[ q + 5 ], mu );
 
+		clist[ offset + 0 ] = lerp( scope.palette[ c_offset1 * 3 + 0 ], scope.palette[ c_offset2 * 3 + 0 ], mu );
+		clist[ offset + 1 ] = lerp( scope.palette[ c_offset1 * 3 + 1 ], scope.palette[ c_offset2 * 3 + 1 ], mu );
+		clist[ offset + 2 ] = lerp( scope.palette[ c_offset1 * 3 + 2 ], scope.palette[ c_offset2 * 3 + 2 ], mu );
+
 	}
 
-	function VIntY( q, offset, isol, x, y, z, valp1, valp2 ) {
+	function VIntY( q, offset, isol, x, y, z, valp1, valp2, c_offset1, c_offset2 ) {
 
 		var mu = ( isol - valp1 ) / ( valp2 - valp1 ),
 			nc = scope.normal_cache;
@@ -113,9 +120,13 @@ THREE.MarchingCubes = function ( resolution, material, enableUvs, enableColors )
 		nlist[ offset + 1 ] = lerp( nc[ q + 1 ], nc[ q2 + 1 ], mu );
 		nlist[ offset + 2 ] = lerp( nc[ q + 2 ], nc[ q2 + 2 ], mu );
 
+		clist[ offset + 0 ] = lerp( scope.palette[ c_offset1 * 3 + 0 ], scope.palette[ c_offset2 * 3 + 0 ], mu );
+		clist[ offset + 1 ] = lerp( scope.palette[ c_offset1 * 3 + 1 ], scope.palette[ c_offset2 * 3 + 1 ], mu );
+		clist[ offset + 2 ] = lerp( scope.palette[ c_offset1 * 3 + 2 ], scope.palette[ c_offset2 * 3 + 2 ], mu );
+
 	}
 
-	function VIntZ( q, offset, isol, x, y, z, valp1, valp2 ) {
+	function VIntZ( q, offset, isol, x, y, z, valp1, valp2, c_offset1, c_offset2 ) {
 
 		var mu = ( isol - valp1 ) / ( valp2 - valp1 ),
 			nc = scope.normal_cache;
@@ -130,6 +141,10 @@ THREE.MarchingCubes = function ( resolution, material, enableUvs, enableColors )
 		nlist[ offset + 1 ] = lerp( nc[ q + 1 ], nc[ q2 + 1 ], mu );
 		nlist[ offset + 2 ] = lerp( nc[ q + 2 ], nc[ q2 + 2 ], mu );
 
+		clist[ offset + 0 ] = lerp( scope.palette[ c_offset1 * 3 + 0 ], scope.palette[ c_offset2 * 3 + 0 ], mu );
+		clist[ offset + 1 ] = lerp( scope.palette[ c_offset1 * 3 + 1 ], scope.palette[ c_offset2 * 3 + 1 ], mu );
+		clist[ offset + 2 ] = lerp( scope.palette[ c_offset1 * 3 + 2 ], scope.palette[ c_offset2 * 3 + 2 ], mu );
+
 	}
 
 	function compNorm( q ) {
@@ -139,8 +154,10 @@ THREE.MarchingCubes = function ( resolution, material, enableUvs, enableColors )
 		if ( scope.normal_cache[ q3 ] === 0.0 ) {
 
 			scope.normal_cache[ q3 + 0 ] = scope.field[ q - 1 ] - scope.field[ q + 1 ];
-			scope.normal_cache[ q3 + 1 ] = scope.field[ q - scope.yd ] - scope.field[ q + scope.yd ];
-			scope.normal_cache[ q3 + 2 ] = scope.field[ q - scope.zd ] - scope.field[ q + scope.zd ];
+			scope.normal_cache[ q3 + 1 ] =
+				scope.field[ q - scope.yd ] - scope.field[ q + scope.yd ];
+			scope.normal_cache[ q3 + 2 ] =
+				scope.field[ q - scope.zd ] - scope.field[ q + scope.zd ];
 
 		}
 
@@ -195,7 +212,7 @@ THREE.MarchingCubes = function ( resolution, material, enableUvs, enableColors )
 
 			compNorm( q );
 			compNorm( q1 );
-			VIntX( q * 3, 0, isol, fx, fy, fz, field0, field1 );
+			VIntX( q * 3, 0, isol, fx, fy, fz, field0, field1, q, q1 );
 
 		}
 
@@ -203,7 +220,7 @@ THREE.MarchingCubes = function ( resolution, material, enableUvs, enableColors )
 
 			compNorm( q1 );
 			compNorm( q1y );
-			VIntY( q1 * 3, 3, isol, fx2, fy, fz, field1, field3 );
+			VIntY( q1 * 3, 3, isol, fx2, fy, fz, field1, field3, q1, q1y );
 
 		}
 
@@ -211,7 +228,7 @@ THREE.MarchingCubes = function ( resolution, material, enableUvs, enableColors )
 
 			compNorm( qy );
 			compNorm( q1y );
-			VIntX( qy * 3, 6, isol, fx, fy2, fz, field2, field3 );
+			VIntX( qy * 3, 6, isol, fx, fy2, fz, field2, field3, qy, q1y );
 
 		}
 
@@ -219,7 +236,7 @@ THREE.MarchingCubes = function ( resolution, material, enableUvs, enableColors )
 
 			compNorm( q );
 			compNorm( qy );
-			VIntY( q * 3, 9, isol, fx, fy, fz, field0, field2 );
+			VIntY( q * 3, 9, isol, fx, fy, fz, field0, field2, q, qy );
 
 		}
 
@@ -229,7 +246,7 @@ THREE.MarchingCubes = function ( resolution, material, enableUvs, enableColors )
 
 			compNorm( qz );
 			compNorm( q1z );
-			VIntX( qz * 3, 12, isol, fx, fy, fz2, field4, field5 );
+			VIntX( qz * 3, 12, isol, fx, fy, fz2, field4, field5, qz, q1z );
 
 		}
 
@@ -237,7 +254,18 @@ THREE.MarchingCubes = function ( resolution, material, enableUvs, enableColors )
 
 			compNorm( q1z );
 			compNorm( q1yz );
-			VIntY( q1z * 3, 15, isol, fx2, fy, fz2, field5, field7 );
+			VIntY(
+				q1z * 3,
+				15,
+				isol,
+				fx2,
+				fy,
+				fz2,
+				field5,
+				field7,
+				q1z,
+				q1yz
+			);
 
 		}
 
@@ -245,7 +273,18 @@ THREE.MarchingCubes = function ( resolution, material, enableUvs, enableColors )
 
 			compNorm( qyz );
 			compNorm( q1yz );
-			VIntX( qyz * 3, 18, isol, fx, fy2, fz2, field6, field7 );
+			VIntX(
+				qyz * 3,
+				18,
+				isol,
+				fx,
+				fy2,
+				fz2,
+				field6,
+				field7,
+				qyz,
+				q1yz
+			);
 
 		}
 
@@ -253,17 +292,16 @@ THREE.MarchingCubes = function ( resolution, material, enableUvs, enableColors )
 
 			compNorm( qz );
 			compNorm( qyz );
-			VIntY( qz * 3, 21, isol, fx, fy, fz2, field4, field6 );
+			VIntY( qz * 3, 21, isol, fx, fy, fz2, field4, field6, qz, qyz );
 
 		}
 
 		// vertical lines of the cube
-
 		if ( bits & 256 ) {
 
 			compNorm( q );
 			compNorm( qz );
-			VIntZ( q * 3, 24, isol, fx, fy, fz, field0, field4 );
+			VIntZ( q * 3, 24, isol, fx, fy, fz, field0, field4, q, qz );
 
 		}
 
@@ -271,7 +309,7 @@ THREE.MarchingCubes = function ( resolution, material, enableUvs, enableColors )
 
 			compNorm( q1 );
 			compNorm( q1z );
-			VIntZ( q1 * 3, 27, isol, fx2, fy, fz, field1, field5 );
+			VIntZ( q1 * 3, 27, isol, fx2, fy, fz, field1, field5, q1, q1z );
 
 		}
 
@@ -279,7 +317,18 @@ THREE.MarchingCubes = function ( resolution, material, enableUvs, enableColors )
 
 			compNorm( q1y );
 			compNorm( q1yz );
-			VIntZ( q1y * 3, 30, isol, fx2, fy2, fz, field3, field7 );
+			VIntZ(
+				q1y * 3,
+				30,
+				isol,
+				fx2,
+				fy2,
+				fz,
+				field3,
+				field7,
+				q1y,
+				q1yz
+			);
 
 		}
 
@@ -287,13 +336,17 @@ THREE.MarchingCubes = function ( resolution, material, enableUvs, enableColors )
 
 			compNorm( qy );
 			compNorm( qyz );
-			VIntZ( qy * 3, 33, isol, fx, fy2, fz, field2, field6 );
+			VIntZ( qy * 3, 33, isol, fx, fy2, fz, field2, field6, qy, qyz );
 
 		}
 
 		cubeindex <<= 4; // re-purpose cubeindex into an offset into triTable
 
-		var o1, o2, o3, numtris = 0, i = 0;
+		var o1,
+			o2,
+			o3,
+			numtris = 0,
+			i = 0;
 
 		// here is where triangles are created
 
@@ -303,11 +356,15 @@ THREE.MarchingCubes = function ( resolution, material, enableUvs, enableColors )
 			o2 = o1 + 1;
 			o3 = o1 + 2;
 
-			posnormtriv( vlist, nlist,
+			posnormtriv(
+				vlist,
+				nlist,
+				clist,
 				3 * THREE.triTable[ o1 ],
 				3 * THREE.triTable[ o2 ],
 				3 * THREE.triTable[ o3 ],
-				renderCallback );
+				renderCallback
+			);
 
 			i += 3;
 			numtris ++;
@@ -322,7 +379,7 @@ THREE.MarchingCubes = function ( resolution, material, enableUvs, enableColors )
 	// Immediate render mode simulator
 	/////////////////////////////////////
 
-	function posnormtriv( pos, norm, o1, o2, o3, renderCallback ) {
+	function posnormtriv( pos, norm, colors, o1, o2, o3, renderCallback ) {
 
 		var c = scope.count * 3;
 
@@ -360,7 +417,6 @@ THREE.MarchingCubes = function ( resolution, material, enableUvs, enableColors )
 			scope.normalArray[ c + 7 ] = ny;
 			scope.normalArray[ c + 8 ] = nz;
 
-
 		} else {
 
 			scope.normalArray[ c + 0 ] = norm[ o1 + 0 ];
@@ -398,17 +454,17 @@ THREE.MarchingCubes = function ( resolution, material, enableUvs, enableColors )
 
 		if ( scope.enableColors ) {
 
-			scope.colorArray[ c + 0 ] = pos[ o1 + 0 ];
-			scope.colorArray[ c + 1 ] = pos[ o1 + 1 ];
-			scope.colorArray[ c + 2 ] = pos[ o1 + 2 ];
+			scope.colorArray[ c + 0 ] = colors[ o1 + 0 ];
+			scope.colorArray[ c + 1 ] = colors[ o1 + 1 ];
+			scope.colorArray[ c + 2 ] = colors[ o1 + 2 ];
 
-			scope.colorArray[ c + 3 ] = pos[ o2 + 0 ];
-			scope.colorArray[ c + 4 ] = pos[ o2 + 1 ];
-			scope.colorArray[ c + 5 ] = pos[ o2 + 2 ];
+			scope.colorArray[ c + 3 ] = colors[ o2 + 0 ];
+			scope.colorArray[ c + 4 ] = colors[ o2 + 1 ];
+			scope.colorArray[ c + 5 ] = colors[ o2 + 2 ];
 
-			scope.colorArray[ c + 6 ] = pos[ o3 + 0 ];
-			scope.colorArray[ c + 7 ] = pos[ o3 + 1 ];
-			scope.colorArray[ c + 8 ] = pos[ o3 + 2 ];
+			scope.colorArray[ c + 6 ] = colors[ o3 + 0 ];
+			scope.colorArray[ c + 7 ] = colors[ o3 + 1 ];
+			scope.colorArray[ c + 8 ] = colors[ o3 + 2 ];
 
 		}
 
@@ -484,10 +540,35 @@ THREE.MarchingCubes = function ( resolution, material, enableUvs, enableColors )
 	// Adds a reciprocal ball (nice and blobby) that, to be fast, fades to zero after
 	// a fixed distance, determined by strength and subtract.
 
-	this.addBall = function ( ballx, bally, ballz, strength, subtract ) {
+	this.addBall = function ( ballx, bally, ballz, strength, subtract, colors ) {
 
 		var sign = Math.sign( strength );
 		strength = Math.abs( strength );
+		var userDefineColor = ! ( colors === undefined || colors === null );
+		var ballColor = new THREE.Color( ballx, bally, ballz );
+		if ( userDefineColor ) {
+
+			try {
+
+				ballColor =
+					colors instanceof THREE.Color
+						? colors
+						: Array.isArray( colors )
+							? new THREE.Color(
+								Math.min( Math.abs( colors[ 0 ] ), 1 ),
+								Math.min( Math.abs( colors[ 1 ] ), 1 ),
+								Math.min( Math.abs( colors[ 2 ] ), 1 )
+						  )
+							: new THREE.Color( colors );
+
+			} catch ( err ) {
+
+				userDefineColor = false;
+				ballColor = new THREE.Color( ballx, bally, ballz );
+
+			}
+
+		}
 
 		// Let's solve the equation to find the radius:
 		// 1.0 / (0.000001 + radius^2) * strength - subtract = 0
@@ -501,19 +582,23 @@ THREE.MarchingCubes = function ( resolution, material, enableUvs, enableColors )
 			ys = bally * this.size,
 			xs = ballx * this.size;
 
-		var min_z = Math.floor( zs - radius ); if ( min_z < 1 ) min_z = 1;
-		var max_z = Math.floor( zs + radius ); if ( max_z > this.size - 1 ) max_z = this.size - 1;
-		var min_y = Math.floor( ys - radius ); if ( min_y < 1 ) min_y = 1;
-		var max_y = Math.floor( ys + radius ); if ( max_y > this.size - 1 ) max_y = this.size - 1;
-		var min_x = Math.floor( xs - radius ); if ( min_x < 1 ) min_x = 1;
-		var max_x = Math.floor( xs + radius ); if ( max_x > this.size - 1 ) max_x = this.size - 1;
-
+		var min_z = Math.floor( zs - radius );
+		if ( min_z < 1 ) min_z = 1;
+		var max_z = Math.floor( zs + radius );
+		if ( max_z > this.size - 1 ) max_z = this.size - 1;
+		var min_y = Math.floor( ys - radius );
+		if ( min_y < 1 ) min_y = 1;
+		var max_y = Math.floor( ys + radius );
+		if ( max_y > this.size - 1 ) max_y = this.size - 1;
+		var min_x = Math.floor( xs - radius );
+		if ( min_x < 1 ) min_x = 1;
+		var max_x = Math.floor( xs + radius );
+		if ( max_x > this.size - 1 ) max_x = this.size - 1;
 
 		// Don't polygonize in the outer layer because normals aren't
 		// well-defined there.
 
 		var x, y, z, y_offset, z_offset, fx, fy, fz, fz2, fy2, val;
-
 		for ( z = min_z; z < max_z; z ++ ) {
 
 			z_offset = this.size2 * z;
@@ -530,7 +615,21 @@ THREE.MarchingCubes = function ( resolution, material, enableUvs, enableColors )
 
 					fx = x / this.size - ballx;
 					val = strength / ( 0.000001 + fx * fx + fy2 + fz2 ) - subtract;
-					if ( val > 0.0 ) this.field[ y_offset + x ] += val * sign;
+					if ( val > 0.0 ) {
+
+						this.field[ y_offset + x ] += val * sign;
+
+						// optimization
+						// http://www.geisswerks.com/ryan/BLOBS/blobs.html
+						const ratio =
+							Math.sqrt( ( x - xs ) * ( x - xs ) + ( y - ys ) * ( y - ys ) + ( z - zs ) * ( z - zs ) ) / radius;
+						const contrib =
+							1 - ratio * ratio * ratio * ( ratio * ( ratio * 6 - 15 ) + 10 );
+						this.palette[ ( y_offset + x ) * 3 + 0 ] += ballColor.r * contrib;
+						this.palette[ ( y_offset + x ) * 3 + 1 ] += ballColor.g * contrib;
+						this.palette[ ( y_offset + x ) * 3 + 2 ] += ballColor.b * contrib;
+
+					}
 
 				}
 
@@ -542,14 +641,18 @@ THREE.MarchingCubes = function ( resolution, material, enableUvs, enableColors )
 
 	this.addPlaneX = function ( strength, subtract ) {
 
-		var x, y, z, xx, val, xdiv, cxy,
-
+		var x,
+			y,
+			z,
+			xx,
+			val,
+			xdiv,
+			cxy,
 			// cache attribute lookups
 			size = this.size,
 			yd = this.yd,
 			zd = this.zd,
 			field = this.field,
-
 			dist = size * Math.sqrt( strength / subtract );
 
 		if ( dist > size ) dist = size;
@@ -582,14 +685,19 @@ THREE.MarchingCubes = function ( resolution, material, enableUvs, enableColors )
 
 	this.addPlaneY = function ( strength, subtract ) {
 
-		var x, y, z, yy, val, ydiv, cy, cxy,
-
+		var x,
+			y,
+			z,
+			yy,
+			val,
+			ydiv,
+			cy,
+			cxy,
 			// cache attribute lookups
 			size = this.size,
 			yd = this.yd,
 			zd = this.zd,
 			field = this.field,
-
 			dist = size * Math.sqrt( strength / subtract );
 
 		if ( dist > size ) dist = size;
@@ -608,8 +716,7 @@ THREE.MarchingCubes = function ( resolution, material, enableUvs, enableColors )
 
 					cxy = cy + x;
 
-					for ( z = 0; z < size; z ++ )
-						field[ zd * z + cxy ] += val;
+					for ( z = 0; z < size; z ++ ) field[ zd * z + cxy ] += val;
 
 				}
 
@@ -621,14 +728,19 @@ THREE.MarchingCubes = function ( resolution, material, enableUvs, enableColors )
 
 	this.addPlaneZ = function ( strength, subtract ) {
 
-		var x, y, z, zz, val, zdiv, cz, cyz,
-
+		var x,
+			y,
+			z,
+			zz,
+			val,
+			zdiv,
+			cz,
+			cyz,
 			// cache attribute lookups
 			size = this.size,
 			yd = this.yd,
 			zd = this.zd,
 			field = this.field,
-
 			dist = size * Math.sqrt( strength / subtract );
 
 		if ( dist > size ) dist = size;
@@ -646,8 +758,7 @@ THREE.MarchingCubes = function ( resolution, material, enableUvs, enableColors )
 
 					cyz = cz + y * yd;
 
-					for ( x = 0; x < size; x ++ )
-						field[ cyz + x ] += val;
+					for ( x = 0; x < size; x ++ ) field[ cyz + x ] += val;
 
 				}
 
@@ -671,6 +782,9 @@ THREE.MarchingCubes = function ( resolution, material, enableUvs, enableColors )
 
 			this.normal_cache[ i * 3 ] = 0.0;
 			this.field[ i ] = 0.0;
+			this.palette[ i * 3 ] = this.palette[ i * 3 + 1 ] = this.palette[
+				i * 3 + 2
+			] = 0.0;
 
 		}
 
@@ -713,7 +827,9 @@ THREE.MarchingCubes = function ( resolution, material, enableUvs, enableColors )
 
 	this.generateGeometry = function () {
 
-		console.warn( 'THREE.MarchingCubes: generateGeometry() now returns THREE.BufferGeometry' );
+		console.warn(
+			"THREE.MarchingCubes: generateGeometry() now returns THREE.BufferGeometry"
+		);
 		return this.generateBufferGeometry();
 
 	};
@@ -738,10 +854,26 @@ THREE.MarchingCubes = function ( resolution, material, enableUvs, enableColors )
 
 		var geo_callback = function ( object ) {
 
-			if ( scope.hasPositions ) posArray = concatenate( posArray, object.positionArray, object.count * 3 );
-			if ( scope.hasNormals ) normArray = concatenate( normArray, object.normalArray, object.count * 3 );
-			if ( scope.hasColors ) colorArray = concatenate( colorArray, object.colorArray, object.count * 3 );
-			if ( scope.hasUvs ) uvArray = concatenate( uvArray, object.uvArray, object.count * 2 );
+			if ( scope.hasPositions )
+				posArray = concatenate(
+					posArray,
+					object.positionArray,
+					object.count * 3
+				);
+			if ( scope.hasNormals )
+				normArray = concatenate(
+					normArray,
+					object.normalArray,
+					object.count * 3
+				);
+			if ( scope.hasColors )
+				colorArray = concatenate(
+					colorArray,
+					object.colorArray,
+					object.count * 3
+				);
+			if ( scope.hasUvs )
+				uvArray = concatenate( uvArray, object.uvArray, object.count * 2 );
 
 			object.count = 0;
 
@@ -749,10 +881,14 @@ THREE.MarchingCubes = function ( resolution, material, enableUvs, enableColors )
 
 		this.render( geo_callback );
 
-		if ( this.hasPositions ) geo.addAttribute( 'position', new THREE.BufferAttribute( posArray, 3 ) );
-		if ( this.hasNormals ) geo.addAttribute( 'normal', new THREE.BufferAttribute( normArray, 3 ) );
-		if ( this.hasColors ) geo.addAttribute( 'color', new THREE.BufferAttribute( colorArray, 3 ) );
-		if ( this.hasUvs ) geo.addAttribute( 'uv', new THREE.BufferAttribute( uvArray, 2 ) );
+		if ( this.hasPositions )
+			geo.addAttribute( "position", new THREE.BufferAttribute( posArray, 3 ) );
+		if ( this.hasNormals )
+			geo.addAttribute( "normal", new THREE.BufferAttribute( normArray, 3 ) );
+		if ( this.hasColors )
+			geo.addAttribute( "color", new THREE.BufferAttribute( colorArray, 3 ) );
+		if ( this.hasUvs )
+			geo.addAttribute( "uv", new THREE.BufferAttribute( uvArray, 2 ) );
 
 		return geo;
 

+ 2 - 2
examples/js/loaders/ColladaLoader.js

@@ -1506,7 +1506,7 @@ THREE.ColladaLoader.prototype = {
 
 			}
 
-			material.name = data.name;
+			material.name = data.name || '';
 
 			function getTexture( textureObject ) {
 
@@ -1834,7 +1834,7 @@ THREE.ColladaLoader.prototype = {
 
 			}
 
-			camera.name = data.name;
+			camera.name = data.name || '';
 
 			return camera;
 

+ 22 - 7
examples/js/loaders/FBXLoader.js

@@ -499,7 +499,7 @@ THREE.FBXLoader = ( function () {
 					break;
 				default:
 					console.warn( 'THREE.FBXLoader: unknown material type "%s". Defaulting to MeshPhongMaterial.', type );
-					material = new THREE.MeshPhongMaterial( { color: 0x3300ff } );
+					material = new THREE.MeshPhongMaterial();
 					break;
 
 			}
@@ -532,11 +532,13 @@ THREE.FBXLoader = ( function () {
 				parameters.color = new THREE.Color().fromArray( materialNode.DiffuseColor.value );
 
 			}
+
 			if ( materialNode.DisplacementFactor ) {
 
 				parameters.displacementScale = materialNode.DisplacementFactor.value;
 
 			}
+
 			if ( materialNode.Emissive ) {
 
 				parameters.emissive = new THREE.Color().fromArray( materialNode.Emissive.value );
@@ -547,31 +549,37 @@ THREE.FBXLoader = ( function () {
 				parameters.emissive = new THREE.Color().fromArray( materialNode.EmissiveColor.value );
 
 			}
+
 			if ( materialNode.EmissiveFactor ) {
 
 				parameters.emissiveIntensity = parseFloat( materialNode.EmissiveFactor.value );
 
 			}
+
 			if ( materialNode.Opacity ) {
 
 				parameters.opacity = parseFloat( materialNode.Opacity.value );
 
 			}
+
 			if ( parameters.opacity < 1.0 ) {
 
 				parameters.transparent = true;
 
 			}
+
 			if ( materialNode.ReflectionFactor ) {
 
 				parameters.reflectivity = materialNode.ReflectionFactor.value;
 
 			}
+
 			if ( materialNode.Shininess ) {
 
 				parameters.shininess = materialNode.Shininess.value;
 
 			}
+
 			if ( materialNode.Specular ) {
 
 				parameters.specular = new THREE.Color().fromArray( materialNode.Specular.value );
@@ -594,7 +602,12 @@ THREE.FBXLoader = ( function () {
 						parameters.bumpMap = self.getTexture( textureMap, child.ID );
 						break;
 
+					case 'Maya|TEX_ao_map':
+						parameters.aoMap = self.getTexture( textureMap, child.ID );
+						break;
+
 					case 'DiffuseColor':
+					case 'Maya|TEX_color_map':
 						parameters.map = self.getTexture( textureMap, child.ID );
 						break;
 
@@ -602,12 +615,12 @@ THREE.FBXLoader = ( function () {
 						parameters.displacementMap = self.getTexture( textureMap, child.ID );
 						break;
 
-
 					case 'EmissiveColor':
 						parameters.emissiveMap = self.getTexture( textureMap, child.ID );
 						break;
 
 					case 'NormalMap':
+					case 'Maya|TEX_normal_map':
 						parameters.normalMap = self.getTexture( textureMap, child.ID );
 						break;
 
@@ -2336,15 +2349,17 @@ THREE.FBXLoader = ( function () {
 
 			var rawClips = this.parseClips();
 
-			if ( rawClips === undefined ) return;
+			if ( rawClips !== undefined ) {
+
+				for ( var key in rawClips ) {
 
-			for ( var key in rawClips ) {
+					var rawClip = rawClips[ key ];
 
-				var rawClip = rawClips[ key ];
+					var clip = this.addClip( rawClip );
 
-				var clip = this.addClip( rawClip );
+					animationClips.push( clip );
 
-				animationClips.push( clip );
+				}
 
 			}
 

+ 205 - 432
examples/js/loaders/GLTFLoader.js

@@ -218,23 +218,7 @@ THREE.GLTFLoader = ( function () {
 
 			} );
 
-			parser.parse( function ( scene, scenes, cameras, animations, json ) {
-
-				var glTF = {
-					scene: scene,
-					scenes: scenes,
-					cameras: cameras,
-					animations: animations,
-					asset: json.asset,
-					parser: parser,
-					userData: {}
-				};
-
-				addUnknownExtensionsToUserData( extensions, glTF, json );
-
-				onLoad( glTF );
-
-			}, onError );
+			parser.parse( onLoad, onError );
 
 		}
 
@@ -528,21 +512,23 @@ THREE.GLTFLoader = ( function () {
 
 		for ( var attributeName in gltfAttributeMap ) {
 
-			if ( ! ( attributeName in ATTRIBUTES ) ) continue;
+			var threeAttributeName = ATTRIBUTES[ attributeName ] || attributeName.toLowerCase();
 
-			threeAttributeMap[ ATTRIBUTES[ attributeName ] ] = gltfAttributeMap[ attributeName ];
+			threeAttributeMap[ threeAttributeName ] = gltfAttributeMap[ attributeName ];
 
 		}
 
 		for ( attributeName in primitive.attributes ) {
 
-			if ( ATTRIBUTES[ attributeName ] !== undefined && gltfAttributeMap[ attributeName ] !== undefined ) {
+			var threeAttributeName = ATTRIBUTES[ attributeName ] || attributeName.toLowerCase();
+
+			if ( gltfAttributeMap[ attributeName ] !== undefined ) {
 
 				var accessorDef = json.accessors[ primitive.attributes[ attributeName ] ];
 				var componentType = WEBGL_COMPONENT_TYPES[ accessorDef.componentType ];
 
-				attributeTypeMap[ ATTRIBUTES[ attributeName ] ] = componentType;
-				attributeNormalizedMap[ ATTRIBUTES[ attributeName ] ] = accessorDef.normalized === true;
+				attributeTypeMap[ threeAttributeName ] = componentType;
+				attributeNormalizedMap[ threeAttributeName ] = accessorDef.normalized === true;
 
 			}
 
@@ -1218,10 +1204,8 @@ THREE.GLTFLoader = ( function () {
 	};
 
 	var INTERPOLATION = {
-		CUBICSPLINE: THREE.InterpolateSmooth, // We use custom interpolation GLTFCubicSplineInterpolation for CUBICSPLINE.
-		                                      // KeyframeTrack.optimize() can't handle glTF Cubic Spline output values layout,
-		                                      // using THREE.InterpolateSmooth for KeyframeTrack instantiation to prevent optimization.
-		                                      // See KeyframeTrack.optimize() for the detail.
+		CUBICSPLINE: undefined, // We use a custom interpolant (GLTFCubicSplineInterpolation) for CUBICSPLINE tracks. Each
+		                        // keyframe track will be initialized with a default interpolation type, then modified.
 		LINEAR: THREE.InterpolateLinear,
 		STEP: THREE.InterpolateDiscrete
 	};
@@ -1267,12 +1251,14 @@ THREE.GLTFLoader = ( function () {
 
 	}
 
+	var defaultMaterial;
+
 	/**
 	 * Specification: https://github.com/KhronosGroup/glTF/blob/master/specification/2.0/README.md#default-material
 	 */
 	function createDefaultMaterial() {
 
-		return new THREE.MeshStandardMaterial( {
+		defaultMaterial = defaultMaterial || new THREE.MeshStandardMaterial( {
 			color: 0xFFFFFF,
 			emissive: 0x000000,
 			metalness: 1,
@@ -1282,6 +1268,8 @@ THREE.GLTFLoader = ( function () {
 			side: THREE.FrontSide
 		} );
 
+		return defaultMaterial;
+
 	}
 
 	function addUnknownExtensionsToUserData( knownExtensions, object, objectDef ) {
@@ -1358,30 +1346,21 @@ THREE.GLTFLoader = ( function () {
 
 			if ( hasMorphPosition ) {
 
-				// TODO: Error-prone use of a callback inside a loop.
-				var accessor = target.POSITION !== undefined
+				var pendingAccessor = target.POSITION !== undefined
 					? parser.getDependency( 'accessor', target.POSITION )
-						.then( function ( accessor ) {
-							// Cloning not to pollute original accessor below
-							return cloneBufferAttribute( accessor );
-						} )
 					: geometry.attributes.position;
 
-				pendingPositionAccessors.push( accessor );
+				pendingPositionAccessors.push( pendingAccessor );
 
 			}
 
 			if ( hasMorphNormal ) {
 
-				// TODO: Error-prone use of a callback inside a loop.
-				var accessor = target.NORMAL !== undefined
+				var pendingAccessor = target.NORMAL !== undefined
 					? parser.getDependency( 'accessor', target.NORMAL )
-						.then( function ( accessor ) {
-							return cloneBufferAttribute( accessor );
-						} )
 					: geometry.attributes.normal;
 
-				pendingNormalAccessors.push( accessor );
+				pendingNormalAccessors.push( pendingAccessor );
 
 			}
 
@@ -1395,6 +1374,24 @@ THREE.GLTFLoader = ( function () {
 			var morphPositions = accessors[ 0 ];
 			var morphNormals = accessors[ 1 ];
 
+			// Clone morph target accessors before modifying them.
+
+			for ( var i = 0, il = morphPositions.length; i < il; i ++ ) {
+
+				if ( geometry.attributes.position === morphPositions[ i ] ) continue;
+
+				morphPositions[ i ] = cloneBufferAttribute( morphPositions[ i ] );
+
+			}
+
+			for ( var i = 0, il = morphNormals.length; i < il; i ++ ) {
+
+				if ( geometry.attributes.normal === morphNormals[ i ] ) continue;
+
+				morphNormals[ i ] = cloneBufferAttribute( morphNormals[ i ] );
+
+			}
+
 			for ( var i = 0, il = targets.length; i < il; i ++ ) {
 
 				var target = targets[ i ];
@@ -1515,30 +1512,6 @@ THREE.GLTFLoader = ( function () {
 		}
 
 	}
-
-	function isPrimitiveEqual( a, b ) {
-
-		var dracoExtA = a.extensions ? a.extensions[ EXTENSIONS.KHR_DRACO_MESH_COMPRESSION ] : undefined;
-		var dracoExtB = b.extensions ? b.extensions[ EXTENSIONS.KHR_DRACO_MESH_COMPRESSION ] : undefined;
-
-		if ( dracoExtA && dracoExtB ) {
-
-			if ( dracoExtA.bufferView !== dracoExtB.bufferView ) return false;
-
-			return isObjectEqual( dracoExtA.attributes, dracoExtB.attributes );
-
-		}
-
-		if ( a.indices !== b.indices ) {
-
-			return false;
-
-		}
-
-		return isObjectEqual( a.attributes, b.attributes );
-
-	}
-
 	function isObjectEqual( a, b ) {
 
 		if ( Object.keys( a ).length !== Object.keys( b ).length ) return false;
@@ -1553,59 +1526,40 @@ THREE.GLTFLoader = ( function () {
 
 	}
 
-	function isArrayEqual( a, b ) {
+	function createPrimitiveKey( primitiveDef ) {
 
-		if ( a.length !== b.length ) return false;
+		var dracoExtension = primitiveDef.extensions && primitiveDef.extensions[ EXTENSIONS.KHR_DRACO_MESH_COMPRESSION ];
+		var geometryKey;
 
-		for ( var i = 0, il = a.length; i < il; i ++ ) {
+		if ( dracoExtension ) {
 
-			if ( a[ i ] !== b[ i ] ) return false;
+			geometryKey = 'draco:' + dracoExtension.bufferView
+				+ ':' + dracoExtension.indices
+				+ ':' + createAttributesKey( dracoExtension.attributes );
 
-		}
-
-		return true;
-
-	}
-
-	function getCachedGeometry( cache, newPrimitive ) {
-
-		for ( var i = 0, il = cache.length; i < il; i ++ ) {
-
-			var cached = cache[ i ];
+		} else {
 
-			if ( isPrimitiveEqual( cached.primitive, newPrimitive ) ) return cached.promise;
+			geometryKey = primitiveDef.indices + ':' + createAttributesKey( primitiveDef.attributes ) + ':' + primitiveDef.mode;
 
 		}
 
-		return null;
+		return geometryKey;
 
 	}
 
-	function getCachedCombinedGeometry( cache, geometries ) {
-
-		for ( var i = 0, il = cache.length; i < il; i ++ ) {
-
-			var cached = cache[ i ];
-
-			if ( isArrayEqual( geometries, cached.baseGeometries ) ) return cached.geometry;
-
-		}
-
-		return null;
-
-	}
+	function createAttributesKey( attributes ) {
 
-	function getCachedMultiPassGeometry( cache, geometry, primitives ) {
+		var attributesKey = '';
 
-		for ( var i = 0, il = cache.length; i < il; i ++ ) {
+		var keys = Object.keys( attributes ).sort();
 
-			var cached = cache[ i ];
+		for ( var i = 0, il = keys.length; i < il; i ++ ) {
 
-			if ( geometry === cached.baseGeometry && isArrayEqual( primitives, cached.primitives ) ) return cached.geometry;
+			attributesKey += keys[ i ] + ':' + attributes[ keys[ i ] ] + ';';
 
 		}
 
-		return null;
+		return attributesKey;
 
 	}
 
@@ -1634,48 +1588,6 @@ THREE.GLTFLoader = ( function () {
 
 	}
 
-	/**
-	 * Checks if we can build a single Mesh with MultiMaterial from multiple primitives.
-	 * Returns true if all primitives use the same attributes/morphAttributes/mode
-	 * and also have index. Otherwise returns false.
-	 *
-	 * @param {Array<GLTF.Primitive>} primitives
-	 * @return {Boolean}
-	 */
-	function isMultiPassGeometry( primitives ) {
-
-		if ( primitives.length < 2 ) return false;
-
-		var primitive0 = primitives[ 0 ];
-		var targets0 = primitive0.targets || [];
-
-		if ( primitive0.indices === undefined ) return false;
-
-		for ( var i = 1, il = primitives.length; i < il; i ++ ) {
-
-			var primitive = primitives[ i ];
-
-			if ( primitive0.mode !== primitive.mode ) return false;
-			if ( primitive.indices === undefined ) return false;
-			if ( primitive.extensions && primitive.extensions[ EXTENSIONS.KHR_DRACO_MESH_COMPRESSION ] ) return false;
-			if ( ! isObjectEqual( primitive0.attributes, primitive.attributes ) ) return false;
-
-			var targets = primitive.targets || [];
-
-			if ( targets0.length !== targets.length ) return false;
-
-			for ( var j = 0, jl = targets0.length; j < jl; j ++ ) {
-
-				if ( ! isObjectEqual( targets0[ j ], targets[ j ] ) ) return false;
-
-			}
-
-		}
-
-		return true;
-
-	}
-
 	/* GLTF PARSER */
 
 	function GLTFParser( json, extensions, options ) {
@@ -1688,9 +1600,7 @@ THREE.GLTFLoader = ( function () {
 		this.cache = new GLTFRegistry();
 
 		// BufferGeometry caching
-		this.primitiveCache = [];
-		this.multiplePrimitivesCache = [];
-		this.multiPassGeometryCache = [];
+		this.primitiveCache = {};
 
 		this.textureLoader = new THREE.TextureLoader( this.options.manager );
 		this.textureLoader.setCrossOrigin( this.options.crossOrigin );
@@ -1702,7 +1612,9 @@ THREE.GLTFLoader = ( function () {
 
 	GLTFParser.prototype.parse = function ( onLoad, onError ) {
 
+		var parser = this;
 		var json = this.json;
+		var extensions = this.extensions;
 
 		// Clear the loader cache
 		this.cache.removeAll();
@@ -1710,21 +1622,27 @@ THREE.GLTFLoader = ( function () {
 		// Mark the special nodes/meshes in json for efficient parse
 		this.markDefs();
 
-		// Fire the callback on complete
-		this.getMultiDependencies( [
+		Promise.all( [
 
-			'scene',
-			'animation',
-			'camera'
+			this.getDependencies( 'scene' ),
+			this.getDependencies( 'animation' ),
+			this.getDependencies( 'camera' ),
 
 		] ).then( function ( dependencies ) {
 
-			var scenes = dependencies.scenes || [];
-			var scene = scenes[ json.scene || 0 ];
-			var animations = dependencies.animations || [];
-			var cameras = dependencies.cameras || [];
+			var result = {
+				scene: dependencies[ 0 ][ json.scene || 0 ],
+				scenes: dependencies[ 0 ],
+				animations: dependencies[ 1 ],
+				cameras: dependencies[ 2 ],
+				asset: json.asset,
+				parser: parser,
+				userData: {}
+			};
+
+			addUnknownExtensionsToUserData( extensions, result, json );
 
-			onLoad( scene, scenes, cameras, animations, json );
+			onLoad( result );
 
 		} ).catch( onError );
 
@@ -1897,40 +1815,6 @@ THREE.GLTFLoader = ( function () {
 
 	};
 
-	/**
-	 * Requests all multiple dependencies of the specified types asynchronously, with caching.
-	 * @param {Array<string>} types
-	 * @return {Promise<Object<Array<Object>>>}
-	 */
-	GLTFParser.prototype.getMultiDependencies = function ( types ) {
-
-		var results = {};
-		var pending = [];
-
-		for ( var i = 0, il = types.length; i < il; i ++ ) {
-
-			var type = types[ i ];
-			var value = this.getDependencies( type );
-
-			// TODO: Error-prone use of a callback inside a loop.
-			value = value.then( function ( key, value ) {
-
-				results[ key ] = value;
-
-			}.bind( this, type + ( type === 'mesh' ? 'es' : 's' ) ) );
-
-			pending.push( value );
-
-		}
-
-		return Promise.all( pending ).then( function () {
-
-			return results;
-
-		} );
-
-	};
-
 	/**
 	 * Specification: https://github.com/KhronosGroup/glTF/blob/master/specification/2.0/README.md#buffers-and-buffer-views
 	 * @param {number} bufferIndex
@@ -2263,6 +2147,124 @@ THREE.GLTFLoader = ( function () {
 
 	};
 
+	/**
+	 * Assigns final material to a Mesh, Line, or Points instance. The instance
+	 * already has a material (generated from the glTF material options alone)
+	 * but reuse of the same glTF material may require multiple threejs materials
+	 * to accomodate different primitive types, defines, etc. New materials will
+	 * be created if necessary, and reused from a cache.
+	 * @param  {THREE.Object3D} mesh Mesh, Line, or Points instance.
+	 */
+	GLTFParser.prototype.assignFinalMaterial = function ( mesh ) {
+
+		var geometry = mesh.geometry;
+		var material = mesh.material;
+		var extensions = this.extensions;
+
+		var useVertexTangents = geometry.attributes.tangent !== undefined;
+		var useVertexColors = geometry.attributes.color !== undefined;
+		var useFlatShading = geometry.attributes.normal === undefined;
+		var useSkinning = mesh.isSkinnedMesh === true;
+		var useMorphTargets = Object.keys( geometry.morphAttributes ).length > 0;
+		var useMorphNormals = useMorphTargets && geometry.morphAttributes.normal !== undefined;
+
+		if ( mesh.isPoints ) {
+
+			var cacheKey = 'PointsMaterial:' + material.uuid;
+
+			var pointsMaterial = this.cache.get( cacheKey );
+
+			if ( ! pointsMaterial ) {
+
+				pointsMaterial = new THREE.PointsMaterial();
+				THREE.Material.prototype.copy.call( pointsMaterial, material );
+				pointsMaterial.color.copy( material.color );
+				pointsMaterial.map = material.map;
+				pointsMaterial.lights = false; // PointsMaterial doesn't support lights yet
+
+				this.cache.add( cacheKey, pointsMaterial );
+
+			}
+
+			material = pointsMaterial;
+
+		} else if ( mesh.isLine ) {
+
+			var cacheKey = 'LineBasicMaterial:' + material.uuid;
+
+			var lineMaterial = this.cache.get( cacheKey );
+
+			if ( ! lineMaterial ) {
+
+				lineMaterial = new THREE.LineBasicMaterial();
+				THREE.Material.prototype.copy.call( lineMaterial, material );
+				lineMaterial.color.copy( material.color );
+				lineMaterial.lights = false; // LineBasicMaterial doesn't support lights yet
+
+				this.cache.add( cacheKey, lineMaterial );
+
+			}
+
+			material = lineMaterial;
+
+		}
+
+		// Clone the material if it will be modified
+		if ( useVertexTangents || useVertexColors || useFlatShading || useSkinning || useMorphTargets ) {
+
+			var cacheKey = 'ClonedMaterial:' + material.uuid + ':';
+
+			if ( material.isGLTFSpecularGlossinessMaterial ) cacheKey += 'specular-glossiness:';
+			if ( useSkinning ) cacheKey += 'skinning:';
+			if ( useVertexTangents ) cacheKey += 'vertex-tangents:';
+			if ( useVertexColors ) cacheKey += 'vertex-colors:';
+			if ( useFlatShading ) cacheKey += 'flat-shading:';
+			if ( useMorphTargets ) cacheKey += 'morph-targets:';
+			if ( useMorphNormals ) cacheKey += 'morph-normals:';
+
+			var cachedMaterial = this.cache.get( cacheKey );
+
+			if ( ! cachedMaterial ) {
+
+				cachedMaterial = material.isGLTFSpecularGlossinessMaterial
+					? extensions[ EXTENSIONS.KHR_MATERIALS_PBR_SPECULAR_GLOSSINESS ].cloneMaterial( material )
+					: material.clone();
+
+				if ( useSkinning ) cachedMaterial.skinning = true;
+				if ( useVertexTangents ) cachedMaterial.vertexTangents = true;
+				if ( useVertexColors ) cachedMaterial.vertexColors = THREE.VertexColors;
+				if ( useFlatShading ) cachedMaterial.flatShading = true;
+				if ( useMorphTargets ) cachedMaterial.morphTargets = true;
+				if ( useMorphNormals ) cachedMaterial.morphNormals = true;
+
+				this.cache.add( cacheKey, cachedMaterial );
+
+			}
+
+			material = cachedMaterial;
+
+		}
+
+		// workarounds for mesh and geometry
+
+		if ( material.aoMap && geometry.attributes.uv2 === undefined && geometry.attributes.uv !== undefined ) {
+
+			console.log( 'THREE.GLTFLoader: Duplicating UVs to support aoMap.' );
+			geometry.addAttribute( 'uv2', new THREE.BufferAttribute( geometry.attributes.uv.array, 2 ) );
+
+		}
+
+		if ( material.isGLTFSpecularGlossinessMaterial ) {
+
+			// for GLTFSpecularGlossinessMaterial(ShaderMaterial) uniforms runtime update
+			mesh.onBeforeRender = extensions[ EXTENSIONS.KHR_MATERIALS_PBR_SPECULAR_GLOSSINESS ].refreshUniforms;
+
+		}
+
+		mesh.material = material;
+
+	};
+
 	/**
 	 * Specification: https://github.com/KhronosGroup/glTF/blob/master/specification/2.0/README.md#materials
 	 * @param {number} materialIndex
@@ -2450,9 +2452,7 @@ THREE.GLTFLoader = ( function () {
 
 		for ( var gltfAttributeName in attributes ) {
 
-			var threeAttributeName = ATTRIBUTES[ gltfAttributeName ];
-
-			if ( ! threeAttributeName ) continue;
+			var threeAttributeName = ATTRIBUTES[ gltfAttributeName ] || gltfAttributeName.toLowerCase();
 
 			// Skip attributes already provided by e.g. Draco extension.
 			if ( threeAttributeName in geometry.attributes ) continue;
@@ -2489,8 +2489,6 @@ THREE.GLTFLoader = ( function () {
 	 * Specification: https://github.com/KhronosGroup/glTF/blob/master/specification/2.0/README.md#geometry
 	 *
 	 * Creates BufferGeometries from primitives.
-	 * If we can build a single BufferGeometry with .groups from multiple primitives, returns one BufferGeometry.
-	 * Otherwise, returns BufferGeometries without .groups as many as primitives.
 	 *
 	 * @param {Array<GLTF.Primitive>} primitives
 	 * @return {Promise<Array<THREE.BufferGeometry>>}
@@ -2501,22 +2499,6 @@ THREE.GLTFLoader = ( function () {
 		var extensions = this.extensions;
 		var cache = this.primitiveCache;
 
-		var isMultiPass = isMultiPassGeometry( primitives );
-		var originalPrimitives;
-
-		if ( isMultiPass ) {
-
-			originalPrimitives = primitives; // save original primitives and use later
-
-			// We build a single BufferGeometry with .groups from multiple primitives
-			// because all primitives share the same attributes/morph/mode and have indices.
-
-			primitives = [ primitives[ 0 ] ];
-
-			// Sets .groups and combined indices to a geometry later in this method.
-
-		}
-
 		function createDracoPrimitive( primitive ) {
 
 			return extensions[ EXTENSIONS.KHR_DRACO_MESH_COMPRESSION ]
@@ -2534,14 +2516,15 @@ THREE.GLTFLoader = ( function () {
 		for ( var i = 0, il = primitives.length; i < il; i ++ ) {
 
 			var primitive = primitives[ i ];
+			var cacheKey = createPrimitiveKey( primitive );
 
 			// See if we've already created this geometry
-			var cached = getCachedGeometry( cache, primitive );
+			var cached = cache[ cacheKey ];
 
 			if ( cached ) {
 
 				// Use the cached geometry if it exists
-				pending.push( cached );
+				pending.push( cached.promise );
 
 			} else {
 
@@ -2560,7 +2543,7 @@ THREE.GLTFLoader = ( function () {
 				}
 
 				// Cache this geometry
-				cache.push( { primitive: primitive, promise: geometryPromise } );
+				cache[ cacheKey ] = { primitive: primitive, promise: geometryPromise };
 
 				pending.push( geometryPromise );
 
@@ -2568,95 +2551,7 @@ THREE.GLTFLoader = ( function () {
 
 		}
 
-		return Promise.all( pending ).then( function ( geometries ) {
-
-			if ( isMultiPass ) {
-
-				var baseGeometry = geometries[ 0 ];
-
-				// See if we've already created this combined geometry
-				var cache = parser.multiPassGeometryCache;
-				var cached = getCachedMultiPassGeometry( cache, baseGeometry, originalPrimitives );
-
-				if ( cached !== null ) return [ cached.geometry ];
-
-				// Cloning geometry because of index override.
-				// Attributes can be reused so cloning by myself here.
-				var geometry = new THREE.BufferGeometry();
-
-				geometry.name = baseGeometry.name;
-				geometry.userData = baseGeometry.userData;
-
-				for ( var key in baseGeometry.attributes ) geometry.addAttribute( key, baseGeometry.attributes[ key ] );
-				for ( var key in baseGeometry.morphAttributes ) geometry.morphAttributes[ key ] = baseGeometry.morphAttributes[ key ];
-
-				var pendingIndices = [];
-
-				for ( var i = 0, il = originalPrimitives.length; i < il; i ++ ) {
-
-					pendingIndices.push( parser.getDependency( 'accessor', originalPrimitives[ i ].indices ) );
-
-				}
-
-				return Promise.all( pendingIndices ).then( function ( accessors ) {
-
-					var indices = [];
-					var offset = 0;
-
-					for ( var i = 0, il = originalPrimitives.length; i < il; i ++ ) {
-
-						var accessor = accessors[ i ];
-
-						for ( var j = 0, jl = accessor.count; j < jl; j ++ ) indices.push( accessor.array[ j ] );
-
-						geometry.addGroup( offset, accessor.count, i );
-
-						offset += accessor.count;
-
-					}
-
-					geometry.setIndex( indices );
-
-					cache.push( { geometry: geometry, baseGeometry: baseGeometry, primitives: originalPrimitives } );
-
-					return [ geometry ];
-
-				} );
-
-			} else if ( geometries.length > 1 && THREE.BufferGeometryUtils !== undefined ) {
-
-				// Tries to merge geometries with BufferGeometryUtils if possible
-
-				for ( var i = 1, il = primitives.length; i < il; i ++ ) {
-
-					// can't merge if draw mode is different
-					if ( primitives[ 0 ].mode !== primitives[ i ].mode ) return geometries;
-
-				}
-
-				// See if we've already created this combined geometry
-				var cache = parser.multiplePrimitivesCache;
-				var cached = getCachedCombinedGeometry( cache, geometries );
-
-				if ( cached ) {
-
-					if ( cached.geometry !== null ) return [ cached.geometry ];
-
-				} else {
-
-					var geometry = THREE.BufferGeometryUtils.mergeBufferGeometries( geometries, true );
-
-					cache.push( { geometry: geometry, baseGeometries: geometries } );
-
-					if ( geometry !== null ) return [ geometry ];
-
-				}
-
-			}
-
-			return geometries;
-
-		} );
+		return Promise.all( pending );
 
 	};
 
@@ -2690,8 +2585,6 @@ THREE.GLTFLoader = ( function () {
 
 			return parser.loadGeometries( primitives ).then( function ( geometries ) {
 
-				var isMultiMaterial = geometries.length === 1 && geometries[ 0 ].groups.length > 0;
-
 				var meshes = [];
 
 				for ( var i = 0, il = geometries.length; i < il; i ++ ) {
@@ -2703,7 +2596,7 @@ THREE.GLTFLoader = ( function () {
 
 					var mesh;
 
-					var material = isMultiMaterial ? originalMaterials : originalMaterials[ i ];
+					var material = originalMaterials[ i ];
 
 					if ( primitive.mode === WEBGL_CONSTANTS.TRIANGLES ||
 						primitive.mode === WEBGL_CONSTANTS.TRIANGLE_STRIP ||
@@ -2761,121 +2654,9 @@ THREE.GLTFLoader = ( function () {
 
 					assignExtrasToUserData( mesh, meshDef );
 
-					meshes.push( mesh );
-
-					// 2. update Material depending on Mesh and BufferGeometry
-
-					var materials = isMultiMaterial ? mesh.material : [ mesh.material ];
-
-					var useVertexTangents = geometry.attributes.tangent !== undefined;
-					var useVertexColors = geometry.attributes.color !== undefined;
-					var useFlatShading = geometry.attributes.normal === undefined;
-					var useSkinning = mesh.isSkinnedMesh === true;
-					var useMorphTargets = Object.keys( geometry.morphAttributes ).length > 0;
-					var useMorphNormals = useMorphTargets && geometry.morphAttributes.normal !== undefined;
-
-					for ( var j = 0, jl = materials.length; j < jl; j ++ ) {
-
-						var material = materials[ j ];
+					parser.assignFinalMaterial( mesh );
 
-						if ( mesh.isPoints ) {
-
-							var cacheKey = 'PointsMaterial:' + material.uuid;
-
-							var pointsMaterial = parser.cache.get( cacheKey );
-
-							if ( ! pointsMaterial ) {
-
-								pointsMaterial = new THREE.PointsMaterial();
-								THREE.Material.prototype.copy.call( pointsMaterial, material );
-								pointsMaterial.color.copy( material.color );
-								pointsMaterial.map = material.map;
-								pointsMaterial.lights = false; // PointsMaterial doesn't support lights yet
-
-								parser.cache.add( cacheKey, pointsMaterial );
-
-							}
-
-							material = pointsMaterial;
-
-						} else if ( mesh.isLine ) {
-
-							var cacheKey = 'LineBasicMaterial:' + material.uuid;
-
-							var lineMaterial = parser.cache.get( cacheKey );
-
-							if ( ! lineMaterial ) {
-
-								lineMaterial = new THREE.LineBasicMaterial();
-								THREE.Material.prototype.copy.call( lineMaterial, material );
-								lineMaterial.color.copy( material.color );
-								lineMaterial.lights = false; // LineBasicMaterial doesn't support lights yet
-
-								parser.cache.add( cacheKey, lineMaterial );
-
-							}
-
-							material = lineMaterial;
-
-						}
-
-						// Clone the material if it will be modified
-						if ( useVertexTangents || useVertexColors || useFlatShading || useSkinning || useMorphTargets ) {
-
-							var cacheKey = 'ClonedMaterial:' + material.uuid + ':';
-
-							if ( material.isGLTFSpecularGlossinessMaterial ) cacheKey += 'specular-glossiness:';
-							if ( useSkinning ) cacheKey += 'skinning:';
-							if ( useVertexTangents ) cacheKey += 'vertex-tangents:';
-							if ( useVertexColors ) cacheKey += 'vertex-colors:';
-							if ( useFlatShading ) cacheKey += 'flat-shading:';
-							if ( useMorphTargets ) cacheKey += 'morph-targets:';
-							if ( useMorphNormals ) cacheKey += 'morph-normals:';
-
-							var cachedMaterial = parser.cache.get( cacheKey );
-
-							if ( ! cachedMaterial ) {
-
-								cachedMaterial = material.isGLTFSpecularGlossinessMaterial
-									? extensions[ EXTENSIONS.KHR_MATERIALS_PBR_SPECULAR_GLOSSINESS ].cloneMaterial( material )
-									: material.clone();
-
-								if ( useSkinning ) cachedMaterial.skinning = true;
-								if ( useVertexTangents ) cachedMaterial.vertexTangents = true;
-								if ( useVertexColors ) cachedMaterial.vertexColors = THREE.VertexColors;
-								if ( useFlatShading ) cachedMaterial.flatShading = true;
-								if ( useMorphTargets ) cachedMaterial.morphTargets = true;
-								if ( useMorphNormals ) cachedMaterial.morphNormals = true;
-
-								parser.cache.add( cacheKey, cachedMaterial );
-
-							}
-
-							material = cachedMaterial;
-
-						}
-
-						materials[ j ] = material;
-
-						// workarounds for mesh and geometry
-
-						if ( material.aoMap && geometry.attributes.uv2 === undefined && geometry.attributes.uv !== undefined ) {
-
-							console.log( 'THREE.GLTFLoader: Duplicating UVs to support aoMap.' );
-							geometry.addAttribute( 'uv2', new THREE.BufferAttribute( geometry.attributes.uv.array, 2 ) );
-
-						}
-
-						if ( material.isGLTFSpecularGlossinessMaterial ) {
-
-							// for GLTFSpecularGlossinessMaterial(ShaderMaterial) uniforms runtime update
-							mesh.onBeforeRender = extensions[ EXTENSIONS.KHR_MATERIALS_PBR_SPECULAR_GLOSSINESS ].refreshUniforms;
-
-						}
-
-					}
-
-					mesh.material = isMultiMaterial ? materials : materials[ 0 ];
+					meshes.push( mesh );
 
 				}
 
@@ -3060,10 +2841,7 @@ THREE.GLTFLoader = ( function () {
 
 				if ( PATH_PROPERTIES[ target.path ] === PATH_PROPERTIES.weights ) {
 
-					// node can be THREE.Group here but
-					// PATH_PROPERTIES.weights(morphTargetInfluences) should be
-					// the property of a mesh object under group.
-
+					// Node may be a THREE.Group (glTF mesh with several primitives) or a THREE.Mesh.
 					node.traverse( function ( object ) {
 
 						if ( object.isMesh === true && object.morphTargetInfluences ) {
@@ -3080,20 +2858,16 @@ THREE.GLTFLoader = ( function () {
 
 				}
 
-				// KeyframeTrack.optimize() will modify given 'times' and 'values'
-				// buffers before creating a truncated copy to keep. Because buffers may
-				// be reused by other tracks, make copies here.
 				for ( var j = 0, jl = targetNames.length; j < jl; j ++ ) {
 
 					var track = new TypedKeyframeTrack(
 						targetNames[ j ] + '.' + PATH_PROPERTIES[ target.path ],
-						THREE.AnimationUtils.arraySlice( inputAccessor.array, 0 ),
-						THREE.AnimationUtils.arraySlice( outputAccessor.array, 0 ),
+						inputAccessor.array,
+						outputAccessor.array,
 						interpolation
 					);
 
-					// Here is the trick to enable custom interpolation.
-					// Overrides .createInterpolant in a factory method which creates custom interpolation.
+					// Override interpolation with custom factory method.
 					if ( sampler.interpolation === 'CUBICSPLINE' ) {
 
 						track.createInterpolant = function InterpolantFactoryMethodGLTFCubicSpline( result ) {
@@ -3106,8 +2880,7 @@ THREE.GLTFLoader = ( function () {
 
 						};
 
-						// Workaround, provide an alternate way to know if the interpolant type is cubis spline to track.
-						// track.getInterpolation() doesn't return valid value for custom interpolant.
+						// Mark as CUBICSPLINE. `track.getInterpolation()` doesn't support custom interpolants.
 						track.createInterpolant.isInterpolantFactoryMethodGLTFCubicSpline = true;
 
 					}
@@ -3335,7 +3108,7 @@ THREE.GLTFLoader = ( function () {
 
 						mesh.bind( new THREE.Skeleton( bones, boneInverses ), mesh.matrixWorld );
 
-					};
+					}
 
 					return node;
 

+ 29 - 11
examples/js/loaders/VRMLLoader.js

@@ -932,7 +932,7 @@ THREE.VRMLLoader.prototype = {
 
 						if ( data.coordIndex ) {
 
-							function triangulateIndexArray( indexArray, ccw ) {
+							function triangulateIndexArray( indexArray, ccw, colorPerVertex ) {
 
 								if ( ccw === undefined ) {
 
@@ -946,21 +946,37 @@ THREE.VRMLLoader.prototype = {
 
 								for ( i = 0, il = indexArray.length; i < il; i ++ ) {
 
-									var indexedFace = indexArray[ i ];
+									if ( colorPerVertex === false ) {
 
-									// VRML support multipoint indexed face sets (more then 3 vertices). You must calculate the composing triangles here
+										var colorIndices = indexArray[ i ];
 
-									skip = 0;
+										for ( j = 0, jl = colorIndices.length; j < jl; j ++ ) {
 
-									while ( indexedFace.length >= 3 && skip < ( indexedFace.length - 2 ) ) {
+											var index = colorIndices[ j ];
 
-										var i1 = indexedFace[ 0 ];
-										var i2 = indexedFace[ skip + ( ccw ? 1 : 2 ) ];
-										var i3 = indexedFace[ skip + ( ccw ? 2 : 1 ) ];
+											triangulatedIndexArray.push( index, index, index );
 
-										triangulatedIndexArray.push( i1, i2, i3 );
+										}
 
-										skip ++;
+									} else {
+
+										var indexedFace = indexArray[ i ];
+
+										// VRML support multipoint indexed face sets (more then 3 vertices). You must calculate the composing triangles here
+
+										skip = 0;
+
+										while ( indexedFace.length >= 3 && skip < ( indexedFace.length - 2 ) ) {
+
+											var i1 = indexedFace[ 0 ];
+											var i2 = indexedFace[ skip + ( ccw ? 1 : 2 ) ];
+											var i3 = indexedFace[ skip + ( ccw ? 2 : 1 ) ];
+
+											triangulatedIndexArray.push( i1, i2, i3 );
+
+											skip ++;
+
+										}
 
 									}
 
@@ -972,7 +988,7 @@ THREE.VRMLLoader.prototype = {
 
 							var positionIndexes = data.coordIndex ? triangulateIndexArray( data.coordIndex, data.ccw ) : [];
 							var normalIndexes = data.normalIndex ? triangulateIndexArray( data.normalIndex, data.ccw ) : positionIndexes;
-							var colorIndexes = data.colorIndex ? triangulateIndexArray( data.colorIndex, data.ccw ) : positionIndexes;
+							var colorIndexes = data.colorIndex ? triangulateIndexArray( data.colorIndex, data.ccw, data.colorPerVertex ) : [];
 							var uvIndexes = data.texCoordIndex ? triangulateIndexArray( data.texCoordIndex, data.ccw ) : positionIndexes;
 
 							var newIndexes = [];
@@ -1095,6 +1111,8 @@ THREE.VRMLLoader.prototype = {
 
 							geometry.addAttribute( 'color', new THREE.Float32BufferAttribute( colors, 3 ) );
 
+							parent.material.vertexColors = THREE.VertexColors;
+
 						}
 
 						if ( uvs.length > 0 ) {

+ 1 - 1
examples/js/nodes/core/StructNode.js

@@ -49,7 +49,7 @@ StructNode.prototype.generate = function ( builder, output ) {
 
 	} else {
 
-		return builder.format( '( ' + src + ' )', this.getType( builder ), output );
+		return builder.format( '( ' + this.src + ' )', this.getType( builder ), output );
 
 	}
 

+ 23 - 23
examples/js/postprocessing/AdaptiveToneMappingPass.js

@@ -49,7 +49,7 @@ THREE.AdaptiveToneMappingPass = function ( adaptive, resolution ) {
 
 	this.adaptLuminanceShader = {
 		defines: {
-			"MIP_LEVEL_1X1" : ( Math.log( this.resolution ) / Math.log( 2.0 ) ).toFixed( 1 )
+			"MIP_LEVEL_1X1": ( Math.log( this.resolution ) / Math.log( 2.0 ) ).toFixed( 1 )
 		},
 		uniforms: {
 			"lastLum": { value: null },
@@ -63,8 +63,8 @@ THREE.AdaptiveToneMappingPass = function ( adaptive, resolution ) {
 
 			"void main() {",
 
-				"vUv = uv;",
-				"gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );",
+			"	vUv = uv;",
+			"	gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );",
 
 			"}"
 		].join( '\n' ),
@@ -79,20 +79,20 @@ THREE.AdaptiveToneMappingPass = function ( adaptive, resolution ) {
 
 			"void main() {",
 
-				"vec4 lastLum = texture2D( lastLum, vUv, MIP_LEVEL_1X1 );",
-				"vec4 currentLum = texture2D( currentLum, vUv, MIP_LEVEL_1X1 );",
+			"	vec4 lastLum = texture2D( lastLum, vUv, MIP_LEVEL_1X1 );",
+			"	vec4 currentLum = texture2D( currentLum, vUv, MIP_LEVEL_1X1 );",
 
-				"float fLastLum = max( minLuminance, lastLum.r );",
-				"float fCurrentLum = max( minLuminance, currentLum.r );",
+			"	float fLastLum = max( minLuminance, lastLum.r );",
+			"	float fCurrentLum = max( minLuminance, currentLum.r );",
 
-				//The adaption seems to work better in extreme lighting differences
-				//if the input luminance is squared.
-				"fCurrentLum *= fCurrentLum;",
+			//The adaption seems to work better in extreme lighting differences
+			//if the input luminance is squared.
+			"	fCurrentLum *= fCurrentLum;",
 
-				// Adapt the luminance using Pattanaik's technique
-				"float fAdaptedLum = fLastLum + (fCurrentLum - fLastLum) * (1.0 - exp(-delta * tau));",
-				// "fAdaptedLum = sqrt(fAdaptedLum);",
-				"gl_FragColor.r = fAdaptedLum;",
+			// Adapt the luminance using Pattanaik's technique
+			"	float fAdaptedLum = fLastLum + (fCurrentLum - fLastLum) * (1.0 - exp(-delta * tau));",
+			// "fAdaptedLum = sqrt(fAdaptedLum);",
+			"	gl_FragColor.r = fAdaptedLum;",
 			"}"
 		].join( '\n' )
 	};
@@ -118,7 +118,7 @@ THREE.AdaptiveToneMappingPass = function ( adaptive, resolution ) {
 	} );
 
 	this.camera = new THREE.OrthographicCamera( - 1, 1, 1, - 1, 0, 1 );
-	this.scene  = new THREE.Scene();
+	this.scene = new THREE.Scene();
 
 	this.quad = new THREE.Mesh( new THREE.PlaneBufferGeometry( 2, 2 ), null );
 	this.quad.frustumCulled = false; // Avoid getting clipped
@@ -188,7 +188,7 @@ THREE.AdaptiveToneMappingPass.prototype = Object.assign( Object.create( THREE.Pa
 
 	},
 
-	reset: function( renderer ) {
+	reset: function ( renderer ) {
 
 		// render targets
 		if ( this.luminanceRT ) {
@@ -240,7 +240,7 @@ THREE.AdaptiveToneMappingPass.prototype = Object.assign( Object.create( THREE.Pa
 
 	},
 
-	setAdaptive: function( adaptive ) {
+	setAdaptive: function ( adaptive ) {
 
 		if ( adaptive ) {
 
@@ -259,7 +259,7 @@ THREE.AdaptiveToneMappingPass.prototype = Object.assign( Object.create( THREE.Pa
 
 	},
 
-	setAdaptionRate: function( rate ) {
+	setAdaptionRate: function ( rate ) {
 
 		if ( rate ) {
 
@@ -269,7 +269,7 @@ THREE.AdaptiveToneMappingPass.prototype = Object.assign( Object.create( THREE.Pa
 
 	},
 
-	setMinLuminance: function( minLum ) {
+	setMinLuminance: function ( minLum ) {
 
 		if ( minLum ) {
 
@@ -280,7 +280,7 @@ THREE.AdaptiveToneMappingPass.prototype = Object.assign( Object.create( THREE.Pa
 
 	},
 
-	setMaxLuminance: function( maxLum ) {
+	setMaxLuminance: function ( maxLum ) {
 
 		if ( maxLum ) {
 
@@ -290,7 +290,7 @@ THREE.AdaptiveToneMappingPass.prototype = Object.assign( Object.create( THREE.Pa
 
 	},
 
-	setAverageLuminance: function( avgLum ) {
+	setAverageLuminance: function ( avgLum ) {
 
 		if ( avgLum ) {
 
@@ -300,7 +300,7 @@ THREE.AdaptiveToneMappingPass.prototype = Object.assign( Object.create( THREE.Pa
 
 	},
 
-	setMiddleGrey: function( middleGrey ) {
+	setMiddleGrey: function ( middleGrey ) {
 
 		if ( middleGrey ) {
 
@@ -310,7 +310,7 @@ THREE.AdaptiveToneMappingPass.prototype = Object.assign( Object.create( THREE.Pa
 
 	},
 
-	dispose: function() {
+	dispose: function () {
 
 		if ( this.luminanceRT ) {
 

+ 2 - 2
examples/js/postprocessing/AfterimagePass.js

@@ -42,7 +42,7 @@ THREE.AfterimagePass = function ( damp ) {
 	this.sceneComp = new THREE.Scene();
 	this.scene = new THREE.Scene();
 
-	this.camera = new THREE.OrthographicCamera( -1, 1, 1, -1, 0, 1 );
+	this.camera = new THREE.OrthographicCamera( - 1, 1, 1, - 1, 0, 1 );
 	this.camera.position.z = 1;
 
 	var geometry = new THREE.PlaneBufferGeometry( 2, 2 );
@@ -50,7 +50,7 @@ THREE.AfterimagePass = function ( damp ) {
 	this.quadComp = new THREE.Mesh( geometry, this.shaderMaterial );
 	this.sceneComp.add( this.quadComp );
 
-	var material = new THREE.MeshBasicMaterial( { 
+	var material = new THREE.MeshBasicMaterial( {
 		map: this.textureComp.texture
 	} );
 

+ 2 - 2
examples/js/postprocessing/BloomPass.js

@@ -56,7 +56,7 @@ THREE.BloomPass = function ( strength, kernelSize, sigma, resolution ) {
 	this.materialConvolution = new THREE.ShaderMaterial( {
 
 		uniforms: this.convolutionUniforms,
-		vertexShader:  convolutionShader.vertexShader,
+		vertexShader: convolutionShader.vertexShader,
 		fragmentShader: convolutionShader.fragmentShader,
 		defines: {
 			"KERNEL_SIZE_FLOAT": kernelSize.toFixed( 1 ),
@@ -68,7 +68,7 @@ THREE.BloomPass = function ( strength, kernelSize, sigma, resolution ) {
 	this.needsSwap = false;
 
 	this.camera = new THREE.OrthographicCamera( - 1, 1, 1, - 1, 0, 1 );
-	this.scene  = new THREE.Scene();
+	this.scene = new THREE.Scene();
 
 	this.quad = new THREE.Mesh( new THREE.PlaneBufferGeometry( 2, 2 ), null );
 	this.quad.frustumCulled = false; // Avoid getting clipped

+ 1 - 1
examples/js/postprocessing/BokehPass.js

@@ -67,7 +67,7 @@ THREE.BokehPass = function ( scene, camera, params ) {
 	this.needsSwap = false;
 
 	this.camera2 = new THREE.OrthographicCamera( - 1, 1, 1, - 1, 0, 1 );
-	this.scene2  = new THREE.Scene();
+	this.scene2 = new THREE.Scene();
 
 	this.quad2 = new THREE.Mesh( new THREE.PlaneBufferGeometry( 2, 2 ), null );
 	this.quad2.frustumCulled = false; // Avoid getting clipped

+ 1 - 1
examples/js/postprocessing/DotScreenPass.js

@@ -26,7 +26,7 @@ THREE.DotScreenPass = function ( center, angle, scale ) {
 	} );
 
 	this.camera = new THREE.OrthographicCamera( - 1, 1, 1, - 1, 0, 1 );
-	this.scene  = new THREE.Scene();
+	this.scene = new THREE.Scene();
 
 	this.quad = new THREE.Mesh( new THREE.PlaneBufferGeometry( 2, 2 ), null );
 	this.quad.frustumCulled = false; // Avoid getting clipped

+ 1 - 1
examples/js/postprocessing/FilmPass.js

@@ -27,7 +27,7 @@ THREE.FilmPass = function ( noiseIntensity, scanlinesIntensity, scanlinesCount,
 	if ( scanlinesCount !== undefined ) this.uniforms.sCount.value = scanlinesCount;
 
 	this.camera = new THREE.OrthographicCamera( - 1, 1, 1, - 1, 0, 1 );
-	this.scene  = new THREE.Scene();
+	this.scene = new THREE.Scene();
 
 	this.quad = new THREE.Mesh( new THREE.PlaneBufferGeometry( 2, 2 ), null );
 	this.quad.frustumCulled = false; // Avoid getting clipped

+ 3 - 3
examples/js/postprocessing/GlitchPass.js

@@ -24,7 +24,7 @@ THREE.GlitchPass = function ( dt_size ) {
 	} );
 
 	this.camera = new THREE.OrthographicCamera( - 1, 1, 1, - 1, 0, 1 );
-	this.scene  = new THREE.Scene();
+	this.scene = new THREE.Scene();
 
 	this.quad = new THREE.Mesh( new THREE.PlaneBufferGeometry( 2, 2 ), null );
 	this.quad.frustumCulled = false; // Avoid getting clipped
@@ -90,13 +90,13 @@ THREE.GlitchPass.prototype = Object.assign( Object.create( THREE.Pass.prototype
 
 	},
 
-	generateTrigger: function() {
+	generateTrigger: function () {
 
 		this.randX = THREE.Math.randInt( 120, 240 );
 
 	},
 
-	generateHeightmap: function( dt_size ) {
+	generateHeightmap: function ( dt_size ) {
 
 		var data_arr = new Float32Array( dt_size * dt_size * 3 );
 		var length = dt_size * dt_size;

+ 3 - 3
examples/js/postprocessing/HalftonePass.js

@@ -30,7 +30,7 @@ THREE.HalftonePass = function ( width, height, params ) {
 
 		if ( params.hasOwnProperty( key ) && this.uniforms.hasOwnProperty( key ) ) {
 
-			this.uniforms[key].value = params[key];
+			this.uniforms[ key ].value = params[ key ];
 
 		}
 
@@ -42,9 +42,9 @@ THREE.HalftonePass = function ( width, height, params ) {
  	this.quad.frustumCulled = false;
  	this.scene.add( this.quad );
 
- };
+};
 
- THREE.HalftonePass.prototype = Object.assign( Object.create( THREE.Pass.prototype ), {
+THREE.HalftonePass.prototype = Object.assign( Object.create( THREE.Pass.prototype ), {
 
 	constructor: THREE.HalftonePass,
 

+ 1 - 1
examples/js/postprocessing/MaskPass.js

@@ -73,7 +73,7 @@ THREE.MaskPass.prototype = Object.assign( Object.create( THREE.Pass.prototype ),
 
 		// only render where stencil is set to 1
 
-		state.buffers.stencil.setFunc( context.EQUAL, 1, 0xffffffff );  // draw if == 1
+		state.buffers.stencil.setFunc( context.EQUAL, 1, 0xffffffff ); // draw if == 1
 		state.buffers.stencil.setOp( context.KEEP, context.KEEP, context.KEEP );
 
 	}

+ 4 - 1
examples/js/postprocessing/RenderPass.js

@@ -49,7 +49,9 @@ THREE.RenderPass.prototype = Object.assign( Object.create( THREE.Pass.prototype
 		}
 
 		renderer.setRenderTarget( this.renderToScreen ? null : readBuffer );
-		if ( this.clear ) renderer.clear();
+
+		// TODO: Avoid using autoClear properties, see https://github.com/mrdoob/three.js/pull/15571#issuecomment-465669600
+		if ( this.clear ) renderer.clear( renderer.autoClearColor, renderer.autoClearDepth, renderer.autoClearStencil );
 		renderer.render( this.scene, this.camera );
 
 		if ( this.clearColor ) {
@@ -60,6 +62,7 @@ THREE.RenderPass.prototype = Object.assign( Object.create( THREE.Pass.prototype
 
 		this.scene.overrideMaterial = null;
 		renderer.autoClear = oldAutoClear;
+
 	}
 
 } );

+ 1 - 1
examples/js/postprocessing/SAOPass.js

@@ -319,7 +319,7 @@ THREE.SAOPass.prototype = Object.assign( Object.create( THREE.Pass.prototype ),
 		var originalClearAlpha = renderer.getClearAlpha();
 		var originalAutoClear = renderer.autoClear;
 
-		renderer.setRenderTarget( renderTarget);
+		renderer.setRenderTarget( renderTarget );
 
 		// setup pass state
 		renderer.autoClear = false;

+ 3 - 1
examples/js/postprocessing/SMAAPass.js

@@ -31,9 +31,11 @@ THREE.SMAAPass = function ( width, height ) {
 
 	var areaTextureImage = new Image();
 	areaTextureImage.src = this.getAreaTexture();
-	areaTextureImage.onload = function() {
+	areaTextureImage.onload = function () {
+
 		// assigning data to HTMLImageElement.src is asynchronous (see #15162)
 		scope.areaTexture.needsUpdate = true;
+
 	};
 
 	this.areaTexture = new THREE.Texture();

+ 1 - 1
examples/js/postprocessing/SSAARenderPass.js

@@ -100,7 +100,7 @@ THREE.SSAARenderPass.prototype = Object.assign( Object.create( THREE.Pass.protot
 			if ( this.camera.setViewOffset ) {
 
 				this.camera.setViewOffset( width, height,
-					jitterOffset[ 0 ] * 0.0625, jitterOffset[ 1 ] * 0.0625,   // 0.0625 = 1 / 16
+					jitterOffset[ 0 ] * 0.0625, jitterOffset[ 1 ] * 0.0625, // 0.0625 = 1 / 16
 					width, height );
 
 			}

+ 1 - 1
examples/js/postprocessing/SSAOPass.js

@@ -392,7 +392,7 @@ THREE.SSAOPass.prototype = Object.assign( Object.create( THREE.Pass.prototype ),
 
 		}
 
-		this.noiseTexture = new THREE.DataTexture( data, width, height, THREE.RGBA, THREE.FloatType );
+		this.noiseTexture = new THREE.DataTexture( data, width, height, THREE.RGBAFormat, THREE.FloatType );
 		this.noiseTexture.wrapS = THREE.RepeatWrapping;
 		this.noiseTexture.wrapT = THREE.RepeatWrapping;
 		this.noiseTexture.needsUpdate = true;

+ 3 - 2
examples/js/postprocessing/ShaderPass.js

@@ -42,7 +42,7 @@ THREE.ShaderPass.prototype = Object.assign( Object.create( THREE.Pass.prototype
 
 	constructor: THREE.ShaderPass,
 
-	render: function( renderer, writeBuffer, readBuffer, deltaTime, maskActive ) {
+	render: function ( renderer, writeBuffer, readBuffer, deltaTime, maskActive ) {
 
 		if ( this.uniforms[ this.textureID ] ) {
 
@@ -60,7 +60,8 @@ THREE.ShaderPass.prototype = Object.assign( Object.create( THREE.Pass.prototype
 		} else {
 
 			renderer.setRenderTarget( writeBuffer );
-			if ( this.clear ) renderer.clear();
+			// TODO: Avoid using autoClear properties, see https://github.com/mrdoob/three.js/pull/15571#issuecomment-465669600
+			if ( this.clear ) renderer.clear( renderer.autoClearColor, renderer.autoClearDepth, renderer.autoClearStencil );
 			renderer.render( this.scene, this.camera );
 
 		}

+ 1 - 1
examples/js/postprocessing/TAARenderPass.js

@@ -88,7 +88,7 @@ THREE.TAARenderPass.prototype = Object.assign( Object.create( THREE.SSAARenderPa
 				if ( this.camera.setViewOffset ) {
 
 					this.camera.setViewOffset( readBuffer.width, readBuffer.height,
-						jitterOffset[ 0 ] * 0.0625, jitterOffset[ 1 ] * 0.0625,   // 0.0625 = 1 / 16
+						jitterOffset[ 0 ] * 0.0625, jitterOffset[ 1 ] * 0.0625, // 0.0625 = 1 / 16
 						readBuffer.width, readBuffer.height );
 
 				}

+ 1 - 1
examples/js/postprocessing/TexturePass.js

@@ -29,7 +29,7 @@ THREE.TexturePass = function ( map, opacity ) {
 	this.needsSwap = false;
 
 	this.camera = new THREE.OrthographicCamera( - 1, 1, 1, - 1, 0, 1 );
-	this.scene  = new THREE.Scene();
+	this.scene = new THREE.Scene();
 
 	this.quad = new THREE.Mesh( new THREE.PlaneBufferGeometry( 2, 2 ), null );
 	this.quad.frustumCulled = false; // Avoid getting clipped

+ 15 - 13
examples/js/renderers/WebGLDeferredRenderer.js

@@ -40,7 +40,8 @@ THREE.WebGLDeferredRenderer = function ( parameters ) {
 
 	var _this = this;
 
-	var _gl;
+	var _context;
+	var _state;
 
 	var _width, _height;
 
@@ -114,7 +115,7 @@ THREE.WebGLDeferredRenderer = function ( parameters ) {
 	this.renderer = undefined;
 	this.domElement = undefined;
 
-	this.forwardRendering = false;  // for debug
+	this.forwardRendering = false; // for debug
 
 	// private methods
 
@@ -123,7 +124,8 @@ THREE.WebGLDeferredRenderer = function ( parameters ) {
 		_this.renderer = parameters.renderer !== undefined ? parameters.renderer : new THREE.WebGLRenderer();
 		_this.domElement = _this.renderer.domElement;
 
-		_gl = _this.renderer.context;
+		_context = _this.renderer.context;
+		_state = _this.renderer.state;
 
 		_width = parameters.width !== undefined ? parameters.width : _this.renderer.getSize( new THREE.Vector2() ).width;
 		_height = parameters.height !== undefined ? parameters.height : _this.renderer.getSize( new THREE.Vector2() ).height;
@@ -1176,7 +1178,7 @@ THREE.WebGLDeferredRenderer = function ( parameters ) {
 
 			if ( cache[ key ].used === false ) {
 
-				cache[ key ].count++;
+				cache[ key ].count ++;
 
 				if ( cache[ key ].keepAlive === false && cache[ key ].count > _removeThresholdCount ) {
 
@@ -1255,9 +1257,9 @@ THREE.WebGLDeferredRenderer = function ( parameters ) {
 		_this.renderer.autoClearDepth = true;
 		_this.renderer.autoClearStencil = true;
 
-		_gl.enable( _gl.STENCIL_TEST );
-		_gl.stencilFunc( _gl.ALWAYS, 1, 0xffffffff );
-		_gl.stencilOp( _gl.REPLACE, _gl.REPLACE, _gl.REPLACE );
+		_state.buffers.stencil.setTest( true );
+		_state.buffers.stencil.setFunc( _context.ALWAYS, 1, 0xffffffff );
+		_state.buffers.stencil.setOp( _context.REPLACE, _context.REPLACE, _context.REPLACE );
 
 		_compNormalDepth.render();
 
@@ -1286,8 +1288,8 @@ THREE.WebGLDeferredRenderer = function ( parameters ) {
 		_this.renderer.autoClearDepth = false;
 		_this.renderer.autoClearStencil = false;
 
-		_gl.stencilFunc( _gl.EQUAL, 1, 0xffffffff );
-		_gl.stencilOp( _gl.KEEP, _gl.KEEP, _gl.KEEP );
+		_state.buffers.stencil.setFunc( _context.EQUAL, 1, 0xffffffff );
+		_state.buffers.stencil.setOp( _context.KEEP, _context.KEEP, _context.KEEP );
 
 		_compColor.render();
 
@@ -1318,7 +1320,7 @@ THREE.WebGLDeferredRenderer = function ( parameters ) {
 
 		_compLight.render();
 
-		_gl.disable( _gl.STENCIL_TEST );
+		_state.buffers.stencil.setTest( false );
 
 	}
 
@@ -1343,8 +1345,8 @@ THREE.WebGLDeferredRenderer = function ( parameters ) {
 		_this.renderer.autoClearDepth = false;
 		_this.renderer.autoClearStencil = false;
 
-		_gl.stencilFunc( _gl.EQUAL, 1, 0xffffffff );
-		_gl.stencilOp( _gl.KEEP, _gl.KEEP, _gl.KEEP );
+		_state.buffers.stencil.setFunc( _context.EQUAL, 1, 0xffffffff );
+		_state.buffers.stencil.setOp( _context.KEEP, _context.KEEP, _context.KEEP );
 
 		_compLight.render();
 
@@ -1371,7 +1373,7 @@ THREE.WebGLDeferredRenderer = function ( parameters ) {
 
 		_compReconstruction.render();
 
-		_gl.disable( _gl.STENCIL_TEST );
+		_state.buffers.stencil.setTest( false );
 
 		scene.traverse( restoreOriginalMaterial );
 

+ 2 - 1
examples/js/utils/BufferGeometryUtils.js

@@ -498,7 +498,8 @@ THREE.BufferGeometryUtils = {
 		var getters = [ 'getX', 'getY', 'getZ', 'getW' ];
 
 		// initialize the arrays
-		for ( var name of attributeNames ) {
+		for ( var i = 0, l = attributeNames.length; i < l; i ++ ) {
+			var name = attributeNames[ i ];
 
 			attrArrays[ name ] = [];
 

BIN
examples/models/gltf/Flamingo.glb


BIN
examples/models/gltf/Horse.glb


BIN
examples/models/gltf/Parrot.glb


BIN
examples/models/gltf/Stork.glb


BIN
examples/textures/tri_pattern.jpg


+ 1 - 1
examples/webgl_animation_skinning_morph.html

@@ -223,7 +223,7 @@
 
 				for ( var i = 0; i < expressions.length; i++ ) {
 
-					expressionFolder.add( face.morphTargetInfluences, i, 0, 1 ).name( expressions[ i ] );
+					expressionFolder.add( face.morphTargetInfluences, i, 0, 1, 0.01 ).name( expressions[ i ] );
 
 				}
 

+ 0 - 1
examples/webgl_depth_texture.html

@@ -93,7 +93,6 @@
 		</div>
 
 		<script src="../build/three.js"></script>
-		<script src="js/shaders/SSAOShader.js"></script>
 		<script src="js/controls/OrbitControls.js"></script>
 		<script src="js/libs/stats.min.js"></script>
 

+ 21 - 21
examples/webgl_gpgpu_birds.html

@@ -83,7 +83,7 @@
 			uniform float time;
 			uniform float testing;
 			uniform float delta; // about 0.016
-			uniform float seperationDistance; // 20
+			uniform float separationDistance; // 20
 			uniform float alignmentDistance; // 40
 			uniform float cohesionDistance; //
 			uniform float freedomFactor;
@@ -107,15 +107,15 @@
 
 			const float SPEED_LIMIT = 9.0;
 
-			float rand(vec2 co){
-				return fract(sin(dot(co.xy ,vec2(12.9898,78.233))) * 43758.5453);
+			float rand( vec2 co ){
+				return fract( sin( dot( co.xy, vec2(12.9898,78.233) ) ) * 43758.5453 );
 			}
 
 			void main() {
 
-				zoneRadius = seperationDistance + alignmentDistance + cohesionDistance;
-				separationThresh = seperationDistance / zoneRadius;
-				alignmentThresh = ( seperationDistance + alignmentDistance ) / zoneRadius;
+				zoneRadius = separationDistance + alignmentDistance + cohesionDistance;
+				separationThresh = separationDistance / zoneRadius;
+				alignmentThresh = ( separationDistance + alignmentDistance ) / zoneRadius;
 				zoneRadiusSquared = zoneRadius * zoneRadius;
 
 
@@ -129,7 +129,7 @@
 				vec3 dir; // direction
 				float distSquared;
 
-				float seperationSquared = seperationDistance * seperationDistance;
+				float separationSquared = separationDistance * separationDistance;
 				float cohesionSquared = cohesionDistance * cohesionDistance;
 
 				float f;
@@ -150,7 +150,7 @@
 
 
 				// move birds away from predator
-				if (dist < preyRadius) {
+				if ( dist < preyRadius ) {
 
 					f = ( distSquared / preyRadiusSq - 1.0 ) * delta * 100.;
 					velocity += normalize( dir ) * f;
@@ -170,28 +170,28 @@
 				dir.y *= 2.5;
 				velocity -= normalize( dir ) * delta * 5.;
 
-				for (float y=0.0;y<height;y++) {
-					for (float x=0.0;x<width;x++) {
+				for ( float y = 0.0; y < height; y++ ) {
+					for ( float x = 0.0; x < width; x++ ) {
 
 						vec2 ref = vec2( x + 0.5, y + 0.5 ) / resolution.xy;
 						birdPosition = texture2D( texturePosition, ref ).xyz;
 
 						dir = birdPosition - selfPosition;
-						dist = length(dir);
+						dist = length( dir );
 
-						if (dist < 0.0001) continue;
+						if ( dist < 0.0001 ) continue;
 
 						distSquared = dist * dist;
 
-						if (distSquared > zoneRadiusSquared ) continue;
+						if ( distSquared > zoneRadiusSquared ) continue;
 
 						percent = distSquared / zoneRadiusSquared;
 
 						if ( percent < separationThresh ) { // low
 
 							// Separation - Move apart for comfort
-							f = (separationThresh / percent - 1.0) * delta;
-							velocity -= normalize(dir) * f;
+							f = ( separationThresh / percent - 1.0 ) * delta;
+							velocity -= normalize( dir ) * f;
 
 						} else if ( percent < alignmentThresh ) { // high
 
@@ -202,7 +202,7 @@
 							birdVelocity = texture2D( textureVelocity, ref ).xyz;
 
 							f = ( 0.5 - cos( adjustedPercent * PI_2 ) * 0.5 + 0.5 ) * delta;
-							velocity += normalize(birdVelocity) * f;
+							velocity += normalize( birdVelocity ) * f;
 
 						} else {
 
@@ -212,7 +212,7 @@
 
 							f = ( 0.5 - ( cos( adjustedPercent * PI_2 ) * -0.5 + 0.5 ) ) * delta;
 
-							velocity += normalize(dir) * f;
+							velocity += normalize( dir ) * f;
 
 						}
 
@@ -502,7 +502,7 @@
 
 
 				var effectController = {
-					seperation: 20.0,
+					separation: 20.0,
 					alignment: 20.0,
 					cohesion: 20.0,
 					freedom: 0.75
@@ -510,7 +510,7 @@
 
 				var valuesChanger = function () {
 
-					velocityUniforms[ "seperationDistance" ].value = effectController.seperation;
+					velocityUniforms[ "separationDistance" ].value = effectController.separation;
 					velocityUniforms[ "alignmentDistance" ].value = effectController.alignment;
 					velocityUniforms[ "cohesionDistance" ].value = effectController.cohesion;
 					velocityUniforms[ "freedomFactor" ].value = effectController.freedom;
@@ -520,7 +520,7 @@
 				valuesChanger();
 
 
-				gui.add( effectController, "seperation", 0.0, 100.0, 1.0 ).onChange( valuesChanger );
+				gui.add( effectController, "separation", 0.0, 100.0, 1.0 ).onChange( valuesChanger );
 				gui.add( effectController, "alignment", 0.0, 100, 0.001 ).onChange( valuesChanger );
 				gui.add( effectController, "cohesion", 0.0, 100, 0.025 ).onChange( valuesChanger );
 				gui.close();
@@ -552,7 +552,7 @@
 				velocityUniforms[ "time" ] = { value: 1.0 };
 				velocityUniforms[ "delta" ] = { value: 0.0 };
 				velocityUniforms[ "testing" ] = { value: 1.0 };
-				velocityUniforms[ "seperationDistance" ] = { value: 1.0 };
+				velocityUniforms[ "separationDistance" ] = { value: 1.0 };
 				velocityUniforms[ "alignmentDistance" ] = { value: 1.0 };
 				velocityUniforms[ "cohesionDistance" ] = { value: 1.0 };
 				velocityUniforms[ "freedomFactor" ] = { value: 1.0 };

+ 28 - 18
examples/webgl_loader_gltf.html

@@ -40,6 +40,9 @@
 		<script src="js/controls/OrbitControls.js"></script>
 		<script src="js/loaders/GLTFLoader.js"></script>
 
+		<script src="js/pmrem/PMREMGenerator.js"></script>
+		<script src="js/pmrem/PMREMCubeUVPacker.js"></script>
+
 		<script src="js/WebGL.js"></script>
 		<script src="js/libs/stats.min.js"></script>
 
@@ -52,7 +55,7 @@
 			}
 
 			var container, stats, controls;
-			var camera, scene, renderer, light;
+			var camera, scene, renderer;
 
 			init();
 			animate();
@@ -69,36 +72,43 @@
 				controls.target.set( 0, - 0.2, - 0.2 );
 				controls.update();
 
+				scene = new THREE.Scene();
+
 				var urls = [ 'posx.jpg', 'negx.jpg', 'posy.jpg', 'negy.jpg', 'posz.jpg', 'negz.jpg' ];
 				var loader = new THREE.CubeTextureLoader().setPath( 'textures/cube/Bridge2/' );
-				var background = loader.load( urls );
+				loader.load( urls, function ( texture ) {
 
-				scene = new THREE.Scene();
-				scene.background = background;
+					var pmremGenerator = new THREE.PMREMGenerator( texture );
+					pmremGenerator.update( renderer );
 
-				light = new THREE.HemisphereLight( 0xbbbbff, 0x444422 );
-				light.position.set( 0, 1, 0 );
-				scene.add( light );
+					var pmremCubeUVPacker = new THREE.PMREMCubeUVPacker( pmremGenerator.cubeLods );
+					pmremCubeUVPacker.update( renderer );
 
-				// model
-				var loader = new THREE.GLTFLoader().setPath( 'models/gltf/DamagedHelmet/glTF/' );
-				loader.load( 'DamagedHelmet.gltf', function ( gltf ) {
+					var envMap = pmremCubeUVPacker.CubeUVRenderTarget.texture;
 
-					gltf.scene.traverse( function ( child ) {
+					// model
 
-						if ( child.isMesh ) {
+					var loader = new THREE.GLTFLoader().setPath( 'models/gltf/DamagedHelmet/glTF/' );
+					loader.load( 'DamagedHelmet.gltf', function ( gltf ) {
 
-							child.material.envMap = background;
+						gltf.scene.traverse( function ( child ) {
 
-						}
+							if ( child.isMesh ) {
 
-					} );
+								child.material.envMap = envMap;
 
-					scene.add( gltf.scene );
+							}
+
+						} );
+
+						scene.add( gltf.scene );
+
+					} );
 
-				}, undefined, function ( e ) {
+					pmremGenerator.dispose();
+					pmremCubeUVPacker.dispose();
 
-					console.error( e );
+					scene.background = texture;
 
 				} );
 

+ 41 - 46
examples/webgl_loader_gltf_extensions.html

@@ -56,10 +56,13 @@
 		<script src="js/loaders/DDSLoader.js"></script>
 		<script src="js/loaders/GLTFLoader.js"></script>
 
+		<script src="js/pmrem/PMREMGenerator.js"></script>
+		<script src="js/pmrem/PMREMCubeUVPacker.js"></script>
+
 		<script>
 			var orbitControls;
 			var container, camera, scene, renderer, loader;
-			var gltf, envMap, mixer, gui, extensionControls;
+			var gltf, background, envMap, mixer, gui, extensionControls;
 
 			var clock = new THREE.Clock();
 
@@ -71,7 +74,6 @@
 					authorURL: 'https://www.microsoft.com/',
 					cameraPos: new THREE.Vector3( 0.02, 0.01, 0.03 ),
 					objectRotation: new THREE.Euler( 0, Math.PI, 0 ),
-					addLights: true,
 					extensions: [ 'glTF', 'glTF-pbrSpecularGlossiness', 'glTF-Binary', 'glTF-dds' ],
 					addEnvMap: true
 				},
@@ -95,7 +97,6 @@
 					authorURL: 'https://twitter.com/emackey',
 					cameraPos: new THREE.Vector3( 2, 1, 15 ),
 					objectRotation: new THREE.Euler( 0, 0, 0 ),
-					addLights: true,
 					extensions: [ 'glTF', 'glTF-Embedded' ],
 					addEnvMap: true
 				},
@@ -170,18 +171,46 @@
 
 			function onload() {
 
+				container = document.getElementById( 'container' );
+
+				renderer = new THREE.WebGLRenderer( { antialias: true } );
+				renderer.setPixelRatio( window.devicePixelRatio );
+				renderer.setSize( window.innerWidth, window.innerHeight );
+				renderer.gammaOutput = true;
+				renderer.physicallyCorrectLights = true;
+				container.appendChild( renderer.domElement );
+
 				window.addEventListener( 'resize', onWindowResize, false );
 
-				buildGUI();
-				initScene( scenes[ state.scene ] );
-				animate();
+				// Load background and generate envMap
+
+				var urls = [ 'posx.jpg', 'negx.jpg', 'posy.jpg', 'negy.jpg', 'posz.jpg', 'negz.jpg' ];
+				var loader = new THREE.CubeTextureLoader().setPath( 'textures/cube/Park2/' );
+				background = loader.load( urls, function ( texture ) {
+
+					var pmremGenerator = new THREE.PMREMGenerator( texture );
+					pmremGenerator.update( renderer );
+
+					var pmremCubeUVPacker = new THREE.PMREMCubeUVPacker( pmremGenerator.cubeLods );
+					pmremCubeUVPacker.update( renderer );
+
+					envMap = pmremCubeUVPacker.CubeUVRenderTarget.texture;
+
+					pmremGenerator.dispose();
+					pmremCubeUVPacker.dispose();
+
+					//
+
+					buildGUI();
+					initScene( scenes[ state.scene ] );
+					animate();
+
+				} );
 
 			}
 
 			function initScene( sceneInfo ) {
 
-				container = document.getElementById( 'container' );
-
 				var descriptionEl = document.getElementById( 'description' );
 
 				if ( sceneInfo.author && sceneInfo.authorURL ) {
@@ -227,15 +256,6 @@
 
 				}
 
-				// RENDERER
-
-				// TODO: Reuse existing WebGLRenderer, GLTFLoaders, and so on
-				renderer = new THREE.WebGLRenderer( { antialias: true } );
-				renderer.setPixelRatio( window.devicePixelRatio );
-				renderer.setSize( window.innerWidth, window.innerHeight );
-				renderer.gammaOutput = true;
-				renderer.physicallyCorrectLights = true;
-
 				if ( sceneInfo.shadows ) {
 
 					renderer.shadowMap.enabled = true;
@@ -243,7 +263,7 @@
 
 				}
 
-				container.appendChild( renderer.domElement );
+				// TODO: Reuse existing OrbitControls, GLTFLoaders, and so on
 
 				orbitControls = new THREE.OrbitControls( camera, renderer.domElement );
 
@@ -330,21 +350,19 @@
 
 					if ( sceneInfo.addEnvMap ) {
 
-						if ( ! envMap ) envMap = getEnvMap();
-
 						object.traverse( function ( node ) {
 
 							if ( node.material && ( node.material.isMeshStandardMaterial ||
 								 ( node.material.isShaderMaterial && node.material.envMap !== undefined ) ) ) {
 
 								node.material.envMap = envMap;
-								node.material.needsUpdate = true;
+								node.material.envMapIntensity = 1.5; // boombox seems too dark otherwise
 
 							}
 
 						} );
 
-						scene.background = envMap;
+						scene.background = background;
 
 					}
 
@@ -418,23 +436,6 @@
 
 			}
 
-			function getEnvMap() {
-
-				var path = 'textures/cube/Park2/';
-				var format = '.jpg';
-				var urls = [
-					path + 'posx' + format, path + 'negx' + format,
-					path + 'posy' + format, path + 'negy' + format,
-					path + 'posz' + format, path + 'negz' + format
-				];
-
-				envMap = new THREE.CubeTextureLoader().load( urls );
-				envMap.format = THREE.RGBFormat;
-
-				return envMap;
-
-			}
-
 			function buildGUI() {
 
 				gui = new dat.GUI( { width: 330 } );
@@ -482,12 +483,6 @@
 
 			function reload() {
 
-				if ( container && renderer ) {
-
-					container.removeChild( renderer.domElement );
-
-				}
-
 				if ( loader && mixer ) mixer.stopAllAction();
 
 				updateGUI();
@@ -499,4 +494,4 @@
 		</script>
 
 	</body>
-</html>
+</html>

+ 10 - 10
examples/webgl_loader_pcd.html

@@ -97,10 +97,10 @@
 				document.body.appendChild( renderer.domElement );
 
 				var loader = new THREE.PCDLoader();
-				loader.load( './models/pcd/binary/Zaghetto.pcd', function ( mesh ) {
+				loader.load( './models/pcd/binary/Zaghetto.pcd', function ( points ) {
 
-					scene.add( mesh );
-					var center = mesh.geometry.boundingSphere.center;
+					scene.add( points );
+					var center = points.geometry.boundingSphere.center;
 					controls.target.set( center.x, center.y, center.z );
 					controls.update();
 
@@ -130,23 +130,23 @@
 
 			function keyboard( ev ) {
 
-				var ZaghettoMesh = scene.getObjectByName( 'Zaghetto.pcd' );
+				var points = scene.getObjectByName( 'Zaghetto.pcd' );
 
 				switch ( ev.key || String.fromCharCode( ev.keyCode || ev.charCode ) ) {
 
 					case '+':
-						ZaghettoMesh.material.size *= 1.2;
-						ZaghettoMesh.material.needsUpdate = true;
+						points.material.size *= 1.2;
+						points.material.needsUpdate = true;
 						break;
 
 					case '-':
-						ZaghettoMesh.material.size /= 1.2;
-						ZaghettoMesh.material.needsUpdate = true;
+						points.material.size /= 1.2;
+						points.material.needsUpdate = true;
 						break;
 
 					case 'c':
-						ZaghettoMesh.material.color.setHex( Math.random() * 0xffffff );
-						ZaghettoMesh.material.needsUpdate = true;
+						points.material.color.setHex( Math.random() * 0xffffff );
+						points.material.needsUpdate = true;
 						break;
 
 				}

+ 97 - 213
examples/webgl_marchingcubes.html

@@ -58,18 +58,6 @@
 
 	<script src="js/controls/OrbitControls.js"></script>
 
-	<script src="js/shaders/CopyShader.js"></script>
-	<script src="js/shaders/FXAAShader.js"></script>
-	<script src="js/shaders/HorizontalTiltShiftShader.js"></script>
-	<script src="js/shaders/VerticalTiltShiftShader.js"></script>
-
-	<script src="js/postprocessing/EffectComposer.js"></script>
-	<script src="js/postprocessing/RenderPass.js"></script>
-	<script src="js/postprocessing/BloomPass.js"></script>
-	<script src="js/postprocessing/ShaderPass.js"></script>
-	<script src="js/postprocessing/MaskPass.js"></script>
-	<script src="js/postprocessing/SavePass.js"></script>
-
 	<script src="js/MarchingCubes.js"></script>
 	<script src="js/ShaderToon.js"></script>
 
@@ -85,11 +73,6 @@
 
 		}
 
-		var MARGIN = 0;
-
-		var SCREEN_WIDTH = window.innerWidth;
-		var SCREEN_HEIGHT = window.innerHeight - 2 * MARGIN;
-
 		var container, stats;
 
 		var camera, scene, renderer;
@@ -100,8 +83,6 @@
 
 		var effect, resolution;
 
-		var composer, effectFXAA, hblur, vblur;
-
 		var effectController;
 
 		var time = 0;
@@ -116,7 +97,7 @@
 
 			// CAMERA
 
-			camera = new THREE.PerspectiveCamera( 45, SCREEN_WIDTH / SCREEN_HEIGHT, 1, 10000 );
+			camera = new THREE.PerspectiveCamera( 45, window.innerWidth / window.innerHeight, 1, 10000 );
 			camera.position.set( - 500, 500, 1500 );
 
 			// SCENE
@@ -158,20 +139,16 @@
 			// RENDERER
 
 			renderer = new THREE.WebGLRenderer();
+			renderer.gammaOutput = true;
 			renderer.setPixelRatio( window.devicePixelRatio );
-			renderer.setSize( SCREEN_WIDTH, SCREEN_HEIGHT );
+			renderer.setSize( window.innerWidth, window.innerHeight );
 
 			renderer.domElement.style.position = "absolute";
-			renderer.domElement.style.top = MARGIN + "px";
+			renderer.domElement.style.top = "0px";
 			renderer.domElement.style.left = "0px";
 
 			container.appendChild( renderer.domElement );
 
-			//
-
-			renderer.gammaInput = true;
-			renderer.gammaOutput = true;
-
 			// CONTROLS
 
 			var controls = new THREE.OrbitControls( camera, renderer.domElement );
@@ -181,41 +158,6 @@
 			stats = new Stats();
 			container.appendChild( stats.dom );
 
-			// COMPOSER
-
-			renderer.autoClear = false;
-
-			var renderTargetParameters = { minFilter: THREE.LinearFilter, magFilter: THREE.LinearFilter, format: THREE.RGBFormat, stencilBuffer: false };
-			var renderTarget = new THREE.WebGLRenderTarget( SCREEN_WIDTH, SCREEN_HEIGHT, renderTargetParameters );
-
-			effectFXAA = new THREE.ShaderPass( THREE.FXAAShader );
-
-			hblur = new THREE.ShaderPass( THREE.HorizontalTiltShiftShader );
-			vblur = new THREE.ShaderPass( THREE.VerticalTiltShiftShader );
-
-			var bluriness = 8;
-
-			hblur.uniforms[ 'h' ].value = bluriness / SCREEN_WIDTH;
-			vblur.uniforms[ 'v' ].value = bluriness / SCREEN_HEIGHT;
-
-			hblur.uniforms[ 'r' ].value = vblur.uniforms[ 'r' ].value = 0.5;
-
-			effectFXAA.uniforms[ 'resolution' ].value.set( 1 / SCREEN_WIDTH, 1 / SCREEN_HEIGHT );
-
-			var renderModel = new THREE.RenderPass( scene, camera );
-
-			vblur.renderToScreen = true;
-			//effectFXAA.renderToScreen = true;
-
-			composer = new THREE.EffectComposer( renderer, renderTarget );
-
-			composer.addPass( renderModel );
-
-			composer.addPass( effectFXAA );
-
-			composer.addPass( hblur );
-			composer.addPass( vblur );
-
 			// GUI
 
 			setupGui();
@@ -230,19 +172,10 @@
 
 		function onWindowResize() {
 
-			SCREEN_WIDTH = window.innerWidth;
-			SCREEN_HEIGHT = window.innerHeight - 2 * MARGIN;
-
-			camera.aspect = SCREEN_WIDTH / SCREEN_HEIGHT;
+			camera.aspect = window.innerWidth / window.innerHeight;
 			camera.updateProjectionMatrix();
 
-			renderer.setSize( SCREEN_WIDTH, SCREEN_HEIGHT );
-			composer.setSize( SCREEN_WIDTH, SCREEN_HEIGHT );
-
-			hblur.uniforms[ 'h' ].value = 4 / SCREEN_WIDTH;
-			vblur.uniforms[ 'v' ].value = 4 / SCREEN_HEIGHT;
-
-			effectFXAA.uniforms[ 'resolution' ].value.set( 1 / SCREEN_WIDTH, 1 / SCREEN_HEIGHT );
+			renderer.setSize( window.innerWidth, window.innerHeight );
 
 		}
 
@@ -261,118 +194,86 @@
 			var cubeTextureLoader = new THREE.CubeTextureLoader();
 
 			var reflectionCube = cubeTextureLoader.load( urls );
-			reflectionCube.format = THREE.RGBFormat;
-
 			var refractionCube = cubeTextureLoader.load( urls );
-			reflectionCube.format = THREE.RGBFormat;
 			refractionCube.mapping = THREE.CubeRefractionMapping;
 
 			// toons
 
-			var toonMaterial1 = createShaderMaterial( "toon1", light, ambientLight ),
-				toonMaterial2 = createShaderMaterial( "toon2", light, ambientLight ),
-				hatchingMaterial = createShaderMaterial( "hatching", light, ambientLight ),
-				hatchingMaterial2 = createShaderMaterial( "hatching", light, ambientLight ),
-				dottedMaterial = createShaderMaterial( "dotted", light, ambientLight ),
-				dottedMaterial2 = createShaderMaterial( "dotted", light, ambientLight );
-
-			hatchingMaterial2.uniforms[ "uBaseColor" ].value.setRGB( 0, 0, 0 );
-			hatchingMaterial2.uniforms[ "uLineColor1" ].value.setHSL( 0, 0.8, 0.5 );
-			hatchingMaterial2.uniforms[ "uLineColor2" ].value.setHSL( 0, 0.8, 0.5 );
-			hatchingMaterial2.uniforms[ "uLineColor3" ].value.setHSL( 0, 0.8, 0.5 );
-			hatchingMaterial2.uniforms[ "uLineColor4" ].value.setHSL( 0.1, 0.8, 0.5 );
-
-			dottedMaterial2.uniforms[ "uBaseColor" ].value.setRGB( 0, 0, 0 );
-			dottedMaterial2.uniforms[ "uLineColor1" ].value.setHSL( 0.05, 1.0, 0.5 );
+			var toonMaterial1 = createShaderMaterial( "toon1", light, ambientLight );
+			var toonMaterial2 = createShaderMaterial( "toon2", light, ambientLight );
+			var hatchingMaterial = createShaderMaterial( "hatching", light, ambientLight );
+			var dottedMaterial = createShaderMaterial( "dotted", light, ambientLight );
 
 			var texture = new THREE.TextureLoader().load( "textures/UV_Grid_Sm.jpg" );
-			texture.wrapS = texture.wrapT = THREE.RepeatWrapping;
+			texture.wrapS = THREE.RepeatWrapping;
+			texture.wrapT = THREE.RepeatWrapping;
 
 			var materials = {
 
-				"chrome":
-			{
-				m: new THREE.MeshLambertMaterial( { color: 0xffffff, envMap: reflectionCube } ),
-				h: 0, s: 0, l: 1
-			},
-
-				"liquid":
-			{
-				m: new THREE.MeshLambertMaterial( { color: 0xffffff, envMap: refractionCube, refractionRatio: 0.85 } ),
-				h: 0, s: 0, l: 1
-			},
-
-				"shiny":
-			{
-				m: new THREE.MeshStandardMaterial( { color: 0x550000, envMap: reflectionCube, roughness: 0.1, metalness: 1.0 } ),
-				h: 0, s: 0.8, l: 0.2
-			},
-
-				"matte":
-			{
-				m: new THREE.MeshPhongMaterial( { color: 0x000000, specular: 0x111111, shininess: 1 } ),
-				h: 0, s: 0, l: 1
-			},
-
-				"flat":
-			{
-				m: new THREE.MeshLambertMaterial( { color: 0x000000, flatShading: true } ),
-				h: 0, s: 0, l: 1
-			},
-
-				"textured":
-			{
-				m: new THREE.MeshPhongMaterial( { color: 0xffffff, specular: 0x111111, shininess: 1, map: texture } ),
-				h: 0, s: 0, l: 1
-			},
-
-				"colors":
-			{
-				m: new THREE.MeshPhongMaterial( { color: 0xffffff, specular: 0xffffff, shininess: 2, vertexColors: THREE.VertexColors } ),
-				h: 0, s: 0, l: 1
-			},
-
-				"plastic":
-			{
-				m: new THREE.MeshPhongMaterial( { color: 0x000000, specular: 0x888888, shininess: 250 } ),
-				h: 0.6, s: 0.8, l: 0.1
-			},
-
-				"toon1":
-			{
-				m: toonMaterial1,
-				h: 0.2, s: 1, l: 0.75
-			},
-
-				"toon2":
-			{
-				m: toonMaterial2,
-				h: 0.4, s: 1, l: 0.75
-			},
-
-				"hatching":
-			{
-				m: hatchingMaterial,
-				h: 0.2, s: 1, l: 0.9
-			},
-
-				"hatching2":
-			{
-				m: hatchingMaterial2,
-				h: 0.0, s: 0.8, l: 0.5
-			},
-
-				"dotted":
-			{
-				m: dottedMaterial,
-				h: 0.2, s: 1, l: 0.9
-			},
-
-				"dotted2":
-			{
-				m: dottedMaterial2,
-				h: 0.1, s: 1, l: 0.5
-			}
+				"chrome": {
+					m: new THREE.MeshLambertMaterial( { color: 0xffffff, envMap: reflectionCube } ),
+					h: 0, s: 0, l: 1
+				},
+
+				"liquid": {
+					m: new THREE.MeshLambertMaterial( { color: 0xffffff, envMap: refractionCube, refractionRatio: 0.85 } ),
+					h: 0, s: 0, l: 1
+				},
+
+				"shiny": {
+					m: new THREE.MeshStandardMaterial( { color: 0x550000, envMap: reflectionCube, roughness: 0.1, metalness: 1.0 } ),
+					h: 0, s: 0.8, l: 0.2
+				},
+
+				"matte": {
+					m: new THREE.MeshPhongMaterial( { color: 0x000000, specular: 0x111111, shininess: 1 } ),
+					h: 0, s: 0, l: 1
+				},
+
+				"flat": {
+					m: new THREE.MeshLambertMaterial( { color: 0x000000, flatShading: true } ),
+					h: 0, s: 0, l: 1
+				},
+
+				"textured": {
+					m: new THREE.MeshPhongMaterial( { color: 0xffffff, specular: 0x111111, shininess: 1, map: texture } ),
+					h: 0, s: 0, l: 1
+				},
+
+				"colors": {
+					m: new THREE.MeshPhongMaterial( { color: 0xffffff, specular: 0xffffff, shininess: 2, vertexColors: THREE.VertexColors } ),
+					h: 0, s: 0, l: 1
+				},
+
+				"multiColors": {
+					m: new THREE.MeshPhongMaterial( { shininess: 2, vertexColors: THREE.VertexColors } ),
+					h: 0, s: 0, l: 1
+				},
+
+				"plastic": {
+					m: new THREE.MeshPhongMaterial( { color: 0x000000, specular: 0x888888, shininess: 250 } ),
+					h: 0.6, s: 0.8, l: 0.1
+				},
+
+				"toon1": {
+					m: toonMaterial1,
+					h: 0.2, s: 1, l: 0.75
+				},
+
+				"toon2": {
+					m: toonMaterial2,
+					h: 0.4, s: 1, l: 0.75
+				},
+
+				"hatching": {
+					m: hatchingMaterial,
+					h: 0.2, s: 1, l: 0.9
+				},
+
+				"dotted": {
+					m: dottedMaterial,
+					h: 0.2, s: 1, l: 0.9
+				}
 
 			};
 
@@ -423,7 +324,7 @@
 					m_l.setValue( mat.l );
 
 					effect.enableUvs = ( current_material === "textured" ) ? true : false;
-					effect.enableColors = ( current_material === "colors" ) ? true : false;
+					effect.enableColors = ( current_material === "colors" || current_material === "multiColors" ) ? true : false;
 
 				};
 
@@ -454,8 +355,6 @@
 				ly: 0.5,
 				lz: 1.0,
 
-				postprocessing: false,
-
 				dummy: function () {}
 
 			};
@@ -512,11 +411,6 @@
 			h.add( effectController, "wallx" );
 			h.add( effectController, "wallz" );
 
-			// rendering
-
-			h = gui.addFolder( "Rendering" );
-			h.add( effectController, "postprocessing" );
-
 		}
 
 		// this controls content of marching cubes voxel field
@@ -528,7 +422,15 @@
 			// fill the field with some metaballs
 
 			var i, ballx, bally, ballz, subtract, strength;
-
+			var rainbow = [
+					new THREE.Color(0xff0000),
+					new THREE.Color(0xff7f00),
+					new THREE.Color(0xffff00),
+					new THREE.Color(0x00ff00),
+					new THREE.Color(0x0000ff),
+					new THREE.Color(0x4b0082),
+					new THREE.Color(0x9400d3)
+				];
 			subtract = 12;
 			strength = 1.2 / ( ( Math.sqrt( numblobs ) - 1 ) / 4 + 1 );
 
@@ -538,7 +440,15 @@
 				bally = Math.abs( Math.cos( i + 1.12 * time * Math.cos( 1.22 + 0.1424 * i ) ) ) * 0.77; // dip into the floor
 				ballz = Math.cos( i + 1.32 * time * 0.1 * Math.sin( ( 0.92 + 0.53 * i ) ) ) * 0.27 + 0.5;
 
-				object.addBall( ballx, bally, ballz, strength, subtract );
+				if ( current_material === 'multiColors' ) {
+
+					object.addBall( ballx, bally, ballz, strength, subtract, rainbow[i % 7] );
+
+				} else {
+
+					object.addBall( ballx, bally, ballz, strength, subtract );
+
+				}
 
 			}
 
@@ -586,24 +496,7 @@
 
 			if ( effect.material instanceof THREE.ShaderMaterial ) {
 
-				if ( current_material === "dotted2" ) {
-
-					effect.material.uniforms[ "uLineColor1" ].value.setHSL( effectController.hue, effectController.saturation, effectController.lightness );
-
-				} else if ( current_material === "hatching2" ) {
-
-					var u = effect.material.uniforms;
-
-					u.uLineColor1.value.setHSL( effectController.hue, effectController.saturation, effectController.lightness );
-					u.uLineColor2.value.setHSL( effectController.hue, effectController.saturation, effectController.lightness );
-					u.uLineColor3.value.setHSL( effectController.hue, effectController.saturation, effectController.lightness );
-					u.uLineColor4.value.setHSL( ( effectController.hue + 0.2 % 1.0 ), effectController.saturation, effectController.lightness );
-
-				} else {
-
-					effect.material.uniforms[ "uBaseColor" ].value.setHSL( effectController.hue, effectController.saturation, effectController.lightness );
-
-				}
+				effect.material.uniforms[ "uBaseColor" ].value.setHSL( effectController.hue, effectController.saturation, effectController.lightness );
 
 			} else {
 
@@ -620,16 +513,7 @@
 
 			// render
 
-			if ( effectController.postprocessing ) {
-
-				composer.render( delta );
-
-			} else {
-
-				renderer.clear();
-				renderer.render( scene, camera );
-
-			}
+			renderer.render( scene, camera );
 
 		}
 

+ 47 - 61
examples/webgl_materials_cars.html

@@ -45,6 +45,9 @@
 		<script src="js/loaders/DRACOLoader.js"></script>
 		<script src="js/loaders/GLTFLoader.js"></script>
 
+		<script src="js/pmrem/PMREMGenerator.js"></script>
+		<script src="js/pmrem/PMREMCubeUVPacker.js"></script>
+
 		<script src="js/Car.js"></script>
 
 		<script src="js/WebGL.js"></script>
@@ -65,9 +68,7 @@
 			var glassMatSelect = document.getElementById( 'glass-mat' );
 
 			var followCamera = document.getElementById( 'camera-toggle' );
-			followCamera.addEventListener( 'change', onFollowCameraToggle );
 
-			var lightHolder = new THREE.Group();
 			var clock = new THREE.Clock();
 			var car = new THREE.Car();
 			car.turningRadius = 75;
@@ -81,7 +82,6 @@
 			var damping = 5.0;
 			var distance = 5;
 			var cameraTarget = new THREE.Vector3();
-			var origin = new THREE.Vector3();
 
 			function init() {
 
@@ -89,15 +89,35 @@
 
 				camera = new THREE.PerspectiveCamera( 50, window.innerWidth / window.innerHeight, 0.1, 200 );
 				camera.position.set( 3.25, 2.0, -5 );
+				camera.lookAt( 0, 0.5, 0 );
 
 				scene = new THREE.Scene();
 				scene.fog = new THREE.Fog( 0xd7cbb1, 1, 80 );
 
-				envMap = new THREE.CubeTextureLoader()
-					.setPath( 'textures/cube/skyboxsun25deg/')
-					.load( [ 'px.jpg', 'nx.jpg', 'py.jpg', 'ny.jpg', 'pz.jpg', 'nz.jpg' ] );
+				var urls = [ 'px.jpg', 'nx.jpg', 'py.jpg', 'ny.jpg', 'pz.jpg', 'nz.jpg' ];
+				var loader = new THREE.CubeTextureLoader().setPath( 'textures/cube/skyboxsun25deg/');
+				loader.load( urls, function ( texture ) {
+
+					scene.background = texture;
+
+					var pmremGenerator = new THREE.PMREMGenerator( texture );
+					pmremGenerator.update( renderer );
+
+					var pmremCubeUVPacker = new THREE.PMREMCubeUVPacker( pmremGenerator.cubeLods );
+					pmremCubeUVPacker.update( renderer );
+
+					envMap = pmremCubeUVPacker.CubeUVRenderTarget.texture;
 
-				scene.background = envMap;
+					pmremGenerator.dispose();
+					pmremCubeUVPacker.dispose();
+
+					//
+
+					initCar();
+					initMaterials();
+					initMaterialSelectionMenus();
+
+				} );
 
 				var ground = new THREE.Mesh(
 					new THREE.PlaneBufferGeometry( 2400, 2400 ),
@@ -114,28 +134,9 @@
 				grid.material.transparent = true;
 				scene.add( grid );
 
-				var hemiLight = new THREE.HemisphereLight( 0x7c849b, 0xd7cbb1, 0.1 );
-				hemiLight.position.set( 0, 1, 0 );
-				scene.add( hemiLight );
-
-				var shadowLight  = new THREE.DirectionalLight( 0xffffee, 0.1 );
-				shadowLight.position.set( -1.5, 1.25, -1.5 );
-				shadowLight.castShadow = true;
-				shadowLight.shadow.width = 512;
-				shadowLight.shadow.height = 512;
-				shadowLight.shadow.camera.top = 2;
-				shadowLight.shadow.camera.bottom = -2;
-				shadowLight.shadow.camera.left = -2.5;
-				shadowLight.shadow.camera.right = 2.5;
-				shadowLight.shadow.camera.far = 5.75;
-				shadowLight.shadow.bias = -0.025;
-
-				lightHolder.add( shadowLight, shadowLight.target );
-
 				renderer = new THREE.WebGLRenderer( { antialias: true } );
-				renderer.setPixelRatio( window.devicePixelRatio );
 				renderer.gammaOutput = true;
-				renderer.shadowMap.enabled = true;
+				renderer.setPixelRatio( window.devicePixelRatio );
 				renderer.setSize( window.innerWidth, window.innerHeight );
 
 				container.appendChild( renderer.domElement );
@@ -143,10 +144,6 @@
 				stats = new Stats();
 				container.appendChild( stats.dom );
 
-				initCar();
-				initMaterials();
-				initMaterialSelectionMenus();
-
 				window.addEventListener( 'resize', onWindowResize, false );
 
 				renderer.setAnimationLoop( function() {
@@ -170,17 +167,12 @@
 
 					carModel = gltf.scene.children[ 0 ];
 
-					// add lightHolder to car so that the shadow will track the car as it moves
-					carModel.add( lightHolder );
-
 					car.setModel( carModel );
 
 					carModel.traverse( function ( child ) {
 
 						if ( child.isMesh  ) {
 
-							child.castShadow = true;
-							child.receiveShadow = true;
 							child.material.envMap = envMap;
 
 						}
@@ -236,9 +228,9 @@
 
 					glass: [
 
-						new THREE.MeshStandardMaterial( { color: 0xffffff, envMap: envMap, metalness: 0.9, roughness: 0.1, opacity: 0.15, transparent: true, premultipliedAlpha: true, name: 'clear' } ),
-						new THREE.MeshStandardMaterial( { color: 0x000000, envMap: envMap, metalness: 0.9, roughness: 0.1, opacity: 0.15, transparent: true, premultipliedAlpha: true, name: 'smoked' } ),
-						new THREE.MeshStandardMaterial( { color: 0x001133, envMap: envMap, metalness: 0.9, roughness: 0.1, opacity: 0.15, transparent: true, premultipliedAlpha: true, name: 'blue' } ),
+						new THREE.MeshStandardMaterial( { color: 0xffffff, envMap: envMap, metalness: 1, roughness: 0, opacity: 0.2, transparent: true, premultipliedAlpha: true, name: 'clear' } ),
+						new THREE.MeshStandardMaterial( { color: 0x000000, envMap: envMap, metalness: 1, roughness: 0, opacity: 0.2, transparent: true, premultipliedAlpha: true, name: 'smoked' } ),
+						new THREE.MeshStandardMaterial( { color: 0x001133, envMap: envMap, metalness: 1, roughness: 0, opacity: 0.2, transparent: true, premultipliedAlpha: true, name: 'blue' } ),
 
 					],
 
@@ -270,8 +262,8 @@
 
 				} );
 
-				bodyMatSelect.selectedIndex = 2;
-				rimMatSelect.selectedIndex = 4;
+				bodyMatSelect.selectedIndex = 3;
+				rimMatSelect.selectedIndex = 5;
 				glassMatSelect.selectedIndex = 0;
 
 				bodyMatSelect.addEventListener( 'change', updateMaterials );
@@ -302,12 +294,6 @@
 
 			}
 
-			function onFollowCameraToggle() {
-
-				carModel.position.copy( origin );
-
-			}
-
 			function update() {
 
 				var delta = clock.getDelta();
@@ -316,10 +302,14 @@
 
 					car.update( delta / 3 );
 
-					resetPosition();
+					console.log(   );
 
-					// keep the light (and shadow) pointing in the same direction as the car rotates
-					lightHolder.rotation.y = -carModel.rotation.y;
+					if ( carModel.position.length() > 200 ) {
+
+						carModel.position.set( 0, 0, 0 );
+						car.speed = 0;
+
+					}
 
 					if ( followCamera.checked ) {
 
@@ -329,6 +319,13 @@
 
 						camera.position.lerp( cameraTarget, delta * damping );
 
+					} else {
+
+						carModel.getWorldPosition( cameraTarget );
+						cameraTarget.y += 0.5;
+
+						camera.position.set( 3.25, 2.0, -5 );
+
 					}
 
 					camera.lookAt( carModel.position );
@@ -339,17 +336,6 @@
 
 			}
 
-			function resetPosition() {
-
-				if ( carModel.position.distanceTo( origin ) > 200 ) {
-
-					carModel.position.copy( origin );
-					car.speed = 0;
-
-				}
-
-			}
-
 			init();
 
 		</script>

+ 10 - 19
examples/webgl_materials_standard.html

@@ -46,8 +46,6 @@
 
 		<script src="js/controls/TrackballControls.js"></script>
 		<script src="js/loaders/OBJLoader.js"></script>
-		<script src="js/loaders/RGBELoader.js"></script>
-		<script src="js/loaders/HDRCubeTextureLoader.js"></script>
 
 		<script src="js/pmrem/PMREMGenerator.js"></script>
 		<script src="js/pmrem/PMREMCubeUVPacker.js"></script>
@@ -140,33 +138,26 @@
 
 					} );
 
-				var genCubeUrls = function ( prefix, postfix ) {
+				new THREE.CubeTextureLoader().setPath( './textures/cube/pisaRGBM16/' )
+					.load( [ 'px.png', 'nx.png', 'py.png', 'ny.png', 'pz.png', 'nz.png' ], function ( rgbmCubeMap ) {
 
-					return [
-						prefix + 'px' + postfix, prefix + 'nx' + postfix,
-						prefix + 'py' + postfix, prefix + 'ny' + postfix,
-						prefix + 'pz' + postfix, prefix + 'nz' + postfix
-					];
+					rgbmCubeMap.encoding = THREE.RGBM16Encoding;
+					rgbmCubeMap.format = THREE.RGBAFormat;
 
-				};
-
-				var hdrUrls = genCubeUrls( './textures/cube/pisaHDR/', '.hdr' );
-				new THREE.HDRCubeTextureLoader().load( THREE.UnsignedByteType, hdrUrls, function ( hdrCubeMap ) {
-
-					var pmremGenerator = new THREE.PMREMGenerator( hdrCubeMap );
+					var pmremGenerator = new THREE.PMREMGenerator( rgbmCubeMap );
 					pmremGenerator.update( renderer );
 
 					var pmremCubeUVPacker = new THREE.PMREMCubeUVPacker( pmremGenerator.cubeLods );
 					pmremCubeUVPacker.update( renderer );
 
-					var hdrCubeRenderTarget = pmremCubeUVPacker.CubeUVRenderTarget;
+					var rgbmCubeRenderTarget = pmremCubeUVPacker.CubeUVRenderTarget;
 
-					material.envMap = hdrCubeRenderTarget.texture;
+					material.envMap = rgbmCubeRenderTarget.texture;
 					material.needsUpdate = true; // is this needed?
 
-					hdrCubeMap.magFilter = THREE.LinearFilter;
-					hdrCubeMap.needsUpdate = true;
-					scene.background = hdrCubeMap;
+					rgbmCubeMap.magFilter = THREE.LinearFilter;
+					rgbmCubeMap.needsUpdate = true;
+					scene.background = rgbmCubeMap;
 
 					pmremGenerator.dispose();
 					pmremCubeUVPacker.dispose();

+ 4 - 0
examples/webgl_morphtargets_horse.html

@@ -78,6 +78,10 @@
 				renderer = new THREE.WebGLRenderer();
 				renderer.setPixelRatio( window.devicePixelRatio );
 				renderer.setSize( window.innerWidth, window.innerHeight );
+
+				renderer.gammaOutput = true;
+				renderer.gammaFactor = 2.2;
+
 				container.appendChild(renderer.domElement);
 
 				//

+ 4 - 3
examples/webgl_panorama_equirectangular.html

@@ -66,9 +66,10 @@
 				// invert the geometry on the x-axis so that all of the faces point inward
 				geometry.scale( - 1, 1, 1 );
 
-				var material = new THREE.MeshBasicMaterial( {
-					map: new THREE.TextureLoader().load( 'textures/2294472375_24a3b8ef46_o.jpg' )
-				} );
+				var texture = new THREE.TextureLoader().load( 'textures/2294472375_24a3b8ef46_o.jpg' );
+				texture.minFilter = THREE.LinearFilter;
+
+				var material = new THREE.MeshBasicMaterial( { map: texture } );
 
 				mesh = new THREE.Mesh( geometry, material );
 

+ 1 - 0
examples/webgl_performance_static.html

@@ -46,6 +46,7 @@
 
 				scene = new THREE.Scene();
 				scene.background = new THREE.Color( 0xffffff );
+				scene.matrixAutoUpdate = false;
 
 				var material = new THREE.MeshNormalMaterial();
 

+ 9 - 0
examples/webgl_postprocessing_dof2.html

@@ -332,6 +332,15 @@
 				camera.aspect = window.innerWidth / window.innerHeight;
 				camera.updateProjectionMatrix();
 
+				windowHalfX = window.innerWidth / 2;
+				windowHalfY = window.innerHeight / 2;
+
+				postprocessing.rtTextureDepth.setSize( window.innerWidth, window.innerHeight );
+				postprocessing.rtTextureColor.setSize( window.innerWidth, window.innerHeight );
+
+				postprocessing.bokeh_uniforms[ 'textureWidth' ].value = window.innerWidth;
+				postprocessing.bokeh_uniforms[ 'textureHeight' ].value = window.innerHeight;
+
 				renderer.setSize( window.innerWidth, window.innerHeight );
 
 			}

+ 3 - 1
examples/webgl_shadowmap.html

@@ -134,6 +134,8 @@
 				renderer.setSize( SCREEN_WIDTH, SCREEN_HEIGHT );
 				container.appendChild( renderer.domElement );
 
+				renderer.gammaOutput = true;
+				renderer.gammaFactor = 2.2;
 				renderer.autoClear = false;
 
 				//
@@ -195,7 +197,7 @@
 				// GROUND
 
 				var geometry = new THREE.PlaneBufferGeometry( 100, 100 );
-				var planeMaterial = new THREE.MeshPhongMaterial( { color: 0xffdd99 } );
+				var planeMaterial = new THREE.MeshPhongMaterial( { color: 0xffb851 } );
 
 				var ground = new THREE.Mesh( geometry, planeMaterial );
 

+ 117 - 123
package-lock.json

@@ -1,6 +1,6 @@
 {
   "name": "three",
-  "version": "0.101.1",
+  "version": "0.102.0",
   "lockfileVersion": 1,
   "requires": true,
   "dependencies": {
@@ -31,15 +31,15 @@
       "dev": true
     },
     "@types/node": {
-      "version": "10.12.25",
-      "resolved": "https://registry.npmjs.org/@types/node/-/node-10.12.25.tgz",
-      "integrity": "sha512-IcvnGLGSQFDvC07Bz2I8SX+QKErDZbUdiQq7S2u3XyzTyJfUmT0sWJMbeQkMzpTAkO7/N7sZpW/arUM2jfKsbQ==",
+      "version": "10.12.27",
+      "resolved": "https://registry.npmjs.org/@types/node/-/node-10.12.27.tgz",
+      "integrity": "sha512-e9wgeY6gaY21on3ve0xAjgBVjGDWq/xUteK0ujsE53bUoxycMkqfnkUgMt6ffZtykZ5X12Mg3T7Pw4TRCObDKg==",
       "dev": true
     },
     "acorn": {
-      "version": "6.1.0",
-      "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.1.0.tgz",
-      "integrity": "sha512-MW/FjM+IvU9CgBzjO3UIPCE2pyEwUsoFl+VGdczOPEdxfGFjuKny/gN54mOuX7Qxmb9Rg9MCn2oKiSUeW+pjrw==",
+      "version": "6.1.1",
+      "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.1.1.tgz",
+      "integrity": "sha512-jPTiwtOxaHNaAPg/dmrJ/beuzLRnXtB0kQPQ8JpotKJgTB6rX6c8mlf315941pyjBSaPg8NHXS9fhP4u17DpGA==",
       "dev": true
     },
     "acorn-jsx": {
@@ -49,9 +49,9 @@
       "dev": true
     },
     "ajv": {
-      "version": "6.9.1",
-      "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.9.1.tgz",
-      "integrity": "sha512-XDN92U311aINL77ieWHmqCcNlwjoP5cHXDxIxbf2MaPYuCXOHS7gHH8jktxeK5omgd52XbSTX6a4Piwd1pQmzA==",
+      "version": "6.9.2",
+      "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.9.2.tgz",
+      "integrity": "sha512-4UFy0/LgDo7Oa/+wOAlj44tp9K78u38E5/359eSrqEp1Z5PdVfimCcs7SluXMP755RUQu6d2b4AvF0R1C9RZjg==",
       "dev": true,
       "requires": {
         "fast-deep-equal": "^2.0.1",
@@ -192,7 +192,7 @@
     },
     "camelcase-keys": {
       "version": "2.1.0",
-      "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-2.1.0.tgz",
+      "resolved": "http://registry.npmjs.org/camelcase-keys/-/camelcase-keys-2.1.0.tgz",
       "integrity": "sha1-MIvur/3ygRkFHvodkyITyRuPkuc=",
       "dev": true,
       "requires": {
@@ -242,12 +242,6 @@
       "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==",
       "dev": true
     },
-    "circular-json": {
-      "version": "0.3.3",
-      "resolved": "https://registry.npmjs.org/circular-json/-/circular-json-0.3.3.tgz",
-      "integrity": "sha512-UZK3NBx2Mca+b5LsG7bY183pHWt5Y1xts4P3Pz7ENTwGVnJOUWbRb3ocjvX7hx9tq/yTAdclXm9sZ38gNuem4A==",
-      "dev": true
-    },
     "cli-cursor": {
       "version": "2.1.0",
       "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz",
@@ -295,7 +289,7 @@
     "cloneable-readable": {
       "version": "1.1.2",
       "resolved": "https://registry.npmjs.org/cloneable-readable/-/cloneable-readable-1.1.2.tgz",
-      "integrity": "sha1-1ZHe5Kj4vBXaQ86X3O66E9Q+KmU=",
+      "integrity": "sha512-Bq6+4t+lbM8vhTs/Bef5c5AdEMtapp/iFb6+s4/Hh9MVTt8OLKH7ZOOZSCT+Ys7hsHvqv0GuMPJ1lnQJVHvxpg==",
       "dev": true,
       "requires": {
         "inherits": "^2.0.1",
@@ -538,9 +532,9 @@
       "dev": true
     },
     "doctrine": {
-      "version": "2.1.0",
-      "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz",
-      "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==",
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz",
+      "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==",
       "dev": true,
       "requires": {
         "esutils": "^2.0.2"
@@ -612,9 +606,9 @@
       }
     },
     "electron": {
-      "version": "4.0.4",
-      "resolved": "https://registry.npmjs.org/electron/-/electron-4.0.4.tgz",
-      "integrity": "sha512-zG5VtLrmPfmw1fXY/3BEtRZk7OZ7djQhweZ6rW+R5NeF6s8RTz/AwTGtLoBo4z8wmJ5QTy0Y941FZw4pe5YlpA==",
+      "version": "4.0.6",
+      "resolved": "https://registry.npmjs.org/electron/-/electron-4.0.6.tgz",
+      "integrity": "sha512-r2ow/EmDibjoCNJp35mB1CcPs2xBF9fp2eoWuUOJmpVQyzdba6EnqsSD1BxwXzF9vQ5WkQ2UbfXBIvpomrdioQ==",
       "dev": true,
       "requires": {
         "@types/node": "^10.12.18",
@@ -699,35 +693,35 @@
       "dev": true
     },
     "eslint": {
-      "version": "5.13.0",
-      "resolved": "https://registry.npmjs.org/eslint/-/eslint-5.13.0.tgz",
-      "integrity": "sha512-nqD5WQMisciZC5EHZowejLKQjWGuFS5c70fxqSKlnDME+oz9zmE8KTlX+lHSg+/5wsC/kf9Q9eMkC8qS3oM2fg==",
+      "version": "5.15.0",
+      "resolved": "https://registry.npmjs.org/eslint/-/eslint-5.15.0.tgz",
+      "integrity": "sha512-xwG7SS5JLeqkiR3iOmVgtF8Y6xPdtr6AAsN6ph7Q6R/fv+3UlKYoika8SmNzmb35qdRF+RfTY35kMEdtbi+9wg==",
       "dev": true,
       "requires": {
         "@babel/code-frame": "^7.0.0",
-        "ajv": "^6.5.3",
+        "ajv": "^6.9.1",
         "chalk": "^2.1.0",
         "cross-spawn": "^6.0.5",
         "debug": "^4.0.1",
-        "doctrine": "^2.1.0",
-        "eslint-scope": "^4.0.0",
+        "doctrine": "^3.0.0",
+        "eslint-scope": "^4.0.2",
         "eslint-utils": "^1.3.1",
         "eslint-visitor-keys": "^1.0.0",
-        "espree": "^5.0.0",
+        "espree": "^5.0.1",
         "esquery": "^1.0.1",
         "esutils": "^2.0.2",
-        "file-entry-cache": "^2.0.0",
+        "file-entry-cache": "^5.0.1",
         "functional-red-black-tree": "^1.0.1",
         "glob": "^7.1.2",
         "globals": "^11.7.0",
         "ignore": "^4.0.6",
         "import-fresh": "^3.0.0",
         "imurmurhash": "^0.1.4",
-        "inquirer": "^6.1.0",
+        "inquirer": "^6.2.2",
         "js-yaml": "^3.12.0",
         "json-stable-stringify-without-jsonify": "^1.0.1",
         "levn": "^0.3.0",
-        "lodash": "^4.17.5",
+        "lodash": "^4.17.11",
         "minimatch": "^3.0.4",
         "mkdirp": "^0.5.1",
         "natural-compare": "^1.4.0",
@@ -738,7 +732,7 @@
         "semver": "^5.5.1",
         "strip-ansi": "^4.0.0",
         "strip-json-comments": "^2.0.1",
-        "table": "^5.0.2",
+        "table": "^5.2.3",
         "text-table": "^0.2.0"
       },
       "dependencies": {
@@ -775,9 +769,9 @@
       }
     },
     "eslint-scope": {
-      "version": "4.0.0",
-      "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-4.0.0.tgz",
-      "integrity": "sha512-1G6UTDi7Jc1ELFwnR58HV4fK9OQK4S6N985f166xqXxpjU6plxFISJa2Ba9KCQuFa8RCnj/lSFJbHo7UFDBnUA==",
+      "version": "4.0.2",
+      "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-4.0.2.tgz",
+      "integrity": "sha512-5q1+B/ogmHl8+paxtOKx38Z8LtWkVGuNt3+GQNErqwLl6ViNp/gdJGMCjZNxZ8j/VYjDNZ2Fo+eQc1TAVPIzbg==",
       "dev": true,
       "requires": {
         "esrecurse": "^4.1.0",
@@ -797,12 +791,12 @@
       "dev": true
     },
     "espree": {
-      "version": "5.0.0",
-      "resolved": "https://registry.npmjs.org/espree/-/espree-5.0.0.tgz",
-      "integrity": "sha512-1MpUfwsdS9MMoN7ZXqAr9e9UKdVHDcvrJpyx7mm1WuQlx/ygErEQBzgi5Nh5qBHIoYweprhtMkTCb9GhcAIcsA==",
+      "version": "5.0.1",
+      "resolved": "https://registry.npmjs.org/espree/-/espree-5.0.1.tgz",
+      "integrity": "sha512-qWAZcWh4XE/RwzLJejfcofscgMc9CamR6Tn1+XRXNzrvUSSbiAjGOI/fggztjIi7y9VLPqnICMIPiGyr8JaZ0A==",
       "dev": true,
       "requires": {
-        "acorn": "^6.0.2",
+        "acorn": "^6.0.7",
         "acorn-jsx": "^5.0.0",
         "eslint-visitor-keys": "^1.0.0"
       }
@@ -936,13 +930,12 @@
       }
     },
     "file-entry-cache": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-2.0.0.tgz",
-      "integrity": "sha1-w5KZDD5oR4PYOLjISkXYoEhFg2E=",
+      "version": "5.0.1",
+      "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-5.0.1.tgz",
+      "integrity": "sha512-bCg29ictuBaKUwwArK4ouCaqDgLZcysCFLmM/Yn/FDoqndh/9vNuQfXRDvTuXKLxfD/JtZQGKFT8MGcJBK644g==",
       "dev": true,
       "requires": {
-        "flat-cache": "^1.2.1",
-        "object-assign": "^4.0.1"
+        "flat-cache": "^2.0.1"
       }
     },
     "find-up": {
@@ -955,17 +948,22 @@
       }
     },
     "flat-cache": {
-      "version": "1.3.4",
-      "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-1.3.4.tgz",
-      "integrity": "sha512-VwyB3Lkgacfik2vhqR4uv2rvebqmDvFu4jlN/C1RzWoJEo8I7z4Q404oiqYCkq41mni8EzQnm95emU9seckwtg==",
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-2.0.1.tgz",
+      "integrity": "sha512-LoQe6yDuUMDzQAEH8sgmh4Md6oZnc/7PjtwjNFSzveXqSHt6ka9fPBuso7IGf9Rz4uqnSnWiFH2B/zj24a5ReA==",
       "dev": true,
       "requires": {
-        "circular-json": "^0.3.1",
-        "graceful-fs": "^4.1.2",
-        "rimraf": "~2.6.2",
-        "write": "^0.2.1"
+        "flatted": "^2.0.0",
+        "rimraf": "2.6.3",
+        "write": "1.0.3"
       }
     },
+    "flatted": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/flatted/-/flatted-2.0.0.tgz",
+      "integrity": "sha512-R+H8IZclI8AAkSBRQJLVOsxwAoHd6WC40b4QTNWIjzAa6BXOBfQcM587MXDTVPeYaopFNWHUFLx7eNmHDSxMWg==",
+      "dev": true
+    },
     "follow-redirects": {
       "version": "1.5.7",
       "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.5.7.tgz",
@@ -1077,16 +1075,16 @@
       "dev": true
     },
     "google-closure-compiler": {
-      "version": "20181210.0.0",
-      "resolved": "https://registry.npmjs.org/google-closure-compiler/-/google-closure-compiler-20181210.0.0.tgz",
-      "integrity": "sha512-GCMLakdibnc+jpdNTvF3M/ET5i6I4zzxGKw67A4bQahxc0TPLXQdkVfhF3kwBSoPfK8xwgU5kA+KO0qvDZHKHw==",
+      "version": "20190215.0.2",
+      "resolved": "https://registry.npmjs.org/google-closure-compiler/-/google-closure-compiler-20190215.0.2.tgz",
+      "integrity": "sha512-yhxVcm2bl05IoombIiTs5mRZChjJaOg4riFtrtsJrJL8WR1a2lz3btH6giX4+NgWduD5LNg4joF9BT4xLfzkIQ==",
       "dev": true,
       "requires": {
         "chalk": "^1.0.0",
-        "google-closure-compiler-java": "^20181210.0.0",
-        "google-closure-compiler-js": "^20181210.0.0",
-        "google-closure-compiler-linux": "^20181210.0.0",
-        "google-closure-compiler-osx": "^20181210.0.0",
+        "google-closure-compiler-java": "^20190215.0.1",
+        "google-closure-compiler-js": "^20190215.0.1",
+        "google-closure-compiler-linux": "^20190215.0.1",
+        "google-closure-compiler-osx": "^20190215.0.1",
         "minimist": "^1.2.0",
         "vinyl": "^2.0.1",
         "vinyl-sourcemaps-apply": "^0.2.0"
@@ -1106,7 +1104,7 @@
         },
         "chalk": {
           "version": "1.1.3",
-          "resolved": "http://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
+          "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
           "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=",
           "dev": true,
           "requires": {
@@ -1135,28 +1133,28 @@
       }
     },
     "google-closure-compiler-java": {
-      "version": "20181210.0.0",
-      "resolved": "https://registry.npmjs.org/google-closure-compiler-java/-/google-closure-compiler-java-20181210.0.0.tgz",
-      "integrity": "sha512-FMGzY+vp25DePolYNyVcXz8UI2PV/I3AYU3nuFexmHcKn5XiBVy4CqK7em6NpVbZdDXJYUF3GUv5A0x0gLvbfw==",
+      "version": "20190215.0.2",
+      "resolved": "https://registry.npmjs.org/google-closure-compiler-java/-/google-closure-compiler-java-20190215.0.2.tgz",
+      "integrity": "sha512-G/H5X47DQ2NqJc47aMQw/8RJ8m4+CDufabEm07Q3K7QHyxA7heHPHzFE/4Z+PZhKa+sGNmBqfsVt6SRfdDYp9A==",
       "dev": true
     },
     "google-closure-compiler-js": {
-      "version": "20181210.0.0",
-      "resolved": "https://registry.npmjs.org/google-closure-compiler-js/-/google-closure-compiler-js-20181210.0.0.tgz",
-      "integrity": "sha512-gn+2hT4uQtYKD/jXJqGIXzPMln3/JD7R4caAKDPJm7adqqDvrCAw7qxAiK4Vz1rNec7hJXPXh9TeKQjzz03ZaQ==",
+      "version": "20190215.0.2",
+      "resolved": "https://registry.npmjs.org/google-closure-compiler-js/-/google-closure-compiler-js-20190215.0.2.tgz",
+      "integrity": "sha512-tBu+xxFTZxo/SNz0NkZzSaO1L0EblyulCLBxsDtOsohyprXBAmoti8Cp2ZakzTmlnSp7dT8sbCemjehxXMQPfg==",
       "dev": true
     },
     "google-closure-compiler-linux": {
-      "version": "20181210.0.0",
-      "resolved": "https://registry.npmjs.org/google-closure-compiler-linux/-/google-closure-compiler-linux-20181210.0.0.tgz",
-      "integrity": "sha512-Gp+yp+Vb6QWEhtYkePKxkspRlzX5dx6L46zUoHGWW7Henuk3ACYoUXuaHLQQ+tF0lmi2QAmFXEkvdnKVDIxR+Q==",
+      "version": "20190215.0.2",
+      "resolved": "https://registry.npmjs.org/google-closure-compiler-linux/-/google-closure-compiler-linux-20190215.0.2.tgz",
+      "integrity": "sha512-gznwt/wE2GbvsKYSlCVBxGXwLuTuOf2ram12j8SCfdwptjJCCWWv+HupHlqXeDedDYzUWVCvhniSd6zExYOcvQ==",
       "dev": true,
       "optional": true
     },
     "google-closure-compiler-osx": {
-      "version": "20181210.0.0",
-      "resolved": "https://registry.npmjs.org/google-closure-compiler-osx/-/google-closure-compiler-osx-20181210.0.0.tgz",
-      "integrity": "sha512-SYUakmEpq8BorJU/O5CfrC+ABYjXR0rTvBd3Khwd1sml9B2aKEiHArdHC5SCmBRZd3ccUhp/XyrVO6PoxHKeZA==",
+      "version": "20190215.0.2",
+      "resolved": "https://registry.npmjs.org/google-closure-compiler-osx/-/google-closure-compiler-osx-20190215.0.2.tgz",
+      "integrity": "sha512-jg3ajI+ZKhfUg7t9W3zvDsZyfkR1zPppjat1i2RYsTBhFzhPWZHmoB0TPGPVI3xJ5/DNUEZ0QwwX0ybgldEE7A==",
       "dev": true,
       "optional": true
     },
@@ -1391,12 +1389,6 @@
             "supports-color": "^5.3.0"
           }
         },
-        "lodash": {
-          "version": "4.17.11",
-          "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz",
-          "integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==",
-          "dev": true
-        },
         "strip-ansi": {
           "version": "5.0.0",
           "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.0.0.tgz",
@@ -1508,9 +1500,9 @@
       "dev": true
     },
     "js-yaml": {
-      "version": "3.12.1",
-      "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.12.1.tgz",
-      "integrity": "sha512-um46hB9wNOKlwkHgiuyEVAybXBjwFUV0Z/RaHJblRd9DXltue9FTYvzCr9ErQrK9Adz5MU4gHWVaNUfdmrC8qA==",
+      "version": "3.12.2",
+      "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.12.2.tgz",
+      "integrity": "sha512-QHn/Lh/7HhZ/Twc7vJYQTkjuCa0kaCcDcjK5Zlk2rvnUpy7DxMJ23+Jc2dcyvltwQVg1nygAVlB2oRDFHoRS5Q==",
       "dev": true,
       "requires": {
         "argparse": "^1.0.7",
@@ -1595,7 +1587,7 @@
     },
     "load-json-file": {
       "version": "1.1.0",
-      "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz",
+      "resolved": "http://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz",
       "integrity": "sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA=",
       "dev": true,
       "requires": {
@@ -1617,7 +1609,7 @@
         },
         "pify": {
           "version": "2.3.0",
-          "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
+          "resolved": "http://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
           "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=",
           "dev": true
         }
@@ -1634,9 +1626,9 @@
       }
     },
     "lodash": {
-      "version": "4.17.10",
-      "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.10.tgz",
-      "integrity": "sha512-UejweD1pDoXu+AD825lWwp4ZGtSwgnpZxb3JDViD7StjQz+Nb/6l093lx4OQ0foGWNRoc19mWy7BzL+UAK2iVg==",
+      "version": "4.17.11",
+      "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz",
+      "integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==",
       "dev": true
     },
     "loud-rejection": {
@@ -1677,7 +1669,7 @@
     },
     "meow": {
       "version": "3.7.0",
-      "resolved": "https://registry.npmjs.org/meow/-/meow-3.7.0.tgz",
+      "resolved": "http://registry.npmjs.org/meow/-/meow-3.7.0.tgz",
       "integrity": "sha1-cstmi0JSKCkKu/qFaJJYcwioAfs=",
       "dev": true,
       "requires": {
@@ -1700,18 +1692,18 @@
       "dev": true
     },
     "mime-db": {
-      "version": "1.37.0",
-      "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.37.0.tgz",
-      "integrity": "sha512-R3C4db6bgQhlIhPU48fUtdVmKnflq+hRdad7IyKhtFj06VPNVdk2RhiYL3UjQIlso8L+YxAtFkobT0VK+S/ybg==",
+      "version": "1.38.0",
+      "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.38.0.tgz",
+      "integrity": "sha512-bqVioMFFzc2awcdJZIzR3HjZFX20QhilVS7hytkKrv7xFAn8bM1gzc/FOX2awLISvWe0PV8ptFKcon+wZ5qYkg==",
       "dev": true
     },
     "mime-types": {
-      "version": "2.1.21",
-      "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.21.tgz",
-      "integrity": "sha512-3iL6DbwpyLzjR3xHSFNFeb9Nz/M8WDkX33t1GFQnFOllWk8pOrh/LSrB5OXlnlW5P9LH73X6loW/eogc+F5lJg==",
+      "version": "2.1.22",
+      "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.22.tgz",
+      "integrity": "sha512-aGl6TZGnhm/li6F7yx82bJiBZwgiEa4Hf6CNr8YO+r5UHr53tSTYZb102zyU50DOWWKeOv0uQLRL0/9EiKWCog==",
       "dev": true,
       "requires": {
-        "mime-db": "~1.37.0"
+        "mime-db": "~1.38.0"
       }
     },
     "mimic-fn": {
@@ -1917,7 +1909,7 @@
     },
     "os-tmpdir": {
       "version": "1.0.2",
-      "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz",
+      "resolved": "http://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz",
       "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=",
       "dev": true
     },
@@ -1990,7 +1982,7 @@
     },
     "path-is-absolute": {
       "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
+      "resolved": "http://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
       "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=",
       "dev": true
     },
@@ -2142,16 +2134,16 @@
       "dev": true
     },
     "qunit": {
-      "version": "2.9.1",
-      "resolved": "https://registry.npmjs.org/qunit/-/qunit-2.9.1.tgz",
-      "integrity": "sha512-ipXgW4SD557GrQtiBhj+g7eHk76pmSIYKglEXuAD/WsC06XzXDc4r9qlm4DSG5LxqxvpgK8naGlJ1Zcnj9/NdQ==",
+      "version": "2.9.2",
+      "resolved": "https://registry.npmjs.org/qunit/-/qunit-2.9.2.tgz",
+      "integrity": "sha512-wTOYHnioWHcx5wa85Wl15IE7D6zTZe2CQlsodS14yj7s2FZ3MviRnQluspBZsueIDEO7doiuzKlv05yfky1R7w==",
       "dev": true,
       "requires": {
         "commander": "2.12.2",
         "js-reporters": "1.2.1",
         "minimatch": "3.0.4",
         "node-watch": "0.6.0",
-        "resolve": "1.5.0"
+        "resolve": "1.9.0"
       }
     },
     "rc": {
@@ -2221,7 +2213,7 @@
     },
     "readable-stream": {
       "version": "1.1.14",
-      "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz",
+      "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz",
       "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=",
       "dev": true,
       "requires": {
@@ -2315,12 +2307,12 @@
       "dev": true
     },
     "resolve": {
-      "version": "1.5.0",
-      "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.5.0.tgz",
-      "integrity": "sha512-hgoSGrc3pjzAPHNBg+KnFcK2HwlHTs/YrAGUr6qgTVUZmXv1UEXXl0bZNBKMA9fud6lRYFdPGz0xXxycPzmmiw==",
+      "version": "1.9.0",
+      "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.9.0.tgz",
+      "integrity": "sha512-TZNye00tI67lwYvzxCxHGjwTNlUV70io54/Ed4j6PscB8xVfuBJpRenI/o6dVk0cY0PYTY27AgCoGGxRnYuItQ==",
       "dev": true,
       "requires": {
-        "path-parse": "^1.0.5"
+        "path-parse": "^1.0.6"
       }
     },
     "resolve-from": {
@@ -2349,14 +2341,22 @@
       }
     },
     "rollup": {
-      "version": "1.1.2",
-      "resolved": "https://registry.npmjs.org/rollup/-/rollup-1.1.2.tgz",
-      "integrity": "sha512-OkdMxqMl8pWoQc5D8y1cIinYQPPLV8ZkfLgCzL6SytXeNA2P7UHynEQXI9tYxuAjAMsSyvRaWnyJDLHMxq0XAg==",
+      "version": "1.4.0",
+      "resolved": "https://registry.npmjs.org/rollup/-/rollup-1.4.0.tgz",
+      "integrity": "sha512-E5HP4rgvAqkXQNYfNHgCDnX5HDHwAPDLUVSNp8iTmT49vY34G0DxEfhjPWnqnFi7v0vQtDGkKl2hvLfmsMvmcA==",
       "dev": true,
       "requires": {
         "@types/estree": "0.0.39",
-        "@types/node": "*",
-        "acorn": "^6.0.5"
+        "@types/node": "^11.9.5",
+        "acorn": "^6.1.1"
+      },
+      "dependencies": {
+        "@types/node": {
+          "version": "11.10.4",
+          "resolved": "https://registry.npmjs.org/@types/node/-/node-11.10.4.tgz",
+          "integrity": "sha512-wa09itaLE8L705aXd8F80jnFpxz3Y1/KRHfKsYL2bPc0XF+wEWu8sR9n5bmeu8Ba1N9z2GRNzm/YdHcghLkLKg==",
+          "dev": true
+        }
       }
     },
     "run-async": {
@@ -2651,12 +2651,6 @@
           "integrity": "sha512-iB5Dda8t/UqpPI/IjsejXu5jOGDrzn41wJyljwPH65VCIbk6+1BzFIMJGFwTNrYXT1CrD+B4l19U7awiQ8rk7w==",
           "dev": true
         },
-        "lodash": {
-          "version": "4.17.11",
-          "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz",
-          "integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==",
-          "dev": true
-        },
         "string-width": {
           "version": "3.0.0",
           "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.0.0.tgz",
@@ -2693,13 +2687,13 @@
     },
     "through": {
       "version": "2.3.8",
-      "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz",
+      "resolved": "http://registry.npmjs.org/through/-/through-2.3.8.tgz",
       "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=",
       "dev": true
     },
     "through2": {
       "version": "0.2.3",
-      "resolved": "https://registry.npmjs.org/through2/-/through2-0.2.3.tgz",
+      "resolved": "http://registry.npmjs.org/through2/-/through2-0.2.3.tgz",
       "integrity": "sha1-6zKE2k6jEbbMis42U3SKUqvyWj8=",
       "dev": true,
       "requires": {
@@ -2951,9 +2945,9 @@
       "dev": true
     },
     "write": {
-      "version": "0.2.1",
-      "resolved": "https://registry.npmjs.org/write/-/write-0.2.1.tgz",
-      "integrity": "sha1-X8A4KOJkzqP+kUVUdvejxWbLB1c=",
+      "version": "1.0.3",
+      "resolved": "https://registry.npmjs.org/write/-/write-1.0.3.tgz",
+      "integrity": "sha512-/lg70HAjtkUgWPVZhZcm+T4hkL8Zbtp1nFNOn3lRrxnlv50SRBv7cR7RqR+GMsd3hUXy9hWBo4CHTbFTcOYwig==",
       "dev": true,
       "requires": {
         "mkdirp": "^0.5.1"

+ 6 - 6
package.json

@@ -1,6 +1,6 @@
 {
   "name": "three",
-  "version": "0.101.1",
+  "version": "0.102.1",
   "description": "JavaScript 3D library",
   "main": "build/three.js",
   "repository": "mrdoob/three.js",
@@ -57,14 +57,14 @@
   "homepage": "https://threejs.org/",
   "devDependencies": {
     "concurrently": "^4.1.0",
-    "electron": "^4.0.4",
-    "eslint": "^5.13.0",
+    "electron": "^4.0.6",
+    "eslint": "^5.15.0",
     "eslint-config-mdcs": "^4.2.3",
     "eslint-plugin-html": "^5.0.3",
-    "google-closure-compiler": "20181210.0.0",
+    "google-closure-compiler": "20190215.0.2",
     "http-server": "^0.11.1",
-    "qunit": "^2.9.1",
-    "rollup": "^1.1.2"
+    "qunit": "^2.9.2",
+    "rollup": "^1.4.0"
   },
   "jspm": {
     "files": [

+ 167 - 153
src/Three.d.ts

@@ -1,160 +1,174 @@
-import './polyfills';
-
-export {
-  WebGLMultisampleRenderTarget,
-} from './renderers/WebGLMultisampleRenderTarget';
-export { WebGLRenderTargetCube } from './renderers/WebGLRenderTargetCube';
-export { WebGLRenderTarget } from './renderers/WebGLRenderTarget';
-export { WebGLRenderer } from './renderers/WebGLRenderer';
-export { ShaderLib } from './renderers/shaders/ShaderLib';
-export { UniformsLib } from './renderers/shaders/UniformsLib';
-export { UniformsUtils } from './renderers/shaders/UniformsUtils';
-export { ShaderChunk } from './renderers/shaders/ShaderChunk';
-export { FogExp2 } from './scenes/FogExp2';
-export { Fog } from './scenes/Fog';
-export { Scene } from './scenes/Scene';
-export { Sprite } from './objects/Sprite';
-export { LOD } from './objects/LOD';
-export { SkinnedMesh } from './objects/SkinnedMesh';
-export { Skeleton } from './objects/Skeleton';
-export { Bone } from './objects/Bone';
-export { Mesh } from './objects/Mesh';
-export { LineSegments } from './objects/LineSegments';
-export { LineLoop } from './objects/LineLoop';
-export { Line } from './objects/Line';
-export { Points } from './objects/Points';
-export { Group } from './objects/Group';
-export { VideoTexture } from './textures/VideoTexture';
-export { DataTexture } from './textures/DataTexture';
-export { DataTexture3D } from './textures/DataTexture3D';
-export { CompressedTexture } from './textures/CompressedTexture';
-export { CubeTexture } from './textures/CubeTexture';
-export { CanvasTexture } from './textures/CanvasTexture';
-export { DepthTexture } from './textures/DepthTexture';
-export { Texture } from './textures/Texture';
+export * from './polyfills';
+export * from './renderers/WebGLMultisampleRenderTarget';
+export * from './renderers/WebGLRenderTargetCube';
+export * from './renderers/WebGLRenderTarget';
+export * from './renderers/WebGLRenderer';
+export * from './renderers/shaders/ShaderLib';
+export * from './renderers/shaders/UniformsLib';
+export * from './renderers/shaders/UniformsUtils';
+export * from './renderers/shaders/ShaderChunk';
+export * from './scenes/FogExp2';
+export * from './scenes/Fog';
+export * from './scenes/Scene';
+export * from './objects/Sprite';
+export * from './objects/LOD';
+export * from './objects/SkinnedMesh';
+export * from './objects/Skeleton';
+export * from './objects/Bone';
+export * from './objects/Mesh';
+export * from './objects/LineSegments';
+export * from './objects/LineLoop';
+export * from './objects/Line';
+export * from './objects/Points';
+export * from './objects/Group';
+export * from './textures/VideoTexture';
+export * from './textures/DataTexture';
+export * from './textures/DataTexture3D';
+export * from './textures/CompressedTexture';
+export * from './textures/CubeTexture';
+export * from './textures/CanvasTexture';
+export * from './textures/DepthTexture';
+export * from './textures/Texture';
 export * from './geometries/Geometries';
 export * from './materials/Materials';
-//export { AnimationLoader } from './loaders/AnimationLoader';
-export { CompressedTextureLoader } from './loaders/CompressedTextureLoader';
-export { DataTextureLoader } from './loaders/DataTextureLoader';
-export { CubeTextureLoader } from './loaders/CubeTextureLoader';
-export { TextureLoader } from './loaders/TextureLoader';
-export { ObjectLoader } from './loaders/ObjectLoader';
-export { MaterialLoader } from './loaders/MaterialLoader';
-export { BufferGeometryLoader } from './loaders/BufferGeometryLoader';
-export { LoadingManager } from './loaders/LoadingManager';
-export { ImageLoader } from './loaders/ImageLoader';
-export { ImageBitmapLoader } from './loaders/ImageBitmapLoader';
-export { FontLoader } from './loaders/FontLoader';
-export { FileLoader } from './loaders/FileLoader';
-export { Loader } from './loaders/Loader';
-export { LoaderUtils } from './loaders/LoaderUtils';
-export { Cache } from './loaders/Cache';
-export { AudioLoader } from './loaders/AudioLoader';
-export { SpotLightShadow } from './lights/SpotLightShadow';
-export { SpotLight } from './lights/SpotLight';
-export { PointLight } from './lights/PointLight';
-export { RectAreaLight } from './lights/RectAreaLight';
-export { HemisphereLight } from './lights/HemisphereLight';
-export { DirectionalLightShadow } from './lights/DirectionalLightShadow';
-export { DirectionalLight } from './lights/DirectionalLight';
-export { AmbientLight } from './lights/AmbientLight';
-export { LightShadow } from './lights/LightShadow';
-export { Light } from './lights/Light';
-export { StereoCamera } from './cameras/StereoCamera';
-export { PerspectiveCamera } from './cameras/PerspectiveCamera';
-export { OrthographicCamera } from './cameras/OrthographicCamera';
-export { CubeCamera } from './cameras/CubeCamera';
-export { ArrayCamera } from './cameras/ArrayCamera';
-export { Camera } from './cameras/Camera';
-export { AudioListener } from './audio/AudioListener';
-export { PositionalAudio } from './audio/PositionalAudio';
-export { AudioContext } from './audio/AudioContext';
-export { AudioAnalyser } from './audio/AudioAnalyser';
-export { Audio } from './audio/Audio';
-export { VectorKeyframeTrack } from './animation/tracks/VectorKeyframeTrack';
-export { StringKeyframeTrack } from './animation/tracks/StringKeyframeTrack';
-export {
-  QuaternionKeyframeTrack,
-} from './animation/tracks/QuaternionKeyframeTrack';
-export { NumberKeyframeTrack } from './animation/tracks/NumberKeyframeTrack';
-export { ColorKeyframeTrack } from './animation/tracks/ColorKeyframeTrack';
-export { BooleanKeyframeTrack } from './animation/tracks/BooleanKeyframeTrack';
-export { PropertyMixer } from './animation/PropertyMixer';
-export { PropertyBinding } from './animation/PropertyBinding';
-export { KeyframeTrack } from './animation/KeyframeTrack';
-export { AnimationUtils } from './animation/AnimationUtils';
-export { AnimationObjectGroup } from './animation/AnimationObjectGroup';
-export { AnimationMixer } from './animation/AnimationMixer';
-export { AnimationClip } from './animation/AnimationClip';
-export { Uniform } from './core/Uniform';
-export { InstancedBufferGeometry } from './core/InstancedBufferGeometry';
-export { BufferGeometry } from './core/BufferGeometry';
-export { Geometry } from './core/Geometry';
-export { InterleavedBufferAttribute } from './core/InterleavedBufferAttribute';
-export { InstancedInterleavedBuffer } from './core/InstancedInterleavedBuffer';
-export { InterleavedBuffer } from './core/InterleavedBuffer';
-export { InstancedBufferAttribute } from './core/InstancedBufferAttribute';
+export * from './loaders/AnimationLoader';
+export * from './loaders/CompressedTextureLoader';
+export * from './loaders/DataTextureLoader';
+export * from './loaders/CubeTextureLoader';
+export * from './loaders/TextureLoader';
+export * from './loaders/ObjectLoader';
+export * from './loaders/MaterialLoader';
+export * from './loaders/BufferGeometryLoader';
+export * from './loaders/LoadingManager';
+export * from './loaders/ImageLoader';
+export * from './loaders/ImageBitmapLoader';
+export * from './loaders/FontLoader';
+export * from './loaders/FileLoader';
+export * from './loaders/Loader';
+export * from './loaders/LoaderUtils';
+export * from './loaders/Cache';
+export * from './loaders/AudioLoader';
+export * from './lights/SpotLightShadow';
+export * from './lights/SpotLight';
+export * from './lights/PointLight';
+export * from './lights/RectAreaLight';
+export * from './lights/HemisphereLight';
+export * from './lights/DirectionalLightShadow';
+export * from './lights/DirectionalLight';
+export * from './lights/AmbientLight';
+export * from './lights/LightShadow';
+export * from './lights/Light';
+export * from './cameras/StereoCamera';
+export * from './cameras/PerspectiveCamera';
+export * from './cameras/OrthographicCamera';
+export * from './cameras/CubeCamera';
+export * from './cameras/ArrayCamera';
+export * from './cameras/Camera';
+export * from './audio/AudioListener';
+export * from './audio/PositionalAudio';
+export * from './audio/AudioContext';
+export * from './audio/AudioAnalyser';
+export * from './audio/Audio';
+export * from './animation/tracks/VectorKeyframeTrack';
+export * from './animation/tracks/StringKeyframeTrack';
+export * from './animation/tracks/QuaternionKeyframeTrack';
+export * from './animation/tracks/NumberKeyframeTrack';
+export * from './animation/tracks/ColorKeyframeTrack';
+export * from './animation/tracks/BooleanKeyframeTrack';
+export * from './animation/PropertyMixer';
+export * from './animation/PropertyBinding';
+export * from './animation/KeyframeTrack';
+export * from './animation/AnimationUtils';
+export * from './animation/AnimationObjectGroup';
+export * from './animation/AnimationMixer';
+export * from './animation/AnimationClip';
+export * from './animation/AnimationAction';
+export * from './core/Uniform';
+export * from './core/InstancedBufferGeometry';
+export * from './core/BufferGeometry';
+export * from './core/Geometry';
+export * from './core/InterleavedBufferAttribute';
+export * from './core/InstancedInterleavedBuffer';
+export * from './core/InterleavedBuffer';
+export * from './core/InstancedBufferAttribute';
 export * from './core/BufferAttribute';
-export { Face3 } from './core/Face3';
-export { Object3D } from './core/Object3D';
-export { Raycaster } from './core/Raycaster';
-export { Layers } from './core/Layers';
-export { EventDispatcher } from './core/EventDispatcher';
-export { Clock } from './core/Clock';
-export {
-  QuaternionLinearInterpolant,
-} from './math/interpolants/QuaternionLinearInterpolant';
-export { LinearInterpolant } from './math/interpolants/LinearInterpolant';
-export { DiscreteInterpolant } from './math/interpolants/DiscreteInterpolant';
-export { CubicInterpolant } from './math/interpolants/CubicInterpolant';
-export { Interpolant } from './math/Interpolant';
-export { Triangle } from './math/Triangle';
+export * from './core/Face3';
+export * from './core/Object3D';
+export * from './core/Raycaster';
+export * from './core/Layers';
+export * from './core/EventDispatcher';
+export * from './core/DirectGeometry';
+export * from './core/Clock';
+export * from './math/interpolants/QuaternionLinearInterpolant';
+export * from './math/interpolants/LinearInterpolant';
+export * from './math/interpolants/DiscreteInterpolant';
+export * from './math/interpolants/CubicInterpolant';
+export * from './math/Interpolant';
+export * from './math/Triangle';
 export { _Math as Math } from './math/Math';
-export { Spherical } from './math/Spherical';
-export { Cylindrical } from './math/Cylindrical';
-export { Plane } from './math/Plane';
-export { Frustum } from './math/Frustum';
-export { Sphere } from './math/Sphere';
-export { Ray } from './math/Ray';
-export { Matrix4 } from './math/Matrix4';
-export { Matrix3 } from './math/Matrix3';
-export { Box3 } from './math/Box3';
-export { Box2 } from './math/Box2';
-export { Line3 } from './math/Line3';
-export { Euler } from './math/Euler';
-export { Vector4 } from './math/Vector4';
-export { Vector3 } from './math/Vector3';
-export { Vector2 } from './math/Vector2';
-export { Quaternion } from './math/Quaternion';
-export { Color } from './math/Color';
-export { ImmediateRenderObject } from './extras/objects/ImmediateRenderObject';
-export { VertexNormalsHelper } from './helpers/VertexNormalsHelper';
-export { SpotLightHelper } from './helpers/SpotLightHelper';
-export { SkeletonHelper } from './helpers/SkeletonHelper';
-export { PointLightHelper } from './helpers/PointLightHelper';
-export { RectAreaLightHelper } from './helpers/RectAreaLightHelper';
-export { HemisphereLightHelper } from './helpers/HemisphereLightHelper';
-export { GridHelper } from './helpers/GridHelper';
-export { PolarGridHelper } from './helpers/PolarGridHelper';
-export { PositionalAudioHelper } from './helpers/PositionalAudioHelper';
-export { FaceNormalsHelper } from './helpers/FaceNormalsHelper';
-export { DirectionalLightHelper } from './helpers/DirectionalLightHelper';
-export { CameraHelper } from './helpers/CameraHelper';
-export { BoxHelper } from './helpers/BoxHelper';
-export { Box3Helper } from './helpers/Box3Helper';
-export { PlaneHelper } from './helpers/PlaneHelper';
-export { ArrowHelper } from './helpers/ArrowHelper';
-export { AxesHelper } from './helpers/AxesHelper';
+export * from './math/Spherical';
+export * from './math/Cylindrical';
+export * from './math/Plane';
+export * from './math/Frustum';
+export * from './math/Sphere';
+export * from './math/Ray';
+export * from './math/Matrix4';
+export * from './math/Matrix3';
+export * from './math/Box3';
+export * from './math/Box2';
+export * from './math/Line3';
+export * from './math/Euler';
+export * from './math/Vector4';
+export * from './math/Vector3';
+export * from './math/Vector2';
+export * from './math/Quaternion';
+export * from './math/Color';
+export * from './extras/objects/ImmediateRenderObject';
+export * from './helpers/VertexNormalsHelper';
+export * from './helpers/SpotLightHelper';
+export * from './helpers/SkeletonHelper';
+export * from './helpers/PointLightHelper';
+export * from './helpers/RectAreaLightHelper';
+export * from './helpers/HemisphereLightHelper';
+export * from './helpers/GridHelper';
+export * from './helpers/PolarGridHelper';
+export * from './helpers/PositionalAudioHelper';
+export * from './helpers/FaceNormalsHelper';
+export * from './helpers/DirectionalLightHelper';
+export * from './helpers/CameraHelper';
+export * from './helpers/BoxHelper';
+export * from './helpers/Box3Helper';
+export * from './helpers/PlaneHelper';
+export * from './helpers/ArrowHelper';
+export * from './helpers/AxesHelper';
 export * from './extras/curves/Curves';
-export { Shape } from './extras/core/Shape';
-export { Path } from './extras/core/Path';
-export { ShapePath } from './extras/core/ShapePath';
-export { Font } from './extras/core/Font';
-export { CurvePath } from './extras/core/CurvePath';
-export { Curve } from './extras/core/Curve';
-export { ImageUtils } from './extras/ImageUtils';
-export { ShapeUtils } from './extras/ShapeUtils';
-//export { WebGLUtils } from './renderers/webgl/WebGLUtils';
+export * from './extras/core/Shape';
+export * from './extras/core/Path';
+export * from './extras/core/ShapePath';
+export * from './extras/core/Font';
+export * from './extras/core/CurvePath';
+export * from './extras/core/Curve';
+export * from './extras/ImageUtils';
+export * from './extras/ShapeUtils';
+export * from './renderers/webgl/WebGLBufferRenderer';
+export * from './renderers/webgl/WebGLCapabilities';
+export * from './renderers/webgl/WebGLClipping';
+export * from './renderers/webgl/WebGLExtensions';
+export * from './renderers/webgl/WebGLGeometries';
+export * from './renderers/webgl/WebGLIndexedBufferRenderer';
+export * from './renderers/webgl/WebGLInfo';
+export * from './renderers/webgl/WebGLLights';
+export * from './renderers/webgl/WebGLObjects';
+export * from './renderers/webgl/WebGLProgram';
+export * from './renderers/webgl/WebGLPrograms';
+export * from './renderers/webgl/WebGLProperties';
+export * from './renderers/webgl/WebGLRenderLists';
+export * from './renderers/webgl/WebGLShader';
+export * from './renderers/webgl/WebGLShadowMap';
+export * from './renderers/webgl/WebGLState';
+export * from './renderers/webgl/WebGLTextures';
+export * from './renderers/webgl/WebGLUniforms';
+//export * from './renderers/webgl/WebGLUtils';
+export * from './renderers/webvr/WebVRManager';
 export * from './constants';
 export * from './Three.Legacy';

+ 1 - 2
src/cameras/CubeCamera.js

@@ -97,8 +97,7 @@ function CubeCamera( near, far, cubeResolution, options ) {
 
 		for ( var i = 0; i < 6; i ++ ) {
 
-			renderTarget.activeCubeFace = i;
-			renderer.setRenderTarget( renderTarget );
+			renderer.setRenderTarget( renderTarget, i );
 
 			renderer.clear( color, depth, stencil );
 

+ 6 - 6
src/cameras/PerspectiveCamera.js

@@ -130,17 +130,17 @@ PerspectiveCamera.prototype = Object.assign( Object.create( Camera.prototype ),
 	 *   var fullHeight = h * 2;
 	 *
 	 *   --A--
-	 *   camera.setOffset( fullWidth, fullHeight, w * 0, h * 0, w, h );
+	 *   camera.setViewOffset( fullWidth, fullHeight, w * 0, h * 0, w, h );
 	 *   --B--
-	 *   camera.setOffset( fullWidth, fullHeight, w * 1, h * 0, w, h );
+	 *   camera.setViewOffset( fullWidth, fullHeight, w * 1, h * 0, w, h );
 	 *   --C--
-	 *   camera.setOffset( fullWidth, fullHeight, w * 2, h * 0, w, h );
+	 *   camera.setViewOffset( fullWidth, fullHeight, w * 2, h * 0, w, h );
 	 *   --D--
-	 *   camera.setOffset( fullWidth, fullHeight, w * 0, h * 1, w, h );
+	 *   camera.setViewOffset( fullWidth, fullHeight, w * 0, h * 1, w, h );
 	 *   --E--
-	 *   camera.setOffset( fullWidth, fullHeight, w * 1, h * 1, w, h );
+	 *   camera.setViewOffset( fullWidth, fullHeight, w * 1, h * 1, w, h );
 	 *   --F--
-	 *   camera.setOffset( fullWidth, fullHeight, w * 2, h * 1, w, h );
+	 *   camera.setViewOffset( fullWidth, fullHeight, w * 2, h * 1, w, h );
 	 *
 	 *   Note there is no reason monitors have to be the same size or in a grid.
 	 */

+ 1 - 1
src/constants.js

@@ -1,4 +1,4 @@
-export var REVISION = '102dev';
+export var REVISION = '103dev';
 export var MOUSE = { LEFT: 0, MIDDLE: 1, RIGHT: 2 };
 export var CullFaceNone = 0;
 export var CullFaceBack = 1;

+ 10 - 10
src/extras/curves/Curves.d.ts

@@ -1,10 +1,10 @@
-export { ArcCurve } from './ArcCurve';
-export { CatmullRomCurve3 } from './CatmullRomCurve3';
-export { CubicBezierCurve } from './CubicBezierCurve';
-export { CubicBezierCurve3 } from './CubicBezierCurve3';
-export { EllipseCurve } from './EllipseCurve';
-export { LineCurve } from './LineCurve';
-export { LineCurve3 } from './LineCurve3';
-export { QuadraticBezierCurve } from './QuadraticBezierCurve';
-export { QuadraticBezierCurve3 } from './QuadraticBezierCurve3';
-export { SplineCurve } from './SplineCurve';
+export * from './ArcCurve';
+export * from './CatmullRomCurve3';
+export * from './CubicBezierCurve';
+export * from './CubicBezierCurve3';
+export * from './EllipseCurve';
+export * from './LineCurve';
+export * from './LineCurve3';
+export * from './QuadraticBezierCurve';
+export * from './QuadraticBezierCurve3';
+export * from './SplineCurve';

+ 22 - 43
src/geometries/Geometries.d.ts

@@ -1,43 +1,22 @@
-export { WireframeGeometry } from './WireframeGeometry';
-export {
-  ParametricGeometry,
-  ParametricBufferGeometry,
-} from './ParametricGeometry';
-export {
-  TetrahedronGeometry,
-  TetrahedronBufferGeometry,
-} from './TetrahedronGeometry';
-export {
-  OctahedronGeometry,
-  OctahedronBufferGeometry,
-} from './OctahedronGeometry';
-export {
-  IcosahedronGeometry,
-  IcosahedronBufferGeometry,
-} from './IcosahedronGeometry';
-export {
-  DodecahedronGeometry,
-  DodecahedronBufferGeometry,
-} from './DodecahedronGeometry';
-export {
-  PolyhedronGeometry,
-  PolyhedronBufferGeometry,
-} from './PolyhedronGeometry';
-export { TubeGeometry, TubeBufferGeometry } from './TubeGeometry';
-export {
-  TorusKnotGeometry,
-  TorusKnotBufferGeometry,
-} from './TorusKnotGeometry';
-export { TorusGeometry, TorusBufferGeometry } from './TorusGeometry';
-export { TextGeometry, TextBufferGeometry } from './TextGeometry';
-export { SphereGeometry, SphereBufferGeometry } from './SphereGeometry';
-export { RingGeometry, RingBufferGeometry } from './RingGeometry';
-export { PlaneGeometry, PlaneBufferGeometry } from './PlaneGeometry';
-export { LatheGeometry, LatheBufferGeometry } from './LatheGeometry';
-export { ShapeGeometry, ShapeBufferGeometry } from './ShapeGeometry';
-export { ExtrudeGeometry, ExtrudeBufferGeometry } from './ExtrudeGeometry';
-export { EdgesGeometry } from './EdgesGeometry';
-export { ConeGeometry, ConeBufferGeometry } from './ConeGeometry';
-export { CylinderGeometry, CylinderBufferGeometry } from './CylinderGeometry';
-export { CircleGeometry, CircleBufferGeometry } from './CircleGeometry';
-export { BoxGeometry, BoxBufferGeometry } from './BoxGeometry';
+export * from './WireframeGeometry';
+export * from './ParametricGeometry';
+export * from './TetrahedronGeometry';
+export * from './OctahedronGeometry';
+export * from './IcosahedronGeometry';
+export * from './DodecahedronGeometry';
+export * from './PolyhedronGeometry';
+export * from './TubeGeometry';
+export * from './TorusKnotGeometry';
+export * from './TorusGeometry';
+export * from './TextGeometry';
+export * from './SphereGeometry';
+export * from './RingGeometry';
+export * from './PlaneGeometry';
+export * from './LatheGeometry';
+export * from './ShapeGeometry';
+export * from './ExtrudeGeometry';
+export * from './EdgesGeometry';
+export * from './ConeGeometry';
+export * from './CylinderGeometry';
+export * from './CircleGeometry';
+export * from './BoxGeometry';

+ 1 - 1
src/loaders/LoadingManager.d.ts

@@ -32,7 +32,7 @@ export class LoadingManager {
   constructor(
     onLoad?: () => void,
     onProgress?: (url: string, loaded: number, total: number) => void,
-    onError?: () => void
+    onError?: (url: string) => void
   );
 
   onStart?: (url: string, loaded: number, total: number) => void;

+ 18 - 18
src/materials/Materials.d.ts

@@ -1,18 +1,18 @@
-export { ShadowMaterial } from './ShadowMaterial';
-export { SpriteMaterial } from './SpriteMaterial';
-export { RawShaderMaterial } from './RawShaderMaterial';
-export { ShaderMaterial } from './ShaderMaterial';
-export { PointsMaterial } from './PointsMaterial';
-export { MeshPhysicalMaterial } from './MeshPhysicalMaterial';
-export { MeshStandardMaterial } from './MeshStandardMaterial';
-export { MeshPhongMaterial } from './MeshPhongMaterial';
-//export { MeshToonMaterial } from './MeshToonMaterial';
-export { MeshNormalMaterial } from './MeshNormalMaterial';
-export { MeshLambertMaterial } from './MeshLambertMaterial';
-export { MeshDepthMaterial } from './MeshDepthMaterial';
-//export { MeshDistanceMaterial } from './MeshDistanceMaterial';
-export { MeshBasicMaterial } from './MeshBasicMaterial';
-//export { MeshMatcapMaterial } from './MeshMatcapMaterial';
-export { LineDashedMaterial } from './LineDashedMaterial';
-export { LineBasicMaterial } from './LineBasicMaterial';
-export { Material } from './Material';
+export * from './ShadowMaterial';
+export * from './SpriteMaterial';
+export * from './RawShaderMaterial';
+export * from './ShaderMaterial';
+export * from './PointsMaterial';
+export * from './MeshPhysicalMaterial';
+export * from './MeshStandardMaterial';
+export * from './MeshPhongMaterial';
+//export * from './MeshToonMaterial';
+export * from './MeshNormalMaterial';
+export * from './MeshLambertMaterial';
+export * from './MeshDepthMaterial';
+//export * from './MeshDistanceMaterial';
+export * from './MeshBasicMaterial';
+//export * from './MeshMatcapMaterial';
+export * from './LineDashedMaterial';
+export * from './LineBasicMaterial';
+export * from './Material';

+ 1 - 1
src/objects/Line.d.ts

@@ -15,7 +15,7 @@ export class Line extends Object3D {
   geometry: Geometry | BufferGeometry;
   material: Material | Material[];
 
-  type: 'Line';
+  type: 'Line' | 'LineLoop' | 'LineSegments';
   isLine: true;
 
   computeLineDistances(): this;

+ 3 - 0
src/objects/LineLoop.d.ts

@@ -8,4 +8,7 @@ export class LineLoop extends Line {
     geometry?: Geometry | BufferGeometry,
     material?: Material | Material[]
   );
+
+  type: 'LineLoop';
+  isLineLoop: true;
 }

+ 3 - 0
src/objects/LineSegments.d.ts

@@ -18,4 +18,7 @@ export class LineSegments extends Line {
     material?: Material | Material[],
     mode?: number
   );
+
+  type: 'LineSegments';
+  isLineSegments: true;
 }

+ 1 - 1
src/polyfills.d.ts

@@ -4,7 +4,7 @@ export function error(message?: any, ...optionalParams: any[]): void;
 export function log(message?: any, ...optionalParams: any[]): void;
 
 // typed array parameters
-type TypedArray =
+export type TypedArray =
   | Int8Array
   | Uint8Array
   | Uint8ClampedArray

+ 4 - 6
src/renderers/WebGLRenderer.d.ts

@@ -70,16 +70,14 @@ export interface WebGLRendererParameters {
   preserveDrawingBuffer?: boolean;
 
   /**
-   * default is 0x000000.
+   *  Can be "high-performance", "low-power" or "default"
    */
-  clearColor?: number;
+  powerPreference?: string;
 
   /**
-   * default is 0.
+   * default is true.
    */
-  clearAlpha?: number;
-
-  devicePixelRatio?: number;
+  depth?: boolean;
 
   /**
    * default is false.

+ 4 - 9
src/renderers/WebGLRenderer.js

@@ -706,7 +706,7 @@ function WebGLRenderer( parameters ) {
 
 	this.renderBufferDirect = function ( camera, fog, geometry, material, object, group ) {
 
-		var frontFaceCW = ( object.isMesh && object.normalMatrix.determinant() < 0 );
+		var frontFaceCW = ( object.isMesh && object.matrixWorld.determinant() < 0 );
 
 		state.setMaterial( material, frontFaceCW );
 
@@ -2462,16 +2462,11 @@ function WebGLRenderer( parameters ) {
 
 	}() );
 
-	this.setTexture3D = ( function () {
+	this.setTexture3D = function ( texture, slot ) {
 
-		// backwards compatibility: peel texture.texture
-		return function setTexture3D( texture, slot ) {
-
-			textures.setTexture3D( texture, slot );
-
-		};
+		textures.setTexture3D( texture, slot );
 
-	}() );
+	};
 
 	this.setTexture = ( function () {
 

+ 3 - 0
src/renderers/webgl/WebGLBackground.js

@@ -27,6 +27,9 @@ function WebGLBackground( renderer, state, objects, premultipliedAlpha ) {
 
 		var background = scene.background;
 
+		var session = renderer.vr.getSession();
+		if ( session && session.environmentBlendMode === 'additive' ) background = null;
+
 		if ( background === null ) {
 
 			setClear( clearColor, clearAlpha );

+ 1 - 1
src/renderers/webgl/WebGLPrograms.js

@@ -163,7 +163,7 @@ function WebGLPrograms( renderer, extensions, capabilities ) {
 
 			combine: material.combine,
 
-			vertexTangents: material.vertexTangents,
+			vertexTangents: ( material.normalMap && material.vertexTangents ),
 			vertexColors: material.vertexColors,
 
 			fog: !! fog,

+ 3 - 1
src/renderers/webgl/WebGLTextures.js

@@ -42,7 +42,9 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils,
 
 			// only perform resize for certain image types
 
-			if ( image instanceof ImageBitmap || image instanceof HTMLImageElement || image instanceof HTMLCanvasElement ) {
+			if ( ( typeof HTMLImageElement !== 'undefined' && image instanceof HTMLImageElement ) ||
+				( typeof HTMLCanvasElement !== 'undefined' && image instanceof HTMLCanvasElement ) ||
+				( typeof ImageBitmap !== 'undefined' && image instanceof ImageBitmap ) ) {
 
 				var floor = needsPowerOfTwo ? _Math.floorPowerOfTwo : Math.floor;
 

+ 1 - 1
src/renderers/webgl/WebGLUniforms.js

@@ -476,7 +476,7 @@ function getSingularSetter( type ) {
 		case 0x8b5c: return setValue4fm; // _MAT4
 
 		case 0x8b5e: case 0x8d66: return setValueT1; // SAMPLER_2D, SAMPLER_EXTERNAL_OES
-		case 0x8B5F: return setValueT3D1; // SAMPLER_3D
+		case 0x8b5f: return setValueT3D1; // SAMPLER_3D
 		case 0x8b60: return setValueT6; // SAMPLER_CUBE
 
 		case 0x1404: case 0x8b56: return setValue1i; // INT, BOOL

+ 3 - 3
src/renderers/webvr/WebVRManager.js

@@ -234,9 +234,11 @@ function WebVRManager( renderer ) {
 
 		var userHeight = frameOfReferenceType === 'stage' ? 1.6 : 0;
 
-		if ( device === null ) {
+		if ( isPresenting() === false ) {
 
 			camera.position.set( 0, userHeight, 0 );
+			camera.rotation.set( 0, 0, 0 );
+
 			return camera;
 
 		}
@@ -290,8 +292,6 @@ function WebVRManager( renderer ) {
 
 		poseObject.updateMatrixWorld();
 
-		if ( device.isPresenting === false ) return camera;
-
 		//
 
 		cameraL.near = camera.near;

+ 3 - 1
src/renderers/webvr/WebXRManager.js

@@ -8,6 +8,7 @@ import { ArrayCamera } from '../../cameras/ArrayCamera.js';
 import { PerspectiveCamera } from '../../cameras/PerspectiveCamera.js';
 import { WebGLAnimation } from '../webgl/WebGLAnimation.js';
 import { setProjectionFromUnion } from './WebVRUtils.js';
+import { Matrix4 } from '../../math/Matrix4';
 
 function WebXRManager( renderer ) {
 
@@ -93,6 +94,7 @@ function WebXRManager( renderer ) {
 	function onSessionEnd() {
 
 		renderer.setFramebuffer( null );
+		renderer.setRenderTarget( renderer.getRenderTarget() ); // Hack #15830
 		animation.stop();
 
 	}
@@ -302,7 +304,7 @@ function WebXRManager( renderer ) {
 	this.getStandingMatrix = function () {
 
 		console.warn( 'THREE.WebXRManager: getStandingMatrix() is no longer needed.' );
-		return new THREE.Matrix4();
+		return new Matrix4();
 
 	};
 

+ 18 - 14
src/scenes/Fog.js

@@ -1,10 +1,10 @@
-import { Color } from '../math/Color.js';
-
 /**
  * @author mrdoob / http://mrdoob.com/
  * @author alteredq / http://alteredqualia.com/
  */
 
+import { Color } from '../math/Color.js';
+
 function Fog( color, near, far ) {
 
 	this.name = '';
@@ -16,23 +16,27 @@ function Fog( color, near, far ) {
 
 }
 
-Fog.prototype.isFog = true;
+Object.assign( Fog.prototype, {
+
+	isFog: true,
+
+	clone: function () {
 
-Fog.prototype.clone = function () {
+		return new Fog( this.color, this.near, this.far );
 
-	return new Fog( this.color, this.near, this.far );
+	},
 
-};
+	toJSON: function ( /* meta */ ) {
 
-Fog.prototype.toJSON = function ( /* meta */ ) {
+		return {
+			type: 'Fog',
+			color: this.color.getHex(),
+			near: this.near,
+			far: this.far
+		};
 
-	return {
-		type: 'Fog',
-		color: this.color.getHex(),
-		near: this.near,
-		far: this.far
-	};
+	}
 
-};
+} );
 
 export { Fog };

+ 17 - 13
src/scenes/FogExp2.js

@@ -1,10 +1,10 @@
-import { Color } from '../math/Color.js';
-
 /**
  * @author mrdoob / http://mrdoob.com/
  * @author alteredq / http://alteredqualia.com/
  */
 
+import { Color } from '../math/Color.js';
+
 function FogExp2( color, density ) {
 
 	this.name = '';
@@ -14,22 +14,26 @@ function FogExp2( color, density ) {
 
 }
 
-FogExp2.prototype.isFogExp2 = true;
+Object.assign( FogExp2.prototype, {
+
+	isFogExp2: true,
+
+	clone: function () {
 
-FogExp2.prototype.clone = function () {
+		return new FogExp2( this.color, this.density );
 
-	return new FogExp2( this.color, this.density );
+	},
 
-};
+	toJSON: function ( /* meta */ ) {
 
-FogExp2.prototype.toJSON = function ( /* meta */ ) {
+		return {
+			type: 'FogExp2',
+			color: this.color.getHex(),
+			density: this.density
+		};
 
-	return {
-		type: 'FogExp2',
-		color: this.color.getHex(),
-		density: this.density
-	};
+	}
 
-};
+} );
 
 export { FogExp2 };

Энэ ялгаанд хэт олон файл өөрчлөгдсөн тул зарим файлыг харуулаагүй болно