Mr.doob 9 years ago
parent
commit
f735178187
100 changed files with 5215 additions and 4842 deletions
  1. 3026 3033
      build/three.js
  2. 326 338
      build/three.min.js
  3. 0 8
      docs/api/core/BufferGeometry.html
  4. 213 0
      docs/api/core/Uniform.html
  5. 0 57
      docs/api/extras/helpers/EdgesHelper.html
  6. 0 58
      docs/api/extras/helpers/WireframeHelper.html
  7. 1 1
      docs/api/geometries/BoxBufferGeometry.html
  8. 1 1
      docs/api/geometries/BoxGeometry.html
  9. 1 1
      docs/api/geometries/CircleBufferGeometry.html
  10. 1 1
      docs/api/geometries/CircleGeometry.html
  11. 1 1
      docs/api/geometries/ConeBufferGeometry.html
  12. 1 1
      docs/api/geometries/ConeGeometry.html
  13. 1 1
      docs/api/geometries/CylinderBufferGeometry.html
  14. 1 1
      docs/api/geometries/CylinderGeometry.html
  15. 1 1
      docs/api/geometries/DodecahedronGeometry.html
  16. 1 1
      docs/api/geometries/ExtrudeGeometry.html
  17. 1 1
      docs/api/geometries/IcosahedronGeometry.html
  18. 1 1
      docs/api/geometries/LatheBufferGeometry.html
  19. 1 1
      docs/api/geometries/LatheGeometry.html
  20. 1 1
      docs/api/geometries/OctahedronGeometry.html
  21. 1 1
      docs/api/geometries/ParametricGeometry.html
  22. 1 1
      docs/api/geometries/PlaneBufferGeometry.html
  23. 1 1
      docs/api/geometries/PlaneGeometry.html
  24. 1 1
      docs/api/geometries/PolyhedronGeometry.html
  25. 1 1
      docs/api/geometries/RingBufferGeometry.html
  26. 1 1
      docs/api/geometries/RingGeometry.html
  27. 1 1
      docs/api/geometries/ShapeGeometry.html
  28. 1 1
      docs/api/geometries/SphereBufferGeometry.html
  29. 1 1
      docs/api/geometries/SphereGeometry.html
  30. 1 1
      docs/api/geometries/TetrahedronGeometry.html
  31. 1 1
      docs/api/geometries/TextGeometry.html
  32. 1 1
      docs/api/geometries/TorusBufferGeometry.html
  33. 1 1
      docs/api/geometries/TorusGeometry.html
  34. 1 1
      docs/api/geometries/TorusKnotBufferGeometry.html
  35. 1 1
      docs/api/geometries/TorusKnotGeometry.html
  36. 1 1
      docs/api/geometries/TubeGeometry.html
  37. 5 4
      docs/api/loaders/OBJLoader.html
  38. 1 146
      docs/api/materials/ShaderMaterial.html
  39. 1 18
      docs/api/objects/Mesh.html
  40. 36 37
      docs/list.js
  41. 1 1
      docs/scenes/bones-browser.html
  42. 1 1
      docs/scenes/geometry-browser.html
  43. 1 1
      docs/scenes/material-browser.html
  44. 1 1
      editor/js/Menubar.View.js
  45. 20 20
      editor/js/libs/tern-threejs/threejs.js
  46. 4 1
      examples/files.js
  47. 1 1
      examples/js/GPUComputationRenderer.js
  48. 170 183
      examples/js/MarchingCubes.js
  49. 93 11
      examples/js/ViveController.js
  50. 10 2
      examples/js/controls/TransformControls.js
  51. 23 59
      examples/js/controls/VRControls.js
  52. 1 1
      examples/js/effects/StereoEffect.js
  53. 100 131
      examples/js/effects/VREffect.js
  54. 0 58
      examples/js/libs/dat.gui.min.js
  55. 3 6
      examples/js/loaders/AMFLoader.js
  56. 51 112
      examples/js/loaders/MMDLoader.js
  57. 34 9
      examples/js/loaders/OBJLoader.js
  58. 38 0
      examples/js/nodes/AttributeNode.js
  59. 0 208
      examples/js/nodes/BuilderNode.js
  60. 43 17
      examples/js/nodes/ConstNode.js
  61. 6 8
      examples/js/nodes/FunctionCallNode.js
  62. 119 75
      examples/js/nodes/FunctionNode.js
  63. 24 18
      examples/js/nodes/GLNode.js
  64. 4 2
      examples/js/nodes/InputNode.js
  65. 258 0
      examples/js/nodes/NodeBuilder.js
  66. 120 40
      examples/js/nodes/NodeLib.js
  67. 107 46
      examples/js/nodes/NodeMaterial.js
  68. 1 2
      examples/js/nodes/RawNode.js
  69. 11 14
      examples/js/nodes/TempNode.js
  70. 26 0
      examples/js/nodes/VarNode.js
  71. 16 3
      examples/js/nodes/accessors/CameraNode.js
  72. 2 2
      examples/js/nodes/accessors/ColorsNode.js
  73. 1 2
      examples/js/nodes/accessors/LightNode.js
  74. 2 2
      examples/js/nodes/accessors/NormalNode.js
  75. 2 2
      examples/js/nodes/accessors/PositionNode.js
  76. 3 3
      examples/js/nodes/accessors/ReflectNode.js
  77. 1 2
      examples/js/nodes/accessors/ScreenUVNode.js
  78. 1 1
      examples/js/nodes/accessors/UVNode.js
  79. 1 1
      examples/js/nodes/inputs/ColorNode.js
  80. 21 1
      examples/js/nodes/inputs/CubeTextureNode.js
  81. 1 1
      examples/js/nodes/inputs/FloatNode.js
  82. 1 1
      examples/js/nodes/inputs/IntNode.js
  83. 1 1
      examples/js/nodes/inputs/Matrix4Node.js
  84. 7 4
      examples/js/nodes/inputs/MirrorNode.js
  85. 21 1
      examples/js/nodes/inputs/TextureNode.js
  86. 1 1
      examples/js/nodes/inputs/Vector2Node.js
  87. 1 1
      examples/js/nodes/inputs/Vector3Node.js
  88. 1 1
      examples/js/nodes/inputs/Vector4Node.js
  89. 19 17
      examples/js/nodes/materials/PhongNode.js
  90. 22 17
      examples/js/nodes/materials/StandardNode.js
  91. 1 1
      examples/js/nodes/math/Math3Node.js
  92. 8 8
      examples/js/nodes/math/OperatorNode.js
  93. 114 0
      examples/js/nodes/utils/BlurNode.js
  94. 49 0
      examples/js/nodes/utils/BumpNode.js
  95. 3 3
      examples/js/nodes/utils/JoinNode.js
  96. 1 2
      examples/js/nodes/utils/NormalMapNode.js
  97. 1 1
      examples/js/nodes/utils/ResolutionNode.js
  98. 2 4
      examples/js/nodes/utils/RoughnessToBlinnExponentNode.js
  99. 1 1
      examples/js/nodes/utils/SwitchNode.js
  100. 1 1
      examples/js/nodes/utils/TimerNode.js

File diff suppressed because it is too large
+ 3026 - 3033
build/three.js


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


+ 0 - 8
docs/api/core/BufferGeometry.html

@@ -228,14 +228,6 @@
 		Bounding spheres aren't computed by default. They need to be explicitly computed, otherwise they are *null*.
 		Bounding spheres aren't computed by default. They need to be explicitly computed, otherwise they are *null*.
 		</div>
 		</div>
 
 
-		<h3>[method:null computeOffsets] ( [page:Integer size] )</h3>
-		<div>
-		Compute the draw offset for large models by chunking the index buffer into chunks of 65k addressable vertices.
-		This method will effectively rewrite the index buffer and remap all attributes to match the new indices.
-		WARNING: This method will also expand the vertex count to prevent sprawled triangles across draw offsets.
-		size - Defaults to 65535 or 4294967296 if extension OES_element_index_uint supported, but allows for larger or smaller chunks.
-		</div>
-
 		<h3>[method:null merge]( [page:BufferGeometry bufferGeometry], [page:Integer offset] )</h3>
 		<h3>[method:null merge]( [page:BufferGeometry bufferGeometry], [page:Integer offset] )</h3>
 		<div>
 		<div>
 		Merge in another BufferGeometry with an optional offset of where to start merging in.
 		Merge in another BufferGeometry with an optional offset of where to start merging in.

+ 213 - 0
docs/api/core/Uniform.html

