diff --git a/src/renderers/common/Renderer.js b/src/renderers/common/Renderer.js index 9bf337c0d37f50..b9af1664701937 100644 --- a/src/renderers/common/Renderer.js +++ b/src/renderers/common/Renderer.js @@ -1284,11 +1284,56 @@ class Renderer { copyFramebufferToTexture( framebufferTexture, rectangle = null ) { - const renderContext = this._currentRenderContext; + if ( rectangle !== null ) { + + if ( rectangle.isVector2 ) { + + rectangle = _vector4.set( rectangle.x, rectangle.y, framebufferTexture.image.width, framebufferTexture.image.height ).floor(); + + } else if ( rectangle.isVector4 ) { + + rectangle = _vector4.copy( rectangle ).floor(); + + } else { + + console.error( 'THREE.Renderer.copyFramebufferToTexture: Invalid rectangle.' ); + + return; + + } + + } else { + + rectangle = _vector4.set( 0, 0, framebufferTexture.image.width, framebufferTexture.image.height ); + + } + + // + + let renderContext = this._currentRenderContext; + let renderTarget; + + if ( renderContext !== null ) { + + renderTarget = renderContext.renderTarget; + + } else { + + renderTarget = this._renderTarget || this._getFrameBufferTarget(); + + if ( renderTarget !== null ) { - this._textures.updateTexture( framebufferTexture ); + this._textures.updateRenderTarget( renderTarget ); - rectangle = rectangle === null ? _vector4.set( 0, 0, framebufferTexture.image.width, framebufferTexture.image.height ) : rectangle; + renderContext = this._textures.get( renderTarget ); + + } + + } + + // + + this._textures.updateTexture( framebufferTexture, { renderTarget } ); this.backend.copyFramebufferToTexture( framebufferTexture, renderContext, rectangle ); @@ -1303,7 +1348,6 @@ class Renderer { } - readRenderTargetPixelsAsync( renderTarget, x, y, width, height, index = 0, faceIndex = 0 ) { return this.backend.copyTextureToBuffer( renderTarget.textures[ index ], x, y, width, height, faceIndex ); diff --git a/src/renderers/common/Textures.js b/src/renderers/common/Textures.js index 3a817fcd450814..6907194c8236c1 100644 --- a/src/renderers/common/Textures.js +++ b/src/renderers/common/Textures.js @@ -160,8 +160,7 @@ class Textures extends DataMap { if ( texture.isFramebufferTexture ) { - const renderer = this.renderer; - const renderTarget = renderer.getRenderTarget(); + const renderTarget = this.renderer.getRenderTarget(); if ( renderTarget ) { diff --git a/src/renderers/webgl-fallback/utils/WebGLTextureUtils.js b/src/renderers/webgl-fallback/utils/WebGLTextureUtils.js index 94012f3b4609e7..8f9c0448016e5a 100644 --- a/src/renderers/webgl-fallback/utils/WebGLTextureUtils.js +++ b/src/renderers/webgl-fallback/utils/WebGLTextureUtils.js @@ -606,9 +606,9 @@ class WebGLTextureUtils { const { textureGPU: dstTextureGPU, glTextureType, glType, glFormat } = backend.get( dstTexture ); - let width, height, minX, minY; let dstX, dstY; + if ( srcRegion !== null ) { width = srcRegion.max.x - srcRegion.min.x; diff --git a/src/renderers/webgpu/WebGPUBackend.js b/src/renderers/webgpu/WebGPUBackend.js index d480f3987634cc..410e67a979eda1 100644 --- a/src/renderers/webgpu/WebGPUBackend.js +++ b/src/renderers/webgpu/WebGPUBackend.js @@ -1469,8 +1469,6 @@ class WebGPUBackend extends Backend { const renderContextData = this.get( renderContext ); - const { encoder, descriptor } = renderContextData; - let sourceGPU = null; if ( renderContext.renderTarget ) { @@ -1509,7 +1507,19 @@ class WebGPUBackend extends Backend { } - renderContextData.currentPass.end(); + let encoder; + + if ( renderContextData.currentPass ) { + + renderContextData.currentPass.end(); + + encoder = renderContextData.encoder; + + } else { + + encoder = this.device.createCommandEncoder( { label: 'copyFramebufferToTexture_' + texture.id } ); + + } encoder.copyTextureToTexture( { @@ -1527,17 +1537,27 @@ class WebGPUBackend extends Backend { if ( texture.generateMipmaps ) this.textureUtils.generateMipmaps( texture ); - for ( let i = 0; i < descriptor.colorAttachments.length; i ++ ) { + if ( renderContextData.currentPass ) { - descriptor.colorAttachments[ i ].loadOp = GPULoadOp.Load; + const { descriptor } = renderContextData; - } + for ( let i = 0; i < descriptor.colorAttachments.length; i ++ ) { - if ( renderContext.depth ) descriptor.depthStencilAttachment.depthLoadOp = GPULoadOp.Load; - if ( renderContext.stencil ) descriptor.depthStencilAttachment.stencilLoadOp = GPULoadOp.Load; + descriptor.colorAttachments[ i ].loadOp = GPULoadOp.Load; - renderContextData.currentPass = encoder.beginRenderPass( descriptor ); - renderContextData.currentSets = { attributes: {}, bindingGroups: [], pipeline: null, index: null }; + } + + if ( renderContext.depth ) descriptor.depthStencilAttachment.depthLoadOp = GPULoadOp.Load; + if ( renderContext.stencil ) descriptor.depthStencilAttachment.stencilLoadOp = GPULoadOp.Load; + + renderContextData.currentPass = encoder.beginRenderPass( descriptor ); + renderContextData.currentSets = { attributes: {}, bindingGroups: [], pipeline: null, index: null }; + + } else { + + this.device.queue.submit( [ encoder.finish() ] ); + + } } diff --git a/src/renderers/webgpu/utils/WebGPUTextureUtils.js b/src/renderers/webgpu/utils/WebGPUTextureUtils.js index 08d2f22bc2273f..b24be132721844 100644 --- a/src/renderers/webgpu/utils/WebGPUTextureUtils.js +++ b/src/renderers/webgpu/utils/WebGPUTextureUtils.js @@ -127,6 +127,20 @@ class WebGPUTextureUtils { const { width, height, depth, levels } = options; + if ( texture.isFramebufferTexture ) { + + if ( options.renderTarget ) { + + options.format = this.backend.utils.getCurrentColorFormat( options.renderTarget ); + + } else { + + options.format = this.backend.utils.getPreferredCanvasFormat(); + + } + + } + const dimension = this._getDimension( texture ); const format = texture.internalFormat || options.format || getFormat( texture, backend.device ); @@ -858,11 +872,7 @@ export function getFormat( texture, device = null ) { let formatGPU; - if ( texture.isFramebufferTexture === true && texture.type === UnsignedByteType ) { - - formatGPU = GPUTextureFormat.BGRA8Unorm; - - } else if ( texture.isCompressedTexture === true || texture.isCompressedArrayTexture === true ) { + if ( texture.isCompressedTexture === true || texture.isCompressedArrayTexture === true ) { switch ( format ) { diff --git a/src/renderers/webgpu/utils/WebGPUUtils.js b/src/renderers/webgpu/utils/WebGPUUtils.js index d89ef8fc7880fd..f7ba94556d98e4 100644 --- a/src/renderers/webgpu/utils/WebGPUUtils.js +++ b/src/renderers/webgpu/utils/WebGPUUtils.js @@ -44,7 +44,6 @@ class WebGPUUtils { format = this.getTextureFormatGPU( renderContext.textures[ 0 ] ); - } else { format = this.getPreferredCanvasFormat(); // default context format