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

Merge branch 'dev' of https://github.com/mrdoob/three.js into dev

Luis Blanco 6 жил өмнө
parent
commit
54c6ef8d35
100 өөрчлөгдсөн 2295 нэмэгдсэн , 2842 устгасан
  1. 1 1
      .github/ISSUE_TEMPLATE.md
  2. 2 2
      README.md
  3. 9 7
      build/three.js
  4. 223 399
      build/three.min.js
  5. 9 7
      build/three.module.js
  6. 1 4
      docs/api/en/animation/AnimationClip.html
  7. 3 0
      docs/api/en/audio/Audio.html
  8. 6 18
      docs/api/en/deprecated/DeprecatedList.html
  9. 0 122
      docs/api/en/loaders/JSONLoader.html
  10. 0 4
      docs/api/en/loaders/ObjectLoader.html
  11. 0 5
      docs/api/en/objects/SkinnedMesh.html
  12. 1 1
      docs/api/en/scenes/Scene.html
  13. 1 4
      docs/api/zh/animation/AnimationClip.html
  14. 14 14
      docs/api/zh/animation/tracks/BooleanKeyframeTrack.html
  15. 12 13
      docs/api/zh/animation/tracks/ColorKeyframeTrack.html
  16. 12 12
      docs/api/zh/animation/tracks/NumberKeyframeTrack.html
  17. 17 16
      docs/api/zh/animation/tracks/QuaternionKeyframeTrack.html
  18. 16 16
      docs/api/zh/animation/tracks/StringKeyframeTrack.html
  19. 12 12
      docs/api/zh/animation/tracks/VectorKeyframeTrack.html
  20. 3 0
      docs/api/zh/audio/Audio.html
  21. 6 25
      docs/api/zh/deprecated/DeprecatedList.html
  22. 0 119
      docs/api/zh/loaders/JSONLoader.html
  23. 0 4
      docs/api/zh/loaders/ObjectLoader.html
  24. 48 57
      docs/api/zh/math/Plane.html
  25. 0 5
      docs/api/zh/objects/SkinnedMesh.html
  26. 1 1
      docs/examples/loaders/GLTFLoader.html
  27. 23 0
      docs/examples/loaders/MMDLoader.html
  28. 0 2
      docs/list.js
  29. 0 1
      docs/manual/en/introduction/Animation-system.html
  30. 0 58
      docs/manual/en/introduction/How-to-run-things-locally.html
  31. 1 1
      docs/manual/en/introduction/Loading-3D-models.html
  32. 2 3
      docs/manual/zh/introduction/Animation-system.html
  33. 4 6
      editor/index.html
  34. 1 44
      editor/js/Loader.js
  35. 1 49
      editor/js/libs/tern-threejs/threejs.js
  36. 0 1
      examples/files.js
  37. 3 1
      examples/js/loaders/AssimpLoader.js
  38. 183 69
      examples/js/loaders/EquirectangularToCubeGenerator.js
  39. 11 9
      examples/js/loaders/GLTFLoader.js
  40. 2 2
      examples/js/loaders/HDRCubeTextureLoader.js
  41. 132 11
      examples/js/loaders/MMDLoader.js
  42. 578 0
      examples/js/loaders/deprecated/LegacyJSONLoader.js
  43. 64 2
      examples/js/loaders/sea3d/SEA3DLoader.js
  44. 1 2
      examples/js/nodes/materials/nodes/StandardNode.js
  45. 38 0
      examples/js/offscreen/jank.js
  46. 9 0
      examples/js/offscreen/offscreen.js
  47. 77 0
      examples/js/offscreen/scene.js
  48. 164 135
      examples/js/pmrem/PMREMCubeUVPacker.js
  49. 126 121
      examples/js/pmrem/PMREMGenerator.js
  50. 8 8
      examples/js/postprocessing/UnrealBloomPass.js
  51. 0 76
      examples/js/workers/OffscreenCanvas.js
  52. BIN
      examples/models/gltf/Soldier.glb
  53. BIN
      examples/models/skinned/marine/M4.png
  54. BIN
      examples/models/skinned/marine/MarineCv2_color.jpg
  55. BIN
      examples/models/skinned/marine/m4.blend
  56. 0 36
      examples/models/skinned/marine/m4.js
  57. 0 10
      examples/models/skinned/marine/marine_anims.json
  58. BIN
      examples/models/skinned/marine/marine_anims_all.blend
  59. 0 10
      examples/models/skinned/marine/marine_anims_all.json
  60. BIN
      examples/models/skinned/marine/marine_anims_core.blend
  61. 0 10
      examples/models/skinned/marine/marine_anims_core.json
  62. BIN
      examples/models/skinned/marine/marine_anims_single.blend
  63. 0 10
      examples/models/skinned/marine/marine_anims_single.json
  64. BIN
      examples/models/skinned/marine/marine_ik.blend
  65. 0 10
      examples/models/skinned/marine/marine_ik.json
  66. 1 1
      examples/webaudio_orientation.html
  67. 71 80
      examples/webgl_animation_skinning_blending.html
  68. 7 12
      examples/webgl_loader_gltf.html
  69. 0 179
      examples/webgl_loader_json.html
  70. 18 10
      examples/webgl_materials_cubemap_dynamic.html
  71. 24 0
      examples/webgl_materials_envmaps.html
  72. 47 47
      examples/webgl_materials_envmaps_exr.html
  73. 88 90
      examples/webgl_materials_envmaps_hdr.html
  74. 8 10
      examples/webgl_materials_matcap.html
  75. 12 8
      examples/webgl_postprocessing_ssao.html
  76. 1 0
      examples/webgl_tiled_forward.html
  77. 62 37
      examples/webgl_worker_offscreencanvas.html
  78. 4 6
      examples/webvr_ballshooter.html
  79. 4 6
      examples/webvr_cubes.html
  80. 4 6
      examples/webvr_dragging.html
  81. 4 6
      examples/webvr_lorenzattractor.html
  82. 4 6
      examples/webvr_paint.html
  83. 4 6
      examples/webvr_panorama.html
  84. 4 6
      examples/webvr_rollercoaster.html
  85. 4 6
      examples/webvr_sandbox.html
  86. 4 6
      examples/webvr_sculpt.html
  87. 4 6
      examples/webvr_video.html
  88. 4 6
      examples/webvr_vive_paint.html
  89. 4 6
      examples/webvr_vive_sculpt.html
  90. 1 1
      package.json
  91. 15 12
      src/Three.Legacy.js
  92. 0 1
      src/Three.js
  93. 23 1
      src/audio/Audio.js
  94. 1 1
      src/constants.js
  95. 2 4
      src/helpers/SpotLightHelper.js
  96. 0 587
      src/loaders/JSONLoader.js
  97. 12 4
      src/loaders/ObjectLoader.js
  98. 0 17
      src/materials/MeshMatcapMaterial.js
  99. 23 112
      src/objects/SkinnedMesh.js
  100. 6 1
      src/renderers/shaders/ShaderLib/equirect_frag.glsl.js

+ 1 - 1
.github/ISSUE_TEMPLATE.md

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

+ 2 - 2
README.md

