Mr.doob 6 years ago
parent
commit
ea61255137
100 changed files with 1939 additions and 1440 deletions
  1. 32 1
      build/three.js
  2. 161 396
      build/three.min.js
  3. 32 1
      build/three.module.js
  4. 5 0
      docs/api/en/animation/AnimationClip.html
  5. 5 0
      docs/api/en/animation/KeyframeTrack.html
  6. 8 7
      docs/api/en/core/Object3D.html
  7. 1 1
      docs/api/en/loaders/CompressedTextureLoader.html
  8. 2 2
      docs/api/en/loaders/CubeTextureLoader.html
  9. 1 1
      docs/api/en/loaders/DataTextureLoader.html
  10. 4 4
      docs/api/en/loaders/FileLoader.html
  11. 1 1
      docs/api/en/loaders/FontLoader.html
  12. 1 1
      docs/api/en/loaders/ImageLoader.html
  13. 1 1
      docs/api/en/loaders/MaterialLoader.html
  14. 0 9
      docs/api/en/math/Box3.html
  15. 1 1
      docs/api/en/math/Spherical.html
  16. 3 3
      docs/api/en/objects/SkinnedMesh.html
  17. 49 0
      docs/api/en/renderers/WebGLMultisampleRenderTarget.html
  18. 5 0
      docs/api/en/scenes/Scene.html
  19. 3 0
      docs/api/zh/animation/AnimationClip.html
  20. 6 0
      docs/api/zh/animation/AnimationUtils.html
  21. 3 0
      docs/api/zh/animation/KeyframeTrack.html
  22. 1 1
      docs/api/zh/audio/Audio.html
  23. 3 11
      docs/api/zh/math/Box3.html
  24. 7 7
      docs/api/zh/math/Cylindrical.html
  25. 2 2
      docs/api/zh/math/Euler.html
  26. 16 19
      docs/api/zh/math/Spherical.html
  27. 117 115
      docs/api/zh/math/Vector2.html
  28. 136 138
      docs/api/zh/math/Vector3.html
  29. 111 111
      docs/api/zh/math/Vector4.html
  30. 7 7
      docs/api/zh/objects/SkinnedMesh.html
  31. 46 0
      docs/api/zh/renderers/WebGLMultisampleRenderTarget.html
  32. 5 0
      docs/api/zh/scenes/Scene.html
  33. 13 0
      docs/examples/exporters/GLTFExporter.html
  34. 6 3
      docs/examples/loaders/GLTFLoader.html
  35. 28 0
      docs/examples/utils/BufferGeometryUtils.html
  36. 15 0
      docs/index.html
  37. 2 0
      docs/list.js
  38. 2 0
      docs/manual/en/introduction/How-to-use-WebGL2.html
  39. 6 2
      docs/manual/en/introduction/Useful-links.html
  40. 11 9
      docs/manual/en/introduction/WebGL-compatibility-check.html
  41. 7 7
      docs/manual/zh/introduction/Creating-a-scene.html
  42. 2 2
      docs/manual/zh/introduction/How-to-run-things-locally.html
  43. 2 0
      docs/manual/zh/introduction/How-to-use-WebGL2.html
  44. 2 2
      docs/manual/zh/introduction/Useful-links.html
  45. 8 0
      docs/scenes/js/geometry.js
  46. 17 66
      docs/scenes/js/material.js
  47. 3 10
      docs/scenes/material-browser.html
  48. 6 6
      editor/examples/arkanoid.app.json
  49. 4 4
      editor/examples/camera.app.json
  50. 1 1
      editor/examples/particles.app.json
  51. 4 4
      editor/examples/pong.app.json
  52. 1 1
      editor/examples/shaders.app.json
  53. 1 1
      editor/js/Menubar.Add.js
  54. 1 1
      editor/js/libs/three.html.js
  55. 2 0
      examples/files.js
  56. 1 1
      examples/js/Ocean.js
  57. 0 4
      examples/js/ShaderSkin.js
  58. 87 45
      examples/js/controls/FirstPersonControls.js
  59. 11 0
      examples/js/controls/OrbitControls.js
  60. 51 49
      examples/js/controls/TransformControls.js
  61. 20 6
      examples/js/exporters/ColladaExporter.js
  62. 336 48
      examples/js/exporters/GLTFExporter.js
  63. 105 100
      examples/js/interactive/SelectionBox.js
  64. 60 50
      examples/js/interactive/SelectionHelper.js
  65. 1 1
      examples/js/loaders/ColladaLoader.js
  66. 9 4
      examples/js/loaders/GLTFLoader.js
  67. 1 0
      examples/js/nodes/Nodes.js
  68. 2 0
      examples/js/nodes/THREE.Nodes.js
  69. 2 2
      examples/js/nodes/accessors/CameraNode.js
  70. 1 1
      examples/js/nodes/accessors/NormalNode.js
  71. 1 1
      examples/js/nodes/accessors/PositionNode.js
  72. 1 1
      examples/js/nodes/core/FunctionNode.js
  73. 12 4
      examples/js/nodes/core/InputNode.js
  74. 28 18
      examples/js/nodes/core/NodeBuilder.js
  75. 23 9
      examples/js/nodes/core/TempNode.js
  76. 51 0
      examples/js/nodes/inputs/BoolNode.js
  77. 1 1
      examples/js/nodes/inputs/ScreenNode.js
  78. 1 0
      examples/js/nodes/materials/PhongNodeMaterial.js
  79. 1 0
      examples/js/nodes/materials/SpriteNodeMaterial.js
  80. 1 0
      examples/js/nodes/materials/StandardNodeMaterial.js
  81. 21 2
      examples/js/nodes/materials/nodes/PhongNode.js
  82. 23 6
      examples/js/nodes/materials/nodes/SpriteNode.js
  83. 22 3
      examples/js/nodes/materials/nodes/StandardNode.js
  84. 35 16
      examples/js/nodes/math/CondNode.js
  85. 2 2
      examples/js/nodes/utils/ColorSpaceNode.js
  86. 3 3
      examples/js/nodes/utils/TimerNode.js
  87. 1 1
      examples/js/nodes/utils/VelocityNode.js
  88. 37 37
      examples/js/objects/Fire.js
  89. 9 9
      examples/js/objects/Lensflare.js
  90. 3 4
      examples/js/objects/Reflector.js
  91. 3 3
      examples/js/objects/Refractor.js
  92. 6 6
      examples/js/objects/Sky.js
  93. 22 22
      examples/js/objects/Water.js
  94. 14 14
      examples/js/objects/Water2.js
  95. 6 2
      examples/js/offscreen/scene.js
  96. 2 2
      examples/js/postprocessing/AdaptiveToneMappingPass.js
  97. 1 1
      examples/js/postprocessing/BloomPass.js
  98. 1 1
      examples/js/postprocessing/BokehPass.js
  99. 1 1
      examples/js/postprocessing/ClearPass.js
  100. 1 1
      examples/js/postprocessing/CubeTexturePass.js

File diff suppressed because it is too large
+ 32 - 1
build/three.js


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


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


+ 5 - 0
docs/api/en/animation/AnimationClip.html

@@ -66,6 +66,11 @@
 		<h2>Methods</h2>
 
 
