소스 검색

Implement mipmap support in BasisTextureLoader

This change makes sure that we load all mipmaps present in the .basis
file. This is important for multiple reasons, one of them being that to
use .basis files in glTF out of the box, the texture has to have a
complete mipchain (otherwise the texture is incomplete as per WebGL spec
and sampling this texture returns (0,0,0)).

Contributes to #16524.
Arseny Kapoulkine 6 년 전
부모
커밋
274b5ddbc4
1개의 변경된 파일35개의 추가작업 그리고 21개의 파일을 삭제
  1. 35 21
      examples/js/loaders/BasisTextureLoader.js

+ 35 - 21
examples/js/loaders/BasisTextureLoader.js

@@ -117,9 +117,7 @@ THREE.BasisTextureLoader = class BasisTextureLoader {
 
 				var config = this.workerConfig;
 
-				var { data, width, height } = message;
-
-				var mipmaps = [ { data, width, height } ];
+				var { width, height, mipmaps } = message;
 
 				var texture;
 
@@ -305,9 +303,17 @@ THREE.BasisTextureLoader.BasisWorker = function () {
 			case 'transcode':
 				transcoderPending.then( () => {
 
-					var { data, width, height } = transcode( message.buffer );
+					var { width, height, mipmaps } = transcode( message.buffer );
+
+					var buffers = [];
+
+					for ( var i = 0; i < mipmaps.length; ++i ) {
+
+						buffers.push( mipmaps[i].data.buffer );
+
+					}
 
-					self.postMessage( { type: 'transcode', id: message.id, data, width, height }, [ data.buffer ] );
+					self.postMessage( { type: 'transcode', id: message.id, width, height, mipmaps }, buffers );
 
 				} );
 				break;
@@ -348,7 +354,6 @@ THREE.BasisTextureLoader.BasisWorker = function () {
 
 		var width = basisFile.getImageWidth( 0, 0 );
 		var height = basisFile.getImageHeight( 0, 0 );
-		var images = basisFile.getNumImages();
 		var levels = basisFile.getNumLevels( 0 );
 
 		function cleanup () {
@@ -358,7 +363,7 @@ THREE.BasisTextureLoader.BasisWorker = function () {
 
 		}
 
-		if ( ! width || ! height || ! images || ! levels ) {
+		if ( ! width || ! height || ! levels ) {
 
 			cleanup();
 			throw new Error( 'THREE.BasisTextureLoader:  Invalid .basis file' );
@@ -372,28 +377,37 @@ THREE.BasisTextureLoader.BasisWorker = function () {
 
 		}
 
-		var dst = new Uint8Array( basisFile.getImageTranscodedSizeInBytes( 0, 0, config.format ) );
+		var mipmaps = [];
 
-		var startTime = performance.now();
+		for ( var mip = 0; mip < levels; mip++ ) {
 
-		var status = basisFile.transcodeImage(
-			dst,
-			0,
-			0,
-			config.format,
-			config.etcSupported ? 0 : ( config.dxtSupported ? 1 : 0 ),
-			0
-		);
+			var mipWidth = basisFile.getImageWidth( 0, mip );
+			var mipHeight = basisFile.getImageHeight( 0, mip );
+			var dst = new Uint8Array( basisFile.getImageTranscodedSizeInBytes( 0, mip, config.format ) );
 
-		cleanup();
+			var status = basisFile.transcodeImage(
+				dst,
+				0,
+				mip,
+				config.format,
+				config.etcSupported ? 0 : ( config.dxtSupported ? 1 : 0 ),
+				0
+			);
+
+			if ( ! status ) {
+
+				cleanup();
+				throw new Error( 'THREE.BasisTextureLoader: .transcodeImage failed.' );
 
-		if ( ! status ) {
+			}
 
-			throw new Error( 'THREE.BasisTextureLoader: .transcodeImage failed.' );
+			mipmaps.push( { data: dst, width: mipWidth, height: mipHeight } );
 
 		}
 
-		return { data: dst, width, height };
+		cleanup();
+
+		return { width, height, mipmaps };
 
 	}