浏览代码

Merge branch 'dev' into lighthelper_colours

Mr.doob 8 年之前
父节点
当前提交
985220c007
共有 100 个文件被更改,包括 2941 次插入1584 次删除
  1. 1 1
      README.md
  2. 55 25
      build/three.js
  3. 343 335
      build/three.min.js
  4. 55 25
      build/three.module.js
  5. 1 1
      docs/api/materials/Material.html
  6. 6 2
      docs/api/materials/MeshBasicMaterial.html
  7. 6 2
      docs/api/materials/MeshLambertMaterial.html
  8. 6 2
      docs/api/materials/MeshPhongMaterial.html
  9. 6 2
      docs/api/materials/MeshStandardMaterial.html
  10. 4 13
      docs/api/math/Euler.html
  11. 16 34
      docs/api/math/Plane.html
  12. 9 0
      docs/api/math/Vector4.html
  13. 1 1
      docs/api/objects/Group.html
  14. 3 0
      docs/api/renderers/WebGLRenderer.html
  15. 1 1
      examples/css3d_sandbox.html
  16. 2 0
      examples/files.js
  17. 8 7
      examples/js/GPUParticleSystem.js
  18. 25 15
      examples/js/Mirror.js
  19. 2 0
      examples/js/controls/OrbitControls.js
  20. 2 0
      examples/js/controls/TrackballControls.js
  21. 4 11
      examples/js/effects/OutlineEffect.js
  22. 151 34
      examples/js/loaders/ColladaLoader2.js
  23. 77 18
      examples/js/loaders/FBXLoader.js
  24. 66 31
      examples/js/loaders/GLTF2Loader.js
  25. 1 1
      examples/js/loaders/GLTFLoader.js
  26. 293 0
      examples/js/loaders/PRWMLoader.js
  27. 52 53
      examples/js/nodes/materials/PhongNode.js
  28. 139 0
      examples/js/nodes/materials/SpriteNode.js
  29. 17 0
      examples/js/nodes/materials/SpriteNodeMaterial.js
  30. 82 78
      examples/js/nodes/materials/StandardNode.js
  31. 4 3
      examples/js/nodes/utils/ResolutionNode.js
  32. 48 0
      examples/js/nodes/utils/UVTransformNode.js
  33. 52 52
      examples/js/renderers/WebGLDeferredRenderer.js
  34. 0 153
      examples/js/vr/WebVRCamera.js
  35. 二进制
      examples/models/prwm/faceted-nefertiti.be.prwm
  36. 二进制
      examples/models/prwm/faceted-nefertiti.le.prwm
  37. 二进制
      examples/models/prwm/smooth-suzanne.be.prwm
  38. 二进制
      examples/models/prwm/smooth-suzanne.le.prwm
  39. 二进制
      examples/models/prwm/vive-controller.be.prwm
  40. 二进制
      examples/models/prwm/vive-controller.le.prwm
  41. 二进制
      examples/textures/WalkingManSpriteSheet.png
  42. 1 0
      examples/webgl_clipping.html
  43. 1 1
      examples/webgl_gpgpu_water.html
  44. 7 2
      examples/webgl_loader_imagebitmap.html
  45. 250 0
      examples/webgl_loader_prwm.html
  46. 249 181
      examples/webgl_materials_nodes.html
  47. 12 2
      examples/webgl_mirror.html
  48. 6 6
      examples/webgl_panorama_equirectangular.html
  49. 2 20
      examples/webgl_postprocessing_outline.html
  50. 74 5
      examples/webgl_shadowmap_pointlight.html
  51. 281 0
      examples/webgl_sprites_nodes.html
  52. 8 12
      examples/webvr_cubes.html
  53. 11 17
      examples/webvr_daydream.html
  54. 16 15
      examples/webvr_panorama.html
  55. 15 17
      examples/webvr_rollercoaster.html
  56. 13 15
      examples/webvr_sandbox.html
  57. 9 18
      examples/webvr_video.html
  58. 11 17
      examples/webvr_vive.html
  59. 9 15
      examples/webvr_vive_camerarig.html
  60. 9 15
      examples/webvr_vive_dragging.html
  61. 14 20
      examples/webvr_vive_paint.html
  62. 9 15
      examples/webvr_vive_sculpt.html
  63. 1 1
      package.json
  64. 2 0
      src/Three.js
  65. 1 1
      src/constants.js
  66. 5 5
      src/helpers/AxisHelper.js
  67. 55 0
      src/helpers/Box3Helper.js
  68. 5 5
      src/helpers/BoxHelper.js
  69. 9 9
      src/helpers/CameraHelper.js
  70. 6 6
      src/helpers/DirectionalLightHelper.js
  71. 5 5
      src/helpers/FaceNormalsHelper.js
  72. 4 4
      src/helpers/GridHelper.js
  73. 6 6
      src/helpers/HemisphereLightHelper.js
  74. 60 0
      src/helpers/PlaneHelper.js
  75. 4 4
      src/helpers/PointLightHelper.js
  76. 6 6
      src/helpers/PolarGridHelper.js
  77. 8 8
      src/helpers/SkeletonHelper.js
  78. 6 6
      src/helpers/SpotLightHelper.js
  79. 5 5
      src/helpers/VertexNormalsHelper.js
  80. 1 1
      src/materials/MeshNormalMaterial.js
  81. 2 2
      src/math/Matrix3.js
  82. 14 4
      src/math/Matrix4.js
  83. 7 15
      src/math/Plane.js
  84. 4 4
      src/math/Vector2.js
  85. 17 11
      src/math/Vector3.js
  86. 19 5
      src/math/Vector4.js
  87. 3 4
      src/objects/Mesh.js
  88. 98 141
      src/renderers/WebGLRenderer.js
  89. 3 3
      src/renderers/shaders/ShaderChunk/defaultnormal_vertex.glsl
  90. 1 1
      src/renderers/shaders/ShaderChunk/displacementmap_vertex.glsl
  91. 1 9
      src/renderers/shaders/ShaderChunk/project_vertex.glsl
  92. 6 4
      src/renderers/shaders/ShaderChunk/shadowmap_pars_fragment.glsl
  93. 2 1
      src/renderers/shaders/ShaderChunk/skinning_vertex.glsl
  94. 1 9
      src/renderers/shaders/ShaderChunk/worldpos_vertex.glsl
  95. 6 3
      src/renderers/shaders/ShaderLib.js
  96. 9 1
      src/renderers/shaders/ShaderLib/depth_vert.glsl
  97. 9 0
      src/renderers/shaders/ShaderLib/distanceRGBA_frag.glsl
  98. 3 0
      src/renderers/shaders/ShaderLib/distanceRGBA_vert.glsl
  99. 1 1
      src/renderers/shaders/ShaderLib/meshphong_vert.glsl
  100. 1 1
      src/renderers/shaders/ShaderLib/meshphysical_vert.glsl

+ 1 - 1
README.md

@@ -66,7 +66,7 @@ function animate() {
 }
 }
 ```
 ```
 
 
