Browse Source

Merge branch 'dev' of [email protected]:mrdoob/three.js into texture_encoding

Ben Houston 9 years ago
parent
commit
79bcfdc037
55 changed files with 1492 additions and 701 deletions
  1. 1 2
      build/three.js
  2. 5 6
      build/three.min.js
  3. 9 19
      docs/api/core/BufferGeometry.html
  4. 0 6
      docs/api/lights/DirectionalLight.html
  5. 23 30
      docs/api/lights/SpotLight.html
  6. 0 88
      docs/api/loaders/OBJMTLLoader.html
  7. 2 1
      docs/api/materials/LineBasicMaterial.html
  8. 5 6
      docs/api/materials/LineDashedMaterial.html
  9. 20 16
      docs/api/materials/MeshBasicMaterial.html
  10. 8 8
      docs/api/materials/MeshDepthMaterial.html
  11. 24 10
      docs/api/materials/MeshLambertMaterial.html
  12. 1 1
      docs/api/materials/MeshNormalMaterial.html
  13. 45 25
      docs/api/materials/MeshPhongMaterial.html
  14. 221 0
      docs/api/materials/MeshStandardMaterial.html
  15. 9 8
      docs/api/materials/PointsMaterial.html
  16. 1 0
      docs/api/materials/ShaderMaterial.html
  17. 3 3
      docs/api/materials/SpriteMaterial.html
  18. 1 1
      docs/list.js
  19. 43 0
      docs/scenes/js/material.js
  20. 1 0
      editor/js/Config.js
  21. 1 9
      editor/js/Editor.js
  22. 14 0
      editor/js/Sidebar.Project.js
  23. 33 1
      editor/js/libs/app/index.html
  24. 1 0
      examples/files.js
  25. 19 6
      examples/js/effects/VREffect.js
  26. 71 4
      examples/js/exporters/OBJExporter.js
  27. 1 1
      examples/js/loaders/OBJLoader.js
  28. 2 2
      examples/js/loaders/PCDLoader.js
  29. 389 350
      examples/js/modifiers/SubdivisionModifier.js
  30. 1 1
      examples/js/postprocessing/BloomPass.js
  31. 1 1
      examples/js/postprocessing/EffectComposer.js
  32. 144 0
      examples/js/postprocessing/ManualMSAARenderPass.js
  33. 48 0
      examples/js/shaders/CompositeShader.js
  34. 9 11
      examples/webgl_animation_cloth.html
  35. 1 1
      examples/webgl_effects_cardboard.html
  36. 0 1
      examples/webgl_geometry_large_mesh.html
  37. 183 0
      examples/webgl_postprocessing_msaa.html
  38. 37 16
      examples/webgl_postprocessing_smaa.html
  39. 23 29
      examples/webgl_shadowmap_pointlight.html
  40. 7 0
      src/Three.Legacy.js
  41. 0 1
      src/materials/MeshNormalMaterial.js
  42. 2 2
      src/renderers/WebGLRenderer.js
  43. 11 1
      src/renderers/shaders/ShaderChunk/aomap_fragment.glsl
  44. 5 6
      src/renderers/shaders/ShaderChunk/lights_pars.glsl
  45. 7 0
      src/renderers/shaders/ShaderChunk/lights_standard_pars_fragment.glsl
  46. 0 3
      src/renderers/shaders/ShaderLib.js
  47. 2 2
      src/renderers/shaders/UniformsLib.js
  48. 2 2
      src/renderers/webgl/WebGLLights.js
  49. 3 4
      src/renderers/webgl/WebGLShadowMap.js
  50. 7 2
      src/renderers/webgl/WebGLState.js
  51. 28 9
      utils/exporters/blender/addons/io_three/__init__.py
  52. 4 2
      utils/exporters/blender/addons/io_three/constants.py
  53. 1 1
      utils/exporters/blender/addons/io_three/exporter/geometry.py
  54. 12 2
      utils/exporters/blender/addons/io_three/exporter/image.py
  55. 1 1
      utils/exporters/blender/addons/io_three/exporter/scene.py

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


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


+ 9 - 19
docs/api/core/BufferGeometry.html

@@ -27,25 +27,15 @@
 		var geometry = new THREE.BufferGeometry();
 		// create a simple square shape. We duplicate the top left and bottom right
 		// vertices because each vertex needs to appear once per triangle.
-		var vertexPositions = [
-			[-1.0, -1.0,  1.0],
-			[ 1.0, -1.0,  1.0],
-			[ 1.0,  1.0,  1.0],
-
-			[ 1.0,  1.0,  1.0],
-			[-1.0,  1.0,  1.0],
-			[-1.0, -1.0,  1.0]
-		];
-		var vertices = new Float32Array( vertexPositions.length * 3 ); // three components per vertex
-
-		// components of the position vector for each vertex are stored
-		// contiguously in the buffer.
-		for ( var i = 0; i < vertexPositions.length; i++ )
-		{
-			vertices[ i*3 + 0 ] = vertexPositions[i][0];
-			vertices[ i*3 + 1 ] = vertexPositions[i][1];
-			vertices[ i*3 + 2 ] = vertexPositions[i][2];
-		}
+		var vertices = new Float32Array( [
+			-1.0, -1.0,  1.0,
+			 1.0, -1.0,  1.0,
+			 1.0,  1.0,  1.0,
+
+			 1.0,  1.0,  1.0,
+			-1.0,  1.0,  1.0,
+			-1.0, -1.0,  1.0
+		] );
 
 		// itemSize = 3 because there are 3 values (components) per vertex
 		geometry.addAttribute( 'position', new THREE.BufferAttribute( vertices, 3 ) );

+ 0 - 6
docs/api/lights/DirectionalLight.html

@@ -63,12 +63,6 @@ scene.add( directionalLight );</code>
 			Default — *1.0*.
 		</div>
 
-		<h3>[property:Boolean onlyShadow]</h3>
-		<div>
-			If set to *true* light will only cast shadow but not contribute any lighting (as if *intensity* was 0 but cheaper to compute).<br />
-			Default — *false*.
-		</div>
-
 		<h3>[property:Boolean castShadow]</h3>
 		<div>
 			If set to true light will cast dynamic shadows. Warning: This is expensive and requires tweaking to get shadows looking right.<br />

+ 23 - 30
docs/api/lights/SpotLight.html

@@ -13,7 +13,7 @@
 		<h1>[name]</h1>
 
 		<div class="desc">A point light that can cast shadow in one direction.</div>
-		
+
 		<div class="desc">Affects objects using [page:MeshLambertMaterial] or [page:MeshPhongMaterial].</div>
 
 
@@ -24,7 +24,7 @@
 		<div>[example:webgl_materials_cubemap_dynamic materials / cubemap / dynamic ]</div>
 		<div>[example:webgl_morphtargets_md2 morphtargets / md2 ]</div>
 		<div>[example:webgl_shading_physical shading / physical ]</div>
-		
+
 		<code>
 		// white spotlight shining from the side, casting shadow
 
@@ -55,13 +55,13 @@
 		<h2>Constructor</h2>
 
 
-		<h3>[name]([page:Integer hex], [page:Float intensity], [page:Float distance], [page:Radians angle], [page:Float exponent], [page:Float decay])</h3>
+		<h3>[name]([page:Integer hex], [page:Float intensity], [page:Float distance], [page:Radians angle], [page:Float penumbra], [page:Float decay])</h3>
 		<div>
 		[page:Integer hex] — Numeric value of the RGB component of the color. <br />
 		[page:Float intensity] — Numeric value of the light's strength/intensity. <br />
 		[page:Float distance] -- Maximum distance from origin where light will shine whose intensity is attenuated linearly based on distance from origin. <br />
 		[page:Radians angle] -- Maximum angle of light dispersion from its direction whose upper bound is Math.PI/2.<br />
-		[page:Float exponent] -- Rapidity of the falloff of light from its target direction.<br />
+		[page:Float penumbra] -- Percent of the spotlight cone that is attenuated due to penumbra. Takes values between zero and 1. Default is zero.<br />
 		[page:Float decay] -- The amount the light dims along the distance of the light.
 		</div>
 
@@ -73,50 +73,43 @@
 			Default position — *(0,0,0)*.<br />
 			*Note*: Currently for target property to work properly, it must be part of the [page:Scene scene], e.g. this will help: <code>scene.add( light.target )</code>
 		</div>
-	
+
 		<h3>[property:Float intensity]</h3>
 		<div>
 			Light's intensity.<br />
 			Default — *1.0*.
 		</div>
-	
+
 		<h3>[property:Float distance]</h3>
 		<div>
 			If non-zero, light will attenuate linearly from maximum intensity at light *position* down to zero at *distance*.<br />
 			Default — *0.0*.
 		</div>
-	
+
 		<h3>[property:Float angle]</h3>
 		<div>
 			Maximum extent of the spotlight, in radians, from its direction. Should be no more than *Math.PI/2*.<br />
 			Default — *Math.PI/3*.
 		</div>
-	
-		<h3>[property:Float exponent]</h3>
+
+		<h3>[property:Float penumbra]</h3>
 		<div>
-			Rapidity of the falloff of light from its target direction. A lower value spreads out the light, while a higher
-			focuses it towards the center.<br />
-			Default — *10.0*.
+			Percent of the spotlight cone that is attenuated due to penumbra. Takes values between zero and 1.<br />
+			Default — *0.0*.
 		</div>
-		
+
 		<h3>[property:Float decay]</h3>
 		<div>
 			The amount the light dims along the distance of the light<br />
 			Default — *1*.
 		</div>
-	
+
 		<h3>[property:Boolean castShadow]</h3>
 		<div>
 			If set to *true* light will cast dynamic shadows. *Warning*: This is expensive and requires tweaking to get shadows looking right.<br />
 			Default — *false*.
 		</div>
-		
-		<h3>[property:Boolean onlyShadow]</h3>
-		<div>
-			If set to *true* light will only cast shadow but not contribute any lighting (as if *intensity* was 0 but cheaper to compute).<br />
-			Default — *false*.
-		</div>
-		
+
 		<h3>[property:Float shadowCameraNear]</h3>
 		<div>
 			Perspective shadow camera frustum <em>near</em> parameter.<br />
@@ -134,13 +127,13 @@
 			Perspective shadow camera frustum <em>field of view</em> parameter.<br />
 			Default — *50*.
 		</div>
-		
+
 		<h3>[property:Boolean shadowCameraVisible]</h3>
 		<div>
 			Show debug shadow camera frustum.<br />
 			Default — *false*.
 		</div>
-		
+
 		<h3>[property:Float shadowBias]</h3>
 		<div>
 			Shadow map bias, how much to add or subtract from the normalized depth when deciding whether a surface is in shadow.<br />
@@ -158,34 +151,34 @@
 			Shadow map texture height in pixels.<br />
 			Default — *512*.
 		</div>
-		
+
 		<h3>[property:Vector2 shadowMapSize]</h3>
 		<div>
 			The shadowMapWidth and shadowMapHeight stored in a [page:Vector2 THREE.Vector2]. Set internally during rendering.
-		</div> 
+		</div>
 
 		<h3>[property:PerspectiveCamera shadowCamera]</h3>
 		<div>
 			The shadow's view of the world. Computed internally during rendering from the shadowCamera* settings.
-		</div> 
+		</div>
 
 		<h3>[property:Matrix4 shadowMatrix]</h3>
 		<div>
 			Model to shadow camera space, to compute location and depth in shadow map. Computed internally during rendering.
-		</div> 
+		</div>
 
 		<h3>[property:WebGLRenderTarget shadowMap]</h3>
 		<div>
 		    The depth map generated using the shadowCamera; a location beyond a pixel's depth is in shadow. Computed internally during rendering.
-		</div> 
+		</div>
 
-		<h2>Methods</h2>		
+		<h2>Methods</h2>
 		<h3>[method:SpotLight clone]()</h3>
 		<div>
 		<br />
 		It returns a clone of SpotLight.
 		</div>
-		
+
 		<h3>[method:JSON toJSON]()</h3>
 		<div>
 		Return SpotLight data in JSON format.

+ 0 - 88
docs/api/loaders/OBJMTLLoader.html

