docs: function updateObject( object ) {
  
  		var geometry = object.geometry;
  
  		if ( geometry instanceof THREE.BufferGeometry ) {
  
  			var attributes = geometry.attributes;
  			var attributesKeys = geometry.attributesKeys;
  
  			for ( var i = 0, l = attributesKeys.length; i < l; i ++ ) {
  
  				var key = attributesKeys[ i ];
  				var attribute = attributes[ key ];
  
  				if ( attribute.buffer === undefined ) {
  
  					attribute.buffer = _gl.createBuffer();
  					attribute.needsUpdate = true;
  
  				}
  
  				if ( attribute.needsUpdate === true ) {
  
  					var bufferType = ( key === 'index' ) ? _gl.ELEMENT_ARRAY_BUFFER : _gl.ARRAY_BUFFER;
  
  					_gl.bindBuffer( bufferType, attribute.buffer );
  					_gl.bufferData( bufferType, attribute.array, _gl.STATIC_DRAW );
  
  					attribute.needsUpdate = false;
  
  				}
  
  			}
  
  		} else if ( object instanceof THREE.Mesh ) {
  
  			// check all geometry groups
  
  			if ( geometry.groupsNeedUpdate === true ) {
  
  				initGeometryGroups( object, geometry );
  
  			}
  
  			var geometryGroupsList = geometryGroups[ geometry.id ];
  
  			for ( var i = 0, il = geometryGroupsList.length; i < il; i ++ ) {
  
  				var geometryGroup = geometryGroupsList[ i ];
  				var material = getBufferMaterial( object, geometryGroup );
  
  				if ( geometry.groupsNeedUpdate === true ) {
  
  					initMeshBuffers( geometryGroup, object );
  
  				}
  
  				var customAttributesDirty = material.attributes && areCustomAttributesDirty( material );
  
  				if ( geometry.verticesNeedUpdate || geometry.morphTargetsNeedUpdate || geometry.elementsNeedUpdate ||
  					 geometry.uvsNeedUpdate || geometry.normalsNeedUpdate ||
  					 geometry.colorsNeedUpdate || geometry.tangentsNeedUpdate || customAttributesDirty ) {
  
  					setMeshBuffers( geometryGroup, object, _gl.DYNAMIC_DRAW, ! geometry.dynamic, material );
  
  				}
  
  			}
  
  			geometry.verticesNeedUpdate = false;
  			geometry.morphTargetsNeedUpdate = false;
  			geometry.elementsNeedUpdate = false;
  			geometry.uvsNeedUpdate = false;
  			geometry.normalsNeedUpdate = false;
  			geometry.colorsNeedUpdate = false;
  			geometry.tangentsNeedUpdate = false;
  
  			material.attributes && clearCustomAttributes( material );
  
  		} else if ( object instanceof THREE.Line ) {
  
  			var material = getBufferMaterial( object, geometry );
  			var customAttributesDirty = material.attributes && areCustomAttributesDirty( material );
  
  			if ( geometry.verticesNeedUpdate || geometry.colorsNeedUpdate || geometry.lineDistancesNeedUpdate || customAttributesDirty ) {
  
  				setLineBuffers( geometry, _gl.DYNAMIC_DRAW );
  
  			}
  
  			geometry.verticesNeedUpdate = false;
  			geometry.colorsNeedUpdate = false;
  			geometry.lineDistancesNeedUpdate = false;
  
  			material.attributes && clearCustomAttributes( material );
  
  		} else if ( object instanceof THREE.PointCloud ) {
  
  			var material = getBufferMaterial( object, geometry );
  			var customAttributesDirty = material.attributes && areCustomAttributesDirty( material );
  
  			if ( geometry.verticesNeedUpdate || geometry.colorsNeedUpdate || customAttributesDirty ) {
  
  				setParticleBuffers( geometry, _gl.DYNAMIC_DRAW, object );
  
  			}
  
  			geometry.verticesNeedUpdate = false;
  			geometry.colorsNeedUpdate = false;
  
  			material.attributes && clearCustomAttributes( material );
  
  		}
  
  	}