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*.
 		</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>
 		<div>
 		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">
 	<head>
 		<meta charset="utf-8" />
-		<base href="../../../" />
+		<base href="../../" />
 		<script src="list.js"></script>
 		<script src="page.js"></script>
 		<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">
 	<head>
 		<meta charset="utf-8" />
-		<base href="../../../" />
+		<base href="../../" />
 		<script src="list.js"></script>
 		<script src="page.js"></script>
 		<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">
 	<head>
 		<meta charset="utf-8" />
-		<base href="../../../" />
+		<base href="../../" />
 		<script src="list.js"></script>
 		<script src="page.js"></script>
 		<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">
 	<head>
 		<meta charset="utf-8" />
-		<base href="../../../" />
+		<base href="../../" />
 		<script src="list.js"></script>
 		<script src="page.js"></script>
 		<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">
 	<head>
 		<meta charset="utf-8" />
-		<base href="../../../" />
+		<base href="../../" />
 		<script src="list.js"></script>
 		<script src="page.js"></script>
 		<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">
 	<head>
 		<meta charset="utf-8" />
-		<base href="../../../" />
+		<base href="../../" />
 		<script src="list.js"></script>
 		<script src="page.js"></script>
 		<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">
 	<head>
 		<meta charset="utf-8" />
-		<base href="../../../" />
+		<base href="../../" />
 		<script src="list.js"></script>
 		<script src="page.js"></script>
 		<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">
 	<head>
 		<meta charset="utf-8" />
-		<base href="../../../" />
+		<base href="../../" />
 		<script src="list.js"></script>
 		<script src="page.js"></script>
 		<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">
 	<head>
 		<meta charset="utf-8" />
-		<base href="../../../" />
+		<base href="../../" />
 		<script src="list.js"></script>
 		<script src="page.js"></script>
 		<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">
 	<head>
 		<meta charset="utf-8" />
-		<base href="../../../" />
+		<base href="../../" />
 		<script src="list.js"></script>
 		<script src="page.js"></script>
 		<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">
 	<head>
 		<meta charset="utf-8" />
-		<base href="../../../" />
+		<base href="../../" />
 		<script src="list.js"></script>
 		<script src="page.js"></script>
 		<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">
 	<head>
 		<meta charset="utf-8" />
-		<base href="../../../" />
+		<base href="../../" />
 		<script src="list.js"></script>
 		<script src="page.js"></script>
 		<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">
 	<head>
 		<meta charset="utf-8" />
-		<base href="../../../" />
+		<base href="../../" />
 		<script src="list.js"></script>
 		<script src="page.js"></script>
 		<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">
 	<head>
 		<meta charset="utf-8" />
-		<base href="../../../" />
+		<base href="../../" />
 		<script src="list.js"></script>
 		<script src="page.js"></script>
 		<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">
 	<head>
 		<meta charset="utf-8" />
-		<base href="../../../" />
+		<base href="../../" />
 		<script src="list.js"></script>
 		<script src="page.js"></script>
 		<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">
 	<head>
 		<meta charset="utf-8" />
-		<base href="../../../" />
+		<base href="../../" />
 		<script src="list.js"></script>
 		<script src="page.js"></script>
 		<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">
 	<head>
 		<meta charset="utf-8" />
-		<base href="../../../" />
+		<base href="../../" />
 		<script src="list.js"></script>
 		<script src="page.js"></script>
 		<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">
 	<head>
 		<meta charset="utf-8" />
-		<base href="../../../" />
+		<base href="../../" />
 		<script src="list.js"></script>
 		<script src="page.js"></script>
 		<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">
 	<head>
 		<meta charset="utf-8" />
-		<base href="../../../" />
+		<base href="../../" />
 		<script src="list.js"></script>
 		<script src="page.js"></script>
 		<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">
 	<head>
 		<meta charset="utf-8" />
-		<base href="../../../" />
+		<base href="../../" />
 		<script src="list.js"></script>
 		<script src="page.js"></script>
 		<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">
 	<head>
 		<meta charset="utf-8" />
-		<base href="../../../" />
+		<base href="../../" />
 		<script src="list.js"></script>
 		<script src="page.js"></script>
 		<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">
 	<head>
 		<meta charset="utf-8" />
-		<base href="../../../" />
+		<base href="../../" />
 		<script src="list.js"></script>
 		<script src="page.js"></script>
 		<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">
 	<head>
 		<meta charset="utf-8" />
-		<base href="../../../" />
+		<base href="../../" />
 		<script src="list.js"></script>
 		<script src="page.js"></script>
 		<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">
 	<head>
 		<meta charset="utf-8" />
-		<base href="../../../" />
+		<base href="../../" />
 		<script src="list.js"></script>
 		<script src="page.js"></script>
 		<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">
 	<head>
 		<meta charset="utf-8" />
