Browse Source

Updated examples builds.

Mr.doob 2 years ago
parent
commit
290f32bcf1
35 changed files with 406 additions and 104 deletions
  1. 24 2
      examples/js/animation/CCDIKSolver.js
  2. 24 0
      examples/js/animation/MMDPhysics.js
  3. 20 20
      examples/js/controls/FirstPersonControls.js
  4. 16 16
      examples/js/controls/FlyControls.js
  5. 14 2
      examples/js/controls/TrackballControls.js
  6. 1 0
      examples/js/csm/CSM.js
  7. 26 0
      examples/js/csm/CSMHelper.js
  8. 1 14
      examples/js/exporters/GLTFExporter.js
  9. 24 10
      examples/js/helpers/OctreeHelper.js
  10. 7 0
      examples/js/helpers/VertexNormalsHelper.js
  11. 7 0
      examples/js/helpers/VertexTangentsHelper.js
  12. 21 0
      examples/js/helpers/ViewHelper.js
  13. 1 1
      examples/js/loaders/GLTFLoader.js
  14. 13 1
      examples/js/loaders/VRMLLoader.js
  15. 4 0
      examples/js/math/ConvexHull.js
  16. 15 4
      examples/js/postprocessing/AfterimagePass.js
  17. 10 0
      examples/js/postprocessing/BloomPass.js
  18. 9 0
      examples/js/postprocessing/BokehPass.js
  19. 7 0
      examples/js/postprocessing/CubeTexturePass.js
  20. 7 0
      examples/js/postprocessing/DotScreenPass.js
  21. 8 0
      examples/js/postprocessing/EffectComposer.js
  22. 7 0
      examples/js/postprocessing/FilmPass.js
  23. 10 1
      examples/js/postprocessing/GlitchPass.js
  24. 7 0
      examples/js/postprocessing/HalftonePass.js
  25. 19 1
      examples/js/postprocessing/OutlinePass.js
  26. 2 0
      examples/js/postprocessing/Pass.js
  27. 18 0
      examples/js/postprocessing/SAOPass.js
  28. 13 0
      examples/js/postprocessing/SMAAPass.js
  29. 3 0
      examples/js/postprocessing/SSAARenderPass.js
  30. 8 0
      examples/js/postprocessing/SavePass.js
  31. 7 0
      examples/js/postprocessing/ShaderPass.js
  32. 8 0
      examples/js/postprocessing/TAARenderPass.js
  33. 7 0
      examples/js/postprocessing/TexturePass.js
  34. 13 1
      examples/js/postprocessing/UnrealBloomPass.js
  35. 25 31
      examples/js/utils/BufferGeometryUtils.js

+ 24 - 2
examples/js/animation/CCDIKSolver.js

