Bladeren bron

Merge pull request #7 from mrdoob/dev

merge from upstream
gogoend 6 jaren geleden
bovenliggende
commit
a30489ceab
58 gewijzigde bestanden met toevoegingen van 933 en 749 verwijderingen
  1. 8 2
      build/three.js
  2. 218 218
      build/three.min.js
  3. 8 2
      build/three.module.js
  4. 0 1
      docs/api/en/cameras/CubeCamera.html
  5. 0 3
      docs/api/en/core/Geometry.html
  6. 0 1
      docs/api/en/helpers/AxesHelper.html
  7. 1 1
      docs/api/en/helpers/RectAreaLightHelper.html
  8. 1 1
      docs/api/en/lights/RectAreaLight.html
  9. 0 1
      docs/api/en/loaders/CubeTextureLoader.html
  10. 0 4
      docs/api/en/loaders/FileLoader.html
  11. 0 1
      docs/api/en/materials/LineBasicMaterial.html
  12. 0 2
      docs/api/en/materials/PointsMaterial.html
  13. 0 1
      docs/api/en/materials/ShaderMaterial.html
  14. 42 26
      docs/api/en/objects/SkinnedMesh.html
  15. 1 1
      docs/api/en/renderers/WebGLRenderer.html
  16. 4 4
      docs/api/zh/core/bufferAttributeTypes/BufferAttributeTypes.html
  17. 6 6
      docs/api/zh/extras/Earcut.html
  18. 12 15
      docs/api/zh/extras/ShapeUtils.html
  19. 41 23
      docs/api/zh/objects/SkinnedMesh.html
  20. 2 2
      docs/manual/en/introduction/Browser-support.html
  21. 2 1
      docs/manual/en/introduction/Loading-3D-models.html
  22. 60 69
      docs/manual/zh/buildTools/Testing-with-NPM.html
  23. 49 53
      docs/manual/zh/introduction/Animation-system.html
  24. 1 1
      docs/manual/zh/introduction/Browser-support.html
  25. 33 34
      docs/manual/zh/introduction/How-to-update-things.html
  26. 14 14
      docs/manual/zh/introduction/Matrix-transformations.html
  27. 7 7
      docs/page.js
  28. 34 25
      docs/scenes/bones-browser.html
  29. 5 0
      examples/js/Octree.js
  30. 3 1
      examples/js/VolumeSlice.js
  31. 13 13
      examples/js/animation/MMDPhysics.js
  32. 3 2
      examples/js/controls/EditorControls.js
  33. 66 19
      examples/js/exporters/GLTFExporter.js
  34. 23 1
      examples/js/loaders/ColladaLoader.js
  35. 17 0
      examples/js/loaders/GLTFLoader.js
  36. 18 24
      examples/js/loaders/KTXLoader.js
  37. 15 0
      examples/js/loaders/MTLLoader.js
  38. 1 1
      examples/js/nodes/math/Math1Node.js
  39. 1 0
      examples/js/nodes/math/Math3Node.js
  40. 18 13
      examples/js/renderers/RaytracingWorker.js
  41. 1 1
      examples/js/renderers/SoftwareRenderer.js
  42. 3 3
      examples/raytracing_sandbox.html
  43. 35 24
      examples/software_lines_splines.html
  44. 63 32
      examples/software_sandbox.html
  45. 27 15
      examples/svg_sandbox.html
  46. 1 2
      examples/webgl_lights_rectarealight.html
  47. 2 2
      examples/webgl_loader_nrrd.html
  48. 1 19
      examples/webgl_materials.html
  49. 7 7
      examples/webgl_materials_nodes.html
  50. 2 1
      rollup.config.js
  51. 2 0
      src/audio/PositionalAudio.js
  52. 1 1
      src/constants.js
  53. 1 1
      src/core/Object3D.js
  54. 5 7
      src/geometries/ShapeGeometry.js
  55. 39 36
      src/helpers/RectAreaLightHelper.js
  56. 5 0
      src/loaders/ObjectLoader.js
  57. 4 4
      src/renderers/shaders/ShaderChunk/lights_physical_pars_fragment.glsl.js
  58. 7 1
      src/textures/Texture.js

File diff suppressed because it is too large
+ 8 - 2
build/three.js


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


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


+ 0 - 1
docs/api/en/cameras/CubeCamera.html

@@ -17,7 +17,6 @@
 		<h2>Examples</h2>
 
 		<p>[example:webgl_materials_cubemap_dynamic materials / cubemap / dynamic ]</p>
-		<p>[example:webgl_materials_cubemap_dynamic2 materials / cubemap / dynamic2 ]</p>
 		<p>[example:webgl_shading_physical shading / physical ]</p>
 
 		<code>// Create cube camera

+ 0 - 3
docs/api/en/core/Geometry.html

@@ -32,7 +32,6 @@
 		<div>[example:webgl_interactive_lines WebGL / interactive / lines ]</div>
 		<div>[example:webgl_interactive_raycasting_points WebGL / interactive / raycasting / points ]</div>
 		<div>[example:webgl_interactive_voxelpainter WebGL / interactive / voxelpainter ]</div>
-		<div>[example:webgl_morphnormals WebGL / morphNormals ]</div>
 
 
 		<code>var geometry = new THREE.Geometry();
@@ -123,8 +122,6 @@
 		<p>
 		Array of morph normals. Morph normals have similar structure as morph targets, each normal set is a Javascript object:
 		<code>morphNormal = { name: "NormalName", normals: [ new THREE.Vector3(), ... ] }</code>
-
-		See the [example:webgl_morphnormals WebGL / morphNormals] example.
 		</p>
 
 		<h3>[property:String name]</h3>

+ 0 - 1
docs/api/en/helpers/AxesHelper.html

@@ -19,7 +19,6 @@
 		<h2>Example</h2>
 
 		<div>[example:webgl_geometries WebGL / geometries]</div>
-		<div>[example:webgl_geometries2 WebGL / geometries2]</div>
 		<div>[example:webgl_geometry_convex WebGL / geometry / convex]</div>
 		<div>[example:webgl_geometry_spline_editor WebGL / geometry / spline / editor]</div>
 

+ 1 - 1
docs/api/en/helpers/RectAreaLightHelper.html

@@ -23,7 +23,7 @@ var light = new THREE.RectAreaLight( 0xffffbb, 1.0, 5, 5 );
 
 var helper = new THREE.RectAreaLightHelper( light );
 
-scene.add( helper );
+light.add( helper ); // helper must be added as a child of the light
 		</code>
 
 

+ 1 - 1
docs/api/en/lights/RectAreaLight.html

@@ -41,7 +41,7 @@ rectLight.lookAt( 0, 0, 0 );
 scene.add( rectLight )
 
 rectLightHelper = new THREE.RectAreaLightHelper( rectLight );
-scene.add( rectLightHelper );
+rectLight.add( rectLightHelper );
 
 			</code>
 		</p>

+ 0 - 1
docs/api/en/loaders/CubeTextureLoader.html

@@ -22,7 +22,6 @@
 			[example:webgl_materials_cubemap_balls_reflection materials / cubemap / balls / reflection]<br />
 			[example:webgl_materials_cubemap_balls_refraction materials / cubemap / balls / refraction]<br />
 			[example:webgl_materials_cubemap_dynamic materials / cubemap / dynamic]<br />
-			[example:webgl_materials_cubemap_dynamic2 materials / cubemap / dynamic2]<br />
 			[example:webgl_materials_cubemap_refraction materials / cubemap / refraction]
 		</p>
 

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

@@ -17,10 +17,6 @@
 		</p>
 
 		<h2>Example</h2>
-		<p>
-			[example:webgl_loader_msgpack WebGL / loader / msgpack]<br />
-			[example:webgl_morphtargets_human WebGL / morphtargets / human]<br />
-		</p>
 		<code>
 		var loader = new THREE.FileLoader();
 

+ 0 - 1
docs/api/en/materials/LineBasicMaterial.html

@@ -29,7 +29,6 @@
 			[example:webgl_lines_colors WebGL / lines / colors]<br />
 			[example:webgl_lines_dashed WebGL / lines / dashed]<br />
 			[example:webgl_lines_sphere WebGL / lines / sphere]<br />
-			[example:webgl_lines_splines WebGL / lines / splines]<br />
 			[example:webgl_materials WebGL / materials]<br />
 			[example:webgl_physics_rope WebGL / phyics / rope]
 		</p>

+ 0 - 2
docs/api/en/materials/PointsMaterial.html

@@ -26,9 +26,7 @@
 			[example:webgl_interactive_raycasting_points WebGL / interactive / raycasting / points]<br />
 			[example:webgl_multiple_elements_text WebGL / multiple / elements / text]<br />
 			[example:webgl_points_billboards WebGL / points / billboards]<br />
-			[example:webgl_points_billboards_colors WebGL / points / billboards / colors]<br />
 			[example:webgl_points_dynamic WebGL / points / dynamic]<br />
-			[example:webgl_points_random WebGL / points / random]<br />
 			[example:webgl_points_sprites WebGL / points / sprites]<br />
 			[example:webgl_trails WebGL / trails]
 		</p>

+ 0 - 1
docs/api/en/materials/ShaderMaterial.html

@@ -96,7 +96,6 @@
 			[example:webgl_materials_parallaxmap webgl / materials / parallaxmap]<br />
 			[example:webgl_materials_shaders_fresnel webgl / materials / shaders / fresnel]<br />
 			[example:webgl_materials_skin webgl / materials / skin]<br />
-			[example:webgl_materials_texture_hdr webgl / materials / texture / hdr]<br />
 			[example:webgl_materials_wireframe webgl / materials / wireframe]<br />
 			[example:webgl_modifier_tessellation webgl / modifier / tessellation]<br />
 			[example:webgl_nearestneighbour webgl / nearestneighbour]<br />

+ 42 - 26
docs/api/en/objects/SkinnedMesh.html

@@ -38,41 +38,60 @@
 		<h2>Example</h2>
 
 		<code>
-		var geometry = new THREE.CylinderGeometry( 5, 5, 5, 5, 15, 5, 30 );
+		var geometry = new THREE.CylinderBufferGeometry( 5, 5, 5, 5, 15, 5, 30 );
 
