|
@@ -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 ),
|