Browse Source

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

Conflicts:
	src/renderers/WebGLRenderer.js
gero3 10 years ago
parent
commit
ca09c18f45
100 changed files with 4264 additions and 8331 deletions
  1. 124 505
      build/three.js
  2. 147 148
      build/three.min.js
  3. 1 2
      docs/api/constants/Materials.html
  4. 7 24
      docs/api/core/BufferGeometry.html
  5. 2 7
      docs/api/core/Face3.html
  6. 15 32
      docs/api/core/Geometry.html
  7. 0 59
      docs/api/extras/helpers/VertexTangentsHelper.html
  8. 0 93
      docs/api/lights/AreaLight.html
  9. 1 1
      docs/api/loaders/ColladaLoader.html
  10. 0 8
      docs/api/loaders/Loader.html
  11. 8 14
      docs/api/materials/MeshLambertMaterial.html
  12. 15 15
      docs/api/materials/MeshPhongMaterial.html
  13. 19 36
      docs/api/math/Matrix3.html
  14. 11 11
      docs/api/math/Matrix4.html
  15. 0 2
      docs/list.js
  16. 99 100
      docs/scenes/js/geometry.js
  17. 0 1
      docs/scenes/js/material.js
  18. 2 0
      editor/index.html
  19. 6 0
      editor/js/Loader.js
  20. 28 0
      editor/js/Menubar.Add.js
  21. 11 0
      editor/js/Sidebar.Geometry.BufferGeometry.js
  22. 0 20
      editor/js/Sidebar.Geometry.Modifiers.js
  23. 103 0
      editor/js/Sidebar.Geometry.TeapotBufferGeometry.js
  24. 13 0
      editor/js/Sidebar.Geometry.js
  25. 49 2
      editor/js/Sidebar.Material.js
  26. 5 5
      editor/js/Viewport.Info.js
  27. 4 92
      editor/js/libs/tern-threejs/threejs.js
  28. 3 6
      examples/index.html
  29. 0 170
      examples/js/AudioObject.js
  30. 187 0
      examples/js/BufferGeometryUtils.js
  31. 0 1104
      examples/js/ShaderDeferred.js
  32. 52 59
      examples/js/ShaderSkin.js
  33. 28 15
      examples/js/WaterShader.js
  34. 5 3
      examples/js/controls/TransformControls.js
  35. 22 23
      examples/js/geometries/DecalGeometry.js
  36. 751 0
      examples/js/geometries/TeapotBufferGeometry.js
  37. 0 2
      examples/js/loaders/AssimpJSONLoader.js
  38. 0 2
      examples/js/loaders/BinaryLoader.js
  39. 23 15
      examples/js/loaders/DDSLoader.js
  40. 1 27
      examples/js/loaders/deprecated/SceneLoader.js
  41. 506 329
      examples/js/loaders/sea3d/SEA3D.js
  42. 11 12
      examples/js/loaders/sea3d/SEA3DDeflate.js
  43. 25 19
      examples/js/loaders/sea3d/SEA3DLZMA.js
  44. 0 13
      examples/js/loaders/sea3d/SEA3DLZMA_LZIP.js
  45. 760 1087
      examples/js/loaders/sea3d/SEA3DLoader.js
  46. 0 1209
      examples/js/renderers/WebGLDeferredRenderer.js
  47. 0 515
      examples/js/shaders/NormalDisplacementShader.js
  48. 6 7
      examples/misc_controls_fly.html
  49. 0 43
      examples/models/animated/elderlyWalk.js
  50. BIN
      examples/models/sea3d/flag.sea
  51. BIN
      examples/models/sea3d/flag.tjs.sea
  52. BIN
      examples/models/sea3d/keyframe.tjs.sea
  53. BIN
      examples/models/sea3d/mascot.tjs.sea
  54. BIN
      examples/models/sea3d/morph.tjs.sea
  55. BIN
      examples/models/sea3d/robot.tjs.sea
  56. BIN
      examples/models/sea3d/skin.tjs.sea
  57. BIN
      examples/models/sea3d/sound.tjs.sea
  58. 0 43
      examples/models/skinned/human_walk_0_female.js
  59. BIN
      examples/obj/box/box.bin
  60. 0 29
      examples/obj/box/box.js
  61. 0 7
      examples/obj/ninja/.htaccess
  62. 393 0
      examples/webgl_geometry_teapot.html
  63. 0 2
      examples/webgl_loader_ctm.html
  64. 5 7
      examples/webgl_loader_sea3d.html
  65. 3 7
      examples/webgl_loader_sea3d_hierarchy.html
  66. 4 6
      examples/webgl_loader_sea3d_keyframe.html
  67. 5 7
      examples/webgl_loader_sea3d_morph.html
  68. 5 6
      examples/webgl_loader_sea3d_skinning.html
  69. 2 4
      examples/webgl_loader_sea3d_sound.html
  70. 246 0
      examples/webgl_materials_displacementmap.html
  71. 0 325
      examples/webgl_materials_normaldisplacementmap.html
  72. 0 2
      examples/webgl_materials_normalmap.html
  73. 15 5
      examples/webgl_materials_skin.html
  74. 0 2
      examples/webgl_postprocessing_advanced.html
  75. 377 0
      examples/webgl_raycast_texture.html
  76. 1 9
      examples/webgl_sandbox.html
  77. 3 1
      examples/webgl_terrain_dynamic.html
  78. 0 479
      examples/webgldeferred_animation.html
  79. 0 388
      examples/webgldeferred_arealights.html
  80. 0 429
      examples/webgldeferred_pointlights.html
  81. 27 28
      src/Three.js
  82. 18 206
      src/core/BufferGeometry.js
  83. 0 34
      src/core/DirectGeometry.js
  84. 0 8
      src/core/Face3.js
  85. 1 118
      src/core/Geometry.js
  86. 1 1
      src/extras/SceneUtils.js
  87. 1 90
      src/extras/geometries/SphereGeometry.js
  88. 0 144
      src/extras/helpers/VertexTangentsHelper.js
  89. 0 56
      src/lights/AreaLight.js
  90. 9 0
      src/loaders/BufferGeometryLoader.js
  91. 4 6
      src/loaders/ImageLoader.js
  92. 20 6
      src/loaders/JSONLoader.js
  93. 0 14
      src/loaders/Loader.js
  94. 11 0
      src/loaders/LoadingManager.js
  95. 0 1
      src/loaders/MaterialLoader.js
  96. 41 13
      src/loaders/ObjectLoader.js
  97. 4 6
      src/loaders/XHRLoader.js
  98. 6 0
      src/materials/Material.js
  99. 0 5
      src/materials/MeshLambertMaterial.js
  100. 12 0
      src/materials/MeshPhongMaterial.js

File diff suppressed because it is too large
+ 124 - 505
build/three.js


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


+ 1 - 2
docs/api/constants/Materials.html

@@ -19,7 +19,6 @@
 
 		<h2>Shading</h2>
 		<div>
-		THREE.NoShading<br />
 		THREE.FlatShading<br />
 		THREE.SmoothShading
 		</div>
@@ -40,7 +39,7 @@
 		THREE.MultiplyBlending<br />
 		THREE.CustomBlending
 		</div>
-	
+
 		<h2>Source</h2>
 
 		[link:https://github.com/mrdoob/three.js/blob/master/src/Three.js src/Three.js]

+ 7 - 24
docs/api/core/BufferGeometry.html

@@ -86,11 +86,6 @@
 		Set by [page:.fromGeometry]().
 		</div>
 
-		<h4>[page:BufferAttribute tangent] (itemSize: 3)</h4>
-		<div>
-		Stores the x, y, and z components of the tangent vector of each vertex in this geometry. Set by [page:.computeTangents]().
-		</div>
-
 		<h4>[page:BufferAttribute index] (itemSize: 3)</h4>
 		Allows for vertices to be re-used across multiple triangles; this is called using "indexed triangles," and works much the same as it does in [page:Geometry]: each triangle is associated with the index of three vertices. This attribute therefore stores the index of each vertex for each triangular face.
 
@@ -158,11 +153,6 @@
 		Morph vertices match number and order of primary vertices.
 		</div>
 
-		<h3>[property:boolean hasTangents]</h3>
-		<div>
-		True if BufferGeometry has tangents. Set in [page:.computeTangents].
-		</div>
-
 		<h2>Methods</h2>
 
 		<h3>[page:EventDispatcher EventDispatcher] methods are available on this class.</h3>
@@ -178,7 +168,7 @@
 		<div>
 		Adds a draw call to this geometry; see the [page:BufferGeometry.drawcalls drawcalls] property for details.
 		</div>
-    
+
 		<h3>[method:null clearDrawCalls]( )</h3>
 		<div>
 		Clears all draw calls.
@@ -188,12 +178,12 @@
 		<div>
 		Bakes matrix transform directly into vertex coordinates.
 		</div>
-    
+
 		<h3>[method:null center] ()</h3>
 		<div>
 		Center the geometry based on the bounding box.
 		</div>
-    
+
 		<h3>[method:BufferGeometry rotateX] ( [page:Float radians] )</h3>
 		<div>
 		Rotate the geometry about the X axis. This is typically done as a one time operation, and not during a loop
@@ -243,13 +233,6 @@
 		Computes vertex normals by averaging face normals.<br />
 		</div>
 
-		<h3>[method:null computeTangents]()</h3>
-		<div>
-		Computes vertex tangents.<br />
-		Based on [link:http://www.terathon.com/code/tangent.html]<br />
-		Geometry must have vertex [page:UV UVs] (layer 0 will be used).
-		</div>
-
 		<h3>[method:null computeBoundingBox]()</h3>
 		<div>
 		Computes bounding box of the geometry, updating [page:Geometry Geometry.boundingBox] attribute.<br />
@@ -306,18 +289,18 @@
 		<div>
 		Returns a raw object representation of the BufferGeometry.
 		</div>
-		
+
 		<h3>[method:BufferGeometry clone]()</h3>
 		<div>
 		Creates a clone of this BufferGeometry.
 		</div>
-		
+
 		<h3>[method:BufferGeometry copy]( [page:BufferGeometry bufferGeometry] )</h3>
 		<div>
 		Copies another BufferGeometry to this BufferGeometry.
 		</div>
-		
-		
+
+
 
 		<h2>Source</h2>
 

+ 2 - 7
docs/api/core/Face3.html

@@ -71,11 +71,6 @@
 		Array of 3 vertex colors.
 		</div>
 
-		<h3>[property:Array vertexTangents]</h3>
-		<div>
-		Array of 3 vertex tangents.
-		</div>
-
 
 		<h3>[property:Integer materialIndex]</h3>
 		<div>
@@ -88,8 +83,8 @@
 		<div>
 		Creates a new clone of the Face3 object.
 		</div>
-		
-		
+
+
 		<h2>Source</h2>
 
 		[link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js]

+ 15 - 32
docs/api/core/Geometry.html

@@ -117,10 +117,10 @@
 		// e.g.
 		geometry.skinIndices[15] = new THREE.Vector4(   0,   5,   9, 0 );
 		geometry.skinWeights[15] = new THREE.Vector4( 0.2, 0.5, 0.3, 0 );
-		
+
 		// corresponds with the following vertex
 		geometry.vertices[15];
-		
+
 		// these bones will be used like so:
 		skeleton.bones[0]; // weight of 0.2
 		skeleton.bones[5]; // weight of 0.5
@@ -141,48 +141,38 @@
 		<code>{ radius: float }</code>
 		</div>
 
-		<h3>[property:Boolean hasTangents]</h3>
-		<div>
-		True if geometry has tangents. Set in [page:Geometry Geometry.computeTangents].
-		</div>
-
 		<h3>[property:Boolean dynamic]</h3>
 		<div>
 		Set to *true* if attribute buffers will need to change in runtime (using "dirty" flags).<br/>
 		Unless set to true internal typed arrays corresponding to buffers will be deleted once sent to GPU.<br/>
 		Defaults to true.
 		</div>
-		
+
 		<h3>[property:Boolean verticesNeedUpdate]</h3>
 		<div>
 		Set to *true* if the vertices array has been updated.
 		</div>
-		
+
 		<h3>[property:Boolean elementsNeedUpdate]</h3>
 		<div>
 		Set to *true* if the faces array has been updated.
 		</div>
-		
+
 		<h3>[property:Boolean uvsNeedUpdate]</h3>
 		<div>
 		Set to *true* if the uvs array has been updated.
 		</div>
-		
+
 		<h3>[property:Boolean normalsNeedUpdate]</h3>
 		<div>
 		Set to *true* if the normals array has been updated.
 		</div>
-		
-		<h3>[property:Boolean tangentsNeedUpdate]</h3>
-		<div>
-		Set to *true* if the tangents in the faces has been updated.
-		</div>
-		
+
 		<h3>[property:Boolean colorsNeedUpdate]</h3>
 		<div>
 		Set to *true* if the colors array has been updated.
 		</div>
-		
+
 		<h3>[property:Boolean lineDistancesNeedUpdate]</h3>
 		<div>
 		Set to *true* if the linedistances array has been updated.
@@ -193,10 +183,10 @@
 		An array containing distances between vertices for Line geometries.
 		This is required for LinePieces/LineDashedMaterial to render correctly.
 		Line distances can also be generated with computeLineDistances.
-		</div> 
+		</div>
 
 		<h2>Methods</h2>
-		
+
 		<h3>[page:EventDispatcher EventDispatcher] methods are available on this class.</h3>
 
 		<h3>[method:null applyMatrix]( [page:Matrix4 matrix] )</h3>
@@ -208,7 +198,7 @@
 		<div>
 		Center the geometry based on the bounding box.
 		</div>
-    
+
 		<h3>[method:Geometry rotateX] ( [page:Float radians] )</h3>
 		<div>
 		Rotate the geometry about the X axis. This is typically done as a one time operation, and not during a loop
@@ -264,13 +254,6 @@
 		Computes morph normals.
 		</div>
 
-		<h3>[method:null computeTangents]()</h3>
-		<div>
-		Computes vertex tangents.<br />
-		Based on [link:http://www.terathon.com/code/tangent.html]<br />
-		Geometry must have vertex [page:UV UVs] (layer 0 will be used).
-		</div>
-
 		<h3>[method:null computeBoundingBox]()</h3>
 		<div>
 		Computes bounding box of the geometry, updating [page:Geometry Geometry.boundingBox] attribute.
@@ -280,7 +263,7 @@
 		<div>
 		Computes bounding sphere of the geometry, updating [page:Geometry Geometry.boundingSphere] attribute.
 		</div>
-		
+
 		<div>Neither bounding boxes or bounding spheres are computed by default. They need to be explicitly computed, otherwise they are *null*.</div>
 
 		<h3>[method:null merge]( [page:Geometry geometry], [page:Matrix4 matrix], [page:Integer materialIndexOffset] )</h3>
@@ -297,16 +280,16 @@
 		Normalize the geometry. <br />
 		Make the geometry centered and has a bounding sphere whose raidus equals to 1.0.
 		</div>
-		
+
 		<h3>[method:Geometry clone]()</h3>
 		<div>
 		Creates a new clone of the Geometry.
 		</div>
-		
+
 		<h3>[method:null dispose]()</h3>
 		<div>
 		Removes The object from memory. <br />
-		Don't forget to call this method when you remove a geometry because it can cause memory leaks. 
+		Don't forget to call this method when you remove a geometry because it can cause memory leaks.
 		</div>
 
 		<h3>[method:null computeLineDistances]()</h3>

+ 0 - 59
docs/api/extras/helpers/VertexTangentsHelper.html

@@ -1,59 +0,0 @@
-<!DOCTYPE html>
-<html lang="en">
-	<head>
-		<meta charset="utf-8" />
-		<base href="../../../" />
-		<script src="list.js"></script>
-		<script src="page.js"></script>
-		<link type="text/css" rel="stylesheet" href="page.css" />
-	</head>
-	<body>
-		[page:Line] &rarr;
-
-		<h1>[name]</h1>
-
-		<div class="desc">Renders [page:ArrowHelper arrows] to visualize an object's vertex tangent vectors. Requires that tangents have been specified in a [page:BufferAttribute custom attribute] or have been computed using [page:Geometry.computeTangents computeTangents]. </div>
-
-		<h2>Example</h2>
-
-		<code>
-		geometry = new THREE.BoxGeometry( 10, 10, 10, 2, 2, 2 );
-		material = new THREE.MeshBasicMaterial( { color: 0xff0000 } );
-		object = new THREE.Mesh( geometry, material );
-
-		edges = new THREE.VertexTangentsHelper( object, 2, 0x00ff00, 1 );
-
-		scene.add( object );
-		scene.add( edges );
-		</code>
-
-		<h2>Constructor</h2>
-
-
-		<h3>[name]( [page:Object3D object], [page:Number size], [page:Color color], [page:Number linewidth] )</h3>
-		<div>object -- object for which to render vertex tangents
-		size -- size (length) of the arrows
-		color -- color of the arrows
-		linewidth -- width of the arrow lines
-		</div>
-
-
-		<h2>Properties</h2>
-
-		<h3>[property:Object3D object]</h3>
-		<div>
-		The attached object
-		</div>
-
-
-		<h2>Methods</h2>
-
-
-		<h3>[method:null update]()</h3>
-		<div>Updates the vertex tangent preview arrows based on the new position and tangents of the object.</div>
-
-		<h2>Source</h2>
-
-		[link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js]
-	</body>
-</html>

+ 0 - 93
docs/api/lights/AreaLight.html

@@ -1,93 +0,0 @@
-<!DOCTYPE html>
-<html lang="en">
-	<head>
-		<meta charset="utf-8" />
-		<base href="../../" />
-		<script src="list.js"></script>
-		<script src="page.js"></script>
-		<link type="text/css" rel="stylesheet" href="page.css" />
-	</head>
-	<body>
-        [page:Object3D] &rarr; [page:Light] &rarr;
-
-		<h1>[name]</h1>
-
-		<div class="desc">This illuminates the scene from a complete surface. This light only works in the [page:WebGLDeferredRenderer deferredrenderer]. </div>
-
-
-		<h2>Example</h2>
-		<h2>Example</h2>
-
-		<div>[example:webgldeferred_arealights arealights ]</div>
-
-		<code>areaLight1 = new THREE.AreaLight( 0xffffff, 1 );
-areaLight1.position.set( 0.0001, 10.0001, -18.5001 );
-areaLight1.rotation.set( -0.74719, 0.0001, 0.0001 );
-areaLight1.width = 10;
-areaLight1.height = 1;
-
-scene.add( areaLight1 );</code>
-
-		<h2>Constructor</h2>
-
-
-		<h3>[name]( [page:Integer hex], [page:Float intensity])</h3>
-		<div>
-		[page:Integer hex] — Numeric value of the RGB component of the color.<br />
-		[page:Float intensity] — Numeric value of the light's strength/intensity.
-		</div>
-		<div>
-		This creates a arealight with color.
-		</div>
-
-
-		<h2>Properties</h2>
-
-
-
-		<h3>[property:Vector3 right]</h3>
-		<div>
-		Sets or gets an unit vector that indicates the right side of the light. This is calculated in local space.
-		</div>
-
-		<h3>[property:Vector3 normal]</h3>
-		<div>
-		Sets or gets an unit vectorSets or gets an unit vector that indicates the right side of the light. This is calculated in local space.
-		</div>
-
-		<h3>[property:number height]</h3>
-		<div>
-		Sets or gets the height of the illuminating plane.
-		</div>
-
-		<h3>[property:number width]</h3>
-		<div>
-		Sets or gets the width of the illuminating plane.
-		</div>
-
-		<h3>[property:Float intensity]</h3>
-		<div>
-		Light's intensity.<br />
-		Default — *1.0*.
-		</div>
-
-		<h3>[property:number constantAttenuation]</h3>
-		<div>
-		Sets or gets the attenuation of the light in constant space. This is independant of the distance of the light.
-		</div>
-
-		<h3>[property:number linearAttenuation]</h3>
-		<div>
-		Sets or gets the attenuation of the light in linear space. This increases the attenuation linearly with the distance from the light.
-		</div>
-
-		<h3>[property:number quadraticAttenuation]</h3>
-		<div>
-		Sets or gets the attenuation of the light in quadratic space. This increases the attenuation quadraticly with the distance from the light.
-		</div>
-
-		<h2>Source</h2>
-
-		[link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js]
-	</body>
-</html>

+ 1 - 1
docs/api/loaders/ColladaLoader.html

@@ -67,7 +67,7 @@
 		</div>
 		<div>
 		Set the .[page:Integer shading] property on the resource's materials.<br />
-		Options are [page:Materials THREE.SmoothShading], [page:Materials THREE.FlatShading], [page:Materials THREE.NoShading].
+		Options are [page:Materials THREE.SmoothShading], [page:Materials THREE.FlatShading].
 		</div>
 
 		<h3>[method:null applySkin]( [page:Geometry geometry], [page:Object instanceCtrl], [page:Integer frame] )</h3>

+ 0 - 8
docs/api/loaders/Loader.html

@@ -43,14 +43,6 @@
 
 		<h2>Methods</h2>
 
-		<h3>[method:Boolean needsTangents]( [page:Array materials] )</h3>
-		<div>
-		[page:Array materials] — an array of [page:Material]
-		</div>
-		<div>
-		Checks if the loaded object needs tangents based on its materials.
-		</div>
-
 		<h3>[method:Material createMaterial]( [page:object m], [page:string texturePath] )</h3>
 		<div>
 		[page:Object m] — The parameters to create the material. <br />

+ 8 - 14
docs/api/materials/MeshLambertMaterial.html

@@ -13,7 +13,7 @@
 		<h1>[name]</h1>
 
 		<div class="desc">A material for non-shiny (Lambertian) surfaces, evaluated per vertex.</div>
-		
+
 		<iframe src='scenes/material-browser.html#MeshLambertMaterial'></iframe>
 
 		<h2>Constructor</h2>
@@ -30,7 +30,6 @@
 		alphaMap — Set alpha map. Default is null.<br />
 		envMap — Set env map. Default is null.<br />
 		fog — Define whether the material color is affected by global fog settings. Default is false.<br />
-		shading — How the triangles of a curved surface are rendered. Default is [page:Materials THREE.SmoothShading].<br/>
 		wireframe — Render geometry as wireframe. Default is false (i.e. render as smooth shaded).<br/>
 		wireframeLinewidth — Controls wireframe thickness. Default is 1.<br/>
 		wireframeLinecap — Define appearance of line ends. Default is 'round'.<br />
@@ -68,12 +67,12 @@
 		<div>Set env map. Default is null.</div>
 
 		<h3>[property:Integer combine]</h3>
-		<div>How to combine the result of the surface's color with the environment map, if any.</div> 
-		 
+		<div>How to combine the result of the surface's color with the environment map, if any.</div>
+
 		<div>Options are [page:Textures THREE.Multiply] (default), [page:Textures THREE.MixOperation], [page:Textures THREE.AddOperation]. If mix is chosen, the reflectivity is used to blend between the two colors.</div>
-		 
+
 		<h3>[property:Float reflectivity]</h3>
-		<div>How much the environment map affects the surface; also see "combine".</div> 
+		<div>How much the environment map affects the surface; also see "combine".</div>
 
 		<h3>[property:Float refractionRatio]</h3>
 		<div>The index of refraction for an environment map using [page:Textures THREE.CubeRefractionMapping]. Default is *0.98*.</div>
@@ -82,14 +81,9 @@
 		<div>Define whether the material color is affected by global fog settings. Default is *true*.</div>
 		<div>This setting might not have any effect when used with certain renderers. For example, it is ignored with the [page:CanvasRenderer Canvas] renderer, but does work with the [page:WebGLRenderer WebGL] renderer.</div>
 
-		<h3>[property:Integer shading]</h3>
-		<div>How the triangles of a curved surface are rendered: as a smooth surface, as flat separate facets, or no shading at all.</div>
-
-		<div>Options are [page:Materials THREE.SmoothShading] (default), [page:Materials THREE.FlatShading], [page:Materials THREE.NoShading].</div>
-		
 		<h3>[property:Boolean wireframe]</h3>
 		<div>Whether the triangles' edges are displayed instead of surfaces. Default is *false*.</div>
-		
+
 		<h3>[property:Float wireframeLinewidth]</h3>
 		<div>Line thickness for wireframe mode. Default is *1.0*.</div>
 		<div>Due to limitations in the <a href="https://code.google.com/p/angleproject/" target="_blank">ANGLE layer</a>, on Windows platforms linewidth will always be 1 regardless of the set value.</div>
@@ -108,9 +102,9 @@
 
 		<h3>[property:Boolean skinning]</h3>
 		<div>Define whether the material uses skinning. Default is *false*.</div>
-	
+
 		<h3>[property:Boolean morphTargets]</h3>
-		<div>Define whether the material uses morphTargets. Default is *false*.</div>	
+		<div>Define whether the material uses morphTargets. Default is *false*.</div>
 
 		<h3>[property:boolean morphNormals]</h3>
 		<div>

+ 15 - 15
docs/api/materials/MeshPhongMaterial.html

@@ -45,7 +45,7 @@
 		<div>
 		Example:<br>
 		materials.push( new THREE.MeshPhongMaterial( { color: 0xdddddd, specular: 0x009900, shininess: 30, shading: THREE.FlatShading } ) );
-	
+
 		</div>
 
 
@@ -75,7 +75,7 @@
 			If set to true the shader multiplies the specular highlight by the underlying color of the object, making
 			it appear to be more metal-like and darker. If set to false the specular highlight is added ontop of the
 			underlying colors.
-		</div> 
+		</div>
 
 		<h3>[property:Texture map]</h3>
 		<div>Set color texture map. Default is null. The texture map color is modulated by the diffuse color.</div>
@@ -95,7 +95,7 @@
 			Bump doesn't actually affect the geometry of the object, only the lighting. If a normal map is defined this will
 			be ignored.
 		</div>
-		
+
 		<h3>[property:Float bumpScale]</h3>
 		<div>
 			How much the bump map affects the material. Typical ranges are 0-1. Default is 1.
@@ -106,11 +106,11 @@
 			The texture to create a normal map. The RGB values affect the surface normal for each pixel fragment and change
 			the way the color is lit. Normal maps do not change the actual shape of the surface, only the lighting.
 		</div>
-		
+
 		<h3>[property:Vector2 normalScale]</h3>
 		<div>
 			How much the normal map affects the material. Typical ranges are 0-1. Default is (1,1).
-		</div> 
+		</div>
 
 		<h3>[property:Texture specularMap]</h3>
 		<div>The specular map value affects both how much the specular surface highlight contributes and how much of the environment map affects the surface. Default is null.</div>
@@ -121,14 +121,14 @@
 
 		<h3>[property:TextureCube envMap]</h3>
 		<div>Set env map. Default is null.</div>
-		
+
 		<h3>[property:Integer combine]</h3>
-		<div>How to combine the result of the surface's color with the environment map, if any.</div> 
-		 
+		<div>How to combine the result of the surface's color with the environment map, if any.</div>
+
 		<div>Options are [page:Textures THREE.MultiplyOperation] (default), [page:Textures THREE.MixOperation], [page:Textures THREE.AddOperation]. If mix is chosen, the reflectivity is used to blend between the two colors.</div>
-		 
+
 		<h3>[property:Float reflectivity]</h3>
-		<div>How much the environment map affects the surface; also see "combine".</div> 
+		<div>How much the environment map affects the surface; also see "combine".</div>
 
 		<h3>[property:Float refractionRatio]</h3>
 		<div>The index of refraction for an environment map using [page:Textures THREE.CubeRefractionMapping]. Default is *0.98*.</div>
@@ -140,11 +140,11 @@
 		<h3>[property:Integer shading]</h3>
 		<div>How the triangles of a curved surface are rendered: as a smooth surface, as flat separate facets, or no shading at all.</div>
 
-		<div>Options are [page:Materials THREE.SmoothShading] (default), [page:Materials THREE.FlatShading], [page:Materials THREE.NoShading].</div>
-		
+		<div>Options are [page:Materials THREE.SmoothShading] (default), [page:Materials THREE.FlatShading].</div>
+
 		<h3>[property:Boolean wireframe]</h3>
 		<div>Whether the triangles' edges are displayed instead of surfaces. Default is *false*.</div>
-		
+
 		<h3>[property:Float wireframeLinewidth]</h3>
 		<div>Line thickness for wireframe mode. Default is *1.0*.</div>
 		<div>Due to limitations in the <a href="https://code.google.com/p/angleproject/" target="_blank">ANGLE layer</a>, on Windows platforms linewidth will always be 1 regardless of the set value.</div>
@@ -163,9 +163,9 @@
 
 		<h3>[property:Boolean skinning]</h3>
 		<div>Define whether the material uses skinning. Default is *false*.</div>
-	
+
 		<h3>[property:Boolean morphTargets]</h3>
-		<div>Define whether the material uses morphTargets. Default is *false*.</div>	
+		<div>Define whether the material uses morphTargets. Default is *false*.</div>
 
 		<h3>[property:boolean morphNormals]</h3>
 		<div>

+ 19 - 36
docs/api/math/Matrix3.html

@@ -16,26 +16,9 @@
 		<h2>Constructor</h2>
 
 
-		<h3>[name]([page:Float n11], [page:Float n12], [page:Float n13], [page:Float n21], [page:Float n22], [page:Float n23], [page:Float n31], [page:Float n32], [page:Float n33])</h3>
+		<h3>[name]()</h3>
 		<div>
-		n11 -- [page:Float] <br />
-		n12 -- [page:Float] <br />
-		n13 -- [page:Float] <br />
-		n21 -- [page:Float] <br />
-		n22 -- [page:Float] <br />
-		n23 -- [page:Float] <br />
-		n31 -- [page:Float] <br />
-		n32 -- [page:Float] <br />
-		n33 -- [page:Float]
-		</div>
-		<div>
-		Initialize the 3x3 matrix with a row-major sequence of values.<br/><br/>
-		
-		n11, n12, n13,<br/>
-		n21, n22, n23,<br/>
-		n31, n32, n33<br/><br/>
-		
-		If no values are sent the matrix will be initialized as an identity matrix.
+		Creates and initializes the 3x3 matrix to the identity matrix.
 		</div>
 
 
@@ -44,7 +27,7 @@
 
 		<h3>[property:Float32Array elements]</h3>
 		<div>
-		Float32Array with column-major matrix values.
+		A column-major list of matrix values.
 		</div>
 
 
@@ -60,13 +43,13 @@
 		array -- [page:Array] <br />
 		</div>
 		<div>
-		Transposes this matrix into the supplied array, and returns itself.
+		Transposes this matrix into the supplied array, and returns itself unchanged.
 		</div>
 
 
 		<h3>[method:Float determinant]()</h3>
 		<div>
-		Returns the matrix's determinant.
+		Computes and returns the determinant of this matrix.
 		</div>
 
 		<h3>[method:Matrix3 set]([page:Float n11], [page:Float n12], [page:Float n13], [page:Float n21], [page:Float n22], [page:Float n23], [page:Float n31], [page:Float n32], [page:Float n33]) [page:Matrix3 this]</h3>
@@ -82,15 +65,15 @@
 		n33 -- [page:Float]
 		</div>
 		<div>
-		Set the 3x3 matrix values to the given row-major sequence of values.
+		Sets the 3x3 matrix values to the given row-major sequence of values.
 		</div>
 
-		<h3>[method:Matrix3 multiplyScalar]([page:Float scalar]) [page:Matrix3 this]</h3>
+		<h3>[method:Matrix3 multiplyScalar]([page:Float s]) [page:Matrix3 this]</h3>
 		<div>
 		scalar -- [page:Float]
 		</div>
 		<div>
-		Multiply every component of the matrix by a scalar value.
+		Multiplies every component of the matrix by the scalar value *s*.
 		</div>
 
 		<h3>[method:Array applyToVector3Array]([page:Array array])</h3>
@@ -98,42 +81,42 @@
 		array -- An array in the form [vector1x, vector1y, vector1z, vector2x, vector2y, vector2z, ...]
 		</div>
 		<div>
-		Multiply (apply) this matrix to every vector3 in the array.
+		Multiplies (applies) this matrix to every vector3 in the array.
 		</div>
 
-		<h3>[method:Matrix3 getNormalMatrix]([page:Matrix4 matrix4]) [page:Matrix3 this]</h3>
+		<h3>[method:Matrix3 getNormalMatrix]([page:Matrix4 m]) [page:Matrix3 this]</h3>
 		<div>
-		matrix4 -- [page:Matrix4]
+		m -- [page:Matrix4]
 		</div>
 		<div>
-		Set this matrix as the normal matrix of the passed [page:Matrix4 matrix4]. The normal matrix is the inverse transpose of the matrix.
+		Sets this matrix as the normal matrix (upper left 3x3)of the passed [page:Matrix4 matrix4]. The normal matrix is the inverse transpose of the matrix *m*.
 		</div>
 
-		<h3>[method:Matrix3 getInverse]([page:Matrix4 matrix4], [page:Boolean throwOnInvertible]) [page:Matrix3 this]</h3>
+		<h3>[method:Matrix3 getInverse]([page:Matrix4 m], [page:Boolean throwOnInvertible]) [page:Matrix3 this]</h3>
 		<div>
-		matrix4 -- [page:Matrix4] <br />
+		m -- [page:Matrix4]<br />
 		throwOnInvertible -- [Page:Boolean] If true, throw an error if the matrix is invertible.
 		</div>
 		<div>
 		Set this matrix to the inverse of the passed matrix.
 		</div>
 
-		<h3>[method:Matrix3 copy]([page:Matrix3 matrix]) [page:Matrix3 this]</h3>
+		<h3>[method:Matrix3 copy]([page:Matrix3 m]) [page:Matrix3 this]</h3>
 		<div>
-		matrix -- [page:Matrix3]
+		m -- [page:Matrix4]
 		</div>
 		<div>
-		Copy the values of the passed matrix.
+		Copies the values of matrix *m* into this matrix.
 		</div>
 
 		<h3>[method:Matrix3 clone]()</h3>
 		<div>
-		Create a copy of the matrix.
+		Creates a copy of this matrix.
 		</div>
 
 		<h3>[method:Matrix3 identity]() [page:Matrix3 this]</h3>
 		<div>
-		Set as an identity matrix.<br/><br/>
+		Resets this matrix to identity.<br/><br/>
 		
 		1, 0, 0<br/>
 		0, 1, 0<br/>

+ 11 - 11
docs/api/math/Matrix4.html

@@ -39,10 +39,10 @@
 		<h2>Constructor</h2>
 
 
-		<h3>[name]( [page:Float n11], [page:Float n12], [page:Float n13], [page:Float n14], [page:Float n21], [page:Float n22], [page:Float n23], [page:Float n24], [page:Float n31], [page:Float n32], [page:Float n33], [page:Float n34], [page:Float n41], [page:Float n42], [page:Float n43], [page:Float n44] )</h3>
+		<h3>[name]()</h3>
 
 		<div>
-		Initialises the matrix with the supplied row-major values n11..n44, or just creates an identity matrix if no values are passed.
+		Creates and initializes the matrix to the identity matrix.
 		</div>
 
 		<h2>Properties</h2>
@@ -64,7 +64,7 @@
 
 		<h3>[method:Matrix4 copy]( [page:Matrix4 m] ) [page:Matrix4 this]</h3>
 		<div>
-		Copies a matrix *m* into this matrix.
+		Copies the values of matrix *m* into this matrix.
 		</div>
 
 		<h3>[method:Matrix4 copyPosition]( [page:Matrix4 m] ) [page:Matrix4 this]</h3>
@@ -72,12 +72,12 @@
 		Copies the translation component of the supplied matrix *m* into this matrix translation component.
 		</div>
 
-		<h3>[method:Matrix4 makeBasis]( [page:Vector3 xAxis], [page:Vector3 yAxis], [page:Vector3 zAxis] ) [page:Matrix4 this]</h3>
+		<h3>[method:Matrix4 makeBasis]( [page:Vector3 xAxis], [page:Vector3 zAxis], [page:Vector3 zAxis] ) [page:Matrix4 this]</h3>
 		<div>
 		Creates the basis matrix consisting of the three provided axis vectors.  Returns the current matrix.
 		</div>
 
-		<h3>[method:Matrix4 extractBasis]( [page:Vector3 xAxis], [page:Vector3 yAxis], [page:Vector3 zAxis] ) [page:Matrix4 this]</h3>
+		<h3>[method:Matrix4 extractBasis]( [page:Vector3 xAxis], [page:Vector3 zAxis], [page:Vector3 zAxis] ) [page:Matrix4 this]</h3>
 		<div>
 		Extracts basis of into the three axis vectors provided.  Returns the current matrix.
 		</div>
@@ -110,12 +110,12 @@
 
 		<h3>[method:Matrix4 multiplyScalar]( [page:Float s] ) [page:Matrix4 this]</h3>
 		<div>
-		Multiplies this matrix by *s*.
+		Multiplies every component of the matrix by a scalar value *s*.
 		</div>
 
 		<h3>[method:Float determinant]()</h3>
 		<div>
-		Computes determinant of this matrix.<br />
+		Computes and returns the determinant of this matrix.<br />
 		Based on [link:http://www.euclideanspace.com/maths/algebra/matrix/functions/inverse/fourD/index.htm]
 		</div>
 
@@ -142,7 +142,7 @@
 
 		<h3>[method:Matrix4 makeRotationFromEuler]( [page:Euler euler] ) [page:Matrix4 this]</h3>
 		<div>
-		euler — Rotation vector followed by order of rotations. Eg. "XYZ".
+		euler — Rotation vector followed by order of rotations, e.g., "XYZ".
 		</div>
 		<div>
 		Sets the rotation submatrix of this matrix to the rotation specified by Euler angles, the rest of the matrix is identity.<br />
@@ -230,7 +230,7 @@
 
 		<h3>[method:Matrix4 clone]()</h3>
 		<div>
-		Clones this matrix.
+		Creates a copy of this matrix.
 		</div>
 
 		<h3>[method:Array applyToVector3Array]([page:Array a])</h3>
@@ -238,12 +238,12 @@
 		array -- An array in the form [vector1x, vector1y, vector1z, vector2x, vector2y, vector2z, ...]
 		</div>
 		<div>
-		Multiply (apply) this matrix to every vector3 in the array.
+		Multiplies (applies) this matrix to every vector3 in the array.
 		</div>
 
 		<h3>[method:Float getMaxScaleOnAxis]()</h3>
 		<div>
-		Gets the max scale value of the 3 axes.
+		Gets the maximum scale value of the 3 axes.
 		</div>
 
 		<h2>Source</h2>

+ 0 - 2
docs/list.js

@@ -37,7 +37,6 @@ var list = {
 
 		"Lights": [
 			[ "AmbientLight", "api/lights/AmbientLight" ],
-			[ "AreaLight", "api/lights/AreaLight" ],
 			[ "DirectionalLight", "api/lights/DirectionalLight" ],
 			[ "HemisphereLight", "api/lights/HemisphereLight" ],
 			[ "Light", "api/lights/Light" ],
@@ -231,7 +230,6 @@ var list = {
 			[ "PointLightHelper", "api/extras/helpers/PointLightHelper" ],
 			[ "SpotLightHelper", "api/extras/helpers/SpotLightHelper" ],
 			[ "VertexNormalsHelper", "api/extras/helpers/VertexNormalsHelper" ],
-			[ "VertexTangentsHelper", "api/extras/helpers/VertexTangentsHelper" ],
 			[ "WireframeHelper", "api/extras/helpers/WireframeHelper" ]
 		],
 

+ 99 - 100
docs/scenes/js/geometry.js

@@ -24,7 +24,6 @@ var constants = {
 
 	shading : {
 
-		"THREE.NoShading" : THREE.NoShading,
 		"THREE.FlatShading" : THREE.FlatShading,
 		"THREE.SmoothShading" : THREE.SmoothShading
 
@@ -81,13 +80,13 @@ var constants = {
 }
 
 function updateGroupGeometry( mesh, geometry ) {
-	
+
 	mesh.children[0].geometry.dispose();
 	mesh.children[1].geometry.dispose();
-	
+
 	mesh.children[0].geometry = new THREE.WireframeGeometry( geometry );
 	mesh.children[1].geometry = geometry;
-	
+
 	//these do not update nicely together if shared
 }
 
@@ -103,26 +102,26 @@ var guis = {
 			heightSegments : 1,
 			depthSegments : 1
 		};
-		
+
 		function generateGeometry() {
-			
-			updateGroupGeometry( mesh, 
+
+			updateGroupGeometry( mesh,
 				new THREE.BoxGeometry(
 					data.width, data.height, data.depth, data.widthSegments, data.heightSegments, data.depthSegments
 				)
 			);
-			
+
 		}
 
 		var folder = gui.addFolder('THREE.BoxGeometry');
-		
+
 		folder.add( data, 'width', 1, 30 ).onChange( generateGeometry );
 		folder.add( data, 'height', 1, 30 ).onChange( generateGeometry );
 		folder.add( data, 'depth', 1, 30 ).onChange( generateGeometry );
 		folder.add( data, 'widthSegments', 1, 10 ).step(1).onChange( generateGeometry );
 		folder.add( data, 'heightSegments', 1, 10 ).step(1).onChange( generateGeometry );
 		folder.add( data, 'depthSegments', 1, 10 ).step(1).onChange( generateGeometry );
-		
+
 		generateGeometry();
 	},
 
@@ -138,10 +137,10 @@ var guis = {
 			thetaStart : 0,
 			thetaLength : twoPi,
 		};
-		
+
 		function generateGeometry() {
-			
-			updateGroupGeometry( mesh, 
+
+			updateGroupGeometry( mesh,
 				new THREE.CylinderGeometry(
 					data.radiusTop,
 					data.radiusBottom,
@@ -153,11 +152,11 @@ var guis = {
 					data.thetaLength
 				)
 			)
-			
+
 		}
 
 		var folder = gui.addFolder('THREE.CylinderGeometry');
-		
+
 		folder.add( data, 'radiusTop', 1, 30 ).onChange( generateGeometry );
 		folder.add( data, 'radiusBottom', 1, 30 ).onChange( generateGeometry );
 		folder.add( data, 'height', 1, 50 ).onChange( generateGeometry );
@@ -166,8 +165,8 @@ var guis = {
 		folder.add( data, 'openEnded' ).onChange( generateGeometry );
 		folder.add( data, 'thetaStart', 0, twoPi ).onChange( generateGeometry );
 		folder.add( data, 'thetaLength', 0, twoPi ).onChange( generateGeometry );
-		
-		
+
+
 		generateGeometry();
 	},
 
@@ -179,103 +178,103 @@ var guis = {
 			thetaStart : 0,
 			thetaLength : twoPi,
 		};
-		
+
 		function generateGeometry() {
-			
-			updateGroupGeometry( mesh, 
+
+			updateGroupGeometry( mesh,
 				new THREE.CircleGeometry(
 					data.radius, data.segments, data.thetaStart, data.thetaLength
 				)
 			);
-			
+
 		}
 
 		var folder = gui.addFolder('THREE.CircleGeometry');
-		
+
 		folder.add( data, 'radius', 1, 20 ).onChange( generateGeometry );
 		folder.add( data, 'segments', 0, 128 ).step(1).onChange( generateGeometry );
 		folder.add( data, 'thetaStart', 0, twoPi ).onChange( generateGeometry );
 		folder.add( data, 'thetaLength', 0, twoPi ).onChange( generateGeometry );
-		
+
 		generateGeometry();
 	},
-	
+
 	DodecahedronGeometry : function() {
 
 		var data = {
 			radius : 10,
 			detail : 0,
 		};
-		
+
 		function generateGeometry() {
-			
-			updateGroupGeometry( mesh, 
+
+			updateGroupGeometry( mesh,
 				new THREE.DodecahedronGeometry(
 					data.radius, data.detail
 				)
 			)
-			
+
 		}
 
 		var folder = gui.addFolder('THREE.DodecahedronGeometry');
-		
+
 		folder.add( data, 'radius', 1, 20 ).onChange( generateGeometry )
 		folder.add( data, 'detail', 0, 5 ).step(1).onChange( generateGeometry )
-		
+
 		generateGeometry()
-		
+
 	},
-	
+
 	IcosahedronGeometry : function() {
 
 		var data = {
 			radius : 10,
 			detail : 0,
 		};
-		
+
 		function generateGeometry() {
-			
-			updateGroupGeometry( mesh, 
+
+			updateGroupGeometry( mesh,
 				new THREE.IcosahedronGeometry(
 					data.radius, data.detail
 				)
 			)
-			
+
 		}
 
 		var folder = gui.addFolder('THREE.IcosahedronGeometry');
-		
+
 		folder.add( data, 'radius', 1, 20 ).onChange( generateGeometry )
 		folder.add( data, 'detail', 0, 5 ).step(1).onChange( generateGeometry )
-		
+
 		generateGeometry()
-		
+
 	},
-	
+
 	OctahedronGeometry : function() {
 
 		var data = {
 			radius : 10,
 			detail : 0,
 		};
-		
+
 		function generateGeometry() {
-			
-			updateGroupGeometry( mesh, 
+
+			updateGroupGeometry( mesh,
 				new THREE.OctahedronGeometry(
 					data.radius, data.detail
 				)
 			)
-			
+
 		}
 
 		var folder = gui.addFolder('THREE.OctahedronGeometry');
-		
+
 		folder.add( data, 'radius', 1, 20 ).onChange( generateGeometry )
 		folder.add( data, 'detail', 0, 5 ).step(1).onChange( generateGeometry )
-		
+
 		generateGeometry()
-		
+
 	},
 
 	PlaneGeometry : function( mesh ) {
@@ -286,24 +285,24 @@ var guis = {
 			widthSegments : 1,
 			heightSegments : 1
 		};
-		
+
 		function generateGeometry() {
-			
-			updateGroupGeometry( mesh, 
+
+			updateGroupGeometry( mesh,
 				new THREE.PlaneGeometry(
 					data.width, data.height, data.widthSegments, data.heightSegments
 				)
 			);
-			
+
 		}
 
 		var folder = gui.addFolder('THREE.PlaneGeometry');
-		
+
 		folder.add( data, 'width', 1, 30 ).onChange( generateGeometry );
 		folder.add( data, 'height', 1, 30 ).onChange( generateGeometry );
 		folder.add( data, 'widthSegments', 1, 30 ).step(1).onChange( generateGeometry );
 		folder.add( data, 'heightSegments', 1, 30 ).step(1).onChange( generateGeometry );
-		
+
 		generateGeometry();
 	},
 
@@ -317,29 +316,29 @@ var guis = {
 			thetaStart : 0,
 			thetaLength : twoPi,
 		};
-		
+
 		function generateGeometry() {
-			
-			updateGroupGeometry( mesh, 
+
+			updateGroupGeometry( mesh,
 				new THREE.RingGeometry(
 					data.innerRadius, data.outerRadius, data.thetaSegments, data.phiSegments, data.thetaStart, data.thetaLength
 				)
 			);
-			
+
 		}
 
 		var folder = gui.addFolder('THREE.RingGeometry');
-		
+
 		folder.add( data, 'innerRadius', 0, 30 ).onChange( generateGeometry );
 		folder.add( data, 'outerRadius', 1, 30 ).onChange( generateGeometry );
 		folder.add( data, 'thetaSegments', 1, 30 ).step(1).onChange( generateGeometry );
 		folder.add( data, 'phiSegments', 1, 30 ).step(1).onChange( generateGeometry );
 		folder.add( data, 'thetaStart', 0, twoPi ).onChange( generateGeometry );
 		folder.add( data, 'thetaLength', 0, twoPi ).onChange( generateGeometry );
-		
+
 		generateGeometry();
 	},
-	
+
 	SphereGeometry : function( mesh ) {
 
 		var data = {
@@ -351,19 +350,19 @@ var guis = {
 			thetaStart : 0,
 			thetaLength : Math.PI,
 		};
-		
+
 		function generateGeometry() {
-			
-			updateGroupGeometry( mesh, 
+
+			updateGroupGeometry( mesh,
 				new THREE.SphereGeometry(
 					data.radius, data.widthSegments, data.heightSegments, data.phiStart, data.phiLength, data.thetaStart, data.thetaLength
 				)
 			);
-			
+
 		}
 
 		var folder = gui.addFolder('THREE.SphereGeometry');
-		
+
 		folder.add( data, 'radius', 1, 30 ).onChange( generateGeometry );
 		folder.add( data, 'widthSegments', 3, 32 ).step(1).onChange( generateGeometry );
 		folder.add( data, 'heightSegments', 2, 32 ).step(1).onChange( generateGeometry );
@@ -371,36 +370,36 @@ var guis = {
 		folder.add( data, 'phiLength', 0, twoPi ).onChange( generateGeometry );
 		folder.add( data, 'thetaStart', 0, twoPi ).onChange( generateGeometry );
 		folder.add( data, 'thetaLength', 0, twoPi ).onChange( generateGeometry );
-		
+
 		generateGeometry();
 	},
-	
+
 	TetrahedronGeometry : function() {
 
 		var data = {
 			radius : 10,
 			detail : 0,
 		};
-		
+
 		function generateGeometry() {
-			
-			updateGroupGeometry( mesh, 
+
+			updateGroupGeometry( mesh,
 				new THREE.TetrahedronGeometry(
 					data.radius, data.detail
 				)
 			)
-			
+
 		}
 
 		var folder = gui.addFolder('THREE.TetrahedronGeometry');
-		
+
 		folder.add( data, 'radius', 1, 20 ).onChange( generateGeometry )
 		folder.add( data, 'detail', 0, 5 ).step(1).onChange( generateGeometry )
-		
+
 		generateGeometry()
-		
+
 	},
-	
+
 	TextGeometry : function( mesh ) {
 
 		var data = {
@@ -415,33 +414,33 @@ var guis = {
 			bevelThickness : 1,
 			bevelSize : 0.5
 		};
-		
+
 		var fonts = [
 			"helvetiker",
 			"optimer",
 			"gentilis",
 			"droid serif"
 		]
-		
+
 		var weights = [
 			"normal", "bold"
 		]
-		
+
 		function generateGeometry() {
-			
+
 			var geometry = new THREE.TextGeometry( data.text, data )
-			
+
 			geometry.center()
-			
+
 			updateGroupGeometry( mesh, geometry );
-			
+
 		}
-		
+
 		//Hide the wireframe
 		mesh.children[0].visible = false;
 
 		var folder = gui.addFolder('THREE.TextGeometry');
-		
+
 		folder.add( data, 'text' ).onChange( generateGeometry );
 		folder.add( data, 'size', 1, 30 ).onChange( generateGeometry );
 		folder.add( data, 'height', 1, 20 ).onChange( generateGeometry );
@@ -452,10 +451,10 @@ var guis = {
 		folder.add( data, 'bevelEnabled' ).onChange( generateGeometry );
 		folder.add( data, 'bevelThickness', 0.1, 3 ).onChange( generateGeometry );
 		folder.add( data, 'bevelSize', 0.1, 3 ).onChange( generateGeometry );
-		
+
 		generateGeometry();
 	},
-	
+
 	TorusGeometry : function( mesh ) {
 
 		var data = {
@@ -465,29 +464,29 @@ var guis = {
 			tubularSegments : 100,
 			arc : twoPi
 		};
-		
+
 		function generateGeometry() {
-			
-			updateGroupGeometry( mesh, 
+
+			updateGroupGeometry( mesh,
 				new THREE.TorusGeometry(
 					data.radius, data.tube, data.radialSegments, data.tubularSegments, data.arc
 				)
 			)
-			
+
 		}
 
 		var folder = gui.addFolder('THREE.TorusGeometry');
-		
+
 		folder.add( data, 'radius', 1, 20 ).onChange( generateGeometry );
 		folder.add( data, 'tube', 0.1, 10 ).onChange( generateGeometry );
 		folder.add( data, 'radialSegments', 2, 30 ).step(1).onChange( generateGeometry );
 		folder.add( data, 'tubularSegments', 3, 200 ).step(1).onChange( generateGeometry );
 		folder.add( data, 'arc', 0.1, twoPi ).onChange( generateGeometry );
-		
+
 		generateGeometry();
 
 	},
-	
+
 	TorusKnotGeometry : function( mesh ) {
 
 		var data = {
@@ -499,20 +498,20 @@ var guis = {
 			q : 3,
 			heightScale : 1
 		};
-		
+
 		function generateGeometry() {
-			
-			updateGroupGeometry( mesh, 
+
+			updateGroupGeometry( mesh,
 				new THREE.TorusKnotGeometry(
 					data.radius, data.tube, data.radialSegments, data.tubularSegments,
 					data.p, data.q, data.heightScale
 				)
 			)
-			
+
 		}
 
 		var folder = gui.addFolder('THREE.TorusGeometry');
-		
+
 		folder.add( data, 'radius', 1, 20 ).onChange( generateGeometry )
 		folder.add( data, 'tube', 0.1, 10 ).onChange( generateGeometry )
 		folder.add( data, 'radialSegments', 3, 300 ).step(1).onChange( generateGeometry )
@@ -520,11 +519,11 @@ var guis = {
 		folder.add( data, 'p', 1, 20 ).step(1).onChange( generateGeometry )
 		folder.add( data, 'q', 1, 20 ).step(1).onChange( generateGeometry )
 		folder.add( data, 'heightScale', 1, 20 ).onChange( generateGeometry )
-		
+
 		generateGeometry()
 
 	}
-	
+
 }
 
 function chooseFromHash ( mesh ) {

+ 0 - 1
docs/scenes/js/material.js

@@ -22,7 +22,6 @@ var constants = {
 
 	shading : {
 
-		"THREE.NoShading" : THREE.NoShading,
 		"THREE.FlatShading" : THREE.FlatShading,
 		"THREE.SmoothShading" : THREE.SmoothShading
 

+ 2 - 0
editor/index.html

@@ -112,6 +112,8 @@
 		<script src="js/Sidebar.Geometry.SphereGeometry.js"></script>
 		<script src="js/Sidebar.Geometry.TorusGeometry.js"></script>
 		<script src="js/Sidebar.Geometry.TorusKnotGeometry.js"></script>
+		<script src="../examples/js/geometries/TeapotBufferGeometry.js"></script>
+		<script src="js/Sidebar.Geometry.TeapotBufferGeometry.js"></script>
 		<script src="js/Sidebar.Material.js"></script>
 		<script src="js/Sidebar.Script.js"></script>
 		<script src="js/Toolbar.js"></script>

+ 6 - 0
editor/js/Loader.js

@@ -7,6 +7,8 @@ var Loader = function ( editor ) {
 	var scope = this;
 	var signals = editor.signals;
 
+	this.texturePath = '';
+
 	this.loadFile = function ( file ) {
 
 		var filename = file.name;
@@ -386,6 +388,8 @@ var Loader = function ( editor ) {
 		} else if ( data.metadata.type.toLowerCase() === 'geometry' ) {
 
 			var loader = new THREE.JSONLoader();
+			loader.setTexturePath( scope.texturePath );
+
 			var result = loader.parse( data );
 
 			var geometry = result.geometry;
@@ -432,6 +436,8 @@ var Loader = function ( editor ) {
 		} else if ( data.metadata.type.toLowerCase() === 'object' ) {
 
 			var loader = new THREE.ObjectLoader();
+			loader.setTexturePath( scope.texturePath );
+
 			var result = loader.parse( data );
 
 			if ( result instanceof THREE.Scene ) {

+ 28 - 0
editor/js/Menubar.Add.js

@@ -236,6 +236,34 @@ Menubar.Add = function ( editor ) {
 	} );
 	options.add( option );
 
+	// Teapot
+
+	var option = new UI.Panel();
+	option.setClass( 'option' );
+	option.setTextContent( 'Teapot' );
+	option.onClick( function () {
+
+		var size = 50;
+		var segments = 10;
+		var bottom = true;
+		var lid = true;
+		var body = true;
+		var fitLid = false;
+		var blinnScale = true;
+
+		var material = new THREE.MeshPhongMaterial();
+		material.side = 2;
+
+		var geometry = new THREE.TeapotBufferGeometry( size, segments, bottom, lid, body, fitLid, blinnScale );
+		var mesh = new THREE.Mesh( geometry, material );
+		mesh.name = 'Teapot ' + ( ++ meshCount );
+
+		editor.addObject( mesh );
+		editor.select( mesh );
+
+	} );
+	options.add( option );
+
 	// Sprite
 
 	var option = new UI.Panel();

+ 11 - 0
editor/js/Sidebar.Geometry.BufferGeometry.js

@@ -17,6 +17,17 @@ Sidebar.Geometry.BufferGeometry = function ( signals ) {
 			container.clear();
 			container.setDisplay( 'block' );
 
+			var index = geometry.index;
+
+			if ( index !== null ) {
+
+				var panel = new UI.Panel();
+				panel.add( new UI.Text( 'index' ).setWidth( '90px' ) );
+				panel.add( new UI.Text( ( index.count ).format() ).setFontSize( '12px' ) );
+				container.add( panel );
+
+			}
+
 			var attributes = geometry.attributes;
 
 			for ( var name in attributes ) {

+ 0 - 20
editor/js/Sidebar.Geometry.Modifiers.js

@@ -31,26 +31,6 @@ Sidebar.Geometry.Modifiers = function ( signals, object ) {
 
 	container.add( button );
 
-	// Convert to Geometry/BufferGeometry
-
-	var isBufferGeometry = geometry instanceof THREE.BufferGeometry;
-
-	if ( geometry instanceof THREE.Geometry ) {
-
-		var button = new UI.Button( 'Convert to BufferGeometry' );
-		button.onClick( function () {
-
-			if ( confirm( 'Are you sure?' ) === false ) return;
-
-			object.geometry = new THREE.BufferGeometry().fromGeometry( object.geometry );
-
-			signals.geometryChanged.dispatch( object );
-
-		} );
-		container.add( button );
-
-	}
-
 	//
 
 	return container;

+ 103 - 0
editor/js/Sidebar.Geometry.TeapotBufferGeometry.js

@@ -0,0 +1,103 @@
+/**
+ * @author tschw
+ */
+
+Sidebar.Geometry.TeapotBufferGeometry = function ( signals, object ) {
+
+	var container = new UI.Panel();
+
+	var parameters = object.geometry.parameters;
+
+	// size
+
+	var sizeRow = new UI.Panel();
+	var size = new UI.Number( parameters.size ).onChange( update );
+
+	sizeRow.add( new UI.Text( 'Size' ).setWidth( '90px' ) );
+	sizeRow.add( size );
+
+	container.add( sizeRow );
+
+	// segments
+
+	var segmentsRow = new UI.Panel();
+	var segments = new UI.Integer( parameters.segments ).setRange( 1, Infinity ).onChange( update );
+
+	segmentsRow.add( new UI.Text( 'Segments' ).setWidth( '90px' ) );
+	segmentsRow.add( segments );
+
+	container.add( segmentsRow );
+
+	// bottom
+
+	var bottomRow = new UI.Panel();
+	var bottom = new UI.Checkbox( parameters.bottom ).onChange( update );
+
+	bottomRow.add( new UI.Text( 'Bottom' ).setWidth( '90px' ) );
+	bottomRow.add( bottom );
+
+	container.add( bottomRow );
+
+	// lid
+
+	var lidRow = new UI.Panel();
+	var lid = new UI.Checkbox( parameters.lid ).onChange( update );
+
+	lidRow.add( new UI.Text( 'Lid' ).setWidth( '90px' ) );
+	lidRow.add( lid );
+
+	container.add( lidRow );
+
+	// body
+
+	var bodyRow = new UI.Panel();
+	var body = new UI.Checkbox( parameters.body ).onChange( update );
+
+	bodyRow.add( new UI.Text( 'Body' ).setWidth( '90px' ) );
+	bodyRow.add( body );
+
+	container.add( bodyRow );
+
+	// fitted lid
+
+	var fitLidRow = new UI.Panel();
+	var fitLid = new UI.Checkbox( parameters.fitLid ).onChange( update );
+
+	fitLidRow.add( new UI.Text( 'Fitted Lid' ).setWidth( '90px' ) );
+	fitLidRow.add( fitLid );
+
+	container.add( fitLidRow );
+
+	// blinn-sized
+
+	var blinnRow = new UI.Panel();
+	var blinn = new UI.Checkbox( parameters.blinn ).onChange( update );
+
+	blinnRow.add( new UI.Text( 'Blinn-scaled' ).setWidth( '90px' ) );
+	blinnRow.add( blinn );
+
+	container.add( blinnRow );
+
+	function update() {
+
+		object.geometry.dispose();
+
+		object.geometry = new THREE.TeapotBufferGeometry(
+			size.getValue(),
+			segments.getValue(),
+			bottom.getValue(),
+			lid.getValue(),
+			body.getValue(),
+			fitLid.getValue(),
+			blinn.getValue()
+		);
+
+		object.geometry.computeBoundingSphere();
+
+		signals.geometryChanged.dispatch( object );
+
+	}
+
+	return container;
+
+}

+ 13 - 0
editor/js/Sidebar.Geometry.js

@@ -25,6 +25,7 @@ Sidebar.Geometry = function ( editor ) {
 
 		'Actions': 'Actions',
 		'Center': 'Center',
+		'Convert': 'Convert',
 		'Flatten': 'Flatten'
 
 	} );
@@ -55,6 +56,18 @@ Sidebar.Geometry = function ( editor ) {
 
 				break;
 
+			case 'Convert':
+
+				if ( geometry instanceof THREE.Geometry ) {
+
+					object.geometry = new THREE.BufferGeometry().fromGeometry( geometry );
+
+					signals.geometryChanged.dispatch( object );
+
+				}
+
+				break;
+
 			case 'Flatten':
 
 				geometry.applyMatrix( object.matrix );

+ 49 - 2
editor/js/Sidebar.Material.js

@@ -223,6 +223,20 @@ Sidebar.Material = function ( editor ) {
 
 	container.add( materialNormalMapRow );
 
+	// displacement map
+
+	var materialDisplacementMapRow = new UI.Panel();
+	var materialDisplacementMapEnabled = new UI.Checkbox( false ).onChange( update );
+	var materialDisplacementMap = new UI.Texture().onChange( update );
+	var materialDisplacementScale = new UI.Number( 1 ).setWidth( '30px' ).onChange( update );
+
+	materialDisplacementMapRow.add( new UI.Text( 'Displace Map' ).setWidth( '90px' ) );
+	materialDisplacementMapRow.add( materialDisplacementMapEnabled );
+	materialDisplacementMapRow.add( materialDisplacementMap );
+	materialDisplacementMapRow.add( materialDisplacementScale );
+
+	container.add( materialDisplacementMapRow );
+
 	// specular map
 
 	var materialSpecularMapRow = new UI.Panel();
@@ -517,6 +531,24 @@ Sidebar.Material = function ( editor ) {
 
 			}
 
+			if ( material.displacementMap !== undefined ) {
+
+				var displacementMapEnabled = materialDisplacementMapEnabled.getValue() === true;
+
+				if ( objectHasUvs ) {
+
+					material.displacementMap = displacementMapEnabled ? materialDisplacementMap.getValue() : null;
+					material.displacementScale = materialDisplacementScale.getValue();
+					material.needsUpdate = true;
+
+				} else {
+
+					if ( displacementMapEnabled ) textureWarning = true;
+
+				}
+
+			}
+
 			if ( material.specularMap !== undefined ) {
 
 				var specularMapEnabled = materialSpecularMapEnabled.getValue() === true;
@@ -551,7 +583,7 @@ Sidebar.Material = function ( editor ) {
 
 				if ( objectHasUvs ) {
 
-					material.lightMap = specularMapEnabled ? materialLightMap.getValue() : null;
+					material.lightMap = lightMapEnabled ? materialLightMap.getValue() : null;
 					material.needsUpdate = true;
 
 				} else {
@@ -659,6 +691,7 @@ Sidebar.Material = function ( editor ) {
 			'alphaMap': materialAlphaMapRow,
 			'bumpMap': materialBumpMapRow,
 			'normalMap': materialNormalMapRow,
+			'displacementMap': materialDisplacementMapRow,
 			'specularMap': materialSpecularMapRow,
 			'envMap': materialEnvMapRow,
 			'lightMap': materialLightMapRow,
@@ -683,7 +716,7 @@ Sidebar.Material = function ( editor ) {
 	};
 
 
-	function refreshUi(resetTextureSelectors) {
+	function refreshUi( resetTextureSelectors ) {
 
 		var material = currentObject.material;
 
@@ -787,6 +820,20 @@ Sidebar.Material = function ( editor ) {
 
 		}
 
+		if ( material.displacementMap !== undefined ) {
+
+			materialDisplacementMapEnabled.setValue( material.displacementMap !== null );
+
+			if ( material.displacementMap !== null || resetTextureSelectors ) {
+
+				materialDisplacementMap.setValue( material.displacementMap );
+
+			}
+
+			materialDisplacementScale.setValue( material.displacementScale );
+
+		}
+
 		if ( material.specularMap !== undefined ) {
 
 			materialSpecularMapEnabled.setValue( material.specularMap !== null );

+ 5 - 5
editor/js/Viewport.Info.js

@@ -53,15 +53,15 @@ Viewport.Info = function ( editor ) {
 
 					} else if ( geometry instanceof THREE.BufferGeometry ) {
 
-						vertices += geometry.attributes.position.array.length / 3;
+						if ( geometry.index !== null ) {
 
-						if ( geometry.attributes.index !== undefined ) {
-
-							triangles += geometry.attributes.index.array.length / 3;
+							vertices += geometry.index.count * 3;
+							triangles += geometry.index.count;
 
 						} else {
 
-							triangles += geometry.attributes.position.array.length / 9;
+							vertices += geometry.attributes.position.count;
+							triangles += geometry.attributes.position.count / 3;
 
 						}
 

+ 4 - 92
editor/js/libs/tern-threejs/threejs.js

@@ -225,10 +225,6 @@
           "!type": "[]",
           "!doc": "Array of morph targets. Each morph target is a Javascript object:\n\t\t<code>{ name: \"targetName\", vertices: [ new THREE.Vertex(), ... ] }</code>\n\t\tMorph vertices match number and order of primary vertices."
         },
-        "hasTangents": {
-          "!type": "boolean",
-          "!doc": "True if BufferGeometry has tangents. Set in [page:.computeTangents]."
-        },
         "addAttribute": {
           "!type": "null",
           "!doc": "Adds an attribute to this geometry. Use this rather than the attributes property, \n\t\tbecause an internal array of attributes is maintained to speed up iterating over\n\t\tattributes."
@@ -245,10 +241,6 @@
           "!type": "fn()",
           "!doc": "Computes vertex normals by averaging face normals.<br>"
         },
-        "computeTangents": {
-          "!type": "fn()",
-          "!doc": "Computes vertex tangents.<br>\n\t\tBased on [link:http://www.terathon.com/code/tangent.html]<br>\n\t\tGeometry must have vertex [page:UV UVs] (layer 0 will be used)."
-        },
         "computeBoundingBox": {
           "!type": "fn()",
           "!doc": "Computes bounding box of the geometry, updating [page:Geometry Geometry.boundingBox] attribute.<br>\n\t\tBounding boxes aren't computed by default. They need to be explicitly computed, otherwise they are *null*."
@@ -374,10 +366,6 @@
           "!type": "[]",
           "!doc": "Array of 3 vertex colors."
         },
-        "vertexTangents": {
-          "!type": "[]",
-          "!doc": "Array of 3 vertex tangents."
-        },
         "materialIndex": {
           "!type": "number",
           "!doc": "Material index (points to [page:MeshFaceMaterial MeshFaceMaterial.materials])."
@@ -445,10 +433,6 @@
           "!type": "object",
           "!doc": "Bounding sphere.\n\t\t<code>{ radius: float }</code>"
         },
-        "hasTangents": {
-          "!type": "bool",
-          "!doc": "True if geometry has tangents. Set in [page:Geometry Geometry.computeTangents]."
-        },
         "dynamic": {
           "!type": "bool",
           "!doc": "Set to *true* if attribute buffers will need to change in runtime (using \"dirty\" flags).<br>\n\t\tUnless set to true internal typed arrays corresponding to buffers will be deleted once sent to GPU.<br>\n\t\tDefaults to true."
@@ -469,10 +453,6 @@
           "!type": "bool",
           "!doc": "Set to *true* if the normals array has been updated."
         },
-        "tangentsNeedUpdate": {
-          "!type": "bool",
-          "!doc": "Set to *true* if the tangents in the faces has been updated."
-        },
         "colorsNeedUpdate": {
           "!type": "bool",
           "!doc": "Set to *true* if the colors array has been updated."
@@ -501,10 +481,6 @@
           "!type": "fn()",
           "!doc": "Computes morph normals."
         },
-        "computeTangents": {
-          "!type": "fn()",
-          "!doc": "Computes vertex tangents.<br>\n\t\tBased on [link:http://www.terathon.com/code/tangent.html]<br>\n\t\tGeometry must have vertex [page:UV UVs] (layer 0 will be used)."
-        },
         "computeBoundingBox": {
           "!type": "fn()",
           "!doc": "Computes bounding box of the geometry, updating [page:Geometry Geometry.boundingBox] attribute."
@@ -2005,22 +1981,6 @@
       "!doc": "Renders [page:ArrowHelper arrows] to visualize an object's vertex normal vectors. Requires that normals have been specified in a [page:BufferAttribute custom attribute] or have been calculated using [page:Geometry.computeVertexNormals computeVertexNormals].",
       "!type": "fn(object: +THREE.Object3D, size: number, color: +THREE.Color, linewidth: number)"
     },
-    "VertexTangentsHelper": {
-      "!url": "http://threejs.org/docs/#Reference/extras/helpers/VertexTangentsHelper",
-      "prototype": {
-        "!proto": "THREE.Line.prototype",
-        "object": {
-          "!type": "+THREE.Object3D",
-          "!doc": "The attached object"
-        },
-        "update": {
-          "!type": "fn()",
-          "!doc": "Updates the vertex tangent preview arrows based on the new position and tangents of the object."
-        }
-      },
-      "!doc": "Renders [page:ArrowHelper arrows] to visualize an object's vertex tangent vectors. Requires that tangents have been specified in a [page:BufferAttribute custom attribute] or have been computed using [page:Geometry.computeTangents computeTangents].",
-      "!type": "fn(object: +THREE.Object3D, size: number, color: +THREE.Color, linewidth: number)"
-    },
     "WireframeHelper": {
       "!url": "http://threejs.org/docs/#Reference/extras/helpers/WireframeHelper",
       "prototype": {
@@ -2117,46 +2077,6 @@
       "!doc": "This light's color gets applied to all the objects in the scene globally.",
       "!type": "fn(hex: number)"
     },
-    "AreaLight": {
-      "!url": "http://threejs.org/docs/#Reference/lights/AreaLight",
-      "prototype": {
-        "!proto": "THREE.Light.prototype",
-        "right": {
-          "!type": "+THREE.Vector3",
-          "!doc": "Sets or gets an unit vector that indicates the right side of the light. This is calculated in local space."
-        },
-        "normal": {
-          "!type": "+THREE.Vector3",
-          "!doc": "Sets or gets an unit vectorSets or gets an unit vector that indicates the right side of the light. This is calculated in local space."
-        },
-        "height": {
-          "!type": "number",
-          "!doc": "Sets or gets the height of the illuminating plane."
-        },
-        "width": {
-          "!type": "number",
-          "!doc": "Sets or gets the width of the illuminating plane."
-        },
-        "intensity": {
-          "!type": "number",
-          "!doc": "Light's intensity.<br>\n\t\tDefault — *1.0*."
-        },
-        "constantAttenuation": {
-          "!type": "number",
-          "!doc": "Sets or gets the attention of the light in constant space. This is independant of the distance of the light."
-        },
-        "linearAttenuation": {
-          "!type": "number",
-          "!doc": "Sets or gets the attention of the light in linear space. This increases the attenuation linearly with the distance from the light."
-        },
-        "quadraticAttenuation": {
-          "!type": "number",
-          "!doc": "Sets or gets the attention of the light in linear space. This increases the attenuation quadratic with the distance from the light."
-        }
-      },
-      "!doc": "This illuminates the scene from a complete surface. This light only works in the [page:WebGLDeferredRenderer deferredrenderer].",
-      "!type": "fn(hex: number, intensity: number)"
-    },
     "DirectionalLight": {
       "!url": "http://threejs.org/docs/#Reference/lights/DirectionalLight",
       "prototype": {
@@ -2479,7 +2399,7 @@
         },
         "setPreferredShading": {
           "!type": "fn(shading: number)",
-          "!doc": "Set the .[page:Integer shading] property on the resource's materials.<br>\n\t\tOptions are [page:Materials THREE.SmoothShading], [page:Materials THREE.FlatShading], [page:Materials THREE.NoShading]."
+          "!doc": "Set the .[page:Integer shading] property on the resource's materials.<br>\n\t\tOptions are [page:Materials THREE.SmoothShading], [page:Materials THREE.FlatShading]."
         },
         "applySkin": {
           "!type": "fn(geometry: +THREE.Geometry, instanceCtrl: object, frame: number)",
@@ -2544,10 +2464,6 @@
           "!type": "fn(json: object, texturePath: string) -> +THREE.Object3D",
           "!doc": "Parse a <em>JSON</em> structure and return an [page:Object] containing the parsed .[page:Geometry] and .[page:Array materials]."
         },
-        "needsTangents": {
-          "!type": "fn(materials: []) -> bool",
-          "!doc": "Checks if the loaded object needs tangents based on its materials."
-        },
         "updateProgress": {
           "!type": "fn(progress: object)",
           "!doc": "Updates the DOM object with the progress made."
@@ -2599,10 +2515,6 @@
           "!type": "string",
           "!doc": "The crossOrigin string to implement CORS for loading the url from a different domain that allows CORS."
         },
-        "needsTangents": {
-          "!type": "fn(materials: []) -> bool",
-          "!doc": "Checks if the loaded object needs tangents based on its materials."
-        },
         "updateProgress": {
           "!type": "fn(progress: object)",
           "!doc": "Updates the DOM object with the progress made."
@@ -3156,7 +3068,7 @@
         },
         "shading": {
           "!type": "number",
-          "!doc": "Options are [page:Materials THREE.SmoothShading] (default), [page:Materials THREE.FlatShading], [page:Materials THREE.NoShading]."
+          "!doc": "Options are [page:Materials THREE.SmoothShading] (default), [page:Materials THREE.FlatShading]."
         },
         "wireframe": {
           "!type": "bool",
@@ -3300,7 +3212,7 @@
         },
         "shading": {
           "!type": "number",
-          "!doc": "Options are [page:Materials THREE.SmoothShading] (default), [page:Materials THREE.FlatShading], [page:Materials THREE.NoShading]."
+          "!doc": "Options are [page:Materials THREE.SmoothShading] (default), [page:Materials THREE.FlatShading]."
         },
         "wireframe": {
           "!type": "bool",
@@ -6025,4 +5937,4 @@
 }
     };
   });
-});
+});

+ 3 - 6
examples/index.html

@@ -219,6 +219,7 @@
 				"webgl_geometry_nurbs",
 				"webgl_geometry_shapes",
 				"webgl_geometry_spline_editor",
+				"webgl_geometry_teapot",
 				"webgl_geometry_terrain",
 				"webgl_geometry_terrain_fog",
 				"webgl_geometry_terrain_raycast",
@@ -294,10 +295,10 @@
 				"webgl_materials_cubemap_dynamic2",
 				"webgl_materials_cubemap_escher",
 				"webgl_materials_cubemap_refraction",
+				"webgl_materials_displacementmap",
 				"webgl_materials_envmaps",
 				"webgl_materials_grass",
 				"webgl_materials_lightmap",
-				"webgl_materials_normaldisplacementmap",
 				"webgl_materials_normalmap",
 				"webgl_materials_parallaxmap",
 				"webgl_materials_shaders_fresnel",
@@ -345,6 +346,7 @@
 				"webgl_postprocessing_glitch",
 				"webgl_postprocessing_godrays",
 				"webgl_postprocessing_ssao",
+				"webgl_raycast_texture",
 				"webgl_rtt",
 				"webgl_sandbox",
 				"webgl_shader",
@@ -388,11 +390,6 @@
 				"webgl_custom_attributes_particles2",
 				"webgl_custom_attributes_particles3"
 			],
-			"webgldeferred": [
-				"webgldeferred_animation",
-				"webgldeferred_arealights",
-				"webgldeferred_pointlights"
-			],
 			"vr": [
 				"vr_cubes",
 				"vr_video"

+ 0 - 170
examples/js/AudioObject.js

@@ -1,170 +0,0 @@
-/**
- * @author alteredq / http://alteredqualia.com/
- *
- * AudioObject
- *
- *	- 3d spatialized sound with Doppler-shift effect
- *
- *	- uses Audio API (currently supported in WebKit-based browsers)
- *		https://dvcs.w3.org/hg/audio/raw-file/tip/webaudio/specification.html
- *
- *	- based on Doppler effect demo from Chromium
- * 		http://chromium.googlecode.com/svn/trunk/samples/audio/doppler.html
- *
- * - parameters
- *
- *		- listener
- *			dopplerFactor	// A constant used to determine the amount of pitch shift to use when rendering a doppler effect.
- *			speedOfSound	// The speed of sound used for calculating doppler shift. The default value is 343.3 meters / second.
- *
- *		- panner
- *			refDistance		// A reference distance for reducing volume as source move further from the listener.
- *			maxDistance		// The maximum distance between source and listener, after which the volume will not be reduced any further.
- *			rolloffFactor	// Describes how quickly the volume is reduced as source moves away from listener.
- * 			coneInnerAngle	// An angle inside of which there will be no volume reduction.
- *			coneOuterAngle 	// An angle outside of which the volume will be reduced to a constant value of coneOuterGain.
- *			coneOuterGain	// Amount of volume reduction outside of the coneOuterAngle.
- */
-
-THREE.AudioObject = function ( url, volume, playbackRate, loop ) {
-
-	THREE.Object3D.call( this );
-
-	if ( playbackRate === undefined ) playbackRate = 1;
-	if ( volume === undefined ) volume = 1;
-	if ( loop === undefined ) loop = true;
-
-	if ( ! this.context ) {
-
-		try {
-
-			THREE.AudioObject.prototype.context = new webkitAudioContext();
-
-		} catch ( error ) {
-
-			console.warn( "THREE.AudioObject: webkitAudioContext not found" );
-			return this;
-
-		}
-
-	}
-
-	this.directionalSource = false;
-
-	this.listener = this.context.listener;
-	this.panner = this.context.createPanner();
-	this.source = this.context.createBufferSource();
-
-	this.masterGainNode = this.context.createGainNode();
-	this.dryGainNode = this.context.createGainNode();
-
-	// Setup initial gains
-
-	this.masterGainNode.gain.value = volume;
-	this.dryGainNode.gain.value = 3.0;
-
-	// Connect dry mix
-
-	this.source.connect( this.panner );
-	this.panner.connect( this.dryGainNode );
-	this.dryGainNode.connect( this.masterGainNode );
-
-	// Connect master gain
-
-	this.masterGainNode.connect( this.context.destination );
-
-	// Set source parameters and load sound
-
-	this.source.playbackRate.value = playbackRate;
-	this.source.loop = loop;
-
-	loadBufferAndPlay( url );
-
-	// private properties
-
-	var soundPosition = new THREE.Vector3(),
-	cameraPosition = new THREE.Vector3(),
-	oldSoundPosition = new THREE.Vector3(),
-	oldCameraPosition = new THREE.Vector3(),
-
-	soundDelta = new THREE.Vector3(),
-	cameraDelta = new THREE.Vector3(),
-
-	soundFront = new THREE.Vector3(),
-	cameraFront = new THREE.Vector3(),
-	soundUp = new THREE.Vector3(),
-	cameraUp = new THREE.Vector3();
-
-	var _this = this;
-
-	// API
-
-	this.setVolume = function ( volume ) {
-
-		this.masterGainNode.gain.value = volume;
-
-	};
-
-	this.update = function ( camera ) {
-
-		oldSoundPosition.copy( soundPosition );
-		oldCameraPosition.copy( cameraPosition );
-
-		soundPosition.setFromMatrixPosition( this.matrixWorld );
-		cameraPosition.setFromMatrixPosition( camera.matrixWorld );
-
-		soundDelta.subVectors( soundPosition, oldSoundPosition );
-		cameraDelta.subVectors( cameraPosition, oldCameraPosition );
-
-		cameraUp.copy( camera.up );
-
-		cameraFront.set( 0, 0, - 1 );
-		cameraFront.transformDirection( camera.matrixWorld );
-
-		this.listener.setPosition( cameraPosition.x, cameraPosition.y, cameraPosition.z );
-		this.listener.setVelocity( cameraDelta.x, cameraDelta.y, cameraDelta.z );
-		this.listener.setOrientation( cameraFront.x, cameraFront.y, cameraFront.z, cameraUp.x, cameraUp.y, cameraUp.z );
-
-		this.panner.setPosition( soundPosition.x, soundPosition.y, soundPosition.z );
-		this.panner.setVelocity( soundDelta.x, soundDelta.y, soundDelta.z );
-
-		if ( this.directionalSource ) {
-
-			soundFront.set( 0, 0, - 1 );
-			soundFront.transformDirection( this.matrixWorld );
-
-			soundUp.copy( this.up );
-			this.panner.setOrientation( soundFront.x, soundFront.y, soundFront.z, soundUp.x, soundUp.y, soundUp.z );
-
-		}
-
-
-	};
-
-	function loadBufferAndPlay( url ) {
-
-		// Load asynchronously
-
-		var request = new XMLHttpRequest();
-		request.open( "GET", url, true );
-		request.responseType = "arraybuffer";
-
-		request.onload = function() {
-
-			_this.source.buffer = _this.context.createBuffer( request.response, true );
-			_this.source.noteOn( 0 );
-
-		};
-
-		request.send();
-
-	}
-
-};
-
-THREE.AudioObject.prototype = Object.create( THREE.Object3D.prototype );
-THREE.AudioObject.prototype.constructor = THREE.AudioObject;
-
-THREE.AudioObject.prototype.context = null;
-THREE.AudioObject.prototype.type = null;
-

+ 187 - 0
examples/js/BufferGeometryUtils.js

@@ -0,0 +1,187 @@
+/**
+ * @author mrdoob / http://mrdoob.com/
+ */
+
+THREE.BufferGeometryUtils = {
+
+	computeTangents: function ( geometry ) {
+
+		var index = geometry.index;
+		var attributes = geometry.attributes;
+
+		// based on http://www.terathon.com/code/tangent.html
+		// (per vertex tangents)
+
+		if ( index === null ||
+			 attributes.position === undefined ||
+			 attributes.normal === undefined ||
+			 attributes.uv === undefined ) {
+
+			console.warn( 'THREE.BufferGeometry: Missing required attributes (index, position, normal or uv) in BufferGeometry.computeTangents()' );
+			return;
+
+		}
+
+		var indices = index.array;
+		var positions = attributes.position.array;
+		var normals = attributes.normal.array;
+		var uvs = attributes.uv.array;
+
+		var nVertices = positions.length / 3;
+
+		if ( attributes.tangent === undefined ) {
+
+			geometry.addAttribute( 'tangent', new THREE.BufferAttribute( new Float32Array( 4 * nVertices ), 4 ) );
+
+		}
+
+		var tangents = attributes.tangent.array;
+
+		var tan1 = [], tan2 = [];
+
+		for ( var k = 0; k < nVertices; k ++ ) {
+
+			tan1[ k ] = new THREE.Vector3();
+			tan2[ k ] = new THREE.Vector3();
+
+		}
+
+		var vA = new THREE.Vector3(),
+			vB = new THREE.Vector3(),
+			vC = new THREE.Vector3(),
+
+			uvA = new THREE.Vector2(),
+			uvB = new THREE.Vector2(),
+			uvC = new THREE.Vector2(),
+
+			sdir = new THREE.Vector3(),
+			tdir = new THREE.Vector3();
+
+		function handleTriangle( a, b, c ) {
+
+			vA.fromArray( positions, a * 3 );
+			vB.fromArray( positions, b * 3 );
+			vC.fromArray( positions, c * 3 );
+
+			uvA.fromArray( uvs, a * 2 );
+			uvB.fromArray( uvs, b * 2 );
+			uvC.fromArray( uvs, c * 2 );
+
+			var x1 = vB.x - vA.x;
+			var x2 = vC.x - vA.x;
+
+			var y1 = vB.y - vA.y;
+			var y2 = vC.y - vA.y;
+
+			var z1 = vB.z - vA.z;
+			var z2 = vC.z - vA.z;
+
+			var s1 = uvB.x - uvA.x;
+			var s2 = uvC.x - uvA.x;
+
+			var t1 = uvB.y - uvA.y;
+			var t2 = uvC.y - uvA.y;
+
+			var r = 1.0 / ( s1 * t2 - s2 * t1 );
+
+			sdir.set(
+				( t2 * x1 - t1 * x2 ) * r,
+				( t2 * y1 - t1 * y2 ) * r,
+				( t2 * z1 - t1 * z2 ) * r
+			);
+
+			tdir.set(
+				( s1 * x2 - s2 * x1 ) * r,
+				( s1 * y2 - s2 * y1 ) * r,
+				( s1 * z2 - s2 * z1 ) * r
+			);
+
+			tan1[ a ].add( sdir );
+			tan1[ b ].add( sdir );
+			tan1[ c ].add( sdir );
+
+			tan2[ a ].add( tdir );
+			tan2[ b ].add( tdir );
+			tan2[ c ].add( tdir );
+
+		}
+
+		var groups = geometry.groups;
+
+		if ( groups.length === 0 ) {
+
+			groups = [ {
+				start: 0,
+				count: indices.length
+			} ];
+
+		}
+
+		for ( var j = 0, jl = groups.length; j < jl; ++ j ) {
+
+			var group = groups[ j ];
+
+			var start = group.start;
+			var count = group.count;
+
+			for ( var i = start, il = start + count; i < il; i += 3 ) {
+
+				handleTriangle(
+					indices[ i + 0 ],
+					indices[ i + 1 ],
+					indices[ i + 2 ]
+				);
+
+			}
+
+		}
+
+		var tmp = new THREE.Vector3(), tmp2 = new THREE.Vector3();
+		var n = new THREE.Vector3(), n2 = new THREE.Vector3();
+		var w, t, test;
+
+		function handleVertex( v ) {
+
+			n.fromArray( normals, v * 3 );
+			n2.copy( n );
+
+			t = tan1[ v ];
+
+			// Gram-Schmidt orthogonalize
+
+			tmp.copy( t );
+			tmp.sub( n.multiplyScalar( n.dot( t ) ) ).normalize();
+
+			// Calculate handedness
+
+			tmp2.crossVectors( n2, t );
+			test = tmp2.dot( tan2[ v ] );
+			w = ( test < 0.0 ) ? - 1.0 : 1.0;
+
+			tangents[ v * 4 ] = tmp.x;
+			tangents[ v * 4 + 1 ] = tmp.y;
+			tangents[ v * 4 + 2 ] = tmp.z;
+			tangents[ v * 4 + 3 ] = w;
+
+		}
+
+		for ( var j = 0, jl = groups.length; j < jl; ++ j ) {
+
+			var group = groups[ j ];
+
+			var start = group.start;
+			var count = group.count;
+
+			for ( var i = start, il = start + count; i < il; i += 3 ) {
+
+				handleVertex( indices[ i + 0 ] );
+				handleVertex( indices[ i + 1 ] );
+				handleVertex( indices[ i + 2 ] );
+
+			}
+
+		}
+
+	}
+
+};

+ 0 - 1104
examples/js/ShaderDeferred.js

@@ -1,1104 +0,0 @@
-/**
- * @author alteredq / http://alteredqualia.com/
- * @author MPanknin / http://www.redplant.de/
- * @author benaadams / http://blog.illyriad.co.uk/
- *
- */
-
-
-THREE.DeferredShaderChunk = {
-
-	// decode float to vec3
-
-	unpackFloat: [
-
-		"vec3 float_to_vec3( float data ) {",
-
-			"vec3 uncompressed;",
-			"uncompressed.x = fract( data );",
-			"float zInt = floor( data / 255.0 );",
-			"uncompressed.z = fract( zInt / 255.0 );",
-			"uncompressed.y = fract( floor( data - ( zInt * 255.0 ) ) / 255.0 );",
-			"return uncompressed;",
-
-		"}"
-
-	].join( "\n" ),
-
-	computeVertexPositionVS: [
-
-		"vec2 texCoord = gl_FragCoord.xy / vec2( viewWidth, viewHeight );",
-
-		"vec4 normalDepth = texture2D( samplerNormalDepth, texCoord );",
-		"float z = normalDepth.w;",
-
-		"if ( z == 0.0 ) discard;",
-
-		"vec2 xy = texCoord * 2.0 - 1.0;",
-
-		"vec4 vertexPositionProjected = vec4( xy, z, 1.0 );",
-		"vec4 vertexPositionVS = matProjInverse * vertexPositionProjected;",
-		"vertexPositionVS.xyz /= vertexPositionVS.w;",
-		"vertexPositionVS.w = 1.0;"
-
-	].join( "\n" ),
-
-	computeNormal: [
-
-		"vec3 normal = normalDepth.xyz * 2.0 - 1.0;"
-
-	].join( "\n" ),
-
-	unpackColorMap: [
-
-		"vec4 colorMap = texture2D( samplerColor, texCoord );",
-
-		"vec3 albedo = float_to_vec3( abs( colorMap.x ) );",
-		"vec3 specularColor = float_to_vec3( abs( colorMap.y ) );",
-		"float shininess = abs( colorMap.z );",
-		"float wrapAround = sign( colorMap.z );",
-		"float additiveSpecular = sign( colorMap.y );"
-
-	].join( "\n" ),
-
-	computeDiffuse: [
-
-		"float dotProduct = dot( normal, lightVector );",
-		"float diffuseFull = max( dotProduct, 0.0 );",
-
-		"vec3 diffuse;",
-
-		"if ( wrapAround < 0.0 ) {",
-
-			// wrap around lighting
-
-			"float diffuseHalf = max( 0.5 * dotProduct + 0.5, 0.0 );",
-
-			"const vec3 wrapRGB = vec3( 1.0, 1.0, 1.0 );",
-			"diffuse = mix( vec3( diffuseFull ), vec3( diffuseHalf ), wrapRGB );",
-
-		"} else {",
-
-			// simple lighting
-
-			"diffuse = vec3( diffuseFull );",
-
-		"}"
-
-	].join( "\n" ),
-
-	computeSpecular: [
-
-		"vec3 halfVector = normalize( lightVector - normalize( vertexPositionVS.xyz ) );",
-		"float dotNormalHalf = max( dot( normal, halfVector ), 0.0 );",
-
-		// simple specular
-
-		//"vec3 specular = specularColor * max( pow( dotNormalHalf, shininess ), 0.0 ) * diffuse;",
-
-		// physically based specular
-
-		"float specularNormalization = ( shininess + 2.0001 ) / 8.0;",
-
-		"vec3 schlick = specularColor + vec3( 1.0 - specularColor ) * pow( 1.0 - dot( lightVector, halfVector ), 5.0 );",
-		"vec3 specular = schlick * max( pow( dotNormalHalf, shininess ), 0.0 ) * diffuse * specularNormalization;"
-
-	].join( "\n" ),
-
-	combine: [
-
-		"vec3 light = lightIntensity * lightColor;",
-		"gl_FragColor = vec4( light * ( albedo * diffuse + specular ), attenuation );"
-
-	].join( "\n" )
-
-};
-
-THREE.ShaderDeferred = {
-
-	"color" : {
-
-		uniforms: THREE.UniformsUtils.merge( [
-
-			THREE.UniformsLib[ "common" ],
-			THREE.UniformsLib[ "fog" ],
-			THREE.UniformsLib[ "shadowmap" ],
-
-			{
-				"emissive" :  { type: "c", value: new THREE.Color( 0x000000 ) },
-				"specular" :  { type: "c", value: new THREE.Color( 0x111111 ) },
-				"shininess":  { type: "f", value: 30 },
-				"wrapAround": 		{ type: "f", value: 1 },
-				"additiveSpecular": { type: "f", value: 1 },
-
-				"samplerNormalDepth": { type: "t", value: null },
-				"viewWidth": 		{ type: "f", value: 800 },
-				"viewHeight": 		{ type: "f", value: 600 }
-			}
-
-		] ),
-
-		fragmentShader : [
-
-			"uniform vec3 diffuse;",
-			"uniform vec3 specular;",
-			"uniform vec3 emissive;",
-			"uniform float shininess;",
-			"uniform float wrapAround;",
-			"uniform float additiveSpecular;",
-
-			THREE.ShaderChunk[ "common" ],
-			THREE.ShaderChunk[ "color_pars_fragment" ],
-			THREE.ShaderChunk[ "uv_pars_fragment" ],
-			THREE.ShaderChunk[ "uv2_pars_fragment" ],
-			THREE.ShaderChunk[ "map_pars_fragment" ],
-
-			"#ifdef USE_ENVMAP",
-
-				"varying vec3 vWorldPosition;",
-
-				"uniform float reflectivity;",
-				"uniform samplerCube envMap;",
-				"uniform float flipEnvMap;",
-				"uniform int combine;",
-
-				"uniform bool useRefract;",
-				"uniform float refractionRatio;",
-
-				"uniform sampler2D samplerNormalDepth;",
-				"uniform float viewHeight;",
-				"uniform float viewWidth;",
-
-			"#endif",
-
-			THREE.ShaderChunk[ "fog_pars_fragment" ],
-			THREE.ShaderChunk[ "shadowmap_pars_fragment" ],
-			THREE.ShaderChunk[ "specularmap_pars_fragment" ],
-
-			"const float unit = 255.0/256.0;",
-
-			"float vec3_to_float( vec3 data ) {",
-
-				"highp float compressed = fract( data.x * unit ) + floor( data.y * unit * 255.0 ) + floor( data.z * unit * 255.0 ) * 255.0;",
-				"return compressed;",
-
-			"}",
-
-			"void main() {",
-
-				"const float opacity = 1.0;",
-
-				"vec3 outgoingLight = vec3( 0.0 );",	// outgoing light does not have an alpha, the surface does
-				"vec4 diffuseColor = vec4( diffuse, opacity );",
-
-				THREE.ShaderChunk[ "map_fragment" ],
-				THREE.ShaderChunk[ "alphatest_fragment" ],
-				THREE.ShaderChunk[ "specularmap_fragment" ],
-				THREE.ShaderChunk[ "lightmap_fragment" ],
-				THREE.ShaderChunk[ "color_fragment" ],
-
-				"outgoingLight = diffuseColor.rgb;",
-
-				"#ifdef USE_ENVMAP",
-
-					"vec2 texCoord = gl_FragCoord.xy / vec2( viewWidth, viewHeight );",
-					"vec4 normalDepth = texture2D( samplerNormalDepth, texCoord );",
-					"vec3 normal = normalDepth.xyz * 2.0 - 1.0;",
-
-					"vec3 reflectVec;",
-
-					"vec3 cameraToVertex = normalize( vWorldPosition - cameraPosition );",
-
-					"if ( useRefract ) {",
-
-						"reflectVec = refract( cameraToVertex, normal, refractionRatio );",
-
-					"} else { ",
-
-						"reflectVec = reflect( cameraToVertex, normal );",
-
-					"}",
-
-					"#ifdef DOUBLE_SIDED",
-
-						"float flipNormal = ( -1.0 + 2.0 * float( gl_FrontFacing ) );",
-						"vec4 cubeColor = textureCube( envMap, flipNormal * vec3( flipEnvMap * reflectVec.x, reflectVec.yz ) );",
-
-					"#else",
-
-						"vec4 cubeColor = textureCube( envMap, vec3( flipEnvMap * reflectVec.x, reflectVec.yz ) );",
-
-					"#endif",
-
-					"cubeColor.xyz = inputToLinear( cubeColor.xyz );",
-
-					"if ( combine == 1 ) {",
-
-						"outgoingLight = mix( outgoingLight, cubeColor.xyz, specularStrength * reflectivity );",
-
-					"} else if ( combine == 2 ) {",
-
-						"outgoingLight += cubeColor.xyz * specularStrength * reflectivity;",
-
-					"} else {",
-
-						"outgoingLight = mix( outgoingLight, diffuseColor.xyz * cubeColor.xyz, specularStrength * reflectivity );",
-
-					"}",
-
-				"#endif",
-
-				THREE.ShaderChunk[ "shadowmap_fragment" ],
-				THREE.ShaderChunk[ "fog_fragment" ],
-
-				//
-
-				"const float compressionScale = 0.999;",
-
-				//
-
-				"vec3 diffuseMapColor;",
-
-				"#ifdef USE_MAP",
-
-					"diffuseMapColor = texelColor.xyz;",
-
-				"#else",
-
-					"diffuseMapColor = vec3( 1.0 );",
-
-				"#endif",
-
-				// diffuse color
-
-				"gl_FragColor.x = vec3_to_float( compressionScale * outgoingLight );",
-
-				// specular color
-
-				"if ( additiveSpecular < 0.0 ) {",
-
-					"gl_FragColor.y = vec3_to_float( compressionScale * specular );",
-
-				"} else {",
-
-					"gl_FragColor.y = vec3_to_float( compressionScale * specular * diffuseMapColor );",
-
-				"}",
-
-				"gl_FragColor.y *= additiveSpecular;",
-
-				// shininess
-
-				"gl_FragColor.z = wrapAround * shininess;",
-
-				// emissive color
-
-				"#ifdef USE_COLOR",
-
-					"gl_FragColor.w = vec3_to_float( compressionScale * emissive * diffuseMapColor * vColor );",
-
-				"#else",
-
-					"gl_FragColor.w = vec3_to_float( compressionScale * emissive * diffuseMapColor );",
-
-				"#endif",
-
-			"}"
-
-		].join( "\n" ),
-
-		vertexShader : [
-
-			THREE.ShaderChunk[ "common" ],
-			THREE.ShaderChunk[ "uv_pars_vertex" ],
-			THREE.ShaderChunk[ "uv2_pars_vertex" ],
-			THREE.ShaderChunk[ "color_pars_vertex" ],
-			THREE.ShaderChunk[ "morphtarget_pars_vertex" ],
-			THREE.ShaderChunk[ "skinning_pars_vertex" ],
-			THREE.ShaderChunk[ "shadowmap_pars_vertex" ],
-
-			"#ifdef USE_ENVMAP",
-
-				"varying vec3 vWorldPosition;",
-
-			"#endif",
-
-			"void main() {",
-
-				THREE.ShaderChunk[ "uv_vertex" ],
-				THREE.ShaderChunk[ "uv2_vertex" ],
-				THREE.ShaderChunk[ "color_vertex" ],
-
-				THREE.ShaderChunk[ "skinbase_vertex" ],
-
-				THREE.ShaderChunk[ "morphtarget_vertex" ],
-				THREE.ShaderChunk[ "skinning_vertex" ],
-				THREE.ShaderChunk[ "default_vertex" ],
-
-				THREE.ShaderChunk[ "worldpos_vertex" ],
-				THREE.ShaderChunk[ "shadowmap_vertex" ],
-
-				"#ifdef USE_ENVMAP",
-
-					"vWorldPosition = worldPosition.xyz;",
-
-				"#endif",
-
-			"}"
-
-		].join( "\n" )
-
-	},
-
-	"normalDepth" : {
-
-		uniforms: {
-
-			bumpMap: 	  { type: "t", value: null },
-			bumpScale:	  { type: "f", value: 1 },
-			offsetRepeat: { type: "v4", value: new THREE.Vector4( 0, 0, 1, 1 ) }
-
-		},
-
-		fragmentShader : [
-
-			"#ifdef USE_BUMPMAP",
-
-				"varying vec2 vUv;",
-				"varying vec3 vViewPosition;",
-
-				THREE.ShaderChunk[ "bumpmap_pars_fragment" ],
-
-			"#endif",
-
-			"varying vec3 normalView;",
-			"varying vec4 clipPos;",
-
-			"void main() {",
-
-				"vec3 normal = normalize( normalView );",
-
-				"#ifdef USE_BUMPMAP",
-
-					"normal = perturbNormalArb( -vViewPosition, normal, dHdxy_fwd() );",
-
-				"#endif",
-
-				"gl_FragColor.xyz = normal * 0.5 + 0.5;",
-				"gl_FragColor.w = clipPos.z / clipPos.w;",
-
-			"}"
-
-		].join( "\n" ),
-
-		vertexShader : [
-
-			"varying vec3 normalView;",
-			"varying vec4 clipPos;",
-
-			"#ifdef USE_BUMPMAP",
-
-				"varying vec2 vUv;",
-				"varying vec3 vViewPosition;",
-
-				"uniform vec4 offsetRepeat;",
-
-			"#endif",
-
-			THREE.ShaderChunk[ "morphtarget_pars_vertex" ],
-			THREE.ShaderChunk[ "skinning_pars_vertex" ],
-
-			"void main() {",
-
-				THREE.ShaderChunk[ "morphnormal_vertex" ],
-				THREE.ShaderChunk[ "skinbase_vertex" ],
-				THREE.ShaderChunk[ "skinnormal_vertex" ],
-				THREE.ShaderChunk[ "defaultnormal_vertex" ],
-
-				THREE.ShaderChunk[ "morphtarget_vertex" ],
-				THREE.ShaderChunk[ "skinning_vertex" ],
-				THREE.ShaderChunk[ "default_vertex" ],
-
-				"normalView = normalize( normalMatrix * objectNormal );",
-
-				"#ifdef USE_BUMPMAP",
-
-					"vUv = uv * offsetRepeat.zw + offsetRepeat.xy;",
-					"vViewPosition = -mvPosition.xyz;",
-
-				"#endif",
-
-				"clipPos = gl_Position;",
-
-			"}"
-
-		].join( "\n" )
-
-	},
-
-	"composite" : {
-
-		uniforms: {
-
-			samplerLight: 	{ type: "t", value: null },
-			brightness:		{ type: "f", value: 1 }
-
-		},
-
-		fragmentShader : [
-
-			"varying vec2 texCoord;",
-			"uniform sampler2D samplerLight;",
-			"uniform float brightness;",
-
-			// tonemapping operators
-			// based on John Hable's HLSL snippets
-			// from http://filmicgames.com/archives/75
-
-			"#ifdef TONEMAP_UNCHARTED",
-
-				"const float A = 0.15;",
-				"const float B = 0.50;",
-				"const float C = 0.10;",
-				"const float D = 0.20;",
-				"const float E = 0.02;",
-				"const float F = 0.30;",
-				"const float W = 11.2;",
-
-				"vec3 Uncharted2Tonemap( vec3 x ) {",
-
-				   "return ( ( x * ( A * x + C * B ) + D * E ) / ( x * ( A * x + B ) + D * F ) ) - E / F;",
-
-				"}",
-
-			"#endif",
-
-			"void main() {",
-
-				"vec3 inColor = texture2D( samplerLight, texCoord ).xyz;",
-				"inColor *= brightness;",
-
-				"vec3 outColor;",
-
-				"#if defined( TONEMAP_SIMPLE )",
-
-					"outColor = sqrt( inColor );",
-
-				"#elif defined( TONEMAP_LINEAR )",
-
-					// simple linear to gamma conversion
-
-					"outColor = pow( inColor, vec3( 1.0 / 2.2 ) );",
-
-				"#elif defined( TONEMAP_REINHARD )",
-
-					// Reinhard operator
-
-					"inColor = inColor / ( 1.0 + inColor );",
-					"outColor = pow( inColor, vec3( 1.0 / 2.2 ) );",
-
-				"#elif defined( TONEMAP_FILMIC )",
-
-					// filmic operator by Jim Hejl and Richard Burgess-Dawson
-
-					"vec3 x = max( vec3( 0.0 ), inColor - 0.004 );",
-					"outColor = ( x * ( 6.2 * x + 0.5 ) ) / ( x * ( 6.2 * x + 1.7 ) + 0.06 );",
-
-				"#elif defined( TONEMAP_UNCHARTED )",
-
-					// tonemapping operator from Uncharted 2 by John Hable
-
-					"float ExposureBias = 2.0;",
-					"vec3 curr = Uncharted2Tonemap( ExposureBias * inColor );",
-
-					"vec3 whiteScale = vec3( 1.0 ) / Uncharted2Tonemap( vec3( W ) );",
-					"vec3 color = curr * whiteScale;",
-
-					"outColor = pow( color, vec3( 1.0 / 2.2 ) );",
-
-				"#else",
-
-					"outColor = inColor;",
-
-				"#endif",
-
-				"gl_FragColor = vec4( outColor, 1.0 );",
-
-			"}"
-
-		].join( "\n" ),
-
-		vertexShader : [
-
-			"varying vec2 texCoord;",
-
-			"void main() {",
-
-				"vec4 pos = vec4( sign( position.xy ), 0.0, 1.0 );",
-				"texCoord = pos.xy * vec2( 0.5 ) + 0.5;",
-				"gl_Position = pos;",
-
-			"}"
-
-		].join( "\n" )
-
-	},
-
-	"pointLight" : {
-
-		uniforms: {
-
-			samplerNormalDepth: { type: "t", value: null },
-			samplerColor: 		{ type: "t", value: null },
-			matProjInverse: { type: "m4", value: new THREE.Matrix4() },
-			viewWidth: 		{ type: "f", value: 800 },
-			viewHeight: 	{ type: "f", value: 600 },
-
-			lightPositionVS: { type: "v3", value: new THREE.Vector3( 0, 0, 0 ) },
-			lightColor: 	{ type: "c", value: new THREE.Color( 0x000000 ) },
-			lightIntensity: { type: "f", value: 1.0 },
-			lightRadius: 	{ type: "f", value: 1.0 }
-
-		},
-
-		fragmentShader : [
-
-			"uniform sampler2D samplerColor;",
-			"uniform sampler2D samplerNormalDepth;",
-
-			"uniform float lightRadius;",
-			"uniform float lightIntensity;",
-			"uniform float viewHeight;",
-			"uniform float viewWidth;",
-
-			"uniform vec3 lightColor;",
-			"uniform vec3 lightPositionVS;",
-
-			"uniform mat4 matProjInverse;",
-
-			THREE.DeferredShaderChunk[ "unpackFloat" ],
-
-			"void main() {",
-
-				THREE.DeferredShaderChunk[ "computeVertexPositionVS" ],
-
-				// bail out early when pixel outside of light sphere
-
-				"vec3 lightVector = lightPositionVS - vertexPositionVS.xyz;",
-				"float distance = length( lightVector );",
-
-				"if ( distance > lightRadius ) discard;",
-
-				THREE.DeferredShaderChunk[ "computeNormal" ],
-				THREE.DeferredShaderChunk[ "unpackColorMap" ],
-
-				// compute light
-
-				"lightVector = normalize( lightVector );",
-
-				THREE.DeferredShaderChunk[ "computeDiffuse" ],
-				THREE.DeferredShaderChunk[ "computeSpecular" ],
-
-				// combine
-
-				"float cutoff = 0.3;",
-				"float denom = distance / lightRadius + 1.0;",
-				"float attenuation = 1.0 / ( denom * denom );",
-				"attenuation = ( attenuation - cutoff ) / ( 1.0 - cutoff );",
-				"attenuation = max( attenuation, 0.0 );",
-				"attenuation *= attenuation;",
-
-				THREE.DeferredShaderChunk[ "combine" ],
-
-			"}"
-
-		].join( "\n" ),
-
-		vertexShader : [
-
-			"void main() { ",
-
-				// sphere proxy needs real position
-
-				"vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );",
-				"gl_Position = projectionMatrix * mvPosition;",
-
-			"}"
-
-		].join( "\n" )
-
-	},
-
-	"spotLight" : {
-
-		uniforms: {
-
-			samplerNormalDepth: { type: "t", value: null },
-			samplerColor: 		{ type: "t", value: null },
-			matProjInverse: { type: "m4", value: new THREE.Matrix4() },
-			viewWidth: 		{ type: "f", value: 800 },
-			viewHeight: 	{ type: "f", value: 600 },
-
-			lightPositionVS : { type: "v3", value: new THREE.Vector3( 0, 1, 0 ) },
-			lightDirectionVS: { type: "v3", value: new THREE.Vector3( 0, 1, 0 ) },
-			lightColor: 	{ type: "c", value: new THREE.Color( 0x000000 ) },
-			lightIntensity: { type: "f", value: 1.0 },
-			lightDistance: 	{ type: "f", value: 1.0 },
-			lightAngle: 	{ type: "f", value: 1.0 }
-
-		},
-
-		fragmentShader : [
-
-			"uniform vec3 lightPositionVS;",
-			"uniform vec3 lightDirectionVS;",
-
-			"uniform sampler2D samplerColor;",
-			"uniform sampler2D samplerNormalDepth;",
-
-			"uniform float viewHeight;",
-			"uniform float viewWidth;",
-
-			"uniform float lightAngle;",
-			"uniform float lightIntensity;",
-			"uniform vec3 lightColor;",
-
-			"uniform mat4 matProjInverse;",
-
-			THREE.DeferredShaderChunk[ "unpackFloat" ],
-
-			"void main() {",
-
-				THREE.DeferredShaderChunk[ "computeVertexPositionVS" ],
-				THREE.DeferredShaderChunk[ "computeNormal" ],
-				THREE.DeferredShaderChunk[ "unpackColorMap" ],
-
-				// compute light
-
-				"vec3 lightVector = normalize( lightPositionVS.xyz - vertexPositionVS.xyz );",
-
-				"float rho = dot( lightDirectionVS, lightVector );",
-				"float rhoMax = cos( lightAngle * 0.5 );",
-
-				"if ( rho <= rhoMax ) discard;",
-
-				"float theta = rhoMax + 0.0001;",
-				"float phi = rhoMax + 0.05;",
-				"float falloff = 4.0;",
-
-				"float spot = 0.0;",
-
-				"if ( rho >= phi ) {",
-
-					"spot = 1.0;",
-
-				"} else if ( rho <= theta ) {",
-
-					"spot = 0.0;",
-
-				"} else { ",
-
-					"spot = pow( ( rho - theta ) / ( phi - theta ), falloff );",
-
-				"}",
-
-				THREE.DeferredShaderChunk[ "computeDiffuse" ],
-
-				"diffuse *= spot;",
-
-				THREE.DeferredShaderChunk[ "computeSpecular" ],
-
-				// combine
-
-				"const float attenuation = 1.0;",
-
-				THREE.DeferredShaderChunk[ "combine" ],
-
-			"}"
-
-		].join( "\n" ),
-
-		vertexShader : [
-
-			"void main() { ",
-
-				// full screen quad proxy
-
-				"gl_Position = vec4( sign( position.xy ), 0.0, 1.0 );",
-
-			"}"
-
-		].join( "\n" )
-
-	},
-
-	"directionalLight" : {
-
-		uniforms: {
-
-			samplerNormalDepth: { type: "t", value: null },
-			samplerColor: 		{ type: "t", value: null },
-			matProjInverse: { type: "m4", value: new THREE.Matrix4() },
-			viewWidth: 		{ type: "f", value: 800 },
-			viewHeight: 	{ type: "f", value: 600 },
-
-			lightDirectionVS: { type: "v3", value: new THREE.Vector3( 0, 1, 0 ) },
-			lightColor: 	{ type: "c", value: new THREE.Color( 0x000000 ) },
-			lightIntensity: { type: "f", value: 1.0 }
-
-		},
-
-		fragmentShader : [
-
-			"uniform sampler2D samplerColor;",
-			"uniform sampler2D samplerNormalDepth;",
-
-			"uniform float lightRadius;",
-			"uniform float lightIntensity;",
-			"uniform float viewHeight;",
-			"uniform float viewWidth;",
-
-			"uniform vec3 lightColor;",
-			"uniform vec3 lightDirectionVS;",
-
-			"uniform mat4 matProjInverse;",
-
-			THREE.DeferredShaderChunk[ "unpackFloat" ],
-
-			"void main() {",
-
-				THREE.DeferredShaderChunk[ "computeVertexPositionVS" ],
-				THREE.DeferredShaderChunk[ "computeNormal" ],
-				THREE.DeferredShaderChunk[ "unpackColorMap" ],
-
-				// compute light
-
-				"vec3 lightVector = lightDirectionVS;",
-
-				THREE.DeferredShaderChunk[ "computeDiffuse" ],
-				THREE.DeferredShaderChunk[ "computeSpecular" ],
-
-				// combine
-
-				"const float attenuation = 1.0;",
-
-				THREE.DeferredShaderChunk[ "combine" ],
-
-			"}"
-
-		].join( "\n" ),
-
-		vertexShader : [
-
-			"void main() { ",
-
-				// full screen quad proxy
-
-				"gl_Position = vec4( sign( position.xy ), 0.0, 1.0 );",
-
-			"}"
-
-		].join( "\n" )
-
-	},
-
-	"hemisphereLight" : {
-
-		uniforms: {
-
-			samplerNormalDepth: { type: "t", value: null },
-			samplerColor: 		{ type: "t", value: null },
-			matProjInverse: { type: "m4", value: new THREE.Matrix4() },
-			viewWidth: 		{ type: "f", value: 800 },
-			viewHeight: 	{ type: "f", value: 600 },
-
-			lightDirectionVS: { type: "v3", value: new THREE.Vector3( 0, 1, 0 ) },
-			lightColorSky: 	  { type: "c", value: new THREE.Color( 0x000000 ) },
-			lightColorGround: { type: "c", value: new THREE.Color( 0x000000 ) },
-			lightIntensity:   { type: "f", value: 1.0 }
-
-		},
-
-		fragmentShader : [
-
-			"uniform sampler2D samplerColor;",
-			"uniform sampler2D samplerNormalDepth;",
-
-			"uniform float lightRadius;",
-			"uniform float lightIntensity;",
-			"uniform float viewHeight;",
-			"uniform float viewWidth;",
-
-			"uniform vec3 lightColorSky;",
-			"uniform vec3 lightColorGround;",
-			"uniform vec3 lightDirectionVS;",
-
-			"uniform mat4 matProjInverse;",
-
-			THREE.DeferredShaderChunk[ "unpackFloat" ],
-
-			"void main() {",
-
-				THREE.DeferredShaderChunk[ "computeVertexPositionVS" ],
-				THREE.DeferredShaderChunk[ "computeNormal" ],
-				THREE.DeferredShaderChunk[ "unpackColorMap" ],
-
-				// compute light
-
-				"vec3 lightVector = lightDirectionVS;",
-
-				// diffuse
-
-				"float dotProduct = dot( normal, lightVector );",
-				"float hemiDiffuseWeight = 0.5 * dotProduct + 0.5;",
-
-				"vec3 hemiColor = mix( lightColorGround, lightColorSky, hemiDiffuseWeight );",
-
-				"vec3 diffuse = hemiColor;",
-
-				// specular (sky light)
-
-				"vec3 hemiHalfVectorSky = normalize( lightVector - vertexPositionVS.xyz );",
-				"float hemiDotNormalHalfSky = 0.5 * dot( normal, hemiHalfVectorSky ) + 0.5;",
-				"float hemiSpecularWeightSky = max( pow( hemiDotNormalHalfSky, shininess ), 0.0 );",
-
-				// specular (ground light)
-
-				"vec3 lVectorGround = -lightVector;",
-
-				"vec3 hemiHalfVectorGround = normalize( lVectorGround - vertexPositionVS.xyz );",
-				"float hemiDotNormalHalfGround = 0.5 * dot( normal, hemiHalfVectorGround ) + 0.5;",
-				"float hemiSpecularWeightGround = max( pow( hemiDotNormalHalfGround, shininess ), 0.0 );",
-
-				"float dotProductGround = dot( normal, lVectorGround );",
-
-				"float specularNormalization = ( shininess + 2.0001 ) / 8.0;",
-
-				"vec3 schlickSky = specularColor + vec3( 1.0 - specularColor ) * pow( 1.0 - dot( lightVector, hemiHalfVectorSky ), 5.0 );",
-				"vec3 schlickGround = specularColor + vec3( 1.0 - specularColor ) * pow( 1.0 - dot( lVectorGround, hemiHalfVectorGround ), 5.0 );",
-				"vec3 specular = hemiColor * specularNormalization * ( schlickSky * hemiSpecularWeightSky * max( dotProduct, 0.0 ) + schlickGround * hemiSpecularWeightGround * max( dotProductGround, 0.0 ) );",
-
-				// combine
-
-				"gl_FragColor = vec4( lightIntensity * ( albedo * diffuse + specular ), 1.0 );",
-
-			"}"
-
-		].join( "\n" ),
-
-		vertexShader : [
-
-			"void main() { ",
-
-				// full screen quad proxy
-
-				"gl_Position = vec4( sign( position.xy ), 0.0, 1.0 );",
-
-			"}"
-
-		].join( "\n" )
-
-	},
-
-	"areaLight" : {
-
-		uniforms: {
-
-			samplerNormalDepth: { type: "t", value: null },
-			samplerColor: 		{ type: "t", value: null },
-			matProjInverse: { type: "m4", value: new THREE.Matrix4() },
-			viewWidth: 		{ type: "f", value: 800 },
-			viewHeight: 	{ type: "f", value: 600 },
-
-			lightPositionVS: { type: "v3", value: new THREE.Vector3( 0, 1, 0 ) },
-			lightNormalVS: 	 { type: "v3", value: new THREE.Vector3( 0, - 1, 0 ) },
-			lightRightVS:  	 { type: "v3", value: new THREE.Vector3( 1, 0, 0 ) },
-			lightUpVS:  	 { type: "v3", value: new THREE.Vector3( 1, 0, 0 ) },
-
-			lightColor: 	{ type: "c", value: new THREE.Color( 0x000000 ) },
-			lightIntensity: { type: "f", value: 1.0 },
-
-			lightWidth:  { type: "f", value: 1.0 },
-			lightHeight: { type: "f", value: 1.0 },
-
-			constantAttenuation:  { type: "f", value: 1.5 },
-			linearAttenuation:    { type: "f", value: 0.5 },
-			quadraticAttenuation: { type: "f", value: 0.1 }
-
-		},
-
-		fragmentShader : [
-
-			"uniform vec3 lightPositionVS;",
-			"uniform vec3 lightNormalVS;",
-			"uniform vec3 lightRightVS;",
-			"uniform vec3 lightUpVS;",
-
-			"uniform sampler2D samplerColor;",
-			"uniform sampler2D samplerNormalDepth;",
-
-			"uniform float lightWidth;",
-			"uniform float lightHeight;",
-
-			"uniform float constantAttenuation;",
-			"uniform float linearAttenuation;",
-			"uniform float quadraticAttenuation;",
-
-			"uniform float lightIntensity;",
-			"uniform vec3 lightColor;",
-
-			"uniform float viewHeight;",
-			"uniform float viewWidth;",
-
-			"uniform mat4 matProjInverse;",
-
-			THREE.DeferredShaderChunk[ "unpackFloat" ],
-
-			"vec3 projectOnPlane( vec3 point, vec3 planeCenter, vec3 planeNorm ) {",
-
-				"return point - dot( point - planeCenter, planeNorm ) * planeNorm;",
-
-			"}",
-
-			"bool sideOfPlane( vec3 point, vec3 planeCenter, vec3 planeNorm ) {",
-
-				"return ( dot( point - planeCenter, planeNorm ) >= 0.0 );",
-
-			"}",
-
-			"vec3 linePlaneIntersect( vec3 lp, vec3 lv, vec3 pc, vec3 pn ) {",
-
-				"return lp + lv * ( dot( pn, pc - lp ) / dot( pn, lv ) );",
-
-			"}",
-
-			"float calculateAttenuation( float dist ) {",
-
-				"return ( 1.0 / ( constantAttenuation + linearAttenuation * dist + quadraticAttenuation * dist * dist ) );",
-
-			"}",
-
-			"void main() {",
-
-				THREE.DeferredShaderChunk[ "computeVertexPositionVS" ],
-				THREE.DeferredShaderChunk[ "computeNormal" ],
-				THREE.DeferredShaderChunk[ "unpackColorMap" ],
-
-				"float w = lightWidth;",
-				"float h = lightHeight;",
-
-				"vec3 proj = projectOnPlane( vertexPositionVS.xyz, lightPositionVS, lightNormalVS );",
-				"vec3 dir = proj - lightPositionVS;",
-
-				"vec2 diagonal = vec2( dot( dir, lightRightVS ), dot( dir, lightUpVS ) );",
-				"vec2 nearest2D = vec2( clamp( diagonal.x, -w, w ), clamp( diagonal.y, -h, h ) );",
-				"vec3 nearestPointInside = vec3( lightPositionVS ) + ( lightRightVS * nearest2D.x + lightUpVS * nearest2D.y );",
-
-				"vec3 lightDir = normalize( nearestPointInside - vertexPositionVS.xyz );",
-				"float NdotL = max( dot( lightNormalVS, -lightDir ), 0.0 );",
-				"float NdotL2 = max( dot( normal, lightDir ), 0.0 );",
-
-				//"if ( NdotL2 * NdotL > 0.0 && sideOfPlane( vertexPositionVS.xyz, lightPositionVS, lightNormalVS ) ) {",
-				"if ( NdotL2 * NdotL > 0.0 ) {",
-
-					// diffuse
-
-					"vec3 diffuse = vec3( sqrt( NdotL * NdotL2 ) );",
-
-					// specular
-
-					"vec3 specular = vec3( 0.0 );",
-
-					"vec3 R = reflect( normalize( -vertexPositionVS.xyz ), normal );",
-					"vec3 E = linePlaneIntersect( vertexPositionVS.xyz, R, vec3( lightPositionVS ), lightNormalVS );",
-
-					"float specAngle = dot( R, lightNormalVS );",
-
-					"if ( specAngle > 0.0 ) {",
-
-						"vec3 dirSpec = E - vec3( lightPositionVS );",
-						"vec2 dirSpec2D = vec2( dot( dirSpec, lightRightVS ), dot( dirSpec, lightUpVS ) );",
-						"vec2 nearestSpec2D = vec2( clamp( dirSpec2D.x, -w, w ), clamp( dirSpec2D.y, -h, h ) );",
-						"float specFactor = 1.0 - clamp( length( nearestSpec2D - dirSpec2D ) * 0.05 * shininess, 0.0, 1.0 );",
-						"specular = specularColor * specFactor * specAngle * diffuse;",
-
-					"}",
-
-					// combine
-
-					"float dist = distance( vertexPositionVS.xyz, nearestPointInside );",
-					"float attenuation = calculateAttenuation( dist );",
-
-					THREE.DeferredShaderChunk[ "combine" ],
-
-				"} else {",
-
-					"discard;",
-
-				"}",
-
-			"}"
-
-		].join( "\n" ),
-
-		vertexShader : [
-
-			"void main() {",
-
-				// full screen quad proxy
-
-				"gl_Position = vec4( sign( position.xy ), 0.0, 1.0 );",
-
-			"}"
-
-		].join( "\n" )
-
-	},
-
-	"emissiveLight" : {
-
-		uniforms: {
-
-			samplerColor: 	{ type: "t", value: null },
-			viewWidth: 		{ type: "f", value: 800 },
-			viewHeight: 	{ type: "f", value: 600 },
-
-		},
-
-		fragmentShader : [
-
-			"uniform sampler2D samplerColor;",
-
-			"uniform float viewHeight;",
-			"uniform float viewWidth;",
-
-			THREE.DeferredShaderChunk[ "unpackFloat" ],
-
-			"void main() {",
-
-				"vec2 texCoord = gl_FragCoord.xy / vec2( viewWidth, viewHeight );",
-
-				"vec4 colorMap = texture2D( samplerColor, texCoord );",
-				"vec3 emissiveColor = float_to_vec3( abs( colorMap.w ) );",
-
-				"gl_FragColor = vec4( emissiveColor, 1.0 );",
-
-			"}"
-
-		].join( "\n" ),
-
-		vertexShader : [
-
-			"void main() { ",
-
-				// full screen quad proxy
-
-				"gl_Position = vec4( sign( position.xy ), 0.0, 1.0 );",
-
-			"}"
-
-		].join( "\n" )
-
-	}
-
-};

+ 52 - 59
examples/js/ShaderSkin.js

@@ -167,7 +167,7 @@ THREE.ShaderSkin = {
 				"diffuseColor = diffuseColor * colDiffuse;",
 
 				"vec3 normal = normalize( vNormal );",
-				"vec3 viewPosition = normalize( vViewPosition );",
+				"vec3 viewerDirection = normalize( vViewPosition );",
 
 				"float specularStrength;",
 
@@ -207,10 +207,10 @@ THREE.ShaderSkin = {
 						"float pointDiffuseWeightHalf = max( 0.5 * dot( normal, lVector ) + 0.5, 0.0 );",
 						"vec3 pointDiffuseWeight = mix( vec3 ( pointDiffuseWeightFull ), vec3( pointDiffuseWeightHalf ), uWrapRGB );",
 
-						"float pointSpecularWeight = KS_Skin_Specular( normal, lVector, viewPosition, uRoughness, uSpecularBrightness );",
+						"float pointSpecularWeight = KS_Skin_Specular( normal, lVector, viewerDirection, uRoughness, uSpecularBrightness );",
 
-						"totalDiffuseLight += attenuation * pointLightColor[ i ] * pointDiffuseWeight;",
-						"totalSpecularLight += attenuation * specular * pointLightColor[ i ] * pointSpecularWeight * specularStrength;",
+						"totalDiffuseLight += pointLightColor[ i ] * ( pointDiffuseWeight * attenuation );",
+						"totalSpecularLight += pointLightColor[ i ] * specular * ( pointSpecularWeight * specularStrength * attenuation );",
 
 					"}",
 
@@ -222,16 +222,16 @@ THREE.ShaderSkin = {
 
 					"for( int i = 0; i < MAX_DIR_LIGHTS; i++ ) {",
 
-						"vec3 dirVector = transformDirection( directionalLightDirection[ i ], viewMatrix );",
+						"vec3 dirVector = directionalLightDirection[ i ];",
 
 						"float dirDiffuseWeightFull = max( dot( normal, dirVector ), 0.0 );",
 						"float dirDiffuseWeightHalf = max( 0.5 * dot( normal, dirVector ) + 0.5, 0.0 );",
 						"vec3 dirDiffuseWeight = mix( vec3 ( dirDiffuseWeightFull ), vec3( dirDiffuseWeightHalf ), uWrapRGB );",
 
-						"float dirSpecularWeight = KS_Skin_Specular( normal, dirVector, viewPosition, uRoughness, uSpecularBrightness );",
+						"float dirSpecularWeight = KS_Skin_Specular( normal, dirVector, viewerDirection, uRoughness, uSpecularBrightness );",
 
 						"totalDiffuseLight += directionalLightColor[ i ] * dirDiffuseWeight;",
-						"totalSpecularLight += specular * directionalLightColor[ i ] * dirSpecularWeight * specularStrength;",
+						"totalSpecularLight += directionalLightColor[ i ] * ( dirSpecularWeight * specularStrength );",
 
 					"}",
 
@@ -243,7 +243,7 @@ THREE.ShaderSkin = {
 
 					"for ( int i = 0; i < MAX_HEMI_LIGHTS; i ++ ) {",
 
-						"vec3 lVector = transformDirection( hemisphereLightDirection[ i ], viewMatrix );",
+						"vec3 lVector = hemisphereLightDirection[ i ];",
 
 						"float dotProduct = dot( normal, lVector );",
 						"float hemiDiffuseWeight = 0.5 * dotProduct + 0.5;",
@@ -253,14 +253,16 @@ THREE.ShaderSkin = {
 						// specular (sky light)
 
 						"float hemiSpecularWeight = 0.0;",
-						"hemiSpecularWeight += KS_Skin_Specular( normal, lVector, viewPosition, uRoughness, uSpecularBrightness );",
+						"hemiSpecularWeight += KS_Skin_Specular( normal, lVector, viewerDirection, uRoughness, uSpecularBrightness );",
 
 						// specular (ground light)
 
 						"vec3 lVectorGround = -lVector;",
-						"hemiSpecularWeight += KS_Skin_Specular( normal, lVectorGround, viewPosition, uRoughness, uSpecularBrightness );",
+						"hemiSpecularWeight += KS_Skin_Specular( normal, lVectorGround, viewerDirection, uRoughness, uSpecularBrightness );",
 
-						"totalSpecularLight += specular * mix( hemisphereLightGroundColor[ i ], hemisphereLightSkyColor[ i ], hemiDiffuseWeight ) * hemiSpecularWeight * specularStrength;",
+						"vec3 hemiSpecularColor = mix( hemisphereLightGroundColor[ i ], hemisphereLightSkyColor[ i ], hemiDiffuseWeight );",
+
+						"totalSpecularLight += hemiSpecularColor * specular * ( hemiSpecularWeight * specularStrength );",
 
 					"}",
 
@@ -355,7 +357,9 @@ THREE.ShaderSkin = {
 				"opacity": 	  { type: "f", value: 1 },
 
 				"uRoughness": 	  		{ type: "f", value: 0.15 },
-				"uSpecularBrightness": 	{ type: "f", value: 0.75 }
+				"uSpecularBrightness": 	{ type: "f", value: 0.75 },
+
+				"uPixelSize":	{ type: "f", value: 0.01 }
 
 			}
 
@@ -383,9 +387,8 @@ THREE.ShaderSkin = {
 			"uniform sampler2D tBeckmann;",
 
 			"uniform float uNormalScale;",
+			"uniform float uPixelSize;",
 
-			"varying vec3 vTangent;",
-			"varying vec3 vBinormal;",
 			"varying vec3 vNormal;",
 			"varying vec2 vUv;",
 
@@ -453,20 +456,30 @@ THREE.ShaderSkin = {
 
 				"vec4 mSpecular = vec4( specular, opacity );",
 
-				"vec3 normalTex = texture2D( tNormal, vUv ).xyz * 2.0 - 1.0;",
-				"normalTex.xy *= uNormalScale;",
-				"normalTex = normalize( normalTex );",
-
 				"vec4 colDiffuse = texture2D( tDiffuse, vUv );",
 				"colDiffuse *= colDiffuse;",
 
 				"diffuseColor *= colDiffuse;",
 
-				"mat3 tsb = mat3( vTangent, vBinormal, vNormal );",
+				// normal mapping
+
+				"vec2 uz = vec2( vUv.x, vViewPosition.z );",
+				"vec2 uzDx = dFdx( uz ), uzDy = dFdy( uz );",
+				"vec2 tangent2D = normalize( vec2( uzDx.x, uzDy.x ) );",
+				"vec2 zVec2D = vec2( uzDx.y, uzDy.y );",
+				"vec3 tangent = vec3( tangent2D * uPixelSize, dot( tangent2D, zVec2D ) );",
+				"vec3 binormal = normalize( cross( vNormal, tangent ) );",
+				"tangent = cross( binormal, vNormal );",
+				"mat3 tsb = mat3( tangent, binormal, vNormal );",
+
+				"vec3 normalTex = texture2D( tNormal, vUv ).xyz * 2.0 - 1.0;",
+				"normalTex.xy *= uNormalScale;",
+				"normalTex = normalize( normalTex );",
+
 				"vec3 finalNormal = tsb * normalTex;",
 
 				"vec3 normal = normalize( finalNormal );",
-				"vec3 viewPosition = normalize( vViewPosition );",
+				"vec3 viewerDirection = normalize( vViewPosition );",
 
 				// point lights
 
@@ -478,14 +491,19 @@ THREE.ShaderSkin = {
 					"for ( int i = 0; i < MAX_POINT_LIGHTS; i ++ ) {",
 
 						"vec3 pointVector = normalize( vPointLight[ i ].xyz );",
-						"float pointDistance = vPointLight[ i ].w;",
+						"float attenuation = vPointLight[ i ].w;",
 
 						"float pointDiffuseWeight = max( dot( normal, pointVector ), 0.0 );",
 
-						"totalDiffuseLight += pointDistance * pointLightColor[ i ] * pointDiffuseWeight;",
+						"totalDiffuseLight += pointLightColor[ i ] * ( pointDiffuseWeight * attenuation );",
+
+						"if ( passID == 1 ) {",
 
-						"if ( passID == 1 )",
-							"totalSpecularLight += pointDistance * mSpecular.xyz * pointLightColor[ i ] * KS_Skin_Specular( normal, pointVector, viewPosition, uRoughness, uSpecularBrightness );",
+							"float pointSpecularWeight = KS_Skin_Specular( normal, pointVector, viewerDirection, uRoughness, uSpecularBrightness );",
+
+							"totalSpecularLight += pointLightColor[ i ] * mSpecular.xyz * ( pointSpecularWeight * attenuation );",
+
+						"}",
 
 					"}",
 
@@ -497,14 +515,19 @@ THREE.ShaderSkin = {
 
 					"for( int i = 0; i < MAX_DIR_LIGHTS; i++ ) {",
 
-						"vec3 dirVector = transformDirection( directionalLightDirection[ i ], viewMatrix );",
+						"vec3 dirVector = directionalLightDirection[ i ];",
 
 						"float dirDiffuseWeight = max( dot( normal, dirVector ), 0.0 );",
 
 						"totalDiffuseLight += directionalLightColor[ i ] * dirDiffuseWeight;",
 
-						"if ( passID == 1 )",
-							"totalSpecularLight += mSpecular.xyz * directionalLightColor[ i ] * KS_Skin_Specular( normal, dirVector, viewPosition, uRoughness, uSpecularBrightness );",
+						"if ( passID == 1 ) {",
+
+							"float dirSpecularWeight = KS_Skin_Specular( normal, dirVector, viewerDirection, uRoughness, uSpecularBrightness );",
+
+							"totalSpecularLight += directionalLightColor[ i ] * mSpecular.xyz * dirSpecularWeight;",
+
+						"}",
 
 					"}",
 
@@ -572,8 +595,6 @@ THREE.ShaderSkin = {
 
 		vertexShader: [
 
-			"attribute vec4 tangent;",
-
 			"#ifdef VERTEX_TEXTURES",
 
 				"uniform sampler2D tDisplacement;",
@@ -582,8 +603,6 @@ THREE.ShaderSkin = {
 
 			"#endif",
 
-			"varying vec3 vTangent;",
-			"varying vec3 vBinormal;",
 			"varying vec3 vNormal;",
 			"varying vec2 vUv;",
 
@@ -611,13 +630,6 @@ THREE.ShaderSkin = {
 
 				"vNormal = normalize( normalMatrix * normal );",
 
-				// tangent and binormal vectors
-
-				"vTangent = normalize( normalMatrix * tangent.xyz );",
-
-				"vBinormal = cross( vNormal, vTangent ) * tangent.w;",
-				"vBinormal = normalize( vBinormal );",
-
 				"vUv = uv;",
 
 				// point lights
@@ -626,7 +638,7 @@ THREE.ShaderSkin = {
 
 					"for( int i = 0; i < MAX_POINT_LIGHTS; i++ ) {",
 
-						"vec3 lVector = pointLightPosition[ i ] - mvPosition.xyz;",
+						"vec3 lVector = pointLightPosition[ i ] - vViewPosition;",
 
 						"float attenuation = calcLightAttenuation( length( lVector ), pointLightDistance[ i ], pointLightDecay[i] );",
 
@@ -659,18 +671,6 @@ THREE.ShaderSkin = {
 
 		vertexShaderUV: [
 
-			"attribute vec4 tangent;",
-
-			"#ifdef VERTEX_TEXTURES",
-
-				"uniform sampler2D tDisplacement;",
-				"uniform float uDisplacementScale;",
-				"uniform float uDisplacementBias;",
-
-			"#endif",
-
-			"varying vec3 vTangent;",
-			"varying vec3 vBinormal;",
 			"varying vec3 vNormal;",
 			"varying vec2 vUv;",
 
@@ -698,13 +698,6 @@ THREE.ShaderSkin = {
 
 				"vNormal = normalize( normalMatrix * normal );",
 
-				// tangent and binormal vectors
-
-				"vTangent = normalize( normalMatrix * tangent.xyz );",
-
-				"vBinormal = cross( vNormal, vTangent ) * tangent.w;",
-				"vBinormal = normalize( vBinormal );",
-
 				"vUv = uv;",
 
 				// point lights
@@ -713,7 +706,7 @@ THREE.ShaderSkin = {
 
 					"for( int i = 0; i < MAX_POINT_LIGHTS; i++ ) {",
 
-						"vec3 lVector = pointLightPosition[ i ] - mvPosition.xyz;",
+						"vec3 lVector = pointLightPosition[ i ] - vViewPosition;",
 
 						"float attenuation = calcLightAttenuation( length( lVector ), pointLightDistance[ i ], pointLightDecay[i] );",
 

+ 28 - 15
examples/js/WaterShader.js

@@ -9,17 +9,21 @@
 
 THREE.ShaderLib[ 'water' ] = {
 
-	uniforms: { "normalSampler":	{ type: "t", value: null },
-				"mirrorSampler":	{ type: "t", value: null },
-				"alpha":			{ type: "f", value: 1.0 },
-				"time":				{ type: "f", value: 0.0 },
-				"distortionScale":	{ type: "f", value: 20.0 },
-				"textureMatrix" :	{ type: "m4", value: new THREE.Matrix4() },
-				"sunColor":			{ type: "c", value: new THREE.Color( 0x7F7F7F ) },
-				"sunDirection":		{ type: "v3", value: new THREE.Vector3( 0.70707, 0.70707, 0 ) },
-				"eye":				{ type: "v3", value: new THREE.Vector3( 0, 0, 0 ) },
-				"waterColor":		{ type: "c", value: new THREE.Color( 0x555555 ) }
-	},
+	uniforms: THREE.UniformsUtils.merge( [
+		THREE.UniformsLib[ "fog" ], { 
+			"normalSampler":    { type: "t", value: null },
+			"mirrorSampler":    { type: "t", value: null },
+			"alpha":            { type: "f", value: 1.0 },
+			"time":             { type: "f", value: 0.0 },
+			"distortionScale":  { type: "f", value: 20.0 },
+			"noiseScale":       { type: "f", value: 1.0 },
+			"textureMatrix" :   { type: "m4", value: new THREE.Matrix4() },
+			"sunColor":         { type: "c", value: new THREE.Color(0x7F7F7F) },
+			"sunDirection":     { type: "v3", value: new THREE.Vector3(0.70707, 0.70707, 0) },
+			"eye":              { type: "v3", value: new THREE.Vector3(0, 0, 0) },
+			"waterColor":       { type: "c", value: new THREE.Color(0x555555) }
+		}
+	] ),
 
 	vertexShader: [
 		'uniform mat4 textureMatrix;',
@@ -73,7 +77,10 @@ THREE.ShaderLib[ 'water' ] = {
 		'	specularColor += pow( direction, shiny ) * sunColor * spec;',
 		'	diffuseColor += max( dot( sunDirection, surfaceNormal ), 0.0 ) * sunColor * diffuse;',
 		'}',
-		
+
+		THREE.ShaderChunk[ "common" ],
+		THREE.ShaderChunk[ "fog_pars_fragment" ],		
+
 		'void main()',
 		'{',
 		'	vec4 noise = getNoise( worldPosition.xz );',
@@ -96,7 +103,9 @@ THREE.ShaderLib[ 'water' ] = {
 		'	float reflectance = rf0 + ( 1.0 - rf0 ) * pow( ( 1.0 - theta ), 5.0 );',
 		'	vec3 scatter = max( 0.0, dot( surfaceNormal, eyeDirection ) ) * waterColor;',
 		'	vec3 albedo = mix( sunColor * diffuseLight * 0.3 + scatter, ( vec3( 0.1 ) + reflectionSample * 0.9 + reflectionSample * specularLight ), reflectance );',
-		'	gl_FragColor = vec4( albedo, alpha );',
+		'	vec3 outgoingLight = albedo;',
+			THREE.ShaderChunk[ "fog_fragment" ],
+		'	gl_FragColor = vec4( outgoingLight, alpha );',		
 		'}'
 	].join( '\n' )
 
@@ -128,7 +137,9 @@ THREE.Water = function ( renderer, camera, scene, options ) {
 	this.waterColor = new THREE.Color( optionalParameter( options.waterColor, 0x7F7F7F ) );
 	this.eye = optionalParameter( options.eye, new THREE.Vector3( 0, 0, 0 ) );
 	this.distortionScale = optionalParameter( options.distortionScale, 20.0 );
-	
+	this.side = optionalParameter(options.side, THREE.FrontSide);
+	this.fog = optionalParameter(options.fog, false);
+
 	this.renderer = renderer;
 	this.scene = scene;
 	this.mirrorPlane = new THREE.Plane();
@@ -162,7 +173,9 @@ THREE.Water = function ( renderer, camera, scene, options ) {
 		fragmentShader: mirrorShader.fragmentShader, 
 		vertexShader: mirrorShader.vertexShader, 
 		uniforms: mirrorUniforms,
-		transparent: true
+		transparent: true,
+		side: this.side,
+		fog: this.fog		
 	} );
 
 	this.material.uniforms.mirrorSampler.value = this.texture;

+ 5 - 3
examples/js/controls/TransformControls.js

@@ -806,7 +806,7 @@
 
 		function onPointerHover( event ) {
 
-			if ( scope.object === undefined || _dragging === true ) return;
+			if ( scope.object === undefined || _dragging === true || ( event.button !== undefined && event.button !== 0 ) ) return;
 
 			var pointer = event.changedTouches ? event.changedTouches[ 0 ] : event;
 
@@ -834,7 +834,7 @@
 
 		function onPointerDown( event ) {
 
-			if ( scope.object === undefined || _dragging === true ) return;
+			if ( scope.object === undefined || _dragging === true || ( event.button !== undefined && event.button !== 0 ) ) return;
 
 			var pointer = event.changedTouches ? event.changedTouches[ 0 ] : event;
 
@@ -884,7 +884,7 @@
 
 		function onPointerMove( event ) {
 
-			if ( scope.object === undefined || scope.axis === null || _dragging === false ) return;
+			if ( scope.object === undefined || scope.axis === null || _dragging === false || ( event.button !== undefined && event.button !== 0 ) ) return;
 
 			var pointer = event.changedTouches ? event.changedTouches[ 0 ] : event;
 
@@ -1055,6 +1055,8 @@
 
 		function onPointerUp( event ) {
 
+			if ( event.button !== undefined && event.button !== 0 ) return;
+
 			if ( _dragging && ( scope.axis !== null ) ) {
 
 				mouseUpEvent.mode = _mode;

+ 22 - 23
examples/js/geometries/DecalGeometry.js

@@ -27,7 +27,7 @@ THREE.DecalGeometry = function( mesh, position, rotation, dimensions, check ) {
 	this.cube.updateMatrix();
 
 	this.iCubeMatrix = ( new THREE.Matrix4() ).getInverse( this.cube.matrix );
-	
+
 	this.faceIndices = [ 'a', 'b', 'c', 'd' ];
 
 	this.clipFace = function( inVertices, plane ) {
@@ -40,16 +40,16 @@ THREE.DecalGeometry = function( mesh, position, rotation, dimensions, check ) {
 				d1 = v1.vertex.dot( p ) - size;
 
 			var s = d0 / ( d0 - d1 );
-			var v = new THREE.DecalVertex( 
-				new THREE.Vector3( 
+			var v = new THREE.DecalVertex(
+				new THREE.Vector3(
 					v0.vertex.x + s * ( v1.vertex.x - v0.vertex.x ),
 					v0.vertex.y + s * ( v1.vertex.y - v0.vertex.y ),
-					v0.vertex.z + s * ( v1.vertex.z - v0.vertex.z ) 
+					v0.vertex.z + s * ( v1.vertex.z - v0.vertex.z )
 				),
 				new THREE.Vector3(
 					v0.normal.x + s * ( v1.normal.x - v0.normal.x ),
 					v0.normal.y + s * ( v1.normal.y - v0.normal.y ),
-					v0.normal.z + s * ( v1.normal.z - v0.normal.z ) 
+					v0.normal.z + s * ( v1.normal.z - v0.normal.z )
 				)
 			);
 
@@ -91,19 +91,19 @@ THREE.DecalGeometry = function( mesh, position, rotation, dimensions, check ) {
 					var nV1, nV2, nV3;
 					if ( v1Out ) {
 
-						nV1 = inVertices[ j + 1 ]; 
+						nV1 = inVertices[ j + 1 ];
 						nV2 = inVertices[ j + 2 ];
 						nV3 = clip( inVertices[ j ], nV1, plane );
 						nV4 = clip( inVertices[ j ], nV2, plane );
 
 					}
-					if ( v2Out ) { 
+					if ( v2Out ) {
 
-						nV1 = inVertices[ j ]; 
+						nV1 = inVertices[ j ];
 						nV2 = inVertices[ j + 2 ];
 						nV3 = clip( inVertices[ j + 1 ], nV1, plane );
 						nV4 = clip( inVertices[ j + 1 ], nV2, plane );
-						
+
 						outVertices.push( nV3 );
 						outVertices.push( nV2.clone() );
 						outVertices.push( nV1.clone() );
@@ -114,9 +114,9 @@ THREE.DecalGeometry = function( mesh, position, rotation, dimensions, check ) {
 						break;
 
 					}
-					if ( v3Out ) { 
+					if ( v3Out ) {
 
-						nV1 = inVertices[ j ]; 
+						nV1 = inVertices[ j ];
 						nV2 = inVertices[ j + 1 ];
 						nV3 = clip( inVertices[ j + 2 ], nV1, plane );
 						nV4 = clip( inVertices[ j + 2 ], nV2, plane );
@@ -137,17 +137,17 @@ THREE.DecalGeometry = function( mesh, position, rotation, dimensions, check ) {
 				case 2: {
 
 					var nV1, nV2, nV3;
-					if ( ! v1Out ) { 
+					if ( ! v1Out ) {
 
 						nV1 = inVertices[ j ].clone();
 						nV2 = clip( nV1, inVertices[ j + 1 ], plane );
-						nV3 = clip( nV1, inVertices[ j + 2 ], plane ); 
+						nV3 = clip( nV1, inVertices[ j + 2 ], plane );
 						outVertices.push( nV1 );
 						outVertices.push( nV2 );
 						outVertices.push( nV3 );
 
 					}
-					if ( ! v2Out ) { 
+					if ( ! v2Out ) {
 
 						nV1 = inVertices[ j + 1 ].clone();
 						nV2 = clip( nV1, inVertices[ j + 2 ], plane );
@@ -245,30 +245,30 @@ THREE.DecalGeometry = function( mesh, position, rotation, dimensions, check ) {
 		}
 
 		for ( var k = 0; k < finalVertices.length; k += 3 ) {
-			
+
 			this.vertices.push(
 				finalVertices[ k ].vertex,
 				finalVertices[ k + 1 ].vertex,
 				finalVertices[ k + 2 ].vertex
 			);
 
-			var f = new THREE.Face3( 
-				k, 
-				k + 1, 
+			var f = new THREE.Face3(
+				k,
+				k + 1,
 				k + 2
 			);
 			f.vertexNormals.push( finalVertices[ k + 0 ].normal );
 			f.vertexNormals.push( finalVertices[ k + 1 ].normal );
 			f.vertexNormals.push( finalVertices[ k + 2 ].normal );
-			
+
 			this.faces.push( f );
-			
+
 			this.faceVertexUvs[ 0 ].push( [
 				this.uvs[ k ],
-				this.uvs[ k + 1 ], 
+				this.uvs[ k + 1 ],
 				this.uvs[ k + 2 ]
 			] );
-		
+
 		}
 
 		this.verticesNeedUpdate = true;
@@ -277,7 +277,6 @@ THREE.DecalGeometry = function( mesh, position, rotation, dimensions, check ) {
 		this.uvsNeedUpdate = true;
 		this.normalsNeedUpdate = true;
 		this.colorsNeedUpdate = true;
-		this.tangentsNeedUpdate = true;
 		this.computeFaceNormals();
 
 	};

+ 751 - 0
examples/js/geometries/TeapotBufferGeometry.js

@@ -0,0 +1,751 @@
+/**
+ * @author Eric Haines / http://erichaines.com/
+ *
+ * Tessellates the famous Utah teapot database by Martin Newell into triangles.
+ *
+ * THREE.TeapotBufferGeometry = function ( size, segments, bottom, lid, body, fitLid, blinn )
+ *
+ * defaults: size = 50, segments = 10, bottom = true, lid = true, body = true,
+ *   fitLid = false, blinn = true
+ *
+ * size is a relative scale: I've scaled the teapot to fit vertically between -1 and 1.
+ * Think of it as a "radius".
+ * segments - number of line segments to subdivide each patch edge;
+ *   1 is possible but gives degenerates, so two is the real minimum.
+ * bottom - boolean, if true (default) then the bottom patches are added. Some consider
+ *   adding the bottom heresy, so set this to "false" to adhere to the One True Way.
+ * lid - to remove the lid and look inside, set to true.
+ * body - to remove the body and leave the lid, set this and "bottom" to false.
+ * fitLid - the lid is a tad small in the original. This stretches it a bit so you can't
+ *   see the teapot's insides through the gap.
+ * blinn - Jim Blinn scaled the original data vertically by dividing by about 1.3 to look
+ *   nicer. If you want to see the original teapot, similar to the real-world model, set
+ *   this to false. True by default.
+ *   See http://en.wikipedia.org/wiki/File:Original_Utah_Teapot.jpg for the original
+ *   real-world teapot (from http://en.wikipedia.org/wiki/Utah_teapot).
+ *
+ * Note that the bottom (the last four patches) is not flat - blame Frank Crow, not me.
+ *
+ * The teapot should normally be rendered as a double sided object, since for some
+ * patches both sides can be seen, e.g., the gap around the lid and inside the spout.
+ *
+ * Segments 'n' determines the number of triangles output.
+ *   Total triangles = 32*2*n*n - 8*n    [degenerates at the top and bottom cusps are deleted]
+ *
+ *   size_factor   # triangles
+ *       1          56
+ *       2         240
+ *       3         552
+ *       4         992
+ *
+ *      10        6320
+ *      20       25440
+ *      30       57360
+ *
+ * Code converted from my ancient SPD software, http://tog.acm.org/resources/SPD/
+ * Created for the Udacity course "Interactive Rendering", http://bit.ly/ericity
+ * Lesson: https://www.udacity.com/course/viewer#!/c-cs291/l-68866048/m-106482448
+ * YouTube video on teapot history: https://www.youtube.com/watch?v=DxMfblPzFNc
+ *
+ * See https://en.wikipedia.org/wiki/Utah_teapot for the history of the teapot
+ *
+ */
+/*global THREE */
+
+THREE.TeapotBufferGeometry = function ( size, segments, bottom, lid, body, fitLid, blinn ) {
+
+	"use strict";
+
+	// 32 * 4 * 4 Bezier spline patches
+	var teapotPatches = [
+/*rim*/
+0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,
+3,16,17,18,7,19,20,21,11,22,23,24,15,25,26,27,
+18,28,29,30,21,31,32,33,24,34,35,36,27,37,38,39,
+30,40,41,0,33,42,43,4,36,44,45,8,39,46,47,12,
+/*body*/
+12,13,14,15,48,49,50,51,52,53,54,55,56,57,58,59,
+15,25,26,27,51,60,61,62,55,63,64,65,59,66,67,68,
+27,37,38,39,62,69,70,71,65,72,73,74,68,75,76,77,
+39,46,47,12,71,78,79,48,74,80,81,52,77,82,83,56,
+56,57,58,59,84,85,86,87,88,89,90,91,92,93,94,95,
+59,66,67,68,87,96,97,98,91,99,100,101,95,102,103,104,
+68,75,76,77,98,105,106,107,101,108,109,110,104,111,112,113,
+77,82,83,56,107,114,115,84,110,116,117,88,113,118,119,92,
+/*handle*/
+120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,
+123,136,137,120,127,138,139,124,131,140,141,128,135,142,143,132,
+132,133,134,135,144,145,146,147,148,149,150,151,68,152,153,154,
+135,142,143,132,147,155,156,144,151,157,158,148,154,159,160,68,
+/*spout*/
+161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,
+164,177,178,161,168,179,180,165,172,181,182,169,176,183,184,173,
+173,174,175,176,185,186,187,188,189,190,191,192,193,194,195,196,
+176,183,184,173,188,197,198,185,192,199,200,189,196,201,202,193,
+/*lid*/
+203,203,203,203,204,205,206,207,208,208,208,208,209,210,211,212,
+203,203,203,203,207,213,214,215,208,208,208,208,212,216,217,218,
+203,203,203,203,215,219,220,221,208,208,208,208,218,222,223,224,
+203,203,203,203,221,225,226,204,208,208,208,208,224,227,228,209,
+209,210,211,212,229,230,231,232,233,234,235,236,237,238,239,240,
+212,216,217,218,232,241,242,243,236,244,245,246,240,247,248,249,
+218,222,223,224,243,250,251,252,246,253,254,255,249,256,257,258,
+224,227,228,209,252,259,260,229,255,261,262,233,258,263,264,237,
+/*bottom*/
+265,265,265,265,266,267,268,269,270,271,272,273,92,119,118,113,
+265,265,265,265,269,274,275,276,273,277,278,279,113,112,111,104,
+265,265,265,265,276,280,281,282,279,283,284,285,104,103,102,95,
+265,265,265,265,282,286,287,266,285,288,289,270,95,94,93,92
+	] ;
+
+	var teapotVertices = [
+1.4,0,2.4,
+1.4,-0.784,2.4,
+0.784,-1.4,2.4,
+0,-1.4,2.4,
+1.3375,0,2.53125,
+1.3375,-0.749,2.53125,
+0.749,-1.3375,2.53125,
+0,-1.3375,2.53125,
+1.4375,0,2.53125,
+1.4375,-0.805,2.53125,
+0.805,-1.4375,2.53125,
+0,-1.4375,2.53125,
+1.5,0,2.4,
+1.5,-0.84,2.4,
+0.84,-1.5,2.4,
+0,-1.5,2.4,
+-0.784,-1.4,2.4,
+-1.4,-0.784,2.4,
+-1.4,0,2.4,
+-0.749,-1.3375,2.53125,
+-1.3375,-0.749,2.53125,
+-1.3375,0,2.53125,
+-0.805,-1.4375,2.53125,
+-1.4375,-0.805,2.53125,
+-1.4375,0,2.53125,
+-0.84,-1.5,2.4,
+-1.5,-0.84,2.4,
+-1.5,0,2.4,
+-1.4,0.784,2.4,
+-0.784,1.4,2.4,
+0,1.4,2.4,
+-1.3375,0.749,2.53125,
+-0.749,1.3375,2.53125,
+0,1.3375,2.53125,
+-1.4375,0.805,2.53125,
+-0.805,1.4375,2.53125,
+0,1.4375,2.53125,
+-1.5,0.84,2.4,
+-0.84,1.5,2.4,
+0,1.5,2.4,
+0.784,1.4,2.4,
+1.4,0.784,2.4,
+0.749,1.3375,2.53125,
+1.3375,0.749,2.53125,
+0.805,1.4375,2.53125,
+1.4375,0.805,2.53125,
+0.84,1.5,2.4,
+1.5,0.84,2.4,
+1.75,0,1.875,
+1.75,-0.98,1.875,
+0.98,-1.75,1.875,
+0,-1.75,1.875,
+2,0,1.35,
+2,-1.12,1.35,
+1.12,-2,1.35,
+0,-2,1.35,
+2,0,0.9,
+2,-1.12,0.9,
+1.12,-2,0.9,
+0,-2,0.9,
+-0.98,-1.75,1.875,
+-1.75,-0.98,1.875,
+-1.75,0,1.875,
+-1.12,-2,1.35,
+-2,-1.12,1.35,
+-2,0,1.35,
+-1.12,-2,0.9,
+-2,-1.12,0.9,
+-2,0,0.9,
+-1.75,0.98,1.875,
+-0.98,1.75,1.875,
+0,1.75,1.875,
+-2,1.12,1.35,
+-1.12,2,1.35,
+0,2,1.35,
+-2,1.12,0.9,
+-1.12,2,0.9,
+0,2,0.9,
+0.98,1.75,1.875,
+1.75,0.98,1.875,
+1.12,2,1.35,
+2,1.12,1.35,
+1.12,2,0.9,
+2,1.12,0.9,
+2,0,0.45,
+2,-1.12,0.45,
+1.12,-2,0.45,
+0,-2,0.45,
+1.5,0,0.225,
+1.5,-0.84,0.225,
+0.84,-1.5,0.225,
+0,-1.5,0.225,
+1.5,0,0.15,
+1.5,-0.84,0.15,
+0.84,-1.5,0.15,
+0,-1.5,0.15,
+-1.12,-2,0.45,
+-2,-1.12,0.45,
+-2,0,0.45,
+-0.84,-1.5,0.225,
+-1.5,-0.84,0.225,
+-1.5,0,0.225,
+-0.84,-1.5,0.15,
+-1.5,-0.84,0.15,
+-1.5,0,0.15,
+-2,1.12,0.45,
+-1.12,2,0.45,
+0,2,0.45,
+-1.5,0.84,0.225,
+-0.84,1.5,0.225,
+0,1.5,0.225,
+-1.5,0.84,0.15,
+-0.84,1.5,0.15,
+0,1.5,0.15,
+1.12,2,0.45,
+2,1.12,0.45,
+0.84,1.5,0.225,
+1.5,0.84,0.225,
+0.84,1.5,0.15,
+1.5,0.84,0.15,
+-1.6,0,2.025,
+-1.6,-0.3,2.025,
+-1.5,-0.3,2.25,
+-1.5,0,2.25,
+-2.3,0,2.025,
+-2.3,-0.3,2.025,
+-2.5,-0.3,2.25,
+-2.5,0,2.25,
+-2.7,0,2.025,
+-2.7,-0.3,2.025,
+-3,-0.3,2.25,
+-3,0,2.25,
+-2.7,0,1.8,
+-2.7,-0.3,1.8,
+-3,-0.3,1.8,
+-3,0,1.8,
+-1.5,0.3,2.25,
+-1.6,0.3,2.025,
+-2.5,0.3,2.25,
+-2.3,0.3,2.025,
+-3,0.3,2.25,
+-2.7,0.3,2.025,
+-3,0.3,1.8,
+-2.7,0.3,1.8,
+-2.7,0,1.575,
+-2.7,-0.3,1.575,
+-3,-0.3,1.35,
+-3,0,1.35,
+-2.5,0,1.125,
+-2.5,-0.3,1.125,
+-2.65,-0.3,0.9375,
+-2.65,0,0.9375,
+-2,-0.3,0.9,
+-1.9,-0.3,0.6,
+-1.9,0,0.6,
+-3,0.3,1.35,
+-2.7,0.3,1.575,
+-2.65,0.3,0.9375,
+-2.5,0.3,1.125,
+-1.9,0.3,0.6,
+-2,0.3,0.9,
+1.7,0,1.425,
+1.7,-0.66,1.425,
+1.7,-0.66,0.6,
+1.7,0,0.6,
+2.6,0,1.425,
+2.6,-0.66,1.425,
+3.1,-0.66,0.825,
+3.1,0,0.825,
+2.3,0,2.1,
+2.3,-0.25,2.1,
+2.4,-0.25,2.025,
+2.4,0,2.025,
+2.7,0,2.4,
+2.7,-0.25,2.4,
+3.3,-0.25,2.4,
+3.3,0,2.4,
+1.7,0.66,0.6,
+1.7,0.66,1.425,
+3.1,0.66,0.825,
+2.6,0.66,1.425,
+2.4,0.25,2.025,
+2.3,0.25,2.1,
+3.3,0.25,2.4,
+2.7,0.25,2.4,
+2.8,0,2.475,
+2.8,-0.25,2.475,
+3.525,-0.25,2.49375,
+3.525,0,2.49375,
+2.9,0,2.475,
+2.9,-0.15,2.475,
+3.45,-0.15,2.5125,
+3.45,0,2.5125,
+2.8,0,2.4,
+2.8,-0.15,2.4,
+3.2,-0.15,2.4,
+3.2,0,2.4,
+3.525,0.25,2.49375,
+2.8,0.25,2.475,
+3.45,0.15,2.5125,
+2.9,0.15,2.475,
+3.2,0.15,2.4,
+2.8,0.15,2.4,
+0,0,3.15,
+0.8,0,3.15,
+0.8,-0.45,3.15,
+0.45,-0.8,3.15,
+0,-0.8,3.15,
+0,0,2.85,
+0.2,0,2.7,
+0.2,-0.112,2.7,
+0.112,-0.2,2.7,
+0,-0.2,2.7,
+-0.45,-0.8,3.15,
+-0.8,-0.45,3.15,
+-0.8,0,3.15,
+-0.112,-0.2,2.7,
+-0.2,-0.112,2.7,
+-0.2,0,2.7,
+-0.8,0.45,3.15,
+-0.45,0.8,3.15,
+0,0.8,3.15,
+-0.2,0.112,2.7,
+-0.112,0.2,2.7,
+0,0.2,2.7,
+0.45,0.8,3.15,
+0.8,0.45,3.15,
+0.112,0.2,2.7,
+0.2,0.112,2.7,
+0.4,0,2.55,
+0.4,-0.224,2.55,
+0.224,-0.4,2.55,
+0,-0.4,2.55,
+1.3,0,2.55,
+1.3,-0.728,2.55,
+0.728,-1.3,2.55,
+0,-1.3,2.55,
+1.3,0,2.4,
+1.3,-0.728,2.4,
+0.728,-1.3,2.4,
+0,-1.3,2.4,
+-0.224,-0.4,2.55,
+-0.4,-0.224,2.55,
+-0.4,0,2.55,
+-0.728,-1.3,2.55,
+-1.3,-0.728,2.55,
+-1.3,0,2.55,
+-0.728,-1.3,2.4,
+-1.3,-0.728,2.4,
+-1.3,0,2.4,
+-0.4,0.224,2.55,
+-0.224,0.4,2.55,
+0,0.4,2.55,
+-1.3,0.728,2.55,
+-0.728,1.3,2.55,
+0,1.3,2.55,
+-1.3,0.728,2.4,
+-0.728,1.3,2.4,
+0,1.3,2.4,
+0.224,0.4,2.55,
+0.4,0.224,2.55,
+0.728,1.3,2.55,
+1.3,0.728,2.55,
+0.728,1.3,2.4,
+1.3,0.728,2.4,
+0,0,0,
+1.425,0,0,
+1.425,0.798,0,
+0.798,1.425,0,
+0,1.425,0,
+1.5,0,0.075,
+1.5,0.84,0.075,
+0.84,1.5,0.075,
+0,1.5,0.075,
+-0.798,1.425,0,
+-1.425,0.798,0,
+-1.425,0,0,
+-0.84,1.5,0.075,
+-1.5,0.84,0.075,
+-1.5,0,0.075,
+-1.425,-0.798,0,
+-0.798,-1.425,0,
+0,-1.425,0,
+-1.5,-0.84,0.075,
+-0.84,-1.5,0.075,
+0,-1.5,0.075,
+0.798,-1.425,0,
+1.425,-0.798,0,
+0.84,-1.5,0.075,
+1.5,-0.84,0.075
+	] ;
+
+	THREE.BufferGeometry.call( this );
+
+	this.type = 'TeapotBufferGeometry';
+
+	this.parameters = {
+		size: size,
+		segments: segments,
+		bottom: bottom,
+		lid: lid,
+		body: body,
+		fitLid: fitLid,
+		blinn: blinn
+	};
+
+	size = size || 50;
+
+	// number of segments per patch
+	segments = segments !== undefined ? Math.max( 2, Math.floor( segments ) || 10 ) : 10;
+
+	// which parts should be visible
+	bottom = bottom === undefined ? true : bottom;
+	lid = lid === undefined ? true : lid;
+	body = body === undefined ? true : body;
+
+	// Should the lid be snug? It's not traditional, so off by default
+	fitLid = fitLid === undefined ? false : fitLid;
+
+	// Jim Blinn scaled the teapot down in size by about 1.3 for
+	// some rendering tests. He liked the new proportions that he kept
+	// the data in this form. The model was distributed with these new
+	// proportions and became the norm. Trivia: comparing images of the
+	// real teapot and the computer model, the ratio for the bowl of the
+	// real teapot is more like 1.25, but since 1.3 is the traditional
+	// value given, we use it here.
+	var blinnScale = 1.3;
+	blinn = blinn === undefined ? true : blinn;
+
+	// scale the size to be the real scaling factor
+	var maxHeight = 3.15 * ( blinn ? 1 : blinnScale );
+
+	var maxHeight2 = maxHeight / 2;
+	var trueSize = size / maxHeight2;
+
+	// Number of elements depends on what is needed. Subtract degenerate
+	// triangles at tip of bottom and lid out in advance.
+	var numTriangles = bottom ? ( 8 * segments - 4 ) * segments : 0;
+	numTriangles += lid ? ( 16 * segments - 4 ) * segments : 0;
+	numTriangles += body ? 40 * segments * segments : 0;
+
+	var indices = new Uint32Array( numTriangles * 3 );
+
+	var numVertices = bottom ? 4 : 0;
+	numVertices += lid ? 8 : 0;
+	numVertices += body ? 20 : 0;
+	numVertices *= ( segments + 1 ) * ( segments + 1 );
+
+	var vertices = new Float32Array( numVertices * 3 );
+	var normals = new Float32Array( numVertices * 3 );
+	var uvs = new Float32Array( numVertices * 2 );
+
+	// Bezier form
+	var ms = new THREE.Matrix4();
+	ms.set( -1.0,  3.0, -3.0,  1.0,
+			 3.0, -6.0,  3.0,  0.0,
+			-3.0,  3.0,  0.0,  0.0,
+			 1.0,  0.0,  0.0,  0.0 ) ;
+
+	var g = [];
+	var i, r, c;
+
+	var sp = [];
+	var tp = [];
+	var dsp = [];
+	var dtp = [];
+
+	// M * G * M matrix, sort of see
+	// http://www.cs.helsinki.fi/group/goa/mallinnus/curves/surfaces.html
+	var mgm = [];
+
+	var vert = [];
+	var sdir = [];
+	var tdir = [];
+
+	var norm = new THREE.Vector3();
+
+	var tcoord;
+
+	var sstep, tstep;
+	var vertPerRow, eps;
+
+	var s, t, sval, tval, p, dsval, dtval;
+
+	var normOut = new THREE.Vector3();
+	var v1, v2, v3, v4;
+
+	var gmx = new THREE.Matrix4();
+	var tmtx = new THREE.Matrix4();
+
+	var vsp = new THREE.Vector4();
+	var vtp = new THREE.Vector4();
+	var vdsp = new THREE.Vector4();
+	var vdtp = new THREE.Vector4();
+
+	var vsdir = new THREE.Vector3();
+	var vtdir = new THREE.Vector3();
+
+	var mst = ms.clone();
+	mst.transpose();
+
+	// internal function: test if triangle has any matching vertices;
+	// if so, don't save triangle, since it won't display anything.
+	var notDegenerate = function ( vtx1, vtx2, vtx3 ) {
+
+		// if any vertex matches, return false
+		return ! ( ( ( vertices[ vtx1 * 3 ]     === vertices[ vtx2 * 3 ] ) &&
+					 ( vertices[ vtx1 * 3 + 1 ] === vertices[ vtx2 * 3 + 1 ] ) &&
+					 ( vertices[ vtx1 * 3 + 2 ] === vertices[ vtx2 * 3 + 2 ] ) ) ||
+				   ( ( vertices[ vtx1 * 3 ]     === vertices[ vtx3 * 3 ] ) &&
+					 ( vertices[ vtx1 * 3 + 1 ] === vertices[ vtx3 * 3 + 1 ] ) &&
+					 ( vertices[ vtx1 * 3 + 2 ] === vertices[ vtx3 * 3 + 2 ] ) ) ||
+				   ( ( vertices[ vtx2 * 3 ]     === vertices[ vtx3 * 3 ] ) &&
+					 ( vertices[ vtx2 * 3 + 1 ] === vertices[ vtx3 * 3 + 1 ] ) &&
+					 ( vertices[ vtx2 * 3 + 2 ] === vertices[ vtx3 * 3 + 2 ] ) ) );
+
+	};
+
+
+	for ( i = 0; i < 3; i ++ )
+	{
+
+		mgm[ i ] = new THREE.Matrix4();
+
+	}
+
+	var minPatches = body ? 0 : 20;
+	var maxPatches = bottom ? 32 : 28;
+
+	vertPerRow = segments + 1;
+
+	eps = 0.0000001;
+
+	var surfCount = 0;
+
+	var vertCount = 0;
+	var normCount = 0;
+	var uvCount = 0;
+
+	var indexCount = 0;
+
+	for ( var surf = minPatches ; surf < maxPatches ; surf ++ ) {
+
+		// lid is in the middle of the data, patches 20-27,
+		// so ignore it for this part of the loop if the lid is not desired
+		if ( lid || ( surf < 20 || surf >= 28 ) ) {
+
+			// get M * G * M matrix for x,y,z
+			for ( i = 0 ; i < 3 ; i ++ ) {
+
+				// get control patches
+				for ( r = 0 ; r < 4 ; r ++ ) {
+
+					for ( c = 0 ; c < 4 ; c ++ ) {
+
+						// transposed
+						g[ c * 4 + r ] = teapotVertices[ teapotPatches[ surf * 16 + r * 4 + c ] * 3 + i ] ;
+
+						// is the lid to be made larger, and is this a point on the lid
+						// that is X or Y?
+						if ( fitLid && ( surf >= 20 && surf < 28 ) && ( i !== 2 ) ) {
+
+							// increase XY size by 7.7%, found empirically. I don't
+							// increase Z so that the teapot will continue to fit in the
+							// space -1 to 1 for Y (Y is up for the final model).
+							g[ c * 4 + r ] *= 1.077;
+
+						}
+
+						// Blinn "fixed" the teapot by dividing Z by blinnScale, and that's the
+						// data we now use. The original teapot is taller. Fix it:
+						if ( ! blinn && ( i === 2 ) ) {
+
+							g[ c * 4 + r ] *= blinnScale;
+
+						}
+
+					}
+
+				}
+
+				gmx.set( g[ 0 ], g[ 1 ], g[ 2 ], g[ 3 ], g[ 4 ], g[ 5 ], g[ 6 ], g[ 7 ], g[ 8 ], g[ 9 ], g[ 10 ], g[ 11 ], g[ 12 ], g[ 13 ], g[ 14 ], g[ 15 ] );
+
+				tmtx.multiplyMatrices( gmx, ms );
+				mgm[ i ].multiplyMatrices( mst, tmtx );
+
+			}
+
+			// step along, get points, and output
+			for ( sstep = 0 ; sstep <= segments ; sstep ++ ) {
+
+				s = sstep / segments;
+
+				for ( tstep = 0 ; tstep <= segments ; tstep ++ ) {
+
+					t = tstep / segments;
+
+					// point from basis
+					// get power vectors and their derivatives
+					for ( p = 4, sval = tval = 1.0 ; p -- ; ) {
+
+						sp[ p ] = sval ;
+						tp[ p ] = tval ;
+						sval *= s ;
+						tval *= t ;
+
+						if ( p === 3 ) {
+
+							dsp[ p ] = dtp[ p ] = 0.0 ;
+							dsval = dtval = 1.0 ;
+
+						} else {
+
+							dsp[ p ] = dsval * ( 3 - p ) ;
+							dtp[ p ] = dtval * ( 3 - p ) ;
+							dsval *= s ;
+							dtval *= t ;
+
+						}
+
+					}
+
+					vsp.fromArray( sp );
+					vtp.fromArray( tp );
+					vdsp.fromArray( dsp );
+					vdtp.fromArray( dtp );
+
+					// do for x,y,z
+					for ( i = 0 ; i < 3 ; i ++ ) {
+
+						// multiply power vectors times matrix to get value
+						tcoord = vsp.clone();
+						tcoord.applyMatrix4( mgm[ i ] );
+						vert[ i ] = tcoord.dot( vtp );
+
+						// get s and t tangent vectors
+						tcoord = vdsp.clone();
+						tcoord.applyMatrix4( mgm[ i ] );
+						sdir[ i ] = tcoord.dot( vtp ) ;
+
+						tcoord = vsp.clone();
+						tcoord.applyMatrix4( mgm[ i ] );
+						tdir[ i ] = tcoord.dot( vdtp ) ;
+
+					}
+
+					// find normal
+					vsdir.fromArray( sdir );
+					vtdir.fromArray( tdir );
+					norm.crossVectors( vtdir, vsdir );
+					norm.normalize();
+
+					// if X and Z length is 0, at the cusp, so point the normal up or down, depending on patch number
+					if ( vert[ 0 ] === 0 && vert[ 1 ] === 0 )
+					{
+
+						// if above the middle of the teapot, normal points up, else down
+						normOut.set( 0, vert[ 2 ] > maxHeight2 ? 1 : - 1, 0 );
+
+					}
+					else
+					{
+
+						// standard output: rotate on X axis
+						normOut.set( norm.x, norm.z, - norm.y );
+
+					}
+
+					// store it all
+					vertices[ vertCount ++ ] = trueSize * vert[ 0 ];
+					vertices[ vertCount ++ ] = trueSize * ( vert[ 2 ] - maxHeight2 );
+					vertices[ vertCount ++ ] = - trueSize * vert[ 1 ];
+
+					normals[ normCount ++ ] = normOut.x;
+					normals[ normCount ++ ] = normOut.y;
+					normals[ normCount ++ ] = normOut.z;
+
+					uvs[ uvCount ++ ] = 1 - t;
+					uvs[ uvCount ++ ] = 1 - s;
+
+				}
+
+			}
+
+			// save the faces
+			for ( sstep = 0 ; sstep < segments ; sstep ++ ) {
+
+				for ( tstep = 0 ; tstep < segments ; tstep ++ ) {
+
+					v1 = surfCount * vertPerRow * vertPerRow + sstep * vertPerRow + tstep;
+					v2 = v1 + 1;
+					v3 = v2 + vertPerRow;
+					v4 = v1 + vertPerRow;
+
+					// Normals and UVs cannot be shared. Without clone(), you can see the consequences
+					// of sharing if you call geometry.applyMatrix( matrix ).
+					if ( notDegenerate ( v1, v2, v3 ) ) {
+
+						indices[ indexCount ++ ] = v1;
+						indices[ indexCount ++ ] = v2;
+						indices[ indexCount ++ ] = v3;
+
+					}
+					if ( notDegenerate ( v1, v3, v4 ) ) {
+
+						indices[ indexCount ++ ] = v1;
+						indices[ indexCount ++ ] = v3;
+						indices[ indexCount ++ ] = v4;
+
+					}
+
+				}
+
+			}
+
+			// increment only if a surface was used
+			surfCount ++;
+
+		}
+
+	}
+
+	this.addIndex( new THREE.BufferAttribute( indices, 1 ) );
+	this.addAttribute( 'position', new THREE.BufferAttribute( vertices, 3 ) );
+	this.addAttribute( 'normal', new THREE.BufferAttribute( normals, 3 ) );
+	this.addAttribute( 'uv', new THREE.BufferAttribute( uvs, 2 ) );
+
+	this.computeBoundingSphere();
+
+};
+
+
+THREE.TeapotBufferGeometry.prototype = Object.create( THREE.BufferGeometry.prototype );
+THREE.TeapotBufferGeometry.prototype.constructor = THREE.TeapotBufferGeometry;
+
+THREE.TeapotBufferGeometry.prototype.clone = function () {
+
+	var bufferGeometry = new THREE.TeapotBufferGeometry(
+		this.parameters.size,
+		this.parameters.segments,
+		this.parameters.bottom,
+		this.parameters.lid,
+		this.parameters.body,
+		this.parameters.fitLid,
+		this.parameters.blinn
+	);
+
+	return bufferGeometry;
+
+};

+ 0 - 2
examples/js/loaders/AssimpJSONLoader.js

@@ -212,10 +212,8 @@ THREE.AssimpJSONLoader.prototype = {
 
 		//geometry.computeFaceNormals();
 		//geometry.computeVertexNormals();
-		//geometry.computeTangents();
 		geometry.computeBoundingSphere();
 
-		// TODO: tangents
 		return geometry;
 
 	},

+ 0 - 2
examples/js/loaders/BinaryLoader.js

@@ -686,8 +686,6 @@ THREE.BinaryLoader.prototype = {
 		var geometry = new Model( texturePath );
 		var materials = THREE.Loader.prototype.initMaterials( jsonMaterials, texturePath, this.crossOrigin );
 
-		if ( THREE.Loader.prototype.needsTangents( materials ) ) geometry.computeTangents();
-
 		callback( geometry, materials );
 
 	}

+ 23 - 15
examples/js/loaders/DDSLoader.js

@@ -16,7 +16,7 @@ THREE.DDSLoader.parse = function ( buffer, loadMipmaps ) {
 	var dds = { mipmaps: [], width: 0, height: 0, format: null, mipmapCount: 1 };
 
 	// Adapted from @toji's DDS utils
-	//	https://github.com/toji/webgl-texture-utils/blob/master/texture-util/dds.js
+	// https://github.com/toji/webgl-texture-utils/blob/master/texture-util/dds.js
 
 	// All values and structures referenced from:
 	// http://msdn.microsoft.com/en-us/library/bb943991.aspx/
@@ -175,9 +175,9 @@ THREE.DDSLoader.parse = function ( buffer, loadMipmaps ) {
 
 		default:
 
-			if ( header[ off_RGBBitCount ] == 32 
+			if ( header[ off_RGBBitCount ] === 32
 				&& header[ off_RBitMask ] & 0xff0000
-				&& header[ off_GBitMask ] & 0xff00 
+				&& header[ off_GBitMask ] & 0xff00
 				&& header[ off_BBitMask ] & 0xff
 				&& header[ off_ABitMask ] & 0xff000000  ) {
 
@@ -201,9 +201,21 @@ THREE.DDSLoader.parse = function ( buffer, loadMipmaps ) {
 
 	}
 
-	//TODO: Verify that all faces of the cubemap are present with DDSCAPS2_CUBEMAP_POSITIVEX, etc.
+	var caps2 = header[ off_caps2 ];
+	dds.isCubemap = caps2 & DDSCAPS2_CUBEMAP ? true : false;
+	if ( dds.isCubemap && (
+		! ( caps2 & DDSCAPS2_CUBEMAP_POSITIVEX ) ||
+		! ( caps2 & DDSCAPS2_CUBEMAP_NEGATIVEX ) ||
+		! ( caps2 & DDSCAPS2_CUBEMAP_POSITIVEY ) ||
+		! ( caps2 & DDSCAPS2_CUBEMAP_NEGATIVEY ) ||
+		! ( caps2 & DDSCAPS2_CUBEMAP_POSITIVEZ ) ||
+		! ( caps2 & DDSCAPS2_CUBEMAP_NEGATIVEZ )
+		) ) {
+
+		console.error( 'THREE.DDSLoader.parse: Incomplete cubemap faces' );
+		return dds;
 
-	dds.isCubemap = header[ off_caps2 ] & DDSCAPS2_CUBEMAP ? true : false;
+	}
 
 	dds.width = header[ off_width ];
 	dds.height = header[ off_height ];
@@ -212,13 +224,13 @@ THREE.DDSLoader.parse = function ( buffer, loadMipmaps ) {
 
 	// Extract mipmaps buffers
 
-	var width = dds.width;
-	var height = dds.height;
-
 	var faces = dds.isCubemap ? 6 : 1;
 
 	for ( var face = 0; face < faces; face ++ ) {
 
+		var width = dds.width;
+		var height = dds.height;
+
 		for ( var i = 0; i < dds.mipmapCount; i ++ ) {
 
 			if ( isRGBAUncompressed ) {
@@ -232,23 +244,19 @@ THREE.DDSLoader.parse = function ( buffer, loadMipmaps ) {
 				var byteArray = new Uint8Array( buffer, dataOffset, dataLength );
 
 			}
-			
+
 			var mipmap = { "data": byteArray, "width": width, "height": height };
 			dds.mipmaps.push( mipmap );
 
 			dataOffset += dataLength;
 
-			width = Math.max( width * 0.5, 1 );
-			height = Math.max( height * 0.5, 1 );
+			width = Math.max( width >> 1, 1 );
+			height = Math.max( height >> 1, 1 );
 
 		}
 
-		width = dds.width;
-		height = dds.height;
-
 	}
 
 	return dds;
 
 };
-

+ 1 - 27
examples/js/loaders/deprecated/SceneLoader.js

@@ -218,10 +218,7 @@ THREE.SceneLoader.prototype = {
 
 						if ( geometry ) {
 
-							var needsTangents = false;
-
 							material = result.materials[ objJSON.material ];
-							needsTangents = material instanceof THREE.ShaderMaterial;
 
 							pos = objJSON.position;
 							rot = objJSON.rotation;
@@ -248,22 +245,6 @@ THREE.SceneLoader.prototype = {
 
 							}
 
-							if ( material instanceof THREE.MeshFaceMaterial ) {
-
-								for ( var i = 0; i < material.materials.length; i ++ ) {
-
-									needsTangents = needsTangents || ( material.materials[ i ] instanceof THREE.ShaderMaterial );
-
-								}
-
-							}
-
-							if ( needsTangents ) {
-
-								geometry.computeTangents();
-
-							}
-
 							if ( objJSON.skin ) {
 
 								object = new THREE.SkinnedMesh( geometry, material );
@@ -346,7 +327,7 @@ THREE.SceneLoader.prototype = {
 
 					} else if ( objJSON.type === "AmbientLight" || objJSON.type === "PointLight" ||
 						objJSON.type === "DirectionalLight" || objJSON.type === "SpotLight" ||
-						objJSON.type === "HemisphereLight" || objJSON.type === "AreaLight" ) {
+						objJSON.type === "HemisphereLight" ) {
 
 						var color = objJSON.color;
 						var intensity = objJSON.intensity;
@@ -384,13 +365,6 @@ THREE.SceneLoader.prototype = {
 								light.target.applyEuler( new THREE.Euler( rotation[ 0 ], rotation[ 1 ], rotation[ 2 ], 'XYZ' ) );
 								break;
 
-							case 'AreaLight':
-								light = new THREE.AreaLight( color, intensity );
-								light.position.fromArray( position );
-								light.width = objJSON.size;
-								light.height = objJSON.size_y;
-								break;
-
 						}
 
 						parent.add( light );

File diff suppressed because it is too large
+ 506 - 329
examples/js/loaders/sea3d/SEA3D.js


+ 11 - 12
examples/js/loaders/sea3d/SEA3DDeflate.js

@@ -318,7 +318,6 @@ var zip_GET_BYTE = function() {
     if(zip_inflate_data.length == zip_inflate_pos)
 	return -1;
 	return zip_inflate_data[zip_inflate_pos++];
-    //return zip_inflate_data.charCodeAt(zip_inflate_pos++) & 0xff;
 }
 
 var zip_NEEDBITS = function(n) {
@@ -730,11 +729,11 @@ var zip_inflate_internal = function(buff, off, size) {
     return n;
 }
 
-var zip_inflate = function(str) {
+var zip_inflate = function(data) {
     var i, j, pos = 0;
 
     zip_inflate_start();
-    zip_inflate_data = str;
+    zip_inflate_data = new Uint8Array(data);
     zip_inflate_pos = 0;
 	
     var buff = new Uint8Array(1024);
@@ -745,7 +744,7 @@ var zip_inflate = function(str) {
 			out[pos++] = buff[j];		    
 	
     zip_inflate_data = null; // G.C.
-    return new Uint8Array(out);
+    return new Uint8Array(out).buffer;
 }
 
 if (! ctx.RawDeflate) ctx.RawDeflate = {};
@@ -754,14 +753,14 @@ ctx.RawDeflate.inflate = zip_inflate;
 })(this);
 
 /**
- * 	SEA3D.js - SEA3D SDK ( Deflate )
- * 	Copyright (C) 2013 Sunag Entertainment 
- * 
- * 	http://code.google.com/p/sea3d/
+ * 	SEA3D DEFLATE
+ * 	@author Sunag / http://www.sunag.com.br/
  */
- 
-SEA3D.File.DeflateUncompress = function(data) {	
-	return RawDeflate.inflate(data);
+
+SEA3D.File.DeflateUncompress = function( data ) {
+
+	return RawDeflate.inflate( data );
+
 }
 
-SEA3D.File.setDecompressionEngine(1, "deflate", SEA3D.File.DeflateUncompress);
+SEA3D.File.setDecompressionEngine( 1, "deflate", SEA3D.File.DeflateUncompress );

+ 25 - 19
examples/js/loaders/sea3d/SEA3DLZMA.js

@@ -561,32 +561,38 @@ LZMA.decompressFile = function(inStream, outStream){
 };
 
 /**
- * 	SEA3D.js - SEA3D SDK ( LZMA )
- * 	Copyright (C) 2013 Sunag Entertainment 
- * 
- * 	http://code.google.com/p/sea3d/
+ * 	SEA3D LZMA
+ * 	@author Sunag / http://www.sunag.com.br/
  */
- 
-SEA3D.File.LZMAUncompress = function(data) {	
+
+SEA3D.File.LZMAUncompress = function( data ) {
+
+	data = new Uint8Array( data );
+
 	var inStream = {
-		data:data,
-		position:0,
-		readByte:function(){
-			return this.data[this.position++];
+		data: data,
+		position: 0,
+		readByte: function() {
+
+			return this.data[ this.position ++ ];
+
 		}
 	}
-	
+
 	var outStream = {
-		data:[],
-		position:0,
-		writeByte: function(value){
-			this.data[this.position++] = value;
+		data: [],
+		position: 0,
+		writeByte: function( value ) {
+
+			this.data[ this.position ++ ] = value;
+
 		}
 	}
-	
-	LZMA.decompressFile(inStream, outStream);
 
-	return new Uint8Array(outStream.data);
+	LZMA.decompressFile( inStream, outStream );
+
+	return new Uint8Array( outStream.data ).buffer;
+
 }
 
-SEA3D.File.setDecompressionEngine(2, "lzma", SEA3D.File.LZMAUncompress);
+SEA3D.File.setDecompressionEngine( 2, "lzma", SEA3D.File.LZMAUncompress );

File diff suppressed because it is too large
+ 0 - 13
examples/js/loaders/sea3d/SEA3DLZMA_LZIP.js


File diff suppressed because it is too large
+ 760 - 1087
examples/js/loaders/sea3d/SEA3DLoader.js


+ 0 - 1209
examples/js/renderers/WebGLDeferredRenderer.js

@@ -1,1209 +0,0 @@
-/**
- * @author alteredq / http://alteredqualia.com/
- * @author MPanknin / http://www.redplant.de/
- */
-
-THREE.WebGLDeferredRenderer = function ( parameters ) {
-
-	var _this = this;
-
-	var pixelWidth = parameters.width !== undefined ? parameters.width : 800;
-	var pixelHeight = parameters.height !== undefined ? parameters.height : 600;
-	var currentScale = parameters.scale !== undefined ? parameters.scale : 1;
-
-	var scaledWidth = Math.floor( currentScale * pixelWidth );
-	var scaledHeight = Math.floor( currentScale * pixelHeight );
-
-	var brightness = parameters.brightness !== undefined ? parameters.brightness : 1;
-	var tonemapping = parameters.tonemapping !== undefined ? parameters.tonemapping : THREE.SimpleOperator;
-	var antialias = parameters.antialias !== undefined ? parameters.antialias : false;
-
-	this.renderer = parameters.renderer;
-
-	if ( this.renderer === undefined ) {
-
-		this.renderer = new THREE.WebGLRenderer( { antialias: false } );
-		this.renderer.setSize( pixelWidth, pixelHeight );
-		this.renderer.setClearColor( 0x000000, 0 );
-
-		this.renderer.autoClear = false;
-
-	}
-
-	this.domElement = this.renderer.domElement;
-
-	//
-
-	var gl = this.renderer.context;
-
-	//
-
-	var currentCamera = null;
-	var projectionMatrixInverse = new THREE.Matrix4();
-
-	var positionVS = new THREE.Vector3();
-	var directionVS = new THREE.Vector3();
-	var tempVS = new THREE.Vector3();
-
-	var rightVS = new THREE.Vector3();
-	var normalVS = new THREE.Vector3();
-	var upVS = new THREE.Vector3();
-
-	//
-
-	var geometryLightSphere = new THREE.SphereGeometry( 1, 16, 8 );
-	var geometryLightPlane = new THREE.PlaneBufferGeometry( 2, 2 );
-
-	var black = new THREE.Color( 0x000000 );
-
-	var colorShader = THREE.ShaderDeferred[ "color" ];
-	var normalDepthShader = THREE.ShaderDeferred[ "normalDepth" ];
-
-	//
-
-	var emissiveLightShader = THREE.ShaderDeferred[ "emissiveLight" ];
-	var pointLightShader = THREE.ShaderDeferred[ "pointLight" ];
-	var spotLightShader = THREE.ShaderDeferred[ "spotLight" ];
-	var directionalLightShader = THREE.ShaderDeferred[ "directionalLight" ];
-	var hemisphereLightShader = THREE.ShaderDeferred[ "hemisphereLight" ];
-	var areaLightShader = THREE.ShaderDeferred[ "areaLight" ];
-
-	var compositeShader = THREE.ShaderDeferred[ "composite" ];
-
-	//
-
-	var compColor, compNormal, compDepth, compLight, compFinal;
-	var passColor, passNormal, passDepth, passLightFullscreen, passLightProxy, compositePass;
-
-	var effectFXAA;
-
-	//
-
-	var lightSceneFullscreen, lightSceneProxy;
-
-	//
-
-	var resizableMaterials = [];
-
-	//
-
-	var invisibleMaterial = new THREE.ShaderMaterial();
-	invisibleMaterial.visible = false;
-
-
-	var defaultNormalDepthMaterial = new THREE.ShaderMaterial( {
-
-		uniforms:       THREE.UniformsUtils.clone( normalDepthShader.uniforms ),
-		vertexShader:   normalDepthShader.vertexShader,
-		fragmentShader: normalDepthShader.fragmentShader,
-		blending:       THREE.NoBlending,
-		derivatives:    true
-
-	} );
-
-	//
-
-	var initDeferredMaterials = function ( object ) {
-
-		if ( object.material instanceof THREE.MeshFaceMaterial ) {
-
-			var colorMaterials = [];
-			var normalDepthMaterials = [];
-
-			var materials = object.material.materials;
-
-			for ( var i = 0, il = materials.length; i < il; i ++ ) {
-
-				var deferredMaterials = createDeferredMaterials( materials[ i ] );
-
-				if ( deferredMaterials.transparent ) {
-
-					colorMaterials.push( invisibleMaterial );
-					normalDepthMaterials.push( invisibleMaterial );
-
-				} else {
-
-					colorMaterials.push( deferredMaterials.colorMaterial );
-					normalDepthMaterials.push( deferredMaterials.normalDepthMaterial );
-
-				}
-
-			}
-
-			object.userData.colorMaterial = new THREE.MeshFaceMaterial( colorMaterials );
-			object.userData.normalDepthMaterial = new THREE.MeshFaceMaterial( normalDepthMaterials );
-
-		} else {
-
-			var deferredMaterials = createDeferredMaterials( object.material );
-
-			object.userData.colorMaterial = deferredMaterials.colorMaterial;
-			object.userData.normalDepthMaterial = deferredMaterials.normalDepthMaterial;
-			object.userData.transparent = deferredMaterials.transparent;
-
-		}
-
-	};
-
-	var createDeferredMaterials = function ( originalMaterial ) {
-
-		var deferredMaterials = {};
-
-		// color material
-		// -----------------
-		// 	diffuse color
-		//	specular color
-		//	shininess
-		//	diffuse map
-		//	vertex colors
-		//	alphaTest
-		// 	morphs
-
-		var uniforms = THREE.UniformsUtils.clone( colorShader.uniforms );
-		var defines = { "USE_MAP": !! originalMaterial.map, "USE_ENVMAP": !! originalMaterial.envMap, "GAMMA_INPUT": true };
-
-		var material = new THREE.ShaderMaterial( {
-
-			fragmentShader: colorShader.fragmentShader,
-			vertexShader: 	colorShader.vertexShader,
-			uniforms: 		uniforms,
-			defines: 		defines,
-			shading:		originalMaterial.shading
-
-		} );
-
-		if ( originalMaterial instanceof THREE.MeshBasicMaterial ) {
-
-			var diffuse = black;
-			var emissive = originalMaterial.color;
-
-		} else {
-
-			var diffuse = originalMaterial.color;
-			var emissive = originalMaterial.emissive !== undefined ? originalMaterial.emissive : black;
-
-		}
-
-		var specular = originalMaterial.specular !== undefined ? originalMaterial.specular : black;
-		var shininess = originalMaterial.shininess !== undefined ? originalMaterial.shininess : 1;
-		var wrapAround = originalMaterial.wrapAround !== undefined ? ( originalMaterial.wrapAround ? - 1 : 1 ) : 1;
-		var additiveSpecular = originalMaterial.metal !== undefined ? ( originalMaterial.metal ? 1 : - 1 ) : - 1;
-
-		uniforms.emissive.value.copyGammaToLinear( emissive );
-		uniforms.diffuse.value.copyGammaToLinear( diffuse );
-		uniforms.specular.value.copyGammaToLinear( specular );
-		uniforms.shininess.value = shininess;
-		uniforms.wrapAround.value = wrapAround;
-		uniforms.additiveSpecular.value = additiveSpecular;
-
-		uniforms.map.value = originalMaterial.map;
-
-		if ( originalMaterial.envMap ) {
-
-			uniforms.envMap.value = originalMaterial.envMap;
-			uniforms.refractionRatio.value = originalMaterial.refractionRatio;
-			uniforms.reflectivity.value = originalMaterial.reflectivity;
-			uniforms.flipEnvMap.value = ( originalMaterial.envMap instanceof THREE.WebGLRenderTargetCube ) ? 1 : - 1;
-
-			uniforms.samplerNormalDepth.value = compNormalDepth.renderTarget2;
-			uniforms.viewWidth.value = scaledWidth;
-			uniforms.viewHeight.value = scaledHeight;
-
-			resizableMaterials.push( { "material": material } );
-
-		}
-
-		material.vertexColors = originalMaterial.vertexColors;
-		material.morphTargets = originalMaterial.morphTargets;
-		material.morphNormals = originalMaterial.morphNormals;
-		material.skinning = originalMaterial.skinning;
-
-		material.alphaTest = originalMaterial.alphaTest;
-		material.wireframe = originalMaterial.wireframe;
-
-		// uv repeat and offset setting priorities
-		//	1. color map
-		//	2. specular map
-		//	3. normal map
-		//	4. bump map
-
-		var uvScaleMap;
-
-		if ( originalMaterial.map ) {
-
-			uvScaleMap = originalMaterial.map;
-
-		} else if ( originalMaterial.specularMap ) {
-
-			uvScaleMap = originalMaterial.specularMap;
-
-		} else if ( originalMaterial.normalMap ) {
-
-			uvScaleMap = originalMaterial.normalMap;
-
-		} else if ( originalMaterial.bumpMap ) {
-
-			uvScaleMap = originalMaterial.bumpMap;
-
-		}
-
-		if ( uvScaleMap !== undefined ) {
-
-			var offset = uvScaleMap.offset;
-			var repeat = uvScaleMap.repeat;
-
-			uniforms.offsetRepeat.value.set( offset.x, offset.y, repeat.x, repeat.y );
-
-		}
-
-		deferredMaterials.colorMaterial = material;
-
-		// normal + depth material
-		// -----------------
-		//	vertex normals
-		//	morph normals
-		//	bump map
-		//	bump scale
-		//  clip depth
-
-		if ( originalMaterial.morphTargets || originalMaterial.skinning || originalMaterial.bumpMap ) {
-
-			var uniforms = THREE.UniformsUtils.clone( normalDepthShader.uniforms );
-			var defines = { "USE_BUMPMAP": !! originalMaterial.bumpMap };
-
-			var normalDepthMaterial = new THREE.ShaderMaterial( {
-
-				uniforms:       uniforms,
-				vertexShader:   normalDepthShader.vertexShader,
-				fragmentShader: normalDepthShader.fragmentShader,
-				shading:        originalMaterial.shading,
-				defines:        defines,
-				blending:       THREE.NoBlending,
-				derivatives:    true
-
-			} );
-
-			normalDepthMaterial.morphTargets = originalMaterial.morphTargets;
-			normalDepthMaterial.morphNormals = originalMaterial.morphNormals;
-			normalDepthMaterial.skinning = originalMaterial.skinning;
-
-			if ( originalMaterial.bumpMap ) {
-
-				uniforms.bumpMap.value = originalMaterial.bumpMap;
-				uniforms.bumpScale.value = originalMaterial.bumpScale;
-
-				var offset = originalMaterial.bumpMap.offset;
-				var repeat = originalMaterial.bumpMap.repeat;
-
-				uniforms.offsetRepeat.value.set( offset.x, offset.y, repeat.x, repeat.y );
-
-			}
-
-		} else {
-
-			var normalDepthMaterial = defaultNormalDepthMaterial.clone();
-
-		}
-
-		normalDepthMaterial.wireframe = originalMaterial.wireframe;
-		normalDepthMaterial.vertexColors = originalMaterial.vertexColors;
-
-		deferredMaterials.normalDepthMaterial = normalDepthMaterial;
-
-		//
-
-		deferredMaterials.transparent = originalMaterial.transparent;
-
-		return deferredMaterials;
-
-	};
-
-	var updatePointLightProxy = function ( lightProxy ) {
-
-		var light = lightProxy.userData.originalLight;
-		var uniforms = lightProxy.material.uniforms;
-
-		// skip infinite pointlights
-		// right now you can't switch between infinite and finite pointlights
-		// it's just too messy as they use different proxies
-
-		var distance = light.distance;
-
-		if ( distance > 0 ) {
-
-			lightProxy.scale.set( 1, 1, 1 ).multiplyScalar( distance );
-			uniforms[ "lightRadius" ].value = distance;
-
-			positionVS.setFromMatrixPosition( light.matrixWorld );
-			positionVS.applyMatrix4( currentCamera.matrixWorldInverse );
-
-			uniforms[ "lightPositionVS" ].value.copy( positionVS );
-
-			lightProxy.position.setFromMatrixPosition( light.matrixWorld );
-
-		} else {
-
-			uniforms[ "lightRadius" ].value = Infinity;
-
-		}
-
-		// linear space colors
-
-		var intensity = light.intensity * light.intensity;
-
-		uniforms[ "lightIntensity" ].value = intensity;
-		uniforms[ "lightColor" ].value.copyGammaToLinear( light.color );
-
-	};
-
-	var createDeferredPointLight = function ( light ) {
-
-		// setup light material
-
-		var materialLight = new THREE.ShaderMaterial( {
-
-			uniforms:       THREE.UniformsUtils.clone( pointLightShader.uniforms ),
-			vertexShader:   pointLightShader.vertexShader,
-			fragmentShader: pointLightShader.fragmentShader,
-
-			blending:		THREE.AdditiveBlending,
-			depthWrite:		false,
-			transparent:	true,
-
-			side: THREE.BackSide
-
-		} );
-
-		// infinite pointlights use full-screen quad proxy
-		// regular pointlights use sphere proxy
-
-		var  geometry;
-
-		if ( light.distance > 0 ) {
-
-			geometry = geometryLightSphere;
-
-		} else {
-
-			geometry = geometryLightPlane;
-
-			materialLight.depthTest = false;
-			materialLight.side = THREE.FrontSide;
-
-		}
-
-		materialLight.uniforms[ "viewWidth" ].value = scaledWidth;
-		materialLight.uniforms[ "viewHeight" ].value = scaledHeight;
-
-		materialLight.uniforms[ 'samplerColor' ].value = compColor.renderTarget2;
-		materialLight.uniforms[ 'samplerNormalDepth' ].value = compNormalDepth.renderTarget2;
-
-		// create light proxy mesh
-
-		var meshLight = new THREE.Mesh( geometry, materialLight );
-
-		// keep reference for color and intensity updates
-
-		meshLight.userData.originalLight = light;
-
-		// keep reference for size reset
-
-		resizableMaterials.push( { "material": materialLight } );
-
-		// sync proxy uniforms to the original light
-
-		updatePointLightProxy( meshLight );
-
-		return meshLight;
-
-	};
-
-	var updateSpotLightProxy = function ( lightProxy ) {
-
-		var light = lightProxy.userData.originalLight;
-		var uniforms = lightProxy.material.uniforms;
-
-		var viewMatrix = currentCamera.matrixWorldInverse;
-		var modelMatrix = light.matrixWorld;
-
-		positionVS.setFromMatrixPosition( modelMatrix );
-		positionVS.applyMatrix4( viewMatrix );
-
-		directionVS.setFromMatrixPosition( modelMatrix );
-		tempVS.setFromMatrixPosition( light.target.matrixWorld );
-		directionVS.sub( tempVS );
-		directionVS.normalize();
-		directionVS.transformDirection( viewMatrix );
-
-		uniforms[ "lightPositionVS" ].value.copy( positionVS );
-		uniforms[ "lightDirectionVS" ].value.copy( directionVS );
-
-		uniforms[ "lightAngle" ].value = light.angle;
-		uniforms[ "lightDistance" ].value = light.distance;
-
-		// linear space colors
-
-		var intensity = light.intensity * light.intensity;
-
-		uniforms[ "lightIntensity" ].value = intensity;
-		uniforms[ "lightColor" ].value.copyGammaToLinear( light.color );
-
-	};
-
-	var createDeferredSpotLight = function ( light ) {
-
-		// setup light material
-
-		var uniforms = THREE.UniformsUtils.clone( spotLightShader.uniforms );
-
-		var materialLight = new THREE.ShaderMaterial( {
-
-			uniforms:       uniforms,
-			vertexShader:   spotLightShader.vertexShader,
-			fragmentShader: spotLightShader.fragmentShader,
-
-			blending:		THREE.AdditiveBlending,
-			depthWrite:		false,
-			depthTest:		false,
-			transparent:	true
-
-		} );
-
-		uniforms[ "viewWidth" ].value = scaledWidth;
-		uniforms[ "viewHeight" ].value = scaledHeight;
-
-		uniforms[ 'samplerColor' ].value = compColor.renderTarget2;
-		uniforms[ 'samplerNormalDepth' ].value = compNormalDepth.renderTarget2;
-
-		// create light proxy mesh
-
-		var meshLight = new THREE.Mesh( geometryLightPlane, materialLight );
-
-		// keep reference for color and intensity updates
-
-		meshLight.userData.originalLight = light;
-
-		// keep reference for size reset
-
-		resizableMaterials.push( { "material": materialLight } );
-
-		// sync proxy uniforms to the original light
-
-		updateSpotLightProxy( meshLight );
-
-		return meshLight;
-
-	};
-
-	var updateDirectionalLightProxy = function ( lightProxy ) {
-
-		var light = lightProxy.userData.originalLight;
-		var uniforms = lightProxy.material.uniforms;
-
-		directionVS.setFromMatrixPosition( light.matrixWorld );
-		tempVS.setFromMatrixPosition( light.target.matrixWorld );
-		directionVS.sub( tempVS );
-		directionVS.normalize();
-		directionVS.transformDirection( currentCamera.matrixWorldInverse );
-
-		uniforms[ "lightDirectionVS" ].value.copy( directionVS );
-
-		// linear space colors
-
-		var intensity = light.intensity * light.intensity;
-
-		uniforms[ "lightIntensity" ].value = intensity;
-		uniforms[ "lightColor" ].value.copyGammaToLinear( light.color );
-
-	};
-
-	var createDeferredDirectionalLight = function ( light ) {
-
-		// setup light material
-
-		var uniforms = THREE.UniformsUtils.clone( directionalLightShader.uniforms );
-
-		var materialLight = new THREE.ShaderMaterial( {
-
-			uniforms:       uniforms,
-			vertexShader:   directionalLightShader.vertexShader,
-			fragmentShader: directionalLightShader.fragmentShader,
-
-			blending:		THREE.AdditiveBlending,
-			depthWrite:		false,
-			depthTest:		false,
-			transparent:	true
-
-		} );
-
-		uniforms[ "viewWidth" ].value = scaledWidth;
-		uniforms[ "viewHeight" ].value = scaledHeight;
-
-		uniforms[ 'samplerColor' ].value = compColor.renderTarget2;
-		uniforms[ 'samplerNormalDepth' ].value = compNormalDepth.renderTarget2;
-
-		// create light proxy mesh
-
-		var meshLight = new THREE.Mesh( geometryLightPlane, materialLight );
-
-		// keep reference for color and intensity updates
-
-		meshLight.userData.originalLight = light;
-
-		// keep reference for size reset
-
-		resizableMaterials.push( { "material": materialLight } );
-
-		// sync proxy uniforms to the original light
-
-		updateDirectionalLightProxy( meshLight );
-
-		return meshLight;
-
-	};
-
-	var updateHemisphereLightProxy = function ( lightProxy ) {
-
-		var light = lightProxy.userData.originalLight;
-		var uniforms = lightProxy.material.uniforms;
-
-		directionVS.setFromMatrixPosition( light.matrixWorld );
-		directionVS.normalize();
-		directionVS.transformDirection( currentCamera.matrixWorldInverse );
-
-		uniforms[ "lightDirectionVS" ].value.copy( directionVS );
-
-		// linear space colors
-
-		var intensity = light.intensity * light.intensity;
-
-		uniforms[ "lightIntensity" ].value = intensity;
-		uniforms[ "lightColorSky" ].value.copyGammaToLinear( light.color );
-		uniforms[ "lightColorGround" ].value.copyGammaToLinear( light.groundColor );
-
-	};
-
-	var createDeferredHemisphereLight = function ( light ) {
-
-		// setup light material
-
-		var uniforms = THREE.UniformsUtils.clone( hemisphereLightShader.uniforms );
-
-		var materialLight = new THREE.ShaderMaterial( {
-
-			uniforms:       uniforms,
-			vertexShader:   hemisphereLightShader.vertexShader,
-			fragmentShader: hemisphereLightShader.fragmentShader,
-
-			blending:		THREE.AdditiveBlending,
-			depthWrite:		false,
-			depthTest:		false,
-			transparent:	true
-
-		} );
-
-		uniforms[ "viewWidth" ].value = scaledWidth;
-		uniforms[ "viewHeight" ].value = scaledHeight;
-
-		uniforms[ 'samplerColor' ].value = compColor.renderTarget2;
-		uniforms[ 'samplerNormalDepth' ].value = compNormalDepth.renderTarget2;
-
-		// create light proxy mesh
-
-		var meshLight = new THREE.Mesh( geometryLightPlane, materialLight );
-
-		// keep reference for color and intensity updates
-
-		meshLight.userData.originalLight = light;
-
-		// keep reference for size reset
-
-		resizableMaterials.push( { "material": materialLight } );
-
-		// sync proxy uniforms to the original light
-
-		updateHemisphereLightProxy( meshLight );
-
-		return meshLight;
-
-	};
-
-	var updateAreaLightProxy = function ( lightProxy ) {
-
-		var light = lightProxy.userData.originalLight;
-		var uniforms = lightProxy.material.uniforms;
-
-		var modelMatrix = light.matrixWorld;
-		var viewMatrix = currentCamera.matrixWorldInverse;
-
-		positionVS.setFromMatrixPosition( modelMatrix );
-		positionVS.applyMatrix4( viewMatrix );
-
-		uniforms[ "lightPositionVS" ].value.copy( positionVS );
-
-		rightVS.copy( light.right );
-		rightVS.transformDirection( modelMatrix );
-		rightVS.transformDirection( viewMatrix );
-
-		normalVS.copy( light.normal );
-		normalVS.transformDirection( modelMatrix );
-		normalVS.transformDirection( viewMatrix );
-
-		upVS.crossVectors( rightVS, normalVS );
-		upVS.normalize();
-
-		uniforms[ "lightRightVS" ].value.copy( rightVS );
-		uniforms[ "lightNormalVS" ].value.copy( normalVS );
-		uniforms[ "lightUpVS" ].value.copy( upVS );
-
-		uniforms[ "lightWidth" ].value = light.width;
-		uniforms[ "lightHeight" ].value = light.height;
-
-		uniforms[ "constantAttenuation" ].value = light.constantAttenuation;
-		uniforms[ "linearAttenuation" ].value = light.linearAttenuation;
-		uniforms[ "quadraticAttenuation" ].value = light.quadraticAttenuation;
-
-		// linear space colors
-
-		var intensity = light.intensity * light.intensity;
-
-		uniforms[ "lightIntensity" ].value = intensity;
-		uniforms[ "lightColor" ].value.copyGammaToLinear( light.color );
-
-	};
-
-	var createDeferredAreaLight = function ( light ) {
-
-		// setup light material
-
-		var uniforms = THREE.UniformsUtils.clone( areaLightShader.uniforms );
-
-		var materialLight = new THREE.ShaderMaterial( {
-
-			uniforms:       uniforms,
-			vertexShader:   areaLightShader.vertexShader,
-			fragmentShader: areaLightShader.fragmentShader,
-
-			blending:		THREE.AdditiveBlending,
-			depthWrite:		false,
-			depthTest:		false,
-			transparent:	true
-
-		} );
-
-		uniforms[ "viewWidth" ].value = scaledWidth;
-		uniforms[ "viewHeight" ].value = scaledHeight;
-
-		uniforms[ 'samplerColor' ].value = compColor.renderTarget2;
-		uniforms[ 'samplerNormalDepth' ].value = compNormalDepth.renderTarget2;
-
-		// create light proxy mesh
-
-		var meshLight = new THREE.Mesh( geometryLightPlane, materialLight );
-
-		// keep reference for color and intensity updates
-
-		meshLight.userData.originalLight = light;
-
-		// keep reference for size reset
-
-		resizableMaterials.push( { "material": materialLight } );
-
-		// sync proxy uniforms to the original light
-
-		updateAreaLightProxy( meshLight );
-
-		return meshLight;
-
-	};
-
-	var createDeferredEmissiveLight = function () {
-
-		// setup light material
-
-		var materialLight = new THREE.ShaderMaterial( {
-
-			uniforms:       THREE.UniformsUtils.clone( emissiveLightShader.uniforms ),
-			vertexShader:   emissiveLightShader.vertexShader,
-			fragmentShader: emissiveLightShader.fragmentShader,
-			depthTest:		false,
-			depthWrite:		false,
-			blending:		THREE.NoBlending
-
-		} );
-
-		materialLight.uniforms[ "viewWidth" ].value = scaledWidth;
-		materialLight.uniforms[ "viewHeight" ].value = scaledHeight;
-
-		materialLight.uniforms[ 'samplerColor' ].value = compColor.renderTarget2;
-
-		// create light proxy mesh
-
-		var meshLight = new THREE.Mesh( geometryLightPlane, materialLight );
-
-		// keep reference for size reset
-
-		resizableMaterials.push( { "material": materialLight } );
-
-		return meshLight;
-
-	};
-
-	var initDeferredProperties = function ( object ) {
-
-		if ( object.userData.deferredInitialized ) return;
-
-		if ( object.material ) initDeferredMaterials( object );
-
-		if ( object instanceof THREE.PointLight ) {
-
-			var proxy = createDeferredPointLight( object );
-
-			if ( object.distance > 0 ) {
-
-				lightSceneProxy.add( proxy );
-
-			} else {
-
-				lightSceneFullscreen.add( proxy );
-
-			}
-
-		} else if ( object instanceof THREE.SpotLight ) {
-
-			var proxy = createDeferredSpotLight( object );
-			lightSceneFullscreen.add( proxy );
-
-		} else if ( object instanceof THREE.DirectionalLight ) {
-
-			var proxy = createDeferredDirectionalLight( object );
-			lightSceneFullscreen.add( proxy );
-
-		} else if ( object instanceof THREE.HemisphereLight ) {
-
-			var proxy = createDeferredHemisphereLight( object );
-			lightSceneFullscreen.add( proxy );
-
-		} else if ( object instanceof THREE.AreaLight ) {
-
-			var proxy = createDeferredAreaLight( object );
-			lightSceneFullscreen.add( proxy );
-
-		}
-
-		object.userData.deferredInitialized = true;
-
-	};
-
-	//
-
-	var setMaterialColor = function ( object ) {
-
-		if ( object.material ) {
-
-			if ( object.userData.transparent ) {
-
-				object.material = invisibleMaterial;
-
-			} else {
-
-				object.material = object.userData.colorMaterial;
-
-			}
-
-		}
-
-	};
-
-	var setMaterialNormalDepth = function ( object ) {
-
-		if ( object.material ) {
-
-			if ( object.userData.transparent ) {
-
-				object.material = invisibleMaterial;
-
-			} else {
-
-				object.material = object.userData.normalDepthMaterial;
-
-			}
-
-		}
-
-	};
-
-	// external API
-
-	this.setAntialias = function ( enabled ) {
-
-		antialias = enabled;
-
-		if ( antialias ) {
-
-			effectFXAA.enabled = true;
-			compositePass.renderToScreen = false;
-
-		} else {
-
-			effectFXAA.enabled = false;
-			compositePass.renderToScreen = true;
-
-		}
-
-	};
-
-	this.getAntialias = function () {
-
-		return antialias;
-
-	};
-
-	this.addEffect = function ( effect, normalDepthUniform, colorUniform ) {
-
-		if ( effect.material && effect.uniforms ) {
-
-			if ( normalDepthUniform ) effect.uniforms[ normalDepthUniform ].value = compNormalDepth.renderTarget2;
-			if ( colorUniform )    	  effect.uniforms[ colorUniform ].value = compColor.renderTarget2;
-
-			if ( normalDepthUniform || colorUniform ) {
-
-				resizableMaterials.push( { "material": effect.material, "normalDepth": normalDepthUniform, "color": colorUniform } );
-
-			}
-
-		}
-
-		compFinal.insertPass( effect, - 1 );
-
-	};
-
-	this.setScale = function ( scale ) {
-
-		currentScale = scale;
-
-		scaledWidth = Math.floor( currentScale * pixelWidth );
-		scaledHeight = Math.floor( currentScale * pixelHeight );
-
-		compNormalDepth.setSize( scaledWidth, scaledHeight );
-		compColor.setSize( scaledWidth, scaledHeight );
-		compLight.setSize( scaledWidth, scaledHeight );
-		compFinal.setSize( scaledWidth, scaledHeight );
-
-		compColor.renderTarget2.shareDepthFrom = compNormalDepth.renderTarget2;
-		compLight.renderTarget2.shareDepthFrom = compNormalDepth.renderTarget2;
-
-		for ( var i = 0, il = resizableMaterials.length; i < il; i ++ ) {
-
-			var materialEntry = resizableMaterials[ i ];
-
-			var material = materialEntry.material;
-			var uniforms = material.uniforms;
-
-			var colorLabel = materialEntry.color !== undefined ? materialEntry.color : 'samplerColor';
-			var normalDepthLabel = materialEntry.normalDepth !== undefined ? materialEntry.normalDepth : 'samplerNormalDepth';
-
-			if ( uniforms[ colorLabel ] ) uniforms[ colorLabel ].value = compColor.renderTarget2;
-			if ( uniforms[ normalDepthLabel ] ) uniforms[ normalDepthLabel ].value = compNormalDepth.renderTarget2;
-
-			if ( uniforms[ 'viewWidth' ] ) uniforms[ "viewWidth" ].value = scaledWidth;
-			if ( uniforms[ 'viewHeight' ] ) uniforms[ "viewHeight" ].value = scaledHeight;
-
-		}
-
-		compositePass.uniforms[ 'samplerLight' ].value = compLight.renderTarget2;
-
-		effectFXAA.uniforms[ 'resolution' ].value.set( 1 / pixelWidth, 1 / pixelHeight );
-
-	};
-
-	this.setSize = function ( width, height ) {
-
-		pixelWidth = width;
-		pixelHeight = height;
-
-		this.renderer.setSize( pixelWidth, pixelHeight );
-
-		this.setScale( currentScale );
-
-	};
-
-	//
-
-	function updateLightProxy ( proxy ) {
-
-		var uniforms = proxy.material.uniforms;
-
-		if ( uniforms[ "matProjInverse" ] ) uniforms[ "matProjInverse" ].value = projectionMatrixInverse;
-		if ( uniforms[ "matView" ] ) uniforms[ "matView" ].value = currentCamera.matrixWorldInverse;
-
-		var originalLight = proxy.userData.originalLight;
-
-		if ( originalLight ) {
-
-			proxy.visible = originalLight.visible;
-
-			if ( originalLight instanceof THREE.PointLight ) {
-
-				updatePointLightProxy( proxy );
-
-			} else if ( originalLight instanceof THREE.SpotLight ) {
-
-				updateSpotLightProxy( proxy );
-
-			} else if ( originalLight instanceof THREE.DirectionalLight ) {
-
-				updateDirectionalLightProxy( proxy );
-
-			} else if ( originalLight instanceof THREE.HemisphereLight ) {
-
-				updateHemisphereLightProxy( proxy );
-
-			} else if ( originalLight instanceof THREE.AreaLight ) {
-
-				updateAreaLightProxy( proxy );
-
-			}
-
-		}
-
-	}
-
-	this.render = function ( scene, camera ) {
-
-		// setup deferred properties
-
-		if ( ! scene.userData.lightSceneProxy ) {
-
-			scene.userData.lightSceneProxy = new THREE.Scene();
-			scene.userData.lightSceneFullscreen = new THREE.Scene();
-
-			var meshLight = createDeferredEmissiveLight();
-			scene.userData.lightSceneFullscreen.add( meshLight );
-
-		}
-
-		currentCamera = camera;
-
-		lightSceneProxy = scene.userData.lightSceneProxy;
-		lightSceneFullscreen = scene.userData.lightSceneFullscreen;
-
-		passColor.camera = currentCamera;
-		passNormalDepth.camera = currentCamera;
-		passLightProxy.camera = currentCamera;
-		passLightFullscreen.camera = new THREE.OrthographicCamera( - 1, 1, 1, - 1, 0, 1 );
-
-		passColor.scene = scene;
-		passNormalDepth.scene = scene;
-		passLightFullscreen.scene = lightSceneFullscreen;
-		passLightProxy.scene = lightSceneProxy;
-
-		scene.traverse( initDeferredProperties );
-
-		// update scene graph only once per frame
-		// (both color and normalDepth passes use exactly the same scene state)
-
-		scene.autoUpdate = false;
-		scene.updateMatrixWorld();
-
-		// 1) g-buffer normals + depth pass
-
-		scene.traverse( setMaterialNormalDepth );
-
-		// clear shared depth buffer
-
-		this.renderer.autoClearDepth = true;
-		this.renderer.autoClearStencil = true;
-
-		// write 1 to shared stencil buffer
-		// for non-background pixels
-
-		//gl.enable( gl.STENCIL_TEST );
-		gl.stencilOp( gl.REPLACE, gl.REPLACE, gl.REPLACE );
-		gl.stencilFunc( gl.ALWAYS, 1, 0xffffffff );
-		gl.clearStencil( 0 );
-
-		compNormalDepth.render();
-
-		// just touch foreground pixels (stencil == 1)
-		// both in color and light passes
-
-		gl.stencilFunc( gl.EQUAL, 1, 0xffffffff );
-		gl.stencilOp( gl.KEEP, gl.KEEP, gl.KEEP );
-
-		// 2) g-buffer color pass
-
-		scene.traverse( setMaterialColor );
-
-		// must use clean slate depth buffer
-		// otherwise there are z-fighting glitches
-		// not enough precision between two geometry passes
-		// just to use EQUAL depth test
-
-		this.renderer.autoClearDepth = true;
-		this.renderer.autoClearStencil = false;
-
-		compColor.render();
-
-		// 3) light pass
-
-		// do not clear depth buffer in this pass
-		// depth from geometry pass is used for light culling
-		// (write light proxy color pixel if behind scene pixel)
-
-		this.renderer.autoClearDepth = false;
-
-		scene.autoUpdate = true;
-
-		gl.depthFunc( gl.GEQUAL );
-
-		projectionMatrixInverse.getInverse( currentCamera.projectionMatrix );
-
-		for ( var i = 0, il = lightSceneProxy.children.length; i < il; i ++ ) {
-
-			var proxy = lightSceneProxy.children[ i ];
-			updateLightProxy( proxy );
-
-		}
-
-		for ( var i = 0, il = lightSceneFullscreen.children.length; i < il; i ++ ) {
-
-			var proxy = lightSceneFullscreen.children[ i ];
-			updateLightProxy( proxy );
-
-		}
-
-		compLight.render();
-
-		// 4) composite pass
-
-		// return back to usual depth and stencil handling state
-
-		this.renderer.autoClearDepth = true;
-		this.renderer.autoClearStencil = true;
-		gl.depthFunc( gl.LEQUAL );
-		gl.disable( gl.STENCIL_TEST );
-
-		compFinal.render( 0.1 );
-
-	};
-
-	//
-
-	var createRenderTargets = function ( ) {
-
-		var rtParamsFloatLinear = { minFilter: THREE.NearestFilter, magFilter: THREE.LinearFilter, stencilBuffer: true,
-									format: THREE.RGBAFormat, type: THREE.FloatType };
-
-		var rtParamsFloatNearest = { minFilter: THREE.NearestFilter, magFilter: THREE.NearestFilter, stencilBuffer: true,
-									 format: THREE.RGBAFormat, type: THREE.FloatType };
-
-		var rtParamsUByte = { minFilter: THREE.NearestFilter, magFilter: THREE.LinearFilter, stencilBuffer: false,
-							  format: THREE.RGBFormat, type: THREE.UnsignedByteType };
-
-		// g-buffers
-
-		var rtColor   = new THREE.WebGLRenderTarget( scaledWidth, scaledHeight, rtParamsFloatNearest );
-		var rtNormalDepth = new THREE.WebGLRenderTarget( scaledWidth, scaledHeight, rtParamsFloatNearest );
-		var rtLight   = new THREE.WebGLRenderTarget( scaledWidth, scaledHeight, rtParamsFloatLinear );
-		var rtFinal   = new THREE.WebGLRenderTarget( scaledWidth, scaledHeight, rtParamsUByte );
-
-		rtColor.generateMipmaps = false;
-		rtNormalDepth.generateMipmaps = false;
-		rtLight.generateMipmaps = false;
-		rtFinal.generateMipmaps = false;
-
-		// normal + depth composer
-
-		passNormalDepth = new THREE.RenderPass();
-		passNormalDepth.clear = true;
-
-		compNormalDepth = new THREE.EffectComposer( _this.renderer, rtNormalDepth );
-		compNormalDepth.addPass( passNormalDepth );
-
-		// color composer
-
-		passColor = new THREE.RenderPass();
-		passColor.clear = true;
-
-		compColor = new THREE.EffectComposer( _this.renderer, rtColor );
-		compColor.addPass( passColor );
-
-		compColor.renderTarget2.shareDepthFrom = compNormalDepth.renderTarget2;
-
-		// light composer
-
-		passLightFullscreen = new THREE.RenderPass();
-		passLightFullscreen.clear = true;
-
-		passLightProxy = new THREE.RenderPass();
-		passLightProxy.clear = false;
-
-		compLight = new THREE.EffectComposer( _this.renderer, rtLight );
-		compLight.addPass( passLightFullscreen );
-		compLight.addPass( passLightProxy );
-
-		compLight.renderTarget2.shareDepthFrom = compNormalDepth.renderTarget2;
-
-		// final composer
-
-		compositePass = new THREE.ShaderPass( compositeShader );
-		compositePass.uniforms[ 'samplerLight' ].value = compLight.renderTarget2;
-		compositePass.uniforms[ 'brightness' ].value = brightness;
-		compositePass.material.blending = THREE.NoBlending;
-		compositePass.clear = true;
-
-		var defines;
-
-		switch ( tonemapping ) {
-
-			case THREE.SimpleOperator:    defines = { "TONEMAP_SIMPLE": true };    break;
-			case THREE.LinearOperator:    defines = { "TONEMAP_LINEAR": true };    break;
-			case THREE.ReinhardOperator:  defines = { "TONEMAP_REINHARD": true };  break;
-			case THREE.FilmicOperator:    defines = { "TONEMAP_FILMIC": true };    break;
-			case THREE.UnchartedOperator: defines = { "TONEMAP_UNCHARTED": true }; break;
-
-		}
-
-		compositePass.material.defines = defines;
-
-		// FXAA
-
-		effectFXAA = new THREE.ShaderPass( THREE.FXAAShader );
-		effectFXAA.uniforms[ 'resolution' ].value.set( 1 / pixelWidth, 1 / pixelHeight );
-		effectFXAA.renderToScreen = true;
-
-		//
-
-		compFinal = new THREE.EffectComposer( _this.renderer, rtFinal );
-		compFinal.addPass( compositePass );
-		compFinal.addPass( effectFXAA );
-
-		if ( antialias ) {
-
-			effectFXAA.enabled = true;
-			compositePass.renderToScreen = false;
-
-		} else {
-
-			effectFXAA.enabled = false;
-			compositePass.renderToScreen = true;
-
-		}
-
-	};
-
-	// init
-
-	createRenderTargets();
-
-};
-
-// tonemapping operator types
-
-THREE.NoOperator = 0;
-THREE.SimpleOperator = 1;
-THREE.LinearOperator = 2;
-THREE.ReinhardOperator = 3;
-THREE.FilmicOperator = 4;
-THREE.UnchartedOperator = 5;

+ 0 - 515
examples/js/shaders/NormalDisplacementShader.js

@@ -1,515 +0,0 @@
-/*
- * @author alteredq / http://alteredqualia.com/
- *
- * Normal map shader
- *  - Blinn-Phong
- *  - normal + diffuse + specular + AO + displacement + reflection + shadow maps
- *  - point and directional lights (use with "lights: true" material option)
- */
-
-THREE.NormalDisplacementShader = {
-
-	uniforms: THREE.UniformsUtils.merge( [
-
-		THREE.UniformsLib[ "fog" ],
-		THREE.UniformsLib[ "lights" ],
-		THREE.UniformsLib[ "shadowmap" ],
-
-		{
-
-			"enableAO"          : { type: "i", value: 0 },
-			"enableDiffuse"     : { type: "i", value: 0 },
-			"enableSpecular"    : { type: "i", value: 0 },
-			"enableReflection"  : { type: "i", value: 0 },
-			"enableDisplacement": { type: "i", value: 0 },
-
-			"tDisplacement": { type: "t", value: null }, // must go first as this is vertex texture
-			"tDiffuse"     : { type: "t", value: null },
-			"tCube"        : { type: "t", value: null },
-			"tNormal"      : { type: "t", value: null },
-			"tSpecular"    : { type: "t", value: null },
-			"tAO"          : { type: "t", value: null },
-
-			"uNormalScale": { type: "v2", value: new THREE.Vector2( 1, 1 ) },
-
-			"uDisplacementBias": { type: "f", value: 0.0 },
-			"uDisplacementScale": { type: "f", value: 1.0 },
-
-			"diffuse": { type: "c", value: new THREE.Color( 0xffffff ) },
-			"specular": { type: "c", value: new THREE.Color( 0x111111 ) },
-			"shininess": { type: "f", value: 30 },
-			"opacity": { type: "f", value: 1 },
-
-			"refractionRatio": { type: "f", value: 0.98 },
-			"reflectivity": { type: "f", value: 0.5 },
-
-			"uOffset" : { type: "v2", value: new THREE.Vector2( 0, 0 ) },
-			"uRepeat" : { type: "v2", value: new THREE.Vector2( 1, 1 ) },
-
-		}
-
-	] ),
-
-	fragmentShader: [
-
-		"uniform vec3 diffuse;",
-		"uniform vec3 specular;",
-		"uniform float shininess;",
-		"uniform float opacity;",
-
-		"uniform bool enableDiffuse;",
-		"uniform bool enableSpecular;",
-		"uniform bool enableAO;",
-		"uniform bool enableReflection;",
-
-		"uniform sampler2D tDiffuse;",
-		"uniform sampler2D tNormal;",
-		"uniform sampler2D tSpecular;",
-		"uniform sampler2D tAO;",
-
-		"uniform samplerCube tCube;",
-
-		"uniform vec2 uNormalScale;",
-
-		"uniform float refractionRatio;",
-		"uniform float reflectivity;",
-
-		"varying vec3 vTangent;",
-		"varying vec3 vBinormal;",
-		"varying vec3 vNormal;",
-		"varying vec2 vUv;",
-
-		"uniform vec3 ambientLightColor;",
-
-		"#if MAX_DIR_LIGHTS > 0",
-
-		"	uniform vec3 directionalLightColor[ MAX_DIR_LIGHTS ];",
-		"	uniform vec3 directionalLightDirection[ MAX_DIR_LIGHTS ];",
-
-		"#endif",
-
-		"#if MAX_HEMI_LIGHTS > 0",
-
-		"	uniform vec3 hemisphereLightSkyColor[ MAX_HEMI_LIGHTS ];",
-		"	uniform vec3 hemisphereLightGroundColor[ MAX_HEMI_LIGHTS ];",
-		"	uniform vec3 hemisphereLightDirection[ MAX_HEMI_LIGHTS ];",
-
-		"#endif",
-
-		"#if MAX_POINT_LIGHTS > 0",
-
-		"	uniform vec3 pointLightColor[ MAX_POINT_LIGHTS ];",
-		"	uniform vec3 pointLightPosition[ MAX_POINT_LIGHTS ];",
-		"	uniform float pointLightDistance[ MAX_POINT_LIGHTS ];",
-
-		"#endif",
-
-		"#if MAX_SPOT_LIGHTS > 0",
-
-		"	uniform vec3 spotLightColor[ MAX_SPOT_LIGHTS ];",
-		"	uniform vec3 spotLightPosition[ MAX_SPOT_LIGHTS ];",
-		"	uniform vec3 spotLightDirection[ MAX_SPOT_LIGHTS ];",
-		"	uniform float spotLightAngleCos[ MAX_SPOT_LIGHTS ];",
-		"	uniform float spotLightExponent[ MAX_SPOT_LIGHTS ];",
-		"	uniform float spotLightDistance[ MAX_SPOT_LIGHTS ];",
-
-		"#endif",
-
-		"varying vec3 vWorldPosition;",
-		"varying vec3 vViewPosition;",
-
-		THREE.ShaderChunk[ "common" ],
-		THREE.ShaderChunk[ "shadowmap_pars_fragment" ],
-		THREE.ShaderChunk[ "fog_pars_fragment" ],
-		THREE.ShaderChunk[ "logdepthbuf_pars_fragment" ],
-
-		"void main() {",
-
-			THREE.ShaderChunk[ "logdepthbuf_fragment" ],
-
-		"	vec3 outgoingLight = vec3( 0.0 );",
-
-		"	vec4 diffuseColor = vec4( diffuse, opacity );",
-
-		"	vec3 specularTex = vec3( 1.0 );",
-
-		"	vec3 normalTex = texture2D( tNormal, vUv ).xyz * 2.0 - 1.0;",
-		"	normalTex.xy *= uNormalScale;",
-		"	normalTex = normalize( normalTex );",
-
-		"	if( enableDiffuse ) {",
-
-		"		#ifdef GAMMA_INPUT",
-
-		"			vec4 texelColor = texture2D( tDiffuse, vUv );",
-		"			texelColor.xyz *= texelColor.xyz;",
-
-		"			diffuseColor *= texelColor;",
-
-		"		#else",
-
-		"			diffuseColor *= texture2D( tDiffuse, vUv );",
-
-		"		#endif",
-
-		"	}",
-
-		"	if( enableAO ) {",
-
-		"		diffuseColor.rgb *= texture2D( tAO, vUv ).xyz;", // actually, the AOmap should be modulating ambient light sources only,
-																 // and should use the second set of UVs, as is done elsewhere in the library
-		"	}",
-
-			THREE.ShaderChunk[ "alphatest_fragment" ],
-
-		"	if( enableSpecular )",
-		"		specularTex = texture2D( tSpecular, vUv ).xyz;",
-
-		"	mat3 tsb = mat3( normalize( vTangent ), normalize( vBinormal ), normalize( vNormal ) );",
-		"	vec3 finalNormal = tsb * normalTex;",
-
-		"	#ifdef FLIP_SIDED",
-
-		"		finalNormal = - finalNormal;",
-
-		"	#endif",
-
-		"	vec3 normal = normalize( finalNormal );",
-		"	vec3 viewPosition = normalize( vViewPosition );",
-
-		"	vec3 totalDiffuseLight = vec3( 0.0 );",
-		"	vec3 totalSpecularLight = vec3( 0.0 );",
-
-			// point lights
-
-		"	#if MAX_POINT_LIGHTS > 0",
-
-		"		for ( int i = 0; i < MAX_POINT_LIGHTS; i ++ ) {",
-
-		"			vec3 pointVector = pointLightPosition[ i ] + vViewPosition.xyz;",
-
-		"			float pointDistance = 1.0;",
-		"			if ( pointLightDistance[ i ] > 0.0 )",
-		"				pointDistance = 1.0 - min( ( length( pointVector ) / pointLightDistance[ i ] ), 1.0 );",
-
-		"			pointVector = normalize( pointVector );",
-
-					// diffuse
-
-		"			float pointDiffuseWeight = max( dot( normal, pointVector ), 0.0 );",
-
-		"			totalDiffuseLight += pointDistance * pointLightColor[ i ] * pointDiffuseWeight;",
-
-					// specular
-
-		"			vec3 pointHalfVector = normalize( pointVector + viewPosition );",
-		"			float pointDotNormalHalf = max( dot( normal, pointHalfVector ), 0.0 );",
-		"			float pointSpecularWeight = specularTex.r * max( pow( pointDotNormalHalf, shininess ), 0.0 );",
-
-		"			float specularNormalization = ( shininess + 2.0 ) / 8.0;",
-
-		"			vec3 schlick = specular + vec3( 1.0 - specular ) * pow( max( 1.0 - dot( pointVector, pointHalfVector ), 0.0 ), 5.0 );",
-		"			totalSpecularLight += schlick * pointLightColor[ i ] * pointSpecularWeight * pointDiffuseWeight * pointDistance * specularNormalization;",
-
-		"		}",
-
-		"	#endif",
-
-			// spot lights
-
-		"	#if MAX_SPOT_LIGHTS > 0",
-
-		"		for ( int i = 0; i < MAX_SPOT_LIGHTS; i ++ ) {",
-
-		"			vec3 spotVector = spotLightPosition[ i ] + vViewPosition.xyz;",
-
-		"			float spotDistance = 1.0;",
-		"			if ( spotLightDistance[ i ] > 0.0 )",
-		"				spotDistance = 1.0 - min( ( length( spotVector ) / spotLightDistance[ i ] ), 1.0 );",
-
-		"			spotVector = normalize( spotVector );",
-
-		"			float spotEffect = dot( spotLightDirection[ i ], spotVector );",
-
-		"			if ( spotEffect > spotLightAngleCos[ i ] ) {",
-
-		"				spotEffect = max( pow( max( spotEffect, 0.0 ), spotLightExponent[ i ] ), 0.0 );",
-
-						// diffuse
-
-
-		"				float spotDiffuseWeight = max( dot( normal, spotVector ), 0.0 );",
-
-		"				totalDiffuseLight += spotDistance * spotLightColor[ i ] * spotDiffuseWeight * spotEffect;",
-
-						// specular
-
-		"				vec3 spotHalfVector = normalize( spotVector + viewPosition );",
-		"				float spotDotNormalHalf = max( dot( normal, spotHalfVector ), 0.0 );",
-		"				float spotSpecularWeight = specularTex.r * max( pow( spotDotNormalHalf, shininess ), 0.0 );",
-
-		"				float specularNormalization = ( shininess + 2.0 ) / 8.0;",
-
-		"				vec3 schlick = specular + vec3( 1.0 - specular ) * pow( max( 1.0 - dot( spotVector, spotHalfVector ), 0.0 ), 5.0 );",
-		"				totalSpecularLight += schlick * spotLightColor[ i ] * spotSpecularWeight * spotDiffuseWeight * spotDistance * specularNormalization * spotEffect;",
-
-		"			}",
-
-		"		}",
-
-		"	#endif",
-
-			// directional lights
-
-		"	#if MAX_DIR_LIGHTS > 0",
-
-		"		for( int i = 0; i < MAX_DIR_LIGHTS; i ++ ) {",
-
-		"			vec3 dirVector = directionalLightDirection[ i ];",
-
-					// diffuse
-
-		"			float dirDiffuseWeight = max( dot( normal, dirVector ), 0.0 );",
-
-		"			totalDiffuseLight += directionalLightColor[ i ] * dirDiffuseWeight;",
-
-					// specular
-
-		"			vec3 dirHalfVector = normalize( dirVector + viewPosition );",
-		"			float dirDotNormalHalf = max( dot( normal, dirHalfVector ), 0.0 );",
-		"			float dirSpecularWeight = specularTex.r * max( pow( dirDotNormalHalf, shininess ), 0.0 );",
-
-		"			float specularNormalization = ( shininess + 2.0 ) / 8.0;",
-
-		"			vec3 schlick = specular + vec3( 1.0 - specular ) * pow( max( 1.0 - dot( dirVector, dirHalfVector ), 0.0 ), 5.0 );",
-		"			totalSpecularLight += schlick * directionalLightColor[ i ] * dirSpecularWeight * dirDiffuseWeight * specularNormalization;",
-
-		"		}",
-
-		"	#endif",
-
-			// hemisphere lights
-
-		"	#if MAX_HEMI_LIGHTS > 0",
-
-		"		for( int i = 0; i < MAX_HEMI_LIGHTS; i ++ ) {",
-
-		"			vec3 lVector = hemisphereLightDirection[ i ];",
-
-					// diffuse
-
-		"			float dotProduct = dot( normal, lVector );",
-		"			float hemiDiffuseWeight = 0.5 * dotProduct + 0.5;",
-
-		"			vec3 hemiColor = mix( hemisphereLightGroundColor[ i ], hemisphereLightSkyColor[ i ], hemiDiffuseWeight );",
-
-		"			totalDiffuseLight += hemiColor;",
-
-					// specular (sky light)
-
-		"			vec3 hemiHalfVectorSky = normalize( lVector + viewPosition );",
-		"			float hemiDotNormalHalfSky = 0.5 * dot( normal, hemiHalfVectorSky ) + 0.5;",
-		"			float hemiSpecularWeightSky = specularTex.r * max( pow( max( hemiDotNormalHalfSky, 0.0 ), shininess ), 0.0 );",
-
-					//
-
-		"			float specularNormalization = ( shininess + 2.0 ) / 8.0;",
-
-		"			vec3 schlickSky = specular + vec3( 1.0 - specular ) * pow( max( 1.0 - dot( lVector, hemiHalfVectorSky ), 0.0 ), 5.0 );",
-		"			totalSpecularLight += hemiColor * specularNormalization * ( schlickSky * hemiSpecularWeightSky * max( dotProduct, 0.0 ) );",
-
-		"		}",
-
-		"	#endif",
-
-		"	#ifdef METAL",
-
-		"		outgoingLight += diffuseColor.xyz * ( totalDiffuseLight + ambientLightColor + totalSpecularLight );",
-
-		"	#else",
-
-		"		outgoingLight += diffuseColor.xyz * ( totalDiffuseLight + ambientLightColor ) + totalSpecularLight;",
-
-		"	#endif",
-
-		"	if ( enableReflection ) {",
-
-		"		vec3 cameraToVertex = normalize( vWorldPosition - cameraPosition );",
-
-		"		vec3 worldNormal = inverseTransformDirection( normal, viewMatrix );",
-
-		"		#ifdef ENVMAP_MODE_REFLECTION",
-
-		"			vec3 vReflect = reflect( cameraToVertex, worldNormal );",
-
-		"		#else",
-
-		"			vec3 vReflect = refract( cameraToVertex, worldNormal, refractionRatio );",
-
-		"		#endif",
-
-		"		vec4 cubeColor = textureCube( tCube, vec3( -vReflect.x, vReflect.yz ) );",
-
-		"		#ifdef GAMMA_INPUT",
-
-		"			cubeColor.xyz *= cubeColor.xyz;",
-
-		"		#endif",
-
-		"		outgoingLight = mix( outgoingLight, cubeColor.xyz, specularTex.r * reflectivity );",
-
-		"	}",
-
-			THREE.ShaderChunk[ "shadowmap_fragment" ],
-			THREE.ShaderChunk[ "linear_to_gamma_fragment" ],
-			THREE.ShaderChunk[ "fog_fragment" ],
-
-		"	gl_FragColor = vec4( outgoingLight, diffuseColor.a );",
-
-		"}"
-
-	].join( "\n" ),
-
-	vertexShader: [
-
-		"attribute vec4 tangent;",
-
-		"uniform vec2 uOffset;",
-		"uniform vec2 uRepeat;",
-
-		"uniform bool enableDisplacement;",
-
-		"#ifdef VERTEX_TEXTURES",
-
-		"	uniform sampler2D tDisplacement;",
-		"	uniform float uDisplacementScale;",
-		"	uniform float uDisplacementBias;",
-
-		"#endif",
-
-		"varying vec3 vTangent;",
-		"varying vec3 vBinormal;",
-		"varying vec3 vNormal;",
-		"varying vec2 vUv;",
-
-		"varying vec3 vWorldPosition;",
-		"varying vec3 vViewPosition;",
-
-		THREE.ShaderChunk[ "skinning_pars_vertex" ],
-		THREE.ShaderChunk[ "shadowmap_pars_vertex" ],
-		THREE.ShaderChunk[ "logdepthbuf_pars_vertex" ],
-
-		"void main() {",
-
-			THREE.ShaderChunk[ "skinbase_vertex" ],
-			THREE.ShaderChunk[ "skinnormal_vertex" ],
-
-			// normal, tangent and binormal vectors
-
-		"	#ifdef USE_SKINNING",
-
-		"		vNormal = normalize( normalMatrix * skinnedNormal.xyz );",
-
-		"		vec4 skinnedTangent = skinMatrix * vec4( tangent.xyz, 0.0 );",
-		"		vTangent = normalize( normalMatrix * skinnedTangent.xyz );",
-
-		"	#else",
-
-		"		vNormal = normalize( normalMatrix * normal );",
-		"		vTangent = normalize( normalMatrix * tangent.xyz );",
-
-		"	#endif",
-
-		"	vBinormal = normalize( cross( vNormal, vTangent ) * tangent.w );",
-
-		"	vUv = uv * uRepeat + uOffset;",
-
-			// displacement mapping
-
-		"	vec3 displacedPosition;",
-
-		"	#ifdef VERTEX_TEXTURES",
-
-		"		if ( enableDisplacement ) {",
-
-		"			vec3 dv = texture2D( tDisplacement, uv ).xyz;",
-		"			float df = uDisplacementScale * dv.x + uDisplacementBias;",
-		"			displacedPosition = position + normalize( normal ) * df;",
-
-		"		} else {",
-
-		"			#ifdef USE_SKINNING",
-
-		"				vec4 skinVertex = bindMatrix * vec4( position, 1.0 );",
-
-		"				vec4 skinned = vec4( 0.0 );",
-		"				skinned += boneMatX * skinVertex * skinWeight.x;",
-		"				skinned += boneMatY * skinVertex * skinWeight.y;",
-		"				skinned += boneMatZ * skinVertex * skinWeight.z;",
-		"				skinned += boneMatW * skinVertex * skinWeight.w;",
-		"				skinned  = bindMatrixInverse * skinned;",
-
-		"				displacedPosition = skinned.xyz;",
-
-		"			#else",
-
-		"				displacedPosition = position;",
-
-		"			#endif",
-
-		"		}",
-
-		"	#else",
-
-		"		#ifdef USE_SKINNING",
-
-		"			vec4 skinVertex = bindMatrix * vec4( position, 1.0 );",
-
-		"			vec4 skinned = vec4( 0.0 );",
-		"			skinned += boneMatX * skinVertex * skinWeight.x;",
-		"			skinned += boneMatY * skinVertex * skinWeight.y;",
-		"			skinned += boneMatZ * skinVertex * skinWeight.z;",
-		"			skinned += boneMatW * skinVertex * skinWeight.w;",
-		"			skinned  = bindMatrixInverse * skinned;",
-
-		"			displacedPosition = skinned.xyz;",
-
-		"		#else",
-
-		"			displacedPosition = position;",
-
-		"		#endif",
-
-		"	#endif",
-
-			//
-
-		"	vec4 mvPosition = modelViewMatrix * vec4( displacedPosition, 1.0 );",
-		"	vec4 worldPosition = modelMatrix * vec4( displacedPosition, 1.0 );",
-
-		"	gl_Position = projectionMatrix * mvPosition;",
-
-			THREE.ShaderChunk[ "logdepthbuf_vertex" ],
-
-			//
-
-		"	vWorldPosition = worldPosition.xyz;",
-		"	vViewPosition = - mvPosition.xyz;",
-
-			// shadows
-
-		"	#ifdef USE_SHADOWMAP",
-
-		"		for( int i = 0; i < MAX_SHADOWS; i ++ ) {",
-
-		"			vShadowCoord[ i ] = shadowMatrix[ i ] * worldPosition;",
-
-		"		}",
-
-		"	#endif",
-
-		"}"
-
-	].join( "\n" )
-
-};

+ 6 - 7
examples/misc_controls_fly.html

@@ -108,20 +108,19 @@
 				scene.add( dirLight );
 
 				var materialNormalMap = new THREE.MeshPhongMaterial( {
-				
+
 					specular: 0x333333,
 					shininess: 15,
 					map: THREE.ImageUtils.loadTexture( "textures/planets/earth_atmos_2048.jpg" ),
 					specularMap: THREE.ImageUtils.loadTexture( "textures/planets/earth_specular_2048.jpg" ),
 					normalMap: THREE.ImageUtils.loadTexture( "textures/planets/earth_normal_2048.jpg" ),
 					normalScale: new THREE.Vector2( 0.85, 0.85 )
-				
+
 				} );
 
 				// planet
 
 				geometry = new THREE.SphereGeometry( radius, 100, 50 );
-				geometry.computeTangents();
 
 				meshPlanet = new THREE.Mesh( geometry, materialNormalMap );
 				meshPlanet.rotation.y = 0;
@@ -131,10 +130,10 @@
 				// clouds
 
 				var materialClouds = new THREE.MeshLambertMaterial( {
-				
+
 					map: THREE.ImageUtils.loadTexture( "textures/planets/earth_clouds_1024.png" ),
 					transparent: true
-				
+
 				} );
 
 				meshClouds = new THREE.Mesh( geometry, materialClouds );
@@ -145,9 +144,9 @@
 				// moon
 
 				var materialMoon = new THREE.MeshPhongMaterial( {
-				
+
 					map: THREE.ImageUtils.loadTexture( "textures/planets/moon_1024.jpg" )
-				
+
 				} );
 
 				meshMoon = new THREE.Mesh( geometry, materialMoon );

File diff suppressed because it is too large
+ 0 - 43
examples/models/animated/elderlyWalk.js


BIN
examples/models/sea3d/flag.sea


BIN
examples/models/sea3d/flag.tjs.sea


BIN
examples/models/sea3d/keyframe.tjs.sea


BIN
examples/models/sea3d/mascot.tjs.sea


BIN
examples/models/sea3d/morph.tjs.sea


BIN
examples/models/sea3d/robot.tjs.sea


BIN
examples/models/sea3d/skin.tjs.sea


BIN
examples/models/sea3d/sound.tjs.sea


File diff suppressed because it is too large
+ 0 - 43
examples/models/skinned/human_walk_0_female.js


BIN
examples/obj/box/box.bin


+ 0 - 29
examples/obj/box/box.js

@@ -1,29 +0,0 @@
-{
-
-    "metadata" :
-    {
-        "formatVersion" : 3.1,
-        "sourceFile"    : "box.obj",
-        "generatedBy"   : "OBJConverter",
-        "vertices"      : 36,
-        "faces"         : 25,
-        "normals"       : 8,
-        "uvs"           : 0,
-        "materials"     : 1
-    },
-
-    "materials": [	{
-	"DbgColor" : 15658734,
-	"DbgIndex" : 0,
-	"DbgName" : "",
-	"colorAmbient" : [0.0, 0.0, 0.0],
-	"colorDiffuse" : [0.8, 0.8, 0.8],
-	"colorSpecular" : [0.8, 0.8, 0.8],
-	"illumination" : 2,
-	"specularCoef" : 0.0,
-	"opacity" : 1.0
-	}],
-
-    "buffers": "box.bin"
-
-}

+ 0 - 7
examples/obj/ninja/.htaccess

@@ -1,7 +0,0 @@
-<Files *.js>
-SetOutputFilter DEFLATE
-</Files>
-
-<Files *.bin>
-SetOutputFilter DEFLATE
-</Files>

+ 393 - 0
examples/webgl_geometry_teapot.html

@@ -0,0 +1,393 @@
+<!DOCTYPE html>
+<html lang="en">
+	<head>
+		<title>three.js webgl - teapot buffer geometry</title>
+		<meta charset="utf-8">
+		<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
+		<style>
+			body {
+				color: #fff;
+				font-family: Monospace;
+				font-size: 13px;
+				text-align: center;
+				font-weight: bold;
+
+				background-color: #000;
+				margin: 0px;
+				overflow: hidden;
+			}
+
+			#info {
+				position: absolute;
+				padding: 10px;
+				width: 100%;
+				text-align: center;
+				color: #fff;
+			}
+
+			a { color: blue; }
+
+		</style>
+	</head>
+	<body>
+		<div id="info">
+			<a href="http://threejs.org" target="_blank">three.js</a> - the Utah Teapot<br />
+			from <a href="https://www.udacity.com/course/interactive-3d-graphics--cs291">Udacity Interactive 3D Graphics</a>
+		</div>
+
+		<script src="../build/three.min.js"></script>
+
+		<script src="js/controls/OrbitControls.js"></script>
+
+		<script src="js/Detector.js"></script>
+
+		<script src='js/libs/dat.gui.min.js'></script>
+
+		<script src='js/geometries/TeapotBufferGeometry.js'></script>
+
+		<script>
+
+			////////////////////////////////////////////////////////////////////////////////
+			// Utah/Newell Teapot demo
+			////////////////////////////////////////////////////////////////////////////////
+			/*global THREE, Detector, container, dat, window */
+
+			if ( ! Detector.webgl ) Detector.addGetWebGLMessage();
+
+			var camera, scene, sceneCube, renderer;
+			var cameraControls;
+			var effectController;
+			var teapotSize = 400;
+			var ambientLight, light;
+			var skybox;
+
+			var tess = -1;	// force initialization
+			var bBottom ;
+			var bLid;
+			var bBody;
+			var bFitLid;
+			var bNonBlinn;
+			var shading;
+			var wireMaterial, flatMaterial, gouraudMaterial, phongMaterial, texturedMaterial, reflectiveMaterial;
+
+			var teapot;
+
+			// allocate these just once
+			var diffuseColor = new THREE.Color();
+			var specularColor = new THREE.Color();
+
+			init();
+			render();
+
+			function init() {
+
+				container = document.createElement( 'div' );
+				document.body.appendChild( container );
+
+				var canvasWidth = window.innerWidth;
+				var canvasHeight = window.innerHeight;
+
+				// CAMERA
+				camera = new THREE.PerspectiveCamera( 45, window.innerWidth / window.innerHeight, 1, 80000 );
+				camera.position.set( -600, 550, 1300 );
+
+				// LIGHTS
+				ambientLight = new THREE.AmbientLight( 0x333333 );	// 0.2
+
+				light = new THREE.DirectionalLight( 0xFFFFFF, 1.0 );
+				// direction is set in GUI
+
+				// RENDERER
+				renderer = new THREE.WebGLRenderer( { antialias: true } );
+				renderer.setSize( canvasWidth, canvasHeight );
+				renderer.setClearColor( 0xAAAAAA );
+				renderer.gammaInput = true;
+				renderer.gammaOutput = true;
+				container.appendChild( renderer.domElement );
+
+				// EVENTS
+				window.addEventListener( 'resize', onWindowResize, false );
+
+				// CONTROLS
+				cameraControls = new THREE.OrbitControls( camera, renderer.domElement );
+				cameraControls.target.set( 0, 0, 0 );
+				cameraControls.addEventListener( 'change', render );
+
+				// TEXTURE MAP
+				var textureMap = THREE.ImageUtils.loadTexture( 'textures/UV_Grid_Sm.jpg' );
+				textureMap.wrapS = textureMap.wrapT = THREE.RepeatWrapping;
+				textureMap.anisotropy = 16;
+
+				// REFLECTION MAP
+				var path = "textures/cube/skybox/";
+				var urls = [ path + "px.jpg", path + "nx.jpg",
+							 path + "py.jpg", path + "ny.jpg",
+							 path + "pz.jpg", path + "nz.jpg" ];
+
+				var textureCube = THREE.ImageUtils.loadTextureCube( urls );
+
+				// MATERIALS
+				var materialColor = new THREE.Color();
+				materialColor.setRGB( 1.0, 1.0, 1.0 );
+
+				wireMaterial = new THREE.MeshBasicMaterial( { color: 0xFFFFFF, wireframe: true } ) ;
+
+				flatMaterial = new THREE.MeshPhongMaterial( { color: materialColor, specular: 0x0, shading: THREE.FlatShading, side: THREE.DoubleSide } );
+
+				gouraudMaterial = new THREE.MeshLambertMaterial( { color: materialColor, shading: THREE.SmoothShading, side: THREE.DoubleSide } );
+
+				phongMaterial = new THREE.MeshPhongMaterial( { color: materialColor, shading: THREE.SmoothShading, side: THREE.DoubleSide } );
+
+				texturedMaterial = new THREE.MeshPhongMaterial( { color: materialColor, map: textureMap, shading: THREE.SmoothShading, side: THREE.DoubleSide } );
+
+				reflectiveMaterial = new THREE.MeshPhongMaterial( { color: materialColor, envMap: textureCube, shading: THREE.SmoothShading, side: THREE.DoubleSide } );
+
+				// SKYBOX
+				var shader = THREE.ShaderLib[ "cube" ];
+				shader.uniforms[ "tCube" ].value = textureCube;
+
+				var skyboxMaterial = new THREE.ShaderMaterial( {
+
+					fragmentShader: shader.fragmentShader,
+					vertexShader: shader.vertexShader,
+					uniforms: shader.uniforms,
+					depthWrite: false,
+					side: THREE.BackSide
+
+				} );
+
+				skybox = new THREE.Mesh( new THREE.BoxGeometry( 5000, 5000, 5000 ), skyboxMaterial );
+
+				// skybox scene - keep camera centered here
+				sceneCube = new THREE.Scene();
+				sceneCube.add( skybox );
+
+				// scene itself
+				scene = new THREE.Scene();
+
+				scene.add( ambientLight );
+				scene.add( light );
+
+				// GUI
+				setupGui();
+
+			}
+
+			// EVENT HANDLERS
+
+			function onWindowResize() {
+
+				var canvasWidth = window.innerWidth;
+				var canvasHeight = window.innerHeight;
+
+				renderer.setSize( canvasWidth, canvasHeight );
+
+				camera.aspect = canvasWidth / canvasHeight;
+				camera.updateProjectionMatrix();
+
+				render();
+
+			}
+
+			function setupGui() {
+
+				effectController = {
+
+					shininess: 40.0,
+					ka: 0.17,
+					kd: 0.51,
+					ks: 0.2,
+					metallic: true,
+
+					hue:		0.121,
+					saturation: 0.73,
+					lightness:  0.66,
+
+					lhue:		 0.04,
+					lsaturation: 0.01,	// non-zero so that fractions will be shown
+					llightness:  1.0,
+
+					// bizarrely, if you initialize these with negative numbers, the sliders
+					// will not show any decimal places.
+					lx: 0.32,
+					ly: 0.39,
+					lz: 0.7,
+					newTess: 15,
+					bottom: true,
+					lid: true,
+					body: true,
+					fitLid: false,
+					nonblinn: false,
+					newShading: "glossy"
+				};
+
+				var h;
+
+				var gui = new dat.GUI();
+
+				// material (attributes)
+
+				h = gui.addFolder( "Material control" );
+
+				h.add( effectController, "shininess", 1.0, 400.0, 1.0 ).name( "shininess" ).onChange( render );
+				h.add( effectController, "kd", 0.0, 1.0, 0.025 ).name( "diffuse strength" ).onChange( render );
+				h.add( effectController, "ks", 0.0, 1.0, 0.025 ).name( "specular strength" ).onChange( render );
+				h.add( effectController, "metallic" ).onChange( render );
+
+				// material (color)
+
+				h = gui.addFolder( "Material color" );
+
+				h.add( effectController, "hue", 0.0, 1.0, 0.025 ).name( "hue" ).onChange( render );
+				h.add( effectController, "saturation", 0.0, 1.0, 0.025 ).name( "saturation" ).onChange( render );
+				h.add( effectController, "lightness", 0.0, 1.0, 0.025 ).name( "lightness" ).onChange( render );
+
+				// light (point)
+
+				h = gui.addFolder( "Lighting" );
+
+				h.add( effectController, "lhue", 0.0, 1.0, 0.025 ).name( "hue" ).onChange( render );
+				h.add( effectController, "lsaturation", 0.0, 1.0, 0.025 ).name( "saturation" ).onChange( render );
+				h.add( effectController, "llightness", 0.0, 1.0, 0.025 ).name( "lightness" ).onChange( render );
+				h.add( effectController, "ka", 0.0, 1.0, 0.025 ).name( "ambient" ).onChange( render );
+
+				// light (directional)
+
+				h = gui.addFolder( "Light direction" );
+
+				h.add( effectController, "lx", -1.0, 1.0, 0.025 ).name( "x" ).onChange( render );
+				h.add( effectController, "ly", -1.0, 1.0, 0.025 ).name( "y" ).onChange( render );
+				h.add( effectController, "lz", -1.0, 1.0, 0.025 ).name( "z" ).onChange( render );
+
+				h = gui.addFolder( "Tessellation control" );
+				h.add( effectController, "newTess", [ 2, 3, 4, 5, 6, 8, 10, 15, 20, 30, 40, 50 ] ).name( "Tessellation Level" ).onChange( render );
+				h.add( effectController, "lid" ).name( "display lid" ).onChange( render );
+				h.add( effectController, "body" ).name( "display body" ).onChange( render );
+				h.add( effectController, "bottom" ).name( "display bottom" ).onChange( render );
+				h.add( effectController, "fitLid" ).name( "snug lid" ).onChange( render );
+				h.add( effectController, "nonblinn" ).name( "original scale" ).onChange( render );
+
+				// shading
+				h = gui.add( effectController, "newShading", [ "wireframe", "flat", "smooth", "glossy", "textured", "reflective" ] ).name( "Shading" ).onChange( render );
+
+			}
+
+
+			//
+
+			function render() {
+
+				if ( effectController.newTess !== tess ||
+					effectController.bottom !== bBottom ||
+					effectController.lid !== bLid ||
+					effectController.body !== bBody ||
+					effectController.fitLid !== bFitLid ||
+					effectController.nonblinn !== bNonBlinn ||
+					effectController.newShading !== shading )
+				{
+
+					tess = effectController.newTess;
+					bBottom = effectController.bottom;
+					bLid = effectController.lid;
+					bBody = effectController.body;
+					bFitLid = effectController.fitLid;
+					bNonBlinn = effectController.nonblinn;
+					shading = effectController.newShading;
+
+					createNewTeapot();
+
+				}
+
+				// We're a bit lazy here. We could check to see if any material attributes changed and update
+				// only if they have. But, these calls are cheap enough and this is just a demo.
+				phongMaterial.shininess = effectController.shininess;
+				texturedMaterial.shininess = effectController.shininess;
+
+				diffuseColor.setHSL( effectController.hue, effectController.saturation, effectController.lightness );
+				if ( effectController.metallic )
+				{
+
+					// make colors match to give a more metallic look
+					specularColor.copy( diffuseColor );
+
+				}
+				else
+				{
+
+					// more of a plastic look
+					specularColor.setRGB( 1, 1, 1 );
+
+				}
+
+				diffuseColor.multiplyScalar( effectController.kd );
+				flatMaterial.color.copy( diffuseColor );
+				gouraudMaterial.color.copy( diffuseColor );
+				phongMaterial.color.copy( diffuseColor );
+				texturedMaterial.color.copy( diffuseColor );
+
+				specularColor.multiplyScalar( effectController.ks );
+				phongMaterial.specular.copy( specularColor );
+				texturedMaterial.specular.copy( specularColor );
+
+				// Ambient's actually controlled by the light for this demo
+				ambientLight.color.setHSL( effectController.hue, effectController.saturation, effectController.lightness * effectController.ka );
+
+				light.position.set( effectController.lx, effectController.ly, effectController.lz );
+				light.color.setHSL( effectController.lhue, effectController.lsaturation, effectController.llightness );
+
+				// skybox is rendered separately, so that it is always behind the teapot.
+				if ( shading === "reflective" )
+				{
+
+					// clear to skybox
+					renderer.autoClear = false;
+					skybox.position.copy( camera.position );
+					renderer.render( sceneCube, camera );
+
+				}
+				else
+				{
+
+					// clear to regular background color
+					renderer.autoClear = true;
+
+				}
+
+				renderer.render( scene, camera );
+
+			}
+
+			// Whenever the teapot changes, the scene is rebuilt from scratch (not much to it).
+			function createNewTeapot() {
+
+				if ( teapot !== undefined ) {
+
+					teapot.geometry.dispose();
+					scene.remove( teapot );
+
+				}
+
+				var teapotGeometry = new THREE.TeapotBufferGeometry( teapotSize,
+					tess,
+					effectController.bottom,
+					effectController.lid,
+					effectController.body,
+					effectController.fitLid,
+					! effectController.nonblinn );
+
+				teapot = new THREE.Mesh(
+					teapotGeometry,
+					shading === "wireframe" ? wireMaterial : (
+					shading === "flat" ? flatMaterial : (
+					shading === "smooth" ? gouraudMaterial : (
+					shading === "glossy" ? phongMaterial : (
+					shading === "textured" ? texturedMaterial : reflectiveMaterial ) ) ) ) );	// if no match, pick Phong
+
+				scene.add( teapot );
+
+			}
+
+		</script>
+
+	</body>
+</html>

+ 0 - 2
examples/webgl_loader_ctm.html

@@ -179,8 +179,6 @@
 
 				loader.load( "models/ctm/LeePerry.ctm",  function( geometry ) {
 
-					geometry.computeTangents();
-
 					var material = new THREE.MeshPhongMaterial( {
 
 						specular: 0x303030,

+ 5 - 7
examples/webgl_loader_sea3d.html

@@ -71,26 +71,26 @@
 			loader = new THREE.SEA3D( {
 
 				autoPlay : true, // Auto play animations
-				container : scene, // Container to add models
-				parser : THREE.SEA3D.AUTO, // Auto choose THREE.BufferGeometry and THREE.Geometry
-				multiplier : 1 // Light multiplier
+				container : scene // Container to add models
 
 			} );
 
 			loader.onComplete = function( e ) {
 
-				// Get camera from 3ds Max
+				// Get camera from SEA3D Studio
 				// use loader.get... to get others objects
 
 				var cam = loader.getCamera( "Camera007" );
 				camera.position.copy( cam.position );
 				camera.rotation.copy( cam.rotation );
 
+				controls = new THREE.OrbitControls( camera );
+
 				animate();
 
 			};
 
-			loader.load( './models/sea3d/mascot.sea' );
+			loader.load( './models/sea3d/mascot.tjs.sea' );
 
 			//
 
@@ -104,8 +104,6 @@
 				camera = new THREE.PerspectiveCamera( 45, window.innerWidth / window.innerHeight, 1, 10000 );
 				camera.position.set( 1000, - 300, 1000 );
 
-				controls = new THREE.OrbitControls( camera );
-
 				renderer = new THREE.WebGLRenderer();
 				renderer.setPixelRatio( window.devicePixelRatio );
 				renderer.setSize( window.innerWidth, window.innerHeight );

+ 3 - 7
examples/webgl_loader_sea3d_hierarchy.html

@@ -71,9 +71,7 @@
 			loader = new THREE.SEA3D( {
 
 				autoPlay : false, // Auto play animations
-				container : scene, // Container to add models
-				parser : THREE.SEA3D.BUFFER, // THREE.BufferGeometry
-				multiplier : 1 // Light multiplier
+				container : scene // Container to add models
 
 			} );
 
@@ -88,7 +86,7 @@
 						loader.meshes[i].animation.play("root");
 				}
 
-				// Get the first camera from 3ds Max
+				// Get the first camera from SEA3D Studio
 				// use loader.get... to get others objects
 
 				var cam = loader.cameras[0];
@@ -96,14 +94,12 @@
 				camera.rotation.copy( cam.rotation );
 
 				controls = new THREE.OrbitControls( camera );
-				controls.enableZoom = false;
-				controls.enablePan = false;
 
 				animate();
 
 			};
 
-			loader.load( './models/sea3d/robot.sea' );
+			loader.load( './models/sea3d/robot.tjs.sea' );
 
 			//
 

+ 4 - 6
examples/webgl_loader_sea3d_keyframe.html

@@ -72,9 +72,7 @@
 			loader = new THREE.SEA3D( {
 
 				autoPlay : false, // Manual play animations
-				container : scene, // Container to add models
-				parser : THREE.SEA3D.BUFFER, // THREE.SEA3D.BUFFER to THREE.BufferGeometry
-				multiplier : 1 // Light multiplier
+				container : scene // Container to add models
 
 			} );
 
@@ -87,6 +85,8 @@
 				camera.position.copy( cam.position );
 				camera.rotation.copy( cam.rotation );
 
+				controls = new THREE.OrbitControls( camera );
+
 				// reset global animation time
 				SEA3D.AnimationHandler.setTime( 0 );
 
@@ -98,7 +98,7 @@
 
 			};
 
-			loader.load( './models/sea3d/keyframe.sea' );
+			loader.load( './models/sea3d/keyframe.tjs.sea' );
 
 			//
 			//	Animation Functions
@@ -148,8 +148,6 @@
 				camera = new THREE.PerspectiveCamera( 45, window.innerWidth / window.innerHeight, 1, 2000 );
 				camera.position.set( 1000, - 300, 1000 );
 
-				controls = new THREE.OrbitControls( camera );
-
 				renderer = new THREE.WebGLRenderer();
 				renderer.setPixelRatio( window.devicePixelRatio );
 				renderer.setSize( window.innerWidth, window.innerHeight );

+ 5 - 7
examples/webgl_loader_sea3d_morph.html

@@ -71,21 +71,21 @@
 			loader = new THREE.SEA3D( {
 
 				autoPlay : true, // Auto play animations
-				container : scene, // Container to add models
-				parser : THREE.SEA3D.DEFAULT, // Auto choose THREE.BufferGeometry and THREE.Geometry
-				multiplier : 1 // Light multiplier
+				container : scene // Container to add models
 
 			} );
 
 			loader.onComplete = function( e ) {
 
-				// Get the first camera from 3ds Max
+				// Get the first camera from SEA3D Studio
 				// use loader.get... to get others objects
 
 				var cam = loader.cameras[0];
 				camera.position.copy( cam.position );
 				camera.rotation.copy( cam.rotation );
 
+				controls = new THREE.OrbitControls( camera );
+
 				// get mesh
 				teapot = loader.getMesh("Teapot01");
 
@@ -97,7 +97,7 @@
 
 			};
 
-			loader.load( './models/sea3d/morph.sea' );
+			loader.load( './models/sea3d/morph.tjs.sea' );
 
 			//
 
@@ -111,8 +111,6 @@
 				camera = new THREE.PerspectiveCamera( 45, window.innerWidth / window.innerHeight, 1, 2000 );
 				camera.position.set( 1000, - 300, 1000 );
 
-				controls = new THREE.OrbitControls( camera );
-
 				renderer = new THREE.WebGLRenderer();
 				renderer.setPixelRatio( window.devicePixelRatio );
 				renderer.setSize( window.innerWidth, window.innerHeight );

+ 5 - 6
examples/webgl_loader_sea3d_skinning.html

@@ -74,20 +74,21 @@
 
 				autoPlay : true, // Auto play animations
 				container : scene, // Container to add models
-				parser : THREE.SEA3D.AUTO, // Auto choose THREE.BufferGeometry and THREE.Geometry
-				multiplier : 1 // Light multiplier
+				multiplier : .6 // Light multiplier
 
 			} );
 
 			loader.onComplete = function( e ) {
 
-				// Get the first camera from 3ds Max
+				// Get the first camera from SEA3D Studio
 				// use loader.get... to get others objects
 
 				var cam = loader.cameras[0];
 				camera.position.copy( cam.position );
 				camera.rotation.copy( cam.rotation );
 
+				controls = new THREE.OrbitControls( camera );
+
 				// get meshes
 				player = loader.getMesh("Player");
 
@@ -102,7 +103,7 @@
 
 			};
 
-			loader.load( './models/sea3d/skin.sea' );
+			loader.load( './models/sea3d/skin.tjs.sea' );
 
 			//
 
@@ -116,8 +117,6 @@
 				camera = new THREE.PerspectiveCamera( 45, window.innerWidth / window.innerHeight, 1, 2000 );
 				camera.position.set( 1000, - 300, 1000 );
 
-				controls = new THREE.OrbitControls( camera );
-
 				renderer = new THREE.WebGLRenderer();
 				renderer.setPixelRatio( window.devicePixelRatio );
 				renderer.setSize( window.innerWidth, window.innerHeight );

+ 2 - 4
examples/webgl_loader_sea3d_sound.html

@@ -128,9 +128,7 @@
 			loader = new THREE.SEA3D( {
 
 				autoPlay : true, // Auto play animations
-				container : scene, // Container to add models
-				parser : THREE.SEA3D.AUTO, // Auto choose THREE.BufferGeometry and THREE.Geometry
-				multiplier : 1 // Light multiplier
+				container : scene // Container to add models
 
 			} );
 
@@ -150,7 +148,7 @@
 
 			};
 
-			loader.load( './models/sea3d/sound.sea' );
+			loader.load( './models/sea3d/sound.tjs.sea' );
 
 			//
 

+ 246 - 0
examples/webgl_materials_displacementmap.html

@@ -0,0 +1,246 @@
+<!DOCTYPE html>
+<html lang="en">
+	<head>
+		<title>three.js webgl - materials - displacement map</title>
+		<meta charset="utf-8">
+		<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
+		<style>
+			body {
+				background:#000;
+				color:#fff;
+				padding:0;
+				margin:0;
+				font-weight: bold;
+				overflow:hidden;
+			}
+
+			a {	color: #ffffff;	}
+
+			#info {
+				position: absolute;
+				top: 0px; width: 100%;
+				color: #ffffff;
+				padding: 5px;
+				font-family:Monospace;
+				font-size:13px;
+				text-align:center;
+				z-index:1000;
+			}
+
+			#vt { display:none }
+			#vt, #vt a { color:orange; }
+
+			#stats { position: absolute; top:0; left: 0 }
+			#stats #fps { background: transparent !important }
+			#stats #fps #fpsText { color: #aaa !important }
+			#stats #fps #fpsGraph { display: none }
+
+		</style>
+	</head>
+
+	<body>
+
+		<div id="info">
+			<a href="http://threejs.org" target="_blank">three.js</a> - (<span id="description">normal + ao + displacement + environment</span>) map demo.
+			ninja head from <a href="http://developer.amd.com/tools-and-sdks/archive/legacy-cpu-gpu-tools/amd-gpu-meshmapper/" target="_blank">AMD GPU MeshMapper</a>
+
+			<div id="vt">displacement mapping requires vertex textures</div>
+		</div>
+
+		<script src="../build/three.min.js"></script>
+		<script src="js/controls/OrbitControls.js"></script>
+
+
+		<script src="js/loaders/BinaryLoader.js"></script>
+
+		<script src="js/Detector.js"></script>
+		<script src="js/libs/stats.min.js"></script>
+
+		<script>
+
+			if ( ! Detector.webgl ) Detector.addGetWebGLMessage();
+
+			var stats, loader;
+
+			var camera, scene, renderer, controls;
+
+			var mesh;
+
+			var pointLight;
+
+			var mouseX = 0;
+			var mouseY = 0;
+
+			var windowHalfX = window.innerWidth / 2;
+			var windowHalfY = window.innerHeight / 2;
+
+			var height = 500; // of camera frustum
+
+			var r = 0.0;
+
+			init();
+			animate();
+
+			function init() {
+
+				var container = document.createElement( 'div' );
+				document.body.appendChild( container );
+
+				renderer = new THREE.WebGLRenderer();
+				renderer.setPixelRatio( window.devicePixelRatio );
+				renderer.setSize( window.innerWidth, window.innerHeight );
+				container.appendChild( renderer.domElement );
+
+				renderer.gammaInput = true;
+				renderer.gammaOutput = true;
+
+				//
+
+				scene = new THREE.Scene();
+
+				var aspect = window.innerWidth / window.innerHeight;
+				camera = new THREE.OrthographicCamera( - height * aspect, height * aspect, height, - height, 1, 10000 );
+				camera.position.z = 1500;
+				scene.add( camera );
+
+				controls = new THREE.OrbitControls( camera, renderer.domElement );
+				controls.enableZoom = false;
+				controls.enableDamping = true;
+
+				// lights
+
+				var ambientLight = new THREE.AmbientLight( 0x111111 );
+				scene.add( ambientLight );
+
+				pointLight = new THREE.PointLight( 0xff0000, 0.5 );
+				pointLight.position.z = 2500;
+				scene.add( pointLight );
+
+				var pointLight2 = new THREE.PointLight( 0xff6666, 1 );
+				camera.add( pointLight2 );
+
+				var pointLight3 = new THREE.PointLight( 0x0000ff, 0.5 );
+				pointLight3.position.x = - 1000;
+				pointLight3.position.z = 1000;
+				scene.add( pointLight3 );
+
+				// env map
+
+				var path = "textures/cube/SwedishRoyalCastle/";
+				var format = '.jpg';
+				var urls = [
+						path + 'px' + format, path + 'nx' + format,
+						path + 'py' + format, path + 'ny' + format,
+						path + 'pz' + format, path + 'nz' + format
+					];
+
+				var reflectionCube = THREE.ImageUtils.loadTextureCube( urls, THREE.CubeReflectionMapping );
+
+				// material
+
+				var normalMap = THREE.ImageUtils.loadTexture( "textures/normal/ninja/normal.jpg" );
+
+				var aoMap = THREE.ImageUtils.loadTexture( "textures/normal/ninja/ao.jpg" );
+
+				var displacementMap = THREE.ImageUtils.loadTexture( "textures/normal/ninja/displacement.jpg" );
+
+				var material = new THREE.MeshPhongMaterial( {
+
+					color: 0x0a0100,
+					specular: 0xffffff,
+					shininess: 10,
+
+					normalMap: normalMap,
+					normalScale: new THREE.Vector2( 1, - 1 ), // why does the normal map require negation in this case?
+
+					aoMap: aoMap,
+					aoMapIntensity: 1,
+
+					displacementMap: displacementMap,
+					displacementScale: 2.436143,
+					displacementBias: - 0.428408,
+
+					envMap: reflectionCube,
+					combine: THREE.AddOperation,
+					reflectivity: 0.2,
+
+					side: THREE.DoubleSide
+
+				} );
+
+				//
+
+				loader = new THREE.BinaryLoader();
+
+				loader.load( "obj/ninja/NinjaLo_bin.js", function( geometry ) {
+
+					geometry.faceVertexUvs[ 1 ] = geometry.faceVertexUvs[ 0 ]; // 2nd set of UVs required for aoMap and displacementMap with MeshPhongMaterial
+
+					mesh = new THREE.Mesh( geometry, material );
+					mesh.scale.multiplyScalar( 25 );
+					scene.add( mesh );
+
+				} );
+
+				//
+
+				var description = "normal + ao" + ( renderer.supportsVertexTextures() ? " + displacement + environment" : " + <strike>displacement</strike>" );
+				document.getElementById( "description" ).innerHTML = description;
+				document.getElementById( "vt" ).style.display = renderer.supportsVertexTextures() ? "none" : "block";
+
+				//
+
+				stats = new Stats();
+				container.appendChild( stats.domElement );
+
+				//
+
+				window.addEventListener( 'resize', onWindowResize, false );
+
+			}
+
+			function onWindowResize() {
+
+				var aspect = window.innerWidth / window.innerHeight;
+
+				camera.left = - height * aspect;
+				camera.right = height * aspect;
+				camera.top = height;
+				camera.bottom = - height;
+
+				camera.updateProjectionMatrix();
+
+				renderer.setSize( window.innerWidth, window.innerHeight );
+
+			}
+
+			//
+
+			function animate() {
+
+				requestAnimationFrame( animate );
+
+				controls.update();
+
+				render();
+
+				stats.update();
+
+			}
+
+			function render() {
+
+				pointLight.position.x = 2500 * Math.cos( r );
+				pointLight.position.z = 2500 * Math.sin( r );
+
+				r += 0.01;
+
+				renderer.render( scene, camera );
+
+			}
+
+		</script>
+
+	</body>
+
+</html>

+ 0 - 325
examples/webgl_materials_normaldisplacementmap.html

@@ -1,325 +0,0 @@
-<!DOCTYPE html>
-<html lang="en">
-	<head>
-		<title>three.js webgl - materials - normal map</title>
-		<meta charset="utf-8">
-		<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
-		<style>
-			body {
-				background:#000;
-				color:#fff;
-				padding:0;
-				margin:0;
-				font-weight: bold;
-				overflow:hidden;
-			}
-
-			a {	color: #ffffff;	}
-
-			#info {
-				position: absolute;
-				top: 0px; width: 100%;
-				color: #ffffff;
-				padding: 5px;
-				font-family:Monospace;
-				font-size:13px;
-				text-align:center;
-				z-index:1000;
-			}
-
-			#oldie {
-				background:rgb(200,100,0) !important;
-				color:#fff;
-			}
-
-			#vt { display:none }
-			#vt, #vt a { color:orange; }
-		</style>
-	</head>
-
-	<body>
-
-		<div id="info">
-			<a href="http://threejs.org" target="_blank">three.js</a> - webgl (<span id="description">normal + ao + displacement + environment + shadow</span>) map demo.
-			ninja head from <a href="http://developer.amd.com/archive/gpu/MeshMapper/pages/default.aspx" target="_blank">AMD GPU MeshMapper</a>
-
-			<div id="vt">displacement mapping needs vertex textures (GPU with Shader Model 3.0)</div>
-		</div>
-
-		<script src="../build/three.min.js"></script>
-
-		<script src="js/loaders/BinaryLoader.js"></script>
-		<script src="js/shaders/NormalDisplacementShader.js"></script>
-
-		<script src="js/Detector.js"></script>
-		<script src="js/libs/stats.min.js"></script>
-
-		<script>
-
-			if ( ! Detector.webgl ) Detector.addGetWebGLMessage();
-
-			var stats, loader;
-
-			var camera, scene, renderer;
-
-			var mesh1, mesh2;
-
-			var pointLight;
-
-			var mouseX = 0;
-			var mouseY = 0;
-
-			var windowHalfX = window.innerWidth / 2;
-			var windowHalfY = window.innerHeight / 2;
-
-			var r = 0.0;
-
-			document.addEventListener( 'mousemove', onDocumentMouseMove, false );
-
-			init();
-			animate();
-
-			function init() {
-
-				var container = document.createElement( 'div' );
-				document.body.appendChild( container );
-
-				scene = new THREE.Scene();
-
-				var width = 500;
-				var aspect = window.innerWidth / window.innerHeight;
-				camera = new THREE.OrthographicCamera( - width * aspect, width * aspect, width, - width, 1, 10000 );
-				camera.position.z = 1500;
-
-				// LIGHTS
-
-				var ambientLight = new THREE.AmbientLight( 0x111111 );
-				scene.add( ambientLight );
-
-				pointLight = new THREE.PointLight( 0xff0000 );
-				pointLight.position.z = 10000;
-				pointLight.distance = 4000;
-				scene.add( pointLight );
-
-				var pointLight2 = new THREE.PointLight( 0xff5500 );
-				pointLight2.position.z = 1000;
-				scene.add( pointLight2 );
-
-				var pointLight3 = new THREE.PointLight( 0x0000ff );
-				pointLight3.position.x = -1000;
-				pointLight3.position.z = 1000;
-				scene.add( pointLight3 );
-
-				var spotLight = new THREE.SpotLight( 0xaaaaaa );
-				spotLight.position.set( 1000, 500, 1000 );
-				spotLight.castShadow = true;
-				spotLight.shadowCameraNear = 500;
-				spotLight.shadowCameraFov = 70;
-				spotLight.shadowBias = - 0.001;
-				spotLight.shadowMapWidth = 1024;
-				spotLight.shadowMapHeight = 1024;
-				spotLight.shadowDarkness = 0.5;
-				scene.add( spotLight );
-
-				// env map
-
-				var path = "textures/cube/SwedishRoyalCastle/";
-				var format = '.jpg';
-				var urls = [
-						path + 'px' + format, path + 'nx' + format,
-						path + 'py' + format, path + 'ny' + format,
-						path + 'pz' + format, path + 'nz' + format
-					];
-
-				var reflectionCube = THREE.ImageUtils.loadTextureCube( urls, THREE.CubeReflectionMapping );
-
-				// common material parameters
-
-				var diffuse = 0x0a0100, specular = 0xffffff, shininess = 10, scale = 23;
-
-				// normal map shader
-
-				var shader = THREE.NormalDisplacementShader;
-				var uniforms = THREE.UniformsUtils.clone( shader.uniforms );
-
-				uniforms[ "enableAO" ].value = true;
-				uniforms[ "enableDiffuse" ].value = false;
-				uniforms[ "enableSpecular" ].value = false;
-				uniforms[ "enableReflection" ].value = true;
-				uniforms[ "enableDisplacement" ].value = true;
-
-				uniforms[ "tNormal" ].value = THREE.ImageUtils.loadTexture( "textures/normal/ninja/normal.jpg" );
-				uniforms[ "tAO" ].value = THREE.ImageUtils.loadTexture( "textures/normal/ninja/ao.jpg" );
-
-				uniforms[ "tDisplacement" ].value = THREE.ImageUtils.loadTexture( "textures/normal/ninja/displacement.jpg" );
-				uniforms[ "uDisplacementBias" ].value = - 0.428408;
-				uniforms[ "uDisplacementScale" ].value = 2.436143;
-
-				uniforms[ "uNormalScale" ].value.y = - 1;
-
-				uniforms[ "diffuse" ].value.setHex( diffuse );
-				uniforms[ "specular" ].value.setHex( specular );
-
-				uniforms[ "shininess" ].value = shininess;
-
-				uniforms[ "tCube" ].value = reflectionCube;
-				uniforms[ "reflectivity" ].value = 0.2;
-
-				var defines = {};
-				defines[ "ENVMAP_MODE_REFLECTION" ] = "";
-
-				var parameters = {
-					defines: defines,
-					uniforms: uniforms,
-					vertexShader: shader.vertexShader,
-					fragmentShader: shader.fragmentShader,
-					lights: true,
-					fog: false
-				};
-
-				var material1 = new THREE.ShaderMaterial( parameters );
-
-				var material2 = new THREE.MeshPhongMaterial( {
-					color: diffuse,
-					specular: specular,
-					shininess: shininess,
-					normalMap: uniforms[ "tNormal" ].value,
-					normalScale: uniforms[ "uNormalScale" ].value,
-					aoMap: uniforms[ "tAO" ].value,
-					aoMapIntensity: 1,
-					envMap: reflectionCube,
-					combine: THREE.MixOperation,
-					reflectivity: 0.2
-				} );
-
-				//
-
-				loader = new THREE.BinaryLoader();
-				loader.load( "obj/ninja/NinjaLo_bin.js", function( geometry ) { createScene( geometry, scale, material1, material2 ) } );
-
-				//
-
-				renderer = new THREE.WebGLRenderer();
-				renderer.setPixelRatio( window.devicePixelRatio );
-				renderer.setSize( window.innerWidth, window.innerHeight );
-				container.appendChild( renderer.domElement );
-
-				//
-
-				renderer.gammaInput = true;
-				renderer.gammaOutput = true;
-
-				//
-
-				renderer.shadowMap.enabled = true;
-				renderer.shadowMap.type = THREE.PCFShadowMap;
-
-				//
-
-				var description = "normal + ao" + ( renderer.supportsVertexTextures() ? " + displacement + environment + shadow" : " + <strike>displacement</strike>" );
-				document.getElementById( "description" ).innerHTML = description;
-				document.getElementById( "vt" ).style.display = renderer.supportsVertexTextures() ? "none" : "block";
-
-				//
-
-				stats = new Stats();
-				stats.domElement.style.position = 'absolute';
-				stats.domElement.style.top = '0px';
-				stats.domElement.style.zIndex = 100;
-				container.appendChild( stats.domElement );
-
-				//
-
-				window.addEventListener( 'resize', onWindowResize, false );
-
-			}
-
-			function onWindowResize() {
-
-				windowHalfX = window.innerWidth / 2;
-				windowHalfY = window.innerHeight / 2;
-
-				camera.left = window.innerWidth / - 2;
-				camera.right = window.innerWidth / 2;
-				camera.top = window.innerHeight / 2;
-				camera.bottom = window.innerHeight / - 2;
-
-				camera.updateProjectionMatrix();
-
-				renderer.setSize( window.innerWidth, window.innerHeight );
-
-			}
-
-			function createScene( geometry, scale, material1, material2 ) {
-
-				geometry.computeTangents(); // attribute tangents are required for NormalDisplacementShader
-
-				geometry.faceVertexUvs[ 1 ] = geometry.faceVertexUvs[ 0 ]; // 2nd set of UVs required for aoMap with MeshPhongMaterial
-
-				mesh1 = new THREE.Mesh( geometry, material1 );
-				mesh1.position.x = - scale * 12;
-				mesh1.scale.set( scale, scale, scale );
-				mesh1.castShadow = true;
-				mesh1.receiveShadow = true;
-				scene.add( mesh1 );
-
-				mesh2 = new THREE.Mesh( geometry, material2 );
-				mesh2.position.x = scale * 12;
-				mesh2.scale.set( scale, scale, scale );
-				mesh2.castShadow = true;
-				mesh2.receiveShadow = true;
-				scene.add( mesh2 );
-
-			}
-
-			function onDocumentMouseMove(event) {
-
-				mouseX = ( event.clientX - windowHalfX ) * 10;
-				mouseY = ( event.clientY - windowHalfY ) * 10;
-
-			}
-
-			//
-
-			function animate() {
-
-				requestAnimationFrame( animate );
-
-				render();
-
-				stats.update();
-
-			}
-
-			function render() {
-
-				var ry = mouseX * 0.0003, rx = mouseY * 0.0003;
-
-				if( mesh1 ) {
-
-					mesh1.rotation.y = ry;
-					mesh1.rotation.x = rx;
-
-				}
-
-				if( mesh2 ) {
-
-					mesh2.rotation.y = ry;
-					mesh2.rotation.x = rx;
-
-				}
-
-				pointLight.position.x = 2500 * Math.cos( r );
-				pointLight.position.z = 2500 * Math.sin( r );
-
-				r += 0.01;
-
-				renderer.render( scene, camera );
-
-			}
-
-
-		</script>
-
-	</body>
-</html>

+ 0 - 2
examples/webgl_materials_normalmap.html

@@ -190,8 +190,6 @@
 
 			function createScene( geometry, scale, material ) {
 
-				geometry.computeTangents();
-
 				mesh1 = new THREE.Mesh( geometry, material );
 
 				mesh1.position.y = - 50;

+ 15 - 5
examples/webgl_materials_skin.html

@@ -87,6 +87,8 @@
 			var windowHalfX = window.innerWidth / 2;
 			var windowHalfY = window.innerHeight / 2;
 
+			var pixelSizeUniform = { type: 'f', value: 0.001 };
+
 			var firstPass = true;
 
 			init();
@@ -134,14 +136,18 @@
 				uniformsUV[ "uRoughness" ].value = 0.185;
 				uniformsUV[ "uSpecularBrightness" ].value = 0.8;
 
+
 				var uniforms = THREE.UniformsUtils.clone( uniformsUV );
 				uniforms[ "tDiffuse" ].value = uniformsUV[ "tDiffuse" ].value;
 				uniforms[ "tNormal" ].value = uniformsUV[ "tNormal" ].value;
 				uniforms[ "passID" ].value = 1;
 
-				var parameters = { fragmentShader: shader.fragmentShader, vertexShader: shader.vertexShader, uniforms: uniforms, lights: true };
-				var parametersUV = { fragmentShader: shader.fragmentShader, vertexShader: shader.vertexShaderUV, uniforms: uniformsUV, lights: true };
+				// let those refer to the same object for central control
+				uniformsUV[ "pixelSize" ] = pixelSizeUniform;
+				uniforms[ "pixelSize" ] = pixelSizeUniform;
 
+				var parameters = { fragmentShader: shader.fragmentShader, vertexShader: shader.vertexShader, uniforms: uniforms, lights: true, derivatives: true };
+				var parametersUV = { fragmentShader: shader.fragmentShader, vertexShader: shader.vertexShaderUV, uniforms: uniformsUV, lights: true, derivatives: true };
 
 				material = new THREE.ShaderMaterial( parameters );
 				var materialUV = new THREE.ShaderMaterial( parametersUV );
@@ -156,9 +162,10 @@
 				renderer = new THREE.WebGLRenderer( { antialias: false } );
 				renderer.setClearColor( 0x050505 );
 				renderer.setPixelRatio( window.devicePixelRatio );
-				renderer.setSize( window.innerWidth, window.innerHeight );
 				renderer.autoClear = false;
 
+				onWindowResize(); // sets size
+
 				container.appendChild( renderer.domElement );
 
 				// STATS
@@ -267,14 +274,17 @@
 				camera.aspect = window.innerWidth / window.innerHeight;
 				camera.updateProjectionMatrix();
 
+				var projection00 = camera.projectionMatrix.elements[0];
+				// == 1 / windowHalfX, in view space, assuming near == 1
+
+				pixelSizeUniform.value = 1 / ( projection00 * windowHalfX );
+
 				renderer.setSize( window.innerWidth, window.innerHeight );
 
 			}
 
 			function createScene( geometry, scale, material ) {
 
-				geometry.computeTangents();
-
 				mesh = new THREE.Mesh( geometry, material );
 				mesh.position.y = - 50;
 				mesh.scale.set( scale, scale, scale );

+ 0 - 2
examples/webgl_postprocessing_advanced.html

@@ -329,8 +329,6 @@
 
 			function createMesh( geometry, scene, scale ) {
 
-				geometry.computeTangents();
-
 				var mat2 = new THREE.MeshLambertMaterial( {
 
 					color: 0x999999,

+ 377 - 0
examples/webgl_raycast_texture.html

@@ -0,0 +1,377 @@
+<!DOCTYPE html>
+<html lang="en">
+	<head>
+		<title>three.js raycast - texture</title>
+		<meta charset="utf-8">
+		<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
+		<style>
+			body {
+				color: #808080;
+				font-family:Monospace;
+				font-size:13px;
+				text-align:center;
+
+				background-color: #ffffff;
+				margin: 0px;
+				overflow: hidden;
+			}
+
+			#info {
+				position: absolute;
+				top: 0px; width: 100%;
+				padding: 5px;
+			}
+
+			#controls {
+				position: absolute;
+				text-align:left;
+				top: 40px;
+				left: 5px;
+				padding: 5px;
+			}
+
+			.control {
+				margin-bottom: 3px;
+			}
+
+			input {
+				width: 50px;
+			}
+		</style>
+	</head>
+	<body>
+		<div id="container"></div>
+		<div id="info"><a href="http://threejs.org" target="_blank">three.js</a> - raycast texture<br>Left to right: buffer geometry - geometry - indexed buffer geometry</div>
+		<fieldset id="controls">
+			<legend>Circle</legend>
+			<div class="control">
+				WrapS : <select onchange="setwrapS(this)">
+					<option value="ClampToEdgeWrapping">ClampToEdgeWrapping</option>
+					<option value="RepeatWrapping" selected>RepeatWrapping</option>
+					<option value="MirroredRepeatWrapping">MirroredRepeatWrapping</option>
+				</select>
+			</div>
+			<div class="control">
+				WrapT : <select onchange="setwrapT(this)">
+					<option value="ClampToEdgeWrapping">ClampToEdgeWrapping</option>
+					<option value="RepeatWrapping" selected>RepeatWrapping</option>
+					<option value="MirroredRepeatWrapping">MirroredRepeatWrapping</option>
+				</select>
+			</div>
+			<div class="control">
+				Offset : X <input type="number" value="0" step="0.05" onchange="setOffsetU(this)" />
+				Y <input type="number" value="0" step="0.05" onchange="setOffsetV(this)" /><br />
+			</div>
+			<div class="control">
+				Repeat : X <input type="number" value="1" step="0.1" onchange="setRepeatU(this)" />
+				Y <input type="number" value="1" step="0.1" onchange="setRepeatV(this)" />
+			</div>
+		</fieldset>
+		<script src="../build/three.min.js"></script>
+		<script>
+
+			CanvasTexture = function ( parentTexture ) {
+
+				this._canvas = document.createElement( "canvas" );
+				this._canvas.width = this._canvas.height = 1024;
+				this._context2D = this._canvas.getContext( "2d" );
+
+				if ( parentTexture ) {
+
+					this._parentTexture.push( parentTexture );
+					parentTexture.image = this._canvas;
+
+				}
+
+				var that = this;
+				this._background = document.createElement( "img" );
+				this._background.addEventListener( "load", function ( event ) {
+
+					that._canvas.width = that._background.naturalWidth;
+					that._canvas.height = that._background.naturalHeight;
+
+					that._crossRadius = Math.ceil( Math.min( that._canvas.width, that._canvas.height / 30 ) );
+					that._crossMax = Math.ceil( 0.70710678 * that._crossRadius );
+					that._crossMin = Math.ceil( that._crossMax / 10 );
+					that._crossThickness = Math.ceil( that._crossMax / 10 );
+
+					that._draw();
+
+				}, false );
+				this._background.crossOrigin = '';
+				this._background.src = "textures/UV_Grid_Sm.jpg";
+
+				this._draw();
+
+			}
+
+
+			CanvasTexture.prototype = {
+
+				constructor: CanvasTexture,
+
+				_canvas: null,
+				_context2D: null,
+				_xCross: 0,
+				_yCross: 0,
+
+				_crossRadius: 57,
+				_crossMax: 40,
+				_crossMin: 4,
+				_crossThickness: 4,
+
+				_parentTexture: [],
+
+				addParent: function ( parentTexture ) {
+
+					if ( this._parentTexture.indexOf( parentTexture ) === - 1 ) {
+
+						this._parentTexture.push( parentTexture );
+						parentTexture.image = this._canvas;
+
+					}
+
+				},
+
+				setCrossPosition: function ( x, y ) {
+
+					this._xCross = x * this._canvas.width;
+					this._yCross = y * this._canvas.height;
+
+					this._draw();
+
+				},
+
+				_draw: function () {
+
+					if ( ! this._context2D ) return;
+
+					this._context2D.clearRect( 0, 0, this._canvas.width, this._canvas.height )
+
+					// Background.
+					this._context2D.drawImage( this._background, 0, 0 );
+
+					// Yellow cross.
+					this._context2D.lineWidth = this._crossThickness * 3;
+					this._context2D.strokeStyle = "#FFFF00";
+
+					this._context2D.beginPath();
+					this._context2D.moveTo( this._xCross - this._crossMax - 2, this._yCross - this._crossMax - 2 );
+					this._context2D.lineTo( this._xCross - this._crossMin, this._yCross - this._crossMin );
+
+					this._context2D.moveTo( this._xCross + this._crossMin, this._yCross + this._crossMin );
+					this._context2D.lineTo( this._xCross + this._crossMax + 2, this._yCross + this._crossMax + 2 );
+
+					this._context2D.moveTo( this._xCross - this._crossMax - 2, this._yCross + this._crossMax + 2 );
+					this._context2D.lineTo( this._xCross - this._crossMin, this._yCross + this._crossMin );
+
+					this._context2D.moveTo( this._xCross + this._crossMin, this._yCross - this._crossMin );
+					this._context2D.lineTo( this._xCross + this._crossMax + 2, this._yCross - this._crossMax - 2 );
+
+					this._context2D.stroke();
+
+					for ( var i = 0; i < this._parentTexture.length; i ++ ) {
+
+						this._parentTexture[ i ].needsUpdate = true;
+
+					}
+
+				}
+
+			}
+
+		</script>
+		<script>
+
+			var width = window.innerWidth;
+			var height = window.innerHeight;
+
+			var canvas;
+			var planeTexture, cubeTexture, circleTexture;
+
+			var container;
+
+			var camera, scene, renderer;
+
+			var raycaster = new THREE.Raycaster();
+			var mouse = new THREE.Vector2();
+			var onClickPosition = new THREE.Vector2();
+
+			init();
+			render();
+
+			function init() {
+
+				container = document.getElementById( "container" );
+
+				scene = new THREE.Scene();
+
+				camera = new THREE.PerspectiveCamera( 45, width / height, 1, 1000 );
+				camera.position.x = - 30;
+				camera.position.y = 40;
+				camera.position.z = 50;
+				camera.lookAt( scene.position );
+
+				renderer = new THREE.WebGLRenderer();
+				renderer.setClearColor( new THREE.Color( 0xEEEEEE, 1.0 ) );
+				renderer.setSize( width, height );
+				container.appendChild( renderer.domElement );
+
+				// A cube, in the middle.
+				cubeTexture = new THREE.Texture( undefined, THREE.UVMapping, THREE.RepeatWrapping, THREE.RepeatWrapping );
+				canvas = new CanvasTexture( cubeTexture );
+				var cubeMaterial = new THREE.MeshBasicMaterial( { map: cubeTexture } );
+				var cubeGeometry = new THREE.BoxGeometry( 20, 20, 20 );
+				// Set a specific texture mapping.
+				var uvs;
+				for ( var i = 0; i < cubeGeometry.faceVertexUvs[ 0 ].length; i ++ ) {
+
+					uvs = cubeGeometry.faceVertexUvs[ 0 ][ i ];
+					for ( var j = 0; j < 3; j ++ ) {
+
+						if ( uvs[ j ].x < 0.1 ) uvs[ j ].x = - 1;
+						if ( uvs[ j ].y < 0.1 ) uvs[ j ].y = - 1;
+
+					}
+
+				}
+				var cube = new THREE.Mesh( cubeGeometry, cubeMaterial );
+				cube.position.x = 4;
+				cube.position.y = - 5;
+				cube.position.z = 0;
+				scene.add( cube );
+
+				// A plane on the left.
+				planeTexture = new THREE.Texture( undefined, THREE.UVMapping, THREE.MirroredRepeatWrapping, THREE.MirroredRepeatWrapping );
+				canvas.addParent( planeTexture );
+				var planeMaterial = new THREE.MeshBasicMaterial( { map: planeTexture } );
+				var planeGeometry = new THREE.PlaneBufferGeometry( 25, 25, 1, 1 );
+				var uvs = planeGeometry.attributes.uv.array;
+				// Set a specific texture mapping.
+				for ( var i = 0; i < uvs.length; i ++ ) {
+
+					uvs[ i ] *= 2;
+
+				}
+				var plane = new THREE.Mesh( planeGeometry, planeMaterial );
+				plane.position.x = - 16;
+				plane.position.y = - 5;
+				plane.position.z = 0;
+				scene.add( plane );
+
+				// A circle on the right.
+				circleTexture = new THREE.Texture( undefined, THREE.UVMapping, THREE.RepeatWrapping, THREE.RepeatWrapping );
+				canvas.addParent( circleTexture );
+				var circleMaterial = new THREE.MeshBasicMaterial( { map: circleTexture } );
+				var circleGeometry = new THREE.CircleBufferGeometry( 25, 40, 0, Math.PI * 2 );
+				var uvs = circleGeometry.attributes.uv.array;
+				// Set a specific texture mapping.
+				for ( var i = 0; i < uvs.length; i ++ ) {
+
+					uvs[ i ] = ( uvs[ i ] - 0.25 ) * 2;
+
+				}
+				var circle = new THREE.Mesh( circleGeometry, circleMaterial );
+				circle.position.x = 24;
+				circle.position.y = - 5;
+				circle.position.z = 0;
+				scene.add( circle );
+
+				window.addEventListener( 'resize', onWindowResize, false );
+				container.addEventListener( 'mousemove', onMouseMove, false );
+
+			}
+
+			function onWindowResize() {
+
+				camera.aspect = window.innerWidth / window.innerHeight;
+				camera.updateProjectionMatrix();
+
+				renderer.setSize( window.innerWidth, window.innerHeight );
+
+			};
+
+			function onMouseMove( evt ) {
+
+				evt.preventDefault();
+
+				var array = getMousePosition( container, evt.clientX, evt.clientY );
+				onClickPosition.fromArray( array );
+
+				var intersects = getIntersects( onClickPosition, scene.children );
+
+				if ( intersects.length > 0 && intersects[ 0 ].uv ) {
+
+					var uv = intersects[ 0 ].uv;
+					intersects[ 0 ].object.material.map.transformUv( uv );
+					canvas.setCrossPosition( uv.x, uv.y );
+
+				}
+
+			};
+
+			var getMousePosition = function ( dom, x, y ) {
+
+				var rect = dom.getBoundingClientRect();
+				return [ ( x - rect.left ) / rect.width, ( y - rect.top ) / rect.height ];
+
+			};
+
+			var getIntersects = function ( point, objects ) {
+
+				mouse.set( ( point.x * 2 ) - 1, - ( point.y * 2 ) + 1 );
+
+				raycaster.setFromCamera( mouse, camera );
+
+				return raycaster.intersectObjects( objects );
+
+			};
+
+			function render() {
+
+				requestAnimationFrame( render );
+				renderer.render( scene, camera );
+
+			};
+
+			function setwrapS( that ) {
+
+				circleTexture.wrapS = THREE[ that.value ];
+				circleTexture.needsUpdate = true;
+
+			};
+
+			function setwrapT( that ) {
+
+				circleTexture.wrapT = THREE[ that.value ];
+				circleTexture.needsUpdate = true;
+
+			};
+
+			function setOffsetU( that ) {
+
+				circleTexture.offset.x = parseFloat( that.value );
+
+			};
+
+			function setOffsetV( that ) {
+
+				circleTexture.offset.y = parseFloat( that.value );
+
+			};
+
+			function setRepeatU( that ) {
+
+				circleTexture.repeat.x = parseFloat( that.value );
+
+			};
+
+			function setRepeatV( that ) {
+
+				circleTexture.repeat.y = parseFloat( that.value );
+
+			};
+
+		</script>
+	</body>
+</html>

+ 1 - 9
examples/webgl_sandbox.html

@@ -97,14 +97,7 @@
 
 				];
 
-				var geometries = [];
-
-				for ( var i = 0, l = materials.length; i < l; i ++ ) {
-
-					var geometry = new THREE.SphereGeometry( 50, 32, 16 );
-					geometries.push( geometry );
-
-				}
+				var geometry = new THREE.SphereGeometry( 50, 32, 16 );
 
 				for ( var i = 0; i < 5000; i ++ ) {
 
@@ -115,7 +108,6 @@
 					var index = Math.floor( ( i / 5000 ) * materials.length );
 
 					var material = materials[ index ];
-					var geometry = geometries[ index ];
 
 					var mesh = new THREE.Mesh( geometry, material );
 

+ 3 - 1
examples/webgl_terrain_dynamic.html

@@ -73,6 +73,7 @@
 		<script src="js/postprocessing/MaskPass.js"></script>
 		<script src="js/postprocessing/SavePass.js"></script>
 
+		<script src="js/BufferGeometryUtils.js"></script>
 		<script src="js/ShaderTerrain.js"></script>
 
 		<script src="js/Detector.js"></script>
@@ -415,7 +416,8 @@
 				// TERRAIN MESH
 
 				var geometryTerrain = new THREE.PlaneBufferGeometry( 6000, 6000, 256, 256 );
-				geometryTerrain.computeTangents();
+
+				THREE.BufferGeometryUtils.computeTangents( geometryTerrain );
 
 				terrain = new THREE.Mesh( geometryTerrain, mlib[ "terrain" ] );
 				terrain.position.set( 0, -125, 0 );

+ 0 - 479
examples/webgldeferred_animation.html

@@ -1,479 +0,0 @@
-<!DOCTYPE HTML>
-<html lang="en">
-	<head>
-		<title>three.js webgl - deferred rendering [morphing + skinning]</title>
-		<meta charset="utf-8" />
-		<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
-		<style>
-			body {
-				background-color: #000;
-				margin: 0px;
-				overflow: hidden;
-			}
-
-			#info {
-				position: absolute;
-				top: 20px; width: 100%;
-				color: #ffffff;
-				padding: 5px;
-				font-family: Monospace;
-				font-size: 13px;
-				text-align: center;
-			}
-
-			a {
-				color: #ff0080;
-				text-decoration: none;
-			}
-
-			a:hover {
-				color: #0080ff;
-			}
-
-			#stats { position: absolute; top:10px; left: 5px }
-			#stats #fps { background: transparent !important }
-			#stats #fps #fpsText { color: #aaa !important }
-			#stats #fps #fpsGraph { display: none }
-		</style>
-	</head>
-
-	<body>
-		<div id="info">
-			<a href="http://threejs.org" target="_blank">three.js</a> - webgl deferred rendering with morphing and skinning animations -
-			characters from <a href="http://www.sintel.org/">Sintel</a> and by <a href="http://opengameart.org/content/walk-cycles">Clint Bellanger</a>
-		</div>
-		<div id="container"></div>
-
-
-		<script src="js/libs/stats.min.js"></script>
-
-		<script src="../build/three.min.js"></script>
-
-		<script src="js/Detector.js"></script>
-
-		<script src="js/renderers/WebGLDeferredRenderer.js"></script>
-		<script src="js/ShaderDeferred.js"></script>
-
-		<script src="js/shaders/CopyShader.js"></script>
-		<script src="js/shaders/FXAAShader.js"></script>
-
-		<script src="js/postprocessing/EffectComposer.js"></script>
-		<script src="js/postprocessing/RenderPass.js"></script>
-		<script src="js/postprocessing/ShaderPass.js"></script>
-		<script src="js/postprocessing/MaskPass.js"></script>
-
-		<script>
-
-			if ( ! Detector.webgl ) Detector.addGetWebGLMessage();
-
-			var SCALE = 0.75;
-
-			var WIDTH = window.innerWidth;
-			var HEIGHT = window.innerHeight;
-
-			var NEAR = 1.0, FAR = 350.0;
-			var VIEW_ANGLE = 45;
-
-			// controls
-
-			var mouseX = 0;
-			var mouseY = 0;
-
-			var targetX = 0, targetY = 0;
-			var angle = 0;
-			var target = new THREE.Vector3( 0, 0, 0 );
-
-			var windowHalfX = window.innerWidth / 2;
-			var windowHalfY = window.innerHeight / 2;
-
-			// core
-
-			var renderer, camera, scene, controls, stats, clock;
-
-			// lights
-
-			var numLights = 50;
-			var lights = [];
-
-			// morphs
-
-			var morphs = [];
-
-			// skins
-
-			var skins = [];
-
-			//
-
-			init();
-			animate();
-
-			// -----------------------------
-
-			function init() {
-
-				// renderer
-
-				renderer = new THREE.WebGLDeferredRenderer( { width: WIDTH, height: HEIGHT, scale: SCALE, brightness: 2, antialias: true } );
-
-				var container = document.getElementById( 'container' );
-				container.appendChild( renderer.domElement );
-
-				// camera
-
-				camera = new THREE.PerspectiveCamera( VIEW_ANGLE, WIDTH / HEIGHT, NEAR, FAR );
-				camera.position.z = 150;
-
-				// scene
-
-				scene = new THREE.Scene();
-				scene.add( camera );
-
-				// stats
-
-				stats = new Stats();
-				stats.domElement.style.position = 'absolute';
-				stats.domElement.style.top = '8px';
-				stats.domElement.style.zIndex = 100;
-				container.appendChild( stats.domElement );
-
-				// clock
-
-				clock = new THREE.Clock();
-
-				// add lights
-
-				initLights();
-
-				// add objects
-
-				initObjects();
-
-				// events
-
-				document.addEventListener( 'mousemove', onDocumentMouseMove, false );
-				window.addEventListener( 'resize', onWindowResize, false );
-
-			}
-
-
-			// -----------------------------
-
-			function initLights() {
-
-				var distance = 40;
-
-				// front light
-
-				var light = new THREE.PointLight( 0xffffff, 1.5, 1.5 * distance );
-				scene.add( light );
-				lights.push( light );
-
-				// random lights
-
-				var c = new THREE.Vector3();
-
-				for ( var i = 1; i < numLights; i ++ ) {
-
-					var light = new THREE.PointLight( 0xffffff, 2.0, distance );
-
-					c.set( Math.random(), Math.random(), Math.random() ).normalize();
-					light.color.setRGB( c.x, c.y, c.z );
-
-					scene.add( light );
-					lights.push( light );
-
-				}
-
-				var geometry = new THREE.SphereGeometry( 0.7, 7, 7 );
-
-				for ( var i = 0; i < numLights; i ++ ) {
-
-					var light = lights[ i ];
-
-					var material = new THREE.MeshBasicMaterial();
-					material.color = light.color;
-
-					var emitter = new THREE.Mesh( geometry, material );
-					light.add( emitter );
-
-				}
-
-			}
-
-			function ensureLoop( animation ) {
-
-				for ( var i = 0; i < animation.hierarchy.length; i ++ ) {
-
-					var bone = animation.hierarchy[ i ];
-
-					var first = bone.keys[ 0 ];
-					var last = bone.keys[ bone.keys.length - 1 ];
-
-					last.pos = first.pos;
-					last.rot = first.rot;
-					last.scl = first.scl;
-
-				}
-
-			}
-
-			function initObjects() {
-
-				// add animated model
-
-				var loader = new THREE.JSONLoader();
-				loader.load( "models/animated/elderlyWalk.js", function( geometry ) {
-
-					geometry.computeMorphNormals();
-
-					var material = new THREE.MeshPhongMaterial( { color: 0xffffff, specular: 0x333333, shininess: 20, morphTargets: true, morphNormals: true, vertexColors: THREE.NoColors, shading: THREE.FlatShading } );
-					var meshAnim = new THREE.MorphAnimMesh( geometry, material );
-
-					meshAnim.duration = 3000;
-					meshAnim.userData.delta = -13;
-
-					meshAnim.scale.multiplyScalar( 50 );
-					meshAnim.position.set( 180, -48, -10 );
-					meshAnim.rotation.y = -Math.PI/2;
-
-					scene.add( meshAnim );
-					morphs.push( meshAnim );
-
-				} );
-
-				loader.load( "models/skinned/human_walk_0_female.js", function ( geometry, materials ) {
-
-					geometry.computeVertexNormals();
-					geometry.computeBoundingBox();
-
-					ensureLoop( geometry.animation );
-
-					for ( var i = 0, il = materials.length; i < il; i ++ ) {
-
-						var originalMaterial = materials[ i ];
-						originalMaterial.skinning = true;
-
-						originalMaterial.map = undefined;
-						originalMaterial.shading = THREE.SmoothShading;
-						originalMaterial.color.setHSL( 0.01, 0.3, 0.3 );
-						originalMaterial.specular.setHSL( 0, 0, 0.1 );
-						originalMaterial.shininess = 75;
-
-					}
-
-					var s = 18.5;
-
-					var material = new THREE.MeshFaceMaterial( materials );
-					var mesh = new THREE.SkinnedMesh( geometry, material, false );
-					mesh.scale.set( s, s, s );
-
-					mesh.rotation.y = Math.PI/2;
-
-					mesh.position.x = -100;
-					mesh.position.y = -geometry.boundingBox.min.y * s - 48;
-					mesh.position.z = 18;
-
-					mesh.userData.delta = 25;
-
-					scene.add( mesh );
-					skins.push( mesh );
-
-
-					animation = new THREE.Animation( mesh, geometry.animation );
-					animation.play();
-					animation.update( 0 );
-
-				} );
-
-				// add box
-
-				var box = generateBox();
-				box.scale.multiplyScalar( 8 );
-				scene.add( box );
-
-			}
-
-			// -----------------------------
-
-			function generateBox() {
-
-				var object = new THREE.Object3D();
-
-				var mapHeight2 = THREE.ImageUtils.loadTexture( "obj/lightmap/rocks.jpg" );
-				mapHeight2.repeat.set( 3, 1.5 );
-				mapHeight2.wrapS = mapHeight2.wrapT = THREE.RepeatWrapping;
-				mapHeight2.anisotropy = 4;
-				mapHeight2.format = THREE.RGBFormat;
-
-				var mapHeight3 = THREE.ImageUtils.loadTexture( "textures/water.jpg" );
-				mapHeight3.repeat.set( 16, 8 );
-				mapHeight3.wrapS = mapHeight3.wrapT = THREE.RepeatWrapping;
-				mapHeight3.anisotropy = 4;
-				mapHeight3.format = THREE.RGBFormat;
-
-				var geoPlane = new THREE.PlaneBufferGeometry( 40, 20 );
-
-				var matPlaneSide   = new THREE.MeshPhongMaterial( { color: 0x000000, specular: 0x222222, shininess: 75, bumpMap: mapHeight2, bumpScale: 0.5 } );
-				var matPlaneBottom = new THREE.MeshPhongMaterial( { color: 0x000000, specular: 0x222222, shininess: 75, bumpMap: mapHeight3, bumpScale: 0.5 } );
-				var matPlaneTop    = new THREE.MeshPhongMaterial( { color: 0x000000, specular: 0x222222, shininess: 75, bumpMap: mapHeight3, bumpScale: 1 } );
-
-
-				// bottom
-
-				var mesh = new THREE.Mesh( geoPlane, matPlaneBottom );
-				mesh.position.z = -2;
-				mesh.position.y = -6;
-				mesh.rotation.x = -Math.PI/2;
-				object.add( mesh );
-
-				// top
-
-				var mesh = new THREE.Mesh( geoPlane, matPlaneTop );
-				mesh.position.z = -2;
-				mesh.position.y = 7;
-				mesh.rotation.x = Math.PI/2;
-				object.add( mesh );
-
-				// back
-
-				var mesh = new THREE.Mesh( geoPlane, matPlaneSide );
-				mesh.position.z = -4;
-				mesh.position.y = 0;
-				object.add( mesh );
-
-				// right
-
-				var mesh = new THREE.Mesh( geoPlane, matPlaneSide );
-				mesh.position.z = 0;
-				mesh.position.y = 0;
-				mesh.position.x = 13;
-				mesh.rotation.y = -Math.PI/2;
-				//object.add( mesh );
-
-				// left
-
-				var mesh = new THREE.Mesh( geoPlane, matPlaneSide );
-				mesh.position.z = 0;
-				mesh.position.y = 0;
-				mesh.position.x = -13;
-				mesh.rotation.y = Math.PI/2;
-				//object.add( mesh );
-
-				return object;
-
-			}
-
-			// -----------------------------
-
-			function onWindowResize( event ) {
-
-				windowHalfX = window.innerWidth / 2;
-				windowHalfY = window.innerHeight / 2;
-
-				WIDTH = window.innerWidth;
-				HEIGHT = window.innerHeight;
-
-				renderer.setSize( WIDTH, HEIGHT );
-
-				camera.aspect = WIDTH / HEIGHT;
-				camera.updateProjectionMatrix();
-
-			}
-
-			function onDocumentMouseMove( event ) {
-
-				mouseX = ( event.clientX - windowHalfX ) * 1;
-				mouseY = ( event.clientY - windowHalfY ) * 1;
-
-			}
-
-			// -----------------------------
-
-			function animate() {
-
-				requestAnimationFrame( animate );
-
-				render();
-				stats.update();
-
-			}
-
-			function render() {
-
-				var delta = clock.getDelta();
-				var time = Date.now() * 0.0005;
-
-				// update lights
-
-				var x, y, z;
-
-				for ( var i = 0, il = lights.length; i < il; i ++ ) {
-
-					var light = lights[ i ];
-
-					if ( i > 0 ) {
-
-						x = Math.sin( time + i * 1.7 ) * 80;
-						y = Math.cos( time + i * 1.5 ) * 40;
-						z = Math.cos( time + i * 1.3 ) * 30;
-
-					} else {
-
-						x = Math.sin( time * 3 ) * 20;
-						y = 15;
-						z = Math.cos( time * 3 ) * 25 + 10;
-
-					}
-
-					light.position.set( x, y, z );
-
-				}
-
-				// update morphs
-
-				for ( var i = 0; i < morphs.length; i ++ ) {
-
-					var morph = morphs[ i ];
-					morph.updateAnimation( 1000 * delta );
-
-					morph.position.x += morph.userData.delta * delta;
-					if ( morph.position.x < -50 ) morph.position.x = 200;
-
-				}
-
-				// update skins
-
-				THREE.AnimationHandler.update( 0.4 * delta );
-
-				for ( var i = 0; i < skins.length; i ++ ) {
-
-					var skin = skins[ i ];
-
-					skin.position.x += skin.userData.delta * delta;
-					if ( skin.position.x > 200 ) skin.position.x = -200;
-
-				}
-
-				// update controls
-
-				targetX = mouseX * .001;
-				targetY = mouseY * .001;
-
-				angle += 0.05 * ( targetX - angle );
-
-				camera.position.x = -Math.sin( angle ) * 150;
-				camera.position.z = Math.cos( angle ) * 150;
-
-				camera.lookAt( target );
-
-				// render
-
-				renderer.render( scene, camera );
-
-			}
-
-		</script>
-	</body>
-
-</html>

+ 0 - 388
examples/webgldeferred_arealights.html

@@ -1,388 +0,0 @@
-<!DOCTYPE HTML>
-<html lang="en">
-	<head>
-		<title>three.js webgl - deferred rendering</title>
-		<meta charset="utf-8" />
-		<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
-		<style>
-			body {
-				background-color: #000;
-				margin: 0px;
-				overflow: hidden;
-			}
-
-			#info {
-				position: absolute;
-				top: 20px; width: 100%;
-				color: #ffffff;
-				padding: 5px;
-				font-family: Monospace;
-				font-size: 13px;
-				text-align: center;
-			}
-
-			a {
-				color: #ff0080;
-				text-decoration: none;
-			}
-
-			a:hover {
-				color: #0080ff;
-			}
-
-			#stats { position: absolute; top:10px; left: 5px }
-			#stats #fps { background: transparent !important }
-			#stats #fps #fpsText { color: #aaa !important }
-			#stats #fps #fpsGraph { display: none }
-		</style>
-	</head>
-
-	<body>
-		<div id="info">
-			<a href="http://threejs.org" target="_blank">three.js</a> - deferred area lights WebGL demo by <a href="http://de.redplant.de" target=_blank>redPlant</a> -
-			based on <a href="http://www.gamedev.net/topic/552315-glsl-area-light-implementation/" target=_blank>ArKano22's</a> glsl implementation
-		</div>
-		<div id="container"></div>
-
-		<script src="../build/three.min.js"></script>
-
-		<script src="js/loaders/BinaryLoader.js"></script>
-
-		<script src="js/renderers/WebGLDeferredRenderer.js"></script>
-		<script src="js/ShaderDeferred.js"></script>
-
-		<script src="js/shaders/CopyShader.js"></script>
-		<script src="js/shaders/FXAAShader.js"></script>
-		<script src="js/shaders/ConvolutionShader.js"></script>
-
-		<script src="js/postprocessing/EffectComposer.js"></script>
-		<script src="js/postprocessing/RenderPass.js"></script>
-		<script src="js/postprocessing/ShaderPass.js"></script>
-		<script src="js/postprocessing/MaskPass.js"></script>
-		<script src="js/postprocessing/BloomPass.js"></script>
-
-		<script src="js/Detector.js"></script>
-		<script src="js/libs/stats.min.js"></script>
-
-		<script>
-
-			if ( ! Detector.webgl ) Detector.addGetWebGLMessage();
-
-			var SCALE = 1;
-
-			var WIDTH = window.innerWidth;
-			var HEIGHT = window.innerHeight;
-
-			var NEAR = 1.0, FAR = 350.0;
-			var VIEW_ANGLE = 40;
-
-			// controls
-
-			var mouseX = 0;
-			var mouseY = 0;
-
-			var targetX = 0, targetY = 0;
-			var angle = 0;
-			var target = new THREE.Vector3( 0, 0, 0 );
-
-			var windowHalfX = window.innerWidth / 2;
-			var windowHalfY = window.innerHeight / 2;
-
-			// core
-
-			var renderer, camera, scene, stats, clock;
-
-			// lights
-
-			var areaLight1, areaLight2, areaLight3;
-
-			//
-
-			init();
-			animate();
-
-			// -----------------------------
-
-			function init() {
-
-				// renderer
-
-				renderer = new THREE.WebGLDeferredRenderer( { width: WIDTH, height: HEIGHT, scale: SCALE, antialias: true, tonemapping: THREE.FilmicOperator, brightness: 2.5 } );
-
-				var container = document.getElementById( 'container' );
-				container.appendChild( renderer.domElement );
-
-				// effects
-
-				var bloomEffect = new THREE.BloomPass( 0.65 );
-				renderer.addEffect( bloomEffect );
-
-				// camera
-
-				camera = new THREE.PerspectiveCamera( VIEW_ANGLE, WIDTH / HEIGHT, NEAR, FAR );
-				camera.position.y = 40;
-
-				// scene
-
-				scene = new THREE.Scene();
-				scene.add( camera );
-
-				// stats
-
-				stats = new Stats();
-				stats.domElement.style.position = 'absolute';
-				stats.domElement.style.top = '8px';
-				stats.domElement.style.zIndex = 100;
-				container.appendChild( stats.domElement );
-
-				// clock
-
-				clock = new THREE.Clock();
-
-				// add lights
-
-				initLights();
-
-				// add objects
-
-				initObjects();
-
-				// events
-
-				document.addEventListener( 'mousemove', onDocumentMouseMove, false );
-				window.addEventListener( 'resize', onWindowResize, false );
-
-			}
-
-			// -----------------------------
-
-			function createAreaEmitter( light ) {
-
-				var geometry = new THREE.BoxGeometry( 1, 1, 1 );
-				var material = new THREE.MeshBasicMaterial( { color: light.color.getHex(), vertexColors: THREE.FaceColors } );
-
-				var backColor = 0x222222;
-
-				geometry.faces[ 5 ].color.setHex( backColor );
-				geometry.faces[ 4 ].color.setHex( backColor );
-				geometry.faces[ 2 ].color.setHex( backColor );
-				geometry.faces[ 1 ].color.setHex( backColor );
-				geometry.faces[ 0 ].color.setHex( backColor );
-
-				var emitter = new THREE.Mesh( geometry, material );
-				emitter.scale.set( light.width * 2, 0.2, light.height * 2 );
-
-				return emitter;
-
-			}
-
-			function setupAreaLight( light ) {
-
-				var matrix = light.matrixWorld;
-
-				light.right.set( 1, 0, 0 );
-				light.normal.set( 0, -1, 0 );
-
-				light.right.applyMatrix4( matrix );
-				light.normal.applyMatrix4( matrix );
-
-			}
-
-			function initLights() {
-
-				areaLight1 = new THREE.AreaLight( 0xffffff, 1 );
-				areaLight1.position.set( 0.0001, 10.0001, -18.5001 );
-				areaLight1.rotation.set( -0.74719, 0.0001, 0.0001 );
-				areaLight1.width = 10;
-				areaLight1.height = 1;
-				scene.add( areaLight1 );
-
-				var meshEmitter = createAreaEmitter( areaLight1 );
-				areaLight1.add( meshEmitter );
-
-				//
-
-				areaLight2 = new THREE.AreaLight( 0x33ff66, 1.5 );
-				areaLight2.position.set( -19.0001, 3.0001, 0.0001 );
-				areaLight2.rotation.set( -1.5707, 0.0001, 1.5707 );
-				areaLight2.width = 8;
-				areaLight2.height = 1;
-				scene.add( areaLight2 );
-
-				var meshEmitter = createAreaEmitter( areaLight2 );
-				areaLight2.add( meshEmitter );
-
-				//
-
-				areaLight3 = new THREE.AreaLight( 0x3366ff, 1.5 );
-				areaLight3.position.set( 19.0001, 3.0001, 0.0001 );
-				areaLight3.rotation.set( 1.5707, 0.0001, -1.5707 );
-				areaLight3.width = 8;
-				areaLight3.height = 1;
-				scene.add( areaLight3 );
-
-				var meshEmitter = createAreaEmitter( areaLight3 );
-				areaLight3.add( meshEmitter );
-
-			}
-
-			// -----------------------------
-
-			function initObjects() {
-
-				var loader = new THREE.BinaryLoader();
-				loader.load( "obj/box/box.js", function ( geometry, materials ) {
-
-					var material = new THREE.MeshPhongMaterial( { color: 0xffaa55, specular: 0x888888, shininess: 200 } );
-					var object = new THREE.Mesh( geometry, material );
-					object.scale.multiplyScalar( 2 );
-					scene.add( object );
-
-				} );
-
-				/*
-				var loader = new THREE.BinaryLoader();
-				loader.load( "obj/veyron/VeyronNoUv_bin.js", function ( geometry ) {
-
-					var r = "textures/cube/Bridge2/";
-					var urls = [
-						r + "posx.jpg", r + "negx.jpg",
-						r + "posy.jpg", r + "negy.jpg",
-						r + "posz.jpg", r + "negz.jpg"
-					];
-
-					var textureCube = THREE.ImageUtils.loadTextureCube( urls );
-					textureCube.format = THREE.RGBFormat;
-
-					var materials = [
-						// tires + inside
-						new THREE.MeshLambertMaterial( {
-							color: 0x050505
-						} ),
-						// wheels + extras chrome
-						new THREE.MeshLambertMaterial( {
-							color: 0xffffff,
-							envMap: textureCube
-						} ),
-						// back / top / front torso
-						new THREE.MeshLambertMaterial( {
-							color: 0x000000,
-							envMap: textureCube,
-							combine: THREE.MixOperation,
-							reflectivity: 0.15
-						} ),
-						// glass
-						new THREE.MeshLambertMaterial( {
-							color: 0x101046,
-							envMap: textureCube,
-							opacity: 0.25,
-							transparent: true
-						} ),
-						// sides torso
-						new THREE.MeshLambertMaterial( {
-							color: 0xffffff,
-							envMap: textureCube
-						} ),
-						// engine
-						new THREE.MeshLambertMaterial( {
-							color: 0xffffff,
-							envMap: textureCube
-						} ),
-						// backlights
-						new THREE.MeshLambertMaterial( {
-							color: 0xff0000,
-							opacity: 0.5,
-							transparent: true
-						} ),
-						// backsignals
-						new THREE.MeshLambertMaterial( {
-							color: 0xffbb00,
-							opacity: 0.5,
-							transparent: true
-						} )
-					];
-
-					var object = new THREE.Mesh( geometry, new THREE.MeshFaceMaterial( materials ) );
-					object.position.y = 5;
-					object.rotation.y = Math.PI / 4;
-					object.scale.multiplyScalar( 0.1 );
-					scene.add( object );
-
-				} );
-				*/
-
-			}
-
-
-			// -----------------------------
-
-			function onWindowResize( event ) {
-
-				windowHalfX = window.innerWidth / 2;
-				windowHalfY = window.innerHeight / 2;
-
-				WIDTH = window.innerWidth;
-				HEIGHT = window.innerHeight - 2 * MARGIN;
-
-				renderer.setSize( WIDTH, HEIGHT );
-
-				camera.aspect = WIDTH / HEIGHT;
-				camera.updateProjectionMatrix();
-
-			}
-
-			function onDocumentMouseMove( event ) {
-
-				mouseX = ( event.clientX - windowHalfX ) * 1;
-				mouseY = ( event.clientY - windowHalfY ) * 1;
-
-			}
-
-			// -----------------------------
-
-			function animate() {
-
-				requestAnimationFrame( animate );
-
-				render();
-				stats.update();
-
-			}
-
-			function render() {
-
-				// update camera
-
-				var delta = clock.getDelta();
-
-				targetX = mouseX * .001;
-				targetY = mouseY * .001;
-
-				angle += 0.05 * ( targetX - angle );
-
-				camera.position.x = -Math.sin( angle ) * 40;
-				camera.position.z =  Math.cos( angle ) * 40;
-
-				camera.lookAt( target );
-
-				var time = Date.now();
-
-				areaLight1.position.x = Math.sin( Date.now() * 0.001 ) * 9;
-				areaLight1.position.y = Math.sin( Date.now() * 0.0013 ) * 5 + 5;
-
-				areaLight2.position.y = Math.sin( Date.now() * 0.0011 ) * 3 + 5;
-				areaLight2.position.z = Math.sin( Date.now() * 0.00113 ) * 10;
-
-				areaLight3.position.y = Math.sin( Date.now() * 0.00111 ) * 3 + 5;
-				areaLight3.position.z = Math.sin( Date.now() * 0.001113 ) * 10;
-
-				// render
-
-				renderer.render( scene, camera );
-
-			}
-
-		</script>
-	</body>
-
-</html>

+ 0 - 429
examples/webgldeferred_pointlights.html

@@ -1,429 +0,0 @@
-<!DOCTYPE HTML>
-<html lang="en">
-	<head>
-		<title>three.js webgl - deferred rendering</title>
-		<meta charset="utf-8" />
-		<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
-		<style>
-			body {
-				background-color: #000;
-				margin: 0px;
-				overflow: hidden;
-			}
-
-			#info {
-				position: absolute;
-				top: 20px; width: 100%;
-				color: #ffffff;
-				padding: 5px;
-				font-family: Monospace;
-				font-size: 13px;
-				text-align: center;
-			}
-
-			a {
-				color: #ff0080;
-				text-decoration: none;
-			}
-
-			a:hover {
-				color: #0080ff;
-			}
-
-			#stats { position: absolute; top:10px; left: 5px }
-			#stats #fps { background: transparent !important }
-			#stats #fps #fpsText { color: #aaa !important }
-			#stats #fps #fpsGraph { display: none }
-		</style>
-	</head>
-
-	<body>
-		<div id="info">
-			<a href="http://threejs.org" target="_blank">three.js</a> - deferred point lights WebGL demo by <a href="http://de.redplant.de" target=_blank>redPlant</a> -
-			<a href="http://www.ir-ltd.net/infinite-3d-head-scan-released/" target="_blank">Lee Perry-Smith</a> head -
-			light attenuation formula by <a href="http://imdoingitwrong.wordpress.com/tag/glsl/" target=_blank>Tom Madams</a>
-		</div>
-		<div id="container"></div>
-
-		<script src="../build/three.min.js"></script>
-
-		<script src="js/loaders/BinaryLoader.js"></script>
-		<!-- <script src="js/loaders/UTF8Loader.js"></script> -->
-
-		<script src="js/renderers/WebGLDeferredRenderer.js"></script>
-		<script src="js/ShaderDeferred.js"></script>
-
-		<script src="js/shaders/CopyShader.js"></script>
-		<script src="js/shaders/FXAAShader.js"></script>
-
-		<script src="js/postprocessing/EffectComposer.js"></script>
-		<script src="js/postprocessing/RenderPass.js"></script>
-		<script src="js/postprocessing/ShaderPass.js"></script>
-		<script src="js/postprocessing/MaskPass.js"></script>
-
-		<script src="js/Detector.js"></script>
-		<script src="js/libs/stats.min.js"></script>
-
-		<script>
-
-			if ( ! Detector.webgl ) Detector.addGetWebGLMessage();
-
-			var SCALE = 1;
-
-			var WIDTH = window.innerWidth;
-			var HEIGHT = window.innerHeight;
-
-			var NEAR = 1.0, FAR = 350.0;
-			var VIEW_ANGLE = 45;
-
-			// controls
-
-			var mouseX = 0;
-			var mouseY = 0;
-
-			var targetX = 0, targetY = 0;
-			var angle = 0;
-			var target = new THREE.Vector3( 0, 0, 0 );
-
-			var windowHalfX = window.innerWidth / 2;
-			var windowHalfY = window.innerHeight / 2;
-
-			// core
-
-			var renderer, camera, scene, stats, clock;
-
-			// lights
-
-			var numLights = 50;
-			var lights = [];
-
-			//
-
-			init();
-			animate();
-
-			// -----------------------------
-
-			function init() {
-
-				// renderer
-
-				renderer = new THREE.WebGLDeferredRenderer( { width: WIDTH, height: HEIGHT, scale: SCALE, antialias: true } );
-
-				var container = document.getElementById( 'container' );
-				container.appendChild( renderer.domElement );
-
-				// camera
-
-				camera = new THREE.PerspectiveCamera( VIEW_ANGLE, WIDTH / HEIGHT, NEAR, FAR );
-				camera.position.z = 150;
-
-				// scene
-
-				scene = new THREE.Scene();
-				scene.add( camera );
-
-				// stats
-
-				stats = new Stats();
-				stats.domElement.style.position = 'absolute';
-				stats.domElement.style.top = '8px';
-				stats.domElement.style.zIndex = 100;
-				container.appendChild( stats.domElement );
-
-				// clock
-
-				clock = new THREE.Clock();
-
-				// add lights
-
-				initLights();
-
-				// add objects
-
-				initObjects();
-
-				// events
-
-				document.addEventListener( 'mousemove', onDocumentMouseMove, false );
-				window.addEventListener( 'resize', onWindowResize, false );
-
-			}
-
-			// -----------------------------
-
-			function initLights() {
-
-				var distance = 40;
-
-				// front light
-
-				var light = new THREE.PointLight( 0xffffff, 1.5, 1.5 * distance );
-				scene.add( light );
-				lights.push( light );
-
-				// random lights
-
-				var c = new THREE.Vector3();
-
-				for ( var i = 1; i < numLights; i ++ ) {
-
-					var light = new THREE.PointLight( 0xffffff, 2.0, distance );
-
-					c.set( Math.random(), Math.random(), Math.random() ).normalize();
-					light.color.setRGB( c.x, c.y, c.z );
-
-					scene.add( light );
-					lights.push( light );
-
-				}
-
-				var geometry = new THREE.SphereGeometry( 0.7, 7, 7 );
-
-				for ( var i = 0; i < numLights; i ++ ) {
-
-					var light = lights[ i ];
-
-					var material = new THREE.MeshBasicMaterial();
-					material.color = light.color;
-
-					var emitter = new THREE.Mesh( geometry, material );
-					light.add( emitter );
-
-				}
-
-			}
-
-			// -----------------------------
-
-			function initObjects() {
-
-				/*
-
-				var loader = new THREE.UTF8Loader();
-
-				loader.load( "models/utf8/ben_dds.js", function ( object ) {
-
-					object.scale.multiplyScalar( 150 );
-					object.position.y = -75;
-					scene.add( object );
-
-				}, { normalizeRGB: true } );
-
-				loader.load( "models/utf8/WaltHi.js", function ( object ) {
-
-					object.position.y = -35;
-					scene.add( object );
-
-				}, { normalizeRGB: true } );
-
-				*/
-
-
-				var loader = new THREE.JSONLoader();
-				loader.load( "obj/leeperrysmith/LeePerrySmith.js", function( geometry, materials ) {
-
-					var mapColor = THREE.ImageUtils.loadTexture( "obj/leeperrysmith/Map-COL.jpg" );
-					var mapHeight = THREE.ImageUtils.loadTexture( "obj/leeperrysmith/Infinite-Level_02_Disp_NoSmoothUV-4096.jpg" );
-					mapHeight.repeat.set( 0.998, 0.998 );
-					mapHeight.offset.set( 0.001, 0.001 );
-					mapHeight.wrapS = mapHeight.wrapT = THREE.RepeatWrapping;
-					mapHeight.anisotropy = 4;
-					mapHeight.format = THREE.RGBFormat;
-
-					var material = new THREE.MeshPhongMaterial( { map: mapColor, bumpMap: mapHeight, bumpScale: 2.5, shininess: 75, specular: 0x333333, metal: true } );
-
-					var object = new THREE.Mesh( geometry, material );
-					object.scale.multiplyScalar( 8 );
-					scene.add( object );
-
-				} );
-
-
-				var loader = new THREE.BinaryLoader();
-				loader.load( "obj/female02/Female02_bin.js", function( geometry, materials ) {
-
-					var object = new THREE.Mesh( geometry, new THREE.MeshFaceMaterial( materials ) );
-					object.position.x = -50;
-					object.position.y = -48;
-					object.scale.multiplyScalar( 0.45 );
-					scene.add( object );
-
-				} );
-
-				loader.load( "obj/male02/Male02_bin.js", function( geometry, materials ) {
-
-					var object = new THREE.Mesh( geometry, new THREE.MeshFaceMaterial( materials ) );
-					object.position.x = 50;
-					object.position.y = -48;
-					object.scale.multiplyScalar( 0.45 );
-					scene.add( object );
-
-				} );
-
-				// create box
-
-				var box = generateBox();
-				box.scale.multiplyScalar( 8 );
-				scene.add( box );
-
-			}
-
-			// -----------------------------
-
-			function generateBox() {
-
-				var object = new THREE.Object3D();
-
-				var mapHeight2 = THREE.ImageUtils.loadTexture( "obj/lightmap/rocks.jpg" );
-				mapHeight2.repeat.set( 3, 1.5 );
-				mapHeight2.wrapS = mapHeight2.wrapT = THREE.RepeatWrapping;
-				mapHeight2.anisotropy = 4;
-				mapHeight2.format = THREE.RGBFormat;
-
-				var mapHeight3 = THREE.ImageUtils.loadTexture( "textures/water.jpg" );
-				mapHeight3.repeat.set( 16, 8 );
-				mapHeight3.wrapS = mapHeight3.wrapT = THREE.RepeatWrapping;
-				mapHeight3.anisotropy = 4;
-				mapHeight3.format = THREE.RGBFormat;
-
-				var geoPlane = new THREE.PlaneBufferGeometry( 40, 20 );
-
-				var matPlane  = new THREE.MeshPhongMaterial( { color: 0xffffff, specular: 0x111111, shininess:  50, bumpMap: mapHeight2, bumpScale: 0.5 } );
-				var matPlane2 = new THREE.MeshPhongMaterial( { color: 0x331919, specular: 0x111111, shininess:  50, bumpMap: mapHeight2, bumpScale: 1 } );
-				var matPlane3 = new THREE.MeshPhongMaterial( { color: 0x00aaff, specular: 0xffffff, shininess: 200, bumpMap: mapHeight3, bumpScale: 1.2 } );
-				var matPlane4 = new THREE.MeshPhongMaterial( { color: 0xffffff, specular: 0x111111, shininess:  50, bumpMap: mapHeight3, bumpScale: 1 } );
-
-				// bottom
-
-				var mesh = new THREE.Mesh( geoPlane, matPlane3 );
-				mesh.position.z = -2;
-				mesh.position.y = -6;
-				mesh.rotation.x = -Math.PI/2;
-				object.add( mesh );
-
-				// top
-
-				var mesh = new THREE.Mesh( geoPlane, matPlane4 );
-				mesh.position.z = -2;
-				mesh.position.y = 6;
-				mesh.rotation.x = Math.PI/2;
-				object.add( mesh );
-
-				// back
-
-				var mesh = new THREE.Mesh( geoPlane, matPlane );
-				mesh.position.z = -4;
-				mesh.position.y = 0;
-				object.add( mesh );
-
-				// right
-
-				var mesh = new THREE.Mesh( geoPlane, matPlane );
-				mesh.position.z = 0;
-				mesh.position.y = 0;
-				mesh.position.x = 13;
-				mesh.rotation.y = -Math.PI/2;
-				//object.add( mesh );
-
-				// left
-
-				var mesh = new THREE.Mesh( geoPlane, matPlane );
-				mesh.position.z = 0;
-				mesh.position.y = 0;
-				mesh.position.x = -13;
-				mesh.rotation.y = Math.PI/2;
-				//object.add( mesh );
-
-				return object;
-
-			}
-
-			// -----------------------------
-
-			function onWindowResize( event ) {
-
-				windowHalfX = window.innerWidth / 2;
-				windowHalfY = window.innerHeight / 2;
-
-				WIDTH = window.innerWidth;
-				HEIGHT = window.innerHeight;
-
-				renderer.setSize( WIDTH, HEIGHT );
-
-				camera.aspect = WIDTH / HEIGHT;
-				camera.updateProjectionMatrix();
-
-			}
-
-			function onDocumentMouseMove( event ) {
-
-				mouseX = ( event.clientX - windowHalfX ) * 1;
-				mouseY = ( event.clientY - windowHalfY ) * 1;
-
-			}
-
-			// -----------------------------
-
-			function animate() {
-
-				requestAnimationFrame( animate );
-
-				render();
-				stats.update();
-
-			}
-
-			function render() {
-
-				// update lights
-
-				var time = Date.now() * 0.0005;
-				var x, y, z;
-
-				for ( var i = 0, il = lights.length; i < il; i ++ ) {
-
-					var light = lights[ i ];
-
-					if ( i > 0 ) {
-
-						x = Math.sin( time + i * 1.7 ) * 80;
-						y = Math.cos( time + i * 1.5 ) * 40;
-						z = Math.cos( time + i * 1.3 ) * 30;
-
-					} else {
-
-						x = Math.sin( time * 3 ) * 20;
-						y = 15;
-						z = Math.cos( time * 3 ) * 25 + 10;
-
-					}
-
-					light.position.set( x, y, z );
-
-				}
-
-				// update camera
-
-				var delta = clock.getDelta();
-
-				targetX = mouseX * .001;
-				targetY = mouseY * .001;
-
-				angle += 0.05 * ( targetX - angle );
-
-				camera.position.x = -Math.sin( angle ) * 150;
-				camera.position.z =  Math.cos( angle ) * 150;
-
-				camera.lookAt( target );
-
-				// render
-
-				renderer.render( scene, camera );
-
-			}
-
-		</script>
-	</body>
-
-</html>

+ 27 - 28
src/Three.js

@@ -8,11 +8,11 @@ var THREE = { REVISION: '72dev' };
 
 if ( typeof define === 'function' && define.amd ) {
 
-    define( 'three', THREE );
+		define( 'three', THREE );
 
 } else if ( 'undefined' !== typeof exports && 'undefined' !== typeof module ) {
 
-    module.exports = THREE;
+		module.exports = THREE;
 
 }
 
@@ -21,48 +21,48 @@ if ( typeof define === 'function' && define.amd ) {
 
 if ( self.requestAnimationFrame === undefined || self.cancelAnimationFrame === undefined ) {
 
-  // Missing in Android stock browser.
+	// Missing in Android stock browser.
 
-  ( function () {
+	( function () {
 
-  	var lastTime = 0;
-  	var vendors = [ 'ms', 'moz', 'webkit', 'o' ];
+		var lastTime = 0;
+		var vendors = [ 'ms', 'moz', 'webkit', 'o' ];
 
-  	for ( var x = 0; x < vendors.length && ! self.requestAnimationFrame; ++ x ) {
+		for ( var x = 0; x < vendors.length && ! self.requestAnimationFrame; ++ x ) {
 
-  		self.requestAnimationFrame = self[ vendors[ x ] + 'RequestAnimationFrame' ];
-  		self.cancelAnimationFrame = self[ vendors[ x ] + 'CancelAnimationFrame' ] || self[ vendors[ x ] + 'CancelRequestAnimationFrame' ];
+			self.requestAnimationFrame = self[ vendors[ x ] + 'RequestAnimationFrame' ];
+			self.cancelAnimationFrame = self[ vendors[ x ] + 'CancelAnimationFrame' ] || self[ vendors[ x ] + 'CancelRequestAnimationFrame' ];
 
-  	}
+		}
 
-  	if ( self.requestAnimationFrame === undefined && self.setTimeout !== undefined ) {
+		if ( self.requestAnimationFrame === undefined && self.setTimeout !== undefined ) {
 
-  		self.requestAnimationFrame = function ( callback ) {
+			self.requestAnimationFrame = function ( callback ) {
 
-  			var currTime = Date.now(), timeToCall = Math.max( 0, 16 - ( currTime - lastTime ) );
-  			var id = self.setTimeout( function () {
+				var currTime = Date.now(), timeToCall = Math.max( 0, 16 - ( currTime - lastTime ) );
+				var id = self.setTimeout( function () {
 
-  				callback( currTime + timeToCall );
+					callback( currTime + timeToCall );
 
-  			}, timeToCall );
-  			lastTime = currTime + timeToCall;
-  			return id;
+				}, timeToCall );
+				lastTime = currTime + timeToCall;
+				return id;
 
-  		};
+			};
 
-  	}
+		}
 
-  	if ( self.cancelAnimationFrame === undefined && self.clearTimeout !== undefined ) {
+		if ( self.cancelAnimationFrame === undefined && self.clearTimeout !== undefined ) {
 
-  		self.cancelAnimationFrame = function ( id ) {
+			self.cancelAnimationFrame = function ( id ) {
 
-  			self.clearTimeout( id );
+				self.clearTimeout( id );
 
-  		};
+			};
 
-  	}
+		}
 
-  }() );
+	}() );
 
 }
 
@@ -125,7 +125,6 @@ THREE.DoubleSide = 2;
 
 // shading
 
-THREE.NoShading = 0;
 THREE.FlatShading = 1;
 THREE.SmoothShading = 2;
 
@@ -146,7 +145,7 @@ THREE.CustomBlending = 5;
 
 // custom blending equations
 // (numbers start from 100 not to clash with other
-//  mappings to OpenGL constants defined in Texture.js)
+// mappings to OpenGL constants defined in Texture.js)
 
 THREE.AddEquation = 100;
 THREE.SubtractEquation = 101;

+ 18 - 206
src/core/BufferGeometry.js

@@ -353,14 +353,12 @@ THREE.BufferGeometry.prototype = {
 			direct.normalsNeedUpdate = geometry.normalsNeedUpdate;
 			direct.colorsNeedUpdate = geometry.colorsNeedUpdate;
 			direct.uvsNeedUpdate = geometry.uvsNeedUpdate;
-			direct.tangentsNeedUpdate = geometry.tangentsNeedUpdate;
 			direct.groupsNeedUpdate = geometry.groupsNeedUpdate;
 
 			geometry.verticesNeedUpdate = false;
 			geometry.normalsNeedUpdate = false;
 			geometry.colorsNeedUpdate = false;
 			geometry.uvsNeedUpdate = false;
-			geometry.tangentsNeedUpdate = false;
 			geometry.groupsNeedUpdate = false;
 
 			geometry = direct;
@@ -412,21 +410,6 @@ THREE.BufferGeometry.prototype = {
 
 		}
 
-		if ( geometry.tangentsNeedUpdate === true ) {
-
-			var attribute = this.attributes.tangent;
-
-			if ( attribute !== undefined ) {
-
-				attribute.copyVector4sArray( geometry.tangents );
-				attribute.needsUpdate = true;
-
-			}
-
-			geometry.tangentsNeedUpdate = false;
-
-		}
-
 		if ( geometry.lineDistancesNeedUpdate ) {
 
 			var attribute = this.attributes.lineDistance;
@@ -496,13 +479,6 @@ THREE.BufferGeometry.prototype = {
 
 		}
 
-		if ( geometry.tangents.length > 0 ) {
-
-			var tangents = new Float32Array( geometry.tangents.length * 4 );
-			this.addAttribute( 'tangent', new THREE.BufferAttribute( tangents, 4 ).copyVector4sArray( geometry.tangents ) );
-
-		}
-
 		if ( geometry.indices.length > 0 ) {
 
 			var TypeArray = geometry.vertices.length > 65535 ? Uint32Array : Uint16Array;
@@ -805,185 +781,7 @@ THREE.BufferGeometry.prototype = {
 
 	computeTangents: function () {
 
-		// based on http://www.terathon.com/code/tangent.html
-		// (per vertex tangents)
-
-		if ( this.index === undefined ||
-			 this.attributes.position === undefined ||
-			 this.attributes.normal === undefined ||
-			 this.attributes.uv === undefined ) {
-
-			console.warn( 'THREE.BufferGeometry: Missing required attributes (index, position, normal or uv) in BufferGeometry.computeTangents()' );
-			return;
-
-		}
-
-		var indices = this.index.array;
-		var positions = this.attributes.position.array;
-		var normals = this.attributes.normal.array;
-		var uvs = this.attributes.uv.array;
-
-		var nVertices = positions.length / 3;
-
-		if ( this.attributes.tangent === undefined ) {
-
-			this.addAttribute( 'tangent', new THREE.BufferAttribute( new Float32Array( 4 * nVertices ), 4 ) );
-
-		}
-
-		var tangents = this.attributes.tangent.array;
-
-		var tan1 = [], tan2 = [];
-
-		for ( var k = 0; k < nVertices; k ++ ) {
-
-			tan1[ k ] = new THREE.Vector3();
-			tan2[ k ] = new THREE.Vector3();
-
-		}
-
-		var vA = new THREE.Vector3(),
-			vB = new THREE.Vector3(),
-			vC = new THREE.Vector3(),
-
-			uvA = new THREE.Vector2(),
-			uvB = new THREE.Vector2(),
-			uvC = new THREE.Vector2(),
-
-			x1, x2, y1, y2, z1, z2,
-			s1, s2, t1, t2, r;
-
-		var sdir = new THREE.Vector3(), tdir = new THREE.Vector3();
-
-		function handleTriangle( a, b, c ) {
-
-			vA.fromArray( positions, a * 3 );
-			vB.fromArray( positions, b * 3 );
-			vC.fromArray( positions, c * 3 );
-
-			uvA.fromArray( uvs, a * 2 );
-			uvB.fromArray( uvs, b * 2 );
-			uvC.fromArray( uvs, c * 2 );
-
-			x1 = vB.x - vA.x;
-			x2 = vC.x - vA.x;
-
-			y1 = vB.y - vA.y;
-			y2 = vC.y - vA.y;
-
-			z1 = vB.z - vA.z;
-			z2 = vC.z - vA.z;
-
-			s1 = uvB.x - uvA.x;
-			s2 = uvC.x - uvA.x;
-
-			t1 = uvB.y - uvA.y;
-			t2 = uvC.y - uvA.y;
-
-			r = 1.0 / ( s1 * t2 - s2 * t1 );
-
-			sdir.set(
-				( t2 * x1 - t1 * x2 ) * r,
-				( t2 * y1 - t1 * y2 ) * r,
-				( t2 * z1 - t1 * z2 ) * r
-			);
-
-			tdir.set(
-				( s1 * x2 - s2 * x1 ) * r,
-				( s1 * y2 - s2 * y1 ) * r,
-				( s1 * z2 - s2 * z1 ) * r
-			);
-
-			tan1[ a ].add( sdir );
-			tan1[ b ].add( sdir );
-			tan1[ c ].add( sdir );
-
-			tan2[ a ].add( tdir );
-			tan2[ b ].add( tdir );
-			tan2[ c ].add( tdir );
-
-		}
-
-		var i, il;
-		var j, jl;
-		var iA, iB, iC;
-
-		if ( this.groups.length === 0 ) {
-
-			this.addGroup( 0, indices.length );
-
-		}
-
-		var groups = this.groups;
-
-		for ( j = 0, jl = groups.length; j < jl; ++ j ) {
-
-			var group = groups[ j ];
-
-			var start = group.start;
-			var count = group.count;
-
-			for ( i = start, il = start + count; i < il; i += 3 ) {
-
-				iA = indices[ i + 0 ];
-				iB = indices[ i + 1 ];
-				iC = indices[ i + 2 ];
-
-				handleTriangle( iA, iB, iC );
-
-			}
-
-		}
-
-		var tmp = new THREE.Vector3(), tmp2 = new THREE.Vector3();
-		var n = new THREE.Vector3(), n2 = new THREE.Vector3();
-		var w, t, test;
-
-		function handleVertex( v ) {
-
-			n.fromArray( normals, v * 3 );
-			n2.copy( n );
-
-			t = tan1[ v ];
-
-			// Gram-Schmidt orthogonalize
-
-			tmp.copy( t );
-			tmp.sub( n.multiplyScalar( n.dot( t ) ) ).normalize();
-
-			// Calculate handedness
-
-			tmp2.crossVectors( n2, t );
-			test = tmp2.dot( tan2[ v ] );
-			w = ( test < 0.0 ) ? - 1.0 : 1.0;
-
-			tangents[ v * 4 ] = tmp.x;
-			tangents[ v * 4 + 1 ] = tmp.y;
-			tangents[ v * 4 + 2 ] = tmp.z;
-			tangents[ v * 4 + 3 ] = w;
-
-		}
-
-		for ( j = 0, jl = groups.length; j < jl; ++ j ) {
-
-			var group = groups[ j ];
-
-			var start = group.start;
-			var count = group.count;
-
-			for ( i = start, il = start + count; i < il; i += 3 ) {
-
-				iA = indices[ i + 0 ];
-				iB = indices[ i + 1 ];
-				iC = indices[ i + 2 ];
-
-				handleVertex( iA );
-				handleVertex( iB );
-				handleVertex( iC );
-
-			}
-
-		}
+		console.warn( 'THREE.BufferGeometry: .computeTangents() has been removed.' );
 
 	},
 
@@ -1084,10 +882,20 @@ THREE.BufferGeometry.prototype = {
 
 		data.data = { attributes: {} };
 
-		var attributes = this.attributes;
-		var groups = this.groups;
+		var index = this.index;
 
-		var boundingSphere = this.boundingSphere;
+		if ( index !== null ) {
+
+			var array = Array.prototype.slice.call( index.array );
+
+			data.data.index = {
+				type: index.array.constructor.name,
+				array: array
+			};
+
+		}
+
+		var attributes = this.attributes;
 
 		for ( var key in attributes ) {
 
@@ -1103,12 +911,16 @@ THREE.BufferGeometry.prototype = {
 
 		}
 
+		var groups = this.groups;
+
 		if ( groups.length > 0 ) {
 
 			data.data.groups = JSON.parse( JSON.stringify( groups ) );
 
 		}
 
+		var boundingSphere = this.boundingSphere;
+
 		if ( boundingSphere !== null ) {
 
 			data.data.boundingSphere = {

+ 0 - 34
src/core/DirectGeometry.js

@@ -17,7 +17,6 @@ THREE.DirectGeometry = function () {
 	this.colors = [];
 	this.uvs = [];
 	this.uvs2 = [];
-	this.tangents = [];
 
 	this.groups = [];
 
@@ -37,7 +36,6 @@ THREE.DirectGeometry = function () {
 	this.normalsNeedUpdate = false;
 	this.colorsNeedUpdate = false;
 	this.uvsNeedUpdate = false;
-	this.tangentsNeedUpdate = false;
 	this.groupsNeedUpdate = false;
 
 };
@@ -52,21 +50,12 @@ THREE.DirectGeometry.prototype = {
 	computeFaceNormals: function () {
 
 		console.warn( 'THREE.DirectGeometry: computeFaceNormals() is not a method of this type of geometry.' );
-		return this;
 
 	},
 
 	computeVertexNormals: function () {
 
 		console.warn( 'THREE.DirectGeometry: computeVertexNormals() is not a method of this type of geometry.' );
-		return this;
-
-	},
-
-	computeTangents: function () {
-
-		console.warn( 'THREE.DirectGeometry: computeTangents() is not a method of this type of geometry.' );
-		return this;
 
 	},
 
@@ -124,8 +113,6 @@ THREE.DirectGeometry.prototype = {
 		var hasFaceVertexUv = faceVertexUvs[ 0 ] && faceVertexUvs[ 0 ].length > 0;
 		var hasFaceVertexUv2 = faceVertexUvs[ 1 ] && faceVertexUvs[ 1 ].length > 0;
 
-		var hasTangents = geometry.hasTangents;
-
 		// morphs
 
 		var morphTargets = geometry.morphTargets;
@@ -242,26 +229,6 @@ THREE.DirectGeometry.prototype = {
 
 			}
 
-			// tangents
-
-			if ( hasTangents === true ) {
-
-				var vertexTangents = face.vertexTangents;
-
-				if ( vertexTangents.length === 3 ) {
-
-					this.tangents.push( vertexTangents[ 0 ], vertexTangents[ 1 ], vertexTangents[ 2 ] );
-
-				} else {
-
-					console.warn( 'THREE.DirectGeometry.fromGeometry(): Undefined tangents ', i );
-
-					this.tangents.push( new THREE.Vector4(), new THREE.Vector4(), new THREE.Vector4() );
-
-				}
-
-			}
-
 			// morphs
 
 			for ( var j = 0; j < morphTargetsLength; j ++ ) {
@@ -302,7 +269,6 @@ THREE.DirectGeometry.prototype = {
 		this.normalsNeedUpdate = geometry.normalsNeedUpdate;
 		this.colorsNeedUpdate = geometry.colorsNeedUpdate;
 		this.uvsNeedUpdate = geometry.uvsNeedUpdate;
-		this.tangentsNeedUpdate = geometry.tangentsNeedUpdate;
 		this.groupsNeedUpdate = geometry.groupsNeedUpdate;
 
 		return this;

+ 0 - 8
src/core/Face3.js

@@ -15,8 +15,6 @@ THREE.Face3 = function ( a, b, c, normal, color, materialIndex ) {
 	this.color = color instanceof THREE.Color ? color : new THREE.Color();
 	this.vertexColors = Array.isArray( color ) ? color : [];
 
-	this.vertexTangents = [];
-
 	this.materialIndex = materialIndex !== undefined ? materialIndex : 0;
 
 };
@@ -54,12 +52,6 @@ THREE.Face3.prototype = {
 
 		}
 
-		for ( var i = 0, il = source.vertexTangents.length; i < il; i ++ ) {
-
-			this.vertexTangents[ i ] = source.vertexTangents[ i ].clone();
-
-		}
-
 		return this;
 
 	}

+ 1 - 118
src/core/Geometry.js

@@ -33,15 +33,12 @@ THREE.Geometry = function () {
 	this.boundingBox = null;
 	this.boundingSphere = null;
 
-	this.hasTangents = false;
-
 	// update flags
 
 	this.verticesNeedUpdate = false;
 	this.elementsNeedUpdate = false;
 	this.uvsNeedUpdate = false;
 	this.normalsNeedUpdate = false;
-	this.tangentsNeedUpdate = false;
 	this.colorsNeedUpdate = false;
 	this.lineDistancesNeedUpdate = false;
 	this.groupsNeedUpdate = false;
@@ -223,15 +220,12 @@ THREE.Geometry.prototype = {
 		var colors = attributes.color !== undefined ? attributes.color.array : undefined;
 		var uvs = attributes.uv !== undefined ? attributes.uv.array : undefined;
 		var uvs2 = attributes.uv2 !== undefined ? attributes.uv2.array : undefined;
-		var tangents = attributes.tangent !== undefined ? attributes.tangent.array : undefined;
 
 		if ( uvs2 !== undefined ) this.faceVertexUvs[ 1 ] = [];
-		if ( tangents !== undefined ) this.hasTangents = true;
 
 		var tempNormals = [];
 		var tempUVs = [];
 		var tempUVs2 = [];
-		var tempTangents = [];
 
 		for ( var i = 0, j = 0, k = 0; i < vertices.length; i += 3, j += 2, k += 4 ) {
 
@@ -261,12 +255,6 @@ THREE.Geometry.prototype = {
 
 			}
 
-			if ( tangents !== undefined ) {
-
-				tempTangents.push( new THREE.Vector4( tangents[ k ], tangents[ k + 1 ], tangents[ k + 2 ], tangents[ k + 3 ] ) );
-
-			}
-
 		}
 
 		var addFace = function ( a, b, c ) {
@@ -290,12 +278,6 @@ THREE.Geometry.prototype = {
 
 			}
 
-			if ( tangents !== undefined ) {
-
-				face.vertexTangents.push( tempTangents[ a ].clone(), tempTangents[ b ].clone(), tempTangents[ c ].clone() );
-
-			}
-
 		};
 
 		if ( indices !== undefined ) {
@@ -617,106 +599,7 @@ THREE.Geometry.prototype = {
 
 	computeTangents: function () {
 
-		// based on http://www.terathon.com/code/tangent.html
-		// tangents go to vertices
-
-		var f, fl, v, vl, i, vertexIndex,
-			face, uv, vA, vB, vC, uvA, uvB, uvC,
-			x1, x2, y1, y2, z1, z2,
-			s1, s2, t1, t2, r, t, test,
-			tan1 = [], tan2 = [],
-			sdir = new THREE.Vector3(), tdir = new THREE.Vector3(),
-			tmp = new THREE.Vector3(), tmp2 = new THREE.Vector3(),
-			n = new THREE.Vector3(), w;
-
-		for ( v = 0, vl = this.vertices.length; v < vl; v ++ ) {
-
-			tan1[ v ] = new THREE.Vector3();
-			tan2[ v ] = new THREE.Vector3();
-
-		}
-
-		function handleTriangle( context, a, b, c, ua, ub, uc ) {
-
-			vA = context.vertices[ a ];
-			vB = context.vertices[ b ];
-			vC = context.vertices[ c ];
-
-			uvA = uv[ ua ];
-			uvB = uv[ ub ];
-			uvC = uv[ uc ];
-
-			x1 = vB.x - vA.x;
-			x2 = vC.x - vA.x;
-			y1 = vB.y - vA.y;
-			y2 = vC.y - vA.y;
-			z1 = vB.z - vA.z;
-			z2 = vC.z - vA.z;
-
-			s1 = uvB.x - uvA.x;
-			s2 = uvC.x - uvA.x;
-			t1 = uvB.y - uvA.y;
-			t2 = uvC.y - uvA.y;
-
-			r = 1.0 / ( s1 * t2 - s2 * t1 );
-			sdir.set( ( t2 * x1 - t1 * x2 ) * r,
-					  ( t2 * y1 - t1 * y2 ) * r,
-					  ( t2 * z1 - t1 * z2 ) * r );
-			tdir.set( ( s1 * x2 - s2 * x1 ) * r,
-					  ( s1 * y2 - s2 * y1 ) * r,
-					  ( s1 * z2 - s2 * z1 ) * r );
-
-			tan1[ a ].add( sdir );
-			tan1[ b ].add( sdir );
-			tan1[ c ].add( sdir );
-
-			tan2[ a ].add( tdir );
-			tan2[ b ].add( tdir );
-			tan2[ c ].add( tdir );
-
-		}
-
-		for ( f = 0, fl = this.faces.length; f < fl; f ++ ) {
-
-			face = this.faces[ f ];
-			uv = this.faceVertexUvs[ 0 ][ f ]; // use UV layer 0 for tangents
-
-			handleTriangle( this, face.a, face.b, face.c, 0, 1, 2 );
-
-		}
-
-		var faceIndex = [ 'a', 'b', 'c', 'd' ];
-
-		for ( f = 0, fl = this.faces.length; f < fl; f ++ ) {
-
-			face = this.faces[ f ];
-
-			for ( i = 0; i < Math.min( face.vertexNormals.length, 3 ); i ++ ) {
-
-				n.copy( face.vertexNormals[ i ] );
-
-				vertexIndex = face[ faceIndex[ i ] ];
-
-				t = tan1[ vertexIndex ];
-
-				// Gram-Schmidt orthogonalize
-
-				tmp.copy( t );
-				tmp.sub( n.multiplyScalar( n.dot( t ) ) ).normalize();
-
-				// Calculate handedness
-
-				tmp2.crossVectors( face.vertexNormals[ i ], t );
-				test = tmp2.dot( tan2[ vertexIndex ] );
-				w = ( test < 0.0 ) ? - 1.0 : 1.0;
-
-				face.vertexTangents[ i ] = new THREE.Vector4( tmp.x, tmp.y, tmp.z, w );
-
-			}
-
-		}
-
-		this.hasTangents = true;
+		console.warn( 'THREE.Geometry: .computeTangents() has been removed.' );
 
 	},
 

+ 1 - 1
src/extras/SceneUtils.js

@@ -6,7 +6,7 @@ THREE.SceneUtils = {
 
 	createMultiMaterialObject: function ( geometry, materials ) {
 
-		var group = new THREE.Object3D();
+		var group = new THREE.Group();
 
 		for ( var i = 0, l = materials.length; i < l; i ++ ) {
 

+ 1 - 90
src/extras/geometries/SphereGeometry.js

@@ -4,8 +4,6 @@
 
 THREE.SphereGeometry = function ( radius, widthSegments, heightSegments, phiStart, phiLength, thetaStart, thetaLength ) {
 
-	console.log( 'THREE.SphereGeometry: Consider using THREE.SphereBufferGeometry for lower memory footprint.' );
-
 	THREE.Geometry.call( this );
 
 	this.type = 'SphereGeometry';
@@ -20,94 +18,7 @@ THREE.SphereGeometry = function ( radius, widthSegments, heightSegments, phiStar
 		thetaLength: thetaLength
 	};
 
-	radius = radius || 50;
-
-	widthSegments = Math.max( 3, Math.floor( widthSegments ) || 8 );
-	heightSegments = Math.max( 2, Math.floor( heightSegments ) || 6 );
-
-	phiStart = phiStart !== undefined ? phiStart : 0;
-	phiLength = phiLength !== undefined ? phiLength : Math.PI * 2;
-
-	thetaStart = thetaStart !== undefined ? thetaStart : 0;
-	thetaLength = thetaLength !== undefined ? thetaLength : Math.PI;
-
-	var x, y, vertices = [], uvs = [];
-
-	for ( y = 0; y <= heightSegments; y ++ ) {
-
-		var verticesRow = [];
-		var uvsRow = [];
-
-		for ( x = 0; x <= widthSegments; x ++ ) {
-
-			var u = x / widthSegments;
-			var v = y / heightSegments;
-
-			var vertex = new THREE.Vector3();
-			vertex.x = - radius * Math.cos( phiStart + u * phiLength ) * Math.sin( thetaStart + v * thetaLength );
-			vertex.y = radius * Math.cos( thetaStart + v * thetaLength );
-			vertex.z = radius * Math.sin( phiStart + u * phiLength ) * Math.sin( thetaStart + v * thetaLength );
-
-			this.vertices.push( vertex );
-
-			verticesRow.push( this.vertices.length - 1 );
-			uvsRow.push( new THREE.Vector2( u, 1 - v ) );
-
-		}
-
-		vertices.push( verticesRow );
-		uvs.push( uvsRow );
-
-	}
-
-	for ( y = 0; y < heightSegments; y ++ ) {
-
-		for ( x = 0; x < widthSegments; x ++ ) {
-
-			var v1 = vertices[ y ][ x + 1 ];
-			var v2 = vertices[ y ][ x ];
-			var v3 = vertices[ y + 1 ][ x ];
-			var v4 = vertices[ y + 1 ][ x + 1 ];
-
-			var n1 = this.vertices[ v1 ].clone().normalize();
-			var n2 = this.vertices[ v2 ].clone().normalize();
-			var n3 = this.vertices[ v3 ].clone().normalize();
-			var n4 = this.vertices[ v4 ].clone().normalize();
-
-			var uv1 = uvs[ y ][ x + 1 ].clone();
-			var uv2 = uvs[ y ][ x ].clone();
-			var uv3 = uvs[ y + 1 ][ x ].clone();
-			var uv4 = uvs[ y + 1 ][ x + 1 ].clone();
-
-			if ( Math.abs( this.vertices[ v1 ].y ) === radius ) {
-
-				uv1.x = ( uv1.x + uv2.x ) / 2;
-				this.faces.push( new THREE.Face3( v1, v3, v4, [ n1, n3, n4 ] ) );
-				this.faceVertexUvs[ 0 ].push( [ uv1, uv3, uv4 ] );
-
-			} else if ( Math.abs( this.vertices[ v3 ].y ) === radius ) {
-
-				uv3.x = ( uv3.x + uv4.x ) / 2;
-				this.faces.push( new THREE.Face3( v1, v2, v3, [ n1, n2, n3 ] ) );
-				this.faceVertexUvs[ 0 ].push( [ uv1, uv2, uv3 ] );
-
-			} else {
-
-				this.faces.push( new THREE.Face3( v1, v2, v4, [ n1, n2, n4 ] ) );
-				this.faceVertexUvs[ 0 ].push( [ uv1, uv2, uv4 ] );
-
-				this.faces.push( new THREE.Face3( v2, v3, v4, [ n2.clone(), n3, n4.clone() ] ) );
-				this.faceVertexUvs[ 0 ].push( [ uv2.clone(), uv3, uv4.clone() ] );
-
-			}
-
-		}
-
-	}
-
-	this.computeFaceNormals();
-
-	this.boundingSphere = new THREE.Sphere( new THREE.Vector3(), radius );
+	this.fromBufferGeometry( new THREE.SphereBufferGeometry( radius, widthSegments, heightSegments, phiStart, phiLength, thetaStart, thetaLength ) );
 
 };
 

+ 0 - 144
src/extras/helpers/VertexTangentsHelper.js

@@ -1,144 +0,0 @@
-/**
- * @author mrdoob / http://mrdoob.com/
- * @author WestLangley / http://github.com/WestLangley
-*/
-
-THREE.VertexTangentsHelper = function ( object, size, hex, linewidth ) {
-
-	this.object = object;
-
-	this.size = ( size !== undefined ) ? size : 1;
-
-	var color = ( hex !== undefined ) ? hex : 0x0000ff;
-
-	var width = ( linewidth !== undefined ) ? linewidth : 1;
-
-	//
-
-	var nTangents = 0;
-
-	var objGeometry = this.object.geometry;
-
-	if ( objGeometry instanceof THREE.Geometry ) {
-
-		nTangents = objGeometry.faces.length * 3;
-
-	} else if ( objGeometry instanceof THREE.BufferGeometry ) {
-
-		nTangents = objGeometry.attributes.tangent.count
-
-	}
-
-	//
-
-	var geometry = new THREE.BufferGeometry();
-
-	var positions = new THREE.Float32Attribute( nTangents * 2 * 3, 3 );
-
-	geometry.addAttribute( 'position', positions );
-
-	THREE.LineSegments.call( this, geometry, new THREE.LineBasicMaterial( { color: color, linewidth: width } ) );
-
-	//
-
-	this.matrixAutoUpdate = false;
-
-	this.update();
-
-};
-
-THREE.VertexTangentsHelper.prototype = Object.create( THREE.LineSegments.prototype );
-THREE.VertexTangentsHelper.prototype.constructor = THREE.VertexTangentsHelper;
-
-THREE.VertexTangentsHelper.prototype.update = ( function ( object ) {
-
-	var v1 = new THREE.Vector3();
-	var v2 = new THREE.Vector3();
-
-	return function() {
-
-		var keys = [ 'a', 'b', 'c' ];
-
-		this.object.updateMatrixWorld( true );
-
-		var matrixWorld = this.object.matrixWorld;
-
-		var position = this.geometry.attributes.position;
-
-		//
-
-		var objGeometry = this.object.geometry;
-
-		if ( objGeometry instanceof THREE.Geometry ) {
-
-			var vertices = objGeometry.vertices;
-
-			var faces = objGeometry.faces;
-
-			var idx = 0;
-
-			for ( var i = 0, l = faces.length; i < l; i ++ ) {
-
-				var face = faces[ i ];
-
-				for ( var j = 0, jl = face.vertexTangents.length; j < jl; j ++ ) {
-
-					var vertex = vertices[ face[ keys[ j ] ] ];
-
-					var tangent = face.vertexTangents[ j ];
-
-					v1.copy( vertex ).applyMatrix4( matrixWorld );
-
-					v2.set( tangent.x, tangent.y, tangent.z ); // tangent.w used for bitangents only
-
-					v2.transformDirection( matrixWorld ).multiplyScalar( this.size ).add( v1 );
-
-					position.setXYZ( idx, v1.x, v1.y, v1.z );
-
-					idx = idx + 1;
-
-					position.setXYZ( idx, v2.x, v2.y, v2.z );
-
-					idx = idx + 1;
-
-				}
-
-			}
-
-		} else if ( objGeometry instanceof THREE.BufferGeometry ) {
-
-			var objPos = objGeometry.attributes.position;
-
-			var objTan = objGeometry.attributes.tangent;
-
-			var idx = 0;
-
-			// for simplicity, ignore index and drawcalls, and render every tangent
-
-			for ( var j = 0, jl = objPos.count; j < jl; j ++ ) {
-
-				v1.set( objPos.getX( j ), objPos.getY( j ), objPos.getZ( j ) ).applyMatrix4( matrixWorld );
-
-				v2.set( objTan.getX( j ), objTan.getY( j ), objTan.getZ( j ) ); // tangent.w used for bitangents only
-
-				v2.transformDirection( matrixWorld ).multiplyScalar( this.size ).add( v1 );
-
-				position.setXYZ( idx, v1.x, v1.y, v1.z );
-
-				idx = idx + 1;
-
-				position.setXYZ( idx, v2.x, v2.y, v2.z );
-
-				idx = idx + 1;
-
-			}
-
-		}
-
-		position.needsUpdate = true;
-
-		return this;
-
-	}
-
-}() );

+ 0 - 56
src/lights/AreaLight.js

@@ -1,56 +0,0 @@
-/**
- * @author MPanknin / http://www.redplant.de/
- * @author alteredq / http://alteredqualia.com/
- * @author prafullit
- */
-
-THREE.AreaLight = function ( color, intensity ) {
-
-	THREE.Light.call( this, color );
-
-	this.type = 'AreaLight';
-
-	this.normal = new THREE.Vector3( 0, - 1, 0 );
-	this.right = new THREE.Vector3( 1, 0, 0 );
-
-	this.intensity = ( intensity !== undefined ) ? intensity : 1;
-
-	this.width = 1.0;
-	this.height = 1.0;
-
-	this.constantAttenuation = 1.5;
-	this.linearAttenuation = 0.5;
-	this.quadraticAttenuation = 0.1;
-
-};
-
-THREE.AreaLight.prototype = Object.create( THREE.Light.prototype );
-THREE.AreaLight.prototype.constructor = THREE.AreaLight;
-
-THREE.AreaLight.prototype.copy = function ( source ) {
-
-	THREE.Light.prototype.copy.call( this, source );
-
-	this.intensity = source.intensity;
-	this.normal.copy( source.normal );
-	this.right.copy( source.right );
-	this.width = source.width;
-	this.height = source.height;
-	this.constantAttenuation = source.constantAttenuation;
-	this.linearAttenuation = source.linearAttenuation;
-	this.quadraticAttenuation = source.quadraticAttenuation;
-
-	return this;
-
-};
-
-THREE.AreaLight.prototype.toJSON = function ( meta ) {
-
-	var data = THREE.Object3D.prototype.toJSON.call( this, meta );
-
-	data.object.color = this.color.getHex();
-	data.object.intensity = this.intensity;
-
-	return data;
-
-};

+ 9 - 0
src/loaders/BufferGeometryLoader.js

@@ -36,6 +36,15 @@ THREE.BufferGeometryLoader.prototype = {
 
 		var geometry = new THREE.BufferGeometry();
 
+		var index = json.data.index;
+
+		if ( index !== undefined ) {
+
+			var typedArray = new self[ index.type ]( index.array );
+			geometry.addIndex( new THREE.BufferAttribute( typedArray, 1 ) );
+
+		}
+
 		var attributes = json.data.attributes;
 
 		for ( var key in attributes ) {

+ 4 - 6
src/loaders/ImageLoader.js

@@ -56,15 +56,13 @@ THREE.ImageLoader.prototype = {
 
 		}
 
-		if ( onError !== undefined ) {
+		image.addEventListener( 'error', function ( event ) {
 
-			image.addEventListener( 'error', function ( event ) {
+			if ( onError ) onError( event );
 
-				onError( event );
+			scope.manager.itemError( url );
 
-			}, false );
-
-		}
+		}, false );
 
 		if ( this.crossOrigin !== undefined ) image.crossOrigin = this.crossOrigin;
 

+ 20 - 6
src/loaders/JSONLoader.js

@@ -5,6 +5,13 @@
 
 THREE.JSONLoader = function ( manager ) {
 
+	if ( typeof manager === 'boolean' ) {
+
+		console.warn( 'THREE.JSONLoader: showStatus parameter has been removed from constructor.' );
+		manager = undefined;
+
+	}
+
 	this.manager = ( manager !== undefined ) ? manager : THREE.DefaultLoadingManager;
 
 	this.withCredentials = false;
@@ -15,6 +22,19 @@ THREE.JSONLoader.prototype = {
 
 	constructor: THREE.JSONLoader,
 
+	get statusDomElement () {
+
+		if ( this._statusDomElement === undefined ) {
+
+			this._statusDomElement = document.createElement( 'div' );
+
+		}
+
+		console.warn( 'THREE.JSONLoader: .statusDomElement has been removed.' );
+		return this._statusDomElement;
+
+	},
+
 	load: function( url, onLoad, onProgress, onError ) {
 
 		var scope = this;
@@ -495,12 +515,6 @@ THREE.JSONLoader.prototype = {
 
 			var materials = THREE.Loader.prototype.initMaterials( json.materials, texturePath, this.crossOrigin );
 
-			if ( THREE.Loader.prototype.needsTangents( materials ) ) {
-
-				geometry.computeTangents();
-
-			}
-
 			return { geometry: geometry, materials: materials };
 
 		}

+ 0 - 14
src/loaders/Loader.js

@@ -42,20 +42,6 @@ THREE.Loader.prototype = {
 
 	},
 
-	needsTangents: function ( materials ) {
-
-		for ( var i = 0, il = materials.length; i < il; i ++ ) {
-
-			var m = materials[ i ];
-
-			if ( m instanceof THREE.ShaderMaterial ) return true;
-
-		}
-
-		return false;
-
-	},
-
 	createMaterial: ( function () {
 
 		var imageLoader;

+ 11 - 0
src/loaders/LoadingManager.js

@@ -8,6 +8,7 @@ THREE.LoadingManager = function ( onLoad, onProgress, onError ) {
 
 	var isLoading = false, itemsLoaded = 0, itemsTotal = 0;
 
+	this.onStart = undefined;
 	this.onLoad = onLoad;
 	this.onProgress = onProgress;
 	this.onError = onError;
@@ -54,6 +55,16 @@ THREE.LoadingManager = function ( onLoad, onProgress, onError ) {
 
 	};
 
+	this.itemError = function ( url ) {
+
+		if ( scope.onError !== undefined ) {
+
+			scope.onError( url );
+
+		}
+
+	};
+
 };
 
 THREE.DefaultLoadingManager = new THREE.LoadingManager();

+ 0 - 1
src/loaders/MaterialLoader.js

@@ -41,7 +41,6 @@ THREE.MaterialLoader.prototype = {
 		if ( json.specular !== undefined ) material.specular.setHex( json.specular );
 		if ( json.shininess !== undefined ) material.shininess = json.shininess;
 		if ( json.uniforms !== undefined ) material.uniforms = json.uniforms;
-		if ( json.attributes !== undefined ) material.attributes = json.attributes;
 		if ( json.vertexShader !== undefined ) material.vertexShader = json.vertexShader;
 		if ( json.fragmentShader !== undefined ) material.fragmentShader = json.fragmentShader;
 		if ( json.vertexColors !== undefined ) material.vertexColors = json.vertexColors;

+ 41 - 13
src/loaders/ObjectLoader.js

@@ -251,6 +251,15 @@ THREE.ObjectLoader.prototype = {
 
 						break;
 
+					case 'TextGeometry':
+
+						geometry = new THREE.TextGeometry(
+							data.text,
+							data.data
+						);
+
+						break;
+
 					case 'BufferGeometry':
 
 						geometry = bufferGeometryLoader.parse( data );
@@ -263,14 +272,11 @@ THREE.ObjectLoader.prototype = {
 
 						break;
 
-					case 'TextGeometry':
+					default:
 
-						geometry = new THREE.TextGeometry(
-							data.text,
-							data.data
-						);
+						console.warn( 'THREE.ObjectLoader: Unsupported geometry type "' + data.type + '"' );
 
-						break;
+						continue;
 
 				}
 
@@ -335,6 +341,9 @@ THREE.ObjectLoader.prototype = {
 				if ( data.normalMap !== undefined ) material.normalMap = getTexture( data.normalMap );
 				if ( data.normalScale )	material.normalScale = new THREE.Vector2( data.normalScale, data.normalScale );
 
+				if ( data.displacementMap !== undefined ) material.displacementMap = getTexture( data.displacementMap );
+				if ( data.displacementScale !== undefined ) material.displacementScale = data.displacementScale;
+
 				if ( data.specularMap !== undefined ) material.specularMap = getTexture( data.specularMap );
 
 				if ( data.envMap !== undefined ) {
@@ -440,6 +449,7 @@ THREE.ObjectLoader.prototype = {
 
 				if ( data.name !== undefined ) texture.name = data.name;
 				if ( data.mapping !== undefined ) texture.mapping = parseConstant( data.mapping );
+				if ( data.offset !== undefined ) texture.offset = new THREE.Vector2( data.offset[ 0 ], data.offset[ 1 ] );
 				if ( data.repeat !== undefined ) texture.repeat = new THREE.Vector2( data.repeat[ 0 ], data.repeat[ 1 ] );
 				if ( data.minFilter !== undefined ) texture.minFilter = parseConstant( data.minFilter );
 				if ( data.magFilter !== undefined ) texture.magFilter = parseConstant( data.magFilter );
@@ -519,13 +529,6 @@ THREE.ObjectLoader.prototype = {
 
 					break;
 
-
-				case 'AreaLight':
-
-					object = new THREE.AreaLight( data.color, data.intensity );
-
-					break;
-
 				case 'DirectionalLight':
 
 					object = new THREE.DirectionalLight( data.color, data.intensity );
@@ -556,6 +559,12 @@ THREE.ObjectLoader.prototype = {
 
 					break;
 
+				case 'LOD':
+
+					object = new THREE.LOD();
+
+					break;
+
 				case 'Line':
 
 					object = new THREE.Line( getGeometry( data.geometry ), getMaterial( data.material ), data.mode );
@@ -618,6 +627,25 @@ THREE.ObjectLoader.prototype = {
 
 			}
 
+			if ( data.type === 'LOD' ) {
+
+				var levels = data.levels;
+
+				for ( var l = 0; l < levels.length; l ++ ) {
+
+					var level = levels[ l ];
+					var child = object.getObjectByProperty( 'uuid', level.object );
+
+					if ( child !== undefined ) {
+
+						object.addLevel( child, level.distance );
+
+					}
+
+				}
+
+			}
+
 			return object;
 
 		}

+ 4 - 6
src/loaders/XHRLoader.js

@@ -57,15 +57,13 @@ THREE.XHRLoader.prototype = {
 
 		}
 
-		if ( onError !== undefined ) {
+		request.addEventListener( 'error', function ( event ) {
 
-			request.addEventListener( 'error', function ( event ) {
+			if ( onError ) onError( event );
 
-				onError( event );
+			scope.manager.itemError( url );
 
-			}, false );
-
-		}
+		}, false );
 
 		if ( this.crossOrigin !== undefined ) request.crossOrigin = this.crossOrigin;
 		if ( this.responseType !== undefined ) request.responseType = this.responseType;

+ 6 - 0
src/materials/Material.js

@@ -144,6 +144,12 @@ THREE.Material.prototype = {
 			data.normalMap = this.normalMap.toJSON( meta ).uuid;
 			data.normalScale = this.normalScale; // Removed for now, causes issue in editor ui.js
 
+		}
+		if ( this.displacementMap instanceof THREE.Texture ) {
+
+			data.displacementMap = this.displacementMap.toJSON( meta ).uuid;
+			data.displacementScale = this.displacementScale;
+
 		}
 		if ( this.specularMap instanceof THREE.Texture ) data.specularMap = this.specularMap.toJSON( meta ).uuid;
 		if ( this.envMap instanceof THREE.Texture ) {

+ 0 - 5
src/materials/MeshLambertMaterial.js

@@ -18,7 +18,6 @@
  *  reflectivity: <float>,
  *  refractionRatio: <float>,
  *
- *  shading: THREE.SmoothShading,
  *  blending: THREE.NormalBlending,
  *  depthTest: <bool>,
  *  depthWrite: <bool>,
@@ -58,8 +57,6 @@ THREE.MeshLambertMaterial = function ( parameters ) {
 
 	this.fog = true;
 
-	this.shading = THREE.SmoothShading;
-
 	this.wireframe = false;
 	this.wireframeLinewidth = 1;
 	this.wireframeLinecap = 'round';
@@ -98,8 +95,6 @@ THREE.MeshLambertMaterial.prototype.copy = function ( source ) {
 
 	this.fog = source.fog;
 
-	this.shading = source.shading;
-
 	this.wireframe = source.wireframe;
 	this.wireframeLinewidth = source.wireframeLinewidth;
 	this.wireframeLinecap = source.wireframeLinecap;

+ 12 - 0
src/materials/MeshPhongMaterial.js

@@ -25,6 +25,10 @@
  *  normalMap: new THREE.Texture( <Image> ),
  *  normalScale: <Vector2>,
  *
+ *  displacementMap: new THREE.Texture( <Image> ),
+ *  displacementScale: <float>,
+ *  displacementBias: <float>,
+ *
  *  specularMap: new THREE.Texture( <Image> ),
  *
  *  alphaMap: new THREE.Texture( <Image> ),
@@ -81,6 +85,10 @@ THREE.MeshPhongMaterial = function ( parameters ) {
 	this.normalMap = null;
 	this.normalScale = new THREE.Vector2( 1, 1 );
 
+	this.displacementMap = null;
+	this.displacementScale = 1;
+	this.displacementBias = 0;
+
 	this.specularMap = null;
 
 	this.alphaMap = null;
@@ -139,6 +147,10 @@ THREE.MeshPhongMaterial.prototype.copy = function ( source ) {
 	this.normalMap = source.normalMap;
 	this.normalScale.copy( source.normalScale );
 
+	this.displacementMap = source.displacementMap;
+	this.displacementScale = source.displacementScale;
+	this.displacementBias = source.displacementBias;
+
 	this.specularMap = source.specularMap;
 
 	this.alphaMap = source.alphaMap;

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