Kaynağa Gözat

Merge pull request #15286 from Mugen87/dev7

WebGLTextures: Introduce .resizeImage()
Mr.doob 6 yıl önce
ebeveyn
işleme
c9822c8b3b
1 değiştirilmiş dosya ile 35 ekleme ve 39 silme
  1. 35 39
      src/renderers/webgl/WebGLTextures.js

+ 35 - 39
src/renderers/webgl/WebGLTextures.js

@@ -12,60 +12,55 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils,
 
 	//
 
-	function clampToMaxSize( image, maxSize ) {
+	function resizeImage( image, needsPowerOfTwo, needsNewCanvas, maxSize ) {
 
-		if ( image.width > maxSize || image.height > maxSize ) {
+		var scale = 1;
 
-			if ( 'data' in image ) {
+		// handle case if texture exceeds max size
 
-				console.warn( 'THREE.WebGLRenderer: image in DataTexture is too big (' + image.width + 'x' + image.height + ').' );
-				return;
+		if ( image.width > maxSize || image.height > maxSize ) {
 
-			}
+			scale = maxSize / Math.max( image.width, image.height );
 
-			// Warning: Scaling through the canvas will only work with images that use
-			// premultiplied alpha.
+		}
 
-			var scale = maxSize / Math.max( image.width, image.height );
+		// only perform resize if necessary
 
-			var canvas = document.createElementNS( 'http://www.w3.org/1999/xhtml', 'canvas' );
-			canvas.width = Math.floor( image.width * scale );
-			canvas.height = Math.floor( image.height * scale );
+		if ( scale < 1 || needsPowerOfTwo === true ) {
 
-			var context = canvas.getContext( '2d' );
-			context.drawImage( image, 0, 0, image.width, image.height, 0, 0, canvas.width, canvas.height );
+			// only perform resize for certain image types
 
-			console.warn( 'THREE.WebGLRenderer: image is too big (' + image.width + 'x' + image.height + '). Resized to ' + canvas.width + 'x' + canvas.height );
+			if ( image instanceof HTMLImageElement || image instanceof HTMLCanvasElement || image instanceof ImageBitmap ) {
 
-			return canvas;
+				if ( _canvas === undefined ) _canvas = document.createElementNS( 'http://www.w3.org/1999/xhtml', 'canvas' );
 
-		}
+				// cube textures can't reuse the same canvas
 
-		return image;
+				var canvas = needsNewCanvas ? document.createElementNS( 'http://www.w3.org/1999/xhtml', 'canvas' ) : _canvas;
 
-	}
+				var floor = needsPowerOfTwo ? _Math.floorPowerOfTwo : Math.floor;
 
-	function isPowerOfTwo( image ) {
+				canvas.width = floor( scale * image.width );
+				canvas.height = floor( scale * image.height );
 
-		return _Math.isPowerOfTwo( image.width ) && _Math.isPowerOfTwo( image.height );
+				var context = canvas.getContext( '2d' );
+				context.drawImage( image, 0, 0, canvas.width, canvas.height );
 
-	}
+				console.warn( 'THREE.WebGLRenderer: Texture has been resized from (' + image.width + 'x' + image.height + ') to (' + canvas.width + 'x' + canvas.height + ').' );
 
-	function makePowerOfTwo( image ) {
+				return canvas;
 
-		if ( image instanceof HTMLImageElement || image instanceof HTMLCanvasElement || image instanceof ImageBitmap ) {
+			} else {
 
-			if ( _canvas === undefined ) _canvas = document.createElementNS( 'http://www.w3.org/1999/xhtml', 'canvas' );
+				if ( 'data' in image ) {
 
-			_canvas.width = _Math.floorPowerOfTwo( image.width );
-			_canvas.height = _Math.floorPowerOfTwo( image.height );
+					console.warn( 'THREE.WebGLRenderer: Image in DataTexture is too big (' + image.width + 'x' + image.height + ').' );
 
-			var context = _canvas.getContext( '2d' );
-			context.drawImage( image, 0, 0, _canvas.width, _canvas.height );
+				}
 
-			console.warn( 'THREE.WebGLRenderer: image is not power of two (' + image.width + 'x' + image.height + '). Resized to ' + _canvas.width + 'x' + _canvas.height );
+				return image;
 
-			return _canvas;
+			}
 
 		}
 
@@ -73,6 +68,12 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils,
 
 	}
 
+	function isPowerOfTwo( image ) {
+
+		return _Math.isPowerOfTwo( image.width ) && _Math.isPowerOfTwo( image.height );
+
+	}
+
 	function textureNeedsPowerOfTwo( texture ) {
 
 		if ( capabilities.isWebGL2 ) return false;
@@ -343,7 +344,7 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils,
 
 					if ( ! isCompressed && ! isDataTexture ) {
 
-						cubeImage[ i ] = clampToMaxSize( texture.image[ i ], capabilities.maxCubemapSize );
+						cubeImage[ i ] = resizeImage( texture.image[ i ], false, true, capabilities.maxCubemapSize );
 
 					} else {
 
@@ -535,13 +536,8 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils,
 		_gl.pixelStorei( _gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, texture.premultiplyAlpha );
 		_gl.pixelStorei( _gl.UNPACK_ALIGNMENT, texture.unpackAlignment );
 
-		var image = clampToMaxSize( texture.image, capabilities.maxTextureSize );
-
-		if ( textureNeedsPowerOfTwo( texture ) && isPowerOfTwo( image ) === false ) {
-
-			image = makePowerOfTwo( image );
-
-		}
+		var needsPowerOfTwo = textureNeedsPowerOfTwo( texture ) && isPowerOfTwo( texture.image ) === false;
+		var image = resizeImage( texture.image, needsPowerOfTwo, false, capabilities.maxTextureSize );
 
 		var isPowerOfTwoImage = isPowerOfTwo( image ),
 			glFormat = utils.convert( texture.format ),