diff --git a/src/cameras/CubeCamera.js b/src/cameras/CubeCamera.js index c60e199c00cb0d..472247d20baea0 100644 --- a/src/cameras/CubeCamera.js +++ b/src/cameras/CubeCamera.js @@ -100,6 +100,8 @@ class CubeCamera extends Object3D { renderer.xr.enabled = currentXrEnabled; + renderTarget.texture.needsPMREMUpdate = true; + } } diff --git a/src/extras/PMREMGenerator.js b/src/extras/PMREMGenerator.js index b85cf5d97fa64d..45fdb44447a840 100644 --- a/src/extras/PMREMGenerator.js +++ b/src/extras/PMREMGenerator.js @@ -124,9 +124,9 @@ class PMREMGenerator { * or HDR. The ideal input image size is 1k (1024 x 512), * as this matches best with the 256 x 256 cubemap output. */ - fromEquirectangular( equirectangular ) { + fromEquirectangular( equirectangular, renderTarget = null ) { - return this._fromTexture( equirectangular ); + return this._fromTexture( equirectangular, renderTarget ); } @@ -135,9 +135,9 @@ class PMREMGenerator { * or HDR. The ideal input cube size is 256 x 256, * as this matches best with the 256 x 256 cubemap output. */ - fromCubemap( cubemap ) { + fromCubemap( cubemap, renderTarget = null ) { - return this._fromTexture( cubemap ); + return this._fromTexture( cubemap, renderTarget ); } @@ -202,10 +202,10 @@ class PMREMGenerator { } - _fromTexture( texture ) { + _fromTexture( texture, renderTarget ) { _oldTarget = this._renderer.getRenderTarget(); - const cubeUVRenderTarget = this._allocateTargets( texture ); + const cubeUVRenderTarget = renderTarget || this._allocateTargets( texture ); this._textureToCubeUV( texture, cubeUVRenderTarget ); this._applyPMREM( cubeUVRenderTarget ); this._cleanup( cubeUVRenderTarget ); diff --git a/src/renderers/webgl/WebGLCubeUVMaps.js b/src/renderers/webgl/WebGLCubeUVMaps.js index 3e14ff230914a2..f7c7bc3cd710d5 100644 --- a/src/renderers/webgl/WebGLCubeUVMaps.js +++ b/src/renderers/webgl/WebGLCubeUVMaps.js @@ -9,41 +9,58 @@ function WebGLCubeUVMaps( renderer ) { function get( texture ) { - if ( texture && texture.isTexture && texture.isRenderTargetTexture === false ) { + if ( texture && texture.isTexture ) { const mapping = texture.mapping; const isEquirectMap = ( mapping === EquirectangularReflectionMapping || mapping === EquirectangularRefractionMapping ); const isCubeMap = ( mapping === CubeReflectionMapping || mapping === CubeRefractionMapping ); + // equirect/cube map to cubeUV conversion + if ( isEquirectMap || isCubeMap ) { - // equirect/cube map to cubeUV conversion + if ( texture.isRenderTargetTexture && texture.needsPMREMUpdate === true ) { + + texture.needsPMREMUpdate = false; + + let renderTarget = cubeUVmaps.get( texture ); - if ( cubeUVmaps.has( texture ) ) { + if ( pmremGenerator === null ) pmremGenerator = new PMREMGenerator( renderer ); - return cubeUVmaps.get( texture ).texture; + renderTarget = isEquirectMap ? pmremGenerator.fromEquirectangular( texture, renderTarget ) : pmremGenerator.fromCubemap( texture, renderTarget ); + cubeUVmaps.set( texture, renderTarget ); + + return renderTarget.texture; } else { - const image = texture.image; + if ( cubeUVmaps.has( texture ) ) { + + return cubeUVmaps.get( texture ).texture; - if ( ( isEquirectMap && image && image.height > 0 ) || ( isCubeMap && image && isCubeTextureComplete( image ) ) ) { + } else { - if ( pmremGenerator === null ) pmremGenerator = new PMREMGenerator( renderer ); + const image = texture.image; - const renderTarget = isEquirectMap ? pmremGenerator.fromEquirectangular( texture ) : pmremGenerator.fromCubemap( texture ); - cubeUVmaps.set( texture, renderTarget ); + if ( ( isEquirectMap && image && image.height > 0 ) || ( isCubeMap && image && isCubeTextureComplete( image ) ) ) { - texture.addEventListener( 'dispose', onTextureDispose ); + if ( pmremGenerator === null ) pmremGenerator = new PMREMGenerator( renderer ); - return renderTarget.texture; + const renderTarget = isEquirectMap ? pmremGenerator.fromEquirectangular( texture ) : pmremGenerator.fromCubemap( texture ); + cubeUVmaps.set( texture, renderTarget ); - } else { + texture.addEventListener( 'dispose', onTextureDispose ); + + return renderTarget.texture; + + } else { + + // image not yet ready. try the conversion next frame - // image not yet ready. try the conversion next frame + return null; - return null; + } } diff --git a/src/textures/Texture.js b/src/textures/Texture.js index 108642328b468a..49713629101fd0 100644 --- a/src/textures/Texture.js +++ b/src/textures/Texture.js @@ -70,7 +70,8 @@ class Texture extends EventDispatcher { this.version = 0; this.onUpdate = null; - this.isRenderTargetTexture = false; + this.isRenderTargetTexture = false; // indicates whether a texture belongs to a render target or not + this.needsPMREMUpdate = false; // indicates whether this texture should be processed by PMREMGenerator or not (only relevant for render target textures) }