]> gitweb.ps.run Git - cloth_sim/blobdiff - Scripts/three.module.js
copy old files for refactoring, update Three.js
[cloth_sim] / Scripts / three.module.js
index 4f400532591c6d2e39b422157a194112390f154a..a499d33400b6416d0462bb59ac85d05a9765ad6f 100644 (file)
@@ -1,5 +1,5 @@
 // threejs.org/license
-const REVISION = '123';
+const REVISION = '125';
 const MOUSE = { LEFT: 0, MIDDLE: 1, RIGHT: 2, ROTATE: 0, DOLLY: 1, PAN: 2 };
 const TOUCH = { ROTATE: 0, PAN: 1, DOLLY_PAN: 2, DOLLY_ROTATE: 3 };
 const CullFaceNone = 0;
@@ -197,8 +197,8 @@ const StaticCopyUsage = 35046;
 const DynamicCopyUsage = 35050;
 const StreamCopyUsage = 35042;
 
-const GLSL1 = "100";
-const GLSL3 = "300 es";
+const GLSL1 = '100';
+const GLSL3 = '300 es';
 
 /**
  * https://github.com/mrdoob/eventdispatcher.js/
@@ -349,6 +349,22 @@ const MathUtils = {
 
        },
 
+       // http://www.rorydriscoll.com/2016/03/07/frame-rate-independent-damping-using-lerp/
+
+       damp: function ( x, y, lambda, dt ) {
+
+               return MathUtils.lerp( x, y, 1 - Math.exp( - lambda * dt ) );
+
+       },
+
+       // https://www.desmos.com/calculator/vcsjnyz7x4
+
+       pingpong: function ( x, length = 1 ) {
+
+               return length - Math.abs( MathUtils.euclideanModulo( x, length * 2 ) - length );
+
+       },
+
        // http://en.wikipedia.org/wiki/Smoothstep
 
        smoothstep: function ( x, min, max ) {
@@ -1216,6 +1232,8 @@ class Matrix3 {
                        0, 0, 1
                );
 
+               return this;
+
        }
 
        scale( sx, sy ) {
@@ -1683,7 +1701,7 @@ Texture.prototype = Object.assign( Object.create( EventDispatcher.prototype ), {
 
 } );
 
-Object.defineProperty( Texture.prototype, "needsUpdate", {
+Object.defineProperty( Texture.prototype, 'needsUpdate', {
 
        set: function ( value ) {
 
@@ -1956,6 +1974,17 @@ class Vector4 {
 
        }
 
+       multiply( v ) {
+
+               this.x *= v.x;
+               this.y *= v.y;
+               this.z *= v.z;
+               this.w *= v.w;
+
+               return this;
+
+       }
+
        multiplyScalar( scalar ) {
 
                this.x *= scalar;
@@ -2375,40 +2404,40 @@ class Vector4 {
  * Texture parameters for an auto-generated target texture
  * depthBuffer/stencilBuffer: Booleans to indicate if we should generate these buffers
 */
