Sfoglia il codice sorgente

Merge branch 'dev' into 91dev-shadercompile

sunag 7 anni fa
parent
commit
4f67097030
100 ha cambiato i file con 6126 aggiunte e 2677 eliminazioni
  1. 647 886
      build/three.js
  2. 307 330
      build/three.min.js
  3. 647 886
      build/three.module.js
  4. 1 4
      docs/api/animation/AnimationAction.html
  5. 4 7
      docs/api/cameras/Camera.html
  6. 0 3
      docs/api/core/BufferAttribute.html
  7. 3 2
      docs/api/core/BufferGeometry.html
  8. 0 21
      docs/api/core/DirectGeometry.html
  9. 10 14
      docs/api/core/Object3D.html
  10. 1 0
      docs/api/deprecated/DeprecatedList.html
  11. 9 9
      docs/api/math/Vector3.html
  12. 6 2
      docs/api/renderers/WebGLRenderer.html
  13. 1 1
      docs/api/renderers/shaders/ShaderChunk.html
  14. 51 0
      docs/examples/BufferGeometryUtils.html
  15. 4 2
      docs/examples/exporters/GLTFExporter.html
  16. 29 29
      docs/examples/loaders/GLTFLoader.html
  17. 1 0
      docs/list.js
  18. 3 0
      docs/manual/introduction/Useful-links.html
  19. 26 0
      editor/js/Menubar.File.js
  20. 34 0
      editor/js/Sidebar.Object.js
  21. 1 0
      editor/js/libs/ui.three.js
  22. 10 9
      examples/canvas_geometry_nurbs.html
  23. 2 2
      examples/canvas_geometry_shapes.html
  24. 4 2
      examples/canvas_lines.html
  25. 1 0
      examples/files.js
  26. 188 0
      examples/js/BufferGeometryUtils.js
  27. 23 1
      examples/js/controls/EditorControls.js
  28. 23 2
      examples/js/controls/OrbitControls.js
  29. 366 145
      examples/js/exporters/GLTFExporter.js
  30. 2 2
      examples/js/exporters/OBJExporter.js
  31. 7 12
      examples/js/loaders/ColladaLoader.js
  32. 730 72
      examples/js/loaders/EXRLoader.js
  33. 85 24
      examples/js/loaders/GLTFLoader.js
  34. 1 1
      examples/js/loaders/MMDLoader.js
  35. 2 4
      examples/js/loaders/OBJLoader.js
  36. 7 5
      examples/js/math/Lut.js
  37. 0 2
      examples/js/objects/Lensflare.js
  38. 2 1
      examples/js/objects/Sky.js
  39. 1 1
      examples/js/postprocessing/AdaptiveToneMappingPass.js
  40. 1 1
      examples/js/postprocessing/BokehPass.js
  41. 8 4
      examples/js/postprocessing/SAOPass.js
  42. 2 2
      examples/js/postprocessing/SMAAPass.js
  43. 1 1
      examples/js/postprocessing/ShaderPass.js
  44. 1 1
      examples/js/renderers/WebGLDeferredRenderer.js
  45. 10 1
      examples/js/vr/DaydreamController.js
  46. 10 1
      examples/js/vr/GearVRController.js
  47. 17 10
      examples/misc_controls_orbit.html
  48. 1 1
      examples/misc_controls_trackball.html
  49. 29 3
      examples/misc_exporter_gltf.html
  50. BIN
      examples/models/gltf/BotSkinned/glTF-MaterialsUnlit/AvatarBotA_Head_Tex_Combined.png
  51. BIN
      examples/models/gltf/BotSkinned/glTF-MaterialsUnlit/AvatarBotA_Tex_Combined.png
  52. 2265 0
      examples/models/gltf/BotSkinned/glTF-MaterialsUnlit/Bot_Skinned.gltf
  53. BIN
      examples/models/gltf/BotSkinned/glTF-MaterialsUnlit/buffer.bin
  54. BIN
      examples/textures/piz_compressed.exr
  55. 1 1
      examples/webgl_buffergeometry.html
  56. 1 1
      examples/webgl_buffergeometry_lines.html
  57. 1 1
      examples/webgl_buffergeometry_lines_indexed.html
  58. 1 1
      examples/webgl_buffergeometry_points.html
  59. 1 1
      examples/webgl_buffergeometry_points_interleaved.html
  60. 1 1
      examples/webgl_buffergeometry_uint.html
  61. 6 5
      examples/webgl_decals.html
  62. 1 1
      examples/webgl_effects_anaglyph.html
  63. 1 1
      examples/webgl_effects_parallaxbarrier.html
  64. 12 9
      examples/webgl_geometry_nurbs.html
  65. 1 1
      examples/webgl_interactive_buffergeometry.html
  66. 1 1
      examples/webgl_lights_pointlights2.html
  67. 1 1
      examples/webgl_lines_colors.html
  68. 14 1
      examples/webgl_loader_gltf_extensions.html
  69. 1 1
      examples/webgl_loader_nrrd.html
  70. 1 1
      examples/webgl_loader_texture_exr.html
  71. 1 1
      examples/webgl_loader_vrml.html
  72. 1 1
      examples/webgl_loader_vtk.html
  73. 1 1
      examples/webgl_materials_bumpmap.html
  74. 1 1
      examples/webgl_materials_cubemap_dynamic.html
  75. 378 0
      examples/webgl_materials_curvature.html
  76. 1 1
      examples/webgl_materials_envmaps_hdr.html
  77. 9 21
      examples/webgl_materials_modified.html
  78. 1 1
      examples/webgl_materials_normalmap.html
  79. 1 1
      examples/webgl_materials_shaders_fresnel.html
  80. 1 1
      examples/webgl_materials_skin.html
  81. 1 1
      examples/webgl_materials_video.html
  82. 1 1
      examples/webgl_multiple_renderers.html
  83. 1 1
      examples/webgl_performance_static.html
  84. 1 1
      examples/webgl_points_dynamic.html
  85. 1 1
      examples/webgl_postprocessing_advanced.html
  86. 1 1
      examples/webgl_postprocessing_backgrounds.html
  87. 1 1
      examples/webgl_postprocessing_dof.html
  88. 1 1
      examples/webgl_postprocessing_dof2.html
  89. 1 1
      examples/webgl_postprocessing_godrays.html
  90. 1 1
      examples/webgl_postprocessing_masking.html
  91. 1 1
      examples/webgl_postprocessing_outline.html
  92. 1 1
      examples/webgl_postprocessing_procedural.html
  93. 1 1
      examples/webgl_postprocessing_smaa.html
  94. 1 1
      examples/webgl_postprocessing_ssaa.html
  95. 1 1
      examples/webgl_postprocessing_ssaa_unbiased.html
  96. 1 1
      examples/webgl_postprocessing_ssao.html
  97. 1 1
      examples/webgl_postprocessing_taa.html
  98. 1 1
      examples/webgl_postprocessing_unreal_bloom.html
  99. 83 95
      examples/webgl_shaders_ocean.html
  100. 1 1
      examples/webgl_shadowmap_performance.html

File diff suppressed because it is too large
+ 647 - 886
build/three.js


File diff suppressed because it is too large
+ 307 - 330
build/three.min.js


File diff suppressed because it is too large
+ 647 - 886
build/three.module.js


+ 1 - 4
docs/api/animation/AnimationAction.html

@@ -91,10 +91,7 @@
 			The number of repetitions of the performed [page:AnimationClip] over the course of this action.
 			Can be set via [page:.setLoop setLoop]. Default is *Infinity*.<br /><br />
 			Setting this number has no effect, if the [page:.loop loop mode] is set to
-			[page:Animation THREE.LoopOnce].<br /><br />
-
-			Note: The first run is not taken into account. For example: if *repetition* is set to 2, the
-			total number of executed rounds will be 3.
+			[page:Animation THREE.LoopOnce].
 		</div>
 
 		<h3>[property:Number time]</h3>

+ 4 - 7
docs/api/cameras/Camera.html

@@ -69,16 +69,13 @@
 		Copy the properties from the source camera into this one.
 		</div>
 
-		<h3>[method:Vector3 getWorldDirection]( [param:Vector3 optionalTarget] )</h3>
+		<h3>[method:Vector3 getWorldDirection]( [param:Vector3 target] )</h3>
 		<div>
-		Returns a [page:Vector3] representing the world space direction in which the camera is looking.<br /><br />
 
-		Note: This is not the camera’s positive, but its negative z-axis, in contrast to
-		[page:Object3D.getWorldDirection getWorldDirection] of the base class (Object3D).<br /><br />
+		[page:Vector3 target] — the result will be copied into this Vector3. <br /><br />
 
-		If an [page:Vector3 optionalTarget] vector is specified, the result will be copied into this vector
-		(which can be reused in this way), otherwise a new vector will be created.
-		</div>
+		Returns a [page:Vector3] representing the world space direction in which the camera is looking.
+		(Note: A camera looks down its local, negative z-axis).<br /><br />
 
 		<h2>Source</h2>
 

+ 0 - 3
docs/api/core/BufferAttribute.html

@@ -140,9 +140,6 @@
 		<h3>[method:BufferAttribute copyColorsArray]( colors ) </h3>
 		<div>Copy an array representing RGB color values into [page:BufferAttribute.array array].</div>
 
-		<h3>[method:BufferAttribute copyIndicesArray]( indices ) </h3>
-		<div>Copy an array representing [page:Face3] indices into [page:BufferAttribute.array array].</div>
-
 		<h3>[method:BufferAttribute copyVector2sArray]( vectors ) </h3>
 		<div>Copy an array representing [page:Vector2]s into [page:BufferAttribute.array array].</div>
 

+ 3 - 2
docs/api/core/BufferGeometry.html

@@ -134,8 +134,9 @@
 
 			Each group is an object of the form:
 			<code>{ start: Integer, count: Integer, materialIndex: Integer }</code>
-			where start specifies the index of the first vertex in this draw call, count specifies
-			how many vertices are included, and materialIndex specifies the material array index to use.<br /><br />
+			where start specifies the first element in this draw call – the first vertex for non-indexed geometry,
+			otherwise the first triangle index. Count specifies how many vertices (or indices) are included, and
+			materialIndex specifies the material array index to use.<br /><br />
 
 			Use [page:.addGroup] to add groups, rather than modifying this array directly.
 		</div>

+ 0 - 21
docs/api/core/DirectGeometry.html

@@ -34,9 +34,6 @@
 		<h3>[property:Array type]</h3>
 		<div>String 'DirectGeometry'.</div>
 
-		<h3>[property:Array indices]</h3>
-		<div>Initialiased as an empty array, this is populated by [page:.fromGeometry]().</div>
-
 		<h3>[property:Array vertices]</h3>
 		<div>Initialiased as an empty array, this is populated by [page:.fromGeometry]().</div>
 
@@ -94,30 +91,12 @@
 
 		<h2>Methods</h2>
 
-		<h3>[page:EventDispatcher EventDispatcher] methods are available on this class.</h3>
-
-		<h3>[property:null computeBoundingBox](  )</h3>
-		<div>
-		 See [page:Geometry.computeBoundingBox].
-		</div>
-
-		<h3>[property:null computeBoundingSphere](  )</h3>
-		<div>
-		 See [page:Geometry.computeBoundingSphere].
-		</div>
-
 		<h3>[property:null computeGroups]( [page:Geometry geometry] )</h3>
 		<div>
 			Compute the parts of the geometry that have different materialIndex.
 			See [page:BufferGeometry.groups].
 		</div>
 
-		<h3>[method:null dispose]()</h3>
-		<div>
-		Disposes the object from memory. <br />
-		You need to call this when you want the directGeometry removed while the application is running.
-		</div>
-
 		<h3>[property:null fromGeometry]( [page:Geometry geometry] )</h3>
 		<div>Pass in a [page:Geometry] instance for conversion.</div>
 

+ 10 - 14
docs/api/core/Object3D.html

@@ -240,41 +240,37 @@
 		Searches through the object's children and returns the first with a property that matches the value given.
 		</div>
 
-		<h3>[method:Vector3 getWorldPosition]( [param:Vector3 optionalTarget] )</h3>
+		<h3>[method:Vector3 getWorldPosition]( [param:Vector3 target] )</h3>
 		<div>
-		optionalTarget — (optional) target to set the result. Otherwise, a new [page:Vector3] is instantiated. <br /><br />
+		[page:Vector3 target] — the result will be copied into this Vector3. <br /><br />
 
 		Returns a vector representing the position of the object in world space.
 		</div>
 
-		<h3>[method:Quaternion getWorldQuaternion]( [param:Quaternion optionalTarget] )</h3>
+		<h3>[method:Quaternion getWorldQuaternion]( [param:Quaternion target] )</h3>
 		<div>
-		optionalTarget — (optional) if specified, the result will be copied into this Quaternion,
-		otherwise a new Quaternion will be created. <br /><br />
+		[page:Quaternion target] — the result will be copied into this Quaternion. <br /><br />
 
 		Returns a quaternion representing the rotation of the object in world space.
 		</div>
 
-		<h3>[method:Euler getWorldRotation]( [param:Euler optionalTarget] )</h3>
+		<h3>[method:Euler getWorldRotation]( [param:Euler target] )</h3>
 		<div>
-		optionalTarget — (optional) if specified, the result will be copied into this Euler,
-		otherwise a new Euler will be created. <br /><br />
+		[page:Euler target] — the result will be copied into this Euler. <br /><br />
 
 		Returns the euler angles representing the rotation of the object in world space.
 		</div>
 
-		<h3>[method:Vector3 getWorldScale]( [param:Vector3 optionalTarget] )</h3>
+		<h3>[method:Vector3 getWorldScale]( [param:Vector3 target] )</h3>
 		<div>
-		[page:Vector3 optionalTarget] — (optional) if specified, the result will be copied into this Vector3,
-		otherwise a new Vector3 will be created. <br /><br />
+		[page:Vector3 target] — the result will be copied into this Vector3. <br /><br />
 
 		Returns a vector of the scaling factors applied to the object for each axis in world space.
 		</div>
 
-		<h3>[method:Vector3 getWorldDirection]( [param:Vector3 optionalTarget] )</h3>
+		<h3>[method:Vector3 getWorldDirection]( [param:Vector3 target] )</h3>
 		<div>
-		[page:Vector3 optionalTarget] — (optional) if specified, the result will be copied into this Vector3,
-		otherwise a new Vector3 will be created. <br /><br />
+		[page:Vector3 target] — the result will be copied into this Vector3. <br /><br />
 
 		Returns a vector representing the direction of object's positive z-axis in world space.
 		</div>

+ 1 - 0
docs/api/deprecated/DeprecatedList.html

@@ -51,6 +51,7 @@
 
 		<h3>[page:BufferAttribute]</h3>
 		<div>BufferAttribute.length has been renamed to [page:BufferAttribute.count].</div>
+		<div>BufferAttribute.copyIndicesArray() has been removed.</div>
 
 
 		<h3>[page:DynamicBufferAttribute]</h3>

+ 9 - 9
docs/api/math/Vector3.html

@@ -273,15 +273,6 @@ var d = a.distanceTo( b );
 		- alpha = 0 will be [page:Vector3 v1], and alpha = 1 will be [page:Vector3 v2].
 		</div>
 