@@ -272,14 +272,14 @@
 
 	class CCDIKHelper extends THREE.Object3D {
 
-		constructor( mesh, iks = [] ) {
+		constructor( mesh, iks = [], sphereSize = 0.25 ) {
 
 			super();
 			this.root = mesh;
 			this.iks = iks;
 			this.matrix.copy( mesh.matrixWorld );
 			this.matrixAutoUpdate = false;
-			this.sphereGeometry = new THREE.SphereGeometry( 0.25, 16, 8 );
+			this.sphereGeometry = new THREE.SphereGeometry( sphereSize, 16, 8 );
 			this.targetSphereMaterial = new THREE.MeshBasicMaterial( {
 				color: new THREE.Color( 0xff8888 ),
 				depthTest: false,
@@ -366,6 +366,28 @@
 			this.matrix.copy( mesh.matrixWorld );
 			super.updateMatrixWorld( force );
 
+		}
+		/**
+   * Frees the GPU-related resources allocated by this instance. Call this method whenever this instance is no longer used in your app.
+   */
+
+
+		dispose() {
+
+			this.sphereGeometry.dispose();
+			this.targetSphereMaterial.dispose();
+			this.effectorSphereMaterial.dispose();
+			this.linkSphereMaterial.dispose();
+			this.lineMaterial.dispose();
+			const children = this.children;
+
+			for ( let i = 0; i < children.length; i ++ ) {
+
+				const child = children[ i ];
+				if ( child.isLine ) child.geometry.dispose();
+
+			}
+
 		} // private method
 
 

+ 24 - 0
examples/js/animation/MMDPhysics.js

@@ -1162,6 +1162,30 @@
 
 			this._init();
 
+		}
+		/**
+   * Frees the GPU-related resources allocated by this instance. Call this method whenever this instance is no longer used in your app.
+   */
+
+
+		dispose() {
+
+			const materials = this.materials;
+			const children = this.children;
+
+			for ( let i = 0; i < materials.length; i ++ ) {
+
+				materials[ i ].dispose();
+
+			}
+
+			for ( let i = 0; i < children.length; i ++ ) {
+
+				const child = children[ i ];
+				if ( child.isMesh ) child.geometry.dispose();
+
+			}
+
 		}
 		/**
    * Updates Rigid Bodies visualization.

+ 20 - 20
examples/js/controls/FirstPersonControls.js

@@ -29,8 +29,8 @@
 			this.mouseDragOn = false; // internals
 
 			this.autoSpeedFactor = 0.0;
-			this.mouseX = 0;
-			this.mouseY = 0;
+			this.pointerX = 0;
+			this.pointerY = 0;
 			this.moveForward = false;
 			this.moveBackward = false;
 			this.moveLeft = false;
@@ -57,7 +57,7 @@
 
 			};
 
-			this.onMouseDown = function ( event ) {
+			this.onPointerDown = function ( event ) {
 
 				if ( this.domElement !== document ) {
 
@@ -85,7 +85,7 @@
 
 			};
 
-			this.onMouseUp = function ( event ) {
+			this.onPointerUp = function ( event ) {
 
 				if ( this.activeLook ) {
 
@@ -107,17 +107,17 @@
 
 			};
 
-			this.onMouseMove = function ( event ) {
+			this.onPointerMove = function ( event ) {
 
 				if ( this.domElement === document ) {
 
-					this.mouseX = event.pageX - this.viewHalfX;
-					this.mouseY = event.pageY - this.viewHalfY;
+					this.pointerX = event.pageX - this.viewHalfX;
+					this.pointerY = event.pageY - this.viewHalfY;
 
 				} else {
 
-					this.mouseX = event.pageX - this.domElement.offsetLeft - this.viewHalfX;
-					this.mouseY = event.pageY - this.domElement.offsetTop - this.viewHalfY;
+					this.pointerX = event.pageX - this.domElement.offsetLeft - this.viewHalfX;
+					this.pointerY = event.pageY - this.domElement.offsetTop - this.viewHalfY;
 
 				}
 
@@ -255,8 +255,8 @@
 
 					}
 
-					lon -= this.mouseX * actualLookSpeed;
-					if ( this.lookVertical ) lat -= this.mouseY * actualLookSpeed * verticalLookRatio;
+					lon -= this.pointerX * actualLookSpeed;
+					if ( this.lookVertical ) lat -= this.pointerY * actualLookSpeed * verticalLookRatio;
 					lat = Math.max( - 85, Math.min( 85, lat ) );
 					let phi = THREE.MathUtils.degToRad( 90 - lat );
 					const theta = THREE.MathUtils.degToRad( lon );
@@ -278,28 +278,28 @@
 			this.dispose = function () {
 
 				this.domElement.removeEventListener( 'contextmenu', contextmenu );
-				this.domElement.removeEventListener( 'mousedown', _onMouseDown );
-				this.domElement.removeEventListener( 'mousemove', _onMouseMove );
-				this.domElement.removeEventListener( 'mouseup', _onMouseUp );
+				this.domElement.removeEventListener( 'pointerdown', _onPointerDown );
+				this.domElement.removeEventListener( 'pointermove', _onPointerMove );
+				this.domElement.removeEventListener( 'pointerup', _onPointerUp );
 				window.removeEventListener( 'keydown', _onKeyDown );
 				window.removeEventListener( 'keyup', _onKeyUp );
 
 			};
 
-			const _onMouseMove = this.onMouseMove.bind( this );
+			const _onPointerMove = this.onPointerMove.bind( this );
 
-			const _onMouseDown = this.onMouseDown.bind( this );
+			const _onPointerDown = this.onPointerDown.bind( this );
 
-			const _onMouseUp = this.onMouseUp.bind( this );
+			const _onPointerUp = this.onPointerUp.bind( this );
 
 			const _onKeyDown = this.onKeyDown.bind( this );
 
 			const _onKeyUp = this.onKeyUp.bind( this );
 
 			this.domElement.addEventListener( 'contextmenu', contextmenu );
-			this.domElement.addEventListener( 'mousemove', _onMouseMove );
-			this.domElement.addEventListener( 'mousedown', _onMouseDown );
-			this.domElement.addEventListener( 'mouseup', _onMouseUp );
+			this.domElement.addEventListener( 'pointerdown', _onPointerDown );
+			this.domElement.addEventListener( 'pointermove', _onPointerMove );
+			this.domElement.addEventListener( 'pointerup', _onPointerUp );
 			window.addEventListener( 'keydown', _onKeyDown );
 			window.addEventListener( 'keyup', _onKeyUp );
 

+ 16 - 16
examples/js/controls/FlyControls.js

@@ -23,7 +23,7 @@
 			const lastQuaternion = new THREE.Quaternion();
 			const lastPosition = new THREE.Vector3();
 			this.tmpQuaternion = new THREE.Quaternion();
-			this.mouseStatus = 0;
+			this.status = 0;
 			this.moveState = {
 				up: 0,
 				down: 0,
@@ -175,11 +175,11 @@
 
 			};
 
-			this.mousedown = function ( event ) {
+			this.pointerdown = function ( event ) {
 
 				if ( this.dragToLook ) {
 
-					this.mouseStatus ++;
+					this.status ++;
 
 				} else {
 
@@ -201,9 +201,9 @@
 
 			};
 
-			this.mousemove = function ( event ) {
+			this.pointermove = function ( event ) {
 
-				if ( ! this.dragToLook || this.mouseStatus > 0 ) {
+				if ( ! this.dragToLook || this.status > 0 ) {
 
 					const container = this.getContainerDimensions();
 					const halfWidth = container.size[ 0 ] / 2;
@@ -216,11 +216,11 @@
 
 			};
 
-			this.mouseup = function ( event ) {
+			this.pointerup = function ( event ) {
 
 				if ( this.dragToLook ) {
 
-					this.mouseStatus --;
+					this.status --;
 					this.moveState.yawLeft = this.moveState.pitchDown = 0;
 
 				} else {
@@ -305,28 +305,28 @@
 			this.dispose = function () {
 
 				this.domElement.removeEventListener( 'contextmenu', contextmenu );
-				this.domElement.removeEventListener( 'mousedown', _mousedown );
-				this.domElement.removeEventListener( 'mousemove', _mousemove );
-				this.domElement.removeEventListener( 'mouseup', _mouseup );
+				this.domElement.removeEventListener( 'pointerdown', _pointerdown );
+				this.domElement.removeEventListener( 'pointermove', _pointermove );
+				this.domElement.removeEventListener( 'pointerup', _pointerup );
 				window.removeEventListener( 'keydown', _keydown );
 				window.removeEventListener( 'keyup', _keyup );
 
 			};
 
-			const _mousemove = this.mousemove.bind( this );
+			const _pointermove = this.pointermove.bind( this );
 
-			const _mousedown = this.mousedown.bind( this );
+			const _pointerdown = this.pointerdown.bind( this );
 
-			const _mouseup = this.mouseup.bind( this );
+			const _pointerup = this.pointerup.bind( this );
 
 			const _keydown = this.keydown.bind( this );
 
 			const _keyup = this.keyup.bind( this );
 
 			this.domElement.addEventListener( 'contextmenu', contextmenu );
-			this.domElement.addEventListener( 'mousemove', _mousemove );
-			this.domElement.addEventListener( 'mousedown', _mousedown );
-			this.domElement.addEventListener( 'mouseup', _mouseup );
+			this.domElement.addEventListener( 'pointerdown', _pointerdown );
+			this.domElement.addEventListener( 'pointermove', _pointermove );
+			this.domElement.addEventListener( 'pointerup', _pointerup );
 			window.addEventListener( 'keydown', _keydown );
 			window.addEventListener( 'keyup', _keyup );
 			this.updateMovementVector();

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

@@ -683,9 +683,21 @@
 					case 2:
 						_state = STATE.TOUCH_ZOOM_PAN;
 
-						_moveCurr.copy( getMouseOnCircle( event.pageX - _movePrev.x, event.pageY - _movePrev.y ) );
+						for ( let i = 0; i < _pointers.length; i ++ ) {
 
-						_movePrev.copy( _moveCurr );
+							if ( _pointers[ i ].pointerId !== event.pointerId ) {
+
+								const position = _pointerPositions[ _pointers[ i ].pointerId ];
+
+								_moveCurr.copy( getMouseOnCircle( position.x, position.y ) );
+
+								_movePrev.copy( _moveCurr );
+
+								break;
+
+							}
+
+						}
 
 						break;
 

+ 1 - 0
examples/js/csm/CSM.js

@@ -344,6 +344,7 @@
 
 			for ( let i = 0; i < this.lights.length; i ++ ) {
 
+				this.parent.remove( this.lights[ i ].target );
 				this.parent.remove( this.lights[ i ] );
 
 			}

+ 26 - 0
examples/js/csm/CSMHelper.js

@@ -138,6 +138,32 @@
 
 		}
 
+		dispose() {
+
+			const frustumLines = this.frustumLines;
+			const cascadeLines = this.cascadeLines;
+			const cascadePlanes = this.cascadePlanes;
+			const shadowLines = this.shadowLines;
+			frustumLines.geometry.dispose();
+			frustumLines.material.dispose();
+			const cascades = this.csm.cascades;
+
+			for ( let i = 0; i < cascades; i ++ ) {
+
+				const cascadeLine = cascadeLines[ i ];
+				const cascadePlane = cascadePlanes[ i ];
+				const shadowLineGroup = shadowLines[ i ];
+				const shadowLine = shadowLineGroup.children[ 0 ];
+				cascadeLine.dispose(); // THREE.Box3Helper
+
+				cascadePlane.geometry.dispose();
+				cascadePlane.material.dispose();
+				shadowLine.dispose(); // THREE.Box3Helper
+
+			}
+
+		}
+
 	}
 
 	THREE.CSMHelper = CSMHelper;

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

@@ -389,7 +389,6 @@
 				binary: false,
 				trs: false,
 				onlyVisible: true,
-				truncateDrawRange: true,
 				maxTextureSize: Infinity,
 				animations: [],
 				includeCustomExtensions: false
@@ -893,7 +892,6 @@
 
 		processAccessor( attribute, geometry, start, count ) {
 
-			const options = this.options;
 			const json = this.json;
 			const types = {
 				1: 'SCALAR',
@@ -927,18 +925,7 @@
 			}
 
 			if ( start === undefined ) start = 0;
-			if ( count === undefined ) count = attribute.count; // @TODO Indexed buffer geometry with drawRange not supported yet
-
-			if ( options.truncateDrawRange && geometry !== undefined && geometry.index === null ) {
-
-				const end = start + count;
-				const end2 = geometry.drawRange.count === Infinity ? attribute.count : geometry.drawRange.start + geometry.drawRange.count;
-				start = Math.max( start, geometry.drawRange.start );
-				count = Math.min( end, end2 ) - start;
-				if ( count < 0 ) count = 0;
-
-			} // Skip creating an accessor if the attribute doesn't have data to export
-
+			if ( count === undefined ) count = attribute.count; // Skip creating an accessor if the attribute doesn't have data to export
 
 			if ( count === 0 ) return null;
 			const minMax = getMinMax( attribute, start, count );

+ 24 - 10
examples/js/helpers/OctreeHelper.js

@@ -4,6 +4,19 @@
 
 		constructor( octree, color = 0xffff00 ) {
 
+			super( new THREE.BufferGeometry(), new THREE.LineBasicMaterial( {
+				color: color,
+				toneMapped: false
+			} ) );
+			this.octree = octree;
+			this.color = color;
+			this.type = 'OctreeHelper';
+			this.update();
+
+		}
+
+		update() {
+
 			const vertices = [];
 
 			function traverse( tree ) {
@@ -54,16 +67,17 @@
 
 			}
 
-			traverse( octree.subTrees );
-			const geometry = new THREE.BufferGeometry();
-			geometry.setAttribute( 'position', new THREE.Float32BufferAttribute( vertices, 3 ) );
-			super( geometry, new THREE.LineBasicMaterial( {
-				color: color,
-				toneMapped: false
-			} ) );
-			this.octree = octree;
-			this.color = color;
-			this.type = 'OctreeHelper';
+			traverse( this.octree.subTrees );
+			this.geometry.dispose();
+			this.geometry = new THREE.BufferGeometry();
+			this.geometry.setAttribute( 'position', new THREE.Float32BufferAttribute( vertices, 3 ) );
+
+		}
+
+		dispose() {
+
+			this.geometry.dispose();
+			this.material.dispose();
 
 		}
 

+ 7 - 0
examples/js/helpers/VertexNormalsHelper.js

@@ -65,6 +65,13 @@
 
 		}
 
+		dispose() {
+
+			this.geometry.dispose();
+			this.material.dispose();
+
+		}
+
 	}
 
 	THREE.VertexNormalsHelper = VertexNormalsHelper;

+ 7 - 0
examples/js/helpers/VertexTangentsHelper.js

@@ -55,6 +55,13 @@
 
 		}
 
+		dispose() {
+
+			this.geometry.dispose();
+			this.material.dispose();
+
+		}
+
 	}
 
 	THREE.VertexTangentsHelper = VertexTangentsHelper;

+ 21 - 0
examples/js/helpers/ViewHelper.js

@@ -169,6 +169,27 @@
 
 			};
 
+			this.dispose = function () {
+
+				geometry.dispose();
+				xAxis.material.dispose();
+				yAxis.material.dispose();
+				zAxis.material.dispose();
+				posXAxisHelper.material.map.dispose();
+				posYAxisHelper.material.map.dispose();
+				posZAxisHelper.material.map.dispose();
+				negXAxisHelper.material.map.dispose();
+				negYAxisHelper.material.map.dispose();
+				negZAxisHelper.material.map.dispose();
+				posXAxisHelper.material.dispose();
+				posYAxisHelper.material.dispose();
+				posZAxisHelper.material.dispose();
+				negXAxisHelper.material.dispose();
+				negYAxisHelper.material.dispose();
+				negZAxisHelper.material.dispose();
+
+			};
+
 			function prepareAnimationData( object, focusPoint ) {
 
 				switch ( object.userData.type ) {

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

@@ -922,7 +922,7 @@
 
 			}
 
-			materialParams.attenuationDistance = extension.attenuationDistance || 0;
+			materialParams.attenuationDistance = extension.attenuationDistance || Infinity;
 			const colorArray = extension.attenuationColor || [ 1, 1, 1 ];
 			materialParams.attenuationColor = new THREE.Color( colorArray[ 0 ], colorArray[ 1 ], colorArray[ 2 ] );
 			return Promise.all( pending );

+ 13 - 1
examples/js/loaders/VRMLLoader.js

@@ -549,6 +549,7 @@
 
 				switch ( nodeName ) {
 
+					case 'Anchor':
 					case 'Group':
 					case 'Transform':
 					case 'Collision':
@@ -630,7 +631,6 @@
 						build = buildWorldInfoNode( node );
 						break;
 
-					case 'Anchor':
 					case 'Billboard':
 					case 'Inline':
 					case 'LOD':
@@ -709,10 +709,18 @@
 							parseFieldChildren( fieldValues, object );
 							break;
 
+						case 'description':
+							// field not supported
+							break;
+
 						case 'collide':
 							// field not supported
 							break;
 
+						case 'parameter':
+							// field not supported
+							break;
+
 						case 'rotation':
 							const axis = new THREE.Vector3( fieldValues[ 0 ], fieldValues[ 1 ], fieldValues[ 2 ] );
 							const angle = fieldValues[ 3 ];
@@ -735,6 +743,10 @@
 							// field not supported
 							break;
 
+						case 'url':
+							// field not supported
+							break;
+
 						default:
 							console.warn( 'THREE.VRMLLoader: Unknown field:', fieldName );
 							break;

+ 4 - 0
examples/js/math/ConvexHull.js

@@ -1106,5 +1106,9 @@
 	}
 
 	THREE.ConvexHull = ConvexHull;
+	THREE.Face = Face;
+	THREE.HalfEdge = HalfEdge;
+	THREE.VertexList = VertexList;
+	THREE.VertexNode = VertexNode;
 
 } )();

+ 15 - 4
examples/js/postprocessing/AfterimagePass.js

@@ -15,14 +15,14 @@
 			this.textureOld = new THREE.WebGLRenderTarget( window.innerWidth, window.innerHeight, {
 				magFilter: THREE.NearestFilter
 			} );
-			this.shaderMaterial = new THREE.ShaderMaterial( {
+			this.compFsMaterial = new THREE.ShaderMaterial( {
 				uniforms: this.uniforms,
 				vertexShader: this.shader.vertexShader,
 				fragmentShader: this.shader.fragmentShader
 			} );
-			this.compFsQuad = new THREE.FullScreenQuad( this.shaderMaterial );
-			const material = new THREE.MeshBasicMaterial();
-			this.copyFsQuad = new THREE.FullScreenQuad( material );
+			this.compFsQuad = new THREE.FullScreenQuad( this.compFsMaterial );
+			this.copyFsMaterial = new THREE.MeshBasicMaterial();
+			this.copyFsQuad = new THREE.FullScreenQuad( this.copyFsMaterial );
 
 		}
 
@@ -63,6 +63,17 @@
 
 		}
 
+		dispose() {
+
+			this.textureComp.dispose();
+			this.textureOld.dispose();
+			this.compFsMaterial.dispose();
+			this.copyFsMaterial.dispose();
+			this.compFsQuad.dispose();
+			this.copyFsQuad.dispose();
+
+		}
+
 	}
 
 	THREE.AfterimagePass = AfterimagePass;

+ 10 - 0
examples/js/postprocessing/BloomPass.js

@@ -66,6 +66,16 @@
 
 		}
 
+		dispose() {
+
+			this.renderTargetX.dispose();
+			this.renderTargetY.dispose();
+			this.materialCombine.dispose();
+			this.materialConvolution.dispose();
+			this.fsQuad.dispose();
+
+		}
+
 	}
 
 	const CombineShader = {

+ 9 - 0
examples/js/postprocessing/BokehPass.js

@@ -96,6 +96,15 @@
 
 		}
 
+		dispose() {
+
+			this.renderTargetDepth.dispose();
+			this.materialDepth.dispose();
+			this.materialBokeh.dispose();
+			this.fsQuad.dispose();
+
+		}
+
 	}
 
 	THREE.BokehPass = BokehPass;

+ 7 - 0
examples/js/postprocessing/CubeTexturePass.js

@@ -50,6 +50,13 @@
 
 		}
 
+		dispose() {
+
+			this.cubeMesh.geometry.dispose();
+			this.cubeMesh.material.dispose();
+
+		}
+
 	}
 
 	THREE.CubeTexturePass = CubeTexturePass;

+ 7 - 0
examples/js/postprocessing/DotScreenPass.js

@@ -42,6 +42,13 @@
 
 		}
 
+		dispose() {
+
+			this.material.dispose();
+			this.fsQuad.dispose();
+
+		}
+
 	}
 
 	THREE.DotScreenPass = DotScreenPass;

+ 8 - 0
examples/js/postprocessing/EffectComposer.js

@@ -201,6 +201,14 @@
 
 		}
 
+		dispose() {
+
+			this.renderTarget1.dispose();
+			this.renderTarget2.dispose();
+			this.copyPass.dispose();
+
+		}
+
 	}
 
 	class Pass {

+ 7 - 0
examples/js/postprocessing/FilmPass.js

@@ -43,6 +43,13 @@
 
 		}
 
+		dispose() {
+
+			this.material.dispose();
+			this.fsQuad.dispose();
+
+		}
+
 	}
 
 	THREE.FilmPass = FilmPass;

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

@@ -8,7 +8,8 @@
 			if ( THREE.DigitalGlitch === undefined ) console.error( 'THREE.GlitchPass relies on THREE.DigitalGlitch' );
 			const shader = THREE.DigitalGlitch;
 			this.uniforms = THREE.UniformsUtils.clone( shader.uniforms );
-			this.uniforms[ 'tDisp' ].value = this.generateHeightmap( dt_size );
+			this.heightMap = this.generateHeightmap( dt_size );
+			this.uniforms[ 'tDisp' ].value = this.heightMap;
 			this.material = new THREE.ShaderMaterial( {
 				uniforms: this.uniforms,
 				vertexShader: shader.vertexShader,
@@ -98,6 +99,14 @@
 
 		}
 
+		dispose() {
+
+			this.material.dispose();
+			this.heightMap.dispose();
+			this.fsQuad.dispose();
+
+		}
+
 	}
 
 	THREE.GlitchPass = GlitchPass;

+ 7 - 0
examples/js/postprocessing/HalftonePass.js

@@ -68,6 +68,13 @@
 
 		}
 
+		dispose() {
+
+			this.material.dispose();
+			this.fsQuad.dispose();
+
+		}
+
 	}
 
 	THREE.HalftonePass = HalftonePass;

+ 19 - 1
examples/js/postprocessing/OutlinePass.js

@@ -100,6 +100,14 @@
 			this.renderTargetBlurBuffer2.dispose();
 			this.renderTargetEdgeBuffer1.dispose();
 			this.renderTargetEdgeBuffer2.dispose();
+			this.depthMaterial.dispose();
+			this.prepareMaskMaterial.dispose();
+			this.edgeDetectionMaterial.dispose();
+			this.separableBlurMaterial1.dispose();
+			this.separableBlurMaterial2.dispose();
+			this.overlayMaterial.dispose();
+			this.materialCopy.dispose();
+			this.fsQuad.dispose();
 
 		}
 
@@ -384,9 +392,19 @@
 					#include <morphtarget_vertex>
 					#include <skinning_vertex>
 					#include <project_vertex>
-					#include <worldpos_vertex>
 
 					vPosition = mvPosition;
+
+					vec4 worldPosition = vec4( transformed, 1.0 );
+
+					#ifdef USE_INSTANCING
+
+						worldPosition = instanceMatrix * worldPosition;
+
+					#endif
+					
+					worldPosition = modelMatrix * worldPosition;
+
 					projTexCoord = textureMatrix * worldPosition;
 
 				}`,

+ 2 - 0
examples/js/postprocessing/Pass.js

@@ -23,6 +23,8 @@
 
 		}
 
+		dispose() {}
+
 	} // Helper for passes that need to fill the viewport with a single quad.
 
 

+ 18 - 0
examples/js/postprocessing/SAOPass.js

@@ -351,6 +351,24 @@
 
 		}
 
+		dispose() {
+
+			this.saoRenderTarget.dispose();
+			this.blurIntermediateRenderTarget.dispose();
+			this.beautyRenderTarget.dispose();
+			this.normalRenderTarget.dispose();
+			this.depthRenderTarget.dispose();
+			this.depthMaterial.dispose();
+			this.normalMaterial.dispose();
+			this.saoMaterial.dispose();
+			this.vBlurMaterial.dispose();
+			this.hBlurMaterial.dispose();
+			this.materialCopy.dispose();
+			this.depthCopy.dispose();
+			this.fsQuad.dispose();
+
+		}
+
 	}
 
 	SAOPass.OUTPUT = {

+ 13 - 0
examples/js/postprocessing/SMAAPass.js

@@ -146,6 +146,19 @@
 
 		}
 
+		dispose() {
+
+			this.edgesRT.dispose();
+			this.weightsRT.dispose();
+			this.areaTexture.dispose();
+			this.searchTexture.dispose();
+			this.materialEdges.dispose();
+			this.materialWeights.dispose();
+			this.materialBlend.dispose();
+			this.fsQuad.dispose();
+
+		}
+
 	}
 
 	THREE.SMAAPass = SMAAPass;

+ 3 - 0
examples/js/postprocessing/SSAARenderPass.js

@@ -49,6 +49,9 @@
 
 			}
 
+			this.copyMaterial.dispose();
+			this.fsQuad.dispose();
+
 		}
 
 		setSize( width, height ) {

+ 8 - 0
examples/js/postprocessing/SavePass.js

@@ -44,6 +44,14 @@
 
 		}
 
+		dispose() {
+
+			this.renderTarget.dispose();
+			this.material.dispose();
+			this.fsQuad.dispose();
+
+		}
+
 	}
 
 	THREE.SavePass = SavePass;

+ 7 - 0
examples/js/postprocessing/ShaderPass.js

@@ -56,6 +56,13 @@
 
 		}
 
+		dispose() {
+
+			this.material.dispose();
+			this.fsQuad.dispose();
+
+		}
+
 	}
 
 	THREE.ShaderPass = ShaderPass;

+ 8 - 0
examples/js/postprocessing/TAARenderPass.js

@@ -119,6 +119,14 @@
 
 		}
 
+		dispose() {
+
+			super.dispose();
+			if ( this.sampleRenderTarget !== undefined ) this.sampleRenderTarget.dispose();
+			if ( this.holdRenderTarget !== undefined ) this.holdRenderTarget.dispose();
+
+		}
+
 	}
 
 	const _JitterVectors = [[[ 0, 0 ]], [[ 4, 4 ], [ - 4, - 4 ]], [[ - 2, - 6 ], [ 6, - 2 ], [ - 6, 2 ], [ 2, 6 ]], [[ 1, - 3 ], [ - 1, 3 ], [ 5, 1 ], [ - 3, - 5 ], [ - 5, 5 ], [ - 7, - 1 ], [ 3, 7 ], [ 7, - 7 ]], [[ 1, 1 ], [ - 1, - 3 ], [ - 3, 2 ], [ 4, - 1 ], [ - 5, - 2 ], [ 2, 5 ], [ 5, 3 ], [ 3, - 5 ], [ - 2, 6 ], [ 0, - 7 ], [ - 4, - 6 ], [ - 6, 4 ], [ - 8, 0 ], [ 7, - 4 ], [ 6, 7 ], [ - 7, - 8 ]], [[ - 4, - 7 ], [ - 7, - 5 ], [ - 3, - 5 ], [ - 5, - 4 ], [ - 1, - 4 ], [ - 2, - 2 ], [ - 6, - 1 ], [ - 4, 0 ], [ - 7, 1 ], [ - 1, 2 ], [ - 6, 3 ], [ - 3, 3 ], [ - 7, 6 ], [ - 3, 6 ], [ - 5, 7 ], [ - 1, 7 ], [ 5, - 7 ], [ 1, - 6 ], [ 6, - 5 ], [ 4, - 4 ], [ 2, - 3 ], [ 7, - 2 ], [ 1, - 1 ], [ 4, - 1 ], [ 2, 1 ], [ 6, 2 ], [ 0, 4 ], [ 4, 4 ], [ 2, 5 ], [ 7, 5 ], [ 5, 6 ], [ 3, 7 ]]];

+ 7 - 0
examples/js/postprocessing/TexturePass.js

@@ -39,6 +39,13 @@
 
 		}
 
+		dispose() {
+
+			this.material.dispose();
+			this.fsQuad.dispose();
+
+		}
+
 	}
 
 	THREE.TexturePass = TexturePass;

+ 13 - 1
examples/js/postprocessing/UnrealBloomPass.js

@@ -129,7 +129,19 @@
 
 			}
 
-			this.renderTargetBright.dispose();
+			this.renderTargetBright.dispose(); //
+
+			for ( let i = 0; i < this.separableBlurMaterials.length; i ++ ) {
+
+				this.separableBlurMaterials[ i ].dispose();
+
+			}
+
+			this.compositeMaterial.dispose();
+			this.materialCopy.dispose();
+			this.basic.dispose(); //
+
+			this.fsQuad.dispose();
 
 		}
 

+ 25 - 31
examples/js/utils/BufferGeometryUtils.js

@@ -24,17 +24,16 @@
 
 			if ( attribute.normalized || attribute.isInterleavedBufferAttribute ) {
 
-				const srcArray = attribute.isInterleavedBufferAttribute ? attribute.data.array : attribute.array;
 				const dstArray = new Float32Array( attribute.getCount() * attribute.itemSize );
 
 				for ( let i = 0, j = 0; i < attribute.getCount(); i ++ ) {
 
-					dstArray[ j ++ ] = THREE.MathUtils.denormalize( attribute.getX( i ), srcArray );
-					dstArray[ j ++ ] = THREE.MathUtils.denormalize( attribute.getY( i ), srcArray );
+					dstArray[ j ++ ] = attribute.getX( i );
+					dstArray[ j ++ ] = attribute.getY( i );
 
 					if ( attribute.itemSize > 2 ) {
 
-						dstArray[ j ++ ] = THREE.MathUtils.denormalize( attribute.getZ( i ), srcArray );
+						dstArray[ j ++ ] = attribute.getZ( i );
 
 					}
 
@@ -532,20 +531,23 @@
 		let nextIndex = 0; // attributes and new attribute arrays
 
 		const attributeNames = Object.keys( geometry.attributes );
-		const attrArrays = {};
-		const morphAttrsArrays = {};
+		const tmpAttributes = {};
+		const tmpMorphAttributes = {};
 		const newIndices = [];
-		const getters = [ 'getX', 'getY', 'getZ', 'getW' ]; // initialize the arrays
+		const getters = [ 'getX', 'getY', 'getZ', 'getW' ];
+		const setters = [ 'setX', 'setY', 'setZ', 'setW' ]; // Initialize the arrays, allocating space conservatively. Extra
+		// space will be trimmed in the last step.
 
 		for ( let i = 0, l = attributeNames.length; i < l; i ++ ) {
 
 			const name = attributeNames[ i ];
-			attrArrays[ name ] = [];
+			const attr = geometry.attributes[ name ];
+			tmpAttributes[ name ] = new THREE.BufferAttribute( new attr.array.constructor( attr.count * attr.itemSize ), attr.itemSize, attr.normalized );
 			const morphAttr = geometry.morphAttributes[ name ];
 
 			if ( morphAttr ) {
 
-				morphAttrsArrays[ name ] = new Array( morphAttr.length ).fill().map( () => [] );
+				tmpMorphAttributes[ name ] = new THREE.BufferAttribute( new morphAttr.array.constructor( morphAttr.count * morphAttr.itemSize ), morphAttr.itemSize, morphAttr.normalized );
 
 			}
 
@@ -584,26 +586,27 @@
 
 			} else {
 
-				// copy data to the new index in the attribute arrays
+				// copy data to the new index in the temporary attributes
 				for ( let j = 0, l = attributeNames.length; j < l; j ++ ) {
 
 					const name = attributeNames[ j ];
 					const attribute = geometry.getAttribute( name );
 					const morphAttr = geometry.morphAttributes[ name ];
 					const itemSize = attribute.itemSize;
-					const newarray = attrArrays[ name ];
-					const newMorphArrays = morphAttrsArrays[ name ];
+					const newarray = tmpAttributes[ name ];
+					const newMorphArrays = tmpMorphAttributes[ name ];
 
 					for ( let k = 0; k < itemSize; k ++ ) {
 
 						const getterFunc = getters[ k ];
-						newarray.push( attribute[ getterFunc ]( index ) );
+						const setterFunc = setters[ k ];
+						newarray[ setterFunc ]( nextIndex, attribute[ getterFunc ]( index ) );
 
 						if ( morphAttr ) {
 
 							for ( let m = 0, ml = morphAttr.length; m < ml; m ++ ) {
 
-								newMorphArrays[ m ].push( morphAttr[ m ][ getterFunc ]( index ) );
+								newMorphArrays[ m ][ setterFunc ]( nextIndex, morphAttr[ m ][ getterFunc ]( index ) );
 
 							}
 
@@ -619,30 +622,21 @@
 
 			}
 
-		} // Generate typed arrays from new attribute arrays and update
-		// the attributeBuffers
+		} // generate result THREE.BufferGeometry
 
 
 		const result = geometry.clone();
 
-		for ( let i = 0, l = attributeNames.length; i < l; i ++ ) {
-
-			const name = attributeNames[ i ];
-			const oldAttribute = geometry.getAttribute( name );
-			const buffer = new oldAttribute.array.constructor( attrArrays[ name ] );
-			const attribute = new THREE.BufferAttribute( buffer, oldAttribute.itemSize, oldAttribute.normalized );
-			result.setAttribute( name, attribute ); // Update the attribute arrays
-
-			if ( name in morphAttrsArrays ) {
+		for ( const name in geometry.attributes ) {
 
-				for ( let j = 0; j < morphAttrsArrays[ name ].length; j ++ ) {
+			const tmpAttribute = tmpAttributes[ name ];
+			result.setAttribute( name, new THREE.BufferAttribute( tmpAttribute.array.slice( 0, nextIndex * tmpAttribute.itemSize ), tmpAttribute.itemSize, tmpAttribute.normalized ) );
+			if ( ! ( name in tmpMorphAttributes ) ) continue;
 
-					const oldMorphAttribute = geometry.morphAttributes[ name ][ j ];
-					const buffer = new oldMorphAttribute.array.constructor( morphAttrsArrays[ name ][ j ] );
-					const morphAttribute = new THREE.BufferAttribute( buffer, oldMorphAttribute.itemSize, oldMorphAttribute.normalized );
-					result.morphAttributes[ name ][ j ] = morphAttribute;
+			for ( let j = 0; j < tmpMorphAttributes[ name ].length; j ++ ) {
 
-				}
+				const tmpMorphAttribute = tmpMorphAttributes[ name ][ j ];
+				result.morphAttributes[ name ][ j ] = new THREE.BufferAttribute( tmpMorphAttribute.array.slice( 0, nextIndex * tmpMorphAttribute.itemSize ), tmpMorphAttribute.itemSize, tmpMorphAttribute.normalized );
 
 			}