diff --git a/docs/api/en/renderers/WebGLRenderer.html b/docs/api/en/renderers/WebGLRenderer.html index 6b49a59f5caf06..ad2f41a6271c85 100644 --- a/docs/api/en/renderers/WebGLRenderer.html +++ b/docs/api/en/renderers/WebGLRenderer.html @@ -380,21 +380,13 @@

- [method:undefined copyTextureToTexture]( [param:Texture srcTexture], [param:Texture dstTexture], [param:Box2 srcRegion], [param:Vector2 dstPosition], [param:Number level] ) -

-

- Copies the pixels of a texture in the bounds '[page:Box2 srcRegion]' in the destination texture starting from the given position. - The `depthTexture` and `texture` property of render targets are supported as well.
- When using render target textures as `srcTexture` and `dstTexture`, you must make sure both render targets are intitialized e.g. via [page:.initRenderTarget](). -

- -

- [method:undefined copyTextureToTexture3D]( [param:Texture srcTexture], [param:Texture dstTexture], [param:Box3 srcRegion], [param:Vector3 dstPosition], [param:Number level] ) + [method:undefined copyTextureToTexture]( [param:Texture srcTexture], [param:Texture dstTexture], [param:Box2 srcRegion] | [param:Box3 srcRegion], [param:Vector2 dstPosition] | [param:Vector3 dstPosition], [param:Number dstLevel] )

Copies the pixels of a texture in the bounds '[page:Box3 srcRegion]' in the destination texture starting from the given position. - The `depthTexture` and `texture` property of 3D render targets are supported as well.
- When using render target textures as `srcTexture` and `dstTexture`, you must make sure both render targets are intitialized e.g. via [page:.initRenderTarget](). + 2D Texture, 3D Textures, or a mix of the two can be used as source and destination texture arguments for copying between layers of 3d textures.
+ The `depthTexture` and `texture` property of render targets are supported as well.
+ When using render target textures as `srcTexture` and `dstTexture`, you must make sure both render targets are initialized e.g. via [page:.initRenderTarget]().

[method:undefined dispose]( )

