Mr.doob 6 years ago
parent
commit
a242ec4459
100 changed files with 2902 additions and 2499 deletions
  1. 20 14
      build/three.js
  2. 75 406
      build/three.min.js
  3. 20 14
      build/three.module.js
  4. 1 4
      docs/api/en/animation/AnimationClip.html
  5. 3 0
      docs/api/en/audio/Audio.html
  6. 6 4
      docs/api/en/core/BufferGeometry.html
  7. 0 1
      docs/api/en/core/Face3.html
  8. 2 1
      docs/api/en/core/Geometry.html
  9. 1 1
      docs/api/en/core/Object3D.html
  10. 6 18
      docs/api/en/deprecated/DeprecatedList.html
  11. 0 1
      docs/api/en/lights/DirectionalLight.html
  12. 0 122
      docs/api/en/loaders/JSONLoader.html
  13. 3 8
      docs/api/en/loaders/ObjectLoader.html
  14. 0 1
      docs/api/en/materials/SpriteMaterial.html
  15. 0 5
      docs/api/en/objects/SkinnedMesh.html
  16. 1 1
      docs/api/en/scenes/Scene.html
  17. 1 4
      docs/api/zh/animation/AnimationClip.html
  18. 14 14
      docs/api/zh/animation/tracks/BooleanKeyframeTrack.html
  19. 12 13
      docs/api/zh/animation/tracks/ColorKeyframeTrack.html
  20. 12 12
      docs/api/zh/animation/tracks/NumberKeyframeTrack.html
  21. 17 16
      docs/api/zh/animation/tracks/QuaternionKeyframeTrack.html
  22. 16 16
      docs/api/zh/animation/tracks/StringKeyframeTrack.html
  23. 12 12
      docs/api/zh/animation/tracks/VectorKeyframeTrack.html
  24. 3 0
      docs/api/zh/audio/Audio.html
  25. 0 1
      docs/api/zh/core/Face3.html
  26. 6 25
      docs/api/zh/deprecated/DeprecatedList.html
  27. 0 1
      docs/api/zh/lights/DirectionalLight.html
  28. 0 119
      docs/api/zh/loaders/JSONLoader.html
  29. 3 8
      docs/api/zh/loaders/ObjectLoader.html
  30. 0 1
      docs/api/zh/materials/SpriteMaterial.html
  31. 92 105
      docs/api/zh/math/Box3.html
  32. 96 103
      docs/api/zh/math/Color.html
  33. 17 19
      docs/api/zh/math/Cylindrical.html
  34. 64 75
      docs/api/zh/math/Euler.html
  35. 33 36
      docs/api/zh/math/Frustum.html
  36. 10 11
      docs/api/zh/math/Interpolant.html
  37. 34 40
      docs/api/zh/math/Line3.html
  38. 38 43
      docs/api/zh/math/Math.html
  39. 63 71
      docs/api/zh/math/Matrix3.html
  40. 109 130
      docs/api/zh/math/Matrix4.html
  41. 49 58
      docs/api/zh/math/Plane.html
  42. 0 5
      docs/api/zh/objects/SkinnedMesh.html
  43. 1 1
      docs/examples/loaders/GLTFLoader.html
  44. 23 0
      docs/examples/loaders/MMDLoader.html
  45. 3 2
      docs/examples/utils/BufferGeometryUtils.html
  46. 4 4
      docs/examples/utils/SceneUtils.html
  47. 0 2
      docs/list.js
  48. 0 1
      docs/manual/en/introduction/Animation-system.html
  49. 0 58
      docs/manual/en/introduction/How-to-run-things-locally.html
  50. 1 1
      docs/manual/en/introduction/Loading-3D-models.html
  51. 2 3
      docs/manual/zh/introduction/Animation-system.html
  52. 1 44
      editor/js/Loader.js
  53. 2 2
      editor/js/Menubar.Play.js
  54. 3 1
      editor/js/Menubar.Status.js
  55. 4 2
      editor/js/Sidebar.History.js
  56. 1 1
      editor/js/Sidebar.Material.js
  57. 4 4
      editor/js/Sidebar.Project.js
  58. 1 1
      editor/js/Sidebar.Script.js
  59. 2 2
      editor/js/Sidebar.Settings.js
  60. 37 9
      editor/js/Strings.js
  61. 1 49
      editor/js/libs/tern-threejs/threejs.js
  62. 2 3
      examples/files.js
  63. 11 7
      examples/js/controls/DragControls.js
  64. 6 0
      examples/js/exporters/GLTFExporter.js
  65. 3 1
      examples/js/loaders/AssimpLoader.js
  66. 183 69
      examples/js/loaders/EquirectangularToCubeGenerator.js
  67. 19 6
      examples/js/loaders/GLTFLoader.js
  68. 2 2
      examples/js/loaders/HDRCubeTextureLoader.js
  69. 132 11
      examples/js/loaders/MMDLoader.js
  70. 7 3
      examples/js/loaders/OBJLoader.js
  71. 578 0
      examples/js/loaders/deprecated/LegacyJSONLoader.js
  72. 64 2
      examples/js/loaders/sea3d/SEA3DLoader.js
  73. 1 2
      examples/js/nodes/materials/nodes/StandardNode.js
  74. 38 0
      examples/js/offscreen/jank.js
  75. 9 0
      examples/js/offscreen/offscreen.js
  76. 77 0
      examples/js/offscreen/scene.js
  77. 164 135
      examples/js/pmrem/PMREMCubeUVPacker.js
  78. 126 121
      examples/js/pmrem/PMREMGenerator.js
  79. 1 0
      examples/js/postprocessing/AdaptiveToneMappingPass.js
  80. 5 4
      examples/js/postprocessing/SAOPass.js
  81. 340 130
      examples/js/postprocessing/SSAOPass.js
  82. 8 8
      examples/js/postprocessing/UnrealBloomPass.js
  83. 8 1
      examples/js/renderers/CSS3DRenderer.js
  84. 185 123
      examples/js/shaders/SSAOShader.js
  85. 1 0
      examples/js/utils/BufferGeometryUtils.js
  86. 0 76
      examples/js/workers/OffscreenCanvas.js
  87. 3 3
      examples/misc_boxselection.html
  88. BIN
      examples/models/gltf/Soldier.glb
  89. 0 0
      examples/models/json/lightmap/lightmap.json
  90. 0 0
      examples/models/json/platform/platform.json
  91. 0 0
      examples/models/json/teapot-claraio.json
  92. BIN
      examples/models/skinned/marine/M4.png
  93. BIN
      examples/models/skinned/marine/MarineCv2_color.jpg
  94. BIN
      examples/models/skinned/marine/m4.blend
  95. 0 36
      examples/models/skinned/marine/m4.js
  96. 0 10
      examples/models/skinned/marine/marine_anims.json
  97. BIN
      examples/models/skinned/marine/marine_anims_all.blend
  98. 0 10
      examples/models/skinned/marine/marine_anims_all.json
  99. BIN
      examples/models/skinned/marine/marine_anims_core.blend
  100. 0 10
      examples/models/skinned/marine/marine_anims_core.json

File diff suppressed because it is too large
+ 20 - 14
build/three.js


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


File diff suppressed because it is too large
+ 20 - 14
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 - 4
docs/api/en/core/BufferGeometry.html

@@ -119,12 +119,13 @@
 
 		<h3>[property:Object drawRange]</h3>
 		<p>
-			Used to determine what part of the geometry should be rendered. This should not
-			be set directly, instead use [page:.setDrawRange].<br />
-			Default is
+			Determines the part of the geometry to render. This should not
+			be set directly, instead use [page:.setDrawRange]. Default is
 			<code>
 				{ start: 0, count: Infinity }
 			</code>
+			For non-indexed BufferGeometry, count is the number of vertices to render.
+			For indexed BufferGeometry, count is the number of indices to render.
 		</p>
 
 		<h3>[property:Array groups]</h3>
@@ -316,7 +317,8 @@
 		<p>Set the [page:.index] buffer.</p>
 
 		<h3>[method:null setDrawRange] ( [param:Integer start], [param:Integer count] )</h3>
-		<p>Set the [page:.drawRange] buffer. See that property for details.</p>
+		<p>Set the [page:.drawRange] property. For non-indexed BufferGeometry, count is the number of vertices to render.
+		For indexed BufferGeometry, count is the number of indices to render.</p>
 
 		<h3>[method:BufferGeometry setFromObject] ( [param:Object3D object] )</h3>
 		<p>Sets the attributes for this BufferGeometry from an [page:Object3D].</p>

+ 0 - 1
docs/api/en/core/Face3.html

@@ -19,7 +19,6 @@
 
 		<h2>Examples</h2>
 
-		<p>[example:misc_ubiquity_test ubiquity / test ]</p>
 		<p>[example:svg_sandbox svg / sandbox ]</p>
 		<p>[example:misc_exporter_obj exporter / obj ]</p>
 		<p>[example:webgl_shaders_vector WebGL / shaders / vector ]</p>

+ 2 - 1
docs/api/en/core/Geometry.html

@@ -267,7 +267,8 @@
 
 		<h3>[method:Geometry fromBufferGeometry]( [param:BufferGeometry geometry] )</h3>
 		<p>Convert a [page:BufferGeometry] to a Geometry. <br />
-		The array used to store the vertices in the bufferGeometry is a non indexed array, so the resultant geometry may contain duplicated vertices. Use [page:mergeVertices] to remove them.</p>
+		When converting from BufferGeometry to Geometry, all vertices are preserved, so duplicated vertices may appear.
+		Use [page:Geometry.mergeVertices] to remove them.</p>
 
 		<h3>[method:Geometry lookAt] ( [param:Vector3 vector] )</h3>
 		<p>

+ 1 - 1
docs/api/en/core/Object3D.html

@@ -286,7 +286,7 @@
 
 		Rotates the object to face a point in world space.<br /><br />
 
-		This method does not support objects with rotated and/or translated parent(s).
+		This method does not support objects having non-uniformly-scaled parent(s).
 		</p>
 
 		<h3>[method:Array raycast]( [param:Raycaster raycaster], [param:Array intersects] )</h3>

+ 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 - 1
docs/api/en/lights/DirectionalLight.html

@@ -41,7 +41,6 @@
 		<h2>Example</h2>
 		<p>
 			[example:misc_controls_fly controls / fly ]<br />
-			[example:misc_lights_test lights / test ]<br />
 			[example:webvr_cubes cubes ]<br />
 			[example:webgl_effects_parallaxbarrier effects / parallaxbarrier ]<br />
 			[example:webgl_effects_stereo effects / stereo ]<br />

+ 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>

+ 3 - 8
docs/api/en/loaders/ObjectLoader.html

@@ -11,10 +11,7 @@
 		<h1>[name]</h1>
 
 		<p class="desc">
-			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.<br /><br />
-
-			Note that this loader can't load [page:Geometries]. Use [page:JSONLoader] instead for that.<br /><br />
+			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 />
 
 			This uses the [page:FileLoader] internally for loading files.
 		</p>
@@ -22,10 +19,9 @@
 		<h2>Example</h2>
 
 		<p>
-
-			[example:webgl_animation_scene WebGL / animation / scene]<br />
+			[example:webgl_animation_skinning_blending WebGL / animation / skinning / blending]<br />
 			[example:webgl_loader_json_claraio WebGL / loader / json / claraio]<br />
-			[example:webgl_loader_msgpack WebGL / loader / msgpack]
+			[example:webgl_materials_lightmap WebGL / materials / lightmap]
 		</p>
 
 		<code>
@@ -121,7 +117,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 - 1
docs/api/en/materials/SpriteMaterial.html

@@ -17,7 +17,6 @@
 		<h2>Examples</h2>
 		<div>
 			[example:webgl_sprites WebGL / sprites]<br />
-			[example:misc_ubiquity_test misc / ubiquity / test]<br />
 			[example:software_sandbox software / sandbox]<br />
 			[example:svg_sandbox svg / sandbox]<br />
 			[example:webgl_materials_cubemap_dynamic webgl / materials / cubemap / dynamic]

+ 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>
 

+ 0 - 1
docs/api/zh/core/Face3.html

@@ -18,7 +18,6 @@
 
 		<h2>示例</h2>
 
-		<p>[example:misc_ubiquity_test ubiquity / test ]</p>
 		<p>[example:svg_sandbox svg / sandbox ]</p>
 		<p>[example:misc_exporter_obj exporter / obj ]</p>
 		<p>[example:webgl_shaders_vector WebGL / shaders / vector ]</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 - 1
docs/api/zh/lights/DirectionalLight.html

@@ -38,7 +38,6 @@
 		<p>
 			[example:canvas_morphtargets_horse morphtargets / horse ]<br />
 			[example:misc_controls_fly controls / fly ]<br />
-			[example:misc_lights_test lights / test ]<br />
 			[example:webvr_cubes cubes ]<br />
 			[example:webgl_effects_parallaxbarrier effects / parallaxbarrier ]<br />
 			[example:webgl_effects_stereo effects / stereo ]<br />

+ 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>

+ 3 - 8
docs/api/zh/loaders/ObjectLoader.html

@@ -11,10 +11,7 @@
 		<h1>[name]</h1>
 
 		<p class="desc">
-			一个用来加载JSON资源的加载器。 不像[page:JSONLoader],这个加载器使用
-			<em>.type</em>对象属性,来映射它自己到源类。<br /><br />
-
-			请注意这个加载器不能用来加载[page:Geometries],而是用[page:JSONLoader]进行加载。<br /><br />
+			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 />
 
 			此加载器内部使用[page:FileLoader]进行加载文件。
 		</p>
@@ -22,10 +19,9 @@
 		<h2>例子</h2>
 
 		<p>
-
-			[example:webgl_animation_scene WebGL / animation / scene]<br />
+			[example:webgl_animation_skinning_blending WebGL / animation / skinning / blending]<br />
 			[example:webgl_loader_json_claraio WebGL / loader / json / claraio]<br />
-			[example:webgl_loader_msgpack WebGL / loader / msgpack]
+			[example:webgl_materials_lightmap WebGL / materials / lightmap]
 		</p>
 
 		<code>
@@ -120,7 +116,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>

+ 0 - 1
docs/api/zh/materials/SpriteMaterial.html

@@ -17,7 +17,6 @@
 		<h2>例子(Examples)</h2>
 		<div>
 			[example:webgl_sprites WebGL / sprites]<br />
-			[example:misc_ubiquity_test misc / ubiquity / test]<br />
 			[example:software_sandbox software / sandbox]<br />
 			[example:svg_sandbox svg / sandbox]<br />
 			[example:webgl_materials_cubemap_dynamic webgl / materials / cubemap / dynamic]

+ 92 - 105
docs/api/zh/math/Box3.html

@@ -11,291 +11,278 @@
 		<h1>[name]</h1>
 
 		<p class="desc">