-		<h3>[method:Vector3 negate]()</h3>
-		<div>Inverts this vector - i.e. sets x = -x, y = -y and z = -z.</div>
-
-		<h3>[method:Vector3 normalize]()</h3>
-		<div>
-		Convert this vector to a [link:https://en.wikipedia.org/wiki/Unit_vector unit vector] - that is, sets it equal to the vector with the same direction
-		as this one, but [page:.length length] 1.
-		</div>
-
 		<h3>[method:Vector3 max]( [param:Vector3 v] )</h3>
 		<div>
 		If this vector's x, y or z value is less than [page:Vector3 v]'s x, y or z value, replace
@@ -303,6 +294,15 @@ var d = a.distanceTo( b );
 		<h3>[method:Vector3 multiplyVectors]( [param:Vector3 a], [param:Vector3 b] )</h3>
 		<div>Sets this vector equal to [page:Vector3 a] * [page:Vector3 b], component-wise.</div>
 
+		<h3>[method:Vector3 negate]()</h3>
+		<div>Inverts this vector - i.e. sets x = -x, y = -y and z = -z.</div>
+
+		<h3>[method:Vector3 normalize]()</h3>
+		<div>
+		Convert this vector to a [link:https://en.wikipedia.org/wiki/Unit_vector unit vector] - that is, sets it equal to the vector with the same direction
+		as this one, but [page:.length length] 1.
+		</div>
+
 		<h3>[method:Vector3 project]( [param:Camera camera] )</h3>
 		<div>
 		[page:Camera camera] — camera to use in the projection.<br /><br />

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

@@ -180,9 +180,9 @@
 			<li>render:
 				<ul>
 					<li>calls</li>
-					<li>vertices</li>
-					<li>faces</li>
+					<li>triangles</li>
 					<li>points</li>
+					<li>lines</li>
 				</ul>
 			</li>
 			<li>programs
@@ -286,6 +286,10 @@
 		See [page:WebGLRenderer.capabilities capabilities.maxTextures].
 		</div>
 
+		<h3>[method:null animate]( [param:Function callback] )</h3>
+		<div>[page:Function callback] — The function will be called every available frame. If `null` is passed it will stop any already ongoing animation.</div>
+		<div>A build in function that can be used instead of [link:https://developer.mozilla.org/en-US/docs/Web/API/window/requestAnimationFrame requestAnimationFrame]. For WebVR projects this function must be used.</div>
+
 		<h3>[method:null clear]( [param:Boolean color], [param:Boolean depth], [param:Boolean stencil] )</h3>
 		<div>
 		Tells the renderer to clear its color, depth or stencil drawing buffer(s).

+ 1 - 1
docs/api/renderers/shaders/ShaderChunk.html

@@ -10,7 +10,7 @@
 	<body>
 		<h1>[name]</h1>
 
-		<div class="desc">Shader chunks for WebLG Shader library</div>
+		<div class="desc">Shader chunks for WebGL Shader library</div>
 
 
 

+ 51 - 0
docs/examples/BufferGeometryUtils.html

@@ -0,0 +1,51 @@
+<!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 [page:BufferGeometry BufferGeometry] instances.<br /><br />
+    </div>
+
+
+    <h2>Methods</h2>
+
+    <h3>[method:null computeTangents]( [param:BufferGeometry geometry] )</h3>
+    <div>
+    geometry -- A [page:BufferGeometry BufferGeometry] instance, which must have index, position, normal, and uv attributes.<br /><br />
+
+    Calculates and adds tangent attribute to a geometry.<br /><br />
+
+    </div>
+
+    <h3>[method:BufferGeometry mergeBufferGeometries]( [param:Array geometries] )</h3>
+    <div>
+    geometries -- Array of [page:BufferGeometry BufferGeometry] instances.<br /><br />
+
+    Merges a set of geometries into a single instance. All geometries must have compatible attributes.
+    If merge does not succeed, the method returns null.<br /><br />
+
+    </div>
+
+    <h3>[method:BufferAttribute mergeBufferAttributes]( [param:Array attributes] )</h3>
+    <div>
+    attributes -- Array of [page:BufferAttribute BufferAttribute] instances.<br /><br />
+
+    Merges a set of attributes into a single instance. All attributes must have compatible properties
+    and types, and [page:InterleavedBufferAttribute InterleavedBufferAttributes] are not supported. If merge does not succeed, the method
+    returns null.
+
+    </div>
+
+    <h2>Source</h2>
+
+    [link:https://github.com/mrdoob/three.js/blob/master/examples/js/BufferGeometryUtils.js examples/js/BufferGeometryUtils.js]
+  </body>
+</html>

+ 4 - 2
docs/examples/exporters/GLTFExporter.html

@@ -16,7 +16,7 @@
 		<a href="https://www.khronos.org/gltf">glTF</a> (GL Transmission Format) is an
 		<a href="https://github.com/KhronosGroup/glTF/tree/master/specification/2.0">open format specification</a>
 		for efficient delivery and loading of 3D content. Assets may be provided either in JSON (.gltf)
-		or binary (.glb) format. External files store textures (.jpg, .png, ...) and additional binary
+		or binary (.glb) format. External files store textures (.jpg, .png) and additional binary
 		data (.bin). A glTF asset may deliver one or more scenes, including meshes, materials,
 		textures, skins, skeletons, morph targets, animations, lights, and/or cameras.
 		</div>
@@ -80,7 +80,9 @@ exporter.parse( [ scene1, object1, object2, scene2 ], ...)
 			<li>truncateDrawRange - bool. Export just the attributes within the drawRange, if defined, instead of exporting the whole array. Default is true.</li>
 			<li>binary - bool. Export in binary (.glb) format, returning an ArrayBuffer. Default is false.</li>
 			<li>embedImages - bool. Export with images embedded into the glTF asset. Default is true.</li>
-			<li>animations - Array<[page:AnimationClip AnimationClip]>. List of animations to be included in the export.
+			<li>animations - Array<[page:AnimationClip AnimationClip]>. List of animations to be included in the export.</li>
+			<li>forceIndices - bool. Generate indices for non-index geometry and export with them. Default is false.</li>
+			<li>forcePowerOfTwoTextures - bool. Export with images resized to POT size. This option works only if embedImages is true. Default is false.</li>
 		</ul>
 		</div>
 		<div>

+ 29 - 29
docs/examples/loaders/GLTFLoader.html

@@ -15,7 +15,7 @@
 		<a href="https://www.khronos.org/gltf">glTF</a> (GL Transmission Format) is an
 		<a href="https://github.com/KhronosGroup/glTF/tree/master/specification/2.0">open format specification</a>
 		for efficient delivery and loading of 3D content. Assets may be provided either in JSON (.gltf)
-		or binary (.glb) format. External files store textures (.jpg, .png, ...) and additional binary
+		or binary (.glb) format. External files store textures (.jpg, .png) and additional binary
 		data (.bin). A glTF asset may deliver one or more scenes, including meshes, materials,
 		textures, skins, skeletons, morph targets, animations, lights, and/or cameras.
 		</div>
@@ -45,43 +45,43 @@
 		<h2>Example</h2>
 
 		<code>
-			// Instantiate a loader
-			var loader = new THREE.GLTFLoader();
+		// Instantiate a loader
+		var loader = new THREE.GLTFLoader();
 
-			// Optional: Provide a DRACOLoader instance to decode compressed mesh data
-			THREE.DRACOLoader.setDecoderPath( '/examples/js/libs/draco' );
-			loader.setDRACOLoader( new THREE.DRACOLoader() );
+		// Optional: Provide a DRACOLoader instance to decode compressed mesh data
+		THREE.DRACOLoader.setDecoderPath( '/examples/js/libs/draco' );
+		loader.setDRACOLoader( new THREE.DRACOLoader() );
 
-			// Load a glTF resource
-			loader.load(
-				// resource URL
-				'models/gltf/duck/duck.gltf',
-				// called when the resource is loaded
-				function ( gltf ) {
+		// Load a glTF resource
+		loader.load(
+			// resource URL
+			'models/gltf/duck/duck.gltf',
+			// called when the resource is loaded
+			function ( gltf ) {
 
-					scene.add( gltf.scene );
+				scene.add( gltf.scene );
 
-					gltf.animations; // Array&lt;THREE.AnimationClip&gt;
-					gltf.scene; // THREE.Scene
-					gltf.scenes; // Array&lt;THREE.Scene&gt;
-					gltf.cameras; // Array&lt;THREE.Camera&gt;
-					gltf.asset; // Object
+				gltf.animations; // Array&lt;THREE.AnimationClip&gt;
+				gltf.scene; // THREE.Scene
+				gltf.scenes; // Array&lt;THREE.Scene&gt;
+				gltf.cameras; // Array&lt;THREE.Camera&gt;
+				gltf.asset; // Object
 
-				},
-				// called when loading is in progresses
-				function ( xhr ) {
+			},
+			// called when loading is in progresses
+			function ( xhr ) {
 
-					console.log( ( xhr.loaded / xhr.total * 100 ) + '% loaded' );
+				console.log( ( xhr.loaded / xhr.total * 100 ) + '% loaded' );
 
-				},
-				// called when loading has errors
-				function ( error ) {
+			},
+			// called when loading has errors
+			function ( error ) {
 
-					console.log( 'An error happened' );
+				console.log( 'An error happened' );
 
-				}
-			);
-			</code>
+			}
+		);
+		</code>
 
 		[example:webgl_loader_gltf]
 

+ 1 - 0
docs/list.js

@@ -386,6 +386,7 @@ var list = {
 		},
 
 		"Utils": {
+			"BufferGeometryUtils": "examples/BufferGeometryUtils",
 			"SceneUtils": "examples/utils/SceneUtils"
 		}
 

+ 3 - 0
docs/manual/introduction/Useful-links.html

@@ -91,6 +91,9 @@
 
 		<h2>Examples</h2>
 		<ul>
+			<li>
+				[link:https://github.com/edwinwebb/three-seed/ three-seed] - three.js starter project with ES6 and Webpack
+			</li>
 			<li>
 				[link:http://stemkoski.github.io/Three.js/index.html Professor Stemkoskis Examples] - a collection of beginner friendly
 				examples built using three.js r60.

+ 26 - 0
editor/js/Menubar.File.js

@@ -184,6 +184,26 @@ Menubar.File = function ( editor ) {
 
 	options.add( new UI.HorizontalRule() );
 
+	// Export GLB
+
+	var option = new UI.Row();
+	option.setClass( 'option' );
+	option.setTextContent( 'Export GLB' );
+	option.onClick( function () {
+
+		var exporter = new THREE.GLTFExporter();
+
+		exporter.parse( editor.scene, function ( result ) {
+
+			saveArrayBuffer( result, 'scene.glb' );
+
+			// forceIndices: true, forcePowerOfTwoTextures: true
+			// to allow compatibility with facebook
+		}, { binary: true, forceIndices: true, forcePowerOfTwoTextures: true } );
+		
+	} );
+	options.add( option );
+
 	// Export GLTF
 
 	var option = new UI.Row();
@@ -352,6 +372,12 @@ Menubar.File = function ( editor ) {
 
 	}
 
+	function saveArrayBuffer( buffer, filename ) {
+
+		save( new Blob( [ buffer ], { type: 'application/octet-stream' } ), filename );
+
+	}
+
 	function saveString( text, filename ) {
 
 		save( new Blob( [ text ], { type: 'text/plain' } ), filename );

+ 34 - 0
editor/js/Sidebar.Object.js

@@ -259,6 +259,26 @@ Sidebar.Object = function ( editor ) {
 
 	container.add( objectVisibleRow );
 
+	// frustumCulled
+
+	var objectFrustumCulledRow = new UI.Row();
+	var objectFrustumCulled = new UI.Checkbox().onChange( update );
+
+	objectFrustumCulledRow.add( new UI.Text( 'Frustum Culled' ).setWidth( '90px' ) );
+	objectFrustumCulledRow.add( objectFrustumCulled );
+
+	container.add( objectFrustumCulledRow );
+
+	// renderOrder
+
+	var objectRenderOrderRow = new UI.Row();
+	var objectRenderOrder = new UI.Integer().setWidth( '50px' ).onChange( update );
+
+	objectRenderOrderRow.add( new UI.Text( 'Render Order' ).setWidth( '90px' ) );
+	objectRenderOrderRow.add( objectRenderOrder );
+
+	container.add( objectRenderOrderRow );
+
 	// user data
 
 	var timeout;
@@ -436,6 +456,18 @@ Sidebar.Object = function ( editor ) {
 
 			}
 
+			if ( object.frustumCulled !== objectFrustumCulled.getValue() ) {
+
+				editor.execute( new SetValueCommand( object, 'frustumCulled', objectFrustumCulled.getValue() ) );
+
+			}
+
+			if ( object.renderOrder !== objectRenderOrder.getValue() ) {
+
+				editor.execute( new SetValueCommand( object, 'renderOrder', objectRenderOrder.getValue() ) );
+
+			}
+
 			if ( object.castShadow !== undefined && object.castShadow !== objectCastShadow.getValue() ) {
 
 				editor.execute( new SetValueCommand( object, 'castShadow', objectCastShadow.getValue() ) );
@@ -654,6 +686,8 @@ Sidebar.Object = function ( editor ) {
 		}
 
 		objectVisible.setValue( object.visible );
+		objectFrustumCulled.setValue( object.frustumCulled );
+		objectRenderOrder.setValue( object.renderOrder );
 
 		try {
 

+ 1 - 0
editor/js/libs/ui.three.js

@@ -79,6 +79,7 @@ UI.Texture = function ( mapping ) {
 
 						var texture = new THREE.Texture( this, mapping );
 						texture.sourceFile = file.name;
+						texture.format = file.type === 'image/jpeg' ? THREE.RGBFormat : THREE.RGBAFormat;
 						texture.needsUpdate = true;
 
 						scope.setValue( texture );

+ 10 - 9
examples/canvas_geometry_nurbs.html

@@ -105,25 +105,26 @@
 
 				}
 
-				var nurbsCurve = new THREE.NURBSCurve(nurbsDegree, nurbsKnots, nurbsControlPoints);
+				var nurbsCurve = new THREE.NURBSCurve( nurbsDegree, nurbsKnots, nurbsControlPoints );
+
+				var nurbsGeometry = new THREE.BufferGeometry();
+				nurbsGeometry.setFromPoints( nurbsCurve.getPoints( 200 ) );
 
-				var nurbsGeometry = new THREE.Geometry();
-				nurbsGeometry.vertices = nurbsCurve.getPoints( 200 );
 				var nurbsMaterial = new THREE.LineBasicMaterial( { linewidth: 10, color: 0x333333 } );
 
 				var nurbsLine = new THREE.Line( nurbsGeometry, nurbsMaterial );
-				nurbsLine.position.set( 0, -100, 0 );
+				nurbsLine.position.set( 0, - 100, 0 );
+				group.add( nurbsLine );
+
+				var nurbsControlPointsGeometry = new THREE.BufferGeometry();
+				nurbsControlPointsGeometry.setFromPoints( nurbsCurve.controlPoints );
 
-				var nurbsControlPointsGeometry = new THREE.Geometry();
-				nurbsControlPointsGeometry.vertices = nurbsCurve.controlPoints;
 				var nurbsControlPointsMaterial = new THREE.LineBasicMaterial( { linewidth: 2, color: 0x333333, opacity: 0.25 } );
 
 				var nurbsControlPointsLine = new THREE.Line( nurbsControlPointsGeometry, nurbsControlPointsMaterial );
 				nurbsControlPointsLine.position.copy( nurbsLine.position );
 
-				group.add( nurbsLine, nurbsControlPointsLine );
-				// this also works:
-				// group.add( nurbsLine ).add( nurbsControlPointsLine );
+				group.add( nurbsControlPointsLine );
 
 				//
 

+ 2 - 2
examples/canvas_geometry_shapes.html

@@ -83,9 +83,9 @@
 					// line
 
 					var points = shape.getPoints();
-					var geometry = new THREE.Geometry().setFromPoints( points );
+					var geometry = new THREE.BufferGeometry().setFromPoints( points );
 
-					var material = new THREE.LineBasicMaterial( { linewidth: 10, color: 0x333333, transparent: true } );
+					var material = new THREE.LineBasicMaterial( { linewidth: 10, color: 0x333333 } );
 
 					var line = new THREE.Line( geometry, material );
 					line.position.set( x, y, z );

+ 4 - 2
examples/canvas_lines.html

@@ -73,7 +73,7 @@
 
 				} );
 
-				var geometry = new THREE.Geometry();
+				var points = [];
 
 				for ( var i = 0; i < 100; i ++ ) {
 
@@ -86,12 +86,14 @@
 					particle.scale.x = particle.scale.y = 10;
 					scene.add( particle );
 
-					geometry.vertices.push( particle.position );
+					points.push( particle.position );
 
 				}
 
 				// lines
 
+				var geometry = new THREE.BufferGeometry().setFromPoints( points );
+
 				var line = new THREE.Line( geometry, new THREE.LineBasicMaterial( { color: 0xffffff, opacity: 0.5 } ) );
 				scene.add( line );
 

+ 1 - 0
examples/files.js

@@ -152,6 +152,7 @@ var files = {
 		"webgl_materials_cubemap_dynamic",
 		"webgl_materials_cubemap_dynamic2",
 		"webgl_materials_cubemap_refraction",
+		"webgl_materials_curvature",
 		"webgl_materials_displacementmap",
 		"webgl_materials_envmaps",
 		"webgl_materials_envmaps_hdr",

+ 188 - 0
examples/js/BufferGeometryUtils.js

@@ -182,6 +182,194 @@ THREE.BufferGeometryUtils = {
 
 		}
 
+	},
+
+	/**
+	 * @param  {Array<THREE.BufferGeometry>} geometries
+	 * @return {THREE.BufferGeometry}
+	 */
+	mergeBufferGeometries: function ( geometries ) {
+
+		var isIndexed = geometries[ 0 ].index !== null;
+
+		var attributesUsed = new Set( Object.keys( geometries[ 0 ].attributes ) );
+		var morphAttributesUsed = new Set( Object.keys( geometries[ 0 ].morphAttributes ) );
+
+		var attributes = {};
+		var morphAttributes = {};
+
+		var mergedGeometry = new THREE.BufferGeometry();
+
+		for ( var i = 0; i < geometries.length; ++ i ) {
+
+			var geometry = geometries[ i ];
+
+			// ensure that all geometries are indexed, or none
+
+			if ( isIndexed !== ( geometry.index !== null ) ) return null;
+
+			// gather attributes, exit early if they're different
+
+			for ( var name in geometry.attributes ) {
+
+				if ( !attributesUsed.has( name ) ) return null;
+
+				if ( attributes[ name ] === undefined ) attributes[ name ] = [];
+
+				attributes[ name ].push( geometry.attributes[ name ] );
+
+			}
+
+			// gather morph attributes, exit early if they're different
+
+			for ( var name in geometry.morphAttributes ) {
+
+				if ( !morphAttributesUsed.has( name ) ) return null;
+
+				if ( morphAttributes[ name ] === undefined ) morphAttributes[ name ] = [];
+
+				morphAttributes[ name ].push( geometry.morphAttributes[ name ] );
+
+			}
+
+			// gather .userData
+
+			if ( geometry.userData !== undefined ) {
+
+				mergedGeometry.userData = mergedGeometry.userData || {};
+				mergedGeometry.userData.mergedUserData = mergedGeometry.userData.mergedUserData || [];
+				mergedGeometry.userData.mergedUserData.push( geometry.userData );
+
+			}
+
+		}
+
+		// merge indices
+
+		if ( isIndexed ) {
+
+			var indexOffset = 0;
+			var indexList = [];
+
+			for ( var i = 0; i < geometries.length; ++ i ) {
+
+				var index = geometries[ i ].index;
+
+				if ( indexOffset > 0 ) {
+
+					index = index.clone();
+
+					for ( var j = 0; j < index.count; ++ j ) {
+
+						index.setX( j, index.getX( j ) + indexOffset );
+
+					}
+
+				}
+
+				indexList.push( index );
+				indexOffset += geometries[ i ].attributes.position.count;
+
+			}
+
+			var mergedIndex = this.mergeBufferAttributes( indexList );
+
+			if ( !mergedIndex ) return null;
+
+			mergedGeometry.index = mergedIndex;
+
+		}
+
+		// merge attributes
+
+		for ( var name in attributes ) {
+
+			var mergedAttribute = this.mergeBufferAttributes( attributes[ name ] );
+
+			if ( ! mergedAttribute ) return null;
+
+			mergedGeometry.addAttribute( name, mergedAttribute );
+
+		}
+
+		// merge morph attributes
+
+		for ( var name in morphAttributes ) {
+
+			var numMorphTargets = morphAttributes[ name ][ 0 ].length;
+
+			if ( numMorphTargets === 0 ) break;
+
+			mergedGeometry.morphAttributes = mergedGeometry.morphAttributes || {};
+			mergedGeometry.morphAttributes[ name ] = [];
+
+			for ( var i = 0; i < numMorphTargets; ++ i ) {
+
+				var morphAttributesToMerge = [];
+
+				for ( var j = 0; j < morphAttributes[ name ].length; ++ j ) {
+
+					morphAttributesToMerge.push( morphAttributes[ name ][ j ][ i ] );
+
+				}
+
+				var mergedMorphAttribute = this.mergeBufferAttributes( morphAttributesToMerge );
+
+				if ( !mergedMorphAttribute ) return null;
+
+				mergedGeometry.morphAttributes[ name ].push( mergedMorphAttribute );
+
+			}
+
+		}
+
+		return mergedGeometry;
+
+	},
+
+	/**
+	 * @param {Array<THREE.BufferAttribute>} attributes
+	 * @return {THREE.BufferAttribute}
+	 */
+	mergeBufferAttributes: function ( attributes ) {
+
+		var TypedArray;
+		var itemSize;
+		var normalized;
+		var arrayLength = 0;
+
+		for ( var i = 0; i < attributes.length; ++ i ) {
+
+			var attribute = attributes[ i ];
+
+			if ( attribute.isInterleavedBufferAttribute ) return null;
+
+			if ( TypedArray === undefined ) TypedArray = attribute.array.constructor;
+			if ( TypedArray !== attribute.array.constructor ) return null;
+
+			if ( itemSize === undefined ) itemSize = attribute.itemSize;
+			if ( itemSize !== attribute.itemSize ) return null;
+
+			if ( normalized === undefined ) normalized = attribute.normalized;
+			if ( normalized !== attribute.normalized ) return null;
+
+			arrayLength += attribute.array.length;
+
+		}
+
+		var array = new TypedArray( arrayLength );
+		var offset = 0;
+
+		for ( var j = 0; j < attributes.length; ++ j ) {
+
+			array.set( attributes[ j ].array, offset );
+
+			offset += attributes[ j ].array.length;
+
+		}
+
+		return new THREE.BufferAttribute( array, itemSize, normalized );
+
 	}
 
 };

+ 23 - 1
examples/js/controls/EditorControls.js

@@ -38,7 +38,29 @@ THREE.EditorControls = function ( object, domElement ) {
 	this.focus = function ( target ) {
 
 		var box = new THREE.Box3().setFromObject( target );
-		object.lookAt( center.copy( box.getCenter() ) );
+
+		var distance;
+
+		if ( box.isEmpty() === false ) {
+
+			center.copy( box.getCenter() );
+			distance = box.getBoundingSphere().radius;
+
+		} else {
+
+			// Focusing on an Group, AmbientLight, etc
+
+			center.setFromMatrixPosition( target.matrixWorld );
+			distance = 0.1;
+
+		}
+
+		var delta = new THREE.Vector3( 0, 0, 1 );
+		delta.applyQuaternion( object.quaternion );
+		delta.multiplyScalar( distance * 4 );
+
+		object.position.copy( center ).add( delta );
+
 		scope.dispatchEvent( changeEvent );
 
 	};

+ 23 - 2
examples/js/controls/OrbitControls.js

@@ -59,6 +59,7 @@ THREE.OrbitControls = function ( object, domElement ) {
 
 	// Set to false to disable panning
 	this.enablePan = true;
+	this.panningMode = THREE.ScreenSpacePanning; // alternate THREE.HorizontalPanning
 	this.keyPanSpeed = 7.0;	// pixels moved per arrow key push
 
 	// Set to true to automatically rotate around the target
@@ -183,14 +184,17 @@ THREE.OrbitControls = function ( object, domElement ) {
 				sphericalDelta.theta *= ( 1 - scope.dampingFactor );
 				sphericalDelta.phi *= ( 1 - scope.dampingFactor );
 
+				panOffset.multiplyScalar( 1 - scope.dampingFactor );
+
 			} else {
 
 				sphericalDelta.set( 0, 0, 0 );
 
+				panOffset.set( 0, 0, 0 );
+
 			}
 
 			scale = 1;
-			panOffset.set( 0, 0, 0 );
 
 			// update condition is:
 			// min(camera displacement, camera rotation in radians)^2 > EPS
@@ -316,7 +320,21 @@ THREE.OrbitControls = function ( object, domElement ) {
 
 		return function panUp( distance, objectMatrix ) {
 
-			v.setFromMatrixColumn( objectMatrix, 1 ); // get Y column of objectMatrix
+			switch ( scope.panningMode ) {
+
+				case THREE.ScreenSpacePanning:
+
+					v.setFromMatrixColumn( objectMatrix, 1 );
+					break;
+
+				case THREE.HorizontalPanning:
+
+					v.setFromMatrixColumn( objectMatrix, 0 );
+					v.crossVectors( scope.object.up, v );
+					break;
+
+			}
+
 			v.multiplyScalar( distance );
 
 			panOffset.add( v );
@@ -1041,3 +1059,6 @@ Object.defineProperties( THREE.OrbitControls.prototype, {
 	}
 
 } );
+
+THREE.ScreenSpacePanning = 0;
+THREE.HorizontalPanning = 1;

+ 366 - 145
examples/js/exporters/GLTFExporter.js

@@ -1,5 +1,7 @@
 /**
  * @author fernandojsg / http://fernandojsg.com
+ * @author Don McCurdy / https://www.donmccurdy.com
+ * @author Takahiro / https://github.com/takahirox
  */
 
 //------------------------------------------------------------------------------
@@ -68,7 +70,9 @@ THREE.GLTFExporter.prototype = {
 			onlyVisible: true,
 			truncateDrawRange: true,
 			embedImages: true,
-			animations: []
+			animations: [],
+			forceIndices: false,
+			forcePowerOfTwoTextures: false
 		};
 
 		options = Object.assign( {}, DEFAULT_OPTIONS, options );
@@ -92,13 +96,14 @@ THREE.GLTFExporter.prototype = {
 		};
 
 		var byteOffset = 0;
-		var dataViews = [];
+		var buffers = [];
+		var pending = [];
 		var nodeMap = {};
 		var skins = [];
 		var cachedData = {
 
-			images: {},
-			materials: {}
+			materials: {},
+			textures: {}
 
 		};
 
@@ -128,7 +133,18 @@ THREE.GLTFExporter.prototype = {
 		 * @param  {string} text
 		 * @return {ArrayBuffer}
 		 */
-		function stringToArrayBuffer( text ) {
+		function stringToArrayBuffer( text, padded ) {
+			if ( padded ) {
+
+				var pad = getPaddedBufferSize( text.length ) - text.length;
+
+				for ( var i = 0; i < pad; i++ ) {
+
+					text += ' ';
+
+				}
+
+			}
 
 			if ( window.TextEncoder !== undefined ) {
 
@@ -180,6 +196,19 @@ THREE.GLTFExporter.prototype = {
 
 		}
 
+		/**
+		 * Checks if image size is POT.
+		 *
+		 * @param {Image} image The image to be checked.
+		 * @returns {Boolean} Returns true if image size is POT.
+		 *
+		 */
+		function isPowerOfTwo( image ) {
+
+			return THREE.Math.isPowerOfTwo( image.width ) && THREE.Math.isPowerOfTwo( image.height );
+
+		}
+
 		/**
 		 * Get the required size + padding for a buffer, rounded to the next 4-byte boundary.
 		 * https://github.com/KhronosGroup/glTF/tree/master/specification/2.0#data-alignment
@@ -194,45 +223,77 @@ THREE.GLTFExporter.prototype = {
 
 		}
 
+		/**
+		 * Returns a buffer aligned to 4-byte boundary.
+		 *
+		 * @param {ArrayBuffer} arrayBuffer Buffer to pad
+		 * @returns {ArrayBuffer} The same buffer if it's already aligned to 4-byte boundary or a new buffer
+		 */
+		function getPaddedArrayBuffer( arrayBuffer ) {
+
+			var paddedLength = getPaddedBufferSize( arrayBuffer.byteLength );
+
+			if (paddedLength !== arrayBuffer.byteLength ) {
+
+				var paddedBuffer = new ArrayBuffer( paddedLength );
+				new Uint8Array( paddedBuffer ).set(new Uint8Array(arrayBuffer));
+				return paddedBuffer;
+
+			}
+
+			return arrayBuffer;
+
+		}
+
 		/**
 		 * Process a buffer to append to the default one.
-		 * @param  {THREE.BufferAttribute} attribute     Attribute to store
-		 * @param  {Integer} componentType Component type (Unsigned short, unsigned int or float)
-		 * @return {Integer}               Index of the buffer created (Currently always 0)
+		 * @param  {ArrayBuffer} buffer
+		 * @return {Integer}
 		 */
-		function processBuffer( attribute, componentType, start, count ) {
+		function processBuffer( buffer ) {
 
 			if ( ! outputJSON.buffers ) {
 
-				outputJSON.buffers = [
+				outputJSON.buffers = [ { byteLength: 0 } ];
 
-					{
+			}
 
-						byteLength: 0,
-						uri: ''
+			// All buffers are merged before export.
+			buffers.push( buffer );
 
-					}
+			return 0;
 
-				];
+		}
 
-			}
+		/**
+		 * Process and generate a BufferView
+		 * @param  {THREE.BufferAttribute} attribute
+		 * @param  {number} componentType
+		 * @param  {number} start
+		 * @param  {number} count
+		 * @param  {number} target (Optional) Target usage of the BufferView
+		 * @return {Object}
+		 */
+		function processBufferView( attribute, componentType, start, count, target ) {
 
-			var offset = 0;
-			var componentSize = componentType === WEBGL_CONSTANTS.UNSIGNED_SHORT ? 2 : 4;
+			if ( ! outputJSON.bufferViews ) {
 
-			// Create a new dataview and dump the attribute's array into it
-			var byteLength = count * attribute.itemSize * componentSize;
+				outputJSON.bufferViews = [];
 
-			// adjust required size of array buffer with padding
-			// to satisfy gltf requirement that the length is divisible by 4
-			byteLength = getPaddedBufferSize( byteLength );
+			}
 
+			// Create a new dataview and dump the attribute's array into it
+			var componentSize = componentType === WEBGL_CONSTANTS.UNSIGNED_SHORT ? 2 : 4;
+			var byteLength = getPaddedBufferSize( count * attribute.itemSize * componentSize );
 			var dataView = new DataView( new ArrayBuffer( byteLength ) );
+			var offset = 0;
 
 			for ( var i = start; i < start + count; i ++ ) {
 
 				for ( var a = 0; a < attribute.itemSize; a ++ ) {
 
+					// @TODO Fails on InterleavedBufferAttribute, and could probably be
+					// optimized for normal BufferAttribute.
 					var value = attribute.array[ i * attribute.itemSize + a ];
 
 					if ( componentType === WEBGL_CONSTANTS.FLOAT ) {
@@ -255,39 +316,9 @@ THREE.GLTFExporter.prototype = {
 
 			}
 
-			// We just use one buffer
-			dataViews.push( dataView );
-
-			// Always using just one buffer
-			return 0;
-
-		}
-
-		/**
-		 * Process and generate a BufferView
-		 * @param  {THREE.BufferAttribute} data
-		 * @param  {number} componentType
-		 * @param  {number} start
-		 * @param  {number} count
-		 * @param  {number} target (Optional) Target usage of the BufferView
-		 * @return {Object}
-		 */
-		function processBufferView( data, componentType, start, count, target ) {
-
-			if ( ! outputJSON.bufferViews ) {
-
-				outputJSON.bufferViews = [];
-
-			}
-
-			var componentSize = componentType === WEBGL_CONSTANTS.UNSIGNED_SHORT ? 2 : 4;
-
-			// Create a new dataview and dump the attribute's array into it
-			var byteLength = count * data.itemSize * componentSize;
-
 			var gltfBufferView = {
 
-				buffer: processBuffer( data, componentType, start, count ),
+				buffer: processBuffer( dataView.buffer ),
 				byteOffset: byteOffset,
 				byteLength: byteLength
 
@@ -298,7 +329,7 @@ THREE.GLTFExporter.prototype = {
 			if ( target === WEBGL_CONSTANTS.ARRAY_BUFFER ) {
 
 				// Only define byteStride for vertex attributes.
-				gltfBufferView.byteStride = data.itemSize * componentSize;
+				gltfBufferView.byteStride = attribute.itemSize * componentSize;
 
 			}
 
@@ -306,7 +337,7 @@ THREE.GLTFExporter.prototype = {
 
 			outputJSON.bufferViews.push( gltfBufferView );
 
-			// @TODO Ideally we'll have just two bufferviews: 0 is for vertex attributes, 1 for indices
+			// @TODO Merge bufferViews where possible.
 			var output = {
 
 				id: outputJSON.bufferViews.length - 1,
@@ -318,6 +349,45 @@ THREE.GLTFExporter.prototype = {
 
 		}
 
+		/**
+		 * Process and generate a BufferView from an image Blob.
+		 * @param {Blob} blob
+		 * @return {Promise<Integer>}
+		 */
+		function processBufferViewImage( blob ) {
+
+			if ( ! outputJSON.bufferViews ) {
+
+				outputJSON.bufferViews = [];
+
+			}
+
+			return new Promise( function ( resolve ) {
+
+				var reader = new window.FileReader();
+				reader.readAsArrayBuffer( blob );
+				reader.onloadend = function () {
+
+					var buffer = getPaddedArrayBuffer( reader.result );
+
+					var bufferView = {
+						buffer: processBuffer( buffer ),
+						byteOffset: byteOffset,
+						byteLength: buffer.byteLength
+					};
+
+					byteOffset += buffer.byteLength;
+
+					outputJSON.bufferViews.push( bufferView );
+
+					resolve( outputJSON.bufferViews.length - 1 );
+
+				};
+
+			} );
+
+		}
+
 		/**
 		 * Process attribute to generate an accessor
 		 * @param  {THREE.BufferAttribute} attribute Attribute to process
@@ -414,11 +484,7 @@ THREE.GLTFExporter.prototype = {
 		 */
 		function processImage( map ) {
 
-			if ( cachedData.images[ map.uuid ] !== undefined ) {
-
-				return cachedData.images[ map.uuid ];
-
-			}
+			// @TODO Cache
 
 			if ( ! outputJSON.images ) {
 
@@ -432,22 +498,53 @@ THREE.GLTFExporter.prototype = {
 			if ( options.embedImages ) {
 
 				var canvas = cachedCanvas = cachedCanvas || document.createElement( 'canvas' );
+
 				canvas.width = map.image.width;
 				canvas.height = map.image.height;
+
+				if ( options.forcePowerOfTwoTextures && ! isPowerOfTwo( map.image ) ) {
+
+					console.warn( 'GLTFExporter: Resized non-power-of-two image.', map.image );
+
+					canvas.width = THREE.Math.floorPowerOfTwo( canvas.width );
+					canvas.height = THREE.Math.floorPowerOfTwo( canvas.height );
+
+				}
+
 				var ctx = canvas.getContext( '2d' );
 
 				if ( map.flipY === true ) {
 
-					ctx.translate( 0, map.image.height );
+					ctx.translate( 0, canvas.height );
 					ctx.scale( 1, - 1 );
 
 				}
 
-				ctx.drawImage( map.image, 0, 0 );
+				ctx.drawImage( map.image, 0, 0, canvas.width, canvas.height );
+
+				if ( options.binary === true ) {
+
+					pending.push( new Promise( function ( resolve ) {
+
+						canvas.toBlob( function ( blob ) {
+
+							processBufferViewImage( blob ).then( function ( bufferViewIndex ) {
+
+								gltfImage.bufferView = bufferViewIndex;
+
+								resolve();
+
+							} );
+
+						}, mimeType );
 
-				// @TODO Embed in { bufferView } if options.binary set.
+					} ) );
 
-				gltfImage.uri = canvas.toDataURL( mimeType );
+				} else {
+
+					gltfImage.uri = canvas.toDataURL( mimeType );
+
+				}
 
 			} else {
 
@@ -457,10 +554,7 @@ THREE.GLTFExporter.prototype = {
 
 			outputJSON.images.push( gltfImage );
 
-			var index = outputJSON.images.length - 1;
-			cachedData.images[ map.uuid ] = index;
-
-			return index;
+			return outputJSON.images.length - 1;
 
 		}
 
@@ -499,6 +593,12 @@ THREE.GLTFExporter.prototype = {
 		 */
 		function processTexture( map ) {
 
+			if ( cachedData.textures[ map.uuid ] !== undefined ) {
+
+				return cachedData.textures[ map.uuid ];
+
+			}
+
 			if ( ! outputJSON.textures ) {
 
 				outputJSON.textures = [];
@@ -514,7 +614,10 @@ THREE.GLTFExporter.prototype = {
 
 			outputJSON.textures.push( gltfTexture );
 
-			return outputJSON.textures.length - 1;
+			var index = outputJSON.textures.length - 1;
+			cachedData.textures[ map.uuid ] = index;
+
+			return index;
 
 		}
 
@@ -547,7 +650,7 @@ THREE.GLTFExporter.prototype = {
 
 			if ( ! ( material instanceof THREE.MeshStandardMaterial ) ) {
 
-				console.warn( 'GLTFExporter: Currently just THREE.StandardMaterial is supported. Material conversion may lose information.' );
+				console.warn( 'GLTFExporter: Currently just THREE.MeshStandardMaterial is supported. Material conversion may lose information.' );
 
 			}
 
@@ -579,6 +682,25 @@ THREE.GLTFExporter.prototype = {
 
 			}
 
+			// pbrMetallicRoughness.metallicRoughnessTexture
+			if ( material.metalnessMap || material.roughnessMap ) {
+
+				if ( material.metalnessMap === material.roughnessMap ) {
+
+					gltfMaterial.pbrMetallicRoughness.metallicRoughnessTexture = {
+
+						index: processTexture( material.metalnessMap )
+
+					};
+
+				} else {
+
+					console.warn( 'THREE.GLTFExporter: Ignoring metalnessMap and roughnessMap because they are not the same Texture.' );
+
+				}
+
+			}
+
 			// pbrMetallicRoughness.baseColorTexture
 			if ( material.map ) {
 
@@ -776,6 +898,18 @@ THREE.GLTFExporter.prototype = {
 
 				gltfMesh.primitives[ 0 ].indices = processAccessor( geometry.index, geometry );
 
+			} else if ( options.forceIndices ) {
+
+				var numFaces = geometry.attributes.position.count;
+				var indices = new Uint32Array( numFaces );
+				for ( var i = 0; i < numFaces; i ++ ) {
+
+					indices[ i ] = i;
+
+				}
+
+				gltfMesh.primitives[ 0 ].indices = processAccessor( new THREE.Uint32BufferAttribute( indices, 1 ), geometry );
+
 			}
 
 			// We've just one primitive per mesh
@@ -811,28 +945,87 @@ THREE.GLTFExporter.prototype = {
 			if ( mesh.morphTargetInfluences !== undefined && mesh.morphTargetInfluences.length > 0 ) {
 
 				var weights = [];
+				var targetNames = [];
+				var reverseDictionary = {};
+
+				if ( mesh.morphTargetDictionary !== undefined ) {
+
+					for ( var key in mesh.morphTargetDictionary ) {
+
+						reverseDictionary[ mesh.morphTargetDictionary[ key ] ] = key;
+
+					}
+
+				}
+
 				gltfMesh.primitives[ 0 ].targets = [];
 
 				for ( var i = 0; i < mesh.morphTargetInfluences.length; ++ i ) {
 
 					var target = {};
 
+					var warned = false;
+
 					for ( var attributeName in geometry.morphAttributes ) {
 
+						// glTF 2.0 morph supports only POSITION/NORMAL/TANGENT.
+						// Three.js doesn't support TANGENT yet.
+
+						if ( attributeName !== 'position' && attributeName !== 'normal' ) {
+
+							if ( ! warned ) {
+
+								console.warn( 'GLTFExporter: Only POSITION and NORMAL morph are supported.' );
+								warned = true;
+
+							}
+
+							continue;
+
+						}
+
 						var attribute = geometry.morphAttributes[ attributeName ][ i ];
-						attributeName = nameConversion[ attributeName ] || attributeName.toUpperCase();
-						target[ attributeName ] = processAccessor( attribute, geometry );
+
+						// Three.js morph attribute has absolute values while the one of glTF has relative values.
+						//
+						// glTF 2.0 Specification:
+						// https://github.com/KhronosGroup/glTF/tree/master/specification/2.0#morph-targets
+
+						var baseAttribute = geometry.attributes[ attributeName ];
+						// Clones attribute not to override
+						var relativeAttribute = attribute.clone();
+
+						for ( var j = 0, jl = attribute.count; j < jl; j ++ ) {
+
+							relativeAttribute.setXYZ(
+								j,
+								attribute.getX( j ) - baseAttribute.getX( j ),
+								attribute.getY( j ) - baseAttribute.getY( j ),
+								attribute.getZ( j ) - baseAttribute.getZ( j )
+							);
+
+						}
+
+						target[ attributeName.toUpperCase() ] = processAccessor( relativeAttribute, geometry );
 
 					}
 
 					gltfMesh.primitives[ 0 ].targets.push( target );
 
 					weights.push( mesh.morphTargetInfluences[ i ] );
+					if ( mesh.morphTargetDictionary !== undefined ) targetNames.push( reverseDictionary[ i ] );
 
 				}
 
 				gltfMesh.weights = weights;
 
+				if ( targetNames.length > 0 ) {
+
+					gltfMesh.extras = {};
+					gltfMesh.extras.targetNames = targetNames;
+
+				}
+
 			}
 
 			outputJSON.meshes.push( gltfMesh );
@@ -868,8 +1061,8 @@ THREE.GLTFExporter.prototype = {
 
 					xmag: camera.right * 2,
 					ymag: camera.top * 2,
-					zfar: camera.far,
-					znear: camera.near
+					zfar: camera.far <= 0 ? 0.001 : camera.far,
+					znear: camera.near < 0 ? 0 : camera.near
 
 				};
 
@@ -879,8 +1072,8 @@ THREE.GLTFExporter.prototype = {
 
 					aspectRatio: camera.aspect,
 					yfov: THREE.Math.degToRad( camera.fov ) / camera.aspect,
-					zfar: camera.far,
-					znear: camera.near
+					zfar: camera.far <= 0 ? 0.001 : camera.far,
+					znear: camera.near < 0 ? 0 : camera.near
 
 				};
 
@@ -903,7 +1096,6 @@ THREE.GLTFExporter.prototype = {
 		 *
 		 * Status:
 		 * - Only properties listed in PATH_PROPERTIES may be animated.
-		 * - Only LINEAR and STEP interpolation currently supported.
 		 *
 		 * @param {THREE.AnimationClip} clip
 		 * @param {THREE.Object3D} root
@@ -957,11 +1149,37 @@ THREE.GLTFExporter.prototype = {
 
 				}
 
+				var interpolation;
+
+				// @TODO export CubicInterpolant(InterpolateSmooth) as CUBICSPLINE
+
+				// Detecting glTF cubic spline interpolant by checking factory method's special property
+				// GLTFCubicSplineInterpolant is a custom interpolant and track doesn't return
+				// valid value from .getInterpolation().
+				if ( track.createInterpolant.isInterpolantFactoryMethodGLTFCubicSpline === true ) {
+
+					interpolation = 'CUBICSPLINE';
+
+					// itemSize of CUBICSPLINE keyframe is 9
+					// (VEC3 * 3: inTangent, splineVertex, and outTangent)
+					// but needs to be stored as VEC3 so dividing by 3 here.
+					outputItemSize /= 3;
+
+				} else if ( track.getInterpolation() === THREE.InterpolateDiscrete ) {
+
+					interpolation = 'STEP';
+
+				} else {
+
+					interpolation = 'LINEAR';
+
+				}
+
 				samplers.push( {
 
 					input: processAccessor( new THREE.BufferAttribute( track.times, inputItemSize ) ),
 					output: processAccessor( new THREE.BufferAttribute( track.values, outputItemSize ) ),
-					interpolation: track.getInterpolation() === THREE.InterpolateDiscrete ? 'STEP' : 'LINEAR'
+					interpolation: interpolation
 
 				} );
 
@@ -1086,7 +1304,8 @@ THREE.GLTFExporter.prototype = {
 
 			}
 
-			if ( object.name ) {
+			// We don't export empty strings name because it represents no-name in Three.js.
+			if ( object.name !== '' ) {
 
 				gltfNode.name = String( object.name );
 
@@ -1281,91 +1500,93 @@ THREE.GLTFExporter.prototype = {
 
 		processInput( input );
 
-		// Generate buffer
-		// Create a new blob with all the dataviews from the buffers
-		var blob = new Blob( dataViews, { type: 'application/octet-stream' } );
+		Promise.all( pending ).then( function () {
 
-		// Update the bytlength of the only main buffer and update the uri with the base64 representation of it
-		if ( outputJSON.buffers && outputJSON.buffers.length > 0 ) {
+			// Merge buffers.
+			var blob = new Blob( buffers, { type: 'application/octet-stream' } );
 
-			outputJSON.buffers[ 0 ].byteLength = blob.size;
+			if ( outputJSON.buffers && outputJSON.buffers.length > 0 ) {
 
-			var reader = new window.FileReader();
+				// Update bytelength of the single buffer.
+				outputJSON.buffers[ 0 ].byteLength = blob.size;
 
-			if ( options.binary === true ) {
+				var reader = new window.FileReader();
 
-				// https://github.com/KhronosGroup/glTF/blob/master/specification/2.0/README.md#glb-file-format-specification
+				if ( options.binary === true ) {
 
-				var GLB_HEADER_BYTES = 12;
-				var GLB_HEADER_MAGIC = 0x46546C67;
-				var GLB_VERSION = 2;
+					// https://github.com/KhronosGroup/glTF/blob/master/specification/2.0/README.md#glb-file-format-specification
 
-				var GLB_CHUNK_PREFIX_BYTES = 8;
-				var GLB_CHUNK_TYPE_JSON = 0x4E4F534A;
-				var GLB_CHUNK_TYPE_BIN = 0x004E4942;
+					var GLB_HEADER_BYTES = 12;
+					var GLB_HEADER_MAGIC = 0x46546C67;
+					var GLB_VERSION = 2;
 
-				reader.readAsArrayBuffer( blob );
-				reader.onloadend = function () {
+					var GLB_CHUNK_PREFIX_BYTES = 8;
+					var GLB_CHUNK_TYPE_JSON = 0x4E4F534A;
+					var GLB_CHUNK_TYPE_BIN = 0x004E4942;
+
+					reader.readAsArrayBuffer( blob );
+					reader.onloadend = function () {
+
+						// Binary chunk.
+						var binaryChunk = getPaddedArrayBuffer( reader.result );
+						var binaryChunkPrefix = new DataView( new ArrayBuffer( GLB_CHUNK_PREFIX_BYTES ) );
+						binaryChunkPrefix.setUint32( 0, binaryChunk.byteLength, true );
+						binaryChunkPrefix.setUint32( 4, GLB_CHUNK_TYPE_BIN, true );
+
+						// JSON chunk.
+						var jsonChunk = stringToArrayBuffer( JSON.stringify( outputJSON ), true );
+						var jsonChunkPrefix = new DataView( new ArrayBuffer( GLB_CHUNK_PREFIX_BYTES ) );
+						jsonChunkPrefix.setUint32( 0, jsonChunk.byteLength, true );
+						jsonChunkPrefix.setUint32( 4, GLB_CHUNK_TYPE_JSON, true );
+
+						// GLB header.
+						var header = new ArrayBuffer( GLB_HEADER_BYTES );
+						var headerView = new DataView( header );
+						headerView.setUint32( 0, GLB_HEADER_MAGIC, true );
+						headerView.setUint32( 4, GLB_VERSION, true );
+						var totalByteLength = GLB_HEADER_BYTES
+							+ jsonChunkPrefix.byteLength + jsonChunk.byteLength
+							+ binaryChunkPrefix.byteLength + binaryChunk.byteLength;
+						headerView.setUint32( 8, totalByteLength, true );
+
+						var glbBlob = new Blob( [
+							header,
+							jsonChunkPrefix,
+							jsonChunk,
+							binaryChunkPrefix,
+							binaryChunk
+						], { type: 'application/octet-stream' } );
 
-					// Binary chunk.
-					var binaryChunk = reader.result;
-					var binaryChunkPrefix = new DataView( new ArrayBuffer( GLB_CHUNK_PREFIX_BYTES ) );
-					binaryChunkPrefix.setUint32( 0, binaryChunk.byteLength, true );
-					binaryChunkPrefix.setUint32( 4, GLB_CHUNK_TYPE_BIN, true );
-
-					// JSON chunk.
-					delete outputJSON.buffers[ 0 ].uri; // Omitted URI indicates use of binary chunk.
-					var jsonChunk = stringToArrayBuffer( JSON.stringify( outputJSON ) );
-					var jsonChunkPrefix = new DataView( new ArrayBuffer( GLB_CHUNK_PREFIX_BYTES ) );
-					jsonChunkPrefix.setUint32( 0, jsonChunk.byteLength, true );
-					jsonChunkPrefix.setUint32( 4, GLB_CHUNK_TYPE_JSON, true );
-
-					// GLB header.
-					var header = new ArrayBuffer( GLB_HEADER_BYTES );
-					var headerView = new DataView( header );
-					headerView.setUint32( 0, GLB_HEADER_MAGIC, true );
-					headerView.setUint32( 4, GLB_VERSION, true );
-					var totalByteLength = GLB_HEADER_BYTES
-						+ jsonChunkPrefix.byteLength + jsonChunk.byteLength
-						+ binaryChunkPrefix.byteLength + binaryChunk.byteLength;
-					headerView.setUint32( 8, totalByteLength, true );
-
-					var glbBlob = new Blob( [
-						header,
-						jsonChunkPrefix,
-						jsonChunk,
-						binaryChunkPrefix,
-						binaryChunk
-					], { type: 'application/octet-stream' } );
-
-					var glbReader = new window.FileReader();
-					glbReader.readAsArrayBuffer( glbBlob );
-					glbReader.onloadend = function () {
-
-						onDone( glbReader.result );
+						var glbReader = new window.FileReader();
+						glbReader.readAsArrayBuffer( glbBlob );
+						glbReader.onloadend = function () {
+
+							onDone( glbReader.result );
+
+						};
 
 					};
 
-				};
+				} else {
 
-			} else {
+					reader.readAsDataURL( blob );
+					reader.onloadend = function () {
 
-				reader.readAsDataURL( blob );
-				reader.onloadend = function () {
+						var base64data = reader.result;
+						outputJSON.buffers[ 0 ].uri = base64data;
+						onDone( outputJSON );
 
-					var base64data = reader.result;
-					outputJSON.buffers[ 0 ].uri = base64data;
-					onDone( outputJSON );
+					};
 
-				};
+				}
 
-			}
+			} else {
 
-		} else {
+				onDone( outputJSON );
 
-			onDone( outputJSON );
+			}
 
-		}
+		} );
 
 	}
 

+ 2 - 2
examples/js/exporters/OBJExporter.js

@@ -124,7 +124,7 @@ THREE.OBJExporter.prototype = {
 
 							j = indices.getX( i + m ) + 1;
 
-							face[ m ] = ( indexVertex + j ) + '/' + ( uvs ? ( indexVertexUvs + j ) : '' ) + '/' + ( indexNormals + j );
+							face[ m ] = ( indexVertex + j ) + ( normals || uvs ? '/' + ( uvs ? ( indexVertexUvs + j ) : '' ) + ( normals ? '/' + ( indexNormals + j ) : '' ) : '' );
 
 						}
 
@@ -141,7 +141,7 @@ THREE.OBJExporter.prototype = {
 
 							j = i + m + 1;
 
-							face[ m ] = ( indexVertex + j ) + '/' + ( uvs ? ( indexVertexUvs + j ) : '' ) + '/' + ( indexNormals + j );
+							face[ m ] = ( indexVertex + j ) + ( normals || uvs ? '/' + ( uvs ? ( indexVertexUvs + j ) : '' ) + ( normals ? '/' + ( indexNormals + j ) : '' ) : '' );
 
 						}
 

+ 7 - 12
examples/js/loaders/ColladaLoader.js

@@ -3306,7 +3306,12 @@ THREE.ColladaLoader.prototype = {
 
 			}
 
-			object.name = ( type === 'JOINT' ) ? data.sid : data.name;
+			if ( object.name === '' ) {
+
+				object.name = ( type === 'JOINT' ) ? data.sid : data.name;
+				
+			}
+
 			object.matrix.copy( matrix );
 			object.matrix.decompose( object.position, object.quaternion, object.scale );
 
@@ -3450,17 +3455,7 @@ THREE.ColladaLoader.prototype = {
 
 				var child = children[ i ];
 
-				if ( child.id === null ) {
-
-					group.add( buildNode( child ) );
-
-				} else {
-
-					// if there is an ID, let's try to get the finished build (e.g. joints are already build)
-
-					group.add( getNode( child.id ) );
-
-				}
+				group.add( getNode( child.id ) );
 
 			}
 

+ 730 - 72
examples/js/loaders/EXRLoader.js

@@ -1,9 +1,77 @@
 /**
  * @author Richard M. / https://github.com/richardmonette
+ *
+ * OpenEXR loader which, currently, supports reading 16 bit half data, in either
+ * uncompressed or PIZ wavelet compressed form.
+ *
+ * Referred to the original Industrial Light & Magic OpenEXR implementation and the TinyEXR / Syoyo Fujita
+ * implementation, so I have preserved their copyright notices.
  */
 
-// https://github.com/mrdoob/three.js/issues/10652
-// https://en.wikipedia.org/wiki/OpenEXR
+// /*
+// Copyright (c) 2014 - 2017, Syoyo Fujita
+// All rights reserved.
+
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+//     * Redistributions of source code must retain the above copyright
+//       notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above copyright
+//       notice, this list of conditions and the following disclaimer in the
+//       documentation and/or other materials provided with the distribution.
+//     * Neither the name of the Syoyo Fujita nor the
+//       names of its contributors may be used to endorse or promote products
+//       derived from this software without specific prior written permission.
+
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+// DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
+// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// */
+
+// // TinyEXR contains some OpenEXR code, which is licensed under ------------
+
+// ///////////////////////////////////////////////////////////////////////////
+// //
+// // Copyright (c) 2002, Industrial Light & Magic, a division of Lucas
+// // Digital Ltd. LLC
+// //
+// // All rights reserved.
+// //
+// // Redistribution and use in source and binary forms, with or without
+// // modification, are permitted provided that the following conditions are
+// // met:
+// // *       Redistributions of source code must retain the above copyright
+// // notice, this list of conditions and the following disclaimer.
+// // *       Redistributions in binary form must reproduce the above
+// // copyright notice, this list of conditions and the following disclaimer
+// // in the documentation and/or other materials provided with the
+// // distribution.
+// // *       Neither the name of Industrial Light & Magic nor the names of
+// // its contributors may be used to endorse or promote products derived
+// // from this software without specific prior written permission.
+// //
+// // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// //
+// ///////////////////////////////////////////////////////////////////////////
+
+// // End of OpenEXR license -------------------------------------------------
 
 THREE.EXRLoader = function ( manager ) {
 
@@ -15,6 +83,518 @@ THREE.EXRLoader.prototype = Object.create( THREE.DataTextureLoader.prototype );
 
 THREE.EXRLoader.prototype._parser = function ( buffer ) {
 
+	const USHORT_RANGE = (1 << 16);
+	const BITMAP_SIZE = (USHORT_RANGE >> 3);
+
+	const HUF_ENCBITS = 16;  // literal (value) bit length
+	const HUF_DECBITS = 14;  // decoding bit size (>= 8)
+
+	const HUF_ENCSIZE = (1 << HUF_ENCBITS) + 1;  // encoding table size
+	const HUF_DECSIZE = 1 << HUF_DECBITS;        // decoding table size
+	const HUF_DECMASK = HUF_DECSIZE - 1;
+
+	const SHORT_ZEROCODE_RUN = 59;
+	const LONG_ZEROCODE_RUN = 63;
+	const SHORTEST_LONG_RUN = 2 + LONG_ZEROCODE_RUN - SHORT_ZEROCODE_RUN;
+	const LONGEST_LONG_RUN = 255 + SHORTEST_LONG_RUN;
+
+	const BYTES_PER_HALF = 2;
+
+	const ULONG_SIZE = 8;
+	const FLOAT32_SIZE = 4;
+	const INT32_SIZE = 4;
+	const INT16_SIZE = 2;
+	const INT8_SIZE = 1;
+
+	function reverseLutFromBitmap(bitmap, lut) {
+		var k = 0;
+
+		for (var i = 0; i < USHORT_RANGE; ++i) {
+			if ((i == 0) || (bitmap[i >> 3] & (1 << (i & 7)))) {
+				lut[k++] = i;
+			}
+		}
+
+		var n = k - 1;
+
+		while (k < USHORT_RANGE) lut[k++] = 0;
+
+		return n;
+	}
+
+	function hufClearDecTable(hdec) {
+		for (var i = 0; i < HUF_DECSIZE; i++) {
+			hdec[i] = {}
+			hdec[i].len = 0;
+			hdec[i].lit = 0;
+			hdec[i].p = null;
+		}
+	}
+
+	const getBitsReturn = { l: 0, c: 0, lc: 0 };
+	function getBits(nBits, c, lc, uInt8Array, inOffset) {
+		while (lc < nBits) {
+			c = (c << 8) | parseUint8Array(uInt8Array, inOffset);
+			lc += 8;
+		}
+
+		lc -= nBits;
+
+		getBitsReturn.l = (c >> lc) & ((1 << nBits) - 1);
+		getBitsReturn.c = c;
+		getBitsReturn.lc = lc;
+	}
+
+	const hufTableBuffer = new Array(59);
+	function hufCanonicalCodeTable(hcode) {
+		for (var i = 0; i <= 58; ++i) hufTableBuffer[i] = 0;
+
+		for (var i = 0; i < HUF_ENCSIZE; ++i) hufTableBuffer[hcode[i]] += 1;
+
+		var c = 0;
+
+		for (var i = 58; i > 0; --i) {
+			var nc = ((c + hufTableBuffer[i]) >> 1);
+			hufTableBuffer[i] = c;
+			c = nc;
+		}
+
+		for (var i = 0; i < HUF_ENCSIZE; ++i) {
+			var l = hcode[i];
+
+			if (l > 0) hcode[i] = l | (hufTableBuffer[l]++ << 6);
+		}
+	}
+
+	function hufUnpackEncTable(uInt8Array, inDataView, inOffset, ni, im, iM, hcode) {
+		var p = inOffset;
+		var c = 0;
+		var lc = 0;
+
+		for (; im <= iM; im++) {
+			if (p.value - inOffset.value > ni) {
+				return false;
+			}
+
+			getBits(6, c, lc, uInt8Array, p);
+			var l = getBitsReturn.l;
+			c = getBitsReturn.c;
+			lc = getBitsReturn.lc;
+			hcode[im] = l;
+
+			if (l == LONG_ZEROCODE_RUN) {
+				if (p.value - inOffset.value > ni) {
+					throw 'Something wrong with hufUnpackEncTable';
+				}
+
+				getBits(8, c, lc, uInt8Array, p);
+				var zerun = getBitsReturn.l + SHORTEST_LONG_RUN;
+				c = getBitsReturn.c;
+				lc = getBitsReturn.lc;
+
+				if (im + zerun > iM + 1) {
+					throw 'Something wrong with hufUnpackEncTable';
+				}
+
+				while (zerun--) hcode[im++] = 0;
+
+				im--;
+			} else if (l >= SHORT_ZEROCODE_RUN) {
+				var zerun = l - SHORT_ZEROCODE_RUN + 2;
+
+				if (im + zerun > iM + 1) {
+					throw 'Something wrong with hufUnpackEncTable';
+				}
+
+				while (zerun--) hcode[im++] = 0;
+
+				im--;
+			}
+		}
+
+		hufCanonicalCodeTable(hcode);
+	}
+
+	function hufLength(code) { return code & 63; }
+
+	function hufCode(code) { return code >> 6; }
+
+	function hufBuildDecTable(hcode, im, iM, hdecod) {
+		for (; im <= iM; im++) {
+			var c = hufCode(hcode[im]);
+			var l = hufLength(hcode[im]);
+
+			if (c >> l) {
+				throw 'Invalid table entry';
+			}
+
+			if (l > HUF_DECBITS) {
+				var pl = hdecod[(c >> (l - HUF_DECBITS))];
+
+				if (pl.len) {
+					throw 'Invalid table entry';
+				}
+
+				pl.lit++;
+
+				if (pl.p) {
+					var p = pl.p;
+					pl.p = new Array(pl.lit);
+
+					for (var i = 0; i < pl.lit - 1; ++i) {
+						pl.p[i] = p[i];
+					}
+				} else {
+					pl.p = new Array(1);
+				}
+
+				pl.p[pl.lit - 1] = im;
+			} else if (l) {
+				var plOffset = 0;
+
+				for (var i = 1 << (HUF_DECBITS - l); i > 0; i--) {
+					var pl = hdecod[(c << (HUF_DECBITS - l)) + plOffset];
+
+					if (pl.len || pl.p) {
+						throw 'Invalid table entry';
+					}
+
+					pl.len = l;
+					pl.lit = im;
+
+					plOffset++;
+				}
+			}
+		}
+
+		return true;
+	}
+
+	const getCharReturn = { c: 0, lc: 0 };
+	function getChar(c, lc, uInt8Array, inOffset) {
+		c = (c << 8) | parseUint8Array(uInt8Array, inOffset);
+		lc += 8;
+
+		getCharReturn.c = c;
+		getCharReturn.lc = lc;
+	}
+
+	const getCodeReturn = { c: 0, lc: 0 };
+	function getCode(po, rlc, c, lc, uInt8Array, inDataView, inOffset, outBuffer, outBufferOffset, outBufferEndOffset) {
+		if (po == rlc) {
+			if (lc < 8) {
+				getChar(c, lc, uInt8Array, inOffset);
+				c = getCharReturn.c;
+				lc = getCharReturn.lc;
+			}
+
+			lc -= 8;
+
+			var cs = (c >> lc);
+
+			if (out + cs > oe) {
+				throw 'Issue with getCode';
+			}
+
+			var s = out[-1];
+
+			while (cs-- > 0) {
+				outBuffer[outBufferOffset.value++] = s;
+			}
+		} else if (outBufferOffset.value < outBufferEndOffset) {
+			outBuffer[outBufferOffset.value++] = po;
+		} else {
+			throw 'Issue with getCode';
+		}
+
+		getCodeReturn.c = c;
+		getCodeReturn.lc = lc;
+	}
+
+	var NBITS = 16;
+	var A_OFFSET = 1 << (NBITS - 1);
+	var M_OFFSET = 1 << (NBITS - 1);
+	var MOD_MASK = (1 << NBITS) - 1;
+
+	function UInt16(value) {
+		return (value & 0xFFFF);
+	};
+
+	function Int16(value) {
+		var ref = UInt16(value);
+		return (ref > 0x7FFF) ? ref - 0x10000 : ref;
+	};
+
+	const wdec14Return = { a: 0, b: 0 };
+	function wdec14(l, h) {
+		var ls = Int16(l);
+		var hs = Int16(h);
+
+		var hi = hs;
+		var ai = ls + (hi & 1) + (hi >> 1);
+
+		var as = ai;
+		var bs = ai - hi;
+
+		wdec14Return.a = as;
+		wdec14Return.b = bs;
+	}
+
+	function wav2Decode(j, buffer, nx, ox, ny, oy, mx) {
+		var n = (nx > ny) ? ny : nx;
+		var p = 1;
+		var p2;
+
+		while (p <= n) p <<= 1;
+
+		p >>= 1;
+		p2 = p;
+		p >>= 1;
+
+		while (p >= 1) {
+			var py = 0;
+			var ey = py + oy * (ny - p2);
+			var oy1 = oy * p;
+			var oy2 = oy * p2;
+			var ox1 = ox * p;
+			var ox2 = ox * p2;
+			var i00, i01, i10, i11;
+
+			for (; py <= ey; py += oy2) {
+				var px = py;
+				var ex = py + ox * (nx - p2);
+
+				for (; px <= ex; px += ox2) {
+					var p01 = px + ox1;
+					var p10 = px + oy1;
+					var p11 = p10 + ox1;
+
+					wdec14(buffer[px + j], buffer[p10 + j]);
+					i00 = wdec14Return.a;
+					i10 = wdec14Return.b;
+
+					wdec14(buffer[p01 + j], buffer[p11 + j]);
+					i01 = wdec14Return.a;
+					i11 = wdec14Return.b;
+
+					wdec14(i00, i01);
+					buffer[px + j] = wdec14Return.a;
+					buffer[p01 + j] = wdec14Return.b;
+
+					wdec14(i10, i11);
+					buffer[p10 + j] = wdec14Return.a;
+					buffer[p11 + j] = wdec14Return.b;
+				}
+
+				if (nx & p) {
+					var p10 = px + oy1;
+
+					wdec14(buffer[px + j], buffer[p10 + j]);
+					i00 = wdec14Return.a;
+					buffer[p10 + j] = wdec14Return.b;
+
+					buffer[px + j] = i00;
+				}
+			}
+
+			if (ny & p) {
+				var px = py;
+				var ex = py + ox * (nx - p2);
+
+				for (; px <= ex; px += ox2) {
+					var p01 = px + ox1;
+
+					wdec14(buffer[px + j], buffer[p01 + j]);
+					i00 = wdec14Return.a;
+					buffer[p01 + j] = wdec14Return.b;
+
+					buffer[px + j] = i00;
+				}
+			}
+
+			p2 = p;
+			p >>= 1;
+		}
+
+		return py;
+	}
+
+	function hufDecode(encodingTable, decodingTable, uInt8Array, inDataView, inOffset, ni, rlc, no, outBuffer, outOffset) {
+		var c = 0;
+		var lc = 0;
+		var outBufferEndOffset = no;
+		var inOffsetEnd = Math.trunc(inOffset.value + (ni + 7) / 8);
+
+		while (inOffset.value < inOffsetEnd) {
+			getChar(c, lc, uInt8Array, inOffset);
+			c = getCharReturn.c;
+			lc = getCharReturn.lc;
+
+			while (lc >= HUF_DECBITS) {
+				var index = (c >> (lc - HUF_DECBITS)) & HUF_DECMASK;
+				var pl = decodingTable[index];
+
+				if (pl.len) {
+					lc -= pl.len;
+					getCode(pl.lit, rlc, c, lc, uInt8Array, inDataView, inOffset, outBuffer, outOffset, outBufferEndOffset);
+					c = getCodeReturn.c;
+					lc = getCodeReturn.lc;
+				} else {
+					if (!pl.p) {
+						throw 'hufDecode issues';
+					}
+
+					var j;
+
+					for (j = 0; j < pl.lit; j++) {
+						var l = hufLength(encodingTable[pl.p[j]]);
+
+						while (lc < l && inOffset.value < inOffsetEnd) {
+							getChar(c, lc, uInt8Array, inOffset);
+							c = getCharReturn.c;
+							lc = getCharReturn.lc;
+						}
+
+						if (lc >= l) {
+							if (hufCode(encodingTable[pl.p[j]]) ==
+								((c >> (lc - l)) & ((1 << l) - 1))) {
+
+								lc -= l;
+								getCode(pl.p[j], rlc, c, lc, uInt8Array, inDataView, inOffset, outBuffer, outOffset, outBufferEndOffset);
+								c = getCodeReturn.c;
+								lc = getCodeReturn.lc;
+								break;
+							}
+						}
+					}
+
+					if (j == pl.lit) {
+						throw 'hufDecode issues';
+					}
+				}
+			}
+		}
+
+		var i = (8 - ni) & 7;
+		c >>= i;
+		lc -= i;
+
+		while (lc > 0) {
+			var pl = decodingTable[(c << (HUF_DECBITS - lc)) & HUF_DECMASK];
+
+			if (pl.len) {
+				lc -= pl.len;
+				getCode(pl.lit, rlc, c, lc, uInt8Array, inDataView, inOffset, outBuffer, outOffset, outBufferEndOffset);
+				c = getCodeReturn.c;
+				lc = getCodeReturn.lc;
+			} else {
+				throw 'hufDecode issues';
+			}
+		}
+
+		return true;
+	}
+
+	function hufUncompress(uInt8Array, inDataView, inOffset, nCompressed, outBuffer, outOffset, nRaw) {
+		var initialInOffset = inOffset.value;
+
+		var im = parseUint32(inDataView, inOffset);
+		var iM = parseUint32(inDataView, inOffset);
+		inOffset.value += 4;
+		var nBits = parseUint32(inDataView, inOffset);
+		inOffset.value += 4;
+
+		if (im < 0 || im >= HUF_ENCSIZE || iM < 0 || iM >= HUF_ENCSIZE) {
+			throw 'Something wrong with HUF_ENCSIZE';
+		}
+
+		var freq = new Array(HUF_ENCSIZE);
+		var hdec = new Array(HUF_DECSIZE);
+
+		hufClearDecTable(hdec);
+
+		var ni = nCompressed - (inOffset.value - initialInOffset);
+
+		hufUnpackEncTable(uInt8Array, inDataView, inOffset, ni, im, iM, freq);
+
+		if (nBits > 8 * (nCompressed - (inOffset.value - initialInOffset))) {
+			throw 'Something wrong with hufUncompress';
+		}
+
+		hufBuildDecTable(freq, im, iM, hdec);
+
+		hufDecode(freq, hdec, uInt8Array, inDataView, inOffset, nBits, iM, nRaw, outBuffer, outOffset);
+	}
+
+	function applyLut(lut, data, nData) {
+		for (var i = 0; i < nData; ++i) {
+			data[i] = lut[data[i]];
+		}
+	}
+
+	function decompressPIZ(outBuffer, outOffset, uInt8Array, inDataView, inOffset, tmpBufSize, num_channels, exrChannelInfos, dataWidth, num_lines) {
+		var bitmap = new Uint8Array(BITMAP_SIZE);
+
+		var minNonZero = parseUint16(inDataView, inOffset);
+		var maxNonZero = parseUint16(inDataView, inOffset);
+
+		if (maxNonZero >= BITMAP_SIZE) {
+			throw 'Something is wrong with PIZ_COMPRESSION BITMAP_SIZE'
+		}
+
+		if (minNonZero <= maxNonZero) {
+			for (var i = 0; i < maxNonZero - minNonZero + 1; i++) {
+				bitmap[i + minNonZero] = parseUint8(inDataView, inOffset);
+			}
+		}
+
+		var lut = new Uint16Array(USHORT_RANGE);
+		var maxValue = reverseLutFromBitmap(bitmap, lut);
+
+		var length = parseUint32(inDataView, inOffset);
+
+		hufUncompress(uInt8Array, inDataView, inOffset, length, outBuffer, outOffset, tmpBufSize);
+
+		var pizChannelData = new Array(num_channels);
+
+		var outBufferEnd = 0
+
+		for (var i = 0; i < num_channels; i++) {
+			var exrChannelInfo = exrChannelInfos[i];
+
+			var pixelSize = 2; // assumes HALF_FLOAT
+
+			pizChannelData[i] = {};
+			pizChannelData[i]['start'] = outBufferEnd;
+			pizChannelData[i]['end'] = pizChannelData[i]['start'];
+			pizChannelData[i]['nx'] = dataWidth;
+			pizChannelData[i]['ny'] = num_lines;
+			pizChannelData[i]['size'] = 1;
+
+			outBufferEnd += pizChannelData[i].nx * pizChannelData[i].ny * pizChannelData[i].size;
+		}
+
+		var fooOffset = 0;
+
+		for (var i = 0; i < num_channels; i++) {
+			for (var j = 0; j < pizChannelData[i].size; ++j) {
+				fooOffset += wav2Decode(
+				j + fooOffset,
+				outBuffer,
+				pizChannelData[i].nx,
+				pizChannelData[i].size,
+				pizChannelData[i].ny,
+				pizChannelData[i].nx * pizChannelData[i].size,
+				maxValue
+				);
+			}
+		}
+
+		applyLut(lut, outBuffer, outBufferEnd);
+
+		return true;
+	}
+
 	function parseNullTerminatedString( buffer, offset ) {
 
 		var uintBuffer = new Uint8Array( buffer );
@@ -27,7 +607,7 @@ THREE.EXRLoader.prototype._parser = function ( buffer ) {
 		}
 
 		var stringValue = new TextDecoder().decode(
-			new Uint8Array( buffer ).slice( offset.value, offset.value + endOffset )
+			uintBuffer.slice( offset.value, offset.value + endOffset )
 		);
 
 		offset.value = offset.value + endOffset + 1;
@@ -48,41 +628,51 @@ THREE.EXRLoader.prototype._parser = function ( buffer ) {
 
 	}
 
-	function parseUlong( buffer, offset ) {
+	function parseUlong( dataView, offset ) {
 
-		var uLong = new DataView( buffer.slice( offset.value, offset.value + 4 ) ).getUint32( 0, true );
+		var uLong = dataView.getUint32( 0, true );
 
-		offset.value = offset.value + 8;
+		offset.value = offset.value + ULONG_SIZE;
 
 		return uLong;
 
 	}
 
-	function parseUint32( buffer, offset ) {
+	function parseUint32( dataView, offset ) {
 
-		var Uint32 = new DataView( buffer.slice( offset.value, offset.value + 4 ) ).getUint32( 0, true );
+		var Uint32 = dataView.getUint32(offset.value, true);
 
-		offset.value = offset.value + 4;
+		offset.value = offset.value + INT32_SIZE;
 
 		return Uint32;
 
 	}
 
-	function parseUint8( buffer, offset ) {
+	function parseUint8Array( uInt8Array, offset ) {
+
+		var Uint8 = uInt8Array[offset.value];
+
+		offset.value = offset.value + INT8_SIZE;
+
+		return Uint8;
+
+	}
+
+	function parseUint8( dataView, offset ) {
 
-		var Uint8 = new DataView( buffer.slice( offset.value, offset.value + 1 ) ).getUint8( 0, true );
+		var Uint8 = dataView.getUint8(offset.value);
 
-		offset.value = offset.value + 1;
+		offset.value = offset.value + INT8_SIZE;
 
 		return Uint8;
 
 	}
 
-	function parseFloat32( buffer, offset ) {
+	function parseFloat32( dataView, offset ) {
 
-		var float = new DataView( buffer.slice( offset.value, offset.value + 4 ) ).getFloat32( 0, true );
+		var float = dataView.getFloat32(offset.value, true);
 
-		offset.value += 4;
+		offset.value += FLOAT32_SIZE;
 
 		return float;
 
@@ -106,17 +696,23 @@ THREE.EXRLoader.prototype._parser = function ( buffer ) {
 
 	}
 
-	function parseFloat16( buffer, offset ) {
+	function parseUint16( dataView, offset ) {
 
-		var float = new DataView( buffer.slice( offset.value, offset.value + 2 ) ).getUint16( 0, true );
+		var Uint16 = dataView.getUint16( offset.value, true );
 
-		offset.value += 2;
+		offset.value += INT16_SIZE;
 
-		return decodeFloat16( float );
+		return Uint16;
 
 	}
 
-	function parseChlist( buffer, offset, size ) {
+	function parseFloat16( buffer, offset ) {
+
+		return decodeFloat16( parseUint16( buffer, offset) );
+
+	}
+
+	function parseChlist( dataView, buffer, offset, size ) {
 
 		var startOffset = offset.value;
 		var channels = [];
@@ -124,11 +720,11 @@ THREE.EXRLoader.prototype._parser = function ( buffer ) {
 		while ( offset.value < ( startOffset + size - 1 ) ) {
 
 			var name = parseNullTerminatedString( buffer, offset );
-			var pixelType = parseUint32( buffer, offset ); // TODO: Cast this to UINT, HALF or FLOAT
-			var pLinear = parseUint8( buffer, offset );
+			var pixelType = parseUint32( dataView, offset ); // TODO: Cast this to UINT, HALF or FLOAT
+			var pLinear = parseUint8( dataView, offset );
 			offset.value += 3; // reserved, three chars
-			var xSampling = parseUint32( buffer, offset );
-			var ySampling = parseUint32( buffer, offset );
+			var xSampling = parseUint32( dataView, offset );
+			var ySampling = parseUint32( dataView, offset );
 
 			channels.push( {
 				name: name,
@@ -146,67 +742,70 @@ THREE.EXRLoader.prototype._parser = function ( buffer ) {
 
 	}
 
-	function parseChromaticities( buffer, offset ) {
+	function parseChromaticities( dataView, offset ) {
 
-		var redX = parseFloat32( buffer, offset );
-		var redY = parseFloat32( buffer, offset );
-		var greenX = parseFloat32( buffer, offset );
-		var greenY = parseFloat32( buffer, offset );
-		var blueX = parseFloat32( buffer, offset );
-		var blueY = parseFloat32( buffer, offset );
-		var whiteX = parseFloat32( buffer, offset );
-		var whiteY = parseFloat32( buffer, offset );
+		var redX = parseFloat32( dataView, offset );
+		var redY = parseFloat32( dataView, offset );
+		var greenX = parseFloat32( dataView, offset );
+		var greenY = parseFloat32( dataView, offset );
+		var blueX = parseFloat32( dataView, offset );
+		var blueY = parseFloat32( dataView, offset );
+		var whiteX = parseFloat32( dataView, offset );
+		var whiteY = parseFloat32( dataView, offset );
 
 		return { redX: redX, redY: redY, greenX, greenY, blueX, blueY, whiteX, whiteY };
 
 	}
 
-	function parseCompression( buffer, offset ) {
+	function parseCompression( dataView, offset ) {
 
 		var compressionCodes = [
 			'NO_COMPRESSION',
+			'RLE_COMPRESSION',
+			'ZIPS_COMPRESSION',
+			'ZIP_COMPRESSION',
 			'PIZ_COMPRESSION'
 		];
 
-		var compression = parseUint8( buffer, offset );
+		var compression = parseUint8( dataView, offset );
 
 		return compressionCodes[ compression ];
 
 	}
 
-	function parseBox2i( buffer, offset ) {
+	function parseBox2i( dataView, offset ) {
 
-		var xMin = parseUint32( buffer, offset );
-		var yMin = parseUint32( buffer, offset );
-		var xMax = parseUint32( buffer, offset );
-		var yMax = parseUint32( buffer, offset );
+		var xMin = parseUint32( dataView, offset );
+		var yMin = parseUint32( dataView, offset );
+		var xMax = parseUint32( dataView, offset );
+		var yMax = parseUint32( dataView, offset );
 
 		return { xMin: xMin, yMin: yMin, xMax: xMax, yMax: yMax };
 
 	}
 
-	function parseLineOrder( buffer, offset ) {
+	function parseLineOrder( dataView, offset ) {
 
 		var lineOrders = [
 			'INCREASING_Y'
 		];
 
-		var lineOrder = parseUint8( buffer, offset );
+		var lineOrder = parseUint8( dataView, offset );
 
 		return lineOrders[ lineOrder ];
 
 	}
 
-	function parseV2f( buffer, offset ) {
+	function parseV2f( dataView, offset ) {
 
-		var x = parseFloat32( buffer, offset );
-		var y = parseFloat32( buffer, offset );
+		var x = parseFloat32( dataView, offset );
+		var y = parseFloat32( dataView, offset );
 
 		return [ x, y ];
 
 	}
 
-	function parseValue( buffer, offset, type, size ) {
+	function parseValue( dataView, buffer, offset, type, size ) {
 
 		if ( type == 'string' || type == 'iccProfile' ) {
 
@@ -214,7 +813,7 @@ THREE.EXRLoader.prototype._parser = function ( buffer ) {
 
 		} else if ( type == 'chlist' ) {
 
-			return parseChlist( buffer, offset, size );
+			return parseChlist( dataView, buffer, offset, size );
 
 		} else if ( type == 'chromaticities' ) {
 
@@ -222,23 +821,23 @@ THREE.EXRLoader.prototype._parser = function ( buffer ) {
 
 		} else if ( type == 'compression' ) {
 
-			return parseCompression( buffer, offset );
+			return parseCompression( dataView, offset );
 
 		} else if ( type == 'box2i' ) {
 
-			return parseBox2i( buffer, offset );
+			return parseBox2i( dataView, offset );
 
 		} else if ( type == 'lineOrder' ) {
 
-			return parseLineOrder( buffer, offset );
+			return parseLineOrder( dataView, offset );
 
 		} else if ( type == 'float' ) {
 
-			return parseFloat32( buffer, offset );
+			return parseFloat32( dataView, offset );
 
 		} else if ( type == 'v2f' ) {
 
-			return parseV2f( buffer, offset );
+			return parseV2f( dataView, offset );
 
 		} else {
 
@@ -248,11 +847,14 @@ THREE.EXRLoader.prototype._parser = function ( buffer ) {
 
 	}
 
+	var bufferDataView = new DataView(buffer);
+	var uInt8Array = new Uint8Array(buffer);
+
 	var EXRHeader = {};
 
-	var magic = new DataView( buffer ).getUint32( 0, true );
-	var versionByteZero = new DataView( buffer ).getUint8( 4, true );
-	var fullMask = new DataView( buffer ).getUint8( 5, true );
+	var magic = bufferDataView.getUint32( 0, true );
+	var versionByteZero = bufferDataView.getUint8( 4, true );
+	var fullMask = bufferDataView.getUint8( 5, true );
 
 	// start of header
 
@@ -271,8 +873,8 @@ THREE.EXRLoader.prototype._parser = function ( buffer ) {
 		} else {
 
 			var attributeType = parseNullTerminatedString( buffer, offset );
-			var attributeSize = parseUint32( buffer, offset );
-			var attributeValue = parseValue( buffer, offset, attributeType, attributeSize );
+			var attributeSize = parseUint32( bufferDataView, offset );
+			var attributeValue = parseValue( bufferDataView, buffer, offset, attributeType, attributeSize );
 
 			EXRHeader[ attributeName ] = attributeValue;
 
@@ -283,12 +885,15 @@ THREE.EXRLoader.prototype._parser = function ( buffer ) {
 	// offsets
 
 	var dataWindowHeight = EXRHeader.dataWindow.yMax + 1;
-	var scanlineBlockSize = 1; // 1 for no compression, 32 for PIZ
+	var scanlineBlockSize = 1; // 1 for NO_COMPRESSION
+	if (EXRHeader.compression == 'PIZ_COMPRESSION') {
+		scanlineBlockSize = 32;
+	}
 	var numBlocks = dataWindowHeight / scanlineBlockSize;
 
 	for ( var i = 0; i < numBlocks; i ++ ) {
 
-		var scanlineOffset = parseUlong( buffer, offset );
+		var scanlineOffset = parseUlong( bufferDataView, offset );
 
 	}
 
@@ -307,33 +912,86 @@ THREE.EXRLoader.prototype._parser = function ( buffer ) {
 		A: 3
 	};
 
-	for ( var y = 0; y < height; y ++ ) {
+	if (EXRHeader.compression == 'NO_COMPRESSION') {
 
-		var y_scanline = parseUint32( buffer, offset );
-		var dataSize = parseUint32( buffer, offset );
+		for ( var y = 0; y < height; y ++ ) {
 
-		for ( var channelID = 0; channelID < EXRHeader.channels.length; channelID ++ ) {
+			var y_scanline = parseUint32( buffer, offset );
+			var dataSize = parseUint32( buffer, offset );
 
-			if ( EXRHeader.channels[ channelID ].pixelType == 1 ) {
+			for ( var channelID = 0; channelID < EXRHeader.channels.length; channelID ++ ) {
 
-				// HALF
-				for ( var x = 0; x < width; x ++ ) {
+				var cOff = channelOffsets[ EXRHeader.channels[ channelID ].name ];
 
-					var val = parseFloat16( buffer, offset );
-					var cOff = channelOffsets[ EXRHeader.channels[ channelID ].name ];
+				if ( EXRHeader.channels[ channelID ].pixelType == 1 ) {
+
+					// HALF
+					for ( var x = 0; x < width; x ++ ) {
+
+						var val = parseFloat16( buffer, offset );
+
+						byteArray[ ( ( ( width - y_scanline ) * ( height * numChannels ) ) + ( x * numChannels ) ) + cOff ] = val;
+
+					}
 
-					byteArray[ ( ( ( width - y_scanline ) * ( height * numChannels ) ) + ( x * numChannels ) ) + cOff ] = val;
+				} else {
+
+					throw 'Only supported pixel format is HALF';
 
 				}
 
-			} else {
+			}
+
+		}
+
+	} else if (EXRHeader.compression == 'PIZ_COMPRESSION') {
+
+		for ( var scanlineBlockIdx = 0; scanlineBlockIdx < height / scanlineBlockSize; scanlineBlockIdx++ ) {
+
+			var line_no = parseUint32( bufferDataView, offset );
+			var data_len = parseUint32( bufferDataView, offset );
+
+			var tmpBufferSize = width * scanlineBlockSize * (EXRHeader.channels.length * BYTES_PER_HALF);
+			var tmpBuffer = new Uint16Array(tmpBufferSize);
+			var tmpOffset = { value: 0 };
+
+			decompressPIZ(tmpBuffer, tmpOffset, uInt8Array, bufferDataView, offset, tmpBufferSize, numChannels, EXRHeader.channels, width, scanlineBlockSize);
+
+			for ( var line_y = 0; line_y < scanlineBlockSize; line_y ++ ) {
+
+				for ( var channelID = 0; channelID < EXRHeader.channels.length; channelID ++ ) {
+
+					var cOff = channelOffsets[ EXRHeader.channels[ channelID ].name ];
+
+					if ( EXRHeader.channels[ channelID ].pixelType == 1 ) {
+
+						// HALF
+						for ( var x = 0; x < width; x ++ ) {
+
+							var val = decodeFloat16(tmpBuffer[ (channelID * (scanlineBlockSize * width)) + (line_y * width) + x ]);
+
+							var true_y = line_y + (scanlineBlockIdx * scanlineBlockSize);
+
+							byteArray[ ( ( (height - true_y) * ( width * numChannels ) ) + ( x * numChannels ) ) + cOff ] = val;
+
+						}
 
-				throw 'Only supported pixel format is HALF';
+					} else {
+
+						throw 'Only supported pixel format is HALF';
+
+					}
+
+				}
 
 			}
 
 		}
 
+	} else {
+
+		throw 'Cannot decompress unsupported compression';
+
 	}
 
 	return {
@@ -341,7 +999,7 @@ THREE.EXRLoader.prototype._parser = function ( buffer ) {
 		width: width,
 		height: height,
 		data: byteArray,
-		format: THREE.RGBAFormat,
+		format: THREE.RGBFormat,
 		type: THREE.FloatType
 	};
 

+ 85 - 24
examples/js/loaders/GLTFLoader.js

@@ -128,6 +128,12 @@ THREE.GLTFLoader = ( function () {
 
 				}
 
+				if ( json.extensionsUsed.indexOf( EXTENSIONS.KHR_MATERIALS_UNLIT ) >= 0 ) {
+
+					extensions[ EXTENSIONS.KHR_MATERIALS_UNLIT ] = new GLTFMaterialsUnlitExtension( json );
+
+				}
+
 				if ( json.extensionsUsed.indexOf( EXTENSIONS.KHR_MATERIALS_PBR_SPECULAR_GLOSSINESS ) >= 0 ) {
 
 					extensions[ EXTENSIONS.KHR_MATERIALS_PBR_SPECULAR_GLOSSINESS ] = new GLTFMaterialsPbrSpecularGlossinessExtension();
@@ -216,7 +222,8 @@ THREE.GLTFLoader = ( function () {
 		KHR_BINARY_GLTF: 'KHR_binary_glTF',
 		KHR_DRACO_MESH_COMPRESSION: 'KHR_draco_mesh_compression',
 		KHR_LIGHTS: 'KHR_lights',
-		KHR_MATERIALS_PBR_SPECULAR_GLOSSINESS: 'KHR_materials_pbrSpecularGlossiness'
+		KHR_MATERIALS_PBR_SPECULAR_GLOSSINESS: 'KHR_materials_pbrSpecularGlossiness',
+		KHR_MATERIALS_UNLIT: 'KHR_materials_unlit'
 	};
 
 	/**
@@ -303,6 +310,55 @@ THREE.GLTFLoader = ( function () {
 
 	}
 
+	/**
+	 * Unlit Materials Extension (pending)
+	 *
+	 * PR: https://github.com/KhronosGroup/glTF/pull/1163
+	 */
+	function GLTFMaterialsUnlitExtension( json ) {
+
+		this.name = EXTENSIONS.KHR_MATERIALS_UNLIT;
+
+	}
+
+	GLTFMaterialsUnlitExtension.prototype.getMaterialType = function ( material ) {
+
+		return THREE.MeshBasicMaterial;
+
+	};
+
+	GLTFMaterialsUnlitExtension.prototype.extendParams = function ( materialParams, material, parser ) {
+
+		var pending = [];
+
+		materialParams.color = new THREE.Color( 1.0, 1.0, 1.0 );
+		materialParams.opacity = 1.0;
+
+		var metallicRoughness = material.pbrMetallicRoughness;
+
+		if ( metallicRoughness ) {
+
+			if ( Array.isArray( metallicRoughness.baseColorFactor ) ) {
+
+				var array = metallicRoughness.baseColorFactor;
+
+				materialParams.color.fromArray( array );
+				materialParams.opacity = array[ 3 ];
+
+			}
+
+			if ( metallicRoughness.baseColorTexture !== undefined ) {
+
+				pending.push( parser.assignTexture( materialParams, 'map', metallicRoughness.baseColorTexture.index ) );
+
+			}
+
+		}
+
+		return Promise.all( pending );
+
+	};
+
 	/* BINARY EXTENSION */
 
 	var BINARY_EXTENSION_BUFFER_NAME = 'binary_glTF';
@@ -1205,6 +1261,17 @@ THREE.GLTFLoader = ( function () {
 
 		}
 
+		// .extras has user-defined data, so check that .extras.targetNames is an array.
+		if ( meshDef.extras && Array.isArray( meshDef.extras.targetNames ) ) {
+
+			for ( var i = 0, il = meshDef.extras.targetNames.length; i < il; i ++ ) {
+
+				mesh.morphTargetDictionary[ meshDef.extras.targetNames[ i ] ] = i;
+
+			}
+
+		}
+
 	}
 
 	function isPrimitiveEqual( a, b ) {
@@ -1797,6 +1864,12 @@ THREE.GLTFLoader = ( function () {
 			materialType = sgExtension.getMaterialType( materialDef );
 			pending.push( sgExtension.extendParams( materialParams, materialDef, parser ) );
 
+		} else if ( materialExtensions[ EXTENSIONS.KHR_MATERIALS_UNLIT ] ) {
+
+			var kmuExtension = extensions[ EXTENSIONS.KHR_MATERIALS_UNLIT ];
+			materialType = kmuExtension.getMaterialType( materialDef );
+			pending.push( kmuExtension.extendParams( materialParams, materialDef, parser ) );
+
 		} else if ( materialDef.pbrMetallicRoughness !== undefined ) {
 
 			// Specification:
@@ -1865,7 +1938,7 @@ THREE.GLTFLoader = ( function () {
 
 		}
 
-		if ( materialDef.normalTexture !== undefined ) {
+		if ( materialDef.normalTexture !== undefined && materialType !== THREE.MeshBasicMaterial) {
 
 			pending.push( parser.assignTexture( materialParams, 'normalMap', materialDef.normalTexture.index ) );
 
@@ -1879,7 +1952,7 @@ THREE.GLTFLoader = ( function () {
 
 		}
 
-		if ( materialDef.occlusionTexture !== undefined ) {
+		if ( materialDef.occlusionTexture !== undefined && materialType !== THREE.MeshBasicMaterial) {
 
 			pending.push( parser.assignTexture( materialParams, 'aoMap', materialDef.occlusionTexture.index ) );
 
@@ -1891,31 +1964,15 @@ THREE.GLTFLoader = ( function () {
 
 		}
 
-		if ( materialDef.emissiveFactor !== undefined ) {
-
-			if ( materialType === THREE.MeshBasicMaterial ) {
-
-				materialParams.color = new THREE.Color().fromArray( materialDef.emissiveFactor );
+		if ( materialDef.emissiveFactor !== undefined && materialType !== THREE.MeshBasicMaterial) {
 
-			} else {
-
-				materialParams.emissive = new THREE.Color().fromArray( materialDef.emissiveFactor );
-
-			}
+			materialParams.emissive = new THREE.Color().fromArray( materialDef.emissiveFactor );
 
 		}
 
-		if ( materialDef.emissiveTexture !== undefined ) {
+		if ( materialDef.emissiveTexture !== undefined && materialType !== THREE.MeshBasicMaterial) {
 
-			if ( materialType === THREE.MeshBasicMaterial ) {
-
-				pending.push( parser.assignTexture( materialParams, 'map', materialDef.emissiveTexture.index ) );
-
-			} else {
-
-				pending.push( parser.assignTexture( materialParams, 'emissiveMap', materialDef.emissiveTexture.index ) );
-
-			}
+			pending.push( parser.assignTexture( materialParams, 'emissiveMap', materialDef.emissiveTexture.index ) );
 
 		}
 
@@ -2453,7 +2510,7 @@ THREE.GLTFLoader = ( function () {
 							// Overrides .createInterpolant in a factory method which creates custom interpolation.
 							if ( sampler.interpolation === 'CUBICSPLINE' ) {
 
-								track.createInterpolant = function ( result ) {
+								track.createInterpolant = function InterpolantFactoryMethodGLTFCubicSpline( result ) {
 
 									// A CUBICSPLINE keyframe in glTF has three output values for each input value,
 									// representing inTangent, splineVertex, and outTangent. As a result, track.getValueSize()
@@ -2463,6 +2520,10 @@ THREE.GLTFLoader = ( function () {
 
 								};
 
+								// Workaround, provide an alternate way to know if the interpolant type is cubis spline to track.
+								// track.getInterpolation() doesn't return valid value for custom interpolant.
+								track.createInterpolant.isInterpolantFactoryMethodGLTFCubicSpline = true;
+
 							}
 
 							tracks.push( track );

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

@@ -1476,7 +1476,7 @@ THREE.MMDLoader.prototype.createMesh = function ( model, texturePath, onProgress
 		geometry.addAttribute( 'position', new THREE.Float32BufferAttribute( buffer.vertices, 3 ) );
 		geometry.addAttribute( 'normal', new THREE.Float32BufferAttribute( buffer.normals, 3 ) );
 		geometry.addAttribute( 'uv', new THREE.Float32BufferAttribute( buffer.uvs, 2 ) );
-		geometry.addAttribute( 'skinIndex', new THREE.Float32BufferAttribute( buffer.skinIndices, 4 ) );
+		geometry.addAttribute( 'skinIndex', new THREE.Uint16BufferAttribute( buffer.skinIndices, 4 ) );
 		geometry.addAttribute( 'skinWeight', new THREE.Float32BufferAttribute( buffer.skinWeights, 4 ) );
 
 		geometry.computeBoundingSphere();

+ 2 - 4
examples/js/loaders/OBJLoader.js

@@ -286,19 +286,17 @@ THREE.OBJLoader = ( function () {
 
 				this.addVertex( ia, ib, ic );
 
-				if ( ua !== undefined ) {
+				if ( ua !== undefined && ua !== '' ) {
 
 					var uvLen = this.uvs.length;
-
 					ia = this.parseUVIndex( ua, uvLen );
 					ib = this.parseUVIndex( ub, uvLen );
 					ic = this.parseUVIndex( uc, uvLen );
-
 					this.addUV( ia, ib, ic );
 
 				}
 
-				if ( na !== undefined ) {
+				if ( na !== undefined && na !== '' ) {
 
 					// Normals are many times the same. If so, skip function call and parseInt.
 					var nLen = this.normals.length;

+ 7 - 5
examples/js/math/Lut.js

@@ -451,16 +451,16 @@ THREE.Lut.prototype = {
 
 				var material = new THREE.LineBasicMaterial( { color: 0x000000, linewidth: 2 } );
 
-				var geometry = new THREE.Geometry();
+				var points = [];
 
 
 				if ( this.legend.layout == 'vertical' ) {
 
 					var linePosition = ( this.legend.position.y - ( this.legend.dimensions.height * 0.5 ) + 0.01 ) + ( this.legend.dimensions.height ) * ( ( value - this.minV ) / ( this.maxV - this.minV ) * 0.99 );
 
-					geometry.vertices.push( new THREE.Vector3( this.legend.position.x + this.legend.dimensions.width * 0.55, linePosition, this.legend.position.z  ) );
+					points.push( new THREE.Vector3( this.legend.position.x + this.legend.dimensions.width * 0.55, linePosition, this.legend.position.z  ) );
 
-					geometry.vertices.push( new THREE.Vector3( this.legend.position.x + this.legend.dimensions.width * 0.7, linePosition, this.legend.position.z  ) );
+					points.push( new THREE.Vector3( this.legend.position.x + this.legend.dimensions.width * 0.7, linePosition, this.legend.position.z  ) );
 
 				}
 
@@ -468,12 +468,14 @@ THREE.Lut.prototype = {
 
 					var linePosition = ( this.legend.position.x - ( this.legend.dimensions.height * 0.5 ) + 0.01 ) + ( this.legend.dimensions.height ) * ( ( value - this.minV ) / ( this.maxV - this.minV ) * 0.99 );
 
-					geometry.vertices.push( new THREE.Vector3( linePosition, this.legend.position.y - this.legend.dimensions.width * 0.55, this.legend.position.z  ) );
+					points.push( new THREE.Vector3( linePosition, this.legend.position.y - this.legend.dimensions.width * 0.55, this.legend.position.z  ) );
 
-					geometry.vertices.push( new THREE.Vector3( linePosition, this.legend.position.y - this.legend.dimensions.width * 0.7, this.legend.position.z  ) );
+					points.push( new THREE.Vector3( linePosition, this.legend.position.y - this.legend.dimensions.width * 0.7, this.legend.position.z  ) );
 
 				}
 
+				var geometry = new THREE.BufferGeometry().setFromPoints( points );
+
 				var line = new THREE.Line( geometry, material );
 
 				lines[ i ] = line;

+ 0 - 2
examples/js/objects/Lensflare.js

@@ -35,8 +35,6 @@ THREE.Lensflare = function () {
 
 	var geometry = THREE.Lensflare.Geometry;
 
-	var shader = THREE.Lensflare.Shader;
-
 	var material1a = new THREE.RawShaderMaterial( {
 		uniforms: {
 			'scale': { value: null },

+ 2 - 1
examples/js/objects/Sky.js

@@ -25,7 +25,7 @@ THREE.Sky = function () {
 		side: THREE.BackSide
 	} );
 
-	THREE.Mesh.call( this, new THREE.SphereBufferGeometry( 1, 32, 15 ), material );
+	THREE.Mesh.call( this, new THREE.BoxBufferGeometry( 1, 1, 1 ), material );
 
 };
 
@@ -96,6 +96,7 @@ THREE.Sky.SkyShader = {
 		'	vWorldPosition = worldPosition.xyz;',
 
 		'	gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );',
+		'	gl_Position.z = gl_Position.w;', // set z to camera.far
 
 		'	vSunDirection = normalize( sunPosition );',
 

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

@@ -102,7 +102,7 @@ THREE.AdaptiveToneMappingPass = function ( adaptive, resolution ) {
 		uniforms: THREE.UniformsUtils.clone( this.adaptLuminanceShader.uniforms ),
 		vertexShader: this.adaptLuminanceShader.vertexShader,
 		fragmentShader: this.adaptLuminanceShader.fragmentShader,
-		defines: this.adaptLuminanceShader.defines,
+		defines: Object.assign( {}, this.adaptLuminanceShader.defines ),
 		blending: THREE.NoBlending
 	} );
 

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

@@ -57,7 +57,7 @@ THREE.BokehPass = function ( scene, camera, params ) {
 	bokehUniforms[ "farClip" ].value = camera.far;
 
 	this.materialBokeh = new THREE.ShaderMaterial( {
-		defines: bokehShader.defines,
+		defines: Object.assign( {}, bokehShader.defines ),
 		uniforms: bokehUniforms,
 		vertexShader: bokehShader.vertexShader,
 		fragmentShader: bokehShader.fragmentShader

+ 8 - 4
examples/js/postprocessing/SAOPass.js

@@ -74,9 +74,13 @@ THREE.SAOPass = function ( scene, camera, depthTexture, useNormals, resolution )
 
 	}
 
-	this.saoMaterial = new THREE.ShaderMaterial( THREE.SAOShader );
+	this.saoMaterial = new THREE.ShaderMaterial( {
+		defines: Object.assign( {}, THREE.SAOShader.defines ),
+		fragmentShader: THREE.SAOShader.fragmentShader,
+		vertexShader: THREE.SAOShader.vertexShader,
+		uniforms: THREE.UniformsUtils.clone( THREE.SAOShader.uniforms )
+	} );
 	this.saoMaterial.extensions.derivatives = true;
-	this.saoMaterial.extensions.drawBuffers = true;
 	this.saoMaterial.defines[ 'DEPTH_PACKING' ] = this.supportsDepthTextureExtension ? 0 : 1;
 	this.saoMaterial.defines[ 'NORMAL_TEXTURE' ] = this.supportsNormalTexture ? 1 : 0;
 	this.saoMaterial.defines[ 'PERSPECTIVE_CAMERA' ] = this.camera.isPerspectiveCamera ? 1 : 0;
@@ -95,7 +99,7 @@ THREE.SAOPass = function ( scene, camera, depthTexture, useNormals, resolution )
 
 	this.vBlurMaterial = new THREE.ShaderMaterial( {
 		uniforms: THREE.UniformsUtils.clone( THREE.DepthLimitedBlurShader.uniforms ),
-		defines: THREE.DepthLimitedBlurShader.defines,
+		defines: Object.assign( {}, THREE.DepthLimitedBlurShader.defines ),
 		vertexShader: THREE.DepthLimitedBlurShader.vertexShader,
 		fragmentShader: THREE.DepthLimitedBlurShader.fragmentShader
 	} );
@@ -108,7 +112,7 @@ THREE.SAOPass = function ( scene, camera, depthTexture, useNormals, resolution )
 
 	this.hBlurMaterial = new THREE.ShaderMaterial( {
 		uniforms: THREE.UniformsUtils.clone( THREE.DepthLimitedBlurShader.uniforms ),
-		defines: THREE.DepthLimitedBlurShader.defines,
+		defines: Object.assign( {}, THREE.DepthLimitedBlurShader.defines ),
 		vertexShader: THREE.DepthLimitedBlurShader.vertexShader,
 		fragmentShader: THREE.DepthLimitedBlurShader.fragmentShader
 	} );

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

@@ -63,7 +63,7 @@ THREE.SMAAPass = function ( width, height ) {
 	this.uniformsEdges[ "resolution" ].value.set( 1 / width, 1 / height );
 
 	this.materialEdges = new THREE.ShaderMaterial( {
-		defines: THREE.SMAAShader[0].defines,
+		defines: Object.assign( {}, THREE.SMAAShader[ 0 ].defines ),
 		uniforms: this.uniformsEdges,
 		vertexShader: THREE.SMAAShader[0].vertexShader,
 		fragmentShader: THREE.SMAAShader[0].fragmentShader
@@ -79,7 +79,7 @@ THREE.SMAAPass = function ( width, height ) {
 	this.uniformsWeights[ "tSearch" ].value = this.searchTexture;
 
 	this.materialWeights = new THREE.ShaderMaterial( {
-		defines: THREE.SMAAShader[1].defines,
+		defines: Object.assign( {}, THREE.SMAAShader[ 1 ].defines ),
 		uniforms: this.uniformsWeights,
 		vertexShader: THREE.SMAAShader[1].vertexShader,
 		fragmentShader: THREE.SMAAShader[1].fragmentShader

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

@@ -20,7 +20,7 @@ THREE.ShaderPass = function ( shader, textureID ) {
 
 		this.material = new THREE.ShaderMaterial( {
 
-			defines: shader.defines || {},
+			defines: Object.assign( {}, shader.defines ),
 			uniforms: this.uniforms,
 			vertexShader: shader.vertexShader,
 			fragmentShader: shader.fragmentShader

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

@@ -120,7 +120,7 @@ THREE.WebGLDeferredRenderer = function ( parameters ) {
 
 	function init( parameters ) {
 
-		_this.renderer = parameters.renderer !== undefined ? parameters.renderer : new THREE.WebGLRenderer( { antialias: false } );
+		_this.renderer = parameters.renderer !== undefined ? parameters.renderer : new THREE.WebGLRenderer();
 		_this.domElement = _this.renderer.domElement;
 
 		_gl = _this.renderer.context;

+ 10 - 1
examples/js/vr/DaydreamController.js

@@ -42,7 +42,7 @@ THREE.DaydreamController = function () {
 
 	};
 
-	this.getTouchPadState = function () {
+	this.getTouchpadState = function () {
 
 		return touchpadIsPressed;
 
@@ -103,6 +103,15 @@ THREE.DaydreamController = function () {
 
 	};
 
+	// DEPRECATED
+
+	this.getTouchPadState = function () {
+
+		console.warn( 'THREE.DaydreamController: getTouchPadState() is now getTouchpadState()' );
+		return touchpadIsPressed;
+
+	};
+
 };
 
 THREE.DaydreamController.prototype = Object.create( THREE.Object3D.prototype );

+ 10 - 1
examples/js/vr/GearVRController.js

@@ -60,7 +60,7 @@ THREE.GearVRController = function () {
 
 	};
 
-	this.getTouchPadState = function () {
+	this.getTouchpadState = function () {
 
 		return touchpadIsPressed;
 
@@ -131,6 +131,15 @@ THREE.GearVRController = function () {
 
 	};
 
+	// DEPRECATED
+
+	this.getTouchPadState = function () {
+
+		console.warn( 'THREE.GearVRController: getTouchPadState() is now getTouchpadState()' );
+		return touchpadIsPressed;
+
+	};
+
 };
 
 THREE.GearVRController.prototype = Object.create( THREE.Object3D.prototype );

+ 17 - 10
examples/misc_controls_orbit.html

@@ -48,8 +48,8 @@
 			var camera, controls, scene, renderer;
 
 			init();
-			render(); // remove when using next line for animation loop (requestAnimationFrame)
-			//animate();
+			//render(); // remove when using next line for animation loop (requestAnimationFrame)
+			animate();
 
 			function init() {
 
@@ -67,13 +67,20 @@
 				camera = new THREE.PerspectiveCamera( 60, window.innerWidth / window.innerHeight, 1, 1000 );
 				camera.position.set( 400, 200, 0 );
 
+				// controls
+
 				controls = new THREE.OrbitControls( camera, renderer.domElement );
-				controls.addEventListener( 'change', render ); // remove when using animation loop
-				// enable animation loop when using damping or autorotation
-				//controls.enableDamping = true;
-				//controls.dampingFactor = 0.25;
+
+				//controls.addEventListener( 'change', render ); // call this only in static scenes (i.e., if there is no animation loop)
+
+				controls.enableDamping = true; // an animation loop is required when either damping or auto-rotation are enabled
+				controls.dampingFactor = 0.25;
+
+				controls.panningMode = THREE.HorizontalPanning; // default is THREE.ScreenSpacePanning
+
 				controls.minDistance = 100;
 				controls.maxDistance = 500
+
 				controls.maxPolarAngle = Math.PI / 2;
 
 				// world
@@ -84,9 +91,9 @@
 				for ( var i = 0; i < 500; i ++ ) {
 
 					var mesh = new THREE.Mesh( geometry, material );
-					mesh.position.x = ( Math.random() - 0.5 ) * 1000;
+					mesh.position.x = Math.random() * 1600 - 800;
 					mesh.position.y = 0;
-					mesh.position.z = ( Math.random() - 0.5 ) * 1000;
+					mesh.position.z = Math.random() * 1600 - 800;
 					mesh.updateMatrix();
 					mesh.matrixAutoUpdate = false;
 					scene.add( mesh );
@@ -100,7 +107,7 @@
 				scene.add( light );
 
 				var light = new THREE.DirectionalLight( 0x002288 );
-				light.position.set( -1, -1, -1 );
+				light.position.set( - 1, - 1, - 1 );
 				scene.add( light );
 
 				var light = new THREE.AmbientLight( 0x222222 );
@@ -125,7 +132,7 @@
 
 				requestAnimationFrame( animate );
 
-				//controls.update(); // only required if controls.enableDamping = true, or if controls.autoRotate = true
+				controls.update(); // only required if controls.enableDamping = true, or if controls.autoRotate = true
 
 				render();
 

+ 1 - 1
examples/misc_controls_trackball.html

@@ -117,7 +117,7 @@
 
 				// renderer
 
-				renderer = new THREE.WebGLRenderer( { antialias: false } );
+				renderer = new THREE.WebGLRenderer();
 				renderer.setPixelRatio( window.devicePixelRatio );
 				renderer.setSize( window.innerWidth, window.innerHeight );
 

+ 29 - 3
examples/misc_exporter_gltf.html

@@ -26,6 +26,7 @@
 			<button id="export_scene">Export Scene1</button>
 			<button id="export_scenes">Export Scene1 and Scene 2</button>
 			<button id="export_object">Export Sphere</button>
+			<button id="export_obj">Export WaltHead</button>
 			<button id="export_objects">Export Sphere and Grid</button>
 			<button id="export_scene_object">Export Scene1 and Sphere</button>
 			<br/>
@@ -33,11 +34,14 @@
 			<label><input id="option_visible" name="visible" type="checkbox" checked="checked"/>Only Visible</label>
 			<label><input id="option_drawrange" name="visible" type="checkbox" checked="checked"/>Truncate drawRange</label>
 			<label><input id="option_binary" name="visible" type="checkbox">Binary (<code>.glb</code>)</label>
+			<label><input id="option_forceindices" name="visible" type="checkbox">Force indices</label>
+			<label><input id="option_forcepot" name="visible" type="checkbox">Force POT textures</label>
 		</div>
 
 		<script src="../build/three.js"></script>
 
 		<script src="js/Detector.js"></script>
+		<script src="js/loaders/OBJLoader.js"></script>
 		<script src="js/exporters/GLTFExporter.js"></script>
 
 		<script>
@@ -50,7 +54,9 @@
 					trs: document.getElementById('option_trs').checked,
 					onlyVisible: document.getElementById('option_visible').checked,
 					truncateDrawRange: document.getElementById('option_drawrange').checked,
-					binary: document.getElementById('option_binary').checked
+					binary: document.getElementById('option_binary').checked,
+					forceIndices: document.getElementById('option_forceindices').checked,
+					forcePowerOfTwoTextures: document.getElementById('option_forcepot').checked
 				};
 				gltfExporter.parse( input, function( result ) {
 
@@ -88,6 +94,12 @@
 
 			} );
 
+			document.getElementById( 'export_obj' ).addEventListener( 'click', function () {
+
+				exportGLTF( waltHead );
+
+			} );
+
 			document.getElementById( 'export_objects' ).addEventListener( 'click', function () {
 
 				exportGLTF( [ sphere, gridHelper ] );
@@ -133,7 +145,7 @@
 			var container;
 
 			var camera, object, scene1, scene2, renderer;
-			var gridHelper, sphere;
+			var gridHelper, sphere, waltHead;
 
 			init();
 			animate();
@@ -428,7 +440,7 @@
 				// ---------------------------------------------------------------------
 				// Ortho camera
 				// ---------------------------------------------------------------------
-				var cameraOrtho = new THREE.OrthographicCamera( window.innerWidth / - 2, window.innerWidth / 2, window.innerHeight / 2, window.innerHeight / - 2, - 10, 10 );
+				var cameraOrtho = new THREE.OrthographicCamera( window.innerWidth / - 2, window.innerWidth / 2, window.innerHeight / 2, window.innerHeight / - 2, 0.1, 10 );
 				scene1.add( cameraOrtho );
 				cameraOrtho.name = 'OrthographicCamera';
 
@@ -474,6 +486,20 @@
 				object.visible = false;
 				scene1.add( object );
 
+				// ---------------------------------------------------------------------
+				//
+				//
+				var loader = new THREE.OBJLoader();
+				loader.load( 'models/obj/walt/WaltHead.obj', function ( obj ) {
+
+					waltHead = obj;
+					waltHead.scale.multiplyScalar( 1.5 );
+					waltHead.position.set(400, 0, 0);
+					scene1.add( waltHead );
+
+				} );
+				
+				
 				// ---------------------------------------------------------------------
 				// 2nd Scene
 				// ---------------------------------------------------------------------

BIN
examples/models/gltf/BotSkinned/glTF-MaterialsUnlit/AvatarBotA_Head_Tex_Combined.png


BIN
examples/models/gltf/BotSkinned/glTF-MaterialsUnlit/AvatarBotA_Tex_Combined.png


+ 2265 - 0
examples/models/gltf/BotSkinned/glTF-MaterialsUnlit/Bot_Skinned.gltf

@@ -0,0 +1,2265 @@
+{
+    "asset": {
+        "generator": "FBX2glTF",
+        "version": "2.0"
+    },
+    "scene": 0,
+    "extensionsUsed": [
+        "KHR_materials_unlit"
+    ],
+    "buffers": [
+        {
+            "byteLength": 272844,
+            "uri": "buffer.bin"
+        }
+    ],
+    "bufferViews": [
+        {
+            "buffer": 0,
+            "byteLength": 644,
+            "byteOffset": 0
+        },
+        {
+            "buffer": 0,
+            "byteLength": 2576,
+            "byteOffset": 644
+        },
+        {
+            "buffer": 0,
+            "byteLength": 2576,
+            "byteOffset": 3220
+        },
+        {
+            "buffer": 0,
+            "byteLength": 2576,
+            "byteOffset": 5796
+        },
+        {
+            "buffer": 0,
+            "byteLength": 2576,
+            "byteOffset": 8372
+        },
+        {
+            "buffer": 0,
+            "byteLength": 2576,
+            "byteOffset": 10948
+        },
+        {
+            "buffer": 0,
+            "byteLength": 2576,
+            "byteOffset": 13524
+        },
+        {
+            "buffer": 0,
+            "byteLength": 2576,
+            "byteOffset": 16100
+        },
+        {
+            "buffer": 0,
+            "byteLength": 2576,
+            "byteOffset": 18676
+        },
+        {
+            "buffer": 0,
+            "byteLength": 2576,
+            "byteOffset": 21252
+        },
+        {
+            "buffer": 0,
+            "byteLength": 2576,
+            "byteOffset": 23828
+        },
+        {
+            "buffer": 0,
+            "byteLength": 2576,
+            "byteOffset": 26404
+        },
+        {
+            "buffer": 0,
+            "byteLength": 2576,
+            "byteOffset": 28980
+        },
+        {
+            "buffer": 0,
+            "byteLength": 2576,
+            "byteOffset": 31556
+        },
+        {
+            "buffer": 0,
+            "byteLength": 2576,
+            "byteOffset": 34132
+        },
+        {
+            "buffer": 0,
+            "byteLength": 2576,
+            "byteOffset": 36708
+        },
+        {
+            "buffer": 0,
+            "byteLength": 2576,
+            "byteOffset": 39284
+        },
+        {
+            "buffer": 0,
+            "byteLength": 2576,
+            "byteOffset": 41860
+        },
+        {
+            "buffer": 0,
+            "byteLength": 2576,
+            "byteOffset": 44436
+        },
+        {
+            "buffer": 0,
+            "byteLength": 2576,
+            "byteOffset": 47012
+        },
+        {
+            "buffer": 0,
+            "byteLength": 2576,
+            "byteOffset": 49588
+        },
+        {
+            "buffer": 0,
+            "byteLength": 2576,
+            "byteOffset": 52164
+        },
+        {
+            "buffer": 0,
+            "byteLength": 2576,
+            "byteOffset": 54740
+        },
+        {
+            "buffer": 0,
+            "byteLength": 2576,
+            "byteOffset": 57316
+        },
+        {
+            "buffer": 0,
+            "byteLength": 2576,
+            "byteOffset": 59892
+        },
+        {
+            "buffer": 0,
+            "byteLength": 2576,
+            "byteOffset": 62468
+        },
+        {
+            "buffer": 0,
+            "byteLength": 2576,
+            "byteOffset": 65044
+        },
+        {
+            "buffer": 0,
+            "byteLength": 2576,
+            "byteOffset": 67620
+        },
+        {
+            "buffer": 0,
+            "byteLength": 2576,
+            "byteOffset": 70196
+        },
+        {
+            "buffer": 0,
+            "byteLength": 1932,
+            "byteOffset": 72772
+        },
+        {
+            "buffer": 0,
+            "byteLength": 2576,
+            "byteOffset": 74704
+        },
+        {
+            "buffer": 0,
+            "byteLength": 1932,
+            "byteOffset": 77280
+        },
+        {
+            "buffer": 0,
+            "byteLength": 2576,
+            "byteOffset": 79212
+        },
+        {
+            "buffer": 0,
+            "byteLength": 12330,
+            "byteOffset": 81788,
+            "target": 34963
+        },
+        {
+            "buffer": 0,
+            "byteLength": 33108,
+            "byteOffset": 94120,
+            "target": 34962
+        },
+        {
+            "buffer": 0,
+            "byteLength": 33108,
+            "byteOffset": 127228,
+            "target": 34962
+        },
+        {
+            "buffer": 0,
+            "byteLength": 22072,
+            "byteOffset": 160336,
+            "target": 34962
+        },
+        {
+            "buffer": 0,
+            "byteLength": 22072,
+            "byteOffset": 182408,
+            "target": 34962
+        },
+        {
+            "buffer": 0,
+            "byteLength": 44144,
+            "byteOffset": 204480,
+            "target": 34962
+        },
+        {
+            "buffer": 0,
+            "byteLength": 2268,
+            "byteOffset": 248624,
+            "target": 34963
+        },
+        {
+            "buffer": 0,
+            "byteLength": 4032,
+            "byteOffset": 250892,
+            "target": 34962
+        },
+        {
+            "buffer": 0,
+            "byteLength": 4032,
+            "byteOffset": 254924,
+            "target": 34962
+        },
+        {
+            "buffer": 0,
+            "byteLength": 2688,
+            "byteOffset": 258956,
+            "target": 34962
+        },
+        {
+            "buffer": 0,
+            "byteLength": 2688,
+            "byteOffset": 261644,
+            "target": 34962
+        },
+        {
+            "buffer": 0,
+            "byteLength": 5376,
+            "byteOffset": 264332,
+            "target": 34962
+        },
+        {
+            "buffer": 0,
+            "byteLength": 3136,
+            "byteOffset": 269708
+        }
+    ],
+    "scenes": [
+        {
+            "name": "Root Scene",
+            "nodes": [
+                0
+            ]
+        }
+    ],
+    "accessors": [
+        {
+            "componentType": 5126,
+            "type": "SCALAR",
+            "count": 161,
+            "bufferView": 0,
+            "byteOffset": 0,
+            "min": [
+                0.0
+            ],
+            "max": [
+                6.66666650772095
+            ]
+        },
+        {
+            "componentType": 5126,
+            "type": "VEC4",
+            "count": 161,
+            "bufferView": 1,
+            "byteOffset": 0
+        },
+        {
+            "componentType": 5126,
+            "type": "VEC4",
+            "count": 161,
+            "bufferView": 2,
+            "byteOffset": 0
+        },
+        {
+            "componentType": 5126,
+            "type": "VEC4",
+            "count": 161,
+            "bufferView": 3,
+            "byteOffset": 0
+        },
+        {
+            "componentType": 5126,
+            "type": "VEC4",
+            "count": 161,
+            "bufferView": 4,
+            "byteOffset": 0
+        },
+        {
+            "componentType": 5126,
+            "type": "VEC4",
+            "count": 161,
+            "bufferView": 5,
+            "byteOffset": 0
+        },
+        {
+            "componentType": 5126,
+            "type": "VEC4",
+            "count": 161,
+            "bufferView": 6,
+            "byteOffset": 0
+        },
+        {
+            "componentType": 5126,
+            "type": "VEC4",
+            "count": 161,
+            "bufferView": 7,
+            "byteOffset": 0
+        },
+        {
+            "componentType": 5126,
+            "type": "VEC4",
+            "count": 161,
+            "bufferView": 8,
+            "byteOffset": 0
+        },
+        {
+            "componentType": 5126,
+            "type": "VEC4",
+            "count": 161,
+            "bufferView": 9,
+            "byteOffset": 0
+        },
+        {
+            "componentType": 5126,
+            "type": "VEC4",
+            "count": 161,
+            "bufferView": 10,
+            "byteOffset": 0
+        },
+        {
+            "componentType": 5126,
+            "type": "VEC4",
+            "count": 161,
+            "bufferView": 11,
+            "byteOffset": 0
+        },
+        {
+            "componentType": 5126,
+            "type": "VEC4",
+            "count": 161,
+            "bufferView": 12,
+            "byteOffset": 0
+        },
+        {
+            "componentType": 5126,
+            "type": "VEC4",
+            "count": 161,
+            "bufferView": 13,
+            "byteOffset": 0
+        },
+        {
+            "componentType": 5126,
+            "type": "VEC4",
+            "count": 161,
+            "bufferView": 14,
+            "byteOffset": 0
+        },
+        {
+            "componentType": 5126,
+            "type": "VEC4",
+            "count": 161,
+            "bufferView": 15,
+            "byteOffset": 0
+        },
+        {
+            "componentType": 5126,
+            "type": "VEC4",
+            "count": 161,
+            "bufferView": 16,
+            "byteOffset": 0
+        },
+        {
+            "componentType": 5126,
+            "type": "VEC4",
+            "count": 161,
+            "bufferView": 17,
+            "byteOffset": 0
+        },
+        {
+            "componentType": 5126,
+            "type": "VEC4",
+            "count": 161,
+            "bufferView": 18,
+            "byteOffset": 0
+        },
+        {
+            "componentType": 5126,
+            "type": "VEC4",
+            "count": 161,
+            "bufferView": 19,
+            "byteOffset": 0
+        },
+        {
+            "componentType": 5126,
+            "type": "VEC4",
+            "count": 161,
+            "bufferView": 20,
+            "byteOffset": 0
+        },
+        {
+            "componentType": 5126,
+            "type": "VEC4",
+            "count": 161,
+            "bufferView": 21,
+            "byteOffset": 0
+        },
+        {
+            "componentType": 5126,
+            "type": "VEC4",
+            "count": 161,
+            "bufferView": 22,
+            "byteOffset": 0
+        },
+        {
+            "componentType": 5126,
+            "type": "VEC4",
+            "count": 161,
+            "bufferView": 23,
+            "byteOffset": 0
+        },
+        {
+            "componentType": 5126,
+            "type": "VEC4",
+            "count": 161,
+            "bufferView": 24,
+            "byteOffset": 0
+        },
+        {
+            "componentType": 5126,
+            "type": "VEC4",
+            "count": 161,
+            "bufferView": 25,
+            "byteOffset": 0
+        },
+        {
+            "componentType": 5126,
+            "type": "VEC4",
+            "count": 161,
+            "bufferView": 26,
+            "byteOffset": 0
+        },
+        {
+            "componentType": 5126,
+            "type": "VEC4",
+            "count": 161,
+            "bufferView": 27,
+            "byteOffset": 0
+        },
+        {
+            "componentType": 5126,
+            "type": "VEC4",
+            "count": 161,
+            "bufferView": 28,
+            "byteOffset": 0
+        },
+        {
+            "componentType": 5126,
+            "type": "VEC3",
+            "count": 161,
+            "bufferView": 29,
+            "byteOffset": 0
+        },
+        {
+            "componentType": 5126,
+            "type": "VEC4",
+            "count": 161,
+            "bufferView": 30,
+            "byteOffset": 0
+        },
+        {
+            "componentType": 5126,
+            "type": "VEC3",
+            "count": 161,
+            "bufferView": 31,
+            "byteOffset": 0
+        },
+        {
+            "componentType": 5126,
+            "type": "VEC4",
+            "count": 161,
+            "bufferView": 32,
+            "byteOffset": 0
+        },
+        {
+            "componentType": 5123,
+            "type": "SCALAR",
+            "count": 6165,
+            "bufferView": 33,
+            "byteOffset": 0
+        },
+        {
+            "componentType": 5126,
+            "type": "VEC3",
+            "count": 2759,
+            "bufferView": 34,
+            "byteOffset": 0,
+            "min": [
+                -81.9805221557617,
+                86.7850799560547,
+                -18.6015281677246
+            ],
+            "max": [
+                81.9540557861328,
+                143.793167114258,
+                17.2828502655029
+            ]
+        },
+        {
+            "componentType": 5126,
+            "type": "VEC3",
+            "count": 2759,
+            "bufferView": 35,
+            "byteOffset": 0
+        },
+        {
+            "componentType": 5126,
+            "type": "VEC2",
+            "count": 2759,
+            "bufferView": 36,
+            "byteOffset": 0
+        },
+        {
+            "componentType": 5123,
+            "type": "VEC4",
+            "count": 2759,
+            "bufferView": 37,
+            "byteOffset": 0
+        },
+        {
+            "componentType": 5126,
+            "type": "VEC4",
+            "count": 2759,
+            "bufferView": 38,
+            "byteOffset": 0
+        },
+        {
+            "componentType": 5123,
+            "type": "SCALAR",
+            "count": 1134,
+            "bufferView": 39,
+            "byteOffset": 0
+        },
+        {
+            "componentType": 5126,
+            "type": "VEC3",
+            "count": 336,
+            "bufferView": 40,
+            "byteOffset": 0,
+            "min": [
+                -12.0123357772827,
+                151.862823486328,
+                -8.23231601715088
+            ],
+            "max": [
+                12.0123262405396,
+                174.369445800781,
+                16.5866527557373
+            ]
+        },
+        {
+            "componentType": 5126,
+            "type": "VEC3",
+            "count": 336,
+            "bufferView": 41,
+            "byteOffset": 0
+        },
+        {
+            "componentType": 5126,
+            "type": "VEC2",
+            "count": 336,
+            "bufferView": 42,
+            "byteOffset": 0
+        },
+        {
+            "componentType": 5123,
+            "type": "VEC4",
+            "count": 336,
+            "bufferView": 43,
+            "byteOffset": 0
+        },
+        {
+            "componentType": 5126,
+            "type": "VEC4",
+            "count": 336,
+            "bufferView": 44,
+            "byteOffset": 0
+        },
+        {
+            "componentType": 5126,
+            "type": "MAT4",
+            "count": 49,
+            "bufferView": 45,
+            "byteOffset": 0
+        }
+    ],
+    "images": [
+        {
+            "name": "AvatarBotA_Tex_Combined.png",
+            "uri": "AvatarBotA_Tex_Combined.png"
+        },
+        {
+            "name": "AvatarBotA_Head_Tex_Combined.png",
+            "uri": "AvatarBotA_Head_Tex_Combined.png"
+        }
+    ],
+    "samplers": [
+        {}
+    ],
+    "textures": [
+        {
+            "name": "file5",
+            "sampler": 0,
+            "source": 0
+        },
+        {
+            "name": "file6",
+            "sampler": 0,
+            "source": 1
+        }
+    ],
+    "materials": [
+        {
+            "name": "Bot_BodyHands_mat",
+            "alphaMode": "OPAQUE",
+            "pbrMetallicRoughness": {
+                "baseColorTexture": {
+                    "index": 0,
+                    "texCoord": 0
+                },
+                "baseColorFactor": [
+                    0.800000011920929,
+                    0.800000011920929,
+                    0.800000011920929,
+                    1.0
+                ],
+                "metallicFactor": 0.0,
+                "roughnessFactor": 1.0
+            },
+            "extensions": {
+                "KHR_materials_unlit": {}
+            }
+        },
+        {
+            "name": "Bot_Head_mat",
+            "alphaMode": "OPAQUE",
+            "pbrMetallicRoughness": {
+                "baseColorTexture": {
+                    "index": 1,
+                    "texCoord": 0
+                },
+                "baseColorFactor": [
+                    1.0,
+                    1.0,
+                    1.0,
+                    1.0
+                ],
+                "metallicFactor": 0.0,
+                "roughnessFactor": 1.0
+            },
+            "extensions": {
+                "KHR_materials_unlit": {}
+            }
+        }
+    ],
+    "meshes": [
+        {
+            "name": "Bot_Skinned",
+            "primitives": [
+                {
+                    "material": 0,
+                    "mode": 4,
+                    "attributes": {
+                        "JOINTS_0": 37,
+                        "NORMAL": 35,
+                        "POSITION": 34,
+                        "TEXCOORD_0": 36,
+                        "WEIGHTS_0": 38
+                    },
+                    "indices": 33
+                },
+                {
+                    "material": 1,
+                    "mode": 4,
+                    "attributes": {
+                        "JOINTS_0": 43,
+                        "NORMAL": 41,
+                        "POSITION": 40,
+                        "TEXCOORD_0": 42,
+                        "WEIGHTS_0": 44
+                    },
+                    "indices": 39
+                }
+            ]
+        }
+    ],
+    "skins": [
+        {
+            "joints": [
+                1,
+                2,
+                3,
+                4,
+                5,
+                6,
+                7,
+                8,
+                9,
+                10,
+                11,
+                12,
+                13,
+                14,
+                15,
+                16,
+                17,
+                18,
+                19,
+                20,
+                21,
+                22,
+                23,
+                24,
+                25,
+                26,
+                27,
+                28,
+                29,
+                30,
+                31,
+                32,
+                33,
+                34,
+                35,
+                36,
+                37,
+                38,
+                39,
+                40,
+                41,
+                42,
+                43,
+                44,
+                45,
+                46,
+                47,
+                48,
+                49
+            ],
+            "inverseBindMatrices": 45,
+            "skeleton": 1
+        }
+    ],
+    "animations": [
+        {
+            "name": "Take 001",
+            "channels": [
+                {
+                    "sampler": 0,
+                    "target": {
+                        "node": 5,
+                        "path": "rotation"
+                    }
+                },
+                {
+                    "sampler": 1,
+                    "target": {
+                        "node": 6,
+                        "path": "rotation"
+                    }
+                },
+                {
+                    "sampler": 2,
+                    "target": {
+                        "node": 8,
+                        "path": "rotation"
+                    }
+                },
+                {
+                    "sampler": 3,
+                    "target": {
+                        "node": 9,
+                        "path": "rotation"
+                    }
+                },
+                {
+                    "sampler": 4,
+                    "target": {
+                        "node": 10,
+                        "path": "rotation"
+                    }
+                },
+                {
+                    "sampler": 5,
+                    "target": {
+                        "node": 12,
+                        "path": "rotation"
+                    }
+                },
+                {
+                    "sampler": 6,
+                    "target": {
+                        "node": 13,
+                        "path": "rotation"
+                    }
+                },
+                {
+                    "sampler": 7,
+                    "target": {
+                        "node": 14,
+                        "path": "rotation"
+                    }
+                },
+                {
+                    "sampler": 8,
+                    "target": {
+                        "node": 16,
+                        "path": "rotation"
+                    }
+                },
+                {
+                    "sampler": 9,
+                    "target": {
+                        "node": 17,
+                        "path": "rotation"
+                    }
+                },
+                {
+                    "sampler": 10,
+                    "target": {
+                        "node": 18,
+                        "path": "rotation"
+                    }
+                },
+                {
+                    "sampler": 11,
+                    "target": {
+                        "node": 20,
+                        "path": "rotation"
+                    }
+                },
+                {
+                    "sampler": 12,
+                    "target": {
+                        "node": 21,
+                        "path": "rotation"
+                    }
+                },
+                {
+                    "sampler": 13,
+                    "target": {
+                        "node": 22,
+                        "path": "rotation"
+                    }
+                },
+                {
+                    "sampler": 14,
+                    "target": {
+                        "node": 26,
+                        "path": "rotation"
+                    }
+                },
+                {
+                    "sampler": 15,
+                    "target": {
+                        "node": 27,
+                        "path": "rotation"
+                    }
+                },
+                {
+                    "sampler": 16,
+                    "target": {
+                        "node": 29,
+                        "path": "rotation"
+                    }
+                },
+                {
+                    "sampler": 17,
+                    "target": {
+                        "node": 30,
+                        "path": "rotation"
+                    }
+                },
+                {
+                    "sampler": 18,
+                    "target": {
+                        "node": 31,
+                        "path": "rotation"
+                    }
+                },
+                {
+                    "sampler": 19,
+                    "target": {
+                        "node": 33,
+                        "path": "rotation"
+                    }
+                },
+                {
+                    "sampler": 20,
+                    "target": {
+                        "node": 34,
+                        "path": "rotation"
+                    }
+                },
+                {
+                    "sampler": 21,
+                    "target": {
+                        "node": 35,
+                        "path": "rotation"
+                    }
+                },
+                {
+                    "sampler": 22,
+                    "target": {
+                        "node": 37,
+                        "path": "rotation"
+                    }
+                },
+                {
+                    "sampler": 23,
+                    "target": {
+                        "node": 38,
+                        "path": "rotation"
+                    }
+                },
+                {
+                    "sampler": 24,
+                    "target": {
+                        "node": 39,
+                        "path": "rotation"
+                    }
+                },
+                {
+                    "sampler": 25,
+                    "target": {
+                        "node": 41,
+                        "path": "rotation"
+                    }
+                },
+                {
+                    "sampler": 26,
+                    "target": {
+                        "node": 42,
+                        "path": "rotation"
+                    }
+                },
+                {
+                    "sampler": 27,
+                    "target": {
+                        "node": 43,
+                        "path": "rotation"
+                    }
+                },
+                {
+                    "sampler": 28,
+                    "target": {
+                        "node": 48,
+                        "path": "translation"
+                    }
+                },
+                {
+                    "sampler": 29,
+                    "target": {
+                        "node": 48,
+                        "path": "rotation"
+                    }
+                },
+                {
+                    "sampler": 30,
+                    "target": {
+                        "node": 49,
+                        "path": "translation"
+                    }
+                },
+                {
+                    "sampler": 31,
+                    "target": {
+                        "node": 49,
+                        "path": "rotation"
+                    }
+                }
+            ],
+            "samplers": [
+                {
+                    "input": 0,
+                    "interpolation": "LINEAR",
+                    "output": 1
+                },
+                {
+                    "input": 0,
+                    "interpolation": "LINEAR",
+                    "output": 2
+                },
+                {
+                    "input": 0,
+                    "interpolation": "LINEAR",
+                    "output": 3
+                },
+                {
+                    "input": 0,
+                    "interpolation": "LINEAR",
+                    "output": 4
+                },
+                {
+                    "input": 0,
+                    "interpolation": "LINEAR",
+                    "output": 5
+                },
+                {
+                    "input": 0,
+                    "interpolation": "LINEAR",
+                    "output": 6
+                },
+                {
+                    "input": 0,
+                    "interpolation": "LINEAR",
+                    "output": 7
+                },
+                {
+                    "input": 0,
+                    "interpolation": "LINEAR",
+                    "output": 8
+                },
+                {
+                    "input": 0,
+                    "interpolation": "LINEAR",
+                    "output": 9
+                },
+                {
+                    "input": 0,
+                    "interpolation": "LINEAR",
+                    "output": 10
+                },
+                {
+                    "input": 0,
+                    "interpolation": "LINEAR",
+                    "output": 11
+                },
+                {
+                    "input": 0,
+                    "interpolation": "LINEAR",
+                    "output": 12
+                },
+                {
+                    "input": 0,
+                    "interpolation": "LINEAR",
+                    "output": 13
+                },
+                {
+                    "input": 0,
+                    "interpolation": "LINEAR",
+                    "output": 14
+                },
+                {
+                    "input": 0,
+                    "interpolation": "LINEAR",
+                    "output": 15
+                },
+                {
+                    "input": 0,
+                    "interpolation": "LINEAR",
+                    "output": 16
+                },
+                {
+                    "input": 0,
+                    "interpolation": "LINEAR",
+                    "output": 17
+                },
+                {
+                    "input": 0,
+                    "interpolation": "LINEAR",
+                    "output": 18
+                },
+                {
+                    "input": 0,
+                    "interpolation": "LINEAR",
+                    "output": 19
+                },
+                {
+                    "input": 0,
+                    "interpolation": "LINEAR",
+                    "output": 20
+                },
+                {
+                    "input": 0,
+                    "interpolation": "LINEAR",
+                    "output": 21
+                },
+                {
+                    "input": 0,
+                    "interpolation": "LINEAR",
+                    "output": 22
+                },
+                {
+                    "input": 0,
+                    "interpolation": "LINEAR",
+                    "output": 23
+                },
+                {
+                    "input": 0,
+                    "interpolation": "LINEAR",
+                    "output": 24
+                },
+                {
+                    "input": 0,
+                    "interpolation": "LINEAR",
+                    "output": 25
+                },
+                {
+                    "input": 0,
+                    "interpolation": "LINEAR",
+                    "output": 26
+                },
+                {
+                    "input": 0,
+                    "interpolation": "LINEAR",
+                    "output": 27
+                },
+                {
+                    "input": 0,
+                    "interpolation": "LINEAR",
+                    "output": 28
+                },
+                {
+                    "input": 0,
+                    "interpolation": "LINEAR",
+                    "output": 29
+                },
+                {
+                    "input": 0,
+                    "interpolation": "LINEAR",
+                    "output": 30
+                },
+                {
+                    "input": 0,
+                    "interpolation": "LINEAR",
+                    "output": 31
+                },
+                {
+                    "input": 0,
+                    "interpolation": "LINEAR",
+                    "output": 32
+                }
+            ]
+        }
+    ],
+    "nodes": [
+        {
+            "name": "RootNode",
+            "translation": [
+                0.0,
+                0.0,
+                0.0
+            ],
+            "rotation": [
+                0.0,
+                0.0,
+                0.0,
+                1.0
+            ],
+            "scale": [
+                1.0,
+                1.0,
+                1.0
+            ],
+            "children": [
+                1,
+                50
+            ]
+        },
+        {
+            "name": "Hips",
+            "translation": [
+                0.0,
+                1.0,
+                0.0
+            ],
+            "rotation": [
+                0.0,
+                0.0,
+                0.0,
+                1.0
+            ],
+            "scale": [
+                0.00999999977648258,
+                0.00999999977648258,
+                0.00999999977648258
+            ],
+            "children": [
+                2
+            ]
+        },
+        {
+            "name": "Chest",
+            "translation": [
+                0.0,
+                33.0,
+                0.0
+            ],
+            "rotation": [
+                0.0,
+                0.0,
+                0.0,
+                1.0
+            ],
+            "scale": [
+                1.0,
+                1.0,
+                1.0
+            ],
+            "children": [
+                3,
+                24,
+                45
+            ]
+        },
+        {
+            "name": "RightHand",
+            "translation": [
+                -65.8264923095703,
+                0.0,
+                2.53653403836651e-10
+            ],
+            "rotation": [
+                -0.52379697561264,
+                -0.475012362003326,
+                -0.475012362003326,
+                0.52379697561264
+            ],
+            "scale": [
+                1.0,
+                1.0,
+                1.0
+            ],
+            "children": [
+                4,
+                8,
+                12,
+                16,
+                20
+            ]
+        },
+        {
+            "name": "RightHandThumb1",
+            "translation": [
+                2.75763964653015,
+                -2.15007448196411,
+                0.0
+            ],
+            "rotation": [
+                -0.0845961794257164,
+                0.24460332095623,
+                0.315717250108719,
+                0.912872016429901
+            ],
+            "scale": [
+                1.0,
+                1.0,
+                1.0
+            ],
+            "children": [
+                5
+            ]
+        },
+        {
+            "name": "RightHandThumb2",
+            "translation": [
+                -0.193791568279266,
+                -3.45449066162109,
+                -0.111885614693165
+            ],
+            "rotation": [
+                0.259822696447372,
+                0.0406266376376152,
+                -0.0417451933026314,
+                0.963897824287415
+            ],
+            "scale": [
+                1.0,
+                1.0,
+                1.0
+            ],
+            "children": [
+                6
+            ]
+        },
+        {
+            "name": "RightHandThumb3",
+            "translation": [
+                0.0183828547596931,
+                -2.60901737213135,
+                0.604700565338135
+            ],
+            "rotation": [
+                0.130526185035706,
+                -3.11409512388451e-17,
+                -2.38952924416889e-17,
+                0.991444885730743
+            ],
+            "scale": [
+                1.0,
+                1.0,
+                1.0
+            ],
+            "children": [
+                7
+            ]
+        },
+        {
+            "name": "RightHandThumb4",
+            "translation": [
+                -0.00614145956933498,
+                -1.84276032447815,
+                0.275437027215958
+            ],
+            "rotation": [
+                -0.0143108321353793,
+                -0.00529135810211301,
+                -0.346111297607422,
+                0.938069403171539
+            ],
+            "scale": [
+                1.0,
+                1.0,
+                1.0
+            ]
+        },
+        {
+            "name": "RightHandIndex1",
+            "translation": [
+                2.1877007484436,
+                -8.50447845458984,
+                -0.00400000018998981
+            ],
+            "rotation": [
+                0.129879087209702,
+                0.00267119123600423,
+                0.0197229869663715,
+                0.991330087184906
+            ],
+            "scale": [
+                1.0,
+                1.0,
+                1.0
+            ],
+            "children": [
+                9
+            ]
+        },
+        {
+            "name": "RightHandIndex2",
+            "translation": [
+                1.10285200207727e-05,
+                -3.35957384109497,
+                -0.000199394213268533
+            ],
+            "rotation": [
+                0.131140783429146,
+                0.000969027169048786,
+                0.00806150026619434,
+                0.991330504417419
+            ],
+            "scale": [
+                1.0,
+                1.0,
+                1.0
+            ],
+            "children": [
+                10
+            ]
+        },
+        {
+            "name": "RightHandIndex3",
+            "translation": [
+                -2.62199250755657e-07,
+                -2.57685971260071,
+                1.63709046319127e-11
+            ],
+            "rotation": [
+                0.130491554737091,
+                -0.00300704198889434,
+                -0.02284075319767,
+                0.99118173122406
+            ],
+            "scale": [
+                1.0,
+                1.0,
+                1.0
+            ],
+            "children": [
+                11
+            ]
+        },
+        {
+            "name": "RightHandIndex4",
+            "translation": [
+                -6.4880941863521e-07,
+                -2.16984295845032,
+                1.45519152283669e-11
+            ],
+            "rotation": [
+                7.44831396559675e-09,
+                -1.83785861529451e-10,
+                -0.0246648676693439,
+                0.999695777893066
+            ],
+            "scale": [
+                1.0,
+                1.0,
+                1.0
+            ]
+        },
+        {
+            "name": "RightHandMiddle1",
+            "translation": [
+                -1.02776675703353e-06,
+                -8.89051723480225,
+                0.0
+            ],
+            "rotation": [
+                0.13047268986702,
+                -0.00373660982586443,
+                -0.0283823702484369,
+                0.991038501262665
+            ],
+            "scale": [
+                1.0,
+                1.0,
+                1.0
+            ],
+            "children": [
+                13
+            ]
+        },
+        {
+            "name": "RightHandMiddle2",
+            "translation": [
+                1.85175611022714e-06,
+                -3.40467071533203,
+                0.0
+            ],
+            "rotation": [
+                0.130523636937141,
+                -0.000818223459646106,
+                -0.00621502334252,
+                0.991425395011902
+            ],
+            "scale": [
+                1.0,
+                1.0,
+                1.0
+            ],
+            "children": [
+                14
+            ]
+        },
+        {
+            "name": "RightHandMiddle3",
+            "translation": [
+                1.05654953586054e-06,
+                -2.67793536186218,
+                -1.81898940354586e-12
+            ],
+            "rotation": [
+                0.130522698163986,
+                0.000956544012296945,
+                0.00726567255333066,
+                0.991418242454529
+            ],
+            "scale": [
+                1.0,
+                1.0,
+                1.0
+            ],
+            "children": [
+                15
+            ]
+        },
+        {
+            "name": "RightHandMiddle4",
+            "translation": [
+                -3.79802463612577e-06,
+                -2.63057136535645,
+                6.78955984767526e-08
+            ],
+            "rotation": [
+                1.82495529799098e-08,
+                3.47519013566e-10,
+                0.0078874584287405,
+                0.999968886375427
+            ],
+            "scale": [
+                1.0,
+                1.0,
+                1.0
+            ]
+        },
+        {
+            "name": "RightHandRing1",
+            "translation": [
+                -1.72323477268219,
+                -8.434814453125,
+                0.0
+            ],
+            "rotation": [
+                0.130034267902374,
+                -0.0113214813172817,
+                -0.085995189845562,
+                0.987708330154419
+            ],
+            "scale": [
+                1.0,
+                1.0,
+                1.0
+            ],
+            "children": [
+                17
+            ]
+        },
+        {
+            "name": "RightHandRing2",
+            "translation": [
+                4.97117707709549e-06,
+                -2.92135119438171,
+                0.0
+            ],
+            "rotation": [
+                0.130523890256882,
+                0.000776301021687686,
+                0.00589659111574292,
+                0.991427302360535
+            ],
+            "scale": [
+                1.0,
+                1.0,
+                1.0
+            ],
+            "children": [
+                18
+            ]
+        },
+        {
+            "name": "RightHandRing3",
+            "translation": [
+                -4.25719008489978e-06,
+                -2.7104823589325,
+                -1.81898940354586e-12
+            ],
+            "rotation": [
+                0.130523800849915,
+                -0.000789301353506744,
+                -0.0059953392483294,
+                0.991426706314087
+            ],
+            "scale": [
+                1.0,
+                1.0,
+                1.0
+            ],
+            "children": [
+                19
+            ]
+        },
+        {
+            "name": "RightHandRing4",
+            "translation": [
+                -1.67088660418813e-06,
+                -2.41632723808289,
+                0.0
+            ],
+            "rotation": [
+                -2.85607333715533e-17,
+                4.32810741164245e-17,
+                0.067211352288723,
+                0.997738778591156
+            ],
+            "scale": [
+                1.0,
+                1.0,
+                1.0
+            ]
+        },
+        {
+            "name": "RightHandPinky1",
+            "translation": [
+                -3.45131826400757,
+                -7.36873292922974,
+                0.0
+            ],
+            "rotation": [
+                0.128799960017204,
+                -0.0211579278111458,
+                -0.160710424184799,
+                0.978332817554474
+            ],
+            "scale": [
+                1.0,
+                1.0,
+                1.0
+            ],
+            "children": [
+                21
+            ]
+        },
+        {
+            "name": "RightHandPinky2",
+            "translation": [
+                7.14437692295178e-06,
+                -3.33492231369019,
+                -1.81898940354586e-12
+            ],
+            "rotation": [
+                0.130520552396774,
+                0.00121425895486027,
+                0.00922321155667305,
+                0.991401970386505
+            ],
+            "scale": [
+                1.0,
+                1.0,
+                1.0
+            ],
+            "children": [
+                22
+            ]
+        },
+        {
+            "name": "RightHandPinky3",
+            "translation": [
+                -6.04431488682167e-06,
+                -1.95470726490021,
+                5.04514900967479e-08
+            ],
+            "rotation": [
+                0.13052274286747,
+                -0.0009512152755633,
+                -0.00722519494593143,
+                0.991418540477753
+            ],
+            "scale": [
+                1.0,
+                1.0,
+                1.0
+            ],
+            "children": [
+                23
+            ]
+        },
+        {
+            "name": "RightHandPinky4",
+            "translation": [
+                7.62369018048048e-06,
+                -1.84980952739716,
+                1.02871126728132e-07
+            ],
+            "rotation": [
+                2.44651445768795e-08,
+                1.11148032999608e-08,
+                0.140648439526558,
+                0.990059614181519
+            ],
+            "scale": [
+                1.0,
+                1.0,
+                1.0
+            ]
+        },
+        {
+            "name": "LeftHand",
+            "translation": [
+                65.8000030517578,
+                0.0,
+                0.0
+            ],
+            "rotation": [
+                0.52379697561264,
+                0.475012362003326,
+                -0.475012362003326,
+                0.52379697561264
+            ],
+            "scale": [
+                1.0,
+                1.0,
+                1.0
+            ],
+            "children": [
+                25,
+                29,
+                33,
+                37,
+                41
+            ]
+        },
+        {
+            "name": "LeftHandThumb1",
+            "translation": [
+                -2.7576425075531,
+                2.15009140968323,
+                -1.09139364212751e-11
+            ],
+            "rotation": [
+                -0.0845961794257164,
+                0.24460332095623,
+                0.315717250108719,
+                0.912872016429901
+            ],
+            "scale": [
+                1.0,
+                1.0,
+                1.0
+            ],
+            "children": [
+                26
+            ]
+        },
+        {
+            "name": "LeftHandThumb2",
+            "translation": [
+                0.193819507956505,
+                3.45451331138611,
+                0.111901737749577
+            ],
+            "rotation": [
+                0.258741647005081,
+                0.0406734235584736,
+                -0.0416996106505394,
+                0.964188575744629
+            ],
+            "scale": [
+                1.0,
+                1.0,
+                1.0
+            ],
+            "children": [
+                27
+            ]
+        },
+        {
+            "name": "LeftHandThumb3",
+            "translation": [
+                -0.018382428213954,
+                2.60901665687561,
+                -0.604700148105621
+            ],
+            "rotation": [
+                0.130526185035706,
+                8.98000309354021e-17,
+                4.41677554847997e-17,
+                0.991444885730743
+            ],
+            "scale": [
+                1.0,
+                1.0,
+                1.0
+            ],
+            "children": [
+                28
+            ]
+        },
+        {
+            "name": "LeftHandThumb4",
+            "translation": [
+                0.00620248122140765,
+                1.84271383285522,
+                -0.275547921657562
+            ],
+            "rotation": [
+                -0.0143108321353793,
+                -0.00529135810211301,
+                -0.346111297607422,
+                0.938069403171539
+            ],
+            "scale": [
+                1.0,
+                1.0,
+                1.0
+            ]
+        },
+        {
+            "name": "LeftHandIndex1",
+            "translation": [
+                -2.18770694732666,
+                8.50446128845215,
+                0.00419948389753699
+            ],
+            "rotation": [
+                0.129879087209702,
+                0.00267119123600423,
+                0.0197229869663715,
+                0.991330087184906
+            ],
+            "scale": [
+                1.0,
+                1.0,
+                1.0
+            ],
+            "children": [
+                30
+            ]
+        },
+        {
+            "name": "LeftHandIndex2",
+            "translation": [
+                -1.13686837721616e-13,
+                3.35964441299438,
+                1.81898940354586e-12
+            ],
+            "rotation": [
+                0.131140783429146,
+                0.000969027169048786,
+                0.00806150026619434,
+                0.991330504417419
+            ],
+            "scale": [
+                1.0,
+                1.0,
+                1.0
+            ],
+            "children": [
+                31
+            ]
+        },
+        {
+            "name": "LeftHandIndex3",
+            "translation": [
+                0.0,
+                2.57680535316467,
+                0.0
+            ],
+            "rotation": [
+                0.130491554737091,
+                -0.00300704198889434,
+                -0.02284075319767,
+                0.99118173122406
+            ],
+            "scale": [
+                1.0,
+                1.0,
+                1.0
+            ],
+            "children": [
+                32
+            ]
+        },
+        {
+            "name": "LeftHandIndex4",
+            "translation": [
+                -1.13686837721616e-13,
+                2.16987800598145,
+                0.0
+            ],
+            "rotation": [
+                4.28986164068626e-18,
+                6.83516462791247e-18,
+                -0.0246648676693439,
+                0.999695777893066
+            ],
+            "scale": [
+                1.0,
+                1.0,
+                1.0
+            ]
+        },
+        {
+            "name": "LeftHandMiddle1",
+            "translation": [
+                0.0,
+                8.89050388336182,
+                4.54747350886464e-11
+            ],
+            "rotation": [
+                0.13047268986702,
+                -0.00373660982586443,
+                -0.0283823702484369,
+                0.991038501262665
+            ],
+            "scale": [
+                1.0,
+                1.0,
+                1.0
+            ],
+            "children": [
+                34
+            ]
+        },
+        {
+            "name": "LeftHandMiddle2",
+            "translation": [
+                -5.6843418860808e-14,
+                3.40468168258667,
+                2.36468622460961e-11
+            ],
+            "rotation": [
+                0.13052362203598,
+                -0.000818223343230784,
+                -0.00621502334252,
+                0.991425395011902
+            ],
+            "scale": [
+                1.0,
+                1.0,
+                1.0
+            ],
+            "children": [
+                35
+            ]
+        },
+        {
+            "name": "LeftHandMiddle3",
+            "translation": [
+                -2.8421709430404e-14,
+                2.67797994613647,
+                3.63797880709171e-12
+            ],
+            "rotation": [
+                0.130522683262825,
+                0.000956543954089284,
+                0.00726567255333066,
+                0.991418242454529
+            ],
+            "scale": [
+                1.0,
+                1.0,
+                1.0
+            ],
+            "children": [
+                36
+            ]
+        },
+        {
+            "name": "LeftHandMiddle4",
+            "translation": [
+                0.0,
+                2.63050961494446,
+                -1.81898940354586e-12
+            ],
+            "rotation": [
+                -6.30038723337714e-17,
+                1.23782160635548e-18,
+                0.0078874584287405,
+                0.999968886375427
+            ],
+            "scale": [
+                1.0,
+                1.0,
+                1.0
+            ]
+        },
+        {
+            "name": "LeftHandRing1",
+            "translation": [
+                1.72323560714722,
+                8.4348258972168,
+                6.00266503170133e-11
+            ],
+            "rotation": [
+                0.130034267902374,
+                -0.0113214813172817,
+                -0.085995189845562,
+                0.987708330154419
+            ],
+            "scale": [
+                1.0,
+                1.0,
+                1.0
+            ],
+            "children": [
+                38
+            ]
+        },
+        {
+            "name": "LeftHandRing2",
+            "translation": [
+                0.0,
+                2.92133402824402,
+                2.36468622460961e-11
+            ],
+            "rotation": [
+                0.130523890256882,
+                0.000776300963480026,
+                0.00589659111574292,
+                0.991427302360535
+            ],
+            "scale": [
+                1.0,
+                1.0,
+                1.0
+            ],
+            "children": [
+                39
+            ]
+        },
+        {
+            "name": "LeftHandRing3",
+            "translation": [
+                0.0,
+                2.71053099632263,
+                0.0
+            ],
+            "rotation": [
+                0.130523800849915,
+                -0.000789301353506744,
+                -0.0059953392483294,
+                0.991426706314087
+            ],
+            "scale": [
+                1.0,
+                1.0,
+                1.0
+            ],
+            "children": [
+                40
+            ]
+        },
+        {
+            "name": "LeftHandRing4",
+            "translation": [
+                0.0,
+                2.4163134098053,
+                1.81898940354586e-12
+            ],
+            "rotation": [
+                5.34889858011413e-17,
+                -6.82871510067639e-18,
+                0.067211352288723,
+                0.997738778591156
+            ],
+            "scale": [
+                1.0,
+                1.0,
+                1.0
+            ]
+        },
+        {
+            "name": "LeftHandPinky1",
+            "translation": [
+                3.45132112503052,
+                7.36876058578491,
+                6.54836185276508e-11
+            ],
+            "rotation": [
+                0.128799960017204,
+                -0.0211579278111458,
+                -0.160710424184799,
+                0.978332817554474
+            ],
+            "scale": [
+                1.0,
+                1.0,
+                1.0
+            ],
+            "children": [
+                42
+            ]
+        },
+        {
+            "name": "LeftHandPinky2",
+            "translation": [
+                0.0,
+                3.33487010002136,
+                3.09228198602796e-11
+            ],
+            "rotation": [
+                0.130520537495613,
+                0.00121425883844495,
+                0.00922321155667305,
+                0.991401970386505
+            ],
+            "scale": [
+                1.0,
+                1.0,
+                1.0
+            ],
+            "children": [
+                43
+            ]
+        },
+        {
+            "name": "LeftHandPinky3",
+            "translation": [
+                2.27373675443232e-13,
+                1.95477187633514,
+                1.81898940354586e-12
+            ],
+            "rotation": [
+                0.130522727966309,
+                -0.000951214926317334,
+                -0.00722519494593143,
+                0.991418540477753
+            ],
+            "scale": [
+                1.0,
+                1.0,
+                1.0
+            ],
+            "children": [
+                44
+            ]
+        },
+        {
+            "name": "LeftHandPinky4",
+            "translation": [
+                0.0,
+                1.84976482391357,
+                1.81898940354586e-12
+            ],
+            "rotation": [
+                8.82180761380352e-18,
+                -1.27638923328801e-17,
+                0.140648439526558,
+                0.990059614181519
+            ],
+            "scale": [
+                1.0,
+                1.0,
+                1.0
+            ]
+        },
+        {
+            "name": "Neck",
+            "translation": [
+                -2.09076530502568e-16,
+                14.3466949462891,
+                -3.28626015289046e-14
+            ],
+            "rotation": [
+                0.0,
+                0.0,
+                0.0,
+                1.0
+            ],
+            "scale": [
+                1.0,
+                1.0,
+                1.0
+            ],
+            "children": [
+                46
+            ]
+        },
+        {
+            "name": "Head",
+            "translation": [
+                -1.72115390890012e-17,
+                9.05494976043701,
+                2.07404236001782e-16
+            ],
+            "rotation": [
+                -6.93889390390723e-18,
+                1.27054942088145e-20,
+                1.0842021724855e-19,
+                1.0
+            ],
+            "scale": [
+                1.0,
+                1.0,
+                1.0
+            ],
+            "children": [
+                47,
+                48,
+                49
+            ]
+        },
+        {
+            "name": "HeadTop_End",
+            "translation": [
+                -2.66453525910038e-15,
+                17.8367767333984,
+                -4.03896783473158e-28
+            ],
+            "rotation": [
+                0.0,
+                0.0,
+                1.76324152623343e-37,
+                1.0
+            ],
+            "scale": [
+                1.0,
+                1.0,
+                1.0
+            ]
+        },
+        {
+            "name": "RightEye",
+            "translation": [
+                -6.14273977279663,
+                6.2331337928772,
+                13.0336484909058
+            ],
+            "rotation": [
+                -6.938892249546e-18,
+                -1.36491360355013e-20,
+                0.00379808945581317,
+                0.999992787837982
+            ],
+            "scale": [
+                1.0,
+                1.0,
+                1.0
+            ]
+        },
+        {
+            "name": "LeftEye",
+            "translation": [
+                6.14274263381958,
+                6.2331337928772,
+                13.0336484909058
+            ],
+            "rotation": [
+                -6.938892249546e-18,
+                -1.36491360355013e-20,
+                0.00379808945581317,
+                0.999992787837982
+            ],
+            "scale": [
+                1.0,
+                1.0,
+                1.0
+            ]
+        },
+        {
+            "name": "Bot_Skinned",
+            "translation": [
+                0.0,
+                0.0,
+                0.0
+            ],
+            "rotation": [
+                0.0,
+                0.0,
+                0.0,
+                1.0
+            ],
+            "scale": [
+                0.00999999977648258,
+                0.00999999977648258,
+                0.00999999977648258
+            ],
+            "mesh": 0,
+            "skin": 0
+        }
+    ]
+}

BIN
examples/models/gltf/BotSkinned/glTF-MaterialsUnlit/buffer.bin


BIN
examples/textures/piz_compressed.exr


+ 1 - 1
examples/webgl_buffergeometry.html

@@ -174,7 +174,7 @@
 
 				//
 
-				renderer = new THREE.WebGLRenderer( { antialias: false } );
+				renderer = new THREE.WebGLRenderer();
 				renderer.setPixelRatio( window.devicePixelRatio );
 				renderer.setSize( window.innerWidth, window.innerHeight );
 

+ 1 - 1
examples/webgl_buffergeometry_lines.html

@@ -100,7 +100,7 @@
 
 				//
 
-				renderer = new THREE.WebGLRenderer( { antialias: false } );
+				renderer = new THREE.WebGLRenderer();
 				renderer.setPixelRatio( window.devicePixelRatio );
 				renderer.setSize( window.innerWidth, window.innerHeight );
 

+ 1 - 1
examples/webgl_buffergeometry_lines_indexed.html

@@ -210,7 +210,7 @@
 
 				scene.add( parent_node );
 
-				renderer = new THREE.WebGLRenderer( { antialias: false } );
+				renderer = new THREE.WebGLRenderer();
 				renderer.setPixelRatio( window.devicePixelRatio );
 				renderer.setSize( window.innerWidth, window.innerHeight );
 

+ 1 - 1
examples/webgl_buffergeometry_points.html

@@ -112,7 +112,7 @@
 
 				//
 
-				renderer = new THREE.WebGLRenderer( { antialias: false } );
+				renderer = new THREE.WebGLRenderer();
 				renderer.setPixelRatio( window.devicePixelRatio );
 				renderer.setSize( window.innerWidth, window.innerHeight );
 

+ 1 - 1
examples/webgl_buffergeometry_points_interleaved.html

@@ -126,7 +126,7 @@
 
 				//
 
-				renderer = new THREE.WebGLRenderer( { antialias: false } );
+				renderer = new THREE.WebGLRenderer();
 				renderer.setPixelRatio( window.devicePixelRatio );
 				renderer.setSize( window.innerWidth, window.innerHeight );
 

+ 1 - 1
examples/webgl_buffergeometry_uint.html

@@ -179,7 +179,7 @@
 
 				//
 
-				renderer = new THREE.WebGLRenderer( { antialias: false } );
+				renderer = new THREE.WebGLRenderer();
 				renderer.setPixelRatio( window.devicePixelRatio );
 				renderer.setSize( window.innerWidth, window.innerHeight );
 

+ 6 - 5
examples/webgl_decals.html

@@ -124,8 +124,8 @@
 			light.position.set( -1, 0.75, -0.5 );
 			scene.add( light );
 
-			var geometry = new THREE.Geometry();
-			geometry.vertices.push( new THREE.Vector3(), new THREE.Vector3() );
+			var geometry = new THREE.BufferGeometry();
+			geometry.setFromPoints( [ new THREE.Vector3(), new THREE.Vector3() ] );
 
 			line = new THREE.Line( geometry, new THREE.LineBasicMaterial( { linewidth: 4 } ) );
 			scene.add( line );
@@ -209,9 +209,10 @@
 					intersection.normal.copy( intersects[ 0 ].face.normal );
 					mouseHelper.lookAt( n );
 
-					line.geometry.vertices[ 0 ].copy( intersection.point );
-					line.geometry.vertices[ 1 ].copy( n );
-					line.geometry.verticesNeedUpdate = true;
+					var positions = line.geometry.attributes.position;
+					positions.setXYZ( 0, p.x, p.y, p.z );
+					positions.setXYZ( 1, n.x, n.y, n.z );
+					positions.needsUpdate = true;
 
 					intersection.intersects = true;
 

+ 1 - 1
examples/webgl_effects_anaglyph.html

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

+ 1 - 1
examples/webgl_effects_parallaxbarrier.html

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

+ 12 - 9
examples/webgl_geometry_nurbs.html

@@ -107,19 +107,22 @@
 
 				}
 
-				var nurbsCurve = new THREE.NURBSCurve(nurbsDegree, nurbsKnots, nurbsControlPoints);
+				var nurbsCurve = new THREE.NURBSCurve( nurbsDegree, nurbsKnots, nurbsControlPoints );
 
-				var nurbsGeometry = new THREE.Geometry();
-				nurbsGeometry.vertices = nurbsCurve.getPoints(200);
-				var nurbsMaterial = new THREE.LineBasicMaterial( { linewidth: 10, color: 0x333333, transparent: true } );
+				var nurbsGeometry = new THREE.BufferGeometry();
+				nurbsGeometry.setFromPoints( nurbsCurve.getPoints( 200 ) );
+
+				var nurbsMaterial = new THREE.LineBasicMaterial( { linewidth: 10, color: 0x333333 } );
 
 				var nurbsLine = new THREE.Line( nurbsGeometry, nurbsMaterial );
-				nurbsLine.position.set( 200, -100, 0 );
+				nurbsLine.position.set( 200, - 100, 0 );
 				group.add( nurbsLine );
 
-				var nurbsControlPointsGeometry = new THREE.Geometry();
-				nurbsControlPointsGeometry.vertices = nurbsCurve.controlPoints;
+				var nurbsControlPointsGeometry = new THREE.BufferGeometry();
+				nurbsControlPointsGeometry.setFromPoints( nurbsCurve.controlPoints );
+
 				var nurbsControlPointsMaterial = new THREE.LineBasicMaterial( { linewidth: 2, color: 0x333333, opacity: 0.25, transparent: true } );
+
 				var nurbsControlPointsLine = new THREE.Line( nurbsControlPointsGeometry, nurbsControlPointsMaterial );
 				nurbsControlPointsLine.position.copy( nurbsLine.position );
 				group.add( nurbsControlPointsLine );
@@ -156,9 +159,9 @@
 				map.wrapS = map.wrapT = THREE.RepeatWrapping;
 				map.anisotropy = 16;
 
-				function getSurfacePoint(u, v) {
+				function getSurfacePoint( u, v ) {
 
-					return nurbsSurface.getPoint(u, v);
+					return nurbsSurface.getPoint( u, v );
 
 				}
 

+ 1 - 1
examples/webgl_interactive_buffergeometry.html

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

+ 1 - 1
examples/webgl_lights_pointlights2.html

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

+ 1 - 1
examples/webgl_lines_colors.html

@@ -89,7 +89,7 @@
 
 				scene = new THREE.Scene();
 
-				renderer = new THREE.WebGLRenderer( { antialias: false } );
+				renderer = new THREE.WebGLRenderer();
 				renderer.setPixelRatio( window.devicePixelRatio );
 				renderer.setSize( window.innerWidth, window.innerHeight );
 				renderer.autoClear = false;

+ 14 - 1
examples/webgl_loader_gltf_extensions.html

@@ -89,6 +89,7 @@
 				<option value="glTF">None (Default)</option>
 				<option value="glTF-Embedded">None (Embedded)</option>
 				<option value="glTF-Binary">None (Binary)</option>
+				<option value="glTF-MaterialsUnlit">Materials Unlit</option>
 				<option value="glTF-pbrSpecularGlossiness">Specular-Glossiness (PBR)</option>
 				<option value="glTF-Draco">Draco (Compressed)</option>
 			</select>
@@ -213,7 +214,11 @@
 					var child = extensionSelect.children[i];
 					child.disabled = sceneInfo.extensions.indexOf(child.value) === -1;
 					if (child.disabled && child.selected) {
-						extensionSelect.value = extension = 'glTF';
+						if (sceneInfo.extensions.length === 0) {
+							extensionSelect.value = extension = 'glTF';
+						} else {
+							extensionSelect.value = extension = sceneInfo.extensions[0];
+						}
 					}
 				}
 
@@ -436,6 +441,14 @@
 					extensions: ['glTF', 'glTF-pbrSpecularGlossiness', 'glTF-Binary'],
 					addEnvMap: true
 				},
+				{
+					name : 'Bot Skinned', url : './models/gltf/BotSkinned/%s/Bot_Skinned.gltf',
+					cameraPos: new THREE.Vector3(0, 4, 6),
+					objectRotation: new THREE.Euler(0, 0, 0),
+					addLights:true,
+					extensions: ['glTF-MaterialsUnlit'],
+					addEnvMap: true
+				},
 				{
 					name : 'MetalRoughSpheres (PBR)', url : './models/gltf/MetalRoughSpheres/%s/MetalRoughSpheres.gltf',
 					cameraPos: new THREE.Vector3(2, 1, 15),

+ 1 - 1
examples/webgl_loader_nrrd.html

@@ -176,7 +176,7 @@
 				} );
 				// renderer
 
-				renderer = new THREE.WebGLRenderer( { antialias: false, alpha: true } );
+				renderer = new THREE.WebGLRenderer( { alpha: true } );
 				renderer.setPixelRatio( window.devicePixelRatio );
 				renderer.setSize( window.innerWidth, window.innerHeight );
 

+ 1 - 1
examples/webgl_loader_texture_exr.html

@@ -111,7 +111,7 @@
 
 				var loader = new THREE.EXRLoader();
 
-				var texture = loader.load( "textures/uncompressed.exr", function( texture, textureData ){
+				var texture = loader.load( "textures/piz_compressed.exr", function( texture, textureData ){
 					console.log( textureData.header ); // exr header
 
 					texture.minFilter = THREE.NearestFilter;

+ 1 - 1
examples/webgl_loader_vrml.html

@@ -84,7 +84,7 @@
 
 				// renderer
 
-				renderer = new THREE.WebGLRenderer( { antialias: false } );
+				renderer = new THREE.WebGLRenderer();
 				renderer.setPixelRatio( window.devicePixelRatio );
 				renderer.setSize( window.innerWidth, window.innerHeight );
 

+ 1 - 1
examples/webgl_loader_vtk.html

@@ -152,7 +152,7 @@
 
 				// renderer
 
-				renderer = new THREE.WebGLRenderer( { antialias: false } );
+				renderer = new THREE.WebGLRenderer();
 				renderer.setPixelRatio( window.devicePixelRatio );
 				renderer.setSize( window.innerWidth, window.innerHeight );
 

+ 1 - 1
examples/webgl_materials_bumpmap.html

@@ -123,7 +123,7 @@
 				loader = new THREE.JSONLoader();
 				loader.load( "models/json/leeperrysmith/LeePerrySmith.json", function( geometry ) { createScene( geometry, 100, material ) } );
 
-				renderer = new THREE.WebGLRenderer( { antialias: false } );
+				renderer = new THREE.WebGLRenderer();
 				renderer.setPixelRatio( window.devicePixelRatio );
 				renderer.setSize( window.innerWidth, window.innerHeight );
 				container.appendChild( renderer.domElement );

+ 1 - 1
examples/webgl_materials_cubemap_dynamic.html

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

+ 378 - 0
examples/webgl_materials_curvature.html

@@ -0,0 +1,378 @@
+<!DOCTYPE html>
+<html lang="en">
+	<head>
+		<title>three.js webgl - shader - curvature [ninja]</title>
+		<meta charset="utf-8">
+		<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
+		<style>
+			body {
+				color: #ffffff;
+				font-family:Monospace;
+				font-size:13px;
+				text-align:center;
+				font-weight: bold;
+
+				background-color: #000000;
+				margin: 0px;
+				overflow: hidden;
+			}
+
+			#info {
+				position: absolute;
+				top: 0px; width: 100%;
+				padding: 5px;
+			}
+
+			a {
+
+				color: #ffffff;
+			}
+
+			#oldie a { color:#da0 }
+		</style>
+	</head>
+	<body>
+
+		<div id="container"></div>
+		<div id="info"><a href="http://threejs.org" target="_blank" rel="noopener">three.js</a> - curvature estimation of a geometry by <a href="http://codercat.club" target="_blank" rel="noopener">CoderCat</a></div>
+
+		<script src="../build/three.js"></script>
+		<script src="js/Detector.js"></script>
+
+		<script src="js/controls/OrbitControls.js"></script>
+		<script src="js/loaders/OBJLoader.js"></script>
+		<script src="js/libs/dat.gui.min.js"></script>
+
+		<script id="vertexShaderRaw" type="x-shader/x-vertex">
+
+		attribute float curvature;
+
+		varying float vCurvature;
+
+		void main() {
+
+			vec3 p = position;
+			vec4 modelViewPosition = modelViewMatrix * vec4( p , 1.0 );
+			gl_Position = projectionMatrix * modelViewPosition;
+			vCurvature = curvature;
+
+		}
+
+		</script>
+
+		<script id="fragmentShaderRaw" type="x-shader/x-fragment">
+
+		varying vec3 vViewPosition;
+		varying float vCurvature;
+
+		void main() {
+				gl_FragColor = vec4( vCurvature * 2.0, 0.0, 0.0, 0.0 );
+		}
+
+		</script>
+
+		<script>
+
+			if ( ! Detector.webgl ) Detector.addGetWebGLMessage();
+
+			var container;
+
+			var camera, scene, renderer;
+
+			var ninjaMeshRaw, curvatureAttribute;
+
+			init();
+			animate();
+
+			//returns average of elements in a dictionary
+			function average( dict ) {
+
+				var sum = 0;
+				var length = 0;
+
+				Object.keys( dict ).forEach( function( key ) {
+
+					sum += dict[ key ];
+					length ++;
+
+				});
+
+				return sum / length;
+
+			}
+
+			//clamp a number between min and max
+			function clamp( number, min, max ) {
+
+			  return Math.max( min, Math.min( number, max ) );
+
+			}
+
+			//filter the curvature array to only show concave values
+			function filterConcave( curvature ) {
+
+				for ( var i = 0; i < curvature.length; i++ ) {
+
+					curvature[ i ] = Math.abs( clamp( curvature[ i ], -1, 0 ) );
+
+				}
+
+			}
+
+			//filter the curvature array to only show convex values
+			function filterConvex( curvature ) {
+
+				for ( var i = 0; i < curvature.length; i++ ) {
+
+					curvature[ i ] = clamp( curvature[ i ], 0, 1 );
+
+				}
+
+			}
+
+			//filter the curvature array to show both the concave and convex values
+			function filterBoth( curvature ) {
+
+				for ( var i = 0; i < curvature.length; i++ ) {
+
+					curvature[ i ] = Math.abs( curvature[ i ] );
+
+				}
+
+			}
+
+			//initialize the scene
+			function init() {
+
+				scene = new THREE.Scene();
+
+				camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 0.1, 1000 );
+
+				camera.position.x = -23;
+				camera.position.y = 2;
+				camera.position.z = 24;
+
+				controls = new THREE.OrbitControls( camera );
+
+				renderer = new THREE.WebGLRenderer();
+				renderer.setSize( window.innerWidth, window.innerHeight );
+				renderer.autoClear = false;
+
+				document.body.appendChild( renderer.domElement );
+
+				var loader = new THREE.OBJLoader();
+				//load the obj
+				loader.load( 'models/obj/ninja/ninjaHead_Low.obj', function ( object ) {
+					object.traverse( function ( child ) {
+						if ( child instanceof THREE.Mesh ) {
+
+							bufferGeo = child.geometry;
+							bufferGeo.center();
+							var dict= {};
+
+							for ( var i = 0; i < bufferGeo.attributes.position.count; i+=3 ) {
+								//create a dictionary of every position, and its neighboring positions
+								var array = bufferGeo.attributes.position.array;
+								var normArray = bufferGeo.attributes.normal.array;
+
+								var posA = new THREE.Vector3(array[ 3 * i ], array[ 3 * i + 1 ], array[ 3 * i + 2 ]);
+								var posB = new THREE.Vector3(array[ 3 * ( i + 1 ) ], array[ 3 * ( i + 1 ) + 1 ], array[ 3 * ( i + 1 ) + 2 ]);
+								var posC = new THREE.Vector3(array[ 3 * ( i + 2 ) ], array[ 3 * ( i + 2 ) + 1 ], array[ 3 * ( i + 2 ) + 2 ]);
+
+								var normA = new THREE.Vector3(normArray[ 3 * i ], normArray[ 3 * i + 1 ], normArray[ 3 * i + 2 ]).normalize();
+								var normB = new THREE.Vector3(normArray[ 3 * ( i + 1 ) ], normArray[ 3 * ( i + 1 ) + 1 ], normArray[ 3 * ( i + 1 ) + 2 ]).normalize();
+								var normC = new THREE.Vector3(normArray[ 3 * ( i + 2 ) ], normArray[ 3 * ( i + 2 ) + 1 ], normArray[ 3 * ( i + 2 ) + 2 ]).normalize();
+
+								var strA = posA.toArray().toString();
+								var strB = posB.toArray().toString();
+								var strC = posC.toArray().toString();
+
+								var posB_A = new THREE.Vector3().subVectors( posB, posA );
+								var posB_C = new THREE.Vector3().subVectors( posB, posC );
+								var posC_A = new THREE.Vector3().subVectors( posC, posA );
+
+								var normB_A = new THREE.Vector3().subVectors( normB, normA );
+								var normB_C = new THREE.Vector3().subVectors( normB, normC );
+								var normC_A = new THREE.Vector3().subVectors( normC, normA );
+
+								var b2a = normB.dot( posB_A.normalize() );
+								var b2c = normB.dot( posB_C.normalize() );
+								var c2a = normC.dot( posC_A.normalize() );
+
+								var a2b = -normA.dot( posB_A.normalize() );
+								var c2b = -normC.dot( posB_C.normalize() );
+								var a2c = -normA.dot( posC_A.normalize() );
+
+								if (dict[ strA ] === undefined ) {
+									dict[ strA ] = {};
+								}
+								if (dict[ strB ] === undefined ) {
+									dict[ strB ] = {};
+								}
+								if (dict[ strC ] === undefined ) {
+									dict[ strC ] = {};
+								}
+
+								dict[ strA ][ strB ] = a2b;
+								dict[ strA ][ strC ] = a2c;
+								dict[ strB ][ strA ] = b2a;
+								dict[ strB ][ strC ] = b2c;
+								dict[ strC ][ strA ] = c2a;
+								dict[ strC ][ strB ] = c2b;
+
+							}
+
+							curvatureDict = {};
+							var min = 10, max = 0;
+
+							Object.keys( dict ).forEach( function( key ) {
+
+								curvatureDict[ key ] = average( dict[ key ] );
+
+							});
+
+							//smoothing
+							var smoothCurvatureDict  = Object.create(curvatureDict);
+
+							Object.keys( dict ).forEach( function( key ) {
+
+								var count = 0;
+								var sum = 0;
+								Object.keys( dict[ key ] ).forEach( function( key2 ) {
+
+									sum += smoothCurvatureDict[ key2 ];
+									count ++;
+
+								});
+								smoothCurvatureDict[key] = sum / count;
+
+							});
+
+							curvatureDict = smoothCurvatureDict;
+
+							// fit values to 0 and 1
+							Object.keys( curvatureDict ).forEach( function( key ) {
+
+								val = Math.abs( curvatureDict[ key ] );
+								if ( val < min ) min = val;
+								if ( val > max ) max = val;
+
+							});
+
+							var range = ( max - min );
+
+							Object.keys( curvatureDict ).forEach( function( key ) {
+
+								val = Math.abs( curvatureDict[ key ] );
+								if ( curvatureDict[ key ] < 0 ) {
+									curvatureDict[ key ] = (min - val) / range
+								} else {
+									curvatureDict[ key ] = (val - min) / range;
+								}
+
+							});
+
+							curvatureAttribute = new Float32Array( bufferGeo.attributes.position.count );
+
+							for ( var i = 0; i < bufferGeo.attributes.position.count; i++ ) {
+
+								array = bufferGeo.attributes.position.array;
+								var pos = new THREE.Vector3( array[ 3 * i ], array[ 3 * i + 1 ], array[ 3 * i + 2 ] );
+								var str = pos.toArray().toString();
+								curvatureAttribute[i] = curvatureDict[ str ];
+							}
+
+							bufferGeo.addAttribute( 'curvature', new THREE.BufferAttribute( curvatureAttribute, 1 ) );
+
+							//starting filter is to show both concave and convex
+							var curvatureFiltered = new Float32Array( curvatureAttribute );
+							filterBoth(curvatureFiltered);
+
+							var materialRaw = new THREE.ShaderMaterial ({
+
+								vertexShader: document.getElementById( 'vertexShaderRaw' ).textContent,
+								fragmentShader: document.getElementById( 'fragmentShaderRaw' ).textContent
+
+							} );
+
+							ninjaMeshRaw = new THREE.Mesh( bufferGeo, materialRaw );
+
+						}
+					} );
+
+					scene.add( ninjaMeshRaw );
+
+				} );
+
+
+				//init GUI
+				var params = {
+
+					filterConvex: function () {
+
+						var curvatureFiltered = new Float32Array( curvatureAttribute );
+						filterConvex(curvatureFiltered);
+						bufferGeo.attributes.curvature.array = curvatureFiltered;
+						bufferGeo.attributes.curvature.needsUpdate = true;
+
+
+					},
+					filterConcave: function () {
+
+						var curvatureFiltered = new Float32Array( curvatureAttribute );
+						filterConcave(curvatureFiltered);
+						bufferGeo.attributes.curvature.array = curvatureFiltered;
+						bufferGeo.attributes.curvature.needsUpdate = true;
+
+
+					},
+					filterBoth: function () {
+
+						var curvatureFiltered = new Float32Array( curvatureAttribute );
+						filterBoth(curvatureFiltered);
+						bufferGeo.attributes.curvature.array = curvatureFiltered;
+						bufferGeo.attributes.curvature.needsUpdate = true;
+
+					}
+				};
+
+				var gui = new dat.GUI();
+
+				topologyFolder = gui.addFolder( 'Topology' );
+				topologyFolder.add( params, 'filterConvex' );
+				topologyFolder.add( params, 'filterConcave' );
+				topologyFolder.add( params, 'filterBoth' );
+				topologyFolder.open()
+
+				onWindowResize();
+
+				window.addEventListener( 'resize', onWindowResize, false );
+
+			}
+
+			function onWindowResize( event ) {
+
+				renderer.setSize( window.innerWidth, window.innerHeight );
+				camera.aspect = window.innerWidth / window.innerHeight;
+				camera.updateProjectionMatrix();
+
+			}
+
+			function animate() {
+
+				requestAnimationFrame( animate );
+
+				render();
+
+			}
+
+			function render() {
+
+				renderer.render(scene, camera);
+
+			}
+
+		</script>
+
+	</body>
+</html>

+ 1 - 1
examples/webgl_materials_envmaps_hdr.html

@@ -86,7 +86,7 @@
 				scene = new THREE.Scene();
 				scene.background = new THREE.Color( 0xffffff );
 
-				renderer = new THREE.WebGLRenderer( { antialias: false } );
+				renderer = new THREE.WebGLRenderer();
 				renderer.toneMapping = THREE.LinearToneMapping;
 
 				standardMaterial = new THREE.MeshStandardMaterial( {

+ 9 - 21
examples/webgl_materials_modified.html

@@ -48,23 +48,11 @@
 		<script src="js/Detector.js"></script>
 		<script src="js/libs/stats.min.js"></script>
 
-		<script src="js/shaders/BleachBypassShader.js"></script>
-		<script src="js/shaders/ColorCorrectionShader.js"></script>
-		<script src="js/shaders/CopyShader.js"></script>
-		<script src="js/shaders/FXAAShader.js"></script>
-
-		<script src="js/postprocessing/EffectComposer.js"></script>
-		<script src="js/postprocessing/RenderPass.js"></script>
-		<script src="js/postprocessing/ShaderPass.js"></script>
-		<script src="js/postprocessing/MaskPass.js"></script>
-
 		<script>
 
 			if ( ! Detector.webgl ) Detector.addGetWebGLMessage();
 
-			var container, stats, loader;
-
-			var camera, scene, renderer;
+			var camera, scene, renderer, stats;
 
 			var mesh, materialShader;
 
@@ -82,9 +70,6 @@
 
 			function init() {
 
-				container = document.createElement( 'div' );
-				document.body.appendChild( container );
-
 				camera = new THREE.PerspectiveCamera( 27, window.innerWidth / window.innerHeight, 1, 10000 );
 				camera.position.z = 1200;
 
@@ -114,8 +99,8 @@
 
 				};
 
-				loader = new THREE.JSONLoader();
-				loader.load( "models/json/leeperrysmith/LeePerrySmith.json", function( geometry ) {
+				var loader = new THREE.JSONLoader();
+				loader.load( 'models/json/leeperrysmith/LeePerrySmith.json', function( geometry ) {
 
 					mesh = new THREE.Mesh( geometry, material );
 					mesh.position.y = - 50;
@@ -124,15 +109,15 @@
 
 				} );
 
-				renderer = new THREE.WebGLRenderer( { antialias: false } );
+				renderer = new THREE.WebGLRenderer( { antialias: true } );
 				renderer.setPixelRatio( window.devicePixelRatio );
 				renderer.setSize( window.innerWidth, window.innerHeight );
-				container.appendChild( renderer.domElement );
+				document.body.appendChild( renderer.domElement );
 
 				//
 
 				stats = new Stats();
-				container.appendChild( stats.dom );
+				document.body.appendChild( stats.dom );
 
 				// EVENTS
 
@@ -148,6 +133,9 @@
 				var width = window.innerWidth;
 				var height = window.innerHeight;
 
+				windowHalfX = width / 2;
+				windowHalfY = height / 2;
+
 				camera.aspect = width / height;
 				camera.updateProjectionMatrix();
 

+ 1 - 1
examples/webgl_materials_normalmap.html

@@ -133,7 +133,7 @@
 				loader = new THREE.JSONLoader();
 				loader.load( "models/json/leeperrysmith/LeePerrySmith.json", function( geometry ) { createScene( geometry, 100, material ) } );
 
-				renderer = new THREE.WebGLRenderer( { antialias: false } );
+				renderer = new THREE.WebGLRenderer();
 				renderer.setSize( window.innerWidth, window.innerHeight );
 				container.appendChild( renderer.domElement );
 

+ 1 - 1
examples/webgl_materials_shaders_fresnel.html

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

+ 1 - 1
examples/webgl_materials_skin.html

@@ -158,7 +158,7 @@
 
 				// RENDERER
 
-				renderer = new THREE.WebGLRenderer( { antialias: false } );
+				renderer = new THREE.WebGLRenderer();
 				renderer.setPixelRatio( window.devicePixelRatio );
 				renderer.setSize( window.innerWidth, window.innerHeight );
 				renderer.autoClear = false;

+ 1 - 1
examples/webgl_materials_video.html

@@ -97,7 +97,7 @@
 				light.position.set( 0.5, 1, 1 ).normalize();
 				scene.add( light );
 
-				renderer = new THREE.WebGLRenderer( { antialias: false } );
+				renderer = new THREE.WebGLRenderer();
 				renderer.setPixelRatio( window.devicePixelRatio );
 				renderer.setSize( window.innerWidth, window.innerHeight );
 				container.appendChild( renderer.domElement );

+ 1 - 1
examples/webgl_multiple_renderers.html

@@ -172,7 +172,7 @@
 				renderer1.setSize( window.innerWidth, window.innerHeight / 2 );
 				document.body.appendChild( renderer1.domElement );
 
-				renderer2 = new THREE.WebGLRenderer( { antialias: false } );
+				renderer2 = new THREE.WebGLRenderer();
 				renderer2.setPixelRatio( window.devicePixelRatio );
 				renderer2.setSize( window.innerWidth, window.innerHeight / 2 );
 				document.body.appendChild( renderer2.domElement );

+ 1 - 1
examples/webgl_performance_static.html

@@ -75,7 +75,7 @@
 
 				} );
 
-				renderer = new THREE.WebGLRenderer( { antialias: false } );
+				renderer = new THREE.WebGLRenderer();
 				renderer.setPixelRatio( window.devicePixelRatio );
 				renderer.setSize( window.innerWidth, window.innerHeight );
 				//renderer.sortObjects = false;

+ 1 - 1
examples/webgl_points_dynamic.html

@@ -107,7 +107,7 @@
 				} );
 
 
-				renderer = new THREE.WebGLRenderer( { antialias: false } );
+				renderer = new THREE.WebGLRenderer();
 				renderer.setPixelRatio( window.devicePixelRatio );
 				renderer.setSize( window.innerWidth,window.innerHeight );
 				renderer.autoClear = false;

+ 1 - 1
examples/webgl_postprocessing_advanced.html

@@ -141,7 +141,7 @@
 
 				//
 
-				renderer = new THREE.WebGLRenderer( { antialias: false } );
+				renderer = new THREE.WebGLRenderer();
 				renderer.setPixelRatio( window.devicePixelRatio );
 				renderer.setSize( width, height );
 				renderer.autoClear = false;

+ 1 - 1
examples/webgl_postprocessing_backgrounds.html

@@ -118,7 +118,7 @@
 				var aspect = width / height;
 				var devicePixelRatio = window.devicePixelRatio || 1;
 
-				renderer = new THREE.WebGLRenderer( { antialias: false } );
+				renderer = new THREE.WebGLRenderer();
 				renderer.setPixelRatio( devicePixelRatio );
 				renderer.setSize( width, height );
 				document.body.appendChild( renderer.domElement );

+ 1 - 1
examples/webgl_postprocessing_dof.html

@@ -88,7 +88,7 @@
 
 				scene = new THREE.Scene();
 
-				renderer = new THREE.WebGLRenderer( { antialias: false } );
+				renderer = new THREE.WebGLRenderer();
 				renderer.setPixelRatio( window.devicePixelRatio );
 				renderer.setSize( width, height );
 				container.appendChild( renderer.domElement );

+ 1 - 1
examples/webgl_postprocessing_dof2.html

@@ -93,7 +93,7 @@ Use WEBGL Depth buffer support?
 				scene = new THREE.Scene();
 				scene.add( camera );
 
-				renderer = new THREE.WebGLRenderer( { antialias: false } );
+				renderer = new THREE.WebGLRenderer();
 				renderer.setPixelRatio( window.devicePixelRatio );
 				renderer.setSize( window.innerWidth, height );
 				//renderer.sortObjects = false;

+ 1 - 1
examples/webgl_postprocessing_godrays.html

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

+ 1 - 1
examples/webgl_postprocessing_masking.html

@@ -53,7 +53,7 @@
 				torus = new THREE.Mesh( new THREE.TorusGeometry( 3, 1, 16, 32 ) );
 				scene2.add( torus );
 
-				renderer = new THREE.WebGLRenderer( { antialias: false } );
+				renderer = new THREE.WebGLRenderer();
 				renderer.setClearColor( 0xe0e0e0 );
 				renderer.setPixelRatio( window.devicePixelRatio );
 				renderer.setSize( window.innerWidth, window.innerHeight );

+ 1 - 1
examples/webgl_postprocessing_outline.html

@@ -145,7 +145,7 @@
 				var width = window.innerWidth;
 				var height = window.innerHeight;
 
-				renderer = new THREE.WebGLRenderer( { antialias: false } );
+				renderer = new THREE.WebGLRenderer();
 				renderer.shadowMap.enabled = true;
 				// todo - support pixelRatio in this demo
 				renderer.setSize( width, height );

+ 1 - 1
examples/webgl_postprocessing_procedural.html

@@ -105,7 +105,7 @@
 
 				var container = document.getElementById( "container" );
 
-				renderer = new THREE.WebGLRenderer( { antialias: false } );
+				renderer = new THREE.WebGLRenderer();
 				renderer.setPixelRatio( window.devicePixelRatio );
 				renderer.setSize( window.innerWidth, window.innerHeight );
 				document.body.appendChild( renderer.domElement );

+ 1 - 1
examples/webgl_postprocessing_smaa.html

@@ -40,7 +40,7 @@
 
 				var container = document.getElementById( "container" );
 
-				renderer = new THREE.WebGLRenderer( { antialias: false } );
+				renderer = new THREE.WebGLRenderer();
 				renderer.setPixelRatio( window.devicePixelRatio );
 				renderer.setSize( window.innerWidth, window.innerHeight );
 				document.body.appendChild( renderer.domElement );

+ 1 - 1
examples/webgl_postprocessing_ssaa.html

@@ -87,7 +87,7 @@
 
 				var container = document.getElementById( "container" );
 
-				renderer = new THREE.WebGLRenderer( { antialias: false } );
+				renderer = new THREE.WebGLRenderer();
 				renderer.setPixelRatio( window.devicePixelRatio );
 				renderer.setSize( window.innerWidth, window.innerHeight );
 				document.body.appendChild( renderer.domElement );

+ 1 - 1
examples/webgl_postprocessing_ssaa_unbiased.html

@@ -107,7 +107,7 @@
 				var aspect = width / height;
 				var devicePixelRatio = window.devicePixelRatio || 1;
 
-				renderer = new THREE.WebGLRenderer( { antialias: false } );
+				renderer = new THREE.WebGLRenderer();
 				renderer.setPixelRatio( devicePixelRatio );
 				renderer.setSize( width, height );
 				document.body.appendChild( renderer.domElement );

+ 1 - 1
examples/webgl_postprocessing_ssao.html

@@ -79,7 +79,7 @@ Spiral sampling http://web.archive.org/web/20120421191837/http://www.cgafaq.info
 				container = document.createElement( 'div' );
 				document.body.appendChild( container );
 
-				renderer = new THREE.WebGLRenderer( { antialias: false } );
+				renderer = new THREE.WebGLRenderer();
 				renderer.setSize( window.innerWidth, window.innerHeight );
 				document.body.appendChild( renderer.domElement );
 

+ 1 - 1
examples/webgl_postprocessing_taa.html

@@ -107,7 +107,7 @@
 
 				var container = document.getElementById( "container" );
 
-				renderer = new THREE.WebGLRenderer( { antialias: false } );
+				renderer = new THREE.WebGLRenderer();
 				renderer.setPixelRatio( window.devicePixelRatio );
 				renderer.setSize( window.innerWidth, window.innerHeight );
 				document.body.appendChild( renderer.domElement );

+ 1 - 1
examples/webgl_postprocessing_unreal_bloom.html

@@ -96,7 +96,7 @@
 				scene = new THREE.Scene();
 				scene.background = new THREE.Color( 0x111111 );
 
-				renderer = new THREE.WebGLRenderer( { antialias: false } );
+				renderer = new THREE.WebGLRenderer();
 				renderer.toneMapping = THREE.LinearToneMapping;
 
 				standardMaterial = new THREE.MeshStandardMaterial( {

+ 83 - 95
examples/webgl_shaders_ocean.html

@@ -34,6 +34,7 @@
 
 		<script src="js/controls/OrbitControls.js"></script>
 		<script src="js/objects/Water.js"></script>
+		<script src="js/objects/Sky.js"></script>
 
 		<script src="js/Detector.js"></script>
 		<script src="js/libs/stats.min.js"></script>
@@ -45,14 +46,7 @@
 
 			var container, stats;
 			var camera, scene, renderer, light;
-			var controls, water, sphere, cubeMap;
-
-			var parameters = {
-				oceanSide: 2000,
-				size: 1.0,
-				distortionScale: 3.7,
-				alpha: 1.0
-			};
+			var controls, water, sphere;
 
 			init();
 			animate();
@@ -66,13 +60,11 @@
 				renderer = new THREE.WebGLRenderer();
 				renderer.setPixelRatio( window.devicePixelRatio );
 				renderer.setSize( window.innerWidth, window.innerHeight );
-				renderer.shadowMap.enabled = true;
 				container.appendChild( renderer.domElement );
 
 				//
 
 				scene = new THREE.Scene();
-				scene.fog = new THREE.FogExp2( 0xaabbbb, 0.001 );
 
 				//
 
@@ -82,29 +74,77 @@
 				//
 
 				light = new THREE.DirectionalLight( 0xffffff, 0.8 );
-				light.position.set( - 30, 30, 30 );
-				light.castShadow = true;
-				light.shadow.camera.top = 45;
-				light.shadow.camera.right = 40;
-				light.shadow.camera.left = light.shadow.camera.bottom = -40;
-				light.shadow.camera.near = 1;
-				light.shadow.camera.far = 200;
 				scene.add( light );
 
-				var ambientLight = new THREE.AmbientLight( 0xcccccc, 0.4 );
-				scene.add( ambientLight );
+				// Water
 
-				//
+				var waterGeometry = new THREE.PlaneBufferGeometry( 10000, 10000 );
 
-				setWater();
+				water = new THREE.Water(
+					waterGeometry,
+					{
+						textureWidth: 512,
+						textureHeight: 512,
+						waterNormals: new THREE.TextureLoader().load( 'textures/waternormals.jpg', function ( texture ) {
+							texture.wrapS = texture.wrapT = THREE.RepeatWrapping;
+						}),
+						alpha: 1.0,
+						sunDirection: light.position.clone().normalize(),
+						sunColor: 0xffffff,
+						waterColor: 0x001e0f,
+						distortionScale:  3.7,
+						fog: scene.fog !== undefined
+					}
+				);
 
-				//
+				water.rotation.x = - Math.PI / 2;
 
-				setSkybox();
+				scene.add( water );
+
+				// Skybox
+
+				var sky = new THREE.Sky();
+				sky.scale.setScalar( 10000 );
+				scene.add( sky );
+
+				var uniforms = sky.material.uniforms;
+
+				uniforms.turbidity.value = 10;
+				uniforms.rayleigh.value = 2;
+				uniforms.luminance.value = 1;
+				uniforms.mieCoefficient.value = 0.005;
+				uniforms.mieDirectionalG.value = 0.8;
+
+				var parameters = {
+					distance: 400,
+					inclination: 0.49,
+					azimuth: 0.205
+				};
+
+				var cubeCamera = new THREE.CubeCamera( 1, 20000, 256 );
+				cubeCamera.renderTarget.texture.minFilter = THREE.LinearMipMapLinearFilter;
+
+				function updateSun() {
+
+					var theta = Math.PI * ( parameters.inclination - 0.5 );
+					var phi = 2 * Math.PI * ( parameters.azimuth - 0.5 );
+
+					light.position.x = parameters.distance * Math.cos( phi );
+					light.position.y = parameters.distance * Math.sin( phi ) * Math.sin( theta );
+					light.position.z = parameters.distance * Math.sin( phi ) * Math.cos( theta );
+
+					sky.material.uniforms.sunPosition.value = light.position.copy( light.position );
+					water.material.uniforms.sunDirection.value.copy( light.position ).normalize();
+
+					cubeCamera.update( renderer, scene );
+
+				}
+
+				updateSun();
 
 				//
 
-				var geometry = new THREE.IcosahedronGeometry( 20, 2 );
+				var geometry = new THREE.IcosahedronGeometry( 20, 1 );
 
 				for ( var i = 0, j = geometry.faces.length; i < j; i ++ ) {
 
@@ -112,15 +152,15 @@
 
 				}
 
-				var material = new THREE.MeshPhongMaterial( {
+				var material = new THREE.MeshStandardMaterial( {
 					vertexColors: THREE.FaceColors,
-					shininess: 10,
-					envMap: cubeMap,
+					roughness: 0.0,
+					flatShading: true,
+					envMap: cubeCamera.renderTarget.texture,
 					side: THREE.DoubleSide
 				} );
 
 				sphere = new THREE.Mesh( geometry, material );
-				sphere.castShadow = true;
 				scene.add( sphere );
 
 				//
@@ -128,7 +168,7 @@
 				controls = new THREE.OrbitControls( camera, renderer.domElement );
 				controls.maxPolarAngle = Math.PI * 0.495;
 				controls.target.set( 0, 10, 0 );
-				controls.enablePan = false;
+				controls.panningMode = THREE.HorizontalPanning;
 				controls.minDistance = 40.0;
 				controls.maxDistance = 200.0;
 				camera.lookAt( controls.target );
@@ -138,77 +178,28 @@
 				stats = new Stats();
 				container.appendChild( stats.dom );
 
-				//
+				// GUI
 
 				var gui = new dat.GUI();
 
-				gui.add( parameters, 'distortionScale', 0, 8, 0.1 );
-				gui.add( parameters, 'size', 0.1, 10, 0.1 );
-				gui.add( parameters, 'alpha', 0.9, 1, .001 );
+				var uniforms = sky.material.uniforms;
 
-				//
+				var folder = gui.addFolder( 'Sky' );
+				folder.add( parameters, 'inclination', 0, 0.5, 0.0001 ).onChange( updateSun );
+				folder.add( parameters, 'azimuth', 0, 1, 0.0001 ).onChange( updateSun );
+				folder.open();
 
-				window.addEventListener( 'resize', onWindowResize, false );
-
-			}
-
-			function setWater() {
-
-				var waterGeometry = new THREE.PlaneBufferGeometry( parameters.oceanSide * 5, parameters.oceanSide * 5 );
-
-				water = new THREE.Water(
-					waterGeometry,
-					{
-						textureWidth: 512,
-						textureHeight: 512,
-						waterNormals: new THREE.TextureLoader().load( 'textures/waternormals.jpg', function ( texture ) {
-							texture.wrapS = texture.wrapT = THREE.RepeatWrapping;
-						}),
-						alpha: parameters.alpha,
-						sunDirection: light.position.clone().normalize(),
-						sunColor: 0xffffff,
-						waterColor: 0x001e0f,
-						distortionScale: parameters.distortionScale,
-						fog: scene.fog !== undefined
-					}
-				);
-
-				water.rotation.x = - Math.PI / 2;
-				water.receiveShadow = true;
-
-				scene.add( water );
-
-			}
+				var uniforms = water.material.uniforms;
 
-			function setSkybox() {
+				var folder = gui.addFolder( 'Water' );
+				folder.add( uniforms.distortionScale, 'value', 0, 8, 0.1 ).name( 'distortionScale' );
+				folder.add( uniforms.size, 'value', 0.1, 10, 0.1 ).name( 'size' );
+				folder.add( uniforms.alpha, 'value', 0.9, 1, .001 ).name( 'alpha' );
+				folder.open();
 
-				var cubeTextureLoader = new THREE.CubeTextureLoader();
-				cubeTextureLoader.setPath( 'textures/cube/skyboxsun25deg/' );
-
-				cubeMap = cubeTextureLoader.load( [
-					'px.jpg', 'nx.jpg',
-					'py.jpg', 'ny.jpg',
-					'pz.jpg', 'nz.jpg',
-				] );
-
-				var cubeShader = THREE.ShaderLib[ 'cube' ];
-				cubeShader.uniforms[ 'tCube' ].value = cubeMap;
-
-				var skyBoxMaterial = new THREE.ShaderMaterial( {
-					fragmentShader: cubeShader.fragmentShader,
-					vertexShader: cubeShader.vertexShader,
-					uniforms: cubeShader.uniforms,
-					side: THREE.BackSide
-				} );
-
-				var skyBoxGeometry = new THREE.BoxBufferGeometry(
-					parameters.oceanSide * 5 + 100,
-					parameters.oceanSide * 5 + 100,
-					parameters.oceanSide * 5 + 100 );
-
-				var skyBox = new THREE.Mesh( skyBoxGeometry, skyBoxMaterial );
+				//
 
-				scene.add( skyBox );
+				window.addEventListener( 'resize', onWindowResize, false );
 
 			}
 
@@ -238,9 +229,6 @@
 				sphere.rotation.z = time * 0.51;
 
 				water.material.uniforms.time.value += 1.0 / 60.0;
-				water.material.uniforms.size.value = parameters.size;
-				water.material.uniforms.distortionScale.value = parameters.distortionScale;
-				water.material.uniforms.alpha.value = parameters.alpha;
 
 				renderer.render( scene, camera );
 

+ 1 - 1
examples/webgl_shadowmap_performance.html

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

Some files were not shown because too many files changed in this diff