Pārlūkot izejas kodu

Merge branch 'dev' into ChainableEffect

Takahiro 8 gadi atpakaļ
vecāks
revīzija
1ced6b3ab3
80 mainītis faili ar 3153 papildinājumiem un 1497 dzēšanām
  1. 5 2
      README.md
  2. 173 175
      build/three.js
  3. 0 0
      build/three.js.map
  4. 244 248
      build/three.min.js
  5. 172 174
      build/three.modules.js
  6. 0 0
      build/three.modules.js.map
  7. 65 0
      docs/api/cameras/StereoCamera.html
  8. 0 0
      docs/api/constants/Renderer.html
  9. 5 1
      docs/api/core/BufferAttribute.html
  10. 63 0
      docs/api/extras/CurveUtils.html
  11. 88 0
      docs/api/extras/ShapeUtils.html
  12. 32 0
      docs/api/extras/core/Font.html
  13. 75 0
      docs/api/extras/helpers/SkeletonHelper.html
  14. 57 0
      docs/api/geometries/EdgesGeometry.html
  15. 63 0
      docs/api/geometries/WireframeGeometry.html
  16. 10 2
      docs/api/materials/MeshBasicMaterial.html
  17. 71 0
      docs/api/materials/MeshPhysicalMaterial.html
  18. 56 0
      docs/api/materials/ShadowMaterial.html
  19. 84 0
      docs/api/math/Interpolant.html
  20. 54 26
      docs/api/math/Math.html
  21. 87 0
      docs/api/math/interpolants/CubicInterpolant.html
  22. 87 0
      docs/api/math/interpolants/DiscreteInterpolant.html
  23. 87 0
      docs/api/math/interpolants/LinearInterpolant.html
  24. 87 0
      docs/api/math/interpolants/QuaternionLinearInterpolant.html
  25. 59 0
      docs/api/objects/Group.html
  26. 10 3
      docs/api/renderers/CanvasRenderer.html
  27. 292 163
      docs/api/renderers/WebGLRenderer.html
  28. 118 0
      docs/api/textures/DepthTexture.html
  29. 0 5
      docs/api/textures/Texture.html
  30. 24 4
      docs/list.js
  31. 7 1
      examples/js/animation/MMDPhysics.js
  32. 140 27
      examples/js/effects/OutlineEffect.js
  33. 1 1
      examples/js/loaders/GLTFLoader.js
  34. 418 227
      examples/js/loaders/MMDLoader.js
  35. 0 3
      examples/js/loaders/deprecated/gltf/glTFLoader.js
  36. 108 108
      examples/js/renderers/WebGLDeferredRenderer.js
  37. BIN
      examples/models/mmd/default/toon00.bmp
  38. BIN
      examples/models/mmd/default/toon01.bmp
  39. BIN
      examples/models/mmd/default/toon02.bmp
  40. BIN
      examples/models/mmd/default/toon03.bmp
  41. BIN
      examples/models/mmd/default/toon04.bmp
  42. BIN
      examples/models/mmd/default/toon05.bmp
  43. BIN
      examples/models/mmd/default/toon06.bmp
  44. BIN
      examples/models/mmd/default/toon07.bmp
  45. BIN
      examples/models/mmd/default/toon08.bmp
  46. BIN
      examples/models/mmd/default/toon09.bmp
  47. BIN
      examples/models/mmd/default/toon10.bmp
  48. 77 55
      examples/webgl_loader_mmd.html
  49. 1 40
      examples/webgl_loader_mmd_audio.html
  50. 0 1
      examples/webgl_loader_mmd_pose.html
  51. 66 0
      src/Three.Legacy.js
  52. 0 1
      src/Three.js
  53. 1 1
      src/animation/PropertyBinding.js
  54. 2 0
      src/core/BufferAttribute.js
  55. 4 4
      src/core/BufferGeometry.js
  56. 1 1
      src/extras/helpers/BoxHelper.js
  57. 1 1
      src/extras/helpers/FaceNormalsHelper.js
  58. 3 3
      src/extras/helpers/SkeletonHelper.js
  59. 4 4
      src/extras/helpers/VertexNormalsHelper.js
  60. 1 1
      src/geometries/EdgesGeometry.js
  61. 2 2
      src/geometries/WireframeGeometry.js
  62. 15 15
      src/materials/Material.js
  63. 9 0
      src/materials/MeshBasicMaterial.js
  64. 1 2
      src/materials/ShaderMaterial.js
  65. 3 4
      src/materials/ShadowMaterial.js
  66. 3 3
      src/math/Box3.js
  67. 1 1
      src/math/Color.js
  68. 1 1
      src/math/Matrix3.js
  69. 2 2
      src/objects/Line.js
  70. 2 2
      src/objects/Mesh.js
  71. 1 1
      src/objects/Points.js
  72. 1 1
      src/objects/Skeleton.js
  73. 2 2
      src/objects/SkinnedMesh.js
  74. 15 62
      src/renderers/WebGLRenderer.js
  75. 17 42
      src/renderers/shaders/ShaderLib.js
  76. 16 5
      src/renderers/shaders/ShaderLib/meshbasic_frag.glsl
  77. 0 67
      src/renderers/shaders/UniformsUtils.js
  78. 58 0
      src/renderers/webgl/WebGLObjects.js
  79. 1 2
      src/renderers/webgl/WebGLShadowMap.js
  80. 0 1
      src/textures/Texture.js

+ 5 - 2
README.md

@@ -5,8 +5,11 @@ three.js
 
 The aim of the project is to create an easy to use, lightweight, 3D library. The library provides <canvas>, <svg>, CSS3D and WebGL renderers.
 