+		<h3>[method:AnimationClip clone]()</h3>
+		<p>
+			Returns a copy of this clip.
+		</p>
+
 		<h3>[method:this optimize]()</h3>
 		<p>
 			Optimizes each track by removing equivalent sequential keys (which are common in morph target

+ 5 - 0
docs/api/en/animation/KeyframeTrack.html

@@ -160,6 +160,11 @@
 		<h2>Methods</h2>
 
 
+		<h3>[method:KeyframeTrack clone]()</h3>
+		<p>
+			Returns a copy of this track.
+		</p>
+
 		<h3>[method:null createInterpolant]()</h3>
 		<p>
 			Creates a [page:LinearInterpolant LinearInterpolant], [page:CubicInterpolant CubicInterpolant]

+ 8 - 7
docs/api/en/core/Object3D.html

@@ -107,14 +107,14 @@
 		On the other hand the translation part of the modelViewMatrix is not relevant for the calculation of normals. Thus a Matrix3 is sufficient.
 		</p>
 
-		<h3>[property:function onAfterRender]</h3>
+		<h3>[property:Function onAfterRender]</h3>
 		<p>
 		An optional callback that is executed immediately after the Object3D is rendered.
 		This function is called with the following parameters: renderer, scene, camera, geometry,
 		material, group.
 		</p>
 
-		<h3>[property:function onBeforeRender]</h3>
+		<h3>[property:Function onBeforeRender]</h3>
 		<p>
 		An optional callback that is executed immediately before the Object3D is rendered.
 		This function is called with the following parameters: renderer, scene, camera, geometry,
@@ -137,7 +137,8 @@
 		<h3>[property:Number renderOrder]</h3>
 		<p>
 		This value allows the default rendering order of [link:https://en.wikipedia.org/wiki/Scene_graph scene graph]
-		objects to be overridden although opaque and transparent objects remain sorted independently.
+		objects to be overridden although opaque and transparent objects remain sorted independently. When this property
+		is set for an instance of [page:Group Group], all descendants objects will be sorted and rendered together.
 		Sorting is from lowest to highest renderOrder. Default value is *0*.
 		</p>
 
@@ -157,7 +158,7 @@
 		Default is [page:Object3D.DefaultUp] - that is, ( 0, 1, 0 ).
 		</p>
 
-		<h3>[property:object userData]</h3>
+		<h3>[property:Object userData]</h3>
 		<p>
 		An object that can be used to store custom data about the Object3D. It should not hold
 		references to functions as these will not be cloned.
@@ -202,7 +203,7 @@
 
 		<h3>[page:EventDispatcher EventDispatcher] methods are available on this class.</h3>
 
-		<h3>[method:null add]( [param:Object3D object], ... )</h3>
+		<h3>[method:this add]( [param:Object3D object], ... )</h3>
 		<p>
 		Adds *object* as child of this object. An arbitrary number of objects may be added. Any current parent on an
 		object passed in here will be removed, since an object can have at most one parent.<br /><br />
@@ -213,7 +214,7 @@
 		<h3>[method:null applyMatrix]( [param:Matrix4 matrix] )</h3>
 		<p>Applies the matrix transform to the object and updates the object's position, rotation and scale.</p>
 
-		<h3>[method:Object3D applyQuaternion]( [param:Quaternion quaternion] )</h3>
+		<h3>[method:this applyQuaternion]( [param:Quaternion quaternion] )</h3>
 		<p>Applies the rotation represented by the quaternion to the object.</p>
 
 		<h3>[method:Object3D clone]( [param:Boolean recursive] )</h3>
@@ -309,7 +310,7 @@
 		to use raycasting.
 		</p>
 
-		<h3>[method:null remove]( [param:Object3D object], ... )</h3>
+		<h3>[method:this remove]( [param:Object3D object], ... )</h3>
 		<p>
 		Removes *object* as child of this object. An arbitrary number of objects may be removed.
 		</p>

+ 1 - 1
docs/api/en/loaders/CompressedTextureLoader.html

@@ -48,7 +48,7 @@
 
 		<h2>Methods</h2>
 
-		<h3>[method:null load]( [param:String url], [param:Function onLoad], [param:Function onProgress], [param:Function onError] )</h3>
+		<h3>[method:CompressedTexture 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 />

+ 2 - 2
docs/api/en/loaders/CubeTextureLoader.html

@@ -70,7 +70,7 @@ scene.background = new THREE.CubeTextureLoader()
 
 		<h2>Methods</h2>
 
-		<h3>[method:null load]( [param:String urls], [param:Function onLoad], [param:Function onProgress], [param:Function onError] )</h3>
+		<h3>[method:CubeTexture load]( [param:String urls], [param:Function onLoad], [param:Function onProgress], [param:Function onError] )</h3>
 		<p>
 		[page:String urls] — array of 6 urls to images, one for each side of the CubeTexture.
 		The urls should be specified in the following order: pos-x, neg-x, pos-y, neg-y, pos-z, neg-z.
@@ -83,7 +83,7 @@ scene.background = new THREE.CubeTextureLoader()
 		[page:Function onError] — Will be called when load errors.<br />
 		</p>
 		<p>
-		Begin loading from url and pass the loaded [page:Texture texture] to onLoad.
+		Begin loading from url and pass the loaded [page:CubeTexture texture] to onLoad.
 		</p>
 
 		<h3>[method:null setCrossOrigin]( [param:String value] )</h3>

+ 1 - 1
docs/api/en/loaders/DataTextureLoader.html

@@ -44,7 +44,7 @@
 
 		<h2>Methods</h2>
 
-		<h3>[method:null load]( [param:String url], [param:Function onLoad], [param:Function onProgress], [param:Function onError] )</h3>
+		<h3>[method:DataTexture 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 />

+ 4 - 4
docs/api/en/loaders/FileLoader.html

@@ -76,7 +76,7 @@
 		<h3>[property:String path]</h3>
 		<p>The base path from which files will be loaded. See [page:.setPath]. Default is *undefined*.</p>
 
-		<h3>[property:object requestHeader]</h3>
+		<h3>[property:Object requestHeader]</h3>
 		<p>The [link:https://developer.mozilla.org/en-US/docs/Glossary/Request_header request header] used in HTTP request. See [page:.setRequestHeader]. Default is *undefined*.</p>
 
 		<h3>[property:String responseType]</h3>
@@ -91,7 +91,7 @@
 
 		<h2>Methods</h2>
 
-		<h3>[method:null load]( [param:String url], [param:Function onLoad], [param:Function onProgress], [param:Function onError] )</h3>
+		<h3>[method:XMLHttpRequest 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 />
@@ -115,7 +115,7 @@
 			you are loading many models from the same directory.
 		</p>
 
-		<h3>[method:FileLoader setRequestHeader]( [param:object requestHeader] )</h3>
+		<h3>[method:FileLoader setRequestHeader]( [param:Object requestHeader] )</h3>
 		<p>
 			[page:object requestHeader] - key: The name of the header whose value is to be set. value: The value to set as the body of the header.<br /><br />
 
@@ -125,7 +125,7 @@
 		<h3>[method:FileLoader setResponseType]( [param:String responseType] )</h3>
 		<p>
 			Change the response type. Valid values are:<br />
-			[page:String text] or empty string (default) - returns the data as [page:String string].<br />
+			[page:String text] or empty string (default) - returns the data as [page:String String].<br />
 			[page:String arraybuffer] - loads the data into a [link:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/ArrayBuffer ArrayBuffer] and returns that.<br />
 			[page:String blob] - returns the data as a [link:https://developer.mozilla.org/en/docs/Web/API/Blob Blob].<br />
 			[page:String document] - parses the file using the [link:https://developer.mozilla.org/en-US/docs/Web/API/DOMParser DOMParser].<br />

+ 1 - 1
docs/api/en/loaders/FontLoader.html

@@ -73,7 +73,7 @@
 		<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 [page:Texture texture].<br />
+		[page:Function onLoad] — Will be called when load completes. The argument will be the loaded [page:Font font].<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 /><br />
 

+ 1 - 1
docs/api/en/loaders/ImageLoader.html

@@ -82,7 +82,7 @@
 
 		<h2>Methods</h2>
 
-		<h3>[method:null load]( [param:String url], [param:Function onLoad], [param:Function onProgress], [param:Function onError] )</h3>
+		<h3>[method:HTMLImageElement 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 />

+ 1 - 1
docs/api/en/loaders/MaterialLoader.html

@@ -74,7 +74,7 @@
 		[page:Function onProgress] — Will be called while load progresses. The argument will be the progress event.<br />
 		[page:Function onError] — Will be called when load errors.<br /><br />
 
-		Begin loading from url and return the [page:Material] object that will contain the data.
+		Begin loading from url.
 		</p>
 
 		<h3>[method:Material parse]( [param:Object json] )</h3>

+ 0 - 9
docs/api/en/math/Box3.html

@@ -244,15 +244,6 @@
 		Sets the upper and lower bounds of this box to include all of the data in [page:BufferAttribute attribute].
 		</p>
 
-		<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 />
-
-		Centers this box on [page:Vector3 center] and sets this box's width and height to the values specified
-		in [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>

+ 1 - 1
docs/api/en/math/Spherical.html

@@ -40,7 +40,7 @@
 
 		<h3>[method:Spherical clone]()</h3>
 		<p>
-		Returns a new plane with the same [page:.radius radius], [page:.phi phi]
+		Returns a new spherical with the same [page:.radius radius], [page:.phi phi]
 		and [page:.theta theta] properties as this one.
 		</p>
 

+ 3 - 3
docs/api/en/objects/SkinnedMesh.html

@@ -91,8 +91,8 @@
 		<h2>Constructor</h2>
 		<h3>[name]( [param:BufferGeometry geometry], [param:Material material] )</h3>
 		<p>
-    [page:Geometry geometry] - an instance of [page:BufferGeometry].<br />
-    [page:Material material] - (optional) an instance of [page:Material]. Default is a new [page:MeshBasicMaterial].
+		[page:Geometry geometry] - an instance of [page:BufferGeometry].<br />
+		[page:Material material] - (optional) an instance of [page:Material]. Default is a new [page:MeshBasicMaterial].
 		</p>
 
 
@@ -128,7 +128,7 @@
 
 		<h3>[property:Skeleton skeleton]</h3>
 		<p>
-		[page:Skeleton] representing the bone hierachy of the skinned mesh.
+		[page:Skeleton] representing the bone hierarchy of the skinned mesh.
 		</p>
 
 

+ 49 - 0
docs/api/en/renderers/WebGLMultisampleRenderTarget.html

@@ -0,0 +1,49 @@
+<!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 special render target that can be used to utilize multi-sampled renderbuffers.
+			Heads up: [name] can only be used with a WebGL 2 rendering context.
+		</p>
+
+
+		<h2>Constructor</h2>
+
+
+		<h3>[name]([param:Number width], [param:Number height], [param:Object options])</h3>
+
+		<p>
+		[page:Float width] - The width of the render target. <br />
+		[page:Float height] - The height of the render target.<br />
+		[page:Object options] - (optional) object that holds texture parameters for an auto-generated target
+		texture and depthBuffer/stencilBuffer booleans.
+		</p>
+
+		<h2>Properties</h2>
+
+		<h3>[property:number samples]</h3>
+		<p>
+		Specifies the number of samples to be used for the renderbuffer storage. However, the maximum supported
+		size for multisampling is platform dependent and defined via *gl.MAX_SAMPLES*.
+		</p>
+
+		<p>[page:WebGLRenderTarget WebGLRenderTarget] properties are available on this class.</p>
+
+		<h2>Methods</h2>
+
+		<p>[page:WebGLRenderTarget WebGLRenderTarget] methods are available on this class.</p>
+
+		<h2>Source</h2>
+
+		[link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js]
+	</body>
+</html>

+ 5 - 0
docs/api/en/scenes/Scene.html

@@ -51,6 +51,11 @@
 		Return the scene data in JSON format.
 		</p>
 
+		<h3>[method:null dispose]()</h3>
+		<p>
+		Clears scene related data internally cached by [page:WebGLRenderer].
+		</p>
+
 		<h2>Source</h2>
 
 		[link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js]

+ 3 - 0
docs/api/zh/animation/AnimationClip.html

@@ -62,6 +62,9 @@
 		<h2>方法</h2>
 
 
+		<h3>[method:AnimationClip clone]()</h3>
+		<p></p>
+
 		<h3>[method:this optimize]()</h3>
 		<p>
             通过移除等效的顺序键(在变形目标序列中很常见)来优化每一个轨道

+ 6 - 0
docs/api/zh/animation/AnimationUtils.html

@@ -38,12 +38,18 @@
             返回一个数组,时间和值可以根据此数组排序。
 		</p>
 
+		<h3>[method:Number insertKeyframe]( [param:KeyframeTrack track], [param:Number time] )</h3>
+		<p></p>
+
 		<h3>[method:Boolean isTypedArray]( object )</h3>
 		<p>
             如果该对象是类型化数组,返回*true*
 
 		</p>
 
+		<h3>[method:AnimationClip mergeMorphTargetTracks]( [param:AnimationClip clip], [param:Object3D root] )</h3>
+		<p></p>
+
 		<h3>[method:Array sortedArray]( values, stride, order )</h3>
 		<p>
             将[page:AnimationUtils.getKeyframeOrder getKeyframeOrder]方法返回的数组排序。

+ 3 - 0
docs/api/zh/animation/KeyframeTrack.html

@@ -137,6 +137,9 @@
 		<h2>方法</h2>
 
 
+		<h3>[method:KeyframeTrack clone]()</h3>
+		<p></p>
+
 		<h3>[method:null createInterpolant]()</h3>
 		<p>
 			根据传入构造器中的插值类型参数,创建线性插值([page:LinearInterpolant LinearInterpolant]),立方插值([page:CubicInterpolant CubicInterpolant])或离散插值

+ 1 - 1
docs/api/zh/audio/Audio.html

@@ -63,7 +63,7 @@
 		<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>
+		<p>修改音高,以音分为单位。 +/- 100为一个半音, +/- 1200为一个八度。默认值为0。</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>

+ 3 - 11
docs/api/zh/math/Box3.html

@@ -34,7 +34,7 @@
 		<h3>[property:Boolean isBox3]</h3>
 		<p>
 			用于检测当前对象或者派生类对象是否是Box3。默认为 *true*。<br /><br />
-			
+
 			不应该修改这个值,因为内部使用该属性做了优化的任务。
 		</p>
 
@@ -57,7 +57,7 @@
 		<h3>[method:Box3 applyMatrix4]( [param:Matrix4 matrix] )</h3>
 		<p>
 		[page:Matrix4 matrix] - 要应用的 [page:Matrix4] <br /><br />
-		
+
 		使用传入的矩阵变换Box3(包围盒8个顶点都会乘以这个变换矩阵)。
 		</p>
 
@@ -219,7 +219,7 @@
 		[page:Vector3 min] - [page:Vector3] 表示下边界每个纬度(x,y,z)的值。<br />
 		[page:Vector3 max] - [page:Vector3] 表示上边界每个纬度(x,y,z)的值。<br /><br />
 
-		设置包围盒上下边界每个纬度(x,y,z)的值。 
+		设置包围盒上下边界每个纬度(x,y,z)的值。
 		</p>
 
 		<h3>[method:Box3 setFromArray]( [param:Array array] ) [param:Box3 this]</h3>
@@ -236,14 +236,6 @@
 		设置此包围盒的上边界和下边界,以包含 [page:BufferAttribute attribute] 中的所有位置数据。
 		</p>
 
-<!--	<h3>[method:Box3 setFromCenterAndSize]( [param:Vector3 center], [param:Vector3 size] )</h3>
-		<p>
-		[page:Vector3 center] - 包围盒的中心位置 ([page:Vector3]). <br>
-		[page:Vector3 size] - 需要设置包围盒x,y,z的分量 ([page:Vector3]).<br /><br />
-
-		将包围盒的中心点设为 [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], - 包围盒所要设置的中心位置。 <br>

+ 7 - 7
docs/api/zh/math/Cylindrical.html

@@ -8,10 +8,10 @@
 		<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].
+			一个点的[link:https://en.wikipedia.org/wiki/Cylindrical_coordinate_system cylindrical coordinates](圆柱坐标)。
 		</p>
 
 
@@ -39,12 +39,12 @@
 
 		<h3>[method:Cylindrical clone]()</h3>
 		<p>
-			返回一个与当前拥有相同 [page:.radius radius], [page:.theta theta] 和 [page:.y y] 属性的圆柱
+			返回一个与当前拥有相同 [page:.radius radius], [page:.theta theta] 和 [page:.y y] 属性的圆柱坐标
 		</p>
 
 		<h3>[method:Cylindrical copy]( [param:Cylindrical other] )</h3>
 		<p>
-			将传入的圆柱对象的 [page:.radius radius], [page:.theta theta] 和 [page:.y y] 属性赋给当前对象。
+			将传入的圆柱坐标对象的 [page:.radius radius], [page:.theta theta] 和 [page:.y y] 属性赋给当前对象。
 		</p>
 
 		<h3>[method:Cylindrical set]( [param:Float radius], [param:Float theta], [param:Float y] )</h3>
@@ -53,15 +53,15 @@
 
 		<h3>[method:Cylindrical setFromVector3]( [param:Vector3 vec3] )</h3>
 		<p>
-			从 [page:Vector3 Vector3] 中取x,y,z,并调用setFromCartesianCoords来设置圆柱
+			从 [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>
-			使用笛卡尔坐标来设置该圆柱体的 [page:.radius radius], [page:.theta theta]
-			and [page:.y y] 属性值。
+			使用笛卡尔坐标来设置该圆柱坐标中 [page:.radius radius], [page:.theta theta]
+			以及 [page:.y y] 的属性值。
 		</p>
 
 		<h2>源码(Source)</h2>

+ 2 - 2
docs/api/zh/math/Euler.html

@@ -8,7 +8,7 @@
 		<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/Euler_angles Euler] 的类。<br /><br />
@@ -51,7 +51,7 @@
 			绕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轴相同),
+			这意味着旋转是在<em>本地</em>坐标系下进行的。也就是说,对于“XYZ”顺序,首先是围绕local-X轴旋转(与world- x轴相同),
 			然后是local-Y(现在可能与world y轴不同),然后是local-Z(可能与world z轴不同)。<br /><br />
 
 			如果order值被改变,[page:.onChangeCallback onChangeCallback] 会被调用。

+ 16 - 19
docs/api/zh/math/Spherical.html

@@ -8,18 +8,18 @@
 		<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/Spherical_coordinate_system spherical coordinates].</p>
+		<p class="desc">一个点的[link:https://en.wikipedia.org/wiki/Spherical_coordinate_system spherical coordinates](球坐标)。</p>
 
 
-		<h2>Constructor</h2>
+		<h2>构造函数</h2>
 
 
 		<h3>[name]( [param:Float radius], [param:Float phi], [param:Float theta] )</h3>
 		<p>
-		[page:Float radius] - the radius, or the [link:https://en.wikipedia.org/wiki/Euclidean_distance Euclidean distance]
-		(straight-line distance) from the point to the origin. Default is *1.0*.<br />
+		[page:Float radius] - 半径值,或者说从该点到原点的
+		[link:https://en.wikipedia.org/wiki/Euclidean_distance Euclidean distance](欧几里得距离,即直线距离)。默认值为*1.0*。<br />
 		[page:Float phi] - polar angle from the y (up) axis. Default is *0*.<br />
 		[page:Float theta] - equator angle around the y (up) axis. Default is *0*.<br /><br />
 
@@ -27,7 +27,7 @@
 		</p>
 
 
-		<h2>Properties</h2>
+		<h2>属性</h2>
 
 		<h3>[property:Float radius]</h3>
 
@@ -36,42 +36,39 @@
 		<h3>[property:Float theta]</h3>
 
 
-		<h2>Methods</h2>
+		<h2>方法</h2>
 
 		<h3>[method:Spherical clone]()</h3>
 		<p>
-		Returns a new plane with the same [page:.radius radius], [page:.phi phi]
-		and [page:.theta theta] properties as this one.
+		返回一个新的球坐标,新的球坐标与该球坐标具有相同的
+		[page:.radius radius]、[page:.phi phi]和[page:.theta theta]。
 		</p>
 
 		<h3>[method:Spherical copy]( [param:Spherical s] )</h3>
 		<p>
-			Copies the values of the passed Spherical's [page:.radius radius], [page:.phi phi]
-			and [page:.theta theta] properties to this spherical.
+		复制所传入的球坐标的[page:.radius radius]、
+		[page:.phi phi] 和[page:.theta theta]属性到该球坐标中。
 		</p>
 
 		<h3>[method:Spherical makeSafe]()</h3>
 		<p>
-		Restricts the polar angle [page:.phi phi] to be between 0.000001 and pi - 0.000001.
+		将极角 [page:.phi phi] 的值限制在0.000001 和 pi - 0.000001 之间。
 		</p>
 
 		<h3>[method:Spherical set]( [param:Float radius], [param:Float phi], [param:Float theta] )</h3>
-		<p>Sets values of this spherical's [page:.radius radius], [page:.phi phi]
-		and [page:.theta theta] properties.</p>
+		<p>设置球坐标中[page:.radius radius]、[page:.phi phi] 和 [page:.theta theta] 属性的值。</p>
 
 		<h3>[method:Spherical setFromVector3]( [param:Vector3 vec3] )</h3>
 		<p>
-			Sets values of this spherical's [page:.radius radius], [page:.phi phi]
-			and [page:.theta theta] properties from the [page:Vector3 Vector3].
+			从[page:Vector3 Vector3]中设置球坐标的[page:.radius radius]、[page:.phi phi]和[page:.theta theta]值。
 		</p>
 
 		<h3>[method:Spherical setFromCartesianCoords]( [param:Float x], [param:Float y], [param:Float z] )</h3>
 		<p>
-			Sets values of this spherical's [page:.radius radius], [page:.phi phi]
-			and [page:.theta theta] properties from Cartesian coordinates.
+			从笛卡尔坐标系中设置球坐标的[page:.radius radius]、[page:.phi phi]和[page:.theta theta]值。
 		</p>
 
-		<h2>Source</h2>
+		<h2>源代码</h2>
 
 		[link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js]
 	</body>

+ 117 - 115
docs/api/zh/math/Vector2.html

@@ -8,36 +8,34 @@
 		<link type="text/css" rel="stylesheet" href="page.css" />
 	</head>
 	<body>
-		<h1>[name]</h1>
+		<h1>二维向量([name]</h1>
 
 		<p class="desc">
-			Class representing a 2D [link:https://en.wikipedia.org/wiki/Vector_space vector].
+			表示2D [link:https://en.wikipedia.org/wiki/Vector_space vector](二维向量)的类。
 
-			A 2D vector is an ordered pair of numbers (labeled x and y), which can be used to
-			represent a number of things, such as:
+			一个二维向量是一对有顺序的数字(标记为x和y),可用来表示很多事物,例如:
 		</p>
 
 		<ul>
 			<li>
-				A point in 2D space (i.e. a position on a plane).
+				一个位于二维空间中的点(例如一个在平面上的点)。
 			</li>
 			<li>
-				A direction and length across a plane. In three.js the length will always be the
-				[link:https://en.wikipedia.org/wiki/Euclidean_distance Euclidean distance]
-				(straight-line distance) from (0, 0) to (x, y) and the direction is also
-				measured from (0, 0) towards (x, y).
+				一个在平面上的方向与长度的定义。在three.js中,长度总是从(0, 0)到(x, y)的
+				[link:https://en.wikipedia.org/wiki/Euclidean_distance Euclidean distance](欧几里德距离,即直线距离),
+				方向也是从(0, 0)到(x, y)的方向。
 			</li>
 			<li>
-				Any arbitrary ordered pair of numbers.
+				任意的、有顺序的一对数字。
 			</li>
 		</ul>
 
 		<p>
-			There are other things a 2D vector can be used to represent, such as momentum
-			vectors, complex numbers and so on,	however these are the most common uses in three.js.
+			其他的一些事物也可以使用二维向量进行表示,比如说动量矢量、复数等等;但以上这些是它在three.js中的常用用途。
 		</p>
 
-		<h2>Example</h2>
+		<h2>示例</h2>
+
 
 		<code>
 		var a = new THREE.Vector2( 0, 1 );
@@ -49,297 +47,301 @@
 		</code>
 
 
-		<h2>Constructor</h2>
+		<h2>构造函数</h2>
 
 		<h3>[name]( [param:Float x], [param:Float y] )</h3>
 		<p>
-		[page:Float x] - the x value of the vector. Default is *0*.<br />
-		[page:Float y] -  the y value of the vector. Default is *0*.<br /><br />
+		[page:Float x] - 向量的x值,默认为*0*。<br />
+		[page:Float y] - 向量的y值,默认为*0*。<br /><br />
 
-		Creates a new [name].
+		创建一个新的[name]。
 		</p>
 
 
-		<h2>Properties</h2>
+		<h2>属性</h2>
 
 		<h3>[property:Boolean isVector2]</h3>
 		<p>
-			Used to check whether this or derived classes are Vector2s. Default is *true*.<br /><br />
+			用于测试这个类或者派生类是否为Vector2,默认为*true*。<br /><br />
 
-			You should not change this, as it is used internally for optimisation.
+			你不应当对这个属性进行改变,因为它在内部使用,以用于优化。
 		</p>
 
 		<h3>[property:Float height]</h3>
-		<p>Alias for [page:.y y].</p>
+		<p>[page:.y y]的别名。</p>
 
 		<h3>[property:Float width]</h3>
-		<p>Alias for [page:.x x].</p>
+		<p>[page:.x x]的别名。</p>
 
 		<h3>[property:Float x]</h3>
 
 		<h3>[property:Float y]</h3>
 
 
-		<h2>Methods</h2>
+		<h2>方法</h2>
 
 		<h3>[method:this add]( [param:Vector2 v] )</h3>
-		<p>Adds [page:Vector2 v] to this vector.</p>
+		<p>将传入的向量[page:Vector2 v]和这个向量相加。</p>
 
 		<h3>[method:this addScalar]( [param:Float s] )</h3>
-		<p>Adds the scalar value [page:Float s] to this vector's [page:.x x] and [page:.y y] values.</p>
+		<p>将传入的标量[page:Float s]和这个向量的[page:.x x]值、[page:.y y]值相加。</p>
 
 		<h3>[method:this addScaledVector]( [param:Vector2 v], [param:Float s] )</h3>
-		<p>Adds the multiple of [page:Vector2 v] and [page:Float s] to this vector.</p>
+		<p>将所传入的[page:Vector2 v]与[page:Float s]相乘所得乘积和这个向量相加。</p>
 
 		<h3>[method:this addVectors]( [param:Vector2 a], [param:Vector2 b] )</h3>
-		<p>Sets this vector to [page:Vector2 a] + [page:Vector2 b].</p>
+		<p>将该向量设置为 [page:Vector2 a] + [page:Vector2 b]。</p>
 
 		<h3>[method:Float angle]()</h3>
 		<p>
-		Computes the angle in radians of this vector with respect to the positive x-axis.
+			计算该向量相对于x轴正方向的弧度角度。
 		</p>
 
 		<h3>[method:this applyMatrix3]( [param:Matrix3 m] )</h3>
 		<p>
-		Multiplies this vector (with an implicit 1 as the 3rd component) by m.
+			将该向量乘以三阶矩阵m(第三个值隐式地为1)。
 		</p>
 
 		<h3>[method:this ceil]()</h3>
 		<p>
-		The [page:.x x] and [page:.y y] components of the vector are rounded up to the nearest integer value.
+			向量中的[page:.x x]分量和[page:.y y]分量向上取整为最接近的整数值。
 		</p>
 
 		<h3>[method:this clamp]( [param:Vector2 min], [param:Vector2 max] )</h3>
 		<p>
-		[page:Vector2 min] - the minimum x and y values.<br />
-		[page:Vector2 max] - the maximum x and y values in the desired range<br /><br />
+		[page:Vector2 min] - 在限制范围内,x和y的最小值。<br />
+		[page:Vector2 max] - 在限制范围内,x和y的最大值。<br /><br />
+
+		如果该向量的x值或y值大于限制范围内最大x值或y值,则该值将会被所对应的值取代。<br /><br />
+		如果该向量的x值或y值小于限制范围内最小x值或y值,则该值将会被所对应的值取代。
 
-		If this vector's x or y value is greater than the max vector's x or y value, it is replaced by the corresponding value. <br /><br />
-		If this vector's x or y value is less than the min vector's x or y value, it is replaced by the corresponding value.
 		</p>
 
 		<h3>[method:this clampLength]( [param:Float min], [param:Float max] )</h3>
 		<p>
-		[page:Float min] - the minimum value the length will be clamped to <br />
-		[page:Float max] - the maximum value the length will be clamped to<br /><br />
+		[page:Float min] - 长度将被限制为的最小值 <br />
+		[page:Float max] - 长度将被限制为的最大值<br /><br />
+
+		如果向量长度大于最大值,则它将会被最大值所取代。<br /><br />
+		如果向量长度小于最小值,则它将会被最小值所取代。
 
-		If this vector's length is greater than the max value, it is replaced by the max value. <br /><br />
-		If this vector's length is less than the min value, it is replaced by the min value.
 		</p>
 
 		<h3>[method:this clampScalar]( [param:Float min], [param:Float max] )</h3>
 		<p>
-		[page:Float min] - the minimum value the components will be clamped to <br />
-		[page:Float max] - the maximum value the components will be clamped to<br /><br />
+		[page:Float min] - 分量将被限制为的最小值 <br />
+		[page:Float max] - 分量将被限制为的最大值<br /><br />
+
+		如果该向量的x值或y值大于最大值,则它们将被最大值所取代。<br /><br />
+		如果该向量的x值或y值小于最小值,则它们将被最小值所取代。
 
-		If this vector's x or y values are greater than the max value, they are replaced by the max value. <br /><br />
-		If this vector's x or y values are less than the min value, they are replaced by the min value.
 		</p>
 
 		<h3>[method:Vector2 clone]()</h3>
 		<p>
-		Returns a new Vector2 with the same [page:.x x] and [page:.y y] values as this one.
+			返回一个新的Vector2,其具有和当前这个向量相同的[page:.x x]和[page:.y y]。
 		</p>
 
 		<h3>[method:this copy]( [param:Vector2 v] )</h3>
 		<p>
-			Copies the values of the passed Vector2's [page:.x x] and [page:.y y]
-			properties to this Vector2.
+			将所传入Vector2的[page:.x x]和[page:.y y]属性复制给这一Vector2。
 		</p>
 
 		<h3>[method:Float distanceTo]( [param:Vector2 v] )</h3>
-		<p>Computes the distance from this vector to [page:Vector2 v].</p>
+		<p>计算该vector到传入的[page:Vector2 v]的距离。</p>
 
 		<h3>[method:Float manhattanDistanceTo]( [param:Vector2 v] )</h3>
 		<p>
-		Computes the [link:https://en.wikipedia.org/wiki/Taxicab_geometry Manhattan distance] from this vector to [page:Vector2 v].
+		计算该vector到传入的[page:Vector2 v]的曼哈顿距离([link:https://en.wikipedia.org/wiki/Taxicab_geometry Manhattan distance])。
 		</p>
 
 		<h3>[method:Float distanceToSquared]( [param:Vector2 v] )</h3>
 		<p>
-		Computes the squared distance from this vector to [page:Vector2 v]. If you are just
-		comparing the distance with another distance, you should compare the distance squared instead
-		as it is slightly more efficient to calculate.
+		计算该向量到传入的[page:Vector2 v]的平方距离。
+		如果你只是将该距离和另一个距离进行比较,则应当比较的是距离的平方,
+		因为它的计算效率会更高一些。
 		</p>
 
 		<h3>[method:this divide]( [param:Vector2 v] )</h3>
-		<p>Divides this vector by [page:Vector2 v].</p>
+		<p>将该向量除以向量[page:Vector2 v]。</p>
 
 		<h3>[method:this divideScalar]( [param:Float s] )</h3>
 		<p>
-		Divides this vector by scalar [page:Float s].<br />
-		Sets vector to *( 0, 0 )* if [page:Float s] = 0.
+			将该向量除以标量[page:Float s]。<br />
+			如果传入的[page:Float s] = 0,则向量将被设置为*( 0, 0 )*。
 		</p>
 
 		<h3>[method:Float dot]( [param:Vector2 v] )</h3>
 		<p>
-		Calculates the [link:https://en.wikipedia.org/wiki/Dot_product dot product] of this
-	  vector and [page:Vector2 v].
+			计算该vector和所传入[page:Vector2 v]的点积([link:https://en.wikipedia.org/wiki/Dot_product dot product])。
 		</p>
         
 		<h3>[method:Float cross]( [param:Vector2 v] )</h3>
 		<p>
-		Calculates the [link:https://en.wikipedia.org/wiki/Cross_product cross product] of this
-	  vector and [page:Vector2 v]. Note that a 'cross-product' in 2D is not well-defined. This function computes a geometric cross-product often used in 2D graphics
+			计算该vector和所传入[page:Vector2 v]的叉积([link:https://en.wikipedia.org/wiki/Cross_product cross product])。 
+			请注意,“叉积”在2D中并没有被明确定义。该函数计算的是2D图形中经常使用的几何叉积。
 		</p>
 
 		<h3>[method:Boolean equals]( [param:Vector2 v] )</h3>
-		<p>Checks for strict equality of this vector and [page:Vector2 v].</p>
+		<p>检查该向量和[page:Vector2 v]的严格相等性。</p>
 
 		<h3>[method:this floor]()</h3>
-		<p>The components of the vector are rounded down to the nearest integer value.</p>
+		<p>
+			向量中的[page:.x x]分量和[page:.y y]分量向下取整为最接近的整数值。
+		</p>
 
 		<h3>[method:this fromArray]( [param:Array array], [param:Integer offset] )</h3>
 		<p>
-		[page:Array array] - the source array.<br />
-		[page:Integer offset] - (optional) offset into the array. Default is 0.<br /><br />
+		[page:Array array] - 来源的数组。<br />
+		[page:Integer offset] - (可选)在数组中的元素偏移量,默认值为0。<br /><br />
 
-		Sets this vector's [page:.x x] value to be array[ offset ] and [page:.y y] value to be array[ offset + 1 ].
+		设置向量中的[page:.x x]值为array[ offset ],[page:.y y]值为array[ offset + 1 ]。
 		</p>
 
 		<h3>[method:this fromBufferAttribute]( [param:BufferAttribute attribute], [param:Integer index] )</h3>
 		<p>
-		[page:BufferAttribute attribute] - the source attribute.<br />
-		[page:Integer index] - index in the attribute.<br /><br />
+		[page:BufferAttribute attribute] - 来源的attribute。<br />
+		[page:Integer index] - 在attribute中的索引。<br /><br />
 
-		Sets this vector's [page:.x x] and [page:.y y] values from the [page:BufferAttribute attribute].
-		</p>
+		从[page:BufferAttribute attribute]中设置向量的[page:.x x]值和[page:.y y]值。 
+		</p>
 
 		<h3>[method:Float getComponent]( [param:Integer index] )</h3>
 		<p>
-		[page:Integer index] - 0 or 1.<br /><br />
+		[page:Integer index] - 0 或 1<br /><br />
 
-		If index equals 0 returns the [page:.x x] value. <br />
-		If index equals 1 returns the [page:.y y] value.
+		如果index值为0则返回[page:.x x]值。<br />
+		如果index值为1则返回[page:.y y]值。
 		</p>
 
 		<h3>[method:Float length]()</h3>
-		<p>Computes the [link:https://en.wikipedia.org/wiki/Euclidean_distance Euclidean length]
-		(straight-line length) from (0, 0) to (x, y).</p>
+		<p>
+		计算从(0, 0)到(x, y)的欧几里得长度
+		([link:https://en.wikipedia.org/wiki/Euclidean_distance Euclidean length],即直线长度)。
+		</p>
 
 		<h3>[method:Float manhattanLength]()</h3>
 		<p>
-		Computes the [link:http://en.wikipedia.org/wiki/Taxicab_geometry Manhattan length] of this vector.
+		计算该向量的曼哈顿长度([link:http://en.wikipedia.org/wiki/Taxicab_geometry Manhattan length])。
 		</p>
 
 		<h3>[method:Float lengthSq]()</h3>
 		<p>
-		Computes the square of the [link:https://en.wikipedia.org/wiki/Euclidean_distance Euclidean length]
-		(straight-line length) from (0, 0) to (x, y). If you are 	comparing the lengths of
-		vectors, you should compare the length squared instead as it is slightly more efficient to calculate.
+		计算从(0, 0)到(x, y)的欧几里得长度
+		([link:https://en.wikipedia.org/wiki/Euclidean_distance Euclidean length],即直线长度)的平方。
+		如果你正在比较向量的长度,应当比较的是长度的平方,因为它的计算效率更高一些。
 		</p>
 
 		<h3>[method:this lerp]( [param:Vector2 v], [param:Float alpha] )</h3>
 		<p>
-		[page:Vector2 v] - [page:Vector2] to interpolate towards.<br />
-		alpha - interpolation factor in the closed interval [0, 1].<br /><br />
+		[page:Vector2 v] - 朝着进行插值的[page:Vector2]。<br />
+		alpha - 插值因数,其范围在[0, 1]闭区间。<br /><br />
 
-		Linearly interpolates between this vector and [page:Vector2 v], where alpha is the
-		distance along the line - alpha = 0 will be this vector, and alpha = 1 will be [page:Vector2 v].
+		在该向量与传入的向量[page:Vector2 v]之间的线性插值,alpha是沿着线的距离长度。
+		—— alpha = 0 时表示的是当前向量,alpha = 1 时表示的是所传入的向量[page:Vector2 v]。
 		</p>
 
 		<h3>[method:this lerpVectors]( [param:Vector2 v1], [param:Vector2 v2], [param:Float alpha] )</h3>
 		<p>
-		[page:Vector2 v1] - the starting [page:Vector2].<br />
-		[page:Vector2 v2] - [page:Vector2] to interpolate towards.<br />
-		[page:Float alpha] - interpolation factor in the closed interval [0, 1].<br /><br />
+		[page:Vector2 v1] - 起始的[page:Vector2]。<br />
+		[page:Vector2 v2] - 朝着进行插值的[page:Vector2]。<br />
+		[page:Float alpha] - 插值因数,其范围在[0, 1]闭区间。<br /><br />
 
-		Sets this vector to be the vector linearly interpolated between [page:Vector2 v1] and
-		[page:Vector2 v2] where alpha is the distance along the line connecting the two vectors
-		- alpha = 0 will be [page:Vector2 v1], and alpha = 1 will be [page:Vector2 v2].
+		将此向量设置为在[page:Vector2 v1]和[page:Vector2 v2]之间进行线性插值的向量,
+		其中alpha为两个向量之间连线的距离长度。
+		—— alpha = 0 时表示的是[page:Vector2 v1],alpha = 1 时表示的是[page:Vector2 v2]。
 		</p>
 
 		<h3>[method:this negate]()</h3>
-		<p>Inverts this vector - i.e. sets x = -x and y = -y.</p>
+		<p>向量取反,即: x = -x , y = -y。</p>
 
 		<h3>[method:this normalize]()</h3>
 		<p>
-		Converts this vector to a [link:https://en.wikipedia.org/wiki/Unit_vector unit vector] - that is, sets it equal to the vector with the same direction
-		as this one, but [page:.length length] 1.
+		将该向量转换为单位向量([link:https://en.wikipedia.org/wiki/Unit_vector unit vector]),
+		也就是说,将该向量的方向设置为和原向量相同,但是其长度([page:.length length])为1。
 		</p>
 
 		<h3>[method:this max]( [param:Vector2 v] )</h3>
 		<p>
-		If this vector's x or y value is less than [page:Vector2 v]'s x or y value, replace
-		that value with the corresponding max value.
+		如果该向量的x值或y值小于所传入[page:Vector2 v]的x值或y值,则将该值替换为对应的最大值。
 		</p>
 
 		<h3>[method:this min]( [param:Vector2 v] )</h3>
 		<p>
-		If this vector's x or y value is greater than [page:Vector2 v]'s x or y value, replace
-		that value with the corresponding min value.
+		如果该向量的x值或y值大于所传入[page:Vector2 v]的x值或y值,则将该值替换为对应的最小值。
 		</p>
 
 		<h3>[method:this multiply]( [param:Vector2 v] )</h3>
-		<p>Multiplies this vector by [page:Vector2 v].</p>
+		<p>将该向量与所传入的向量[page:Vector2 v]进行相乘。</p>
 
 
 		<h3>[method:this multiplyScalar]( [param:Float s] )</h3>
-		<p>Multiplies this vector by scalar [page:Float s].</p>
+		<p>将该向量与所传入的标量[page:Float s]进行相乘。</p>
 
 		<h3>[method:this rotateAround]( [param:Vector2 center], [param:float angle] )</h3>
 		<p>
-			[page:Vector2 center] - the point around which to rotate.<br />
-			[page:float angle] - the angle to rotate, in radians.<br /><br />
+		[page:Vector2 center] - 将被围绕旋转的点。<br />
+		[page:float angle] - 将要旋转的角度,以弧度来表示。<br /><br />
 
-			Rotates the vector around [page:Vector2 center] by [page:float angle] radians.
+		将向量围绕着[page:Vector2 center]旋转[page:float angle]弧度。
 		</p>
 
 		<h3>[method:this round]()</h3>
-		<p>The components of the vector are rounded to the nearest integer value.</p>
+		<p>			
+			向量中的[page:.x x]分量和[page:.y y]分量四舍五入取整为最接近的整数值。
+		</p>
 
 		<h3>[method:this roundToZero]()</h3>
 		<p>
-		The components of the vector are rounded towards zero (up if negative, down if positive) to an integer value.
+			向量中的分量朝向0取整数(若分量为负数则向上取整,若为正数则向下取整)。
 		</p>
 
 		<h3>[method:this set]( [param:Float x], [param:Float y] )</h3>
-		<p>Sets the [page:.x x] and [page:.y y] components of this vector.</p>
+		<p>设置该向量的[page:.x x]和[page:.y y]分量。</p>
 
 		<h3>[method:null setComponent]( [param:Integer index], [param:Float value] )</h3>
 		<p>
-		[page:Integer index] - 0 or 1.<br />
+		[page:Integer index] - 0 或 1<br />
 		[page:Float value] - [page:Float]<br /><br />
 
-		If index equals 0 set [page:.x x] to [page:Float value]. <br />
-		If index equals 1 set [page:.y y] to [page:Float value]
+		如果index值为0则将[page:.x x]值设置为[page:Float value]。<br />
+		如果index值为1则将[page:.y y]值设置为[page:Float value]
 		</p>
 
 		<h3>[method:this setLength]( [param:Float l] )</h3>
 		<p>
-		Sets this vector to the vector with the same direction as this one, but [page:.length length]
-		[page:Float l].
+			将该向量的方向设置为和原向量相同,但是长度([page:.length length])为[page:Float l]。
 		</p>
 
 		<h3>[method:this setScalar]( [param:Float scalar] )</h3>
 		<p>
-		Sets the [page:.x x] and [page:.y y] values of this vector both equal to [page:Float scalar].
+		将该向量的[page:.x x]、[page:.y y]值同时设置为等于传入的[page:Float scalar]。
 		</p>
 
 		<h3>[method:this setX]( [param:Float x] )</h3>
-		<p>Replaces this vector's [page:.x x] value with [page:Float x].</p>
+		<p>将向量中的[page:.x x]值替换为[page:Float x]。</p>
 
 		<h3>[method:this setY]( [param:Float y] )</h3>
-		<p>Replaces this vector's [page:.y y] value with [page:Float y].</p>
+		<p>将向量中的[page:.y y]值替换为[page:Float y]。</p>
 
 		<h3>[method:this sub]( [param:Vector2 v] )</h3>
-		<p>Subtracts [page:Vector2 v] from this vector.</p>
+		<p>从该向量减去向量[page:Vector2 v]。</p>
 
 		<h3>[method:this subScalar]( [param:Float s] )</h3>
-		<p>Subtracts [page:Float s]  from this vector's [page:.x x] and [page:.y y] components.</p>
+		<p>从该向量的[page:.x x]和[page:.y y]中减去标量[page:Float s]。</p>
 
 		<h3>[method:this subVectors]( [param:Vector2 a], [param:Vector2 b] )</h3>
-		<p>Sets this vector to [page:Vector2 a] - [page:Vector2 b].</p>
+		<p>将该向量设置为[page:Vector2 a] - [page:Vector2 b]。</p>
 
 		<h3>[method:Array toArray]( [param:Array array], [param:Integer offset] )</h3>
 		<p>
-		[page:Array array] - (optional) array to store the vector to. If this is not provided, a new array will be created.<br />
-		[page:Integer offset] - (optional) optional offset into the array.<br /><br />
+		[page:Array array] - (可选)被用于存储向量的数组。如果这个值没有传入,则将创建一个新的数组。<br />
+		[page:Integer offset] - (可选) 数组中元素的偏移量。<br /><br />
 
-		Returns an array [x, y], or copies x and y into the provided [page:Array array].
+		返回一个数组[x, y],或者将x和y复制到所传入的[page:Array array]中。
 		</p>
 
-		<h2>Source</h2>
+		<h2>源代码</h2>
 
 		[link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js]
 	</body>

+ 136 - 138
docs/api/zh/math/Vector3.html

@@ -8,36 +8,36 @@
 		<link type="text/css" rel="stylesheet" href="page.css" />
 	</head>
 	<body>
-		<h1>[name]</h1>
+		<h1>三维向量([name]</h1>
 
-		<p class="desc">Class representing a 3D [link:https://en.wikipedia.org/wiki/Vector_space vector].
+		<p class="desc">该类表示的是一个三维向量(3D [link:https://en.wikipedia.org/wiki/Vector_space vector])。
 
-		A 3D vector is an ordered triplet of numbers (labeled x, y, and z), which can be used to
-		represent a number of things, such as:
+		一个三维向量表示的是一个有顺序的、三个为一组的数字组合(标记为x、y和z),
+		可被用来表示很多事物,例如:
+		
 		</p>
 
 		<ul>
 			<li>
-				A point in 3D space.
+				一个位于三维空间中的点。
 			</li>
 			<li>
-				A direction and length in 3D space. In three.js the length will always be the
-				[link:https://en.wikipedia.org/wiki/Euclidean_distance Euclidean distance]
-				(straight-line distance) from (0, 0, 0) to (x, y, z) and the direction is also
-				measured from (0, 0, 0) towards (x, y, z).
+				一个在三维空间中的方向与长度的定义。在three.js中,长度总是从(0, 0, 0)到(x, y, z)的
+				[link:https://en.wikipedia.org/wiki/Euclidean_distance Euclidean distance](欧几里德距离,即直线距离),
+				方向也是从(0, 0, 0)到(x, y, z)的方向。
 			</li>
 			<li>
-				Any arbitrary ordered triplet of numbers.
+				任意的、有顺序的、三个为一组的数字组合。
 			</li>
 		</ul>
 
 		<p>
-		There are other things a 3D vector can be used to represent, such as momentum
-		vectors and so on, however these are the most common uses in three.js.
+		其他的一些事物也可以使用二维向量进行表示,比如说动量矢量等等;
+		但以上这些是它在three.js中的常用用途。
 		</p>
 
 
-		<h2>Example</h2>
+		<h2>示例</h2>
 
 		<code>
 var a = new THREE.Vector3( 0, 1, 0 );
@@ -49,25 +49,25 @@ var d = a.distanceTo( b );
 		</code>
 
 
-		<h2>Constructor</h2>
+		<h2>构造函数</h2>
 
 		<h3>[name]( [param:Float x], [param:Float y], [param:Float z] )</h3>
 		<p>
-		[page:Float x] - the x value of the vector. Default is *0*.<br />
-		[page:Float y] -  the y value of the vector. Default is *0*.<br />
-		[page:Float z] - the z value of the vector. Default is *0*.<br /><br />
+		[page:Float x] - 向量的x值,默认为*0*。<br />
+		[page:Float y] - 向量的y值,默认为*0*。<br />
+		[page:Float z] - 向量的z值,默认为*0*。<br /><br />
 
-		Creates a new [name].
+		创建一个新的[name]。
 		</p>
 
 
-		<h2>Properties</h2>
+		<h2>属性</h2>
 
 		<h3>[property:Boolean isVector3]</h3>
 		<p>
-			Used to check whether this or derived classes are Vector3s. Default is *true*.<br /><br />
+			用于测试这个类或者派生类是否为Vector3,默认为*true*。<br /><br />
 
-			You should not change this, as it is used internally for optimisation.
+			你不应当对这个属性进行改变,因为它在内部使用,以用于优化。
 		</p>
 
 		<h3>[property:Float x]</h3>
@@ -77,239 +77,239 @@ var d = a.distanceTo( b );
 		<h3>[property:Float z]</h3>
 
 
-		<h2>Methods</h2>
+		<h2>方法</h2>
 
 		<h3>[method:this add]( [param:Vector3 v] )</h3>
-		<p>Adds [page:Vector3 v] to this vector.</p>
+		<p>将传入的向量[page:Vector3 v]和这个向量相加。</p>
 
 		<h3>[method:this addScalar]( [param:Float s] )</h3>
-		<p>Adds the scalar value s to this vector's [page:.x x], [page:.y y] and [page:.z z] values.</p>
+		<p>将传入的标量s和这个向量的[page:.x x]值、[page:.y y]值以及[page:.z z]值相加。</p>
 
 		<h3>[method:this addScaledVector]( [param:Vector3 v], [param:Float s] )</h3>
-		<p>Adds the multiple of [page:Vector3 v] and [page:Float s] to this vector.</p>
+		<p>将所传入的[page:Vector3 v]与[page:Float s]相乘所得的乘积和这个向量相加。</p>
 
 		<h3>[method:this addVectors]( [param:Vector3 a], [param:Vector3 b] )</h3>
-		<p>Sets this vector to [page:Vector3 a] + [page:Vector3 b].</p>
+		<p>将该向量设置为[page:Vector3 a] + [page:Vector3 b]。</p>
 
 		<h3>[method:this applyAxisAngle]( [param:Vector3 axis], [param:Float angle] )</h3>
 		<p>
-		[page:Vector3 axis] - A normalized [page:Vector3].<br />
-		[page:Float angle] - An angle in radians.<br /><br />
+		[page:Vector3 axis] - 一个被归一化的[page:Vector3]。<br />
+		[page:Float angle] - 以弧度表示的角度。<br /><br />
 
-		Applies a rotation specified by an axis and an angle to this vector.
+		将轴和角度所指定的旋转应用到该向量上。
 		</p>
 
 		<h3>[method:this applyEuler]( [param:Euler euler] )</h3>
 		<p>
-		Applies euler transform to this vector by converting the [page:Euler] object to a
-		[page:Quaternion] and applying.
+		通过将[page:Euler](欧拉)对象转换为[page:Quaternion](四元数)并应用,
+		将欧拉变换应用到这一向量上。
 		</p>
 
 		<h3>[method:this applyMatrix3]( [param:Matrix3 m] )</h3>
-		<p>Multiplies this vector by [page:Matrix3 m]</p>
+		<p>将该向量乘以三阶矩阵[page:Matrix3 m]。</p>
 
 		<h3>[method:this applyMatrix4]( [param:Matrix4 m] )</h3>
 		<p>
-		Multiplies this vector (with an implicit 1 in the 4th dimension) and m, and divides by perspective.
+			将该向量乘以四阶矩阵m(第四个维度隐式地为1),and divides by perspective.
 		</p>
 
 		<h3>[method:this applyQuaternion]( [param:Quaternion quaternion] )</h3>
 		<p>
-		Applies a [page:Quaternion] transform to this vector.
+		将[page:Quaternion]变换应用到该向量。
 		</p>
 
 
 		<h3>[method:Float angleTo]( [param:Vector3 v] )</h3>
 		<p>
-		Returns the angle between this vector and vector [page:Vector3 v] in radians.
+		以弧度返回该向量与向量[page:Vector3 v]之间的角度。
 		</p>
 
 		<h3>[method:this ceil]()</h3>
 		<p>
-		The [page:.x x], [page:.y y] and [page:.z z] components of the vector are rounded up to the nearest integer value.
+		将该向量[page:.x x]分量、 [page:.y y]分量以及[page:.z z]分量向上取整为最接近的整数。
 		</p>
 
 		<h3>[method:this clamp]( [param:Vector3 min], [param:Vector3 max] )</h3>
 		<p>
-		[page:Vector3 min] - the minimum [page:.x x], [page:.y y] and [page:.z z] values.<br />
-		[page:Vector3 max] - the maximum [page:.x x], [page:.y y] and [page:.z z] values in the desired range<br /><br />
+		[page:Vector3 min] - 在限制范围内,[page:.x x]值、[page:.y y]值和[page:.z z]的最小值。<br />
+		[page:Vector3 max] - 在限制范围内,[page:.x x]值、[page:.y y]值和[page:.z z]的最大值。<br /><br />
 
-		If this vector's x, y or z value is greater than the max vector's x, y or z value, it is replaced by the corresponding value. <br /><br />
-		If this vector's x, y or z value is less than the min vector's x, y or z value, it is replaced by the corresponding value.
+		如果该向量的x值、y值或z值大于限制范围内最大x值、y值或z值,则该值将会被所对应的值取代。<br /><br />
+		如果该向量的x值、y值或z值小于限制范围内最小x值、y值或z值,则该值将会被所对应的值取代。
 		</p>
 
 		<h3>[method:this clampLength]( [param:Float min], [param:Float max] )</h3>
 		<p>
-		[page:Float min] - the minimum value the length will be clamped to <br />
-		[page:Float max] - the maximum value the length will be clamped to<br /><br />
+		[page:Float min] - 长度将被限制为的最小值 <br />
+		[page:Float max] - 长度将被限制为的最大值<br /><br />
 
-		If this vector's length is greater than the max value, it is replaced by the max value. <br /><br />
-		If this vector's length is less than the min value, it is replaced by the min value.
+		如果向量长度大于最大值,则它将会被最大值所取代。<br /><br />
+		如果向量长度小于最小值,则它将会被最小值所取代。
 		</p>
 
 		<h3>[method:this clampScalar]( [param:Float min], [param:Float max] )</h3>
 		<p>
-		[page:Float min] - the minimum value the components will be clamped to <br />
-		[page:Float max] - the maximum value the components will be clamped to<br /><br />
+		[page:Float min] - 分量将被限制为的最小值 <br />
+		[page:Float max] - 分量将被限制为的最大值<br /><br />
 
-		If this vector's x, y or z values are greater than the max value, they are replaced by the max value. <br /><br />
-		If this vector's x, y or z values are less than the min value, they are replaced by the min value.
+		如果该向量的x值、y值或z值大于最大值,则它们将被最大值所取代。<br /><br />
+		如果该向量的x值、y值或z值小于最小值,则它们将被最小值所取代。
 		</p>
 
 		<h3>[method:Vector3 clone]()</h3>
 		<p>
-		Returns a new vector3 with the same [page:.x x], [page:.y y] and [page:.z z] values as this one.
+		返回一个新的Vector3,其具有和当前这个向量相同的[page:.x x]、[page:.y y]和[page:.z z]。
 		</p>
 
 		<h3>[method:this copy]( [param:Vector3 v] )</h3>
 		<p>
-			Copies the values of the passed vector3's [page:.x x], [page:.y y] and [page:.z z]
-			properties to this vector3.
+		将所传入Vector3的[page:.x x]、[page:.y y]和[page:.z z]属性复制给这一Vector3。
 		</p>
 
 		<h3>[method:this cross]( [param:Vector3 v] )</h3>
 		<p>
-		Sets this vector to [link:https://en.wikipedia.org/wiki/Cross_product cross product] of itself and [page:Vector3 v].
+		将该向量设置为它本身与传入的[page:Vector3 v]的叉积([link:https://en.wikipedia.org/wiki/Cross_product cross product])。
 		</p>
 
 		<h3>[method:this crossVectors]( [param:Vector3 a], [param:Vector3 b] )</h3>
 		<p>
-		Sets this vector to [link:https://en.wikipedia.org/wiki/Cross_product cross product] of [page:Vector3 a] and [page:Vector3 b].
+		将该向量设置为传入的[page:Vector3 a]与[page:Vector3 b]的叉积([link:https://en.wikipedia.org/wiki/Cross_product cross product])。
 		</p>
 
 		<h3>[method:Float distanceTo]( [param:Vector3 v] )</h3>
-		<p>Computes the distance from this vector to [page:Vector3 v].</p>
+		<p>计算该向量到所传入的[page:Vector3 v]间的距离。</p>
 
 		<h3>[method:Float manhattanDistanceTo]( [param:Vector3 v] )</h3>
 		<p>
-		Computes the [link:https://en.wikipedia.org/wiki/Taxicab_geometry Manhattan distance] from this vector to [page:Vector3 v].
+		计算该向量到所传入的[page:Vector3 v]之间的曼哈顿距离([link:https://en.wikipedia.org/wiki/Taxicab_geometry Manhattan distance])。
 		</p>
 
 		<h3>[method:Float distanceToSquared]( [param:Vector3 v] )</h3>
 		<p>
-		Computes the squared distance from this vector to [page:Vector3 v]. If you are just
-		comparing the distance with another distance, you should compare the distance squared instead
-		as it is slightly more efficient to calculate.
+		计算该向量到传入的[page:Vector3 v]的平方距离。
+		如果你只是将该距离和另一个距离进行比较,则应当比较的是距离的平方,
+		因为它的计算效率会更高一些。
 		</p>
 
 		<h3>[method:this divide]( [param:Vector3 v] )</h3>
-		<p>Divides this vector by [page:Vector3 v].</p>
+		<p>将该向量除以向量[page:Vector3 v]。</p>
 
 		<h3>[method:this divideScalar]( [param:Float s] )</h3>
 		<p>
-		Divides this vector by scalar [page:Float s].<br />
-		Sets vector to *( 0, 0, 0 )* if *[page:Float s] = 0*.
+		将该向量除以标量[page:Float s]。<br />
+		如果传入的[page:Float s] = 0,则向量将被设置为*( 0, 0, 0 )*。
 		</p>
 
 		<h3>[method:Float dot]( [param:Vector3 v] )</h3>
 		<p>
-		Calculate the [link:https://en.wikipedia.org/wiki/Dot_product dot product] of this
-		vector and [page:Vector3 v].
+		计算该vector和所传入[page:Vector3 v]的点积([link:https://en.wikipedia.org/wiki/Dot_product dot product])。
 		</p>
 
 		<h3>[method:Boolean equals]( [param:Vector3 v] )</h3>
-		<p>Checks for strict equality of this vector and [page:Vector3 v].</p>
+		<p>检查该向量和[page:Vector3 v]的严格相等性。</p>
 
 		<h3>[method:this floor]()</h3>
-		<p>The components of the vector are rounded down to the nearest integer value.</p>
+		<p>向量的分量向下取整为最接近的整数值。</p>
 
 		<h3>[method:this fromArray]( [param:Array array], [param:Integer offset] )</h3>
 		<p>
-		[page:Array array] - the source array.<br />
-		[page:Integer offset] - ( optional) offset into the array. Default is 0.<br /><br />
+		[page:Array array] - 来源矩阵。<br />
+		[page:Integer offset] - (可选)在数组中的元素偏移量,默认值为0。<br /><br />
 
-		Sets this vector's [page:.x x] value to be array[ offset + 0 ], [page:.y y] value to be array[ offset + 1 ]
-		and [page:.z z] value to be array[ offset + 2 ].
+		设置向量中的[page:.x x]值为array[ offset + 0 ],[page:.y y]值为array[ offset + 1 ],
+		[page:.z z]值为array[ offset + 2 ]。
 		</p>
 
 		<h3>[method:this fromBufferAttribute]( [param:BufferAttribute attribute], [param:Integer index] )</h3>
 		<p>
-		[page:BufferAttribute attribute] - the source attribute.<br />
-		[page:Integer index] - index in the attribute.<br /><br />
+		[page:BufferAttribute attribute] - 来源的attribute。<br />
+		[page:Integer index] - 在attribute中的索引。<br /><br />
 
-		Sets this vector's [page:.x x], [page:.y y] and [page:.z z] values from the [page:BufferAttribute attribute].
+		从[page:BufferAttribute attribute]中设置向量的[page:.x x]值、[page:.y y]值和[page:.z z]值。
 		</p>
 
 		<h3>[method:Float getComponent]( [param:Integer index] )</h3>
 		<p>
 		[page:Integer index] - 0, 1 or 2.<br /><br />
 
-		If index equals 0 returns the [page:.x x] value. <br />
-		If index equals 1 returns the [page:.y y] value. <br />
-		If index equals 2 returns the [page:.z z] value.
+		如果index值为0返回[page:.x x]值。 <br />
+		如果index值为1返回[page:.y y]值。 <br />
+		如果index值为2返回[page:.z z]值。
 		</p>
 
 		<h3>[method:Float length]()</h3>
-		<p>Computes the [link:https://en.wikipedia.org/wiki/Euclidean_distance Euclidean length]
-		(straight-line length) from (0, 0, 0) to (x, y, z).</p>
+		<p>计算从(0, 0, 0) 到 (x, y, z)的欧几里得长度
+		([link:https://en.wikipedia.org/wiki/Euclidean_distance Euclidean length],即直线长度)
+		</p>
 
 		<h3>[method:Float manhattanLength]()</h3>
 		<p>
-		Computes the [link:http://en.wikipedia.org/wiki/Taxicab_geometry Manhattan length] of this vector.
+		计算该向量的曼哈顿长度([link:http://en.wikipedia.org/wiki/Taxicab_geometry Manhattan length])。
 		</p>
 
 		<h3>[method:Float lengthSq]()</h3>
 		<p>
-		Computes the square of the [link:https://en.wikipedia.org/wiki/Euclidean_distance Euclidean length]
-		(straight-line length) from (0, 0, 0) to (x, y, z). If you are 	comparing the lengths of
-		vectors, you should compare the length squared instead as it is slightly more efficient to calculate.
+		计算从(0, 0, 0)到(x, y, z)的欧几里得长度
+		([link:https://en.wikipedia.org/wiki/Euclidean_distance Euclidean length],即直线长度)的平方。
+		如果你正在比较向量的长度,应当比较的是长度的平方,因为它的计算效率更高一些。
 		</p>
 
 		<h3>[method:this lerp]( [param:Vector3 v], [param:Float alpha] )</h3>
 		<p>
-		[page:Vector3 v] - [page:Vector3] to interpolate towards.<br />
-		alpha - interpolation factor in the closed interval [0, 1].<br /><br />
+		[page:Vector3 v] - 朝着进行插值的[page:Vector3]。<br />
+		alpha - 插值因数,其范围在[0, 1]闭区间。<br /><br />
 
-		Linearly interpolate between this vector and [page:Vector3 v], where alpha is the
-		distance along the line - alpha = 0 will be this vector, and alpha = 1 will be [page:Vector3 v].
+		在该向量与传入的向量[page:Vector3 v]之间的线性插值,alpha是沿着线的距离长度。
+		—— alpha = 0 时表示的是当前向量,alpha = 1 时表示的是所传入的向量[page:Vector3 v]。
 		</p>
 
 		<h3>[method:this lerpVectors]( [param:Vector3 v1], [param:Vector3 v2], [param:Float alpha] )</h3>
 		<p>
-		[page:Vector3 v1] - the starting [page:Vector3].<br />
-		[page:Vector3 v2] - [page:Vector3] to interpolate towards.<br />
-		[page:Float alpha] - interpolation factor in the closed interval [0, 1].<br /><br />
+		[page:Vector3 v1] - 起始的[page:Vector3]。<br />
+		[page:Vector3 v2] - 朝着进行插值的[page:Vector3]。<br />
+		[page:Float alpha] - 插值因数,其范围在[0, 1]闭区间。<br /><br />
 
-		Sets this vector to be the vector linearly interpolated between [page:Vector3 v1] and
-		[page:Vector3 v2] where alpha is the distance along the line connecting the two vectors
-		- alpha = 0 will be [page:Vector3 v1], and alpha = 1 will be [page:Vector3 v2].
+		
+		将此向量设置为在[page:Vector3 v1]和[page:Vector3 v2]之间进行线性插值的向量,
+		其中alpha为两个向量之间连线的距离长度。
+		—— alpha = 0 时表示的是[page:Vector3 v1],alpha = 1 时表示的是[page:Vector3 v2]。
 		</p>
 
 		<h3>[method:this max]( [param:Vector3 v] )</h3>
 		<p>
-		If this vector's x, y or z value is less than [page:Vector3 v]'s x, y or z value, replace
-		that value with the corresponding max value.
+		如果该向量的x值、y值或z值小于所传入[page:Vector3 v]的x值、y值或z值,
+		则将该值替换为对应的最大值。
 		</p>
 
 		<h3>[method:this min]( [param:Vector3 v] )</h3>
 		<p>
-		If this vector's x, y or z value is greater than [page:Vector3 v]'s x, y or z value, replace
-		that value with the corresponding min value.
+		如果该向量的x值、y值或z值大于所传入[page:Vector3 v]的x值、y值或z值,
+		则将该值替换为对应的最小值。
 		</p>
 
 		<h3>[method:this multiply]( [param:Vector3 v] )</h3>
-		<p>Multiplies this vector by [page:Vector3 v].</p>
+		<p>将该向量与所传入的向量[page:Vector3 v]进行相乘。</p>
 
 		<h3>[method:this multiplyScalar]( [param:Float s] )</h3>
-		<p>Multiplies this vector by scalar [page:Float s].</p>
+		<p>将该向量与所传入的标量[page:Float s]进行相乘。</p>
 
 		<h3>[method:this multiplyVectors]( [param:Vector3 a], [param:Vector3 b] )</h3>
-		<p>Sets this vector equal to [page:Vector3 a] * [page:Vector3 b], component-wise.</p>
+		<p>按照分量顺序,将该向量设置为和[page:Vector3 a] * [page:Vector3 b]相等。</p>
 
 		<h3>[method:this negate]()</h3>
-		<p>Inverts this vector - i.e. sets x = -x, y = -y and z = -z.</p>
+		<p>向量取反,即: x = -x, y = -y , z = -z。</p>
 
 		<h3>[method:this normalize]()</h3>
 		<p>
-		Convert this vector to a [link:https://en.wikipedia.org/wiki/Unit_vector unit vector] - that is, sets it equal to the vector with the same direction
-		as this one, but [page:.length length] 1.
+		将该向量转换为单位向量([link:https://en.wikipedia.org/wiki/Unit_vector unit vector]),
+		也就是说,将该向量的方向设置为和原向量相同,但是其长度([page:.length length])为1。
 		</p>
 
 		<h3>[method:this project]( [param:Camera camera] )</h3>
 		<p>
-		[page:Camera camera] — camera to use in the projection.<br /><br />
+		[page:Camera camera] — 在投影中使用的摄像机。<br /><br />
 
-		[link:https://en.wikipedia.org/wiki/Vector_projection Projects] the vector with the camera.
+		使用所传入的摄像机来投影([link:https://en.wikipedia.org/wiki/Vector_projection projects])该向量。
 		</p>
 
 		<h3>[method:this projectOnPlane]( [param:Vector3 planeNormal] )</h3>
@@ -321,7 +321,7 @@ var d = a.distanceTo( b );
 		</p>
 
 		<h3>[method:this projectOnVector]( [param:Vector3] )</h3>
-		<p>[link:https://en.wikipedia.org/wiki/Vector_projection Projects] this vector onto another vector.</p>
+		<p>投影([link:https://en.wikipedia.org/wiki/Vector_projection Projects])该向量到另一个向量上。 </p>
 
 		<h3>[method:this reflect]( [param:Vector3 normal] )</h3>
 		<p>
@@ -332,114 +332,112 @@ var d = a.distanceTo( b );
 		</p>
 
 		<h3>[method:this round]()</h3>
-		<p>The components of the vector are rounded to the nearest integer value.</p>
+		<p>	向量中的分量四舍五入取整为最接近的整数值。</p>
 
 		<h3>[method:this roundToZero]()</h3>
 		<p>
-		The components of the vector are rounded towards zero (up if negative, down if positive) to an integer value.
+		向量中的分量朝向0取整数(若分量为负数则向上取整,若为正数则向下取整)。
 		</p>
 
 		<h3>[method:this set]( [param:Float x], [param:Float y], [param:Float z] )</h3>
-		<p>Sets the [page:.x x], [page:.y y] and [page:.z z] components of this vector.</p>
+		<p>设置该向量的[page:.x x]、[page:.y y] 和 [page:.z z] 分量。</p>
 
 		<h3>[method:null setComponent]( [param:Integer index], [param:Float value] )</h3>
 		<p>
-		[page:Integer index] - 0, 1 or 2.<br />
+		[page:Integer index] - 0、1 或 2。<br />
 		[page:Float value] - [page:Float]<br /><br />
 
-		If index equals 0 set [page:.x x] to [page:Float value].<br />
-		If index equals 1 set [page:.y y] to [page:Float value].<br />
-		If index equals 2 set [page:.z z] to [page:Float value]
+		若index为 0 则设置 [page:.x x] 值为 [page:Float value]。<br />
+		若index为 1 则设置 [page:.y y] 值为 [page:Float value]。<br />
+		若index为 2 则设置 [page:.z z] 值为 [page:Float value]。
 		</p>
 
 		<h3>[method:this setFromCylindrical]( [param:Cylindrical c] )</h3>
 		<p>
-		Sets this vector from the cylindrical coordinates [page:Cylindrical c].
+		从圆柱坐标[page:Cylindrical c]中设置该向量。
 		</p>
 
 		<h3>[method:this setFromCylindricalCoords]( [param:Float radius], [param:Float theta], [param:Float y] )</h3>
-		<p>Sets this vector from the cylindrical coordinates [page:Cylindrical radius], [page:Cylindrical theta] and [page:Cylindrical y].</p>
+		<p>从圆柱坐标中的[page:Cylindrical radius]、[page:Cylindrical theta]和[page:Cylindrical y]设置该向量。</p>
 
 		<h3>[method:this setFromMatrixColumn]( [param:Matrix4 matrix], [param:Integer index] )</h3>
 		<p>
-		Sets this vector's [page:.x x], [page:.y y] and [page:.z z] equal to the column of
-		the [page:Matrix4 matrix] specified by the [page:Integer index].
+		从传入的四阶矩阵[page:Matrix4 matrix]由[page:Integer index]指定的列中,
+		设置该向量的[page:.x x]值、[page:.y y]值和[page:.z z]值。
 		</p>
 
 		<h3>[method:this setFromMatrixPosition]( [param:Matrix4 m] )</h3>
 		<p>
-		Sets this vector to the position elements of the
-		[link:https://en.wikipedia.org/wiki/Transformation_matrix transformation matrix] [page:Matrix4 m].
+		从变换矩阵([link:https://en.wikipedia.org/wiki/Transformation_matrix transformation matrix])[page:Matrix4 m]中,
+		设置该向量为其中与位置相关的元素。
 		</p>
 
 		<h3>[method:this setFromMatrixScale]( [param:Matrix4 m] )</h3>
 		<p>
-		Sets this vector to the scale elements of the
-		[link:https://en.wikipedia.org/wiki/Transformation_matrix transformation matrix] [page:Matrix4 m].
+		从变换矩阵([link:https://en.wikipedia.org/wiki/Transformation_matrix transformation matrix])[page:Matrix4 m]中,
+		设置该向量为其中与缩放相关的元素。
 		</p>
 
 		<h3>[method:this setFromSpherical]( [param:Spherical s] )</h3>
 		<p>
-		Sets this vector from the spherical coordinates [page:Spherical s].
+		从球坐标[page:Spherical s]中设置该向量。
 		</p>
 
 		<h3>[method:this setFromSphericalCoords]( [param:Float radius], [param:Float phi], [param:Float theta] )</h3>
-		<p>Sets this vector from the spherical coordinates [page:Spherical radius], [page:Spherical phi] and [page:Spherical theta].</p>
+		<p>从球坐标中的[page:Spherical radius]、[page:Spherical phi]和[page:Spherical theta]设置该向量。</p>
 
 		<h3>[method:this setLength]( [param:Float l] )</h3>
 		<p>
-		Set this vector to the vector with the same direction as this one, but [page:.length length]
-		[page:Float l].
+		将该向量的方向设置为和原向量相同,但是长度([page:.length length])为[page:Float l]。
 		</p>
 
 		<h3>[method:this setScalar]( [param:Float scalar] )</h3>
 		<p>
-		Set the [page:.x x], [page:.y y] and [page:.z z] values of this vector both equal to [page:Float scalar].
+		将该向量的[page:.x x]、[page:.y y]和[page:.z z]值同时设置为等于传入的[page:Float scalar]。
 		</p>
 
 		<h3>[method:this setX]( [param:Float x] )</h3>
-		<p>Replace this vector's [page:.x x] value with [page:Float x].</p>
+		<p>将向量中的[page:.x x]值替换为[page:Float x]。</p>
 
 		<h3>[method:this setY]( [param:Float y] )</h3>
-		<p>Replace this vector's [page:.y y] value with [page:Float y].</p>
+		<p>将向量中的[page:.y y]值替换为[page:Float y]。</p>
 
 		<h3>[method:this setZ]( [param:Float z] )</h3>
-		<p>Replace this vector's [page:.z z] value with [page:Float z].</p>
+		<p>将向量中的[page:.z z]值替换为[page:Float z]。</p>
 
 		<h3>[method:this sub]( [param:Vector3 v] )</h3>
-		<p>Subtracts [page:Vector3 v] from this vector.</p>
+		<p>从该向量减去向量[page:Vector3 v]。</p>
 
 		<h3>[method:this subScalar]( [param:Float s] )</h3>
-		<p>Subtracts [page:Float s]  from this vector's [page:.x x], [page:.y y] and [page:.z z] compnents.</p>
+		<p>从该向量的[page:.x x]、[page:.y y]和[page:.z z]中减去标量[page:Float s]。</p>
 
 		<h3>[method:this subVectors]( [param:Vector3 a], [param:Vector3 b] )</h3>
-		<p>Sets this vector to [page:Vector3 a] - [page:Vector3 b].</p>
+		<p>将该向量设置为[page:Vector3 a] - [page:Vector3 b]。</p>
 
 		<h3>[method:Array toArray]( [param:Array array], [param:Integer offset] )</h3>
 		<p>
-		[page:Array array] - (optional) array to store the vector to. If this is not provided
-		a new array will be created.<br />
-		[page:Integer offset] - (optional) optional offset into the array.<br /><br />
+		[page:Array array] - (可选)被用于存储向量的数组。如果这个值没有传入,则将创建一个新的数组。<br />
+		[page:Integer offset] - (可选) 数组中元素的偏移量。<br /><br />
 
-		Returns an array [x, y, z], or copies x, y and z into the provided [page:Array array].
+		返回一个数组[x, y ,z],或者将x、y和z复制到所传入的[page:Array array]中。
 		</p>
 
 		<h3>[method:this transformDirection]( [param:Matrix4 m] )</h3>
 		<p>
-		Transforms the direction of this vector by a matrix (the upper left 3 x 3 subset of a [page:Matrix4 m])
-		and then [page:.normalize normalizes] the result.
+		通过传入的矩阵([page:Matrix4 m]的左上角3 x 3子矩阵)变换向量的方向,
+		并将结果进行[page:.normalize normalizes](归一化)。
 		</p>
 
 		<h3>[method:this unproject]( [param:Camera camera] )</h3>
 		<p>
-		[page:Camera camera] — camera to use in the projection.<br /><br />
+		[page:Camera camera] — 在投影中使用的摄像机。<br /><br />
 
 		[link:https://en.wikipedia.org/wiki/Vector_projection Unprojects] the vector with the
 		camera's projection matrix.
 		</p>
 
 
-		<h2>Source</h2>
+		<h2>源代码</h2>
 
 		[link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js]
 	</body>

+ 111 - 111
docs/api/zh/math/Vector4.html

@@ -8,35 +8,35 @@
 		<link type="text/css" rel="stylesheet" href="page.css" />
 	</head>
 	<body>
-		<h1>[name]</h1>
+		<h1>四维向量([name]</h1>
 
-		<p class="desc">Class representing a 4D [link:https://en.wikipedia.org/wiki/Vector_space vector].
+		<p class="desc">该类表示的是一个三维向量(4D [link:https://en.wikipedia.org/wiki/Vector_space vector])。
 
-		A 4D vector is an ordered quadruplet of numbers (labeled x, y, z, and w), which can be used to
-		represent a number of things, such as:
+
+		一个四维向量表示的是一个有顺序的、四个为一组的数字组合(标记为x、y和z),
+		可被用来表示很多事物,例如:
 		</p>
 
 		<ul>
 			<li>
-				A point in 4D space.
+				一个位于四维空间中的点。
 			</li>
 			<li>
-				A direction and length in 4D space. In three.js the length will always be the
-				[link:https://en.wikipedia.org/wiki/Euclidean_distance Euclidean distance]
-				(straight-line distance) from (0, 0, 0, 0) to (x, y, z, w) and the direction is also
-				measured from (0, 0, 0, 0) towards (x, y, z, w).
+				一个在四维空间中的方向与长度的定义。在three.js中,长度总是从(0, 0, 0, 0)到(x, y, z, w)的
+				[link:https://en.wikipedia.org/wiki/Euclidean_distance Euclidean distance](欧几里德距离,即直线距离),
+				方向也是从(0, 0, 0, 0)到(x, y, z, w)的方向。
 			</li>
 			<li>
-				Any arbitrary ordered quadruplet of numbers.
+				任意的、有顺序的、四个为一组的数字组合。
 			</li>
 		</ul>
 
 		<p>
-		There are other things a 4D vector can be used to represent, however these are the most common uses in three.js.
+		其他的一些事物也可以使用二维向量进行表示,但以上这些是它在three.js中的常用用途。
 		</p>
 
 
-		<h2>Example</h2>
+		<h2>示例</h2>
 
 		<code>
 var a = new THREE.Vector4( 0, 1, 0, 0 );
@@ -48,26 +48,26 @@ var d = a.dot( b );
 		</code>
 
 
-		<h2>Constructor</h2>
+		<h2>构造函数</h2>
 
 		<h3>[name]( [param:Float x], [param:Float y], [param:Float z], [param:Float w] )</h3>
 		<p>
-		[page:Float x] - the x value of the vector. Default is *0*.<br />
-		[page:Float y] -  the y value of the vector. Default is *0*.<br />
-		[page:Float z] - the z value of the vector. Default is *0*.<br />
-		[page:Float w] - the w value of the vector. Default is *1*.<br /><br />
+		[page:Float x] - 向量的x值,默认为*0*。<br />
+		[page:Float y] - 向量的y值,默认为*0*。<br />
+		[page:Float z] - 向量的z值,默认为*0*。<br />
+		[page:Float w] - 向量的w值,默认为*1*。<br /><br />
 
-		Creates a new [name].
+		创建一个新的[name]。
 		</p>
 
 
-		<h2>Properties</h2>
+		<h2>属性</h2>
 
 		<h3>[property:Boolean isVector4]</h3>
 		<p>
-			Used to check whether this or derived classes are Vector4s. Default is *true*.<br /><br />
+			用于测试这个类或者派生类是否为Vector4,默认为*true*。<br /><br />
 
-			You should not change this, as it is used internally for optimisation.
+			你不应当对这个属性进行改变,因为它在内部使用,以用于优化。
 		</p>
 
 		<h3>[property:Float x]</h3>
@@ -79,252 +79,252 @@ var d = a.dot( b );
 		<h3>[property:Float w]</h3>
 
 
-		<h2>Methods</h2>
+		<h2>方法</h2>
 
 		<h3>[method:this add]( [param:Vector4 v] )</h3>
-		<p>Adds [page:Vector4 v] to this vector.</p>
+		<p>将传入的向量[page:Vector4 v]和这个向量相加。</p>
 
 		<h3>[method:this addScalar]( [param:Float s] )</h3>
-		<p>Adds the scalar value s to this vector's [page:.x x], [page:.y y], [page:.z z] and [page:.w w] values.</p>
+		<p>将传入的标量s和这个向量的[page:.x x]值、[page:.y y]值、[page:.z z]值以及[page:.w w]值相加。</p>
 
 		<h3>[method:this addScaledVector]( [param:Vector4 v], [param:Float s] )</h3>
-		<p>Adds the multiple of [page:Vector4 v] and [page:Float s] to this vector.</p>
+		<p>将所传入的[page:Vector4 v]与[page:Float s]相乘所得的乘积和这个向量相加。</p>
 
 		<h3>[method:this addVectors]( [param:Vector4 a], [param:Vector4 b] )</h3>
-		<p>Sets this vector to [page:Vector4 a] + [page:Vector4 b].</p>
+		<p>将该向量设置为[page:Vector4 a] + [page:Vector4 b].</p>
 
 		<h3>[method:this applyMatrix4]( [param:Matrix4 m] )</h3>
 		<p>
-		Multiplies this vector by 4 x 4 [page:Matrix4 m].
+		将该向量乘以四阶矩阵[page:Matrix4 m]。
 		</p>
 
 		<h3>[method:this ceil]()</h3>
 		<p>
-		The [page:.x x], [page:.y y], [page:.z z] and [page:.w w] components of the vector are rounded up to the nearest integer value.
+		将该向量[page:.x x]分量、 [page:.y y]分量[page:.z z]分量以及[page:.w w]分量向上取整为最接近的整数。
 		</p>
 
 		<h3>[method:this clamp]( [param:Vector4 min], [param:Vector4 max] )</h3>
 		<p>
-		[page:Vector4 min] - the minimum [page:.x x], [page:.y y], [page:.z z] and [page:.w w] values.<br />
-		[page:Vector4 max] - the maximum [page:.x x], [page:.y y], [page:.z z] and [page:.w w] values in the desired range<br /><br />
+		[page:Vector4 min] - 在限制范围内,[page:.x x]值、[page:.y y]值、[page:.z z]值以及[page:.w w]值的最小值<br />
+		[page:Vector4 max] - 在限制范围内,[page:.x x]值、[page:.y y]值、[page:.z z]值以及[page:.w w]值的最大值<br /><br />
 
-		If this vector's x, y, z or w value is greater than the max vector's x, y, z or w value, it is replaced by the corresponding value. <br /><br />
-		If this vector's x, y, z or w value is less than the min vector's x, y, z or w value, it is replaced by the corresponding value.
+		如果该向量的x值、y值、z值或w值大于限制范围内最大x值、y值、z值或w值,则该值将会被所对应的值取代。<br /><br />
+		如果该向量的x值、y值、z值或w值小于限制范围内最小x值、y值、z值或w值,则该值将会被所对应的值取代。
 		</p>
 
 		<h3>[method:this clampLength]( [param:Float min], [param:Float max] )</h3>
 		<p>
-		[page:Float min] - the minimum value the length will be clamped to <br />
-		[page:Float max] - the maximum value the length will be clamped to<br /><br />
+		[page:Float min] - 长度将被限制为的最小值 <br />
+		[page:Float max] - 长度将被限制为的最大值<br /><br />
 
-		If this vector's length is greater than the max value, it is replaced by the max value. <br /><br />
-		If this vector's length is less than the min value, it is replaced by the min value.
+		如果向量长度大于最大值,则它将会被最大值所取代。<br /><br />
+		如果向量长度小于最小值,则它将会被最小值所取代。
 		</p>
 
 		<h3>[method:this clampScalar]( [param:Float min], [param:Float max] )</h3>
 		<p>
-		[page:Float min] - the minimum value the components will be clamped to <br />
-		[page:Float max] - the maximum value the components will be clamped to<br /><br />
+		[page:Float min] - 分量将被限制为的最小值<br />
+		[page:Float max] - 分量将被限制为的最大值<br /><br />
 
-		If this vector's x, y, z or w values are greater than the max value, they are replaced by the max value. <br /><br />
-		If this vector's x, y, z or w values are less than the min value, they are replaced by the min value.
+		如果该向量的x值、y值、z值或w值大于最大值,则它们将被最大值所取代。<br /><br />
+		如果该向量的x值、y值、z值或w值小于最小值,则它们将被最小值所取代。
 		</p>
 
 		<h3>[method:Vector4 clone]()</h3>
 		<p>
-		Returns a new Vector4 with the same [page:.x x], [page:.y y], [page:.z z] and [page:.w w] values as this one.
+		返回一个新的Vector4,其具有和当前这个向量相同的[page:.x x]、[page:.y y]、[page:.z z]和[page:.w w]。
 		</p>
 
 		<h3>[method:this copy]( [param:Vector4 v] )</h3>
 		<p>
-			Copies the values of the passed Vector4's [page:.x x], [page:.y y], [page:.z z] and [page:.w w]
-			properties to this Vector4.
+			将所传入Vector4的[page:.x x]、[page:.y y]、[page:.z z]和[page:.w w]属性复制给这一Vector4。
 		</p>
 
 		<h3>[method:this divideScalar]( [param:Float s] )</h3>
 		<p>
-		Divides this vector by scalar [page:Float s].<br />
-		Sets vector to *( 0, 0, 0, 0 )* if *[page:Float s] = 0*.
+		将该向量除以标量[page:Float s]。<br />
+		如果传入的[page:Float s] = 0,则向量将被设置为*( 0, 0, 0, 0 )*。
 		</p>
 
 		<h3>[method:Float dot]( [param:Vector4 v] )</h3>
 		<p>
-		Calculates the [link:https://en.wikipedia.org/wiki/Dot_product dot product] of this
-		vector and [page:Vector4 v].
+		计算该vector和所传入[page:Vector4 v]
+		的点积([link:https://en.wikipedia.org/wiki/Dot_product dot product])。
 		</p>
 
 		<h3>[method:Boolean equals]( [param:Vector4 v] )</h3>
-		<p>Checks for strict equality of this vector and [page:Vector4 v].</p>
+		<p>检查该向量和[page:Vector4 v]的严格相等性。</p>
 
 		<h3>[method:this floor]()</h3>
-		<p>The components of the vector are rounded down to the nearest integer value.</p>
+		<p>向量的分量向下取整为最接近的整数值。</p>
 
 		<h3>[method:this fromArray]( [param:Array array], [param:Integer offset] )</h3>
 		<p>
-		[page:Array array] - the source array.<br />
-		[page:Integer offset] - (optional) offset into the array. Default is 0.<br /><br />
+		[page:Array array] - 来源矩阵。<br />
+		[page:Integer offset] - (可选)在数组中的元素偏移量,默认值为0。<br /><br />
 
-		Sets this vector's [page:.x x] value to be array[ offset + 0 ], [page:.y y] value to be array[ offset + 1 ]
-		[page:.z z] value to be array[ offset + 2 ] and [page:.w w ] value to be array[ offset + 3 ].
+		设置向量中的[page:.x x]值为array[ offset + 0 ],[page:.y y]值为array[ offset + 1 ],
+		[page:.z z]值为array[ offset + 2 ],[page:.w w ]值为array[ offset + 3 ]。
 		</p>
 
 		<h3>[method:this fromBufferAttribute]( [param:BufferAttribute attribute], [param:Integer index] )</h3>
 		<p>
-		[page:BufferAttribute attribute] - the source attribute.<br />
-		[page:Integer index] - index in the attribute.<br /><br />
+		[page:BufferAttribute attribute] - 来源的attribute。<br />
+		[page:Integer index] - 在attribute中的索引。<br /><br />
 
-		Sets this vector's [page:.x x], [page:.y y], [page:.z z] and [page:.w w] values from the [page:BufferAttribute attribute].
+		从[page:BufferAttribute attribute]中设置向量的[page:.x x]值、[page:.y y]值、[page:.z z]值和[page:.w w]值。
 		</p>
 
 		<h3>[method:Float getComponent]( [param:Integer index] )</h3>
 		<p>
 		[page:Integer index] - 0, 1, 2 or 3.<br /><br />
 
-		If index equals 0 returns the [page:.x x] value. <br />
-		If index equals 1 returns the [page:.y y] value. <br />
-		If index equals 2 returns the [page:.z z] value.<br />
-		If index equals 3 returns the [page:.w w] value.
+		如果index值为0返回[page:.x x]值。 <br />
+		如果index值为1返回[page:.y y]值。 <br />
+		如果index值为2返回[page:.z z]值。<br />
+		如果index值为3返回[page:.w w]值。
 		</p>
 
 		<h3>[method:Float length]()</h3>
-		<p>Computes the [link:https://en.wikipedia.org/wiki/Euclidean_distance Euclidean length]
-		(straight-line length) from (0, 0, 0, 0) to (x, y, z, w).</p>
+		<p>
+		计算从(0, 0, 0, 0) 到 (x, y, z, w)的欧几里得长度
+		([link:https://en.wikipedia.org/wiki/Euclidean_distance Euclidean length],即直线长度)。</p>
 
 		<h3>[method:Float manhattanLength]()</h3>
 		<p>
-		Computes the [link:http://en.wikipedia.org/wiki/Taxicab_geometry Manhattan length] of this vector.
+		计算该向量的曼哈顿长度([link:http://en.wikipedia.org/wiki/Taxicab_geometry Manhattan length])。
 		</p>
 
 		<h3>[method:Float lengthSq]()</h3>
 		<p>
-		Computes the square of the [link:https://en.wikipedia.org/wiki/Euclidean_distance Euclidean length]
-		(straight-line length) from (0, 0, 0, 0) to (x, y, z, w). If you are 	comparing the lengths of
-		vectors, you should compare the length squared instead as it is slightly more efficient to calculate.
+		计算从(0, 0, 0, 0)到(x, y, z, w)的欧几里得长度
+		([link:https://en.wikipedia.org/wiki/Euclidean_distance Euclidean length],即直线长度)的平方。
+		如果你正在比较向量的长度,应当比较的是长度的平方,因为它的计算效率更高一些。
 		</p>
 
 		<h3>[method:this lerp]( [param:Vector4 v], [param:Float alpha] )</h3>
 		<p>
-		[page:Vector4 v] - [page:Vector4] to interpolate towards.<br />
-		alpha - interpolation factor in the closed interval [0, 1].<br /><br />
+		[page:Vector4 v] - 朝着进行插值的[page:Vector4]。<br />
+		alpha - 插值因数,其范围在[0, 1]闭区间。<br /><br />
 
-		Linearly interpolates between this vector and [page:Vector4 v], where alpha is the
-		distance along the line - alpha = 0 will be this vector, and alpha = 1 will be [page:Vector4 v].
+		在该向量与传入的向量[page:Vector4 v]之间的线性插值,alpha是沿着线的距离长度。
+		—— alpha = 0 时表示的是当前向量,alpha = 1 时表示的是所传入的向量[page:Vector4 v]。
 		</p>
 
 		<h3>[method:this lerpVectors]( [param:Vector4 v1], [param:Vector4 v2], [param:Float alpha] )</h3>
 		<p>
-		[page:Vector4 v1] - the starting [page:Vector4].<br />
-		[page:Vector4 v2] - [page:Vector4] to interpolate towards.<br />
-		[page:Float alpha] - interpolation factor in the closed interval [0, 1].<br /><br />
+		[page:Vector4 v1] - 起始的[page:Vector4]。<br />
+		[page:Vector4 v2] - 朝着进行插值的[page:Vector4]。<br />
+		[page:Float alpha] - 插值因数,其范围在[0, 1]闭区间。<br /><br />
 
-		Sets this vector to be the vector linearly interpolated between [page:Vector4 v1] and
-		[page:Vector4 v2] where alpha is the distance along the line connecting the two vectors
-		- alpha = 0 will be [page:Vector4 v1], and alpha = 1 will be [page:Vector4 v2].
+		将此向量设置为在[page:Vector4 v1]和[page:Vector4 v2]之间进行线性插值的向量,
+		其中alpha为两个向量之间连线的距离长度。
+		—— alpha = 0 时表示的是[page:Vector4 v1],alpha = 1 时表示的是[page:Vector4 v2]。
 		</p>
 
 		<h3>[method:this negate]()</h3>
-		<p>Inverts this vector - i.e. sets x = -x, y = -y, z = -z and w = -w.</p>
+		<p>向量取反,即: x = -x, y = -y, z = -z , w = -w。</p>
 
 		<h3>[method:this normalize]()</h3>
 		<p>
-		Converts this vector to a [link:https://en.wikipedia.org/wiki/Unit_vector unit vector] - that is, sets it equal to the vector with the same direction
-		as this one, but [page:.length length] 1.
+		将该向量转换为单位向量([link:https://en.wikipedia.org/wiki/Unit_vector unit vector]),
+		也就是说,将该向量的方向设置为和原向量相同,但是其长度([page:.length length])为1。
 		</p>
 
 		<h3>[method:this max]( [param:Vector4 v] )</h3>
 		<p>
-		If this vector's x, y, z or w value is less than [page:Vector4 v]'s x, y, z or w value, replace
-		that value with the corresponding max value.
+		如果该向量的x值、y值、z值或w值小于所传入[page:Vector4 v]的x值、y值、z值或w值,
+		则将该值替换为对应的最大值。
 		</p>
 
 		<h3>[method:this min]( [param:Vector4 v] )</h3>
 		<p>
-		If this vector's x, y, z or w value is greater than [page:Vector4 v]'s x, y, z or w value, replace
-		that value with the corresponding min value.
+		如果该向量的x值、y值、z值或w值大于所传入[page:Vector4 v]的x值、y值、z值或w值,
+		则将该值替换为对应的最小值。
 		</p>
 
 		<h3>[method:this multiplyScalar]( [param:Float s] )</h3>
-		<p>Multiplies this vector by scalar [page:Float s].</p>
+		<p>将该向量与所传入的标量[page:Float s]进行相乘。</p>
 
 		<h3>[method:this round]()</h3>
-		<p>The components of the vector are rounded to the nearest integer value.</p>
+		<p>向量中的分量四舍五入取整为最接近的整数值。</p>
 
 		<h3>[method:this roundToZero]()</h3>
 		<p>
-		The components of the vector are rounded towards zero (up if negative, down if positive) to an integer value.
+		向量中的分量朝向0取整数(若分量为负数则向上取整,若为正数则向下取整)
 		</p>
 
 		<h3>[method:this set]( [param:Float x], [param:Float y], [param:Float z], [param:Float w] )</h3>
-		<p>Sets the [page:.x x], [page:.y y], [page:.z z] and [page:.w w] components of this vector.</p>
+		<p>设置该向量的[page:.x x]、[page:.y y]、[page:.z z]和[page:.w w]分量。</p>
 
 		<h3>[method:this setAxisAngleFromQuaternion]( [param:Quaterion q] )</h3>
 		<p>
-			[page:Quaterion q] - a normalized [page:Quaterion]<br /><br />
+			[page:Quaterion q] - 归一化的[page:Quaterion](四元数)<br /><br />
+
+			将该向量的[page:.x x]、[page:.y y]和[page:.z z]分量设置为四元数的轴,
+			[page:.w w]分量设置为四元数的角度。
 
-			Sets the [page:.x x], [page:.y y] and [page:.z z] components of this vector to the
-			quaternion's axis and [page:.w w] to the angle.
 		</p>
 
 		<h3>[method:this setAxisAngleFromRotationMatrix]( [param:Matrix4 m] )</h3>
 		<p>
-			 [page:Matrix4 m] - a [page:Matrix4] of which the upper left 3x3 matrix is a pure rotation matrix.<br /><br />
+			[page:Matrix4 m] - 一个[page:Matrix4](四阶矩阵),其左上角3x3的元素表示的是一个纯旋转矩。<br /><br />
 
-			Sets the [page:.x x], [page:.y y] and [page:.z z] to the axis of rotation and [page:.w w] to the angle.
+			将该向量的[page:.x x]、[page:.y y]和[page:.z z]设置为旋转轴,[page:.w w]为角度。
 		</p>
 
 		<h3>[method:null setComponent]( [param:Integer index], [param:Float value] )</h3>
 		<p>
-		[page:Integer index] - 0, 1 or 2.<br />
+		[page:Integer index] - 0、1或2。<br />
 		[page:Float value] - [page:Float]<br /><br />
 
-		If index equals 0 set [page:.x x] to [page:Float value].<br />
-		If index equals 1 set [page:.y y] to [page:Float value].<br />
-		If index equals 2 set [page:.z z] to [page:Float value].<br />
-		If index equals 3 set [page:.w w] to [page:Float value].
+		若index为 0 则设置 [page:.x x] 值为 [page:Float value]。<br />
+		若index为 1 则设置 [page:.y y] 值为 [page:Float value]。<br />
+		若index为 2 则设置 [page:.z z] 值为 [page:Float value]。<br />
+		若index为 3 则设置 [page:.w w] 值为 [page:Float value]。
 		</p>
 
 
 		<h3>[method:this setLength]( [param:Float l] )</h3>
 		<p>
-		Sets this vector to the vector with the same direction as this one, but [page:.length length]
-		[page:Float l].
+		将该向量的方向设置为和原向量相同,但是长度([page:.length length])为[page:Float l]。
 		</p>
 
 		<h3>[method:this setScalar]( [param:Float scalar] )</h3>
 		<p>
-		Sets the [page:.x x], [page:.y y], [page:.z z] and [page:.w w] values of this vector both equal to [page:Float scalar].
+		将该向量的[page:.x x]、[page:.y y]、[page:.z z]值和[page:.w w]同时设置为等于传入的[page:Float scalar]。
 		</p>
 
 		<h3>[method:this setX]( [param:Float x] )</h3>
-		<p>Replaces this vector's [page:.x x] value with [page:Float x].</p>
+		<p>将向量中的[page:.x x]值替换为[page:Float x]。</p>
 
 		<h3>[method:this setY]( [param:Float y] )</h3>
-		<p>Replaces this vector's [page:.y y] value with [page:Float y].</p>
+		<p>将向量中的[page:.y y]值替换为[page:Float y]。</p>
 
 		<h3>[method:this setZ]( [param:Float z] )</h3>
-		<p>Replaces this vector's [page:.z z] value with [page:Float z].</p>
+		<p>将向量中的[page:.z z]值替换为[page:Float z]。</p>
 
 		<h3>[method:this setW]( [param:Float w] )</h3>
-		<p>Replaces this vector's [page:.w w] value with [page:Float w].</p>
+		<p>将向量中的[page:.w w]值替换为[page:Float w]。</p>
 
 		<h3>[method:this sub]( [param:Vector4 v] )</h3>
-		<p>Subtracts [page:Vector4 v] from this vector.</p>
+		<p>从该向量减去向量[page:Vector4 v]。</p>
 
 		<h3>[method:this subScalar]( [param:Float s] )</h3>
-		<p>Subtracts [page:Float s]  from this vector's [page:.x x], [page:.y y], [page:.z z] and [page:.w w] compnents.</p>
+		<p>从该向量的[page:.x x]、[page:.y y]、[page:.z z]和[page:.w w]分量中减去标量[page:Float s]。</p>
 
 		<h3>[method:this subVectors]( [param:Vector4 a], [param:Vector4 b] )</h3>
-		<p>Sets this vector to [page:Vector4 a] - [page:Vector4 b].</p>
+		<p>将该向量设置为[page:Vector4 a] - [page:Vector4 b]。</p>
 
 		<h3>[method:Array toArray]( [param:Array array], [param:Integer offset] )</h3>
 		<p>
-		[page:Array array] - (optional) array to store the vector to. If this is not provided, a new array will be created.<br />
-		[page:Integer offset] - (optional) optional offset into the array.<br /><br />
+		[page:Array array] - (可选)被用于存储向量的数组。如果这个值没有传入,则将创建一个新的数组。<br />
+		[page:Integer offset] - (可选) 数组中元素的偏移量。<br /><br />
 
-		Returns an array [x, y, z, w], or copies x, y, z and w into the provided [page:Array array].
+		返回一个数组[x, y, z, w],或者将x、y、z和w复制到所传入的[page:Array array]中。
 		</p>
 
-		<h2>Source</h2>
+		<h2>源代码</h2>
 
 		[link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js]
 	</body>

+ 7 - 7
docs/api/zh/objects/SkinnedMesh.html

@@ -91,8 +91,8 @@
 		<h2>构造器</h2>
 		<h3>[name]( [param:BufferGeometry geometry], [param:Material material] )</h3>
 		<p>
-    [page:BufferGeometry geometry] —— TODO<br />
-    [page:Material material] —— (可选)一个[page:Material]实例,默认值是一个新的[page:MeshBasicMaterial]。
+    [page:BufferGeometry geometry] —— 一个[page:BufferGeometry]实例。<br />
+    [page:Material material] —— (可选)一个[page:Material]实例,默认值是一个新的[page:MeshBasicMaterial]。
 		</p>
 
 
@@ -111,12 +111,12 @@
 
 		<h3>[property:Matrix4 bindMatrix]</h3>
 		<p>
-		用于绑定骨骼变换的基础矩阵
+			该基础矩阵用于绑定骨骼变换。
 		</p>
 
 		<h3>[property:Matrix4 bindMatrixInverse]</h3>
 		<p>
-		用于重置绑定骨骼变换的基础矩阵
+			该基础矩阵用于重置绑定骨骼变换。
 		</p>
 
 		<h3>[property:Boolean isSkinnedMesh]</h3>
@@ -127,7 +127,7 @@
 
 		<h3>[property:Skeleton skeleton]</h3>
 		<p>
-			TODO
+			用于表示蒙皮网格中骨骼的层次结构的[page:Skeleton](骨架)。
 		</p>
 
 
@@ -138,7 +138,7 @@
 		<h3>[method:null bind]( [param:Skeleton skeleton], [param:Matrix4 bindMatrix] )</h3>
 		<p>
 		[page:Skeleton skeleton] —— 由一棵[page:Bone Bones]树创建的[page:Skeleton]。<br/>
-		[page:Matrix4 bindMatrix] —— 代表着骨架基本变换的[page:Matrix4](4x4矩阵)。<br /><br />
+		[page:Matrix4 bindMatrix] —— 表示骨架基本变换的[page:Matrix4](4x4矩阵)。<br /><br />
 		将骨架绑定到一个蒙皮网格上。bindMatrix会被保存到.bindMatrix属性中,其逆矩阵.bindMatrixInverse也会被计算出来。
 		</p>
 
@@ -149,7 +149,7 @@
 
 		<h3>[method:null normalizeSkinWeights]()</h3>
 		<p>
-		TODO
+		标准化蒙皮的权重。
 		</p>
 
 		<h3>[method:null pose]()</h3>

+ 46 - 0
docs/api/zh/renderers/WebGLMultisampleRenderTarget.html

@@ -0,0 +1,46 @@
+<!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">
+			TODO
+		</p>
+
+
+		<h2>Constructor</h2>
+
+
+		<h3>[name]([param:Number width], [param:Number height], [param:Object options])</h3>
+
+		<p>
+		[page:Float width] - TODO <br />
+		[page:Float height] - TODO<br />
+		[page:Object options] - TODO
+		</p>
+
+		<h2>Properties</h2>
+
+		<h3>[property:Number samples]</h3>
+		<p>
+		TODO
+		</p>
+
+		<p>[page:WebGLRenderTarget WebGLRenderTarget] TODO</p>
+
+		<h2>Methods</h2>
+
+		<p>[page:WebGLRenderTarget WebGLRenderTarget] TODO</p>
+
+		<h2>Source</h2>
+
+		[link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js]
+	</body>
+</html>

+ 5 - 0
docs/api/zh/scenes/Scene.html

@@ -54,6 +54,11 @@
 			使用JSON格式返回场景数据。
 		</p>
 
+		<h3>[method:null dispose]()</h3>
+		<p>
+			清除[page:WebGLRenderer]内部所缓存的场景相关的数据。
+		</p>
+
 		<h2>源代码</h2>
 
 		[link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js]

+ 13 - 0
docs/examples/exporters/GLTFExporter.html

@@ -21,6 +21,19 @@
 		textures, skins, skeletons, morph targets, animations, lights, and/or cameras.
 		</p>
 
+		<h2>Extensions</h2>
+
+		<p>
+			GLTFExporter supports the following
+			[link:https://github.com/KhronosGroup/glTF/tree/master/extensions/ glTF 2.0 extensions]:
+		</p>
+
+		<ul>
+			<li>KHR_lights_punctual</li>
+			<li>KHR_materials_unlit</li>
+			<li>KHR_texture_transform</li>
+		</ul>
+
 		<h2>Example</h2>
 
 		<code>

+ 6 - 3
docs/examples/loaders/GLTFLoader.html

@@ -31,13 +31,16 @@
 			<li>KHR_draco_mesh_compression</li>
 			<li>KHR_materials_pbrSpecularGlossiness</li>
 			<li>KHR_materials_unlit</li>
-			<li>KHR_lights_punctual</li>
-			<li>KHR_texture_transform<sup>*</sup></li>
+			<li>KHR_lights_punctual<sup>1</sup></li>
+			<li>KHR_texture_transform<sup>2</sup></li>
 			<li>MSFT_texture_dds</li>
 		</ul>
 
 		<p><i>
-			<sup>*</sup>UV transforms are supported, with several key limitations. Transforms applied to
+			<sup>1</sup>Requires [link:https://threejs.org/docs/#api/en/renderers/WebGLRenderer.physicallyCorrectLights physicallyCorrectLights] to be enabled.
+		</i></p>
+		<p><i>
+			<sup>2</sup>UV transforms are supported, with several key limitations. Transforms applied to
 			a texture using the first UV slot (all textures except aoMap and lightMap) must share the same
 			transform, or no transfor at all. The aoMap and lightMap textures cannot be transformed. No
 			more than one transform may be used per material. Each use of a texture with a unique

+ 28 - 0
docs/examples/utils/BufferGeometryUtils.html

@@ -45,6 +45,34 @@
 
     </p>
 
+    <h3>[method:InterleavedBufferAttribute interleaveAttributes]( [param:Array attributes] )</h3>
+    <p>
+    attributes -- Array of [page:BufferAttribute BufferAttribute] instances.<br /><br />
+
+    Interleaves a set of attributes and returns a new array of corresponding attributes that share
+    a single InterleavedBuffer instance. All attributes must have compatible types. If merge does not
+    succeed, the method returns null.
+
+    </p>
+
+    <h3>[method:Number estimateBytesUsed]( [param:BufferGeometry geometry] )</h3>
+    <p>
+    geometry -- Instance of [page:BufferGeometry BufferGeometry] to estimate the memory use of.<br /><br />
+
+    Returns the amount of bytes used by all attributes to represent the geometry.
+
+    </p>
+
+    <h3>[method:BufferGeometry mergeVertices]( [param:BufferGeometry geometry], [param:Number tolerance] )</h3>
+    <p>
+    geometry -- Instance of [page:BufferGeometry BufferGeometry] to merge the vertices of.<br />
+    tolerance -- The maximum allowable difference between vertex attributes to merge. Defaults to 1e-4.<br /><br />
+
+    Returns a new [page:BufferGeometry BufferGeometry] with vertices for which all similar vertex attributes
+    (within tolerance) are merged.
+
+    </p>
+
     <h2>Source</h2>
 
     [link:https://github.com/mrdoob/three.js/blob/master/examples/js/utils/BufferGeometryUtils.js examples/js/utils/BufferGeometryUtils.js]

+ 15 - 0
docs/index.html

@@ -82,6 +82,8 @@
 
 				language = value;
 				createNavigation();
+				updateFilter();
+				autoChangeUrlLanguage( language );
 
 			}
 
@@ -239,6 +241,19 @@
 
 			}
 
+			// Auto change language url. If a reader open a document in English, when he click "zh", the document he read will auto change into Chinese version
+
+			function autoChangeUrlLanguage( language ) {
+
+				var hash = location.hash;
+				if ( hash === '' ) return;
+				var docType = hash.substr( 0, hash.indexOf( '/' ) + 1 );
+				var docLink = hash.substr( hash.indexOf( '/' ) + 1 );
+				docLink = docLink.substr( docLink.indexOf( '/' ) );
+				location.href = docType + language + docLink;
+
+			}
+
 
 			// Filtering
 

+ 2 - 0
docs/list.js

@@ -309,6 +309,7 @@ var list = {
 			},
 
 			"Renderers": {
+				"WebGLMultisampleRenderTarget": "api/en/renderers/WebGLMultisampleRenderTarget",
 				"WebGLRenderer": "api/en/renderers/WebGLRenderer",
 				"WebGLRenderTarget": "api/en/renderers/WebGLRenderTarget",
 				"WebGLRenderTargetCube": "api/en/renderers/WebGLRenderTargetCube"
@@ -733,6 +734,7 @@ var list = {
 			},
 
 			"渲染器": {
+				"WebGLMultisampleRenderTarget": "api/zh/renderers/WebGLMultisampleRenderTarget",
 				"WebGLRenderer": "api/zh/renderers/WebGLRenderer",
 				"WebGLRenderTarget": "api/zh/renderers/WebGLRenderTarget",
 				"WebGLRenderTargetCube": "api/zh/renderers/WebGLRenderTargetCube"

+ 2 - 0
docs/manual/en/introduction/How-to-use-WebGL2.html

@@ -101,6 +101,7 @@ var material = new THREE.ShaderMaterial( {
 
 		[example:webgl2_materials_texture3d WebGL2 / materials / texture3d]<br />
 		[example:webgl2_materials_texture3d_volume WebGL2 / materials / texture3d / volume]<br />
+		[example:webgl2_multisampled_renderbuffers WebGL2 / multisampled renderbuffers]
 	</p>
 
 	<h2>Supported features</h2>
@@ -110,6 +111,7 @@ var material = new THREE.ShaderMaterial( {
 		overview about what's already available in the latest version of three.js.
 		<ul>
 			<li>3D Textures</li>
+			<li>Multisampled Renderbuffers</li>
 		</ul>
 
 	</p>

+ 6 - 2
docs/manual/en/introduction/Useful-links.html

@@ -112,7 +112,7 @@
 	 <h2>Tools</h2>
 	 <ul>
 		 <li>
-			[link:http://www.physgl.org/ physgl.org] - javascript front-end with wrappers to three.js, to bring WebGL
+			[link:http://www.physgl.org/ physgl.org] - JavaScript front-end with wrappers to three.js, to bring WebGL
  			graphics to students learning physics and math.
 		 </li>
 		 <li>
@@ -125,12 +125,16 @@
 		<li>
 			[link:http://idflood.github.io/ThreeNodes.js/ ThreeNodes.js].
 		</li>
+		<li>
+			<a href="https://marketplace.visualstudio.com/items?itemName=bierner.comment-tagged-templates" target="_blank">comment-tagged-templates</a> -
+			VSCode extension syntax highlighting for tagged template strings, like: glsl.js.
+		</li>
 	 </ul>
 
 	<h2>WebGL References</h2>
 	 <ul>
 		 <li>
-			[link:https://www.khronos.org/files/webgl/webgl-reference-card-1_0.pdf] - Reference of all WebGL and GLSL keywords, terminology, syntex and definations.
+			[link:https://www.khronos.org/files/webgl/webgl-reference-card-1_0.pdf] - Reference of all WebGL and GLSL keywords, terminology, syntax and definitions.
 		 </li>
 	 </ul>
 

+ 11 - 9
docs/manual/en/introduction/WebGL-compatibility-check.html

@@ -19,16 +19,18 @@
 			to your javascript and run the following before attempting to render anything.
 		</p>
 
-<code>
-if (WEBGL.isWebGLAvailable()) {
-    // Initiate function or other initializations here
-    animate();
-} else {
-    var warning = WEBGL.getWebGLErrorMessage();
-    document.getElementById('container').appendChild(warning);
-}
-</code>
+		<code>
+		if ( WEBGL.isWebGLAvailable() ) {
 
+			// Initiate function or other initializations here
+			animate();
 
+		} else {
+
+			var warning = WEBGL.getWebGLErrorMessage();
+			document.getElementById( 'container' ).appendChild( warning );
+
+		}
+		</code>
 	</body>
 </html>

+ 7 - 7
docs/manual/zh/introduction/Creating-a-scene.html

@@ -10,11 +10,11 @@
 	<body>
 		<h1>创建一个场景([name])</h1><br />
 
-		<p>这一部分将对three.js来做一个简要的介绍。在这一部分里,我们将以搭建一个包含有旋转立方体的场景。在页面下方有一个已经完成的例子,当你遇到麻烦,或者需要帮助的时候,可以看一看。</p>
+		<p>这一部分将对three.js来做一个简要的介绍;我们将开始搭建一个的场景,其中包含一个正在旋转的立方体。页面下方有一个已经完成的例子,当你遇到麻烦,或者需要帮助的时候,可以看一看。</p>
 
 		<h2>开始之前</h2>
 		<p>
-			在开始使用three.js之前,你需要一个地方来显示它。将下列HTML代码保存为你电脑上的一个HTML文件,同时将[link:https://threejs.org/build/three.js three.js]复制到该HTML文件所在的目录下的js/目录下,然后在你的浏览器中打开这个HTML文件。
+			在开始使用three.js之前,你需要一个地方来显示它。将下列HTML代码保存为你电脑上的一个HTML文件,同时将[link:https://threejs.org/build/three.js three.js]复制到该HTML文件所在的目录下的js/目录下,然后在你的浏览器中打开这个HTML文件。
 		</p>
 		<code>
 		&lt;!DOCTYPE html&gt;
@@ -69,7 +69,7 @@
 
 		<p>最后,我们将<strong>renderer</strong>(渲染器)这个元素添加到我们的HTML文档中,这也就是渲染器使用&lt;canvas&gt;元素来将场景展现给我们。</p>
 
-		<p><em>“嗯,看起来很不错,那你说的那个立方体在哪儿?”</em>我们接下来来对它继续进行添加。</p>
+		<p><em>“嗯,看起来很不错,那你说的那个立方体在哪儿?”</em>接下来,我们就来对它继续进行添加。</p>
 
 		<code>
 		var geometry = new THREE.BoxGeometry( 1, 1, 1 );
@@ -80,9 +80,9 @@
 		camera.position.z = 5;
 		</code>
 
-		<p>要创建一个立方体,我们需要一个<strong>BoxGeometry</strong>(立方体)对象. 这个对象包含了一个立方体中所有的顶点(<strong>vertices</strong>)和面<strong>faces</strong>。未来我们将在这方面进行更多的探索。</p>
+		<p>要创建一个立方体,我们需要一个<strong>BoxGeometry</strong>(立方体)对象. 这个对象包含了一个立方体中所有的顶点(<strong>vertices</strong>)和面<strong>faces</strong>。未来我们将在这方面进行更多的探索。</p>
 
-		<p>接下来,对于这个立方体,我们需要给它一个材质,来让它有颜色。Three.js自带了几种材质,在这里我们使用的是<strong>MeshBasicMaterial</strong>。所有的材质是都一个将会被应用于立方体的属性对象。在这里为了简单起见,我们只设置一个color属性,值为<strong>0x00ff00</strong>,也就是绿色。这里所做的事情,就相当于是在CSS或者Photoshop中使用十六进制(<strong>hex colors</strong>)的颜色格式来设置颜色。</p>
+		<p>接下来,对于这个立方体,我们需要给它一个材质,来让它有颜色。Three.js自带了几种材质,在这里我们使用的是<strong>MeshBasicMaterial</strong>。所有的材质是都一个将会被应用于立方体的属性对象。在这里为了简单起见,我们只设置一个color属性,值为<strong>0x00ff00</strong>,也就是绿色。这里所做的事情,就相当于是在CSS或者Photoshop中使用十六进制(<strong>hex colors</strong>)的颜色格式来设置颜色。</p>
 
 		<p>第三步,我们需要一个<strong>Mesh</strong>(网格)。 网格是包含有一个几何体以及应用在在此几何体上的材质的对象,我们可以直接将网格对象放入到我们的场景中,并让它在场景中自由移动。</p>
 
@@ -105,7 +105,7 @@
 		<h2>使立方体动起来</h2>
 
 		<p>
-			在开始之前,如果你已经将上面的代码写入到了你所创建的文件中,你应当已经可以看到一个绿色的立方体。让我们来做一些更加有趣的事——让它旋转起来。</p>
+			在开始之前,如果你已经将上面的代码写入到了你所创建的文件中,你应当已经可以看到一个绿色的立方体。让我们来做一些更加有趣的事 —— 让它旋转起来。</p>
 
 		<p>将下列代码添加到animate()函数中<strong>renderer.render</strong>调用的上方:</p>
 
@@ -114,7 +114,7 @@
 		cube.rotation.y += 0.01;
 		</code>
 
-		<p>这一段代码将在每一帧时被渲染时调用(正常情况下是60次/秒),这就让立方体有了一个看起来很不错的旋转动画。基本上来说,当应用程序运行时,如果你想要移动或者改变任何场景中的东西,都必须要经过这个动画循环。当然,在这个动画循环函数里,你也可以调用别的函数,这样你在写<strong>animate</strong>函数的时候,这样你在写animate函数的时候,就不用在这里以成千上万的代码来结尾了。</p>
+		<p>这一段代码将在每一帧时被渲染时调用(正常情况下是60次/秒),这就让立方体有了一个看起来很不错的旋转动画。基本上来说,当应用程序运行时,如果你想要移动或者改变任何场景中的东西,都必须要经过这个动画循环。当然,在这个动画循环函数里,你也可以调用别的函数,这样你在写<strong>animate</strong>函数的时候,就不用在这里以成千上万的代码来结尾了。</p>
 
 		<h2>结果</h2>
 		<p>祝贺你!你现在已经成功完成了你的第一个Three.js应用程序。虽然它很简单,但现在你已经有了一个入门的起点。</p>

+ 2 - 2
docs/manual/zh/introduction/How-to-run-things-locally.html

@@ -25,10 +25,10 @@
 
 			<ol>
 				<li>
-                    在浏览器中改变本地文件的安全策略,这将使你可以通过<code>file:///yourFile.html</code>来直接运行*本地文件系统*中的文件。
+                    在浏览器中改变本地文件的安全策略,这将使你可以通过<code>file:///yourFile.html</code>来直接运行本地文件系统中的文件。
 				</li>
 				<li>
-                    从本地的服务器运行文件,这可以让你通过<code>http://localhost/yourFile.html</code>来访问运行在*本地服务器*上的文件。
+                    从本地的服务器运行文件,这可以让你通过<code>http://localhost/yourFile.html</code>来访问运行在本地服务器上的文件。
 				</li>
 			</ol>
 

+ 2 - 0
docs/manual/zh/introduction/How-to-use-WebGL2.html

@@ -99,6 +99,7 @@ var material = new THREE.ShaderMaterial( {
 
 		[example:webgl2_materials_texture3d WebGL2 / materials / texture3d]<br />
 		[example:webgl2_materials_texture3d_volume WebGL2 / materials / texture3d / volume]<br />
+		[example:webgl2_multisampled_renderbuffers WebGL2 / multisampled renderbuffers]
 	</p>
 
 	<h2>支持的特性</h2>
@@ -108,6 +109,7 @@ var material = new THREE.ShaderMaterial( {
 		下列列表展现了在最新版本three.js中,已可用的特性的概览。
 		<ul>
 			<li>3D Textures</li>
+			<li>Multisampled Renderbuffers</li>
 		</ul>
 
 	</p>

+ 2 - 2
docs/manual/zh/introduction/Useful-links.html

@@ -109,7 +109,7 @@
 	 <h2>工具</h2>
 	 <ul>
 		 <li>
-			[link:http://www.physgl.org/ physgl.org] - javascript front-end with wrappers to three.js, to bring WebGL
+			[link:http://www.physgl.org/ physgl.org] - JavaScript front-end with wrappers to three.js, to bring WebGL
  			graphics to students learning physics and math.
 		 </li>
 		 <li>
@@ -127,7 +127,7 @@
 	<h2>WebGL参考</h2>
 	 <ul>
 		 <li>
-			[link:https://www.khronos.org/files/webgl/webgl-reference-card-1_0.pdf] - Reference of all WebGL and GLSL keywords, terminology, syntex and definations.
+			[link:https://www.khronos.org/files/webgl/webgl-reference-card-1_0.pdf] - Reference of all WebGL and GLSL keywords, terminology, syntax and definitions.
 		 </li>
 	 </ul>
 

+ 8 - 0
docs/scenes/js/geometry.js

@@ -6,6 +6,14 @@ var twoPi = Math.PI * 2;
 
 function updateGroupGeometry( mesh, geometry ) {
 
+	if ( geometry.isGeometry ) {
+
+		geometry = new THREE.BufferGeometry().fromGeometry( geometry );
+
+		console.warn( 'THREE.GeometryBrowser: Converted Geometry to BufferGeometry.' );
+
+	}
+
 	mesh.children[ 0 ].geometry.dispose();
 	mesh.children[ 1 ].geometry.dispose();
 

+ 17 - 66
docs/scenes/js/material.js

@@ -23,7 +23,6 @@ var constants = {
 	colors: {
 
 		'THREE.NoColors': THREE.NoColors,
-		'THREE.FaceColors': THREE.FaceColors,
 		'THREE.VertexColors': THREE.VertexColors
 
 	},
@@ -128,51 +127,19 @@ var textureMapKeys = getObjectsKeys( textureMaps );
 
 function generateVertexColors( geometry ) {
 
-	for ( var i = 0, il = geometry.faces.length; i < il; i ++ ) {
-
-		geometry.faces[ i ].vertexColors.push( new THREE.Color().setHSL(
-			i / il * Math.random(),
-			0.5,
-			0.5
-		) );
-		geometry.faces[ i ].vertexColors.push( new THREE.Color().setHSL(
-			i / il * Math.random(),
-			0.5,
-			0.5
-		) );
-		geometry.faces[ i ].vertexColors.push( new THREE.Color().setHSL(
-			i / il * Math.random(),
-			0.5,
-			0.5
-		) );
-
-		geometry.faces[ i ].color = new THREE.Color().setHSL(
-			i / il * Math.random(),
-			0.5,
-			0.5
-		);
+	var positionAttribute = geometry.attributes.position;
 
-	}
-
-}
-
-function generateMorphTargets( mesh, geometry ) {
-
-	var vertices = [], scale;
-
-	for ( var i = 0; i < geometry.vertices.length; i ++ ) {
-
-		vertices.push( geometry.vertices[ i ].clone() );
+	var colors = [];
+	var color = new THREE.Color();
 
-		scale = 1 + Math.random() * 0.3;
+	for ( var i = 0, il = positionAttribute.count; i < il; i ++ ) {
 
-		vertices[ vertices.length - 1 ].x *= scale;
-		vertices[ vertices.length - 1 ].y *= scale;
-		vertices[ vertices.length - 1 ].z *= scale;
+		color.setHSL( i / il * Math.random(), 0.5, 0.5 );
+		colors.push( color.r, color.g, color.b );
 
 	}
 
-	geometry.morphTargets.push( { name: 'target1', vertices: vertices } );
+	geometry.addAttribute( 'color', new THREE.Float32BufferAttribute( colors, 3 ) );
 
 }
 
@@ -196,23 +163,12 @@ function needsUpdate( material, geometry ) {
 
 	return function () {
 
-		material.vertexColors = + material.vertexColors; //Ensure number
-		material.side = + material.side; //Ensure number
-		material.needsUpdate = true;
-		geometry.verticesNeedUpdate = true;
-		geometry.normalsNeedUpdate = true;
-		geometry.colorsNeedUpdate = true;
-
-	};
-
-}
-
-function updateMorphs( torus, material ) {
-
-	return function () {
-
-		torus.updateMorphTargets();
+		material.vertexColors = parseInt( material.vertexColors ); //Ensure number
+		material.side = parseInt( material.side ); //Ensure number
 		material.needsUpdate = true;
+		geometry.attributes.position.needsUpdate = true;
+		geometry.attributes.normal.needsUpdate = true;
+		geometry.attributes.color.needsUpdate = true;
 
 	};
 
@@ -329,8 +285,7 @@ function guiMeshBasicMaterial( gui, mesh, material, geometry ) {
 	folder.add( data, 'map', textureMapKeys ).onChange( updateTexture( material, 'map', textureMaps ) );
 	folder.add( data, 'specularMap', textureMapKeys ).onChange( updateTexture( material, 'specularMap', textureMaps ) );
 	folder.add( data, 'alphaMap', textureMapKeys ).onChange( updateTexture( material, 'alphaMap', textureMaps ) );
-	folder.add( material, 'morphTargets' ).onChange( updateMorphs( mesh, material ) );
-	folder.add( material, 'combine', constants.combine ).onChange( updateMorphs( mesh, material ) );
+	folder.add( material, 'combine', constants.combine );
 	folder.add( material, 'reflectivity', 0, 1 );
 	folder.add( material, 'refractionRatio', 0, 1 );
 
@@ -342,7 +297,6 @@ function guiMeshDepthMaterial( gui, mesh, material, geometry ) {
 
 	folder.add( material, 'wireframe' );
 	folder.add( material, 'wireframeLinewidth', 0, 10 );
-	folder.add( material, 'morphTargets' ).onChange( updateMorphs( mesh, material ) );
 
 }
 
@@ -353,7 +307,6 @@ function guiMeshNormalMaterial( gui, mesh, material, geometry ) {
 	folder.add( material, 'flatShading' ).onChange( needsUpdate( material, geometry ) );
 	folder.add( material, 'wireframe' );
 	folder.add( material, 'wireframeLinewidth', 0, 10 );
-	folder.add( material, 'morphTargets' ).onChange( updateMorphs( mesh, material ) );
 
 }
 
@@ -399,11 +352,9 @@ function guiMeshLambertMaterial( gui, mesh, material, geometry ) {
 	folder.add( data, 'map', textureMapKeys ).onChange( updateTexture( material, 'map', textureMaps ) );
 	folder.add( data, 'specularMap', textureMapKeys ).onChange( updateTexture( material, 'specularMap', textureMaps ) );
 	folder.add( data, 'alphaMap', textureMapKeys ).onChange( updateTexture( material, 'alphaMap', textureMaps ) );
-	folder.add( material, 'morphTargets' ).onChange( updateMorphs( mesh, material ) );
-	folder.add( material, 'combine', constants.combine ).onChange( updateMorphs( mesh, material ) );
+	folder.add( material, 'combine', constants.combine );
 	folder.add( material, 'reflectivity', 0, 1 );
 	folder.add( material, 'refractionRatio', 0, 1 );
-	//folder.add( material, 'skinning' );
 
 }
 
@@ -430,7 +381,7 @@ function guiMeshPhongMaterial( gui, mesh, material, geometry ) {
 	folder.add( material, 'flatShading' ).onChange( needsUpdate( material, geometry ) );
 	folder.add( material, 'wireframe' );
 	folder.add( material, 'wireframeLinewidth', 0, 10 );
-	folder.add( material, 'vertexColors', constants.colors );
+	folder.add( material, 'vertexColors', constants.colors ).onChange( needsUpdate( material, geometry ) );
 	folder.add( material, 'fog' );
 	folder.add( data, 'envMaps', envMapKeys ).onChange( updateTexture( material, 'envMap', envMaps ) );
 	folder.add( data, 'map', textureMapKeys ).onChange( updateTexture( material, 'map', textureMaps ) );
@@ -462,7 +413,7 @@ function guiMeshStandardMaterial( gui, mesh, material, geometry ) {
 	folder.add( material, 'flatShading' ).onChange( needsUpdate( material, geometry ) );
 	folder.add( material, 'wireframe' );
 	folder.add( material, 'wireframeLinewidth', 0, 10 );
-	folder.add( material, 'vertexColors', constants.colors );
+	folder.add( material, 'vertexColors', constants.colors ).onChange( needsUpdate( material, geometry ) );
 	folder.add( material, 'fog' );
 	folder.add( data, 'envMaps', envMapKeys ).onChange( updateTexture( material, 'envMap', envMaps ) );
 	folder.add( data, 'map', textureMapKeys ).onChange( updateTexture( material, 'map', textureMaps ) );
@@ -498,7 +449,7 @@ function guiMeshPhysicalMaterial( gui, mesh, material, geometry ) {
 	folder.add( material, 'flatShading' ).onChange( needsUpdate( material, geometry ) );
 	folder.add( material, 'wireframe' );
 	folder.add( material, 'wireframeLinewidth', 0, 10 );
-	folder.add( material, 'vertexColors', constants.colors );
+	folder.add( material, 'vertexColors', constants.colors ).onChange( needsUpdate( material, geometry ) );
 	folder.add( material, 'fog' );
 	folder.add( data, 'envMaps', envMapKeys ).onChange( updateTexture( material, 'envMap', envMaps ) );
 	folder.add( data, 'map', textureMapKeys ).onChange( updateTexture( material, 'map', textureMaps ) );

+ 3 - 10
docs/scenes/material-browser.html

@@ -71,15 +71,14 @@
 
 			guiScene( gui, scene, camera );
 
-			var geometry = new THREE.TorusKnotGeometry( 10, 3, 100, 16 );
-			var mesh = new THREE.Mesh( geometry );
+			var geometry = new THREE.TorusKnotBufferGeometry( 10, 3, 100, 16 );
+			geometry = geometry.toNonIndexed();
 
 			generateVertexColors( geometry );
 
+			var mesh = new THREE.Mesh( geometry );
 			mesh.material = chooseFromHash( gui, mesh, geometry );
 
-			generateMorphTargets( mesh, geometry );
-
 			scene.add( mesh );
 
 			var prevFog = false;
@@ -100,12 +99,6 @@
 
 				}
 
-				if ( mesh.morphTargetInfluences ) {
-
-					mesh.morphTargetInfluences[ 0 ] = ( 1 + Math.sin( 4 * time ) ) / 2;
-
-				}
-
 				renderer.render( scene, camera );
 
 			};

+ 6 - 6
editor/examples/arkanoid.app.json

@@ -39,7 +39,7 @@
 		"geometries": [
 			{
 				"uuid": "BBEE74D1-E43D-4C32-A9F3-4656E78C26F3",
-				"type": "PlaneGeometry",
+				"type": "PlaneBufferGeometry",
 				"width": 30,
 				"height": 40,
 				"widthSegments": 1,
@@ -47,7 +47,7 @@
 			},
 			{
 				"uuid": "C1722F5F-89AD-45D8-B78C-D1D34AF2A012",
-				"type": "BoxGeometry",
+				"type": "BoxBufferGeometry",
 				"width": 2,
 				"height": 1,
 				"depth": 1,
@@ -57,7 +57,7 @@
 			},
 			{
 				"uuid": "327EFFCF-649C-4EF3-86D4-B422C5A86E89",
-				"type": "CylinderGeometry",
+				"type": "CylinderBufferGeometry",
 				"radiusTop": 0.5,
 				"radiusBottom": 0.5,
 				"height": 2,
@@ -67,7 +67,7 @@
 			},
 			{
 				"uuid": "0791211B-BB02-4E57-82B5-64C05DE92B39",
-				"type": "SphereGeometry",
+				"type": "SphereBufferGeometry",
 				"radius": 0.5,
 				"widthSegments": 32,
 				"heightSegments": 16,
@@ -78,7 +78,7 @@
 			},
 			{
 				"uuid": "73F12A47-9EA7-47FD-BCF3-89B8219B2626",
-				"type": "BoxGeometry",
+				"type": "BoxBufferGeometry",
 				"width": 2,
 				"height": 1,
 				"depth": 1,
@@ -88,7 +88,7 @@
 			},
 			{
 				"uuid": "3BDEB9FB-BDD4-44AD-8A47-008BED1C8982",
-				"type": "CylinderGeometry",
+				"type": "CylinderBufferGeometry",
 				"radiusTop": 0.5,
 				"radiusBottom": 0.5,
 				"height": 2,

+ 4 - 4
editor/examples/camera.app.json

@@ -39,7 +39,7 @@
 		"geometries": [
 			{
 				"uuid": "6D90C4BE-EBA6-4E21-8F54-7CFDAA61F30B",
-				"type": "PlaneGeometry",
+				"type": "PlaneBufferGeometry",
 				"width": 10,
 				"height": 10,
 				"widthSegments": 1,
@@ -47,7 +47,7 @@
 			},
 			{
 				"uuid": "D3008B2A-ACDD-43CC-87F7-4F942607D21A",
-				"type": "BoxGeometry",
+				"type": "BoxBufferGeometry",
 				"width": 1,
 				"height": 1,
 				"depth": 1,
@@ -57,7 +57,7 @@
 			},
 			{
 				"uuid": "F482ACD4-013A-49CF-AE0F-C9FF4ADAE409",
-				"type": "CylinderGeometry",
+				"type": "CylinderBufferGeometry",
 				"radiusTop": 0,
 				"radiusBottom": 0.4,
 				"height": 0.75,
@@ -67,7 +67,7 @@
 			},
 			{
 				"uuid": "51CDDCED-BC71-4B1B-A485-725B6A48204B",
-				"type": "IcosahedronGeometry",
+				"type": "IcosahedronBufferGeometry",
 				"radius": 0.4,
 				"detail": 2
 			}],

+ 1 - 1
editor/examples/particles.app.json

@@ -39,7 +39,7 @@
 		"geometries": [
 			{
 				"uuid": "C3C0CE7D-10B8-43FC-8F74-011CC6E57800",
-				"type": "PlaneGeometry",
+				"type": "PlaneBufferGeometry",
 				"width": 100,
 				"height": 100,
 				"widthSegments": 1,

+ 4 - 4
editor/examples/pong.app.json

@@ -39,7 +39,7 @@
 		"geometries": [
 			{
 				"uuid": "490CEBA3-6A25-4BE1-B517-C5FB11A5D18A",
-				"type": "PlaneGeometry",
+				"type": "PlaneBufferGeometry",
 				"width": 6,
 				"height": 4,
 				"widthSegments": 1,
@@ -47,7 +47,7 @@
 			},
 			{
 				"uuid": "D9A92F2D-2F08-4851-99C7-12D8D1CA13C7",
-				"type": "BoxGeometry",
+				"type": "BoxBufferGeometry",
 				"width": 0.1,
 				"height": 0.1,
 				"depth": 0.1,
@@ -57,7 +57,7 @@
 			},
 			{
 				"uuid": "5E63B8CF-E225-4ABC-994A-4D06BD4E21EB",
-				"type": "BoxGeometry",
+				"type": "BoxBufferGeometry",
 				"width": 0.2,
 				"height": 0.2,
 				"depth": 1,
@@ -67,7 +67,7 @@
 			},
 			{
 				"uuid": "D61532B4-24C3-4BC4-B56B-7245E8163E09",
-				"type": "BoxGeometry",
+				"type": "BoxBufferGeometry",
 				"width": 0.2,
 				"height": 0.2,
 				"depth": 1,

+ 1 - 1
editor/examples/shaders.app.json

@@ -39,7 +39,7 @@
 		"geometries": [
 			{
 				"uuid": "EA781333-F3AE-470D-9110-A9724FCB42AA",
-				"type": "IcosahedronGeometry",
+				"type": "IcosahedronBufferGeometry",
 				"radius": 1,
 				"detail": 4
 			}],

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

@@ -125,7 +125,7 @@ Menubar.Add = function ( editor ) {
 	option.setTextContent( strings.getKey( 'menubar/add/icosahedron' )  );
 	option.onClick( function () {
 
-		var geometry = new THREE.IcosahedronGeometry( 1, 0 );
+		var geometry = new THREE.IcosahedronBufferGeometry( 1, 0 );
 		var mesh = new THREE.Mesh( geometry, new THREE.MeshStandardMaterial() );
 		mesh.name = 'Icosahedron';
 

+ 1 - 1
editor/js/libs/three.html.js

@@ -34,7 +34,7 @@
 
  	var texture = new THREE.HTMLTexture( dom );
 
- 	var geometry = new THREE.PlaneGeometry( texture.image.width * 0.05, texture.image.height * 0.05 );
+ 	var geometry = new THREE.PlaneBufferGeometry( texture.image.width * 0.05, texture.image.height * 0.05 );
  	var material = new THREE.MeshBasicMaterial( { map: texture } );
 
  	THREE.Mesh.call( this, geometry, material );

+ 2 - 0
examples/files.js

@@ -19,6 +19,7 @@ var files = {
 		"webgl_effects_peppersghost",
 		"webgl_effects_stereo",
 		"webgl_framebuffer_texture",
+		"webgl_furnace_test",
 		"webgl_geometries",
 		"webgl_geometries_parametric",
 		"webgl_geometry_colors",
@@ -316,6 +317,7 @@ var files = {
 	"webgl2": [
 		"webgl2_materials_texture3d",
 		"webgl2_materials_texture3d_volume",
+		"webgl2_multisampled_renderbuffers",
 		"webgl2_sandbox"
 	],
 	"webaudio": [

+ 1 - 1
examples/js/Ocean.js

@@ -120,7 +120,7 @@ THREE.Ocean = function ( renderer, camera, scene, options ) {
 	var initialSpectrumUniforms = THREE.UniformsUtils.clone( initialSpectrumShader.uniforms );
 	this.materialInitialSpectrum = new THREE.ShaderMaterial( {
 		uniforms: initialSpectrumUniforms,
-		vertexShader: fullscreeenVertexShader.vertexShader,
+		vertexShader: initialSpectrumShader.vertexShader,
 		fragmentShader: initialSpectrumShader.fragmentShader
 	} );
 	this.materialInitialSpectrum.uniforms.u_wind = { value: new THREE.Vector2() };

+ 0 - 4
examples/js/ShaderSkin.js

@@ -16,7 +16,6 @@ THREE.ShaderSkin = {
 	//		- specular map
 	//		- point, directional and hemisphere lights (use with "lights: true" material option)
 	//		- fog (use with "fog: true" material option)
-	//		- shadow maps
 	//
 	// ------------------------------------------------------------------------------------------ */
 
@@ -85,7 +84,6 @@ THREE.ShaderSkin = {
 			THREE.ShaderChunk[ "bsdfs" ],
 			THREE.ShaderChunk[ "packing" ],
 			THREE.ShaderChunk[ "lights_pars_begin" ],
-			THREE.ShaderChunk[ "shadowmap_pars_fragment" ],
 			THREE.ShaderChunk[ "fog_pars_fragment" ],
 			THREE.ShaderChunk[ "bumpmap_pars_fragment" ],
 
@@ -265,7 +263,6 @@ THREE.ShaderSkin = {
 
 			THREE.ShaderChunk[ "common" ],
 			THREE.ShaderChunk[ "lights_pars_begin" ],
-			THREE.ShaderChunk[ "shadowmap_pars_vertex" ],
 			THREE.ShaderChunk[ "fog_pars_vertex" ],
 
 			"void main() {",
@@ -281,7 +278,6 @@ THREE.ShaderSkin = {
 
 				"gl_Position = projectionMatrix * mvPosition;",
 
-				THREE.ShaderChunk[ "shadowmap_vertex" ],
 				THREE.ShaderChunk[ "fog_vertex" ],
 
 			"}"

+ 87 - 45
examples/js/controls/FirstPersonControls.js

@@ -7,7 +7,6 @@
 THREE.FirstPersonControls = function ( object, domElement ) {
 
 	this.object = object;
-	this.target = new THREE.Vector3( 0, 0, 0 );
 
 	this.domElement = ( domElement !== undefined ) ? domElement : document;
 
@@ -35,11 +34,6 @@ THREE.FirstPersonControls = function ( object, domElement ) {
 	this.mouseX = 0;
 	this.mouseY = 0;
 
-	this.lat = 0;
-	this.lon = 0;
-	this.phi = 0;
-	this.theta = 0;
-
 	this.moveForward = false;
 	this.moveBackward = false;
 	this.moveLeft = false;
@@ -50,6 +44,17 @@ THREE.FirstPersonControls = function ( object, domElement ) {
 	this.viewHalfX = 0;
 	this.viewHalfY = 0;
 
+	// private variables
+
+	var lat = 0;
+	var lon = 0;
+
+	var lookDirection = new THREE.Vector3();
+	var spherical = new THREE.Spherical();
+	var target = new THREE.Vector3();
+
+	//
+
 	if ( this.domElement !== document ) {
 
 		this.domElement.setAttribute( 'tabindex', - 1 );
@@ -184,74 +189,97 @@ THREE.FirstPersonControls = function ( object, domElement ) {
 
 	};
 
-	this.update = function ( delta ) {
-
-		if ( this.enabled === false ) return;
-
-		if ( this.heightSpeed ) {
+	this.lookAt = function ( x, y, z ) {
 
-			var y = THREE.Math.clamp( this.object.position.y, this.heightMin, this.heightMax );
-			var heightDelta = y - this.heightMin;
+		if ( x.isVector3 ) {
 
-			this.autoSpeedFactor = delta * ( heightDelta * this.heightCoef );
+			target.copy( x );
 
 		} else {
 
-			this.autoSpeedFactor = 0.0;
+			target.set( x, y, z );
 
 		}
 
-		var actualMoveSpeed = delta * this.movementSpeed;
+		this.object.lookAt( target );
 
-		if ( this.moveForward || ( this.autoForward && ! this.moveBackward ) ) this.object.translateZ( - ( actualMoveSpeed + this.autoSpeedFactor ) );
-		if ( this.moveBackward ) this.object.translateZ( actualMoveSpeed );
+		setOrientation( this );
 
-		if ( this.moveLeft ) this.object.translateX( - actualMoveSpeed );
-		if ( this.moveRight ) this.object.translateX( actualMoveSpeed );
+		return this;
 
-		if ( this.moveUp ) this.object.translateY( actualMoveSpeed );
-		if ( this.moveDown ) this.object.translateY( - actualMoveSpeed );
+	};
 
-		var actualLookSpeed = delta * this.lookSpeed;
+	this.update = function () {
 
-		if ( ! this.activeLook ) {
+		var targetPosition = new THREE.Vector3();
 
-			actualLookSpeed = 0;
+		return function update( delta ) {
 
-		}
+			if ( this.enabled === false ) return;
 
-		var verticalLookRatio = 1;
+			if ( this.heightSpeed ) {
 
-		if ( this.constrainVertical ) {
+				var y = THREE.Math.clamp( this.object.position.y, this.heightMin, this.heightMax );
+				var heightDelta = y - this.heightMin;
 
-			verticalLookRatio = Math.PI / ( this.verticalMax - this.verticalMin );
+				this.autoSpeedFactor = delta * ( heightDelta * this.heightCoef );
 
-		}
+			} else {
 
-		this.lon += this.mouseX * actualLookSpeed;
-		if ( this.lookVertical ) this.lat -= this.mouseY * actualLookSpeed * verticalLookRatio;
+				this.autoSpeedFactor = 0.0;
 
-		this.lat = Math.max( - 85, Math.min( 85, this.lat ) );
-		this.phi = THREE.Math.degToRad( 90 - this.lat );
+			}
 
-		this.theta = THREE.Math.degToRad( this.lon );
+			var actualMoveSpeed = delta * this.movementSpeed;
 
-		if ( this.constrainVertical ) {
+			if ( this.moveForward || ( this.autoForward && ! this.moveBackward ) ) this.object.translateZ( - ( actualMoveSpeed + this.autoSpeedFactor ) );
+			if ( this.moveBackward ) this.object.translateZ( actualMoveSpeed );
 
-			this.phi = THREE.Math.mapLinear( this.phi, 0, Math.PI, this.verticalMin, this.verticalMax );
+			if ( this.moveLeft ) this.object.translateX( - actualMoveSpeed );
+			if ( this.moveRight ) this.object.translateX( actualMoveSpeed );
 
-		}
+			if ( this.moveUp ) this.object.translateY( actualMoveSpeed );
+			if ( this.moveDown ) this.object.translateY( - actualMoveSpeed );
 
-		var targetPosition = this.target,
-			position = this.object.position;
+			var actualLookSpeed = delta * this.lookSpeed;
 
-		targetPosition.x = position.x + 100 * Math.sin( this.phi ) * Math.cos( this.theta );
-		targetPosition.y = position.y + 100 * Math.cos( this.phi );
-		targetPosition.z = position.z + 100 * Math.sin( this.phi ) * Math.sin( this.theta );
+			if ( ! this.activeLook ) {
 
-		this.object.lookAt( targetPosition );
+				actualLookSpeed = 0;
 
-	};
+			}
+
+			var verticalLookRatio = 1;
+
+			if ( this.constrainVertical ) {
+
+				verticalLookRatio = Math.PI / ( this.verticalMax - this.verticalMin );
+
+			}
+
+			lon -= this.mouseX * actualLookSpeed;
+			if ( this.lookVertical ) lat -= this.mouseY * actualLookSpeed * verticalLookRatio;
+
+			lat = Math.max( - 85, Math.min( 85, lat ) );
+
+			var phi = THREE.Math.degToRad( 90 - lat );
+			var theta = THREE.Math.degToRad( lon );
+
+			if ( this.constrainVertical ) {
+
+				phi = THREE.Math.mapLinear( phi, 0, Math.PI, this.verticalMin, this.verticalMax );
+
+			}
+
+			var position = this.object.position;
+
+			targetPosition.setFromSphericalCoords( 1, phi, theta ).add( position );
+
+			this.object.lookAt( targetPosition );
+
+		};
+
+	}();
 
 	function contextmenu( event ) {
 
@@ -295,6 +323,20 @@ THREE.FirstPersonControls = function ( object, domElement ) {
 
 	}
 
+	function setOrientation( controls ) {
+
+		var quaternion = controls.object.quaternion;
+
+		lookDirection.set( 0, 0, - 1 ).applyQuaternion( quaternion );
+		spherical.setFromVector3( lookDirection );
+
+		lat = 90 - THREE.Math.radToDeg( spherical.phi );
+		lon = THREE.Math.radToDeg( spherical.theta );
+
+	}
+
 	this.handleResize();
 
+	setOrientation( this );
+
 };

+ 11 - 0
examples/js/controls/OrbitControls.js

@@ -539,6 +539,10 @@ THREE.OrbitControls = function ( object, domElement ) {
 
 		//console.log( 'handleKeyDown' );
 
+		// prevent the browser from scrolling on cursor up/down
+
+		event.preventDefault();
+
 		switch ( event.keyCode ) {
 
 			case scope.keys.UP:
@@ -673,8 +677,15 @@ THREE.OrbitControls = function ( object, domElement ) {
 
 		if ( scope.enabled === false ) return;
 
+		// Prevent the browser from scrolling.
+
 		event.preventDefault();
 
+		// Manually set the focus since calling preventDefault above
+		// prevents the browser from setting it automatically.
+
+		scope.domElement.focus ? scope.domElement.focus() : window.focus();
+
 		switch ( event.button ) {
 
 			case scope.mouseButtons.LEFT:

+ 51 - 49
examples/js/controls/TransformControls.js

@@ -58,7 +58,10 @@ THREE.TransformControls = function ( camera, domElement ) {
 
 	var pointStart = new THREE.Vector3();
 	var pointEnd = new THREE.Vector3();
+	var offset = new THREE.Vector3();
 	var rotationAxis = new THREE.Vector3();
+	var startNorm = new THREE.Vector3();
+	var endNorm = new THREE.Vector3();
 	var rotationAngle = 0;
 
 	var cameraPosition = new THREE.Vector3();
@@ -67,6 +70,7 @@ THREE.TransformControls = function ( camera, domElement ) {
 
 	var parentPosition = new THREE.Vector3();
 	var parentQuaternion = new THREE.Quaternion();
+	var parentQuaternionInv = new THREE.Quaternion();
 	var parentScale = new THREE.Vector3();
 
 	var worldPositionStart = new THREE.Vector3();
@@ -75,17 +79,17 @@ THREE.TransformControls = function ( camera, domElement ) {
 
 	var worldPosition = new THREE.Vector3();
 	var worldQuaternion = new THREE.Quaternion();
+	var worldQuaternionInv = new THREE.Quaternion();
 	var worldScale = new THREE.Vector3();
 
 	var eye = new THREE.Vector3();
 
-	var _positionStart = new THREE.Vector3();
-	var _quaternionStart = new THREE.Quaternion();
-	var _scaleStart = new THREE.Vector3();
+	var positionStart = new THREE.Vector3();
+	var quaternionStart = new THREE.Quaternion();
+	var scaleStart = new THREE.Vector3();
 
 	// TODO: remove properties unused in plane and gizmo
 
-	defineProperty( "parentQuaternion", parentQuaternion );
 	defineProperty( "worldPosition", worldPosition );
 	defineProperty( "worldPositionStart", worldPositionStart );
 	defineProperty( "worldQuaternion", worldQuaternion );
@@ -190,6 +194,9 @@ THREE.TransformControls = function ( camera, domElement ) {
 			this.object.parent.matrixWorld.decompose( parentPosition, parentQuaternion, parentScale );
 			this.object.matrixWorld.decompose( worldPosition, worldQuaternion, worldScale );
 
+			parentQuaternionInv.copy( parentQuaternion ).inverse();
+			worldQuaternionInv.copy( worldQuaternion ).inverse();
+
 		}
 
 		this.camera.updateMatrixWorld();
@@ -266,16 +273,14 @@ THREE.TransformControls = function ( camera, domElement ) {
 				this.object.updateMatrixWorld();
 				this.object.parent.updateMatrixWorld();
 
-				_positionStart.copy( this.object.position );
-				_quaternionStart.copy( this.object.quaternion );
-				_scaleStart.copy( this.object.scale );
+				positionStart.copy( this.object.position );
+				quaternionStart.copy( this.object.quaternion );
+				scaleStart.copy( this.object.scale );
 
 				this.object.matrixWorld.decompose( worldPositionStart, worldQuaternionStart, worldScaleStart );
 
 				pointStart.copy( planeIntersect.point ).sub( worldPositionStart );
 
-				if ( space === 'local' ) pointStart.applyQuaternion( worldQuaternionStart.clone().inverse() );
-
 			}
 
 			this.dragging = true;
@@ -313,29 +318,27 @@ THREE.TransformControls = function ( camera, domElement ) {
 
 		pointEnd.copy( planeIntersect.point ).sub( worldPositionStart );
 
-		if ( space === 'local' ) pointEnd.applyQuaternion( worldQuaternionStart.clone().inverse() );
-
 		if ( mode === 'translate' ) {
 
-			if ( axis.search( 'X' ) === -1 ) {
-				pointEnd.x = pointStart.x;
-			}
-			if ( axis.search( 'Y' ) === -1 ) {
-				pointEnd.y = pointStart.y;
-			}
-			if ( axis.search( 'Z' ) === -1 ) {
-				pointEnd.z = pointStart.z;
+			// Apply translate
+
+			offset.copy( pointEnd ).sub( pointStart );
+
+			if ( space === 'local' && axis !== 'XYZ' ) {
+				offset.applyQuaternion( worldQuaternionInv );
 			}
 
-			// Apply translate
+			if ( axis.indexOf( 'X' ) === -1 ) offset.x = 0;
+			if ( axis.indexOf( 'Y' ) === -1 ) offset.y = 0;
+			if ( axis.indexOf( 'Z' ) === -1 ) offset.z = 0;
 
-			if ( space === 'local' ) {
-				object.position.copy( pointEnd ).sub( pointStart ).applyQuaternion( _quaternionStart );
+			if ( space === 'local' && axis !== 'XYZ') {
+				offset.applyQuaternion( quaternionStart ).divide( parentScale );
 			} else {
-				object.position.copy( pointEnd ).sub( pointStart );
+				offset.applyQuaternion( parentQuaternionInv ).divide( parentScale );
 			}
 
-			object.position.add( _positionStart );
+			object.position.copy( offset ).add( positionStart );
 
 			// Apply translation snap
 
@@ -343,7 +346,7 @@ THREE.TransformControls = function ( camera, domElement ) {
 
 				if ( space === 'local' ) {
 
-					object.position.applyQuaternion(_tempQuaternion.copy( _quaternionStart ).inverse() );
+					object.position.applyQuaternion(_tempQuaternion.copy( quaternionStart ).inverse() );
 
 					if ( axis.search( 'X' ) !== -1 ) {
 						object.position.x = Math.round( object.position.x / this.translationSnap ) * this.translationSnap;
@@ -357,7 +360,7 @@ THREE.TransformControls = function ( camera, domElement ) {
 						object.position.z = Math.round( object.position.z / this.translationSnap ) * this.translationSnap;
 					}
 
-					object.position.applyQuaternion( _quaternionStart );
+					object.position.applyQuaternion( quaternionStart );
 
 				}
 
@@ -415,41 +418,40 @@ THREE.TransformControls = function ( camera, domElement ) {
 
 			// Apply scale
 
-			object.scale.copy( _scaleStart ).multiply( _tempVector );
+			object.scale.copy( scaleStart ).multiply( _tempVector );
 
 		} else if ( mode === 'rotate' ) {
 
-			var ROTATION_SPEED = 20 / worldPosition.distanceTo( _tempVector.setFromMatrixPosition( this.camera.matrixWorld ) );
-
-			var quaternion = this.space === "local" ? worldQuaternion : _identityQuaternion;
+			offset.copy( pointEnd ).sub( pointStart );
 
-			var unit = _unit[ axis ];
+			var ROTATION_SPEED = 20 / worldPosition.distanceTo( _tempVector.setFromMatrixPosition( this.camera.matrixWorld ) );
 
 			if ( axis === 'E' ) {
 
-				_tempVector.copy( pointEnd ).cross( pointStart );
 				rotationAxis.copy( eye );
-				rotationAngle = pointEnd.angleTo( pointStart ) * ( _tempVector.dot( eye ) < 0 ? 1 : -1 );
+				rotationAngle = pointEnd.angleTo( pointStart );
+
+				startNorm.copy( pointStart ).normalize();
+				endNorm.copy( pointEnd ).normalize();
+
+				rotationAngle *= ( endNorm.cross( startNorm ).dot( eye ) < 0 ? 1 : -1);
 
 			} else if ( axis === 'XYZE' ) {
 
-				_tempVector.copy( pointEnd ).sub( pointStart ).cross( eye ).normalize();
-				rotationAxis.copy( _tempVector );
-				rotationAngle = pointEnd.sub( pointStart ).dot( _tempVector.cross( eye ) ) * ROTATION_SPEED;
+				rotationAxis.copy( offset ).cross( eye ).normalize(  );
+				rotationAngle = offset.dot( _tempVector.copy( rotationAxis ).cross( this.eye ) ) * ROTATION_SPEED;
 
 			} else if ( axis === 'X' || axis === 'Y' || axis === 'Z' ) {
 
-				_alignVector.copy( unit ).applyQuaternion( quaternion );
+				rotationAxis.copy( _unit[ axis ] );
 
-				rotationAxis.copy( unit );
+				_tempVector.copy( _unit[ axis ] );
 
-				_tempVector = unit.clone();
-				_tempVector2 = pointEnd.clone().sub( pointStart );
 				if ( space === 'local' ) {
-					_tempVector.applyQuaternion( quaternion );
-					_tempVector2.applyQuaternion( worldQuaternionStart );
+					_tempVector.applyQuaternion( worldQuaternion );
 				}
-				rotationAngle = _tempVector2.dot( _tempVector.cross( eye ).normalize() ) * ROTATION_SPEED;
+
+				rotationAngle = offset.dot( _tempVector.cross( eye ).normalize() ) * ROTATION_SPEED;
 
 			}
 
@@ -460,16 +462,16 @@ THREE.TransformControls = function ( camera, domElement ) {
 			this.rotationAngle = rotationAngle;
 
 			// Apply rotate
+			if ( space === 'local' && axis !== 'E' && axis !== 'XYZE' ) {
 
-			if ( space === 'local' ) {
-
-				object.quaternion.copy( _quaternionStart );
-				object.quaternion.multiply( _tempQuaternion.setFromAxisAngle( rotationAxis, rotationAngle ) );
+				object.quaternion.copy( quaternionStart );
+				object.quaternion.multiply( _tempQuaternion.setFromAxisAngle( rotationAxis, rotationAngle ) ).normalize();
 
 			} else {
 
+				rotationAxis.applyQuaternion( parentQuaternionInv );
 				object.quaternion.copy( _tempQuaternion.setFromAxisAngle( rotationAxis, rotationAngle ) );
-				object.quaternion.multiply( _quaternionStart );
+				object.quaternion.multiply( quaternionStart ).normalize();
 
 			}
 
@@ -534,7 +536,7 @@ THREE.TransformControls = function ( camera, domElement ) {
 		if ( !scope.enabled ) return;
 
 		event.preventDefault();
-		
+
 		document.addEventListener( "mousemove", onPointerMove, false );
 
 		scope.pointerHover( getPointer( event ) );

+ 20 - 6
examples/js/exporters/ColladaExporter.js

@@ -359,6 +359,15 @@ THREE.ColladaExporter.prototype = {
 
 					type = 'constant';
 
+					if ( m.map !== null ) {
+
+						// The Collada spec does not support diffuse texture maps with the
+						// constant shader type.
+						// mrdoob/three.js#15469
+						console.warn( 'ColladaExporter: Texture maps not supported with MeshBasicMaterial.' );
+
+					}
+
 				}
 
 				var emissive = m.emissive ? m.emissive : new THREE.Color( 0, 0, 0 );
@@ -404,7 +413,7 @@ THREE.ColladaExporter.prototype = {
 
 					(
 						type !== 'constant' ?
-						'<diffuse>' +
+							'<diffuse>' +
 
 						(
 							m.map ?
@@ -412,12 +421,12 @@ THREE.ColladaExporter.prototype = {
 								`<color sid="diffuse">${ diffuse.r } ${ diffuse.g } ${ diffuse.b } 1</color>`
 						) +
 						'</diffuse>'
-						: ''
+							: ''
 					) +
 
 					(
 						type === 'phong' ?
-						`<specular><color sid="specular">${ specular.r } ${ specular.g } ${ specular.b } 1</color></specular>` +
+							`<specular><color sid="specular">${ specular.r } ${ specular.g } ${ specular.b } 1</color></specular>` +
 
 						'<shininess>' +
 
@@ -427,8 +436,8 @@ THREE.ColladaExporter.prototype = {
 								`<float sid="shininess">${ shininess }</float>`
 						) +
 
-						'</shininess>' 
-						: ''
+						'</shininess>'
+							: ''
 					) +
 
 					`<reflective><color>${ diffuse.r } ${ diffuse.g } ${ diffuse.b } 1</color></reflective>` +
@@ -516,10 +525,15 @@ THREE.ColladaExporter.prototype = {
 				// the materials.
 				var mat = o.material || new THREE.MeshBasicMaterial();
 				var materials = Array.isArray( mat ) ? mat : [ mat ];
+
 				if ( geometry.groups.length > materials.length ) {
+
 					matidsArray = new Array( geometry.groups.length );
+
 				} else {
-					matidsArray = new Array( materials.length )
+
+					matidsArray = new Array( materials.length );
+
 				}
 				matids = matidsArray.fill()
 					.map( ( v, i ) => processMaterial( materials[ i % materials.length ] ) );

+ 336 - 48
examples/js/exporters/GLTFExporter.js

@@ -359,6 +359,46 @@ THREE.GLTFExporter.prototype = {
 
 		}
 
+		/**
+		 * Applies a texture transform, if present, to the map definition. Requires
+		 * the KHR_texture_transform extension.
+		 */
+		function applyTextureTransform( mapDef, texture ) {
+
+			var didTransform = false;
+			var transformDef = {};
+
+			if ( texture.offset.x !== 0 || texture.offset.y !== 0 ) {
+
+				transformDef.offset = texture.offset.toArray();
+				didTransform = true;
+
+			}
+
+			if ( texture.rotation !== 0 ) {
+
+				transformDef.rotation = texture.rotation;
+				didTransform = true;
+
+			}
+
+			if ( texture.repeat.x !== 1 || texture.repeat.y !== 1 ) {
+
+				transformDef.scale = texture.repeat.toArray();
+				didTransform = true;
+
+			}
+
+			if ( didTransform ) {
+
+				mapDef.extensions = mapDef.extensions || {};
+				mapDef.extensions[ 'KHR_texture_transform' ] = transformDef;
+				extensionsUsed[ 'KHR_texture_transform' ] = true;
+
+			}
+
+		}
+
 		/**
 		 * Process a buffer to append to the default one.
 		 * @param  {ArrayBuffer} buffer
@@ -868,11 +908,9 @@ THREE.GLTFExporter.prototype = {
 
 				if ( material.metalnessMap === material.roughnessMap ) {
 
-					gltfMaterial.pbrMetallicRoughness.metallicRoughnessTexture = {
-
-						index: processTexture( material.metalnessMap )
-
-					};
+					var metalRoughMapDef = { index: processTexture( material.metalnessMap ) };
+					applyTextureTransform( metalRoughMapDef, material.metalnessMap );
+					gltfMaterial.pbrMetallicRoughness.metallicRoughnessTexture = metalRoughMapDef;
 
 				} else {
 
@@ -885,11 +923,9 @@ THREE.GLTFExporter.prototype = {
 			// pbrMetallicRoughness.baseColorTexture
 			if ( material.map ) {
 
-				gltfMaterial.pbrMetallicRoughness.baseColorTexture = {
-
-					index: processTexture( material.map )
-
-				};
+				var baseColorMapDef = { index: processTexture( material.map ) };
+				applyTextureTransform( baseColorMapDef, material.map );
+				gltfMaterial.pbrMetallicRoughness.baseColorTexture = baseColorMapDef;
 
 			}
 
@@ -911,11 +947,9 @@ THREE.GLTFExporter.prototype = {
 				// emissiveTexture
 				if ( material.emissiveMap ) {
 
-					gltfMaterial.emissiveTexture = {
-
-						index: processTexture( material.emissiveMap )
-
-					};
+					var emissiveMapDef = { index: processTexture( material.emissiveMap ) };
+					applyTextureTransform( emissiveMapDef, material.emissiveMap );
+					gltfMaterial.emissiveTexture = emissiveMapDef;
 
 				}
 
@@ -924,11 +958,7 @@ THREE.GLTFExporter.prototype = {
 			// normalTexture
 			if ( material.normalMap ) {
 
-				gltfMaterial.normalTexture = {
-
-					index: processTexture( material.normalMap )
-
-				};
+				var normalMapDef = { index: processTexture( material.normalMap ) };
 
 				if ( material.normalScale.x !== - 1 ) {
 
@@ -938,27 +968,34 @@ THREE.GLTFExporter.prototype = {
 
 					}
 
-					gltfMaterial.normalTexture.scale = material.normalScale.x;
+					normalMapDef.scale = material.normalScale.x;
 
 				}
 
+				applyTextureTransform( normalMapDef, material.normalMap );
+
+				gltfMaterial.normalTexture = normalMapDef;
+
 			}
 
 			// occlusionTexture
 			if ( material.aoMap ) {
 
-				gltfMaterial.occlusionTexture = {
-
-					index: processTexture( material.aoMap )
-
+				var occlusionMapDef = {
+					index: processTexture( material.aoMap ),
+					texCoord: 1
 				};
 
 				if ( material.aoMapIntensity !== 1.0 ) {
 
-					gltfMaterial.occlusionTexture.strength = material.aoMapIntensity;
+					occlusionMapDef.strength = material.aoMapIntensity;
 
 				}
 
+				applyTextureTransform( occlusionMapDef, material.aoMap );
+
+				gltfMaterial.occlusionTexture = occlusionMapDef;
+
 			}
 
 			// alphaMode
@@ -1094,6 +1131,7 @@ THREE.GLTFExporter.prototype = {
 
 			// @QUESTION Detect if .vertexColors = THREE.VertexColors?
 			// For every attribute create an accessor
+			var modifiedAttribute = null;
 			for ( var attributeName in geometry.attributes ) {
 
 				var attribute = geometry.attributes[ attributeName ];
@@ -1107,7 +1145,7 @@ THREE.GLTFExporter.prototype = {
 				}
 
 				// JOINTS_0 must be UNSIGNED_BYTE or UNSIGNED_SHORT.
-				var modifiedAttribute;
+				modifiedAttribute = null;
 				var array = attribute.array;
 				if ( attributeName === 'JOINTS_0' &&
 					! ( array instanceof Uint16Array ) &&
@@ -1192,9 +1230,9 @@ THREE.GLTFExporter.prototype = {
 
 						var baseAttribute = geometry.attributes[ attributeName ];
 
-						if ( cachedData.attributes.has( baseAttribute ) ) {
+						if ( cachedData.attributes.has( attribute ) ) {
 
-							target[ gltfAttributeName ] = cachedData.attributes.get( baseAttribute );
+							target[ gltfAttributeName ] = cachedData.attributes.get( attribute );
 							continue;
 
 						}
@@ -1408,12 +1446,15 @@ THREE.GLTFExporter.prototype = {
 
 			}
 
+			clip = THREE.GLTFExporter.Utils.mergeMorphTargetTracks( clip.clone(), root );
+
+			var tracks = clip.tracks;
 			var channels = [];
 			var samplers = [];
 
-			for ( var i = 0; i < clip.tracks.length; ++ i ) {
+			for ( var i = 0; i < tracks.length; ++ i ) {
 
-				var track = clip.tracks[ i ];
+				var track = tracks[ i ];
 				var trackBinding = THREE.PropertyBinding.parseTrackName( track.name );
 				var trackNode = THREE.PropertyBinding.findNode( root, trackBinding.nodeName );
 				var trackProperty = PATH_PROPERTIES[ trackBinding.propertyName ];
@@ -1444,16 +1485,6 @@ THREE.GLTFExporter.prototype = {
 
 				if ( trackProperty === PATH_PROPERTIES.morphTargetInfluences ) {
 
-					if ( trackNode.morphTargetInfluences.length !== 1 &&
-						trackBinding.propertyIndex !== undefined ) {
-
-						console.warn( 'THREE.GLTFExporter: Skipping animation track "%s". ' +
-							'Morph target keyframe tracks must target all available morph targets ' +
-							'for the given mesh.', track.name );
-						continue;
-
-					}
-
 					outputItemSize /= trackNode.morphTargetInfluences.length;
 
 				}
@@ -1556,6 +1587,59 @@ THREE.GLTFExporter.prototype = {
 
 		}
 
+		function processLight( light ) {
+
+			var lightDef = {};
+
+			if ( light.name ) lightDef.name = light.name;
+
+			lightDef.color = light.color.toArray();
+
+			lightDef.intensity = light.intensity;
+
+			if ( light.isDirectionalLight ) {
+
+				lightDef.type = 'directional';
+
+			} else if ( light.isPointLight ) {
+
+				lightDef.type = 'point';
+				if ( light.distance > 0 ) lightDef.range = light.distance;
+
+			} else if ( light.isSpotLight ) {
+
+				lightDef.type = 'spot';
+				if ( light.distance > 0 ) lightDef.range = light.distance;
+				lightDef.spot = {};
+				lightDef.spot.innerConeAngle = ( light.penumbra - 1.0 ) * light.angle * - 1.0;
+				lightDef.spot.outerConeAngle = light.angle;
+
+			}
+
+			if ( light.decay !== undefined && light.decay !== 2 ) {
+
+				console.warn( 'THREE.GLTFExporter: Light decay may be lost. glTF is physically-based, '
+					+ 'and expects light.decay=2.' );
+
+			}
+
+			if ( light.target
+					&& ( light.target.parent !== light
+					 || light.target.position.x !== 0
+					 || light.target.position.y !== 0
+					 || light.target.position.z !== - 1 ) ) {
+
+				console.warn( 'THREE.GLTFExporter: Light direction may be lost. For best results, '
+					+ 'make light.target a child of the light with position 0,0,-1.' );
+
+			}
+
+			var lights = outputJSON.extensions[ 'KHR_lights_punctual' ].lights;
+			lights.push( lightDef );
+			return lights.length - 1;
+
+		}
+
 		/**
 		 * Process Object3D node
 		 * @param  {THREE.Object3D} node Object3D to processNode
@@ -1563,13 +1647,6 @@ THREE.GLTFExporter.prototype = {
 		 */
 		function processNode( object ) {
 
-			if ( object.isLight ) {
-
-				console.warn( 'GLTFExporter: Unsupported node type:', object.constructor.name );
-				return null;
-
-			}
-
 			if ( ! outputJSON.nodes ) {
 
 				outputJSON.nodes = [];
@@ -1640,6 +1717,24 @@ THREE.GLTFExporter.prototype = {
 
 				gltfNode.camera = processCamera( object );
 
+			} else if ( object.isDirectionalLight || object.isPointLight || object.isSpotLight ) {
+
+				if ( ! extensionsUsed[ 'KHR_lights_punctual' ] ) {
+
+					outputJSON.extensions = outputJSON.extensions || {};
+					outputJSON.extensions[ 'KHR_lights_punctual' ] = { lights: [] };
+					extensionsUsed[ 'KHR_lights_punctual' ] = true;
+
+				}
+
+				gltfNode.extensions = gltfNode.extensions || {};
+				gltfNode.extensions[ 'KHR_lights_punctual' ] = { light: processLight( object ) };
+
+			} else if ( object.isLight ) {
+
+				console.warn( 'THREE.GLTFExporter: Only directional, point, and spot lights are supported.' );
+				return null;
+
 			}
 
 			if ( object.isSkinnedMesh ) {
@@ -1907,3 +2002,196 @@ THREE.GLTFExporter.prototype = {
 	}
 
 };
+
+THREE.GLTFExporter.Utils = {
+
+	insertKeyframe: function ( track, time ) {
+
+		var tolerance = 0.001; // 1ms
+		var valueSize = track.getValueSize();
+
+		var times = new track.TimeBufferType( track.times.length + 1 );
+		var values = new track.ValueBufferType( track.values.length + valueSize );
+		var interpolant = track.createInterpolant( new track.ValueBufferType( valueSize ) );
+
+		var index;
+
+		if ( track.times.length === 0 ) {
+
+			times[ 0 ] = time;
+
+			for ( var i = 0; i < valueSize; i ++ ) {
+
+				values[ i ] = 0;
+
+			}
+
+			index = 0;
+
+		} else if ( time < track.times[ 0 ] ) {
+
+			if ( Math.abs( track.times[ 0 ] - time ) < tolerance ) return 0;
+
+			times[ 0 ] = time;
+			times.set( track.times, 1 );
+
+			values.set( interpolant.evaluate( time ), 0 );
+			values.set( track.values, valueSize );
+
+			index = 0;
+
+		} else if ( time > track.times[ track.times.length - 1 ] ) {
+
+			if ( Math.abs( track.times[ track.times.length - 1 ] - time ) < tolerance ) {
+
+				return track.times.length - 1;
+
+			}
+
+			times[ times.length - 1 ] = time;
+			times.set( track.times, 0 );
+
+			values.set( track.values, 0 );
+			values.set( interpolant.evaluate( time ), track.values.length );
+
+			index = times.length - 1;
+
+		} else {
+
+			for ( var i = 0; i < track.times.length; i ++ ) {
+
+				if ( Math.abs( track.times[ i ] - time ) < tolerance ) return i;
+
+				if ( track.times[ i ] < time && track.times[ i + 1 ] > time ) {
+
+					times.set( track.times.slice( 0, i + 1 ), 0 );
+					times[ i + 1 ] = time;
+					times.set( track.times.slice( i + 1 ), i + 2 );
+
+					values.set( track.values.slice( 0, ( i + 1 ) * valueSize ), 0 );
+					values.set( interpolant.evaluate( time ), ( i + 1 ) * valueSize );
+					values.set( track.values.slice( ( i + 1 ) * valueSize ), ( i + 2 ) * valueSize );
+
+					index = i + 1;
+
+					break;
+
+				}
+
+			}
+
+		}
+
+		track.times = times;
+		track.values = values;
+
+		return index;
+
+	},
+
+	mergeMorphTargetTracks: function ( clip, root ) {
+
+		var tracks = [];
+		var mergedTracks = {};
+		var sourceTracks = clip.tracks;
+
+		for ( var i = 0; i < sourceTracks.length; ++ i ) {
+
+			var sourceTrack = sourceTracks[ i ];
+			var sourceTrackBinding = THREE.PropertyBinding.parseTrackName( sourceTrack.name );
+			var sourceTrackNode = THREE.PropertyBinding.findNode( root, sourceTrackBinding.nodeName );
+
+			if ( sourceTrackBinding.propertyName !== 'morphTargetInfluences' || sourceTrackBinding.propertyIndex === undefined ) {
+
+				// Tracks that don't affect morph targets, or that affect all morph targets together, can be left as-is.
+				tracks.push( sourceTrack );
+				continue;
+
+			}
+
+			if ( sourceTrack.createInterpolant !== sourceTrack.InterpolantFactoryMethodDiscrete
+				&& sourceTrack.createInterpolant !== sourceTrack.InterpolantFactoryMethodLinear ) {
+
+				if ( sourceTrack.createInterpolant.isInterpolantFactoryMethodGLTFCubicSpline ) {
+
+					// This should never happen, because glTF morph target animations
+					// affect all targets already.
+					throw new Error( 'THREE.GLTFExporter: Cannot merge tracks with glTF CUBICSPLINE interpolation.' );
+
+				}
+
+				console.warn( 'THREE.GLTFExporter: Morph target interpolation mode not yet supported. Using LINEAR instead.' );
+
+				sourceTrack = sourceTrack.clone();
+				sourceTrack.setInterpolation( InterpolateLinear );
+
+			}
+
+			var targetCount = sourceTrackNode.morphTargetInfluences.length;
+			var targetIndex = sourceTrackNode.morphTargetDictionary[ sourceTrackBinding.propertyIndex ];
+
+			if ( targetIndex === undefined ) {
+
+				throw new Error( 'THREE.GLTFExporter: Morph target name not found: ' + sourceTrackBinding.propertyIndex );
+
+			}
+
+			var mergedTrack;
+
+			// If this is the first time we've seen this object, create a new
+			// track to store merged keyframe data for each morph target.
+			if ( mergedTracks[ sourceTrackNode.uuid ] === undefined ) {
+
+				mergedTrack = sourceTrack.clone();
+
+				var values = new mergedTrack.ValueBufferType( targetCount * mergedTrack.times.length );
+
+				for ( var j = 0; j < mergedTrack.times.length; j ++ ) {
+
+					values[ j * targetCount + targetIndex ] = mergedTrack.values[ j ];
+
+				}
+
+				mergedTrack.name = '.morphTargetInfluences';
+				mergedTrack.values = values;
+
+				mergedTracks[ sourceTrackNode.uuid ] = mergedTrack;
+				tracks.push( mergedTrack );
+
+				continue;
+
+			}
+
+			var mergedKeyframeIndex = 0;
+			var sourceKeyframeIndex = 0;
+			var sourceInterpolant = sourceTrack.createInterpolant( new sourceTrack.ValueBufferType( 1 ) );
+
+			mergedTrack = mergedTracks[ sourceTrackNode.uuid ];
+
+			// For every existing keyframe of the merged track, write a (possibly
+			// interpolated) value from the source track.
+			for ( var j = 0; j < mergedTrack.times.length; j ++ ) {
+
+				mergedTrack.values[ j * targetCount + targetIndex ] = sourceInterpolant.evaluate( mergedTrack.times[ j ] );
+
+			}
+
+			// For every existing keyframe of the source track, write a (possibly
+			// new) keyframe to the merged track. Values from the previous loop may
+			// be written again, but keyframes are de-duplicated.
+			for ( var j = 0; j < sourceTrack.times.length; j ++ ) {
+
+				var keyframeIndex = this.insertKeyframe( mergedTrack, sourceTrack.times[ j ] );
+				mergedTrack.values[ keyframeIndex * targetCount + targetIndex ] = sourceTrack.values[ j ];
+
+			}
+
+		}
+
+		clip.tracks = tracks;
+
+		return clip;
+
+	}
+
+};

+ 105 - 100
examples/js/interactive/SelectionBox.js

@@ -3,114 +3,119 @@
  * This is a class to check whether objects are in a selection area in 3D space
  */
 
-function SelectionBox ( camera, scene, deep ) {
-	
-	this.camera = camera;
-	this.scene = scene;
-	this.startPoint = new THREE.Vector3();
-	this.endPoint = new THREE.Vector3();
-	this.collection = [];
-	this.deep = deep || Number.MAX_VALUE;
-	
-}
-
-SelectionBox.prototype.select = function ( startPoint, endPoint ) {
-	
-	this.startPoint = startPoint || this.startPoint;
-	this.endPoint = endPoint || this.endPoint;
-	this.collection = [];
-    
-	var boxSelectionFrustum = this.createFrustum( this.startPoint, this.endPoint );
-	this.searchChildInFrustum( boxSelectionFrustum, this.scene );
-    
-	return this.collection;
-	
-}
-
-SelectionBox.prototype.createFrustum = function ( startPoint, endPoint ) {
-	
-	startPoint = startPoint || this.startPoint;
-	endPoint = endPoint || this.endPoint
-
-	this.camera.updateProjectionMatrix();
-	this.camera.updateMatrixWorld();
-	this.camera.updateMatrix();
-
-	var tmpPoint = startPoint.clone();
-	tmpPoint.x = Math.min( startPoint.x, endPoint.x );
-	tmpPoint.y = Math.max( startPoint.y, endPoint.y );
-	endPoint.x = Math.max( startPoint.x, endPoint.x );
-	endPoint.y = Math.min( startPoint.y, endPoint.y );
-
-	var vecNear = this.camera.position.clone();
-	var vecTopLeft = tmpPoint.clone();
-	var vecTopRight = new THREE.Vector3( endPoint.x, tmpPoint.y, 0 );
-	var vecDownRight = endPoint.clone();
-	var vecDownLeft = new THREE.Vector3( tmpPoint.x, endPoint.y, 0 );
-	vecTopLeft.unproject( this.camera );
-	vecTopRight.unproject( this.camera );
-	vecDownRight.unproject( this.camera );
-	vecDownLeft.unproject( this.camera );
-
-	var vectemp1 = vecTopLeft.clone().sub( vecNear );
-	var vectemp2 = vecTopRight.clone().sub( vecNear );
-	var vectemp3 = vecDownRight.clone().sub( vecNear );
-	vectemp1.normalize();
-	vectemp2.normalize();
-	vectemp3.normalize();
-
-	vectemp1.multiplyScalar( this.deep );
-	vectemp2.multiplyScalar( this.deep );
-	vectemp3.multiplyScalar( this.deep );
-	vectemp1.add( vecNear );
-	vectemp2.add( vecNear );
-	vectemp3.add( vecNear );
-
-	var planeTop = new THREE.Plane();
-	planeTop.setFromCoplanarPoints( vecNear, vecTopLeft, vecTopRight );
-	var planeRight = new THREE.Plane();
-	planeRight.setFromCoplanarPoints( vecNear, vecTopRight, vecDownRight );
-	var planeDown = new THREE.Plane();
-	planeDown.setFromCoplanarPoints( vecDownRight, vecDownLeft, vecNear );
-	var planeLeft = new THREE.Plane();
-	planeLeft.setFromCoplanarPoints( vecDownLeft, vecTopLeft, vecNear );
-	var planeFront = new THREE.Plane();
-	planeFront.setFromCoplanarPoints( vecTopRight, vecDownRight, vecDownLeft );
-	var planeBack = new THREE.Plane();
-	planeBack.setFromCoplanarPoints( vectemp3, vectemp2, vectemp1 );
-	planeBack.normal = planeBack.normal.multiplyScalar( -1 );
-
-	return new THREE.Frustum( planeTop, planeRight, planeDown, planeLeft, planeFront, planeBack );
-
-}
-
-SelectionBox.prototype.searchChildInFrustum = function ( frustum, object ) {
-
-	if ( object instanceof THREE.Mesh ) {
-
-		if ( object.material !== undefined ) {
-
-			object.geometry.computeBoundingSphere();
-			var center = object.geometry.boundingSphere.center.clone().applyMatrix4( object.matrixWorld );
-
-			if ( frustum.containsPoint( center ) ) {
-
-				this.collection.push( object );
+THREE.SelectionBox = ( function () {
+
+	var frustum = new THREE.Frustum();
+	var center = new THREE.Vector3();
+
+	function SelectionBox( camera, scene, deep ) {
+
+		this.camera = camera;
+		this.scene = scene;
+		this.startPoint = new THREE.Vector3();
+		this.endPoint = new THREE.Vector3();
+		this.collection = [];
+		this.deep = deep || Number.MAX_VALUE;
+
+	}
+
+	SelectionBox.prototype.select = function ( startPoint, endPoint ) {
+
+		this.startPoint = startPoint || this.startPoint;
+		this.endPoint = endPoint || this.endPoint;
+		this.collection = [];
+
+		this.updateFrustum( this.startPoint, this.endPoint );
+		this.searchChildInFrustum( frustum, this.scene );
+
+		return this.collection;
+
+	};
+
+	SelectionBox.prototype.updateFrustum = function ( startPoint, endPoint ) {
+
+		startPoint = startPoint || this.startPoint;
+		endPoint = endPoint || this.endPoint;
+
+		this.camera.updateProjectionMatrix();
+		this.camera.updateMatrixWorld();
+
+		var tmpPoint = startPoint.clone();
+		tmpPoint.x = Math.min( startPoint.x, endPoint.x );
+		tmpPoint.y = Math.max( startPoint.y, endPoint.y );
+		endPoint.x = Math.max( startPoint.x, endPoint.x );
+		endPoint.y = Math.min( startPoint.y, endPoint.y );
+
+		var vecNear = this.camera.position.clone();
+		var vecTopLeft = tmpPoint.clone();
+		var vecTopRight = new THREE.Vector3( endPoint.x, tmpPoint.y, 0 );
+		var vecDownRight = endPoint.clone();
+		var vecDownLeft = new THREE.Vector3( tmpPoint.x, endPoint.y, 0 );
+		vecTopLeft.unproject( this.camera );
+		vecTopRight.unproject( this.camera );
+		vecDownRight.unproject( this.camera );
+		vecDownLeft.unproject( this.camera );
+
+		var vectemp1 = vecTopLeft.clone().sub( vecNear );
+		var vectemp2 = vecTopRight.clone().sub( vecNear );
+		var vectemp3 = vecDownRight.clone().sub( vecNear );
+		vectemp1.normalize();
+		vectemp2.normalize();
+		vectemp3.normalize();
+
+		vectemp1.multiplyScalar( this.deep );
+		vectemp2.multiplyScalar( this.deep );
+		vectemp3.multiplyScalar( this.deep );
+		vectemp1.add( vecNear );
+		vectemp2.add( vecNear );
+		vectemp3.add( vecNear );
+
+		var planes = frustum.planes;
+
+		planes[ 0 ].setFromCoplanarPoints( vecNear, vecTopLeft, vecTopRight );
+		planes[ 1 ].setFromCoplanarPoints( vecNear, vecTopRight, vecDownRight );
+		planes[ 2 ].setFromCoplanarPoints( vecDownRight, vecDownLeft, vecNear );
+		planes[ 3 ].setFromCoplanarPoints( vecDownLeft, vecTopLeft, vecNear );
+		planes[ 4 ].setFromCoplanarPoints( vecTopRight, vecDownRight, vecDownLeft );
+		planes[ 5 ].setFromCoplanarPoints( vectemp3, vectemp2, vectemp1 );
+		planes[ 5 ].normal.multiplyScalar( - 1 );
+
+	};
+
+	SelectionBox.prototype.searchChildInFrustum = function ( frustum, object ) {
+
+		if ( object.isMesh ) {
+
+			if ( object.material !== undefined ) {
+
+				object.geometry.computeBoundingSphere();
+
+				center.copy( object.geometry.boundingSphere.center );
+
+				center.applyMatrix4( object.matrixWorld );
+
+				if ( frustum.containsPoint( center ) ) {
+
+					this.collection.push( object );
+
+				}
 
 			}
 
 		}
 
-	}
+		if ( object.children.length > 0 ) {
 
-	if ( object.children.length > 0 ) {
+			for ( var x = 0; x < object.children.length; x ++ ) {
 
-		for ( var x = 0; x < object.children.length; x++ ) {
+				this.searchChildInFrustum( frustum, object.children[ x ] );
 
-			this.searchChildInFrustum( frustum, object.children[x] );
+			}
 
 		}
 
-	}
-    
-}
+	};
+
+	return SelectionBox;
+
+} )();

+ 60 - 50
examples/js/interactive/SelectionHelper.js

@@ -1,73 +1,83 @@
-function SelectionHelper ( selectionBox, renderer, cssClassName ) {
+/**
+ * @author HypnosNova / https://www.threejs.org.cn/gallery
+ */
 
-	this.element = document.createElement( "div" );
-	this.element.classList.add( cssClassName );
-	this.element.style.pointerEvents = "none";
+THREE.SelectionHelper = ( function () {
 
-	this.renderer = renderer;
+	function SelectionHelper( selectionBox, renderer, cssClassName ) {
 
-	this.startPoint = { x: 0, y: 0 };
-	this.pointTopLeft = { x: 0, y: 0 };
-	this.pointBottomRight = { x: 0, y: 0 };
+		this.element = document.createElement( 'div' );
+		this.element.classList.add( cssClassName );
+		this.element.style.pointerEvents = 'none';
 
-	this.isDown = false;
+		this.renderer = renderer;
 
-	this.renderer.domElement.addEventListener( "mousedown", function ( event ) {
-		
-		this.isDown = true;
-		this.onSelectStart( event );
+		this.startPoint = { x: 0, y: 0 };
+		this.pointTopLeft = { x: 0, y: 0 };
+		this.pointBottomRight = { x: 0, y: 0 };
 
-	}.bind( this ), false );
+		this.isDown = false;
 
-	this.renderer.domElement.addEventListener( "mousemove", function ( event ) {
+		this.renderer.domElement.addEventListener( 'mousedown', function ( event ) {
 
-		if ( this.isDown ) {
+			this.isDown = true;
+			this.onSelectStart( event );
 
-			this.onSelectMove( event );
+		}.bind( this ), false );
 
-		}
+		this.renderer.domElement.addEventListener( 'mousemove', function ( event ) {
 
-	}.bind( this ), false );
+			if ( this.isDown ) {
 
-	this.renderer.domElement.addEventListener( "mouseup", function ( event ) {
+				this.onSelectMove( event );
 
-		this.isDown = false;
-		this.onSelectOver( event );
+			}
+
+		}.bind( this ), false );
+
+		this.renderer.domElement.addEventListener( 'mouseup', function ( event ) {
+
+			this.isDown = false;
+			this.onSelectOver( event );
+
+		}.bind( this ), false );
+
+	}
+
+	SelectionHelper.prototype.onSelectStart = function ( event ) {
+
+		this.renderer.domElement.parentElement.appendChild( this.element );
+
+		this.element.style.left = event.clientX + 'px';
+		this.element.style.top = event.clientY + 'px';
+		this.element.style.width = '0px';
+		this.element.style.height = '0px';
+
+		this.startPoint.x = event.clientX;
+		this.startPoint.y = event.clientY;
 
-	}.bind( this ), false );
-	
-}
+	};
 
-SelectionHelper.prototype.onSelectStart = function ( event ) {
-	
-	this.renderer.domElement.parentElement.appendChild( this.element );
+	SelectionHelper.prototype.onSelectMove = function ( event ) {
 
-	this.element.style.left = event.clientX + "px";
-	this.element.style.top = event.clientY + "px";
-	this.element.style.width = "0px";
-	this.element.style.height = "0px";
+		this.pointBottomRight.x = Math.max( this.startPoint.x, event.clientX );
+		this.pointBottomRight.y = Math.max( this.startPoint.y, event.clientY );
+		this.pointTopLeft.x = Math.min( this.startPoint.x, event.clientX );
+		this.pointTopLeft.y = Math.min( this.startPoint.y, event.clientY );
 
-	this.startPoint.x = event.clientX;
-	this.startPoint.y = event.clientY;
+		this.element.style.left = this.pointTopLeft.x + 'px';
+		this.element.style.top = this.pointTopLeft.y + 'px';
+		this.element.style.width = ( this.pointBottomRight.x - this.pointTopLeft.x ) + 'px';
+		this.element.style.height = ( this.pointBottomRight.y - this.pointTopLeft.y ) + 'px';
 
-}
+	};
 
-SelectionHelper.prototype.onSelectMove = function ( event ) {
+	SelectionHelper.prototype.onSelectOver = function () {
 
-	this.pointBottomRight.x = Math.max( this.startPoint.x, event.clientX );
-	this.pointBottomRight.y = Math.max( this.startPoint.y, event.clientY );
-	this.pointTopLeft.x = Math.min( this.startPoint.x, event.clientX );
-	this.pointTopLeft.y = Math.min( this.startPoint.y, event.clientY );
+		this.element.parentElement.removeChild( this.element );
 
-	this.element.style.left = this.pointTopLeft.x + "px";
-	this.element.style.top = this.pointTopLeft.y + "px";
-	this.element.style.width = ( this.pointBottomRight.x - this.pointTopLeft.x ) + "px";
-	this.element.style.height = ( this.pointBottomRight.y - this.pointTopLeft.y ) + "px";
-	
-}
+	};
 
-SelectionHelper.prototype.onSelectOver = function ( event ) {
+	return SelectionHelper;
 
-	this.element.parentElement.removeChild( this.element );
-	
-}
+} )();

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

@@ -2825,7 +2825,7 @@ THREE.ColladaLoader.prototype = {
 						break;
 
 					case 'mass':
-						data.mass = parseFloats( child.textContent )[0];
+						data.mass = parseFloats( child.textContent )[ 0 ];
 						break;
 
 				}

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

@@ -338,7 +338,7 @@ THREE.GLTFLoader = ( function () {
 
 			case 'directional':
 				lightNode = new THREE.DirectionalLight( color );
-				lightNode.target.position.set( 0, 0, -1 );
+				lightNode.target.position.set( 0, 0, - 1 );
 				lightNode.add( lightNode.target );
 				break;
 
@@ -356,7 +356,7 @@ THREE.GLTFLoader = ( function () {
 				lightDef.spot.outerConeAngle = lightDef.spot.outerConeAngle !== undefined ? lightDef.spot.outerConeAngle : Math.PI / 4.0;
 				lightNode.angle = lightDef.spot.outerConeAngle;
 				lightNode.penumbra = 1.0 - lightDef.spot.innerConeAngle / lightDef.spot.outerConeAngle;
-				lightNode.target.position.set( 0, 0, -1 );
+				lightNode.target.position.set( 0, 0, - 1 );
 				lightNode.add( lightNode.target );
 				break;
 
@@ -365,6 +365,10 @@ THREE.GLTFLoader = ( function () {
 
 		}
 
+		// Some lights (e.g. spot) default to a position other than the origin. Reset the position
+		// here, because node-level parsing will only override position if explicitly specified.
+		lightNode.position.set( 0, 0, 0 );
+
 		lightNode.decay = 2;
 
 		if ( lightDef.intensity !== undefined ) lightNode.intensity = lightDef.intensity;
@@ -964,6 +968,7 @@ THREE.GLTFLoader = ( function () {
 					uniforms.refractionRatio.value = material.refractionRatio;
 
 					uniforms.maxMipLevel.value = renderer.properties.get( material.envMap ).__maxMipLevel;
+
 				}
 
 				uniforms.specular.value.copy( material.specular );
@@ -1848,7 +1853,7 @@ THREE.GLTFLoader = ( function () {
 
 				case 'light':
 					dependency = this.extensions[ EXTENSIONS.KHR_LIGHTS_PUNCTUAL ].loadLight( index );
-					break
+					break;
 
 				default:
 					throw new Error( 'Unknown type: ' + type );
@@ -3129,7 +3134,7 @@ THREE.GLTFLoader = ( function () {
 
 		var nodeDef = json.nodes[ nodeIndex ];
 
-		return ( function() {
+		return ( function () {
 
 			// .isBone isn't in glTF spec. See .markDefs
 			if ( nodeDef.isBone === true ) {

+ 1 - 0
examples/js/nodes/Nodes.js

@@ -20,6 +20,7 @@ export { NodeBuilder } from './core/NodeBuilder.js';
 
 // inputs
 
+export { BoolNode } from './inputs/BoolNode.js';
 export { IntNode } from './inputs/IntNode.js';
 export { FloatNode } from './inputs/FloatNode.js';
 export { Vector2Node } from './inputs/Vector2Node.js';

+ 2 - 0
examples/js/nodes/THREE.Nodes.js

@@ -20,6 +20,7 @@ import {
 
 	// inputs
 
+	BoolNode,
 	IntNode,
 	FloatNode,
 	Vector2Node,
@@ -132,6 +133,7 @@ THREE.NodeBuilder = NodeBuilder;
 
 // inputs
 
+THREE.BoolNode = BoolNode;
 THREE.IntNode = IntNode;
 THREE.FloatNode = FloatNode;
 THREE.Vector2Node = Vector2Node;

+ 2 - 2
examples/js/nodes/accessors/CameraNode.js

@@ -101,7 +101,7 @@ CameraNode.prototype.getType = function ( builder ) {
 
 };
 
-CameraNode.prototype.isUnique = function ( builder ) {
+CameraNode.prototype.getUnique = function ( builder ) {
 
 	switch ( this.scope ) {
 
@@ -116,7 +116,7 @@ CameraNode.prototype.isUnique = function ( builder ) {
 
 };
 
-CameraNode.prototype.isShared = function ( builder ) {
+CameraNode.prototype.getShared = function ( builder ) {
 
 	switch ( this.scope ) {
 

+ 1 - 1
examples/js/nodes/accessors/NormalNode.js

@@ -21,7 +21,7 @@ NormalNode.prototype = Object.create( TempNode.prototype );
 NormalNode.prototype.constructor = NormalNode;
 NormalNode.prototype.nodeType = "Normal";
 
-NormalNode.prototype.isShared = function ( builder ) {
+NormalNode.prototype.getShared = function ( builder ) {
 
 	switch ( this.scope ) {
 

+ 1 - 1
examples/js/nodes/accessors/PositionNode.js

@@ -36,7 +36,7 @@ PositionNode.prototype.getType = function ( ) {
 
 };
 
-PositionNode.prototype.isShared = function ( builder ) {
+PositionNode.prototype.getShared = function ( builder ) {
 
 	switch ( this.scope ) {
 

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

@@ -25,7 +25,7 @@ FunctionNode.prototype.nodeType = "Function";
 
 FunctionNode.prototype.useKeywords = true;
 
-FunctionNode.prototype.isShared = function ( builder, output ) {
+FunctionNode.prototype.getShared = function ( builder, output ) {
 
 	return ! this.isMethod;
 

+ 12 - 4
examples/js/nodes/core/InputNode.js

@@ -18,7 +18,15 @@ function InputNode( type, params ) {
 InputNode.prototype = Object.create( TempNode.prototype );
 InputNode.prototype.constructor = InputNode;
 
-InputNode.prototype.isReadonly = function ( builder ) {
+InputNode.prototype.setReadonly = function ( value ) {
+
+	this.readonly = value;
+
+	return this;
+
+};
+
+InputNode.prototype.getReadonly = function ( builder ) {
 
 	return this.readonly;
 
@@ -48,7 +56,7 @@ InputNode.prototype.generate = function ( builder, output, uuid, type, ns, needs
 	type = type || this.getType( builder );
 
 	var data = builder.getNodeData( uuid ),
-		readonly = this.isReadonly( builder ) && this.generateReadonly !== undefined;
+		readonly = this.getReadonly( builder ) && this.generateReadonly !== undefined;
 
 	if ( readonly ) {
 
@@ -60,7 +68,7 @@ InputNode.prototype.generate = function ( builder, output, uuid, type, ns, needs
 
 			if ( ! data.vertex ) {
 
-				data.vertex = builder.createVertexUniform( type, this, ns, needsUpdate );
+				data.vertex = builder.createVertexUniform( type, this, ns, needsUpdate, this.getLabel() );
 
 			}
 
@@ -70,7 +78,7 @@ InputNode.prototype.generate = function ( builder, output, uuid, type, ns, needs
 
 			if ( ! data.fragment ) {
 
-				data.fragment = builder.createFragmentUniform( type, this, ns, needsUpdate );
+				data.fragment = builder.createFragmentUniform( type, this, ns, needsUpdate, this.getLabel() );
 
 			}
 

+ 28 - 18
examples/js/nodes/core/NodeBuilder.js

@@ -22,7 +22,8 @@ var elements = NodeUtils.elements,
 		vec3: 'v3',
 		vec4: 'v4',
 		mat4: 'v4',
-		int: 'i'
+		int: 'i',
+		bool: 'b'
 	},
 	convertTypeToFormat = {
 		t: 'sampler2D',
@@ -442,9 +443,7 @@ NodeBuilder.prototype = {
 
 	},
 
-	getVar: function ( uuid, type, ns, shader ) {
-
-		shader = shader || 'varying';
+	getVar: function ( uuid, type, ns, shader = 'varying', prefix = 'V', label = '' ) {
 
 		var vars = this.getVars( shader ),
 			data = vars[ uuid ];
@@ -452,7 +451,7 @@ NodeBuilder.prototype = {
 		if ( ! data ) {
 
 			var index = vars.length,
-				name = ns ? ns : 'nVv' + index;
+				name = ns ? ns : 'node' + prefix + index + ( label ? '_' + label : '' );
 
 			data = { name: name, type: type };
 
@@ -465,9 +464,9 @@ NodeBuilder.prototype = {
 
 	},
 
-	getTempVar: function ( uuid, type, ns ) {
+	getTempVar: function ( uuid, type, ns, label ) {
 
-		return this.getVar( uuid, type, ns, this.shader );
+		return this.getVar( uuid, type, ns, this.shader, 'T', label );
 
 	},
 
@@ -550,14 +549,14 @@ NodeBuilder.prototype = {
 
 	},
 
-	createUniform: function ( shader, type, node, ns, needsUpdate ) {
+	createUniform: function ( shader, type, node, ns, needsUpdate, label ) {
 
 		var uniforms = this.inputs.uniforms,
 			index = uniforms.list.length;
 
 		var uniform = new NodeUniform( {
 			type: type,
-			name: ns ? ns : 'nVu' + index,
+			name: ns ? ns : 'nodeU' + index + ( label ? '_' + label : '' ),
 			node: node,
 			needsUpdate: needsUpdate
 		} );
@@ -573,15 +572,15 @@ NodeBuilder.prototype = {
 
 	},
 
-	createVertexUniform: function ( type, node, ns, needsUpdate ) {
+	createVertexUniform: function ( type, node, ns, needsUpdate, label ) {
 
-		return this.createUniform( 'vertex', type, node, ns, needsUpdate );
+		return this.createUniform( 'vertex', type, node, ns, needsUpdate, label );
 
 	},
 
-	createFragmentUniform: function ( type, node, ns, needsUpdate ) {
+	createFragmentUniform: function ( type, node, ns, needsUpdate, label ) {
 
-		return this.createUniform( 'fragment', type, node, ns, needsUpdate );
+		return this.createUniform( 'fragment', type, node, ns, needsUpdate, label );
 
 	},
 
@@ -821,28 +820,39 @@ NodeBuilder.prototype = {
 			case 'f <- v2' : return code + '.x';
 			case 'f <- v3' : return code + '.x';
 			case 'f <- v4' : return code + '.x';
-			case 'f <- i' : return 'float( ' + code + ' )';
+			case 'f <- i' :
+			case 'f <- b' :	return 'float( ' + code + ' )';
 
 			case 'v2 <- f' : return 'vec2( ' + code + ' )';
 			case 'v2 <- v3': return code + '.xy';
 			case 'v2 <- v4': return code + '.xy';
-			case 'v2 <- i' : return 'vec2( float( ' + code + ' ) )';
+			case 'v2 <- i' :
+			case 'v2 <- b' : return 'vec2( float( ' + code + ' ) )';
 
 			case 'v3 <- f' : return 'vec3( ' + code + ' )';
 			case 'v3 <- v2': return 'vec3( ' + code + ', 0.0 )';
 			case 'v3 <- v4': return code + '.xyz';
-			case 'v3 <- i' : return 'vec2( float( ' + code + ' ) )';
+			case 'v3 <- i' :
+			case 'v3 <- b' : return 'vec2( float( ' + code + ' ) )';
 
 			case 'v4 <- f' : return 'vec4( ' + code + ' )';
 			case 'v4 <- v2': return 'vec4( ' + code + ', 0.0, 1.0 )';
 			case 'v4 <- v3': return 'vec4( ' + code + ', 1.0 )';
-			case 'v4 <- i' : return 'vec4( float( ' + code + ' ) )';
+			case 'v4 <- i' :
+			case 'v4 <- b' : return 'vec4( float( ' + code + ' ) )';
 
-			case 'i <- f' : return 'int( ' + code + ' )';
+			case 'i <- f' :
+			case 'i <- b' : return 'int( ' + code + ' )';
 			case 'i <- v2' : return 'int( ' + code + '.x )';
 			case 'i <- v3' : return 'int( ' + code + '.x )';
 			case 'i <- v4' : return 'int( ' + code + '.x )';
 
+			case 'b <- f' : return '( ' + code + ' != 0.0 )';
+			case 'b <- v2' : return '( ' + code + ' != vec2( 0.0 ) )';
+			case 'b <- v3' : return '( ' + code + ' != vec3( 0.0 ) )';
+			case 'b <- v4' : return '( ' + code + ' != vec4( 0.0 ) )';
+			case 'b <- i' : return '( ' + code + ' != 0 )';
+
 		}
 
 		return code;

+ 23 - 9
examples/js/nodes/core/TempNode.js

@@ -23,9 +23,9 @@ TempNode.prototype.build = function ( builder, output, uuid, ns ) {
 
 	output = output || this.getType( builder );
 
-	if ( this.isShared( builder, output ) ) {
+	if ( this.getShared( builder, output ) ) {
 
-		var isUnique = this.isUnique( builder, output );
+		var isUnique = this.getUnique( builder, output );
 
 		if ( isUnique && this.constructor.uuid === undefined ) {
 
@@ -40,7 +40,7 @@ TempNode.prototype.build = function ( builder, output, uuid, ns ) {
 
 		if ( builder.parsing ) {
 
-			if ( ( data.deps || 0 ) > 0 ) {
+			if ( ( data.deps || 0 ) > 0 || this.getLabel() ) {
 
 				this.appendDepsNode( builder, data, output );
 
@@ -56,7 +56,7 @@ TempNode.prototype.build = function ( builder, output, uuid, ns ) {
 
 			return data.name;
 
-		} else if ( ! this.isShared( builder, type ) || ( ! builder.optimize || data.deps == 1 ) ) {
+		} else if ( ! this.getLabel() && ( ! this.getShared( builder, type ) || ( ! builder.optimize || data.deps === 1 ) ) ) {
 
 			return Node.prototype.build.call( this, builder, output, uuid );
 
@@ -88,23 +88,37 @@ TempNode.prototype.build = function ( builder, output, uuid, ns ) {
 
 };
 
-TempNode.prototype.isShared = function ( builder, output ) {
+TempNode.prototype.getShared = function ( builder, output ) {
 
 	return output !== 'sampler2D' && output !== 'samplerCube' && this.shared;
 
 };
 
-TempNode.prototype.isUnique = function ( builder, output ) {
+TempNode.prototype.getUnique = function ( builder, output ) {
 
 	return this.unique;
 
 };
 
+TempNode.prototype.setLabel = function ( name ) {
+
+	this.label = name;
+
+	return this;
+
+};
+
+TempNode.prototype.getLabel = function ( builder ) {
+
+	return this.label;
+
+};
+
 TempNode.prototype.getUuid = function ( unique ) {
 
 	var uuid = unique || unique == undefined ? this.constructor.uuid || this.uuid : this.uuid;
 
-	if ( typeof this.scope == "string" ) uuid = this.scope + '-' + uuid;
+	if ( typeof this.scope === "string" ) uuid = this.scope + '-' + uuid;
 
 	return uuid;
 
@@ -122,11 +136,11 @@ TempNode.prototype.getTemp = function ( builder, uuid ) {
 
 TempNode.prototype.generate = function ( builder, output, uuid, type, ns ) {
 
-	if ( ! this.isShared( builder, output ) ) console.error( "THREE.TempNode is not shared!" );
+	if ( ! this.getShared( builder, output ) ) console.error( "THREE.TempNode is not shared!" );
 
 	uuid = uuid || this.uuid;
 
-	return builder.getTempVar( uuid, type || this.getType( builder ), ns ).name;
+	return builder.getTempVar( uuid, type || this.getType( builder ), ns, this.getLabel() ).name;
 
 };
 

+ 51 - 0
examples/js/nodes/inputs/BoolNode.js

@@ -0,0 +1,51 @@
+/**
+ * @author sunag / http://www.sunag.com.br/
+ */
+
+import { InputNode } from '../core/InputNode.js';
+
+function BoolNode( value ) {
+
+	InputNode.call( this, 'b' );
+
+	this.value = Boolean( value );
+
+}
+
+BoolNode.prototype = Object.create( InputNode.prototype );
+BoolNode.prototype.constructor = BoolNode;
+BoolNode.prototype.nodeType = "Bool";
+
+BoolNode.prototype.generateReadonly = function ( builder, output, uuid, type, ns, needsUpdate ) {
+
+	return builder.format( this.value, type, output );
+
+};
+
+BoolNode.prototype.copy = function ( source ) {
+
+	InputNode.prototype.copy.call( this, source );
+
+	this.value = source.value;
+
+};
+
+BoolNode.prototype.toJSON = function ( meta ) {
+
+	var data = this.getJSONNode( meta );
+
+	if ( ! data ) {
+
+		data = this.createJSONNode( meta );
+
+		data.value = this.value;
+
+		if ( this.readonly === true ) data.readonly = true;
+
+	}
+
+	return data;
+
+};
+
+export { BoolNode };

+ 1 - 1
examples/js/nodes/inputs/ScreenNode.js

@@ -15,7 +15,7 @@ ScreenNode.prototype = Object.create( TextureNode.prototype );
 ScreenNode.prototype.constructor = ScreenNode;
 ScreenNode.prototype.nodeType = "Screen";
 
-ScreenNode.prototype.isUnique = function () {
+ScreenNode.prototype.getUnique = function () {
 
 	return true;
 

+ 1 - 0
examples/js/nodes/materials/PhongNodeMaterial.js

@@ -32,6 +32,7 @@ NodeUtils.addShortcuts( PhongNodeMaterial.prototype, 'fragment', [
 	'ao',
 	'environment',
 	'environmentAlpha',
+	'mask',
 	'position'
 ] );
 

+ 1 - 0
examples/js/nodes/materials/SpriteNodeMaterial.js

@@ -22,6 +22,7 @@ SpriteNodeMaterial.prototype.constructor = SpriteNodeMaterial;
 NodeUtils.addShortcuts( SpriteNodeMaterial.prototype, 'fragment', [
 	'color',
 	'alpha',
+	'mask',
 	'position',
 	'spherical'
 ] );

+ 1 - 0
examples/js/nodes/materials/StandardNodeMaterial.js

@@ -34,6 +34,7 @@ NodeUtils.addShortcuts( StandardNodeMaterial.prototype, 'fragment', [
 	'shadow',
 	'ao',
 	'environment',
+	'mask',
 	'position'
 ] );
 

+ 21 - 2
examples/js/nodes/materials/nodes/PhongNode.js

@@ -103,6 +103,8 @@ PhongNode.prototype.build = function ( builder ) {
 
 		// parse all nodes to reuse generate codes
 
+		if ( this.mask ) this.mask.parse( builder );
+
 		this.color.parse( builder, { slot: 'color' } );
 		this.specular.parse( builder );
 		this.shininess.parse( builder );
@@ -123,6 +125,8 @@ PhongNode.prototype.build = function ( builder ) {
 
 		// build code
 
+		var mask = this.mask ? this.mask.buildCode( builder, 'b' ) : undefined;
+
 		var color = this.color.buildCode( builder, 'c', { slot: 'color' } );
 		var specular = this.specular.buildCode( builder, 'c' );
 		var shininess = this.shininess.buildCode( builder, 'f' );
@@ -157,8 +161,19 @@ PhongNode.prototype.build = function ( builder ) {
 			"#include <normal_fragment_begin>",
 
 			// prevent undeclared material
-			"	BlinnPhongMaterial material;",
+			"	BlinnPhongMaterial material;"
+		];
+
+		if ( mask ) {
+
+			output.push(
+				mask.code,
+				'if ( ! ' + mask.result + ' ) discard;'
+			);
 
+		}
+
+		output.push(
 			color.code,
 			"	vec3 diffuseColor = " + color.result + ";",
 			"	ReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );",
@@ -172,7 +187,7 @@ PhongNode.prototype.build = function ( builder ) {
 			"	float shininess = max( 0.0001, " + shininess.result + " );",
 
 			"	float specularStrength = 1.0;" // Ignored in MaterialNode ( replace to specular )
-		];
+		);
 
 		if ( alpha ) {
 
@@ -335,6 +350,8 @@ PhongNode.prototype.copy = function ( source ) {
 	this.specular = source.specular;
 	this.shininess = source.shininess;
 
+	if ( source.mask ) this.mask = source.mask;
+
 	if ( source.alpha ) this.alpha = source.alpha;
 
 	if ( source.normal ) this.normal = source.normal;
@@ -370,6 +387,8 @@ PhongNode.prototype.toJSON = function ( meta ) {
 		data.specular = this.specular.toJSON( meta ).uuid;
 		data.shininess = this.shininess.toJSON( meta ).uuid;
 
+		if ( this.mask ) data.mask = this.mask.toJSON( meta ).uuid;
+
 		if ( this.alpha ) data.alpha = this.alpha.toJSON( meta ).uuid;
 
 		if ( this.normal ) data.normal = this.normal.toJSON( meta ).uuid;

+ 23 - 6
examples/js/nodes/materials/nodes/SpriteNode.js

@@ -123,18 +123,31 @@ SpriteNode.prototype.build = function ( builder ) {
 
 		// parse all nodes to reuse generate codes
 
+		if ( this.mask ) this.mask.parse( builder );
+
 		if ( this.alpha ) this.alpha.parse( builder );
 
 		this.color.parse( builder, { slot: 'color' } );
 
 		// build code
 
-		var alpha = this.alpha ? this.alpha.buildCode( builder, 'f' ) : undefined,
-			color = this.color.buildCode( builder, 'c', { slot: 'color' } );
+		var mask = this.mask ? this.mask.buildCode( builder, 'b' ) : undefined,
+			alpha = this.alpha ? this.alpha.buildCode( builder, 'f' ) : undefined,
+			color = this.color.buildCode( builder, 'c', { slot: 'color' } ),
+			output = [];
+
+		if ( mask ) {
+
+			output.push(
+				mask.code,
+				'if ( ! ' + mask.result + ' ) discard;'
+			);
+
+		}
 
 		if ( alpha ) {
 
-			output = [
+			output.push(
 				alpha.code,
 				'#ifdef ALPHATEST',
 
@@ -143,14 +156,14 @@ SpriteNode.prototype.build = function ( builder ) {
 				'#endif',
 				color.code,
 				"gl_FragColor = vec4( " + color.result + ", " + alpha.result + " );"
-			];
+			);
 
 		} else {
 
-			output = [
+			output.push(
 				color.code,
 				"gl_FragColor = vec4( " + color.result + ", 1.0 );"
-			];
+			);
 
 		}
 
@@ -180,6 +193,8 @@ SpriteNode.prototype.copy = function ( source ) {
 
 	if ( source.spherical !== undefined ) this.spherical = source.spherical;
 
+	if ( source.mask ) this.mask = source.mask;
+
 	if ( source.alpha ) this.alpha = source.alpha;
 
 };
@@ -202,6 +217,8 @@ SpriteNode.prototype.toJSON = function ( meta ) {
 
 		if ( this.spherical === false ) data.spherical = false;
 
+		if ( this.mask ) data.mask = this.mask.toJSON( meta ).uuid;
+
 		if ( this.alpha ) data.alpha = this.alpha.toJSON( meta ).uuid;
 
 	}

+ 22 - 3
examples/js/nodes/materials/nodes/StandardNode.js

@@ -117,6 +117,8 @@ StandardNode.prototype.build = function ( builder ) {
 
 		// parse all nodes to reuse generate codes
 
+		if ( this.mask ) this.mask.parse( builder );
+
 		this.color.parse( builder, { slot: 'color', context: contextGammaOnly } );
 		this.roughness.parse( builder );
 		this.metalness.parse( builder );
@@ -141,6 +143,8 @@ StandardNode.prototype.build = function ( builder ) {
 
 		// build code
 
+		var mask = this.mask ? this.mask.buildCode( builder, 'b' ) : undefined;
+
 		var color = this.color.buildCode( builder, 'c', { slot: 'color', context: contextGammaOnly } );
 		var roughness = this.roughness.buildCode( builder, 'f' );
 		var metalness = this.metalness.buildCode( builder, 'f' );
@@ -194,8 +198,19 @@ StandardNode.prototype.build = function ( builder ) {
 
 			// add before: prevent undeclared material
 			"	PhysicalMaterial material;",
-			"	material.diffuseColor = vec3( 1.0 );",
+			"	material.diffuseColor = vec3( 1.0 );"
+		];
+
+		if ( mask ) {
+
+			output.push(
+				mask.code,
+				'if ( ! ' + mask.result + ' ) discard;'
+			);
 
+		}
+
+		output.push(
 			color.code,
 			"	vec3 diffuseColor = " + color.result + ";",
 			"	ReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );",
@@ -207,7 +222,7 @@ StandardNode.prototype.build = function ( builder ) {
 
 			metalness.code,
 			"	float metalnessFactor = " + metalness.result + ";"
-		];
+		);
 
 		if ( alpha ) {
 
@@ -215,7 +230,7 @@ StandardNode.prototype.build = function ( builder ) {
 				alpha.code,
 				'#ifdef ALPHATEST',
 
-				'if ( ' + alpha.result + ' <= ALPHATEST ) discard;',
+				'	if ( ' + alpha.result + ' <= ALPHATEST ) discard;',
 
 				'#endif'
 			);
@@ -403,6 +418,8 @@ StandardNode.prototype.copy = function ( source ) {
 	this.roughness = source.roughness;
 	this.metalness = source.metalness;
 
+	if ( source.mask ) this.mask = source.mask;
+
 	if ( source.alpha ) this.alpha = source.alpha;
 
 	if ( source.normal ) this.normal = source.normal;
@@ -442,6 +459,8 @@ StandardNode.prototype.toJSON = function ( meta ) {
 		data.roughness = this.roughness.toJSON( meta ).uuid;
 		data.metalness = this.metalness.toJSON( meta ).uuid;
 
+		if ( this.mask ) data.mask = this.mask.toJSON( meta ).uuid;
+
 		if ( this.alpha ) data.alpha = this.alpha.toJSON( meta ).uuid;
 
 		if ( this.normal ) data.normal = this.normal.toJSON( meta ).uuid;

+ 35 - 16
examples/js/nodes/math/CondNode.js

@@ -4,18 +4,18 @@
 
 import { TempNode } from '../core/TempNode.js';
 
-function CondNode( a, b, ifNode, elseNode, op ) {
+function CondNode( a, b, op, ifNode, elseNode ) {
 
 	TempNode.call( this );
 
 	this.a = a;
 	this.b = b;
 
+	this.op = op;
+	
 	this.ifNode = ifNode;
 	this.elseNode = elseNode;
 
-	this.op = op;
-
 }
 
 CondNode.EQUAL = '==';
@@ -31,13 +31,22 @@ CondNode.prototype.nodeType = "Cond";
 
 CondNode.prototype.getType = function ( builder ) {
 
-	if ( builder.getTypeLength( this.elseNode.getType( builder ) ) > builder.getTypeLength( this.ifNode.getType( builder ) ) ) {
+	if (this.ifNode) {
+		
+		var ifType = this.ifNode.getType( builder );
+		var elseType = this.elseNode.getType( builder );
+		
+		if ( builder.getTypeLength( elseType ) > builder.getTypeLength( ifType ) ) {
 
-		return this.elseNode.getType( builder );
+			return elseType;
 
-	}
+		}
 
-	return this.ifNode.getType( builder );
+		return ifType;
+		
+	}
+	
+	return 'b';
 
 };
 
@@ -59,10 +68,20 @@ CondNode.prototype.generate = function ( builder, output ) {
 		condType = this.getCondType( builder ),
 		a = this.a.build( builder, condType ),
 		b = this.b.build( builder, condType ),
-		ifNode = this.ifNode.build( builder, type ),
-		elseNode = this.elseNode.build( builder, type );
-
-	var code = '( ' + [ a, this.op, b, '?', ifNode, ':', elseNode ].join( ' ' ) + ' )';
+		code;
+		
+	if (this.ifNode) {
+		
+		var ifCode = this.ifNode.build( builder, type ),
+			elseCode = this.elseNode.build( builder, type );
+		
+		code = '( ' + [ a, this.op, b, '?', ifCode, ':', elseCode ].join( ' ' ) + ' )';
+		
+	} else {
+
+		code = '( ' + a + ' ' + this.op + ' ' +  b  + ' )';
+		
+	}
 
 	return builder.format( code, this.getType( builder ), output );
 
@@ -75,11 +94,11 @@ CondNode.prototype.copy = function ( source ) {
 	this.a = source.a;
 	this.b = source.b;
 
+	this.op = source.op;
+
 	this.ifNode = source.ifNode;
 	this.elseNode = source.elseNode;
 
-	this.op = source.op;
-
 };
 
 CondNode.prototype.toJSON = function ( meta ) {
@@ -93,11 +112,11 @@ CondNode.prototype.toJSON = function ( meta ) {
 		data.a = this.a.toJSON( meta ).uuid;
 		data.b = this.b.toJSON( meta ).uuid;
 
-		data.ifNode = this.ifNode.toJSON( meta ).uuid;
-		data.elseNode = this.elseNode.toJSON( meta ).uuid;
-
 		data.op = this.op;
 
+		if ( data.ifNode ) data.ifNode = this.ifNode.toJSON( meta ).uuid;
+		if ( data.elseNode ) data.elseNode = this.elseNode.toJSON( meta ).uuid;
+
 	}
 
 	return data;

+ 2 - 2
examples/js/nodes/utils/ColorSpaceNode.js

@@ -131,7 +131,7 @@ ColorSpaceNode.Nodes = ( function () {
 	var LinearToLogLuv = new FunctionNode( [
 		"vec4 LinearToLogLuv( in vec4 value ) {",
 
-		"	vec3 Xp_Y_XYZp = value.rgb * cLogLuvM;",
+		"	vec3 Xp_Y_XYZp = cLogLuvM * value.rgb;",
 		"	Xp_Y_XYZp = max(Xp_Y_XYZp, vec3(1e-6, 1e-6, 1e-6));",
 		"	vec4 vResult;",
 		"	vResult.xy = Xp_Y_XYZp.xy / Xp_Y_XYZp.z;",
@@ -155,7 +155,7 @@ ColorSpaceNode.Nodes = ( function () {
 		"	Xp_Y_XYZp.y = exp2((Le - 127.0) / 2.0);",
 		"	Xp_Y_XYZp.z = Xp_Y_XYZp.y / value.y;",
 		"	Xp_Y_XYZp.x = value.x * Xp_Y_XYZp.z;",
-		"	vec3 vRGB = Xp_Y_XYZp.rgb * cLogLuvInverseM;",
+		"	vec3 vRGB = cLogLuvInverseM * Xp_Y_XYZp.rgb;",
 		"	return vec4( max(vRGB, 0.0), 1.0 );",
 
 		"}"

+ 3 - 3
examples/js/nodes/utils/TimerNode.js

@@ -12,7 +12,7 @@ function TimerNode( scale, scope, timeScale ) {
 	this.scale = scale !== undefined ? scale : 1;
 	this.scope = scope || TimerNode.GLOBAL;
 
-	this.timeScale = timeScale !== undefined ? timeScale : this.scale !== 1;
+	this.timeScale = timeScale !== undefined ? timeScale : scale !== undefined;
 
 }
 
@@ -24,7 +24,7 @@ TimerNode.prototype = Object.create( FloatNode.prototype );
 TimerNode.prototype.constructor = TimerNode;
 TimerNode.prototype.nodeType = "Timer";
 
-TimerNode.prototype.isReadonly = function () {
+TimerNode.prototype.getReadonly = function () {
 
 	// never use TimerNode as readonly but aways as "uniform"
 
@@ -32,7 +32,7 @@ TimerNode.prototype.isReadonly = function () {
 
 };
 
-TimerNode.prototype.isUnique = function () {
+TimerNode.prototype.getUnique = function () {
 
 	// share TimerNode "uniform" input if is used on more time with others TimerNode
 

+ 1 - 1
examples/js/nodes/utils/VelocityNode.js

@@ -21,7 +21,7 @@ VelocityNode.prototype = Object.create( Vector3Node.prototype );
 VelocityNode.prototype.constructor = VelocityNode;
 VelocityNode.prototype.nodeType = "Velocity";
 
-VelocityNode.prototype.isReadonly = function ( builder ) {
+VelocityNode.prototype.getReadonly = function ( builder ) {
 
 	return false;
 

+ 37 - 37
examples/js/objects/Fire.js

@@ -58,7 +58,7 @@ THREE.Fire = function ( geometry, options ) {
 
 		}
 
-		this.sourceMaterial.uniforms.sourceMap.value = this.internalSource;
+		this.sourceMaterial.uniforms[ "sourceMap" ].value = this.internalSource;
 		this.sourceMaterial.needsUpdate = true;
 
 		return this.sourceData;
@@ -121,7 +121,7 @@ THREE.Fire = function ( geometry, options ) {
 	// (0 -> 127 = 0.0 -> 1.0, 128 -> 255 = -1.0 -> 0.0 )
 	this.setSourceMap = function ( texture ) {
 
-		this.sourceMaterial.uniforms.sourceMap.value = texture;
+		this.sourceMaterial.uniforms[ "sourceMap" ].value = texture;
 
 	};
 
@@ -190,8 +190,8 @@ THREE.Fire = function ( geometry, options ) {
 		transparent: false
 	} );
 
-	this.diffuseMaterial.uniforms.oneOverWidth.value = oneOverWidth;
-	this.diffuseMaterial.uniforms.oneOverHeight.value = oneOverHeight;
+	this.diffuseMaterial.uniforms[ "oneOverWidth" ].value = oneOverWidth;
+	this.diffuseMaterial.uniforms[ "oneOverHeight" ].value = oneOverHeight;
 
 	this.diffuseMesh = new THREE.Mesh( this.fieldGeometry, this.diffuseMaterial );
 	this.fieldScene.add( this.diffuseMesh );
@@ -206,8 +206,8 @@ THREE.Fire = function ( geometry, options ) {
 		transparent: false
 	} );
 
-	this.driftMaterial.uniforms.oneOverWidth.value = oneOverWidth;
-	this.driftMaterial.uniforms.oneOverHeight.value = oneOverHeight;
+	this.driftMaterial.uniforms[ "oneOverWidth" ].value = oneOverWidth;
+	this.driftMaterial.uniforms[ "oneOverHeight" ].value = oneOverHeight;
 
 	this.driftMesh = new THREE.Mesh( this.fieldGeometry, this.driftMaterial );
 	this.fieldScene.add( this.driftMesh );
@@ -222,8 +222,8 @@ THREE.Fire = function ( geometry, options ) {
 		transparent: false
 	} );
 
-	this.projMaterial1.uniforms.oneOverWidth.value = oneOverWidth;
-	this.projMaterial1.uniforms.oneOverHeight.value = oneOverHeight;
+	this.projMaterial1.uniforms[ "oneOverWidth" ].value = oneOverWidth;
+	this.projMaterial1.uniforms[ "oneOverHeight" ].value = oneOverHeight;
 
 	this.projMesh1 = new THREE.Mesh( this.fieldGeometry, this.projMaterial1 );
 	this.fieldScene.add( this.projMesh1 );
@@ -239,8 +239,8 @@ THREE.Fire = function ( geometry, options ) {
 	} );
 
 
-	this.projMaterial2.uniforms.oneOverWidth.value = oneOverWidth;
-	this.projMaterial2.uniforms.oneOverHeight.value = oneOverHeight;
+	this.projMaterial2.uniforms[ "oneOverWidth" ].value = oneOverWidth;
+	this.projMaterial2.uniforms[ "oneOverHeight" ].value = oneOverHeight;
 
 	this.projMesh2 = new THREE.Mesh( this.fieldGeometry, this.projMaterial2 );
 	this.fieldScene.add( this.projMesh2 );
@@ -256,8 +256,8 @@ THREE.Fire = function ( geometry, options ) {
 	} );
 
 
-	this.projMaterial3.uniforms.oneOverWidth.value = oneOverWidth;
-	this.projMaterial3.uniforms.oneOverHeight.value = oneOverHeight;
+	this.projMaterial3.uniforms[ "oneOverWidth" ].value = oneOverWidth;
+	this.projMaterial3.uniforms[ "oneOverHeight" ].value = oneOverHeight;
 
 	this.projMesh3 = new THREE.Mesh( this.fieldGeometry, this.projMaterial3 );
 	this.fieldScene.add( this.projMesh3 );
@@ -280,31 +280,31 @@ THREE.Fire = function ( geometry, options ) {
 		transparent: true
 	} );
 
-	this.material.uniforms.densityMap.value = this.field1.texture;
+	this.material.uniforms[ "densityMap" ].value = this.field1.texture;
 
 	this.configShaders = function ( dt ) {
 
-		this.diffuseMaterial.uniforms.diffuse.value = dt * 0.05 * this.diffuse;
-		this.diffuseMaterial.uniforms.viscosity.value = dt * 0.05 * this.viscosity;
-		this.diffuseMaterial.uniforms.expansion.value = Math.exp( this.expansion * - 1.0 );
-		this.diffuseMaterial.uniforms.swirl.value = Math.exp( this.swirl * - 0.1 );
-		this.diffuseMaterial.uniforms.drag.value = Math.exp( this.drag * - 0.1 );
-		this.diffuseMaterial.uniforms.burnRate.value = this.burnRate * dt * 0.01;
-		this.driftMaterial.uniforms.windVector.value = this.windVector;
-		this.driftMaterial.uniforms.airSpeed.value = dt * this.airSpeed * 0.001 * textureHeight;
-		this.material.uniforms.color1.value = this.color1;
-		this.material.uniforms.color2.value = this.color2;
-		this.material.uniforms.color3.value = this.color3;
-		this.material.uniforms.colorBias.value = this.colorBias;
+		this.diffuseMaterial.uniforms[ "diffuse" ].value = dt * 0.05 * this.diffuse;
+		this.diffuseMaterial.uniforms[ "viscosity" ].value = dt * 0.05 * this.viscosity;
+		this.diffuseMaterial.uniforms[ "expansion" ].value = Math.exp( this.expansion * - 1.0 );
+		this.diffuseMaterial.uniforms[ "swirl" ].value = Math.exp( this.swirl * - 0.1 );
+		this.diffuseMaterial.uniforms[ "drag" ].value = Math.exp( this.drag * - 0.1 );
+		this.diffuseMaterial.uniforms[ "burnRate" ].value = this.burnRate * dt * 0.01;
+		this.driftMaterial.uniforms[ "windVector" ].value = this.windVector;
+		this.driftMaterial.uniforms[ "airSpeed" ].value = dt * this.airSpeed * 0.001 * textureHeight;
+		this.material.uniforms[ "color1" ].value = this.color1;
+		this.material.uniforms[ "color2" ].value = this.color2;
+		this.material.uniforms[ "color3" ].value = this.color3;
+		this.material.uniforms[ "colorBias" ].value = this.colorBias;
 
 	};
 
 	this.clearDiffuse = function () {
 
-		this.diffuseMaterial.uniforms.expansion.value = 1.0;
-		this.diffuseMaterial.uniforms.swirl.value = 1.0;
-		this.diffuseMaterial.uniforms.drag.value = 1.0;
-		this.diffuseMaterial.uniforms.burnRate.value = 0.0;
+		this.diffuseMaterial.uniforms[ "expansion" ].value = 1.0;
+		this.diffuseMaterial.uniforms[ "swirl" ].value = 1.0;
+		this.diffuseMaterial.uniforms[ "drag" ].value = 1.0;
+		this.diffuseMaterial.uniforms[ "burnRate" ].value = 0.0;
 
 	};
 
@@ -340,7 +340,7 @@ THREE.Fire = function ( geometry, options ) {
 
 		this.sourceMesh.visible = true;
 
-		this.sourceMaterial.uniforms.densityMap.value = this.field0.texture;
+		this.sourceMaterial.uniforms[ "densityMap" ].value = this.field0.texture;
 
 		renderer.render( this.fieldScene, this.orthoCamera, this.field1 );
 
@@ -354,7 +354,7 @@ THREE.Fire = function ( geometry, options ) {
 
 		this.diffuseMesh.visible = true;
 
-		this.diffuseMaterial.uniforms.densityMap.value = this.field0.texture;
+		this.diffuseMaterial.uniforms[ "densityMap" ].value = this.field0.texture;
 
 		renderer.render( this.fieldScene, this.orthoCamera, this.field1 );
 
@@ -368,7 +368,7 @@ THREE.Fire = function ( geometry, options ) {
 
 		this.driftMesh.visible = true;
 
-		this.driftMaterial.uniforms.densityMap.value = this.field0.texture;
+		this.driftMaterial.uniforms[ "densityMap" ].value = this.field0.texture;
 
 		renderer.render( this.fieldScene, this.orthoCamera, this.field1 );
 
@@ -384,13 +384,13 @@ THREE.Fire = function ( geometry, options ) {
 
 		this.projMesh1.visible = true;
 
-		this.projMaterial1.uniforms.densityMap.value = this.field0.texture;
+		this.projMaterial1.uniforms[ "densityMap" ].value = this.field0.texture;
 
 		renderer.render( this.fieldScene, this.orthoCamera, this.fieldProj );
 
 		this.projMesh1.visible = false;
 
-		this.projMaterial2.uniforms.densityMap.value = this.fieldProj.texture;
+		this.projMaterial2.uniforms[ "densityMap" ].value = this.fieldProj.texture;
 
 		// Projection pass 2
 
@@ -404,14 +404,14 @@ THREE.Fire = function ( geometry, options ) {
 			this.field1 = this.fieldProj;
 			this.fieldProj = temp;
 
-			this.projMaterial2.uniforms.densityMap.value = this.fieldProj.texture;
+			this.projMaterial2.uniforms[ "densityMap" ].value = this.fieldProj.texture;
 
 		}
 
 		this.projMesh2.visible = false;
 
-		this.projMaterial3.uniforms.densityMap.value = this.field0.texture;
-		this.projMaterial3.uniforms.projMap.value = this.fieldProj.texture;
+		this.projMaterial3.uniforms[ "densityMap" ].value = this.field0.texture;
+		this.projMaterial3.uniforms[ "projMap" ].value = this.fieldProj.texture;
 
 		// Projection pass 3
 

+ 9 - 9
examples/js/objects/Lensflare.js

@@ -199,8 +199,8 @@ THREE.Lensflare = function () {
 			// render pink quad
 
 			var uniforms = material1a.uniforms;
-			uniforms.scale.value = scale;
-			uniforms.screenPosition.value = positionScreen;
+			uniforms[ "scale" ].value = scale;
+			uniforms[ "screenPosition" ].value = positionScreen;
 
 			renderer.renderBufferDirect( camera, null, geometry, material1a, mesh1, null );
 
@@ -211,8 +211,8 @@ THREE.Lensflare = function () {
 			// restore graphics
 
 			var uniforms = material1b.uniforms;
-			uniforms.scale.value = scale;
-			uniforms.screenPosition.value = positionScreen;
+			uniforms[ "scale" ].value = scale;
+			uniforms[ "screenPosition" ].value = positionScreen;
 
 			renderer.renderBufferDirect( camera, null, geometry, material1b, mesh1, null );
 
@@ -227,15 +227,15 @@ THREE.Lensflare = function () {
 
 				var uniforms = material2.uniforms;
 
-				uniforms.color.value.copy( element.color );
-				uniforms.map.value = element.texture;
-				uniforms.screenPosition.value.x = positionScreen.x + vecX * element.distance;
-				uniforms.screenPosition.value.y = positionScreen.y + vecY * element.distance;
+				uniforms[ "color" ].value.copy( element.color );
+				uniforms[ "map" ].value = element.texture;
+				uniforms[ "screenPosition" ].value.x = positionScreen.x + vecX * element.distance;
+				uniforms[ "screenPosition" ].value.y = positionScreen.y + vecY * element.distance;
 
 				var size = element.size / viewport.w;
 				var invAspect = viewport.w / viewport.z;
 
-				uniforms.scale.value.set( size * invAspect, size );
+				uniforms[ "scale" ].value.set( size * invAspect, size );
 
 				material2.uniformsNeedUpdate = true;
 

+ 3 - 4
examples/js/objects/Reflector.js

@@ -58,12 +58,11 @@ THREE.Reflector = function ( geometry, options ) {
 		vertexShader: shader.vertexShader
 	} );
 
-	material.uniforms.tDiffuse.value = renderTarget.texture;
-	material.uniforms.color.value = color;
-	material.uniforms.textureMatrix.value = textureMatrix;
+	material.uniforms[ "tDiffuse" ].value = renderTarget.texture;
+	material.uniforms[ "color" ].value = color;
+	material.uniforms[ "textureMatrix" ].value = textureMatrix;
 
 	this.material = material;
-	this.renderOrder = - Infinity; // render first
 
 	this.onBeforeRender = function ( renderer, scene, camera ) {
 

+ 3 - 3
examples/js/objects/Refractor.js

@@ -56,9 +56,9 @@ THREE.Refractor = function ( geometry, options ) {
 		transparent: true // ensures, refractors are drawn from farthest to closest
 	} );
 
-	this.material.uniforms.color.value = color;
-	this.material.uniforms.tDiffuse.value = renderTarget.texture;
-	this.material.uniforms.textureMatrix.value = textureMatrix;
+	this.material.uniforms[ "color" ].value = color;
+	this.material.uniforms[ "tDiffuse" ].value = renderTarget.texture;
+	this.material.uniforms[ "textureMatrix" ].value = textureMatrix;
 
 	// functions
 

+ 6 - 6
examples/js/objects/Sky.js

@@ -34,12 +34,12 @@ THREE.Sky.prototype = Object.create( THREE.Mesh.prototype );
 THREE.Sky.SkyShader = {
 
 	uniforms: {
-		luminance: { value: 1 },
-		turbidity: { value: 2 },
-		rayleigh: { value: 1 },
-		mieCoefficient: { value: 0.005 },
-		mieDirectionalG: { value: 0.8 },
-		sunPosition: { value: new THREE.Vector3() }
+		"luminance": { value: 1 },
+		"turbidity": { value: 2 },
+		"rayleigh": { value: 1 },
+		"mieCoefficient": { value: 0.005 },
+		"mieDirectionalG": { value: 0.8 },
+		"sunPosition": { value: new THREE.Vector3() }
 	},
 
 	vertexShader: [

+ 22 - 22
examples/js/objects/Water.js

@@ -69,17 +69,17 @@ THREE.Water = function ( geometry, options ) {
 			THREE.UniformsLib[ 'fog' ],
 			THREE.UniformsLib[ 'lights' ],
 			{
-				normalSampler: { value: null },
-				mirrorSampler: { value: null },
-				alpha: { value: 1.0 },
-				time: { value: 0.0 },
-				size: { value: 1.0 },
-				distortionScale: { value: 20.0 },
-				textureMatrix: { value: new THREE.Matrix4() },
-				sunColor: { value: new THREE.Color( 0x7F7F7F ) },
-				sunDirection: { value: new THREE.Vector3( 0.70707, 0.70707, 0 ) },
-				eye: { value: new THREE.Vector3() },
-				waterColor: { value: new THREE.Color( 0x555555 ) }
+				"normalSampler": { value: null },
+				"mirrorSampler": { value: null },
+				"alpha": { value: 1.0 },
+				"time": { value: 0.0 },
+				"size": { value: 1.0 },
+				"distortionScale": { value: 20.0 },
+				"textureMatrix": { value: new THREE.Matrix4() },
+				"sunColor": { value: new THREE.Color( 0x7F7F7F ) },
+				"sunDirection": { value: new THREE.Vector3( 0.70707, 0.70707, 0 ) },
+				"eye": { value: new THREE.Vector3() },
+				"waterColor": { value: new THREE.Color( 0x555555 ) }
 			}
 		] ),
 
@@ -190,17 +190,17 @@ THREE.Water = function ( geometry, options ) {
 		fog: fog
 	} );
 
-	material.uniforms.mirrorSampler.value = renderTarget.texture;
-	material.uniforms.textureMatrix.value = textureMatrix;
-	material.uniforms.alpha.value = alpha;
-	material.uniforms.time.value = time;
-	material.uniforms.normalSampler.value = normalSampler;
-	material.uniforms.sunColor.value = sunColor;
-	material.uniforms.waterColor.value = waterColor;
-	material.uniforms.sunDirection.value = sunDirection;
-	material.uniforms.distortionScale.value = distortionScale;
-
-	material.uniforms.eye.value = eye;
+	material.uniforms[ "mirrorSampler" ].value = renderTarget.texture;
+	material.uniforms[ "textureMatrix" ].value = textureMatrix;
+	material.uniforms[ "alpha" ].value = alpha;
+	material.uniforms[ "time" ].value = time;
+	material.uniforms[ "normalSampler" ].value = normalSampler;
+	material.uniforms[ "sunColor" ].value = sunColor;
+	material.uniforms[ "waterColor" ].value = waterColor;
+	material.uniforms[ "sunDirection" ].value = sunDirection;
+	material.uniforms[ "distortionScale" ].value = distortionScale;
+
+	material.uniforms[ "eye" ].value = eye;
 
 	scope.material = material;
 

+ 14 - 14
examples/js/objects/Water2.js

@@ -85,14 +85,14 @@ THREE.Water = function ( geometry, options ) {
 	if ( flowMap !== undefined ) {
 
 		this.material.defines.USE_FLOWMAP = '';
-		this.material.uniforms.tFlowMap = {
+		this.material.uniforms[ "tFlowMap" ] = {
 			type: 't',
 			value: flowMap
 		};
 
 	} else {
 
-		this.material.uniforms.flowDirection = {
+		this.material.uniforms[ "flowDirection" ] = {
 			type: 'v2',
 			value: flowDirection
 		};
@@ -104,23 +104,23 @@ THREE.Water = function ( geometry, options ) {
 	normalMap0.wrapS = normalMap0.wrapT = THREE.RepeatWrapping;
 	normalMap1.wrapS = normalMap1.wrapT = THREE.RepeatWrapping;
 
-	this.material.uniforms.tReflectionMap.value = reflector.getRenderTarget().texture;
-	this.material.uniforms.tRefractionMap.value = refractor.getRenderTarget().texture;
-	this.material.uniforms.tNormalMap0.value = normalMap0;
-	this.material.uniforms.tNormalMap1.value = normalMap1;
+	this.material.uniforms[ "tReflectionMap" ].value = reflector.getRenderTarget().texture;
+	this.material.uniforms[ "tRefractionMap" ].value = refractor.getRenderTarget().texture;
+	this.material.uniforms[ "tNormalMap0" ].value = normalMap0;
+	this.material.uniforms[ "tNormalMap1" ].value = normalMap1;
 
 	// water
 
-	this.material.uniforms.color.value = color;
-	this.material.uniforms.reflectivity.value = reflectivity;
-	this.material.uniforms.textureMatrix.value = textureMatrix;
+	this.material.uniforms[ "color" ].value = color;
+	this.material.uniforms[ "reflectivity" ].value = reflectivity;
+	this.material.uniforms[ "textureMatrix" ].value = textureMatrix;
 
 	// inital values
 
-	this.material.uniforms.config.value.x = 0; // flowMapOffset0
-	this.material.uniforms.config.value.y = halfCycle; // flowMapOffset1
-	this.material.uniforms.config.value.z = halfCycle; // halfCycle
-	this.material.uniforms.config.value.w = scale; // scale
+	this.material.uniforms[ "config" ].value.x = 0; // flowMapOffset0
+	this.material.uniforms[ "config" ].value.y = halfCycle; // flowMapOffset1
+	this.material.uniforms[ "config" ].value.z = halfCycle; // halfCycle
+	this.material.uniforms[ "config" ].value.w = scale; // scale
 
 	// functions
 
@@ -142,7 +142,7 @@ THREE.Water = function ( geometry, options ) {
 	function updateFlow() {
 
 		var delta = clock.getDelta();
-		var config = scope.material.uniforms.config;
+		var config = scope.material.uniforms[ "config" ];
 
 		config.value.x += flowSpeed * delta; // flowMapOffset0
 		config.value.y = config.value.x + halfCycle; // flowMapOffset1

+ 6 - 2
examples/js/offscreen/scene.js

@@ -71,7 +71,11 @@ function animate() {
 // PRNG
 
 var seed = 1;
+
 function random() {
-	var x = Math.sin(seed++) * 10000;
-	return x - Math.floor(x);
+
+	var x = Math.sin( seed ++ ) * 10000;
+
+	return x - Math.floor( x );
+
 }

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

@@ -130,7 +130,7 @@ THREE.AdaptiveToneMappingPass.prototype = Object.assign( Object.create( THREE.Pa
 
 	constructor: THREE.AdaptiveToneMappingPass,
 
-	render: function ( renderer, writeBuffer, readBuffer, delta, maskActive ) {
+	render: function ( renderer, writeBuffer, readBuffer, deltaTime, maskActive ) {
 
 		if ( this.needsInit ) {
 
@@ -153,7 +153,7 @@ THREE.AdaptiveToneMappingPass.prototype = Object.assign( Object.create( THREE.Pa
 			//Use the new luminance values, the previous luminance and the frame delta to
 			//adapt the luminance over time.
 			this.quad.material = this.materialAdaptiveLum;
-			this.materialAdaptiveLum.uniforms.delta.value = delta;
+			this.materialAdaptiveLum.uniforms.delta.value = deltaTime;
 			this.materialAdaptiveLum.uniforms.lastLum.value = this.previousLuminanceRT.texture;
 			this.materialAdaptiveLum.uniforms.currentLum.value = this.currentLuminanceRT.texture;
 			renderer.render( this.scene, this.camera, this.luminanceRT );

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

@@ -80,7 +80,7 @@ THREE.BloomPass.prototype = Object.assign( Object.create( THREE.Pass.prototype )
 
 	constructor: THREE.BloomPass,
 
-	render: function ( renderer, writeBuffer, readBuffer, delta, maskActive ) {
+	render: function ( renderer, writeBuffer, readBuffer, deltaTime, maskActive ) {
 
 		if ( maskActive ) renderer.context.disable( renderer.context.STENCIL_TEST );
 

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

@@ -82,7 +82,7 @@ THREE.BokehPass.prototype = Object.assign( Object.create( THREE.Pass.prototype )
 
 	constructor: THREE.BokehPass,
 
-	render: function ( renderer, writeBuffer, readBuffer, delta, maskActive ) {
+	render: function ( renderer, writeBuffer, readBuffer, deltaTime, maskActive ) {
 
 		this.quad2.material = this.materialBokeh;
 

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

@@ -17,7 +17,7 @@ THREE.ClearPass.prototype = Object.assign( Object.create( THREE.Pass.prototype )
 
 	constructor: THREE.ClearPass,
 
-	render: function ( renderer, writeBuffer, readBuffer, delta, maskActive ) {
+	render: function ( renderer, writeBuffer, readBuffer, deltaTime, maskActive ) {
 
 		var oldClearColor, oldClearAlpha;
 

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

@@ -36,7 +36,7 @@ THREE.CubeTexturePass.prototype = Object.assign( Object.create( THREE.Pass.proto
 
 	constructor: THREE.CubeTexturePass,
 
-	render: function ( renderer, writeBuffer, readBuffer, delta, maskActive ) {
+	render: function ( renderer, writeBuffer, readBuffer, deltaTime, maskActive ) {
 
 		var oldAutoClear = renderer.autoClear;
 		renderer.autoClear = false;

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