-		<base href="../../../" />
+		<base href="../../" />
 		<script src="list.js"></script>
 		<script src="page.js"></script>
 		<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">
 	<head>
 		<meta charset="utf-8" />
-		<base href="../../../" />
+		<base href="../../" />
 		<script src="list.js"></script>
 		<script src="page.js"></script>
 		<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">
 	<head>
 		<meta charset="utf-8" />
-		<base href="../../../" />
+		<base href="../../" />
 		<script src="list.js"></script>
 		<script src="page.js"></script>
 		<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">
 	<head>
 		<meta charset="utf-8" />
-		<base href="../../../" />
+		<base href="../../" />
 		<script src="list.js"></script>
 		<script src="page.js"></script>
 		<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">
 	<head>
 		<meta charset="utf-8" />
-		<base href="../../../" />
+		<base href="../../" />
 		<script src="list.js"></script>
 		<script src="page.js"></script>
 		<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">
 	<head>
 		<meta charset="utf-8" />
-		<base href="../../../" />
+		<base href="../../" />
 		<script src="list.js"></script>
 		<script src="page.js"></script>
 		<link type="text/css" rel="stylesheet" href="page.css" />

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

@@ -1,7 +1,7 @@
 <!DOCTYPE html>
 <html lang="en">
 	<head>
-		<meta charset="utf-8" />
+		<meta charset="utf-8" />
 		<base href="../../" />
 		<script src="list.js"></script>
 		<script src="page.js"></script>
@@ -45,8 +45,9 @@
 		[page:String text] — The textual <em>obj</em> structure to parse.
 		</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>
 
 		<h2>Example</h2>