@@ -1,88 +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>
-
-		<h1>[name]</h1>
-
-		<div class="desc">A loader for loading a <em>.obj</em> and its <em>.mtl</em> together.</div>
-
-
-		<h2>Constructor</h2>
-
-		<h3>[name]( [page:LoadingManager manager] )</h3>
-		<div>
-		[page:LoadingManager manager] — The [page:LoadingManager loadingManager] for the loader to use. Default is [page:LoadingManager THREE.DefaultLoadingManager].
-		</div>
-		<div>
-		Creates a new [name].
-		</div>
-
-		<h2>Properties</h2>
-
-
-		<h2>Methods</h2>
-
-		<h3>[method:null load]( [page:String objUrl], [page:String mtlUrl], [page:Function onLoad], [page:Function onProgress], [page:Function onError] )</h3>
-		<div>
-		[page:String objUrl] — required. URL to the <em>.obj</em> resource<br />
-		[page:String mtlUrl] — required. URL to the <em>.mtl</em> resource<br />
-		[page:Function onLoad] — Will be called when both resources load complete. The argument will be the loaded [page:Object3D].<br />
-		[page:Function onProgress] — Will be called while both load progress. The argument will be the XmlHttpRequest instance, that contain .[page:Integer total] and .[page:Integer loaded] bytes.<br />
-		[page:Function onError] — Will be called when load errors.<br />
-		</div>
-		<div>
-		Begin loading from urls and call onLoad with the parsed response content.
-		</div>
-
-		<h3>[method:Object3D parse]( [page:String text], [page:Function mtllibCallback] )</h3>
-		<div>
-		[page:String text] — required. The textual <em>obj</em> structure to parse.<br/>
-		[page:Function mtllibCallback] — optional. Callback to handle <em>mtllib</em> declaration.<br/>
-		</div>
-		<div>
-		Parse an <em>obj</em> text structure and return an [page:Object3D].<br />
-		Found objects are converted to a [page:Mesh] and materials are converted to [page:MeshLambertMaterial].
-		</div>
-
-		<h2>Example</h2>
-
-		<code>
-		// instantiate a loader
-		var loader = new THREE.OBJMTLLoader();
-
-		// load an obj / mtl resource pair
-		loader.load(
-			// OBJ resource URL
-			'obj/male02/male02.obj',
-			// MTL resource URL
-			'obj/male02/male02_dds.mtl',
-			// Function when both resources are loaded
-			function ( object ) {
-				scene.add( object );
-			},
-			// Function called when downloads progress
-			function ( xhr ) {
-				console.log( (xhr.loaded / xhr.total * 100) + '% loaded' );
-			},
-			// Function called when downloads error
-			function ( xhr ) {
-				console.log( 'An error happened' );
-			}
-		);
-		</code>
-
-		[example:webgl_loader_obj_mtl]
-
-
-		<h2>Source</h2>
-
-		[link:https://github.com/mrdoob/three.js/blob/master/examples/js/loaders/OBJMTLLoader.js examples/js/loaders/OBJMTLLoader.js]
-	</body>
-</html>

+ 2 - 1
docs/api/materials/LineBasicMaterial.html

@@ -31,6 +31,7 @@
 		</div>
 
 		<h2>Properties</h2>
+		<div>See the base [page:Material] class for common properties.</div>
 
 		<h3>[property:Integer color]</h3>
 		<div>Sets the color of the line. Default is 0xffffff.</div>
@@ -55,7 +56,7 @@
 		<div>Define whether the material color is affected by global fog settings.</div>
 		<div>This setting might not have any effect when used with certain renderers. For example, it is ignored with the [page:CanvasRenderer Canvas] renderer, but does work with the [page:WebGLRenderer WebGL] renderer.</div>
 
-		
+
 		<h2>Source</h2>
 
 		[link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js]

+ 5 - 6
docs/api/materials/LineDashedMaterial.html

@@ -32,13 +32,12 @@
 
 
 		<h2>Properties</h2>
-
-
+		<div>See the base [page:Material] class for common properties.</div>
 
 		<h3>[property:Color color]</h3>
 		<div>
 		Sets the color of the line. Default is 0xffffff.
-		</div> 
+		</div>
 
 		<h3>[property:number linewidth]</h3>
 		<div>Controls line thickness. Default is 1.</div>
@@ -47,17 +46,17 @@
 		<h3>[property:number scale]</h3>
 		<div>
 		The scale of the dashed part of a line.
-		</div> 
+		</div>
 
 		<h3>[property:number dashSize]</h3>
 		<div>
 		The size of the dash. This is both the gap with the stroke. Default is 3.
-		</div> 
+		</div>
 
 		<h3>[property:number gapSize]</h3>
 		<div>
 		The size of the gap. Default is 1.
-		</div> 
+		</div>
 
 		<h3>[property:boolean vertexColors]</h3>
 		<div>Define how the vertices gets colored. Possible values are THREE.NoColors, THREE.FaceColors and THREE.VertexColors. Default is THREE.NoColors.</div>

+ 20 - 16
docs/api/materials/MeshBasicMaterial.html

@@ -26,10 +26,14 @@
 		<div>
 		color — geometry color in hexadecimal. Default is 0xffffff.<br />
 		map — Set texture map. Default is null <br />
-		aoMap — Set ambient occlusion map. Default is null <br />
+		aoMap — Set ao map. Default is null.<br />
+		aoMapIntensity — Set ao map intensity. Default is 1.<br />
 		specularMap — Set specular map. Default is null.<br />
 		alphaMap — Set alpha map. Default is null.<br />
 		envMap — Set env map. Default is null.<br />
+		combine — Set combine operation. Default is THREE.MultiplyOperation.<br />
+		reflectivity — Set reflectivity. Default is 1.<br />
+		refractionRatio — Set refraction ratio. Default is 0.98.<br />
 		fog — Define whether the material color is affected by global fog settings. Default is true.<br />
 		shading — Define shading type. Default is THREE.SmoothShading.<br />
 		wireframe — render geometry as wireframe. Default is false.<br />
@@ -42,6 +46,7 @@
 		</div>
 
 		<h2>Properties</h2>
+		<div>See the base [page:Material] class for common properties.</div>
 
 		<h3>[property:Integer color]</h3>
 		<div>Sets the color of the geometry. Default is 0xffffff.</div>
@@ -54,6 +59,9 @@
 		<h3>[property:Texture aoMap]</h3>
 		<div>Set ambient occlusion map. Default is null.</div>
 
+		<h3>[property:Float aoMapIntensity]</h3>
+		<div>TODO</div>
+
 		<h3>[property:Texture specularMap]</h3>
 		<div>Set specular map. Default is null.</div>
 
@@ -64,6 +72,17 @@
 		<h3>[property:TextureCube envMap]</h3>
 		<div>Set env map. Default is null.</div>
 
+		<h3>[property:Integer combine]</h3>
+		<div>How to combine the result of the surface's color with the environment map, if any.</div>
+
+		<div>Options are [page:Textures THREE.Multiply] (default), [page:Textures THREE.MixOperation], [page:Textures THREE.AddOperation]. If mix is chosen, the reflectivity is used to blend between the two colors.</div>
+
+		<h3>[property:Float reflectivity]</h3>
+		<div>How much the environment map affects the surface; also see "combine".</div>
+
+		<h3>[property:Float refractionRatio]</h3>
+		<div>The index of refraction for an environment map using [page:Textures THREE.CubeRefractionMapping]. Default is *0.98*.</div>
+
 		<h3>[property:Boolean fog]</h3>
 		<div>Define whether the material color is affected by global fog settings.</div>
 		<div>This setting might not have any effect when used with certain renderers. For example, it is ignored with the [page:CanvasRenderer Canvas] renderer, but does work with the [page:WebGLRenderer WebGL] renderer.</div>
@@ -96,21 +115,6 @@
 		<h3>[property:Boolean morphTargets]</h3>
 		<div>Define whether the material uses morphTargets. Default is false.</div>
 
-		<h3>[property:number combine]</h3>
-		<div>
-		How to combine the result of the surface's color with the environment map, if any.
-		</div>
-
-		<h3>[property:number reflectivity]</h3>
-		<div>
-		How much the environment map affects the surface; also see "combine".
-		</div>
-
-		<h3>[property:number refractionRatio]</h3>
-		<div>
-		The index of refraction for an environment map using [page:Textures THREE.CubeRefractionMapping]. Default is *0.98*.
-		</div>
-
 		<h2>Methods</h2>
 
 		<h2>Source</h2>

+ 8 - 8
docs/api/materials/MeshDepthMaterial.html

@@ -13,7 +13,7 @@
 		<h1>[name]</h1>
 
 		<div class="desc">A material for drawing geometry by depth. Depth is based off of the camera near and far plane. White is nearest, black is farthest.</div>
-		
+
 		<iframe src='scenes/material-browser.html#MeshDepthMaterial'></iframe>
 
 		<h2>Constructor</h2>
@@ -21,7 +21,7 @@
 
 		<h3>[name]([page:Object parameters])</h3>
 		<div>
-		parameters is an object with one or more properties defining the material's appearance. 
+		parameters is an object with one or more properties defining the material's appearance.
 		</div>
 		<div>
 		morphTargets -- Define whether the material uses morphTargets. Default is false.<br/>
@@ -31,20 +31,20 @@
 
 
 		<h2>Properties</h2>
-
+		<div>See the base [page:Material] class for common properties.</div>
 
 		<h3>[property:boolean morphTargets]</h3>
-		<div>Define whether the material uses morphTargets. Default is false.</div> 
+		<div>Define whether the material uses morphTargets. Default is false.</div>
 
 		<h3>[property:boolean wireframe]</h3>
-		<div>Render geometry as wireframe. Default is false (i.e. render as smooth shaded).</div> 
-		
+		<div>Render geometry as wireframe. Default is false (i.e. render as smooth shaded).</div>
+
 		<h3>[property:number wireframeLinewidth]</h3>
 		<div>
 			Controls wireframe thickness. Default is 1.<br/><br/>
 			Due to limitations in the ANGLE layer, on Windows platforms linewidth will always be 1 regardless of the set value.
-		</div> 
-		
+		</div>
+
 		<h2>Methods</h2>
 
 

+ 24 - 10
docs/api/materials/MeshLambertMaterial.html

@@ -27,11 +27,18 @@
 		color — Line color in hexadecimal. Default is 0xffffff.<br />
 		map — Sets the texture map. Default is null <br />
 		lightMap — Set light map. Default is null.<br />
+		lightMapIntensity — Set light map intensity. Default is 1.<br />
 		aoMap — Set ao map. Default is null.<br />
+		aoMapIntensity — Set ao map intensity. Default is 1.<br />
+		emissive - Set emissive color. Default is 0x000000.<br />
 		emissiveMap — Set emissive map. Default is null.<br />
+		emissiveIntensity — Set emissive map intensity. Default is 1.<br />
 		specularMap — Set specular map. Default is null.<br />
 		alphaMap — Set alpha map. Default is null.<br />
 		envMap — Set env map. Default is null.<br />
+		combine — Set combine operation. Default is THREE.MultiplyOperation.<br />
+		reflectivity — Set reflectivity. Default is 1.<br />
+		refractionRatio — Set refraction ratio. Default is 0.98.<br />
 		fog — Define whether the material color is affected by global fog settings. Default is false.<br />
 		wireframe — Render geometry as wireframe. Default is false (i.e. render as smooth shaded).<br/>
 		wireframeLinewidth — Controls wireframe thickness. Default is 1.<br/>
@@ -39,38 +46,45 @@
 		wireframeLinejoin — Define appearance of line joints. Default is 'round'.<br />
 		vertexColors — Define how the vertices gets colored. Default is THREE.NoColors.<br />
 		skinning — Define whether the material uses skinning. Default is false.<br />
-		morphTargets — Define whether the material uses morphTargets. Default is false.<br/>
+		morphTargets — Define whether the material uses morphTargets. Default is false.<br />
+		morphNormals — Define whether the material uses morphNormals. Default is false.
 		</div>
 
 
 		<h2>Properties</h2>
-		<div>See the base [page:Material] class for common parameters.</div>
+		<div>See the base [page:Material] class for common properties.</div>
 
 		<h3>[property:Color color]</h3>
 		<div>
 		Diffuse color of the material. Default is white.<br />
 		</div>
 
-		<h3>[property:Color emissive]</h3>
-		<div>
-		Emissive (light) color of the material, essentially a solid color unaffected by other lighting. Default is black.<br />
-		</div>
-
-		<h3>[property:Float emissiveIntensity]</h3>
-		<div>Intensity of the emissive light. Modulates the emissive color. Default is 1.</div>
-
 		<h3>[property:Texture map]</h3>
 		<div>Set color texture map. Default is null.</div>
 
 		<h3>[property:Texture lightMap]</h3>
 		<div>Set light map. Default is null. The lightMap requires a second set of UVs.</div>
 
+		<h3>[property:Float lightMapIntensity]</h3>
+		<div>TODO</div>
+
 		<h3>[property:Texture aoMap]</h3>
 		<div>Set ambient occlusion map. Default is null. The aoMap requires a second set of UVs.</div>
 
+		<h3>[property:Float aoMapIntensity]</h3>
+		<div>TODO</div>
+
+		<h3>[property:Color emissive]</h3>
+		<div>
+		Emissive (light) color of the material, essentially a solid color unaffected by other lighting. Default is black.<br />
+		</div>
+
 		<h3>[property:Texture emissiveMap]</h3>
 		<div>Set emisssive (glow) map. Default is null. The emissive map color is modulated by the emissive color and the emissive intensity. If you have an emissive map, be sure to set the emissive color to something other than black.</div>
 
+		<h3>[property:Float emissiveIntensity]</h3>
+		<div>Intensity of the emissive light. Modulates the emissive color. Default is 1.</div>
+
 		<h3>[property:Texture specularMap]</h3>
 		<div>Since this material does not have a specular component, the specular value affects only how much of the environment map affects the surface. Default is null.</div>
 

+ 1 - 1
docs/api/materials/MeshNormalMaterial.html

@@ -32,7 +32,7 @@
 
 
 		<h2>Properties</h2>
-
+		<div>See the base [page:Material] class for common properties.</div>
 
 		<h3>[property:boolean wireframe]</h3>
 		<div>

+ 45 - 25
docs/api/materials/MeshPhongMaterial.html

@@ -21,20 +21,33 @@
 
 		<h3>[name]([page:Object parameters])</h3>
 		<div>
-		parameters -- an object with one or more of the material's properties defining the its appearance.
+		parameters -- an object with one or more of the material's properties defining the material's appearance.
 		</div>
 		<div>
 		color — geometry color in hexadecimal. Default is 0xffffff.<br />
-		map — Set texture map. Default is null <br />
+		specular — Set specular color. Default is 0x111111 .<br />
+		shininess — Set shininess Default is 30.<br />
+		map — Set texture map. Default is null.<br />
 		lightMap — Set light map. Default is null.<br />
+		lightMapIntensity — Set light map intensity. Default is 1.<br />
 		aoMap — Set ao map. Default is null.<br />
+		aoMapIntensity — Set ao map intensity. Default is 1.<br />
+		emissive - Set emissive color. Default is 0x000000.<br />
 		emissiveMap — Set emissive map. Default is null.<br />
-		specularMap — Set specular map. Default is null.<br />
-		alphaMap — Set alpha map. Default is null.<br />
+		emissiveIntensity — Set emissive map intensity. Default is 1.<br />
+		bumpMap — Set bump map. Default is null.<br />
+		bumpMapScale — Set bump map scale. Default is 1.<br />
+		normalMap — Set normal map. Default is null.<br />
+		normalMapScale — Set normal map scale. Default is (1, 1).<br />
 		displacementMap — Set displacement map. Default is null.<br />
 		displacementScale — Set displacement scale. Default is 1.<br />
 		displacementBias — Set displacement offset. Default is 0.<br />
+		specularMap — Set specular map. Default is null.<br />
+		alphaMap — Set alpha map. Default is null.<br />
 		envMap — Set env map. Default is null.<br />
+		combine — Set combine operation. Default is THREE.MultiplyOperation.<br />
+		reflectivity — Set reflectivity. Default is 1.<br />
+		refractionRatio — Set refraction ratio. Default is 0.98.<br />
 		fog — Define whether the material color is affected by global fog settings. Default is true.<br />
 		shading — Define shading type. Default is THREE.SmoothShading.<br />
 		wireframe — render geometry as wireframe. Default is false.<br />
@@ -43,7 +56,8 @@
 		wireframeLinejoin — Define appearance of line joints. Default is 'round'.<br />
 		vertexColors — Define how the vertices gets colored. Default is THREE.NoColors.<br />
 		skinning — Define whether the material uses skinning. Default is false.<br />
-		morphTargets — Define whether the material uses morphTargets. Default is false.
+		morphTargets — Define whether the material uses morphTargets. Default is false.<br />
+		morphNormals — Define whether the material uses morphNormals. Default is false.
 		</div>
 		<div>
 		Example:<br>
@@ -53,21 +67,13 @@
 
 
 		<h2>Properties</h2>
-		<div>See the base [page:Material] class for common parameters.</div>
+		<div>See the base [page:Material] class for common properties.</div>
 
 		<h3>[property:Color color]</h3>
 		<div>
 		Diffuse color of the material. Default is white.<br />
 		</div>
 
-		<h3>[property:Color emissive]</h3>
-		<div>
-		Emissive (light) color of the material, essentially a solid color unaffected by other lighting. Default is black.<br />
-		</div>
-
-		<h3>[property:Float emissiveIntensity]</h3>
-		<div>Intensity of the emissive light. Modulates the emissive color. Default is 1.</div>
-
 		<h3>[property:Color specular]</h3>
 		<div>
 		Specular color of the material, i.e., how shiny the material is and the color of its shine. Setting this the same color as the diffuse value (times some intensity) makes the material more metallic-looking; setting this to some gray makes the material look more plastic. Default is dark gray.<br />
@@ -82,12 +88,26 @@
 		<h3>[property:Texture lightMap]</h3>
 		<div>Set light map. Default is null. The lightMap requires a second set of UVs.</div>
 
+		<h3>[property:Float lightMapIntensity]</h3>
+		<div>TODO</div>
+
 		<h3>[property:Texture aoMap]</h3>
 		<div>Set ambient occlusion map. Default is null. The aoMap requires a second set of UVs.</div>
 
+		<h3>[property:Float aoMapIntensity]</h3>
+		<div>TODO</div>
+
+		<h3>[property:Color emissive]</h3>
+		<div>
+		Emissive (light) color of the material, essentially a solid color unaffected by other lighting. Default is black.<br />
+		</div>
+
 		<h3>[property:Texture emissiveMap]</h3>
 		<div>Set emisssive (glow) map. Default is null. The emissive map color is modulated by the emissive color and the emissive intensity. If you have an emissive map, be sure to set the emissive color to something other than black.</div>
 
+		<h3>[property:Float emissiveIntensity]</h3>
+		<div>Intensity of the emissive light. Modulates the emissive color. Default is 1.</div>
+
 		<h3>[property:Texture bumpMap]</h3>
 		<div>
 			The texture to create a bump map. The black and white values map to the perceived depth in relation to the lights.
@@ -111,29 +131,29 @@
 			How much the normal map affects the material. Typical ranges are 0-1. Default is (1,1).
 		</div>
 
-		<h3>[property:Texture specularMap]</h3>
-		<div>The specular map value affects both how much the specular surface highlight contributes and how much of the environment map affects the surface. Default is null.</div>
-
-		<h3>[property:Texture alphaMap]</h3>
-		<div>The alpha map is a grayscale texture that controls the opacity across the surface (black: fully transparent; white: fully opaque). Default is null.</div>
-		<div>Only the color of the texture is used, ignoring the alpha channel if one exists. For RGB and RGBA textures, the [page:WebGLRenderer WebGL] renderer will use the green channel when sampling this texture due to the extra bit of precision provided for green in DXT-compressed and uncompressed RGB 565 formats. Luminance-only and luminance/alpha textures will also still work as expected.</div>
-
 		<h3>[property:Texture displacementMap]</h3>
 		<div>
-			The displacement map affects the position of the mesh's vertices. Unlike other maps which only affect the light and shade of the material the displaced vertices can cast shadows, block other objects, and otherwise act as real geometry. 
+			The displacement map affects the position of the mesh's vertices. Unlike other maps which only affect the light and shade of the material the displaced vertices can cast shadows, block other objects, and otherwise act as real geometry.
 			The displacement texture is an image where the value of each pixel (white being the highest) is mapped against, and repositions, the vertices of the mesh.
 		</div>
-		
+
 		<h3>[property:Float displacementScale]</h3>
 		<div>
 			How much the displacement map affects the mesh (where black is no displacement, and white is maximum displacement). Without a displacement map set, this value is not applied. Default is 1.
 		</div>
-		
+
 		<h3>[property:Float displacementBias]</h3>
 		<div>
 			The offset of the displacement map's values on the mesh's vertices. Without a displacement map set, this value is not applied. Default is 0.
 		</div>
-		
+
+		<h3>[property:Texture specularMap]</h3>
+		<div>The specular map value affects both how much the specular surface highlight contributes and how much of the environment map affects the surface. Default is null.</div>
+
+		<h3>[property:Texture alphaMap]</h3>
+		<div>The alpha map is a grayscale texture that controls the opacity across the surface (black: fully transparent; white: fully opaque). Default is null.</div>
+		<div>Only the color of the texture is used, ignoring the alpha channel if one exists. For RGB and RGBA textures, the [page:WebGLRenderer WebGL] renderer will use the green channel when sampling this texture due to the extra bit of precision provided for green in DXT-compressed and uncompressed RGB 565 formats. Luminance-only and luminance/alpha textures will also still work as expected.</div>
+
 		<h3>[property:TextureCube envMap]</h3>
 		<div>Set env map. Default is null.</div>
 

+ 221 - 0
docs/api/materials/MeshStandardMaterial.html

@@ -0,0 +1,221 @@
+<!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:Material] &rarr;
+
+		<h1>[name]</h1>
+
+		<div class="desc">TODO</div>
+
+		<iframe src='scenes/material-browser.html#MeshStandardMaterial'></iframe>
+
+		<h2>Constructor</h2>
+
+
+		<h3>[name]([page:Object parameters])</h3>
+		<div>
+		parameters -- an object with one or more of the material's properties defining the material's appearance.
+		</div>
+		<div>
+		color — geometry color in hexadecimal. Default is 0xffffff.<br />
+		roughness — Set roughness. Default is 0.5.<br />
+		metalness — Set metalness. Default is 0.5.<br />
+		map — Set texture map. Default is null.<br />
+		lightMap — Set light map. Default is null.<br />
+		lightMapIntensity — Set light map intensity. Default is 1.<br />
+		aoMap — Set ao map. Default is null.<br />
+		aoMapIntensity — Set ao map intensity. Default is 1.<br />
+		emissive - Set emissive color. Default is 0x000000.<br />
+		emissiveMap — Set emissive map. Default is null.<br />
+		emissiveIntensity — Set emissive map intensity. Default is 1.<br />
+		bumpMap — Set bump map. Default is null.<br />
+		bumpMapScale — Set bump map scale. Default is 1.<br />
+		normalMap — Set normal map. Default is null.<br />
+		normalMapScale — Set normal map scale. Default is (1, 1).<br />
+		displacementMap — Set displacement map. Default is null.<br />
+		displacementScale — Set displacement scale. Default is 1.<br />
+		displacementBias — Set displacement offset. Default is 0.<br />
+		roughnessMap - Set roughness map. Default is null.<br />
+		metalnessMap - Set metalness map. Default is null.<br />
+		alphaMap — Set alpha map. Default is null.<br />
+		envMap — Set env map. Default is null.<br />
+		envMapIntensity — Set env map intensity. Default is 1.0.<br />
+		refractionRatio — Set refraction ratio. Default is 0.98.<br />
+		fog — Define whether the material color is affected by global fog settings. Default is true.<br />
+		shading — Define shading type. Default is THREE.SmoothShading.<br />
+		wireframe — render geometry as wireframe. Default is false.<br />
+		wireframeLinewidth — Line thickness. Default is 1.<br />
+		wireframeLinecap — Define appearance of line ends. Default is 'round'.<br />
+		wireframeLinejoin — Define appearance of line joints. Default is 'round'.<br />
+		vertexColors — Define how the vertices gets colored. Default is THREE.NoColors.<br />
+		skinning — Define whether the material uses skinning. Default is false.<br />
+		morphTargets — Define whether the material uses morphTargets. Default is false.<br />
+		morphNormals — Define whether the material uses morphNormals. Default is false.
+		</div>
+		<div>
+		Example:<br>
+		materials.push( new THREE.MeshStandardMaterial( { color: 0x550000, envMap: reflectionCube, roughness: 0.1, metalness: 1.0 } ) );
+
+		</div>
+
+
+		<h2>Properties</h2>
+		<div>See the base [page:Material] class for common properties.</div>
+
+		<h3>[property:Color color]</h3>
+		<div>
+		Diffuse color of the material. Default is white.<br />
+		</div>
+
+		<h3>[property:Float roughness]</h3>
+		<div>
+		TODO.<br />
+		</div>
+
+		<h3>[property:Float metalness]</h3>
+		<div>
+		TODO<br />
+		</div>
+
+		<h3>[property:Texture map]</h3>
+		<div>Set color texture map. Default is null. The texture map color is modulated by the diffuse color.</div>
+
+		<h3>[property:Texture lightMap]</h3>
+		<div>Set light map. Default is null. The lightMap requires a second set of UVs.</div>
+
+		<h3>[property:Float lightMapIntensity]</h3>
+		<div>TODO</div>
+
+		<h3>[property:Texture aoMap]</h3>
+		<div>Set ambient occlusion map. Default is null. The aoMap requires a second set of UVs.</div>
+
+		<h3>[property:Float aoMapIntensity]</h3>
+		<div>TODO</div>
+
+		<h3>[property:Color emissive]</h3>
+		<div>
+			Emissive (light) color of the material, essentially a solid color unaffected by other lighting. Default is black.<br />
+		</div>
+
+		<h3>[property:Texture emissiveMap]</h3>
+		<div>Set emisssive (glow) map. Default is null. The emissive map color is modulated by the emissive color and the emissive intensity. If you have an emissive map, be sure to set the emissive color to something other than black.</div>
+
+		<h3>[property:Float emissiveIntensity]</h3>
+		<div>Intensity of the emissive light. Modulates the emissive color. Default is 1.</div>
+
+		<h3>[property:Texture bumpMap]</h3>
+		<div>
+			The texture to create a bump map. The black and white values map to the perceived depth in relation to the lights.
+			Bump doesn't actually affect the geometry of the object, only the lighting. If a normal map is defined this will
+			be ignored.
+		</div>
+
+		<h3>[property:Float bumpScale]</h3>
+		<div>
+			How much the bump map affects the material. Typical ranges are 0-1. Default is 1.
+		</div>
+
+		<h3>[property:Texture normalMap]</h3>
+		<div>
+			The texture to create a normal map. The RGB values affect the surface normal for each pixel fragment and change
+			the way the color is lit. Normal maps do not change the actual shape of the surface, only the lighting.
+		</div>
+
+		<h3>[property:Vector2 normalScale]</h3>
+		<div>
+			How much the normal map affects the material. Typical ranges are 0-1. Default is (1, 1).
+		</div>
+
+		<h3>[property:Texture displacementMap]</h3>
+		<div>
+			The displacement map affects the position of the mesh's vertices. Unlike other maps which only affect the light and shade of the material the displaced vertices can cast shadows, block other objects, and otherwise act as real geometry.
+			The displacement texture is an image where the value of each pixel (white being the highest) is mapped against, and repositions, the vertices of the mesh.
+		</div>
+
+		<h3>[property:Float displacementScale]</h3>
+		<div>
+			How much the displacement map affects the mesh (where black is no displacement, and white is maximum displacement). Without a displacement map set, this value is not applied. Default is 1.
+		</div>
+
+		<h3>[property:Float displacementBias]</h3>
+		<div>
+			The offset of the displacement map's values on the mesh's vertices. Without a displacement map set, this value is not applied. Default is 0.
+		</div>
+
+		<h3>[property:Texture roughnessMap]</h3>
+		<div>
+			TODO.
+		</div>
+
+		<h3>[property:Texture metalnessMap]</h3>
+		<div>
+			TODO.
+		</div>
+
+		<h3>[property:Texture alphaMap]</h3>
+		<div>The alpha map is a grayscale texture that controls the opacity across the surface (black: fully transparent; white: fully opaque). Default is null.</div>
+		<div>Only the color of the texture is used, ignoring the alpha channel if one exists. For RGB and RGBA textures, the [page:WebGLRenderer WebGL] renderer will use the green channel when sampling this texture due to the extra bit of precision provided for green in DXT-compressed and uncompressed RGB 565 formats. Luminance-only and luminance/alpha textures will also still work as expected.</div>
+
+		<h3>[property:TextureCube envMap]</h3>
+		<div>Set env map. Default is null.</div>
+
+		<h3>[property:Float envMapIntensity]</h3>
+		<div>TODO</div>
+
+		<h3>[property:Float refractionRatio]</h3>
+		<div>The index of refraction for an environment map using [page:Textures THREE.CubeRefractionMapping]. Default is *0.98*.</div>
+
+		<h3>[property:Boolean fog]</h3>
+		<div>Define whether the material color is affected by global fog settings. Default is *true*.</div>
+		<div>This setting might not have any effect when used with certain renderers. For example, it is ignored with the [page:CanvasRenderer Canvas] renderer, but does work with the [page:WebGLRenderer WebGL] renderer.</div>
+
+		<h3>[property:Integer shading]</h3>
+		<div>How the triangles of a curved surface are rendered: as a smooth surface, as flat separate facets, or no shading at all.</div>
+
+		<div>Options are [page:Materials THREE.SmoothShading] (default), [page:Materials THREE.FlatShading].</div>
+
+		<h3>[property:Boolean wireframe]</h3>
+		<div>Whether the triangles' edges are displayed instead of surfaces. Default is *false*.</div>
+
+		<h3>[property:Float wireframeLinewidth]</h3>
+		<div>Line thickness for wireframe mode. Default is *1.0*.</div>
+		<div>Due to limitations in the <a href="https://code.google.com/p/angleproject/" target="_blank">ANGLE layer</a>, on Windows platforms linewidth will always be 1 regardless of the set value.</div>
+
+		<h3>[property:String wireframeLinecap]</h3>
+		<div>Define appearance of line ends. Possible values are "butt", "round" and "square". Default is 'round'.</div>
+		<div>This setting might not have any effect when used with certain renderers. For example, it is ignored with the [page:WebGLRenderer WebGL] renderer, but does work with the [page:CanvasRenderer Canvas] renderer.</div>
+
+		<h3>[property:String wireframeLinejoin]</h3>
+		<div>Define appearance of line joints. Possible values are "round", "bevel" and "miter". Default is 'round'.</div>
+		<div>This setting might not have any effect when used with certain renderers. For example, it is ignored with the [page:WebGLRenderer WebGL] renderer, but does work with the [page:CanvasRenderer Canvas] renderer.</div>
+
+		<h3>[property:Integer vertexColors]</h3>
+		<div>Define how the vertices gets colored. Possible values are THREE.NoColors, THREE.FaceColors and THREE.VertexColors. Default is THREE.NoColors.</div>
+		<div>This setting might not have any effect when used with certain renderers. For example, it is ignored with the [page:CanvasRenderer Canvas] renderer, but does work with the [page:WebGLRenderer WebGL] renderer.</div>
+
+		<h3>[property:Boolean skinning]</h3>
+		<div>Define whether the material uses skinning. Default is *false*.</div>
+
+		<h3>[property:Boolean morphTargets]</h3>
+		<div>Define whether the material uses morphTargets. Default is *false*.</div>
+
+		<h3>[property:boolean morphNormals]</h3>
+		<div>
+			Defines whether the material uses morphNormals. Set as true to pass morphNormal attributes from the [page:Geometry]
+			to the shader. Default is *false*.
+		</div>
+
+		<h2>Methods</h2>
+
+		<h2>Source</h2>
+
+		[link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js]
+	</body>
+</html>

