Skip to content

Commit a6fba0f

Browse files
WebGPURenderer: copyTextureToTexture subframe upload and new API (#28315)
* align copyTextureToTexture with webglrenderer * Update webgpu_materials_texture_partialupdate.html ---------
1 parent 232b4ea commit a6fba0f

File tree

4 files changed

+71
-11
lines changed

4 files changed

+71
-11
lines changed

examples/jsm/renderers/common/Renderer.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1086,12 +1086,12 @@ class Renderer {
10861086

10871087
}
10881088

1089-
copyTextureToTexture( position, srcTexture, dstTexture, level = 0 ) {
1089+
copyTextureToTexture( srcTexture, dstTexture, srcRegion = null, dstPosition = null, level = 0 ) {
10901090

10911091
this._textures.updateTexture( srcTexture );
10921092
this._textures.updateTexture( dstTexture );
10931093

1094-
this.backend.copyTextureToTexture( position, srcTexture, dstTexture, level );
1094+
this.backend.copyTextureToTexture( srcTexture, dstTexture, srcRegion, dstPosition, level );
10951095

10961096
}
10971097

examples/jsm/renderers/webgl/utils/WebGLTextureUtils.js

Lines changed: 56 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -524,41 +524,91 @@ class WebGLTextureUtils {
524524

525525
}
526526

527-
copyTextureToTexture( position, srcTexture, dstTexture, level = 0 ) {
527+
copyTextureToTexture( srcTexture, dstTexture, srcRegion = null, dstPosition = null, level = 0 ) {
528528

529529
const { gl, backend } = this;
530530
const { state } = this.backend;
531531

532-
const width = srcTexture.image.width;
533-
const height = srcTexture.image.height;
534532
const { textureGPU: dstTextureGPU, glTextureType, glType, glFormat } = backend.get( dstTexture );
535533

534+
535+
let width, height, minX, minY;
536+
let dstX, dstY;
537+
if ( srcRegion !== null ) {
538+
539+
width = srcRegion.max.x - srcRegion.min.x;
540+
height = srcRegion.max.y - srcRegion.min.y;
541+
minX = srcRegion.min.x;
542+
minY = srcRegion.min.y;
543+
544+
} else {
545+
546+
width = srcTexture.image.width;
547+
height = srcTexture.image.height;
548+
minX = 0;
549+
minY = 0;
550+
551+
}
552+
553+
if ( dstPosition !== null ) {
554+
555+
dstX = dstPosition.x;
556+
dstY = dstPosition.y;
557+
558+
} else {
559+
560+
dstX = 0;
561+
dstY = 0;
562+
563+
}
564+
536565
state.bindTexture( glTextureType, dstTextureGPU );
537566

538567
// As another texture upload may have changed pixelStorei
539568
// parameters, make sure they are correct for the dstTexture
569+
gl.pixelStorei( gl.UNPACK_ALIGNMENT, dstTexture.unpackAlignment );
540570
gl.pixelStorei( gl.UNPACK_FLIP_Y_WEBGL, dstTexture.flipY );
541571
gl.pixelStorei( gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, dstTexture.premultiplyAlpha );
542572
gl.pixelStorei( gl.UNPACK_ALIGNMENT, dstTexture.unpackAlignment );
543573

574+
const currentUnpackRowLen = gl.getParameter( gl.UNPACK_ROW_LENGTH );
575+
const currentUnpackImageHeight = gl.getParameter( gl.UNPACK_IMAGE_HEIGHT );
576+
const currentUnpackSkipPixels = gl.getParameter( gl.UNPACK_SKIP_PIXELS );
577+
const currentUnpackSkipRows = gl.getParameter( gl.UNPACK_SKIP_ROWS );
578+
const currentUnpackSkipImages = gl.getParameter( gl.UNPACK_SKIP_IMAGES );
579+
580+
const image = srcTexture.isCompressedTexture ? srcTexture.mipmaps[ level ] : srcTexture.image;
581+
582+
gl.pixelStorei( gl.UNPACK_ROW_LENGTH, image.width );
583+
gl.pixelStorei( gl.UNPACK_IMAGE_HEIGHT, image.height );
584+
gl.pixelStorei( gl.UNPACK_SKIP_PIXELS, minX );
585+
gl.pixelStorei( gl.UNPACK_SKIP_ROWS, minY );
586+
587+
544588
if ( srcTexture.isDataTexture ) {
545589

546-
gl.texSubImage2D( gl.TEXTURE_2D, level, position.x, position.y, width, height, glFormat, glType, srcTexture.image.data );
590+
gl.texSubImage2D( gl.TEXTURE_2D, level, dstX, dstY, width, height, glFormat, glType, image.data );
547591

548592
} else {
549593

550594
if ( srcTexture.isCompressedTexture ) {
551595

552-
gl.compressedTexSubImage2D( gl.TEXTURE_2D, level, position.x, position.y, srcTexture.mipmaps[ 0 ].width, srcTexture.mipmaps[ 0 ].height, glFormat, srcTexture.mipmaps[ 0 ].data );
596+
gl.compressedTexSubImage2D( gl.TEXTURE_2D, level, dstX, dstY, image.width, image.height, glFormat, image.data );
553597

554598
} else {
555599

556-
gl.texSubImage2D( gl.TEXTURE_2D, level, position.x, position.y, glFormat, glType, srcTexture.image );
600+
gl.texSubImage2D( gl.TEXTURE_2D, level, dstX, dstY, glFormat, glType, image );
557601

558602
}
559603

560604
}
561605

606+
gl.pixelStorei( gl.UNPACK_ROW_LENGTH, currentUnpackRowLen );
607+
gl.pixelStorei( gl.UNPACK_IMAGE_HEIGHT, currentUnpackImageHeight );
608+
gl.pixelStorei( gl.UNPACK_SKIP_PIXELS, currentUnpackSkipPixels );
609+
gl.pixelStorei( gl.UNPACK_SKIP_ROWS, currentUnpackSkipRows );
610+
gl.pixelStorei( gl.UNPACK_SKIP_IMAGES, currentUnpackSkipImages );
611+
562612
// Generate mipmaps only when copying level 0
563613
if ( level === 0 && dstTexture.generateMipmaps ) gl.generateMipmap( gl.TEXTURE_2D );
564614

examples/jsm/renderers/webgpu/WebGPUBackend.js

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1235,8 +1235,18 @@ class WebGPUBackend extends Backend {
12351235

12361236
}
12371237

1238-
copyTextureToTexture( position, srcTexture, dstTexture, level = 0 ) {
1238+
copyTextureToTexture( srcTexture, dstTexture, srcRegion = null, dstPosition = null, level = 0 ) {
12391239

1240+
let dstX = 0;
1241+
let dstY = 0;
1242+
1243+
if ( dstPosition !== null ) {
1244+
1245+
dstX = dstPosition.x;
1246+
dstY = dstPosition.y;
1247+
1248+
}
1249+
12401250
const encoder = this.device.createCommandEncoder( { label: 'copyTextureToTexture_' + srcTexture.id + '_' + dstTexture.id } );
12411251

12421252
const sourceGPU = this.get( srcTexture ).texture;
@@ -1251,7 +1261,7 @@ class WebGPUBackend extends Backend {
12511261
{
12521262
texture: destinationGPU,
12531263
mipLevel: level,
1254-
origin: { x: position.x, y: position.y, z: position.z }
1264+
origin: { x: dstX, y: dstY, z: 0 }
12551265
},
12561266
[
12571267
srcTexture.image.width,

examples/webgpu_materials_texture_partialupdate.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@
110110

111111
// perform copy from src to dest texture to a random position
112112

113-
renderer.copyTextureToTexture( position, dataTexture, diffuseMap );
113+
renderer.copyTextureToTexture( dataTexture, diffuseMap, new THREE.Vector2(), position );
114114

115115
}
116116

0 commit comments

Comments
 (0)