diff --git a/src/objects/BatchedMesh.js b/src/objects/BatchedMesh.js index e873e3c8f53313..cf1617951bb6e5 100644 --- a/src/objects/BatchedMesh.js +++ b/src/objects/BatchedMesh.js @@ -744,6 +744,7 @@ class BatchedMesh extends Mesh { } nextVertexStart += geometryInfo.reservedVertexCount; + geometryInfo.start = geometry.index ? geometryInfo.indexStart : geometryInfo.vertexStart; // step the next geometry points to the shifted position this._nextIndexStart = geometry.index ? geometryInfo.indexStart + geometryInfo.reservedIndexCount : 0; diff --git a/src/renderers/WebGLRenderer.js b/src/renderers/WebGLRenderer.js index 33bf1a112c0e64..dc6219794ceee2 100644 --- a/src/renderers/WebGLRenderer.js +++ b/src/renderers/WebGLRenderer.js @@ -2579,134 +2579,7 @@ class WebGLRenderer { } - let width, height, minX, minY; - let dstX, dstY; - if ( srcRegion !== null ) { - - width = srcRegion.max.x - srcRegion.min.x; - height = srcRegion.max.y - srcRegion.min.y; - minX = srcRegion.min.x; - minY = srcRegion.min.y; - - } else { - - width = srcTexture.image.width; - height = srcTexture.image.height; - minX = 0; - minY = 0; - - } - - if ( dstPosition !== null ) { - - dstX = dstPosition.x; - dstY = dstPosition.y; - - } else { - - dstX = 0; - dstY = 0; - - } - - const glFormat = utils.convert( dstTexture.format ); - const glType = utils.convert( dstTexture.type ); - - textures.setTexture2D( dstTexture, 0 ); - - // As another texture upload may have changed pixelStorei - // parameters, make sure they are correct for the dstTexture - _gl.pixelStorei( _gl.UNPACK_FLIP_Y_WEBGL, dstTexture.flipY ); - _gl.pixelStorei( _gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, dstTexture.premultiplyAlpha ); - _gl.pixelStorei( _gl.UNPACK_ALIGNMENT, dstTexture.unpackAlignment ); - - const currentUnpackRowLen = _gl.getParameter( _gl.UNPACK_ROW_LENGTH ); - const currentUnpackImageHeight = _gl.getParameter( _gl.UNPACK_IMAGE_HEIGHT ); - const currentUnpackSkipPixels = _gl.getParameter( _gl.UNPACK_SKIP_PIXELS ); - const currentUnpackSkipRows = _gl.getParameter( _gl.UNPACK_SKIP_ROWS ); - const currentUnpackSkipImages = _gl.getParameter( _gl.UNPACK_SKIP_IMAGES ); - - const image = srcTexture.isCompressedTexture ? srcTexture.mipmaps[ level ] : srcTexture.image; - - _gl.pixelStorei( _gl.UNPACK_ROW_LENGTH, image.width ); - _gl.pixelStorei( _gl.UNPACK_IMAGE_HEIGHT, image.height ); - _gl.pixelStorei( _gl.UNPACK_SKIP_PIXELS, minX ); - _gl.pixelStorei( _gl.UNPACK_SKIP_ROWS, minY ); - - if ( srcTexture.isRenderTargetTexture || 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 ); - - if ( srcTexture.isDepthTexture ) { - - _gl.blitFramebuffer( minX, minY, width, height, dstX, dstY, width, height, _gl.DEPTH_BUFFER_BIT, _gl.NEAREST ); - - } else { - - _gl.copyTexSubImage2D( _gl.TEXTURE_2D, level, dstX, dstY, minX, minY, width, height ); - - } - - state.bindFramebuffer( _gl.READ_FRAMEBUFFER, null ); - state.bindFramebuffer( _gl.DRAW_FRAMEBUFFER, null ); - - } else { - - if ( srcTexture.isDataTexture ) { - - _gl.texSubImage2D( _gl.TEXTURE_2D, level, dstX, dstY, width, height, glFormat, glType, image.data ); - - } else { - - if ( srcTexture.isCompressedTexture ) { - - _gl.compressedTexSubImage2D( _gl.TEXTURE_2D, level, dstX, dstY, image.width, image.height, glFormat, image.data ); - - } else { - - _gl.texSubImage2D( _gl.TEXTURE_2D, level, dstX, dstY, width, height, glFormat, glType, image ); - - } - - } - - } - - _gl.pixelStorei( _gl.UNPACK_ROW_LENGTH, currentUnpackRowLen ); - _gl.pixelStorei( _gl.UNPACK_IMAGE_HEIGHT, currentUnpackImageHeight ); - _gl.pixelStorei( _gl.UNPACK_SKIP_PIXELS, currentUnpackSkipPixels ); - _gl.pixelStorei( _gl.UNPACK_SKIP_ROWS, currentUnpackSkipRows ); - _gl.pixelStorei( _gl.UNPACK_SKIP_IMAGES, currentUnpackSkipImages ); - - // Generate mipmaps only when copying level 0 - if ( level === 0 && dstTexture.generateMipmaps ) _gl.generateMipmap( _gl.TEXTURE_2D ); - - state.unbindTexture(); - - }; - - this.copyTextureToTexture3D = function ( srcTexture, dstTexture, srcRegion = null, dstPosition = null, level = 0 ) { - - // support previous signature with source box first - if ( srcTexture.isTexture !== true ) { - - // @deprecated, r165 - warnOnce( 'WebGLRenderer: copyTextureToTexture3D function signature has changed.' ); - - srcRegion = arguments[ 0 ] || null; - dstPosition = arguments[ 1 ] || null; - srcTexture = arguments[ 2 ]; - dstTexture = arguments[ 3 ]; - level = arguments[ 4 ] || 0; - - } - + // gather the necessary dimensions to copy let width, height, depth, minX, minY, minZ; let dstX, dstY, dstZ; const image = srcTexture.isCompressedTexture ? srcTexture.mipmaps[ level ] : srcTexture.image; @@ -2714,16 +2587,16 @@ class WebGLRenderer { width = srcRegion.max.x - srcRegion.min.x; height = srcRegion.max.y - srcRegion.min.y; - depth = srcRegion.max.z - srcRegion.min.z; + depth = srcRegion.isBox3 ? srcRegion.max.z - srcRegion.min.z : 1; minX = srcRegion.min.x; minY = srcRegion.min.y; - minZ = srcRegion.min.z; + minZ = srcRegion.isBox3 ? srcRegion.min.z : 0; } else { width = image.width; height = image.height; - depth = image.depth; + depth = image.depth || 1; minX = 0; minY = 0; minZ = 0; @@ -2744,6 +2617,7 @@ class WebGLRenderer { } + // Set up the destination target const glFormat = utils.convert( dstTexture.format ); const glType = utils.convert( dstTexture.type ); let glTarget; @@ -2760,8 +2634,8 @@ class WebGLRenderer { } else { - console.warn( 'THREE.WebGLRenderer.copyTextureToTexture3D: only supports THREE.DataTexture3D and THREE.DataTexture2DArray.' ); - return; + textures.setTexture2D( dstTexture, 0 ); + glTarget = _gl.TEXTURE_2D; } @@ -2769,6 +2643,7 @@ class WebGLRenderer { _gl.pixelStorei( _gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, dstTexture.premultiplyAlpha ); _gl.pixelStorei( _gl.UNPACK_ALIGNMENT, dstTexture.unpackAlignment ); + // used for copying data from cpu const currentUnpackRowLen = _gl.getParameter( _gl.UNPACK_ROW_LENGTH ); const currentUnpackImageHeight = _gl.getParameter( _gl.UNPACK_IMAGE_HEIGHT ); const currentUnpackSkipPixels = _gl.getParameter( _gl.UNPACK_SKIP_PIXELS ); @@ -2781,6 +2656,9 @@ class WebGLRenderer { _gl.pixelStorei( _gl.UNPACK_SKIP_ROWS, minY ); _gl.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.isRenderTargetTexture || srcTexture.isDepthTexture ) { const srcTextureProperties = properties.get( srcTexture ); @@ -2793,17 +2671,31 @@ class WebGLRenderer { for ( let i = 0; i < depth; i ++ ) { - _gl.framebufferTextureLayer( _gl.READ_FRAMEBUFFER, _gl.COLOR_ATTACHMENT0, properties.get( srcTexture ).__webglTexture, level, minZ + 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, level, minZ + i ); + + } if ( srcTexture.isDepthTexture ) { - _gl.framebufferTextureLayer( _gl.DRAW_FRAMEBUFFER, _gl.COLOR_ATTACHMENT0, properties.get( dstTexture ).__webglTexture, level, dstZ + i ); + if ( isDst3D ) { + + _gl.framebufferTextureLayer( _gl.DRAW_FRAMEBUFFER, _gl.COLOR_ATTACHMENT0, properties.get( dstTexture ).__webglTexture, level, dstZ + i ); + + } + _gl.blitFramebuffer( minX, minY, width, height, dstX, dstY, width, height, _gl.DEPTH_BUFFER_BIT, _gl.NEAREST ); - } else { + } else if ( isDst3D ) { _gl.copyTexSubImage3D( glTarget, level, dstX, dstY, dstZ + i, minX, minY, width, height ); + } else { + + _gl.copyTexSubImage2D( glTarget, level, dstX, dstY, dstZ + i, minX, minY, width, height ); + } } @@ -2813,13 +2705,14 @@ class WebGLRenderer { } else { - if ( srcTexture.isDataTexture || srcTexture.isData3DTexture ) { + if ( isDst3D ) { - _gl.texSubImage3D( glTarget, level, dstX, dstY, dstZ, width, height, depth, glFormat, glType, image.data ); + // copy data into the 3d texture + if ( srcTexture.isDataTexture || srcTexture.isData3DTexture ) { - } else { + _gl.texSubImage3D( glTarget, level, dstX, dstY, dstZ, width, height, depth, glFormat, glType, image.data ); - if ( dstTexture.isCompressedArrayTexture ) { + } else if ( dstTexture.isCompressedArrayTexture ) { _gl.compressedTexSubImage3D( glTarget, level, dstX, dstY, dstZ, width, height, depth, glFormat, image.data ); @@ -2829,10 +2722,28 @@ class WebGLRenderer { } + } else { + + // copy data into the 2d texture + if ( srcTexture.isDataTexture ) { + + _gl.texSubImage2D( _gl.TEXTURE_2D, level, dstX, dstY, width, height, glFormat, glType, image.data ); + + } else if ( srcTexture.isCompressedTexture ) { + + _gl.compressedTexSubImage2D( _gl.TEXTURE_2D, level, dstX, dstY, image.width, image.height, glFormat, image.data ); + + } else { + + _gl.texSubImage2D( _gl.TEXTURE_2D, level, dstX, dstY, width, height, glFormat, glType, image ); + + } + } } + // reset values _gl.pixelStorei( _gl.UNPACK_ROW_LENGTH, currentUnpackRowLen ); _gl.pixelStorei( _gl.UNPACK_IMAGE_HEIGHT, currentUnpackImageHeight ); _gl.pixelStorei( _gl.UNPACK_SKIP_PIXELS, currentUnpackSkipPixels ); @@ -2840,12 +2751,39 @@ class WebGLRenderer { _gl.pixelStorei( _gl.UNPACK_SKIP_IMAGES, currentUnpackSkipImages ); // Generate mipmaps only when copying level 0 - if ( level === 0 && dstTexture.generateMipmaps ) _gl.generateMipmap( glTarget ); + if ( level === 0 && dstTexture.generateMipmaps ) { + + _gl.generateMipmap( glTarget ); + + } state.unbindTexture(); }; + this.copyTextureToTexture3D = function ( srcTexture, dstTexture, srcRegion = null, dstPosition = null, level = 0 ) { + + // support previous signature with source box first + if ( srcTexture.isTexture !== true ) { + + // @deprecated, r165 + warnOnce( 'WebGLRenderer: copyTextureToTexture3D function signature has changed.' ); + + srcRegion = arguments[ 0 ] || null; + dstPosition = arguments[ 1 ] || null; + srcTexture = arguments[ 2 ]; + dstTexture = arguments[ 3 ]; + level = arguments[ 4 ] || 0; + + } + + // @deprecated, r170 + warnOnce( 'WebGLRenderer: copyTextureToTexture3D function has been deprecated. Use "copyTextureToTexture" instead.' ); + + return this.copyTextureToTexture( srcTexture, dstTexture, srcRegion, dstPosition, level ); + + }; + this.initRenderTarget = function ( target ) { if ( properties.get( target ).__webglFramebuffer === undefined ) {