+ 9 - 8
docs/api/materials/PointsMaterial.html

@@ -20,7 +20,7 @@
 		<h3>[name]( [page:Object parameters] )</h3>
 
 		<div>parameters is an object with one or more properties defining the material's appearance.</div>
-		
+
 		<div>
 		color — Particle color in hexadecimal. Default is 0xffffff.<br />
 		map — a [page:Texture texture].If defined, then a point has the data from texture as colors. Default is null.<br />
@@ -31,27 +31,28 @@
 		</div>
 
 		<h2>Properties</h2>
+		<div>See the base [page:Material] class for common properties.</div>
 
 		<h3>[property:Number color]</h3>
-		
+
 		<div>Sets the color of the particles. Default is 0xffffff.</div>
-		
+
 		<h3>[property:Texture map]</h3>
-		
+
 		<div>Sets the color of the particles using data from a texture.</div>
-		
+
 		<h3>[property:Number size]</h3>
-		
+
 		<div>Sets the size of the particles. Default is 1.0.</div>
 
 		<h3>[property:Boolean sizeAttenuation]</h3>
-		
+
 		<div>Specify whether particles' size will get smaller with the distance. Default is true.</div>
 
 		<h3>[property:Boolean vertexColors]</h3>
 		<div>Define how the vertices gets colored. Possible values are THREE.NoColors, THREE.FaceColors and THREE.VertexColors. Default is THREE.NoColors.</div>
 		<div>This setting might not have any effect when used with certain renderers. For example, it is ignored with the [page:CanvasRenderer Canvas] renderer, but does work with the [page:WebGLRenderer WebGL] renderer.</div>
