浏览代码

Merge pull request #1 from mrdoob/dev

Update fork to r102
Temdog007 6 年之前
父节点
当前提交
65ebf35d27
共有 100 个文件被更改,包括 1652 次插入815 次删除
  1. 0 1
      .npmignore
  2. 4 7
      build/three.js
  3. 171 410
      build/three.min.js
  4. 2 5
      build/three.module.js
  5. 1 1
      docs/api/en/audio/Audio.html
  6. 1 1
      docs/api/en/audio/AudioAnalyser.html
  7. 4 4
      docs/api/en/audio/AudioListener.html
  8. 2 2
      docs/api/en/audio/PositionalAudio.html
  9. 1 0
      docs/api/en/constants/Renderer.html
  10. 1 1
      docs/api/en/core/Object3D.html
  11. 4 1
      docs/api/en/extras/core/ShapePath.html
  12. 73 0
      docs/api/en/helpers/PositionalAudioHelper.html
  13. 7 0
      docs/api/en/materials/Material.html
  14. 0 6
      docs/api/en/renderers/WebGLRenderTargetCube.html
  15. 67 22
      docs/api/en/renderers/WebGLRenderer.html
  16. 10 2
      docs/api/en/textures/DataTexture3D.html
  17. 1 1
      docs/api/zh/audio/Audio.html
  18. 1 1
      docs/api/zh/audio/AudioAnalyser.html
  19. 4 4
      docs/api/zh/audio/AudioListener.html
  20. 2 2
      docs/api/zh/audio/PositionalAudio.html
  21. 1 1
      docs/api/zh/core/Object3D.html
  22. 73 0
      docs/api/zh/helpers/PositionalAudioHelper.html
  23. 4 0
      docs/api/zh/materials/Material.html
  24. 0 5
      docs/api/zh/renderers/WebGLRenderTargetCube.html
  25. 4 2
      docs/api/zh/renderers/WebGLRenderer.html
  26. 1 1
      docs/api/zh/textures/Texture.html
  27. 4 0
      docs/list.js
  28. 126 0
      docs/manual/en/introduction/How-to-dispose-of-objects.html
  29. 1 1
      docs/manual/zh/introduction/Creating-a-scene.html
  30. 125 0
      docs/manual/zh/introduction/How-to-dispose-of-objects.html
  31. 3 4
      editor/index.html
  32. 12 0
      editor/js/Editor.js
  33. 22 9
      editor/js/Loader.js
  34. 41 18
      editor/js/Menubar.Add.js
  35. 65 5
      editor/js/Sidebar.Animation.js
  36. 183 0
      editor/js/Sidebar.Geometry.TubeGeometry.js
  37. 10 0
      editor/js/Strings.js
  38. 23 0
      editor/js/Viewport.js
  39. 1 5
      editor/js/libs/tern-threejs/threejs.js
  40. 5 5
      editor/js/libs/ui.js
  41. 8 2
      examples/js/GPUComputationRenderer.js
  42. 39 14
      examples/js/Ocean.js
  43. 11 2
      examples/js/cameras/CinematicCamera.js
  44. 16 8
      examples/js/controls/OrbitControls.js
  45. 0 14
      examples/js/controls/TransformControls.js
  46. 11 3
      examples/js/crossfade/scenes.js
  47. 4 2
      examples/js/crossfade/transition.js
  48. 13 2
      examples/js/effects/AnaglyphEffect.js
  49. 27 6
      examples/js/effects/OutlineEffect.js
  50. 9 2
      examples/js/effects/ParallaxBarrierEffect.js
  51. 2 1
      examples/js/effects/StereoEffect.js
  52. 3 1
      examples/js/exporters/GLTFExporter.js
  53. 7 3
      examples/js/loaders/AssimpJSONLoader.js
  54. 14 6
      examples/js/loaders/EquirectangularToCubeGenerator.js
  55. 2 1
      examples/js/loaders/FBXLoader.js
  56. 18 10
      examples/js/loaders/GLTFLoader.js
  57. 57 67
      examples/js/loaders/LDrawLoader.js
  58. 19 4
      examples/js/loaders/SVGLoader.js
  59. 4 2
      examples/js/loaders/TGALoader.js
  60. 23 19
      examples/js/loaders/deprecated/LegacyGLTFLoader.js
  61. 6 2
      examples/js/nodes/inputs/RTTNode.js
  62. 4 2
      examples/js/nodes/postprocessing/NodePostProcessing.js
  63. 12 6
      examples/js/objects/Fire.js
  64. 1 1
      examples/js/objects/Lensflare.js
  65. 5 2
      examples/js/objects/Reflector.js
  66. 5 2
      examples/js/objects/Refractor.js
  67. 3 1
      examples/js/objects/Water.js
  68. 2 1
      examples/js/pmrem/PMREMCubeUVPacker.js
  69. 3 2
      examples/js/pmrem/PMREMGenerator.js
  70. 12 4
      examples/js/postprocessing/AdaptiveToneMappingPass.js
  71. 16 8
      examples/js/postprocessing/AfterimagePass.js
  72. 9 3
      examples/js/postprocessing/BloomPass.js
  73. 8 3
      examples/js/postprocessing/BokehPass.js
  74. 3 1
      examples/js/postprocessing/CubeTexturePass.js
  75. 4 1
      examples/js/postprocessing/DotScreenPass.js
  76. 7 3
      examples/js/postprocessing/EffectComposer.js
  77. 4 1
      examples/js/postprocessing/FilmPass.js
  78. 4 1
      examples/js/postprocessing/GlitchPass.js
  79. 4 1
      examples/js/postprocessing/HalftonePass.js
  80. 7 2
      examples/js/postprocessing/MaskPass.js
  81. 27 9
      examples/js/postprocessing/OutlinePass.js
  82. 3 1
      examples/js/postprocessing/RenderPass.js
  83. 12 7
      examples/js/postprocessing/SAOPass.js
  84. 10 3
      examples/js/postprocessing/SMAAPass.js
  85. 7 2
      examples/js/postprocessing/SSAARenderPass.js
  86. 12 8
      examples/js/postprocessing/SSAOPass.js
  87. 3 1
      examples/js/postprocessing/SavePass.js
  88. 4 1
      examples/js/postprocessing/ShaderPass.js
  89. 13 4
      examples/js/postprocessing/TAARenderPass.js
  90. 3 1
      examples/js/postprocessing/TexturePass.js
  91. 19 7
      examples/js/postprocessing/UnrealBloomPass.js
  92. 2 2
      examples/js/renderers/WebGLDeferredRenderer.js
  93. 二进制
      examples/models/svg/tests/8.png
  94. 31 0
      examples/models/svg/tests/8.svg
  95. 1 1
      examples/software_sandbox.html
  96. 27 20
      examples/webaudio_orientation.html
  97. 1 1
      examples/webgl2_multisampled_renderbuffers.html
  98. 3 1
      examples/webgl_depth_texture.html
  99. 3 1
      examples/webgl_interactive_cubes_gpu.html
  100. 5 2
      examples/webgl_interactive_instances_gpu.html

+ 0 - 1
.npmignore

