浏览代码

WebGLTextures: More flexible image dimensions computation. (#27810)

* WebGLTextures: More flexibel image dimensions computation.

* WebGLTextures: Create dimensions object once.
Michael Herzog 1 年之前
父节点
当前提交
d5a0288e93
共有 2 个文件被更改,包括 51 次插入12 次删除
  1. 2 1
      .eslintrc.json
  2. 49 11
      src/renderers/webgl/WebGLTextures.js

+ 2 - 1
.eslintrc.json

@@ -40,7 +40,8 @@
     "XRMediaBinding": "readonly",
     "XRMediaBinding": "readonly",
     "CodeMirror": "readonly",
     "CodeMirror": "readonly",
     "esprima": "readonly",
     "esprima": "readonly",
-    "jsonlint": "readonly"
+    "jsonlint": "readonly",
+    "VideoFrame": "readonly"
   },
   },
   "rules": {
   "rules": {
     "no-throw-literal": [
     "no-throw-literal": [

+ 49 - 11
src/renderers/webgl/WebGLTextures.js

@@ -3,6 +3,7 @@ import * as MathUtils from '../../math/MathUtils.js';
 import { ImageUtils } from '../../extras/ImageUtils.js';
 import { ImageUtils } from '../../extras/ImageUtils.js';
 import { createElementNS } from '../../utils.js';
 import { createElementNS } from '../../utils.js';
 import { ColorManagement } from '../../math/ColorManagement.js';
 import { ColorManagement } from '../../math/ColorManagement.js';
+import { Vector2 } from '../../math/Vector2.js';
 
 
 function WebGLTextures( _gl, extensions, state, properties, capabilities, utils, info ) {
 function WebGLTextures( _gl, extensions, state, properties, capabilities, utils, info ) {
 
 
@@ -10,6 +11,7 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils,
 	const multisampledRTTExt = extensions.has( 'WEBGL_multisampled_render_to_texture' ) ? extensions.get( 'WEBGL_multisampled_render_to_texture' ) : null;
 	const multisampledRTTExt = extensions.has( 'WEBGL_multisampled_render_to_texture' ) ? extensions.get( 'WEBGL_multisampled_render_to_texture' ) : null;
 	const supportsInvalidateFramebuffer = typeof navigator === 'undefined' ? false : /OculusBrowser/g.test( navigator.userAgent );
 	const supportsInvalidateFramebuffer = typeof navigator === 'undefined' ? false : /OculusBrowser/g.test( navigator.userAgent );
 
 
+	const _imageDimensions = new Vector2();
 	const _videoTextures = new WeakMap();
 	const _videoTextures = new WeakMap();
 	let _canvas;
 	let _canvas;
 
 
@@ -47,11 +49,13 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils,
 
 
 		let scale = 1;
 		let scale = 1;
 
 
+		const dimensions = getDimensions( image );
+
 		// handle case if texture exceeds max size
 		// handle case if texture exceeds max size
 
 
-		if ( image.width > maxSize || image.height > maxSize ) {
+		if ( dimensions.width > maxSize || dimensions.height > maxSize ) {
 
 
-			scale = maxSize / Math.max( image.width, image.height );
+			scale = maxSize / Math.max( dimensions.width, dimensions.height );
 
 
 		}
 		}
 
 
@@ -63,12 +67,13 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils,
 
 
 			if ( ( typeof HTMLImageElement !== 'undefined' && image instanceof HTMLImageElement ) ||
 			if ( ( typeof HTMLImageElement !== 'undefined' && image instanceof HTMLImageElement ) ||
 				( typeof HTMLCanvasElement !== 'undefined' && image instanceof HTMLCanvasElement ) ||
 				( typeof HTMLCanvasElement !== 'undefined' && image instanceof HTMLCanvasElement ) ||
-				( typeof ImageBitmap !== 'undefined' && image instanceof ImageBitmap ) ) {
+				( typeof ImageBitmap !== 'undefined' && image instanceof ImageBitmap ) ||
+				( typeof VideoFrame !== 'undefined' && image instanceof VideoFrame ) ) {
 
 
 				const floor = needsPowerOfTwo ? MathUtils.floorPowerOfTwo : Math.floor;
 				const floor = needsPowerOfTwo ? MathUtils.floorPowerOfTwo : Math.floor;
 
 
-				const width = floor( scale * image.width );
-				const height = floor( scale * image.height );
+				const width = floor( scale * dimensions.width );
+				const height = floor( scale * dimensions.height );
 
 
 				if ( _canvas === undefined ) _canvas = createCanvas( width, height );
 				if ( _canvas === undefined ) _canvas = createCanvas( width, height );
 
 
@@ -82,7 +87,7 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils,
 				const context = canvas.getContext( '2d' );
 				const context = canvas.getContext( '2d' );
 				context.drawImage( image, 0, 0, width, height );
 				context.drawImage( image, 0, 0, width, height );
 
 
-				console.warn( 'THREE.WebGLRenderer: Texture has been resized from (' + image.width + 'x' + image.height + ') to (' + width + 'x' + height + ').' );
+				console.warn( 'THREE.WebGLRenderer: Texture has been resized from (' + dimensions.width + 'x' + dimensions.height + ') to (' + width + 'x' + height + ').' );
 
 
 				return canvas;
 				return canvas;
 
 
@@ -90,7 +95,7 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils,
 
 
 				if ( 'data' in image ) {
 				if ( 'data' in image ) {
 
 
-					console.warn( 'THREE.WebGLRenderer: Image in DataTexture is too big (' + image.width + 'x' + image.height + ').' );
+					console.warn( 'THREE.WebGLRenderer: Image in DataTexture is too big (' + dimensions.width + 'x' + dimensions.height + ').' );
 
 
 				}
 				}
 
 
@@ -106,7 +111,9 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils,
 
 
 	function isPowerOfTwo( image ) {
 	function isPowerOfTwo( image ) {
 
 
-		return MathUtils.isPowerOfTwo( image.width ) && MathUtils.isPowerOfTwo( image.height );
+		const dimensions = getDimensions( image );
+
+		return MathUtils.isPowerOfTwo( dimensions.width ) && MathUtils.isPowerOfTwo( dimensions.height );
 
 
 	}
 	}
 
 
@@ -1114,7 +1121,9 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils,
 
 
 					if ( useTexStorage && allocateMemory ) {
 					if ( useTexStorage && allocateMemory ) {
 
 
-						state.texStorage2D( _gl.TEXTURE_2D, levels, glInternalFormat, mipmaps[ 0 ].width, mipmaps[ 0 ].height );
+						const dimensions = getDimensions( mipmaps[ 0 ] );
+
+						state.texStorage2D( _gl.TEXTURE_2D, levels, glInternalFormat, dimensions.width, dimensions.height );
 
 
 					}
 					}
 
 
@@ -1146,7 +1155,9 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils,
 
 
 						if ( allocateMemory ) {
 						if ( allocateMemory ) {
 
 
-							state.texStorage2D( _gl.TEXTURE_2D, levels, glInternalFormat, image.width, image.height );
+							const dimensions = getDimensions( image );
+
+							state.texStorage2D( _gl.TEXTURE_2D, levels, glInternalFormat, dimensions.width, dimensions.height );
 
 
 						}
 						}
 
 
@@ -1316,7 +1327,9 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils,
 
 
 					if ( mipmaps.length > 0 ) levels ++;
 					if ( mipmaps.length > 0 ) levels ++;
 
 
-					state.texStorage2D( _gl.TEXTURE_CUBE_MAP, levels, glInternalFormat, cubeImage[ 0 ].width, cubeImage[ 0 ].height );
+					const dimensions = getDimensions( cubeImage[ 0 ] );
+
+					state.texStorage2D( _gl.TEXTURE_CUBE_MAP, levels, glInternalFormat, dimensions.width, dimensions.height );
 
 
 				}
 				}
 
 
@@ -2153,6 +2166,31 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils,
 
 
 	}
 	}
 
 
+	function getDimensions( image ) {
+
+		if ( typeof HTMLImageElement !== 'undefined' && image instanceof HTMLImageElement ) {
+
+			// if intrinsic data are not available, fallback to width/height
+
+			_imageDimensions.width = image.naturalWidth || image.width;
+			_imageDimensions.height = image.naturalHeight || image.height;
+
+		} else if ( typeof VideoFrame !== 'undefined' && image instanceof VideoFrame ) {
+
+			_imageDimensions.width = image.displayWidth;
+			_imageDimensions.height = image.displayHeight;
+
+		} else {
+
+			_imageDimensions.width = image.width;
+			_imageDimensions.height = image.height;
+
+		}
+
+		return _imageDimensions;
+
+	}
+
 	//
 	//
 
 
 	this.allocateTextureUnit = allocateTextureUnit;
 	this.allocateTextureUnit = allocateTextureUnit;