@@ -58,7 +59,7 @@
 		// load a resource
 		loader.load(
 			// resource URL
-			'models/skinned/UCS_config.json',
+			'models/monster.obj',
 			// Function when resource is loaded
 			function ( object ) {
 				scene.add( object );

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

@@ -120,158 +120,13 @@
 		</p>
 
 		<p>
-		To declare a custom uniform, use the *uniforms* property:
+		To declare a custom [page:Uniform], use the *uniforms* property:
 		<code>
 		uniforms: {
 			time: { value: 1.0 },
 			resolution: { value: new THREE.Vector2() }
 		}
 		</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>
 
 		<h2>Constructor</h2>

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

@@ -43,7 +43,7 @@
 		<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>
-		
+
 		<h3>[property:Array morphTargetInfluences]</h3>
 
 		<div>
@@ -58,29 +58,12 @@
 		Undefined by default, but rebuilt [page:Mesh.updateMorphTargets updateMorphTargets].
 		</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>
 
-		<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>
 		<div>
 		Updates the morphtargets to have no influence on the object. Resets the
-		[page:Mesh.morphTargetForcedOrder morphTargetForcedOrder],
 		[page:Mesh.morphTargetInfluences morphTargetInfluences],
 		[page:Mesh.morphTargetDictionary morphTargetDictionary], and
 		[page:Mesh.morphTargetBase morphTargetBase] properties.

+ 36 - 37
docs/list.js

@@ -31,7 +31,41 @@ var list = {
 			[ "Face3", "api/core/Face3" ],
 			[ "Geometry", "api/core/Geometry" ],
 			[ "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": [
@@ -190,39 +224,6 @@ var list = {
 			[ "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": [
 			[ "ArrowHelper", "api/extras/helpers/ArrowHelper" ],
 			[ "AxisHelper", "api/extras/helpers/AxisHelper" ],
@@ -230,14 +231,12 @@ var list = {
 			[ "BoxHelper", "api/extras/helpers/BoxHelper" ],
 			[ "CameraHelper", "api/extras/helpers/CameraHelper" ],
 			[ "DirectionalLightHelper", "api/extras/helpers/DirectionalLightHelper" ],
-			[ "EdgesHelper", "api/extras/helpers/EdgesHelper" ],
 			[ "FaceNormalsHelper", "api/extras/helpers/FaceNormalsHelper" ],
 			[ "GridHelper", "api/extras/helpers/GridHelper" ],
 			[ "HemisphereLightHelper", "api/extras/helpers/HemisphereLightHelper" ],
 			[ "PointLightHelper", "api/extras/helpers/PointLightHelper" ],
 			[ "SpotLightHelper", "api/extras/helpers/SpotLightHelper" ],
-			[ "VertexNormalsHelper", "api/extras/helpers/VertexNormalsHelper" ],
-			[ "WireframeHelper", "api/extras/helpers/WireframeHelper" ]
+			[ "VertexNormalsHelper", "api/extras/helpers/VertexNormalsHelper" ]
 		],
 
 		"Extras / Objects": [

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

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

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

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

+ 4 - 1
examples/files.js

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

+ 1 - 1
examples/js/GPUComputationRenderer.js

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

+ 170 - 183
examples/js/MarchingCubes.js

@@ -1,14 +1,20 @@
 /**
  * @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.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.enableColors = enableColors !== undefined ? enableColors : false;
 
@@ -40,11 +46,6 @@ THREE.MarchingCubes = function ( resolution, material, enableUvs, enableColors )
 		this.field = new Float32Array( this.size3 );
 		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
 
 		this.maxCount = 4096; // TODO: find the fastest size for this buffer
@@ -76,98 +77,98 @@ THREE.MarchingCubes = function ( resolution, material, enableUvs, enableColors )
 	// Polygonization
 	///////////////////////
 
-	this.lerp = function( a, b, t ) {
+	function lerp( a, b, 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 ),
-		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 ),
-		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 ),
-		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;
 
-		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.
 	// (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
 		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,
-			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 ( field1 < isol ) cubeindex |= 2;
@@ -183,7 +184,7 @@ THREE.MarchingCubes = function ( resolution, material, enableUvs, enableColors )
 		var bits = THREE.edgeTable[ cubeindex ];
 		if ( bits === 0 ) return 0;
 
-		var d = this.delta,
+		var d = scope.delta,
 			fx2 = fx + d,
 			fy2 = fy + d,
 			fz2 = fz + d;
@@ -192,33 +193,33 @@ THREE.MarchingCubes = function ( resolution, material, enableUvs, enableColors )
 
 		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 ) {
 
-			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 ) {
 
-			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 ) {
 
-			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 ) {
 
-			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 ) {
 
-			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 ) {
 
-			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 ) {
 
-			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 ) {
 
-			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 ) {
 
-			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 ) {
 
-			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 ) {
 
-			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;
 			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;
 			numtris ++;
@@ -315,105 +316,105 @@ THREE.MarchingCubes = function ( resolution, material, enableUvs, enableColors )
 
 		return numtris;
 
-	};
+	}
 
 	/////////////////////////////////////
 	// 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
 
-		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
 
-		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
 
-		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
 
-		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;
 
@@ -424,7 +425,7 @@ THREE.MarchingCubes = function ( resolution, material, enableUvs, enableColors )
 
 	};
 
-	this.end = function( renderCallback ) {
+	this.end = function ( renderCallback ) {
 
 		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
 	// 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:
 		// 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;
 					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 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 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 );
 				normals.push( normal );
 
 			}
 
-			nfaces = object.count / 3;
+			var nfaces = object.count / 3;
 
 			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 );
 
 			}

+ 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.Object3D.call( this );
 
+	var scope = this;
 	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.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 ) {
 
+			//  Position and orientation.
+
 			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.multiplyMatrices( scope.standingMatrix, scope.matrix );
 			scope.matrixWorldNeedsUpdate = 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 {
 
 			scope.visible = false;
 
 		}
 
-	}
-
-	update();
+	};
 
 };
 

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

@@ -420,7 +420,7 @@
 			],
 
 			XYZE: [
-				[ new THREE.Mesh( new THREE.Geometry() ) ]// TODO
+				[ new THREE.Mesh() ]// TODO
 			]
 
 		};
@@ -799,7 +799,15 @@
 			this.position.copy( worldPosition );
 			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" ) {
 

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

@@ -11,23 +11,20 @@ THREE.VRControls = function ( object, onError ) {
 
 	var standingMatrix = new THREE.Matrix4();
 
+	var frameData = null;
+	if ( 'VRFrameData' in window ) {
+		frameData = new VRFrameData();
+	}
+
 	function gotVRDisplays( 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.' );
 
@@ -39,11 +36,6 @@ THREE.VRControls = function ( object, onError ) {
 
 		navigator.getVRDisplays().then( gotVRDisplays );
 
-	} else if ( navigator.getVRDevices ) {
-
-		// Deprecated API.
-		navigator.getVRDevices().then( gotVRDisplays );
-
 	}
 
 	// the Rift SDK returns the position in meters
@@ -82,46 +74,32 @@ THREE.VRControls = function ( object, onError ) {
 
 		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.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();
 
-		renderer.setScissorTest( true );
 		renderer.clear();
+		renderer.setScissorTest( true );
 
 		renderer.setScissor( 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
  *
  * 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 ) {
 
-	var isWebVR1 = true;
-
 	var vrDisplay, vrDisplays;
 	var eyeTranslationL = new THREE.Vector3();
 	var eyeTranslationR = new THREE.Vector3();
 	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' );
 
@@ -53,11 +46,6 @@ THREE.VREffect = function ( renderer, onError ) {
 
 		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 rendererSize = renderer.getSize();
+	var rendererUpdateStyle = false;
 	var rendererPixelRatio = renderer.getPixelRatio();
 
 	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 };
+		rendererUpdateStyle = updateStyle;
 
 		if ( scope.isPresenting ) {
 
 			var eyeParamsL = vrDisplay.getEyeParameters( 'left' );
 			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 {
 
 			renderer.setPixelRatio( rendererPixelRatio );
-			renderer.setSize( width, height );
+			renderer.setSize( width, height, updateStyle );
 
 		}
 
@@ -122,34 +103,19 @@ THREE.VREffect = function ( renderer, onError ) {
 	function onFullscreenChange() {
 
 		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 ) {
 
 			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 ) {
 
 			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 );
 
 	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 {
 
-				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 ) {
 
-		if ( isWebVR1 && vrDisplay !== undefined ) {
+		if ( vrDisplay !== undefined ) {
 
 			return vrDisplay.requestAnimationFrame( f );
 
@@ -275,7 +200,7 @@ THREE.VREffect = function ( renderer, onError ) {
 
 	this.cancelAnimationFrame = function ( h ) {
 
-		if ( isWebVR1 && vrDisplay !== undefined ) {
+		if ( vrDisplay !== undefined ) {
 
 			vrDisplay.cancelAnimationFrame( h );
 
@@ -289,7 +214,7 @@ THREE.VREffect = function ( renderer, onError ) {
 
 	this.submitFrame = function () {
 
-		if ( isWebVR1 && vrDisplay !== undefined && scope.isPresenting ) {
+		if ( vrDisplay !== undefined && scope.isPresenting ) {
 
 			vrDisplay.submitFrame();
 
@@ -323,21 +248,8 @@ THREE.VREffect = function ( renderer, onError ) {
 			var eyeParamsL = vrDisplay.getEyeParameters( 'left' );
 			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 ) ) {
 
@@ -370,23 +282,44 @@ THREE.VREffect = function ( renderer, onError ) {
 			} else  {
 
 				renderer.setScissorTest( true );
-			
+
 			}
 
 			if ( renderer.autoClear || forceClear ) renderer.clear();
 
 			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( 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
 			if ( renderTarget ) {
@@ -424,11 +357,11 @@ THREE.VREffect = function ( renderer, onError ) {
 				renderer.setRenderTarget( null );
 
 			} else {
-				
+
 				renderer.setScissorTest( false );
 
 			}
-			
+
 			if ( autoUpdate ) {
 
 				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 ) {
 
 		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 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;
 
 				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 newGeometry = new THREE.BufferGeometry();
-					var indexes = Uint32Array.from( volume.triangles );
+					var indexes = new  Uint32Array( volume.triangles );
 					var material = objDefaultMaterial;
 
 					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 textureLoader = new THREE.TextureLoader( this.manager );
 		var tgaLoader = new THREE.TGALoader( this.manager );
-		var materialLoader = new THREE.MaterialLoader( this.manager );
 		var color = new THREE.Color();
 		var offset = 0;
 		var materialParams = [];
@@ -2037,6 +2036,8 @@ THREE.MMDLoader.prototype.createMesh = function ( model, texturePath, onProgress
 
 				}
 
+				delete 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++ ) {
 
 			geometry.faceVertexUvs.push( [] );
@@ -2058,12 +2071,7 @@ THREE.MMDLoader.prototype.createMesh = function ( model, texturePath, onProgress
 		for ( var i = 0; i < model.metadata.materialCount; i++ ) {
 
 			var m = model.materials[ i ];
-			var params = {
-
-				uuid: THREE.Math.generateUUID(),
-				type: 'MMDMaterial'
-
-			};
+			var params = {};
 
 			params.faceOffset = offset;
 			params.faceNum = m.faceCount;
@@ -2088,9 +2096,9 @@ THREE.MMDLoader.prototype.createMesh = function ( model, texturePath, onProgress
 			}
 
 			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.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;
 
 			if ( params.opacity === 1.0 ) {
@@ -2185,33 +2193,37 @@ THREE.MMDLoader.prototype.createMesh = function ( model, texturePath, onProgress
 			// TODO: check if this logic is right
 			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 );
 
 		}
 
-		materialLoader.setTextures( textures );
+		var shader = THREE.ShaderLib[ 'mmd' ];
 
 		for ( var i = 0; i < materialParams.length; i++ ) {
 
 			var p = materialParams[ 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.faceNum = p.faceNum;
 
+			if ( p.name !== undefined ) m.name = p.name;
+
 			m.skinning = geometry.bones.length > 0 ? true : false;
 			m.morphTargets = geometry.morphTargets.length > 0 ? true : false;
 			m.lights = true;
+			m.side = p.side;
+			m.transparent = p.transparent;
+			m.fog = true;
 
 			m.blending = THREE.CustomBlending;
 			m.blendSrc = THREE.SrcAlphaFactor;
@@ -2219,7 +2231,7 @@ THREE.MMDLoader.prototype.createMesh = function ( model, texturePath, onProgress
 			m.blendSrcAlpha = THREE.SrcAlphaFactor;
 			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
 				function checkTextureTransparency ( m ) {
@@ -2326,45 +2338,45 @@ THREE.MMDLoader.prototype.createMesh = function ( model, texturePath, onProgress
 
 						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 );
 
 			}
 
-			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' ) {
 
@@ -2458,7 +2470,7 @@ THREE.MMDLoader.prototype.createMesh = function ( model, texturePath, onProgress
 
 					var m = material.materials[ e.index ];
 
-					if ( m.opacity !== e.diffuse[ 3 ] ) {
+					if ( m.uniforms.opacity.value !== e.diffuse[ 3 ] ) {
 
 						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.
  * Keep shaders updated on MeshPhongMaterial.
@@ -4489,7 +4428,7 @@ THREE.MMDHelper.prototype = {
 			m.uniforms.outlineDrawing.value = 0;
 			m.visible = true;
 
-			if ( m.opacity === 1.0 ) {
+			if ( m.uniforms.opacity.value === 1.0 ) {
 
 				m.side = THREE.FrontSide;
 				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' ) {
 
-					this.object._finalize();
+					this.object._finalize( true );
 
 				}
 
-				var previousMaterial = ( this.object && typeof this.object.currentMaterial === 'function' ? this.object.currentMaterial() : undefined );
-
 				this.object = {
 					name : name || '',
 					fromDeclaration : ( fromDeclaration !== false ),
@@ -132,16 +132,18 @@ THREE.OBJLoader.prototype = {
 							inherited  : false,
 
 							clone : function( index ) {
-								return {
+								var cloned = {
 									index      : ( typeof index === 'number' ? index : this.index ),
 									name       : this.name,
 									mtllib     : this.mtllib,
 									smooth     : this.smooth,
-									groupStart : this.groupEnd,
+									groupStart : 0,
 									groupEnd   : -1,
 									groupCount : -1,
 									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.
-						if ( end !== false && this.materials.length === 0 ) {
+						if ( end && this.materials.length === 0 ) {
+
 							this.materials.push({
 								name   : '',
 								smooth : this.smooth
 							});
+
 						}
 
 						return lastMultiMaterial;
@@ -207,7 +222,7 @@ THREE.OBJLoader.prototype = {
 
 				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 ) {
 
 			// 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
 				// 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 );
 
 			} 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/
  */
 
-THREE.ConstNode = function( name, useDefine ) {
+THREE.ConstNode = function( src, useDefine ) {
 
 	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.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;
 		type = 'fv1';
@@ -53,6 +52,33 @@ THREE.ConstNode.prototype.parse = function( src, useDefine ) {
 
 	this.name = name;
 	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/
  */
 
-THREE.FunctionCallNode = function( value ) {
+THREE.FunctionCallNode = function( func, inputs ) {
 
 	THREE.TempNode.call( this );
 
-	this.setFunction( value );
+	this.setFunction( func, inputs );
 
 };
 
 THREE.FunctionCallNode.prototype = Object.create( THREE.TempNode.prototype );
 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 func = this.value;
 
-	builder.include( func );
-
-	var code = func.name + '(';
+	var code = func.build( builder, output ) + '(';
 	var params = [];
 
 	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/
  */
 
-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.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;
 
@@ -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.allow = {};
+	this.allows = {};
 	this.requestUpdate = false;
 
 	this.type = type;
 
 };
 
-THREE.GLNode.prototype.parse = function( builder, cache, requires ) {
+THREE.GLNode.prototype.parse = function( builder, context ) {
+
+	context = context || {};
 
 	builder.parsing = true;
 
 	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.clearFragmentNode();
 
-	builder.removeCache();
+	builder.removeCache().removeSlot();
 
 	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 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();
 	else data.code = material.clearFragmentNode();
 
-	builder.removeCache();
+	builder.removeCache().removeSlot();
 
 	return data;
 
@@ -55,21 +61,21 @@ THREE.GLNode.prototype.buildCode = function( builder, output, cache, requires )
 
 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 ( this.allow[ builder.shader ] === false ) {
+	if ( this.allows[ builder.shader ] === false ) {
 
 		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 );
-		data.requestUpdate = true;
 
 	}
 
@@ -83,7 +89,7 @@ THREE.GLNode.prototype.appendDepsNode = function( builder, data, 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.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 ) {
 
+	params = params || {};
+	params.shared = params.shared !== undefined ? params.shared : false;
+
 	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 );
 
-	}
-	else {
+	} else {
 
 		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 = {
+
 	nodes: {},
+	keywords: {},
+
 	add: function( 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 ) {
 
 		delete this.nodes[ node.name ];
 
 	},
+
+	removeKeyword: function( name ) {
+
+		delete this.keywords[ node ];
+
+	},
+
 	get: function( 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 ) {
 
 		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
@@ -57,17 +137,17 @@ THREE.NodeLib.add( new THREE.FunctionNode( [
 // Per-Pixel Tangent Space Normal Mapping
 // 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 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 } ) );
 
@@ -77,7 +157,7 @@ THREE.NodeLib.add( new THREE.FunctionNode( [
 
 THREE.NodeLib.add( new THREE.FunctionNode( [
 "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" ) ) );
 
@@ -87,12 +167,12 @@ THREE.NodeLib.add( new THREE.FunctionNode( [
 
 THREE.NodeLib.add( new THREE.FunctionNode( [
 "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" ) ) );
 
@@ -103,8 +183,8 @@ THREE.NodeLib.add( new THREE.FunctionNode( [
 THREE.NodeLib.add( new THREE.FunctionNode( [
 // Algorithm from Chapter 16 of OpenGL Shading Language
 "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" ) ) );
 
@@ -115,7 +195,7 @@ THREE.NodeLib.add( new THREE.FunctionNode( [
 THREE.NodeLib.add( new THREE.FunctionNode( [
 // Algorithm from Chapter 10 of Graphics Shaders
 "float luminance_rgb(vec3 rgb) {",
-	"return dot(rgb, LUMA);",
+"	return dot(rgb, LUMA);",
 "}"
 ].join( "\n" ) ) );
 
@@ -126,9 +206,9 @@ THREE.NodeLib.add( new THREE.FunctionNode( [
 THREE.NodeLib.add( new THREE.FunctionNode( [
 // Shader by Evan Wallace adapted by @lo-th
 "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" ) ) );

+ 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.constructor = THREE.NodeMaterial;
 
-THREE.NodeMaterial.prototype.updateAnimation = function( delta ) {
+THREE.NodeMaterial.prototype.updateFrame = function( delta ) {
 
 	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.uniforms = {};
+	this.attributes = {};
 
 	this.nodeData = {};
 
 	this.vertexUniform = [];
 	this.fragmentUniform = [];
 
+	this.vars = [];
 	this.vertexTemps = [];
 	this.fragmentTemps = [];
 
@@ -96,7 +98,7 @@ THREE.NodeMaterial.prototype.build = function() {
 
 	this.requestUpdate = [];
 
-	this.requestAttrib = {
+	this.requestAttribs = {
 		uv: [],
 		color: []
 	};
@@ -130,12 +132,12 @@ THREE.NodeMaterial.prototype.build = function() {
 	"#endif"
 	].join( "\n" );
 
-	var builder = new THREE.BuilderNode( this );
+	var builder = new THREE.NodeBuilder( this );
 
 	vertex = this.vertex.build( builder.setShader( 'vertex' ), '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.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.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.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.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.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
 
@@ -191,7 +193,7 @@ THREE.NodeMaterial.prototype.build = function() {
 
 	}
 
-	if ( this.requestAttrib.normal ) {
+	if ( this.requestAttribs.normal ) {
 
 		this.addVertexPars( '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.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.prefixCode,
@@ -286,43 +288,89 @@ THREE.NodeMaterial.prototype.createUniform = function( type, value, ns, needsUpd
 
 THREE.NodeMaterial.prototype.getVertexTemp = function( uuid, type, ns ) {
 
-	if ( ! this.vertexTemps[ uuid ] ) {
+	var data = this.vertexTemps[ uuid ];
+
+	if ( ! data ) {
 
 		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[ uuid ] = data;
 
 	}
 
-	return this.vertexTemps[ uuid ];
+	return data;
 
 };
 
 THREE.NodeMaterial.prototype.getFragmentTemp = function( uuid, type, ns ) {
 
-	if ( ! this.fragmentTemps[ uuid ] ) {
+	var data = this.fragmentTemps[ uuid ];
+
+	if ( ! data ) {
 
 		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[ 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 ) {
 
-		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 '';
 
-		var code = '';
-		var incs = incs.sort( sortByPosition );
+		var code = '', incs = incs.sort( sortByPosition );
 
 		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() {
 
-	var code = this.fragmentNode;
+	var code = this.vertexNode;
 
-	this.fragmentNode = '';
+	this.vertexNode = '';
 
 	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;
 
@@ -467,37 +514,51 @@ THREE.NodeMaterial.prototype.include = function( shader, node ) {
 
 	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 + ';';
 
-	}
-	else {
+	} else {
 
 		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 ) {
 
+	output = output || this.getType( builder );
+
 	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 ) {
 
@@ -47,8 +49,7 @@ THREE.TempNode.prototype.build = function( builder, output, uuid, ns ) {
 
 			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 );
 
@@ -63,8 +64,7 @@ THREE.TempNode.prototype.build = function( builder, output, uuid, ns ) {
 
 			return builder.format( name, type, output );
 
-		}
-		else {
+		} else {
 
 			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;
 
@@ -121,7 +118,7 @@ THREE.TempNode.prototype.getTemp = function( builder, uuid ) {
 
 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;
 

+ 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.DEPTH = 'depth';
 THREE.CameraNode.TO_VERTEX = 'toVertex';
@@ -102,9 +113,11 @@ THREE.CameraNode.prototype.generate = function( builder, output ) {
 
 		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;
 
@@ -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 ) {
 

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

@@ -4,7 +4,7 @@
 
 THREE.ColorsNode = function( index ) {
 
-	THREE.TempNode.call( this, 'v4', { share: false } );
+	THREE.TempNode.call( this, 'v4', { shared: false } );
 
 	this.index = index || 0;
 
@@ -21,7 +21,7 @@ THREE.ColorsNode.prototype.generate = function( builder, output ) {
 	var material = builder.material;
 	var result;
 
-	material.requestAttrib.color[ this.index ] = true;
+	material.requestAttribs.color[ this.index ] = true;
 
 	if ( builder.isShader( 'vertex' ) ) result = THREE.ColorsNode.vertexDict[ 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 )
 
-	}
-	else {
+	} else {
 
 		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:
 
-			material.requestAttrib.normal = true;
+			material.requestAttribs.normal = true;
 
 			if ( builder.isShader( 'vertex' ) ) result = 'normal';
 			else result = 'vObjectNormal';
@@ -46,7 +46,7 @@ THREE.NormalNode.prototype.generate = function( builder, output ) {
 
 		case THREE.NormalNode.WORLD:
 
-			material.requestAttrib.worldNormal = true;
+			material.requestAttribs.worldNormal = true;
 
 			if ( builder.isShader( 'vertex' ) ) result = '( modelMatrix * vec4( objectNormal, 0.0 ) ).xyz';
 			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:
 
-			material.requestAttrib.position = true;
+			material.requestAttribs.position = true;
 
 			if ( builder.isShader( 'vertex' ) ) result = 'transformed';
 			else result = 'vPosition';
@@ -59,7 +59,7 @@ THREE.PositionNode.prototype.generate = function( builder, output ) {
 
 		case THREE.PositionNode.WORLD:
 
-			material.requestAttrib.worldPosition = true;
+			material.requestAttribs.worldPosition = true;
 
 			if ( builder.isShader( 'vertex' ) ) 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 ) {
 
 	switch ( this.scope ) {
-		case THREE.CameraNode.SPHERE:
+		case THREE.ReflectNode.SPHERE:
 			return 'v2';
 	}
 
@@ -36,7 +36,7 @@ THREE.ReflectNode.prototype.generate = function( builder, output ) {
 
 		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';
 
@@ -56,7 +56,7 @@ THREE.ReflectNode.prototype.generate = function( builder, output ) {
 
 			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';
 

+ 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' ) + ')';
 
-	}
-	else {
+	} else {
 
 		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 result;
 
-	material.requestAttrib.uv[ this.index ] = true;
+	material.requestAttribs.uv[ this.index ] = true;
 
 	if ( builder.isShader( 'vertex' ) ) result = THREE.UVNode.vertexDict[ 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.InputNode.call( this, 'c', { share: false } );
+	THREE.InputNode.call( this, 'c' );
 
 	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.InputNode.call( this, 'v4' );
+	THREE.InputNode.call( this, 'v4', { shared : true } );
 
 	this.value = value;
 	this.coord = coord || new THREE.ReflectNode();
@@ -23,6 +23,12 @@ THREE.CubeTextureNode.prototype.getTexture = 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 coord = this.coord.build( builder, 'v3' );
 	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 + ')';
 	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 );
 
 };

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

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

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

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

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

@@ -4,7 +4,7 @@
 
 THREE.Matrix4Node = function( matrix ) {
 
-	THREE.InputNode.call( this, 'm4', { share: false } );
+	THREE.InputNode.call( this, 'm4' );
 
 	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.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." );
 

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

@@ -4,7 +4,7 @@
 
 THREE.TextureNode = function( value, coord, bias, project ) {
 
-	THREE.InputNode.call( this, 'v4' );
+	THREE.InputNode.call( this, 'v4', { shared : true } );
 
 	this.value = value;
 	this.coord = coord || new THREE.UVNode();
@@ -24,6 +24,12 @@ THREE.TextureNode.prototype.getTexture = 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 coord = this.coord.build( builder, this.project ? 'v4' : 'v2' );
 	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 + ')';
 	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 );
 
 };

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

@@ -4,7 +4,7 @@
 
 THREE.Vector2Node = function( x, y ) {
 
-	THREE.InputNode.call( this, 'v2', { share: false } );
+	THREE.InputNode.call( this, 'v2' );
 
 	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.InputNode.call( this, 'v3', { share: false } );
+	THREE.InputNode.call( this, 'v3' );
 
 	this.type = 'v3';
 	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.InputNode.call( this, 'v4', { share: false } );
+	THREE.InputNode.call( this, 'v4' );
 
 	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( 'ALPHATEST', '0.0' );
 
-	material.requestAttrib.light = true;
+	material.requestAttribs.light = true;
 
 	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( [
 
@@ -98,47 +98,47 @@ THREE.PhongNode.prototype.build = function( builder ) {
 
 		// parse all nodes to reuse generate codes
 
-		this.color.parse( builder );
+		this.color.parse( builder, { slot : 'color' } );
 		this.specular.parse( builder );
 		this.shininess.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.ambient ) this.ambient.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.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 );
 
 		// 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 shininess = this.shininess.buildCode( builder, 'fv1' );
 
 		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 ambient = this.ambient ? this.ambient.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 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;
 
-		material.requestAttrib.transparent = alpha != undefined;
+		material.requestAttribs.transparent = alpha != undefined;
 
 		material.addFragmentPars( [
 			THREE.ShaderChunk[ "common" ],
@@ -275,7 +275,7 @@ THREE.PhongNode.prototype.build = function( builder ) {
 
 				output.push(
 					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 ) {
 
 			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" );
 
 	}

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

@@ -20,14 +20,15 @@ THREE.StandardNode.prototype.build = function( builder ) {
 	var material = builder.material;
 	var code;
 
+	material.define( 'STANDARD' );
 	material.define( 'PHYSICAL' );
 	material.define( 'ALPHATEST', '0.0' );
 
-	material.requestAttrib.light = true;
+	material.requestAttribs.light = true;
 
 	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( [
 
@@ -106,27 +107,27 @@ THREE.StandardNode.prototype.build = function( builder ) {
 
 		// parse all nodes to reuse generate codes
 
-		this.color.parse( builder );
+		this.color.parse( builder, { slot : 'color' } );
 		this.roughness.parse( builder );
 		this.metalness.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.ambient ) this.ambient.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.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
 
-		var color = this.color.buildCode( builder, 'c' );
+		var color = this.color.buildCode( builder, 'c', { slot : 'color' } );
 		var roughness = this.roughness.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 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 ambient = this.ambient ? this.ambient.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 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( [
 
@@ -265,7 +266,9 @@ THREE.StandardNode.prototype.build = function( builder ) {
 
 			output.push(
 				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(
-			THREE.ShaderChunk[ "linear_to_gamma_fragment" ],
-			THREE.ShaderChunk[ "fog_fragment" ]
-		);
-
 		if ( alpha ) {
 
 			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" );
 
 	}

+ 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 );
 	else if ( b > c ) return this.b.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 b = this.b.getType( builder );
-	
+
 	if ( builder.isFormatMatrix( a ) ) {
-	
+
 		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;
 
@@ -43,11 +43,11 @@ THREE.OperatorNode.prototype.getType = function( builder ) {
 
 THREE.OperatorNode.prototype.generate = function( builder, output ) {
 
-	var material = builder.material, 
+	var material = builder.material,
 		data = material.getDataNode( this.uuid );
 
 	var type = this.getType( builder );
-	
+
 	var a = this.a.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 ) {
 
-	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 ++ ) {
 
-		var elm = this[ inputs[ i ]];
+		var elm = this[ inputs[ i ] ];
 
 		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 );
 

+ 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.scale.build( builder, 'v2' ) + ')', this.getType( builder ), output );
 
-	}
-	else {
+	} else {
 
 		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.constructor = THREE.ResolutionNode;
 
-THREE.ResolutionNode.prototype.updateAnimation = function( delta ) {
+THREE.ResolutionNode.prototype.updateFrame = function( delta ) {
 
 	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 );
 
-		}
-		else {
+		} else {
 
 			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." );
 

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

@@ -16,7 +16,7 @@ THREE.SwitchNode.prototype.constructor = THREE.SwitchNode;
 
 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.constructor = THREE.TimerNode;
 
-THREE.TimerNode.prototype.updateAnimation = function( delta ) {
+THREE.TimerNode.prototype.updateFrame = function( delta ) {
 
 	this.number += delta * this.scale;
 

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