@@ -1,6 +1,5 @@
 examples/*
 examples/*
 !examples/js/
 !examples/js/
-src/
 test/
 test/
 utils/
 utils/
 docs/
 docs/

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


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


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


+ 1 - 1
docs/api/en/audio/Audio.html

@@ -22,7 +22,7 @@
 		<h2>Example</h2>
 		<h2>Example</h2>
 
 
 		<p>
 		<p>
-			[example:webaudio_sandbox webaudio / sandbox ]</br>
+			[example:webaudio_sandbox webaudio / sandbox ]<br />
 			[example:webaudio_visualizer webaudio / visualizer ]
 			[example:webaudio_visualizer webaudio / visualizer ]
 		</p>
 		</p>
 
 

+ 1 - 1
docs/api/en/audio/AudioAnalyser.html

@@ -22,7 +22,7 @@
 		<h2>Example</h2>
 		<h2>Example</h2>
 
 
 		<p>
 		<p>
-			[example:webaudio_sandbox webaudio / sandbox ]</br>
+			[example:webaudio_sandbox webaudio / sandbox ]<br />
 			[example:webaudio_visualizer webaudio / visualizer ]
 			[example:webaudio_visualizer webaudio / visualizer ]
 		</p>
 		</p>
 
 

+ 4 - 4
docs/api/en/audio/AudioListener.html

@@ -13,8 +13,8 @@
 		<h1>[name]</h1>
 		<h1>[name]</h1>
 
 
 		<p class="desc">
 		<p class="desc">
-			The [name] represents a virtual [link:https://developer.mozilla.org/de/docs/Web/API/AudioListener listener] of the all positional and non-positional audio effects in the scene.</br>
-			A three.js application usually creates a single instance of [name]. It is a mandatory construtor parameter for audios entities like [page:Audio Audio] and [page:PositionalAudio PositionalAudio].</br>
+			The [name] represents a virtual [link:https://developer.mozilla.org/de/docs/Web/API/AudioListener listener] of the all positional and non-positional audio effects in the scene.<br />
+			A three.js application usually creates a single instance of [name]. It is a mandatory construtor parameter for audios entities like [page:Audio Audio] and [page:PositionalAudio PositionalAudio].<br />
 			In most cases, the listener object is a child of the camera. So the 3D transformation of the camera represents the 3D transformation of the listener.
 			In most cases, the listener object is a child of the camera. So the 3D transformation of the camera represents the 3D transformation of the listener.
 		</p>
 		</p>
 
 
@@ -22,8 +22,8 @@
 		<h2>Example</h2>
 		<h2>Example</h2>
 
 
 		<p>
 		<p>
-			[example:webaudio_sandbox webaudio / sandbox ]</br>
-			[example:webaudio_timing webaudio / timing ]</br>
+			[example:webaudio_sandbox webaudio / sandbox ]<br />
+			[example:webaudio_timing webaudio / timing ]<br />
 			[example:webaudio_visualizer webaudio / visualizer ]
 			[example:webaudio_visualizer webaudio / visualizer ]
 		</p>
 		</p>
 
 

+ 2 - 2
docs/api/en/audio/PositionalAudio.html

@@ -22,8 +22,8 @@
 		<h2>Example</h2>
 		<h2>Example</h2>
 
 
 		<p>
 		<p>
-			[example:webaudio_orientation webaudio / orientation ]</br>
-			[example:webaudio_sandbox webaudio / sandbox ]</br>
+			[example:webaudio_orientation webaudio / orientation ]<br />
+			[example:webaudio_sandbox webaudio / sandbox ]<br />
 			[example:webaudio_timing webaudio / timing ]
 			[example:webaudio_timing webaudio / timing ]
 		</p>
 		</p>
 
 

+ 1 - 0
docs/api/en/constants/Renderer.html

@@ -55,6 +55,7 @@
 		THREE.ReinhardToneMapping
 		THREE.ReinhardToneMapping
 		THREE.Uncharted2ToneMapping
 		THREE.Uncharted2ToneMapping
 		THREE.CineonToneMapping
 		THREE.CineonToneMapping
+		THREE.ACESFilmicToneMapping
 		</code>
 		</code>
 		<p>
 		<p>
 		These define the WebGLRenderer's [page:WebGLRenderer.toneMapping toneMapping] property.
 		These define the WebGLRenderer's [page:WebGLRenderer.toneMapping toneMapping] property.

+ 1 - 1
docs/api/en/core/Object3D.html

@@ -292,7 +292,7 @@
 		Converts the vector from local space to world space.
 		Converts the vector from local space to world space.
 		</p>
 		</p>
 
 
-		<h3>[method:null lookAt]( [param:Vector3 vector] )</br>
+		<h3>[method:null lookAt]( [param:Vector3 vector] )<br />
 		[method:null lookAt]( [param:Float x], [param:Float y], [param:Float z] )</h3>
 		[method:null lookAt]( [param:Float x], [param:Float y], [param:Float z] )</h3>
 		<p>
 		<p>
 		vector - A vector representing a position in world space.<br /><br />
 		vector - A vector representing a position in world space.<br /><br />

+ 4 - 1
docs/api/en/extras/core/ShapePath.html

@@ -44,6 +44,9 @@
 		The current [page:Path] that is being generated.
 		The current [page:Path] that is being generated.
 		</p>
 		</p>
 
 
+		<h3>[property:Color color]</h3>
+		<p>[page:Color] of the shape, by default set to white (0xffffff).</p>
+
 		<h2>Methods</h2>
 		<h2>Methods</h2>
 
 
 		<h3>[method:null moveTo]( [param:Float x], [param:Float y] )</h3>
 		<h3>[method:null moveTo]( [param:Float x], [param:Float y] )</h3>
@@ -86,6 +89,6 @@
 
 
 		<h2>Source</h2>
 		<h2>Source</h2>
 
 
-		[link:https://github.com/mrdoob/three.js/blob/master/src/extras/core/Path.js src/extras/core/Path.js]
+		[link:https://github.com/mrdoob/three.js/blob/master/src/extras/core/ShapePath.js src/extras/core/ShapePath.js]
 	</body>
 	</body>
 </html>
 </html>

+ 73 - 0
docs/api/en/helpers/PositionalAudioHelper.html

@@ -0,0 +1,73 @@
+<!DOCTYPE html>
+<html lang="en">
+	<head>
+		<meta charset="utf-8" />
+		<base href="../../../" />
+		<script src="list.js"></script>
+		<script src="page.js"></script>
+		<link type="text/css" rel="stylesheet" href="page.css" />
+	</head>
+	<body>
+		[page:Object3D] &rarr;
+
+		<h1>[name]</h1>
+
+		<p class="desc">This helper displays the directional cone of a [page:PositionalAudio].</p>
+
+		<h2>Example</h2>
+
+		<div>[example:webaudio_orientation webaudio / orientation ]</div>
+
+		<h2>Code Example</h2>
+		<code>
+var positionalAudio = new THREE.PositionalAudio( listener );
+positionalAudio.setDirectionalCone( 180, 230, 0.1 );
+
+var helper = new PositionalAudioHelper( positionalAudio );
+positionalAudio.add( helper );
+		</code>
+
+
+		<h2>Constructor</h2>
+
+		<h3>[name]( [param:PositionalAudio audio], [param:Number range] )</h3>
+		<p>
+			[page:PositionalAudio audio] -- The [page:PositionalAudio] to be visualized. <br /><br/>
+
+			[page:Number range] -- (optional) The range of the directional cone. <br /><br/>
+
+			[page:Number divisionsInnerAngle] -- (optional) The amount of divisions of the inner part of the directional cone. <br /><br/>
+
+			[page:Number divisionsOuterAngle] -- (optional) The amount of divisions of the outer part of the directional cone. <br /><br/>
+		</p>
+
+
+		<h2>Properties</h2>
+		<p>See the base [page:Object3D] class for common properties.</p>
+
+		<h3>[property:PositionalAudio audio]</h3>
+		<p>[page:PositionalAudio] to be visualized.</p>
+
+		<h3>[property:Number range]</h3>
+		<p>The range of the directional cone.</p>
+
+		<h3>[property:Number divisionsInnerAngle]</h3>
+		<p>The amount of divisions of the inner part of the directional cone.</p>
+
+		<h3>[property:Number divisionsOuterAngle]</h3>
+		<p>The amount of divisions of the outer part of the directional cone.</p>
+
+		<h2>Methods</h2>
+		<p>See the base [page:Object3D] class for common methods.</p>
+
+		<h3>[method:null dispose]()</h3>
+		<p>Disposes of the helper.</p>
+
+		<h3>[method:null update]()</h3>
+		<p>Updates the helper.</p>
+
+		<h2>Source</h2>
+
+		[link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js]
+	</body>
+</html>

+ 7 - 0
docs/api/en/materials/Material.html

@@ -261,6 +261,13 @@
 		Other options are [page:Materials THREE.VertexColors] and [page:Materials THREE.FaceColors].
 		Other options are [page:Materials THREE.VertexColors] and [page:Materials THREE.FaceColors].
 		</p>
 		</p>
 
 
+		<h3>[property:Boolean vertexTangents]</h3>
+		<p>
+		Defines whether precomputed vertex tangents, which must be provided in a vec4 "tangent" attribute,
+		are used. When disabled, tangents are derived automatically. Using precomputed tangents will give
+		more accurate normal map details in some cases, such as with mirrored UVs. Default is false.
+		</p>
+
 		<h3>[property:Boolean visible]</h3>
 		<h3>[property:Boolean visible]</h3>
 		<p>
 		<p>
 		Defines whether this material is visible. Default is *true*.
 		Defines whether this material is visible. Default is *true*.

+ 0 - 6
docs/api/en/renderers/WebGLRenderTargetCube.html

@@ -50,12 +50,6 @@
 
 
 		<h2>Properties</h2>
 		<h2>Properties</h2>
 
 
-		<h3>[property:integer activeCubeFace]</h3>
-		<p>
-		The activeCubeFace property corresponds to a cube side (PX 0, NX 1, PY 2, NY 3, PZ 4, NZ 5) and is
-		used and set internally by the [page:CubeCamera].
-		</p>
-
 		<h3>See [page:WebGLRenderTarget] for inherited properties</h3>
 		<h3>See [page:WebGLRenderTarget] for inherited properties</h3>
 
 
 
 

+ 67 - 22
docs/api/en/renderers/WebGLRenderer.html

@@ -348,37 +348,66 @@
 		<h3>[method:RenderTarget getRenderTarget]()</h3>
 		<h3>[method:RenderTarget getRenderTarget]()</h3>
 		<p>Returns the current RenderTarget, if any.</p>
 		<p>Returns the current RenderTarget, if any.</p>
 
 
-		<h3>[method:RenderTarget getCurrentViewport]()</h3>
-		<p>Returns the current viewport.</p>
+		<h3>[method:Vector4 getCurrentViewport]( [param:Vector4 target] )</h3>
+		<p>
+		[page:Vector4 target] — the result will be copied into this Vector4.<br /><br />
+
+		Returns the current viewport.
+		</p>
 
 
-		<h3>[method:Object getDrawingBufferSize]()</h3>
-		<p>Returns an object containing the width and height of the renderer's drawing buffer, in pixels.</p>
+		<h3>[method:Vector2 getDrawingBufferSize]( [param:Vector2 target] )</h3>
+		<p>
+		[page:Vector2 target] — the result will be copied into this Vector2.<br /><br />
+
+		Returns the width and height of the renderer's drawing buffer, in pixels.
+		</p>
 
 
 		<h3>[method:number getPixelRatio]()</h3>
 		<h3>[method:number getPixelRatio]()</h3>
 		<p>Returns current device pixel ratio used.</p>
 		<p>Returns current device pixel ratio used.</p>
 
 
-		<h3>[method:Object getSize]()</h3>
-		<p>Returns an object containing the width and height of the renderer's output canvas, in pixels.</p>
+		<h3>[method:Vector4 getScissor]( [param:Vector4 target] )</h3>
+		<p>
+		[page:Vector4 target] — the result will be copied into this Vector4.<br /><br />
+
+		Returns the scissor region.
+		</p>
+
+		<h3>[method:Boolean getScissorTest]()</h3>
+		<p>Returns *true* if scissor test is enabled; returns *false* otherwise.</p>
+
+		<h3>[method:Vector2 getSize]( [param:Vector2 target] )</h3>
+		<p>
+		[page:Vector2 target] — the result will be copied into this Vector2.<br /><br />
+
+		Returns the width and height of the renderer's output canvas, in pixels.
+		</p>
+
+		<h3>[method:Vector4 getViewport]( [param:Vector4 target] )</h3>
+		<p>
+		[page:Vector4 target] — the result will be copied into this Vector4.<br /><br />
+
+		Returns the viewport.
+		</p>
 
 
 		<h3>[method:null resetGLState]( )</h3>
 		<h3>[method:null resetGLState]( )</h3>
 		<p>Reset the GL state to default. Called internally if the WebGL context is lost.</p>
 		<p>Reset the GL state to default. Called internally if the WebGL context is lost.</p>
 
 
-		<h3>[method:null readRenderTargetPixels]( [param:WebGLRenderTarget renderTarget], [param:Float x], [param:Float y], [param:Float width], [param:Float height], buffer )</h3>
-		<p>Reads the pixel data from the renderTarget into the buffer you pass in. This is a wrapper around [link:https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext/readPixels WebGLRenderingContext.readPixels]().<br />
-		See the [example:webgl_interactive_cubes_gpu interactive / cubes / gpu] example.
+		<h3>[method:null readRenderTargetPixels]( [param:WebGLRenderTarget renderTarget], [param:Float x], [param:Float y], [param:Float width], [param:Float height], [param:TypedArray buffer] )</h3>
+		<p>buffer - Uint8Array is the only destination type supported in all cases, other types are renderTarget and platform dependent. See [link:https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.12 WebGL spec] for details.</p>
+		<p>Reads the pixel data from the renderTarget into the buffer you pass in. This is a wrapper around [link:https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext/readPixels WebGLRenderingContext.readPixels]().</p>
+		<p>See the [example:webgl_interactive_cubes_gpu interactive / cubes / gpu] example.
 		</p>
 		</p>
 
 
-		<h3>[method:null render]( [param:Scene scene], [param:Camera camera], [param:WebGLRenderTarget renderTarget], [param:Boolean forceClear] )</h3>
+
+		<h3>[method:null render]( [param:Scene scene], [param:Camera camera] )</h3>
 		<p>
 		<p>
 			Render a [page:Scene scene] using a [page:Camera camera].<br />
 			Render a [page:Scene scene] using a [page:Camera camera].<br />
 
 
-			The render is done to the [page:WebGLRenderTarget renderTarget] (if specified) or to the canvas as usual.<br />
-
-			If [page:Boolean forceClear] is *true*, the depth, stencil and color buffers will be cleared
-			before rendering even if the renderer's [page:WebGLRenderer.autoClear autoClear] property is false.<br />
+			The render is done to a previously specified [page:WebGLRenderTarget renderTarget] set by calling [page:WebGLRenderer.setRenderTarget .setRenderTarget] or to the canvas as usual.<br />
 
 
-			Even with forceClear set to true you can prevent certain buffers being cleared by setting
-			either the [page:WebGLRenderer.autoClearColor autoClearColor], [page:WebGLRenderer.autoClearStencil autoClearStencil] or [page:WebGLRenderer.autoClearDepth autoClearDepth] properties to false.
+			By default render buffers are cleared before rendering but you can prevent this by setting the property [page:WebGLRenderer.autoClear autoClear] to false.
+			If you want to prevent only certain buffers being cleared you can set either the [page:WebGLRenderer.autoClearColor autoClearColor], [page:WebGLRenderer.autoClearStencil autoClearStencil] or
+			[page:WebGLRenderer.autoClearDepth autoClearDepth] properties to false. To forcibly clear one ore more buffers call [page:WebGLRenderer.clear .clear].
 		</p>
 		</p>
 
 
 		<h3>[method:null renderBufferDirect]( [param:Camera camera], [param:Fog fog], [param:Geometry geometry], [param:Material material], [param:Object3D object], [param:Object group] )</h3>
 		<h3>[method:null renderBufferDirect]( [param:Camera camera], [param:Fog fog], [param:Geometry geometry], [param:Material material], [param:Object3D object], [param:Object group] )</h3>
@@ -405,15 +434,23 @@
 		<h3>[method:null setPixelRatio]( [param:number value] )</h3>
 		<h3>[method:null setPixelRatio]( [param:number value] )</h3>
 		<p>Sets device pixel ratio. This is usually used for HiDPI device to prevent bluring output canvas.</p>
 		<p>Sets device pixel ratio. This is usually used for HiDPI device to prevent bluring output canvas.</p>
 
 
-		<h3>[method:null setRenderTarget]( [param:WebGLRenderTarget renderTarget] )</h3>
+		<h3>[method:null setRenderTarget]( [param:WebGLRenderTarget renderTarget], [param:Integer activeCubeFace], [param:Integer activeMipMapLevel] )</h3>
 		<p>
 		<p>
-		renderTarget -- The [page:WebGLRenderTarget renderTarget] that needs to be activated (optional).<br /><br />
+		renderTarget -- The [page:WebGLRenderTarget renderTarget] that needs to be activated (optional).<br />
+		activeCubeFace -- Specifies the active cube side (PX 0, NX 1, PY 2, NY 3, PZ 4, NZ 5) of [page:WebGLRenderTargetCube] (optional).<br />
+		activeMipMapLevel -- Specifies the active mipmap level (optional).<br /><br />
 		This method sets the active rendertarget. If the parameter is omitted the canvas is set as the active rendertarget.
 		This method sets the active rendertarget. If the parameter is omitted the canvas is set as the active rendertarget.
 		</p>
 		</p>
 
 
-		<h3>[method:null setScissor]( [param:Integer x], [param:Integer y], [param:Integer width], [param:Integer height] )</h3>
+		<h3>[method:null setScissor]( [param:Integer x], [param:Integer y], [param:Integer width], [param:Integer height] )<br />
+		[method:null setScissor]( [param:Vector4 vector] )</h3>
+
 		<p>
 		<p>
-		Sets the scissor area from (x, y) to (x + width, y + height)
+		The x, y, width, and height parameters of the scissor region.<br />
+		Optionally, a 4-component vector specifying the parameters of the region.<br /><br />
+
+		Sets the scissor region from (x, y) to (x + width, y + height).<br />
+		(x, y) is the lower-left corner of the scissor region.
 		</p>
 		</p>
 
 
 		<h3>[method:null setScissorTest]( [param:Boolean boolean] )</h3>
 		<h3>[method:null setScissorTest]( [param:Boolean boolean] )</h3>
@@ -449,8 +486,16 @@
 		The slot number can be found as a value of the uniform of the sampler.
 		The slot number can be found as a value of the uniform of the sampler.
 		</p>
 		</p>
 
 
-		<h3>[method:null setViewport]( [param:Integer x], [param:Integer y], [param:Integer width], [param:Integer height] )</h3>
-		<p>Sets the viewport to render from (x, y) to (x + width, y + height).</p>
+		<h3>[method:null setViewport]( [param:Integer x], [param:Integer y], [param:Integer width], [param:Integer height] )<br />
+		[method:null setViewport]( [param:Vector4 vector] )</h3>
+
+		<p>
+		The x, y, width, and height parameters of the viewport.<br />
+		Optionally, a 4-component vector specifying the parameters of a viewport.<br /><br />
+
+		Sets the viewport to render from (x, y) to (x + width, y + height).<br />
+		(x, y) is the lower-left corner of the region.
+		</p>
 
 
 		<h2>Source</h2>
 		<h2>Source</h2>
 
 

+ 10 - 2
docs/api/en/textures/DataTexture3D.html

@@ -32,10 +32,18 @@
 		<div>[example:webgl2_materials_texture3d WebGL2 / materials / texture3d]</div>
 		<div>[example:webgl2_materials_texture3d WebGL2 / materials / texture3d]</div>
 		<div>[example:webgl2_materials_texture3d_volume WebGL2 / materials / texture3d / volume]</div>
 		<div>[example:webgl2_materials_texture3d_volume WebGL2 / materials / texture3d / volume]</div>
 
 
-		<h2>Properties</h2>
+    <h2>Properties</h2>
 
 
 		<p>
 		<p>
-		See the base [page:Texture Texture] class for common properties.
+    See the base [page:Texture Texture] class for common properties.
+    </p>
+
+    <h3>[property:number wrapR]</h3>
+		<p>
+		This defines how the texture is wrapped in the depth direction.<br />
+		The default is [page:Textures THREE.ClampToEdgeWrapping], where the edge is clamped to the outer edge texels.
+		The other two choices are [page:Textures THREE.RepeatWrapping] and [page:Textures THREE.MirroredRepeatWrapping].
+		See the [page:Textures texture constants] page for details.
 		</p>
 		</p>
 
 
 		<h2>Methods</h2>
 		<h2>Methods</h2>

+ 1 - 1
docs/api/zh/audio/Audio.html

@@ -22,7 +22,7 @@
 		<h2>例子</h2>
 		<h2>例子</h2>
 
 
 		<p>
 		<p>
-			[example:webaudio_sandbox webaudio / sandbox ]</br>
+			[example:webaudio_sandbox webaudio / sandbox ]<br />
 			[example:webaudio_visualizer webaudio / visualizer ]
 			[example:webaudio_visualizer webaudio / visualizer ]
 		</p>
 		</p>
 
 

+ 1 - 1
docs/api/zh/audio/AudioAnalyser.html

@@ -22,7 +22,7 @@
 		<h2>示例</h2>
 		<h2>示例</h2>
 
 
 		<p>
 		<p>
-			[example:webaudio_sandbox webaudio / sandbox ]</br>
+			[example:webaudio_sandbox webaudio / sandbox ]<br />
 			[example:webaudio_visualizer webaudio / visualizer ]
 			[example:webaudio_visualizer webaudio / visualizer ]
 		</p>
 		</p>
 
 

+ 4 - 4
docs/api/zh/audio/AudioListener.html

@@ -13,8 +13,8 @@
 		<h1>[name]</h1>
 		<h1>[name]</h1>
 
 
 		<p class="desc">
 		<p class="desc">
-			[name] 用一个虚拟的[link:https://developer.mozilla.org/de/docs/Web/API/AudioListener listener]表示在场景中所有的位置和非位置相关的音效.</br>
-			一个three.js程序通常创建一个[name]. 它是音频实体构造函数的必须参数,比如 [page:Audio Audio] and [page:PositionalAudio PositionalAudio].</br>
+			[name] 用一个虚拟的[link:https://developer.mozilla.org/de/docs/Web/API/AudioListener listener]表示在场景中所有的位置和非位置相关的音效.<br />
+			一个three.js程序通常创建一个[name]. 它是音频实体构造函数的必须参数,比如 [page:Audio Audio] and [page:PositionalAudio PositionalAudio].<br />
 			大多数情况下, listener对象是camera的子对象. Camera的3D变换表示了listener的3D变换.
 			大多数情况下, listener对象是camera的子对象. Camera的3D变换表示了listener的3D变换.
 		</p>
 		</p>
 
 
@@ -22,8 +22,8 @@
 		<h2>示例</h2>
 		<h2>示例</h2>
 
 
 		<p>
 		<p>
-			[example:webaudio_sandbox webaudio / sandbox ]</br>
-			[example:webaudio_timing webaudio / timing ]</br>
+			[example:webaudio_sandbox webaudio / sandbox ]<br />
+			[example:webaudio_timing webaudio / timing ]<br />
 			[example:webaudio_visualizer webaudio / visualizer ]
 			[example:webaudio_visualizer webaudio / visualizer ]
 		</p>
 		</p>
 
 

+ 2 - 2
docs/api/zh/audio/PositionalAudio.html

@@ -22,8 +22,8 @@
 		<h2>示例</h2>
 		<h2>示例</h2>
 
 
 		<p>
 		<p>
-			[example:webaudio_orientation webaudio / orientation ]</br>
-			[example:webaudio_sandbox webaudio / sandbox ]</br>
+			[example:webaudio_orientation webaudio / orientation ]<br />
+			[example:webaudio_sandbox webaudio / sandbox ]<br />
 			[example:webaudio_timing webaudio / timing ]
 			[example:webaudio_timing webaudio / timing ]
 		</p>
 		</p>
 
 

+ 1 - 1
docs/api/zh/core/Object3D.html

@@ -273,7 +273,7 @@
 		将局部空间向量转换为世界空间向量。
 		将局部空间向量转换为世界空间向量。
 	</p>
 	</p>
 
 
-	<h3>[method:null lookAt]( [param:Vector3 vector] )</br>
+	<h3>[method:null lookAt]( [param:Vector3 vector] )<br />
 		[method:null lookAt]( [param:Float x], [param:Float y], [param:Float z] )</h3>
 		[method:null lookAt]( [param:Float x], [param:Float y], [param:Float z] )</h3>
 	<p>
 	<p>
 		vector - 一个表示世界空间中位置的向量。<br /><br />
 		vector - 一个表示世界空间中位置的向量。<br /><br />

+ 73 - 0
docs/api/zh/helpers/PositionalAudioHelper.html

@@ -0,0 +1,73 @@
+<!DOCTYPE html>
+<html lang="en">
+	<head>
+		<meta charset="utf-8" />
+		<base href="../../../" />
+		<script src="list.js"></script>
+		<script src="page.js"></script>
+		<link type="text/css" rel="stylesheet" href="page.css" />
+	</head>
+	<body>
+		[page:Object3D] &rarr;
+
+		<h1>[name]</h1>
+
+		<p class="desc">这一辅助对象显示[page:PositionalAudio]的方向锥。</p>
+
+		<h2>示例</h2>
+
+		<div>[example:webaudio_orientation webaudio / orientation ]</div>
+
+		<h2>示例代码</h2>
+		<code>
+var positionalAudio = new THREE.PositionalAudio( listener );
+positionalAudio.setDirectionalCone( 180, 230, 0.1 );
+
+var helper = new PositionalAudioHelper( positionalAudio );
+positionalAudio.add( helper );
+		</code>
+
+
+		<h2>构造函数</h2>
+
+		<h3>[name]( [param:PositionalAudio audio], [param:Number range] )</h3>
+		<p>
+			[page:PositionalAudio audio] -- 将会被可视化的[page:PositionalAudio]。<br /><br/>
+
+			[page:Number range] -- (可选)方向锥的范围。<br /><br/>
+
+			[page:Number divisionsInnerAngle] -- (可选)方向锥内侧部分的分段数。<br /><br/>
+
+			[page:Number divisionsOuterAngle] -- (可选)方向锥外侧部分的分段数。<br /><br/>
+		</p>
+
+
+		<h2>属性</h2>
+		<p>请参阅其基类[page:Object3D]来了解共有属性。</p>
+
+		<h3>[property:PositionalAudio audio]</h3>
+		<p>将会被可视化的[page:PositionalAudio]。</p>
+
+		<h3>[property:Number range]</h3>
+		<p>方向锥的范围。</p>
+
+		<h3>[property:Number divisionsInnerAngle]</h3>
+		<p>方向锥内侧部分的分段数。</p>
+
+		<h3>[property:Number divisionsOuterAngle]</h3>
+		<p>方向锥外侧部分的分段数。</p>
+
+		<h2>方法</h2>
+		<p>请参阅其基类[page:Object3D]来了解共有方法。</p>
+
+		<h3>[method:null dispose]()</h3>
+		<p>废置这一辅助对象。</p>
+
+		<h3>[method:null update]()</h3>
+		<p>更新这一辅助对象。</p>
+
+		<h2>源代码</h2>
+
+		[link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js]
+	</body>
+</html>

+ 4 - 0
docs/api/zh/materials/Material.html

@@ -217,6 +217,10 @@
     其他选项有[page:Materials THREE.VertexColors] 和 [page:Materials THREE.FaceColors]。
     其他选项有[page:Materials THREE.VertexColors] 和 [page:Materials THREE.FaceColors]。
 </p>
 </p>
 
 
+<h3>[property:Boolean vertexTangents]</h3>
+<p> TODO.
+</p>
+
 <h3>[property:Boolean visible]</h3>
 <h3>[property:Boolean visible]</h3>
 <p> 此材质是否可见。默认为*true*。
 <p> 此材质是否可见。默认为*true*。
 </p>
 </p>

+ 0 - 5
docs/api/zh/renderers/WebGLRenderTargetCube.html

@@ -47,11 +47,6 @@
 
 
 		<h2>属性</h2>
 		<h2>属性</h2>
 
 
-		<h3>[property:integer activeCubeFace]</h3>
-		<p>
-		activeCubeFace属性对应立方体的面(PX 0, NX 1, PY 2, NY 3, PZ 4, NZ 5) 并由[page:CubeCamera]内部使用和设置
-		</p>
-
 		<h3>继承属性,请参阅[page:WebGLRenderTarget]</h3>
 		<h3>继承属性,请参阅[page:WebGLRenderTarget]</h3>
 
 
 
 

+ 4 - 2
docs/api/zh/renderers/WebGLRenderer.html

@@ -387,9 +387,11 @@
 		<h3>[method:null setPixelRatio]( [param:number value] )</h3>
 		<h3>[method:null setPixelRatio]( [param:number value] )</h3>
 		<p>设置设备像素比。通常用于避免HiDPI设备上绘图模糊</p>
 		<p>设置设备像素比。通常用于避免HiDPI设备上绘图模糊</p>
 
 
-		<h3>[method:null setRenderTarget]( [param:WebGLRenderTarget renderTarget] )</h3>
+		<h3>[method:null setRenderTarget]( [param:WebGLRenderTarget renderTarget], [param:Integer activeCubeFace], [param:Integer activeMipMapLevel] )</h3>
 		<p>
 		<p>
-		renderTarget -- 需要被激活的[page:WebGLRenderTarget renderTarget](可选).<br /><br />
+		renderTarget -- 需要被激活的[page:WebGLRenderTarget renderTarget](可选).<br />
+		activeCubeFace -- Specifies the active cube side (PX 0, NX 1, PY 2, NY 3, PZ 4, NZ 5) of [page:WebGLRenderTargetCube] (optional).<br />
+		activeMipMapLevel -- Specifies the active mipmap level (optional).<br /><br />
 		该方法设置活跃rendertarget. 参数缺省则将canvas设置成活跃rendertarget
 		该方法设置活跃rendertarget. 参数缺省则将canvas设置成活跃rendertarget
 		</p>
 		</p>
 
 

+ 1 - 1
docs/api/zh/textures/Texture.html

@@ -244,7 +244,7 @@
 
 
 		<h3>[method:null dispose]()</h3>
 		<h3>[method:null dispose]()</h3>
 		<p>
 		<p>
-			使用“dispose”事件类型调用[page:EventDispatcher EventDispatcher].dispatchEvent。
+			使用“废置”事件类型调用[page:EventDispatcher EventDispatcher].dispatchEvent。
 		</p>
 		</p>
 
 
 		<h3>[method:Vector2 transformUv]( [param:Vector2 uv] )</h3>
 		<h3>[method:Vector2 transformUv]( [param:Vector2 uv] )</h3>

+ 4 - 0
docs/list.js

@@ -22,6 +22,7 @@ var list = {
 
 
 			"Next Steps": {
 			"Next Steps": {
 				"How to update things": "manual/en/introduction/How-to-update-things",
 				"How to update things": "manual/en/introduction/How-to-update-things",
+				"How to dispose of objects": "manual/en/introduction/How-to-dispose-of-objects",
 				"How to create VR content": "manual/en/introduction/How-to-create-VR-content",
 				"How to create VR content": "manual/en/introduction/How-to-create-VR-content",
 				"Matrix transformations": "manual/en/introduction/Matrix-transformations",
 				"Matrix transformations": "manual/en/introduction/Matrix-transformations",
 				"Animation system": "manual/en/introduction/Animation-system"
 				"Animation system": "manual/en/introduction/Animation-system"
@@ -196,6 +197,7 @@ var list = {
 				"FaceNormalsHelper": "api/en/helpers/FaceNormalsHelper",
 				"FaceNormalsHelper": "api/en/helpers/FaceNormalsHelper",
 				"GridHelper": "api/en/helpers/GridHelper",
 				"GridHelper": "api/en/helpers/GridHelper",
 				"PolarGridHelper": "api/en/helpers/PolarGridHelper",
 				"PolarGridHelper": "api/en/helpers/PolarGridHelper",
+				"PositionalAudioHelper": "api/en/helpers/PositionalAudioHelper",
 				"HemisphereLightHelper": "api/en/helpers/HemisphereLightHelper",
 				"HemisphereLightHelper": "api/en/helpers/HemisphereLightHelper",
 				"PlaneHelper": "api/en/helpers/PlaneHelper",
 				"PlaneHelper": "api/en/helpers/PlaneHelper",
 				"PointLightHelper": "api/en/helpers/PointLightHelper",
 				"PointLightHelper": "api/en/helpers/PointLightHelper",
@@ -447,6 +449,7 @@ var list = {
 
 
 			"进阶": {
 			"进阶": {
 				"如何更新场景": "manual/zh/introduction/How-to-update-things",
 				"如何更新场景": "manual/zh/introduction/How-to-update-things",
+				"如何废置对象": "manual/zh/introduction/How-to-dispose-of-objects",
 				"如何创建VR内容": "manual/zh/introduction/How-to-create-VR-content",
 				"如何创建VR内容": "manual/zh/introduction/How-to-create-VR-content",
 				"矩阵变换": "manual/zh/introduction/Matrix-transformations",
 				"矩阵变换": "manual/zh/introduction/Matrix-transformations",
 				"动画系统": "manual/zh/introduction/Animation-system"
 				"动画系统": "manual/zh/introduction/Animation-system"
@@ -621,6 +624,7 @@ var list = {
 				"FaceNormalsHelper": "api/zh/helpers/FaceNormalsHelper",
 				"FaceNormalsHelper": "api/zh/helpers/FaceNormalsHelper",
 				"GridHelper": "api/zh/helpers/GridHelper",
 				"GridHelper": "api/zh/helpers/GridHelper",
 				"PolarGridHelper": "api/zh/helpers/PolarGridHelper",
 				"PolarGridHelper": "api/zh/helpers/PolarGridHelper",
+				"PositionalAudioHelper": "api/zh/helpers/PositionalAudioHelper",
 				"HemisphereLightHelper": "api/zh/helpers/HemisphereLightHelper",
 				"HemisphereLightHelper": "api/zh/helpers/HemisphereLightHelper",
 				"PlaneHelper": "api/zh/helpers/PlaneHelper",
 				"PlaneHelper": "api/zh/helpers/PlaneHelper",
 				"PointLightHelper": "api/zh/helpers/PointLightHelper",
 				"PointLightHelper": "api/zh/helpers/PointLightHelper",

+ 126 - 0
docs/manual/en/introduction/How-to-dispose-of-objects.html

@@ -0,0 +1,126 @@
+<!DOCTYPE html>
+<html lang="en">
+
+<head>
+	<meta charset="utf-8">
+	<base href="../../../" />
+	<script src="list.js"></script>
+	<script src="page.js"></script>
+	<link type="text/css" rel="stylesheet" href="page.css" />
+</head>
+
+<body>
+	<h1>[name]</h1>
+	<br />
+
+	<p>
+		One important aspect in order to improve performance and avoid memory leaks in your application is the disposal of unused library entities.
+		Whenever you create an instance of a *three.js* type, you allocate a certain amount of memory. However, *three.js* creates for specific objects
+		like geometries or materials WebGL related entities like buffers or shader programs which are necessary for rendering. It's important to
+		highlight that these objects are not released automatically. Instead, the application has to use a special API in order to free such resources.
+		This guide provides a brief overview about how this API is used and what objects are relevant in this context.
+	</p>
+
+	<h2>Geometries</h2>
+
+	<p>
+		A geometry usually represents vertex information defined as a collection of attributes. *three.js* internally creates an object of type [link:https://developer.mozilla.org/en-US/docs/Web/API/WebGLBuffer WebGLBuffer]
+		for each attribute. These entities are only deleted if you call [page:BufferGeometry.dispose](). If a geometry becomes obsolete in your application,
+		execute the method to free all related resources.
+	</p>
+
+	<h2>Materials</h2>
+
+	<p>
+		A material defines how objects are rendered. *three.js* uses the information of a material definition in order to construct a shader program for rendering.
+		Shader programs can only be deleted if the respective material is disposed. For performance reasons, *three.js* tries to reuse existing
+		shader programs if possible. So a shader program is only deleted if all related materials are disposed. You can indicate the disposal of a material by
+		executing [page:Material.dispose]().
+	</p>
+
+	<h2>Textures</h2>
+
+	<p>
+		The disposal of a material has no effect on textures. They are handled separately since a single texture can be used by multiple materials at the same time.
+		Whenever you create an instance of [page:Texture], three.js internally creates an instance of [link:https://developer.mozilla.org/en-US/docs/Web/API/WebGLTexture WebGLTexture].
+		Similar to buffers, this object can only be deleted by calling [page:Texture.dispose]().
+	</p>
+
+	<h2>Render Targets</h2>
+
+	<p>
+		Objects of type [page:WebGLRenderTarget] not only allocate an instance of [link:https://developer.mozilla.org/en-US/docs/Web/API/WebGLTexture WebGLTexture] but also
+		[link:https://developer.mozilla.org/en-US/docs/Web/API/WebGLFramebuffer WebGLFramebuffer]s and [link:https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderbuffer WebGLRenderbuffer]s
+		for realizing custom rendering destinations. These objects are only deallocated by executing [page:WebGLRenderTarget.dispose]().
+	</p>
+
+	<h2>Miscellaneous</h2>
+
+	<p>
+		There are other classes from the examples directory like controls or post processing passes which provide *dispose()* methods in order to remove internal event listeners
+		or render targets. In general, it's recommended to check the API or documentation of a class and watch for *dispose()*. If present, you should use it when cleaning things up.
+	</p>
+
+	<h2>FAQ</h2>
+
+	<h3>Why can't *three.js* dispose objects automatically?</h3>
+
+	<p>
+		This question was asked many times by the community so it's important to clarify this matter. Fact is that *three.js* does not know the lifetime or scope
+		of user-created entities like geometries or materials. This is the responsibility of the application. For example even if a material is currently not used for rendering,
+		it might base necessary for the next frame. So if the application decides that a certain object can be deleted, it has to	notify the engine via calling the respective
+		*dispose()* method.
+	</p>
+
+	<h3>Does removing a mesh from the scene also dispose its geometry and material?</h3>
+
+	<p>
+		No, you have to explicitly dispose the geometry and material via *dispose()*. Keep in mind that geometries and materials can be shared among 3D objects like meshes.
+	</p>
+
+	<h3>Does *three.js* provide information about the amount of cached objects?</h3>
+
+	<p>
+		Yes. It's possible to evaluate [page:WebGLRenderer.info], a special property of the renderer with a series of statistical information about the graphics board memory
+		and the rendering process. Among other things, it tells you have many textures, geometries and shader programs are internally stored. If you notice performance problems
+		in your application, it's a good idea to debug this property in order to easily identify a memory leak.
+	</p>
+
+	<p>
+		Internal resources for a texture are only allocated if the image has fully loaded. If you dispose a texture before the image was loaded,
+		nothing happens. No resources were allocated so there is also no need for clean up.
+	</p>
+
+	<h3>Why happens when you call *dispose()* on a texture but the image is not loaded yet?</h3>
+
+	<p>
+		Internal resources for a texture are only allocated if the image has fully loaded. If you dispose a texture before the image was loaded,
+		nothing happens. No resources were allocated so there is also no need for clean up.
+	</p>
+
+	<h3>What happens when I call *dispose()* and then use the respective object at a later point?</h3>
+
+	<p>
+		The deleted internal resources will be created again by the engine. So no runtime error will occur but you might notice a negative performance impact for the current frame,
+		especially when shader programs have to be compiled.
+	</p>
+
+	<h3>How should I manage *three.js* objects in my app? When do I know how to dispose things?</h3>
+
+	<p>
+		In general, there is no definite recommendation for this. It highly depends on the specific use case when calling *dispose()* is appropriate. It's important to highlight that
+		it's not always necessary to dispose objects all the time. A good example for this is a game which consists of multiple levels. A good place for object disposal is when
+		switching the level. The app could traverse through the old scene and dispose all obsolete materials, geometries and textures. As mentioned in the previous section, it does not
+		produce a runtime error if you dispose an object that is actually still in use. The worst thing that can happen is performance drop for a single frame.
+	</p>
+
+	<h2>Examples that demonstrate the usage of dispose()</h2>
+
+	<p>
+		[example:webgl_test_memory WebGL / test / memory]<br />
+		[example:webgl_test_memory2 WebGL / test / memory2]<br />
+	</p>
+
+</body>
+
+</html>

+ 1 - 1
docs/manual/zh/introduction/Creating-a-scene.html

@@ -10,7 +10,7 @@
 	<body>
 	<body>
 		<h1>创建一个场景([name])</h1><br />
 		<h1>创建一个场景([name])</h1><br />
 
 
-		<p>这一部分将对three.js来做一个简要的介绍;我们将开始搭建一个场景,其中包含一个正在旋转的立方体。页面下方有一个已经完成的例子,当你遇到麻烦,或者需要帮助的时候,可以看一看。</p>
+		<p>这一部分将对three.js来做一个简要的介绍;我们将开始搭建一个场景,其中包含一个正在旋转的立方体。页面下方有一个已经完成的例子,当你遇到麻烦,或者需要帮助的时候,可以看一看。</p>
 
 
 		<h2>开始之前</h2>
 		<h2>开始之前</h2>
 		<p>
 		<p>

+ 125 - 0
docs/manual/zh/introduction/How-to-dispose-of-objects.html

@@ -0,0 +1,125 @@
+<!DOCTYPE html>
+<html lang="en">
+
+<head>
+	<meta charset="utf-8">
+	<base href="../../../" />
+	<script src="list.js"></script>
+	<script src="page.js"></script>
+	<link type="text/css" rel="stylesheet" href="page.css" />
+</head>
+
+<body>
+	<h1>如何废置对象([name])</h1>
+	<br />
+
+	<p>
+		为了提高性能,并避免应用程序中的内存泄露,一个重要的方面是废置未使用的类库实体。
+		每当你创建一个*three.js*中的实例时,都会分配一定数量的内存。然而,*three.js*会创建在渲染中所必需的特定对象,
+		例如几何体或材质,以及与WebGL相关的实体,例如buffers或着色器程序。
+		非常值得注意的是,这些对象并不会被自动释放;相反,应用程序必须使用特殊的API来释放这些资源。
+		本指南简要概述了这一API是如何使用的,以及哪些对象是和这一环境相关的。
+	</p>
+
+	<h2>几何体</h2>
+
+	<p>
+		几何体常用来表示定义为属性集合的顶点信息,*three.js*在内部为每一个属性创建一个[link:https://developer.mozilla.org/en-US/docs/Web/API/WebGLBuffer WebGLBuffer]类型的对象。
+		这些实体仅有在调用[page:BufferGeometry.dispose]()的时候才会被删除。
+		如果应用程序中的几何体已废弃,请执行该方法以释放所有相关资源。
+	</p>
+
+	<h2>材质</h2>
+
+	<p>
+		材质定义了物体将如何被渲染。*three.js*使用材质所定义的信息来构造一个着色器程序,以用于渲染。
+		着色器程序只有在相应材质被废置后才能被删除。由于性能的原因,*three.js*尽可能尝试复用已存在的着色器程序。
+		因此,着色器程序只有在所有相关材质被废置后才被删除。
+		你可以通过执行[page:Material.dispose]()方法来废置材质。
+	</p>
+
+	<h2>纹理</h2>
+
+	<p>
+		对材质的废置不会对纹理造成影响。它们是分离的,因此一个纹理可以同时被多个材质所使用。
+		每当你创建一个[page:Texture]实例的时候,three.js在内部会创建一个[link:https://developer.mozilla.org/en-US/docs/Web/API/WebGLTexture WebGLTexture]实例。
+		和buffer相似,该对象只能通过调用[page:Texture.dispose]()来删除。
+	</p>
+
+	<h2>渲染目标</h2>
+
+	<p>
+		[page:WebGLRenderTarget]类型的对象不仅分配了[link:https://developer.mozilla.org/en-US/docs/Web/API/WebGLTexture WebGLTexture]的实例,
+		还分配了[link:https://developer.mozilla.org/en-US/docs/Web/API/WebGLFramebuffer WebGLFramebuffer]和[link:https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderbuffer WebGLRenderbuffer]来实现自定义渲染目标。
+		这些对象仅能通过执行[page:WebGLRenderTarget.dispose]()来解除分配。
+	</p>
+
+	<h2>杂项</h2>
+
+	<p>
+		有一些来自examples目录的类,例如控制器或者后期处理过程,提供了*dispose()*方法以用于移除内部事件监听器或渲染目标。
+		通常来讲,非常建议查阅类的API或者文档,并注意*dispose()*。如果存在的话,你应当在清理时使用它。
+	</p>
+
+	<h2>常见问题</h2>
+
+	<h3>为何*three.js*不能够自动废置对象?</h3>
+
+	<p>
+		这一问题在社区中多次被问到,因此澄清这件事情是十分有必要的。事实是,*three.js*并不知道用户所创建的实体(例如几何体或者材质)的生命周期或作用范围,这些是应用程序的责任。
+		比如说,即使一个材质当前没有被用于渲染,但它也可能是下一帧所必需的。
+		因此,如果应用程序决定某个对象可以被删除,则它必须通过调用对应的*dispose()*方法来通知引擎。
+	</p>
+
+	<h3>将一个mesh(网格)从场景中移除,是否也会废置它的geometry(几何体)和material(材质)?</h3>
+
+	<p>
+		并不会,你必须通过*dispose()*来明确地废置geometry(几何体)或material(材质)。
+		请记住,eometry(几何体)或material(材质)可以在3D物体之间(例如mesh(网格))被共享。
+	</p>
+
+	<h3>*three.js*是否会提供被缓存对象数量的相关信息?</h3>
+
+	<p>
+		是的,可以评估[page:WebGLRenderer.info] —— 渲染器中的一个特殊属性,具有一系列关于显存和渲染过程的统计信息。
+		除此之外,它还告诉你有多少纹理、几何体和着色器程序在内部存储。
+		如果你在你的应用程序中注意到了性能问题,一个较好的方法便是调试该属性,以便轻松识别内存泄漏。
+	</p>
+
+	<p>
+		对于纹理的内部资源仅在图像完全被加载后才会分配。如果你在图像被加载之前废置纹理,什么都不会发生。
+		没有资源被分配,因此也没有必要进行清理。
+	</p>
+
+	<h3>当你在纹理还没有被加载时,在纹理上调用*dispose()*,会发生什么?</h3>
+
+	<p>
+		对于纹理的内部资源仅在图像完全被加载后才会分配。如果你在图像被加载之前废置纹理,什么都不会发生。
+		没有资源被分配,因此也没有必要进行清理。
+	</p>
+
+	<h3>当我在调用*dispose()*之后,使用相应的对象会发生什么?</h3>
+
+	<p>
+		被删除掉的内部资源会被引擎重新创建,因此不会有运行时错误发生,但你可能会注意到这会对当前帧的性能有一些影响,特别是当着色器程序被编译的时候。
+	</p>
+
+	<h3>我如何在我的应用程序中管理*three.js*中的对象?我如何知道什么时候该废置事物?</h3>
+
+	<p>
+		一般来说,对此并没有明确的建议。调用*dispose()*什么时候合适,很大程度上取决于具体的用例。
+		必须指出的是,没有必要总是废置对象。一个较好的例子便是一个由多个关卡所组成的游戏。使用到对象废置的地方就是当切换关卡的时候。
+		应用程序可以通过较老的场景,并废置所有过时的材质、几何体和纹理贴图。
+		正如在前面的章节中所提到,如果你废置一个仍然在使用的对象,并不会导致运行时错误。可能发生的最糟糕的事情便是单帧的性能会下降。
+	</p>
+
+	<h2>演示dispose()使用方法的示例</h2>
+
+	<p>
+		[example:webgl_test_memory WebGL / test / memory]<br />
+		[example:webgl_test_memory2 WebGL / test / memory2]<br />
+	</p>
+
+</body>
+
+</html>

+ 3 - 4
editor/index.html

@@ -4,10 +4,8 @@
 		<title>three.js / editor</title>
 		<title>three.js / editor</title>
 		<meta charset="utf-8">
 		<meta charset="utf-8">
 		<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
 		<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
-		<!-- Origin Trial Token, feature = WebXR Device API (For Chrome M69+), origin = https://threejs.org, expires = 2019-01-23 -->
-		<meta http-equiv="origin-trial" data-feature="WebXR Device API (For Chrome M69+)" data-expires="2019-01-23" content="ApibcCZfaeEIkwpe6CSIKZXC8ODly5nYX+QlUSgwhUUlMN1/Ko7dr5XUwZDFl9SiEGtOFFe2csLwnNg33ZBh+QMAAABTeyJvcmlnaW4iOiJodHRwczovL3RocmVlanMub3JnOjQ0MyIsImZlYXR1cmUiOiJXZWJYUkRldmljZU02OSIsImV4cGlyeSI6MTU0ODIwMTU5OX0=">
-		<!-- Origin Trial Token, feature = WebXR Gamepad Support, origin = https://threejs.org, expires = 2019-01-23 -->
-		<meta http-equiv="origin-trial" data-feature="WebXR Gamepad Support" data-expires="2019-01-23" content="Agt5pp1xG96NMH+7RdcD7jvbkJiJTagqfKtC+28x/TBeQSh4tF7ad7uXL9Clqbts0vivamPTTkRkNdyfJtEezQ4AAABYeyJvcmlnaW4iOiJodHRwczovL3RocmVlanMub3JnOjQ0MyIsImZlYXR1cmUiOiJXZWJYUkdhbWVwYWRTdXBwb3J0IiwiZXhwaXJ5IjoxNTQ4MjAxNTk5fQ==">
+		<!-- Origin Trial Token, feature = WebXR Device API (For Chrome M69+), origin = https://threejs.org, expires = 2019-03-06 -->
+		<meta http-equiv="origin-trial" data-feature="WebXR Device API (For Chrome M69+)" data-expires="2019-03-06" content="AvDjbxYpoTgOL1PS0JEra7KFCehfTlKnXpU/ORSwNdCQ35cX70cTUkXOnQ26A5XJi3eXHSKpBPchdt5lbcxDuAIAAABTeyJvcmlnaW4iOiJodHRwczovL3RocmVlanMub3JnOjQ0MyIsImZlYXR1cmUiOiJXZWJYUkRldmljZU02OSIsImV4cGlyeSI6MTU1MTgzMDM5OX0=">
 	</head>
 	</head>
 	<body ontouchstart="">
 	<body ontouchstart="">
 		<link href="css/main.css" rel="stylesheet" />
 		<link href="css/main.css" rel="stylesheet" />
@@ -129,6 +127,7 @@
 		<script src="js/Sidebar.Geometry.SphereGeometry.js"></script>
 		<script src="js/Sidebar.Geometry.SphereGeometry.js"></script>
 		<script src="js/Sidebar.Geometry.TorusGeometry.js"></script>
 		<script src="js/Sidebar.Geometry.TorusGeometry.js"></script>
 		<script src="js/Sidebar.Geometry.TorusKnotGeometry.js"></script>
 		<script src="js/Sidebar.Geometry.TorusKnotGeometry.js"></script>
+		<script src="js/Sidebar.Geometry.TubeGeometry.js"></script>
 		<script src="../examples/js/geometries/TeapotBufferGeometry.js"></script>
 		<script src="../examples/js/geometries/TeapotBufferGeometry.js"></script>
 		<script src="js/Sidebar.Geometry.TeapotBufferGeometry.js"></script>
 		<script src="js/Sidebar.Geometry.TeapotBufferGeometry.js"></script>
 		<script src="js/Sidebar.Geometry.LatheGeometry.js"></script>
 		<script src="js/Sidebar.Geometry.LatheGeometry.js"></script>

+ 12 - 0
editor/js/Editor.js

@@ -93,6 +93,9 @@ var Editor = function () {
 	this.textures = {};
 	this.textures = {};
 	this.scripts = {};
 	this.scripts = {};
 
 
+	this.animations = {};
+	this.mixer = new THREE.AnimationMixer( this.scene );
+
 	this.selected = null;
 	this.selected = null;
 	this.helpers = {};
 	this.helpers = {};
 
 
@@ -239,6 +242,12 @@ Editor.prototype = {
 
 
 	},
 	},
 
 
+	addAnimation: function ( object, animations ) {
+
+		this.animations[ object.uuid ] = animations;
+
+	},
+
 	//
 	//
 
 
 	addHelper: function () {
 	addHelper: function () {
@@ -460,6 +469,9 @@ Editor.prototype = {
 		this.textures = {};
 		this.textures = {};
 		this.scripts = {};
 		this.scripts = {};
 
 
+		this.animations = {};
+		this.mixer.stopAllAction();
+
 		this.deselect();
 		this.deselect();
 
 
 		this.signals.editorCleared.dispatch();
 		this.signals.editorCleared.dispatch();

+ 22 - 9
editor/js/Loader.js

@@ -34,7 +34,7 @@ var Loader = function ( editor ) {
 
 
 			for ( var i = 0; i < files.length; i ++ ) {
 			for ( var i = 0; i < files.length; i ++ ) {
 
 
-				scope.loadFile( files[ i ], manager ) ;
+				scope.loadFile( files[ i ], manager );
 
 
 			}
 			}
 
 
@@ -150,7 +150,7 @@ var Loader = function ( editor ) {
 					stream.offset = 0;
 					stream.offset = 0;
 
 
 					var loader = new THREE.CTMLoader();
 					var loader = new THREE.CTMLoader();
-					loader.createModel( new CTM.File( stream ), function( geometry ) {
+					loader.createModel( new CTM.File( stream ), function ( geometry ) {
 
 
 						geometry.sourceType = "ctm";
 						geometry.sourceType = "ctm";
 						geometry.sourceFile = file.name;
 						geometry.sourceFile = file.name;
@@ -215,8 +215,11 @@ var Loader = function ( editor ) {
 					loader.setDRACOLoader( new THREE.DRACOLoader() );
 					loader.setDRACOLoader( new THREE.DRACOLoader() );
 					loader.parse( contents, '', function ( result ) {
 					loader.parse( contents, '', function ( result ) {
 
 
-						result.scene.name = filename;
-						editor.execute( new AddObjectCommand( result.scene ) );
+						var scene = result.scene;
+						scene.name = filename;
+
+						editor.addAnimation( scene, result.animations );
+						editor.execute( new AddObjectCommand( scene ) );
 
 
 					} );
 					} );
 
 
@@ -245,8 +248,11 @@ var Loader = function ( editor ) {
 
 
 					loader.parse( contents, '', function ( result ) {
 					loader.parse( contents, '', function ( result ) {
 
 
-						result.scene.name = filename;
-						editor.execute( new AddObjectCommand( result.scene ) );
+						var scene = result.scene;
+						scene.name = filename;
+
+						editor.addAnimation( scene, result.animations );
+						editor.execute( new AddObjectCommand( scene ) );
 
 
 					} );
 					} );
 
 
@@ -344,6 +350,7 @@ var Loader = function ( editor ) {
 					mesh.mixer = new THREE.AnimationMixer( mesh );
 					mesh.mixer = new THREE.AnimationMixer( mesh );
 					mesh.name = filename;
 					mesh.name = filename;
 
 
+					editor.addAnimation( mesh, geometry.animations );
 					editor.execute( new AddObjectCommand( mesh ) );
 					editor.execute( new AddObjectCommand( mesh ) );
 
 
 				}, false );
 				}, false );
@@ -450,7 +457,7 @@ var Loader = function ( editor ) {
 
 
 					var group = new THREE.Group();
 					var group = new THREE.Group();
 					group.scale.multiplyScalar( 0.1 );
 					group.scale.multiplyScalar( 0.1 );
-					group.scale.y *= -1;
+					group.scale.y *= - 1;
 
 
 					for ( var i = 0; i < paths.length; i ++ ) {
 					for ( var i = 0; i < paths.length; i ++ ) {
 
 
@@ -678,7 +685,10 @@ var Loader = function ( editor ) {
 					var loader = new THREE.GLTFLoader();
 					var loader = new THREE.GLTFLoader();
 					loader.parse( file.asArrayBuffer(), '', function ( result ) {
 					loader.parse( file.asArrayBuffer(), '', function ( result ) {
 
 
-						editor.execute( new AddObjectCommand( result.scene ) );
+						var scene = result.scene;
+
+						editor.addAnimation( scene, result.animations );
+						editor.execute( new AddObjectCommand( scene ) );
 
 
 					} );
 					} );
 
 
@@ -689,7 +699,10 @@ var Loader = function ( editor ) {
 					var loader = new THREE.GLTFLoader( manager );
 					var loader = new THREE.GLTFLoader( manager );
 					loader.parse( file.asText(), '', function ( result ) {
 					loader.parse( file.asText(), '', function ( result ) {
 
 
-						editor.execute( new AddObjectCommand( result.scene ) );
+						var scene = result.scene;
+
+						editor.addAnimation( scene, result.animations );
+						editor.execute( new AddObjectCommand( scene ) );
 
 
 					} );
 					} );
 
 

+ 41 - 18
editor/js/Menubar.Add.js

@@ -41,7 +41,7 @@ Menubar.Add = function ( editor ) {
 
 
 	var option = new UI.Row();
 	var option = new UI.Row();
 	option.setClass( 'option' );
 	option.setClass( 'option' );
-	option.setTextContent( strings.getKey( 'menubar/add/plane' )  );
+	option.setTextContent( strings.getKey( 'menubar/add/plane' ) );
 	option.onClick( function () {
 	option.onClick( function () {
 
 
 		var geometry = new THREE.PlaneBufferGeometry( 1, 1, 1, 1 );
 		var geometry = new THREE.PlaneBufferGeometry( 1, 1, 1, 1 );
@@ -58,7 +58,7 @@ Menubar.Add = function ( editor ) {
 
 
 	var option = new UI.Row();
 	var option = new UI.Row();
 	option.setClass( 'option' );
 	option.setClass( 'option' );
-	option.setTextContent( strings.getKey( 'menubar/add/box' )  );
+	option.setTextContent( strings.getKey( 'menubar/add/box' ) );
 	option.onClick( function () {
 	option.onClick( function () {
 
 
 		var geometry = new THREE.BoxBufferGeometry( 1, 1, 1, 1, 1, 1 );
 		var geometry = new THREE.BoxBufferGeometry( 1, 1, 1, 1, 1, 1 );
@@ -90,7 +90,7 @@ Menubar.Add = function ( editor ) {
 
 
 	var option = new UI.Row();
 	var option = new UI.Row();
 	option.setClass( 'option' );
 	option.setClass( 'option' );
-	option.setTextContent( strings.getKey( 'menubar/add/cylinder' )  );
+	option.setTextContent( strings.getKey( 'menubar/add/cylinder' ) );
 	option.onClick( function () {
 	option.onClick( function () {
 
 
 		var geometry = new THREE.CylinderBufferGeometry( 1, 1, 1, 8, 1, false, 0, Math.PI * 2 );
 		var geometry = new THREE.CylinderBufferGeometry( 1, 1, 1, 8, 1, false, 0, Math.PI * 2 );
@@ -106,7 +106,7 @@ Menubar.Add = function ( editor ) {
 
 
 	var option = new UI.Row();
 	var option = new UI.Row();
 	option.setClass( 'option' );
 	option.setClass( 'option' );
-	option.setTextContent( strings.getKey( 'menubar/add/sphere' )  );
+	option.setTextContent( strings.getKey( 'menubar/add/sphere' ) );
 	option.onClick( function () {
 	option.onClick( function () {
 
 
 		var geometry = new THREE.SphereBufferGeometry( 1, 8, 6, 0, Math.PI * 2, 0, Math.PI );
 		var geometry = new THREE.SphereBufferGeometry( 1, 8, 6, 0, Math.PI * 2, 0, Math.PI );
@@ -122,7 +122,7 @@ Menubar.Add = function ( editor ) {
 
 
 	var option = new UI.Row();
 	var option = new UI.Row();
 	option.setClass( 'option' );
 	option.setClass( 'option' );
-	option.setTextContent( strings.getKey( 'menubar/add/icosahedron' )  );
+	option.setTextContent( strings.getKey( 'menubar/add/icosahedron' ) );
 	option.onClick( function () {
 	option.onClick( function () {
 
 
 		var geometry = new THREE.IcosahedronBufferGeometry( 1, 0 );
 		var geometry = new THREE.IcosahedronBufferGeometry( 1, 0 );
@@ -138,7 +138,7 @@ Menubar.Add = function ( editor ) {
 
 
 	var option = new UI.Row();
 	var option = new UI.Row();
 	option.setClass( 'option' );
 	option.setClass( 'option' );
-	option.setTextContent( strings.getKey( 'menubar/add/torus' )  );
+	option.setTextContent( strings.getKey( 'menubar/add/torus' ) );
 	option.onClick( function () {
 	option.onClick( function () {
 
 
 		var geometry = new THREE.TorusBufferGeometry( 1, 0.4, 8, 6, Math.PI * 2 );
 		var geometry = new THREE.TorusBufferGeometry( 1, 0.4, 8, 6, Math.PI * 2 );
@@ -154,7 +154,7 @@ Menubar.Add = function ( editor ) {
 
 
 	var option = new UI.Row();
 	var option = new UI.Row();
 	option.setClass( 'option' );
 	option.setClass( 'option' );
-	option.setTextContent( strings.getKey( 'menubar/add/torusknot' )  );
+	option.setTextContent( strings.getKey( 'menubar/add/torusknot' ) );
 	option.onClick( function () {
 	option.onClick( function () {
 
 
 		var geometry = new THREE.TorusKnotBufferGeometry( 1, 0.4, 64, 8, 2, 3 );
 		var geometry = new THREE.TorusKnotBufferGeometry( 1, 0.4, 64, 8, 2, 3 );
@@ -166,6 +166,29 @@ Menubar.Add = function ( editor ) {
 	} );
 	} );
 	options.add( option );
 	options.add( option );
 
 
+	// Tube
+
+	var option = new UI.Row();
+	option.setClass( 'option' );
+	option.setTextContent( strings.getKey( 'menubar/add/tube' ) );
+	option.onClick( function () {
+
+		var path = new THREE.CatmullRomCurve3( [
+			new THREE.Vector3( 2, 2, - 2 ),
+			new THREE.Vector3( 2, - 2, - 0.6666666666666667 ),
+			new THREE.Vector3( - 2, - 2, 0.6666666666666667 ),
+			new THREE.Vector3( - 2, 2, 2 )
+		] );
+
+		var geometry = new THREE.TubeBufferGeometry( path, 64, 1, 8, false );
+		var mesh = new THREE.Mesh( geometry, new THREE.MeshStandardMaterial() );
+		mesh.name = 'Tube';
+
+		editor.execute( new AddObjectCommand( mesh ) );
+
+	} );
+	options.add( option );
+
 	/*
 	/*
 	// Teapot
 	// Teapot
 
 
@@ -199,8 +222,8 @@ Menubar.Add = function ( editor ) {
 
 
 	var option = new UI.Row();
 	var option = new UI.Row();
 	option.setClass( 'option' );
 	option.setClass( 'option' );
-	option.setTextContent( strings.getKey( 'menubar/add/lathe' )  );
-	option.onClick( function() {
+	option.setTextContent( strings.getKey( 'menubar/add/lathe' ) );
+	option.onClick( function () {
 
 
 		var points = [
 		var points = [
 			new THREE.Vector2( 0, 0 ),
 			new THREE.Vector2( 0, 0 ),
@@ -229,7 +252,7 @@ Menubar.Add = function ( editor ) {
 
 
 	var option = new UI.Row();
 	var option = new UI.Row();
 	option.setClass( 'option' );
 	option.setClass( 'option' );
-	option.setTextContent( strings.getKey( 'menubar/add/sprite' )  );
+	option.setTextContent( strings.getKey( 'menubar/add/sprite' ) );
 	option.onClick( function () {
 	option.onClick( function () {
 
 
 		var sprite = new THREE.Sprite( new THREE.SpriteMaterial() );
 		var sprite = new THREE.Sprite( new THREE.SpriteMaterial() );
@@ -248,7 +271,7 @@ Menubar.Add = function ( editor ) {
 
 
 	var option = new UI.Row();
 	var option = new UI.Row();
 	option.setClass( 'option' );
 	option.setClass( 'option' );
-	option.setTextContent( strings.getKey( 'menubar/add/pointlight' )  );
+	option.setTextContent( strings.getKey( 'menubar/add/pointlight' ) );
 	option.onClick( function () {
 	option.onClick( function () {
 
 
 		var color = 0xffffff;
 		var color = 0xffffff;
@@ -267,7 +290,7 @@ Menubar.Add = function ( editor ) {
 
 
 	var option = new UI.Row();
 	var option = new UI.Row();
 	option.setClass( 'option' );
 	option.setClass( 'option' );
-	option.setTextContent( strings.getKey( 'menubar/add/spotlight' )  );
+	option.setTextContent( strings.getKey( 'menubar/add/spotlight' ) );
 	option.onClick( function () {
 	option.onClick( function () {
 
 
 		var color = 0xffffff;
 		var color = 0xffffff;
@@ -291,7 +314,7 @@ Menubar.Add = function ( editor ) {
 
 
 	var option = new UI.Row();
 	var option = new UI.Row();
 	option.setClass( 'option' );
 	option.setClass( 'option' );
-	option.setTextContent( strings.getKey( 'menubar/add/directionallight' )  );
+	option.setTextContent( strings.getKey( 'menubar/add/directionallight' ) );
 	option.onClick( function () {
 	option.onClick( function () {
 
 
 		var color = 0xffffff;
 		var color = 0xffffff;
@@ -312,7 +335,7 @@ Menubar.Add = function ( editor ) {
 
 
 	var option = new UI.Row();
 	var option = new UI.Row();
 	option.setClass( 'option' );
 	option.setClass( 'option' );
-	option.setTextContent( strings.getKey( 'menubar/add/hemispherelight' )  );
+	option.setTextContent( strings.getKey( 'menubar/add/hemispherelight' ) );
 	option.onClick( function () {
 	option.onClick( function () {
 
 
 		var skyColor = 0x00aaff;
 		var skyColor = 0x00aaff;
@@ -333,8 +356,8 @@ Menubar.Add = function ( editor ) {
 
 
 	var option = new UI.Row();
 	var option = new UI.Row();
 	option.setClass( 'option' );
 	option.setClass( 'option' );
-	option.setTextContent( strings.getKey( 'menubar/add/ambientlight' )  );
-	option.onClick( function() {
+	option.setTextContent( strings.getKey( 'menubar/add/ambientlight' ) );
+	option.onClick( function () {
 
 
 		var color = 0x222222;
 		var color = 0x222222;
 
 
@@ -354,8 +377,8 @@ Menubar.Add = function ( editor ) {
 
 
 	var option = new UI.Row();
 	var option = new UI.Row();
 	option.setClass( 'option' );
 	option.setClass( 'option' );
-	option.setTextContent( strings.getKey( 'menubar/add/perspectivecamera' )  );
-	option.onClick( function() {
+	option.setTextContent( strings.getKey( 'menubar/add/perspectivecamera' ) );
+	option.onClick( function () {
 
 
 		var camera = new THREE.PerspectiveCamera( 50, 1, 1, 10000 );
 		var camera = new THREE.PerspectiveCamera( 50, 1, 1, 10000 );
 		camera.name = 'PerspectiveCamera';
 		camera.name = 'PerspectiveCamera';

+ 65 - 5
editor/js/Sidebar.Animation.js

@@ -5,19 +5,79 @@
 Sidebar.Animation = function ( editor ) {
 Sidebar.Animation = function ( editor ) {
 
 
 	var signals = editor.signals;
 	var signals = editor.signals;
+	var mixer = editor.mixer;
 
 
-	var options = {};
-	var possibleAnimations = {};
+	var actions = {};
+
+	signals.objectSelected.add( function ( object ) {
+
+		var animations = editor.animations[ object !== null ? object.uuid : '' ];
+
+		if ( animations !== undefined ) {
+
+			container.setDisplay( '' );
+
+			var options = {};
+			var firstAnimation;
+
+			for ( var animation of animations ) {
+
+				if ( firstAnimation === undefined ) firstAnimation = animation.name;
+
+				actions[ animation.name ] = mixer.clipAction( animation, object );
+				options[ animation.name ] = animation.name;
+
+			}
+
+			animationsSelect.setOptions( options );
+			animationsSelect.setValue( firstAnimation );
+
+		} else {
+
+			container.setDisplay( 'none' );
+
+		}
+
+	} );
+
+	signals.objectRemoved.add( function ( object ) {
+
+		var animations = editor.animations[ object !== null ? object.uuid : '' ];
+
+		if ( animations !== undefined ) {
+
+			mixer.uncacheRoot( object );
+
+		}
+
+	} );
+
+	function playAction() {
+
+		actions[ animationsSelect.getValue() ].play();
+
+	}
+
+	function stopAction() {
+
+		actions[ animationsSelect.getValue() ].stop();
+
+	}
 
 
 	var container = new UI.Panel();
 	var container = new UI.Panel();
 	container.setDisplay( 'none' );
 	container.setDisplay( 'none' );
 
 
-	container.add( new UI.Text( 'Animation' ).setTextTransform( 'uppercase' ) );
+	container.add( new UI.Text( 'Animations' ).setTextTransform( 'uppercase' ) );
 	container.add( new UI.Break() );
 	container.add( new UI.Break() );
 	container.add( new UI.Break() );
 	container.add( new UI.Break() );
 
 
-	var animationsRow = new UI.Row();
-	container.add( animationsRow );
+	var div = new UI.Div();
+	container.add( div );
+
+	var animationsSelect = new UI.Select().setFontSize( '12px' );
+	div.add( animationsSelect );
+	div.add( new UI.Button( 'Play' ).setMarginLeft( '4px' ).onClick( playAction ) );
+	div.add( new UI.Button( 'Stop' ).setMarginLeft( '4px' ).onClick( stopAction ) );
 
 
 	return container;
 	return container;
 
 

+ 183 - 0
editor/js/Sidebar.Geometry.TubeGeometry.js

@@ -0,0 +1,183 @@
+/**
+ * @author Temdog007 / http://github.com/Temdog007
+ */
+
+Sidebar.Geometry.TubeGeometry = function ( editor, object ) {
+
+	var strings = editor.strings;
+
+	var signals = editor.signals;
+
+	var container = new UI.Row();
+
+	var geometry = object.geometry;
+	var parameters = geometry.parameters;
+
+	// points
+
+	var lastPointIdx = 0;
+	var pointsUI = [];
+
+	var pointsRow = new UI.Row();
+	pointsRow.add( new UI.Text( strings.getKey( 'sidebar/geometry/tube_geometry/path' ) ).setWidth( '90px' ) );
+
+	var points = new UI.Span().setDisplay( 'inline-block' );
+	pointsRow.add( points );
+
+	var pointsList = new UI.Div();
+	points.add( pointsList );
+
+	var parameterPoints = parameters.path.points;
+	for ( var i = 0; i < parameterPoints.length; i ++ ) {
+
+		var point = parameterPoints[ i ];
+		pointsList.add( createPointRow( point.x, point.y, point.z ) );
+
+	}
+
+	var addPointButton = new UI.Button( '+' ).onClick( function () {
+
+		if ( pointsUI.length === 0 ) {
+
+			pointsList.add( createPointRow( 0, 0, 0 ) );
+
+		} else {
+
+			var point = pointsUI[ pointsUI.length - 1 ];
+
+			pointsList.add( createPointRow( point.x.getValue(), point.y.getValue(), point.z.getValue() ) );
+
+		}
+
+		update();
+
+	} );
+	points.add( addPointButton );
+
+	container.add( pointsRow );
+
+	// radius
+
+	var radiusRow = new UI.Row();
+	var radius = new UI.Number( parameters.radius ).onChange( update );
+
+	radiusRow.add( new UI.Text( strings.getKey( 'sidebar/geometry/tube_geometry/radius' ) ).setWidth( '90px' ) );
+	radiusRow.add( radius );
+
+	container.add( radiusRow );
+
+	// tubularSegments
+
+	var tubularSegmentsRow = new UI.Row();
+	var tubularSegments = new UI.Integer( parameters.tubularSegments ).onChange( update );
+
+	tubularSegmentsRow.add( new UI.Text( strings.getKey( 'sidebar/geometry/tube_geometry/tubularsegments' ) ).setWidth( '90px' ) );
+	tubularSegmentsRow.add( tubularSegments );
+
+	container.add( tubularSegmentsRow );
+
+	// radialSegments
+
+	var radialSegmentsRow = new UI.Row();
+	var radialSegments = new UI.Integer( parameters.radialSegments ).onChange( update );
+
+	radialSegmentsRow.add( new UI.Text( strings.getKey( 'sidebar/geometry/tube_geometry/radialsegments' ) ).setWidth( '90px' ) );
+	radialSegmentsRow.add( radialSegments );
+
+	container.add( radialSegmentsRow );
+
+	// closed
+
+	var closedRow = new UI.Row();
+	var closed = new UI.Checkbox( parameters.closed ).onChange( update );
+
+	closedRow.add( new UI.Text( strings.getKey( 'sidebar/geometry/tube_geometry/closed' ) ).setWidth( '90px' ) );
+	closedRow.add( closed );
+
+	container.add( closedRow );
+
+	// curveType
+
+	var curveTypeRow = new UI.Row();
+	var curveType = new UI.Select().setOptions( { centripetal: 'centripetal', chordal: 'chordal', catmullrom: 'catmullrom' } ).setValue( parameters.path.curveType ).onChange( update );
+
+	curveTypeRow.add( new UI.Text( strings.getKey( 'sidebar/geometry/tube_geometry/curvetype' ) ).setWidth( '90px' ), curveType );
+
+	container.add( curveTypeRow );
+
+	// tension
+
+	var tensionRow = new UI.Row();
+	var tension = new UI.Number( parameters.path.tension ).setStep( 0.01 ).onChange( update );
+
+	tensionRow.add( new UI.Text( strings.getKey( 'sidebar/geometry/tube_geometry/tension' ) ).setWidth( '90px' ), tension );
+
+	container.add( tensionRow );
+
+	//
+
+	function update() {
+
+		var points = [];
+		var count = 0;
+
+		for ( var i = 0; i < pointsUI.length; i ++ ) {
+
+			var pointUI = pointsUI[ i ];
+
+			if ( ! pointUI ) continue;
+
+			points.push( new THREE.Vector3( pointUI.x.getValue(), pointUI.y.getValue(), pointUI.z.getValue() ) );
+			count ++;
+			pointUI.lbl.setValue( count );
+
+		}
+
+		editor.execute( new SetGeometryCommand( object, new THREE[ geometry.type ](
+			new THREE.CatmullRomCurve3( points, closed.getValue(), curveType.getValue(), tension.getValue() ),
+			tubularSegments.getValue(),
+			radius.getValue(),
+			radialSegments.getValue(),
+			closed.getValue()
+		) ) );
+
+	}
+
+	function createPointRow( x, y, z ) {
+
+		var pointRow = new UI.Div();
+		var lbl = new UI.Text( lastPointIdx + 1 ).setWidth( '20px' );
+		var txtX = new UI.Number( x ).setWidth( '30px' ).onChange( update );
+		var txtY = new UI.Number( y ).setWidth( '30px' ).onChange( update );
+		var txtZ = new UI.Number( z ).setWidth( '30px' ).onChange( update );
+		var idx = lastPointIdx;
+		var btn = new UI.Button( '-' ).onClick( function () {
+
+			deletePointRow( idx );
+
+		} );
+
+		pointsUI.push( { row: pointRow, lbl: lbl, x: txtX, y: txtY, z: txtZ } );
+		lastPointIdx ++;
+		pointRow.add( lbl, txtX, txtY, txtZ, btn );
+
+		return pointRow;
+
+	}
+
+	function deletePointRow( idx ) {
+
+		if ( ! pointsUI[ idx ] ) return;
+
+		pointsList.remove( pointsUI[ idx ].row );
+		pointsUI[ idx ] = null;
+
+		update();
+
+	}
+
+	return container;
+
+};
+
+Sidebar.Geometry.TubeBufferGeometry = Sidebar.Geometry.TubeGeometry;