-If everything went well you should see [this](http://jsfiddle.net/hfj7gm6t/).
+If everything went well you should see [this](https://jsfiddle.net/hfj7gm6t/).
 
 
 ### Change log ###
 ### Change log ###
 
 

文件差异内容过多而无法显示
+ 55 - 25
build/three.js


文件差异内容过多而无法显示
+ 343 - 335
build/three.min.js


文件差异内容过多而无法显示
+ 55 - 25
build/three.module.js


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

@@ -84,7 +84,7 @@
 		<div>
 		<div>
 		User-defined clipping planes specified as THREE.Plane objects in world space.
 		User-defined clipping planes specified as THREE.Plane objects in world space.
 		These planes apply to the objects this material is attached to.
 		These planes apply to the objects this material is attached to.
-		Points in space whose dot product with the plane is negative are cut away.
+		Points in space whose signed distance to the plane is negative are clipped (not rendered).
 		See the [example:webgl_clipping_intersection WebGL / clipping /intersection] example.
 		See the [example:webgl_clipping_intersection WebGL / clipping /intersection] example.
 		Default is *null*.
 		Default is *null*.
 		</div>
 		</div>

+ 6 - 2
docs/api/materials/MeshBasicMaterial.html

@@ -63,7 +63,9 @@
 		</div>
 		</div>
 
 
 		<h3>[property:Texture aoMap]</h3>
 		<h3>[property:Texture aoMap]</h3>
-		<div>The red channel of this texture is used as the ambient occlusion map. Default is null. The aoMap requires a second set of UVs.</div>
+		<div>The red channel of this texture is used as the ambient occlusion map. Default is null. 
+		The aoMap requires a second set of UVs, and consequently will ignore the [page:Texture repeat]
+		and [page:Texture offset] Texture properties.</div>
 
 
 		<h3>[property:Float aoMapIntensity]</h3>
 		<h3>[property:Float aoMapIntensity]</h3>
 		<div>Intensity of the ambient occlusion effect. Default is 1. Zero is no occlusion effect.</div>
 		<div>Intensity of the ambient occlusion effect. Default is 1. Zero is no occlusion effect.</div>
@@ -91,7 +93,9 @@
 		<div>The environment map. Default is null.</div>
 		<div>The environment map. Default is null.</div>
 
 
 		<h3>[property:Texture lightMap]</h3>
 		<h3>[property:Texture lightMap]</h3>
-		<div>The light map. Default is null. The lightMap requires a second set of UVs.</div>
+		<div>The light map. Default is null. The lightMap requires a second set of UVs, 
+		and consequently will ignore the [page:Texture repeat] and [page:Texture offset] 
+		Texture properties.</div>
 
 
 		<h3>[property:Float lightMapIntensity]</h3>
 		<h3>[property:Float lightMapIntensity]</h3>
 		<div>Intensity of the baked light. Default is 1.</div>
 		<div>Intensity of the baked light. Default is 1.</div>

+ 6 - 2
docs/api/materials/MeshLambertMaterial.html

@@ -74,7 +74,9 @@
 		</div>
 		</div>
 
 
 		<h3>[property:Texture aoMap]</h3>
 		<h3>[property:Texture aoMap]</h3>
-		<div>The red channel of this texture is used as the ambient occlusion map. Default is null. The aoMap requires a second set of UVs.</div>
+		<div>The red channel of this texture is used as the ambient occlusion map. Default is null. 
+		The aoMap requires a second set of UVs, and consequently will ignore the [page:Texture repeat]
+		and [page:Texture offset] Texture properties.</div>
 
 
 		<h3>[property:Float aoMapIntensity]</h3>
 		<h3>[property:Float aoMapIntensity]</h3>
 		<div>Intensity of the ambient occlusion effect. Default is 1. Zero is no occlusion effect.</div>
 		<div>Intensity of the ambient occlusion effect. Default is 1. Zero is no occlusion effect.</div>
@@ -118,7 +120,9 @@
 		</div>
 		</div>
 
 
 		<h3>[property:Texture lightMap]</h3>
 		<h3>[property:Texture lightMap]</h3>
-		<div>The light map. Default is null. The lightMap requires a second set of UVs.</div>
+		<div>The light map. Default is null. The lightMap requires a second set of UVs, 
+		and consequently will ignore the [page:Texture repeat] and [page:Texture offset] 
+		Texture properties.</div>
 
 
 		<h3>[property:Float lightMapIntensity]</h3>
 		<h3>[property:Float lightMapIntensity]</h3>
 		<div>Intensity of the baked light. Default is 1.</div>
 		<div>Intensity of the baked light. Default is 1.</div>

+ 6 - 2
docs/api/materials/MeshPhongMaterial.html

@@ -73,7 +73,9 @@
 		</div>
 		</div>
 
 
 		<h3>[property:Texture aoMap]</h3>
 		<h3>[property:Texture aoMap]</h3>
-		<div>The red channel of this texture is used as the ambient occlusion map. Default is null. The aoMap requires a second set of UVs.</div>
+		<div>The red channel of this texture is used as the ambient occlusion map. Default is null. 
+		The aoMap requires a second set of UVs, and consequently will ignore the [page:Texture repeat]
+		and [page:Texture offset] Texture properties.</div>
 
 
 		<h3>[property:Float aoMapIntensity]</h3>
 		<h3>[property:Float aoMapIntensity]</h3>
 		<div>Intensity of the ambient occlusion effect. Default is 1. Zero is no occlusion effect.</div>
 		<div>Intensity of the ambient occlusion effect. Default is 1. Zero is no occlusion effect.</div>
@@ -151,7 +153,9 @@
 
 
 
 
 		<h3>[property:Texture lightMap]</h3>
 		<h3>[property:Texture lightMap]</h3>
-		<div>The light map. Default is null. The lightMap requires a second set of UVs.</div>
+		<div>The light map. Default is null. The lightMap requires a second set of UVs, 
+		and consequently will ignore the [page:Texture repeat] and [page:Texture offset] 
+		Texture properties.</div>
 
 
 		<h3>[property:Float lightMapIntensity]</h3>
 		<h3>[property:Float lightMapIntensity]</h3>
 		<div>Intensity of the baked light. Default is 1.</div>
 		<div>Intensity of the baked light. Default is 1.</div>

+ 6 - 2
docs/api/materials/MeshStandardMaterial.html

@@ -97,7 +97,9 @@
 		</div>
 		</div>
 
 
 		<h3>[property:Texture aoMap]</h3>
 		<h3>[property:Texture aoMap]</h3>
-		<div>The red channel of this texture is used as the ambient occlusion map. Default is null. The aoMap requires a second set of UVs.</div>
+		<div>The red channel of this texture is used as the ambient occlusion map. Default is null. 
+		The aoMap requires a second set of UVs, and consequently will ignore the [page:Texture repeat]
+		and [page:Texture offset] Texture properties.</div>
 
 
 		<h3>[property:Float aoMapIntensity]</h3>
 		<h3>[property:Float aoMapIntensity]</h3>
 		<div>Intensity of the ambient occlusion effect. Default is 1. Zero is no occlusion effect.</div>
 		<div>Intensity of the ambient occlusion effect. Default is 1. Zero is no occlusion effect.</div>
@@ -182,7 +184,9 @@
 
 
 
 
 		<h3>[property:Texture lightMap]</h3>
 		<h3>[property:Texture lightMap]</h3>
-		<div>The light map. Default is null. The lightMap requires a second set of UVs.</div>
+		<div>The light map. Default is null. The lightMap requires a second set of UVs, 
+		and consequently will ignore the [page:Texture repeat] and [page:Texture offset] 
+		Texture properties.</div>
 
 
 		<h3>[property:Float lightMapIntensity]</h3>
 		<h3>[property:Float lightMapIntensity]</h3>
 		<div>Intensity of the baked light. Default is 1.</div>
 		<div>Intensity of the baked light. Default is 1.</div>

+ 4 - 13
docs/api/math/Euler.html

@@ -54,19 +54,10 @@
 			rotated around its X axis, then its Y axis and finally its Z axis. Other possibilities are:
 			rotated around its X axis, then its Y axis and finally its Z axis. Other possibilities are:
 			'YZX', 'ZXY', 'XZY', 'YXZ' and 'ZYX'. These must be in upper case.<br /><br />
 			'YZX', 'ZXY', 'XZY', 'YXZ' and 'ZYX'. These must be in upper case.<br /><br />
 
 
-			Three.js uses <em>intrinsic</em> (Tait-Bryan) ordering, also known as <em>yaw</em>, <em>pitch</em>
-			and <em>roll</em>. This means that rotations are performed with respect to the <em>local</em>
-			coordinate system. That is, for order 'XYZ', the rotation is first around world-X, then around
-			local-Y (which may now be different from the world Y-axis), then local-Z (which may be different
-			from the world Z-axis).<br /><br />
-
-			Some implementations may use <em>extrinsic</em> (proper) ordering, in which case rotations are performed
-			with respect to the <em>world</em> coordinate system, so that for order 'XYZ', the rotations
-			are around world-X, world-Y, and world-Z.<br /><br />
-
-			Converting between the two types is relatively straightforward, you just need to reverse the order
-			and the rotation, so that an intrinsic (three.js) Euler rotation of angles a, b, c about XYZ
-			will be equivalent to to an extrinsic Euler rotation of angles c, b, a about ZYX.<br /><br />
+			Three.js uses <em>intrinsic</em> Tait-Bryan angles. This means that rotations are performed with respect
+			to the <em>local</em> coordinate system. That is, for order 'XYZ', the rotation is first around the local-X
+			axis (which is the same as the world-X axis), then around local-Y (which may now be different from the
+			world Y-axis), then local-Z (which may be different from the world Z-axis).<br /><br />
 
 
 			If the order is changed, [page:.onChangeCallback onChangeCallback] will be called.
 			If the order is changed, [page:.onChangeCallback onChangeCallback] will be called.
 		</div>
 		</div>

+ 16 - 34
docs/api/math/Plane.html

@@ -11,9 +11,8 @@
 		<h1>[name]</h1>
 		<h1>[name]</h1>
 
 
 		<div class="desc">
 		<div class="desc">
-			A two dimensional surface that extends infinitely in 3d space, defined by
-			a [link:https://en.wikipedia.org/wiki/Normal_(geometry) normal vector], and a
-			distance from the origin along the normal.
+			A two dimensional surface that extends infinitely in 3d space, represented in [link:http://mathworld.wolfram.com/HessianNormalForm.html Hessian normal form]
+			by a normal vector and a constant.
 		</div>
 		</div>
 
 
 
 
@@ -22,10 +21,8 @@
 
 
 		<h3>[name]( [page:Vector3 normal], [page:Float constant] )</h3>
 		<h3>[name]( [page:Vector3 normal], [page:Float constant] )</h3>
 		<div>
 		<div>
-		[page:Vector3 normal] - (optional) a [page:Vector3] defining the direction of the
-		plane. Default is *(1, 0, 0)*.<br />
-		[page:Float constant] - (optional) the negative distance from the origin to the plane along
-		 the [page:Vector3 normal] vector. Default is *0*.
+		[page:Vector3 normal] - (optional) a [page:Vector3] defining the normal of the plane. Default is *(1, 0, 0)*.<br />
+		[page:Float constant] - (optional) the signed distance from the origin to the plane. Default is *0*.
 		</div>
 		</div>
 
 
 
 
@@ -68,10 +65,10 @@
 		</div>
 		</div>
 
 
 		<h3>[method:Float distanceToPoint]( [page:Vector3 point] )</h3>
 		<h3>[method:Float distanceToPoint]( [page:Vector3 point] )</h3>
-		<div>Returns the smallest distance from the [page:Vector3 point] to the plane.</div>
+		<div>Returns the signed distance from the [page:Vector3 point] to the plane.</div>
 
 
 		<h3>[method:Float distanceToSphere]( [page:Sphere sphere] )</h3>
 		<h3>[method:Float distanceToSphere]( [page:Sphere sphere] )</h3>
-		<div>Returns the smallest distance from the [page:Sphere sphere] to the plane.</div>
+		<div>Returns the signed distance from the [page:Sphere sphere] to the plane.</div>
 
 
 		<h3>[method:Boolean equals]( [page:Plane plane] )</h3>
 		<h3>[method:Boolean equals]( [page:Plane plane] )</h3>
 		<div>
 		<div>
@@ -113,8 +110,7 @@
 
 
 		<h3>[method:Plane negate]()</h3>
 		<h3>[method:Plane negate]()</h3>
 		<div>
 		<div>
-		Negates both the normal vector and constant, effectively mirroring the plane across
-		the origin.
+		Negates both the normal vector and the constant.
 		</div>
 		</div>
 
 
 		<h3>[method:Plane normalize]()</h3>
 		<h3>[method:Plane normalize]()</h3>
@@ -123,32 +119,19 @@
 			value accordingly.
 			value accordingly.
 		</div>
 		</div>
 
 
-		<h3>[method:Vector3 orthoPoint]( [page:Vector3 point], [page:Vector3 optionalTarget] )</h3>
-		<div>
-		[page:Vector3 point] - [page:Vector3] <br />
-		[page:Vector3 optionalTarget] - (optional) if specified, the result will be copied
-		into this [page:Vector3], otherwise a new [page:Vector3] will be created.<br /><br />
-
-		Returns a vector in the same direction as the Plane's normal, but with magnitude
-		equal to the passed point's original distance to the plane.
-		</div>
-
 		<h3>[method:Vector3 projectPoint]( [page:Vector3 point], [page:Vector3 optionalTarget] )</h3>
 		<h3>[method:Vector3 projectPoint]( [page:Vector3 point], [page:Vector3 optionalTarget] )</h3>
 		<div>
 		<div>
 		[page:Vector3 point] - the [page:Vector3] to project onto the plane.<br />
 		[page:Vector3 point] - the [page:Vector3] to project onto the plane.<br />
 		[page:Vector3 optionalTarget] - (optional) if specified, the result will be copied into this [page:Vector3],
 		[page:Vector3 optionalTarget] - (optional) if specified, the result will be copied into this [page:Vector3],
 		otherwise a new [page:Vector3] will be created.<br /><br />
 		otherwise a new [page:Vector3] will be created.<br /><br />
 
 
-		Projects a [page:Vector3 point] onto the plane. The projected point is the closest
-		 point on the plane to the passed point, so a line drawn from the projected point
-		 and the passed point would be orthogonal to the plane.
+		Projects a [page:Vector3 point] onto the plane.
 		</div>
 		</div>
 
 
 		<h3>[method:Plane set]( [page:Vector3 normal], [page:Float constant] )</h3>
 		<h3>[method:Plane set]( [page:Vector3 normal], [page:Float constant] )</h3>
 		<div>
 		<div>
-			[page:Vector3 normal] -  a [page:Vector3] defining the direction of the	plane.<br />
-			[page:Float constant] - (optional) the negative distance from the origin to the plane along
-			 the [page:Vector3 normal] vector. Default is *0*.<br /><br />
+			[page:Vector3 normal] - a [page:Vector3] defining the normal of the plane.<br />
+			[page:Float constant] - the signed distance from the origin to the plane. Default is *0*.<br /><br />
 
 
 			 Sets the plane's [page:.normal normal] and [page:.constant constant] properties.
 			 Sets the plane's [page:.normal normal] and [page:.constant constant] properties.
 		</div>
 		</div>
@@ -160,7 +143,7 @@
 		[page:Float z] - z value of the normal vector.<br />
 		[page:Float z] - z value of the normal vector.<br />
 		[page:Float w] - the value of the plane's [page:.constant constant] property.<br /><br />
 		[page:Float w] - the value of the plane's [page:.constant constant] property.<br /><br />
 
 
-		Set the individual components that make up the plane.
+		Set the individual components that define the plane.
 		</div>
 		</div>
 
 
 		<h3>[method:Plane setFromCoplanarPoints]( [page:Vector3 a], [page:Vector3 b], [page:Vector3 c] )</h3>
 		<h3>[method:Plane setFromCoplanarPoints]( [page:Vector3 a], [page:Vector3 b], [page:Vector3 c] )</h3>
@@ -169,13 +152,13 @@
 		 [page:Vector3 a] - second point on the plane.<br />
 		 [page:Vector3 a] - second point on the plane.<br />
 		 [page:Vector3 a] - third point on the plane.<br /><br />
 		 [page:Vector3 a] - third point on the plane.<br /><br />
 
 
-		Defines the plane based on the 3 provided points. The winding order is counter
-		clockwise, and determines which direction the [page:.normal normal] will point.
+		Defines the plane based on the 3 provided points. The winding order is assumed to be counter-clockwise,
+		and determines the direction of the [page:.normal normal].
 		</div>
 		</div>
 
 
 		<h3>[method:Plane setFromNormalAndCoplanarPoint]( [page:Vector3 normal], [page:Vector3 point] ) [page:Vector3 this]</h3>
 		<h3>[method:Plane setFromNormalAndCoplanarPoint]( [page:Vector3 normal], [page:Vector3 point] ) [page:Vector3 this]</h3>
 		<div>
 		<div>
-		[page:Vector3 normal] - a [page:Vector3] defining the direction of the plane.<br />
+		[page:Vector3 normal] - a [page:Vector3] defining the normal of the plane.<br />
 		[page:Vector3 point] - [page:Vector3]<br /><br />
 		[page:Vector3 point] - [page:Vector3]<br /><br />
 
 
 		Sets the plane's properties as defined by a [page:Vector3 normal] and an arbitrary coplanar [page:Vector3 point].
 		Sets the plane's properties as defined by a [page:Vector3 normal] and an arbitrary coplanar [page:Vector3 point].
@@ -185,9 +168,8 @@
 		<div>
 		<div>
 		[page:Vector3 offset] - the amount to move the plane by.<br /><br />
 		[page:Vector3 offset] - the amount to move the plane by.<br /><br />
 
 
-		Translates the plane the distance defined by the [page:Vector3 offset] vector.
-		Note that this only affects	the constant (distance from origin) and will not affect
-		the normal vector.
+		Translates the plane by the distance defined by the [page:Vector3 offset] vector.
+		Note that this only affects the plane constant and will not affect the normal vector.
 		</div>
 		</div>
 
 
 		<h2>Source</h2>
 		<h2>Source</h2>

+ 9 - 0
docs/api/math/Vector4.html

@@ -110,6 +110,15 @@ var d = a.dot( b );
 		If this vector's x, y, z or w value is less than the min vector's x, y, z or w value, it is replaced by the corresponding value.
 		If this vector's x, y, z or w value is less than the min vector's x, y, z or w value, it is replaced by the corresponding value.
 		</div>
 		</div>
 
 
+		<h3>[method:Vector4 clampLength]( [page:Float min], [page:Float max] )</h3>
+		<div>
+		[page:Float min] - the minimum value the length will be clamped to <br />
+		[page:Float max] - the maximum value the length will be clamped to<br /><br />
+
+		If this vector's length is greater than the max value, it is replaced by the max value. <br /><br />
+		If this vector's length is less than the min value, it is replaced by the min value.
+		</div>
+
 		<h3>[method:Vector4 clampScalar]( [page:Float min], [page:Float max] )</h3>
 		<h3>[method:Vector4 clampScalar]( [page:Float min], [page:Float max] )</h3>
 		<div>
 		<div>
 		[page:Float min] - the minimum value the components will be clamped to <br />
 		[page:Float min] - the minimum value the components will be clamped to <br />

+ 1 - 1
docs/api/objects/Group.html

@@ -28,7 +28,7 @@
 		cubeA.position.set( 100, 100, 0 );
 		cubeA.position.set( 100, 100, 0 );
 
 
 		var cubeB = new THREE.Mesh( geometry, material );
 		var cubeB = new THREE.Mesh( geometry, material );
-		cubeA.position.set( -100, -100, 0 );
+		cubeB.position.set( -100, -100, 0 );
 
 
 		//create a group and add the two cubes
 		//create a group and add the two cubes
 		//These cubes can now be rotated / scaled etc as a group
 		//These cubes can now be rotated / scaled etc as a group

+ 3 - 0
docs/api/renderers/WebGLRenderer.html

@@ -353,6 +353,9 @@
 		<h3>[method:Number getMaxAnisotropy]()</h3>
 		<h3>[method:Number getMaxAnisotropy]()</h3>
 		<div>This returns the anisotropy level of the textures.</div>
 		<div>This returns the anisotropy level of the textures.</div>
 
 
+		<h3>[method:Object getDrawingBufferSize]()</h3>
+		<div>Returns an object containing the width and height of the renderer's drawing buffer, in pixels.</div>
+
 		<h3>[method:number getPixelRatio]()</h3>
 		<h3>[method:number getPixelRatio]()</h3>
 		<div>Returns current device pixel ratio used.</div>
 		<div>Returns current device pixel ratio used.</div>
 
 

+ 1 - 1
examples/css3d_sandbox.html

@@ -66,7 +66,7 @@
 					var element = document.createElement( 'div' );
 					var element = document.createElement( 'div' );
 					element.style.width = '100px';
 					element.style.width = '100px';
 					element.style.height = '100px';
 					element.style.height = '100px';
-					element.style.opacity = 0.5;
+					element.style.opacity = ( i < 5 ) ? 0.5 : 1;
 					element.style.background = new THREE.Color( Math.random() * 0xffffff ).getStyle();
 					element.style.background = new THREE.Color( Math.random() * 0xffffff ).getStyle();
 
 
 					var object = new THREE.CSS3DObject( element );
 					var object = new THREE.CSS3DObject( element );

+ 2 - 0
examples/files.js

@@ -111,6 +111,7 @@ var files = {
 		"webgl_loader_pcd",
 		"webgl_loader_pcd",
 		"webgl_loader_pdb",
 		"webgl_loader_pdb",
 		"webgl_loader_ply",
 		"webgl_loader_ply",
+		"webgl_loader_prwm",
 		"webgl_loader_ttf",
 		"webgl_loader_ttf",
 		"webgl_loader_sea3d",
 		"webgl_loader_sea3d",
 		"webgl_loader_sea3d_hierarchy",
 		"webgl_loader_sea3d_hierarchy",
@@ -245,6 +246,7 @@ var files = {
 		"webgl_simple_gi",
 		"webgl_simple_gi",
 		"webgl_skinning_simple",
 		"webgl_skinning_simple",
 		"webgl_sprites",
 		"webgl_sprites",
+		"webgl_sprites_nodes",
 		"webgl_terrain_dynamic",
 		"webgl_terrain_dynamic",
 		"webgl_test_memory",
 		"webgl_test_memory",
 		"webgl_test_memory2",
 		"webgl_test_memory2",

+ 8 - 7
examples/js/GPUParticleSystem.js

@@ -461,13 +461,14 @@ THREE.GPUParticleContainer = function( maxParticles, particleSystem ) {
 				sizeAttribute.updateRange.offset = 0;
 				sizeAttribute.updateRange.offset = 0;
 				lifeTimeAttribute.updateRange.offset = 0;
 				lifeTimeAttribute.updateRange.offset = 0;
 
 
-				positionStartAttribute.updateRange.count = positionStartAttribute.count;
-				startTimeAttribute.updateRange.count = startTimeAttribute.count;
-				velocityAttribute.updateRange.count = velocityAttribute.count;
-				turbulenceAttribute.updateRange.count = turbulenceAttribute.count;
-				colorAttribute.updateRange.count = colorAttribute.count;
-				sizeAttribute.updateRange.count = sizeAttribute.count;
-				lifeTimeAttribute.updateRange.count = lifeTimeAttribute.count;
+				// Use -1 to update the entire buffer, see #11476
+				positionStartAttribute.updateRange.count = -1;
+				startTimeAttribute.updateRange.count = -1;
+				velocityAttribute.updateRange.count = -1;
+				turbulenceAttribute.updateRange.count = -1;
+				colorAttribute.updateRange.count = -1;
+				sizeAttribute.updateRange.count = -1;
+				lifeTimeAttribute.updateRange.count = -1;
 
 
 			}
 			}
 
 

+ 25 - 15
examples/js/Mirror.js

@@ -27,10 +27,13 @@ THREE.Mirror = function ( width, height, options ) {
 	var lookAtPosition = new THREE.Vector3( 0, 0, - 1 );
 	var lookAtPosition = new THREE.Vector3( 0, 0, - 1 );
 	var clipPlane = new THREE.Vector4();
 	var clipPlane = new THREE.Vector4();
 
 
+	var view = new THREE.Vector3();
+	var target = new THREE.Vector3();
+	var q = new THREE.Vector4();
+
 	var textureMatrix = new THREE.Matrix4();
 	var textureMatrix = new THREE.Matrix4();
 
 
 	var mirrorCamera = new THREE.PerspectiveCamera();
 	var mirrorCamera = new THREE.PerspectiveCamera();
-	mirrorCamera.matrixAutoUpdate = true;
 
 
 	var parameters = {
 	var parameters = {
 		minFilter: THREE.LinearFilter,
 		minFilter: THREE.LinearFilter,
@@ -106,11 +109,6 @@ THREE.Mirror = function ( width, height, options ) {
 
 
 	function updateTextureMatrix( camera ) {
 	function updateTextureMatrix( camera ) {
 
 
-		camera.updateMatrixWorld();
-
-		mirrorCamera.copy( camera );
-		mirrorCamera.updateProjectionMatrix();
-
 		scope.updateMatrixWorld();
 		scope.updateMatrixWorld();
 
 
 		mirrorWorldPosition.setFromMatrixPosition( scope.matrixWorld );
 		mirrorWorldPosition.setFromMatrixPosition( scope.matrixWorld );
@@ -121,7 +119,7 @@ THREE.Mirror = function ( width, height, options ) {
 		normal.set( 0, 0, 1 );
 		normal.set( 0, 0, 1 );
 		normal.applyMatrix4( rotationMatrix );
 		normal.applyMatrix4( rotationMatrix );
 
 
-		var view = mirrorWorldPosition.clone().sub( cameraWorldPosition );
+		view.subVectors( mirrorWorldPosition, cameraWorldPosition );
 		view.reflect( normal ).negate();
 		view.reflect( normal ).negate();
 		view.add( mirrorWorldPosition );
 		view.add( mirrorWorldPosition );
 
 
@@ -131,7 +129,7 @@ THREE.Mirror = function ( width, height, options ) {
 		lookAtPosition.applyMatrix4( rotationMatrix );
 		lookAtPosition.applyMatrix4( rotationMatrix );
 		lookAtPosition.add( cameraWorldPosition );
 		lookAtPosition.add( cameraWorldPosition );
 
 
-		var target = mirrorWorldPosition.clone().sub( lookAtPosition );
+		target.subVectors( mirrorWorldPosition, lookAtPosition );
 		target.reflect( normal ).negate();
 		target.reflect( normal ).negate();
 		target.add( mirrorWorldPosition );
 		target.add( mirrorWorldPosition );
 
 
@@ -141,8 +139,11 @@ THREE.Mirror = function ( width, height, options ) {
 		mirrorCamera.up.reflect( normal ).negate();
 		mirrorCamera.up.reflect( normal ).negate();
 		mirrorCamera.lookAt( target );
 		mirrorCamera.lookAt( target );
 
 
-		mirrorCamera.updateProjectionMatrix();
+		mirrorCamera.near = camera.near;
+		mirrorCamera.far = camera.far;
+
 		mirrorCamera.updateMatrixWorld();
 		mirrorCamera.updateMatrixWorld();
+		mirrorCamera.updateProjectionMatrix();
 
 
 		// Update the texture matrix
 		// Update the texture matrix
 		textureMatrix.set(
 		textureMatrix.set(
@@ -161,7 +162,6 @@ THREE.Mirror = function ( width, height, options ) {
 
 
 		clipPlane.set( mirrorPlane.normal.x, mirrorPlane.normal.y, mirrorPlane.normal.z, mirrorPlane.constant );
 		clipPlane.set( mirrorPlane.normal.x, mirrorPlane.normal.y, mirrorPlane.normal.z, mirrorPlane.constant );
 
 
-		var q = new THREE.Vector4();
 		var projectionMatrix = mirrorCamera.projectionMatrix;
 		var projectionMatrix = mirrorCamera.projectionMatrix;
 
 
 		q.x = ( Math.sign( clipPlane.x ) + projectionMatrix.elements[ 8 ] ) / projectionMatrix.elements[ 0 ];
 		q.x = ( Math.sign( clipPlane.x ) + projectionMatrix.elements[ 8 ] ) / projectionMatrix.elements[ 0 ];
@@ -170,13 +170,13 @@ THREE.Mirror = function ( width, height, options ) {
 		q.w = ( 1.0 + projectionMatrix.elements[ 10 ] ) / projectionMatrix.elements[ 14 ];
 		q.w = ( 1.0 + projectionMatrix.elements[ 10 ] ) / projectionMatrix.elements[ 14 ];
 
 
 		// Calculate the scaled plane vector
 		// Calculate the scaled plane vector
-		var c = clipPlane.multiplyScalar( 2.0 / clipPlane.dot( q ) );
+		clipPlane.multiplyScalar( 2.0 / clipPlane.dot( q ) );
 
 
 		// Replacing the third row of the projection matrix
 		// Replacing the third row of the projection matrix
-		projectionMatrix.elements[ 2 ] = c.x;
-		projectionMatrix.elements[ 6 ] = c.y;
-		projectionMatrix.elements[ 10 ] = c.z + 1.0 - clipBias;
-		projectionMatrix.elements[ 14 ] = c.w;
+		projectionMatrix.elements[ 2 ] = clipPlane.x;
+		projectionMatrix.elements[ 6 ] = clipPlane.y;
+		projectionMatrix.elements[ 10 ] = clipPlane.z + 1.0 - clipBias;
+		projectionMatrix.elements[ 14 ] = clipPlane.w;
 
 
 	}
 	}
 
 
@@ -188,7 +188,17 @@ THREE.Mirror = function ( width, height, options ) {
 
 
 		var currentRenderTarget = renderer.getRenderTarget();
 		var currentRenderTarget = renderer.getRenderTarget();
 
 
+		var currentVrEnabled = renderer.vr.enabled;
+		var currentShadowAutoUpdate = renderer.shadowMap.autoUpdate;
+
+		renderer.vr.enabled = false; // Avoid camera modification and recursion
+		renderer.shadowMap.autoUpdate = false; // Avoid re-computing shadows
+
 		renderer.render( scene, mirrorCamera, renderTarget, true );
 		renderer.render( scene, mirrorCamera, renderTarget, true );
+
+		renderer.vr.enabled = currentVrEnabled;
+		renderer.shadowMap.autoUpdate = currentShadowAutoUpdate;
+
 		renderer.setRenderTarget( currentRenderTarget );
 		renderer.setRenderTarget( currentRenderTarget );
 
 
 		scope.visible = true;
 		scope.visible = true;

+ 2 - 0
examples/js/controls/OrbitControls.js

@@ -888,6 +888,8 @@ THREE.OrbitControls = function ( object, domElement ) {
 
 
 	function onContextMenu( event ) {
 	function onContextMenu( event ) {
 
 
+		if ( scope.enabled === false ) return;
+
 		event.preventDefault();
 		event.preventDefault();
 
 
 	}
 	}

+ 2 - 0
examples/js/controls/TrackballControls.js

@@ -579,6 +579,8 @@ THREE.TrackballControls = function ( object, domElement ) {
 
 
 	function contextmenu( event ) {
 	function contextmenu( event ) {
 
 
+		if ( _this.enabled === false ) return;
+
 		event.preventDefault();
 		event.preventDefault();
 
 
 	}
 	}

+ 4 - 11
examples/js/effects/OutlineEffect.js

@@ -93,27 +93,20 @@ THREE.OutlineEffect = function ( renderer, parameters ) {
 	var vertexShaderChunk2 = [
 	var vertexShaderChunk2 = [
 
 
 		"#if ! defined( LAMBERT ) && ! defined( PHONG ) && ! defined( TOON ) && ! defined( PHYSICAL )",
 		"#if ! defined( LAMBERT ) && ! defined( PHONG ) && ! defined( TOON ) && ! defined( PHYSICAL )",
-
 		"	#ifndef USE_ENVMAP",
 		"	#ifndef USE_ENVMAP",
 		"		vec3 objectNormal = normalize( normal );",
 		"		vec3 objectNormal = normalize( normal );",
-
-		"		#ifdef FLIP_SIDED",
-		"			objectNormal = -objectNormal;",
-		"		#endif",
-
 		"	#endif",
 		"	#endif",
+		"#endif",
 
 
+		"#ifdef FLIP_SIDED",
+		"	objectNormal = -objectNormal;",
 		"#endif",
 		"#endif",
 
 
 		"#ifdef DECLARE_TRANSFORMED",
 		"#ifdef DECLARE_TRANSFORMED",
 		"	vec3 transformed = vec3( position );",
 		"	vec3 transformed = vec3( position );",
 		"#endif",
 		"#endif",
 
 
-		"#ifdef USE_SKINNING",
-		"	gl_Position = calculateOutline( gl_Position, objectNormal, skinned );",
-		"#else",
-		"	gl_Position = calculateOutline( gl_Position, objectNormal, vec4( transformed, 1.0 ) );",
-		"#endif",
+		"gl_Position = calculateOutline( gl_Position, objectNormal, vec4( transformed, 1.0 ) );",
 
 
 		"#include <fog_vertex>"
 		"#include <fog_vertex>"
 
 

+ 151 - 34
examples/js/loaders/ColladaLoader2.js

@@ -432,8 +432,10 @@ THREE.ColladaLoader.prototype = {
 
 
 			var keyframes = prepareAnimationData( data, defaultMatrix );
 			var keyframes = prepareAnimationData( data, defaultMatrix );
 
 
+			if ( node.type !== 'JOINT' ) console.warn( 'THREE.ColladaLoader: Animation data for invalid node with ID "%s" found. The loader only supports animation of bones (skeletal animation).', node.id );
+
 			var animation = {
 			var animation = {
-				name: '.bones[' + node.sid + ']',
+				name: '.skeleton.bones[' + node.sid + ']',
 				keyframes: keyframes
 				keyframes: keyframes
 			}
 			}
 
 
@@ -864,7 +866,7 @@ THREE.ColladaLoader.prototype = {
 			var BONE_LIMIT = 4;
 			var BONE_LIMIT = 4;
 
 
 			var build = {
 			var build = {
-				bones: {},
+				joints: [], // this must be an array to preserve the joint order
 				indices: {
 				indices: {
 					array: [],
 					array: [],
 					stride: BONE_LIMIT
 					stride: BONE_LIMIT
@@ -949,7 +951,7 @@ THREE.ColladaLoader.prototype = {
 				var name = jointSource.array[ i ];
 				var name = jointSource.array[ i ];
 				var boneInverse = new THREE.Matrix4().fromArray( inverseSource.array, i * inverseSource.stride ).transpose();
 				var boneInverse = new THREE.Matrix4().fromArray( inverseSource.array, i * inverseSource.stride ).transpose();
 
 
-				build.bones[ name ] = boneInverse;
+				build.joints.push( { name: name, boneInverse: boneInverse } );
 
 
 			}
 			}
 
 
@@ -1219,7 +1221,9 @@ THREE.ColladaLoader.prototype = {
 
 
 		function parseEffectParameterTexture( xml ) {
 		function parseEffectParameterTexture( xml ) {
 
 
-			var data = {};
+			var data = {
+				technique: {}
+			};
 
 
 			for ( var i = 0, l = xml.childNodes.length; i < l; i ++ ) {
 			for ( var i = 0, l = xml.childNodes.length; i < l; i ++ ) {
 
 
@@ -1230,7 +1234,7 @@ THREE.ColladaLoader.prototype = {
 				switch ( child.nodeName ) {
 				switch ( child.nodeName ) {
 
 
 					case 'extra':
 					case 'extra':
-						data = parseEffectParameterTextureExtra( child );
+						parseEffectParameterTextureExtra( child, data );
 						break;
 						break;
 
 
 				}
 				}
@@ -1241,9 +1245,7 @@ THREE.ColladaLoader.prototype = {
 
 
 		}
 		}
 
 
-		function parseEffectParameterTextureExtra( xml ) {
-
-			var data = {};
+		function parseEffectParameterTextureExtra( xml, data ) {
 
 
 			for ( var i = 0, l = xml.childNodes.length; i < l; i ++ ) {
 			for ( var i = 0, l = xml.childNodes.length; i < l; i ++ ) {
 
 
@@ -1254,20 +1256,16 @@ THREE.ColladaLoader.prototype = {
 				switch ( child.nodeName ) {
 				switch ( child.nodeName ) {
 
 
 					case 'technique':
 					case 'technique':
-						data[ child.nodeName ] = parseEffectParameterTextureExtraTechnique( child );
+						parseEffectParameterTextureExtraTechnique( child, data );
 						break;
 						break;
 
 
 				}
 				}
 
 
 			}
 			}
 
 
-			return data;
-
 		}
 		}
 
 
-		function parseEffectParameterTextureExtraTechnique( xml ) {
-
-			var data = {};
+		function parseEffectParameterTextureExtraTechnique( xml, data ) {
 
 
 			for ( var i = 0, l = xml.childNodes.length; i < l; i ++ ) {
 			for ( var i = 0, l = xml.childNodes.length; i < l; i ++ ) {
 
 
@@ -1281,20 +1279,34 @@ THREE.ColladaLoader.prototype = {
 					case 'repeatV':
 					case 'repeatV':
 					case 'offsetU':
 					case 'offsetU':
 					case 'offsetV':
 					case 'offsetV':
-						data[ child.nodeName ] = parseFloat( child.textContent );
+						data.technique[ child.nodeName ] = parseFloat( child.textContent );
 						break;
 						break;
 
 
 					case 'wrapU':
 					case 'wrapU':
 					case 'wrapV':
 					case 'wrapV':
-						data[ child.nodeName ] = parseInt( child.textContent );
+
+						// some files have values for wrapU/wrapV which become NaN via parseInt
+
+						if ( child.textContent.toUpperCase() === 'TRUE' ) {
+
+							data.technique[ child.nodeName ] = 1;
+
+						} else if ( child.textContent.toUpperCase() === 'FALSE' ) {
+
+							data.technique[ child.nodeName ] = 0;
+
+						} else {
+
+							data.technique[ child.nodeName ] = parseInt( child.textContent );
+
+						}
+
 						break;
 						break;
 
 
 				}
 				}
 
 
 			}
 			}
 
 
-			return data;
-
 		}
 		}
 
 
 		function buildEffect( data ) {
 		function buildEffect( data ) {
@@ -1415,8 +1427,8 @@ THREE.ColladaLoader.prototype = {
 						if ( parameter.texture ) material.map = getTexture( parameter.texture );
 						if ( parameter.texture ) material.map = getTexture( parameter.texture );
 						break;
 						break;
 					case 'specular':
 					case 'specular':
-						if ( parameter.color && material.specular )
-							material.specular.fromArray( parameter.color );
+						if ( parameter.color && material.specular ) material.specular.fromArray( parameter.color );
+						if ( parameter.texture ) material.specularMap = getTexture( parameter.texture );
 						break;
 						break;
 					case 'shininess':
 					case 'shininess':
 						if ( parameter.float && material.shininess )
 						if ( parameter.float && material.shininess )
@@ -2191,7 +2203,8 @@ THREE.ColladaLoader.prototype = {
 
 
 			var data = {
 			var data = {
 				id: parseId( xml.getAttribute( 'url' ) ),
 				id: parseId( xml.getAttribute( 'url' ) ),
-				materials: {}
+				materials: {},
+				skeletons: []
 			};
 			};
 
 
 			for ( var i = 0; i < xml.childNodes.length; i ++ ) {
 			for ( var i = 0; i < xml.childNodes.length; i ++ ) {
@@ -2216,7 +2229,7 @@ THREE.ColladaLoader.prototype = {
 						break;
 						break;
 
 
 					case 'skeleton':
 					case 'skeleton':
-						data.skeleton = parseId( child.textContent );;
+						data.skeletons.push( parseId( child.textContent ) );
 						break;
 						break;
 
 
 					default:
 					default:
@@ -2230,24 +2243,128 @@ THREE.ColladaLoader.prototype = {
 
 
 		}
 		}
 
 
-		function getSkeleton( root, controller ) {
+		function getSkeleton( skeletons, joints, skinnedMesh ) {
+
+			var boneData = [];
+			var sortedBoneData = [];
+
+			var i, j, data;
+
+			// a skeleton can have multiple root bones. collada expresses this
+			// situtation with multiple "skeleton" tags per controller instance
+
+			for ( i = 0; i < skeletons.length; i ++ ) {
+
+				var skeleton = skeletons[ i ];
+				var root = getNode( skeleton );
+
+				// bone hierarchy is a child of the skinned mesh
+
+				skinnedMesh.add( root );
+
+				// setup bone data for a single bone hierarchy
+
+				buildBoneHierarchy( root, joints, boneData );
+
+			}
+
+			// sort bone data (the order is defined in the corresponding controller)
+
+			for ( i = 0; i < joints.length; i ++ ) {
+
+				for ( j = 0; j < boneData.length; j ++ ) {
+
+					data = boneData[ j ];
+
+					if ( data.bone.name === joints[ i ].name ) {
+
+						sortedBoneData[ i ] = data;
+						data.processed = true;
+						break;
+
+					}
+
+				}
+
+			}
+
+			// add unprocessed bone data at the end of the list
+
+			for ( i = 0; i < boneData.length; i ++ ) {
+
+				data = boneData[ i ];
+
+				if ( data.processed === false ) {
+
+					sortedBoneData.push( data );
+					data.processed = true;
+
+				}
+
+			}
+
+			// setup arrays for skeleton creation
+
+			var bones = [];
+			var boneInverses = [];
+
+			for ( i = 0; i < sortedBoneData.length; i ++ ) {
+
+				data = sortedBoneData[ i ];
+
+				bones.push( data.bone );
+				boneInverses.push( data.boneInverse );
+
+			}
+
+			return new THREE.Skeleton( bones, boneInverses );
+
+		}
+
+		function buildBoneHierarchy( root, joints, boneData ) {
 
 
-			var boneArray = [];
-			var boneInverseArray = [];
+			// setup bone data from visual scene
 
 
 			root.traverse( function( object ) {
 			root.traverse( function( object ) {
 
 
 				if ( object.isBone === true ) {
 				if ( object.isBone === true ) {
 
 
-					boneArray.push( object );
-					boneInverseArray.push( controller.skin.bones[ object.name ] );
+					var boneInverse;
+
+					// retrieve the boneInverse from the controller data
+
+					for ( var i = 0; i < joints.length; i ++ ) {
+
+						var joint = joints[ i ];
+
+						if ( joint.name === object.name ) {
+
+							boneInverse = joint.boneInverse;
+							break;
+
+						}
+
+					}
+
+					if ( boneInverse === undefined ) {
+
+						// Unfortunately, there can be joints in the visual scene that are not part of the
+						// corresponding controller. In this case, we have to create a dummy boneInverse matrix
+						// for the respective bone. This bone won't affect any vertices, because there are no skin indices
+						// and weights defined for it. But we still have to add the bone to the sorted bone list in order to
+						// ensure a correct animation of the model.
+
+						 boneInverse = new THREE.Matrix4();
+						 console.warn( 'THREE.ColladaLoader: Missing data for bone: %s.', object.name );
+
+					}
+
+					boneData.push( { bone: object, boneInverse: boneInverse, processed: false } );
 
 
 				}
 				}
 
 
 			} );
 			} );
 
 
-			return new THREE.Skeleton( boneArray, boneInverseArray );
-
 		}
 		}
 
 
 		function buildNode( data ) {
 		function buildNode( data ) {
@@ -2265,7 +2382,7 @@ THREE.ColladaLoader.prototype = {
 
 
 			for ( var i = 0, l = nodes.length; i < l; i ++ ) {
 			for ( var i = 0, l = nodes.length; i < l; i ++ ) {
 
 
-				objects.push( getNode( nodes[ i ] ).clone() );
+				objects.push( getNode( nodes[ i ] ) );
 
 
 			}
 			}
 
 
@@ -2283,13 +2400,13 @@ THREE.ColladaLoader.prototype = {
 				var materials = resolveMaterialBinding( geometry.materialKeys, instance.materials );
 				var materials = resolveMaterialBinding( geometry.materialKeys, instance.materials );
 				var object = getObject( geometry, materials );
 				var object = getObject( geometry, materials );
 
 
-				var node = getNode( instance.skeleton );
-				var skeleton = getSkeleton( node, controller );
+				var skeletons = instance.skeletons;
+				var joints = controller.skin.joints;
+
+				var skeleton = getSkeleton( skeletons, joints, object );
 
 
 				object.bind( skeleton, controller.skin.bindMatrix );
 				object.bind( skeleton, controller.skin.bindMatrix );
 				object.normalizeSkinWeights();
 				object.normalizeSkinWeights();
-				object.bones = skeleton.bones; // this is necessary for property binding
-				object.add( node ); // bone hierarchy is a child of the skinned mesh
 
 
 				objects.push( object );
 				objects.push( object );
 
 

+ 77 - 18
examples/js/loaders/FBXLoader.js

@@ -738,8 +738,38 @@
 
 
 		}
 		}
 
 
+		var weightTable = {};
+
+		if ( deformer ) {
+
+			var subDeformers = deformer.map;
+
+			for ( var key in subDeformers ) {
+
+				var subDeformer = subDeformers[ key ];
+				var indices = subDeformer.indices;
+
+				for ( var j = 0; j < indices.length; j ++ ) {
+
+					var index = indices[ j ];
+					var weight = subDeformer.weights[ j ];
+
+					if ( weightTable[ index ] === undefined ) weightTable[ index ] = [];
+
+					weightTable[ index ].push( {
+						id: subDeformer.index,
+						weight: weight
+					} );
+
+				}
+
+			}
+
+		}
+
 		var faceVertexBuffer = [];
 		var faceVertexBuffer = [];
 		var polygonIndex = 0;
 		var polygonIndex = 0;
+		var displayedWeightsWarning = false;
 
 
 		for ( var polygonVertexIndex = 0; polygonVertexIndex < indexBuffer.length; polygonVertexIndex ++ ) {
 		for ( var polygonVertexIndex = 0; polygonVertexIndex < indexBuffer.length; polygonVertexIndex ++ ) {
 
 
@@ -763,25 +793,14 @@
 
 
 			if ( deformer ) {
 			if ( deformer ) {
 
 
-				var subDeformers = deformer.map;
-
-				for ( var key in subDeformers ) {
+				if ( weightTable[ vertexIndex ] !== undefined ) {
 
 
-					var subDeformer = subDeformers[ key ];
-					var indices = subDeformer.indices;
+					var array = weightTable[ vertexIndex ];
 
 
-					for ( var j = 0; j < indices.length; j ++ ) {
+					for ( var j = 0, jl = array.length; j < jl; j ++ ) {
 
 
-						var index = indices[ j ];
-
-						if ( index === vertexIndex ) {
-
-							weights.push( subDeformer.weights[ j ] );
-							weightIndices.push( subDeformer.index );
-
-							break;
-
-						}
+						weights.push( array[ j ].weight );
+						weightIndices.push( array[ j ].id );
 
 
 					}
 					}
 
 
@@ -789,7 +808,12 @@
 
 
 				if ( weights.length > 4 ) {
 				if ( weights.length > 4 ) {
 
 
-					console.warn( 'FBXLoader: Vertex has more than 4 skinning weights assigned to vertex.  Deleting additional weights.' );
+					if ( ! displayedWeightsWarning ) {
+
+						console.warn( 'FBXLoader: Vertex has more than 4 skinning weights assigned to vertex.  Deleting additional weights.' );
+						displayedWeightsWarning = true;
+
+					}
 
 
 					var WIndex = [ 0, 0, 0, 0 ];
 					var WIndex = [ 0, 0, 0, 0 ];
 					var Weight = [ 0, 0, 0, 0 ];
 					var Weight = [ 0, 0, 0, 0 ];
@@ -2154,6 +2178,41 @@
 			if ( curveNode.attr === 'R' ) {
 			if ( curveNode.attr === 'R' ) {
 
 
 				var curves = curveNode.curves;
 				var curves = curveNode.curves;
+
+				// Seems like some FBX files have AnimationCurveNode
+				// which doesn't have any connected AnimationCurve.
+				// Setting animation parameter for them here.
+
+				if ( curves.x === null ) {
+
+					curves.x = {
+						version: null,
+						times: [ 0.0 ],
+						values: [ 0.0 ]
+					};
+
+				}
+
+				if ( curves.y === null ) {
+
+					curves.y = {
+						version: null,
+						times: [ 0.0 ],
+						values: [ 0.0 ]
+					};
+
+				}
+
+				if ( curves.z === null ) {
+
+					curves.z = {
+						version: null,
+						times: [ 0.0 ],
+						values: [ 0.0 ]
+					};
+
+				}
+
 				curves.x.values = curves.x.values.map( degreeToRadian );
 				curves.x.values = curves.x.values.map( degreeToRadian );
 				curves.y.values = curves.y.values.map( degreeToRadian );
 				curves.y.values = curves.y.values.map( degreeToRadian );
 				curves.z.values = curves.z.values.map( degreeToRadian );
 				curves.z.values = curves.z.values.map( degreeToRadian );
@@ -4270,7 +4329,7 @@
 
 
 					if ( window.Zlib === undefined ) {
 					if ( window.Zlib === undefined ) {
 
 
-						throw new Error( 'FBXLoader: Import inflate.min.js from https://github.com/imaya/zlib.js' );
+						throw new Error( 'FBXLoader: External library Inflate.min.js required, obtain or import from https://github.com/imaya/zlib.js' );
 
 
 					}
 					}
 
 

+ 66 - 31
examples/js/loaders/GLTF2Loader.js

@@ -336,6 +336,36 @@ THREE.GLTF2Loader = ( function () {
 
 
 			if ( lightNode ) {
 			if ( lightNode ) {
 
 
+				if ( light.constantAttenuation !== undefined ) {
+
+					lightNode.intensity = light.constantAttenuation;
+
+				}
+
+				if ( light.linearAttenuation !== undefined ) {
+
+					lightNode.distance = 1 / light.linearAttenuation;
+
+				}
+
+				if ( light.quadraticAttenuation !== undefined ) {
+
+					lightNode.decay = light.quadraticAttenuation;
+
+				}
+
+				if ( light.fallOffAngle !== undefined ) {
+
+					lightNode.angle = light.fallOffAngle;
+
+				}
+
+				if ( light.fallOffExponent !== undefined ) {
+
+					console.warn( 'GLTF2Loader: light.fallOffExponent not currently supported.' );
+
+				}
+
 				lightNode.name = light.name || ( 'light_' + lightId );
 				lightNode.name = light.name || ( 'light_' + lightId );
 				this.lights[ lightId ] = lightNode;
 				this.lights[ lightId ] = lightNode;
 
 
@@ -412,6 +442,7 @@ THREE.GLTF2Loader = ( function () {
 		if ( materialValues.diffuseFactor !== undefined ) {
 		if ( materialValues.diffuseFactor !== undefined ) {
 
 
 			materialParams.color = new THREE.Color().fromArray( materialValues.diffuseFactor );
 			materialParams.color = new THREE.Color().fromArray( materialValues.diffuseFactor );
+			materialParams.opacity = materialValues.diffuseFactor[ 3 ];
 
 
 		}
 		}
 
 
@@ -1781,17 +1812,17 @@ THREE.GLTF2Loader = ( function () {
 				// For VEC3: itemSize is 3, elementBytes is 4, itemBytes is 12.
 				// For VEC3: itemSize is 3, elementBytes is 4, itemBytes is 12.
 				var elementBytes = TypedArray.BYTES_PER_ELEMENT;
 				var elementBytes = TypedArray.BYTES_PER_ELEMENT;
 				var itemBytes = elementBytes * itemSize;
 				var itemBytes = elementBytes * itemSize;
-
+				var byteStride = json.bufferViews[accessor.bufferView].byteStride;	
 				var array;
 				var array;
 
 
 				// The buffer is not interleaved if the stride is the item size in bytes.
 				// The buffer is not interleaved if the stride is the item size in bytes.
-				if ( accessor.byteStride && accessor.byteStride !== itemBytes ) {
+				if ( byteStride && byteStride !== itemBytes ) {
 
 
 					// Use the full buffer if it's interleaved.
 					// Use the full buffer if it's interleaved.
 					array = new TypedArray( arraybuffer );
 					array = new TypedArray( arraybuffer );
 
 
 					// Integer parameters to IB/IBA are in array elements, not bytes.
 					// Integer parameters to IB/IBA are in array elements, not bytes.
-					var ib = new THREE.InterleavedBuffer( array, accessor.byteStride / elementBytes );
+					var ib = new THREE.InterleavedBuffer( array, byteStride / elementBytes );
 
 
 					return new THREE.InterleavedBufferAttribute( ib, itemSize, accessor.byteOffset / elementBytes );
 					return new THREE.InterleavedBufferAttribute( ib, itemSize, accessor.byteOffset / elementBytes );
 
 
@@ -1957,14 +1988,6 @@ THREE.GLTF2Loader = ( function () {
 
 
 						materialParams.map = dependencies.textures[ metallicRoughness.baseColorTexture.index ];
 						materialParams.map = dependencies.textures[ metallicRoughness.baseColorTexture.index ];
 
 
-						var alphaMode = metallicRoughness.baseColorTexture.alphaMode || ALPHA_MODES.OPAQUE;
-
-						if ( alphaMode !== ALPHA_MODES.OPAQUE ) {
-
-							materialParams.transparent = true;
-
-						}
-
 					}
 					}
 
 
 					materialParams.metalness = metallicRoughness.metallicFactor !== undefined ? metallicRoughness.metallicFactor : 1.0;
 					materialParams.metalness = metallicRoughness.metallicFactor !== undefined ? metallicRoughness.metallicFactor : 1.0;
@@ -1990,7 +2013,9 @@ THREE.GLTF2Loader = ( function () {
 
 
 				}
 				}
 
 
-				if ( materialParams.opacity !== undefined && materialParams.opacity < 1.0 ) {
+				var alphaMode = material.alphaMode || ALPHA_MODES.OPAQUE;
+
+				if ( alphaMode !== ALPHA_MODES.OPAQUE ) {
 
 
 					materialParams.transparent = true;
 					materialParams.transparent = true;
 
 
@@ -2531,28 +2556,30 @@ THREE.GLTF2Loader = ( function () {
 		var extensions = this.extensions;
 		var extensions = this.extensions;
 		var scope = this;
 		var scope = this;
 
 
-		return _each( json.nodes, function ( node ) {
+		var nodes = json.nodes || [];
+		var skins = json.skins || [];
 
 
-			var matrix = new THREE.Matrix4();
+		// Nothing in the node definition indicates whether it is a Bone or an
+		// Object3D. Use the skins' joint references to mark bones.
+		skins.forEach( function ( skin ) {
 
 
-			var _node;
+			skin.joints.forEach( function ( id ) {
 
 
-			if ( node.jointName ) {
+				nodes[ id ].isBone = true;
 
 
-				_node = new THREE.Bone();
-				_node.name = node.name !== undefined ? node.name : node.jointName;
-				_node.jointName = node.jointName;
+			} );
 
 
-			} else {
+		} );
 
 
-				_node = new THREE.Object3D();
-				if ( node.name !== undefined ) _node.name = node.name;
+		return _each( json.nodes, function ( node ) {
 
 
-			}
+			var matrix = new THREE.Matrix4();
+
+			var _node = node.isBone === true ? new THREE.Bone() : new THREE.Object3D();
 
 
-			if ( _node.name !== undefined ) {
+			if ( node.name !== undefined ) {
 
 
-				_node.name = THREE.PropertyBinding.sanitizeNodeName( _node.name );
+				_node.name = THREE.PropertyBinding.sanitizeNodeName( node.name );
 
 
 			}
 			}
 
 
@@ -2765,13 +2792,11 @@ THREE.GLTF2Loader = ( function () {
 					}
 					}
 
 
 					if ( node.extensions
 					if ( node.extensions
-							 && node.extensions[ EXTENSIONS.KHR_MATERIALS_COMMON ]
-							 && node.extensions[ EXTENSIONS.KHR_MATERIALS_COMMON ].light ) {
+							 && node.extensions[ EXTENSIONS.KHR_LIGHTS ]
+							 && node.extensions[ EXTENSIONS.KHR_LIGHTS ].light !== undefined ) {
 
 
-						var extensionLights = extensions[ EXTENSIONS.KHR_LIGHTS ].lights;
-						var light = extensionLights[ node.extensions[ EXTENSIONS.KHR_LIGHTS ].light ];
-
-						_node.add( light );
+						var lights = extensions[ EXTENSIONS.KHR_LIGHTS ].lights;
+						_node.add( lights[ node.extensions[ EXTENSIONS.KHR_LIGHTS ].light ] );
 
 
 					}
 					}
 
 
@@ -2857,6 +2882,16 @@ THREE.GLTF2Loader = ( function () {
 
 
 				} );
 				} );
 
 
+				// Ambient lighting, if present, is always attached to the scene root.
+				if ( scene.extensions
+							 && scene.extensions[ EXTENSIONS.KHR_LIGHTS ]
+							 && scene.extensions[ EXTENSIONS.KHR_LIGHTS ].light !== undefined ) {
+
+					var lights = extensions[ EXTENSIONS.KHR_LIGHTS ].lights;
+					_scene.add( lights[ scene.extensions[ EXTENSIONS.KHR_LIGHTS ].light ] );
+
+				}
+
 				return _scene;
 				return _scene;
 
 
 			} );
 			} );

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

@@ -666,7 +666,7 @@ THREE.GLTFLoader = ( function () {
 
 
 		if ( window.TextDecoder !== undefined ) {
 		if ( window.TextDecoder !== undefined ) {
 
 
-			//return new TextDecoder().decode( array );
+			return new TextDecoder().decode( array );
 
 
 		}
 		}
 
 

+ 293 - 0
examples/js/loaders/PRWMLoader.js

@@ -0,0 +1,293 @@
+/**
+ * @author Kevin Chapelier / https://github.com/kchapelier
+ * See https://github.com/kchapelier/PRWM for more informations about this file format
+ */
+
+( function ( THREE ) {
+
+	"use strict";
+
+	var bigEndianPlatform = null;
+
+	/**
+	 * Check if the endianness of the platform is big-endian (most significant bit first)
+	 * @returns {boolean} True if big-endian, false if little-endian
+	 */
+	function isBigEndianPlatform() {
+
+		if ( bigEndianPlatform === null ) {
+
+			var buffer = new ArrayBuffer( 2 ),
+				uint8Array = new Uint8Array( buffer ),
+				uint16Array = new Uint16Array( buffer );
+
+			uint8Array[ 0 ] = 0xAA; // set first byte
+			uint8Array[ 1 ] = 0xBB; // set second byte
+			bigEndianPlatform = ( uint16Array[ 0 ] === 0xAABB );
+
+		}
+
+		return bigEndianPlatform;
+
+	}
+
+	// match the values defined in the spec to the TypedArray types
+	var InvertedEncodingTypes = [
+		null,
+		Float32Array,
+		null,
+		Int8Array,
+		Int16Array,
+		null,
+		Int32Array,
+		Uint8Array,
+		Uint16Array,
+		null,
+		Uint32Array
+	];
+
+	// define the method to use on a DataView, corresponding the TypedArray type
+	var getMethods = {
+		Uint16Array: 'getUint16',
+		Uint32Array: 'getUint32',
+		Int16Array: 'getInt16',
+		Int32Array: 'getInt32',
+		Float32Array: 'getFloat32',
+		Float64Array: 'getFloat64'
+	};
+
+
+	function copyFromBuffer( sourceArrayBuffer, viewType, position, length, fromBigEndian ) {
+
+		var bytesPerElement = viewType.BYTES_PER_ELEMENT,
+			result;
+
+		if ( fromBigEndian === isBigEndianPlatform() || bytesPerElement === 1 ) {
+
+			result = new viewType( sourceArrayBuffer, position, length );
+
+		} else {
+
+			var readView = new DataView( sourceArrayBuffer, position, length * bytesPerElement ),
+				getMethod = getMethods[ viewType.name ],
+				littleEndian = ! fromBigEndian,
+				i = 0;
+
+			result = new viewType( length );
+
+			for ( ; i < length; i ++ ) {
+
+				result[ i ] = readView[ getMethod ]( i * bytesPerElement, littleEndian );
+
+			}
+
+		}
+
+		return result;
+
+	}
+
+
+	function decodePrwm( buffer ) {
+
+		var array = new Uint8Array( buffer ),
+			version = array[ 0 ],
+			flags = array[ 1 ],
+			indexedGeometry = !! ( flags >> 7 & 0x01 ),
+			indicesType = flags >> 6 & 0x01,
+			bigEndian = ( flags >> 5 & 0x01 ) === 1,
+			attributesNumber = flags & 0x1F,
+			valuesNumber = 0,
+			indicesNumber = 0;
+
+		if ( bigEndian ) {
+
+			valuesNumber = ( array[ 2 ] << 16 ) + ( array[ 3 ] << 8 ) + array[ 4 ];
+			indicesNumber = ( array[ 5 ] << 16 ) + ( array[ 6 ] << 8 ) + array[ 7 ];
+
+		} else {
+
+			valuesNumber = array[ 2 ] + ( array[ 3 ] << 8 ) + ( array[ 4 ] << 16 );
+			indicesNumber = array[ 5 ] + ( array[ 6 ] << 8 ) + ( array[ 7 ] << 16 );
+
+		}
+
+		/** PRELIMINARY CHECKS **/
+
+		if ( version === 0 ) {
+
+			throw new Error( 'PRWM decoder: Invalid format version: 0' );
+
+		} else if ( version !== 1 ) {
+
+			throw new Error( 'PRWM decoder: Unsupported format version: ' + version );
+
+		}
+
+		if ( ! indexedGeometry ) {
+
+			if ( indicesType !== 0 ) {
+
+				throw new Error( 'PRWM decoder: Indices type must be set to 0 for non-indexed geometries' );
+
+			} else if ( indicesNumber !== 0 ) {
+
+				throw new Error( 'PRWM decoder: Number of indices must be set to 0 for non-indexed geometries' );
+
+			}
+
+		}
+
+		/** PARSING **/
+
+		var pos = 8;
+
+		var attributes = {},
+			attributeName,
+			char,
+			attributeType,
+			attributeNormalized,
+			cardinality,
+			encodingType,
+			arrayType,
+			values,
+			indices,
+			i;
+
+		for ( i = 0; i < attributesNumber; i ++ ) {
+
+			attributeName = '';
+
+			while ( pos < array.length ) {
+
+				char = array[ pos ];
+				pos ++;
+
+				if ( char === 0 ) {
+
+					break;
+
+				} else {
+
+					attributeName += String.fromCharCode( char );
+
+				}
+
+			}
+
+			flags = array[ pos ];
+
+			attributeType = flags >> 7 & 0x01;
+			attributeNormalized = !! ( flags >> 6 & 0x01 );
+			cardinality = ( flags >> 4 & 0x03 ) + 1;
+			encodingType = flags & 0x0F;
+			arrayType = InvertedEncodingTypes[ encodingType ];
+
+			pos ++;
+
+			// padding to next multiple of 4
+			pos = Math.ceil( pos / 4 ) * 4;
+
+			values = copyFromBuffer( buffer, arrayType, pos, cardinality * valuesNumber, bigEndian );
+
+			pos += arrayType.BYTES_PER_ELEMENT * cardinality * valuesNumber;
+
+			attributes[ attributeName ] = {
+				type: attributeType,
+				cardinality: cardinality,
+				values: values
+			};
+
+		}
+
+		pos = Math.ceil( pos / 4 ) * 4;
+
+		indices = null;
+
+		if ( indexedGeometry ) {
+
+			indices = copyFromBuffer(
+				buffer,
+				indicesType === 1 ? Uint32Array : Uint16Array,
+				pos,
+				indicesNumber,
+				bigEndian
+			);
+
+		}
+
+		return {
+			version: version,
+			attributes: attributes,
+			indices: indices
+		};
+
+	}
+
+	// Define the public interface
+
+	THREE.PRWMLoader = function PRWMLoader( manager ) {
+
+		this.manager = ( manager !== undefined ) ? manager : THREE.DefaultLoadingManager;
+
+	};
+
+	THREE.PRWMLoader.prototype = {
+
+		constructor: THREE.PRWMLoader,
+
+		load: function ( url, onLoad, onProgress, onError ) {
+
+			var scope = this;
+
+			var loader = new THREE.FileLoader( scope.manager );
+			loader.setResponseType( 'arraybuffer' );
+
+			url = url.replace( /\*/g, isBigEndianPlatform() ? 'be' : 'le' );
+
+			loader.load( url, function ( arrayBuffer ) {
+
+				onLoad( scope.parse( arrayBuffer ) );
+
+			}, onProgress, onError );
+
+		},
+
+		parse: function ( arrayBuffer ) {
+
+			console.time( 'PRWMLoader' );
+
+			var data = decodePrwm( arrayBuffer ),
+				attributesKey = Object.keys( data.attributes ),
+				bufferGeometry = new THREE.BufferGeometry(),
+				attribute,
+				i;
+
+			for ( i = 0; i < attributesKey.length; i ++ ) {
+
+				attribute = data.attributes[ attributesKey[ i ] ];
+				bufferGeometry.addAttribute( attributesKey[ i ], new THREE.BufferAttribute( attribute.values, attribute.cardinality, attribute.normalized ) );
+
+			}
+
+			if ( data.indices !== null ) {
+
+				bufferGeometry.setIndex( new THREE.BufferAttribute( data.indices, 1 ) );
+
+			}
+
+			console.timeEnd( 'PRWMLoader' );
+
+			return bufferGeometry;
+
+		}
+
+	};
+
+	THREE.PRWMLoader.isBigEndianPlatform = function () {
+
+		return isBigEndianPlatform();
+
+	};
+
+} )( THREE );

+ 52 - 53
examples/js/nodes/materials/PhongNode.js

@@ -2,7 +2,7 @@
  * @author sunag / http://www.sunag.com.br/
  * @author sunag / http://www.sunag.com.br/
  */
  */
 
 
-THREE.PhongNode = function() {
+THREE.PhongNode = function () {
 
 
 	THREE.GLNode.call( this );
 	THREE.GLNode.call( this );
 
 
@@ -15,7 +15,7 @@ THREE.PhongNode = function() {
 THREE.PhongNode.prototype = Object.create( THREE.GLNode.prototype );
 THREE.PhongNode.prototype = Object.create( THREE.GLNode.prototype );
 THREE.PhongNode.prototype.constructor = THREE.PhongNode;
 THREE.PhongNode.prototype.constructor = THREE.PhongNode;
 
 
-THREE.PhongNode.prototype.build = function( builder ) {
+THREE.PhongNode.prototype.build = function ( builder ) {
 
 
 	var material = builder.material;
 	var material = builder.material;
 	var code;
 	var code;
@@ -27,7 +27,7 @@ THREE.PhongNode.prototype.build = function( builder ) {
 
 
 	if ( builder.isShader( 'vertex' ) ) {
 	if ( builder.isShader( 'vertex' ) ) {
 
 
-		var transform = this.transform ? this.transform.parseAndBuildCode( builder, 'v3', { cache : 'transform' } ) : undefined;
+		var transform = this.transform ? this.transform.parseAndBuildCode( builder, 'v3', { cache: 'transform' } ) : undefined;
 
 
 		material.mergeUniform( THREE.UniformsUtils.merge( [
 		material.mergeUniform( THREE.UniformsUtils.merge( [
 
 
@@ -45,21 +45,20 @@ THREE.PhongNode.prototype.build = function( builder ) {
 
 
 			"#endif",
 			"#endif",
 
 
-			THREE.ShaderChunk[ "common" ],
-			THREE.ShaderChunk[ "fog_parse_vertex" ],
-			THREE.ShaderChunk[ "morphtarget_pars_vertex" ],
-			THREE.ShaderChunk[ "skinning_pars_vertex" ],
-			THREE.ShaderChunk[ "shadowmap_pars_vertex" ],
-			THREE.ShaderChunk[ "logdepthbuf_pars_vertex" ]
-
+			"#include <common>",
+			"#include <fog_pars_vertex>",
+			"#include <morphtarget_pars_vertex>",
+			"#include <skinning_pars_vertex>",
+			"#include <shadowmap_pars_vertex>",
+			"#include <logdepthbuf_pars_vertex>"
 		].join( "\n" ) );
 		].join( "\n" ) );
 
 
 		var output = [
 		var output = [
-				THREE.ShaderChunk[ "beginnormal_vertex" ],
-				THREE.ShaderChunk[ "morphnormal_vertex" ],
-				THREE.ShaderChunk[ "skinbase_vertex" ],
-				THREE.ShaderChunk[ "skinnormal_vertex" ],
-				THREE.ShaderChunk[ "defaultnormal_vertex" ],
+			"#include <beginnormal_vertex>",
+			"#include <morphnormal_vertex>",
+			"#include <skinbase_vertex>",
+			"#include <skinnormal_vertex>",
+			"#include <defaultnormal_vertex>",
 
 
 			"#ifndef FLAT_SHADED", // Normal computed with derivatives when FLAT_SHADED
 			"#ifndef FLAT_SHADED", // Normal computed with derivatives when FLAT_SHADED
 
 
@@ -67,8 +66,7 @@ THREE.PhongNode.prototype.build = function( builder ) {
 
 
 			"#endif",
 			"#endif",
 
 
-				THREE.ShaderChunk[ "begin_vertex" ],
-				THREE.ShaderChunk[ "fog_vertex" ]
+			"#include <begin_vertex>"
 		];
 		];
 
 
 		if ( transform ) {
 		if ( transform ) {
@@ -81,15 +79,16 @@ THREE.PhongNode.prototype.build = function( builder ) {
 		}
 		}
 
 
 		output.push(
 		output.push(
-				THREE.ShaderChunk[ "morphtarget_vertex" ],
-				THREE.ShaderChunk[ "skinning_vertex" ],
-				THREE.ShaderChunk[ "project_vertex" ],
-				THREE.ShaderChunk[ "logdepthbuf_vertex" ],
+			"	#include <morphtarget_vertex>",
+			"	#include <skinning_vertex>",
+			"	#include <project_vertex>",
+			"	#include <fog_vertex>",
+			"	#include <logdepthbuf_vertex>",
 
 
 			"	vViewPosition = - mvPosition.xyz;",
 			"	vViewPosition = - mvPosition.xyz;",
 
 
-				THREE.ShaderChunk[ "worldpos_vertex" ],
-				THREE.ShaderChunk[ "shadowmap_vertex" ]
+			"	#include <worldpos_vertex>",
+			"	#include <shadowmap_vertex>"
 		);
 		);
 
 
 		code = output.join( "\n" );
 		code = output.join( "\n" );
@@ -98,71 +97,71 @@ THREE.PhongNode.prototype.build = function( builder ) {
 
 
 		// parse all nodes to reuse generate codes
 		// parse all nodes to reuse generate codes
 
 
-		this.color.parse( builder, { slot : 'color' } );
+		this.color.parse( builder, { slot: 'color' } );
 		this.specular.parse( builder );
 		this.specular.parse( builder );
 		this.shininess.parse( builder );
 		this.shininess.parse( builder );
 
 
 		if ( this.alpha ) this.alpha.parse( builder );
 		if ( this.alpha ) this.alpha.parse( builder );
-		
+
 		if ( this.normal ) this.normal.parse( builder );
 		if ( this.normal ) this.normal.parse( builder );
 		if ( this.normalScale && this.normal ) this.normalScale.parse( builder );
 		if ( this.normalScale && this.normal ) this.normalScale.parse( builder );
-		
-		if ( this.light ) this.light.parse( builder, { cache : 'light' } );
+
+		if ( this.light ) this.light.parse( builder, { cache: 'light' } );
 
 
 		if ( this.ao ) this.ao.parse( builder );
 		if ( this.ao ) this.ao.parse( builder );
 		if ( this.ambient ) this.ambient.parse( builder );
 		if ( this.ambient ) this.ambient.parse( builder );
 		if ( this.shadow ) this.shadow.parse( builder );
 		if ( this.shadow ) this.shadow.parse( builder );
-		if ( this.emissive ) this.emissive.parse( builder, { slot : 'emissive' } );
+		if ( this.emissive ) this.emissive.parse( builder, { slot: 'emissive' } );
 
 
-		if ( this.environment ) this.environment.parse( builder, { slot : 'environment' } );
+		if ( this.environment ) this.environment.parse( builder, { slot: 'environment' } );
 		if ( this.environmentAlpha && this.environment ) this.environmentAlpha.parse( builder );
 		if ( this.environmentAlpha && this.environment ) this.environmentAlpha.parse( builder );
 
 
 		// build code
 		// build code
 
 
-		var color = this.color.buildCode( builder, 'c', { slot : 'color' } );
+		var color = this.color.buildCode( builder, 'c', { slot: 'color' } );
 		var specular = this.specular.buildCode( builder, 'c' );
 		var specular = this.specular.buildCode( builder, 'c' );
 		var shininess = this.shininess.buildCode( builder, 'fv1' );
 		var shininess = this.shininess.buildCode( builder, 'fv1' );
 
 
 		var alpha = this.alpha ? this.alpha.buildCode( builder, 'fv1' ) : undefined;
 		var alpha = this.alpha ? this.alpha.buildCode( builder, 'fv1' ) : undefined;
-		
+
 		var normal = this.normal ? this.normal.buildCode( builder, 'v3' ) : undefined;
 		var normal = this.normal ? this.normal.buildCode( builder, 'v3' ) : undefined;
 		var normalScale = this.normalScale && this.normal ? this.normalScale.buildCode( builder, 'v2' ) : undefined;
 		var normalScale = this.normalScale && this.normal ? this.normalScale.buildCode( builder, 'v2' ) : undefined;
-		
-		var light = this.light ? this.light.buildCode( builder, 'v3', { cache : 'light' } ) : undefined;
+
+		var light = this.light ? this.light.buildCode( builder, 'v3', { cache: 'light' } ) : undefined;
 
 
 		var ao = this.ao ? this.ao.buildCode( builder, 'fv1' ) : undefined;
 		var ao = this.ao ? this.ao.buildCode( builder, 'fv1' ) : undefined;
 		var ambient = this.ambient ? this.ambient.buildCode( builder, 'c' ) : undefined;
 		var ambient = this.ambient ? this.ambient.buildCode( builder, 'c' ) : undefined;
 		var shadow = this.shadow ? this.shadow.buildCode( builder, 'c' ) : undefined;
 		var shadow = this.shadow ? this.shadow.buildCode( builder, 'c' ) : undefined;
-		var emissive = this.emissive ? this.emissive.buildCode( builder, 'c', { slot : 'emissive' } ) : undefined;
+		var emissive = this.emissive ? this.emissive.buildCode( builder, 'c', { slot: 'emissive' } ) : undefined;
 
 
-		var environment = this.environment ? this.environment.buildCode( builder, 'c', { slot : 'environment' } ) : undefined;
+		var environment = this.environment ? this.environment.buildCode( builder, 'c', { slot: 'environment' } ) : undefined;
 		var environmentAlpha = this.environmentAlpha && this.environment ? this.environmentAlpha.buildCode( builder, 'fv1' ) : undefined;
 		var environmentAlpha = this.environmentAlpha && this.environment ? this.environmentAlpha.buildCode( builder, 'fv1' ) : undefined;
 
 
 		material.requestAttribs.transparent = alpha != undefined;
 		material.requestAttribs.transparent = alpha != undefined;
 
 
 		material.addFragmentPars( [
 		material.addFragmentPars( [
-			THREE.ShaderChunk[ "common" ],
-			THREE.ShaderChunk[ "fog_pars_fragment" ],
-			THREE.ShaderChunk[ "bsdfs" ],
-			THREE.ShaderChunk[ "lights_pars" ],
-			THREE.ShaderChunk[ "lights_phong_pars_fragment" ],
-			THREE.ShaderChunk[ "shadowmap_pars_fragment" ],
-			THREE.ShaderChunk[ "logdepthbuf_pars_fragment" ]
+			"#include <common>",
+			"#include <fog_pars_fragment>",
+			"#include <bsdfs>",
+			"#include <lights_pars>",
+			"#include <lights_phong_pars_fragment>",
+			"#include <shadowmap_pars_fragment>",
+			"#include <logdepthbuf_pars_fragment>"
 		].join( "\n" ) );
 		].join( "\n" ) );
 
 
 		var output = [
 		var output = [
-				// prevent undeclared normal
-				THREE.ShaderChunk[ "normal_flip" ],
-				THREE.ShaderChunk[ "normal_fragment" ],
+			// prevent undeclared normal
+			"#include <normal_flip>",
+			"#include <normal_fragment>",
 
 
-				// prevent undeclared material
+			// prevent undeclared material
 			"	BlinnPhongMaterial material;",
 			"	BlinnPhongMaterial material;",
 
 
-				color.code,
+			color.code,
 			"	vec3 diffuseColor = " + color.result + ";",
 			"	vec3 diffuseColor = " + color.result + ";",
 			"	ReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );",
 			"	ReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );",
 
 
-				THREE.ShaderChunk[ "logdepthbuf_fragment" ],
+			"#include <logdepthbuf_fragment>",
 
 
 			specular.code,
 			specular.code,
 			"	vec3 specular = " + specular.result + ";",
 			"	vec3 specular = " + specular.result + ";",
@@ -209,7 +208,7 @@ THREE.PhongNode.prototype.build = function( builder ) {
 			'material.specularShininess = shininess;',
 			'material.specularShininess = shininess;',
 			'material.specularStrength = specularStrength;',
 			'material.specularStrength = specularStrength;',
 
 
-			THREE.ShaderChunk[ "lights_template" ]
+			"#include <lights_template>"
 		);
 		);
 
 
 		if ( light ) {
 		if ( light ) {
@@ -297,10 +296,10 @@ THREE.PhongNode.prototype.build = function( builder ) {
 		}
 		}
 
 
 		output.push(
 		output.push(
-			THREE.ShaderChunk[ "premultiplied_alpha_fragment" ],
-			THREE.ShaderChunk[ "tonemapping_fragment" ],
-			THREE.ShaderChunk[ "encodings_fragment" ],
-			THREE.ShaderChunk[ "fog_fragment" ]
+			"#include <premultiplied_alpha_fragment>",
+			"#include <tonemapping_fragment>",
+			"#include <encodings_fragment>",
+			"#include <fog_fragment>"
 		);
 		);
 
 
 		code = output.join( "\n" );
 		code = output.join( "\n" );

+ 139 - 0
examples/js/nodes/materials/SpriteNode.js

@@ -0,0 +1,139 @@
+/**
+ * @author sunag / http://www.sunag.com.br/
+ */
+
+THREE.SpriteNode = function () {
+
+	THREE.GLNode.call( this );
+
+	this.color = new THREE.ColorNode( 0xEEEEEE );
+	this.spherical = true;
+
+};
+
+THREE.SpriteNode.prototype = Object.create( THREE.GLNode.prototype );
+THREE.SpriteNode.prototype.constructor = THREE.SpriteNode;
+
+THREE.SpriteNode.prototype.build = function ( builder ) {
+
+	var material = builder.material;
+	var output, code;
+
+	material.define( 'SPRITE' );
+
+	material.requestAttribs.light = false;
+	material.requestAttribs.transparent = this.alpha != undefined;
+
+	if ( builder.isShader( 'vertex' ) ) {
+
+		var transform = this.transform ? this.transform.parseAndBuildCode( builder, 'v3', { cache: 'transform' } ) : undefined;
+
+		material.mergeUniform( THREE.UniformsUtils.merge( [
+			THREE.UniformsLib[ "fog" ]
+		] ) );
+
+		material.addVertexPars( [
+			"#include <fog_pars_vertex>"
+		].join( "\n" ) );
+
+		output = [
+			"#include <begin_vertex>"
+		];
+
+		if ( transform ) {
+
+			output.push(
+				transform.code,
+				"transformed = " + transform.result + ";"
+			);
+
+		}
+
+		output.push(
+			"#include <project_vertex>",
+			"#include <fog_vertex>",
+
+			'mat4 modelViewMtx = modelViewMatrix;',
+			'mat4 modelMtx = modelMatrix;',
+
+			// ignore position from modelMatrix (use vary position)
+			'modelMtx[3][0] = 0.0;',
+			'modelMtx[3][1] = 0.0;',
+			'modelMtx[3][2] = 0.0;'
+		);
+
+		if ( ! this.spherical ) {
+
+			output.push(
+				'modelMtx[1][1] = 1.0;'
+			);
+
+		}
+
+		output.push(
+			// http://www.geeks3d.com/20140807/billboarding-vertex-shader-glsl/
+			// First colunm.
+			'modelViewMtx[0][0] = 1.0;',
+			'modelViewMtx[0][1] = 0.0;',
+			'modelViewMtx[0][2] = 0.0;'
+		);
+
+		if ( this.spherical ) {
+
+			output.push(
+				// Second colunm.
+				'modelViewMtx[1][0] = 0.0;',
+				'modelViewMtx[1][1] = 1.0;',
+				'modelViewMtx[1][2] = 0.0;'
+			);
+
+		}
+
+		output.push(
+			// Thrid colunm.
+			'modelViewMtx[2][0] = 0.0;',
+			'modelViewMtx[2][1] = 0.0;',
+			'modelViewMtx[2][2] = 1.0;',
+
+			// apply
+			'gl_Position = projectionMatrix * modelViewMtx * modelMtx * vec4( transformed, 1.0 );'
+		);
+
+	} else {
+
+		material.addFragmentPars( [
+			"#include <fog_pars_fragment>",
+		].join( "\n" ) );
+
+		// parse all nodes to reuse generate codes
+
+		this.color.parse( builder, { slot: 'color' } );
+		if ( this.alpha ) this.alpha.parse( builder );
+
+		// build code
+
+		var color = this.color.buildCode( builder, 'c', { slot: 'color' } );
+		var alpha = this.alpha ? this.alpha.buildCode( builder, 'fv1' ) : undefined;
+
+		output = [ color.code ];
+
+		if ( alpha ) {
+
+			output.push(
+				alpha.code,
+				"gl_FragColor = vec4( " + color.result + ", " + alpha.result + " );"
+			);
+
+		} else {
+
+			output.push( "gl_FragColor = vec4( " + color.result + ", 1.0 );" );
+
+		}
+
+		output.push( "#include <fog_fragment>" );
+
+	}
+
+	return output.join( "\n" );
+
+};

+ 17 - 0
examples/js/nodes/materials/SpriteNodeMaterial.js

@@ -0,0 +1,17 @@
+/**
+ * @author sunag / http://www.sunag.com.br/
+ */
+
+THREE.SpriteNodeMaterial = function () {
+
+	this.node = new THREE.SpriteNode();
+
+	THREE.NodeMaterial.call( this, this.node, this.node );
+
+};
+
+THREE.SpriteNodeMaterial.prototype = Object.create( THREE.NodeMaterial.prototype );
+THREE.SpriteNodeMaterial.prototype.constructor = THREE.SpriteNodeMaterial;
+
+THREE.NodeMaterial.addShortcuts( THREE.SpriteNodeMaterial.prototype, 'node',
+[ 'color', 'alpha', 'transform', 'spherical' ] );

+ 82 - 78
examples/js/nodes/materials/StandardNode.js

@@ -2,7 +2,7 @@
  * @author sunag / http://www.sunag.com.br/
  * @author sunag / http://www.sunag.com.br/
  */
  */
 
 
-THREE.StandardNode = function() {
+THREE.StandardNode = function () {
 
 
 	THREE.GLNode.call( this );
 	THREE.GLNode.call( this );
 
 
@@ -15,14 +15,14 @@ THREE.StandardNode = function() {
 THREE.StandardNode.prototype = Object.create( THREE.GLNode.prototype );
 THREE.StandardNode.prototype = Object.create( THREE.GLNode.prototype );
 THREE.StandardNode.prototype.constructor = THREE.StandardNode;
 THREE.StandardNode.prototype.constructor = THREE.StandardNode;
 
 
-THREE.StandardNode.prototype.build = function( builder ) {
+THREE.StandardNode.prototype.build = function ( builder ) {
 
 
 	var material = builder.material;
 	var material = builder.material;
 	var code;
 	var code;
 
 
 	material.define( 'PHYSICAL' );
 	material.define( 'PHYSICAL' );
 
 
-	if ( !this.clearCoat && !this.clearCoatRoughness ) material.define( 'STANDARD' );
+	if ( ! this.clearCoat && ! this.clearCoatRoughness ) material.define( 'STANDARD' );
 
 
 	material.define( 'ALPHATEST', '0.0' );
 	material.define( 'ALPHATEST', '0.0' );
 
 
@@ -32,7 +32,7 @@ THREE.StandardNode.prototype.build = function( builder ) {
 
 
 	if ( builder.isShader( 'vertex' ) ) {
 	if ( builder.isShader( 'vertex' ) ) {
 
 
-		var transform = this.transform ? this.transform.parseAndBuildCode( builder, 'v3', { cache : 'transform' } ) : undefined;
+		var transform = this.transform ? this.transform.parseAndBuildCode( builder, 'v3', { cache: 'transform' } ) : undefined;
 
 
 		material.mergeUniform( THREE.UniformsUtils.merge( [
 		material.mergeUniform( THREE.UniformsUtils.merge( [
 
 
@@ -50,21 +50,24 @@ THREE.StandardNode.prototype.build = function( builder ) {
 
 
 			"#endif",
 			"#endif",
 
 
-			THREE.ShaderChunk[ "common" ],
-			THREE.ShaderChunk[ "fog_pars_vertex" ],
-			THREE.ShaderChunk[ "morphtarget_pars_vertex" ],
-			THREE.ShaderChunk[ "skinning_pars_vertex" ],
-			THREE.ShaderChunk[ "shadowmap_pars_vertex" ],
-			THREE.ShaderChunk[ "logdepthbuf_pars_vertex" ]
+			"#include <common>",
+			"#include <fog_pars_vertex>",
+			"#include <morphtarget_pars_vertex>",
+			"#include <skinning_pars_vertex>",
+			"#include <shadowmap_pars_vertex>",
+			"#include <logdepthbuf_pars_vertex>"
 
 
 		].join( "\n" ) );
 		].join( "\n" ) );
 
 
 		var output = [
 		var output = [
-			THREE.ShaderChunk[ "beginnormal_vertex" ],
-			THREE.ShaderChunk[ "morphnormal_vertex" ],
-			THREE.ShaderChunk[ "skinbase_vertex" ],
-			THREE.ShaderChunk[ "skinnormal_vertex" ],
-			THREE.ShaderChunk[ "defaultnormal_vertex" ],
+			"#include <beginnormal_vertex>",
+			"#include <morphnormal_vertex>",
+			"#include <skinbase_vertex>",
+			"#include <skinnormal_vertex>",
+			"#include <defaultnormal_vertex>",
+			"#include <logdepthbuf_pars_vertex>",
+			"#include <logdepthbuf_pars_vertex>",
+			"#include <logdepthbuf_pars_vertex>",
 
 
 			"#ifndef FLAT_SHADED", // Normal computed with derivatives when FLAT_SHADED
 			"#ifndef FLAT_SHADED", // Normal computed with derivatives when FLAT_SHADED
 
 
@@ -72,8 +75,7 @@ THREE.StandardNode.prototype.build = function( builder ) {
 
 
 			"#endif",
 			"#endif",
 
 
-			THREE.ShaderChunk[ "begin_vertex" ],
-			THREE.ShaderChunk[ "fog_vertex" ]        
+			"#include <begin_vertex>"
 		];
 		];
 
 
 		if ( transform ) {
 		if ( transform ) {
@@ -86,15 +88,16 @@ THREE.StandardNode.prototype.build = function( builder ) {
 		}
 		}
 
 
 		output.push(
 		output.push(
-			THREE.ShaderChunk[ "morphtarget_vertex" ],
-			THREE.ShaderChunk[ "skinning_vertex" ],
-			THREE.ShaderChunk[ "project_vertex" ],
-			THREE.ShaderChunk[ "logdepthbuf_vertex" ],
+			"#include <morphtarget_vertex>",
+			"#include <skinning_vertex>",
+			"#include <project_vertex>",
+			"#include <fog_vertex>",
+			"#include <logdepthbuf_vertex>",
 
 
 			"	vViewPosition = - mvPosition.xyz;",
 			"	vViewPosition = - mvPosition.xyz;",
 
 
-			THREE.ShaderChunk[ "worldpos_vertex" ],
-			THREE.ShaderChunk[ "shadowmap_vertex" ]
+			"#include <worldpos_vertex>",
+			"#include <shadowmap_vertex>"
 		);
 		);
 
 
 		code = output.join( "\n" );
 		code = output.join( "\n" );
@@ -104,64 +107,64 @@ THREE.StandardNode.prototype.build = function( builder ) {
 		// blur textures for PBR effect
 		// blur textures for PBR effect
 
 
 		var requires = {
 		var requires = {
-			bias : new THREE.RoughnessToBlinnExponentNode(),
-			offsetU : 0,
-			offsetV : 0
+			bias: new THREE.RoughnessToBlinnExponentNode(),
+			offsetU: 0,
+			offsetV: 0
 		};
 		};
 
 
-		var useClearCoat = !material.isDefined( 'STANDARD' );
-		
+		var useClearCoat = ! material.isDefined( 'STANDARD' );
+
 		// parse all nodes to reuse generate codes
 		// parse all nodes to reuse generate codes
 
 
-		this.color.parse( builder, { slot : 'color' } );
+		this.color.parse( builder, { slot: 'color' } );
 		this.roughness.parse( builder );
 		this.roughness.parse( builder );
 		this.metalness.parse( builder );
 		this.metalness.parse( builder );
 
 
 		if ( this.alpha ) this.alpha.parse( builder );
 		if ( this.alpha ) this.alpha.parse( builder );
-		
+
 		if ( this.normal ) this.normal.parse( builder );
 		if ( this.normal ) this.normal.parse( builder );
 		if ( this.normalScale && this.normal ) this.normalScale.parse( builder );
 		if ( this.normalScale && this.normal ) this.normalScale.parse( builder );
-		
-		if (this.clearCoat) this.clearCoat.parse( builder );
-		if (this.clearCoatRoughness) this.clearCoatRoughness.parse( builder );
-		
+
+		if ( this.clearCoat ) this.clearCoat.parse( builder );
+		if ( this.clearCoatRoughness ) this.clearCoatRoughness.parse( builder );
+
 		if ( this.reflectivity ) this.reflectivity.parse( builder );
 		if ( this.reflectivity ) this.reflectivity.parse( builder );
 
 
-		if ( this.light ) this.light.parse( builder, { cache : 'light' } );
+		if ( this.light ) this.light.parse( builder, { cache: 'light' } );
 
 
 		if ( this.ao ) this.ao.parse( builder );
 		if ( this.ao ) this.ao.parse( builder );
 		if ( this.ambient ) this.ambient.parse( builder );
 		if ( this.ambient ) this.ambient.parse( builder );
 		if ( this.shadow ) this.shadow.parse( builder );
 		if ( this.shadow ) this.shadow.parse( builder );
-		if ( this.emissive ) this.emissive.parse( builder, { slot : 'emissive' } );
+		if ( this.emissive ) this.emissive.parse( builder, { slot: 'emissive' } );
 
 
-		if ( this.environment ) this.environment.parse( builder, { cache : 'env', requires : requires, slot : 'environment' } ); // isolate environment from others inputs ( see TextureNode, CubeTextureNode )
+		if ( this.environment ) this.environment.parse( builder, { cache: 'env', requires: requires, slot: 'environment' } ); // isolate environment from others inputs ( see TextureNode, CubeTextureNode )
 
 
 		// build code
 		// build code
 
 
-		var color = this.color.buildCode( builder, 'c', { slot : 'color' } );
+		var color = this.color.buildCode( builder, 'c', { slot: 'color' } );
 		var roughness = this.roughness.buildCode( builder, 'fv1' );
 		var roughness = this.roughness.buildCode( builder, 'fv1' );
 		var metalness = this.metalness.buildCode( builder, 'fv1' );
 		var metalness = this.metalness.buildCode( builder, 'fv1' );
 
 
 		var alpha = this.alpha ? this.alpha.buildCode( builder, 'fv1' ) : undefined;
 		var alpha = this.alpha ? this.alpha.buildCode( builder, 'fv1' ) : undefined;
-		
+
 		var normal = this.normal ? this.normal.buildCode( builder, 'v3' ) : undefined;
 		var normal = this.normal ? this.normal.buildCode( builder, 'v3' ) : undefined;
 		var normalScale = this.normalScale && this.normal ? this.normalScale.buildCode( builder, 'v2' ) : undefined;
 		var normalScale = this.normalScale && this.normal ? this.normalScale.buildCode( builder, 'v2' ) : undefined;
-		
+
 		var clearCoat = this.clearCoat ? this.clearCoat.buildCode( builder, 'fv1' ) : undefined;
 		var clearCoat = this.clearCoat ? this.clearCoat.buildCode( builder, 'fv1' ) : undefined;
 		var clearCoatRoughness = this.clearCoatRoughness ? this.clearCoatRoughness.buildCode( builder, 'fv1' ) : undefined;
 		var clearCoatRoughness = this.clearCoatRoughness ? this.clearCoatRoughness.buildCode( builder, 'fv1' ) : undefined;
-		
+
 		var reflectivity = this.reflectivity ? this.reflectivity.buildCode( builder, 'fv1' ) : undefined;
 		var reflectivity = this.reflectivity ? this.reflectivity.buildCode( builder, 'fv1' ) : undefined;
 
 
-		var light = this.light ? this.light.buildCode( builder, 'v3', { cache : 'light' } ) : undefined;
+		var light = this.light ? this.light.buildCode( builder, 'v3', { cache: 'light' } ) : undefined;
 
 
 		var ao = this.ao ? this.ao.buildCode( builder, 'fv1' ) : undefined;
 		var ao = this.ao ? this.ao.buildCode( builder, 'fv1' ) : undefined;
 		var ambient = this.ambient ? this.ambient.buildCode( builder, 'c' ) : undefined;
 		var ambient = this.ambient ? this.ambient.buildCode( builder, 'c' ) : undefined;
 		var shadow = this.shadow ? this.shadow.buildCode( builder, 'c' ) : undefined;
 		var shadow = this.shadow ? this.shadow.buildCode( builder, 'c' ) : undefined;
-		var emissive = this.emissive ? this.emissive.buildCode( builder, 'c', { slot : 'emissive' } ) : undefined;
+		var emissive = this.emissive ? this.emissive.buildCode( builder, 'c', { slot: 'emissive' } ) : undefined;
 
 
-		var environment = this.environment ? this.environment.buildCode( builder, 'c', { cache : 'env', requires : requires, slot : 'environment' } ) : undefined;
+		var environment = this.environment ? this.environment.buildCode( builder, 'c', { cache: 'env', requires: requires, slot: 'environment' } ) : undefined;
 
 
-		var clearCoatEnv = useClearCoat && environment ? this.environment.buildCode( builder, 'c', { cache : 'clearCoat', requires : requires, slot : 'environment' } ) : undefined;
+		var clearCoatEnv = useClearCoat && environment ? this.environment.buildCode( builder, 'c', { cache: 'clearCoat', requires: requires, slot: 'environment' } ) : undefined;
 
 
 		material.requestAttribs.transparent = alpha != undefined;
 		material.requestAttribs.transparent = alpha != undefined;
 
 
@@ -175,29 +178,30 @@ THREE.StandardNode.prototype.build = function( builder ) {
 
 
 			"#endif",
 			"#endif",
 
 
-			THREE.ShaderChunk[ "common" ],
-			THREE.ShaderChunk[ "fog_pars_fragment" ],
-			THREE.ShaderChunk[ "bsdfs" ],
-			THREE.ShaderChunk[ "lights_pars" ],
-			THREE.ShaderChunk[ "lights_physical_pars_fragment" ],
-			THREE.ShaderChunk[ "shadowmap_pars_fragment" ],
-			THREE.ShaderChunk[ "logdepthbuf_pars_fragment" ]
+			"#include <common>",
+			"#include <fog_pars_fragment>",
+			"#include <bsdfs>",
+			"#include <lights_pars>",
+			"#include <lights_physical_pars_fragment>",
+			"#include <shadowmap_pars_fragment>",
+			"#include <logdepthbuf_pars_fragment>",
+			"#include <logdepthbuf_vertex>"
 		].join( "\n" ) );
 		].join( "\n" ) );
 
 
 		var output = [
 		var output = [
 				// prevent undeclared normal
 				// prevent undeclared normal
-				THREE.ShaderChunk[ "normal_flip" ],
-				THREE.ShaderChunk[ "normal_fragment" ],
+			"	#include <normal_flip>",
+			"	#include <normal_fragment>",
 
 
 				// prevent undeclared material
 				// prevent undeclared material
 			"	PhysicalMaterial material;",
 			"	PhysicalMaterial material;",
 			"	material.diffuseColor = vec3( 1.0 );",
 			"	material.diffuseColor = vec3( 1.0 );",
 
 
-				color.code,
+			color.code,
 			"	vec3 diffuseColor = " + color.result + ";",
 			"	vec3 diffuseColor = " + color.result + ";",
 			"	ReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );",
 			"	ReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );",
 
 
-				THREE.ShaderChunk[ "logdepthbuf_fragment" ],
+			"#include <logdepthbuf_fragment>",
 
 
 			roughness.code,
 			roughness.code,
 			"	float roughnessFactor = " + roughness.result + ";",
 			"	float roughnessFactor = " + roughness.result + ";",
@@ -240,33 +244,33 @@ THREE.StandardNode.prototype.build = function( builder ) {
 			// accumulation
 			// accumulation
 			'material.specularRoughness = clamp( roughnessFactor, DEFAULT_SPECULAR_COEFFICIENT, 1.0 );' // disney's remapping of [ 0, 1 ] roughness to [ 0.001, 1 ]
 			'material.specularRoughness = clamp( roughnessFactor, DEFAULT_SPECULAR_COEFFICIENT, 1.0 );' // disney's remapping of [ 0, 1 ] roughness to [ 0.001, 1 ]
 		);
 		);
-		
-		if (clearCoat) {
-			
+
+		if ( clearCoat ) {
+
 			output.push(
 			output.push(
 				clearCoat.code,
 				clearCoat.code,
 				'material.clearCoat = saturate( ' + clearCoat.result + ' );'
 				'material.clearCoat = saturate( ' + clearCoat.result + ' );'
 			);
 			);
-			
-		} else if (useClearCoat) {
-			
+
+		} else if ( useClearCoat ) {
+
 			output.push( 'material.clearCoat = 0.0;' );
 			output.push( 'material.clearCoat = 0.0;' );
-			
+
 		}
 		}
-		
-		if (clearCoatRoughness) {
-			
+
+		if ( clearCoatRoughness ) {
+
 			output.push(
 			output.push(
 				clearCoatRoughness.code,
 				clearCoatRoughness.code,
 				'material.clearCoatRoughness = clamp( ' + clearCoatRoughness.result + ', DEFAULT_SPECULAR_COEFFICIENT, 1.0 );'
 				'material.clearCoatRoughness = clamp( ' + clearCoatRoughness.result + ', DEFAULT_SPECULAR_COEFFICIENT, 1.0 );'
 			);
 			);
-			
-		} else if (useClearCoat) {
-			
+
+		} else if ( useClearCoat ) {
+
 			output.push( 'material.clearCoatRoughness = 0.0;' );
 			output.push( 'material.clearCoatRoughness = 0.0;' );
-			
+
 		}
 		}
-		
+
 		if ( reflectivity ) {
 		if ( reflectivity ) {
 
 
 			output.push(
 			output.push(
@@ -283,7 +287,7 @@ THREE.StandardNode.prototype.build = function( builder ) {
 		}
 		}
 
 
 		output.push(
 		output.push(
-			THREE.ShaderChunk[ "lights_template" ]
+			"#include <lights_template>"
 		);
 		);
 
 
 		if ( light ) {
 		if ( light ) {
@@ -347,7 +351,7 @@ THREE.StandardNode.prototype.build = function( builder ) {
 
 
 			output.push( environment.code );
 			output.push( environment.code );
 
 
-			if (clearCoatEnv) {
+			if ( clearCoatEnv ) {
 
 
 				output.push(
 				output.push(
 					clearCoatEnv.code,
 					clearCoatEnv.code,
@@ -356,7 +360,7 @@ THREE.StandardNode.prototype.build = function( builder ) {
 
 
 			} else {
 			} else {
 
 
-				output.push("vec3 clearCoatRadiance = vec3( 0.0 );");
+				output.push( "vec3 clearCoatRadiance = vec3( 0.0 );" );
 
 
 			}
 			}
 
 
@@ -377,10 +381,10 @@ THREE.StandardNode.prototype.build = function( builder ) {
 		}
 		}
 
 
 		output.push(
 		output.push(
-			THREE.ShaderChunk[ "premultiplied_alpha_fragment" ],
-			THREE.ShaderChunk[ "tonemapping_fragment" ],
-			THREE.ShaderChunk[ "encodings_fragment" ],
-			THREE.ShaderChunk[ "fog_fragment" ]
+			"#include <premultiplied_alpha_fragment>",
+			"#include <tonemapping_fragment>",
+			"#include <encodings_fragment>",
+			"#include <fog_fragment>"
 		);
 		);
 
 
 		code = output.join( "\n" );
 		code = output.join( "\n" );

+ 4 - 3
examples/js/nodes/utils/ResolutionNode.js

@@ -17,9 +17,10 @@ THREE.ResolutionNode.prototype.constructor = THREE.ResolutionNode;
 
 
 THREE.ResolutionNode.prototype.updateFrame = function( delta ) {
 THREE.ResolutionNode.prototype.updateFrame = function( delta ) {
 
 
-	var size = this.renderer.getSize();
+	var size = this.renderer.getSize(),
+		pixelRatio = this.renderer.getPixelRatio();
 
 
-	this.x = size.width;
-	this.y = size.height;
+	this.x = size.width * pixelRatio;
+	this.y = size.height * pixelRatio;
 
 
 };
 };

+ 48 - 0
examples/js/nodes/utils/UVTransformNode.js

@@ -0,0 +1,48 @@
+/**
+ * @author sunag / http://www.sunag.com.br/
+ */
+
+THREE.UVTransformNode = function () {
+
+	THREE.FunctionNode.call( this, "( uvTransform * vec4( uvNode, 0, 1 ) ).xy", "vec2" );
+
+	this.uv = new THREE.UVNode();
+	this.transform = new THREE.Matrix4Node();
+
+};
+
+THREE.UVTransformNode.prototype = Object.create( THREE.FunctionNode.prototype );
+THREE.UVTransformNode.prototype.constructor = THREE.UVTransformNode;
+
+THREE.UVTransformNode.prototype.generate = function ( builder, output ) {
+
+	this.keywords[ "uvNode" ] = this.uv;
+	this.keywords[ "uvTransform" ] = this.transform;
+
+	return THREE.FunctionNode.prototype.generate.call( this, builder, output );
+
+};
+
+THREE.UVTransformNode.prototype.compose = function () {
+
+	var defaultPivot = new THREE.Vector2( .5, .5 ),
+		tempVector = new THREE.Vector3(),
+		tempMatrix = new THREE.Matrix4();
+
+	return function compose( translate, rotate, scale, optionalCenter ) {
+
+		optionalCenter = optionalCenter !== undefined ? optionalCenter : defaultPivot;
+
+		var matrix = this.transform.value;
+
+		matrix.identity()
+			.setPosition( tempVector.set( - optionalCenter.x, - optionalCenter.y, 0 ) )
+			.premultiply( tempMatrix.makeRotationZ( rotate ) )
+			.multiply( tempMatrix.makeScale( scale.x, scale.y, 0 ) )
+			.multiply( tempMatrix.makeTranslation( translate.x, translate.y, 0 ) );
+
+		return this;
+
+	};
+
+}();

+ 52 - 52
examples/js/renderers/WebGLDeferredRenderer.js

@@ -1708,21 +1708,21 @@ THREE.ShaderDeferred = {
 			"varying vec3 vNormal;",
 			"varying vec3 vNormal;",
 			"varying vec4 vPosition;",
 			"varying vec4 vPosition;",
 
 
-			THREE.ShaderChunk[ "morphtarget_pars_vertex" ],
-			THREE.ShaderChunk[ "skinning_pars_vertex" ],
+			"#include <morphtarget_pars_vertex>",
+			"#include <skinning_pars_vertex>",
 
 
 			"void main() {",
 			"void main() {",
 
 
-			THREE.ShaderChunk[ "begin_vertex" ],
-			THREE.ShaderChunk[ "beginnormal_vertex" ],
-			THREE.ShaderChunk[ "skinbase_vertex" ],
-			THREE.ShaderChunk[ "skinnormal_vertex" ],
-			THREE.ShaderChunk[ "defaultnormal_vertex" ],
-			THREE.ShaderChunk[ "morphtarget_vertex" ],
-			THREE.ShaderChunk[ "skinning_vertex" ],
-			THREE.ShaderChunk[ "project_vertex" ],
+			"#include <begin_vertex>",
+			"#include <beginnormal_vertex>",
+			"#include <skinbase_vertex>",
+			"#include <skinnormal_vertex>",
+			"#include <defaultnormal_vertex>",
+			"#include <morphtarget_vertex>",
+			"#include <skinning_vertex>",
+			"#include <project_vertex>",
 
 
-			"	vNormal = normalize( normalMatrix * objectNormal );",
+			"	vNormal = normalize( transformedNormal );",
 			"	vPosition = gl_Position;",
 			"	vPosition = gl_Position;",
 
 
 			"}"
 			"}"
@@ -1765,21 +1765,21 @@ THREE.ShaderDeferred = {
 
 
 		vertexShader: [
 		vertexShader: [
 
 
-			THREE.ShaderChunk[ "uv_pars_vertex" ],
-			THREE.ShaderChunk[ "morphtarget_pars_vertex" ],
-			THREE.ShaderChunk[ "skinning_pars_vertex" ],
+			"#include <uv_pars_vertex>",
+			"#include <morphtarget_pars_vertex>",
+			"#include <skinning_pars_vertex>",
 
 
 			"void main() {",
 			"void main() {",
 
 
-			THREE.ShaderChunk[ "uv_vertex" ],
-			THREE.ShaderChunk[ "begin_vertex" ],
-			THREE.ShaderChunk[ "beginnormal_vertex" ],
-			THREE.ShaderChunk[ "skinbase_vertex" ],
-			THREE.ShaderChunk[ "skinnormal_vertex" ],
-			THREE.ShaderChunk[ "defaultnormal_vertex" ],
-			THREE.ShaderChunk[ "morphtarget_vertex" ],
-			THREE.ShaderChunk[ "skinning_vertex" ],
-			THREE.ShaderChunk[ "project_vertex" ],
+			"#include <uv_vertex>",
+			"#include <begin_vertex>",
+			"#include <beginnormal_vertex>",
+			"#include <skinbase_vertex>",
+			"#include <skinnormal_vertex>",
+			"#include <defaultnormal_vertex>",
+			"#include <morphtarget_vertex>",
+			"#include <skinning_vertex>",
+			"#include <project_vertex>",
 
 
 			"}"
 			"}"
 
 
@@ -1792,8 +1792,8 @@ THREE.ShaderDeferred = {
 			"uniform vec3 specular;",
 			"uniform vec3 specular;",
 			"uniform float shininess;",
 			"uniform float shininess;",
 
 
-			THREE.ShaderChunk[ "uv_pars_fragment" ],
-			THREE.ShaderChunk[ "map_pars_fragment" ],
+			"#include <uv_pars_fragment>",
+			"#include <map_pars_fragment>",
 			THREE.DeferredShaderChunk[ "packVector3" ],
 			THREE.DeferredShaderChunk[ "packVector3" ],
 
 
 			"void main() {",
 			"void main() {",
@@ -1802,7 +1802,7 @@ THREE.ShaderDeferred = {
 			"	vec3 emissiveColor = emissive;",
 			"	vec3 emissiveColor = emissive;",
 			"	vec3 specularColor = specular;",
 			"	vec3 specularColor = specular;",
 
 
-			THREE.ShaderChunk[ "map_fragment" ],
+			"#include <map_fragment>",
 			THREE.DeferredShaderChunk[ "packColor" ],
 			THREE.DeferredShaderChunk[ "packColor" ],
 
 
 			"	gl_FragColor = packedColor;",
 			"	gl_FragColor = packedColor;",
@@ -2117,21 +2117,21 @@ THREE.ShaderDeferred = {
 			"varying vec3 vNormal;",
 			"varying vec3 vNormal;",
 			"varying vec4 vPosition;",
 			"varying vec4 vPosition;",
 
 
-			THREE.ShaderChunk[ "morphtarget_pars_vertex" ],
-			THREE.ShaderChunk[ "skinning_pars_vertex" ],
+			"#include <morphtarget_pars_vertex>",
+			"#include <skinning_pars_vertex>",
 
 
 			"void main() {",
 			"void main() {",
 
 
-			THREE.ShaderChunk[ "begin_vertex" ],
-			THREE.ShaderChunk[ "beginnormal_vertex" ],
-			THREE.ShaderChunk[ "skinbase_vertex" ],
-			THREE.ShaderChunk[ "skinnormal_vertex" ],
-			THREE.ShaderChunk[ "defaultnormal_vertex" ],
-			THREE.ShaderChunk[ "morphtarget_vertex" ],
-			THREE.ShaderChunk[ "skinning_vertex" ],
-			THREE.ShaderChunk[ "project_vertex" ],
+			"#include <begin_vertex>",
+			"#include <beginnormal_vertex>",
+			"#include <skinbase_vertex>",
+			"#include <skinnormal_vertex>",
+			"#include <defaultnormal_vertex>",
+			"#include <morphtarget_vertex>",
+			"#include <skinning_vertex>",
+			"#include <project_vertex>",
 
 
-			"	vNormal = normalize( normalMatrix * objectNormal );",
+			"	vNormal = normalize( transformedNormal );",
 			"	vPosition = gl_Position;",
 			"	vPosition = gl_Position;",
 
 
 			"}"
 			"}"
@@ -2420,21 +2420,21 @@ THREE.ShaderDeferred = {
 
 
 		vertexShader: [
 		vertexShader: [
 
 
-			THREE.ShaderChunk[ "uv_pars_vertex" ],
-			THREE.ShaderChunk[ "morphtarget_pars_vertex" ],
-			THREE.ShaderChunk[ "skinning_pars_vertex" ],
+			"#include <uv_pars_vertex>",
+			"#include <morphtarget_pars_vertex>",
+			"#include <skinning_pars_vertex>",
 
 
 			"void main() {",
 			"void main() {",
 
 
-			THREE.ShaderChunk[ "uv_vertex" ],
-			THREE.ShaderChunk[ "begin_vertex" ],
-			THREE.ShaderChunk[ "beginnormal_vertex" ],
-			THREE.ShaderChunk[ "skinbase_vertex" ],
-			THREE.ShaderChunk[ "skinnormal_vertex" ],
-			THREE.ShaderChunk[ "defaultnormal_vertex" ],
-			THREE.ShaderChunk[ "morphtarget_vertex" ],
-			THREE.ShaderChunk[ "skinning_vertex" ],
-			THREE.ShaderChunk[ "project_vertex" ],
+			"#include <uv_vertex>",
+			"#include <begin_vertex>",
+			"#include <beginnormal_vertex>",
+			"#include <skinbase_vertex>",
+			"#include <skinnormal_vertex>",
+			"#include <defaultnormal_vertex>",
+			"#include <morphtarget_vertex>",
+			"#include <skinning_vertex>",
+			"#include <project_vertex>",
 
 
 			"}"
 			"}"
 
 
@@ -2452,8 +2452,8 @@ THREE.ShaderDeferred = {
 			"uniform float viewHeight;",
 			"uniform float viewHeight;",
 			"uniform float viewWidth;",
 			"uniform float viewWidth;",
 
 
-			THREE.ShaderChunk[ "uv_pars_fragment" ],
-			THREE.ShaderChunk[ "map_pars_fragment" ],
+			"#include <uv_pars_fragment>",
+			"#include <map_pars_fragment>",
 
 
 			THREE.DeferredShaderChunk[ "unpackFloat" ],
 			THREE.DeferredShaderChunk[ "unpackFloat" ],
 
 
@@ -2467,7 +2467,7 @@ THREE.ShaderDeferred = {
 
 
 			"	vec4 light = texture2D( samplerLight, texCoord );",
 			"	vec4 light = texture2D( samplerLight, texCoord );",
 
 
-			THREE.ShaderChunk[ "map_fragment" ],
+			"#include <map_fragment>",
 
 
 			"	vec3 diffuseFinal = diffuseColor.rgb * light.rgb;",
 			"	vec3 diffuseFinal = diffuseColor.rgb * light.rgb;",
 			"	vec3 emissiveFinal = emissiveColor;",
 			"	vec3 emissiveFinal = emissiveColor;",

+ 0 - 153
examples/js/vr/WebVRCamera.js

@@ -1,153 +0,0 @@
-/**
- * @author mrdoob / http://mrdoob.com/
- */
-
-THREE.WebVRCamera = function ( display, renderer ) {
-
-	var scope = this;
-
-	var frameData = null;
-
-	if ( 'VRFrameData' in window ) {
-
-		frameData = new window.VRFrameData();
-
-	}
-
-	var cameraL = new THREE.PerspectiveCamera();
-	cameraL.bounds = new THREE.Vector4( 0.0, 0.0, 0.5, 1.0 );
-	cameraL.layers.enable( 1 );
-
-	var cameraR = new THREE.PerspectiveCamera();
-	cameraR.bounds = new THREE.Vector4( 0.5, 0.0, 0.5, 1.0 );
-	cameraR.layers.enable( 2 );
-
-	var matrixWorldInverse = new THREE.Matrix4();
-
-	//
-
-	var currentSize, currentPixelRatio;
-
-	function onVRDisplayPresentChange() {
-
-		if ( display.isPresenting ) {
-
-			var eyeParameters = display.getEyeParameters( 'left' );
-			var renderWidth = eyeParameters.renderWidth;
-			var renderHeight = eyeParameters.renderHeight;
-
-			currentPixelRatio = renderer.getPixelRatio();
-			currentSize = renderer.getSize();
-
-			renderer.setPixelRatio( 1 );
-			renderer.setSize( renderWidth * 2, renderHeight, false );
-
-			scope.enabled = true;
-
-		} else if ( scope.enabled ) {
-
-			scope.enabled = false;
-
-			renderer.setPixelRatio( currentPixelRatio );
-			renderer.setSize( currentSize.width, currentSize.height, true );
-
-		}
-
-	}
-
-	window.addEventListener( 'vrdisplaypresentchange', onVRDisplayPresentChange, false );
-
-	//
-
-	THREE.ArrayCamera.call( this, [ cameraL, cameraR ] );
-
-	//
-
-	this.onBeforeRender = function () {
-
-		display.depthNear = scope.near;
-		display.depthFar = scope.far;
-
-		display.getFrameData( frameData );
-
-		//
-
-		var pose = frameData.pose;
-
-		if ( pose.orientation !== null ) {
-
-			scope.quaternion.fromArray( pose.orientation );
-
-		}
-
-		if ( pose.position !== null ) {
-
-			scope.position.fromArray( pose.position );
-
-		} else {
-
-			scope.position.set( 0, 0, 0 );
-
-		}
-
-		//
-
-		cameraL.matrixWorldInverse.fromArray( frameData.leftViewMatrix );
-		cameraR.matrixWorldInverse.fromArray( frameData.rightViewMatrix );
-
-		if ( scope.parent !== null ) {
-
-			matrixWorldInverse.getInverse( scope.parent.matrixWorld );
-
-			cameraL.matrixWorldInverse.multiply( matrixWorldInverse );
-			cameraR.matrixWorldInverse.multiply( matrixWorldInverse );
-
-		}
-
-		cameraL.projectionMatrix.fromArray( frameData.leftProjectionMatrix );
-		cameraR.projectionMatrix.fromArray( frameData.rightProjectionMatrix );
-
-		// HACK @mrdoob
-		// https://github.com/w3c/webvr/issues/203
-
-		scope.projectionMatrix.copy( cameraL.projectionMatrix );
-
-		//
-
-		var layers = display.getLayers();
-
-		if ( layers.length ) {
-
-			var layer = layers[ 0 ];
-
-			if ( layer.leftBounds !== null && layer.leftBounds.length === 4 ) {
-
-				cameraL.bounds.fromArray( layer.leftBounds );
-
-			}
-
-			if ( layer.rightBounds !== null && layer.rightBounds.length === 4 ) {
-
-				cameraR.bounds.fromArray( layer.rightBounds );
-
-			}
-
-		}
-
-	};
-
-	this.onAfterRender = function () {
-
-		if ( display.isPresenting ) display.submitFrame();
-
-	};
-
-};
-
-THREE.WebVRCamera.prototype = Object.assign( Object.create( THREE.ArrayCamera.prototype ), {
-
-	constructor: THREE.WebVRCamera,
-
-	isWebVRCamera: true
-
-} );

二进制
examples/models/prwm/faceted-nefertiti.be.prwm


二进制
examples/models/prwm/faceted-nefertiti.le.prwm


二进制
examples/models/prwm/smooth-suzanne.be.prwm


二进制
examples/models/prwm/smooth-suzanne.le.prwm


二进制
examples/models/prwm/vive-controller.be.prwm


二进制
examples/models/prwm/vive-controller.le.prwm


二进制
examples/textures/WalkingManSpriteSheet.png


+ 1 - 0
examples/webgl_clipping.html

@@ -106,6 +106,7 @@
 
 
 				renderer = new THREE.WebGLRenderer();
 				renderer = new THREE.WebGLRenderer();
 				renderer.shadowMap.enabled = true;
 				renderer.shadowMap.enabled = true;
+				renderer.shadowMap.renderSingleSided = false;
 				renderer.setPixelRatio( window.devicePixelRatio );
 				renderer.setPixelRatio( window.devicePixelRatio );
 				renderer.setSize( window.innerWidth, window.innerHeight );
 				renderer.setSize( window.innerWidth, window.innerHeight );
 				window.addEventListener( 'resize', onWindowResize, false );
 				window.addEventListener( 'resize', onWindowResize, false );

+ 1 - 1
examples/webgl_gpgpu_water.html

@@ -182,9 +182,9 @@
 				vec3 transformed = vec3( position.x, position.y, heightValue );
 				vec3 transformed = vec3( position.x, position.y, heightValue );
 				//<begin_vertex>
 				//<begin_vertex>
 
 
-				#include <displacementmap_vertex>
 				#include <morphtarget_vertex>
 				#include <morphtarget_vertex>
 				#include <skinning_vertex>
 				#include <skinning_vertex>
+				#include <displacementmap_vertex>
 				#include <project_vertex>
 				#include <project_vertex>
 				#include <logdepthbuf_vertex>
 				#include <logdepthbuf_vertex>
 				#include <clipping_planes_vertex>
 				#include <clipping_planes_vertex>

+ 7 - 2
examples/webgl_loader_imagebitmap.html

@@ -84,7 +84,7 @@
 
 
 				new THREE.ImageBitmapLoader()
 				new THREE.ImageBitmapLoader()
 					.setOptions( { imageOrientation: 'none' } )
 					.setOptions( { imageOrientation: 'none' } )
-					.load( 'textures/planets/earth_atmos_2048.jpg', function( imageBitmap ) {
+					.load( 'textures/planets/earth_atmos_2048.jpg?' + performance.now(), function( imageBitmap ) {
 
 
 						var tex = new THREE.CanvasTexture( imageBitmap );
 						var tex = new THREE.CanvasTexture( imageBitmap );
 
 
@@ -106,6 +106,7 @@
 			function addImage () {
 			function addImage () {
 
 
 				new THREE.ImageLoader()
 				new THREE.ImageLoader()
+					.setCrossOrigin( '*' )
 					.load( 'textures/planets/earth_atmos_2048.jpg?' + performance.now(), function( image ) {
 					.load( 'textures/planets/earth_atmos_2048.jpg?' + performance.now(), function( image ) {
 							var tex = new THREE.CanvasTexture( image );
 							var tex = new THREE.CanvasTexture( image );
 							addCube( tex );
 							addCube( tex );
@@ -169,9 +170,13 @@
 				var clearBtn = document.getElementById( 'clear_btn' );
 				var clearBtn = document.getElementById( 'clear_btn' );
 				clearBtn.addEventListener( 'click', function( e ) {
 				clearBtn.addEventListener( 'click', function( e ) {
 					while( cubes.children.length ) {
 					while( cubes.children.length ) {
-						cubes.remove( cubes.children[ 0 ] );
+						var cube = cubes.children[ 0 ]
+						cubes.remove( cube );
+						cube.geometry.dispose();
+						cube.material.map.dispose();
 					}
 					}
 				})
 				})
+
 				// RENDERER
 				// RENDERER
 
 
 				renderer = new THREE.WebGLRenderer( { antialias: true } );
 				renderer = new THREE.WebGLRenderer( { antialias: true } );

+ 250 - 0
examples/webgl_loader_prwm.html

@@ -0,0 +1,250 @@
+<!DOCTYPE html>
+<html lang="en">
+	<head>
+		<title>three.js webgl - loaders - PRWM loader</title>
+		<meta charset="utf-8">
+		<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
+		<style>
+			html, body {
+				padding:0;
+				margin:0;
+				background:#000000;
+			}
+
+			.models {
+				position:absolute;
+				top:10px;
+				left:12px;
+				z-index:2;
+				font-family: "Arial", "Helvetica Neue", "Helvetica", sans-serif;
+				font-size:13px;
+			}
+
+			.notes {
+				position:absolute;
+				left:12px;
+				bottom:10px;
+				z-index:2;
+				font-family: "Arial", "Helvetica Neue", "Helvetica", sans-serif;
+				font-size:13px;
+				text-align:left;
+				color:#FFFFFF;
+				max-width:300px;
+			}
+
+			.notes a, .notes a:visited {
+				color:#FFFFFF;
+			}
+
+			.models strong {
+				color:#FFFFFF;
+				text-transform: uppercase;
+			}
+
+			.models a, .models a:visited {
+				color:#FFFFFF;
+				margin-left:12px;
+				text-decoration: none;
+			}
+
+			.models a:hover, .models a:focus {
+				text-decoration: underline;
+			}
+		</style>
+	</head>
+
+	<body>
+
+
+		<div class="models">
+			<strong>Models</strong>
+			<a class="model" href="models/prwm/faceted-nefertiti.*.prwm">Faceted Nefertiti</a>
+			<a class="model" href="models/prwm/smooth-suzanne.*.prwm">Smooth Suzanne</a>
+			<a class="model" href="models/prwm/vive-controller.*.prwm">Vive Controller</a>
+		</div>
+		<div class="notes">
+			The parsing of PRWM file is especially fast when the endianness of the file is the same as the endianness
+			of the client platform. The loader will automatically replace the <strong>*</strong> in the model url
+			by either <strong>le</strong> or <strong>be</strong> depending on the client platform's endianness to
+			download the most appropriate file.<br><br>
+			This platform endianness is <strong id="endianness"></strong>.<br><br>
+			See your console for stats.<br><br>
+			<a href="https://github.com/kchapelier/PRWM" target="_blank">Specifications and implementations</a>
+		</div>
+
+		<script src="../build/three.js"></script>
+		<script src="js/loaders/PRWMLoader.js"></script>
+
+		<script>
+
+			var container;
+
+			var camera, scene, renderer;
+
+			var mouseX = 0, mouseY = 0;
+
+			var windowHalfX = window.innerWidth / 2;
+			var windowHalfY = window.innerHeight / 2;
+
+
+			init();
+			animate();
+
+
+			function init() {
+
+				document.getElementById( 'endianness' ).innerHTML = THREE.PRWMLoader.isBigEndianPlatform() ? 'big-endian' : 'little-endian';
+				container = document.createElement( 'div' );
+				document.body.appendChild( container );
+
+				camera = new THREE.PerspectiveCamera( 45, window.innerWidth / window.innerHeight, 1, 2000 );
+				camera.position.z = 250;
+
+				// scene
+
+				scene = new THREE.Scene();
+
+				var ambient = new THREE.AmbientLight( 0x101030 );
+				scene.add( ambient );
+
+				var directionalLight = new THREE.DirectionalLight( 0xffeedd );
+				directionalLight.position.set( 0, 0, 1 );
+				scene.add( directionalLight );
+
+				// model
+
+				var loader = new THREE.PRWMLoader();
+				var material = new THREE.MeshPhongMaterial( {} );
+				var busy = false;
+				var mesh = null;
+
+				var onProgress = function ( xhr ) {
+
+					if ( xhr.lengthComputable ) {
+
+						var percentComplete = xhr.loaded / xhr.total * 100;
+						console.log( Math.round( percentComplete, 2 ) + '% downloaded' );
+
+						if ( xhr.loaded === xhr.total ) {
+
+							console.log( 'File size: ' + ( xhr.total / 1024 ).toFixed( 2 ) + 'kB' );
+							console.timeEnd( 'Download' );
+
+						}
+
+					}
+
+				};
+
+				var onError = function ( xhr ) {
+
+					busy = false;
+
+				};
+
+				function loadGeometry( url ) {
+
+					if ( busy ) return;
+
+					busy = true;
+
+					if ( mesh !== null ) {
+
+						scene.remove( mesh );
+						mesh.geometry.dispose();
+
+					}
+
+					console.log( '-- Loading', url );
+					console.time( 'Download' );
+
+					loader.load( url, function ( geometry ) {
+
+						mesh = new THREE.Mesh( geometry, material );
+						mesh.scale.set( 50, 50, 50 );
+						scene.add( mesh );
+
+						console.log( geometry.index ? 'indexed geometry' : 'non-indexed geometry' );
+						console.log( '# of vertices: ' + geometry.attributes.position.count );
+						console.log( '# of polygons: ' + ( geometry.index ? geometry.index.count / 3 : geometry.attributes.position.count / 3 ) );
+						busy = false;
+
+					}, onProgress, onError );
+
+				}
+
+				//
+
+				renderer = new THREE.WebGLRenderer( { antialias: true } );
+				renderer.setPixelRatio( 1 );
+				renderer.setSize( window.innerWidth, window.innerHeight );
+				container.appendChild( renderer.domElement );
+
+				document.addEventListener( 'mousemove', onDocumentMouseMove, false );
+
+				//
+
+				document.querySelectorAll( 'a.model' ).forEach( function ( anchor ) {
+
+					anchor.addEventListener( 'click', function ( e ) {
+
+						e.preventDefault();
+
+						loadGeometry( anchor.href );
+
+					} );
+
+				} );
+
+				//
+
+				// * is automatically replaced by 'le' or 'be' depending on the client platform's endianness
+				loadGeometry( './models/prwm/smooth-suzanne.*.prwm' );
+
+				window.addEventListener( 'resize', onWindowResize, false );
+
+			}
+
+			function onWindowResize() {
+
+				windowHalfX = window.innerWidth / 2;
+				windowHalfY = window.innerHeight / 2;
+
+				camera.aspect = window.innerWidth / window.innerHeight;
+				camera.updateProjectionMatrix();
+
+				renderer.setSize( window.innerWidth, window.innerHeight );
+
+			}
+
+			function onDocumentMouseMove( event ) {
+
+				mouseX = ( event.clientX - windowHalfX ) / 2;
+				mouseY = ( event.clientY - windowHalfY ) / 2;
+
+			}
+
+			//
+
+			function animate() {
+
+				requestAnimationFrame( animate );
+				render();
+
+			}
+
+			function render() {
+
+				camera.position.x += ( mouseX - camera.position.x ) * .05;
+				camera.position.y += ( - mouseY - camera.position.y ) * .05;
+
+				camera.lookAt( scene.position );
+
+				renderer.render( scene, camera );
+
+			}
+
+		</script>
+
+	</body>
+</html>

文件差异内容过多而无法显示
+ 249 - 181
examples/webgl_materials_nodes.html


+ 12 - 2
examples/webgl_mirror.html

@@ -88,11 +88,21 @@
 
 
 				// MIRROR planes
 				// MIRROR planes
 
 
-				var groundMirror = new THREE.Mirror( 100, 100, { clipBias: 0.003, textureWidth: WIDTH, textureHeight: HEIGHT, color: 0x777777 } );
+				var groundMirror = new THREE.Mirror( 100, 100, {
+					clipBias: 0.003,
+					textureWidth: WIDTH * window.devicePixelRatio,
+					textureHeight: HEIGHT * window.devicePixelRatio,
+					color: 0x777777
+				} );
 				groundMirror.rotateX( - Math.PI / 2 );
 				groundMirror.rotateX( - Math.PI / 2 );
 				scene.add( groundMirror );
 				scene.add( groundMirror );
 
 
-				var verticalMirror = new THREE.Mirror( 60, 60, { clipBias: 0.003, textureWidth: WIDTH, textureHeight: HEIGHT, color:0x889999 } );
+				var verticalMirror = new THREE.Mirror( 60, 60, {
+					clipBias: 0.003,
+					textureWidth: WIDTH * window.devicePixelRatio,
+					textureHeight: HEIGHT * window.devicePixelRatio,
+					color: 0x889999
+				} );
 				verticalMirror.position.y = 35;
 				verticalMirror.position.y = 35;
 				verticalMirror.position.z = -45;
 				verticalMirror.position.z = -45;
 				scene.add( verticalMirror );
 				scene.add( verticalMirror );

+ 6 - 6
examples/webgl_panorama_equirectangular.html

@@ -141,11 +141,11 @@
 
 
 				isUserInteracting = true;
 				isUserInteracting = true;
 
 
-				onPointerDownPointerX = event.clientX;
-				onPointerDownPointerY = event.clientY;
+				onMouseDownMouseX = event.clientX;
+				onMouseDownMouseY = event.clientY;
 
 
-				onPointerDownLon = lon;
-				onPointerDownLat = lat;
+				onMouseDownLon = lon;
+				onMouseDownLat = lat;
 
 
 			}
 			}
 
 
@@ -153,8 +153,8 @@
 
 
 				if ( isUserInteracting === true ) {
 				if ( isUserInteracting === true ) {
 
 
-					lon = ( onPointerDownPointerX - event.clientX ) * 0.1 + onPointerDownLon;
-					lat = ( event.clientY - onPointerDownPointerY ) * 0.1 + onPointerDownLat;
+					lon = ( onMouseDownMouseX - event.clientX ) * 0.1 + onMouseDownLon;
+					lat = ( event.clientY - onMouseDownMouseY ) * 0.1 + onMouseDownLat;
 
 
 				}
 				}
 
 

+ 2 - 20
examples/webgl_postprocessing_outline.html

@@ -1,5 +1,4 @@
 <!DOCTYPE html>
 <!DOCTYPE html>
-
 <html lang="en">
 <html lang="en">
 	<head>
 	<head>
 		<title>three.js webgl - post processing - Outline Pass</title>
 		<title>three.js webgl - post processing - Outline Pass</title>
@@ -311,25 +310,6 @@
 
 
 				window.addEventListener( 'resize', onWindowResize, false );
 				window.addEventListener( 'resize', onWindowResize, false );
 
 
-				var moved = false;
-
-				controls.addEventListener( 'change', function() {
-
-					moved = true;
-
-				} );
-
-				window.addEventListener( 'mousedown', function () {
-
-					moved = false;
-
-				}, false );
-
-				window.addEventListener( 'mouseup', function() {
-					if(!moved)
-						checkIntersection();
-				} );
-
 				window.addEventListener( 'mousemove', onTouchMove );
 				window.addEventListener( 'mousemove', onTouchMove );
 				window.addEventListener( 'touchmove', onTouchMove );
 				window.addEventListener( 'touchmove', onTouchMove );
 
 
@@ -352,6 +332,8 @@
 					mouse.x = ( x / window.innerWidth ) * 2 - 1;
 					mouse.x = ( x / window.innerWidth ) * 2 - 1;
 					mouse.y = - ( y / window.innerHeight ) * 2 + 1;
 					mouse.y = - ( y / window.innerHeight ) * 2 + 1;
 
 
+					checkIntersection();
+
 				}
 				}
 
 
 				function addSelectedObject(object) {
 				function addSelectedObject(object) {

+ 74 - 5
examples/webgl_shadowmap_pointlight.html

@@ -51,7 +51,7 @@
 				scene = new THREE.Scene();
 				scene = new THREE.Scene();
 				scene.add( new THREE.AmbientLight( 0x222233 ) );
 				scene.add( new THREE.AmbientLight( 0x222233 ) );
 
 
-				// Lights
+				// lights
 
 
 				function createLight( color ) {
 				function createLight( color ) {
 
 
@@ -59,7 +59,6 @@
 					pointLight.castShadow = true;
 					pointLight.castShadow = true;
 					pointLight.shadow.camera.near = 1;
 					pointLight.shadow.camera.near = 1;
 					pointLight.shadow.camera.far = 30;
 					pointLight.shadow.camera.far = 30;
-					// pointLight.shadowCameraVisible = true;
 					pointLight.shadow.bias = 0.01;
 					pointLight.shadow.bias = 0.01;
 
 
 					var geometry = new THREE.SphereGeometry( 0.3, 12, 6 );
 					var geometry = new THREE.SphereGeometry( 0.3, 12, 6 );
@@ -67,7 +66,7 @@
 					var sphere = new THREE.Mesh( geometry, material );
 					var sphere = new THREE.Mesh( geometry, material );
 					pointLight.add( sphere );
 					pointLight.add( sphere );
 
 
-					return pointLight
+					return pointLight;
 
 
 				}
 				}
 
 
@@ -77,25 +76,62 @@
 				pointLight2 = createLight( 0xff0000 );
 				pointLight2 = createLight( 0xff0000 );
 				scene.add( pointLight2 );
 				scene.add( pointLight2 );
 
 
+				//
+
 				var geometry = new THREE.TorusKnotGeometry( 14, 1, 150, 20 );
 				var geometry = new THREE.TorusKnotGeometry( 14, 1, 150, 20 );
+
+				var texture = new THREE.CanvasTexture( generateTexture() );
+				texture.wrapS = texture.wrapT = THREE.RepeatWrapping;
+				texture.repeat.set( 32, 1 );
+
 				var material = new THREE.MeshPhongMaterial( {
 				var material = new THREE.MeshPhongMaterial( {
 					color: 0xff0000,
 					color: 0xff0000,
 					shininess: 100,
 					shininess: 100,
-					specular: 0x222222
+					specular: 0x222222,
+					alphaMap: texture, // alphaMap uses the g channel
+					alphaTest: 0.5,
+					transparent: true,
+					side: THREE.DoubleSide
 				} );
 				} );
+
 				torusKnot = new THREE.Mesh( geometry, material );
 				torusKnot = new THREE.Mesh( geometry, material );
 				torusKnot.position.set( 0, 5, 0 );
 				torusKnot.position.set( 0, 5, 0 );
 				torusKnot.castShadow = true;
 				torusKnot.castShadow = true;
-				torusKnot.receiveShadow = true;
 				scene.add( torusKnot );
 				scene.add( torusKnot );
 
 
+				// custom distance material
+
+				var shader = THREE.ShaderLib[ "distanceRGBA" ];
+
+				var uniforms = THREE.UniformsUtils.clone( shader.uniforms );
+				uniforms.alphaMap.value = material.alphaMap;
+				uniforms.offsetRepeat.value.set( texture.offset.x, texture.offset.y, texture.repeat.x, texture.repeat.y );
+
+				var distanceMaterial = new THREE.ShaderMaterial( {
+					defines: {
+						'USE_SHADOWMAP': '',
+						'USE_ALPHAMAP': '',
+						'ALPHATEST': material.alphaTest
+					},
+					uniforms: uniforms,
+					vertexShader: shader.vertexShader,
+					fragmentShader: shader.fragmentShader,
+					side: THREE.DoubleSide
+				} );
+
+				torusKnot.customDistanceMaterial = distanceMaterial;
+
+				//
+
 				var geometry = new THREE.BoxGeometry( 30, 30, 30 );
 				var geometry = new THREE.BoxGeometry( 30, 30, 30 );
+
 				var material = new THREE.MeshPhongMaterial( {
 				var material = new THREE.MeshPhongMaterial( {
 					color: 0xa0adaf,
 					color: 0xa0adaf,
 					shininess: 10,
 					shininess: 10,
 					specular: 0x111111,
 					specular: 0x111111,
 					side: THREE.BackSide
 					side: THREE.BackSide
 				} );
 				} );
+
 				var mesh = new THREE.Mesh( geometry, material );
 				var mesh = new THREE.Mesh( geometry, material );
 				mesh.position.y = 10;
 				mesh.position.y = 10;
 				mesh.receiveShadow = true;
 				mesh.receiveShadow = true;
@@ -108,6 +144,7 @@
 				renderer.setSize( window.innerWidth, window.innerHeight );
 				renderer.setSize( window.innerWidth, window.innerHeight );
 				renderer.shadowMap.enabled = true;
 				renderer.shadowMap.enabled = true;
 				renderer.shadowMap.type = THREE.BasicShadowMap;
 				renderer.shadowMap.type = THREE.BasicShadowMap;
+				renderer.shadowMap.renderSingleSided = false; // must be set to false to honor double-sided materials
 				document.body.appendChild( renderer.domElement );
 				document.body.appendChild( renderer.domElement );
 
 
 				var controls = new THREE.OrbitControls( camera, renderer.domElement );
 				var controls = new THREE.OrbitControls( camera, renderer.domElement );
@@ -132,6 +169,38 @@
 
 
 			}
 			}
 
 
+			function generateTexture() {
+
+				var canvas = document.createElement( 'canvas' );
+				canvas.width = 256;
+				canvas.height = 256;
+
+				var context = canvas.getContext( '2d' );
+				var image = context.getImageData( 0, 0, 256, 256 );
+
+				var x = 0, y = 0, cvalue;
+
+				for ( var i = 0, j = 0, l = image.data.length; i < l; i += 4, j ++ ) {
+
+					x = j % 256;				// pixel col
+					y = ( x == 0 ) ? y + 1 : y;	// pixel row
+
+					// diagonal stripes
+					cvalue = Math.floor( ( x + y ) / 32 ) % 2;
+
+					image.data[ i + 0 ] = 255 * cvalue;
+					image.data[ i + 1 ] = 255 * cvalue;
+					image.data[ i + 2 ] = 255 * cvalue;
+					image.data[ i + 3 ] = 255;
+
+				}
+
+				context.putImageData( image, 0, 0 );
+
+				return canvas;
+
+			}
+
 			function animate() {
 			function animate() {
 
 
 				requestAnimationFrame( animate );
 				requestAnimationFrame( animate );

+ 281 - 0
examples/webgl_sprites_nodes.html

@@ -0,0 +1,281 @@
+<!DOCTYPE html>
+<html lang="en">
+	<head>
+		<title>three.js webgl - sprites nodes</title>
+		<meta charset="utf-8">
+		<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
+		<style>
+			body {
+				color: #fff;
+				font-family:Monospace;
+				font-size:13px;
+				margin: 0px;
+				text-align:center;
+				overflow: hidden;
+			}
+
+			#info {
+				color: #fff;
+				position: absolute;
+				top: 10px;
+				width: 100%;
+				text-align: center;
+				display:block;
+			}
+
+			a { color: white }
+		</style>
+	</head>
+	<body>
+
+		<div id="container"></div>
+		<div id="info">
+			<a href="http://threejs.org" target="_blank" rel="noopener">three.js</a> - Node-Based Sprites
+		</div>
+
+		<script src="../build/three.js"></script>
+
+		<script src='js/geometries/TeapotBufferGeometry.js'></script>
+		<script src="js/controls/OrbitControls.js"></script>
+		<script src="js/libs/dat.gui.min.js"></script>
+
+		<!-- NodeLibrary -->
+		<script src="js/nodes/GLNode.js"></script>
+		<script src="js/nodes/RawNode.js"></script>
+		<script src="js/nodes/TempNode.js"></script>
+		<script src="js/nodes/InputNode.js"></script>
+		<script src="js/nodes/ConstNode.js"></script>
+		<script src="js/nodes/VarNode.js"></script>
+		<script src="js/nodes/FunctionNode.js"></script>
+		<script src="js/nodes/FunctionCallNode.js"></script>
+		<script src="js/nodes/AttributeNode.js"></script>
+		<script src="js/nodes/NodeBuilder.js"></script>
+		<script src="js/nodes/NodeLib.js"></script>
+		<script src="js/nodes/NodeMaterial.js"></script>
+
+		<!-- Accessors -->
+		<script src="js/nodes/accessors/PositionNode.js"></script>
+		<script src="js/nodes/accessors/NormalNode.js"></script>
+		<script src="js/nodes/accessors/UVNode.js"></script>
+		<script src="js/nodes/accessors/ScreenUVNode.js"></script>
+		<script src="js/nodes/accessors/ColorsNode.js"></script>
+		<script src="js/nodes/accessors/CameraNode.js"></script>
+		<script src="js/nodes/accessors/ReflectNode.js"></script>
+		<script src="js/nodes/accessors/LightNode.js"></script>
+
+		<!-- Inputs -->
+		<script src="js/nodes/inputs/IntNode.js"></script>
+		<script src="js/nodes/inputs/FloatNode.js"></script>
+		<script src="js/nodes/inputs/ColorNode.js"></script>
+		<script src="js/nodes/inputs/Vector2Node.js"></script>
+		<script src="js/nodes/inputs/Vector3Node.js"></script>
+		<script src="js/nodes/inputs/Vector4Node.js"></script>
+		<script src="js/nodes/inputs/TextureNode.js"></script>
+		<script src="js/nodes/inputs/Matrix4Node.js"></script>
+		<script src="js/nodes/inputs/CubeTextureNode.js"></script>
+
+		<!-- Math -->
+		<script src="js/nodes/math/Math1Node.js"></script>
+		<script src="js/nodes/math/Math2Node.js"></script>
+		<script src="js/nodes/math/Math3Node.js"></script>
+		<script src="js/nodes/math/OperatorNode.js"></script>
+
+		<!-- Utils -->
+		<script src="js/nodes/utils/SwitchNode.js"></script>
+		<script src="js/nodes/utils/JoinNode.js"></script>
+		<script src="js/nodes/utils/TimerNode.js"></script>
+		<script src="js/nodes/utils/RoughnessToBlinnExponentNode.js"></script>
+		<script src="js/nodes/utils/VelocityNode.js"></script>
+		<script src="js/nodes/utils/LuminanceNode.js"></script>
+		<script src="js/nodes/utils/ColorAdjustmentNode.js"></script>
+		<script src="js/nodes/utils/NoiseNode.js"></script>
+		<script src="js/nodes/utils/ResolutionNode.js"></script>
+		<script src="js/nodes/utils/BumpNode.js"></script>
+		<script src="js/nodes/utils/BlurNode.js"></script>
+		<script src="js/nodes/utils/UVTransformNode.js"></script>
+
+		<!-- Sprite Material -->
+		<script src="js/nodes/materials/SpriteNode.js"></script>
+		<script src="js/nodes/materials/SpriteNodeMaterial.js"></script>
+		
+		<script>
+
+		var container = document.getElementById( 'container' );
+
+		var renderer, scene, camera, clock = new THREE.Clock(), fov = 50;
+		var plane, sprite1, sprite2, sprite3;
+		var controls;
+
+		window.addEventListener( 'load', init );
+
+		function init() {
+
+			//
+			// Renderer / Controls
+			//
+
+			renderer = new THREE.WebGLRenderer( { antialias: true } );
+			renderer.setPixelRatio( window.devicePixelRatio );
+			renderer.setSize( window.innerWidth, window.innerHeight );
+			container.appendChild( renderer.domElement );
+
+			scene = new THREE.Scene();
+			scene.fog = new THREE.Fog( 0x0000FF, 70, 150 );
+
+			camera = new THREE.PerspectiveCamera( fov, window.innerWidth / window.innerHeight, 1, 1000 );
+			camera.position.z = 100;
+			camera.target = new THREE.Vector3();
+
+			controls = new THREE.OrbitControls( camera, renderer.domElement );
+			controls.minDistance = 50;
+			controls.maxDistance = 200;
+
+			//
+			// SpriteNode
+			//
+
+			// use scale to adjuste the real sprite size
+			plane = new THREE.PlaneBufferGeometry( 1, 1 );
+
+			// https://openclipart.org/detail/239883/walking-man-sprite-sheet
+			var walkingManTexture = new THREE.TextureLoader().load( "textures/WalkingManSpriteSheet.png" );
+			walkingManTexture.wrapS = walkingManTexture.wrapT = THREE.RepeatWrapping;
+
+			// horizontal sprite-sheet animator
+
+			function createHorizontalSpriteSheetNode( hCount, speed ) {
+
+				var speed = new THREE.Vector2Node( speed, 0 ); // frame per second
+				var scale = new THREE.Vector2Node( 1 / hCount, 1 ); // 8 horizontal images in sprite-sheet
+
+				var uvTimer = new THREE.OperatorNode(
+					new THREE.TimerNode(),
+					speed,
+					THREE.OperatorNode.MUL
+				);
+
+				var uvIntegerTimer = new THREE.Math1Node(
+					uvTimer,
+					THREE.Math1Node.FLOOR
+				);
+
+				var uvFrameOffset = new THREE.OperatorNode(
+					uvIntegerTimer,
+					scale,
+					THREE.OperatorNode.MUL
+				);
+
+				var uvScale = new THREE.OperatorNode(
+					new THREE.UVNode(),
+					scale,
+					THREE.OperatorNode.MUL
+				);
+
+				var uvFrame = new THREE.OperatorNode(
+					uvScale,
+					uvFrameOffset,
+					THREE.OperatorNode.ADD
+				);
+
+				return uvFrame;
+
+			}
+
+			// sprites
+
+			var spriteWidth = 20,
+				spriteHeight = 20;
+
+			scene.add( sprite1 = new THREE.Mesh( plane, new THREE.SpriteNodeMaterial() ) );
+			sprite1.scale.x = spriteWidth;
+			sprite1.scale.y = spriteHeight;
+			sprite1.material.color = new THREE.TextureNode( walkingManTexture );
+			sprite1.material.color.coord = createHorizontalSpriteSheetNode( 8, 10 );
+			sprite1.material.build();
+
+			scene.add( sprite2 = new THREE.Mesh( plane, new THREE.SpriteNodeMaterial() ) );
+			sprite2.position.x = 30;
+			sprite2.scale.x = spriteWidth;
+			sprite2.scale.y = spriteHeight;
+			sprite2.material.color = new THREE.TextureNode( walkingManTexture );
+			sprite2.material.color.coord = createHorizontalSpriteSheetNode( 8, 30 );
+			sprite2.material.color = new THREE.Math1Node( sprite2.material.color, THREE.Math1Node.INVERT );
+			sprite2.material.spherical = false; // look at camera horizontally only, very used to vegetation
+			// horizontal zigzag sprite
+			sprite2.material.transform = new THREE.OperatorNode(
+				new THREE.OperatorNode( 
+					new THREE.Math1Node( new THREE.TimerNode( 0, 3 ), THREE.Math1Node.SIN ), // 3 is speed (time scale)
+					new THREE.Vector2Node( .3, 0 ), // horizontal scale (position)
+					THREE.OperatorNode.MUL
+				),
+				new THREE.PositionNode(),
+				THREE.OperatorNode.ADD
+			);
+			sprite2.material.build();
+
+			var sineWaveFunction = new THREE.FunctionNode( [
+				// https://stackoverflow.com/questions/36174431/how-to-make-a-wave-warp-effect-in-shader
+				"vec2 sineWave(vec2 uv, vec2 phase) {",
+				// wave distortion
+				"	float x = sin( 25.0*uv.y + 30.0*uv.x + 6.28*phase.x) * 0.01;",
+				"	float y = sin( 25.0*uv.y + 30.0*uv.x + 6.28*phase.y) * 0.03;",
+				"	return vec2(uv.x+x, uv.y+y);",
+				"}"
+			].join( "\n" ) );
+
+			scene.add( sprite3 = new THREE.Mesh( plane, new THREE.SpriteNodeMaterial() ) );
+			sprite3.position.x = - 30;
+			sprite3.scale.x = spriteWidth;
+			sprite3.scale.y = spriteHeight;
+			sprite3.material.fog = true;
+			sprite3.material.color = new THREE.TextureNode( walkingManTexture );
+			sprite3.material.color.coord = new THREE.FunctionCallNode( sineWaveFunction, {
+				"uv": createHorizontalSpriteSheetNode( 8, 0 ),
+				"phase": new THREE.TimerNode()
+			} );
+			sprite3.material.build();
+
+			//
+			// Events
+			//
+
+			window.addEventListener( 'resize', onWindowResize, false );
+
+			onWindowResize();
+			animate();
+
+		}
+
+		function onWindowResize() {
+
+			var width = window.innerWidth, height = window.innerHeight;
+
+			camera.aspect = width / height;
+			camera.updateProjectionMatrix();
+
+			renderer.setSize( width, height );
+
+		}
+
+		function animate() {
+
+			var delta = clock.getDelta();
+
+			// update material animation and/or gpu calcs (pre-renderer)
+			sprite1.material.updateFrame( delta );
+			sprite2.material.updateFrame( delta );
+			sprite3.material.updateFrame( delta );
+
+			// rotate sprite
+			sprite3.rotation.z -= Math.PI * .005;
+
+			renderer.render( scene, camera );
+
+			requestAnimationFrame( animate );
+
+		}
+
+		</script>
+
+	</body>
+</html>

+ 8 - 12
examples/webvr_cubes.html

@@ -4,8 +4,8 @@
 		<title>three.js webvr - cubes</title>
 		<title>three.js webvr - cubes</title>
 		<meta charset="utf-8">
 		<meta charset="utf-8">
 		<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
 		<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
-		<!-- Origin Trial Token, feature = WebVR, origin = https://threejs.org, expires = 2017-06-13 -->
-		<meta http-equiv="origin-trial" data-feature="WebVR" data-expires="2017-06-13" content="ApAQvHfiHMQB7SmRhfvCUX61adJaTA6pAu0Ry439jjeipa5lGm1RcTQynFoHGGcaSJkWfMOv7qK6pwSUb95ClQgAAABKeyJvcmlnaW4iOiJodHRwczovL3RocmVlanMub3JnOjQ0MyIsImZlYXR1cmUiOiJXZWJWUiIsImV4cGlyeSI6MTQ5NzMxMjAwMH0=">
+		<!-- Origin Trial Token, feature = WebVR (For Chrome M59+), origin = https://threejs.org, expires = 2017-07-28 -->
+		<meta http-equiv="origin-trial" data-feature="WebVR (For Chrome M59+)" data-expires="2017-07-28" content="Ave6CPNUgSwHb3vCbyd55P/R7pfkwNniUJsYfSoUqI+l1X1BIOt6HfriVP0g2hmaG7Pp3qaUXuXdZeqGBmoMKg8AAABNeyJvcmlnaW4iOiJodHRwczovL3RocmVlanMub3JnOjQ0MyIsImZlYXR1cmUiOiJXZWJWUjEuMSIsImV4cGlyeSI6MTUwMTI2NzQwNX0=">
 		<style>
 		<style>
 			body {
 			body {
 				font-family: Monospace;
 				font-family: Monospace;
@@ -23,8 +23,6 @@
 
 
 		<script src="../build/three.js"></script>
 		<script src="../build/three.js"></script>
 
 
-		<script src="js/controls/VRControls.js"></script>
-		<script src="js/effects/VREffect.js"></script>
 		<script src="js/vr/WebVR.js"></script>
 		<script src="js/vr/WebVR.js"></script>
 
 
 		<script>
 		<script>
@@ -41,7 +39,6 @@
 
 
 			var container;
 			var container;
 			var camera, scene, raycaster, renderer;
 			var camera, scene, raycaster, renderer;
-			var effect, controls;
 
 
 			var room;
 			var room;
 			var isMouseDown = false;
 			var isMouseDown = false;
@@ -129,11 +126,12 @@
 				renderer.sortObjects = false;
 				renderer.sortObjects = false;
 				container.appendChild( renderer.domElement );
 				container.appendChild( renderer.domElement );
 
 
-				controls = new THREE.VRControls( camera );
-				effect = new THREE.VREffect( renderer );
+				renderer.vr.enabled = true;
 
 
 				WEBVR.getVRDisplay( function ( display ) {
 				WEBVR.getVRDisplay( function ( display ) {
 
 
+					renderer.vr.setDevice( display );
+
 					document.body.appendChild( WEBVR.getButton( display, renderer.domElement ) );
 					document.body.appendChild( WEBVR.getButton( display, renderer.domElement ) );
 
 
 				} );
 				} );
@@ -166,7 +164,7 @@
 				camera.aspect = window.innerWidth / window.innerHeight;
 				camera.aspect = window.innerWidth / window.innerHeight;
 				camera.updateProjectionMatrix();
 				camera.updateProjectionMatrix();
 
 
-				effect.setSize( window.innerWidth, window.innerHeight );
+				renderer.setSize( window.innerWidth, window.innerHeight );
 
 
 			}
 			}
 
 
@@ -174,8 +172,7 @@
 
 
 			function animate() {
 			function animate() {
 
 
-				effect.requestAnimationFrame( animate );
-				render();
+				renderer.animate( render );
 
 
 			}
 			}
 
 
@@ -261,8 +258,7 @@
 
 
 				}
 				}
 
 
-				controls.update();
-				effect.render( scene, camera );
+				renderer.render( scene, camera );
 
 
 			}
 			}
 
 

+ 11 - 17
examples/webvr_daydream.html

@@ -4,8 +4,8 @@
 		<title>three.js webvr - daydream</title>
 		<title>three.js webvr - daydream</title>
 		<meta charset="utf-8">
 		<meta charset="utf-8">
 		<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
 		<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
-		<!-- Origin Trial Token, feature = WebVR, origin = https://threejs.org, expires = 2017-06-13 -->
-		<meta http-equiv="origin-trial" data-feature="WebVR" data-expires="2017-06-13" content="ApAQvHfiHMQB7SmRhfvCUX61adJaTA6pAu0Ry439jjeipa5lGm1RcTQynFoHGGcaSJkWfMOv7qK6pwSUb95ClQgAAABKeyJvcmlnaW4iOiJodHRwczovL3RocmVlanMub3JnOjQ0MyIsImZlYXR1cmUiOiJXZWJWUiIsImV4cGlyeSI6MTQ5NzMxMjAwMH0=">
+		<!-- Origin Trial Token, feature = WebVR (For Chrome M59+), origin = https://threejs.org, expires = 2017-07-28 -->
+		<meta http-equiv="origin-trial" data-feature="WebVR (For Chrome M59+)" data-expires="2017-07-28" content="Ave6CPNUgSwHb3vCbyd55P/R7pfkwNniUJsYfSoUqI+l1X1BIOt6HfriVP0g2hmaG7Pp3qaUXuXdZeqGBmoMKg8AAABNeyJvcmlnaW4iOiJodHRwczovL3RocmVlanMub3JnOjQ0MyIsImZlYXR1cmUiOiJXZWJWUjEuMSIsImV4cGlyeSI6MTUwMTI2NzQwNX0=">
 		<style>
 		<style>
 			body {
 			body {
 				font-family: Monospace;
 				font-family: Monospace;
@@ -25,7 +25,6 @@
 
 
 		<script src="js/vr/DaydreamController.js"></script>
 		<script src="js/vr/DaydreamController.js"></script>
 		<script src="js/vr/WebVR.js"></script>
 		<script src="js/vr/WebVR.js"></script>
-		<script src="js/vr/WebVRCamera.js"></script>
 
 
 		<script>
 		<script>
 
 
@@ -41,7 +40,7 @@
 
 
 			var container;
 			var container;
 			var camera, scene, ray, raycaster, renderer;
 			var camera, scene, ray, raycaster, renderer;
-			var gamepad, vrdisplay;
+			var gamepad;
 
 
 			var room;
 			var room;
 
 
@@ -119,18 +118,14 @@
 				renderer.sortObjects = false;
 				renderer.sortObjects = false;
 				container.appendChild( renderer.domElement );
 				container.appendChild( renderer.domElement );
 
 
-				//
-
-				WEBVR.getVRDisplay( function ( display ) {
-
-					if ( display !== undefined ) {
+				renderer.vr.enabled = true;
 
 
-						vrdisplay = display;
-						camera = new THREE.WebVRCamera( display, renderer );
+				//
 
 
-					}
+				WEBVR.getVRDisplay( function ( device ) {
 
 
-					document.body.appendChild( WEBVR.getButton( display, renderer.domElement ) );
+					renderer.vr.setDevice( device );
+					document.body.appendChild( WEBVR.getButton( device, renderer.domElement ) );
 
 
 				} );
 				} );
 
 
@@ -171,15 +166,14 @@
 
 
 			function animate() {
 			function animate() {
 
 
-				gamepad.update();
-				render();
-
-				( vrdisplay ? vrdisplay : window ).requestAnimationFrame( animate );
+				renderer.animate( render );
 
 
 			}
 			}
 
 
 			function render() {
 			function render() {
 
 
+				gamepad.update();
+
 				var delta = clock.getDelta() * 60;
 				var delta = clock.getDelta() * 60;
 
 
 				// find intersections
 				// find intersections

+ 16 - 15
examples/webvr_panorama.html

@@ -4,8 +4,8 @@
 		<title>three.js webvr - panorama</title>
 		<title>three.js webvr - panorama</title>
 		<meta charset="utf-8">
 		<meta charset="utf-8">
 		<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
 		<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
-		<!-- Origin Trial Token, feature = WebVR, origin = https://threejs.org, expires = 2017-06-13 -->
-		<meta http-equiv="origin-trial" data-feature="WebVR" data-expires="2017-06-13" content="ApAQvHfiHMQB7SmRhfvCUX61adJaTA6pAu0Ry439jjeipa5lGm1RcTQynFoHGGcaSJkWfMOv7qK6pwSUb95ClQgAAABKeyJvcmlnaW4iOiJodHRwczovL3RocmVlanMub3JnOjQ0MyIsImZlYXR1cmUiOiJXZWJWUiIsImV4cGlyeSI6MTQ5NzMxMjAwMH0=">
+		<!-- Origin Trial Token, feature = WebVR (For Chrome M59+), origin = https://threejs.org, expires = 2017-07-28 -->
+		<meta http-equiv="origin-trial" data-feature="WebVR (For Chrome M59+)" data-expires="2017-07-28" content="Ave6CPNUgSwHb3vCbyd55P/R7pfkwNniUJsYfSoUqI+l1X1BIOt6HfriVP0g2hmaG7Pp3qaUXuXdZeqGBmoMKg8AAABNeyJvcmlnaW4iOiJodHRwczovL3RocmVlanMub3JnOjQ0MyIsImZlYXR1cmUiOiJXZWJWUjEuMSIsImV4cGlyeSI6MTUwMTI2NzQwNX0=">
 		<style>
 		<style>
 			html, body {
 			html, body {
 				background-color: #000;
 				background-color: #000;
@@ -19,8 +19,6 @@
 	<body>
 	<body>
 		<script src="../build/three.js"></script>
 		<script src="../build/three.js"></script>
 
 
-		<script src="js/controls/VRControls.js"></script>
-		<script src="js/effects/VREffect.js"></script>
 		<script src="js/vr/WebVR.js"></script>
 		<script src="js/vr/WebVR.js"></script>
 
 
 		<script>
 		<script>
@@ -34,7 +32,6 @@
 		//
 		//
 
 
 		var camera;
 		var camera;
-		var effect, controls;
 		var renderer;
 		var renderer;
 		var scene;
 		var scene;
 
 
@@ -48,20 +45,22 @@
 			renderer.setSize( window.innerWidth, window.innerHeight );
 			renderer.setSize( window.innerWidth, window.innerHeight );
 			document.body.appendChild( renderer.domElement );
 			document.body.appendChild( renderer.domElement );
 
 
+			renderer.vr.enabled = true;
+
 			scene = new THREE.Scene();
 			scene = new THREE.Scene();
 
 
-			camera = new THREE.PerspectiveCamera( 90, window.innerWidth / window.innerHeight, 0.1, 100 );
+			camera = new THREE.PerspectiveCamera( 90, window.innerWidth / window.innerHeight, 1, 1000 );
 			camera.layers.enable( 1 );
 			camera.layers.enable( 1 );
 
 
-			controls = new THREE.VRControls( camera );
-			effect = new THREE.VREffect( renderer );
-
 			WEBVR.getVRDisplay( function ( display ) {
 			WEBVR.getVRDisplay( function ( display ) {
 
 
+				renderer.vr.setDevice( display );
+
 				document.body.appendChild( WEBVR.getButton( display, renderer.domElement ) );
 				document.body.appendChild( WEBVR.getButton( display, renderer.domElement ) );
 
 
 			} );
 			} );
 
 
+			var geometry = new THREE.CubeGeometry( 100, 100, 100 );
 			var textures = getTexturesFromAtlasFile( "textures/cube/sun_temple_stripe_stereo.jpg", 12 );
 			var textures = getTexturesFromAtlasFile( "textures/cube/sun_temple_stripe_stereo.jpg", 12 );
 
 
 			var materials = [];
 			var materials = [];
@@ -72,7 +71,7 @@
 
 
 			}
 			}
 
 
-			var skyBox = new THREE.Mesh( new THREE.CubeGeometry( 1, 1, 1 ), new THREE.MeshFaceMaterial( materials ) );
+			var skyBox = new THREE.Mesh( geometry, materials );
 			skyBox.applyMatrix( new THREE.Matrix4().makeScale( 1, 1, - 1 ) );
 			skyBox.applyMatrix( new THREE.Matrix4().makeScale( 1, 1, - 1 ) );
 			skyBox.layers.set( 1 );
 			skyBox.layers.set( 1 );
 			scene.add( skyBox );
 			scene.add( skyBox );
@@ -86,7 +85,7 @@
 
 
 			}
 			}
 
 
-			var skyBoxR = new THREE.Mesh( new THREE.CubeGeometry( 1, 1, 1 ), new THREE.MeshFaceMaterial( materialsR ) );
+			var skyBoxR = new THREE.Mesh( geometry, materialsR );
 			skyBoxR.applyMatrix( new THREE.Matrix4().makeScale( 1, 1, - 1 ) );
 			skyBoxR.applyMatrix( new THREE.Matrix4().makeScale( 1, 1, - 1 ) );
 			skyBoxR.layers.set( 2 );
 			skyBoxR.layers.set( 2 );
 			scene.add( skyBoxR );
 			scene.add( skyBoxR );
@@ -137,17 +136,19 @@
 			camera.aspect = window.innerWidth / window.innerHeight;
 			camera.aspect = window.innerWidth / window.innerHeight;
 			camera.updateProjectionMatrix();
 			camera.updateProjectionMatrix();
 
 
-			effect.setSize( window.innerWidth, window.innerHeight );
+			renderer.setSize( window.innerWidth, window.innerHeight );
 
 
 		}
 		}
 
 
 		function animate() {
 		function animate() {
 
 
-			controls.update();
+			renderer.animate( render );
+
+		}
 
 
-			effect.render( scene, camera );
+		function render() {
 
 
-			effect.requestAnimationFrame( animate );
+			renderer.render( scene, camera );
 
 
 		}
 		}
 
 

+ 15 - 17
examples/webvr_rollercoaster.html

@@ -4,8 +4,8 @@
 		<title>three.js webvr - roller coaster</title>
 		<title>three.js webvr - roller coaster</title>
 		<meta charset="utf-8">
 		<meta charset="utf-8">
 		<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
 		<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
-		<!-- Origin Trial Token, feature = WebVR, origin = https://threejs.org, expires = 2017-06-13 -->
-		<meta http-equiv="origin-trial" data-feature="WebVR" data-expires="2017-06-13" content="ApAQvHfiHMQB7SmRhfvCUX61adJaTA6pAu0Ry439jjeipa5lGm1RcTQynFoHGGcaSJkWfMOv7qK6pwSUb95ClQgAAABKeyJvcmlnaW4iOiJodHRwczovL3RocmVlanMub3JnOjQ0MyIsImZlYXR1cmUiOiJXZWJWUiIsImV4cGlyeSI6MTQ5NzMxMjAwMH0=">
+		<!-- Origin Trial Token, feature = WebVR (For Chrome M59+), origin = https://threejs.org, expires = 2017-07-28 -->
+		<meta http-equiv="origin-trial" data-feature="WebVR (For Chrome M59+)" data-expires="2017-07-28" content="Ave6CPNUgSwHb3vCbyd55P/R7pfkwNniUJsYfSoUqI+l1X1BIOt6HfriVP0g2hmaG7Pp3qaUXuXdZeqGBmoMKg8AAABNeyJvcmlnaW4iOiJodHRwczovL3RocmVlanMub3JnOjQ0MyIsImZlYXR1cmUiOiJXZWJWUjEuMSIsImV4cGlyeSI6MTUwMTI2NzQwNX0=">
 		<style>
 		<style>
 			body {
 			body {
 				margin: 0px;
 				margin: 0px;
@@ -25,8 +25,6 @@
 
 
 		<script src="js/RollerCoaster.js"></script>
 		<script src="js/RollerCoaster.js"></script>
 
 
-		<script src="js/controls/VRControls.js"></script>
-		<script src="js/effects/VREffect.js"></script>
 		<script src="js/vr/WebVR.js"></script>
 		<script src="js/vr/WebVR.js"></script>
 
 
 		<script>
 		<script>
@@ -45,6 +43,8 @@
 			renderer.setSize( window.innerWidth, window.innerHeight );
 			renderer.setSize( window.innerWidth, window.innerHeight );
 			document.body.appendChild( renderer.domElement );
 			document.body.appendChild( renderer.domElement );
 
 
+			renderer.vr.enabled = true;
+
 			var scene = new THREE.Scene();
 			var scene = new THREE.Scene();
 
 
 			var light = new THREE.HemisphereLight( 0xfff0f0, 0x606066 );
 			var light = new THREE.HemisphereLight( 0xfff0f0, 0x606066 );
@@ -186,25 +186,26 @@
 
 
 			//
 			//
 
 
-			var controls = new THREE.VRControls( camera );
-			var effect = new THREE.VREffect( renderer );
-
 			WEBVR.getVRDisplay( function ( display ) {
 			WEBVR.getVRDisplay( function ( display ) {
 
 
+				renderer.vr.setDevice( display );
+
 				document.body.appendChild( WEBVR.getButton( display, renderer.domElement ) );
 				document.body.appendChild( WEBVR.getButton( display, renderer.domElement ) );
 
 
 			} );
 			} );
 
 
 			//
 			//
 
 
-			window.addEventListener( 'resize', function () {
+			window.addEventListener( 'resize', onWindowResize, false );
+
+			function onWindowResize() {
 
 
 				camera.aspect = window.innerWidth / window.innerHeight;
 				camera.aspect = window.innerWidth / window.innerHeight;
 				camera.updateProjectionMatrix();
 				camera.updateProjectionMatrix();
 
 
-				effect.setSize( window.innerWidth, window.innerHeight );
+				renderer.setSize( window.innerWidth, window.innerHeight );
 
 
-			}, false );
+			}
 
 
 			//
 			//
 
 
@@ -218,10 +219,9 @@
 
 
 			var prevTime = performance.now();
 			var prevTime = performance.now();
 
 
-			function animate( time ) {
-
-				effect.requestAnimationFrame( animate );
+			function render() {
 
 
+				var time = performance.now();
 				var delta = time - prevTime;
 				var delta = time - prevTime;
 
 
 				for ( var i = 0; i < funfairs.length; i ++ ) {
 				for ( var i = 0; i < funfairs.length; i ++ ) {
@@ -249,15 +249,13 @@
 
 
 				//
 				//
 
 
-				controls.update();
-
-				effect.render( scene, camera );
+				renderer.render( scene, camera );
 
 
 				prevTime = time;
 				prevTime = time;
 
 
 			}
 			}
 
 
-			effect.requestAnimationFrame( animate );
+			renderer.animate( render );
 
 
 		</script>
 		</script>
 
 

+ 13 - 15
examples/webvr_sandbox.html

@@ -4,8 +4,8 @@
 		<title>three.js webvr - sandbox</title>
 		<title>three.js webvr - sandbox</title>
 		<meta charset="utf-8">
 		<meta charset="utf-8">
 		<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
 		<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
-		<!-- Origin Trial Token, feature = WebVR, origin = https://threejs.org, expires = 2017-06-13 -->
-		<meta http-equiv="origin-trial" data-feature="WebVR" data-expires="2017-06-13" content="ApAQvHfiHMQB7SmRhfvCUX61adJaTA6pAu0Ry439jjeipa5lGm1RcTQynFoHGGcaSJkWfMOv7qK6pwSUb95ClQgAAABKeyJvcmlnaW4iOiJodHRwczovL3RocmVlanMub3JnOjQ0MyIsImZlYXR1cmUiOiJXZWJWUiIsImV4cGlyeSI6MTQ5NzMxMjAwMH0=">
+		<!-- Origin Trial Token, feature = WebVR (For Chrome M59+), origin = https://threejs.org, expires = 2017-07-28 -->
+		<meta http-equiv="origin-trial" data-feature="WebVR (For Chrome M59+)" data-expires="2017-07-28" content="Ave6CPNUgSwHb3vCbyd55P/R7pfkwNniUJsYfSoUqI+l1X1BIOt6HfriVP0g2hmaG7Pp3qaUXuXdZeqGBmoMKg8AAABNeyJvcmlnaW4iOiJodHRwczovL3RocmVlanMub3JnOjQ0MyIsImZlYXR1cmUiOiJXZWJWUjEuMSIsImV4cGlyeSI6MTUwMTI2NzQwNX0=">
 		<style>
 		<style>
 			body {
 			body {
 				margin: 0px;
 				margin: 0px;
@@ -17,8 +17,6 @@
 
 
 		<script src="../build/three.js"></script>
 		<script src="../build/three.js"></script>
 
 
-		<script src="js/controls/VRControls.js"></script>
-		<script src="js/effects/VREffect.js"></script>
 		<script src="js/vr/WebVR.js"></script>
 		<script src="js/vr/WebVR.js"></script>
 
 
 		<script src="js/Mirror.js"></script>
 		<script src="js/Mirror.js"></script>
@@ -34,7 +32,6 @@
 			//
 			//
 
 
 			var camera, scene, renderer;
 			var camera, scene, renderer;
-			var effect, controls;
 
 
 			var mirror;
 			var mirror;
 
 
@@ -90,7 +87,10 @@
 
 
 				//
 				//
 
 
-				mirror = new THREE.Mirror( 1.4, 1.4, { textureWidth: window.innerWidth, textureHeight: window.innerHeight } );
+				mirror = new THREE.Mirror( 1.4, 1.4, {
+					textureWidth: window.innerWidth * window.devicePixelRatio,
+					textureHeight: window.innerHeight * window.devicePixelRatio
+				} );
 				mirror.position.x = 1;
 				mirror.position.x = 1;
 				mirror.position.y = 0.5;
 				mirror.position.y = 0.5;
 				mirror.position.z = -3;
 				mirror.position.z = -3;
@@ -114,13 +114,14 @@
 				renderer.shadowMap.enabled = true;
 				renderer.shadowMap.enabled = true;
 				document.body.appendChild( renderer.domElement );
 				document.body.appendChild( renderer.domElement );
 
 
-				//
+				renderer.vr.enabled = true;
 
 
-				controls = new THREE.VRControls( camera );
-				effect = new THREE.VREffect( renderer );
+				//
 
 
 				WEBVR.getVRDisplay( function ( display ) {
 				WEBVR.getVRDisplay( function ( display ) {
 
 
+					renderer.vr.setDevice( display );
+
 					document.body.appendChild( WEBVR.getButton( display, renderer.domElement ) );
 					document.body.appendChild( WEBVR.getButton( display, renderer.domElement ) );
 
 
 				} );
 				} );
@@ -136,14 +137,13 @@
 				camera.aspect = window.innerWidth / window.innerHeight;
 				camera.aspect = window.innerWidth / window.innerHeight;
 				camera.updateProjectionMatrix();
 				camera.updateProjectionMatrix();
 
 
-				effect.setSize( window.innerWidth, window.innerHeight );
+				renderer.setSize( window.innerWidth, window.innerHeight );
 
 
 			}
 			}
 
 
 			function animate() {
 			function animate() {
 
 
-				effect.requestAnimationFrame( animate );
-				render();
+				renderer.animate( render );
 
 
 			}
 			}
 
 
@@ -154,9 +154,7 @@
 				mesh.rotation.x = time * 2;
 				mesh.rotation.x = time * 2;
 				mesh.rotation.y = time * 5;
 				mesh.rotation.y = time * 5;
 
 
-				controls.update();
-
-				effect.render( scene, camera );
+				renderer.render( scene, camera );
 
 
 			}
 			}
 
 

+ 9 - 18
examples/webvr_video.html

@@ -4,8 +4,8 @@
 		<title>three.js webvr - video</title>
 		<title>three.js webvr - video</title>
 		<meta charset="utf-8">
 		<meta charset="utf-8">
 		<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
 		<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
-		<!-- Origin Trial Token, feature = WebVR, origin = https://threejs.org, expires = 2017-06-13 -->
-		<meta http-equiv="origin-trial" data-feature="WebVR" data-expires="2017-06-13" content="ApAQvHfiHMQB7SmRhfvCUX61adJaTA6pAu0Ry439jjeipa5lGm1RcTQynFoHGGcaSJkWfMOv7qK6pwSUb95ClQgAAABKeyJvcmlnaW4iOiJodHRwczovL3RocmVlanMub3JnOjQ0MyIsImZlYXR1cmUiOiJXZWJWUiIsImV4cGlyeSI6MTQ5NzMxMjAwMH0=">
+		<!-- Origin Trial Token, feature = WebVR (For Chrome M59+), origin = https://threejs.org, expires = 2017-07-28 -->
+		<meta http-equiv="origin-trial" data-feature="WebVR (For Chrome M59+)" data-expires="2017-07-28" content="Ave6CPNUgSwHb3vCbyd55P/R7pfkwNniUJsYfSoUqI+l1X1BIOt6HfriVP0g2hmaG7Pp3qaUXuXdZeqGBmoMKg8AAABNeyJvcmlnaW4iOiJodHRwczovL3RocmVlanMub3JnOjQ0MyIsImZlYXR1cmUiOiJXZWJWUjEuMSIsImV4cGlyeSI6MTUwMTI2NzQwNX0=">
 		<style>
 		<style>
 			body {
 			body {
 				font-family: Monospace;
 				font-family: Monospace;
@@ -34,8 +34,6 @@
 
 
 		<script src="../build/three.js"></script>
 		<script src="../build/three.js"></script>
 
 
-		<script src="js/controls/VRControls.js"></script>
-		<script src="js/effects/VREffect.js"></script>
 		<script src="js/vr/WebVR.js"></script>
 		<script src="js/vr/WebVR.js"></script>
 
 
 		<script>
 		<script>
@@ -51,8 +49,6 @@
 			var camera, scene, renderer;
 			var camera, scene, renderer;
 			var video, texture;
 			var video, texture;
 
 
-			var controls, effect;
-
 			init();
 			init();
 			animate();
 			animate();
 
 
@@ -142,16 +138,14 @@
 				renderer.setSize( window.innerWidth, window.innerHeight );
 				renderer.setSize( window.innerWidth, window.innerHeight );
 				container.appendChild( renderer.domElement );
 				container.appendChild( renderer.domElement );
 
 
-				//
-
-				controls = new THREE.VRControls( camera );
+				renderer.vr.enabled = true;
 
 
-				effect = new THREE.VREffect( renderer );
-				effect.scale = 0; // video doesn't need eye separation
-				effect.setSize( window.innerWidth, window.innerHeight );
+				//
 
 
 				WEBVR.getVRDisplay( function ( display ) {
 				WEBVR.getVRDisplay( function ( display ) {
 
 
+					renderer.vr.setDevice( display );
+
 					document.body.appendChild( WEBVR.getButton( display, renderer.domElement ) );
 					document.body.appendChild( WEBVR.getButton( display, renderer.domElement ) );
 
 
 				} );
 				} );
@@ -168,22 +162,19 @@
 				camera.aspect = window.innerWidth / window.innerHeight;
 				camera.aspect = window.innerWidth / window.innerHeight;
 				camera.updateProjectionMatrix();
 				camera.updateProjectionMatrix();
 
 
-				effect.setSize( window.innerWidth, window.innerHeight );
+				renderer.setSize( window.innerWidth, window.innerHeight );
 
 
 			}
 			}
 
 
 			function animate() {
 			function animate() {
 
 
-				effect.requestAnimationFrame( animate );
-				render();
+				renderer.animate( render );
 
 
 			}
 			}
 
 
 			function render() {
 			function render() {
 
 
-				controls.update();
-
-				effect.render( scene, camera );
+				renderer.render( scene, camera );
 
 
 			}
 			}
 
 

+ 11 - 17
examples/webvr_vive.html

@@ -21,8 +21,6 @@
 
 
 		<script src="../build/three.js"></script>
 		<script src="../build/three.js"></script>
 
 
-		<script src="js/controls/VRControls.js"></script>
-		<script src="js/effects/VREffect.js"></script>
 		<script src="js/vr/ViveController.js"></script>
 		<script src="js/vr/ViveController.js"></script>
 		<script src="js/vr/WebVR.js"></script>
 		<script src="js/vr/WebVR.js"></script>
 
 
@@ -42,7 +40,6 @@
 
 
 			var container;
 			var container;
 			var camera, scene, renderer;
 			var camera, scene, renderer;
-			var effect, controls;
 			var controller1, controller2;
 			var controller1, controller2;
 
 
 			var room;
 			var room;
@@ -165,17 +162,17 @@
 				renderer.sortObjects = false;
 				renderer.sortObjects = false;
 				container.appendChild( renderer.domElement );
 				container.appendChild( renderer.domElement );
 
 
-				controls = new THREE.VRControls( camera );
-				controls.standing = true;
+				renderer.vr.enabled = true;
+				renderer.vr.standing = true;
 
 
 				// controllers
 				// controllers
 
 
 				controller1 = new THREE.ViveController( 0 );
 				controller1 = new THREE.ViveController( 0 );
-				controller1.standingMatrix = controls.getStandingMatrix();
+				controller1.standingMatrix = renderer.vr.getStandingMatrix();
 				scene.add( controller1 );
 				scene.add( controller1 );
 
 
 				controller2 = new THREE.ViveController( 1 );
 				controller2 = new THREE.ViveController( 1 );
-				controller2.standingMatrix = controls.getStandingMatrix();
+				controller2.standingMatrix = renderer.vr.getStandingMatrix();
 				scene.add( controller2 );
 				scene.add( controller2 );
 
 
 				var loader = new THREE.OBJLoader();
 				var loader = new THREE.OBJLoader();
@@ -194,10 +191,10 @@
 
 
 				} );
 				} );
 
 
-				effect = new THREE.VREffect( renderer );
-
 				WEBVR.getVRDisplay( function ( display ) {
 				WEBVR.getVRDisplay( function ( display ) {
 
 
+					renderer.vr.setDevice( display );
+
 					document.body.appendChild( WEBVR.getButton( display, renderer.domElement ) );
 					document.body.appendChild( WEBVR.getButton( display, renderer.domElement ) );
 
 
 				} );
 				} );
@@ -213,19 +210,18 @@
 				camera.aspect = window.innerWidth / window.innerHeight;
 				camera.aspect = window.innerWidth / window.innerHeight;
 				camera.updateProjectionMatrix();
 				camera.updateProjectionMatrix();
 
 
-				effect.setSize( window.innerWidth, window.innerHeight );
+				renderer.setSize( window.innerWidth, window.innerHeight );
 
 
 			}
 			}
 
 
-			//
-
 			function animate() {
 			function animate() {
 
 
-				effect.requestAnimationFrame( animate );
-				render();
+				renderer.animate( render );
 
 
 			}
 			}
 
 
+			//
+
 			function render() {
 			function render() {
 
 
 				var delta = clock.getDelta() * 60;
 				var delta = clock.getDelta() * 60;
@@ -233,8 +229,6 @@
 				controller1.update();
 				controller1.update();
 				controller2.update();
 				controller2.update();
 
 
-				controls.update();
-
 				for ( var i = 0; i < room.children.length; i ++ ) {
 				for ( var i = 0; i < room.children.length; i ++ ) {
 
 
 					var cube = room.children[ i ];
 					var cube = room.children[ i ];
@@ -268,7 +262,7 @@
 
 
 				}
 				}
 
 
-				effect.render( scene, camera );
+				renderer.render( scene, camera );
 
 
 			}
 			}
 
 

+ 9 - 15
examples/webvr_vive_camerarig.html

@@ -21,8 +21,6 @@
 
 
 		<script src="../build/three.js"></script>
 		<script src="../build/three.js"></script>
 
 
-		<script src="js/controls/VRControls.js"></script>
-		<script src="js/effects/VREffect.js"></script>
 		<script src="js/vr/ViveController.js"></script>
 		<script src="js/vr/ViveController.js"></script>
 		<script src="js/vr/WebVR.js"></script>
 		<script src="js/vr/WebVR.js"></script>
 
 
@@ -42,7 +40,6 @@
 
 
 			var container;
 			var container;
 			var cameraRig, camera, scene, renderer;
 			var cameraRig, camera, scene, renderer;
-			var effect, controls;
 			var controller1, controller2;
 			var controller1, controller2;
 			var scale = 1;
 			var scale = 1;
 			var dragging = {
 			var dragging = {
@@ -174,19 +171,19 @@
 				renderer.sortObjects = false;
 				renderer.sortObjects = false;
 				container.appendChild( renderer.domElement );
 				container.appendChild( renderer.domElement );
 
 
-				controls = new THREE.VRControls( camera );
-				controls.standing = true;
+				renderer.vr.enabled = true;
+				renderer.vr.standing = true;
 
 
 				// controllers
 				// controllers
 
 
 				controller1 = new THREE.ViveController( 0 );
 				controller1 = new THREE.ViveController( 0 );
-				controller1.standingMatrix = controls.getStandingMatrix();
+				controller1.standingMatrix = renderer.vr.getStandingMatrix();
 				controller1.addEventListener( 'triggerdown', onTriggerDown );
 				controller1.addEventListener( 'triggerdown', onTriggerDown );
 				controller1.addEventListener( 'triggerup', onTriggerUp );
 				controller1.addEventListener( 'triggerup', onTriggerUp );
 				cameraRig.add( controller1 );
 				cameraRig.add( controller1 );
 
 
 				controller2 = new THREE.ViveController( 1 );
 				controller2 = new THREE.ViveController( 1 );
-				controller2.standingMatrix = controls.getStandingMatrix();
+				controller2.standingMatrix = renderer.vr.getStandingMatrix();
 				controller2.addEventListener( 'triggerdown', onTriggerDown );
 				controller2.addEventListener( 'triggerdown', onTriggerDown );
 				controller2.addEventListener( 'triggerup', onTriggerUp );
 				controller2.addEventListener( 'triggerup', onTriggerUp );
 				cameraRig.add( controller2 );
 				cameraRig.add( controller2 );
@@ -207,10 +204,10 @@
 
 
 				} );
 				} );
 
 
-				effect = new THREE.VREffect( renderer );
-
 				WEBVR.getVRDisplay( function ( display ) {
 				WEBVR.getVRDisplay( function ( display ) {
 
 
+					renderer.vr.setDevice( display );
+
 					document.body.appendChild( WEBVR.getButton( display, renderer.domElement ) );
 					document.body.appendChild( WEBVR.getButton( display, renderer.domElement ) );
 
 
 				} );
 				} );
@@ -226,7 +223,7 @@
 				camera.aspect = window.innerWidth / window.innerHeight;
 				camera.aspect = window.innerWidth / window.innerHeight;
 				camera.updateProjectionMatrix();
 				camera.updateProjectionMatrix();
 
 
-				effect.setSize( window.innerWidth, window.innerHeight );
+				renderer.setSize( window.innerWidth, window.innerHeight );
 
 
 			}
 			}
 
 
@@ -234,8 +231,7 @@
 
 
 			function animate() {
 			function animate() {
 
 
-				effect.requestAnimationFrame( animate );
-				render();
+				renderer.animate( render );
 
 
 			}
 			}
 
 
@@ -246,8 +242,6 @@
 				controller1.update();
 				controller1.update();
 				controller2.update();
 				controller2.update();
 
 
-				controls.update();
-
 				scaleUpdate();
 				scaleUpdate();
 
 
 				for ( var i = 0; i < room.children.length; i ++ ) {
 				for ( var i = 0; i < room.children.length; i ++ ) {
@@ -283,7 +277,7 @@
 
 
 				}
 				}
 
 
-				effect.render( scene, camera );
+				renderer.render( scene, camera );
 
 
 			}
 			}
 
 

+ 9 - 15
examples/webvr_vive_dragging.html

@@ -21,8 +21,6 @@
 
 
 		<script src="../build/three.js"></script>
 		<script src="../build/three.js"></script>
 
 
-		<script src="js/controls/VRControls.js"></script>
-		<script src="js/effects/VREffect.js"></script>
 		<script src="js/vr/ViveController.js"></script>
 		<script src="js/vr/ViveController.js"></script>
 		<script src="js/vr/WebVR.js"></script>
 		<script src="js/vr/WebVR.js"></script>
 
 
@@ -40,7 +38,6 @@
 
 
 			var container;
 			var container;
 			var camera, scene, renderer;
 			var camera, scene, renderer;
-			var effect, controls;
 			var controller1, controller2;
 			var controller1, controller2;
 
 
 			var raycaster, intersected = [];
 			var raycaster, intersected = [];
@@ -142,19 +139,19 @@
 				renderer.gammaOutput = true;
 				renderer.gammaOutput = true;
 				container.appendChild( renderer.domElement );
 				container.appendChild( renderer.domElement );
 
 
-				controls = new THREE.VRControls( camera );
-				controls.standing = true;
+				renderer.vr.enabled = true;
+				renderer.vr.standing = true;
 
 
 				// controllers
 				// controllers
 
 
 				controller1 = new THREE.ViveController( 0 );
 				controller1 = new THREE.ViveController( 0 );
-				controller1.standingMatrix = controls.getStandingMatrix();
+				controller1.standingMatrix = renderer.vr.getStandingMatrix();
 				controller1.addEventListener( 'triggerdown', onTriggerDown );
 				controller1.addEventListener( 'triggerdown', onTriggerDown );
 				controller1.addEventListener( 'triggerup', onTriggerUp );
 				controller1.addEventListener( 'triggerup', onTriggerUp );
 				scene.add( controller1 );
 				scene.add( controller1 );
 
 
 				controller2 = new THREE.ViveController( 1 );
 				controller2 = new THREE.ViveController( 1 );
-				controller2.standingMatrix = controls.getStandingMatrix();
+				controller2.standingMatrix = renderer.vr.getStandingMatrix();
 				controller2.addEventListener( 'triggerdown', onTriggerDown );
 				controller2.addEventListener( 'triggerdown', onTriggerDown );
 				controller2.addEventListener( 'triggerup', onTriggerUp );
 				controller2.addEventListener( 'triggerup', onTriggerUp );
 				scene.add( controller2 );
 				scene.add( controller2 );
@@ -193,10 +190,10 @@
 
 
 				//
 				//
 
 
-				effect = new THREE.VREffect( renderer );
-
 				WEBVR.getVRDisplay( function ( display ) {
 				WEBVR.getVRDisplay( function ( display ) {
 
 
+					renderer.vr.setDevice( display );
+
 					document.body.appendChild( WEBVR.getButton( display, renderer.domElement ) );
 					document.body.appendChild( WEBVR.getButton( display, renderer.domElement ) );
 
 
 				} );
 				} );
@@ -212,7 +209,7 @@
 				camera.aspect = window.innerWidth / window.innerHeight;
 				camera.aspect = window.innerWidth / window.innerHeight;
 				camera.updateProjectionMatrix();
 				camera.updateProjectionMatrix();
 
 
-				effect.setSize( window.innerWidth, window.innerHeight );
+				renderer.setSize( window.innerWidth, window.innerHeight );
 
 
 			}
 			}
 
 
@@ -312,8 +309,7 @@
 
 
 			function animate() {
 			function animate() {
 
 
-				effect.requestAnimationFrame( animate );
-				render();
+				renderer.animate( render );
 
 
 			}
 			}
 
 
@@ -322,14 +318,12 @@
 				controller1.update();
 				controller1.update();
 				controller2.update();
 				controller2.update();
 
 
-				controls.update();
-
 				cleanIntersected();
 				cleanIntersected();
 
 
 				intersectObjects( controller1 );
 				intersectObjects( controller1 );
 				intersectObjects( controller2 );
 				intersectObjects( controller2 );
 
 
-				effect.render( scene, camera );
+				renderer.render( scene, camera );
 
 
 			}
 			}
 
 

+ 14 - 20
examples/webvr_vive_paint.html

@@ -21,8 +21,6 @@
 
 
 		<script src="../build/three.js"></script>
 		<script src="../build/three.js"></script>
 
 
-		<script src="js/controls/VRControls.js"></script>
-		<script src="js/effects/VREffect.js"></script>
 		<script src="js/vr/ViveController.js"></script>
 		<script src="js/vr/ViveController.js"></script>
 		<script src="js/vr/PaintViveController.js"></script>
 		<script src="js/vr/PaintViveController.js"></script>
 		<script src="js/vr/WebVR.js"></script>
 		<script src="js/vr/WebVR.js"></script>
@@ -41,7 +39,6 @@
 
 
 			var container;
 			var container;
 			var camera, scene, renderer;
 			var camera, scene, renderer;
-			var effect, controls;
 			var controller1, controller2;
 			var controller1, controller2;
 
 
 			var line;
 			var line;
@@ -142,19 +139,19 @@
 				renderer.gammaOutput = true;
 				renderer.gammaOutput = true;
 				container.appendChild( renderer.domElement );
 				container.appendChild( renderer.domElement );
 
 
-				controls = new THREE.VRControls( camera );
-				controls.standing = true;
+				renderer.vr.enabled = true;
+				renderer.vr.standing = true;
 
 
 				// controllers
 				// controllers
 
 
 				controller1 = new THREE.PaintViveController( 0 );
 				controller1 = new THREE.PaintViveController( 0 );
-				controller1.standingMatrix = controls.getStandingMatrix();
+				controller1.standingMatrix = renderer.vr.getStandingMatrix();
 				controller1.userData.points = [ new THREE.Vector3(), new THREE.Vector3() ];
 				controller1.userData.points = [ new THREE.Vector3(), new THREE.Vector3() ];
 				controller1.userData.matrices = [ new THREE.Matrix4(), new THREE.Matrix4() ];
 				controller1.userData.matrices = [ new THREE.Matrix4(), new THREE.Matrix4() ];
 				scene.add( controller1 );
 				scene.add( controller1 );
 
 
 				controller2 = new THREE.PaintViveController( 1 );
 				controller2 = new THREE.PaintViveController( 1 );
-				controller2.standingMatrix = controls.getStandingMatrix();
+				controller2.standingMatrix = renderer.vr.getStandingMatrix();
 				controller2.userData.points = [ new THREE.Vector3(), new THREE.Vector3() ];
 				controller2.userData.points = [ new THREE.Vector3(), new THREE.Vector3() ];
 				controller2.userData.matrices = [ new THREE.Matrix4(), new THREE.Matrix4() ];
 				controller2.userData.matrices = [ new THREE.Matrix4(), new THREE.Matrix4() ];
 				scene.add( controller2 );
 				scene.add( controller2 );
@@ -188,10 +185,10 @@
 
 
 				} );
 				} );
 
 
-				effect = new THREE.VREffect( renderer );
-
 				WEBVR.getVRDisplay( function ( display ) {
 				WEBVR.getVRDisplay( function ( display ) {
 
 
+					renderer.vr.setDevice( display );
+
 					document.body.appendChild( WEBVR.getButton( display, renderer.domElement ) );
 					document.body.appendChild( WEBVR.getButton( display, renderer.domElement ) );
 
 
 				} );
 				} );
@@ -387,19 +384,12 @@
 				camera.aspect = window.innerWidth / window.innerHeight;
 				camera.aspect = window.innerWidth / window.innerHeight;
 				camera.updateProjectionMatrix();
 				camera.updateProjectionMatrix();
 
 
-				effect.setSize( window.innerWidth, window.innerHeight );
+				renderer.setSize( window.innerWidth, window.innerHeight );
 
 
 			}
 			}
 
 
 			//
 			//
 
 
-			function animate() {
-
-				effect.requestAnimationFrame( animate );
-				render();
-
-			}
-
 			function handleController( controller ) {
 			function handleController( controller ) {
 
 
 				controller.update();
 				controller.update();
@@ -435,9 +425,13 @@
 
 
 			}
 			}
 
 
-			function render() {
+			function animate() {
+
+				renderer.animate( render );
 
 
-				controls.update();
+			}
+
+			function render() {
 
 
 				var count = line.geometry.drawRange.count;
 				var count = line.geometry.drawRange.count;
 
 
@@ -446,7 +440,7 @@
 
 
 				updateGeometry( count, line.geometry.drawRange.count );
 				updateGeometry( count, line.geometry.drawRange.count );
 
 
-				effect.render( scene, camera );
+				renderer.render( scene, camera );
 
 
 			}
 			}
 
 

+ 9 - 15
examples/webvr_vive_sculpt.html

@@ -21,8 +21,6 @@
 
 
 		<script src="../build/three.js"></script>
 		<script src="../build/three.js"></script>
 
 
-		<script src="js/controls/VRControls.js"></script>
-		<script src="js/effects/VREffect.js"></script>
 		<script src="js/vr/ViveController.js"></script>
 		<script src="js/vr/ViveController.js"></script>
 		<script src="js/vr/WebVR.js"></script>
 		<script src="js/vr/WebVR.js"></script>
 
 
@@ -41,7 +39,6 @@
 
 
 			var container;
 			var container;
 			var camera, scene, renderer;
 			var camera, scene, renderer;
-			var effect, controls;
 			var controller1, controller2;
 			var controller1, controller2;
 
 
 			var blob, vector;
 			var blob, vector;
@@ -124,17 +121,17 @@
 				renderer.gammaOutput = true;
 				renderer.gammaOutput = true;
 				container.appendChild( renderer.domElement );
 				container.appendChild( renderer.domElement );
 
 
-				controls = new THREE.VRControls( camera );
-				controls.standing = true;
+				renderer.vr.enabled = true;
+				renderer.vr.standing = true;
 
 
 				// controllers
 				// controllers
 
 
 				controller1 = new THREE.ViveController( 0 );
 				controller1 = new THREE.ViveController( 0 );
-				controller1.standingMatrix = controls.getStandingMatrix();
+				controller1.standingMatrix = renderer.vr.getStandingMatrix();
 				scene.add( controller1 );
 				scene.add( controller1 );
 
 
 				controller2 = new THREE.ViveController( 1 );
 				controller2 = new THREE.ViveController( 1 );
-				controller2.standingMatrix = controls.getStandingMatrix();
+				controller2.standingMatrix = renderer.vr.getStandingMatrix();
 				scene.add( controller2 );
 				scene.add( controller2 );
 
 
 				var loader = new THREE.OBJLoader();
 				var loader = new THREE.OBJLoader();
@@ -166,10 +163,10 @@
 
 
 				} );
 				} );
 
 
-				effect = new THREE.VREffect( renderer );
-
 				WEBVR.getVRDisplay( function ( display ) {
 				WEBVR.getVRDisplay( function ( display ) {
 
 
+					renderer.vr.setDevice( display );
+
 					document.body.appendChild( WEBVR.getButton( display, renderer.domElement ) );
 					document.body.appendChild( WEBVR.getButton( display, renderer.domElement ) );
 
 
 				} );
 				} );
@@ -223,7 +220,7 @@
 				camera.aspect = window.innerWidth / window.innerHeight;
 				camera.aspect = window.innerWidth / window.innerHeight;
 				camera.updateProjectionMatrix();
 				camera.updateProjectionMatrix();
 
 
-				effect.setSize( window.innerWidth, window.innerHeight );
+				renderer.setSize( window.innerWidth, window.innerHeight );
 
 
 			}
 			}
 
 
@@ -231,8 +228,7 @@
 
 
 			function animate() {
 			function animate() {
 
 
-				effect.requestAnimationFrame( animate );
-				render();
+				renderer.animate( render );
 
 
 			}
 			}
 
 
@@ -329,9 +325,7 @@
 
 
 				updateBlob();
 				updateBlob();
 
 
-				controls.update();
-
-				effect.render( scene, camera );
+				renderer.render( scene, camera );
 
 
 			}
 			}
 
 

+ 1 - 1
package.json

@@ -1,6 +1,6 @@
 {
 {
   "name": "three",
   "name": "three",
-  "version": "0.85.2",
+  "version": "0.86.0",
   "description": "JavaScript 3D library",
   "description": "JavaScript 3D library",
   "main": "build/three.js",
   "main": "build/three.js",
   "repository": "mrdoob/three.js",
   "repository": "mrdoob/three.js",

+ 2 - 0
src/Three.js

@@ -134,6 +134,8 @@ export { FaceNormalsHelper } from './helpers/FaceNormalsHelper.js';
 export { DirectionalLightHelper } from './helpers/DirectionalLightHelper.js';
 export { DirectionalLightHelper } from './helpers/DirectionalLightHelper.js';
 export { CameraHelper } from './helpers/CameraHelper.js';
 export { CameraHelper } from './helpers/CameraHelper.js';
 export { BoxHelper } from './helpers/BoxHelper.js';
 export { BoxHelper } from './helpers/BoxHelper.js';
+export { Box3Helper } from './helpers/Box3Helper.js';
+export { PlaneHelper } from './helpers/PlaneHelper.js';
 export { ArrowHelper } from './helpers/ArrowHelper.js';
 export { ArrowHelper } from './helpers/ArrowHelper.js';
 export { AxisHelper } from './helpers/AxisHelper.js';
 export { AxisHelper } from './helpers/AxisHelper.js';
 export { CatmullRomCurve3 } from './extras/curves/CatmullRomCurve3.js';
 export { CatmullRomCurve3 } from './extras/curves/CatmullRomCurve3.js';

+ 1 - 1
src/constants.js

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

+ 5 - 5
src/helpers/AxisHelper.js

@@ -1,14 +1,14 @@
+/**
+ * @author sroucheray / http://sroucheray.org/
+ * @author mrdoob / http://mrdoob.com/
+ */
+
 import { LineSegments } from '../objects/LineSegments';
 import { LineSegments } from '../objects/LineSegments';
 import { VertexColors } from '../constants';
 import { VertexColors } from '../constants';
 import { LineBasicMaterial } from '../materials/LineBasicMaterial';
 import { LineBasicMaterial } from '../materials/LineBasicMaterial';
 import { Float32BufferAttribute } from '../core/BufferAttribute';
 import { Float32BufferAttribute } from '../core/BufferAttribute';
 import { BufferGeometry } from '../core/BufferGeometry';
 import { BufferGeometry } from '../core/BufferGeometry';
 
 
-/**
- * @author sroucheray / http://sroucheray.org/
- * @author mrdoob / http://mrdoob.com/
- */
-
 function AxisHelper( size ) {
 function AxisHelper( size ) {
 
 
 	size = size || 1;
 	size = size || 1;

+ 55 - 0
src/helpers/Box3Helper.js

@@ -0,0 +1,55 @@
+/**
+ * @author WestLangley / http://github.com/WestLangley
+ */
+
+import { Box3 } from '../math/Box3';
+import { LineSegments } from '../objects/LineSegments';
+import { LineBasicMaterial } from '../materials/LineBasicMaterial';
+import { BufferAttribute } from '../core/BufferAttribute';
+import { Float32BufferAttribute } from '../core/BufferAttribute';
+import { BufferGeometry } from '../core/BufferGeometry';
+
+function Box3Helper( box, hex ) {
+
+	this.type = 'Box3Helper';
+
+	this.box = box;
+
+	var color = ( hex !== undefined ) ? hex : 0xffff00;
+
+	var indices = new Uint16Array( [ 0, 1, 1, 2, 2, 3, 3, 0, 4, 5, 5, 6, 6, 7, 7, 4, 0, 4, 1, 5, 2, 6, 3, 7 ] );
+
+	var positions = [ 1, 1, 1, - 1, 1, 1, - 1, - 1, 1, 1, - 1, 1, 1, 1, - 1, - 1, 1, - 1, - 1, - 1, - 1, 1, - 1, - 1 ];
+
+	var geometry = new BufferGeometry();
+
+	geometry.setIndex( new BufferAttribute( indices, 1 ) );
+
+	geometry.addAttribute( 'position', new Float32BufferAttribute( positions, 3 ) );
+
+	LineSegments.call( this, geometry, new LineBasicMaterial( { color: color } ) );
+
+	this.geometry.computeBoundingSphere();
+
+	this.onBeforeRender();
+
+}
+
+Box3Helper.prototype = Object.create( LineSegments.prototype );
+Box3Helper.prototype.constructor = Box3Helper;
+
+Box3Helper.prototype.onBeforeRender = function () {
+
+	var box = this.box;
+
+	if ( box.isEmpty() ) return;
+
+	box.getCenter( this.position );
+
+	box.getSize( this.scale );
+
+	this.scale.multiplyScalar( 0.5 );
+
+};
+
+export { Box3Helper };

+ 5 - 5
src/helpers/BoxHelper.js

@@ -1,14 +1,14 @@
+/**
+ * @author mrdoob / http://mrdoob.com/
+ * @author Mugen87 / http://github.com/Mugen87
+ */
+
 import { Box3 } from '../math/Box3';
 import { Box3 } from '../math/Box3';
 import { LineSegments } from '../objects/LineSegments';
 import { LineSegments } from '../objects/LineSegments';
 import { LineBasicMaterial } from '../materials/LineBasicMaterial';
 import { LineBasicMaterial } from '../materials/LineBasicMaterial';
 import { BufferAttribute } from '../core/BufferAttribute';
 import { BufferAttribute } from '../core/BufferAttribute';
 import { BufferGeometry } from '../core/BufferGeometry';
 import { BufferGeometry } from '../core/BufferGeometry';
 
 
-/**
- * @author mrdoob / http://mrdoob.com/
- * @author Mugen87 / http://github.com/Mugen87
- */
-
 function BoxHelper( object, color ) {
 function BoxHelper( object, color ) {
 
 
 	this.object = object;
 	this.object = object;

+ 9 - 9
src/helpers/CameraHelper.js

@@ -1,12 +1,3 @@
-import { Camera } from '../cameras/Camera';
-import { Vector3 } from '../math/Vector3';
-import { LineSegments } from '../objects/LineSegments';
-import { Color } from '../math/Color';
-import { FaceColors } from '../constants';
-import { LineBasicMaterial } from '../materials/LineBasicMaterial';
-import { BufferGeometry } from '../core/BufferGeometry';
-import { Float32BufferAttribute } from '../core/BufferAttribute';
-
 /**
 /**
  * @author alteredq / http://alteredqualia.com/
  * @author alteredq / http://alteredqualia.com/
  * @author Mugen87 / https://github.com/Mugen87
  * @author Mugen87 / https://github.com/Mugen87
@@ -17,6 +8,15 @@ import { Float32BufferAttribute } from '../core/BufferAttribute';
  *		http://evanw.github.com/lightgl.js/tests/shadowmap.html
  *		http://evanw.github.com/lightgl.js/tests/shadowmap.html
  */
  */
 
 
+import { Camera } from '../cameras/Camera';
+import { Vector3 } from '../math/Vector3';
+import { LineSegments } from '../objects/LineSegments';
+import { Color } from '../math/Color';
+import { FaceColors } from '../constants';
+import { LineBasicMaterial } from '../materials/LineBasicMaterial';
+import { BufferGeometry } from '../core/BufferGeometry';
+import { Float32BufferAttribute } from '../core/BufferAttribute';
+
 function CameraHelper( camera ) {
 function CameraHelper( camera ) {
 
 
 	var geometry = new BufferGeometry();
 	var geometry = new BufferGeometry();

+ 6 - 6
src/helpers/DirectionalLightHelper.js

@@ -1,3 +1,9 @@
+/**
+ * @author alteredq / http://alteredqualia.com/
+ * @author mrdoob / http://mrdoob.com/
+ * @author WestLangley / http://github.com/WestLangley
+ */
+
 import { Vector3 } from '../math/Vector3';
 import { Vector3 } from '../math/Vector3';
 import { Object3D } from '../core/Object3D';
 import { Object3D } from '../core/Object3D';
 import { Line } from '../objects/Line';
 import { Line } from '../objects/Line';
@@ -5,12 +11,6 @@ import { Float32BufferAttribute } from '../core/BufferAttribute';
 import { BufferGeometry } from '../core/BufferGeometry';
 import { BufferGeometry } from '../core/BufferGeometry';
 import { LineBasicMaterial } from '../materials/LineBasicMaterial';
 import { LineBasicMaterial } from '../materials/LineBasicMaterial';
 
 
-/**
- * @author alteredq / http://alteredqualia.com/
- * @author mrdoob / http://mrdoob.com/
- * @author WestLangley / http://github.com/WestLangley
- */
-
 function DirectionalLightHelper( light, size, color ) {
 function DirectionalLightHelper( light, size, color ) {
 
 
 	Object3D.call( this );
 	Object3D.call( this );

+ 5 - 5
src/helpers/FaceNormalsHelper.js

@@ -1,3 +1,8 @@
+/**
+ * @author mrdoob / http://mrdoob.com/
+ * @author WestLangley / http://github.com/WestLangley
+ */
+
 import { Matrix3 } from '../math/Matrix3';
 import { Matrix3 } from '../math/Matrix3';
 import { Vector3 } from '../math/Vector3';
 import { Vector3 } from '../math/Vector3';
 import { LineSegments } from '../objects/LineSegments';
 import { LineSegments } from '../objects/LineSegments';
@@ -5,11 +10,6 @@ import { LineBasicMaterial } from '../materials/LineBasicMaterial';
 import { Float32BufferAttribute } from '../core/BufferAttribute';
 import { Float32BufferAttribute } from '../core/BufferAttribute';
 import { BufferGeometry } from '../core/BufferGeometry';
 import { BufferGeometry } from '../core/BufferGeometry';
 
 
-/**
- * @author mrdoob / http://mrdoob.com/
- * @author WestLangley / http://github.com/WestLangley
-*/
-
 function FaceNormalsHelper( object, size, hex, linewidth ) {
 function FaceNormalsHelper( object, size, hex, linewidth ) {
 
 
 	// FaceNormalsHelper only supports THREE.Geometry
 	// FaceNormalsHelper only supports THREE.Geometry

+ 4 - 4
src/helpers/GridHelper.js

@@ -1,3 +1,7 @@
+/**
+ * @author mrdoob / http://mrdoob.com/
+ */
+
 import { LineSegments } from '../objects/LineSegments';
 import { LineSegments } from '../objects/LineSegments';
 import { VertexColors } from '../constants';
 import { VertexColors } from '../constants';
 import { LineBasicMaterial } from '../materials/LineBasicMaterial';
 import { LineBasicMaterial } from '../materials/LineBasicMaterial';
@@ -5,10 +9,6 @@ import { Float32BufferAttribute } from '../core/BufferAttribute';
 import { BufferGeometry } from '../core/BufferGeometry';
 import { BufferGeometry } from '../core/BufferGeometry';
 import { Color } from '../math/Color';
 import { Color } from '../math/Color';
 
 
-/**
- * @author mrdoob / http://mrdoob.com/
- */
-
 function GridHelper( size, divisions, color1, color2 ) {
 function GridHelper( size, divisions, color1, color2 ) {
 
 
 	size = size || 10;
 	size = size || 10;

+ 6 - 6
src/helpers/HemisphereLightHelper.js

@@ -1,3 +1,9 @@
+/**
+ * @author alteredq / http://alteredqualia.com/
+ * @author mrdoob / http://mrdoob.com/
+ * @author Mugen87 / https://github.com/Mugen87
+ */
+
 import { Vector3 } from '../math/Vector3';
 import { Vector3 } from '../math/Vector3';
 import { Color } from '../math/Color';
 import { Color } from '../math/Color';
 import { Object3D } from '../core/Object3D';
 import { Object3D } from '../core/Object3D';
@@ -7,12 +13,6 @@ import { MeshBasicMaterial } from '../materials/MeshBasicMaterial';
 import { OctahedronBufferGeometry } from '../geometries/OctahedronGeometry';
 import { OctahedronBufferGeometry } from '../geometries/OctahedronGeometry';
 import { BufferAttribute } from '../core/BufferAttribute';
 import { BufferAttribute } from '../core/BufferAttribute';
 
 
-/**
- * @author alteredq / http://alteredqualia.com/
- * @author mrdoob / http://mrdoob.com/
- * @author Mugen87 / https://github.com/Mugen87
- */
-
 function HemisphereLightHelper( light, size, color ) {
 function HemisphereLightHelper( light, size, color ) {
 
 
 	Object3D.call( this );
 	Object3D.call( this );

+ 60 - 0
src/helpers/PlaneHelper.js

@@ -0,0 +1,60 @@
+/**
+ * @author WestLangley / http://github.com/WestLangley
+ */
+ 
+import { Box3 } from '../math/Box3';
+import { Line } from '../objects/Line';
+import { LineBasicMaterial } from '../materials/LineBasicMaterial';
+import { Float32BufferAttribute } from '../core/BufferAttribute';
+import { BufferGeometry } from '../core/BufferGeometry';
+
+function PlaneHelper( plane, size, hex ) {
+
+	this.type = 'PlaneHelper';
+
+	this.plane = plane;
+
+	this.size = ( size === undefined ) ? 1 : size;
+
+	var color = ( hex !== undefined ) ? hex : 0xffff00;
+
+	var positions = [ 1, - 1, 1, - 1, 1, 1, - 1, - 1, 1, 1, 1, 1, - 1, 1, 1, - 1, - 1, 1, 1, - 1, 1, 1, 1, 1, 0, 0, 1, 0, 0, 0 ];
+
+	var geometry = new BufferGeometry();
+	geometry.addAttribute( 'position', new Float32BufferAttribute( positions, 3 ) );
+	geometry.computeBoundingSphere();
+
+	Line.call( this, geometry, new LineBasicMaterial( { color: color } ) );
+
+	//
+
+	var positions2 = [ 1, 1, 1, - 1, 1, 1, - 1, - 1, 1, 1, 1, 1, - 1, - 1, 1, 1, - 1, 1 ];
+
+	var geometry2 = new BufferGeometry();
+	geometry2.addAttribute( 'position', new Float32BufferAttribute( positions2, 3 ) );
+	geometry2.computeBoundingSphere();
+
+	this.add( new THREE.Mesh( geometry2, new LineBasicMaterial( { color: color, opacity: 0.2, transparent: true, depthWrite: false } ) ) );
+
+	//
+
+	this.onBeforeRender();
+
+}
+
+PlaneHelper.prototype = Object.create( Line.prototype );
+PlaneHelper.prototype.constructor = PlaneHelper;
+
+PlaneHelper.prototype.onBeforeRender = function () {
+
+	var scale = - this.plane.constant;
+
+	if ( Math.abs( scale ) < 1e-8 ) scale = 1e-8; // sign does not matter
+
+	this.scale.set( 0.5 * this.size, 0.5 * this.size, scale );
+
+	this.lookAt( this.plane.normal );
+
+};
+
+export { PlaneHelper };

+ 4 - 4
src/helpers/PointLightHelper.js

@@ -1,12 +1,12 @@
-import { Mesh } from '../objects/Mesh';
-import { MeshBasicMaterial } from '../materials/MeshBasicMaterial';
-import { SphereBufferGeometry } from '../geometries/SphereGeometry';
-
 /**
 /**
  * @author alteredq / http://alteredqualia.com/
  * @author alteredq / http://alteredqualia.com/
  * @author mrdoob / http://mrdoob.com/
  * @author mrdoob / http://mrdoob.com/
  */
  */
 
 
+import { Mesh } from '../objects/Mesh';
+import { MeshBasicMaterial } from '../materials/MeshBasicMaterial';
+import { SphereBufferGeometry } from '../geometries/SphereGeometry';
+
 function PointLightHelper( light, sphereSize, color ) {
 function PointLightHelper( light, sphereSize, color ) {
 
 
 	this.light = light;
 	this.light = light;

+ 6 - 6
src/helpers/PolarGridHelper.js

@@ -1,3 +1,9 @@
+/**
+ * @author mrdoob / http://mrdoob.com/
+ * @author Mugen87 / http://github.com/Mugen87
+ * @author Hectate / http://www.github.com/Hectate
+ */
+
 import { LineSegments } from '../objects/LineSegments';
 import { LineSegments } from '../objects/LineSegments';
 import { VertexColors } from '../constants';
 import { VertexColors } from '../constants';
 import { LineBasicMaterial } from '../materials/LineBasicMaterial';
 import { LineBasicMaterial } from '../materials/LineBasicMaterial';
@@ -5,12 +11,6 @@ import { Float32BufferAttribute } from '../core/BufferAttribute';
 import { BufferGeometry } from '../core/BufferGeometry';
 import { BufferGeometry } from '../core/BufferGeometry';
 import { Color } from '../math/Color';
 import { Color } from '../math/Color';
 
 
-/**
- * @author mrdoob / http://mrdoob.com/
- * @author Mugen87 / http://github.com/Mugen87
- * @author Hectate / http://www.github.com/Hectate
- */
-
 function PolarGridHelper( radius, radials, circles, divisions, color1, color2 ) {
 function PolarGridHelper( radius, radials, circles, divisions, color1, color2 ) {
 
 
 	radius = radius || 10;
 	radius = radius || 10;

+ 8 - 8
src/helpers/SkeletonHelper.js

@@ -1,3 +1,11 @@
+/**
+ * @author Sean Griffin / http://twitter.com/sgrif
+ * @author Michael Guerrero / http://realitymeltdown.com
+ * @author mrdoob / http://mrdoob.com/
+ * @author ikerr / http://verold.com
+ * @author Mugen87 / https://github.com/Mugen87
+ */
+
 import { LineSegments } from '../objects/LineSegments';
 import { LineSegments } from '../objects/LineSegments';
 import { Matrix4 } from '../math/Matrix4';
 import { Matrix4 } from '../math/Matrix4';
 import { VertexColors } from '../constants';
 import { VertexColors } from '../constants';
@@ -7,14 +15,6 @@ import { Vector3 } from '../math/Vector3';
 import { BufferGeometry } from '../core/BufferGeometry';
 import { BufferGeometry } from '../core/BufferGeometry';
 import { Float32BufferAttribute } from '../core/BufferAttribute';
 import { Float32BufferAttribute } from '../core/BufferAttribute';
 
 
-/**
- * @author Sean Griffin / http://twitter.com/sgrif
- * @author Michael Guerrero / http://realitymeltdown.com
- * @author mrdoob / http://mrdoob.com/
- * @author ikerr / http://verold.com
- * @author Mugen87 / https://github.com/Mugen87
- */
-
 function getBoneList( object ) {
 function getBoneList( object ) {
 
 
 	var boneList = [];
 	var boneList = [];

+ 6 - 6
src/helpers/SpotLightHelper.js

@@ -1,3 +1,9 @@
+/**
+ * @author alteredq / http://alteredqualia.com/
+ * @author mrdoob / http://mrdoob.com/
+ * @author WestLangley / http://github.com/WestLangley
+ */
+
 import { Vector3 } from '../math/Vector3';
 import { Vector3 } from '../math/Vector3';
 import { Object3D } from '../core/Object3D';
 import { Object3D } from '../core/Object3D';
 import { LineSegments } from '../objects/LineSegments';
 import { LineSegments } from '../objects/LineSegments';
@@ -5,12 +11,6 @@ import { LineBasicMaterial } from '../materials/LineBasicMaterial';
 import { Float32BufferAttribute } from '../core/BufferAttribute';
 import { Float32BufferAttribute } from '../core/BufferAttribute';
 import { BufferGeometry } from '../core/BufferGeometry';
 import { BufferGeometry } from '../core/BufferGeometry';
 
 
-/**
- * @author alteredq / http://alteredqualia.com/
- * @author mrdoob / http://mrdoob.com/
- * @author WestLangley / http://github.com/WestLangley
-*/
-
 function SpotLightHelper( light, color ) {
 function SpotLightHelper( light, color ) {
 
 
 	Object3D.call( this );
 	Object3D.call( this );

+ 5 - 5
src/helpers/VertexNormalsHelper.js

@@ -1,3 +1,8 @@
+/**
+ * @author mrdoob / http://mrdoob.com/
+ * @author WestLangley / http://github.com/WestLangley
+ */
+
 import { Matrix3 } from '../math/Matrix3';
 import { Matrix3 } from '../math/Matrix3';
 import { Vector3 } from '../math/Vector3';
 import { Vector3 } from '../math/Vector3';
 import { LineSegments } from '../objects/LineSegments';
 import { LineSegments } from '../objects/LineSegments';
@@ -5,11 +10,6 @@ import { LineBasicMaterial } from '../materials/LineBasicMaterial';
 import { Float32BufferAttribute } from '../core/BufferAttribute';
 import { Float32BufferAttribute } from '../core/BufferAttribute';
 import { BufferGeometry } from '../core/BufferGeometry';
 import { BufferGeometry } from '../core/BufferGeometry';
 
 
-/**
- * @author mrdoob / http://mrdoob.com/
- * @author WestLangley / http://github.com/WestLangley
-*/
-
 function VertexNormalsHelper( object, size, hex, linewidth ) {
 function VertexNormalsHelper( object, size, hex, linewidth ) {
 
 
 	this.object = object;
 	this.object = object;

+ 1 - 1
src/materials/MeshNormalMaterial.js

@@ -29,7 +29,7 @@ import { Vector2 } from '../math/Vector2';
 
 
 function MeshNormalMaterial( parameters ) {
 function MeshNormalMaterial( parameters ) {
 
 
-	Material.call( this, parameters );
+	Material.call( this );
 
 
 	this.type = 'MeshNormalMaterial';
 	this.type = 'MeshNormalMaterial';
 
 

+ 2 - 2
src/math/Matrix3.js

@@ -184,7 +184,7 @@ Object.assign( Matrix3.prototype, {
 
 
 		if ( matrix && matrix.isMatrix4 ) {
 		if ( matrix && matrix.isMatrix4 ) {
 
 
-			console.error( "THREE.Matrix3.getInverse no longer takes a Matrix4 argument." );
+			console.error( "THREE.Matrix3: .getInverse() no longer takes a Matrix4 argument." );
 
 
 		}
 		}
 
 
@@ -203,7 +203,7 @@ Object.assign( Matrix3.prototype, {
 
 
 		if ( det === 0 ) {
 		if ( det === 0 ) {
 
 
-			var msg = "THREE.Matrix3.getInverse(): can't invert matrix, determinant is 0";
+			var msg = "THREE.Matrix3: .getInverse() can't invert matrix, determinant is 0";
 
 
 			if ( throwOnDegenerate === true ) {
 			if ( throwOnDegenerate === true ) {
 
 

+ 14 - 4
src/math/Matrix4.js

@@ -154,7 +154,7 @@ Object.assign( Matrix4.prototype, {
 
 
 		if ( ! ( euler && euler.isEuler ) ) {
 		if ( ! ( euler && euler.isEuler ) ) {
 
 
-			console.error( 'THREE.Matrix: .makeRotationFromEuler() now expects a Euler rotation rather than a Vector3 and order.' );
+			console.error( 'THREE.Matrix4: .makeRotationFromEuler() now expects a Euler rotation rather than a Vector3 and order.' );
 
 
 		}
 		}
 
 
@@ -340,9 +340,19 @@ Object.assign( Matrix4.prototype, {
 
 
 			if ( x.lengthSq() === 0 ) {
 			if ( x.lengthSq() === 0 ) {
 
 
-				// eye and target are in the same vertical
+				// up and z are parallel
 
 
-				z.z += 0.0001;
+				if ( Math.abs( up.z ) === 1 ) {
+
+					z.x += 0.0001;
+
+				} else {
+
+					z.z += 0.0001;
+
+				}
+
+				z.normalize();
 				x.crossVectors( up, z );
 				x.crossVectors( up, z );
 
 
 			}
 			}
@@ -555,7 +565,7 @@ Object.assign( Matrix4.prototype, {
 
 
 		if ( det === 0 ) {
 		if ( det === 0 ) {
 
 
-			var msg = "THREE.Matrix4.getInverse(): can't invert matrix, determinant is 0";
+			var msg = "THREE.Matrix4: .getInverse() can't invert matrix, determinant is 0";
 
 
 			if ( throwOnDegenerate === true ) {
 			if ( throwOnDegenerate === true ) {
 
 

+ 7 - 15
src/math/Plane.js

@@ -35,7 +35,7 @@ Object.assign( Plane.prototype, {
 	setFromNormalAndCoplanarPoint: function ( normal, point ) {
 	setFromNormalAndCoplanarPoint: function ( normal, point ) {
 
 
 		this.normal.copy( normal );
 		this.normal.copy( normal );
-		this.constant = - point.dot( this.normal );	// must be this.normal, not normal, as this.normal is normalized
+		this.constant = - point.dot( this.normal );
 
 
 		return this;
 		return this;
 
 
@@ -110,16 +110,9 @@ Object.assign( Plane.prototype, {
 
 
 	projectPoint: function ( point, optionalTarget ) {
 	projectPoint: function ( point, optionalTarget ) {
 
 
-		return this.orthoPoint( point, optionalTarget ).sub( point ).negate();
-
-	},
-
-	orthoPoint: function ( point, optionalTarget ) {
-
-		var perpendicularMagnitude = this.distanceToPoint( point );
-
 		var result = optionalTarget || new Vector3();
 		var result = optionalTarget || new Vector3();
-		return result.copy( this.normal ).multiplyScalar( perpendicularMagnitude );
+
+		return result.copy( this.normal ).multiplyScalar( - this.distanceToPoint( point ) ).add( point );
 
 
 	},
 	},
 
 
@@ -189,6 +182,7 @@ Object.assign( Plane.prototype, {
 	coplanarPoint: function ( optionalTarget ) {
 	coplanarPoint: function ( optionalTarget ) {
 
 
 		var result = optionalTarget || new Vector3();
 		var result = optionalTarget || new Vector3();
+
 		return result.copy( this.normal ).multiplyScalar( - this.constant );
 		return result.copy( this.normal ).multiplyScalar( - this.constant );
 
 
 	},
 	},
@@ -200,14 +194,12 @@ Object.assign( Plane.prototype, {
 
 
 		return function applyMatrix4( matrix, optionalNormalMatrix ) {
 		return function applyMatrix4( matrix, optionalNormalMatrix ) {
 
 
+			var normalMatrix = optionalNormalMatrix || m1.getNormalMatrix( matrix );
+
 			var referencePoint = this.coplanarPoint( v1 ).applyMatrix4( matrix );
 			var referencePoint = this.coplanarPoint( v1 ).applyMatrix4( matrix );
 
 
-			// transform normal based on theory here:
-			// http://www.songho.ca/opengl/gl_normaltransform.html
-			var normalMatrix = optionalNormalMatrix || m1.getNormalMatrix( matrix );
 			var normal = this.normal.applyMatrix3( normalMatrix ).normalize();
 			var normal = this.normal.applyMatrix3( normalMatrix ).normalize();
 
 
-			// recalculate constant (like in setFromNormalAndCoplanarPoint)
 			this.constant = - referencePoint.dot( normal );
 			this.constant = - referencePoint.dot( normal );
 
 
 			return this;
 			return this;
@@ -218,7 +210,7 @@ Object.assign( Plane.prototype, {
 
 
 	translate: function ( offset ) {
 	translate: function ( offset ) {
 
 
-		this.constant = this.constant - offset.dot( this.normal );
+		this.constant -= offset.dot( this.normal );
 
 
 		return this;
 		return this;
 
 

+ 4 - 4
src/math/Vector2.js

@@ -257,7 +257,7 @@ Object.assign( Vector2.prototype, {
 
 
 	clamp: function ( min, max ) {
 	clamp: function ( min, max ) {
 
 
-		// This function assumes min < max, if this assumption isn't true it will not operate correctly
+		// assumes min < max, componentwise
 
 
 		this.x = Math.max( min.x, Math.min( max.x, this.x ) );
 		this.x = Math.max( min.x, Math.min( max.x, this.x ) );
 		this.y = Math.max( min.y, Math.min( max.y, this.y ) );
 		this.y = Math.max( min.y, Math.min( max.y, this.y ) );
@@ -286,7 +286,7 @@ Object.assign( Vector2.prototype, {
 
 
 		var length = this.length();
 		var length = this.length();
 
 
-		return this.multiplyScalar( Math.max( min, Math.min( max, length ) ) / length );
+		return this.divideScalar( length || 1 ).multiplyScalar( Math.max( min, Math.min( max, length ) ) );
 
 
 	},
 	},
 
 
@@ -361,7 +361,7 @@ Object.assign( Vector2.prototype, {
 
 
 	normalize: function () {
 	normalize: function () {
 
 
-		return this.divideScalar( this.length() );
+		return this.divideScalar( this.length() || 1 );
 
 
 	},
 	},
 
 
@@ -398,7 +398,7 @@ Object.assign( Vector2.prototype, {
 
 
 	setLength: function ( length ) {
 	setLength: function ( length ) {
 
 
-		return this.multiplyScalar( length / this.length() );
+		return this.normalize().multiplyScalar( length );
 
 
 	},
 	},
 
 

+ 17 - 11
src/math/Vector3.js

@@ -280,12 +280,13 @@ Object.assign( Vector3.prototype, {
 		var x = this.x, y = this.y, z = this.z;
 		var x = this.x, y = this.y, z = this.z;
 		var e = m.elements;
 		var e = m.elements;
 
 
-		this.x = e[ 0 ] * x + e[ 4 ] * y + e[ 8 ]  * z + e[ 12 ];
-		this.y = e[ 1 ] * x + e[ 5 ] * y + e[ 9 ]  * z + e[ 13 ];
-		this.z = e[ 2 ] * x + e[ 6 ] * y + e[ 10 ] * z + e[ 14 ];
-		var w =  e[ 3 ] * x + e[ 7 ] * y + e[ 11 ] * z + e[ 15 ];
+		var w = 1 / ( e[ 3 ] * x + e[ 7 ] * y + e[ 11 ] * z + e[ 15 ] );
 
 
-		return this.divideScalar( w );
+		this.x = ( e[ 0 ] * x + e[ 4 ] * y + e[ 8 ]  * z + e[ 12 ] ) * w;
+		this.y = ( e[ 1 ] * x + e[ 5 ] * y + e[ 9 ]  * z + e[ 13 ] ) * w;
+		this.z = ( e[ 2 ] * x + e[ 6 ] * y + e[ 10 ] * z + e[ 14 ] ) * w;
+
+		return this;
 
 
 	},
 	},
 
 
@@ -391,7 +392,7 @@ Object.assign( Vector3.prototype, {
 
 
 	clamp: function ( min, max ) {
 	clamp: function ( min, max ) {
 
 
-		// This function assumes min < max, if this assumption isn't true it will not operate correctly
+		// assumes min < max, componentwise
 
 
 		this.x = Math.max( min.x, Math.min( max.x, this.x ) );
 		this.x = Math.max( min.x, Math.min( max.x, this.x ) );
 		this.y = Math.max( min.y, Math.min( max.y, this.y ) );
 		this.y = Math.max( min.y, Math.min( max.y, this.y ) );
@@ -421,7 +422,7 @@ Object.assign( Vector3.prototype, {
 
 
 		var length = this.length();
 		var length = this.length();
 
 
-		return this.multiplyScalar( Math.max( min, Math.min( max, length ) ) / length );
+		return this.divideScalar( length || 1 ).multiplyScalar( Math.max( min, Math.min( max, length ) ) );
 
 
 	},
 	},
 
 
@@ -503,13 +504,13 @@ Object.assign( Vector3.prototype, {
 
 
 	normalize: function () {
 	normalize: function () {
 
 
-		return this.divideScalar( this.length() );
+		return this.divideScalar( this.length() || 1 );
 
 
 	},
 	},
 
 
 	setLength: function ( length ) {
 	setLength: function ( length ) {
 
 
-		return this.multiplyScalar( length / this.length() );
+		return this.normalize().multiplyScalar( length );
 
 
 	},
 	},
 
 
@@ -652,7 +653,13 @@ Object.assign( Vector3.prototype, {
 
 
 	setFromMatrixPosition: function ( m ) {
 	setFromMatrixPosition: function ( m ) {
 
 
-		return this.setFromMatrixColumn( m, 3 );
+		var e = m.elements;
+
+		this.x = e[ 12 ];
+		this.y = e[ 13 ];
+		this.z = e[ 14 ];
+
+		return this;
 
 
 	},
 	},
 
 
@@ -672,7 +679,6 @@ Object.assign( Vector3.prototype, {
 
 
 	setFromMatrixColumn: function ( m, index ) {
 	setFromMatrixColumn: function ( m, index ) {
 
 
-
 		return this.fromArray( m.elements, index * 4 );
 		return this.fromArray( m.elements, index * 4 );
 
 
 	},
 	},

+ 19 - 5
src/math/Vector4.js

@@ -424,7 +424,7 @@ Object.assign( Vector4.prototype, {
 
 
 	clamp: function ( min, max ) {
 	clamp: function ( min, max ) {
 
 
-		// This function assumes min < max, if this assumption isn't true it will not operate correctly
+		// assumes min < max, componentwise
 
 
 		this.x = Math.max( min.x, Math.min( max.x, this.x ) );
 		this.x = Math.max( min.x, Math.min( max.x, this.x ) );
 		this.y = Math.max( min.y, Math.min( max.y, this.y ) );
 		this.y = Math.max( min.y, Math.min( max.y, this.y ) );
@@ -437,11 +437,17 @@ Object.assign( Vector4.prototype, {
 
 
 	clampScalar: function () {
 	clampScalar: function () {
 
 
-		var min = new Vector4();
-		var max = new Vector4();
+		var min, max;
 
 
 		return function clampScalar( minVal, maxVal ) {
 		return function clampScalar( minVal, maxVal ) {
 
 
+			if ( min === undefined ) {
+
+				min = new Vector4();
+				max = new Vector4();
+
+			}
+
 			min.set( minVal, minVal, minVal, minVal );
 			min.set( minVal, minVal, minVal, minVal );
 			max.set( maxVal, maxVal, maxVal, maxVal );
 			max.set( maxVal, maxVal, maxVal, maxVal );
 
 
@@ -451,6 +457,14 @@ Object.assign( Vector4.prototype, {
 
 
 	}(),
 	}(),
 
 
+	clampLength: function ( min, max ) {
+
+		var length = this.length();
+
+		return this.divideScalar( length || 1 ).multiplyScalar( Math.max( min, Math.min( max, length ) ) );
+
+	},
+
 	floor: function () {
 	floor: function () {
 
 
 		this.x = Math.floor( this.x );
 		this.x = Math.floor( this.x );
@@ -532,13 +546,13 @@ Object.assign( Vector4.prototype, {
 
 
 	normalize: function () {
 	normalize: function () {
 
 
-		return this.divideScalar( this.length() );
+		return this.divideScalar( this.length() || 1 );
 
 
 	},
 	},
 
 
 	setLength: function ( length ) {
 	setLength: function ( length ) {
 
 
-		return this.multiplyScalar( length / this.length() );
+		return this.normalize().multiplyScalar( length );
 
 
 	},
 	},
 
 

+ 3 - 4
src/objects/Mesh.js

@@ -147,10 +147,9 @@ Mesh.prototype = Object.assign( Object.create( Object3D.prototype ), {
 
 
 		}
 		}
 
 
-		function checkIntersection( object, raycaster, ray, pA, pB, pC, point ) {
+		function checkIntersection( object, material, raycaster, ray, pA, pB, pC, point ) {
 
 
 			var intersect;
 			var intersect;
-			var material = object.material;
 
 
 			if ( material.side === BackSide ) {
 			if ( material.side === BackSide ) {
 
 
@@ -185,7 +184,7 @@ Mesh.prototype = Object.assign( Object.create( Object3D.prototype ), {
 			vB.fromBufferAttribute( position, b );
 			vB.fromBufferAttribute( position, b );
 			vC.fromBufferAttribute( position, c );
 			vC.fromBufferAttribute( position, c );
 
 
-			var intersection = checkIntersection( object, raycaster, ray, vA, vB, vC, intersectionPoint );
+			var intersection = checkIntersection( object, object.material, raycaster, ray, vA, vB, vC, intersectionPoint );
 
 
 			if ( intersection ) {
 			if ( intersection ) {
 
 
@@ -348,7 +347,7 @@ Mesh.prototype = Object.assign( Object.create( Object3D.prototype ), {
 
 
 					}
 					}
 
 
-					intersection = checkIntersection( this, raycaster, ray, fvA, fvB, fvC, intersectionPoint );
+					intersection = checkIntersection( this, faceMaterial, raycaster, ray, fvA, fvB, fvC, intersectionPoint );
 
 
 					if ( intersection ) {
 					if ( intersection ) {
 
 

+ 98 - 141
src/renderers/WebGLRenderer.js

@@ -1,4 +1,4 @@
-import { REVISION, MaxEquation, MinEquation, RGB_ETC1_Format, RGBA_PVRTC_2BPPV1_Format, RGBA_PVRTC_4BPPV1_Format, RGB_PVRTC_2BPPV1_Format, RGB_PVRTC_4BPPV1_Format, RGBA_S3TC_DXT5_Format, RGBA_S3TC_DXT3_Format, RGBA_S3TC_DXT1_Format, RGB_S3TC_DXT1_Format, SrcAlphaSaturateFactor, OneMinusDstColorFactor, DstColorFactor, OneMinusDstAlphaFactor, DstAlphaFactor, OneMinusSrcAlphaFactor, SrcAlphaFactor, OneMinusSrcColorFactor, SrcColorFactor, OneFactor, ZeroFactor, ReverseSubtractEquation, SubtractEquation, AddEquation, DepthFormat, DepthStencilFormat, LuminanceAlphaFormat, LuminanceFormat, RGBAFormat, RGBFormat, AlphaFormat, HalfFloatType, FloatType, UnsignedIntType, IntType, UnsignedShortType, ShortType, ByteType, UnsignedInt248Type, UnsignedShort565Type, UnsignedShort5551Type, UnsignedShort4444Type, UnsignedByteType, LinearMipMapLinearFilter, LinearMipMapNearestFilter, LinearFilter, NearestMipMapLinearFilter, NearestMipMapNearestFilter, NearestFilter, MirroredRepeatWrapping, ClampToEdgeWrapping, RepeatWrapping, FrontFaceDirectionCW, NoBlending, BackSide, TriangleFanDrawMode, TriangleStripDrawMode, TrianglesDrawMode, NoColors, FlatShading, LinearToneMapping } from '../constants';
+import { REVISION, MaxEquation, MinEquation, RGB_ETC1_Format, RGBA_PVRTC_2BPPV1_Format, RGBA_PVRTC_4BPPV1_Format, RGB_PVRTC_2BPPV1_Format, RGB_PVRTC_4BPPV1_Format, RGBA_S3TC_DXT5_Format, RGBA_S3TC_DXT3_Format, RGBA_S3TC_DXT1_Format, RGB_S3TC_DXT1_Format, SrcAlphaSaturateFactor, OneMinusDstColorFactor, DstColorFactor, OneMinusDstAlphaFactor, DstAlphaFactor, OneMinusSrcAlphaFactor, SrcAlphaFactor, OneMinusSrcColorFactor, SrcColorFactor, OneFactor, ZeroFactor, ReverseSubtractEquation, SubtractEquation, AddEquation, DepthFormat, DepthStencilFormat, LuminanceAlphaFormat, LuminanceFormat, RGBAFormat, RGBFormat, AlphaFormat, HalfFloatType, FloatType, UnsignedIntType, IntType, UnsignedShortType, ShortType, ByteType, UnsignedInt248Type, UnsignedShort565Type, UnsignedShort5551Type, UnsignedShort4444Type, UnsignedByteType, LinearMipMapLinearFilter, LinearMipMapNearestFilter, LinearFilter, NearestMipMapLinearFilter, NearestMipMapNearestFilter, NearestFilter, MirroredRepeatWrapping, ClampToEdgeWrapping, RepeatWrapping, FrontFaceDirectionCW, NoBlending, TriangleFanDrawMode, TriangleStripDrawMode, TrianglesDrawMode, NoColors, FlatShading, LinearToneMapping } from '../constants';
 import { _Math } from '../math/Math';
 import { _Math } from '../math/Math';
 import { Matrix4 } from '../math/Matrix4';
 import { Matrix4 } from '../math/Matrix4';
 import { DataTexture } from '../textures/DataTexture';
 import { DataTexture } from '../textures/DataTexture';
@@ -9,14 +9,8 @@ import { ShaderLib } from './shaders/ShaderLib';
 import { LensFlarePlugin } from './webgl/plugins/LensFlarePlugin';
 import { LensFlarePlugin } from './webgl/plugins/LensFlarePlugin';
 import { SpritePlugin } from './webgl/plugins/SpritePlugin';
 import { SpritePlugin } from './webgl/plugins/SpritePlugin';
 import { WebGLShadowMap } from './webgl/WebGLShadowMap';
 import { WebGLShadowMap } from './webgl/WebGLShadowMap';
-import { ShaderMaterial } from '../materials/ShaderMaterial';
-import { Mesh } from '../objects/Mesh';
-import { BoxBufferGeometry } from '../geometries/BoxGeometry';
-import { PlaneBufferGeometry } from '../geometries/PlaneGeometry';
-import { MeshBasicMaterial } from '../materials/MeshBasicMaterial';
-import { PerspectiveCamera } from '../cameras/PerspectiveCamera';
-import { OrthographicCamera } from '../cameras/OrthographicCamera';
 import { WebGLAttributes } from './webgl/WebGLAttributes';
 import { WebGLAttributes } from './webgl/WebGLAttributes';
+import { WebGLBackground } from './webgl/WebGLBackground';
 import { WebGLRenderLists } from './webgl/WebGLRenderLists';
 import { WebGLRenderLists } from './webgl/WebGLRenderLists';
 import { WebGLIndexedBufferRenderer } from './webgl/WebGLIndexedBufferRenderer';
 import { WebGLIndexedBufferRenderer } from './webgl/WebGLIndexedBufferRenderer';
 import { WebGLBufferRenderer } from './webgl/WebGLBufferRenderer';
 import { WebGLBufferRenderer } from './webgl/WebGLBufferRenderer';
@@ -28,6 +22,7 @@ import { WebGLTextures } from './webgl/WebGLTextures';
 import { WebGLProperties } from './webgl/WebGLProperties';
 import { WebGLProperties } from './webgl/WebGLProperties';
 import { WebGLState } from './webgl/WebGLState';
 import { WebGLState } from './webgl/WebGLState';
 import { WebGLCapabilities } from './webgl/WebGLCapabilities';
 import { WebGLCapabilities } from './webgl/WebGLCapabilities';
+import { WebVRManager } from './webvr/WebVRManager';
 import { BufferGeometry } from '../core/BufferGeometry';
 import { BufferGeometry } from '../core/BufferGeometry';
 import { WebGLExtensions } from './webgl/WebGLExtensions';
 import { WebGLExtensions } from './webgl/WebGLExtensions';
 import { Vector3 } from '../math/Vector3';
 import { Vector3 } from '../math/Vector3';
@@ -35,7 +30,6 @@ import { Vector3 } from '../math/Vector3';
 import { WebGLClipping } from './webgl/WebGLClipping';
 import { WebGLClipping } from './webgl/WebGLClipping';
 import { Frustum } from '../math/Frustum';
 import { Frustum } from '../math/Frustum';
 import { Vector4 } from '../math/Vector4';
 import { Vector4 } from '../math/Vector4';
-import { Color } from '../math/Color';
 
 
 /**
 /**
  * @author supereggbert / http://www.paulbrunt.co.uk/
  * @author supereggbert / http://www.paulbrunt.co.uk/
@@ -123,7 +117,9 @@ function WebGLRenderer( parameters ) {
 		_currentFramebuffer = null,
 		_currentFramebuffer = null,
 		_currentMaterialId = - 1,
 		_currentMaterialId = - 1,
 		_currentGeometryProgram = '',
 		_currentGeometryProgram = '',
+
 		_currentCamera = null,
 		_currentCamera = null,
+		_currentArrayCamera = null,
 
 
 		_currentScissor = new Vector4(),
 		_currentScissor = new Vector4(),
 		_currentScissorTest = null,
 		_currentScissorTest = null,
@@ -136,9 +132,6 @@ function WebGLRenderer( parameters ) {
 
 
 		//
 		//
 
 
-		_clearColor = new Color( 0x000000 ),
-		_clearAlpha = 0,
-
 		_width = _canvas.width,
 		_width = _canvas.width,
 		_height = _canvas.height,
 		_height = _canvas.height,
 
 
@@ -296,6 +289,9 @@ function WebGLRenderer( parameters ) {
 	var lightCache = new WebGLLights();
 	var lightCache = new WebGLLights();
 	var renderLists = new WebGLRenderLists();
 	var renderLists = new WebGLRenderLists();
 
 
+	var background = new WebGLBackground( this, state, objects, _premultipliedAlpha );
+	var vr = new WebVRManager( this );
+
 	this.info.programs = programCache.programs;
 	this.info.programs = programCache.programs;
 
 
 	var bufferRenderer = new WebGLBufferRenderer( _gl, extensions, _infoRender );
 	var bufferRenderer = new WebGLBufferRenderer( _gl, extensions, _infoRender );
@@ -303,11 +299,6 @@ function WebGLRenderer( parameters ) {
 
 
 	//
 	//
 
 
-	var backgroundPlaneCamera, backgroundPlaneMesh;
-	var backgroundBoxCamera, backgroundBoxMesh;
-
-	//
-
 	function getTargetPixelRatio() {
 	function getTargetPixelRatio() {
 
 
 		return _currentRenderTarget === null ? _pixelRatio : 1;
 		return _currentRenderTarget === null ? _pixelRatio : 1;
@@ -321,8 +312,6 @@ function WebGLRenderer( parameters ) {
 		state.scissor( _currentScissor.copy( _scissor ).multiplyScalar( _pixelRatio ) );
 		state.scissor( _currentScissor.copy( _scissor ).multiplyScalar( _pixelRatio ) );
 		state.viewport( _currentViewport.copy( _viewport ).multiplyScalar( _pixelRatio ) );
 		state.viewport( _currentViewport.copy( _viewport ).multiplyScalar( _pixelRatio ) );
 
 
-		state.buffers.color.setClear( _clearColor.r, _clearColor.g, _clearColor.b, _clearAlpha, _premultipliedAlpha );
-
 	}
 	}
 
 
 	function resetGLState() {
 	function resetGLState() {
@@ -345,6 +334,7 @@ function WebGLRenderer( parameters ) {
 	this.properties = properties;
 	this.properties = properties;
 	this.renderLists = renderLists;
 	this.renderLists = renderLists;
 	this.state = state;
 	this.state = state;
+	this.vr = vr;
 
 
 	// shadow map
 	// shadow map
 
 
@@ -418,6 +408,15 @@ function WebGLRenderer( parameters ) {
 
 
 	this.setSize = function ( width, height, updateStyle ) {
 	this.setSize = function ( width, height, updateStyle ) {
 
 
+		var device = vr.getDevice();
+
+		if ( device && device.isPresenting ) {
+
+			console.warn( 'THREE.WebGLRenderer: Can\'t change size while VR device is presenting.' );
+			return;
+
+		}
+
 		_width = width;
 		_width = width;
 		_height = height;
 		_height = height;
 
 
@@ -435,57 +434,55 @@ function WebGLRenderer( parameters ) {
 
 
 	};
 	};
 
 
-	this.setViewport = function ( x, y, width, height ) {
+	this.getDrawingBufferSize = function () {
 
 
-		_viewport.set( x, _height - y - height, width, height )
-		state.viewport( _currentViewport.copy( _viewport ).multiplyScalar( _pixelRatio ) );
+		return {
+			width: _width * _pixelRatio,
+			height: _height * _pixelRatio
+		};
 
 
 	};
 	};
 
 
-	this.setScissor = function ( x, y, width, height ) {
+	this.setDrawingBufferSize = function ( width, height, pixelRatio ) {
 
 
-		_scissor.set( x, _height - y - height, width, height )
-		state.scissor( _currentScissor.copy( _scissor ).multiplyScalar( _pixelRatio ) );
+		_width = width;
+		_height = height;
 
 
-	};
+		_pixelRatio = pixelRatio;
 
 
-	this.setScissorTest = function ( boolean ) {
+		_canvas.width = width * pixelRatio;
+		_canvas.height = height * pixelRatio;
 
 
-		state.setScissorTest( _scissorTest = boolean );
+		this.setViewport( 0, 0, width, height );
 
 
 	};
 	};
 
 
-	// Clearing
-
-	this.getClearColor = function () {
+	this.setViewport = function ( x, y, width, height ) {
 
 
-		return _clearColor;
+		_viewport.set( x, _height - y - height, width, height )
+		state.viewport( _currentViewport.copy( _viewport ).multiplyScalar( _pixelRatio ) );
 
 
 	};
 	};
 
 
-	this.setClearColor = function ( color, alpha ) {
-
-		_clearColor.set( color );
-
-		_clearAlpha = alpha !== undefined ? alpha : 1;
+	this.setScissor = function ( x, y, width, height ) {
 
 
-		state.buffers.color.setClear( _clearColor.r, _clearColor.g, _clearColor.b, _clearAlpha, _premultipliedAlpha );
+		_scissor.set( x, _height - y - height, width, height )
+		state.scissor( _currentScissor.copy( _scissor ).multiplyScalar( _pixelRatio ) );
 
 
 	};
 	};
 
 
-	this.getClearAlpha = function () {
+	this.setScissorTest = function ( boolean ) {
 
 
-		return _clearAlpha;
+		state.setScissorTest( _scissorTest = boolean );
 
 
 	};
 	};
 
 
-	this.setClearAlpha = function ( alpha ) {
-
-		_clearAlpha = alpha;
+	// Clearing
 
 
-		state.buffers.color.setClear( _clearColor.r, _clearColor.g, _clearColor.b, _clearAlpha, _premultipliedAlpha );
-
-	};
+	this.getClearColor = background.getClearColor;
+	this.setClearColor = background.setClearColor;
+	this.getClearAlpha = background.getClearAlpha;
+	this.setClearAlpha = background.setClearAlpha;
 
 
 	this.clear = function ( color, depth, stencil ) {
 	this.clear = function ( color, depth, stencil ) {
 
 
@@ -1082,6 +1079,20 @@ function WebGLRenderer( parameters ) {
 
 
 	// Rendering
 	// Rendering
 
 
+	this.animate = function ( callback ) {
+
+		function onFrame() {
+
+			callback();
+
+			( vr.getDevice() || window ).requestAnimationFrame( onFrame );
+
+		}
+
+		( vr.getDevice() || window ).requestAnimationFrame( onFrame );
+
+	};
+
 	this.render = function ( scene, camera, renderTarget, forceClear ) {
 	this.render = function ( scene, camera, renderTarget, forceClear ) {
 
 
 		if ( ! ( camera && camera.isCamera ) ) {
 		if ( ! ( camera && camera.isCamera ) ) {
@@ -1103,10 +1114,14 @@ function WebGLRenderer( parameters ) {
 
 
 		// update camera matrices and frustum
 		// update camera matrices and frustum
 
 
-		camera.onBeforeRender( _this );
-
 		if ( camera.parent === null ) camera.updateMatrixWorld();
 		if ( camera.parent === null ) camera.updateMatrixWorld();
 
 
+		if ( vr.enabled ) {
+
+			camera = vr.getCamera( camera );
+
+		}
+
 		_projScreenMatrix.multiplyMatrices( camera.projectionMatrix, camera.matrixWorldInverse );
 		_projScreenMatrix.multiplyMatrices( camera.projectionMatrix, camera.matrixWorldInverse );
 		_frustum.setFromMatrix( _projScreenMatrix );
 		_frustum.setFromMatrix( _projScreenMatrix );
 
 
@@ -1160,81 +1175,9 @@ function WebGLRenderer( parameters ) {
 
 
 		//
 		//
 
 
-		var background = scene.background;
-
-		if ( background === null ) {
-
-			state.buffers.color.setClear( _clearColor.r, _clearColor.g, _clearColor.b, _clearAlpha, _premultipliedAlpha );
-
-		} else if ( background && background.isColor ) {
-
-			state.buffers.color.setClear( background.r, background.g, background.b, 1, _premultipliedAlpha );
-			forceClear = true;
-
-		}
-
-		if ( this.autoClear || forceClear ) {
-
-			this.clear( this.autoClearColor, this.autoClearDepth, this.autoClearStencil );
-
-		}
-
-		if ( background && background.isCubeTexture ) {
-
-			if ( backgroundBoxCamera === undefined ) {
+		background.render( scene, camera, forceClear );
 
 
-				backgroundBoxCamera = new PerspectiveCamera();
-
-				backgroundBoxMesh = new Mesh(
-					new BoxBufferGeometry( 5, 5, 5 ),
-					new ShaderMaterial( {
-						uniforms: ShaderLib.cube.uniforms,
-						vertexShader: ShaderLib.cube.vertexShader,
-						fragmentShader: ShaderLib.cube.fragmentShader,
-						side: BackSide,
-						depthTest: false,
-						depthWrite: false,
-						fog: false
-					} )
-				);
-
-			}
-
-			backgroundBoxCamera.projectionMatrix.copy( camera.projectionMatrix );
-
-			backgroundBoxCamera.matrixWorld.extractRotation( camera.matrixWorld );
-			backgroundBoxCamera.matrixWorldInverse.getInverse( backgroundBoxCamera.matrixWorld );
-
-
-			backgroundBoxMesh.material.uniforms[ "tCube" ].value = background;
-			backgroundBoxMesh.modelViewMatrix.multiplyMatrices( backgroundBoxCamera.matrixWorldInverse, backgroundBoxMesh.matrixWorld );
-
-			objects.update( backgroundBoxMesh );
-
-			_this.renderBufferDirect( backgroundBoxCamera, null, backgroundBoxMesh.geometry, backgroundBoxMesh.material, backgroundBoxMesh, null );
-
-		} else if ( background && background.isTexture ) {
-
-			if ( backgroundPlaneCamera === undefined ) {
-
-				backgroundPlaneCamera = new OrthographicCamera( - 1, 1, 1, - 1, 0, 1 );
-
-				backgroundPlaneMesh = new Mesh(
-					new PlaneBufferGeometry( 2, 2 ),
-					new MeshBasicMaterial( { depthTest: false, depthWrite: false, fog: false } )
-				);
-
-			}
-
-			backgroundPlaneMesh.material.map = background;
-
-			objects.update( backgroundPlaneMesh );
-
-			_this.renderBufferDirect( backgroundPlaneCamera, null, backgroundPlaneMesh.geometry, backgroundPlaneMesh.material, backgroundPlaneMesh, null );
-
-		}
-
-		//
+		// render scene
 
 
 		var opaqueObjects = currentRenderList.opaque;
 		var opaqueObjects = currentRenderList.opaque;
 		var transparentObjects = currentRenderList.transparent;
 		var transparentObjects = currentRenderList.transparent;
@@ -1283,7 +1226,11 @@ function WebGLRenderer( parameters ) {
 
 
 		}
 		}
 
 
-		camera.onAfterRender( _this );
+		if ( vr.enabled ) {
+
+			vr.submitFrame();
+
+		}
 
 
 		// _gl.finish();
 		// _gl.finish();
 
 
@@ -1449,38 +1396,43 @@ function WebGLRenderer( parameters ) {
 			var material = overrideMaterial === undefined ? renderItem.material : overrideMaterial;
 			var material = overrideMaterial === undefined ? renderItem.material : overrideMaterial;
 			var group = renderItem.group;
 			var group = renderItem.group;
 
 
-			object.onBeforeRender( _this, scene, camera, geometry, material, group );
-
 			if ( camera.isArrayCamera ) {
 			if ( camera.isArrayCamera ) {
 
 
+				_currentArrayCamera = camera;
+
 				var cameras = camera.cameras;
 				var cameras = camera.cameras;
 
 
 				for ( var j = 0, jl = cameras.length; j < jl; j ++ ) {
 				for ( var j = 0, jl = cameras.length; j < jl; j ++ ) {
 
 
 					var camera2 = cameras[ j ];
 					var camera2 = cameras[ j ];
-					var bounds = camera2.bounds;
 
 
-					var x = bounds.x * _width;
-					var y = bounds.y * _height;
-					var width = bounds.z * _width;
-					var height = bounds.w * _height;
+					if ( object.layers.test( camera2.layers ) ) {
+
+						var bounds = camera2.bounds;
 
 
-					_this.setViewport( x, y, width, height );
-					_this.setScissor( x, y, width, height );
-					_this.setScissorTest( true );
+						var x = bounds.x * _width;
+						var y = bounds.y * _height;
+						var width = bounds.z * _width;
+						var height = bounds.w * _height;
 
 
-					renderObject( object, scene, camera2, geometry, material, group );
+						_this.setViewport( x, y, width, height );
+						_this.setScissor( x, y, width, height );
+						_this.setScissorTest( true );
+
+						renderObject( object, scene, camera2, geometry, material, group );
+
+					}
 
 
 				}
 				}
 
 
 			} else {
 			} else {
 
 
+				_currentArrayCamera = null;
+
 				renderObject( object, scene, camera, geometry, material, group );
 				renderObject( object, scene, camera, geometry, material, group );
 
 
 			}
 			}
 
 
-			object.onAfterRender( _this, scene, camera, geometry, material, group );
-
 		}
 		}
 
 
 	}
 	}
@@ -1490,6 +1442,8 @@ function WebGLRenderer( parameters ) {
 		object.modelViewMatrix.multiplyMatrices( camera.matrixWorldInverse, object.matrixWorld );
 		object.modelViewMatrix.multiplyMatrices( camera.matrixWorldInverse, object.matrixWorld );
 		object.normalMatrix.getNormalMatrix( object.modelViewMatrix );
 		object.normalMatrix.getNormalMatrix( object.modelViewMatrix );
 
 
+		object.onBeforeRender( _this, scene, camera, geometry, material, group );
+
 		if ( object.isImmediateRenderObject ) {
 		if ( object.isImmediateRenderObject ) {
 
 
 			state.setMaterial( material );
 			state.setMaterial( material );
@@ -1506,6 +1460,8 @@ function WebGLRenderer( parameters ) {
 
 
 		}
 		}
 
 
+		object.onAfterRender( _this, scene, camera, geometry, material, group );
+
 	}
 	}
 
 
 	function initMaterial( material, fog, object ) {
 	function initMaterial( material, fog, object ) {
@@ -1750,10 +1706,11 @@ function WebGLRenderer( parameters ) {
 
 
 			}
 			}
 
 
+			// Avoid unneeded uniform updates per ArrayCamera's sub-camera
 
 
-			if ( camera !== _currentCamera ) {
+			if ( _currentCamera !== ( _currentArrayCamera || camera ) ) {
 
 
-				_currentCamera = camera;
+				_currentCamera = ( _currentArrayCamera || camera );
 
 
 				// lighting uniforms depend on the camera so enforce an update
 				// lighting uniforms depend on the camera so enforce an update
 				// now, in case this material supports lights - or later, when
 				// now, in case this material supports lights - or later, when
@@ -1794,9 +1751,6 @@ function WebGLRenderer( parameters ) {
 
 
 			}
 			}
 
 
-			p_uniforms.setValue( _gl, 'toneMappingExposure', _this.toneMappingExposure );
-			p_uniforms.setValue( _gl, 'toneMappingWhitePoint', _this.toneMappingWhitePoint );
-
 		}
 		}
 
 
 		// skinning uniforms must be set even if material didn't change
 		// skinning uniforms must be set even if material didn't change
@@ -1856,6 +1810,9 @@ function WebGLRenderer( parameters ) {
 
 
 		if ( refreshMaterial ) {
 		if ( refreshMaterial ) {
 
 
+			p_uniforms.setValue( _gl, 'toneMappingExposure', _this.toneMappingExposure );
+			p_uniforms.setValue( _gl, 'toneMappingWhitePoint', _this.toneMappingWhitePoint );
+
 			if ( material.lights ) {
 			if ( material.lights ) {
 
 
 				// the current material requires lighting info
 				// the current material requires lighting info

+ 3 - 3
src/renderers/shaders/ShaderChunk/defaultnormal_vertex.glsl

@@ -1,7 +1,7 @@
+vec3 transformedNormal = normalMatrix * objectNormal;
+
 #ifdef FLIP_SIDED
 #ifdef FLIP_SIDED
 
 
-	objectNormal = -objectNormal;
+	transformedNormal = - transformedNormal;
 
 
 #endif
 #endif
-
-vec3 transformedNormal = normalMatrix * objectNormal;

+ 1 - 1
src/renderers/shaders/ShaderChunk/displacementmap_vertex.glsl

@@ -1,5 +1,5 @@
 #ifdef USE_DISPLACEMENTMAP
 #ifdef USE_DISPLACEMENTMAP
 
 
-	transformed += normal * ( texture2D( displacementMap, uv ).x * displacementScale + displacementBias );
+	transformed += normalize( objectNormal ) * ( texture2D( displacementMap, uv ).x * displacementScale + displacementBias );
 
 
 #endif
 #endif

+ 1 - 9
src/renderers/shaders/ShaderChunk/project_vertex.glsl

@@ -1,11 +1,3 @@
-#ifdef USE_SKINNING
-
-	vec4 mvPosition = modelViewMatrix * skinned;
-
-#else
-
-	vec4 mvPosition = modelViewMatrix * vec4( transformed, 1.0 );
-
-#endif
+vec4 mvPosition = modelViewMatrix * vec4( transformed, 1.0 );
 
 
 gl_Position = projectionMatrix * mvPosition;
 gl_Position = projectionMatrix * mvPosition;

+ 6 - 4
src/renderers/shaders/ShaderChunk/shadowmap_pars_fragment.glsl

@@ -59,6 +59,8 @@
 
 
 	float getShadow( sampler2D shadowMap, vec2 shadowMapSize, float shadowBias, float shadowRadius, vec4 shadowCoord ) {
 	float getShadow( sampler2D shadowMap, vec2 shadowMapSize, float shadowBias, float shadowRadius, vec4 shadowCoord ) {
 
 
+		float shadow = 1.0;
+
 		shadowCoord.xyz /= shadowCoord.w;
 		shadowCoord.xyz /= shadowCoord.w;
 		shadowCoord.z += shadowBias;
 		shadowCoord.z += shadowBias;
 
 
@@ -83,7 +85,7 @@
 			float dx1 = + texelSize.x * shadowRadius;
 			float dx1 = + texelSize.x * shadowRadius;
 			float dy1 = + texelSize.y * shadowRadius;
 			float dy1 = + texelSize.y * shadowRadius;
 
 
-			return (
+			shadow = (
 				texture2DCompare( shadowMap, shadowCoord.xy + vec2( dx0, dy0 ), shadowCoord.z ) +
 				texture2DCompare( shadowMap, shadowCoord.xy + vec2( dx0, dy0 ), shadowCoord.z ) +
 				texture2DCompare( shadowMap, shadowCoord.xy + vec2( 0.0, dy0 ), shadowCoord.z ) +
 				texture2DCompare( shadowMap, shadowCoord.xy + vec2( 0.0, dy0 ), shadowCoord.z ) +
 				texture2DCompare( shadowMap, shadowCoord.xy + vec2( dx1, dy0 ), shadowCoord.z ) +
 				texture2DCompare( shadowMap, shadowCoord.xy + vec2( dx1, dy0 ), shadowCoord.z ) +
@@ -104,7 +106,7 @@
 			float dx1 = + texelSize.x * shadowRadius;
 			float dx1 = + texelSize.x * shadowRadius;
 			float dy1 = + texelSize.y * shadowRadius;
 			float dy1 = + texelSize.y * shadowRadius;
 
 
-			return (
+			shadow = (
 				texture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( dx0, dy0 ), shadowCoord.z ) +
 				texture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( dx0, dy0 ), shadowCoord.z ) +
 				texture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( 0.0, dy0 ), shadowCoord.z ) +
 				texture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( 0.0, dy0 ), shadowCoord.z ) +
 				texture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( dx1, dy0 ), shadowCoord.z ) +
 				texture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( dx1, dy0 ), shadowCoord.z ) +
@@ -118,13 +120,13 @@
 
 
 		#else // no percentage-closer filtering:
 		#else // no percentage-closer filtering:
 
 
-			return texture2DCompare( shadowMap, shadowCoord.xy, shadowCoord.z );
+			shadow = texture2DCompare( shadowMap, shadowCoord.xy, shadowCoord.z );
 
 
 		#endif
 		#endif
 
 
 		}
 		}
 
 
-		return 1.0;
+		return shadow;
 
 
 	}
 	}
 
 

+ 2 - 1
src/renderers/shaders/ShaderChunk/skinning_vertex.glsl

@@ -7,6 +7,7 @@
 	skinned += boneMatY * skinVertex * skinWeight.y;
 	skinned += boneMatY * skinVertex * skinWeight.y;
 	skinned += boneMatZ * skinVertex * skinWeight.z;
 	skinned += boneMatZ * skinVertex * skinWeight.z;
 	skinned += boneMatW * skinVertex * skinWeight.w;
 	skinned += boneMatW * skinVertex * skinWeight.w;
-	skinned  = bindMatrixInverse * skinned;
+
+	transformed = ( bindMatrixInverse * skinned ).xyz;
 
 
 #endif
 #endif

+ 1 - 9
src/renderers/shaders/ShaderChunk/worldpos_vertex.glsl

@@ -1,13 +1,5 @@
 #if defined( USE_ENVMAP ) || defined( PHONG ) || defined( PHYSICAL ) || defined( LAMBERT ) || defined ( USE_SHADOWMAP )
 #if defined( USE_ENVMAP ) || defined( PHONG ) || defined( PHYSICAL ) || defined( LAMBERT ) || defined ( USE_SHADOWMAP )
 
 
-	#ifdef USE_SKINNING
-
-		vec4 worldPosition = modelMatrix * skinned;
-
-	#else
-
-		vec4 worldPosition = modelMatrix * vec4( transformed, 1.0 );
-
-	#endif
+	vec4 worldPosition = modelMatrix * vec4( transformed, 1.0 );
 
 
 #endif
 #endif

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

@@ -190,9 +190,12 @@ var ShaderLib = {
 
 
 	distanceRGBA: {
 	distanceRGBA: {
 
 
-		uniforms: {
-			lightPos: { value: new Vector3() }
-		},
+		uniforms: UniformsUtils.merge( [
+			UniformsLib.common,
+			{
+				lightPos: { value: new Vector3() }
+			}
+		] ),
 
 
 		vertexShader: ShaderChunk.distanceRGBA_vert,
 		vertexShader: ShaderChunk.distanceRGBA_vert,
 		fragmentShader: ShaderChunk.distanceRGBA_frag
 		fragmentShader: ShaderChunk.distanceRGBA_frag

+ 9 - 1
src/renderers/shaders/ShaderLib/depth_vert.glsl

@@ -12,10 +12,18 @@ void main() {
 
 
 	#include <skinbase_vertex>
 	#include <skinbase_vertex>
 
 
+	#ifdef USE_DISPLACEMENTMAP
+
+		#include <beginnormal_vertex>
+		#include <morphnormal_vertex>
+		#include <skinnormal_vertex>
+
+	#endif
+
 	#include <begin_vertex>
 	#include <begin_vertex>
-	#include <displacementmap_vertex>
 	#include <morphtarget_vertex>
 	#include <morphtarget_vertex>
 	#include <skinning_vertex>
 	#include <skinning_vertex>
+	#include <displacementmap_vertex>
 	#include <project_vertex>
 	#include <project_vertex>
 	#include <logdepthbuf_vertex>
 	#include <logdepthbuf_vertex>
 	#include <clipping_planes_vertex>
 	#include <clipping_planes_vertex>

+ 9 - 0
src/renderers/shaders/ShaderLib/distanceRGBA_frag.glsl

@@ -3,12 +3,21 @@ varying vec4 vWorldPosition;
 
 
 #include <common>
 #include <common>
 #include <packing>
 #include <packing>
+#include <uv_pars_fragment>
+#include <map_pars_fragment>
+#include <alphamap_pars_fragment>
 #include <clipping_planes_pars_fragment>
 #include <clipping_planes_pars_fragment>
 
 
 void main () {
 void main () {
 
 
 	#include <clipping_planes_fragment>
 	#include <clipping_planes_fragment>
 
 
+	vec4 diffuseColor = vec4( 1.0 );
+
+	#include <map_fragment>
+	#include <alphamap_fragment>
+	#include <alphatest_fragment>
+
 	gl_FragColor = packDepthToRGBA( length( vWorldPosition.xyz - lightPos.xyz ) / 1000.0 );
 	gl_FragColor = packDepthToRGBA( length( vWorldPosition.xyz - lightPos.xyz ) / 1000.0 );
 
 
 }
 }

+ 3 - 0
src/renderers/shaders/ShaderLib/distanceRGBA_vert.glsl

@@ -1,12 +1,15 @@
 varying vec4 vWorldPosition;
 varying vec4 vWorldPosition;
 
 
 #include <common>
 #include <common>
+#include <uv_pars_vertex>
 #include <morphtarget_pars_vertex>
 #include <morphtarget_pars_vertex>
 #include <skinning_pars_vertex>
 #include <skinning_pars_vertex>
 #include <clipping_planes_pars_vertex>
 #include <clipping_planes_pars_vertex>
 
 
 void main() {
 void main() {
 
 
+	#include <uv_vertex>
+
 	#include <skinbase_vertex>
 	#include <skinbase_vertex>
 	#include <begin_vertex>
 	#include <begin_vertex>
 	#include <morphtarget_vertex>
 	#include <morphtarget_vertex>

+ 1 - 1
src/renderers/shaders/ShaderLib/meshphong_vert.glsl

@@ -40,9 +40,9 @@ void main() {
 #endif
 #endif
 
 
 	#include <begin_vertex>
 	#include <begin_vertex>
-	#include <displacementmap_vertex>
 	#include <morphtarget_vertex>
 	#include <morphtarget_vertex>
 	#include <skinning_vertex>
 	#include <skinning_vertex>
+	#include <displacementmap_vertex>
 	#include <project_vertex>
 	#include <project_vertex>
 	#include <logdepthbuf_vertex>
 	#include <logdepthbuf_vertex>
 	#include <clipping_planes_vertex>
 	#include <clipping_planes_vertex>

+ 1 - 1
src/renderers/shaders/ShaderLib/meshphysical_vert.glsl

@@ -39,9 +39,9 @@ void main() {
 #endif
 #endif
 
 
 	#include <begin_vertex>
 	#include <begin_vertex>
-	#include <displacementmap_vertex>
 	#include <morphtarget_vertex>
 	#include <morphtarget_vertex>
 	#include <skinning_vertex>
 	#include <skinning_vertex>
+	#include <displacementmap_vertex>
 	#include <project_vertex>
 	#include <project_vertex>
 	#include <logdepthbuf_vertex>
 	#include <logdepthbuf_vertex>
 	#include <clipping_planes_vertex>
 	#include <clipping_planes_vertex>

部分文件因为文件数量过多而无法显示