-		
+
 		<h3>[property:Boolean fog]</h3>
 		<div>Define whether the material color is affected by global fog settings.</div>
 		<div>This setting might not have any effect when used with certain renderers. For example, it is ignored with the [page:CanvasRenderer Canvas] renderer, but does work with the [page:WebGLRenderer WebGL] renderer.</div>

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

@@ -211,6 +211,7 @@
 		</div>
 
 		<h2>Properties</h2>
+		<div>See the base [page:Material] class for common properties.</div>
 
 		<h3>[property:Object uniforms]</h3>
 		<div>

+ 3 - 3
docs/api/materials/SpriteMaterial.html

@@ -31,13 +31,13 @@
 
 
 		<h2>Properties</h2>
-
+		<div>See the base [page:Material] class for common properties.</div>
 
 		<h3>[property:Color color]</h3>
-		<div>The texture is multiplied by this color. The default is 0xffffff</div> 
+		<div>The texture is multiplied by this color. The default is 0xffffff</div>
 
 		<h3>[property:Texture map]</h3>
-		<div>The texture map. Default is null.</div> 
+		<div>The texture map. Default is null.</div>
 
 		<h3>[property:Radians rotation]</h3>
 		<div>The rotation of the sprite in radians. Default is 0.</div>

+ 1 - 1
docs/list.js