+ 10 - 0
editor/js/Strings.js

@@ -41,6 +41,7 @@ var Strings = function ( config ) {
 			'menubar/add/sphere': 'Sphere',
 			'menubar/add/sphere': 'Sphere',
 			'menubar/add/icosahedron': 'Icosahedron',
 			'menubar/add/icosahedron': 'Icosahedron',
 			'menubar/add/torus': 'Torus',
 			'menubar/add/torus': 'Torus',
+			'menubar/add/tube': 'Tube',
 			'menubar/add/torusknot': 'TorusKnot',
 			'menubar/add/torusknot': 'TorusKnot',
 			'menubar/add/lathe': 'Lathe',
 			'menubar/add/lathe': 'Lathe',
 			'menubar/add/sprite': 'Sprite',
 			'menubar/add/sprite': 'Sprite',
@@ -162,6 +163,15 @@ var Strings = function ( config ) {
 			'sidebar/geometry/torusKnot_geometry/p': 'P',
 			'sidebar/geometry/torusKnot_geometry/p': 'P',
 			'sidebar/geometry/torusKnot_geometry/q': 'Q',
 			'sidebar/geometry/torusKnot_geometry/q': 'Q',
 
 
+			'sidebar/geometry/tube_geometry/path': 'Path',
+			'sidebar/geometry/tube_geometry/radius': 'Radius',
+			'sidebar/geometry/tube_geometry/tube': 'Tube',
+			'sidebar/geometry/tube_geometry/tubularsegments': 'Tubular segments',
+			'sidebar/geometry/tube_geometry/radialsegments': 'Radial segments',
+			'sidebar/geometry/tube_geometry/closed': 'Closed',
+			'sidebar/geometry/tube_geometry/curvetype': 'Curve Type',
+			'sidebar/geometry/tube_geometry/tension': 'Tension',
+
 			'sidebar/material/new': 'New',
 			'sidebar/material/new': 'New',
 			'sidebar/material/copy': 'Copy',
 			'sidebar/material/copy': 'Copy',
 			'sidebar/material/paste': 'Paste',
 			'sidebar/material/paste': 'Paste',

+ 23 - 0
editor/js/Viewport.js

@@ -519,6 +519,29 @@ var Viewport = function ( editor ) {
 
 
 	} );
 	} );
 
 