-			Represents a box or cube in 3D space. The main purpose of this is to represent
-			the [link:https://en.wikipedia.org/wiki/Minimum_bounding_box Minimum Bounding Boxes]
-			for objects.
+			在3D空间中表示一个盒子或立方体。这个的主要目的是表示对象的最小边界框[link:https://en.wikipedia.org/wiki/Minimum_bounding_box Minimum Bounding Boxes]。
 		</p>
 
 
-		<h2>Constructor</h2>
+		<h2>构造器(Constructor</h2>
 
 
 		<h3>[name]( [param:Vector3 min], [param:Vector3 max] )</h3>
 		<p>
-		[page:Vector3 min] - (optional) [page:Vector3] representing the lower (x, y, z) boundary of the box.
-		Default is ( + Infinity, + Infinity, + Infinity ).<br>
+		[page:Vector3 min] - (参数可选) [page:Vector3] 表示包围盒的下边界。
+		默认值是( + Infinity, + Infinity, + Infinity )。<br>
 
-		[page:Vector3 max] - (optional) [page:Vector3] representing the lower upper (x, y, z) boundary of the box.
-		Default is ( - Infinity, - Infinity, - Infinity ).<br /><br />
+		[page:Vector3 max] - (参数可选) [page:Vector3] 表示包围盒的上边界。
+		默认值是( - Infinity, - Infinity, - Infinity )。<br /><br />
 
-		Creates a [name] bounded by min and max.
+		创建一个以max和min为边界的包围盒。
 		</p>
 
-		<h2>Properties</h2>
+		<h2>属性(Properties</h2>
 
 		<h3>[property:Boolean isBox3]</h3>
 		<p>
-			Used to check whether this or derived classes are Box3s. Default is *true*.<br /><br />
-
-			You should not change this, as it used internally for optimisation.
+			用于检测当前对象或者派生类对象是否是Box3。默认为 *true*。<br /><br />
+			
+			不应该修改这个值,因为内部使用该属性做了优化的任务。
 		</p>
 
 		<h3>[property:Vector3 min]</h3>
 		<p>
-			[page:Vector3] representing the lower (x, y, z) boundary of the box.<br />
-			Default is ( + Infinity, + Infinity, + Infinity ).
+			[page:Vector3] 表示包围盒的下边界。<br />
+			默认值是( - Infinity, - Infinity, - Infinity )。
 		</p>
 
 		<h3>[property:Vector3 max]</h3>
 		<p>
-			[page:Vector3] representing the upper (x, y, z) boundary of the box.<br />
-			Default is ( - Infinity, - Infinity, - Infinity ).
+			[page:Vector3] 包围盒的(x, y, z)上边界。<br />
+			默认值是 ( - Infinity, - Infinity, - Infinity ).
 		</p>
 
 
 
-		<h2>Methods</h2>
+		<h2>方法(Methods</h2>
 
 		<h3>[method:Box3 applyMatrix4]( [param:Matrix4 matrix] )</h3>
 		<p>
-		[page:Matrix4 matrix] - The [page:Matrix4] to apply<br /><br />
-
-		Transforms this Box3 with the supplied matrix.
+		[page:Matrix4 matrix] - 要应用的 [page:Matrix4] <br /><br />
+		
+		使用传入的矩阵变换Box3(包围盒8个顶点都会乘以这个变换矩阵)。
 		</p>
 
 		<h3>[method:Vector3 clampPoint]( [param:Vector3 point], [param:Vector3 target] )</h3>
 		<p>
-		[page:Vector3 point] - [page:Vector3] to clamp. <br>
-		[page:Vector3 target] — the result will be copied into this Vector3.<br /><br />
+		[page:Vector3 point] - 需要做clamp 的坐标 [page:Vector3]。 <br>
+		[page:Vector3 target] — 结果将会被拷贝到这个对象中<br /><br />
 
-		[link:https://en.wikipedia.org/wiki/Clamping_(graphics) Clamps] the [page:Vector3 point] within the bounds of this box.<br />
+		是这个点[page:Vector3 point] [link:https://en.wikipedia.org/wiki/Clamping_(graphics) Clamps](处于范围内) 处于包围盒边界范围内。<br />
 		</p>
 
 		<h3>[method:Box3 clone]()</h3>
-		<p>Returns a new [page:Box3] with the same [page:.min min] and [page:.max max] as this one.</p>
+		<p>返回一个与该包围盒子有相同下边界[page:.min min] 和上边界 [page:.max max]的新包围盒。</p>
 
 		<h3>[method:Boolean containsBox]( [param:Box3 box] )</h3>
 		<p>
-		[page:Box3 box] - [page:Box3 Box3] to test for inclusion.<br /><br />
-
-		Returns true if this box includes the entirety of [page:Box3 box]. If this and [page:Box3 box] are identical, <br>
-		this function also returns true.
+		[page:Box3 box] - 需要检测是否在当前包围盒内的 [page:Box3 Box3]。<br /><br />
+		传入的 [page:Box3 box] 整体都被包含在该对象中则返回true。如果他们两个包围盒是一样的也返回true。
 		</p>
 
 		<h3>[method:Boolean containsPoint]( [param:Vector3 point] )</h3>
 		<p>
-		[page:Vector3 point] - [page:Vector3] to check for inclusion.<br /><br />
+		[page:Vector3 point] - 需要检测是否在当前包围盒内的 [page:Vector3]。<br /><br />
 
-		Returns true if the specified [page:Vector3 point] lies within or on the boundaries of this box.
+		当传入的值 [page:Vector3 point] 在包围盒内部或者边界都会返回true。
 		</p>
 
 		<h3>[method:Box3 copy]( [param:Box3 box] )</h3>
 		<p>
-		[page:Box3 box]  - [page:Box3] to copy.<br /><br />
+		[page:Box3 box]  - 需要复制的包围盒 [page:Box3] 。<br /><br />
 
-		Copies the [page:.min min] and [page:.max max] from [page:Box3 box] to this box.
+		将传入的值 [page:Box3 box] 中的 [page:.min min] 和 [page:.max max] 拷贝到当前对象。
 		</p>
 
 		<h3>[method:Float distanceToPoint]( [param:Vector3 point] )</h3>
 		<p>
-		[page:Vector3 point] - [page:Vector3] to measure distance to.<br /><br />
+		[page:Vector3 point] - 用来测试距离的点 [page:Vector3]。<br /><br />
 
-		Returns the distance from any edge of this box to the specified point.
-		If the [page:Vector3 point] lies inside of this box, the distance will be 0.
+		返回这个box的任何边缘到指定点的距离。如果这个点位于这个盒子里,距离将是0。
 		</p>
 
 
 		<h3>[method:Boolean equals]( [param:Box3 box] )</h3>
 		<p>
-		[page:Box3 box] - Box to compare with this one.<br /><br />
+		[page:Box3 box] - 将box与当前对象做比较。<br /><br />
 
-		Returns true if this box and [page:Box3 box] share the same lower and upper bounds.
+		返回true如果传入的值与当前的对象 [page:Box3 box] 有相同的上下边界。
 		</p>
 
 		<h3>[method:Box3 expandByObject]( [param:Object3D object] )</h3>
 		<p>
-		[page:Object3D object] - [page:Object3D] to expand the box by.<br /><br />
+		[page:Object3D object] - 包裹在包围盒中的3d对象 [page:Object3D]。<br /><br />
 
-		Expands the boundaries of this box to include [page:Object3D object] and its children,
-		accounting for the object's, and children's, world transforms.
+		扩展此包围盒的边界,使得对象及其子对象在包围盒内,包括对象和子对象的世界坐标的变换。
 
 		</p>
 
 		<h3>[method:Box3 expandByPoint]( [param:Vector3 point] )</h3>
 		<p>
-		[page:Vector3 point] - [page:Vector3] that should be included in the box.<br /><br />
+		[page:Vector3 point] - 需要在包围盒中的点 [page:Vector3]。<br /><br />
 
-		Expands the boundaries of this box to include [page:Vector3 point].
+		扩展这个包围盒的边界使得该点([page:Vector3 point])在包围盒内。
 		</p>
 
 		<h3>[method:Box3 expandByScalar]( [param:float scalar] )</h3>
 		<p>
-		[page:float scalar] - Distance to expand the box by.<br /><br />
+		[page:float scalar] - 扩展包围盒的比例。<br /><br />
 
-		Expands each dimension of the box by [page:float scalar]. If negative, the dimensions of the box
-		will be contracted.
+		按 [page:float scalar] 的值展开盒子的每个维度。如果是负数,盒子的尺寸会缩小。
 		</p>
 
 		<h3>[method:Box3 expandByVector]( [param:Vector3 vector] )</h3>
 		<p>
-		[page:Vector3 vector] - [page:Vector3] to expand the box by.<br /><br />
+		[page:Vector3 vector] - 扩展包围盒的数值 [page:Vector3] 。<br /><br />
+
+		按 [page:Vector3 vector] 每个纬度的值展开这个箱子。
+		这个盒子的宽度将由 [page:Vector3 vector] 的x分量在两个方向上展开。
+		这个盒子的高度将由 [page:Vector3 vector] 两个方向上的y分量展开。
+		这个盒子的深度将由 [page:Vector3 vector] z分量在两个方向上展开。
 
-		Expands this box equilaterally by [page:Vector3 vector]. The width of this box will be
-		expanded by the x component of [page:Vector3 vector] in both directions. The height of
-		this box will be expanded by the y component of [page:Vector3 vector] in both directions.
-		The depth of this box will be expanded by the z component of *vector* in both directions.
 		</p>
 
 		<h3>[method:Sphere getBoundingSphere]( [param:Sphere target] )</h3>
 		<p>
-		[page:Sphere target] — the result will be copied into this Sphere.<br /><br />
+		[page:Sphere target] — 如果指定了target ,结果将会被拷贝到target。<br /><br />
 
-		Gets a [page:Sphere] that bounds the box.
+		获取一个包围球 [page:Sphere]。
 		</p>
 
 		<h3>[method:Vector3 getCenter]( [param:Vector3 target] )</h3>
 		<p>
-		[page:Vector3 target] — the result will be copied into this Vector3.<br /><br />
+		[page:Vector3 target] — 如果指定了target ,结果将会被拷贝到target。<br /><br />
 
-		Returns the center point of the box as a [page:Vector3].
+		返回包围盒的中心点 [page:Vector3]。
 		</p>
 
 		<h3>[method:Vector3 getParameter]( [param:Vector3 point], [param:Vector3 target] ) </h3>
 		<p>
 		[page:Vector3 point] - [page:Vector3].<br/>
-		[page:Vector3 target] — the result will be copied into this Vector3.<br /><br />
+		[page:Vector3 target] — 如果指定了target ,结果将会被拷贝到target。<br /><br />
 
-		Returns a point as a proportion of this box's width and height.
+		返回一个点为这个盒子的宽度和高度的比例。
 		</p>
 
 		<h3>[method:Vector3 getSize]( [param:Vector3 target] )</h3>
 		<p>
-		[page:Vector3 target] — the result will be copied into this Vector3.<br /><br />
+		[page:Vector3 target] — 如果指定了target ,结果将会被拷贝到target。<br /><br />
 
-		Returns the width, height and depth of this box.
+		返回包围盒的宽度,高度,和深度。
 		</p>
 
 		<h3>[method:Box3 intersect]( [param:Box3 box] )</h3>
 		<p>
-		[page:Box3 box] - Box to intersect with.<br /><br />
+		[page:Box3 box] - 与包围盒的交集<br /><br />
 
-		Returns the intersection of this and [page:Box3 box], setting the upper bound of this box to the lesser
-		of the two boxes' upper bounds and the lower bound of this box to the greater of the two boxes'
-		lower bounds.
+		返回此包围盒和 [page:Box3 box] 的交集,将此框的上界设置为两个框的max的较小部分,
+		将此包围盒的下界设置为两个包围盒的min的较大部分。
 		</p>
 
 		<h3>[method:Boolean intersectsBox]( [param:Box3 box] )</h3>
 		<p>
-		[page:Box3 box] - Box to check for intersection against.<br /><br />
+		[page:Box3 box] - 用来检测是否相交的包围盒<br /><br />
 
-		Determines whether or not this box intersects [page:Box3 box].
+		确定当前包围盒是否与传入包围盒[page:Box3 box] 相交。
 		</p>
 
 		<h3>[method:Boolean intersectsPlane]( [param:Plane plane] )</h3>
 		<p>
-		[page:Plane plane] - [page:Plane] to check for intersection against.<br /><br />
+		[page:Plane plane] - 用来检测是否相交的 [page:Plane]。<br /><br />
 
-		Determines whether or not this box intersects [page:Plane plane].
+		确定当前包围盒是否与平面 [page:Plane plane] 相交。
 		</p>
 
 		<h3>[method:Boolean intersectsSphere]( [param:Sphere sphere] )</h3>
 		<p>
-		[page:Sphere sphere] - [page:Sphere] to check for intersection against.<br /><br />
+		[page:Sphere sphere] - 用来检测是否相交的球体 [page:Sphere]。<br /><br />
 
-		Determines whether or not this box intersects [page:Sphere sphere].
+		确定当前包围盒是否与球体 [page:Sphere sphere] 相交。
 		</p>
 
 		<h3>[method:Boolean intersectsTriangle]( [param:Triangle triangle] )</h3>
 		<p>
-		[page:Triangle triangle] - [page:Triangle] to check for intersection against.<br /><br />
+		[page:Triangle triangle] - 用来检测是否相交的三角形 [page:Triangle]。<br /><br />
 
-		Determines whether or not this box intersects [page:Triangle triangle].
+		确定当前包围盒是否与三角形 [page:Triangle triangle] 相交。
 		</p>
 
 		<h3>[method:Boolean isEmpty]()</h3>
 		<p>
-		Returns true if this box includes zero points within its bounds.<br>
-		Note that a box with equal lower and upper bounds still includes one point,
-		the one both bounds share.
+		如果这个盒子包含0个顶点,则返回true。<br>
+		注意,下界和上界相等的方框仍然包含一个点,即两个边界共享的那个点。
 		</p>
 
 		<h3>[method:Box3 makeEmpty]()</h3>
-		<p>Makes this box empty.</p>
+		<p>清空包围盒。</p>
 
 		<h3>[method:Box3 set]( [param:Vector3 min], [param:Vector3 max] )</h3>
 		<p>
-		[page:Vector3 min] - [page:Vector3] representing the lower (x, y, z) boundary of the box.<br />
-		[page:Vector3 max] - [page:Vector3] representing the lower upper (x, y, z) boundary of the box.<br /><br />
+		[page:Vector3 min] - [page:Vector3] 表示下边界每个纬度(x,y,z)的值。<br />
+		[page:Vector3 max] - [page:Vector3] 表示上边界每个纬度(x,y,z)的值。<br /><br />
 
-		Sets the lower and upper (x, y, z) boundaries of this box.
+		设置包围盒上下边界每个纬度(x,y,z)的值。 
 		</p>
 
 		<h3>[method:Box3 setFromArray]( [param:Array array] ) [param:Box3 this]</h3>
 		<p>
-		array -- An array of position data that the resulting box will envelop.<br /><br />
+		array -- 数组当中的所有的点都将被包围盒包裹。<br /><br />
 
-		Sets the upper and lower bounds of this box to include all of the data in *array*.
+		设置包围盒的上下边界使得数组 *array* 中的所有点的点都被包含在内。
 		</p>
 
 		<h3>[method:Box3 setFromBufferAttribute]( [param:BufferAttribute attribute] ) [param:Box3 this]</h3>
 		<p>
-		[page:BufferAttribute attribute] - A buffer attribute of position data that the resulting box will envelop.<br /><br />
+		[page:BufferAttribute attribute] - 位置的缓冲数据,包含在返回的包围盒内。<br /><br />
 
-		Sets the upper and lower bounds of this box to include all of the data in [page:BufferAttribute attribute].
+		设置此包围盒的上边界和下边界,以包含 [page:BufferAttribute attribute] 中的所有位置数据。
 		</p>
 
-		<h3>[method:Box3 setFromCenterAndSize]( [param:Vector3 center], [param:Vector3 size] )</h3>
+<!--	<h3>[method:Box3 setFromCenterAndSize]( [param:Vector3 center], [param:Vector3 size] )</h3>
 		<p>
-		[page:Vector3 center] - Desired center position of the box ([page:Vector3]). <br>
-		[page:Vector3 size] - Desired x, y and z dimensions of the box ([page:Vector3]).<br /><br />
+		[page:Vector3 center] - 包围盒的中心位置 ([page:Vector3]). <br>
+		[page:Vector3 size] - 需要设置包围盒x,y,z的分量 ([page:Vector3]).<br /><br />
 
-		Centers this box on [page:Vector3 center] and sets this box's width and height to the values specified
-		in [page:Vector3 size].
-		</p>
+		将包围盒的中心点设为 [page:Vector3 center] ,然后将包围盒的宽高设为指定的 [page:Vector3 size]。
+		</p>-->	
 
 		<h3>[method:Box3 setFromCenterAndSize]( [param:Vector3 center], [param:Vector3 size] ) [param:Box3 this]</h3>
 		<p>
-		[page:Vector3 center], - Desired center position of the box. <br>
-		[page:Vector3 size] - Desired x, y and z dimensions of the box.<br /><br />
+		[page:Vector3 center], - 包围盒所要设置的中心位置。 <br>
+		[page:Vector3 size] - 包围盒所要设置的x、y和z尺寸(宽/高/长)。<br /><br />
 
-		Centers this box on [page:Vector3 center] and sets this box's width, height and depth to the values specified <br>
-		in [page:Vector3 size]
+		将当前包围盒的中心点设置为 [page:Vector3 center] ,并将此包围盒的宽度,高度和深度设置为大小指定 [page:Vector3 size] 的值。
 		</p>
 
 		<h3>[method:Box3 setFromObject]( [param:Object3D object] )</h3>
 		<p>
-		[page:Object3D object] - [page:Object3D] to compute the bounding box of.<br /><br />
+		[page:Object3D object] - 用来计算包围盒的3D对象 [page:Object3D]。<br /><br />
 
-		Computes the world-axis-aligned bounding box of an [page:Object3D] (including its children),
-		accounting for the object's, and children's, world transforms.
+		计算和世界轴对齐的一个对象 [page:Object3D] (含其子对象)的包围盒,计算对象和子对象的世界坐标变换。
 
 		</p>
 
 		<h3>[method:Box3 setFromPoints]( [param:Array points] )</h3>
 		<p>
-		[page:Array points] - Array of [page:Vector3 Vector3s] that the resulting box will contain.<br /><br />
+		[page:Array points] - 计算出的包围盒将包含数组中所有的点 [page:Vector3 Vector3s]<br /><br />
 
-		Sets the upper and lower bounds of this box to include all of the points in [page:Array points].
+		设置此包围盒的上边界和下边界,以包含数组 [page:Array points] 中的所有点。
 		</p>
 
 		<h3>[method:Box3 translate]( [param:Vector3 offset] )</h3>
 		<p>
-		[page:Vector3 offset] - Direction and distance of offset.<br /><br />
+		[page:Vector3 offset] - 偏移方向和距离。<br /><br />
 
-		Adds [page:Vector3 offset] to both the upper and lower bounds of this box, effectively moving this box
-		[page:Vector3 offset] units in 3D space.
+		给包围盒的上下边界添加偏移量 [page:Vector3 offset],这样可以有效的在3D空间中移动包围盒。
+		偏移量为 [page:Vector3 offset] 大小。
 		</p>
 
 		<h3>[method:Box3 union]( [param:Box3 box] )</h3>
 		<p>
-		[page:Box3 box] - Box that will be unioned with this box.<br /><br />
+		[page:Box3 box] - 要结合在一起的包围盒。<br /><br />
 
-		Unions this box with [page:Box3 box], setting the upper bound of this box to the greater of the
-		two boxes' upper bounds and the lower bound of this box to the lesser of the two boxes'
-		lower bounds.
+		在 [page:Box3 box] 参数的上边界和已有box对象的上边界之间取较大者,而对两者的下边界取较小者,这样获得一个新的较大的联合盒子。
 		</p>
 
-		<h2>Source</h2>
+		<h2>源码(Source</h2>
 
 		[link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js]
 	</body>

+ 96 - 103
docs/api/zh/math/Color.html

@@ -8,15 +8,15 @@
 		<link type="text/css" rel="stylesheet" href="page.css" />
 	</head>
 	<body>
-		<h1>[name]</h1>
+		<h1>颜色([name]</h1>
 
 		<p class="desc">
-		Class representing a color.
+		表示一个颜色。
 		</p>
 
 
-		<h2>Examples</h2>
-		A Color can be initialised in any of the following ways:
+		<h2>示例(Examples)</h2>
+		颜色可以用以下任意一种方式初始化。
 		<code>
 //empty constructor - will default white
 var color = new THREE.Color();
@@ -41,25 +41,25 @@ var color = new THREE.Color( 1, 0, 0 );
 
 
 
-		<h2>Constructor</h2>
+		<h2>构造器(Constructor</h2>
 
 
 		<h3>[name]( [param:Color_Hex_or_String r], [param:Float g], [param:Float b] )</h3>
 		<p>
-		[page:Color_Hex_or_String r] - (optional) If arguments [page:Float g] and [page:Float b] are defined, the red component of the color.
-		If they are not defined, it can be a [link:https://en.wikipedia.org/wiki/Web_colors#Hex_triplet hexadecimal triplet] (recommended), a CSS-style string, or another Color instance.<br />
-		[page:Float g] - (optional) If it is defined, the green component of the color.<br />
-		[page:Float b] - (optional) If it is defined, the blue component of the color.<br /><br />
+		[page:Color_Hex_or_String r] - (可选参数)  如果参数g和b被定义,则r表示颜色中的红色分量。
+		如果未被定义,r可以是一个十六进制 [link:https://en.wikipedia.org/wiki/Web_colors#Hex_triplet hexadecimal triplet] 颜色值或CSS样式的字符串或一个Color实例。<br />
+		[page:Float g] - (可选参数) 如果被定义,表示颜色中的绿色分量。<br />
+		[page:Float b] - (可选参数) 如果被定义,表示颜色中的蓝色分量。<br /><br />
 
-		Note that standard method of specifying color in three.js is with a [link:https://en.wikipedia.org/wiki/Web_colors#Hex_triplet hexadecimal triplet], and that method is used
-		throughout the rest of the documentation.<br /><br />
+		注意使用十六进制 [link:https://en.wikipedia.org/wiki/Web_colors#Hex_triplet hexadecimal triplet] 定义一个颜色在three.js中是标准的方法,而且其余
+		文档也将会使用这个方法。<br /><br />
 
-		When all arguments are defined then [page:Color_Hex_or_String r] is the red component, [page:Float g] is the green component and [page:Float b] is the blue component of the color.<br />
-		When only [page:Color_Hex_or_String r] is defined:<br />
+		当所有参数被定义时,r是红色分量,g是绿色分量,b是蓝色分量。<br />
+		当只有 [page:Color_Hex_or_String r] 被定义时:<br />
 		<ul>
-			<li>It can be a [link:https://en.wikipedia.org/wiki/Web_colors#Hex_triplet hexadecimal triplet] representing the color (recommended).</li>
-			<li>It can be an another Color instance.</li>
-			<li>It can be a CSS-style string. For example:
+			<li>它可用一个十六进制 [link:https://en.wikipedia.org/wiki/Web_colors#Hex_triplet hexadecimal triplet] 值表示颜色(推荐)。</li>
+			<li>它可以是一个另一个颜色实例。</li>
+			<li>它可以是另外一个CSS样式。例如:
 				<ul>
 					<li>'rgb(250, 0,0)'</li>
 					<li>'rgb(100%,0%,0%)'</li>
@@ -73,28 +73,28 @@ var color = new THREE.Color( 1, 0, 0 );
 		</ul>
 		</p>
 
-		<h2>Properties</h2>
+		<h2>属性(Properties</h2>
 
 		<h3>[property:Boolean isColor]</h3>
 		<p>
-			Used to check whether this or derived classes are Colors. Default is *true*.<br /><br />
+			用来检测此类或者派生类是否为颜色。默认值是 *true*。<br /><br />
 
-			You should not change this, as it used internally for optimisation.
+			不应该去改变这个值,因为它在内部用于优化。
 		</p>
 
 		<h3>[property:Float r]</h3>
 		<p>
-		Red channel value between 0 and 1. Default is 1.
+			红色通道的值在0到1之间。默认值为1。
 		</p>
 
 		<h3>[property:Float g]</h3>
 		<p>
-		Green channel value between 0 and 1. Default is 1.
+			绿色通道的值在0到1之间。默认值为1。
 		</p>
 
 		<h3>[property:Float b]</h3>
 		<p>
-		Blue channel value between 0 and 1. Default is 1.
+			蓝色通道的值在0到1之间。默认值为1。
 		</p>
 
 
@@ -102,102 +102,99 @@ var color = new THREE.Color( 1, 0, 0 );
 
 
 
-		<h2>Methods</h2>
+		<h2>方法(Methods</h2>
 
 		<h3>[method:Color add]( [param:Color color] ) </h3>
-		<p>Adds the RGB values of [page:Color color] to the RGB values of this color.</p>
+		<p>将给定颜色的RGB值添加到此颜色的RGB值。</p>
 
 		<h3>[method:Color addColors]( [param:Color color1], [param:Color color2] ) </h3>
-		<p>Sets this color's RGB values to the sum of the RGB values of [page:Color color1] and [page:Color color2].</p>
+		<p>将此颜色的RGB值设置为 [page:Color color1] 和 [page:Color color2] 的RGB值之和。</p>
 
 		<h3>[method:Color addScalar]( [param:Number s] ) </h3>
-		<p>Adds [page:Number s] to the RGB values of this color.</p>
+		<p>给现有的RGB值都加上 [page:Number s] 。</p>
 
 		<h3>[method:Color clone]() </h3>
-		<p>Returns a new Color with the same [page:.r r], [page:.g g] and [page:.b b] values as this one.</p>
+		<p>返回一个与当前颜色的 [page:.r r], [page:.g g] 和 [page:.b b] 相同的颜色。</p>
 
 		<h3>[method:Color copy]( [param:Color color] ) </h3>
 		<p>
-			Copies the [page:.r r], [page:.g g] and [page:.b b] parameters from [page:Color color] in to this color.
+			从 [page:Color color] 中拷贝 [page:.r r], [page:.g g] 和 [page:.b b] 值到当前的颜色。
 		</p>
 
 		<h3>[method:Color convertGammaToLinear]( [param:Float gammaFactor] ) </h3>
 		<p>
-		[page:Float gammaFactor] - (optional). Default is *2.0*.<br /><br />
-		Converts this color from gamma space to linear space by taking [page:.r r], [page:.g g] and [page:.b b] to the power of [page:Float gammaFactor].
+		[page:Float gammaFactor] - (可选参数). 默认值 *2.0*.<br /><br />
+		通过取颜色 [page:.r r], [page:.g g] and [page:.b b] 的 [page:Float gammaFactor] 次方将颜色从伽马空间转换成线性空间。
 		</p>
 		
 		<h3>[method:Color convertLinearToGamma]( [param:Float gammaFactor] ) </h3>
 		<p>
-		[page:Float gammaFactor] - (optional). Default is *2.0*.<br /><br />
-		Converts this color from linear space to gamma space by taking [page:.r r], [page:.g g] and [page:.b b] to the power of 1 / [page:Float gammaFactor].
+		[page:Float gammaFactor] - (可选参数). 默认值 *2.0*.<br /><br />
+		通过取颜色 [page:.r r], [page:.g g] and [page:.b b] 的 1/[page:Float gammaFactor] 次方将颜色从线性空间转换成伽马空间。
 		</p>
 
 		<h3>[method:Color convertLinearToSRGB]() </h3>
 		<p>
-		Converts this color from linear space to sRGB space.
+			将此颜色从线性空间转换成sRGB空间。
 		</p>
 
 		<h3>[method:Color convertSRGBToLinear]() </h3>
 		<p>
-		Converts this color from sRGB space to linear space.
+			将此颜色从sRGB空间转换成线性空间。
 		</p>
 
 		<h3>[method:Color copyGammaToLinear]( [param:Color color], [param:Float gammaFactor] ) </h3>
 		<p>
-		[page:Color color] — Color to copy.<br />
-		[page:Float gammaFactor] - (optional). Default is *2.0*.<br /><br />
+		[page:Color color] — 需要拷贝的颜色。<br />
+		[page:Float gammaFactor] - (可选参数). 默认值为 *2.0*.<br /><br />
 
-		Copies the given color into this color, and then converts this color from gamma space to linear space
-		by taking [page:.r r], [page:.g g] and [page:.b b] to the power of [page:Float gammaFactor].
+		将传入的 [param:Color color] 从伽马空间转换到线性空间然后复制给当前颜色。
 		</p>
 
 		<h3>[method:Color copyLinearToGamma]( [param:Color color], [param:Float gammaFactor] ) </h3>
 		<p>
-		[page:Color color] — Color to copy.<br />
-		[page:Float gammaFactor] - (optional). Default is *2.0*.<br /><br />
+		[page:Color color] — 需要拷贝的颜色。<br />
+		[page:Float gammaFactor] - (可选参数). 默认值为 *2.0*.<br /><br />
 
-		Copies the given color into this color, and then converts this color from linear space to gamma space
-		by taking [page:.r r], [page:.g g] and [page:.b b] to the power of 1 / [page:Float gammaFactor].
+		将传入的 [param:Color color] 从线性空间转换到伽马空间然后复制给当前颜色。
 		</p>
 
 		<h3>[method:Color copyLinearToSRGB]( [param:Color color]] ) </h3>
 		<p>
-		[page:Color color] — Color to copy.<br />
+		[page:Color color] — 需要拷贝的颜色。<br />
 
-		Copies the given color into this color, and then converts this color from linear space to sRGB space.
+		将传入的 [param:Color color] 拷贝给当前颜色,然后将当前颜色从线性空间转换到sRGB空间。
 		</p>
 
 		<h3>[method:Color copySRGBToLinear]( [param:Color color] ) </h3>
 		<p>
-		[page:Color color] — Color to copy.<br />
+		[page:Color color] — 需要拷贝的颜色。<br />
 
-		Copies the given color into this color, and then converts this color from sRGB space to linear space.
+		将传入的 [param:Color color] 拷贝给当前颜色,然后将当前颜色从sRGB空间转换到线性空间。
 		</p>
 
 		<h3>[method:Boolean equals]( [param:Color color] ) </h3>
-		<p>Compares the RGB values of [page:Color color] with those of this object. Returns true if they are the same, false otherwise.</p>
+		<p>将 [param:Color color] 的RGB值与该对象的RGB值进行比较。如果它们都是相同的,返回true,否则返回false。</p>
 
 		<h3>[method:Color fromArray]( [param:Array array], [param:Integer offset] ) </h3>
 		<p>
-		[page:Array array] - [page:Array] of floats in the form [ [page:Float r], [page:Float g], [page:Float b] ].<br />
-		[page:Integer offset] - An optional offset into the array.<br /><br />
+		[page:Array array] - 格式为 [ [page:Float r], [page:Float g], [page:Float b] ] 的数组 [page:Array]。<br />
+		[page:Integer offset] - 数组中可选偏移量<br /><br />
 
-		Sets this color's components based on an array formatted like [ [page:Float r], [page:Float g], [page:Float b] ].
+		从格式为[ [page:Float r], [page:Float g], [page:Float b] ]的数组数据中来创建Color对象。
 		</p>
 
 		<h3>[method:Integer getHex]()</h3>
-		<p>Returns the hexadecimal value of this color.</p>
+		<p>返回此颜色的十六进制值。</p>
 
 		<h3>[method:String getHexString]()</h3>
-		<p>Returns the hexadecimal value of this color as a string (for example, 'FFFFFF').</p>
+		<p>将此颜色的十六进制值作为字符串返回 (例如, 'FFFFFF')。</p>
 
 		<h3>[method:Object getHSL]( [param:Object target] )</h3>
 		<p>
-			[page:Object target] — the result will be copied into this Object. Adds h, s and l keys to the object (if not already present).<br /><br />
+			[page:Object target] — 结果将复制到这个对象中。向对象添加h、s和l键(如果不存在)。<br /><br />
 
-			Convert this Color's [page:.r r], [page:.g g] and [page:.b b] values to [link:https://en.wikipedia.org/wiki/HSL_and_HSV HSL]
-			format and returns an object of the form:
+			将此颜色的 [page:.r r], [page:.g g] 和 [page:.b b] 值转换为 [link:https://en.wikipedia.org/wiki/HSL_and_HSV HSL]格式,然后返回一个格式如下的对象:
 
 			<code>
 				{ h: 0, s: 0, l: 0 }
@@ -206,117 +203,113 @@ var color = new THREE.Color( 1, 0, 0 );
 		</p>
 
 		<h3>[method:String getStyle]()</h3>
-		<p>Returns the value of this color as a CSS style string. Example: 'rgb(255,0,0)'.</p>
+		<p>以CSS样式字符串的形式返回该颜色的值。例如:“rgb(255,0,0)”。</p>
 
 		<h3>[method:Color lerp]( [param:Color color], [param:Float alpha] ) </h3>
 		<p>
-		[page:Color color] - color to converge on.<br />
-		[page:Float alpha] - interpolation factor in the closed interval [0, 1].<br /><br />
+		[page:Color color] - 用于收敛的颜色。<br />
+		[page:Float alpha] - 介于0到1的数字。<br /><br />
 
-		Linearly interpolates this color's RGB values toward the RGB values of the passed argument.
-		The alpha argument can be thought of as the ratio between the two colors, where 0.0 is
-		this color and 1.0 is the first argument.
+		将该颜色的RGB值线性插值到传入参数的RGB值。alpha参数可以被认为是两种颜色之间的比例值,其中0是当前颜色和1.0是第一个参数的颜色。
 		</p>
 
 		<h3>[method:Color lerpHSL]( [param:Color color], [param:Float alpha] ) </h3>
 		<p>
-		[page:Color color] - color to converge on.<br />
-		[page:Float alpha] - interpolation factor in the closed interval [0, 1].<br /><br />
-
-		Linearly interpolates this color's HSL values toward the HSL values of the passed argument.
-		It differs from the classic [page:.lerp] by not interpolating straight from one color to the other,
-		but instead going through all the hues in between those two colors.
-		The alpha argument can be thought of as the ratio between the two colors, where 0.0 is
-		this color and 1.0 is the first argument.
+		[page:Color color] - 用于收敛的颜色。<br />
+		[page:Float alpha] - 介于0到1的数字。<br /><br />
+
+		将该颜色的HSL值线性插值到传递参数的HSL值。它不同于上诉的[page:lerp]。通过不直接从一种颜色插入到另一种颜色,
+		而是通过插值这两种颜色之间的所有色相(H)、亮度(L)、饱和度(S)。alpha参数可以被认为是两种颜色之间的比例值,
+		其中0是当前颜色和1.0是第一个参数的颜色。
 		</p>
 
 		<h3>[method:Color multiply]( [param:Color color] ) </h3>
-		<p>Multiplies this color's RGB values by the given [page:Color color]'s RGB values.</p>
+		<p>将此颜色的RGB值乘以给定的[page: color color]的RGB值。</p>
 
 		<h3>[method:Color multiplyScalar]( [param:Number s] ) </h3>
-		<p>Multiplies this color's RGB values by [page:Number s].</p>
+		<p>将此颜色的RGB值乘以给定的[page:Number s]的值。</p>
 
 		<h3>[method:Color offsetHSL]( [param:Float h], [param:Float s], [param:Float l] ) </h3>
 		<p>
-			Adds the given [page:Float h], [page:Float s], and [page:Float l] to this color's values.
-			Internally, this converts the color's [page:.r r], [page:.g g] and [page:.b b] values to HSL, adds
-			[page:Float h], [page:Float s], and [page:Float l], and then converts the color back to RGB.
+			将给定的 [page:Float h], [page:Float s], 和 [page:Float l]值加到当前颜色值。
+			内部的机制为:先将该颜色的 [page:.r r], [page:.g g] 和 [page:.b b] 值转换为HSL,然后与传入的[page:Float h], [page:Float s], 和 [page:Float l]
+			相加,最后再将结果转成RGB值。
 		</p>
 
 		<h3>[method:Color set]( [param:Color_Hex_or_String value] ) </h3>
 		<p>
-		[page:Color_Hex_or_String value] - Value to set this color to.<br /><br />
+		[page:Color_Hex_or_String value] - 用于设置该颜色的值。<br /><br />
 
-		See the Constructor above for full details of what [page:Color_Hex_or_String value] can be.
-		Delegates to [page:.copy], [page:.setStyle], or [page:.setHex] depending on input type.
+		有关 [page:Color_Hex_or_String value] 的详细信息,请参阅上面的构造函数。
+		根据输入类型,将会委托给 [page:.copy], [page:.setStyle], 或者 [page:.setHex] 函数处理。
 		</p>
 
 		<h3>[method:Color setHex]( [param:Integer hex] ) </h3>
 		<p>
-		[page:Integer hex] — [link:https://en.wikipedia.org/wiki/Web_colors#Hex_triplet hexadecimal triplet] format.<br /><br />
+		[page:Integer hex] — [link:https://en.wikipedia.org/wiki/Web_colors#Hex_triplet hexadecimal triplet] 格式。<br /><br />
+
+		采用十六进制值设置此颜色。
 
-		Sets this color from a hexadecimal value.
 		</p>
 
 		<h3>[method:Color setHSL]( [param:Float h], [param:Float s], [param:Float l] ) </h3>
 		<p>
-		[page:Float h] — hue value between 0.0 and 1.0 <br />
-		[page:Float s] — saturation value between 0.0 and 1.0 <br />
-		[page:Float l] — lightness value between 0.0 and 1.0<br /><br />
+		[page:Float h] — 色相值处于0到1之间。hue value between 0.0 and 1.0 <br />
+		[page:Float s] — 饱和度值处于0到1之间。<br />
+		[page:Float l] — 亮度值处于0到1之间。<br /><br />
 
-		Sets color from HSL values.
+		采用HLS值设置此颜色。
 		</p>
 
 		<h3>[method:Color setRGB]( [param:Float r], [param:Float g], [param:Float b] ) </h3>
 		<p>
-		[page:Float r] — Red channel value between 0.0 and 1.0.<br />
-		[page:Float g] — Green channel value between 0.0 and 1.0.<br />
-		[page:Float b] — Blue channel value between 0.0 and 1.0.<br /><br />
+		[page:Float r] — 红色通道的值在0到1之间。<br />
+		[page:Float g] — 绿色通道的值在0到1之间。<br />
+		[page:Float b] — 蓝色通道的值在0到1之间。<br /><br />
 
-		Sets this color from RGB values.
+		采用RGB值设置此颜色。
 		</p>
 
 		<h3>[method:Color setScalar]( [param:Float scalar] ) </h3>
 		<p>
-		[page:Float scalar] — a value between 0.0 and 1.0.<br /><br />
+		[page:Float scalar] — 处于0到1之间的值<br /><br />
 
-		Sets all three color components to the value [page:Float scalar].
+		将颜色的RGB值都设为该 [page:Float scalar] 的值。
 		</p>
 
 		<h3>[method:Color setStyle]( [param:String style] ) </h3>
 		<p>
-		[page:String style] — color as a CSS-style string.<br /><br />
+		[page:String style] — 颜色css样式的字符串<br /><br />
 
-		Sets this color from a CSS-style string. For example,
+		采用ccs样式的字符串设置此颜色。例如,
 		"rgb(250, 0,0)",
 		"rgb(100%, 0%, 0%)",
 		"hsl(0, 100%, 50%)",
 		"#ff0000",
-		"#f00", or
-		"red" ( or any [link:https://en.wikipedia.org/wiki/X11_color_names#Color_name_chart X11 color name]
-		- all 140 color names are supported ).<br />
+		"#f00", 或者
+		"red" ( 或者任何 [link:https://en.wikipedia.org/wiki/X11_color_names#Color_name_chart X11 color name]
+		- 所有140种颜色名称都支持 ).<br />
 
-		Translucent colors such as "rgba(255, 0, 0, 0.5)" and "hsla(0, 100%, 50%, 0.5)" are also accepted,
-		but the alpha-channel coordinate will be discarded.<br /><br />
+		半透明颜色例如 "rgba(255, 0, 0, 0.5)" and "hsla(0, 100%, 50%, 0.5)" 也能支持,
+		但是alpha通道的值将会被丢弃。<br /><br />
 
-		Note that for X11 color names, multiple words such as Dark Orange become the string 'darkorange' (all lowercase).
+		注意,对于X11颜色名称,多个单词(如暗橙色)变成字符串“darkorange”(全部是小写字母)。
 		</p>
 
 		<h3>[method:Color sub]( [param:Color color] ) </h3>
 		<p>
-		Subtracts the RGB components of the given color from the RGB components of this color.
-		If this results in a negative component, that component is set to zero.
+		从该颜色的RGB分量中减去传入颜色的RGB分量。如果分量结果是负,则该分量为零。
 		</p>
 
 		<h3>[method:Array toArray]( [param:Array array], [param:Integer offset] ) </h3>
 		<p>
-		[page:Array array] - An optional array to store the color to. <br />
-		[page:Integer offset] - An optional offset into the array.<br /><br />
+		[page:Array array] -  存储颜色的可选数组 <br />
+		[page:Integer offset] - 数组的可选偏移量<br /><br />
 
-		Returns an array of the form [ r, g, b ].
+		返回一个格式为[ r, g, b ] 数组。
 		</p>
 
-		<h2>Source</h2>
+		<h2>源码(Source</h2>
 
 		[link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js]
 	</body>

+ 17 - 19
docs/api/zh/math/Cylindrical.html

@@ -8,26 +8,25 @@
 		<link type="text/css" rel="stylesheet" href="page.css" />
 	</head>
 	<body>
-		<h1>[name]</h1>
+		<h1>圆柱体[name]</h1>
 
 		<p class="desc">
 			A point's [link:https://en.wikipedia.org/wiki/Cylindrical_coordinate_system cylindrical coordinates].
 		</p>
 
 
-		<h2>Constructor</h2>
+		<h2>构造器(Constructor</h2>
 
 		<h3>[name]( [param:Float radius], [param:Float theta], [param:Float y] )</h3>
 		<p>
-		[page:Float radius] - distance from the origin to a point in the x-z plane.
-		Default is *1.0*.<br />
-		[page:Float theta] - counterclockwise angle in the x-z plane measured in radians
-		from the positive z-axis. Default is *0*.<br />
-		[page:Float y] - height above the x-z plane. Default is *0*.
+		[page:Float radius] - 从原点到x-z平面上一点的距离
+		默认值为 *1.0*.<br />
+		[page:Float theta] - 在x-z平面内的逆时针角度,以z轴正方向的计算弧度。默认值为0。<br />
+		[page:Float y] - x-z平面以上的高度 默认值为 *0*.
 		</p>
 
 
-		<h2>Properties</h2>
+		<h2>属性(Properties</h2>
 
 		<h3>[property:Float radius]</h3>
 
@@ -40,33 +39,32 @@
 
 		<h3>[method:Cylindrical clone]()</h3>
 		<p>
-		Returns a new cylindrical with the same [page:.radius radius], [page:.theta theta]
-		and [page:.y y] properties as this one.
+			返回一个与当前拥有相同 [page:.radius radius], [page:.theta theta] 和 [page:.y y] 属性的圆柱体。
 		</p>
 
 		<h3>[method:Cylindrical copy]( [param:Cylindrical other] )</h3>
 		<p>
-			Copies the values of the passed Cylindrical's [page:.radius radius], [page:.theta theta]
-			and [page:.y y] properties to this cylindrical.
+			将传入的圆柱体对象的 [page:.radius radius], [page:.theta theta] 和 [page:.y y] 属性赋给当前对象。
 		</p>
 
 		<h3>[method:Cylindrical set]( [param:Float radius], [param:Float theta], [param:Float y] )</h3>
-		<p>Sets values of this cylindrical's [page:.radius radius], [page:.theta theta]
-		and [page:.y y] properties.</p>
+		<p>设置该对象的 [page:.radius radius], [page:.theta theta]
+		和 [page:.y y] 属性。</p>
 
 		<h3>[method:Cylindrical setFromVector3]( [param:Vector3 vec3] )</h3>
 		<p>
-			Sets values of this cylindrical's [page:.radius radius], [page:.theta theta]
-			and [page:.y y] properties from the [page:Vector3 Vector3].
+			从 [page:Vector3 Vector3] 中取x,y,z,并调用setFromCartesianCoords来设置圆柱体的
+			[page:.radius radius]、[page:.theta theta] 和 [page:.y y] 的属性值。
+
 		</p>
 
 		<h3>[method:Cylindrical setFromCartesianCoords]( [param:Float x], [param:Float y], [param:Float z] )</h3>
 		<p>
-			Sets values of this cylindrical's [page:.radius radius], [page:.theta theta]
-			and [page:.y y] properties from Cartesian coordinates.
+			使用笛卡尔坐标来设置该圆柱体的 [page:.radius radius], [page:.theta theta]
+			and [page:.y y] 属性值。
 		</p>
 
-		<h2>Source</h2>
+		<h2>源码(Source</h2>
 
 		[link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js]
 	</body>

+ 64 - 75
docs/api/zh/math/Euler.html

@@ -11,13 +11,11 @@
 		<h1>[name]</h1>
 
 		<p class="desc">
-			A class representing [link:http://en.wikipedia.org/wiki/Euler_angles Euler Angles].<br /><br />
-
-			Euler angles describe a rotational transformation by rotating an object on its various
-			axes in specified amounts per axis, and a specified axis order.
+			表示 [link:http://en.wikipedia.org/wiki/Euler_angles Euler] 的类。<br /><br />
+			欧拉角描述一个旋转变换,通过指定轴顺序和其各个轴向上的指定旋转角度来旋转一个物体。
 		</p>
 
-		<h2>Example</h2>
+		<h2>示例(Example</h2>
 
 		<code>var a = new THREE.Euler( 0, 1, 1.57, 'XYZ' );
 		var b = new THREE.Vector3( 1, 0, 1 );
@@ -25,167 +23,158 @@
 		</code>
 
 
-		<h2>Constructor</h2>
+		<h2>构造器(Constructor</h2>
 
 
 		<h3>[name]( [param:Float x], [param:Float y], [param:Float z], [param:String order] )</h3>
 		<p>
-		[page:Float x] - (optional) the angle of the x axis in radians. Default is *0*.<br />
-		[page:Float y] - (optional) the angle of the y axis in radians. Default is *0*.<br />
-		[page:Float z] - (optional) the angle of the z axis in radians. Default is *0*.<br />
-		[page:String order] - (optional) a string representing the order that the rotations are applied,
-		defaults to 'XYZ' (must be upper case).<br /><br />
+		[page:Float x] - (optional) 用弧度表示x轴旋转量。 默认值是 *0*。<br />
+		[page:Float y] - (optional) 用弧度表示y轴旋转量。 默认值是 *0*。<br />
+		[page:Float z] - (optional) 用弧度表示z轴旋转量。 默认值是 *0*。<br />
+		[page:String order] - (optional) 表示旋转顺序的字符串,默认为'XYZ'(必须是大写)。<br /><br />
 
 		</p>
 
 
-		<h2>Properties</h2>
+		<h2>属性(Properties</h2>
 
 		<h3>[property:Boolean isEuler]</h3>
 		<p>
-			Used to check whether this or derived classes are Eulers. Default is *true*.<br /><br />
-
-			You should not change this, as it used internally for optimisation.
+			用于判定此对象或者此类的派生对象是否是欧拉角。默认值为 *true*。<br /><br />
+			
+			不应该改变该值,因为它在内部用于优化。
 		</p>
 
 		<h3>[property:String order]</h3>
 		<p>
-			The order in which to apply rotations. Default is 'XYZ', which means that the object will first be
-			rotated around its X axis, then its Y axis and finally its Z axis. Other possibilities are:
-			'YZX', 'ZXY', 'XZY', 'YXZ' and 'ZYX'. These must be in upper case.<br /><br />
+			order值应用于旋转顺序。默认值为 'XYZ',这意味着对象将首先是
+			绕X轴旋转,然后是Y轴,最后是Z轴。其他可能性包括:
+			'YZX', 'ZXY', 'XZY', 'YXZ'和'ZYX'。这些必须是大写字母。<br /><br />
+			Three.js 使用<em>intrinsic</em> Tait-Bryan angles(Yaw、Pitch、Roll)。
+			这意味着旋转是在<em>本地</em>坐标系下进行的。也就是说,对于“XYZ”订单,首先是围绕local-X轴旋转(与world- x轴相同),
+			然后是local-Y(现在可能与world y轴不同),然后是local-Z(可能与world z轴不同)。<br /><br />
 
-			Three.js uses <em>intrinsic</em> Tait-Bryan angles. This means that rotations are performed with respect
-			to the <em>local</em> coordinate system. That is, for order 'XYZ', the rotation is first around the local-X
-			axis (which is the same as the world-X axis), then around local-Y (which may now be different from the
-			world Y-axis), then local-Z (which may be different from the world Z-axis).<br /><br />
-
-			If the order is changed, [page:.onChangeCallback onChangeCallback] will be called.
+			如果order值被改变,[page:.onChangeCallback onChangeCallback] 会被调用。
 		</p>
 
 		<h3>[property:Float x]</h3>
 		<p>
-			The current value of the x component.<br /><br />
+			当前x分量的值。<br /><br />
 
-			If this is changed, [page:.onChangeCallback onChangeCallback] will be called.
+			如果这个值发生变化,[page:.onChangeCallback onChangeCallback] 会被调用。
 		</p>
 
 		<h3>[property:Float y]</h3>
 		<p>
-			The current value of the y component.<br /><br />
+			当前y分量的值。<br /><br />
 
-			If this is changed, [page:.onChangeCallback onChangeCallback] will be called.
+			如果这个值发生变化,[page:.onChangeCallback onChangeCallback] 会被调用。
 		</p>
 
 		<h3>[property:Float z]</h3>
 		<p>
-			The current value of the z component.<br /><br />
+			当前z分量的值。<br /><br />
 
-			If this is changed, [page:.onChangeCallback onChangeCallback] will be called.
+			如果这个值发生变化,[page:.onChangeCallback onChangeCallback] 会被调用。
 		</p>
 
-		<h2>Methods</h2>
+		<h2>方法(Methods</h2>
 
 		<h3>[method:Euler copy]( [param:Euler euler] )</h3>
-		<p>Copies value of [page:Euler euler] to this euler.</p>
+		<p>将 [page:Euler euler] 的属性拷贝到当前对象。</p>
 
 		<h3>[method:Euler clone]()</h3>
-		<p>Returns a new Euler with the same parameters as this one.</p>
+		<p>返回一个与当前参数相同的新欧拉角。</p>
 
 		<h3>[method:Boolean equals]( [param:Euler euler] )</h3>
-		<p>Checks for strict equality of this euler and [page:Euler euler].</p>
+		<p>检查 [page:Euler euler] 是否与当前对象相同。</p>
 
 		<h3>[method:Euler fromArray]( [param:Array array] )</h3>
 		<p>
-		[page:Array array] of length 3 or 4. The optional 4th argument corresponds to the [page:.order order].<br /><br />
-
-		Assigns this euler's [page:.x x] angle to array[0]. <br />
-		Assigns this euler's [page:.y y] angle to array[1]. <br />
-		Assigns this euler's [page:.z z] angle to array[2]. <br />
-		Optionally assigns this euler's [page:.order order] to array[3].
+		长度为3或4的一个 [page:Array array] 。array[3] 是一个可选的 [page:.order order] 参数。<br /><br />
+		
+		将欧拉角的x分量设置为 array[0]。 <br />
+		将欧拉角的x分量设置为 array[1]。 <br />
+		将欧拉角的x分量设置为 array[2]。 <br />
+		将array[3]设置给欧拉角的 [page:.order order] 。可选。
 		</p>
 
 		<h3>[method:Euler onChange]( [param:Function onChangeCallback] )</h3>
 		<p>
-			[page:Function onChangeCallback] - set the value of the onChangeCallback() function.
+			[page:Function onChangeCallback] - 为 onChangeCallback() 函数赋值。
 		</p>
 
 		<h3>[method:Euler onChangeCallback](  )</h3>
 		<p>
-			By default this is an empty function, however it can be set via [page:.onChange onChange]().<br />
-			It gets called after changing the [page:.x x], [page:.y y], [page:.z z] or [page:.order order] properties,
-			and also after calling most setter functions (see those for details).
+			默认情况下,这个函数为空,但是它可以通过[page:.onChange onChange]()来设置。<br />
+			在更改 [page:.x x], [page:.y y], [page:.z z] 或 [page:.order order] 属性之后调用它,
+			在调用大多数setter函数之后也会调用它(详细信息请参阅那些函数)。
 		</p>
 
 		<h3>[method:Euler reorder]( [param:String newOrder] )</h3>
 		<p>
-		Resets the euler angle with a new order by creating a quaternion from this euler angle
-		and then setting this euler angle with the quaternion and the new order. <br /><br />
+		通过这个欧拉角创建一个四元数,然后用这个四元数和新顺序设置这个欧拉角。 <br /><br />
 
-		<em>WARNING</em>: this discards revolution information.
+		<em>警告</em>: 这将弃用旋转信息。
 		</p>
 
 		<h3>[method:Euler set]( [param:Float x], [param:Float y], [param:Float z], [param:String order] )</h3>
 		<p>
-			[page:.x x] - the angle of the x axis in radians.<br />
-			[page:.y y] - the angle of the y axis in radians.<br />
-			[page:.z z] - the angle of the z axis in radians.<br />
-			[page:.order order] - (optional) a string representing the order that the rotations are applied.<br /><br />
+			[page:.x x] - 用弧度表示x轴旋转量。<br />
+			[page:.y y] - 用弧度表示y轴旋转量。<br />
+			[page:.z z] - 用弧度表示z轴旋转量。<br />
+			[page:.order order] - (optional) 表示旋转顺序的字符串。<br /><br />
 
-			Sets the angles of this euler transform and optionally the [page:.order order] and then call [page:.onChangeCallback onChangeCallback]().
+			设置该欧拉变换的角度和旋转顺序 [page:.order order] ,然后调用  [page:.onChangeCallback onChangeCallback]()。
 		</p>
 
 		<h3>[method:Euler setFromRotationMatrix]( [param:Matrix4 m], [param:String order], [param:Boolean update] )</h3>
 		<p>
-		[page:Matrix4 m] - a [page:Matrix4] of which the upper 3x3 of matrix is a pure
-		[link:https://en.wikipedia.org/wiki/Rotation_matrix rotation matrix] (i.e. unscaled).<br />
-		[page:.order order] - (optional) a string representing the order that the rotations are applied.<br />
-		[page:Boolean update] - (optional) whether to call [page:.onChangeCallback onChangeCallback]() after applying
-		the matrix.<br /><br />
+		[page:Matrix4 m] - [page:Matrix4] 矩阵上面的3x3部分是一个纯旋转矩阵[link:https://en.wikipedia.org/wiki/Rotation_matrix rotation matrix]
+		(也就是不发生缩放)<br />
+		[page:.order order] - (可选参数) 表示旋转顺序的字符串。<br />
+		[page:Boolean update] - (可选参数) 表示设置完变换矩阵后是否调用 [page:.onChangeCallback onChangeCallback]。<br /><br />
 
-		Sets the angles of this euler transform from a pure rotation matrix based on the orientation
-		specified by order.
+		使用基于 [page:.order order] 顺序的纯旋转矩阵来设置当前欧拉角。
 		</p>
 
 		<h3>[method:Euler setFromQuaternion]( [param:Quaternion q], [param:String order], [param:Boolean update] )</h3>
 		<p>
-		[page:Quaternion q] - a normalized quaternion.<br />
-		[page:.order order] - (optional) a string representing the order that the rotations are applied.<br />
-		[page:Boolean update] - (optional) whether to call [page:.onChangeCallback onChangeCallback]() after applying
-		the matrix.<br /><br />
+		[page:Quaternion q] - 归一化的四元数。<br />
+		[page:.order order] - (可选参数) 表示旋转顺序的字符串。<br />
+		[page:Boolean update] - (可选参数) 表示设置完变换矩阵后是否调用 [page:.onChangeCallback onChangeCallback]。<br /><br />
 
-		Sets the angles of this euler transform from a normalized quaternion based on the orientation
-		specified by [page:.order order].
+		根据 [page:.order order] 指定的方向,使用归一化四元数设置这个欧拉变换的角度。
 		</p>
 
 
 		<h3>[method:Euler setFromVector3]( [param:Vector3 vector], [param:String order] )</h3>
 		<p>
 		[page:Vector3 vector] - [page:Vector3].<br />
-		[page:.order order] - (optional) a string representing the order that the rotations are applied.<br /><br />
+		[page:.order order] - (可选参数) 表示旋转顺序的字符串。<br /><br />
 
-		Set the [page:.x x], [page:.y y] and [page:.z z], and optionally update the [page:.order order]. [page:.onChangeCallback onChangeCallback]()
-		is called after these changes are made.
+		设置 [page:.x x], [page:.y y] and [page:.z z] 并且选择性更新 [page:.order order]。
+		更改完成之后调用 [page:.onChangeCallback onChangeCallback]()。
 		</p>
 
 
 		<h3>[method:Array toArray]( [param:Array array], [param:Integer offset] )</h3>
 		<p>
-		[page:Array array] - (optional) array to store the euler in.<br />
-		[page:Integer offset] (optional) offset in the array.<br />
+		[page:Array array] - (可选参数) 存储欧拉角的数组。<br />
+		[page:Integer offset] (可选参数) 数组的偏移量。<br />
 
-		Returns an array of the form [[page:.x x], [page:.y y], [page:.z z], [page:.order order ]].
+		返回一个数组:[[page:.x x], [page:.y y], [page:.z z], [page:.order order ]]。
 		</p>
 
 		<h3>[method:Vector3 toVector3]( [param:Vector3 optionalResult] )</h3>
 		<p>
-			[page:Vector3 optionalResult] — (optional) If specified, the result will be copied into this Vector,
-			otherwise a new one will be created. <br /><br />
+			[page:Vector3 optionalResult] — (可选参数) 如果指定了该参数结果将会被复制给该参数,否者会创建一个新的 Vector3 <br /><br />
 
-			Returns the Euler's [page:.x x], [page:.y y] and [page:.z z] properties as a [page:Vector3].
+			以 [page:Vector3] 的形式返回欧拉角的 [page:.x x], [page:.y y] 和 [page:.z z]。
 		</p>
 
 
-		<h2>Source</h2>
+		<h2>源码(Source</h2>
 
 		[link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js]
 	</body>

+ 33 - 36
docs/api/zh/math/Frustum.html

@@ -8,99 +8,96 @@
 		<link type="text/css" rel="stylesheet" href="page.css" />
 	</head>
 	<body>
-		<h1>[name]</h1>
+		<h1>视锥体([name]</h1>
 
 		<p class="desc">
-			[link:http://en.wikipedia.org/wiki/Frustum Frustums] are used to determine what is
-			inside the camera's field of view. They help speed up the rendering process - object which lie
-			outside a camera's frustum can safely be excluded from rendering.<br /><br />
+			[link:http://en.wikipedia.org/wiki/Frustum Frustums] 用于确定相机视野内的东西。
+			它有助于加速渲染过程——位于摄像机视锥体外的物体可以安全地排除在渲染之外。<br /><br />
 
-			This class is mainly intended for use internally by a renderer for calculating
-			a [page:Camera camera] or [page:LightShadow.camera shadowCamera]'s frustum.
+			该类主要用于渲染器内部计算 [page:Camera camera] 或 [page:LightShadow.camera shadowCamera]的视锥体。
 		</p>
 
 
-		<h2>Constructor</h2>
+		<h2>构造器(Constructor)</h2>
 
 
 		<h3>[name]([param:Plane p0], [param:Plane p1], [param:Plane p2], [param:Plane p3], [param:Plane p4], [param:Plane p5])</h3>
 		<p>
-			[page:Plane p0] - (optional) defaults to a new [page:Plane].<br />
-			[page:Plane p1] - (optional) defaults to a new [page:Plane].<br />
-			[page:Plane p2] - (optional) defaults to a new [page:Plane].<br />
-			[page:Plane p3] - (optional) defaults to a new [page:Plane].<br />
-			[page:Plane p4] - (optional) defaults to a new [page:Plane].<br />
-			[page:Plane p5] - (optional) defaults to a new [page:Plane].<br /><br />
-
-			Creates a new [name].
+			[page:Plane p0] - (可选参数)  [page:Plane].<br />
+			[page:Plane p1] - (可选参数)  [page:Plane].<br />
+			[page:Plane p2] - (可选参数)  [page:Plane].<br />
+			[page:Plane p3] - (可选参数)  [page:Plane].<br />
+			[page:Plane p4] - (可选参数)  [page:Plane].<br />
+			[page:Plane p5] - (可选参数)  [page:Plane].<br /><br />
+
+			使用6个面来构建一个视锥体。
 		</p>
 
 
-		<h2>Properties</h2>
+		<h2>属性(Properties</h2>
 
 		<h3>[property:Array planes]</h3>
-		<p>Array of 6 [page:Plane planes].</p>
+		<p>包含6个平面 [page:Plane planes] 的数组。</p>
 
 
-		<h2>Methods</h2>
+		<h2>方法(Methods</h2>
 
 		<h3>[method:Frustum clone]()</h3>
-		<p>Return a new Frustum with the same parameters as this one.</p>
+		<p>返回一个与当前对象有相同参数的视锥体。</p>
 
 
 		<h3>[method:Boolean containsPoint]( [param:Vector3 point] )</h3>
 		<p>
 		[page:Vector3 point] - [page:Vector3] to test.<br /><br />
 
-		Checks to see if the frustum contains the [page:Vector3 point].
+		检测该点 [page:Vector3 point] 是否在视锥体内。
 		</p>
 
 		<h3>[method:Frustum copy]( [param:Frustum frustum] )</h3>
 		<p>
-		[page:Frustum frustum] - The frustum to copy<br /><br />
+		[page:Frustum frustum] - 用于拷贝的视锥体。<br /><br />
 
-		Copies the properties of the passed [page:Frustum frustum] into this one.
+		将传入 [page:Frustum frustum] 的属性拷贝到当前对象。
 		</p>
 
 		<h3>[method:Boolean intersectsBox]( [param:Box3 box] )</h3>
 		<p>
-		[page:Box3 box] - [page:Box3] to check for intersection.<br /><br />
-
-	 	Return true if [page:Box3 box] intersects with this frustum.
+		[page:Box3 box] - [page:Box3] 用于检测是否要交的包围盒。<br /><br />
+		
+		返回 true 如果该 [page:Box3 box] 与视锥体相交。
 		</p>
 
 		<h3>[method:Boolean intersectsObject]( [param:Object3D object] )</h3>
 		<p>
-			Checks whether the [page:Object3D object]'s [page:Geometry.boundingSphere bounding sphere] is intersecting the Frustum.<br /><br />
+			检测 [page:Object3D object] 的包围球 [page:Geometry.boundingSphere bounding sphere] 是否与视锥体相交。<br /><br />
 
-			Note that the object must have a [page:Geometry] or [page:BufferGeometry] so that the bounding sphere
-			can be calculated.
+			注意:该对象必须有一个 [page:Geometry] 或 [page:BufferGeometry] ,因为这样才能计算出包围球。
 		</p>
 
 		<h3>[method:Boolean intersectsSphere]( [param:Sphere sphere] )</h3>
 		<p>
-		[page:Sphere sphere] - [page:Sphere] to check for intersection.<br /><br />
+		[page:Sphere sphere] - [page:Sphere] 用于检查是否相交。<br /><br />
 
-	 	Return true if [page:Sphere sphere] intersects with this frustum.
+		返回true 如果球[page:Sphere sphere]与视锥体相交。
 		</p>
 
 		<h3>[method:Boolean intersectsSprite]( [param:Sprite sprite] )</h3>
 		<p>
-			Checks whether the [page:Sprite sprite] is intersecting the Frustum.<br /><br />
+			检查精灵[page:Sprite sprite]是否与截锥体相交。<br /><br />
 		</p>
 
 		<h3>[method:Frustum set]( [param:Plane p0], [param:Plane p1], [param:Plane p2], [param:Plane p3], [param:Plane p4], [param:Plane p5] )</h3>
 		<p>
-		Sets the current frustum from the passed planes. No plane order is implicitely implied.
+			使用传入的平面设置当前视锥体。没有隐式的顺序。
 		</p>
 
 		<h3>[method:Frustum setFromMatrix]( [param:Matrix4 matrix] )</h3>
 		<p>
-			[page:Matrix4 matrix] - [page:Matrix4] used to set the [page:.planes planes]<br /><br />
+			[page:Matrix4 matrix] - [page:Matrix4] 用于设置 [page:.planes planes]<br /><br />
 
-			This is used by the [page:WebGLRenderer] to set up the Frustum from a [page:Camera Camera]'s
-			[page:Camera.projectionMatrix projectionMatrix] and [page:Camera.matrixWorldInverse matrixWorldInverse].
-		</p>
+			[page:WebGLRenderer] 使用 [page:Camera Camera]的投影矩阵([page:Camera.projectionMatrix projectionMatrix] )
+			和相机世界变换矩阵的逆矩阵 [page:Camera.matrixWorldInverse matrixWorldInverse] 来设置视锥体。
+				</p>
 
 
 

+ 10 - 11
docs/api/zh/math/Interpolant.html

@@ -8,21 +8,20 @@
 		<link type="text/css" rel="stylesheet" href="page.css" />
 	</head>
 	<body>
-		<h1>[name]</h1>
+		<h1>插值器([name]</h1>
 
 		<p class="desc">
-		Abstract base class of interpolants over parametric samples.<br /><br />
+		A参数样本上插值的抽象基类 <br /><br />
 
-		The parameter domain is one dimensional, typically the time or a path along a curve defined by the data.<br /><br />
+		参数域是一维的,通常是数据定义的曲线上的时间或路径。<br /><br />
 
-		The sample values can have any dimensionality and derived classes may apply special interpretations to the data.<br /><br />
+		示例值可以具有任何维度,派生类可以对数据应用特殊的解释。<br /><br />
 
-		This class provides the interval seek in a Template Method, deferring the actual interpolation to derived classes.<br /><br />
+		该类提供间隔查找的模板方法,将实际的插值延迟到派生类。<br /><br />
 
-		Time complexity is *O(1)* for linear access crossing at most two points and *O(log N)* for random access,
-		where *N* is the number of positions.<br /><br />
+		对于最多两个点之间的访问时间复杂度为O(1),对于随机访问时间复杂度为O(log N),其中N为位置数。<br /><br />
 
-		References:	[link:http://www.oodesign.com/template-method-pattern.html http://www.oodesign.com/template-method-pattern.html]
+		相关:	[link:http://www.oodesign.com/template-method-pattern.html http://www.oodesign.com/template-method-pattern.html]
 		</p>
 
 
@@ -38,7 +37,7 @@
 		sampleSize -- number of samples<br />
 		resultBuffer -- buffer to store the interpolation results.<br /><br />
 
-		Note: This is not designed to be called directly.
+		注意: 这不是设计为直接调用的。
 		</p>
 
 		<h2>Properties</h2>
@@ -74,10 +73,10 @@
 
 		<h3>[method:null evaluate]( [param:Number t] )</h3>
 		<p>
-		Evaluate the interpolant at position *t*.
+			计算补间函数在位置 *t* 的值。
 		</p>
 
-		<h2>Source</h2>
+		<h2>源码(Source</h2>
 
 		[link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js]
 	</body>

+ 34 - 40
docs/api/zh/math/Line3.html

@@ -8,79 +8,75 @@
 		<link type="text/css" rel="stylesheet" href="page.css" />
 	</head>
 	<body>
-		<h1>[name]</h1>
+		<h1>三维几何线段([name]</h1>
 
-		<p class="desc">A geometric line segment represented by a start and end point.</p>
+		<p class="desc">用起点和终点表示的几何线段。</p>
 
 
-		<h2>Constructor</h2>
+		<h2>构造器(Constructor</h2>
 
 
 		<h3>[name]( [param:Vector3 start], [param:Vector3 end] )</h3>
 		<p>
-		[page:Vector3 start] - Start of the line segment. Default is (0, 0, 0).<br />
-		[page:Vector3 end] - End of the line segment. Default is (0, 0, 0).<br /><br />
+		[page:Vector3 start] - 线段的起始点。默认值为 (0, 0, 0)。<br />
+		[page:Vector3 end] - 线段的终点。默认值为 (0, 0, 0)。<br /><br />
 
-		Creates a new [name].
+		创建一个三维几何线段 [name]。
 		</p>
 
 
-		<h2>Properties</h2>
+		<h2>属性(Properties</h2>
 
 		<h3>[property:Vector3 start]</h3>
-		<p>[page:Vector3] representing the start point of the line.</p>
+		<p>[page:Vector3] 表示线段的起点。</p>
 
 		<h3>[property:Vector3 end]</h3>
-		<p>[page:Vector3] representing the end point of the line.</p>
+		<p>[page:Vector3] 表示线段的终点</p>
 
 
 
 
 
-		<h2>Methods</h2>
+		<h2>方法(Methods</h2>
 
 		<h3>[method:Line3 applyMatrix4]( [param:Matrix4 matrix] )</h3>
-		<p>Applies a matrix transform to the line segment.</p>
+		<p>对此线段应用矩阵变换。</p>
 
 		<h3>[method:Vector3 at]( [param:Float t], [param:Vector3 target] )</h3>
 		<p>
-		[page:Float t] - Use values 0-1 to return a position along the line segment. <br />
-		[page:Vector3 target] — the result will be copied into this Vector3.<br /><br />
-
-		Returns a vector at a certain position along the line. When [page:Float t] = 0, it returns the start vector,
-		and when [page:Float t] = 1 it returns the end vector.<br />
+		[page:Float t] - 使用值0-1返回沿线段的位置。<br />
+		[page:Vector3 target] — 计算结果会被拷贝到target。<br /><br />
+		
+		返回一个线段某一位置的向量,当 [page:Float t] = 0的时候返回起始点,当[page:Float t] = 1的时候返回终点。<br />
 		</p>
 
 		<h3>[method:Line3 clone]()</h3>
-		<p>Returns a new [page:Line3] with the same [page:.start start] and [page:.end end] vectors as this one.</p>
+		<p>返回一个与此线段拥有相同起始点 [page:.start start] 和 终点[page:.end end] 的线段。</p>
 
 		<h3>[method:Vector3 closestPointToPoint]( [param:Vector3 point], [param:Boolean clampToLine], [param:Vector3 target] )</h3>
 		<p>
-		[page:Vector3 point] - return the closest point on the line to this point.<br />
-		[page:Boolean clampToLine] - whether to clamp the returned value to the line segment.<br />
-		[page:Vector3 target] — the result will be copied into this Vector3.<br /><br />
+		[page:Vector3 point] - 用于计算线段上到该点最近的点。<br />
+		[page:Boolean clampToLine] - 是否将结果限制在线段起始点和终点之间。<br />
+		[page:Vector3 target] — 结果会拷贝到target。<br /><br />
 
-		Returns the closets point on the line. If [page:Boolean clampToLine] is true, then the returned value will be
-		clamped to the line segment.
+		返回线段上到point最近的点。如果参数 [page:Boolean clampToLine] 为true。返回值将会在线段之间。
 		</p>
 
 		<h3>[method:Float closestPointToPointParameter]( [param:Vector3 point], [param:Boolean clampToLine] )</h3>
 		<p>
-		[page:Vector3 point] - the point for which to return a point parameter. <br />
-		[page:Boolean clampToLine] - Whether to clamp the result to the range [0, 1].<br /><br />
+		[page:Vector3 point] - 用于计算返回值的点 <br />
+		[page:Boolean clampToLine] - 结果是否处于 [0, 1]之间。<br /><br />
 
-		Returns a point parameter based on the closest point as projected on the line segement.
-		If [page:Boolean clampToLine] is true, then the returned value will be between 0 and 1.
+		返回一个基于点投影到线段上的点的参数。如果 [page:Boolean clampToLine] 为true则返回值将在0到1之间。
 		</p>
 
 		<h3>[method:Line3 copy]( [param:Line3 line] )</h3>
-		<p>Copies the passed line's [page:.start start] and [page:.end end] vectors to this line.</p>
+		<p>拷贝传入线段的起始点 [page:.start start] 和终点 [page:.end end] 向量到当前线段。</p>
 
 		<h3>[method:Vector3 delta]( [param:Vector3 target] )</h3>
 		<p>
-		[page:Vector3 target] — the result will be copied into this Vector3.<br /><br />
-
-			Returns the delta vector of the line segment ( [page:.end end] vector minus the [page:.start start] vector).
+		[page:Vector3 target] — 结果将会拷贝到target。<br /><br />
+			返回线段的向量。(终点[page:.end end]向量减去起始点[page:.start start]向量)。
 		</p>
 
 		<h3>[method:Float distance]()</h3>
@@ -89,34 +85,32 @@
 
 		<h3>[method:Float distanceSq]()</h3>
 		<p>
-			Returns the square of the [link:https://en.wikipedia.org/wiki/Euclidean_distance Euclidean distance]
-			(straight-line distance) between the line's [page:.start start]
-			and [page:.end end] vectors.
+			返回起始点[page:.start start]和终点[page:.end end]的欧几里得距离[link:https://en.wikipedia.org/wiki/Euclidean_distance Euclidean distance]。(直线距离)
 		</p>
 
 		<h3>[method:Boolean equals]( [param:Line3 line] )</h3>
 		<p>
 		[page:Line3 line]  - [page:Line3] to compare with this one.<br /><br />
 
-		Returns true if both line's [page:.start start] and [page:.end en] points are equal.
+		如果给定线段与当前线段的起始点[page:.start start]和终点[page:.end end]都相同则返回true。
 		</p>
 
 		<h3>[method:Vector3 getCenter]( [param:Vector3 target] )</h3>
 		<p>
-		[page:Vector3 target] — the result will be copied into this Vector3.<br /><br />
+		[page:Vector3 target] — 结果会写入target。<br /><br />
 
-		Returns the center of the line segment.
+		返回线段的中心点。
 		</p>
 
 		<h3>[method:Line3 set]( [param:Vector3 start], [param:Vector3 end] )</h3>
 		<p>
-		[page:Vector3 start] - set the [page:.start start point] of the line.<br />
-		[page:Vector3 end] - set the [page:.end end point] of the line.<br /><br />
+		[page:Vector3 start] - 设置线段的起点 [page:.start start point]。<br />
+		[page:Vector3 end] - 设置线段的终点 [page:.end end point]。<br /><br />
 
-		Sets the start and end values by copying the provided vectors.
+		将传入的向量设置到线段的起始点和终点。
 		</p>
 
-		<h2>Source</h2>
+		<h2>源码(Source</h2>
 
 		[link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js]
 	</body>

+ 38 - 43
docs/api/zh/math/Math.html

@@ -8,101 +8,96 @@
 		<link type="text/css" rel="stylesheet" href="page.css" />
 	</head>
 	<body>
-		<h1>[name]</h1>
+		<h1>数学函数([name]</h1>
 
-		<p class="desc">An object with several math utility functions.</p>
+		<p class="desc">具有多个数学实用函数的对象。</p>
 
-		<h2>Functions</h2>
+		<h2>函数(Functions</h2>
 
 		<h3>[method:Float clamp]( [param:Float value], [param:Float min], [param:Float max] )</h3>
 		<p>
-		[page:Float value] — Value to be clamped.<br />
-		[page:Float min] — Minimum value.<br />
-		[page:Float max] — Maximum value.<br /><br />
+		[page:Float value] — 需要clamp处理的值。<br />
+		[page:Float min] — 最小值。<br />
+		[page:Float max] — 最大值。<br /><br />
 
-		Clamps the [page:Float value] to be between [page:Float min] and [page:Float max].
+		限制数值[page:Float value]处于最小值[page:Float min]和最大值[page:Float max]之间。
 		</p>
 
 		<h3>[method:Float degToRad]( [param:Float degrees] )</h3>
-		<p>Converts degrees to radians.</p>
+		<p>将度转化为弧度。</p>
 
 		<h3>[method:Integer euclideanModulo]( [param:Integer n], [param:Integer m] )</h3>
 		<p>
-		[page:Integer n], [page:Integer m] - Integers<br /><br />
-
-		Computes the Euclidean modulo of [page:Integer m] % [page:Integer n], that is:
+		[page:Integer n], [page:Integer m] - 整型<br /><br />
+		计算 [page:Integer m] % [page:Integer n] 的欧几里得模:
 		<code>( ( n % m ) + m ) % m</code>
 		</p>
 
 		<h3>[method:UUID generateUUID]( )</h3>
 		<p>
-		Generate a [link:https://en.wikipedia.org/wiki/Universally_unique_identifier UUID]
-		(universally unique identifier).
+			创建一个全局唯一标识符 [link:https://en.wikipedia.org/wiki/Universally_unique_identifier UUID]。
 		</p>
 
 		<h3>[method:Boolean isPowerOfTwo]( [param:Number n] )</h3>
-		<p>Return *true* if [page:Number n] is a power of 2.</p>
+		<p>如果 [page:Number n] 是2的幂,返回true。</p>
 
 		<h3>[method:Float lerp]( [param:Float x], [param:Float y], [param:Float t] )</h3>
 		<p>
-		[page:Float x] - Start point. <br />
-		[page:Float y] - End point. <br />
-		[page:Float t] - interpolation factor in the closed interval [0, 1].<br><br />
+		[page:Float x] - 起始点。 <br />
+		[page:Float y] - 终点。 <br />
+		[page:Float t] - 封闭区间[0,1]内的插值因子。<br><br />
 
-		Returns a value [link:https://en.wikipedia.org/wiki/Linear_interpolation linearly interpolated]
-		from two known points based on the given interval - [page:Float t] = 0 will return [page:Float x]
-		and [page:Float t] = 1 will return [page:Float y].
+		返回给定区间的线性插值[link:https://en.wikipedia.org/wiki/Linear_interpolation linearly interpolated]结果 - [page:Float t] = 0 将会返回 [page:Float x]
+		如果 [page:Float t] = 1 将会返回 [page:Float y].
 		</p>
 
 		<h3>[method:Float mapLinear]( [param:Float x], [param:Float a1], [param:Float a2], [param:Float b1], [param:Float b2] )</h3>
 		<p>
-		[page:Float x] — Value to be mapped.<br />
-		[page:Float a1] — Minimum value for range A.<br />
-		[page:Float a2] — Maximum value for range A.<br />
-		[page:Float b1] — Minimum value for range B.<br />
-		[page:Float b2] — Maximum value for range B.<br /><br />
+		[page:Float x] — 用于映射的值。<br />
+		[page:Float a1] — A区间最小值。<br />
+		[page:Float a2] — A区间最大值。<br />
+		[page:Float b1] — B区间最小值。<br />
+		[page:Float b2] — A区间最大值。<br /><br />
 
-		Linear mapping of [page:Float x] from range [[page:Float a1], [page:Float a2]] to range [[page:Float b1], [page:Float b2]].
+		x从范围[[page:Float a1], [page:Float a2]] 到范围[[page:Float b1], [page:Float b2]]的线性映射。
 		</p>
 
 		<h3>[method:Integer ceilPowerOfTwo]( [param:Number n] )</h3>
-		<p>Returns the smallest power of 2 that is greater than or equal to [page:Number n].</p>
+		<p>返回大于等于 [page:Number n] 的2的最小次幂。</p>
 
 		<h3>[method:Integer floorPowerOfTwo]( [param:Number n] )</h3>
-		<p>Returns the largest power of 2 that is less than or equal to [page:Number n].</p>
+		<p>返回小于等于 [page:Number n] 的2的最大幂。</p>
 
 		<h3>[method:Float radToDeg]( [param:Float radians] )</h3>
-		<p>Converts radians to degrees.</p>
+		<p>将弧度转换为角度。</p>
 
 		<h3>[method:Float randFloat]( [param:Float low], [param:Float high] )</h3>
-		<p>Random float in the interval [page:Float low] to [page:Float high].</p>
+		<p>在区间[page:Float low] 到 [page:Float high]随机一个浮点数。</p>
 
 		<h3>[method:Float randFloatSpread]( [param:Float range] )</h3>
-		<p>Random float in the interval *- [page:Float range] / 2* to *[page:Float range] / 2*.</p>
+		<p>在区间*- [page:Float range] / 2* 到 *[page:Float range] / 2*随机一个浮点数。</p>
 
 		<h3>[method:Integer randInt]( [param:Integer low], [param:Integer high] )</h3>
-		<p>Random integer in the interval [page:Float low] to [page:Float high].</p>
+		<p>在区间[page:Float low] 到 [page:Float high]随机一个整数。</p>
 
 		<h3>[method:Float smoothstep]( [param:Float x], [param:Float min], [param:Float max] )</h3>
 		<p>
-		[page:Float x] - The value to evaluate based on its position between min and max. <br />
-		[page:Float min] - Any x value below min will be 0.<br />
-		[page:Float max] - Any x value above max will be 1.<br /><br />
+		[page:Float x] - 根据其在最小值和最大值之间的位置来计算的值。 <br />
+		[page:Float min] - 任何x比最小值还小会返回0.<br />
+		[page:Float max] - 任何x比最大值还大会返回0.<br /><br />
 
-		Returns a value between 0-1 that represents the percentage that x has moved between min and max,
-		but smoothed or slowed down the closer X is to the min and max.<br/><br/>
+		返回0-1之间的值,该值表示x在最小值和最大值之间移动的百分比,但是当x接近最小值和最大值时,变化程度会平滑或减慢。<br/><br/>
 
-		See [link:http://en.wikipedia.org/wiki/Smoothstep Smoothstep] for details.
+		查看更多详情请移步到 [link:http://en.wikipedia.org/wiki/Smoothstep Smoothstep] 。
 		</p>
 
 		<h3>[method:Float smootherstep]( [param:Float x], [param:Float min], [param:Float max] )</h3>
 		<p>
-		[page:Float x] - The value to evaluate based on its position between min and max. <br />
-		[page:Float min] - Any x value below min will be 0.<br />
-		[page:Float max] - Any x value above max will be 1.<br /><br />
+			[page:Float x] - 根据其在最小值和最大值之间的位置来计算的值。 <br />
+			[page:Float min] - 任何x比最小值还小会返回0.<br />
+			[page:Float max] - 任何x比最大值还大会返回0.<br /><br />
 
-		Returns a value between 0-1. A [link:https://en.wikipedia.org/wiki/Smoothstep#Variations variation on smoothstep]
-		that has zero 1st and 2nd order derivatives at x=0 and x=1.
+		返回一个0-1之间的值。它和smoothstep相同,但变动更平缓。[link:https://en.wikipedia.org/wiki/Smoothstep#Variations variation on smoothstep] 在x=0和x=1处有0阶和二阶导数。
 		</p>
 
 		<h2>Source</h2>

+ 63 - 71
docs/api/zh/math/Matrix3.html

@@ -8,38 +8,37 @@
 		<link type="text/css" rel="stylesheet" href="page.css" />
 	</head>
 	<body>
-		<h1>[name]</h1>
+		<h1>三维矩阵([name]</h1>
 
 		<p class="desc">
-			A class representing a 3x3 [link:https://en.wikipedia.org/wiki/Matrix_(mathematics) matrix].
+			一个表示3X3矩阵[link:https://en.wikipedia.org/wiki/Matrix_(mathematics) matrix].的类。
 		</p>
 
-		<h2>Example</h2>
+		<h2>示例(Example</h2>
 		<code>
 var m = new Matrix3();
 		</code>
 
-		<h2>A Note on Row-Major and Column-Major Ordering</h2>
+		<h2>注意行优先列优先的顺序。</h2>
 		<p>
-			The [page:set]() method takes arguments in [link:https://en.wikipedia.org/wiki/Row-_and_column-major_order#Column-major_order row-major]
-			order, while internally they are stored in the [page:.elements elements] array in column-major order.<br /><br />
+			[page:set]()方法参数采用行优先[link:https://en.wikipedia.org/wiki/Row-_and_column-major_order#Column-major_order row-major]
+			而它们在内部是用列优先[link:https://en.wikipedia.org/wiki/Row-_and_column-major_order column-major]顺序存储在数组当中。<br /><br />
 
-			This means that calling
+			这意味着
 		<code>
 m.set( 11, 12, 13,
        21, 22, 23,
        31, 32, 33 );
 		</code>
-		will result in the [page:.elements elements] array containing:
+		元素数组[page:.elements elements]将存储为:
 		<code>
 m.elements = [ 11, 21, 31,
               12, 22, 32,
               13, 23, 33 ];
 		</code>
-		and internally all calculations are performed using column-major ordering. However, as the actual ordering
-		makes no difference mathematically and most people are used to thinking about matrices in row-major order,
-		the three.js documentation shows matrices in row-major order. Just bear in mind that if you are reading the source
-		code, you'll have to take the [link:https://en.wikipedia.org/wiki/Transpose transpose] of any matrices outlined here to make sense of the calculations.
+		在内部,所有的计算都是使用列优先顺序进行的。然而,由于实际的排序在数学上没有什么不同,
+		而且大多数人习惯于以行优先顺序考虑矩阵,所以three.js文档以行为主的顺序显示矩阵。
+		请记住,如果您正在阅读源代码,您必须对这里列出的任何矩阵进行转置[link:https://en.wikipedia.org/wiki/Transpose transpose],以理解计算。
 		</p>
 
 		<h2>Constructor</h2>
@@ -47,87 +46,81 @@ m.elements = [ 11, 21, 31,
 
 		<h3>[name]()</h3>
 		<p>
-		Creates and initializes the [name] to the 3x3
-		[link:https://en.wikipedia.org/wiki/Identity_matrix identity matrix].
+		创建并初始化一个3X3的单位矩阵[link:https://en.wikipedia.org/wiki/Identity_matrix identity matrix].
 		</p>
 
 
 
-		<h2>Properties</h2>
+		<h2>属性(Properties</h2>
 
 		<h3>[property:Float32Array elements]</h3>
 		<p>
-		A [link:https://en.wikipedia.org/wiki/Row-_and_column-major_order column-major]
-		 list of matrix values.
+			矩阵列优先[link:https://en.wikipedia.org/wiki/Row-_and_column-major_order column-major]列表。
 		</p>
 
 		<h3>[property:Boolean isMatrix3]</h3>
 		<p>
-			Used to check whether this or derived classes are Matrix3s. Default is *true*.<br /><br />
-
-			You should not change this, as it used internally for optimisation.
+				用于判定此对象或者此类的派生对象是否是三维矩阵。默认值为 *true*。<br /><br />
+			
+				不应该改变该值,因为它在内部用于优化。
 		</p>
 
 
 
-		<h2>Methods</h2>
+		<h2>方法(Methods</h2>
 
 		<h3>[method:Array applyToBufferAttribute]( [param:BufferAttribute attribute] )</h3>
 		<p>
-		[page:BufferAttribute attribute] - An attribute of floats that represent 3D vectors.<br /><br />
+		[page:BufferAttribute attribute] - 表示三维向量缓存属性。<br /><br />
 
-		Multiplies (applies) this matrix to every 3D vector in the [page:BufferAttribute attribute].
+		用这个矩阵乘以缓存属性[page:BufferAttribute attribute]里的所有3d向量。
 		</p>
 
 
 		<h3>[method:Matrix3 clone]()</h3>
-		<p>Creates a new Matrix3 and with identical elements to this one.</p>
+		<p>创建一个新的矩阵,元素 [page:.elements elements] 与该矩阵相同。</p>
 
 		<h3>[method:this copy]( [param:Matrix3 m] )</h3>
-		<p>Copies the elements of matrix [page:Matrix3 m] into this matrix.</p>
+		<p>将矩阵[page:Matrix3 m]的元素复制到当前矩阵中。</p>
 
 		<h3>[method:Float determinant]()</h3>
 		<p>
-		Computes and returns the
-		[link:https://en.wikipedia.org/wiki/Determinant determinant] of this matrix.
+			计算并返回矩阵的行列式[link:https://en.wikipedia.org/wiki/Determinant determinant] 。
 		</p>
 
 		<h3>[method:Boolean equals]( [param:Matrix3 m] )</h3>
-		<p>Return true if this matrix and [page:Matrix3 m] are equal.</p>
+		<p>如果矩阵[page:Matrix3 m] 与当前矩阵所有对应元素相同则返回true。</p>
 
 		<h3>[method:this fromArray]( [param:Array array], [param:Integer offset] )</h3>
 		<p>
-		[page:Array array] - the array to read the elements from.<br />
-		[page:Integer offset] - (optional) index of first element in the array. Default is 0.<br /><br />
+		[page:Array array] - 用来存储设置元素数据的数组<br />
+		[page:Integer offset] - (可选参数) 数组的偏移量,默认值为 0。<br /><br />
 
-		Sets the elements of this matrix based on an array in
-		[link:https://en.wikipedia.org/wiki/Row-_and_column-major_order#Column-major_order column-major] format.
+		使用基于列优先格式[link:https://en.wikipedia.org/wiki/Row-_and_column-major_order#Column-major_order column-major]的数组来设置该矩阵。
 		</p>
 
 		<h3>[method:this getInverse]( [param:Matrix3 m], [param:Boolean throwOnDegenerate] )</h3>
 		<p>
-		[page:Matrix3 m] - the matrix to take the inverse of.<br />
-		[page:Boolean throwOnDegenerate] - (optional) If true, throw an error if the matrix is degenerate (not invertible).<br /><br />
-
-		Set this matrix to the [link:https://en.wikipedia.org/wiki/Invertible_matrix inverse] of the passed matrix [page:Matrix3 m],
-		using the [link:https://en.wikipedia.org/wiki/Invertible_matrix#Analytic_solution analytic method].
-
-		If [page:Boolean throwOnDegenerate] is not set and the matrix is not invertible, set this to the 3x3 identity matrix.
+		[page:Matrix3 m] - 取逆的矩阵。<br />
+		[page:Boolean throwOnDegenerate] - (optional) 如果设置为true,如果矩阵是退化的(如果不可逆的话),则会抛出一个错误。<br /><br />
+		
+		使用逆矩阵计算方法[link:https://en.wikipedia.org/wiki/Invertible_matrix#Analytic_solution analytic method],
+		将当前矩阵设置为给定矩阵的逆矩阵[link:https://en.wikipedia.org/wiki/Invertible_matrix inverse],如果[page:Boolean throwOnDegenerate]
+		参数没有设置且给定矩阵不可逆,那么将当前矩阵设置为3X3单位矩阵。
 		</p>
 
 		<h3>[method:this getNormalMatrix]( [param:Matrix4 m] )</h3>
 		<p>
 		[page:Matrix4 m] - [page:Matrix4]<br /><br />
 
-		Sets this matrix as the upper left 3x3 of the [link:https://en.wikipedia.org/wiki/Normal_matrix normal matrix]
-		of the passed [page:Matrix4 matrix4]. The normal matrix is the [link:https://en.wikipedia.org/wiki/Invertible_matrix inverse] [link:https://en.wikipedia.org/wiki/Transpose transpose]
-	  of the matrix [page:Matrix4 m].
+		将这个矩阵设置为给定矩阵的正规矩阵[link:https://en.wikipedia.org/wiki/Normal_matrix normal matrix](左上角的3x3)。
+		正规矩阵是矩阵[page:Matrix4 m]的逆矩阵[link:https://en.wikipedia.org/wiki/Invertible_matrix inverse] 的转置[link:https://en.wikipedia.org/wiki/Transpose transpose]。
 		</p>
 
 		<h3>[method:this identity]()</h3>
 		<p>
-		Resets this matrix to the 3x3 identity matrix:
-		<code>
+			将此矩阵重置为3x3单位矩阵:
+				<code>
 1, 0, 0
 0, 1, 0
 0, 0, 1
@@ -136,22 +129,22 @@ m.elements = [ 11, 21, 31,
 		</p>
 
 		<h3>[method:this multiply]( [param:Matrix3 m] )</h3>
-		<p>Post-multiplies this matrix by [page:Matrix3 m].</p>
+		<p>将当前矩阵乘以矩阵[page:Matrix3 m]。</p>
 
 		<h3>[method:this multiplyMatrices]( [param:Matrix3 a], [param:Matrix3 b] )</h3>
-		<p>Sets this matrix to [page:Matrix3 a] x [page:Matrix3 b].</p>
+		<p>设置当前矩阵为矩阵[page:Matrix3 a] x 矩阵[page:Matrix3 b]。</p>
 
 		<h3>[method:this multiplyScalar]( [param:Float s] )</h3>
-		<p>Multiplies every component of the matrix by the scalar value *s*.</p>
+		<p>当前矩阵所有的元素乘以该缩放值*s*</p>
 
 		<h3>[method:this set]( [param:Float n11], [param:Float n12], [param:Float n13], [param:Float n21], [param:Float n22], [param:Float n23], [param:Float n31], [param:Float n32], [param:Float n33] )</h3>
 		<p>
-		[page:Float n11] - value to put in row 1, col 1.<br />
-		[page:Float n12] - value to put in row 1, col 2.<br />
+		[page:Float n11] - 设置第一行第一列的值。<br />
+		[page:Float n12] - 设置第一行第二列的值。<br />
 		...<br />
 		...<br />
-		[page:Float n32] - value to put in row 3, col 2.<br />
-		[page:Float n33] - value to put in row 3, col 3.<br /><br />
+		[page:Float n32] - 设置第三行第二列的值。<br />
+		[page:Float n33] - 设置第三行第三列的值。<br /><br />
 
 		Sets the 3x3 matrix values to the given
 		[link:https://en.wikipedia.org/wiki/Row-_and_column-major_order row-major]
@@ -159,45 +152,44 @@ m.elements = [ 11, 21, 31,
 		</p>
 
 		<h3>[method:this premultiply]( [param:Matrix3 m] )</h3>
-		<p>Pre-multiplies this matrix by [page:Matrix3 m].</p>
+		<p>将矩阵[page:Matrix3 m]乘以当前矩阵。</p>
 
 		<h3>[method:this setFromMatrix4]( [param:Matrix4 m] )</h3>
-		<p>Set this matrx to the upper 3x3 matrix of the Matrix4 [page:Matrix4 m].</p>
+		<p>将当前矩阵设置为4X4矩阵[page:Matrix4 m]左上3X3</p>
 
 		<h3>[method:this setUvTransform]( [param:Float tx], [param:Float ty], [param:Float sx], [param:Float sy], [param:Float rotation], [param:Float cx], [param:Float cy] )</h3>
 		<p>
-		[page:Float tx] - offset x<br />
-		[page:Float ty] - offset y<br />
-		[page:Float sx] - repeat x<br />
-		[page:Float sy] - repeat y<br />
-		[page:Float rotation] - rotation (in radians)<br />
-		[page:Float cx] - center x of rotation<br />
-		[page:Float cy] - center y of rotation<br /><br />
-
-		Sets the UV transform matrix from offset, repeat, rotation, and center.
+		[page:Float tx] - x偏移量<br />
+		[page:Float ty] - y偏移量<br />
+		[page:Float sx] - x方向的重复比例<br />
+		[page:Float sy] - y方向的重复比例<br />
+		[page:Float rotation] - 旋转(弧度)<br />
+		[page:Float cx] - 旋转中心x<br />
+		[page:Float cy] - 旋转中心y<br /><br />
+
+		使用偏移,重复,旋转和中心点位置设置UV变换矩阵。
 		</p>
 
 		<h3>[method:Array toArray]( [param:Array array], [param:Integer offset] )</h3>
 		<p>
-		[page:Array array] - (optional) array to store the resulting vector in. If not given a new array will be created.<br />
-		[page:Integer offset] - (optional) offset in the array at which to put the result.<br /><br />
+		[page:Array array] - (可选参数) 存储矩阵元素的数组,如果未指定会创建一个新的数组。<br />
+		[page:Integer offset] - (可选参数) 存放矩阵元素数组的偏移量。<br /><br />
 
-		Writes the elements of this matrix to an array in
-		[link:https://en.wikipedia.org/wiki/Row-_and_column-major_order#Column-major_order column-major] format.
+		使用列优先[link:https://en.wikipedia.org/wiki/Row-_and_column-major_order#Column-major_order column-major]格式将此矩阵的元素写入数组中。
 		</p>
 
 		<h3>[method:this transpose]()</h3>
-		<p>[link:https://en.wikipedia.org/wiki/Transpose Transposes] this matrix in place.</p>
+		<p>将该矩阵转置[link:https://en.wikipedia.org/wiki/Transpose Transposes]</p>
 
 		<h3>[method:this transposeIntoArray]( [param:Array array] )</h3>
 		<p>
-		[page:Array array] -  array to store the resulting vector in.<br /><br />
+		[page:Array array] -  用于存储当前矩阵转置结果的数组。<br /><br />
 
-		[link:https://en.wikipedia.org/wiki/Transpose Transposes] this matrix into the supplied array,
-		and returns itself unchanged.
+		将当前矩阵的转置[link:https://en.wikipedia.org/wiki/Transpose Transposes]存入给定的数组[param:Array array]但不改变当前矩阵,
+		并返回当前矩阵。
 		</p>
 
-		<h2>Source</h2>
+		<h2>源码(Source</h2>
 
 		[link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js]
 	</body>

+ 109 - 130
docs/api/zh/math/Matrix4.html

@@ -8,53 +8,48 @@
 		<link type="text/css" rel="stylesheet" href="page.css" />
 	</head>
 	<body>
-		<h1>[name]</h1>
+		<h1>四维矩阵([name]</h1>
 
 		<p class="desc">
-			A class representing a 4x4 [link:https://en.wikipedia.org/wiki/Matrix_(mathematics) matrix].<br /><br />
+			表示为一个 4x4 [link:https://en.wikipedia.org/wiki/Matrix_(mathematics) matrix].<br /><br />
 
-			The most common use of a 4x4 matrix in 3D computer graphics is as a
-			[link:https://en.wikipedia.org/wiki/Transformation_matrix Transformation Matrix].
-			For an introduction to transformation matrices as used in WebGL, check out
-			[link:http://www.opengl-tutorial.org/beginners-tutorials/tutorial-3-matrices this tutorial].<br /><br />
+			在3D计算机图形学中,4x4矩阵最常用的用法是作为一个变换矩阵[link:https://en.wikipedia.org/wiki/Transformation_matrix Transformation Matrix]。
+			有关WebGL中使用的变换矩阵的介绍,请参阅本教程[link:http://www.opengl-tutorial.org/beginners-tutorials/tutorial-3-matrices this tutorial]。<br /><br />
 
-			This allows a [page:Vector3] representing a point in 3D space to undergo transformations
-			such as translation, rotation, shear, scale, reflection, orthogonal or perspective projection
-			and so on, by being multiplied by the matrix. This is known as	<em>applying</em>
-			the matrix to the vector.<br /><br />
+			这使得表示三维空间中的一个点的向量[page:Vector3]通过乘以矩阵来进行转换,如平移、旋转、剪切、缩放、反射、正交或透视投影等。这就是把矩阵<em>应用</em>到向量上。<br /><br />
 
-			Every [page:Object3D] has three associated Matrix4s:
+			任何3D物体[page:Object3D]都有三个关联的矩阵:
 			<ul>
 				<li>
-					[page:Object3D.matrix]: This stores the local transform of the object. This is the object's transformation relative to its parent.
+					[page:Object3D.matrix]: 存储物体的本地变换。 这是对象相对于其父对象的变换。
 				</li>
 				<li>
-					[page:Object3D.matrixWorld]: The global or world transform of the object. If the object has no parent, then this is identical to the local transform stored in [page:Object3D.matrix matrix].
+					[page:Object3D.matrixWorld]: 对象的全局或世界变换。如果对象没有父对象,那么这与存储在矩阵[page:Object3D.matrix matrix]中的本地变换相同。
 				</li>
 				<li>
-					[page:Object3D.modelViewMatrix]: This represents the object's transformation relative to the camera's coordinate system.
-					An object's modelViewMatrix is the object's matrixWorld pre-multiplied by the camera's matrixWorldInverse.
+					[page:Object3D.modelViewMatrix]: 表示对象相坐标相对于摄像机空间坐标转换,
+					一个对象的 modelViewMatrix 是物体世界变换矩阵乘以摄像机相对于世界空间变换矩阵的逆矩阵。
 				</li>
 			</ul>
 
-			[page:Camera Cameras] have two additional Matrix4s:
+			摄像机[page:Camera Cameras] 有两个额外的四维矩阵:
 			<ul>
 				<li>
-					[page:Camera.matrixWorldInverse]: The view matrix - the inverse of the Camera's [page:Object3D.matrixWorld matrixWorld].
+					[page:Camera.matrixWorldInverse]: 视矩阵 - 摄像机世界坐标变换的逆矩阵。
 				</li>
 				<li>
-					[page:Camera.projectionMatrix]: Represents the information how to project the scene to clip space.
+					[page:Camera.projectionMatrix]: 表示将场景中的信息投影到裁剪空间。
 				</li>
 			</ul>
-			Note: [page:Object3D.normalMatrix] is not a Matrix4, but a [page:Matrix3].
+			注意:物体的正规矩阵 [page:Object3D.normalMatrix] 并不是一个4维矩阵,而是一个三维矩阵[page:Matrix3]。
 		</p>
 
-		<h2>A Note on Row-Major and Column-Major Ordering</h2>
+		<h2>注意行优先列优先的顺序。</h2>
 		<p>
-			The [page:set]() method takes arguments in [link:https://en.wikipedia.org/wiki/Row-_and_column-major_order#Column-major_order row-major]
-			order, while internally they are stored in the [page:.elements elements] array in column-major order.<br /><br />
+				设置[page:set]()方法参数采用行优先[link:https://en.wikipedia.org/wiki/Row-_and_column-major_order#Column-major_order row-major]
+				而它们在内部是用列优先[link:https://en.wikipedia.org/wiki/Row-_and_column-major_order column-major]顺序存储在数组当中。<br /><br />
 
-			This means that calling
+				这意味着
 		<code>
 var m = new Matrix4();
 
@@ -64,107 +59,99 @@ m.set( 11, 12, 13, 14,
        41, 42, 43, 44 );
 
 		</code>
-		will result in the [page:.elements elements] array containing:
+		元素数组[page:.elements elements]将存储为:
 		<code>
 m.elements = [ 11, 21, 31, 41,
                12, 22, 32, 42,
                13, 23, 33, 43,
                14, 24, 34, 44 ];
 		</code>
-		and internally all calculations are performed using column-major ordering. However, as the actual ordering
-		makes no difference mathematically and most people are used to thinking about matrices in row-major order,
-		the three.js documentation shows matrices in row-major order. Just bear in mind that if you are reading the source
-		code, you'll have to take the [link:https://en.wikipedia.org/wiki/Transpose transpose] of any matrices outlined here to make sense of the calculations.
+		在内部,所有的计算都是使用列优先顺序进行的。然而,由于实际的排序在数学上没有什么不同,
+		而且大多数人习惯于以行优先顺序考虑矩阵,所以three.js文档以行为主的顺序显示矩阵。
+		请记住,如果您正在阅读源代码,您必须对这里列出的任何矩阵进行转置[link:https://en.wikipedia.org/wiki/Transpose transpose],以理解计算。
 		</p>
 
 
-		<h2>Constructor</h2>
+		<h2>构造器(Constructor</h2>
 
 
 		<h3>[name]()</h3>
 
 		<p>
-			Creates and initializes the [name] to the 4x4
-			[link:https://en.wikipedia.org/wiki/Identity_matrix identity matrix].
+			创建并初始化一个4X4的单位矩阵[link:https://en.wikipedia.org/wiki/Identity_matrix identity matrix].
 	</p>
 
-		<h2>Properties</h2>
+		<h2>属性(Properties</h2>
 
 		<h3>[property:Float32Array elements]</h3>
 		<p>
-		A [link:https://en.wikipedia.org/wiki/Row-_and_column-major_order#Column-major_order column-major]
-		 list of matrix values.
+		矩阵列优先[link:https://en.wikipedia.org/wiki/Row-_and_column-major_order column-major]列表。
 		</p>
 
 		<h3>[property:Boolean isMatrix4]</h3>
 		<p>
-			Used to check whether this or derived classes are Matrix4s. Default is *true*.<br /><br />
-
-			You should not change this, as it used internally for optimisation.
+			用于判定此对象或者此类的派生对象是否是三维矩阵。默认值为 *true*。<br /><br />
+		
+			不应该改变该值,因为它在内部用于优化。
 		</p>
 
 
 
 
-		<h2>Methods</h2>
+		<h2>方法(Methods</h2>
 
 		<h3>[method:Array applyToBufferAttribute]( [param:BufferAttribute attribute] )</h3>
 		<p>
-		[page:BufferAttribute attribute] - An attribute of floats that represent 3D vectors.<br /><br />
+		[page:BufferAttribute attribute] - 表示三维向量缓存属性。<br /><br />
 
-		Multiplies (applies) this matrix to every 3D vector in the [page:BufferAttribute attribute].
+		用这个矩阵乘以缓存属性[page:BufferAttribute attribute]里的所有3d向量。
 		</p>
 
 
 		<h3>[method:Matrix4 clone]()</h3>
-		<p>Creates a new Matrix4 with identical [page:.elements elements] to this one.</p>
+		<p>创建一个新的矩阵,元素[page:.elements elements]与该矩阵相同。</p>
 
 		<h3>[method:this compose]( [param:Vector3 position], [param:Quaternion quaternion], [param:Vector3 scale] )</h3>
 		<p>
-		Sets this matrix to the transformation composed of [page:Vector3 position],
-		[page:Quaternion quaternion] and [page:Vector3 scale]. Internally this calls
-		[page:.makeRotationFromQuaternion makeRotationFromQuaternion]( [page:Quaternion quaternion] )
-		followed by [page:.scale scale]( [page:Vector3 scale] ), then finally
-		[page:.setPosition setPosition]( [page:Vector3 position] ).
+		设置将该对象由位置[page:Vector3 position],四元数[page:Quaternion quaternion] 和 缩放[page:Vector3 scale]
+		组合变换的矩阵。内部先调用[page:.makeRotationFromQuaternion makeRotationFromQuaternion]( [page:Quaternion quaternion] )
+		再调用缩放[page:.scale scale]( [page:Vector3 scale] )最后是平移[page:.setPosition setPosition]( [page:Vector3 position] )。
 		</p>
 
 		<h3>[method:this copy]( [param:Matrix4 m] )</h3>
-		<p>Copies the [page:.elements elements] of matrix [page:Matrix4 m] into this matrix.</p>
+		<p>将矩阵[page:Matrix3 m]的元素[page:.elements elements]复制到当前矩阵中。</p>
 
 		<h3>[method:this copyPosition]( [param:Matrix4 m] )</h3>
 		<p>
-		Copies the translation component of the supplied matrix [page:Matrix4 m] into this
-		matrix's translation component.
+		将给定矩阵[param:Matrix4 m] 的平移分量拷贝到当前矩阵中。
 		</p>
 
 		<h3>[method:null decompose]( [param:Vector3 position], [param:Quaternion quaternion], [param:Vector3 scale] )</h3>
 		<p>
-		Decomposes this matrix into it's [page:Vector3 position], [page:Quaternion quaternion] and
-		[page:Vector3 scale] components.
+			将矩阵分解到给定的平移[page:Vector3 position] ,旋转 [page:Quaternion quaternion],缩放[page:Vector3 scale]分量中。
 		</p>
 
 		<h3>[method:Float determinant]()</h3>
 		<p>
-		Computes and returns the
-		[link:https://en.wikipedia.org/wiki/Determinant determinant] of this matrix.<br /><br />
+				计算并返回矩阵的行列式[link:https://en.wikipedia.org/wiki/Determinant determinant] 。<br /><br />
 
-		Based on the method outlined [link:http://www.euclideanspace.com/maths/algebra/matrix/functions/inverse/fourD/index.htm here].
+		基于这个的方法概述[link:http://www.euclideanspace.com/maths/algebra/matrix/functions/inverse/fourD/index.htm here]。
 		</p>
 
 		<h3>[method:Boolean equals]( [param:Matrix4 m] )</h3>
-		<p>Return true if this matrix and [page:Matrix4 m] are equal.</p>
+		<p>如果矩阵[page:Matrix3 m] 与当前矩阵所有对应元素相同则返回true。</p>
 
 		<h3>[method:this extractBasis]( [param:Vector3 xAxis], [param:Vector3 yAxis], [param:Vector3 zAxis] )</h3>
 		<p>
-		Extracts the [link:https://en.wikipedia.org/wiki/Basis_(linear_algebra) basis] of this
-		matrix into the three axis vectors provided. If this matrix is:
+			将矩阵的基向量[link:https://en.wikipedia.org/wiki/Basis_(linear_algebra) basis]提取到指定的3个轴向量中。
+			如果矩阵如下:
 		<code>
 a, b, c, d,
 e, f, g, h,
 i, j, k, l,
 m, n, o, p
 		</code>
-		then the [page:Vector3 xAxis], [page:Vector3 yAxis], [page:Vector3 zAxis] will be set to:
+		然后x轴y轴z轴被设为:
 		<code>
 xAxis = (a, e, i)
 yAxis = (b, f, j)
@@ -174,58 +161,54 @@ zAxis = (c, g, k)
 
 		<h3>[method:this extractRotation]( [param:Matrix4 m] )</h3>
 		<p>
-		Extracts the rotation component of the supplied matrix [page:Matrix4 m] into this matrix's
-		rotation component.
+		将给定矩阵[page:Matrix4 m]的旋转分量提取到该矩阵的旋转分量中。
 		</p>
 
 		<h3>[method:this fromArray]( [param:Array array], [param:Integer offset] )</h3>
 		<p>
-		[page:Array array] - the array to read the elements from.<br />
-		[page:Integer offset] - ( optional ) offset into the array. Default is 0.<br /><br />
-
-		Sets the elements of this matrix based on an [page:Array array] in
-		[link:https://en.wikipedia.org/wiki/Row-_and_column-major_order#Column-major_order column-major] format.
-		</p>
+			[page:Array array] - 用来存储设置元素数据的数组<br />
+			[page:Integer offset] - (可选参数) 数组的偏移量,默认值为 0。<br /><br />
+	
+			使用基于列优先格式[link:https://en.wikipedia.org/wiki/Row-_and_column-major_order#Column-major_order column-major]的数组来设置该矩阵。
+			</p>
 
 		<h3>[method:this getInverse]( [param:Matrix4 m], [param:Boolean throwOnDegenerate] )</h3>
 		<p>
-		[page:Matrix4 m] - the matrix to take the inverse of.<br />
-		[page:Boolean throwOnDegenerate] - (optional) If true, throw an error if the matrix is degenerate (not invertible).<br /><br />
-
-		Set this matrix to the [link:https://en.wikipedia.org/wiki/Invertible_matrix inverse] of the passed matrix [page:Matrix4 m],
-		using the method outlined [link:http://www.euclideanspace.com/maths/algebra/matrix/functions/inverse/fourD/index.htm here].
-
-		If [page:Boolean throwOnDegenerate] is not set and the matrix is not invertible, set this to the 4x4 identity matrix.
-		</p>
+			[page:Matrix3 m] - 取逆的矩阵。<br />
+			[page:Boolean throwOnDegenerate] - (optional) 如果设置为true,如果矩阵是退化的(如果不可逆的话),则会抛出一个错误。<br /><br />
+			
+			使用逆矩阵计算方法[link:https://en.wikipedia.org/wiki/Invertible_matrix#Analytic_solution analytic method],
+			将当前矩阵设置为给定矩阵的逆矩阵[link:https://en.wikipedia.org/wiki/Invertible_matrix inverse],如果[page:Boolean throwOnDegenerate]
+			参数没有设置且给定矩阵不可逆,那么将当前矩阵设置为3X3单位矩阵。
+				</p>
 
 
 		<h3>[method:Float getMaxScaleOnAxis]()</h3>
-		<p>Gets the maximum scale value of the 3 axes.</p>
+		<p>获取3个轴方向的最大缩放值。</p>
 
 		<h3>[method:this identity]()</h3>
-		<p>Resets this matrix to the [link:https://en.wikipedia.org/wiki/Identity_matrix identity matrix].</p>
+		<p>将当前矩阵重置为单位矩阵[link:https://en.wikipedia.org/wiki/Identity_matrix identity matrix]。</p>
 
 		<h3>[method:this lookAt]( [param:Vector3 eye], [param:Vector3 center], [param:Vector3 up], )</h3>
 		<p>
-			Constructs a rotation matrix, looking from [page:Vector3 eye] towards [page:Vector3 center]
-			oriented by the [page:Vector3 up] vector.
+			构造一个旋转矩阵,从[page:Vector3 eye] 指向 [page:Vector3 center],由向量 [param:Vector3 up] 定向。
+<!--			Constructs a rotation matrix, looking from [page:Vector3 eye] towards [page:Vector3 center]
+			oriented by the [page:Vector3 up] vector.-->
 		</p>
 
 		<h3>[method:this makeRotationAxis]( [param:Vector3 axis], [param:Float theta] )</h3>
 		<p>
-		[page:Vector3 axis] — Rotation axis, should be normalized.<br />
-		[page:Float theta] — Rotation angle in radians.<br /><br />
+		[page:Vector3 axis] — 旋转轴,需要被归一化。<br />
+		[page:Float theta] — 旋转量(弧度)。<br /><br />
 
-		Sets this matrix as rotation transform around [page:Vector3 axis] by [page:Float theta] radians.<br />
+		设置当前矩阵为围绕轴 [page:Vector3 axis] 旋转量为 [page:Float theta]弧度。<br />
 
-		This is a somewhat controversial but mathematically sound alternative to rotating via [page:Quaternions].
-		See the discussion [link:http://www.gamedev.net/reference/articles/article1199.asp here].
+		这是一种有点争议但在数学上可以替代通过四元数[page:Quaternions]旋转的办法。 请参阅此处[link:http://www.gamedev.net/reference/articles/article1199.asp here]的讨论。
 		</p>
 
 		<h3>[method:this makeBasis]( [param:Vector3 xAxis], [param:Vector3 yAxis], [param:Vector3 zAxis] )</h3>
 		<p>
-		Set this to the [link:https://en.wikipedia.org/wiki/Basis_(linear_algebra) basis] matrix consisting
-		of the three provided basis vectors:
+			通过给定的三个向量设置该矩阵为基矩阵[link:https://en.wikipedia.org/wiki/Basis_(linear_algebra) basis]:
 		<code>
 xAxis.x, yAxis.x, zAxis.x, 0,
 xAxis.y, yAxis.y, zAxis.y, 0,
@@ -236,28 +219,27 @@ xAxis.z, yAxis.z, zAxis.z, 0,
 
 		<h3>[method:this makePerspective]( [param:Float left], [param:Float right], [param:Float top], [param:Float bottom], [param:Float near], [param:Float far] )</h3>
 		<p>
-			Creates a [link:https://en.wikipedia.org/wiki/3D_projection#Perspective_projection perspective projection] matrix.
-			This is used internally by [page:PerspectiveCamera.updateProjectionMatrix]()
+			创建一个透视投影矩阵[link:https://en.wikipedia.org/wiki/3D_projection#Perspective_projection perspective projection]。
+			在引擎内部由[page:PerspectiveCamera.updateProjectionMatrix]()使用。
 		</p>
 
 		<h3>[method:this makeOrthographic]( [param:Float left], [param:Float right], [param:Float top], [param:Float bottom], [param:Float near], [param:Float far] )</h3>
 		<p>
-		Creates an [link:https://en.wikipedia.org/wiki/Orthographic_projection orthographic projection] matrix.
-		This is used internally by [page:OrthographicCamera.updateProjectionMatrix]().
+			创建一个正交投影矩阵[link:https://en.wikipedia.org/wiki/Orthographic_projection orthographic projection]。
+			在引擎内部由[page:OrthographicCamera.updateProjectionMatrix]()使用。
 		</p>
 
 		<h3>[method:this makeRotationFromEuler]( [param:Euler euler] )</h3>
 		<p>
-		Sets the rotation component (the upper left 3x3 matrix) of this matrix to the rotation specified by the given [page:Euler Euler Angle].
-		The rest of the matrix is set to the identity. Depending on the [page:Euler.order order] of the [page:Euler euler], there are six possible outcomes.
-		See [link:https://en.wikipedia.org/wiki/Euler_angles#Rotation_matrix this page] for a complete list.
+		将传入的欧拉角转换为该矩阵的旋转分量(左上角的3x3矩阵)。
+		矩阵的其余部分被设为单位矩阵。根据欧拉角[page:Euler euler]的旋转顺序[page:Euler.order order],总共有六种可能的结果。
+		详细信息,请参阅本页[link:https://en.wikipedia.org/wiki/Euler_angles#Rotation_matrix this page]。
 		</p>
 
 		<h3>[method:this makeRotationFromQuaternion]( [param:Quaternion q] )</h3>
 		<p>
-		Sets the rotation component of this matrix to the rotation specified by [page:Quaternion q], as outlined
-		[link:https://en.wikipedia.org/wiki/Rotation_matrix#Quaternion here].
-		The rest of the matrix is set to the identity. So, given [page:Quaternion q] = w + xi + yj + zk, the resulting matrix will be:
+		将这个矩阵的旋转分量设置为四元数[page:Quaternion q]指定的旋转,如下链接所诉[link:https://en.wikipedia.org/wiki/Rotation_matrix#Quaternion here]。
+		矩阵的其余部分被设为单位矩阵。因此,给定四元数[page:Quaternion q] = w + xi + yj + zk,得到的矩阵为:
 		<code>
 1-2y²-2z²    2xy-2zw    2xz+2yw    0
 2xy+2zw      1-2x²-2z²  2yz-2xw    0
@@ -269,9 +251,9 @@ xAxis.z, yAxis.z, zAxis.z, 0,
 		<h3>[method:this makeRotationX]( [param:Float theta] )</h3>
 		<p>
 		[page:Float theta] — Rotation angle in radians.<br /><br />
-
-		Sets this matrix as a rotational transformation around the X axis by [page:Float theta] (&theta;) radians.
-		The resulting matrix will be:
+		
+		把该矩阵设置为绕x轴旋转弧度[page:Float theta] (&theta;)大小的矩阵。
+		结果如下:
 		<code>
 1 0      0        0
 0 cos(&theta;) -sin(&theta;)  0
@@ -284,8 +266,8 @@ xAxis.z, yAxis.z, zAxis.z, 0,
 		<p>
 		[page:Float theta] — Rotation angle in radians.<br /><br />
 
-		Sets this matrix as a rotational transformation around the Y axis by [page:Float theta] (&theta;) radians.
-		The resulting matrix will be:
+		把该矩阵设置为绕Y轴旋转弧度[page:Float theta] (&theta;)大小的矩阵。
+		结果如下:
 		<code>
 cos(&theta;)  0 sin(&theta;) 0
 0       1 0      0
@@ -298,8 +280,8 @@ cos(&theta;)  0 sin(&theta;) 0
 		<p>
 		[page:Float theta] — Rotation angle in radians.<br /><br />
 
-		Sets this matrix as a rotational transformation around the Z axis by [page:Float theta] (&theta;) radians.
-		The resulting matrix will be:
+		把该矩阵设置为绕z轴旋转弧度[page:Float theta] (&theta;)大小的矩阵。
+		结果如下:
 		<code>
 cos(&theta;) -sin(&theta;) 0 0
 sin(&theta;) cos(&theta;)  0 0
@@ -310,11 +292,11 @@ sin(&theta;) cos(&theta;)  0 0
 
 		<h3>[method:this makeScale]( [param:Float x], [param:Float y], [param:Float z] )</h3>
 		<p>
-			[page:Float x] - the amount to scale in the X axis.<br />
-			[page:Float y] - the amount to scale in the Y axis.<br />
-			[page:Float z] - the amount to scale in the Z axis.<br /><br />
+			[page:Float x] - 在X轴方向的缩放比。<br />
+			[page:Float y] - 在Y轴方向的缩放比。<br />
+			[page:Float z] - 在Z轴方向的缩放比。<br /><br />
 
-			Sets this matrix as scale transform:
+			将这个矩阵设置为缩放变换:
 			<code>
 x, 0, 0, 0,
 0, y, 0, 0,
@@ -325,11 +307,11 @@ x, 0, 0, 0,
 
 		<h3>[method:this makeShear]( [param:Float x], [param:Float y], [param:Float z] )</h3>
 		<p>
-		[page:Float x] - the amount to shear in the X axis.<br />
-		[page:Float y] - the amount to shear in the Y axis.<br />
-		[page:Float z] - the amount to shear in the Z axis.<br /><br />
+		[page:Float x] - 在X轴上剪切的量。<br />
+		[page:Float y] - 在Y轴上剪切的量。<br />
+		[page:Float z] - 在Z轴上剪切的量。<br /><br />
 
-		Sets this matrix as a shear transform:
+		将此矩阵设置为剪切变换:
 <code>
 1, y, z, 0,
 x, 1, z, 0,
@@ -340,11 +322,11 @@ x, y, 1, 0,
 
 		<h3>[method:this makeTranslation]( [param:Float x], [param:Float y], [param:Float z] )</h3>
 		<p>
-			[page:Float x] - the amount to translate in the X axis.<br />
-			[page:Float y] - the amount to translate in the Y axis.<br />
-			[page:Float z] - the amount to translate in the Z axis.<br /><br />
+			[page:Float x] - 在X轴上的平移量。<br />
+			[page:Float y] - 在Y轴上的平移量。<br />
+			[page:Float z] - 在Z轴上的平移量。<br /><br />
 
-		Sets this matrix as a translation transform:
+		设置该矩阵为平移变换:
 		<code>
 1, 0, 0, x,
 0, 1, 0, y,
@@ -354,37 +336,35 @@ x, y, 1, 0,
 		</p>
 
 		<h3>[method:this multiply]( [param:Matrix4 m] )</h3>
-		<p>Post-multiplies this matrix by [page:Matrix4 m].</p>
+		<p>将当前矩阵乘以矩阵[page:Matrix4 m]。</p>
 
 		<h3>[method:this multiplyMatrices]( [param:Matrix4 a], [param:Matrix4 b] )</h3>
-		<p>Sets this matrix to [page:Matrix4 a] x [page:Matrix4 b].</p>
+		<p>设置当前矩阵为矩阵[page:Matrix4 a] x 矩阵[page:Matrix4 b]。</p>
 
 		<h3>[method:this multiplyScalar]( [param:Float s] )</h3>
-		<p>Multiplies every component of the matrix by a scalar value [page:Float s].</p>
+		<p>当前矩阵所有的元素乘以该缩放值*s*</p>
 
 		<h3>[method:this premultiply]( [param:Matrix4 m] )</h3>
-		<p>Pre-multiplies this matrix by [page:Matrix4 m].</p>
+		<p>将矩阵[page:Matrix4 m]乘以当前矩阵。</p>
 
 		<h3>[method:this scale]( [param:Vector3 v] )</h3>
-		<p>Multiplies the columns of this matrix by vector [page:Vector3 v].</p>
+		<p>将该矩阵的列向量乘以对应向量[page:Vector3 v]的分量。</p>
 
 		<h3>[method:this set]( [param:Float n11], [param:Float n12], [param:Float n13], [param:Float n14], [param:Float n21], [param:Float n22], [param:Float n23], [param:Float n24], [param:Float n31], [param:Float n32], [param:Float n33], [param:Float n34], [param:Float n41], [param:Float n42], [param:Float n43], [param:Float n44] )</h3>
 		<p>
-			Set the [page:.elements elements] of this matrix to the supplied row-major values [page:Float n11],
-			[page:Float n12], ... [page:Float n44].
+			以行优先的格式将传入的数值设置给该矩阵中的元素[page:.elements elements]。
 		</p>
 
 		<h3>[method:this setPosition]( [param:Vector3 v] )</h3>
 		<p>
-			Sets the position component for this matrix from vector [page:Vector3 v], without affecting the
-			rest of the matrix - i.e. if the matrix is currently:
+			取传入参数[param:Vector3 v]中值设置该矩阵的位置分量,不影响该矩阵的其余部分——即,如果该矩阵当前为:
 <code>
 a, b, c, d,
 e, f, g, h,
 i, j, k, l,
 m, n, o, p
 </code>
-This becomes:
+变成:
 <code>
 a, b, c, v.x,
 e, f, g, v.y,
@@ -395,17 +375,16 @@ m, n, o, p
 
 		<h3>[method:Array toArray]( [param:Array array], [param:Integer offset] )</h3>
 		<p>
-		[page:Array array] - (optional) array to store the resulting vector in.<br />
-		[page:Integer offset] - (optional) offset in the array at which to put the result.<br /><br />
+		[page:Array array] - (可选参数) 存储矩阵元素的数组,如果未指定会创建一个新的数组。<br />
+		[page:Integer offset] -  (可选参数) 存放矩阵元素数组的偏移量。<br /><br />
 
-		Writes the elements of this matrix to an array in
-		[link:https://en.wikipedia.org/wiki/Row-_and_column-major_order#Column-major_order column-major] format.
+		使用列优先[link:https://en.wikipedia.org/wiki/Row-_and_column-major_order#Column-major_order column-major]格式将此矩阵的元素写入数组中。
 		</p>
 
 		<h3>[method:this transpose]()</h3>
-		<p>[link:https://en.wikipedia.org/wiki/Transpose Transposes] this matrix.</p>
+		<p>将该矩阵转置[link:https://en.wikipedia.org/wiki/Transpose Transposes]</p>
 
-		<h2>Source</h2>
+		<h2>源码(Source</h2>
 
 		[link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js]
 	</body>

+ 49 - 58
docs/api/zh/math/Plane.html

@@ -8,165 +8,156 @@
 		<link type="text/css" rel="stylesheet" href="page.css" />
 	</head>
 	<body>
-		<h1>[name]</h1>
+		<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>
 

+ 3 - 2
docs/examples/utils/BufferGeometryUtils.html

@@ -25,9 +25,10 @@
 
     </p>
 
-    <h3>[method:BufferGeometry mergeBufferGeometries]( [param:Array geometries] )</h3>
+    <h3>[method:BufferGeometry mergeBufferGeometries]( [param:Array geometries], [param:Boolean useGroups] )</h3>
     <p>
-    geometries -- Array of [page:BufferGeometry BufferGeometry] instances.<br /><br />
+    geometries -- Array of [page:BufferGeometry BufferGeometry] instances.<br />
+    useGroups -- Whether groups should be generated for the merged geometry or not.<br /><br />
 
     Merges a set of geometries into a single instance. All geometries must have compatible attributes.
     If merge does not succeed, the method returns null.<br /><br />

+ 4 - 4
docs/examples/utils/SceneUtils.html

@@ -29,11 +29,11 @@
 		<h3>[method:null attach]( [param:Object3D child], [param:Object3D scene], [param:Object3D parent] )</h3>
 		<p>
 		child -- The object to add to the parent  <br />
-		scene -- The scene to detach the object on. <br />
-		parent -- The parent to attach the object from.
+		scene -- The scene to detach the object from. <br />
+		parent -- The parent to attach the object to.
 		</p>
 		<p>
-		Attaches the object to the parent without the moving the object in the worldspace. Beware that to do this the matrixWorld needs to be updated, this can be done by calling the updateMatrixWorld method on the parent object.
+		Attaches the object to the parent without the moving the object in the worldspace. Beware that to do this the matrixWorld needs to be updated. This can be done by calling the updateMatrixWorld method on the parent object.
 		</p>
 
 		<h3>[method:null detach]( [param:Object3D child], [param:Object3D parent], [param:Object3D scene] )</h3>
@@ -43,7 +43,7 @@
 		parent -- The parent to detach the object from.
 		</p>
 		<p>
-		Detaches the object from the parent and adds it back to the scene without moving in worldspace. Beware that to do this the matrixWorld needs to be updated, this can be done by calling the updateMatrixWorld method on the parent object.
+		Detaches the object from the parent and adds it back to the scene without moving in worldspace. Beware that to do this the matrixWorld needs to be updated. This can be done by calling the updateMatrixWorld method on the parent object.
 		</p>
 
 		<h2>Source</h2>

+ 0 - 2
docs/list.js

@@ -233,7 +233,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",
@@ -658,7 +657,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, probably 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>

+ 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;
 

+ 2 - 2
editor/js/Menubar.Play.js

@@ -20,13 +20,13 @@ Menubar.Play = function ( editor ) {
 		if ( isPlaying === false ) {
 
 			isPlaying = true;
-			title.setTextContent( 'Stop' );
+			title.setTextContent( strings.getKey( 'menubar/play/stop' ) );
 			signals.startPlayer.dispatch();
 
 		} else {
 
 			isPlaying = false;
-			title.setTextContent( 'Play' );
+			title.setTextContent( strings.getKey( 'menubar/play/play' ) );
 			signals.stopPlayer.dispatch();
 
 		}

+ 3 - 1
editor/js/Menubar.Status.js

@@ -4,10 +4,12 @@
 
 Menubar.Status = function ( editor ) {
 
+	var strings = editor.strings;
+
 	var container = new UI.Panel();
 	container.setClass( 'menu right' );
 
-	var autosave = new UI.THREE.Boolean( editor.config.getKey( 'autosave' ), 'autosave' );
+	var autosave = new UI.THREE.Boolean( editor.config.getKey( 'autosave' ), strings.getKey( 'menubar/status/autosave' ) );
 	autosave.text.setColor( '#888' );
 	autosave.onChange( function () {
 

+ 4 - 2
editor/js/Sidebar.History.js

@@ -5,6 +5,8 @@
 
 Sidebar.History = function ( editor ) {
 
+	var strings = editor.strings;
+
 	var signals = editor.signals;
 
 	var config = editor.config;
@@ -13,11 +15,11 @@ Sidebar.History = function ( editor ) {
 
 	var container = new UI.Panel();
 
-	container.add( new UI.Text( 'HISTORY' ) );
+	container.add( new UI.Text( strings.getKey( 'sidebar/history/history' ) ) );
 
 	//
 
-	var persistent = new UI.THREE.Boolean( config.getKey( 'settings/history' ), 'persistent' );
+	var persistent = new UI.THREE.Boolean( config.getKey( 'settings/history' ), strings.getKey( 'sidebar/history/persistent' ) );
 	persistent.setPosition( 'absolute' ).setRight( '8px' );
 	persistent.onChange( function () {
 

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

@@ -132,7 +132,7 @@ Sidebar.Material = function ( editor ) {
 	var materialProgramRow = new UI.Row();
 	materialProgramRow.add( new UI.Text( strings.getKey( 'sidebar/material/program' ) ).setWidth( '90px' ) );
 
-	var materialProgramInfo = new UI.Button( 'Info' );
+	var materialProgramInfo = new UI.Button( strings.getKey( 'sidebar/material/info' ) );
 	materialProgramInfo.setMarginLeft( '4px' );
 	materialProgramInfo.onClick( function () {
 

+ 4 - 4
editor/js/Sidebar.Project.js

@@ -101,7 +101,7 @@ Sidebar.Project = function ( editor ) {
 
 	var rendererPropertiesRow = new UI.Row().setMarginLeft( '90px' );
 
-	var rendererAntialias = new UI.THREE.Boolean( config.getKey( 'project/renderer/antialias' ), 'antialias' ).onChange( function () {
+	var rendererAntialias = new UI.THREE.Boolean( config.getKey( 'project/renderer/antialias' ), strings.getKey( 'sidebar/project/antialias' ) ).onChange( function () {
 
 		config.setKey( 'project/renderer/antialias', this.getValue() );
 		updateRenderer();
@@ -111,7 +111,7 @@ Sidebar.Project = function ( editor ) {
 
 	// Renderer / Shadows
 
-	var rendererShadows = new UI.THREE.Boolean( config.getKey( 'project/renderer/shadows' ), 'shadows' ).onChange( function () {
+	var rendererShadows = new UI.THREE.Boolean( config.getKey( 'project/renderer/shadows' ), strings.getKey( 'sidebar/project/shadows' ) ).onChange( function () {
 
 		config.setKey( 'project/renderer/shadows', this.getValue() );
 		updateRenderer();
@@ -123,7 +123,7 @@ Sidebar.Project = function ( editor ) {
 
 	// Renderer / Gamma input
 
-	var rendererGammaInput = new UI.THREE.Boolean( config.getKey( 'project/renderer/gammaInput' ), 'γ input' ).onChange( function () {
+	var rendererGammaInput = new UI.THREE.Boolean( config.getKey( 'project/renderer/gammaInput' ), strings.getKey( 'sidebar/project/gammainput' ) ).onChange( function () {
 
 		config.setKey( 'project/renderer/gammaInput', this.getValue() );
 		updateRenderer();
@@ -133,7 +133,7 @@ Sidebar.Project = function ( editor ) {
 
 	// Renderer / Gamma output
 
-	var rendererGammaOutput = new UI.THREE.Boolean( config.getKey( 'project/renderer/gammaOutput' ), 'γ output' ).onChange( function () {
+	var rendererGammaOutput = new UI.THREE.Boolean( config.getKey( 'project/renderer/gammaOutput' ), strings.getKey( 'sidebar/project/gammaoutput' ) ).onChange( function () {
 
 		config.setKey( 'project/renderer/gammaOutput', this.getValue() );
 		updateRenderer();

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

@@ -52,7 +52,7 @@ Sidebar.Script = function ( editor ) {
 
 		var scripts = editor.scripts[ object.uuid ];
 
-		if ( scripts !== undefined ) {
+		if ( scripts !== undefined && scripts.length > 0 ) {
 
 			scriptsContainer.setDisplay( 'block' );
 

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

@@ -46,8 +46,8 @@ Sidebar.Settings = function ( editor ) {
 	// theme
 
 	var options = {
-		'css/light.css': 'light',
-		'css/dark.css': 'dark'
+		'css/light.css': strings.getKey( 'sidebar/settings/theme/light' ),
+		'css/dark.css': strings.getKey( 'sidebar/settings/theme/dark' )
 	};
 
 	var themeRow = new UI.Row();

+ 37 - 9
editor/js/Strings.js

@@ -51,7 +51,11 @@ var Strings = function ( config ) {
 			'menubar/add/ambientlight': 'AmbientLight',
 			'menubar/add/perspectivecamera': 'PerspectiveCamera',
 
+			'menubar/status/autosave': 'autosave',
+
 			'menubar/play': 'Play',
+			'menubar/play/stop': 'Stop',
+			'menubar/play/play': 'Play',
 
 			'menubar/examples': 'Examples',
 
@@ -220,10 +224,16 @@ var Strings = function ( config ) {
 			'sidebar/project/editable': 'Editable',
 			'sidebar/project/vr': 'VR',
 			'sidebar/project/renderer': 'Renderer',
+			'sidebar/project/antialias': 'antialias',
+			'sidebar/project/shadows': 'shadows',
+			'sidebar/project/gammainput': 'γ input',
+			'sidebar/project/gammaoutput': 'γ output',
 
 			'sidebar/settings': 'Settings',
 			'sidebar/settings/language': 'Language',
 			'sidebar/settings/theme': 'Theme',
+			'sidebar/settings/theme/light': 'light',
+			'sidebar/settings/theme/dark': 'dark',
 
 			'sidebar/settings/shortcuts/translate': 'Translate',
 			'sidebar/settings/shortcuts/rotate': 'Rotate',
@@ -233,6 +243,9 @@ var Strings = function ( config ) {
 
 			'sidebar/settings/viewport/grid': 'Grid',
 
+			'sidebar/history/history': 'HISTORY',
+			'sidebar/history/persistent': 'persistent',
+
 			'toolbar/translate': 'Translate',
 			'toolbar/rotate': 'Rotate',
 			'toolbar/scale': 'Scale',
@@ -287,7 +300,11 @@ var Strings = function ( config ) {
 			'menubar/add/ambientlight': '环境光',
 			'menubar/add/perspectivecamera': '透视相机',
 
+			'menubar/status/autosave': '自动保存',
+
 			'menubar/play': '启动',
+			'menubar/play/stop': '暂停',
+			'menubar/play/play': '启动',
 
 			'menubar/examples': '示例',
 
@@ -403,13 +420,13 @@ var Strings = function ( config ) {
 			'sidebar/material/program': '程序',
 			'sidebar/material/info': '信息',
 			'sidebar/material/vertex': '顶点',
-			'sidebar/material/fragment': '分段',
+			'sidebar/material/fragment': '片元',
 			'sidebar/material/color': '颜色',
-			'sidebar/material/roughness': '粗糙',
-			'sidebar/material/metalness': '金属',
-			'sidebar/material/emissive': '放射性',
+			'sidebar/material/roughness': '粗糙',
+			'sidebar/material/metalness': '金属',
+			'sidebar/material/emissive': '自发光',
 			'sidebar/material/specular': '高光',
-			'sidebar/material/shininess': '发光',
+			'sidebar/material/shininess': '高光大小',
 			'sidebar/material/clearcoat': '透明贴图',
 			'sidebar/material/clearcoatroughness': '透明贴图粗糙度',
 			'sidebar/material/vertexcolors': '顶点颜色',
@@ -421,17 +438,17 @@ var Strings = function ( config ) {
 			'sidebar/material/alphamap': '透明贴图',
 			'sidebar/material/bumpmap': '凹凸贴图',
 			'sidebar/material/normalmap': '法线贴图',
-			'sidebar/material/displacemap': '位移贴图',
+			'sidebar/material/displacemap': '置换贴图',
 			'sidebar/material/roughmap': '粗糙贴图',
 			'sidebar/material/metalmap': '金属贴图',
 			'sidebar/material/specularmap': '高光贴图',
 			'sidebar/material/envmap': '环境贴图',
 			'sidebar/material/lightmap': '光照贴图',
-			'sidebar/material/aomap': '烘培贴图',
-			'sidebar/material/emissivemap': '烘培贴图',
+			'sidebar/material/aomap': '环境光遮蔽贴图',
+			'sidebar/material/emissivemap': '自发光贴图',
 			'sidebar/material/side': '面',
 			'sidebar/material/side/front': '正面',
-			'sidebar/material/side/back': '面',
+			'sidebar/material/side/back': '面',
 			'sidebar/material/side/double': '双面',
 			'sidebar/material/flatshaded': '平面着色',
 			'sidebar/material/blending': '混合',
@@ -456,17 +473,28 @@ var Strings = function ( config ) {
 			'sidebar/project/editable': '编辑性',
 			'sidebar/project/vr': '虚拟现实',
 			'sidebar/project/renderer': '渲染器',
+			'sidebar/project/antialias': '抗锯齿',
+			'sidebar/project/shadows': '阴影',
+			'sidebar/project/gammainput': 'γ输入',
+			'sidebar/project/gammaoutput': 'γ输出',
 
 			'sidebar/settings': '设置',
 			'sidebar/settings/language': '语言',
 			'sidebar/settings/theme': '主题',
+			'sidebar/settings/theme/light': '浅色',
+			'sidebar/settings/theme/dark': '深色',
+
 			'sidebar/settings/shortcuts/translate': '移动',
 			'sidebar/settings/shortcuts/rotate': '旋转',
 			'sidebar/settings/shortcuts/scale': '缩放',
 			'sidebar/settings/shortcuts/undo': '撤销',
 			'sidebar/settings/shortcuts/focus': '聚焦',
+
 			'sidebar/settings/viewport/grid': '网格',
 
+			'sidebar/history/history': '历史记录',
+			'sidebar/history/persistent': '本地存储',
+
 			'toolbar/translate': '移动',
 			'toolbar/rotate': '旋转',
 			'toolbar/scale': '缩放',

+ 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": {

+ 2 - 3
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",
@@ -315,8 +314,8 @@ var files = {
 	],
 	"webgl2": [
 		"webgl2_materials_texture3d",
-		"webgl2_materials_texture3d_volume"
-		// "webgl2_sandbox"
+		"webgl2_materials_texture3d_volume",
+		"webgl2_sandbox"
 	],
 	"webaudio": [
 		"webaudio_orientation",

+ 11 - 7
examples/js/controls/DragControls.js

@@ -19,7 +19,9 @@ THREE.DragControls = function ( _objects, _camera, _domElement ) {
 	var _mouse = new THREE.Vector2();
 	var _offset = new THREE.Vector3();
 	var _intersection = new THREE.Vector3();
-
+	var _worldPosition = new THREE.Vector3();
+	var _inverseMatrix = new THREE.Matrix4();
+	
 	var _selected = null, _hovered = null;
 
 	//
@@ -71,7 +73,7 @@ THREE.DragControls = function ( _objects, _camera, _domElement ) {
 
 			if ( _raycaster.ray.intersectPlane( _plane, _intersection ) ) {
 
-				_selected.position.copy( _intersection.sub( _offset ) );
+				_selected.position.copy( _intersection.sub( _offset ).applyMatrix4( _inverseMatrix ) );
 
 			}
 
@@ -89,7 +91,7 @@ THREE.DragControls = function ( _objects, _camera, _domElement ) {
 
 			var object = intersects[ 0 ].object;
 
-			_plane.setFromNormalAndCoplanarPoint( _camera.getWorldDirection( _plane.normal ), object.position );
+			_plane.setFromNormalAndCoplanarPoint( _camera.getWorldDirection( _plane.normal ), _worldPosition.setFromMatrixPosition( object.matrixWorld ) );
 
 			if ( _hovered !== object ) {
 
@@ -129,7 +131,8 @@ THREE.DragControls = function ( _objects, _camera, _domElement ) {
 
 			if ( _raycaster.ray.intersectPlane( _plane, _intersection ) ) {
 
-				_offset.copy( _intersection ).sub( _selected.position );
+				_inverseMatrix.getInverse( _selected.parent.matrixWorld );
+				_offset.copy( _intersection ).sub( _worldPosition.setFromMatrixPosition( _selected.matrixWorld ) );
 
 			}
 
@@ -174,7 +177,7 @@ THREE.DragControls = function ( _objects, _camera, _domElement ) {
 
 			if ( _raycaster.ray.intersectPlane( _plane, _intersection ) ) {
 
-				_selected.position.copy( _intersection.sub( _offset ) );
+				_selected.position.copy( _intersection.sub( _offset ).applyMatrix4( _inverseMatrix ) );
 
 			}
 
@@ -204,11 +207,12 @@ THREE.DragControls = function ( _objects, _camera, _domElement ) {
 
 			_selected = intersects[ 0 ].object;
 
-			_plane.setFromNormalAndCoplanarPoint( _camera.getWorldDirection( _plane.normal ), _selected.position );
+			_plane.setFromNormalAndCoplanarPoint( _camera.getWorldDirection( _plane.normal ), _worldPosition.setFromMatrixPosition( _selected.matrixWorld ) );
 
 			if ( _raycaster.ray.intersectPlane( _plane, _intersection ) ) {
 
-				_offset.copy( _intersection ).sub( _selected.position );
+				_inverseMatrix.getInverse( _selected.parent.matrixWorld );
+				_offset.copy( _intersection ).sub( _worldPosition.setFromMatrixPosition( _selected.matrixWorld ) );
 
 			}
 

+ 6 - 0
examples/js/exporters/GLTFExporter.js

@@ -1666,6 +1666,12 @@ THREE.GLTFExporter.prototype = {
 
 			}
 
+			if ( scene.userData && Object.keys( scene.userData ).length > 0 ) {
+
+				gltfScene.extras = serializeUserData( scene );
+
+			}
+
 			outputJSON.scenes.push( gltfScene );
 
 			var nodes = [];

+ 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;
+
+} )();

+ 19 - 6
examples/js/loaders/GLTFLoader.js

@@ -949,11 +949,22 @@ THREE.GLTFLoader = ( function () {
 
 				}
 
-				uniforms.envMap.value = material.envMap;
-				uniforms.envMapIntensity.value = material.envMapIntensity;
-				uniforms.flipEnvMap.value = ( material.envMap && material.envMap.isCubeTexture ) ? - 1 : 1;
+				if ( material.envMap ) {
 
-				uniforms.refractionRatio.value = material.refractionRatio;
+					uniforms.envMap.value = material.envMap;
+					uniforms.envMapIntensity.value = material.envMapIntensity;
+
+					// don't flip CubeTexture envMaps, flip everything else:
+					//  WebGLRenderTargetCube will be flipped for backwards compatibility
+					//  WebGLRenderTargetCube.texture will be flipped because it's a Texture and NOT a CubeTexture
+					// this check must be handled differently, or removed entirely, if WebGLRenderTargetCube uses a CubeTexture in the future
+					uniforms.flipEnvMap.value = material.envMap.isCubeTexture ? - 1 : 1;
+
+					uniforms.reflectivity.value = material.reflectivity;
+					uniforms.refractionRatio.value = material.refractionRatio;
+
+					uniforms.maxMipLevel.value = renderer.properties.get( material.envMap ).__maxMipLevel;
+				}
 
 				uniforms.specular.value.copy( material.specular );
 				uniforms.glossiness.value = material.glossiness;
@@ -1046,10 +1057,10 @@ THREE.GLTFLoader = ( function () {
 		var offset1 = i1 * stride3;
 		var offset0 = offset1 - stride3;
 
-		var s0 = 2 * ppp - 3 * pp + 1;
-		var s1 = ppp - 2 * pp + p;
 		var s2 = - 2 * ppp + 3 * pp;
 		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, ... ]
@@ -2694,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;

+ 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;
 
 			}
 

+ 7 - 3
examples/js/loaders/OBJLoader.js

@@ -688,14 +688,18 @@ THREE.OBJLoader = ( function () {
 						if ( isLine && material && ! ( material instanceof THREE.LineBasicMaterial ) ) {
 
 							var materialLine = new THREE.LineBasicMaterial();
-							materialLine.copy( material );
-							materialLine.lights = false; // TOFIX
+							THREE.Material.prototype.copy.call( materialLine, material );
+							materialLine.color.copy( material.color );
+							materialLine.lights = false;
 							material = materialLine;
 
 						} else if ( isPoints && material && ! ( material instanceof THREE.PointsMaterial ) ) {
 
 							var materialPoints = new THREE.PointsMaterial( { size: 10, sizeAttenuation: false } );
-							materialLine.copy( material );
+							THREE.Material.prototype.copy.call( materialPoints, material );
+							materialPoints.color.copy( material.color );
+							materialPoints.map = material.map;
+							materialPoints.lights = false;
 							material = materialPoints;
 
 						}

+ 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;
+
+} )();

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

@@ -211,6 +211,7 @@ THREE.AdaptiveToneMappingPass.prototype = Object.assign( Object.create( THREE.Pa
 
 		// We only need mipmapping for the current luminosity because we want a down-sampled version to sample in our adaptive shader
 		pars.minFilter = THREE.LinearMipMapLinearFilter;
+		pars.generateMipmaps = true;
 		this.currentLuminanceRT = new THREE.WebGLRenderTarget( this.resolution, this.resolution, pars );
 		this.currentLuminanceRT.texture.name = "AdaptiveToneMappingPass.cl";
 

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

@@ -16,6 +16,7 @@ THREE.SAOPass = function ( scene, camera, depthTexture, useNormals, resolution )
 	this.supportsDepthTextureExtension = ( depthTexture !== undefined ) ? depthTexture : false;
 	this.supportsNormalTexture = ( useNormals !== undefined ) ? useNormals : false;
 
+	this.originalClearColor = new THREE.Color();
 	this.oldClearColor = new THREE.Color();
 	this.oldClearAlpha = 1;
 
@@ -312,7 +313,7 @@ THREE.SAOPass.prototype = Object.assign( Object.create( THREE.Pass.prototype ),
 	renderPass: function ( renderer, passMaterial, renderTarget, clearColor, clearAlpha ) {
 
 		// save original state
-		var originalClearColor = renderer.getClearColor();
+		this.originalClearColor.copy( renderer.getClearColor() );
 		var originalClearAlpha = renderer.getClearAlpha();
 		var originalAutoClear = renderer.autoClear;
 
@@ -331,14 +332,14 @@ THREE.SAOPass.prototype = Object.assign( Object.create( THREE.Pass.prototype ),
 
 		// restore original state
 		renderer.autoClear = originalAutoClear;
-		renderer.setClearColor( originalClearColor );
+		renderer.setClearColor( this.originalClearColor );
 		renderer.setClearAlpha( originalClearAlpha );
 
 	},
 
 	renderOverride: function ( renderer, overrideMaterial, renderTarget, clearColor, clearAlpha ) {
 
-		var originalClearColor = renderer.getClearColor();
+		this.originalClearColor.copy( renderer.getClearColor() );
 		var originalClearAlpha = renderer.getClearAlpha();
 		var originalAutoClear = renderer.autoClear;
 
@@ -360,7 +361,7 @@ THREE.SAOPass.prototype = Object.assign( Object.create( THREE.Pass.prototype ),
 
 		// restore original state
 		renderer.autoClear = originalAutoClear;
-		renderer.setClearColor( originalClearColor );
+		renderer.setClearColor( this.originalClearColor );
 		renderer.setClearAlpha( originalClearAlpha );
 
 	},

+ 340 - 130
examples/js/postprocessing/SSAOPass.js

@@ -1,190 +1,400 @@
-'use strict';
-
 /**
- * Screen-space ambient occlusion pass.
- *
- * Has the following parameters
- *  - radius
- *  	- Ambient occlusion shadow radius (numeric value).
- *  - onlyAO
- *  	- Display only ambient occlusion result (boolean value).
- *  - aoClamp
- *  	- Ambient occlusion clamp (numeric value).
- *  - lumInfluence
- *  	- Pixel luminosity influence in AO calculation (numeric value).
- *
- * To output to screen set renderToScreens true
- *
- * @author alteredq / http://alteredqualia.com/
- * @author tentone
- * @class SSAOPass
+ * @author Mugen87 / https://github.com/Mugen87
  */
+
 THREE.SSAOPass = function ( scene, camera, width, height ) {
 
+	THREE.Pass.call( this );
+
+	this.width = ( width !== undefined ) ? width : 512;
+	this.height = ( height !== undefined ) ? height : 512;
+
+	this.clear = true;
+
+	this.camera = camera;
+	this.scene = scene;
+
+	this.kernelRadius = 8;
+	this.kernelSize = 64;
+	this.kernel = [];
+	this.noiseTexture = null;
+	this.output = 0;
+
+	this.minDistance = 0.005;
+	this.maxDistance = 0.1;
+
+	//
+
+	this.generateSampleKernel();
+	this.generateRandomKernelRotations();
+
+	// beauty render target with depth buffer
+
+	var depthTexture = new THREE.DepthTexture();
+	depthTexture.type = THREE.UnsignedShortType;
+	depthTexture.minFilter = THREE.NearestFilter;
+	depthTexture.maxFilter = THREE.NearestFilter;
+
+	this.beautyRenderTarget = new THREE.WebGLRenderTarget( this.width, this.height, {
+		minFilter: THREE.LinearFilter,
+		magFilter: THREE.LinearFilter,
+		format: THREE.RGBAFormat,
+		depthTexture: depthTexture,
+		depthBuffer: true
+	} );
+
+	// normal render target
+
+	this.normalRenderTarget = new THREE.WebGLRenderTarget( this.width, this.height, {
+		minFilter: THREE.NearestFilter,
+		magFilter: THREE.NearestFilter,
+		format: THREE.RGBAFormat
+	} );
+
+	// ssao render target
+
+	this.ssaoRenderTarget = new THREE.WebGLRenderTarget( this.width, this.height, {
+		minFilter: THREE.LinearFilter,
+		magFilter: THREE.LinearFilter,
+		format: THREE.RGBAFormat
+	} );
+
+	this.blurRenderTarget = this.ssaoRenderTarget.clone();
+
+	// ssao material
+
 	if ( THREE.SSAOShader === undefined ) {
 
-		console.warn( 'THREE.SSAOPass depends on THREE.SSAOShader' );
-		return new THREE.ShaderPass();
+		console.error( 'THREE.SSAOPass: The pass relies on THREE.SSAOShader.' );
 
 	}
 
-	THREE.ShaderPass.call( this, THREE.SSAOShader );
+	this.ssaoMaterial = new THREE.ShaderMaterial( {
+		defines: Object.assign( {}, THREE.SSAOShader.defines ),
+		uniforms: THREE.UniformsUtils.clone( THREE.SSAOShader.uniforms ),
+		vertexShader: THREE.SSAOShader.vertexShader,
+		fragmentShader: THREE.SSAOShader.fragmentShader,
+		blending: THREE.NoBlending
+	} );
 
-	this.width = ( width !== undefined ) ? width : 512;
-	this.height = ( height !== undefined ) ? height : 256;
+	this.ssaoMaterial.uniforms[ 'tDiffuse' ].value = this.beautyRenderTarget.texture;
+	this.ssaoMaterial.uniforms[ 'tNormal' ].value = this.normalRenderTarget.texture;
+	this.ssaoMaterial.uniforms[ 'tDepth' ].value = this.beautyRenderTarget.depthTexture;
+	this.ssaoMaterial.uniforms[ 'tNoise' ].value = this.noiseTexture;
+	this.ssaoMaterial.uniforms[ 'kernel' ].value = this.kernel;
+	this.ssaoMaterial.uniforms[ 'cameraNear' ].value = this.camera.near;
+	this.ssaoMaterial.uniforms[ 'cameraFar' ].value = this.camera.far;
+	this.ssaoMaterial.uniforms[ 'resolution' ].value.set( this.width, this.height );
+	this.ssaoMaterial.uniforms[ 'cameraProjectionMatrix' ].value.copy( this.camera.projectionMatrix );
+	this.ssaoMaterial.uniforms[ 'cameraInverseProjectionMatrix' ].value.getInverse( this.camera.projectionMatrix );
+
+	// normal material
+
+	this.normalMaterial = new THREE.MeshNormalMaterial();
+	this.normalMaterial.blending = THREE.NoBlending;
+
+	// blur material
+
+	this.blurMaterial = new THREE.ShaderMaterial( {
+		defines: Object.assign( {}, THREE.SSAOBlurShader.defines ),
+		uniforms: THREE.UniformsUtils.clone( THREE.SSAOBlurShader.uniforms ),
+		vertexShader: THREE.SSAOBlurShader.vertexShader,
+		fragmentShader: THREE.SSAOBlurShader.fragmentShader
+	} );
+	this.blurMaterial.uniforms[ 'tDiffuse' ].value = this.ssaoRenderTarget.texture;
+	this.blurMaterial.uniforms[ 'resolution' ].value.set( this.width, this.height );
 
-	this.renderToScreen = false;
+	// material for rendering the depth
 
-	this.camera2 = camera;
-	this.scene2 = scene;
+	this.depthRenderMaterial = new THREE.ShaderMaterial( {
+		defines: Object.assign( {}, THREE.SSAODepthShader.defines ),
+		uniforms: THREE.UniformsUtils.clone( THREE.SSAODepthShader.uniforms ),
+		vertexShader: THREE.SSAODepthShader.vertexShader,
+		fragmentShader: THREE.SSAODepthShader.fragmentShader,
+		blending: THREE.NoBlending
+	} );
+	this.depthRenderMaterial.uniforms[ 'tDepth' ].value = this.beautyRenderTarget.depthTexture;
+	this.depthRenderMaterial.uniforms[ 'cameraNear' ].value = this.camera.near;
+	this.depthRenderMaterial.uniforms[ 'cameraFar' ].value = this.camera.far;
+
+	// material for rendering the content of a render target
+
+	this.copyMaterial = new THREE.ShaderMaterial( {
+		uniforms: THREE.UniformsUtils.clone( THREE.CopyShader.uniforms ),
+		vertexShader: THREE.CopyShader.vertexShader,
+		fragmentShader: THREE.CopyShader.fragmentShader,
+		transparent: true,
+		depthTest: false,
+		depthWrite: false,
+		blendSrc: THREE.DstColorFactor,
+		blendDst: THREE.ZeroFactor,
+		blendEquation: THREE.AddEquation,
+		blendSrcAlpha: THREE.DstAlphaFactor,
+		blendDstAlpha: THREE.ZeroFactor,
+		blendEquationAlpha: THREE.AddEquation
+	} );
 
-	//Depth material
-	this.depthMaterial = new THREE.MeshDepthMaterial();
-	this.depthMaterial.depthPacking = THREE.RGBADepthPacking;
-	this.depthMaterial.blending = THREE.NoBlending;
+	//
 
-	//Depth render target
-	this.depthRenderTarget = new THREE.WebGLRenderTarget( this.width, this.height, { minFilter: THREE.LinearFilter, magFilter: THREE.LinearFilter } );
-	//this.depthRenderTarget.texture.name = 'SSAOShader.rt';
+	this.quadCamera = new THREE.OrthographicCamera( - 1, 1, 1, - 1, 0, 1 );
+	this.quadScene = new THREE.Scene();
+	this.quad = new THREE.Mesh( new THREE.PlaneBufferGeometry( 2, 2 ), null );
+	this.quadScene.add( this.quad );
 
-	//Shader uniforms
-	this.uniforms[ 'tDepth' ].value = this.depthRenderTarget.texture;
-	this.uniforms[ 'size' ].value.set( this.width, this.height );
-	this.uniforms[ 'cameraNear' ].value = this.camera2.near;
-	this.uniforms[ 'cameraFar' ].value = this.camera2.far;
+	//
 
-	this.uniforms[ 'radius' ].value = 4;
-	this.uniforms[ 'onlyAO' ].value = false;
-	this.uniforms[ 'aoClamp' ].value = 0.25;
-	this.uniforms[ 'lumInfluence' ].value = 0.7;
+	this.originalClearColor = new THREE.Color();
 
-	//Setters and getters for uniforms
+};
 
-	Object.defineProperties( this, {
+THREE.SSAOPass.prototype = Object.assign( Object.create( THREE.Pass.prototype ), {
 
-		radius: {
-			get: function () {
+	constructor: THREE.SSAOPass,
 
-				return this.uniforms[ 'radius' ].value;
+	dispose: function () {
 
-			},
-			set: function ( value ) {
+		// dispose render targets
 
-				this.uniforms[ 'radius' ].value = value;
+		this.beautyRenderTarget.dispose();
+		this.normalRenderTarget.dispose();
+		this.ssaoRenderTarget.dispose();
+		this.blurRenderTarget.dispose();
 
-			}
-		},
+		// dispose geometry
 
-		onlyAO: {
-			get: function () {
+		this.quad.geometry.dispose();
 
-				return this.uniforms[ 'onlyAO' ].value;
+		// dispose materials
 
-			},
-			set: function ( value ) {
+		this.normalMaterial.dispose();
+		this.blurMaterial.dispose();
+		this.copyMaterial.dispose();
+		this.depthRenderMaterial.dispose();
 
-				this.uniforms[ 'onlyAO' ].value = value;
+	},
 
-			}
-		},
+	render: function ( renderer, writeBuffer /*, readBuffer, delta, maskActive */ ) {
 
-		aoClamp: {
-			get: function () {
+		// render beauty and depth
 
-				return this.uniforms[ 'aoClamp' ].value;
+		renderer.render( this.scene, this.camera, this.beautyRenderTarget, true );
 
-			},
-			set: function ( value ) {
+		// render normals
 
-				this.uniforms[ 'aoClamp' ].value = value;
+		this.renderOverride( renderer, this.normalMaterial, this.normalRenderTarget, 0x7777ff, 1.0 );
 
-			}
-		},
+		// render SSAO
 
-		lumInfluence: {
-			get: function () {
+		this.ssaoMaterial.uniforms[ 'kernelRadius' ].value = this.kernelRadius;
+		this.ssaoMaterial.uniforms[ 'minDistance' ].value = this.minDistance;
+		this.ssaoMaterial.uniforms[ 'maxDistance' ].value = this.maxDistance;
+		this.renderPass( renderer, this.ssaoMaterial, this.ssaoRenderTarget );
 
-				return this.uniforms[ 'lumInfluence' ].value;
+		// render blur
 
-			},
-			set: function ( value ) {
+		this.renderPass( renderer, this.blurMaterial, this.blurRenderTarget );
 
-				this.uniforms[ 'lumInfluence' ].value = value;
+		// output result to screen
 
-			}
-		},
+		switch ( this.output ) {
 
-	} );
+			case THREE.SSAOPass.OUTPUT.SSAO:
 
-};
+				this.copyMaterial.uniforms[ 'tDiffuse' ].value = this.ssaoRenderTarget.texture;
+				this.copyMaterial.blending = THREE.NoBlending;
+				this.renderPass( renderer, this.copyMaterial, null );
 
-THREE.SSAOPass.prototype = Object.create( THREE.ShaderPass.prototype );
+				break;
 
-/**
- * Render using this pass.
- *
- * @method render
- * @param {WebGLRenderer} renderer
- * @param {WebGLRenderTarget} writeBuffer Buffer to write output.
- * @param {WebGLRenderTarget} readBuffer Input buffer.
- * @param {Number} delta Delta time in milliseconds.
- * @param {Boolean} maskActive Not used in this pass.
- */
-THREE.SSAOPass.prototype.render = function ( renderer, writeBuffer, readBuffer, delta, maskActive ) {
+			case THREE.SSAOPass.OUTPUT.Blur:
 
-	//Render depth into depthRenderTarget
-	this.scene2.overrideMaterial = this.depthMaterial;
+				this.copyMaterial.uniforms[ 'tDiffuse' ].value = this.blurRenderTarget.texture;
+				this.copyMaterial.blending = THREE.NoBlending;
+				this.renderPass( renderer, this.copyMaterial, null );
 
-	renderer.render( this.scene2, this.camera2, this.depthRenderTarget, true );
+				break;
 
-	this.scene2.overrideMaterial = null;
+			case THREE.SSAOPass.OUTPUT.Beauty:
 
+				this.copyMaterial.uniforms[ 'tDiffuse' ].value = this.beautyRenderTarget.texture;
+				this.copyMaterial.blending = THREE.NoBlending;
+				this.renderPass( renderer, this.copyMaterial, null );
 
-	//SSAO shaderPass
-	THREE.ShaderPass.prototype.render.call( this, renderer, writeBuffer, readBuffer, delta, maskActive );
+				break;
 
-};
+			case THREE.SSAOPass.OUTPUT.Depth:
 
-/**
- * Change scene to be renderer by this render pass.
- *
- * @method setScene
- * @param {Scene} scene
- */
-THREE.SSAOPass.prototype.setScene = function ( scene ) {
+				this.renderPass( renderer, this.depthRenderMaterial, null );
 
-	this.scene2 = scene;
+				break;
 
-};
+			case THREE.SSAOPass.OUTPUT.Normal:
 
-/**
- * Set camera used by this render pass.
- *
- * @method setCamera
- * @param {Camera} camera
- */
-THREE.SSAOPass.prototype.setCamera = function ( camera ) {
+				this.copyMaterial.uniforms[ 'tDiffuse' ].value = this.normalRenderTarget.texture;
+				this.copyMaterial.blending = THREE.NoBlending;
+				this.renderPass( renderer, this.copyMaterial, null );
 
-	this.camera2 = camera;
+				break;
 
-	this.uniforms[ 'cameraNear' ].value = this.camera2.near;
-	this.uniforms[ 'cameraFar' ].value = this.camera2.far;
+			case THREE.SSAOPass.OUTPUT.Default:
 
-};
+				this.copyMaterial.uniforms[ 'tDiffuse' ].value = this.beautyRenderTarget.texture;
+				this.copyMaterial.blending = THREE.NoBlending;
+				this.renderPass( renderer, this.copyMaterial, null );
 
-/**
- * Set resolution of this render pass.
- *
- * @method setSize
- * @param {Number} width
- * @param {Number} height
- */
-THREE.SSAOPass.prototype.setSize = function ( width, height ) {
+				this.copyMaterial.uniforms[ 'tDiffuse' ].value = this.blurRenderTarget.texture;
+				this.copyMaterial.blending = THREE.CustomBlending;
+				this.renderPass( renderer, this.copyMaterial, this.renderToScreen ? null : writeBuffer );
+
+				break;
+
+			default:
+				console.warn( 'THREE.SSAOPass: Unknown output type.' );
+
+		}
+
+	},
+
+	renderPass: function ( renderer, passMaterial, renderTarget, clearColor, clearAlpha ) {
 
-	this.width = width;
-	this.height = height;
+		// save original state
+		this.originalClearColor.copy( renderer.getClearColor() );
+		var originalClearAlpha = renderer.getClearAlpha();
+		var originalAutoClear = renderer.autoClear;
+
+		// setup pass state
+		renderer.autoClear = false;
+		var clearNeeded = ( clearColor !== undefined ) && ( clearColor !== null );
+		if ( clearNeeded ) {
+
+			renderer.setClearColor( clearColor );
+			renderer.setClearAlpha( clearAlpha || 0.0 );
+
+		}
+
+		this.quad.material = passMaterial;
+		renderer.render( this.quadScene, this.quadCamera, renderTarget, clearNeeded );
+
+		// restore original state
+		renderer.autoClear = originalAutoClear;
+		renderer.setClearColor( this.originalClearColor );
+		renderer.setClearAlpha( originalClearAlpha );
+
+	},
+
+	renderOverride: function ( renderer, overrideMaterial, renderTarget, clearColor, clearAlpha ) {
+
+		this.originalClearColor.copy( renderer.getClearColor() );
+		var originalClearAlpha = renderer.getClearAlpha();
+		var originalAutoClear = renderer.autoClear;
+
+		renderer.autoClear = false;
+
+		clearColor = overrideMaterial.clearColor || clearColor;
+		clearAlpha = overrideMaterial.clearAlpha || clearAlpha;
+
+		var clearNeeded = ( clearColor !== undefined ) && ( clearColor !== null );
+
+		if ( clearNeeded ) {
+
+			renderer.setClearColor( clearColor );
+			renderer.setClearAlpha( clearAlpha || 0.0 );
+
+		}
+
+		this.scene.overrideMaterial = overrideMaterial;
+		renderer.render( this.scene, this.camera, renderTarget, clearNeeded );
+		this.scene.overrideMaterial = null;
+
+		// restore original state
+
+		renderer.autoClear = originalAutoClear;
+		renderer.setClearColor( this.originalClearColor );
+		renderer.setClearAlpha( originalClearAlpha );
+
+	},
+
+	setSize: function ( width, height ) {
+
+		this.width = width;
+		this.height = height;
+
+		this.beautyRenderTarget.setSize( width, height );
+		this.ssaoRenderTarget.setSize( width, height );
+		this.normalRenderTarget.setSize( width, height );
+		this.blurRenderTarget.setSize( width, height );
+
+		this.ssaoMaterial.uniforms[ 'resolution' ].value.set( width, height );
+		this.ssaoMaterial.uniforms[ 'cameraProjectionMatrix' ].value.copy( this.camera.projectionMatrix );
+		this.ssaoMaterial.uniforms[ 'cameraInverseProjectionMatrix' ].value.getInverse( this.camera.projectionMatrix );
+
+		this.blurMaterial.uniforms[ 'resolution' ].value.set( width, height );
+
+	},
+
+	generateSampleKernel: function () {
+
+		var kernelSize = this.kernelSize;
+		var kernel = this.kernel;
+
+		for ( var i = 0; i < kernelSize; i ++ ) {
+
+			var sample = new THREE.Vector3();
+			sample.x = ( Math.random() * 2 ) - 1;
+			sample.y = ( Math.random() * 2 ) - 1;
+			sample.z = Math.random();
+
+			sample.normalize();
+
+			var scale = i / kernelSize;
+			scale = THREE.Math.lerp( 0.1, 1, scale * scale );
+			sample.multiplyScalar( scale );
+
+			kernel.push( sample );
+
+		}
+
+	},
+
+	generateRandomKernelRotations: function () {
+
+		var width = 4, height = 4;
+
+		if ( SimplexNoise === undefined ) {
+
+			console.error( 'THREE.SSAOPass: The pass relies on THREE.SimplexNoise.' );
+
+		}
+
+		var simplex = new SimplexNoise();
+
+		var size = width * height;
+		var data = new Float32Array( size );
+
+		for ( var i = 0; i < size; i ++ ) {
+
+			var x = ( Math.random() * 2 ) - 1;
+			var y = ( Math.random() * 2 ) - 1;
+			var z = 0;
+
+			data[ i ] = simplex.noise3d( x, y, z );
+
+		}
+
+		this.noiseTexture = new THREE.DataTexture( data, width, height, THREE.LuminanceFormat, THREE.FloatType );
+		this.noiseTexture.wrapS = THREE.RepeatWrapping;
+		this.noiseTexture.wrapT = THREE.RepeatWrapping;
+		this.noiseTexture.needsUpdate = true;
+
+	}
 
-	this.uniforms[ 'size' ].value.set( this.width, this.height );
-	this.depthRenderTarget.setSize( this.width, this.height );
+} );
 
+THREE.SSAOPass.OUTPUT = {
+	'Default': 0,
+	'SSAO': 1,
+	'Blur': 2,
+	'Beauty': 3,
+	'Depth': 4,
+	'Normal': 5
 };

+ 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 );
 

+ 8 - 1
examples/js/renderers/CSS3DRenderer.js

@@ -291,8 +291,15 @@ THREE.CSS3DRenderer = function () {
 
 		if ( camera.parent === null ) camera.updateMatrixWorld();
 
+		if ( camera.isOrthographicCamera ) {
+
+			var tx = - ( camera.right + camera.left ) / 2;
+			var ty = ( camera.top + camera.bottom ) / 2;
+
+		}
+
 		var cameraCSSMatrix = camera.isOrthographicCamera ?
-			'scale(' + fov + ')' + getCameraCSSMatrix( camera.matrixWorldInverse ) :
+			'scale(' + fov + ')' + 'translate(' + epsilon( tx ) + 'px,' + epsilon( ty ) + 'px)' + getCameraCSSMatrix( camera.matrixWorldInverse ) :
 			'translateZ(' + fov + 'px)' + getCameraCSSMatrix( camera.matrixWorldInverse );
 
 		var style = cameraCSSMatrix +

+ 185 - 123
examples/js/shaders/SSAOShader.js

@@ -1,29 +1,34 @@
 /**
- * @author alteredq / http://alteredqualia.com/
+ * @author Mugen87 / https://github.com/Mugen87
  *
- * Screen-space ambient occlusion shader
- * - ported from
- *   SSAO GLSL shader v1.2
- *   assembled by Martins Upitis (martinsh) (http://devlog-martinsh.blogspot.com)
- *   original technique is made by ArKano22 (http://www.gamedev.net/topic/550699-ssao-no-halo-artifacts/)
- * - modifications
- * - modified to use RGBA packed depth texture (use clear color 1,1,1,1 for depth pass)
- * - refactoring and optimizations
+ * References:
+ * http://john-chapman-graphics.blogspot.com/2013/01/ssao-tutorial.html
+ * https://learnopengl.com/Advanced-Lighting/SSAO
+ * https://github.com/McNopper/OpenGL/blob/master/Example28/shader/ssao.frag.glsl
  */
 
 THREE.SSAOShader = {
 
+	defines: {
+		"PERSPECTIVE_CAMERA": 1,
+		"KERNEL_SIZE": 64
+	},
+
 	uniforms: {
 
-		"tDiffuse":     { value: null },
-		"tDepth":       { value: null },
-		"size":         { value: new THREE.Vector2( 512, 512 ) },
-		"cameraNear":   { value: 1 },
-		"cameraFar":    { value: 100 },
-		"radius":       { value: 32 },
-		"onlyAO":       { value: 0 },
-		"aoClamp":      { value: 0.25 },
-		"lumInfluence": { value: 0.7 }
+		"tDiffuse": { value: null },
+		"tNormal": { value: null },
+		"tDepth": { value: null },
+		"tNoise": { value: null },
+		"kernel": { value: null },
+		"cameraNear": { value: null },
+		"cameraFar": { value: null },
+		"resolution": { value: new THREE.Vector2() },
+		"cameraProjectionMatrix": { value: new THREE.Matrix4() },
+		"cameraInverseProjectionMatrix": { value: new THREE.Matrix4() },
+		"kernelRadius": { value: 8 },
+		"minDistance": { value: 0.005 },
+		"maxDistance": { value: 0.05 },
 
 	},
 
@@ -33,9 +38,9 @@ THREE.SSAOShader = {
 
 		"void main() {",
 
-			"vUv = uv;",
+		"	vUv = uv;",
 
-			"gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );",
+		"	gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );",
 
 		"}"
 
@@ -43,188 +48,245 @@ THREE.SSAOShader = {
 
 	fragmentShader: [
 
+		"uniform sampler2D tDiffuse;",
+		"uniform sampler2D tNormal;",
+		"uniform sampler2D tDepth;",
+		"uniform sampler2D tNoise;",
+
+		"uniform vec3 kernel[ KERNEL_SIZE ];",
+
+		"uniform vec2 resolution;",
+
 		"uniform float cameraNear;",
 		"uniform float cameraFar;",
-		"#ifdef USE_LOGDEPTHBUF",
-			"uniform float logDepthBufFC;",
-		"#endif",
+		"uniform mat4 cameraProjectionMatrix;",
+		"uniform mat4 cameraInverseProjectionMatrix;",
 
-		"uniform float radius;",     // ao radius
-		"uniform bool onlyAO;",      // use only ambient occlusion pass?
+		"uniform float kernelRadius;",
+		"uniform float minDistance;", // avoid artifacts caused by neighbour fragments with minimal depth difference
+		"uniform float maxDistance;", // avoid the influence of fragments which are too far away
 
-		"uniform vec2 size;",        // texture width, height
-		"uniform float aoClamp;",    // depth clamp - reduces haloing at screen edges
+		"varying vec2 vUv;",
 
-		"uniform float lumInfluence;",  // how much luminance affects occlusion
+		"#include <packing>",
 
-		"uniform sampler2D tDiffuse;",
-		"uniform sampler2D tDepth;",
+		"float getDepth( const in vec2 screenPosition ) {",
 
-		"varying vec2 vUv;",
+		"	return texture2D( tDepth, screenPosition ).x;",
 
-		// "#define PI 3.14159265",
-		"#define DL 2.399963229728653",  // PI * ( 3.0 - sqrt( 5.0 ) )
-		"#define EULER 2.718281828459045",
+		"}",
 
-		// user variables
+		"float getLinearDepth( const in vec2 screenPosition ) {",
 
-		"const int samples = 64;",     // ao sample count
+		"	#if PERSPECTIVE_CAMERA == 1",
 
-		"const bool useNoise = true;",      // use noise instead of pattern for sample dithering
-		"const float noiseAmount = 0.0004;", // dithering amount
+		"		float fragCoordZ = texture2D( tDepth, screenPosition ).x;",
+		"		float viewZ = perspectiveDepthToViewZ( fragCoordZ, cameraNear, cameraFar );",
+		"		return viewZToOrthographicDepth( viewZ, cameraNear, cameraFar );",
 
-		"const float diffArea = 0.4;",   // self-shadowing reduction
-		"const float gDisplace = 0.4;",  // gauss bell center
+		"	#else",
 
+		"		return texture2D( depthSampler, coord ).x;",
 
-		// RGBA depth
+		"	#endif",
 
-		"#include <packing>",
+		"}",
 
-		// generating noise / pattern texture for dithering
+		"float getViewZ( const in float depth ) {",
 
-		"vec2 rand( const vec2 coord ) {",
+		"	#if PERSPECTIVE_CAMERA == 1",
 
-			"vec2 noise;",
+		"		return perspectiveDepthToViewZ( depth, cameraNear, cameraFar );",
 
-			"if ( useNoise ) {",
+		"	#else",
 
-				"float nx = dot ( coord, vec2( 12.9898, 78.233 ) );",
-				"float ny = dot ( coord, vec2( 12.9898, 78.233 ) * 2.0 );",
+		"		return orthographicDepthToViewZ( depth, cameraNear, cameraFar );",
 
-				"noise = clamp( fract ( 43758.5453 * sin( vec2( nx, ny ) ) ), 0.0, 1.0 );",
+		"	#endif",
 
-			"} else {",
+		"}",
+
+		"vec3 getViewPosition( const in vec2 screenPosition, const in float depth, const in float viewZ ) {",
 
-				"float ff = fract( 1.0 - coord.s * ( size.x / 2.0 ) );",
-				"float gg = fract( coord.t * ( size.y / 2.0 ) );",
+		"	float clipW = cameraProjectionMatrix[2][3] * viewZ + cameraProjectionMatrix[3][3];",
 
-				"noise = vec2( 0.25, 0.75 ) * vec2( ff ) + vec2( 0.75, 0.25 ) * gg;",
+		"	vec4 clipPosition = vec4( ( vec3( screenPosition, depth ) - 0.5 ) * 2.0, 1.0 );",
 
-			"}",
+		"	clipPosition *= clipW; // unprojection.",
 
-			"return ( noise * 2.0  - 1.0 ) * noiseAmount;",
+		"	return ( cameraInverseProjectionMatrix * clipPosition ).xyz;",
 
 		"}",
 
-		"float readDepth( const in vec2 coord ) {",
+		"vec3 getViewNormal( const in vec2 screenPosition ) {",
 
-			"float cameraFarPlusNear = cameraFar + cameraNear;",
-			"float cameraFarMinusNear = cameraFar - cameraNear;",
-			"float cameraCoef = 2.0 * cameraNear;",
+		"	return unpackRGBToNormal( texture2D( tNormal, screenPosition ).xyz );",
 
-			"#ifdef USE_LOGDEPTHBUF",
+		"}",
 
-				"float logz = unpackRGBAToDepth( texture2D( tDepth, coord ) );",
-				"float w = pow(2.0, (logz / logDepthBufFC)) - 1.0;",
-				"float z = (logz / w) + 1.0;",
+		"void main() {",
 
-			"#else",
+		"	float depth = getDepth( vUv );",
+		"	float viewZ = getViewZ( depth );",
 
-				"float z = unpackRGBAToDepth( texture2D( tDepth, coord ) );",
+		"	vec3 viewPosition = getViewPosition( vUv, depth, viewZ );",
+		"	vec3 viewNormal = getViewNormal( vUv );",
 
-			"#endif",
+		" vec2 noiseScale = vec2( resolution.x / 4.0, resolution.y / 4.0 );",
+		"	vec3 random = texture2D( tNoise, vUv * noiseScale ).xyz;",
 
-			"return cameraCoef / ( cameraFarPlusNear - z * cameraFarMinusNear );",
+		// compute matrix used to reorient a kernel vector
 
+		"	vec3 tangent = normalize( random - viewNormal * dot( random, viewNormal ) );",
+		"	vec3 bitangent = cross( viewNormal, tangent );",
+		"	mat3 kernelMatrix = mat3( tangent, bitangent, viewNormal );",
 
-		"}",
+		" float occlusion = 0.0;",
 
-		"float compareDepths( const in float depth1, const in float depth2, inout int far ) {",
+		" for ( int i = 0; i < KERNEL_SIZE; i ++ ) {",
 
-			"float garea = 8.0;",                         // gauss bell width
-			"float diff = ( depth1 - depth2 ) * 100.0;",  // depth difference (0-100)
+		"		vec3 sampleVector = kernelMatrix * kernel[ i ];", // reorient sample vector in view space
+		"		vec3 samplePoint = viewPosition + ( sampleVector * kernelRadius );", // calculate sample point
 
-			// reduce left bell width to avoid self-shadowing
+		"		vec4 samplePointNDC = cameraProjectionMatrix * vec4( samplePoint, 1.0 );", // project point and calculate NDC
+		"		samplePointNDC /= samplePointNDC.w;",
 
-			"if ( diff < gDisplace ) {",
+		"		vec2 samplePointUv = samplePointNDC.xy * 0.5 + 0.5;", // compute uv coordinates
 
-				"garea = diffArea;",
+		"		float realDepth = getLinearDepth( samplePointUv );", // get linear depth from depth texture
+		"		float sampleDepth = viewZToOrthographicDepth( samplePoint.z, cameraNear, cameraFar );", // compute linear depth of the sample view Z value
+		"		float delta = sampleDepth - realDepth;",
 
-			"} else {",
+		"		if ( delta > minDistance && delta < maxDistance ) {", // if fragment is before sample point, increase occlusion
 
-				"far = 1;",
+		"			occlusion += 1.0;",
 
-			"}",
+		"		}",
 
-			"float dd = diff - gDisplace;",
-			"float gauss = pow( EULER, -2.0 * ( dd * dd ) / ( garea * garea ) );",
-			"return gauss;",
+		"	}",
 
-		"}",
+		"	occlusion = clamp( occlusion / float( KERNEL_SIZE ), 0.0, 1.0 );",
 
-		"float calcAO( float depth, float dw, float dh ) {",
+		"	gl_FragColor = vec4( vec3( 1.0 - occlusion ), 1.0 );",
 
-			"vec2 vv = vec2( dw, dh );",
+		"}"
 
-			"vec2 coord1 = vUv + radius * vv;",
-			"vec2 coord2 = vUv - radius * vv;",
+	].join( "\n" )
+
+};
 
-			"float temp1 = 0.0;",
-			"float temp2 = 0.0;",
+THREE.SSAODepthShader = {
 
-			"int far = 0;",
-			"temp1 = compareDepths( depth, readDepth( coord1 ), far );",
+	defines: {
+		"PERSPECTIVE_CAMERA": 1
+	},
 
-			// DEPTH EXTRAPOLATION
+	uniforms: {
 
-			"if ( far > 0 ) {",
+		"tDepth": { value: null },
+		"cameraNear": { value: null },
+		"cameraFar": { value: null },
 
-				"temp2 = compareDepths( readDepth( coord2 ), depth, far );",
-				"temp1 += ( 1.0 - temp1 ) * temp2;",
+	},
 
-			"}",
+	vertexShader: [
 
-			"return temp1;",
+		"varying vec2 vUv;",
+
+		"void main() {",
+
+		"	vUv = uv;",
+		"	gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );",
+
+		"}"
+
+	].join( "\n" ),
+
+	fragmentShader: [
+
+		"uniform sampler2D tDepth;",
+
+		"uniform float cameraNear;",
+		"uniform float cameraFar;",
+
+		"varying vec2 vUv;",
+
+		"#include <packing>",
+
+		"float getLinearDepth( const in vec2 screenPosition ) {",
+
+		"	#if PERSPECTIVE_CAMERA == 1",
+
+		"		float fragCoordZ = texture2D( tDepth, screenPosition ).x;",
+		"		float viewZ = perspectiveDepthToViewZ( fragCoordZ, cameraNear, cameraFar );",
+		"		return viewZToOrthographicDepth( viewZ, cameraNear, cameraFar );",
+
+		"	#else",
+
+		"		return texture2D( depthSampler, coord ).x;",
+
+		"	#endif",
 
 		"}",
 
 		"void main() {",
 
-			"vec2 noise = rand( vUv );",
-			"float depth = readDepth( vUv );",
+		"	float depth = getLinearDepth( vUv );",
+		"	gl_FragColor = vec4( vec3( 1.0 - depth ), 1.0 );",
+
+		"}"
+
+	].join( "\n" )
+
+};
 
-			"float tt = clamp( depth, aoClamp, 1.0 );",
+THREE.SSAOBlurShader = {
 
-			"float w = ( 1.0 / size.x ) / tt + ( noise.x * ( 1.0 - noise.x ) );",
-			"float h = ( 1.0 / size.y ) / tt + ( noise.y * ( 1.0 - noise.y ) );",
+	uniforms: {
 
-			"float ao = 0.0;",
+		"tDiffuse": { value: null },
+		"resolution": { value: new THREE.Vector2() }
+
+	},
 
-			"float dz = 1.0 / float( samples );",
-			"float l = 0.0;",
-			"float z = 1.0 - dz / 2.0;",
+	vertexShader: [
 
-			"for ( int i = 0; i <= samples; i ++ ) {",
+		"varying vec2 vUv;",
 
-				"float r = sqrt( 1.0 - z );",
+		"void main() {",
 
-				"float pw = cos( l ) * r;",
-				"float ph = sin( l ) * r;",
-				"ao += calcAO( depth, pw * w, ph * h );",
-				"z = z - dz;",
-				"l = l + DL;",
+		"	vUv = uv;",
+		"	gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );",
 
-			"}",
+		"}"
 
-			"ao /= float( samples );",
-			"ao = 1.0 - ao;",
+	].join( "\n" ),
+
+	fragmentShader: [
+
+		"uniform sampler2D tDiffuse;",
+
+		"uniform vec2 resolution;",
+
+		"varying vec2 vUv;",
+
+		"void main() {",
 
-			"vec3 color = texture2D( tDiffuse, vUv ).rgb;",
+		"	vec2 texelSize = ( 1.0 / resolution );",
+		"	float result = 0.0;",
 
-			"vec3 lumcoeff = vec3( 0.299, 0.587, 0.114 );",
-			"float lum = dot( color.rgb, lumcoeff );",
-			"vec3 luminance = vec3( lum );",
+		"	for ( int i = - 2; i <= 2; i ++ ) {",
 
-			"vec3 final = vec3( color * mix( vec3( ao ), vec3( 1.0 ), luminance * lumInfluence ) );",  // mix( color * ao, white, luminance )
+		"		for ( int j = - 2; j <= 2; j ++ ) {",
 
-			"if ( onlyAO ) {",
+		"			vec2 offset = ( vec2( float( i ), float( j ) ) ) * texelSize;",
+		"			result += texture2D( tDiffuse, vUv + offset ).r;",
 
-				"final = vec3( mix( vec3( ao ), vec3( 1.0 ), luminance * lumInfluence ) );",  // ambient occlusion only
+		"		}",
 
-			"}",
+		"	}",
 
-			"gl_FragColor = vec4( final, 1.0 );",
+		"	gl_FragColor = vec4( vec3( result / ( 5.0 * 5.0 ) ), 1.0 );",
 
 		"}"
 

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

@@ -186,6 +186,7 @@ THREE.BufferGeometryUtils = {
 
 	/**
 	 * @param  {Array<THREE.BufferGeometry>} geometries
+	 * @param  {Boolean} useGroups
 	 * @return {THREE.BufferGeometry}
 	 */
 	mergeBufferGeometries: function ( geometries, useGroups ) {

+ 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 );
-
-	}
-
-}

+ 3 - 3
examples/misc_boxselection.html

@@ -141,7 +141,7 @@
 			var selectionBox = new SelectionBox( camera, scene );
     		var helper = new SelectionHelper( selectionBox, renderer, "selectBox" );
 
-			document.addEventListener("mousedown", function ( e ) {
+			document.addEventListener("mousedown", function ( event ) {
 
 				for ( var item of selectionBox.collection ) {
 
@@ -155,7 +155,7 @@
 					 0.5 );
     		} );
 
-    		document.addEventListener( "mousemove", function ( e ) {
+    		document.addEventListener( "mousemove", function ( event ) {
 
 				if ( helper.isDown ) {
 
@@ -181,7 +181,7 @@
 
 			} );
 
-			document.addEventListener("mouseup", function (e) {
+			document.addEventListener("mouseup", function ( event ) {
 				
 				selectionBox.endPoint.set(
 					(event.clientX / window.innerWidth) * 2 - 1,

BIN
examples/models/gltf/Soldier.glb


File diff suppressed because it is too large
+ 0 - 0
examples/models/json/lightmap/lightmap.json


File diff suppressed because it is too large
+ 0 - 0
examples/models/json/platform/platform.json


File diff suppressed because it is too large
+ 0 - 0
examples/models/json/teapot-claraio.json


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


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


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


File diff suppressed because it is too large
+ 0 - 36
examples/models/skinned/marine/m4.js


File diff suppressed because it is too large
+ 0 - 10
examples/models/skinned/marine/marine_anims.json


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


File diff suppressed because it is too large
+ 0 - 10
examples/models/skinned/marine/marine_anims_all.json


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


File diff suppressed because it is too large
+ 0 - 10
examples/models/skinned/marine/marine_anims_core.json


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