<!-- SOLUV · part 438 -->
Y = dstPosition.y;
				dstZ = dstPosition.z;

			} else {

				dstX = 0;
				dstY = 0;
				dstZ = 0;

			}

			// Set up the destination target
			const glFormat = utils.convert( dstTexture.format );
			const glType = utils.convert( dstTexture.type );
			let glTarget;

			if ( dstTexture.isData3DTexture ) {

				textures.setTexture3D( dstTexture, 0 );
				glTarget = _gl.TEXTURE_3D;

			} else if ( dstTexture.isDataArrayTexture || dstTexture.isCompressedArrayTexture ) {

				textures.setTexture2DArray( dstTexture, 0 );
				glTarget = _gl.TEXTURE_2D_ARRAY;

			} else {

				textures.setTexture2D( dstTexture, 0 );
				glTarget = _gl.TEXTURE_2D;

			}

			state.activeTexture( _gl.TEXTURE0 ); // see #33153

			state.pixelStorei( _gl.UNPACK_FLIP_Y_WEBGL, dstTexture.flipY );
			state.pixelStorei( _gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, dstTexture.premultiplyAlpha );
			state.pixelStorei( _gl.UNPACK_ALIGNMENT, dstTexture.unpackAlignment );

			// used for copying data from cpu
			const currentUnpackRowLen = state.getParameter( _gl.UNPACK_ROW_LENGTH );
			const currentUnpackImageHeight = state.getParameter( _gl.UNPACK_IMAGE_HEIGHT );
			const currentUnpackSkipPixels = state.getParameter( _gl.UNPACK_SKIP_PIXELS );
			const currentUnpackSkipRows = state.getParameter( _gl.UNPACK_SKIP_ROWS );
			const currentUnpackSkipImages = state.getParameter( _gl.UNPACK_SKIP_IMAGES );

			state.pixelStorei( _gl.UNPACK_ROW_LENGTH, image.width );
			state.pixelStorei( _gl.UNPACK_IMAGE_HEIGHT, image.height );
			state.pixelStorei( _gl.UNPACK_SKIP_PIXELS, minX );
			state.pixelStorei( _gl.UNPACK_SKIP_ROWS, minY );
			state.pixelStorei( _gl.UNPACK_SKIP_IMAGES, minZ );

			// set up the src texture
			const isSrc3D = srcTexture.isDataArrayTexture || srcTexture.isData3DTexture;
			const isDst3D = dstTexture.isDataArrayTexture || dstTexture.isData3DTexture;
			if ( srcTexture.isDepthTexture ) {

				const srcTextureProperties = properties.get( srcTexture );
				const dstTextureProperties = properties.get( dstTexture );
				const srcRenderTargetProperties = properties.get( srcTextureProperties.__renderTarget );
				const dstRenderTargetProperties = properties.get( dstTextureProperties.__renderTarget );
				state.bindFramebuffer( _gl.READ_FRAMEBUFFER, srcRenderTargetProperties.__webglFramebuffer );
				state.bindFramebuffer( _gl.DRAW_FRAMEBUFFER, dstRenderTargetProperties.__webglFramebuffer );

				for ( let i = 0; i < depth; i ++ ) {

					// if the source or destination are a 3d target then a layer needs to be bound
					if ( isSrc3D ) {

						_gl.framebufferTextureLayer( _gl.READ_FRAMEBUFFER, _gl.COLOR_ATTACHMENT0, properties.get( srcTexture ).__webglTexture, srcLevel, minZ + i );
						_gl.framebufferTextureLayer( _gl.DRAW_FRAMEBUFFER, _gl.COLOR_ATTACHMENT0, properties.get( dstTexture ).__webglTexture, dstLevel, dstZ + i );

					}

					_gl.blitFramebuffer( minX, minY, width, height, dstX, dstY, width, height, _gl.DEPTH_BUFFER_BIT, _gl.NEAREST );

				}

				state.bindFramebuffer( _gl.READ_FRAMEBUFFER, null );
				state.bindFramebuffer( _gl.DRAW_FRAMEBUFFER, null );

			} else if ( srcLevel !== 0 || srcTexture.isRenderTargetTexture || properties.has( srcTexture ) ) {

				// get the appropriate frame buffers
				const srcTextureProperties = properties.get( srcTexture );
				const dstTextureProperties = properties.get( dstTexture );

				// bind the frame buffer targets
				state.bindFramebuffer( _gl.READ_FRAMEBUFFER, _srcFramebuffer );
				state.bindFramebuffer( _gl.DRAW_FRAMEBUFFER, _dstFramebuffer );

				for ( let i = 0; i < depth; i ++ ) {

					// assign the correct layers and mip maps to the frame buffers
					if ( isSrc3D ) {

						_gl.framebufferTextureLayer( _gl.READ_FRAMEBUFFER, _gl.COLOR_ATTACHMENT0, srcTextureProperties.__webglTexture, srcLevel, minZ + i );

					} else {

						_gl.framebufferTexture2D( _gl.READ_FRAMEBUFFER, _gl.COLOR_ATTACHMENT0, _gl.TEXTURE_2D, srcTextureProperties.__webglTexture, srcLevel );

					}

					if ( isDst3D ) {

						_gl.framebufferTextureLayer( _gl.DRAW_FRAMEBUFFER, _gl.COLOR_ATTACHMENT0, dstTextureProperties.__webglTexture, dstLevel, dstZ + i );

					} else {

						_gl.framebufferTexture2D( _gl.DRAW_FRAMEBUFFER, _gl.COLOR_ATTACHMENT0, _gl.TEXTURE_2D, dstTextureProperties.__webglTexture, dstLevel );

					}

					// copy the data using the fastest function that can achieve the copy
					if ( srcLevel !== 0 ) {

						_gl.blitFramebuffer( minX, minY, width, height, dstX, dstY, width, height, _gl.COLOR_BUFFER_BIT, _gl.NEAREST );

					} else if ( isDst3D ) {

						_gl.copyTexSubImage3D( glTarget, dstLevel, dstX, dstY, dstZ + i, minX, minY, width, height );

					} else {

						_gl.copyTexSubImage2D( glTarget, dstLevel, dstX, dstY, minX, minY, width, height );

					}

				}

				// unbind read, draw buffers
				state.bindFramebuffer( _gl.READ_FRAMEBUFFER, null );
				state.bindFramebuffer( _gl.DRAW_FRAMEBUFFER, null );

			} else {

				if ( isDst3D ) {

					// co