+	// animations
+
+	var prevTime = performance.now();
+
+	function animate( time ) {
+
+		requestAnimationFrame( animate );
+
+		var mixer = editor.mixer;
+
+		if ( mixer.stats.actions.inUse > 0 ) {
+
+			mixer.update( ( time - prevTime ) / 1000 );
+			render();
+
+		}
+
+		prevTime = time;
+
+	}
+
+	requestAnimationFrame( animate );
+
 	//
 	//
 
 
 	function render() {
 	function render() {

+ 1 - 5
editor/js/libs/tern-threejs/threejs.js

@@ -4621,11 +4621,7 @@
     "WebGLRenderTargetCube": {
     "WebGLRenderTargetCube": {
       "!url": "http://threejs.org/docs/#Reference/renderers/WebGLRenderTargetCube",
       "!url": "http://threejs.org/docs/#Reference/renderers/WebGLRenderTargetCube",
       "prototype": {
       "prototype": {
-        "!proto": "THREE.WebGLRenderTarget.prototype",
-        "activeCubeFace": {
-          "!type": "integer",
-          "!doc": "The activeCubeFace property corresponds to a cube side (PX 0, NX 1, PY 2, NY 3, PZ 4, NZ 5) and is\n\t\tused and set internally by the [page:CubeCamera]."
-        }
+        "!proto": "THREE.WebGLRenderTarget.prototype"
       },
       },
       "!doc": "[page:CubeCamera] uses this as its [page:WebGLRenderTarget]",
       "!doc": "[page:CubeCamera] uses this as its [page:WebGLRenderTarget]",
       "!type": "fn(width: number, height: number, options: object)"
       "!type": "fn(width: number, height: number, options: object)"

+ 5 - 5
editor/js/libs/ui.js

@@ -115,8 +115,8 @@ UI.Element.prototype = {
 // properties
 // properties
 
 
 var properties = [ 'position', 'left', 'top', 'right', 'bottom', 'width', 'height', 'border', 'borderLeft',
 var properties = [ 'position', 'left', 'top', 'right', 'bottom', 'width', 'height', 'border', 'borderLeft',
-'borderTop', 'borderRight', 'borderBottom', 'borderColor', 'display', 'overflow', 'margin', 'marginLeft', 'marginTop', 'marginRight', 'marginBottom', 'padding', 'paddingLeft', 'paddingTop', 'paddingRight', 'paddingBottom', 'color',
-'background', 'backgroundColor', 'opacity', 'fontSize', 'fontWeight', 'textAlign', 'textDecoration', 'textTransform', 'cursor', 'zIndex' ];
+	'borderTop', 'borderRight', 'borderBottom', 'borderColor', 'display', 'overflow', 'margin', 'marginLeft', 'marginTop', 'marginRight', 'marginBottom', 'padding', 'paddingLeft', 'paddingTop', 'paddingRight', 'paddingBottom', 'color',
+	'background', 'backgroundColor', 'opacity', 'fontSize', 'fontWeight', 'textAlign', 'textDecoration', 'textTransform', 'cursor', 'zIndex' ];
 
 
 properties.forEach( function ( property ) {
 properties.forEach( function ( property ) {
 
 
@@ -863,9 +863,9 @@ UI.Integer.prototype.setValue = function ( value ) {
 };
 };
 
 
 UI.Integer.prototype.setStep = function ( step ) {
 UI.Integer.prototype.setStep = function ( step ) {
-	
-	this.step = parseInt( step ); 
-	
+
+	this.step = parseInt( step );
+
 	return this;
 	return this;
 
 
 };
 };

+ 8 - 2
examples/js/GPUComputationRenderer.js

@@ -277,7 +277,9 @@ function GPUComputationRenderer( sizeX, sizeY, renderer ) {
 		addResolutionDefine( material );
 		addResolutionDefine( material );
 
 
 		return material;
 		return material;
+
 	}
 	}
+
 	this.createShaderMaterial = createShaderMaterial;
 	this.createShaderMaterial = createShaderMaterial;
 
 
 	this.createRenderTarget = function( sizeXTexture, sizeYTexture, wrapS, wrapT, minFilter, magFilter ) {
 	this.createRenderTarget = function( sizeXTexture, sizeYTexture, wrapS, wrapT, minFilter, magFilter ) {
@@ -316,7 +318,6 @@ function GPUComputationRenderer( sizeX, sizeY, renderer ) {
 
 
 	};
 	};
 
 
-
 	this.renderTexture = function( input, output ) {
 	this.renderTexture = function( input, output ) {
 
 
 		// Takes a texture, and render out in rendertarget
 		// Takes a texture, and render out in rendertarget
@@ -333,10 +334,15 @@ function GPUComputationRenderer( sizeX, sizeY, renderer ) {
 
 
 	this.doRenderTarget = function( material, output ) {
 	this.doRenderTarget = function( material, output ) {
 
 
+		var currentRenderTarget = renderer.getRenderTarget();
+
 		mesh.material = material;
 		mesh.material = material;
-		renderer.render( scene, camera, output );
+		renderer.setRenderTarget( output );
+		renderer.render( scene, camera );
 		mesh.material = passThruShader;
 		mesh.material = passThruShader;
 
 
+		renderer.setRenderTarget( currentRenderTarget );
+
 	};
 	};
 
 
 	// Shaders
 	// Shaders

+ 39 - 14
examples/js/Ocean.js

@@ -212,6 +212,8 @@ THREE.Ocean.prototype.generateMesh = function () {
 
 
 THREE.Ocean.prototype.render = function () {
 THREE.Ocean.prototype.render = function () {
 
 
+	var currentRenderTarget = this.renderer.getRenderTarget();
+
 	this.scene.overrideMaterial = null;
 	this.scene.overrideMaterial = null;
 
 
 	if ( this.changed )
 	if ( this.changed )
@@ -223,9 +225,11 @@ THREE.Ocean.prototype.render = function () {
 	this.renderNormalMap();
 	this.renderNormalMap();
 	this.scene.overrideMaterial = null;
 	this.scene.overrideMaterial = null;
 
 
+	this.renderer.setRenderTarget( currentRenderTarget );
+
 };
 };
 
 
-THREE.Ocean.prototype.generateSeedPhaseTexture = function() {
+THREE.Ocean.prototype.generateSeedPhaseTexture = function () {
 
 
 	// Setup the seed texture
 	// Setup the seed texture
 	this.pingPhase = true;
 	this.pingPhase = true;
@@ -234,7 +238,7 @@ THREE.Ocean.prototype.generateSeedPhaseTexture = function() {
 
 
 		for ( var j = 0; j < this.resolution; j ++ ) {
 		for ( var j = 0; j < this.resolution; j ++ ) {
 
 
-			phaseArray[ i * this.resolution * 4 + j * 4 ] =  Math.random() * 2.0 * Math.PI;
+			phaseArray[ i * this.resolution * 4 + j * 4 ] = Math.random() * 2.0 * Math.PI;
 			phaseArray[ i * this.resolution * 4 + j * 4 + 1 ] = 0.0;
 			phaseArray[ i * this.resolution * 4 + j * 4 + 1 ] = 0.0;
 			phaseArray[ i * this.resolution * 4 + j * 4 + 2 ] = 0.0;
 			phaseArray[ i * this.resolution * 4 + j * 4 + 2 ] = 0.0;
 			phaseArray[ i * this.resolution * 4 + j * 4 + 3 ] = 0.0;
 			phaseArray[ i * this.resolution * 4 + j * 4 + 3 ] = 0.0;
@@ -256,7 +260,10 @@ THREE.Ocean.prototype.renderInitialSpectrum = function () {
 	this.scene.overrideMaterial = this.materialInitialSpectrum;
 	this.scene.overrideMaterial = this.materialInitialSpectrum;
 	this.materialInitialSpectrum.uniforms.u_wind.value.set( this.windX, this.windY );
 	this.materialInitialSpectrum.uniforms.u_wind.value.set( this.windX, this.windY );
 	this.materialInitialSpectrum.uniforms.u_size.value = this.size;
 	this.materialInitialSpectrum.uniforms.u_size.value = this.size;
-	this.renderer.render( this.scene, this.oceanCamera, this.initialSpectrumFramebuffer, true );
+
+	this.renderer.setRenderTarget( this.initialSpectrumFramebuffer );
+	this.renderer.clear();
+	this.renderer.render( this.scene, this.oceanCamera );
 
 
 };
 };
 
 
@@ -269,14 +276,15 @@ THREE.Ocean.prototype.renderWavePhase = function () {
 		this.materialPhase.uniforms.u_phases.value = this.pingPhaseTexture;
 		this.materialPhase.uniforms.u_phases.value = this.pingPhaseTexture;
 		this.initial = false;
 		this.initial = false;
 
 
-	}else {
+	} else {
 
 
 		this.materialPhase.uniforms.u_phases.value = this.pingPhase ? this.pingPhaseFramebuffer.texture : this.pongPhaseFramebuffer.texture;
 		this.materialPhase.uniforms.u_phases.value = this.pingPhase ? this.pingPhaseFramebuffer.texture : this.pongPhaseFramebuffer.texture;
 
 
 	}
 	}
 	this.materialPhase.uniforms.u_deltaTime.value = this.deltaTime;
 	this.materialPhase.uniforms.u_deltaTime.value = this.deltaTime;
 	this.materialPhase.uniforms.u_size.value = this.size;
 	this.materialPhase.uniforms.u_size.value = this.size;
-	this.renderer.render( this.scene, this.oceanCamera, this.pingPhase ? this.pongPhaseFramebuffer : this.pingPhaseFramebuffer );
+	this.renderer.setRenderTarget( this.pingPhase ? this.pongPhaseFramebuffer : this.pingPhaseFramebuffer );
+	this.renderer.render( this.scene, this.oceanCamera );
 	this.pingPhase = ! this.pingPhase;
 	this.pingPhase = ! this.pingPhase;
 
 
 };
 };
@@ -288,11 +296,13 @@ THREE.Ocean.prototype.renderSpectrum = function () {
 	this.materialSpectrum.uniforms.u_phases.value = this.pingPhase ? this.pingPhaseFramebuffer.texture : this.pongPhaseFramebuffer.texture;
 	this.materialSpectrum.uniforms.u_phases.value = this.pingPhase ? this.pingPhaseFramebuffer.texture : this.pongPhaseFramebuffer.texture;
 	this.materialSpectrum.uniforms.u_choppiness.value = this.choppiness;
 	this.materialSpectrum.uniforms.u_choppiness.value = this.choppiness;
 	this.materialSpectrum.uniforms.u_size.value = this.size;
 	this.materialSpectrum.uniforms.u_size.value = this.size;
-	this.renderer.render( this.scene, this.oceanCamera, this.spectrumFramebuffer );
+
+	this.renderer.setRenderTarget( this.spectrumFramebuffer );
+	this.renderer.render( this.scene, this.oceanCamera );
 
 
 };
 };
 
 
-THREE.Ocean.prototype.renderSpectrumFFT = function() {
+THREE.Ocean.prototype.renderSpectrumFFT = function () {
 
 
 	// GPU FFT using Stockham formulation
 	// GPU FFT using Stockham formulation
 	var iterations = Math.log( this.resolution ) / Math.log( 2 ); // log2
 	var iterations = Math.log( this.resolution ) / Math.log( 2 ); // log2
@@ -305,19 +315,25 @@ THREE.Ocean.prototype.renderSpectrumFFT = function() {
 
 
 			this.materialOceanHorizontal.uniforms.u_input.value = this.spectrumFramebuffer.texture;
 			this.materialOceanHorizontal.uniforms.u_input.value = this.spectrumFramebuffer.texture;
 			this.materialOceanHorizontal.uniforms.u_subtransformSize.value = Math.pow( 2, ( i % ( iterations ) ) + 1 );
 			this.materialOceanHorizontal.uniforms.u_subtransformSize.value = Math.pow( 2, ( i % ( iterations ) ) + 1 );
-			this.renderer.render( this.scene, this.oceanCamera, this.pingTransformFramebuffer );
+
+			this.renderer.setRenderTarget( this.pingTransformFramebuffer );
+			this.renderer.render( this.scene, this.oceanCamera );
 
 
 		} else if ( i % 2 === 1 ) {
 		} else if ( i % 2 === 1 ) {
 
 
 			this.materialOceanHorizontal.uniforms.u_input.value = this.pingTransformFramebuffer.texture;
 			this.materialOceanHorizontal.uniforms.u_input.value = this.pingTransformFramebuffer.texture;
 			this.materialOceanHorizontal.uniforms.u_subtransformSize.value = Math.pow( 2, ( i % ( iterations ) ) + 1 );
 			this.materialOceanHorizontal.uniforms.u_subtransformSize.value = Math.pow( 2, ( i % ( iterations ) ) + 1 );
-			this.renderer.render( this.scene, this.oceanCamera, this.pongTransformFramebuffer );
+
+			this.renderer.setRenderTarget( this.pongTransformFramebuffer );
+			this.renderer.render( this.scene, this.oceanCamera );
 
 
 		} else {
 		} else {
 
 
 			this.materialOceanHorizontal.uniforms.u_input.value = this.pongTransformFramebuffer.texture;
 			this.materialOceanHorizontal.uniforms.u_input.value = this.pongTransformFramebuffer.texture;
 			this.materialOceanHorizontal.uniforms.u_subtransformSize.value = Math.pow( 2, ( i % ( iterations ) ) + 1 );
 			this.materialOceanHorizontal.uniforms.u_subtransformSize.value = Math.pow( 2, ( i % ( iterations ) ) + 1 );
-			this.renderer.render( this.scene, this.oceanCamera, this.pingTransformFramebuffer );
+
+			this.renderer.setRenderTarget( this.pingTransformFramebuffer );
+			this.renderer.render( this.scene, this.oceanCamera );
 
 
 		}
 		}
 
 
@@ -329,19 +345,25 @@ THREE.Ocean.prototype.renderSpectrumFFT = function() {
 
 
 			this.materialOceanVertical.uniforms.u_input.value = ( iterations % 2 === 0 ) ? this.pingTransformFramebuffer.texture : this.pongTransformFramebuffer.texture;
 			this.materialOceanVertical.uniforms.u_input.value = ( iterations % 2 === 0 ) ? this.pingTransformFramebuffer.texture : this.pongTransformFramebuffer.texture;
 			this.materialOceanVertical.uniforms.u_subtransformSize.value = Math.pow( 2, ( i % ( iterations ) ) + 1 );
 			this.materialOceanVertical.uniforms.u_subtransformSize.value = Math.pow( 2, ( i % ( iterations ) ) + 1 );
-			this.renderer.render( this.scene, this.oceanCamera, this.displacementMapFramebuffer );
+
+			this.renderer.setRenderTarget( this.displacementMapFramebuffer );
+			this.renderer.render( this.scene, this.oceanCamera );
 
 
 		} else if ( i % 2 === 1 ) {
 		} else if ( i % 2 === 1 ) {
 
 
 			this.materialOceanVertical.uniforms.u_input.value = this.pingTransformFramebuffer.texture;
 			this.materialOceanVertical.uniforms.u_input.value = this.pingTransformFramebuffer.texture;
 			this.materialOceanVertical.uniforms.u_subtransformSize.value = Math.pow( 2, ( i % ( iterations ) ) + 1 );
 			this.materialOceanVertical.uniforms.u_subtransformSize.value = Math.pow( 2, ( i % ( iterations ) ) + 1 );
-			this.renderer.render( this.scene, this.oceanCamera, this.pongTransformFramebuffer );
+
+			this.renderer.setRenderTarget( this.pongTransformFramebuffer );
+			this.renderer.render( this.scene, this.oceanCamera );
 
 
 		} else {
 		} else {
 
 
 			this.materialOceanVertical.uniforms.u_input.value = this.pongTransformFramebuffer.texture;
 			this.materialOceanVertical.uniforms.u_input.value = this.pongTransformFramebuffer.texture;
 			this.materialOceanVertical.uniforms.u_subtransformSize.value = Math.pow( 2, ( i % ( iterations ) ) + 1 );
 			this.materialOceanVertical.uniforms.u_subtransformSize.value = Math.pow( 2, ( i % ( iterations ) ) + 1 );
-			this.renderer.render( this.scene, this.oceanCamera, this.pingTransformFramebuffer );
+
+			this.renderer.setRenderTarget( this.pingTransformFramebuffer );
+			this.renderer.render( this.scene, this.oceanCamera );
 
 
 		}
 		}
 
 
@@ -354,6 +376,9 @@ THREE.Ocean.prototype.renderNormalMap = function () {
 	this.scene.overrideMaterial = this.materialNormal;
 	this.scene.overrideMaterial = this.materialNormal;
 	if ( this.changed ) this.materialNormal.uniforms.u_size.value = this.size;
 	if ( this.changed ) this.materialNormal.uniforms.u_size.value = this.size;
 	this.materialNormal.uniforms.u_displacementMap.value = this.displacementMapFramebuffer.texture;
 	this.materialNormal.uniforms.u_displacementMap.value = this.displacementMapFramebuffer.texture;
-	this.renderer.render( this.scene, this.oceanCamera, this.normalMapFramebuffer, true );
+
+	this.renderer.setRenderTarget( this.normalMapFramebuffer );
+	this.renderer.clear();
+	this.renderer.render( this.scene, this.oceanCamera );
 
 
 };
 };

+ 11 - 2
examples/js/cameras/CinematicCamera.js

@@ -177,22 +177,31 @@ THREE.CinematicCamera.prototype.renderCinematic = function ( scene, renderer ) {
 
 
 	if ( this.postprocessing.enabled ) {
 	if ( this.postprocessing.enabled ) {
 
 
+		var currentRenderTarget = renderer.getRenderTarget();
+
 		renderer.clear();
 		renderer.clear();
 
 
 		// Render scene into texture
 		// Render scene into texture
 
 
 		scene.overrideMaterial = null;
 		scene.overrideMaterial = null;
-		renderer.render( scene, camera, this.postprocessing.rtTextureColor, true );
+		renderer.setRenderTarget( this.postprocessing.rtTextureColor );
+		renderer.clear();
+		renderer.render( scene, camera );
 
 
 		// Render depth into texture
 		// Render depth into texture
 
 
 		scene.overrideMaterial = this.materialDepth;
 		scene.overrideMaterial = this.materialDepth;
-		renderer.render( scene, camera, this.postprocessing.rtTextureDepth, true );
+		renderer.setRenderTarget( this.postprocessing.rtTextureDepth );
+		renderer.clear();
+		renderer.render( scene, camera );
 
 
 		// Render bokeh composite
 		// Render bokeh composite
 
 
+		renderer.setRenderTarget( null );
 		renderer.render( this.postprocessing.scene, this.postprocessing.camera );
 		renderer.render( this.postprocessing.scene, this.postprocessing.camera );
 
 
+		renderer.setRenderTarget( currentRenderTarget );
+
 	}
 	}
 
 
 };
 };

+ 16 - 8
examples/js/controls/OrbitControls.js

@@ -537,36 +537,44 @@ THREE.OrbitControls = function ( object, domElement ) {
 
 
 	function handleKeyDown( event ) {
 	function handleKeyDown( event ) {
 
 
-		//console.log( 'handleKeyDown' );
+		// console.log( 'handleKeyDown' );
 
 
-		// prevent the browser from scrolling on cursor up/down
-
-		event.preventDefault();
+		var needsUpdate = false;
 
 
 		switch ( event.keyCode ) {
 		switch ( event.keyCode ) {
 
 
 			case scope.keys.UP:
 			case scope.keys.UP:
 				pan( 0, scope.keyPanSpeed );
 				pan( 0, scope.keyPanSpeed );
-				scope.update();
+				needsUpdate = true;
 				break;
 				break;
 
 
 			case scope.keys.BOTTOM:
 			case scope.keys.BOTTOM:
 				pan( 0, - scope.keyPanSpeed );
 				pan( 0, - scope.keyPanSpeed );
-				scope.update();
+				needsUpdate = true;
 				break;
 				break;
 
 
 			case scope.keys.LEFT:
 			case scope.keys.LEFT:
 				pan( scope.keyPanSpeed, 0 );
 				pan( scope.keyPanSpeed, 0 );
-				scope.update();
+				needsUpdate = true;
 				break;
 				break;
 
 
 			case scope.keys.RIGHT:
 			case scope.keys.RIGHT:
 				pan( - scope.keyPanSpeed, 0 );
 				pan( - scope.keyPanSpeed, 0 );
-				scope.update();
+				needsUpdate = true;
 				break;
 				break;
 
 
 		}
 		}
 
 
+		if ( needsUpdate ) {
+
+			// prevent the browser from scrolling on cursor keys
+			event.preventDefault();
+
+			scope.update();
+
+		}
+
+
 	}
 	}
 
 
 	function handleTouchStartRotate( event ) {
 	function handleTouchStartRotate( event ) {

+ 0 - 14
examples/js/controls/TransformControls.js

@@ -113,7 +113,6 @@ THREE.TransformControls = function ( camera, domElement ) {
 		domElement.addEventListener( "touchend", onPointerUp, false );
 		domElement.addEventListener( "touchend", onPointerUp, false );
 		domElement.addEventListener( "touchcancel", onPointerUp, false );
 		domElement.addEventListener( "touchcancel", onPointerUp, false );
 		domElement.addEventListener( "touchleave", onPointerUp, false );
 		domElement.addEventListener( "touchleave", onPointerUp, false );
-		domElement.addEventListener( "contextmenu", onContext, false );
 
 
 	}
 	}
 
 
@@ -128,7 +127,6 @@ THREE.TransformControls = function ( camera, domElement ) {
 		domElement.removeEventListener( "touchend", onPointerUp );
 		domElement.removeEventListener( "touchend", onPointerUp );
 		domElement.removeEventListener( "touchcancel", onPointerUp );
 		domElement.removeEventListener( "touchcancel", onPointerUp );
 		domElement.removeEventListener( "touchleave", onPointerUp );
 		domElement.removeEventListener( "touchleave", onPointerUp );
-		domElement.removeEventListener( "contextmenu", onContext );
 
 
 	};
 	};
 
 
@@ -517,12 +515,6 @@ THREE.TransformControls = function ( camera, domElement ) {
 
 
 	// mouse / touch event handlers
 	// mouse / touch event handlers
 
 
-	function onContext( event ) {
-
-		event.preventDefault();
-
-	}
-
 	function onPointerHover( event ) {
 	function onPointerHover( event ) {
 
 
 		if ( !scope.enabled ) return;
 		if ( !scope.enabled ) return;
@@ -535,8 +527,6 @@ THREE.TransformControls = function ( camera, domElement ) {
 
 
 		if ( !scope.enabled ) return;
 		if ( !scope.enabled ) return;
 
 
-		event.preventDefault();
-
 		document.addEventListener( "mousemove", onPointerMove, false );
 		document.addEventListener( "mousemove", onPointerMove, false );
 
 
 		scope.pointerHover( getPointer( event ) );
 		scope.pointerHover( getPointer( event ) );
@@ -548,8 +538,6 @@ THREE.TransformControls = function ( camera, domElement ) {
 
 
 		if ( !scope.enabled ) return;
 		if ( !scope.enabled ) return;
 
 
-		event.preventDefault();
-
 		scope.pointerMove( getPointer( event ) );
 		scope.pointerMove( getPointer( event ) );
 
 
 	}
 	}
@@ -558,8 +546,6 @@ THREE.TransformControls = function ( camera, domElement ) {
 
 
 		if ( !scope.enabled ) return;
 		if ( !scope.enabled ) return;
 
 
-		event.preventDefault(); // Prevent MouseEvent on mobile
-
 		document.removeEventListener( "mousemove", onPointerMove, false );
 		document.removeEventListener( "mousemove", onPointerMove, false );
 
 
 		scope.pointerUp( getPointer( event ) );
 		scope.pointerUp( getPointer( event ) );

+ 11 - 3
examples/js/crossfade/scenes.js

@@ -101,11 +101,19 @@ function Scene( type, numObjects, cameraZ, fov, rotationSpeed, clearColor ) {
 
 
 		renderer.setClearColor( this.clearColor );
 		renderer.setClearColor( this.clearColor );
 
 
-		if ( rtt )
-			renderer.render( this.scene, this.camera, this.fbo, true );
-		else
+		if ( rtt ) {
+
+			renderer.setRenderTarget( this.fbo );
+			renderer.clear();
+			renderer.render( this.scene, this.camera );
+
+		} else {
+
+			renderer.setRenderTarget( null );
 			renderer.render( this.scene, this.camera );
 			renderer.render( this.scene, this.camera );
 
 
+		}
+
 	};
 	};
 
 
 }
 }

+ 4 - 2
examples/js/crossfade/transition.js

@@ -1,4 +1,4 @@
-function Transition ( sceneA, sceneB ) {
+function Transition( sceneA, sceneB ) {
 
 
 	this.scene = new THREE.Scene();
 	this.scene = new THREE.Scene();
 
 
@@ -157,7 +157,9 @@ function Transition ( sceneA, sceneB ) {
 
 
 			this.sceneA.render( delta, true );
 			this.sceneA.render( delta, true );
 			this.sceneB.render( delta, true );
 			this.sceneB.render( delta, true );
-			renderer.render( this.scene, this.cameraOrtho, null, true );
+			renderer.setRenderTarget( null );
+			renderer.clear();
+			renderer.render( this.scene, this.cameraOrtho );
 
 
 		}
 		}
 
 

+ 13 - 2
examples/js/effects/AnaglyphEffect.js

@@ -130,16 +130,27 @@ THREE.AnaglyphEffect = function ( renderer, width, height ) {
 
 
 	this.render = function ( scene, camera ) {
 	this.render = function ( scene, camera ) {
 
 
+		var currentRenderTarget = renderer.getRenderTarget();
+
 		scene.updateMatrixWorld();
 		scene.updateMatrixWorld();
 
 
 		if ( camera.parent === null ) camera.updateMatrixWorld();
 		if ( camera.parent === null ) camera.updateMatrixWorld();
 
 
 		_stereo.update( camera );
 		_stereo.update( camera );
 
 
-		renderer.render( scene, _stereo.cameraL, _renderTargetL, true );
-		renderer.render( scene, _stereo.cameraR, _renderTargetR, true );
+		renderer.setRenderTarget( _renderTargetL );
+		renderer.clear();
+		renderer.render( scene, _stereo.cameraL );
+
+		renderer.setRenderTarget( _renderTargetR );
+		renderer.clear();
+		renderer.render( scene, _stereo.cameraR );
+
+		renderer.setRenderTarget( null );
 		renderer.render( _scene, _camera );
 		renderer.render( _scene, _camera );
 
 
+		renderer.setRenderTarget( currentRenderTarget );
+
 	};
 	};
 
 
 	this.dispose = function () {
 	this.dispose = function () {

+ 27 - 6
examples/js/effects/OutlineEffect.js

@@ -402,11 +402,32 @@ THREE.OutlineEffect = function ( renderer, parameters ) {
 
 
 	}
 	}
 
 
-	this.render = function ( scene, camera, renderTarget, forceClear ) {
+	this.render = function ( scene, camera ) {
+
+		var renderTarget = null;
+		var forceClear = false;
+
+		if ( arguments[ 2 ] !== undefined ) {
+
+			console.warn( 'THREE.OutlineEffect.render(): the renderTarget argument has been removed. Use .setRenderTarget() instead.' );
+			renderTarget = arguments[ 2 ];
+
+		}
+
+		if ( arguments[ 3 ] !== undefined ) {
+
+			console.warn( 'THREE.OutlineEffect.render(): the forceClear argument has been removed. Use .clear() instead.' );
+			forceClear = arguments[ 3 ];
+
+		}
+
+		renderer.setRenderTarget( renderTarget );
+
+		if ( forceClear ) renderer.clear();
 
 
 		if ( this.enabled === false ) {
 		if ( this.enabled === false ) {
 
 
-			renderer.render( scene, camera, renderTarget, forceClear );
+			renderer.render( scene, camera );
 			return;
 			return;
 
 
 		}
 		}
@@ -415,7 +436,7 @@ THREE.OutlineEffect = function ( renderer, parameters ) {
 		renderer.autoClear = this.autoClear;
 		renderer.autoClear = this.autoClear;
 
 
 		// 1. render normally
 		// 1. render normally
-		renderer.render( scene, camera, renderTarget, forceClear );
+		renderer.render( scene, camera );
 
 
 		// 2. render outline
 		// 2. render outline
 		var currentSceneAutoUpdate = scene.autoUpdate;
 		var currentSceneAutoUpdate = scene.autoUpdate;
@@ -429,7 +450,7 @@ THREE.OutlineEffect = function ( renderer, parameters ) {
 
 
 		scene.traverse( setOutlineMaterial );
 		scene.traverse( setOutlineMaterial );
 
 
-		renderer.render( scene, camera, renderTarget );
+		renderer.render( scene, camera );
 
 
 		scene.traverse( restoreOriginalMaterial );
 		scene.traverse( restoreOriginalMaterial );
 
 
@@ -478,9 +499,9 @@ THREE.OutlineEffect = function ( renderer, parameters ) {
 
 
 	};
 	};
 
 
-	this.getSize = function () {
+	this.getSize = function ( target ) {
 
 
-		return renderer.getSize();
+		return renderer.getSize( target );
 
 
 	};
 	};
 
 

+ 9 - 2
examples/js/effects/ParallaxBarrierEffect.js

@@ -87,8 +87,15 @@ THREE.ParallaxBarrierEffect = function ( renderer ) {
 
 
 		_stereo.update( camera );
 		_stereo.update( camera );
 
 
-		renderer.render( scene, _stereo.cameraL, _renderTargetL, true );
-		renderer.render( scene, _stereo.cameraR, _renderTargetR, true );
+		renderer.setRenderTarget( _renderTargetL );
+		renderer.clear();
+		renderer.render( scene, _stereo.cameraL );
+
+		renderer.setRenderTarget( _renderTargetR );
+		renderer.clear();
+		renderer.render( scene, _stereo.cameraR );
+
+		renderer.setRenderTarget( null );
 		renderer.render( _scene, _camera );
 		renderer.render( _scene, _camera );
 
 
 	};
 	};

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

@@ -9,6 +9,7 @@ THREE.StereoEffect = function ( renderer ) {
 
 
 	var _stereo = new THREE.StereoCamera();
 	var _stereo = new THREE.StereoCamera();
 	_stereo.aspect = 0.5;
 	_stereo.aspect = 0.5;
+	var size = new THREE.Vector2();
 
 
 	this.setEyeSeparation = function ( eyeSep ) {
 	this.setEyeSeparation = function ( eyeSep ) {
 
 
@@ -30,7 +31,7 @@ THREE.StereoEffect = function ( renderer ) {
 
 
 		_stereo.update( camera );
 		_stereo.update( camera );
 
 
-		var size = renderer.getSize();
+		renderer.getSize( size );
 
 
 		if ( renderer.autoClear ) renderer.clear();
 		if ( renderer.autoClear ) renderer.clear();
 		renderer.setScissorTest( true );
 		renderer.setScissorTest( true );

+ 3 - 1
examples/js/exporters/GLTFExporter.js

@@ -1079,6 +1079,8 @@ THREE.GLTFExporter.prototype = {
 
 
 				if ( ! geometry.isBufferGeometry ) {
 				if ( ! geometry.isBufferGeometry ) {
 
 
+					console.warn( 'GLTFExporter: Exporting THREE.Geometry will increase file size. Use THREE.BufferGeometry instead.' );
+
 					var geometryTemp = new THREE.BufferGeometry();
 					var geometryTemp = new THREE.BufferGeometry();
 					geometryTemp.fromGeometry( geometry );
 					geometryTemp.fromGeometry( geometry );
 					geometry = geometryTemp;
 					geometry = geometryTemp;
@@ -1408,7 +1410,7 @@ THREE.GLTFExporter.prototype = {
 				gltfCamera.perspective = {
 				gltfCamera.perspective = {
 
 
 					aspectRatio: camera.aspect,
 					aspectRatio: camera.aspect,
-					yfov: THREE.Math.degToRad( camera.fov ) / camera.aspect,
+					yfov: THREE.Math.degToRad( camera.fov ),
 					zfar: camera.far <= 0 ? 0.001 : camera.far,
 					zfar: camera.far <= 0 ? 0.001 : camera.far,
 					znear: camera.near < 0 ? 0 : camera.near
 					znear: camera.near < 0 ? 0 : camera.near
 
 

+ 7 - 3
examples/js/loaders/AssimpJSONLoader.js

@@ -169,12 +169,13 @@ THREE.AssimpJSONLoader.prototype = {
 
 
 						// prop.semantic gives the type of the texture
 						// prop.semantic gives the type of the texture
 						// 1: diffuse
 						// 1: diffuse
-						// 2: specular mao
+						// 2: specular map
+						// 4: emissive map
 						// 5: height map (bumps)
 						// 5: height map (bumps)
 						// 6: normal map
 						// 6: normal map
-						// more values (i.e. emissive, environment) are known by assimp and may be relevant
+						// more values (i.e. environment, etc) are known by assimp and may be relevant
 
 
-						if ( semantic === 1 || semantic === 2 || semantic === 5 || semantic === 6 ) {
+						if ( semantic === 1 || semantic === 2 || semantic === 4 || semantic === 5 || semantic === 6 ) {
 
 
 							var keyname;
 							var keyname;
 
 
@@ -186,6 +187,9 @@ THREE.AssimpJSONLoader.prototype = {
 								case 2:
 								case 2:
 									keyname = 'specularMap';
 									keyname = 'specularMap';
 									break;
 									break;
+								case 4:
+									keyname = 'emissiveMap';
+									break;
 								case 5:
 								case 5:
 									keyname = 'bumpMap';
 									keyname = 'bumpMap';
 									break;
 									break;

+ 14 - 6
examples/js/loaders/EquirectangularToCubeGenerator.js

@@ -11,6 +11,8 @@ THREE.CubemapGenerator = function ( renderer ) {
 
 
 THREE.CubemapGenerator.prototype.fromEquirectangular = function ( texture, options ) {
 THREE.CubemapGenerator.prototype.fromEquirectangular = function ( texture, options ) {
 
 
+	options = options || {};
+
 	var scene = new THREE.Scene();
 	var scene = new THREE.Scene();
 
 
 	var shader = {
 	var shader = {
@@ -92,9 +94,9 @@ THREE.CubemapGenerator.prototype.fromEquirectangular = function ( texture, optio
 		type: texture.type,
 		type: texture.type,
 		format: texture.format,
 		format: texture.format,
 		encoding: texture.encoding,
 		encoding: texture.encoding,
-		generateMipmaps: ( options.generateMipmaps !== undefined ) ?  options.generateMipmaps : texture.generateMipmaps,
-		minFilter: ( options.minFilter !== undefined ) ?  options.minFilter : texture.minFilter,
-		magFilter: ( options.magFilter !== undefined ) ?  options.magFilter : texture.magFilter
+		generateMipmaps: ( options.generateMipmaps !== undefined ) ? options.generateMipmaps : texture.generateMipmaps,
+		minFilter: ( options.minFilter !== undefined ) ? options.minFilter : texture.minFilter,
+		magFilter: ( options.magFilter !== undefined ) ? options.magFilter : texture.magFilter
 	};
 	};
 
 
 	var camera = new THREE.CubeCamera( 1, 10, resolution, params );
 	var camera = new THREE.CubeCamera( 1, 10, resolution, params );
@@ -120,6 +122,8 @@ THREE.EquirectangularToCubeGenerator = ( function () {
 
 
 	var EquirectangularToCubeGenerator = function ( sourceTexture, options ) {
 	var EquirectangularToCubeGenerator = function ( sourceTexture, options ) {
 
 
+		options = options || {};
+
 		this.sourceTexture = sourceTexture;
 		this.sourceTexture = sourceTexture;
 		this.resolution = options.resolution || 512;
 		this.resolution = options.resolution || 512;
 
 
@@ -152,22 +156,26 @@ THREE.EquirectangularToCubeGenerator = ( function () {
 
 
 		update: function ( renderer ) {
 		update: function ( renderer ) {
 
 
+			var currentRenderTarget = renderer.getRenderTarget();
+
 			boxMesh.material.uniforms.equirectangularMap.value = this.sourceTexture;
 			boxMesh.material.uniforms.equirectangularMap.value = this.sourceTexture;
 
 
 			for ( var i = 0; i < 6; i ++ ) {
 			for ( var i = 0; i < 6; i ++ ) {
 
 
-				this.renderTarget.activeCubeFace = i;
-
 				var v = this.views[ i ];
 				var v = this.views[ i ];
 
 
 				camera.position.set( 0, 0, 0 );
 				camera.position.set( 0, 0, 0 );
 				camera.up.set( v.u[ 0 ], v.u[ 1 ], v.u[ 2 ] );
 				camera.up.set( v.u[ 0 ], v.u[ 1 ], v.u[ 2 ] );
 				camera.lookAt( v.t[ 0 ], v.t[ 1 ], v.t[ 2 ] );
 				camera.lookAt( v.t[ 0 ], v.t[ 1 ], v.t[ 2 ] );
 
 
-				renderer.render( scene, camera, this.renderTarget, true );
+				renderer.setRenderTarget( this.renderTarget, i );
+				renderer.clear();
+				renderer.render( scene, camera );
 
 
 			}
 			}
 
 
+			renderer.setRenderTarget( currentRenderTarget );
+
 			return this.renderTarget.texture;
 			return this.renderTarget.texture;
 
 
 		},
 		},

+ 2 - 1
examples/js/loaders/FBXLoader.js

@@ -44,6 +44,7 @@ THREE.FBXLoader = ( function () {
 			var path = ( self.path === undefined ) ? THREE.LoaderUtils.extractUrlBase( url ) : self.path;
 			var path = ( self.path === undefined ) ? THREE.LoaderUtils.extractUrlBase( url ) : self.path;
 
 
 			var loader = new THREE.FileLoader( this.manager );
 			var loader = new THREE.FileLoader( this.manager );
+			loader.setPath( self.path );
 			loader.setResponseType( 'arraybuffer' );
 			loader.setResponseType( 'arraybuffer' );
 
 
 			loader.load( url, function ( buffer ) {
 			loader.load( url, function ( buffer ) {
@@ -2509,7 +2510,7 @@ THREE.FBXLoader = ( function () {
 
 
 										sceneGraph.traverse( function ( child ) {
 										sceneGraph.traverse( function ( child ) {
 
 
-											if ( child.ID = rawModel.id ) {
+											if ( child.ID === rawModel.id ) {
 
 
 												node.transform = child.matrix;
 												node.transform = child.matrix;
 
 

+ 18 - 10
examples/js/loaders/GLTFLoader.js

@@ -189,7 +189,7 @@ THREE.GLTFLoader = ( function () {
 							break;
 							break;
 
 
 						case EXTENSIONS.MSFT_TEXTURE_DDS:
 						case EXTENSIONS.MSFT_TEXTURE_DDS:
-							extensions[ EXTENSIONS.MSFT_TEXTURE_DDS ] = new GLTFTextureDDSExtension( json );
+							extensions[ EXTENSIONS.MSFT_TEXTURE_DDS ] = new GLTFTextureDDSExtension();
 							break;
 							break;
 
 
 						case EXTENSIONS.KHR_TEXTURE_TRANSFORM:
 						case EXTENSIONS.KHR_TEXTURE_TRANSFORM:
@@ -1202,6 +1202,7 @@ THREE.GLTFLoader = ( function () {
 	var ATTRIBUTES = {
 	var ATTRIBUTES = {
 		POSITION: 'position',
 		POSITION: 'position',
 		NORMAL: 'normal',
 		NORMAL: 'normal',
+		TANGENT: 'tangent',
 		TEXCOORD_0: 'uv',
 		TEXCOORD_0: 'uv',
 		TEXCOORD_1: 'uv2',
 		TEXCOORD_1: 'uv2',
 		COLOR_0: 'color',
 		COLOR_0: 'color',
@@ -2232,6 +2233,18 @@ THREE.GLTFLoader = ( function () {
 
 
 		return this.getDependency( 'texture', mapDef.index ).then( function ( texture ) {
 		return this.getDependency( 'texture', mapDef.index ).then( function ( texture ) {
 
 
+			switch ( mapName ) {
+
+				case 'aoMap':
+				case 'emissiveMap':
+				case 'metalnessMap':
+				case 'normalMap':
+				case 'roughnessMap':
+					texture.format = THREE.RGBFormat;
+					break;
+
+			}
+
 			if ( parser.extensions[ EXTENSIONS.KHR_TEXTURE_TRANSFORM ] ) {
 			if ( parser.extensions[ EXTENSIONS.KHR_TEXTURE_TRANSFORM ] ) {
 
 
 				var transform = mapDef.extensions !== undefined ? mapDef.extensions[ EXTENSIONS.KHR_TEXTURE_TRANSFORM ] : undefined;
 				var transform = mapDef.extensions !== undefined ? mapDef.extensions[ EXTENSIONS.KHR_TEXTURE_TRANSFORM ] : undefined;
@@ -2397,14 +2410,6 @@ THREE.GLTFLoader = ( function () {
 
 
 			if ( materialDef.name !== undefined ) material.name = materialDef.name;
 			if ( materialDef.name !== undefined ) material.name = materialDef.name;
 
 
-			// Normal map textures use OpenGL conventions:
-			// https://github.com/KhronosGroup/glTF/tree/master/specification/2.0#materialnormaltexture
-			if ( material.normalScale ) {
-
-				material.normalScale.y = - material.normalScale.y;
-
-			}
-
 			// baseColorTexture, emissiveTexture, and specularGlossinessTexture use sRGB encoding.
 			// baseColorTexture, emissiveTexture, and specularGlossinessTexture use sRGB encoding.
 			if ( material.map ) material.map.encoding = THREE.sRGBEncoding;
 			if ( material.map ) material.map.encoding = THREE.sRGBEncoding;
 			if ( material.emissiveMap ) material.emissiveMap.encoding = THREE.sRGBEncoding;
 			if ( material.emissiveMap ) material.emissiveMap.encoding = THREE.sRGBEncoding;
@@ -2762,6 +2767,7 @@ THREE.GLTFLoader = ( function () {
 
 
 					var materials = isMultiMaterial ? mesh.material : [ mesh.material ];
 					var materials = isMultiMaterial ? mesh.material : [ mesh.material ];
 
 
+					var useVertexTangents = geometry.attributes.tangent !== undefined;
 					var useVertexColors = geometry.attributes.color !== undefined;
 					var useVertexColors = geometry.attributes.color !== undefined;
 					var useFlatShading = geometry.attributes.normal === undefined;
 					var useFlatShading = geometry.attributes.normal === undefined;
 					var useSkinning = mesh.isSkinnedMesh === true;
 					var useSkinning = mesh.isSkinnedMesh === true;
@@ -2814,12 +2820,13 @@ THREE.GLTFLoader = ( function () {
 						}
 						}
 
 
 						// Clone the material if it will be modified
 						// Clone the material if it will be modified
-						if ( useVertexColors || useFlatShading || useSkinning || useMorphTargets ) {
+						if ( useVertexTangents || useVertexColors || useFlatShading || useSkinning || useMorphTargets ) {
 
 
 							var cacheKey = 'ClonedMaterial:' + material.uuid + ':';
 							var cacheKey = 'ClonedMaterial:' + material.uuid + ':';
 
 
 							if ( material.isGLTFSpecularGlossinessMaterial ) cacheKey += 'specular-glossiness:';
 							if ( material.isGLTFSpecularGlossinessMaterial ) cacheKey += 'specular-glossiness:';
 							if ( useSkinning ) cacheKey += 'skinning:';
 							if ( useSkinning ) cacheKey += 'skinning:';
+							if ( useVertexTangents ) cacheKey += 'vertex-tangents:';
 							if ( useVertexColors ) cacheKey += 'vertex-colors:';
 							if ( useVertexColors ) cacheKey += 'vertex-colors:';
 							if ( useFlatShading ) cacheKey += 'flat-shading:';
 							if ( useFlatShading ) cacheKey += 'flat-shading:';
 							if ( useMorphTargets ) cacheKey += 'morph-targets:';
 							if ( useMorphTargets ) cacheKey += 'morph-targets:';
@@ -2834,6 +2841,7 @@ THREE.GLTFLoader = ( function () {
 									: material.clone();
 									: material.clone();
 
 
 								if ( useSkinning ) cachedMaterial.skinning = true;
 								if ( useSkinning ) cachedMaterial.skinning = true;
+								if ( useVertexTangents ) cachedMaterial.vertexTangents = true;
 								if ( useVertexColors ) cachedMaterial.vertexColors = THREE.VertexColors;
 								if ( useVertexColors ) cachedMaterial.vertexColors = THREE.VertexColors;
 								if ( useFlatShading ) cachedMaterial.flatShading = true;
 								if ( useFlatShading ) cachedMaterial.flatShading = true;
 								if ( useMorphTargets ) cachedMaterial.morphTargets = true;
 								if ( useMorphTargets ) cachedMaterial.morphTargets = true;

+ 57 - 67
examples/js/loaders/LDrawLoader.js

@@ -66,13 +66,13 @@ THREE.LDrawLoader = ( function () {
 
 
 		},
 		},
 
 
-		getRemainingString: function() {
+		getRemainingString: function () {
 
 
 			return this.line.substring( this.currentCharIndex, this.lineLength );
 			return this.line.substring( this.currentCharIndex, this.lineLength );
 
 
 		},
 		},
 
 
-		isAtTheEnd: function() {
+		isAtTheEnd: function () {
 
 
 			return this.currentCharIndex >= this.lineLength;
 			return this.currentCharIndex >= this.lineLength;
 
 
@@ -86,21 +86,27 @@ THREE.LDrawLoader = ( function () {
 
 
 		getLineNumberString: function () {
 		getLineNumberString: function () {
 
 
-			return this.lineNumber >= 0? " at line " + this.lineNumber: "";
+			return this.lineNumber >= 0 ? " at line " + this.lineNumber : "";
 
 
 		}
 		}
 
 
 
 
 	};
 	};
 
 
-	function sortByMaterial ( a, b ) {
+	function sortByMaterial( a, b ) {
 
 
 		if ( a.colourCode === b.colourCode ) {
 		if ( a.colourCode === b.colourCode ) {
+
 			return 0;
 			return 0;
+
 		}
 		}
+
 		if ( a.colourCode < b.colourCode ) {
 		if ( a.colourCode < b.colourCode ) {
-			return -1;
+
+			return - 1;
+
 		}
 		}
+
 		return 1;
 		return 1;
 
 
 	}
 	}
@@ -149,14 +155,14 @@ THREE.LDrawLoader = ( function () {
 				index0 = iElem * elementSize;
 				index0 = iElem * elementSize;
 				numGroupVerts = elementSize;
 				numGroupVerts = elementSize;
 
 
-			}
-			else {
+			} else {
 
 
 				numGroupVerts += elementSize;
 				numGroupVerts += elementSize;
 
 
 			}
 			}
 
 
 		}
 		}
+
 		if ( numGroupVerts > 0 ) {
 		if ( numGroupVerts > 0 ) {
 
 
 			bufferGeometry.addGroup( index0, Infinity, materials.length - 1 );
 			bufferGeometry.addGroup( index0, Infinity, materials.length - 1 );
@@ -166,12 +172,12 @@ THREE.LDrawLoader = ( function () {
 		bufferGeometry.addAttribute( 'position', new THREE.Float32BufferAttribute( vertices, 3 ) );
 		bufferGeometry.addAttribute( 'position', new THREE.Float32BufferAttribute( vertices, 3 ) );
 
 
 		var object3d = null;
 		var object3d = null;
+
 		if ( elementSize === 2 ) {
 		if ( elementSize === 2 ) {
 
 
 			object3d = new THREE.LineSegments( bufferGeometry, materials );
 			object3d = new THREE.LineSegments( bufferGeometry, materials );
 
 
-		}
-		else if ( elementSize === 3 ) {
+		} else if ( elementSize === 3 ) {
 
 
 			bufferGeometry.computeVertexNormals();
 			bufferGeometry.computeVertexNormals();
 
 
@@ -259,7 +265,7 @@ THREE.LDrawLoader = ( function () {
 
 
 			var fileLoader = new THREE.FileLoader( this.manager );
 			var fileLoader = new THREE.FileLoader( this.manager );
 			fileLoader.setPath( this.path );
 			fileLoader.setPath( this.path );
-			fileLoader.load( url, function( text ) {
+			fileLoader.load( url, function ( text ) {
 
 
 				processObject( text, onLoad );
 				processObject( text, onLoad );
 
 
@@ -308,10 +314,10 @@ THREE.LDrawLoader = ( function () {
 							finalizeObject();
 							finalizeObject();
 
 
 						}
 						}
+
 					}
 					}
 
 
-				}
-				else {
+				} else {
 
 
 					// No subobjects, finish object
 					// No subobjects, finish object
 					finalizeObject();
 					finalizeObject();
@@ -349,7 +355,7 @@ THREE.LDrawLoader = ( function () {
 
 
 				}
 				}
 
 
-				function loadSubobject ( subobject, sync ) {
+				function loadSubobject( subobject, sync ) {
 
 
 					parseScope.mainColourCode = subobject.material.userData.code;
 					parseScope.mainColourCode = subobject.material.userData.code;
 					parseScope.mainEdgeColourCode = subobject.material.userData.edgeMaterial.userData.code;
 					parseScope.mainEdgeColourCode = subobject.material.userData.edgeMaterial.userData.code;
@@ -416,8 +422,7 @@ THREE.LDrawLoader = ( function () {
 								// Try absolute path
 								// Try absolute path
 								newLocationState = LDrawLoader.FILE_LOCATION_NOT_FOUND;
 								newLocationState = LDrawLoader.FILE_LOCATION_NOT_FOUND;
 
 
-							}
-							else {
+							} else {
 
 
 								// Next attempt is lower case
 								// Next attempt is lower case
 								subobject.fileName = subobject.fileName.toLowerCase();
 								subobject.fileName = subobject.fileName.toLowerCase();
@@ -442,8 +447,7 @@ THREE.LDrawLoader = ( function () {
 								scope.removeScopeLevel();
 								scope.removeScopeLevel();
 								onProcessed( objGroup );
 								onProcessed( objGroup );
 
 
-							}
-							else {
+							} else {
 
 
 								// Load next subobject
 								// Load next subobject
 								loadSubobject( parseScope.subobjects[ parseScope.subobjectIndex ] );
 								loadSubobject( parseScope.subobjects[ parseScope.subobjectIndex ] );
@@ -485,8 +489,7 @@ THREE.LDrawLoader = ( function () {
 
 
 						loadSubobject( parseScope.subobjects[ parseScope.subobjectIndex ] );
 						loadSubobject( parseScope.subobjects[ parseScope.subobjectIndex ] );
 
 
-					}
-					else {
+					} else {
 
 
 						finalizeObject();
 						finalizeObject();
 
 
@@ -494,7 +497,7 @@ THREE.LDrawLoader = ( function () {
 
 
 				}
 				}
 
 
-				function addSubobject ( subobject, subobjectGroup ) {
+				function addSubobject( subobject, subobjectGroup ) {
 
 
 					if ( scope.separateObjects ) {
 					if ( scope.separateObjects ) {
 
 
@@ -546,7 +549,7 @@ THREE.LDrawLoader = ( function () {
 
 
 		},
 		},
 
 
-		setFileMap: function( fileMap ) {
+		setFileMap: function ( fileMap ) {
 
 
 			this.fileMap = fileMap;
 			this.fileMap = fileMap;
 
 
@@ -601,7 +604,7 @@ THREE.LDrawLoader = ( function () {
 
 
 		},
 		},
 
 
-		removeScopeLevel: function() {
+		removeScopeLevel: function () {
 
 
 			this.parseScopesStack.pop();
 			this.parseScopesStack.pop();
 
 
@@ -641,7 +644,7 @@ THREE.LDrawLoader = ( function () {
 
 
 			}
 			}
 
 
-			for ( var i = this.parseScopesStack.length - 1; i >= 0; i-- ) {
+			for ( var i = this.parseScopesStack.length - 1; i >= 0; i -- ) {
 
 
 				var material = this.parseScopesStack[ i ].lib[ colourCode ];
 				var material = this.parseScopesStack[ i ].lib[ colourCode ];
 
 
@@ -736,9 +739,10 @@ THREE.LDrawLoader = ( function () {
 
 
 							colour = '#' + colour.substring( 2 );
 							colour = '#' + colour.substring( 2 );
 
 
-						}
-						else if ( ! colour.startsWith( '#' ) ) {
+						} else if ( ! colour.startsWith( '#' ) ) {
+
 							throw 'LDrawLoader: Invalid colour while parsing material' + lineParser.getLineNumberString() + ".";
 							throw 'LDrawLoader: Invalid colour while parsing material' + lineParser.getLineNumberString() + ".";
+
 						}
 						}
 						break;
 						break;
 
 
@@ -749,8 +753,7 @@ THREE.LDrawLoader = ( function () {
 
 
 							edgeColour = '#' + edgeColour.substring( 2 );
 							edgeColour = '#' + edgeColour.substring( 2 );
 
 
-						}
-						else if ( ! edgeColour.startsWith( '#' ) ) {
+						} else if ( ! edgeColour.startsWith( '#' ) ) {
 
 
 							// Try to see if edge colour is a colour code
 							// Try to see if edge colour is a colour code
 							edgeMaterial = this.getMaterial( edgeColour );
 							edgeMaterial = this.getMaterial( edgeColour );
@@ -849,13 +852,13 @@ THREE.LDrawLoader = ( function () {
 						// Default plastic material with shiny specular
 						// Default plastic material with shiny specular
 						hsl.l = Math.min( 1, hsl.l + ( 1 - hsl.l ) * 0.12 );
 						hsl.l = Math.min( 1, hsl.l + ( 1 - hsl.l ) * 0.12 );
 
 
-					}
-					else {
+					} else {
 
 
 						// Try to imitate pearlescency by setting the specular to the complementary of the color, and low shininess
 						// Try to imitate pearlescency by setting the specular to the complementary of the color, and low shininess
 						hsl.h = ( hsl.h + 0.5 ) % 1;
 						hsl.h = ( hsl.h + 0.5 ) % 1;
 						hsl.l = Math.min( 1, hsl.l + ( 1 - hsl.l ) * 0.7 );
 						hsl.l = Math.min( 1, hsl.l + ( 1 - hsl.l ) * 0.7 );
 						shininess = 10;
 						shininess = 10;
+
 					}
 					}
 
 
 					specular.setHSL( hsl.h, hsl.s, hsl.l );
 					specular.setHSL( hsl.h, hsl.s, hsl.l );
@@ -891,6 +894,7 @@ THREE.LDrawLoader = ( function () {
 				default:
 				default:
 					// Should not happen
 					// Should not happen
 					break;
 					break;
+
 			}
 			}
 
 
 			// BFC (Back Face Culling) LDraw language meta extension is not implemented, so set all materials double-sided:
 			// BFC (Back Face Culling) LDraw language meta extension is not implemented, so set all materials double-sided:
@@ -902,15 +906,19 @@ THREE.LDrawLoader = ( function () {
 			material.userData.canHaveEnvMap = canHaveEnvMap;
 			material.userData.canHaveEnvMap = canHaveEnvMap;
 
 
 			if ( luminance !== 0 ) {
 			if ( luminance !== 0 ) {
+
 				material.emissive.set( material.color ).multiplyScalar( luminance );
 				material.emissive.set( material.color ).multiplyScalar( luminance );
+
 			}
 			}
 
 
 			if ( ! edgeMaterial ) {
 			if ( ! edgeMaterial ) {
+
 				// This is the material used for edges
 				// This is the material used for edges
 				edgeMaterial = new THREE.LineBasicMaterial( { color: edgeColour } );
 				edgeMaterial = new THREE.LineBasicMaterial( { color: edgeColour } );
 				edgeMaterial.userData.code = code;
 				edgeMaterial.userData.code = code;
 				edgeMaterial.name = name + " - Edge";
 				edgeMaterial.name = name + " - Edge";
 				edgeMaterial.userData.canHaveEnvMap = false;
 				edgeMaterial.userData.canHaveEnvMap = false;
+
 			}
 			}
 
 
 			material.userData.code = code;
 			material.userData.code = code;
@@ -948,8 +956,7 @@ THREE.LDrawLoader = ( function () {
 				triangles = [];
 				triangles = [];
 				lineSegments = [];
 				lineSegments = [];
 
 
-			}
-			else {
+			} else {
 
 
 				if ( this.currentGroupObject === null ) {
 				if ( this.currentGroupObject === null ) {
 
 
@@ -1014,7 +1021,7 @@ THREE.LDrawLoader = ( function () {
 
 
 			}
 			}
 
 
-			function parseVector ( lp ) {
+			function parseVector( lp ) {
 
 
 				var v = new THREE.Vector3( parseFloat( lp.getToken() ), parseFloat( lp.getToken() ), parseFloat( lp.getToken() ) );
 				var v = new THREE.Vector3( parseFloat( lp.getToken() ), parseFloat( lp.getToken() ), parseFloat( lp.getToken() ) );
 
 
@@ -1028,24 +1035,10 @@ THREE.LDrawLoader = ( function () {
 
 
 			}
 			}
 
 
-			function findSubobject( fileName ) {
-
-				for ( var i = 0, n = subobjects.length; i < n; i ++ ) {
-
-					if ( subobjects[ i ].fileName === fileName ) {
-						return subobjects[ i ];
-					}
-
-					return null;
-
-				}
-
-			}
-
 			// Parse all line commands
 			// Parse all line commands
 			for ( lineIndex = 0; lineIndex < numLines; lineIndex ++ ) {
 			for ( lineIndex = 0; lineIndex < numLines; lineIndex ++ ) {
 
 
-				line = lines[ lineIndex ];
+				var line = lines[ lineIndex ];
 
 
 				if ( line.length === 0 ) continue;
 				if ( line.length === 0 ) continue;
 
 
@@ -1060,8 +1053,7 @@ THREE.LDrawLoader = ( function () {
 						currentEmbeddedFileName = line.substring( 7 );
 						currentEmbeddedFileName = line.substring( 7 );
 						currentEmbeddedText = '';
 						currentEmbeddedText = '';
 
 
-					}
-					else {
+					} else {
 
 
 						currentEmbeddedText += line + '\n';
 						currentEmbeddedText += line + '\n';
 
 
@@ -1076,8 +1068,10 @@ THREE.LDrawLoader = ( function () {
 				lp.seekNonSpace();
 				lp.seekNonSpace();
 
 
 				if ( lp.isAtTheEnd() ) {
 				if ( lp.isAtTheEnd() ) {
+
 					// Empty line
 					// Empty line
 					continue;
 					continue;
+
 				}
 				}
 
 
 				// Parse the line type
 				// Parse the line type
@@ -1102,10 +1096,9 @@ THREE.LDrawLoader = ( function () {
 
 
 										this.addMaterial( material );
 										this.addMaterial( material );
 
 
-									}
-									else {
+									}	else {
 
 
-										console.warn( 'LDrawLoader: Error parsing material' + lineParser.getLineNumberString() );
+										console.warn( 'LDrawLoader: Error parsing material' + lp.getLineNumberString() );
 
 
 									}
 									}
 									break;
 									break;
@@ -1117,22 +1110,22 @@ THREE.LDrawLoader = ( function () {
 
 
 								case '!KEYWORDS':
 								case '!KEYWORDS':
 
 
-										var newKeywords = lp.getRemainingString().split( ',' );
-										if ( newKeywords.length > 0 ) {
+									var newKeywords = lp.getRemainingString().split( ',' );
+									if ( newKeywords.length > 0 ) {
 
 
-											if ( ! keywords ) {
+										if ( ! keywords ) {
 
 
-												keywords = [];
+											keywords = [];
 
 
-											}
+										}
 
 
-											newKeywords.forEach( function( keyword ) {
+										newKeywords.forEach( function ( keyword ) {
 
 
-												keywords.push( keyword.trim() );
+											keywords.push( keyword.trim() );
 
 
-											} );
+										} );
 
 
-										}
+									}
 									break;
 									break;
 
 
 								case 'FILE':
 								case 'FILE':
@@ -1190,16 +1183,14 @@ THREE.LDrawLoader = ( function () {
 							// Found the subobject path in the preloaded file path map
 							// Found the subobject path in the preloaded file path map
 							fileName = scope.fileMap[ fileName ];
 							fileName = scope.fileMap[ fileName ];
 
 
-						}
-						else {
+						}	else {
 
 
 							// Standardized subfolders
 							// Standardized subfolders
 							if ( fileName.startsWith( 's/' ) ) {
 							if ( fileName.startsWith( 's/' ) ) {
 
 
 								fileName = 'parts/' + fileName;
 								fileName = 'parts/' + fileName;
 
 
-							}
-							else if ( fileName.startsWith( '48/' ) ) {
+							} else if ( fileName.startsWith( '48/' ) ) {
 
 
 								fileName = 'p/' + fileName;
 								fileName = 'p/' + fileName;
 
 
@@ -1316,8 +1307,7 @@ THREE.LDrawLoader = ( function () {
 
 
 				}
 				}
 
 
-			}
-			else {
+			} else {
 
 
 				groupObject = this.currentGroupObject;
 				groupObject = this.currentGroupObject;
 
 

+ 19 - 4
examples/js/loaders/SVGLoader.js

@@ -162,6 +162,7 @@ THREE.SVGLoader.prototype = {
 							} else {
 							} else {
 								path.lineTo( point.x, point.y );
 								path.lineTo( point.x, point.y );
 							}
 							}
+							if ( j === 0 && doSetFirstPoint === true ) firstPoint.copy( point );
 						}
 						}
 						break;
 						break;
 
 
@@ -172,6 +173,7 @@ THREE.SVGLoader.prototype = {
 							control.x = point.x;
 							control.x = point.x;
 							control.y = point.y;
 							control.y = point.y;
 							path.lineTo( point.x, point.y );
 							path.lineTo( point.x, point.y );
+							if ( j === 0 && doSetFirstPoint === true ) firstPoint.copy( point );
 						}
 						}
 						break;
 						break;
 
 
@@ -182,6 +184,7 @@ THREE.SVGLoader.prototype = {
 							control.x = point.x;
 							control.x = point.x;
 							control.y = point.y;
 							control.y = point.y;
 							path.lineTo( point.x, point.y );
 							path.lineTo( point.x, point.y );
+							if ( j === 0 && doSetFirstPoint === true ) firstPoint.copy( point );
 						}
 						}
 						break;
 						break;
 
 
@@ -193,6 +196,7 @@ THREE.SVGLoader.prototype = {
 							control.x = point.x;
 							control.x = point.x;
 							control.y = point.y;
 							control.y = point.y;
 							path.lineTo( point.x, point.y );
 							path.lineTo( point.x, point.y );
+							if ( j === 0 && doSetFirstPoint === true ) firstPoint.copy( point );
 						}
 						}
 						break;
 						break;
 
 
@@ -211,6 +215,7 @@ THREE.SVGLoader.prototype = {
 							control.y = numbers[ j + 3 ];
 							control.y = numbers[ j + 3 ];
 							point.x = numbers[ j + 4 ];
 							point.x = numbers[ j + 4 ];
 							point.y = numbers[ j + 5 ];
 							point.y = numbers[ j + 5 ];
+							if ( j === 0 && doSetFirstPoint === true ) firstPoint.copy( point );
 						}
 						}
 						break;
 						break;
 
 
@@ -229,6 +234,7 @@ THREE.SVGLoader.prototype = {
 							control.y = numbers[ j + 1 ];
 							control.y = numbers[ j + 1 ];
 							point.x = numbers[ j + 2 ];
 							point.x = numbers[ j + 2 ];
 							point.y = numbers[ j + 3 ];
 							point.y = numbers[ j + 3 ];
+							if ( j === 0 && doSetFirstPoint === true ) firstPoint.copy( point );
 						}
 						}
 						break;
 						break;
 
 
@@ -245,6 +251,7 @@ THREE.SVGLoader.prototype = {
 							control.y = numbers[ j + 1 ];
 							control.y = numbers[ j + 1 ];
 							point.x = numbers[ j + 2 ];
 							point.x = numbers[ j + 2 ];
 							point.y = numbers[ j + 3 ];
 							point.y = numbers[ j + 3 ];
+							if ( j === 0 && doSetFirstPoint === true ) firstPoint.copy( point );
 						}
 						}
 						break;
 						break;
 
 
@@ -263,6 +270,7 @@ THREE.SVGLoader.prototype = {
 							control.y = ry;
 							control.y = ry;
 							point.x = numbers[ j + 0 ];
 							point.x = numbers[ j + 0 ];
 							point.y = numbers[ j + 1 ];
 							point.y = numbers[ j + 1 ];
+							if ( j === 0 && doSetFirstPoint === true ) firstPoint.copy( point );
 						}
 						}
 						break;
 						break;
 
 
@@ -277,6 +285,7 @@ THREE.SVGLoader.prototype = {
 							parseArcCommand(
 							parseArcCommand(
 								path, numbers[ j ], numbers[ j + 1 ], numbers[ j + 2 ], numbers[ j + 3 ], numbers[ j + 4 ], start, point
 								path, numbers[ j ], numbers[ j + 1 ], numbers[ j + 2 ], numbers[ j + 3 ], numbers[ j + 4 ], start, point
 							);
 							);
+							if ( j === 0 && doSetFirstPoint === true ) firstPoint.copy( point );
 						}
 						}
 						break;
 						break;
 
 
@@ -294,6 +303,7 @@ THREE.SVGLoader.prototype = {
 							} else {
 							} else {
 								path.lineTo( point.x, point.y );
 								path.lineTo( point.x, point.y );
 							}
 							}
+							if ( j === 0 && doSetFirstPoint === true ) firstPoint.copy( point );
 						}
 						}
 						break;
 						break;
 
 
@@ -304,6 +314,7 @@ THREE.SVGLoader.prototype = {
 							control.x = point.x;
 							control.x = point.x;
 							control.y = point.y;
 							control.y = point.y;
 							path.lineTo( point.x, point.y );
 							path.lineTo( point.x, point.y );
+							if ( j === 0 && doSetFirstPoint === true ) firstPoint.copy( point );
 						}
 						}
 						break;
 						break;
 
 
@@ -314,6 +325,7 @@ THREE.SVGLoader.prototype = {
 							control.x = point.x;
 							control.x = point.x;
 							control.y = point.y;
 							control.y = point.y;
 							path.lineTo( point.x, point.y );
 							path.lineTo( point.x, point.y );
+							if ( j === 0 && doSetFirstPoint === true ) firstPoint.copy( point );
 						}
 						}
 						break;
 						break;
 
 
@@ -325,6 +337,7 @@ THREE.SVGLoader.prototype = {
 							control.x = point.x;
 							control.x = point.x;
 							control.y = point.y;
 							control.y = point.y;
 							path.lineTo( point.x, point.y );
 							path.lineTo( point.x, point.y );
+							if ( j === 0 && doSetFirstPoint === true ) firstPoint.copy( point );
 						}
 						}
 						break;
 						break;
 
 
@@ -343,6 +356,7 @@ THREE.SVGLoader.prototype = {
 							control.y = point.y + numbers[ j + 3 ];
 							control.y = point.y + numbers[ j + 3 ];
 							point.x += numbers[ j + 4 ];
 							point.x += numbers[ j + 4 ];
 							point.y += numbers[ j + 5 ];
 							point.y += numbers[ j + 5 ];
+							if ( j === 0 && doSetFirstPoint === true ) firstPoint.copy( point );
 						}
 						}
 						break;
 						break;
 
 
@@ -361,6 +375,7 @@ THREE.SVGLoader.prototype = {
 							control.y = point.y + numbers[ j + 1 ];
 							control.y = point.y + numbers[ j + 1 ];
 							point.x += numbers[ j + 2 ];
 							point.x += numbers[ j + 2 ];
 							point.y += numbers[ j + 3 ];
 							point.y += numbers[ j + 3 ];
+							if ( j === 0 && doSetFirstPoint === true ) firstPoint.copy( point );
 						}
 						}
 						break;
 						break;
 
 
@@ -377,6 +392,7 @@ THREE.SVGLoader.prototype = {
 							control.y = point.y + numbers[ j + 1 ];
 							control.y = point.y + numbers[ j + 1 ];
 							point.x += numbers[ j + 2 ];
 							point.x += numbers[ j + 2 ];
 							point.y += numbers[ j + 3 ];
 							point.y += numbers[ j + 3 ];
+							if ( j === 0 && doSetFirstPoint === true ) firstPoint.copy( point );
 						}
 						}
 						break;
 						break;
 
 
@@ -395,6 +411,7 @@ THREE.SVGLoader.prototype = {
 							control.y = ry;
 							control.y = ry;
 							point.x = point.x + numbers[ j + 0 ];
 							point.x = point.x + numbers[ j + 0 ];
 							point.y = point.y + numbers[ j + 1 ];
 							point.y = point.y + numbers[ j + 1 ];
+							if ( j === 0 && doSetFirstPoint === true ) firstPoint.copy( point );
 						}
 						}
 						break;
 						break;
 
 
@@ -409,6 +426,7 @@ THREE.SVGLoader.prototype = {
 							parseArcCommand(
 							parseArcCommand(
 								path, numbers[ j ], numbers[ j + 1 ], numbers[ j + 2 ], numbers[ j + 3 ], numbers[ j + 4 ], start, point
 								path, numbers[ j ], numbers[ j + 1 ], numbers[ j + 2 ], numbers[ j + 3 ], numbers[ j + 4 ], start, point
 							);
 							);
+							if ( j === 0 && doSetFirstPoint === true ) firstPoint.copy( point );
 						}
 						}
 						break;
 						break;
 
 
@@ -432,10 +450,7 @@ THREE.SVGLoader.prototype = {
 
 
 				// console.log( type, parseFloats( data ), parseFloats( data ).length  )
 				// console.log( type, parseFloats( data ), parseFloats( data ).length  )
 
 
-				if ( doSetFirstPoint === true ) {
-					firstPoint.copy( point );
-					doSetFirstPoint = false;
-				}
+				doSetFirstPoint = false;
 
 
 			}
 			}
 
 

+ 4 - 2
examples/js/loaders/TGALoader.js

@@ -522,7 +522,9 @@ THREE.TGALoader.prototype = {
 
 
 		//
 		//
 
 
-		var canvas = document.createElement( 'canvas' );
+		var useOffscreen = typeof OffscreenCanvas !== 'undefined';
+
+		var canvas = useOffscreen ? new OffscreenCanvas( header.width, header.height ) : document.createElement( 'canvas' );
 		canvas.width = header.width;
 		canvas.width = header.width;
 		canvas.height = header.height;
 		canvas.height = header.height;
 
 
@@ -534,7 +536,7 @@ THREE.TGALoader.prototype = {
 
 
 		context.putImageData( imageData, 0, 0 );
 		context.putImageData( imageData, 0, 0 );
 
 
-		return canvas;
+		return useOffscreen ? canvas.transferToImageBitmap() : canvas;
 
 
 	},
 	},
 
 

+ 23 - 19
examples/js/loaders/deprecated/LegacyGLTFLoader.js

@@ -491,8 +491,8 @@ THREE.LegacyGLTFLoader = ( function () {
 	};
 	};
 
 
 	var WEBGL_SIDES = {
 	var WEBGL_SIDES = {
-		1028: THREE.BackSide,  // Culling front
-		1029: THREE.FrontSide  // Culling back
+		1028: THREE.BackSide, // Culling front
+		1029: THREE.FrontSide // Culling back
 		//1032: THREE.NoSide   // Culling front and back, what to do?
 		//1032: THREE.NoSide   // Culling front and back, what to do?
 	};
 	};
 
 
@@ -566,8 +566,10 @@ THREE.LegacyGLTFLoader = ( function () {
 
 
 	function _each( object, callback, thisObj ) {
 	function _each( object, callback, thisObj ) {
 
 
-		if ( !object ) {
+		if ( ! object ) {
+
 			return Promise.resolve();
 			return Promise.resolve();
+
 		}
 		}
 
 
 		var results;
 		var results;
@@ -589,11 +591,11 @@ THREE.LegacyGLTFLoader = ( function () {
 
 
 					if ( value instanceof Promise ) {
 					if ( value instanceof Promise ) {
 
 
-						value.then( function( key, value ) {
+						value.then( function ( key, value ) {
 
 
 							results[ key ] = value;
 							results[ key ] = value;
 
 
-						}.bind( this, idx ));
+						}.bind( this, idx ) );
 
 
 					} else {
 					} else {
 
 
@@ -621,11 +623,11 @@ THREE.LegacyGLTFLoader = ( function () {
 
 
 						if ( value instanceof Promise ) {
 						if ( value instanceof Promise ) {
 
 
-							value.then( function( key, value ) {
+							value.then( function ( key, value ) {
 
 
 								results[ key ] = value;
 								results[ key ] = value;
 
 
-							}.bind( this, key ));
+							}.bind( this, key ) );
 
 
 						} else {
 						} else {
 
 
@@ -641,11 +643,11 @@ THREE.LegacyGLTFLoader = ( function () {
 
 
 		}
 		}
 
 
-		return Promise.all( fns ).then( function() {
+		return Promise.all( fns ).then( function () {
 
 
 			return results;
 			return results;
 
 
-		});
+		} );
 
 
 	}
 	}
 
 
@@ -1210,7 +1212,7 @@ THREE.LegacyGLTFLoader = ( function () {
 
 
 					}
 					}
 
 
-					keys.forEach( function( v ) {
+					keys.forEach( function ( v ) {
 
 
 						if ( khr_material.values[ v ] !== undefined ) materialValues[ v ] = khr_material.values[ v ];
 						if ( khr_material.values[ v ] !== undefined ) materialValues[ v ] = khr_material.values[ v ];
 
 
@@ -1515,7 +1517,7 @@ THREE.LegacyGLTFLoader = ( function () {
 
 
 					materialParams.color = new THREE.Color().fromArray( materialValues.diffuse );
 					materialParams.color = new THREE.Color().fromArray( materialValues.diffuse );
 
 
-				} else if ( typeof( materialValues.diffuse ) === 'string' ) {
+				} else if ( typeof ( materialValues.diffuse ) === 'string' ) {
 
 
 					materialParams.map = dependencies.textures[ materialValues.diffuse ];
 					materialParams.map = dependencies.textures[ materialValues.diffuse ];
 
 
@@ -1523,13 +1525,13 @@ THREE.LegacyGLTFLoader = ( function () {
 
 
 				delete materialParams.diffuse;
 				delete materialParams.diffuse;
 
 
-				if ( typeof( materialValues.reflective ) === 'string' ) {
+				if ( typeof ( materialValues.reflective ) === 'string' ) {
 
 
 					materialParams.envMap = dependencies.textures[ materialValues.reflective ];
 					materialParams.envMap = dependencies.textures[ materialValues.reflective ];
 
 
 				}
 				}
 
 
-				if ( typeof( materialValues.bump ) === 'string' ) {
+				if ( typeof ( materialValues.bump ) === 'string' ) {
 
 
 					materialParams.bumpMap = dependencies.textures[ materialValues.bump ];
 					materialParams.bumpMap = dependencies.textures[ materialValues.bump ];
 
 
@@ -1547,7 +1549,7 @@ THREE.LegacyGLTFLoader = ( function () {
 
 
 					}
 					}
 
 
-				} else if ( typeof( materialValues.emission ) === 'string' ) {
+				} else if ( typeof ( materialValues.emission ) === 'string' ) {
 
 
 					if ( materialType === THREE.MeshBasicMaterial ) {
 					if ( materialType === THREE.MeshBasicMaterial ) {
 
 
@@ -1565,7 +1567,7 @@ THREE.LegacyGLTFLoader = ( function () {
 
 
 					materialParams.specular = new THREE.Color().fromArray( materialValues.specular );
 					materialParams.specular = new THREE.Color().fromArray( materialValues.specular );
 
 
-				} else if ( typeof( materialValues.specular ) === 'string' ) {
+				} else if ( typeof ( materialValues.specular ) === 'string' ) {
 
 
 					materialParams.specularMap = dependencies.textures[ materialValues.specular ];
 					materialParams.specularMap = dependencies.textures[ materialValues.specular ];
 
 
@@ -1670,9 +1672,9 @@ THREE.LegacyGLTFLoader = ( function () {
 
 
 									var parameters = json.techniques[ material.technique ].parameters || {};
 									var parameters = json.techniques[ material.technique ].parameters || {};
 
 
-									for( var attributeName in parameters ) {
+									for ( var attributeName in parameters ) {
 
 
-										if ( parameters [ attributeName ][ 'semantic' ] === attributeId ) {
+										if ( parameters[ attributeName ][ 'semantic' ] === attributeId ) {
 
 
 											geometry.addAttribute( attributeName, bufferAttribute );
 											geometry.addAttribute( attributeName, bufferAttribute );
 
 
@@ -2217,8 +2219,10 @@ THREE.LegacyGLTFLoader = ( function () {
 					if ( child.material && child.material.isRawShaderMaterial ) {
 					if ( child.material && child.material.isRawShaderMaterial ) {
 
 
 						child.gltfShader = new GLTFShader( child, dependencies.nodes );
 						child.gltfShader = new GLTFShader( child, dependencies.nodes );
-						child.onBeforeRender = function(renderer, scene, camera){
-							this.gltfShader.update(scene, camera);
+						child.onBeforeRender = function ( renderer, scene, camera ) {
+
+							this.gltfShader.update( scene, camera );
+
 						};
 						};
 
 
 					}
 					}

+ 6 - 2
examples/js/nodes/inputs/RTTNode.js

@@ -72,7 +72,9 @@ RTTNode.prototype.updateFramesaveTo = function ( frame ) {
 
 
 	this.saveToCurrent = this.saveTo;
 	this.saveToCurrent = this.saveTo;
 
 
-	frame.renderer.render( this.saveToScene, this.camera, this.saveTo.renderTarget, this.saveTo.clear );
+	frame.renderer.setRenderTarget( this.saveTo.renderTarget );
+	if ( this.saveTo.clear ) frame.renderer.clear();
+	frame.renderer.render( this.saveToScene, this.camera );
 
 
 };
 };
 
 
@@ -96,7 +98,9 @@ RTTNode.prototype.updateFrame = function ( frame ) {
 
 
 			}
 			}
 
 
-			frame.renderer.render( this.scene, this.camera, this.renderTarget, this.clear );
+			frame.renderer.setRenderTarget( this.renderTarget );
+			if ( this.clear ) frame.renderer.clear();
+			frame.renderer.render( this.scene, this.camera );
 
 
 		}
 		}
 
 

+ 4 - 2
examples/js/nodes/postprocessing/NodePostProcessing.js

@@ -16,7 +16,7 @@ function NodePostProcessing( renderer, renderTarget ) {
 			stencilBuffer: false
 			stencilBuffer: false
 		};
 		};
 
 
-		var size = renderer.getDrawingBufferSize();
+		var size = renderer.getDrawingBufferSize( new THREE.Vector2() );
 		renderTarget = new THREE.WebGLRenderTarget( size.width, size.height, parameters );
 		renderTarget = new THREE.WebGLRenderTarget( size.width, size.height, parameters );
 
 
 	}
 	}
@@ -64,10 +64,12 @@ NodePostProcessing.prototype = {
 		frame.setRenderer( this.renderer )
 		frame.setRenderer( this.renderer )
 			.setRenderTexture( this.renderTarget.texture );
 			.setRenderTexture( this.renderTarget.texture );
 
 
-		this.renderer.render( scene, camera, this.renderTarget );
+		this.renderer.setRenderTarget( this.renderTarget );
+		this.renderer.render( scene, camera );
 
 
 		frame.updateNode( this.material );
 		frame.updateNode( this.material );
 
 
+		this.renderer.setRenderTarget( null );
 		this.renderer.render( this.scene, this.camera );
 		this.renderer.render( this.scene, this.camera );
 
 
 	},
 	},

+ 12 - 6
examples/js/objects/Fire.js

@@ -342,7 +342,8 @@ THREE.Fire = function ( geometry, options ) {
 
 
 		this.sourceMaterial.uniforms[ "densityMap" ].value = this.field0.texture;
 		this.sourceMaterial.uniforms[ "densityMap" ].value = this.field0.texture;
 
 
-		renderer.render( this.fieldScene, this.orthoCamera, this.field1 );
+		renderer.setRenderTarget( this.field1 );
+		renderer.render( this.fieldScene, this.orthoCamera );
 
 
 		this.sourceMesh.visible = false;
 		this.sourceMesh.visible = false;
 
 
@@ -356,7 +357,8 @@ THREE.Fire = function ( geometry, options ) {
 
 
 		this.diffuseMaterial.uniforms[ "densityMap" ].value = this.field0.texture;
 		this.diffuseMaterial.uniforms[ "densityMap" ].value = this.field0.texture;
 
 
-		renderer.render( this.fieldScene, this.orthoCamera, this.field1 );
+		renderer.setRenderTarget( this.field1 );
+		renderer.render( this.fieldScene, this.orthoCamera );
 
 
 		this.diffuseMesh.visible = false;
 		this.diffuseMesh.visible = false;
 
 
@@ -370,7 +372,8 @@ THREE.Fire = function ( geometry, options ) {
 
 
 		this.driftMaterial.uniforms[ "densityMap" ].value = this.field0.texture;
 		this.driftMaterial.uniforms[ "densityMap" ].value = this.field0.texture;
 
 
-		renderer.render( this.fieldScene, this.orthoCamera, this.field1 );
+		renderer.setRenderTarget( this.field1 );
+		renderer.render( this.fieldScene, this.orthoCamera );
 
 
 		this.driftMesh.visible = false;
 		this.driftMesh.visible = false;
 
 
@@ -386,7 +389,8 @@ THREE.Fire = function ( geometry, options ) {
 
 
 		this.projMaterial1.uniforms[ "densityMap" ].value = this.field0.texture;
 		this.projMaterial1.uniforms[ "densityMap" ].value = this.field0.texture;
 
 
-		renderer.render( this.fieldScene, this.orthoCamera, this.fieldProj );
+		renderer.setRenderTarget( this.fieldProj );
+		renderer.render( this.fieldScene, this.orthoCamera );
 
 
 		this.projMesh1.visible = false;
 		this.projMesh1.visible = false;
 
 
@@ -398,7 +402,8 @@ THREE.Fire = function ( geometry, options ) {
 
 
 		for ( var i = 0; i < 20; i ++ ) {
 		for ( var i = 0; i < 20; i ++ ) {
 
 
-			renderer.render( this.fieldScene, this.orthoCamera, this.field1 );
+			renderer.setRenderTarget( this.field1 );
+			renderer.render( this.fieldScene, this.orthoCamera );
 
 
 			var temp = this.field1;
 			var temp = this.field1;
 			this.field1 = this.fieldProj;
 			this.field1 = this.fieldProj;
@@ -417,7 +422,8 @@ THREE.Fire = function ( geometry, options ) {
 
 
 		this.projMesh3.visible = true;
 		this.projMesh3.visible = true;
 
 
-		renderer.render( this.fieldScene, this.orthoCamera, this.field1 );
+		renderer.setRenderTarget( this.field1 );
+		renderer.render( this.fieldScene, this.orthoCamera );
 
 
 		this.projMesh3.visible = false;
 		this.projMesh3.visible = false;
 
 

+ 1 - 1
examples/js/objects/Lensflare.js

@@ -162,7 +162,7 @@ THREE.Lensflare = function () {
 
 
 	this.onBeforeRender = function ( renderer, scene, camera ) {
 	this.onBeforeRender = function ( renderer, scene, camera ) {
 
 
-		viewport.copy( renderer.getCurrentViewport() );
+		renderer.getCurrentViewport( viewport );
 
 
 		var invAspect = viewport.w / viewport.z;
 		var invAspect = viewport.w / viewport.z;
 		var halfViewportWidth = viewport.z / 2.0;
 		var halfViewportWidth = viewport.z / 2.0;

+ 5 - 2
examples/js/objects/Reflector.js

@@ -33,6 +33,7 @@ THREE.Reflector = function ( geometry, options ) {
 	var view = new THREE.Vector3();
 	var view = new THREE.Vector3();
 	var target = new THREE.Vector3();
 	var target = new THREE.Vector3();
 	var q = new THREE.Vector4();
 	var q = new THREE.Vector4();
+	var size = new THREE.Vector2();
 
 
 	var textureMatrix = new THREE.Matrix4();
 	var textureMatrix = new THREE.Matrix4();
 	var virtualCamera = new THREE.PerspectiveCamera();
 	var virtualCamera = new THREE.PerspectiveCamera();
@@ -160,7 +161,9 @@ THREE.Reflector = function ( geometry, options ) {
 		renderer.vr.enabled = false; // Avoid camera modification and recursion
 		renderer.vr.enabled = false; // Avoid camera modification and recursion
 		renderer.shadowMap.autoUpdate = false; // Avoid re-computing shadows
 		renderer.shadowMap.autoUpdate = false; // Avoid re-computing shadows
 
 
-		renderer.render( scene, virtualCamera, renderTarget, true );
+		renderer.setRenderTarget( renderTarget );
+		renderer.clear();
+		renderer.render( scene, virtualCamera );
 
 
 		renderer.vr.enabled = currentVrEnabled;
 		renderer.vr.enabled = currentVrEnabled;
 		renderer.shadowMap.autoUpdate = currentShadowAutoUpdate;
 		renderer.shadowMap.autoUpdate = currentShadowAutoUpdate;
@@ -173,7 +176,7 @@ THREE.Reflector = function ( geometry, options ) {
 
 
 		if ( bounds !== undefined ) {
 		if ( bounds !== undefined ) {
 
 
-			var size = renderer.getSize();
+			renderer.getSize( size );
 			var pixelRatio = renderer.getPixelRatio();
 			var pixelRatio = renderer.getPixelRatio();
 
 
 			viewport.x = bounds.x * size.width * pixelRatio;
 			viewport.x = bounds.x * size.width * pixelRatio;

+ 5 - 2
examples/js/objects/Refractor.js

@@ -187,6 +187,7 @@ THREE.Refractor = function ( geometry, options ) {
 	var render = ( function () {
 	var render = ( function () {
 
 
 		var viewport = new THREE.Vector4();
 		var viewport = new THREE.Vector4();
+		var size = new THREE.Vector2();
 
 
 		return function render( renderer, scene, camera ) {
 		return function render( renderer, scene, camera ) {
 
 
@@ -199,7 +200,9 @@ THREE.Refractor = function ( geometry, options ) {
 			renderer.vr.enabled = false; // avoid camera modification
 			renderer.vr.enabled = false; // avoid camera modification
 			renderer.shadowMap.autoUpdate = false; // avoid re-computing shadows
 			renderer.shadowMap.autoUpdate = false; // avoid re-computing shadows
 
 
-			renderer.render( scene, virtualCamera, renderTarget, true );
+			renderer.setRenderTarget( renderTarget );
+			renderer.clear();
+			renderer.render( scene, virtualCamera );
 
 
 			renderer.vr.enabled = currentVrEnabled;
 			renderer.vr.enabled = currentVrEnabled;
 			renderer.shadowMap.autoUpdate = currentShadowAutoUpdate;
 			renderer.shadowMap.autoUpdate = currentShadowAutoUpdate;
@@ -211,7 +214,7 @@ THREE.Refractor = function ( geometry, options ) {
 
 
 			if ( bounds !== undefined ) {
 			if ( bounds !== undefined ) {
 
 
-				var size = renderer.getSize();
+				renderer.getSize( size );
 				var pixelRatio = renderer.getPixelRatio();
 				var pixelRatio = renderer.getPixelRatio();
 
 
 				viewport.x = bounds.x * size.width * pixelRatio;
 				viewport.x = bounds.x * size.width * pixelRatio;

+ 3 - 1
examples/js/objects/Water.js

@@ -291,7 +291,9 @@ THREE.Water = function ( geometry, options ) {
 		renderer.vr.enabled = false; // Avoid camera modification and recursion
 		renderer.vr.enabled = false; // Avoid camera modification and recursion
 		renderer.shadowMap.autoUpdate = false; // Avoid re-computing shadows
 		renderer.shadowMap.autoUpdate = false; // Avoid re-computing shadows
 
 
-		renderer.render( scene, mirrorCamera, renderTarget, true );
+		renderer.setRenderTarget( renderTarget );
+		renderer.clear();
+		renderer.render( scene, mirrorCamera );
 
 
 		scope.visible = true;
 		scope.visible = true;
 
 

+ 2 - 1
examples/js/pmrem/PMREMCubeUVPacker.js

@@ -137,7 +137,8 @@ THREE.PMREMCubeUVPacker = ( function () {
 			renderer.gammaOutput = false;
 			renderer.gammaOutput = false;
 			renderer.toneMapping = THREE.LinearToneMapping;
 			renderer.toneMapping = THREE.LinearToneMapping;
 			renderer.toneMappingExposure = 1.0;
 			renderer.toneMappingExposure = 1.0;
-			renderer.render( scene, camera, this.CubeUVRenderTarget, false );
+			renderer.setRenderTarget( this.CubeUVRenderTarget );
+			renderer.render( scene, camera );
 
 
 			renderer.setRenderTarget( currentRenderTarget );
 			renderer.setRenderTarget( currentRenderTarget );
 			renderer.toneMapping = toneMapping;
 			renderer.toneMapping = toneMapping;

+ 3 - 2
examples/js/pmrem/PMREMGenerator.js

@@ -135,9 +135,10 @@ THREE.PMREMGenerator = ( function () {
 
 
 		renderToCubeMapTargetFace: function ( renderer, renderTarget, faceIndex ) {
 		renderToCubeMapTargetFace: function ( renderer, renderTarget, faceIndex ) {
 
 
-			renderTarget.activeCubeFace = faceIndex;
 			shader.uniforms[ 'faceIndex' ].value = faceIndex;
 			shader.uniforms[ 'faceIndex' ].value = faceIndex;
-			renderer.render( scene, camera, renderTarget, true );
+			renderer.setRenderTarget( renderTarget, faceIndex );
+			renderer.clear();
+			renderer.render( scene, camera );
 
 
 		},
 		},
 
 

+ 12 - 4
examples/js/postprocessing/AdaptiveToneMappingPass.js

@@ -148,7 +148,8 @@ THREE.AdaptiveToneMappingPass.prototype = Object.assign( Object.create( THREE.Pa
 			//Render the luminance of the current scene into a render target with mipmapping enabled
 			//Render the luminance of the current scene into a render target with mipmapping enabled
 			this.quad.material = this.materialLuminance;
 			this.quad.material = this.materialLuminance;
 			this.materialLuminance.uniforms.tDiffuse.value = readBuffer.texture;
 			this.materialLuminance.uniforms.tDiffuse.value = readBuffer.texture;
-			renderer.render( this.scene, this.camera, this.currentLuminanceRT );
+			renderer.setRenderTarget( this.currentLuminanceRT );
+			renderer.render( this.scene, this.camera );
 
 
 			//Use the new luminance values, the previous luminance and the frame delta to
 			//Use the new luminance values, the previous luminance and the frame delta to
 			//adapt the luminance over time.
 			//adapt the luminance over time.
@@ -156,12 +157,14 @@ THREE.AdaptiveToneMappingPass.prototype = Object.assign( Object.create( THREE.Pa
 			this.materialAdaptiveLum.uniforms.delta.value = deltaTime;
 			this.materialAdaptiveLum.uniforms.delta.value = deltaTime;
 			this.materialAdaptiveLum.uniforms.lastLum.value = this.previousLuminanceRT.texture;
 			this.materialAdaptiveLum.uniforms.lastLum.value = this.previousLuminanceRT.texture;
 			this.materialAdaptiveLum.uniforms.currentLum.value = this.currentLuminanceRT.texture;
 			this.materialAdaptiveLum.uniforms.currentLum.value = this.currentLuminanceRT.texture;
-			renderer.render( this.scene, this.camera, this.luminanceRT );
+			renderer.setRenderTarget( this.luminanceRT );
+			renderer.render( this.scene, this.camera );
 
 
 			//Copy the new adapted luminance value so that it can be used by the next frame.
 			//Copy the new adapted luminance value so that it can be used by the next frame.
 			this.quad.material = this.materialCopy;
 			this.quad.material = this.materialCopy;
 			this.copyUniforms.tDiffuse.value = this.luminanceRT.texture;
 			this.copyUniforms.tDiffuse.value = this.luminanceRT.texture;
-			renderer.render( this.scene, this.camera, this.previousLuminanceRT );
+			renderer.setRenderTarget( this.previousLuminanceRT );
+			renderer.render( this.scene, this.camera );
 
 
 		}
 		}
 
 
@@ -170,11 +173,16 @@ THREE.AdaptiveToneMappingPass.prototype = Object.assign( Object.create( THREE.Pa
 
 
 		if ( this.renderToScreen ) {
 		if ( this.renderToScreen ) {
 
 
+			renderer.setRenderTarget( null );
 			renderer.render( this.scene, this.camera );
 			renderer.render( this.scene, this.camera );
 
 
 		} else {
 		} else {
 
 
-			renderer.render( this.scene, this.camera, writeBuffer, this.clear );
+			renderer.setRenderTarget( writeBuffer );
+
+			if ( this.clear ) renderer.clear();
+
+			renderer.render( this.scene, this.camera );
 
 
 		}
 		}
 
 

+ 16 - 8
examples/js/postprocessing/AfterimagePass.js

@@ -70,17 +70,25 @@ THREE.AfterimagePass.prototype = Object.assign( Object.create( THREE.Pass.protot
 
 
 		this.quadComp.material = this.shaderMaterial;
 		this.quadComp.material = this.shaderMaterial;
 
 
-		renderer.render( this.sceneComp, this.camera, this.textureComp );
-		renderer.render( this.scene, this.camera, this.textureOld );
-		
+		renderer.setRenderTarget( this.textureComp );
+		renderer.render( this.sceneComp, this.camera );
+
+		renderer.setRenderTarget( this.textureOld );
+		renderer.render( this.scene, this.camera );
+
 		if ( this.renderToScreen ) {
 		if ( this.renderToScreen ) {
-			
+
+			renderer.setRenderTarget( null );
 			renderer.render( this.scene, this.camera );
 			renderer.render( this.scene, this.camera );
-			
+
 		} else {
 		} else {
-			
-			renderer.render( this.scene, this.camera, writeBuffer, this.clear );
-			
+
+			renderer.setRenderTarget( writeBuffer );
+
+			if ( this.clear ) renderer.clear();
+
+			renderer.render( this.scene, this.camera );
+
 		}
 		}
 
 
 	}
 	}

+ 9 - 3
examples/js/postprocessing/BloomPass.js

@@ -91,7 +91,9 @@ THREE.BloomPass.prototype = Object.assign( Object.create( THREE.Pass.prototype )
 		this.convolutionUniforms[ "tDiffuse" ].value = readBuffer.texture;
 		this.convolutionUniforms[ "tDiffuse" ].value = readBuffer.texture;
 		this.convolutionUniforms[ "uImageIncrement" ].value = THREE.BloomPass.blurX;
 		this.convolutionUniforms[ "uImageIncrement" ].value = THREE.BloomPass.blurX;
 
 
-		renderer.render( this.scene, this.camera, this.renderTargetX, true );
+		renderer.setRenderTarget( this.renderTargetX );
+		renderer.clear();
+		renderer.render( this.scene, this.camera );
 
 
 
 
 		// Render quad with blured scene into texture (convolution pass 2)
 		// Render quad with blured scene into texture (convolution pass 2)
@@ -99,7 +101,9 @@ THREE.BloomPass.prototype = Object.assign( Object.create( THREE.Pass.prototype )
 		this.convolutionUniforms[ "tDiffuse" ].value = this.renderTargetX.texture;
 		this.convolutionUniforms[ "tDiffuse" ].value = this.renderTargetX.texture;
 		this.convolutionUniforms[ "uImageIncrement" ].value = THREE.BloomPass.blurY;
 		this.convolutionUniforms[ "uImageIncrement" ].value = THREE.BloomPass.blurY;
 
 
-		renderer.render( this.scene, this.camera, this.renderTargetY, true );
+		renderer.setRenderTarget( this.renderTargetY );
+		renderer.clear();
+		renderer.render( this.scene, this.camera );
 
 
 		// Render original scene with superimposed blur to texture
 		// Render original scene with superimposed blur to texture
 
 
@@ -109,7 +113,9 @@ THREE.BloomPass.prototype = Object.assign( Object.create( THREE.Pass.prototype )
 
 
 		if ( maskActive ) renderer.context.enable( renderer.context.STENCIL_TEST );
 		if ( maskActive ) renderer.context.enable( renderer.context.STENCIL_TEST );
 
 
-		renderer.render( this.scene, this.camera, readBuffer, this.clear );
+		renderer.setRenderTarget( readBuffer );
+		if ( this.clear ) renderer.clear();
+		renderer.render( this.scene, this.camera );
 
 
 	}
 	}
 
 

+ 8 - 3
examples/js/postprocessing/BokehPass.js

@@ -97,7 +97,9 @@ THREE.BokehPass.prototype = Object.assign( Object.create( THREE.Pass.prototype )
 
 
 		renderer.setClearColor( 0xffffff );
 		renderer.setClearColor( 0xffffff );
 		renderer.setClearAlpha( 1.0 );
 		renderer.setClearAlpha( 1.0 );
-		renderer.render( this.scene, this.camera, this.renderTargetDepth, true );
+		renderer.setRenderTarget( this.renderTargetDepth );
+		renderer.clear();
+		renderer.render( this.scene, this.camera );
 
 
 		// Render bokeh composite
 		// Render bokeh composite
 
 
@@ -107,11 +109,14 @@ THREE.BokehPass.prototype = Object.assign( Object.create( THREE.Pass.prototype )
 
 
 		if ( this.renderToScreen ) {
 		if ( this.renderToScreen ) {
 
 
+			renderer.setRenderTarget( null );
 			renderer.render( this.scene2, this.camera2 );
 			renderer.render( this.scene2, this.camera2 );
 
 
 		} else {
 		} else {
 
 
-			renderer.render( this.scene2, this.camera2, writeBuffer, this.clear );
+			renderer.setRenderTarget( writeBuffer );
+			renderer.clear();
+			renderer.render( this.scene2, this.camera2 );
 
 
 		}
 		}
 
 
@@ -119,7 +124,7 @@ THREE.BokehPass.prototype = Object.assign( Object.create( THREE.Pass.prototype )
 		renderer.setClearColor( this.oldClearColor );
 		renderer.setClearColor( this.oldClearColor );
 		renderer.setClearAlpha( this.oldClearAlpha );
 		renderer.setClearAlpha( this.oldClearAlpha );
 		renderer.autoClear = this.oldAutoClear;
 		renderer.autoClear = this.oldAutoClear;
-	
+
 	}
 	}
 
 
 } );
 } );

+ 3 - 1
examples/js/postprocessing/CubeTexturePass.js

@@ -48,7 +48,9 @@ THREE.CubeTexturePass.prototype = Object.assign( Object.create( THREE.Pass.proto
 		this.cubeMesh.material.uniforms[ "opacity" ].value = this.opacity;
 		this.cubeMesh.material.uniforms[ "opacity" ].value = this.opacity;
 		this.cubeMesh.material.transparent = ( this.opacity < 1.0 );
 		this.cubeMesh.material.transparent = ( this.opacity < 1.0 );
 
 
-		renderer.render( this.cubeScene, this.cubeCamera, this.renderToScreen ? null : readBuffer, this.clear );
+		renderer.setRenderTarget( this.renderToScreen ? null : readBuffer );
+		if ( this.clear ) renderer.clear();
+		renderer.render( this.cubeScene, this.cubeCamera );
 
 
 		renderer.autoClear = oldAutoClear;
 		renderer.autoClear = oldAutoClear;
 
 

+ 4 - 1
examples/js/postprocessing/DotScreenPass.js

@@ -47,11 +47,14 @@ THREE.DotScreenPass.prototype = Object.assign( Object.create( THREE.Pass.prototy
 
 
 		if ( this.renderToScreen ) {
 		if ( this.renderToScreen ) {
 
 
+			renderer.setRenderTarget( null );
 			renderer.render( this.scene, this.camera );
 			renderer.render( this.scene, this.camera );
 
 
 		} else {
 		} else {
 
 
-			renderer.render( this.scene, this.camera, writeBuffer, this.clear );
+			renderer.setRenderTarget( writeBuffer );
+			if ( this.clear ) renderer.clear();
+			renderer.render( this.scene, this.camera );
 
 
 		}
 		}
 
 

+ 7 - 3
examples/js/postprocessing/EffectComposer.js

@@ -15,7 +15,7 @@ THREE.EffectComposer = function ( renderer, renderTarget ) {
 			stencilBuffer: false
 			stencilBuffer: false
 		};
 		};
 
 
-		var size = renderer.getDrawingBufferSize();
+		var size = renderer.getDrawingBufferSize( new THREE.Vector2() );
 		renderTarget = new THREE.WebGLRenderTarget( size.width, size.height, parameters );
 		renderTarget = new THREE.WebGLRenderTarget( size.width, size.height, parameters );
 		renderTarget.texture.name = 'EffectComposer.rt1';
 		renderTarget.texture.name = 'EffectComposer.rt1';
 
 
@@ -64,7 +64,7 @@ Object.assign( THREE.EffectComposer.prototype, {
 
 
 		this.passes.push( pass );
 		this.passes.push( pass );
 
 
-		var size = this.renderer.getDrawingBufferSize();
+		var size = this.renderer.getDrawingBufferSize( new THREE.Vector2() );
 		pass.setSize( size.width, size.height );
 		pass.setSize( size.width, size.height );
 
 
 	},
 	},
@@ -87,6 +87,8 @@ Object.assign( THREE.EffectComposer.prototype, {
 
 
 		this._previousFrameTime = Date.now();
 		this._previousFrameTime = Date.now();
 
 
+		var currentRenderTarget = this.renderer.getRenderTarget();
+
 		var maskActive = false;
 		var maskActive = false;
 
 
 		var pass, i, il = this.passes.length;
 		var pass, i, il = this.passes.length;
@@ -133,13 +135,15 @@ Object.assign( THREE.EffectComposer.prototype, {
 
 
 		}
 		}
 
 
+		this.renderer.setRenderTarget( currentRenderTarget );
+
 	},
 	},
 
 
 	reset: function ( renderTarget ) {
 	reset: function ( renderTarget ) {
 
 
 		if ( renderTarget === undefined ) {
 		if ( renderTarget === undefined ) {
 
 
-			var size = this.renderer.getDrawingBufferSize();
+			var size = this.renderer.getDrawingBufferSize( new THREE.Vector2() );
 
 
 			renderTarget = this.renderTarget1.clone();
 			renderTarget = this.renderTarget1.clone();
 			renderTarget.setSize( size.width, size.height );
 			renderTarget.setSize( size.width, size.height );

+ 4 - 1
examples/js/postprocessing/FilmPass.js

@@ -48,11 +48,14 @@ THREE.FilmPass.prototype = Object.assign( Object.create( THREE.Pass.prototype ),
 
 
 		if ( this.renderToScreen ) {
 		if ( this.renderToScreen ) {
 
 
+			renderer.setRenderTarget( null );
 			renderer.render( this.scene, this.camera );
 			renderer.render( this.scene, this.camera );
 
 
 		} else {
 		} else {
 
 
-			renderer.render( this.scene, this.camera, writeBuffer, this.clear );
+			renderer.setRenderTarget( writeBuffer );
+			if ( this.clear ) renderer.clear();
+			renderer.render( this.scene, this.camera );
 
 
 		}
 		}
 
 

+ 4 - 1
examples/js/postprocessing/GlitchPass.js

@@ -77,11 +77,14 @@ THREE.GlitchPass.prototype = Object.assign( Object.create( THREE.Pass.prototype
 
 
 		if ( this.renderToScreen ) {
 		if ( this.renderToScreen ) {
 
 
+			renderer.setRenderTarget( null );
 			renderer.render( this.scene, this.camera );
 			renderer.render( this.scene, this.camera );
 
 
 		} else {
 		} else {
 
 
-			renderer.render( this.scene, this.camera, writeBuffer, this.clear );
+			renderer.setRenderTarget( writeBuffer );
+			if ( this.clear ) renderer.clear();
+			renderer.render( this.scene, this.camera );
 
 
 		}
 		}
 
 

+ 4 - 1
examples/js/postprocessing/HalftonePass.js

@@ -55,11 +55,14 @@ THREE.HalftonePass = function ( width, height, params ) {
 
 
  		if ( this.renderToScreen ) {
  		if ( this.renderToScreen ) {
 
 
+ 			renderer.setRenderTarget( null );
  			renderer.render( this.scene, this.camera );
  			renderer.render( this.scene, this.camera );
 
 
 		} else {
 		} else {
 
 
-			renderer.render( this.scene, this.camera, writeBuffer, this.clear );
+ 			renderer.setRenderTarget( writeBuffer );
+ 			if ( this.clear ) renderer.clear();
+			renderer.render( this.scene, this.camera );
 
 
 		}
 		}
 
 

+ 7 - 2
examples/js/postprocessing/MaskPass.js

@@ -58,8 +58,13 @@ THREE.MaskPass.prototype = Object.assign( Object.create( THREE.Pass.prototype ),
 
 
 		// draw into the stencil buffer
 		// draw into the stencil buffer
 
 
-		renderer.render( this.scene, this.camera, readBuffer, this.clear );
-		renderer.render( this.scene, this.camera, writeBuffer, this.clear );
+		renderer.setRenderTarget( readBuffer );
+		if ( this.clear ) renderer.clear();
+		renderer.render( this.scene, this.camera );
+
+		renderer.setRenderTarget( writeBuffer );
+		if ( this.clear ) renderer.clear();
+		renderer.render( this.scene, this.camera );
 
 
 		// unlock color and depth buffer for subsequent rendering
 		// unlock color and depth buffer for subsequent rendering
 
 

+ 27 - 9
examples/js/postprocessing/OutlinePass.js

@@ -277,7 +277,9 @@ THREE.OutlinePass.prototype = Object.assign( Object.create( THREE.Pass.prototype
 
 
 			// 1. Draw Non Selected objects in the depth buffer
 			// 1. Draw Non Selected objects in the depth buffer
 			this.renderScene.overrideMaterial = this.depthMaterial;
 			this.renderScene.overrideMaterial = this.depthMaterial;
-			renderer.render( this.renderScene, this.renderCamera, this.renderTargetDepthBuffer, true );
+			renderer.setRenderTarget( this.renderTargetDepthBuffer );
+			renderer.clear();
+			renderer.render( this.renderScene, this.renderCamera );
 
 
 			// Make selected objects visible
 			// Make selected objects visible
 			this.changeVisibilityOfSelectedObjects( true );
 			this.changeVisibilityOfSelectedObjects( true );
@@ -291,7 +293,9 @@ THREE.OutlinePass.prototype = Object.assign( Object.create( THREE.Pass.prototype
 			this.prepareMaskMaterial.uniforms[ "cameraNearFar" ].value = new THREE.Vector2( this.renderCamera.near, this.renderCamera.far );
 			this.prepareMaskMaterial.uniforms[ "cameraNearFar" ].value = new THREE.Vector2( this.renderCamera.near, this.renderCamera.far );
 			this.prepareMaskMaterial.uniforms[ "depthTexture" ].value = this.renderTargetDepthBuffer.texture;
 			this.prepareMaskMaterial.uniforms[ "depthTexture" ].value = this.renderTargetDepthBuffer.texture;
 			this.prepareMaskMaterial.uniforms[ "textureMatrix" ].value = this.textureMatrix;
 			this.prepareMaskMaterial.uniforms[ "textureMatrix" ].value = this.textureMatrix;
-			renderer.render( this.renderScene, this.renderCamera, this.renderTargetMaskBuffer, true );
+			renderer.setRenderTarget( this.renderTargetMaskBuffer );
+			renderer.clear();
+			renderer.render( this.renderScene, this.renderCamera );
 			this.renderScene.overrideMaterial = null;
 			this.renderScene.overrideMaterial = null;
 			this.changeVisibilityOfNonSelectedObjects( true );
 			this.changeVisibilityOfNonSelectedObjects( true );
 
 
@@ -300,7 +304,9 @@ THREE.OutlinePass.prototype = Object.assign( Object.create( THREE.Pass.prototype
 			// 2. Downsample to Half resolution
 			// 2. Downsample to Half resolution
 			this.quad.material = this.materialCopy;
 			this.quad.material = this.materialCopy;
 			this.copyUniforms[ "tDiffuse" ].value = this.renderTargetMaskBuffer.texture;
 			this.copyUniforms[ "tDiffuse" ].value = this.renderTargetMaskBuffer.texture;
-			renderer.render( this.scene, this.camera, this.renderTargetMaskDownSampleBuffer, true );
+			renderer.setRenderTarget( this.renderTargetMaskDownSampleBuffer );
+			renderer.clear();
+			renderer.render( this.scene, this.camera );
 
 
 			this.tempPulseColor1.copy( this.visibleEdgeColor );
 			this.tempPulseColor1.copy( this.visibleEdgeColor );
 			this.tempPulseColor2.copy( this.hiddenEdgeColor );
 			this.tempPulseColor2.copy( this.hiddenEdgeColor );
@@ -319,26 +325,36 @@ THREE.OutlinePass.prototype = Object.assign( Object.create( THREE.Pass.prototype
 			this.edgeDetectionMaterial.uniforms[ "texSize" ].value = new THREE.Vector2( this.renderTargetMaskDownSampleBuffer.width, this.renderTargetMaskDownSampleBuffer.height );
 			this.edgeDetectionMaterial.uniforms[ "texSize" ].value = new THREE.Vector2( this.renderTargetMaskDownSampleBuffer.width, this.renderTargetMaskDownSampleBuffer.height );
 			this.edgeDetectionMaterial.uniforms[ "visibleEdgeColor" ].value = this.tempPulseColor1;
 			this.edgeDetectionMaterial.uniforms[ "visibleEdgeColor" ].value = this.tempPulseColor1;
 			this.edgeDetectionMaterial.uniforms[ "hiddenEdgeColor" ].value = this.tempPulseColor2;
 			this.edgeDetectionMaterial.uniforms[ "hiddenEdgeColor" ].value = this.tempPulseColor2;
-			renderer.render( this.scene, this.camera, this.renderTargetEdgeBuffer1, true );
+			renderer.setRenderTarget( this.renderTargetEdgeBuffer1 );
+			renderer.clear();
+			renderer.render( this.scene, this.camera );
 
 
 			// 4. Apply Blur on Half res
 			// 4. Apply Blur on Half res
 			this.quad.material = this.separableBlurMaterial1;
 			this.quad.material = this.separableBlurMaterial1;
 			this.separableBlurMaterial1.uniforms[ "colorTexture" ].value = this.renderTargetEdgeBuffer1.texture;
 			this.separableBlurMaterial1.uniforms[ "colorTexture" ].value = this.renderTargetEdgeBuffer1.texture;
 			this.separableBlurMaterial1.uniforms[ "direction" ].value = THREE.OutlinePass.BlurDirectionX;
 			this.separableBlurMaterial1.uniforms[ "direction" ].value = THREE.OutlinePass.BlurDirectionX;
 			this.separableBlurMaterial1.uniforms[ "kernelRadius" ].value = this.edgeThickness;
 			this.separableBlurMaterial1.uniforms[ "kernelRadius" ].value = this.edgeThickness;
-			renderer.render( this.scene, this.camera, this.renderTargetBlurBuffer1, true );
+			renderer.setRenderTarget( this.renderTargetBlurBuffer1 );
+			renderer.clear();
+			renderer.render( this.scene, this.camera );
 			this.separableBlurMaterial1.uniforms[ "colorTexture" ].value = this.renderTargetBlurBuffer1.texture;
 			this.separableBlurMaterial1.uniforms[ "colorTexture" ].value = this.renderTargetBlurBuffer1.texture;
 			this.separableBlurMaterial1.uniforms[ "direction" ].value = THREE.OutlinePass.BlurDirectionY;
 			this.separableBlurMaterial1.uniforms[ "direction" ].value = THREE.OutlinePass.BlurDirectionY;
-			renderer.render( this.scene, this.camera, this.renderTargetEdgeBuffer1, true );
+			renderer.setRenderTarget( this.renderTargetEdgeBuffer1 );
+			renderer.clear();
+			renderer.render( this.scene, this.camera );
 
 
 			// Apply Blur on quarter res
 			// Apply Blur on quarter res
 			this.quad.material = this.separableBlurMaterial2;
 			this.quad.material = this.separableBlurMaterial2;
 			this.separableBlurMaterial2.uniforms[ "colorTexture" ].value = this.renderTargetEdgeBuffer1.texture;
 			this.separableBlurMaterial2.uniforms[ "colorTexture" ].value = this.renderTargetEdgeBuffer1.texture;
 			this.separableBlurMaterial2.uniforms[ "direction" ].value = THREE.OutlinePass.BlurDirectionX;
 			this.separableBlurMaterial2.uniforms[ "direction" ].value = THREE.OutlinePass.BlurDirectionX;
-			renderer.render( this.scene, this.camera, this.renderTargetBlurBuffer2, true );
+			renderer.setRenderTarget( this.renderTargetBlurBuffer2 );
+			renderer.clear();
+			renderer.render( this.scene, this.camera );
 			this.separableBlurMaterial2.uniforms[ "colorTexture" ].value = this.renderTargetBlurBuffer2.texture;
 			this.separableBlurMaterial2.uniforms[ "colorTexture" ].value = this.renderTargetBlurBuffer2.texture;
 			this.separableBlurMaterial2.uniforms[ "direction" ].value = THREE.OutlinePass.BlurDirectionY;
 			this.separableBlurMaterial2.uniforms[ "direction" ].value = THREE.OutlinePass.BlurDirectionY;
-			renderer.render( this.scene, this.camera, this.renderTargetEdgeBuffer2, true );
+			renderer.setRenderTarget( this.renderTargetEdgeBuffer2 );
+			renderer.clear();
+			renderer.render( this.scene, this.camera );
 
 
 			// Blend it additively over the input texture
 			// Blend it additively over the input texture
 			this.quad.material = this.overlayMaterial;
 			this.quad.material = this.overlayMaterial;
@@ -353,7 +369,8 @@ THREE.OutlinePass.prototype = Object.assign( Object.create( THREE.Pass.prototype
 
 
 			if ( maskActive ) renderer.context.enable( renderer.context.STENCIL_TEST );
 			if ( maskActive ) renderer.context.enable( renderer.context.STENCIL_TEST );
 
 
-			renderer.render( this.scene, this.camera, readBuffer, false );
+			renderer.setRenderTarget( readBuffer );
+			renderer.render( this.scene, this.camera );
 
 
 			renderer.setClearColor( this.oldClearColor, this.oldClearAlpha );
 			renderer.setClearColor( this.oldClearColor, this.oldClearAlpha );
 			renderer.autoClear = oldAutoClear;
 			renderer.autoClear = oldAutoClear;
@@ -364,6 +381,7 @@ THREE.OutlinePass.prototype = Object.assign( Object.create( THREE.Pass.prototype
 
 
 			this.quad.material = this.materialCopy;
 			this.quad.material = this.materialCopy;
 			this.copyUniforms[ "tDiffuse" ].value = readBuffer.texture;
 			this.copyUniforms[ "tDiffuse" ].value = readBuffer.texture;
+			renderer.setRenderTarget( null );
 			renderer.render( this.scene, this.camera );
 			renderer.render( this.scene, this.camera );
 
 
 		}
 		}

+ 3 - 1
examples/js/postprocessing/RenderPass.js

@@ -48,7 +48,9 @@ THREE.RenderPass.prototype = Object.assign( Object.create( THREE.Pass.prototype
 
 
 		}
 		}
 
 
-		renderer.render( this.scene, this.camera, this.renderToScreen ? null : readBuffer, this.clear );
+		renderer.setRenderTarget( this.renderToScreen ? null : readBuffer );
+		if ( this.clear ) renderer.clear();
+		renderer.render( this.scene, this.camera );
 
 
 		if ( this.clearColor ) {
 		if ( this.clearColor ) {
 
 

+ 12 - 7
examples/js/postprocessing/SAOPass.js

@@ -234,7 +234,9 @@ THREE.SAOPass.prototype = Object.assign( Object.create( THREE.Pass.prototype ),
 
 
 		// Rendering scene to depth texture
 		// Rendering scene to depth texture
 		renderer.setClearColor( 0x000000 );
 		renderer.setClearColor( 0x000000 );
-		renderer.render( this.scene, this.camera, this.beautyRenderTarget, true );
+		renderer.setRenderTarget( this.beautyRenderTarget );
+		renderer.clear();
+		renderer.render( this.scene, this.camera );
 
 
 		// Re-render scene if depth texture extension is not supported
 		// Re-render scene if depth texture extension is not supported
 		if ( ! this.supportsDepthTextureExtension ) {
 		if ( ! this.supportsDepthTextureExtension ) {
@@ -317,18 +319,20 @@ THREE.SAOPass.prototype = Object.assign( Object.create( THREE.Pass.prototype ),
 		var originalClearAlpha = renderer.getClearAlpha();
 		var originalClearAlpha = renderer.getClearAlpha();
 		var originalAutoClear = renderer.autoClear;
 		var originalAutoClear = renderer.autoClear;
 
 
+		renderer.setRenderTarget( renderTarget);
+
 		// setup pass state
 		// setup pass state
 		renderer.autoClear = false;
 		renderer.autoClear = false;
-		var clearNeeded = ( clearColor !== undefined ) && ( clearColor !== null );
-		if ( clearNeeded ) {
+		if ( ( clearColor !== undefined ) && ( clearColor !== null ) ) {
 
 
 			renderer.setClearColor( clearColor );
 			renderer.setClearColor( clearColor );
 			renderer.setClearAlpha( clearAlpha || 0.0 );
 			renderer.setClearAlpha( clearAlpha || 0.0 );
+			renderer.clear();
 
 
 		}
 		}
 
 
 		this.quad.material = passMaterial;
 		this.quad.material = passMaterial;
-		renderer.render( this.quadScene, this.quadCamera, renderTarget, clearNeeded );
+		renderer.render( this.quadScene, this.quadCamera );
 
 
 		// restore original state
 		// restore original state
 		renderer.autoClear = originalAutoClear;
 		renderer.autoClear = originalAutoClear;
@@ -343,20 +347,21 @@ THREE.SAOPass.prototype = Object.assign( Object.create( THREE.Pass.prototype ),
 		var originalClearAlpha = renderer.getClearAlpha();
 		var originalClearAlpha = renderer.getClearAlpha();
 		var originalAutoClear = renderer.autoClear;
 		var originalAutoClear = renderer.autoClear;
 
 
+		renderer.setRenderTarget( renderTarget );
 		renderer.autoClear = false;
 		renderer.autoClear = false;
 
 
 		clearColor = overrideMaterial.clearColor || clearColor;
 		clearColor = overrideMaterial.clearColor || clearColor;
 		clearAlpha = overrideMaterial.clearAlpha || clearAlpha;
 		clearAlpha = overrideMaterial.clearAlpha || clearAlpha;
-		var clearNeeded = ( clearColor !== undefined ) && ( clearColor !== null );
-		if ( clearNeeded ) {
+		if ( ( clearColor !== undefined ) && ( clearColor !== null ) ) {
 
 
 			renderer.setClearColor( clearColor );
 			renderer.setClearColor( clearColor );
 			renderer.setClearAlpha( clearAlpha || 0.0 );
 			renderer.setClearAlpha( clearAlpha || 0.0 );
+			renderer.clear();
 
 
 		}
 		}
 
 
 		this.scene.overrideMaterial = overrideMaterial;
 		this.scene.overrideMaterial = overrideMaterial;
-		renderer.render( this.scene, this.camera, renderTarget, clearNeeded );
+		renderer.render( this.scene, this.camera );
 		this.scene.overrideMaterial = null;
 		this.scene.overrideMaterial = null;
 
 
 		// restore original state
 		// restore original state

+ 10 - 3
examples/js/postprocessing/SMAAPass.js

@@ -128,13 +128,17 @@ THREE.SMAAPass.prototype = Object.assign( Object.create( THREE.Pass.prototype ),
 
 
 		this.quad.material = this.materialEdges;
 		this.quad.material = this.materialEdges;
 
 
-		renderer.render( this.scene, this.camera, this.edgesRT, this.clear );
+		renderer.setRenderTarget( this.edgesRT );
+		if ( this.clear ) renderer.clear();
+		renderer.render( this.scene, this.camera );
 
 
 		// pass 2
 		// pass 2
 
 
 		this.quad.material = this.materialWeights;
 		this.quad.material = this.materialWeights;
 
 
-		renderer.render( this.scene, this.camera, this.weightsRT, this.clear );
+		renderer.setRenderTarget( this.weightsRT );
+		if ( this.clear ) renderer.clear();
+		renderer.render( this.scene, this.camera );
 
 
 		// pass 3
 		// pass 3
 
 
@@ -144,11 +148,14 @@ THREE.SMAAPass.prototype = Object.assign( Object.create( THREE.Pass.prototype ),
 
 
 		if ( this.renderToScreen ) {
 		if ( this.renderToScreen ) {
 
 
+			renderer.setRenderTarget( null );
 			renderer.render( this.scene, this.camera );
 			renderer.render( this.scene, this.camera );
 
 
 		} else {
 		} else {
 
 
-			renderer.render( this.scene, this.camera, writeBuffer, this.clear );
+			renderer.setRenderTarget( writeBuffer );
+			if ( this.clear ) renderer.clear();
+			renderer.render( this.scene, this.camera );
 
 
 		}
 		}
 
 

+ 7 - 2
examples/js/postprocessing/SSAARenderPass.js

@@ -120,15 +120,20 @@ THREE.SSAARenderPass.prototype = Object.assign( Object.create( THREE.Pass.protot
 
 
 			this.copyUniforms[ "opacity" ].value = sampleWeight;
 			this.copyUniforms[ "opacity" ].value = sampleWeight;
 			renderer.setClearColor( this.clearColor, this.clearAlpha );
 			renderer.setClearColor( this.clearColor, this.clearAlpha );
-			renderer.render( this.scene, this.camera, this.sampleRenderTarget, true );
+			renderer.setRenderTarget( this.sampleRenderTarget );
+			renderer.clear();
+			renderer.render( this.scene, this.camera );
+
+			renderer.setRenderTarget( this.renderToScreen ? null : writeBuffer );
 
 
 			if ( i === 0 ) {
 			if ( i === 0 ) {
 
 
 				renderer.setClearColor( 0x000000, 0.0 );
 				renderer.setClearColor( 0x000000, 0.0 );
+				renderer.clear();
 
 
 			}
 			}
 
 
-			renderer.render( this.scene2, this.camera2, this.renderToScreen ? null : writeBuffer, ( i === 0 ) );
+			renderer.render( this.scene2, this.camera2 );
 
 
 		}
 		}
 
 

+ 12 - 8
examples/js/postprocessing/SSAOPass.js

@@ -177,7 +177,9 @@ THREE.SSAOPass.prototype = Object.assign( Object.create( THREE.Pass.prototype ),
 
 
 		// render beauty and depth
 		// render beauty and depth
 
 
-		renderer.render( this.scene, this.camera, this.beautyRenderTarget, true );
+		renderer.setRenderTarget( this.beautyRenderTarget );
+		renderer.clear();
+		renderer.render( this.scene, this.camera );
 
 
 		// render normals
 		// render normals
 
 
@@ -262,18 +264,20 @@ THREE.SSAOPass.prototype = Object.assign( Object.create( THREE.Pass.prototype ),
 		var originalClearAlpha = renderer.getClearAlpha();
 		var originalClearAlpha = renderer.getClearAlpha();
 		var originalAutoClear = renderer.autoClear;
 		var originalAutoClear = renderer.autoClear;
 
 
+		renderer.setRenderTarget( renderTarget );
+
 		// setup pass state
 		// setup pass state
 		renderer.autoClear = false;
 		renderer.autoClear = false;
-		var clearNeeded = ( clearColor !== undefined ) && ( clearColor !== null );
-		if ( clearNeeded ) {
+		if ( ( clearColor !== undefined ) && ( clearColor !== null ) ) {
 
 
 			renderer.setClearColor( clearColor );
 			renderer.setClearColor( clearColor );
 			renderer.setClearAlpha( clearAlpha || 0.0 );
 			renderer.setClearAlpha( clearAlpha || 0.0 );
+			renderer.clear();
 
 
 		}
 		}
 
 
 		this.quad.material = passMaterial;
 		this.quad.material = passMaterial;
-		renderer.render( this.quadScene, this.quadCamera, renderTarget, clearNeeded );
+		renderer.render( this.quadScene, this.quadCamera );
 
 
 		// restore original state
 		// restore original state
 		renderer.autoClear = originalAutoClear;
 		renderer.autoClear = originalAutoClear;
@@ -288,22 +292,22 @@ THREE.SSAOPass.prototype = Object.assign( Object.create( THREE.Pass.prototype ),
 		var originalClearAlpha = renderer.getClearAlpha();
 		var originalClearAlpha = renderer.getClearAlpha();
 		var originalAutoClear = renderer.autoClear;
 		var originalAutoClear = renderer.autoClear;
 
 
+		renderer.setRenderTarget( renderTarget );
 		renderer.autoClear = false;
 		renderer.autoClear = false;
 
 
 		clearColor = overrideMaterial.clearColor || clearColor;
 		clearColor = overrideMaterial.clearColor || clearColor;
 		clearAlpha = overrideMaterial.clearAlpha || clearAlpha;
 		clearAlpha = overrideMaterial.clearAlpha || clearAlpha;
 
 
-		var clearNeeded = ( clearColor !== undefined ) && ( clearColor !== null );
-
-		if ( clearNeeded ) {
+		if ( ( clearColor !== undefined ) && ( clearColor !== null ) ) {
 
 
 			renderer.setClearColor( clearColor );
 			renderer.setClearColor( clearColor );
 			renderer.setClearAlpha( clearAlpha || 0.0 );
 			renderer.setClearAlpha( clearAlpha || 0.0 );
+			renderer.clear();
 
 
 		}
 		}
 
 
 		this.scene.overrideMaterial = overrideMaterial;
 		this.scene.overrideMaterial = overrideMaterial;
-		renderer.render( this.scene, this.camera, renderTarget, clearNeeded );
+		renderer.render( this.scene, this.camera );
 		this.scene.overrideMaterial = null;
 		this.scene.overrideMaterial = null;
 
 
 		// restore original state
 		// restore original state

+ 3 - 1
examples/js/postprocessing/SavePass.js

@@ -57,7 +57,9 @@ THREE.SavePass.prototype = Object.assign( Object.create( THREE.Pass.prototype ),
 
 
 		this.quad.material = this.material;
 		this.quad.material = this.material;
 
 
-		renderer.render( this.scene, this.camera, this.renderTarget, this.clear );
+		renderer.setRenderTarget( this.renderTarget );
+		if ( this.clear ) renderer.clear();
+		renderer.render( this.scene, this.camera );
 
 
 	}
 	}
 
 

+ 4 - 1
examples/js/postprocessing/ShaderPass.js

@@ -54,11 +54,14 @@ THREE.ShaderPass.prototype = Object.assign( Object.create( THREE.Pass.prototype
 
 
 		if ( this.renderToScreen ) {
 		if ( this.renderToScreen ) {
 
 
+			renderer.setRenderTarget( null );
 			renderer.render( this.scene, this.camera );
 			renderer.render( this.scene, this.camera );
 
 
 		} else {
 		} else {
 
 
-			renderer.render( this.scene, this.camera, writeBuffer, this.clear );
+			renderer.setRenderTarget( writeBuffer );
+			if ( this.clear ) renderer.clear();
+			renderer.render( this.scene, this.camera );
 
 
 		}
 		}
 
 

+ 13 - 4
examples/js/postprocessing/TAARenderPass.js

@@ -93,8 +93,13 @@ THREE.TAARenderPass.prototype = Object.assign( Object.create( THREE.SSAARenderPa
 
 
 				}
 				}
 
 
-				renderer.render( this.scene, this.camera, writeBuffer, true );
-				renderer.render( this.scene2, this.camera2, this.sampleRenderTarget, ( this.accumulateIndex === 0 ) );
+				renderer.setRenderTarget( writeBuffer );
+				renderer.clear();
+				renderer.render( this.scene, this.camera );
+
+				renderer.setRenderTarget( this.sampleRenderTarget );
+				if ( this.accumulateIndex === 0 ) renderer.clear();
+				renderer.render( this.scene2, this.camera2 );
 
 
 				this.accumulateIndex ++;
 				this.accumulateIndex ++;
 
 
@@ -112,7 +117,9 @@ THREE.TAARenderPass.prototype = Object.assign( Object.create( THREE.SSAARenderPa
 
 
 			this.copyUniforms[ "opacity" ].value = 1.0;
 			this.copyUniforms[ "opacity" ].value = 1.0;
 			this.copyUniforms[ "tDiffuse" ].value = this.sampleRenderTarget.texture;
 			this.copyUniforms[ "tDiffuse" ].value = this.sampleRenderTarget.texture;
-			renderer.render( this.scene2, this.camera2, writeBuffer, true );
+			renderer.setRenderTarget( writeBuffer );
+			renderer.clear();
+			renderer.render( this.scene2, this.camera2 );
 
 
 		}
 		}
 
 
@@ -120,7 +127,9 @@ THREE.TAARenderPass.prototype = Object.assign( Object.create( THREE.SSAARenderPa
 
 
 			this.copyUniforms[ "opacity" ].value = 1.0 - accumulationWeight;
 			this.copyUniforms[ "opacity" ].value = 1.0 - accumulationWeight;
 			this.copyUniforms[ "tDiffuse" ].value = this.holdRenderTarget.texture;
 			this.copyUniforms[ "tDiffuse" ].value = this.holdRenderTarget.texture;
-			renderer.render( this.scene2, this.camera2, writeBuffer, ( accumulationWeight === 0 ) );
+			renderer.setRenderTarget( writeBuffer );
+			if ( accumulationWeight === 0 ) renderer.clear();
+			renderer.render( this.scene2, this.camera2 );
 
 
 		}
 		}
 
 

+ 3 - 1
examples/js/postprocessing/TexturePass.js

@@ -52,7 +52,9 @@ THREE.TexturePass.prototype = Object.assign( Object.create( THREE.Pass.prototype
 		this.uniforms[ "tDiffuse" ].value = this.map;
 		this.uniforms[ "tDiffuse" ].value = this.map;
 		this.material.transparent = ( this.opacity < 1.0 );
 		this.material.transparent = ( this.opacity < 1.0 );
 
 
-		renderer.render( this.scene, this.camera, this.renderToScreen ? null : readBuffer, this.clear );
+		renderer.setRenderTarget( this.renderToScreen ? null : readBuffer );
+		if ( this.clear ) renderer.clear();
+		renderer.render( this.scene, this.camera );
 
 
 		renderer.autoClear = oldAutoClear;
 		renderer.autoClear = oldAutoClear;
 	}
 	}

+ 19 - 7
examples/js/postprocessing/UnrealBloomPass.js

@@ -203,7 +203,9 @@ THREE.UnrealBloomPass.prototype = Object.assign( Object.create( THREE.Pass.proto
 			this.quad.material = this.basic;
 			this.quad.material = this.basic;
 			this.basic.map = readBuffer.texture;
 			this.basic.map = readBuffer.texture;
 
 
-			renderer.render( this.scene, this.camera, undefined, true );
+			renderer.setRenderTarget( null );
+			renderer.clear();
+			renderer.render( this.scene, this.camera );
 
 
 		}
 		}
 
 
@@ -213,7 +215,9 @@ THREE.UnrealBloomPass.prototype = Object.assign( Object.create( THREE.Pass.proto
 		this.highPassUniforms[ "luminosityThreshold" ].value = this.threshold;
 		this.highPassUniforms[ "luminosityThreshold" ].value = this.threshold;
 		this.quad.material = this.materialHighPassFilter;
 		this.quad.material = this.materialHighPassFilter;
 
 
-		renderer.render( this.scene, this.camera, this.renderTargetBright, true );
+		renderer.setRenderTarget( this.renderTargetBright );
+		renderer.clear();
+		renderer.render( this.scene, this.camera );
 
 
 		// 2. Blur All the mips progressively
 		// 2. Blur All the mips progressively
 
 
@@ -225,11 +229,15 @@ THREE.UnrealBloomPass.prototype = Object.assign( Object.create( THREE.Pass.proto
 
 
 			this.separableBlurMaterials[ i ].uniforms[ "colorTexture" ].value = inputRenderTarget.texture;
 			this.separableBlurMaterials[ i ].uniforms[ "colorTexture" ].value = inputRenderTarget.texture;
 			this.separableBlurMaterials[ i ].uniforms[ "direction" ].value = THREE.UnrealBloomPass.BlurDirectionX;
 			this.separableBlurMaterials[ i ].uniforms[ "direction" ].value = THREE.UnrealBloomPass.BlurDirectionX;
-			renderer.render( this.scene, this.camera, this.renderTargetsHorizontal[ i ], true );
+			renderer.setRenderTarget( this.renderTargetsHorizontal[ i ] );
+			renderer.clear();
+			renderer.render( this.scene, this.camera );
 
 
 			this.separableBlurMaterials[ i ].uniforms[ "colorTexture" ].value = this.renderTargetsHorizontal[ i ].texture;
 			this.separableBlurMaterials[ i ].uniforms[ "colorTexture" ].value = this.renderTargetsHorizontal[ i ].texture;
 			this.separableBlurMaterials[ i ].uniforms[ "direction" ].value = THREE.UnrealBloomPass.BlurDirectionY;
 			this.separableBlurMaterials[ i ].uniforms[ "direction" ].value = THREE.UnrealBloomPass.BlurDirectionY;
-			renderer.render( this.scene, this.camera, this.renderTargetsVertical[ i ], true );
+			renderer.setRenderTarget( this.renderTargetsVertical[ i ] );
+			renderer.clear();
+			renderer.render( this.scene, this.camera );
 
 
 			inputRenderTarget = this.renderTargetsVertical[ i ];
 			inputRenderTarget = this.renderTargetsVertical[ i ];
 
 
@@ -242,7 +250,9 @@ THREE.UnrealBloomPass.prototype = Object.assign( Object.create( THREE.Pass.proto
 		this.compositeMaterial.uniforms[ "bloomRadius" ].value = this.radius;
 		this.compositeMaterial.uniforms[ "bloomRadius" ].value = this.radius;
 		this.compositeMaterial.uniforms[ "bloomTintColors" ].value = this.bloomTintColors;
 		this.compositeMaterial.uniforms[ "bloomTintColors" ].value = this.bloomTintColors;
 
 
-		renderer.render( this.scene, this.camera, this.renderTargetsHorizontal[ 0 ], true );
+		renderer.setRenderTarget( this.renderTargetsHorizontal[ 0 ] );
+		renderer.clear();
+		renderer.render( this.scene, this.camera );
 
 
 		// Blend it additively over the input texture
 		// Blend it additively over the input texture
 
 
@@ -254,11 +264,13 @@ THREE.UnrealBloomPass.prototype = Object.assign( Object.create( THREE.Pass.proto
 
 
 		if ( this.renderToScreen ) {
 		if ( this.renderToScreen ) {
 
 
-			renderer.render( this.scene, this.camera, undefined, false );
+			renderer.setRenderTarget( null );
+			renderer.render( this.scene, this.camera );
 
 
 		} else {
 		} else {
 
 
-			renderer.render( this.scene, this.camera, readBuffer, false );
+			renderer.setRenderTarget( readBuffer );
+			renderer.render( this.scene, this.camera );
 
 
 		}
 		}
 
 

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

@@ -125,8 +125,8 @@ THREE.WebGLDeferredRenderer = function ( parameters ) {
 
 
 		_gl = _this.renderer.context;
 		_gl = _this.renderer.context;
 
 
-		_width = parameters.width !== undefined ? parameters.width : _this.renderer.getSize().width;
-		_height = parameters.height !== undefined ? parameters.height : _this.renderer.getSize().height;
+		_width = parameters.width !== undefined ? parameters.width : _this.renderer.getSize( new THREE.Vector2() ).width;
+		_height = parameters.height !== undefined ? parameters.height : _this.renderer.getSize( new THREE.Vector2() ).height;
 
 
 		var antialias = parameters.antialias !== undefined ? parameters.antialias : false;
 		var antialias = parameters.antialias !== undefined ? parameters.antialias : false;
 
 

二进制
examples/models/svg/tests/8.png


+ 31 - 0
examples/models/svg/tests/8.svg

@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   id="svg8"
+   version="1.1"
+   viewBox="0 0 210 197"
+   height="60mm"
+   width="80mm">
+  <defs
+     id="defs2" />
+  <metadata
+     id="metadata5">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+        <dc:title></dc:title>
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <path
+     style="fill:#e9c6af;fill-rule:evenodd;stroke:#000000;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+     d="m 80,10 0,50 -70,0 0,-50 z m -51,31 5,0 0,-5 -5,0 z"
+     id="path7925" />
+</svg>

+ 1 - 1
examples/software_sandbox.html

@@ -28,7 +28,7 @@
 	<body>
 	<body>
 
 
 		<div id="info">
 		<div id="info">
-			<a href="http://threejs.org" target="_blank" rel="noopener">three.js</a> - software renderer</br>
+			<a href="http://threejs.org" target="_blank" rel="noopener">three.js</a> - software renderer<br />
 			drag to change the point of view
 			drag to change the point of view
 		</div>
 		</div>
 
 

+ 27 - 20
examples/webaudio_orientation.html

@@ -114,7 +114,7 @@
 		//
 		//
 
 
 		camera = new THREE.PerspectiveCamera( 45, window.innerWidth / window.innerHeight, 0.1, 100 );
 		camera = new THREE.PerspectiveCamera( 45, window.innerWidth / window.innerHeight, 0.1, 100 );
-		camera.position.set( 0, 1, 2 );
+		camera.position.set( 3, 2, 3 );
 
 
 		var reflectionCube = new THREE.CubeTextureLoader()
 		var reflectionCube = new THREE.CubeTextureLoader()
 			.setPath( 'textures/cube/SwedishRoyalCastle/' )
 			.setPath( 'textures/cube/SwedishRoyalCastle/' )
@@ -127,29 +127,31 @@
 
 
 		//
 		//
 
 
-		var light = new THREE.HemisphereLight( 0xffffff, 0x444444 );
-		light.position.set( 0, 200, 0 );
-		scene.add( light );
+		var hemiLight = new THREE.HemisphereLight( 0xffffff, 0x444444 );
+		hemiLight.position.set( 0, 20, 0 );
+		scene.add( hemiLight );
 
 
-		light = new THREE.DirectionalLight( 0xffffff );
-		light.position.set( 0, 200, 100 );
-		light.castShadow = true;
-		light.shadow.camera.top = 180;
-		light.shadow.camera.bottom = - 100;
-		light.shadow.camera.left = - 120;
-		light.shadow.camera.right = 120;
-		scene.add( light );
+		var dirLight = new THREE.DirectionalLight( 0xffffff );
+		dirLight.position.set( 5, 5, 0 );
+		dirLight.castShadow = true;
+		dirLight.shadow.camera.top = 1;
+		dirLight.shadow.camera.bottom = - 1;
+		dirLight.shadow.camera.left = - 1;
+		dirLight.shadow.camera.right = 1;
+		dirLight.shadow.camera.near = 0.1;
+		dirLight.shadow.camera.far = 20;
+		scene.add( dirLight );
+
+		// scene.add( new THREE.CameraHelper( dirLight.shadow.camera ) );
 
 
 		//
 		//
 
 
-		var mesh = new THREE.Mesh( new THREE.PlaneBufferGeometry( 20, 20 ), new THREE.MeshPhongMaterial( { color: 0x999999, depthWrite: false } ) );
+		var mesh = new THREE.Mesh( new THREE.PlaneBufferGeometry( 50, 50 ), new THREE.MeshPhongMaterial( { color: 0x999999, depthWrite: false } ) );
 		mesh.rotation.x = - Math.PI / 2;
 		mesh.rotation.x = - Math.PI / 2;
 		mesh.receiveShadow = true;
 		mesh.receiveShadow = true;
 		scene.add( mesh );
 		scene.add( mesh );
 
 
-		var grid = new THREE.GridHelper( 20, 20, 0x000000, 0x000000 );
-		grid.material.opacity = 0.2;
-		grid.material.transparent = true;
+		var grid = new THREE.GridHelper( 50, 50, 0x888888, 0x888888 );
 		scene.add( grid );
 		scene.add( grid );
 
 
 		//
 		//
@@ -163,7 +165,10 @@
 		var positionalAudio = new THREE.PositionalAudio( listener );
 		var positionalAudio = new THREE.PositionalAudio( listener );
 		positionalAudio.setMediaElementSource( audioElement );
 		positionalAudio.setMediaElementSource( audioElement );
 		positionalAudio.setRefDistance( 1 );
 		positionalAudio.setRefDistance( 1 );
-		positionalAudio.setDirectionalCone( 210, 230, 0.1 );
+		positionalAudio.setDirectionalCone( 180, 230, 0.1 );
+
+		var helper = new THREE.PositionalAudioHelper( positionalAudio, 0.1 );
+		positionalAudio.add( helper );
 
 
 		//
 		//
 
 
@@ -180,6 +185,7 @@
 
 
 					object.material.envMap = reflectionCube;
 					object.material.envMap = reflectionCube;
 					object.geometry.rotateY( - Math.PI );
 					object.geometry.rotateY( - Math.PI );
+					object.castShadow = true;
 
 
 				}
 				}
 
 
@@ -194,7 +200,7 @@
 		// sound is damped behind this wall
 		// sound is damped behind this wall
 
 
 		var wallGeometry = new THREE.BoxBufferGeometry( 2, 1, 0.1 );
 		var wallGeometry = new THREE.BoxBufferGeometry( 2, 1, 0.1 );
-		var wallMaterial = new THREE.MeshBasicMaterial( { color: 0xff0000, wireframe: true } );
+		var wallMaterial = new THREE.MeshBasicMaterial( { color: 0xff0000, transparent: true, opacity: 0.5 } );
 
 
 		var wall = new THREE.Mesh( wallGeometry, wallMaterial );
 		var wall = new THREE.Mesh( wallGeometry, wallMaterial );
 		wall.position.set( 0, 0.5, - 0.5 );
 		wall.position.set( 0, 0.5, - 0.5 );
@@ -206,9 +212,10 @@
 		renderer = new THREE.WebGLRenderer( { antialias: true } );
 		renderer = new THREE.WebGLRenderer( { antialias: true } );
 		renderer.setSize( window.innerWidth, window.innerHeight );
 		renderer.setSize( window.innerWidth, window.innerHeight );
 		renderer.setPixelRatio( window.devicePixelRatio );
 		renderer.setPixelRatio( window.devicePixelRatio );
-		container.appendChild( renderer.domElement );
-
 		renderer.gammaOutput = true;
 		renderer.gammaOutput = true;
+		renderer.gammaFactor = 2.2;
+		renderer.shadowMap.enabled = true;
+		container.appendChild( renderer.domElement );
 
 
 		//
 		//
 
 

+ 1 - 1
examples/webgl2_multisampled_renderbuffers.html

@@ -130,7 +130,7 @@
 					stencilBuffer: false
 					stencilBuffer: false
 				};
 				};
 
 
-				var size = renderer.getDrawingBufferSize();
+				var size = renderer.getDrawingBufferSize( new THREE.Vector2() );
 				var renderTarget = new THREE.WebGLMultisampleRenderTarget( size.width, size.height, parameters );
 				var renderTarget = new THREE.WebGLMultisampleRenderTarget( size.width, size.height, parameters );
 
 
 				var renderPass = new THREE.RenderPass( scene, camera );
 				var renderPass = new THREE.RenderPass( scene, camera );

+ 3 - 1
examples/webgl_depth_texture.html

@@ -229,9 +229,11 @@
 				requestAnimationFrame( animate );
 				requestAnimationFrame( animate );
 
 
 				// render scene into target
 				// render scene into target
-				renderer.render( scene, camera, target );
+				renderer.setRenderTarget( target );
+				renderer.render( scene, camera );
 
 
 				// render post FX
 				// render post FX
+				renderer.setRenderTarget( null );
 				renderer.render( postScene, postCamera );
 				renderer.render( postScene, postCamera );
 
 
 				stats.update();
 				stats.update();

+ 3 - 1
examples/webgl_interactive_cubes_gpu.html

@@ -206,7 +206,8 @@
 
 
 				// render the scene
 				// render the scene
 
 
-				renderer.render( pickingScene, camera, pickingTexture );
+				renderer.setRenderTarget( pickingTexture );
+				renderer.render( pickingScene, camera );
 
 
 				// clear the view offset so rendering returns to normal
 				// clear the view offset so rendering returns to normal
 
 
@@ -252,6 +253,7 @@
 
 
 				pick();
 				pick();
 
 
+				renderer.setRenderTarget( null );
 				renderer.render( scene, camera );
 				renderer.render( scene, camera );
 
 
 			}
 			}

+ 5 - 2
examples/webgl_interactive_instances_gpu.html

@@ -1045,15 +1045,17 @@
 
 
 			highlightBox.visible = false;
 			highlightBox.visible = false;
 
 
+			renderer.setRenderTarget( pickingRenderTarget );
+
 			if ( singlePickingMaterial ) {
 			if ( singlePickingMaterial ) {
 
 
 				scene.overrideMaterial = singlePickingMaterial;
 				scene.overrideMaterial = singlePickingMaterial;
-				renderer.render( scene, camera, pickingRenderTarget );
+				renderer.render( scene, camera );
 				scene.overrideMaterial = null;
 				scene.overrideMaterial = null;
 
 
 			} else {
 			} else {
 
 
-				renderer.render( pickingScene, camera, pickingRenderTarget );
+				renderer.render( pickingScene, camera );
 
 
 			}
 			}
 
 
@@ -1105,6 +1107,7 @@
 		function render() {
 		function render() {
 
 
 			pick();
 			pick();
+			renderer.setRenderTarget( null );
 			renderer.render( scene, camera );
 			renderer.render( scene, camera );
 
 
 		}
 		}

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