-function WebGLRenderTarget( width, height, options ) {
+class WebGLRenderTarget extends EventDispatcher {
 
-       this.width = width;
-       this.height = height;
+       constructor( width, height, options ) {
 
-       this.scissor = new Vector4( 0, 0, width, height );
-       this.scissorTest = false;
+               super();
 
-       this.viewport = new Vector4( 0, 0, width, height );
+               Object.defineProperty( this, 'isWebGLRenderTarget', { value: true } );
 
-       options = options || {};
+               this.width = width;
+               this.height = height;
 
-       this.texture = new Texture( undefined, options.mapping, options.wrapS, options.wrapT, options.magFilter, options.minFilter, options.format, options.type, options.anisotropy, options.encoding );
+               this.scissor = new Vector4( 0, 0, width, height );
+               this.scissorTest = false;
 
-       this.texture.image = {};
-       this.texture.image.width = width;
-       this.texture.image.height = height;
+               this.viewport = new Vector4( 0, 0, width, height );
 
-       this.texture.generateMipmaps = options.generateMipmaps !== undefined ? options.generateMipmaps : false;
-       this.texture.minFilter = options.minFilter !== undefined ? options.minFilter : LinearFilter;
+               options = options || {};
 
-       this.depthBuffer = options.depthBuffer !== undefined ? options.depthBuffer : true;
-       this.stencilBuffer = options.stencilBuffer !== undefined ? options.stencilBuffer : false;
-       this.depthTexture = options.depthTexture !== undefined ? options.depthTexture : null;
+               this.texture = new Texture( undefined, options.mapping, options.wrapS, options.wrapT, options.magFilter, options.minFilter, options.format, options.type, options.anisotropy, options.encoding );
 
-}
+               this.texture.image = {};
+               this.texture.image.width = width;
+               this.texture.image.height = height;
 
-WebGLRenderTarget.prototype = Object.assign( Object.create( EventDispatcher.prototype ), {
+               this.texture.generateMipmaps = options.generateMipmaps !== undefined ? options.generateMipmaps : false;
+               this.texture.minFilter = options.minFilter !== undefined ? options.minFilter : LinearFilter;
 
-       constructor: WebGLRenderTarget,
+               this.depthBuffer = options.depthBuffer !== undefined ? options.depthBuffer : true;
+               this.stencilBuffer = options.stencilBuffer !== undefined ? options.stencilBuffer : false;
+               this.depthTexture = options.depthTexture !== undefined ? options.depthTexture : null;
 
-       isWebGLRenderTarget: true,
+       }
 
-       setSize: function ( width, height ) {
+       setSize( width, height ) {
 
                if ( this.width !== width || this.height !== height ) {
 
@@ -2425,15 +2454,15 @@ WebGLRenderTarget.prototype = Object.assign( Object.create( EventDispatcher.prot
                this.viewport.set( 0, 0, width, height );
                this.scissor.set( 0, 0, width, height );
 
-       },
+       }
 
-       clone: function () {
+       clone() {
 
                return new this.constructor().copy( this );
 
-       },
+       }
 
-       copy: function ( source ) {
+       copy( source ) {
 
                this.width = source.width;
                this.height = source.height;
@@ -2448,33 +2477,31 @@ WebGLRenderTarget.prototype = Object.assign( Object.create( EventDispatcher.prot
 
                return this;
 
-       },
+       }
 
-       dispose: function () {
+       dispose() {
 
                this.dispatchEvent( { type: 'dispose' } );
 
        }
 
-} );
-
-function WebGLMultisampleRenderTarget( width, height, options ) {
+}
 
-       WebGLRenderTarget.call( this, width, height, options );
+class WebGLMultisampleRenderTarget extends WebGLRenderTarget {
 
-       this.samples = 4;
+       constructor( width, height, options ) {
 
-}
+               super( width, height, options );
 
-WebGLMultisampleRenderTarget.prototype = Object.assign( Object.create( WebGLRenderTarget.prototype ), {
+               Object.defineProperty( this, 'isWebGLMultisampleRenderTarget', { value: true } );
 
-       constructor: WebGLMultisampleRenderTarget,
+               this.samples = 4;
 
-       isWebGLMultisampleRenderTarget: true,
+       }
 
-       copy: function ( source ) {
+       copy( source ) {
 
-               WebGLRenderTarget.prototype.copy.call( this, source );
+               super.copy.call( this, source );
 
                this.samples = source.samples;
 
@@ -2482,7 +2509,7 @@ WebGLMultisampleRenderTarget.prototype = Object.assign( Object.create( WebGLRend
 
        }
 
-} );
+}
 
 class Quaternion {
 
@@ -5160,6 +5187,23 @@ class Matrix4 {
 
        }
 
+       setFromMatrix3( m ) {
+
+               const me = m.elements;
+
+               this.set(
+
+                       me[ 0 ], me[ 3 ], me[ 6 ], 0,
+                       me[ 1 ], me[ 4 ], me[ 7 ], 0,
+                       me[ 2 ], me[ 5 ], me[ 8 ], 0,
+                       0, 0, 0, 1
+
+               );
+
+               return this;
+
+       }
+
        extractBasis( xAxis, yAxis, zAxis ) {
 
                xAxis.setFromMatrixColumn( this, 0 );
@@ -6622,12 +6666,12 @@ Object3D.prototype = Object.assign( Object.create( EventDispatcher.prototype ),
 
                if ( object === this ) {
 
-                       console.error( "THREE.Object3D.add: object can't be added as a child of itself.", object );
+                       console.error( 'THREE.Object3D.add: object can\'t be added as a child of itself.', object );
                        return this;
 
                }
 
-               if ( ( object && object.isObject3D ) ) {
+               if ( object && object.isObject3D ) {
 
                        if ( object.parent !== null ) {
 
@@ -6642,7 +6686,7 @@ Object3D.prototype = Object.assign( Object.create( EventDispatcher.prototype ),
 
                } else {
 
-                       console.error( "THREE.Object3D.add: object not an instance of THREE.Object3D.", object );
+                       console.error( 'THREE.Object3D.add: object not an instance of THREE.Object3D.', object );
 
                }
 
@@ -7922,7 +7966,7 @@ class Color {
 
                let m;
 
-               if ( m = /^((?:rgb|hsl)a?)\(\s*([^\)]*)\)/.exec( style ) ) {
+               if ( m = /^((?:rgb|hsl)a?)\(([^\)]*)\)/.exec( style ) ) {
 
                        // rgb / hsl
 
@@ -7935,27 +7979,27 @@ class Color {
                                case 'rgb':
                                case 'rgba':
 
-                                       if ( color = /^(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*(,\s*([0-9]*\.?[0-9]+)\s*)?$/.exec( components ) ) {
+                                       if ( color = /^\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*(?:,\s*(\d*\.?\d+)\s*)?$/.exec( components ) ) {
 
                                                // rgb(255,0,0) rgba(255,0,0,0.5)
                                                this.r = Math.min( 255, parseInt( color[ 1 ], 10 ) ) / 255;
                                                this.g = Math.min( 255, parseInt( color[ 2 ], 10 ) ) / 255;
                                                this.b = Math.min( 255, parseInt( color[ 3 ], 10 ) ) / 255;
 
-                                               handleAlpha( color[ 5 ] );
+                                               handleAlpha( color[ 4 ] );
 
                                                return this;
 
                                        }
 
-                                       if ( color = /^(\d+)\%\s*,\s*(\d+)\%\s*,\s*(\d+)\%\s*(,\s*([0-9]*\.?[0-9]+)\s*)?$/.exec( components ) ) {
+                                       if ( color = /^\s*(\d+)\%\s*,\s*(\d+)\%\s*,\s*(\d+)\%\s*(?:,\s*(\d*\.?\d+)\s*)?$/.exec( components ) ) {
 
                                                // rgb(100%,0%,0%) rgba(100%,0%,0%,0.5)
                                                this.r = Math.min( 100, parseInt( color[ 1 ], 10 ) ) / 100;
                                                this.g = Math.min( 100, parseInt( color[ 2 ], 10 ) ) / 100;
                                                this.b = Math.min( 100, parseInt( color[ 3 ], 10 ) ) / 100;
 
-                                               handleAlpha( color[ 5 ] );
+                                               handleAlpha( color[ 4 ] );
 
                                                return this;
 
@@ -7966,14 +8010,14 @@ class Color {
                                case 'hsl':
                                case 'hsla':
 
-                                       if ( color = /^([0-9]*\.?[0-9]+)\s*,\s*(\d+)\%\s*,\s*(\d+)\%\s*(,\s*([0-9]*\.?[0-9]+)\s*)?$/.exec( components ) ) {
+                                       if ( color = /^\s*(\d*\.?\d+)\s*,\s*(\d+)\%\s*,\s*(\d+)\%\s*(?:,\s*(\d*\.?\d+)\s*)?$/.exec( components ) ) {
 
                                                // hsl(120,50%,50%) hsla(120,50%,50%,0.5)
                                                const h = parseFloat( color[ 1 ] ) / 360;
                                                const s = parseInt( color[ 2 ], 10 ) / 100;
                                                const l = parseInt( color[ 3 ], 10 ) / 100;
 
-                                               handleAlpha( color[ 5 ] );
+                                               handleAlpha( color[ 4 ] );
 
                                                return this.setHSL( h, s, l );
 
@@ -7983,7 +8027,7 @@ class Color {
 
                        }
 
-               } else if ( m = /^\#([A-Fa-f0-9]+)$/.exec( style ) ) {
+               } else if ( m = /^\#([A-Fa-f\d]+)$/.exec( style ) ) {
 
                        // hex color
 
@@ -8283,6 +8327,16 @@ class Color {
 
        }
 
+       lerpColors( color1, color2, alpha ) {
+
+               this.r = color1.r + ( color2.r - color1.r ) * alpha;
+               this.g = color1.g + ( color2.g - color1.g ) * alpha;
+               this.b = color1.b + ( color2.b - color1.b ) * alpha;
+
+               return this;
+
+       }
+
        lerpHSL( color, alpha ) {
 
                this.getHSL( _hslA );
@@ -8504,7 +8558,7 @@ Material.prototype = Object.assign( Object.create( EventDispatcher.prototype ),
 
                        if ( newValue === undefined ) {
 
-                               console.warn( "THREE.Material: '" + key + "' parameter is undefined." );
+                               console.warn( 'THREE.Material: \'' + key + '\' parameter is undefined.' );
                                continue;
 
                        }
@@ -8522,7 +8576,7 @@ Material.prototype = Object.assign( Object.create( EventDispatcher.prototype ),
 
                        if ( currentValue === undefined ) {
 
-                               console.warn( "THREE." + this.type + ": '" + key + "' is not a property of this material." );
+                               console.warn( 'THREE.' + this.type + ': \'' + key + '\' is not a property of this material.' );
                                continue;
 
                        }
@@ -9464,285 +9518,6 @@ function Float64BufferAttribute( array, itemSize, normalized ) {
 Float64BufferAttribute.prototype = Object.create( BufferAttribute.prototype );
 Float64BufferAttribute.prototype.constructor = Float64BufferAttribute;
 
-class DirectGeometry {
-
-       constructor() {
-
-               this.vertices = [];
-               this.normals = [];
-               this.colors = [];
-               this.uvs = [];
-               this.uvs2 = [];
-
-               this.groups = [];
-
-               this.morphTargets = {};
-
-               this.skinWeights = [];
-               this.skinIndices = [];
-
-               // this.lineDistances = [];
-
-               this.boundingBox = null;
-               this.boundingSphere = null;
-
-               // update flags
-
-               this.verticesNeedUpdate = false;
-               this.normalsNeedUpdate = false;
-               this.colorsNeedUpdate = false;
-               this.uvsNeedUpdate = false;
-               this.groupsNeedUpdate = false;
-
-       }
-
-       computeGroups( geometry ) {
-
-               const groups = [];
-
-               let group, i;
-               let materialIndex = undefined;
-
-               const faces = geometry.faces;
-
-               for ( i = 0; i < faces.length; i ++ ) {
-
-                       const face = faces[ i ];
-
-                       // materials
-
-                       if ( face.materialIndex !== materialIndex ) {
-
-                               materialIndex = face.materialIndex;
-
-                               if ( group !== undefined ) {
-
-                                       group.count = ( i * 3 ) - group.start;
-                                       groups.push( group );
-
-                               }
-
-                               group = {
-                                       start: i * 3,
-                                       materialIndex: materialIndex
-                               };
-
-                       }
-
-               }
-
-               if ( group !== undefined ) {
-
-                       group.count = ( i * 3 ) - group.start;
-                       groups.push( group );
-
-               }
-
-               this.groups = groups;
-
-       }
-
-       fromGeometry( geometry ) {
-
-               const faces = geometry.faces;
-               const vertices = geometry.vertices;
-               const faceVertexUvs = geometry.faceVertexUvs;
-
-               const hasFaceVertexUv = faceVertexUvs[ 0 ] && faceVertexUvs[ 0 ].length > 0;
-               const hasFaceVertexUv2 = faceVertexUvs[ 1 ] && faceVertexUvs[ 1 ].length > 0;
-
-               // morphs
-
-               const morphTargets = geometry.morphTargets;
-               const morphTargetsLength = morphTargets.length;
-
-               let morphTargetsPosition;
-
-               if ( morphTargetsLength > 0 ) {
-
-                       morphTargetsPosition = [];
-
-                       for ( let i = 0; i < morphTargetsLength; i ++ ) {
-
-                               morphTargetsPosition[ i ] = {
-                                       name: morphTargets[ i ].name,
-                                       data: []
-                               };
-
-                       }
-
-                       this.morphTargets.position = morphTargetsPosition;
-
-               }
-
-               const morphNormals = geometry.morphNormals;
-               const morphNormalsLength = morphNormals.length;
-
-               let morphTargetsNormal;
-
-               if ( morphNormalsLength > 0 ) {
-
-                       morphTargetsNormal = [];
-
-                       for ( let i = 0; i < morphNormalsLength; i ++ ) {
-
-                               morphTargetsNormal[ i ] = {
-                                       name: morphNormals[ i ].name,
-                                       data: []
-                               };
-
-                       }
-
-                       this.morphTargets.normal = morphTargetsNormal;
-
-               }
-
-               // skins
-
-               const skinIndices = geometry.skinIndices;
-               const skinWeights = geometry.skinWeights;
-
-               const hasSkinIndices = skinIndices.length === vertices.length;
-               const hasSkinWeights = skinWeights.length === vertices.length;
-
-               //
-
-               if ( vertices.length > 0 && faces.length === 0 ) {
-
-                       console.error( 'THREE.DirectGeometry: Faceless geometries are not supported.' );
-
-               }
-
-               for ( let i = 0; i < faces.length; i ++ ) {
-
-                       const face = faces[ i ];
-
-                       this.vertices.push( vertices[ face.a ], vertices[ face.b ], vertices[ face.c ] );
-
-                       const vertexNormals = face.vertexNormals;
-
-                       if ( vertexNormals.length === 3 ) {
-
-                               this.normals.push( vertexNormals[ 0 ], vertexNormals[ 1 ], vertexNormals[ 2 ] );
-
-                       } else {
-
-                               const normal = face.normal;
-
-                               this.normals.push( normal, normal, normal );
-
-                       }
-
-                       const vertexColors = face.vertexColors;
-
-                       if ( vertexColors.length === 3 ) {
-
-                               this.colors.push( vertexColors[ 0 ], vertexColors[ 1 ], vertexColors[ 2 ] );
-
-                       } else {
-
-                               const color = face.color;
-
-                               this.colors.push( color, color, color );
-
-                       }
-
-                       if ( hasFaceVertexUv === true ) {
-
-                               const vertexUvs = faceVertexUvs[ 0 ][ i ];
-
-                               if ( vertexUvs !== undefined ) {
-
-                                       this.uvs.push( vertexUvs[ 0 ], vertexUvs[ 1 ], vertexUvs[ 2 ] );
-
-                               } else {
-
-                                       console.warn( 'THREE.DirectGeometry.fromGeometry(): Undefined vertexUv ', i );
-
-                                       this.uvs.push( new Vector2(), new Vector2(), new Vector2() );
-
-                               }
-
-                       }
-
-                       if ( hasFaceVertexUv2 === true ) {
-
-                               const vertexUvs = faceVertexUvs[ 1 ][ i ];
-
-                               if ( vertexUvs !== undefined ) {
-
-                                       this.uvs2.push( vertexUvs[ 0 ], vertexUvs[ 1 ], vertexUvs[ 2 ] );
-
-                               } else {
-
-                                       console.warn( 'THREE.DirectGeometry.fromGeometry(): Undefined vertexUv2 ', i );
-
-                                       this.uvs2.push( new Vector2(), new Vector2(), new Vector2() );
-
-                               }
-
-                       }
-
-                       // morphs
-
-                       for ( let j = 0; j < morphTargetsLength; j ++ ) {
-
-                               const morphTarget = morphTargets[ j ].vertices;
-
-                               morphTargetsPosition[ j ].data.push( morphTarget[ face.a ], morphTarget[ face.b ], morphTarget[ face.c ] );
-
-                       }
-
-                       for ( let j = 0; j < morphNormalsLength; j ++ ) {
-
-                               const morphNormal = morphNormals[ j ].vertexNormals[ i ];
-
-                               morphTargetsNormal[ j ].data.push( morphNormal.a, morphNormal.b, morphNormal.c );
-
-                       }
-
-                       // skins
-
-                       if ( hasSkinIndices ) {
-
-                               this.skinIndices.push( skinIndices[ face.a ], skinIndices[ face.b ], skinIndices[ face.c ] );
-
-                       }
-
-                       if ( hasSkinWeights ) {
-
-                               this.skinWeights.push( skinWeights[ face.a ], skinWeights[ face.b ], skinWeights[ face.c ] );
-
-                       }
-
-               }
-
-               this.computeGroups( geometry );
-
-               this.verticesNeedUpdate = geometry.verticesNeedUpdate;
-               this.normalsNeedUpdate = geometry.normalsNeedUpdate;
-               this.colorsNeedUpdate = geometry.colorsNeedUpdate;
-               this.uvsNeedUpdate = geometry.uvsNeedUpdate;
-               this.groupsNeedUpdate = geometry.groupsNeedUpdate;
-
-               if ( geometry.boundingSphere !== null ) {
-
-                       this.boundingSphere = geometry.boundingSphere.clone();
-
-               }
-
-               if ( geometry.boundingBox !== null ) {
-
-                       this.boundingBox = geometry.boundingBox.clone();
-
-               }
-
-               return this;
-
-       }
-
-}
-
 function arrayMax( array ) {
 
        if ( array.length === 0 ) return - Infinity;
@@ -9778,7 +9553,7 @@ function getTypedArray( type, buffer ) {
 
 }
 
-let _bufferGeometryId = 1; // BufferGeometry uses odd numbers as Id
+let _id = 0;
 
 const _m1$2 = new Matrix4();
 const _obj = new Object3D();
@@ -9789,7 +9564,7 @@ const _vector$4 = new Vector3();
 
 function BufferGeometry() {
 
-       Object.defineProperty( this, 'id', { value: _bufferGeometryId += 2 } );
+       Object.defineProperty( this, 'id', { value: _id ++ } );
 
        this.uuid = MathUtils.generateUUID();
 
@@ -10028,54 +9803,6 @@ BufferGeometry.prototype = Object.assign( Object.create( EventDispatcher.prototy
 
        },
 
-       setFromObject: function ( object ) {
-
-               // console.log( 'THREE.BufferGeometry.setFromObject(). Converting', object, this );
-
-               const geometry = object.geometry;
-
-               if ( object.isPoints || object.isLine ) {
-
-                       const positions = new Float32BufferAttribute( geometry.vertices.length * 3, 3 );
-                       const colors = new Float32BufferAttribute( geometry.colors.length * 3, 3 );
-
-                       this.setAttribute( 'position', positions.copyVector3sArray( geometry.vertices ) );
-                       this.setAttribute( 'color', colors.copyColorsArray( geometry.colors ) );
-
-                       if ( geometry.lineDistances && geometry.lineDistances.length === geometry.vertices.length ) {
-
-                               const lineDistances = new Float32BufferAttribute( geometry.lineDistances.length, 1 );
-
-                               this.setAttribute( 'lineDistance', lineDistances.copyArray( geometry.lineDistances ) );
-
-                       }
-
-                       if ( geometry.boundingSphere !== null ) {
-
-                               this.boundingSphere = geometry.boundingSphere.clone();
-
-                       }
-
-                       if ( geometry.boundingBox !== null ) {
-
-                               this.boundingBox = geometry.boundingBox.clone();
-
-                       }
-
-               } else if ( object.isMesh ) {
-
-                       if ( geometry && geometry.isGeometry ) {
-
-                               this.fromGeometry( geometry );
-
-                       }
-
-               }
-
-               return this;
-
-       },
-
        setFromPoints: function ( points ) {
 
                const position = [];
@@ -10093,232 +9820,6 @@ BufferGeometry.prototype = Object.assign( Object.create( EventDispatcher.prototy
 
        },
 
-       updateFromObject: function ( object ) {
-
-               let geometry = object.geometry;
-
-               if ( object.isMesh ) {
-
-                       let direct = geometry.__directGeometry;
-
-                       if ( geometry.elementsNeedUpdate === true ) {
-
-                               direct = undefined;
-                               geometry.elementsNeedUpdate = false;
-
-                       }
-
-                       if ( direct === undefined ) {
-
-                               return this.fromGeometry( geometry );
-
-                       }
-
-                       direct.verticesNeedUpdate = geometry.verticesNeedUpdate;
-                       direct.normalsNeedUpdate = geometry.normalsNeedUpdate;
-                       direct.colorsNeedUpdate = geometry.colorsNeedUpdate;
-                       direct.uvsNeedUpdate = geometry.uvsNeedUpdate;
-                       direct.groupsNeedUpdate = geometry.groupsNeedUpdate;
-
-                       geometry.verticesNeedUpdate = false;
-                       geometry.normalsNeedUpdate = false;
-                       geometry.colorsNeedUpdate = false;
-                       geometry.uvsNeedUpdate = false;
-                       geometry.groupsNeedUpdate = false;
-
-                       geometry = direct;
-
-               }
-
-               if ( geometry.verticesNeedUpdate === true ) {
-
-                       const attribute = this.attributes.position;
-
-                       if ( attribute !== undefined ) {
-
-                               attribute.copyVector3sArray( geometry.vertices );
-                               attribute.needsUpdate = true;
-
-                       }
-
-                       geometry.verticesNeedUpdate = false;
-
-               }
-
-               if ( geometry.normalsNeedUpdate === true ) {
-
-                       const attribute = this.attributes.normal;
-
-                       if ( attribute !== undefined ) {
-
-                               attribute.copyVector3sArray( geometry.normals );
-                               attribute.needsUpdate = true;
-
-                       }
-
-                       geometry.normalsNeedUpdate = false;
-
-               }
-
-               if ( geometry.colorsNeedUpdate === true ) {
-
-                       const attribute = this.attributes.color;
-
-                       if ( attribute !== undefined ) {
-
-                               attribute.copyColorsArray( geometry.colors );
-                               attribute.needsUpdate = true;
-
-                       }
-
-                       geometry.colorsNeedUpdate = false;
-
-               }
-
-               if ( geometry.uvsNeedUpdate ) {
-
-                       const attribute = this.attributes.uv;
-
-                       if ( attribute !== undefined ) {
-
-                               attribute.copyVector2sArray( geometry.uvs );
-                               attribute.needsUpdate = true;
-
-                       }
-
-                       geometry.uvsNeedUpdate = false;
-
-               }
-
-               if ( geometry.lineDistancesNeedUpdate ) {
-
-                       const attribute = this.attributes.lineDistance;
-
-                       if ( attribute !== undefined ) {
-
-                               attribute.copyArray( geometry.lineDistances );
-                               attribute.needsUpdate = true;
-
-                       }
-
-                       geometry.lineDistancesNeedUpdate = false;
-
-               }
-
-               if ( geometry.groupsNeedUpdate ) {
-
-                       geometry.computeGroups( object.geometry );
-                       this.groups = geometry.groups;
-
-                       geometry.groupsNeedUpdate = false;
-
-               }
-
-               return this;
-
-       },
-
-       fromGeometry: function ( geometry ) {
-
-               geometry.__directGeometry = new DirectGeometry().fromGeometry( geometry );
-
-               return this.fromDirectGeometry( geometry.__directGeometry );
-
-       },
-
-       fromDirectGeometry: function ( geometry ) {
-
-               const positions = new Float32Array( geometry.vertices.length * 3 );
-               this.setAttribute( 'position', new BufferAttribute( positions, 3 ).copyVector3sArray( geometry.vertices ) );
-
-               if ( geometry.normals.length > 0 ) {
-
-                       const normals = new Float32Array( geometry.normals.length * 3 );
-                       this.setAttribute( 'normal', new BufferAttribute( normals, 3 ).copyVector3sArray( geometry.normals ) );
-
-               }
-
-               if ( geometry.colors.length > 0 ) {
-
-                       const colors = new Float32Array( geometry.colors.length * 3 );
-                       this.setAttribute( 'color', new BufferAttribute( colors, 3 ).copyColorsArray( geometry.colors ) );
-
-               }
-
-               if ( geometry.uvs.length > 0 ) {
-
-                       const uvs = new Float32Array( geometry.uvs.length * 2 );
-                       this.setAttribute( 'uv', new BufferAttribute( uvs, 2 ).copyVector2sArray( geometry.uvs ) );
-
-               }
-
-               if ( geometry.uvs2.length > 0 ) {
-
-                       const uvs2 = new Float32Array( geometry.uvs2.length * 2 );
-                       this.setAttribute( 'uv2', new BufferAttribute( uvs2, 2 ).copyVector2sArray( geometry.uvs2 ) );
-
-               }
-
-               // groups
-
-               this.groups = geometry.groups;
-
-               // morphs
-
-               for ( const name in geometry.morphTargets ) {
-
-                       const array = [];
-                       const morphTargets = geometry.morphTargets[ name ];
-
-                       for ( let i = 0, l = morphTargets.length; i < l; i ++ ) {
-
-                               const morphTarget = morphTargets[ i ];
-
-                               const attribute = new Float32BufferAttribute( morphTarget.data.length * 3, 3 );
-                               attribute.name = morphTarget.name;
-
-                               array.push( attribute.copyVector3sArray( morphTarget.data ) );
-
-                       }
-
-                       this.morphAttributes[ name ] = array;
-
-               }
-
-               // skinning
-
-               if ( geometry.skinIndices.length > 0 ) {
-
-                       const skinIndices = new Float32BufferAttribute( geometry.skinIndices.length * 4, 4 );
-                       this.setAttribute( 'skinIndex', skinIndices.copyVector4sArray( geometry.skinIndices ) );
-
-               }
-
-               if ( geometry.skinWeights.length > 0 ) {
-
-                       const skinWeights = new Float32BufferAttribute( geometry.skinWeights.length * 4, 4 );
-                       this.setAttribute( 'skinWeight', skinWeights.copyVector4sArray( geometry.skinWeights ) );
-
-               }
-
-               //
-
-               if ( geometry.boundingSphere !== null ) {
-
-                       this.boundingSphere = geometry.boundingSphere.clone();
-
-               }
-
-               if ( geometry.boundingBox !== null ) {
-
-                       this.boundingBox = geometry.boundingBox.clone();
-
-               }
-
-               return this;
-
-       },
-
        computeBoundingBox: function () {
 
                if ( this.boundingBox === null ) {
@@ -10507,6 +10008,171 @@ BufferGeometry.prototype = Object.assign( Object.create( EventDispatcher.prototy
 
        },
 
+       computeTangents: function () {
+
+               const index = this.index;
+               const attributes = this.attributes;
+
+               // based on http://www.terathon.com/code/tangent.html
+               // (per vertex tangents)
+
+               if ( index === null ||
+                        attributes.position === undefined ||
+                        attributes.normal === undefined ||
+                        attributes.uv === undefined ) {
+
+                       console.error( 'THREE.BufferGeometry: .computeTangents() failed. Missing required attributes (index, position, normal or uv)' );
+                       return;
+
+               }
+
+               const indices = index.array;
+               const positions = attributes.position.array;
+               const normals = attributes.normal.array;
+               const uvs = attributes.uv.array;
+
+               const nVertices = positions.length / 3;
+
+               if ( attributes.tangent === undefined ) {
+
+                       this.setAttribute( 'tangent', new BufferAttribute( new Float32Array( 4 * nVertices ), 4 ) );
+
+               }
+
+               const tangents = attributes.tangent.array;
+
+               const tan1 = [], tan2 = [];
+
+               for ( let i = 0; i < nVertices; i ++ ) {
+
+                       tan1[ i ] = new Vector3();
+                       tan2[ i ] = new Vector3();
+
+               }
+
+               const vA = new Vector3(),
+                       vB = new Vector3(),
+                       vC = new Vector3(),
+
+                       uvA = new Vector2(),
+                       uvB = new Vector2(),
+                       uvC = new Vector2(),
+
+                       sdir = new Vector3(),
+                       tdir = new Vector3();
+
+               function handleTriangle( a, b, c ) {
+
+                       vA.fromArray( positions, a * 3 );
+                       vB.fromArray( positions, b * 3 );
+                       vC.fromArray( positions, c * 3 );
+
+                       uvA.fromArray( uvs, a * 2 );
+                       uvB.fromArray( uvs, b * 2 );
+                       uvC.fromArray( uvs, c * 2 );
+
+                       vB.sub( vA );
+                       vC.sub( vA );
+
+                       uvB.sub( uvA );
+                       uvC.sub( uvA );
+
+                       const r = 1.0 / ( uvB.x * uvC.y - uvC.x * uvB.y );
+
+                       // silently ignore degenerate uv triangles having coincident or colinear vertices
+
+                       if ( ! isFinite( r ) ) return;
+
+                       sdir.copy( vB ).multiplyScalar( uvC.y ).addScaledVector( vC, - uvB.y ).multiplyScalar( r );
+                       tdir.copy( vC ).multiplyScalar( uvB.x ).addScaledVector( vB, - uvC.x ).multiplyScalar( r );
+
+                       tan1[ a ].add( sdir );
+                       tan1[ b ].add( sdir );
+                       tan1[ c ].add( sdir );
+
+                       tan2[ a ].add( tdir );
+                       tan2[ b ].add( tdir );
+                       tan2[ c ].add( tdir );
+
+               }
+
+               let groups = this.groups;
+
+               if ( groups.length === 0 ) {
+
+                       groups = [ {
+                               start: 0,
+                               count: indices.length
+                       } ];
+
+               }
+
+               for ( let i = 0, il = groups.length; i < il; ++ i ) {
+
+                       const group = groups[ i ];
+
+                       const start = group.start;
+                       const count = group.count;
+
+                       for ( let j = start, jl = start + count; j < jl; j += 3 ) {
+
+                               handleTriangle(
+                                       indices[ j + 0 ],
+                                       indices[ j + 1 ],
+                                       indices[ j + 2 ]
+                               );
+
+                       }
+
+               }
+
+               const tmp = new Vector3(), tmp2 = new Vector3();
+               const n = new Vector3(), n2 = new Vector3();
+
+               function handleVertex( v ) {
+
+                       n.fromArray( normals, v * 3 );
+                       n2.copy( n );
+
+                       const t = tan1[ v ];
+
+                       // Gram-Schmidt orthogonalize
+
+                       tmp.copy( t );
+                       tmp.sub( n.multiplyScalar( n.dot( t ) ) ).normalize();
+
+                       // Calculate handedness
+
+                       tmp2.crossVectors( n2, t );
+                       const test = tmp2.dot( tan2[ v ] );
+                       const w = ( test < 0.0 ) ? - 1.0 : 1.0;
+
+                       tangents[ v * 4 ] = tmp.x;
+                       tangents[ v * 4 + 1 ] = tmp.y;
+                       tangents[ v * 4 + 2 ] = tmp.z;
+                       tangents[ v * 4 + 3 ] = w;
+
+               }
+
+               for ( let i = 0, il = groups.length; i < il; ++ i ) {
+
+                       const group = groups[ i ];
+
+                       const start = group.start;
+                       const count = group.count;
+
+                       for ( let j = start, jl = start + count; j < jl; j += 3 ) {
+
+                               handleVertex( indices[ j + 0 ] );
+                               handleVertex( indices[ j + 1 ] );
+                               handleVertex( indices[ j + 2 ] );
+
+                       }
+
+               }
+
+       },
+
        computeVertexNormals: function () {
 
                const index = this.index;
@@ -10694,7 +10360,7 @@ BufferGeometry.prototype = Object.assign( Object.create( EventDispatcher.prototy
 
                if ( this.index === null ) {
 
-                       console.warn( 'THREE.BufferGeometry.toNonIndexed(): Geometry is already non-indexed.' );
+                       console.warn( 'THREE.BufferGeometry.toNonIndexed(): BufferGeometry is already non-indexed.' );
                        return this;
 
                }
@@ -11041,14 +10707,14 @@ const _uvC = new Vector2();
 const _intersectionPoint = new Vector3();
 const _intersectionPointWorld = new Vector3();
 
-function Mesh( geometry, material ) {
+function Mesh( geometry = new BufferGeometry(), material = new MeshBasicMaterial() ) {
 
        Object3D.call( this );
 
        this.type = 'Mesh';
 
-       this.geometry = geometry !== undefined ? geometry : new BufferGeometry();
-       this.material = material !== undefined ? material : new MeshBasicMaterial();
+       this.geometry = geometry;
+       this.material = material;
 
        this.updateMorphTargets();
 
@@ -11291,48 +10957,7 @@ Mesh.prototype = Object.assign( Object.create( Object3D.prototype ), {
 
                } else if ( geometry.isGeometry ) {
 
-                       const isMultiMaterial = Array.isArray( material );
-
-                       const vertices = geometry.vertices;
-                       const faces = geometry.faces;
-                       let uvs;
-
-                       const faceVertexUvs = geometry.faceVertexUvs[ 0 ];
-                       if ( faceVertexUvs.length > 0 ) uvs = faceVertexUvs;
-
-                       for ( let f = 0, fl = faces.length; f < fl; f ++ ) {
-
-                               const face = faces[ f ];
-                               const faceMaterial = isMultiMaterial ? material[ face.materialIndex ] : material;
-
-                               if ( faceMaterial === undefined ) continue;
-
-                               const fvA = vertices[ face.a ];
-                               const fvB = vertices[ face.b ];
-                               const fvC = vertices[ face.c ];
-
-                               intersection = checkIntersection( this, faceMaterial, raycaster, _ray, fvA, fvB, fvC, _intersectionPoint );
-
-                               if ( intersection ) {
-
-                                       if ( uvs && uvs[ f ] ) {
-
-                                               const uvs_f = uvs[ f ];
-                                               _uvA.copy( uvs_f[ 0 ] );
-                                               _uvB.copy( uvs_f[ 1 ] );
-                                               _uvC.copy( uvs_f[ 2 ] );
-
-                                               intersection.uv = Triangle.getUV( _intersectionPoint, fvA, fvB, fvC, _uvA, _uvB, _uvC, new Vector2() );
-
-                                       }
-
-                                       intersection.face = face;
-                                       intersection.faceIndex = f;
-                                       intersects.push( intersection );
-
-                               }
-
-                       }
+                       console.error( 'THREE.Mesh.raycast() no longer supports THREE.Geometry. Use THREE.BufferGeometry instead.' );
 
                }
 
@@ -11461,13 +11086,13 @@ function checkBufferGeometryIntersection( object, material, raycaster, ray, posi
 
 }
 
-class BoxBufferGeometry extends BufferGeometry {
+class BoxGeometry extends BufferGeometry {
 
        constructor( width = 1, height = 1, depth = 1, widthSegments = 1, heightSegments = 1, depthSegments = 1 ) {
 
                super();
 
-               this.type = 'BoxBufferGeometry';
+               this.type = 'BoxGeometry';
 
                this.parameters = {
                        width: width,
@@ -12027,7 +11652,7 @@ PerspectiveCamera.prototype = Object.assign( Object.create( Camera.prototype ),
         */
        setFocalLength: function ( focalLength ) {
 
-               // see http://www.bobatkins.com/photography/technical/field_of_view.html
+               /** see {@link http://www.bobatkins.com/photography/technical/field_of_view.html} */
                const vExtentSlope = 0.5 * this.getFilmHeight() / focalLength;
 
                this.fov = MathUtils.RAD2DEG * 2 * Math.atan( vExtentSlope );
@@ -12340,137 +11965,138 @@ Object.defineProperty( CubeTexture.prototype, 'images', {
 
 } );
 
-function WebGLCubeRenderTarget( size, options, dummy ) {
+class WebGLCubeRenderTarget extends WebGLRenderTarget {
 
-       if ( Number.isInteger( options ) ) {
+       constructor( size, options, dummy ) {
 
-               console.warn( 'THREE.WebGLCubeRenderTarget: constructor signature is now WebGLCubeRenderTarget( size, options )' );
+               if ( Number.isInteger( options ) ) {
 
-               options = dummy;
+                       console.warn( 'THREE.WebGLCubeRenderTarget: constructor signature is now WebGLCubeRenderTarget( size, options )' );
 
-       }
+                       options = dummy;
 
-       WebGLRenderTarget.call( this, size, size, options );
+               }
 
-       options = options || {};
+               super( size, size, options );
 
-       this.texture = new CubeTexture( undefined, options.mapping, options.wrapS, options.wrapT, options.magFilter, options.minFilter, options.format, options.type, options.anisotropy, options.encoding );
+               Object.defineProperty( this, 'isWebGLCubeRenderTarget', { value: true } );
 
-       this.texture._needsFlipEnvMap = false;
+               options = options || {};
 
-}
+               this.texture = new CubeTexture( undefined, options.mapping, options.wrapS, options.wrapT, options.magFilter, options.minFilter, options.format, options.type, options.anisotropy, options.encoding );
 
-WebGLCubeRenderTarget.prototype = Object.create( WebGLRenderTarget.prototype );
-WebGLCubeRenderTarget.prototype.constructor = WebGLCubeRenderTarget;
+               this.texture._needsFlipEnvMap = false;
 
-WebGLCubeRenderTarget.prototype.isWebGLCubeRenderTarget = true;
+       }
 
-WebGLCubeRenderTarget.prototype.fromEquirectangularTexture = function ( renderer, texture ) {
+       fromEquirectangularTexture( renderer, texture ) {
 
-       this.texture.type = texture.type;
-       this.texture.format = RGBAFormat; // see #18859
-       this.texture.encoding = texture.encoding;
+               this.texture.type = texture.type;
+               this.texture.format = RGBAFormat; // see #18859
+               this.texture.encoding = texture.encoding;
 
-       this.texture.generateMipmaps = texture.generateMipmaps;
-       this.texture.minFilter = texture.minFilter;
-       this.texture.magFilter = texture.magFilter;
+               this.texture.generateMipmaps = texture.generateMipmaps;
+               this.texture.minFilter = texture.minFilter;
+               this.texture.magFilter = texture.magFilter;
 
-       const shader = {
+               const shader = {
 
-               uniforms: {
-                       tEquirect: { value: null },
-               },
+                       uniforms: {
+                               tEquirect: { value: null },
+                       },
 
-               vertexShader: /* glsl */`
+                       vertexShader: /* glsl */`
 
-                       varying vec3 vWorldDirection;
+                               varying vec3 vWorldDirection;
 
-                       vec3 transformDirection( in vec3 dir, in mat4 matrix ) {
+                               vec3 transformDirection( in vec3 dir, in mat4 matrix ) {
 
-                               return normalize( ( matrix * vec4( dir, 0.0 ) ).xyz );
+                                       return normalize( ( matrix * vec4( dir, 0.0 ) ).xyz );
 
-                       }
+                               }
 
-                       void main() {
+                               void main() {
 
-                               vWorldDirection = transformDirection( position, modelMatrix );
+                                       vWorldDirection = transformDirection( position, modelMatrix );
 
-                               #include <begin_vertex>
-                               #include <project_vertex>
+                                       #include <begin_vertex>
+                                       #include <project_vertex>
 
-                       }
-               `,
+                               }
+                       `,
 
-               fragmentShader: /* glsl */`
+                       fragmentShader: /* glsl */`
 
-                       uniform sampler2D tEquirect;
+                               uniform sampler2D tEquirect;
 
-                       varying vec3 vWorldDirection;
+                               varying vec3 vWorldDirection;
 
-                       #include <common>
+                               #include <common>
 
-                       void main() {
+                               void main() {
 
-                               vec3 direction = normalize( vWorldDirection );
+                                       vec3 direction = normalize( vWorldDirection );
 
-                               vec2 sampleUV = equirectUv( direction );
+                                       vec2 sampleUV = equirectUv( direction );
 
-                               gl_FragColor = texture2D( tEquirect, sampleUV );
+                                       gl_FragColor = texture2D( tEquirect, sampleUV );
 
-                       }
-               `
-       };
+                               }
+                       `
+               };
 
-       const geometry = new BoxBufferGeometry( 5, 5, 5 );
+               const geometry = new BoxGeometry( 5, 5, 5 );
 
-       const material = new ShaderMaterial( {
+               const material = new ShaderMaterial( {
 
-               name: 'CubemapFromEquirect',
+                       name: 'CubemapFromEquirect',
 
-               uniforms: cloneUniforms( shader.uniforms ),
-               vertexShader: shader.vertexShader,
-               fragmentShader: shader.fragmentShader,
-               side: BackSide,
-               blending: NoBlending
+                       uniforms: cloneUniforms( shader.uniforms ),
+                       vertexShader: shader.vertexShader,
+                       fragmentShader: shader.fragmentShader,
+                       side: BackSide,
+                       blending: NoBlending
 
-       } );
+               } );
 
-       material.uniforms.tEquirect.value = texture;
+               material.uniforms.tEquirect.value = texture;
 
-       const mesh = new Mesh( geometry, material );
+               const mesh = new Mesh( geometry, material );
 
-       const currentMinFilter = texture.minFilter;
+               const currentMinFilter = texture.minFilter;
 
-       // Avoid blurred poles
-       if ( texture.minFilter === LinearMipmapLinearFilter ) texture.minFilter = LinearFilter;
+               // Avoid blurred poles
+               if ( texture.minFilter === LinearMipmapLinearFilter ) texture.minFilter = LinearFilter;
 
-       const camera = new CubeCamera( 1, 10, this );
-       camera.update( renderer, mesh );
+               const camera = new CubeCamera( 1, 10, this );
+               camera.update( renderer, mesh );
 
-       texture.minFilter = currentMinFilter;
+               texture.minFilter = currentMinFilter;
 
-       mesh.geometry.dispose();
-       mesh.material.dispose();
+               mesh.geometry.dispose();
+               mesh.material.dispose();
 
-       return this;
+               return this;
 
-};
+       }
 
-WebGLCubeRenderTarget.prototype.clear = function ( renderer, color, depth, stencil ) {
+       clear( renderer, color, depth, stencil ) {
 
-       const currentRenderTarget = renderer.getRenderTarget();
+               const currentRenderTarget = renderer.getRenderTarget();
 
-       for ( let i = 0; i < 6; i ++ ) {
+               for ( let i = 0; i < 6; i ++ ) {
 
-               renderer.setRenderTarget( this, i );
+                       renderer.setRenderTarget( this, i );
 
-               renderer.clear( color, depth, stencil );
+                       renderer.clear( color, depth, stencil );
 
-       }
+               }
 
-       renderer.setRenderTarget( currentRenderTarget );
+               renderer.setRenderTarget( currentRenderTarget );
 
-};
+       }
+
+}
 
 function DataTexture( data, width, height, format, type, mapping, wrapS, wrapT, magFilter, minFilter, anisotropy, encoding ) {
 
@@ -12898,12 +12524,12 @@ function WebGLAttributes( gl, capabilities ) {
 
 }
 
-class PlaneBufferGeometry extends BufferGeometry {
+class PlaneGeometry extends BufferGeometry {
 
        constructor( width = 1, height = 1, widthSegments = 1, heightSegments = 1 ) {
 
                super();
-               this.type = 'PlaneBufferGeometry';
+               this.type = 'PlaneGeometry';
 
                this.parameters = {
                        width: width,
@@ -13932,7 +13558,7 @@ function WebGLBackground( renderer, cubemaps, state, objects, premultipliedAlpha
                        if ( boxMesh === undefined ) {
 
                                boxMesh = new Mesh(
-                                       new BoxBufferGeometry( 1, 1, 1 ),
+                                       new BoxGeometry( 1, 1, 1 ),
                                        new ShaderMaterial( {
                                                name: 'BackgroundCubeMaterial',
                                                uniforms: cloneUniforms( ShaderLib.cube.uniforms ),
@@ -14000,7 +13626,7 @@ function WebGLBackground( renderer, cubemaps, state, objects, premultipliedAlpha
                        if ( planeMesh === undefined ) {
 
                                planeMesh = new Mesh(
-                                       new PlaneBufferGeometry( 2, 2 ),
+                                       new PlaneGeometry( 2, 2 ),
                                        new ShaderMaterial( {
                                                name: 'BackgroundMaterial',
                                                uniforms: cloneUniforms( ShaderLib.background.uniforms ),
@@ -15062,7 +14688,6 @@ function WebGLCubeMaps( renderer ) {
 
                                                const currentRenderList = renderer.getRenderList();
                                                const currentRenderTarget = renderer.getRenderTarget();
-                                               const currentRenderState = renderer.getRenderState();
 
                                                const renderTarget = new WebGLCubeRenderTarget( image.height / 2 );
                                                renderTarget.fromEquirectangularTexture( renderer, texture );
@@ -15070,7 +14695,6 @@ function WebGLCubeMaps( renderer ) {
 
                                                renderer.setRenderTarget( currentRenderTarget );
                                                renderer.setRenderList( currentRenderList );
-                                               renderer.setRenderState( currentRenderState );
 
                                                texture.addEventListener( 'dispose', onTextureDispose );
 
@@ -15128,56 +14752,88 @@ function WebGLExtensions( gl ) {
 
        const extensions = {};
 
-       return {
+       function getExtension( name ) {
 
-               has: function ( name ) {
+               if ( extensions[ name ] !== undefined ) {
 
-                       if ( extensions[ name ] !== undefined ) {
+                       return extensions[ name ];
 
-                               return extensions[ name ] !== null;
+               }
 
-                       }
+               let extension;
 
-                       let extension;
+               switch ( name ) {
 
-                       switch ( name ) {
+                       case 'WEBGL_depth_texture':
+                               extension = gl.getExtension( 'WEBGL_depth_texture' ) || gl.getExtension( 'MOZ_WEBGL_depth_texture' ) || gl.getExtension( 'WEBKIT_WEBGL_depth_texture' );
+                               break;
 
-                               case 'WEBGL_depth_texture':
-                                       extension = gl.getExtension( 'WEBGL_depth_texture' ) || gl.getExtension( 'MOZ_WEBGL_depth_texture' ) || gl.getExtension( 'WEBKIT_WEBGL_depth_texture' );
-                                       break;
+                       case 'EXT_texture_filter_anisotropic':
+                               extension = gl.getExtension( 'EXT_texture_filter_anisotropic' ) || gl.getExtension( 'MOZ_EXT_texture_filter_anisotropic' ) || gl.getExtension( 'WEBKIT_EXT_texture_filter_anisotropic' );
+                               break;
 
-                               case 'EXT_texture_filter_anisotropic':
-                                       extension = gl.getExtension( 'EXT_texture_filter_anisotropic' ) || gl.getExtension( 'MOZ_EXT_texture_filter_anisotropic' ) || gl.getExtension( 'WEBKIT_EXT_texture_filter_anisotropic' );
-                                       break;
+                       case 'WEBGL_compressed_texture_s3tc':
+                               extension = gl.getExtension( 'WEBGL_compressed_texture_s3tc' ) || gl.getExtension( 'MOZ_WEBGL_compressed_texture_s3tc' ) || gl.getExtension( 'WEBKIT_WEBGL_compressed_texture_s3tc' );
+                               break;
 
-                               case 'WEBGL_compressed_texture_s3tc':
-                                       extension = gl.getExtension( 'WEBGL_compressed_texture_s3tc' ) || gl.getExtension( 'MOZ_WEBGL_compressed_texture_s3tc' ) || gl.getExtension( 'WEBKIT_WEBGL_compressed_texture_s3tc' );
-                                       break;
+                       case 'WEBGL_compressed_texture_pvrtc':
+                               extension = gl.getExtension( 'WEBGL_compressed_texture_pvrtc' ) || gl.getExtension( 'WEBKIT_WEBGL_compressed_texture_pvrtc' );
+                               break;
 
-                               case 'WEBGL_compressed_texture_pvrtc':
-                                       extension = gl.getExtension( 'WEBGL_compressed_texture_pvrtc' ) || gl.getExtension( 'WEBKIT_WEBGL_compressed_texture_pvrtc' );
-                                       break;
+                       default:
+                               extension = gl.getExtension( name );
 
-                               default:
-                                       extension = gl.getExtension( name );
+               }
 
-                       }
+               extensions[ name ] = extension;
+
+               return extension;
+
+       }
+
+       return {
+
+               has: function ( name ) {
 
-                       extensions[ name ] = extension;
+                       return getExtension( name ) !== null;
 
-                       return extension !== null;
+               },
+
+               init: function ( capabilities ) {
+
+                       if ( capabilities.isWebGL2 ) {
+
+                               getExtension( 'EXT_color_buffer_float' );
+
+                       } else {
+
+                               getExtension( 'WEBGL_depth_texture' );
+                               getExtension( 'OES_texture_float' );
+                               getExtension( 'OES_texture_half_float' );
+                               getExtension( 'OES_texture_half_float_linear' );
+                               getExtension( 'OES_standard_derivatives' );
+                               getExtension( 'OES_element_index_uint' );
+                               getExtension( 'OES_vertex_array_object' );
+                               getExtension( 'ANGLE_instanced_arrays' );
+
+                       }
+
+                       getExtension( 'OES_texture_float_linear' );
+                       getExtension( 'EXT_color_buffer_half_float' );
 
                },
 
                get: function ( name ) {
 
-                       if ( ! this.has( name ) ) {
+                       const extension = getExtension( name );
+
+                       if ( extension === null ) {
 
                                console.warn( 'THREE.WebGLRenderer: ' + name + ' extension not supported.' );
 
                        }
 
-                       return extensions[ name ];
+                       return extension;
 
                }
 
@@ -15187,40 +14843,39 @@ function WebGLExtensions( gl ) {
 
 function WebGLGeometries( gl, attributes, info, bindingStates ) {
 
-       const geometries = new WeakMap();
+       const geometries = {};
        const wireframeAttributes = new WeakMap();
 
        function onGeometryDispose( event ) {
 
                const geometry = event.target;
-               const buffergeometry = geometries.get( geometry );
 
-               if ( buffergeometry.index !== null ) {
+               if ( geometry.index !== null ) {
 
-                       attributes.remove( buffergeometry.index );
+                       attributes.remove( geometry.index );
 
                }
 
-               for ( const name in buffergeometry.attributes ) {
+               for ( const name in geometry.attributes ) {
 
-                       attributes.remove( buffergeometry.attributes[ name ] );
+                       attributes.remove( geometry.attributes[ name ] );
 
                }
 
                geometry.removeEventListener( 'dispose', onGeometryDispose );
 
-               geometries.delete( geometry );
+               delete geometries[ geometry.id ];
 
-               const attribute = wireframeAttributes.get( buffergeometry );
+               const attribute = wireframeAttributes.get( geometry );
 
                if ( attribute ) {
 
                        attributes.remove( attribute );
-                       wireframeAttributes.delete( buffergeometry );
+                       wireframeAttributes.delete( geometry );
 
                }
 
-               bindingStates.releaseStatesOfGeometry( buffergeometry );
+               bindingStates.releaseStatesOfGeometry( geometry );
 
                if ( geometry.isInstancedBufferGeometry === true ) {
 
@@ -15236,33 +14891,15 @@ function WebGLGeometries( gl, attributes, info, bindingStates ) {
 
        function get( object, geometry ) {
 
-               let buffergeometry = geometries.get( geometry );
-
-               if ( buffergeometry ) return buffergeometry;
+               if ( geometries[ geometry.id ] === true ) return geometry;
 
                geometry.addEventListener( 'dispose', onGeometryDispose );
 
-               if ( geometry.isBufferGeometry ) {
-
-                       buffergeometry = geometry;
-
-               } else if ( geometry.isGeometry ) {
-
-                       if ( geometry._bufferGeometry === undefined ) {
-
-                               geometry._bufferGeometry = new BufferGeometry().setFromObject( object );
-
-                       }
-
-                       buffergeometry = geometry._bufferGeometry;
-
-               }
-
-               geometries.set( geometry, buffergeometry );
+               geometries[ geometry.id ] = true;
 
                info.memory.geometries ++;
 
-               return buffergeometry;
+               return geometry;
 
        }
 
@@ -15697,12 +15334,6 @@ function WebGLObjects( gl, geometries, attributes, info ) {
 
                if ( updateMap.get( buffergeometry ) !== frame ) {
 
-                       if ( geometry.isGeometry ) {
-
-                               buffergeometry.updateFromObject( object );
-
-                       }
-
                        geometries.update( buffergeometry );
 
                        updateMap.set( buffergeometry, frame );
@@ -15711,6 +15342,12 @@ function WebGLObjects( gl, geometries, attributes, info ) {
 
                if ( object.isInstancedMesh ) {
 
+                       if ( object.hasEventListener( 'dispose', onInstancedMeshDispose ) === false ) {
+
+                               object.addEventListener( 'dispose', onInstancedMeshDispose );
+
+                       }
+
                        attributes.update( object.instanceMatrix, 34962 );
 
                        if ( object.instanceColor !== null ) {
@@ -15731,6 +15368,18 @@ function WebGLObjects( gl, geometries, attributes, info ) {
 
        }
 
+       function onInstancedMeshDispose( event ) {
+
+               const instancedMesh = event.target;
+
+               instancedMesh.removeEventListener( 'dispose', onInstancedMeshDispose );
+
+               attributes.remove( instancedMesh.instanceMatrix );
+
+               if ( instancedMesh.instanceColor !== null ) attributes.remove( instancedMesh.instanceColor );
+
+       }
+
        return {
 
                update: update,
@@ -16539,7 +16188,7 @@ StructuredUniform.prototype.setValue = function ( gl, value, textures ) {
 
 // Parser - builds up the property tree from the path strings
 
-const RePathPart = /([\w\d_]+)(\])?(\[|\.)?/g;
+const RePathPart = /(\w+)(\])?(\[|\.)?/g;
 
 // extracts
 //     - the identifier (member name or array index)
@@ -16945,19 +16594,19 @@ function loopReplacer( match, start, end, snippet ) {
 
 function generatePrecision( parameters ) {
 
-       let precisionstring = "precision " + parameters.precision + " float;\nprecision " + parameters.precision + " int;";
+       let precisionstring = 'precision ' + parameters.precision + ' float;\nprecision ' + parameters.precision + ' int;';
 
-       if ( parameters.precision === "highp" ) {
+       if ( parameters.precision === 'highp' ) {
 
-               precisionstring += "\n#define HIGH_PRECISION";
+               precisionstring += '\n#define HIGH_PRECISION';
 
-       } else if ( parameters.precision === "mediump" ) {
+       } else if ( parameters.precision === 'mediump' ) {
 
-               precisionstring += "\n#define MEDIUM_PRECISION";
+               precisionstring += '\n#define MEDIUM_PRECISION';
 
-       } else if ( parameters.precision === "lowp" ) {
+       } else if ( parameters.precision === 'lowp' ) {
 
-               precisionstring += "\n#define LOW_PRECISION";
+               precisionstring += '\n#define LOW_PRECISION';
 
        }
 
@@ -17087,7 +16736,7 @@ function WebGLProgram( renderer, cacheKey, parameters, bindingStates ) {
        const program = gl.createProgram();
 
        let prefixVertex, prefixFragment;
-       let versionString = parameters.glslVersion ? '#version ' + parameters.glslVersion + "\n" : '';
+       let versionString = parameters.glslVersion ? '#version ' + parameters.glslVersion + '\n' : '';
 
        if ( parameters.isRawShaderMaterial ) {
 
@@ -17566,19 +17215,19 @@ function WebGLPrograms( renderer, cubemaps, extensions, capabilities, bindingSta
        };
 
        const parameterNames = [
-               "precision", "isWebGL2", "supportsVertexTextures", "outputEncoding", "instancing", "instancingColor",
-               "map", "mapEncoding", "matcap", "matcapEncoding", "envMap", "envMapMode", "envMapEncoding", "envMapCubeUV",
-               "lightMap", "lightMapEncoding", "aoMap", "emissiveMap", "emissiveMapEncoding", "bumpMap", "normalMap", "objectSpaceNormalMap", "tangentSpaceNormalMap", "clearcoatMap", "clearcoatRoughnessMap", "clearcoatNormalMap", "displacementMap", "specularMap",
-               "roughnessMap", "metalnessMap", "gradientMap",
-               "alphaMap", "combine", "vertexColors", "vertexTangents", "vertexUvs", "uvsVertexOnly", "fog", "useFog", "fogExp2",
-               "flatShading", "sizeAttenuation", "logarithmicDepthBuffer", "skinning",
-               "maxBones", "useVertexTexture", "morphTargets", "morphNormals",
-               "maxMorphTargets", "maxMorphNormals", "premultipliedAlpha",
-               "numDirLights", "numPointLights", "numSpotLights", "numHemiLights", "numRectAreaLights",
-               "numDirLightShadows", "numPointLightShadows", "numSpotLightShadows",
-               "shadowMapEnabled", "shadowMapType", "toneMapping", 'physicallyCorrectLights',
-               "alphaTest", "doubleSided", "flipSided", "numClippingPlanes", "numClipIntersection", "depthPacking", "dithering",
-               "sheen", "transmissionMap"
+               'precision', 'isWebGL2', 'supportsVertexTextures', 'outputEncoding', 'instancing', 'instancingColor',
+               'map', 'mapEncoding', 'matcap', 'matcapEncoding', 'envMap', 'envMapMode', 'envMapEncoding', 'envMapCubeUV',
+               'lightMap', 'lightMapEncoding', 'aoMap', 'emissiveMap', 'emissiveMapEncoding', 'bumpMap', 'normalMap', 'objectSpaceNormalMap', 'tangentSpaceNormalMap', 'clearcoatMap', 'clearcoatRoughnessMap', 'clearcoatNormalMap', 'displacementMap', 'specularMap',
+               'roughnessMap', 'metalnessMap', 'gradientMap',
+               'alphaMap', 'combine', 'vertexColors', 'vertexTangents', 'vertexUvs', 'uvsVertexOnly', 'fog', 'useFog', 'fogExp2',
+               'flatShading', 'sizeAttenuation', 'logarithmicDepthBuffer', 'skinning',
+               'maxBones', 'useVertexTexture', 'morphTargets', 'morphNormals',
+               'maxMorphTargets', 'maxMorphNormals', 'premultipliedAlpha',
+               'numDirLights', 'numPointLights', 'numSpotLights', 'numHemiLights', 'numRectAreaLights',
+               'numDirLightShadows', 'numPointLightShadows', 'numSpotLightShadows',
+               'shadowMapEnabled', 'shadowMapType', 'toneMapping', 'physicallyCorrectLights',
+               'alphaTest', 'doubleSided', 'flipSided', 'numClippingPlanes', 'numClipIntersection', 'depthPacking', 'dithering',
+               'sheen', 'transmissionMap'
        ];
 
        function getMaxBones( object ) {
@@ -17621,19 +17270,19 @@ function WebGLPrograms( renderer, cubemaps, extensions, capabilities, bindingSta
 
                let encoding;
 
-               if ( ! map ) {
-
-                       encoding = LinearEncoding;
-
-               } else if ( map.isTexture ) {
+               if ( map && map.isTexture ) {
 
                        encoding = map.encoding;
 
-               } else if ( map.isWebGLRenderTarget ) {
+               } else if ( map && map.isWebGLRenderTarget ) {
 
-                       console.warn( "THREE.WebGLPrograms.getTextureEncodingFromMap: don't use render targets as textures. Use their .texture property instead." );
+                       console.warn( 'THREE.WebGLPrograms.getTextureEncodingFromMap: don\'t use render targets as textures. Use their .texture property instead.' );
                        encoding = map.texture.encoding;
 
+               } else {
+
+                       encoding = LinearEncoding;
+
                }
 
                return encoding;
@@ -18391,7 +18040,7 @@ function WebGLLights( extensions, capabilities ) {
        const matrix4 = new Matrix4();
        const matrix42 = new Matrix4();
 
-       function setup( lights, shadows, camera ) {
+       function setup( lights ) {
 
                let r = 0, g = 0, b = 0;
 
@@ -18407,8 +18056,6 @@ function WebGLLights( extensions, capabilities ) {
                let numPointShadows = 0;
                let numSpotShadows = 0;
 
-               const viewMatrix = camera.matrixWorldInverse;
-
                lights.sort( shadowCastingLightsFirst );
 
                for ( let i = 0, l = lights.length; i < l; i ++ ) {
@@ -18440,10 +18087,6 @@ function WebGLLights( extensions, capabilities ) {
                                const uniforms = cache.get( light );
 
                                uniforms.color.copy( light.color ).multiplyScalar( light.intensity );
-                               uniforms.direction.setFromMatrixPosition( light.matrixWorld );
-                               vector3.setFromMatrixPosition( light.target.matrixWorld );
-                               uniforms.direction.sub( vector3 );
-                               uniforms.direction.transformDirection( viewMatrix );
 
                                if ( light.castShadow ) {
 
@@ -18473,16 +18116,10 @@ function WebGLLights( extensions, capabilities ) {
                                const uniforms = cache.get( light );
 
                                uniforms.position.setFromMatrixPosition( light.matrixWorld );
-                               uniforms.position.applyMatrix4( viewMatrix );
 
                                uniforms.color.copy( color ).multiplyScalar( intensity );
                                uniforms.distance = distance;
 
-                               uniforms.direction.setFromMatrixPosition( light.matrixWorld );
-                               vector3.setFromMatrixPosition( light.target.matrixWorld );
-                               uniforms.direction.sub( vector3 );
-                               uniforms.direction.transformDirection( viewMatrix );
-
                                uniforms.coneCos = Math.cos( light.angle );
                                uniforms.penumbraCos = Math.cos( light.angle * ( 1 - light.penumbra ) );
                                uniforms.decay = light.decay;
@@ -18520,24 +18157,9 @@ function WebGLLights( extensions, capabilities ) {
                                // (b) intensity is the brightness of the light
                                uniforms.color.copy( color ).multiplyScalar( intensity );
 
-                               uniforms.position.setFromMatrixPosition( light.matrixWorld );
-                               uniforms.position.applyMatrix4( viewMatrix );
-
-                               // extract local rotation of light to derive width/height half vectors
-                               matrix42.identity();
-                               matrix4.copy( light.matrixWorld );
-                               matrix4.premultiply( viewMatrix );
-                               matrix42.extractRotation( matrix4 );
-
                                uniforms.halfWidth.set( light.width * 0.5, 0.0, 0.0 );
                                uniforms.halfHeight.set( 0.0, light.height * 0.5, 0.0 );
 
-                               uniforms.halfWidth.applyMatrix4( matrix42 );
-                               uniforms.halfHeight.applyMatrix4( matrix42 );
-
-                               // TODO (abelnation): RectAreaLight distance?
-                               // uniforms.distance = distance;
-
                                state.rectArea[ rectAreaLength ] = uniforms;
 
                                rectAreaLength ++;
@@ -18546,9 +18168,6 @@ function WebGLLights( extensions, capabilities ) {
 
                                const uniforms = cache.get( light );
 
-                               uniforms.position.setFromMatrixPosition( light.matrixWorld );
-                               uniforms.position.applyMatrix4( viewMatrix );
-
                                uniforms.color.copy( light.color ).multiplyScalar( light.intensity );
                                uniforms.distance = light.distance;
                                uniforms.decay = light.decay;
@@ -18582,10 +18201,6 @@ function WebGLLights( extensions, capabilities ) {
 
                                const uniforms = cache.get( light );
 
-                               uniforms.direction.setFromMatrixPosition( light.matrixWorld );
-                               uniforms.direction.transformDirection( viewMatrix );
-                               uniforms.direction.normalize();
-
                                uniforms.skyColor.copy( light.color ).multiplyScalar( intensity );
                                uniforms.groundColor.copy( light.groundColor ).multiplyScalar( intensity );
 
@@ -18677,8 +18292,94 @@ function WebGLLights( extensions, capabilities ) {
 
        }
 
+       function setupView( lights, camera ) {
+
+               let directionalLength = 0;
+               let pointLength = 0;
+               let spotLength = 0;
+               let rectAreaLength = 0;
+               let hemiLength = 0;
+
+               const viewMatrix = camera.matrixWorldInverse;
+
+               for ( let i = 0, l = lights.length; i < l; i ++ ) {
+
+                       const light = lights[ i ];
+
+                       if ( light.isDirectionalLight ) {
+
+                               const uniforms = state.directional[ directionalLength ];
+
+                               uniforms.direction.setFromMatrixPosition( light.matrixWorld );
+                               vector3.setFromMatrixPosition( light.target.matrixWorld );
+                               uniforms.direction.sub( vector3 );
+                               uniforms.direction.transformDirection( viewMatrix );
+
+                               directionalLength ++;
+
+                       } else if ( light.isSpotLight ) {
+
+                               const uniforms = state.spot[ spotLength ];
+
+                               uniforms.position.setFromMatrixPosition( light.matrixWorld );
+                               uniforms.position.applyMatrix4( viewMatrix );
+
+                               uniforms.direction.setFromMatrixPosition( light.matrixWorld );
+                               vector3.setFromMatrixPosition( light.target.matrixWorld );
+                               uniforms.direction.sub( vector3 );
+                               uniforms.direction.transformDirection( viewMatrix );
+
+                               spotLength ++;
+
+                       } else if ( light.isRectAreaLight ) {
+
+                               const uniforms = state.rectArea[ rectAreaLength ];
+
+                               uniforms.position.setFromMatrixPosition( light.matrixWorld );
+                               uniforms.position.applyMatrix4( viewMatrix );
+
+                               // extract local rotation of light to derive width/height half vectors
+                               matrix42.identity();
+                               matrix4.copy( light.matrixWorld );
+                               matrix4.premultiply( viewMatrix );
+                               matrix42.extractRotation( matrix4 );
+
+                               uniforms.halfWidth.set( light.width * 0.5, 0.0, 0.0 );
+                               uniforms.halfHeight.set( 0.0, light.height * 0.5, 0.0 );
+
+                               uniforms.halfWidth.applyMatrix4( matrix42 );
+                               uniforms.halfHeight.applyMatrix4( matrix42 );
+
+                               rectAreaLength ++;
+
+                       } else if ( light.isPointLight ) {
+
+                               const uniforms = state.point[ pointLength ];
+
+                               uniforms.position.setFromMatrixPosition( light.matrixWorld );
+                               uniforms.position.applyMatrix4( viewMatrix );
+
+                               pointLength ++;
+
+                       } else if ( light.isHemisphereLight ) {
+
+                               const uniforms = state.hemi[ hemiLength ];
+
+                               uniforms.direction.setFromMatrixPosition( light.matrixWorld );
+                               uniforms.direction.transformDirection( viewMatrix );
+                               uniforms.direction.normalize();
+
+                               hemiLength ++;
+
+                       }
+
+               }
+
+       }
+
        return {
                setup: setup,
+               setupView: setupView,
                state: state
        };
 
@@ -18710,9 +18411,15 @@ function WebGLRenderState( extensions, capabilities ) {
 
        }
 
-       function setupLights( camera ) {
+       function setupLights() {
 
-               lights.setup( lightsArray, shadowsArray, camera );
+               lights.setup( lightsArray );
+
+       }
+
+       function setupLightsView( camera ) {
+
+               lights.setupView( lightsArray, camera );
 
        }
 
@@ -18727,6 +18434,7 @@ function WebGLRenderState( extensions, capabilities ) {
                init: init,
                state: state,
                setupLights: setupLights,
+               setupLightsView: setupLightsView,
 
                pushLight: pushLight,
                pushShadow: pushShadow
@@ -18738,26 +18446,26 @@ function WebGLRenderStates( extensions, capabilities ) {
 
        let renderStates = new WeakMap();
 
-       function get( scene, camera ) {
+       function get( scene, renderCallDepth = 0 ) {
 
                let renderState;
 
                if ( renderStates.has( scene ) === false ) {
 
                        renderState = new WebGLRenderState( extensions, capabilities );
-                       renderStates.set( scene, new WeakMap() );
-                       renderStates.get( scene ).set( camera, renderState );
+                       renderStates.set( scene, [] );
+                       renderStates.get( scene ).push( renderState );
 
                } else {
 
-                       if ( renderStates.get( scene ).has( camera ) === false ) {
+                       if ( renderCallDepth >= renderStates.get( scene ).length ) {
 
                                renderState = new WebGLRenderState( extensions, capabilities );
-                               renderStates.get( scene ).set( camera, renderState );
+                               renderStates.get( scene ).push( renderState );
 
                        } else {
 
-                               renderState = renderStates.get( scene ).get( camera );
+                               renderState = renderStates.get( scene )[ renderCallDepth ];
 
                        }
 
@@ -18931,7 +18639,7 @@ MeshDistanceMaterial.prototype.copy = function ( source ) {
 
 };
 
-var vsm_frag = "uniform sampler2D shadow_pass;\nuniform vec2 resolution;\nuniform float radius;\n#include <packing>\nvoid main() {\n\tfloat mean = 0.0;\n\tfloat squared_mean = 0.0;\n\tfloat depth = unpackRGBAToDepth( texture2D( shadow_pass, ( gl_FragCoord.xy ) / resolution ) );\n\tfor ( float i = -1.0; i < 1.0 ; i += SAMPLE_RATE) {\n\t\t#ifdef HORIZONAL_PASS\n\t\t\tvec2 distribution = unpackRGBATo2Half( texture2D( shadow_pass, ( gl_FragCoord.xy + vec2( i, 0.0 ) * radius ) / resolution ) );\n\t\t\tmean += distribution.x;\n\t\t\tsquared_mean += distribution.y * distribution.y + distribution.x * distribution.x;\n\t\t#else\n\t\t\tfloat depth = unpackRGBAToDepth( texture2D( shadow_pass, ( gl_FragCoord.xy + vec2( 0.0, i ) * radius ) / resolution ) );\n\t\t\tmean += depth;\n\t\t\tsquared_mean += depth * depth;\n\t\t#endif\n\t}\n\tmean = mean * HALF_SAMPLE_RATE;\n\tsquared_mean = squared_mean * HALF_SAMPLE_RATE;\n\tfloat std_dev = sqrt( squared_mean - mean * mean );\n\tgl_FragColor = pack2HalfToRGBA( vec2( mean, std_dev ) );\n}";
+var vsm_frag = "uniform sampler2D shadow_pass;\nuniform vec2 resolution;\nuniform float radius;\n#include <packing>\nvoid main() {\n\tfloat mean = 0.0;\n\tfloat squared_mean = 0.0;\n\tfloat depth = unpackRGBAToDepth( texture2D( shadow_pass, ( gl_FragCoord.xy ) / resolution ) );\n\tfor ( float i = -1.0; i < 1.0 ; i += SAMPLE_RATE) {\n\t\t#ifdef HORIZONTAL_PASS\n\t\t\tvec2 distribution = unpackRGBATo2Half( texture2D( shadow_pass, ( gl_FragCoord.xy + vec2( i, 0.0 ) * radius ) / resolution ) );\n\t\t\tmean += distribution.x;\n\t\t\tsquared_mean += distribution.y * distribution.y + distribution.x * distribution.x;\n\t\t#else\n\t\t\tfloat depth = unpackRGBAToDepth( texture2D( shadow_pass, ( gl_FragCoord.xy + vec2( 0.0, i ) * radius ) / resolution ) );\n\t\t\tmean += depth;\n\t\t\tsquared_mean += depth * depth;\n\t\t#endif\n\t}\n\tmean = mean * HALF_SAMPLE_RATE;\n\tsquared_mean = squared_mean * HALF_SAMPLE_RATE;\n\tfloat std_dev = sqrt( squared_mean - mean * mean );\n\tgl_FragColor = pack2HalfToRGBA( vec2( mean, std_dev ) );\n}";
 
 var vsm_vert = "void main() {\n\tgl_Position = vec4( position, 1.0 );\n}";
 
@@ -18970,12 +18678,12 @@ function WebGLShadowMap( _renderer, _objects, maxTextureSize ) {
 
        } );
 
-       const shadowMaterialHorizonal = shadowMaterialVertical.clone();
-       shadowMaterialHorizonal.defines.HORIZONAL_PASS = 1;
+       const shadowMaterialHorizontal = shadowMaterialVertical.clone();
+       shadowMaterialHorizontal.defines.HORIZONTAL_PASS = 1;
 
        const fullScreenTri = new BufferGeometry();
        fullScreenTri.setAttribute(
-               "position",
+               'position',
                new BufferAttribute(
                        new Float32Array( [ - 1, - 1, 0.5, 3, - 1, 0.5, - 1, 3, 0.5 ] ),
                        3
@@ -19061,7 +18769,7 @@ function WebGLShadowMap( _renderer, _objects, maxTextureSize ) {
                                const pars = { minFilter: LinearFilter, magFilter: LinearFilter, format: RGBAFormat };
 
                                shadow.map = new WebGLRenderTarget( _shadowMapSize.x, _shadowMapSize.y, pars );
-                               shadow.map.texture.name = light.name + ".shadowMap";
+                               shadow.map.texture.name = light.name + '.shadowMap';
 
                                shadow.mapPass = new WebGLRenderTarget( _shadowMapSize.x, _shadowMapSize.y, pars );
 
@@ -19074,7 +18782,7 @@ function WebGLShadowMap( _renderer, _objects, maxTextureSize ) {
                                const pars = { minFilter: NearestFilter, magFilter: NearestFilter, format: RGBAFormat };
 
                                shadow.map = new WebGLRenderTarget( _shadowMapSize.x, _shadowMapSize.y, pars );
-                               shadow.map.texture.name = light.name + ".shadowMap";
+                               shadow.map.texture.name = light.name + '.shadowMap';
 
                                shadow.camera.updateProjectionMatrix();
 
@@ -19137,14 +18845,14 @@ function WebGLShadowMap( _renderer, _objects, maxTextureSize ) {
                _renderer.clear();
                _renderer.renderBufferDirect( camera, null, geometry, shadowMaterialVertical, fullScreenMesh, null );
 
-               // horizonal pass
+               // horizontal pass
 
-               shadowMaterialHorizonal.uniforms.shadow_pass.value = shadow.mapPass.texture;
-               shadowMaterialHorizonal.uniforms.resolution.value = shadow.mapSize;
-               shadowMaterialHorizonal.uniforms.radius.value = shadow.radius;
+               shadowMaterialHorizontal.uniforms.shadow_pass.value = shadow.mapPass.texture;
+               shadowMaterialHorizontal.uniforms.resolution.value = shadow.mapSize;
+               shadowMaterialHorizontal.uniforms.radius.value = shadow.radius;
                _renderer.setRenderTarget( shadow.map );
                _renderer.clear();
-               _renderer.renderBufferDirect( camera, null, geometry, shadowMaterialHorizonal, fullScreenMesh, null );
+               _renderer.renderBufferDirect( camera, null, geometry, shadowMaterialHorizontal, fullScreenMesh, null );
 
        }
 
@@ -19710,12 +19418,12 @@ function WebGLState( gl, extensions, capabilities ) {
 
        if ( glVersion.indexOf( 'WebGL' ) !== - 1 ) {
 
-               version = parseFloat( /^WebGL\ ([0-9])/.exec( glVersion )[ 1 ] );
+               version = parseFloat( /^WebGL (\d)/.exec( glVersion )[ 1 ] );
                lineWidthAvailable = ( version >= 1.0 );
 
        } else if ( glVersion.indexOf( 'OpenGL ES' ) !== - 1 ) {
 
-               version = parseFloat( /^OpenGL\ ES\ ([0-9])/.exec( glVersion )[ 1 ] );
+               version = parseFloat( /^OpenGL ES (\d)/.exec( glVersion )[ 1 ] );
                lineWidthAvailable = ( version >= 2.0 );
 
        }
@@ -20334,7 +20042,7 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils,
        try {
 
                useOffscreenCanvas = typeof OffscreenCanvas !== 'undefined'
-                       && ( new OffscreenCanvas( 1, 1 ).getContext( "2d" ) ) !== null;
+                       && ( new OffscreenCanvas( 1, 1 ).getContext( '2d' ) ) !== null;
 
        } catch ( err ) {
 
@@ -21022,6 +20730,8 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils,
                state.bindTexture( 34067, textureProperties.__webglTexture );
 
                _gl.pixelStorei( 37440, texture.flipY );
+               _gl.pixelStorei( 37441, texture.premultiplyAlpha );
+               _gl.pixelStorei( 3317, texture.unpackAlignment );
 
                const isCompressed = ( texture && ( texture.isCompressedTexture || texture.image[ 0 ].isCompressedTexture ) );
                const isDataTexture = ( texture.image[ 0 ] && texture.image[ 0 ].isDataTexture );
@@ -21530,7 +21240,7 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils,
 
                        if ( warnedTexture2D === false ) {
 
-                               console.warn( "THREE.WebGLTextures.safeSetTexture2D: don't use render targets as textures. Use their .texture property instead." );
+                               console.warn( 'THREE.WebGLTextures.safeSetTexture2D: don\'t use render targets as textures. Use their .texture property instead.' );
                                warnedTexture2D = true;
 
                        }
@@ -21549,7 +21259,7 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils,
 
                        if ( warnedTextureCube === false ) {
 
-                               console.warn( "THREE.WebGLTextures.safeSetTextureCube: don't use cube render targets as textures. Use their .texture property instead." );
+                               console.warn( 'THREE.WebGLTextures.safeSetTextureCube: don\'t use cube render targets as textures. Use their .texture property instead.' );
                                warnedTextureCube = true;
 
                        }
@@ -21826,25 +21536,9 @@ Object.assign( WebXRController.prototype, {
                        this._hand.matrixAutoUpdate = false;
                        this._hand.visible = false;
 
-                       this._hand.joints = [];
+                       this._hand.joints = {};
                        this._hand.inputState = { pinching: false };
 
-                       if ( window.XRHand ) {
-
-                               for ( let i = 0; i <= window.XRHand.LITTLE_PHALANX_TIP; i ++ ) {
-
-                                       // The transform of this joint will be updated with the joint pose on each frame
-                                       const joint = new Group();
-                                       joint.matrixAutoUpdate = false;
-                                       joint.visible = false;
-                                       this._hand.joints.push( joint );
-                                       // ??
-                                       this._hand.add( joint );
-
-                               }
-
-                       }
-
                }
 
                return this._hand;
@@ -21945,55 +21639,64 @@ Object.assign( WebXRController.prototype, {
 
                                handPose = true;
 
-                               for ( let i = 0; i <= window.XRHand.LITTLE_PHALANX_TIP; i ++ ) {
+                               for ( const inputjoint of inputSource.hand.values() ) {
+
+                                       // Update the joints groups with the XRJoint poses
+                                       const jointPose = frame.getJointPose( inputjoint, referenceSpace );
 
-                                       if ( inputSource.hand[ i ] ) {
+                                       if ( hand.joints[ inputjoint.jointName ] === undefined ) {
 
-                                               // Update the joints groups with the XRJoint poses
-                                               const jointPose = frame.getJointPose( inputSource.hand[ i ], referenceSpace );
-                                               const joint = hand.joints[ i ];
+                                               // The transform of this joint will be updated with the joint pose on each frame
+                                               const joint = new Group();
+                                               joint.matrixAutoUpdate = false;
+                                               joint.visible = false;
+                                               hand.joints[ inputjoint.jointName ] = joint;
+                                               // ??
+                                               hand.add( joint );
 
-                                               if ( jointPose !== null ) {
+                                       }
 
-                                                       joint.matrix.fromArray( jointPose.transform.matrix );
-                                                       joint.matrix.decompose( joint.position, joint.rotation, joint.scale );
-                                                       joint.jointRadius = jointPose.radius;
+                                       const joint = hand.joints[ inputjoint.jointName ];
 
-                                               }
+                                       if ( jointPose !== null ) {
+
+                                               joint.matrix.fromArray( jointPose.transform.matrix );
+                                               joint.matrix.decompose( joint.position, joint.rotation, joint.scale );
+                                               joint.jointRadius = jointPose.radius;
 
-                                               joint.visible = jointPose !== null;
+                                       }
 
-                                               // Custom events
+                                       joint.visible = jointPose !== null;
 
-                                               // Check pinch
-                                               const indexTip = hand.joints[ window.XRHand.INDEX_PHALANX_TIP ];
-                                               const thumbTip = hand.joints[ window.XRHand.THUMB_PHALANX_TIP ];
-                                               const distance = indexTip.position.distanceTo( thumbTip.position );
+                               }
 
-                                               const distanceToPinch = 0.02;
-                                               const threshold = 0.005;
+                               // Custom events
 
-                                               if ( hand.inputState.pinching && distance > distanceToPinch + threshold ) {
+                               // Check pinchz
+                               const indexTip = hand.joints[ 'index-finger-tip' ];
+                               const thumbTip = hand.joints[ 'thumb-tip' ];
+                               const distance = indexTip.position.distanceTo( thumbTip.position );
 
-                                                       hand.inputState.pinching = false;
-                                                       this.dispatchEvent( {
-                                                               type: "pinchend",
-                                                               handedness: inputSource.handedness,
-                                                               target: this
-                                                       } );
+                               const distanceToPinch = 0.02;
+                               const threshold = 0.005;
 
-                                               } else if ( ! hand.inputState.pinching && distance <= distanceToPinch - threshold ) {
+                               if ( hand.inputState.pinching && distance > distanceToPinch + threshold ) {
 
-                                                       hand.inputState.pinching = true;
-                                                       this.dispatchEvent( {
-                                                               type: "pinchstart",
-                                                               handedness: inputSource.handedness,
-                                                               target: this
-                                                       } );
+                                       hand.inputState.pinching = false;
+                                       this.dispatchEvent( {
+                                               type: 'pinchend',
+                                               handedness: inputSource.handedness,
+                                               target: this
+                                       } );
 
-                                               }
+                               } else if ( ! hand.inputState.pinching && distance <= distanceToPinch - threshold ) {
 
-                                       }
+                                       hand.inputState.pinching = true;
+                                       this.dispatchEvent( {
+                                               type: 'pinchstart',
+                                               handedness: inputSource.handedness,
+                                               target: this
+                                       } );
 
                                }
 
@@ -22163,6 +21866,9 @@ function WebXRManager( renderer, gl ) {
 
                inputSourcesMap.clear();
 
+               _currentDepthNear = null;
+               _currentDepthFar = null;
+
                //
 
                renderer.setFramebuffer( null );
@@ -22175,19 +21881,6 @@ function WebXRManager( renderer, gl ) {
 
        }
 
-       function onRequestReferenceSpace( value ) {
-
-               referenceSpace = value;
-
-               animation.setContext( session );
-               animation.start();
-
-               scope.isPresenting = true;
-
-               scope.dispatchEvent( { type: 'sessionstart' } );
-
-       }
-
        this.setFramebufferScaleFactor = function ( value ) {
 
                framebufferScaleFactor = value;
@@ -22224,7 +21917,7 @@ function WebXRManager( renderer, gl ) {
 
        };
 
-       this.setSession = function ( value ) {
+       this.setSession = async function ( value ) {
 
                session = value;
 
@@ -22237,12 +21930,13 @@ function WebXRManager( renderer, gl ) {
                        session.addEventListener( 'squeezestart', onSessionEvent );
                        session.addEventListener( 'squeezeend', onSessionEvent );
                        session.addEventListener( 'end', onSessionEnd );
+                       session.addEventListener( 'inputsourceschange', onInputSourcesChange );
 
                        const attributes = gl.getContextAttributes();
 
                        if ( attributes.xrCompatible !== true ) {
 
-                               gl.makeXRCompatible();
+                               await gl.makeXRCompatible();
 
                        }
 
@@ -22259,17 +21953,20 @@ function WebXRManager( renderer, gl ) {
 
                        session.updateRenderState( { baseLayer: baseLayer } );
 
-                       session.requestReferenceSpace( referenceSpaceType ).then( onRequestReferenceSpace );
+                       referenceSpace = await session.requestReferenceSpace( referenceSpaceType );
 
-                       //
+                       animation.setContext( session );
+                       animation.start();
 
-                       session.addEventListener( 'inputsourceschange', updateInputSources );
+                       scope.isPresenting = true;
+
+                       scope.dispatchEvent( { type: 'sessionstart' } );
 
                }
 
        };
 
-       function updateInputSources( event ) {
+       function onInputSourcesChange( event ) {
 
                const inputSources = session.inputSources;
 
@@ -22423,6 +22120,8 @@ function WebXRManager( renderer, gl ) {
                // update camera and its children
 
                camera.matrixWorld.copy( cameraVR.matrixWorld );
+               camera.matrix.copy( cameraVR.matrix );
+               camera.matrix.decompose( camera.position, camera.quaternion, camera.scale );
 
                const children = camera.children;
 
@@ -23256,6 +22955,11 @@ function WebGLRenderer( parameters ) {
        let currentRenderList = null;
        let currentRenderState = null;
 
+       // render() can be called from within a callback triggered by another render.
+       // We track this so that the nested render call gets its state isolated from the parent render call.
+
+       const renderStateStack = [];
+
        // public properties
 
        this.domElement = _canvas;
@@ -23322,7 +23026,6 @@ function WebGLRenderer( parameters ) {
        let _currentMaterialId = - 1;
 
        let _currentCamera = null;
-       let _currentArrayCamera = null;
 
        const _currentViewport = new Vector4();
        const _currentScissor = new Vector4();
@@ -23461,20 +23164,7 @@ function WebGLRenderer( parameters ) {
 
                capabilities = new WebGLCapabilities( _gl, extensions, parameters );
 
-               if ( capabilities.isWebGL2 === false ) {
-
-                       extensions.get( 'WEBGL_depth_texture' );
-                       extensions.get( 'OES_texture_float' );
-                       extensions.get( 'OES_texture_half_float' );
-                       extensions.get( 'OES_texture_half_float_linear' );
-                       extensions.get( 'OES_standard_derivatives' );
-                       extensions.get( 'OES_element_index_uint' );
-                       extensions.get( 'OES_vertex_array_object' );
-                       extensions.get( 'ANGLE_instanced_arrays' );
-
-               }
-
-               extensions.get( 'OES_texture_float_linear' );
+               extensions.init( capabilities );
 
                utils = new WebGLUtils( _gl, extensions, capabilities );
 
@@ -23722,9 +23412,17 @@ function WebGLRenderer( parameters ) {
 
        // Clearing
 
-       this.getClearColor = function () {
+       this.getClearColor = function ( target ) {
+
+               if ( target === undefined ) {
+
+                       console.warn( 'WebGLRenderer: .getClearColor() now requires a Color as an argument' );
+
+                       target = new Color();
+
+               }
 
-               return background.getClearColor();
+               return target.copy( background.getClearColor() );
 
        };
 
@@ -24068,7 +23766,7 @@ function WebGLRenderer( parameters ) {
 
        this.compile = function ( scene, camera ) {
 
-               currentRenderState = renderStates.get( scene, camera );
+               currentRenderState = renderStates.get( scene );
                currentRenderState.init();
 
                scene.traverseVisible( function ( object ) {
@@ -24087,7 +23785,7 @@ function WebGLRenderer( parameters ) {
 
                } );
 
-               currentRenderState.setupLights( camera );
+               currentRenderState.setupLights();
 
                const compiled = new WeakMap();
 
@@ -24202,9 +23900,11 @@ function WebGLRenderer( parameters ) {
                //
                if ( scene.isScene === true ) scene.onBeforeRender( _this, scene, camera, renderTarget || _currentRenderTarget );
 
-               currentRenderState = renderStates.get( scene, camera );
+               currentRenderState = renderStates.get( scene, renderStateStack.length );
                currentRenderState.init();
 
+               renderStateStack.push( currentRenderState );
+
                _projScreenMatrix.multiplyMatrices( camera.projectionMatrix, camera.matrixWorldInverse );
                _frustum.setFromProjectionMatrix( _projScreenMatrix );
 
@@ -24232,7 +23932,8 @@ function WebGLRenderer( parameters ) {
 
                shadowMap.render( shadowsArray, scene, camera );
 
-               currentRenderState.setupLights( camera );
+               currentRenderState.setupLights();
+               currentRenderState.setupLightsView( camera );
 
                if ( _clippingEnabled === true ) clipping.endShadows();
 
@@ -24286,8 +23987,18 @@ function WebGLRenderer( parameters ) {
 
                // _gl.finish();
 
+               renderStateStack.pop();
+               if ( renderStateStack.length > 0 ) {
+
+                       currentRenderState = renderStateStack[ renderStateStack.length - 1 ];
+
+               } else {
+
+                       currentRenderState = null;
+
+               }
+
                currentRenderList = null;
-               currentRenderState = null;
 
        };
 
@@ -24431,8 +24142,6 @@ function WebGLRenderer( parameters ) {
 
                        if ( camera.isArrayCamera ) {
 
-                               _currentArrayCamera = camera;
-
                                const cameras = camera.cameras;
 
                                for ( let j = 0, jl = cameras.length; j < jl; j ++ ) {
@@ -24443,7 +24152,7 @@ function WebGLRenderer( parameters ) {
 
                                                state.viewport( _currentViewport.copy( camera2.viewport ) );
 
-                                               currentRenderState.setupLights( camera2 );
+                                               currentRenderState.setupLightsView( camera2 );
 
                                                renderObject( object, scene, camera2, geometry, material, group );
 
@@ -24453,8 +24162,6 @@ function WebGLRenderer( parameters ) {
 
                        } else {
 
-                               _currentArrayCamera = null;
-
                                renderObject( object, scene, camera, geometry, material, group );
 
                        }
@@ -24466,7 +24173,6 @@ function WebGLRenderer( parameters ) {
        function renderObject( object, scene, camera, geometry, material, group ) {
 
                object.onBeforeRender( _this, scene, camera, geometry, material, group );
-               currentRenderState = renderStates.get( scene, _currentArrayCamera || camera );
 
                object.modelViewMatrix.multiplyMatrices( camera.matrixWorldInverse, object.matrixWorld );
                object.normalMatrix.getNormalMatrix( object.modelViewMatrix );
@@ -24488,7 +24194,6 @@ function WebGLRenderer( parameters ) {
                }
 
                object.onAfterRender( _this, scene, camera, geometry, material, group );
-               currentRenderState = renderStates.get( scene, _currentArrayCamera || camera );
 
        }
 
@@ -24509,6 +24214,12 @@ function WebGLRenderer( parameters ) {
                let program = materialProperties.program;
                let programChange = true;
 
+               // always update environment and fog - changing these trigger an initMaterial call, but it's possible that the program doesn't change
+
+               materialProperties.environment = material.isMeshStandardMaterial ? scene.environment : null;
+               materialProperties.fog = scene.fog;
+               materialProperties.envMap = cubemaps.get( material.envMap || materialProperties.environment );
+
                if ( program === undefined ) {
 
                        // new material
@@ -24525,11 +24236,7 @@ function WebGLRenderer( parameters ) {
 
                } else if ( parameters.shaderID !== undefined ) {
 
-                       // same glsl and uniform list, envMap still needs the update here to avoid a frame-late effect
-
-                       const environment = material.isMeshStandardMaterial ? scene.environment : null;
-                       materialProperties.envMap = cubemaps.get( material.envMap || environment );
-
+                       // same glsl and uniform list
                        return;
 
                } else {
@@ -24565,10 +24272,6 @@ function WebGLRenderer( parameters ) {
 
                }
 
-               materialProperties.environment = material.isMeshStandardMaterial ? scene.environment : null;
-               materialProperties.fog = scene.fog;
-               materialProperties.envMap = cubemaps.get( material.envMap || materialProperties.environment );
-
                // store the light setup it was created for
 
                materialProperties.needsLights = materialNeedsLights( material );
@@ -24947,18 +24650,6 @@ function WebGLRenderer( parameters ) {
 
        };
 
-       this.getRenderState = function () {
-
-               return currentRenderState;
-
-       };
-
-       this.setRenderState = function ( renderState ) {
-
-               currentRenderState = renderState;
-
-       };
-
        this.getRenderTarget = function () {
 
                return _currentRenderTarget;
@@ -25073,9 +24764,11 @@ function WebGLRenderer( parameters ) {
 
                                }
 
+                               const halfFloatSupportedByExt = ( textureType === HalfFloatType ) && ( extensions.has( 'EXT_color_buffer_half_float' ) || ( capabilities.isWebGL2 && extensions.has( 'EXT_color_buffer_float' ) ) );
+
                                if ( textureType !== UnsignedByteType && utils.convert( textureType ) !== _gl.getParameter( 35738 ) && // IE11, Edge and Chrome Mac < 52 (#9513)
-                                       ! ( textureType === FloatType && ( capabilities.isWebGL2 || extensions.get( 'OES_texture_float' ) || extensions.get( 'WEBGL_color_buffer_float' ) ) ) && // Chrome Mac >= 52 and Firefox
-                                       ! ( textureType === HalfFloatType && ( capabilities.isWebGL2 ? extensions.get( 'EXT_color_buffer_float' ) : extensions.get( 'EXT_color_buffer_half_float' ) ) ) ) {
+                                       ! ( textureType === FloatType && ( capabilities.isWebGL2 || extensions.has( 'OES_texture_float' ) || extensions.has( 'WEBGL_color_buffer_float' ) ) ) && // Chrome Mac >= 52 and Firefox
+                                       ! halfFloatSupportedByExt ) {
 
                                        console.error( 'THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not in UnsignedByteType or implementation defined type.' );
                                        return;
@@ -25175,6 +24868,13 @@ function WebGLRenderer( parameters ) {
 
        };
 
+       this.resetState = function () {
+
+               state.reset();
+               bindingStates.reset();
+
+       };
+
        if ( typeof __THREE_DEVTOOLS__ !== 'undefined' ) {
 
                __THREE_DEVTOOLS__.dispatchEvent( new CustomEvent( 'observe', { detail: this } ) ); // eslint-disable-line no-undef
@@ -26144,6 +25844,14 @@ LOD.prototype = Object.assign( Object.create( Object3D.prototype ), {
 
 } );
 
+const _basePosition = new Vector3();
+
+const _skinIndex = new Vector4();
+const _skinWeight = new Vector4();
+
+const _vector$7 = new Vector3();
+const _matrix$1 = new Matrix4();
+
 function SkinnedMesh( geometry, material ) {
 
        if ( geometry && geometry.isGeometry ) {
@@ -26258,49 +25966,37 @@ SkinnedMesh.prototype = Object.assign( Object.create( Mesh.prototype ), {
 
        },
 
-       boneTransform: ( function () {
-
-               const basePosition = new Vector3();
+       boneTransform: function ( index, target ) {
 
-               const skinIndex = new Vector4();
-               const skinWeight = new Vector4();
-
-               const vector = new Vector3();
-               const matrix = new Matrix4();
-
-               return function ( index, target ) {
-
-                       const skeleton = this.skeleton;
-                       const geometry = this.geometry;
-
-                       skinIndex.fromBufferAttribute( geometry.attributes.skinIndex, index );
-                       skinWeight.fromBufferAttribute( geometry.attributes.skinWeight, index );
+               const skeleton = this.skeleton;
+               const geometry = this.geometry;
 
-                       basePosition.fromBufferAttribute( geometry.attributes.position, index ).applyMatrix4( this.bindMatrix );
+               _skinIndex.fromBufferAttribute( geometry.attributes.skinIndex, index );
+               _skinWeight.fromBufferAttribute( geometry.attributes.skinWeight, index );
 
-                       target.set( 0, 0, 0 );
+               _basePosition.fromBufferAttribute( geometry.attributes.position, index ).applyMatrix4( this.bindMatrix );
 
-                       for ( let i = 0; i < 4; i ++ ) {
+               target.set( 0, 0, 0 );
 
-                               const weight = skinWeight.getComponent( i );
+               for ( let i = 0; i < 4; i ++ ) {
 
-                               if ( weight !== 0 ) {
+                       const weight = _skinWeight.getComponent( i );
 
-                                       const boneIndex = skinIndex.getComponent( i );
+                       if ( weight !== 0 ) {
 
-                                       matrix.multiplyMatrices( skeleton.bones[ boneIndex ].matrixWorld, skeleton.boneInverses[ boneIndex ] );
+                               const boneIndex = _skinIndex.getComponent( i );
 
-                                       target.addScaledVector( vector.copy( basePosition ).applyMatrix4( matrix ), weight );
+                               _matrix$1.multiplyMatrices( skeleton.bones[ boneIndex ].matrixWorld, skeleton.boneInverses[ boneIndex ] );
 
-                               }
+                               target.addScaledVector( _vector$7.copy( _basePosition ).applyMatrix4( _matrix$1 ), weight );
 
                        }
 
-                       return target.applyMatrix4( this.bindMatrixInverse );
+               }
 
-               };
+               return target.applyMatrix4( this.bindMatrixInverse );
 
-       }() )
+       }
 
 } );
 
@@ -26595,6 +26291,9 @@ InstancedMesh.prototype = Object.assign( Object.create( Mesh.prototype ), {
                Mesh.prototype.copy.call( this, source );
 
                this.instanceMatrix.copy( source.instanceMatrix );
+
+               if ( source.instanceColor !== null ) this.instanceColor = source.instanceColor.clone();
+
                this.count = source.count;
 
                return this;
@@ -26674,6 +26373,12 @@ InstancedMesh.prototype = Object.assign( Object.create( Mesh.prototype ), {
 
        updateMorphTargets: function () {
 
+       },
+
+       dispose: function () {
+
+               this.dispatchEvent( { type: 'dispose' } );
+
        }
 
 } );
@@ -26734,20 +26439,14 @@ const _inverseMatrix$1 = new Matrix4();
 const _ray$1 = new Ray();
 const _sphere$2 = new Sphere();
 
-function Line( geometry, material, mode ) {
-
-       if ( mode === 1 ) {
-
-               console.error( 'THREE.Line: parameter THREE.LinePieces no longer supported. Use THREE.LineSegments instead.' );
-
-       }
+function Line( geometry = new BufferGeometry(), material = new LineBasicMaterial() ) {
 
        Object3D.call( this );
 
        this.type = 'Line';
 
-       this.geometry = geometry !== undefined ? geometry : new BufferGeometry();
-       this.material = material !== undefined ? material : new LineBasicMaterial();
+       this.geometry = geometry;
+       this.material = material;
 
        this.updateMorphTargets();
 
@@ -26803,17 +26502,7 @@ Line.prototype = Object.assign( Object.create( Object3D.prototype ), {
 
                } else if ( geometry.isGeometry ) {
 
-                       const vertices = geometry.vertices;
-                       const lineDistances = geometry.lineDistances;
-
-                       lineDistances[ 0 ] = 0;
-
-                       for ( let i = 1, l = vertices.length; i < l; i ++ ) {
-
-                               lineDistances[ i ] = lineDistances[ i - 1 ];
-                               lineDistances[ i ] += vertices[ i - 1 ].distanceTo( vertices[ i ] );
-
-                       }
+                       console.error( 'THREE.Line.computeLineDistances() no longer supports THREE.Geometry. Use THREE.BufferGeometry instead.' );
 
                }
 
@@ -26930,36 +26619,289 @@ Line.prototype = Object.assign( Object.create( Object3D.prototype ), {
 
                } else if ( geometry.isGeometry ) {
 
-                       const vertices = geometry.vertices;
-                       const nbVertices = vertices.length;
+                       console.error( 'THREE.Line.raycast() no longer supports THREE.Geometry. Use THREE.BufferGeometry instead.' );
 
-                       for ( let i = 0; i < nbVertices - 1; i += step ) {
+               }
 
-                               const distSq = _ray$1.distanceSqToSegment( vertices[ i ], vertices[ i + 1 ], interRay, interSegment );
+       },
 
-                               if ( distSq > localThresholdSq ) continue;
+       updateMorphTargets: function () {
 
-                               interRay.applyMatrix4( this.matrixWorld ); //Move back to world space for distance calculation
+               const geometry = this.geometry;
 
-                               const distance = raycaster.ray.origin.distanceTo( interRay );
+               if ( geometry.isBufferGeometry ) {
 
-                               if ( distance < raycaster.near || distance > raycaster.far ) continue;
+                       const morphAttributes = geometry.morphAttributes;
+                       const keys = Object.keys( morphAttributes );
 
-                               intersects.push( {
+                       if ( keys.length > 0 ) {
 
-                                       distance: distance,
-                                       // What do we want? intersection point on the ray or on the segment??
-                                       // point: raycaster.ray.at( distance ),
-                                       point: interSegment.clone().applyMatrix4( this.matrixWorld ),
-                                       index: i,
-                                       face: null,
-                                       faceIndex: null,
-                                       object: this
+                               const morphAttribute = morphAttributes[ keys[ 0 ] ];
 
-                               } );
+                               if ( morphAttribute !== undefined ) {
+
+                                       this.morphTargetInfluences = [];
+                                       this.morphTargetDictionary = {};
+
+                                       for ( let m = 0, ml = morphAttribute.length; m < ml; m ++ ) {
+
+                                               const name = morphAttribute[ m ].name || String( m );
+
+                                               this.morphTargetInfluences.push( 0 );
+                                               this.morphTargetDictionary[ name ] = m;
+
+                                       }
+
+                               }
+
+                       }
+
+               } else {
+
+                       const morphTargets = geometry.morphTargets;
+
+                       if ( morphTargets !== undefined && morphTargets.length > 0 ) {
+
+                               console.error( 'THREE.Line.updateMorphTargets() does not support THREE.Geometry. Use THREE.BufferGeometry instead.' );
+
+                       }
+
+               }
+
+       }
+
+} );
+
+const _start$1 = new Vector3();
+const _end$1 = new Vector3();
+
+function LineSegments( geometry, material ) {
+
+       Line.call( this, geometry, material );
+
+       this.type = 'LineSegments';
+
+}
+
+LineSegments.prototype = Object.assign( Object.create( Line.prototype ), {
+
+       constructor: LineSegments,
+
+       isLineSegments: true,
+
+       computeLineDistances: function () {
+
+               const geometry = this.geometry;
+
+               if ( geometry.isBufferGeometry ) {
+
+                       // we assume non-indexed geometry
+
+                       if ( geometry.index === null ) {
+
+                               const positionAttribute = geometry.attributes.position;
+                               const lineDistances = [];
+
+                               for ( let i = 0, l = positionAttribute.count; i < l; i += 2 ) {
+
+                                       _start$1.fromBufferAttribute( positionAttribute, i );
+                                       _end$1.fromBufferAttribute( positionAttribute, i + 1 );
+
+                                       lineDistances[ i ] = ( i === 0 ) ? 0 : lineDistances[ i - 1 ];
+                                       lineDistances[ i + 1 ] = lineDistances[ i ] + _start$1.distanceTo( _end$1 );
+
+                               }
+
+                               geometry.setAttribute( 'lineDistance', new Float32BufferAttribute( lineDistances, 1 ) );
+
+                       } else {
+
+                               console.warn( 'THREE.LineSegments.computeLineDistances(): Computation only possible with non-indexed BufferGeometry.' );
 
                        }
 
+               } else if ( geometry.isGeometry ) {
+
+                       console.error( 'THREE.LineSegments.computeLineDistances() no longer supports THREE.Geometry. Use THREE.BufferGeometry instead.' );
+
+               }
+
+               return this;
+
+       }
+
+} );
+
+function LineLoop( geometry, material ) {
+
+       Line.call( this, geometry, material );
+
+       this.type = 'LineLoop';
+
+}
+
+LineLoop.prototype = Object.assign( Object.create( Line.prototype ), {
+
+       constructor: LineLoop,
+
+       isLineLoop: true,
+
+} );
+
+/**
+ * parameters = {
+ *  color: <hex>,
+ *  opacity: <float>,
+ *  map: new THREE.Texture( <Image> ),
+ *  alphaMap: new THREE.Texture( <Image> ),
+ *
+ *  size: <float>,
+ *  sizeAttenuation: <bool>
+ *
+ *  morphTargets: <bool>
+ * }
+ */
+
+function PointsMaterial( parameters ) {
+
+       Material.call( this );
+
+       this.type = 'PointsMaterial';
+
+       this.color = new Color( 0xffffff );
+
+       this.map = null;
+
+       this.alphaMap = null;
+
+       this.size = 1;
+       this.sizeAttenuation = true;
+
+       this.morphTargets = false;
+
+       this.setValues( parameters );
+
+}
+
+PointsMaterial.prototype = Object.create( Material.prototype );
+PointsMaterial.prototype.constructor = PointsMaterial;
+
+PointsMaterial.prototype.isPointsMaterial = true;
+
+PointsMaterial.prototype.copy = function ( source ) {
+
+       Material.prototype.copy.call( this, source );
+
+       this.color.copy( source.color );
+
+       this.map = source.map;
+
+       this.alphaMap = source.alphaMap;
+
+       this.size = source.size;
+       this.sizeAttenuation = source.sizeAttenuation;
+
+       this.morphTargets = source.morphTargets;
+
+       return this;
+
+};
+
+const _inverseMatrix$2 = new Matrix4();
+const _ray$2 = new Ray();
+const _sphere$3 = new Sphere();
+const _position$1 = new Vector3();
+
+function Points( geometry = new BufferGeometry(), material = new PointsMaterial() ) {
+
+       Object3D.call( this );
+
+       this.type = 'Points';
+
+       this.geometry = geometry;
+       this.material = material;
+
+       this.updateMorphTargets();
+
+}
+
+Points.prototype = Object.assign( Object.create( Object3D.prototype ), {
+
+       constructor: Points,
+
+       isPoints: true,
+
+       copy: function ( source ) {
+
+               Object3D.prototype.copy.call( this, source );
+
+               this.material = source.material;
+               this.geometry = source.geometry;
+
+               return this;
+
+       },
+
+       raycast: function ( raycaster, intersects ) {
+
+               const geometry = this.geometry;
+               const matrixWorld = this.matrixWorld;
+               const threshold = raycaster.params.Points.threshold;
+
+               // Checking boundingSphere distance to ray
+
+               if ( geometry.boundingSphere === null ) geometry.computeBoundingSphere();
+
+               _sphere$3.copy( geometry.boundingSphere );
+               _sphere$3.applyMatrix4( matrixWorld );
+               _sphere$3.radius += threshold;
+
+               if ( raycaster.ray.intersectsSphere( _sphere$3 ) === false ) return;
+
+               //
+
+               _inverseMatrix$2.copy( matrixWorld ).invert();
+               _ray$2.copy( raycaster.ray ).applyMatrix4( _inverseMatrix$2 );
+
+               const localThreshold = threshold / ( ( this.scale.x + this.scale.y + this.scale.z ) / 3 );
+               const localThresholdSq = localThreshold * localThreshold;
+
+               if ( geometry.isBufferGeometry ) {
+
+                       const index = geometry.index;
+                       const attributes = geometry.attributes;
+                       const positionAttribute = attributes.position;
+
+                       if ( index !== null ) {
+
+                               const indices = index.array;
+
+                               for ( let i = 0, il = indices.length; i < il; i ++ ) {
+
+                                       const a = indices[ i ];
+
+                                       _position$1.fromBufferAttribute( positionAttribute, a );
+
+                                       testPoint( _position$1, a, localThresholdSq, matrixWorld, raycaster, intersects, this );
+
+                               }
+
+                       } else {
+
+                               for ( let i = 0, l = positionAttribute.count; i < l; i ++ ) {
+
+                                       _position$1.fromBufferAttribute( positionAttribute, i );
+
+                                       testPoint( _position$1, i, localThresholdSq, matrixWorld, raycaster, intersects, this );
+
+                               }
+
+                       }
+
+               } else {
+
+                       console.error( 'THREE.Points.raycast() no longer supports THREE.Geometry. Use THREE.BufferGeometry instead.' );
+
                }
 
        },
@@ -27001,1858 +26943,173 @@ Line.prototype = Object.assign( Object.create( Object3D.prototype ), {
 
                        if ( morphTargets !== undefined && morphTargets.length > 0 ) {
 
-                               console.error( 'THREE.Line.updateMorphTargets() does not support THREE.Geometry. Use THREE.BufferGeometry instead.' );
-
-                       }
-
-               }
-
-       }
-
-} );
-
-const _start$1 = new Vector3();
-const _end$1 = new Vector3();
-
-function LineSegments( geometry, material ) {
-
-       Line.call( this, geometry, material );
-
-       this.type = 'LineSegments';
-
-}
-
-LineSegments.prototype = Object.assign( Object.create( Line.prototype ), {
-
-       constructor: LineSegments,
-
-       isLineSegments: true,
-
-       computeLineDistances: function () {
-
-               const geometry = this.geometry;
-
-               if ( geometry.isBufferGeometry ) {
-
-                       // we assume non-indexed geometry
-
-                       if ( geometry.index === null ) {
-
-                               const positionAttribute = geometry.attributes.position;
-                               const lineDistances = [];
-
-                               for ( let i = 0, l = positionAttribute.count; i < l; i += 2 ) {
-
-                                       _start$1.fromBufferAttribute( positionAttribute, i );
-                                       _end$1.fromBufferAttribute( positionAttribute, i + 1 );
-
-                                       lineDistances[ i ] = ( i === 0 ) ? 0 : lineDistances[ i - 1 ];
-                                       lineDistances[ i + 1 ] = lineDistances[ i ] + _start$1.distanceTo( _end$1 );
-
-                               }
-
-                               geometry.setAttribute( 'lineDistance', new Float32BufferAttribute( lineDistances, 1 ) );
-
-                       } else {
-
-                               console.warn( 'THREE.LineSegments.computeLineDistances(): Computation only possible with non-indexed BufferGeometry.' );
-
-                       }
-
-               } else if ( geometry.isGeometry ) {
-
-                       const vertices = geometry.vertices;
-                       const lineDistances = geometry.lineDistances;
-
-                       for ( let i = 0, l = vertices.length; i < l; i += 2 ) {
-
-                               _start$1.copy( vertices[ i ] );
-                               _end$1.copy( vertices[ i + 1 ] );
-
-                               lineDistances[ i ] = ( i === 0 ) ? 0 : lineDistances[ i - 1 ];
-                               lineDistances[ i + 1 ] = lineDistances[ i ] + _start$1.distanceTo( _end$1 );
-
-                       }
-
-               }
-
-               return this;
-
-       }
-
-} );
-
-function LineLoop( geometry, material ) {
-
-       Line.call( this, geometry, material );
-
-       this.type = 'LineLoop';
-
-}
-
-LineLoop.prototype = Object.assign( Object.create( Line.prototype ), {
-
-       constructor: LineLoop,
-
-       isLineLoop: true,
-
-} );
-
-/**
- * parameters = {
- *  color: <hex>,
- *  opacity: <float>,
- *  map: new THREE.Texture( <Image> ),
- *  alphaMap: new THREE.Texture( <Image> ),
- *
- *  size: <float>,
- *  sizeAttenuation: <bool>
- *
- *  morphTargets: <bool>
- * }
- */
-
-function PointsMaterial( parameters ) {
-
-       Material.call( this );
-
-       this.type = 'PointsMaterial';
-
-       this.color = new Color( 0xffffff );
-
-       this.map = null;
-
-       this.alphaMap = null;
-
-       this.size = 1;
-       this.sizeAttenuation = true;
-
-       this.morphTargets = false;
-
-       this.setValues( parameters );
-
-}
-
-PointsMaterial.prototype = Object.create( Material.prototype );
-PointsMaterial.prototype.constructor = PointsMaterial;
-
-PointsMaterial.prototype.isPointsMaterial = true;
-
-PointsMaterial.prototype.copy = function ( source ) {
-
-       Material.prototype.copy.call( this, source );
-
-       this.color.copy( source.color );
-
-       this.map = source.map;
-
-       this.alphaMap = source.alphaMap;
-
-       this.size = source.size;
-       this.sizeAttenuation = source.sizeAttenuation;
-
-       this.morphTargets = source.morphTargets;
-
-       return this;
-
-};
-
-const _inverseMatrix$2 = new Matrix4();
-const _ray$2 = new Ray();
-const _sphere$3 = new Sphere();
-const _position$1 = new Vector3();
-
-function Points( geometry, material ) {
-
-       Object3D.call( this );
-
-       this.type = 'Points';
-
-       this.geometry = geometry !== undefined ? geometry : new BufferGeometry();
-       this.material = material !== undefined ? material : new PointsMaterial();
-
-       this.updateMorphTargets();
-
-}
-
-Points.prototype = Object.assign( Object.create( Object3D.prototype ), {
-
-       constructor: Points,
-
-       isPoints: true,
-
-       copy: function ( source ) {
-
-               Object3D.prototype.copy.call( this, source );
-
-               this.material = source.material;
-               this.geometry = source.geometry;
-
-               return this;
-
-       },
-
-       raycast: function ( raycaster, intersects ) {
-
-               const geometry = this.geometry;
-               const matrixWorld = this.matrixWorld;
-               const threshold = raycaster.params.Points.threshold;
-
-               // Checking boundingSphere distance to ray
-
-               if ( geometry.boundingSphere === null ) geometry.computeBoundingSphere();
-
-               _sphere$3.copy( geometry.boundingSphere );
-               _sphere$3.applyMatrix4( matrixWorld );
-               _sphere$3.radius += threshold;
-
-               if ( raycaster.ray.intersectsSphere( _sphere$3 ) === false ) return;
-
-               //
-
-               _inverseMatrix$2.copy( matrixWorld ).invert();
-               _ray$2.copy( raycaster.ray ).applyMatrix4( _inverseMatrix$2 );
-
-               const localThreshold = threshold / ( ( this.scale.x + this.scale.y + this.scale.z ) / 3 );
-               const localThresholdSq = localThreshold * localThreshold;
-
-               if ( geometry.isBufferGeometry ) {
-
-                       const index = geometry.index;
-                       const attributes = geometry.attributes;
-                       const positionAttribute = attributes.position;
-
-                       if ( index !== null ) {
-
-                               const indices = index.array;
-
-                               for ( let i = 0, il = indices.length; i < il; i ++ ) {
-
-                                       const a = indices[ i ];
-
-                                       _position$1.fromBufferAttribute( positionAttribute, a );
-
-                                       testPoint( _position$1, a, localThresholdSq, matrixWorld, raycaster, intersects, this );
-
-                               }
-
-                       } else {
-
-                               for ( let i = 0, l = positionAttribute.count; i < l; i ++ ) {
-
-                                       _position$1.fromBufferAttribute( positionAttribute, i );
-
-                                       testPoint( _position$1, i, localThresholdSq, matrixWorld, raycaster, intersects, this );
-
-                               }
-
-                       }
-
-               } else {
-
-                       const vertices = geometry.vertices;
-
-                       for ( let i = 0, l = vertices.length; i < l; i ++ ) {
-
-                               testPoint( vertices[ i ], i, localThresholdSq, matrixWorld, raycaster, intersects, this );
-
-                       }
-
-               }
-
-       },
-
-       updateMorphTargets: function () {
-
-               const geometry = this.geometry;
-
-               if ( geometry.isBufferGeometry ) {
-
-                       const morphAttributes = geometry.morphAttributes;
-                       const keys = Object.keys( morphAttributes );
-
-                       if ( keys.length > 0 ) {
-
-                               const morphAttribute = morphAttributes[ keys[ 0 ] ];
-
-                               if ( morphAttribute !== undefined ) {
-
-                                       this.morphTargetInfluences = [];
-                                       this.morphTargetDictionary = {};
-
-                                       for ( let m = 0, ml = morphAttribute.length; m < ml; m ++ ) {
-
-                                               const name = morphAttribute[ m ].name || String( m );
-
-                                               this.morphTargetInfluences.push( 0 );
-                                               this.morphTargetDictionary[ name ] = m;
-
-                                       }
-
-                               }
-
-                       }
-
-               } else {
-
-                       const morphTargets = geometry.morphTargets;
-
-                       if ( morphTargets !== undefined && morphTargets.length > 0 ) {
-
-                               console.error( 'THREE.Points.updateMorphTargets() does not support THREE.Geometry. Use THREE.BufferGeometry instead.' );
-
-                       }
-
-               }
-
-       }
-
-} );
-
-function testPoint( point, index, localThresholdSq, matrixWorld, raycaster, intersects, object ) {
-
-       const rayPointDistanceSq = _ray$2.distanceSqToPoint( point );
-
-       if ( rayPointDistanceSq < localThresholdSq ) {
-
-               const intersectPoint = new Vector3();
-
-               _ray$2.closestPointToPoint( point, intersectPoint );
-               intersectPoint.applyMatrix4( matrixWorld );
-
-               const distance = raycaster.ray.origin.distanceTo( intersectPoint );
-
-               if ( distance < raycaster.near || distance > raycaster.far ) return;
-
-               intersects.push( {
-
-                       distance: distance,
-                       distanceToRay: Math.sqrt( rayPointDistanceSq ),
-                       point: intersectPoint,
-                       index: index,
-                       face: null,
-                       object: object
-
-               } );
-
-       }
-
-}
-
-function VideoTexture( video, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy ) {
-
-       Texture.call( this, video, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy );
-
-       this.format = format !== undefined ? format : RGBFormat;
-
-       this.minFilter = minFilter !== undefined ? minFilter : LinearFilter;
-       this.magFilter = magFilter !== undefined ? magFilter : LinearFilter;
-
-       this.generateMipmaps = false;
-
-       const scope = this;
-
-       function updateVideo() {
-
-               scope.needsUpdate = true;
-               video.requestVideoFrameCallback( updateVideo );
-
-       }
-
-       if ( 'requestVideoFrameCallback' in video ) {
-
-               video.requestVideoFrameCallback( updateVideo );
-
-       }
-
-}
-
-VideoTexture.prototype = Object.assign( Object.create( Texture.prototype ), {
-
-       constructor: VideoTexture,
-
-       clone: function () {
-
-               return new this.constructor( this.image ).copy( this );
-
-       },
-
-       isVideoTexture: true,
-
-       update: function () {
-
-               const video = this.image;
-               const hasVideoFrameCallback = 'requestVideoFrameCallback' in video;
-
-               if ( hasVideoFrameCallback === false && video.readyState >= video.HAVE_CURRENT_DATA ) {
-
-                       this.needsUpdate = true;
-
-               }
-
-       }
-
-} );
-
-function CompressedTexture( mipmaps, width, height, format, type, mapping, wrapS, wrapT, magFilter, minFilter, anisotropy, encoding ) {
-
-       Texture.call( this, null, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy, encoding );
-
-       this.image = { width: width, height: height };
-       this.mipmaps = mipmaps;
-
-       // no flipping for cube textures
-       // (also flipping doesn't work for compressed textures )
-
-       this.flipY = false;
-
-       // can't generate mipmaps for compressed textures
-       // mips must be embedded in DDS files
-
-       this.generateMipmaps = false;
-
-}
-
-CompressedTexture.prototype = Object.create( Texture.prototype );
-CompressedTexture.prototype.constructor = CompressedTexture;
-
-CompressedTexture.prototype.isCompressedTexture = true;
-
-function CanvasTexture( canvas, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy ) {
-
-       Texture.call( this, canvas, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy );
-
-       this.needsUpdate = true;
-
-}
-
-CanvasTexture.prototype = Object.create( Texture.prototype );
-CanvasTexture.prototype.constructor = CanvasTexture;
-CanvasTexture.prototype.isCanvasTexture = true;
-
-function DepthTexture( width, height, type, mapping, wrapS, wrapT, magFilter, minFilter, anisotropy, format ) {
-
-       format = format !== undefined ? format : DepthFormat;
-
-       if ( format !== DepthFormat && format !== DepthStencilFormat ) {
-
-               throw new Error( 'DepthTexture format must be either THREE.DepthFormat or THREE.DepthStencilFormat' );
-
-       }
-
-       if ( type === undefined && format === DepthFormat ) type = UnsignedShortType;
-       if ( type === undefined && format === DepthStencilFormat ) type = UnsignedInt248Type;
-
-       Texture.call( this, null, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy );
-
-       this.image = { width: width, height: height };
-
-       this.magFilter = magFilter !== undefined ? magFilter : NearestFilter;
-       this.minFilter = minFilter !== undefined ? minFilter : NearestFilter;
-
-       this.flipY = false;
-       this.generateMipmaps = false;
-
-}
-
-DepthTexture.prototype = Object.create( Texture.prototype );
-DepthTexture.prototype.constructor = DepthTexture;
-DepthTexture.prototype.isDepthTexture = true;
-
-let _geometryId = 0; // Geometry uses even numbers as Id
-const _m1$3 = new Matrix4();
-const _obj$1 = new Object3D();
-const _offset$1 = new Vector3();
-
-function Geometry() {
-
-       Object.defineProperty( this, 'id', { value: _geometryId += 2 } );
-
-       this.uuid = MathUtils.generateUUID();
-
-       this.name = '';
-       this.type = 'Geometry';
-
-       this.vertices = [];
-       this.colors = [];
-       this.faces = [];
-       this.faceVertexUvs = [[]];
-
-       this.morphTargets = [];
-       this.morphNormals = [];
-
-       this.skinWeights = [];
-       this.skinIndices = [];
-
-       this.lineDistances = [];
-
-       this.boundingBox = null;
-       this.boundingSphere = null;
-
-       // update flags
-
-       this.elementsNeedUpdate = false;
-       this.verticesNeedUpdate = false;
-       this.uvsNeedUpdate = false;
-       this.normalsNeedUpdate = false;
-       this.colorsNeedUpdate = false;
-       this.lineDistancesNeedUpdate = false;
-       this.groupsNeedUpdate = false;
-
-}
-
-Geometry.prototype = Object.assign( Object.create( EventDispatcher.prototype ), {
-
-       constructor: Geometry,
-
-       isGeometry: true,
-
-       applyMatrix4: function ( matrix ) {
-
-               const normalMatrix = new Matrix3().getNormalMatrix( matrix );
-
-               for ( let i = 0, il = this.vertices.length; i < il; i ++ ) {
-
-                       const vertex = this.vertices[ i ];
-                       vertex.applyMatrix4( matrix );
-
-               }
-
-               for ( let i = 0, il = this.faces.length; i < il; i ++ ) {
-
-                       const face = this.faces[ i ];
-                       face.normal.applyMatrix3( normalMatrix ).normalize();
-
-                       for ( let j = 0, jl = face.vertexNormals.length; j < jl; j ++ ) {
-
-                               face.vertexNormals[ j ].applyMatrix3( normalMatrix ).normalize();
-
-                       }
-
-               }
-
-               if ( this.boundingBox !== null ) {
-
-                       this.computeBoundingBox();
-
-               }
-
-               if ( this.boundingSphere !== null ) {
-
-                       this.computeBoundingSphere();
-
-               }
-
-               this.verticesNeedUpdate = true;
-               this.normalsNeedUpdate = true;
-
-               return this;
-
-       },
-
-       rotateX: function ( angle ) {
-
-               // rotate geometry around world x-axis
-
-               _m1$3.makeRotationX( angle );
-
-               this.applyMatrix4( _m1$3 );
-
-               return this;
-
-       },
-
-       rotateY: function ( angle ) {
-
-               // rotate geometry around world y-axis
-
-               _m1$3.makeRotationY( angle );
-
-               this.applyMatrix4( _m1$3 );
-
-               return this;
-
-       },
-
-       rotateZ: function ( angle ) {
-
-               // rotate geometry around world z-axis
-
-               _m1$3.makeRotationZ( angle );
-
-               this.applyMatrix4( _m1$3 );
-
-               return this;
-
-       },
-
-       translate: function ( x, y, z ) {
-
-               // translate geometry
-
-               _m1$3.makeTranslation( x, y, z );
-
-               this.applyMatrix4( _m1$3 );
-
-               return this;
-
-       },
-
-       scale: function ( x, y, z ) {
-
-               // scale geometry
-
-               _m1$3.makeScale( x, y, z );
-
-               this.applyMatrix4( _m1$3 );
-
-               return this;
-
-       },
-
-       lookAt: function ( vector ) {
-
-               _obj$1.lookAt( vector );
-
-               _obj$1.updateMatrix();
-
-               this.applyMatrix4( _obj$1.matrix );
-
-               return this;
-
-       },
-
-       fromBufferGeometry: function ( geometry ) {
-
-               const scope = this;
-
-               const index = geometry.index !== null ? geometry.index : undefined;
-               const attributes = geometry.attributes;
-
-               if ( attributes.position === undefined ) {
-
-                       console.error( 'THREE.Geometry.fromBufferGeometry(): Position attribute required for conversion.' );
-                       return this;
-
-               }
-
-               const position = attributes.position;
-               const normal = attributes.normal;
-               const color = attributes.color;
-               const uv = attributes.uv;
-               const uv2 = attributes.uv2;
-
-               if ( uv2 !== undefined ) this.faceVertexUvs[ 1 ] = [];
-
-               for ( let i = 0; i < position.count; i ++ ) {
-
-                       scope.vertices.push( new Vector3().fromBufferAttribute( position, i ) );
-
-                       if ( color !== undefined ) {
-
-                               scope.colors.push( new Color().fromBufferAttribute( color, i ) );
-
-                       }
-
-               }
-
-               function addFace( a, b, c, materialIndex ) {
-
-                       const vertexColors = ( color === undefined ) ? [] : [
-                               scope.colors[ a ].clone(),
-                               scope.colors[ b ].clone(),
-                               scope.colors[ c ].clone()
-                       ];
-
-                       const vertexNormals = ( normal === undefined ) ? [] : [
-                               new Vector3().fromBufferAttribute( normal, a ),
-                               new Vector3().fromBufferAttribute( normal, b ),
-                               new Vector3().fromBufferAttribute( normal, c )
-                       ];
-
-                       const face = new Face3( a, b, c, vertexNormals, vertexColors, materialIndex );
-
-                       scope.faces.push( face );
-
-                       if ( uv !== undefined ) {
-
-                               scope.faceVertexUvs[ 0 ].push( [
-                                       new Vector2().fromBufferAttribute( uv, a ),
-                                       new Vector2().fromBufferAttribute( uv, b ),
-                                       new Vector2().fromBufferAttribute( uv, c )
-                               ] );
-
-                       }
-
-                       if ( uv2 !== undefined ) {
-
-                               scope.faceVertexUvs[ 1 ].push( [
-                                       new Vector2().fromBufferAttribute( uv2, a ),
-                                       new Vector2().fromBufferAttribute( uv2, b ),
-                                       new Vector2().fromBufferAttribute( uv2, c )
-                               ] );
-
-                       }
-
-               }
-
-               const groups = geometry.groups;
-
-               if ( groups.length > 0 ) {
-
-                       for ( let i = 0; i < groups.length; i ++ ) {
-
-                               const group = groups[ i ];
-
-                               const start = group.start;
-                               const count = group.count;
-
-                               for ( let j = start, jl = start + count; j < jl; j += 3 ) {
-
-                                       if ( index !== undefined ) {
-
-                                               addFace( index.getX( j ), index.getX( j + 1 ), index.getX( j + 2 ), group.materialIndex );
-
-                                       } else {
-
-                                               addFace( j, j + 1, j + 2, group.materialIndex );
-
-                                       }
-
-                               }
-
-                       }
-
-               } else {
-
-                       if ( index !== undefined ) {
-
-                               for ( let i = 0; i < index.count; i += 3 ) {
-
-                                       addFace( index.getX( i ), index.getX( i + 1 ), index.getX( i + 2 ) );
-
-                               }
-
-                       } else {
-
-                               for ( let i = 0; i < position.count; i += 3 ) {
-
-                                       addFace( i, i + 1, i + 2 );
-
-                               }
-
-                       }
-
-               }
-
-               this.computeFaceNormals();
-
-               if ( geometry.boundingBox !== null ) {
-
-                       this.boundingBox = geometry.boundingBox.clone();
-
-               }
-
-               if ( geometry.boundingSphere !== null ) {
-
-                       this.boundingSphere = geometry.boundingSphere.clone();
-
-               }
-
-               return this;
-
-       },
-
-       center: function () {
-
-               this.computeBoundingBox();
-
-               this.boundingBox.getCenter( _offset$1 ).negate();
-
-               this.translate( _offset$1.x, _offset$1.y, _offset$1.z );
-
-               return this;
-
-       },
-
-       normalize: function () {
-
-               this.computeBoundingSphere();
-
-               const center = this.boundingSphere.center;
-               const radius = this.boundingSphere.radius;
-
-               const s = radius === 0 ? 1 : 1.0 / radius;
-
-               const matrix = new Matrix4();
-               matrix.set(
-                       s, 0, 0, - s * center.x,
-                       0, s, 0, - s * center.y,
-                       0, 0, s, - s * center.z,
-                       0, 0, 0, 1
-               );
-
-               this.applyMatrix4( matrix );
-
-               return this;
-
-       },
-
-       computeFaceNormals: function () {
-
-               const cb = new Vector3(), ab = new Vector3();
-
-               for ( let f = 0, fl = this.faces.length; f < fl; f ++ ) {
-
-                       const face = this.faces[ f ];
-
-                       const vA = this.vertices[ face.a ];
-                       const vB = this.vertices[ face.b ];
-                       const vC = this.vertices[ face.c ];
-
-                       cb.subVectors( vC, vB );
-                       ab.subVectors( vA, vB );
-                       cb.cross( ab );
-
-                       cb.normalize();
-
-                       face.normal.copy( cb );
-
-               }
-
-       },
-
-       computeVertexNormals: function ( areaWeighted = true ) {
-
-               const vertices = new Array( this.vertices.length );
-
-               for ( let v = 0, vl = this.vertices.length; v < vl; v ++ ) {
-
-                       vertices[ v ] = new Vector3();
-
-               }
-
-               if ( areaWeighted ) {
-
-                       // vertex normals weighted by triangle areas
-                       // http://www.iquilezles.org/www/articles/normals/normals.htm
-
-                       const cb = new Vector3(), ab = new Vector3();
-
-                       for ( let f = 0, fl = this.faces.length; f < fl; f ++ ) {
-
-                               const face = this.faces[ f ];
-
-                               const vA = this.vertices[ face.a ];
-                               const vB = this.vertices[ face.b ];
-                               const vC = this.vertices[ face.c ];
-
-                               cb.subVectors( vC, vB );
-                               ab.subVectors( vA, vB );
-                               cb.cross( ab );
-
-                               vertices[ face.a ].add( cb );
-                               vertices[ face.b ].add( cb );
-                               vertices[ face.c ].add( cb );
-
-                       }
-
-               } else {
-
-                       this.computeFaceNormals();
-
-                       for ( let f = 0, fl = this.faces.length; f < fl; f ++ ) {
-
-                               const face = this.faces[ f ];
-
-                               vertices[ face.a ].add( face.normal );
-                               vertices[ face.b ].add( face.normal );
-                               vertices[ face.c ].add( face.normal );
-
-                       }
-
-               }
-
-               for ( let v = 0, vl = this.vertices.length; v < vl; v ++ ) {
-
-                       vertices[ v ].normalize();
-
-               }
-
-               for ( let f = 0, fl = this.faces.length; f < fl; f ++ ) {
-
-                       const face = this.faces[ f ];
-
-                       const vertexNormals = face.vertexNormals;
-
-                       if ( vertexNormals.length === 3 ) {
-
-                               vertexNormals[ 0 ].copy( vertices[ face.a ] );
-                               vertexNormals[ 1 ].copy( vertices[ face.b ] );
-                               vertexNormals[ 2 ].copy( vertices[ face.c ] );
-
-                       } else {
-
-                               vertexNormals[ 0 ] = vertices[ face.a ].clone();
-                               vertexNormals[ 1 ] = vertices[ face.b ].clone();
-                               vertexNormals[ 2 ] = vertices[ face.c ].clone();
-
-                       }
-
-               }
-
-               if ( this.faces.length > 0 ) {
-
-                       this.normalsNeedUpdate = true;
-
-               }
-
-       },
-
-       computeFlatVertexNormals: function () {
-
-               this.computeFaceNormals();
-
-               for ( let f = 0, fl = this.faces.length; f < fl; f ++ ) {
-
-                       const face = this.faces[ f ];
-
-                       const vertexNormals = face.vertexNormals;
-
-                       if ( vertexNormals.length === 3 ) {
-
-                               vertexNormals[ 0 ].copy( face.normal );
-                               vertexNormals[ 1 ].copy( face.normal );
-                               vertexNormals[ 2 ].copy( face.normal );
-
-                       } else {
-
-                               vertexNormals[ 0 ] = face.normal.clone();
-                               vertexNormals[ 1 ] = face.normal.clone();
-                               vertexNormals[ 2 ] = face.normal.clone();
-
-                       }
-
-               }
-
-               if ( this.faces.length > 0 ) {
-
-                       this.normalsNeedUpdate = true;
-
-               }
-
-       },
-
-       computeMorphNormals: function () {
-
-               // save original normals
-               // - create temp variables on first access
-               //   otherwise just copy (for faster repeated calls)
-
-               for ( let f = 0, fl = this.faces.length; f < fl; f ++ ) {
-
-                       const face = this.faces[ f ];
-
-                       if ( ! face.__originalFaceNormal ) {
-
-                               face.__originalFaceNormal = face.normal.clone();
-
-                       } else {
-
-                               face.__originalFaceNormal.copy( face.normal );
-
-                       }
-
-                       if ( ! face.__originalVertexNormals ) face.__originalVertexNormals = [];
-
-                       for ( let i = 0, il = face.vertexNormals.length; i < il; i ++ ) {
-
-                               if ( ! face.__originalVertexNormals[ i ] ) {
-
-                                       face.__originalVertexNormals[ i ] = face.vertexNormals[ i ].clone();
-
-                               } else {
-
-                                       face.__originalVertexNormals[ i ].copy( face.vertexNormals[ i ] );
-
-                               }
-
-                       }
-
-               }
-
-               // use temp geometry to compute face and vertex normals for each morph
-
-               const tmpGeo = new Geometry();
-               tmpGeo.faces = this.faces;
-
-               for ( let i = 0, il = this.morphTargets.length; i < il; i ++ ) {
-
-                       // create on first access
-
-                       if ( ! this.morphNormals[ i ] ) {
-
-                               this.morphNormals[ i ] = {};
-                               this.morphNormals[ i ].faceNormals = [];
-                               this.morphNormals[ i ].vertexNormals = [];
-
-                               const dstNormalsFace = this.morphNormals[ i ].faceNormals;
-                               const dstNormalsVertex = this.morphNormals[ i ].vertexNormals;
-
-                               for ( let f = 0, fl = this.faces.length; f < fl; f ++ ) {
-
-                                       const faceNormal = new Vector3();
-                                       const vertexNormals = { a: new Vector3(), b: new Vector3(), c: new Vector3() };
-
-                                       dstNormalsFace.push( faceNormal );
-                                       dstNormalsVertex.push( vertexNormals );
-
-                               }
-
-                       }
-
-                       const morphNormals = this.morphNormals[ i ];
-
-                       // set vertices to morph target
-
-                       tmpGeo.vertices = this.morphTargets[ i ].vertices;
-
-                       // compute morph normals
-
-                       tmpGeo.computeFaceNormals();
-                       tmpGeo.computeVertexNormals();
-
-                       // store morph normals
-
-                       for ( let f = 0, fl = this.faces.length; f < fl; f ++ ) {
-
-                               const face = this.faces[ f ];
-
-                               const faceNormal = morphNormals.faceNormals[ f ];
-                               const vertexNormals = morphNormals.vertexNormals[ f ];
-
-                               faceNormal.copy( face.normal );
-
-                               vertexNormals.a.copy( face.vertexNormals[ 0 ] );
-                               vertexNormals.b.copy( face.vertexNormals[ 1 ] );
-                               vertexNormals.c.copy( face.vertexNormals[ 2 ] );
-
-                       }
-
-               }
-
-               // restore original normals
-
-               for ( let f = 0, fl = this.faces.length; f < fl; f ++ ) {
-
-                       const face = this.faces[ f ];
-
-                       face.normal = face.__originalFaceNormal;
-                       face.vertexNormals = face.__originalVertexNormals;
-
-               }
-
-       },
-
-       computeBoundingBox: function () {
-
-               if ( this.boundingBox === null ) {
-
-                       this.boundingBox = new Box3();
-
-               }
-
-               this.boundingBox.setFromPoints( this.vertices );
-
-       },
-
-       computeBoundingSphere: function () {
-
-               if ( this.boundingSphere === null ) {
-
-                       this.boundingSphere = new Sphere();
-
-               }
-
-               this.boundingSphere.setFromPoints( this.vertices );
-
-       },
-
-       merge: function ( geometry, matrix, materialIndexOffset = 0 ) {
-
-               if ( ! ( geometry && geometry.isGeometry ) ) {
-
-                       console.error( 'THREE.Geometry.merge(): geometry not an instance of THREE.Geometry.', geometry );
-                       return;
-
-               }
-
-               let normalMatrix;
-               const vertexOffset = this.vertices.length,
-                       vertices1 = this.vertices,
-                       vertices2 = geometry.vertices,
-                       faces1 = this.faces,
-                       faces2 = geometry.faces,
-                       colors1 = this.colors,
-                       colors2 = geometry.colors;
-
-               if ( matrix !== undefined ) {
-
-                       normalMatrix = new Matrix3().getNormalMatrix( matrix );
-
-               }
-
-               // vertices
-
-               for ( let i = 0, il = vertices2.length; i < il; i ++ ) {
-
-                       const vertex = vertices2[ i ];
-
-                       const vertexCopy = vertex.clone();
-
-                       if ( matrix !== undefined ) vertexCopy.applyMatrix4( matrix );
-
-                       vertices1.push( vertexCopy );
-
-               }
-
-               // colors
-
-               for ( let i = 0, il = colors2.length; i < il; i ++ ) {
-
-                       colors1.push( colors2[ i ].clone() );
-
-               }
-
-               // faces
-
-               for ( let i = 0, il = faces2.length; i < il; i ++ ) {
-
-                       const face = faces2[ i ];
-                       let normal, color;
-                       const faceVertexNormals = face.vertexNormals,
-                               faceVertexColors = face.vertexColors;
-
-                       const faceCopy = new Face3( face.a + vertexOffset, face.b + vertexOffset, face.c + vertexOffset );
-                       faceCopy.normal.copy( face.normal );
-
-                       if ( normalMatrix !== undefined ) {
-
-                               faceCopy.normal.applyMatrix3( normalMatrix ).normalize();
-
-                       }
-
-                       for ( let j = 0, jl = faceVertexNormals.length; j < jl; j ++ ) {
-
-                               normal = faceVertexNormals[ j ].clone();
-
-                               if ( normalMatrix !== undefined ) {
-
-                                       normal.applyMatrix3( normalMatrix ).normalize();
-
-                               }
-
-                               faceCopy.vertexNormals.push( normal );
-
-                       }
-
-                       faceCopy.color.copy( face.color );
-
-                       for ( let j = 0, jl = faceVertexColors.length; j < jl; j ++ ) {
-
-                               color = faceVertexColors[ j ];
-                               faceCopy.vertexColors.push( color.clone() );
-
-                       }
-
-                       faceCopy.materialIndex = face.materialIndex + materialIndexOffset;
-
-                       faces1.push( faceCopy );
-
-               }
-
-               // uvs
-
-               for ( let i = 0, il = geometry.faceVertexUvs.length; i < il; i ++ ) {
-
-                       const faceVertexUvs2 = geometry.faceVertexUvs[ i ];
-
-                       if ( this.faceVertexUvs[ i ] === undefined ) this.faceVertexUvs[ i ] = [];
-
-                       for ( let j = 0, jl = faceVertexUvs2.length; j < jl; j ++ ) {
-
-                               const uvs2 = faceVertexUvs2[ j ], uvsCopy = [];
-
-                               for ( let k = 0, kl = uvs2.length; k < kl; k ++ ) {
-
-                                       uvsCopy.push( uvs2[ k ].clone() );
-
-                               }
-
-                               this.faceVertexUvs[ i ].push( uvsCopy );
-
-                       }
-
-               }
-
-       },
-
-       mergeMesh: function ( mesh ) {
-
-               if ( ! ( mesh && mesh.isMesh ) ) {
-
-                       console.error( 'THREE.Geometry.mergeMesh(): mesh not an instance of THREE.Mesh.', mesh );
-                       return;
-
-               }
-
-               if ( mesh.matrixAutoUpdate ) mesh.updateMatrix();
-
-               this.merge( mesh.geometry, mesh.matrix );
-
-       },
-
-       /*
-        * Checks for duplicate vertices with hashmap.
-        * Duplicated vertices are removed
-        * and faces' vertices are updated.
-        */
-
-       mergeVertices: function ( precisionPoints = 4 ) {
-
-               const verticesMap = {}; // Hashmap for looking up vertices by position coordinates (and making sure they are unique)
-               const unique = [], changes = [];
-
-               const precision = Math.pow( 10, precisionPoints );
-
-               for ( let i = 0, il = this.vertices.length; i < il; i ++ ) {
-
-                       const v = this.vertices[ i ];
-                       const key = Math.round( v.x * precision ) + '_' + Math.round( v.y * precision ) + '_' + Math.round( v.z * precision );
-
-                       if ( verticesMap[ key ] === undefined ) {
-
-                               verticesMap[ key ] = i;
-                               unique.push( this.vertices[ i ] );
-                               changes[ i ] = unique.length - 1;
-
-                       } else {
-
-                               //console.log('Duplicate vertex found. ', i, ' could be using ', verticesMap[key]);
-                               changes[ i ] = changes[ verticesMap[ key ] ];
-
-                       }
-
-               }
-
-
-               // if faces are completely degenerate after merging vertices, we
-               // have to remove them from the geometry.
-               const faceIndicesToRemove = [];
-
-               for ( let i = 0, il = this.faces.length; i < il; i ++ ) {
-
-                       const face = this.faces[ i ];
-
-                       face.a = changes[ face.a ];
-                       face.b = changes[ face.b ];
-                       face.c = changes[ face.c ];
-
-                       const indices = [ face.a, face.b, face.c ];
-
-                       // if any duplicate vertices are found in a Face3
-                       // we have to remove the face as nothing can be saved
-                       for ( let n = 0; n < 3; n ++ ) {
-
-                               if ( indices[ n ] === indices[ ( n + 1 ) % 3 ] ) {
-
-                                       faceIndicesToRemove.push( i );
-                                       break;
-
-                               }
-
-                       }
-
-               }
-
-               for ( let i = faceIndicesToRemove.length - 1; i >= 0; i -- ) {
-
-                       const idx = faceIndicesToRemove[ i ];
-
-                       this.faces.splice( idx, 1 );
-
-                       for ( let j = 0, jl = this.faceVertexUvs.length; j < jl; j ++ ) {
-
-                               this.faceVertexUvs[ j ].splice( idx, 1 );
-
-                       }
-
-               }
-
-               // Use unique set of vertices
-
-               const diff = this.vertices.length - unique.length;
-               this.vertices = unique;
-               return diff;
-
-       },
-
-       setFromPoints: function ( points ) {
-
-               this.vertices = [];
-
-               for ( let i = 0, l = points.length; i < l; i ++ ) {
-
-                       const point = points[ i ];
-                       this.vertices.push( new Vector3( point.x, point.y, point.z || 0 ) );
-
-               }
-
-               return this;
-
-       },
-
-       sortFacesByMaterialIndex: function () {
-
-               const faces = this.faces;
-               const length = faces.length;
-
-               // tag faces
-
-               for ( let i = 0; i < length; i ++ ) {
-
-                       faces[ i ]._id = i;
-
-               }
-
-               // sort faces
-
-               function materialIndexSort( a, b ) {
-
-                       return a.materialIndex - b.materialIndex;
-
-               }
-
-               faces.sort( materialIndexSort );
-
-               // sort uvs
-
-               const uvs1 = this.faceVertexUvs[ 0 ];
-               const uvs2 = this.faceVertexUvs[ 1 ];
-
-               let newUvs1, newUvs2;
-
-               if ( uvs1 && uvs1.length === length ) newUvs1 = [];
-               if ( uvs2 && uvs2.length === length ) newUvs2 = [];
-
-               for ( let i = 0; i < length; i ++ ) {
-
-                       const id = faces[ i ]._id;
-
-                       if ( newUvs1 ) newUvs1.push( uvs1[ id ] );
-                       if ( newUvs2 ) newUvs2.push( uvs2[ id ] );
-
-               }
-
-               if ( newUvs1 ) this.faceVertexUvs[ 0 ] = newUvs1;
-               if ( newUvs2 ) this.faceVertexUvs[ 1 ] = newUvs2;
-
-       },
-
-       toJSON: function () {
-
-               const data = {
-                       metadata: {
-                               version: 4.5,
-                               type: 'Geometry',
-                               generator: 'Geometry.toJSON'
-                       }
-               };
-
-               // standard Geometry serialization
-
-               data.uuid = this.uuid;
-               data.type = this.type;
-               if ( this.name !== '' ) data.name = this.name;
-
-               if ( this.parameters !== undefined ) {
-
-                       const parameters = this.parameters;
-
-                       for ( const key in parameters ) {
-
-                               if ( parameters[ key ] !== undefined ) data[ key ] = parameters[ key ];
-
-                       }
-
-                       return data;
-
-               }
-
-               const vertices = [];
-
-               for ( let i = 0; i < this.vertices.length; i ++ ) {
-
-                       const vertex = this.vertices[ i ];
-                       vertices.push( vertex.x, vertex.y, vertex.z );
-
-               }
-
-               const faces = [];
-               const normals = [];
-               const normalsHash = {};
-               const colors = [];
-               const colorsHash = {};
-               const uvs = [];
-               const uvsHash = {};
-
-               for ( let i = 0; i < this.faces.length; i ++ ) {
-
-                       const face = this.faces[ i ];
-
-                       const hasMaterial = true;
-                       const hasFaceUv = false; // deprecated
-                       const hasFaceVertexUv = this.faceVertexUvs[ 0 ][ i ] !== undefined;
-                       const hasFaceNormal = face.normal.length() > 0;
-                       const hasFaceVertexNormal = face.vertexNormals.length > 0;
-                       const hasFaceColor = face.color.r !== 1 || face.color.g !== 1 || face.color.b !== 1;
-                       const hasFaceVertexColor = face.vertexColors.length > 0;
-
-                       let faceType = 0;
-
-                       faceType = setBit( faceType, 0, 0 ); // isQuad
-                       faceType = setBit( faceType, 1, hasMaterial );
-                       faceType = setBit( faceType, 2, hasFaceUv );
-                       faceType = setBit( faceType, 3, hasFaceVertexUv );
-                       faceType = setBit( faceType, 4, hasFaceNormal );
-                       faceType = setBit( faceType, 5, hasFaceVertexNormal );
-                       faceType = setBit( faceType, 6, hasFaceColor );
-                       faceType = setBit( faceType, 7, hasFaceVertexColor );
-
-                       faces.push( faceType );
-                       faces.push( face.a, face.b, face.c );
-                       faces.push( face.materialIndex );
-
-                       if ( hasFaceVertexUv ) {
-
-                               const faceVertexUvs = this.faceVertexUvs[ 0 ][ i ];
-
-                               faces.push(
-                                       getUvIndex( faceVertexUvs[ 0 ] ),
-                                       getUvIndex( faceVertexUvs[ 1 ] ),
-                                       getUvIndex( faceVertexUvs[ 2 ] )
-                               );
-
-                       }
-
-                       if ( hasFaceNormal ) {
-
-                               faces.push( getNormalIndex( face.normal ) );
-
-                       }
-
-                       if ( hasFaceVertexNormal ) {
-
-                               const vertexNormals = face.vertexNormals;
-
-                               faces.push(
-                                       getNormalIndex( vertexNormals[ 0 ] ),
-                                       getNormalIndex( vertexNormals[ 1 ] ),
-                                       getNormalIndex( vertexNormals[ 2 ] )
-                               );
-
-                       }
-
-                       if ( hasFaceColor ) {
-
-                               faces.push( getColorIndex( face.color ) );
-
-                       }
-
-                       if ( hasFaceVertexColor ) {
-
-                               const vertexColors = face.vertexColors;
-
-                               faces.push(
-                                       getColorIndex( vertexColors[ 0 ] ),
-                                       getColorIndex( vertexColors[ 1 ] ),
-                                       getColorIndex( vertexColors[ 2 ] )
-                               );
+                               console.error( 'THREE.Points.updateMorphTargets() does not support THREE.Geometry. Use THREE.BufferGeometry instead.' );
 
                        }
 
                }
 
-               function setBit( value, position, enabled ) {
-
-                       return enabled ? value | ( 1 << position ) : value & ( ~ ( 1 << position ) );
-
-               }
+       }
 
-               function getNormalIndex( normal ) {
+} );
 
-                       const hash = normal.x.toString() + normal.y.toString() + normal.z.toString();
+function testPoint( point, index, localThresholdSq, matrixWorld, raycaster, intersects, object ) {
 
-                       if ( normalsHash[ hash ] !== undefined ) {
+       const rayPointDistanceSq = _ray$2.distanceSqToPoint( point );
 
-                               return normalsHash[ hash ];
+       if ( rayPointDistanceSq < localThresholdSq ) {
 
-                       }
+               const intersectPoint = new Vector3();
 
-                       normalsHash[ hash ] = normals.length / 3;
-                       normals.push( normal.x, normal.y, normal.z );
+               _ray$2.closestPointToPoint( point, intersectPoint );
+               intersectPoint.applyMatrix4( matrixWorld );
 
-                       return normalsHash[ hash ];
+               const distance = raycaster.ray.origin.distanceTo( intersectPoint );
 
-               }
+               if ( distance < raycaster.near || distance > raycaster.far ) return;
 
-               function getColorIndex( color ) {
+               intersects.push( {
 
-                       const hash = color.r.toString() + color.g.toString() + color.b.toString();
+                       distance: distance,
+                       distanceToRay: Math.sqrt( rayPointDistanceSq ),
+                       point: intersectPoint,
+                       index: index,
+                       face: null,
+                       object: object
 
-                       if ( colorsHash[ hash ] !== undefined ) {
+               } );
 
-                               return colorsHash[ hash ];
+       }
 
-                       }
+}
 
-                       colorsHash[ hash ] = colors.length;
-                       colors.push( color.getHex() );
+function VideoTexture( video, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy ) {
 
-                       return colorsHash[ hash ];
+       Texture.call( this, video, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy );
 
-               }
+       this.format = format !== undefined ? format : RGBFormat;
 
-               function getUvIndex( uv ) {
+       this.minFilter = minFilter !== undefined ? minFilter : LinearFilter;
+       this.magFilter = magFilter !== undefined ? magFilter : LinearFilter;
 
-                       const hash = uv.x.toString() + uv.y.toString();
+       this.generateMipmaps = false;
 
-                       if ( uvsHash[ hash ] !== undefined ) {
+       const scope = this;
 
-                               return uvsHash[ hash ];
+       function updateVideo() {
 
-                       }
+               scope.needsUpdate = true;
+               video.requestVideoFrameCallback( updateVideo );
 
-                       uvsHash[ hash ] = uvs.length / 2;
-                       uvs.push( uv.x, uv.y );
+       }
 
-                       return uvsHash[ hash ];
+       if ( 'requestVideoFrameCallback' in video ) {
 
-               }
+               video.requestVideoFrameCallback( updateVideo );
 
-               data.data = {};
+       }
 
-               data.data.vertices = vertices;
-               data.data.normals = normals;
-               if ( colors.length > 0 ) data.data.colors = colors;
-               if ( uvs.length > 0 ) data.data.uvs = [ uvs ]; // temporal backward compatibility
-               data.data.faces = faces;
+}
 
-               return data;
+VideoTexture.prototype = Object.assign( Object.create( Texture.prototype ), {
 
-       },
+       constructor: VideoTexture,
 
        clone: function () {
 
-               /*
-                // Handle primitives
-
-                const parameters = this.parameters;
-
-                if ( parameters !== undefined ) {
-
-                const values = [];
-
-                for ( const key in parameters ) {
-
-                values.push( parameters[ key ] );
-
-                }
-
-                const geometry = Object.create( this.constructor.prototype );
-                this.constructor.apply( geometry, values );
-                return geometry;
-
-                }
-
-                return new this.constructor().copy( this );
-                */
-
-               return new Geometry().copy( this );
+               return new this.constructor( this.image ).copy( this );
 
        },
 
-       copy: function ( source ) {
-
-               // reset
-
-               this.vertices = [];
-               this.colors = [];
-               this.faces = [];
-               this.faceVertexUvs = [[]];
-               this.morphTargets = [];
-               this.morphNormals = [];
-               this.skinWeights = [];
-               this.skinIndices = [];
-               this.lineDistances = [];
-               this.boundingBox = null;
-               this.boundingSphere = null;
-
-               // name
-
-               this.name = source.name;
-
-               // vertices
-
-               const vertices = source.vertices;
-
-               for ( let i = 0, il = vertices.length; i < il; i ++ ) {
-
-                       this.vertices.push( vertices[ i ].clone() );
-
-               }
-
-               // colors
-
-               const colors = source.colors;
-
-               for ( let i = 0, il = colors.length; i < il; i ++ ) {
-
-                       this.colors.push( colors[ i ].clone() );
-
-               }
-
-               // faces
-
-               const faces = source.faces;
-
-               for ( let i = 0, il = faces.length; i < il; i ++ ) {
-
-                       this.faces.push( faces[ i ].clone() );
-
-               }
-
-               // face vertex uvs
-
-               for ( let i = 0, il = source.faceVertexUvs.length; i < il; i ++ ) {
-
-                       const faceVertexUvs = source.faceVertexUvs[ i ];
-
-                       if ( this.faceVertexUvs[ i ] === undefined ) {
-
-                               this.faceVertexUvs[ i ] = [];
-
-                       }
-
-                       for ( let j = 0, jl = faceVertexUvs.length; j < jl; j ++ ) {
-
-                               const uvs = faceVertexUvs[ j ], uvsCopy = [];
-
-                               for ( let k = 0, kl = uvs.length; k < kl; k ++ ) {
-
-                                       const uv = uvs[ k ];
-
-                                       uvsCopy.push( uv.clone() );
-
-                               }
-
-                               this.faceVertexUvs[ i ].push( uvsCopy );
-
-                       }
-
-               }
-
-               // morph targets
-
-               const morphTargets = source.morphTargets;
-
-               for ( let i = 0, il = morphTargets.length; i < il; i ++ ) {
-
-                       const morphTarget = {};
-                       morphTarget.name = morphTargets[ i ].name;
-
-                       // vertices
-
-                       if ( morphTargets[ i ].vertices !== undefined ) {
-
-                               morphTarget.vertices = [];
-
-                               for ( let j = 0, jl = morphTargets[ i ].vertices.length; j < jl; j ++ ) {
-
-                                       morphTarget.vertices.push( morphTargets[ i ].vertices[ j ].clone() );
-
-                               }
-
-                       }
-
-                       // normals
-
-                       if ( morphTargets[ i ].normals !== undefined ) {
-
-                               morphTarget.normals = [];
-
-                               for ( let j = 0, jl = morphTargets[ i ].normals.length; j < jl; j ++ ) {
-
-                                       morphTarget.normals.push( morphTargets[ i ].normals[ j ].clone() );
-
-                               }
-
-                       }
-
-                       this.morphTargets.push( morphTarget );
-
-               }
-
-               // morph normals
-
-               const morphNormals = source.morphNormals;
-
-               for ( let i = 0, il = morphNormals.length; i < il; i ++ ) {
-
-                       const morphNormal = {};
-
-                       // vertex normals
-
-                       if ( morphNormals[ i ].vertexNormals !== undefined ) {
-
-                               morphNormal.vertexNormals = [];
-
-                               for ( let j = 0, jl = morphNormals[ i ].vertexNormals.length; j < jl; j ++ ) {
-
-                                       const srcVertexNormal = morphNormals[ i ].vertexNormals[ j ];
-                                       const destVertexNormal = {};
-
-                                       destVertexNormal.a = srcVertexNormal.a.clone();
-                                       destVertexNormal.b = srcVertexNormal.b.clone();
-                                       destVertexNormal.c = srcVertexNormal.c.clone();
-
-                                       morphNormal.vertexNormals.push( destVertexNormal );
-
-                               }
-
-                       }
-
-                       // face normals
-
-                       if ( morphNormals[ i ].faceNormals !== undefined ) {
-
-                               morphNormal.faceNormals = [];
-
-                               for ( let j = 0, jl = morphNormals[ i ].faceNormals.length; j < jl; j ++ ) {
-
-                                       morphNormal.faceNormals.push( morphNormals[ i ].faceNormals[ j ].clone() );
-
-                               }
-
-                       }
-
-                       this.morphNormals.push( morphNormal );
-
-               }
-
-               // skin weights
-
-               const skinWeights = source.skinWeights;
-
-               for ( let i = 0, il = skinWeights.length; i < il; i ++ ) {
-
-                       this.skinWeights.push( skinWeights[ i ].clone() );
-
-               }
+       isVideoTexture: true,
 
-               // skin indices
+       update: function () {
 
-               const skinIndices = source.skinIndices;
+               const video = this.image;
+               const hasVideoFrameCallback = 'requestVideoFrameCallback' in video;
 
-               for ( let i = 0, il = skinIndices.length; i < il; i ++ ) {
+               if ( hasVideoFrameCallback === false && video.readyState >= video.HAVE_CURRENT_DATA ) {
 
-                       this.skinIndices.push( skinIndices[ i ].clone() );
+                       this.needsUpdate = true;
 
                }
 
-               // line distances
+       }
 
-               const lineDistances = source.lineDistances;
+} );
 
-               for ( let i = 0, il = lineDistances.length; i < il; i ++ ) {
+function CompressedTexture( mipmaps, width, height, format, type, mapping, wrapS, wrapT, magFilter, minFilter, anisotropy, encoding ) {
 
-                       this.lineDistances.push( lineDistances[ i ] );
+       Texture.call( this, null, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy, encoding );
 
-               }
+       this.image = { width: width, height: height };
+       this.mipmaps = mipmaps;
 
-               // bounding box
+       // no flipping for cube textures
+       // (also flipping doesn't work for compressed textures )
 
-               const boundingBox = source.boundingBox;
+       this.flipY = false;
 
-               if ( boundingBox !== null ) {
+       // can't generate mipmaps for compressed textures
+       // mips must be embedded in DDS files
 
-                       this.boundingBox = boundingBox.clone();
+       this.generateMipmaps = false;
 
-               }
+}
 
-               // bounding sphere
+CompressedTexture.prototype = Object.create( Texture.prototype );
+CompressedTexture.prototype.constructor = CompressedTexture;
 
-               const boundingSphere = source.boundingSphere;
+CompressedTexture.prototype.isCompressedTexture = true;
 
-               if ( boundingSphere !== null ) {
+function CanvasTexture( canvas, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy ) {
 
-                       this.boundingSphere = boundingSphere.clone();
+       Texture.call( this, canvas, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy );
 
-               }
+       this.needsUpdate = true;
 
-               // update flags
+}
 
-               this.elementsNeedUpdate = source.elementsNeedUpdate;
-               this.verticesNeedUpdate = source.verticesNeedUpdate;
-               this.uvsNeedUpdate = source.uvsNeedUpdate;
-               this.normalsNeedUpdate = source.normalsNeedUpdate;
-               this.colorsNeedUpdate = source.colorsNeedUpdate;
-               this.lineDistancesNeedUpdate = source.lineDistancesNeedUpdate;
-               this.groupsNeedUpdate = source.groupsNeedUpdate;
+CanvasTexture.prototype = Object.create( Texture.prototype );
+CanvasTexture.prototype.constructor = CanvasTexture;
+CanvasTexture.prototype.isCanvasTexture = true;
 
-               return this;
+function DepthTexture( width, height, type, mapping, wrapS, wrapT, magFilter, minFilter, anisotropy, format ) {
 
-       },
+       format = format !== undefined ? format : DepthFormat;
 
-       dispose: function () {
+       if ( format !== DepthFormat && format !== DepthStencilFormat ) {
 
-               this.dispatchEvent( { type: 'dispose' } );
+               throw new Error( 'DepthTexture format must be either THREE.DepthFormat or THREE.DepthStencilFormat' );
 
        }
 
-} );
-
-class BoxGeometry extends Geometry {
-
-       constructor( width, height, depth, widthSegments, heightSegments, depthSegments ) {
-
-               super();
+       if ( type === undefined && format === DepthFormat ) type = UnsignedShortType;
+       if ( type === undefined && format === DepthStencilFormat ) type = UnsignedInt248Type;
 
-               this.type = 'BoxGeometry';
+       Texture.call( this, null, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy );
 
-               this.parameters = {
-                       width: width,
-                       height: height,
-                       depth: depth,
-                       widthSegments: widthSegments,
-                       heightSegments: heightSegments,
-                       depthSegments: depthSegments
-               };
+       this.image = { width: width, height: height };
 
-               this.fromBufferGeometry( new BoxBufferGeometry( width, height, depth, widthSegments, heightSegments, depthSegments ) );
-               this.mergeVertices();
+       this.magFilter = magFilter !== undefined ? magFilter : NearestFilter;
+       this.minFilter = minFilter !== undefined ? minFilter : NearestFilter;
 
-       }
+       this.flipY = false;
+       this.generateMipmaps = false;
 
 }
 
-class CircleBufferGeometry extends BufferGeometry {
+DepthTexture.prototype = Object.create( Texture.prototype );
+DepthTexture.prototype.constructor = DepthTexture;
+DepthTexture.prototype.isDepthTexture = true;
+
+class CircleGeometry extends BufferGeometry {
 
        constructor( radius = 1, segments = 8, thetaStart = 0, thetaLength = Math.PI * 2 ) {
 
                super();
 
-               this.type = 'CircleBufferGeometry';
+               this.type = 'CircleGeometry';
 
                this.parameters = {
                        radius: radius,
@@ -28924,33 +27181,12 @@ class CircleBufferGeometry extends BufferGeometry {
 
 }
 
-class CircleGeometry extends Geometry {
-
-       constructor( radius, segments, thetaStart, thetaLength ) {
-
-               super();
-               this.type = 'CircleGeometry';
-
-               this.parameters = {
-                       radius: radius,
-                       segments: segments,
-                       thetaStart: thetaStart,
-                       thetaLength: thetaLength
-               };
-
-               this.fromBufferGeometry( new CircleBufferGeometry( radius, segments, thetaStart, thetaLength ) );
-               this.mergeVertices();
-
-       }
-
-}
-
-class CylinderBufferGeometry extends BufferGeometry {
+class CylinderGeometry extends BufferGeometry {
 
        constructor( radiusTop = 1, radiusBottom = 1, height = 1, radialSegments = 8, heightSegments = 1, openEnded = false, thetaStart = 0, thetaLength = Math.PI * 2 ) {
 
                super();
-               this.type = 'CylinderBufferGeometry';
+               this.type = 'CylinderGeometry';
 
                this.parameters = {
                        radiusTop: radiusTop,
@@ -29207,59 +27443,13 @@ class CylinderBufferGeometry extends BufferGeometry {
 
 }
 
-class CylinderGeometry extends Geometry {
-
-       constructor( radiusTop, radiusBottom, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength ) {
-
-               super();
-               this.type = 'CylinderGeometry';
-
-               this.parameters = {
-                       radiusTop: radiusTop,
-                       radiusBottom: radiusBottom,
-                       height: height,
-                       radialSegments: radialSegments,
-                       heightSegments: heightSegments,
-                       openEnded: openEnded,
-                       thetaStart: thetaStart,
-                       thetaLength: thetaLength
-               };
-
-               this.fromBufferGeometry( new CylinderBufferGeometry( radiusTop, radiusBottom, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength ) );
-               this.mergeVertices();
-
-       }
-
-}
-
 class ConeGeometry extends CylinderGeometry {
 
-       constructor( radius, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength ) {
-
-               super( 0, radius, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength );
-               this.type = 'ConeGeometry';
-
-               this.parameters = {
-                       radius: radius,
-                       height: height,
-                       radialSegments: radialSegments,
-                       heightSegments: heightSegments,
-                       openEnded: openEnded,
-                       thetaStart: thetaStart,
-                       thetaLength: thetaLength
-               };
-
-       }
-
-}
-
-class ConeBufferGeometry extends CylinderBufferGeometry {
-
        constructor( radius = 1, height = 1, radialSegments = 8, heightSegments = 1, openEnded = false, thetaStart = 0, thetaLength = Math.PI * 2 ) {
 
                super( 0, radius, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength );
 
-               this.type = 'ConeBufferGeometry';
+               this.type = 'ConeGeometry';
 
                this.parameters = {
                        radius: radius,
@@ -29275,13 +27465,13 @@ class ConeBufferGeometry extends CylinderBufferGeometry {
 
 }
 
-class PolyhedronBufferGeometry extends BufferGeometry {
+class PolyhedronGeometry extends BufferGeometry {
 
        constructor( vertices, indices, radius = 1, detail = 0 ) {
 
                super();
 
-               this.type = 'PolyhedronBufferGeometry';
+               this.type = 'PolyhedronGeometry';
 
                this.parameters = {
                        vertices: vertices,
@@ -29572,7 +27762,7 @@ class PolyhedronBufferGeometry extends BufferGeometry {
 
 }
 
-class DodecahedronBufferGeometry extends PolyhedronBufferGeometry {
+class DodecahedronGeometry extends PolyhedronGeometry {
 
        constructor( radius = 1, detail = 0 ) {
 
@@ -29617,22 +27807,6 @@ class DodecahedronBufferGeometry extends PolyhedronBufferGeometry {
 
                super( vertices, indices, radius, detail );
 
-               this.type = 'DodecahedronBufferGeometry';
-
-               this.parameters = {
-                       radius: radius,
-                       detail: detail
-               };
-
-       }
-
-}
-
-class DodecahedronGeometry extends Geometry {
-
-       constructor( radius, detail ) {
-
-               super();
                this.type = 'DodecahedronGeometry';
 
                this.parameters = {
@@ -29640,9 +27814,6 @@ class DodecahedronGeometry extends Geometry {
                        detail: detail
                };
 
-               this.fromBufferGeometry( new DodecahedronBufferGeometry( radius, detail ) );
-               this.mergeVertices();
-
        }
 
 }
@@ -29666,9 +27837,10 @@ class EdgesGeometry extends BufferGeometry {
 
                thresholdAngle = ( thresholdAngle !== undefined ) ? thresholdAngle : 1;
 
-               if ( geometry.isGeometry ) {
+               if ( geometry.isGeometry === true ) {
 
-                       geometry = new BufferGeometry().fromGeometry( geometry );
+                       console.error( 'THREE.EdgesGeometry no longer supports THREE.Geometry. Use THREE.BufferGeometry instead.' );
+                       return;
 
                }
 
@@ -30686,13 +28858,13 @@ function addContour( vertices, contour ) {
  * }
  */
 
-class ExtrudeBufferGeometry extends BufferGeometry {
+class ExtrudeGeometry extends BufferGeometry {
 
        constructor( shapes, options ) {
 
                super();
 
-               this.type = 'ExtrudeBufferGeometry';
+               this.type = 'ExtrudeGeometry';
 
                this.parameters = {
                        shapes: shapes,
@@ -30835,7 +29007,7 @@ class ExtrudeBufferGeometry extends BufferGeometry {
 
                        function scalePt2( pt, vec, size ) {
 
-                               if ( ! vec ) console.error( "THREE.ExtrudeGeometry: vec does not exist" );
+                               if ( ! vec ) console.error( 'THREE.ExtrudeGeometry: vec does not exist' );
 
                                return vec.clone().multiplyScalar( size ).add( pt );
 
@@ -31441,86 +29613,7 @@ function toJSON( shapes, options, data ) {
 
 }
 
-/**
- * Creates extruded geometry from a path shape.
- *
- * parameters = {
- *
- *  curveSegments: <int>, // number of points on the curves
- *  steps: <int>, // number of points for z-side extrusions / used for subdividing segments of extrude spline too
- *  depth: <float>, // Depth to extrude the shape
- *
- *  bevelEnabled: <bool>, // turn on bevel
- *  bevelThickness: <float>, // how deep into the original shape bevel goes
- *  bevelSize: <float>, // how far from shape outline (including bevelOffset) is bevel
- *  bevelOffset: <float>, // how far from shape outline does bevel start
- *  bevelSegments: <int>, // number of bevel layers
- *
- *  extrudePath: <THREE.Curve> // curve to extrude shape along
- *
- *  UVGenerator: <Object> // object that provides UV generator functions
- *
- * }
- */
-
-class ExtrudeGeometry extends Geometry {
-
-       constructor( shapes, options ) {
-
-               super();
-
-               this.type = 'ExtrudeGeometry';
-
-               this.parameters = {
-                       shapes: shapes,
-                       options: options
-               };
-
-               this.fromBufferGeometry( new ExtrudeBufferGeometry( shapes, options ) );
-               this.mergeVertices();
-
-       }
-
-       toJSON() {
-
-               const data = super.toJSON();
-
-               const shapes = this.parameters.shapes;
-               const options = this.parameters.options;
-
-               return toJSON$1( shapes, options, data );
-
-       }
-
-}
-
-function toJSON$1( shapes, options, data ) {
-
-       data.shapes = [];
-
-       if ( Array.isArray( shapes ) ) {
-
-               for ( let i = 0, l = shapes.length; i < l; i ++ ) {
-
-                       const shape = shapes[ i ];
-
-                       data.shapes.push( shape.uuid );
-
-               }
-
-       } else {
-
-               data.shapes.push( shapes.uuid );
-
-       }
-
-       if ( options.extrudePath !== undefined ) data.options.extrudePath = options.extrudePath.toJSON();
-
-       return data;
-
-}
-
-class IcosahedronBufferGeometry extends PolyhedronBufferGeometry {
+class IcosahedronGeometry extends PolyhedronGeometry {
 
        constructor( radius = 1, detail = 0 ) {
 
@@ -31541,23 +29634,6 @@ class IcosahedronBufferGeometry extends PolyhedronBufferGeometry {
 
                super( vertices, indices, radius, detail );
 
-               this.type = 'IcosahedronBufferGeometry';
-
-               this.parameters = {
-                       radius: radius,
-                       detail: detail
-               };
-
-       }
-
-}
-
-class IcosahedronGeometry extends Geometry {
-
-       constructor( radius, detail ) {
-
-               super();
-
                this.type = 'IcosahedronGeometry';
 
                this.parameters = {
@@ -31565,20 +29641,17 @@ class IcosahedronGeometry extends Geometry {
                        detail: detail
                };
 
-               this.fromBufferGeometry( new IcosahedronBufferGeometry( radius, detail ) );
-               this.mergeVertices();
-
        }
 
 }
 
-class LatheBufferGeometry extends BufferGeometry {
+class LatheGeometry extends BufferGeometry {
 
        constructor( points, segments = 12, phiStart = 0, phiLength = Math.PI * 2 ) {
 
                super();
 
-               this.type = 'LatheBufferGeometry';
+               this.type = 'LatheGeometry';
 
                this.parameters = {
                        points: points,
@@ -31714,29 +29787,7 @@ class LatheBufferGeometry extends BufferGeometry {
 
 }
 
-class LatheGeometry extends Geometry {
-
-       constructor( points, segments, phiStart, phiLength ) {
-
-               super();
-
-               this.type = 'LatheGeometry';
-
-               this.parameters = {
-                       points: points,
-                       segments: segments,
-                       phiStart: phiStart,
-                       phiLength: phiLength
-               };
-
-               this.fromBufferGeometry( new LatheBufferGeometry( points, segments, phiStart, phiLength ) );
-               this.mergeVertices();
-
-       }
-
-}
-
-class OctahedronBufferGeometry extends PolyhedronBufferGeometry {
+class OctahedronGeometry extends PolyhedronGeometry {
 
        constructor( radius = 1, detail = 0 ) {
 
@@ -31753,23 +29804,6 @@ class OctahedronBufferGeometry extends PolyhedronBufferGeometry {
 
                super( vertices, indices, radius, detail );
 
-               this.type = 'OctahedronBufferGeometry';
-
-               this.parameters = {
-                       radius: radius,
-                       detail: detail
-               };
-
-       }
-
-}
-
-class OctahedronGeometry extends Geometry {
-
-       constructor( radius, detail ) {
-
-               super();
-
                this.type = 'OctahedronGeometry';
 
                this.parameters = {
@@ -31777,9 +29811,6 @@ class OctahedronGeometry extends Geometry {
                        detail: detail
                };
 
-               this.fromBufferGeometry( new OctahedronBufferGeometry( radius, detail ) );
-               this.mergeVertices();
-
        }
 
 }
@@ -31789,11 +29820,11 @@ class OctahedronGeometry extends Geometry {
  * based on the brilliant article by @prideout https://prideout.net/blog/old/blog/index.html@p=44.html
  */
 
-function ParametricBufferGeometry( func, slices, stacks ) {
+function ParametricGeometry( func, slices, stacks ) {
 
        BufferGeometry.call( this );
 
-       this.type = 'ParametricBufferGeometry';
+       this.type = 'ParametricGeometry';
 
        this.parameters = {
                func: func,
@@ -31908,85 +29939,16 @@ function ParametricBufferGeometry( func, slices, stacks ) {
 
 }
 
-ParametricBufferGeometry.prototype = Object.create( BufferGeometry.prototype );
-ParametricBufferGeometry.prototype.constructor = ParametricBufferGeometry;
-
-/**
- * Parametric Surfaces Geometry
- * based on the brilliant article by @prideout https://prideout.net/blog/old/blog/index.html@p=44.html
- */
-
-function ParametricGeometry( func, slices, stacks ) {
-
-       Geometry.call( this );
-
-       this.type = 'ParametricGeometry';
-
-       this.parameters = {
-               func: func,
-               slices: slices,
-               stacks: stacks
-       };
-
-       this.fromBufferGeometry( new ParametricBufferGeometry( func, slices, stacks ) );
-       this.mergeVertices();
-
-}
-
-ParametricGeometry.prototype = Object.create( Geometry.prototype );
+ParametricGeometry.prototype = Object.create( BufferGeometry.prototype );
 ParametricGeometry.prototype.constructor = ParametricGeometry;
 
-class PlaneGeometry extends Geometry {
-
-       constructor( width, height, widthSegments, heightSegments ) {
-
-               super();
-
-               this.type = 'PlaneGeometry';
-
-               this.parameters = {
-                       width: width,
-                       height: height,
-                       widthSegments: widthSegments,
-                       heightSegments: heightSegments
-               };
-
-               this.fromBufferGeometry( new PlaneBufferGeometry( width, height, widthSegments, heightSegments ) );
-               this.mergeVertices();
-
-       }
-
-}
-
-class PolyhedronGeometry extends Geometry {
-
-       constructor( vertices, indices, radius, detail ) {
-
-               super();
-
-               this.type = 'PolyhedronGeometry';
-
-               this.parameters = {
-                       vertices: vertices,
-                       indices: indices,
-                       radius: radius,
-                       detail: detail
-               };
-
-               this.fromBufferGeometry( new PolyhedronBufferGeometry( vertices, indices, radius, detail ) );
-               this.mergeVertices();
-
-       }
-
-}
-
-class RingBufferGeometry extends BufferGeometry {
+class RingGeometry extends BufferGeometry {
 
        constructor( innerRadius = 0.5, outerRadius = 1, thetaSegments = 8, phiSegments = 1, thetaStart = 0, thetaLength = Math.PI * 2 ) {
 
                super();
 
-               this.type = 'RingBufferGeometry';
+               this.type = 'RingGeometry';
 
                this.parameters = {
                        innerRadius: innerRadius,
@@ -32085,36 +30047,12 @@ class RingBufferGeometry extends BufferGeometry {
 
 }
 
-class RingGeometry extends Geometry {
-
-       constructor( innerRadius, outerRadius, thetaSegments, phiSegments, thetaStart, thetaLength ) {
-
-               super();
-
-               this.type = 'RingGeometry';
-
-               this.parameters = {
-                       innerRadius: innerRadius,
-                       outerRadius: outerRadius,
-                       thetaSegments: thetaSegments,
-                       phiSegments: phiSegments,
-                       thetaStart: thetaStart,
-                       thetaLength: thetaLength
-               };
-
-               this.fromBufferGeometry( new RingBufferGeometry( innerRadius, outerRadius, thetaSegments, phiSegments, thetaStart, thetaLength ) );
-               this.mergeVertices();
-
-       }
-
-}
-
-class ShapeBufferGeometry extends BufferGeometry {
+class ShapeGeometry extends BufferGeometry {
 
        constructor( shapes, curveSegments = 12 ) {
 
                super();
-               this.type = 'ShapeBufferGeometry';
+               this.type = 'ShapeGeometry';
 
                this.parameters = {
                        shapes: shapes,
@@ -32240,13 +30178,13 @@ class ShapeBufferGeometry extends BufferGeometry {
 
                const shapes = this.parameters.shapes;
 
-               return toJSON$2( shapes, data );
+               return toJSON$1( shapes, data );
 
        }
 
 }
 
-function toJSON$2( shapes, data ) {
+function toJSON$1( shapes, data ) {
 
        data.shapes = [];
 
@@ -32270,73 +30208,12 @@ function toJSON$2( shapes, data ) {
 
 }
 
-class ShapeGeometry extends Geometry {
-
-       constructor( shapes, curveSegments ) {
-
-               super();
-               this.type = 'ShapeGeometry';
-
-               if ( typeof curveSegments === 'object' ) {
-
-                       console.warn( 'THREE.ShapeGeometry: Options parameter has been removed.' );
-
-                       curveSegments = curveSegments.curveSegments;
-
-               }
-
-               this.parameters = {
-                       shapes: shapes,
-                       curveSegments: curveSegments
-               };
-
-               this.fromBufferGeometry( new ShapeBufferGeometry( shapes, curveSegments ) );
-               this.mergeVertices();
-
-       }
-
-       toJSON() {
-
-               const data = Geometry.prototype.toJSON.call( this );
-
-               const shapes = this.parameters.shapes;
-
-               return toJSON$3( shapes, data );
-
-       }
-
-}
-
-function toJSON$3( shapes, data ) {
-
-       data.shapes = [];
-
-       if ( Array.isArray( shapes ) ) {
-
-               for ( let i = 0, l = shapes.length; i < l; i ++ ) {
-
-                       const shape = shapes[ i ];
-
-                       data.shapes.push( shape.uuid );
-
-               }
-
-       } else {
-
-               data.shapes.push( shapes.uuid );
-
-       }
-
-       return data;
-
-}
-
-class SphereBufferGeometry extends BufferGeometry {
+class SphereGeometry extends BufferGeometry {
 
        constructor( radius = 1, widthSegments = 8, heightSegments = 6, phiStart = 0, phiLength = Math.PI * 2, thetaStart = 0, thetaLength = Math.PI ) {
 
                super();
-               this.type = 'SphereBufferGeometry';
+               this.type = 'SphereGeometry';
 
                this.parameters = {
                        radius: radius,
@@ -32446,31 +30323,7 @@ class SphereBufferGeometry extends BufferGeometry {
 
 }
 
-class SphereGeometry extends Geometry {
-
-       constructor( radius, widthSegments, heightSegments, phiStart, phiLength, thetaStart, thetaLength ) {
-
-               super();
-               this.type = 'SphereGeometry';
-
-               this.parameters = {
-                       radius: radius,
-                       widthSegments: widthSegments,
-                       heightSegments: heightSegments,
-                       phiStart: phiStart,
-                       phiLength: phiLength,
-                       thetaStart: thetaStart,
-                       thetaLength: thetaLength
-               };
-
-               this.fromBufferGeometry( new SphereBufferGeometry( radius, widthSegments, heightSegments, phiStart, phiLength, thetaStart, thetaLength ) );
-               this.mergeVertices();
-
-       }
-
-}
-
-class TetrahedronBufferGeometry extends PolyhedronBufferGeometry {
+class TetrahedronGeometry extends PolyhedronGeometry {
 
        constructor( radius = 1, detail = 0 ) {
 
@@ -32484,22 +30337,6 @@ class TetrahedronBufferGeometry extends PolyhedronBufferGeometry {
 
                super( vertices, indices, radius, detail );
 
-               this.type = 'TetrahedronBufferGeometry';
-
-               this.parameters = {
-                       radius: radius,
-                       detail: detail
-               };
-
-       }
-
-}
-
-class TetrahedronGeometry extends Geometry {
-
-       constructor( radius, detail ) {
-
-               super();
                this.type = 'TetrahedronGeometry';
 
                this.parameters = {
@@ -32507,9 +30344,6 @@ class TetrahedronGeometry extends Geometry {
                        detail: detail
                };
 
-               this.fromBufferGeometry( new TetrahedronBufferGeometry( radius, detail ) );
-               this.mergeVertices();
-
        }
 
 }
@@ -32531,7 +30365,7 @@ class TetrahedronGeometry extends Geometry {
  * }
  */
 
-class TextBufferGeometry extends ExtrudeBufferGeometry {
+class TextGeometry extends ExtrudeGeometry {
 
        constructor( text, parameters = {} ) {
 
@@ -32558,54 +30392,18 @@ class TextBufferGeometry extends ExtrudeBufferGeometry {
 
                super( shapes, parameters );
 
-               this.type = 'TextBufferGeometry';
-
-       }
-
-}
-
-/**
- * Text = 3D Text
- *
- * parameters = {
- *  font: <THREE.Font>, // font
- *
- *  size: <float>, // size of the text
- *  height: <float>, // thickness to extrude text
- *  curveSegments: <int>, // number of points on the curves
- *
- *  bevelEnabled: <bool>, // turn on bevel
- *  bevelThickness: <float>, // how deep into text bevel goes
- *  bevelSize: <float>, // how far from text outline (including bevelOffset) is bevel
- *  bevelOffset: <float> // how far from text outline does bevel start
- * }
- */
-
-class TextGeometry extends Geometry {
-
-       constructor( text, parameters ) {
-
-               super();
                this.type = 'TextGeometry';
 
-               this.parameters = {
-                       text: text,
-                       parameters: parameters
-               };
-
-               this.fromBufferGeometry( new TextBufferGeometry( text, parameters ) );
-               this.mergeVertices();
-
        }
 
 }
 
-class TorusBufferGeometry extends BufferGeometry {
+class TorusGeometry extends BufferGeometry {
 
        constructor( radius = 1, tube = 0.4, radialSegments = 8, tubularSegments = 6, arc = Math.PI * 2 ) {
 
                super();
-               this.type = 'TorusBufferGeometry';
+               this.type = 'TorusGeometry';
 
                this.parameters = {
                        radius: radius,
@@ -32698,34 +30496,12 @@ class TorusBufferGeometry extends BufferGeometry {
 
 }
 
-class TorusGeometry extends Geometry {
-
-       constructor( radius, tube, radialSegments, tubularSegments, arc ) {
-
-               super();
-               this.type = 'TorusGeometry';
-
-               this.parameters = {
-                       radius: radius,
-                       tube: tube,
-                       radialSegments: radialSegments,
-                       tubularSegments: tubularSegments,
-                       arc: arc
-               };
-
-               this.fromBufferGeometry( new TorusBufferGeometry( radius, tube, radialSegments, tubularSegments, arc ) );
-               this.mergeVertices();
-
-       }
-
-}
-
-class TorusKnotBufferGeometry extends BufferGeometry {
+class TorusKnotGeometry extends BufferGeometry {
 
        constructor( radius = 1, tube = 0.4, tubularSegments = 64, radialSegments = 8, p = 2, q = 3 ) {
 
                super();
-               this.type = 'TorusKnotBufferGeometry';
+               this.type = 'TorusKnotGeometry';
 
                this.parameters = {
                        radius: radius,
@@ -32865,37 +30641,12 @@ class TorusKnotBufferGeometry extends BufferGeometry {
 
 }
 
-class TorusKnotGeometry extends Geometry {
-
-       constructor( radius, tube, tubularSegments, radialSegments, p, q, heightScale ) {
-
-               super();
-               this.type = 'TorusKnotGeometry';
-
-               this.parameters = {
-                       radius: radius,
-                       tube: tube,
-                       tubularSegments: tubularSegments,
-                       radialSegments: radialSegments,
-                       p: p,
-                       q: q
-               };
-
-               if ( heightScale !== undefined ) console.warn( 'THREE.TorusKnotGeometry: heightScale has been deprecated. Use .scale( x, y, z ) instead.' );
-
-               this.fromBufferGeometry( new TorusKnotBufferGeometry( radius, tube, tubularSegments, radialSegments, p, q ) );
-               this.mergeVertices();
-
-       }
-
-}
-
-class TubeBufferGeometry extends BufferGeometry {
+class TubeGeometry extends BufferGeometry {
 
        constructor( path, tubularSegments = 64, radius = 1, radialSegments = 8, closed = false ) {
 
                super();
-               this.type = 'TubeBufferGeometry';
+               this.type = 'TubeGeometry';
 
                this.parameters = {
                        path: path,
@@ -33059,80 +30810,69 @@ class TubeBufferGeometry extends BufferGeometry {
 
 }
 
-class TubeGeometry extends Geometry {
+class WireframeGeometry extends BufferGeometry {
 
-       constructor( path, tubularSegments, radius, radialSegments, closed, taper ) {
+       constructor( geometry ) {
 
                super();
-               this.type = 'TubeGeometry';
-
-               this.parameters = {
-                       path: path,
-                       tubularSegments: tubularSegments,
-                       radius: radius,
-                       radialSegments: radialSegments,
-                       closed: closed
-               };
-
-               if ( taper !== undefined ) console.warn( 'THREE.TubeGeometry: taper has been removed.' );
+               this.type = 'WireframeGeometry';
 
-               const bufferGeometry = new TubeBufferGeometry( path, tubularSegments, radius, radialSegments, closed );
+               if ( geometry.isGeometry === true ) {
 
-               // expose internals
+                       console.error( 'THREE.WireframeGeometry no longer supports THREE.Geometry. Use THREE.BufferGeometry instead.' );
+                       return;
 
-               this.tangents = bufferGeometry.tangents;
-               this.normals = bufferGeometry.normals;
-               this.binormals = bufferGeometry.binormals;
+               }
 
-               // create geometry
+               // buffer
 
-               this.fromBufferGeometry( bufferGeometry );
-               this.mergeVertices();
+               const vertices = [];
 
-       }
+               // helper variables
 
-}
+               const edge = [ 0, 0 ], edges = {};
 
-class WireframeGeometry extends BufferGeometry {
+               const vertex = new Vector3();
 
-       constructor( geometry ) {
+               if ( geometry.index !== null ) {
 
-               super();
-               this.type = 'WireframeGeometry';
+                       // indexed BufferGeometry
 
-               // buffer
+                       const position = geometry.attributes.position;
+                       const indices = geometry.index;
+                       let groups = geometry.groups;
 
-               const vertices = [];
+                       if ( groups.length === 0 ) {
 
-               // helper variables
+                               groups = [ { start: 0, count: indices.count, materialIndex: 0 } ];
 
-               const edge = [ 0, 0 ], edges = {};
-               const keys = [ 'a', 'b', 'c' ];
+                       }
 
-               // different logic for Geometry and BufferGeometry
+                       // create a data structure that contains all eges without duplicates
 
-               if ( geometry && geometry.isGeometry ) {
+                       for ( let o = 0, ol = groups.length; o < ol; ++ o ) {
 
-                       // create a data structure that contains all edges without duplicates
+                               const group = groups[ o ];
 
-                       const faces = geometry.faces;
+                               const start = group.start;
+                               const count = group.count;
 
-                       for ( let i = 0, l = faces.length; i < l; i ++ ) {
+                               for ( let i = start, l = ( start + count ); i < l; i += 3 ) {
 
-                               const face = faces[ i ];
+                                       for ( let j = 0; j < 3; j ++ ) {
 
-                               for ( let j = 0; j < 3; j ++ ) {
+                                               const edge1 = indices.getX( i + j );
+                                               const edge2 = indices.getX( i + ( j + 1 ) % 3 );
+                                               edge[ 0 ] = Math.min( edge1, edge2 ); // sorting prevents duplicates
+                                               edge[ 1 ] = Math.max( edge1, edge2 );
 
-                                       const edge1 = face[ keys[ j ] ];
-                                       const edge2 = face[ keys[ ( j + 1 ) % 3 ] ];
-                                       edge[ 0 ] = Math.min( edge1, edge2 ); // sorting prevents duplicates
-                                       edge[ 1 ] = Math.max( edge1, edge2 );
+                                               const key = edge[ 0 ] + ',' + edge[ 1 ];
 
-                                       const key = edge[ 0 ] + ',' + edge[ 1 ];
+                                               if ( edges[ key ] === undefined ) {
 
-                                       if ( edges[ key ] === undefined ) {
+                                                       edges[ key ] = { index1: edge[ 0 ], index2: edge[ 1 ] };
 
-                                               edges[ key ] = { index1: edge[ 0 ], index2: edge[ 1 ] };
+                                               }
 
                                        }
 
@@ -33146,103 +30886,37 @@ class WireframeGeometry extends BufferGeometry {
 
                                const e = edges[ key ];
 
-                               let vertex = geometry.vertices[ e.index1 ];
+                               vertex.fromBufferAttribute( position, e.index1 );
                                vertices.push( vertex.x, vertex.y, vertex.z );
 
-                               vertex = geometry.vertices[ e.index2 ];
+                               vertex.fromBufferAttribute( position, e.index2 );
                                vertices.push( vertex.x, vertex.y, vertex.z );
 
                        }
 
-               } else if ( geometry && geometry.isBufferGeometry ) {
-
-                       const vertex = new Vector3();
-
-                       if ( geometry.index !== null ) {
-
-                               // indexed BufferGeometry
-
-                               const position = geometry.attributes.position;
-                               const indices = geometry.index;
-                               let groups = geometry.groups;
-
-                               if ( groups.length === 0 ) {
-
-                                       groups = [ { start: 0, count: indices.count, materialIndex: 0 } ];
-
-                               }
-
-                               // create a data structure that contains all eges without duplicates
-
-                               for ( let o = 0, ol = groups.length; o < ol; ++ o ) {
-
-                                       const group = groups[ o ];
-
-                                       const start = group.start;
-                                       const count = group.count;
-
-                                       for ( let i = start, l = ( start + count ); i < l; i += 3 ) {
-
-                                               for ( let j = 0; j < 3; j ++ ) {
-
-                                                       const edge1 = indices.getX( i + j );
-                                                       const edge2 = indices.getX( i + ( j + 1 ) % 3 );
-                                                       edge[ 0 ] = Math.min( edge1, edge2 ); // sorting prevents duplicates
-                                                       edge[ 1 ] = Math.max( edge1, edge2 );
-
-                                                       const key = edge[ 0 ] + ',' + edge[ 1 ];
-
-                                                       if ( edges[ key ] === undefined ) {
-
-                                                               edges[ key ] = { index1: edge[ 0 ], index2: edge[ 1 ] };
-
-                                                       }
-
-                                               }
+               } else {
 
-                                       }
+                       // non-indexed BufferGeometry
 
-                               }
+                       const position = geometry.attributes.position;
 
-                               // generate vertices
+                       for ( let i = 0, l = ( position.count / 3 ); i < l; i ++ ) {
 
-                               for ( const key in edges ) {
+                               for ( let j = 0; j < 3; j ++ ) {
 
-                                       const e = edges[ key ];
+                                       // three edges per triangle, an edge is represented as (index1, index2)
+                                       // e.g. the first triangle has the following edges: (0,1),(1,2),(2,0)
 
-                                       vertex.fromBufferAttribute( position, e.index1 );
+                                       const index1 = 3 * i + j;
+                                       vertex.fromBufferAttribute( position, index1 );
                                        vertices.push( vertex.x, vertex.y, vertex.z );
 
-                                       vertex.fromBufferAttribute( position, e.index2 );
+                                       const index2 = 3 * i + ( ( j + 1 ) % 3 );
+                                       vertex.fromBufferAttribute( position, index2 );
                                        vertices.push( vertex.x, vertex.y, vertex.z );
 
                                }
 
-                       } else {
-
-                               // non-indexed BufferGeometry
-
-                               const position = geometry.attributes.position;
-
-                               for ( let i = 0, l = ( position.count / 3 ); i < l; i ++ ) {
-
-                                       for ( let j = 0; j < 3; j ++ ) {
-
-                                               // three edges per triangle, an edge is represented as (index1, index2)
-                                               // e.g. the first triangle has the following edges: (0,1),(1,2),(2,0)
-
-                                               const index1 = 3 * i + j;
-                                               vertex.fromBufferAttribute( position, index1 );
-                                               vertices.push( vertex.x, vertex.y, vertex.z );
-
-                                               const index2 = 3 * i + ( ( j + 1 ) % 3 );
-                                               vertex.fromBufferAttribute( position, index2 );
-                                               vertices.push( vertex.x, vertex.y, vertex.z );
-
-                                       }
-
-                               }
-
                        }
 
                }
@@ -33258,46 +30932,46 @@ class WireframeGeometry extends BufferGeometry {
 var Geometries = /*#__PURE__*/Object.freeze({
        __proto__: null,
        BoxGeometry: BoxGeometry,
-       BoxBufferGeometry: BoxBufferGeometry,
+       BoxBufferGeometry: BoxGeometry,
        CircleGeometry: CircleGeometry,
-       CircleBufferGeometry: CircleBufferGeometry,
+       CircleBufferGeometry: CircleGeometry,
        ConeGeometry: ConeGeometry,
-       ConeBufferGeometry: ConeBufferGeometry,
+       ConeBufferGeometry: ConeGeometry,
        CylinderGeometry: CylinderGeometry,
-       CylinderBufferGeometry: CylinderBufferGeometry,
+       CylinderBufferGeometry: CylinderGeometry,
        DodecahedronGeometry: DodecahedronGeometry,
-       DodecahedronBufferGeometry: DodecahedronBufferGeometry,
+       DodecahedronBufferGeometry: DodecahedronGeometry,
        EdgesGeometry: EdgesGeometry,
        ExtrudeGeometry: ExtrudeGeometry,
-       ExtrudeBufferGeometry: ExtrudeBufferGeometry,
+       ExtrudeBufferGeometry: ExtrudeGeometry,
        IcosahedronGeometry: IcosahedronGeometry,
-       IcosahedronBufferGeometry: IcosahedronBufferGeometry,
+       IcosahedronBufferGeometry: IcosahedronGeometry,
        LatheGeometry: LatheGeometry,
-       LatheBufferGeometry: LatheBufferGeometry,
+       LatheBufferGeometry: LatheGeometry,
        OctahedronGeometry: OctahedronGeometry,
-       OctahedronBufferGeometry: OctahedronBufferGeometry,
+       OctahedronBufferGeometry: OctahedronGeometry,
        ParametricGeometry: ParametricGeometry,
-       ParametricBufferGeometry: ParametricBufferGeometry,
+       ParametricBufferGeometry: ParametricGeometry,
        PlaneGeometry: PlaneGeometry,
-       PlaneBufferGeometry: PlaneBufferGeometry,
+       PlaneBufferGeometry: PlaneGeometry,
        PolyhedronGeometry: PolyhedronGeometry,
-       PolyhedronBufferGeometry: PolyhedronBufferGeometry,
+       PolyhedronBufferGeometry: PolyhedronGeometry,
        RingGeometry: RingGeometry,
-       RingBufferGeometry: RingBufferGeometry,
+       RingBufferGeometry: RingGeometry,
        ShapeGeometry: ShapeGeometry,
-       ShapeBufferGeometry: ShapeBufferGeometry,
+       ShapeBufferGeometry: ShapeGeometry,
        SphereGeometry: SphereGeometry,
-       SphereBufferGeometry: SphereBufferGeometry,
+       SphereBufferGeometry: SphereGeometry,
        TetrahedronGeometry: TetrahedronGeometry,
-       TetrahedronBufferGeometry: TetrahedronBufferGeometry,
+       TetrahedronBufferGeometry: TetrahedronGeometry,
        TextGeometry: TextGeometry,
-       TextBufferGeometry: TextBufferGeometry,
+       TextBufferGeometry: TextGeometry,
        TorusGeometry: TorusGeometry,
-       TorusBufferGeometry: TorusBufferGeometry,
+       TorusBufferGeometry: TorusGeometry,
        TorusKnotGeometry: TorusKnotGeometry,
-       TorusKnotBufferGeometry: TorusKnotBufferGeometry,
+       TorusKnotBufferGeometry: TorusKnotGeometry,
        TubeGeometry: TubeGeometry,
-       TubeBufferGeometry: TubeBufferGeometry,
+       TubeBufferGeometry: TubeGeometry,
        WireframeGeometry: WireframeGeometry
 });
 
@@ -35233,8 +32907,8 @@ Object.assign( KeyframeTrack.prototype, {
 
                if ( factoryMethod === undefined ) {
 
-                       const message = "unsupported interpolation for " +
-                               this.ValueTypeName + " keyframe track named " + this.name;
+                       const message = 'unsupported interpolation for ' +
+                               this.ValueTypeName + ' keyframe track named ' + this.name;
 
                        if ( this.createInterpolant === undefined ) {
 
@@ -35471,7 +33145,7 @@ Object.assign( KeyframeTrack.prototype, {
 
                        // remove adjacent keyframes scheduled at the same time
 
-                       if ( time !== timeNext && ( i !== 1 || time !== time[ 0 ] ) ) {
+                       if ( time !== timeNext && ( i !== 1 || time !== times[ 0 ] ) ) {
 
                                if ( ! smoothInterpolation ) {
 
@@ -35765,12 +33439,12 @@ VectorKeyframeTrack.prototype = Object.assign( Object.create( KeyframeTrack.prot
 
 } );
 
-function AnimationClip( name, duration, tracks, blendMode ) {
+function AnimationClip( name, duration = - 1, tracks, blendMode = NormalAnimationBlendMode ) {
 
        this.name = name;
        this.tracks = tracks;
-       this.duration = ( duration !== undefined ) ? duration : - 1;
-       this.blendMode = ( blendMode !== undefined ) ? blendMode : NormalAnimationBlendMode;
+       this.duration = duration;
+       this.blendMode = blendMode;
 
        this.uuid = MathUtils.generateUUID();
 
@@ -36852,7 +34526,6 @@ CompressedTextureLoader.prototype = Object.assign( Object.create( Loader.prototy
                const images = [];
 
                const texture = new CompressedTexture();
-               texture.image = images;
 
                const loader = new FileLoader( this.manager );
                loader.setPath( this.path );
@@ -36879,9 +34552,9 @@ CompressedTextureLoader.prototype = Object.assign( Object.create( Loader.prototy
 
                                if ( loaded === 6 ) {
 
-                                       if ( texDatas.mipmapCount === 1 )
-                                               texture.minFilter = LinearFilter;
+                                       if ( texDatas.mipmapCount === 1 ) texture.minFilter = LinearFilter;
 
+                                       texture.image = images;
                                        texture.format = texDatas.format;
                                        texture.needsUpdate = true;
 
@@ -36928,6 +34601,8 @@ CompressedTextureLoader.prototype = Object.assign( Object.create( Loader.prototy
 
                                        }
 
+                                       texture.image = images;
+
                                } else {
 
                                        texture.image.width = texDatas.width;
@@ -37144,6 +34819,18 @@ DataTextureLoader.prototype = Object.assign( Object.create( Loader.prototype ),
 
                        texture.anisotropy = texData.anisotropy !== undefined ? texData.anisotropy : 1;
 
+                       if ( texData.encoding !== undefined ) {
+
+                               texture.encoding = texData.encoding;
+
+                       }
+
+                       if ( texData.flipY !== undefined ) {
+
+                               texture.flipY = texData.flipY;
+
+                       }
+
                        if ( texData.format !== undefined ) {
 
                                texture.format = texData.format;
@@ -39652,7 +37339,7 @@ PointLight.prototype = Object.assign( Object.create( Light.prototype ), {
 
 } );
 
-function OrthographicCamera( left, right, top, bottom, near, far ) {
+function OrthographicCamera( left = - 1, right = 1, top = 1, bottom = - 1, near = 0.1, far = 2000 ) {
 
        Camera.call( this );
 
@@ -39661,13 +37348,13 @@ function OrthographicCamera( left, right, top, bottom, near, far ) {
        this.zoom = 1;
        this.view = null;
 
-       this.left = ( left !== undefined ) ? left : - 1;
-       this.right = ( right !== undefined ) ? right : 1;
-       this.top = ( top !== undefined ) ? top : 1;
-       this.bottom = ( bottom !== undefined ) ? bottom : - 1;
+       this.left = left;
+       this.right = right;
+       this.top = top;
+       this.bottom = bottom;
 
-       this.near = ( near !== undefined ) ? near : 0.1;
-       this.far = ( far !== undefined ) ? far : 2000;
+       this.near = near;
+       this.far = far;
 
        this.updateProjectionMatrix();
 
@@ -40995,7 +38682,6 @@ class ObjectLoader extends Loader {
 
                                        case 'BoxGeometry':
                                        case 'BoxBufferGeometry':
-                                       case 'CubeGeometry': // backwards compatible
 
                                                geometry = new Geometries[ data.type ](
                                                        data.width,
@@ -41732,7 +39418,7 @@ class ObjectLoader extends Loader {
 
                        case 'Line':
 
-                               object = new Line( getGeometry( data.geometry ), getMaterial( data.material ), data.mode );
+                               object = new Line( getGeometry( data.geometry ), getMaterial( data.material ) );
 
                                break;
 
@@ -42315,19 +40001,19 @@ Object.assign( ShapePath.prototype, {
 
 } );
 
-function Font( data ) {
+class Font {
 
-       this.type = 'Font';
+       constructor( data ) {
 
-       this.data = data;
+               Object.defineProperty( this, 'isFont', { value: true } );
 
-}
+               this.type = 'Font';
 
-Object.assign( Font.prototype, {
+               this.data = data;
 
-       isFont: true,
+       }
 
-       generateShapes: function ( text, size = 100 ) {
+       generateShapes( text, size = 100 ) {
 
                const shapes = [];
                const paths = createPaths( text, size, this.data );
@@ -42342,7 +40028,7 @@ Object.assign( Font.prototype, {
 
        }
 
-} );
+}
 
 function createPaths( text, size, data ) {
 
@@ -44019,7 +41705,7 @@ Object.assign( PropertyBinding, {
 
        findNode: function ( root, nodeName ) {
 
-               if ( ! nodeName || nodeName === "" || nodeName === "." || nodeName === - 1 || nodeName === root.name || nodeName === root.uuid ) {
+               if ( ! nodeName || nodeName === '' || nodeName === '.' || nodeName === - 1 || nodeName === root.name || nodeName === root.uuid ) {
 
                        return root;
 
@@ -44422,7 +42108,7 @@ Object.assign( PropertyBinding.prototype, { // prototype, continued
 
                        // access a sub element of the property array (only primitives are supported right now)
 
-                       if ( propertyName === "morphTargetInfluences" ) {
+                       if ( propertyName === 'morphTargetInfluences' ) {
 
                                // potential optimization, skip this if propertyIndex is already an integer, and convert the integer string to a true integer.
 
@@ -46551,13 +44237,13 @@ Object.assign( Raycaster.prototype, {
 
        setFromCamera: function ( coords, camera ) {
 
-               if ( ( camera && camera.isPerspectiveCamera ) ) {
+               if ( camera && camera.isPerspectiveCamera ) {
 
                        this.ray.origin.setFromMatrixPosition( camera.matrixWorld );
                        this.ray.direction.set( coords.x, coords.y, 0.5 ).unproject( camera ).sub( this.ray.origin ).normalize();
                        this.camera = camera;
 
-               } else if ( ( camera && camera.isOrthographicCamera ) ) {
+               } else if ( camera && camera.isOrthographicCamera ) {
 
                        this.ray.origin.set( coords.x, coords.y, ( camera.near + camera.far ) / ( camera.near - camera.far ) ).unproject( camera ); // set origin in plane of camera
                        this.ray.direction.set( 0, 0, - 1 ).transformDirection( camera.matrixWorld );
@@ -46565,7 +44251,7 @@ Object.assign( Raycaster.prototype, {
 
                } else {
 
-                       console.error( 'THREE.Raycaster: Unsupported camera type.' );
+                       console.error( 'THREE.Raycaster: Unsupported camera type: ' + camera.type );
 
                }
 
@@ -46751,7 +44437,7 @@ class Cylindrical {
 
 }
 
-const _vector$7 = /*@__PURE__*/ new Vector2();
+const _vector$8 = /*@__PURE__*/ new Vector2();
 
 class Box2 {
 
@@ -46789,7 +44475,7 @@ class Box2 {
 
        setFromCenterAndSize( center, size ) {
 
-               const halfSize = _vector$7.copy( size ).multiplyScalar( 0.5 );
+               const halfSize = _vector$8.copy( size ).multiplyScalar( 0.5 );
                this.min.copy( center ).sub( halfSize );
                this.max.copy( center ).add( halfSize );
 
@@ -46939,7 +44625,7 @@ class Box2 {
 
        distanceToPoint( point ) {
 
-               const clampedPoint = _vector$7.copy( point ).clamp( this.min, this.max );
+               const clampedPoint = _vector$8.copy( point ).clamp( this.min, this.max );
                return clampedPoint.sub( point ).length();
 
        }
@@ -47144,7 +44830,7 @@ ImmediateRenderObject.prototype.constructor = ImmediateRenderObject;
 
 ImmediateRenderObject.prototype.isImmediateRenderObject = true;
 
-const _vector$8 = /*@__PURE__*/ new Vector3();
+const _vector$9 = /*@__PURE__*/ new Vector3();
 
 class SpotLightHelper extends Object3D {
 
@@ -47208,9 +44894,9 @@ class SpotLightHelper extends Object3D {
 
                this.cone.scale.set( coneWidth, coneWidth, coneLength );
 
-               _vector$8.setFromMatrixPosition( this.light.target.matrixWorld );
+               _vector$9.setFromMatrixPosition( this.light.target.matrixWorld );
 
-               this.cone.lookAt( _vector$8 );
+               this.cone.lookAt( _vector$9 );
 
                if ( this.color !== undefined ) {
 
@@ -47226,7 +44912,7 @@ class SpotLightHelper extends Object3D {
 
 }
 
-const _vector$9 = /*@__PURE__*/ new Vector3();
+const _vector$a = /*@__PURE__*/ new Vector3();
 const _boneMatrix = /*@__PURE__*/ new Matrix4();
 const _matrixWorldInv = /*@__PURE__*/ new Matrix4();
 
@@ -47294,12 +44980,12 @@ class SkeletonHelper extends LineSegments {
                        if ( bone.parent && bone.parent.isBone ) {
 
                                _boneMatrix.multiplyMatrices( _matrixWorldInv, bone.matrixWorld );
-                               _vector$9.setFromMatrixPosition( _boneMatrix );
-                               position.setXYZ( j, _vector$9.x, _vector$9.y, _vector$9.z );
+                               _vector$a.setFromMatrixPosition( _boneMatrix );
+                               position.setXYZ( j, _vector$a.x, _vector$a.y, _vector$a.z );
 
                                _boneMatrix.multiplyMatrices( _matrixWorldInv, bone.parent.matrixWorld );
-                               _vector$9.setFromMatrixPosition( _boneMatrix );
-                               position.setXYZ( j + 1, _vector$9.x, _vector$9.y, _vector$9.z );
+                               _vector$a.setFromMatrixPosition( _boneMatrix );
+                               position.setXYZ( j + 1, _vector$a.x, _vector$a.y, _vector$a.z );
 
                                j += 2;
 
@@ -47340,7 +45026,7 @@ class PointLightHelper extends Mesh {
 
        constructor( light, sphereSize, color ) {
 
-               const geometry = new SphereBufferGeometry( sphereSize, 4, 2 );
+               const geometry = new SphereGeometry( sphereSize, 4, 2 );
                const material = new MeshBasicMaterial( { wireframe: true, fog: false, toneMapped: false } );
 
                super( geometry, material );
@@ -47421,7 +45107,7 @@ class PointLightHelper extends Mesh {
 
 }
 
-const _vector$a = /*@__PURE__*/ new Vector3();
+const _vector$b = /*@__PURE__*/ new Vector3();
 const _color1 = /*@__PURE__*/ new Color();
 const _color2 = /*@__PURE__*/ new Color();
 
@@ -47438,7 +45124,7 @@ class HemisphereLightHelper extends Object3D {
 
                this.color = color;
 
-               const geometry = new OctahedronBufferGeometry( size );
+               const geometry = new OctahedronGeometry( size );
                geometry.rotateY( Math.PI * 0.5 );
 
                this.material = new MeshBasicMaterial( { wireframe: true, fog: false, toneMapped: false } );
@@ -47489,7 +45175,7 @@ class HemisphereLightHelper extends Object3D {
 
                }
 
-               mesh.lookAt( _vector$a.setFromMatrixPosition( this.light.matrixWorld ).negate() );
+               mesh.lookAt( _vector$b.setFromMatrixPosition( this.light.matrixWorld ).negate() );
 
        }
 
@@ -47692,7 +45378,7 @@ class DirectionalLightHelper extends Object3D {
 
 }
 
-const _vector$b = /*@__PURE__*/ new Vector3();
+const _vector$c = /*@__PURE__*/ new Vector3();
 const _camera = /*@__PURE__*/ new Camera();
 
 /**
@@ -47868,7 +45554,7 @@ class CameraHelper extends LineSegments {
 
 function setPoint( point, pointMap, geometry, camera, x, y, z ) {
 
-       _vector$b.set( x, y, z ).unproject( camera );
+       _vector$c.set( x, y, z ).unproject( camera );
 
        const points = pointMap[ point ];
 
@@ -47878,7 +45564,7 @@ function setPoint( point, pointMap, geometry, camera, x, y, z ) {
 
                for ( let i = 0, l = points.length; i < l; i ++ ) {
 
-                       position.setXYZ( points[ i ], _vector$b.x, _vector$b.y, _vector$b.z );
+                       position.setXYZ( points[ i ], _vector$c.x, _vector$c.y, _vector$c.z );
 
                }
 
@@ -48099,7 +45785,7 @@ class ArrowHelper extends Object3D {
                        _lineGeometry = new BufferGeometry();
                        _lineGeometry.setAttribute( 'position', new Float32BufferAttribute( [ 0, 0, 0, 0, 1, 0 ], 3 ) );
 
-                       _coneGeometry = new CylinderBufferGeometry( 0, 0.5, 1, 5, 1 );
+                       _coneGeometry = new CylinderGeometry( 0, 0.5, 1, 5, 1 );
                        _coneGeometry.translate( 0, - 0.5, 0 );
 
                }
@@ -48291,8 +45977,16 @@ const ENCODINGS = {
        [ GammaEncoding ]: 6
 };
 
+const backgroundMaterial = new MeshBasicMaterial( {
+       side: BackSide,
+       depthWrite: false,
+       depthTest: false,
+} );
+const backgroundBox = new Mesh( new BoxGeometry(), backgroundMaterial );
+
 const _flatCamera = /*@__PURE__*/ new OrthographicCamera();
 const { _lodPlanes, _sizeLods, _sigmas } = /*@__PURE__*/ _createPlanes();
+const _clearColor = /*@__PURE__*/ new Color();
 let _oldTarget = null;
 
 // Golden Ratio
@@ -48325,6 +46019,17 @@ const _axisDirections = [
  * interpolate diffuse lighting while limiting sampling computation.
  */
 
+function convertLinearToRGBE( color ) {
+
+       const maxComponent = Math.max( color.r, color.g, color.b );
+       const fExp = Math.min( Math.max( Math.ceil( Math.log2( maxComponent ) ), - 128.0 ), 127.0 );
+       color.multiplyScalar( Math.pow( 2.0, - fExp ) );
+
+       const alpha = ( fExp + 128.0 ) / 255.0;
+       return alpha;
+
+}
+
 class PMREMGenerator {
 
        constructor( renderer ) {
@@ -48496,28 +46201,41 @@ class PMREMGenerator {
                const forwardSign = [ 1, 1, 1, - 1, - 1, - 1 ];
                const renderer = this._renderer;
 
+               const originalAutoClear = renderer.autoClear;
                const outputEncoding = renderer.outputEncoding;
                const toneMapping = renderer.toneMapping;
-               const clearColor = renderer.getClearColor();
-               const clearAlpha = renderer.getClearAlpha();
+               renderer.getClearColor( _clearColor );
 
                renderer.toneMapping = NoToneMapping;
                renderer.outputEncoding = LinearEncoding;
+               renderer.autoClear = false;
+
+               let useSolidColor = false;
+               const background = scene.background;
+               if ( background ) {
 
-               let background = scene.background;
-               if ( background && background.isColor ) {
+                       if ( background.isColor ) {
 
-                       background.convertSRGBToLinear();
-                       // Convert linear to RGBE
-                       const maxComponent = Math.max( background.r, background.g, background.b );
-                       const fExp = Math.min( Math.max( Math.ceil( Math.log2( maxComponent ) ), - 128.0 ), 127.0 );
-                       background = background.multiplyScalar( Math.pow( 2.0, - fExp ) );
-                       const alpha = ( fExp + 128.0 ) / 255.0;
-                       renderer.setClearColor( background, alpha );
-                       scene.background = null;
+                               backgroundMaterial.color.copy( background ).convertSRGBToLinear();
+                               scene.background = null;
+
+                               const alpha = convertLinearToRGBE( backgroundMaterial.color );
+                               backgroundMaterial.opacity = alpha;
+                               useSolidColor = true;
+
+                       }
+
+               } else {
+
+                       backgroundMaterial.color.copy( _clearColor ).convertSRGBToLinear();
+
+                       const alpha = convertLinearToRGBE( backgroundMaterial.color );
+                       backgroundMaterial.opacity = alpha;
+                       useSolidColor = true;
 
                }
 
+
                for ( let i = 0; i < 6; i ++ ) {
 
                        const col = i % 3;
@@ -48541,13 +46259,20 @@ class PMREMGenerator {
                        _setViewport( cubeUVRenderTarget,
                                col * SIZE_MAX, i > 2 ? SIZE_MAX : 0, SIZE_MAX, SIZE_MAX );
                        renderer.setRenderTarget( cubeUVRenderTarget );
+
+                       if ( useSolidColor ) {
+
+                               renderer.render( backgroundBox, cubeCamera );
+
+                       }
+
                        renderer.render( scene, cubeCamera );
 
                }
 
                renderer.toneMapping = toneMapping;
                renderer.outputEncoding = outputEncoding;
-               renderer.setClearColor( clearColor, clearAlpha );
+               renderer.autoClear = originalAutoClear;
 
        }
 
@@ -49367,51 +47092,6 @@ Curve.create = function ( construct, getPoint ) {
 
 //
 
-Object.assign( CurvePath.prototype, {
-
-       createPointsGeometry: function ( divisions ) {
-
-               console.warn( 'THREE.CurvePath: .createPointsGeometry() has been removed. Use new THREE.Geometry().setFromPoints( points ) instead.' );
-
-               // generate geometry from path points (for Line or Points objects)
-
-               const pts = this.getPoints( divisions );
-               return this.createGeometry( pts );
-
-       },
-
-       createSpacedPointsGeometry: function ( divisions ) {
-
-               console.warn( 'THREE.CurvePath: .createSpacedPointsGeometry() has been removed. Use new THREE.Geometry().setFromPoints( points ) instead.' );
-
-               // generate geometry from equidistant sampling along the path
-
-               const pts = this.getSpacedPoints( divisions );
-               return this.createGeometry( pts );
-
-       },
-
-       createGeometry: function ( points ) {
-
-               console.warn( 'THREE.CurvePath: .createGeometry() has been removed. Use new THREE.Geometry().setFromPoints( points ) instead.' );
-
-               const geometry = new Geometry();
-
-               for ( let i = 0, l = points.length; i < l; i ++ ) {
-
-                       const point = points[ i ];
-                       geometry.vertices.push( new Vector3( point.x, point.y, point.z || 0 ) );
-
-               }
-
-               return geometry;
-
-       }
-
-} );
-
-//
-
 Object.assign( Path.prototype, {
 
        fromPoints: function ( points ) {
@@ -49686,7 +47366,7 @@ Object.assign( Matrix3.prototype, {
 
        flattenToArrayOffset: function ( array, offset ) {
 
-               console.warn( "THREE.Matrix3: .flattenToArrayOffset() has been deprecated. Use .toArray() instead." );
+               console.warn( 'THREE.Matrix3: .flattenToArrayOffset() has been deprecated. Use .toArray() instead.' );
                return this.toArray( array, offset );
 
        },
@@ -49731,7 +47411,7 @@ Object.assign( Matrix4.prototype, {
        },
        flattenToArrayOffset: function ( array, offset ) {
 
-               console.warn( "THREE.Matrix4: .flattenToArrayOffset() has been deprecated. Use .toArray() instead." );
+               console.warn( 'THREE.Matrix4: .flattenToArrayOffset() has been deprecated. Use .toArray() instead.' );
                return this.toArray( array, offset );
 
        },
@@ -50053,27 +47733,6 @@ Object.assign( Vector4.prototype, {
 
 //
 
-Object.assign( Geometry.prototype, {
-
-       computeTangents: function () {
-
-               console.error( 'THREE.Geometry: .computeTangents() has been removed.' );
-
-       },
-       computeLineDistances: function () {
-
-               console.error( 'THREE.Geometry: .computeLineDistances() has been removed. Use THREE.Line.computeLineDistances() instead.' );
-
-       },
-       applyMatrix: function ( matrix ) {
-
-               console.warn( 'THREE.Geometry: .applyMatrix() has been renamed to .applyMatrix4().' );
-               return this.applyMatrix4( matrix );
-
-       }
-
-} );
-
 Object.assign( Object3D.prototype, {
 
        getChildByName: function ( name ) {
@@ -50221,8 +47880,8 @@ Object.defineProperty( Curve.prototype, '__arcLengthDivisions', {
 
 PerspectiveCamera.prototype.setLens = function ( focalLength, filmGauge ) {
 
-       console.warn( "THREE.PerspectiveCamera.setLens is deprecated. " +
-                       "Use .setFocalLength and .filmGauge for a photographic setup." );
+       console.warn( 'THREE.PerspectiveCamera.setLens is deprecated. ' +
+                       'Use .setFocalLength and .filmGauge for a photographic setup.' );
 
        if ( filmGauge !== undefined ) this.filmGauge = filmGauge;
        this.setFocalLength( focalLength );
@@ -50433,11 +48092,6 @@ Object.assign( BufferGeometry.prototype, {
                console.warn( 'THREE.BufferGeometry: .clearDrawCalls() is now .clearGroups().' );
                this.clearGroups();
 
-       },
-       computeTangents: function () {
-
-               console.warn( 'THREE.BufferGeometry: .computeTangents() has been removed.' );
-
        },
        computeOffsets: function () {
 
@@ -50555,23 +48209,23 @@ Object.assign( InterleavedBuffer.prototype, {
 
 //
 
-Object.assign( ExtrudeBufferGeometry.prototype, {
+Object.assign( ExtrudeGeometry.prototype, {
 
        getArrays: function () {
 
-               console.error( 'THREE.ExtrudeBufferGeometry: .getArrays() has been removed.' );
+               console.error( 'THREE.ExtrudeGeometry: .getArrays() has been removed.' );
 
        },
 
        addShapeList: function () {
 
-               console.error( 'THREE.ExtrudeBufferGeometry: .addShapeList() has been removed.' );
+               console.error( 'THREE.ExtrudeGeometry: .addShapeList() has been removed.' );
 
        },
 
        addShape: function () {
 
-               console.error( 'THREE.ExtrudeBufferGeometry: .addShape() has been removed.' );
+               console.error( 'THREE.ExtrudeGeometry: .addShape() has been removed.' );
 
        }
 
@@ -51369,4 +49023,18 @@ if ( typeof __THREE_DEVTOOLS__ !== 'undefined' ) {
 
 }
 
-export { ACESFilmicToneMapping, AddEquation, AddOperation, AdditiveAnimationBlendMode, AdditiveBlending, AlphaFormat, AlwaysDepth, AlwaysStencilFunc, AmbientLight, AmbientLightProbe, AnimationClip, AnimationLoader, AnimationMixer, AnimationObjectGroup, AnimationUtils, ArcCurve, ArrayCamera, ArrowHelper, Audio, AudioAnalyser, AudioContext, AudioListener, AudioLoader, AxesHelper, AxisHelper, BackSide, BasicDepthPacking, BasicShadowMap, BinaryTextureLoader, Bone, BooleanKeyframeTrack, BoundingBoxHelper, Box2, Box3, Box3Helper, BoxBufferGeometry, BoxGeometry, BoxHelper, BufferAttribute, BufferGeometry, BufferGeometryLoader, ByteType, Cache, Camera, CameraHelper, CanvasRenderer, CanvasTexture, CatmullRomCurve3, CineonToneMapping, CircleBufferGeometry, CircleGeometry, ClampToEdgeWrapping, Clock, ClosedSplineCurve3, Color, ColorKeyframeTrack, CompressedTexture, CompressedTextureLoader, ConeBufferGeometry, ConeGeometry, CubeCamera, BoxGeometry as CubeGeometry, CubeReflectionMapping, CubeRefractionMapping, CubeTexture, CubeTextureLoader, CubeUVReflectionMapping, CubeUVRefractionMapping, CubicBezierCurve, CubicBezierCurve3, CubicInterpolant, CullFaceBack, CullFaceFront, CullFaceFrontBack, CullFaceNone, Curve, CurvePath, CustomBlending, CustomToneMapping, CylinderBufferGeometry, CylinderGeometry, Cylindrical, DataTexture, DataTexture2DArray, DataTexture3D, DataTextureLoader, DataUtils, DecrementStencilOp, DecrementWrapStencilOp, DefaultLoadingManager, DepthFormat, DepthStencilFormat, DepthTexture, DirectionalLight, DirectionalLightHelper, DiscreteInterpolant, DodecahedronBufferGeometry, DodecahedronGeometry, DoubleSide, DstAlphaFactor, DstColorFactor, DynamicBufferAttribute, DynamicCopyUsage, DynamicDrawUsage, DynamicReadUsage, EdgesGeometry, EdgesHelper, EllipseCurve, EqualDepth, EqualStencilFunc, EquirectangularReflectionMapping, EquirectangularRefractionMapping, Euler, EventDispatcher, ExtrudeBufferGeometry, ExtrudeGeometry, Face3, Face4, FaceColors, FileLoader, FlatShading, Float16BufferAttribute, Float32Attribute, Float32BufferAttribute, Float64Attribute, Float64BufferAttribute, FloatType, Fog, FogExp2, Font, FontLoader, FrontSide, Frustum, GLBufferAttribute, GLSL1, GLSL3, GammaEncoding, Geometry, GeometryUtils, GreaterDepth, GreaterEqualDepth, GreaterEqualStencilFunc, GreaterStencilFunc, GridHelper, Group, HalfFloatType, HemisphereLight, HemisphereLightHelper, HemisphereLightProbe, IcosahedronBufferGeometry, IcosahedronGeometry, ImageBitmapLoader, ImageLoader, ImageUtils, ImmediateRenderObject, IncrementStencilOp, IncrementWrapStencilOp, InstancedBufferAttribute, InstancedBufferGeometry, InstancedInterleavedBuffer, InstancedMesh, Int16Attribute, Int16BufferAttribute, Int32Attribute, Int32BufferAttribute, Int8Attribute, Int8BufferAttribute, IntType, InterleavedBuffer, InterleavedBufferAttribute, Interpolant, InterpolateDiscrete, InterpolateLinear, InterpolateSmooth, InvertStencilOp, JSONLoader, KeepStencilOp, KeyframeTrack, LOD, LatheBufferGeometry, LatheGeometry, Layers, LensFlare, LessDepth, LessEqualDepth, LessEqualStencilFunc, LessStencilFunc, Light, LightProbe, Line, Line3, LineBasicMaterial, LineCurve, LineCurve3, LineDashedMaterial, LineLoop, LinePieces, LineSegments, LineStrip, LinearEncoding, LinearFilter, LinearInterpolant, LinearMipMapLinearFilter, LinearMipMapNearestFilter, LinearMipmapLinearFilter, LinearMipmapNearestFilter, LinearToneMapping, Loader, LoaderUtils, LoadingManager, LogLuvEncoding, LoopOnce, LoopPingPong, LoopRepeat, LuminanceAlphaFormat, LuminanceFormat, MOUSE, Material, MaterialLoader, MathUtils as Math, MathUtils, Matrix3, Matrix4, MaxEquation, Mesh, MeshBasicMaterial, MeshDepthMaterial, MeshDistanceMaterial, MeshFaceMaterial, MeshLambertMaterial, MeshMatcapMaterial, MeshNormalMaterial, MeshPhongMaterial, MeshPhysicalMaterial, MeshStandardMaterial, MeshToonMaterial, MinEquation, MirroredRepeatWrapping, MixOperation, MultiMaterial, MultiplyBlending, MultiplyOperation, NearestFilter, NearestMipMapLinearFilter, NearestMipMapNearestFilter, NearestMipmapLinearFilter, NearestMipmapNearestFilter, NeverDepth, NeverStencilFunc, NoBlending, NoColors, NoToneMapping, NormalAnimationBlendMode, NormalBlending, NotEqualDepth, NotEqualStencilFunc, NumberKeyframeTrack, Object3D, ObjectLoader, ObjectSpaceNormalMap, OctahedronBufferGeometry, OctahedronGeometry, OneFactor, OneMinusDstAlphaFactor, OneMinusDstColorFactor, OneMinusSrcAlphaFactor, OneMinusSrcColorFactor, OrthographicCamera, PCFShadowMap, PCFSoftShadowMap, PMREMGenerator, ParametricBufferGeometry, ParametricGeometry, Particle, ParticleBasicMaterial, ParticleSystem, ParticleSystemMaterial, Path, PerspectiveCamera, Plane, PlaneBufferGeometry, PlaneGeometry, PlaneHelper, PointCloud, PointCloudMaterial, PointLight, PointLightHelper, Points, PointsMaterial, PolarGridHelper, PolyhedronBufferGeometry, PolyhedronGeometry, PositionalAudio, PropertyBinding, PropertyMixer, QuadraticBezierCurve, QuadraticBezierCurve3, Quaternion, QuaternionKeyframeTrack, QuaternionLinearInterpolant, REVISION, RGBADepthPacking, RGBAFormat, RGBAIntegerFormat, RGBA_ASTC_10x10_Format, RGBA_ASTC_10x5_Format, RGBA_ASTC_10x6_Format, RGBA_ASTC_10x8_Format, RGBA_ASTC_12x10_Format, RGBA_ASTC_12x12_Format, RGBA_ASTC_4x4_Format, RGBA_ASTC_5x4_Format, RGBA_ASTC_5x5_Format, RGBA_ASTC_6x5_Format, RGBA_ASTC_6x6_Format, RGBA_ASTC_8x5_Format, RGBA_ASTC_8x6_Format, RGBA_ASTC_8x8_Format, RGBA_BPTC_Format, RGBA_ETC2_EAC_Format, RGBA_PVRTC_2BPPV1_Format, RGBA_PVRTC_4BPPV1_Format, RGBA_S3TC_DXT1_Format, RGBA_S3TC_DXT3_Format, RGBA_S3TC_DXT5_Format, RGBDEncoding, RGBEEncoding, RGBEFormat, RGBFormat, RGBIntegerFormat, RGBM16Encoding, RGBM7Encoding, RGB_ETC1_Format, RGB_ETC2_Format, RGB_PVRTC_2BPPV1_Format, RGB_PVRTC_4BPPV1_Format, RGB_S3TC_DXT1_Format, RGFormat, RGIntegerFormat, RawShaderMaterial, Ray, Raycaster, RectAreaLight, RedFormat, RedIntegerFormat, ReinhardToneMapping, RepeatWrapping, ReplaceStencilOp, ReverseSubtractEquation, RingBufferGeometry, RingGeometry, SRGB8_ALPHA8_ASTC_10x10_Format, SRGB8_ALPHA8_ASTC_10x5_Format, SRGB8_ALPHA8_ASTC_10x6_Format, SRGB8_ALPHA8_ASTC_10x8_Format, SRGB8_ALPHA8_ASTC_12x10_Format, SRGB8_ALPHA8_ASTC_12x12_Format, SRGB8_ALPHA8_ASTC_4x4_Format, SRGB8_ALPHA8_ASTC_5x4_Format, SRGB8_ALPHA8_ASTC_5x5_Format, SRGB8_ALPHA8_ASTC_6x5_Format, SRGB8_ALPHA8_ASTC_6x6_Format, SRGB8_ALPHA8_ASTC_8x5_Format, SRGB8_ALPHA8_ASTC_8x6_Format, SRGB8_ALPHA8_ASTC_8x8_Format, Scene, SceneUtils, ShaderChunk, ShaderLib, ShaderMaterial, ShadowMaterial, Shape, ShapeBufferGeometry, ShapeGeometry, ShapePath, ShapeUtils, ShortType, Skeleton, SkeletonHelper, SkinnedMesh, SmoothShading, Sphere, SphereBufferGeometry, SphereGeometry, Spherical, SphericalHarmonics3, Spline, SplineCurve, SplineCurve3, SpotLight, SpotLightHelper, Sprite, SpriteMaterial, SrcAlphaFactor, SrcAlphaSaturateFactor, SrcColorFactor, StaticCopyUsage, StaticDrawUsage, StaticReadUsage, StereoCamera, StreamCopyUsage, StreamDrawUsage, StreamReadUsage, StringKeyframeTrack, SubtractEquation, SubtractiveBlending, TOUCH, TangentSpaceNormalMap, TetrahedronBufferGeometry, TetrahedronGeometry, TextBufferGeometry, TextGeometry, Texture, TextureLoader, TorusBufferGeometry, TorusGeometry, TorusKnotBufferGeometry, TorusKnotGeometry, Triangle, TriangleFanDrawMode, TriangleStripDrawMode, TrianglesDrawMode, TubeBufferGeometry, TubeGeometry, UVMapping, Uint16Attribute, Uint16BufferAttribute, Uint32Attribute, Uint32BufferAttribute, Uint8Attribute, Uint8BufferAttribute, Uint8ClampedAttribute, Uint8ClampedBufferAttribute, Uniform, UniformsLib, UniformsUtils, UnsignedByteType, UnsignedInt248Type, UnsignedIntType, UnsignedShort4444Type, UnsignedShort5551Type, UnsignedShort565Type, UnsignedShortType, VSMShadowMap, Vector2, Vector3, Vector4, VectorKeyframeTrack, Vertex, VertexColors, VideoTexture, WebGL1Renderer, WebGLCubeRenderTarget, WebGLMultisampleRenderTarget, WebGLRenderTarget, WebGLRenderTargetCube, WebGLRenderer, WebGLUtils, WireframeGeometry, WireframeHelper, WrapAroundEnding, XHRLoader, ZeroCurvatureEnding, ZeroFactor, ZeroSlopeEnding, ZeroStencilOp, sRGBEncoding };
+if ( typeof window !== 'undefined' ) {
+
+       if ( window.__THREE__ ) {
+
+               console.warn( 'WARNING: Multiple instances of Three.js being imported.' );
+
+       } else {
+
+               window.__THREE__ = REVISION;
+
+       }
+
+}
+
+export { ACESFilmicToneMapping, AddEquation, AddOperation, AdditiveAnimationBlendMode, AdditiveBlending, AlphaFormat, AlwaysDepth, AlwaysStencilFunc, AmbientLight, AmbientLightProbe, AnimationClip, AnimationLoader, AnimationMixer, AnimationObjectGroup, AnimationUtils, ArcCurve, ArrayCamera, ArrowHelper, Audio, AudioAnalyser, AudioContext, AudioListener, AudioLoader, AxesHelper, AxisHelper, BackSide, BasicDepthPacking, BasicShadowMap, BinaryTextureLoader, Bone, BooleanKeyframeTrack, BoundingBoxHelper, Box2, Box3, Box3Helper, BoxGeometry as BoxBufferGeometry, BoxGeometry, BoxHelper, BufferAttribute, BufferGeometry, BufferGeometryLoader, ByteType, Cache, Camera, CameraHelper, CanvasRenderer, CanvasTexture, CatmullRomCurve3, CineonToneMapping, CircleGeometry as CircleBufferGeometry, CircleGeometry, ClampToEdgeWrapping, Clock, ClosedSplineCurve3, Color, ColorKeyframeTrack, CompressedTexture, CompressedTextureLoader, ConeGeometry as ConeBufferGeometry, ConeGeometry, CubeCamera, CubeReflectionMapping, CubeRefractionMapping, CubeTexture, CubeTextureLoader, CubeUVReflectionMapping, CubeUVRefractionMapping, CubicBezierCurve, CubicBezierCurve3, CubicInterpolant, CullFaceBack, CullFaceFront, CullFaceFrontBack, CullFaceNone, Curve, CurvePath, CustomBlending, CustomToneMapping, CylinderGeometry as CylinderBufferGeometry, CylinderGeometry, Cylindrical, DataTexture, DataTexture2DArray, DataTexture3D, DataTextureLoader, DataUtils, DecrementStencilOp, DecrementWrapStencilOp, DefaultLoadingManager, DepthFormat, DepthStencilFormat, DepthTexture, DirectionalLight, DirectionalLightHelper, DiscreteInterpolant, DodecahedronGeometry as DodecahedronBufferGeometry, DodecahedronGeometry, DoubleSide, DstAlphaFactor, DstColorFactor, DynamicBufferAttribute, DynamicCopyUsage, DynamicDrawUsage, DynamicReadUsage, EdgesGeometry, EdgesHelper, EllipseCurve, EqualDepth, EqualStencilFunc, EquirectangularReflectionMapping, EquirectangularRefractionMapping, Euler, EventDispatcher, ExtrudeGeometry as ExtrudeBufferGeometry, ExtrudeGeometry, Face3, Face4, FaceColors, FileLoader, FlatShading, Float16BufferAttribute, Float32Attribute, Float32BufferAttribute, Float64Attribute, Float64BufferAttribute, FloatType, Fog, FogExp2, Font, FontLoader, FrontSide, Frustum, GLBufferAttribute, GLSL1, GLSL3, GammaEncoding, GeometryUtils, GreaterDepth, GreaterEqualDepth, GreaterEqualStencilFunc, GreaterStencilFunc, GridHelper, Group, HalfFloatType, HemisphereLight, HemisphereLightHelper, HemisphereLightProbe, IcosahedronGeometry as IcosahedronBufferGeometry, IcosahedronGeometry, ImageBitmapLoader, ImageLoader, ImageUtils, ImmediateRenderObject, IncrementStencilOp, IncrementWrapStencilOp, InstancedBufferAttribute, InstancedBufferGeometry, InstancedInterleavedBuffer, InstancedMesh, Int16Attribute, Int16BufferAttribute, Int32Attribute, Int32BufferAttribute, Int8Attribute, Int8BufferAttribute, IntType, InterleavedBuffer, InterleavedBufferAttribute, Interpolant, InterpolateDiscrete, InterpolateLinear, InterpolateSmooth, InvertStencilOp, JSONLoader, KeepStencilOp, KeyframeTrack, LOD, LatheGeometry as LatheBufferGeometry, LatheGeometry, Layers, LensFlare, LessDepth, LessEqualDepth, LessEqualStencilFunc, LessStencilFunc, Light, LightProbe, Line, Line3, LineBasicMaterial, LineCurve, LineCurve3, LineDashedMaterial, LineLoop, LinePieces, LineSegments, LineStrip, LinearEncoding, LinearFilter, LinearInterpolant, LinearMipMapLinearFilter, LinearMipMapNearestFilter, LinearMipmapLinearFilter, LinearMipmapNearestFilter, LinearToneMapping, Loader, LoaderUtils, LoadingManager, LogLuvEncoding, LoopOnce, LoopPingPong, LoopRepeat, LuminanceAlphaFormat, LuminanceFormat, MOUSE, Material, MaterialLoader, MathUtils as Math, MathUtils, Matrix3, Matrix4, MaxEquation, Mesh, MeshBasicMaterial, MeshDepthMaterial, MeshDistanceMaterial, MeshFaceMaterial, MeshLambertMaterial, MeshMatcapMaterial, MeshNormalMaterial, MeshPhongMaterial, MeshPhysicalMaterial, MeshStandardMaterial, MeshToonMaterial, MinEquation, MirroredRepeatWrapping, MixOperation, MultiMaterial, MultiplyBlending, MultiplyOperation, NearestFilter, NearestMipMapLinearFilter, NearestMipMapNearestFilter, NearestMipmapLinearFilter, NearestMipmapNearestFilter, NeverDepth, NeverStencilFunc, NoBlending, NoColors, NoToneMapping, NormalAnimationBlendMode, NormalBlending, NotEqualDepth, NotEqualStencilFunc, NumberKeyframeTrack, Object3D, ObjectLoader, ObjectSpaceNormalMap, OctahedronGeometry as OctahedronBufferGeometry, OctahedronGeometry, OneFactor, OneMinusDstAlphaFactor, OneMinusDstColorFactor, OneMinusSrcAlphaFactor, OneMinusSrcColorFactor, OrthographicCamera, PCFShadowMap, PCFSoftShadowMap, PMREMGenerator, ParametricGeometry as ParametricBufferGeometry, ParametricGeometry, Particle, ParticleBasicMaterial, ParticleSystem, ParticleSystemMaterial, Path, PerspectiveCamera, Plane, PlaneGeometry as PlaneBufferGeometry, PlaneGeometry, PlaneHelper, PointCloud, PointCloudMaterial, PointLight, PointLightHelper, Points, PointsMaterial, PolarGridHelper, PolyhedronGeometry as PolyhedronBufferGeometry, PolyhedronGeometry, PositionalAudio, PropertyBinding, PropertyMixer, QuadraticBezierCurve, QuadraticBezierCurve3, Quaternion, QuaternionKeyframeTrack, QuaternionLinearInterpolant, REVISION, RGBADepthPacking, RGBAFormat, RGBAIntegerFormat, RGBA_ASTC_10x10_Format, RGBA_ASTC_10x5_Format, RGBA_ASTC_10x6_Format, RGBA_ASTC_10x8_Format, RGBA_ASTC_12x10_Format, RGBA_ASTC_12x12_Format, RGBA_ASTC_4x4_Format, RGBA_ASTC_5x4_Format, RGBA_ASTC_5x5_Format, RGBA_ASTC_6x5_Format, RGBA_ASTC_6x6_Format, RGBA_ASTC_8x5_Format, RGBA_ASTC_8x6_Format, RGBA_ASTC_8x8_Format, RGBA_BPTC_Format, RGBA_ETC2_EAC_Format, RGBA_PVRTC_2BPPV1_Format, RGBA_PVRTC_4BPPV1_Format, RGBA_S3TC_DXT1_Format, RGBA_S3TC_DXT3_Format, RGBA_S3TC_DXT5_Format, RGBDEncoding, RGBEEncoding, RGBEFormat, RGBFormat, RGBIntegerFormat, RGBM16Encoding, RGBM7Encoding, RGB_ETC1_Format, RGB_ETC2_Format, RGB_PVRTC_2BPPV1_Format, RGB_PVRTC_4BPPV1_Format, RGB_S3TC_DXT1_Format, RGFormat, RGIntegerFormat, RawShaderMaterial, Ray, Raycaster, RectAreaLight, RedFormat, RedIntegerFormat, ReinhardToneMapping, RepeatWrapping, ReplaceStencilOp, ReverseSubtractEquation, RingGeometry as RingBufferGeometry, RingGeometry, SRGB8_ALPHA8_ASTC_10x10_Format, SRGB8_ALPHA8_ASTC_10x5_Format, SRGB8_ALPHA8_ASTC_10x6_Format, SRGB8_ALPHA8_ASTC_10x8_Format, SRGB8_ALPHA8_ASTC_12x10_Format, SRGB8_ALPHA8_ASTC_12x12_Format, SRGB8_ALPHA8_ASTC_4x4_Format, SRGB8_ALPHA8_ASTC_5x4_Format, SRGB8_ALPHA8_ASTC_5x5_Format, SRGB8_ALPHA8_ASTC_6x5_Format, SRGB8_ALPHA8_ASTC_6x6_Format, SRGB8_ALPHA8_ASTC_8x5_Format, SRGB8_ALPHA8_ASTC_8x6_Format, SRGB8_ALPHA8_ASTC_8x8_Format, Scene, SceneUtils, ShaderChunk, ShaderLib, ShaderMaterial, ShadowMaterial, Shape, ShapeGeometry as ShapeBufferGeometry, ShapeGeometry, ShapePath, ShapeUtils, ShortType, Skeleton, SkeletonHelper, SkinnedMesh, SmoothShading, Sphere, SphereGeometry as SphereBufferGeometry, SphereGeometry, Spherical, SphericalHarmonics3, Spline, SplineCurve, SplineCurve3, SpotLight, SpotLightHelper, Sprite, SpriteMaterial, SrcAlphaFactor, SrcAlphaSaturateFactor, SrcColorFactor, StaticCopyUsage, StaticDrawUsage, StaticReadUsage, StereoCamera, StreamCopyUsage, StreamDrawUsage, StreamReadUsage, StringKeyframeTrack, SubtractEquation, SubtractiveBlending, TOUCH, TangentSpaceNormalMap, TetrahedronGeometry as TetrahedronBufferGeometry, TetrahedronGeometry, TextGeometry as TextBufferGeometry, TextGeometry, Texture, TextureLoader, TorusGeometry as TorusBufferGeometry, TorusGeometry, TorusKnotGeometry as TorusKnotBufferGeometry, TorusKnotGeometry, Triangle, TriangleFanDrawMode, TriangleStripDrawMode, TrianglesDrawMode, TubeGeometry as TubeBufferGeometry, TubeGeometry, UVMapping, Uint16Attribute, Uint16BufferAttribute, Uint32Attribute, Uint32BufferAttribute, Uint8Attribute, Uint8BufferAttribute, Uint8ClampedAttribute, Uint8ClampedBufferAttribute, Uniform, UniformsLib, UniformsUtils, UnsignedByteType, UnsignedInt248Type, UnsignedIntType, UnsignedShort4444Type, UnsignedShort5551Type, UnsignedShort565Type, UnsignedShortType, VSMShadowMap, Vector2, Vector3, Vector4, VectorKeyframeTrack, Vertex, VertexColors, VideoTexture, WebGL1Renderer, WebGLCubeRenderTarget, WebGLMultisampleRenderTarget, WebGLRenderTarget, WebGLRenderTargetCube, WebGLRenderer, WebGLUtils, WireframeGeometry, WireframeHelper, WrapAroundEnding, XHRLoader, ZeroCurvatureEnding, ZeroFactor, ZeroSlopeEnding, ZeroStencilOp, sRGBEncoding };