@@ -57,7 +57,6 @@ var list = {
 			[ "MaterialLoader", "api/loaders/MaterialLoader" ],
 			[ "MTLLoader", "api/loaders/MTLLoader" ],
 			[ "OBJLoader", "api/loaders/OBJLoader" ],
-			[ "OBJMTLLoader", "api/loaders/OBJMTLLoader" ],
 			[ "ObjectLoader", "api/loaders/ObjectLoader" ],
 			[ "PDBLoader", "api/loaders/PDBLoader" ],
 			[ "SVGLoader", "api/loaders/SVGLoader" ],
@@ -76,6 +75,7 @@ var list = {
 			[ "MeshLambertMaterial", "api/materials/MeshLambertMaterial" ],
 			[ "MeshNormalMaterial", "api/materials/MeshNormalMaterial" ],
 			[ "MeshPhongMaterial", "api/materials/MeshPhongMaterial" ],
+			[ "MeshStandardMaterial", "api/materials/MeshStandardMaterial" ],
 			[ "PointsMaterial", "api/materials/PointsMaterial" ],
 			[ "RawShaderMaterial", "api/materials/RawShaderMaterial" ],
 			[ "ShaderMaterial", "api/materials/ShaderMaterial" ],

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

@@ -453,6 +453,39 @@ function guiMeshPhongMaterial ( gui, mesh, material, geometry ) {
 
 }
 
+function guiMeshStandardMaterial ( gui, mesh, material, geometry ) {
+
+	var data = {
+		color : material.color.getHex(),
+		emissive : material.emissive.getHex(),
+		envMaps : envMapKeys,
+		map : textureMapKeys,
+		lightMap : textureMapKeys,
+		specularMap : textureMapKeys,
+		alphaMap : textureMapKeys
+	};
+
+	var folder = gui.addFolder('THREE.MeshStandardMaterial');
+
+	folder.addColor( data, 'color' ).onChange( handleColorChange( material.color ) );
+	folder.addColor( data, 'emissive' ).onChange( handleColorChange( material.emissive ) );
+
+	folder.add( material, 'roughness', 0, 1 );
+	folder.add( material, 'metalness', 0, 1 );
+	folder.add( material, 'shading', constants.shading).onChange( needsUpdate( material, geometry ) );
+	folder.add( material, 'wireframe' );
+	folder.add( material, 'wireframeLinewidth', 0, 10 );
+	folder.add( material, 'vertexColors', constants.colors);
+	folder.add( material, 'fog' );
+	folder.add( data, 'envMaps', envMapKeys ).onChange( updateTexture( material, 'envMap', envMaps ) );
+	folder.add( data, 'map', textureMapKeys ).onChange( updateTexture( material, 'map', textureMaps ) );
+	folder.add( data, 'lightMap', textureMapKeys ).onChange( updateTexture( material, 'lightMap', textureMaps ) );
+	folder.add( data, 'alphaMap', textureMapKeys ).onChange( updateTexture( material, 'alphaMap', textureMaps ) );
+
+	// TODO roughnessMap and metalnessMap
+
+}
+
 function chooseFromHash ( gui, mesh, geometry ) {
 
 	var selectedMaterial = window.location.hash.substring(1) || "MeshBasicMaterial";
@@ -490,6 +523,16 @@ function chooseFromHash ( gui, mesh, geometry ) {
 
 		break;
 
+	case "MeshStandardMaterial" :
+
+		material = new THREE.MeshStandardMaterial({color: 0x2194CE});
+		guiMaterial( gui, mesh, material, geometry );
+		guiMeshStandardMaterial( gui, mesh, material, geometry );
+
+		return material;
+
+		break;
+
 	case "MeshDepthMaterial" :
 
 		material = new THREE.MeshDepthMaterial({color: 0x2194CE});

+ 1 - 0
editor/js/Config.js

@@ -13,6 +13,7 @@ var Config = function () {
 		'project/renderer': 'WebGLRenderer',
 		'project/renderer/antialias': true,
 		'project/renderer/shadows': true,
+		'project/editable': false,
 		'project/vr': false,
 
 		'settings/history': false,

+ 1 - 9
editor/js/Editor.js

@@ -446,15 +446,6 @@ Editor.prototype = {
 
 		}
 
-		// TODO: Clean this up somehow
-
-		if ( json.project !== undefined ) {
-
-			this.config.setKey( 'project/renderer/shadows', json.project.shadows );
-			this.config.setKey( 'project/vr', json.project.vr );
-
-		}
-
 		var camera = loader.parse( json.camera );
 
 		this.camera.copy( camera );
@@ -494,6 +485,7 @@ Editor.prototype = {
 			metadata: {},
 			project: {
 				shadows: this.config.getKey( 'project/renderer/shadows' ),
+				editable: this.config.getKey( 'project/editable' ),
 				vr: this.config.getKey( 'project/vr' )
 			},
 			camera: this.camera.toJSON(),

+ 14 - 0
editor/js/Sidebar.Project.js

@@ -80,6 +80,20 @@ Sidebar.Project = function ( editor ) {
 
 	container.add( rendererPropertiesRow );
 
+	// Editable
+
+	var editableRow = new UI.Row();
+	var editable = new UI.Checkbox( config.getKey( 'project/editable' ) ).setLeft( '100px' ).onChange( function () {
+
+		config.setKey( 'project/editable', this.getValue() );
+
+	} );
+
+	editableRow.add( new UI.Text( 'Editable' ).setWidth( '90px' ) );
+	editableRow.add( editable );
+
+	container.add( editableRow );
+
 	// VR
 
 	var vrRow = new UI.Row();

+ 33 - 1
editor/js/libs/app/index.html

@@ -6,10 +6,25 @@
 		<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
 		<style>
 		body {
+			font-family: Helvetica, Arial, sans-serif;
+			font-size: 12px;
 			background-color: #000;
 			margin: 0px;
 			overflow: hidden;
 		}
+		#edit {
+			position: absolute;
+			bottom: 20px;
+			right: 20px;
+			padding: 8px;
+			color: #555;
+			background-color: #fff;
+			opacity: 0.5;
+		}
+		#edit:hover {
+			cursor: pointer;
+			opacity: 1;
+		}
 		</style>
 	</head>
 	<body ontouchstart="">
@@ -20,13 +35,30 @@
 			var loader = new THREE.XHRLoader();
 			loader.load( 'app.json', function ( text ) {
 
+				var json = JSON.parse( text );
+
 				var player = new APP.Player();
-				player.load( JSON.parse( text ) );
+				player.load( json );
 				player.setSize( window.innerWidth, window.innerHeight );
 				player.play();
 
 				document.body.appendChild( player.dom );
 
+				if ( json.project.editable === true ) {
+
+					var button = document.createElement( 'div' );
+					button.id = 'edit';
+					button.textContent = 'EDIT';
+					button.addEventListener( 'click', function ( event ) {
+
+						var url = location.href.split( '/' ).slice( 0, - 1 ).join( '/' );
+						window.open( 'http://threejs.org/editor/#file=https://crossorigin.me/' + url + '/app.json' );
+
+					}, false );
+					document.body.appendChild( button );
+
+				}
+
 				window.addEventListener( 'resize', function () {
 					player.setSize( window.innerWidth, window.innerHeight );
 				} );

+ 1 - 0
examples/files.js

@@ -177,6 +177,7 @@ var files = {
 		"webgl_postprocessing_glitch",
 		"webgl_postprocessing_godrays",
 		"webgl_postprocessing_masking",
+		"webgl_postprocessing_msaa",
 		"webgl_postprocessing_nodes",
 		"webgl_postprocessing_smaa",
 		"webgl_postprocessing_ssao",

+ 19 - 6
examples/js/effects/VREffect.js

@@ -12,8 +12,8 @@
 THREE.VREffect = function ( renderer, onError ) {
 
 	var vrHMD;
-	var eyeTranslationL, eyeFOVL;
-	var eyeTranslationR, eyeFOVR;
+	var eyeTranslationL, eyeFOVL, renderRectL;
+	var eyeTranslationR, eyeFOVR, renderRectR;
 
 	function gotVRDevices( devices ) {
 
@@ -102,6 +102,8 @@ THREE.VREffect = function ( renderer, onError ) {
 			eyeTranslationR = eyeParamsR.eyeTranslation;
 			eyeFOVL = eyeParamsL.recommendedFieldOfView;
 			eyeFOVR = eyeParamsR.recommendedFieldOfView;
+			renderRectL = eyeParamsL.renderRect;
+			renderRectR = eyeParamsR.renderRect;
 
 			if ( Array.isArray( scene ) ) {
 
@@ -127,13 +129,24 @@ THREE.VREffect = function ( renderer, onError ) {
 			cameraR.translateX( eyeTranslationR.x * this.scale );
 
 			// render left eye
-			renderer.setViewport( 0, 0, size.width / 2, size.height );
-			renderer.setScissor( 0, 0, size.width / 2, size.height );
+			if ( renderRectL === undefined ) {
+
+				renderRectL = { x: 0, y: 0, width: size.width / 2, height: size.height };
+
+			}
+			renderer.setViewport( renderRectL.x, renderRectL.y, renderRectL.width, renderRectL.height );
+			renderer.setScissor( renderRectL.x, renderRectL.y, renderRectL.width, renderRectL.height );
 			renderer.render( scene, cameraL );
 
 			// render right eye
-			renderer.setViewport( size.width / 2, 0, size.width / 2, size.height );
-			renderer.setScissor( size.width / 2, 0, size.width / 2, size.height );
+			if ( renderRectR === undefined ) {
+
+				renderRectR = { x: size.width / 2, y: 0, width: size.width / 2, height: size.height };
+
+			}
+
+			renderer.setViewport( renderRectR.x, renderRectR.y, renderRectR.width, renderRectR.height );
+			renderer.setScissor( renderRectR.x, renderRectR.y, renderRectR.width, renderRectR.height );
 			renderer.render( scene, cameraR );
 
 			renderer.setScissorTest( false );

+ 71 - 4
examples/js/exporters/OBJExporter.js

@@ -123,11 +123,11 @@ THREE.OBJExporter.prototype = {
 					var face = faces[ i ];
 
 					for ( var m = 0; m < 3; m ++ ) {
-					
+
 					    indices[ m ] = ( indexVertex + face[ faceVertexKeys[ m ] ] + 1 ) + '/' + ( hasVertexUvs ? ( indexVertexUvs + j + m + 1 ) : '' ) + '/' + ( indexNormals + j + m + 1 );
-					
+
 					}
-					
+
 					output += 'f ' + indices.join( ' ' ) + "\n";
 
 				}
@@ -145,9 +145,76 @@ THREE.OBJExporter.prototype = {
 
 		};
 
+		var parseLine = function( line ) {
+
+			var geometry = line.geometry;
+			var type = line.type;
+
+			if ( geometry instanceof THREE.BufferGeometry ) {
+
+				geometry = new THREE.Geometry().fromBufferGeometry( geometry );
+
+			}
+
+			if ( geometry instanceof THREE.Geometry ) {
+
+				output += 'o ' + line.name + '\n';
+
+				var vertices = geometry.vertices;
+
+				for ( var i = 0, l = vertices.length; i < l; i++ ) {
+
+					var vertex = vertices[ i ].clone();
+					vertex.applyMatrix4( line.matrixWorld );
+
+					output += 'v ' + vertex.x + ' ' + vertex.y + ' ' + vertex.z + '\n';
+
+				}
+
+				if ( type === 'Line' ) {
+
+					output += 'l ';
+
+					for ( var j = 1, m = vertices.length; j <= m; j++ ) {
+
+						output += j + ' ';
+
+					}
+
+					output += '\n';
+
+				}
+
+				if ( type === 'LineSegments' ) {
+
+					for ( var j = 1, k = j + 1, m = vertices.length; j < m; j += 2, k = j + 1 ) {
+
+						output += 'l ' + j + ' ' + k + '\n';
+
+					}
+
+				}
+
+			} else {
+
+				console.warn('THREE.OBJExporter.parseLine(): geometry type unsupported', line);
+
+			}
+		};
+
 		object.traverse( function ( child ) {
 
-			if ( child instanceof THREE.Mesh ) parseMesh( child );
+			if ( child instanceof THREE.Mesh ) {
+
+				parseMesh( child );
+
+			}
+
+			if ( child instanceof THREE.Line ) {
+
+				parseLine( child );
+
+			}
 
 		} );
 

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

@@ -217,7 +217,7 @@ THREE.OBJLoader.prototype = {
 
 		var object_pattern = /^[og]\s+(.+)/;
 
-		var smoothing_pattern = /^s\s+([01]|on|off)/;
+		var smoothing_pattern = /^s\s+(\d+|on|off)/;
 
 		//
 

+ 2 - 2
examples/js/loaders/PCDLoader.js

@@ -33,7 +33,7 @@ THREE.PCDLoader.prototype = {
 
 	binarryToStr: function( data ) {
 
-		text = "";
+		var text = "";
 		var charArray = new Uint8Array( data );
 		for ( var i = 0; i < data.byteLength; i ++ ) {
 
@@ -125,7 +125,7 @@ THREE.PCDLoader.prototype = {
 
 	parse: function( data, url ) {
 
-		textData = this.binarryToStr( data );
+		var textData = this.binarryToStr( data );
 
 		// Parse the header
 		// Header is always ascii format

+ 389 - 350
examples/js/modifiers/SubdivisionModifier.js

@@ -1,350 +1,389 @@
-/*
- *	@author zz85 / http://twitter.com/blurspline / http://www.lab4games.net/zz85/blog 
- *
- *	Subdivision Geometry Modifier 
- *		using Loop Subdivision Scheme
- *
- *	References:
- *		http://graphics.stanford.edu/~mdfisher/subdivision.html
- *		http://www.holmes3d.net/graphics/subdivision/
- *		http://www.cs.rutgers.edu/~decarlo/readings/subdiv-sg00c.pdf
- *
- *	Known Issues:
- *		- currently doesn't handle UVs
- *		- currently doesn't handle "Sharp Edges"
- *
- */
-
-THREE.SubdivisionModifier = function ( subdivisions ) {
-
-	this.subdivisions = ( subdivisions === undefined ) ? 1 : subdivisions;
-
-};
-
-// Applies the "modify" pattern
-THREE.SubdivisionModifier.prototype.modify = function ( geometry ) {
-
-	var repeats = this.subdivisions;
-
-	while ( repeats -- > 0 ) {
-
-		this.smooth( geometry );
-
-	}
-
-	delete geometry.__tmpVertices;
-
-	geometry.computeFaceNormals();
-	geometry.computeVertexNormals();
-
-};
-
-( function() {
-
-	// Some constants
-	var WARNINGS = ! true; // Set to true for development
-	var ABC = [ 'a', 'b', 'c' ];
-	
-
-	function getEdge( a, b, map ) {
-
-		var vertexIndexA = Math.min( a, b );
-		var vertexIndexB = Math.max( a, b );
-
-		var key = vertexIndexA + "_" + vertexIndexB;
-
-		return map[ key ];
-
-	}
-
-
-	function processEdge( a, b, vertices, map, face, metaVertices ) {
-
-		var vertexIndexA = Math.min( a, b );
-		var vertexIndexB = Math.max( a, b );
-
-		var key = vertexIndexA + "_" + vertexIndexB;
-
-		var edge;
-
-		if ( key in map ) {
-
-			edge = map[ key ];
-
-		} else {
-			
-			var vertexA = vertices[ vertexIndexA ];
-			var vertexB = vertices[ vertexIndexB ];
-
-			edge = {
-
-				a: vertexA, // pointer reference
-				b: vertexB,
-				newEdge: null,
-				// aIndex: a, // numbered reference
-				// bIndex: b,
-				faces: [] // pointers to face
-
-			};
-
-			map[ key ] = edge;
-
-		}
-
-		edge.faces.push( face );
-
-		metaVertices[ a ].edges.push( edge );
-		metaVertices[ b ].edges.push( edge );
-		
-
-	}
-
-	function generateLookups( vertices, faces, metaVertices, edges ) {
-
-		var i, il, face, edge;
-
-		for ( i = 0, il = vertices.length; i < il; i ++ ) {
-
-			metaVertices[ i ] = { edges: [] };
-
-		}
-		
-		for ( i = 0, il = faces.length; i < il; i ++ ) {
-
-			face = faces[ i ];
-
-			processEdge( face.a, face.b, vertices, edges, face, metaVertices );
-			processEdge( face.b, face.c, vertices, edges, face, metaVertices );
-			processEdge( face.c, face.a, vertices, edges, face, metaVertices );
-
-		}
-
-	}
-
-	function newFace( newFaces, a, b, c ) {
-
-		newFaces.push( new THREE.Face3( a, b, c ) );
-
-	}
-
-
-	/////////////////////////////
-
-	// Performs one iteration of Subdivision
-	THREE.SubdivisionModifier.prototype.smooth = function ( geometry ) {
-
-		var tmp = new THREE.Vector3();
-
-		var oldVertices, oldFaces;
-		var newVertices, newFaces; // newUVs = [];
-
-		var n, l, i, il, j, k;
-		var metaVertices, sourceEdges;
-
-		// new stuff.
-		var sourceEdges, newEdgeVertices, newSourceVertices;
-
-		oldVertices = geometry.vertices; // { x, y, z}
-		oldFaces = geometry.faces; // { a: oldVertex1, b: oldVertex2, c: oldVertex3 }
-
-		/******************************************************
-		 *
-		 * Step 0: Preprocess Geometry to Generate edges Lookup
-		 *
-		 *******************************************************/
-
-		metaVertices = new Array( oldVertices.length );
-		sourceEdges = {}; // Edge => { oldVertex1, oldVertex2, faces[]  }
-
-		generateLookups( oldVertices, oldFaces, metaVertices, sourceEdges );
-
-
-		/******************************************************
-		 *
-		 *	Step 1. 
-		 *	For each edge, create a new Edge Vertex,
-		 *	then position it.
-		 *
-		 *******************************************************/
-
-		newEdgeVertices = [];
-		var other, currentEdge, newEdge, face;
-		var edgeVertexWeight, adjacentVertexWeight, connectedFaces;
-
-		for ( i in sourceEdges ) {
-
-			currentEdge = sourceEdges[ i ];
-			newEdge = new THREE.Vector3();
-
-			edgeVertexWeight = 3 / 8;
-			adjacentVertexWeight = 1 / 8;
-
-			connectedFaces = currentEdge.faces.length;
-
-			// check how many linked faces. 2 should be correct.
-			if ( connectedFaces != 2 ) {
-
-				// if length is not 2, handle condition
-				edgeVertexWeight = 0.5;
-				adjacentVertexWeight = 0;
-
-				if ( connectedFaces != 1 ) {
-					
-					if ( WARNINGS ) console.warn( 'Subdivision Modifier: Number of connected faces != 2, is: ', connectedFaces, currentEdge );
-			
-				}
-
-			}
-
-			newEdge.addVectors( currentEdge.a, currentEdge.b ).multiplyScalar( edgeVertexWeight );
-
-			tmp.set( 0, 0, 0 );
-
-			for ( j = 0; j < connectedFaces; j ++ ) {
-
-				face = currentEdge.faces[ j ];
-				
-				for ( k = 0; k < 3; k ++ ) {
-
-					other = oldVertices[ face[ ABC[ k ] ] ];
-					if ( other !== currentEdge.a && other !== currentEdge.b ) break;
-
-				}
-
-				tmp.add( other );
-
-			}
-
-			tmp.multiplyScalar( adjacentVertexWeight );
-			newEdge.add( tmp );
-
-			currentEdge.newEdge = newEdgeVertices.length;
-			newEdgeVertices.push( newEdge );
-
-			// console.log(currentEdge, newEdge);
-
-		}
-
-		/******************************************************
-		 *
-		 *	Step 2. 
-		 *	Reposition each source vertices.
-		 *
-		 *******************************************************/
-
-		var beta, sourceVertexWeight, connectingVertexWeight;
-		var connectingEdge, connectingEdges, oldVertex, newSourceVertex;
-		newSourceVertices = [];
-
-		for ( i = 0, il = oldVertices.length; i < il; i ++ ) {
-
-			oldVertex = oldVertices[ i ];
-
-			// find all connecting edges (using lookupTable)
-			connectingEdges = metaVertices[ i ].edges;
-			n = connectingEdges.length;
-			beta;
-
-			if ( n == 3 ) {
-
-				beta = 3 / 16;
-
-			} else if ( n > 3 ) {
-
-				beta = 3 / ( 8 * n ); // Warren's modified formula
-
-			}
-
-			// Loop's original beta formula
-			// beta = 1 / n * ( 5/8 - Math.pow( 3/8 + 1/4 * Math.cos( 2 * Math. PI / n ), 2) );
-
-			sourceVertexWeight = 1 - n * beta;
-			connectingVertexWeight = beta;
-
-			if ( n <= 2 ) {
-				
-				// crease and boundary rules
-				// console.warn('crease and boundary rules');
-
-				if ( n == 2 ) {
-
-					if ( WARNINGS ) console.warn( '2 connecting edges', connectingEdges );
-					sourceVertexWeight = 3 / 4;
-					connectingVertexWeight = 1 / 8;
-
-					// sourceVertexWeight = 1;
-					// connectingVertexWeight = 0;
-
-				} else if ( n == 1 ) {
-
-					if ( WARNINGS ) console.warn( 'only 1 connecting edge' );
-
-				} else if ( n == 0 ) {
-
-					if ( WARNINGS ) console.warn( '0 connecting edges' );
-			
-				}
-			
-			}
-
-			newSourceVertex = oldVertex.clone().multiplyScalar( sourceVertexWeight );
-
-			tmp.set( 0, 0, 0 );
-
-			for ( j = 0; j < n; j ++ ) {
-
-				connectingEdge = connectingEdges[ j ];
-				other = connectingEdge.a !== oldVertex ? connectingEdge.a : connectingEdge.b;
-				tmp.add( other );
-
-			}
-
-			tmp.multiplyScalar( connectingVertexWeight );
-			newSourceVertex.add( tmp );
-			
-			newSourceVertices.push( newSourceVertex );
-
-		}
-
-							   
-		/******************************************************
-		 *
-		 *	Step 3. 
-		 *	Generate Faces between source vertecies
-		 *	and edge vertices.
-		 *
-		 *******************************************************/
-
-		newVertices = newSourceVertices.concat( newEdgeVertices );
-		var sl = newSourceVertices.length, edge1, edge2, edge3;
-		newFaces = [];
-
-		for ( i = 0, il = oldFaces.length; i < il; i ++ ) {
-
-			face = oldFaces[ i ];
-
-			// find the 3 new edges vertex of each old face
-
-			edge1 = getEdge( face.a, face.b, sourceEdges ).newEdge + sl;
-			edge2 = getEdge( face.b, face.c, sourceEdges ).newEdge + sl;
-			edge3 = getEdge( face.c, face.a, sourceEdges ).newEdge + sl;
-
-			// create 4 faces.
-
-			newFace( newFaces, edge1, edge2, edge3 );
-			newFace( newFaces, face.a, edge1, edge3 );
-			newFace( newFaces, face.b, edge2, edge1 );
-			newFace( newFaces, face.c, edge3, edge2 );
-
-		}
-
-		// Overwrite old arrays
-		geometry.vertices = newVertices;
-		geometry.faces = newFaces;
-
-		// console.log('done');
-
-	};
-
-
-} )();
+/*
+ *	@author zz85 / http://twitter.com/blurspline / http://www.lab4games.net/zz85/blog
+ *	@author centerionware / http://www.centerionware.com
+ *
+ *	Subdivision Geometry Modifier
+ *		using Loop Subdivision Scheme
+ *
+ *	References:
+ *		http://graphics.stanford.edu/~mdfisher/subdivision.html
+ *		http://www.holmes3d.net/graphics/subdivision/
+ *		http://www.cs.rutgers.edu/~decarlo/readings/subdiv-sg00c.pdf
+ *
+ *	Known Issues:
+ *		- currently doesn't handle "Sharp Edges"
+ */
+
+THREE.SubdivisionModifier = function ( subdivisions ) {
+
+	this.subdivisions = ( subdivisions === undefined ) ? 1 : subdivisions;
+
+};
+
+// Applies the "modify" pattern
+THREE.SubdivisionModifier.prototype.modify = function ( geometry ) {
+
+	var repeats = this.subdivisions;
+
+	while ( repeats -- > 0 ) {
+
+		this.smooth( geometry );
+
+	}
+
+	delete geometry.__tmpVertices;
+
+	geometry.computeFaceNormals();
+	geometry.computeVertexNormals();
+
+};
+
+( function() {
+
+	// Some constants
+	var WARNINGS = ! true; // Set to true for development
+	var ABC = [ 'a', 'b', 'c' ];
+
+
+	function getEdge( a, b, map ) {
+
+		var vertexIndexA = Math.min( a, b );
+		var vertexIndexB = Math.max( a, b );
+
+		var key = vertexIndexA + "_" + vertexIndexB;
+
+		return map[ key ];
+
+	}
+
+
+	function processEdge( a, b, vertices, map, face, metaVertices ) {
+
+		var vertexIndexA = Math.min( a, b );
+		var vertexIndexB = Math.max( a, b );
+
+		var key = vertexIndexA + "_" + vertexIndexB;
+
+		var edge;
+
+		if ( key in map ) {
+
+			edge = map[ key ];
+
+		} else {
+
+			var vertexA = vertices[ vertexIndexA ];
+			var vertexB = vertices[ vertexIndexB ];
+
+			edge = {
+
+				a: vertexA, // pointer reference
+				b: vertexB,
+				newEdge: null,
+				// aIndex: a, // numbered reference
+				// bIndex: b,
+				faces: [] // pointers to face
+
+			};
+
+			map[ key ] = edge;
+
+		}
+
+		edge.faces.push( face );
+
+		metaVertices[ a ].edges.push( edge );
+		metaVertices[ b ].edges.push( edge );
+
+
+	}
+
+	function generateLookups( vertices, faces, metaVertices, edges ) {
+
+		var i, il, face, edge;
+
+		for ( i = 0, il = vertices.length; i < il; i ++ ) {
+
+			metaVertices[ i ] = { edges: [] };
+
+		}
+
+		for ( i = 0, il = faces.length; i < il; i ++ ) {
+
+			face = faces[ i ];
+
+			processEdge( face.a, face.b, vertices, edges, face, metaVertices );
+			processEdge( face.b, face.c, vertices, edges, face, metaVertices );
+			processEdge( face.c, face.a, vertices, edges, face, metaVertices );
+
+		}
+
+	}
+
+	function newFace( newFaces, a, b, c ) {
+
+		newFaces.push( new THREE.Face3( a, b, c ) );
+
+	}
+
+	function midpoint( a, b ) {
+
+		return ( Math.abs( b - a ) / 2 ) + Math.min( a, b );
+
+	}
+
+	function newUv( newUvs, a, b, c ) {
+
+		newUvs.push( [ a.clone(), b.clone(), c.clone() ] );
+
+	}
+
+	/////////////////////////////
+
+	// Performs one iteration of Subdivision
+	THREE.SubdivisionModifier.prototype.smooth = function ( geometry ) {
+
+		var tmp = new THREE.Vector3();
+
+		var oldVertices, oldFaces, oldUvs;
+		var newVertices, newFaces, newUVs = [];
+
+		var n, l, i, il, j, k;
+		var metaVertices, sourceEdges;
+
+		// new stuff.
+		var sourceEdges, newEdgeVertices, newSourceVertices;
+
+		oldVertices = geometry.vertices; // { x, y, z}
+		oldFaces = geometry.faces; // { a: oldVertex1, b: oldVertex2, c: oldVertex3 }
+		oldUvs = geometry.faceVertexUvs[ 0 ];
+
+		var hasUvs = oldUvs !== undefined && oldUvs.length > 0;
+
+		/******************************************************
+		 *
+		 * Step 0: Preprocess Geometry to Generate edges Lookup
+		 *
+		 *******************************************************/
+
+		metaVertices = new Array( oldVertices.length );
+		sourceEdges = {}; // Edge => { oldVertex1, oldVertex2, faces[]  }
+
+		generateLookups( oldVertices, oldFaces, metaVertices, sourceEdges );
+
+
+		/******************************************************
+		 *
+		 *	Step 1.
+		 *	For each edge, create a new Edge Vertex,
+		 *	then position it.
+		 *
+		 *******************************************************/
+
+		newEdgeVertices = [];
+		var other, currentEdge, newEdge, face;
+		var edgeVertexWeight, adjacentVertexWeight, connectedFaces;
+
+		for ( i in sourceEdges ) {
+
+			currentEdge = sourceEdges[ i ];
+			newEdge = new THREE.Vector3();
+
+			edgeVertexWeight = 3 / 8;
+			adjacentVertexWeight = 1 / 8;
+
+			connectedFaces = currentEdge.faces.length;
+
+			// check how many linked faces. 2 should be correct.
+			if ( connectedFaces != 2 ) {
+
+				// if length is not 2, handle condition
+				edgeVertexWeight = 0.5;
+				adjacentVertexWeight = 0;
+
+				if ( connectedFaces != 1 ) {
+
+					if ( WARNINGS ) console.warn( 'Subdivision Modifier: Number of connected faces != 2, is: ', connectedFaces, currentEdge );
+
+				}
+
+			}
+
+			newEdge.addVectors( currentEdge.a, currentEdge.b ).multiplyScalar( edgeVertexWeight );
+
+			tmp.set( 0, 0, 0 );
+
+			for ( j = 0; j < connectedFaces; j ++ ) {
+
+				face = currentEdge.faces[ j ];
+
+				for ( k = 0; k < 3; k ++ ) {
+
+					other = oldVertices[ face[ ABC[ k ] ] ];
+					if ( other !== currentEdge.a && other !== currentEdge.b ) break;
+
+				}
+
+				tmp.add( other );
+
+			}
+
+			tmp.multiplyScalar( adjacentVertexWeight );
+			newEdge.add( tmp );
+
+			currentEdge.newEdge = newEdgeVertices.length;
+			newEdgeVertices.push( newEdge );
+
+			// console.log(currentEdge, newEdge);
+
+		}
+
+		/******************************************************
+		 *
+		 *	Step 2.
+		 *	Reposition each source vertices.
+		 *
+		 *******************************************************/
+
+		var beta, sourceVertexWeight, connectingVertexWeight;
+		var connectingEdge, connectingEdges, oldVertex, newSourceVertex;
+		newSourceVertices = [];
+
+		for ( i = 0, il = oldVertices.length; i < il; i ++ ) {
+
+			oldVertex = oldVertices[ i ];
+
+			// find all connecting edges (using lookupTable)
+			connectingEdges = metaVertices[ i ].edges;
+			n = connectingEdges.length;
+
+			if ( n == 3 ) {
+
+				beta = 3 / 16;
+
+			} else if ( n > 3 ) {
+
+				beta = 3 / ( 8 * n ); // Warren's modified formula
+
+			}
+
+			// Loop's original beta formula
+			// beta = 1 / n * ( 5/8 - Math.pow( 3/8 + 1/4 * Math.cos( 2 * Math. PI / n ), 2) );
+
+			sourceVertexWeight = 1 - n * beta;
+			connectingVertexWeight = beta;
+
+			if ( n <= 2 ) {
+
+				// crease and boundary rules
+				// console.warn('crease and boundary rules');
+
+				if ( n == 2 ) {
+
+					if ( WARNINGS ) console.warn( '2 connecting edges', connectingEdges );
+					sourceVertexWeight = 3 / 4;
+					connectingVertexWeight = 1 / 8;
+
+					// sourceVertexWeight = 1;
+					// connectingVertexWeight = 0;
+
+				} else if ( n == 1 ) {
+
+					if ( WARNINGS ) console.warn( 'only 1 connecting edge' );
+
+				} else if ( n == 0 ) {
+
+					if ( WARNINGS ) console.warn( '0 connecting edges' );
+
+				}
+
+			}
+
+			newSourceVertex = oldVertex.clone().multiplyScalar( sourceVertexWeight );
+
+			tmp.set( 0, 0, 0 );
+
+			for ( j = 0; j < n; j ++ ) {
+
+				connectingEdge = connectingEdges[ j ];
+				other = connectingEdge.a !== oldVertex ? connectingEdge.a : connectingEdge.b;
+				tmp.add( other );
+
+			}
+
+			tmp.multiplyScalar( connectingVertexWeight );
+			newSourceVertex.add( tmp );
+
+			newSourceVertices.push( newSourceVertex );
+
+		}
+
+
+		/******************************************************
+		 *
+		 *	Step 3.
+		 *	Generate Faces between source vertices
+		 *	and edge vertices.
+		 *
+		 *******************************************************/
+
+		newVertices = newSourceVertices.concat( newEdgeVertices );
+		var sl = newSourceVertices.length, edge1, edge2, edge3;
+		newFaces = [];
+
+		var uv, x0, x1, x2;
+		var x3 = new THREE.Vector2();
+		var x4 = new THREE.Vector2();
+		var x5 = new THREE.Vector2();
+
+		for ( i = 0, il = oldFaces.length; i < il; i ++ ) {
+
+			face = oldFaces[ i ];
+
+			// find the 3 new edges vertex of each old face
+
+			edge1 = getEdge( face.a, face.b, sourceEdges ).newEdge + sl;
+			edge2 = getEdge( face.b, face.c, sourceEdges ).newEdge + sl;
+			edge3 = getEdge( face.c, face.a, sourceEdges ).newEdge + sl;
+
+			// create 4 faces.
+
+			newFace( newFaces, edge1, edge2, edge3 );
+			newFace( newFaces, face.a, edge1, edge3 );
+			newFace( newFaces, face.b, edge2, edge1 );
+			newFace( newFaces, face.c, edge3, edge2 );
+
+			// create 4 new uv's
+
+			if ( hasUvs ) {
+
+				uv = oldUvs[ i ];
+
+				x0 = uv[ 0 ];
+				x1 = uv[ 1 ];
+				x2 = uv[ 2 ];
+
+				x3.set( midpoint( x0.x, x1.x ), midpoint( x0.y, x1.y ) );
+				x4.set( midpoint( x1.x, x2.x ), midpoint( x1.y, x2.y ) );
+				x5.set( midpoint( x0.x, x2.x ), midpoint( x0.y, x2.y ) );
+
+				newUv( newUVs, x3, x4, x5 );
+				newUv( newUVs, x0, x3, x5 );
+
+				newUv( newUVs, x1, x4, x3 );
+				newUv( newUVs, x2, x5, x4 );
+
+			}
+
+		}
+
+		// Overwrite old arrays
+		geometry.vertices = newVertices;
+		geometry.faces = newFaces;
+		if ( hasUvs ) geometry.faceVertexUvs[ 0 ] = newUVs;
+
+		// console.log('done');
+
+	};
+
+} )();

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

@@ -11,7 +11,7 @@ THREE.BloomPass = function ( strength, kernelSize, sigma, resolution ) {
 
 	// render targets
 
-	var pars = { minFilter: THREE.LinearFilter, magFilter: THREE.LinearFilter, format: THREE.RGBFormat };
+	var pars = { minFilter: THREE.LinearFilter, magFilter: THREE.LinearFilter, format: THREE.RGBAFormat };
 
 	this.renderTargetX = new THREE.WebGLRenderTarget( resolution, resolution, pars );
 	this.renderTargetY = new THREE.WebGLRenderTarget( resolution, resolution, pars );

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

@@ -12,7 +12,7 @@ THREE.EffectComposer = function ( renderer, renderTarget ) {
 
 		var width  = Math.floor( renderer.context.canvas.width  / pixelRatio ) || 1;
 		var height = Math.floor( renderer.context.canvas.height / pixelRatio ) || 1;
-		var parameters = { minFilter: THREE.LinearFilter, magFilter: THREE.LinearFilter, format: THREE.RGBFormat, stencilBuffer: false };
+		var parameters = { minFilter: THREE.LinearFilter, magFilter: THREE.LinearFilter, format: THREE.RGBAFormat, stencilBuffer: false };
 
 		renderTarget = new THREE.WebGLRenderTarget( width, height, parameters );
 

+ 144 - 0
examples/js/postprocessing/ManualMSAARenderPass.js

@@ -0,0 +1,144 @@
+/**
+ * @author bhouston / http://clara.io/ *
+ */
+
+THREE.ManualMSAARenderPass = function ( scene, camera, params ) {
+
+	this.scene = scene;
+	this.camera = camera;
+
+	this.sampleLevel = 4; // specified as n, where the number of samples is 2^n, so sampleLevel = 4, is 2^4 samples, 16.
+
+	this.params = params || { minFilter: THREE.NearestFilter, magFilter: THREE.NearestFilter, format: THREE.RGBAFormat };
+	this.params.minFilter = THREE.NearestFilter;
+	this.params.maxFilter = THREE.NearestFilter;
+	this.enabled = true;
+
+	this.needsSwap = true;
+
+	if ( THREE.CompositeShader === undefined ) {
+
+		console.error( "THREE.MSAAPass relies on THREE.CompositeShader" );
+
+	}
+
+	var compositeShader = THREE.CompositeShader;
+	this.uniforms = THREE.UniformsUtils.clone( compositeShader.uniforms );
+
+	this.materialComposite = new THREE.ShaderMaterial(	{
+
+		uniforms: this.uniforms,
+		vertexShader: compositeShader.vertexShader,
+		fragmentShader: compositeShader.fragmentShader,
+		transparent: true,
+		blending: THREE.CustomBlending,
+		blendSrc: THREE.OneFactor,
+		blendDst: THREE.OneFactor,
+		blendEquation: THREE.AddEquation,
+		depthTest: false,
+		depthWrite: false
+
+	} );
+
+	this.camera2 = new THREE.OrthographicCamera( - 1, 1, 1, - 1, 0, 1 );
+	this.scene2	= new THREE.Scene();
+	this.quad2 = new THREE.Mesh( new THREE.PlaneGeometry( 2, 2 ), this.materialComposite );
+	this.scene2.add( this.quad2 );
+
+};
+
+THREE.ManualMSAARenderPass.prototype = {
+
+	dispose: function() {
+
+		if ( this.sampleRenderTarget ) {
+
+			this.sampleRenderTarget.dispose();
+			this.sampleRenderTarget = null;
+
+		}
+
+	},
+
+
+	setSize: function ( width, height ) {
+
+		this.sampleRenderTarget.setSize( width, height );
+
+	},
+
+	render: function ( renderer, writeBuffer, readBuffer, delta ) {
+
+		var camera = ( this.camera || this.scene.camera );
+		var jitterOffsets = THREE.ManualMSAARenderPass.JitterVectors[ Math.max( 0, Math.min( this.sampleLevel, 4 ) ) ];
+
+		if( jitterOffsets.length === 1 ) {
+
+			renderer.render( this.scene, camera, writeBuffer, true );
+			return;
+
+		}
+
+		if ( ! this.sampleRenderTarget ) {
+
+			this.sampleRenderTarget = new THREE.WebGLRenderTarget( readBuffer.width, readBuffer.height, this.params );
+
+		}
+
+		var autoClear = renderer.autoClear;
+		renderer.autoClear = false;
+
+		this.uniforms[ "scale" ].value = 1.0 / ( jitterOffsets.length );
+		this.uniforms[ "tForeground" ].value = this.sampleRenderTarget;
+
+		// render the scene multiple times, each slightly jitter offset from the last and accumulate the results.
+		for ( var i = 0; i < jitterOffsets.length; i ++ ) {
+
+			// only jitters perspective cameras.	TODO: add support for jittering orthogonal cameras
+			var jitterOffset = jitterOffsets[i];
+			if ( camera.setViewOffset ) {
+				camera.setViewOffset( readBuffer.width, readBuffer.height,
+					jitterOffset[ 0 ] * 0.0625, jitterOffset[ 1 ] * 0.0625,   // 0.0625 = 1 / 16
+					readBuffer.width, readBuffer.height );
+			}
+
+			renderer.render( this.scene, this.camera, this.sampleRenderTarget, true );
+			renderer.render( this.scene2, this.camera2, writeBuffer, ( i === 0 ) );
+
+		}
+
+		// reset jitter to nothing.	TODO: add support for orthogonal cameras
+		if ( camera.setViewOffset ) camera.setViewOffset( undefined, undefined, undefined, undefined, undefined, undefined );
+
+		renderer.autoClear = true;
+
+	}
+
+};
+
+// These jitter vectors are specified in integers because it is easier.
+// I am assuming a [-8,8) integer grid, but it needs to be mapped onto [-0.5,0.5)
+// before being used, thus these integers need to be scaled by 1/16.
+//
+// Sample patterns reference: https://msdn.microsoft.com/en-us/library/windows/desktop/ff476218%28v=vs.85%29.aspx?f=255&MSPPError=-2147217396
+THREE.ManualMSAARenderPass.JitterVectors = [
+	[
+		[ 0, 0 ]
+	],
+	[
+		[ 4, 4 ], [ - 4, - 4 ]
+	],
+	[
+		[ - 2, - 6 ], [ 6, - 2 ], [ - 6, 2 ], [ 2, 6 ]
+	],
+	[
+		[ 1, - 3 ], [ - 1, 3 ], [ 5, 1 ], [ - 3, - 5 ],
+		[ - 5, 5 ], [ - 7, - 1 ], [ 3, 7 ], [ 7, - 7 ]
+	],
+	[
+		[ 1, 1 ], [ - 1, - 3 ], [ - 3, 2 ], [ 4, - 1 ],
+		[ - 5, - 2 ], [ 2, 5 ], [ 5, 3 ], [ 3, - 5 ],
+		[ - 2, 6 ], [ 0, - 7 ], [ - 4, - 6 ], [ - 6, 4 ],
+		[ - 8, 0 ], [ 7, - 4 ], [ 6, 7 ], [ - 7, - 8 ]
+	]
+];

+ 48 - 0
examples/js/shaders/CompositeShader.js

@@ -0,0 +1,48 @@
+/**
+ * @author bhouston / http://clara.io/
+ *
+ * Multi-Sample Anti-aliasing shader - for blending together sample buffers
+ */
+
+THREE.CompositeShader = {
+
+	shaderID: "composite",
+
+	uniforms: {
+
+		"tForeground": { type: "t", value: null },
+		"scale": { type: "f", value: 1.0 }
+
+	},
+
+	vertexShader: [
+
+		"varying vec2 vUv;",
+
+		"void main() {",
+
+			"vUv = uv;",
+			"gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );",
+
+		"}"
+
+	].join( '\n' ),
+
+	fragmentShader: [
+
+		"varying vec2 vUv;",
+
+		"uniform sampler2D tForeground;",
+		"uniform float scale;",
+
+		"void main() {",
+
+			"vec4 foreground = texture2D( tForeground, vUv );",
+
+			"gl_FragColor = foreground * scale;",
+
+		"}"
+
+	].join( '\n' )
+
+};

+ 9 - 11
examples/webgl_animation_cloth.html

@@ -25,10 +25,6 @@
 				cursor: pointer;
 			}
 
-			#stats { position: absolute; top:0; left: 0 }
-			#stats #fps { background: transparent !important }
-			#stats #fps #fpsText { color: #aaa !important }
-			#stats #fps #fpsGraph { display: none }
 		</style>
 	</head>
 
@@ -164,17 +160,17 @@
 				light.castShadow = true;
 				// light.shadowCameraVisible = true;
 
-				light.shadowMapWidth = 1024;
-				light.shadowMapHeight = 1024;
+				light.shadow.mapSize.width = 1024;
+				light.shadow.mapSize.height = 1024;
 
 				var d = 300;
 
-				light.shadowCameraLeft = -d;
-				light.shadowCameraRight = d;
-				light.shadowCameraTop = d;
-				light.shadowCameraBottom = -d;
+				light.shadow.camera.left = -d;
+				light.shadow.camera.right = d;
+				light.shadow.camera.top = d;
+				light.shadow.camera.bottom = -d;
 
-				light.shadowCameraFar = 1000;
+				light.shadow.camera.far = 1000;
 
 				scene.add( light );
 
@@ -297,6 +293,8 @@
 				//
 
 				stats = new Stats();
+				stats.domElement.style.position = 'absolute';
+				stats.domElement.style.top = '0px';
 				container.appendChild( stats.domElement );
 
 				//

+ 1 - 1
examples/webgl_effects_cardboard.html

@@ -64,7 +64,7 @@
 				renderer.setClearColor( 0x101010 );
 				renderer.setPixelRatio( window.devicePixelRatio );
 				renderer.setSize( window.innerWidth, window.innerHeight );
-				renderer.shadowMap.enabled = window.location.search === "";
+				renderer.shadowMap.enabled = true;
 				document.body.appendChild( renderer.domElement );
 
 				//

+ 0 - 1
examples/webgl_geometry_large_mesh.html

@@ -58,7 +58,6 @@
 
 			var SCREEN_WIDTH = window.innerWidth;
 			var SCREEN_HEIGHT = window.innerHeight;
-			var FLOOR = -250;
 
 			var container, stats;
 

+ 183 - 0
examples/webgl_postprocessing_msaa.html

@@ -0,0 +1,183 @@
+<!DOCTYPE html>
+<html lang="en">
+	<head>
+		<title>three.js webgl - postprocessing manual msaa</title>
+		<meta charset="utf-8">
+		<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
+		<style>
+			body {
+				margin: 0px;
+				background-color: #000;
+				overflow: hidden;
+				font-family:Monospace;
+				font-size:13px;
+				margin: 0px;
+				text-align:center;
+				overflow: hidden;
+			}
+
+			#info {
+				color: #fff;
+				position: absolute;
+				top: 10px;
+				width: 100%;
+				text-align: center;
+				display:block;
+			}
+		</style>
+	</head>
+	<body>
+		<div id="info">
+			<a href="http://threejs.org" target="_blank">three.js</a> - Manual Multi-Sample Anti-Aliasing (MSAA) pass by <a href="https://clara.io" target="_blank">Ben Houston</a><br/><br/>
+			Texture interpolation, mipmapping and anistropic sampling is disabled to emphasize<br/> the effect MSAA levels have one the resulting render quality.
+		</div>
+
+		<div id="container"></div>
+
+		<script src="../build/three.min.js"></script>
+		<script src="js/libs/stats.min.js"></script>
+		<script src="js/libs/dat.gui.min.js"></script>
+
+		<script src="js/postprocessing/ManualMSAARenderPass.js"></script>
+		<script src="js/shaders/CopyShader.js"></script>
+		<script src="js/shaders/CompositeShader.js"></script>
+
+		<script src="js/postprocessing/EffectComposer.js"></script>
+		<script src="js/postprocessing/RenderPass.js"></script>
+		<script src="js/postprocessing/MaskPass.js"></script>
+		<script src="js/postprocessing/ShaderPass.js"></script>
+
+
+		<script>
+
+			var camera, scene, renderer, composer, copyPass, manualMSAARenderPass;
+			var gui, stats, texture;
+
+			var param = { MSAASampleLevel: 2 };
+
+			init();
+			animate();
+
+			clearGui();
+
+			function clearGui() {
+
+				if ( gui ) gui.destroy();
+
+				gui = new dat.GUI();
+
+				var example = gui.add( param, 'MSAASampleLevel', {
+					'Level 0: 1 Sample': 0,
+					'Level 1: 2 Samples': 1,
+					'Level 2: 4 Samples': 2,
+					'Level 3: 8 Samples': 3,
+					'Level 4: 16 Samples': 4
+				} ).onFinishChange( function() {
+
+					if( manualMSAARenderPass ) {
+						manualMSAARenderPass.sampleLevel = param.MSAASampleLevel;
+					}
+
+				} );
+
+				gui.open();
+
+			}
+
+			function init() {
+
+				container = document.getElementById( "container" );
+
+				renderer = new THREE.WebGLRenderer( { antialias: false } );
+				renderer.setPixelRatio( window.devicePixelRatio );
+				renderer.setSize( window.innerWidth, window.innerHeight );
+				document.body.appendChild( renderer.domElement );
+
+				stats = new Stats();
+				stats.domElement.style.position = 'absolute';
+				stats.domElement.style.top = '0px';
+				container.appendChild( stats.domElement );
+
+				//
+
+				camera = new THREE.PerspectiveCamera( 70, window.innerWidth / window.innerHeight, 1, 1000 );
+				camera.position.z = 300;
+
+				scene = new THREE.Scene();
+
+				var geometry = new THREE.BoxGeometry( 120, 120, 120 );
+				var material = new THREE.MeshBasicMaterial( { color: 0xffffff, wireframe: true } );
+
+				var mesh = new THREE.Mesh( geometry, material );
+				mesh.position.x = - 100;
+				scene.add( mesh );
+
+				var texture = new THREE.TextureLoader().load( "textures/brick_diffuse.jpg" );
+				texture.minFilter = THREE.NearestFilter;
+				texture.magFilter = THREE.NearestFilter;
+				texture.anisotropy = 1;
+				texture.generateMipmaps = false;
+
+				var material = new THREE.MeshBasicMaterial( { map: texture } );
+
+				var mesh = new THREE.Mesh( geometry, material );
+				mesh.position.x = 100;
+				scene.add( mesh );
+
+				// postprocessing
+
+				composer = new THREE.EffectComposer( renderer );
+
+				manualMSAARenderPass = new THREE.ManualMSAARenderPass( scene, camera );
+				manualMSAARenderPass.sampleLevel = param.MSAASampleLevel;
+				composer.addPass( manualMSAARenderPass );
+
+				copyPass = new THREE.ShaderPass( THREE.CopyShader );
+		    copyPass.renderToScreen = true;
+				composer.addPass( copyPass );
+
+				window.addEventListener( 'resize', onWindowResize, false );
+
+			}
+
+			function onWindowResize() {
+
+				var width = window.innerWidth;
+				var height = window.innerHeight;
+
+				camera.aspect = width / height;
+				camera.updateProjectionMatrix();
+
+				renderer.setSize( width, height );
+
+				var pixelRatio = renderer.getPixelRatio();
+				var newWidth  = Math.floor( width / pixelRatio ) || 1;
+				var newHeight = Math.floor( height / pixelRatio ) || 1;
+				composer.setSize( newWidth, newHeight );
+				msaaPass.setSize( newWidth, newHeight );
+
+			}
+
+			function animate() {
+
+				requestAnimationFrame( animate );
+
+				for ( var i = 0; i < scene.children.length; i ++ ) {
+
+					var child = scene.children[ i ];
+
+					child.rotation.x += 0.005;
+					child.rotation.y += 0.01;
+
+				}
+
+				composer.render();
+
+				stats.update();
+
+			}
+
+		</script>
+		<div>
+	</body>
+</html>

+ 37 - 16
examples/webgl_postprocessing_smaa.html

@@ -14,7 +14,10 @@
 	</head>
 	<body>
 
+		<div id="container"></div>
+
 		<script src="../build/three.min.js"></script>
+		<script src="js/libs/stats.min.js"></script>
 
 		<script src="js/postprocessing/SMAAPass.js"></script>
 		<script src="js/shaders/CopyShader.js"></script>
@@ -28,37 +31,47 @@
 
 		<script>
 
-			var camera, scene, renderer, composer, pass;
-			var geometry, material, object;
-
-			var textureLoader = new THREE.TextureLoader();
+			var camera, scene, renderer, composer, pass, stats;
 
-			textureLoader.load( "textures/brick_diffuse.jpg", function( meshTexture ) {
-				init( meshTexture );
-				animate();
-			});
+			init();
+			animate();
 
 			function init( meshTexture ) {
 
+				container = document.getElementById( "container" );
+
 				renderer = new THREE.WebGLRenderer( { antialias: false } );
 				renderer.setPixelRatio( window.devicePixelRatio );
 				renderer.setSize( window.innerWidth, window.innerHeight );
 				document.body.appendChild( renderer.domElement );
 
+				stats = new Stats();
+				stats.domElement.style.position = 'absolute';
+				stats.domElement.style.top = '0px';
+				container.appendChild( stats.domElement );
+
 				//
 
 				camera = new THREE.PerspectiveCamera( 70, window.innerWidth / window.innerHeight, 1, 1000 );
-				camera.position.z = 400;
+				camera.position.z = 300;
 
 				scene = new THREE.Scene();
 
-				geometry = new THREE.BoxGeometry( 200, 200, 200 );
-				material = new THREE.MeshBasicMaterial( { map: meshTexture } );
-				meshTexture.anisotropy = 4;
+				var geometry = new THREE.BoxGeometry( 120, 120, 120 );
+				var material = new THREE.MeshBasicMaterial( { color: 0xffffff, wireframe: true } );
+
+				var mesh = new THREE.Mesh( geometry, material );
+				mesh.position.x = - 100;
+				scene.add( mesh );
 
-				object = new THREE.Mesh( geometry, material );
+				var texture = new THREE.TextureLoader().load( "textures/brick_diffuse.jpg" );
+				texture.anisotropy = 4;
 
-				scene.add( object );
+				var material = new THREE.MeshBasicMaterial( { map: texture } );
+
+				var mesh = new THREE.Mesh( geometry, material );
+				mesh.position.x = 100;
+				scene.add( mesh );
 
 				// postprocessing
 
@@ -95,11 +108,19 @@
 
 				requestAnimationFrame( animate );
 
-				object.rotation.x += 0.005;
-				object.rotation.y += 0.01;
+				for ( var i = 0; i < scene.children.length; i ++ ) {
+
+					var child = scene.children[ i ];
+
+					child.rotation.x += 0.005;
+					child.rotation.y += 0.01;
+
+				}
 
 				composer.render();
 
+				stats.update();
+
 			}
 
 		</script>

+ 23 - 29
examples/webgl_shadowmap_pointlight.html

@@ -39,7 +39,7 @@
 			var camera, scene, renderer, stats;
 			var pointLight, pointLight2;
 			var torusKnot;
-			var cubeMaterial;
+			var torusKnotMaterial;
 			var wallMaterial;
 			var ground;
 
@@ -59,7 +59,7 @@
 			function initScene() {
 
 				camera = new THREE.PerspectiveCamera( 45, window.innerWidth / window.innerHeight, 1, 1000 );
-				camera.position.set( 0, 10, 40 );
+				camera.position.set( 0, 10, 60 );
 
 				scene = new THREE.Scene();
 				scene.add( new THREE.AmbientLight( 0x222233 ) );
@@ -70,12 +70,12 @@
 
 					var pointLight = new THREE.PointLight( color, 1, 30 );
 					pointLight.castShadow = true;
-					pointLight.shadowCameraNear = 1;
-					pointLight.shadowCameraFar = 30;
+					pointLight.shadow.camera.near = 1;
+					pointLight.shadow.camera.far = 30;
 					// pointLight.shadowCameraVisible = true;
-					pointLight.shadowBias = 0.01;
+					pointLight.shadow.bias = 0.01;
 
-					var geometry = new THREE.SphereGeometry( 0.3, 32, 32 );
+					var geometry = new THREE.SphereGeometry( 0.3, 12, 6 );
 					var material = new THREE.MeshBasicMaterial( { color: color } );
 					var sphere = new THREE.Mesh( geometry, material );
 					pointLight.add( sphere );
@@ -84,27 +84,29 @@
 
 				}
 
-				pointLight = createLight( 0xffffff );
+				pointLight = createLight( 0xaaffaa );
 				scene.add( pointLight );
 
-				pointLight2 = createLight( 0xff0000 );
+				pointLight2 = createLight( 0xaaaaff );
 				scene.add( pointLight2 );
 
-				cubeMaterial = new THREE.MeshPhongMaterial( {
+				torusKnotMaterial = new THREE.MeshPhongMaterial( {
 					color: 0xff0000,
-					shininess: 50,
+					shininess: 100,
+					//wireframe: true,
+					//wireframeLinewidth: 2,
 					specular: 0x222222
 				} );
 
-				var torusGeometry =  new THREE.TorusKnotGeometry( 14, 1, 150, 20 );
-				torusKnot = new THREE.Mesh( torusGeometry, cubeMaterial );
-				torusKnot.position.set( 0, 5, 0 );
+				var torusKnotGeometry = new THREE.TorusKnotGeometry( 8, 1, 150, 20 );
+				torusKnot = new THREE.Mesh( torusKnotGeometry, torusKnotMaterial );
+				torusKnot.position.set( 0, 9, 0 );
 				torusKnot.castShadow = true;
 				torusKnot.receiveShadow = true;
 				scene.add( torusKnot );
 
 				wallMaterial = new THREE.MeshPhongMaterial( {
-					color: 0xa0adaf,
+					color: 0xffffff,
 					shininess: 10,
 					specular: 0x111111,
 					shading: THREE.SmoothShading
@@ -112,7 +114,7 @@
 
 				var wallGeometry = new THREE.BoxGeometry( 10, 0.15, 10 );
 				ground = new THREE.Mesh( wallGeometry, wallMaterial );
-				ground.position.set( 0, -5, 0 );
+				ground.position.set( 0, - 5, 0 );
 				ground.scale.multiplyScalar( 3 );
 				ground.receiveShadow = true;
 				scene.add( ground );
@@ -124,7 +126,7 @@
 				scene.add( ceiling );
 
 				var wall = new THREE.Mesh( wallGeometry, wallMaterial );
-				wall.position.set( -14, 10, 0 );
+				wall.position.set( - 14, 10, 0 );
 				wall.rotation.z = Math.PI / 2;
 				wall.scale.multiplyScalar( 3 );
 				wall.receiveShadow = true;
@@ -138,29 +140,18 @@
 				scene.add( wall );
 
 				wall = new THREE.Mesh( wallGeometry, wallMaterial );
-				wall.position.set( 0, 10, -14 );
+				wall.position.set( 0, 10, - 14 );
 				wall.rotation.y = Math.PI / 2;
 				wall.rotation.z = Math.PI / 2;
 				wall.scale.multiplyScalar( 3 );
 				wall.receiveShadow = true;
 				scene.add( wall );
 
-				/*
-				wall = new THREE.Mesh( wallGeometry, wallMaterial );
-				wall.scale.multiplyScalar( 3 );
-				wall.castShadow = false;
-				wall.receiveShadow = true;
-				scene.add( wall );
-				wall.position.set( 0, 10, 14 );
-				wall.rotation.y = Math.PI / 2;
-				wall.rotation.z = Math.PI / 2;
-				*/
-
 			}
 
 			function initMisc() {
 
-				renderer = new THREE.WebGLRenderer();
+				renderer = new THREE.WebGLRenderer( { antialias: true } );
 				renderer.setClearColor( 0x000000 );
 				renderer.setPixelRatio( window.devicePixelRatio );
 				renderer.setSize( window.innerWidth, window.innerHeight );
@@ -169,6 +160,9 @@
 
 				// Mouse control
 				controls = new THREE.OrbitControls( camera, renderer.domElement );
+				controls.minDistance = 12;
+				controls.maxDistance = 60;
+				controls.enablePan = false;
 				controls.target.set( 0, 10, 0 );
 				controls.update();
 

+ 7 - 0
src/Three.Legacy.js

@@ -202,6 +202,13 @@ THREE.Face4 = function ( a, b, c, d, normal, color, materialIndex ) {
 
 };
 
+THREE.Vertex = function ( x, y, z ) {
+
+	console.warn( 'THREE.Vertex has been removed. Use THREE.Vector3 instead.' );
+	return new THREE.Vector3( x, y, z );
+
+};
+
 //
 
 Object.defineProperties( THREE.Object3D.prototype, {

+ 0 - 1
src/materials/MeshNormalMaterial.js

@@ -4,7 +4,6 @@
  * parameters = {
  *  opacity: <float>,
  *
- *  shading: THREE.FlatShading,
  *  blending: THREE.NormalBlending,
  *  depthTest: <bool>,
  *  depthWrite: <bool>,

+ 2 - 2
src/renderers/WebGLRenderer.js

@@ -2701,8 +2701,8 @@ THREE.WebGLRenderer = function ( parameters ) {
 				uniforms.direction.sub( _vector3 );
 				uniforms.direction.transformDirection( viewMatrix );
 
-				uniforms.angleCos = Math.cos( light.angle );
-				uniforms.penumbra = Math.cos( light.angle ) * light.penumbra;
+				uniforms.coneCos = Math.cos( light.angle );
+				uniforms.penumbraCos = Math.cos( light.angle * ( 1 - light.penumbra ) );
 				uniforms.decay = ( light.distance === 0 ) ? 0.0 : light.decay;
 
 				uniforms.shadow = light.castShadow;

+ 11 - 1
src/renderers/shaders/ShaderChunk/aomap_fragment.glsl

@@ -1,5 +1,15 @@
 #ifdef USE_AOMAP
 
-	reflectedLight.indirectDiffuse *= ( texture2D( aoMap, vUv2 ).r - 1.0 ) * aoMapIntensity + 1.0;
+	float ambientOcclusion = ( texture2D( aoMap, vUv2 ).r - 1.0 ) * aoMapIntensity + 1.0;
+
+	reflectedLight.indirectDiffuse *= ambientOcclusion;
+
+	#if defined( USE_ENVMAP ) && defined( STANDARD )
+
+		float dotNV = saturate( dot( geometry.normal, geometry.viewDir ) );
+
+		reflectedLight.indirectSpecular *= computeSpecularOcclusion( dotNV, ambientOcclusion, material.specularRoughness );
+
+	#endif
 
 #endif

+ 5 - 6
src/renderers/shaders/ShaderChunk/lights_pars.glsl

@@ -80,8 +80,8 @@
 		vec3 color;
 		float distance;
 		float decay;
-		float angleCos;
-		float penumbra;
+		float coneCos;
+		float penumbraCos;
 
 		int shadow;
 		float shadowBias;
@@ -99,12 +99,11 @@
 		directLight.direction = normalize( lVector );
 
 		float lightDistance = length( lVector );
-		float spotEffect = dot( directLight.direction, spotLight.direction );
+		float angleCos = dot( directLight.direction, spotLight.direction );
 
-		if ( all( bvec2( spotEffect > spotLight.angleCos, testLightInRange( lightDistance, spotLight.distance ) ) ) ) {
+		if ( all( bvec2( angleCos > spotLight.coneCos, testLightInRange( lightDistance, spotLight.distance ) ) ) ) {
 
-			float spotEffect = dot( spotLight.direction, directLight.direction );
-			spotEffect *= clamp( ( spotEffect - spotLight.angleCos ) / spotLight.penumbra, 0.0, 1.0 );
+			float spotEffect = smoothstep( spotLight.coneCos, spotLight.penumbraCos, angleCos );
 
 			directLight.color = spotLight.color;
 			directLight.color *= ( spotEffect * calcLightAttenuation( lightDistance, spotLight.distance, spotLight.decay ) );

+ 7 - 0
src/renderers/shaders/ShaderChunk/lights_standard_pars_fragment.glsl

@@ -35,3 +35,10 @@ void RE_IndirectSpecular_Standard( const in vec3 radiance, const in GeometricCon
 #define RE_IndirectSpecular		RE_IndirectSpecular_Standard
 
 #define Material_BlinnShininessExponent( material )   GGXRoughnessToBlinnExponent( material.specularRoughness )
+
+// ref: http://www.frostbite.com/wp-content/uploads/2014/11/course_notes_moving_frostbite_to_pbr_v2.pdf
+float computeSpecularOcclusion( const in float dotNV, const in float ambientOcclusion, const in float roughness ) {
+
+	return saturate( pow( dotNV + ambientOcclusion, exp2( - 16.0 * roughness - 1.0 ) ) - 1.0 + ambientOcclusion );
+
+}

+ 0 - 3
src/renderers/shaders/ShaderLib.js

@@ -28,7 +28,6 @@ THREE.ShaderLib = {
 			THREE.ShaderChunk[ "color_pars_vertex" ],
 			THREE.ShaderChunk[ "morphtarget_pars_vertex" ],
 			THREE.ShaderChunk[ "skinning_pars_vertex" ],
-			THREE.ShaderChunk[ "shadowmap_pars_vertex" ],
 			THREE.ShaderChunk[ "logdepthbuf_pars_vertex" ],
 
 			"void main() {",
@@ -55,7 +54,6 @@ THREE.ShaderLib = {
 
 				THREE.ShaderChunk[ "worldpos_vertex" ],
 				THREE.ShaderChunk[ "envmap_vertex" ],
-				THREE.ShaderChunk[ "shadowmap_vertex" ],
 
 			"}"
 
@@ -82,7 +80,6 @@ THREE.ShaderLib = {
 			THREE.ShaderChunk[ "aomap_pars_fragment" ],
 			THREE.ShaderChunk[ "envmap_pars_fragment" ],
 			THREE.ShaderChunk[ "fog_pars_fragment" ],
-			THREE.ShaderChunk[ "shadowmap_pars_fragment" ],
 			THREE.ShaderChunk[ "specularmap_pars_fragment" ],
 			THREE.ShaderChunk[ "logdepthbuf_pars_fragment" ],
 

+ 2 - 2
src/renderers/shaders/UniformsLib.js

@@ -111,8 +111,8 @@ THREE.UniformsLib = {
 			"position": { type: "v3" },
 			"direction": { type: "v3" },
 			"distance": { type: "f" },
-			"angleCos": { type: "f" },
-			"penumbra": { type: "f" },
+			"coneCos": { type: "f" },
+			"penumbraCos": { type: "f" },
 			"decay": { type: "f" },
 
 			"shadow": { type: "i" },

+ 2 - 2
src/renderers/webgl/WebGLLights.js

@@ -36,8 +36,8 @@ THREE.WebGLLights = function () {
 					direction: new THREE.Vector3(),
 					color: new THREE.Color(),
 					distance: 0,
-					angleCos: 0,
-					penumbra: 0,
+					coneCos: 0,
+					penumbraCos: 0,
 					decay: 0,
 
 					shadow: false,

+ 3 - 4
src/renderers/webgl/WebGLShadowMap.js

@@ -61,11 +61,12 @@ THREE.WebGLShadowMap = function ( _renderer, _lights, _objects ) {
 			skinning: useSkinning
 		} );
 
-		depthMaterial._shadowPass = true;
-
 		_depthMaterials[ i ] = depthMaterial;
 
 		var distanceMaterial = new THREE.ShaderMaterial( {
+			defines: {
+				'USE_SHADOWMAP': ''
+			},
 			uniforms: distanceUniforms,
 			vertexShader: distanceShader.vertexShader,
 			fragmentShader: distanceShader.fragmentShader,
@@ -73,8 +74,6 @@ THREE.WebGLShadowMap = function ( _renderer, _lights, _objects ) {
 			skinning: useSkinning
 		} );
 
-		distanceMaterial._shadowPass = true;
-
 		_distanceMaterials[ i ] = distanceMaterial;
 
 	}

+ 7 - 2
src/renderers/webgl/WebGLState.js

@@ -58,6 +58,11 @@ THREE.WebGLState = function ( gl, extensions, paramThreeToGL ) {
 	var currentScissor = new THREE.Vector4();
 	var currentViewport = new THREE.Vector4();
 
+	var emptyTexture = gl.createTexture();
+	gl.bindTexture( gl.TEXTURE_2D, emptyTexture );
+	gl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR );
+	gl.texImage2D( gl.TEXTURE_2D, 0, gl.RGB, 1, 1, 0, gl.RGB, gl.UNSIGNED_BYTE, new Uint8Array( 3 ) );
+
 	this.init = function () {
 
 		this.clearColor( 0, 0, 0, 1 );
@@ -174,7 +179,7 @@ THREE.WebGLState = function ( gl, extensions, paramThreeToGL ) {
 
 			if ( extensions.get( 'WEBGL_compressed_texture_pvrtc' ) ||
 			     extensions.get( 'WEBGL_compressed_texture_s3tc' ) ||
-			     extensions.get( 'WEBGL_compressed_texture_etc1' )) {
+			     extensions.get( 'WEBGL_compressed_texture_etc1' ) ) {
 
 				var formats = gl.getParameter( gl.COMPRESSED_TEXTURE_FORMATS );
 
@@ -551,7 +556,7 @@ THREE.WebGLState = function ( gl, extensions, paramThreeToGL ) {
 
 		if ( boundTexture.type !== webglType || boundTexture.texture !== webglTexture ) {
 
-			gl.bindTexture( webglType, webglTexture );
+			gl.bindTexture( webglType, webglTexture || emptyTexture );
 
 			boundTexture.type = webglType;
 			boundTexture.texture = webglTexture;

+ 28 - 9
utils/exporters/blender/addons/io_three/__init__.py

@@ -374,9 +374,13 @@ def restore_export_settings(properties, settings):
         constants.INDENT,
         constants.EXPORT_OPTIONS[constants.INDENT])
 
-    properties.option_copy_textures = settings.get(
-        constants.COPY_TEXTURES,
-        constants.EXPORT_OPTIONS[constants.COPY_TEXTURES])
+    properties.option_export_textures = settings.get(
+        constants.EXPORT_TEXTURES,
+        constants.EXPORT_OPTIONS[constants.EXPORT_TEXTURES])
+
+    properties.option_embed_textures = settings.get(
+        constants.EMBED_TEXTURES,
+        constants.EXPORT_OPTIONS[constants.EMBED_TEXTURES])
 
     properties.option_texture_folder = settings.get(
         constants.TEXTURE_FOLDER,
@@ -467,7 +471,8 @@ def set_settings(properties):
         constants.LOGGING: properties.option_logging,
         constants.COMPRESSION: properties.option_compression,
         constants.INDENT: properties.option_indent,
-        constants.COPY_TEXTURES: properties.option_copy_textures,
+        constants.EXPORT_TEXTURES: properties.option_export_textures,
+        constants.EMBED_TEXTURES: properties.option_embed_textures,
         constants.TEXTURE_FOLDER: properties.option_texture_folder,
 
         constants.SCENE: properties.option_export_scene,
@@ -521,6 +526,10 @@ def animation_options():
 
     return anim
 
+def resolve_conflicts(self, context):
+    if(not self.option_export_textures):
+        self.option_embed_textures = False;
+
 class ExportThree(bpy.types.Operator, ExportHelper):
     """Class that handles the export properties"""
 
@@ -665,10 +674,16 @@ class ExportThree(bpy.types.Operator, ExportHelper):
         description="Embed animation data with the geometry data",
         default=constants.EXPORT_OPTIONS[constants.EMBED_ANIMATION])
 
-    option_copy_textures = BoolProperty(
-        name="Copy textures",
-        description="Copy textures",
-        default=constants.EXPORT_OPTIONS[constants.COPY_TEXTURES])
+    option_export_textures = BoolProperty(
+        name="Export textures",
+        description="Export textures",
+        default=constants.EXPORT_OPTIONS[constants.EXPORT_TEXTURES],
+        update=resolve_conflicts)
+
+    option_embed_textures = BoolProperty(
+        name="Embed textures",
+        description="Embed base64 textures in .json",
+        default=constants.EXPORT_OPTIONS[constants.EMBED_TEXTURES])
 
     option_texture_folder = StringProperty(
         name="Texture folder",
@@ -914,7 +929,11 @@ class ExportThree(bpy.types.Operator, ExportHelper):
         row.prop(self.properties, 'option_maps')
 
         row = layout.row()
-        row.prop(self.properties, 'option_copy_textures')
+        row.prop(self.properties, 'option_export_textures')
+
+        row = layout.row()
+        row.prop(self.properties, 'option_embed_textures')
+        row.enabled = self.properties.option_export_textures
 
         row = layout.row()
         row.prop(self.properties, 'option_texture_folder')

+ 4 - 2
utils/exporters/blender/addons/io_three/constants.py

@@ -93,7 +93,8 @@ LIGHTS = 'lights'
 HIERARCHY = 'hierarchy'
 FACE_MATERIALS = 'faceMaterials'
 SKINNING = 'skinning'
-COPY_TEXTURES = 'copyTextures'
+EXPORT_TEXTURES = 'exportTextures'
+EMBED_TEXTURES = 'embedTextures'
 TEXTURE_FOLDER = 'textureFolder'
 ENABLE_PRECISION = 'enablePrecision'
 PRECISION = 'precision'
@@ -153,7 +154,8 @@ EXPORT_OPTIONS = {
     CAMERAS: False,
     LIGHTS: False,
     HIERARCHY: False,
-    COPY_TEXTURES: True,
+    EXPORT_TEXTURES: True,
+    EMBED_TEXTURES: False,
     TEXTURE_FOLDER: '',
     LOGGING: DEBUG,
     ENABLE_PRECISION: True,

+ 1 - 1
utils/exporters/blender/addons/io_three/exporter/geometry.py

@@ -148,7 +148,7 @@ class Geometry(base_classes.BaseNode):
     def copy_textures(self, texture_folder=''):
         """Copy the textures to the destination directory."""
         logger.debug("Geometry().copy_textures()")
-        if self.options.get(constants.COPY_TEXTURES):
+        if self.options.get(constants.EXPORT_TEXTURES) and not self.options.get(constants.EMBED_TEXTURES):
             texture_registration = self.register_textures()
             if texture_registration:
                 logger.info("%s has registered textures", self.node)

+ 12 - 2
utils/exporters/blender/addons/io_three/exporter/image.py

@@ -1,4 +1,5 @@
 import os
+import base64
 from .. import constants, logger
 from . import base_classes, io, api
 
@@ -11,8 +12,17 @@ class Image(base_classes.BaseNode):
         logger.debug("Image().__init__(%s)", node)
         base_classes.BaseNode.__init__(self, node, parent, constants.IMAGE)
 
-        texture_folder = self.scene.options.get(constants.TEXTURE_FOLDER, "")
-        self[constants.URL] = os.path.join(texture_folder, api.image.file_name(self.node))
+        if(self.scene.options.get(constants.EMBED_TEXTURES, False)):
+            texturefile = open(api.image.file_path(self.node),"rb")
+            extension = os.path.splitext(api.image.file_path(self.node))[1][1:].strip().lower()
+            if(extension == 'jpg') :
+                extension = 'jpeg'
+            self[constants.URL] = "data:image/" + extension + ";base64," + base64.b64encode(texturefile.read()).decode("utf-8")
+            texturefile.close();
+        else:
+            texture_folder = self.scene.options.get(constants.TEXTURE_FOLDER, "")
+            self[constants.URL] = os.path.join(texture_folder, api.image.file_name(self.node))
+
 
     @property
     def destination(self):

+ 1 - 1
utils/exporters/blender/addons/io_three/exporter/scene.py

@@ -171,7 +171,7 @@ class Scene(base_classes.BaseScene):
 
         io.dump(self.filepath, data, options=self.options)
 
-        if self.options.get(constants.COPY_TEXTURES):
+        if self.options.get(constants.EXPORT_TEXTURES) and not self.options.get(constants.EMBED_TEXTURES):
             texture_folder = self.options.get(constants.TEXTURE_FOLDER)
             for geo in self[constants.GEOMETRIES]:
                 logger.info("Copying textures from %s", geo.node)

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