-[Examples](http://threejs.org/examples/) — [Documentation](http://threejs.org/docs/) — [Migrating](https://github.com/mrdoob/three.js/wiki/Migration) — [Help](http://stackoverflow.com/questions/tagged/three.js)
-
+[Examples](http://threejs.org/examples/) —
+[Documentation](http://threejs.org/docs/) —
+[Wiki](https://github.com/mrdoob/three.js/wiki) —
+[Migrating](https://github.com/mrdoob/three.js/wiki/Migration) —
+[Help](http://stackoverflow.com/questions/tagged/three.js)
 
 ### Usage ###
 

+ 173 - 175
build/three.js

@@ -1014,7 +1014,6 @@
 		this.uuid = _Math.generateUUID();
 
 		this.name = '';
-		this.sourceFile = '';
 
 		this.image = image !== undefined ? image : Texture.DEFAULT_IMAGE;
 		this.mipmaps = [];
@@ -4925,71 +4924,6 @@
 
 	};
 
-	/**
-	 * Uniform Utilities
-	 */
-
-	var UniformsUtils = {
-
-		merge: function ( uniforms ) {
-
-			var merged = {};
-
-			for ( var u = 0; u < uniforms.length; u ++ ) {
-
-				var tmp = this.clone( uniforms[ u ] );
-
-				for ( var p in tmp ) {
-
-					merged[ p ] = tmp[ p ];
-
-				}
-
-			}
-
-			return merged;
-
-		},
-
-		clone: function ( uniforms_src ) {
-
-			var uniforms_dst = {};
-
-			for ( var u in uniforms_src ) {
-
-				uniforms_dst[ u ] = {};
-
-				for ( var p in uniforms_src[ u ] ) {
-
-					var parameter_src = uniforms_src[ u ][ p ];
-
-					if ( parameter_src && ( parameter_src.isColor ||
-						parameter_src.isMatrix3 || parameter_src.isMatrix4 ||
-						parameter_src.isVector2 || parameter_src.isVector3 || parameter_src.isVector4 ||
-						parameter_src.isTexture ) ) {
-
-						uniforms_dst[ u ][ p ] = parameter_src.clone();
-
-					} else if ( Array.isArray( parameter_src ) ) {
-
-						uniforms_dst[ u ][ p ] = parameter_src.slice();
-
-					} else {
-
-						uniforms_dst[ u ][ p ] = parameter_src;
-
-					}
-
-				}
-
-			}
-
-			return uniforms_dst;
-
-		}
-
-	};
-
 	var alphamap_fragment = "#ifdef USE_ALPHAMAP\n\tdiffuseColor.a *= texture2D( alphaMap, vUv ).g;\n#endif\n";
 
 	var alphamap_pars_fragment = "#ifdef USE_ALPHAMAP\n\tuniform sampler2D alphaMap;\n#endif\n";
@@ -5172,7 +5106,7 @@
 
 	var linedashed_vert = "uniform float scale;\nattribute float lineDistance;\nvarying float vLineDistance;\n#include <common>\n#include <color_pars_vertex>\n#include <logdepthbuf_pars_vertex>\n#include <clipping_planes_pars_vertex>\nvoid main() {\n\t#include <color_vertex>\n\tvLineDistance = scale * lineDistance;\n\tvec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );\n\tgl_Position = projectionMatrix * mvPosition;\n\t#include <logdepthbuf_vertex>\n\t#include <clipping_planes_vertex>\n}\n";
 
-	var meshbasic_frag = "uniform vec3 diffuse;\nuniform float opacity;\n#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n#endif\n#include <common>\n#include <color_pars_fragment>\n#include <uv_pars_fragment>\n#include <uv2_pars_fragment>\n#include <map_pars_fragment>\n#include <alphamap_pars_fragment>\n#include <aomap_pars_fragment>\n#include <envmap_pars_fragment>\n#include <fog_pars_fragment>\n#include <specularmap_pars_fragment>\n#include <logdepthbuf_pars_fragment>\n#include <clipping_planes_pars_fragment>\nvoid main() {\n\t#include <clipping_planes_fragment>\n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\t#include <logdepthbuf_fragment>\n\t#include <map_fragment>\n\t#include <color_fragment>\n\t#include <alphamap_fragment>\n\t#include <alphatest_fragment>\n\t#include <specularmap_fragment>\n\tReflectedLight reflectedLight;\n\treflectedLight.directDiffuse = vec3( 0.0 );\n\treflectedLight.directSpecular = vec3( 0.0 );\n\treflectedLight.indirectDiffuse = diffuseColor.rgb;\n\treflectedLight.indirectSpecular = vec3( 0.0 );\n\t#include <aomap_fragment>\n\tvec3 outgoingLight = reflectedLight.indirectDiffuse;\n\t#include <normal_flip>\n\t#include <envmap_fragment>\n\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\n\t#include <premultiplied_alpha_fragment>\n\t#include <tonemapping_fragment>\n\t#include <encodings_fragment>\n\t#include <fog_fragment>\n}\n";
+	var meshbasic_frag = "uniform vec3 diffuse;\nuniform float opacity;\n#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n#endif\n#include <common>\n#include <color_pars_fragment>\n#include <uv_pars_fragment>\n#include <uv2_pars_fragment>\n#include <map_pars_fragment>\n#include <alphamap_pars_fragment>\n#include <aomap_pars_fragment>\n#include <lightmap_pars_fragment>\n#include <envmap_pars_fragment>\n#include <fog_pars_fragment>\n#include <specularmap_pars_fragment>\n#include <logdepthbuf_pars_fragment>\n#include <clipping_planes_pars_fragment>\nvoid main() {\n\t#include <clipping_planes_fragment>\n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\t#include <logdepthbuf_fragment>\n\t#include <map_fragment>\n\t#include <color_fragment>\n\t#include <alphamap_fragment>\n\t#include <alphatest_fragment>\n\t#include <specularmap_fragment>\n\tReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );\n\t#ifdef USE_LIGHTMAP\n\t\treflectedLight.indirectDiffuse += texture2D( lightMap, vUv2 ).xyz * lightMapIntensity;\n\t#else\n\t\treflectedLight.indirectDiffuse += vec3( 1.0 );\n\t#endif\n\t#include <aomap_fragment>\n\treflectedLight.indirectDiffuse *= diffuseColor.rgb;\n\tvec3 outgoingLight = reflectedLight.indirectDiffuse;\n\t#include <normal_flip>\n\t#include <envmap_fragment>\n\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\n\t#include <premultiplied_alpha_fragment>\n\t#include <tonemapping_fragment>\n\t#include <encodings_fragment>\n\t#include <fog_fragment>\n}\n";
 
 	var meshbasic_vert = "#include <common>\n#include <uv_pars_vertex>\n#include <uv2_pars_vertex>\n#include <envmap_pars_vertex>\n#include <color_pars_vertex>\n#include <morphtarget_pars_vertex>\n#include <skinning_pars_vertex>\n#include <logdepthbuf_pars_vertex>\n#include <clipping_planes_pars_vertex>\nvoid main() {\n\t#include <uv_vertex>\n\t#include <uv2_vertex>\n\t#include <color_vertex>\n\t#include <skinbase_vertex>\n\t#ifdef USE_ENVMAP\n\t#include <beginnormal_vertex>\n\t#include <morphnormal_vertex>\n\t#include <skinnormal_vertex>\n\t#include <defaultnormal_vertex>\n\t#endif\n\t#include <begin_vertex>\n\t#include <morphtarget_vertex>\n\t#include <skinning_vertex>\n\t#include <project_vertex>\n\t#include <logdepthbuf_vertex>\n\t#include <worldpos_vertex>\n\t#include <clipping_planes_vertex>\n\t#include <envmap_vertex>\n}\n";
 
@@ -5998,13 +5932,12 @@
 
 		basic: {
 
-			uniforms: UniformsUtils.merge( [
-
+			uniforms: Object.assign( {},
 				UniformsLib.common,
 				UniformsLib.aomap,
+				UniformsLib.lightmap,
 				UniformsLib.fog
-
-			] ),
+			),
 
 			vertexShader: ShaderChunk.meshbasic_vert,
 			fragmentShader: ShaderChunk.meshbasic_frag
@@ -6013,20 +5946,17 @@
 
 		lambert: {
 
-			uniforms: UniformsUtils.merge( [
-
+			uniforms: Object.assign( {},
 				UniformsLib.common,
 				UniformsLib.aomap,
 				UniformsLib.lightmap,
 				UniformsLib.emissivemap,
 				UniformsLib.fog,
 				UniformsLib.lights,
-
 				{
 					emissive : { value: new Color( 0x000000 ) }
 				}
-
-			] ),
+			),
 
 			vertexShader: ShaderChunk.meshlambert_vert,
 			fragmentShader: ShaderChunk.meshlambert_frag
@@ -6035,8 +5965,7 @@
 
 		phong: {
 
-			uniforms: UniformsUtils.merge( [
-
+			uniforms: Object.assign( {},
 				UniformsLib.common,
 				UniformsLib.aomap,
 				UniformsLib.lightmap,
@@ -6046,14 +5975,12 @@
 				UniformsLib.displacementmap,
 				UniformsLib.fog,
 				UniformsLib.lights,
-
 				{
 					emissive : { value: new Color( 0x000000 ) },
 					specular : { value: new Color( 0x111111 ) },
 					shininess: { value: 30 }
 				}
-
-			] ),
+			),
 
 			vertexShader: ShaderChunk.meshphong_vert,
 			fragmentShader: ShaderChunk.meshphong_frag
@@ -6062,8 +5989,7 @@
 
 		standard: {
 
-			uniforms: UniformsUtils.merge( [
-
+			uniforms: Object.assign( {},
 				UniformsLib.common,
 				UniformsLib.aomap,
 				UniformsLib.lightmap,
@@ -6075,15 +6001,13 @@
 				UniformsLib.metalnessmap,
 				UniformsLib.fog,
 				UniformsLib.lights,
-
 				{
 					emissive : { value: new Color( 0x000000 ) },
 					roughness: { value: 0.5 },
 					metalness: { value: 0 },
 					envMapIntensity : { value: 1 }, // temporary
 				}
-
-			] ),
+			),
 
 			vertexShader: ShaderChunk.meshphysical_vert,
 			fragmentShader: ShaderChunk.meshphysical_frag
@@ -6092,12 +6016,10 @@
 
 		points: {
 
-			uniforms: UniformsUtils.merge( [
-
+			uniforms: Object.assign( {},
 				UniformsLib.points,
 				UniformsLib.fog
-
-			] ),
+			),
 
 			vertexShader: ShaderChunk.points_vert,
 			fragmentShader: ShaderChunk.points_frag
@@ -6106,18 +6028,15 @@
 
 		dashed: {
 
-			uniforms: UniformsUtils.merge( [
-
+			uniforms: Object.assign( {},
 				UniformsLib.common,
 				UniformsLib.fog,
-
 				{
 					scale    : { value: 1 },
 					dashSize : { value: 1 },
 					totalSize: { value: 2 }
 				}
-
-			] ),
+			),
 
 			vertexShader: ShaderChunk.linedashed_vert,
 			fragmentShader: ShaderChunk.linedashed_frag
@@ -6126,12 +6045,10 @@
 
 		depth: {
 
-			uniforms: UniformsUtils.merge( [
-
+			uniforms: Object.assign( {},
 				UniformsLib.common,
 				UniformsLib.displacementmap
-
-			] ),
+			),
 
 			vertexShader: ShaderChunk.depth_vert,
 			fragmentShader: ShaderChunk.depth_frag
@@ -6141,9 +6058,7 @@
 		normal: {
 
 			uniforms: {
-
 				opacity : { value: 1.0 }
-
 			},
 
 			vertexShader: ShaderChunk.normal_vert,
@@ -6187,9 +6102,7 @@
 		distanceRGBA: {
 
 			uniforms: {
-
 				lightPos: { value: new Vector3() }
-
 			},
 
 			vertexShader: ShaderChunk.distanceRGBA_vert,
@@ -6201,16 +6114,13 @@
 
 	ShaderLib.physical = {
 
-		uniforms: UniformsUtils.merge( [
-
+		uniforms: Object.assign( {},
 			ShaderLib.standard.uniforms,
-
 			{
 				clearCoat: { value: 0 },
 				clearCoatRoughness: { value: 0 }
 			}
-
-		] ),
+		),
 
 		vertexShader: ShaderChunk.meshphysical_vert,
 		fragmentShader: ShaderChunk.meshphysical_frag
@@ -7641,7 +7551,7 @@
 		this.fragmentShader = source.fragmentShader;
 		this.vertexShader = source.vertexShader;
 
-		this.uniforms = UniformsUtils.clone( source.uniforms );
+		this.uniforms = Object.assign( {}, source.uniforms );
 
 		this.defines = source.defines;
 
@@ -9203,7 +9113,7 @@
 		depthMaterialTemplate.clipping = true;
 
 		var distanceShader = ShaderLib[ "distanceRGBA" ];
-		var distanceUniforms = UniformsUtils.clone( distanceShader.uniforms );
+		var distanceUniforms = Object.assign( {}, distanceShader.uniforms );
 
 		for ( var i = 0; i !== _NumberOfMaterialVariants; ++ i ) {
 
@@ -11684,6 +11594,9 @@
 	 *  opacity: <float>,
 	 *  map: new THREE.Texture( <Image> ),
 	 *
+	 *  lightMap: new THREE.Texture( <Image> ),
+	 *  lightMapIntensity: <float>
+	 *
 	 *  aoMap: new THREE.Texture( <Image> ),
 	 *  aoMapIntensity: <float>
 	 *
@@ -11718,6 +11631,9 @@
 
 		this.map = null;
 
+		this.lightMap = null;
+		this.lightMapIntensity = 1.0;
+
 		this.aoMap = null;
 		this.aoMapIntensity = 1.0;
 
@@ -11757,6 +11673,9 @@
 
 		this.map = source.map;
 
+		this.lightMap = source.lightMap;
+		this.lightMapIntensity = source.lightMapIntensity;
+
 		this.aoMap = source.aoMap;
 		this.aoMapIntensity = source.aoMapIntensity;
 
@@ -11803,6 +11722,8 @@
 		this.dynamic = false;
 		this.updateRange = { offset: 0, count: - 1 };
 
+		this.onUpload = null;
+
 		this.version = 0;
 
 	}
@@ -17253,8 +17174,53 @@
 
 			gl.bufferData( bufferType, data.array, usage );
 
+			var type = gl.FLOAT;
+			var array = data.array;
+
+			if ( array instanceof Float32Array ) {
+
+				type = gl.FLOAT;
+
+			} else if ( array instanceof Float64Array ) {
+
+				console.warn( "Unsupported data buffer format: Float64Array" );
+
+			} else if ( array instanceof Uint16Array ) {
+
+				type = gl.UNSIGNED_SHORT;
+
+			} else if ( array instanceof Int16Array ) {
+
+				type = gl.SHORT;
+
+			} else if ( array instanceof Uint32Array ) {
+
+				type = gl.UNSIGNED_INT;
+
+			} else if ( array instanceof Int32Array ) {
+
+				type = gl.INT;
+
+			} else if ( array instanceof Int8Array ) {
+
+				type = gl.BYTE;
+
+			} else if ( array instanceof Uint8Array ) {
+
+				type = gl.UNSIGNED_BYTE;
+
+			}
+
+			attributeProperties.bytesPerElement = array.BYTES_PER_ELEMENT;
+			attributeProperties.type = type;
 			attributeProperties.version = data.version;
 
+			if ( data.onUpload !== null ) {
+
+				data.onUpload();
+
+			}
+
 		}
 
 		function updateBuffer( attributeProperties, data, bufferType ) {
@@ -17300,6 +17266,18 @@
 
 		}
 
+		function getAttributeProperties( attribute ) {
+
+			if ( attribute.isInterleavedBufferAttribute ) {
+
+				return properties.get( attribute.data );
+
+			}
+
+			return properties.get( attribute );
+
+		}
+
 		function getWireframeAttribute( geometry ) {
 
 			var property = properties.get( geometry );
@@ -17365,6 +17343,7 @@
 		return {
 
 			getAttributeBuffer: getAttributeBuffer,
+			getAttributeProperties: getAttributeProperties,
 			getWireframeAttribute: getWireframeAttribute,
 
 			update: update
@@ -20373,46 +20352,14 @@
 
 					if ( geometryAttribute !== undefined ) {
 
-						var type = _gl.FLOAT;
-						var array = geometryAttribute.array;
 						var normalized = geometryAttribute.normalized;
+						var size = geometryAttribute.itemSize;
 
-						if ( array instanceof Float32Array ) {
-
-							type = _gl.FLOAT;
-
-						} else if ( array instanceof Float64Array ) {
-
-							console.warn( "Unsupported data buffer format: Float64Array" );
-
-						} else if ( array instanceof Uint16Array ) {
-
-							type = _gl.UNSIGNED_SHORT;
-
-						} else if ( array instanceof Int16Array ) {
-
-							type = _gl.SHORT;
-
-						} else if ( array instanceof Uint32Array ) {
-
-							type = _gl.UNSIGNED_INT;
-
-						} else if ( array instanceof Int32Array ) {
-
-							type = _gl.INT;
-
-						} else if ( array instanceof Int8Array ) {
-
-							type = _gl.BYTE;
-
-						} else if ( array instanceof Uint8Array ) {
-
-							type = _gl.UNSIGNED_BYTE;
+						var attributeProperties = objects.getAttributeProperties( geometryAttribute );
 
-						}
-
-						var size = geometryAttribute.itemSize;
-						var buffer = objects.getAttributeBuffer( geometryAttribute );
+						var buffer = attributeProperties.__webglBuffer;
+						var type = attributeProperties.type;
+						var bytesPerElement = attributeProperties.bytesPerElement;
 
 						if ( geometryAttribute.isInterleavedBufferAttribute ) {
 
@@ -20437,7 +20384,7 @@
 							}
 
 							_gl.bindBuffer( _gl.ARRAY_BUFFER, buffer );
-							_gl.vertexAttribPointer( programAttribute, size, type, normalized, stride * data.array.BYTES_PER_ELEMENT, ( startIndex * stride + offset ) * data.array.BYTES_PER_ELEMENT );
+							_gl.vertexAttribPointer( programAttribute, size, type, normalized, stride * bytesPerElement, ( startIndex * stride + offset ) * bytesPerElement );
 
 						} else {
 
@@ -20458,7 +20405,7 @@
 							}
 
 							_gl.bindBuffer( _gl.ARRAY_BUFFER, buffer );
-							_gl.vertexAttribPointer( programAttribute, size, type, normalized, 0, startIndex * size * geometryAttribute.array.BYTES_PER_ELEMENT );
+							_gl.vertexAttribPointer( programAttribute, size, type, normalized, 0, startIndex * size * bytesPerElement );
 
 						}
 
@@ -21006,7 +20953,7 @@
 
 					materialProperties.__webglShader = {
 						name: material.type,
-						uniforms: UniformsUtils.clone( shader.uniforms ),
+						uniforms: Object.assign( {}, shader.uniforms ),
 						vertexShader: shader.vertexShader,
 						fragmentShader: shader.fragmentShader
 					};
@@ -21418,6 +21365,13 @@
 			uniforms.specularMap.value = material.specularMap;
 			uniforms.alphaMap.value = material.alphaMap;
 
+			if ( material.lightMap ) {
+
+				uniforms.lightMap.value = material.lightMap;
+				uniforms.lightMapIntensity.value = material.lightMapIntensity;
+
+			}
+
 			if ( material.aoMap ) {
 
 				uniforms.aoMap.value = material.aoMap;
@@ -21556,13 +21510,6 @@
 
 		function refreshUniformsLambert( uniforms, material ) {
 
-			if ( material.lightMap ) {
-
-				uniforms.lightMap.value = material.lightMap;
-				uniforms.lightMapIntensity.value = material.lightMapIntensity;
-
-			}
-
 			if ( material.emissiveMap ) {
 
 				uniforms.emissiveMap.value = material.emissiveMap;
@@ -21576,13 +21523,6 @@
 			uniforms.specular.value = material.specular;
 			uniforms.shininess.value = Math.max( material.shininess, 1e-4 ); // to prevent pow( 0.0, 0.0 )
 
-			if ( material.lightMap ) {
-
-				uniforms.lightMap.value = material.lightMap;
-				uniforms.lightMapIntensity.value = material.lightMapIntensity;
-
-			}
-
 			if ( material.emissiveMap ) {
 
 				uniforms.emissiveMap.value = material.emissiveMap;
@@ -21630,13 +21570,6 @@
 
 			}
 
-			if ( material.lightMap ) {
-
-				uniforms.lightMap.value = material.lightMap;
-				uniforms.lightMapIntensity.value = material.lightMapIntensity;
-
-			}
-
 			if ( material.emissiveMap ) {
 
 				uniforms.emissiveMap.value = material.emissiveMap;
@@ -28183,12 +28116,12 @@
 	function ShadowMaterial() {
 
 		ShaderMaterial.call( this, {
-			uniforms: UniformsUtils.merge( [
-				UniformsLib[ "lights" ],
+			uniforms: Object.assign( {},
+				UniformsLib.lights,
 				{
 					opacity: { value: 1.0 }
 				}
-			] ),
+			),
 			vertexShader: ShaderChunk[ 'shadow_vert' ],
 			fragmentShader: ShaderChunk[ 'shadow_frag' ]
 		} );
@@ -42095,6 +42028,71 @@
 
 	};
 
+	var UniformsUtils = {
+
+		merge: function ( uniforms ) {
+
+			console.warn( 'THREE.UniformsUtils.merge() has been deprecated. Use Object.assign() instead.' );
+
+			var merged = {};
+
+			for ( var u = 0; u < uniforms.length; u ++ ) {
+
+				var tmp = this.clone( uniforms[ u ] );
+
+				for ( var p in tmp ) {
+
+					merged[ p ] = tmp[ p ];
+
+				}
+
+			}
+
+			return merged;
+
+		},
+
+		clone: function ( uniforms_src ) {
+
+			console.warn( 'THREE.UniformsUtils.clone() has been deprecated.' );
+
+			var uniforms_dst = {};
+
+			for ( var u in uniforms_src ) {
+
+				uniforms_dst[ u ] = {};
+
+				for ( var p in uniforms_src[ u ] ) {
+
+					var parameter_src = uniforms_src[ u ][ p ];
+
+					if ( parameter_src && ( parameter_src.isColor ||
+						parameter_src.isMatrix3 || parameter_src.isMatrix4 ||
+						parameter_src.isVector2 || parameter_src.isVector3 || parameter_src.isVector4 ||
+						parameter_src.isTexture ) ) {
+
+						uniforms_dst[ u ][ p ] = parameter_src.clone();
+
+					} else if ( Array.isArray( parameter_src ) ) {
+
+						uniforms_dst[ u ][ p ] = parameter_src.slice();
+
+					} else {
+
+						uniforms_dst[ u ][ p ] = parameter_src;
+
+					}
+
+				}
+
+			}
+
+			return uniforms_dst;
+
+		}
+
+	};
+
 	//
 
 	function Projector () {
@@ -42143,7 +42141,6 @@
 	exports.WebGL2Renderer = WebGL2Renderer;
 	exports.ShaderLib = ShaderLib;
 	exports.UniformsLib = UniformsLib;
-	exports.UniformsUtils = UniformsUtils;
 	exports.ShaderChunk = ShaderChunk;
 	exports.FogExp2 = FogExp2;
 	exports.Fog = Fog;
@@ -42507,6 +42504,7 @@
 	exports.XHRLoader = XHRLoader;
 	exports.GeometryUtils = GeometryUtils;
 	exports.ImageUtils = ImageUtils;
+	exports.UniformsUtils = UniformsUtils;
 	exports.Projector = Projector;
 	exports.CanvasRenderer = CanvasRenderer;
 

Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 0 - 0
build/three.js.map


Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 244 - 248
build/three.min.js


Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 172 - 174
build/three.modules.js


Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 0 - 0
build/three.modules.js.map


+ 65 - 0
docs/api/cameras/StereoCamera.html

@@ -0,0 +1,65 @@
+<!DOCTYPE html>
+<html lang="en">
+	<head>
+		<meta charset="utf-8" />
+		<base href="../../" />
+		<script src="list.js"></script>
+		<script src="page.js"></script>
+		<link type="text/css" rel="stylesheet" href="page.css" />
+	</head>
+	<body>
+
+		<h1>[name]</h1>
+
+		<div class="desc">
+		Dual [page:PerspectiveCamera PerspectiveCamera]s used for effects such as
+		[link:https://en.wikipedia.org/wiki/Anaglyph_3D 3D Anaglyph] or [link:https://en.wikipedia.org/wiki/parallax_barrier Parallax Barrier].
+		</div>
+
+
+		<h2>Example</h2>
+
+		<div>[example:webgl_effects_anaglyph effects / anaglyph ]</div>
+		<div>[example:webgl_effects_parallaxbarrier effects / parallaxbarrier ]</div>
+		<div>[example:webgl_effects_stereo effects / stereo ]</div>
+
+		<div>
+		This class is used internally in the files<br /><br />
+		[link:https://github.com/mrdoob/three.js/blob/master/examples/js/effects/AnaglyphEffect.js examples/js/effects/AnaglyphEffect.js]<br /><br />
+		[link:https://github.com/mrdoob/three.js/blob/master/examples/js/effects/ParallaxBarrierEffect.js examples/js/effects/ParallaxBarrierEffect.js]<br /><br />
+		[link:https://github.com/mrdoob/three.js/blob/master/examples/js/effects/StereoEffect.js examples/js/effects/StereoEffect.js]<br /><br />
+		used in the above examples.
+		</div>
+
+
+		<h2>Constructor</h2>
+
+		<h3>[name]( )</h3>
+
+		<h2>Properties</h2>
+
+		<h3>[property:Float aspect]</h3>
+		<div>Default is *1*.</div>
+
+		<h3>[property:Float eyeSep]</h3>
+		<div>Default is *0.064*.</div>
+
+		<h3>[property:PerspectiveCamera cameraL]</h3>
+		<div>Left camera.</div>
+
+		<h3>[property:PerspectiveCamera cameraR]</h3>
+		<div>Right camera.</div>
+
+
+		<h2>Methods</h2>
+
+		<h3>[method:null update]( camera )</h3>
+		<div>
+		Update the stereo cameras based on the camera passed in.
+		</div>
+
+		<h2>Source</h2>
+
+		[link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js]
+	</body>
+</html>

+ 0 - 0
docs/api/constants/WebGLRenderer.html → docs/api/constants/Renderer.html


+ 5 - 1
docs/api/core/BufferAttribute.html

@@ -18,7 +18,7 @@
 		<h3>[name]( [page:TypedArray array], [page:Integer itemSize], [page:Boolean normalized] )</h3>
 		<div>
 		Instantiates this attribute with data from the associated buffer.
-		itemSize gives the number of values of the array that should be associated with a particular vertex. normalized indicates how the underlying data in the buffer maps to the values in the GLSL shader code. 
+		itemSize gives the number of values of the array that should be associated with a particular vertex. normalized indicates how the underlying data in the buffer maps to the values in the GLSL shader code.
 		</div>
 
 		<h2>Properties</h2>
@@ -54,6 +54,10 @@
 		A version number, incremented every time the needsUpdate property is set to true.
 		</div>
 
+		<h3>[property:Function onUpload]</h3>
+		<div>
+		A callback function that is executed after the Renderer has transfered the attribute array data to the GPU.
+		</div>
 
 		<h2>Methods</h2>
 

+ 63 - 0
docs/api/extras/CurveUtils.html

@@ -0,0 +1,63 @@
+<!DOCTYPE html>
+<html lang="en">
+	<head>
+		<meta charset="utf-8" />
+		<base href="../../" />
+		<script src="list.js"></script>
+		<script src="page.js"></script>
+		<link type="text/css" rel="stylesheet" href="page.css" />
+	</head>
+	<body>
+		<h1>[name]</h1>
+
+		<div class="desc">
+		A class containing utility functions for curves.<br />
+
+		Note that these are all linear functions so it is neccessary to calculate seperately for
+		x, y (and z, w if present) components of a curve.
+		</div>
+
+
+		<h2>Methods</h2>
+
+		<h3>[method:Number interpolate]( p0, p1, p2, p3, t )</h3>
+		<div>
+		t -- interpolation weight. <br />
+		p0, p1, p2, p4 -- the points defining the spline curve.<br /><br />
+
+		Used internally by [page:SplineCurve SplineCurve] and [page:SplineCurve3 SplineCurve3].
+		</div>
+
+		<h3>[method:Number tangentQuadraticBezier]( t, p0, p1, p2 )</h3>
+		<div>
+		t -- the point at which to calculate the tangent. <br />
+		p0, p1, p2 -- the three points defining the quadratic Bézier curve.<br /><br />
+
+		Calculate the tangent at the point t on a quadratic Bézier curve given by the three points.<br /><br />
+
+		Used internally by [page:QuadraticBezierCurve QuadraticBezierCurve].
+		</div>
+
+		<h3>[method:Number tangentCubicBezier]( t, p0, p1, p2, p3 )</h3>
+		<div>
+		t -- the point at which to calculate the tangent. <br />
+		p0, p1, p2, p3 -- the points defining the cubic Bézier curve.<br /><br />
+
+		Calculate the tangent at the point t on a cubic Bézier curve given by the four points.<br /><br />
+
+		Used internally by [page:CubicBezierCurve CubicBezierCurve].
+		</div>
+
+		<h3>[method:Number tangentSpline]( t, p0, p1, p2, p3 )</h3>
+		<div>
+		t -- the point at which to calculate the tangent. <br />
+		p0, p1, p2, p3 -- the points defining the spline curve.<br /><br />
+
+		Calculate the tangent at the point t on a spline curve given by the four points.
+		</div>
+
+		<h2>Source</h2>
+
+		[link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js]
+	</body>
+</html>

+ 88 - 0
docs/api/extras/ShapeUtils.html

@@ -0,0 +1,88 @@
+<!DOCTYPE html>
+<html lang="en">
+	<head>
+		<meta charset="utf-8" />
+		<base href="../../" />
+		<script src="list.js"></script>
+		<script src="page.js"></script>
+		<link type="text/css" rel="stylesheet" href="page.css" />
+	</head>
+	<body>
+		<h1>[name]</h1>
+
+		<div class="desc">
+		A class containing utility functions for shapes.<br />
+
+		Note that these are all linear functions so it is neccessary to calculate seperately for
+		x, y (an z, w if present) components of a vector.
+		</div>
+
+
+		<h2>Methods</h2>
+
+		<h3>[method:Number area]( contour )</h3>
+		<div>
+		contour -- 2D polygon.<br /><br />
+
+		Calculate area of a ( 2D ) contour polygon.<br /><br />
+
+		</div>
+
+		<h3>[method:Number b2]( t, p0, p1, p2 )</h3>
+		<div>
+		t -- number<br />
+		p0, p1, p2 -- x, y, z or w components of a quadratic bezier curve.<br /><br />
+
+		Note that this is a linear function so it is neccessary to calculate seperately for
+		x, y (and z for 3D curves) components of a curve.<br /><br />
+
+		Used internally by [page:QuadraticBezierCurve QuadraticBezierCurve],
+		[page:QuadraticBezierCurve3 QuadraticBezierCurve3] and [page:Font Font].
+		</div>
+
+		<h3>[method:Number b3]( t, p0, p1, p2, p3 )</h3>
+		<div>
+		t -- number. <br />
+		p0, p1, p2, p3 -- x, y or z components of a cubic bezier curve..<br /><br />
+
+		Note that this is a linear function so it is neccessary to calculate seperately for
+		x, y (and z for 3D curves) components of a curve.<br /><br />
+
+		Used internally by [page:CubicBezierCurve CubicBezierCurve],
+		[page:CubicBezierCurve3 CubicBezierCurve3] and [page:Font Font].
+		</div>
+
+		<h3>[method:Boolean isClockwise]( pts )</h3>
+		<div>
+		pts -- points defining a 2D polygon<br /><br />
+
+		Note that this is a linear function so it is neccessary to calculate seperately for
+		x, y  components of a polygon.<br /><br />
+
+		Used internally by [page:Path Path],
+		[page:ExtrudeGeometry ExtrudeGeometry] and [page:ShapeBufferGeometry ShapeBufferGeometry].
+		</div>
+
+		<h3>[method:null triangulate]( contour, indices )</h3>
+		<div>
+		contour --  2D polygon.<br />
+		indices -- <br /><br />
+
+		Used internally by [page:ExtrudeGeometry ExtrudeGeometry]
+		and [page:ShapeBufferGeometry ShapeBufferGeometry] to calculate faces.
+		</div>
+
+		<h3>[method:null triangulateShape]( contour, holes )</h3>
+		<div>
+		contour -- 2D polygon.<br />
+		holes -- array of holes<br /><br />
+
+		Used internally by [page:ExtrudeGeometry ExtrudeGeometry]
+		and [page:ShapeBufferGeometry ShapeBufferGeometry] to calculate faces in shapes with holes.
+		</div>
+
+		<h2>Source</h2>
+
+		[link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js]
+	</body>
+</html>

+ 32 - 0
docs/api/extras/core/Font.html

@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<html lang="en">
+	<head>
+		<meta charset="utf-8" />
+		<base href="../../../" />
+		<script src="list.js"></script>
+		<script src="page.js"></script>
+		<link type="text/css" rel="stylesheet" href="page.css" />
+	</head>
+	<body>
+		<h1>[name]</h1>
+
+		<div class="desc">
+		Create a set of [page:Shape Shape]s representing a font loaded in JSON format.<br /><br />
+
+		Used internally by the [page:FontLoader].
+		</div>
+
+		<h2>Constructor</h2>
+
+		<h3>[name]( data )</h3>
+		<div>
+		data -- JSON data representing the font.<br /><br />
+
+		This constructor creates a new [name], which is an array of [page:Shape Shape]s.
+		</div>
+
+		<h2>Source</h2>
+
+		[link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js]
+	</body>
+</html>

+ 75 - 0
docs/api/extras/helpers/SkeletonHelper.html

@@ -0,0 +1,75 @@
+<!DOCTYPE html>
+<html lang="en">
+	<head>
+		<meta charset="utf-8" />
+		<base href="../../../" />
+		<script src="list.js"></script>
+		<script src="page.js"></script>
+		<link type="text/css" rel="stylesheet" href="page.css" />
+	</head>
+	<body>
+		[page:Object3D] &rarr; [page:Line] &rarr; [page:LineSegments] &rarr;
+
+		<h1>[name]</h1>
+
+		<div class="desc">
+		A helper object to assist with visualizing a [page:Skeleton Skeleton].
+		The helper is renderered using a [page:LineBasicMaterial LineBasicMaterial].
+		</div>
+
+
+		<h2>Example</h2>
+
+		[example:webgl_animation_skinning_blending animation / skinning / blending]<br />
+		[example:webgl_animation_skinning_morph animation / skinning / morph]<br />
+		[example:webgl_loader_bvh loader / bvh ]
+
+		<code>
+var helper = new THREE.SkeletonHelper( mesh );
+helper.material.linewidth = 3;
+scene.add( helper );
+		</code>
+
+
+
+		<h2>Constructor</h2>
+
+
+		<h3>[name]( object )</h3>
+		<div>
+		object -- can be any object that has an array of [page:Bone Bone]s as a sub object. <br />
+		For example, a [page:Skeleton Skeleton] or a [page:SkinnedMesh SkinnedMesh].
+		</div>
+
+
+		<h2>Properties</h2>
+
+		<h3>[property:Array bones]</h3>
+		<div>
+		The list of bones that the helper renders as [page:Line Line]s.
+		</div>
+
+		<h3>[property:Object root]</h3>
+		<div>
+		The object passed in the constructor.
+		</div>
+
+		<h2>Methods</h2>
+
+		<h3>[method:Array getBoneList]( object )</h3>
+		<div>
+		getBoneList -- the object used in the constructor.<br /><br />
+
+		This is called automatically to generate a list of bones from the object passed in the constructor.
+		</div>
+
+		<h3>[method:null update]()</h3>
+		<div>
+		Update the helper. Call in the render loop if animating the model.
+		</div>
+
+		<h2>Source</h2>
+
+		[link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js]
+	</body>
+</html>

+ 57 - 0
docs/api/geometries/EdgesGeometry.html

@@ -0,0 +1,57 @@
+<!DOCTYPE html>
+<html lang="en">
+	<head>
+		<meta charset="utf-8" />
+		<base href="../../" />
+		<script src="list.js"></script>
+		<script src="page.js"></script>
+		<link type="text/css" rel="stylesheet" href="page.css" />
+	</head>
+	<body>
+		[page:BufferGeometry] &rarr;
+
+		<h1>[name]</h1>
+
+		<div class="desc">This can be used as a helper object to view the edges of a [page:Geometry Geometry] object.</div>
+
+		<!-- <iframe id="scene" src="scenes/geometry-browser.html#EdgeGeometry"></iframe>
+
+		<script>
+
+		// iOS iframe auto-resize workaround
+
+		if ( /(iPad|iPhone|iPod)/g.test( navigator.userAgent ) ) {
+
+			var scene = document.getElementById( 'scene' );
+
+			scene.style.width = getComputedStyle( scene ).width;
+			scene.style.height = getComputedStyle( scene ).height;
+			scene.setAttribute( 'scrolling', 'no' );
+
+		}
+
+		</script> -->
+
+		<h2>Example</h2>
+
+		[example:webgl_helpers helpers]
+
+		<code>
+var geometry = new THREE.BoxBufferGeometry( 100, 100, 100 );
+var edges = new THREE.EdgesGeometry( geometry );
+var line = new THREE.LineSegments( edges );
+scene.add( line );
+		</code>
+
+		<h2>Constructor</h2>
+
+		<h3>[name]( [page:Geometry geometry] )</h3>
+		<div>
+		geometry — any geometry object.
+		</div>
+
+		<h2>Source</h2>
+
+		[link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js]
+	</body>
+</html>

+ 63 - 0
docs/api/geometries/WireframeGeometry.html

@@ -0,0 +1,63 @@
+<!DOCTYPE html>
+<html lang="en">
+	<head>
+		<meta charset="utf-8" />
+		<base href="../../" />
+		<script src="list.js"></script>
+		<script src="page.js"></script>
+		<link type="text/css" rel="stylesheet" href="page.css" />
+	</head>
+	<body>
+		[page:BufferGeometry] &rarr;
+
+		<h1>[name]</h1>
+
+		<div class="desc">This can be used as a helper object to view a [page:Geometry Geometry] object as a wireframe.</div>
+
+		<!-- <iframe id="scene" src="scenes/geometry-browser.html#EdgeGeometry"></iframe>
+
+		<script>
+
+		// iOS iframe auto-resize workaround
+
+		if ( /(iPad|iPhone|iPod)/g.test( navigator.userAgent ) ) {
+
+			var scene = document.getElementById( 'scene' );
+
+			scene.style.width = getComputedStyle( scene ).width;
+			scene.style.height = getComputedStyle( scene ).height;
+			scene.setAttribute( 'scrolling', 'no' );
+
+		}
+
+		</script> -->
+
+		<h2>Example</h2>
+
+		[example:webgl_helpers helpers]
+
+		<code>
+var geometry = new THREE.SphereBufferGeometry( 100, 100, 100 );
+
+var wireframe = new THREE.WireframeGeometry( geometry );
+
+var line = new THREE.LineSegments( wireframe );
+line.material.depthTest = false;
+line.material.opacity = 0.25;
+line.material.transparent = true;
+
+scene.add( line );
+		</code>
+
+		<h2>Constructor</h2>
+
+		<h3>[name]( [page:Geometry geometry] )</h3>
+		<div>
+		geometry — any geometry object.
+		</div>
+
+		<h2>Source</h2>
+
+		[link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js]
+	</body>
+</html>

+ 10 - 2
docs/api/materials/MeshBasicMaterial.html

@@ -1,7 +1,7 @@
 <!DOCTYPE html>
 <html lang="en">
 	<head>
-		<meta charset="utf-8" />
+		<meta charset="utf-8" />
 		<base href="../../" />
 		<script src="list.js"></script>
 		<script src="page.js"></script>
@@ -41,6 +41,8 @@
 		<div>
 		color — geometry color in hexadecimal. Default is 0xffffff.<br />
 		map — Set texture map. Default is null <br />
+		lightMap — Set light map. Default is null.<br />
+		lightMapIntensity — Set light map intensity. Default is 1.<br />
 		aoMap — Set ao map. Default is null.<br />
 		aoMapIntensity — Set ao map intensity. Default is 1.<br />
 		specularMap — Set specular map. Default is null.<br />
@@ -71,11 +73,17 @@
 		Set texture map. Default is  null.
 		</div>
 
+		<h3>[property:Texture lightMap]</h3>
+		<div>Set light map. Default is null. The lightMap requires a second set of UVs.</div>
+
+		<h3>[property:Float lightMapIntensity]</h3>
+		<div>Intensity of the baked light. Default is 1.</div>
+
 		<h3>[property:Texture aoMap]</h3>
 		<div>Set ambient occlusion map. Default is null.</div>
 
 		<h3>[property:Float aoMapIntensity]</h3>
-		<div>TODO</div>
+		<div>Intensity of the ambient occlusion effect. Default is 1. Zero is no occlusion effect.</div>
 
 		<h3>[property:Texture specularMap]</h3>
 		<div>Set specular map. Default is null.</div>

+ 71 - 0
docs/api/materials/MeshPhysicalMaterial.html

@@ -0,0 +1,71 @@
+<!DOCTYPE html>
+<html lang="en">
+	<head>
+		<meta charset="utf-8" />
+		<base href="../../" />
+		<script src="list.js"></script>
+		<script src="page.js"></script>
+		<link type="text/css" rel="stylesheet" href="page.css" />
+	</head>
+	<body>
+		[page:Material] &rarr; [page:MeshStandardMaterial] &rarr;
+
+		<h1>[name]</h1>
+
+		<div class="desc">An extension of the [page:MeshStandardMaterial] that allows for greater control over reflectivity.</div>
+
+		<!-- <iframe id="scene" src="scenes/material-browser.html#MeshStandardMaterial"></iframe>
+
+		<script>
+
+		// iOS iframe auto-resize workaround
+
+		if ( /(iPad|iPhone|iPod)/g.test( navigator.userAgent ) ) {
+
+			var scene = document.getElementById( 'scene' );
+
+			scene.style.width = getComputedStyle( scene ).width;
+			scene.style.height = getComputedStyle( scene ).height;
+			scene.setAttribute( 'scrolling', 'no' );
+
+		}
+
+		</script> -->
+
+		<h2>Examples</h2>
+		[example:webgl_materials_variations_physical materials / variations / physical]<br />
+		[example:webgl_materials_reflectivity materials / reflectivity]
+
+		<h2>Constructor</h2>
+
+		<h3>[name]( [page:Object parameters] )</h3>
+		<div>
+		parameters -- see [page:MeshStandardMaterial]
+		</div>
+
+
+		<h2>Properties</h2>
+		<div>See the base [page:Material] and [page:MeshStandardMaterial] classes for common properties.</div>
+
+		<h3>[property:Float reflectivity]</h3>
+		<div>
+		Degree of reflectivity, from *0.0* to *1.0*. Default is *0.5*.<br />
+			
+		This models the reflectivity of non-metallic materials. It has no effect when [page:MeshStandardMaterial.metalness metalness] is *1.0*
+		</div>
+
+		<h3>[property:Float clearCoat]</h3>
+		<div>
+		ClearCoat level, from *0.0* to *1.0*. Default is *0.0*.
+		</div>
+
+		<h3>[property:Float clearCoatRoughness]</h3>
+		<div>
+		How rough the clearCoat appears, from *0.0* to *1.0*. Default is *0.0*.
+		</div>
+
+		<h2>Source</h2>
+
+		[link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js]
+	</body>
+</html>

+ 56 - 0
docs/api/materials/ShadowMaterial.html

@@ -0,0 +1,56 @@
+<!DOCTYPE html>
+<html lang="en">
+	<head>
+		<meta charset="utf-8" />
+		<base href="../../" />
+		<script src="list.js"></script>
+		<script src="page.js"></script>
+		<link type="text/css" rel="stylesheet" href="page.css" />
+	</head>
+	<body>
+		[page:Material] &rarr; [page:ShaderMaterial] &rarr;
+
+		<h1>[name]</h1>
+
+		<div class="desc">
+		This material can recieve shadows, but otherwise is completely transparent.
+		</div>
+
+		<h3>Example</h3>
+		[example:webgl_geometry_spline_editor gemoetry / spline / editor]
+
+		<code>
+var planeGeometry = new THREE.PlaneGeometry( 2000, 2000 );
+planeGeometry.rotateX( - Math.PI / 2 );
+
+var planeMaterial = new THREE.ShadowMaterial();
+planeMaterial.opacity = 0.2;
+
+var plane = new THREE.Mesh( planeGeometry, planeMaterial );
+plane.position.y = -200;
+plane.receiveShadow = true;
+scene.add( plane );
+		</code>
+
+		<h2>Constructor</h2>
+
+		<h3>[name]( )</h3>
+
+
+		<h2>Properties</h2>
+		<div>See the base [page:Material] and [page:ShaderMaterial] classes for common properties.</div>
+
+		<h3>[property:Boolean lights]</h3>
+		<div>Whether the material is affected by lights. Default is *true*.</div>
+
+		<h3>[property:Boolean transparent]</h3>
+		<div>Defines whether this material is transparent. Default is *true*.</div>
+
+		<h2>Methods</h2>
+		<div>See the base [page:Material] and [page:ShaderMaterial] classes for common methods.</div>
+
+		<h2>Source</h2>
+
+		[link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js]
+	</body>
+</html>

+ 84 - 0
docs/api/math/Interpolant.html

@@ -0,0 +1,84 @@
+<!DOCTYPE html>
+<html lang="en">
+	<head>
+		<meta charset="utf-8" />
+		<base href="../../" />
+		<script src="list.js"></script>
+		<script src="page.js"></script>
+		<link type="text/css" rel="stylesheet" href="page.css" />
+	</head>
+	<body>
+		<h1>[name]</h1>
+
+		<div class="desc">
+		Abstract base class of interpolants over parametric samples.<br /><br />
+
+		The parameter domain is one dimensional, typically the time or a path along a curve defined by the data.<br /><br />
+
+		The sample values can have any dimensionality and derived classes may apply special interpretations to the data.<br /><br />
+
+		This class provides the interval seek in a Template Method, deferring the actual interpolation to derived classes.<br /><br />
+
+		Time complexity is *O(1)* for linear access crossing at most two points and *O(log N)* for random access,
+		where *N* is the number of positions.<br /><br />
+
+		References:	[link:http://www.oodesign.com/template-method-pattern.html http://www.oodesign.com/template-method-pattern.html]
+		</div>
+
+
+		<h2>Constructor</h2>
+
+
+		<h2>Constructor</h2>
+
+		<h3>[name]( parameterPositions, sampleValues, sampleSize, resultBuffer )</h3>
+		<div>
+		parameterPositions -- array of positions<br />
+		sampleValues -- array of samples<br />
+		sampleSize -- number of samples<br />
+		resultBuffer -- buffer to store the interpolation results.<br /><br />
+
+		Note: This is not designed to be called directly.
+		</div>
+
+		<h2>Properties</h2>
+
+
+
+		<h3>[property:null parameterPositions]</h3>
+		<div>
+
+		</div>
+
+		<h3>[property:null resultBuffer]</h3>
+		<div>
+
+		</div>
+
+		<h3>[property:null sampleValues]</h3>
+		<div>
+
+		</div>
+
+		<h3>[property:Object settings]</h3>
+		<div>
+		Optional, subclass-specific settings structure.
+		</div>
+
+		<h3>[property:null valueSize]</h3>
+		<div>
+
+		</div>
+
+		<h2>Methods</h2>
+
+		<h3>[method:null evaluate]( [page:Number t] )</h3>
+		<div>
+		Evaluate the interpolant at position *t*.
+		</div>
+
+		<h2>Source</h2>
+
+		[link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js]
+	</body>
+</html>

+ 54 - 26
docs/api/math/Math.html

@@ -26,45 +26,63 @@
 		Clamps the *value* to be between *min* and *max*.
 		</div>
 
-		<h3>[method:Float mapLinear]( [page:Float x], [page:Float a1], [page:Float a2], [page:Float b1], [page:Float b2] )</h3>
+		<h3>[method:Float degToRad]( [page:Float degrees] )</h3>
 		<div>
-		x — Value to be mapped.<br />
-		a1 — Minimum value for range A.<br />
-		a2 — Maximum value for range A.<br />
-		b1 — Minimum value for range B.<br />
-		b2 — Maximum value for range B.
+		degrees -- [page:Float]
 		</div>
 		<div>
-		Linear mapping of *x* from range [*a1*, *a2*] to range [*b1*, *b2*].
+		Converts degrees to radians.
 		</div>
 
-		<h3>[method:Float random16]()</h3>
+		<h3>[method:Integer euclideanModulo]( [page:Integer n], [page:Integer m] )</h3>
 		<div>
-		Random float from 0 to 1 with 16 bits of randomness.<br />
-		Standard Math.random() creates repetitive patterns when applied over larger space.
+		n, m --Integers
+		</div>
+		<div>
+		Compute the Euclidian modulo of m % n, that is:
+		<code>( ( n % m ) + m ) % m</code>
 		</div>
 
-		<h3>[method:Integer randInt]( [page:Integer low], [page:Integer high] )</h3>
+		<h3>[method:UUID generateUUID]( )</h3>
 		<div>
-		Random integer from *low* to *high* interval.
+		Generate a [link:https://en.wikipedia.org/wiki/Universally_unique_identifier UUID] (universally unique identifier).
 		</div>
 
-		<h3>[method:Float randFloat]( [page:Float low], [page:Float high] )</h3>
+		<h3>[method:Boolean isPowerOfTwo]( n )</h3>
 		<div>
-		Random float from *low* to *high* interval.
+		Return *true* if n is a power of 2.
 		</div>
 
-		<h3>[method:Float randFloatSpread]( [page:Float range] )</h3>
+		<h3>[method:Float lerp]( [page:Float x], [page:Float y], [page:Float t] )</h3>
 		<div>
-		Random float from *- range / 2* to *range / 2* interval.
+		x -- Start point. <br />
+		y -- End point. <br />
+		t -- Closed unit interval from [0,1].
+		</div>
+		<div>
+		Returns a value [link:https://en.wikipedia.org/wiki/Linear_interpolation linearly interpolated] from two known points based on the given interval.
 		</div>
 
-		<h3>[method:Float degToRad]( [page:Float degrees] )</h3>
+		<h3>[method:Float mapLinear]( [page:Float x], [page:Float a1], [page:Float a2], [page:Float b1], [page:Float b2] )</h3>
 		<div>
-		degrees -- [page:Float]
+		x — Value to be mapped.<br />
+		a1 — Minimum value for range A.<br />
+		a2 — Maximum value for range A.<br />
+		b1 — Minimum value for range B.<br />
+		b2 — Maximum value for range B.
 		</div>
 		<div>
-		Converts degrees to radians.
+		Linear mapping of *x* from range [*a1*, *a2*] to range [*b1*, *b2*].
+		</div>
+
+		<h3>[method:Integer nearestPowerOfTwo]( n )</h3>
+		<div>
+		Return the nearest power of 2 to a given number n.
+		</div>
+
+		<h3>[method:Integer nextPowerOfTwo]( n )</h3>
+		<div>
+		Return the nearest power of 2 that is bigger than n.
 		</div>
 
 		<h3>[method:Float radToDeg]( [page:Float radians] )</h3>
@@ -75,16 +93,25 @@
 		Converts radians to degrees
 		</div>
 
-		<h3>[method:Float lerp]( [page:Float x], [page:Float y], [page:Float t] )</h3>
+		<h3>[method:Float randFloat]( [page:Float low], [page:Float high] )</h3>
 		<div>
-		x -- Start point. <br />
-		y -- End point. <br />
-		t -- Closed unit interval from [0,1].
+		Random float from *low* to *high* interval.
 		</div>
+
+		<h3>[method:Float randFloatSpread]( [page:Float range] )</h3>
 		<div>
-		Returns a value interpolated from two known points based on the interval.<br/><br/>
+		Random float from *- range / 2* to *range / 2* interval.
+		</div>
 
-		[link:https://en.wikipedia.org/wiki/Linear_interpolation Wikipedia]
+		<h3>[method:Integer randInt]( [page:Integer low], [page:Integer high] )</h3>
+		<div>
+		Random integer from *low* to *high* interval.
+		</div>
+
+		<h3>[method:Float random16]()</h3>
+		<div>
+		Random float from 0 to 1 with 16 bits of randomness.<br />
+		Standard Math.random() creates repetitive patterns when applied over larger space.
 		</div>
 
 		<h3>[method:Float smoothstep]( [page:Float x], [page:Float min], [page:Float max] )</h3>
@@ -94,7 +121,8 @@
 		max -- Any x value above max will be 1
 		</div>
 		<div>
-		Returns a value between 0-1 that represents the percentage that x has moved between min and max, but smoothed or slowed down the closer X is to the min and max.<br/><br/>
+		Returns a value between 0-1 that represents the percentage that x has moved between min and max,
+		but smoothed or slowed down the closer X is to the min and max.<br/><br/>
 
 		[link:http://en.wikipedia.org/wiki/Smoothstep Wikipedia]
 		</div>

+ 87 - 0
docs/api/math/interpolants/CubicInterpolant.html

@@ -0,0 +1,87 @@
+<!DOCTYPE html>
+<html lang="en">
+	<head>
+		<meta charset="utf-8" />
+		<base href="../../../" />
+		<script src="list.js"></script>
+		<script src="page.js"></script>
+		<link type="text/css" rel="stylesheet" href="page.css" />
+	</head>
+	<body>
+		[page:Interpolant] &rarr;
+
+		<h1>[name]</h1>
+
+		<div class="desc">
+
+		</div>
+
+		<h2>Example</h2>
+
+		<code>
+var interpolant = new THREE.[name](
+		new Float32Array( 2 ),
+		new Float32Array( 2 ),
+		1,
+		new Float32Array( 1 )
+);
+
+interpolant.evaluate( 0.5 );
+		</code>
+
+
+		<h2>Constructor</h2>
+
+		<h3>[name]( parameterPositions, sampleValues, sampleSize, resultBuffer )</h3>
+		<div>
+		parameterPositions -- array of positions<br />
+		sampleValues -- array of samples<br />
+		sampleSize -- number of samples<br />
+		resultBuffer -- buffer to store the interpolation results.<br /><br />
+
+
+		</div>
+
+		<h2>Properties</h2>
+
+
+
+		<h3>[property:null parameterPositions]</h3>
+		<div>
+
+		</div>
+
+		<h3>[property:null resultBuffer]</h3>
+		<div>
+
+		</div>
+
+		<h3>[property:null sampleValues]</h3>
+		<div>
+
+		</div>
+
+		<h3>[property:Object settings]</h3>
+		<div>
+
+		</div>
+
+		<h3>[property:null valueSize]</h3>
+		<div>
+
+		</div>
+
+		<h2>Methods</h2>
+
+		<h3>[method:null evaluate]( [page:Number t] )</h3>
+		<div>
+		Evaluate the interpolant at position *t*.
+		</div>
+
+		</div>
+
+		<h2>Source</h2>
+
+		[link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js]
+	</body>
+</html>

+ 87 - 0
docs/api/math/interpolants/DiscreteInterpolant.html

@@ -0,0 +1,87 @@
+<!DOCTYPE html>
+<html lang="en">
+	<head>
+		<meta charset="utf-8" />
+		<base href="../../../" />
+		<script src="list.js"></script>
+		<script src="page.js"></script>
+		<link type="text/css" rel="stylesheet" href="page.css" />
+	</head>
+	<body>
+		[page:Interpolant] &rarr;
+
+		<h1>[name]</h1>
+
+		<div class="desc">
+
+		</div>
+
+		<h2>Example</h2>
+
+		<code>
+var interpolant = new THREE.[name](
+		new Float32Array( 2 ),
+		new Float32Array( 2 ),
+		1,
+		new Float32Array( 1 )
+);
+
+interpolant.evaluate( 0.5 );
+		</code>
+
+
+		<h2>Constructor</h2>
+
+		<h3>[name]( parameterPositions, sampleValues, sampleSize, resultBuffer )</h3>
+		<div>
+		parameterPositions -- array of positions<br />
+		sampleValues -- array of samples<br />
+		sampleSize -- number of samples<br />
+		resultBuffer -- buffer to store the interpolation results.<br /><br />
+
+
+		</div>
+
+		<h2>Properties</h2>
+
+
+
+		<h3>[property:null parameterPositions]</h3>
+		<div>
+
+		</div>
+
+		<h3>[property:null resultBuffer]</h3>
+		<div>
+
+		</div>
+
+		<h3>[property:null sampleValues]</h3>
+		<div>
+
+		</div>
+
+		<h3>[property:Object settings]</h3>
+		<div>
+
+		</div>
+
+		<h3>[property:null valueSize]</h3>
+		<div>
+
+		</div>
+
+		<h2>Methods</h2>
+
+		<h3>[method:null evaluate]( [page:Number t] )</h3>
+		<div>
+		Evaluate the interpolant at position *t*.
+		</div>
+
+		</div>
+
+		<h2>Source</h2>
+
+		[link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js]
+	</body>
+</html>

+ 87 - 0
docs/api/math/interpolants/LinearInterpolant.html

@@ -0,0 +1,87 @@
+<!DOCTYPE html>
+<html lang="en">
+	<head>
+		<meta charset="utf-8" />
+		<base href="../../../" />
+		<script src="list.js"></script>
+		<script src="page.js"></script>
+		<link type="text/css" rel="stylesheet" href="page.css" />
+	</head>
+	<body>
+		[page:Interpolant] &rarr;
+
+		<h1>[name]</h1>
+
+		<div class="desc">
+
+		</div>
+
+		<h2>Example</h2>
+
+		<code>
+var interpolant = new THREE.[name](
+		new Float32Array( 2 ),
+		new Float32Array( 2 ),
+		1,
+		new Float32Array( 1 )
+);
+
+interpolant.evaluate( 0.5 );
+		</code>
+
+
+		<h2>Constructor</h2>
+
+		<h3>[name]( parameterPositions, sampleValues, sampleSize, resultBuffer )</h3>
+		<div>
+		parameterPositions -- array of positions<br />
+		sampleValues -- array of samples<br />
+		sampleSize -- number of samples<br />
+		resultBuffer -- buffer to store the interpolation results.<br /><br />
+
+
+		</div>
+
+		<h2>Properties</h2>
+
+
+
+		<h3>[property:null parameterPositions]</h3>
+		<div>
+
+		</div>
+
+		<h3>[property:null resultBuffer]</h3>
+		<div>
+
+		</div>
+
+		<h3>[property:null sampleValues]</h3>
+		<div>
+
+		</div>
+
+		<h3>[property:Object settings]</h3>
+		<div>
+
+		</div>
+
+		<h3>[property:null valueSize]</h3>
+		<div>
+
+		</div>
+
+		<h2>Methods</h2>
+
+		<h3>[method:null evaluate]( [page:Number t] )</h3>
+		<div>
+		Evaluate the interpolant at position *t*.
+		</div>
+
+		</div>
+
+		<h2>Source</h2>
+
+		[link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js]
+	</body>
+</html>

+ 87 - 0
docs/api/math/interpolants/QuaternionLinearInterpolant.html

@@ -0,0 +1,87 @@
+<!DOCTYPE html>
+<html lang="en">
+	<head>
+		<meta charset="utf-8" />
+		<base href="../../../" />
+		<script src="list.js"></script>
+		<script src="page.js"></script>
+		<link type="text/css" rel="stylesheet" href="page.css" />
+	</head>
+	<body>
+		[page:Interpolant] &rarr;
+
+		<h1>[name]</h1>
+
+		<div class="desc">
+
+		</div>
+
+		<h2>Example</h2>
+
+		<code>
+var interpolant = new THREE.[name](
+		new Float32Array( 2 ),
+		new Float32Array( 2 ),
+		1,
+		new Float32Array( 1 )
+);
+
+interpolant.evaluate( 0.5 );
+		</code>
+
+
+		<h2>Constructor</h2>
+
+		<h3>[name]( parameterPositions, sampleValues, sampleSize, resultBuffer )</h3>
+		<div>
+		parameterPositions -- array of positions<br />
+		sampleValues -- array of samples<br />
+		sampleSize -- number of samples<br />
+		resultBuffer -- buffer to store the interpolation results.<br /><br />
+
+
+		</div>
+
+		<h2>Properties</h2>
+
+
+
+		<h3>[property:null parameterPositions]</h3>
+		<div>
+
+		</div>
+
+		<h3>[property:null resultBuffer]</h3>
+		<div>
+
+		</div>
+
+		<h3>[property:null sampleValues]</h3>
+		<div>
+
+		</div>
+
+		<h3>[property:Object settings]</h3>
+		<div>
+
+		</div>
+
+		<h3>[property:null valueSize]</h3>
+		<div>
+
+		</div>
+
+		<h2>Methods</h2>
+
+		<h3>[method:null evaluate]( [page:Number t] )</h3>
+		<div>
+		Evaluate the interpolant at position *t*.
+		</div>
+
+		</div>
+
+		<h2>Source</h2>
+
+		[link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js]
+	</body>
+</html>

+ 59 - 0
docs/api/objects/Group.html

@@ -0,0 +1,59 @@
+<!DOCTYPE html>
+<html lang="en">
+	<head>
+		<meta charset="utf-8" />
+		<base href="../../" />
+		<script src="list.js"></script>
+		<script src="page.js"></script>
+		<link type="text/css" rel="stylesheet" href="page.css" />
+	</head>
+	<body>
+		[page:Object3D] &rarr;
+
+		<h1>[name]</h1>
+
+		<div class="desc">This is almost identical to an [page:Object3D Object3D]. It's purpose is to make working with groups of objects syntactically clearer.</div>
+
+
+		<h2>Example</h2>
+
+		<code>
+		var geometry = new THREE.BoxBufferGeometry( 1, 1, 1 );
+		var material = new THREE.MeshBasicMaterial( {color: 0x00ff00} );
+
+		var cubeA = new THREE.Mesh( geometry, material );
+		cubeA.position.set( 100, 100, 0 );
+
+		var cubeB = new THREE.Mesh( geometry, material );
+		cubeA.position.set( -100, -100, 0 );
+
+		//create a group and add the two cubes
+		//These cubes can now be rotated / scaled etc as a group
+		var group = new THREE.Group();
+		group.add( cubeA );
+		group.add( cubeB )
+
+		scene.add( group );
+		</code>
+
+
+		<h2>Constructor</h2>
+
+		<h3>[name]( )</h3>
+
+		<h2>Properties</h2>
+
+		Properties are identical to an [page:Object3D]'s properties, with the exception of:
+
+		<h3>[property:String type]</h3>
+		<div>A string 'Group'. This should not be changed.</div>
+
+		<h2>Methods</h2>
+
+		Methods are identical to an [page:Object3D]'s methods.
+
+		<h2>Source</h2>
+
+		[link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js]
+	</body>
+</html>

+ 10 - 3
docs/api/renderers/CanvasRenderer.html

@@ -11,7 +11,15 @@
 		<h1>[name]</h1>
 
 		<div class="desc">
-			The Canvas renderer displays your beautifully crafted scenes <em>not</em> using WebGL, but draws it using the (slower) <a href="http://drafts.htmlwg.org/2dcontext/html5_canvas_CR/Overview.html">Canvas 2D Context</a> API.<br /><br />
+			The Canvas renderer displays your beautifully crafted scenes <em>not</em> using WebGL,
+			but draws it using the (slower) <a href="http://drafts.htmlwg.org/2dcontext/html5_canvas_CR/Overview.html">Canvas 2D Context</a>
+			API.<br /><br />
+
+			<b>
+			NOTE: The Canvas renderer has been deprecated and is no longer part of the Three.js core.
+			</b>
+			If you still need to use it you can find it here: [link:https://github.com/mrdoob/three.js/blob/master/examples/js/[path].js examples/js/[path].js].<br /><br />
+
 			This renderer can be a nice fallback from [page:WebGLRenderer] for simple scenes:
 
 			<code>
@@ -38,7 +46,6 @@
 			The "Canvas" in CanvasRenderer means it uses Canvas 2D instead of WebGL.<br /><br />
 
 			Don't confuse either CanvasRenderer with the SoftwareRenderer example, which simulates a screen buffer in a Javascript array.
-			Because the Canvas renderer is not part of the three.js core, you have to include it from /examples/js/renderers/.
 		</div>
 
 		<h2>Constructor</h2>
@@ -158,6 +165,6 @@
 
 		<h2>Source</h2>
 
-		[link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js]
+		[link:https://github.com/mrdoob/three.js/blob/master/examples/js/[path].js examples/js/[path].js]
 	</body>
 </html>

+ 292 - 163
docs/api/renderers/WebGLRenderer.html

@@ -11,120 +11,134 @@
 		<h1>[name]</h1>
 
 		<div class="desc">The WebGL renderer displays your beautifully crafted scenes using WebGL, if your device supports it.</div>
-		<div class="desc">This renderer has way better performance than [page:CanvasRenderer].</div>
-
 
 		<h2>Constructor</h2>
 
-
 		<h3>[name]( [page:Object parameters] )</h3>
 
-		<div>parameters is an optional object with properties defining the renderer's behaviour. The constructor also accepts no parameters at all. In all cases, it will assume sane defaults when parameters are missing.</div>
-
 		<div>
-		canvas — A [page:Canvas] where the renderer draws its output.<br />
-		context — The [page:RenderingContext] context to use.<br />
-		precision — Shader precision. Can be *"highp"*, *"mediump"* or *"lowp"*. Defaults to *"highp"* if supported by the device.<br />
-		alpha — [page:Boolean], default is *false*.<br />
-		premultipliedAlpha — [page:Boolean], default is *true*.<br />
-		antialias — [page:Boolean], default is *false*.<br />
-		stencil — [page:Boolean], default is *true*.<br />
-		preserveDrawingBuffer — [page:Boolean], default is *false*.<br />
-		depth — [page:Boolean], default is *true*.<br />
-		logarithmicDepthBuffer — [page:Boolean], default is *false*.<br />
+		parameters is an optional object with properties defining the renderer's behaviour.
+			The constructor also accepts no parameters at all. In all cases, it will assume sane defaults
+			when parameters are missing.
 		</div>
 
-		<h2>Properties</h2>
-
-		<h3>[property:DOMElement domElement]</h3>
-
-		<div>A [page:Canvas] where the renderer draws its output.<br />
-		This is automatically created by the renderer in the constructor (if not provided already); you just need to add it to your page.</div>
+		<div>
+		canvas — A [link:https://developer.mozilla.org/en-US/docs/Web/HTML/Element/canvas canvas] where the renderer draws its output.
+		This corresponds to the [page:WebGLRenderer.domElement .domElement] property below.<br />
 
-		<h3>[property:WebGLRenderingContext context]</h3>
+		context — This can be used to attach the renderer to an existing [link:https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext RenderingContext].<br />
 
-		<div>The HTML5 Canvas's 'webgl' context obtained from the canvas where the renderer will draw.</div>
+		precision — Shader precision. Can be *"highp"*, *"mediump"* or *"lowp"*. Defaults to *"highp"* if supported by the device.<br />
 
-		<h3>[property:Boolean autoClear]</h3>
+		alpha — whether the canvas contains an alpha (transparency) buffer or not. Default is *false*.<br />
 
-		<div>Defines whether the renderer should automatically clear its output before rendering.</div>
+		premultipliedAlpha — whether the renderer will assume that colors have premultiplied alpha. Default is *true*.<br />
 
+		antialias — whether to perform antialiasing. Default is *false*.<br />
 
-		<h3>[property:Boolean autoClearColor]</h3>
+		stencil — whether the drawing buffer has a stencil buffer of at least 8 bits. Default is *true*.<br />
 
-		<div>If autoClear is true, defines whether the renderer should clear the color buffer. Default is true.</div>
+		preserveDrawingBuffer — whether to preserve the buffers until manually cleared or overwritten. Default is *false*.<br />
 
+		depth — whether the drawing buffer has a depth buffer of at least 16 bits. Default is *true*.<br />
 
-		<h3>[property:Boolean autoClearDepth]</h3>
+		logarithmicDepthBuffer —  whether to use a lograthimic depth buffer. Default is *false*.
+		See the [example:webgl_camera_logarithmicdepthbuffer camera / logarithmicdepthbuffer] example.
+		</div>
 
-		<div>If autoClear is true, defines whether the renderer should clear the depth buffer. Default is true.</div>
+		<h2>Properties</h2>
 
+		<h3>[property:Boolean autoClear]</h3>
+		<div>Defines whether the renderer should automatically clear its output before rendering.</div>
 
-		<h3>[property:Boolean autoClearStencil]</h3>
 
-		<div>If autoClear is true, defines whether the renderer should clear the stencil buffer. Default is true.</div>
+		<h3>[property:Boolean autoClearColor]</h3>
+		<div>If autoClear is true, defines whether the renderer should clear the color buffer. Default is *true*.</div>
 
 
-		<h3>[property:Boolean sortObjects]</h3>
+		<h3>[property:Boolean autoClearDepth]</h3>
+		<div>If autoClear is true, defines whether the renderer should clear the depth buffer. Default is *true*.</div>
 
-		<div>Defines whether the renderer should sort objects. Default is true.</div>
 
-		<div>Note: Sorting is used to attempt to properly render objects that have some degree of transparency.  By definition, sorting objects may not work in all cases.  Depending on the needs of application, it may be neccessary to turn off sorting and use other methods to deal with transparency rendering e.g. manually determining the object rendering order.</div>
+		<h3>[property:Boolean autoClearStencil]</h3>
+		<div>If autoClear is true, defines whether the renderer should clear the stencil buffer. Default is *true*.</div>
 
+		<h3>[property:Object capabilities]</h3>
+		<div>
+		An object containing details about the capabilities of the current [link:https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext RenderingContext].<br />
+
+		- [property:Boolean floatFragmentTextures]: whether the context supports the [link:https://developer.mozilla.org/en-US/docs/Web/API/OES_texture_float OES_texture_float] extension.
+			According to [link:https://webglstats.com/ WebGLStats], as of February 2016 over 95% of WebGL enabled devices support this.<br />
+		- [property:Boolean floatVertexTextures]: *true* if [property:Boolean floatFragmentTextures] and [property:Boolean vertexTextures] are both true.<br />
+		- [property:Method getMaxAnisotropy](): see [page:WebGLRenderer.getMaxAnisotropy getMaxAnisotropy] below. <br />
+		- [property:Method getMaxPrecision](): see [page:WebGLRenderer.getMaxPrecision getMaxPrecision] below. <br />
+		- [property:Boolean logarithmicDepthBuffer]: *true* if the [property:parameter logarithmicDepthBuffer] was set to true in the constructor and
+		the context supports the [link:https://developer.mozilla.org/en-US/docs/Web/API/EXT_frag_depth EXT_frag_depth] extension.
+			According to [link:https://webglstats.com/ WebGLStats], as of February 2016 around 66% of WebGL enabled devices support this.<br />
+		- [property:Integer maxAttributes]: The value of *gl.MAX_VERTEX_ATTRIBS*.<br />
+		- [property:Integer maxCubemapSize]: The value of *gl.MAX_CUBE_MAP_TEXTURE_SIZE*.
+		Maximum height * width of cube map textures that a shader can use.<br />
+		- [property:Integer maxFragmentUniforms]: The value of *gl.MAX_FRAGMENT_UNIFORM_VECTORS*.
+		  The number of uniforms that can be used by a fragment shader.<br />
+		- [property:Integer maxTextureSize]: The value of *gl.MAX_TEXTURE_SIZE*.
+		Maximum height * width of a texture that a shader use.<br />
+		- [property:Integer maxTextures]: The value of *gl.MAX_TEXTURE_IMAGE_UNITS*.
+		  The maximum number of textures that can be used by a shader.<br />
+		- [property:Integer maxVaryings]: The value of *gl.MAX_VARYING_VECTORS*.
+		  The number of varying vectors that can used by shaders.<br />
+		- [property:Integer maxVertexTextures]: The value of *gl.MAX_VERTEX_TEXTURE_IMAGE_UNITS*.
+		   The number of textures that can be used in a vertex shader.<br />
+		- [property:Integer maxVertexUniforms]: The value of *gl.MAX_VERTEX_UNIFORM_VECTORS*.
+		   The maximum number of uniforms that can be used in a vertex shader.<br />
+		- [property:String precision]: The shader precision currently being used by the renderer.<br />
+		- [property:Boolean vertexTextures]: *true* if [property:Integer maxVertexTextures] is greater than 0 (i.e. vertext textures can be used).<br />
+		</div>
 
 		<h3>[property:Array clippingPlanes]</h3>
-
-		<div>User-defined clipping planes specified as THREE.Plane objects in world space. These planes apply globally. Points in space whose dot product with the plane is negative are cut away. Default is [].</div>
-
-		<h3>[property:Boolean localClippingEnabled]</h3>
-
-		<div>Defines whether the renderer respects object-level clipping planes. Default is false.</div>
-
-
-
-		<h3>[property:Boolean gammaInput]</h3>
-
-		<div>Default is false. If set, then it expects that all textures and colors are premultiplied gamma.</div>
-
-
-		<h3>[property:Boolean gammaOutput]</h3>
-
-		<div>Default is false.  If set, then it expects that all textures and colors need to be outputted in premultiplied gamma.</div>
-
-		<h3>[property:WebGLShadowMap shadowMap]</h3>
 		<div>
-		This contains the reference to the component implementing shadow mapping.
+		User-defined clipping planes specified as THREE.Plane objects in world space.
+			These planes apply globally. Points in space whose dot product with the plane is negative are cut away.
+		 Default is [].
 		</div>
 
-		<h3>[property:Boolean shadowMap.enabled]</h3>
-
-		<div>Default is false. If set, use shadow maps in the scene.</div>
-
-		<h3>[property:Integer shadowMap.type]</h3>
-
-		<div>Defines shadow map type (unfiltered, percentage close filtering, percentage close filtering with bilinear filtering in shader)</div>
-		<div>Options are THREE.BasicShadowMap, THREE.PCFShadowMap (default), THREE.PCFSoftShadowMap. See [page:WebGLRenderer WebGLRenderer constants] for details.</div>
-
-		<h3>[property:Boolean shadowMap.renderReverseSided]</h3>
-
-		<div>Default is true. Whether to render the opposite side as specified by the material into the shadow map. When disabled, an appropriate shadow.bias must be set on the light source for surfaces that can both cast and receive shadows at the same time to render correctly.</div>
+		<h3>[property:WebGLRenderingContext context]</h3>
+		<div>
+		The renderer obtains a [link:https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext RenderingContext] context
+		  from its [page:WebGLRenderer.domElement domElement][page:WebGLRenderer.domElement domElement] by default, using
+			[link:https://developer.mozilla.org/en/docs/Web/API/HTMLCanvasElement/getContext HTMLCanvasElement.getContext]()</a>.<br /><br />
 
-		<h3>[property:Boolean shadowMap.renderSingleSided]</h3>
+		You can create this manually, however it must correspond to the
+		[page:WebGLRenderer.domElement domElement] in order to render to the screen.
+		</div>
 
-		<div>Default is true. Whether to treat materials specified as double-sided as if they were specified as front-sided when rendering the shadow map. When disabled, an appropriate shadow.bias must be set on the light source for surfaces that can both cast and receive shadows at the same time to render correctly.</div>
+		<h3>[property:DOMElement domElement]</h3>
+		<div>
+		A [link:https://developer.mozilla.org/en-US/docs/Web/HTML/Element/canvas canvas] where the renderer draws its output.<br />
+			This is automatically created by the renderer in the constructor (if not provided already);
+			you just need to add it to your page like so:<br />
+		<code>
+			document.body.appendChild( renderer.domElement );
+		</code>
+	  </div>
 
-		<h3>[property:Integer maxMorphTargets]</h3>
+		<h3>[property:Object extensions]</h3>
+		<div>
+		A wrapper for the [page:WebGLRenderer.extensions.get .extensions.get] method, used to check whether
+		various WebGL extensions are supported.
+		</div>
 
-		<div>Default is 8. The maximum number of MorphTargets allowed in a shader. Keep in mind that the standard materials only allow 8 MorphTargets.</div>
+		<h3>[property:Boolean gammaFactor]</h3>
+		<div>Default is *2*. </div>
 
 
-		<h3>[property:Integer maxMorphNormals]</h3>
+		<h3>[property:Boolean gammaInput]</h3>
+		<div>If set, then it expects that all textures and colors are premultiplied gamma. Default is *false*.</div>
 
-		<div>Default is 4. The maximum number of MorphNormals allowed in a shader. Keep in mind that the standard materials only allow 4 MorphNormals. </div>
 
+		<h3>[property:Boolean gammaOutput]</h3>
+		<div>If set, then it expects that all textures and colors need to be outputted in premultiplied gamma. Default is *false*.</div>
 
 		<h3>[property:Object info]</h3>
-
 		<div>An object with a series of statistical information about the graphics board memory and the rendering process. Useful for debugging or just for the sake of curiosity. The object contains the following fields:</div>
 		<div>
 		<ul>
@@ -147,167 +161,282 @@
 		</ul>
 		</div>
 
-		<h2>Methods</h2>
+		<h3>[property:Boolean localClippingEnabled]</h3>
+		<div>Defines whether the renderer respects object-level clipping planes. Default is *false*.</div>
 
-		<h3>[method:WebGLRenderingContext getContext]()</h3>
+		<h3>[property:Integer maxMorphTargets]</h3>
 		<div>
-		Return the WebGL context.
+		Default is 8. The maximum number of MorphTargets allowed in a shader.
+			Keep in mind that the standard materials only allow 8 MorphTargets.
 		</div>
 
-		<h3>[method:WebGLContextAttributes getContextAttributes]()</h3>
+		<h3>[property:Integer maxMorphNormals]</h3>
 		<div>
-		Returns an object that describes the attributes set on the WebGL context when it was created.
+		Default is 4. The maximum number of MorphNormals allowed in a shader.
+			Keep in mind that the standard materials only allow 4 MorphNormals.
 		</div>
 
-		<h3>[method:Boolean supportsVertexTextures]()</h3>
+		<h3>[property:Integer physicallyCorrectLights]</h3>
 		<div>
-		Return a [page:Boolean] true if the context supports vertex textures.
+		Whether to use physically correct lighting mode. Default is *false*.
+		See the [example:webgl_lights_physical lights / physical] example.
 		</div>
 
-		<h3>[method:number getPixelRatio]()</h3>
-		<div>Returns current device pixel ratio used.</div>
+		<h3>[property:Object properties]</h3>
+		<div>
+		Used internally by the renderer to keep track of various sub object properties.
+		</div>
 
-		<h3>[method:null setPixelRatio]( [page:number value] )</h3>
-		<div>Sets device pixel ratio. This is usually used for HiDPI device to prevent bluring output canvas.</div>
+		<h3>[property:WebGLShadowMap shadowMap]</h3>
+		<div>
+		This contains the reference to the shadow map, if used.
+		</div>
 
-		<h3>[method:Object getSize]()</h3>
-		<div>Returns an object containing the width and height of the renderer's output canvas, in pixels.</div>
+		<h3>[property:Boolean shadowMap.enabled]</h3>
+		<div>If set, use shadow maps in the scene. Default is *false*.</div>
 
-		<h3>[method:null setSize]( [page:Integer width], [page:Integer height], [page:Boolean updateStyle] )</h3>
-		<div>Resizes the output canvas to (width, height) with device pixel ratio taken into account, and also sets the viewport to fit that size, starting in (0, 0). Setting updateStyle to true adds explicit pixel units to the output canvas style.</div>
+		<h3>[property:Integer shadowMap.type]</h3>
+		<div>Defines shadow map type (unfiltered, percentage close filtering, percentage close filtering with bilinear filtering in shader)</div>
+		<div>Options are THREE.BasicShadowMap, THREE.PCFShadowMap (default), THREE.PCFSoftShadowMap. See [page:WebGLRenderer WebGLRenderer constants] for details.</div>
 
-		<h3>[method:null setViewport]( [page:Integer x], [page:Integer y], [page:Integer width], [page:Integer height] )</h3>
-		<div>Sets the viewport to render from (x, y) to (x + width, y + height).</div>
+		<h3>[property:Boolean shadowMap.renderReverseSided]</h3>
+		<div>
+		Whether to render the opposite side as specified by the material into the shadow map.
+			When disabled, an appropriate shadow.bias must be set on the light source for surfaces that can
+			both cast and receive shadows at the same time to render correctly. Default is *true*.
+		</div>
 
+		<h3>[property:Boolean shadowMap.renderSingleSided]</h3>
+		<div>
+		Whether to treat materials specified as double-sided as if they were specified as front-sided
+		when rendering the shadow map. When disabled, an appropriate shadow.bias must be set on the light
+		source for surfaces that can both cast and receive shadows at the same time to render correctly.
+		Default is *true*.
+		</div>
 
-		<h3>[method:null setScissor]( [page:Integer x], [page:Integer y], [page:Integer width], [page:Integer height] )</h3>
-		<div>Sets the scissor area from (x, y) to (x + width, y + height).</div>
+		<h3>[property:Boolean sortObjects]</h3>
+		<div>
+		Defines whether the renderer should sort objects. Default is *true*.<br /><br />
 
-		<div>NOTE: The point (x, y) is the lower left corner of the area to be set for both of these methods. The area is defined from left to right in width but bottom to top in height. The sense of the vertical definition is opposite to the fill direction of an HTML canvas element.</div>
+		Note: Sorting is used to attempt to properly render objects that have some degree of transparency.
+		By definition, sorting objects may not work in all cases.  Depending on the needs of application,
+		it may be neccessary to turn off sorting and use other methods to deal with transparency
+		rendering e.g. manually determining each object's rendering order.
+		</div>
 
-		<h3>[method:null setScissorTest]( [page:Boolean boolean] )</h3>
-		<div>Enable or disable the scissor test. When this is enabled, only the pixels within the defined scissor area will be affected by further renderer actions.</div>
+		<h3>[property:Object state]</h3>
+		<div>
+		Contains functions for setting various properties of the [page:WebGLRenderer.context] state.
+		</div>
 
-		<h3>[method:null setClearColor]( [page:Color color], [page:Float alpha] )</h3>
-		<div>Sets the clear color and opacity.</div>
+		<h3>[property:Constant toneMapping]</h3>
+		<div>
+		Default is [page:Renderer LinearToneMapping]. See the [page:Renderer Renderer constants] for other choices.
+		</div>
 
-		<code>// Creates a renderer with red background
-		var renderer = new THREE.WebGLRenderer();
-		renderer.setSize( 200, 100 );
-		renderer.setClearColor( 0xff0000 );
-		</code>
+		<h3>[property:Number toneMappingExposure]</h3>
+		<div>
+		Exposure level of tone mapping. Default is *1*.
+		</div>
 
-		<h3>[method:Color getClearColor]()</h3>
-		<div>Returns a [page:Color THREE.Color] instance with the current clear color.</div>
+		<h3>[property:Number toneMappingWhitePoint]</h3>
+		<div>
+		Tone mapping white point. Default is *1*.
+		</div>
 
-		<h3>[method:Float getClearAlpha]()</h3>
-		<div>Returns a [page:Float float] with the current clear alpha. Ranges from 0 to 1.</div>
+		<h2>Methods</h2>
+
+		<h3>[method:Integer allocTextureUnit]</h3>
+		<div>
+		Attempt to allocate a texture unit for use by a shader. Will warn if trying to allocate
+		more texture units than the GPU supports. This is mainly used internally.
+		See [page:WebGLRenderer.capabilities capabilities.maxTextures].
+		</div>
 
 		<h3>[method:null clear]( [page:Boolean color], [page:Boolean depth], [page:Boolean stencil] )</h3>
-		<div>Tells the renderer to clear its color, depth or stencil drawing buffer(s). This method initializes the color buffer to the current clear color value.</div>
-		<div>Arguments default to true.</div>
+		<div>
+		Tells the renderer to clear its color, depth or stencil drawing buffer(s).
+			This method initializes the color buffer to the current clear color value.<br />
+		Arguments default to *true*.
+		</div>
 
-		<h3>[method:null renderBufferImmediate]( [page:Object3D object], [page:shaderprogram program], [page:Material shading] )</h3>
-		<div>object — an instance of [page:Object3D]<br />
-		program — an instance of shaderProgram<br />
-		shading — an instance of Material<br />
+		<h3>[method:null clearColor]( )</h3>
+		<div>Clear the color buffer. Equivalent to calling [page:WebGLRenderer.clear .clear]( true, false, false ).</div>
+
+		<h3>[method:null clearDepth]( )</h3>
+		<div>Clear the depth buffer. Equivalent to calling [page:WebGLRenderer.clear .clear]( false, true, false ).</div>
+
+		<h3>[method:null clearStencil]( )</h3>
+		<div>Clear the stencil buffers. Equivalent to calling [page:WebGLRenderer.clear .clear]( false, false, true ).</div>
+
+		<h3>[method:null clearTarget]([page:WebGLRenderTarget renderTarget], [page:boolean color], [page:boolean depth], [page:boolean stencil])</h3>
+		<div>
+		renderTarget -- The [page:WebGLRenderTarget renderTarget] that needs to be cleared.<br />
+		color -- If set, then the color gets cleared. <br />
+		depth -- If set, then the depth gets cleared. <br />
+		stencil -- If set, then the stencil gets cleared.
 		</div>
 		<div>
-		Render an immediate buffer. Gets called by renderImmediateObject.
+		This method clears a rendertarget. To do this, it activates the rendertarget.
 		</div>
 
+		<h3>[method:null dispose]( )</h3>
+		<div>Dispose of the current rendering context.</div>
 
-		<h3>[method:null renderBufferDirect]( [page:Camera camera], [page:Array lights], [page:Fog fog], [page:Material material], [page:Object geometryGroup], [page:Object3D object] )</h3>
-		<div>Render a buffer geometry group using the camera and with the correct material.</div>
+		<h3>[method:Object extensions.get]( [page:String extensionName] )</h3>
+		<div>
+		Used to check whether various extensions are supported and returns an object with details of the extension if available.
+		This method can check for the following extensions:<br /><br />
+
+		- *WEBGL_depth_texture*<br />
+		- *EXT_texture_filter_anisotropic*<br />
+		- *WEBGL_compressed_texture_s3tc*<br />
+		- *WEBGL_compressed_texture_pvrtc*<br />
+		- *WEBGL_compressed_texture_etc1*
+		</div>
+
+		<h3>[method:null forceContextLoss]( )</h3>
+		<div>
+		Simulate loss of the WebGL context. This requires support for the
+			[link:https://developer.mozilla.org/en-US/docs/Web/API/WEBGL_lose_context WEBGL_lose_context] extensions.
+		According to [link:https://webglstats.com/ WebGLStats], as of February 2016 90% of WebGL enabled devices support this.
+		</div>
+
+		<h3>[method:Float getClearAlpha]()</h3>
+		<div>Returns a [page:Float float] with the current clear alpha. Ranges from 0 to 1.</div>
 
+		<h3>[method:Color getClearColor]()</h3>
+		<div>Returns a [page:Color THREE.Color] instance with the current clear color.</div>
 
-		<h3>[method:null renderBuffer]( [page:Camera camera], [page:Array lights], [page:Fog fog], [page:Material material], [page:Object geometryGroup], [page:Object3D object] )</h3>
-		<div>Render a geometry group using the camera and with the correct material.</div>
+		<h3>[method:WebGLRenderingContext getContext]()</h3>
+		<div>Return the current WebGL context.</div>
 
+		<h3>[method:WebGLContextAttributes getContextAttributes]()</h3>
+		<div>Returns an object that describes the attributes set on the WebGL context when it was created.</div>
 
-		<h3>[method:null render]( [page:Scene scene], [page:Camera camera], [page:WebGLRenderTarget renderTarget], [page:Boolean forceClear] )</h3>
-		<div>Render a scene using a camera.</div>
-		<div>The render is done to the renderTarget (if specified) or to the canvas as usual.</div>
-		<div>If forceClear is true, the depth, stencil and color buffers will be cleared before rendering even if the renderer's autoClear property is false.</div>
-		<div>Even with forceClear set to true you can prevent certain buffers being cleared by setting either the .autoClearColor, .autoClearStencil or .autoClearDepth properties to false.</div>
+		<h3>[method:RenderTarget getCurrentRenderTarget](  )</h3>
+		<div>Returns the current RenderTarget, if any.</div>
 
-		<h3>[method:null readRenderTargetPixels]( [page:WebGLRenderTarget renderTarget], [page:Float x], [page:Float y], [page:Float width], [page:Float height], buffer )</h3>
-		<div>Reads the pixel data from the renderTarget into the buffer you pass in. Buffer should be a Javascript Uint8Array instantiated with new Uint8Array( renderTargetWidth * renderTargetWidth * 4 ) to account for size and color information. This is a wrapper around gl.readPixels.</div>
+		<h3>[method:Number getMaxAnisotropy]()</h3>
+		<div>This returns the anisotropy level of the textures.</div>
 
-		<h3>[method:null renderImmediateObject]( camera, lights, fog, material, object )</h3>
-		<div>Renders an immediate Object using a camera.</div>
+		<h3>[method:number getPixelRatio]()</h3>
+		<div>Returns current device pixel ratio used.</div>
+
+		<h3>[method:string getPrecision]()</h3>
+		<div>This gets the precision used by the shaders. It returns "highp","mediump" or "lowp".</div>
 
+		<h3>[method:Object getSize]()</h3>
+		<div>Returns an object containing the width and height of the renderer's output canvas, in pixels.</div>
 
-		<h3>[method:null setFaceCulling]( cullFace, frontFace )</h3>
+		<h3>[method:null resetGLState]( )</h3>
+		<div>Reset the GL state to default. Called internally if the WebGL context is lost.</div>
+
+		<h3>[method:null readRenderTargetPixels]( [page:WebGLRenderTarget renderTarget], [page:Float x], [page:Float y], [page:Float width], [page:Float height], buffer )</h3>
+		<div>Reads the pixel data from the renderTarget into the buffer you pass in.
+			Buffer should be a Javascript Uint8Array instantiated with
+			new Uint8Array( renderTargetWidth * renderTargetWidth * 4 ) to account for size and color
+			information. This is a wrapper around gl.readPixels.<br />
+		See the [example:webgl_interactive_cubes_gpu interactive / cubes / gpu] example.
+		</div>
+
+		<h3>[method:null render]( [page:Scene scene], [page:Camera camera], [page:WebGLRenderTarget renderTarget], [page:Boolean forceClear] )</h3>
 		<div>
-		See [page:WebGLRenderer WebGLRenderer constants] for all possible values for [page:String cullFace] and [page:String frontFace].<br />
-		Used for setting the gl.frontFace and gl.cullFace states in the GPU, thus enabling/disabling face culling when rendering.<br />
-		If cullFace is set to THREE.[page:String CullFaceNone], culling will be disabled.<br />
+			Render a [page:Scene scene] using a [page:Camera camera].<br />
+
+			The render is done to the [page:WebGLRenderTarget renderTarget] (if specified) or to the canvas as usual.<br />
+
+			If [page:Boolean forceClear] is *true*, the depth, stencil and color buffers will be cleared
+			before rendering even if the renderer's [page:WebGLRenderer.autoClear autoClear] property is false.<br />
+
+			Even with forceClear set to true you can prevent certain buffers being cleared by setting
+			either the [page:WebGLRenderer.autoClearColor autoClearColor], [page:WebGLRenderer.autoClearStencil autoClearStencil] or [page:WebGLRenderer.autoClearDepth autoClearDepth] properties to false.
 		</div>
 
+		<h3>[method:null renderBufferDirect]( [page:Camera camera], [page:Array lights], [page:Fog fog], [page:Material material], [page:Object geometryGroup], [page:Object3D object] )</h3>
+		<div>Render a buffer geometry group using the camera and with the specified material.</div>
 
+		<h3>[method:null renderBufferImmediate]( [page:Object3D object], [page:shaderprogram program], [page:Material shading] )</h3>
+		<div>object — an instance of [page:Object3D]<br />
+		program — an instance of shaderProgram<br />
+		shading — an instance of Material<br /><br />
 
-		<h3>[method:null setTexture]( [page:Texture texture], [page:number slot] )</h3>
-		<div>
-		texture -- The [page:Texture texture] that needs to be set.<br />
-		slot -- The number indicating which slot should be used by the texture.
+		Render an immediate buffer. Gets called by renderImmediateObject.
 		</div>
+
+		<h3>[method:null setClearAlpha]( [page:Float alpha] )</h3>
+		<div>Sets the clear alpha. Valid input is a float between *0.0* and *1.0*.</div>
+
+		<h3>[method:null setClearColor]( [page:Color color], [page:Float alpha] )</h3>
+		<div>Sets the clear color and opacity.</div>
+
+		<h3>[method:null setFaceCulling]( [page:Renderer cullFace], [page:Renderer frontFace] )</h3>
 		<div>
-		This method sets the correct texture to the correct slot for the wegl shader. The slot number can be found as a value of the uniform of the sampler.
+		See [page:Renderer WebGLRenderer constants] for all possible values for [page:Renderer cullFace] and [page:Renderer frontFace].<br />
+		Used for setting the gl.frontFace and gl.cullFace states in the GPU, thus enabling/disabling face culling when rendering.<br />
+		If cullFace is set to [page:Renderer CullFaceNone], culling will be disabled.<br />
 		</div>
 
+		<h3>[method:null setPixelRatio]( [page:number value] )</h3>
+		<div>Sets device pixel ratio. This is usually used for HiDPI device to prevent bluring output canvas.</div>
+
 		<h3>[method:null setRenderTarget]( [page:WebGLRenderTarget renderTarget] )</h3>
 		<div>
-		renderTarget -- The [page:WebGLRenderTarget renderTarget] that needs to be activated (optional).<br />
-		</div>
-		<div>
+		renderTarget -- The [page:WebGLRenderTarget renderTarget] that needs to be activated (optional).<br /><br />
 		This method sets the active rendertarget. If the parameter is omitted the canvas is set as the active rendertarget.
 		</div>
 
-		<h3>[method:boolean supportsCompressedTextureS3TC]()</h3>
+		<h3>[method:null setScissor]( [page:Integer x], [page:Integer y], [page:Integer width], [page:Integer height] )</h3>
 		<div>
-		This method returns true if the webgl implementation supports compressed textures of the format S3TC.
+		Sets the scissor area from (x, y) to (x + width, y + height)
 		</div>
 
-		<h3>[method:number getMaxAnisotropy]()</h3>
+		<h3>[method:null setScissorTest]( [page:Boolean boolean] )</h3>
 		<div>
-		This returns the anisotropy level of the textures.
-		</div>
+		Enable or disable the scissor test. When this is enabled, only the pixels within
+			the defined scissor area will be affected by further renderer actions..<br /><br />
 
-		<h3>[method:string getPrecision]()</h3>
-		<div>
-		This gets the precision used by the shaders. It returns "highp","mediump" or "lowp".
+		NOTE: The point (x, y) is the lower left corner of the area to be set for both of these methods.
+			The area is defined from left to right in width but bottom to top in height.
+			The sense of the vertical definition is opposite to the fill direction of an HTML canvas element.
 		</div>
 
-		<h3>[method:null setMaterialFaces]([page:Material material])</h3>
-		<div>
-		material -- The [page:Material material] with side that shouldn't be culled.
-		</div>
+		<h3>[method:Boolean supportsVertexTextures]()</h3>
 		<div>
-		This sets which side needs to be culled in the webgl renderer.
+		Return a [page:Boolean] true if the context supports vertex textures.
+		This has been deprecated in favour of [page:WebGLRenderer.capabilities capabilities.vertexTexures].
 		</div>
 
-		<h3>[method:boolean supportsStandardDerivatives]()</h3>
+		<h3>[method:null setSize]( [page:Integer width], [page:Integer height], [page:Boolean updateStyle] )</h3>
 		<div>
-		This method returns true if the webgl implementation supports standard derivatives.
+		Resizes the output canvas to (width, height) with device pixel ratio taken into account,
+			and also sets the viewport to fit that size, starting in (0, 0).
+			Setting [page:Boolean updateStyle] to true adds explicit pixel units to the output canvas style.
 		</div>
 
-		<h3>[method:boolean supportsFloatTextures]()</h3>
+		<h3>[method:null setTexture2D]( [page:Texture texture], [page:number slot] )</h3>
 		<div>
-		This method returns true if the webgl implementation supports float textures.
-		</div>
+		texture -- The [page:Texture texture] that needs to be set.<br />
+		slot -- The number indicating which slot should be used by the texture.<br /><br />
 
-		<h3>[method:null clearTarget]([page:WebGLRenderTarget renderTarget], [page:boolean color], [page:boolean depth], [page:boolean stencil])</h3>
-		<div>
-		renderTarget -- The [page:WebGLRenderTarget renderTarget] that needs to be cleared.<br />
-		color -- If set, then the color gets cleared. <br />
-		depth -- If set, then the depth gets cleared. <br />
-		stencil -- If set, then the stencil gets cleared.
+		This method sets the correct texture to the correct slot for the WebGL shader.
+		The slot number can be found as a value of the uniform of the sampler.<br /><br />
+
+		Note: This method replaces the older [method:null setTexture] method.
 		</div>
+
+		<h3>[method:null setTextureCube]( [page:CubeTexture cubeTexture], [page:Number slot] )</h3>
 		<div>
-		This method clears a rendertarget. To do this, it activates the rendertarget.
+		texture -- The [page:CubeTexture cubeTexture] that needs to be set.<br />
+		slot -- The number indicating which slot should be used by the texture.<br /><br />
+
+		This method sets the correct texture to the correct slot for the WebGL shader.
+		The slot number can be found as a value of the uniform of the sampler.
 		</div>
 
+		<h3>[method:null setViewport]( [page:Integer x], [page:Integer y], [page:Integer width], [page:Integer height] )</h3>
+		<div>Sets the viewport to render from (x, y) to (x + width, y + height).</div>
+
 		<h2>Source</h2>
 
 		[link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js]

+ 118 - 0
docs/api/textures/DepthTexture.html

@@ -0,0 +1,118 @@
+<!DOCTYPE html>
+<html lang="en">
+	<head>
+		<meta charset="utf-8" />
+		<base href="../../" />
+		<script src="list.js"></script>
+		<script src="page.js"></script>
+		<link type="text/css" rel="stylesheet" href="page.css" />
+	</head>
+	<body>
+		[page:Texture] &rarr;
+
+		<h1>[name]</h1>
+
+		<div class="desc">
+		Creates a texture for use as a Depth Texture. Require support for the
+    <a href="https://www.khronos.org/registry/webgl/extensions/WEBGL_depth_texture/">WEBGL_depth_texture</a>
+    extension. According to <a href="https://webglstats.com/">WebGLStats</a>, as of February 2016 around 85%
+    of WebGL enabled devices support this.
+    <br /><br />
+
+			</div>
+
+    <h2>Example</h2>
+
+    [example:webgl_depth_texture depth / texture]
+
+		<h2>Constructor</h2>
+		<h3>[name]( [page:Number width], [page:Number height], [page:Constant type], [page:Constant wrapS], [page:Constant wrapT], [page:Constant magFilter], [page:Constant minFilter], [page:Number anisotropy], [page:Constant format] )</h3>
+
+    <div>
+		[page:Number width] -- width of the texture.<br />
+
+		[page:Number height] -- height of the texture.<br />
+
+    [page:Constant type] -- Default is [page:Textures THREE.UnsignedShortType].
+     See [page:Textures type constants] for other choices.<br />
+
+    [page:Constant mapping] --
+    See [page:Textures type constants] for details.<br />
+
+    [page:Constant wrapS] -- The default is [page:Textures THREE.ClampToEdgeWrapping].
+		See [page:Textures wrap mode constants] for other choices.<br />
+
+		[page:Constant wrapT] -- The default is [page:Textures THREE.ClampToEdgeWrapping].
+		See [page:Textures wrap mode constants] for other choices.<br />
+
+		[page:Constant magFilter] -- How the texture is sampled when a texel covers more than one pixel.
+		The default is [page:Textures THREE.NearestFilter]. See [page:Textures magnification filter constants] for other choices.<br />
+
+		[page:Constant minFilter] -- How the texture is sampled when a texel covers less than one pixel.
+		 The default is [page:Textures THREE.NearestFilter]. See [page:Textures minification filter constants] for other choices.<br />
+
+     [page:Number anisotropy] -- The number of samples taken along the axis through the pixel that has the highest density of texels.
+     By default, this value is 1. A higher value gives a less blurry result than a basic mipmap, at the cost of more texture samples being used.
+     Use [page:WebGLrenderer.getMaxAnisotropy renderer.getMaxAnisotropy]() to find the maximum valid anisotropy value for the GPU; this value is usually a power of 2.<br />
+
+    [page:Constant format] -- must be either [page:Textures DepthFormat] (default) or [page:Textures DepthStencilFormat].
+     See [page:Textures format constants] for details.<br />
+
+		</div>
+
+
+		<h2>Properties</h2>
+
+		<div>
+    See the base [page:Texture Texture] class for common properties
+    - the following are also part of the texture class, but have different defaults here.
+    </div>
+
+		<h3>[page:Texture.format .format]</h3>
+		<div>
+    Either [page:Textures DepthFormat] (default) or [page:Textures DepthStencilFormat].
+    See [page:Textures format constants] for details.<br />
+		</div>
+
+    <h3>[page:Texture.type .type]</h3>
+    <div>
+    Default is [page:Textures THREE.UnsignedShortType].
+    See [page:Textures format constants] for details.<br />
+    </div>
+
+    <h3>[page:Texture.magFilter .magFilter]</h3>
+    <div>
+      How the texture is sampled when a texel covers more than one pixel.
+  		The default is [page:Textures THREE.NearestFilter].
+      See [page:Textures magnification filter constants] for other choices.
+    </div>
+
+    <h3>[page:Texture.minFilter .minFilter]</h3>
+    <div>
+    How the texture is sampled when a texel covers less than one pixel.
+  	The default is [page:Textures THREE.NearestFilter].
+    See [page:Textures magnification filter constants] for other choices.
+    </div>
+
+    <h3>[page:Texture.flipY .flipY]</h3>
+    <div>
+    Depth textures do not need to be flipped so this is *false* by default.
+    </div>
+
+    <h3>[page:Texture.generateMipmaps .generateMipmaps]</h3>
+    <div>
+    Depth textures do not use mipmaps.
+    </div>
+
+		<h2>Methods</h2>
+
+    <div>
+    See the base [page:Texture Texture] class for common methods.
+    </div>
+
+
+		<h2>Source</h2>
+
+		[link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js]
+	</body>
+</html>

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

@@ -55,11 +55,6 @@
 		as long as video is playing - the [page:VideoTexture VideoTexture] class handles this automatically.
 		</div>
 
-		<h3>[property:string sourceFile]</h3>
-		<div>
-		This property is currently unused.
-		</div>
-
 		<h3>[property:array mipmaps]</h3>
 		<div>
 		Array of user-specified mipmaps (optional).

+ 24 - 4
docs/list.js

@@ -14,14 +14,15 @@ var list = {
 			[ "DrawModes", "api/constants/DrawModes" ],
 			[ "Materials", "api/constants/Materials" ],
 			[ "Textures", "api/constants/Textures" ],
-			[ "WebGLRenderer", "api/constants/WebGLRenderer" ]
+			[ "Renderer", "api/constants/Renderer" ]
 		],
 
 		"Cameras": [
 			[ "Camera", "api/cameras/Camera" ],
 			[ "CubeCamera", "api/cameras/CubeCamera" ],
 			[ "OrthographicCamera", "api/cameras/OrthographicCamera" ],
-			[ "PerspectiveCamera", "api/cameras/PerspectiveCamera" ]
+			[ "PerspectiveCamera", "api/cameras/PerspectiveCamera" ],
+			[ "StereoCamera", "api/cameras/StereoCamera" ]
 		],
 
 		"Core": [
@@ -48,6 +49,7 @@ var list = {
 			[ "CylinderGeometry", "api/geometries/CylinderGeometry" ],
 			[ "DodecahedronBufferGeometry", "api/geometries/DodecahedronBufferGeometry" ],
 			[ "DodecahedronGeometry", "api/geometries/DodecahedronGeometry" ],
+			[ "EdgesGeometry", "api/geometries/EdgesGeometry" ],
 			[ "ExtrudeGeometry", "api/geometries/ExtrudeGeometry" ],
 			[ "IcosahedronBufferGeometry", "api/geometries/IcosahedronBufferGeometry" ],
 			[ "IcosahedronGeometry", "api/geometries/IcosahedronGeometry" ],
@@ -75,7 +77,8 @@ var list = {
 			[ "TorusKnotBufferGeometry", "api/geometries/TorusKnotBufferGeometry" ],
 			[ "TorusKnotGeometry", "api/geometries/TorusKnotGeometry" ],
 			[ "TubeGeometry", "api/geometries/TubeGeometry" ],
-			[ "TubeBufferGeometry", "api/geometries/TubeBufferGeometry" ]
+			[ "TubeBufferGeometry", "api/geometries/TubeBufferGeometry" ],
+			[ "WireframeGeometry", "api/geometries/WireframeGeometry" ]
 		],
 
 		"Lights": [
@@ -123,10 +126,12 @@ var list = {
 			[ "MeshLambertMaterial", "api/materials/MeshLambertMaterial" ],
 			[ "MeshNormalMaterial", "api/materials/MeshNormalMaterial" ],
 			[ "MeshPhongMaterial", "api/materials/MeshPhongMaterial" ],
+			[ "MeshPhysicalMaterial", "api/materials/MeshPhysicalMaterial" ],
 			[ "MeshStandardMaterial", "api/materials/MeshStandardMaterial" ],
 			[ "PointsMaterial", "api/materials/PointsMaterial" ],
 			[ "RawShaderMaterial", "api/materials/RawShaderMaterial" ],
 			[ "ShaderMaterial", "api/materials/ShaderMaterial" ],
+			[ "ShadowMaterial", "api/materials/ShadowMaterial" ],
 			[ "SpriteMaterial", "api/materials/SpriteMaterial" ]
 		],
 
@@ -136,6 +141,7 @@ var list = {
 			[ "Color", "api/math/Color" ],
 			[ "Euler", "api/math/Euler" ],
 			[ "Frustum", "api/math/Frustum" ],
+			[ "Interpolant", "api/math/Interpolant" ],
 			[ "Line3", "api/math/Line3" ],
 			[ "Math", "api/math/Math" ],
 			[ "Matrix3", "api/math/Matrix3" ],
@@ -152,8 +158,17 @@ var list = {
 			[ "Vector4", "api/math/Vector4" ]
 		],
 
+		"Math / Interpolants": [
+			[ "CubicInterpolant", "api/math/interpolants/CubicInterpolant" ],
+			[ "DiscreteInterpolant", "api/math/interpolants/DiscreteInterpolant" ],
+			[ "LinearInterpolant", "api/math/interpolants/LinearInterpolant" ],
+			[ "QuaternionLinearInterpolant", "api/math/interpolants/QuaternionLinearInterpolant" ]
+		],
+
+
 		"Objects": [
 			[ "Bone", "api/objects/Bone" ],
+			[ "Group", "api/objects/Group" ],
 			[ "LensFlare", "api/objects/LensFlare" ],
 			[ "Line", "api/objects/Line" ],
 			[ "LineSegments", "api/objects/LineSegments" ],
@@ -201,6 +216,7 @@ var list = {
 			[ "CompressedTexture", "api/textures/CompressedTexture" ],
 			[ "CubeTexture", "api/textures/CubeTexture" ],
 			[ "DataTexture", "api/textures/DataTexture" ],
+			[ "DepthTexture", "api/textures/DepthTexture" ],
 			[ "Texture", "api/textures/Texture" ],
 			[ "VideoTexture", "api/textures/VideoTexture" ]
 		],
@@ -212,7 +228,9 @@ var list = {
 		],
 
 		"Extras": [
-			[ "SceneUtils", "api/extras/SceneUtils" ]
+			[ "CurveUtils", "api/extras/CurveUtils" ],
+			[ "SceneUtils", "api/extras/SceneUtils" ],
+			[ "ShapeUtils", "api/extras/ShapeUtils" ]
 		],
 
 		"Extras / Collada Animation": [
@@ -224,6 +242,7 @@ var list = {
 		"Extras / Core": [
 			[ "Curve", "api/extras/core/Curve" ],
 			[ "CurvePath", "api/extras/core/CurvePath" ],
+			[ "Font", "api/extras/core/Font" ],
 			[ "Path", "api/extras/core/Path" ],
 			[ "Shape", "api/extras/core/Shape" ]
 		],
@@ -254,6 +273,7 @@ var list = {
 			[ "GridHelper", "api/extras/helpers/GridHelper" ],
 			[ "HemisphereLightHelper", "api/extras/helpers/HemisphereLightHelper" ],
 			[ "PointLightHelper", "api/extras/helpers/PointLightHelper" ],
+			[ "SkeletonHelper", "api/extras/helpers/SkeletonHelper" ],
 			[ "SpotLightHelper", "api/extras/helpers/SpotLightHelper" ],
 			[ "VertexNormalsHelper", "api/extras/helpers/VertexNormalsHelper" ]
 		],

+ 7 - 1
examples/js/animation/MMDPhysics.js

@@ -26,7 +26,13 @@ THREE.MMDPhysics = function ( mesh, params ) {
 	this.mesh = mesh;
 	this.helper = new THREE.MMDPhysics.ResourceHelper();
 
-	this.unitStep = ( params.unitStep !== undefined ) ? params.unitStep : 1 / 60;
+	/*
+	 * I don't know why but 1/60 unitStep easily breaks models
+	 * so I set it 1/65 so far.
+	 * Don't set too small unitStep because
+	 * the smaller unitStep can make the performance worse.
+	 */
+	this.unitStep = ( params.unitStep !== undefined ) ? params.unitStep : 1 / 65;
 	this.maxStepNum = ( params.maxStepNum !== undefined ) ? params.maxStepNum : 3;
 
 	this.world = null;

+ 140 - 27
examples/js/effects/OutlineEffect.js

@@ -21,7 +21,6 @@
  * };
  *
  * TODO
- *  - shared material
  *  - support shader material without objectNormal in its vertexShader
  */
 
@@ -76,9 +75,24 @@ THREE.OutlineEffect = function ( renderer, parameters ) {
 	var defaultAlpha = parameters.defaultAlpha !== undefined ? parameters.defaultAlpha : 1.0;
 	var defaultKeepAlive = parameters.defaultKeepAlive !== undefined ? parameters.defaultKeepAlive : false;
 
+	// object.material.uuid -> outlineMaterial
+	// (no mapping from children of MultiMaterial)
+	// save at the outline material creation and release
+	// if it's unused removeThresholdCount frames
+	// unless keepAlive is true.
 	var cache = {};
+
 	var removeThresholdCount = 60;
 
+	// outlineMaterial.uuid (or object.uuid for invisibleMaterial) -> originalMaterial
+	// including children of MultiMaterial.
+	// save before render and release after render.
+	var originalMaterials = {};
+
+	// object.uuid -> originalOnBeforeRender
+	// save before render and release after render.
+	var originalOnBeforeRenders = {};
+
 	//this.cache = cache;  // for debug
 
 	var invisibleMaterial = new THREE.ShaderMaterial( { visible: false } );
@@ -179,10 +193,7 @@ THREE.OutlineEffect = function ( renderer, parameters ) {
 
 		}
 
-		var uniforms = THREE.UniformsUtils.merge( [
-			originalUniforms,
-			uniformsChunk
-		] );
+		var uniforms = Object.assign( {}, originalUniforms, uniformsChunk );
 
 		var vertexShader = originalVertexShader
 					// put vertexShaderChunk right before "void main() {...}"
@@ -196,7 +207,7 @@ THREE.OutlineEffect = function ( renderer, parameters ) {
 					.replace( /#include\s+<[\w_]*light[\w_]*>/g, '' );
 
 		var material = new THREE.ShaderMaterial( {
-			uniforms: THREE.UniformsUtils.clone( uniforms ),
+			uniforms: uniforms,
 			vertexShader: vertexShader,
 			fragmentShader: fragmentShader,
 			side: THREE.BackSide,
@@ -234,7 +245,7 @@ THREE.OutlineEffect = function ( renderer, parameters ) {
 		if ( data === undefined ) {
 
 			data = {
-				material: object.material.type === 'MultiMaterial' ? createMultiMaterial( object.material ) : createMaterial( object.material ),
+				material: object.material.isMultiMaterial === true ? createMultiMaterial( object.material ) : createMaterial( object.material ),
 				used: true,
 				keepAlive: defaultKeepAlive,
 				count: 0
@@ -247,7 +258,22 @@ THREE.OutlineEffect = function ( renderer, parameters ) {
 		var outlineMaterial = data.material;
 		data.used = true;
 
-		if ( outlineMaterial.type === 'MultiMaterial' ) {
+		var uuid= outlineMaterial !== invisibleMaterial ? outlineMaterial.uuid : object.uuid;
+		originalMaterials[ uuid ] = object.material;
+
+		if ( object.material.isMultiMaterial === true ) {
+
+			for ( var i = 0, il = object.material.materials.length; i < il; i ++ ) {
+
+				// originalMaterial of leaf material of MultiMaterial is used only for
+				// updating outlineMaterial. so need not to save for invisibleMaterial.
+				if ( outlineMaterial.materials[ i ] !== invisibleMaterial ) {
+
+					originalMaterials[ outlineMaterial.materials[ i ].uuid ] = object.material.materials[ i ];
+
+				}
+
+			}
 
 			updateOutlineMultiMaterial( outlineMaterial, object.material );
 
@@ -257,9 +283,62 @@ THREE.OutlineEffect = function ( renderer, parameters ) {
 
 		}
 
-		object.userData.originalMaterial = object.material;
 		object.material = outlineMaterial;
 
+		originalOnBeforeRenders[ object.uuid ] = object.onBeforeRender;
+		object.onBeforeRender = onBeforeRender;
+
+	}
+
+	function restoreOriginalMaterial( object ) {
+
+		if ( object.material === undefined ) return;
+
+		var originalMaterial = originalMaterials[ object.material.uuid ]
+
+		if ( originalMaterial === undefined ) {
+
+			originalMaterial = originalMaterials[ object.uuid ]
+
+			if ( originalMaterial === undefined ) return;
+
+		}
+
+		object.material = originalMaterial;
+		object.onBeforeRender = originalOnBeforeRenders[ object.uuid ];
+
+	}
+
+	function onBeforeRender( renderer, scene, camera, geometry, material, group ) {
+
+		// check some things before updating just in case
+
+		if ( material === invisibleMaterial ) return;
+
+		if ( material.isMultiMaterial === true ) return;
+
+		var originalMaterial = originalMaterials[ material.uuid ];
+
+		if ( originalMaterial === undefined ) return;
+
+		updateUniforms( material, originalMaterial );
+
+	}
+
+	function updateUniforms( material, originalMaterial ) {
+
+		var outlineParameters = originalMaterial.outlineParameters;
+
+		material.uniforms.outlineAlpha.value = originalMaterial.opacity;
+
+		if ( outlineParameters !== undefined ) {
+
+			if ( outlineParameters.thickness !== undefined ) material.uniforms.outlineThickness.value = outlineParameters.thickness;
+			if ( outlineParameters.color !== undefined ) material.uniforms.outlineColor.value.copy( outlineParameters.color );
+			if ( outlineParameters.alpha !== undefined ) material.uniforms.outlineAlpha.value = outlineParameters.alpha;
+
+		}
+
 	}
 
 	function updateOutlineMaterial( material, originalMaterial ) {
@@ -272,35 +351,59 @@ THREE.OutlineEffect = function ( renderer, parameters ) {
 		material.morphTargets = originalMaterial.morphTargets;
 		material.morphNormals = originalMaterial.morphNormals;
 		material.fog = originalMaterial.fog;
-		material.visible = originalMaterial.visible;
-		material.uniforms.outlineAlpha.value = originalMaterial.opacity;
 
 		if ( outlineParameters !== undefined ) {
 
-			if ( outlineParameters.thickness !== undefined ) material.uniforms.outlineThickness.value = outlineParameters.thickness;
-			if ( outlineParameters.color !== undefined ) material.uniforms.outlineColor.value.copy( outlineParameters.color );
-			if ( outlineParameters.alpha !== undefined ) material.uniforms.outlineAlpha.value = outlineParameters.alpha;
-			if ( outlineParameters.visible !== undefined ) material.visible = outlineParameters.visible;
+			if ( originalMaterial.visible === false ) {
+
+				material.visible = false;
+
+			} else {
+
+				material.visible = ( outlineParameters.visible !== undefined ) ? outlineParameters.visible : true;
+
+			}
+
+			material.transparent = ( outlineParameters.alpha !== undefined && outlineParameters.alpha < 1.0 ) ? true : originalMaterial.transparent;
+
 			// cache[ originalMaterial.uuid ] is undefined if originalMaterial is in materials of MultiMaterial
 			if ( outlineParameters.keepAlive !== undefined && cache[ originalMaterial.uuid ] !== undefined ) cache[ originalMaterial.uuid ].keepAlive = outlineParameters.keepAlive;
 
+		} else {
+
+			material.transparent = originalMaterial.transparent;
+			material.visible = originalMaterial.visible;
+
 		}
 
-		material.transparent = ( material.uniforms.outlineAlpha.value < 1.0 ) ? true : false;
+		if ( originalMaterial.wireframe === true || originalMaterial.depthTest === false ) material.visible = false;
 
 	}
 
 	function updateOutlineMultiMaterial( material, originalMaterial ) {
 
-		var outlineParameters = originalMaterial.outlineParameters;
+		if ( material === invisibleMaterial ) return;
 
-		material.visible = originalMaterial.visible;
+		var outlineParameters = originalMaterial.outlineParameters;
 
 		if ( outlineParameters !== undefined ) {
 
-			if ( outlineParameters.visible !== undefined ) material.visible = outlineParameters.visible;
+			if ( originalMaterial.visible === false ) {
+
+				material.visible = false;
+
+			} else {
+
+				material.visible = ( outlineParameters.visible !== undefined ) ? outlineParameters.visible : true;
+
+			}
+
 			if ( outlineParameters.keepAlive !== undefined ) cache[ originalMaterial.uuid ].keepAlive = outlineParameters.keepAlive;
 
+		} else {
+
+			material.visible = originalMaterial.visible;
+
 		}
 
 		for ( var i = 0, il = material.materials.length; i < il; i ++ ) {
@@ -311,20 +414,30 @@ THREE.OutlineEffect = function ( renderer, parameters ) {
 
 	}
 
-	function restoreOriginalMaterial( object ) {
+	function cleanupCache() {
+
+		var keys;
 
-		if ( object.userData.originalMaterial !== undefined ) {
+		// clear originialMaterials
+		keys = Object.keys( originalMaterials );
+
+		for ( var i = 0, il = keys.length; i < il; i ++ ) {
 
-			object.material = object.userData.originalMaterial;
-			object.userData.originalMaterial = undefined;
+			originalMaterials[ keys[ i ] ] = undefined;
 
 		}
 
-	}
+		// clear originalOnBeforeRenders
+		keys = Object.keys( originalOnBeforeRenders );
+
+		for ( var i = 0, il = keys.length; i < il; i ++ ) {
 
-	function removeUnusedOutlineMaterialFromCache() {
+			originalOnBeforeRenders[ keys[ i ] ] = undefined;
+
+		}
 
-		var keys = Object.keys( cache );
+		// remove unused outlineMaterial from cache
+		keys = Object.keys( cache );
 
 		for ( var i = 0, il = keys.length; i < il; i ++ ) {
 
@@ -382,7 +495,7 @@ THREE.OutlineEffect = function ( renderer, parameters ) {
 
 		scene.traverse( restoreOriginalMaterial );
 
-		removeUnusedOutlineMaterialFromCache();
+		cleanupCache();
 
 		scene.autoUpdate = currentSceneAutoUpdate;
 		scene.background = currentSceneBackground;

+ 1 - 1
examples/js/loaders/GLTFLoader.js

@@ -1080,7 +1080,7 @@ GLTFParser.prototype.loadMaterials = function() {
 
 									}
 
-									if ( value ) {
+									if ( value !== undefined ) {
 
 										uvalue = value;
 

+ 418 - 227
examples/js/loaders/MMDLoader.js

@@ -41,18 +41,31 @@ THREE.MMDLoader = function ( manager ) {
 
 	THREE.Loader.call( this );
 	this.manager = ( manager !== undefined ) ? manager : THREE.DefaultLoadingManager;
-	this.defaultTexturePath = './models/default/';
 
 };
 
 THREE.MMDLoader.prototype = Object.create( THREE.Loader.prototype );
 THREE.MMDLoader.prototype.constructor = THREE.MMDLoader;
 
-THREE.MMDLoader.prototype.setDefaultTexturePath = function ( path ) {
-
-	this.defaultTexturePath = path;
-
-};
+/*
+ * base64 encoded defalut toon textures toon00.bmp - toon10.bmp
+ * Users don't need to prepare default texture files.
+ *
+ * This idea is from http://www20.atpages.jp/katwat/three.js_r58/examples/mytest37/mmd.three.js
+ */
+THREE.MMDLoader.prototype.defaultToonTextures = [
+	'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAL0lEQVRYR+3QQREAAAzCsOFfNJPBJ1XQS9r2hsUAAQIECBAgQIAAAQIECBAgsBZ4MUx/ofm2I/kAAAAASUVORK5CYII=',
+	'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAN0lEQVRYR+3WQREAMBACsZ5/bWiiMvgEBTt5cW37hjsBBAgQIECAwFwgyfYPCCBAgAABAgTWAh8aBHZBl14e8wAAAABJRU5ErkJggg==',
+	'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAOUlEQVRYR+3WMREAMAwDsYY/yoDI7MLwIiP40+RJklfcCCBAgAABAgTqArfb/QMCCBAgQIAAgbbAB3z/e0F3js2cAAAAAElFTkSuQmCC',
+	'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAN0lEQVRYR+3WQREAMBACsZ5/B5ilMvgEBTt5cW37hjsBBAgQIECAwFwgyfYPCCBAgAABAgTWAh81dWyx0gFwKAAAAABJRU5ErkJggg==',
+	'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAOklEQVRYR+3WoREAMAwDsWb/UQtCy9wxTOQJ/oQ8SXKKGwEECBAgQIBAXeDt7f4BAQQIECBAgEBb4AOz8Hzx7WLY4wAAAABJRU5ErkJggg==',
+	'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAABPUlEQVRYR+1XwW7CMAy1+f9fZOMysSEOEweEOPRNdm3HbdOyIhAcklPrOs/PLy9RygBALxzcCDQFmgJNgaZAU6Ap0BR4PwX8gsRMVLssMRH5HcpzJEaWL7EVg9F1IHRlyqQohgVr4FGUlUcMJSjcUlDw0zvjeun70cLWmneoyf7NgBTQSniBTQQSuJAZsOnnaczjIMb5hCiuHKxokCrJfVnrctyZL0PkJAJe1HMil4nxeyi3Ypfn1kX51jpPvo/JeCNC4PhVdHdJw2XjBR8brF8PEIhNVn12AgP7uHsTBguBn53MUZCqv7Lp07Pn5k1Ro+uWmUNn7D+M57rtk7aG0Vo73xyF/fbFf0bPJjDXngnGocDTdFhygZjwUQrMNrDcmZlQT50VJ/g/UwNyHpu778+yW+/ksOz/BFo54P4AsUXMfRq7XWsAAAAASUVORK5CYII=',
+	'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAACMElEQVRYR+2Xv4pTQRTGf2dubhLdICiii2KnYKHVolhauKWPoGAnNr6BD6CvIVaihYuI2i1ia0BY0MZGRHQXjZj/mSPnnskfNWiWZUlzJ5k7M2cm833nO5Mziej2DWWJRUoCpQKlAntSQCqgw39/iUWAGmh37jrRnVsKlgpiqmkoGVABA7E57fvY+pJDdgKqF6HzFCSADkDq+F6AHABtQ+UMVE5D7zXod7fFNhTEckTbj5XQgHzNN+5tQvc5NG7C6BNkp6D3EmpXHDR+dQAjFLchW3VS9rlw3JBh+B7ys5Cf9z0GW1C/7P32AyBAOAz1q4jGliIH3YPuBnSfQX4OGreTIgEYQb/pBDtPnEQ4CivXYPAWBk13oHrB54yA9QuSn2H4AcKRpEILDt0BUzj+RLR1V5EqjD66NPRBVpLcQwjHoHYJOhsQv6U4mnzmrIXJCFr4LDwm/xBUoboG9XX4cc9VKdYoSA2yk5NQLJaKDUjTBoveG3Z2TElTxwjNK4M3LEZgUdDdruvcXzKBpStgp2NPiWi3ks9ZXxIoFVi+AvHLdc9TqtjL3/aYjpPlrzOcEnK62Szhimdd7xX232zFDTgtxezOu3WNMRLjiKgjtOhHVMd1loynVHvOgjuIIJMaELEqhJAV/RCSLbWTcfPFakFgFlALTRRvx+ok6Hlp/Q+v3fmx90bMyUzaEAhmM3KvHlXTL5DxnbGf/1M8RNNACLL5MNtPxP/mypJAqcDSFfgFhpYqWUzhTEAAAAAASUVORK5CYII=',
+	'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAL0lEQVRYR+3QQREAAAzCsOFfNJPBJ1XQS9r2hsUAAQIECBAgQIAAAQIECBAgsBZ4MUx/ofm2I/kAAAAASUVORK5CYII=',
+	'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAL0lEQVRYR+3QQREAAAzCsOFfNJPBJ1XQS9r2hsUAAQIECBAgQIAAAQIECBAgsBZ4MUx/ofm2I/kAAAAASUVORK5CYII=',
+	'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAL0lEQVRYR+3QQREAAAzCsOFfNJPBJ1XQS9r2hsUAAQIECBAgQIAAAQIECBAgsBZ4MUx/ofm2I/kAAAAASUVORK5CYII=',
+	'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAL0lEQVRYR+3QQREAAAzCsOFfNJPBJ1XQS9r2hsUAAQIECBAgQIAAAQIECBAgsBZ4MUx/ofm2I/kAAAAASUVORK5CYII='
+];
 
 THREE.MMDLoader.prototype.load = function ( modelUrl, vmdUrls, callback, onProgress, onError ) {
 
@@ -224,67 +237,186 @@ THREE.MMDLoader.prototype.pourVmdIntoCamera = function ( camera, vmd, name ) {
 
 		var orderedMotions = helper.createOrderedMotionArray( vmd.cameras );
 
-		var q = new THREE.Quaternion();
-		var e = new THREE.Euler();
-		var pkeys = [];
-		var ckeys = [];
-		var ukeys = [];
-		var fkeys = [];
+		var times = [];
+		var centers = [];
+		var quaternions = [];
+		var positions = [];
+		var fovs = [];
+
+		var cInterpolations = [];
+		var qInterpolations = [];
+		var pInterpolations = [];
+		var fInterpolations = [];
+
+		var quaternion = new THREE.Quaternion();
+		var euler = new THREE.Euler();
+		var position = new THREE.Vector3();
+		var center = new THREE.Vector3();
+
+		var pushVector3 = function ( array, vec ) {
+
+			array.push( vec.x );
+			array.push( vec.y );
+			array.push( vec.z );
+
+		};
+
+		var pushQuaternion = function ( array, q ) {
+
+			array.push( q.x );
+			array.push( q.y );
+			array.push( q.z );
+			array.push( q.w );
+
+		};
+
+		var pushInterpolation = function ( array, interpolation, index ) {
+
+			array.push( interpolation[ index * 4 + 0 ] / 127 ); // x1
+			array.push( interpolation[ index * 4 + 1 ] / 127 ); // x2
+			array.push( interpolation[ index * 4 + 2 ] / 127 ); // y1
+			array.push( interpolation[ index * 4 + 3 ] / 127 ); // y2
+
+		};
+
+		var createTrack = function ( node, type, times, values, interpolations ) {
+
+			/*
+			 * optimizes here not to let KeyframeTrackPrototype optimize
+			 * because KeyframeTrackPrototype optimizes times and values but
+			 * doesn't optimize interpolations.
+			 */
+			if ( times.length > 2 ) {
+
+				times = times.slice();
+				values = values.slice();
+				interpolations = interpolations.slice();
+
+				var stride = values.length / times.length;
+				var interpolateStride = ( stride === 3 ) ? 12 : 4;  // 3: Vector3, others: Quaternion or Number
+
+				var aheadIndex = 2;
+				var index = 1;
+
+				for ( aheadIndex = 2, endIndex = times.length; aheadIndex < endIndex; aheadIndex ++ ) {
+
+					for ( var i = 0; i < stride; i ++ ) {
+
+						if ( values[ index * stride + i ] !== values[ ( index - 1 ) * stride + i ] ||
+							values[ index * stride + i ] !== values[ aheadIndex * stride + i ] ) {
+
+							index ++;
+							break;
+
+						}
+
+					}
+
+					if ( aheadIndex > index ) {
+
+						times[ index ] = times[ aheadIndex ];
+
+						for ( var i = 0; i < stride; i ++ ) {
+
+							values[ index * stride + i ] = values[ aheadIndex * stride + i ];
+
+						}
+
+						for ( var i = 0; i < interpolateStride; i ++ ) {
+
+							interpolations[ index * interpolateStride + i ] = interpolations[ aheadIndex * interpolateStride + i ];
+
+						}
+
+					}
+
+				}
+
+				times.length = index + 1;
+				values.length = ( index + 1 ) * stride;
+				interpolations.length = ( index + 1 ) * interpolateStride;
+
+			}
+
+			return new THREE.MMDLoader[ type ]( node, times, values, interpolations );
+
+		};
 
 		for ( var i = 0; i < orderedMotions.length; i++ ) {
 
 			var m = orderedMotions[ i ];
-			var t = m.frameNum / 30;
-			var p = m.position;
-			var r = m.rotation;
-			var d = m.distance;
-			var f = m.fov;
 
-			var position = new THREE.Vector3( 0, 0, -d );
-			var center = new THREE.Vector3( p[ 0 ], p[ 1 ], p[ 2 ] );
-			var up = new THREE.Vector3( 0, 1, 0 );
+			var time = m.frameNum / 30;
+			var pos = m.position;
+			var rot = m.rotation;
+			var distance = m.distance;
+			var fov = m.fov;
+			var interpolation = m.interpolation;
 
-			e.set( -r[ 0 ], -r[ 1 ], -r[ 2 ] );
-			q.setFromEuler( e );
+			position.set( 0, 0, -distance );
+			center.set( pos[ 0 ], pos[ 1 ], pos[ 2 ] );
+
+			euler.set( -rot[ 0 ], -rot[ 1 ], -rot[ 2 ] );
+			quaternion.setFromEuler( euler );
 
 			position.add( center );
-			position.applyQuaternion( q );
+			position.applyQuaternion( quaternion );
 
-			up.applyQuaternion( q );
+			/*
+			 * Note: This is a workaround not to make Animation system calculate lerp
+			 *       if the diff from the last frame is 1 frame (in 30fps).
+			 */
+			if ( times.length > 0 && time < times[ times.length - 1 ] + ( 1 / 30 ) * 1.5 ) {
 
-			helper.pushAnimationKey( pkeys, t, position, true );
-			helper.pushAnimationKey( ckeys, t, center, true );
-			helper.pushAnimationKey( ukeys, t, up, true );
-			helper.pushAnimationKey( fkeys, t, f, true );
+				times[ times.length - 1 ] = time - 1e-13;
 
-		}
+			}
 
-		helper.insertAnimationKeyAtTimeZero( pkeys, new THREE.Vector3( 0, 0, 0 ) );
-		helper.insertAnimationKeyAtTimeZero( ckeys, new THREE.Vector3( 0, 0, 0 ) );
-		helper.insertAnimationKeyAtTimeZero( ukeys, new THREE.Vector3( 0, 0, 0 ) );
-		helper.insertAnimationKeyAtTimeZero( fkeys, 45 );
+			times.push( time );
 
-		helper.insertStartAnimationKey( pkeys );
-		helper.insertStartAnimationKey( ckeys );
-		helper.insertStartAnimationKey( ukeys );
-		helper.insertStartAnimationKey( fkeys );
+			pushVector3( centers, center );
+			pushQuaternion( quaternions, quaternion );
+			pushVector3( positions, position );
 
-		var tracks = [];
+			fovs.push( fov );
+
+			for ( var j = 0; j < 3; j ++ ) {
 
-		tracks.push( helper.generateTrackFromAnimationKeys( pkeys, 'VectorKeyframeTrackEx', '.position' ) );
-		tracks.push( helper.generateTrackFromAnimationKeys( ckeys, 'VectorKeyframeTrackEx', '.center' ) );
-		tracks.push( helper.generateTrackFromAnimationKeys( ukeys, 'VectorKeyframeTrackEx', '.up' ) );
-		tracks.push( helper.generateTrackFromAnimationKeys( fkeys, 'NumberKeyframeTrackEx', '.fov' ) );
+				pushInterpolation( cInterpolations, interpolation, j );
+
+			}
 
-		camera.center = new THREE.Vector3( 0, 0, 0 );
+			pushInterpolation( qInterpolations, interpolation, 3 );
 
-		if ( camera.animations === undefined ) {
+			// use same one parameter for x, y, z axis.
+			for ( var j = 0; j < 3; j ++ ) {
+
+				pushInterpolation( pInterpolations, interpolation, 4 );
+
+			}
 
-			camera.animations = [];
+			pushInterpolation( fInterpolations, interpolation, 5 );
 
 		}
 
-		camera.animations.push( new THREE.AnimationClip( name === undefined ? THREE.Math.generateUUID() : name, -1, tracks ) );
+		if ( times.length === 0 ) return;
+
+		var tracks = [];
+
+		tracks.push( createTrack( '.center', 'VectorKeyframeTrackEx', times, centers, cInterpolations ) );
+		tracks.push( createTrack( '.quaternion', 'QuaternionKeyframeTrackEx', times, quaternions, qInterpolations ) );
+		tracks.push( createTrack( '.position', 'VectorKeyframeTrackEx', times, positions, pInterpolations ) );
+		tracks.push( createTrack( '.fov', 'NumberKeyframeTrackEx', times, fovs, fInterpolations ) );
+
+		var clip = new THREE.AnimationClip( name === undefined ? THREE.Math.generateUUID() : name, -1, tracks );
+
+		if ( clip !== null ) {
+
+			if ( camera.center === undefined ) camera.center = new THREE.Vector3( 0, 0, 0 );
+			if ( camera.animations === undefined ) camera.animations = [];
+			camera.animations.push( clip );
+
+		}
 
 	};
 
@@ -364,7 +496,6 @@ THREE.MMDLoader.prototype.parseModel = function ( buffer, modelExtension ) {
 
 THREE.MMDLoader.prototype.parsePmd = function ( buffer ) {
 
-	var scope = this;
 	var pmd = {};
 	var dv = new THREE.MMDLoader.DataView( buffer );
 	var helper = new THREE.MMDLoader.DataCreationHelper();
@@ -859,7 +990,6 @@ THREE.MMDLoader.prototype.parsePmd = function ( buffer ) {
 
 THREE.MMDLoader.prototype.parsePmx = function ( buffer ) {
 
-	var scope = this;
 	var pmx = {};
 	var dv = new THREE.MMDLoader.DataView( buffer );
 	var helper = new THREE.MMDLoader.DataCreationHelper();
@@ -1408,7 +1538,6 @@ THREE.MMDLoader.prototype.parsePmx = function ( buffer ) {
 
 THREE.MMDLoader.prototype.parseVmd = function ( buffer ) {
 
-	var scope = this;
 	var vmd = {};
 	var dv = new THREE.MMDLoader.DataView( buffer );
 	var helper = new THREE.MMDLoader.DataCreationHelper();
@@ -1441,7 +1570,6 @@ THREE.MMDLoader.prototype.parseVmd = function ( buffer ) {
 			p.position = dv.getFloat32Array( 3 );
 			p.rotation = dv.getFloat32Array( 4 );
 			p.interpolation = dv.getUint8Array( 64 );
-
 			return p;
 
 		};
@@ -1924,11 +2052,18 @@ THREE.MMDLoader.prototype.createMesh = function ( model, texturePath, onProgress
 			param.isLocal = grant.isLocal;
 			param.affectRotation = grant.affectRotation;
 			param.affectPosition = grant.affectPosition;
+			param.transformationClass = b.transformationClass;
 
 			grants.push( param );
 
 		}
 
+		grants.sort( function ( a, b ) {
+
+			return a.transformationClass - b.transformationClass;
+
+		} );
+
 		geometry.grants = grants;
 
 	};
@@ -2075,8 +2210,26 @@ THREE.MMDLoader.prototype.createMesh = function ( model, texturePath, onProgress
 
 			}
 
-			var directoryPath = ( params.defaultTexturePath === true ) ? scope.defaultTexturePath : texturePath;
-			var fullPath = directoryPath + filePath;
+			var fullPath;
+
+			if ( params.defaultTexturePath === true ) {
+
+				try {
+
+					fullPath = scope.defaultToonTextures[ parseInt( filePath.match( 'toon([0-9]{2})\.bmp$' )[ 1 ] ) ];
+
+				} catch ( e ) {
+
+					console.warn( 'THREE.MMDLoader: ' + filePath + ' seems like not right default texture path. Using toon00.bmp instead.' )
+					fullPath = scope.defaultToonTextures[ 0 ];
+
+				}
+
+			} else {
+
+				fullPath = texturePath + filePath;
+
+			}
 
 			var loader = THREE.Loader.Handlers.get( fullPath );
 
@@ -2685,8 +2838,6 @@ THREE.MMDLoader.prototype.createMesh = function ( model, texturePath, onProgress
 
 THREE.MMDLoader.prototype.createAnimation = function ( mesh, vmd, name ) {
 
-	var scope = this;
-
 	var helper = new THREE.MMDLoader.DataCreationHelper();
 
 	var initMotionAnimations = function () {
@@ -2700,104 +2851,107 @@ THREE.MMDLoader.prototype.createAnimation = function ( mesh, vmd, name ) {
 		var bones = mesh.geometry.bones;
 		var orderedMotions = helper.createOrderedMotionArrays( bones, vmd.motions, 'boneName' );
 
-		var animation = {
-			name: name === undefined ? THREE.Math.generateUUID() : name,
-			fps: 30,
-			hierarchy: []
+		var tracks = [];
+
+		var pushInterpolation = function ( array, interpolation, index ) {
+
+			array.push( interpolation[ index + 0 ] / 127 );  // x1
+			array.push( interpolation[ index + 8 ] / 127 );  // x2
+			array.push( interpolation[ index + 4 ] / 127 );  // y1
+			array.push( interpolation[ index + 12 ] / 127 ); // y2
+
 		};
 
 		for ( var i = 0; i < orderedMotions.length; i++ ) {
 
-			animation.hierarchy.push(
-				{
-					parent: bones[ i ].parent,
-					keys: []
-				}
-			);
+			var times = [];
+			var positions = [];
+			var rotations = [];
+			var pInterpolations = [];
+			var rInterpolations = [];
 
-			var array = orderedMotions[ i ];
-			var keys = animation.hierarchy[ i ].keys;
 			var bone = bones[ i ];
+			var array = orderedMotions[ i ];
 
 			for ( var j = 0; j < array.length; j++ ) {
 
-				var t = array[ j ].frameNum / 30;
-				var p = array[ j ].position;
-				var r = array[ j ].rotation;
+				var time = array[ j ].frameNum / 30;
+				var pos = array[ j ].position;
+				var rot = array[ j ].rotation;
+				var interpolation = array[ j ].interpolation;
 
-				helper.pushBoneAnimationKey( keys, t, bone, p, r );
+				times.push( time );
 
-			}
+				for ( var k = 0; k < 3; k ++ ) {
 
-			helper.insertBoneAnimationKeyAtTimeZero( keys, bone );
-			helper.insertStartBoneAnimationKey( keys );
+					positions.push( bone.pos[ k ] + pos[ k ] );
 
-		}
+				}
 
-		var clip = THREE.AnimationClip.parseAnimation( animation, mesh.geometry.bones );
+				for ( var k = 0; k < 4; k ++ ) {
 
-		if ( clip !== null ) {
+					rotations.push( rot[ k ] );
 
-			if ( mesh.geometry.animations === undefined ) {
+				}
 
-				mesh.geometry.animations = [];
+				for ( var k = 0; k < 3; k ++ ) {
 
-			}
+					pushInterpolation( pInterpolations, interpolation, k );
 
-			mesh.geometry.animations.push( clip );
+				}
 
-		}
+				pushInterpolation( rInterpolations, interpolation, 3 );
 
-	};
+			}
 
-	var initMorphAnimations = function () {
+			if ( times.length === 0 ) continue;
 
-		if ( vmd.metadata.morphCount === 0 ) {
+			var boneName = '.bones[' + bone.name + ']';
 
-			return;
+			tracks.push( new THREE.MMDLoader.VectorKeyframeTrackEx( boneName + '.position', times, positions, pInterpolations ) );
+			tracks.push( new THREE.MMDLoader.QuaternionKeyframeTrackEx( boneName + '.quaternion', times, rotations, rInterpolations ) );
 
 		}
 
-		var orderedMorphs = helper.createOrderedMotionArrays( mesh.geometry.morphTargets, vmd.morphs, 'morphName' );
-
-		var morphAnimation = {
-			fps: 30,
-			hierarchy: []
-		};
+		var clip = new THREE.AnimationClip( name === undefined ? THREE.Math.generateUUID() : name, -1, tracks );
 
-		for ( var i = 0; i < orderedMorphs.length; i++ ) {
+		if ( clip !== null ) {
 
-			morphAnimation.hierarchy.push( { keys: [] } );
+			if ( mesh.geometry.animations === undefined ) mesh.geometry.animations = [];
+			mesh.geometry.animations.push( clip );
 
-			var array = orderedMorphs[ i ];
-			var keys = morphAnimation.hierarchy[ i ].keys;
+		}
 
-			for ( var j = 0; j < array.length; j++ ) {
+	};
 
-				var t = array[ j ].frameNum / 30;
-				var w = array[ j ].weight;
+	var initMorphAnimations = function () {
 
-				helper.pushAnimationKey( keys, t, w );
+		if ( vmd.metadata.morphCount === 0 ) {
 
-			}
+			return;
 
 		}
 
-		// TODO: should we use THREE.AnimationClip.CreateFromMorphTargetSequence() instead?
+		var orderedMorphs = helper.createOrderedMotionArrays( mesh.geometry.morphTargets, vmd.morphs, 'morphName' );
 
 		var tracks = [];
 
 		for ( var i = 0; i < orderedMorphs.length; i++ ) {
 
-			var keys = morphAnimation.hierarchy[ i ].keys;
+			var times = [];
+			var values = [];
+			var array = orderedMorphs[ i ];
 
-			if ( keys.length === 0 ) {
+			for ( var j = 0; j < array.length; j++ ) {
 
-				continue;
+				times.push( array[ j ].frameNum / 30 );
+				values.push( array[ j ].weight );
 
 			}
 
-			tracks.push( helper.generateTrackFromAnimationKeys( keys, 'NumberKeyframeTrackEx', '.morphTargetInfluences[' + i + ']' ) );
+			if ( times.length === 0 ) continue;
+
+			tracks.push( new THREE.NumberKeyframeTrack( '.morphTargetInfluences[' + i + ']', times, values ) );
 
 		}
 
@@ -2805,12 +2959,7 @@ THREE.MMDLoader.prototype.createAnimation = function ( mesh, vmd, name ) {
 
 		if ( clip !== null ) {
 
-			if ( mesh.geometry.animations === undefined ) {
-
-				mesh.geometry.animations = [];
-
-			}
-
+			if ( mesh.geometry.animations === undefined ) mesh.geometry.animations = [];
 			mesh.geometry.animations.push( clip );
 
 		}
@@ -2914,6 +3063,7 @@ THREE.MMDLoader.prototype.leftToRightVmd = function ( vmd ) {
 
 	for ( var i = 0; i < vmd.metadata.cameraCount; i++ ) {
 
+		helper.leftToRightVector3( vmd.cameras[ i ].position );
 		helper.leftToRightEuler( vmd.cameras[ i ].rotation );
 
 	}
@@ -3113,180 +3263,220 @@ THREE.MMDLoader.DataCreationHelper.prototype = {
 
 		return result;
 
-	},
+	}
 
-	pushAnimationKey: function ( keys, time, value, preventInterpolation ) {
+};
 
-		/*
-		 * Note: This is a workaround not to make Animation system calculate lerp
-		 *       if the diff from the last frame is 1 frame (in 30fps).
-		 */
-		if ( keys.length > 0 && preventInterpolation === true ) {
+/*
+ * extends existing KeyframeTrack for bone and camera animation.
+ *   - use Float64Array for times
+ *   - use Cubic Bezier curves interpolation
+ */
+THREE.MMDLoader.VectorKeyframeTrackEx = function ( name, times, values, interpolationParameterArray ) {
 
-			var k = keys[ keys.length - 1 ];
+	this.interpolationParameters = new Float32Array( interpolationParameterArray );
 
-			if ( time < k.time + ( 1 / 30 ) * 1.5 ) {
+	THREE.VectorKeyframeTrack.call( this, name, times, values );
 
-				keys.push(
-					{
-						time: time - 1e-13,
-						value: k.value.clone === undefined ? k.value : k.value.clone()
-					}
-				);
+};
 
-			}
+THREE.MMDLoader.VectorKeyframeTrackEx.prototype = Object.create( THREE.VectorKeyframeTrack.prototype );
+THREE.MMDLoader.VectorKeyframeTrackEx.prototype.constructor = THREE.MMDLoader.VectorKeyframeTrackEx;
+THREE.MMDLoader.VectorKeyframeTrackEx.prototype.TimeBufferType = Float64Array;
 
-		}
+THREE.MMDLoader.VectorKeyframeTrackEx.prototype.InterpolantFactoryMethodCubicBezier = function( result ) {
 
-		keys.push(
-			{
-				time: time,
-				value: value
-			}
-		);
+	return new THREE.MMDLoader.CubicBezierInterpolation( this.times, this.values, this.getValueSize(), result, this.interpolationParameters );
 
-	},
+};
 
-	insertAnimationKeyAtTimeZero: function ( keys, value ) {
+THREE.MMDLoader.VectorKeyframeTrackEx.prototype.setInterpolation = function( interpolation ) {
 
-		if ( keys.length === 0 ) {
+	this.createInterpolant = this.InterpolantFactoryMethodCubicBezier;
 
-			keys.push(
-				{
-					time: 0.0,
-					value: value
-				}
-			);
+};
 
-		}
+THREE.MMDLoader.QuaternionKeyframeTrackEx = function ( name, times, values, interpolationParameterArray ) {
 
-	},
+	this.interpolationParameters = new Float32Array( interpolationParameterArray );
 
-	insertStartAnimationKey: function ( keys ) {
+	THREE.QuaternionKeyframeTrack.call( this, name, times, values );
 
-		var k = keys[ 0 ];
+};
 
-		if ( k.time !== 0.0 ) {
+THREE.MMDLoader.QuaternionKeyframeTrackEx.prototype = Object.create( THREE.QuaternionKeyframeTrack.prototype );
+THREE.MMDLoader.QuaternionKeyframeTrackEx.prototype.constructor = THREE.MMDLoader.QuaternionKeyframeTrackEx;
+THREE.MMDLoader.QuaternionKeyframeTrackEx.prototype.TimeBufferType = Float64Array;
 
-			keys.unshift(
-				{
-					time: 0.0,
-					value: k.value.clone === undefined ? k.value : k.value.clone()
-				}
-			);
+THREE.MMDLoader.QuaternionKeyframeTrackEx.prototype.InterpolantFactoryMethodCubicBezier = function( result ) {
 
-		}
+	return new THREE.MMDLoader.CubicBezierInterpolation( this.times, this.values, this.getValueSize(), result, this.interpolationParameters );
 
-	},
+};
 
-	pushBoneAnimationKey: function ( keys, time, bone, pos, rot ) {
+THREE.MMDLoader.QuaternionKeyframeTrackEx.prototype.setInterpolation = function( interpolation ) {
 
-		keys.push(
-			{
-				time: time,
-				 pos: [ bone.pos[ 0 ] + pos[ 0 ],
-				        bone.pos[ 1 ] + pos[ 1 ],
-				        bone.pos[ 2 ] + pos[ 2 ] ],
-				 rot: [ rot[ 0 ], rot[ 1 ], rot[ 2 ], rot[ 3 ] ],
-				 scl: [ 1, 1, 1 ]
-			}
-		);
+	this.createInterpolant = this.InterpolantFactoryMethodCubicBezier;
 
-	},
+};
 
-	insertBoneAnimationKeyAtTimeZero: function ( keys, bone ) {
+THREE.MMDLoader.NumberKeyframeTrackEx = function ( name, times, values, interpolationParameterArray ) {
 
-		if ( keys.length === 0 ) {
+	this.interpolationParameters = new Float32Array( interpolationParameterArray );
 
-			keys.push(
-				{
-					time: 0.0,
-					 pos: [ bone.pos[ 0 ], bone.pos[ 1 ], bone.pos[ 2 ] ],
-					 rot: [ 0, 0, 0, 1 ],
-					 scl: [ 1, 1, 1 ]
-				}
-			);
+	THREE.NumberKeyframeTrack.call( this, name, times, values );
 
-		}
+};
 
-	},
+THREE.MMDLoader.NumberKeyframeTrackEx.prototype = Object.create( THREE.NumberKeyframeTrack.prototype );
+THREE.MMDLoader.NumberKeyframeTrackEx.prototype.constructor = THREE.MMDLoader.NumberKeyframeTrackEx;
+THREE.MMDLoader.NumberKeyframeTrackEx.prototype.TimeBufferType = Float64Array;
 
-	insertStartBoneAnimationKey: function ( keys ) {
+THREE.MMDLoader.NumberKeyframeTrackEx.prototype.InterpolantFactoryMethodCubicBezier = function( result ) {
 
-		var k = keys[ 0 ];
+	return new THREE.MMDLoader.CubicBezierInterpolation( this.times, this.values, this.getValueSize(), result, this.interpolationParameters );
 
-		if ( k.time !== 0.0 ) {
+};
 
-			keys.unshift(
-				{
-					time: 0.0,
-					pos: [ k.pos[ 0 ], k.pos[ 1 ], k.pos[ 2 ] ],
-					rot: [ k.rot[ 0 ], k.rot[ 1 ], k.rot[ 2 ], k.rot[ 3 ] ],
-					scl: [ k.scl[ 0 ], k.scl[ 1 ], k.scl[ 2 ] ]
-				}
-			);
+THREE.MMDLoader.NumberKeyframeTrackEx.prototype.setInterpolation = function( interpolation ) {
 
-		}
+	this.createInterpolant = this.InterpolantFactoryMethodCubicBezier;
 
-	},
+};
 
-	/*
-	 * This method wraps r74 Animation key frame track API for r73 Animation.
-	 */
-	generateTrackFromAnimationKeys: function ( keys, trackKey, name ) {
+THREE.MMDLoader.CubicBezierInterpolation = function ( parameterPositions, sampleValues, sampleSize, resultBuffer, params ) {
 
-		var times = [];
-		var values = [];
+	THREE.Interpolant.call( this, parameterPositions, sampleValues, sampleSize, resultBuffer );
 
-		for ( var i = 0; i < keys.length; i++ ) {
+	this.params = params;
 
-			var key = keys[ i ];
+}
 
-			times.push( key.time );
+THREE.MMDLoader.CubicBezierInterpolation.prototype = Object.create( THREE.LinearInterpolant.prototype );
+THREE.MMDLoader.CubicBezierInterpolation.prototype.constructor = THREE.MMDLoader.CubicBezierInterpolation;
 
-			if ( trackKey === 'VectorKeyframeTrackEx' ) {
+THREE.MMDLoader.CubicBezierInterpolation.prototype.interpolate_ = function( i1, t0, t, t1 ) {
 
-				values.push( key.value.x );
-				values.push( key.value.y );
-				values.push( key.value.z );
+	var result = this.resultBuffer;
+	var values = this.sampleValues;
+	var stride = this.valueSize;
 
-			} else {
+	var offset1 = i1 * stride;
+	var offset0 = offset1 - stride;
 
-				values.push( key.value );
+	var weight1 = ( t - t0 ) / ( t1 - t0 );
 
-			}
+	if ( stride === 4 ) {  // Quaternion
+
+		var x1 = this.params[ i1 * 4 + 0 ];
+		var x2 = this.params[ i1 * 4 + 1 ];
+		var y1 = this.params[ i1 * 4 + 2 ];
+		var y2 = this.params[ i1 * 4 + 3 ];
+
+		var ratio = this._calculate( x1, x2, y1, y2, weight1 );
+
+		THREE.Quaternion.slerpFlat( result, 0, values, offset0, values, offset1, ratio );
+
+	} else if ( stride === 3 ) {  // Vector3
+
+		for ( var i = 0; i !== stride; ++ i ) {
+
+			var x1 = this.params[ i1 * 12 + i * 4 + 0 ];
+			var x2 = this.params[ i1 * 12 + i * 4 + 1 ];
+			var y1 = this.params[ i1 * 12 + i * 4 + 2 ];
+			var y2 = this.params[ i1 * 12 + i * 4 + 3 ];
+
+			var ratio = this._calculate( x1, x2, y1, y2, weight1 );
+
+			result[ i ] = values[ offset0 + i ] * ( 1 - ratio ) + values[ offset1 + i ] * ratio;
 
 		}
 
-		return new THREE.MMDLoader[ trackKey ]( name, times, values );
+	} else {  // Number
+
+		var x1 = this.params[ i1 * 4 + 0 ];
+		var x2 = this.params[ i1 * 4 + 1 ];
+		var y1 = this.params[ i1 * 4 + 2 ];
+		var y2 = this.params[ i1 * 4 + 3 ];
+
+		var ratio = this._calculate( x1, x2, y1, y2, weight1 );
+
+		result[ 0 ] = values[ offset0 ] * ( 1 - ratio ) + values[ offset1 ] * ratio;
 
 	}
 
+	return result;
+
 };
 
-/*
- * These two classes are for high precision of times and values.
- * TODO: Let Three.KeyframeTrack support type select on instance creation.
- */
-THREE.MMDLoader.VectorKeyframeTrackEx = function ( name, times, values, interpolation ) {
+THREE.MMDLoader.CubicBezierInterpolation.prototype._calculate = function( x1, x2, y1, y2, x ) {
 
-	THREE.VectorKeyframeTrack.call( this, name, times, values, interpolation );
+	/*
+	 * Cubic Bezier curves
+	 *   https://en.wikipedia.org/wiki/B%C3%A9zier_curve#Cubic_B.C3.A9zier_curves
+	 *
+	 * B(t) = ( 1 - t ) ^ 3 * P0
+	 *      + 3 * ( 1 - t ) ^ 2 * t * P1
+	 *      + 3 * ( 1 - t ) * t^2 * P2
+	 *      + t ^ 3 * P3
+	 *      ( 0 <= t <= 1 )
+	 *
+	 * MMD uses Cubic Bezier curves for bone and camera animation interpolation.
+	 *   http://d.hatena.ne.jp/edvakf/20111016/1318716097
+	 *
+	 *    x = ( 1 - t ) ^ 3 * x0
+	 *      + 3 * ( 1 - t ) ^ 2 * t * x1
+	 *      + 3 * ( 1 - t ) * t^2 * x2
+	 *      + t ^ 3 * x3
+	 *    y = ( 1 - t ) ^ 3 * y0
+	 *      + 3 * ( 1 - t ) ^ 2 * t * y1
+	 *      + 3 * ( 1 - t ) * t^2 * y2
+	 *      + t ^ 3 * y3
+	 *      ( x0 = 0, y0 = 0 )
+	 *      ( x3 = 1, y3 = 1 )
+	 *      ( 0 <= t, x1, x2, y1, y2 <= 1 )
+	 *
+	 * Here solves this equation with Bisection method,
+	 *   https://en.wikipedia.org/wiki/Bisection_method
+	 * gets t, and then calculate y.
+	 *
+	 * f(t) = 3 * ( 1 - t ) ^ 2 * t * x1
+	 *      + 3 * ( 1 - t ) * t^2 * x2
+	 *      + t ^ 3 - x = 0
+	 *
+	 * (Another option: Newton's method
+	 *    https://en.wikipedia.org/wiki/Newton%27s_method)
+	 */
 
-};
+	var c = 0.5;
+	var t = c;
+	var s = 1.0 - t;
+	var loop = 15;
+	var eps = 1e-5;
+	var math = Math;
 
-THREE.MMDLoader.VectorKeyframeTrackEx.prototype = Object.create( THREE.VectorKeyframeTrack.prototype );
-THREE.MMDLoader.VectorKeyframeTrackEx.prototype.constructor = THREE.MMDLoader.VectorKeyframeTrackEx;
-THREE.MMDLoader.VectorKeyframeTrackEx.prototype.TimeBufferType = Float64Array;
+	var sst3, stt3, ttt;
 
-THREE.MMDLoader.NumberKeyframeTrackEx = function ( name, times, values, interpolation ) {
+	for ( var i = 0; i < loop; i ++ ) {
 
-	THREE.VectorKeyframeTrack.call( this, name, times, values, interpolation );
+		sst3 = 3.0 * s * s * t;
+		stt3 = 3.0 * s * t * t;
+		ttt = t * t * t;
 
-};
+		var ft = ( sst3 * x1 ) + ( stt3 * x2 ) + ( ttt ) - x;
 
-THREE.MMDLoader.NumberKeyframeTrackEx.prototype = Object.create( THREE.NumberKeyframeTrack.prototype );
-THREE.MMDLoader.NumberKeyframeTrackEx.prototype.constructor = THREE.MMDLoader.NumberKeyframeTrackEx;
-THREE.MMDLoader.NumberKeyframeTrackEx.prototype.TimeBufferType = Float64Array;
+		if ( math.abs( ft ) < eps ) break;
+
+		c /= 2.0;
+
+		t += ( ft < 0 ) ? c : -c;
+		s = 1.0 - t;
+
+	}
+
+	return ( sst3 * y1 ) + ( stt3 * y2 ) + ttt;
+
+};
 
 THREE.MMDLoader.DataView = function ( buffer, littleEndian ) {
 
@@ -3810,7 +4000,6 @@ THREE.MMDGrantSolver.prototype = {
 						q.set( 0, 0, 0, 1 );
 						q.slerp( pb.quaternion, g.ratio );
 						b.quaternion.multiply( q );
-						b.updateMatrixWorld( true );
 
 					}
 
@@ -4240,6 +4429,8 @@ THREE.MMDHelper.prototype = {
 			// TODO: Let PerspectiveCamera automatically update?
 			this.camera.updateProjectionMatrix();
 
+			this.camera.up.set( 0, 1, 0 );
+			this.camera.up.applyQuaternion( this.camera.quaternion );
 			this.camera.lookAt( this.camera.center );
 
 		}

+ 0 - 3
examples/js/loaders/deprecated/gltf/glTFLoader.js

@@ -1063,9 +1063,6 @@ THREE.glTFLoader.prototype.load = function( url, callback ) {
 				params.color = RgbArraytoHex(diffuseColor);
 				params.opacity = opacity;
 				params.transparent = opacity < 1.0;
-				// hack hack hack
-				if (params.map && params.map.sourceFile.toLowerCase().indexOf(".png") != -1)
-					params.transparent = true;
 
 				if (!(shininess === undefined))
 				{

+ 108 - 108
examples/js/renderers/WebGLDeferredRenderer.js

@@ -76,7 +76,7 @@ THREE.WebGLDeferredRenderer = function ( parameters ) {
 
 	// private methods
 
-	var init = function ( parameters ) {
+	function init( parameters ) {
 
 		_this.renderer = parameters.renderer !== undefined ? parameters.renderer : new THREE.WebGLRenderer( { antialias: false } );
 		_this.domElement = _this.renderer.domElement;
@@ -100,9 +100,9 @@ THREE.WebGLDeferredRenderer = function ( parameters ) {
 		_this.setAntialias( antialias );
 		_this.enableLightPrePass( false );
 
-	};
+	}
 
-	var initDepthTexture = function () {
+	function initDepthTexture() {
 
 		_depthTexture = new THREE.DepthTexture(
 			_width,
@@ -117,9 +117,9 @@ THREE.WebGLDeferredRenderer = function ( parameters ) {
 			THREE.DepthStencilFormat
 		)
 
-	};
+	}
 
-	var initPassNormalDepth = function () {
+	function initPassNormalDepth() {
 
 		_passNormalDepth = new THREE.RenderPass();
 		_passNormalDepth.clear = true;
@@ -138,9 +138,9 @@ THREE.WebGLDeferredRenderer = function ( parameters ) {
 		_compNormalDepth = new THREE.EffectComposer( _this.renderer, rt );
 		_compNormalDepth.addPass( _passNormalDepth );
 
-	};
+	}
 
-	var initPassColor = function () {
+	function initPassColor() {
 
 		_passColor = new THREE.RenderPass();
 		_passColor.clear = true;
@@ -158,9 +158,9 @@ THREE.WebGLDeferredRenderer = function ( parameters ) {
 		_compColor = new THREE.EffectComposer( _this.renderer, rt );
 		_compColor.addPass( _passColor );
 
-	};
+	}
 
-	var initPassLight = function () {
+	function initPassLight() {
 
 		_passLightFullscreen = new THREE.RenderPass();
 		_passLightFullscreen.clear = true;
@@ -183,9 +183,9 @@ THREE.WebGLDeferredRenderer = function ( parameters ) {
 		_compLight.addPass( _passLightFullscreen );
 		_compLight.addPass( _passLight );
 
-	};
+	}
 
-	var initPassReconstruction = function () {
+	function initPassReconstruction() {
 
 		_passReconstruction = new THREE.RenderPass();
 		_passReconstruction.clear = true;
@@ -203,9 +203,9 @@ THREE.WebGLDeferredRenderer = function ( parameters ) {
 		_compReconstruction = new THREE.EffectComposer( _this.renderer, rt );
 		_compReconstruction.addPass( _passReconstruction );
 
-	};
+	}
 
-	var initPassFinal = function () {
+	function initPassFinal() {
 
 		_passFinal = new THREE.ShaderPass( THREE.ShaderDeferred[ 'final' ] );
 		_passFinal.clear = true;
@@ -237,9 +237,9 @@ THREE.WebGLDeferredRenderer = function ( parameters ) {
 		_compFinal.addPass( _passCopy );
 		_compFinal.addPass( _passFXAA );
 
-	};
+	}
 
-	var initLightScene = function ( scene ) {
+	function initLightScene( scene ) {
 
 		if ( scene.userData.lightScene === undefined ) {
 
@@ -268,9 +268,9 @@ THREE.WebGLDeferredRenderer = function ( parameters ) {
 		// emissiveLight is only for Classic Deferred Rendering
 		_lightFullscreenScene.userData.emissiveLight.visible = ! _lightPrePass;
 
-	};
+	}
 
-	var setMaterialNormalDepth = function ( object ) {
+	function setMaterialNormalDepth( object ) {
 
 		if ( object.material === undefined ) return;
 
@@ -290,9 +290,9 @@ THREE.WebGLDeferredRenderer = function ( parameters ) {
 
 		}
 
-	};
+	}
 
-	var getNormalDepthMaterial = function ( object ) {
+	function getNormalDepthMaterial( object ) {
 
 		if ( ( _lightPrePass && object.userData.normalDepthShininessMaterial === undefined ) ||
 		     ( ! _lightPrePass && object.userData.normalDepthMaterial === undefined ) ) {
@@ -303,9 +303,9 @@ THREE.WebGLDeferredRenderer = function ( parameters ) {
 
 		return ( _lightPrePass ) ? object.userData.normalDepthShininessMaterial : object.userData.normalDepthMaterial;
 
-	};
+	}
 
-	var initDeferredNormalDepthMaterial = function ( object, isLightPrePass ) {
+	function initDeferredNormalDepthMaterial( object, isLightPrePass ) {
 
 		var originalMaterial = object.userData.originalMaterial;
 		var material;
@@ -338,9 +338,9 @@ THREE.WebGLDeferredRenderer = function ( parameters ) {
 
 		}
 
-	};
+	}
 
-	var createDeferredNormalDepthMaterial = function ( originalMaterial, isLightPrePass ) {
+	function createDeferredNormalDepthMaterial( originalMaterial, isLightPrePass ) {
 
 		var shader = ( isLightPrePass ) ? THREE.ShaderDeferred[ 'normalDepthShininess' ] : THREE.ShaderDeferred[ 'normalDepth' ];
 
@@ -353,9 +353,9 @@ THREE.WebGLDeferredRenderer = function ( parameters ) {
 
 		return material;
 
-	};
+	}
 
-	var updateDeferredNormalDepthMaterial = function ( material, originalMaterial, isLightPrePass ) {
+	function updateDeferredNormalDepthMaterial( material, originalMaterial, isLightPrePass ) {
 
 		if ( originalMaterial.skinning !== undefined ) material.skinning = originalMaterial.skinning;
 		if ( originalMaterial.morphTargets !== undefined ) material.morphTargets = originalMaterial.morphTargets;
@@ -384,9 +384,9 @@ THREE.WebGLDeferredRenderer = function ( parameters ) {
 
 		}
 
-	};
+	}
 
-	var setMaterialColor = function ( object ) {
+	function setMaterialColor( object ) {
 
 		if ( object.material === undefined ) return;
 
@@ -406,9 +406,9 @@ THREE.WebGLDeferredRenderer = function ( parameters ) {
 
 		}
 
-	};
+	}
 
-	var getColorMaterial = function ( object ) {
+	function getColorMaterial( object ) {
 
 		if ( object.userData.colorMaterial === undefined ) {
 
@@ -418,9 +418,9 @@ THREE.WebGLDeferredRenderer = function ( parameters ) {
 
 		return object.userData.colorMaterial;
 
-	};
+	}
 
-	var initDeferredColorMaterial = function ( object ) {
+	function initDeferredColorMaterial( object ) {
 
 		var originalMaterial = object.userData.originalMaterial;
 
@@ -442,9 +442,9 @@ THREE.WebGLDeferredRenderer = function ( parameters ) {
 
 		}
 
-	};
+	}
 
-	var createDeferredColorMaterial = function ( originalMaterial ) {
+	function createDeferredColorMaterial( originalMaterial ) {
 
 		var shader = THREE.ShaderDeferred[ 'color' ];
 
@@ -459,9 +459,9 @@ THREE.WebGLDeferredRenderer = function ( parameters ) {
 
 		return material;
 
-	};
+	}
 
-	var updateDeferredColorMaterial = function ( material, originalMaterial ) {
+	function updateDeferredColorMaterial( material, originalMaterial ) {
 
 		var diffuse, emissive;
 
@@ -514,9 +514,9 @@ THREE.WebGLDeferredRenderer = function ( parameters ) {
 
 		}
 
-	};
+	}
 
-	var setMaterialReconstruction = function ( object ) {
+	function setMaterialReconstruction( object ) {
 
 		if ( object.material === undefined ) return;
 
@@ -544,9 +544,9 @@ THREE.WebGLDeferredRenderer = function ( parameters ) {
 
 		}
 
-	};
+	}
 
-	var getReconstructionMaterial = function ( object ) {
+	function getReconstructionMaterial( object ) {
 
 		if ( object.userData.reconstructionMaterial === undefined ) {
 
@@ -556,9 +556,9 @@ THREE.WebGLDeferredRenderer = function ( parameters ) {
 
 		return object.userData.reconstructionMaterial;
 
-	};
+	}
 
-	var initDeferredReconstructionMaterial = function ( object ) {
+	function initDeferredReconstructionMaterial( object ) {
 
 		var originalMaterial = object.userData.originalMaterial;
 
@@ -580,9 +580,9 @@ THREE.WebGLDeferredRenderer = function ( parameters ) {
 
 		}
 
-	};
+	}
 
-	var createDeferredReconstructionMaterial = function ( originalMaterial ) {
+	function createDeferredReconstructionMaterial( originalMaterial ) {
 
 		var shader = THREE.ShaderDeferred[ 'reconstruction' ];
 
@@ -599,18 +599,18 @@ THREE.WebGLDeferredRenderer = function ( parameters ) {
 
 		return material;
 
-	};
+	}
 
-	var updateDeferredReconstructionMaterial = function ( material, originalMaterial ) {
+	function updateDeferredReconstructionMaterial( material, originalMaterial ) {
 
 		updateDeferredColorMaterial( material, originalMaterial );
 
 		material.uniforms.viewWidth.value = _width;
 		material.uniforms.viewHeight.value = _height;
 
-	};
+	}
 
-	var setMaterialForwardRendering = function ( object ) {
+	function setMaterialForwardRendering( object ) {
 
 		if ( object.material === undefined ) return;
 
@@ -636,9 +636,9 @@ THREE.WebGLDeferredRenderer = function ( parameters ) {
 
 		}
 
-	};
+	}
 
-	var initInvisibleMaterial = function ( object ) {
+	function initInvisibleMaterial( object ) {
 
 		if ( object.userData.originalMaterial.isMultiMaterial === true ) {
 
@@ -654,9 +654,9 @@ THREE.WebGLDeferredRenderer = function ( parameters ) {
 
 		}
 
-	};
+	}
 
-	var getForwardRenderingMaterial = function ( originalMaterial ) {
+	function getForwardRenderingMaterial( originalMaterial ) {
 
 		if ( originalMaterial.transparent === true && originalMaterial.visible === true ) {
 
@@ -668,9 +668,9 @@ THREE.WebGLDeferredRenderer = function ( parameters ) {
 
 		}
 
-	};
+	}
 
-	var createDeferredEmissiveLight = function () {
+	function createDeferredEmissiveLight() {
 
 		var shader = THREE.ShaderDeferred[ 'emissiveLight' ];
 
@@ -689,18 +689,18 @@ THREE.WebGLDeferredRenderer = function ( parameters ) {
 
 		return mesh;
 
-	};
+	}
 
-	var updateDeferredEmissiveLight = function ( light, camera ) {
+	function updateDeferredEmissiveLight( light, camera ) {
 
 		var uniforms = light.material.uniforms;
 
 		uniforms.viewWidth.value = _width;
 		uniforms.viewHeight.value = _height;
 
-	};
+	}
 
-	var initDeferredLight = function ( light ) {
+	function initDeferredLight( light ) {
 
 		var deferredLight;
 
@@ -724,9 +724,9 @@ THREE.WebGLDeferredRenderer = function ( parameters ) {
 
 		light.userData.deferredLight = deferredLight;
 
-	};
+	}
 
-	var initDeferredLightMaterial = function ( light, isLightPrePass ) {
+	function initDeferredLightMaterial( light, isLightPrePass ) {
 
 		var originalLight = light.userData.originalLight;
 		var material;
@@ -759,9 +759,9 @@ THREE.WebGLDeferredRenderer = function ( parameters ) {
 
 		}
 
-	};
+	}
 
-	var getDeferredLightMaterial = function ( light ) {
+	function getDeferredLightMaterial( light ) {
 
 		if ( ( _lightPrePass && light.userData.materialLightPrePass === undefined ) ||
 		     ( ! _lightPrePass && light.userData.materialClassic === undefined ) ) {
@@ -772,9 +772,9 @@ THREE.WebGLDeferredRenderer = function ( parameters ) {
 
 		return ( _lightPrePass ) ? light.userData.materialLightPrePass : light.userData.materialClassic;
 
-	};
+	}
 
-	var updateDeferredLight = function ( light, camera ) {
+	function updateDeferredLight( light, camera ) {
 
 		var originalLight = light.userData.originalLight;
 
@@ -792,9 +792,9 @@ THREE.WebGLDeferredRenderer = function ( parameters ) {
 
 		}
 
-	};
+	}
 
-	var createDeferredLightMesh = function ( light, geometry ) {
+	function createDeferredLightMesh( light, geometry ) {
 
 		var mesh = new THREE.Mesh( geometry, _invisibleMaterial );
 
@@ -802,9 +802,9 @@ THREE.WebGLDeferredRenderer = function ( parameters ) {
 
 		return mesh;
 
-	};
+	}
 
-	var createDeferredLightMaterial = function ( shader, isLightPrePass ) {
+	function createDeferredLightMaterial( shader, isLightPrePass ) {
 
 		var material = new THREE.ShaderMaterial( {
 			uniforms: THREE.UniformsUtils.clone( shader.uniforms ),
@@ -829,19 +829,19 @@ THREE.WebGLDeferredRenderer = function ( parameters ) {
 
 		return material;
 
-	};
+	}
 
-	var createDeferredPointLight = function ( light ) {
+	function createDeferredPointLight( light ) {
 
 		return createDeferredLightMesh( light, new THREE.SphereGeometry( 1, 16, 8 ) );
 
-	};
+	}
 
 	/*
 	 * optimization:
 	 * Renders PointLight only back face with stencil test.
 	 */
-	var createDeferredPointLightMaterial = function ( isLightPrePass ) {
+	function createDeferredPointLightMaterial( isLightPrePass ) {
 
 		var shader = ( isLightPrePass ) ? THREE.ShaderDeferred[ 'pointLightPre' ] : THREE.ShaderDeferred[ 'pointLight' ];
 
@@ -852,9 +852,9 @@ THREE.WebGLDeferredRenderer = function ( parameters ) {
 
 		return material;
 
-	};
+	}
 
-	var updateDeferredPointLight = function ( light, camera ) {
+	function updateDeferredPointLight( light, camera ) {
 
 		var originalLight = light.userData.originalLight;
 		var distance = originalLight.distance;
@@ -879,15 +879,15 @@ THREE.WebGLDeferredRenderer = function ( parameters ) {
 
 		}
 
-	};
+	}
 
-	var createDeferredSpotLight = function ( light ) {
+	function createDeferredSpotLight( light ) {
 
 		return createDeferredLightMesh(	light, new THREE.PlaneBufferGeometry( 2, 2 ) );
 
-	};
+	}
 
-	var createDeferredSpotLightMaterial = function ( isLightPrePass ) {
+	function createDeferredSpotLightMaterial( isLightPrePass ) {
 
 		var shader = ( isLightPrePass ) ? THREE.ShaderDeferred[ 'spotLightPre' ] : THREE.ShaderDeferred[ 'spotLight' ];
 
@@ -897,9 +897,9 @@ THREE.WebGLDeferredRenderer = function ( parameters ) {
 
 		return material;
 
-	};
+	}
 
-	var updateDeferredSpotLight = function ( light, camera ) {
+	function updateDeferredSpotLight( light, camera ) {
 
 		var originalLight = light.userData.originalLight;
 		var uniforms = light.material.uniforms;
@@ -919,15 +919,15 @@ THREE.WebGLDeferredRenderer = function ( parameters ) {
 		vec2.setFromMatrixPosition( originalLight.target.matrixWorld );
 		vec.sub( vec2 ).normalize().transformDirection( camera.matrixWorldInverse );
 
-	};
+	}
 
-	var createDeferredDirectionalLight = function ( light ) {
+	function createDeferredDirectionalLight( light ) {
 
 		return createDeferredLightMesh(	light, new THREE.PlaneBufferGeometry( 2, 2 ) );
 
-	};
+	}
 
-	var createDeferredDirectionalLightMaterial = function ( isLightPrePass ) {
+	function createDeferredDirectionalLightMaterial( isLightPrePass ) {
 
 		var shader = ( isLightPrePass ) ? THREE.ShaderDeferred[ 'directionalLightPre' ] : THREE.ShaderDeferred[ 'directionalLight' ];
 
@@ -937,9 +937,9 @@ THREE.WebGLDeferredRenderer = function ( parameters ) {
 
 		return material;
 
-	};
+	}
 
-	var updateDeferredDirectionalLight = function ( light, camera ) {
+	function updateDeferredDirectionalLight( light, camera ) {
 
 		var originalLight = light.userData.originalLight;
 		var uniforms = light.material.uniforms;
@@ -957,9 +957,9 @@ THREE.WebGLDeferredRenderer = function ( parameters ) {
 		vec2.setFromMatrixPosition( originalLight.target.matrixWorld );
 		vec.sub( vec2 ).normalize().transformDirection( camera.matrixWorldInverse );
 
-	};
+	}
 
-	var saveOriginalMaterialAndCheckTransparency = function ( object ) {
+	function saveOriginalMaterialAndCheckTransparency( object ) {
 
 		if ( object.material !== undefined ) {
 
@@ -988,15 +988,15 @@ THREE.WebGLDeferredRenderer = function ( parameters ) {
 
 		}
 
-	};
+	}
 
-	var restoreOriginalMaterial = function ( object ) {
+	function restoreOriginalMaterial( object ) {
 
 		if ( object.userData.originalMaterial !== undefined ) object.material = object.userData.originalMaterial;
 
-	};
+	}
 
-	var addDeferredLightsToLightScene = function ( object ) {
+	function addDeferredLightsToLightScene( object ) {
 
 		if ( object.isLight !== true ) return;
 
@@ -1027,9 +1027,9 @@ THREE.WebGLDeferredRenderer = function ( parameters ) {
 
 		lights[ light.uuid ].found = true;
 
-	};
+	}
 
-	var updateDeferredLightsInLightScene = function ( scene, camera ) {
+	function updateDeferredLightsInLightScene( scene, camera ) {
 
 		var lights = scene.userData.lights;
 		var keys = Object.keys( lights );
@@ -1056,9 +1056,9 @@ THREE.WebGLDeferredRenderer = function ( parameters ) {
 
 		}
 
-	};
+	}
 
-	var enableFinalPasses = function () {
+	function enableFinalPasses() {
 
 		if ( _lightPrePass ) {
 
@@ -1150,7 +1150,7 @@ THREE.WebGLDeferredRenderer = function ( parameters ) {
 
 		}
 
-	};
+	}
 
 	/*
 	 * Classic Deferred Rendering
@@ -1170,7 +1170,7 @@ THREE.WebGLDeferredRenderer = function ( parameters ) {
 	 *   A: depth
 	 */
 
-	var renderNormalDepth = function ( scene, camera ) {
+	function renderNormalDepth( scene, camera ) {
 
 		scene.traverse( setMaterialNormalDepth );
 
@@ -1186,7 +1186,7 @@ THREE.WebGLDeferredRenderer = function ( parameters ) {
 
 		_compNormalDepth.render();
 
-	};
+	}
 
 	/*
 	 * Classic Deferred Rendering
@@ -1199,7 +1199,7 @@ THREE.WebGLDeferredRenderer = function ( parameters ) {
 	 * A: shininess
 	 */
 
-	var renderColor = function ( scene, camera ) {
+	function renderColor( scene, camera ) {
 
 		scene.traverse( setMaterialColor );
 
@@ -1214,7 +1214,7 @@ THREE.WebGLDeferredRenderer = function ( parameters ) {
 
 		_compColor.render();
 
-	};
+	}
 
 	/*
 	 * Classic Deferred Rendering
@@ -1222,7 +1222,7 @@ THREE.WebGLDeferredRenderer = function ( parameters ) {
 	 * 3) light pass
 	 */
 
-	var renderLight = function ( scene, camera ) {
+	function renderLight( scene, camera ) {
 
 		updateDeferredEmissiveLight( _lightFullscreenScene.userData.emissiveLight, camera );
 
@@ -1243,7 +1243,7 @@ THREE.WebGLDeferredRenderer = function ( parameters ) {
 
 		_gl.disable( _gl.STENCIL_TEST );
 
-	};
+	}
 
 	/*
 	 * Light Pre-Pass Rendering
@@ -1251,7 +1251,7 @@ THREE.WebGLDeferredRenderer = function ( parameters ) {
 	 * 2') Light pre pass
 	 */
 
-	var renderLightPre = function ( scene, camera ) {
+	function renderLightPre( scene, camera ) {
 
 		scene.traverse( addDeferredLightsToLightScene );
 
@@ -1271,7 +1271,7 @@ THREE.WebGLDeferredRenderer = function ( parameters ) {
 
 		_compLight.render();
 
-	};
+	}
 
 	/*
 	 * Light Pre-Pass Rendering
@@ -1282,7 +1282,7 @@ THREE.WebGLDeferredRenderer = function ( parameters ) {
 	 * Here renders transparent objects with normal forward rendering.
 	 */
 
-	var renderReconstruction = function ( scene, camera ) {
+	function renderReconstruction( scene, camera ) {
 
 		scene.traverse( setMaterialReconstruction );
 
@@ -1296,7 +1296,7 @@ THREE.WebGLDeferredRenderer = function ( parameters ) {
 
 		_gl.disable( _gl.STENCIL_TEST );
 
-	};
+	}
 
 	/*
 	 * Classic Deferred Rendering
@@ -1321,7 +1321,7 @@ THREE.WebGLDeferredRenderer = function ( parameters ) {
 	 *
 	 */
 
-	var renderFinal = function ( scene, camera ) {
+	function renderFinal( scene, camera ) {
 
 		if ( ! _lightPrePass && _hasTransparentObject ) {
 
@@ -1339,7 +1339,7 @@ THREE.WebGLDeferredRenderer = function ( parameters ) {
 
 		_compFinal.render();
 
-	};
+	}
 
 	// external APIs
 

BIN
examples/models/mmd/default/toon00.bmp


BIN
examples/models/mmd/default/toon01.bmp


BIN
examples/models/mmd/default/toon02.bmp


BIN
examples/models/mmd/default/toon03.bmp


BIN
examples/models/mmd/default/toon04.bmp


BIN
examples/models/mmd/default/toon05.bmp


BIN
examples/models/mmd/default/toon06.bmp


BIN
examples/models/mmd/default/toon07.bmp


BIN
examples/models/mmd/default/toon08.bmp


BIN
examples/models/mmd/default/toon09.bmp


BIN
examples/models/mmd/default/toon10.bmp


+ 77 - 55
examples/webgl_loader_mmd.html

@@ -44,8 +44,11 @@
 		<script src="js/animation/CCDIKSolver.js"></script>
 		<script src="js/animation/MMDPhysics.js"></script>
 
+		<script src="js/controls/OrbitControls.js"></script>
+
 		<script src="js/Detector.js"></script>
 		<script src="js/libs/stats.min.js"></script>
+		<script src="js/libs/dat.gui.min.js"></script>
 
 		<script>
 
@@ -70,12 +73,16 @@
 				document.body.appendChild( container );
 
 				camera = new THREE.PerspectiveCamera( 45, window.innerWidth / window.innerHeight, 1, 2000 );
-				camera.position.z = 25;
+				camera.position.z = 30;
 
 				// scene
 
 				scene = new THREE.Scene();
 
+				var gridHelper = new THREE.GridHelper( 100, 100 )
+				gridHelper.position.y = -10;
+				scene.add( gridHelper );
+
 				var ambient = new THREE.AmbientLight( 0x666666 );
 				scene.add( ambient );
 
@@ -92,6 +99,10 @@
 				container.appendChild( renderer.domElement );
 
 				effect = new THREE.OutlineEffect( renderer );
+				// STATS
+
+				stats = new Stats();
+				container.appendChild( stats.dom );
 
 				// model
 
@@ -111,46 +122,93 @@
 				helper = new THREE.MMDHelper();
 
 				var loader = new THREE.MMDLoader();
-				loader.setDefaultTexturePath( './models/mmd/default/' );
 
 				loader.load( modelFile, vmdFiles, function ( object ) {
 
 					mesh = object;
 					mesh.position.y = -10;
+					scene.add( mesh );
 
 					helper.add( mesh );
 					helper.setAnimation( mesh );
 
-					// create CCDIKHelper after calling helper.setAnimation()
+					/*
+					 * Note: create CCDIKHelper after calling helper.setAnimation()
+					 */
 					ikHelper = new THREE.CCDIKHelper( mesh );
+					ikHelper.visible = false;
 					scene.add( ikHelper );
 
 					/*
 					 * Note: You're recommended to call helper.setPhysics()
 					 *       after calling helper.setAnimation().
-					 * Note: Physics calculation is pretty heavy.
-					 *       It may not be acceptable for most mobile devices yet.
 			 		 */
-					if ( ! isMobileDevice() ) {
-
-						helper.setPhysics( mesh );
-						physicsHelper = new THREE.MMDPhysicsHelper( mesh );
-						scene.add( physicsHelper );
-
-					}
+					helper.setPhysics( mesh );
+					physicsHelper = new THREE.MMDPhysicsHelper( mesh );
+					physicsHelper.visible = false;
+					scene.add( physicsHelper );
 
 					helper.unifyAnimationDuration( { afterglow: 2.0 } );
 
-					scene.add( mesh );
+					initGui();
 
 				}, onProgress, onError );
 
-				document.addEventListener( 'mousemove', onDocumentMouseMove, false );
-
-				//
+				var controls = new THREE.OrbitControls( camera, renderer.domElement );
+				controls.update();
 
 				window.addEventListener( 'resize', onWindowResize, false );
 
+				function initGui () {
+
+					var api = {
+						'animation': true,
+						'gradient mapping': true,
+						'ik': true,
+						'outline': true,
+						'physics': true,
+						'show IK bones': false,
+						'show rigid bodies': false
+					};
+
+					var gui = new dat.GUI();
+
+					gui.add( api, 'animation' ).onChange( function () {
+						helper.doAnimation = api[ 'animation' ];
+					} );
+
+					gui.add( api, 'gradient mapping' ).onChange( function () {
+
+						for ( var i = 0, il = mesh.material.materials.length; i < il; i ++ ) {
+
+							var material = mesh.material.materials[ i ].uniforms.celShading.value = api[ 'gradient mapping' ] ? 1 : 0;
+
+						}
+
+					} );
+
+					gui.add( api, 'ik' ).onChange( function () {
+						helper.doIk = api[ 'ik' ];
+					} );
+
+					gui.add( api, 'outline' ).onChange( function () {
+						helper.doOutlineDrawing = api[ 'outline' ];
+					} );
+
+					gui.add( api, 'physics' ).onChange( function () {
+						helper.enablePhysics( api[ 'physics' ] );
+					} );
+
+					gui.add( api, 'show IK bones' ).onChange( function () {
+						ikHelper.visible = api[ 'show IK bones' ];
+					} );
+
+					gui.add( api, 'show rigid bodies' ).onChange( function () {
+						if ( physicsHelper !== undefined ) physicsHelper.visible = api[ 'show rigid bodies' ];
+					} );
+
+				}
+
 			}
 
 			function onWindowResize() {
@@ -165,29 +223,20 @@
 
 			}
 
-			function onDocumentMouseMove( event ) {
-
-				mouseX = ( event.clientX - windowHalfX ) / 2;
-				mouseY = ( event.clientY - windowHalfY ) / 2;
-
-			}
-
 			//
 
 			function animate() {
 
 				requestAnimationFrame( animate );
+
+				stats.begin();
 				render();
+				stats.end();
 
 			}
 
 			function render() {
 
-				camera.position.x += ( - mouseX - camera.position.x ) * .05;
-				camera.position.y += ( - mouseY - camera.position.y ) * .05;
-
-				camera.lookAt( scene.position );
-
 				helper.animate( clock.getDelta() );
 				if ( physicsHelper !== undefined && physicsHelper.visible ) physicsHelper.update();
 				if ( ikHelper !== undefined && ikHelper.visible ) ikHelper.update();
@@ -195,33 +244,6 @@
 
 			}
 
-			// easy mobile device detection
-			function isMobileDevice () {
-
-				if ( navigator === undefined || navigator.userAgent === undefined ) {
-
-					return true;
-
-				}
-
-				var s = navigator.userAgent;
-
-				if (    s.match( /iPhone/i )
-//				     || s.match( /iPad/i )
-				     || s.match( /iPod/i )
-				     || s.match( /webOS/i )
-				     || s.match( /BlackBerry/i )
-				     || ( s.match( /Windows/i ) && s.match( /Phone/i ) )
-				     || ( s.match( /Android/i ) && s.match( /Mobile/i ) ) ) {
-
-					return true;
-
-				}
-
-				return false;
-
-			}
-
 		</script>
 
 	</body>

+ 1 - 40
examples/webgl_loader_mmd_audio.html

@@ -119,7 +119,6 @@
 				helper = new THREE.MMDHelper();
 
 				var loader = new THREE.MMDLoader();
-				loader.setDefaultTexturePath( './models/mmd/default/' );
 
 				loader.load( modelFile, vmdFiles, function ( object ) {
 
@@ -127,18 +126,7 @@
 
 					helper.add( mesh );
 					helper.setAnimation( mesh );
-
-					/*
-					 * Note: You're recommended to call helper.setPhysics()
-					 *       after calling helper.setAnimation().
-					 * Note: Physics calculation is pretty heavy.
-					 *       It may not be acceptable for most mobile devices yet.
-			 		 */
-					if ( ! isMobileDevice() ) {
-
-						helper.setPhysics( mesh );
-
-					}
+					helper.setPhysics( mesh );
 
 					loader.loadVmds( cameraFiles, function ( vmd ) {
 
@@ -224,33 +212,6 @@
 
 			}
 
-			// easy mobile device detection
-			function isMobileDevice () {
-
-				if ( navigator === undefined || navigator.userAgent === undefined ) {
-
-					return true;
-
-				}
-
-				var s = navigator.userAgent;
-
-				if (    s.match( /iPhone/i )
-//				     || s.match( /iPad/i )
-				     || s.match( /iPod/i )
-				     || s.match( /webOS/i )
-				     || s.match( /BlackBerry/i )
-				     || ( s.match( /Windows/i ) && s.match( /Phone/i ) )
-				     || ( s.match( /Android/i ) && s.match( /Mobile/i ) ) ) {
-
-					return true;
-
-				}
-
-				return false;
-
-			}
-
 		</script>
 
 	</body>

+ 0 - 1
examples/webgl_loader_mmd_pose.html

@@ -128,7 +128,6 @@
 				helper = new THREE.MMDHelper();
 
 				var loader = new THREE.MMDLoader();
-				loader.setDefaultTexturePath( './models/mmd/default/' );
 
 				loader.loadModel( modelFile, function ( object ) {
 

+ 66 - 0
src/Three.Legacy.js

@@ -575,6 +575,7 @@ Object.assign( WebGLRenderer.prototype, {
 		return this.extensions.get( 'EXT_blend_minmax' );
 	},
 	supportsVertexTextures: function () {
+		console.warn( 'THREE.WebGLRenderer: .supportsVertexTextures() is now .capabilities.vertexTextures.' );
 		return this.capabilities.vertexTextures;
 	},
 	supportsInstancedArrays: function () {
@@ -848,6 +849,71 @@ export var ImageUtils = {
 
 };
 
+export var UniformsUtils = {
+
+	merge: function ( uniforms ) {
+
+		console.warn( 'THREE.UniformsUtils.merge() has been deprecated. Use Object.assign() instead.' );
+
+		var merged = {};
+
+		for ( var u = 0; u < uniforms.length; u ++ ) {
+
+			var tmp = this.clone( uniforms[ u ] );
+
+			for ( var p in tmp ) {
+
+				merged[ p ] = tmp[ p ];
+
+			}
+
+		}
+
+		return merged;
+
+	},
+
+	clone: function ( uniforms_src ) {
+
+		console.warn( 'THREE.UniformsUtils.clone() has been deprecated.' );
+
+		var uniforms_dst = {};
+
+		for ( var u in uniforms_src ) {
+
+			uniforms_dst[ u ] = {};
+
+			for ( var p in uniforms_src[ u ] ) {
+
+				var parameter_src = uniforms_src[ u ][ p ];
+
+				if ( parameter_src && ( parameter_src.isColor ||
+					parameter_src.isMatrix3 || parameter_src.isMatrix4 ||
+					parameter_src.isVector2 || parameter_src.isVector3 || parameter_src.isVector4 ||
+					parameter_src.isTexture ) ) {
+
+					uniforms_dst[ u ][ p ] = parameter_src.clone();
+
+				} else if ( Array.isArray( parameter_src ) ) {
+
+					uniforms_dst[ u ][ p ] = parameter_src.slice();
+
+				} else {
+
+					uniforms_dst[ u ][ p ] = parameter_src;
+
+				}
+
+			}
+
+		}
+
+		return uniforms_dst;
+
+	}
+
+};
+
 //
 
 export function Projector () {

+ 0 - 1
src/Three.js

@@ -6,7 +6,6 @@ export { WebGLRenderer } from './renderers/WebGLRenderer.js';
 export { WebGL2Renderer } from './renderers/WebGL2Renderer.js';
 export { ShaderLib } from './renderers/shaders/ShaderLib.js';
 export { UniformsLib } from './renderers/shaders/UniformsLib.js';
-export { UniformsUtils } from './renderers/shaders/UniformsUtils.js';
 export { ShaderChunk } from './renderers/shaders/ShaderChunk.js';
 export { FogExp2 } from './scenes/FogExp2.js';
 export { Fog } from './scenes/Fog.js';

+ 1 - 1
src/animation/PropertyBinding.js

@@ -518,7 +518,7 @@ PropertyBinding.Composite.prototype = {
 
 PropertyBinding.create = function( root, path, parsedPath ) {
 
-	if ( ! ( (root && root.isAnimationObjectGroup) ) ) {
+	if ( ! ( root && root.isAnimationObjectGroup ) ) {
 
 		return new PropertyBinding( root, path, parsedPath );
 

+ 2 - 0
src/core/BufferAttribute.js

@@ -26,6 +26,8 @@ function BufferAttribute( array, itemSize, normalized ) {
 	this.dynamic = false;
 	this.updateRange = { offset: 0, count: - 1 };
 
+	this.onUpload = null;
+
 	this.version = 0;
 
 }

+ 4 - 4
src/core/BufferGeometry.js

@@ -294,7 +294,7 @@ Object.assign( BufferGeometry.prototype, EventDispatcher.prototype, {
 
 		var geometry = object.geometry;
 
-		if ( (object && object.isPoints) || (object && object.isLine) ) {
+		if ( object.isPoints || object.isLine ) {
 
 			var positions = new Float32Attribute( geometry.vertices.length * 3, 3 );
 			var colors = new Float32Attribute( geometry.colors.length * 3, 3 );
@@ -322,9 +322,9 @@ Object.assign( BufferGeometry.prototype, EventDispatcher.prototype, {
 
 			}
 
-		} else if ( (object && object.isMesh) ) {
+		} else if ( object.isMesh ) {
 
-			if ( (geometry && geometry.isGeometry) ) {
+			if ( geometry && geometry.isGeometry ) {
 
 				this.fromGeometry( geometry );
 
@@ -340,7 +340,7 @@ Object.assign( BufferGeometry.prototype, EventDispatcher.prototype, {
 
 		var geometry = object.geometry;
 
-		if ( (object && object.isMesh) ) {
+		if ( object.isMesh ) {
 
 			var direct = geometry.__directGeometry;
 

+ 1 - 1
src/extras/helpers/BoxHelper.js

@@ -38,7 +38,7 @@ BoxHelper.prototype.update = ( function () {
 
 	return function update( object ) {
 
-		if ( (object && object.isBox3) ) {
+		if ( object && object.isBox3 ) {
 
 			box.copy( object );
 

+ 1 - 1
src/extras/helpers/FaceNormalsHelper.js

@@ -28,7 +28,7 @@ function FaceNormalsHelper( object, size, hex, linewidth ) {
 
 	var objGeometry = this.object.geometry;
 
-	if ( (objGeometry && objGeometry.isGeometry) ) {
+	if ( objGeometry && objGeometry.isGeometry ) {
 
 		nNormals = objGeometry.faces.length;
 

+ 3 - 3
src/extras/helpers/SkeletonHelper.js

@@ -23,7 +23,7 @@ function SkeletonHelper( object ) {
 
 		var bone = this.bones[ i ];
 
-		if ( (bone.parent && bone.parent.isBone) ) {
+		if ( bone.parent && bone.parent.isBone ) {
 
 			geometry.vertices.push( new Vector3() );
 			geometry.vertices.push( new Vector3() );
@@ -57,7 +57,7 @@ SkeletonHelper.prototype.getBoneList = function( object ) {
 
 	var boneList = [];
 
-	if ( (object && object.isBone) ) {
+	if ( object && object.isBone ) {
 
 		boneList.push( object );
 
@@ -87,7 +87,7 @@ SkeletonHelper.prototype.update = function () {
 
 		var bone = this.bones[ i ];
 
-		if ( (bone.parent && bone.parent.isBone) ) {
+		if ( bone.parent && bone.parent.isBone ) {
 
 			boneMatrix.multiplyMatrices( matrixWorldInv, bone.matrixWorld );
 			geometry.vertices[ j ].setFromMatrixPosition( boneMatrix );

+ 4 - 4
src/extras/helpers/VertexNormalsHelper.js

@@ -26,11 +26,11 @@ function VertexNormalsHelper( object, size, hex, linewidth ) {
 
 	var objGeometry = this.object.geometry;
 
-	if ( (objGeometry && objGeometry.isGeometry) ) {
+	if ( objGeometry && objGeometry.isGeometry ) {
 
 		nNormals = objGeometry.faces.length * 3;
 
-	} else if ( (objGeometry && objGeometry.isBufferGeometry) ) {
+	} else if ( objGeometry && objGeometry.isBufferGeometry ) {
 
 		nNormals = objGeometry.attributes.normal.count;
 
@@ -79,7 +79,7 @@ VertexNormalsHelper.prototype.update = ( function () {
 
 		var objGeometry = this.object.geometry;
 
-		if ( (objGeometry && objGeometry.isGeometry) ) {
+		if ( objGeometry && objGeometry.isGeometry ) {
 
 			var vertices = objGeometry.vertices;
 
@@ -113,7 +113,7 @@ VertexNormalsHelper.prototype.update = ( function () {
 
 			}
 
-		} else if ( (objGeometry && objGeometry.isBufferGeometry) ) {
+		} else if ( objGeometry && objGeometry.isBufferGeometry ) {
 
 			var objPos = objGeometry.attributes.position;
 

+ 1 - 1
src/geometries/EdgesGeometry.js

@@ -27,7 +27,7 @@ function EdgesGeometry( geometry, thresholdAngle ) {
 
 	var geometry2;
 
-	if ( (geometry && geometry.isBufferGeometry) ) {
+	if ( geometry.isBufferGeometry ) {
 
 		geometry2 = new Geometry();
 		geometry2.fromBufferGeometry( geometry );

+ 2 - 2
src/geometries/WireframeGeometry.js

@@ -19,7 +19,7 @@ function WireframeGeometry( geometry ) {
 
 	var keys = [ 'a', 'b', 'c' ];
 
-	if ( (geometry && geometry.isGeometry) ) {
+	if ( geometry && geometry.isGeometry ) {
 
 		var vertices = geometry.vertices;
 		var faces = geometry.faces;
@@ -72,7 +72,7 @@ function WireframeGeometry( geometry ) {
 
 		this.addAttribute( 'position', new BufferAttribute( coords, 3 ) );
 
-	} else if ( (geometry && geometry.isBufferGeometry) ) {
+	} else if ( geometry && geometry.isBufferGeometry ) {
 
 		if ( geometry.index !== null ) {
 

+ 15 - 15
src/materials/Material.js

@@ -104,7 +104,7 @@ Material.prototype = {
 
 			}
 
-			if ( (currentValue && currentValue.isColor) ) {
+			if ( currentValue && currentValue.isColor ) {
 
 				currentValue.set( newValue );
 
@@ -154,44 +154,44 @@ Material.prototype = {
 
 		if ( this.name !== '' ) data.name = this.name;
 
-		if ( (this.color && this.color.isColor) ) data.color = this.color.getHex();
+		if ( this.color && this.color.isColor ) data.color = this.color.getHex();
 
 		if ( this.roughness !== undefined ) data.roughness = this.roughness;
 		if ( this.metalness !== undefined ) data.metalness = this.metalness;
 
-		if ( (this.emissive && this.emissive.isColor) ) data.emissive = this.emissive.getHex();
-		if ( (this.specular && this.specular.isColor) ) data.specular = this.specular.getHex();
+		if ( this.emissive && this.emissive.isColor ) data.emissive = this.emissive.getHex();
+		if ( this.specular && this.specular.isColor ) data.specular = this.specular.getHex();
 		if ( this.shininess !== undefined ) data.shininess = this.shininess;
 
-		if ( (this.map && this.map.isTexture) ) data.map = this.map.toJSON( meta ).uuid;
-		if ( (this.alphaMap && this.alphaMap.isTexture) ) data.alphaMap = this.alphaMap.toJSON( meta ).uuid;
-		if ( (this.lightMap && this.lightMap.isTexture) ) data.lightMap = this.lightMap.toJSON( meta ).uuid;
-		if ( (this.bumpMap && this.bumpMap.isTexture) ) {
+		if ( this.map && this.map.isTexture ) data.map = this.map.toJSON( meta ).uuid;
+		if ( this.alphaMap && this.alphaMap.isTexture ) data.alphaMap = this.alphaMap.toJSON( meta ).uuid;
+		if ( this.lightMap && this.lightMap.isTexture ) data.lightMap = this.lightMap.toJSON( meta ).uuid;
+		if ( this.bumpMap && this.bumpMap.isTexture ) {
 
 			data.bumpMap = this.bumpMap.toJSON( meta ).uuid;
 			data.bumpScale = this.bumpScale;
 
 		}
-		if ( (this.normalMap && this.normalMap.isTexture) ) {
+		if ( this.normalMap && this.normalMap.isTexture ) {
 
 			data.normalMap = this.normalMap.toJSON( meta ).uuid;
 			data.normalScale = this.normalScale.toArray();
 
 		}
-		if ( (this.displacementMap && this.displacementMap.isTexture) ) {
+		if ( this.displacementMap && this.displacementMap.isTexture ) {
 
 			data.displacementMap = this.displacementMap.toJSON( meta ).uuid;
 			data.displacementScale = this.displacementScale;
 			data.displacementBias = this.displacementBias;
 
 		}
-		if ( (this.roughnessMap && this.roughnessMap.isTexture) ) data.roughnessMap = this.roughnessMap.toJSON( meta ).uuid;
-		if ( (this.metalnessMap && this.metalnessMap.isTexture) ) data.metalnessMap = this.metalnessMap.toJSON( meta ).uuid;
+		if ( this.roughnessMap && this.roughnessMap.isTexture ) data.roughnessMap = this.roughnessMap.toJSON( meta ).uuid;
+		if ( this.metalnessMap && this.metalnessMap.isTexture ) data.metalnessMap = this.metalnessMap.toJSON( meta ).uuid;
 
-		if ( (this.emissiveMap && this.emissiveMap.isTexture) ) data.emissiveMap = this.emissiveMap.toJSON( meta ).uuid;
-		if ( (this.specularMap && this.specularMap.isTexture) ) data.specularMap = this.specularMap.toJSON( meta ).uuid;
+		if ( this.emissiveMap && this.emissiveMap.isTexture ) data.emissiveMap = this.emissiveMap.toJSON( meta ).uuid;
+		if ( this.specularMap && this.specularMap.isTexture ) data.specularMap = this.specularMap.toJSON( meta ).uuid;
 
-		if ( (this.envMap && this.envMap.isTexture) ) {
+		if ( this.envMap && this.envMap.isTexture ) {
 
 			data.envMap = this.envMap.toJSON( meta ).uuid;
 			data.reflectivity = this.reflectivity; // Scale behind envMap

+ 9 - 0
src/materials/MeshBasicMaterial.js

@@ -11,6 +11,9 @@ import { Color } from '../math/Color';
  *  opacity: <float>,
  *  map: new THREE.Texture( <Image> ),
  *
+ *  lightMap: new THREE.Texture( <Image> ),
+ *  lightMapIntensity: <float>
+ *
  *  aoMap: new THREE.Texture( <Image> ),
  *  aoMapIntensity: <float>
  *
@@ -45,6 +48,9 @@ function MeshBasicMaterial( parameters ) {
 
 	this.map = null;
 
+	this.lightMap = null;
+	this.lightMapIntensity = 1.0;
+
 	this.aoMap = null;
 	this.aoMapIntensity = 1.0;
 
@@ -84,6 +90,9 @@ MeshBasicMaterial.prototype.copy = function ( source ) {
 
 	this.map = source.map;
 
+	this.lightMap = source.lightMap;
+	this.lightMapIntensity = source.lightMapIntensity;
+
 	this.aoMap = source.aoMap;
 	this.aoMapIntensity = source.aoMapIntensity;
 

+ 1 - 2
src/materials/ShaderMaterial.js

@@ -1,5 +1,4 @@
 import { Material } from './Material';
-import { UniformsUtils } from '../renderers/shaders/UniformsUtils';
 
 /**
  * @author alteredq / http://alteredqualia.com/
@@ -90,7 +89,7 @@ ShaderMaterial.prototype.copy = function ( source ) {
 	this.fragmentShader = source.fragmentShader;
 	this.vertexShader = source.vertexShader;
 
-	this.uniforms = UniformsUtils.clone( source.uniforms );
+	this.uniforms = Object.assign( {}, source.uniforms );
 
 	this.defines = source.defines;
 

+ 3 - 4
src/materials/ShadowMaterial.js

@@ -1,7 +1,6 @@
 import { ShaderMaterial } from './ShaderMaterial';
 import { ShaderChunk } from '../renderers/shaders/ShaderChunk';
 import { UniformsLib } from '../renderers/shaders/UniformsLib';
-import { UniformsUtils } from '../renderers/shaders/UniformsUtils';
 
 /**
  * @author mrdoob / http://mrdoob.com/
@@ -10,12 +9,12 @@ import { UniformsUtils } from '../renderers/shaders/UniformsUtils';
 function ShadowMaterial() {
 
 	ShaderMaterial.call( this, {
-		uniforms: UniformsUtils.merge( [
-			UniformsLib[ "lights" ],
+		uniforms: Object.assign( {},
+			UniformsLib.lights,
 			{
 				opacity: { value: 1.0 }
 			}
-		] ),
+		),
 		vertexShader: ShaderChunk[ 'shadow_vert' ],
 		fragmentShader: ShaderChunk[ 'shadow_frag' ]
 	} );

+ 3 - 3
src/math/Box3.js

@@ -111,7 +111,7 @@ Box3.prototype = {
 
 				if ( geometry !== undefined ) {
 
-					if ( (geometry && geometry.isGeometry) ) {
+					if ( geometry.isGeometry ) {
 
 						var vertices = geometry.vertices;
 
@@ -124,7 +124,7 @@ Box3.prototype = {
 
 						}
 
-					} else if ( (geometry && geometry.isBufferGeometry) ) {
+					} else if ( geometry.isBufferGeometry ) {
 
 						var attribute = geometry.attributes.position;
 
@@ -132,7 +132,7 @@ Box3.prototype = {
 
 							var array, offset, stride;
 
-							if ( (attribute && attribute.isInterleavedBufferAttribute) ) {
+							if ( attribute.isInterleavedBufferAttribute ) {
 
 								array = attribute.data.array;
 								offset = attribute.offset;

+ 1 - 1
src/math/Color.js

@@ -27,7 +27,7 @@ Color.prototype = {
 
 	set: function ( value ) {
 
-		if ( (value && value.isColor) ) {
+		if ( value && value.isColor ) {
 
 			this.copy( value );
 

+ 1 - 1
src/math/Matrix3.js

@@ -173,7 +173,7 @@ Matrix3.prototype = {
 
 	getInverse: function ( matrix, throwOnDegenerate ) {
 
-		if ( (matrix && matrix.isMatrix4) ) {
+		if ( matrix && matrix.isMatrix4 ) {
 
 			console.error( "THREE.Matrix3.getInverse no longer takes a Matrix4 argument." );
 

+ 2 - 2
src/objects/Line.js

@@ -69,7 +69,7 @@ Line.prototype = Object.assign( Object.create( Object3D.prototype ), {
 			var interRay = new Vector3();
 			var step = (this && this.isLineSegments) ? 2 : 1;
 
-			if ( (geometry && geometry.isBufferGeometry) ) {
+			if ( geometry.isBufferGeometry ) {
 
 				var index = geometry.index;
 				var attributes = geometry.attributes;
@@ -146,7 +146,7 @@ Line.prototype = Object.assign( Object.create( Object3D.prototype ), {
 
 				}
 
-			} else if ( (geometry && geometry.isGeometry) ) {
+			} else if ( geometry.isGeometry ) {
 
 				var vertices = geometry.vertices;
 				var nbVertices = vertices.length;

+ 2 - 2
src/objects/Mesh.js

@@ -204,7 +204,7 @@ Mesh.prototype = Object.assign( Object.create( Object3D.prototype ), {
 
 			var uvs, intersection;
 
-			if ( (geometry && geometry.isBufferGeometry) ) {
+			if ( geometry.isBufferGeometry ) {
 
 				var a, b, c;
 				var index = geometry.index;
@@ -260,7 +260,7 @@ Mesh.prototype = Object.assign( Object.create( Object3D.prototype ), {
 
 				}
 
-			} else if ( (geometry && geometry.isGeometry) ) {
+			} else if ( geometry.isGeometry ) {
 
 				var fvA, fvB, fvC;
 				var isFaceMaterial = (material && material.isMultiMaterial);

+ 1 - 1
src/objects/Points.js

@@ -86,7 +86,7 @@ Points.prototype = Object.assign( Object.create( Object3D.prototype ), {
 
 			}
 
-			if ( (geometry && geometry.isBufferGeometry) ) {
+			if ( geometry.isBufferGeometry ) {
 
 				var index = geometry.index;
 				var attributes = geometry.attributes;

+ 1 - 1
src/objects/Skeleton.js

@@ -128,7 +128,7 @@ Object.assign( Skeleton.prototype, {
 
 			if ( bone ) {
 
-				if ( (bone.parent && bone.parent.isBone) ) {
+				if ( bone.parent && bone.parent.isBone ) {
 
 					bone.matrix.getInverse( bone.parent.matrixWorld );
 					bone.matrix.multiply( bone.matrixWorld );

+ 2 - 2
src/objects/SkinnedMesh.js

@@ -105,7 +105,7 @@ SkinnedMesh.prototype = Object.assign( Object.create( Mesh.prototype ), {
 
 	normalizeSkinWeights: function () {
 
-		if ( (this.geometry && this.geometry.isGeometry) ) {
+		if ( this.geometry && this.geometry.isGeometry ) {
 
 			for ( var i = 0; i < this.geometry.skinWeights.length; i ++ ) {
 
@@ -125,7 +125,7 @@ SkinnedMesh.prototype = Object.assign( Object.create( Mesh.prototype ), {
 
 			}
 
-		} else if ( (this.geometry && this.geometry.isBufferGeometry) ) {
+		} else if ( this.geometry && this.geometry.isBufferGeometry ) {
 
 			var vec = new Vector4();
 

+ 15 - 62
src/renderers/WebGLRenderer.js

@@ -1,7 +1,6 @@
 import { REVISION, MaxEquation, MinEquation, RGB_ETC1_Format, RGBA_PVRTC_2BPPV1_Format, RGBA_PVRTC_4BPPV1_Format, RGB_PVRTC_2BPPV1_Format, RGB_PVRTC_4BPPV1_Format, RGBA_S3TC_DXT5_Format, RGBA_S3TC_DXT3_Format, RGBA_S3TC_DXT1_Format, RGB_S3TC_DXT1_Format, SrcAlphaSaturateFactor, OneMinusDstColorFactor, DstColorFactor, OneMinusDstAlphaFactor, DstAlphaFactor, OneMinusSrcAlphaFactor, SrcAlphaFactor, OneMinusSrcColorFactor, SrcColorFactor, OneFactor, ZeroFactor, ReverseSubtractEquation, SubtractEquation, AddEquation, DepthFormat, DepthStencilFormat, LuminanceAlphaFormat, LuminanceFormat, RGBAFormat, RGBFormat, AlphaFormat, HalfFloatType, FloatType, UnsignedIntType, IntType, UnsignedShortType, ShortType, ByteType, UnsignedInt248Type, UnsignedShort565Type, UnsignedShort5551Type, UnsignedShort4444Type, UnsignedByteType, LinearMipMapLinearFilter, LinearMipMapNearestFilter, LinearFilter, NearestMipMapLinearFilter, NearestMipMapNearestFilter, NearestFilter, MirroredRepeatWrapping, ClampToEdgeWrapping, RepeatWrapping, FrontFaceDirectionCW, NoBlending, BackSide, DoubleSide, TriangleFanDrawMode, TriangleStripDrawMode, TrianglesDrawMode, NoColors, FlatShading, LinearToneMapping } from '../constants';
 import { Matrix4 } from '../math/Matrix4';
 import { WebGLUniforms } from './webgl/WebGLUniforms';
-import { UniformsUtils } from './shaders/UniformsUtils';
 import { ShaderLib } from './shaders/ShaderLib';
 import { LensFlarePlugin } from './webgl/plugins/LensFlarePlugin';
 import { SpritePlugin } from './webgl/plugins/SpritePlugin';
@@ -933,46 +932,14 @@ function WebGLRenderer( parameters ) {
 
 				if ( geometryAttribute !== undefined ) {
 
-					var type = _gl.FLOAT;
-					var array = geometryAttribute.array;
 					var normalized = geometryAttribute.normalized;
+					var size = geometryAttribute.itemSize;
 
-					if ( array instanceof Float32Array ) {
-
-						type = _gl.FLOAT;
-
-					} else if ( array instanceof Float64Array ) {
-
-						console.warn( "Unsupported data buffer format: Float64Array" );
-
-					} else if ( array instanceof Uint16Array ) {
-
-						type = _gl.UNSIGNED_SHORT;
-
-					} else if ( array instanceof Int16Array ) {
-
-						type = _gl.SHORT;
-
-					} else if ( array instanceof Uint32Array ) {
-
-						type = _gl.UNSIGNED_INT;
-
-					} else if ( array instanceof Int32Array ) {
-
-						type = _gl.INT;
-
-					} else if ( array instanceof Int8Array ) {
-
-						type = _gl.BYTE;
-
-					} else if ( array instanceof Uint8Array ) {
-
-						type = _gl.UNSIGNED_BYTE;
-
-					}
+					var attributeProperties = objects.getAttributeProperties( geometryAttribute );
 
-					var size = geometryAttribute.itemSize;
-					var buffer = objects.getAttributeBuffer( geometryAttribute );
+					var buffer = attributeProperties.__webglBuffer;
+					var type = attributeProperties.type;
+					var bytesPerElement = attributeProperties.bytesPerElement;
 
 					if ( geometryAttribute.isInterleavedBufferAttribute ) {
 
@@ -997,7 +964,7 @@ function WebGLRenderer( parameters ) {
 						}
 
 						_gl.bindBuffer( _gl.ARRAY_BUFFER, buffer );
-						_gl.vertexAttribPointer( programAttribute, size, type, normalized, stride * data.array.BYTES_PER_ELEMENT, ( startIndex * stride + offset ) * data.array.BYTES_PER_ELEMENT );
+						_gl.vertexAttribPointer( programAttribute, size, type, normalized, stride * bytesPerElement, ( startIndex * stride + offset ) * bytesPerElement );
 
 					} else {
 
@@ -1018,7 +985,7 @@ function WebGLRenderer( parameters ) {
 						}
 
 						_gl.bindBuffer( _gl.ARRAY_BUFFER, buffer );
-						_gl.vertexAttribPointer( programAttribute, size, type, normalized, 0, startIndex * size * geometryAttribute.array.BYTES_PER_ELEMENT );
+						_gl.vertexAttribPointer( programAttribute, size, type, normalized, 0, startIndex * size * bytesPerElement );
 
 					}
 
@@ -1566,7 +1533,7 @@ function WebGLRenderer( parameters ) {
 
 				materialProperties.__webglShader = {
 					name: material.type,
-					uniforms: UniformsUtils.clone( shader.uniforms ),
+					uniforms: Object.assign( {}, shader.uniforms ),
 					vertexShader: shader.vertexShader,
 					fragmentShader: shader.fragmentShader
 				};
@@ -1978,6 +1945,13 @@ function WebGLRenderer( parameters ) {
 		uniforms.specularMap.value = material.specularMap;
 		uniforms.alphaMap.value = material.alphaMap;
 
+		if ( material.lightMap ) {
+
+			uniforms.lightMap.value = material.lightMap;
+			uniforms.lightMapIntensity.value = material.lightMapIntensity;
+
+		}
+
 		if ( material.aoMap ) {
 
 			uniforms.aoMap.value = material.aoMap;
@@ -2116,13 +2090,6 @@ function WebGLRenderer( parameters ) {
 
 	function refreshUniformsLambert( uniforms, material ) {
 
-		if ( material.lightMap ) {
-
-			uniforms.lightMap.value = material.lightMap;
-			uniforms.lightMapIntensity.value = material.lightMapIntensity;
-
-		}
-
 		if ( material.emissiveMap ) {
 
 			uniforms.emissiveMap.value = material.emissiveMap;
@@ -2136,13 +2103,6 @@ function WebGLRenderer( parameters ) {
 		uniforms.specular.value = material.specular;
 		uniforms.shininess.value = Math.max( material.shininess, 1e-4 ); // to prevent pow( 0.0, 0.0 )
 
-		if ( material.lightMap ) {
-
-			uniforms.lightMap.value = material.lightMap;
-			uniforms.lightMapIntensity.value = material.lightMapIntensity;
-
-		}
-
 		if ( material.emissiveMap ) {
 
 			uniforms.emissiveMap.value = material.emissiveMap;
@@ -2190,13 +2150,6 @@ function WebGLRenderer( parameters ) {
 
 		}
 
-		if ( material.lightMap ) {
-
-			uniforms.lightMap.value = material.lightMap;
-			uniforms.lightMapIntensity.value = material.lightMapIntensity;
-
-		}
-
 		if ( material.emissiveMap ) {
 
 			uniforms.emissiveMap.value = material.emissiveMap;

+ 17 - 42
src/renderers/shaders/ShaderLib.js

@@ -1,5 +1,4 @@
 import { ShaderChunk } from './ShaderChunk';
-import { UniformsUtils } from './UniformsUtils';
 import { Vector3 } from '../../math/Vector3';
 import { UniformsLib } from './UniformsLib';
 import { Color } from '../../math/Color';
@@ -14,13 +13,12 @@ var ShaderLib = {
 
 	basic: {
 
-		uniforms: UniformsUtils.merge( [
-
+		uniforms: Object.assign( {},
 			UniformsLib.common,
 			UniformsLib.aomap,
+			UniformsLib.lightmap,
 			UniformsLib.fog
-
-		] ),
+		),
 
 		vertexShader: ShaderChunk.meshbasic_vert,
 		fragmentShader: ShaderChunk.meshbasic_frag
@@ -29,20 +27,17 @@ var ShaderLib = {
 
 	lambert: {
 
-		uniforms: UniformsUtils.merge( [
-
+		uniforms: Object.assign( {},
 			UniformsLib.common,
 			UniformsLib.aomap,
 			UniformsLib.lightmap,
 			UniformsLib.emissivemap,
 			UniformsLib.fog,
 			UniformsLib.lights,
-
 			{
 				emissive : { value: new Color( 0x000000 ) }
 			}
-
-		] ),
+		),
 
 		vertexShader: ShaderChunk.meshlambert_vert,
 		fragmentShader: ShaderChunk.meshlambert_frag
@@ -51,8 +46,7 @@ var ShaderLib = {
 
 	phong: {
 
-		uniforms: UniformsUtils.merge( [
-
+		uniforms: Object.assign( {},
 			UniformsLib.common,
 			UniformsLib.aomap,
 			UniformsLib.lightmap,
@@ -62,14 +56,12 @@ var ShaderLib = {
 			UniformsLib.displacementmap,
 			UniformsLib.fog,
 			UniformsLib.lights,
-
 			{
 				emissive : { value: new Color( 0x000000 ) },
 				specular : { value: new Color( 0x111111 ) },
 				shininess: { value: 30 }
 			}
-
-		] ),
+		),
 
 		vertexShader: ShaderChunk.meshphong_vert,
 		fragmentShader: ShaderChunk.meshphong_frag
@@ -78,8 +70,7 @@ var ShaderLib = {
 
 	standard: {
 
-		uniforms: UniformsUtils.merge( [
-
+		uniforms: Object.assign( {},
 			UniformsLib.common,
 			UniformsLib.aomap,
 			UniformsLib.lightmap,
@@ -91,15 +82,13 @@ var ShaderLib = {
 			UniformsLib.metalnessmap,
 			UniformsLib.fog,
 			UniformsLib.lights,
-
 			{
 				emissive : { value: new Color( 0x000000 ) },
 				roughness: { value: 0.5 },
 				metalness: { value: 0 },
 				envMapIntensity : { value: 1 }, // temporary
 			}
-
-		] ),
+		),
 
 		vertexShader: ShaderChunk.meshphysical_vert,
 		fragmentShader: ShaderChunk.meshphysical_frag
@@ -108,12 +97,10 @@ var ShaderLib = {
 
 	points: {
 
-		uniforms: UniformsUtils.merge( [
-
+		uniforms: Object.assign( {},
 			UniformsLib.points,
 			UniformsLib.fog
-
-		] ),
+		),
 
 		vertexShader: ShaderChunk.points_vert,
 		fragmentShader: ShaderChunk.points_frag
@@ -122,18 +109,15 @@ var ShaderLib = {
 
 	dashed: {
 
-		uniforms: UniformsUtils.merge( [
-
+		uniforms: Object.assign( {},
 			UniformsLib.common,
 			UniformsLib.fog,
-
 			{
 				scale    : { value: 1 },
 				dashSize : { value: 1 },
 				totalSize: { value: 2 }
 			}
-
-		] ),
+		),
 
 		vertexShader: ShaderChunk.linedashed_vert,
 		fragmentShader: ShaderChunk.linedashed_frag
@@ -142,12 +126,10 @@ var ShaderLib = {
 
 	depth: {
 
-		uniforms: UniformsUtils.merge( [
-
+		uniforms: Object.assign( {},
 			UniformsLib.common,
 			UniformsLib.displacementmap
-
-		] ),
+		),
 
 		vertexShader: ShaderChunk.depth_vert,
 		fragmentShader: ShaderChunk.depth_frag
@@ -157,9 +139,7 @@ var ShaderLib = {
 	normal: {
 
 		uniforms: {
-
 			opacity : { value: 1.0 }
-
 		},
 
 		vertexShader: ShaderChunk.normal_vert,
@@ -203,9 +183,7 @@ var ShaderLib = {
 	distanceRGBA: {
 
 		uniforms: {
-
 			lightPos: { value: new Vector3() }
-
 		},
 
 		vertexShader: ShaderChunk.distanceRGBA_vert,
@@ -217,16 +195,13 @@ var ShaderLib = {
 
 ShaderLib.physical = {
 
-	uniforms: UniformsUtils.merge( [
-
+	uniforms: Object.assign( {},
 		ShaderLib.standard.uniforms,
-
 		{
 			clearCoat: { value: 0 },
 			clearCoatRoughness: { value: 0 }
 		}
-
-	] ),
+	),
 
 	vertexShader: ShaderChunk.meshphysical_vert,
 	fragmentShader: ShaderChunk.meshphysical_frag

+ 16 - 5
src/renderers/shaders/ShaderLib/meshbasic_frag.glsl

@@ -14,6 +14,7 @@ uniform float opacity;
 #include <map_pars_fragment>
 #include <alphamap_pars_fragment>
 #include <aomap_pars_fragment>
+#include <lightmap_pars_fragment>
 #include <envmap_pars_fragment>
 #include <fog_pars_fragment>
 #include <specularmap_pars_fragment>
@@ -33,14 +34,24 @@ void main() {
 	#include <alphatest_fragment>
 	#include <specularmap_fragment>
 
-	ReflectedLight reflectedLight;
-	reflectedLight.directDiffuse = vec3( 0.0 );
-	reflectedLight.directSpecular = vec3( 0.0 );
-	reflectedLight.indirectDiffuse = diffuseColor.rgb;
-	reflectedLight.indirectSpecular = vec3( 0.0 );
+	ReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );
 
+	// accumulation (baked indirect lighting only)
+	#ifdef USE_LIGHTMAP
+
+		reflectedLight.indirectDiffuse += texture2D( lightMap, vUv2 ).xyz * lightMapIntensity;
+
+	#else
+
+		reflectedLight.indirectDiffuse += vec3( 1.0 );
+
+	#endif
+
+	// modulation
 	#include <aomap_fragment>
 
+	reflectedLight.indirectDiffuse *= diffuseColor.rgb;
+
 	vec3 outgoingLight = reflectedLight.indirectDiffuse;
 
 	#include <normal_flip>

+ 0 - 67
src/renderers/shaders/UniformsUtils.js

@@ -1,67 +0,0 @@
-/**
- * Uniform Utilities
- */
-
-var UniformsUtils = {
-
-	merge: function ( uniforms ) {
-
-		var merged = {};
-
-		for ( var u = 0; u < uniforms.length; u ++ ) {
-
-			var tmp = this.clone( uniforms[ u ] );
-
-			for ( var p in tmp ) {
-
-				merged[ p ] = tmp[ p ];
-
-			}
-
-		}
-
-		return merged;
-
-	},
-
-	clone: function ( uniforms_src ) {
-
-		var uniforms_dst = {};
-
-		for ( var u in uniforms_src ) {
-
-			uniforms_dst[ u ] = {};
-
-			for ( var p in uniforms_src[ u ] ) {
-
-				var parameter_src = uniforms_src[ u ][ p ];
-
-				if ( parameter_src && ( parameter_src.isColor ||
-					parameter_src.isMatrix3 || parameter_src.isMatrix4 ||
-					parameter_src.isVector2 || parameter_src.isVector3 || parameter_src.isVector4 ||
-					parameter_src.isTexture ) ) {
-
-					uniforms_dst[ u ][ p ] = parameter_src.clone();
-
-				} else if ( Array.isArray( parameter_src ) ) {
-
-					uniforms_dst[ u ][ p ] = parameter_src.slice();
-
-				} else {
-
-					uniforms_dst[ u ][ p ] = parameter_src;
-
-				}
-
-			}
-
-		}
-
-		return uniforms_dst;
-
-	}
-
-};
-
-
-export { UniformsUtils };

+ 58 - 0
src/renderers/webgl/WebGLObjects.js

@@ -85,8 +85,53 @@ function WebGLObjects( gl, properties, info ) {
 
 		gl.bufferData( bufferType, data.array, usage );
 
+		var type = gl.FLOAT;
+		var array = data.array;
+
+		if ( array instanceof Float32Array ) {
+
+			type = gl.FLOAT;
+
+		} else if ( array instanceof Float64Array ) {
+
+			console.warn( "Unsupported data buffer format: Float64Array" );
+
+		} else if ( array instanceof Uint16Array ) {
+
+			type = gl.UNSIGNED_SHORT;
+
+		} else if ( array instanceof Int16Array ) {
+
+			type = gl.SHORT;
+
+		} else if ( array instanceof Uint32Array ) {
+
+			type = gl.UNSIGNED_INT;
+
+		} else if ( array instanceof Int32Array ) {
+
+			type = gl.INT;
+
+		} else if ( array instanceof Int8Array ) {
+
+			type = gl.BYTE;
+
+		} else if ( array instanceof Uint8Array ) {
+
+			type = gl.UNSIGNED_BYTE;
+
+		}
+
+		attributeProperties.bytesPerElement = array.BYTES_PER_ELEMENT;
+		attributeProperties.type = type;
 		attributeProperties.version = data.version;
 
+		if ( data.onUpload !== null ) {
+
+			data.onUpload();
+
+		}
+
 	}
 
 	function updateBuffer( attributeProperties, data, bufferType ) {
@@ -132,6 +177,18 @@ function WebGLObjects( gl, properties, info ) {
 
 	}
 
+	function getAttributeProperties( attribute ) {
+
+		if ( attribute.isInterleavedBufferAttribute ) {
+
+			return properties.get( attribute.data );
+
+		}
+
+		return properties.get( attribute );
+
+	}
+
 	function getWireframeAttribute( geometry ) {
 
 		var property = properties.get( geometry );
@@ -197,6 +254,7 @@ function WebGLObjects( gl, properties, info ) {
 	return {
 
 		getAttributeBuffer: getAttributeBuffer,
+		getAttributeProperties: getAttributeProperties,
 		getWireframeAttribute: getWireframeAttribute,
 
 		update: update

+ 1 - 2
src/renderers/webgl/WebGLShadowMap.js

@@ -6,7 +6,6 @@
 import { FrontSide, BackSide, DoubleSide, RGBAFormat, NearestFilter, PCFShadowMap, RGBADepthPacking } from '../../constants';
 import { WebGLRenderTarget } from '../WebGLRenderTarget';
 import { ShaderMaterial } from '../../materials/ShaderMaterial';
-import { UniformsUtils } from '../shaders/UniformsUtils';
 import { ShaderLib } from '../shaders/ShaderLib';
 import { MeshDepthMaterial } from '../../materials/MeshDepthMaterial';
 import { Vector4 } from '../../math/Vector4';
@@ -64,7 +63,7 @@ function WebGLShadowMap( _renderer, _lights, _objects, capabilities ) {
 	depthMaterialTemplate.clipping = true;
 
 	var distanceShader = ShaderLib[ "distanceRGBA" ];
-	var distanceUniforms = UniformsUtils.clone( distanceShader.uniforms );
+	var distanceUniforms = Object.assign( {}, distanceShader.uniforms );
 
 	for ( var i = 0; i !== _NumberOfMaterialVariants; ++ i ) {
 

+ 0 - 1
src/textures/Texture.js

@@ -17,7 +17,6 @@ function Texture( image, mapping, wrapS, wrapT, magFilter, minFilter, format, ty
 	this.uuid = _Math.generateUUID();
 
 	this.name = '';
-	this.sourceFile = '';
 
 	this.image = image !== undefined ? image : Texture.DEFAULT_IMAGE;
 	this.mipmaps = [];

Daži faili netika attēloti, jo izmaiņu fails ir pārāk liels