-
-
Notifications
You must be signed in to change notification settings - Fork 35.7k
WebGLBackend: Bring back 3D functionality for copyTextureToTexture #30584
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -697,70 +697,94 @@ class WebGLTextureUtils { | |
* | ||
* @param {Texture} srcTexture - The source texture. | ||
* @param {Texture} dstTexture - The destination texture. | ||
* @param {?Vector4} [srcRegion=null] - The region of the source texture to copy. | ||
* @param {?(Box3|Box2)} [srcRegion=null] - The region of the source texture to copy. | ||
* @param {?(Vector2|Vector3)} [dstPosition=null] - The destination position of the copy. | ||
* @param {number} [level=0] - The mip level to copy. | ||
* @param {number} [srcLevel=0] - The source mip level to copy from. | ||
* @param {number} [dstLevel=0] - The destination mip level to copy to. | ||
*/ | ||
copyTextureToTexture( srcTexture, dstTexture, srcRegion = null, dstPosition = null, level = 0 ) { | ||
copyTextureToTexture( srcTexture, dstTexture, srcRegion = null, dstPosition = null, srcLevel = 0, dstLevel = 0 ) { | ||
|
||
const { gl, backend } = this; | ||
const { state } = this.backend; | ||
|
||
const { textureGPU: dstTextureGPU, glTextureType, glType, glFormat } = backend.get( dstTexture ); | ||
|
||
let width, height, minX, minY; | ||
let dstX, dstY; | ||
state.bindTexture( glTextureType, dstTextureGPU ); | ||
|
||
// gather the necessary dimensions to copy | ||
let width, height, depth, minX, minY, minZ; | ||
let dstX, dstY, dstZ; | ||
const image = srcTexture.isCompressedTexture ? srcTexture.mipmaps[ dstLevel ] : srcTexture.image; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This bit isn't correct. The default value of Please change the default value of There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Regarding your comment in #30584 (comment): The signature in There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ah yes that makes sense, I have updated them to use dstLevel = 0 by default now. |
||
|
||
if ( srcRegion !== null ) { | ||
|
||
width = srcRegion.max.x - srcRegion.min.x; | ||
height = srcRegion.max.y - srcRegion.min.y; | ||
depth = srcRegion.isBox3 ? srcRegion.max.z - srcRegion.min.z : 1; | ||
minX = srcRegion.min.x; | ||
minY = srcRegion.min.y; | ||
minZ = srcRegion.isBox3 ? srcRegion.min.z : 0; | ||
|
||
} else { | ||
|
||
width = srcTexture.image.width; | ||
height = srcTexture.image.height; | ||
const levelScale = Math.pow( 2, - srcLevel ); | ||
width = Math.floor( image.width * levelScale ); | ||
height = Math.floor( image.height * levelScale ); | ||
|
||
if ( srcTexture.isDataArrayTexture ) { | ||
|
||
depth = image.depth; | ||
|
||
} else if ( srcTexture.isData3DTexture ) { | ||
|
||
depth = Math.floor( image.depth * levelScale ); | ||
|
||
} else { | ||
|
||
depth = 1; | ||
|
||
} | ||
|
||
minX = 0; | ||
minY = 0; | ||
minZ = 0; | ||
|
||
} | ||
|
||
if ( dstPosition !== null ) { | ||
|
||
dstX = dstPosition.x; | ||
dstY = dstPosition.y; | ||
dstZ = dstPosition.z; | ||
|
||
} else { | ||
|
||
dstX = 0; | ||
dstY = 0; | ||
dstZ = 0; | ||
|
||
} | ||
|
||
state.bindTexture( glTextureType, dstTextureGPU ); | ||
|
||
// As another texture upload may have changed pixelStorei | ||
// parameters, make sure they are correct for the dstTexture | ||
gl.pixelStorei( gl.UNPACK_ALIGNMENT, dstTexture.unpackAlignment ); | ||
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 ); | ||
|
||
// 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 ); | ||
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 ); | ||
gl.pixelStorei( gl.UNPACK_SKIP_IMAGES, minZ ); | ||
|
||
// set up the src texture | ||
const isDst3D = dstTexture.isDataArrayTexture || dstTexture.isData3DTexture; | ||
if ( srcTexture.isRenderTargetTexture || srcTexture.isDepthTexture ) { | ||
|
||
const srcTextureData = backend.get( srcTexture ); | ||
|
@@ -786,39 +810,63 @@ class WebGLTextureUtils { | |
|
||
} else { | ||
|
||
if ( srcTexture.isDataTexture ) { | ||
if ( isDst3D ) { | ||
|
||
gl.texSubImage2D( gl.TEXTURE_2D, level, dstX, dstY, width, height, glFormat, glType, image.data ); | ||
// copy data into the 3d texture | ||
if ( srcTexture.isDataTexture || srcTexture.isData3DTexture ) { | ||
|
||
gl.texSubImage3D( glTextureType, dstLevel, dstX, dstY, dstZ, width, height, depth, glFormat, glType, image.data ); | ||
|
||
} else if ( dstTexture.isCompressedArrayTexture ) { | ||
|
||
gl.compressedTexSubImage3D( glTextureType, dstLevel, dstX, dstY, dstZ, width, height, depth, glFormat, image.data ); | ||
|
||
} else { | ||
|
||
gl.texSubImage3D( glTextureType, dstLevel, dstX, dstY, dstZ, width, height, depth, glFormat, glType, image ); | ||
|
||
} | ||
|
||
} else { | ||
|
||
if ( srcTexture.isCompressedTexture ) { | ||
// copy data into the 2d texture | ||
if ( srcTexture.isDataTexture ) { | ||
|
||
gl.texSubImage2D( glTextureType, dstLevel, dstX, dstY, width, height, glFormat, glType, image.data ); | ||
|
||
gl.compressedTexSubImage2D( gl.TEXTURE_2D, level, dstX, dstY, image.width, image.height, glFormat, image.data ); | ||
} else if ( srcTexture.isCompressedTexture ) { | ||
|
||
gl.compressedTexSubImage2D( glTextureType, dstLevel, dstX, dstY, image.width, image.height, glFormat, image.data ); | ||
|
||
} else { | ||
|
||
gl.texSubImage2D( gl.TEXTURE_2D, level, dstX, dstY, width, height, glFormat, glType, image ); | ||
gl.texSubImage2D( glTextureType, dstLevel, 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 ); | ||
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 ); | ||
if ( dstLevel === 0 && dstTexture.generateMipmaps ) { | ||
|
||
gl.generateMipmap( glTextureType ); | ||
|
||
} | ||
|
||
state.unbindTexture(); | ||
|
||
} | ||
|
||
|
||
/** | ||
* Copies the current bound framebuffer to the given texture. | ||
* | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you mind updating all
copyTextureToTexture()
signatures inWebGPURenderer
? For that, you have to updateRenderer.copyTextureToTexture()
,Backend.copyTextureToTexture()
(the interface definition) and both backends.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Cool I've updated the signatures too, hopefully it's looking alright