| /** |
| * @author Don McCurdy / https://www.donmccurdy.com |
| * @author Austin Eng / https://github.com/austinEng |
| * @author Shrek Shao / https://github.com/shrekshao |
| */ |
| |
| /** |
| * An example three.js loader for Basis compressed textures. |
| */ |
| THREE.BasisTextureLoader = class BasisTextureLoader { |
| |
| constructor () { |
| |
| this.etcSupported = false; |
| this.dxtSupported = false; |
| this.pvrtcSupported = false; |
| |
| this.format = null; |
| |
| } |
| |
| detectSupport ( renderer ) { |
| |
| const context = renderer.context; |
| |
| this.etcSupported = context.getExtension('WEBGL_compressed_texture_etc1'); |
| this.dxtSupported = context.getExtension('WEBGL_compressed_texture_s3tc'); |
| this.pvrtcSupported = context.getExtension('WEBGL_compressed_texture_pvrtc') |
| || context.getExtension('WEBKIT_WEBGL_compressed_texture_pvrtc'); |
| |
| if ( ! this.etcSupported && ! this.dxtSupported && ! this.pvrtcSupported ) { |
| |
| throw new Error( 'THREE.BasisTextureLoader: No suitable compressed texture format found.' ); |
| |
| } |
| |
| this.format = this.etcSupported |
| ? BASIS_FORMAT.cTFETC1 |
| : ( this.dxtSupported |
| ? BASIS_FORMAT.cTFBC1 |
| : BASIS_FORMAT.cTFPVRTC1_4_OPAQUE_ONLY ); |
| |
| return this; |
| |
| } |
| |
| load ( url, onLoad, onProgress, onError ) { |
| |
| fetch( url ) |
| .then( ( res ) => res.arrayBuffer() ) |
| .then( (arrayBuffer) => this._createTexture( arrayBuffer ) ) |
| .then( onLoad ) |
| .catch( onError ); |
| |
| } |
| |
| _createTexture ( arrayBuffer ) { |
| |
| const BASIS_FORMAT = THREE.BasisTextureLoader.BASIS_FORMAT; |
| const DXT_FORMAT_MAP = THREE.BasisTextureLoader.DXT_FORMAT_MAP; |
| |
| const basisFile = new BasisFile( new Uint8Array( arrayBuffer ) ); |
| |
| const width = basisFile.getImageWidth( 0, 0 ); |
| const height = basisFile.getImageHeight( 0, 0 ); |
| const images = basisFile.getNumImages(); |
| const levels = basisFile.getNumLevels( 0 ); |
| |
| function cleanup () { |
| |
| basisFile.close(); |
| basisFile.delete(); |
| |
| } |
| |
| if ( ! width || ! height || ! images || ! levels ) { |
| |
| cleanup(); |
| throw new Error( 'THREE.BasisTextureLoader: Invalid .basis file' ); |
| |
| } |
| |
| if ( ! basisFile.startTranscoding() ) { |
| |
| cleanup(); |
| throw new Error( 'THREE.BasisTextureLoader: .startTranscoding failed' ); |
| |
| } |
| |
| const dst = new Uint8Array( basisFile.getImageTranscodedSizeInBytes( 0, 0, this.format ) ); |
| |
| const startTime = performance.now(); |
| |
| const status = basisFile.transcodeImage( |
| dst, |
| 0, |
| 0, |
| this.format, |
| this.etcSupported ? 0 : ( this.dxtSupported ? 1 : 0 ), |
| 0 |
| ); |
| |
| console.log( `THREE.BasisTextureLoader: Transcode time: ${performance.now() - startTime}ms`, dst ); |
| |
| cleanup(); |
| |
| if ( ! status ) { |
| |
| throw new Error( 'THREE.BasisTextureLoader: .transcodeImage failed.' ); |
| |
| } |
| |
| const mipmaps = [ { data: dst, width, height } ]; |
| |
| let texture; |
| |
| if ( this.etcSupported ) { |
| |
| texture = new THREE.CompressedTexture( mipmaps, width, height, THREE.RGB_ETC1_Format ); |
| |
| } else if ( this.dxtSupported ) { |
| |
| texture = new THREE.CompressedTexture( mipmaps, width, height, DXT_FORMAT_MAP[ this.format ], THREE.UnsignedByteType ); |
| |
| } else if ( this.pvrtcSupported ) { |
| |
| texture = new THREE.CompressedTexture( mipmaps, width, height, THREE.RGB_PVRTC_4BPPV1_Format ); |
| |
| } else { |
| |
| throw new Error( 'THREE.BasisTextureLoader: No supported format available.' ); |
| |
| } |
| |
| texture.minFilter = THREE.LinearMipMapLinearFilter; |
| texture.magFilter = THREE.LinearFilter; |
| texture.encoding = THREE.sRGBEncoding; |
| texture.generateMipmaps = false; |
| texture.flipY = false; |
| texture.needsUpdate = true; |
| |
| return texture; |
| |
| } |
| } |
| |
| const BASIS_FORMAT = { |
| cTFETC1: 0, |
| cTFBC1: 1, |
| cTFBC4: 2, |
| cTFPVRTC1_4_OPAQUE_ONLY: 3, |
| cTFBC7_M6_OPAQUE_ONLY: 4, |
| cTFETC2: 5, |
| cTFBC3: 6, |
| cTFBC5: 7, |
| }; |
| |
| // DXT formats, from: |
| // http://www.khronos.org/registry/webgl/extensions/WEBGL_compressed_texture_s3tc/ |
| const DXT_FORMAT_MAP = {}; |
| const COMPRESSED_RGB_S3TC_DXT1_EXT = 0x83F0; |
| const COMPRESSED_RGBA_S3TC_DXT1_EXT = 0x83F1; |
| const COMPRESSED_RGBA_S3TC_DXT3_EXT = 0x83F2; |
| const COMPRESSED_RGBA_S3TC_DXT5_EXT = 0x83F3; |
| DXT_FORMAT_MAP[ BASIS_FORMAT.cTFBC1 ] = COMPRESSED_RGB_S3TC_DXT1_EXT; |
| DXT_FORMAT_MAP[ BASIS_FORMAT.cTFBC3 ] = COMPRESSED_RGBA_S3TC_DXT5_EXT; |
| |
| THREE.BasisTextureLoader.BASIS_FORMAT = BASIS_FORMAT; |
| THREE.BasisTextureLoader.DXT_FORMAT_MAP = DXT_FORMAT_MAP; |