@@ -79,8 +79,8 @@ If everything went well you should see [this](https://jsfiddle.net/f2Lommf5/).
 
 [npm]: https://img.shields.io/npm/v/three.svg
 [npm-url]: https://www.npmjs.com/package/three
-[build-size]: https://badge-size.herokuapp.com/mrdoob/three.js/master/build/three.min.js.svg?compression=gzip
-[build-size-url]: https://github.com/mrdoob/three.js/tree/master/build
+[build-size]: https://badgen.net/bundlephobia/minzip/three
+[build-size-url]: https://bundlephobia.com/result?p=three
 [build-status]: https://travis-ci.org/mrdoob/three.js.svg?branch=dev
 [build-status-url]: https://travis-ci.org/mrdoob/three.js
 [dependencies]: https://img.shields.io/david/mrdoob/three.js.svg

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


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


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


+ 1 - 4
docs/api/en/animation/AnimationClip.html

@@ -96,10 +96,7 @@
 		<p>
 			Returns an array of new AnimationClips created from the [page:Geometry.morphTargets morph
 			target sequences] of a geometry, trying to sort morph target names into animation-group-based
-			patterns like "Walk_001, Walk_002, Run_001, Run_002 ..."<br /><br />
-
-			This method is called by the [page:JSONLoader] internally, and it uses
-			[page:.CreateFromMorphTargetSequence CreateFromMorphTargetSequence].
+			patterns like "Walk_001, Walk_002, Run_001, Run_002 ...".
 		</p>
 
 		<h3>[method:AnimationClip CreateFromMorphTargetSequence]( [param:String name], [param:Array morphTargetSequence], [param:Number fps], [param:Boolean noLoop] )</h3>

+ 3 - 0
docs/api/en/audio/Audio.html

@@ -62,6 +62,9 @@
 		<h3>[property:AudioContext context]</h3>
 		<p>The [link:https://developer.mozilla.org/en-US/docs/Web/API/AudioContext AudioContext] of the [page:AudioListener listener] given in the constructor.</p>
 
+		<h3>[property:Number detune]</h3>
+		<p>Modify pitch, measured in cents. +/- 100 is a semitone. +/- 1200 is an octave. Default is *0*.</p>
+
 		<h3>[property:Array filters]</h3>
 		<p>Represents an array of [link:https://developer.mozilla.org/en-US/docs/Web/API/BiquadFilterNode BiquadFilterNodes]. Can be used to apply a variety of low-order filters to create more complex sound effects. Filters are set via [page:Audio.setFilter] or [page:Audio.setFilters].</p>
 

+ 6 - 18
docs/api/en/deprecated/DeprecatedList.html

@@ -245,24 +245,13 @@
 			Light.shadowMapHeight is now [page:Light.shadow.mapSize.height].
 		</p>
 
-
-
-
-
-
-
-
 		<h2>Loaders</h2>
 
 		<h3>[page:XHRLoader]</h3>
 		<p>XHRLoader has been renamed to [page:FileLoader].</p>
 
-
-
-
-
-
-
+		<h3>[page:JSONLoader]</h3>
+		<p>JSONLoader has been removed from core.</p>
 
 		<h2>Maths</h2>
 
@@ -494,11 +483,10 @@
 			Shape.makeGeometry has been removed. Use [page:ShapeGeometry] instead.
 		</p>
 
-
-
-
-
-
+		<h3>[page:SkinnedMesh]</h3>
+		<p>
+			SkinnedMesh.initBones() has been removed.
+		</p>
 
 
 		<h2>Renderers</h2>

+ 0 - 122
docs/api/en/loaders/JSONLoader.html

@@ -1,122 +0,0 @@
-<!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>
-
-		<p class="desc">
-			A loader for loading objects in JSON format.
-			This uses the [page:FileLoader] internally for loading files.
-		</p>
-
-		<h2>Example</h2>
-
-		<p>
-		[example:webgl_loader_json WebGL / loader / json]
-		</p>
-
-		<code>
-		// instantiate a loader
-		var loader = new THREE.JSONLoader();
-
-		// load a resource
-		loader.load(
-			// resource URL
-			'models/animated/monster/monster.js',
-
-			// onLoad callback
-			function ( geometry, materials ) {
-				var material = materials[ 0 ];
-				var object = new THREE.Mesh( geometry, material );
-				scene.add( object );
-			},
-
-			// onProgress callback
-			function ( xhr ) {
-				console.log( (xhr.loaded / xhr.total * 100) + '% loaded' );
-			},
-
-			// onError callback
-			function( err ) {
-				console.log( 'An error happened' );
-			}
-		);
-		</code>
-
-		<h2>Constructor</h2>
-
-		<h3>[name]( [param:LoadingManager manager] )</h3>
-		<p>
-		[page:LoadingManager manager] — The [page:LoadingManager loadingManager] for the loader to use. Default is [page:LoadingManager THREE.DefaultLoadingManager].
-		</p>
-		<p>
-		Creates a new [name].
-		</p>
-
-		<h2>Properties</h2>
-
-		<h3>[property:String crossOrigin]</h3>
-		<p>
-		If set, assigns the [link:https://developer.mozilla.org/en-US/docs/Web/HTML/CORS_settings_attributes crossOrigin]
-	 attribute of the image to the value of *crossOrigin*, prior to starting the load. Default is *"anonymous"*.
-		</p>
-
-		<h3>[property:LoadingManager manager]</h3>
-		<p>
-			The [page:LoadingManager loadingManager]  the loader is using. Default is [page:DefaultLoadingManager].
-		</p>
-
-		<h3>[property:String withCredentials]</h3>
-		<p>
-			Whether the XMLHttpRequest uses credentials.
-			Default is *false*.
-		</p>
-
-		<h2>Methods</h2>
-
-		<h3>[method:null load]( [param:String url], [param:Function onLoad], [param:Function onProgress], [param:Function onError] )</h3>
-		<p>
-		[page:String url] — the path or URL to the file. This can also be a
-			[link:https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/Data_URIs Data URI]..<br />
-		[page:Function onLoad] — Will be called when load completes. The argument will be the loaded text response.<br />
-		[page:Function onProgress] — Will be called while load progresses. The argument will be the XMLHttpRequest instance, which contains .[page:Integer total] and .[page:Integer loaded] bytes.<br />
-		[page:Function onError] — Will be called when load errors.<br />
-		</p>
-		<p>
-		Begin loading from url and pass the <em>JSON</em> to onLoad.
-		</p>
-
-		<h3>[method:Object3D parse]( [param:Object json], [param:String path] )</h3>
-		<p>
-		[page:String json] — JSON object to parse.<br />
-		[page:String path] — Base path for resources if no resource path is defined.<br /><br />
-
-		Parse a <em>JSON</em> structure and return an [page:object] containing the parsed [page:Geometry geometry] and [page:Array materials].
-		</p>
-
-		<h3>[method:JSONLoader setCrossOrigin]( [param:String value] )</h3>
-		<p>
-			Set the [page:.crossOrigin] attribute.
-		</p>
-
-		<h3>[method:JSONLoader setPath]( [param:String value] )</h3>
-		<p>
-			Set the base path for the original file.
-		</p>
-
-		<h3>[method:JSONLoader setResourcePath]( [param:String value] )</h3>
-		<p>
-			Set the base path for dependent resources like textures.
-		</p>
-
-		<h2>Source</h2>
-
-		[link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js]
-	</body>
-</html>

+ 0 - 4
docs/api/en/loaders/ObjectLoader.html

@@ -13,15 +13,12 @@
 		<p class="desc">
 			A loader for loading a JSON resource in the [link:https://github.com/mrdoob/three.js/wiki/JSON-Object-Scene-format-4 JSON Object/Scene format].<br /><br />
 
-			Note that this loader can't load geometries of type [page:Geometry]. Use [page:JSONLoader] instead for that.<br /><br />
-
 			This uses the [page:FileLoader] internally for loading files.
 		</p>
 
 		<h2>Example</h2>
 
 		<p>
-			[example:webgl_animation_skinning_blending WebGL / animation / skinning / blending]<br />
 			[example:webgl_loader_json_claraio WebGL / loader / json / claraio]<br />
 			[example:webgl_materials_lightmap WebGL / materials / lightmap]
 		</p>
@@ -119,7 +116,6 @@
 		[page:Object json] — required. The JSON source to parse.<br /><br />
 
 		This is used [page:.parse] to parse any [page:Geometry geometries] or [page:BufferGeometry buffer geometries]  in the JSON structure.
-		Internally it uses [page:JSONLoader] for geometries and [page:BufferGeometryLoader] for buffer geometries.
 		</p>
 
 		<h3>[method:Object3D parseMaterials]( [param:Object json] )</h3>

+ 0 - 5
docs/api/en/objects/SkinnedMesh.html

@@ -149,11 +149,6 @@
 		Updates the [page:Matrix4 MatrixWorld].
 		</p>
 
-		<h3>[method:null initBones]()</h3>
-		<p>
-		Creates an array of hierarchical [page:Bone bones] objects from the internal geometry.
-		</p>
-
 		<h2>Source</h2>
 
 		[link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js]

+ 1 - 1
docs/api/en/scenes/Scene.html

@@ -41,7 +41,7 @@
 
 		<h3>[property:Object background]</h3>
 		<p>
-		If not null, sets the background used when rendering the scene, and is always rendered first. Can be set to a [page:Color] which sets the clear color, a [page:Texture] covering the canvas, or a [page:CubeTexture]. Default is null.
+		If not null, sets the background used when rendering the scene, and is always rendered first. Can be set to a [page:Color] which sets the clear color, a [page:Texture] covering the canvas, or a cubemap as a [page:CubeTexture] or [page:WebGLRenderTargetCube]. Default is null.
 		</p>
 
 		<h2>Methods</h2>

+ 1 - 4
docs/api/zh/animation/AnimationClip.html

@@ -91,10 +91,7 @@
 		<h3>[method:Array CreateClipsFromMorphTargetSequences]( [param:String name], [param:Array morphTargetSequence], [param:Number fps], [param:Boolean noLoop] )</h3>
 		<p>
 			返回从几何体的变形目标序列([page:Geometry.morphTargets morph
-			target sequences])创建的新动画剪辑(AnimationClip)数组,并尝试将变形目标名称分类为基于动画组的模式,如“Walk_001、Walk_002、Run_001、Run_002……”。<br /><br />
-
-			该方法被[page:JSONLoader]内部调用, 并且它使用了
-			[page:.CreateFromMorphTargetSequence CreateFromMorphTargetSequence].
+			target sequences])创建的新动画剪辑(AnimationClip)数组,并尝试将变形目标名称分类为基于动画组的模式,如“Walk_001、Walk_002、Run_001、Run_002……”。
 		</p>
 
 		<h3>[method:AnimationClip CreateFromMorphTargetSequence]( [param:String name], [param:Array morphTargetSequence], [param:Number fps], [param:Boolean noLoop] )</h3>

+ 14 - 14
docs/api/zh/animation/tracks/BooleanKeyframeTrack.html

@@ -14,36 +14,36 @@
 		<h1>[name]</h1>
 
 		<p class="desc">
-			A Track of boolean keyframe values.
+			布尔类型的关键帧轨道。
 		</p>
 
 
-		<h2>Constructor</h2>
+		<h2>构造函数</h2>
 
 
 		<h3>[name]( [param:String name], [param:Array times], [param:Array values] )</h3>
 		<p>
-			[page:String name] - (required) identifier for the KeyframeTrack.<br />
-			[page:Array times] - (required) array of keyframe times.<br />
-			[page:Array values] - values for the keyframes at the times specified.<br />
+			[page:String name] - (必须) 关键帧轨道(KeyframeTrack)的标识符.<br />
+			[page:Array times] - (必须) 关键帧的时间数组.<br />
+			[page:Array values] - 与时间数组中的时间点对应的值数组.<br />
 		</p>
 
 
-		<h2>Properties</h2>
+		<h2>属性</h2>
 
 
 		<p class="desc">
-			See [page:KeyframeTrack] for inherited properties.
+			参见 [page:KeyframeTrack] 查看继承的属性.
 		</p>
 
 		<h3>[property:Constant DefaultInterpolation]</h3>
 		<p>
-			The default interpolation type to use, [page:Animation InterpolateDiscrete].
+			默认的插值类型。 参见 [page:Animation InterpolateDiscrete].
 		</p>
 
 		<h3>[property:Array ValueBufferType]</h3>
 		<p>
-			A normal Array (no Float32Array in this case, unlike *ValueBufferType* of [page:KeyframeTrack]).
+			一个基本数组 (不是 Float32Array 类型, 与 [page:KeyframeTrack] 内的 *ValueBufferType* 属性不一样).
 		</p>
 
 		<h3>[property:String ValueTypeName]</h3>
@@ -52,25 +52,25 @@
 		</p>
 
 
-		<h2>Methods</h2>
+		<h2>方法</h2>
 
 
 		<p class="desc">
-			See [page:KeyframeTrack] for inherited methods.
+			参见 [page:KeyframeTrack] 查看继承的方法.
 		</p>
 
 		<h3>[method:null InterpolantFactoryMethodLinear ]()</h3>
 		<p>
-			The value of this method here is 'undefined', as it does not make sense for discrete properties.
+			这个方法在这里的值为 'undefined', 因为他对离散属性没有意义.
 		</p>
 
 		<h3>[method:null InterpolantFactoryMethodSmooth ]()</h3>
 		<p>
-			The value of this method here is 'undefined', as it does not make sense for discrete properties.
+			这个方法在这里的值为 'undefined', 因为他对离散属性没有意义.
 		</p>
 
 
-		<h2>Source</h2>
+		<h2>源码</h2>
 
 
 		[link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js]

+ 12 - 13
docs/api/zh/animation/tracks/ColorKeyframeTrack.html

@@ -14,31 +14,30 @@
 		<h1>[name]</h1>
 
 		<p class="desc">
-			A Track of keyframe values that represent color changes.<br /><br />
-			The very basic implementation of this subclass has nothing special yet. However, this is the place
-			for color space parameterization.
+			反应颜色变化的关键帧轨道。<br /><br />
+			这个子类的基本实现还没有什么特别之处。不过,这里可以表示颜色空间参数化。
 		</p>
 
 
-		<h2>Constructor</h2>
+		<h2>构造函数</h2>
 
 
 		<h3>[name]( [param:String name], [param:Array times], [param:Array values] )</h3>
 		<p>
-			[page:String name] - (required) identifier for the KeyframeTrack.<br />
-			[page:Array times] - (required) array of keyframe times.<br />
-			[page:Array values] - values for the keyframes at the times specified.<br />
-			[page:Constant interpolation] - the type of interpolation to use. See
-			[page:Animation Animation Constants] for possible values. Default is
+			[page:String name] - (必须) 关键帧轨道(KeyframeTrack)的标识符.<br />
+			[page:Array times] - (必须) 关键帧的时间数组.<br />
+			[page:Array values] - 与时间数组中的时间点对应的值数组.<br />
+			[page:Constant interpolation] - 使用的插值类型。 取值参考
+			[page:Animation Animation Constants]. 默认值为
 			[page:Animation InterpolateLinear].
 		</p>
 
 
-		<h2>Properties</h2>
+		<h2>属性</h2>
 
 
 		<p class="desc">
-			See [page:KeyframeTrack] for inherited properties.
+			参见 [page:KeyframeTrack] 查看继承的属性.
 		</p>
 
 		<h3>[property:String ValueTypeName]</h3>
@@ -51,10 +50,10 @@
 
 
 		<p class="desc">
-			See [page:KeyframeTrack] for inherited methods.
+			参见 [page:KeyframeTrack] 查看继承的方法.
 		</p>
 
-		<h2>Source</h2>
+		<h2>源码</h2>
 
 
 		[link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js]

+ 12 - 12
docs/api/zh/animation/tracks/NumberKeyframeTrack.html

@@ -14,29 +14,29 @@
 		<h1>[name]</h1>
 
 		<p class="desc">
-			A Track of numeric keyframe values.
+			数字类型的关键帧轨道
 		</p>
 
 
-		<h2>Constructor</h2>
+		<h2>构造函数</h2>
 
 
 		<h3>[name]( [param:String name], [param:Array times], [param:Array values] )</h3>
 		<p>
-			[page:String name] - (required) identifier for the KeyframeTrack.<br />
-			[page:Array times] - (required) array of keyframe times.<br />
-			[page:Array values] - values for the keyframes at the times specified.<br />
-			[page:Constant interpolation] - the type of interpolation to use. See
-			[page:Animation Animation Constants] for possible values. Default is
+			[page:String name] - (必须) 关键帧轨道(KeyframeTrack)的标识符.<br />
+			[page:Array times] - (必须) 关键帧的时间数组.<br />
+			[page:Array values] - 与时间数组中的时间点对应的值数组.<br />
+			[page:Constant interpolation] - 使用的插值类型。 取值参考
+			[page:Animation Animation Constants] 默认值为
 			[page:Animation InterpolateLinear].
 		</p>
 
 
-		<h2>Properties</h2>
+		<h2>属性</h2>
 
 
 		<p class="desc">
-			See [page:KeyframeTrack] for inherited properties.
+			参见 [page:KeyframeTrack] 查看继承的属性.
 		</p>
 
 
@@ -46,15 +46,15 @@
 		</p>
 
 
-		<h2>Methods</h2>
+		<h2>方法</h2>
 
 
 		<p class="desc">
-			See [page:KeyframeTrack] for inherited methods.
+			参见 [page:KeyframeTrack] 查看继承的方法.
 		</p>
 
 
-		<h2>Source</h2>
+		<h2>源码</h2>
 
 
 		[link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js]

+ 17 - 16
docs/api/zh/animation/tracks/QuaternionKeyframeTrack.html

@@ -14,34 +14,34 @@
 		<h1>[name]</h1>
 
 		<p class="desc">
-			A Track of quaternion keyframe values.
+			四元数类型的关键帧轨道。
 		</p>
 
 
-		<h2>Constructor</h2>
+		<h2>构造函数</h2>
 
 
 		<h3>[name]( [param:String name], [param:Array times], [param:Array values] )</h3>
 		<p>
-			[page:String name] (required) identifier for the KeyframeTrack.<br />
-			[page:Array times] (required) array of keyframe times.<br />
-			[page:Array values] values for the keyframes at the times specified.<br />
-			[page:Constant interpolation] the type of interpolation to use. See
-			[page:Animation Animation Constants] for possible values. Default is
+			[page:String name] - (必须) 关键帧轨道(KeyframeTrack)的标识符.<br />
+			[page:Array times] - (必须) 关键帧的时间数组.<br />
+			[page:Array values] - 与时间数组中的时间点对应的值数组.<br />
+			[page:Constant interpolation] - 使用的插值类型。 取值参考
+			[page:Animation Animation Constants] 默认值为
 			[page:Animation InterpolateLinear].
 		</p>
 
 
-		<h2>Properties</h2>
+		<h2>属性</h2>
 
 
 		<p class="desc">
-			See [page:KeyframeTrack] for inherited properties.
+			参见 [page:KeyframeTrack] 查看继承的属性.
 		</p>
 
 		<h3>[property:Constant DefaultInterpolation]</h3>
 		<p>
-			The default interpolation type to use, [page:Animation InterpolateLinear].
+			默认的插值类型。 参见 [page:Animation InterpolateDiscrete].
 		</p>
 
 		<h3>[property:String ValueTypeName]</h3>
@@ -50,22 +50,23 @@
 		</p>
 
 
-		<h2>Methods</h2>
+		<h2>方法</h2>
 
 
 		<p class="desc">
-			See [page:KeyframeTrack] for inherited methods.
+			参见 [page:KeyframeTrack] 查看继承的方法.
 		</p>
 
 		<h3>[method:null InterpolantFactoryMethodLinear]()</h3>
 		<p>
-			Returns a new [page:QuaternionLinearInterpolant QuaternionLinearInterpolant] based on the
-			[page:KeyframeTrack.values values], [page:KeyframeTrack.times times] and
-			[page:KeyframeTrack.valueSize valueSize] of the keyframes.
+			根据值数组 ([page:KeyframeTrack.values values]),
+			时间 ([page:KeyframeTrack.times times])
+			和值大小 [page:KeyframeTrack.valueSize valueSize]
+			创建一个新的线性插值 ([page:QuaternionLinearInterpolant QuaternionLinearInterpolant])。
 		</p>
 
 
-		<h2>Source</h2>
+		<h2>源码</h2>
 
 
 		[link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js]

+ 16 - 16
docs/api/zh/animation/tracks/StringKeyframeTrack.html

@@ -14,39 +14,39 @@
 		<h1>[name]</h1>
 
 		<p class="desc">
-			A Track of string keyframe values.
+			字符串类型的关键帧轨道
 		</p>
 
 
-		<h2>Constructor</h2>
+		<h2>构造函数</h2>
 
 
 		<h3>[name]( [param:String name], [param:Array times], [param:Array values] )</h3>
 		<p>
-			[page:String name] - (required) identifier for the KeyframeTrack.<br />
-			[page:Array times] - (required) array of keyframe times.<br />
-			[page:Array values] - values for the keyframes at the times specified.<br />
-			[page:Constant interpolation] - the type of interpolation to use. See
-			[page:Animation Animation Constants] for possible values. Default is
+			[page:String name] - (必须) 关键帧轨道(KeyframeTrack)的标识符.<br />
+			[page:Array times] - (必须) 关键帧的时间数组.<br />
+			[page:Array values] - 与时间数组中的时间点对应的值数组.<br />
+			[page:Constant interpolation] - 使用的插值类型。 取值参考
+			[page:Animation Animation Constants] 默认值为
 			[page:Animation InterpolateDiscrete].
 		</p>
 
 
-		<h2>Properties</h2>
+		<h2>属性</h2>
 
 
 		<p class="desc">
-			See [page:KeyframeTrack] for inherited properties.
+			参见 [page:KeyframeTrack] 查看继承的属性.
 		</p>
 
 		<h3>[property:Constant DefaultInterpolation]</h3>
 		<p>
-			The default interpolation type to use, [page:Animation InterpolateDiscrete].
+			默认的插值类型。 参见 [page:Animation InterpolateDiscrete].
 		</p>
 
 		<h3>[property:Array ValueBufferType]</h3>
 		<p>
-			A normal Array (no Float32Array in this case, unlike *ValueBufferType* of [page:KeyframeTrack]).
+			一个基本数组 (不是 Float32Array 类型, 与 [page:KeyframeTrack] 内的 *ValueBufferType* 属性不一样).
 		</p>
 
 		<h3>[property:String ValueTypeName]</h3>
@@ -55,25 +55,25 @@
 		</p>
 
 
-		<h2>Methods</h2>
+		<h2>方法</h2>
 
 
 		<p class="desc">
-			See [page:KeyframeTrack] for inherited methods.
+			参见 [page:KeyframeTrack] 查看继承的方法.
 		</p>
 
 		<h3>[method:null InterpolantFactoryMethodLinear]()</h3>
 		<p>
-		  The value of this method here is 'undefined', as it does not make sense for discrete properties.
+			这个方法在这里的值为 'undefined', 因为他对离散属性没有意义.
 		</p>
 
 		<h3>[method:null InterpolantFactoryMethodSmooth]()</h3>
 		<p>
-		  The value of this method here is 'undefined', as it does not make sense for discrete properties.
+			这个方法在这里的值为 'undefined', 因为他对离散属性没有意义.
 		</p>
 
 
-		<h2>Source</h2>
+		<h2>源码</h2>
 
 
 		[link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js]

+ 12 - 12
docs/api/zh/animation/tracks/VectorKeyframeTrack.html

@@ -14,29 +14,29 @@
 		<h1>[name]</h1>
 
 		<p class="desc">
-			A Track of vector keyframe values.
+			向量类型的关键帧轨道
 		</p>
 
 
-		<h2>Constructor</h2>
+		<h2>构造函数</h2>
 
 
 		<h3>[name]( [param:String name], [param:Array times], [param:Array values] )</h3>
 		<p>
-			[page:String name] - (required) identifier for the KeyframeTrack.<br />
-			[page:Array times] - (required) array of keyframe times.<br />
-			[page:Array values] - values for the keyframes at the times specified.<br />
-			[page:Constant interpolation] - the type of interpolation to use. See
-			[page:Animation Animation Constants] for possible values. Default is
+			[page:String name] - (必须) 关键帧轨道(KeyframeTrack)的标识符.<br />
+			[page:Array times] - (必须) 关键帧的时间数组.<br />
+			[page:Array values] - 与时间数组中的时间点对应的值数组.<br />
+			[page:Constant interpolation] - 使用的插值类型。 取值参考
+			[page:Animation Animation Constants] 默认值为
 			[page:Animation InterpolateLinear].
 		</p>
 
 
-		<h2>Properties</h2>
+		<h2>属性</h2>
 
 
 		<p class="desc">
-			See [page:KeyframeTrack] for inherited properties.
+			参见 [page:KeyframeTrack] 查看继承的属性.
 		</p>
 
 		<h3>[property:String ValueTypeName]</h3>
@@ -45,15 +45,15 @@
 		</p>
 
 
-		<h2>Methods</h2>
+		<h2>方法</h2>
 
 
 		<p class="desc">
-			See [page:KeyframeTrack] for inherited methods.
+			参见 [page:KeyframeTrack] 查看继承的方法.
 		</p>
 
 
-		<h2>Source</h2>
+		<h2>源码</h2>
 
 
 		[link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js]

+ 3 - 0
docs/api/zh/audio/Audio.html

@@ -62,6 +62,9 @@
 		<h3>[property:AudioContext context]</h3>
 		<p>构造函数中传入[page:AudioListener listener]的[link:https://developer.mozilla.org/en-US/docs/Web/API/AudioContext AudioContext].</p>
 
+		<h3>[property:Number detune]</h3>
+		<p>TODO</p>
+
 		<h3>[property:Array filters]</h3>
 		<p>表示[link:https://developer.mozilla.org/en-US/docs/Web/API/BiquadFilterNode BiquadFilterNodes]的数组. 可以使用多种不同的低阶filters去创建复杂的音效. filters可以通过 [page:Audio.setFilter] 或者 [page:Audio.setFilters]设置.</p>
 

+ 6 - 25
docs/api/zh/deprecated/DeprecatedList.html

@@ -15,10 +15,6 @@
 			下面就列举出了这些API元素,以及一些关于他们的替代信息。
 		</p>
 
-		
-		
-		
-		
 		<h2>音频(Audio)</h2>
 
 		<h3>[page:Audio]</h3>
@@ -31,9 +27,6 @@
 		<p>BinaryTextureLoader 已被重命名为 [page:DataTextureLoader]。</p>
 
 
-		
-		
-		
 		<h2>缓冲器(Buffers)</h2>
 
 		<h3>[page:BufferAttribute]</h3>
@@ -232,24 +225,13 @@
 			Light.shadowMapHeight 现在是 [page:Light.shadow.mapSize.height]。
 		</p>
 
-
-
-
-
-
-
-
 		<h2>加载器(Loaders)</h2>
 
 		<h3>[page:XHRLoader]</h3>
 		<p>XHRLoader 已被重命名为 [page:FileLoader]。</p>
 
-
-
-
-
-
-
+		<h3>[page:JSONLoader]</h3>
+		<p>JSONLoader has been removed from core.</p>
 
 		<h2>数学(Maths)</h2>
 
@@ -481,11 +463,10 @@
 			Shape.makeGeometry 已被删除。 请使用[page:ShapeGeometry] 。
 		</p>
 
-
-
-
-
-
+		<h3>[page:SkinnedMesh]</h3>
+		<p>
+			SkinnedMesh.initBones() has been removed.
+		</p>
 
 
 		<h2>渲染器(Renderer)</h2>

+ 0 - 119
docs/api/zh/loaders/JSONLoader.html

@@ -1,119 +0,0 @@
-<!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>
-
-		<p class="desc">
-            以JSON格式来加载对象的加载器。
-			此加载器内部用 [page:FileLoader] 来加载文件。
-		</p>
-
-		<h2>例子</h2>
-
-		<p>
-		[example:webgl_loader_json WebGL / loader / json]<br />
-		[example:webgl_loader_json_objconverter WebGL / loader / json / objconverter]
-		</p>
-
-		<code>
-		// 初始化一个加载器
-		var loader = new THREE.JSONLoader();
-
-		// 加载一个资源
-		loader.load(
-			// 资源URL
-			'models/animated/monster/monster.js',
-
-			// onLoad的回调
-			function ( geometry, materials ) {
-				var material = materials[ 0 ];
-				var object = new THREE.Mesh( geometry, material );
-				scene.add( object );
-			},
-
-			// onProgress的回调
-			function ( xhr ) {
-				console.log( (xhr.loaded / xhr.total * 100) + '% loaded' );
-			},
-
-			// onError的回调
-			function( err ) {
-				console.log( 'An error happened' );
-			}
-		);
-		</code>
-
-		<h2>构造函数</h2>
-
-		<h3>[name]( [param:LoadingManager manager] )</h3>
-		<p>
-		[page:LoadingManager manager] — 加载器所使用的 [page:LoadingManager loadingManager]。 默认为 [page:LoadingManager THREE.DefaultLoadingManager].
-		</p>
-		<p>
-		创建一个新的 [name].
-		</p>
-
-		<h2>属性</h2>
-
-		<h3>[property:String crossOrigin]</h3>
-		<p>
-		如果设置了,在开始加载前, 将为图片分配 [link:https://developer.mozilla.org/en-US/docs/Web/HTML/CORS_settings_attributes crossOrigin]
-	 属性,其值为 *crossOrigin*,默认为"anonymous"。
-		</p>
-
-		<h3>[property:LoadingManager manager]</h3>
-		<p>
-			加载器正在使用的 [page:LoadingManager loadingManager] 。 默认为 [page:DefaultLoadingManager].
-		</p>
-
-		<h3>[property:String withCredentials]</h3>
-		<p>
-            XMLHttpRequest请求是否使用了证书。
-			默认为 *false*.
-		</p>
-
-		<h2>方法</h2>
-
-		<h3>[method:null load]( [param:String url], [param:Function onLoad], [param:Function onProgress], [param:Function onError] )</h3>
-		<p>
-		[page:String url] — 文件的URL或者路径,也可以为
-			[link:https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/Data_URIs Data URI]..<br />
-		[page:Function onLoad] — 加载完成时将调用。回调参数将是加载的响应。<br />
-		[page:Function onProgress] — 将在加载过程中进行调用。参数为XMLHttpRequest实例,
-            其中包含 [page:Integer total] 和 [page:Integer loaded] 字节。<br />
-		[page:Function onError] — 在加载错误时被调用。<br />
-		</p>
-		<p>
-		从URL中进行加载并将 <em>JSON</em> 传递给 onLoad。
-		</p>
-
-		<h3>[method:JSONLoader setCrossOrigin]( [param:String value] )</h3>
-		<p>
-			设置 [page:.crossOrigin] 的属性。
-		</p>
-
-		<h3>[method:JSONLoader setTexturePath]( [param:String texturePath] )</h3>
-		<p>
-            设置加载文件的基本路径或URL。当加载同一目录中的许多模型,此方法将很有用。
-		</p>
-
-		<h3>[method:Object3D parse]( [param:Object json], [param:String texturePath] )</h3>
-		<p>
-		[page:String json] — 需要解析的JSON对象。<br />
-		[page:String texturePath] — 纹理的基本路径。<br /><br />
-
-		解析要给 <em>JSON</em> 结构并返回 [page:object] 包含 [page:Geometry geometry] 和 [page:Array materials] 的对象.
-		</p>
-
-		<h2>源</h2>
-
-		[link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js]
-	</body>
-</html>

+ 0 - 4
docs/api/zh/loaders/ObjectLoader.html

@@ -13,15 +13,12 @@
 		<p class="desc">
 			A loader for loading a JSON resource in the [link:https://github.com/mrdoob/three.js/wiki/JSON-Object-Scene-format-4 JSON Object/Scene format].<br /><br />
 
-			Note that this loader can't load geometries of type [page:Geometry]. Use [page:JSONLoader] instead for that.<br /><br />
-
 			此加载器内部使用[page:FileLoader]进行加载文件。
 		</p>
 
 		<h2>例子</h2>
 
 		<p>
-			[example:webgl_animation_skinning_blending WebGL / animation / skinning / blending]<br />
 			[example:webgl_loader_json_claraio WebGL / loader / json / claraio]<br />
 			[example:webgl_materials_lightmap WebGL / materials / lightmap]
 		</p>
@@ -118,7 +115,6 @@
 		[page:Object json] — 必选参数,需要被解析的JSON源。<br /><br />
 
             此函数以JSON结构,用[page:.parse]去解析[page:Geometry geometries]或[page:BufferGeometry buffer geometries]。
-            在内部,它使用JSONLoader作为几何加载器,使用BufferGeometryLoader作为几何缓冲区加载器。
 		</p>
 
 		<h3>[method:Object3D parseMaterials]( [param:Object json] )</h3>

+ 48 - 57
docs/api/zh/math/Plane.html

@@ -11,162 +11,153 @@
 		<h1>平面([name])</h1>
 
 		<p class="desc">
-			A two dimensional surface that extends infinitely in 3d space, represented in [link:http://mathworld.wolfram.com/HessianNormalForm.html Hessian normal form]
-			by a unit length normal vector and a constant.
+			在三维空间中无限延伸的二维平面,平面方程用单位长度的法向量和常数表示为海塞法向量[link:http://mathworld.wolfram.com/HessianNormalForm.html Hessian normal form]形式。
 		</p>
 
 
-		<h2>Constructor</h2>
+		<h2>构造器(Constructor</h2>
 
 
 		<h3>[name]( [param:Vector3 normal], [param:Float constant] )</h3>
 		<p>
-		[page:Vector3 normal] - (optional) a unit length [page:Vector3] defining the normal of the plane. Default is *(1, 0, 0)*.<br />
-		[page:Float constant] - (optional) the signed distance from the origin to the plane. Default is *0*.
+		[page:Vector3 normal] - (可选参数) 定义单位长度的平面法向量[page:Vector3]。默认值为 *(1, 0, 0)*。<br />
+		[page:Float constant] - (可选参数) 从原点到平面的有符号距离。 默认值为 *0*.
 		</p>
 
 
-		<h2>Properties</h2>
+		<h2>属性(Properties</h2>
 
 		<h3>[property:Vector3 normal]</h3>
 
 		<h3>[property:Float constant]</h3>
 
-		<h2>Methods</h2>
+		<h2>方法(Methods</h2>
 
 		<h3>[method:Plane applyMatrix4]( [param:Matrix4 matrix], [param:Matrix3 optionalNormalMatrix] )</h3>
 		<p>
-		[page:Matrix4 matrix] - the [Page:Matrix4] to apply.<br />
-		[page:Matrix3 optionalNormalMatrix] - (optional) pre-computed normal [Page:Matrix3] of the Matrix4 being applied.<br /><br />
+		[page:Matrix4 matrix] - 要应用的四位矩阵([Page:Matrix4])。<br />
+		[page:Matrix3 optionalNormalMatrix] - (可选参数) 预先计算好的上述Matrix4参数的法线矩阵 [Page:Matrix3]。<br /><br />
 
-		Apply a Matrix4 to the plane. The matrix must be an affine, homogeneous transform.<br />
-		If supplying an [page:Matrix3 optionalNormalMatrix], it can be created like so:
+		在平面上应用矩阵。矩阵必须是仿射齐次变换。<br />
+		如果提供一个optionalNormalMatrix,可以这样创建:
 		<code>
 		var optionalNormalMatrix = new THREE.Matrix3().getNormalMatrix( matrix );
 		</code>
 		</p>
 
 		<h3>[method:Plane clone]()</h3>
-		<p>Returns a new plane with the same [page:.normal normal] and [page:.constant constant] as this one.</p>
+		<p>返回一个与当前平面有相同法线 [page:.normal normal],常量 [page:.constant constant] 距离的平面。</p>
 
 		<h3>[method:Vector3 coplanarPoint]( [param:Vector3 target] )</h3>
 		<p>
-		[page:Vector3 target] — the result will be copied into this Vector3.<br /><br />
+		[page:Vector3 target] — 结果会拷贝到该向量中。<br /><br />
 
-		Returns a [page:Vector3] coplanar to the plane, by calculating the projection of the
-		normal vector at the origin onto the plane.
+		返回一个共面点,通过原点的法向量在平面上投影算得。
 		</p>
 
 		<h3>[method:Plane copy]( [param:Plane plane] )</h3>
 		<p>
-		Copies the values of the passed plane's [page:.normal normal] and [page:.constant constant]
-		properties to this plane.
+			拷贝给定平面,将其中的法线 [page:.normal normal],距离常量 [page:.constant constant]属性拷贝给该对象。
 		</p>
 
 		<h3>[method:Float distanceToPoint]( [param:Vector3 point] )</h3>
-		<p>Returns the signed distance from the [page:Vector3 point] to the plane.</p>
+		<p>返回点[page:Vector3 point]到平面的有符号距离。</p>
 
 		<h3>[method:Float distanceToSphere]( [param:Sphere sphere] )</h3>
-		<p>Returns the signed distance from the [page:Sphere sphere] to the plane.</p>
+		<p>返回球面 [page:Sphere sphere] 的边缘到平面的最短距离。</p>
 
 		<h3>[method:Boolean equals]( [param:Plane plane] )</h3>
 		<p>
-			Checks to see if two planes are equal (their [page:.normal normal] and
-			[page:.constant constant] properties match).
+			检查两个平面是否相等。(法线 [page:.normal normal] 以及常量 [page:.constant constant] 都相同)。
 		</p>
 
 		<h3>[method:Vector3 intersectLine]( [param:Line3 line], [param:Vector3 target] )</h3>
 		<p>
-		[page:Line3 line] - the [page:Line3] to check for intersection.<br />
-		[page:Vector3 target] — the result will be copied into this Vector3.<br /><br />
+		[page:Line3 line] - 检测是否相交的三维几何线段 [page:Line3]。<br />
+		[page:Vector3 target] — 结果将会写入该向量中。<br /><br />
 
-		Returns the intersection point of the passed line and the plane. Returns undefined
-		 if the line does not intersect. Returns the line's starting point if the line is
-		 coplanar with the plane.
+		返回给定线段和平面的交点。如果不相交则返回undefined。如果线与平面共面,则返回该线段的起始点。
 		</p>
 
 		<h3>[method:Boolean intersectsBox]( [param:Box3 box] )</h3>
 		<p>
-		[page:Box3 box] - the [page:Box3] to check for intersection.<br /><br />
+		[page:Box3 box] - 检查是否相交的包围盒 [page:Box3]。<br /><br />
 
-		Determines whether or not this plane intersects [page:Box3 box].
+		确定该平面是否与给定3d包围盒[page:Box3]相交。
 		</p>
 
 		<h3>[method:Boolean intersectsLine]( [param:Line3 line] )</h3>
 		<p>
-		[page:Line3 line] - the [page:Line3] to check for intersection.<br /><br />
+		[page:Line3 line] - 检查是否相交的三维线段 [page:Line3]。<br /><br />
 
-		Tests whether a line segment intersects with (passes through) the plane.
+		测试线段是否与平面相交。
 		</p>
 
 		<h3>[method:Boolean intersectsSphere]( [param:Sphere sphere] )</h3>
 		<p>
-		[page:Sphere sphere]  - the [page:Sphere] to check for intersection.<br /><br />
+		[page:Sphere sphere]  - 检查是否相交的球体 [page:Sphere]。<br /><br />
 
-		Determines whether or not this plane intersects [page:Sphere sphere].
+		确定该平面是否与给定球体 [page:Sphere] 相交。
 		</p>
 
 		<h3>[method:Plane negate]()</h3>
 		<p>
-		Negates both the normal vector and the constant.
+			将法向量与常量求反(乘以-1)。
 		</p>
 
 		<h3>[method:Plane normalize]()</h3>
 		<p>
-			Normalizes the [page:.normal normal] vector, and adjusts the [page:.constant constant]
-			value accordingly.
+			归一化法向量 [page:.normal normal] ,并相应的调整常量 [page:.constant constant]数值。
 		</p>
 
 		<h3>[method:Vector3 projectPoint]( [param:Vector3 point], [param:Vector3 target] )</h3>
 		<p>
-		[page:Vector3 point] - the [page:Vector3] to project onto the plane.<br />
-		[page:Vector3 target] — the result will be copied into this Vector3.<br /><br />
+		[page:Vector3 point] - 需要投射到该平面的点。<br />
+		[page:Vector3 target] — 在该平面上离投射点最近的点。<br /><br />
 
-		Projects a [page:Vector3 point] onto the plane.
+		将一个点[page:Vector3 point]投射到该平面上。
 		</p>
 
 		<h3>[method:Plane set]( [param:Vector3 normal], [param:Float constant] )</h3>
 		<p>
-			[page:Vector3 normal] - a unit length [page:Vector3] defining the normal of the plane.<br />
-			[page:Float constant] - the signed distance from the origin to the plane. Default is *0*.<br /><br />
+			[page:Vector3 normal] - 单位长度的向量表示平面的法向量。<br />
+			[page:Float constant] - 原点到平面有符号距离。默认值为 *0*。<br /><br />
 
-			 Sets the plane's [page:.normal normal] and [page:.constant constant] properties.
+			设置平面 [page:.normal normal] 的法线和常量 [page:.constant constant] 属性值。
 		</p>
 
 		<h3>[method:Plane setComponents]( [param:Float x], [param:Float y], [param:Float z], [param:Float w] )</h3>
 		<p>
-		[page:Float x] - x value of the unit length normal vector.<br />
-		[page:Float y] - y value of the unit length normal vector.<br />
-		[page:Float z] - z value of the unit length normal vector.<br />
-		[page:Float w] - the value of the plane's [page:.constant constant] property.<br /><br />
+		[page:Float x] - 单位长度法向量的x值。<br />
+		[page:Float y] - 单位长度法向量的y值。<br />
+		[page:Float z] - 单位长度法向量的z值。<br />
+		[page:Float w] - 原点沿法向量到平面常量 [page:.constant constant] 距离。<br /><br />
 
-		Set the individual components that define the plane.
+		设置定义平面的各个变量。
 		</p>
 
 		<h3>[method:Plane setFromCoplanarPoints]( [param:Vector3 a], [param:Vector3 b], [param:Vector3 c] )</h3>
 		<p>
-		 [page:Vector3 a] - first point on the plane.<br />
-		 [page:Vector3 b] - second point on the plane.<br />
-		 [page:Vector3 c] - third point on the plane.<br /><br />
+		 [page:Vector3 a] - 用于确定平面的第一个点。<br />
+		 [page:Vector3 b] - 用于确定平面的第二个点。<br />
+		 [page:Vector3 c] - 用于确定平面的第三个点。<br /><br />
 
-		Defines the plane based on the 3 provided points. The winding order is assumed to be counter-clockwise,
-		and determines the direction of the [page:.normal normal].
+		 根据给定的三个点确定平面。如果三个点共线将会抛出错误。通过右手螺旋规则确定(向量叉乘)法向量 [page:.normal normal]。
 		</p>
 
 		<h3>[method:Plane setFromNormalAndCoplanarPoint]( [param:Vector3 normal], [param:Vector3 point] ) [param:Vector3 this]</h3>
 		<p>
-		[page:Vector3 normal] - a unit length [page:Vector3] defining the normal of the plane.<br />
-		[page:Vector3 point] - [page:Vector3]<br /><br />
+		[page:Vector3 normal] - 平面单位法向量<br />
+		[page:Vector3 point] - 平面上的点<br /><br />
 
-		Sets the plane's properties as defined by a [page:Vector3 normal] and an arbitrary coplanar [page:Vector3 point].
+		通过平面上的一点以及法线确定原点到平面的最短距离(常量)。
 		</p>
 
 		<h3>[method:Plane translate]( [param:Vector3 offset] )</h3>
 		<p>
-		[page:Vector3 offset] - the amount to move the plane by.<br /><br />
+		[page:Vector3 offset] - 平移量<br /><br />
 
-		Translates the plane by the distance defined by the [page:Vector3 offset] vector.
-		Note that this only affects the plane constant and will not affect the normal vector.
+		将平面平移给定向量大小,注意:这只会影响平面的常量不会影响平面的法向量。
 		</p>
 
 		<h2>Source</h2>

+ 0 - 5
docs/api/zh/objects/SkinnedMesh.html

@@ -144,11 +144,6 @@
 		更新[page:Matrix4 MatrixWorld]矩阵。
 		</p>
 
-		<h3>[method:null initBones]()</h3>
-		<p>
-		从内部几何体中创建一个分层[page:Bone bones]对象的数组。
-		</p>
-
 		<h2>源代码</h2>
 		[link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js]
 	</body>

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

@@ -31,7 +31,7 @@
 			<li>KHR_draco_mesh_compression</li>
 			<li>KHR_materials_pbrSpecularGlossiness</li>
 			<li>KHR_materials_unlit</li>
-			<li>KHR_lights_punctual (experimental)</li>
+			<li>KHR_lights_punctual</li>
 			<li>KHR_texture_transform<sup>*</sup></li>
 			<li>MSFT_texture_dds</li>
 		</ul>

+ 23 - 0
docs/examples/loaders/MMDLoader.html

@@ -110,6 +110,29 @@
 		[page:String crossOrigin] — The crossOrigin string to implement CORS for loading the url from a different domain that allows CORS.
 		</p>
 
+		<h3>[method:MMDLoader setAnimationPath]( [param:String animationPath] )</h3>
+		<p>
+		[page:String animationPath] — Base path for loading animation data (VMD/VPD files).
+		</p>
+		<p>
+		Set the base path for additional resources like textures.
+		</p>
+
+		<h3>[method:MMDLoader setPath]( [param:String path] )</h3>
+		<p>
+		[page:String path] — Base path.
+		</p>
+		<p>
+		Sets the base path or URL from which to load files.
+		</p>
+
+		<h3>[method:MMDLoader setResourcePath]( [param:String resourcePath] )</h3>
+		<p>
+		[page:String resourcePath] — Base path for loading additional resources e.g. textures.
+		</p>
+		<p>
+		Set the base path for additional resources like textures.
+		</p>
 
 		<h2>Source</h2>
 

+ 0 - 2
docs/list.js

@@ -234,7 +234,6 @@ var list = {
 				"FontLoader": "api/en/loaders/FontLoader",
 				"ImageBitmapLoader": "api/en/loaders/ImageBitmapLoader",
 				"ImageLoader": "api/en/loaders/ImageLoader",
-				"JSONLoader": "api/en/loaders/JSONLoader",
 				"Loader": "api/en/loaders/Loader",
 				"LoaderUtils": "api/en/loaders/LoaderUtils",
 				"MaterialLoader": "api/en/loaders/MaterialLoader",
@@ -659,7 +658,6 @@ var list = {
 				"FontLoader": "api/zh/loaders/FontLoader",
 				"ImageBitmapLoader": "api/zh/loaders/ImageBitmapLoader",
 				"ImageLoader": "api/zh/loaders/ImageLoader",
-				"JSONLoader": "api/zh/loaders/JSONLoader",
 				"Loader": "api/zh/loaders/Loader",
 				"LoaderUtils": "api/zh/loaders/LoaderUtils",
 				"MaterialLoader": "api/zh/loaders/MaterialLoader",

+ 0 - 1
docs/manual/en/introduction/Animation-system.html

@@ -107,7 +107,6 @@
 		</p>
 
 			<ul>
-				<li>[page:JSONLoader THREE.JSONLoader]</li>
 				<li>[page:ObjectLoader THREE.ObjectLoader]</li>
 				<li>THREE.BVHLoader</li>
 				<li>THREE.ColladaLoader</li>

+ 0 - 58
docs/manual/en/introduction/How-to-run-things-locally.html

@@ -122,64 +122,6 @@ ruby -r webrick -e "s = WEBrick::HTTPServer.new(:Port => 8000, :DocumentRoot =>
 				</ol>
 			</div>
 
-		<h2>Change local files security policy</h2>
-		<div>
-			<h3>Safari</h3>
-			<div>
-				<p>
-					Enable the develop menu using the preferences panel, under Advanced -&gt; "Show develop menu
-					in menu bar".
-				</p>
-
-				<p>
-					Then from the safari "Develop" menu, select "Disable local file restrictions", it is also
-					worth noting safari has some odd behaviour with caches, so it is advisable to use the
-					"Disable caches" option in the same menu; if you are editing &amp; debugging using safari.
-				</p>
-			</div>
-
-
-			<h3>Chrome</h3>
-			<div>
-				<p>Close all running Chrome instances first. The important word here is 'all'.</p>
-
-				<p>
-					On Windows, you may check for Chrome instances using the Windows Task Manager.
-					Alternatively, if you see a Chrome icon in the system tray, then you may open its context
-					menu and click 'Exit'. This should close all Chrome instances.
-				</p>
-
-				<p>Then start the Chrome executable with a command line flag:</p>
-
-				<code>chrome --allow-file-access-from-files</code>
-
-				<p>
-					On Windows, the easiest is probably to create a special shortcut icon which has
-					added the flag given above (right-click on shortcut -&gt; properties -&gt; target).
-				</p>
-
-				<p>On Mac OSX, you can do this with</p>
-
-				<code>open /Applications/Google\ Chrome.app --args --allow-file-access-from-files</code>
-			</div>
-
-			<h3>Firefox</h3>
-			<div>
-				<ol>
-				<li>
-					In the address bar, type <code>about:config</code>
-				</li>
-				<li>
-					Find the <code>security.fileuri.strict_origin_policy</code> parameter
-				</li>
-				<li>
-					Set it to <em>false</em>
-				</li>
-				</ol>
-			</div>
-
-		</div>
-
 			<p>
 				Other simple alternatives are [link:http://stackoverflow.com/q/12905426/24874 discussed here]
 				on Stack Overflow.

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

@@ -79,7 +79,7 @@
 	<h2>Loading</h2>
 
 	<p>
-		Only a few loaders ([page:ObjectLoader] and [page:JSONLoader]) are included by default with
+		Only a few loaders (e.g. [page:ObjectLoader]) are included by default with
 		three.js — others should be added to your page individually. Depending on your
 		preference and comfort with build tools, choose one of the following:
 	</p>

+ 2 - 3
docs/manual/zh/introduction/Animation-system.html

@@ -32,7 +32,7 @@
 			<br /><br />
 			每个* AnimationClip *通常保存对象的某个活动的数据。 如果
 			mesh是一个字符,例如,可以有一个用于walkcycle的动画片段,第二个
-			跳跃,三分之一的回避等等。		
+			跳跃,三分之一的回避等等。
 		</p>
 
 		<h3>Keyframe Tracks(关键帧轨道)</h3>
@@ -83,11 +83,10 @@
 		<p class="desc">
 			请注意,并非所有模型格式都包含动画(尤其是OBJ,没有),而且只有一些
 			three.js加载器支持[page:AnimationClip AnimationClip]序列。 以下几个<i>确实</ i>
-			支持此动画类型:		
+			支持此动画类型:
 		</p>
 
 			<ul>
-				<li>[page:JSONLoader THREE.JSONLoader]</li>
 				<li>[page:ObjectLoader THREE.ObjectLoader]</li>
 				<li>THREE.BVHLoader</li>
 				<li>THREE.ColladaLoader</li>

+ 4 - 6
editor/index.html

@@ -4,12 +4,10 @@
 		<title>three.js / editor</title>
 		<meta charset="utf-8">
 		<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
-		<!-- Origin Trial Token, feature = WebVR (For Chrome M62+), origin = https://threejs.org, expires = 2018-09-11 -->
-		<meta http-equiv="origin-trial" data-feature="WebVR (For Chrome M62+)" data-expires="2018-09-11" content="AqhFUYKxq/d+E8CDT0fuYRCg8TvlTP52x0Jv7I9t27sLhR30LmcahBRfSwzP89ukjs2+ia99VrrLoRyaFAwJVA0AAABQeyJvcmlnaW4iOiJodHRwczovL3RocmVlanMub3JnOjQ0MyIsImZlYXR1cmUiOiJXZWJWUjEuMU02MiIsImV4cGlyeSI6MTUzNjYyNDAwMH0=">
-		<!-- Origin Trial Token, feature = WebXR Device API (For Chrome M69+), origin = https://threejs.org, expires = 2018-12-02 -->
-		<meta http-equiv="origin-trial" data-feature="WebXR Device API (For Chrome M69+)" data-expires="2018-12-02" content="Ah46myef4Ax/+fcLtkeotXmIqnvun4lg4bYbHVttuJvbsWiE4oacrvroId7hbCEb4/byxFHIO6+uwq4pwr6RfQkAAABTeyJvcmlnaW4iOiJodHRwczovL3RocmVlanMub3JnOjQ0MyIsImZlYXR1cmUiOiJXZWJYUkRldmljZU02OSIsImV4cGlyeSI6MTU0Mzc1ODIyNn0=">
-		<!-- Origin Trial Token, feature = WebXR Gamepad Support, origin = https://threejs.org, expires = 2018-12-02 -->
-		<meta http-equiv="origin-trial" data-feature="WebXR Gamepad Support" data-expires="2018-12-02" content="AqI9LIanbGxr/HoTOsYCUNxG82Vy94NZbjhv83R+bF+5NX2jiZOaf7ny+mFoTUP5wrWpYlPjQ6+HeVas9f1lRwYAAABYeyJvcmlnaW4iOiJodHRwczovL3RocmVlanMub3JnOjQ0MyIsImZlYXR1cmUiOiJXZWJYUkdhbWVwYWRTdXBwb3J0IiwiZXhwaXJ5IjoxNTQzNzU4MjI2fQ==">
+		<!-- Origin Trial Token, feature = WebXR Device API (For Chrome M69+), origin = https://threejs.org, expires = 2019-01-07 -->
+		<meta http-equiv="origin-trial" data-feature="WebXR Device API (For Chrome M69+)" data-expires="2019-01-07" content="ArPzyYNrUDiXsGOh647Ya7MtVUA1nM+WFMnPWu7eoF2nQHOP6mTATIbiv0w+k2kFaPofZG/04ZEQdsACq4IA0wQAAABTeyJvcmlnaW4iOiJodHRwczovL3RocmVlanMub3JnOjQ0MyIsImZlYXR1cmUiOiJXZWJYUkRldmljZU02OSIsImV4cGlyeSI6MTU0Njg4MzAxOH0=">
+		<!-- Origin Trial Token, feature = WebXR Gamepad Support, origin = https://threejs.org, expires = 2019-01-07 -->
+		<meta http-equiv="origin-trial" data-feature="WebXR Gamepad Support" data-expires="2019-01-07" content="Av16a8LVXasKVQV9j3u0OlXdTfz5O9qDqhROyL5Up6R3sdOPbtFuc6n6o5DHitwnb5VdirH0GyvROwvz8xxd0AkAAABYeyJvcmlnaW4iOiJodHRwczovL3RocmVlanMub3JnOjQ0MyIsImZlYXR1cmUiOiJXZWJYUkdhbWVwYWRTdXBwb3J0IiwiZXhwaXJ5IjoxNTQ2ODgzMDE4fQ==">
 	</head>
 	<body ontouchstart="">
 		<link href="css/main.css" rel="stylesheet" />

+ 1 - 44
editor/js/Loader.js

@@ -576,50 +576,7 @@ var Loader = function ( editor ) {
 
 			case 'geometry':
 
-				var loader = new THREE.JSONLoader();
-				loader.setResourcePath( scope.texturePath );
-
-				var result = loader.parse( data );
-
-				var geometry = result.geometry;
-				var material;
-
-				if ( result.materials !== undefined ) {
-
-					if ( result.materials.length > 1 ) {
-
-						material = new THREE.MultiMaterial( result.materials );
-
-					} else {
-
-						material = result.materials[ 0 ];
-
-					}
-
-				} else {
-
-					material = new THREE.MeshStandardMaterial();
-
-				}
-
-				geometry.sourceType = "ascii";
-				geometry.sourceFile = file.name;
-
-				var mesh;
-
-				if ( geometry.animation && geometry.animation.hierarchy ) {
-
-					mesh = new THREE.SkinnedMesh( geometry, material );
-
-				} else {
-
-					mesh = new THREE.Mesh( geometry, material );
-
-				}
-
-				mesh.name = filename;
-
-				editor.execute( new AddObjectCommand( mesh ) );
+				console.error( 'Loader: "Geometry" is no longer supported.' );
 
 				break;
 

+ 1 - 49
editor/js/libs/tern-threejs/threejs.js

@@ -1714,54 +1714,6 @@
       "!doc": "A loader for loading an [page:Image].",
       "!type": "fn(manager: +THREE.LoadingManager)"
     },
-    "JSONLoader": {
-      "!url": "http://threejs.org/docs/#Reference/loaders/JSONLoader",
-      "prototype": {
-        "!proto": "THREE.Loader.prototype",
-        "withCredentials": {
-          "!type": "boolean",
-          "!doc": "If true, the ajax request will use cookies."
-        },
-        "onLoadStart": {
-          "!type": "function",
-          "!doc": "The default is a function with empty body."
-        },
-        "onLoadComplete": {
-          "!type": "function",
-          "!doc": "The default is a function with empty body."
-        },
-        "load": {
-          "!type": "fn(url: string, callback: function, texturePath: string)",
-          "!doc": "[page:String url] — required<br>\n\t\t[page:Function callback] — required. Will be called when load completes. The arguments will be the loaded [page:Object3D] and the loaded [page:Array materials].<br>\n\t\t[page:String texturePath] — optional. If not specified, textures will be assumed to be in the same folder as the Javascript model file."
-        },
-        "loadAjaxJSON": {
-          "!type": "fn(context: +THREE.JSONLoader, url: string, callback: function, texturePath: string, callbackProgress: function)",
-          "!doc": "Begin loading from url and call <em>callback</em> with the parsed response content."
-        },
-        "parse": {
-          "!type": "fn(json: object, texturePath: string) -> +THREE.Object3D",
-          "!doc": "Parse a <em>JSON</em> structure and return an [page:Object] containing the parsed .[page:Geometry] and .[page:Array materials]."
-        },
-        "updateProgress": {
-          "!type": "fn(progress: object)",
-          "!doc": "Updates the DOM object with the progress made."
-        },
-        "createMaterial": {
-          "!type": "fn(m: object, texturePath: string) -> +THREE.Material",
-          "!doc": "Creates the Material based on the parameters m."
-        },
-        "initMaterials": {
-          "!type": "fn(materials: [], texturePath: string) -> []",
-          "!doc": "Creates an array of [page:Material] based on the array of parameters m. The index of the parameters decide the correct index of the materials."
-        },
-        "extractUrlBase": {
-          "!type": "fn(url: string) -> string",
-          "!doc": "Extract the base from the URL."
-        }
-      },
-      "!doc": "A loader for loading objects in JSON format.",
-      "!type": "fn()"
-    },
     "Loader": {
       "!url": "http://threejs.org/docs/#Reference/loaders/Loader",
       "prototype": {
@@ -1904,7 +1856,7 @@
           "!doc": "[page:String value] — The crossOrigin string to implement CORS for loading the url from a different domain that allows CORS."
         }
       },
-      "!doc": "A loader for loading a JSON resource. Unlike the [page:JSONLoader], this one make use of the <em>.type</em> attributes of objects to map them to their original classes.",
+      "!doc": "A loader for loading a JSON resource.",
       "!type": "fn(manager: +THREE.LoadingManager)"
     },
     "PDBLoader": {

+ 0 - 1
examples/files.js

@@ -90,7 +90,6 @@ var files = {
 		"webgl_loader_gltf",
 		"webgl_loader_gltf_extensions",
 		"webgl_loader_imagebitmap",
-		"webgl_loader_json",
 		"webgl_loader_json_claraio",
 		"webgl_loader_kmz",
 		"webgl_loader_md2",

+ 3 - 1
examples/js/loaders/AssimpLoader.js

@@ -772,8 +772,10 @@ THREE.AssimpLoader.prototype = {
 				if ( this.mBones.length == 0 )
 					mesh = new THREE.Mesh( geometry, mat );
 
-				if ( this.mBones.length > 0 )
+				if ( this.mBones.length > 0 ) {
 					mesh = new THREE.SkinnedMesh( geometry, mat );
+					mesh.normalizeSkinWeights();
+				}
 
 				this.threeNode = mesh;
 				//mesh.matrixAutoUpdate = false;

+ 183 - 69
examples/js/loaders/EquirectangularToCubeGenerator.js

@@ -1,97 +1,217 @@
 /**
 * @author Richard M. / https://github.com/richardmonette
+* @author WestLangley / http://github.com/WestLangley
 */
 
-THREE.EquirectangularToCubeGenerator = function ( sourceTexture, options ) {
+THREE.CubemapGenerator = function ( renderer ) {
 
-	this.sourceTexture = sourceTexture;
-	this.resolution = options.resolution || 512;
+	this.renderer = renderer;
 
- 	this.views = [
-		{ t: [ 1, 0, 0 ], u: [ 0, - 1, 0 ] },
-		{ t: [ - 1, 0, 0 ], u: [ 0, - 1, 0 ] },
-		{ t: [ 0, 1, 0 ], u: [ 0, 0, 1 ] },
-		{ t: [ 0, - 1, 0 ], u: [ 0, 0, - 1 ] },
-		{ t: [ 0, 0, 1 ], u: [ 0, - 1, 0 ] },
-		{ t: [ 0, 0, - 1 ], u: [ 0, - 1, 0 ] },
-	];
+};
+
+THREE.CubemapGenerator.prototype.fromEquirectangular = function ( texture, options ) {
+
+	var scene = new THREE.Scene();
+
+	var shader = {
+
+		uniforms: {
+			tEquirect: { value: null },
+		},
+
+		vertexShader:
+
+			`
+			varying vec3 vWorldDirection;
+
+			//include <common>
+			vec3 transformDirection( in vec3 dir, in mat4 matrix ) {
+
+				return normalize( ( matrix * vec4( dir, 0.0 ) ).xyz );
+
+			}
+
+			void main() {
+
+				vWorldDirection = transformDirection( position, modelMatrix );
+
+				#include <begin_vertex>
+				#include <project_vertex>
+
+			}
+			`,
+
+		fragmentShader:
+
+			`
+			uniform sampler2D tEquirect;
+
+			varying vec3 vWorldDirection;
+
+			//include <common>
+			#define RECIPROCAL_PI 0.31830988618
+			#define RECIPROCAL_PI2 0.15915494
+
+			void main() {
+
+				vec3 direction = normalize( vWorldDirection );
+
+				vec2 sampleUV;
+
+				sampleUV.y = asin( clamp( direction.y, - 1.0, 1.0 ) ) * RECIPROCAL_PI + 0.5;
+
+				sampleUV.x = atan( direction.z, direction.x ) * RECIPROCAL_PI2 + 0.5;
+
+				gl_FragColor = texture2D( tEquirect, sampleUV );
+
+			}
+			`
+	};
+
+	var material = new THREE.ShaderMaterial( {
+
+		type: 'CubemapFromEquirect',
+
+		uniforms: THREE.UniformsUtils.clone( shader.uniforms ),
+		vertexShader: shader.vertexShader,
+		fragmentShader: shader.fragmentShader,
+		side: THREE.BackSide,
+		blending: THREE.NoBlending
+
+	} );
 
-	this.camera = new THREE.PerspectiveCamera( 90, 1, 0.1, 10 );
-	this.boxMesh = new THREE.Mesh( new THREE.BoxBufferGeometry( 1, 1, 1 ), this.getShader() );
-	this.boxMesh.material.side = THREE.BackSide;
-	this.scene = new THREE.Scene();
-	this.scene.add( this.boxMesh );
+	material.uniforms.tEquirect.value = texture;
+
+	var mesh = new THREE.Mesh( new THREE.BoxBufferGeometry( 5, 5, 5 ), material );
+
+	scene.add( mesh );
+
+	var resolution = options.resolution || 512;
 
 	var params = {
-		format: options.format || this.sourceTexture.format,
-		magFilter: this.sourceTexture.magFilter,
-		minFilter: this.sourceTexture.minFilter,
-		type: options.type || this.sourceTexture.type,
-		generateMipmaps: this.sourceTexture.generateMipmaps,
-		anisotropy: this.sourceTexture.anisotropy,
-		encoding: this.sourceTexture.encoding
+		type: texture.type,
+		format: texture.format,
+		encoding: texture.encoding,
+		generateMipmaps: ( options.generateMipmaps !== undefined ) ?  options.generateMipmaps : texture.generateMipmaps,
+		minFilter: ( options.minFilter !== undefined ) ?  options.minFilter : texture.minFilter,
+		magFilter: ( options.magFilter !== undefined ) ?  options.magFilter : texture.magFilter
 	};
 
-	this.renderTarget = new THREE.WebGLRenderTargetCube( this.resolution, this.resolution, params );
+	var camera = new THREE.CubeCamera( 1, 10, resolution, params );
+
+	camera.update( this.renderer, scene );
+
+	mesh.geometry.dispose();
+	mesh.material.dispose();
+
+	return camera.renderTarget;
 
 };
 
-THREE.EquirectangularToCubeGenerator.prototype = {
+//
 
-	constructor: THREE.EquirectangularToCubeGenerator,
+THREE.EquirectangularToCubeGenerator = ( function () {
 
-	update: function ( renderer ) {
+	var camera = new THREE.PerspectiveCamera( 90, 1, 0.1, 10 );
+	var scene = new THREE.Scene();
+	var boxMesh = new THREE.Mesh( new THREE.BoxBufferGeometry( 1, 1, 1 ), getShader() );
+	boxMesh.material.side = THREE.BackSide;
+	scene.add( boxMesh );
 
-		for ( var i = 0; i < 6; i ++ ) {
+	var EquirectangularToCubeGenerator = function ( sourceTexture, options ) {
 
-			this.renderTarget.activeCubeFace = i;
+		this.sourceTexture = sourceTexture;
+		this.resolution = options.resolution || 512;
 
-			var v = this.views[ i ];
+		this.views = [
+			{ t: [ 1, 0, 0 ], u: [ 0, - 1, 0 ] },
+			{ t: [ - 1, 0, 0 ], u: [ 0, - 1, 0 ] },
+			{ t: [ 0, 1, 0 ], u: [ 0, 0, 1 ] },
+			{ t: [ 0, - 1, 0 ], u: [ 0, 0, - 1 ] },
+			{ t: [ 0, 0, 1 ], u: [ 0, - 1, 0 ] },
+			{ t: [ 0, 0, - 1 ], u: [ 0, - 1, 0 ] },
+		];
 
-			this.camera.position.set( 0, 0, 0 );
-			this.camera.up.set( v.u[ 0 ], v.u[ 1 ], v.u[ 2 ] );
-			this.camera.lookAt( v.t[ 0 ], v.t[ 1 ], v.t[ 2 ] );
+		var params = {
+			format: options.format || this.sourceTexture.format,
+			magFilter: this.sourceTexture.magFilter,
+			minFilter: this.sourceTexture.minFilter,
+			type: options.type || this.sourceTexture.type,
+			generateMipmaps: this.sourceTexture.generateMipmaps,
+			anisotropy: this.sourceTexture.anisotropy,
+			encoding: this.sourceTexture.encoding
+		};
 
-			renderer.render( this.scene, this.camera, this.renderTarget, true );
+		this.renderTarget = new THREE.WebGLRenderTargetCube( this.resolution, this.resolution, params );
 
-		}
+	};
+
+	EquirectangularToCubeGenerator.prototype = {
+
+		constructor: EquirectangularToCubeGenerator,
+
+		update: function ( renderer ) {
+
+			boxMesh.material.uniforms.equirectangularMap.value = this.sourceTexture;
+
+			for ( var i = 0; i < 6; i ++ ) {
+
+				this.renderTarget.activeCubeFace = i;
+
+				var v = this.views[ i ];
 
-		return this.renderTarget.texture;
+				camera.position.set( 0, 0, 0 );
+				camera.up.set( v.u[ 0 ], v.u[ 1 ], v.u[ 2 ] );
+				camera.lookAt( v.t[ 0 ], v.t[ 1 ], v.t[ 2 ] );
 
-	},
+				renderer.render( scene, camera, this.renderTarget, true );
 
-	getShader: function () {
+			}
+
+			return this.renderTarget.texture;
+
+		},
+
+		dispose: function () {
+
+			this.renderTarget.dispose();
+
+		}
+
+	};
+
+	function getShader() {
 
 		var shaderMaterial = new THREE.ShaderMaterial( {
 
 			uniforms: {
-				"equirectangularMap": { value: this.sourceTexture },
+				"equirectangularMap": { value: null },
 			},
 
 			vertexShader:
-				"varying vec3 localPosition;\n\
-				\n\
-				void main() {\n\
-					localPosition = position;\n\
-					gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );\n\
-				}",
+        "varying vec3 localPosition;\n\
+        \n\
+        void main() {\n\
+          localPosition = position;\n\
+          gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );\n\
+        }",
 
 			fragmentShader:
-				"#include <common>\n\
-				varying vec3 localPosition;\n\
-				uniform sampler2D equirectangularMap;\n\
-				\n\
-				vec2 EquirectangularSampleUV(vec3 v) {\n\
-			    vec2 uv = vec2(atan(v.z, v.x), asin(v.y));\n\
-			    uv *= vec2(0.1591, 0.3183); // inverse atan\n\
-			    uv += 0.5;\n\
-			    return uv;\n\
-				}\n\
-				\n\
-				void main() {\n\
-					vec2 uv = EquirectangularSampleUV(normalize(localPosition));\n\
-					gl_FragColor = texture2D(equirectangularMap, uv);\n\
-				}",
+        "#include <common>\n\
+        varying vec3 localPosition;\n\
+        uniform sampler2D equirectangularMap;\n\
+        \n\
+        vec2 EquirectangularSampleUV(vec3 v) {\n\
+          vec2 uv = vec2(atan(v.z, v.x), asin(v.y));\n\
+          uv *= vec2(0.1591, 0.3183); // inverse atan\n\
+          uv += 0.5;\n\
+          return uv;\n\
+        }\n\
+        \n\
+        void main() {\n\
+          vec2 uv = EquirectangularSampleUV(normalize(localPosition));\n\
+          gl_FragColor = texture2D(equirectangularMap, uv);\n\
+        }",
 
 			blending: THREE.NoBlending
 
@@ -101,14 +221,8 @@ THREE.EquirectangularToCubeGenerator.prototype = {
 
 		return shaderMaterial;
 
-	},
-
-	dispose: function () {
-
-		this.boxMesh.geometry.dispose();
-		this.boxMesh.material.dispose();
-		this.renderTarget.dispose();
-
 	}
 
-};
+	return EquirectangularToCubeGenerator;
+
+} )();

+ 11 - 9
examples/js/loaders/GLTFLoader.js

@@ -1061,7 +1061,7 @@ THREE.GLTFLoader = ( function () {
 		var s3 = ppp - pp;
 		var s0 = 1 - s2;
 		var s1 = s3 - pp + p;
-		
+
 		// Layout of keyframe output values for CUBICSPLINE animations:
 		//   [ inTangent_1, splineVertex_1, outTangent_1, inTangent_2, splineVertex_2, ... ]
 		for ( var i = 0; i !== stride; i ++ ) {
@@ -2705,6 +2705,8 @@ THREE.GLTFLoader = ( function () {
 							? new THREE.SkinnedMesh( geometry, material )
 							: new THREE.Mesh( geometry, material );
 
+						if ( mesh.isSkinnedMesh === true ) mesh.normalizeSkinWeights(); // #15319
+
 						if ( primitive.mode === WEBGL_CONSTANTS.TRIANGLE_STRIP ) {
 
 							mesh.drawMode = THREE.TriangleStripDrawMode;
@@ -3127,16 +3129,16 @@ THREE.GLTFLoader = ( function () {
 
 		var nodeDef = json.nodes[ nodeIndex ];
 
-		return new Promise( function ( resolve ) {
+		return ( function() {
 
 			// .isBone isn't in glTF spec. See .markDefs
 			if ( nodeDef.isBone === true ) {
 
-				resolve( new THREE.Bone() );
+				return Promise.resolve( new THREE.Bone() );
 
 			} else if ( nodeDef.mesh !== undefined ) {
 
-				parser.getDependency( 'mesh', nodeDef.mesh ).then( function ( mesh ) {
+				return parser.getDependency( 'mesh', nodeDef.mesh ).then( function ( mesh ) {
 
 					var node;
 
@@ -3163,27 +3165,27 @@ THREE.GLTFLoader = ( function () {
 
 					}
 
-					resolve( node );
+					return node;
 
 				} );
 
 			} else if ( nodeDef.camera !== undefined ) {
 
-				parser.getDependency( 'camera', nodeDef.camera ).then( resolve );
+				return parser.getDependency( 'camera', nodeDef.camera );
 
 			} else if ( nodeDef.extensions
 				&& nodeDef.extensions[ EXTENSIONS.KHR_LIGHTS_PUNCTUAL ]
 				&& nodeDef.extensions[ EXTENSIONS.KHR_LIGHTS_PUNCTUAL ].light !== undefined ) {
 
-				parser.getDependency( 'light', nodeDef.extensions[ EXTENSIONS.KHR_LIGHTS_PUNCTUAL ].light ).then( resolve );
+				return parser.getDependency( 'light', nodeDef.extensions[ EXTENSIONS.KHR_LIGHTS_PUNCTUAL ].light );
 
 			} else {
 
-				resolve( new THREE.Object3D() );
+				return Promise.resolve( new THREE.Object3D() );
 
 			}
 
-		} ).then( function ( node ) {
+		}() ).then( function ( node ) {
 
 			if ( nodeDef.name !== undefined ) {
 

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

@@ -102,7 +102,7 @@ THREE.HDRCubeTextureLoader.prototype.load = function ( type, urls, onLoad, onPro
 	texture.generateMipmaps = ( texture.encoding !== THREE.RGBEEncoding );
 	texture.anisotropy = 0;
 
-	var scope = this.hdrLoader;
+	var scope = this;
 
 	var loaded = 0;
 
@@ -115,7 +115,7 @@ THREE.HDRCubeTextureLoader.prototype.load = function ( type, urls, onLoad, onPro
 
 			loaded ++;
 
-			var texData = scope._parser( buffer );
+			var texData = scope.hdrLoader._parser( buffer );
 
 			if ( ! texData ) return;
 

+ 132 - 11
examples/js/loaders/MMDLoader.js

@@ -53,7 +53,7 @@ THREE.MMDLoader = ( function () {
 		crossOrigin: 'anonymous',
 
 		/**
-		 * @param {string} value
+		 * @param {string} crossOrigin
 		 * @return {THREE.MMDLoader}
 		 */
 		setCrossOrigin: function ( crossOrigin ) {
@@ -63,6 +63,39 @@ THREE.MMDLoader = ( function () {
 
 		},
 
+		/**
+		 * @param {string} animationPath
+		 * @return {THREE.MMDLoader}
+		 */
+		setAnimationPath: function ( animationPath ) {
+
+			this.animationPath = animationPath;
+			return this;
+
+		},
+
+		/**
+		 * @param {string} path
+		 * @return {THREE.MMDLoader}
+		 */
+		setPath: function ( path ) {
+
+			this.path = path;
+			return this;
+
+		},
+
+		/**
+		 * @param {string} resourcePath
+		 * @return {THREE.MMDLoader}
+		 */
+		setResoucePath: function ( resourcePath ) {
+
+			this.resourcePath = resourcePath;
+			return this;
+
+		},
+
 		// Load MMD assets as Three.js Object
 
 		/**
@@ -77,7 +110,24 @@ THREE.MMDLoader = ( function () {
 
 			var builder = this.meshBuilder.setCrossOrigin( this.crossOrigin );
 
-			var texturePath = THREE.LoaderUtils.extractUrlBase( url );
+			// resource path
+
+			var resourcePath;
+
+			if ( this.resourcePath !== undefined ) {
+
+				resourcePath = this.resourcePath;
+
+			} else if ( this.path !== undefined ) {
+
+				resourcePath = this.path;
+
+			} else {
+
+				resourcePath = THREE.LoaderUtils.extractUrlBase( url );
+
+			}
+
 			var modelExtension = this._extractExtension( url ).toLowerCase();
 
 			// Should I detect by seeing header?
@@ -91,7 +141,7 @@ THREE.MMDLoader = ( function () {
 
 			this[ modelExtension === 'pmd' ? 'loadPMD' : 'loadPMX' ]( url, function ( data ) {
 
-				onLoad(	builder.build( data, texturePath, onProgress, onError )	);
+				onLoad(	builder.build( data, resourcePath, onProgress, onError )	);
 
 			}, onProgress, onError );
 
@@ -167,6 +217,7 @@ THREE.MMDLoader = ( function () {
 
 			this.loader
 				.setMimeType( undefined )
+				.setPath( this.path )
 				.setResponseType( 'arraybuffer' )
 				.load( url, function ( buffer ) {
 
@@ -190,6 +241,7 @@ THREE.MMDLoader = ( function () {
 
 			this.loader
 				.setMimeType( undefined )
+				.setPath( this.path )
 				.setResponseType( 'arraybuffer' )
 				.load( url, function ( buffer ) {
 
@@ -219,6 +271,7 @@ THREE.MMDLoader = ( function () {
 
 			this.loader
 				.setMimeType( undefined )
+				.setPath( this.animationPath )
 				.setResponseType( 'arraybuffer' );
 
 			for ( var i = 0, il = urls.length; i < il; i ++ ) {
@@ -250,6 +303,7 @@ THREE.MMDLoader = ( function () {
 
 			this.loader
 				.setMimeType( isUnicode ? undefined : 'text/plain; charset=shift_jis' )
+				.setPath( this.animationPath )
 				.setResponseType( 'text' )
 				.load( url, function ( text ) {
 
@@ -340,21 +394,24 @@ THREE.MMDLoader = ( function () {
 
 		/**
 		 * @param {Object} data - parsed PMD/PMX data
-		 * @param {string} texturePath
+		 * @param {string} resourcePath
 		 * @param {function} onProgress
 		 * @param {function} onError
 		 * @return {THREE.SkinnedMesh}
 		 */
-		build: function ( data, texturePath, onProgress, onError ) {
+		build: function ( data, resourcePath, onProgress, onError ) {
 
 			var geometry = this.geometryBuilder.build( data );
 			var material = this.materialBuilder
 				.setCrossOrigin( this.crossOrigin )
-				.setTexturePath( texturePath )
+				.setResourcePath( resourcePath )
 				.build( data, geometry, onProgress, onError );
 
 			var mesh = new THREE.SkinnedMesh( geometry, material );
 
+			var skeleton = new THREE.Skeleton( initBones( mesh ) );
+			mesh.bind( skeleton );
+
 			// console.log( mesh ); // for console debug
 
 			return mesh;
@@ -363,6 +420,70 @@ THREE.MMDLoader = ( function () {
 
 	};
 
+	// TODO: Try to remove this function
+
+	function initBones( mesh ) {
+
+		var geometry = mesh.geometry;
+
+		var bones = [], bone, gbone;
+		var i, il;
+
+		if ( geometry && geometry.bones !== undefined ) {
+
+			// first, create array of 'Bone' objects from geometry data
+
+			for ( i = 0, il = geometry.bones.length; i < il; i ++ ) {
+
+				gbone = geometry.bones[ i ];
+
+				// create new 'Bone' object
+
+				bone = new THREE.Bone();
+				bones.push( bone );
+
+				// apply values
+
+				bone.name = gbone.name;
+				bone.position.fromArray( gbone.pos );
+				bone.quaternion.fromArray( gbone.rotq );
+				if ( gbone.scl !== undefined ) bone.scale.fromArray( gbone.scl );
+
+			}
+
+			// second, create bone hierarchy
+
+			for ( i = 0, il = geometry.bones.length; i < il; i ++ ) {
+
+				gbone = geometry.bones[ i ];
+
+				if ( ( gbone.parent !== - 1 ) && ( gbone.parent !== null ) && ( bones[ gbone.parent ] !== undefined ) ) {
+
+					// subsequent bones in the hierarchy
+
+					bones[ gbone.parent ].add( bones[ i ] );
+
+				} else {
+
+					// topmost bone, immediate child of the skinned mesh
+
+					mesh.add( bones[ i ] );
+
+				}
+
+			}
+
+		}
+
+		// now the bones are part of the scene graph and children of the skinned mesh.
+		// let's update the corresponding matrices
+
+		mesh.updateMatrixWorld( true );
+
+		return bones;
+
+	}
+
 	//
 
 	function GeometryBuilder() {
@@ -874,7 +995,7 @@ THREE.MMDLoader = ( function () {
 
 		crossOrigin: 'anonymous',
 
-		texturePath: undefined,
+		resourcePath: undefined,
 
 		/**
 		 * @param {string} crossOrigin
@@ -888,12 +1009,12 @@ THREE.MMDLoader = ( function () {
 		},
 
 		/**
-		 * @param {string} texturePath
+		 * @param {string} resourcePath
 		 * @return {MaterialBuilder}
 		 */
-		setTexturePath: function ( texturePath ) {
+		setResourcePath: function ( resourcePath ) {
 
-			this.texturePath = texturePath;
+			this.resourcePath = resourcePath;
 			return this;
 
 		},
@@ -1213,7 +1334,7 @@ THREE.MMDLoader = ( function () {
 
 			} else {
 
-				fullPath = this.texturePath + filePath;
+				fullPath = this.resourcePath + filePath;
 
 			}
 

+ 578 - 0
examples/js/loaders/deprecated/LegacyJSONLoader.js

@@ -0,0 +1,578 @@
+/**
+ * @author mrdoob / http://mrdoob.com/
+ * @author alteredq / http://alteredqualia.com/
+ */
+
+THREE.LegacyJSONLoader = ( function () {
+
+	function LegacyJSONLoader( manager ) {
+
+		if ( typeof manager === 'boolean' ) {
+
+			console.warn( 'THREE.JSONLoader: showStatus parameter has been removed from constructor.' );
+			manager = undefined;
+
+		}
+
+		this.manager = ( manager !== undefined ) ? manager : THREE.DefaultLoadingManager;
+
+		this.withCredentials = false;
+
+	}
+
+	Object.assign( LegacyJSONLoader.prototype, {
+
+		crossOrigin: 'anonymous',
+
+		load: function ( url, onLoad, onProgress, onError ) {
+
+			var scope = this;
+
+			var path = ( this.path === undefined ) ? THREE.LoaderUtils.extractUrlBase( url ) : this.path;
+
+			var loader = new THREE.FileLoader( this.manager );
+			loader.setPath( this.path );
+			loader.setWithCredentials( this.withCredentials );
+			loader.load( url, function ( text ) {
+
+				var json = JSON.parse( text );
+				var metadata = json.metadata;
+
+				if ( metadata !== undefined ) {
+
+					var type = metadata.type;
+
+					if ( type !== undefined ) {
+
+						if ( type.toLowerCase() === 'object' ) {
+
+							console.error( 'THREE.JSONLoader: ' + url + ' should be loaded with THREE.ObjectLoader instead.' );
+							return;
+
+						}
+
+					}
+
+				}
+
+				var object = scope.parse( json, path );
+				onLoad( object.geometry, object.materials );
+
+			}, onProgress, onError );
+
+		},
+
+		setPath: function ( value ) {
+
+			this.path = value;
+			return this;
+
+		},
+
+		setResourcePath: function ( value ) {
+
+			this.resourcePath = value;
+			return this;
+
+		},
+
+		setCrossOrigin: function ( value ) {
+
+			this.crossOrigin = value;
+			return this;
+
+		},
+
+		parse: ( function () {
+
+			function parseModel( json, geometry ) {
+
+				function isBitSet( value, position ) {
+
+					return value & ( 1 << position );
+
+				}
+
+				var i, j, fi,
+
+					offset, zLength,
+
+					colorIndex, normalIndex, uvIndex, materialIndex,
+
+					type,
+					isQuad,
+					hasMaterial,
+					hasFaceVertexUv,
+					hasFaceNormal, hasFaceVertexNormal,
+					hasFaceColor, hasFaceVertexColor,
+
+					vertex, face, faceA, faceB, hex, normal,
+
+					uvLayer, uv, u, v,
+
+					faces = json.faces,
+					vertices = json.vertices,
+					normals = json.normals,
+					colors = json.colors,
+
+					scale = json.scale,
+
+					nUvLayers = 0;
+
+
+				if ( json.uvs !== undefined ) {
+
+					// disregard empty arrays
+
+					for ( i = 0; i < json.uvs.length; i ++ ) {
+
+						if ( json.uvs[ i ].length ) nUvLayers ++;
+
+					}
+
+					for ( i = 0; i < nUvLayers; i ++ ) {
+
+						geometry.faceVertexUvs[ i ] = [];
+
+					}
+
+				}
+
+				offset = 0;
+				zLength = vertices.length;
+
+				while ( offset < zLength ) {
+
+					vertex = new THREE.Vector3();
+
+					vertex.x = vertices[ offset ++ ] * scale;
+					vertex.y = vertices[ offset ++ ] * scale;
+					vertex.z = vertices[ offset ++ ] * scale;
+
+					geometry.vertices.push( vertex );
+
+				}
+
+				offset = 0;
+				zLength = faces.length;
+
+				while ( offset < zLength ) {
+
+					type = faces[ offset ++ ];
+
+					isQuad = isBitSet( type, 0 );
+					hasMaterial = isBitSet( type, 1 );
+					hasFaceVertexUv = isBitSet( type, 3 );
+					hasFaceNormal = isBitSet( type, 4 );
+					hasFaceVertexNormal = isBitSet( type, 5 );
+					hasFaceColor = isBitSet( type, 6 );
+					hasFaceVertexColor = isBitSet( type, 7 );
+
+					// console.log("type", type, "bits", isQuad, hasMaterial, hasFaceVertexUv, hasFaceNormal, hasFaceVertexNormal, hasFaceColor, hasFaceVertexColor);
+
+					if ( isQuad ) {
+
+						faceA = new THREE.Face3();
+						faceA.a = faces[ offset ];
+						faceA.b = faces[ offset + 1 ];
+						faceA.c = faces[ offset + 3 ];
+
+						faceB = new THREE.Face3();
+						faceB.a = faces[ offset + 1 ];
+						faceB.b = faces[ offset + 2 ];
+						faceB.c = faces[ offset + 3 ];
+
+						offset += 4;
+
+						if ( hasMaterial ) {
+
+							materialIndex = faces[ offset ++ ];
+							faceA.materialIndex = materialIndex;
+							faceB.materialIndex = materialIndex;
+
+						}
+
+						// to get face <=> uv index correspondence
+
+						fi = geometry.faces.length;
+
+						if ( hasFaceVertexUv ) {
+
+							for ( i = 0; i < nUvLayers; i ++ ) {
+
+								uvLayer = json.uvs[ i ];
+
+								geometry.faceVertexUvs[ i ][ fi ] = [];
+								geometry.faceVertexUvs[ i ][ fi + 1 ] = [];
+
+								for ( j = 0; j < 4; j ++ ) {
+
+									uvIndex = faces[ offset ++ ];
+
+									u = uvLayer[ uvIndex * 2 ];
+									v = uvLayer[ uvIndex * 2 + 1 ];
+
+									uv = new THREE.Vector2( u, v );
+
+									if ( j !== 2 ) geometry.faceVertexUvs[ i ][ fi ].push( uv );
+									if ( j !== 0 ) geometry.faceVertexUvs[ i ][ fi + 1 ].push( uv );
+
+								}
+
+							}
+
+						}
+
+						if ( hasFaceNormal ) {
+
+							normalIndex = faces[ offset ++ ] * 3;
+
+							faceA.normal.set(
+								normals[ normalIndex ++ ],
+								normals[ normalIndex ++ ],
+								normals[ normalIndex ]
+							);
+
+							faceB.normal.copy( faceA.normal );
+
+						}
+
+						if ( hasFaceVertexNormal ) {
+
+							for ( i = 0; i < 4; i ++ ) {
+
+								normalIndex = faces[ offset ++ ] * 3;
+
+								normal = new THREE.Vector3(
+									normals[ normalIndex ++ ],
+									normals[ normalIndex ++ ],
+									normals[ normalIndex ]
+								);
+
+
+								if ( i !== 2 ) faceA.vertexNormals.push( normal );
+								if ( i !== 0 ) faceB.vertexNormals.push( normal );
+
+							}
+
+						}
+
+
+						if ( hasFaceColor ) {
+
+							colorIndex = faces[ offset ++ ];
+							hex = colors[ colorIndex ];
+
+							faceA.color.setHex( hex );
+							faceB.color.setHex( hex );
+
+						}
+
+
+						if ( hasFaceVertexColor ) {
+
+							for ( i = 0; i < 4; i ++ ) {
+
+								colorIndex = faces[ offset ++ ];
+								hex = colors[ colorIndex ];
+
+								if ( i !== 2 ) faceA.vertexColors.push( new THREE.Color( hex ) );
+								if ( i !== 0 ) faceB.vertexColors.push( new THREE.Color( hex ) );
+
+							}
+
+						}
+
+						geometry.faces.push( faceA );
+						geometry.faces.push( faceB );
+
+					} else {
+
+						face = new THREE.Face3();
+						face.a = faces[ offset ++ ];
+						face.b = faces[ offset ++ ];
+						face.c = faces[ offset ++ ];
+
+						if ( hasMaterial ) {
+
+							materialIndex = faces[ offset ++ ];
+							face.materialIndex = materialIndex;
+
+						}
+
+						// to get face <=> uv index correspondence
+
+						fi = geometry.faces.length;
+
+						if ( hasFaceVertexUv ) {
+
+							for ( i = 0; i < nUvLayers; i ++ ) {
+
+								uvLayer = json.uvs[ i ];
+
+								geometry.faceVertexUvs[ i ][ fi ] = [];
+
+								for ( j = 0; j < 3; j ++ ) {
+
+									uvIndex = faces[ offset ++ ];
+
+									u = uvLayer[ uvIndex * 2 ];
+									v = uvLayer[ uvIndex * 2 + 1 ];
+
+									uv = new THREE.Vector2( u, v );
+
+									geometry.faceVertexUvs[ i ][ fi ].push( uv );
+
+								}
+
+							}
+
+						}
+
+						if ( hasFaceNormal ) {
+
+							normalIndex = faces[ offset ++ ] * 3;
+
+							face.normal.set(
+								normals[ normalIndex ++ ],
+								normals[ normalIndex ++ ],
+								normals[ normalIndex ]
+							);
+
+						}
+
+						if ( hasFaceVertexNormal ) {
+
+							for ( i = 0; i < 3; i ++ ) {
+
+								normalIndex = faces[ offset ++ ] * 3;
+
+								normal = new THREE.Vector3(
+									normals[ normalIndex ++ ],
+									normals[ normalIndex ++ ],
+									normals[ normalIndex ]
+								);
+
+								face.vertexNormals.push( normal );
+
+							}
+
+						}
+
+
+						if ( hasFaceColor ) {
+
+							colorIndex = faces[ offset ++ ];
+							face.color.setHex( colors[ colorIndex ] );
+
+						}
+
+
+						if ( hasFaceVertexColor ) {
+
+							for ( i = 0; i < 3; i ++ ) {
+
+								colorIndex = faces[ offset ++ ];
+								face.vertexColors.push( new THREE.Color( colors[ colorIndex ] ) );
+
+							}
+
+						}
+
+						geometry.faces.push( face );
+
+					}
+
+				}
+
+			}
+
+			function parseSkin( json, geometry ) {
+
+				var influencesPerVertex = ( json.influencesPerVertex !== undefined ) ? json.influencesPerVertex : 2;
+
+				if ( json.skinWeights ) {
+
+					for ( var i = 0, l = json.skinWeights.length; i < l; i += influencesPerVertex ) {
+
+						var x = json.skinWeights[ i ];
+						var y = ( influencesPerVertex > 1 ) ? json.skinWeights[ i + 1 ] : 0;
+						var z = ( influencesPerVertex > 2 ) ? json.skinWeights[ i + 2 ] : 0;
+						var w = ( influencesPerVertex > 3 ) ? json.skinWeights[ i + 3 ] : 0;
+
+						geometry.skinWeights.push( new THREE.Vector4( x, y, z, w ) );
+
+					}
+
+				}
+
+				if ( json.skinIndices ) {
+
+					for ( var i = 0, l = json.skinIndices.length; i < l; i += influencesPerVertex ) {
+
+						var a = json.skinIndices[ i ];
+						var b = ( influencesPerVertex > 1 ) ? json.skinIndices[ i + 1 ] : 0;
+						var c = ( influencesPerVertex > 2 ) ? json.skinIndices[ i + 2 ] : 0;
+						var d = ( influencesPerVertex > 3 ) ? json.skinIndices[ i + 3 ] : 0;
+
+						geometry.skinIndices.push( new THREE.Vector4( a, b, c, d ) );
+
+					}
+
+				}
+
+				geometry.bones = json.bones;
+
+				if ( geometry.bones && geometry.bones.length > 0 && ( geometry.skinWeights.length !== geometry.skinIndices.length || geometry.skinIndices.length !== geometry.vertices.length ) ) {
+
+					console.warn( 'When skinning, number of vertices (' + geometry.vertices.length + '), skinIndices (' +
+						geometry.skinIndices.length + '), and skinWeights (' + geometry.skinWeights.length + ') should match.' );
+
+				}
+
+			}
+
+			function parseMorphing( json, geometry ) {
+
+				var scale = json.scale;
+
+				if ( json.morphTargets !== undefined ) {
+
+					for ( var i = 0, l = json.morphTargets.length; i < l; i ++ ) {
+
+						geometry.morphTargets[ i ] = {};
+						geometry.morphTargets[ i ].name = json.morphTargets[ i ].name;
+						geometry.morphTargets[ i ].vertices = [];
+
+						var dstVertices = geometry.morphTargets[ i ].vertices;
+						var srcVertices = json.morphTargets[ i ].vertices;
+
+						for ( var v = 0, vl = srcVertices.length; v < vl; v += 3 ) {
+
+							var vertex = new THREE.Vector3();
+							vertex.x = srcVertices[ v ] * scale;
+							vertex.y = srcVertices[ v + 1 ] * scale;
+							vertex.z = srcVertices[ v + 2 ] * scale;
+
+							dstVertices.push( vertex );
+
+						}
+
+					}
+
+				}
+
+				if ( json.morphColors !== undefined && json.morphColors.length > 0 ) {
+
+					console.warn( 'THREE.JSONLoader: "morphColors" no longer supported. Using them as face colors.' );
+
+					var faces = geometry.faces;
+					var morphColors = json.morphColors[ 0 ].colors;
+
+					for ( var i = 0, l = faces.length; i < l; i ++ ) {
+
+						faces[ i ].color.fromArray( morphColors, i * 3 );
+
+					}
+
+				}
+
+			}
+
+			function parseAnimations( json, geometry ) {
+
+				var outputAnimations = [];
+
+				// parse old style Bone/Hierarchy animations
+				var animations = [];
+
+				if ( json.animation !== undefined ) {
+
+					animations.push( json.animation );
+
+				}
+
+				if ( json.animations !== undefined ) {
+
+					if ( json.animations.length ) {
+
+						animations = animations.concat( json.animations );
+
+					} else {
+
+						animations.push( json.animations );
+
+					}
+
+				}
+
+				for ( var i = 0; i < animations.length; i ++ ) {
+
+					var clip = THREE.AnimationClip.parseAnimation( animations[ i ], geometry.bones );
+					if ( clip ) outputAnimations.push( clip );
+
+				}
+
+				// parse implicit morph animations
+				if ( geometry.morphTargets ) {
+
+					// TODO: Figure out what an appropraite FPS is for morph target animations -- defaulting to 10, but really it is completely arbitrary.
+					var morphAnimationClips = THREE.AnimationClip.CreateClipsFromMorphTargetSequences( geometry.morphTargets, 10 );
+					outputAnimations = outputAnimations.concat( morphAnimationClips );
+
+				}
+
+				if ( outputAnimations.length > 0 ) geometry.animations = outputAnimations;
+
+			}
+
+			return function parse( json, path ) {
+
+				if ( json.data !== undefined ) {
+
+					// Geometry 4.0 spec
+					json = json.data;
+
+				}
+
+				if ( json.scale !== undefined ) {
+
+					json.scale = 1.0 / json.scale;
+
+				} else {
+
+					json.scale = 1.0;
+
+				}
+
+				var geometry = new THREE.Geometry();
+
+				parseModel( json, geometry );
+				parseSkin( json, geometry );
+				parseMorphing( json, geometry );
+				parseAnimations( json, geometry );
+
+				geometry.computeFaceNormals();
+				geometry.computeBoundingSphere();
+
+				if ( json.materials === undefined || json.materials.length === 0 ) {
+
+					return { geometry: geometry };
+
+				} else {
+
+					var materials = THREE.Loader.prototype.initMaterials( json.materials, this.resourcePath || path, this.crossOrigin );
+
+					return { geometry: geometry, materials: materials };
+
+				}
+
+			};
+
+		} )()
+
+	} );
+
+	return LegacyJSONLoader;
+
+} )();

+ 64 - 2
examples/js/loaders/sea3d/SEA3DLoader.js

@@ -1296,9 +1296,11 @@ THREE.SEA3D.Mesh.prototype = Object.assign( Object.create( THREE.Mesh.prototype
 //	Skinning
 //
 
-THREE.SEA3D.SkinnedMesh = function ( geometry, material, useVertexTexture ) {
+THREE.SEA3D.SkinnedMesh = function ( geometry, material ) {
 
-	THREE.SkinnedMesh.call( this, geometry, material, useVertexTexture );
+	THREE.SkinnedMesh.call( this, geometry, material );
+
+	this.bind( new THREE.Skeleton( this.initBones() ), this.matrixWorld );
 
 	this.updateAnimations( geometry.animations, new THREE.AnimationMixer( this ) );
 
@@ -1308,6 +1310,66 @@ THREE.SEA3D.SkinnedMesh.prototype = Object.assign( Object.create( THREE.SkinnedM
 
 	constructor: THREE.SEA3D.SkinnedMesh,
 
+	initBones: function () {
+
+		var bones = [], bone, gbone;
+		var i, il;
+
+		if ( this.geometry && this.geometry.bones !== undefined ) {
+
+			// first, create array of 'Bone' objects from geometry data
+
+			for ( i = 0, il = this.geometry.bones.length; i < il; i ++ ) {
+
+				gbone = this.geometry.bones[ i ];
+
+				// create new 'Bone' object
+
+				bone = new THREE.Bone();
+				bones.push( bone );
+
+				// apply values
+
+				bone.name = gbone.name;
+				bone.position.fromArray( gbone.pos );
+				bone.quaternion.fromArray( gbone.rotq );
+				if ( gbone.scl !== undefined ) bone.scale.fromArray( gbone.scl );
+
+			}
+
+			// second, create bone hierarchy
+
+			for ( i = 0, il = this.geometry.bones.length; i < il; i ++ ) {
+
+				gbone = this.geometry.bones[ i ];
+
+				if ( ( gbone.parent !== - 1 ) && ( gbone.parent !== null ) && ( bones[ gbone.parent ] !== undefined ) ) {
+
+					// subsequent bones in the hierarchy
+
+					bones[ gbone.parent ].add( bones[ i ] );
+
+				} else {
+
+					// topmost bone, immediate child of the skinned mesh
+
+					this.add( bones[ i ] );
+
+				}
+
+			}
+
+		}
+
+		// now the bones are part of the scene graph and children of the skinned mesh.
+		// let's update the corresponding matrices
+
+		this.updateMatrixWorld( true );
+
+		return bones;
+
+	},
+
 	boneByName: function ( name ) {
 
 		var bones = this.skeleton.bones;

+ 1 - 2
examples/js/nodes/materials/nodes/StandardNode.js

@@ -183,8 +183,7 @@ StandardNode.prototype.build = function ( builder ) {
 			"#include <lights_pars_begin>",
 			"#include <lights_physical_pars_fragment>",
 			"#include <shadowmap_pars_fragment>",
-			"#include <logdepthbuf_pars_fragment>",
-			"#include <logdepthbuf_vertex>"
+			"#include <logdepthbuf_pars_fragment>"
 		].join( "\n" ) );
 
 		var output = [

+ 38 - 0
examples/js/offscreen/jank.js

@@ -0,0 +1,38 @@
+var interval = null;
+
+var button = document.getElementById( 'button' );
+button.addEventListener( 'click', function () {
+
+	if ( interval === null ) {
+
+		interval = setInterval( jank, 1000 / 60 );
+
+		button.textContent = 'STOP JANK';
+
+	} else {
+
+		clearInterval( interval );
+		interval = null;
+
+		button.textContent = 'START JANK';
+		result.textContent = '';
+
+	}
+
+} );
+
+var result = document.getElementById( 'result' );
+
+function jank() {
+
+	var number = 0;
+
+	for ( var i = 0; i < 10000000; i ++ ) {
+
+		number += Math.random();
+
+	}
+
+	result.textContent = number;
+
+}

+ 9 - 0
examples/js/offscreen/offscreen.js

@@ -0,0 +1,9 @@
+self.importScripts( '../../../build/three.js' );
+self.importScripts( './scene.js' );
+
+self.onmessage = function ( message ) {
+
+	var data = message.data;
+	init( data.drawingSurface, data.width, data.height, data.pixelRatio, data.path );
+
+};

+ 77 - 0
examples/js/offscreen/scene.js

@@ -0,0 +1,77 @@
+var camera, scene, renderer, group;
+
+function init( canvas, width, height, pixelRatio, path ) {
+
+	camera = new THREE.PerspectiveCamera( 40, width / height, 1, 1000 );
+	camera.position.z = 200;
+
+	scene = new THREE.Scene();
+	scene.fog = new THREE.Fog( 0x444466, 100, 400 );
+	scene.background = new THREE.Color( 0x444466 );
+
+	group = new THREE.Group();
+	scene.add( group );
+
+	// we don't use ImageLoader since it has a DOM dependency (HTML5 image element)
+
+	var loader = new THREE.ImageBitmapLoader().setPath( path );
+	loader.load( 'textures/matcaps/matcap-porcelain-white.jpg', function ( imageBitmap ) {
+
+		var texture = new THREE.CanvasTexture( imageBitmap );
+
+		var geometry = new THREE.IcosahedronBufferGeometry( 5, 3 );
+		var materials = [
+			new THREE.MeshMatcapMaterial( { color: 0xaa24df, matcap: texture } ),
+			new THREE.MeshMatcapMaterial( { color: 0x605d90, matcap: texture } ),
+			new THREE.MeshMatcapMaterial( { color: 0xe04a3f, matcap: texture } ),
+			new THREE.MeshMatcapMaterial( { color: 0xe30456, matcap: texture } )
+		];
+
+		for ( var i = 0; i < 100; i ++ ) {
+
+			var material = materials[ i % materials.length ];
+			var mesh = new THREE.Mesh( geometry, material );
+			mesh.position.x = random() * 200 - 100;
+			mesh.position.y = random() * 200 - 100;
+			mesh.position.z = random() * 200 - 100;
+			mesh.scale.setScalar( random() + 1 );
+			group.add( mesh );
+
+		}
+
+		renderer = new THREE.WebGLRenderer( { antialias: true, canvas: canvas } );
+		renderer.setPixelRatio( pixelRatio );
+		renderer.setSize( width, height, false );
+
+		animate();
+
+	} );
+
+}
+
+function animate() {
+
+	// group.rotation.x = Date.now() / 4000;
+	group.rotation.y = - Date.now() / 4000;
+
+	renderer.render( scene, camera );
+
+	if ( self.requestAnimationFrame ) {
+
+		self.requestAnimationFrame( animate );
+
+	} else {
+
+		// Firefox
+
+	}
+
+}
+
+// PRNG
+
+var seed = 1;
+function random() {
+	var x = Math.sin(seed++) * 10000;
+	return x - Math.floor(x);
+}

+ 164 - 135
examples/js/pmrem/PMREMCubeUVPacker.js

@@ -13,123 +13,161 @@
  * The arrangement of the faces is fixed, as assuming this arrangement, the sampling function has been written.
  */
 
-THREE.PMREMCubeUVPacker = function ( cubeTextureLods ) {
-
-	this.cubeLods = cubeTextureLods;
-	var size = cubeTextureLods[ 0 ].width * 4;
-
-	var sourceTexture = cubeTextureLods[ 0 ].texture;
-	var params = {
-		format: sourceTexture.format,
-		magFilter: sourceTexture.magFilter,
-		minFilter: sourceTexture.minFilter,
-		type: sourceTexture.type,
-		generateMipmaps: sourceTexture.generateMipmaps,
-		anisotropy: sourceTexture.anisotropy,
-		encoding: ( sourceTexture.encoding === THREE.RGBEEncoding ) ? THREE.RGBM16Encoding : sourceTexture.encoding
-	};
+THREE.PMREMCubeUVPacker = ( function () {
 
-	if ( params.encoding === THREE.RGBM16Encoding ) {
+	var camera = new THREE.OrthographicCamera();
+	var scene = new THREE.Scene();
+	var shader = getShader();
 
-		params.magFilter = THREE.LinearFilter;
-		params.minFilter = THREE.LinearFilter;
+	var PMREMCubeUVPacker = function ( cubeTextureLods ) {
 
-	}
+		this.cubeLods = cubeTextureLods;
+		var size = cubeTextureLods[ 0 ].width * 4;
 
-	this.CubeUVRenderTarget = new THREE.WebGLRenderTarget( size, size, params );
-	this.CubeUVRenderTarget.texture.name = "PMREMCubeUVPacker.cubeUv";
-	this.CubeUVRenderTarget.texture.mapping = THREE.CubeUVReflectionMapping;
-	this.camera = new THREE.OrthographicCamera( - size * 0.5, size * 0.5, - size * 0.5, size * 0.5, 0, 1 ); // top and bottom are swapped for some reason?
+		var sourceTexture = cubeTextureLods[ 0 ].texture;
+		var params = {
+			format: sourceTexture.format,
+			magFilter: sourceTexture.magFilter,
+			minFilter: sourceTexture.minFilter,
+			type: sourceTexture.type,
+			generateMipmaps: sourceTexture.generateMipmaps,
+			anisotropy: sourceTexture.anisotropy,
+			encoding: ( sourceTexture.encoding === THREE.RGBEEncoding ) ? THREE.RGBM16Encoding : sourceTexture.encoding
+		};
 
-	this.scene = new THREE.Scene();
+		if ( params.encoding === THREE.RGBM16Encoding ) {
 
-	this.objects = [];
+			params.magFilter = THREE.LinearFilter;
+			params.minFilter = THREE.LinearFilter;
 
-	var geometry = new THREE.PlaneBufferGeometry( 1, 1 );
+		}
 
-	var faceOffsets = [];
-	faceOffsets.push( new THREE.Vector2( 0, 0 ) );
-	faceOffsets.push( new THREE.Vector2( 1, 0 ) );
-	faceOffsets.push( new THREE.Vector2( 2, 0 ) );
-	faceOffsets.push( new THREE.Vector2( 0, 1 ) );
-	faceOffsets.push( new THREE.Vector2( 1, 1 ) );
-	faceOffsets.push( new THREE.Vector2( 2, 1 ) );
+		this.CubeUVRenderTarget = new THREE.WebGLRenderTarget( size, size, params );
+		this.CubeUVRenderTarget.texture.name = "PMREMCubeUVPacker.cubeUv";
+		this.CubeUVRenderTarget.texture.mapping = THREE.CubeUVReflectionMapping;
+
+		this.objects = [];
+
+		var geometry = new THREE.PlaneBufferGeometry( 1, 1 );
+
+		var faceOffsets = [];
+		faceOffsets.push( new THREE.Vector2( 0, 0 ) );
+		faceOffsets.push( new THREE.Vector2( 1, 0 ) );
+		faceOffsets.push( new THREE.Vector2( 2, 0 ) );
+		faceOffsets.push( new THREE.Vector2( 0, 1 ) );
+		faceOffsets.push( new THREE.Vector2( 1, 1 ) );
+		faceOffsets.push( new THREE.Vector2( 2, 1 ) );
+
+		var textureResolution = size;
+		size = cubeTextureLods[ 0 ].width;
+
+		var offset2 = 0;
+		var c = 4.0;
+		this.numLods = Math.log( cubeTextureLods[ 0 ].width ) / Math.log( 2 ) - 2; // IE11 doesn't support Math.log2
+		for ( var i = 0; i < this.numLods; i ++ ) {
+
+			var offset1 = ( textureResolution - textureResolution / c ) * 0.5;
+			if ( size > 16 ) c *= 2;
+			var nMips = size > 16 ? 6 : 1;
+			var mipOffsetX = 0;
+			var mipOffsetY = 0;
+			var mipSize = size;
+
+			for ( var j = 0; j < nMips; j ++ ) {
+
+				// Mip Maps
+				for ( var k = 0; k < 6; k ++ ) {
+
+					// 6 Cube Faces
+					var material = shader.clone();
+					material.uniforms[ 'envMap' ].value = this.cubeLods[ i ].texture;
+					material.envMap = this.cubeLods[ i ].texture;
+					material.uniforms[ 'faceIndex' ].value = k;
+					material.uniforms[ 'mapSize' ].value = mipSize;
+
+					var planeMesh = new THREE.Mesh( geometry, material );
+					planeMesh.position.x = faceOffsets[ k ].x * mipSize - offset1 + mipOffsetX;
+					planeMesh.position.y = faceOffsets[ k ].y * mipSize - offset1 + offset2 + mipOffsetY;
+					planeMesh.material.side = THREE.BackSide;
+					planeMesh.scale.setScalar( mipSize );
+					this.objects.push( planeMesh );
+
+				}
+				mipOffsetY += 1.75 * mipSize;
+				mipOffsetX += 1.25 * mipSize;
+				mipSize /= 2;
 
-	var textureResolution = size;
-	size = cubeTextureLods[ 0 ].width;
+			}
+			offset2 += 2 * size;
+			if ( size > 16 ) size /= 2;
 
-	var offset2 = 0;
-	var c = 4.0;
-	this.numLods = Math.log( cubeTextureLods[ 0 ].width ) / Math.log( 2 ) - 2; // IE11 doesn't support Math.log2
-	for ( var i = 0; i < this.numLods; i ++ ) {
+		}
+
+	};
 
-		var offset1 = ( textureResolution - textureResolution / c ) * 0.5;
-		if ( size > 16 ) c *= 2;
-		var nMips = size > 16 ? 6 : 1;
-		var mipOffsetX = 0;
-		var mipOffsetY = 0;
-		var mipSize = size;
+	PMREMCubeUVPacker.prototype = {
 
-		for ( var j = 0; j < nMips; j ++ ) {
+		constructor: PMREMCubeUVPacker,
 
-			// Mip Maps
-			for ( var k = 0; k < 6; k ++ ) {
+		update: function ( renderer ) {
 
-				// 6 Cube Faces
-				var material = this.getShader();
-				material.uniforms[ 'envMap' ].value = this.cubeLods[ i ].texture;
-				material.envMap = this.cubeLods[ i ].texture;
-				material.uniforms[ 'faceIndex' ].value = k;
-				material.uniforms[ 'mapSize' ].value = mipSize;
+			var size = this.cubeLods[ 0 ].width * 4;
+			// top and bottom are swapped for some reason?
+			camera.left = - size * 0.5;
+			camera.right = size * 0.5;
+			camera.top = - size * 0.5;
+			camera.bottom = size * 0.5;
+			camera.near = 0;
+			camera.far = 1;
+			camera.updateProjectionMatrix();
 
-				var planeMesh = new THREE.Mesh( geometry, material );
-				planeMesh.position.x = faceOffsets[ k ].x * mipSize - offset1 + mipOffsetX;
-				planeMesh.position.y = faceOffsets[ k ].y * mipSize - offset1 + offset2 + mipOffsetY;
-				planeMesh.material.side = THREE.BackSide;
-				planeMesh.scale.setScalar( mipSize );
-				this.scene.add( planeMesh );
-				this.objects.push( planeMesh );
+			for ( var i = 0; i < this.objects.length; i ++ ) {
+
+				scene.add( this.objects[ i ] );
 
 			}
-			mipOffsetY += 1.75 * mipSize;
-			mipOffsetX += 1.25 * mipSize;
-			mipSize /= 2;
 
-		}
-		offset2 += 2 * size;
-		if ( size > 16 ) size /= 2;
+			var gammaInput = renderer.gammaInput;
+			var gammaOutput = renderer.gammaOutput;
+			var toneMapping = renderer.toneMapping;
+			var toneMappingExposure = renderer.toneMappingExposure;
+			var currentRenderTarget = renderer.getRenderTarget();
 
-	}
+			renderer.gammaInput = false;
+			renderer.gammaOutput = false;
+			renderer.toneMapping = THREE.LinearToneMapping;
+			renderer.toneMappingExposure = 1.0;
+			renderer.render( scene, camera, this.CubeUVRenderTarget, false );
 
-};
+			renderer.setRenderTarget( currentRenderTarget );
+			renderer.toneMapping = toneMapping;
+			renderer.toneMappingExposure = toneMappingExposure;
+			renderer.gammaInput = gammaInput;
+			renderer.gammaOutput = gammaOutput;
 
-THREE.PMREMCubeUVPacker.prototype = {
+			for ( var i = 0; i < this.objects.length; i ++ ) {
 
-	constructor: THREE.PMREMCubeUVPacker,
+				scene.remove( this.objects[ i ] );
 
-	update: function ( renderer ) {
+			}
+
+		},
 
-		var gammaInput = renderer.gammaInput;
-		var gammaOutput = renderer.gammaOutput;
-		var toneMapping = renderer.toneMapping;
-		var toneMappingExposure = renderer.toneMappingExposure;
-		var currentRenderTarget = renderer.getRenderTarget();
+		dispose: function () {
 
-		renderer.gammaInput = false;
-		renderer.gammaOutput = false;
-		renderer.toneMapping = THREE.LinearToneMapping;
-		renderer.toneMappingExposure = 1.0;
-		renderer.render( this.scene, this.camera, this.CubeUVRenderTarget, false );
+			for ( var i = 0, l = this.objects.length; i < l; i ++ ) {
 
-		renderer.setRenderTarget( currentRenderTarget );
-		renderer.toneMapping = toneMapping;
-		renderer.toneMappingExposure = toneMappingExposure;
-		renderer.gammaInput = gammaInput;
-		renderer.gammaOutput = gammaOutput;
+				this.objects[ i ].material.dispose();
 
-	},
+			}
 
-	getShader: function () {
+			this.objects[ 0 ].geometry.dispose();
+
+		}
+
+	};
+
+	function getShader() {
 
 		var shaderMaterial = new THREE.ShaderMaterial( {
 
@@ -141,42 +179,42 @@ THREE.PMREMCubeUVPacker.prototype = {
 			},
 
 			vertexShader:
-				"precision highp float;\
-				varying vec2 vUv;\
-				void main() {\
-					vUv = uv;\
-					gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );\
-				}",
+        "precision highp float;\
+        varying vec2 vUv;\
+        void main() {\
+          vUv = uv;\
+          gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );\
+        }",
 
 			fragmentShader:
-				"precision highp float;\
-				varying vec2 vUv;\
-				uniform samplerCube envMap;\
-				uniform float mapSize;\
-				uniform vec3 testColor;\
-				uniform int faceIndex;\
-				\
-				void main() {\
-					vec3 sampleDirection;\
-					vec2 uv = vUv;\
-					uv = uv * 2.0 - 1.0;\
-					uv.y *= -1.0;\
-					if(faceIndex == 0) {\
-						sampleDirection = normalize(vec3(1.0, uv.y, -uv.x));\
-					} else if(faceIndex == 1) {\
-						sampleDirection = normalize(vec3(uv.x, 1.0, uv.y));\
-					} else if(faceIndex == 2) {\
-						sampleDirection = normalize(vec3(uv.x, uv.y, 1.0));\
-					} else if(faceIndex == 3) {\
-						sampleDirection = normalize(vec3(-1.0, uv.y, uv.x));\
-					} else if(faceIndex == 4) {\
-						sampleDirection = normalize(vec3(uv.x, -1.0, -uv.y));\
-					} else {\
-						sampleDirection = normalize(vec3(-uv.x, uv.y, -1.0));\
-					}\
-					vec4 color = envMapTexelToLinear( textureCube( envMap, sampleDirection ) );\
-					gl_FragColor = linearToOutputTexel( color );\
-				}",
+        "precision highp float;\
+        varying vec2 vUv;\
+        uniform samplerCube envMap;\
+        uniform float mapSize;\
+        uniform vec3 testColor;\
+        uniform int faceIndex;\
+        \
+        void main() {\
+          vec3 sampleDirection;\
+          vec2 uv = vUv;\
+          uv = uv * 2.0 - 1.0;\
+          uv.y *= -1.0;\
+          if(faceIndex == 0) {\
+            sampleDirection = normalize(vec3(1.0, uv.y, -uv.x));\
+          } else if(faceIndex == 1) {\
+            sampleDirection = normalize(vec3(uv.x, 1.0, uv.y));\
+          } else if(faceIndex == 2) {\
+            sampleDirection = normalize(vec3(uv.x, uv.y, 1.0));\
+          } else if(faceIndex == 3) {\
+            sampleDirection = normalize(vec3(-1.0, uv.y, uv.x));\
+          } else if(faceIndex == 4) {\
+            sampleDirection = normalize(vec3(uv.x, -1.0, -uv.y));\
+          } else {\
+            sampleDirection = normalize(vec3(-uv.x, uv.y, -1.0));\
+          }\
+          vec4 color = envMapTexelToLinear( textureCube( envMap, sampleDirection ) );\
+          gl_FragColor = linearToOutputTexel( color );\
+        }",
 
 			blending: THREE.NoBlending
 
@@ -186,18 +224,9 @@ THREE.PMREMCubeUVPacker.prototype = {
 
 		return shaderMaterial;
 
-	},
-
-	dispose: function () {
-
-		for ( var i = 0, l = this.objects.length; i < l; i ++ ) {
-
-			this.objects[ i ].material.dispose();
-
-		}
+	}
 
-		this.objects[ 0 ].geometry.dispose();
 
-	}
+	return PMREMCubeUVPacker;
 
-};
+} )();

+ 126 - 121
examples/js/pmrem/PMREMGenerator.js

@@ -11,132 +11,149 @@
  *	by this class.
  */
 
-THREE.PMREMGenerator = function ( sourceTexture, samplesPerLevel, resolution ) {
+THREE.PMREMGenerator = ( function () {
 
-	this.sourceTexture = sourceTexture;
-	this.resolution = ( resolution !== undefined ) ? resolution : 256; // NODE: 256 is currently hard coded in the glsl code for performance reasons
-	this.samplesPerLevel = ( samplesPerLevel !== undefined ) ? samplesPerLevel : 16;
+	var shader = getShader();
+	var camera = new THREE.OrthographicCamera( - 1, 1, 1, - 1, 0.0, 1000 );
+	var scene = new THREE.Scene();
+	var planeMesh = new THREE.Mesh( new THREE.PlaneBufferGeometry( 2, 2, 0 ), shader );
+	planeMesh.material.side = THREE.DoubleSide;
+	scene.add( planeMesh );
+	scene.add( camera );
 
-	var monotonicEncoding = ( sourceTexture.encoding === THREE.LinearEncoding ) ||
-		( sourceTexture.encoding === THREE.GammaEncoding ) || ( sourceTexture.encoding === THREE.sRGBEncoding );
+	var PMREMGenerator = function ( sourceTexture, samplesPerLevel, resolution ) {
 
-	this.sourceTexture.minFilter = ( monotonicEncoding ) ? THREE.LinearFilter : THREE.NearestFilter;
-	this.sourceTexture.magFilter = ( monotonicEncoding ) ? THREE.LinearFilter : THREE.NearestFilter;
-	this.sourceTexture.generateMipmaps = this.sourceTexture.generateMipmaps && monotonicEncoding;
+		this.sourceTexture = sourceTexture;
+		this.resolution = ( resolution !== undefined ) ? resolution : 256; // NODE: 256 is currently hard coded in the glsl code for performance reasons
+		this.samplesPerLevel = ( samplesPerLevel !== undefined ) ? samplesPerLevel : 32;
 
-	this.cubeLods = [];
+		var monotonicEncoding = ( this.sourceTexture.encoding === THREE.LinearEncoding ) ||
+			( this.sourceTexture.encoding === THREE.GammaEncoding ) || ( this.sourceTexture.encoding === THREE.sRGBEncoding );
 
-	var size = this.resolution;
-	var params = {
-		format: this.sourceTexture.format,
-		magFilter: this.sourceTexture.magFilter,
-		minFilter: this.sourceTexture.minFilter,
-		type: this.sourceTexture.type,
-		generateMipmaps: this.sourceTexture.generateMipmaps,
-		anisotropy: this.sourceTexture.anisotropy,
-		encoding: this.sourceTexture.encoding
-	 };
+		this.sourceTexture.minFilter = ( monotonicEncoding ) ? THREE.LinearFilter : THREE.NearestFilter;
+		this.sourceTexture.magFilter = ( monotonicEncoding ) ? THREE.LinearFilter : THREE.NearestFilter;
+		this.sourceTexture.generateMipmaps = this.sourceTexture.generateMipmaps && monotonicEncoding;
 
-	// how many LODs fit in the given CubeUV Texture.
-	this.numLods = Math.log( size ) / Math.log( 2 ) - 2; // IE11 doesn't support Math.log2
+		this.cubeLods = [];
 
-	for ( var i = 0; i < this.numLods; i ++ ) {
+		var size = this.resolution;
+		var params = {
+			format: this.sourceTexture.format,
+			magFilter: this.sourceTexture.magFilter,
+			minFilter: this.sourceTexture.minFilter,
+			type: this.sourceTexture.type,
+			generateMipmaps: this.sourceTexture.generateMipmaps,
+			anisotropy: this.sourceTexture.anisotropy,
+			encoding: this.sourceTexture.encoding
+		};
 
-		var renderTarget = new THREE.WebGLRenderTargetCube( size, size, params );
-		renderTarget.texture.name = "PMREMGenerator.cube" + i;
-		this.cubeLods.push( renderTarget );
-		size = Math.max( 16, size / 2 );
+		// how many LODs fit in the given CubeUV Texture.
+		this.numLods = Math.log( size ) / Math.log( 2 ) - 2; // IE11 doesn't support Math.log2
 
-	}
+		for ( var i = 0; i < this.numLods; i ++ ) {
 
-	this.camera = new THREE.OrthographicCamera( - 1, 1, 1, - 1, 0.0, 1000 );
-
-	this.shader = this.getShader();
-	this.shader.defines[ 'SAMPLES_PER_LEVEL' ] = this.samplesPerLevel;
-	this.planeMesh = new THREE.Mesh( new THREE.PlaneBufferGeometry( 2, 2, 0 ), this.shader );
-	this.planeMesh.material.side = THREE.DoubleSide;
-	this.scene = new THREE.Scene();
-	this.scene.add( this.planeMesh );
-	this.scene.add( this.camera );
-
-	this.shader.uniforms[ 'envMap' ].value = this.sourceTexture;
-	this.shader.envMap = this.sourceTexture;
-
-};
-
-THREE.PMREMGenerator.prototype = {
-
-	constructor: THREE.PMREMGenerator,
-
-	/*
-	 * Prashant Sharma / spidersharma03: More thought and work is needed here.
-	 * Right now it's a kind of a hack to use the previously convolved map to convolve the current one.
-	 * I tried to use the original map to convolve all the lods, but for many textures(specially the high frequency)
-	 * even a high number of samples(1024) dosen't lead to satisfactory results.
-	 * By using the previous convolved maps, a lower number of samples are generally sufficient(right now 32, which
-	 * gives okay results unless we see the reflection very carefully, or zoom in too much), however the math
-	 * goes wrong as the distribution function tries to sample a larger area than what it should be. So I simply scaled
-	 * the roughness by 0.9(totally empirical) to try to visually match the original result.
-	 * The condition "if(i <5)" is also an attemt to make the result match the original result.
-	 * This method requires the most amount of thinking I guess. Here is a paper which we could try to implement in future::
-	 * http://http.developer.nvidia.com/GPUGems3/gpugems3_ch20.html
-	 */
-	update: function ( renderer ) {
-
-		this.shader.uniforms[ 'envMap' ].value = this.sourceTexture;
-		this.shader.envMap = this.sourceTexture;
-
-		var gammaInput = renderer.gammaInput;
-		var gammaOutput = renderer.gammaOutput;
-		var toneMapping = renderer.toneMapping;
-		var toneMappingExposure = renderer.toneMappingExposure;
-		var currentRenderTarget = renderer.getRenderTarget();
-
-		renderer.toneMapping = THREE.LinearToneMapping;
-		renderer.toneMappingExposure = 1.0;
-		renderer.gammaInput = false;
-		renderer.gammaOutput = false;
+			var renderTarget = new THREE.WebGLRenderTargetCube( size, size, params );
+			renderTarget.texture.name = "PMREMGenerator.cube" + i;
+			this.cubeLods.push( renderTarget );
+			size = Math.max( 16, size / 2 );
 
-		for ( var i = 0; i < this.numLods; i ++ ) {
+		}
 
-			var r = i / ( this.numLods - 1 );
-			this.shader.uniforms[ 'roughness' ].value = r * 0.9; // see comment above, pragmatic choice
-			this.shader.uniforms[ 'queryScale' ].value.x = ( i == 0 ) ? - 1 : 1;
-			var size = this.cubeLods[ i ].width;
-			this.shader.uniforms[ 'mapSize' ].value = size;
-			this.renderToCubeMapTarget( renderer, this.cubeLods[ i ] );
+	};
 
-			if ( i < 5 ) this.shader.uniforms[ 'envMap' ].value = this.cubeLods[ i ].texture;
+	PMREMGenerator.prototype = {
 
-		}
+		constructor: PMREMGenerator,
 
-		renderer.setRenderTarget( currentRenderTarget );
-		renderer.toneMapping = toneMapping;
-		renderer.toneMappingExposure = toneMappingExposure;
-		renderer.gammaInput = gammaInput;
-		renderer.gammaOutput = gammaOutput;
+		/*
+		 * Prashant Sharma / spidersharma03: More thought and work is needed here.
+		 * Right now it's a kind of a hack to use the previously convolved map to convolve the current one.
+		 * I tried to use the original map to convolve all the lods, but for many textures(specially the high frequency)
+		 * even a high number of samples(1024) dosen't lead to satisfactory results.
+		 * By using the previous convolved maps, a lower number of samples are generally sufficient(right now 32, which
+		 * gives okay results unless we see the reflection very carefully, or zoom in too much), however the math
+		 * goes wrong as the distribution function tries to sample a larger area than what it should be. So I simply scaled
+		 * the roughness by 0.9(totally empirical) to try to visually match the original result.
+		 * The condition "if(i <5)" is also an attemt to make the result match the original result.
+		 * This method requires the most amount of thinking I guess. Here is a paper which we could try to implement in future::
+		 * https://developer.nvidia.com/gpugems/GPUGems3/gpugems3_ch20.html
+		 */
+		update: function ( renderer ) {
 
-	},
+			// Texture should only be flipped for CubeTexture, not for
+			// a Texture created via THREE.WebGLRenderTargetCube.
+			var tFlip = ( this.sourceTexture.isCubeTexture ) ? - 1 : 1;
 
-	renderToCubeMapTarget: function ( renderer, renderTarget ) {
+			shader.defines[ 'SAMPLES_PER_LEVEL' ] = this.samplesPerLevel;
+			shader.uniforms[ 'faceIndex' ].value = 0;
+			shader.uniforms[ 'envMap' ].value = this.sourceTexture;
+			shader.envMap = this.sourceTexture;
+			shader.needsUpdate = true;
 
-		for ( var i = 0; i < 6; i ++ ) {
+			var gammaInput = renderer.gammaInput;
+			var gammaOutput = renderer.gammaOutput;
+			var toneMapping = renderer.toneMapping;
+			var toneMappingExposure = renderer.toneMappingExposure;
+			var currentRenderTarget = renderer.getRenderTarget();
 
-			this.renderToCubeMapTargetFace( renderer, renderTarget, i );
+			renderer.toneMapping = THREE.LinearToneMapping;
+			renderer.toneMappingExposure = 1.0;
+			renderer.gammaInput = false;
+			renderer.gammaOutput = false;
 
-		}
+			for ( var i = 0; i < this.numLods; i ++ ) {
+
+				var r = i / ( this.numLods - 1 );
+				shader.uniforms[ 'roughness' ].value = r * 0.9; // see comment above, pragmatic choice
+				// Only apply the tFlip for the first LOD
+				shader.uniforms[ 'tFlip' ].value = ( i == 0 ) ? tFlip : 1;
+				var size = this.cubeLods[ i ].width;
+				shader.uniforms[ 'mapSize' ].value = size;
+				this.renderToCubeMapTarget( renderer, this.cubeLods[ i ] );
+
+				if ( i < 5 ) shader.uniforms[ 'envMap' ].value = this.cubeLods[ i ].texture;
+
+			}
+
+			renderer.setRenderTarget( currentRenderTarget );
+			renderer.toneMapping = toneMapping;
+			renderer.toneMappingExposure = toneMappingExposure;
+			renderer.gammaInput = gammaInput;
+			renderer.gammaOutput = gammaOutput;
+
+		},
+
+		renderToCubeMapTarget: function ( renderer, renderTarget ) {
+
+			for ( var i = 0; i < 6; i ++ ) {
+
+				this.renderToCubeMapTargetFace( renderer, renderTarget, i );
+
+			}
 
-	},
+		},
 
-	renderToCubeMapTargetFace: function ( renderer, renderTarget, faceIndex ) {
+		renderToCubeMapTargetFace: function ( renderer, renderTarget, faceIndex ) {
 
-		renderTarget.activeCubeFace = faceIndex;
-		this.shader.uniforms[ 'faceIndex' ].value = faceIndex;
-		renderer.render( this.scene, this.camera, renderTarget, true );
+			renderTarget.activeCubeFace = faceIndex;
+			shader.uniforms[ 'faceIndex' ].value = faceIndex;
+			renderer.render( scene, camera, renderTarget, true );
 
-	},
+		},
 
-	getShader: function () {
+		dispose: function () {
+
+			for ( var i = 0, l = this.cubeLods.length; i < l; i ++ ) {
+
+				this.cubeLods[ i ].dispose();
+
+			}
+
+		},
+
+	};
+
+	function getShader() {
 
 		var shaderMaterial = new THREE.ShaderMaterial( {
 
@@ -149,8 +166,7 @@ THREE.PMREMGenerator.prototype = {
 				"roughness": { value: 0.5 },
 				"mapSize": { value: 0.5 },
 				"envMap": { value: null },
-				"queryScale": { value: new THREE.Vector3( 1, 1, 1 ) },
-				"testColor": { value: new THREE.Vector3( 1, 1, 1 ) },
+				"tFlip": { value: - 1 },
 			},
 
 			vertexShader:
@@ -167,8 +183,7 @@ THREE.PMREMGenerator.prototype = {
 				uniform float roughness;\n\
 				uniform samplerCube envMap;\n\
 				uniform float mapSize;\n\
-				uniform vec3 testColor;\n\
-				uniform vec3 queryScale;\n\
+				uniform float tFlip;\n\
 				\n\
 				float GGXRoughnessToBlinnExponent( const in float ggxRoughness ) {\n\
 					float a = ggxRoughness + 0.0001;\n\
@@ -239,7 +254,8 @@ THREE.PMREMGenerator.prototype = {
 					} else {\n\
 						sampleDirection = vec3(-uv.x, -uv.y, -1.0);\n\
 					}\n\
-					mat3 vecSpace = matrixFromVector(normalize(sampleDirection * queryScale));\n\
+					vec3 correctedDirection = vec3( tFlip * sampleDirection.x, sampleDirection.yz );\n\
+					mat3 vecSpace = matrixFromVector( normalize( correctedDirection ) );\n\
 					vec3 rgbColor = vec3(0.0);\n\
 					const int NumSamples = SAMPLES_PER_LEVEL;\n\
 					vec3 vect;\n\
@@ -251,7 +267,7 @@ THREE.PMREMGenerator.prototype = {
 						vect = ImportanceSampleGGX(vec2(float(i) / float(NumSamples), r), vecSpace, roughness);\n\
 						float dotProd = dot(vect, normalize(sampleDirection));\n\
 						weight += dotProd;\n\
-						vec3 color = envMapTexelToLinear(textureCube(envMap,vect)).rgb;\n\
+						vec3 color = envMapTexelToLinear(textureCube(envMap, vect)).rgb;\n\
 						rgbColor.rgb += color;\n\
 					}\n\
 					rgbColor /= float(NumSamples);\n\
@@ -267,19 +283,8 @@ THREE.PMREMGenerator.prototype = {
 
 		return shaderMaterial;
 
-	},
-
-	dispose: function () {
-
-		for ( var i = 0, l = this.cubeLods.length; i < l; i ++ ) {
-
-			this.cubeLods[ i ].dispose();
-
-		}
-
-		this.planeMesh.geometry.dispose();
-		this.planeMesh.material.dispose();
-
 	}
 
-};
+	return PMREMGenerator;
+
+} )();

+ 8 - 8
examples/js/postprocessing/UnrealBloomPass.js

@@ -30,19 +30,19 @@ THREE.UnrealBloomPass = function ( resolution, strength, radius, threshold ) {
 
 	for ( var i = 0; i < this.nMips; i ++ ) {
 
-		var renderTarget = new THREE.WebGLRenderTarget( resx, resy, pars );
+		var renderTargetHorizonal = new THREE.WebGLRenderTarget( resx, resy, pars );
 
-		renderTarget.texture.name = "UnrealBloomPass.h" + i;
-		renderTarget.texture.generateMipmaps = false;
+		renderTargetHorizonal.texture.name = "UnrealBloomPass.h" + i;
+		renderTargetHorizonal.texture.generateMipmaps = false;
 
-		this.renderTargetsHorizontal.push( renderTarget );
+		this.renderTargetsHorizontal.push( renderTargetHorizonal );
 
-		var renderTarget = new THREE.WebGLRenderTarget( resx, resy, pars );
+		var renderTargetVertical = new THREE.WebGLRenderTarget( resx, resy, pars );
 
-		renderTarget.texture.name = "UnrealBloomPass.v" + i;
-		renderTarget.texture.generateMipmaps = false;
+		renderTargetVertical.texture.name = "UnrealBloomPass.v" + i;
+		renderTargetVertical.texture.generateMipmaps = false;
 
-		this.renderTargetsVertical.push( renderTarget );
+		this.renderTargetsVertical.push( renderTargetVertical );
 
 		resx = Math.round( resx / 2 );
 

+ 0 - 76
examples/js/workers/OffscreenCanvas.js

@@ -1,76 +0,0 @@
-self.importScripts( '../../../build/three.js' );
-
-self.onmessage = function ( message ) {
-
-	var data = message.data;
-	init( data.drawingSurface, data.width, data.height, data.pixelRatio );
-
-};
-
-var camera, scene, renderer, mesh, clock;
-
-function init( offscreen, width, height, pixelRatio ) {
-
-	camera = new THREE.PerspectiveCamera( 70, width / height, 1, 1000 );
-	camera.position.z = 400;
-
-	scene = new THREE.Scene();
-
-	clock = new THREE.Clock();
-
-	// we don't use ImageLoader since it has a DOM dependency (HTML5 image element)
-
-	var loader = new THREE.ImageBitmapLoader();
-
-	loader.load( '../../textures/crate.gif', function ( imageBitmap ) {
-
-		var texture = new THREE.CanvasTexture( imageBitmap );
-		var material = new THREE.MeshBasicMaterial( { map: texture } );
-		var geometry = new THREE.BoxBufferGeometry( 200, 200, 200 );
-		mesh = new THREE.Mesh( geometry, material );
-		scene.add( mesh );
-
-		animate();
-
-	}, null, function () {
-
-		// Workaround for Firefox
-		// https://bugzilla.mozilla.org/show_bug.cgi?id=1335594
-
-		var material = new THREE.MeshBasicMaterial( { color: 0x00ff00 } );
-		var geometry = new THREE.BoxBufferGeometry( 200, 200, 200 );
-		mesh = new THREE.Mesh( geometry, material );
-		scene.add( mesh );
-
-		animate();
-
-	} );
-
-	renderer = new THREE.WebGLRenderer( { antialias: true, canvas: offscreen } );
-	renderer.setPixelRatio( pixelRatio );
-	renderer.setSize( width, height, false );
-
-}
-
-function animate() {
-
-	var delta = clock.getDelta();
-
-	mesh.rotation.x += delta * 0.2;
-	mesh.rotation.y += delta * 0.5;
-
-	renderer.render( scene, camera );
-
-	if ( self.requestAnimationFrame ) {
-
-		self.requestAnimationFrame( animate );
-
-	} else if ( renderer.context.commit ) {
-
-		// Deprecated
-
-		renderer.context.commit().then( animate );
-
-	}
-
-}

BIN
examples/models/gltf/Soldier.glb


BIN
examples/models/skinned/marine/M4.png


BIN
examples/models/skinned/marine/MarineCv2_color.jpg


BIN
examples/models/skinned/marine/m4.blend


Файлын зөрүү хэтэрхий том тул дарагдсан байна
+ 0 - 36
examples/models/skinned/marine/m4.js


Файлын зөрүү хэтэрхий том тул дарагдсан байна
+ 0 - 10
examples/models/skinned/marine/marine_anims.json


BIN
examples/models/skinned/marine/marine_anims_all.blend


Файлын зөрүү хэтэрхий том тул дарагдсан байна
+ 0 - 10
examples/models/skinned/marine/marine_anims_all.json


BIN
examples/models/skinned/marine/marine_anims_core.blend


Файлын зөрүү хэтэрхий том тул дарагдсан байна
+ 0 - 10
examples/models/skinned/marine/marine_anims_core.json


BIN
examples/models/skinned/marine/marine_anims_single.blend


Файлын зөрүү хэтэрхий том тул дарагдсан байна
+ 0 - 10
examples/models/skinned/marine/marine_anims_single.json


BIN
examples/models/skinned/marine/marine_ik.blend


Файлын зөрүү хэтэрхий том тул дарагдсан байна
+ 0 - 10
examples/models/skinned/marine/marine_ik.json


+ 1 - 1
examples/webaudio_orientation.html

@@ -158,6 +158,7 @@
 		camera.add( listener );
 
 		var audioElement = document.getElementById( 'music' );
+		audioElement.play();
 
 		var positionalAudio = new THREE.PositionalAudio( listener );
 		positionalAudio.setMediaElementSource( audioElement );
@@ -184,7 +185,6 @@
 
 			} );
 
-			audioElement.play();
 			boomBox.add( positionalAudio );
 			scene.add( boomBox );
 			animate();

+ 71 - 80
examples/webgl_animation_skinning_blending.html

@@ -20,7 +20,7 @@
 				padding: 5px;
 			}
 			a {
-				color: #bbb;
+				color: #ff0000;
 			}
 			.ac {  /* prevent dat-gui from being selected */
 				-webkit-user-select: none;
@@ -40,17 +40,16 @@
 	<body>
 		<div id="container"></div>
 		<div id="info">
-			<a href="http://threejs.org" target="_blank" rel="noopener">three.js</a> - Skeletal Animation Blending
-			(model from <a href="http://realitymeltdown.com" target="_blank" rel="noopener">realitymeltdown.com</a>)
-			<br><br>camera orbit/zoom/pan with left/middle/right mouse button
-			<br>Note: crossfades are possible with blend weights being set to (1,0,0), (0,1,0) or (0,0,1)
+			<a href="https://threejs.org" target="_blank" rel="noopener">three.js</a> - Skeletal Animation Blending
+			(model from <a href="https://www.mixamo.com/" target="_blank" rel="noopener">mixamo.com</a>)
+			<br/><br/>Note: crossfades are possible with blend weights being set to (1,0,0), (0,1,0) or (0,0,1)
 		</div>
 
 		<script src="../build/three.js"></script>
 
 		<script src="js/WebGL.js"></script>
 		<script src="js/libs/stats.min.js"></script>
-		<script src="js/controls/OrbitControls.js"></script>
+		<script src="js/loaders/GLTFLoader.js"></script>
 		<script src="js/libs/dat.gui.min.js"></script>
 
 		<script>
@@ -61,115 +60,113 @@
 
 			}
 
-			var container = document.getElementById( 'container' );
-
-			var scene, renderer, camera, controls, stats;
-			var mesh, skeleton, mixer;
+			var scene, renderer, camera, stats;
+			var model, skeleton, mixer, clock;
 
 			var crossFadeControls = [];
 
 			var idleAction, walkAction, runAction;
 			var idleWeight, walkWeight, runWeight;
-			var actions;
-			var settings;
-
-			var clock = new THREE.Clock();
+			var actions, settings;
 
 			var singleStepMode = false;
 			var sizeOfNextStep = 0;
 
-			var url = 'models/skinned/marine/marine_anims_core.json';
-
-
-			// Initialize stats (fps display)
-
-			stats = new Stats();
-			container.appendChild( stats.dom );
-
-
-			// Initialize scene, light and renderer
+			init();
 
-			scene = new THREE.Scene();
-			scene.background = new THREE.Color( 0x333333 );
-			scene.add( new THREE.AmbientLight( 0xffffff ) );
+			function init() {
 
-			renderer = new THREE.WebGLRenderer( { antialias: true } );
-			renderer.setPixelRatio( window.devicePixelRatio );
-			renderer.setSize( window.innerWidth, window.innerHeight );
+				var container = document.getElementById( 'container' );
 
-			container.appendChild( renderer.domElement );
+				camera = new THREE.PerspectiveCamera( 45, window.innerWidth / window.innerHeight, 1, 1000 );
+				camera.position.set( 1, 2, - 3 );
+				camera.lookAt( 0, 1, 0 );
 
+				clock = new THREE.Clock();
 
-			// Load skinned mesh
+				scene = new THREE.Scene();
+				scene.background = new THREE.Color( 0xa0a0a0 );
+				scene.fog = new THREE.Fog( 0xa0a0a0, 10, 50 );
 
-			new THREE.ObjectLoader().load( url, function ( loadedObject ) {
+				var hemiLight = new THREE.HemisphereLight( 0xffffff, 0x444444 );
+				hemiLight.position.set( 0, 20, 0 );
+				scene.add( hemiLight );
 
-				loadedObject.traverse( function ( child ) {
+				var dirLight = new THREE.DirectionalLight( 0xffffff );
+				dirLight.position.set( - 3, 10, - 10 );
+				dirLight.castShadow = true;
+				dirLight.shadow.camera.top = 2;
+				dirLight.shadow.camera.bottom = - 2;
+				dirLight.shadow.camera.left = - 2;
+				dirLight.shadow.camera.right = 2;
+				dirLight.shadow.camera.near = 0.1;
+				dirLight.shadow.camera.far = 40;
+				scene.add( dirLight );
 
-					if ( child instanceof THREE.SkinnedMesh ) {
+				// scene.add( new THREE.CameraHelper( light.shadow.camera ) );
 
-						mesh = child;
+				// ground
 
-					}
-
-				} );
-
-				if ( mesh === undefined ) {
-
-					alert( 'Unable to find a SkinnedMesh in this place:\n\n' + url + '\n\n' );
-					return;
+				var mesh = new THREE.Mesh( new THREE.PlaneBufferGeometry( 100, 100 ), new THREE.MeshPhongMaterial( { color: 0x999999, depthWrite: false } ) );
+				mesh.rotation.x = - Math.PI / 2;
+				mesh.receiveShadow = true;
+				scene.add( mesh );
 
-				}
+				var loader = new THREE.GLTFLoader();
+				loader.load( 'models/gltf/Soldier.glb', function ( gltf ) {
 
+					model = gltf.scene;
+					scene.add( model );
 
-				// Add mesh and skeleton helper to scene
+					model.traverse( function ( object ) {
 
-				mesh.rotation.y = - 135 * Math.PI / 180;
-				scene.add( mesh );
+						if ( object.isMesh ) object.castShadow = true;
 
-				skeleton = new THREE.SkeletonHelper( mesh );
-				skeleton.visible = false;
-				scene.add( skeleton );
+					} );
 
+					//
 
-				// Initialize camera and camera controls
+					skeleton = new THREE.SkeletonHelper( model );
+					skeleton.visible = false;
+					scene.add( skeleton );
 
-				var radius = mesh.geometry.boundingSphere.radius;
+					//
 
-				var aspect = window.innerWidth / window.innerHeight;
-				camera = new THREE.PerspectiveCamera( 45, aspect, 1, 10000 );
-				camera.position.set( 0.0, radius, radius * 3.5 );
+					createPanel();
 
-				controls = new THREE.OrbitControls( camera, renderer.domElement );
-				controls.target.set( 0, radius, 0 );
-				controls.update();
 
+					//
 
-				// Create the control panel
+					var animations = gltf.animations;
 
-				createPanel();
+					mixer = new THREE.AnimationMixer( model );
 
+					idleAction = mixer.clipAction( animations[ 0 ] );
+					walkAction = mixer.clipAction( animations[ 3 ] );
+					runAction = mixer.clipAction( animations[ 1 ] );
 
-				// Initialize mixer and clip actions
+					actions = [ idleAction, walkAction, runAction ];
 
-				mixer = new THREE.AnimationMixer( mesh );
+					activateAllActions();
 
-				idleAction = mixer.clipAction( 'idle' );
-				walkAction = mixer.clipAction( 'walk' );
-				runAction = mixer.clipAction( 'run' );
-				actions = [ idleAction, walkAction, runAction ];
+					animate();
 
-				activateAllActions();
+				} );
 
+				renderer = new THREE.WebGLRenderer( { antialias: true } );
+				renderer.setPixelRatio( window.devicePixelRatio );
+				renderer.setSize( window.innerWidth, window.innerHeight );
+				renderer.gammaOutput = true;
+				renderer.gammaFactor = 2.2;
+				renderer.shadowMap.enabled = true;
+				container.appendChild( renderer.domElement );
 
-				// Listen on window resizing and start the render loop
+				stats = new Stats();
+				container.appendChild( stats.dom );
 
 				window.addEventListener( 'resize', onWindowResize, false );
-				animate();
-
-
-			} );
 
+			}
 
 			function createPanel() {
 
@@ -281,7 +278,7 @@
 
 			function showModel( visibility ) {
 
-				mesh.visible = visibility;
+				model.visible = visibility;
 
 			}
 
@@ -310,7 +307,6 @@
 
 			}
 
-
 			function activateAllActions() {
 
 				setWeight( idleAction, settings[ 'modify idle weight' ] );
@@ -325,7 +321,6 @@
 
 			}
 
-
 			function pauseContinue() {
 
 				if ( singleStepMode ) {
@@ -349,7 +344,6 @@
 
 			}
 
-
 			function pauseAllActions() {
 
 				actions.forEach( function ( action ) {
@@ -360,7 +354,6 @@
 
 			}
 
-
 			function unPauseAllActions() {
 
 				actions.forEach( function ( action ) {
@@ -371,7 +364,6 @@
 
 			}
 
-
 			function toSingleStepMode() {
 
 				unPauseAllActions();
@@ -381,7 +373,6 @@
 
 			}
 
-
 			function prepareCrossFade( startAction, endAction, defaultDuration ) {
 
 				// Switch default / custom crossfade duration (according to the user's choice)

+ 7 - 12
examples/webgl_loader_gltf.html

@@ -69,31 +69,26 @@
 				controls.target.set( 0, - 0.2, - 0.2 );
 				controls.update();
 
-				// envmap
-				var path = 'textures/cube/Bridge2/';
-				var format = '.jpg';
-				var envMap = new THREE.CubeTextureLoader().load( [
-					path + 'posx' + format, path + 'negx' + format,
-					path + 'posy' + format, path + 'negy' + format,
-					path + 'posz' + format, path + 'negz' + format
-				] );
+				var urls = [ 'posx.jpg', 'negx.jpg', 'posy.jpg', 'negy.jpg', 'posz.jpg', 'negz.jpg' ];
+				var loader = new THREE.CubeTextureLoader().setPath( 'textures/cube/Bridge2/' );
+				var background = loader.load( urls );
 
 				scene = new THREE.Scene();
-				scene.background = envMap;
+				scene.background = background;
 
 				light = new THREE.HemisphereLight( 0xbbbbff, 0x444422 );
 				light.position.set( 0, 1, 0 );
 				scene.add( light );
 
 				// model
-				var loader = new THREE.GLTFLoader();
-				loader.load( 'models/gltf/DamagedHelmet/glTF/DamagedHelmet.gltf', function ( gltf ) {
+				var loader = new THREE.GLTFLoader().setPath( 'models/gltf/DamagedHelmet/glTF/' );
+				loader.load( 'DamagedHelmet.gltf', function ( gltf ) {
 
 					gltf.scene.traverse( function ( child ) {
 
 						if ( child.isMesh ) {
 
-							child.material.envMap = envMap;
+							child.material.envMap = background;
 
 						}
 

+ 0 - 179
examples/webgl_loader_json.html

@@ -1,179 +0,0 @@
-<!DOCTYPE html>
-<html lang="en">
-	<head>
-		<title>three.js webgl - loader -json</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 {
-				background:#777;
-				padding:0;
-				margin:0;
-				font-weight: bold;
-				overflow:hidden;
-			}
-
-			#info {
-				position: absolute;
-				top: 0px;
-				width: 100%;
-				color: #ffffff;
-				padding: 5px;
-				font-family:Monospace;
-				font-size:13px;
-				text-align:center;
-			}
-
-			a {
-				color: #ffffff;
-			}
-		</style>
-	</head>
-	<body>
-
-		<div id="container"></div>
-		<div id="info">
-			<a href="https://threejs.org" target="_blank" rel="noopener">three.js</a> -
-			monster by <a href="http://www.3drt.com/downloads.htm" target="_blank" rel="noopener">3drt</a>
-		</div>
-
-		<script src="../build/three.js"></script>
-
-		<script src="js/WebGL.js"></script>
-		<script src="js/libs/stats.min.js"></script>
-
-		<script>
-
-			if ( WEBGL.isWebGLAvailable() === false ) {
-
-				document.body.appendChild( WEBGL.getWebGLErrorMessage() );
-
-			}
-
-			var container, stats, clock, mixer;
-			var camera, scene, renderer;
-
-			init();
-			animate();
-
-			function init() {
-
-				container = document.getElementById( 'container' );
-
-				camera = new THREE.PerspectiveCamera( 50, window.innerWidth / window.innerHeight, 1, 2000 );
-				camera.position.set( 2, 4, 5 );
-
-				clock = new THREE.Clock();
-
-				scene = new THREE.Scene();
-				scene.fog = new THREE.FogExp2( 0x000000, 0.035 );
-
-				mixer = new THREE.AnimationMixer( scene );
-
-				var loader = new THREE.JSONLoader();
-				loader.load( 'models/json/legacy/monster/monster.js', function ( geometry, materials ) {
-
-					// adjust color a bit
-
-					var material = materials[ 0 ];
-					material.morphTargets = true;
-					material.color.setHex( 0xffaaaa );
-
-					for ( var i = 0; i < 729; i ++ ) {
-
-						var mesh = new THREE.Mesh( geometry, materials );
-
-						// random placement in a grid
-
-						var x = ( ( i % 27 ) - 13.5 ) * 2 + THREE.Math.randFloatSpread( 1 );
-						var z = ( Math.floor( i / 27 ) - 13.5 ) * 2 + THREE.Math.randFloatSpread( 1 );
-
-						mesh.position.set( x, 0, z );
-
-						var s = THREE.Math.randFloat( 0.00075, 0.001 );
-						mesh.scale.set( s, s, s );
-
-						mesh.rotation.y = THREE.Math.randFloat( - 0.25, 0.25 );
-
-						mesh.matrixAutoUpdate = false;
-						mesh.updateMatrix();
-
-						scene.add( mesh );
-
-						mixer.clipAction( geometry.animations[ 0 ], mesh )
-							.setDuration( 1 )			// one second
-							.startAt( - Math.random() )	// random phase (already running)
-							.play();					// let's go
-
-					}
-
-				} );
-
-				// lights
-
-				var ambientLight = new THREE.AmbientLight( 0xcccccc );
-				scene.add( ambientLight );
-
-				var pointLight = new THREE.PointLight( 0xff4400, 5, 30 );
-				pointLight.position.set( 5, 0, 0 );
-				scene.add( pointLight );
-
-				// renderer
-
-				renderer = new THREE.WebGLRenderer();
-				renderer.setPixelRatio( window.devicePixelRatio );
-				renderer.setSize( window.innerWidth, window.innerHeight );
-				container.appendChild( renderer.domElement );
-
-				// stats
-
-				stats = new Stats();
-				container.appendChild( stats.dom );
-
-				// events
-
-				window.addEventListener( 'resize', onWindowResize, false );
-
-			}
-
-			//
-
-			function onWindowResize() {
-
-				renderer.setSize( window.innerWidth, window.innerHeight );
-
-				camera.aspect = window.innerWidth / window.innerHeight;
-				camera.updateProjectionMatrix();
-
-			}
-
-			//
-
-			function animate() {
-
-				requestAnimationFrame( animate );
-
-				render();
-				stats.update();
-
-			}
-
-			function render() {
-
-				var timer = Date.now() * 0.0005;
-
-				camera.position.x = Math.cos( timer ) * 10;
-				camera.position.y = 4;
-				camera.position.z = Math.sin( timer ) * 10;
-
-				mixer.update( clock.getDelta() );
-
-				camera.lookAt( scene.position );
-
-				renderer.render( scene, camera );
-
-			}
-
-		</script>
-	</body>
-</html>

+ 18 - 10
examples/webgl_materials_cubemap_dynamic.html

@@ -32,6 +32,7 @@
 		<div id="info"><a href="http://threejs.org" target="_blank" rel="noopener">three.js webgl</a> - materials - dynamic cube reflection<br/>Photo by <a href="http://www.flickr.com/photos/jonragnarsson/2294472375/" target="_blank" rel="noopener">J&oacute;n Ragnarsson</a>.</div>
 
 		<script src="../build/three.js"></script>
+		<script src="js/loaders/EquirectangularToCubeGenerator.js"></script>
 
 		<script>
 
@@ -58,17 +59,27 @@
 
 			function init( texture ) {
 
-				camera = new THREE.PerspectiveCamera( 60, window.innerWidth / window.innerHeight, 1, 1000 );
+				renderer = new THREE.WebGLRenderer( { antialias: true } );
+				renderer.setPixelRatio( window.devicePixelRatio );
+				renderer.setSize( window.innerWidth, window.innerHeight );
 
 				scene = new THREE.Scene();
 
-				backgroundMesh = new THREE.Mesh( new THREE.SphereBufferGeometry( 500, 32, 16 ), new THREE.MeshBasicMaterial( { map: texture } ) );
-				backgroundMesh.geometry.scale( - 1, 1, 1 );
-				scene.add( backgroundMesh );
+				camera = new THREE.PerspectiveCamera( 60, window.innerWidth / window.innerHeight, 1, 1000 );
 
-				renderer = new THREE.WebGLRenderer( { antialias: true } );
-				renderer.setPixelRatio( window.devicePixelRatio );
-				renderer.setSize( window.innerWidth, window.innerHeight );
+				// background
+
+				var options = {
+					resolution: 1024,
+
+					generateMipmaps: true,
+					minFilter: THREE.LinearMipMapLinearFilter,
+					magFilter: THREE.LinearFilter
+				};
+
+				scene.background = new THREE.CubemapGenerator( renderer ).fromEquirectangular( texture, options );
+
+				//
 
 				cubeCamera1 = new THREE.CubeCamera( 1, 1000, 256 );
 				cubeCamera1.renderTarget.texture.generateMipmaps = true;
@@ -198,13 +209,11 @@
 				if ( count % 2 === 0 ) {
 
 					material.envMap = cubeCamera1.renderTarget.texture;
-					backgroundMesh.position.copy( cubeCamera2.position );
 					cubeCamera2.update( renderer, scene );
 
 				} else {
 
 					material.envMap = cubeCamera2.renderTarget.texture;
-					backgroundMesh.position.copy( cubeCamera1.position );
 					cubeCamera1.update( renderer, scene );
 
 				}
@@ -213,7 +222,6 @@
 
 				sphere.visible = true;
 
-				backgroundMesh.position.copy( camera.position );
 				renderer.render( scene, camera );
 
 			}

+ 24 - 0
examples/webgl_materials_envmaps.html

@@ -79,6 +79,7 @@
 				textureCube = new THREE.CubeTextureLoader().load( urls );
 				textureCube.format = THREE.RGBFormat;
 				textureCube.mapping = THREE.CubeReflectionMapping;
+				textureCube.encoding = THREE.sRGBEncoding;
 
 				var textureLoader = new THREE.TextureLoader();
 
@@ -86,9 +87,11 @@
 				textureEquirec.mapping = THREE.EquirectangularReflectionMapping;
 				textureEquirec.magFilter = THREE.LinearFilter;
 				textureEquirec.minFilter = THREE.LinearMipMapLinearFilter;
+				textureEquirec.encoding = THREE.sRGBEncoding;
 
 				textureSphere = textureLoader.load( "textures/metal.jpg" );
 				textureSphere.mapping = THREE.SphericalReflectionMapping;
+				textureSphere.encoding = THREE.sRGBEncoding;
 
 				// Materials
 
@@ -103,6 +106,16 @@
 				} );
 
 				equirectMaterial.uniforms[ "tEquirect" ].value = textureEquirec;
+				// enable code injection for non-built-in material
+				Object.defineProperty( equirectMaterial, 'map', {
+
+					get: function () {
+
+						return this.uniforms.tEquirect.value;
+
+					}
+
+				} );
 
 				var cubeShader = THREE.ShaderLib[ "cube" ];
 				var cubeMaterial = new THREE.ShaderMaterial( {
@@ -114,6 +127,15 @@
 				} );
 
 				cubeMaterial.uniforms[ "tCube" ].value = textureCube;
+				Object.defineProperty( cubeMaterial, 'map', {
+
+					get: function () {
+
+						return this.uniforms.tCube.value;
+
+					}
+
+				} );
 
 				// Skybox
 
@@ -136,6 +158,8 @@
 				renderer.setSize( window.innerWidth, window.innerHeight );
 				document.body.appendChild( renderer.domElement );
 
+				renderer.gammaOutput = true;
+
 				//
 
 				var params = {

+ 47 - 47
examples/webgl_materials_envmaps_exr.html

@@ -51,16 +51,20 @@
 
 			}
 
-			var container, stats;
 			var params = {
 				envMap: 'EXR',
 				roughness: 0.0,
 				metalness: 0.0,
-				exposure: 1.0
+				exposure: 1.0,
+				debug: false,
 			};
-			var camera, scene, renderer, controls, objects = [];
+
+			var container, stats;
+			var camera, scene, renderer, controls;
+			var torusMesh, planeMesh;
 			var standardMaterial, floorMaterial;
 			var pngCubeRenderTarget, exrCubeRenderTarget;
+			var pngBackground, exrBackground;
 
 			init();
 			animate();
@@ -74,43 +78,38 @@
 				camera.position.set( 0, 0, 120 );
 
 				scene = new THREE.Scene();
-				scene.background = new THREE.Color( 0x000000 );
 
 				renderer = new THREE.WebGLRenderer();
 				renderer.toneMapping = THREE.LinearToneMapping;
 
-				standardMaterial = new THREE.MeshStandardMaterial( {
-					map: null,
-					color: 0xffffff,
+				//
+
+				var geometry = new THREE.TorusKnotBufferGeometry( 18, 8, 150, 20 );
+				var material = new THREE.MeshStandardMaterial( {
 					metalness: params.roughness,
 					roughness: params.metalness,
 					envMapIntensity: 1.0
 				} );
 
-				var geometry = new THREE.TorusKnotBufferGeometry( 18, 8, 150, 20 );
-
-				var torusMesh1 = new THREE.Mesh( geometry, standardMaterial );
+				torusMesh = new THREE.Mesh( geometry, material );
+				scene.add( torusMesh );
 
-				scene.add( torusMesh1 );
-				objects.push( torusMesh1 );
-
-				floorMaterial = new THREE.MeshBasicMaterial( {
-					color: 0xffffff
-				} );
+				var geometry = new THREE.PlaneBufferGeometry( 200, 200 );
+				var material = new THREE.MeshBasicMaterial();
 
-				var planeGeometry = new THREE.PlaneBufferGeometry( 200, 200 );
-				var planeMesh1 = new THREE.Mesh( planeGeometry, floorMaterial );
-				planeMesh1.position.y = - 50;
-				planeMesh1.rotation.x = - Math.PI * 0.5;
-				scene.add( planeMesh1 );
+				planeMesh = new THREE.Mesh( geometry, material );
+				planeMesh.position.y = - 50;
+				planeMesh.rotation.x = - Math.PI * 0.5;
+				scene.add( planeMesh );
 
 				new THREE.EXRLoader().load( 'textures/piz_compressed.exr', function ( texture ) {
 
 					texture.minFilter = THREE.NearestFilter;
-					texture.magFilter = THREE.NearestFilter;
+					// texture.magFilter = THREE.NearestFilter;
 					texture.encoding = THREE.LinearEncoding;
 
 					var cubemapGenerator = new THREE.EquirectangularToCubeGenerator( texture, { resolution: 512, type: THREE.HalfFloatType } );
+					exrBackground = cubemapGenerator.renderTarget;
 					var cubeMapTexture = cubemapGenerator.update( renderer );
 
 					var pmremGenerator = new THREE.PMREMGenerator( cubeMapTexture );
@@ -122,7 +121,6 @@
 					exrCubeRenderTarget = pmremCubeUVPacker.CubeUVRenderTarget;
 
 					texture.dispose();
-					cubemapGenerator.dispose();
 					pmremGenerator.dispose();
 					pmremCubeUVPacker.dispose();
 
@@ -133,6 +131,8 @@
 					texture.encoding = THREE.sRGBEncoding;
 
 					var cubemapGenerator = new THREE.EquirectangularToCubeGenerator( texture, { resolution: 512 } );
+					pngBackground = cubemapGenerator.renderTarget;
+
 					var cubeMapTexture = cubemapGenerator.update( renderer );
 
 					var pmremGenerator = new THREE.PMREMGenerator( cubeMapTexture );
@@ -144,7 +144,6 @@
 					pngCubeRenderTarget = pmremCubeUVPacker.CubeUVRenderTarget;
 
 					texture.dispose();
-					cubemapGenerator.dispose();
 					pmremGenerator.dispose();
 					pmremCubeUVPacker.dispose();
 
@@ -173,6 +172,7 @@
 				gui.add( params, 'roughness', 0, 1 );
 				gui.add( params, 'metalness', 0, 1 );
 				gui.add( params, 'exposure', 0, 2 );
+				gui.add( params, 'debug', false );
 				gui.open();
 
 			}
@@ -201,40 +201,40 @@
 
 			function render() {
 
-				if ( standardMaterial !== undefined ) {
-
-					standardMaterial.roughness = params.roughness;
-					standardMaterial.metalness = params.metalness;
-
-					var newEnvMap = standardMaterial.envMap;
+				torusMesh.material.roughness = params.roughness;
+				torusMesh.material.metalness = params.metalness;
 
-					switch ( params.envMap ) {
+				var newEnvMap = torusMesh.material.envMap;
+				var background = scene.background;
 
-						case 'EXR': newEnvMap = exrCubeRenderTarget ? exrCubeRenderTarget.texture : null; break;
-						case 'PNG': newEnvMap = pngCubeRenderTarget ? pngCubeRenderTarget.texture : null; break;
+				switch ( params.envMap ) {
 
-					}
+					case 'EXR':
+						newEnvMap = exrCubeRenderTarget ? exrCubeRenderTarget.texture : null;
+						background = exrBackground;
+						break;
+					case 'PNG':
+						newEnvMap = pngCubeRenderTarget ? pngCubeRenderTarget.texture : null;
+						background = pngBackground;
+						break;
 
-					if ( newEnvMap !== standardMaterial.envMap ) {
+				}
 
-						standardMaterial.envMap = newEnvMap;
-						standardMaterial.needsUpdate = true;
+				if ( newEnvMap !== torusMesh.material.envMap ) {
 
-						floorMaterial.map = newEnvMap;
-						floorMaterial.needsUpdate = true;
+					torusMesh.material.envMap = newEnvMap;
+					torusMesh.material.needsUpdate = true;
 
-					}
+					planeMesh.material.map = newEnvMap;
+					planeMesh.material.needsUpdate = true;
 
 				}
 
-				renderer.toneMappingExposure = params.exposure;
+				torusMesh.rotation.y += 0.005;
+				planeMesh.visible = params.debug;
 
-				for ( var i = 0, l = objects.length; i < l; i ++ ) {
-
-					var object = objects[ i ];
-					object.rotation.y += 0.005;
-
-				}
+				scene.background = background;
+				renderer.toneMappingExposure = params.exposure;
 
 				renderer.render( scene, camera );
 

+ 88 - 90
examples/webgl_materials_envmaps_hdr.html

@@ -52,16 +52,19 @@
 
 			}
 
-			var container, stats;
 			var params = {
 				envMap: 'HDR',
 				roughness: 0.0,
 				metalness: 0.0,
-				exposure: 1.0
+				exposure: 1.0,
+				debug: false
 			};
-			var camera, scene, renderer, controls, objects = [];
-			var standardMaterial, floorMaterial;
+
+			var container, stats;
+			var camera, scene, renderer, controls;
+			var torusMesh, planeMesh;
 			var ldrCubeRenderTarget, hdrCubeRenderTarget, rgbmCubeRenderTarget;
+			var ldrCubeMap, hdrCubeMap, rgbmCubeMap;
 
 			init();
 			animate();
@@ -80,94 +83,85 @@
 				renderer = new THREE.WebGLRenderer();
 				renderer.toneMapping = THREE.LinearToneMapping;
 
-				standardMaterial = new THREE.MeshStandardMaterial( {
-					color: 0xffffff,
-					metalness: params.metalness,
-					roughness: params.roughness
-				} );
+				//
 
 				var geometry = new THREE.TorusKnotBufferGeometry( 18, 8, 150, 20 );
-
-				var torusMesh1 = new THREE.Mesh( geometry, standardMaterial );
-
-				scene.add( torusMesh1 );
-				objects.push( torusMesh1 );
-
-				floorMaterial = new THREE.MeshBasicMaterial( {
+				var material = new THREE.MeshStandardMaterial( {
 					color: 0xffffff,
+					metalness: params.metalness,
+					roughness: params.roughness
 				} );
 
-				var planeGeometry = new THREE.PlaneBufferGeometry( 200, 200 );
-				var planeMesh1 = new THREE.Mesh( planeGeometry, floorMaterial );
-				planeMesh1.position.y = - 50;
-				planeMesh1.rotation.x = - Math.PI * 0.5;
-				scene.add( planeMesh1 );
+				torusMesh = new THREE.Mesh( geometry, material );
+				scene.add( torusMesh );
 
-				var genCubeUrls = function ( prefix, postfix ) {
 
-					return [
-						prefix + 'px' + postfix, prefix + 'nx' + postfix,
-						prefix + 'py' + postfix, prefix + 'ny' + postfix,
-						prefix + 'pz' + postfix, prefix + 'nz' + postfix
-					];
+				var geometry = new THREE.PlaneBufferGeometry( 200, 200 );
+				var material = new THREE.MeshBasicMaterial();
 
-				};
+				planeMesh = new THREE.Mesh( geometry, material );
+				planeMesh.position.y = - 50;
+				planeMesh.rotation.x = - Math.PI * 0.5;
+				scene.add( planeMesh );
 
-				var hdrUrls = genCubeUrls( './textures/cube/pisaHDR/', '.hdr' );
-				new THREE.HDRCubeTextureLoader().load( THREE.UnsignedByteType, hdrUrls, function ( hdrCubeMap ) {
+				var hdrUrls = [ 'px.hdr', 'nx.hdr', 'py.hdr', 'ny.hdr', 'pz.hdr', 'nz.hdr' ];
+				hdrCubeMap = new THREE.HDRCubeTextureLoader()
+					.setPath( './textures/cube/pisaHDR/' )
+					.load( THREE.UnsignedByteType, hdrUrls, function () {
 
-					var pmremGenerator = new THREE.PMREMGenerator( hdrCubeMap );
-					pmremGenerator.update( renderer );
+						var pmremGenerator = new THREE.PMREMGenerator( hdrCubeMap );
+						pmremGenerator.update( renderer );
 
-					var pmremCubeUVPacker = new THREE.PMREMCubeUVPacker( pmremGenerator.cubeLods );
-					pmremCubeUVPacker.update( renderer );
+						var pmremCubeUVPacker = new THREE.PMREMCubeUVPacker( pmremGenerator.cubeLods );
+						pmremCubeUVPacker.update( renderer );
 
-					hdrCubeRenderTarget = pmremCubeUVPacker.CubeUVRenderTarget;
+						hdrCubeRenderTarget = pmremCubeUVPacker.CubeUVRenderTarget;
 
-					hdrCubeMap.dispose();
-					pmremGenerator.dispose();
-					pmremCubeUVPacker.dispose();
+						pmremGenerator.dispose();
+						pmremCubeUVPacker.dispose();
 
-				} );
+					} );
 
-				var ldrUrls = genCubeUrls( './textures/cube/pisa/', '.png' );
-				new THREE.CubeTextureLoader().load( ldrUrls, function ( ldrCubeMap ) {
+				var ldrUrls = [ 'px.png', 'nx.png', 'py.png', 'ny.png', 'pz.png', 'nz.png' ];
+				ldrCubeMap = new THREE.CubeTextureLoader()
+					.setPath( './textures/cube/pisa/' )
+					.load( ldrUrls, function () {
 
-					ldrCubeMap.encoding = THREE.GammaEncoding;
+						ldrCubeMap.encoding = THREE.GammaEncoding;
 
-					var pmremGenerator = new THREE.PMREMGenerator( ldrCubeMap );
-					pmremGenerator.update( renderer );
+						var pmremGenerator = new THREE.PMREMGenerator( ldrCubeMap );
+						pmremGenerator.update( renderer );
 
-					var pmremCubeUVPacker = new THREE.PMREMCubeUVPacker( pmremGenerator.cubeLods );
-					pmremCubeUVPacker.update( renderer );
+						var pmremCubeUVPacker = new THREE.PMREMCubeUVPacker( pmremGenerator.cubeLods );
+						pmremCubeUVPacker.update( renderer );
 
-					ldrCubeRenderTarget = pmremCubeUVPacker.CubeUVRenderTarget;
+						ldrCubeRenderTarget = pmremCubeUVPacker.CubeUVRenderTarget;
 
-					ldrCubeMap.dispose();
-					pmremGenerator.dispose();
-					pmremCubeUVPacker.dispose();
+						pmremGenerator.dispose();
+						pmremCubeUVPacker.dispose();
 
-				} );
+					} );
 
 
-				var rgbmUrls = genCubeUrls( './textures/cube/pisaRGBM16/', '.png' );
-				new THREE.CubeTextureLoader().load( rgbmUrls, function ( rgbmCubeMap ) {
+				var rgbmUrls = [ 'px.png', 'nx.png', 'py.png', 'ny.png', 'pz.png', 'nz.png' ];
+				rgbmCubeMap = new THREE.CubeTextureLoader()
+					.setPath( './textures/cube/pisaRGBM16/' )
+					.load( rgbmUrls, function () {
 
-					rgbmCubeMap.encoding = THREE.RGBM16Encoding;
+						rgbmCubeMap.encoding = THREE.RGBM16Encoding;
 
-					var pmremGenerator = new THREE.PMREMGenerator( rgbmCubeMap );
-					pmremGenerator.update( renderer );
+						var pmremGenerator = new THREE.PMREMGenerator( rgbmCubeMap );
+						pmremGenerator.update( renderer );
 
-					var pmremCubeUVPacker = new THREE.PMREMCubeUVPacker( pmremGenerator.cubeLods );
-					pmremCubeUVPacker.update( renderer );
+						var pmremCubeUVPacker = new THREE.PMREMCubeUVPacker( pmremGenerator.cubeLods );
+						pmremCubeUVPacker.update( renderer );
 
-					rgbmCubeRenderTarget = pmremCubeUVPacker.CubeUVRenderTarget;
+						rgbmCubeRenderTarget = pmremCubeUVPacker.CubeUVRenderTarget;
 
-					rgbmCubeMap.dispose();
-					pmremGenerator.dispose();
-					pmremCubeUVPacker.dispose();
+						pmremGenerator.dispose();
+						pmremCubeUVPacker.dispose();
 
-				} );
+					} );
 
 				renderer.setPixelRatio( window.devicePixelRatio );
 				renderer.setSize( window.innerWidth, window.innerHeight );
@@ -192,6 +186,7 @@
 				gui.add( params, 'roughness', 0, 1 );
 				gui.add( params, 'metalness', 0, 1 );
 				gui.add( params, 'exposure', 0, 2 );
+				gui.add( params, 'debug', false );
 				gui.open();
 
 			}
@@ -220,41 +215,44 @@
 
 			function render() {
 
-				if ( standardMaterial !== undefined ) {
-
-					standardMaterial.roughness = params.roughness;
-					standardMaterial.metalness = params.metalness;
-
-					var newEnvMap = standardMaterial.envMap;
-
-					switch ( params.envMap ) {
-
-						case 'LDR': newEnvMap = ldrCubeRenderTarget ? ldrCubeRenderTarget.texture : null; break;
-						case 'HDR': newEnvMap = hdrCubeRenderTarget ? hdrCubeRenderTarget.texture : null; break;
-						case 'RGBM16': newEnvMap = rgbmCubeRenderTarget ? rgbmCubeRenderTarget.texture : null; break;
-
-					}
+				torusMesh.material.roughness = params.roughness;
+				torusMesh.material.metalness = params.metalness;
+
+				var renderTarget, cubeMap;
+
+				switch ( params.envMap ) {
+
+					case 'LDR':
+						renderTarget = ldrCubeRenderTarget;
+						cubeMap = ldrCubeMap;
+						break;
+					case 'HDR':
+						renderTarget = hdrCubeRenderTarget;
+						cubeMap = hdrCubeMap;
+						break;
+					case 'RGBM16':
+						renderTarget = rgbmCubeRenderTarget;
+						cubeMap = rgbmCubeMap;
+						break;
+				}
 
-					if ( newEnvMap !== standardMaterial.envMap ) {
+				var newEnvMap = renderTarget ? renderTarget.texture : null;
 
-						standardMaterial.envMap = newEnvMap;
-						standardMaterial.needsUpdate = true;
+				if ( newEnvMap && newEnvMap !== torusMesh.material.envMap ) {
 
-						floorMaterial.map = newEnvMap;
-						floorMaterial.needsUpdate = true;
+					torusMesh.material.envMap = newEnvMap;
+					torusMesh.material.needsUpdate = true;
 
-					}
+					planeMesh.material.map = newEnvMap;
+					planeMesh.material.needsUpdate = true;
 
 				}
 
-				renderer.toneMappingExposure = params.exposure;
-
-				for ( var i = 0, l = objects.length; i < l; i ++ ) {
+				torusMesh.rotation.y += 0.005;
+				planeMesh.visible = params.debug;
 
-					var object = objects[ i ];
-					object.rotation.y += 0.005;
-
-				}
+				scene.background = cubeMap;
+				renderer.toneMappingExposure = params.exposure;
 
 				renderer.render( scene, camera );
 

+ 8 - 10
examples/webgl_materials_matcap.html

@@ -67,7 +67,7 @@
 			function init() {
 
 				// renderer
-				renderer = new THREE.WebGLRenderer();
+				renderer = new THREE.WebGLRenderer( { antialias: true } );
 				renderer.setPixelRatio( window.devicePixelRatio );
 				renderer.setSize( window.innerWidth, window.innerHeight );
 				document.body.appendChild( renderer.domElement );
@@ -100,8 +100,6 @@
 
 					matcap.encoding = THREE.sRGBEncoding;
 
-					if ( mesh ) mesh.material.needsUpdate = true;
-
 				} );
 
 				// model
@@ -185,18 +183,18 @@
 
 			function imgCallback( event ) {
 
-				var matcap = mesh.material.matcap;
+				if ( mesh.material.matcap ) {
 
-				matcap.image = event.target;
+					mesh.material.matcap.dispose();
 
-				matcap.needsUpdate = true;
+				}
 
-				API.color = 0xffffff;
-				mesh.material.color.set( API.color );
+				mesh.material.matcap = new THREE.Texture( event.target );
+				mesh.material.matcap.needsUpdate = true;
 
-				render();
+				image.src = mesh.material.matcap.image.src; // corner div
 
-				image.src = matcap.image.src; // corner div
+				render();
 
 			}
 

+ 12 - 8
examples/webgl_postprocessing_ssao.html

@@ -90,18 +90,21 @@
 				camera.position.z = 500;
 
 				scene = new THREE.Scene();
-				scene.background = new THREE.Color( 0xa0a0a0 );
+				scene.background = new THREE.Color( 0xaaaaaa );
+
+				scene.add( new THREE.DirectionalLight() );
+				scene.add( new THREE.HemisphereLight() );
 
 				group = new THREE.Group();
 				scene.add( group );
 
-				var geometry = new THREE.IcosahedronBufferGeometry( 5, 3 );
-				for ( var i = 0; i < 200; i ++ ) {
+				var geometry = new THREE.BoxBufferGeometry( 10, 10, 10 );
+
+				for ( var i = 0; i < 100; i ++ ) {
 
-					var material = new THREE.MeshBasicMaterial();
-					material.color.r = Math.random();
-					material.color.g = Math.random();
-					material.color.b = Math.random();
+					var material = new THREE.MeshLambertMaterial( {
+						color: Math.random() * 0xffffff
+					} );
 
 					var mesh = new THREE.Mesh( geometry, material );
 					mesh.position.x = Math.random() * 400 - 200;
@@ -111,7 +114,7 @@
 					mesh.rotation.y = Math.random();
 					mesh.rotation.z = Math.random();
 
-					mesh.scale.setScalar( Math.random() * 10 + 1 );
+					mesh.scale.setScalar( Math.random() * 10 + 2 );
 					group.add( mesh );
 
 				}
@@ -123,6 +126,7 @@
 				var height = window.innerHeight;
 
 				ssaoPass = new THREE.SSAOPass( scene, camera, width, height );
+				ssaoPass.kernelRadius = 16;
 				ssaoPass.renderToScreen = true;
 
 				effectComposer = new THREE.EffectComposer( renderer );

+ 1 - 0
examples/webgl_tiled_forward.html

@@ -51,6 +51,7 @@
 		var RADIUS = 75;
 
 		THREE.ShaderChunk[ 'lights_pars_begin' ] += [
+			'',
 			'#if defined TILED_FORWARD',
 			'uniform vec4 tileData;',
 			'uniform sampler2D tileTexture;',

+ 62 - 37
examples/webgl_worker_offscreencanvas.html

@@ -5,28 +5,29 @@
 		<meta charset="utf-8">
 		<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
 		<style>
+			html, body {
+				height: 100%;
+			}
+
 			body {
-				background:#000000;
-				padding:0;
-				margin:0;
-				font-weight: bold;
-				overflow:hidden;
+				background: #ffffff;
+				padding: 0;
+				margin: 0;
+				font-family: Monospace;
+				font-size: 13px;
+				overflow: hidden;
 			}
 
 			#info {
-				position: absolute;
 				top: 0px;
 				width: 100%;
-				color: #ffffff;
-				padding: 5px;
-				font-family:Monospace;
-				font-size:13px;
-				text-align:center;
+				color: #000000;
+				margin: 6px 0px;
+				text-align: center;
 			}
 
 			#message {
 				color: #ff0000;
-				font-size:14px;
 				display: none;
 			}
 
@@ -34,47 +35,71 @@
 				color: #ff0000;
 			}
 
-			a { color: #ffffff; }
+			#container {
+				width: 100%;
+				height: calc(100% - 80px);
+			}
+
+			#ui {
+				margin-top: 8px;
+				height: 80px;
+				text-align: center;
+			}
+			#button {
+				border: 0;
+				padding: 4px 6px;
+				background: #dddddd;
+				outline: none;
+			}
 		</style>
-		<script src="js/WebGL.js"></script>
 	</head>
 	<body>
 		<div id="info">
-			<a href="https://threejs.org" target="_blank" rel="noopener noreferrer">three.js</a> offscreen canvas<br/><br/>
-			three.js runs in a worker and produces asynchronously frames for the canvas element in the main thread. <br/>
-			This is an <a href="https://developer.mozilla.org/en-US/docs/Web/API/OffscreenCanvas" target="_blank" rel="noopener noreferrer"> experimental feature</a>!
+			<a href="https://threejs.org" target="_blank" rel="noopener noreferrer">three.js</a> - offscreen canvas (<a href="https://developer.mozilla.org/en-US/docs/Web/API/OffscreenCanvas" target="_blank" rel="noopener noreferrer">about</a>)<br/>
 			<p id="message">Your browser does not support OffscreenCanvas. Check the browser support <a href="https://caniuse.com/#feat=offscreencanvas" target="_blank" rel="noopener noreferrer">here</a></p>
 		</div>
 
-		<canvas id="canvas" style="width: 100%; height: 100%"></canvas>
-	</body>
-	<script>
+		<div id="container">
+			<canvas id="canvas1" style="width: 50%; height: 100%"></canvas><canvas id="canvas2" style="width: 50%; height: 100%"></canvas>
+		</div>
+		<div id="ui">
+			<button id="button">START JANK</button><br/>
+			<span id="result"></span>
+		</div>
 
-		if ( WEBGL.isWebGLAvailable() === false ) {
+		<script src="../build/three.js"></script>
+		<script src="js/offscreen/scene.js"></script>
+		<script src="js/offscreen/jank.js"></script>
+		<script>
 
-			document.body.appendChild( WEBGL.getWebGLErrorMessage() );
+			// onscreen
 
-		}
+			var width = canvas1.clientWidth;
+			var height = canvas1.clientHeight;
+			var pixelRatio = window.devicePixelRatio;
 
-		var canvas = document.getElementById( 'canvas' );
+			init( canvas1, width, height, pixelRatio, './' );
 
-		if ( canvas.transferControlToOffscreen !== undefined ) {
+			// offscreen
 
-			var offscreen = canvas.transferControlToOffscreen();
-			var worker = new Worker( 'js/workers/OffscreenCanvas.js' );
+			if ( 'transferControlToOffscreen' in canvas2 ) {
 
-			worker.postMessage( {
-				drawingSurface: offscreen,
-				width: window.innerWidth,
-				height: window.innerHeight,
-				pixelRatio: window.devicePixelRatio
-			}, [ offscreen ] ); // transfer
+				var offscreen = canvas2.transferControlToOffscreen();
+				var worker = new Worker( 'js/offscreen/offscreen.js' );
+				worker.postMessage( {
+					drawingSurface: offscreen,
+					width: canvas2.clientWidth,
+					height: canvas2.clientHeight,
+					pixelRatio: window.devicePixelRatio,
+					path: '../../'
+				}, [ offscreen ] );
 
-		} else {
+			} else {
 
-			document.getElementById( 'message' ).style.display = 'block';
+				document.getElementById( 'message' ).style.display = 'block';
 
-		}
+			}
 
-	</script>
+		</script>
+	</body>
 </html>

+ 4 - 6
examples/webvr_ballshooter.html

@@ -4,12 +4,10 @@
 		<title>three.js webvr - ball shooter</title>
 		<meta charset="utf-8">
 		<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
-		<!-- Origin Trial Token, feature = WebVR (For Chrome M62+), origin = https://threejs.org, expires = 2018-09-11 -->
-		<meta http-equiv="origin-trial" data-feature="WebVR (For Chrome M62+)" data-expires="2018-09-11" content="AqhFUYKxq/d+E8CDT0fuYRCg8TvlTP52x0Jv7I9t27sLhR30LmcahBRfSwzP89ukjs2+ia99VrrLoRyaFAwJVA0AAABQeyJvcmlnaW4iOiJodHRwczovL3RocmVlanMub3JnOjQ0MyIsImZlYXR1cmUiOiJXZWJWUjEuMU02MiIsImV4cGlyeSI6MTUzNjYyNDAwMH0=">
-		<!-- Origin Trial Token, feature = WebXR Device API (For Chrome M69+), origin = https://threejs.org, expires = 2018-12-02 -->
-		<meta http-equiv="origin-trial" data-feature="WebXR Device API (For Chrome M69+)" data-expires="2018-12-02" content="Ah46myef4Ax/+fcLtkeotXmIqnvun4lg4bYbHVttuJvbsWiE4oacrvroId7hbCEb4/byxFHIO6+uwq4pwr6RfQkAAABTeyJvcmlnaW4iOiJodHRwczovL3RocmVlanMub3JnOjQ0MyIsImZlYXR1cmUiOiJXZWJYUkRldmljZU02OSIsImV4cGlyeSI6MTU0Mzc1ODIyNn0=">
-		<!-- Origin Trial Token, feature = WebXR Gamepad Support, origin = https://threejs.org, expires = 2018-12-02 -->
-		<meta http-equiv="origin-trial" data-feature="WebXR Gamepad Support" data-expires="2018-12-02" content="AqI9LIanbGxr/HoTOsYCUNxG82Vy94NZbjhv83R+bF+5NX2jiZOaf7ny+mFoTUP5wrWpYlPjQ6+HeVas9f1lRwYAAABYeyJvcmlnaW4iOiJodHRwczovL3RocmVlanMub3JnOjQ0MyIsImZlYXR1cmUiOiJXZWJYUkdhbWVwYWRTdXBwb3J0IiwiZXhwaXJ5IjoxNTQzNzU4MjI2fQ==">
+		<!-- Origin Trial Token, feature = WebXR Device API (For Chrome M69+), origin = https://threejs.org, expires = 2019-01-07 -->
+		<meta http-equiv="origin-trial" data-feature="WebXR Device API (For Chrome M69+)" data-expires="2019-01-07" content="ArPzyYNrUDiXsGOh647Ya7MtVUA1nM+WFMnPWu7eoF2nQHOP6mTATIbiv0w+k2kFaPofZG/04ZEQdsACq4IA0wQAAABTeyJvcmlnaW4iOiJodHRwczovL3RocmVlanMub3JnOjQ0MyIsImZlYXR1cmUiOiJXZWJYUkRldmljZU02OSIsImV4cGlyeSI6MTU0Njg4MzAxOH0=">
+		<!-- Origin Trial Token, feature = WebXR Gamepad Support, origin = https://threejs.org, expires = 2019-01-07 -->
+		<meta http-equiv="origin-trial" data-feature="WebXR Gamepad Support" data-expires="2019-01-07" content="Av16a8LVXasKVQV9j3u0OlXdTfz5O9qDqhROyL5Up6R3sdOPbtFuc6n6o5DHitwnb5VdirH0GyvROwvz8xxd0AkAAABYeyJvcmlnaW4iOiJodHRwczovL3RocmVlanMub3JnOjQ0MyIsImZlYXR1cmUiOiJXZWJYUkdhbWVwYWRTdXBwb3J0IiwiZXhwaXJ5IjoxNTQ2ODgzMDE4fQ==">
 		<style>
 			body {
 				font-family: Monospace;

+ 4 - 6
examples/webvr_cubes.html

@@ -4,12 +4,10 @@
 		<title>three.js webvr - cubes</title>
 		<meta charset="utf-8">
 		<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
-		<!-- Origin Trial Token, feature = WebVR (For Chrome M62+), origin = https://threejs.org, expires = 2018-09-11 -->
-		<meta http-equiv="origin-trial" data-feature="WebVR (For Chrome M62+)" data-expires="2018-09-11" content="AqhFUYKxq/d+E8CDT0fuYRCg8TvlTP52x0Jv7I9t27sLhR30LmcahBRfSwzP89ukjs2+ia99VrrLoRyaFAwJVA0AAABQeyJvcmlnaW4iOiJodHRwczovL3RocmVlanMub3JnOjQ0MyIsImZlYXR1cmUiOiJXZWJWUjEuMU02MiIsImV4cGlyeSI6MTUzNjYyNDAwMH0=">
-		<!-- Origin Trial Token, feature = WebXR Device API (For Chrome M69+), origin = https://threejs.org, expires = 2018-12-02 -->
-		<meta http-equiv="origin-trial" data-feature="WebXR Device API (For Chrome M69+)" data-expires="2018-12-02" content="Ah46myef4Ax/+fcLtkeotXmIqnvun4lg4bYbHVttuJvbsWiE4oacrvroId7hbCEb4/byxFHIO6+uwq4pwr6RfQkAAABTeyJvcmlnaW4iOiJodHRwczovL3RocmVlanMub3JnOjQ0MyIsImZlYXR1cmUiOiJXZWJYUkRldmljZU02OSIsImV4cGlyeSI6MTU0Mzc1ODIyNn0=">
-		<!-- Origin Trial Token, feature = WebXR Gamepad Support, origin = https://threejs.org, expires = 2018-12-02 -->
-		<meta http-equiv="origin-trial" data-feature="WebXR Gamepad Support" data-expires="2018-12-02" content="AqI9LIanbGxr/HoTOsYCUNxG82Vy94NZbjhv83R+bF+5NX2jiZOaf7ny+mFoTUP5wrWpYlPjQ6+HeVas9f1lRwYAAABYeyJvcmlnaW4iOiJodHRwczovL3RocmVlanMub3JnOjQ0MyIsImZlYXR1cmUiOiJXZWJYUkdhbWVwYWRTdXBwb3J0IiwiZXhwaXJ5IjoxNTQzNzU4MjI2fQ==">
+		<!-- Origin Trial Token, feature = WebXR Device API (For Chrome M69+), origin = https://threejs.org, expires = 2019-01-07 -->
+		<meta http-equiv="origin-trial" data-feature="WebXR Device API (For Chrome M69+)" data-expires="2019-01-07" content="ArPzyYNrUDiXsGOh647Ya7MtVUA1nM+WFMnPWu7eoF2nQHOP6mTATIbiv0w+k2kFaPofZG/04ZEQdsACq4IA0wQAAABTeyJvcmlnaW4iOiJodHRwczovL3RocmVlanMub3JnOjQ0MyIsImZlYXR1cmUiOiJXZWJYUkRldmljZU02OSIsImV4cGlyeSI6MTU0Njg4MzAxOH0=">
+		<!-- Origin Trial Token, feature = WebXR Gamepad Support, origin = https://threejs.org, expires = 2019-01-07 -->
+		<meta http-equiv="origin-trial" data-feature="WebXR Gamepad Support" data-expires="2019-01-07" content="Av16a8LVXasKVQV9j3u0OlXdTfz5O9qDqhROyL5Up6R3sdOPbtFuc6n6o5DHitwnb5VdirH0GyvROwvz8xxd0AkAAABYeyJvcmlnaW4iOiJodHRwczovL3RocmVlanMub3JnOjQ0MyIsImZlYXR1cmUiOiJXZWJYUkdhbWVwYWRTdXBwb3J0IiwiZXhwaXJ5IjoxNTQ2ODgzMDE4fQ==">
 		<style>
 			body {
 				font-family: Monospace;

+ 4 - 6
examples/webvr_dragging.html

@@ -4,12 +4,10 @@
 		<title>three.js webvr - dragging</title>
 		<meta charset="utf-8">
 		<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
-		<!-- Origin Trial Token, feature = WebVR (For Chrome M62+), origin = https://threejs.org, expires = 2018-09-11 -->
-		<meta http-equiv="origin-trial" data-feature="WebVR (For Chrome M62+)" data-expires="2018-09-11" content="AqhFUYKxq/d+E8CDT0fuYRCg8TvlTP52x0Jv7I9t27sLhR30LmcahBRfSwzP89ukjs2+ia99VrrLoRyaFAwJVA0AAABQeyJvcmlnaW4iOiJodHRwczovL3RocmVlanMub3JnOjQ0MyIsImZlYXR1cmUiOiJXZWJWUjEuMU02MiIsImV4cGlyeSI6MTUzNjYyNDAwMH0=">
-		<!-- Origin Trial Token, feature = WebXR Device API (For Chrome M69+), origin = https://threejs.org, expires = 2018-12-02 -->
-		<meta http-equiv="origin-trial" data-feature="WebXR Device API (For Chrome M69+)" data-expires="2018-12-02" content="Ah46myef4Ax/+fcLtkeotXmIqnvun4lg4bYbHVttuJvbsWiE4oacrvroId7hbCEb4/byxFHIO6+uwq4pwr6RfQkAAABTeyJvcmlnaW4iOiJodHRwczovL3RocmVlanMub3JnOjQ0MyIsImZlYXR1cmUiOiJXZWJYUkRldmljZU02OSIsImV4cGlyeSI6MTU0Mzc1ODIyNn0=">
-		<!-- Origin Trial Token, feature = WebXR Gamepad Support, origin = https://threejs.org, expires = 2018-12-02 -->
-		<meta http-equiv="origin-trial" data-feature="WebXR Gamepad Support" data-expires="2018-12-02" content="AqI9LIanbGxr/HoTOsYCUNxG82Vy94NZbjhv83R+bF+5NX2jiZOaf7ny+mFoTUP5wrWpYlPjQ6+HeVas9f1lRwYAAABYeyJvcmlnaW4iOiJodHRwczovL3RocmVlanMub3JnOjQ0MyIsImZlYXR1cmUiOiJXZWJYUkdhbWVwYWRTdXBwb3J0IiwiZXhwaXJ5IjoxNTQzNzU4MjI2fQ==">
+		<!-- Origin Trial Token, feature = WebXR Device API (For Chrome M69+), origin = https://threejs.org, expires = 2019-01-07 -->
+		<meta http-equiv="origin-trial" data-feature="WebXR Device API (For Chrome M69+)" data-expires="2019-01-07" content="ArPzyYNrUDiXsGOh647Ya7MtVUA1nM+WFMnPWu7eoF2nQHOP6mTATIbiv0w+k2kFaPofZG/04ZEQdsACq4IA0wQAAABTeyJvcmlnaW4iOiJodHRwczovL3RocmVlanMub3JnOjQ0MyIsImZlYXR1cmUiOiJXZWJYUkRldmljZU02OSIsImV4cGlyeSI6MTU0Njg4MzAxOH0=">
+		<!-- Origin Trial Token, feature = WebXR Gamepad Support, origin = https://threejs.org, expires = 2019-01-07 -->
+		<meta http-equiv="origin-trial" data-feature="WebXR Gamepad Support" data-expires="2019-01-07" content="Av16a8LVXasKVQV9j3u0OlXdTfz5O9qDqhROyL5Up6R3sdOPbtFuc6n6o5DHitwnb5VdirH0GyvROwvz8xxd0AkAAABYeyJvcmlnaW4iOiJodHRwczovL3RocmVlanMub3JnOjQ0MyIsImZlYXR1cmUiOiJXZWJYUkdhbWVwYWRTdXBwb3J0IiwiZXhwaXJ5IjoxNTQ2ODgzMDE4fQ==">
 		<style>
 			body {
 				font-family: Monospace;

+ 4 - 6
examples/webvr_lorenzattractor.html

@@ -4,12 +4,10 @@
 		<title>three.js webvr - lorenz attractor</title>
 		<meta charset="utf-8">
 		<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
-		<!-- Origin Trial Token, feature = WebVR (For Chrome M62+), origin = https://threejs.org, expires = 2018-09-11 -->
-		<meta http-equiv="origin-trial" data-feature="WebVR (For Chrome M62+)" data-expires="2018-09-11" content="AqhFUYKxq/d+E8CDT0fuYRCg8TvlTP52x0Jv7I9t27sLhR30LmcahBRfSwzP89ukjs2+ia99VrrLoRyaFAwJVA0AAABQeyJvcmlnaW4iOiJodHRwczovL3RocmVlanMub3JnOjQ0MyIsImZlYXR1cmUiOiJXZWJWUjEuMU02MiIsImV4cGlyeSI6MTUzNjYyNDAwMH0=">
-		<!-- Origin Trial Token, feature = WebXR Device API (For Chrome M69+), origin = https://threejs.org, expires = 2018-12-02 -->
-		<meta http-equiv="origin-trial" data-feature="WebXR Device API (For Chrome M69+)" data-expires="2018-12-02" content="Ah46myef4Ax/+fcLtkeotXmIqnvun4lg4bYbHVttuJvbsWiE4oacrvroId7hbCEb4/byxFHIO6+uwq4pwr6RfQkAAABTeyJvcmlnaW4iOiJodHRwczovL3RocmVlanMub3JnOjQ0MyIsImZlYXR1cmUiOiJXZWJYUkRldmljZU02OSIsImV4cGlyeSI6MTU0Mzc1ODIyNn0=">
-		<!-- Origin Trial Token, feature = WebXR Gamepad Support, origin = https://threejs.org, expires = 2018-12-02 -->
-		<meta http-equiv="origin-trial" data-feature="WebXR Gamepad Support" data-expires="2018-12-02" content="AqI9LIanbGxr/HoTOsYCUNxG82Vy94NZbjhv83R+bF+5NX2jiZOaf7ny+mFoTUP5wrWpYlPjQ6+HeVas9f1lRwYAAABYeyJvcmlnaW4iOiJodHRwczovL3RocmVlanMub3JnOjQ0MyIsImZlYXR1cmUiOiJXZWJYUkdhbWVwYWRTdXBwb3J0IiwiZXhwaXJ5IjoxNTQzNzU4MjI2fQ==">
+		<!-- Origin Trial Token, feature = WebXR Device API (For Chrome M69+), origin = https://threejs.org, expires = 2019-01-07 -->
+		<meta http-equiv="origin-trial" data-feature="WebXR Device API (For Chrome M69+)" data-expires="2019-01-07" content="ArPzyYNrUDiXsGOh647Ya7MtVUA1nM+WFMnPWu7eoF2nQHOP6mTATIbiv0w+k2kFaPofZG/04ZEQdsACq4IA0wQAAABTeyJvcmlnaW4iOiJodHRwczovL3RocmVlanMub3JnOjQ0MyIsImZlYXR1cmUiOiJXZWJYUkRldmljZU02OSIsImV4cGlyeSI6MTU0Njg4MzAxOH0=">
+		<!-- Origin Trial Token, feature = WebXR Gamepad Support, origin = https://threejs.org, expires = 2019-01-07 -->
+		<meta http-equiv="origin-trial" data-feature="WebXR Gamepad Support" data-expires="2019-01-07" content="Av16a8LVXasKVQV9j3u0OlXdTfz5O9qDqhROyL5Up6R3sdOPbtFuc6n6o5DHitwnb5VdirH0GyvROwvz8xxd0AkAAABYeyJvcmlnaW4iOiJodHRwczovL3RocmVlanMub3JnOjQ0MyIsImZlYXR1cmUiOiJXZWJYUkdhbWVwYWRTdXBwb3J0IiwiZXhwaXJ5IjoxNTQ2ODgzMDE4fQ==">
 		<style>
 			body {
 				margin: 0px;

+ 4 - 6
examples/webvr_paint.html

@@ -4,12 +4,10 @@
 		<title>three.js webvr - paint</title>
 		<meta charset="utf-8">
 		<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
-		<!-- Origin Trial Token, feature = WebVR (For Chrome M62+), origin = https://threejs.org, expires = 2018-09-11 -->
-		<meta http-equiv="origin-trial" data-feature="WebVR (For Chrome M62+)" data-expires="2018-09-11" content="AqhFUYKxq/d+E8CDT0fuYRCg8TvlTP52x0Jv7I9t27sLhR30LmcahBRfSwzP89ukjs2+ia99VrrLoRyaFAwJVA0AAABQeyJvcmlnaW4iOiJodHRwczovL3RocmVlanMub3JnOjQ0MyIsImZlYXR1cmUiOiJXZWJWUjEuMU02MiIsImV4cGlyeSI6MTUzNjYyNDAwMH0=">
-		<!-- Origin Trial Token, feature = WebXR Device API (For Chrome M69+), origin = https://threejs.org, expires = 2018-12-02 -->
-		<meta http-equiv="origin-trial" data-feature="WebXR Device API (For Chrome M69+)" data-expires="2018-12-02" content="Ah46myef4Ax/+fcLtkeotXmIqnvun4lg4bYbHVttuJvbsWiE4oacrvroId7hbCEb4/byxFHIO6+uwq4pwr6RfQkAAABTeyJvcmlnaW4iOiJodHRwczovL3RocmVlanMub3JnOjQ0MyIsImZlYXR1cmUiOiJXZWJYUkRldmljZU02OSIsImV4cGlyeSI6MTU0Mzc1ODIyNn0=">
-		<!-- Origin Trial Token, feature = WebXR Gamepad Support, origin = https://threejs.org, expires = 2018-12-02 -->
-		<meta http-equiv="origin-trial" data-feature="WebXR Gamepad Support" data-expires="2018-12-02" content="AqI9LIanbGxr/HoTOsYCUNxG82Vy94NZbjhv83R+bF+5NX2jiZOaf7ny+mFoTUP5wrWpYlPjQ6+HeVas9f1lRwYAAABYeyJvcmlnaW4iOiJodHRwczovL3RocmVlanMub3JnOjQ0MyIsImZlYXR1cmUiOiJXZWJYUkdhbWVwYWRTdXBwb3J0IiwiZXhwaXJ5IjoxNTQzNzU4MjI2fQ==">
+		<!-- Origin Trial Token, feature = WebXR Device API (For Chrome M69+), origin = https://threejs.org, expires = 2019-01-07 -->
+		<meta http-equiv="origin-trial" data-feature="WebXR Device API (For Chrome M69+)" data-expires="2019-01-07" content="ArPzyYNrUDiXsGOh647Ya7MtVUA1nM+WFMnPWu7eoF2nQHOP6mTATIbiv0w+k2kFaPofZG/04ZEQdsACq4IA0wQAAABTeyJvcmlnaW4iOiJodHRwczovL3RocmVlanMub3JnOjQ0MyIsImZlYXR1cmUiOiJXZWJYUkRldmljZU02OSIsImV4cGlyeSI6MTU0Njg4MzAxOH0=">
+		<!-- Origin Trial Token, feature = WebXR Gamepad Support, origin = https://threejs.org, expires = 2019-01-07 -->
+		<meta http-equiv="origin-trial" data-feature="WebXR Gamepad Support" data-expires="2019-01-07" content="Av16a8LVXasKVQV9j3u0OlXdTfz5O9qDqhROyL5Up6R3sdOPbtFuc6n6o5DHitwnb5VdirH0GyvROwvz8xxd0AkAAABYeyJvcmlnaW4iOiJodHRwczovL3RocmVlanMub3JnOjQ0MyIsImZlYXR1cmUiOiJXZWJYUkdhbWVwYWRTdXBwb3J0IiwiZXhwaXJ5IjoxNTQ2ODgzMDE4fQ==">
 		<style>
 			body {
 				font-family: Monospace;

+ 4 - 6
examples/webvr_panorama.html

@@ -4,12 +4,10 @@
 		<title>three.js webvr - panorama</title>
 		<meta charset="utf-8">
 		<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
-		<!-- Origin Trial Token, feature = WebVR (For Chrome M62+), origin = https://threejs.org, expires = 2018-09-11 -->
-		<meta http-equiv="origin-trial" data-feature="WebVR (For Chrome M62+)" data-expires="2018-09-11" content="AqhFUYKxq/d+E8CDT0fuYRCg8TvlTP52x0Jv7I9t27sLhR30LmcahBRfSwzP89ukjs2+ia99VrrLoRyaFAwJVA0AAABQeyJvcmlnaW4iOiJodHRwczovL3RocmVlanMub3JnOjQ0MyIsImZlYXR1cmUiOiJXZWJWUjEuMU02MiIsImV4cGlyeSI6MTUzNjYyNDAwMH0=">
-		<!-- Origin Trial Token, feature = WebXR Device API (For Chrome M69+), origin = https://threejs.org, expires = 2018-12-02 -->
-		<meta http-equiv="origin-trial" data-feature="WebXR Device API (For Chrome M69+)" data-expires="2018-12-02" content="Ah46myef4Ax/+fcLtkeotXmIqnvun4lg4bYbHVttuJvbsWiE4oacrvroId7hbCEb4/byxFHIO6+uwq4pwr6RfQkAAABTeyJvcmlnaW4iOiJodHRwczovL3RocmVlanMub3JnOjQ0MyIsImZlYXR1cmUiOiJXZWJYUkRldmljZU02OSIsImV4cGlyeSI6MTU0Mzc1ODIyNn0=">
-		<!-- Origin Trial Token, feature = WebXR Gamepad Support, origin = https://threejs.org, expires = 2018-12-02 -->
-		<meta http-equiv="origin-trial" data-feature="WebXR Gamepad Support" data-expires="2018-12-02" content="AqI9LIanbGxr/HoTOsYCUNxG82Vy94NZbjhv83R+bF+5NX2jiZOaf7ny+mFoTUP5wrWpYlPjQ6+HeVas9f1lRwYAAABYeyJvcmlnaW4iOiJodHRwczovL3RocmVlanMub3JnOjQ0MyIsImZlYXR1cmUiOiJXZWJYUkdhbWVwYWRTdXBwb3J0IiwiZXhwaXJ5IjoxNTQzNzU4MjI2fQ==">
+		<!-- Origin Trial Token, feature = WebXR Device API (For Chrome M69+), origin = https://threejs.org, expires = 2019-01-07 -->
+		<meta http-equiv="origin-trial" data-feature="WebXR Device API (For Chrome M69+)" data-expires="2019-01-07" content="ArPzyYNrUDiXsGOh647Ya7MtVUA1nM+WFMnPWu7eoF2nQHOP6mTATIbiv0w+k2kFaPofZG/04ZEQdsACq4IA0wQAAABTeyJvcmlnaW4iOiJodHRwczovL3RocmVlanMub3JnOjQ0MyIsImZlYXR1cmUiOiJXZWJYUkRldmljZU02OSIsImV4cGlyeSI6MTU0Njg4MzAxOH0=">
+		<!-- Origin Trial Token, feature = WebXR Gamepad Support, origin = https://threejs.org, expires = 2019-01-07 -->
+		<meta http-equiv="origin-trial" data-feature="WebXR Gamepad Support" data-expires="2019-01-07" content="Av16a8LVXasKVQV9j3u0OlXdTfz5O9qDqhROyL5Up6R3sdOPbtFuc6n6o5DHitwnb5VdirH0GyvROwvz8xxd0AkAAABYeyJvcmlnaW4iOiJodHRwczovL3RocmVlanMub3JnOjQ0MyIsImZlYXR1cmUiOiJXZWJYUkdhbWVwYWRTdXBwb3J0IiwiZXhwaXJ5IjoxNTQ2ODgzMDE4fQ==">
 		<style>
 			html, body {
 				background-color: #000;

+ 4 - 6
examples/webvr_rollercoaster.html

@@ -4,12 +4,10 @@
 		<title>three.js webvr - roller coaster</title>
 		<meta charset="utf-8">
 		<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
-		<!-- Origin Trial Token, feature = WebVR (For Chrome M62+), origin = https://threejs.org, expires = 2018-09-11 -->
-		<meta http-equiv="origin-trial" data-feature="WebVR (For Chrome M62+)" data-expires="2018-09-11" content="AqhFUYKxq/d+E8CDT0fuYRCg8TvlTP52x0Jv7I9t27sLhR30LmcahBRfSwzP89ukjs2+ia99VrrLoRyaFAwJVA0AAABQeyJvcmlnaW4iOiJodHRwczovL3RocmVlanMub3JnOjQ0MyIsImZlYXR1cmUiOiJXZWJWUjEuMU02MiIsImV4cGlyeSI6MTUzNjYyNDAwMH0=">
-		<!-- Origin Trial Token, feature = WebXR Device API (For Chrome M69+), origin = https://threejs.org, expires = 2018-12-02 -->
-		<meta http-equiv="origin-trial" data-feature="WebXR Device API (For Chrome M69+)" data-expires="2018-12-02" content="Ah46myef4Ax/+fcLtkeotXmIqnvun4lg4bYbHVttuJvbsWiE4oacrvroId7hbCEb4/byxFHIO6+uwq4pwr6RfQkAAABTeyJvcmlnaW4iOiJodHRwczovL3RocmVlanMub3JnOjQ0MyIsImZlYXR1cmUiOiJXZWJYUkRldmljZU02OSIsImV4cGlyeSI6MTU0Mzc1ODIyNn0=">
-		<!-- Origin Trial Token, feature = WebXR Gamepad Support, origin = https://threejs.org, expires = 2018-12-02 -->
-		<meta http-equiv="origin-trial" data-feature="WebXR Gamepad Support" data-expires="2018-12-02" content="AqI9LIanbGxr/HoTOsYCUNxG82Vy94NZbjhv83R+bF+5NX2jiZOaf7ny+mFoTUP5wrWpYlPjQ6+HeVas9f1lRwYAAABYeyJvcmlnaW4iOiJodHRwczovL3RocmVlanMub3JnOjQ0MyIsImZlYXR1cmUiOiJXZWJYUkdhbWVwYWRTdXBwb3J0IiwiZXhwaXJ5IjoxNTQzNzU4MjI2fQ==">
+		<!-- Origin Trial Token, feature = WebXR Device API (For Chrome M69+), origin = https://threejs.org, expires = 2019-01-07 -->
+		<meta http-equiv="origin-trial" data-feature="WebXR Device API (For Chrome M69+)" data-expires="2019-01-07" content="ArPzyYNrUDiXsGOh647Ya7MtVUA1nM+WFMnPWu7eoF2nQHOP6mTATIbiv0w+k2kFaPofZG/04ZEQdsACq4IA0wQAAABTeyJvcmlnaW4iOiJodHRwczovL3RocmVlanMub3JnOjQ0MyIsImZlYXR1cmUiOiJXZWJYUkRldmljZU02OSIsImV4cGlyeSI6MTU0Njg4MzAxOH0=">
+		<!-- Origin Trial Token, feature = WebXR Gamepad Support, origin = https://threejs.org, expires = 2019-01-07 -->
+		<meta http-equiv="origin-trial" data-feature="WebXR Gamepad Support" data-expires="2019-01-07" content="Av16a8LVXasKVQV9j3u0OlXdTfz5O9qDqhROyL5Up6R3sdOPbtFuc6n6o5DHitwnb5VdirH0GyvROwvz8xxd0AkAAABYeyJvcmlnaW4iOiJodHRwczovL3RocmVlanMub3JnOjQ0MyIsImZlYXR1cmUiOiJXZWJYUkdhbWVwYWRTdXBwb3J0IiwiZXhwaXJ5IjoxNTQ2ODgzMDE4fQ==">
 		<style>
 			body {
 				margin: 0px;

+ 4 - 6
examples/webvr_sandbox.html

@@ -4,12 +4,10 @@
 		<title>three.js webvr - sandbox</title>
 		<meta charset="utf-8">
 		<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
-		<!-- Origin Trial Token, feature = WebVR (For Chrome M62+), origin = https://threejs.org, expires = 2018-09-11 -->
-		<meta http-equiv="origin-trial" data-feature="WebVR (For Chrome M62+)" data-expires="2018-09-11" content="AqhFUYKxq/d+E8CDT0fuYRCg8TvlTP52x0Jv7I9t27sLhR30LmcahBRfSwzP89ukjs2+ia99VrrLoRyaFAwJVA0AAABQeyJvcmlnaW4iOiJodHRwczovL3RocmVlanMub3JnOjQ0MyIsImZlYXR1cmUiOiJXZWJWUjEuMU02MiIsImV4cGlyeSI6MTUzNjYyNDAwMH0=">
-		<!-- Origin Trial Token, feature = WebXR Device API (For Chrome M69+), origin = https://threejs.org, expires = 2018-12-02 -->
-		<meta http-equiv="origin-trial" data-feature="WebXR Device API (For Chrome M69+)" data-expires="2018-12-02" content="Ah46myef4Ax/+fcLtkeotXmIqnvun4lg4bYbHVttuJvbsWiE4oacrvroId7hbCEb4/byxFHIO6+uwq4pwr6RfQkAAABTeyJvcmlnaW4iOiJodHRwczovL3RocmVlanMub3JnOjQ0MyIsImZlYXR1cmUiOiJXZWJYUkRldmljZU02OSIsImV4cGlyeSI6MTU0Mzc1ODIyNn0=">
-		<!-- Origin Trial Token, feature = WebXR Gamepad Support, origin = https://threejs.org, expires = 2018-12-02 -->
-		<meta http-equiv="origin-trial" data-feature="WebXR Gamepad Support" data-expires="2018-12-02" content="AqI9LIanbGxr/HoTOsYCUNxG82Vy94NZbjhv83R+bF+5NX2jiZOaf7ny+mFoTUP5wrWpYlPjQ6+HeVas9f1lRwYAAABYeyJvcmlnaW4iOiJodHRwczovL3RocmVlanMub3JnOjQ0MyIsImZlYXR1cmUiOiJXZWJYUkdhbWVwYWRTdXBwb3J0IiwiZXhwaXJ5IjoxNTQzNzU4MjI2fQ==">
+		<!-- Origin Trial Token, feature = WebXR Device API (For Chrome M69+), origin = https://threejs.org, expires = 2019-01-07 -->
+		<meta http-equiv="origin-trial" data-feature="WebXR Device API (For Chrome M69+)" data-expires="2019-01-07" content="ArPzyYNrUDiXsGOh647Ya7MtVUA1nM+WFMnPWu7eoF2nQHOP6mTATIbiv0w+k2kFaPofZG/04ZEQdsACq4IA0wQAAABTeyJvcmlnaW4iOiJodHRwczovL3RocmVlanMub3JnOjQ0MyIsImZlYXR1cmUiOiJXZWJYUkRldmljZU02OSIsImV4cGlyeSI6MTU0Njg4MzAxOH0=">
+		<!-- Origin Trial Token, feature = WebXR Gamepad Support, origin = https://threejs.org, expires = 2019-01-07 -->
+		<meta http-equiv="origin-trial" data-feature="WebXR Gamepad Support" data-expires="2019-01-07" content="Av16a8LVXasKVQV9j3u0OlXdTfz5O9qDqhROyL5Up6R3sdOPbtFuc6n6o5DHitwnb5VdirH0GyvROwvz8xxd0AkAAABYeyJvcmlnaW4iOiJodHRwczovL3RocmVlanMub3JnOjQ0MyIsImZlYXR1cmUiOiJXZWJYUkdhbWVwYWRTdXBwb3J0IiwiZXhwaXJ5IjoxNTQ2ODgzMDE4fQ==">
 		<style>
 			body {
 				margin: 0px;

+ 4 - 6
examples/webvr_sculpt.html

@@ -4,12 +4,10 @@
 		<title>three.js webvr - sculpt</title>
 		<meta charset="utf-8">
 		<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
-		<!-- Origin Trial Token, feature = WebVR (For Chrome M62+), origin = https://threejs.org, expires = 2018-09-11 -->
-		<meta http-equiv="origin-trial" data-feature="WebVR (For Chrome M62+)" data-expires="2018-09-11" content="AqhFUYKxq/d+E8CDT0fuYRCg8TvlTP52x0Jv7I9t27sLhR30LmcahBRfSwzP89ukjs2+ia99VrrLoRyaFAwJVA0AAABQeyJvcmlnaW4iOiJodHRwczovL3RocmVlanMub3JnOjQ0MyIsImZlYXR1cmUiOiJXZWJWUjEuMU02MiIsImV4cGlyeSI6MTUzNjYyNDAwMH0=">
-		<!-- Origin Trial Token, feature = WebXR Device API (For Chrome M69+), origin = https://threejs.org, expires = 2018-12-02 -->
-		<meta http-equiv="origin-trial" data-feature="WebXR Device API (For Chrome M69+)" data-expires="2018-12-02" content="Ah46myef4Ax/+fcLtkeotXmIqnvun4lg4bYbHVttuJvbsWiE4oacrvroId7hbCEb4/byxFHIO6+uwq4pwr6RfQkAAABTeyJvcmlnaW4iOiJodHRwczovL3RocmVlanMub3JnOjQ0MyIsImZlYXR1cmUiOiJXZWJYUkRldmljZU02OSIsImV4cGlyeSI6MTU0Mzc1ODIyNn0=">
-		<!-- Origin Trial Token, feature = WebXR Gamepad Support, origin = https://threejs.org, expires = 2018-12-02 -->
-		<meta http-equiv="origin-trial" data-feature="WebXR Gamepad Support" data-expires="2018-12-02" content="AqI9LIanbGxr/HoTOsYCUNxG82Vy94NZbjhv83R+bF+5NX2jiZOaf7ny+mFoTUP5wrWpYlPjQ6+HeVas9f1lRwYAAABYeyJvcmlnaW4iOiJodHRwczovL3RocmVlanMub3JnOjQ0MyIsImZlYXR1cmUiOiJXZWJYUkdhbWVwYWRTdXBwb3J0IiwiZXhwaXJ5IjoxNTQzNzU4MjI2fQ==">
+		<!-- Origin Trial Token, feature = WebXR Device API (For Chrome M69+), origin = https://threejs.org, expires = 2019-01-07 -->
+		<meta http-equiv="origin-trial" data-feature="WebXR Device API (For Chrome M69+)" data-expires="2019-01-07" content="ArPzyYNrUDiXsGOh647Ya7MtVUA1nM+WFMnPWu7eoF2nQHOP6mTATIbiv0w+k2kFaPofZG/04ZEQdsACq4IA0wQAAABTeyJvcmlnaW4iOiJodHRwczovL3RocmVlanMub3JnOjQ0MyIsImZlYXR1cmUiOiJXZWJYUkRldmljZU02OSIsImV4cGlyeSI6MTU0Njg4MzAxOH0=">
+		<!-- Origin Trial Token, feature = WebXR Gamepad Support, origin = https://threejs.org, expires = 2019-01-07 -->
+		<meta http-equiv="origin-trial" data-feature="WebXR Gamepad Support" data-expires="2019-01-07" content="Av16a8LVXasKVQV9j3u0OlXdTfz5O9qDqhROyL5Up6R3sdOPbtFuc6n6o5DHitwnb5VdirH0GyvROwvz8xxd0AkAAABYeyJvcmlnaW4iOiJodHRwczovL3RocmVlanMub3JnOjQ0MyIsImZlYXR1cmUiOiJXZWJYUkdhbWVwYWRTdXBwb3J0IiwiZXhwaXJ5IjoxNTQ2ODgzMDE4fQ==">
 		<style>
 			body {
 				font-family: Monospace;

+ 4 - 6
examples/webvr_video.html

@@ -4,12 +4,10 @@
 		<title>three.js webvr - 360 stereo video</title>
 		<meta charset="utf-8">
 		<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
-		<!-- Origin Trial Token, feature = WebVR (For Chrome M62+), origin = https://threejs.org, expires = 2018-09-11 -->
-		<meta http-equiv="origin-trial" data-feature="WebVR (For Chrome M62+)" data-expires="2018-09-11" content="AqhFUYKxq/d+E8CDT0fuYRCg8TvlTP52x0Jv7I9t27sLhR30LmcahBRfSwzP89ukjs2+ia99VrrLoRyaFAwJVA0AAABQeyJvcmlnaW4iOiJodHRwczovL3RocmVlanMub3JnOjQ0MyIsImZlYXR1cmUiOiJXZWJWUjEuMU02MiIsImV4cGlyeSI6MTUzNjYyNDAwMH0=">
-		<!-- Origin Trial Token, feature = WebXR Device API (For Chrome M69+), origin = https://threejs.org, expires = 2018-12-02 -->
-		<meta http-equiv="origin-trial" data-feature="WebXR Device API (For Chrome M69+)" data-expires="2018-12-02" content="Ah46myef4Ax/+fcLtkeotXmIqnvun4lg4bYbHVttuJvbsWiE4oacrvroId7hbCEb4/byxFHIO6+uwq4pwr6RfQkAAABTeyJvcmlnaW4iOiJodHRwczovL3RocmVlanMub3JnOjQ0MyIsImZlYXR1cmUiOiJXZWJYUkRldmljZU02OSIsImV4cGlyeSI6MTU0Mzc1ODIyNn0=">
-		<!-- Origin Trial Token, feature = WebXR Gamepad Support, origin = https://threejs.org, expires = 2018-12-02 -->
-		<meta http-equiv="origin-trial" data-feature="WebXR Gamepad Support" data-expires="2018-12-02" content="AqI9LIanbGxr/HoTOsYCUNxG82Vy94NZbjhv83R+bF+5NX2jiZOaf7ny+mFoTUP5wrWpYlPjQ6+HeVas9f1lRwYAAABYeyJvcmlnaW4iOiJodHRwczovL3RocmVlanMub3JnOjQ0MyIsImZlYXR1cmUiOiJXZWJYUkdhbWVwYWRTdXBwb3J0IiwiZXhwaXJ5IjoxNTQzNzU4MjI2fQ==">
+		<!-- Origin Trial Token, feature = WebXR Device API (For Chrome M69+), origin = https://threejs.org, expires = 2019-01-07 -->
+		<meta http-equiv="origin-trial" data-feature="WebXR Device API (For Chrome M69+)" data-expires="2019-01-07" content="ArPzyYNrUDiXsGOh647Ya7MtVUA1nM+WFMnPWu7eoF2nQHOP6mTATIbiv0w+k2kFaPofZG/04ZEQdsACq4IA0wQAAABTeyJvcmlnaW4iOiJodHRwczovL3RocmVlanMub3JnOjQ0MyIsImZlYXR1cmUiOiJXZWJYUkRldmljZU02OSIsImV4cGlyeSI6MTU0Njg4MzAxOH0=">
+		<!-- Origin Trial Token, feature = WebXR Gamepad Support, origin = https://threejs.org, expires = 2019-01-07 -->
+		<meta http-equiv="origin-trial" data-feature="WebXR Gamepad Support" data-expires="2019-01-07" content="Av16a8LVXasKVQV9j3u0OlXdTfz5O9qDqhROyL5Up6R3sdOPbtFuc6n6o5DHitwnb5VdirH0GyvROwvz8xxd0AkAAABYeyJvcmlnaW4iOiJodHRwczovL3RocmVlanMub3JnOjQ0MyIsImZlYXR1cmUiOiJXZWJYUkdhbWVwYWRTdXBwb3J0IiwiZXhwaXJ5IjoxNTQ2ODgzMDE4fQ==">
 		<style>
 			body {
 				font-family: Monospace;

+ 4 - 6
examples/webvr_vive_paint.html

@@ -4,12 +4,10 @@
 		<title>three.js webvr - htc vive - paint</title>
 		<meta charset="utf-8">
 		<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
-		<!-- Origin Trial Token, feature = WebVR (For Chrome M62+), origin = https://threejs.org, expires = 2018-09-11 -->
-		<meta http-equiv="origin-trial" data-feature="WebVR (For Chrome M62+)" data-expires="2018-09-11" content="AqhFUYKxq/d+E8CDT0fuYRCg8TvlTP52x0Jv7I9t27sLhR30LmcahBRfSwzP89ukjs2+ia99VrrLoRyaFAwJVA0AAABQeyJvcmlnaW4iOiJodHRwczovL3RocmVlanMub3JnOjQ0MyIsImZlYXR1cmUiOiJXZWJWUjEuMU02MiIsImV4cGlyeSI6MTUzNjYyNDAwMH0=">
-		<!-- Origin Trial Token, feature = WebXR Device API (For Chrome M69+), origin = https://threejs.org, expires = 2018-12-02 -->
-		<meta http-equiv="origin-trial" data-feature="WebXR Device API (For Chrome M69+)" data-expires="2018-12-02" content="Ah46myef4Ax/+fcLtkeotXmIqnvun4lg4bYbHVttuJvbsWiE4oacrvroId7hbCEb4/byxFHIO6+uwq4pwr6RfQkAAABTeyJvcmlnaW4iOiJodHRwczovL3RocmVlanMub3JnOjQ0MyIsImZlYXR1cmUiOiJXZWJYUkRldmljZU02OSIsImV4cGlyeSI6MTU0Mzc1ODIyNn0=">
-		<!-- Origin Trial Token, feature = WebXR Gamepad Support, origin = https://threejs.org, expires = 2018-12-02 -->
-		<meta http-equiv="origin-trial" data-feature="WebXR Gamepad Support" data-expires="2018-12-02" content="AqI9LIanbGxr/HoTOsYCUNxG82Vy94NZbjhv83R+bF+5NX2jiZOaf7ny+mFoTUP5wrWpYlPjQ6+HeVas9f1lRwYAAABYeyJvcmlnaW4iOiJodHRwczovL3RocmVlanMub3JnOjQ0MyIsImZlYXR1cmUiOiJXZWJYUkdhbWVwYWRTdXBwb3J0IiwiZXhwaXJ5IjoxNTQzNzU4MjI2fQ==">
+		<!-- Origin Trial Token, feature = WebXR Device API (For Chrome M69+), origin = https://threejs.org, expires = 2019-01-07 -->
+		<meta http-equiv="origin-trial" data-feature="WebXR Device API (For Chrome M69+)" data-expires="2019-01-07" content="ArPzyYNrUDiXsGOh647Ya7MtVUA1nM+WFMnPWu7eoF2nQHOP6mTATIbiv0w+k2kFaPofZG/04ZEQdsACq4IA0wQAAABTeyJvcmlnaW4iOiJodHRwczovL3RocmVlanMub3JnOjQ0MyIsImZlYXR1cmUiOiJXZWJYUkRldmljZU02OSIsImV4cGlyeSI6MTU0Njg4MzAxOH0=">
+		<!-- Origin Trial Token, feature = WebXR Gamepad Support, origin = https://threejs.org, expires = 2019-01-07 -->
+		<meta http-equiv="origin-trial" data-feature="WebXR Gamepad Support" data-expires="2019-01-07" content="Av16a8LVXasKVQV9j3u0OlXdTfz5O9qDqhROyL5Up6R3sdOPbtFuc6n6o5DHitwnb5VdirH0GyvROwvz8xxd0AkAAABYeyJvcmlnaW4iOiJodHRwczovL3RocmVlanMub3JnOjQ0MyIsImZlYXR1cmUiOiJXZWJYUkdhbWVwYWRTdXBwb3J0IiwiZXhwaXJ5IjoxNTQ2ODgzMDE4fQ==">
 		<style>
 			body {
 				font-family: Monospace;

+ 4 - 6
examples/webvr_vive_sculpt.html

@@ -4,12 +4,10 @@
 		<title>three.js webvr - htc vive - sculpt</title>
 		<meta charset="utf-8">
 		<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
-		<!-- Origin Trial Token, feature = WebVR (For Chrome M62+), origin = https://threejs.org, expires = 2018-09-11 -->
-		<meta http-equiv="origin-trial" data-feature="WebVR (For Chrome M62+)" data-expires="2018-09-11" content="AqhFUYKxq/d+E8CDT0fuYRCg8TvlTP52x0Jv7I9t27sLhR30LmcahBRfSwzP89ukjs2+ia99VrrLoRyaFAwJVA0AAABQeyJvcmlnaW4iOiJodHRwczovL3RocmVlanMub3JnOjQ0MyIsImZlYXR1cmUiOiJXZWJWUjEuMU02MiIsImV4cGlyeSI6MTUzNjYyNDAwMH0=">
-		<!-- Origin Trial Token, feature = WebXR Device API (For Chrome M69+), origin = https://threejs.org, expires = 2018-12-02 -->
-		<meta http-equiv="origin-trial" data-feature="WebXR Device API (For Chrome M69+)" data-expires="2018-12-02" content="Ah46myef4Ax/+fcLtkeotXmIqnvun4lg4bYbHVttuJvbsWiE4oacrvroId7hbCEb4/byxFHIO6+uwq4pwr6RfQkAAABTeyJvcmlnaW4iOiJodHRwczovL3RocmVlanMub3JnOjQ0MyIsImZlYXR1cmUiOiJXZWJYUkRldmljZU02OSIsImV4cGlyeSI6MTU0Mzc1ODIyNn0=">
-		<!-- Origin Trial Token, feature = WebXR Gamepad Support, origin = https://threejs.org, expires = 2018-12-02 -->
-		<meta http-equiv="origin-trial" data-feature="WebXR Gamepad Support" data-expires="2018-12-02" content="AqI9LIanbGxr/HoTOsYCUNxG82Vy94NZbjhv83R+bF+5NX2jiZOaf7ny+mFoTUP5wrWpYlPjQ6+HeVas9f1lRwYAAABYeyJvcmlnaW4iOiJodHRwczovL3RocmVlanMub3JnOjQ0MyIsImZlYXR1cmUiOiJXZWJYUkdhbWVwYWRTdXBwb3J0IiwiZXhwaXJ5IjoxNTQzNzU4MjI2fQ==">
+		<!-- Origin Trial Token, feature = WebXR Device API (For Chrome M69+), origin = https://threejs.org, expires = 2019-01-07 -->
+		<meta http-equiv="origin-trial" data-feature="WebXR Device API (For Chrome M69+)" data-expires="2019-01-07" content="ArPzyYNrUDiXsGOh647Ya7MtVUA1nM+WFMnPWu7eoF2nQHOP6mTATIbiv0w+k2kFaPofZG/04ZEQdsACq4IA0wQAAABTeyJvcmlnaW4iOiJodHRwczovL3RocmVlanMub3JnOjQ0MyIsImZlYXR1cmUiOiJXZWJYUkRldmljZU02OSIsImV4cGlyeSI6MTU0Njg4MzAxOH0=">
+		<!-- Origin Trial Token, feature = WebXR Gamepad Support, origin = https://threejs.org, expires = 2019-01-07 -->
+		<meta http-equiv="origin-trial" data-feature="WebXR Gamepad Support" data-expires="2019-01-07" content="Av16a8LVXasKVQV9j3u0OlXdTfz5O9qDqhROyL5Up6R3sdOPbtFuc6n6o5DHitwnb5VdirH0GyvROwvz8xxd0AkAAABYeyJvcmlnaW4iOiJodHRwczovL3RocmVlanMub3JnOjQ0MyIsImZlYXR1cmUiOiJXZWJYUkdhbWVwYWRTdXBwb3J0IiwiZXhwaXJ5IjoxNTQ2ODgzMDE4fQ==">
 		<style>
 			body {
 				font-family: Monospace;

+ 1 - 1
package.json

@@ -1,6 +1,6 @@
 {
   "name": "three",
-  "version": "0.98.0",
+  "version": "0.99.0",
   "description": "JavaScript 3D library",
   "main": "build/three.js",
   "repository": "mrdoob/three.js",

+ 15 - 12
src/Three.Legacy.js

@@ -44,7 +44,6 @@ import { FileLoader } from './loaders/FileLoader.js';
 import { AudioLoader } from './loaders/AudioLoader.js';
 import { CubeTextureLoader } from './loaders/CubeTextureLoader.js';
 import { DataTextureLoader } from './loaders/DataTextureLoader.js';
-import { JSONLoader } from './loaders/JSONLoader.js';
 import { ObjectLoader } from './loaders/ObjectLoader.js';
 import { TextureLoader } from './loaders/TextureLoader.js';
 import { Material } from './materials/Material.js';
@@ -71,6 +70,7 @@ import { LOD } from './objects/LOD.js';
 import { Points } from './objects/Points.js';
 import { Sprite } from './objects/Sprite.js';
 import { Skeleton } from './objects/Skeleton.js';
+import { SkinnedMesh } from './objects/SkinnedMesh.js';
 import { WebGLRenderer } from './renderers/WebGLRenderer.js';
 import { WebGLRenderTarget } from './renderers/WebGLRenderTarget.js';
 import { WebGLShadowMap } from './renderers/webgl/WebGLShadowMap.js';
@@ -437,17 +437,6 @@ export function BinaryTextureLoader( manager ) {
 
 }
 
-Object.assign( JSONLoader.prototype, {
-
-	setTexturePath: function ( value ) {
-
-		console.warn( 'THREE.JSONLoader: .setTexturePath() has been renamed to .setResourcePath().' );
-		return this.setResourcePath( value );
-
-	}
-
-} );
-
 Object.assign( ObjectLoader.prototype, {
 
 	setTexturePath: function ( value ) {
@@ -1012,6 +1001,12 @@ Object.defineProperty( Skeleton.prototype, 'useVertexTexture', {
 
 } );
 
+SkinnedMesh.prototype.initBones = function () {
+
+	console.error( 'THREE.SkinnedMesh: initBones() has been removed.' );
+
+};
+
 Object.defineProperty( Curve.prototype, '__arcLengthDivisions', {
 
 	get: function () {
@@ -1893,6 +1888,14 @@ export function CanvasRenderer() {
 
 //
 
+export function JSONLoader() {
+
+	console.error( 'THREE.JSONLoader has been removed.' );
+
+}
+
+//
+
 export var SceneUtils = {
 
 	createMultiMaterialObject: function ( /* geometry, materials */ ) {

+ 0 - 1
src/Three.js

@@ -40,7 +40,6 @@ export { ObjectLoader } from './loaders/ObjectLoader.js';
 export { MaterialLoader } from './loaders/MaterialLoader.js';
 export { BufferGeometryLoader } from './loaders/BufferGeometryLoader.js';
 export { DefaultLoadingManager, LoadingManager } from './loaders/LoadingManager.js';
-export { JSONLoader } from './loaders/JSONLoader.js';
 export { ImageLoader } from './loaders/ImageLoader.js';
 export { ImageBitmapLoader } from './loaders/ImageBitmapLoader.js';
 export { FontLoader } from './loaders/FontLoader.js';

+ 23 - 1
src/audio/Audio.js

@@ -20,6 +20,7 @@ function Audio( listener ) {
 	this.autoplay = false;
 
 	this.buffer = null;
+	this.detune = 0;
 	this.loop = false;
 	this.startTime = 0;
 	this.offset = 0;
@@ -94,6 +95,7 @@ Audio.prototype = Object.assign( Object.create( Object3D.prototype ), {
 		var source = this.context.createBufferSource();
 
 		source.buffer = this.buffer;
+		source.detune.value = this.detune;
 		source.loop = this.loop;
 		source.onended = this.onEnded.bind( this );
 		source.playbackRate.setValueAtTime( this.playbackRate, this.startTime );
@@ -222,6 +224,26 @@ Audio.prototype = Object.assign( Object.create( Object3D.prototype ), {
 
 	},
 
+	setDetune: function ( value ) {
+
+		this.detune = value;
+
+		if ( this.isPlaying === true ) {
+
+			this.source.detune.setTargetAtTime( this.detune, this.context.currentTime, 0.01 );
+
+		}
+
+		return this;
+
+	},
+
+	getDetune: function () {
+
+		return this.detune;
+
+	},
+
 	getFilter: function () {
 
 		return this.getFilters()[ 0 ];
@@ -247,7 +269,7 @@ Audio.prototype = Object.assign( Object.create( Object3D.prototype ), {
 
 		if ( this.isPlaying === true ) {
 
-			this.source.playbackRate.setValueAtTime( this.playbackRate, this.context.currentTime );
+			this.source.playbackRate.setTargetAtTime( this.playbackRate, this.context.currentTime, 0.01 );
 
 		}
 

+ 1 - 1
src/constants.js

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

+ 2 - 4
src/helpers/SpotLightHelper.js

@@ -69,7 +69,6 @@ SpotLightHelper.prototype.dispose = function () {
 SpotLightHelper.prototype.update = function () {
 
 	var vector = new Vector3();
-	var vector2 = new Vector3();
 
 	return function update() {
 
@@ -80,10 +79,9 @@ SpotLightHelper.prototype.update = function () {
 
 		this.cone.scale.set( coneWidth, coneWidth, coneLength );
 
-		vector.setFromMatrixPosition( this.light.matrixWorld );
-		vector2.setFromMatrixPosition( this.light.target.matrixWorld );
+		vector.setFromMatrixPosition( this.light.target.matrixWorld );
 
-		this.cone.lookAt( vector2.sub( vector ) );
+		this.cone.lookAt( vector );
 
 		if ( this.color !== undefined ) {
 

+ 0 - 587
src/loaders/JSONLoader.js

@@ -1,587 +0,0 @@
-import { Loader } from './Loader.js';
-import { LoaderUtils } from './LoaderUtils.js';
-import { AnimationClip } from '../animation/AnimationClip.js';
-import { Vector3 } from '../math/Vector3.js';
-import { Vector4 } from '../math/Vector4.js';
-import { Color } from '../math/Color.js';
-import { Vector2 } from '../math/Vector2.js';
-import { Face3 } from '../core/Face3.js';
-import { Geometry } from '../core/Geometry.js';
-import { FileLoader } from './FileLoader.js';
-import { DefaultLoadingManager } from './LoadingManager.js';
-
-/**
- * @author mrdoob / http://mrdoob.com/
- * @author alteredq / http://alteredqualia.com/
- */
-
-function JSONLoader( manager ) {
-
-	if ( typeof manager === 'boolean' ) {
-
-		console.warn( 'THREE.JSONLoader: showStatus parameter has been removed from constructor.' );
-		manager = undefined;
-
-	}
-
-	this.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager;
-
-	this.withCredentials = false;
-
-}
-
-Object.assign( JSONLoader.prototype, {
-
-	crossOrigin: 'anonymous',
-
-	load: function ( url, onLoad, onProgress, onError ) {
-
-		var scope = this;
-
-		var path = ( this.path === undefined ) ? LoaderUtils.extractUrlBase( url ) : this.path;
-
-		var loader = new FileLoader( this.manager );
-		loader.setPath( this.path );
-		loader.setWithCredentials( this.withCredentials );
-		loader.load( url, function ( text ) {
-
-			var json = JSON.parse( text );
-			var metadata = json.metadata;
-
-			if ( metadata !== undefined ) {
-
-				var type = metadata.type;
-
-				if ( type !== undefined ) {
-
-					if ( type.toLowerCase() === 'object' ) {
-
-						console.error( 'THREE.JSONLoader: ' + url + ' should be loaded with THREE.ObjectLoader instead.' );
-						return;
-
-					}
-
-				}
-
-			}
-
-			var object = scope.parse( json, path );
-			onLoad( object.geometry, object.materials );
-
-		}, onProgress, onError );
-
-	},
-
-	setPath: function ( value ) {
-
-		this.path = value;
-		return this;
-
-	},
-
-	setResourcePath: function ( value ) {
-
-		this.resourcePath = value;
-		return this;
-
-	},
-
-	setCrossOrigin: function ( value ) {
-
-		this.crossOrigin = value;
-		return this;
-
-	},
-
-	parse: ( function () {
-
-		function parseModel( json, geometry ) {
-
-			function isBitSet( value, position ) {
-
-				return value & ( 1 << position );
-
-			}
-
-			var i, j, fi,
-
-				offset, zLength,
-
-				colorIndex, normalIndex, uvIndex, materialIndex,
-
-				type,
-				isQuad,
-				hasMaterial,
-				hasFaceVertexUv,
-				hasFaceNormal, hasFaceVertexNormal,
-				hasFaceColor, hasFaceVertexColor,
-
-				vertex, face, faceA, faceB, hex, normal,
-
-				uvLayer, uv, u, v,
-
-				faces = json.faces,
-				vertices = json.vertices,
-				normals = json.normals,
-				colors = json.colors,
-
-				scale = json.scale,
-
-				nUvLayers = 0;
-
-
-			if ( json.uvs !== undefined ) {
-
-				// disregard empty arrays
-
-				for ( i = 0; i < json.uvs.length; i ++ ) {
-
-					if ( json.uvs[ i ].length ) nUvLayers ++;
-
-				}
-
-				for ( i = 0; i < nUvLayers; i ++ ) {
-
-					geometry.faceVertexUvs[ i ] = [];
-
-				}
-
-			}
-
-			offset = 0;
-			zLength = vertices.length;
-
-			while ( offset < zLength ) {
-
-				vertex = new Vector3();
-
-				vertex.x = vertices[ offset ++ ] * scale;
-				vertex.y = vertices[ offset ++ ] * scale;
-				vertex.z = vertices[ offset ++ ] * scale;
-
-				geometry.vertices.push( vertex );
-
-			}
-
-			offset = 0;
-			zLength = faces.length;
-
-			while ( offset < zLength ) {
-
-				type = faces[ offset ++ ];
-
-				isQuad = isBitSet( type, 0 );
-				hasMaterial = isBitSet( type, 1 );
-				hasFaceVertexUv = isBitSet( type, 3 );
-				hasFaceNormal = isBitSet( type, 4 );
-				hasFaceVertexNormal = isBitSet( type, 5 );
-				hasFaceColor = isBitSet( type, 6 );
-				hasFaceVertexColor = isBitSet( type, 7 );
-
-				// console.log("type", type, "bits", isQuad, hasMaterial, hasFaceVertexUv, hasFaceNormal, hasFaceVertexNormal, hasFaceColor, hasFaceVertexColor);
-
-				if ( isQuad ) {
-
-					faceA = new Face3();
-					faceA.a = faces[ offset ];
-					faceA.b = faces[ offset + 1 ];
-					faceA.c = faces[ offset + 3 ];
-
-					faceB = new Face3();
-					faceB.a = faces[ offset + 1 ];
-					faceB.b = faces[ offset + 2 ];
-					faceB.c = faces[ offset + 3 ];
-
-					offset += 4;
-
-					if ( hasMaterial ) {
-
-						materialIndex = faces[ offset ++ ];
-						faceA.materialIndex = materialIndex;
-						faceB.materialIndex = materialIndex;
-
-					}
-
-					// to get face <=> uv index correspondence
-
-					fi = geometry.faces.length;
-
-					if ( hasFaceVertexUv ) {
-
-						for ( i = 0; i < nUvLayers; i ++ ) {
-
-							uvLayer = json.uvs[ i ];
-
-							geometry.faceVertexUvs[ i ][ fi ] = [];
-							geometry.faceVertexUvs[ i ][ fi + 1 ] = [];
-
-							for ( j = 0; j < 4; j ++ ) {
-
-								uvIndex = faces[ offset ++ ];
-
-								u = uvLayer[ uvIndex * 2 ];
-								v = uvLayer[ uvIndex * 2 + 1 ];
-
-								uv = new Vector2( u, v );
-
-								if ( j !== 2 ) geometry.faceVertexUvs[ i ][ fi ].push( uv );
-								if ( j !== 0 ) geometry.faceVertexUvs[ i ][ fi + 1 ].push( uv );
-
-							}
-
-						}
-
-					}
-
-					if ( hasFaceNormal ) {
-
-						normalIndex = faces[ offset ++ ] * 3;
-
-						faceA.normal.set(
-							normals[ normalIndex ++ ],
-							normals[ normalIndex ++ ],
-							normals[ normalIndex ]
-						);
-
-						faceB.normal.copy( faceA.normal );
-
-					}
-
-					if ( hasFaceVertexNormal ) {
-
-						for ( i = 0; i < 4; i ++ ) {
-
-							normalIndex = faces[ offset ++ ] * 3;
-
-							normal = new Vector3(
-								normals[ normalIndex ++ ],
-								normals[ normalIndex ++ ],
-								normals[ normalIndex ]
-							);
-
-
-							if ( i !== 2 ) faceA.vertexNormals.push( normal );
-							if ( i !== 0 ) faceB.vertexNormals.push( normal );
-
-						}
-
-					}
-
-
-					if ( hasFaceColor ) {
-
-						colorIndex = faces[ offset ++ ];
-						hex = colors[ colorIndex ];
-
-						faceA.color.setHex( hex );
-						faceB.color.setHex( hex );
-
-					}
-
-
-					if ( hasFaceVertexColor ) {
-
-						for ( i = 0; i < 4; i ++ ) {
-
-							colorIndex = faces[ offset ++ ];
-							hex = colors[ colorIndex ];
-
-							if ( i !== 2 ) faceA.vertexColors.push( new Color( hex ) );
-							if ( i !== 0 ) faceB.vertexColors.push( new Color( hex ) );
-
-						}
-
-					}
-
-					geometry.faces.push( faceA );
-					geometry.faces.push( faceB );
-
-				} else {
-
-					face = new Face3();
-					face.a = faces[ offset ++ ];
-					face.b = faces[ offset ++ ];
-					face.c = faces[ offset ++ ];
-
-					if ( hasMaterial ) {
-
-						materialIndex = faces[ offset ++ ];
-						face.materialIndex = materialIndex;
-
-					}
-
-					// to get face <=> uv index correspondence
-
-					fi = geometry.faces.length;
-
-					if ( hasFaceVertexUv ) {
-
-						for ( i = 0; i < nUvLayers; i ++ ) {
-
-							uvLayer = json.uvs[ i ];
-
-							geometry.faceVertexUvs[ i ][ fi ] = [];
-
-							for ( j = 0; j < 3; j ++ ) {
-
-								uvIndex = faces[ offset ++ ];
-
-								u = uvLayer[ uvIndex * 2 ];
-								v = uvLayer[ uvIndex * 2 + 1 ];
-
-								uv = new Vector2( u, v );
-
-								geometry.faceVertexUvs[ i ][ fi ].push( uv );
-
-							}
-
-						}
-
-					}
-
-					if ( hasFaceNormal ) {
-
-						normalIndex = faces[ offset ++ ] * 3;
-
-						face.normal.set(
-							normals[ normalIndex ++ ],
-							normals[ normalIndex ++ ],
-							normals[ normalIndex ]
-						);
-
-					}
-
-					if ( hasFaceVertexNormal ) {
-
-						for ( i = 0; i < 3; i ++ ) {
-
-							normalIndex = faces[ offset ++ ] * 3;
-
-							normal = new Vector3(
-								normals[ normalIndex ++ ],
-								normals[ normalIndex ++ ],
-								normals[ normalIndex ]
-							);
-
-							face.vertexNormals.push( normal );
-
-						}
-
-					}
-
-
-					if ( hasFaceColor ) {
-
-						colorIndex = faces[ offset ++ ];
-						face.color.setHex( colors[ colorIndex ] );
-
-					}
-
-
-					if ( hasFaceVertexColor ) {
-
-						for ( i = 0; i < 3; i ++ ) {
-
-							colorIndex = faces[ offset ++ ];
-							face.vertexColors.push( new Color( colors[ colorIndex ] ) );
-
-						}
-
-					}
-
-					geometry.faces.push( face );
-
-				}
-
-			}
-
-		}
-
-		function parseSkin( json, geometry ) {
-
-			var influencesPerVertex = ( json.influencesPerVertex !== undefined ) ? json.influencesPerVertex : 2;
-
-			if ( json.skinWeights ) {
-
-				for ( var i = 0, l = json.skinWeights.length; i < l; i += influencesPerVertex ) {
-
-					var x = json.skinWeights[ i ];
-					var y = ( influencesPerVertex > 1 ) ? json.skinWeights[ i + 1 ] : 0;
-					var z = ( influencesPerVertex > 2 ) ? json.skinWeights[ i + 2 ] : 0;
-					var w = ( influencesPerVertex > 3 ) ? json.skinWeights[ i + 3 ] : 0;
-
-					geometry.skinWeights.push( new Vector4( x, y, z, w ) );
-
-				}
-
-			}
-
-			if ( json.skinIndices ) {
-
-				for ( var i = 0, l = json.skinIndices.length; i < l; i += influencesPerVertex ) {
-
-					var a = json.skinIndices[ i ];
-					var b = ( influencesPerVertex > 1 ) ? json.skinIndices[ i + 1 ] : 0;
-					var c = ( influencesPerVertex > 2 ) ? json.skinIndices[ i + 2 ] : 0;
-					var d = ( influencesPerVertex > 3 ) ? json.skinIndices[ i + 3 ] : 0;
-
-					geometry.skinIndices.push( new Vector4( a, b, c, d ) );
-
-				}
-
-			}
-
-			geometry.bones = json.bones;
-
-			if ( geometry.bones && geometry.bones.length > 0 && ( geometry.skinWeights.length !== geometry.skinIndices.length || geometry.skinIndices.length !== geometry.vertices.length ) ) {
-
-				console.warn( 'When skinning, number of vertices (' + geometry.vertices.length + '), skinIndices (' +
-					geometry.skinIndices.length + '), and skinWeights (' + geometry.skinWeights.length + ') should match.' );
-
-			}
-
-		}
-
-		function parseMorphing( json, geometry ) {
-
-			var scale = json.scale;
-
-			if ( json.morphTargets !== undefined ) {
-
-				for ( var i = 0, l = json.morphTargets.length; i < l; i ++ ) {
-
-					geometry.morphTargets[ i ] = {};
-					geometry.morphTargets[ i ].name = json.morphTargets[ i ].name;
-					geometry.morphTargets[ i ].vertices = [];
-
-					var dstVertices = geometry.morphTargets[ i ].vertices;
-					var srcVertices = json.morphTargets[ i ].vertices;
-
-					for ( var v = 0, vl = srcVertices.length; v < vl; v += 3 ) {
-
-						var vertex = new Vector3();
-						vertex.x = srcVertices[ v ] * scale;
-						vertex.y = srcVertices[ v + 1 ] * scale;
-						vertex.z = srcVertices[ v + 2 ] * scale;
-
-						dstVertices.push( vertex );
-
-					}
-
-				}
-
-			}
-
-			if ( json.morphColors !== undefined && json.morphColors.length > 0 ) {
-
-				console.warn( 'THREE.JSONLoader: "morphColors" no longer supported. Using them as face colors.' );
-
-				var faces = geometry.faces;
-				var morphColors = json.morphColors[ 0 ].colors;
-
-				for ( var i = 0, l = faces.length; i < l; i ++ ) {
-
-					faces[ i ].color.fromArray( morphColors, i * 3 );
-
-				}
-
-			}
-
-		}
-
-		function parseAnimations( json, geometry ) {
-
-			var outputAnimations = [];
-
-			// parse old style Bone/Hierarchy animations
-			var animations = [];
-
-			if ( json.animation !== undefined ) {
-
-				animations.push( json.animation );
-
-			}
-
-			if ( json.animations !== undefined ) {
-
-				if ( json.animations.length ) {
-
-					animations = animations.concat( json.animations );
-
-				} else {
-
-					animations.push( json.animations );
-
-				}
-
-			}
-
-			for ( var i = 0; i < animations.length; i ++ ) {
-
-				var clip = AnimationClip.parseAnimation( animations[ i ], geometry.bones );
-				if ( clip ) outputAnimations.push( clip );
-
-			}
-
-			// parse implicit morph animations
-			if ( geometry.morphTargets ) {
-
-				// TODO: Figure out what an appropraite FPS is for morph target animations -- defaulting to 10, but really it is completely arbitrary.
-				var morphAnimationClips = AnimationClip.CreateClipsFromMorphTargetSequences( geometry.morphTargets, 10 );
-				outputAnimations = outputAnimations.concat( morphAnimationClips );
-
-			}
-
-			if ( outputAnimations.length > 0 ) geometry.animations = outputAnimations;
-
-		}
-
-		return function parse( json, path ) {
-
-			if ( json.data !== undefined ) {
-
-				// Geometry 4.0 spec
-				json = json.data;
-
-			}
-
-			if ( json.scale !== undefined ) {
-
-				json.scale = 1.0 / json.scale;
-
-			} else {
-
-				json.scale = 1.0;
-
-			}
-
-			var geometry = new Geometry();
-
-			parseModel( json, geometry );
-			parseSkin( json, geometry );
-			parseMorphing( json, geometry );
-			parseAnimations( json, geometry );
-
-			geometry.computeFaceNormals();
-			geometry.computeBoundingSphere();
-
-			if ( json.materials === undefined || json.materials.length === 0 ) {
-
-				return { geometry: geometry };
-
-			} else {
-
-				var materials = Loader.prototype.initMaterials( json.materials, this.resourcePath || path, this.crossOrigin );
-
-				return { geometry: geometry, materials: materials };
-
-			}
-
-		};
-
-	} )()
-
-} );
-
-
-export { JSONLoader };

+ 12 - 4
src/loaders/ObjectLoader.js

@@ -50,7 +50,6 @@ import { AnimationClip } from '../animation/AnimationClip.js';
 import { MaterialLoader } from './MaterialLoader.js';
 import { LoaderUtils } from './LoaderUtils.js';
 import { BufferGeometryLoader } from './BufferGeometryLoader.js';
-import { JSONLoader } from './JSONLoader.js';
 import { FileLoader } from './FileLoader.js';
 import * as Geometries from '../geometries/Geometries.js';
 import * as Curves from '../extras/curves/Curves.js';
@@ -101,7 +100,7 @@ Object.assign( ObjectLoader.prototype, {
 
 			if ( metadata === undefined || metadata.type === undefined || metadata.type.toLowerCase() === 'geometry' ) {
 
-				console.error( 'THREE.ObjectLoader: Can\'t load ' + url + '. Use THREE.JSONLoader instead.' );
+				console.error( 'THREE.ObjectLoader: Can\'t load ' + url );
 				return;
 
 			}
@@ -191,7 +190,6 @@ Object.assign( ObjectLoader.prototype, {
 
 		if ( json !== undefined ) {
 
-			var geometryLoader = new JSONLoader();
 			var bufferGeometryLoader = new BufferGeometryLoader();
 
 			for ( var i = 0, l = json.length; i < l; i ++ ) {
@@ -424,7 +422,17 @@ Object.assign( ObjectLoader.prototype, {
 
 					case 'Geometry':
 
-						geometry = geometryLoader.parse( data, this.resourcePath ).geometry;
+						if ( 'THREE' in window && 'LegacyJSONLoader' in THREE ) {
+
+							var geometryLoader = new THREE.LegacyJSONLoader();
+							geometry = geometryLoader.parse( data, this.resourcePath ).geometry;
+
+
+						} else {
+
+							console.error( 'THREE.ObjectLoader: You have to import LegacyJSONLoader in order load geometry data of type "Geometry".' );
+
+						}
 
 						break;
 

+ 0 - 17
src/materials/MeshMatcapMaterial.js

@@ -68,23 +68,6 @@ function MeshMatcapMaterial( parameters ) {
 
 	this.setValues( parameters );
 
-	// a matcap is required
-
-	if ( this.matcap === null ) {
-
-		var canvas = document.createElementNS( 'http://www.w3.org/1999/xhtml', 'canvas' );
-		canvas.width = 1;
-		canvas.height = 1;
-
-		var context = canvas.getContext( '2d' );
-
-		context.fillStyle = '#fff';
-		context.fillRect( 0, 0, 1, 1 );
-
-		this.matcap = new THREE.CanvasTexture( canvas );
-
-	}
-
 }
 
 MeshMatcapMaterial.prototype = Object.create( Material.prototype );

+ 23 - 112
src/objects/SkinnedMesh.js

@@ -1,17 +1,21 @@
-import { Mesh } from './Mesh.js';
-import { Vector4 } from '../math/Vector4.js';
-import { Skeleton } from './Skeleton.js';
-import { Bone } from './Bone.js';
-import { Matrix4 } from '../math/Matrix4.js';
-
 /**
  * @author mikael emtinger / http://gomo.se/
  * @author alteredq / http://alteredqualia.com/
  * @author ikerr / http://verold.com
  */
 
+import { Mesh } from './Mesh.js';
+import { Matrix4 } from '../math/Matrix4.js';
+import { Vector4 } from '../math/Vector4.js';
+
 function SkinnedMesh( geometry, material ) {
 
+	if ( geometry && geometry.isGeometry ) {
+
+		console.error( 'THREE.SkinnedMesh no longer supports THREE.Geometry. Use THREE.BufferGeometry instead.' );
+
+	}
+
 	Mesh.call( this, geometry, material );
 
 	this.type = 'SkinnedMesh';
@@ -20,13 +24,6 @@ function SkinnedMesh( geometry, material ) {
 	this.bindMatrix = new Matrix4();
 	this.bindMatrixInverse = new Matrix4();
 
-	var bones = this.initBones();
-	var skeleton = new Skeleton( bones );
-
-	this.bind( skeleton, this.matrixWorld );
-
-	this.normalizeSkinWeights();
-
 }
 
 SkinnedMesh.prototype = Object.assign( Object.create( Mesh.prototype ), {
@@ -35,66 +32,6 @@ SkinnedMesh.prototype = Object.assign( Object.create( Mesh.prototype ), {
 
 	isSkinnedMesh: true,
 
-	initBones: function () {
-
-		var bones = [], bone, gbone;
-		var i, il;
-
-		if ( this.geometry && this.geometry.bones !== undefined ) {
-
-			// first, create array of 'Bone' objects from geometry data
-
-			for ( i = 0, il = this.geometry.bones.length; i < il; i ++ ) {
-
-				gbone = this.geometry.bones[ i ];
-
-				// create new 'Bone' object
-
-				bone = new Bone();
-				bones.push( bone );
-
-				// apply values
-
-				bone.name = gbone.name;
-				bone.position.fromArray( gbone.pos );
-				bone.quaternion.fromArray( gbone.rotq );
-				if ( gbone.scl !== undefined ) bone.scale.fromArray( gbone.scl );
-
-			}
-
-			// second, create bone hierarchy
-
-			for ( i = 0, il = this.geometry.bones.length; i < il; i ++ ) {
-
-				gbone = this.geometry.bones[ i ];
-
-				if ( ( gbone.parent !== - 1 ) && ( gbone.parent !== null ) && ( bones[ gbone.parent ] !== undefined ) ) {
-
-					// subsequent bones in the hierarchy
-
-					bones[ gbone.parent ].add( bones[ i ] );
-
-				} else {
-
-					// topmost bone, immediate child of the skinned mesh
-
-					this.add( bones[ i ] );
-
-				}
-
-			}
-
-		}
-
-		// now the bones are part of the scene graph and children of the skinned mesh.
-		// let's update the corresponding matrices
-
-		this.updateMatrixWorld( true );
-
-		return bones;
-
-	},
-
 	bind: function ( skeleton, bindMatrix ) {
 
 		this.skeleton = skeleton;
@@ -122,56 +59,30 @@ SkinnedMesh.prototype = Object.assign( Object.create( Mesh.prototype ), {
 
 	normalizeSkinWeights: function () {
 
-		var scale, i;
-
-		if ( this.geometry && this.geometry.isGeometry ) {
+		var vector = new Vector4();
 
-			for ( i = 0; i < this.geometry.skinWeights.length; i ++ ) {
+		var skinWeight = this.geometry.attributes.skinWeight;
 
-				var sw = this.geometry.skinWeights[ i ];
+		for ( var i = 0, l = skinWeight.count; i < l; i ++ ) {
 
-				scale = 1.0 / sw.manhattanLength();
+			vector.x = skinWeight.getX( i );
+			vector.y = skinWeight.getY( i );
+			vector.z = skinWeight.getZ( i );
+			vector.w = skinWeight.getW( i );
 
-				if ( scale !== Infinity ) {
+			var scale = 1.0 / vector.manhattanLength();
 
-					sw.multiplyScalar( scale );
+			if ( scale !== Infinity ) {
 
-				} else {
+				vector.multiplyScalar( scale );
 
-					sw.set( 1, 0, 0, 0 ); // do something reasonable
+			} else {
 
-				}
+				vector.set( 1, 0, 0, 0 ); // do something reasonable
 
 			}
 
-		} else if ( this.geometry && this.geometry.isBufferGeometry ) {
-
-			var vec = new Vector4();
-
-			var skinWeight = this.geometry.attributes.skinWeight;
-
-			for ( i = 0; i < skinWeight.count; i ++ ) {
-
-				vec.x = skinWeight.getX( i );
-				vec.y = skinWeight.getY( i );
-				vec.z = skinWeight.getZ( i );
-				vec.w = skinWeight.getW( i );
-
-				scale = 1.0 / vec.manhattanLength();
-
-				if ( scale !== Infinity ) {
-
-					vec.multiplyScalar( scale );
-
-				} else {
-
-					vec.set( 1, 0, 0, 0 ); // do something reasonable
-
-				}
-
-				skinWeight.setXYZW( i, vec.x, vec.y, vec.z, vec.w );
-
-			}
+			skinWeight.setXYZW( i, vector.x, vector.y, vector.z, vector.w );
 
 		}
 

+ 6 - 1
src/renderers/shaders/ShaderLib/equirect_frag.glsl.js

@@ -15,7 +15,12 @@ void main() {
 
 	sampleUV.x = atan( direction.z, direction.x ) * RECIPROCAL_PI2 + 0.5;
 
-	gl_FragColor = texture2D( tEquirect, sampleUV );
+	vec4 texColor = texture2D( tEquirect, sampleUV );
+
+	gl_FragColor = mapTexelToLinear( texColor );
+
+	#include <tonemapping_fragment>
+	#include <encodings_fragment>
 
 }
 `;

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