-		//Create the skin indices and skin weights
-		for ( var i = 0; i < geometry.vertices.length; i ++ ) {
+		// create the skin indices and skin weights
 
-			// Imaginary functions to calculate the indices and weights
-			// This part will need to be changed depending your skeleton and model
-			var skinIndex = calculateSkinIndex( geometry.vertices, i );
-			var skinWeight = calculateSkinWeight( geometry.vertices, i );
+		var position = geometry.attributes.position;
 
-			// Ease between each bone
-			geometry.skinIndices.push( new THREE.Vector4( skinIndex, skinIndex + 1, 0, 0 ) );
-			geometry.skinWeights.push( new THREE.Vector4( 1 - skinWeight, skinWeight, 0, 0 ) );
+		var vertex = new THREE.Vector3();
+
+		var skinIndices = [];
+		var skinWeights = [];
+
+		for ( var i = 0; i < position.count; i ++ ) {
+
+			vertex.fromBufferAttribute( position, i );
+
+			// compute skinIndex and skinWeight based on some configuration data
+
+			var y = ( vertex.y + sizing.halfHeight );
+
+			var skinIndex = Math.floor( y / sizing.segmentHeight );
+			var skinWeight = ( y % sizing.segmentHeight ) / sizing.segmentHeight;
+
+			skinIndices.push( skinIndex, skinIndex + 1, 0, 0 );
+			skinWeights.push( 1 - skinWeight, skinWeight, 0, 0 );
 
 		}
 
+		geometry.addAttribute( 'skinIndex', new THREE.Uint16BufferAttribute( skinIndices, 4 ) );
+		geometry.addAttribute( 'skinWeight', new THREE.Float32BufferAttribute( skinWeights, 4 ) );
+
+		// create skinned mesh and skeleton
+
 		var mesh = new THREE.SkinnedMesh( geometry, material );
+		var skeleton = new THREE.Skeleton( bones );
 
-		// See example from THREE.Skeleton for the armSkeleton
-		var rootBone = armSkeleton.bones[ 0 ];
+		// see example from THREE.Skeleton
+
+		var rootBone = skeleton.bones[ 0 ];
 		mesh.add( rootBone );
 
-		// Bind the skeleton to the mesh
-		mesh.bind( armSkeleton );
+		// bind the skeleton to the mesh
+
+		mesh.bind( skeleton );
+
+		// move the bones and manipulate the model
 
-		// Move the bones and manipulate the model
-		armSkeleton.bones[ 0 ].rotation.x = -0.1;
-		armSkeleton.bones[ 1 ].rotation.x = 0.2;
+		skeleton.bones[ 0 ].rotation.x = -0.1;
+		skeleton.bones[ 1 ].rotation.x = 0.2;
 		</code>
 
 		<h2>Constructor</h2>
-		<h3>[name]( [param:Geometry geometry], [param:Material material] )</h3>
+		<h3>[name]( [param:BufferGeometry geometry], [param:Material material] )</h3>
 		<p>
-    [page:Geometry geometry] - an instance of [page:Geometry] or [page:BufferGeometry] (recommended).
-		[page:Geometry.skinIndices skinIndices] and [page:Geometry.skinWeights skinWeights] should be set to true on the geometry.<br />
+    [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>
 
@@ -109,8 +128,7 @@
 
 		<h3>[property:Skeleton skeleton]</h3>
 		<p>
-		[page:Skeleton] created from the [page:Geometry.bones bones] of the [page:Geometry] passed in the
-		constructor.
+		[page:Skeleton] representing the bone hierachy of the skinned mesh.
 		</p>
 
 
@@ -124,9 +142,7 @@
 		[page:Matrix4 bindMatrix] - [page:Matrix4] that represents the base transform of the skeleton.<br /><br />
 
 		Bind a skeleton to the skinned mesh. The bindMatrix gets saved to .bindMatrix property
-		and the .bindMatrixInverse gets calculated. This is called automatically in the constructor, and the skeleton
-		is created from the [page:Geometry.bones bones] of the [page:Geometry] passed in the
-		constructor.
+		and the .bindMatrixInverse gets calculated.
 		</p>
 
 		<h3>[method:SkinnedMesh clone]()</h3>
@@ -136,7 +152,7 @@
 
 		<h3>[method:null normalizeSkinWeights]()</h3>
 		<p>
-		Normalizes the [page:Geometry.skinWeights] vectors. Does not affect [page:BufferGeometry].
+		Normalizes the skin weights.
 		</p>
 
 		<h3>[method:null pose]()</h3>

+ 1 - 1
docs/api/en/renderers/WebGLRenderer.html

@@ -253,7 +253,7 @@
 
 		Note: Sorting is used to attempt to properly render objects that have some degree of transparency.
 		By definition, sorting objects may not work in all cases.  Depending on the needs of application,
-		it may be neccessary to turn off sorting and use other methods to deal with transparency
+		it may be necessary to turn off sorting and use other methods to deal with transparency
 		rendering e.g. manually determining each object's rendering order.
 		</p>
 

+ 4 - 4
docs/api/zh/core/bufferAttributeTypes/BufferAttributeTypes.html

@@ -31,14 +31,14 @@
 
 		<h2>构造函数</h2>
 
-		All of the above are called in the same way.
+		所有上述内容都以相同的方式调用。
 		<h3>TypedBufferAttribute( [param:Array array], [param:Integer itemSize], [param:Boolean normalized] )</h3>
 		<p>
-			array -- this can be a typed or untyped (normal) array. It will be converted to the Type specified.<br /><br />
+			array -- 这可以是类型化或非类型化的(普通)数组。它将被转换为指定的类型。<br /><br />
 
-			itemSize -- the number of values of the array that should be associated with a particular vertex.<br /><br />
+			itemSize -- 应与特定顶点关联的数组值的数量。<br /><br />
 
-			normalized -- (optional) indicates how the underlying data in the buffer maps to the values in the GLSL code.
+			normalized -- (可选)表示缓冲区中的基础数据如何映射到GLSL代码中的值。
 		</p>
 
 		<h2>属性</h2>

+ 6 - 6
docs/api/zh/extras/Earcut.html

@@ -11,20 +11,20 @@
 		<h1>[name]</h1>
 
 		<p class="desc">
-		An implementation of the earcut polygon triangulation algorithm. The code is a port of [link:https://github.com/mapbox/earcut mapbox/earcut].
+		切割多边形三角剖分算法的实现。这份代码是[link:https://github.com/mapbox/earcut mapbox/earcut]的一个端口。
 		</p>
 
-		<h2>Methods</h2>
+		<h2>方法</h2>
 
 		<h3>[method:Array triangulate]( data, holeIndices, dim )</h3>
 		<p>
-		data -- A flat array of vertice coordinates.<br /><br />
-		holeIndices -- An array of hole indices if any.<br /><br />
-		dim -- The number of coordinates per vertice in the input array.<br /><br />
+		data -- 一个顶点坐标的平面数组。<br /><br />
+		holeIndices -- 空洞索引的数组(如果有的话)。<br /><br />
+		dim -- 输入数组中每个顶点的坐标数。<br /><br />
 
 		</p>
 
-		<h2>Source</h2>
+		<h2>源代码</h2>
 
 		[link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js]
 	</body>

+ 12 - 15
docs/api/zh/extras/ShapeUtils.html

@@ -11,43 +11,40 @@
 		<h1>[name]</h1>
 
 		<p class="desc">
-		A class containing utility functions for shapes.<br /><br />
+		一个包含形状实用函数的类。<br /><br />
 
-		Note that these are all linear functions so it is neccessary to calculate separately for
-		x, y (and z, w if present) components of a vector.
+		请注意,这些都是线性函数,因此有必要分别计算向量的x,y(和z,w,如果存在的话)分量。
 		</p>
 
 
-		<h2>Methods</h2>
+		<h2>方法</h2>
 
 		<h3>[method:Number area]( contour )</h3>
 		<p>
-		contour -- 2D polygon.<br /><br />
+		contour -- 2D多边形。<br /><br />
 
-		Calculate area of a ( 2D ) contour polygon.<br /><br />
+		计算(2D)轮廓多边形的面积。<br /><br />
 
 		</p>
 
 		<h3>[method:Boolean isClockwise]( pts )</h3>
 		<p>
-		pts -- points defining a 2D polygon<br /><br />
+		pts -- 定义2D多边形的点<br /><br />
 
-		Note that this is a linear function so it is neccessary to calculate separately for
-		x, y  components of a polygon.<br /><br />
+		请注意,这是一个线性函数,因此需要分别计算多边形的x,y分量。<br /><br />
 
-		Used internally by [page:Path Path],
-		[page:ExtrudeGeometry ExtrudeGeometry] and [page:ShapeGeometry ShapeGeometry].
+		由[page:Path Path],[page:ExtrudeGeometry ExtrudeGeometry]和[page:ShapeGeometry ShapeGeometry]内部使用。
 		</p>
 
 		<h3>[method:Array triangulateShape]( contour, holes )</h3>
 		<p>
-		contour -- 2D polygon.<br />
-		holes -- array of holes<br /><br />
+		contour -- 2D多边形。<br />
+		holes -- 空洞数组<br /><br />
 
-		Used internally by [page:ExtrudeGeometry ExtrudeGeometry] and [page:ShapeGeometry ShapeGeometry] to calculate faces in shapes with holes.
+		由[page:ExtrudeGeometry ExtrudeGeometry]和[page:ShapeGeometry ShapeGeometry]内部使用以计算带孔的形状中的面。
 		</p>
 
-		<h2>Source</h2>
+		<h2>源代码</h2>
 
 		[link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js]
 	</body>

+ 41 - 23
docs/api/zh/objects/SkinnedMesh.html

@@ -38,41 +38,60 @@
 		<h2>示例</h2>
 
 		<code>
-		var geometry = new THREE.CylinderGeometry( 5, 5, 5, 5, 15, 5, 30 );
+		var geometry = new THREE.CylinderBufferGeometry( 5, 5, 5, 5, 15, 5, 30 );
 
-		//Create the skin indices and skin weights
-		for ( var i = 0; i < geometry.vertices.length; i ++ ) {
+		// create the skin indices and skin weights
 
-			// Imaginary functions to calculate the indices and weights
-			// This part will need to be changed depending your skeleton and model
-			var skinIndex = calculateSkinIndex( geometry.vertices, i );
-			var skinWeight = calculateSkinWeight( geometry.vertices, i );
+		var position = geometry.attributes.position;
 
-			// Ease between each bone
-			geometry.skinIndices.push( new THREE.Vector4( skinIndex, skinIndex + 1, 0, 0 ) );
-			geometry.skinWeights.push( new THREE.Vector4( 1 - skinWeight, skinWeight, 0, 0 ) );
+		var vertex = new THREE.Vector3();
+
+		var skinIndices = [];
+		var skinWeights = [];
+
+		for ( var i = 0; i < position.count; i ++ ) {
+
+			vertex.fromBufferAttribute( position, i );
+
+			// compute skinIndex and skinWeight based on some configuration data
+
+			var y = ( vertex.y + sizing.halfHeight );
+
+			var skinIndex = Math.floor( y / sizing.segmentHeight );
+			var skinWeight = ( y % sizing.segmentHeight ) / sizing.segmentHeight;
+
+			skinIndices.push( skinIndex, skinIndex + 1, 0, 0 );
+			skinWeights.push( 1 - skinWeight, skinWeight, 0, 0 );
 
 		}
 
+		geometry.addAttribute( 'skinIndex', new THREE.Uint16BufferAttribute( skinIndices, 4 ) );
+		geometry.addAttribute( 'skinWeight', new THREE.Float32BufferAttribute( skinWeights, 4 ) );
+
+		// create skinned mesh and skeleton
+
 		var mesh = new THREE.SkinnedMesh( geometry, material );
+		var skeleton = new THREE.Skeleton( bones );
 
-		// See example from THREE.Skeleton for the armSkeleton
-		var rootBone = armSkeleton.bones[ 0 ];
+		// see example from THREE.Skeleton
+
+		var rootBone = skeleton.bones[ 0 ];
 		mesh.add( rootBone );
 
-		// Bind the skeleton to the mesh
-		mesh.bind( armSkeleton );
+		// bind the skeleton to the mesh
+
+		mesh.bind( skeleton );
+
+		// move the bones and manipulate the model
 
-		// Move the bones and manipulate the model
-		armSkeleton.bones[ 0 ].rotation.x = -0.1;
-		armSkeleton.bones[ 1 ].rotation.x = 0.2;
+		skeleton.bones[ 0 ].rotation.x = -0.1;
+		skeleton.bones[ 1 ].rotation.x = 0.2;
 		</code>
 
 		<h2>构造器</h2>
-		<h3>[name]( [param:Geometry geometry], [param:Material material] )</h3>
+		<h3>[name]( [param:BufferGeometry geometry], [param:Material material] )</h3>
 		<p>
-    [page:Geometry geometry] —— 一个[page:Geometry]或者[page:BufferGeometry](推荐)的实例。
-	[page:Geometry.skinIndices skinIndices] 和 [page:Geometry.skinWeights skinWeights] 在几何体上应当被设置为true。<br />
+    [page:BufferGeometry geometry] —— TODO<br />
     [page:Material material] —— (可选)一个[page:Material]的实例,默认值是一个新的[page:MeshBasicMaterial]。
 		</p>
 
@@ -108,7 +127,7 @@
 
 		<h3>[property:Skeleton skeleton]</h3>
 		<p>
-			[page:Skeleton]是由从构造函数中传入的[page:Geometry]中的[page:Geometry.bones bones]来创建的。
+			TODO
 		</p>
 
 
@@ -121,7 +140,6 @@
 		[page:Skeleton skeleton] —— 由一棵[page:Bone Bones]树创建的[page:Skeleton]。<br/>
 		[page:Matrix4 bindMatrix] —— 代表着骨架基本变换的[page:Matrix4](4x4矩阵)。<br /><br />
 		将骨架绑定到一个蒙皮网格上。bindMatrix会被保存到.bindMatrix属性中,其逆矩阵.bindMatrixInverse也会被计算出来。
-		它在构造函数中会被自动调用,其骨架是由传入到构造函数的[page:Geometry]中的[page:Geometry.bones bones]来创建的。
 		</p>
 
 		<h3>[method:SkinnedMesh clone]()</h3>
@@ -131,7 +149,7 @@
 
 		<h3>[method:null normalizeSkinWeights]()</h3>
 		<p>
-		规范化[page:Geometry.skinWeights]矢量。不会对[page:BufferGeometry]产生影响。
+		TODO
 		</p>
 
 		<h3>[method:null pose]()</h3>

+ 2 - 2
docs/manual/en/introduction/Browser-support.html

@@ -13,7 +13,7 @@
 	<h2>Overview</h2>
 	<div>
 		<p>
-			Three.js can use WebGL to render your scenes on all modern browsers. For older browsers, especially Internet Explorer 10 and below, you may have to fallback to one of the other [link:https://github.com/mrdoob/three.js/tree/master/examples/js/renderers renderers] (CSS2DRenderer, CSS3DRenderer, SVGRenderer, CanvasRenderer). Additionally, you may have to include some polyfills, especially if you are using files from the [link:https://github.com/mrdoob/three.js/tree/master/examples /examples] folder.
+			Three.js can use WebGL to render your scenes on all modern browsers. For older browsers, especially Internet Explorer 10 and below, you may have to fallback to one of the other [link:https://github.com/mrdoob/three.js/tree/master/examples/js/renderers renderers] (CSS2DRenderer, CSS3DRenderer, SVGRenderer). Additionally, you may have to include some polyfills, especially if you are using files from the [link:https://github.com/mrdoob/three.js/tree/master/examples /examples] folder.
 		</p>
 		<p>
 			Note: if you don't need to support these old browsers, then it is not recommended to use the other renderers as they are slower and support less features than the WebGLRenderer.
@@ -120,4 +120,4 @@
 		</ul>
 	</div>
 </body>
-</html>
+</html>

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

@@ -55,13 +55,14 @@
 	</p>
 
 	<ul>
-		<li><a href="https://github.com/KhronosGroup/glTF-Blender-Exporter" target="_blank" rel="noopener">glTF-Blender-Exporter</a> by the Khronos Group</li>
+		<li><a href="https://github.com/KhronosGroup/glTF-Blender-IO" target="_blank" rel="noopener">glTF-Blender-IO</a> by the Khronos Group</li>
 		<li><a href="https://github.com/KhronosGroup/COLLADA2GLTF" target="_blank" rel="noopener">COLLADA2GLTF</a> by the Khronos Group</li>
 		<li><a href="https://github.com/facebookincubator/FBX2glTF" target="_blank" rel="noopener">FBX2GLTF</a> by Facebook</li>
 		<li><a href="https://github.com/AnalyticalGraphicsInc/obj2gltf" target="_blank" rel="noopener">OBJ2GLTF</a> by Analytical Graphics Inc</li>
 		<li><a href="https://www.allegorithmic.com/products/substance-painter" target="_blank" rel="noopener">Substance Painter</a> by Allegorithmic</li>
 		<li><a href="https://www.foundry.com/products/modo" target="_blank" rel="noopener">Modo</a> by Foundry</li>
 		<li><a href="https://www.marmoset.co/toolbag/" target="_blank" rel="noopener">Toolbag</a> by Marmoset</li>
+		<li><a href="https://www.sidefx.com/products/houdini/" target="_blank" rel="noopener">Houdini</a> by SideFX</li>
 		<li>&hellip;and <a href="https://github.com/khronosgroup/gltf#gltf-tools" target="_blank" rel="noopener">many more</a></li>
 	</ul>
 

+ 60 - 69
docs/manual/zh/buildTools/Testing-with-NPM.html

@@ -8,69 +8,67 @@
 		<link type="text/css" rel="stylesheet" href="page.css" />
 	</head>
 	<body>
-		<h1>[name]</h1>
+		<h1>使用NPM进行测试([name]</h1>
 
 		<p class="desc">
-			This article shows how to get three.js into a [link:https://nodejs.org/en/ node.js] environment so that you
-			can execute automated tests. Tests can be run on the command line, or by automated
-			CI tools like [link:https://travis-ci.org/ Travis].
+			这篇文章展示了如何将three.js置入[link:https://nodejs.org/en/ node.js]环境中,
+			这样你就可以执行自动化测试了。测试可以通过命令行或者类似[link:https://travis-ci.org/ Travis]的CI工具来运行。
 		</p>
 
-		<h2>The short version</h2>
+		<h2>一句话概括</h2>
 
 		<p>
-			If you're comfortable with node and npm,
+			如果你习惯使用node和npm,
 			<code>
 				$ npm install three --save-dev
 			</code>
-			and add
+			并将
 		<code>
 			var THREE = require('three');
 		</code>
-			to your test.
+			添加到你的测试中。
 		</p>
 
-		<h2>Create a testable project from scratch</h2>
+		<h2>从头创建一个可测试的项目</h2>
 		<p>
-			If you're not familiar with these tools, here's a quick guide (for linux, the installation process
-			will be slightly different using windows, but the NPM commands are identical).
+			如果你不太熟悉这些工具,下面是一个快速入门。(基于linux,在windows上的安装过程会稍稍有点不一样,不过NPM指令是相同的。)
 		</p>
 
-		<h3>Basic setup</h3>
+		<h3>基本设置</h3>
 		<div>
 			<ol>
 				<li>
-					Install [link:https://www.npmjs.org/ npm] and nodejs. The shortest path typically looks something like
+					安装[link:https://www.npmjs.org/ npm]和nodejs。最简单的方式一般像这样
 					<code>
 $ sudo apt-get install -y npm nodejs-legacy
-# fix any problems with SSL in the default registry URL
+# 修复默认registry URL中任何SSL的问题
 $ npm config set registry http://registry.npmjs.org/
 					</code>
 				</li>
 
 				<li>
-					Make a new project directory
+					新建一个项目路径
 					<code>
 						 $ mkdir test-example; cd test-example
 					</code>
 				</li>
 
 				<li>
-					Ask npm to create a new project file for you:
+					让npm为你创建一份新的项目文件:
 					<code>
 					 $ npm init
 					</code>
-					 and accept all defaults by hitting Enter on all the prompts.
-					 This will create package.json.
+					 在所有出现的提示中敲击回车键来接受默认值。
+					 这样,一份package.json就建立好了。
 				</li><br />
 
 				<li>
-					Try and start the test feature with
+					尝试启动测试功能
 					<code>
 $ npm test
 					</code>
-					This will fail, which is expected.
-					If you look in the package.json, the definition of the test script is
+					当然,这一定会失败。
+					如果你检查一下package.json,test script的定义是这样的
 					<code>
 						"test": "echo \"Error: no test specified\" && exit 1"
 					</code>
@@ -79,78 +77,75 @@ $ npm test
 			</ol>
 		</div>
 
-		<h2>Add mocha</h2>
+		<h2>添加mocha</h2>
 		<div>
-			We're going to use [link:https://mochajs.org/ mocha].
+			我们将使用[link:https://mochajs.org/ mocha]。
 
 			<ol>
 				<li>
-					Install mocha with
+					安装mocha
 					<code>
 $ npm install mocha --save-dev
 					</code>
-					Notice that node_modules/ is created and your dependencies appear in there.
-				  Also notice that your package.json has been updated: the property devDependencies
-					is added and updated by the use of --save-dev.
+					你会注意到 node_modules/ 被创建了,并且你的依赖都出现在了这里面。
+					还有你的package.json被更新了,--save-dev指令向其中加入并更新了devDependencies属性。
 				</li><br />
 
 				<li>
-					Edit package.json to use mocha for testing. When test is invoked, we just want to run
-					mocha and specify a verbose reporter. By default this will run anything in test/
-					(not having directory test/ can run into npm ERR!, create it by mkdir test)
+					编辑package.json来使用mocha进行测试。当调用测试的时候,我们只想运行mocha并且生成一份详细的报告。
+					默认情况下这会运行 test/ 中的任何东西。
+					(如果项目中没有 test/ 目录的话,会导致npm报错。你可以通过mkdir test来创建这个目录)
 					<code>
 						"test": "mocha --reporter list"
 					</code>
 				</li>
 
 				<li>
-					Rerun the test with
+					重新运行测试
 					<code>
 						$ npm test
 					</code>
 
-					This should now succeed, reporting 0 passing (1ms)
-				 	or similar.
+					现在应该就能成功执行了,生成类似 0 passing (1ms) 的报告。
 				</li>
 
 			</ol>
 		</div>
 
-		<h2>Add three.js</h2>
+		<h2>添加three.js</h2>
 		<div>
 			<ol>
 				<li>
-					Let's pull in our three.js dependency with
+					现在添加我们的three.js依赖
 					<code>
 $ npm install three --save-dev
 					</code>
 					<ul>
 						<li>
-							If you need a different three version, use
+							如果你需要three.js的其他版本,使用
 							<code>
 								$ npm show three versions
 							</code>
-						  to see
-							what's available. To tell npm the right one, use
+						  	来确认哪些是可用的。要让npm使用正确的版本,执行
 							<code>
  $ npm install [email protected] --save
 							</code>
-							(0.84.0 in this example). --save makes this a dependency of this project, rather than
-							dev dependency. See the docs [link:https://www.npmjs.org/doc/json.html here] for more info.
+							(例子中用的是0.84.0)。 --save 指令将此加入项目的dependency而不是dev dependency。
+							更多信息请参阅<a href="https://www.npmjs.org/doc/json.html">这份文档</a>。
 						</li>
 					</ul>
 				</li>
 
 				<li>
-					Mocha will look for tests in test/, so let's
+					Mocha会在 test/ 目录中寻找测试文件,所以我们先创建这个目录:
 					<code>
 					$ mkdir test
 					</code>
 				</li>
 
 				<li>
-					Finally we actually need a JS test to run. Let's add a simple test that will verify that
-					the three.js object is available and working. Create test/verify-three.js containing:
+					最后我们需要一份JS测试文件来运行。我们就添加一段简单的测试程序,这段程序会检验three.js对象是否能正常工作。
+					在 test/ 目录下创建verify-three.js包含以下代码:
 <code>
 var THREE = require('three');
 var assert = require("assert");
@@ -169,8 +164,7 @@ describe('The THREE object', function() {
 				</li>
 
 				<li>
-				Finally let's test again with $ npm test. This should run the tests above and succeed,
-				showing something like:
+				最后再次通过$ npm test来测试。这次应该能正确执行上面的代码,并且返回类似:
 				<code>
 The THREE object should have a defined BasicShadowMap constant: 0ms
 The THREE object should be able to construct a Vector3 with default of x=0: 0ms
@@ -180,33 +174,33 @@ The THREE object should be able to construct a Vector3 with default of x=0: 0ms
 			</ol>
 		</div>
 
-		<h2>Add your own code</h2>
+		<h2>加入你自己的代码</h2>
 		<div>
-			You need to do three things:
+			你需要做下面三件事:
 
 			<ol>
 				<li>
-					Write a test for the expected behaviour of your code, and place it under test/.
-					[link:https://github.com/air/encounter/blob/master/test/Physics-test.js Here] is an example from a real project.
+					为你的代码写一段测试程序来检验期望结果,并把它放在 test/ 目录下。
+					<a href="https://github.com/air/encounter/blob/master/test/Physics-test.js">这里</a>有一个实际项目的例子。
 				</li>
 
 				<li>
-					Export your functional code in such a way that nodejs can see it, for use in conjunction with require.
-					See it [link:https://github.com/air/encounter/blob/master/js/Physics.js here].
+					将你的代码以nodejs承认的方式导出,即可以通过require的方式引用。
+					参考<a href="https://github.com/air/encounter/blob/master/js/Physics.js">这份代码</a>。
 				</li>
 
 				<li>
-					Require your code into the test file, in the same way we did a require('three') in the example above.
+					在测试程序中通过require引入你自己的代码,就像上面例子中我们通过require('three')来引入一样。
 				</li>
 			</ol>
 
 			<p>
-				Items 2 and 3 will vary depending on how you manage your code. In the example of Physics.js
-		  	given above, the export part is right at the end. We assign an object to module.exports:
+				第2、3条会根据你组织代码的方式而改变。在上面给出的Physics.js的例子中,导出的部分在代码的最末尾。
+				我们将module.exports赋值为一个对象:
 			</p>
 			<code>
 //=============================================================================
-// make available in nodejs
+// 为了在nodejs中可用
 //=============================================================================
 if (typeof exports !== 'undefined')
 {
@@ -215,38 +209,35 @@ if (typeof exports !== 'undefined')
 			</code>
 		</div>
 
-		<h2>Dealing with dependencies</h2>
+		<h2>处理依赖</h2>
 		<div>
 			<p>
-				If you're already using something clever like require.js or browserify, skip this part.
+				如果你已经在使用require.js或者browserify之类的便捷工具,就跳过这个部分。
 			</p>
 			<p>
-				Typically a three.js project is going to run in the browser. Module loading is hence done by
-				the browser executing a bunch of script tags. Your individual files don't have to worry
-				about dependencies. In a nodejs context however, there is no index.html binding everything
-				together, so you have to be explicit.
+				一般来说,一个three.js项目将在浏览器中运行,浏览器会通过执行一系列script标签来加载模块。
+				你自己的文件不用考虑依赖的问题。然而在nodejs环境中,没有一个关联所有文件的index.html,所以你需要显式地加载。
 			</p>
 			<p>
-				If you're exporting a module that depends on other files, you're going to have to tell node to load them.
-				Here is one approach:
+				如果你要导出的模块还依赖其他文件,你需要告诉node去加载它们。下面是一种方式:
 			</p>
 			<ol>
 				<li>
-					At the start of your module, check to see if you're in a nodejs environment.
+					在你的模块顶部,检查是否处于nodejs环境中。
 				</li>
 				<li>
-					If so, explicitly declare your dependencies.
+					如果是,那就显式地声明你的依赖。
 				</li>
 				<li>
-					If not, you're probably in a browser so you don't need to do anything else.
+					如果不是,你多半处于浏览器环境中。这时候你不需要做任何多余操作。
 				</li>
 			</ol>
-			Example code from Physics.js:
+			用Physics.js中的代码举例:
 			<code>
 //=============================================================================
-// setup for server-side testing
+// 服务器端测试配置
 //=============================================================================
-if (typeof require === 'function') // test for nodejs environment
+if (typeof require === 'function') // 检测nodejs环境
 {
   var THREE = require('three');
   var MY3 = require('./MY3.js');

+ 49 - 53
docs/manual/zh/introduction/Animation-system.html

@@ -8,82 +8,79 @@
 		<link type="text/css" rel="stylesheet" href="page.css" />
 	</head>
 	<body>
-		<h1>[name]</h1>
+		<h1>动画系统([name]</h1>
 
-		<h2>Overview(概述)</h2>
+		<h2>概述</h2>
 
 		<p class="desc">
 			在three.js动画系统中,您可以为模型的各种属性设置动画:
-			[page:SkinnedMesh 蒙皮和装配模型]的骨头,[page:Geometry.morphTargets 变形目标],不同的材料属性(颜色,
-			不透明度,布尔运算),可见性和变换。 动画属性可以淡入,淡出,交叉淡化和扭曲。 不同时间的重量和时间尺度
-			可以更改同一对象以及不同对象上的动画独立。 可以在相同和不同对象上进行各种动画同步。
+			[page:SkinnedMesh](蒙皮和装配模型)的骨骼,[page:Geometry.morphTargets](变形目标),
+			不同的材料属性(颜色,不透明度,布尔运算),可见性和变换。动画属性可以淡入、淡出、交叉淡化和扭曲。
+			在相同或不同物体上同时发生的动画的权重和时间比例的变化可以独立地进行。
+			相同或不同物体的动画也可以同步发生。
 			<br /><br />
-			在一个同构系统中实现所有这一切,即three.js动画系统
-			[link:https://github.com/mrdoob/three.js/issues/6881在2015年彻底改变]
-			(注意过时的信息!),它现在有一个与Unity /虚幻引擎4类似的架构.此页面简要概述了主要组件系统以及它们如何协同工作。
+			为了在一个同构系统中实现所有这一切,
+			three.js的动画系统<a href="https://github.com/mrdoob/three.js/issues/6881">在2015年彻底改变</a>(注意过时的信息!),
+			它现在有一个与Unity/虚幻4引擎类似的架构。此页面简要阐述了这个系统中的主要组件以及它们如何协同工作。
 		</p>
 
-		<h3>Animation Clips(动画片段)</h3>
+		<h3>动画片段(Animation Clips)</h3>
 
 		<p class="desc">
-			如果您已成功导入动画3D对象(如果有,则无关紧要)
-			骨骼或变形目标或两者) - 例如使用[link:https://github.com/KhronosGroup/glTF-Blender-Exporter glTF Blender导出器]从Blender导出它
-			使用[page:GLTFLoader]将其加载到three.js场景中 - 其中一个响应字段应该是一个名为“animations”的数组,其中包含此模型的[page:AnimationClip AnimationClips](请参阅下面的可能加载器列表)。
+			如果您已成功导入3D动画对象(无论它是否有骨骼或变形目标或两者皆有都不要紧)——
+			例如使用<a href="https://github.com/KhronosGroup/glTF-Blender-Exporter">glTF Blender导出器</a>
+			从Blender导出它并使用[page:GLTFLoader]将其加载到three.js场景中
+			—— 其中一个响应字段应该是一个名为“animations”的数组,
+			其中包含此模型的[page:AnimationClip AnimationClips](请参阅下面可用的加载器列表)。
 			<br /><br />
-			每个* AnimationClip *通常保存对象的某个活动的数据。 如果
-			mesh是一个字符,例如,可以有一个用于walkcycle的动画片段,第二个
-			跳跃,三分之一的回避等等。
+			每个*AnimationClip*通常保存对象某个活动的数据。
+			举个例子,假如mesh是一个角色,可能有一个AnimationClip实现步行循环,
+			第二个AnimationClip实现跳跃,第三个AnimationClip实现闪避等等。
 		</p>
 
-		<h3>Keyframe Tracks(关键帧轨道)</h3>
+		<h3>关键帧轨道(Keyframe Tracks)</h3>
 
 		<p class="desc">
-			在这样的* AnimationClip *里面,每个动画属性的数据都存储在一个
-			单独[page:KeyframeTrack]。 假设一个角色对象有一个[page:Skeleton skeleton],
-			一个关键帧轨道可以存储下臂骨骼位置变化的数据
-			随着时间的推移,不同的轨道数据为同一骨骼的旋转变化,三分之一
-			轨道位置,旋转或缩放另一个骨骼,等等。 应该很清楚,
-			AnimationClip可以由许多这样的轨道组成。
-			.<br /><br />
-			假设模型具有[page:Geometry.morphTargets 变形目标](例如一个变形
-			目标显示一个友好的面孔,另一个显示愤怒的脸),每个轨道持有
-			关于某个变形的[page:Mesh.morphTargetInfluences 影响]的信息
-			目标在剪辑执行期间发生变化。
+			在这样的*AnimationClip*里面,每个动画属性的数据都存储在一个单独的[page:KeyframeTrack]中。
+			假设一个角色对象有[page:Skeleton](骨架),
+			一个关键帧轨道可以存储下臂骨骼位置随时间变化的数据,
+			另一个轨道追踪同一块骨骼的旋转变化,第三个追踪另外一块骨骼的位置、转角和尺寸,等等。
+			应该很清楚,AnimationClip可以由许多这样的轨道组成。
+			<br /><br />
+			假设模型具有[page:Geometry.morphTargets](变形目标)——
+			例如一个变形目标显示一个笑脸,另一个显示愤怒的脸 ——
+			每个轨道都持有某个变形目标在AnimationClip运行期间产生的[page:Mesh.morphTargetInfluences](变形目标影响)如何变化的信息。
 		</p>
 
-		<h3>Animation Mixer(动画混音器)</h3>
+		<h3>动画混合器(Animation Mixer)</h3>
 
 		<p class="desc">
-			存储的数据仅构成动画的基础 - 实际播放由控制
-			[page:AnimationMixer]。 你可以想象这不仅仅是动画的播放器,而是
-			作为硬件的模拟,如真正的调音台控制台,可以控制几个动画
-			同时,混合和合并它们。
+			存储的数据仅构成动画的基础 —— 实际播放由[page:AnimationMixer]控制。
+			你可以想象这不仅仅是动画的播放器,而是作为硬件的模拟,如真正的调音台,可以同时控制和混合若干动画。
 		</p>
 
-		<h3>Animation Actions</h3>
+		<h3>动画行为(Animation Actions</h3>
 
 		<p class="desc">
-			* AnimationMixer *本身只有很少(通用)属性和方法,因为它
-			可以通过[page:AnimationAction AnimationActions]来控制。 通过配置
-			* AnimationAction *您可以确定何时播放某个* AnimationClip *,暂停
-			或者停在其中一个混音器上,是否以及频率必须重复,无论是否
-			应使用淡入淡出或时间缩放以及一些其他内容(例如交叉渐变)来执行
-			或同步。
+			*AnimationMixer*本身只有很少的(大体上)属性和方法,
+			因为它可以通过[page:AnimationAction AnimationActions]来控制。
+			通过配置*AnimationAction*,您可以决定何时播放、暂停或停止其中一个混合器中的某个*AnimationClip*,
+			这个*AnimationClip*是否需要重复播放以及重复的频率,
+			是否需要使用淡入淡出或时间缩放,以及一些其他内容(例如交叉渐变和同步)。
 		</p>
 
-		<h3>Animation Object Groups(动画对象组)</h3>
+		<h3>动画对象组(Animation Object Groups)</h3>
 
 		<p class="desc">
-				如果您希望一组对象接收共享动画状态,则可以使用[page:AnimationObjectGroup].
-
+			如果您希望一组对象接收共享的动画状态,则可以使用[page:AnimationObjectGroup]。
 		</p>
 
-		<h3>Supported Formats and Loaders(支持的格式和加载器)</h3>
+		<h3>支持的格式和加载器(Supported Formats and Loaders)</h3>
 
 		<p class="desc">
-			请注意,并非所有模型格式都包含动画(尤其是OBJ,没有),而且只有一些
-			three.js加载器支持[page:AnimationClip AnimationClip]序列。 以下几个<i>确实</ i>
-			支持此动画类型:
+			请注意,并非所有模型格式都包含动画(尤其是OBJ,没有),
+			而且只有某些three.js加载器支持[page:AnimationClip AnimationClip]序列。
+			以下几个<i>确实</i>支持此动画类型:
 		</p>
 
 			<ul>
@@ -97,30 +94,29 @@
 			</ul>
 
 		<p class="desc">
-			请注意,3ds max和Maya当前无法导出多个动画(这意味着动画不是
-			在同一时间线上)直接到一个文件。
+			请注意,3ds max和Maya当前无法直接导出多个动画(这意味着动画不是在同一时间线上)到一个文件中。
 		</p>
 
-		<h2>Example</h2>
+		<h2>范例</h2>
 
 		<code>
 		var mesh;
 
-		// Create an AnimationMixer, and get the list of AnimationClip instances
+		// 新建一个AnimationMixer, 并取得AnimationClip实例列表
 		var mixer = new THREE.AnimationMixer( mesh );
 		var clips = mesh.animations;
 
-		// Update the mixer on each frame
+		// 在每一帧中更新mixer
 		function update () {
 			mixer.update( deltaSeconds );
 		}
 
-		// Play a specific animation
+		// 播放一个特定的动画
 		var clip = THREE.AnimationClip.findByName( clips, 'dance' );
 		var action = mixer.clipAction( clip );
 		action.play();
 
-		// Play all animations
+		// 播放所有动画
 		clips.forEach( function ( clip ) {
 			mixer.clipAction( clip ).play();
 		} );

+ 1 - 1
docs/manual/zh/introduction/Browser-support.html

@@ -13,7 +13,7 @@
 	<h2>总览</h2>
 	<div>
 		<p>
-            在所有现代浏览器中,Three.js可以使用WebGL来渲染场景。对于较旧的浏览器,特别是Internet Explorer 10或者更低版本浏览器,你将需要回落到其它[link:https://github.com/mrdoob/three.js/tree/master/examples/js/renderers renderers](CSS2DRenderer、CSS3DRenderer、SVGRenderer、CanvasRenderer)。此外,你或许不得不包含一些额外的“填充物”来解决兼容性问题,特别是当你使用[link:https://github.com/mrdoob/three.js/tree/master/examples /examples]目录中的文件时。
+            在所有现代浏览器中,Three.js可以使用WebGL来渲染场景。对于较旧的浏览器,特别是Internet Explorer 10或者更低版本浏览器,你将需要回落到其它[link:https://github.com/mrdoob/three.js/tree/master/examples/js/renderers renderers](CSS2DRenderer、CSS3DRenderer、SVGRenderer)。此外,你或许不得不包含一些额外的“填充物”来解决兼容性问题,特别是当你使用[link:https://github.com/mrdoob/three.js/tree/master/examples /examples]目录中的文件时。
 		</p>
 		<p>
             注意:如果你并不需要支持较旧的浏览器,那就不推荐使用其他渲染器来进行渲染,因为与WebGLRenderer相比,其它渲染器渲染较慢,并且不支持WebGL的诸多特性。

+ 33 - 34
docs/manual/zh/introduction/How-to-update-things.html

@@ -8,7 +8,7 @@
 		<link type="text/css" rel="stylesheet" href="page.css" />
 	</head>
 	<body>
-		<h1>[name]</h1>
+		<h1>如何更新场景([name]</h1>
 		<div>
 			<p>默认情况下,所有对象都会自动更新它们的矩阵(如果它们已添加到场景中)</p>
 			<code>
@@ -21,7 +21,7 @@ var object1 = new THREE.Object3D();
 var object2 = new THREE.Object3D();
 
 object1.add( object2 );
-scene.add( object1 ); //object1 and object2 will automatically update their matrices
+scene.add( object1 ); //object1 和 object2 会自动更新它们的矩阵
 			</code>
 		</div>
 
@@ -32,27 +32,27 @@ object.matrixAutoUpdate  = false;
 object.updateMatrix();
 		</code>
 
-		<h2>Geometries(几何形状)</h2>
+		<h2>几何形状(Geometries)</h2>
 		<div>
 			<h3>[page:BufferGeometry]</h3>
 			<div>
 				<p>
-					BufferGeometries 将信息(例如顶点位置,面索引,法线,颜色,uv和任何自定义属性) 存储在 [page:BufferAttribute buffers] - 也就是,
+					BufferGeometries 将信息(例如顶点位置,面索引,法线,颜色,uv和任何自定义属性)存储在[page:BufferAttribute buffers] —— 也就是,
 					[link:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Typed_arrays typed arrays].
 					这使得它们通常比标准Geometries更快,缺点是更难用。
 				</p>
 				<p>
-					关于更新BufferGeometries, 最重要的是理解你不能调整 buffers 大小(这种操作开销很大,	相当于创建了个新的geometry).
-					但你可以更新 buffers的内容.
+					关于更新BufferGeometries,最重要的是理解你不能调整 buffers 大小(这种操作开销很大,相当于创建了个新的geometry)。
+					但你可以更新 buffers的内容
 				</p>
 				<p>
 					这意味着如果你知道BufferGeometry的一个属性会增长,比如顶点的数量,
 					你必须预先分配足够大的buffer来容纳可能创建的任何新顶点。
-					当然,这也意味着BufferGeometry将有一个最大大小 - 无法创建一个可以高效地无限扩展的BufferGeometry。
+					当然,这也意味着BufferGeometry将有一个最大大小 —— 无法创建一个可以高效地无限扩展的BufferGeometry。
 				</p>
 				<p>
 					我们以在渲染时扩展的line来示例。我们将分配可容纳500个顶点的空间但起初仅绘制2个,使用
-					在500个顶点的缓冲区中,但首先只使用 [page:BufferGeometry.drawRange].
+					在500个顶点的缓冲区中,但首先只使用 [page:BufferGeometry.drawRange]
 				</p>
 				<code>
 var MAX_POINTS = 500;
@@ -106,14 +106,14 @@ line.geometry.setDrawRange( 0, newValue );
 					如果要在第一次渲染后更改position数值,则需要像这样设置needsUpdate标志:
 				</p>
 				<code>
-line.geometry.attributes.position.needsUpdate = true; // required after the first render
+line.geometry.attributes.position.needsUpdate = true; // 需要加在第一次渲染之后
 				</code>
 
 				<p>
-					[link:http://jsfiddle.net/w67tzfhx/ 这个fiddle] 展示了一个你可以参考的运动的line.
+					<a href="http://jsfiddle.net/w67tzfhx/">这个fiddle</a>展示了一个你可以参考的运动的line。
 				</p>
 
-				<h3>Examples:</h3>
+				<h3>例子:</h3>
 					[example:webgl_custom_attributes WebGL / custom / attributes]<br />
 					[example:webgl_buffergeometry_custom_attributes_particles WebGL / buffergeometry / custom / attributes / particles]
 
@@ -123,10 +123,9 @@ line.geometry.attributes.position.needsUpdate = true; // required after the firs
 			<h3>[page:Geometry]</h3>
 			<div>
 				<p>
-					以下标志控制各种geometry属性的更新. 仅对于需要更新的属性设置标志
-					,因为更新成本很高. 一旦buffers
-					改变, 这些标志位会自动重置为false. 你需要保持这些设置为true,如果你想要持续更新buffers. 请注意这仅适用于[page:Geometry]
-					而不是 [page:BufferGeometry].
+					以下标志控制各种geometry属性的更新。仅对于需要更新的属性设置标志,因为更新成本很高。
+					一旦buffers改变,这些标志位会自动重置为false。如果你想要持续更新buffers,你需要保持这些设置为true。
+					请注意这仅适用于[page:Geometry]而不是[page:BufferGeometry]。
 				</p>
 				<code>
 var geometry = new THREE.Geometry();
@@ -140,8 +139,8 @@ geometry.tangentsNeedUpdate = true;
 				</code>
 
 				<p>
-					在早于 [link:https://github.com/mrdoob/three.js/releases/tag/r66 r66]版本中, meshes
-					需要额外设定 <em>dynamic</em> 标志true (为了维持内部的 typed arrays):
+					在早于[link:https://github.com/mrdoob/three.js/releases/tag/r66 r66]版本中,meshes
+					需要额外设定 <em>dynamic</em> 标志为true (为了维持内部的 typed arrays):
 				</p>
 
 				<code>
@@ -149,7 +148,7 @@ geometry.tangentsNeedUpdate = true;
 		geometry.dynamic = true;
 				</code>
 
-				<h3>Examples:</h3>
+				<h3>例子:</h3>
 					[example:webgl_geometry_dynamic WebGL / geometry / dynamic]<br />
 			</div>
 
@@ -158,19 +157,19 @@ geometry.tangentsNeedUpdate = true;
 
 
 
-		<h2>Materials(材质)</h2>
+		<h2>材质(Materials)</h2>
 		<div>
-			<p>所有uniforms值都可以自由改变 (e.g. colors, textures, opacity, etc), 这些数值在每帧都发给shader .</p>
+			<p>所有uniforms值都可以自由改变(比如 colors, textures, opacity 等等),这些数值在每帧都发给shader。</p>
 
-			<p>GL状态相关参数也可以随时改变 (depthTest, blending, polygonOffset, etc).</p>
+			<p>GL状态相关参数也可以随时改变(depthTest, blending, polygonOffset 等)。</p>
 
-			<p>平滑/平滑阴影被作到法线. 你需要重置法线 buffer (见上).</p>
+			<p>平整/光滑阴影被作到法线。你需要重置法线 buffer(见上)。</p>
 
-			<p>在运行时无法轻松更改以下属性 (一旦material被渲染了一次):</p>
+			<p>在运行时无法轻松更改以下属性(一旦material被渲染了一次):</p>
 			<ul>
 				<li>uniforms的数量和类型</li>
 				<li>lights的数量和类型</li>
-				<li>存在与否
+				<li>是否存在
 					<ul>
 						<li>texture</li>
 						<li>fog</li>
@@ -183,42 +182,42 @@ geometry.tangentsNeedUpdate = true;
 				</li>
 			</ul>
 
-			<p>这些变化需要建立新的shader程序. 你需要设置</p>
+			<p>这些变化需要建立新的shader程序你需要设置</p>
 			<code>material.needsUpdate = true</code>
 
-			<p>请记住,这可能会非常缓慢并导致帧率的波动。 (特别是在Windows上,因为shader编译在directx中比opengl慢).</p>
+			<p>请记住,这可能会非常缓慢并导致帧率的波动。(特别是在Windows上,因为shader编译在directx中比opengl慢)。</p>
 
-			<p>为了获得更流畅的体验,您可以通过“虚拟”值(如零强度光,白色纹理或零密度雾)在一定程度上模拟这些功能的变化.</p>
+			<p>为了获得更流畅的体验,您可以通过“虚拟”值(如零强度光,白色纹理或零密度雾)在一定程度上模拟这些功能的变化</p>
 
-			<p>您可以自由更改用于几何块的材质,但是无法更改对象如何划分为块(根据面材料). </p>
+			<p>您可以自由更改用于几何块的材质,但是无法更改对象如何划分为块(根据面材料)</p>
 
 			<h3>如果你需要在运行时使用不同的材料配置:</h3>
-			<p>如果材料/块的数量很少,您可以事先预先划分物体(例如,人的头发/脸部/身体/上衣/裤子,汽车的前部/侧面/顶部/玻璃/轮胎/内部). </p>
+			<p>如果材料/块的数量很少,您可以事先预先划分物体(例如,人的头发/脸部/身体/上衣/裤子,汽车的前部/侧面/顶部/玻璃/轮胎/内部)</p>
 
 			<p>如果数量很大(例如,每个面可能有所不同),请考虑不同的解决方案,例如使用属性/纹理来驱动不同的每个面部外观。</p>
 
-			<h3>Examples:</h3>
+			<h3>例子:</h3>
 			[example:webgl_materials_cars WebGL / materials / cars]<br />
 			[example:webgl_postprocessing_dof WebGL / webgl_postprocessing / dof]
 		</div>
 
 
-		<h2>Textures(纹理)</h2>
+		<h2>纹理(Textures)</h2>
 		<div>
 			<p>如果更改了图像,画布,视频和数据纹理,则需要设置以下标志:</p>
 			<code>
 				texture.needsUpdate = true;
 			</code>
-			<p>Render targets update automatically.</p>
+			<p>渲染对象就会自动更新。</p>
 
-			<h3>Examples:</h3>
+			<h3>例子:</h3>
 			[example:webgl_materials_video WebGL / materials / video]<br />
 			[example:webgl_rtt WebGL / rtt]
 
 		</div>
 
 
-		<h2>Cameras(相机)</h2>
+		<h2>相机(Cameras)</h2>
 		<div>
 			<p>相机的位置和目标会自动更新。 如果你需要改变</p>
 			<ul>

+ 14 - 14
docs/manual/zh/introduction/Matrix-transformations.html

@@ -8,24 +8,24 @@
 		<link type="text/css" rel="stylesheet" href="page.css" />
 	</head>
 	<body>
-		<h1>[name]</h1>
+		<h1>矩阵变换([name]</h1>
 
 		<p>
-				Three.js使用*matrix*编码3D变换 - 平移(位置),旋转和缩放。 [page:Object3D]的每个实例都有一个[page:Object3D.matrix matrix],用于存储该对象的位置,旋转和比例。 本页介绍如何更新对象的转换。
+				Three.js使用*matrix*编码3D变换 —— 平移(位置),旋转和缩放。
+				[page:Object3D]的每个实例都有一个[page:Object3D.matrix matrix],用于存储该对象的位置,旋转和比例。本页介绍如何更新对象的变换。
 		</p>
 
-		<h2>Convenience properties and *matrixAutoUpdate*(便利属性和 *matrixAutoUpdate*)</h2>
+		<h2>便利的属性和*matrixAutoUpdate*(Convenience properties and *matrixAutoUpdate*)</h2>
 
 		有两种方法可以更新对象的转换:
 		<ol>
 			<li>
-				修改对象的* position *,* quaternion *和* scale *属性,让three.js重新计算
-				来自这些属性的对象矩阵:
+				修改对象的*position*,*quaternion*和*scale*属性,让three.js重新计算来自这些属性的对象矩阵:
 				<code>
 				object.position.copy(start_position);
 				object.quaternion.copy(quaternion);
 				</code>
-				默认情况下,* matrixAutoUpdate *属性设置为true,并且将自动重新计算矩阵。
+				默认情况下,*matrixAutoUpdate*属性设置为true,并且将自动重新计算矩阵。
 如果对象是静态的,或者您希望在重新计算时手动控制,则可以通过将属性设置为false来获得更好的性能:
 				<code>
 				object.matrixAutoUpdate = false;
@@ -42,25 +42,25 @@
 				object.matrix.setPosition(start_position);
 				object.matrixAutoUpdate = false;
 				</code>
-				请注意,在这种情况下,* matrixAutoUpdate * <em>必须</em>设置为* false *,并且您应该确保<em>不</em>调用* updateMatrix *。 调用* updateMatrix *将破坏对矩阵所做的手动更改,从* position *,* scale *重新计算矩阵,依此类推。
+				请注意,在这种情况下,*matrixAutoUpdate* <em> 必须 </em>设置为*false*,并且您应该确保<em> 不 </em>调用*updateMatrix*。
+				调用*updateMatrix*将破坏对矩阵所做的手动更改,从*position*,*scale*重新计算矩阵,依此类推。
 			</li>
 		</ol>
 
-		<h2>Object and world matrices(对象和世界矩阵)</h2>
+		<h2>对象和世界矩阵(Object and world matrices)</h2>
 		<p>
-		对象的[page:Object3D.matrix matrix]将对象的转换<em> 相对于 </em>对象的[page:Object3D.parent parent]; 要在<em> 世界 </em>坐标中获取对象的转换,您必须访问该对象的[page:Object3D.matrixWorld]。
-		An object's [page:Object3D.matrix matrix] stores the object's transformation 
+		一个对象的[page:Object3D.matrix matrix]存储了该对象<em> 相对于 </em>其[page:Object3D.parent](父节点)的变换。要在<em> 世界 </em>坐标系中获取对象的转换,您必须访问该对象的[page:Object3D.matrixWorld]。
 		</p>
 		<p>
-		当父对象或子对象的转换发生更改时,可以通过调用[page:Object3D.updateMatrixWorld updateMatrixWorld]()来请求更新子对象的[page:Object3D.matrixWorld matrixWorld]。
+		当父对象或子对象的变换发生更改时,可以通过调用[page:Object3D.updateMatrixWorld updateMatrixWorld()]来请求更新子对象的[page:Object3D.matrixWorld matrixWorld]。
 		</p>
 
-		<h2>Rotation and Quaternion(旋转和四元数)</h2>
+		<h2>旋转和四元数(Rotation and Quaternion)</h2>
 		<p>
-		Three.js提供了两种表示3D旋转的方式:[page:Euler Euler angles]和[page:Quaternion Quaternions],以及两者之间的转换方法。 欧拉角受到称为“万向节锁定”的问题,其中某些配置可能失去一定程度的自由度(防止物体绕一个轴旋转)。 因此,对象旋转<em>始终</em>存储在对象的[page:Object3D.quaternion quaternion]中。
+		Three.js提供了两种表示3D旋转的方式:[page:Euler Euler angles](欧拉角)和[page:Quaternion Quaternions](四元数),以及两者之间的转换方法。 欧拉角有称为“万向节锁定”的问题,其中某些配置可能失去一定程度的自由度(防止物体绕一个轴旋转)。 因此,对象旋转<em> 始终 </em>存储在对象的[page:Object3D.quaternion quaternion]中。
 		</p>
 		<p>
-		该库的早期版本包含* useQuaternion *属性,当设置为false时,将导致对象的[page:Object3D.matrix矩阵]从欧拉角计算。 这种做法已被弃用 - 相反,您应该使用[page:Object3D.setRotationFromEuler setRotationFromEuler]方法,该方法将更新四元数。	
+		该库的早期版本包含*useQuaternion*属性,当设置为false时,将导致对象的[page:Object3D.matrix matrix]从欧拉角计算。这种做法已被弃用 - 作为代替,您应该使用[page:Object3D.setRotationFromEuler setRotationFromEuler]方法,该方法将更新四元数。
 		</p>
 
 	</body>

+ 7 - 7
docs/page.js

@@ -17,7 +17,7 @@ if ( !window.frameElement && window.location.protocol !== 'file:' ) {
 
 	}
 
-	var pathSnippet = href.slice( splitIndex, -5 );
+	var pathSnippet = href.slice( splitIndex, - 5 );
 
 	window.location.replace( docsBaseURL + '#' + pathSnippet + hash );
 
@@ -26,7 +26,7 @@ if ( !window.frameElement && window.location.protocol !== 'file:' ) {
 
 function onDocumentLoad( event ) {
 
-	var path;
+	var path, localizedPath;
 	var pathname = window.location.pathname;
 	var section = /\/(manual|api|examples)\//.exec( pathname )[ 1 ].toString().split( '.html' )[ 0 ];
 	var name = /[\-A-z0-9]+\.html/.exec( pathname ).toString().split( '.html' )[ 0 ];
@@ -34,22 +34,22 @@ function onDocumentLoad( event ) {
 	switch ( section ) {
 
 		case 'api':
-			path = /\/api\/[A-z0-9\/]+/.exec( pathname ).toString().substr( 5 );
+			localizedPath = /\/api\/[A-z0-9\/]+/.exec( pathname ).toString().substr( 5 );
 
 			// Remove localized part of the path (e.g. 'en/' or 'es-MX/'):
-			path = path.replace( /^[A-z0-9-]+\//, '' );
+			path = localizedPath.replace( /^[A-z0-9-]+\//, '' );
 
 			break;
 
 		case 'examples':
-			path = /\/examples\/[A-z0-9\/]+/.exec( pathname ).toString().substr( 10 );
+			path = localizedPath = /\/examples\/[A-z0-9\/]+/.exec( pathname ).toString().substr( 10 );
 			break;
 
 		case 'manual':
 			name = name.replace( /\-/g, ' ' );
 
 			path = pathname.replace( /\ /g, '-' );
-			path = /\/manual\/[-A-z0-9\/]+/.exec( path ).toString().substr( 8 );
+			path = localizedPath = /\/manual\/[-A-z0-9\/]+/.exec( path ).toString().substr( 8 );
 			break;
 
 	}
@@ -101,7 +101,7 @@ function onDocumentLoad( event ) {
 
 	button.addEventListener( 'click', function ( event ) {
 
-		window.open( 'https://github.com/mrdoob/three.js/blob/dev/docs/' + section + '/' + path + '.html' );
+		window.open( 'https://github.com/mrdoob/three.js/blob/dev/docs/' + section + '/' + localizedPath + '.html' );
 
 	}, false );
 

+ 34 - 25
docs/scenes/bones-browser.html

@@ -43,12 +43,10 @@
 			var gui, scene, camera, renderer, orbit, lights, mesh, bones, skeletonHelper;
 
 			var state = {
-
-				animateBones : false
-
+				animateBones: false
 			};
 
-			function initScene () {
+			function initScene() {
 
 				gui = new dat.GUI();
 				scene = new THREE.Scene();
@@ -92,35 +90,46 @@
 
 			}
 
-			function createGeometry ( sizing ) {
+			function createGeometry( sizing ) {
 
-				var geometry = new THREE.CylinderGeometry(
-					5,                       // radiusTop
-					5,                       // radiusBottom
-					sizing.height,           // height
-					8,                       // radiusSegments
+				var geometry = new THREE.CylinderBufferGeometry(
+					5, // radiusTop
+					5, // radiusBottom
+					sizing.height, // height
+					8, // radiusSegments
 					sizing.segmentCount * 3, // heightSegments
-					true                     // openEnded
+					true // openEnded
 				);
 
-				for ( var i = 0; i < geometry.vertices.length; i ++ ) {
+				var position = geometry.attributes.position;
+
+				var vertex = new THREE.Vector3();
+
+				var skinIndices = [];
+				var skinWeights = [];
+
+				for ( var i = 0; i < position.count; i ++ ) {
+
+					vertex.fromBufferAttribute( position, i );
 
-					var vertex = geometry.vertices[ i ];
 					var y = ( vertex.y + sizing.halfHeight );
 
 					var skinIndex = Math.floor( y / sizing.segmentHeight );
 					var skinWeight = ( y % sizing.segmentHeight ) / sizing.segmentHeight;
 
-					geometry.skinIndices.push( new THREE.Vector4( skinIndex, skinIndex + 1, 0, 0 ) );
-					geometry.skinWeights.push( new THREE.Vector4( 1 - skinWeight, skinWeight, 0, 0 ) );
+					skinIndices.push( skinIndex, skinIndex + 1, 0, 0 );
+					skinWeights.push( 1 - skinWeight, skinWeight, 0, 0 );
 
 				}
 
+				geometry.addAttribute( 'skinIndex', new THREE.Uint16BufferAttribute( skinIndices, 4 ) );
+				geometry.addAttribute( 'skinWeight', new THREE.Float32BufferAttribute( skinWeights, 4 ) );
+
 				return geometry;
 
 			}
 
-			function createBones ( sizing ) {
+			function createBones( sizing ) {
 
 				bones = [];
 
@@ -142,10 +151,10 @@
 
 			}
 
-			function createMesh ( geometry, bones ) {
+			function createMesh( geometry, bones ) {
 
 				var material = new THREE.MeshPhongMaterial( {
-					skinning : true,
+					skinning: true,
 					color: 0x156289,
 					emissive: 0x072534,
 					side: THREE.DoubleSide,
@@ -167,7 +176,7 @@
 
 			}
 
-			function setupDatGui () {
+			function setupDatGui() {
 
 				var folder = gui.addFolder( "General Options" );
 
@@ -213,7 +222,7 @@
 
 			}
 
-			function initBones () {
+			function initBones() {
 
 				var segmentHeight = 8;
 				var segmentCount = 4;
@@ -221,10 +230,10 @@
 				var halfHeight = height * 0.5;
 
 				var sizing = {
-					segmentHeight : segmentHeight,
-					segmentCount : segmentCount,
-					height : height,
-					halfHeight : halfHeight
+					segmentHeight: segmentHeight,
+					segmentCount: segmentCount,
+					height: height,
+					halfHeight: halfHeight
 				};
 
 				var geometry = createGeometry( sizing );
@@ -236,7 +245,7 @@
 
 			}
 
-			function render () {
+			function render() {
 
 				requestAnimationFrame( render );
 

+ 5 - 0
examples/js/Octree.js

@@ -2131,6 +2131,11 @@
 
 		}
 
+		// we should sort it, the elements in it aren't arranged by distance.
+		intersects.sort( function( a, b ) {
+			return a.distance - b.distance;
+		} );
+
 		return intersects;
 
 	};

+ 3 - 1
examples/js/VolumeSlice.js

@@ -196,13 +196,15 @@ THREE.VolumeSlice.prototype = {
 		this.ctx = this.canvas.getContext( '2d' );
 		this.ctxBuffer = this.canvasBuffer.getContext( '2d' );
 
+		if ( this.geometry ) this.geometry.dispose(); // dispose existing geometry
+
 		this.geometry = new THREE.PlaneBufferGeometry( extracted.planeWidth, extracted.planeHeight );
 
 		if ( this.mesh ) {
 
 			this.mesh.geometry = this.geometry;
 			//reset mesh matrix
-			this.mesh.matrix = ( new THREE.Matrix4() ).identity();
+			this.mesh.matrix.identity();
 			this.mesh.applyMatrix( this.matrix );
 
 		}

+ 13 - 13
examples/js/animation/MMDPhysics.js

@@ -1072,19 +1072,19 @@ THREE.MMDPhysics = ( function () {
 
 			var manager = this.manager;
 
-			var tr = this._getWorldTransformForBone();
-
-			var thV = manager.allocThreeVector3();
-
-			var o = manager.getOrigin( tr );
-			thV.set( o.x(), o.y(), o.z() );
-
-			var v = this.bone.worldToLocal( thV );
-			this.bone.position.add( v );
-
-			manager.freeThreeVector3( thV );
-
-			manager.freeTransform( tr );
+			var tr = this.body.getCenterOfMassTransform();
+			var origin = tr.getOrigin();
+			
+			var matrixInv = manager.allocThreeMatrix4();
+			matrixInv.copy( this.bone.parent.matrixWorld ).getInverse( matrixInv );
+			
+			var pos = manager.allocThreeVector3();
+			pos.set( origin.x(), origin.y(), origin.z() ).applyMatrix4( matrixInv );
+
+			this.bone.position.copy( pos );
+
+			manager.freeThreeVector3( pos );
+			manager.freeThreeMatrix4( matrixInv );
 
 		}
 

+ 3 - 2
examples/js/controls/EditorControls.js

@@ -32,6 +32,7 @@ THREE.EditorControls = function ( object, domElement ) {
 	var pointer = new THREE.Vector2();
 	var pointerOld = new THREE.Vector2();
 	var spherical = new THREE.Spherical();
+	var sphere = new THREE.Sphere();
 
 	// events
 
@@ -45,8 +46,8 @@ THREE.EditorControls = function ( object, domElement ) {
 
 		if ( box.isEmpty() === false ) {
 
-			center.copy( box.getCenter() );
-			distance = box.getBoundingSphere().radius;
+			box.getCenter( center );
+			distance = box.getBoundingSphere( sphere ).radius;
 
 		} else {
 

+ 66 - 19
examples/js/exporters/GLTFExporter.js

@@ -28,19 +28,26 @@ var WEBGL_CONSTANTS = {
 	NEAREST_MIPMAP_NEAREST: 0x2700,
 	LINEAR_MIPMAP_NEAREST: 0x2701,
 	NEAREST_MIPMAP_LINEAR: 0x2702,
-	LINEAR_MIPMAP_LINEAR: 0x2703
-};
+	LINEAR_MIPMAP_LINEAR: 0x2703,
 
-var THREE_TO_WEBGL = {
-	// @TODO Replace with computed property name [THREE.*] when available on es6
-	1003: WEBGL_CONSTANTS.NEAREST,
-	1004: WEBGL_CONSTANTS.NEAREST_MIPMAP_NEAREST,
-	1005: WEBGL_CONSTANTS.NEAREST_MIPMAP_LINEAR,
-	1006: WEBGL_CONSTANTS.LINEAR,
-	1007: WEBGL_CONSTANTS.LINEAR_MIPMAP_NEAREST,
-	1008: WEBGL_CONSTANTS.LINEAR_MIPMAP_LINEAR
+	CLAMP_TO_EDGE: 33071,
+	MIRRORED_REPEAT: 33648,
+	REPEAT: 10497
 };
 
+var THREE_TO_WEBGL = {};
+
+THREE_TO_WEBGL[ THREE.NearestFilter ] = WEBGL_CONSTANTS.NEAREST;
+THREE_TO_WEBGL[ THREE.NearestMipMapNearestFilter ] = WEBGL_CONSTANTS.NEAREST_MIPMAP_NEAREST;
+THREE_TO_WEBGL[ THREE.NearestMipMapLinearFilter ] = WEBGL_CONSTANTS.NEAREST_MIPMAP_LINEAR;
+THREE_TO_WEBGL[ THREE.LinearFilter ] = WEBGL_CONSTANTS.LINEAR;
+THREE_TO_WEBGL[ THREE.LinearMipMapNearestFilter ] = WEBGL_CONSTANTS.LINEAR_MIPMAP_NEAREST;
+THREE_TO_WEBGL[ THREE.LinearMipMapLinearFilter ] = WEBGL_CONSTANTS.LINEAR_MIPMAP_LINEAR;
+
+THREE_TO_WEBGL[ THREE.ClampToEdgeWrapping ] = WEBGL_CONSTANTS.CLAMP_TO_EDGE;
+THREE_TO_WEBGL[ THREE.RepeatWrapping ] = WEBGL_CONSTANTS.REPEAT;
+THREE_TO_WEBGL[ THREE.MirroredRepeatWrapping ] = WEBGL_CONSTANTS.MIRRORED_REPEAT;
+
 var PATH_PROPERTIES = {
 	scale: 'scale',
 	position: 'translation',
@@ -104,7 +111,9 @@ THREE.GLTFExporter.prototype = {
 		var extensionsUsed = {};
 		var cachedData = {
 
+			meshes: new Map(),
 			attributes: new Map(),
+			attributesNormalized: new Map(),
 			materials: new Map(),
 			textures: new Map(),
 			images: new Map()
@@ -214,7 +223,7 @@ THREE.GLTFExporter.prototype = {
 		 */
 		function isNormalizedNormalAttribute( normal ) {
 
-			if ( cachedData.attributes.has( normal ) ) {
+			if ( cachedData.attributesNormalized.has( normal ) ) {
 
 				return false;
 
@@ -242,9 +251,9 @@ THREE.GLTFExporter.prototype = {
 		 */
 		function createNormalizedNormalAttribute( normal ) {
 
-			if ( cachedData.attributes.has( normal ) ) {
+			if ( cachedData.attributesNormalized.has( normal ) ) {
 
-				return cachedData.attributes.get( normal );
+				return cachedData.attributesNormalized.get( normal );
 
 			}
 
@@ -271,7 +280,7 @@ THREE.GLTFExporter.prototype = {
 
 			}
 
-			cachedData.attributes.set( normal, attribute );
+			cachedData.attributesNormalized.set( normal, attribute );
 
 			return attribute;
 
@@ -1001,6 +1010,13 @@ THREE.GLTFExporter.prototype = {
 		 */
 		function processMesh( mesh ) {
 
+			var cacheKey = mesh.geometry.uuid + ':' + mesh.material.uuid;
+			if ( cachedData.meshes.has( cacheKey ) ) {
+
+				return cachedData.meshes.get( cacheKey );
+
+			}
+
 			var geometry = mesh.geometry;
 
 			var mode;
@@ -1083,23 +1099,32 @@ THREE.GLTFExporter.prototype = {
 				var attribute = geometry.attributes[ attributeName ];
 				attributeName = nameConversion[ attributeName ] || attributeName.toUpperCase();
 
+				if ( cachedData.attributes.has( attribute ) ) {
+
+					attributes[ attributeName ] = cachedData.attributes.get( attribute );
+					continue;
+
+				}
+
 				// JOINTS_0 must be UNSIGNED_BYTE or UNSIGNED_SHORT.
+				var modifiedAttribute;
 				var array = attribute.array;
 				if ( attributeName === 'JOINTS_0' &&
 					! ( array instanceof Uint16Array ) &&
 					! ( array instanceof Uint8Array ) ) {
 
 					console.warn( 'GLTFExporter: Attribute "skinIndex" converted to type UNSIGNED_SHORT.' );
-					attribute = new THREE.BufferAttribute( new Uint16Array( array ), attribute.itemSize, attribute.normalized );
+					modifiedAttribute = new THREE.BufferAttribute( new Uint16Array( array ), attribute.itemSize, attribute.normalized );
 
 				}
 
 				if ( attributeName.substr( 0, 5 ) !== 'MORPH' ) {
 
-					var accessor = processAccessor( attribute, geometry );
+					var accessor = processAccessor( modifiedAttribute || attribute, geometry );
 					if ( accessor !== null ) {
 
 						attributes[ attributeName ] = accessor;
+						cachedData.attributes.set( attribute, accessor );
 
 					}
 
@@ -1158,6 +1183,7 @@ THREE.GLTFExporter.prototype = {
 						}
 
 						var attribute = geometry.morphAttributes[ attributeName ][ i ];
+						var gltfAttributeName = attributeName.toUpperCase();
 
 						// Three.js morph attribute has absolute values while the one of glTF has relative values.
 						//
@@ -1165,6 +1191,14 @@ THREE.GLTFExporter.prototype = {
 						// https://github.com/KhronosGroup/glTF/tree/master/specification/2.0#morph-targets
 
 						var baseAttribute = geometry.attributes[ attributeName ];
+
+						if ( cachedData.attributes.has( baseAttribute ) ) {
+
+							target[ gltfAttributeName ] = cachedData.attributes.get( baseAttribute );
+							continue;
+
+						}
+
 						// Clones attribute not to override
 						var relativeAttribute = attribute.clone();
 
@@ -1179,7 +1213,8 @@ THREE.GLTFExporter.prototype = {
 
 						}
 
-						target[ attributeName.toUpperCase() ] = processAccessor( relativeAttribute, geometry );
+						target[ gltfAttributeName ] = processAccessor( relativeAttribute, geometry );
+						cachedData.attributes.set( baseAttribute, target[ gltfAttributeName ] );
 
 					}
 
@@ -1250,7 +1285,16 @@ THREE.GLTFExporter.prototype = {
 
 				if ( geometry.index !== null ) {
 
-					primitive.indices = processAccessor( geometry.index, geometry, groups[ i ].start, groups[ i ].count );
+					if ( cachedData.attributes.has( geometry.index ) ) {
+
+						primitive.indices = cachedData.attributes.get( geometry.index );
+
+					} else {
+
+						primitive.indices = processAccessor( geometry.index, geometry, groups[ i ].start, groups[ i ].count );
+						cachedData.attributes.set( geometry.index, primitive.indices );
+
+					}
 
 				}
 
@@ -1282,7 +1326,10 @@ THREE.GLTFExporter.prototype = {
 
 			outputJSON.meshes.push( gltfMesh );
 
-			return outputJSON.meshes.length - 1;
+			var index = outputJSON.meshes.length - 1;
+			cachedData.meshes.set( cacheKey, index );
+
+			return index;
 
 		}
 

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

@@ -1228,6 +1228,8 @@ THREE.ColladaLoader.prototype = {
 					case 'emission':
 					case 'diffuse':
 					case 'specular':
+					case 'bump':
+					case 'ambient':
 					case 'shininess':
 					case 'transparency':
 						data[ child.nodeName ] = parseEffectParameter( child );
@@ -1590,6 +1592,12 @@ THREE.ColladaLoader.prototype = {
 						if ( parameter.color && material.specular ) material.specular.fromArray( parameter.color );
 						if ( parameter.texture ) material.specularMap = getTexture( parameter.texture );
 						break;
+					case 'bump':
+						if ( parameter.texture ) material.normalMap = getTexture( parameter.texture );
+						break;
+					case 'ambient':
+						if ( parameter.texture ) material.lightMap = getTexture( parameter.texture );
+						break;
 					case 'shininess':
 						if ( parameter.float && material.shininess ) material.shininess = parameter.float;
 						break;
@@ -2122,7 +2130,9 @@ THREE.ColladaLoader.prototype = {
 						var id = parseId( child.getAttribute( 'source' ) );
 						var semantic = child.getAttribute( 'semantic' );
 						var offset = parseInt( child.getAttribute( 'offset' ) );
-						primitive.inputs[ semantic ] = { id: id, offset: offset };
+						var set = parseInt( child.getAttribute( 'set' ) );
+						var inputname = ( set > 0 ? semantic + set : semantic );
+						primitive.inputs[ inputname ] = { id: id, offset: offset };
 						primitive.stride = Math.max( primitive.stride, offset + 1 );
 						if ( semantic === 'TEXCOORD' ) primitive.hasUV = true;
 						break;
@@ -2225,6 +2235,7 @@ THREE.ColladaLoader.prototype = {
 			var position = { array: [], stride: 0 };
 			var normal = { array: [], stride: 0 };
 			var uv = { array: [], stride: 0 };
+			var uv2 = { array: [], stride: 0 };
 			var color = { array: [], stride: 0 };
 
 			var skinIndex = { array: [], stride: 4 };
@@ -2357,6 +2368,11 @@ THREE.ColladaLoader.prototype = {
 										uv.stride = sources[ id ].stride;
 										break;
 
+									case 'TEXCOORD1':
+										buildGeometryData( primitive, sources[ id ], input.offset, uv2.array );
+										uv.stride = sources[ id ].stride;
+										break;
+
 									default:
 										console.warn( 'THREE.ColladaLoader: Semantic "%s" not handled in geometry build process.', key );
 
@@ -2380,6 +2396,11 @@ THREE.ColladaLoader.prototype = {
 							uv.stride = sources[ input.id ].stride;
 							break;
 
+						case 'TEXCOORD1':
+							buildGeometryData( primitive, sources[ input.id ], input.offset, uv2.array );
+							uv2.stride = sources[ input.id ].stride;
+							break;
+
 					}
 
 				}
@@ -2392,6 +2413,7 @@ THREE.ColladaLoader.prototype = {
 			if ( normal.array.length > 0 ) geometry.addAttribute( 'normal', new THREE.Float32BufferAttribute( normal.array, normal.stride ) );
 			if ( color.array.length > 0 ) geometry.addAttribute( 'color', new THREE.Float32BufferAttribute( color.array, color.stride ) );
 			if ( uv.array.length > 0 ) geometry.addAttribute( 'uv', new THREE.Float32BufferAttribute( uv.array, uv.stride ) );
+			if ( uv2.array.length > 0 ) geometry.addAttribute( 'uv2', new THREE.Float32BufferAttribute( uv2.array, uv2.stride ) );
 
 			if ( skinIndex.array.length > 0 ) geometry.addAttribute( 'skinIndex', new THREE.Float32BufferAttribute( skinIndex.array, skinIndex.stride ) );
 			if ( skinWeight.array.length > 0 ) geometry.addAttribute( 'skinWeight', new THREE.Float32BufferAttribute( skinWeight.array, skinWeight.stride ) );

+ 17 - 0
examples/js/loaders/GLTFLoader.js

@@ -3165,6 +3165,23 @@ THREE.GLTFLoader = ( function () {
 
 					}
 
+					// if weights are provided on the node, override weights on the mesh.
+					if ( nodeDef.weights !== undefined ) {
+
+						node.traverse( function ( o ) {
+
+							if ( ! o.isMesh ) return;
+
+							for ( var i = 0, il = nodeDef.weights.length; i < il; i ++ ) {
+
+								o.morphTargetInfluences[ i ] = nodeDef.weights[ i ];
+
+							}
+
+						} );
+
+					}
+
 					return node;
 
 				} );

+ 18 - 24
examples/js/loaders/KTXLoader.js

@@ -68,23 +68,24 @@ var KhronosTextureContainer = ( function () {
 
 		}
 
-		// load the reset of the header in native 32 bit int
-		var header = new Int32Array( this.arrayBuffer, 12, 13 );
-		// determine of the remaining header values are recorded in the opposite endianness & require conversion
-		var oppositeEndianess = header[ 0 ] === 0x01020304;
-		// read all the header elements in order they exist in the file, without modification (sans endainness)
-		this.glType = oppositeEndianess ? this.switchEndainness( header[ 1 ] ) : header[ 1 ]; // must be 0 for compressed textures
-		this.glTypeSize = oppositeEndianess ? this.switchEndainness( header[ 2 ] ) : header[ 2 ]; // must be 1 for compressed textures
-		this.glFormat = oppositeEndianess ? this.switchEndainness( header[ 3 ] ) : header[ 3 ]; // must be 0 for compressed textures
-		this.glInternalFormat = oppositeEndianess ? this.switchEndainness( header[ 4 ] ) : header[ 4 ]; // the value of arg passed to gl.compressedTexImage2D(,,x,,,,)
-		this.glBaseInternalFormat = oppositeEndianess ? this.switchEndainness( header[ 5 ] ) : header[ 5 ]; // specify GL_RGB, GL_RGBA, GL_ALPHA, etc (un-compressed only)
-		this.pixelWidth = oppositeEndianess ? this.switchEndainness( header[ 6 ] ) : header[ 6 ]; // level 0 value of arg passed to gl.compressedTexImage2D(,,,x,,,)
-		this.pixelHeight = oppositeEndianess ? this.switchEndainness( header[ 7 ] ) : header[ 7 ]; // level 0 value of arg passed to gl.compressedTexImage2D(,,,,x,,)
-		this.pixelDepth = oppositeEndianess ? this.switchEndainness( header[ 8 ] ) : header[ 8 ]; // level 0 value of arg passed to gl.compressedTexImage3D(,,,,,x,,)
-		this.numberOfArrayElements = oppositeEndianess ? this.switchEndainness( header[ 9 ] ) : header[ 9 ]; // used for texture arrays
-		this.numberOfFaces = oppositeEndianess ? this.switchEndainness( header[ 10 ] ) : header[ 10 ]; // used for cubemap textures, should either be 1 or 6
-		this.numberOfMipmapLevels = oppositeEndianess ? this.switchEndainness( header[ 11 ] ) : header[ 11 ]; // number of levels; disregard possibility of 0 for compressed textures
-		this.bytesOfKeyValueData = oppositeEndianess ? this.switchEndainness( header[ 12 ] ) : header[ 12 ]; // the amount of space after the header for meta-data
+		// load the reset of the header in native 32 bit uint
+		var dataSize = Uint32Array.BYTES_PER_ELEMENT;
+		var headerDataView = new DataView( this.arrayBuffer, 12, 13 * dataSize );
+		var endianness = headerDataView.getUint32( 0, true );
+		var littleEndian = endianness === 0x04030201;
+
+		this.glType = headerDataView.getUint32( 1 * dataSize, littleEndian ); // must be 0 for compressed textures
+		this.glTypeSize = headerDataView.getUint32( 2 * dataSize, littleEndian ); // must be 1 for compressed textures
+		this.glFormat = headerDataView.getUint32( 3 * dataSize, littleEndian ); // must be 0 for compressed textures
+		this.glInternalFormat = headerDataView.getUint32( 4 * dataSize, littleEndian ); // the value of arg passed to gl.compressedTexImage2D(,,x,,,,)
+		this.glBaseInternalFormat = headerDataView.getUint32( 5 * dataSize, littleEndian ); // specify GL_RGB, GL_RGBA, GL_ALPHA, etc (un-compressed only)
+		this.pixelWidth = headerDataView.getUint32( 6 * dataSize, littleEndian ); // level 0 value of arg passed to gl.compressedTexImage2D(,,,x,,,)
+		this.pixelHeight = headerDataView.getUint32( 7 * dataSize, littleEndian ); // level 0 value of arg passed to gl.compressedTexImage2D(,,,,x,,)
+		this.pixelDepth = headerDataView.getUint32( 8 * dataSize, littleEndian ); // level 0 value of arg passed to gl.compressedTexImage3D(,,,,,x,,)
+		this.numberOfArrayElements = headerDataView.getUint32( 9 * dataSize, littleEndian ); // used for texture arrays
+		this.numberOfFaces = headerDataView.getUint32( 10 * dataSize, littleEndian ); // used for cubemap textures, should either be 1 or 6
+		this.numberOfMipmapLevels = headerDataView.getUint32( 11 * dataSize, littleEndian ); // number of levels; disregard possibility of 0 for compressed textures
+		this.bytesOfKeyValueData = headerDataView.getUint32( 12 * dataSize, littleEndian ); // the amount of space after the header for meta-data
 
 		// Make sure we have a compressed type.  Not only reduces work, but probably better to let dev know they are not compressing.
 		if ( this.glType !== 0 ) {
@@ -122,13 +123,6 @@ var KhronosTextureContainer = ( function () {
 
 	}
 
-	// not as fast hardware based, but will probably never need to use
-	KhronosTextureContainer.prototype.switchEndainness = function ( val ) {
-
-		return ( ( val & 0xFF ) << 24 ) | ( ( val & 0xFF00 ) << 8 ) | ( ( val >> 8 ) & 0xFF00 ) | ( ( val >> 24 ) & 0xFF );
-
-	};
-
 	// return mipmaps for THREE.js
 	KhronosTextureContainer.prototype.mipmaps = function ( loadMipmaps ) {
 

+ 15 - 0
examples/js/loaders/MTLLoader.js

@@ -413,6 +413,13 @@ THREE.MTLLoader.MaterialCreator.prototype = {
 
 					break;
 
+				case 'ke':
+
+					// Emissive using RGB values
+					params.emissive = new THREE.Color().fromArray( value );
+
+					break;
+
 				case 'map_kd':
 
 					// Diffuse texture map
@@ -429,6 +436,14 @@ THREE.MTLLoader.MaterialCreator.prototype = {
 
 					break;
 
+				case 'map_ke':
+
+					// Emissive map
+
+					setMapForType( "emissiveMap", value );
+
+					break;
+
 				case 'norm':
 
 					setMapForType( "normalMap", value );

+ 1 - 1
examples/js/nodes/math/Math1Node.js

@@ -26,7 +26,7 @@ Math1Node.FLOOR = 'floor';
 Math1Node.CEIL = 'ceil';
 Math1Node.NORMALIZE = 'normalize';
 Math1Node.FRACT = 'fract';
-Math1Node.SAT = 'saturate';
+Math1Node.SATURATE = 'saturate';
 Math1Node.SIN = 'sin';
 Math1Node.COS = 'cos';
 Math1Node.TAN = 'tan';

+ 1 - 0
examples/js/nodes/math/Math3Node.js

@@ -17,6 +17,7 @@ function Math3Node( a, b, c, method ) {
 }
 
 Math3Node.MIX = 'mix';
+Math3Node.CLAMP = 'clamp';
 Math3Node.REFRACT = 'refract';
 Math3Node.SMOOTHSTEP = 'smoothstep';
 Math3Node.FACEFORWARD = 'faceforward';

+ 18 - 13
examples/js/renderers/RaytracingWorker.js

@@ -168,7 +168,7 @@ THREE.RaytracingRendererWorker = function () {
 			var material = object.material;
 			var face = intersection.face;
 
-			var vertices = object.geometry.vertices;
+			var geometry = object.geometry;
 
 			//
 
@@ -250,7 +250,7 @@ THREE.RaytracingRendererWorker = function () {
 						// (should be possible to cache even more)
 
 						localPoint.copy( point ).applyMatrix4( _object.inverseMatrix );
-						computePixelNormal( normalVector, localPoint, material.flatShading, face, vertices );
+						computePixelNormal( normalVector, localPoint, material.flatShading, face, geometry );
 						normalVector.applyMatrix3( _object.normalMatrix ).normalize();
 
 						normalComputed = true;
@@ -378,14 +378,17 @@ THREE.RaytracingRendererWorker = function () {
 
 	var computePixelNormal = ( function () {
 
+		var vA = new THREE.Vector3();
+		var vB = new THREE.Vector3();
+		var vC = new THREE.Vector3();
+
 		var tmpVec1 = new THREE.Vector3();
 		var tmpVec2 = new THREE.Vector3();
 		var tmpVec3 = new THREE.Vector3();
 
-		return function computePixelNormal( outputVector, point, flatShading, face, vertices ) {
+		return function computePixelNormal( outputVector, point, flatShading, face, geometry ) {
 
 			var faceNormal = face.normal;
-			var vertexNormals = face.vertexNormals;
 
 			if ( flatShading === true ) {
 
@@ -393,11 +396,14 @@ THREE.RaytracingRendererWorker = function () {
 
 			} else {
 
-				// compute barycentric coordinates
+				var positions = geometry.attributes.position;
+				var normals = geometry.attributes.normal;
 
-				var vA = vertices[ face.a ];
-				var vB = vertices[ face.b ];
-				var vC = vertices[ face.c ];
+				vA.fromBufferAttribute( positions, face.a );
+				vB.fromBufferAttribute( positions, face.b );
+				vC.fromBufferAttribute( positions, face.c );
+
+				// compute barycentric coordinates
 
 				tmpVec3.crossVectors( tmpVec1.subVectors( vB, vA ), tmpVec2.subVectors( vC, vA ) );
 				var areaABC = faceNormal.dot( tmpVec3 );
@@ -414,13 +420,12 @@ THREE.RaytracingRendererWorker = function () {
 
 				// compute interpolated vertex normal
 
-				tmpVec1.copy( vertexNormals[ 0 ] );
-				tmpVec1.multiplyScalar( a );
+				tmpVec1.fromBufferAttribute( normals, face.a );
+				tmpVec2.fromBufferAttribute( normals, face.b );
+				tmpVec3.fromBufferAttribute( normals, face.c );
 
-				tmpVec2.copy( vertexNormals[ 1 ] );
+				tmpVec1.multiplyScalar( a );
 				tmpVec2.multiplyScalar( b );
-
-				tmpVec3.copy( vertexNormals[ 2 ] );
 				tmpVec3.multiplyScalar( c );
 
 				outputVector.addVectors( tmpVec1, tmpVec2 );

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

@@ -540,7 +540,7 @@ THREE.SoftwareRenderer = function ( parameters ) {
 
 				} else {
 
-					if ( material.vertexColors === THREE.FaceColors ) {
+					if ( material.vertexColors === THREE.FaceColors || material.vertexColors === THREE.VertexColors ) {
 
 						string = [
 							'var colorOffset = offset * 4;',

+ 3 - 3
examples/raytracing_sandbox.html

@@ -139,9 +139,9 @@
 
 				// geometries
 
-				var sphereGeometry = new THREE.SphereGeometry( 100, 16, 8 );
-				var planeGeometry = new THREE.BoxGeometry( 600, 5, 600 );
-				var boxGeometry = new THREE.BoxGeometry( 100, 100, 100 );
+				var sphereGeometry = new THREE.SphereBufferGeometry( 100, 16, 8 );
+				var planeGeometry = new THREE.BoxBufferGeometry( 600, 5, 600 );
+				var boxGeometry = new THREE.BoxBufferGeometry( 100, 100, 100 );
 
 				// Sphere
 

+ 35 - 24
examples/software_lines_splines.html

@@ -66,9 +66,7 @@
 
 			function init() {
 
-				var i, container;
-
-				container = document.createElement( 'div' );
+				var container = document.createElement( 'div' );
 				document.body.appendChild( container );
 
 				camera = new THREE.PerspectiveCamera( 33, window.innerWidth / window.innerHeight, 1, 10000 );
@@ -81,38 +79,51 @@
 
 				container.appendChild( renderer.domElement );
 
-				var geometry = new THREE.Geometry(),
-					geometry2 = new THREE.Geometry(),
-					geometry3 = new THREE.Geometry(),
-					points = hilbert3D( new THREE.Vector3(), 200.0, 1, 0, 1, 2, 3, 4, 5, 6, 7 ),
-					colors = [], colors2 = [], colors3 = [];
+				//
+
+				var hilbertPoints = hilbert3D( new THREE.Vector3( 0, 0, 0 ), 200.0, 1, 0, 1, 2, 3, 4, 5, 6, 7 );
+
+				var geometry1 = new THREE.BufferGeometry();
+				var geometry2 = new THREE.BufferGeometry();
+				var geometry3 = new THREE.BufferGeometry();
 
 				var subdivisions = 6;
 
-				var spline = new THREE.CatmullRomCurve3( points );
+				var vertices = [];
+				var colors1 = [];
+				var colors2 = [];
+				var colors3 = [];
+
 				var point = new THREE.Vector3();
+				var color = new THREE.Color();
+
+				var spline = new THREE.CatmullRomCurve3( hilbertPoints );
+
+				for ( var i = 0; i < hilbertPoints.length * subdivisions; i ++ ) {
 
-				for ( i = 0; i < points.length * subdivisions; i ++ ) {
+					var t = i / ( hilbertPoints.length * subdivisions );
+					spline.getPoint( t, point );
 
-					var t = i / ( points.length * subdivisions );
-					geometry.vertices[ i ] = spline.getPoint( t );
+					vertices.push( point.x, point.y, point.z );
 
-					colors[ i ] = new THREE.Color( 0xffffff );
-					colors[ i ].setHSL( 0.6, 1.0, Math.max( 0, - point.x / 200 ) + 0.5 );
+					color.setHSL( 0.6, 1.0, Math.max( 0, - point.x / 200 ) + 0.5 );
+					colors1.push( color.r, color.g, color.b );
 
-					colors2[ i ] = new THREE.Color( 0xffffff );
-					colors2[ i ].setHSL( 0.9, 1.0, Math.max( 0, - point.y / 200 ) + 0.5 );
+					color.setHSL( 0.9, 1.0, Math.max( 0, - point.y / 200 ) + 0.5 );
+					colors2.push( color.r, color.g, color.b );
 
-					colors3[ i ] = new THREE.Color( 0xffffff );
-					colors3[ i ].setHSL( i / ( points.length * subdivisions ), 1.0, 0.5 );
+					color.setHSL( i / ( hilbertPoints.length * subdivisions ), 1.0, 0.5 );
+					colors3.push( color.r, color.g, color.b );
 
 				}
 
-				geometry2.vertices = geometry3.vertices = geometry.vertices;
+				geometry1.addAttribute( 'position', new THREE.Float32BufferAttribute( vertices, 3 ) );
+				geometry2.addAttribute( 'position', new THREE.Float32BufferAttribute( vertices, 3 ) );
+				geometry3.addAttribute( 'position', new THREE.Float32BufferAttribute( vertices, 3 ) );
 
-				geometry.colors = colors;
-				geometry2.colors = colors2;
-				geometry3.colors = colors3;
+				geometry1.addAttribute( 'color', new THREE.Float32BufferAttribute( colors1, 3 ) );
+				geometry2.addAttribute( 'color', new THREE.Float32BufferAttribute( colors2, 3 ) );
+				geometry3.addAttribute( 'color', new THREE.Float32BufferAttribute( colors3, 3 ) );
 
 				// lines
 
@@ -120,12 +131,12 @@
 
 				var line, p, scale = 0.3, d = 225;
 				var parameters = [
-					[ material, scale * 1.5, [ - d, 0, 0 ], geometry ],
+					[ material, scale * 1.5, [ - d, 0, 0 ], geometry1 ],
 					[ material, scale * 1.5, [ 0, 0, 0 ], geometry2 ],
 					[ material, scale * 1.5, [ d, 0, 0 ], geometry3 ]
 				];
 
-				for ( i = 0; i < parameters.length; ++ i ) {
+				for ( var i = 0; i < parameters.length; ++ i ) {
 
 					p = parameters[ i ];
 					line = new THREE.Line( p[ 3 ], p[ 0 ] );

+ 63 - 32
examples/software_sandbox.html

@@ -7,14 +7,31 @@
 		<style>
 			body {
 				font-family: Monospace;
-				background-color: #f0f0f0;
 				margin: 0px;
 				overflow: hidden;
 			}
+			a {
+				color:#0078ff;
+			}
+			#info {
+				position: absolute;
+				top: 10px; width: 100%;
+				color: #ffffff;
+				padding: 5px;
+				font-family: Monospace;
+				font-size: 13px;
+				text-align: center;
+				z-index:100;
+			}
 		</style>
 	</head>
 	<body>
 
+		<div id="info">
+			<a href="http://threejs.org" target="_blank" rel="noopener">three.js</a> - software renderer</br>
+			drag to change the point of view
+		</div>
+
 		<script src="../build/three.js"></script>
 		<script src="js/geometries/hilbert3D.js"></script>
 		<script src="js/controls/TrackballControls.js"></script>
@@ -23,9 +40,7 @@
 		<script src="js/libs/stats.min.js"></script>
 		<script>
 
-			var container, stats;
-
-			var camera, controls, scene, renderer;
+			var camera, controls, scene, renderer, stats;
 
 			var torus, cube, texCube;
 
@@ -36,17 +51,9 @@
 
 			function init() {
 
-				container = document.createElement( 'div' );
+				var container = document.createElement( 'div' );
 				document.body.appendChild( container );
 
-				var info = document.createElement( 'div' );
-				info.style.position = 'absolute';
-				info.style.top = '10px';
-				info.style.width = '100%';
-				info.style.textAlign = 'center';
-				info.innerHTML = '<a href="http://threejs.org" target="_blank" rel="noopener">three.js<a/> - software renderer<br/>drag to change the point of view';
-				container.appendChild( info );
-
 				camera = new THREE.PerspectiveCamera( 70, window.innerWidth / window.innerHeight, 1, 2000 );
 				camera.position.z = 600;
 
@@ -55,34 +62,47 @@
 				scene = new THREE.Scene();
 
 				// Torus
-				var geometry = new THREE.TorusKnotGeometry( 150 );
+				var torusGeometry = new THREE.TorusKnotBufferGeometry( 150, 10 );
+				torusGeometry = torusGeometry.toNonIndexed();
 
-				for ( var i = 0, j = geometry.faces.length; i < j; i ++ ) {
+				var colors = [];
+				var color = new THREE.Color();
 
-					geometry.faces[ i ].color.setHex( Math.random() * 0xffffff );
+				for ( var i = 0; i < torusGeometry.attributes.position.count; i ++ ) {
+
+					color.setHex( Math.random() * 0xffffff );
+					colors.push( color.r, color.g, color.b );
 
 				}
 
-				torus = new THREE.Mesh( geometry, new THREE.MeshBasicMaterial( { color: 0x0000ff, vertexColors: THREE.FaceColors } ) );
+				torusGeometry.addAttribute( 'color', new THREE.Float32BufferAttribute( colors, 3 ) );
+
+				torus = new THREE.Mesh( torusGeometry, new THREE.MeshBasicMaterial( { color: 0x0000ff, vertexColors: THREE.VertexColors } ) );
 				scene.add( torus );
 
 				// Cube
-				var geometry = new THREE.BoxGeometry( 200, 200, 200 );
+				var boxGeometry = new THREE.BoxBufferGeometry( 200, 200, 200 );
+				boxGeometry = boxGeometry.toNonIndexed();
 
-				for ( var i = 0, j = geometry.faces.length; i < j; i ++ ) {
+				colors = [];
 
-					geometry.faces[ i ].color.setHex( Math.random() * 0xffffff );
+				for ( var i = 0; i < boxGeometry.attributes.position.count; i ++ ) {
+
+					color.setHex( Math.random() * 0xffffff );
+					colors.push( color.r, color.g, color.b );
 
 				}
 
-				cube = new THREE.Mesh( geometry, new THREE.MeshBasicMaterial( { color: 0x00ff00, vertexColors: THREE.FaceColors } ) );
+				boxGeometry.addAttribute( 'color', new THREE.Float32BufferAttribute( colors, 3 ) );
+
+				cube = new THREE.Mesh( boxGeometry, new THREE.MeshBasicMaterial( { color: 0x00ff00, vertexColors: THREE.VertexColors } ) );
 				scene.position.set( 100, 0, 0 );
 				scene.add( cube );
 
 				// Cube with texture
 				var loader = new THREE.TextureLoader();
 				var map = loader.load( 'textures/brick_diffuse.jpg' );
-				texCube = new THREE.Mesh( geometry, new THREE.MeshLambertMaterial( { map: map } ) );
+				texCube = new THREE.Mesh( boxGeometry, new THREE.MeshLambertMaterial( { map: map } ) );
 				texCube.position.set( - 300, 0, 0 );
 				scene.add( texCube );
 
@@ -101,22 +121,31 @@
 				scene.add( texSprite );
 
 				// Line
-				var points = hilbert3D( new THREE.Vector3( 0, 0, 0 ), 200.0, 1, 0, 1, 2, 3, 4, 5, 6, 7 );
-				var spline = new THREE.CatmullRomCurve3( points );
-				var n_sub = 6, colors = [];
+				var hilbertPoints = hilbert3D( new THREE.Vector3( 0, 0, 0 ), 200.0, 1, 0, 1, 2, 3, 4, 5, 6, 7 );
+
+				var lineGeometry = new THREE.BufferGeometry();
+				var subdivisions = 6;
+
+				var vertices = [];
+				colors = [];
 
-				var lineGeometry = new THREE.Geometry();
-				var vertices = lineGeometry.vertices;
+				var point = new THREE.Vector3();
+				color.setHex( 0x88aaff );
 
-				for ( var i = 0; i < points.length * n_sub; i ++ ) {
+				var spline = new THREE.CatmullRomCurve3( hilbertPoints );
 
-					var t = i / ( points.length * n_sub );
-					vertices[ i ] = spline.getPoint( t );
-					colors[ i ] = new THREE.Color( 0x88aaff );
+				for ( var i = 0; i < hilbertPoints.length * subdivisions; i ++ ) {
+
+					var t = i / ( hilbertPoints.length * subdivisions );
+					spline.getPoint( t, point );
+
+					vertices.push( point.x, point.y, point.z );
+					colors.push( color.r, color.g, color.b );
 
 				}
 
-				lineGeometry.colors = colors;
+				lineGeometry.addAttribute( 'position', new THREE.Float32BufferAttribute( vertices, 3 ) );
+				lineGeometry.addAttribute( 'color', new THREE.Float32BufferAttribute( colors, 3 ) );
 
 				var material = new THREE.LineBasicMaterial( { opacity: 1, linewidth: 3, vertexColors: THREE.VertexColors } );
 				var line = new THREE.Line( lineGeometry, material );
@@ -124,6 +153,8 @@
 				line.position.set( 0, - 200, 0 );
 				scene.add( line );
 
+				//
+
 				renderer = new THREE.SoftwareRenderer();
 				renderer.setSize( window.innerWidth, window.innerHeight );
 

+ 27 - 15
examples/svg_sandbox.html

@@ -84,30 +84,39 @@
 
 				// POLYFIELD
 
-				var geometry = new THREE.Geometry();
-				var material = new THREE.MeshBasicMaterial( { vertexColors: THREE.FaceColors, side: THREE.DoubleSide } );
+				var geometry = new THREE.BufferGeometry();
+				var material = new THREE.MeshBasicMaterial( { vertexColors: THREE.VertexColors, side: THREE.DoubleSide } );
+
+				var v = new THREE.Vector3();
+				var v0 = new THREE.Vector3();
+				var v1 = new THREE.Vector3();
+				var v2 = new THREE.Vector3();
+				var color = new THREE.Color();
+
+				var vertices = [];
+				var colors = [];
 
 				for ( var i = 0; i < 100; i ++ ) {
 
-					var v = new THREE.Vector3(
+					v.set(
 						Math.random() * 1000 - 500,
 						Math.random() * 1000 - 500,
 						Math.random() * 1000 - 500
 					);
 
-					var v0 = new THREE.Vector3(
+					v0.set(
 						Math.random() * 100 - 50,
 						Math.random() * 100 - 50,
 						Math.random() * 100 - 50
 					);
 
-					var v1 = new THREE.Vector3(
+					v1.set(
 						Math.random() * 100 - 50,
 						Math.random() * 100 - 50,
 						Math.random() * 100 - 50
 					);
 
-					var v2 = new THREE.Vector3(
+					v2.set(
 						Math.random() * 100 - 50,
 						Math.random() * 100 - 50,
 						Math.random() * 100 - 50
@@ -117,19 +126,22 @@
 					v1.add( v );
 					v2.add( v );
 
-					var face = new THREE.Face3(
-						geometry.vertices.push( v0 ) - 1,
-						geometry.vertices.push( v1 ) - 1,
-						geometry.vertices.push( v2 ) - 1,
-						null,
-						new THREE.Color( Math.random() * 0xffffff )
-					);
+					color.setHex( Math.random() * 0xffffff );
+
+					// create a single triangle
+
+					vertices.push( v0.x, v0.y, v0.z );
+					vertices.push( v1.x, v1.y, v1.z );
+					vertices.push( v2.x, v2.y, v2.z );
 
-					geometry.faces.push( face );
+					colors.push( color.r, color.g, color.b );
+					colors.push( color.r, color.g, color.b );
+					colors.push( color.r, color.g, color.b );
 
 				}
 
-				geometry.computeFaceNormals();
+				geometry.addAttribute( 'position', new THREE.Float32BufferAttribute( vertices, 3 ) );
+				geometry.addAttribute( 'color', new THREE.Float32BufferAttribute( colors, 3 ) );
 
 				group = new THREE.Mesh( geometry, material );
 				group.scale.set( 2, 2, 2 );

+ 1 - 2
examples/webgl_lights_rectarealight.html

@@ -108,13 +108,12 @@
 				rectLight.position.set( 5, 5, 0 );
 				scene.add( rectLight );
 
-				var rectLightMesh = new THREE.Mesh( new THREE.PlaneBufferGeometry(), new THREE.MeshBasicMaterial() );
+				var rectLightMesh = new THREE.Mesh( new THREE.PlaneBufferGeometry(), new THREE.MeshBasicMaterial( { side: THREE.BackSide } ) );
 				rectLightMesh.scale.x = rectLight.width;
 				rectLightMesh.scale.y = rectLight.height;
 				rectLight.add( rectLightMesh );
 
 				var rectLightMeshBack = new THREE.Mesh( new THREE.PlaneBufferGeometry(), new THREE.MeshBasicMaterial( { color: 0x080808 } ) );
-				rectLightMeshBack.rotation.y = Math.PI;
 				rectLightMesh.add( rectLightMeshBack );
 
 				var geoFloor = new THREE.BoxBufferGeometry( 2000, 0.1, 2000 );

+ 2 - 2
examples/webgl_loader_nrrd.html

@@ -1,7 +1,7 @@
 <!DOCTYPE html>
 <html lang="en">
 	<head>
-		<title>three.js webgl - loaders - vtk loader</title>
+		<title>three.js webgl - loaders - NRRD loader</title>
 		<meta charset="utf-8">
 		<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
 		<style>
@@ -43,7 +43,7 @@
 	<body>
 		<div id="info">
 			<a href="http://threejs.org" target="_blank" rel="noopener">three.js</a> -
-			nrrd format loader test
+			NRRD format loader test
 		</div>
 		<div id="inset"></div>
 

+ 1 - 19
examples/webgl_materials.html

@@ -64,34 +64,18 @@
 				materials.push( new THREE.MeshPhongMaterial( { color: 0xdddddd, specular: 0x009900, shininess: 30, flatShading: true } ) );
 				materials.push( new THREE.MeshNormalMaterial() );
 				materials.push( new THREE.MeshBasicMaterial( { color: 0xffaa00, transparent: true, blending: THREE.AdditiveBlending } ) );
-				//materials.push( new THREE.MeshBasicMaterial( { color: 0xff0000, blending: THREE.SubtractiveBlending } ) );
-
 				materials.push( new THREE.MeshLambertMaterial( { color: 0xdddddd } ) );
 				materials.push( new THREE.MeshPhongMaterial( { color: 0xdddddd, specular: 0x009900, shininess: 30, map: texture, transparent: true } ) );
 				materials.push( new THREE.MeshNormalMaterial( { flatShading: true } ) );
 				materials.push( new THREE.MeshBasicMaterial( { color: 0xffaa00, wireframe: true } ) );
-
 				materials.push( new THREE.MeshDepthMaterial() );
-
 				materials.push( new THREE.MeshLambertMaterial( { color: 0x666666, emissive: 0xff0000 } ) );
 				materials.push( new THREE.MeshPhongMaterial( { color: 0x000000, specular: 0x666666, emissive: 0xff0000, shininess: 10, opacity: 0.9, transparent: true } ) );
-
 				materials.push( new THREE.MeshBasicMaterial( { map: texture, transparent: true } ) );
 
 				// Spheres geometry
 
-				var geometry = new THREE.SphereGeometry( 70, 32, 16 );
-
-				for ( var i = 0, l = geometry.faces.length; i < l; i ++ ) {
-
-					var face = geometry.faces[ i ];
-					face.materialIndex = Math.floor( Math.random() * materials.length );
-
-				}
-
-				geometry.sortFacesByMaterialIndex();
-
-				objects = [];
+				var geometry = new THREE.SphereBufferGeometry( 70, 32, 16 );
 
 				for ( var i = 0, l = materials.length; i < l; i ++ ) {
 
@@ -99,8 +83,6 @@
 
 				}
 
-				addMesh( geometry, materials );
-
 				// Lights
 
 				scene.add( new THREE.AmbientLight( 0x111111 ) );

+ 7 - 7
examples/webgl_materials_nodes.html

@@ -1073,7 +1073,7 @@
 
 						mtl.color = new THREE.ColorNode( 0x3399FF );
 						mtl.environment = color;
-						mtl.environmentAlpha = new THREE.Math1Node( fresnel, THREE.Math1Node.SAT );
+						mtl.environmentAlpha = new THREE.Math1Node( fresnel, THREE.Math1Node.SATURATE );
 
 						// GUI
 
@@ -1209,7 +1209,7 @@
 							THREE.OperatorNode.ADD
 						);
 
-						var clamp0at1 = new THREE.Math1Node( offsetClamp, THREE.Math1Node.SAT );
+						var clamp0at1 = new THREE.Math1Node( offsetClamp, THREE.Math1Node.SATURATE );
 
 						var blend = new THREE.Math3Node( top, bottom, clamp0at1, THREE.Math3Node.MIX );
 
@@ -1498,7 +1498,7 @@
 						var mask = new THREE.SwitchNode( worldNormal, 'y' );
 
 						// clamp0at1
-						mask = new THREE.Math1Node( mask, THREE.Math1Node.SAT );
+						mask = new THREE.Math1Node( mask, THREE.Math1Node.SATURATE );
 
 						var timeOffset = new THREE.OperatorNode(
 							time,
@@ -1531,7 +1531,7 @@
 						var voronoiColors = new THREE.Math3Node(
 							colorB,
 							colorA,
-							new THREE.Math1Node( voronoiIntensity, THREE.Math1Node.SAT ), // mix needs clamp
+							new THREE.Math1Node( voronoiIntensity, THREE.Math1Node.SATURATE ), // mix needs clamp
 							THREE.Math3Node.MIX
 						);
 
@@ -1780,7 +1780,7 @@
 							THREE.OperatorNode.MUL
 						);
 
-						var bloodArea = new THREE.Math1Node( wrappedLightColor, THREE.Math1Node.SAT );
+						var bloodArea = new THREE.Math1Node( wrappedLightColor, THREE.Math1Node.SATURATE );
 
 						var totalLight = new THREE.OperatorNode(
 							directLight,
@@ -1903,7 +1903,7 @@
 							THREE.Math3Node.SMOOTHSTEP
 						);
 
-						var innerContour = new THREE.Math1Node( new THREE.Math1Node( lineScaled, THREE.Math1Node.SAT ), THREE.Math1Node.INVERT );
+						var innerContour = new THREE.Math1Node( new THREE.Math1Node( lineScaled, THREE.Math1Node.SATURATE ), THREE.Math1Node.INVERT );
 
 						// APPLY
 
@@ -2550,7 +2550,7 @@
 							THREE.Math3Node.SMOOTHSTEP
 						);
 
-						var sssAlpha = new THREE.Math1Node( sss, THREE.Math1Node.SAT );
+						var sssAlpha = new THREE.Math1Node( sss, THREE.Math1Node.SATURATE );
 
 						var frontColor, backColor;
 

+ 2 - 1
rollup.config.js

@@ -162,11 +162,12 @@ function glsl() {
 
 			if ( /\.glsl.js$/.test( id ) === false ) return;
 
-			code = code.replace( /\`((.*|\n)*)\`/, function ( match, p1 ) {
+			code = code.replace( /\`((.*|\n|\r\n)*)\`/, function ( match, p1 ) {
 
 				return JSON.stringify(
 					p1
 						.trim()
+						.replace( /\r/g, '' )
 						.replace( /[ \t]*\/\/.*\n/g, '' ) // remove //
 						.replace( /[ \t]*\/\*[\s\S]*?\*\//g, '' ) // remove /* */
 						.replace( /\n{2,}/g, '\n' ) // # \n+ to \n

+ 2 - 0
src/audio/PositionalAudio.js

@@ -104,6 +104,8 @@ PositionalAudio.prototype = Object.assign( Object.create( Audio.prototype ), {
 
 			Object3D.prototype.updateMatrixWorld.call( this, force );
 
+			if ( this.isPlaying === false ) return;
+
 			var panner = this.panner;
 			this.matrixWorld.decompose( position, quaternion, scale );
 

+ 1 - 1
src/constants.js

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

+ 1 - 1
src/core/Object3D.js

@@ -332,7 +332,7 @@ Object3D.prototype = Object.assign( Object.create( EventDispatcher.prototype ),
 
 			position.setFromMatrixPosition( this.matrixWorld );
 
-			if ( this.isCamera ) {
+			if ( this.isCamera || this.isLight ) {
 
 				m1.lookAt( position, target, this.up );
 

+ 5 - 7
src/geometries/ShapeGeometry.js

@@ -121,17 +121,15 @@ function ShapeBufferGeometry( shapes, curveSegments ) {
 
 			shapeVertices = shapeVertices.reverse();
 
-			// also check if holes are in the opposite direction
-
-			for ( i = 0, l = shapeHoles.length; i < l; i ++ ) {
+		}
 
-				shapeHole = shapeHoles[ i ];
+		for ( i = 0, l = shapeHoles.length; i < l; i ++ ) {
 
-				if ( ShapeUtils.isClockWise( shapeHole ) === true ) {
+			shapeHole = shapeHoles[ i ];
 
-					shapeHoles[ i ] = shapeHole.reverse();
+			if ( ShapeUtils.isClockWise( shapeHole ) === true ) {
 
-				}
+				shapeHoles[ i ] = shapeHole.reverse();
 
 			}
 

+ 39 - 36
src/helpers/RectAreaLightHelper.js

@@ -2,79 +2,82 @@
  * @author abelnation / http://github.com/abelnation
  * @author Mugen87 / http://github.com/Mugen87
  * @author WestLangley / http://github.com/WestLangley
+ *
+ *  This helper must be added as a child of the light
  */
 
-import { Object3D } from '../core/Object3D.js';
 import { Line } from '../objects/Line.js';
+import { Mesh } from '../objects/Mesh.js';
 import { LineBasicMaterial } from '../materials/LineBasicMaterial.js';
+import { MeshBasicMaterial } from '../materials/MeshBasicMaterial.js';
+import { Float32BufferAttribute } from '../core/BufferAttribute.js';
 import { BufferGeometry } from '../core/BufferGeometry.js';
-import { BufferAttribute } from '../core/BufferAttribute.js';
 
 function RectAreaLightHelper( light, color ) {
 
-	Object3D.call( this );
+	this.type = 'RectAreaLightHelper';
 
 	this.light = light;
-	this.light.updateMatrixWorld();
 
-	this.matrix = light.matrixWorld;
-	this.matrixAutoUpdate = false;
+	this.color = color; // optional hardwired color for the helper
 
-	this.color = color;
+	var positions = [ 1, 1, 0, - 1, 1, 0, - 1, - 1, 0, 1, - 1, 0, 1, 1, 0 ];
+
+	var geometry = new BufferGeometry();
+	geometry.addAttribute( 'position', new Float32BufferAttribute( positions, 3 ) );
+	geometry.computeBoundingSphere();
 
 	var material = new LineBasicMaterial( { fog: false } );
 
-	var geometry = new BufferGeometry();
+	Line.call( this, geometry, material );
 
-	geometry.addAttribute( 'position', new BufferAttribute( new Float32Array( 5 * 3 ), 3 ) );
+	//
 
-	this.line = new Line( geometry, material );
-	this.add( this.line );
+	var positions2 = [ 1, 1, 0, - 1, 1, 0, - 1, - 1, 0, 1, 1, 0, - 1, - 1, 0, 1, - 1, 0 ];
 
+	var geometry2 = new BufferGeometry();
+	geometry2.addAttribute( 'position', new Float32BufferAttribute( positions2, 3 ) );
+	geometry2.computeBoundingSphere();
+
+	this.add( new Mesh( geometry2, new MeshBasicMaterial( { side: THREE.BackSide, fog: false } ) ) );
 
 	this.update();
 
 }
 
-RectAreaLightHelper.prototype = Object.create( Object3D.prototype );
+RectAreaLightHelper.prototype = Object.create( Line.prototype );
 RectAreaLightHelper.prototype.constructor = RectAreaLightHelper;
 
-RectAreaLightHelper.prototype.dispose = function () {
-
-	this.children[ 0 ].geometry.dispose();
-	this.children[ 0 ].material.dispose();
-
-};
-
 RectAreaLightHelper.prototype.update = function () {
 
-	// calculate new dimensions of the helper
+	this.scale.set( 0.5 * this.light.width, 0.5 * this.light.height, 1 );
 
-	var hx = this.light.width * 0.5;
-	var hy = this.light.height * 0.5;
+	if ( this.color !== undefined ) {
 
-	var position = this.line.geometry.attributes.position;
-	var array = position.array;
+		this.material.color.set( this.color );
+		this.children[ 0 ].material.color.set( this.color );
 
-	// update vertices
+	} else {
 
-	array[ 0 ] = hx; array[ 1 ] = - hy; array[ 2 ] = 0;
-	array[ 3 ] = hx; array[ 4 ] = hy; array[ 5 ] = 0;
-	array[ 6 ] = - hx; array[ 7 ] = hy; array[ 8 ] = 0;
-	array[ 9 ] = - hx; array[ 10 ] = - hy; array[ 11 ] = 0;
-	array[ 12 ] = hx; array[ 13 ] = - hy; array[ 14 ] = 0;
+		this.material.color.copy( this.light.color ).multiplyScalar( this.light.intensity );
 
-	position.needsUpdate = true;
+		// prevent hue shift
+		var c = this.material.color;
+		var max = Math.max( c.r, c.g, c.b );
+		if ( max > 1 ) c.multiplyScalar( 1 / max );
 
-	if ( this.color !== undefined ) {
+		this.children[ 0 ].material.color.copy( this.material.color );
 
-		this.line.material.color.set( this.color );
+	}
 
-	} else {
+};
 
-		this.line.material.color.copy( this.light.color );
+RectAreaLightHelper.prototype.dispose = function () {
 
-	}
+	this.geometry.dispose();
+	this.material.dispose();
+	this.children[ 0 ].geometry.dispose();
+	this.children[ 0 ].material.dispose();
 
 };
 

+ 5 - 0
src/loaders/ObjectLoader.js

@@ -663,6 +663,8 @@ Object.assign( ObjectLoader.prototype, {
 				}
 
 				if ( data.format !== undefined ) texture.format = data.format;
+				if ( data.type !== undefined ) texture.type = data.type;
+				if ( data.encoding !== undefined ) texture.encoding = data.encoding;
 
 				if ( data.minFilter !== undefined ) texture.minFilter = parseConstant( data.minFilter, TEXTURE_FILTER );
 				if ( data.magFilter !== undefined ) texture.magFilter = parseConstant( data.magFilter, TEXTURE_FILTER );
@@ -670,6 +672,9 @@ Object.assign( ObjectLoader.prototype, {
 
 				if ( data.flipY !== undefined ) texture.flipY = data.flipY;
 
+				if ( data.premultiplyAlpha !== undefined ) texture.premultiplyAlpha = data.premultiplyAlpha;
+				if ( data.unpackAlignment !== undefined ) texture.unpackAlignment = data.unpackAlignment;
+
 				textures[ data.uuid ] = texture;
 
 			}

+ 4 - 4
src/renderers/shaders/ShaderChunk/lights_physical_pars_fragment.glsl.js

@@ -36,10 +36,10 @@ float clearCoatDHRApprox( const in float roughness, const in float dotNL ) {
 		float roughness = material.specularRoughness;
 
 		vec3 rectCoords[ 4 ];
-		rectCoords[ 0 ] = lightPos - halfWidth - halfHeight; // counterclockwise
-		rectCoords[ 1 ] = lightPos + halfWidth - halfHeight;
-		rectCoords[ 2 ] = lightPos + halfWidth + halfHeight;
-		rectCoords[ 3 ] = lightPos - halfWidth + halfHeight;
+		rectCoords[ 0 ] = lightPos + halfWidth - halfHeight; // counterclockwise; light shines in local neg z direction
+		rectCoords[ 1 ] = lightPos - halfWidth - halfHeight;
+		rectCoords[ 2 ] = lightPos - halfWidth + halfHeight;
+		rectCoords[ 3 ] = lightPos + halfWidth + halfHeight;
 
 		vec2 uv = LTC_Uv( normal, viewDir, roughness );
 

+ 7 - 1
src/textures/Texture.js

@@ -161,11 +161,17 @@ Texture.prototype = Object.assign( Object.create( EventDispatcher.prototype ), {
 			wrap: [ this.wrapS, this.wrapT ],
 
 			format: this.format,
+			type: this.type,
+			encoding: this.encoding,
+
 			minFilter: this.minFilter,
 			magFilter: this.magFilter,
 			anisotropy: this.anisotropy,
 
-			flipY: this.flipY
+			flipY: this.flipY,
+
+			premultiplyAlpha: this.premultiplyAlpha,
+			unpackAlignment: this.unpackAlignment
 
 		};
 

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