@@ -0,0 +1,213 @@
+<!DOCTYPE html>
+<html lang="en">
+	<head>
+		<meta charset="utf-8" />
+		<base href="../../" />
+		<script src="list.js"></script>
+		<script src="page.js"></script>
+		<link type="text/css" rel="stylesheet" href="page.css" />
+	</head>
+	<body>
+		<h1>[name]</h1>
+
+		<div class="desc">Uniforms are global [link:https://www.opengl.org/documentation/glsl/ GLSL] variables. They are passed to shader programs.
+		</div>
+
+		<h3>Example</h3>
+		<p>
+		When declaring a uniform of a [page:ShaderMaterial], it is declared by value or by object.
+		</p>
+		<code>
+		uniforms: {
+			time: { value: 1.0 },
+			resolution: new THREE.Uniform(new THREE.Vector2())
+		}
+		</code>
+
+		<h3>Uniform types</h3>
+
+		<p>
+		Each uniform must have a *value* property. The type of the value must correspond to the type of the uniform variable in the GLSL code as specified for the primitive GLSL types in the table below. Uniform structures and arrays are also supported. GLSL arrays of primitive type must either be specified as an array of the corresponding THREE objects or as a flat array containing the data of all the objects. In other words; GLSL primitives in arrays must not be represented by arrays. This rule does not apply transitively.  An array of *vec2* arrays, each with a length of five vectors, must be an array of arrays, of either five *THREE.Vector2* objects or ten *number*s.
+		</p>
+		<table>
+			<caption><a id="uniform-types">Uniform types</a></caption>
+			<thead>
+				<tr>
+					<th>GLSL type</th>
+					<th>JavaScript type</th>
+				</tr>
+			</thead>
+			<tbody>
+
+				<tr>
+					<td>int</td>
+					<td>[page:Number]</td>
+				</tr>
+				<tr>
+					<td>float</td>
+					<td>[page:Number]</td>
+				</tr>
+				<tr>
+					<td>bool</td>
+					<td>[page:Boolean]</td>
+				</tr>
+				<tr>
+					<td>bool</td>
+					<td>[page:Number]</td>
+				</tr>
+
+				<tr>
+					<td>vec2</td>
+					<td>[page:Vector2 THREE.Vector2]</td>
+				</tr>
+				<tr>
+					<td>vec2</td>
+					<td>[page:Float32Array Float32Array] (*)</td>
+				</tr>
+				<tr>
+					<td>vec2</td>
+					<td>[page:Array Array] (*)</td>
+				</tr>
+				<tr>
+					<td>vec3</td>
+					<td>[page:Vector3 THREE.Vector3]</td>
+				</tr>
+				<tr>
+					<td>vec3</td>
+					<td>[page:Color THREE.Color]</td>
+				</tr>
+				<tr>
+					<td>vec3</td>
+					<td>[page:Float32Array Float32Array] (*)</td>
+				</tr>
+				<tr>
+					<td>vec3</td>
+					<td>[page:Array Array] (*)</td>
+				</tr>
+				<tr>
+					<td>vec4</td>
+					<td>[page:Vector4 THREE.Vector4]</td>
+				</tr>
+				<tr>
+					<td>vec4</td>
+					<td>[page:Quaternion THREE.Quaternion]</td>
+				</tr>
+				<tr>
+					<td>vec4</td>
+					<td>[page:Float32Array Float32Array] (*)</td>
+				</tr>
+				<tr>
+					<td>vec4</td>
+					<td>[page:Array Array] (*)</td>
+				</tr>
+
+				<tr>
+					<td>mat2</td>
+					<td>[page:Float32Array Float32Array] (*)</td>
+				</td>
+				<tr>
+					<td>mat2</td>
+					<td>[page:Array Array] (*)</td>
+				</td>
+				<tr>
+					<td>mat3</td>
+					<td>[page:Matrix3 THREE.Matrix3]</td>
+				</tr>
+				<tr>
+					<td>mat3</td>
+					<td>[page:Float32Array Float32Array] (*)</td>
+				</tr>
+				<tr>
+					<td>mat3</td>
+					<td>[page:Array Array] (*)</td>
+				</tr>
+				<tr>
+					<td>mat4</td>
+					<td>[page:Matrix3 THREE.Matrix4]</td>
+				</tr>
+				<tr>
+					<td>mat4</td>
+					<td>[page:Float32Array Float32Array] (*)</td>
+				</tr>
+				<tr>
+					<td>mat4</td>
+					<td>[page:Array Array] (*)</td>
+				</tr>
+
+				<tr>
+					<td>ivec2, bvec2</td>
+					<td>[page:Float32Array Float32Array] (*)</td>
+				</tr>
+				<tr>
+					<td>ivec2, bvec2</td>
+					<td>[page:Array Array] (*)</td>
+				</tr>
+				<tr>
+					<td>ivec3, bvec3</td>
+					<td>[page:Int32Array Int32Array] (*)</td>
+				</tr>
+				<tr>
+					<td>ivec3, bvec3</td>
+					<td>[page:Array Array] (*)</td>
+				</tr>
+				<tr>
+					<td>ivec4, bvec4</td>
+					<td>[page:Int32Array Int32Array] (*)</td>
+				</tr>
+				<tr>
+					<td>ivec4, bvec4</td>
+					<td>[page:Array Array] (*)</td>
+				</tr>
+
+				<tr>
+					<td>sampler2D</td>
+					<td>[page:Texture THREE.Texture]</td>
+				</tr>
+				<tr>
+					<td>samplerCube</td>
+					<td>[page:CubeTexture THREE.CubeTexture]</tr>
+				</tr>
+
+			</tbody>
+		</table>
+		</p>
+		<p>
+		(*) Same for an (innermost) array (dimension) of the same GLSL type, containing the components of all vectors or matrices in the array.
+		</p>
+
+		<h2>Constructor</h2>
+
+		<h3>[name]( [page:Object value] )</h3>
+		<div>
+		value -- An object containing the value to set up the uniform. It's type must be one of the Uniform Types described above.
+		</div>
+
+		<h2>Properties</h2>
+
+		<h3>[property:Object value]</h3>
+		<div>
+		Current value of the uniform.
+		</div>
+
+		<h3>[property:Boolean dynamic]</h3>
+		<div>
+		Sets wether this uniform is updated at each render call when used by a renderer.
+		You must set this attribute by calling [page:.onUpdate].
+		</div>
+
+		<h2>Methods</h2>
+
+		<h3>[method:Uniform onUpdate]( [page:Function callback] ) [page:Uniform this]</h3>
+		<div>
+		Set the callback function to update this uniform at each render call. The callback has two optional parameters :
+		<ul>
+			<li>[page:Object object] : The current object associated to the [page:Material] using this [page:Uniform]</li>
+			<li>[page:Camera camera] : The current camera used by the current [page:WebGLRenderer]</li>
+		</ul>
+		</div>
+
+		<h2>Source</h2>
+
+		[link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js]
+	</body>
+</html>

+ 0 - 57
docs/api/extras/helpers/EdgesHelper.html

@@ -1,57 +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">Creates a wireframe object that shows the "hard" edges of another object's geometry. To draw a full wireframe image of an object, see [page:WireframeHelper].</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.EdgesHelper( object, 0x00ff00 );
-
-		scene.add( object );
-		scene.add( edges );
-		</code>
-
-		<h2>Constructor</h2>
-		<h3>[name]( [page:Object3D object], [page:Color color], [page:Float thresholdAngle] )</h3>
-		<div>
-		object -- Object of which to draw edges <br />
-		color -- Color of the edges.<br />
-		thresholdAngle -- the minimim angle (in degrees), between the face normals of adjacent faces, that is required to render an edge. Default is 0.1.
-
-		</div>
-		<div>
-		Creates a [page:Line], showing only the "hard" edges of the passed object; specifically, no edge will be drawn between faces which are adjacent and coplanar (or nearly coplanar).
-		</div>
-
-
-		<h2>Properties</h2>
-
-		<div>none</div>
-
-
-		<h2>Methods</h2>
-
-		<div>none</div>
-
-
-		<h2>Source</h2>
-
-		[link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js]
-	</body>
-</html>

+ 0 - 58
docs/api/extras/helpers/WireframeHelper.html

@@ -1,58 +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">Creates a wireframe object that shows the edges of another object's geometry. To draw a  wireframe image showing only "hard" edges (edges between non-coplanar faces), see [page:EdgesHelper].</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 );
-
-		wireframe = new THREE.WireframeHelper( object, 0x00ff00 );
-
-		scene.add( object );
-		scene.add( wireframe );
-
-		</code>
-		[example:webgl_helpers Example using various helpers], [example:webgl_materials_wireframe Alternative approach using a shader.]
-
-		<h2>Constructor</h2>
-		<h3>[name]( [page:Object3D object], [page:Color color] )</h3>
-		<div>
-		object -- Object of which to draw edges <br />
-		color -- Color of the edges.
-		</div>
-		<div>
-		Creates a [page:Line], showing only the edges between vertices of an object.
-		</div>
-
-
-		<h2>Properties</h2>
-
-		<div>none</div>
-
-
-		<h2>Methods</h2>
-
-		<div>none</div>
-
-
-		<h2>Source</h2>
-		<h2>Source</h2>
-
-		[link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js]
-	</body>
-</html>

+ 1 - 1
docs/api/extras/geometries/BoxBufferGeometry.html → docs/api/geometries/BoxBufferGeometry.html

@@ -2,7 +2,7 @@
 <html lang="en">
 <html lang="en">
 	<head>
 	<head>
 		<meta charset="utf-8" />
 		<meta charset="utf-8" />
-		<base href="../../../" />
+		<base href="../../" />
 		<script src="list.js"></script>
 		<script src="list.js"></script>
 		<script src="page.js"></script>
 		<script src="page.js"></script>
 		<link type="text/css" rel="stylesheet" href="page.css" />
 		<link type="text/css" rel="stylesheet" href="page.css" />

+ 1 - 1
docs/api/extras/geometries/BoxGeometry.html → docs/api/geometries/BoxGeometry.html

@@ -2,7 +2,7 @@
 <html lang="en">
 <html lang="en">
 	<head>
 	<head>
 		<meta charset="utf-8" />
 		<meta charset="utf-8" />
-		<base href="../../../" />
+		<base href="../../" />
 		<script src="list.js"></script>
 		<script src="list.js"></script>
 		<script src="page.js"></script>
 		<script src="page.js"></script>
 		<link type="text/css" rel="stylesheet" href="page.css" />
 		<link type="text/css" rel="stylesheet" href="page.css" />

+ 1 - 1
docs/api/extras/geometries/CircleBufferGeometry.html → docs/api/geometries/CircleBufferGeometry.html

@@ -2,7 +2,7 @@
 <html lang="en">
 <html lang="en">
 	<head>
 	<head>
 		<meta charset="utf-8" />
 		<meta charset="utf-8" />
-		<base href="../../../" />
+		<base href="../../" />
 		<script src="list.js"></script>
 		<script src="list.js"></script>
 		<script src="page.js"></script>
 		<script src="page.js"></script>
 		<link type="text/css" rel="stylesheet" href="page.css" />
 		<link type="text/css" rel="stylesheet" href="page.css" />

+ 1 - 1
docs/api/extras/geometries/CircleGeometry.html → docs/api/geometries/CircleGeometry.html

@@ -2,7 +2,7 @@
 <html lang="en">
 <html lang="en">
 	<head>
 	<head>
 		<meta charset="utf-8" />
 		<meta charset="utf-8" />
-		<base href="../../../" />
+		<base href="../../" />
 		<script src="list.js"></script>
 		<script src="list.js"></script>
 		<script src="page.js"></script>
 		<script src="page.js"></script>
 		<link type="text/css" rel="stylesheet" href="page.css" />
 		<link type="text/css" rel="stylesheet" href="page.css" />

+ 1 - 1
docs/api/extras/geometries/ConeBufferGeometry.html → docs/api/geometries/ConeBufferGeometry.html

@@ -2,7 +2,7 @@
 <html lang="en">
 <html lang="en">
 	<head>
 	<head>
 		<meta charset="utf-8" />
 		<meta charset="utf-8" />
-		<base href="../../../" />
+		<base href="../../" />
 		<script src="list.js"></script>
 		<script src="list.js"></script>
 		<script src="page.js"></script>
 		<script src="page.js"></script>
 		<link type="text/css" rel="stylesheet" href="page.css" />
 		<link type="text/css" rel="stylesheet" href="page.css" />

+ 1 - 1
docs/api/extras/geometries/ConeGeometry.html → docs/api/geometries/ConeGeometry.html

@@ -2,7 +2,7 @@
 <html lang="en">
 <html lang="en">
 	<head>
 	<head>
 		<meta charset="utf-8" />
 		<meta charset="utf-8" />
-		<base href="../../../" />
+		<base href="../../" />
 		<script src="list.js"></script>
 		<script src="list.js"></script>
 		<script src="page.js"></script>
 		<script src="page.js"></script>
 		<link type="text/css" rel="stylesheet" href="page.css" />
 		<link type="text/css" rel="stylesheet" href="page.css" />

+ 1 - 1
docs/api/extras/geometries/CylinderBufferGeometry.html → docs/api/geometries/CylinderBufferGeometry.html

@@ -2,7 +2,7 @@
 <html lang="en">
 <html lang="en">
 	<head>
 	<head>
 		<meta charset="utf-8" />
 		<meta charset="utf-8" />
-		<base href="../../../" />
+		<base href="../../" />
 		<script src="list.js"></script>
 		<script src="list.js"></script>
 		<script src="page.js"></script>
 		<script src="page.js"></script>
 		<link type="text/css" rel="stylesheet" href="page.css" />
 		<link type="text/css" rel="stylesheet" href="page.css" />

+ 1 - 1
docs/api/extras/geometries/CylinderGeometry.html → docs/api/geometries/CylinderGeometry.html

@@ -2,7 +2,7 @@
 <html lang="en">
 <html lang="en">
 	<head>
 	<head>
 		<meta charset="utf-8" />
 		<meta charset="utf-8" />
-		<base href="../../../" />
+		<base href="../../" />
 		<script src="list.js"></script>
 		<script src="list.js"></script>
 		<script src="page.js"></script>
 		<script src="page.js"></script>
 		<link type="text/css" rel="stylesheet" href="page.css" />
 		<link type="text/css" rel="stylesheet" href="page.css" />

+ 1 - 1
docs/api/extras/geometries/DodecahedronGeometry.html → docs/api/geometries/DodecahedronGeometry.html

@@ -2,7 +2,7 @@
 <html lang="en">
 <html lang="en">
 	<head>
 	<head>
 		<meta charset="utf-8" />
 		<meta charset="utf-8" />
-		<base href="../../../" />
+		<base href="../../" />
 		<script src="list.js"></script>
 		<script src="list.js"></script>
 		<script src="page.js"></script>
 		<script src="page.js"></script>
 		<link type="text/css" rel="stylesheet" href="page.css" />
 		<link type="text/css" rel="stylesheet" href="page.css" />

+ 1 - 1
docs/api/extras/geometries/ExtrudeGeometry.html → docs/api/geometries/ExtrudeGeometry.html

@@ -2,7 +2,7 @@
 <html lang="en">
 <html lang="en">
 	<head>
 	<head>
 		<meta charset="utf-8" />
 		<meta charset="utf-8" />
-		<base href="../../../" />
+		<base href="../../" />
 		<script src="list.js"></script>
 		<script src="list.js"></script>
 		<script src="page.js"></script>
 		<script src="page.js"></script>
 		<link type="text/css" rel="stylesheet" href="page.css" />
 		<link type="text/css" rel="stylesheet" href="page.css" />

+ 1 - 1
docs/api/extras/geometries/IcosahedronGeometry.html → docs/api/geometries/IcosahedronGeometry.html

@@ -2,7 +2,7 @@
 <html lang="en">
 <html lang="en">
 	<head>
 	<head>
 		<meta charset="utf-8" />
 		<meta charset="utf-8" />
-		<base href="../../../" />
+		<base href="../../" />
 		<script src="list.js"></script>
 		<script src="list.js"></script>
 		<script src="page.js"></script>
 		<script src="page.js"></script>
 		<link type="text/css" rel="stylesheet" href="page.css" />
 		<link type="text/css" rel="stylesheet" href="page.css" />

+ 1 - 1
docs/api/extras/geometries/LatheBufferGeometry.html → docs/api/geometries/LatheBufferGeometry.html

@@ -2,7 +2,7 @@
 <html lang="en">
 <html lang="en">
 	<head>
 	<head>
 		<meta charset="utf-8" />
 		<meta charset="utf-8" />
-		<base href="../../../" />
+		<base href="../../" />
 		<script src="list.js"></script>
 		<script src="list.js"></script>
 		<script src="page.js"></script>
 		<script src="page.js"></script>
 		<link type="text/css" rel="stylesheet" href="page.css" />
 		<link type="text/css" rel="stylesheet" href="page.css" />

+ 1 - 1
docs/api/extras/geometries/LatheGeometry.html → docs/api/geometries/LatheGeometry.html

@@ -2,7 +2,7 @@
 <html lang="en">
 <html lang="en">
 	<head>
 	<head>
 		<meta charset="utf-8" />
 		<meta charset="utf-8" />
-		<base href="../../../" />
+		<base href="../../" />
 		<script src="list.js"></script>
 		<script src="list.js"></script>
 		<script src="page.js"></script>
 		<script src="page.js"></script>
 		<link type="text/css" rel="stylesheet" href="page.css" />
 		<link type="text/css" rel="stylesheet" href="page.css" />

+ 1 - 1
docs/api/extras/geometries/OctahedronGeometry.html → docs/api/geometries/OctahedronGeometry.html

@@ -2,7 +2,7 @@
 <html lang="en">
 <html lang="en">
 	<head>
 	<head>
 		<meta charset="utf-8" />
 		<meta charset="utf-8" />
-		<base href="../../../" />
+		<base href="../../" />
 		<script src="list.js"></script>
 		<script src="list.js"></script>
 		<script src="page.js"></script>
 		<script src="page.js"></script>
 		<link type="text/css" rel="stylesheet" href="page.css" />
 		<link type="text/css" rel="stylesheet" href="page.css" />

+ 1 - 1
docs/api/extras/geometries/ParametricGeometry.html → docs/api/geometries/ParametricGeometry.html

@@ -2,7 +2,7 @@
 <html lang="en">
 <html lang="en">
 	<head>
 	<head>
 		<meta charset="utf-8" />
 		<meta charset="utf-8" />
-		<base href="../../../" />
+		<base href="../../" />
 		<script src="list.js"></script>
 		<script src="list.js"></script>
 		<script src="page.js"></script>
 		<script src="page.js"></script>
 		<link type="text/css" rel="stylesheet" href="page.css" />
 		<link type="text/css" rel="stylesheet" href="page.css" />

+ 1 - 1
docs/api/extras/geometries/PlaneBufferGeometry.html → docs/api/geometries/PlaneBufferGeometry.html

@@ -2,7 +2,7 @@
 <html lang="en">
 <html lang="en">
 	<head>
 	<head>
 		<meta charset="utf-8" />
 		<meta charset="utf-8" />
-		<base href="../../../" />
+		<base href="../../" />
 		<script src="list.js"></script>
 		<script src="list.js"></script>
 		<script src="page.js"></script>
 		<script src="page.js"></script>
 		<link type="text/css" rel="stylesheet" href="page.css" />
 		<link type="text/css" rel="stylesheet" href="page.css" />

+ 1 - 1
docs/api/extras/geometries/PlaneGeometry.html → docs/api/geometries/PlaneGeometry.html

@@ -2,7 +2,7 @@
 <html lang="en">
 <html lang="en">
 	<head>
 	<head>
 		<meta charset="utf-8" />
 		<meta charset="utf-8" />
-		<base href="../../../" />
+		<base href="../../" />
 		<script src="list.js"></script>
 		<script src="list.js"></script>
 		<script src="page.js"></script>
 		<script src="page.js"></script>
 		<link type="text/css" rel="stylesheet" href="page.css" />
 		<link type="text/css" rel="stylesheet" href="page.css" />

+ 1 - 1
docs/api/extras/geometries/PolyhedronGeometry.html → docs/api/geometries/PolyhedronGeometry.html

@@ -2,7 +2,7 @@
 <html lang="en">
 <html lang="en">
 	<head>
 	<head>
 		<meta charset="utf-8" />
 		<meta charset="utf-8" />
-		<base href="../../../" />
+		<base href="../../" />
 		<script src="list.js"></script>
 		<script src="list.js"></script>
 		<script src="page.js"></script>
 		<script src="page.js"></script>
 		<link type="text/css" rel="stylesheet" href="page.css" />
 		<link type="text/css" rel="stylesheet" href="page.css" />

+ 1 - 1
docs/api/extras/geometries/RingBufferGeometry.html → docs/api/geometries/RingBufferGeometry.html

@@ -2,7 +2,7 @@
 <html lang="en">
 <html lang="en">
 	<head>
 	<head>
 		<meta charset="utf-8" />
 		<meta charset="utf-8" />
-		<base href="../../../" />
+		<base href="../../" />
 		<script src="list.js"></script>
 		<script src="list.js"></script>
 		<script src="page.js"></script>
 		<script src="page.js"></script>
 		<link type="text/css" rel="stylesheet" href="page.css" />
 		<link type="text/css" rel="stylesheet" href="page.css" />

+ 1 - 1
docs/api/extras/geometries/RingGeometry.html → docs/api/geometries/RingGeometry.html

@@ -2,7 +2,7 @@
 <html lang="en">
 <html lang="en">
 	<head>
 	<head>
 		<meta charset="utf-8" />
 		<meta charset="utf-8" />
-		<base href="../../../" />
+		<base href="../../" />
 		<script src="list.js"></script>
 		<script src="list.js"></script>
 		<script src="page.js"></script>
 		<script src="page.js"></script>
 		<link type="text/css" rel="stylesheet" href="page.css" />
 		<link type="text/css" rel="stylesheet" href="page.css" />

+ 1 - 1
docs/api/extras/geometries/ShapeGeometry.html → docs/api/geometries/ShapeGeometry.html

@@ -2,7 +2,7 @@
 <html lang="en">
 <html lang="en">
 	<head>
 	<head>
 		<meta charset="utf-8" />
 		<meta charset="utf-8" />
-		<base href="../../../" />
+		<base href="../../" />
 		<script src="list.js"></script>
 		<script src="list.js"></script>
 		<script src="page.js"></script>
 		<script src="page.js"></script>
 		<link type="text/css" rel="stylesheet" href="page.css" />
 		<link type="text/css" rel="stylesheet" href="page.css" />

+ 1 - 1
docs/api/extras/geometries/SphereBufferGeometry.html → docs/api/geometries/SphereBufferGeometry.html

@@ -2,7 +2,7 @@
 <html lang="en">
 <html lang="en">
 	<head>
 	<head>
 		<meta charset="utf-8" />
 		<meta charset="utf-8" />
-		<base href="../../../" />
+		<base href="../../" />
 		<script src="list.js"></script>
 		<script src="list.js"></script>
 		<script src="page.js"></script>
 		<script src="page.js"></script>
 		<link type="text/css" rel="stylesheet" href="page.css" />
 		<link type="text/css" rel="stylesheet" href="page.css" />

+ 1 - 1
docs/api/extras/geometries/SphereGeometry.html → docs/api/geometries/SphereGeometry.html

@@ -2,7 +2,7 @@
 <html lang="en">
 <html lang="en">
 	<head>
 	<head>
 		<meta charset="utf-8" />
 		<meta charset="utf-8" />
-		<base href="../../../" />
+		<base href="../../" />
 		<script src="list.js"></script>
 		<script src="list.js"></script>
 		<script src="page.js"></script>
 		<script src="page.js"></script>
 		<link type="text/css" rel="stylesheet" href="page.css" />
 		<link type="text/css" rel="stylesheet" href="page.css" />

+ 1 - 1
docs/api/extras/geometries/TetrahedronGeometry.html → docs/api/geometries/TetrahedronGeometry.html

@@ -2,7 +2,7 @@
 <html lang="en">
 <html lang="en">
 	<head>
 	<head>
 		<meta charset="utf-8" />
 		<meta charset="utf-8" />
-		<base href="../../../" />
+		<base href="../../" />
 		<script src="list.js"></script>
 		<script src="list.js"></script>
 		<script src="page.js"></script>
 		<script src="page.js"></script>
 		<link type="text/css" rel="stylesheet" href="page.css" />
 		<link type="text/css" rel="stylesheet" href="page.css" />

+ 1 - 1
docs/api/extras/geometries/TextGeometry.html → docs/api/geometries/TextGeometry.html

@@ -2,7 +2,7 @@
 <html lang="en">
 <html lang="en">
 	<head>
 	<head>
 		<meta charset="utf-8" />
 		<meta charset="utf-8" />
-		<base href="../../../" />
+		<base href="../../" />
 		<script src="list.js"></script>
 		<script src="list.js"></script>
 		<script src="page.js"></script>
 		<script src="page.js"></script>
 		<link type="text/css" rel="stylesheet" href="page.css" />
 		<link type="text/css" rel="stylesheet" href="page.css" />

+ 1 - 1
docs/api/extras/geometries/TorusBufferGeometry.html → docs/api/geometries/TorusBufferGeometry.html

@@ -2,7 +2,7 @@
 <html lang="en">
 <html lang="en">
 	<head>
 	<head>
 		<meta charset="utf-8" />
 		<meta charset="utf-8" />
-		<base href="../../../" />
+		<base href="../../" />
 		<script src="list.js"></script>
 		<script src="list.js"></script>
 		<script src="page.js"></script>
 		<script src="page.js"></script>
 		<link type="text/css" rel="stylesheet" href="page.css" />
 		<link type="text/css" rel="stylesheet" href="page.css" />

+ 1 - 1
docs/api/extras/geometries/TorusGeometry.html → docs/api/geometries/TorusGeometry.html

@@ -2,7 +2,7 @@
 <html lang="en">
 <html lang="en">
 	<head>
 	<head>
 		<meta charset="utf-8" />
 		<meta charset="utf-8" />
-		<base href="../../../" />
+		<base href="../../" />
 		<script src="list.js"></script>
 		<script src="list.js"></script>
 		<script src="page.js"></script>
 		<script src="page.js"></script>
 		<link type="text/css" rel="stylesheet" href="page.css" />
 		<link type="text/css" rel="stylesheet" href="page.css" />

+ 1 - 1
docs/api/extras/geometries/TorusKnotBufferGeometry.html → docs/api/geometries/TorusKnotBufferGeometry.html

@@ -2,7 +2,7 @@
 <html lang="en">
 <html lang="en">
 	<head>
 	<head>
 		<meta charset="utf-8" />
 		<meta charset="utf-8" />
-		<base href="../../../" />
+		<base href="../../" />
 		<script src="list.js"></script>
 		<script src="list.js"></script>
 		<script src="page.js"></script>
 		<script src="page.js"></script>
 		<link type="text/css" rel="stylesheet" href="page.css" />
 		<link type="text/css" rel="stylesheet" href="page.css" />

+ 1 - 1
docs/api/extras/geometries/TorusKnotGeometry.html → docs/api/geometries/TorusKnotGeometry.html

@@ -2,7 +2,7 @@
 <html lang="en">
 <html lang="en">
 	<head>
 	<head>
 		<meta charset="utf-8" />
 		<meta charset="utf-8" />
-		<base href="../../../" />
+		<base href="../../" />
 		<script src="list.js"></script>
 		<script src="list.js"></script>
 		<script src="page.js"></script>
 		<script src="page.js"></script>
 		<link type="text/css" rel="stylesheet" href="page.css" />
 		<link type="text/css" rel="stylesheet" href="page.css" />

+ 1 - 1
docs/api/extras/geometries/TubeGeometry.html → docs/api/geometries/TubeGeometry.html

@@ -2,7 +2,7 @@
 <html lang="en">
 <html lang="en">
 	<head>
 	<head>
 		<meta charset="utf-8" />
 		<meta charset="utf-8" />
-		<base href="../../../" />
+		<base href="../../" />
 		<script src="list.js"></script>
 		<script src="list.js"></script>
 		<script src="page.js"></script>
 		<script src="page.js"></script>
 		<link type="text/css" rel="stylesheet" href="page.css" />
 		<link type="text/css" rel="stylesheet" href="page.css" />

+ 5 - 4
docs/api/loaders/OBJLoader.html

@@ -1,7 +1,7 @@
 <!DOCTYPE html>
 <!DOCTYPE html>
 <html lang="en">
 <html lang="en">
 	<head>
 	<head>
-		<meta charset="utf-8" />
+		<meta charset="utf-8" />
 		<base href="../../" />
 		<base href="../../" />
 		<script src="list.js"></script>
 		<script src="list.js"></script>
 		<script src="page.js"></script>
 		<script src="page.js"></script>
@@ -45,8 +45,9 @@
 		[page:String text] — The textual <em>obj</em> structure to parse.
 		[page:String text] — The textual <em>obj</em> structure to parse.
 		</div>
 		</div>
 		<div>
 		<div>
-		Parse an <em>obj</em> text structure and return an [page:Object3D].<br />
-		Found objects are converted to [page:Mesh] with a [page:BufferGeometry] and a default [page:MeshPhongMaterial].
+		Returns an [page:Object3D]. It contains the parsed meshes as [page:Mesh] and lines as [page:LineSegments].<br />
+		All geometry is created as [page:BufferGeometry]. Default materials are created as [page:MeshPhongMaterial].<br />
+		If an <em>obj</em> object or group uses multiple materials while declaring faces geometry groups and an [page:MultiMaterial] is used.
 		</div>
 		</div>
 
 
 		<h2>Example</h2>
 		<h2>Example</h2>
@@ -58,7 +59,7 @@
 		// load a resource
 		// load a resource
 		loader.load(
 		loader.load(
 			// resource URL
 			// resource URL
-			'models/skinned/UCS_config.json',
+			'models/monster.obj',
 			// Function when resource is loaded
 			// Function when resource is loaded
 			function ( object ) {
 			function ( object ) {
 				scene.add( object );
 				scene.add( object );

+ 1 - 146
docs/api/materials/ShaderMaterial.html

@@ -120,158 +120,13 @@
 		</p>
 		</p>
 
 
 		<p>
 		<p>
-		To declare a custom uniform, use the *uniforms* property:
+		To declare a custom [page:Uniform], use the *uniforms* property:
 		<code>
 		<code>
 		uniforms: {
 		uniforms: {
 			time: { value: 1.0 },
 			time: { value: 1.0 },
 			resolution: { value: new THREE.Vector2() }
 			resolution: { value: new THREE.Vector2() }
 		}
 		}
 		</code>
 		</code>
-		Each uniform must have a *value* property. The type of the value must correspond to the type of the uniform variable in the GLSL code as specified for the primitive GLSL types in the table below. Uniform structures and arrays are also supported. GLSL arrays of primitive type must either be specified as an array of the corresponding THREE objects or as a flat array containing the data of all the objects. In other words; GLSL primitives in arrays must not be represented by arrays. This rule does not apply transitively.  An array of *vec2* arrays, each with a length of five vectors, must be an array of arrays, of either five *THREE.Vector2* objects or ten *number*s.
-		<table>
-			<caption><a id="uniform-types">Uniform types</a></caption>
-			<thead>
-				<tr>
-					<th>GLSL type</th>
-					<th>JavaScript type</th>
-				</tr>
-			</thead>
-			<tbody>
-
-				<tr>
-					<td>int</td>
-					<td>[page:Number]</td>
-				</tr>
-				<tr>
-					<td>float</td>
-					<td>[page:Number]</td>
-				</tr>
-				<tr>
-					<td>bool</td>
-					<td>[page:Boolean]</td>
-				</tr>
-				<tr>
-					<td>bool</td>
-					<td>[page:Number]</td>
-				</tr>
-
-				<tr>
-					<td>vec2</td>
-					<td>[page:Vector2 THREE.Vector2]</td>
-				</tr>
-				<tr>
-					<td>vec2</td>
-					<td>[page:Float32Array Float32Array] (*)</td>
-				</tr>
-				<tr>
-					<td>vec2</td>
-					<td>[page:Array Array] (*)</td>
-				</tr>
-				<tr>
-					<td>vec3</td>
-					<td>[page:Vector3 THREE.Vector3]</td>
-				</tr>
-				<tr>
-					<td>vec3</td>
-					<td>[page:Color THREE.Color]</td>
-				</tr>
-				<tr>
-					<td>vec3</td>
-					<td>[page:Float32Array Float32Array] (*)</td>
-				</tr>
-				<tr>
-					<td>vec3</td>
-					<td>[page:Array Array] (*)</td>
-				</tr>
-				<tr>
-					<td>vec4</td>
-					<td>[page:Vector4 THREE.Vector4]</td>
-				</tr>
-				<tr>
-					<td>vec4</td>
-					<td>[page:Quaternion THREE.Quaternion]</td>
-				</tr>
-				<tr>
-					<td>vec4</td>
-					<td>[page:Float32Array Float32Array] (*)</td>
-				</tr>
-				<tr>
-					<td>vec4</td>
-					<td>[page:Array Array] (*)</td>
-				</tr>
-
-				<tr>
-					<td>mat2</td>
-					<td>[page:Float32Array Float32Array] (*)</td>
-				</td>
-				<tr>
-					<td>mat2</td>
-					<td>[page:Array Array] (*)</td>
-				</td>
-				<tr>
-					<td>mat3</td>
-					<td>[page:Matrix3 THREE.Matrix3]</td>
-				</tr>
-				<tr>
-					<td>mat3</td>
-					<td>[page:Float32Array Float32Array] (*)</td>
-				</tr>
-				<tr>
-					<td>mat3</td>
-					<td>[page:Array Array] (*)</td>
-				</tr>
-				<tr>
-					<td>mat4</td>
-					<td>[page:Matrix3 THREE.Matrix4]</td>
-				</tr>
-				<tr>
-					<td>mat4</td>
-					<td>[page:Float32Array Float32Array] (*)</td>
-				</tr>
-				<tr>
-					<td>mat4</td>
-					<td>[page:Array Array] (*)</td>
-				</tr>
-
-				<tr>
-					<td>ivec2, bvec2</td>
-					<td>[page:Float32Array Float32Array] (*)</td>
-				</tr>
-				<tr>
-					<td>ivec2, bvec2</td>
-					<td>[page:Array Array] (*)</td>
-				</tr>
-				<tr>
-					<td>ivec3, bvec3</td>
-					<td>[page:Int32Array Int32Array] (*)</td>
-				</tr>
-				<tr>
-					<td>ivec3, bvec3</td>
-					<td>[page:Array Array] (*)</td>
-				</tr>
-				<tr>
-					<td>ivec4, bvec4</td>
-					<td>[page:Int32Array Int32Array] (*)</td>
-				</tr>
-				<tr>
-					<td>ivec4, bvec4</td>
-					<td>[page:Array Array] (*)</td>
-				</tr>
-
-				<tr>
-					<td>sampler2D</td>
-					<td>[page:Texture THREE.Texture]</td>
-				</tr>
-				<tr>
-					<td>samplerCube</td>
-					<td>[page:CubeTexture THREE.CubeTexture]</tr>
-				</tr>
-
-			</tbody>
-		</table>
-		</p>
-		<p>
-		(*) Same for an (innermost) array (dimension) of the same GLSL type, containing the components of all vectors or matrices in the array.
 		</p>
 		</p>
 
 
 		<h2>Constructor</h2>
 		<h2>Constructor</h2>

+ 1 - 18
docs/api/objects/Mesh.html

@@ -43,7 +43,7 @@
 		<h3>[property:Material material]</h3>
 		<h3>[property:Material material]</h3>
 
 
 		<div>An instance of [page:Material], defining the object's appearance. Default is a [page:MeshBasicMaterial] with wireframe mode enabled and randomised colour.</div>
 		<div>An instance of [page:Material], defining the object's appearance. Default is a [page:MeshBasicMaterial] with wireframe mode enabled and randomised colour.</div>
-		
+
 		<h3>[property:Array morphTargetInfluences]</h3>
 		<h3>[property:Array morphTargetInfluences]</h3>
 
 
 		<div>
 		<div>
@@ -58,29 +58,12 @@
 		Undefined by default, but rebuilt [page:Mesh.updateMorphTargets updateMorphTargets].
 		Undefined by default, but rebuilt [page:Mesh.updateMorphTargets updateMorphTargets].
 		</div>
 		</div>
 
 
-		<h3>[property:Integer morphTargetBase]</h3>
-
-		<div>
-		Specify the index of the morph that should be used as the base morph. Replaces the positions.
-		Undefined by default, but reset to -1 (non set) by [page:Mesh.updateMorphTargets updateMorphTargets].
-		</div>
-
 
 
 		<h2>Methods</h2>
 		<h2>Methods</h2>
 
 
-		<h3>[method:Integer getMorphTargetIndexByName]( [page:String name] )</h3>
-		<div>
-		name — a morph target name<br />
-		</div>
-		<div>
-		Returns the index of a morph target defined by name.
-		</div>
-
-
 		<h3>[method:null updateMorphTargets]()</h3>
 		<h3>[method:null updateMorphTargets]()</h3>
 		<div>
 		<div>
 		Updates the morphtargets to have no influence on the object. Resets the
 		Updates the morphtargets to have no influence on the object. Resets the
-		[page:Mesh.morphTargetForcedOrder morphTargetForcedOrder],
 		[page:Mesh.morphTargetInfluences morphTargetInfluences],
 		[page:Mesh.morphTargetInfluences morphTargetInfluences],
 		[page:Mesh.morphTargetDictionary morphTargetDictionary], and
 		[page:Mesh.morphTargetDictionary morphTargetDictionary], and
 		[page:Mesh.morphTargetBase morphTargetBase] properties.
 		[page:Mesh.morphTargetBase morphTargetBase] properties.

+ 36 - 37
docs/list.js

@@ -31,7 +31,41 @@ var list = {
 			[ "Face3", "api/core/Face3" ],
 			[ "Face3", "api/core/Face3" ],
 			[ "Geometry", "api/core/Geometry" ],
 			[ "Geometry", "api/core/Geometry" ],
 			[ "Object3D", "api/core/Object3D" ],
 			[ "Object3D", "api/core/Object3D" ],
-			[ "Raycaster", "api/core/Raycaster" ]
+			[ "Raycaster", "api/core/Raycaster" ],
+			[ "Uniform", "api/core/Uniform"]
+		],
+
+		"Geometries": [
+			[ "BoxBufferGeometry", "api/geometries/BoxBufferGeometry" ],
+			[ "BoxGeometry", "api/geometries/BoxGeometry" ],
+			[ "CircleBufferGeometry", "api/geometries/CircleBufferGeometry" ],
+			[ "CircleGeometry", "api/geometries/CircleGeometry" ],
+			[ "ConeBufferGeometry", "api/geometries/ConeBufferGeometry" ],
+			[ "ConeGeometry", "api/geometries/ConeGeometry" ],
+			[ "CylinderBufferGeometry", "api/geometries/CylinderBufferGeometry" ],
+			[ "CylinderGeometry", "api/geometries/CylinderGeometry" ],
+			[ "DodecahedronGeometry", "api/geometries/DodecahedronGeometry" ],
+			[ "ExtrudeGeometry", "api/geometries/ExtrudeGeometry" ],
+			[ "IcosahedronGeometry", "api/geometries/IcosahedronGeometry" ],
+			[ "LatheBufferGeometry", "api/geometries/LatheBufferGeometry" ],
+			[ "LatheGeometry", "api/geometries/LatheGeometry" ],
+			[ "OctahedronGeometry", "api/geometries/OctahedronGeometry" ],
+			[ "ParametricGeometry", "api/geometries/ParametricGeometry" ],
+			[ "PlaneBufferGeometry", "api/geometries/PlaneBufferGeometry" ],
+			[ "PlaneGeometry", "api/geometries/PlaneGeometry" ],
+			[ "PolyhedronGeometry", "api/geometries/PolyhedronGeometry" ],
+			[ "RingBufferGeometry", "api/geometries/RingBufferGeometry" ],
+			[ "RingGeometry", "api/geometries/RingGeometry" ],
+			[ "ShapeGeometry", "api/geometries/ShapeGeometry" ],
+			[ "SphereBufferGeometry", "api/geometries/SphereBufferGeometry" ],
+			[ "SphereGeometry", "api/geometries/SphereGeometry" ],
+			[ "TetrahedronGeometry", "api/geometries/TetrahedronGeometry" ],
+			[ "TextGeometry", "api/geometries/TextGeometry" ],
+			[ "TorusBufferGeometry", "api/geometries/TorusBufferGeometry" ],
+			[ "TorusGeometry", "api/geometries/TorusGeometry" ],
+			[ "TorusKnotBufferGeometry", "api/geometries/TorusKnotBufferGeometry" ],
+			[ "TorusKnotGeometry", "api/geometries/TorusKnotGeometry" ],
+			[ "TubeGeometry", "api/geometries/TubeGeometry" ]
 		],
 		],
 
 
 		"Lights": [
 		"Lights": [
@@ -190,39 +224,6 @@ var list = {
 			[ "SplineCurve3", "api/extras/curves/SplineCurve3" ]
 			[ "SplineCurve3", "api/extras/curves/SplineCurve3" ]
 		],
 		],
 
 
-		"Extras / Geometries": [
-			[ "BoxBufferGeometry", "api/extras/geometries/BoxBufferGeometry" ],
-			[ "BoxGeometry", "api/extras/geometries/BoxGeometry" ],
-			[ "CircleBufferGeometry", "api/extras/geometries/CircleBufferGeometry" ],
-			[ "CircleGeometry", "api/extras/geometries/CircleGeometry" ],
-			[ "ConeBufferGeometry", "api/extras/geometries/ConeBufferGeometry" ],
-			[ "ConeGeometry", "api/extras/geometries/ConeGeometry" ],
-			[ "CylinderBufferGeometry", "api/extras/geometries/CylinderBufferGeometry" ],
-			[ "CylinderGeometry", "api/extras/geometries/CylinderGeometry" ],
-			[ "DodecahedronGeometry", "api/extras/geometries/DodecahedronGeometry" ],
-			[ "ExtrudeGeometry", "api/extras/geometries/ExtrudeGeometry" ],
-			[ "IcosahedronGeometry", "api/extras/geometries/IcosahedronGeometry" ],
-			[ "LatheBufferGeometry", "api/extras/geometries/LatheBufferGeometry" ],
-			[ "LatheGeometry", "api/extras/geometries/LatheGeometry" ],
-			[ "OctahedronGeometry", "api/extras/geometries/OctahedronGeometry" ],
-			[ "ParametricGeometry", "api/extras/geometries/ParametricGeometry" ],
-			[ "PlaneBufferGeometry", "api/extras/geometries/PlaneBufferGeometry" ],
-			[ "PlaneGeometry", "api/extras/geometries/PlaneGeometry" ],
-			[ "PolyhedronGeometry", "api/extras/geometries/PolyhedronGeometry" ],
-			[ "RingBufferGeometry", "api/extras/geometries/RingBufferGeometry" ],
-			[ "RingGeometry", "api/extras/geometries/RingGeometry" ],
-			[ "ShapeGeometry", "api/extras/geometries/ShapeGeometry" ],
-			[ "SphereBufferGeometry", "api/extras/geometries/SphereBufferGeometry" ],
-			[ "SphereGeometry", "api/extras/geometries/SphereGeometry" ],
-			[ "TetrahedronGeometry", "api/extras/geometries/TetrahedronGeometry" ],
-			[ "TextGeometry", "api/extras/geometries/TextGeometry" ],
-			[ "TorusBufferGeometry", "api/extras/geometries/TorusBufferGeometry" ],
-			[ "TorusGeometry", "api/extras/geometries/TorusGeometry" ],
-			[ "TorusKnotBufferGeometry", "api/extras/geometries/TorusKnotBufferGeometry" ],
-			[ "TorusKnotGeometry", "api/extras/geometries/TorusKnotGeometry" ],
-			[ "TubeGeometry", "api/extras/geometries/TubeGeometry" ]
-		],
-
 		"Extras / Helpers": [
 		"Extras / Helpers": [
 			[ "ArrowHelper", "api/extras/helpers/ArrowHelper" ],
 			[ "ArrowHelper", "api/extras/helpers/ArrowHelper" ],
 			[ "AxisHelper", "api/extras/helpers/AxisHelper" ],
 			[ "AxisHelper", "api/extras/helpers/AxisHelper" ],
@@ -230,14 +231,12 @@ var list = {
 			[ "BoxHelper", "api/extras/helpers/BoxHelper" ],
 			[ "BoxHelper", "api/extras/helpers/BoxHelper" ],
 			[ "CameraHelper", "api/extras/helpers/CameraHelper" ],
 			[ "CameraHelper", "api/extras/helpers/CameraHelper" ],
 			[ "DirectionalLightHelper", "api/extras/helpers/DirectionalLightHelper" ],
 			[ "DirectionalLightHelper", "api/extras/helpers/DirectionalLightHelper" ],
-			[ "EdgesHelper", "api/extras/helpers/EdgesHelper" ],
 			[ "FaceNormalsHelper", "api/extras/helpers/FaceNormalsHelper" ],
 			[ "FaceNormalsHelper", "api/extras/helpers/FaceNormalsHelper" ],
 			[ "GridHelper", "api/extras/helpers/GridHelper" ],
 			[ "GridHelper", "api/extras/helpers/GridHelper" ],
 			[ "HemisphereLightHelper", "api/extras/helpers/HemisphereLightHelper" ],
 			[ "HemisphereLightHelper", "api/extras/helpers/HemisphereLightHelper" ],
 			[ "PointLightHelper", "api/extras/helpers/PointLightHelper" ],
 			[ "PointLightHelper", "api/extras/helpers/PointLightHelper" ],
 			[ "SpotLightHelper", "api/extras/helpers/SpotLightHelper" ],
 			[ "SpotLightHelper", "api/extras/helpers/SpotLightHelper" ],
-			[ "VertexNormalsHelper", "api/extras/helpers/VertexNormalsHelper" ],
-			[ "WireframeHelper", "api/extras/helpers/WireframeHelper" ]
+			[ "VertexNormalsHelper", "api/extras/helpers/VertexNormalsHelper" ]
 		],
 		],
 
 
 		"Extras / Objects": [
 		"Extras / Objects": [

+ 1 - 1
docs/scenes/bones-browser.html

@@ -59,7 +59,7 @@
 				renderer = new THREE.WebGLRenderer( { antialias: true } );
 				renderer = new THREE.WebGLRenderer( { antialias: true } );
 				renderer.setPixelRatio( window.devicePixelRatio );
 				renderer.setPixelRatio( window.devicePixelRatio );
 				renderer.setSize( window.innerWidth, window.innerHeight );
 				renderer.setSize( window.innerWidth, window.innerHeight );
-				renderer.setClearColor( 0x000000 );
+				renderer.setClearColor( 0x000000, 1 );
 				document.body.appendChild( renderer.domElement );
 				document.body.appendChild( renderer.domElement );
 
 
 				orbit = new THREE.OrbitControls( camera, renderer.domElement );
 				orbit = new THREE.OrbitControls( camera, renderer.domElement );

+ 1 - 1
docs/scenes/geometry-browser.html

@@ -52,7 +52,7 @@
 			var renderer = new THREE.WebGLRenderer( { antialias: true } );
 			var renderer = new THREE.WebGLRenderer( { antialias: true } );
 			renderer.setPixelRatio( window.devicePixelRatio );
 			renderer.setPixelRatio( window.devicePixelRatio );
 			renderer.setSize( window.innerWidth, window.innerHeight );
 			renderer.setSize( window.innerWidth, window.innerHeight );
-			renderer.setClearColor( 0x000000 );
+			renderer.setClearColor( 0x000000, 1 );
 			document.body.appendChild( renderer.domElement );
 			document.body.appendChild( renderer.domElement );
 
 
 			var orbit = new THREE.OrbitControls( camera, renderer.domElement );
 			var orbit = new THREE.OrbitControls( camera, renderer.domElement );

+ 1 - 1
docs/scenes/material-browser.html

@@ -50,7 +50,7 @@
 			var renderer = new THREE.WebGLRenderer( { antialias: true } );
 			var renderer = new THREE.WebGLRenderer( { antialias: true } );
 			renderer.setPixelRatio( window.devicePixelRatio );
 			renderer.setPixelRatio( window.devicePixelRatio );
 			renderer.setSize( window.innerWidth, window.innerHeight );
 			renderer.setSize( window.innerWidth, window.innerHeight );
-			renderer.setClearColor( 0x000000 );
+			renderer.setClearColor( 0x000000, 1 );
 			document.body.appendChild( renderer.domElement );
 			document.body.appendChild( renderer.domElement );
 
 
 			var ambientLight = new THREE.AmbientLight( 0x000000 );
 			var ambientLight = new THREE.AmbientLight( 0x000000 );

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

@@ -29,7 +29,7 @@ Menubar.View = function ( editor ) {
 
 
 		} else {
 		} else {
 
 
-			alert( 'WebVR nor available' );
+			alert( 'WebVR not available' );
 
 
 		}
 		}
 
 

+ 20 - 20
editor/js/libs/tern-threejs/threejs.js

@@ -1539,7 +1539,7 @@
       "!type": "fn(points: [])"
       "!type": "fn(points: [])"
     },
     },
     "BoxGeometry": {
     "BoxGeometry": {
-      "!url": "http://threejs.org/docs/#Reference/extras/geometries/BoxGeometry",
+      "!url": "http://threejs.org/docs/#Reference/geometries/BoxGeometry",
       "prototype": {
       "prototype": {
         "!proto": "THREE.Geometry.prototype"
         "!proto": "THREE.Geometry.prototype"
       },
       },
@@ -1547,7 +1547,7 @@
       "!type": "fn(width: number, height: number, depth: number, widthSegments: number, heightSegments: number, depthSegments: number)"
       "!type": "fn(width: number, height: number, depth: number, widthSegments: number, heightSegments: number, depthSegments: number)"
     },
     },
     "CircleGeometry": {
     "CircleGeometry": {
-      "!url": "http://threejs.org/docs/#Reference/extras/geometries/CircleGeometry",
+      "!url": "http://threejs.org/docs/#Reference/geometries/CircleGeometry",
       "prototype": {
       "prototype": {
         "!proto": "THREE.Geometry.prototype"
         "!proto": "THREE.Geometry.prototype"
       },
       },
@@ -1555,14 +1555,14 @@
       "!type": "fn(radius: number, segments: number, thetaStart: number, thetaLength: number)"
       "!type": "fn(radius: number, segments: number, thetaStart: number, thetaLength: number)"
     },
     },
     "CubeGeometry": {
     "CubeGeometry": {
-      "!url": "http://threejs.org/docs/#Reference/extras/geometries/CubeGeometry",
+      "!url": "http://threejs.org/docs/#Reference/geometries/CubeGeometry",
       "prototype": {
       "prototype": {
         "!proto": "THREE.Geometry.prototype"
         "!proto": "THREE.Geometry.prototype"
       },
       },
       "!doc": "Renamed CubeGeometry to BoxGeometry. see [page:BoxGeometry]."
       "!doc": "Renamed CubeGeometry to BoxGeometry. see [page:BoxGeometry]."
     },
     },
     "CylinderGeometry": {
     "CylinderGeometry": {
-      "!url": "http://threejs.org/docs/#Reference/extras/geometries/CylinderGeometry",
+      "!url": "http://threejs.org/docs/#Reference/geometries/CylinderGeometry",
       "prototype": {
       "prototype": {
         "!proto": "THREE.Geometry.prototype"
         "!proto": "THREE.Geometry.prototype"
       },
       },
@@ -1570,7 +1570,7 @@
       "!type": "fn(radiusTop: number, radiusBottom: number, height: number, radiusSegments: number, heightSegments: number, openEnded: bool, thetaStart: number, thetaLength: number)"
       "!type": "fn(radiusTop: number, radiusBottom: number, height: number, radiusSegments: number, heightSegments: number, openEnded: bool, thetaStart: number, thetaLength: number)"
     },
     },
     "DodecahedronGeometry": {
     "DodecahedronGeometry": {
-      "!url": "http://threejs.org/docs/#Reference/extras/geometries/DodecahedronGeometry",
+      "!url": "http://threejs.org/docs/#Reference/geometries/DodecahedronGeometry",
       "prototype": {
       "prototype": {
         "!proto": "THREE.PolyhedronGeometry.prototype",
         "!proto": "THREE.PolyhedronGeometry.prototype",
         "parameters": {
         "parameters": {
@@ -1582,7 +1582,7 @@
       "!type": "fn(radius: number, detail: number)"
       "!type": "fn(radius: number, detail: number)"
     },
     },
     "ExtrudeGeometry": {
     "ExtrudeGeometry": {
-      "!url": "http://threejs.org/docs/#Reference/extras/geometries/ExtrudeGeometry",
+      "!url": "http://threejs.org/docs/#Reference/geometries/ExtrudeGeometry",
       "prototype": {
       "prototype": {
         "!proto": "THREE.Geometry.prototype",
         "!proto": "THREE.Geometry.prototype",
         "addShapeList": {
         "addShapeList": {
@@ -1598,7 +1598,7 @@
       "!type": "fn(shapes: [], options: object)"
       "!type": "fn(shapes: [], options: object)"
     },
     },
     "IcosahedronGeometry": {
     "IcosahedronGeometry": {
-      "!url": "http://threejs.org/docs/#Reference/extras/geometries/IcosahedronGeometry",
+      "!url": "http://threejs.org/docs/#Reference/geometries/IcosahedronGeometry",
       "prototype": {
       "prototype": {
         "!proto": "THREE.PolyhedronGeometry.prototype",
         "!proto": "THREE.PolyhedronGeometry.prototype",
         "parameters": {
         "parameters": {
@@ -1610,7 +1610,7 @@
       "!type": "fn(radius: number, detail: number)"
       "!type": "fn(radius: number, detail: number)"
     },
     },
     "LatheGeometry": {
     "LatheGeometry": {
-      "!url": "http://threejs.org/docs/#Reference/extras/geometries/LatheGeometry",
+      "!url": "http://threejs.org/docs/#Reference/geometries/LatheGeometry",
       "prototype": {
       "prototype": {
         "!proto": "THREE.Geometry.prototype"
         "!proto": "THREE.Geometry.prototype"
       },
       },
@@ -1618,7 +1618,7 @@
       "!type": "fn(points: [], segments: number, phiStart: number, phiLength: number)"
       "!type": "fn(points: [], segments: number, phiStart: number, phiLength: number)"
     },
     },
     "OctahedronGeometry": {
     "OctahedronGeometry": {
-      "!url": "http://threejs.org/docs/#Reference/extras/geometries/OctahedronGeometry",
+      "!url": "http://threejs.org/docs/#Reference/geometries/OctahedronGeometry",
       "prototype": {
       "prototype": {
         "!proto": "THREE.PolyhedronGeometry.prototype",
         "!proto": "THREE.PolyhedronGeometry.prototype",
         "parameters": {
         "parameters": {
@@ -1630,7 +1630,7 @@
       "!type": "fn(radius: number, detail: number)"
       "!type": "fn(radius: number, detail: number)"
     },
     },
     "ParametricGeometry": {
     "ParametricGeometry": {
-      "!url": "http://threejs.org/docs/#Reference/extras/geometries/ParametricGeometry",
+      "!url": "http://threejs.org/docs/#Reference/geometries/ParametricGeometry",
       "prototype": {
       "prototype": {
         "!proto": "THREE.Geometry.prototype"
         "!proto": "THREE.Geometry.prototype"
       },
       },
@@ -1638,7 +1638,7 @@
       "!type": "fn(func: function, slices: number, stacks: number)"
       "!type": "fn(func: function, slices: number, stacks: number)"
     },
     },
     "PlaneGeometry": {
     "PlaneGeometry": {
-      "!url": "http://threejs.org/docs/#Reference/extras/geometries/PlaneGeometry",
+      "!url": "http://threejs.org/docs/#Reference/geometries/PlaneGeometry",
       "prototype": {
       "prototype": {
         "!proto": "THREE.Geometry.prototype"
         "!proto": "THREE.Geometry.prototype"
       },
       },
@@ -1646,7 +1646,7 @@
       "!type": "fn(width: number, height: number, widthSegments: number, heightSegments: number)"
       "!type": "fn(width: number, height: number, widthSegments: number, heightSegments: number)"
     },
     },
     "PolyhedronGeometry": {
     "PolyhedronGeometry": {
-      "!url": "http://threejs.org/docs/#Reference/extras/geometries/PolyhedronGeometry",
+      "!url": "http://threejs.org/docs/#Reference/geometries/PolyhedronGeometry",
       "prototype": {
       "prototype": {
         "!proto": "THREE.Geometry.prototype",
         "!proto": "THREE.Geometry.prototype",
         "parameters": {
         "parameters": {
@@ -1658,7 +1658,7 @@
       "!type": "fn(vertices: [], faces: [], radius: number, detail: number)"
       "!type": "fn(vertices: [], faces: [], radius: number, detail: number)"
     },
     },
     "RingGeometry": {
     "RingGeometry": {
-      "!url": "http://threejs.org/docs/#Reference/extras/geometries/RingGeometry",
+      "!url": "http://threejs.org/docs/#Reference/geometries/RingGeometry",
       "prototype": {
       "prototype": {
         "!proto": "THREE.Geometry.prototype"
         "!proto": "THREE.Geometry.prototype"
       },
       },
@@ -1666,7 +1666,7 @@
       "!type": "fn(innerRadius: number, outerRadius: number, thetaSegments: number, phiSegments: number, thetaStart: number, thetaLength: number)"
       "!type": "fn(innerRadius: number, outerRadius: number, thetaSegments: number, phiSegments: number, thetaStart: number, thetaLength: number)"
     },
     },
     "ShapeGeometry": {
     "ShapeGeometry": {
-      "!url": "http://threejs.org/docs/#Reference/extras/geometries/ShapeGeometry",
+      "!url": "http://threejs.org/docs/#Reference/geometries/ShapeGeometry",
       "prototype": {
       "prototype": {
         "!proto": "THREE.Geometry.prototype",
         "!proto": "THREE.Geometry.prototype",
         "addShape": {
         "addShape": {
@@ -1678,7 +1678,7 @@
       "!type": "fn(shapes: [], options: object)"
       "!type": "fn(shapes: [], options: object)"
     },
     },
     "SphereGeometry": {
     "SphereGeometry": {
-      "!url": "http://threejs.org/docs/#Reference/extras/geometries/SphereGeometry",
+      "!url": "http://threejs.org/docs/#Reference/geometries/SphereGeometry",
       "prototype": {
       "prototype": {
         "!proto": "THREE.Geometry.prototype"
         "!proto": "THREE.Geometry.prototype"
       },
       },
@@ -1686,7 +1686,7 @@
       "!type": "fn(radius: number, widthSegments: number, heightSegments: number, phiStart: number, phiLength: number, thetaStart: number, thetaLength: number)"
       "!type": "fn(radius: number, widthSegments: number, heightSegments: number, phiStart: number, phiLength: number, thetaStart: number, thetaLength: number)"
     },
     },
     "TetrahedronGeometry": {
     "TetrahedronGeometry": {
-      "!url": "http://threejs.org/docs/#Reference/extras/geometries/TetrahedronGeometry",
+      "!url": "http://threejs.org/docs/#Reference/geometries/TetrahedronGeometry",
       "prototype": {
       "prototype": {
         "!proto": "THREE.PolyhedronGeometry.prototype",
         "!proto": "THREE.PolyhedronGeometry.prototype",
         "parameters": {
         "parameters": {
@@ -1698,7 +1698,7 @@
       "!type": "fn(radius: number, detail: number)"
       "!type": "fn(radius: number, detail: number)"
     },
     },
     "TextGeometry": {
     "TextGeometry": {
-      "!url": "http://threejs.org/docs/#Reference/extras/geometries/TextGeometry",
+      "!url": "http://threejs.org/docs/#Reference/geometries/TextGeometry",
       "prototype": {
       "prototype": {
         "!proto": "THREE.ExtrudeGeometry.prototype"
         "!proto": "THREE.ExtrudeGeometry.prototype"
       },
       },
@@ -1706,7 +1706,7 @@
       "!type": "fn(text: string, parameters: object)"
       "!type": "fn(text: string, parameters: object)"
     },
     },
     "TorusGeometry": {
     "TorusGeometry": {
-      "!url": "http://threejs.org/docs/#Reference/extras/geometries/TorusGeometry",
+      "!url": "http://threejs.org/docs/#Reference/geometries/TorusGeometry",
       "prototype": {
       "prototype": {
         "!proto": "THREE.Geometry.prototype"
         "!proto": "THREE.Geometry.prototype"
       },
       },
@@ -1714,7 +1714,7 @@
       "!type": "fn(radius: number, tube: number, radialSegments: number, tubularSegments: number, arc: number)"
       "!type": "fn(radius: number, tube: number, radialSegments: number, tubularSegments: number, arc: number)"
     },
     },
     "TorusKnotGeometry": {
     "TorusKnotGeometry": {
-      "!url": "http://threejs.org/docs/#Reference/extras/geometries/TorusKnotGeometry",
+      "!url": "http://threejs.org/docs/#Reference/geometries/TorusKnotGeometry",
       "prototype": {
       "prototype": {
         "!proto": "THREE.Geometry.prototype"
         "!proto": "THREE.Geometry.prototype"
       },
       },
@@ -1722,7 +1722,7 @@
       "!type": "fn(radius: number, tube: number, radialSegments: number, tubularSegments: number, p: number, q: number, heightScale: number)"
       "!type": "fn(radius: number, tube: number, radialSegments: number, tubularSegments: number, p: number, q: number, heightScale: number)"
     },
     },
     "TubeGeometry": {
     "TubeGeometry": {
-      "!url": "http://threejs.org/docs/#Reference/extras/geometries/TubeGeometry",
+      "!url": "http://threejs.org/docs/#Reference/geometries/TubeGeometry",
       "prototype": {
       "prototype": {
         "!proto": "THREE.Geometry.prototype",
         "!proto": "THREE.Geometry.prototype",
         "parameters": {
         "parameters": {

+ 4 - 1
examples/files.js

@@ -264,7 +264,10 @@ var files = {
 		"webvr_rollercoaster",
 		"webvr_rollercoaster",
 		"webvr_shadow",
 		"webvr_shadow",
 		"webvr_video",
 		"webvr_video",
-		"webvr_vive"
+		"webvr_vive",
+		"webvr_vive_dragging",
+		"webvr_vive_paint",
+		"webvr_vive_sculpt"
 	],
 	],
 	"css3d": [
 	"css3d": [
 		"css3d_molecules",
 		"css3d_molecules",

+ 1 - 1
examples/js/GPUComputationRenderer.js

@@ -297,7 +297,7 @@ function GPUComputationRenderer( sizeX, sizeY, renderer ) {
 			minFilter: minFilter,
 			minFilter: minFilter,
 			magFilter: magFilter,
 			magFilter: magFilter,
 			format: THREE.RGBAFormat,
 			format: THREE.RGBAFormat,
-			type: THREE.FloatType,
+			type: ( /(iPad|iPhone|iPod)/g.test( navigator.userAgent ) ) ? THREE.HalfFloatType : THREE.FloatType,
 			stencilBuffer: false
 			stencilBuffer: false
 		} );
 		} );
 
 

+ 170 - 183
examples/js/MarchingCubes.js

@@ -1,14 +1,20 @@
 /**
 /**
  * @author alteredq / http://alteredqualia.com/
  * @author alteredq / http://alteredqualia.com/
- *
- * Port of greggman's ThreeD version of marching cubes to Three.js
- * http://webglsamples.googlecode.com/hg/blob/blob.html
+ * @author mrdoob / http://mrdoob.com
+ * Port of http://webglsamples.org/blob/blob.html
  */
  */
 
 
 THREE.MarchingCubes = function ( resolution, material, enableUvs, enableColors ) {
 THREE.MarchingCubes = function ( resolution, material, enableUvs, enableColors ) {
 
 
 	THREE.ImmediateRenderObject.call( this, material );
 	THREE.ImmediateRenderObject.call( this, material );
 
 
+	var scope = this;
+
+	// temp buffers used in polygonize
+
+	var vlist = new Float32Array( 12 * 3 );
+	var nlist = new Float32Array( 12 * 3 );
+
 	this.enableUvs = enableUvs !== undefined ? enableUvs : false;
 	this.enableUvs = enableUvs !== undefined ? enableUvs : false;
 	this.enableColors = enableColors !== undefined ? enableColors : false;
 	this.enableColors = enableColors !== undefined ? enableColors : false;
 
 
@@ -40,11 +46,6 @@ THREE.MarchingCubes = function ( resolution, material, enableUvs, enableColors )
 		this.field = new Float32Array( this.size3 );
 		this.field = new Float32Array( this.size3 );
 		this.normal_cache = new Float32Array( this.size3 * 3 );
 		this.normal_cache = new Float32Array( this.size3 * 3 );
 
 
-		// temp buffers used in polygonize
-
-		this.vlist = new Float32Array( 12 * 3 );
-		this.nlist = new Float32Array( 12 * 3 );
-
 		// immediate render mode simulator
 		// immediate render mode simulator
 
 
 		this.maxCount = 4096; // TODO: find the fastest size for this buffer
 		this.maxCount = 4096; // TODO: find the fastest size for this buffer
@@ -76,98 +77,98 @@ THREE.MarchingCubes = function ( resolution, material, enableUvs, enableColors )
 	// Polygonization
 	// Polygonization
 	///////////////////////
 	///////////////////////
 
 
-	this.lerp = function( a, b, t ) {
+	function lerp( a, b, t ) {
 
 
 		return a + ( b - a ) * t;
 		return a + ( b - a ) * t;
 
 
-	};
+	}
 
 
-	this.VIntX = function( q, pout, nout, offset, isol, x, y, z, valp1, valp2 ) {
+	function VIntX( q, offset, isol, x, y, z, valp1, valp2 ) {
 
 
 		var mu = ( isol - valp1 ) / ( valp2 - valp1 ),
 		var mu = ( isol - valp1 ) / ( valp2 - valp1 ),
-		nc = this.normal_cache;
+		nc = scope.normal_cache;
 
 
-		pout[ offset ] 	   = x + mu * this.delta;
-		pout[ offset + 1 ] = y;
-		pout[ offset + 2 ] = z;
+		vlist[ offset + 0 ] = x + mu * scope.delta;
+		vlist[ offset + 1 ] = y;
+		vlist[ offset + 2 ] = z;
 
 
-		nout[ offset ] 	   = this.lerp( nc[ q ],     nc[ q + 3 ], mu );
-		nout[ offset + 1 ] = this.lerp( nc[ q + 1 ], nc[ q + 4 ], mu );
-		nout[ offset + 2 ] = this.lerp( nc[ q + 2 ], nc[ q + 5 ], mu );
+		nlist[ offset + 0 ] = lerp( nc[ q + 0 ], nc[ q + 3 ], mu );
+		nlist[ offset + 1 ] = lerp( nc[ q + 1 ], nc[ q + 4 ], mu );
+		nlist[ offset + 2 ] = lerp( nc[ q + 2 ], nc[ q + 5 ], mu );
 
 
-	};
+	}
 
 
-	this.VIntY = function( q, pout, nout, offset, isol, x, y, z, valp1, valp2 ) {
+	function VIntY( q, offset, isol, x, y, z, valp1, valp2 ) {
 
 
 		var mu = ( isol - valp1 ) / ( valp2 - valp1 ),
 		var mu = ( isol - valp1 ) / ( valp2 - valp1 ),
-		nc = this.normal_cache;
+		nc = scope.normal_cache;
 
 
-		pout[ offset ] 	   = x;
-		pout[ offset + 1 ] = y + mu * this.delta;
-		pout[ offset + 2 ] = z;
+		vlist[ offset + 0 ] = x;
+		vlist[ offset + 1 ] = y + mu * scope.delta;
+		vlist[ offset + 2 ] = z;
 
 
-		var q2 = q + this.yd * 3;
+		var q2 = q + scope.yd * 3;
 
 
-		nout[ offset ] 	   = this.lerp( nc[ q ],     nc[ q2 ],     mu );
-		nout[ offset + 1 ] = this.lerp( nc[ q + 1 ], nc[ q2 + 1 ], mu );
-		nout[ offset + 2 ] = this.lerp( nc[ q + 2 ], nc[ q2 + 2 ], mu );
+		nlist[ offset + 0 ] = lerp( nc[ q + 0 ], nc[ q2 + 0 ], mu );
+		nlist[ offset + 1 ] = lerp( nc[ q + 1 ], nc[ q2 + 1 ], mu );
+		nlist[ offset + 2 ] = lerp( nc[ q + 2 ], nc[ q2 + 2 ], mu );
 
 
-	};
+	}
 
 
-	this.VIntZ = function( q, pout, nout, offset, isol, x, y, z, valp1, valp2 ) {
+	function VIntZ( q, offset, isol, x, y, z, valp1, valp2 ) {
 
 
 		var mu = ( isol - valp1 ) / ( valp2 - valp1 ),
 		var mu = ( isol - valp1 ) / ( valp2 - valp1 ),
-		nc = this.normal_cache;
+		nc = scope.normal_cache;
 
 
-		pout[ offset ] 	   = x;
-		pout[ offset + 1 ] = y;
-		pout[ offset + 2 ] = z + mu * this.delta;
+		vlist[ offset + 0 ] = x;
+		vlist[ offset + 1 ] = y;
+		vlist[ offset + 2 ] = z + mu * scope.delta;
 
 
-		var q2 = q + this.zd * 3;
+		var q2 = q + scope.zd * 3;
 
 
-		nout[ offset ] 	   = this.lerp( nc[ q ],     nc[ q2 ],     mu );
-		nout[ offset + 1 ] = this.lerp( nc[ q + 1 ], nc[ q2 + 1 ], mu );
-		nout[ offset + 2 ] = this.lerp( nc[ q + 2 ], nc[ q2 + 2 ], mu );
+		nlist[ offset + 0 ] = lerp( nc[ q + 0 ], nc[ q2 + 0 ], mu );
+		nlist[ offset + 1 ] = lerp( nc[ q + 1 ], nc[ q2 + 1 ], mu );
+		nlist[ offset + 2 ] = lerp( nc[ q + 2 ], nc[ q2 + 2 ], mu );
 
 
-	};
+	}
 
 
-	this.compNorm = function( q ) {
+	function compNorm( q ) {
 
 
 		var q3 = q * 3;
 		var q3 = q * 3;
 
 
-		if ( this.normal_cache[ q3 ] === 0.0 ) {
+		if ( scope.normal_cache[ q3 ] === 0.0 ) {
 
 
-			this.normal_cache[ q3 ] = this.field[ q - 1 ] 	    - this.field[ q + 1 ];
-			this.normal_cache[ q3 + 1 ] = this.field[ q - this.yd ] - this.field[ q + this.yd ];
-			this.normal_cache[ q3 + 2 ] = this.field[ q - this.zd ] - this.field[ q + this.zd ];
+			scope.normal_cache[ q3 + 0 ] = scope.field[ q - 1 ] 	    - scope.field[ q + 1 ];
+			scope.normal_cache[ q3 + 1 ] = scope.field[ q - scope.yd ] - scope.field[ q + scope.yd ];
+			scope.normal_cache[ q3 + 2 ] = scope.field[ q - scope.zd ] - scope.field[ q + scope.zd ];
 
 
 		}
 		}
 
 
-	};
+	}
 
 
 	// Returns total number of triangles. Fills triangles.
 	// Returns total number of triangles. Fills triangles.
 	// (this is where most of time is spent - it's inner work of O(n3) loop )
 	// (this is where most of time is spent - it's inner work of O(n3) loop )
 
 
-	this.polygonize = function( fx, fy, fz, q, isol, renderCallback ) {
+	function polygonize( fx, fy, fz, q, isol, renderCallback ) {
 
 
 		// cache indices
 		// cache indices
 		var q1 = q + 1,
 		var q1 = q + 1,
-			qy = q + this.yd,
-			qz = q + this.zd,
-			q1y = q1 + this.yd,
-			q1z = q1 + this.zd,
-			qyz = q + this.yd + this.zd,
-			q1yz = q1 + this.yd + this.zd;
+			qy = q + scope.yd,
+			qz = q + scope.zd,
+			q1y = q1 + scope.yd,
+			q1z = q1 + scope.zd,
+			qyz = q + scope.yd + scope.zd,
+			q1yz = q1 + scope.yd + scope.zd;
 
 
 		var cubeindex = 0,
 		var cubeindex = 0,
-			field0 = this.field[ q ],
-			field1 = this.field[ q1 ],
-			field2 = this.field[ qy ],
-			field3 = this.field[ q1y ],
-			field4 = this.field[ qz ],
-			field5 = this.field[ q1z ],
-			field6 = this.field[ qyz ],
-			field7 = this.field[ q1yz ];
+			field0 = scope.field[ q ],
+			field1 = scope.field[ q1 ],
+			field2 = scope.field[ qy ],
+			field3 = scope.field[ q1y ],
+			field4 = scope.field[ qz ],
+			field5 = scope.field[ q1z ],
+			field6 = scope.field[ qyz ],
+			field7 = scope.field[ q1yz ];
 
 
 		if ( field0 < isol ) cubeindex |= 1;
 		if ( field0 < isol ) cubeindex |= 1;
 		if ( field1 < isol ) cubeindex |= 2;
 		if ( field1 < isol ) cubeindex |= 2;
@@ -183,7 +184,7 @@ THREE.MarchingCubes = function ( resolution, material, enableUvs, enableColors )
 		var bits = THREE.edgeTable[ cubeindex ];
 		var bits = THREE.edgeTable[ cubeindex ];
 		if ( bits === 0 ) return 0;
 		if ( bits === 0 ) return 0;
 
 
-		var d = this.delta,
+		var d = scope.delta,
 			fx2 = fx + d,
 			fx2 = fx + d,
 			fy2 = fy + d,
 			fy2 = fy + d,
 			fz2 = fz + d;
 			fz2 = fz + d;
@@ -192,33 +193,33 @@ THREE.MarchingCubes = function ( resolution, material, enableUvs, enableColors )
 
 
 		if ( bits & 1 ) {
 		if ( bits & 1 ) {
 
 
-			this.compNorm( q );
-			this.compNorm( q1 );
-			this.VIntX( q * 3, this.vlist, this.nlist, 0, isol, fx, fy, fz, field0, field1 );
+			compNorm( q );
+			compNorm( q1 );
+			VIntX( q * 3, 0, isol, fx, fy, fz, field0, field1 );
 
 
 		}
 		}
 
 
 		if ( bits & 2 ) {
 		if ( bits & 2 ) {
 
 
-			this.compNorm( q1 );
-			this.compNorm( q1y );
-			this.VIntY( q1 * 3, this.vlist, this.nlist, 3, isol, fx2, fy, fz, field1, field3 );
+			compNorm( q1 );
+			compNorm( q1y );
+			VIntY( q1 * 3, 3, isol, fx2, fy, fz, field1, field3 );
 
 
 		}
 		}
 
 
 		if ( bits & 4 ) {
 		if ( bits & 4 ) {
 
 
-			this.compNorm( qy );
-			this.compNorm( q1y );
-			this.VIntX( qy * 3, this.vlist, this.nlist, 6, isol, fx, fy2, fz, field2, field3 );
+			compNorm( qy );
+			compNorm( q1y );
+			VIntX( qy * 3, 6, isol, fx, fy2, fz, field2, field3 );
 
 
 		}
 		}
 
 
 		if ( bits & 8 ) {
 		if ( bits & 8 ) {
 
 
-			this.compNorm( q );
-			this.compNorm( qy );
-			this.VIntY( q * 3, this.vlist, this.nlist, 9, isol, fx, fy, fz, field0, field2 );
+			compNorm( q );
+			compNorm( qy );
+			VIntY( q * 3, 9, isol, fx, fy, fz, field0, field2 );
 
 
 		}
 		}
 
 
@@ -226,33 +227,33 @@ THREE.MarchingCubes = function ( resolution, material, enableUvs, enableColors )
 
 
 		if ( bits & 16 ) {
 		if ( bits & 16 ) {
 
 
-			this.compNorm( qz );
-			this.compNorm( q1z );
-			this.VIntX( qz * 3, this.vlist, this.nlist, 12, isol, fx, fy, fz2, field4, field5 );
+			compNorm( qz );
+			compNorm( q1z );
+			VIntX( qz * 3, 12, isol, fx, fy, fz2, field4, field5 );
 
 
 		}
 		}
 
 
 		if ( bits & 32 ) {
 		if ( bits & 32 ) {
 
 
-			this.compNorm( q1z );
-			this.compNorm( q1yz );
-			this.VIntY( q1z * 3,  this.vlist, this.nlist, 15, isol, fx2, fy, fz2, field5, field7 );
+			compNorm( q1z );
+			compNorm( q1yz );
+			VIntY( q1z * 3, 15, isol, fx2, fy, fz2, field5, field7 );
 
 
 		}
 		}
 
 
 		if ( bits & 64 ) {
 		if ( bits & 64 ) {
 
 
-			this.compNorm( qyz );
-			this.compNorm( q1yz );
-			this.VIntX( qyz * 3, this.vlist, this.nlist, 18, isol, fx, fy2, fz2, field6, field7 );
+			compNorm( qyz );
+			compNorm( q1yz );
+			VIntX( qyz * 3, 18, isol, fx, fy2, fz2, field6, field7 );
 
 
 		}
 		}
 
 
 		if ( bits & 128 ) {
 		if ( bits & 128 ) {
 
 
-			this.compNorm( qz );
-			this.compNorm( qyz );
-			this.VIntY( qz * 3,  this.vlist, this.nlist, 21, isol, fx, fy, fz2, field4, field6 );
+			compNorm( qz );
+			compNorm( qyz );
+			VIntY( qz * 3, 21, isol, fx, fy, fz2, field4, field6 );
 
 
 		}
 		}
 
 
@@ -260,33 +261,33 @@ THREE.MarchingCubes = function ( resolution, material, enableUvs, enableColors )
 
 
 		if ( bits & 256 ) {
 		if ( bits & 256 ) {
 
 
-			this.compNorm( q );
-			this.compNorm( qz );
-			this.VIntZ( q * 3, this.vlist, this.nlist, 24, isol, fx, fy, fz, field0, field4 );
+			compNorm( q );
+			compNorm( qz );
+			VIntZ( q * 3, 24, isol, fx, fy, fz, field0, field4 );
 
 
 		}
 		}
 
 
 		if ( bits & 512 ) {
 		if ( bits & 512 ) {
 
 
-			this.compNorm( q1 );
-			this.compNorm( q1z );
-			this.VIntZ( q1 * 3,  this.vlist, this.nlist, 27, isol, fx2, fy,  fz, field1, field5 );
+			compNorm( q1 );
+			compNorm( q1z );
+			VIntZ( q1 * 3, 27, isol, fx2, fy,  fz, field1, field5 );
 
 
 		}
 		}
 
 
 		if ( bits & 1024 ) {
 		if ( bits & 1024 ) {
 
 
-			this.compNorm( q1y );
-			this.compNorm( q1yz );
-			this.VIntZ( q1y * 3, this.vlist, this.nlist, 30, isol, fx2, fy2, fz, field3, field7 );
+			compNorm( q1y );
+			compNorm( q1yz );
+			VIntZ( q1y * 3, 30, isol, fx2, fy2, fz, field3, field7 );
 
 
 		}
 		}
 
 
 		if ( bits & 2048 ) {
 		if ( bits & 2048 ) {
 
 
-			this.compNorm( qy );
-			this.compNorm( qyz );
-			this.VIntZ( qy * 3, this.vlist, this.nlist, 33, isol, fx,  fy2, fz, field2, field6 );
+			compNorm( qy );
+			compNorm( qyz );
+			VIntZ( qy * 3, 33, isol, fx,  fy2, fz, field2, field6 );
 
 
 		}
 		}
 
 
@@ -302,11 +303,11 @@ THREE.MarchingCubes = function ( resolution, material, enableUvs, enableColors )
 			o2 = o1 + 1;
 			o2 = o1 + 1;
 			o3 = o1 + 2;
 			o3 = o1 + 2;
 
 
-			this.posnormtriv( this.vlist, this.nlist,
-							  3 * THREE.triTable[ o1 ],
-							  3 * THREE.triTable[ o2 ],
-							  3 * THREE.triTable[ o3 ],
-							  renderCallback );
+			posnormtriv( vlist, nlist,
+				3 * THREE.triTable[ o1 ],
+				3 * THREE.triTable[ o2 ],
+				3 * THREE.triTable[ o3 ],
+				renderCallback );
 
 
 			i += 3;
 			i += 3;
 			numtris ++;
 			numtris ++;
@@ -315,105 +316,105 @@ THREE.MarchingCubes = function ( resolution, material, enableUvs, enableColors )
 
 
 		return numtris;
 		return numtris;
 
 
-	};
+	}
 
 
 	/////////////////////////////////////
 	/////////////////////////////////////
 	// Immediate render mode simulator
 	// Immediate render mode simulator
 	/////////////////////////////////////
 	/////////////////////////////////////
 
 
-	this.posnormtriv = function( pos, norm, o1, o2, o3, renderCallback ) {
+	function posnormtriv( pos, norm, o1, o2, o3, renderCallback ) {
 
 
-		var c = this.count * 3;
+		var c = scope.count * 3;
 
 
 		// positions
 		// positions
 
 
-		this.positionArray[ c ] 	= pos[ o1 ];
-		this.positionArray[ c + 1 ] = pos[ o1 + 1 ];
-		this.positionArray[ c + 2 ] = pos[ o1 + 2 ];
+		scope.positionArray[ c + 0 ] = pos[ o1 ];
+		scope.positionArray[ c + 1 ] = pos[ o1 + 1 ];
+		scope.positionArray[ c + 2 ] = pos[ o1 + 2 ];
 
 
-		this.positionArray[ c + 3 ] = pos[ o2 ];
-		this.positionArray[ c + 4 ] = pos[ o2 + 1 ];
-		this.positionArray[ c + 5 ] = pos[ o2 + 2 ];
+		scope.positionArray[ c + 3 ] = pos[ o2 ];
+		scope.positionArray[ c + 4 ] = pos[ o2 + 1 ];
+		scope.positionArray[ c + 5 ] = pos[ o2 + 2 ];
 
 
-		this.positionArray[ c + 6 ] = pos[ o3 ];
-		this.positionArray[ c + 7 ] = pos[ o3 + 1 ];
-		this.positionArray[ c + 8 ] = pos[ o3 + 2 ];
+		scope.positionArray[ c + 6 ] = pos[ o3 ];
+		scope.positionArray[ c + 7 ] = pos[ o3 + 1 ];
+		scope.positionArray[ c + 8 ] = pos[ o3 + 2 ];
 
 
 		// normals
 		// normals
 
 
-		this.normalArray[ c ] 	  = norm[ o1 ];
-		this.normalArray[ c + 1 ] = norm[ o1 + 1 ];
-		this.normalArray[ c + 2 ] = norm[ o1 + 2 ];
+		scope.normalArray[ c + 0 ] = norm[ o1 ];
+		scope.normalArray[ c + 1 ] = norm[ o1 + 1 ];
+		scope.normalArray[ c + 2 ] = norm[ o1 + 2 ];
 
 
-		this.normalArray[ c + 3 ] = norm[ o2 ];
-		this.normalArray[ c + 4 ] = norm[ o2 + 1 ];
-		this.normalArray[ c + 5 ] = norm[ o2 + 2 ];
+		scope.normalArray[ c + 3 ] = norm[ o2 ];
+		scope.normalArray[ c + 4 ] = norm[ o2 + 1 ];
+		scope.normalArray[ c + 5 ] = norm[ o2 + 2 ];
 
 
-		this.normalArray[ c + 6 ] = norm[ o3 ];
-		this.normalArray[ c + 7 ] = norm[ o3 + 1 ];
-		this.normalArray[ c + 8 ] = norm[ o3 + 2 ];
+		scope.normalArray[ c + 6 ] = norm[ o3 ];
+		scope.normalArray[ c + 7 ] = norm[ o3 + 1 ];
+		scope.normalArray[ c + 8 ] = norm[ o3 + 2 ];
 
 
 		// uvs
 		// uvs
 
 
-		if ( this.enableUvs ) {
+		if ( scope.enableUvs ) {
 
 
-			var d = this.count * 2;
+			var d = scope.count * 2;
 
 
-			this.uvArray[ d ] 	  = pos[ o1 ];
-			this.uvArray[ d + 1 ] = pos[ o1 + 2 ];
+			scope.uvArray[ d + 0 ] = pos[ o1 ];
+			scope.uvArray[ d + 1 ] = pos[ o1 + 2 ];
 
 
-			this.uvArray[ d + 2 ] = pos[ o2 ];
-			this.uvArray[ d + 3 ] = pos[ o2 + 2 ];
+			scope.uvArray[ d + 2 ] = pos[ o2 ];
+			scope.uvArray[ d + 3 ] = pos[ o2 + 2 ];
 
 
-			this.uvArray[ d + 4 ] = pos[ o3 ];
-			this.uvArray[ d + 5 ] = pos[ o3 + 2 ];
+			scope.uvArray[ d + 4 ] = pos[ o3 ];
+			scope.uvArray[ d + 5 ] = pos[ o3 + 2 ];
 
 
 		}
 		}
 
 
 		// colors
 		// colors
 
 
-		if ( this.enableColors ) {
+		if ( scope.enableColors ) {
 
 
-			this.colorArray[ c ] 	 = pos[ o1 ];
-			this.colorArray[ c + 1 ] = pos[ o1 + 1 ];
-			this.colorArray[ c + 2 ] = pos[ o1 + 2 ];
+			scope.colorArray[ c + 0 ] = pos[ o1 ];
+			scope.colorArray[ c + 1 ] = pos[ o1 + 1 ];
+			scope.colorArray[ c + 2 ] = pos[ o1 + 2 ];
 
 
-			this.colorArray[ c + 3 ] = pos[ o2 ];
-			this.colorArray[ c + 4 ] = pos[ o2 + 1 ];
-			this.colorArray[ c + 5 ] = pos[ o2 + 2 ];
+			scope.colorArray[ c + 3 ] = pos[ o2 ];
+			scope.colorArray[ c + 4 ] = pos[ o2 + 1 ];
+			scope.colorArray[ c + 5 ] = pos[ o2 + 2 ];
 
 
-			this.colorArray[ c + 6 ] = pos[ o3 ];
-			this.colorArray[ c + 7 ] = pos[ o3 + 1 ];
-			this.colorArray[ c + 8 ] = pos[ o3 + 2 ];
+			scope.colorArray[ c + 6 ] = pos[ o3 ];
+			scope.colorArray[ c + 7 ] = pos[ o3 + 1 ];
+			scope.colorArray[ c + 8 ] = pos[ o3 + 2 ];
 
 
 		}
 		}
 
 
-		this.count += 3;
+		scope.count += 3;
 
 
-		if ( this.count >= this.maxCount - 3 ) {
+		if ( scope.count >= scope.maxCount - 3 ) {
 
 
-			this.hasPositions = true;
-			this.hasNormals = true;
+			scope.hasPositions = true;
+			scope.hasNormals = true;
 
 
-			if ( this.enableUvs ) {
+			if ( scope.enableUvs ) {
 
 
-				this.hasUvs = true;
+				scope.hasUvs = true;
 
 
 			}
 			}
 
 
-			if ( this.enableColors ) {
+			if ( scope.enableColors ) {
 
 
-				this.hasColors = true;
+				scope.hasColors = true;
 
 
 			}
 			}
 
 
-			renderCallback( this );
+			renderCallback( scope );
 
 
 		}
 		}
 
 
 	};
 	};
 
 
-	this.begin = function( ) {
+	this.begin = function () {
 
 
 		this.count = 0;
 		this.count = 0;
 
 
@@ -424,7 +425,7 @@ THREE.MarchingCubes = function ( resolution, material, enableUvs, enableColors )
 
 
 	};
 	};
 
 
-	this.end = function( renderCallback ) {
+	this.end = function ( renderCallback ) {
 
 
 		if ( this.count === 0 ) return;
 		if ( this.count === 0 ) return;
 
 
@@ -460,7 +461,10 @@ THREE.MarchingCubes = function ( resolution, material, enableUvs, enableColors )
 	// Adds a reciprocal ball (nice and blobby) that, to be fast, fades to zero after
 	// Adds a reciprocal ball (nice and blobby) that, to be fast, fades to zero after
 	// a fixed distance, determined by strength and subtract.
 	// a fixed distance, determined by strength and subtract.
 
 
-	this.addBall = function( ballx, bally, ballz, strength, subtract ) {
+	this.addBall = function ( ballx, bally, ballz, strength, subtract ) {
+
+		var sign = Math.sign( strength );
+		strength = Math.abs( strength );
 
 
 		// Let's solve the equation to find the radius:
 		// Let's solve the equation to find the radius:
 		// 1.0 / (0.000001 + radius^2) * strength - subtract = 0
 		// 1.0 / (0.000001 + radius^2) * strength - subtract = 0
@@ -503,7 +507,7 @@ THREE.MarchingCubes = function ( resolution, material, enableUvs, enableColors )
 
 
 					fx = x / this.size - ballx;
 					fx = x / this.size - ballx;
 					val = strength / ( 0.000001 + fx * fx + fy2 + fz2 ) - subtract;
 					val = strength / ( 0.000001 + fx * fx + fy2 + fz2 ) - subtract;
-					if ( val > 0.0 ) this.field[ y_offset + x ] += val;
+					if ( val > 0.0 ) this.field[ y_offset + x ] += val * sign;
 
 
 				}
 				}
 
 
@@ -672,7 +676,7 @@ THREE.MarchingCubes = function ( resolution, material, enableUvs, enableColors )
 					var fx = ( x - this.halfsize ) / this.halfsize; //+ 1
 					var fx = ( x - this.halfsize ) / this.halfsize; //+ 1
 					var q = y_offset + x;
 					var q = y_offset + x;
 
 
-					this.polygonize( fx, fy, fz, q, this.isolation, renderCallback );
+					polygonize( fx, fy, fz, q, this.isolation, renderCallback );
 
 
 				}
 				}
 
 
@@ -691,46 +695,29 @@ THREE.MarchingCubes = function ( resolution, material, enableUvs, enableColors )
 
 
 		var geo_callback = function( object ) {
 		var geo_callback = function( object ) {
 
 
-			var i, x, y, z, vertex, normal,
-				face, a, b, c, na, nb, nc, nfaces;
-
+			for ( var i = 0; i < object.count; i ++ ) {
 
 
-			for ( i = 0; i < object.count; i ++ ) {
-
-				a = i * 3;
-				b = a + 1;
-				c = a + 2;
-
-				x = object.positionArray[ a ];
-				y = object.positionArray[ b ];
-				z = object.positionArray[ c ];
-				vertex = new THREE.Vector3( x, y, z );
-
-				x = object.normalArray[ a ];
-				y = object.normalArray[ b ];
-				z = object.normalArray[ c ];
-				normal = new THREE.Vector3( x, y, z );
-				normal.normalize();
+				var vertex = new THREE.Vector3().fromArray( object.positionArray, i * 3 );
+				var normal = new THREE.Vector3().fromArray( object.normalArray, i * 3 );
 
 
 				geo.vertices.push( vertex );
 				geo.vertices.push( vertex );
 				normals.push( normal );
 				normals.push( normal );
 
 
 			}
 			}
 
 
-			nfaces = object.count / 3;
+			var nfaces = object.count / 3;
 
 
 			for ( i = 0; i < nfaces; i ++ ) {
 			for ( i = 0; i < nfaces; i ++ ) {
 
 
-				a = ( start + i ) * 3;
-				b = a + 1;
-				c = a + 2;
-
-				na = normals[ a ];
-				nb = normals[ b ];
-				nc = normals[ c ];
+				var a = ( start + i ) * 3;
+				var b = a + 1;
+				var c = a + 2;
 
 
-				face = new THREE.Face3( a, b, c, [ na, nb, nc ] );
+				var na = normals[ a ];
+				var nb = normals[ b ];
+				var nc = normals[ c ];
 
 
+				var face = new THREE.Face3( a, b, c, [ na, nb, nc ] );
 				geo.faces.push( face );
 				geo.faces.push( face );
 
 
 			}
 			}

+ 93 - 11
examples/js/ViveController.js

@@ -1,42 +1,124 @@
+/**
+ * @author mrdoob / http://mrdoob.com
+ * @author stewdio / http://stewd.io
+ */
+
 THREE.ViveController = function ( id ) {
 THREE.ViveController = function ( id ) {
 
 
 	THREE.Object3D.call( this );
 	THREE.Object3D.call( this );
 
 
+	var scope = this;
 	var gamepad;
 	var gamepad;
 
 
-	this.getGamepad = function () { return gamepad; };
+	var axes = [ 0, 0 ];
+	var thumbpadIsPressed = false;
+	var triggerIsPressed = false;
+	var gripsArePressed = false;
+	var menuIsPressed = false;
+
+	function findGamepad( id ) {
+
+		// Iterate across gamepads as Vive Controllers may not be
+		// in position 0 and 1.
+
+		var gamepads = navigator.getGamepads();
+
+		for ( var i = 0, j = 0; i < 4; i ++ ) {
+
+			var gamepad = gamepads[ i ];
+
+			if ( gamepad && gamepad.id === 'OpenVR Gamepad' ) {
+
+				if ( j === id ) return gamepad;
+
+				j ++;
+
+			}
+
+		}
+
+	}
+
 	this.matrixAutoUpdate = false;
 	this.matrixAutoUpdate = false;
 	this.standingMatrix = new THREE.Matrix4();
 	this.standingMatrix = new THREE.Matrix4();
 
 
-	var scope = this;
+	this.getGamepad = function () {
+
+		return gamepad;
+
+	};
+
+	this.getButtonState = function ( button ) {
+
+		if ( button === 'thumbpad' ) return thumbpadIsPressed;
+		if ( button === 'trigger' ) return triggerIsPressed;
+		if ( button === 'grips' ) return gripsArePressed;
+		if ( button === 'menu' ) return menuIsPressed;
 
 
-	function update() {
+	};
 
 
-		requestAnimationFrame( update );
+	this.update = function () {
 
 
-		gamepad = navigator.getGamepads()[ id ];
+		gamepad = findGamepad( id );
 
 
 		if ( gamepad !== undefined && gamepad.pose !== null ) {
 		if ( gamepad !== undefined && gamepad.pose !== null ) {
 
 
+			//  Position and orientation.
+
 			var pose = gamepad.pose;
 			var pose = gamepad.pose;
 
 
-			scope.position.fromArray( pose.position );
-			scope.quaternion.fromArray( pose.orientation );
+			if ( pose.position !== null ) scope.position.fromArray( pose.position );
+			if ( pose.orientation !== null ) scope.quaternion.fromArray( pose.orientation );
 			scope.matrix.compose( scope.position, scope.quaternion, scope.scale );
 			scope.matrix.compose( scope.position, scope.quaternion, scope.scale );
 			scope.matrix.multiplyMatrices( scope.standingMatrix, scope.matrix );
 			scope.matrix.multiplyMatrices( scope.standingMatrix, scope.matrix );
 			scope.matrixWorldNeedsUpdate = true;
 			scope.matrixWorldNeedsUpdate = true;
-
 			scope.visible = true;
 			scope.visible = true;
 
 
+			//  Thumbpad and Buttons.
+
+			if ( axes[ 0 ] !== gamepad.axes[ 0 ] || axes[ 1 ] !== gamepad.axes[ 1 ] ) {
+
+				axes[ 0 ] = gamepad.axes[ 0 ]; //  X axis: -1 = Left, +1 = Right.
+				axes[ 1 ] = gamepad.axes[ 1 ]; //  Y axis: -1 = Bottom, +1 = Top.
+				scope.dispatchEvent( { type: 'axischanged', axes: axes } );
+
+			}
+
+			if ( thumbpadIsPressed !== gamepad.buttons[ 0 ].pressed ) {
+
+				thumbpadIsPressed = gamepad.buttons[ 0 ].pressed;
+				scope.dispatchEvent( { type: thumbpadIsPressed ? 'thumbpaddown' : 'thumbpadup' } );
+
+			}
+
+			if ( triggerIsPressed !== gamepad.buttons[ 1 ].pressed ) {
+
+				triggerIsPressed = gamepad.buttons[ 1 ].pressed;
+				scope.dispatchEvent( { type: triggerIsPressed ? 'triggerdown' : 'triggerup' } );
+
+			}
+
+			if ( gripsArePressed !== gamepad.buttons[ 2 ].pressed ) {
+
+				gripsArePressed = gamepad.buttons[ 2 ].pressed;
+				scope.dispatchEvent( { type: gripsArePressed ? 'gripsdown' : 'gripsup' } );
+
+			}
+
+			if ( menuIsPressed !== gamepad.buttons[ 3 ].pressed ) {
+
+				menuIsPressed = gamepad.buttons[ 3 ].pressed;
+				scope.dispatchEvent( { type: menuIsPressed ? 'menudown' : 'menuup' } );
+
+			}
+
 		} else {
 		} else {
 
 
 			scope.visible = false;
 			scope.visible = false;
 
 
 		}
 		}
 
 
-	}
-
-	update();
+	};
 
 
 };
 };
 
 

+ 10 - 2
examples/js/controls/TransformControls.js

@@ -420,7 +420,7 @@
 			],
 			],
 
 
 			XYZE: [
 			XYZE: [
-				[ new THREE.Mesh( new THREE.Geometry() ) ]// TODO
+				[ new THREE.Mesh() ]// TODO
 			]
 			]
 
 
 		};
 		};
@@ -799,7 +799,15 @@
 			this.position.copy( worldPosition );
 			this.position.copy( worldPosition );
 			this.scale.set( scale, scale, scale );
 			this.scale.set( scale, scale, scale );
 
 
-			eye.copy( camPosition ).sub( worldPosition ).normalize();
+			if ( camera instanceof THREE.PerspectiveCamera ) {
+
+				eye.copy( camPosition ).sub( worldPosition ).normalize();
+
+			} else if ( camera instanceof THREE.OrthographicCamera ) {
+
+				eye.copy( camPosition ).normalize();
+
+			}
 
 
 			if ( scope.space === "local" ) {
 			if ( scope.space === "local" ) {
 
 

+ 23 - 59
examples/js/controls/VRControls.js

@@ -11,23 +11,20 @@ THREE.VRControls = function ( object, onError ) {
 
 
 	var standingMatrix = new THREE.Matrix4();
 	var standingMatrix = new THREE.Matrix4();
 
 
+	var frameData = null;
+	if ( 'VRFrameData' in window ) {
+		frameData = new VRFrameData();
+	}
+
 	function gotVRDisplays( displays ) {
 	function gotVRDisplays( displays ) {
 
 
 		vrDisplays = displays;
 		vrDisplays = displays;
 
 
-		for ( var i = 0; i < displays.length; i ++ ) {
+		if ( displays.length > 0 ) {
 
 
-			if ( ( 'VRDisplay' in window && displays[ i ] instanceof VRDisplay ) ||
-				 ( 'PositionSensorVRDevice' in window && displays[ i ] instanceof PositionSensorVRDevice ) ) {
+			vrDisplay = displays[ 0 ];
 
 
-				vrDisplay = displays[ i ];
-				break;  // We keep the first we encounter
-
-			}
-
-		}
-
-		if ( vrDisplay === undefined ) {
+		} else {
 
 
 			if ( onError ) onError( 'VR input not available.' );
 			if ( onError ) onError( 'VR input not available.' );
 
 
@@ -39,11 +36,6 @@ THREE.VRControls = function ( object, onError ) {
 
 
 		navigator.getVRDisplays().then( gotVRDisplays );
 		navigator.getVRDisplays().then( gotVRDisplays );
 
 
-	} else if ( navigator.getVRDevices ) {
-
-		// Deprecated API.
-		navigator.getVRDevices().then( gotVRDisplays );
-
 	}
 	}
 
 
 	// the Rift SDK returns the position in meters
 	// the Rift SDK returns the position in meters
@@ -82,46 +74,32 @@ THREE.VRControls = function ( object, onError ) {
 
 
 		if ( vrDisplay ) {
 		if ( vrDisplay ) {
 
 
-			if ( vrDisplay.getPose ) {
+			var pose;
 
 
-				var pose = vrDisplay.getPose();
+			if ( vrDisplay.getFrameData ) {
 
 
-				if ( pose.orientation !== null ) {
+				vrDisplay.getFrameData( frameData );
+				pose = frameData.pose;
 
 
-					object.quaternion.fromArray( pose.orientation );
+			} else if ( vrDisplay.getPose ) {
 
 
-				}
-
-				if ( pose.position !== null ) {
-
-					object.position.fromArray( pose.position );
-
-				} else {
-
-					object.position.set( 0, 0, 0 );
-
-				}
+				pose = vrDisplay.getPose();
 
 
-			} else {
-
-				// Deprecated API.
-				var state = vrDisplay.getState();
-
-				if ( state.orientation !== null ) {
+			}
 
 
-					object.quaternion.copy( state.orientation );
+			if ( pose.orientation !== null ) {
 
 
-				}
+				object.quaternion.fromArray( pose.orientation );
 
 
-				if ( state.position !== null ) {
+			}
 
 
-					object.position.copy( state.position );
+			if ( pose.position !== null ) {
 
 
-				} else {
+				object.position.fromArray( pose.position );
 
 
-					object.position.set( 0, 0, 0 );
+			} else {
 
 
-				}
+				object.position.set( 0, 0, 0 );
 
 
 			}
 			}
 
 
@@ -152,21 +130,7 @@ THREE.VRControls = function ( object, onError ) {
 
 
 		if ( vrDisplay ) {
 		if ( vrDisplay ) {
 
 
-			if ( vrDisplay.resetPose !== undefined ) {
-
-				vrDisplay.resetPose();
-
-			} else if ( vrDisplay.resetSensor !== undefined ) {
-
-				// Deprecated API.
-				vrDisplay.resetSensor();
-
-			} else if ( vrDisplay.zeroSensor !== undefined ) {
-
-				// Really deprecated API.
-				vrDisplay.zeroSensor();
-
-			}
+			vrDisplay.resetPose();
 
 
 		}
 		}
 
 

+ 1 - 1
examples/js/effects/StereoEffect.js

@@ -32,8 +32,8 @@ THREE.StereoEffect = function ( renderer ) {
 
 
 		var size = renderer.getSize();
 		var size = renderer.getSize();
 
 
-		renderer.setScissorTest( true );
 		renderer.clear();
 		renderer.clear();
+		renderer.setScissorTest( true );
 
 
 		renderer.setScissor( 0, 0, size.width / 2, size.height );
 		renderer.setScissor( 0, 0, size.width / 2, size.height );
 		renderer.setViewport( 0, 0, size.width / 2, size.height );
 		renderer.setViewport( 0, 0, size.width / 2, size.height );

+ 100 - 131
examples/js/effects/VREffect.js

@@ -5,43 +5,36 @@
  * WebVR Spec: http://mozvr.github.io/webvr-spec/webvr.html
  * WebVR Spec: http://mozvr.github.io/webvr-spec/webvr.html
  *
  *
  * Firefox: http://mozvr.com/downloads/
  * Firefox: http://mozvr.com/downloads/
- * Chromium: https://drive.google.com/folderview?id=0BzudLt22BqGRbW9WTHMtOWMzNjQ&usp=sharing#list
+ * Chromium: https://webvr.info/get-chrome
  *
  *
  */
  */
 
 
 THREE.VREffect = function ( renderer, onError ) {
 THREE.VREffect = function ( renderer, onError ) {
 
 
-	var isWebVR1 = true;
-
 	var vrDisplay, vrDisplays;
 	var vrDisplay, vrDisplays;
 	var eyeTranslationL = new THREE.Vector3();
 	var eyeTranslationL = new THREE.Vector3();
 	var eyeTranslationR = new THREE.Vector3();
 	var eyeTranslationR = new THREE.Vector3();
 	var renderRectL, renderRectR;
 	var renderRectL, renderRectR;
-	var eyeFOVL, eyeFOVR;
-
-	function gotVRDisplays( displays ) {
+	var headMatrix = new THREE.Matrix4();
+	var headToEyeMatrixL = new THREE.Matrix4();
+	var headToEyeMatrixR = new THREE.Matrix4();
 
 
-		vrDisplays = displays;
-
-		for ( var i = 0; i < displays.length; i ++ ) {
+	var frameData = null;
+	if ( 'VRFrameData' in window ) {
 
 
-			if ( 'VRDisplay' in window && displays[ i ] instanceof VRDisplay ) {
+		frameData = new VRFrameData();
 
 
-				vrDisplay = displays[ i ];
-				isWebVR1 = true;
-				break; // We keep the first we encounter
+	}
 
 
-			} else if ( 'HMDVRDevice' in window && displays[ i ] instanceof HMDVRDevice ) {
+	function gotVRDisplays( displays ) {
 
 
-				vrDisplay = displays[ i ];
-				isWebVR1 = false;
-				break; // We keep the first we encounter
+		vrDisplays = displays;
 
 
-			}
+		if ( displays.length > 0 ) {
 
 
-		}
+			vrDisplay = displays[ 0 ];
 
 
-		if ( vrDisplay === undefined ) {
+		} else {
 
 
 			if ( onError ) onError( 'HMD not available' );
 			if ( onError ) onError( 'HMD not available' );
 
 
@@ -53,11 +46,6 @@ THREE.VREffect = function ( renderer, onError ) {
 
 
 		navigator.getVRDisplays().then( gotVRDisplays );
 		navigator.getVRDisplays().then( gotVRDisplays );
 
 
-	} else if ( navigator.getVRDevices ) {
-
-		// Deprecated API.
-		navigator.getVRDevices().then( gotVRDisplays );
-
 	}
 	}
 
 
 	//
 	//
@@ -68,6 +56,7 @@ THREE.VREffect = function ( renderer, onError ) {
 	var scope = this;
 	var scope = this;
 
 
 	var rendererSize = renderer.getSize();
 	var rendererSize = renderer.getSize();
+	var rendererUpdateStyle = false;
 	var rendererPixelRatio = renderer.getPixelRatio();
 	var rendererPixelRatio = renderer.getPixelRatio();
 
 
 	this.getVRDisplay = function () {
 	this.getVRDisplay = function () {
@@ -82,29 +71,21 @@ THREE.VREffect = function ( renderer, onError ) {
 
 
 	};
 	};
 
 
-	this.setSize = function ( width, height ) {
+	this.setSize = function ( width, height, updateStyle ) {
 
 
 		rendererSize = { width: width, height: height };
 		rendererSize = { width: width, height: height };
+		rendererUpdateStyle = updateStyle;
 
 
 		if ( scope.isPresenting ) {
 		if ( scope.isPresenting ) {
 
 
 			var eyeParamsL = vrDisplay.getEyeParameters( 'left' );
 			var eyeParamsL = vrDisplay.getEyeParameters( 'left' );
 			renderer.setPixelRatio( 1 );
 			renderer.setPixelRatio( 1 );
-
-			if ( isWebVR1 ) {
-
-				renderer.setSize( eyeParamsL.renderWidth * 2, eyeParamsL.renderHeight, false );
-
-			} else {
-
-				renderer.setSize( eyeParamsL.renderRect.width * 2, eyeParamsL.renderRect.height, false );
-
-			}
+			renderer.setSize( eyeParamsL.renderWidth * 2, eyeParamsL.renderHeight, false );
 
 
 		} else {
 		} else {
 
 
 			renderer.setPixelRatio( rendererPixelRatio );
 			renderer.setPixelRatio( rendererPixelRatio );
-			renderer.setSize( width, height );
+			renderer.setSize( width, height, updateStyle );
 
 
 		}
 		}
 
 
@@ -122,34 +103,19 @@ THREE.VREffect = function ( renderer, onError ) {
 	function onFullscreenChange() {
 	function onFullscreenChange() {
 
 
 		var wasPresenting = scope.isPresenting;
 		var wasPresenting = scope.isPresenting;
-		scope.isPresenting = vrDisplay !== undefined && ( vrDisplay.isPresenting || ( ! isWebVR1 && document[ fullscreenElement ] instanceof window.HTMLElement ) );
+		scope.isPresenting = vrDisplay !== undefined && vrDisplay.isPresenting;
 
 
 		if ( scope.isPresenting ) {
 		if ( scope.isPresenting ) {
 
 
 			var eyeParamsL = vrDisplay.getEyeParameters( 'left' );
 			var eyeParamsL = vrDisplay.getEyeParameters( 'left' );
-			var eyeWidth, eyeHeight;
-
-			if ( isWebVR1 ) {
+			var eyeWidth = eyeParamsL.renderWidth;
+			var eyeHeight = eyeParamsL.renderHeight;
 
 
-				eyeWidth = eyeParamsL.renderWidth;
-				eyeHeight = eyeParamsL.renderHeight;
+			var layers = vrDisplay.getLayers();
+			if ( layers.length ) {
 
 
-				if ( vrDisplay.getLayers ) {
-
-					var layers = vrDisplay.getLayers();
-					if ( layers.length ) {
-
-						leftBounds = layers[0].leftBounds || [ 0.0, 0.0, 0.5, 1.0 ];
-						rightBounds = layers[0].rightBounds || [ 0.5, 0.0, 0.5, 1.0 ];
-
-					}
-
-				}
-
-			} else {
-
-				eyeWidth = eyeParamsL.renderRect.width;
-				eyeHeight = eyeParamsL.renderRect.height;
+				leftBounds = layers[0].leftBounds || [ 0.0, 0.0, 0.5, 1.0 ];
+				rightBounds = layers[0].rightBounds || [ 0.5, 0.0, 0.5, 1.0 ];
 
 
 			}
 			}
 
 
@@ -166,35 +132,12 @@ THREE.VREffect = function ( renderer, onError ) {
 		} else if ( wasPresenting ) {
 		} else if ( wasPresenting ) {
 
 
 			renderer.setPixelRatio( rendererPixelRatio );
 			renderer.setPixelRatio( rendererPixelRatio );
-			renderer.setSize( rendererSize.width, rendererSize.height );
+			renderer.setSize( rendererSize.width, rendererSize.height, rendererUpdateStyle );
 
 
 		}
 		}
 
 
 	}
 	}
 
 
-	if ( canvas.requestFullscreen ) {
-
-		requestFullscreen = 'requestFullscreen';
-		fullscreenElement = 'fullscreenElement';
-		exitFullscreen = 'exitFullscreen';
-		document.addEventListener( 'fullscreenchange', onFullscreenChange, false );
-
-	} else if ( canvas.mozRequestFullScreen ) {
-
-		requestFullscreen = 'mozRequestFullScreen';
-		fullscreenElement = 'mozFullScreenElement';
-		exitFullscreen = 'mozCancelFullScreen';
-		document.addEventListener( 'mozfullscreenchange', onFullscreenChange, false );
-
-	} else {
-
-		requestFullscreen = 'webkitRequestFullscreen';
-		fullscreenElement = 'webkitFullscreenElement';
-		exitFullscreen = 'webkitExitFullscreen';
-		document.addEventListener( 'webkitfullscreenchange', onFullscreenChange, false );
-
-	}
-
 	window.addEventListener( 'vrdisplaypresentchange', onFullscreenChange, false );
 	window.addEventListener( 'vrdisplaypresentchange', onFullscreenChange, false );
 
 
 	this.setFullScreen = function ( boolean ) {
 	this.setFullScreen = function ( boolean ) {
@@ -215,31 +158,13 @@ THREE.VREffect = function ( renderer, onError ) {
 
 
 			}
 			}
 
 
-			if ( isWebVR1 ) {
+			if ( boolean ) {
 
 
-				if ( boolean ) {
-
-					resolve( vrDisplay.requestPresent( [ { source: canvas } ] ) );
-
-				} else {
-
-					resolve( vrDisplay.exitPresent() );
-
-				}
+				resolve( vrDisplay.requestPresent( [ { source: canvas } ] ) );
 
 
 			} else {
 			} else {
 
 
-				if ( canvas[ requestFullscreen ] ) {
-
-					canvas[ boolean ? requestFullscreen : exitFullscreen ]( { vrDisplay: vrDisplay } );
-					resolve();
-
-				} else {
-
-					console.error( 'No compatible requestFullscreen method found.' );
-					reject( new Error( 'No compatible requestFullscreen method found.' ) );
-
-				}
+				resolve( vrDisplay.exitPresent() );
 
 
 			}
 			}
 
 
@@ -261,7 +186,7 @@ THREE.VREffect = function ( renderer, onError ) {
 
 
 	this.requestAnimationFrame = function ( f ) {
 	this.requestAnimationFrame = function ( f ) {
 
 
-		if ( isWebVR1 && vrDisplay !== undefined ) {
+		if ( vrDisplay !== undefined ) {
 
 
 			return vrDisplay.requestAnimationFrame( f );
 			return vrDisplay.requestAnimationFrame( f );
 
 
@@ -275,7 +200,7 @@ THREE.VREffect = function ( renderer, onError ) {
 
 
 	this.cancelAnimationFrame = function ( h ) {
 	this.cancelAnimationFrame = function ( h ) {
 
 
-		if ( isWebVR1 && vrDisplay !== undefined ) {
+		if ( vrDisplay !== undefined ) {
 
 
 			vrDisplay.cancelAnimationFrame( h );
 			vrDisplay.cancelAnimationFrame( h );
 
 
@@ -289,7 +214,7 @@ THREE.VREffect = function ( renderer, onError ) {
 
 
 	this.submitFrame = function () {
 	this.submitFrame = function () {
 
 
-		if ( isWebVR1 && vrDisplay !== undefined && scope.isPresenting ) {
+		if ( vrDisplay !== undefined && scope.isPresenting ) {
 
 
 			vrDisplay.submitFrame();
 			vrDisplay.submitFrame();
 
 
@@ -323,21 +248,8 @@ THREE.VREffect = function ( renderer, onError ) {
 			var eyeParamsL = vrDisplay.getEyeParameters( 'left' );
 			var eyeParamsL = vrDisplay.getEyeParameters( 'left' );
 			var eyeParamsR = vrDisplay.getEyeParameters( 'right' );
 			var eyeParamsR = vrDisplay.getEyeParameters( 'right' );
 
 
-			if ( isWebVR1 ) {
-
-				eyeTranslationL.fromArray( eyeParamsL.offset );
-				eyeTranslationR.fromArray( eyeParamsR.offset );
-				eyeFOVL = eyeParamsL.fieldOfView;
-				eyeFOVR = eyeParamsR.fieldOfView;
-
-			} else {
-
-				eyeTranslationL.copy( eyeParamsL.eyeTranslation );
-				eyeTranslationR.copy( eyeParamsR.eyeTranslation );
-				eyeFOVL = eyeParamsL.recommendedFieldOfView;
-				eyeFOVR = eyeParamsR.recommendedFieldOfView;
-
-			}
+			eyeTranslationL.fromArray( eyeParamsL.offset );
+			eyeTranslationR.fromArray( eyeParamsR.offset );
 
 
 			if ( Array.isArray( scene ) ) {
 			if ( Array.isArray( scene ) ) {
 
 
@@ -370,23 +282,44 @@ THREE.VREffect = function ( renderer, onError ) {
 			} else  {
 			} else  {
 
 
 				renderer.setScissorTest( true );
 				renderer.setScissorTest( true );
-			
+
 			}
 			}
 
 
 			if ( renderer.autoClear || forceClear ) renderer.clear();
 			if ( renderer.autoClear || forceClear ) renderer.clear();
 
 
 			if ( camera.parent === null ) camera.updateMatrixWorld();
 			if ( camera.parent === null ) camera.updateMatrixWorld();
 
 
-			cameraL.projectionMatrix = fovToProjection( eyeFOVL, true, camera.near, camera.far );
-			cameraR.projectionMatrix = fovToProjection( eyeFOVR, true, camera.near, camera.far );
-
 			camera.matrixWorld.decompose( cameraL.position, cameraL.quaternion, cameraL.scale );
 			camera.matrixWorld.decompose( cameraL.position, cameraL.quaternion, cameraL.scale );
 			camera.matrixWorld.decompose( cameraR.position, cameraR.quaternion, cameraR.scale );
 			camera.matrixWorld.decompose( cameraR.position, cameraR.quaternion, cameraR.scale );
 
 
-			var scale = this.scale;
-			cameraL.translateOnAxis( eyeTranslationL, scale );
-			cameraR.translateOnAxis( eyeTranslationR, scale );
+			if ( vrDisplay.getFrameData ) {
+
+				vrDisplay.depthNear = camera.near;
+				vrDisplay.depthFar = camera.far;
+
+				vrDisplay.getFrameData( frameData );
+
+				cameraL.projectionMatrix.elements = frameData.leftProjectionMatrix;
+				cameraR.projectionMatrix.elements = frameData.rightProjectionMatrix;
+
+				getHeadToEyeMatrices( frameData );
+
+				cameraL.updateMatrix();
+				cameraL.applyMatrix( headToEyeMatrixL );
+
+				cameraR.updateMatrix();
+				cameraR.applyMatrix( headToEyeMatrixR );
+
+			} else {
+
+				cameraL.projectionMatrix = fovToProjection( eyeParamsL.fieldOfView, true, camera.near, camera.far );
+				cameraR.projectionMatrix = fovToProjection( eyeParamsR.fieldOfView, true, camera.near, camera.far );
 
 
+				var scale = this.scale;
+				cameraL.translateOnAxis( eyeTranslationL, scale );
+				cameraR.translateOnAxis( eyeTranslationR, scale );
+
+			}
 
 
 			// render left eye
 			// render left eye
 			if ( renderTarget ) {
 			if ( renderTarget ) {
@@ -424,11 +357,11 @@ THREE.VREffect = function ( renderer, onError ) {
 				renderer.setRenderTarget( null );
 				renderer.setRenderTarget( null );
 
 
 			} else {
 			} else {
-				
+
 				renderer.setScissorTest( false );
 				renderer.setScissorTest( false );
 
 
 			}
 			}
-			
+
 			if ( autoUpdate ) {
 			if ( autoUpdate ) {
 
 
 				scene.autoUpdate = true;
 				scene.autoUpdate = true;
@@ -453,6 +386,42 @@ THREE.VREffect = function ( renderer, onError ) {
 
 
 	//
 	//
 
 
+	var poseOrientation = new THREE.Quaternion();
+	var posePosition = new THREE.Vector3();
+
+	function getHeadToEyeMatrices( frameData ) {
+
+		// Compute the matrix for the position of the head based on the pose
+		if ( frameData.pose.orientation ) {
+
+			poseOrientation.fromArray( frameData.pose.orientation );
+			headMatrix.makeRotationFromQuaternion( poseOrientation );
+
+		}	else {
+
+			headMatrix.identity();
+
+		}
+
+		if ( frameData.pose.position ) {
+
+			posePosition.fromArray( frameData.pose.position );
+			headMatrix.setPosition( posePosition );
+
+		}
+
+		// Take the view matricies and multiply them by the head matrix, which
+		// leaves only the head-to-eye transform.
+		headToEyeMatrixL.fromArray( frameData.leftViewMatrix );
+		headToEyeMatrixL.premultiply( headMatrix );
+		headToEyeMatrixL.getInverse( headToEyeMatrixL );
+
+		headToEyeMatrixR.fromArray( frameData.rightViewMatrix );
+		headToEyeMatrixR.premultiply( headMatrix );
+		headToEyeMatrixR.getInverse( headToEyeMatrixR );
+
+	}
+
 	function fovToNDCScaleOffset( fov ) {
 	function fovToNDCScaleOffset( fov ) {
 
 
 		var pxscale = 2.0 / ( fov.leftTan + fov.rightTan );
 		var pxscale = 2.0 / ( fov.leftTan + fov.rightTan );

File diff suppressed because it is too large
+ 0 - 58
examples/js/libs/dat.gui.min.js


+ 3 - 6
examples/js/loaders/AMFLoader.js

@@ -433,15 +433,12 @@ THREE.AMFLoader.prototype = {
 
 
 				var objDefaultMaterial = defaultMaterial;
 				var objDefaultMaterial = defaultMaterial;
 				var mesh = meshes[ i ];
 				var mesh = meshes[ i ];
-				var meshVertices = Float32Array.from( mesh.vertices );
-				var vertices = new THREE.BufferAttribute( Float32Array.from( meshVertices ), 3 );
-				var meshNormals = null;
+				var vertices = new THREE.BufferAttribute( new Float32Array( mesh.vertices ), 3 );
 				var normals = null;
 				var normals = null;
 
 
 				if ( mesh.normals.length ) {
 				if ( mesh.normals.length ) {
 
 
-					meshNormals = Float32Array.from( mesh.normals );
-					normals = new THREE.BufferAttribute( Float32Array.from( meshNormals ), 3 );
+					normals = new THREE.BufferAttribute( new Float32Array( mesh.normals ), 3 );
 
 
 				}
 				}
 
 
@@ -467,7 +464,7 @@ THREE.AMFLoader.prototype = {
 
 
 					var volume = volumes[ j ];
 					var volume = volumes[ j ];
 					var newGeometry = new THREE.BufferGeometry();
 					var newGeometry = new THREE.BufferGeometry();
-					var indexes = Uint32Array.from( volume.triangles );
+					var indexes = new  Uint32Array( volume.triangles );
 					var material = objDefaultMaterial;
 					var material = objDefaultMaterial;
 
 
 					newGeometry.setIndex( new THREE.BufferAttribute( indexes, 1 ) );
 					newGeometry.setIndex( new THREE.BufferAttribute( indexes, 1 ) );

+ 51 - 112
examples/js/loaders/MMDLoader.js

@@ -1995,7 +1995,6 @@ THREE.MMDLoader.prototype.createMesh = function ( model, texturePath, onProgress
 		var textures = [];
 		var textures = [];
 		var textureLoader = new THREE.TextureLoader( this.manager );
 		var textureLoader = new THREE.TextureLoader( this.manager );
 		var tgaLoader = new THREE.TGALoader( this.manager );
 		var tgaLoader = new THREE.TGALoader( this.manager );
-		var materialLoader = new THREE.MaterialLoader( this.manager );
 		var color = new THREE.Color();
 		var color = new THREE.Color();
 		var offset = 0;
 		var offset = 0;
 		var materialParams = [];
 		var materialParams = [];
@@ -2037,6 +2036,8 @@ THREE.MMDLoader.prototype.createMesh = function ( model, texturePath, onProgress
 
 
 				}
 				}
 
 
+				delete texture.readyCallbacks;
+
 			} );
 			} );
 
 
 			texture.readyCallbacks = [];
 			texture.readyCallbacks = [];
@@ -2049,6 +2050,18 @@ THREE.MMDLoader.prototype.createMesh = function ( model, texturePath, onProgress
 
 
 		};
 		};
 
 
+		function getTexture( name, textures ) {
+
+			if ( textures[ name ] === undefined ) {
+
+				console.warn( 'THREE.MMDLoader: Undefined texture', name );
+
+			}
+
+			return textures[ name ];
+
+		};
+
 		for ( var i = 0; i < model.metadata.materialCount; i++ ) {
 		for ( var i = 0; i < model.metadata.materialCount; i++ ) {
 
 
 			geometry.faceVertexUvs.push( [] );
 			geometry.faceVertexUvs.push( [] );
@@ -2058,12 +2071,7 @@ THREE.MMDLoader.prototype.createMesh = function ( model, texturePath, onProgress
 		for ( var i = 0; i < model.metadata.materialCount; i++ ) {
 		for ( var i = 0; i < model.metadata.materialCount; i++ ) {
 
 
 			var m = model.materials[ i ];
 			var m = model.materials[ i ];
-			var params = {
-
-				uuid: THREE.Math.generateUUID(),
-				type: 'MMDMaterial'
-
-			};
+			var params = {};
 
 
 			params.faceOffset = offset;
 			params.faceOffset = offset;
 			params.faceNum = m.faceCount;
 			params.faceNum = m.faceCount;
@@ -2088,9 +2096,9 @@ THREE.MMDLoader.prototype.createMesh = function ( model, texturePath, onProgress
 			}
 			}
 
 
 			params.name = m.name;
 			params.name = m.name;
-			params.color = color.fromArray( [ m.diffuse[ 0 ], m.diffuse[ 1 ], m.diffuse[ 2 ] ] ).getHex();
+			params.color = color.fromArray( [ m.diffuse[ 0 ], m.diffuse[ 1 ], m.diffuse[ 2 ] ] ).clone();
 			params.opacity = m.diffuse[ 3 ];
 			params.opacity = m.diffuse[ 3 ];
-			params.specular = color.fromArray( [ m.specular[ 0 ], m.specular[ 1 ], m.specular[ 2 ] ] ).getHex();
+			params.specular = color.fromArray( [ m.specular[ 0 ], m.specular[ 1 ], m.specular[ 2 ] ] ).clone();
 			params.shininess = m.shininess;
 			params.shininess = m.shininess;
 
 
 			if ( params.opacity === 1.0 ) {
 			if ( params.opacity === 1.0 ) {
@@ -2185,33 +2193,37 @@ THREE.MMDLoader.prototype.createMesh = function ( model, texturePath, onProgress
 			// TODO: check if this logic is right
 			// TODO: check if this logic is right
 			if ( params.map === undefined /* && params.envMap === undefined */ ) {
 			if ( params.map === undefined /* && params.envMap === undefined */ ) {
 
 
-				params.emissive = color.fromArray( [ m.emissive[ 0 ], m.emissive[ 1 ], m.emissive[ 2 ] ] ).getHex();
+				params.emissive = color.fromArray( [ m.emissive[ 0 ], m.emissive[ 1 ], m.emissive[ 2 ] ] ).clone();
 
 
 			}
 			}
 
 
-			var shader = THREE.ShaderLib[ 'mmd' ];
-			params.uniforms = THREE.UniformsUtils.clone( shader.uniforms );
-			params.vertexShader = shader.vertexShader;
-			params.fragmentShader = shader.fragmentShader;
-
 			materialParams.push( params );
 			materialParams.push( params );
 
 
 		}
 		}
 
 
-		materialLoader.setTextures( textures );
+		var shader = THREE.ShaderLib[ 'mmd' ];
 
 
 		for ( var i = 0; i < materialParams.length; i++ ) {
 		for ( var i = 0; i < materialParams.length; i++ ) {
 
 
 			var p = materialParams[ i ];
 			var p = materialParams[ i ];
 			var p2 = model.materials[ i ];
 			var p2 = model.materials[ i ];
-			var m = materialLoader.parse( p );
+			var m = new THREE.ShaderMaterial( {
+				uniforms: THREE.UniformsUtils.clone( shader.uniforms ),
+				vertexShader: shader.vertexShader,
+				fragmentShader: shader.fragmentShader
+			} );
 
 
 			m.faceOffset = p.faceOffset;
 			m.faceOffset = p.faceOffset;
 			m.faceNum = p.faceNum;
 			m.faceNum = p.faceNum;
 
 
+			if ( p.name !== undefined ) m.name = p.name;
+
 			m.skinning = geometry.bones.length > 0 ? true : false;
 			m.skinning = geometry.bones.length > 0 ? true : false;
 			m.morphTargets = geometry.morphTargets.length > 0 ? true : false;
 			m.morphTargets = geometry.morphTargets.length > 0 ? true : false;
 			m.lights = true;
 			m.lights = true;
+			m.side = p.side;
+			m.transparent = p.transparent;
+			m.fog = true;
 
 
 			m.blending = THREE.CustomBlending;
 			m.blending = THREE.CustomBlending;
 			m.blendSrc = THREE.SrcAlphaFactor;
 			m.blendSrc = THREE.SrcAlphaFactor;
@@ -2219,7 +2231,7 @@ THREE.MMDLoader.prototype.createMesh = function ( model, texturePath, onProgress
 			m.blendSrcAlpha = THREE.SrcAlphaFactor;
 			m.blendSrcAlpha = THREE.SrcAlphaFactor;
 			m.blendDstAlpha = THREE.DstAlphaFactor;
 			m.blendDstAlpha = THREE.DstAlphaFactor;
 
 
-			if ( m.map !== null ) {
+			if ( p.map !== undefined ) {
 
 
 				// Check if this part of the texture image the material uses requires transparency
 				// Check if this part of the texture image the material uses requires transparency
 				function checkTextureTransparency ( m ) {
 				function checkTextureTransparency ( m ) {
@@ -2326,45 +2338,45 @@ THREE.MMDLoader.prototype.createMesh = function ( model, texturePath, onProgress
 
 
 						m.textureTransparency = detectTextureTransparency( imageData, uvs );
 						m.textureTransparency = detectTextureTransparency( imageData, uvs );
 
 
+						delete m.faceOffset;
+						delete m.faceNum;
+
 					} );
 					} );
 
 
 				}
 				}
 
 
+				m.map = getTexture( p.map, textures );
+				m.uniforms.map.value = m.map;
 				checkTextureTransparency( m );
 				checkTextureTransparency( m );
 
 
 			}
 			}
 
 
-			if ( m.envMap !== null ) {
+			if ( p.envMap !== undefined ) {
 
 
-				// TODO: WebGLRenderer should automatically update?
-				function updateMaterialWhenTextureIsReady ( m ) {
-
-					m.envMap.readyCallbacks.push( function ( t ) {
-
-						m.needsUpdate = true;
+				m.envMap = getTexture( p.envMap, textures );
+				m.uniforms.envMap.value = m.envMap;
+				m.combine = p.envMapType;
 
 
-					} );
+				// TODO: WebGLRenderer should automatically update?
+				m.envMap.readyCallbacks.push( function ( t ) {
 
 
-				}
+					m.needsUpdate = true;
 
 
-				m.combine = p.envMapType;
-				updateMaterialWhenTextureIsReady( m );
+				} );
 
 
 			}
 			}
 
 
-			m.uniforms.opacity.value = m.opacity;
-			m.uniforms.diffuse.value = m.color;
+			m.uniforms.opacity.value = p.opacity;
+			m.uniforms.diffuse.value.copy( p.color );
 
 
-			if ( m.emissive ) {
+			if ( p.emissive !== undefined ) {
 
 
-				m.uniforms.emissive.value = m.emissive;
+				m.uniforms.emissive.value.copy( p.emissive );
 
 
 			}
 			}
 
 
-			m.uniforms.map.value = m.map;
-			m.uniforms.envMap.value = m.envMap;
-			m.uniforms.specular.value = m.specular;
-			m.uniforms.shininess.value = Math.max( m.shininess, 1e-4 ); // to prevent pow( 0.0, 0.0 )
+			m.uniforms.specular.value.copy( p.specular );
+			m.uniforms.shininess.value = Math.max( p.shininess, 1e-4 ); // to prevent pow( 0.0, 0.0 )
 
 
 			if ( model.metadata.format === 'pmd' ) {
 			if ( model.metadata.format === 'pmd' ) {
 
 
@@ -2458,7 +2470,7 @@ THREE.MMDLoader.prototype.createMesh = function ( model, texturePath, onProgress
 
 
 					var m = material.materials[ e.index ];
 					var m = material.materials[ e.index ];
 
 
-					if ( m.opacity !== e.diffuse[ 3 ] ) {
+					if ( m.uniforms.opacity.value !== e.diffuse[ 3 ] ) {
 
 
 						m.morphTransparency = true;
 						m.morphTransparency = true;
 
 
@@ -3538,79 +3550,6 @@ THREE.MMDLoader.DataView.prototype = {
 
 
 };
 };
 
 
-/*
- * MMD custom shaders based on MeshPhongMaterial.
- * This class extends ShaderMaterial while shaders are based on MeshPhongMaterial.
- * Keep this class updated on MeshPhongMaterial.
- */
-THREE.MMDMaterial = function ( parameters ) {
-
-	THREE.ShaderMaterial.call( this, parameters );
-
-//	this.type = 'MMDMaterial';
-
-	this.faceOffset = null;
-	this.faceNum = null;
-	this.textureTransparency = false;
-	this.morphTransparency = false;
-
-	// the followings are copied from MeshPhongMaterial
-	this.color = new THREE.Color( 0xffffff ); // diffuse
-	this.emissive = new THREE.Color( 0x000000 );
-	this.specular = new THREE.Color( 0x111111 );
-	this.shininess = 30;
-
-	this.map = null;
-
-	this.lightMap = null;
-	this.lightMapIntensity = 1.0;
-
-	this.aoMap = null;
-	this.aoMapIntensity = 1.0;
-
-	this.emissiveMap = null;
-
-	this.bumpMap = null;
-	this.bumpScale = 1;
-
-	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;
-
-	this.envMap = null;
-	this.combine = THREE.MultiplyOperation;
-	this.reflectivity = 1;
-	this.refractionRatio = 0.98;
-
-	this.fog = true;
-
-	this.shading = THREE.SmoothShading;
-
-	this.wireframe = false;
-	this.wireframeLinewidth = 1;
-	this.wireframeLinecap = 'round';
-	this.wireframeLinejoin = 'round';
-
-	this.vertexColors = THREE.NoColors;
-
-	this.skinning = false;
-	this.morphTargets = false;
-	this.morphNormals = false;
-
-	this.setValues( parameters );
-
-};
-
-THREE.MMDMaterial.prototype = Object.create( THREE.ShaderMaterial.prototype );
-THREE.MMDMaterial.prototype.constructor = THREE.MMDMaterial;
-
 /*
 /*
  * Shaders are copied from MeshPhongMaterial and then MMD spcific codes are inserted.
  * Shaders are copied from MeshPhongMaterial and then MMD spcific codes are inserted.
  * Keep shaders updated on MeshPhongMaterial.
  * Keep shaders updated on MeshPhongMaterial.
@@ -4489,7 +4428,7 @@ THREE.MMDHelper.prototype = {
 			m.uniforms.outlineDrawing.value = 0;
 			m.uniforms.outlineDrawing.value = 0;
 			m.visible = true;
 			m.visible = true;
 
 
-			if ( m.opacity === 1.0 ) {
+			if ( m.uniforms.opacity.value === 1.0 ) {
 
 
 				m.side = THREE.FrontSide;
 				m.side = THREE.FrontSide;
 				m.transparent = false;
 				m.transparent = false;

+ 34 - 9
examples/js/loaders/OBJLoader.js

@@ -89,14 +89,14 @@ THREE.OBJLoader.prototype = {
 
 
 				}
 				}
 
 
+				var previousMaterial = ( this.object && typeof this.object.currentMaterial === 'function' ? this.object.currentMaterial() : undefined );
+
 				if ( this.object && typeof this.object._finalize === 'function' ) {
 				if ( this.object && typeof this.object._finalize === 'function' ) {
 
 
-					this.object._finalize();
+					this.object._finalize( true );
 
 
 				}
 				}
 
 
-				var previousMaterial = ( this.object && typeof this.object.currentMaterial === 'function' ? this.object.currentMaterial() : undefined );
-
 				this.object = {
 				this.object = {
 					name : name || '',
 					name : name || '',
 					fromDeclaration : ( fromDeclaration !== false ),
 					fromDeclaration : ( fromDeclaration !== false ),
@@ -132,16 +132,18 @@ THREE.OBJLoader.prototype = {
 							inherited  : false,
 							inherited  : false,
 
 
 							clone : function( index ) {
 							clone : function( index ) {
-								return {
+								var cloned = {
 									index      : ( typeof index === 'number' ? index : this.index ),
 									index      : ( typeof index === 'number' ? index : this.index ),
 									name       : this.name,
 									name       : this.name,
 									mtllib     : this.mtllib,
 									mtllib     : this.mtllib,
 									smooth     : this.smooth,
 									smooth     : this.smooth,
-									groupStart : this.groupEnd,
+									groupStart : 0,
 									groupEnd   : -1,
 									groupEnd   : -1,
 									groupCount : -1,
 									groupCount : -1,
 									inherited  : false
 									inherited  : false
 								};
 								};
+								cloned.clone = this.clone.bind(cloned);
+								return cloned;
 							}
 							}
 						};
 						};
 
 
@@ -172,12 +174,25 @@ THREE.OBJLoader.prototype = {
 
 
 						}
 						}
 
 
+						// Ignore objects tail materials if no face declarations followed them before a new o/g started.
+						if ( end && this.materials.length > 1 ) {
+
+							for ( var mi = this.materials.length - 1; mi >= 0; mi-- ) {
+								if ( this.materials[mi].groupCount <= 0 ) {
+									this.materials.splice( mi, 1 );
+								}
+							}
+
+						}
+
 						// Guarantee at least one empty material, this makes the creation later more straight forward.
 						// Guarantee at least one empty material, this makes the creation later more straight forward.
-						if ( end !== false && this.materials.length === 0 ) {
+						if ( end && this.materials.length === 0 ) {
+
 							this.materials.push({
 							this.materials.push({
 								name   : '',
 								name   : '',
 								smooth : this.smooth
 								smooth : this.smooth
 							});
 							});
+
 						}
 						}
 
 
 						return lastMultiMaterial;
 						return lastMultiMaterial;
@@ -207,7 +222,7 @@ THREE.OBJLoader.prototype = {
 
 
 				if ( this.object && typeof this.object._finalize === 'function' ) {
 				if ( this.object && typeof this.object._finalize === 'function' ) {
 
 
-					this.object._finalize();
+					this.object._finalize( true );
 
 
 				}
 				}
 
 
@@ -412,7 +427,14 @@ THREE.OBJLoader.prototype = {
 		if ( text.indexOf( '\r\n' ) !== - 1 ) {
 		if ( text.indexOf( '\r\n' ) !== - 1 ) {
 
 
 			// This is faster than String.split with regex that splits on both
 			// This is faster than String.split with regex that splits on both
-			text = text.replace( '\r\n', '\n' );
+			text = text.replace( /\r\n/g, '\n' );
+
+		}
+
+		if ( text.indexOf( '\\\n' ) !== - 1) {
+
+			// join lines separated by a line continuation character (\)
+			text = text.replace( /\\\n/g, '' );
 
 
 		}
 		}
 
 
@@ -563,7 +585,10 @@ THREE.OBJLoader.prototype = {
 				// or
 				// or
 				// g group_name
 				// g group_name
 
 
-				var name = result[ 0 ].substr( 1 ).trim();
+				// WORKAROUND: https://bugs.chromium.org/p/v8/issues/detail?id=2869
+				// var name = result[ 0 ].substr( 1 ).trim();
+				var name = ( " " + result[ 0 ].substr( 1 ).trim() ).substr( 1 );
+
 				state.startObject( name );
 				state.startObject( name );
 
 
 			} else if ( this.regexp.material_use_pattern.test( line ) ) {
 			} else if ( this.regexp.material_use_pattern.test( line ) ) {

+ 38 - 0
examples/js/nodes/AttributeNode.js

@@ -0,0 +1,38 @@
+/**
+ * @author sunag / http://www.sunag.com.br/
+ */
+
+THREE.AttributeNode = function( name, type ) {
+
+	THREE.GLNode.call( this, type );
+
+	this.name = name;
+
+};
+
+THREE.AttributeNode.prototype = Object.create( THREE.GLNode.prototype );
+THREE.AttributeNode.prototype.constructor = THREE.AttributeNode;
+
+THREE.AttributeNode.prototype.getAttributeType = function( builder ) {
+
+	return typeof this.type === 'number' ? builder.getConstructorFromLength( this.type ) : this.type;
+
+};
+
+THREE.AttributeNode.prototype.getType = function( builder ) {
+
+	var type = this.getAttributeType( builder );
+
+	return builder.getTypeByFormat( type );
+
+};
+
+THREE.AttributeNode.prototype.generate = function( builder, output ) {
+
+	var type = this.getAttributeType( builder );
+
+	var attribute = builder.material.getAttribute( this.name, type );
+
+	return builder.format( builder.isShader( 'vertex' ) ? this.name : attribute.varying.name, this.getType( builder ), output );
+
+};

+ 0 - 208
examples/js/nodes/BuilderNode.js

@@ -1,208 +0,0 @@
-/**
- * @author sunag / http://www.sunag.com.br/
- */
-
-THREE.BuilderNode = function( material ) {
-
-	this.material = material;
-
-	this.caches = [];
-
-	this.parsing = false;
-	this.optimize = true;
-
-	this.addCache();
-
-};
-
-THREE.BuilderNode.prototype = {
-	constructor: THREE.BuilderNode,
-
-	addCache : function( name, requires ) {
-
-		this.caches.push( {
-			name : name || '',
-			requires : requires || {}
-		} );
-
-		return this.updateCache();
-
-	},
-
-	removeCache : function() {
-
-		this.caches.pop();
-
-		return this.updateCache();
-
-	},
-
-	isCache : function( name ) {
-
-		var i = this.caches.length;
-
-		while ( i -- ) {
-
-			if ( this.caches[ i ].name == name ) return true;
-
-		}
-
-		return false;
-
-	},
-
-	updateCache : function() {
-
-		var cache = this.caches[ this.caches.length - 1 ];
-
-		this.cache = cache.name;
-		this.requires = cache.requires;
-
-		return this;
-
-	},
-
-	require : function( name, node ) {
-
-		this.requires[ name ] = node;
-
-		return this;
-
-	},
-
-	include : function( func ) {
-
-		this.material.include( this.shader, func );
-
-		return this;
-
-	},
-
-	colorToVector : function( color ) {
-
-		return color.replace( 'r', 'x' ).replace( 'g', 'y' ).replace( 'b', 'z' ).replace( 'a', 'w' );
-
-	},
-
-	getFormatConstructor : function( len ) {
-
-		return THREE.BuilderNode.constructors[ len - 1 ];
-
-	},
-
-	getFormatName : function( format ) {
-
-		return format.replace( /c/g, 'v3' ).replace( /fv1|iv1/g, 'v1' );
-
-	},
-
-	isFormatMatrix : function( format ) {
-
-		return /^m/.test( format );
-
-	},
-
-	getFormatLength : function( format ) {
-
-		return parseInt( this.getFormatName( format ).substr( 1 ) );
-
-	},
-
-	getFormatByLength : function( len ) {
-
-		if ( len == 1 ) return 'fv1';
-
-		return 'v' + len;
-
-	},
-
-	format : function( code, from, to ) {
-
-		var format = this.getFormatName( from + '=' + to );
-
-		switch ( format ) {
-			case 'v1=v2': return 'vec2(' + code + ')';
-			case 'v1=v3': return 'vec3(' + code + ')';
-			case 'v1=v4': return 'vec4(' + code + ')';
-
-			case 'v2=v1': return code + '.x';
-			case 'v2=v3': return 'vec3(' + code + ',0.0)';
-			case 'v2=v4': return 'vec4(' + code + ',0.0,1.0)';
-
-			case 'v3=v1': return code + '.x';
-			case 'v3=v2': return code + '.xy';
-			case 'v3=v4': return 'vec4(' + code + ',1.0)';
-
-			case 'v4=v1': return code + '.x';
-			case 'v4=v2': return code + '.xy';
-			case 'v4=v3': return code + '.xyz';
-		}
-
-		return code;
-
-	},
-
-	getTypeByFormat : function( format ) {
-
-		return THREE.BuilderNode.type[ format ];
-
-	},
-
-	getUuid : function( uuid, useCache ) {
-
-		useCache = useCache !== undefined ? useCache : true;
-
-		if ( useCache && this.cache ) uuid = this.cache + '-' + uuid;
-
-		return uuid;
-
-	},
-
-	getElementByIndex : function( index ) {
-
-		return THREE.BuilderNode.elements[ index ];
-
-	},
-
-	getIndexByElement : function( elm ) {
-
-		return THREE.BuilderNode.elements.indexOf( elm );
-
-	},
-
-	isShader : function( shader ) {
-
-		return this.shader == shader;
-
-	},
-
-	setShader : function( shader ) {
-
-		this.shader = shader;
-
-		return this;
-
-	}
-};
-
-THREE.BuilderNode.type = {
-	'float' : 'fv1',
-	vec2 : 'v2',
-	vec3 : 'v3',
-	vec4 : 'v4',
-	mat4 : 'v4'
-};
-
-THREE.BuilderNode.constructors = [
-	'',
-	'vec2',
-	'vec3',
-	'vec4'
-];
-
-THREE.BuilderNode.elements = [
-	'x',
-	'y',
-	'z',
-	'w'
-];

+ 43 - 17
examples/js/nodes/ConstNode.js

@@ -2,11 +2,11 @@
  * @author sunag / http://www.sunag.com.br/
  * @author sunag / http://www.sunag.com.br/
  */
  */
 
 
-THREE.ConstNode = function( name, useDefine ) {
+THREE.ConstNode = function( src, useDefine ) {
 
 
 	THREE.TempNode.call( this );
 	THREE.TempNode.call( this );
 
 
-	this.parse( name || THREE.ConstNode.PI, useDefine );
+	this.eval( src || THREE.ConstNode.PI, useDefine );
 
 
 };
 };
 
 
@@ -20,31 +20,30 @@ THREE.ConstNode.EPSILON = 'EPSILON';
 THREE.ConstNode.prototype = Object.create( THREE.TempNode.prototype );
 THREE.ConstNode.prototype = Object.create( THREE.TempNode.prototype );
 THREE.ConstNode.prototype.constructor = THREE.ConstNode;
 THREE.ConstNode.prototype.constructor = THREE.ConstNode;
 
 
-THREE.ConstNode.prototype.parse = function( src, useDefine ) {
+THREE.ConstNode.prototype.getType = function( builder ) {
 
 
-	var name, type;
+	return builder.getTypeByFormat( this.type );
 
 
-	var rDeclaration = /^([a-z_0-9]+)\s([a-z_0-9]+)\s?\=(.*?)\;/i;
-	var match = src.match( rDeclaration );
+};
 
 
-	if ( match && match.length > 1 ) {
+THREE.ConstNode.prototype.eval = function( src, useDefine ) {
 
 
-		type = match[ 1 ];
-		name = match[ 2 ];
+	src = ( src || '' ).trim();
 
 
-		if ( useDefine ) {
+	var name, type, value;
 
 
-			this.src = '#define ' + name + ' ' + match[ 3 ];
+	var rDeclaration = /^([a-z_0-9]+)\s([a-z_0-9]+)\s?\=?\s?(.*?)(\;|$)/i;
+	var match = src.match( rDeclaration );
 
 
-		}
-		else {
+	this.useDefine = useDefine;
 
 
-			this.src = 'const ' + type + ' ' + name + ' = ' + match[ 3 ] + ';';
+	if ( match && match.length > 1 ) {
 
 
-		}
+		type = match[ 1 ];
+		name = match[ 2 ];
+		value = match[ 3 ];
 
 
-	}
-	else {
+	} else {
 
 
 		name = src;
 		name = src;
 		type = 'fv1';
 		type = 'fv1';
@@ -53,6 +52,33 @@ THREE.ConstNode.prototype.parse = function( src, useDefine ) {
 
 
 	this.name = name;
 	this.name = name;
 	this.type = type;
 	this.type = type;
+	this.value = value;
+
+};
+
+THREE.ConstNode.prototype.build = function( builder, output ) {
+
+	if ( output === 'source' ) {
+
+		if ( this.value ) {
+
+			if ( this.useDefine ) {
+
+				return '#define ' + this.name + ' ' + this.value;
+
+			}
+
+			return 'const ' + this.type + ' ' + this.name + ' = ' + this.value + ';';
+
+		}
+
+	} else {
+
+		builder.include( this );
+
+		return builder.format( this.name, this.getType( builder ), output );
+
+	}
 
 
 };
 };
 
 

+ 6 - 8
examples/js/nodes/FunctionCallNode.js

@@ -2,21 +2,21 @@
  * @author sunag / http://www.sunag.com.br/
  * @author sunag / http://www.sunag.com.br/
  */
  */
 
 
-THREE.FunctionCallNode = function( value ) {
+THREE.FunctionCallNode = function( func, inputs ) {
 
 
 	THREE.TempNode.call( this );
 	THREE.TempNode.call( this );
 
 
-	this.setFunction( value );
+	this.setFunction( func, inputs );
 
 
 };
 };
 
 
 THREE.FunctionCallNode.prototype = Object.create( THREE.TempNode.prototype );
 THREE.FunctionCallNode.prototype = Object.create( THREE.TempNode.prototype );
 THREE.FunctionCallNode.prototype.constructor = THREE.FunctionCallNode;
 THREE.FunctionCallNode.prototype.constructor = THREE.FunctionCallNode;
 
 
-THREE.FunctionCallNode.prototype.setFunction = function( val ) {
+THREE.FunctionCallNode.prototype.setFunction = function( func, inputs ) {
 
 
-	this.inputs = [];
-	this.value = val;
+	this.value = func;
+	this.inputs = inputs || [];
 
 
 };
 };
 
 
@@ -39,9 +39,7 @@ THREE.FunctionCallNode.prototype.generate = function( builder, output ) {
 	var type = this.getType( builder );
 	var type = this.getType( builder );
 	var func = this.value;
 	var func = this.value;
 
 
-	builder.include( func );
-
-	var code = func.name + '(';
+	var code = func.build( builder, output ) + '(';
 	var params = [];
 	var params = [];
 
 
 	for ( var i = 0; i < func.inputs.length; i ++ ) {
 	for ( var i = 0; i < func.inputs.length; i ++ ) {

+ 119 - 75
examples/js/nodes/FunctionNode.js

@@ -3,37 +3,35 @@
  * @thanks bhouston / https://clara.io/
  * @thanks bhouston / https://clara.io/
  */
  */
 
 
-THREE.FunctionNode = function( src, includes, extensions ) {
+THREE.FunctionNode = function( src, includesOrType, extensionsOrIncludes, keywordsOrExtensions ) {
 
 
-	THREE.GLNode.call( this );
+	src = src || '';
 
 
-	this.parse( src || '', includes, extensions );
+	this.isMethod = typeof includesOrType !== "string";
+	this.useKeywords = true;
+
+	THREE.TempNode.call( this, this.isMethod ? null : includesOrType );
+
+	if ( this.isMethod ) this.eval( src, includesOrType, extensionsOrIncludes, keywordsOrExtensions );
+	else this.eval( src, extensionsOrIncludes, keywordsOrExtensions );
 
 
 };
 };
 
 
-THREE.FunctionNode.prototype = Object.create( THREE.GLNode.prototype );
+THREE.FunctionNode.rDeclaration = /^([a-z_0-9]+)\s([a-z_0-9]+)\s?\((.*?)\)/i;
+THREE.FunctionNode.rProperties = /[a-z_0-9]+/ig;
+
+THREE.FunctionNode.prototype = Object.create( THREE.TempNode.prototype );
 THREE.FunctionNode.prototype.constructor = THREE.FunctionNode;
 THREE.FunctionNode.prototype.constructor = THREE.FunctionNode;
 
 
-THREE.FunctionNode.prototype.parseReference = function( name ) {
-
-	switch ( name ) {
-		case 'uv': return new THREE.UVNode().name;
-		case 'uv2': return new THREE.UVNode( 1 ).name;
-		case 'position': return new THREE.PositionNode().name;
-		case 'worldPosition': return new THREE.PositionNode( THREE.PositionNode.WORLD ).name;
-		case 'normal': return new THREE.NormalNode().name;
-		case 'normalPosition': return new THREE.NormalNode( THREE.NormalNode.WORLD ).name;
-		case 'viewPosition': return new THREE.PositionNode( THREE.NormalNode.VIEW ).name;
-		case 'viewNormal': return new THREE.NormalNode( THREE.NormalNode.VIEW ).name;
-	}
+THREE.FunctionNode.prototype.isShared = function( builder, output ) {
 
 
-	return name;
+	return ! this.isMethod;
 
 
 };
 };
 
 
-THREE.FunctionNode.prototype.getTypeNode = function( builder, type ) {
+THREE.FunctionNode.prototype.getType = function( builder ) {
 
 
-	return builder.getTypeByFormat( type ) || type;
+	return builder.getTypeByFormat( this.type );
 
 
 };
 };
 
 
@@ -50,13 +48,7 @@ THREE.FunctionNode.prototype.getInputByName = function( name ) {
 
 
 };
 };
 
 
-THREE.FunctionNode.prototype.getType = function( builder ) {
-
-	return this.getTypeNode( builder, this.type );
-
-};
-
-THREE.FunctionNode.prototype.getInclude = function( name ) {
+THREE.FunctionNode.prototype.getIncludeByName = function( name ) {
 
 
 	var i = this.includes.length;
 	var i = this.includes.length;
 
 
@@ -67,93 +59,145 @@ THREE.FunctionNode.prototype.getInclude = function( name ) {
 
 
 	}
 	}
 
 
-	return undefined;
-
 };
 };
 
 
-THREE.FunctionNode.prototype.parse = function( src, includes, extensions ) {
-
-	var rDeclaration = /^([a-z_0-9]+)\s([a-z_0-9]+)\s?\((.*?)\)/i;
-	var rProperties = /[a-z_0-9]+/ig;
+THREE.FunctionNode.prototype.generate = function( builder, output ) {
 
 
-	this.includes = includes || [];
-	this.extensions = extensions || {};
+	var match, offset = 0, src = this.value;
 
 
-	var match = src.match( rDeclaration );
+	for ( var i = 0; i < this.includes.length; i ++ ) {
 
 
-	this.inputs = [];
+		builder.include( this.includes[ i ], this );
 
 
-	if ( match && match.length == 4 ) {
-
-		this.type = match[ 1 ];
-		this.name = match[ 2 ];
+	}
 
 
-		var inputs = match[ 3 ].match( rProperties );
+	for ( var ext in this.extensions ) {
 
 
-		if ( inputs ) {
+		builder.material.extensions[ ext ] = true;
 
 
-			var i = 0;
+	}
 
 
-			while ( i < inputs.length ) {
+	while ( match = THREE.FunctionNode.rProperties.exec( this.value ) ) {
 
 
-				var qualifier = inputs[ i ++ ];
-				var type, name;
+		var prop = match[ 0 ], isGlobal = this.isMethod ? ! this.getInputByName( prop ) : true;
+		var reference = prop;
 
 
-				if ( qualifier == 'in' || qualifier == 'out' || qualifier == 'inout' ) {
+		if ( this.keywords[ prop ] || ( this.useKeywords && isGlobal && THREE.NodeLib.containsKeyword( prop ) ) ) {
 
 
-					type = inputs[ i ++ ];
+			var node = this.keywords[ prop ];
 
 
-				}
-				else {
+			if ( ! node ) {
 
 
-					type = qualifier;
-					qualifier = '';
+				var keyword = THREE.NodeLib.getKeywordData( prop );
 
 
-				}
+				if ( keyword.cache ) node = builder.keywords[ prop ];
 
 
-				name = inputs[ i ++ ];
+				node = node || THREE.NodeLib.getKeyword( prop, builder );
 
 
-				this.inputs.push( {
-					name : name,
-					type : type,
-					qualifier : qualifier
-				} );
+				if ( keyword.cache ) builder.keywords[ prop ] = node;
 
 
 			}
 			}
 
 
+			reference = node.build( builder );
+
 		}
 		}
 
 
-		var match, offset = 0;
+		if ( prop != reference ) {
 
 
-		while ( match = rProperties.exec( src ) ) {
+			src = src.substring( 0, match.index + offset ) + reference + src.substring( match.index + prop.length + offset );
 
 
-			var prop = match[ 0 ];
-			var reference = this.parseReference( prop );
+			offset += reference.length - prop.length;
 
 
-			if ( prop != reference ) {
+		}
 
 
-				src = src.substring( 0, match.index + offset ) + reference + src.substring( match.index + prop.length + offset );
+		if ( this.getIncludeByName( reference ) === undefined && THREE.NodeLib.contains( reference ) ) {
 
 
-				offset += reference.length - prop.length;
+			builder.include( THREE.NodeLib.get( reference ) );
 
 
-			}
+		}
 
 
-			if ( this.getInclude( reference ) === undefined && THREE.NodeLib.contains( reference ) ) {
+	}
 
 
-				this.includes.push( THREE.NodeLib.get( reference ) );
+	if ( output === 'source' ) {
 
 
-			}
+		return src;
 
 
-		}
+	} else if ( this.isMethod ) {
+
+		builder.include( this, false, src );
+
+		return this.name;
 
 
-		this.src = src;
+	} else {
+
+		return builder.format( "(" + src + ")", this.getType( builder ), output );
 
 
 	}
 	}
-	else {
 
 
-		this.type = '';
-		this.name = '';
+};
+
+THREE.FunctionNode.prototype.eval = function( src, includes, extensions, keywords ) {
+
+	src = ( src || '' ).trim();
+
+	this.includes = includes || [];
+	this.extensions = extensions || {};
+	this.keywords = keywords || {};
+
+	if ( this.isMethod ) {
+
+		var match = src.match( THREE.FunctionNode.rDeclaration );
+
+		this.inputs = [];
+
+		if ( match && match.length == 4 ) {
+
+			this.type = match[ 1 ];
+			this.name = match[ 2 ];
+
+			var inputs = match[ 3 ].match( THREE.FunctionNode.rProperties );
+
+			if ( inputs ) {
+
+				var i = 0;
+
+				while ( i < inputs.length ) {
+
+					var qualifier = inputs[ i ++ ];
+					var type, name;
+
+					if ( qualifier == 'in' || qualifier == 'out' || qualifier == 'inout' ) {
+
+						type = inputs[ i ++ ];
+
+					} else {
+
+						type = qualifier;
+						qualifier = '';
+
+					}
+
+					name = inputs[ i ++ ];
+
+					this.inputs.push( {
+						name : name,
+						type : type,
+						qualifier : qualifier
+					} );
+
+				}
+
+			}
+
+		} else {
+
+			this.type = '';
+			this.name = '';
+
+		}
 
 
 	}
 	}
 
 
+	this.value = src;
+
 };
 };

+ 24 - 18
examples/js/nodes/GLNode.js

@@ -6,48 +6,54 @@ THREE.GLNode = function( type ) {
 
 
 	this.uuid = THREE.Math.generateUUID();
 	this.uuid = THREE.Math.generateUUID();
 
 
-	this.allow = {};
+	this.allows = {};
 	this.requestUpdate = false;
 	this.requestUpdate = false;
 
 
 	this.type = type;
 	this.type = type;
 
 
 };
 };
 
 
-THREE.GLNode.prototype.parse = function( builder, cache, requires ) {
+THREE.GLNode.prototype.parse = function( builder, context ) {
+
+	context = context || {};
 
 
 	builder.parsing = true;
 	builder.parsing = true;
 
 
 	var material = builder.material;
 	var material = builder.material;
 
 
-	this.build( builder.addCache( cache, requires ), 'v4' );
+	this.build( builder.addCache( context.cache, context.requires ).addSlot( context.slot ), 'v4' );
 
 
 	material.clearVertexNode();
 	material.clearVertexNode();
 	material.clearFragmentNode();
 	material.clearFragmentNode();
 
 
-	builder.removeCache();
+	builder.removeCache().removeSlot();
 
 
 	builder.parsing = false;
 	builder.parsing = false;
 
 
 };
 };
 
 
-THREE.GLNode.prototype.parseAndBuildCode = function( builder, output, cache, requires ) {
+THREE.GLNode.prototype.parseAndBuildCode = function( builder, output, context ) {
+
+	context = context || {};
 
 
-	this.parse( builder, cache, requires );
+	this.parse( builder, context );
 
 
-	return this.buildCode( builder, output, cache, requires );
+	return this.buildCode( builder, output, context );
 
 
 };
 };
 
 
-THREE.GLNode.prototype.buildCode = function( builder, output, cache, requires ) {
+THREE.GLNode.prototype.buildCode = function( builder, output, context ) {
+
+	context = context || {};
 
 
 	var material = builder.material;
 	var material = builder.material;
 
 
-	var data = { result : this.build( builder.addCache( cache, requires ), output ) };
+	var data = { result : this.build( builder.addCache( context.cache, context.requires ).addSlot( context.slot ), output ) };
 
 
 	if ( builder.isShader( 'vertex' ) ) data.code = material.clearVertexNode();
 	if ( builder.isShader( 'vertex' ) ) data.code = material.clearVertexNode();
 	else data.code = material.clearFragmentNode();
 	else data.code = material.clearFragmentNode();
 
 
-	builder.removeCache();
+	builder.removeCache().removeSlot();
 
 
 	return data;
 	return data;
 
 
@@ -55,21 +61,21 @@ THREE.GLNode.prototype.buildCode = function( builder, output, cache, requires )
 
 
 THREE.GLNode.prototype.build = function( builder, output, uuid ) {
 THREE.GLNode.prototype.build = function( builder, output, uuid ) {
 
 
-	var material = builder.material;
-	var data = material.getDataNode( uuid || this.uuid );
+	output = output || this.getType( builder, output );
+
+	var material = builder.material, data = material.getDataNode( uuid || this.uuid );
 
 
 	if ( builder.parsing ) this.appendDepsNode( builder, data, output );
 	if ( builder.parsing ) this.appendDepsNode( builder, data, output );
 
 
-	if ( this.allow[ builder.shader ] === false ) {
+	if ( this.allows[ builder.shader ] === false ) {
 
 
 		throw new Error( 'Shader ' + shader + ' is not compatible with this node.' );
 		throw new Error( 'Shader ' + shader + ' is not compatible with this node.' );
 
 
 	}
 	}
 
 
-	if ( this.requestUpdate && ! data.requestUpdate ) {
+	if ( this.requestUpdate && material.requestUpdate.indexOf( this ) === - 1 ) {
 
 
 		material.requestUpdate.push( this );
 		material.requestUpdate.push( this );
-		data.requestUpdate = true;
 
 
 	}
 	}
 
 
@@ -83,7 +89,7 @@ THREE.GLNode.prototype.appendDepsNode = function( builder, data, output ) {
 
 
 	var outputLen = builder.getFormatLength( output );
 	var outputLen = builder.getFormatLength( output );
 
 
-	if ( outputLen > ( data.outputMax || 0 ) || this.getType( builder ) ) {
+	if ( outputLen > ( data.outputMax || 0 ) || this.getType( builder, output ) ) {
 
 
 		data.outputMax = outputLen;
 		data.outputMax = outputLen;
 		data.output = output;
 		data.output = output;
@@ -92,8 +98,8 @@ THREE.GLNode.prototype.appendDepsNode = function( builder, data, output ) {
 
 
 };
 };
 
 
-THREE.GLNode.prototype.getType = function( builder ) {
+THREE.GLNode.prototype.getType = function( builder, output ) {
 
 
-	return this.type;
+	return output === 'sampler2D' || output === 'samplerCube' ? output : this.type;
 
 
 };
 };

+ 4 - 2
examples/js/nodes/InputNode.js

@@ -4,6 +4,9 @@
 
 
 THREE.InputNode = function( type, params ) {
 THREE.InputNode = function( type, params ) {
 
 
+	params = params || {};
+	params.shared = params.shared !== undefined ? params.shared : false;
+
 	THREE.TempNode.call( this, type, params );
 	THREE.TempNode.call( this, type, params );
 
 
 };
 };
@@ -30,8 +33,7 @@ THREE.InputNode.prototype.generate = function( builder, output, uuid, type, ns,
 
 
 		return builder.format( data.vertex.name, type, output );
 		return builder.format( data.vertex.name, type, output );
 
 
-	}
-	else {
+	} else {
 
 
 		if ( ! data.fragment ) {
 		if ( ! data.fragment ) {
 
 

+ 258 - 0
examples/js/nodes/NodeBuilder.js

@@ -0,0 +1,258 @@
+/**
+ * @author sunag / http://www.sunag.com.br/
+ */
+
+THREE.NodeBuilder = function( material ) {
+
+	this.material = material;
+
+	this.caches = [];
+	this.slots = [];
+
+	this.keywords = {};
+
+	this.parsing = false;
+	this.optimize = true;
+
+	this.update();
+
+};
+
+THREE.NodeBuilder.type = {
+	float : 'fv1',
+	vec2 : 'v2',
+	vec3 : 'v3',
+	vec4 : 'v4',
+	mat4 : 'v4',
+	int : 'iv1'
+};
+
+THREE.NodeBuilder.constructors = [
+	'float',
+	'vec2',
+	'vec3',
+	'vec4'
+];
+
+THREE.NodeBuilder.elements = [
+	'x',
+	'y',
+	'z',
+	'w'
+];
+
+THREE.NodeBuilder.prototype = {
+
+	constructor: THREE.NodeBuilder,
+
+	addCache : function( name, requires ) {
+
+		this.caches.push( {
+			name : name || '',
+			requires : requires || {}
+		} );
+
+		return this.update();
+
+	},
+
+	removeCache : function() {
+
+		this.caches.pop();
+
+		return this.update();
+
+	},
+
+	addSlot : function( name ) {
+
+		this.slots.push( {
+			name : name || '',
+		} );
+
+		return this.update();
+
+	},
+
+	removeSlot : function() {
+
+		this.slots.pop();
+
+		return this.update();
+
+	},
+
+	isCache : function( name ) {
+
+		var i = this.caches.length;
+
+		while ( i -- ) {
+
+			if ( this.caches[ i ].name == name ) return true;
+
+		}
+
+		return false;
+
+	},
+
+	isSlot : function( name ) {
+
+		var i = this.slots.length;
+
+		while ( i -- ) {
+
+			if ( this.slots[ i ].name == name ) return true;
+
+		}
+
+		return false;
+
+	},
+
+	update : function() {
+
+		var cache = this.caches[ this.caches.length - 1 ];
+		var slot = this.slots[ this.slots.length - 1 ];
+
+		this.slot = slot ? slot.name : '';
+		this.cache = cache ? cache.name : '';
+		this.requires = cache ? cache.requires : {};
+
+		return this;
+
+	},
+
+	require : function( name, node ) {
+
+		this.requires[ name ] = node;
+
+		return this;
+
+	},
+
+	include : function( node, parent, source ) {
+
+		this.material.include( this, node, parent, source );
+
+		return this;
+
+	},
+
+	colorToVector : function( color ) {
+
+		return color.replace( 'r', 'x' ).replace( 'g', 'y' ).replace( 'b', 'z' ).replace( 'a', 'w' );
+
+	},
+
+	getConstructorFromLength : function( len ) {
+
+		return THREE.NodeBuilder.constructors[ len - 1 ];
+
+	},
+
+	getFormatName : function( format ) {
+
+		return format.replace( /c/g, 'v3' ).replace( /fv1/g, 'v1' ).replace( /iv1/g, 'i' );
+
+	},
+
+	isFormatMatrix : function( format ) {
+
+		return /^m/.test( format );
+
+	},
+
+	getFormatLength : function( format ) {
+
+		return parseInt( this.getFormatName( format ).substr( 1 ) );
+
+	},
+
+	getFormatFromLength : function( len ) {
+
+		if ( len == 1 ) return 'fv1';
+
+		return 'v' + len;
+
+	},
+
+	format : function( code, from, to ) {
+
+		var format = this.getFormatName( to + '=' + from );
+
+		switch ( format ) {
+
+			case 'v1=v2': return code + '.x';
+			case 'v1=v3': return code + '.x';
+			case 'v1=v4': return code + '.x';
+			case 'v1=i': return 'float(' + code + ')';
+
+			case 'v2=v1': return 'vec2(' + code + ')';
+			case 'v2=v3': return code + '.xy';
+			case 'v2=v4': return code + '.xy';
+			case 'v2=i': return 'vec2(float(' + code + '))';
+
+			case 'v3=v1': return 'vec3(' + code + ')';
+			case 'v3=v2': return 'vec3(' + code + ',0.0)';
+			case 'v3=v4': return code + '.xyz';
+			case 'v3=i': return 'vec2(float(' + code + '))';
+
+			case 'v4=v1': return 'vec4(' + code + ')';
+			case 'v4=v2': return 'vec4(' + code + ',0.0,1.0)';
+			case 'v4=v3': return 'vec4(' + code + ',1.0)';
+			case 'v4=i': return 'vec4(float(' + code + '))';
+
+			case 'i=v1': return 'int(' + code + ')';
+			case 'i=v2': return 'int(' + code + '.x)';
+			case 'i=v3': return 'int(' + code + '.x)';
+			case 'i=v4': return 'int(' + code + '.x)';
+
+		}
+
+		return code;
+
+	},
+
+	getTypeByFormat : function( format ) {
+
+		return THREE.NodeBuilder.type[ format ] || format;
+
+	},
+
+	getUuid : function( uuid, useCache ) {
+
+		useCache = useCache !== undefined ? useCache : true;
+
+		if ( useCache && this.cache ) uuid = this.cache + '-' + uuid;
+
+		return uuid;
+
+	},
+
+	getElementByIndex : function( index ) {
+
+		return THREE.NodeBuilder.elements[ index ];
+
+	},
+
+	getIndexByElement : function( elm ) {
+
+		return THREE.NodeBuilder.elements.indexOf( elm );
+
+	},
+
+	isShader : function( shader ) {
+
+		return this.shader == shader;
+
+	},
+
+	setShader : function( shader ) {
+
+		this.shader = shader;
+
+		return this;
+
+	}
+};

+ 120 - 40
examples/js/nodes/NodeLib.js

@@ -3,51 +3,131 @@
  */
  */
 
 
 THREE.NodeLib = {
 THREE.NodeLib = {
+
 	nodes: {},
 	nodes: {},
+	keywords: {},
+
 	add: function( node ) {
 	add: function( node ) {
 
 
 		this.nodes[ node.name ] = node;
 		this.nodes[ node.name ] = node;
 
 
 	},
 	},
+
+	addKeyword: function( name, callback, cache ) {
+
+		cache = cache !== undefined ? cache : true;
+
+		this.keywords[ name ] = { callback : callback, cache : cache };
+
+	},
+
 	remove: function( node ) {
 	remove: function( node ) {
 
 
 		delete this.nodes[ node.name ];
 		delete this.nodes[ node.name ];
 
 
 	},
 	},
+
+	removeKeyword: function( name ) {
+
+		delete this.keywords[ node ];
+
+	},
+
 	get: function( name ) {
 	get: function( name ) {
 
 
 		return this.nodes[ name ];
 		return this.nodes[ name ];
 
 
 	},
 	},
+
+	getKeyword: function( name, material ) {
+
+		return this.keywords[ name ].callback.call( this, material );
+
+	},
+
+	getKeywordData: function( name ) {
+
+		return this.keywords[ name ];
+
+	},
+
 	contains: function( name ) {
 	contains: function( name ) {
 
 
 		return this.nodes[ name ] != undefined;
 		return this.nodes[ name ] != undefined;
 
 
+	},
+
+	containsKeyword: function( name ) {
+
+		return this.keywords[ name ] != undefined;
+
 	}
 	}
+
 };
 };
 
 
 //
 //
-//	Luma
+//	Keywords
 //
 //
 
 
-THREE.NodeLib.add( new THREE.ConstNode( "vec3 LUMA = vec3(0.2125, 0.7154, 0.0721);" ) );
+THREE.NodeLib.addKeyword( 'uv', function() {
 
 
-//
-//	DepthColor
-//
+	return new THREE.UVNode();
 
 
-THREE.NodeLib.add( new THREE.FunctionNode( [
-"float depthcolor( float mNear, float mFar ) {",
+} );
 
 
-	"#ifdef USE_LOGDEPTHBUF_EXT",
-		"float depth = gl_FragDepthEXT / gl_FragCoord.w;",
-	"#else",
-		"float depth = gl_FragCoord.z / gl_FragCoord.w;",
-	"#endif",
+THREE.NodeLib.addKeyword( 'uv2', function() {
 
 
-	"return 1.0 - smoothstep( mNear, mFar, depth );",
-"}"
-].join( "\n" ) ) );
+	return new THREE.UVNode( 1 );
+
+} );
+
+THREE.NodeLib.addKeyword( 'position', function() {
+
+	return new THREE.PositionNode();
+
+} );
+
+THREE.NodeLib.addKeyword( 'worldPosition', function() {
+
+	return new THREE.PositionNode( THREE.PositionNode.WORLD );
+
+} );
+
+THREE.NodeLib.addKeyword( 'normal', function() {
+
+	return new THREE.NormalNode();
+
+} );
+
+THREE.NodeLib.addKeyword( 'worldNormal', function() {
+
+	return new THREE.NormalNode( THREE.NormalNode.WORLD );
+
+} );
+
+THREE.NodeLib.addKeyword( 'viewPosition', function() {
+
+	return new THREE.PositionNode( THREE.NormalNode.VIEW );
+
+} );
+
+THREE.NodeLib.addKeyword( 'viewNormal', function() {
+
+	return new THREE.NormalNode( THREE.NormalNode.VIEW );
+
+} );
+
+THREE.NodeLib.addKeyword( 'time', function() {
+
+	return new THREE.TimerNode();
+
+} );
+
+//
+//	Luma
+//
+
+THREE.NodeLib.add( new THREE.ConstNode( "vec3 LUMA vec3(0.2125, 0.7154, 0.0721)" ) );
 
 
 //
 //
 //	NormalMap
 //	NormalMap
@@ -57,17 +137,17 @@ THREE.NodeLib.add( new THREE.FunctionNode( [
 // Per-Pixel Tangent Space Normal Mapping
 // Per-Pixel Tangent Space Normal Mapping
 // http://hacksoflife.blogspot.ch/2009/11/per-pixel-tangent-space-normal-mapping.html
 // http://hacksoflife.blogspot.ch/2009/11/per-pixel-tangent-space-normal-mapping.html
 "vec3 perturbNormal2Arb( vec3 eye_pos, vec3 surf_norm, vec3 map, vec2 mUv, vec2 scale ) {",
 "vec3 perturbNormal2Arb( vec3 eye_pos, vec3 surf_norm, vec3 map, vec2 mUv, vec2 scale ) {",
-	"vec3 q0 = dFdx( eye_pos );",
-	"vec3 q1 = dFdy( eye_pos );",
-	"vec2 st0 = dFdx( mUv.st );",
-	"vec2 st1 = dFdy( mUv.st );",
-	"vec3 S = normalize( q0 * st1.t - q1 * st0.t );",
-	"vec3 T = normalize( -q0 * st1.s + q1 * st0.s );",
-	"vec3 N = normalize( surf_norm );",
-	"vec3 mapN = map * 2.0 - 1.0;",
-	"mapN.xy = scale * mapN.xy;",
-	"mat3 tsn = mat3( S, T, N );",
-	"return normalize( tsn * mapN );",
+"	vec3 q0 = dFdx( eye_pos );",
+"	vec3 q1 = dFdy( eye_pos );",
+"	vec2 st0 = dFdx( mUv.st );",
+"	vec2 st1 = dFdy( mUv.st );",
+"	vec3 S = normalize( q0 * st1.t - q1 * st0.t );",
+"	vec3 T = normalize( -q0 * st1.s + q1 * st0.s );",
+"	vec3 N = normalize( surf_norm );",
+"	vec3 mapN = map * 2.0 - 1.0;",
+"	mapN.xy = scale * mapN.xy;",
+"	mat3 tsn = mat3( S, T, N );",
+"	return normalize( tsn * mapN );",
 "}"
 "}"
 ].join( "\n" ), null, { derivatives: true } ) );
 ].join( "\n" ), null, { derivatives: true } ) );
 
 
@@ -77,7 +157,7 @@ THREE.NodeLib.add( new THREE.FunctionNode( [
 
 
 THREE.NodeLib.add( new THREE.FunctionNode( [
 THREE.NodeLib.add( new THREE.FunctionNode( [
 "float snoise(vec2 co) {",
 "float snoise(vec2 co) {",
-	"return fract( sin( dot(co.xy, vec2(12.9898,78.233) ) ) * 43758.5453 );",
+"	return fract( sin( dot(co.xy, vec2(12.9898,78.233) ) ) * 43758.5453 );",
 "}"
 "}"
 ].join( "\n" ) ) );
 ].join( "\n" ) ) );
 
 
@@ -87,12 +167,12 @@ THREE.NodeLib.add( new THREE.FunctionNode( [
 
 
 THREE.NodeLib.add( new THREE.FunctionNode( [
 THREE.NodeLib.add( new THREE.FunctionNode( [
 "vec3 hue_rgb(vec3 rgb, float adjustment) {",
 "vec3 hue_rgb(vec3 rgb, float adjustment) {",
-	"const mat3 RGBtoYIQ = mat3(0.299, 0.587, 0.114, 0.595716, -0.274453, -0.321263, 0.211456, -0.522591, 0.311135);",
-	"const mat3 YIQtoRGB = mat3(1.0, 0.9563, 0.6210, 1.0, -0.2721, -0.6474, 1.0, -1.107, 1.7046);",
-	"vec3 yiq = RGBtoYIQ * rgb;",
-	"float hue = atan(yiq.z, yiq.y) + adjustment;",
-	"float chroma = sqrt(yiq.z * yiq.z + yiq.y * yiq.y);",
-	"return YIQtoRGB * vec3(yiq.x, chroma * cos(hue), chroma * sin(hue));",
+"	const mat3 RGBtoYIQ = mat3(0.299, 0.587, 0.114, 0.595716, -0.274453, -0.321263, 0.211456, -0.522591, 0.311135);",
+"	const mat3 YIQtoRGB = mat3(1.0, 0.9563, 0.6210, 1.0, -0.2721, -0.6474, 1.0, -1.107, 1.7046);",
+"	vec3 yiq = RGBtoYIQ * rgb;",
+"	float hue = atan(yiq.z, yiq.y) + adjustment;",
+"	float chroma = sqrt(yiq.z * yiq.z + yiq.y * yiq.y);",
+"	return YIQtoRGB * vec3(yiq.x, chroma * cos(hue), chroma * sin(hue));",
 "}"
 "}"
 ].join( "\n" ) ) );
 ].join( "\n" ) ) );
 
 
@@ -103,8 +183,8 @@ THREE.NodeLib.add( new THREE.FunctionNode( [
 THREE.NodeLib.add( new THREE.FunctionNode( [
 THREE.NodeLib.add( new THREE.FunctionNode( [
 // Algorithm from Chapter 16 of OpenGL Shading Language
 // Algorithm from Chapter 16 of OpenGL Shading Language
 "vec3 saturation_rgb(vec3 rgb, float adjustment) {",
 "vec3 saturation_rgb(vec3 rgb, float adjustment) {",
-	"vec3 intensity = vec3(dot(rgb, LUMA));",
-	"return mix(intensity, rgb, adjustment);",
+"	vec3 intensity = vec3(dot(rgb, LUMA));",
+"	return mix(intensity, rgb, adjustment);",
 "}"
 "}"
 ].join( "\n" ) ) );
 ].join( "\n" ) ) );
 
 
@@ -115,7 +195,7 @@ THREE.NodeLib.add( new THREE.FunctionNode( [
 THREE.NodeLib.add( new THREE.FunctionNode( [
 THREE.NodeLib.add( new THREE.FunctionNode( [
 // Algorithm from Chapter 10 of Graphics Shaders
 // Algorithm from Chapter 10 of Graphics Shaders
 "float luminance_rgb(vec3 rgb) {",
 "float luminance_rgb(vec3 rgb) {",
-	"return dot(rgb, LUMA);",
+"	return dot(rgb, LUMA);",
 "}"
 "}"
 ].join( "\n" ) ) );
 ].join( "\n" ) ) );
 
 
@@ -126,9 +206,9 @@ THREE.NodeLib.add( new THREE.FunctionNode( [
 THREE.NodeLib.add( new THREE.FunctionNode( [
 THREE.NodeLib.add( new THREE.FunctionNode( [
 // Shader by Evan Wallace adapted by @lo-th
 // Shader by Evan Wallace adapted by @lo-th
 "vec3 vibrance_rgb(vec3 rgb, float adjustment) {",
 "vec3 vibrance_rgb(vec3 rgb, float adjustment) {",
-	"float average = (rgb.r + rgb.g + rgb.b) / 3.0;",
-	"float mx = max(rgb.r, max(rgb.g, rgb.b));",
-	"float amt = (mx - average) * (-3.0 * adjustment);",
-	"return mix(rgb.rgb, vec3(mx), amt);",
+"	float average = (rgb.r + rgb.g + rgb.b) / 3.0;",
+"	float mx = max(rgb.r, max(rgb.g, rgb.b));",
+"	float amt = (mx - average) * (-3.0 * adjustment);",
+"	return mix(rgb.rgb, vec3(mx), amt);",
 "}"
 "}"
 ].join( "\n" ) ) );
 ].join( "\n" ) ) );

+ 107 - 46
examples/js/nodes/NodeMaterial.js

@@ -64,11 +64,11 @@ THREE.NodeMaterial.addShortcuts = function( proto, prop, list ) {
 THREE.NodeMaterial.prototype = Object.create( THREE.ShaderMaterial.prototype );
 THREE.NodeMaterial.prototype = Object.create( THREE.ShaderMaterial.prototype );
 THREE.NodeMaterial.prototype.constructor = THREE.NodeMaterial;
 THREE.NodeMaterial.prototype.constructor = THREE.NodeMaterial;
 
 
-THREE.NodeMaterial.prototype.updateAnimation = function( delta ) {
+THREE.NodeMaterial.prototype.updateFrame = function( delta ) {
 
 
 	for ( var i = 0; i < this.requestUpdate.length; ++ i ) {
 	for ( var i = 0; i < this.requestUpdate.length; ++ i ) {
 
 
-		this.requestUpdate[ i ].updateAnimation( delta );
+		this.requestUpdate[ i ].updateFrame( delta );
 
 
 	}
 	}
 
 
@@ -80,12 +80,14 @@ THREE.NodeMaterial.prototype.build = function() {
 
 
 	this.defines = {};
 	this.defines = {};
 	this.uniforms = {};
 	this.uniforms = {};
+	this.attributes = {};
 
 
 	this.nodeData = {};
 	this.nodeData = {};
 
 
 	this.vertexUniform = [];
 	this.vertexUniform = [];
 	this.fragmentUniform = [];
 	this.fragmentUniform = [];
 
 
+	this.vars = [];
 	this.vertexTemps = [];
 	this.vertexTemps = [];
 	this.fragmentTemps = [];
 	this.fragmentTemps = [];
 
 
@@ -96,7 +98,7 @@ THREE.NodeMaterial.prototype.build = function() {
 
 
 	this.requestUpdate = [];
 	this.requestUpdate = [];
 
 
-	this.requestAttrib = {
+	this.requestAttribs = {
 		uv: [],
 		uv: [],
 		color: []
 		color: []
 	};
 	};
@@ -130,12 +132,12 @@ THREE.NodeMaterial.prototype.build = function() {
 	"#endif"
 	"#endif"
 	].join( "\n" );
 	].join( "\n" );
 
 
-	var builder = new THREE.BuilderNode( this );
+	var builder = new THREE.NodeBuilder( this );
 
 
 	vertex = this.vertex.build( builder.setShader( 'vertex' ), 'v4' );
 	vertex = this.vertex.build( builder.setShader( 'vertex' ), 'v4' );
 	fragment = this.fragment.build( builder.setShader( 'fragment' ), 'v4' );
 	fragment = this.fragment.build( builder.setShader( 'fragment' ), 'v4' );
 
 
-	if ( this.requestAttrib.uv[ 0 ] ) {
+	if ( this.requestAttribs.uv[ 0 ] ) {
 
 
 		this.addVertexPars( 'varying vec2 vUv;' );
 		this.addVertexPars( 'varying vec2 vUv;' );
 		this.addFragmentPars( 'varying vec2 vUv;' );
 		this.addFragmentPars( 'varying vec2 vUv;' );
@@ -144,7 +146,7 @@ THREE.NodeMaterial.prototype.build = function() {
 
 
 	}
 	}
 
 
-	if ( this.requestAttrib.uv[ 1 ] ) {
+	if ( this.requestAttribs.uv[ 1 ] ) {
 
 
 		this.addVertexPars( 'varying vec2 vUv2; attribute vec2 uv2;' );
 		this.addVertexPars( 'varying vec2 vUv2; attribute vec2 uv2;' );
 		this.addFragmentPars( 'varying vec2 vUv2;' );
 		this.addFragmentPars( 'varying vec2 vUv2;' );
@@ -153,7 +155,7 @@ THREE.NodeMaterial.prototype.build = function() {
 
 
 	}
 	}
 
 
-	if ( this.requestAttrib.color[ 0 ] ) {
+	if ( this.requestAttribs.color[ 0 ] ) {
 
 
 		this.addVertexPars( 'varying vec4 vColor; attribute vec4 color;' );
 		this.addVertexPars( 'varying vec4 vColor; attribute vec4 color;' );
 		this.addFragmentPars( 'varying vec4 vColor;' );
 		this.addFragmentPars( 'varying vec4 vColor;' );
@@ -162,7 +164,7 @@ THREE.NodeMaterial.prototype.build = function() {
 
 
 	}
 	}
 
 
-	if ( this.requestAttrib.color[ 1 ] ) {
+	if ( this.requestAttribs.color[ 1 ] ) {
 
 
 		this.addVertexPars( 'varying vec4 vColor2; attribute vec4 color2;' );
 		this.addVertexPars( 'varying vec4 vColor2; attribute vec4 color2;' );
 		this.addFragmentPars( 'varying vec4 vColor2;' );
 		this.addFragmentPars( 'varying vec4 vColor2;' );
@@ -171,7 +173,7 @@ THREE.NodeMaterial.prototype.build = function() {
 
 
 	}
 	}
 
 
-	if ( this.requestAttrib.position ) {
+	if ( this.requestAttribs.position ) {
 
 
 		this.addVertexPars( 'varying vec3 vPosition;' );
 		this.addVertexPars( 'varying vec3 vPosition;' );
 		this.addFragmentPars( 'varying vec3 vPosition;' );
 		this.addFragmentPars( 'varying vec3 vPosition;' );
@@ -180,7 +182,7 @@ THREE.NodeMaterial.prototype.build = function() {
 
 
 	}
 	}
 
 
-	if ( this.requestAttrib.worldPosition ) {
+	if ( this.requestAttribs.worldPosition ) {
 
 
 		// for future update replace from the native "varying vec3 vWorldPosition" for optimization
 		// for future update replace from the native "varying vec3 vWorldPosition" for optimization
 
 
@@ -191,7 +193,7 @@ THREE.NodeMaterial.prototype.build = function() {
 
 
 	}
 	}
 
 
-	if ( this.requestAttrib.normal ) {
+	if ( this.requestAttribs.normal ) {
 
 
 		this.addVertexPars( 'varying vec3 vObjectNormal;' );
 		this.addVertexPars( 'varying vec3 vObjectNormal;' );
 		this.addFragmentPars( 'varying vec3 vObjectNormal;' );
 		this.addFragmentPars( 'varying vec3 vObjectNormal;' );
@@ -200,7 +202,7 @@ THREE.NodeMaterial.prototype.build = function() {
 
 
 	}
 	}
 
 
-	if ( this.requestAttrib.worldNormal ) {
+	if ( this.requestAttribs.worldNormal ) {
 
 
 		this.addVertexPars( 'varying vec3 vWNormal;' );
 		this.addVertexPars( 'varying vec3 vWNormal;' );
 		this.addFragmentPars( 'varying vec3 vWNormal;' );
 		this.addFragmentPars( 'varying vec3 vWNormal;' );
@@ -209,8 +211,8 @@ THREE.NodeMaterial.prototype.build = function() {
 
 
 	}
 	}
 
 
-	this.lights = this.requestAttrib.light;
-	this.transparent = this.requestAttrib.transparent || (this.blendMode !== THREE.NormalBlending && this.blendMode !== THREE.NoBlending);
+	this.lights = this.requestAttribs.light;
+	this.transparent = this.requestAttribs.transparent || this.blendMode > THREE.NormalBlending;
 
 
 	this.vertexShader = [
 	this.vertexShader = [
 		this.prefixCode,
 		this.prefixCode,
@@ -286,43 +288,89 @@ THREE.NodeMaterial.prototype.createUniform = function( type, value, ns, needsUpd
 
 
 THREE.NodeMaterial.prototype.getVertexTemp = function( uuid, type, ns ) {
 THREE.NodeMaterial.prototype.getVertexTemp = function( uuid, type, ns ) {
 
 
-	if ( ! this.vertexTemps[ uuid ] ) {
+	var data = this.vertexTemps[ uuid ];
+
+	if ( ! data ) {
 
 
 		var index = this.vertexTemps.length,
 		var index = this.vertexTemps.length,
-			name = ns ? ns : 'nVt' + index,
-			data = { name : name, type : type };
+			name = ns ? ns : 'nVt' + index;
+
+		data = { name : name, type : type };
 
 
 		this.vertexTemps.push( data );
 		this.vertexTemps.push( data );
 		this.vertexTemps[ uuid ] = data;
 		this.vertexTemps[ uuid ] = data;
 
 
 	}
 	}
 
 
-	return this.vertexTemps[ uuid ];
+	return data;
 
 
 };
 };
 
 
 THREE.NodeMaterial.prototype.getFragmentTemp = function( uuid, type, ns ) {
 THREE.NodeMaterial.prototype.getFragmentTemp = function( uuid, type, ns ) {
 
 
-	if ( ! this.fragmentTemps[ uuid ] ) {
+	var data = this.fragmentTemps[ uuid ];
+
+	if ( ! data ) {
 
 
 		var index = this.fragmentTemps.length,
 		var index = this.fragmentTemps.length,
-			name = ns ? ns : 'nVt' + index,
-			data = { name : name, type : type };
+			name = ns ? ns : 'nVt' + index;
+
+		data = { name : name, type : type };
 
 
 		this.fragmentTemps.push( data );
 		this.fragmentTemps.push( data );
 		this.fragmentTemps[ uuid ] = data;
 		this.fragmentTemps[ uuid ] = data;
 
 
 	}
 	}
 
 
-	return this.fragmentTemps[ uuid ];
+	return data;
 
 
 };
 };
 
 
-THREE.NodeMaterial.prototype.getIncludes = function( incs ) {
+THREE.NodeMaterial.prototype.getVar = function( uuid, type, ns ) {
+
+	var data = this.vars[ uuid ];
+
+	if ( ! data ) {
+
+		var index = this.vars.length,
+			name = ns ? ns : 'nVv' + index;
+
+		data = { name : name, type : type }
+
+		this.vars.push( data );
+		this.vars[ uuid ] = data;
+
+		this.addVertexPars( 'varying ' + type + ' ' + name + ';' );
+		this.addFragmentPars( 'varying ' + type + ' ' + name + ';' );
+
+	}
+
+	return data;
+
+};
+
+THREE.NodeMaterial.prototype.getAttribute = function( name, type ) {
+
+	if ( ! this.attributes[ name ] ) {
+
+		var varying = this.getVar( name, type );
+
+		this.addVertexPars( 'attribute ' + type + ' ' + name + ';' );
+		this.addVertexCode( varying.name + ' = ' + name + ';' );
+
+		this.attributes[ name ] = { varying : varying, name : name, type : type };
+
+	}
+
+	return this.attributes[ name ];
+
+};
+
+THREE.NodeMaterial.prototype.getIncludes = function() {
 
 
 	function sortByPosition( a, b ) {
 	function sortByPosition( a, b ) {
 
 
-		return b.deps - a.deps;
+		return a.deps.length - b.deps.length;
 
 
 	}
 	}
 
 
@@ -330,12 +378,11 @@ THREE.NodeMaterial.prototype.getIncludes = function( incs ) {
 
 
 		if ( ! incs ) return '';
 		if ( ! incs ) return '';
 
 
-		var code = '';
-		var incs = incs.sort( sortByPosition );
+		var code = '', incs = incs.sort( sortByPosition );
 
 
 		for ( var i = 0; i < incs.length; i ++ ) {
 		for ( var i = 0; i < incs.length; i ++ ) {
 
 
-			code += incs[ i ].node.src + '\n';
+			if ( incs[ i ].src ) code += incs[ i ].src + '\n';
 
 
 		}
 		}
 
 
@@ -377,9 +424,9 @@ THREE.NodeMaterial.prototype.addVertexNode = function( code ) {
 
 
 THREE.NodeMaterial.prototype.clearVertexNode = function() {
 THREE.NodeMaterial.prototype.clearVertexNode = function() {
 
 
-	var code = this.fragmentNode;
+	var code = this.vertexNode;
 
 
-	this.fragmentNode = '';
+	this.vertexNode = '';
 
 
 	return code;
 	return code;
 
 
@@ -459,7 +506,7 @@ THREE.NodeMaterial.prototype.getDataNode = function( uuid ) {
 
 
 };
 };
 
 
-THREE.NodeMaterial.prototype.include = function( shader, node ) {
+THREE.NodeMaterial.prototype.include = function( builder, node, parent, source ) {
 
 
 	var includes;
 	var includes;
 
 
@@ -467,37 +514,51 @@ THREE.NodeMaterial.prototype.include = function( shader, node ) {
 
 
 	if ( node instanceof THREE.FunctionNode ) {
 	if ( node instanceof THREE.FunctionNode ) {
 
 
-		for ( var i = 0; i < node.includes.length; i ++ ) {
+		includes = this.functions[ builder.shader ] = this.functions[ builder.shader ] || [];
 
 
-			this.include( shader, node.includes[ i ] );
+	} else if ( node instanceof THREE.ConstNode ) {
 
 
-		}
-
-		includes = this.functions[ shader ] = this.functions[ shader ] || [];
+		includes = this.consts[ builder.shader ] = this.consts[ builder.shader ] || [];
 
 
 	}
 	}
-	else if ( node instanceof THREE.ConstNode ) {
 
 
-		includes = this.consts[ shader ] = this.consts[ shader ] || [];
+	var included = includes[ node.name ];
+
+	if ( ! included ) {
+
+		included = includes[ node.name ] = {
+			node : node,
+			deps : []
+		};
+
+		includes.push( included );
+
+		included.src = node.build( builder, 'source' );
 
 
 	}
 	}
 
 
-	if ( includes[ node.name ] === undefined ) {
+	if ( node instanceof THREE.FunctionNode && parent && includes[ parent.name ] && includes[ parent.name ].deps.indexOf( node ) == - 1 ) {
+
+		includes[ parent.name ].deps.push( node );
+
+		if ( node.includes && node.includes.length ) {
+
+			var i = 0;
 
 
-		for ( var ext in node.extensions ) {
+			do {
 
 
-			this.extensions[ ext ] = true;
+				this.include( builder, node.includes[ i ++ ], parent );
+
+			} while ( i < node.includes.length );
 
 
 		}
 		}
 
 
-		includes[ node.name ] = {
-			node : node,
-			deps : 1
-		};
+	}
+
+	if ( source ) {
 
 
-		includes.push( includes[ node.name ] );
+		included.src = source;
 
 
 	}
 	}
-	else ++ includes[ node.name ].deps;
 
 
 };
 };

+ 1 - 2
examples/js/nodes/RawNode.js

@@ -25,8 +25,7 @@ THREE.GLNode.prototype.generate = function( builder ) {
 
 
 		code += 'gl_Position = ' + data.result + ';';
 		code += 'gl_Position = ' + data.result + ';';
 
 
-	}
-	else {
+	} else {
 
 
 		code += 'gl_FragColor = ' + data.result + ';';
 		code += 'gl_FragColor = ' + data.result + ';';
 
 

+ 11 - 14
examples/js/nodes/TempNode.js

@@ -19,11 +19,13 @@ THREE.TempNode.prototype.constructor = THREE.TempNode;
 
 
 THREE.TempNode.prototype.build = function( builder, output, uuid, ns ) {
 THREE.TempNode.prototype.build = function( builder, output, uuid, ns ) {
 
 
+	output = output || this.getType( builder );
+
 	var material = builder.material;
 	var material = builder.material;
 
 
-	if ( this.isShared() ) {
+	if ( this.isShared( builder, output ) ) {
 
 
-		var isUnique = this.isUnique();
+		var isUnique = this.isUnique( builder, output );
 
 
 		if ( isUnique && this.constructor.uuid === undefined ) {
 		if ( isUnique && this.constructor.uuid === undefined ) {
 
 
@@ -47,8 +49,7 @@ THREE.TempNode.prototype.build = function( builder, output, uuid, ns ) {
 
 
 			return THREE.GLNode.prototype.build.call( this, builder, output, uuid );
 			return THREE.GLNode.prototype.build.call( this, builder, output, uuid );
 
 
-		}
-		else if ( ! builder.optimize || data.deps == 1 ) {
+		} else if ( ! builder.optimize || data.deps == 1 ) {
 
 
 			return THREE.GLNode.prototype.build.call( this, builder, output, uuid );
 			return THREE.GLNode.prototype.build.call( this, builder, output, uuid );
 
 
@@ -63,8 +64,7 @@ THREE.TempNode.prototype.build = function( builder, output, uuid, ns ) {
 
 
 			return builder.format( name, type, output );
 			return builder.format( name, type, output );
 
 
-		}
-		else {
+		} else {
 
 
 			name = THREE.TempNode.prototype.generate.call( this, builder, output, uuid, data.output, ns );
 			name = THREE.TempNode.prototype.generate.call( this, builder, output, uuid, data.output, ns );
 
 
@@ -78,21 +78,18 @@ THREE.TempNode.prototype.build = function( builder, output, uuid, ns ) {
 		}
 		}
 
 
 	}
 	}
-	else {
 
 
-		return builder.format( this.generate( builder, this.getType( builder ), uuid ), this.getType( builder ), output );
-
-	}
+	return THREE.GLNode.prototype.build.call( this, builder, output, uuid );
 
 
 };
 };
 
 
-THREE.TempNode.prototype.isShared = function() {
+THREE.TempNode.prototype.isShared = function( builder, output ) {
 
 
-	return this.shared;
+	return output !== 'sampler2D' && output !== 'samplerCube' && this.shared;
 
 
 };
 };
 
 
-THREE.TempNode.prototype.isUnique = function() {
+THREE.TempNode.prototype.isUnique = function( builder, output ) {
 
 
 	return this.unique;
 	return this.unique;
 
 
@@ -121,7 +118,7 @@ THREE.TempNode.prototype.getTemp = function( builder, uuid ) {
 
 
 THREE.TempNode.prototype.generate = function( builder, output, uuid, type, ns ) {
 THREE.TempNode.prototype.generate = function( builder, output, uuid, type, ns ) {
 
 
-	if ( ! this.isShared() ) console.error( "THREE.TempNode is not shared!" );
+	if ( ! this.isShared( builder, output ) ) console.error( "THREE.TempNode is not shared!" );
 
 
 	uuid = uuid || this.uuid;
 	uuid = uuid || this.uuid;
 
 

+ 26 - 0
examples/js/nodes/VarNode.js

@@ -0,0 +1,26 @@
+/**
+ * @author sunag / http://www.sunag.com.br/
+ */
+
+THREE.VarNode = function( type ) {
+
+	THREE.GLNode.call( this, type );
+
+};
+
+THREE.VarNode.prototype = Object.create( THREE.GLNode.prototype );
+THREE.VarNode.prototype.constructor = THREE.VarNode;
+
+THREE.VarNode.prototype.getType = function( builder ) {
+
+	return builder.getTypeByFormat( this.type );
+
+};
+
+THREE.VarNode.prototype.generate = function( builder, output ) {
+
+	var varying = builder.material.getVar( this.uuid, this.type );
+
+	return builder.format( varying.name, this.getType( builder ), output );
+
+};

+ 16 - 3
examples/js/nodes/accessors/CameraNode.js

@@ -11,6 +11,17 @@ THREE.CameraNode = function( scope, camera ) {
 
 
 };
 };
 
 
+THREE.CameraNode.fDepthColor = new THREE.FunctionNode( [
+"float depthColor( float mNear, float mFar ) {",
+"	#ifdef USE_LOGDEPTHBUF_EXT",
+"		float depth = gl_FragDepthEXT / gl_FragCoord.w;",
+"	#else",
+"		float depth = gl_FragCoord.z / gl_FragCoord.w;",
+"	#endif",
+"	return 1.0 - smoothstep( mNear, mFar, depth );",
+"}"
+].join( "\n" ) );
+
 THREE.CameraNode.POSITION = 'position';
 THREE.CameraNode.POSITION = 'position';
 THREE.CameraNode.DEPTH = 'depth';
 THREE.CameraNode.DEPTH = 'depth';
 THREE.CameraNode.TO_VERTEX = 'toVertex';
 THREE.CameraNode.TO_VERTEX = 'toVertex';
@@ -102,9 +113,11 @@ THREE.CameraNode.prototype.generate = function( builder, output ) {
 
 
 		case THREE.CameraNode.DEPTH:
 		case THREE.CameraNode.DEPTH:
 
 
-			builder.include( 'depthcolor' );
+			var func = THREE.CameraNode.fDepthColor;
+
+			builder.include( func );
 
 
-			result = 'depthcolor(' + this.near.build( builder, 'fv1' ) + ',' + this.far.build( builder, 'fv1' ) + ')';
+			result = func.name + '(' + this.near.build( builder, 'fv1' ) + ',' + this.far.build( builder, 'fv1' ) + ')';
 
 
 			break;
 			break;
 
 
@@ -120,7 +133,7 @@ THREE.CameraNode.prototype.generate = function( builder, output ) {
 
 
 };
 };
 
 
-THREE.CameraNode.prototype.updateAnimation = function( delta ) {
+THREE.CameraNode.prototype.updateFrame = function( delta ) {
 
 
 	switch ( this.scope ) {
 	switch ( this.scope ) {
 
 

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

@@ -4,7 +4,7 @@
 
 
 THREE.ColorsNode = function( index ) {
 THREE.ColorsNode = function( index ) {
 
 
-	THREE.TempNode.call( this, 'v4', { share: false } );
+	THREE.TempNode.call( this, 'v4', { shared: false } );
 
 
 	this.index = index || 0;
 	this.index = index || 0;
 
 
@@ -21,7 +21,7 @@ THREE.ColorsNode.prototype.generate = function( builder, output ) {
 	var material = builder.material;
 	var material = builder.material;
 	var result;
 	var result;
 
 
-	material.requestAttrib.color[ this.index ] = true;
+	material.requestAttribs.color[ this.index ] = true;
 
 
 	if ( builder.isShader( 'vertex' ) ) result = THREE.ColorsNode.vertexDict[ this.index ];
 	if ( builder.isShader( 'vertex' ) ) result = THREE.ColorsNode.vertexDict[ this.index ];
 	else result = THREE.ColorsNode.fragmentDict[ this.index ];
 	else result = THREE.ColorsNode.fragmentDict[ this.index ];

+ 1 - 2
examples/js/nodes/accessors/LightNode.js

@@ -17,8 +17,7 @@ THREE.LightNode.prototype.generate = function( builder, output ) {
 
 
 		return builder.format( 'reflectedLight.directDiffuse', this.getType( builder ), output )
 		return builder.format( 'reflectedLight.directDiffuse', this.getType( builder ), output )
 
 
-	}
-	else {
+	} else {
 
 
 		console.warn( "THREE.LightNode is only compatible in \"light\" channel." );
 		console.warn( "THREE.LightNode is only compatible in \"light\" channel." );
 
 

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

@@ -37,7 +37,7 @@ THREE.NormalNode.prototype.generate = function( builder, output ) {
 
 
 		case THREE.NormalNode.LOCAL:
 		case THREE.NormalNode.LOCAL:
 
 
-			material.requestAttrib.normal = true;
+			material.requestAttribs.normal = true;
 
 
 			if ( builder.isShader( 'vertex' ) ) result = 'normal';
 			if ( builder.isShader( 'vertex' ) ) result = 'normal';
 			else result = 'vObjectNormal';
 			else result = 'vObjectNormal';
@@ -46,7 +46,7 @@ THREE.NormalNode.prototype.generate = function( builder, output ) {
 
 
 		case THREE.NormalNode.WORLD:
 		case THREE.NormalNode.WORLD:
 
 
-			material.requestAttrib.worldNormal = true;
+			material.requestAttribs.worldNormal = true;
 
 
 			if ( builder.isShader( 'vertex' ) ) result = '( modelMatrix * vec4( objectNormal, 0.0 ) ).xyz';
 			if ( builder.isShader( 'vertex' ) ) result = '( modelMatrix * vec4( objectNormal, 0.0 ) ).xyz';
 			else result = 'vWNormal';
 			else result = 'vWNormal';

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

@@ -50,7 +50,7 @@ THREE.PositionNode.prototype.generate = function( builder, output ) {
 
 
 		case THREE.PositionNode.LOCAL:
 		case THREE.PositionNode.LOCAL:
 
 
-			material.requestAttrib.position = true;
+			material.requestAttribs.position = true;
 
 
 			if ( builder.isShader( 'vertex' ) ) result = 'transformed';
 			if ( builder.isShader( 'vertex' ) ) result = 'transformed';
 			else result = 'vPosition';
 			else result = 'vPosition';
@@ -59,7 +59,7 @@ THREE.PositionNode.prototype.generate = function( builder, output ) {
 
 
 		case THREE.PositionNode.WORLD:
 		case THREE.PositionNode.WORLD:
 
 
-			material.requestAttrib.worldPosition = true;
+			material.requestAttribs.worldPosition = true;
 
 
 			if ( builder.isShader( 'vertex' ) ) result = 'vWPosition';
 			if ( builder.isShader( 'vertex' ) ) result = 'vWPosition';
 			else result = 'vWPosition';
 			else result = 'vWPosition';

+ 3 - 3
examples/js/nodes/accessors/ReflectNode.js

@@ -20,7 +20,7 @@ THREE.ReflectNode.prototype.constructor = THREE.ReflectNode;
 THREE.ReflectNode.prototype.getType = function( builder ) {
 THREE.ReflectNode.prototype.getType = function( builder ) {
 
 
 	switch ( this.scope ) {
 	switch ( this.scope ) {
-		case THREE.CameraNode.SPHERE:
+		case THREE.ReflectNode.SPHERE:
 			return 'v2';
 			return 'v2';
 	}
 	}
 
 
@@ -36,7 +36,7 @@ THREE.ReflectNode.prototype.generate = function( builder, output ) {
 
 
 		case THREE.ReflectNode.VECTOR:
 		case THREE.ReflectNode.VECTOR:
 
 
-			builder.material.addFragmentNode( 'vec3 reflectVec = inverseTransformDirection( reflect( -geometry.viewDir, geometry.normal ), viewMatrix );' );
+			builder.material.addFragmentNode( 'vec3 reflectVec = inverseTransformDirection( reflect( -normalize( vViewPosition ), normal ), viewMatrix );' );
 
 
 			result = 'reflectVec';
 			result = 'reflectVec';
 
 
@@ -56,7 +56,7 @@ THREE.ReflectNode.prototype.generate = function( builder, output ) {
 
 
 			var reflectVec = new THREE.ReflectNode( THREE.ReflectNode.VECTOR ).build( builder, 'v3' );
 			var reflectVec = new THREE.ReflectNode( THREE.ReflectNode.VECTOR ).build( builder, 'v3' );
 
 
-			builder.material.addFragmentNode( 'vec3 reflectSphereVec = normalize((viewMatrix * vec4(' + reflectVec + ', 0.0 )).xyz + vec3(0.0,0.0,1.0)).xy * 0.5 + 0.5;' );
+			builder.material.addFragmentNode( 'vec2 reflectSphereVec = normalize((viewMatrix * vec4(' + reflectVec + ', 0.0 )).xyz + vec3(0.0,0.0,1.0)).xy * 0.5 + 0.5;' );
 
 
 			result = 'reflectSphereVec';
 			result = 'reflectSphereVec';
 
 

+ 1 - 2
examples/js/nodes/accessors/ScreenUVNode.js

@@ -22,8 +22,7 @@ THREE.ScreenUVNode.prototype.generate = function( builder, output ) {
 
 
 		result = '(gl_FragCoord.xy/' + this.resolution.build( builder, 'v2' ) + ')';
 		result = '(gl_FragCoord.xy/' + this.resolution.build( builder, 'v2' ) + ')';
 
 
-	}
-	else {
+	} else {
 
 
 		console.warn( "THREE.ScreenUVNode is not compatible with " + builder.shader + " shader." );
 		console.warn( "THREE.ScreenUVNode is not compatible with " + builder.shader + " shader." );
 
 

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

@@ -21,7 +21,7 @@ THREE.UVNode.prototype.generate = function( builder, output ) {
 	var material = builder.material;
 	var material = builder.material;
 	var result;
 	var result;
 
 
-	material.requestAttrib.uv[ this.index ] = true;
+	material.requestAttribs.uv[ this.index ] = true;
 
 
 	if ( builder.isShader( 'vertex' ) ) result = THREE.UVNode.vertexDict[ this.index ];
 	if ( builder.isShader( 'vertex' ) ) result = THREE.UVNode.vertexDict[ this.index ];
 	else result = THREE.UVNode.fragmentDict[ this.index ];
 	else result = THREE.UVNode.fragmentDict[ this.index ];

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

@@ -4,7 +4,7 @@
 
 
 THREE.ColorNode = function( color ) {
 THREE.ColorNode = function( color ) {
 
 
-	THREE.InputNode.call( this, 'c', { share: false } );
+	THREE.InputNode.call( this, 'c' );
 
 
 	this.value = new THREE.Color( color || 0 );
 	this.value = new THREE.Color( color || 0 );
 
 

+ 21 - 1
examples/js/nodes/inputs/CubeTextureNode.js

@@ -4,7 +4,7 @@
 
 
 THREE.CubeTextureNode = function( value, coord, bias ) {
 THREE.CubeTextureNode = function( value, coord, bias ) {
 
 
-	THREE.InputNode.call( this, 'v4' );
+	THREE.InputNode.call( this, 'v4', { shared : true } );
 
 
 	this.value = value;
 	this.value = value;
 	this.coord = coord || new THREE.ReflectNode();
 	this.coord = coord || new THREE.ReflectNode();
@@ -23,6 +23,12 @@ THREE.CubeTextureNode.prototype.getTexture = function( builder, output ) {
 
 
 THREE.CubeTextureNode.prototype.generate = function( builder, output ) {
 THREE.CubeTextureNode.prototype.generate = function( builder, output ) {
 
 
+	if ( output === 'samplerCube' ) {
+
+		return this.getTexture( builder, output );
+
+	}
+
 	var cubetex = this.getTexture( builder, output );
 	var cubetex = this.getTexture( builder, output );
 	var coord = this.coord.build( builder, 'v3' );
 	var coord = this.coord.build( builder, 'v3' );
 	var bias = this.bias ? this.bias.build( builder, 'fv1' ) : undefined;
 	var bias = this.bias ? this.bias.build( builder, 'fv1' ) : undefined;
@@ -38,6 +44,20 @@ THREE.CubeTextureNode.prototype.generate = function( builder, output ) {
 	if ( bias ) code = 'texCubeBias(' + cubetex + ',' + coord + ',' + bias + ')';
 	if ( bias ) code = 'texCubeBias(' + cubetex + ',' + coord + ',' + bias + ')';
 	else code = 'texCube(' + cubetex + ',' + coord + ')';
 	else code = 'texCube(' + cubetex + ',' + coord + ')';
 
 
+	if ( builder.isSlot( 'color' ) ) {
+
+		code = 'mapTexelToLinear(' + code + ')';
+
+	} else if ( builder.isSlot( 'emissive' ) ) {
+
+		code = 'emissiveMapTexelToLinear(' + code + ')';
+
+	} else if ( builder.isSlot( 'environment' ) ) {
+
+		code = 'envMapTexelToLinear(' + code + ')';
+
+	}
+
 	return builder.format( code, this.type, output );
 	return builder.format( code, this.type, output );
 
 
 };
 };

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

@@ -4,7 +4,7 @@
 
 
 THREE.FloatNode = function( value ) {
 THREE.FloatNode = function( value ) {
 
 
-	THREE.InputNode.call( this, 'fv1', { share: false } );
+	THREE.InputNode.call( this, 'fv1' );
 
 
 	this.value = [ value || 0 ];
 	this.value = [ value || 0 ];
 
 

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

@@ -4,7 +4,7 @@
 
 
 THREE.IntNode = function( value ) {
 THREE.IntNode = function( value ) {
 
 
-	THREE.InputNode.call( this, 'fv1', { share: false } );
+	THREE.InputNode.call( this, 'iv1' );
 
 
 	this.value = [ Math.floor( value || 0 ) ];
 	this.value = [ Math.floor( value || 0 ) ];
 
 

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

@@ -4,7 +4,7 @@
 
 
 THREE.Matrix4Node = function( matrix ) {
 THREE.Matrix4Node = function( matrix ) {
 
 
-	THREE.InputNode.call( this, 'm4', { share: false } );
+	THREE.InputNode.call( this, 'm4' );
 
 
 	this.value = matrix || new THREE.Matrix4();
 	this.value = matrix || new THREE.Matrix4();
 
 

+ 7 - 4
examples/js/nodes/inputs/MirrorNode.js

@@ -27,12 +27,15 @@ THREE.MirrorNode.prototype.generate = function( builder, output ) {
 		this.coordResult.a = this.offset;
 		this.coordResult.a = this.offset;
 		this.texture.coord = this.offset ? this.coordResult : this.coord;
 		this.texture.coord = this.offset ? this.coordResult : this.coord;
 
 
-		var coord = this.texture.build( builder, this.type );
+		if ( output === 'sampler2D' ) {
 
 
-		return builder.format( coord, this.type, output );
+			return this.texture.build( builder, output );
 
 
-	}
-	else {
+		}
+
+		return builder.format( this.texture.build( builder, this.type ), this.type, output );
+
+	} else {
 
 
 		console.warn( "THREE.MirrorNode is not compatible with " + builder.shader + " shader." );
 		console.warn( "THREE.MirrorNode is not compatible with " + builder.shader + " shader." );
 
 

+ 21 - 1
examples/js/nodes/inputs/TextureNode.js

@@ -4,7 +4,7 @@
 
 
 THREE.TextureNode = function( value, coord, bias, project ) {
 THREE.TextureNode = function( value, coord, bias, project ) {
 
 
-	THREE.InputNode.call( this, 'v4' );
+	THREE.InputNode.call( this, 'v4', { shared : true } );
 
 
 	this.value = value;
 	this.value = value;
 	this.coord = coord || new THREE.UVNode();
 	this.coord = coord || new THREE.UVNode();
@@ -24,6 +24,12 @@ THREE.TextureNode.prototype.getTexture = function( builder, output ) {
 
 
 THREE.TextureNode.prototype.generate = function( builder, output ) {
 THREE.TextureNode.prototype.generate = function( builder, output ) {
 
 
+	if ( output === 'sampler2D' ) {
+
+		return this.getTexture( builder, output );
+
+	}
+
 	var tex = this.getTexture( builder, output );
 	var tex = this.getTexture( builder, output );
 	var coord = this.coord.build( builder, this.project ? 'v4' : 'v2' );
 	var coord = this.coord.build( builder, this.project ? 'v4' : 'v2' );
 	var bias = this.bias ? this.bias.build( builder, 'fv1' ) : undefined;
 	var bias = this.bias ? this.bias.build( builder, 'fv1' ) : undefined;
@@ -42,6 +48,20 @@ THREE.TextureNode.prototype.generate = function( builder, output ) {
 	if ( bias ) code = method + '(' + tex + ',' + coord + ',' + bias + ')';
 	if ( bias ) code = method + '(' + tex + ',' + coord + ',' + bias + ')';
 	else code = method + '(' + tex + ',' + coord + ')';
 	else code = method + '(' + tex + ',' + coord + ')';
 
 
+	if ( builder.isSlot( 'color' ) ) {
+
+		code = 'mapTexelToLinear(' + code + ')';
+
+	} else if ( builder.isSlot( 'emissive' ) ) {
+
+		code = 'emissiveMapTexelToLinear(' + code + ')';
+
+	} else if ( builder.isSlot( 'environment' ) ) {
+
+		code = 'envMapTexelToLinear(' + code + ')';
+
+	}
+
 	return builder.format( code, this.type, output );
 	return builder.format( code, this.type, output );
 
 
 };
 };

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

@@ -4,7 +4,7 @@
 
 
 THREE.Vector2Node = function( x, y ) {
 THREE.Vector2Node = function( x, y ) {
 
 
-	THREE.InputNode.call( this, 'v2', { share: false } );
+	THREE.InputNode.call( this, 'v2' );
 
 
 	this.value = new THREE.Vector2( x, y );
 	this.value = new THREE.Vector2( x, y );
 
 

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

@@ -4,7 +4,7 @@
 
 
 THREE.Vector3Node = function( x, y, z ) {
 THREE.Vector3Node = function( x, y, z ) {
 
 
-	THREE.InputNode.call( this, 'v3', { share: false } );
+	THREE.InputNode.call( this, 'v3' );
 
 
 	this.type = 'v3';
 	this.type = 'v3';
 	this.value = new THREE.Vector3( x, y, z );
 	this.value = new THREE.Vector3( x, y, z );

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

@@ -4,7 +4,7 @@
 
 
 THREE.Vector4Node = function( x, y, z, w ) {
 THREE.Vector4Node = function( x, y, z, w ) {
 
 
-	THREE.InputNode.call( this, 'v4', { share: false } );
+	THREE.InputNode.call( this, 'v4' );
 
 
 	this.value = new THREE.Vector4( x, y, z, w );
 	this.value = new THREE.Vector4( x, y, z, w );
 
 

+ 19 - 17
examples/js/nodes/materials/PhongNode.js

@@ -23,11 +23,11 @@ THREE.PhongNode.prototype.build = function( builder ) {
 	material.define( 'PHONG' );
 	material.define( 'PHONG' );
 	material.define( 'ALPHATEST', '0.0' );
 	material.define( 'ALPHATEST', '0.0' );
 
 
-	material.requestAttrib.light = true;
+	material.requestAttribs.light = true;
 
 
 	if ( builder.isShader( 'vertex' ) ) {
 	if ( builder.isShader( 'vertex' ) ) {
 
 
-		var transform = this.transform ? this.transform.parseAndBuildCode( builder, 'v3', 'transform' ) : undefined;
+		var transform = this.transform ? this.transform.parseAndBuildCode( builder, 'v3', { cache : 'transform' } ) : undefined;
 
 
 		material.mergeUniform( THREE.UniformsUtils.merge( [
 		material.mergeUniform( THREE.UniformsUtils.merge( [
 
 
@@ -98,47 +98,47 @@ THREE.PhongNode.prototype.build = function( builder ) {
 
 
 		// parse all nodes to reuse generate codes
 		// parse all nodes to reuse generate codes
 
 
-		this.color.parse( builder );
+		this.color.parse( builder, { slot : 'color' } );
 		this.specular.parse( builder );
 		this.specular.parse( builder );
 		this.shininess.parse( builder );
 		this.shininess.parse( builder );
 
 
 		if ( this.alpha ) this.alpha.parse( builder );
 		if ( this.alpha ) this.alpha.parse( builder );
 
 
-		if ( this.light ) this.light.parse( builder, 'light' );
+		if ( this.light ) this.light.parse( builder, { cache : 'light' } );
 
 
 		if ( this.ao ) this.ao.parse( builder );
 		if ( this.ao ) this.ao.parse( builder );
 		if ( this.ambient ) this.ambient.parse( builder );
 		if ( this.ambient ) this.ambient.parse( builder );
 		if ( this.shadow ) this.shadow.parse( builder );
 		if ( this.shadow ) this.shadow.parse( builder );
-		if ( this.emissive ) this.emissive.parse( builder );
+		if ( this.emissive ) this.emissive.parse( builder, { slot : 'emissive' } );
 
 
 		if ( this.normal ) this.normal.parse( builder );
 		if ( this.normal ) this.normal.parse( builder );
 		if ( this.normalScale && this.normal ) this.normalScale.parse( builder );
 		if ( this.normalScale && this.normal ) this.normalScale.parse( builder );
 
 
-		if ( this.environment ) this.environment.parse( builder );
+		if ( this.environment ) this.environment.parse( builder, { slot : 'environment' } );
 		if ( this.environmentAlpha && this.environment ) this.environmentAlpha.parse( builder );
 		if ( this.environmentAlpha && this.environment ) this.environmentAlpha.parse( builder );
 
 
 		// build code
 		// build code
 
 
-		var color = this.color.buildCode( builder, 'c' );
+		var color = this.color.buildCode( builder, 'c', { slot : 'color' } );
 		var specular = this.specular.buildCode( builder, 'c' );
 		var specular = this.specular.buildCode( builder, 'c' );
 		var shininess = this.shininess.buildCode( builder, 'fv1' );
 		var shininess = this.shininess.buildCode( builder, 'fv1' );
 
 
 		var alpha = this.alpha ? this.alpha.buildCode( builder, 'fv1' ) : undefined;
 		var alpha = this.alpha ? this.alpha.buildCode( builder, 'fv1' ) : undefined;
 
 
-		var light = this.light ? this.light.buildCode( builder, 'v3', 'light' ) : undefined;
+		var light = this.light ? this.light.buildCode( builder, 'v3', { cache : 'light' } ) : undefined;
 
 
 		var ao = this.ao ? this.ao.buildCode( builder, 'fv1' ) : undefined;
 		var ao = this.ao ? this.ao.buildCode( builder, 'fv1' ) : undefined;
 		var ambient = this.ambient ? this.ambient.buildCode( builder, 'c' ) : undefined;
 		var ambient = this.ambient ? this.ambient.buildCode( builder, 'c' ) : undefined;
 		var shadow = this.shadow ? this.shadow.buildCode( builder, 'c' ) : undefined;
 		var shadow = this.shadow ? this.shadow.buildCode( builder, 'c' ) : undefined;
-		var emissive = this.emissive ? this.emissive.buildCode( builder, 'c' ) : undefined;
+		var emissive = this.emissive ? this.emissive.buildCode( builder, 'c', { slot : 'emissive' } ) : undefined;
 
 
 		var normal = this.normal ? this.normal.buildCode( builder, 'v3' ) : undefined;
 		var normal = this.normal ? this.normal.buildCode( builder, 'v3' ) : undefined;
 		var normalScale = this.normalScale && this.normal ? this.normalScale.buildCode( builder, 'v2' ) : undefined;
 		var normalScale = this.normalScale && this.normal ? this.normalScale.buildCode( builder, 'v2' ) : undefined;
 
 
-		var environment = this.environment ? this.environment.buildCode( builder, 'c' ) : undefined;
+		var environment = this.environment ? this.environment.buildCode( builder, 'c', { slot : 'environment' } ) : undefined;
 		var environmentAlpha = this.environmentAlpha && this.environment ? this.environmentAlpha.buildCode( builder, 'fv1' ) : undefined;
 		var environmentAlpha = this.environmentAlpha && this.environment ? this.environmentAlpha.buildCode( builder, 'fv1' ) : undefined;
 
 
-		material.requestAttrib.transparent = alpha != undefined;
+		material.requestAttribs.transparent = alpha != undefined;
 
 
 		material.addFragmentPars( [
 		material.addFragmentPars( [
 			THREE.ShaderChunk[ "common" ],
 			THREE.ShaderChunk[ "common" ],
@@ -275,7 +275,7 @@ THREE.PhongNode.prototype.build = function( builder ) {
 
 
 				output.push(
 				output.push(
 					environmentAlpha.code,
 					environmentAlpha.code,
-					"outgoingLight = mix(" + 'outgoingLight' + "," + environment.result + "," + environmentAlpha.result + ");"
+					"outgoingLight = mix( outgoingLight, " + environment.result + ", " + environmentAlpha.result + " );"
 				);
 				);
 
 
 			}
 			}
@@ -287,11 +287,6 @@ THREE.PhongNode.prototype.build = function( builder ) {
 
 
 		}
 		}
 
 
-		output.push(
-			THREE.ShaderChunk[ "linear_to_gamma_fragment" ],
-			THREE.ShaderChunk[ "fog_fragment" ]
-		);
-
 		if ( alpha ) {
 		if ( alpha ) {
 
 
 			output.push( "gl_FragColor = vec4( outgoingLight, " + alpha.result + " );" );
 			output.push( "gl_FragColor = vec4( outgoingLight, " + alpha.result + " );" );
@@ -303,6 +298,13 @@ THREE.PhongNode.prototype.build = function( builder ) {
 
 
 		}
 		}
 
 
+		output.push(
+			THREE.ShaderChunk[ "premultiplied_alpha_fragment" ],
+			THREE.ShaderChunk[ "tonemapping_fragment" ],
+			THREE.ShaderChunk[ "encodings_fragment" ],
+			THREE.ShaderChunk[ "fog_fragment" ]
+		);
+
 		code = output.join( "\n" );
 		code = output.join( "\n" );
 
 
 	}
 	}

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

@@ -20,14 +20,15 @@ THREE.StandardNode.prototype.build = function( builder ) {
 	var material = builder.material;
 	var material = builder.material;
 	var code;
 	var code;
 
 
+	material.define( 'STANDARD' );
 	material.define( 'PHYSICAL' );
 	material.define( 'PHYSICAL' );
 	material.define( 'ALPHATEST', '0.0' );
 	material.define( 'ALPHATEST', '0.0' );
 
 
-	material.requestAttrib.light = true;
+	material.requestAttribs.light = true;
 
 
 	if ( builder.isShader( 'vertex' ) ) {
 	if ( builder.isShader( 'vertex' ) ) {
 
 
-		var transform = this.transform ? this.transform.parseAndBuildCode( builder, 'v3', 'transform' ) : undefined;
+		var transform = this.transform ? this.transform.parseAndBuildCode( builder, 'v3', { cache : 'transform' } ) : undefined;
 
 
 		material.mergeUniform( THREE.UniformsUtils.merge( [
 		material.mergeUniform( THREE.UniformsUtils.merge( [
 
 
@@ -106,27 +107,27 @@ THREE.StandardNode.prototype.build = function( builder ) {
 
 
 		// parse all nodes to reuse generate codes
 		// parse all nodes to reuse generate codes
 
 
-		this.color.parse( builder );
+		this.color.parse( builder, { slot : 'color' } );
 		this.roughness.parse( builder );
 		this.roughness.parse( builder );
 		this.metalness.parse( builder );
 		this.metalness.parse( builder );
 
 
 		if ( this.alpha ) this.alpha.parse( builder );
 		if ( this.alpha ) this.alpha.parse( builder );
 
 
-		if ( this.light ) this.light.parse( builder, 'light' );
+		if ( this.light ) this.light.parse( builder, { cache : 'light' } );
 
 
 		if ( this.ao ) this.ao.parse( builder );
 		if ( this.ao ) this.ao.parse( builder );
 		if ( this.ambient ) this.ambient.parse( builder );
 		if ( this.ambient ) this.ambient.parse( builder );
 		if ( this.shadow ) this.shadow.parse( builder );
 		if ( this.shadow ) this.shadow.parse( builder );
-		if ( this.emissive ) this.emissive.parse( builder );
+		if ( this.emissive ) this.emissive.parse( builder, { slot : 'emissive' } );
 
 
 		if ( this.normal ) this.normal.parse( builder );
 		if ( this.normal ) this.normal.parse( builder );
 		if ( this.normalScale && this.normal ) this.normalScale.parse( builder );
 		if ( this.normalScale && this.normal ) this.normalScale.parse( builder );
 
 
-		if ( this.environment ) this.environment.parse( builder, 'env', requires ); // isolate environment from others inputs ( see TextureNode, CubeTextureNode )
+		if ( this.environment ) this.environment.parse( builder, { cache : 'env', requires : requires, slot : 'environment' } ); // isolate environment from others inputs ( see TextureNode, CubeTextureNode )
 
 
 		// build code
 		// build code
 
 
-		var color = this.color.buildCode( builder, 'c' );
+		var color = this.color.buildCode( builder, 'c', { slot : 'color' } );
 		var roughness = this.roughness.buildCode( builder, 'fv1' );
 		var roughness = this.roughness.buildCode( builder, 'fv1' );
 		var metalness = this.metalness.buildCode( builder, 'fv1' );
 		var metalness = this.metalness.buildCode( builder, 'fv1' );
 
 
@@ -134,19 +135,19 @@ THREE.StandardNode.prototype.build = function( builder ) {
 
 
 		var alpha = this.alpha ? this.alpha.buildCode( builder, 'fv1' ) : undefined;
 		var alpha = this.alpha ? this.alpha.buildCode( builder, 'fv1' ) : undefined;
 
 
-		var light = this.light ? this.light.buildCode( builder, 'v3', 'light' ) : undefined;
+		var light = this.light ? this.light.buildCode( builder, 'v3', { cache : 'light' } ) : undefined;
 
 
 		var ao = this.ao ? this.ao.buildCode( builder, 'fv1' ) : undefined;
 		var ao = this.ao ? this.ao.buildCode( builder, 'fv1' ) : undefined;
 		var ambient = this.ambient ? this.ambient.buildCode( builder, 'c' ) : undefined;
 		var ambient = this.ambient ? this.ambient.buildCode( builder, 'c' ) : undefined;
 		var shadow = this.shadow ? this.shadow.buildCode( builder, 'c' ) : undefined;
 		var shadow = this.shadow ? this.shadow.buildCode( builder, 'c' ) : undefined;
-		var emissive = this.emissive ? this.emissive.buildCode( builder, 'c' ) : undefined;
+		var emissive = this.emissive ? this.emissive.buildCode( builder, 'c', { slot : 'emissive' } ) : undefined;
 
 
 		var normal = this.normal ? this.normal.buildCode( builder, 'v3' ) : undefined;
 		var normal = this.normal ? this.normal.buildCode( builder, 'v3' ) : undefined;
 		var normalScale = this.normalScale && this.normal ? this.normalScale.buildCode( builder, 'v2' ) : undefined;
 		var normalScale = this.normalScale && this.normal ? this.normalScale.buildCode( builder, 'v2' ) : undefined;
 
 
-		var environment = this.environment ? this.environment.buildCode( builder, 'c', 'env', requires ) : undefined;
+		var environment = this.environment ? this.environment.buildCode( builder, 'c', { cache : 'env', requires : requires, slot : 'environment' } ) : undefined;
 
 
-		material.requestAttrib.transparent = alpha != undefined;
+		material.requestAttribs.transparent = alpha != undefined;
 
 
 		material.addFragmentPars( [
 		material.addFragmentPars( [
 
 
@@ -265,7 +266,9 @@ THREE.StandardNode.prototype.build = function( builder ) {
 
 
 			output.push(
 			output.push(
 				ao.code,
 				ao.code,
-				"reflectedLight.indirectDiffuse *= " + ao.result + ";"
+				"reflectedLight.indirectDiffuse *= " + ao.result + ";",
+				"float dotNV = saturate( dot( geometry.normal, geometry.viewDir ) );",
+				"reflectedLight.indirectSpecular *= computeSpecularOcclusion( dotNV, " + ao.result + ", material.specularRoughness );"
 			);
 			);
 
 
 		}
 		}
@@ -309,11 +312,6 @@ THREE.StandardNode.prototype.build = function( builder ) {
 
 
 		output.push( "vec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + reflectedLight.directSpecular + reflectedLight.indirectSpecular;" );
 		output.push( "vec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + reflectedLight.directSpecular + reflectedLight.indirectSpecular;" );
 
 
-		output.push(
-			THREE.ShaderChunk[ "linear_to_gamma_fragment" ],
-			THREE.ShaderChunk[ "fog_fragment" ]
-		);
-
 		if ( alpha ) {
 		if ( alpha ) {
 
 
 			output.push( "gl_FragColor = vec4( outgoingLight, " + alpha.result + " );" );
 			output.push( "gl_FragColor = vec4( outgoingLight, " + alpha.result + " );" );
@@ -325,6 +323,13 @@ THREE.StandardNode.prototype.build = function( builder ) {
 
 
 		}
 		}
 
 
+		output.push(
+			THREE.ShaderChunk[ "premultiplied_alpha_fragment" ],
+			THREE.ShaderChunk[ "tonemapping_fragment" ],
+			THREE.ShaderChunk[ "encodings_fragment" ],
+			THREE.ShaderChunk[ "fog_fragment" ]
+		);
+
 		code = output.join( "\n" );
 		code = output.join( "\n" );
 
 
 	}
 	}

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

@@ -30,7 +30,7 @@ THREE.Math3Node.prototype.getType = function( builder ) {
 
 
 	if ( a > b && a > c ) return this.a.getType( builder );
 	if ( a > b && a > c ) return this.a.getType( builder );
 	else if ( b > c ) return this.b.getType( builder );
 	else if ( b > c ) return this.b.getType( builder );
-	
+
 	return this.c.getType( builder );
 	return this.c.getType( builder );
 
 
 };
 };

+ 8 - 8
examples/js/nodes/math/OperatorNode.js

@@ -24,14 +24,14 @@ THREE.OperatorNode.prototype.getType = function( builder ) {
 
 
 	var a = this.a.getType( builder );
 	var a = this.a.getType( builder );
 	var b = this.b.getType( builder );
 	var b = this.b.getType( builder );
-	
+
 	if ( builder.isFormatMatrix( a ) ) {
 	if ( builder.isFormatMatrix( a ) ) {
-	
+
 		return 'v4';
 		return 'v4';
-		
-	}
-	// use the greater length vector
-	else if ( builder.getFormatLength( b ) > builder.getFormatLength( a ) ) {
+
+	} else if ( builder.getFormatLength( b ) > builder.getFormatLength( a ) ) {
+
+		// use the greater length vector
 
 
 		return b;
 		return b;
 
 
@@ -43,11 +43,11 @@ THREE.OperatorNode.prototype.getType = function( builder ) {
 
 
 THREE.OperatorNode.prototype.generate = function( builder, output ) {
 THREE.OperatorNode.prototype.generate = function( builder, output ) {
 
 
-	var material = builder.material, 
+	var material = builder.material,
 		data = material.getDataNode( this.uuid );
 		data = material.getDataNode( this.uuid );
 
 
 	var type = this.getType( builder );
 	var type = this.getType( builder );
-	
+
 	var a = this.a.build( builder, type );
 	var a = this.a.build( builder, type );
 	var b = this.b.build( builder, type );
 	var b = this.b.build( builder, type );
 
 

+ 114 - 0
examples/js/nodes/utils/BlurNode.js

@@ -0,0 +1,114 @@
+/**
+ * @author sunag / http://www.sunag.com.br/
+ */
+
+THREE.BlurNode = function( value, coord, radius, size ) {
+
+	THREE.TempNode.call( this, 'v4' );
+
+	this.requestUpdate = true;
+
+	this.value = value;
+	this.coord = coord || new THREE.UVNode();
+	this.radius = new THREE.Vector2Node( 1, 1 );
+	this.size = size;
+
+	this.blurX = true;
+	this.blurY = true;
+
+	this.horizontal = new THREE.FloatNode( 1 / 64 );
+	this.vertical = new THREE.FloatNode( 1 / 64 );
+
+};
+
+THREE.BlurNode.fBlurX = new THREE.FunctionNode( [
+"vec4 blurX( sampler2D texture, vec2 uv, float s ) {",
+"	vec4 sum = vec4( 0.0 );",
+"	sum += texture2D( texture, vec2( uv.x - 4.0 * s, uv.y ) ) * 0.051;",
+"	sum += texture2D( texture, vec2( uv.x - 3.0 * s, uv.y ) ) * 0.0918;",
+"	sum += texture2D( texture, vec2( uv.x - 2.0 * s, uv.y ) ) * 0.12245;",
+"	sum += texture2D( texture, vec2( uv.x - 1.0 * s, uv.y ) ) * 0.1531;",
+"	sum += texture2D( texture, vec2( uv.x, uv.y ) ) * 0.1633;",
+"	sum += texture2D( texture, vec2( uv.x + 1.0 * s, uv.y ) ) * 0.1531;",
+"	sum += texture2D( texture, vec2( uv.x + 2.0 * s, uv.y ) ) * 0.12245;",
+"	sum += texture2D( texture, vec2( uv.x + 3.0 * s, uv.y ) ) * 0.0918;",
+"	sum += texture2D( texture, vec2( uv.x + 4.0 * s, uv.y ) ) * 0.051;",
+"	return sum;",
+"}"
+].join( "\n" ) );
+
+THREE.BlurNode.fBlurY = new THREE.FunctionNode( [
+"vec4 blurY( sampler2D texture, vec2 uv, float s ) {",
+"	vec4 sum = vec4( 0.0 );",
+"	sum += texture2D( texture, vec2( uv.x, uv.y - 4.0 * s ) ) * 0.051;",
+"	sum += texture2D( texture, vec2( uv.x, uv.y - 3.0 * s ) ) * 0.0918;",
+"	sum += texture2D( texture, vec2( uv.x, uv.y - 2.0 * s ) ) * 0.12245;",
+"	sum += texture2D( texture, vec2( uv.x, uv.y - 1.0 * s ) ) * 0.1531;",
+"	sum += texture2D( texture, vec2( uv.x, uv.y ) ) * 0.1633;",
+"	sum += texture2D( texture, vec2( uv.x, uv.y + 1.0 * s ) ) * 0.1531;",
+"	sum += texture2D( texture, vec2( uv.x, uv.y + 2.0 * s ) ) * 0.12245;",
+"	sum += texture2D( texture, vec2( uv.x, uv.y + 3.0 * s ) ) * 0.0918;",
+"	sum += texture2D( texture, vec2( uv.x, uv.y + 4.0 * s ) ) * 0.051;",
+"	return sum;",
+"}"
+].join( "\n" ) );
+
+THREE.BlurNode.prototype = Object.create( THREE.TempNode.prototype );
+THREE.BlurNode.prototype.constructor = THREE.BlurNode;
+
+THREE.BlurNode.prototype.updateFrame = function( delta ) {
+
+	if ( this.size ) {
+
+		this.horizontal.number = this.radius.x / this.size.x;
+		this.vertical.number = this.radius.y / this.size.y;
+
+	} else if ( this.value.value && this.value.value.image ) {
+
+		var image = this.value.value.image;
+
+		this.horizontal.number = this.radius.x / image.width;
+		this.vertical.number = this.radius.y / image.height;
+
+	}
+
+};
+
+THREE.BlurNode.prototype.generate = function( builder, output ) {
+
+	var material = builder.material, blurX = THREE.BlurNode.fBlurX, blurY = THREE.BlurNode.fBlurY;
+
+	builder.include( blurX );
+	builder.include( blurY );
+
+	if ( builder.isShader( 'fragment' ) ) {
+
+		var blurCode = [], code;
+
+		if ( this.blurX ) {
+
+			blurCode.push( blurX.name + '(' + this.value.build( builder, 'sampler2D' ) + ',' + this.coord.build( builder, 'v2' ) + ',' + this.horizontal.build( builder, 'fv1' ) + ')' );
+
+		}
+
+		if ( this.blurY ) {
+
+			blurCode.push( blurY.name + '(' + this.value.build( builder, 'sampler2D' ) + ',' + this.coord.build( builder, 'v2' ) + ',' + this.vertical.build( builder, 'fv1' ) + ')' );
+
+		}
+
+		if ( blurCode.length == 2 ) code = '(' + blurCode.join( '+' ) + '/2.0)';
+		else if ( blurCode.length ) code = '(' + blurCode[ 0 ] + ')';
+		else code = 'vec4( 0.0 )';
+
+		return builder.format( code, this.getType( builder ), output );
+
+	} else {
+
+		console.warn( "THREE.BlurNode is not compatible with " + builder.shader + " shader." );
+
+		return builder.format( 'vec4( 0.0 )', this.getType( builder ), output );
+
+	}
+
+};

+ 49 - 0
examples/js/nodes/utils/BumpNode.js

@@ -0,0 +1,49 @@
+/**
+ * @author sunag / http://www.sunag.com.br/
+ */
+
+THREE.BumpNode = function( value, coord, scale ) {
+
+	THREE.TempNode.call( this, 'v3' );
+
+	this.value = value;
+	this.coord = coord || new THREE.UVNode();
+	this.scale = scale || new THREE.Vector2Node( 1, 1 );
+
+};
+
+THREE.BumpNode.fBumpToNormal = new THREE.FunctionNode( [
+"vec3 bumpToNormal( sampler2D bumpMap, vec2 uv, vec2 scale ) {",
+"	vec2 dSTdx = dFdx( uv );",
+"	vec2 dSTdy = dFdy( uv );",
+"	float Hll = texture2D( bumpMap, uv ).x;",
+"	float dBx = texture2D( bumpMap, uv + dSTdx ).x - Hll;",
+"	float dBy = texture2D( bumpMap, uv + dSTdy ).x - Hll;",
+"	return vec3( .5 + ( dBx * scale.x ), .5 + ( dBy * scale.y ), 1.0 );",
+"}"
+].join( "\n" ), null, { derivatives: true } );
+
+THREE.BumpNode.prototype = Object.create( THREE.TempNode.prototype );
+THREE.BumpNode.prototype.constructor = THREE.BumpNode;
+
+THREE.BumpNode.prototype.generate = function( builder, output ) {
+
+	var material = builder.material, func = THREE.BumpNode.fBumpToNormal;
+
+	builder.include( func );
+
+	if ( builder.isShader( 'fragment' ) ) {
+
+		return builder.format( func.name + '(' + this.value.build( builder, 'sampler2D' ) + ',' +
+			this.coord.build( builder, 'v2' ) + ',' +
+			this.scale.build( builder, 'v2' ) + ')', this.getType( builder ), output );
+
+	} else {
+
+		console.warn( "THREE.BumpNode is not compatible with " + builder.shader + " shader." );
+
+		return builder.format( 'vec3( 0.0 )', this.getType( builder ), output );
+
+	}
+
+};

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

@@ -40,7 +40,7 @@ THREE.JoinNode.prototype.getNumElements = function() {
 
 
 THREE.JoinNode.prototype.getType = function( builder ) {
 THREE.JoinNode.prototype.getType = function( builder ) {
 
 
-	return builder.getFormatByLength( this.getNumElements() );
+	return builder.getFormatFromLength( this.getNumElements() );
 
 
 };
 };
 
 
@@ -56,13 +56,13 @@ THREE.JoinNode.prototype.generate = function( builder, output ) {
 
 
 	for ( var i = 0; i < length; i ++ ) {
 	for ( var i = 0; i < length; i ++ ) {
 
 
-		var elm = this[ inputs[ i ]];
+		var elm = this[ inputs[ i ] ];
 
 
 		outputs.push( elm ? elm.build( builder, 'fv1' ) : '0.' );
 		outputs.push( elm ? elm.build( builder, 'fv1' ) : '0.' );
 
 
 	}
 	}
 
 
-	var code = builder.getFormatConstructor( length ) + '(' + outputs.join( ',' ) + ')';
+	var code = ( length > 1 ? builder.getConstructorFromLength( length ) : '' ) + '(' + outputs.join( ',' ) + ')';
 
 
 	return builder.format( code, type, output );
 	return builder.format( code, type, output );
 
 

+ 1 - 2
examples/js/nodes/utils/NormalMapNode.js

@@ -31,8 +31,7 @@ THREE.NormalMapNode.prototype.generate = function( builder, output ) {
 			this.value.coord.build( builder, 'v2' ) + ',' +
 			this.value.coord.build( builder, 'v2' ) + ',' +
 			this.scale.build( builder, 'v2' ) + ')', this.getType( builder ), output );
 			this.scale.build( builder, 'v2' ) + ')', this.getType( builder ), output );
 
 
-	}
-	else {
+	} else {
 
 
 		console.warn( "THREE.NormalMapNode is not compatible with " + builder.shader + " shader." );
 		console.warn( "THREE.NormalMapNode is not compatible with " + builder.shader + " shader." );
 
 

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

@@ -15,7 +15,7 @@ THREE.ResolutionNode = function( renderer ) {
 THREE.ResolutionNode.prototype = Object.create( THREE.Vector2Node.prototype );
 THREE.ResolutionNode.prototype = Object.create( THREE.Vector2Node.prototype );
 THREE.ResolutionNode.prototype.constructor = THREE.ResolutionNode;
 THREE.ResolutionNode.prototype.constructor = THREE.ResolutionNode;
 
 
-THREE.ResolutionNode.prototype.updateAnimation = function( delta ) {
+THREE.ResolutionNode.prototype.updateFrame = function( delta ) {
 
 
 	var size = this.renderer.getSize();
 	var size = this.renderer.getSize();
 
 

+ 2 - 4
examples/js/nodes/utils/RoughnessToBlinnExponentNode.js

@@ -37,8 +37,7 @@ THREE.RoughnessToBlinnExponentNode.prototype.generate = function( builder, outpu
 
 
 			return builder.format( 'getSpecularMIPLevel( Material_BlinnShininessExponent( material ), 8 )', this.type, output );
 			return builder.format( 'getSpecularMIPLevel( Material_BlinnShininessExponent( material ), 8 )', this.type, output );
 
 
-		}
-		else {
+		} else {
 
 
 			console.warn( "THREE.RoughnessToBlinnExponentNode is only compatible with PhysicalMaterial." );
 			console.warn( "THREE.RoughnessToBlinnExponentNode is only compatible with PhysicalMaterial." );
 
 
@@ -46,8 +45,7 @@ THREE.RoughnessToBlinnExponentNode.prototype.generate = function( builder, outpu
 
 
 		}
 		}
 
 
-	}
-	else {
+	} else {
 
 
 		console.warn( "THREE.RoughnessToBlinnExponentNode is not compatible with " + builder.shader + " shader." );
 		console.warn( "THREE.RoughnessToBlinnExponentNode is not compatible with " + builder.shader + " shader." );
 
 

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

@@ -16,7 +16,7 @@ THREE.SwitchNode.prototype.constructor = THREE.SwitchNode;
 
 
 THREE.SwitchNode.prototype.getType = function( builder ) {
 THREE.SwitchNode.prototype.getType = function( builder ) {
 
 
-	return builder.getFormatByLength( this.components.length );
+	return builder.getFormatFromLength( this.components.length );
 
 
 };
 };
 
 

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

@@ -15,7 +15,7 @@ THREE.TimerNode = function( value, scale ) {
 THREE.TimerNode.prototype = Object.create( THREE.FloatNode.prototype );
 THREE.TimerNode.prototype = Object.create( THREE.FloatNode.prototype );
 THREE.TimerNode.prototype.constructor = THREE.TimerNode;
 THREE.TimerNode.prototype.constructor = THREE.TimerNode;
 
 
-THREE.TimerNode.prototype.updateAnimation = function( delta ) {
+THREE.TimerNode.prototype.updateFrame = function( delta ) {
 
 
 	this.number += delta * this.scale;
 	this.number += delta * this.scale;
 
 

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