itowns 2.45.1-next.0 → 2.45.1-next.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/455.js +2 -0
- package/dist/455.js.map +1 -0
- package/dist/debug.js +3 -0
- package/dist/debug.js.LICENSE.txt +13 -0
- package/dist/debug.js.map +1 -0
- package/dist/itowns.js +3 -0
- package/dist/itowns.js.LICENSE.txt +5 -0
- package/dist/itowns.js.map +1 -0
- package/dist/itowns_lasparser.js +2 -0
- package/dist/itowns_lasparser.js.map +1 -0
- package/dist/itowns_lasworker.js +2 -0
- package/dist/itowns_lasworker.js.map +1 -0
- package/dist/itowns_potree2worker.js +2 -0
- package/dist/itowns_potree2worker.js.map +1 -0
- package/dist/itowns_widgets.js +2 -0
- package/dist/itowns_widgets.js.map +1 -0
- package/lib/Controls/FirstPersonControls.js +308 -0
- package/lib/Controls/FlyControls.js +175 -0
- package/lib/Controls/GlobeControls.js +1178 -0
- package/lib/Controls/PlanarControls.js +1025 -0
- package/lib/Controls/StateControl.js +432 -0
- package/lib/Controls/StreetControls.js +392 -0
- package/lib/Converter/Feature2Mesh.js +612 -0
- package/lib/Converter/Feature2Texture.js +174 -0
- package/lib/Converter/convertToTile.js +70 -0
- package/lib/Converter/textureConverter.js +43 -0
- package/lib/Core/3DTiles/C3DTBatchTable.js +131 -0
- package/lib/Core/3DTiles/C3DTBatchTableHierarchyExtension.js +96 -0
- package/lib/Core/3DTiles/C3DTBoundingVolume.js +156 -0
- package/lib/Core/3DTiles/C3DTExtensions.js +97 -0
- package/lib/Core/3DTiles/C3DTFeature.js +110 -0
- package/lib/Core/3DTiles/C3DTilesEnums.js +20 -0
- package/lib/Core/3DTiles/C3DTileset.js +99 -0
- package/lib/Core/3DTiles/utils/BinaryPropertyAccessor.js +100 -0
- package/lib/Core/AnimationPlayer.js +142 -0
- package/lib/Core/CopcNode.js +174 -0
- package/lib/Core/Deprecated/Undeprecator.js +74 -0
- package/lib/Core/EntwinePointTileNode.js +126 -0
- package/lib/Core/Feature.js +488 -0
- package/lib/Core/Geographic/GeoidGrid.js +108 -0
- package/lib/Core/Label.js +222 -0
- package/lib/Core/MainLoop.js +209 -0
- package/lib/Core/Picking.js +255 -0
- package/lib/Core/PointCloudNode.js +42 -0
- package/lib/Core/Potree2Node.js +206 -0
- package/lib/Core/Potree2PointAttributes.js +139 -0
- package/lib/Core/PotreeNode.js +101 -0
- package/lib/Core/Prefab/Globe/Atmosphere.js +293 -0
- package/lib/Core/Prefab/Globe/GlobeLayer.js +152 -0
- package/lib/Core/Prefab/Globe/GlobeTileBuilder.js +110 -0
- package/lib/Core/Prefab/Globe/SkyShader.js +78 -0
- package/lib/Core/Prefab/GlobeView.js +155 -0
- package/lib/Core/Prefab/Planar/PlanarLayer.js +59 -0
- package/lib/Core/Prefab/Planar/PlanarTileBuilder.js +71 -0
- package/lib/Core/Prefab/PlanarView.js +62 -0
- package/lib/Core/Prefab/TileBuilder.js +82 -0
- package/lib/Core/Prefab/computeBufferTileGeometry.js +248 -0
- package/lib/Core/Scheduler/Cache.js +17 -0
- package/lib/Core/Scheduler/CancelledCommandException.js +15 -0
- package/lib/Core/Scheduler/Scheduler.js +294 -0
- package/lib/Core/Style.js +660 -0
- package/lib/Core/StyleOptions.js +486 -0
- package/lib/Core/System/Capabilities.js +63 -0
- package/lib/Core/Tile/Tile.js +205 -0
- package/lib/Core/Tile/TileGrid.js +49 -0
- package/lib/Core/TileGeometry.js +124 -0
- package/lib/Core/TileMesh.js +108 -0
- package/lib/Core/View.js +1115 -0
- package/lib/Layer/C3DTilesLayer.js +459 -0
- package/lib/Layer/ColorLayer.js +154 -0
- package/lib/Layer/CopcLayer.js +63 -0
- package/lib/Layer/ElevationLayer.js +139 -0
- package/lib/Layer/EntwinePointTileLayer.js +71 -0
- package/lib/Layer/FeatureGeometryLayer.js +77 -0
- package/lib/Layer/GeoidLayer.js +80 -0
- package/lib/Layer/GeometryLayer.js +233 -0
- package/lib/Layer/InfoLayer.js +64 -0
- package/lib/Layer/LabelLayer.js +469 -0
- package/lib/Layer/Layer.js +335 -0
- package/lib/Layer/LayerUpdateState.js +89 -0
- package/lib/Layer/LayerUpdateStrategy.js +80 -0
- package/lib/Layer/OGC3DTilesLayer.js +543 -0
- package/lib/Layer/OrientedImageLayer.js +227 -0
- package/lib/Layer/PointCloudLayer.js +405 -0
- package/lib/Layer/Potree2Layer.js +171 -0
- package/lib/Layer/PotreeLayer.js +72 -0
- package/lib/Layer/RasterLayer.js +37 -0
- package/lib/Layer/ReferencingLayerProperties.js +62 -0
- package/lib/Layer/TiledGeometryLayer.js +459 -0
- package/lib/Loader/LASLoader.js +193 -0
- package/lib/Loader/Potree2BrotliLoader.js +261 -0
- package/lib/Loader/Potree2Loader.js +207 -0
- package/lib/Main.js +113 -0
- package/lib/MainBundle.js +4 -0
- package/lib/Parser/B3dmParser.js +174 -0
- package/lib/Parser/CameraCalibrationParser.js +94 -0
- package/lib/Parser/GDFParser.js +72 -0
- package/lib/Parser/GTXParser.js +75 -0
- package/lib/Parser/GeoJsonParser.js +212 -0
- package/lib/Parser/GpxParser.js +25 -0
- package/lib/Parser/ISGParser.js +71 -0
- package/lib/Parser/KMLParser.js +25 -0
- package/lib/Parser/LASParser.js +137 -0
- package/lib/Parser/MapBoxUrlParser.js +83 -0
- package/lib/Parser/PntsParser.js +131 -0
- package/lib/Parser/Potree2BinParser.js +92 -0
- package/lib/Parser/PotreeBinParser.js +106 -0
- package/lib/Parser/PotreeCinParser.js +29 -0
- package/lib/Parser/ShapefileParser.js +78 -0
- package/lib/Parser/VectorTileParser.js +215 -0
- package/lib/Parser/XbilParser.js +120 -0
- package/lib/Parser/deprecated/LegacyGLTFLoader.js +1386 -0
- package/lib/Parser/iGLTFLoader.js +168 -0
- package/lib/Process/3dTilesProcessing.js +304 -0
- package/lib/Process/FeatureProcessing.js +76 -0
- package/lib/Process/LayeredMaterialNodeProcessing.js +229 -0
- package/lib/Process/ObjectRemovalHelper.js +97 -0
- package/lib/Process/handlerNodeError.js +23 -0
- package/lib/Provider/3dTilesProvider.js +149 -0
- package/lib/Provider/DataSourceProvider.js +24 -0
- package/lib/Provider/Fetcher.js +233 -0
- package/lib/Provider/PointCloudProvider.js +45 -0
- package/lib/Provider/TileProvider.js +16 -0
- package/lib/Provider/URLBuilder.js +116 -0
- package/lib/Renderer/Camera.js +281 -0
- package/lib/Renderer/Color.js +56 -0
- package/lib/Renderer/ColorLayersOrdering.js +115 -0
- package/lib/Renderer/CommonMaterial.js +31 -0
- package/lib/Renderer/Label2DRenderer.js +192 -0
- package/lib/Renderer/LayeredMaterial.js +243 -0
- package/lib/Renderer/OBB.js +150 -0
- package/lib/Renderer/OrientedImageCamera.js +118 -0
- package/lib/Renderer/OrientedImageMaterial.js +167 -0
- package/lib/Renderer/PointsMaterial.js +485 -0
- package/lib/Renderer/RasterTile.js +243 -0
- package/lib/Renderer/RenderMode.js +31 -0
- package/lib/Renderer/Shader/ShaderChunk.js +160 -0
- package/lib/Renderer/Shader/ShaderUtils.js +47 -0
- package/lib/Renderer/SphereHelper.js +17 -0
- package/lib/Renderer/WebXR.js +51 -0
- package/lib/Renderer/c3DEngine.js +214 -0
- package/lib/Source/C3DTilesGoogleSource.js +74 -0
- package/lib/Source/C3DTilesIonSource.js +54 -0
- package/lib/Source/C3DTilesSource.js +30 -0
- package/lib/Source/CopcSource.js +126 -0
- package/lib/Source/EntwinePointTileSource.js +72 -0
- package/lib/Source/FileSource.js +188 -0
- package/lib/Source/OGC3DTilesGoogleSource.js +29 -0
- package/lib/Source/OGC3DTilesIonSource.js +34 -0
- package/lib/Source/OGC3DTilesSource.js +21 -0
- package/lib/Source/OrientedImageSource.js +59 -0
- package/lib/Source/Potree2Source.js +167 -0
- package/lib/Source/PotreeSource.js +82 -0
- package/lib/Source/Source.js +202 -0
- package/lib/Source/TMSSource.js +144 -0
- package/lib/Source/VectorTilesSource.js +182 -0
- package/lib/Source/WFSSource.js +170 -0
- package/lib/Source/WMSSource.js +167 -0
- package/lib/Source/WMTSSource.js +92 -0
- package/lib/ThreeExtended/capabilities/WebGL.js +69 -0
- package/lib/ThreeExtended/libs/ktx-parse.module.js +506 -0
- package/lib/ThreeExtended/libs/zstddec.module.js +29 -0
- package/lib/ThreeExtended/loaders/DDSLoader.js +200 -0
- package/lib/ThreeExtended/loaders/DRACOLoader.js +400 -0
- package/lib/ThreeExtended/loaders/GLTFLoader.js +2879 -0
- package/lib/ThreeExtended/loaders/KTX2Loader.js +709 -0
- package/lib/ThreeExtended/math/ColorSpaces.js +59 -0
- package/lib/ThreeExtended/utils/BufferGeometryUtils.js +846 -0
- package/lib/ThreeExtended/utils/WorkerPool.js +70 -0
- package/lib/Utils/CameraUtils.js +554 -0
- package/lib/Utils/DEMUtils.js +350 -0
- package/lib/Utils/FeaturesUtils.js +156 -0
- package/lib/Utils/Gradients.js +16 -0
- package/lib/Utils/ThreeUtils.js +115 -0
- package/lib/Utils/gui/C3DTilesStyle.js +218 -0
- package/lib/Utils/gui/Main.js +7 -0
- package/lib/Utils/gui/Minimap.js +152 -0
- package/lib/Utils/gui/Navigation.js +245 -0
- package/lib/Utils/gui/Scale.js +104 -0
- package/lib/Utils/gui/Searchbar.js +234 -0
- package/lib/Utils/gui/Widget.js +80 -0
- package/lib/Utils/placeObjectOnGround.js +136 -0
- package/lib/Worker/LASLoaderWorker.js +19 -0
- package/lib/Worker/Potree2Worker.js +21 -0
- package/package.json +2 -2
|
@@ -0,0 +1,709 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Loader for KTX 2.0 GPU Texture containers.
|
|
3
|
+
*
|
|
4
|
+
* KTX 2.0 is a container format for various GPU texture formats. The loader
|
|
5
|
+
* supports Basis Universal GPU textures, which can be quickly transcoded to
|
|
6
|
+
* a wide variety of GPU texture compression formats, as well as some
|
|
7
|
+
* uncompressed DataTexture and Data3DTexture formats.
|
|
8
|
+
*
|
|
9
|
+
* References:
|
|
10
|
+
* - KTX: http://github.khronos.org/KTX-Specification/
|
|
11
|
+
* - DFD: https://www.khronos.org/registry/DataFormat/specs/1.3/dataformat.1.3.html#basicdescriptor
|
|
12
|
+
* - BasisU HDR: https://github.com/BinomialLLC/basis_universal/wiki/UASTC-HDR-Texture-Specification-v1.0
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
import { CompressedTexture, CompressedArrayTexture, CompressedCubeTexture, Data3DTexture, DataTexture, FileLoader, FloatType, HalfFloatType, NoColorSpace, LinearFilter, LinearMipmapLinearFilter, LinearSRGBColorSpace, Loader, RedFormat, RGB_BPTC_UNSIGNED_Format, RGB_ETC1_Format, RGB_ETC2_Format, RGB_PVRTC_4BPPV1_Format, RGBA_ASTC_4x4_Format, RGBA_ASTC_6x6_Format, RGBA_BPTC_Format, RGBA_ETC2_EAC_Format, RGBA_PVRTC_4BPPV1_Format, RGBA_S3TC_DXT5_Format, RGBA_S3TC_DXT1_Format, RGBAFormat, RGFormat, SRGBColorSpace, UnsignedByteType } from 'three';
|
|
16
|
+
import { WorkerPool } from "../utils/WorkerPool.js";
|
|
17
|
+
import { read, KHR_DF_FLAG_ALPHA_PREMULTIPLIED, KHR_DF_TRANSFER_SRGB, KHR_SUPERCOMPRESSION_NONE, KHR_SUPERCOMPRESSION_ZSTD, VK_FORMAT_UNDEFINED, VK_FORMAT_R16_SFLOAT, VK_FORMAT_R16G16_SFLOAT, VK_FORMAT_R16G16B16A16_SFLOAT, VK_FORMAT_R32_SFLOAT, VK_FORMAT_R32G32_SFLOAT, VK_FORMAT_R32G32B32A32_SFLOAT, VK_FORMAT_R8_SRGB, VK_FORMAT_R8_UNORM, VK_FORMAT_R8G8_SRGB, VK_FORMAT_R8G8_UNORM, VK_FORMAT_R8G8B8A8_SRGB, VK_FORMAT_R8G8B8A8_UNORM, VK_FORMAT_ASTC_4x4_SFLOAT_BLOCK_EXT, VK_FORMAT_ASTC_6x6_SRGB_BLOCK, VK_FORMAT_ASTC_6x6_UNORM_BLOCK, KHR_DF_PRIMARIES_UNSPECIFIED, KHR_DF_PRIMARIES_BT709, KHR_DF_PRIMARIES_DISPLAYP3 } from "../libs/ktx-parse.module.js";
|
|
18
|
+
import { ZSTDDecoder } from "../libs/zstddec.module.js";
|
|
19
|
+
import { DisplayP3ColorSpace, LinearDisplayP3ColorSpace } from "../math/ColorSpaces.js";
|
|
20
|
+
const _taskCache = new WeakMap();
|
|
21
|
+
let _activeLoaders = 0;
|
|
22
|
+
let _zstd;
|
|
23
|
+
class KTX2Loader extends Loader {
|
|
24
|
+
constructor(manager) {
|
|
25
|
+
super(manager);
|
|
26
|
+
this.transcoderPath = '';
|
|
27
|
+
this.transcoderBinary = null;
|
|
28
|
+
this.transcoderPending = null;
|
|
29
|
+
this.workerPool = new WorkerPool();
|
|
30
|
+
this.workerSourceURL = '';
|
|
31
|
+
this.workerConfig = null;
|
|
32
|
+
if (typeof MSC_TRANSCODER !== 'undefined') {
|
|
33
|
+
console.warn('THREE.KTX2Loader: Please update to latest "basis_transcoder".' + ' "msc_basis_transcoder" is no longer supported in three.js r125+.');
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
setTranscoderPath(path) {
|
|
37
|
+
this.transcoderPath = path;
|
|
38
|
+
return this;
|
|
39
|
+
}
|
|
40
|
+
setWorkerLimit(num) {
|
|
41
|
+
this.workerPool.setWorkerLimit(num);
|
|
42
|
+
return this;
|
|
43
|
+
}
|
|
44
|
+
async detectSupportAsync(renderer) {
|
|
45
|
+
this.workerConfig = {
|
|
46
|
+
astcSupported: await renderer.hasFeatureAsync('texture-compression-astc'),
|
|
47
|
+
astcHDRSupported: false,
|
|
48
|
+
// https://github.com/gpuweb/gpuweb/issues/3856
|
|
49
|
+
etc1Supported: await renderer.hasFeatureAsync('texture-compression-etc1'),
|
|
50
|
+
etc2Supported: await renderer.hasFeatureAsync('texture-compression-etc2'),
|
|
51
|
+
dxtSupported: await renderer.hasFeatureAsync('texture-compression-bc'),
|
|
52
|
+
bptcSupported: await renderer.hasFeatureAsync('texture-compression-bptc'),
|
|
53
|
+
pvrtcSupported: await renderer.hasFeatureAsync('texture-compression-pvrtc')
|
|
54
|
+
};
|
|
55
|
+
return this;
|
|
56
|
+
}
|
|
57
|
+
detectSupport(renderer) {
|
|
58
|
+
if (renderer.isWebGPURenderer === true) {
|
|
59
|
+
this.workerConfig = {
|
|
60
|
+
astcSupported: renderer.hasFeature('texture-compression-astc'),
|
|
61
|
+
astcHDRSupported: false,
|
|
62
|
+
// https://github.com/gpuweb/gpuweb/issues/3856
|
|
63
|
+
etc1Supported: renderer.hasFeature('texture-compression-etc1'),
|
|
64
|
+
etc2Supported: renderer.hasFeature('texture-compression-etc2'),
|
|
65
|
+
dxtSupported: renderer.hasFeature('texture-compression-bc'),
|
|
66
|
+
bptcSupported: renderer.hasFeature('texture-compression-bptc'),
|
|
67
|
+
pvrtcSupported: renderer.hasFeature('texture-compression-pvrtc')
|
|
68
|
+
};
|
|
69
|
+
} else {
|
|
70
|
+
this.workerConfig = {
|
|
71
|
+
astcSupported: renderer.extensions.has('WEBGL_compressed_texture_astc'),
|
|
72
|
+
astcHDRSupported: renderer.extensions.has('WEBGL_compressed_texture_astc') && renderer.extensions.get('WEBGL_compressed_texture_astc').getSupportedProfiles().includes('hdr'),
|
|
73
|
+
etc1Supported: renderer.extensions.has('WEBGL_compressed_texture_etc1'),
|
|
74
|
+
etc2Supported: renderer.extensions.has('WEBGL_compressed_texture_etc'),
|
|
75
|
+
dxtSupported: renderer.extensions.has('WEBGL_compressed_texture_s3tc'),
|
|
76
|
+
bptcSupported: renderer.extensions.has('EXT_texture_compression_bptc'),
|
|
77
|
+
pvrtcSupported: renderer.extensions.has('WEBGL_compressed_texture_pvrtc') || renderer.extensions.has('WEBKIT_WEBGL_compressed_texture_pvrtc')
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
return this;
|
|
81
|
+
}
|
|
82
|
+
init() {
|
|
83
|
+
if (!this.transcoderPending) {
|
|
84
|
+
// Load transcoder wrapper.
|
|
85
|
+
const jsLoader = new FileLoader(this.manager);
|
|
86
|
+
jsLoader.setPath(this.transcoderPath);
|
|
87
|
+
jsLoader.setWithCredentials(this.withCredentials);
|
|
88
|
+
const jsContent = jsLoader.loadAsync('basis_transcoder.js');
|
|
89
|
+
|
|
90
|
+
// Load transcoder WASM binary.
|
|
91
|
+
const binaryLoader = new FileLoader(this.manager);
|
|
92
|
+
binaryLoader.setPath(this.transcoderPath);
|
|
93
|
+
binaryLoader.setResponseType('arraybuffer');
|
|
94
|
+
binaryLoader.setWithCredentials(this.withCredentials);
|
|
95
|
+
const binaryContent = binaryLoader.loadAsync('basis_transcoder.wasm');
|
|
96
|
+
this.transcoderPending = Promise.all([jsContent, binaryContent]).then(_ref => {
|
|
97
|
+
let [jsContent, binaryContent] = _ref;
|
|
98
|
+
const fn = KTX2Loader.BasisWorker.toString();
|
|
99
|
+
const body = ['/* constants */', 'let _EngineFormat = ' + JSON.stringify(KTX2Loader.EngineFormat), 'let _EngineType = ' + JSON.stringify(KTX2Loader.EngineType), 'let _TranscoderFormat = ' + JSON.stringify(KTX2Loader.TranscoderFormat), 'let _BasisFormat = ' + JSON.stringify(KTX2Loader.BasisFormat), '/* basis_transcoder.js */', jsContent, '/* worker */', fn.substring(fn.indexOf('{') + 1, fn.lastIndexOf('}'))].join('\n');
|
|
100
|
+
this.workerSourceURL = URL.createObjectURL(new Blob([body]));
|
|
101
|
+
this.transcoderBinary = binaryContent;
|
|
102
|
+
this.workerPool.setWorkerCreator(() => {
|
|
103
|
+
const worker = new Worker(this.workerSourceURL);
|
|
104
|
+
const transcoderBinary = this.transcoderBinary.slice(0);
|
|
105
|
+
worker.postMessage({
|
|
106
|
+
type: 'init',
|
|
107
|
+
config: this.workerConfig,
|
|
108
|
+
transcoderBinary
|
|
109
|
+
}, [transcoderBinary]);
|
|
110
|
+
return worker;
|
|
111
|
+
});
|
|
112
|
+
});
|
|
113
|
+
if (_activeLoaders > 0) {
|
|
114
|
+
// Each instance loads a transcoder and allocates workers, increasing network and memory cost.
|
|
115
|
+
|
|
116
|
+
console.warn('THREE.KTX2Loader: Multiple active KTX2 loaders may cause performance issues.' + ' Use a single KTX2Loader instance, or call .dispose() on old instances.');
|
|
117
|
+
}
|
|
118
|
+
_activeLoaders++;
|
|
119
|
+
}
|
|
120
|
+
return this.transcoderPending;
|
|
121
|
+
}
|
|
122
|
+
load(url, onLoad, onProgress, onError) {
|
|
123
|
+
if (this.workerConfig === null) {
|
|
124
|
+
throw new Error('THREE.KTX2Loader: Missing initialization with `.detectSupport( renderer )`.');
|
|
125
|
+
}
|
|
126
|
+
const loader = new FileLoader(this.manager);
|
|
127
|
+
loader.setResponseType('arraybuffer');
|
|
128
|
+
loader.setWithCredentials(this.withCredentials);
|
|
129
|
+
loader.load(url, buffer => {
|
|
130
|
+
this.parse(buffer, onLoad, onError);
|
|
131
|
+
}, onProgress, onError);
|
|
132
|
+
}
|
|
133
|
+
parse(buffer, onLoad, onError) {
|
|
134
|
+
if (this.workerConfig === null) {
|
|
135
|
+
throw new Error('THREE.KTX2Loader: Missing initialization with `.detectSupport( renderer )`.');
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
// Check for an existing task using this buffer. A transferred buffer cannot be transferred
|
|
139
|
+
// again from this thread.
|
|
140
|
+
if (_taskCache.has(buffer)) {
|
|
141
|
+
const cachedTask = _taskCache.get(buffer);
|
|
142
|
+
return cachedTask.promise.then(onLoad).catch(onError);
|
|
143
|
+
}
|
|
144
|
+
this._createTexture(buffer).then(texture => onLoad ? onLoad(texture) : null).catch(onError);
|
|
145
|
+
}
|
|
146
|
+
_createTextureFrom(transcodeResult, container) {
|
|
147
|
+
const {
|
|
148
|
+
type: messageType,
|
|
149
|
+
error,
|
|
150
|
+
data: {
|
|
151
|
+
faces,
|
|
152
|
+
width,
|
|
153
|
+
height,
|
|
154
|
+
format,
|
|
155
|
+
type,
|
|
156
|
+
dfdFlags
|
|
157
|
+
}
|
|
158
|
+
} = transcodeResult;
|
|
159
|
+
if (messageType === 'error') return Promise.reject(error);
|
|
160
|
+
let texture;
|
|
161
|
+
if (container.faceCount === 6) {
|
|
162
|
+
texture = new CompressedCubeTexture(faces, format, type);
|
|
163
|
+
} else {
|
|
164
|
+
const mipmaps = faces[0].mipmaps;
|
|
165
|
+
texture = container.layerCount > 1 ? new CompressedArrayTexture(mipmaps, width, height, container.layerCount, format, type) : new CompressedTexture(mipmaps, width, height, format, type);
|
|
166
|
+
}
|
|
167
|
+
texture.minFilter = faces[0].mipmaps.length === 1 ? LinearFilter : LinearMipmapLinearFilter;
|
|
168
|
+
texture.magFilter = LinearFilter;
|
|
169
|
+
texture.generateMipmaps = false;
|
|
170
|
+
texture.needsUpdate = true;
|
|
171
|
+
texture.colorSpace = parseColorSpace(container);
|
|
172
|
+
texture.premultiplyAlpha = !!(dfdFlags & KHR_DF_FLAG_ALPHA_PREMULTIPLIED);
|
|
173
|
+
return texture;
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
/**
|
|
177
|
+
* @param {ArrayBuffer} buffer
|
|
178
|
+
* @param {object?} config
|
|
179
|
+
* @return {Promise<CompressedTexture|CompressedArrayTexture|DataTexture|Data3DTexture>}
|
|
180
|
+
*/
|
|
181
|
+
async _createTexture(buffer) {
|
|
182
|
+
let config = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
|
|
183
|
+
const container = read(new Uint8Array(buffer));
|
|
184
|
+
|
|
185
|
+
// Basis UASTC HDR is a subset of ASTC, which can be transcoded efficiently
|
|
186
|
+
// to BC6H. To detect whether a KTX2 file uses Basis UASTC HDR, or default
|
|
187
|
+
// ASTC, inspect the DFD color model.
|
|
188
|
+
//
|
|
189
|
+
// Source: https://github.com/BinomialLLC/basis_universal/issues/381
|
|
190
|
+
const isBasisHDR = container.vkFormat === VK_FORMAT_ASTC_4x4_SFLOAT_BLOCK_EXT && container.dataFormatDescriptor[0].colorModel === 0xA7;
|
|
191
|
+
|
|
192
|
+
// If the device supports ASTC, Basis UASTC HDR requires no transcoder.
|
|
193
|
+
const needsTranscoder = container.vkFormat === VK_FORMAT_UNDEFINED || isBasisHDR && !this.workerConfig.astcHDRSupported;
|
|
194
|
+
if (!needsTranscoder) {
|
|
195
|
+
return createRawTexture(container);
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
//
|
|
199
|
+
|
|
200
|
+
const texturePending = this.init().then(() => {
|
|
201
|
+
return this.workerPool.postMessage({
|
|
202
|
+
type: 'transcode',
|
|
203
|
+
buffer,
|
|
204
|
+
taskConfig: config
|
|
205
|
+
}, [buffer]);
|
|
206
|
+
}).then(e => this._createTextureFrom(e.data, container));
|
|
207
|
+
|
|
208
|
+
// Cache the task result.
|
|
209
|
+
_taskCache.set(buffer, {
|
|
210
|
+
promise: texturePending
|
|
211
|
+
});
|
|
212
|
+
return texturePending;
|
|
213
|
+
}
|
|
214
|
+
dispose() {
|
|
215
|
+
this.workerPool.dispose();
|
|
216
|
+
if (this.workerSourceURL) URL.revokeObjectURL(this.workerSourceURL);
|
|
217
|
+
_activeLoaders--;
|
|
218
|
+
return this;
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
/* CONSTANTS */
|
|
223
|
+
|
|
224
|
+
KTX2Loader.BasisFormat = {
|
|
225
|
+
ETC1S: 0,
|
|
226
|
+
UASTC: 1,
|
|
227
|
+
UASTC_HDR: 2
|
|
228
|
+
};
|
|
229
|
+
|
|
230
|
+
// Source: https://github.com/BinomialLLC/basis_universal/blob/master/webgl/texture_test/index.html
|
|
231
|
+
KTX2Loader.TranscoderFormat = {
|
|
232
|
+
ETC1: 0,
|
|
233
|
+
ETC2: 1,
|
|
234
|
+
BC1: 2,
|
|
235
|
+
BC3: 3,
|
|
236
|
+
BC4: 4,
|
|
237
|
+
BC5: 5,
|
|
238
|
+
BC7_M6_OPAQUE_ONLY: 6,
|
|
239
|
+
BC7_M5: 7,
|
|
240
|
+
PVRTC1_4_RGB: 8,
|
|
241
|
+
PVRTC1_4_RGBA: 9,
|
|
242
|
+
ASTC_4x4: 10,
|
|
243
|
+
ATC_RGB: 11,
|
|
244
|
+
ATC_RGBA_INTERPOLATED_ALPHA: 12,
|
|
245
|
+
RGBA32: 13,
|
|
246
|
+
RGB565: 14,
|
|
247
|
+
BGR565: 15,
|
|
248
|
+
RGBA4444: 16,
|
|
249
|
+
BC6H: 22,
|
|
250
|
+
RGB_HALF: 24,
|
|
251
|
+
RGBA_HALF: 25
|
|
252
|
+
};
|
|
253
|
+
KTX2Loader.EngineFormat = {
|
|
254
|
+
RGBAFormat: RGBAFormat,
|
|
255
|
+
RGBA_ASTC_4x4_Format: RGBA_ASTC_4x4_Format,
|
|
256
|
+
RGB_BPTC_UNSIGNED_Format: RGB_BPTC_UNSIGNED_Format,
|
|
257
|
+
RGBA_BPTC_Format: RGBA_BPTC_Format,
|
|
258
|
+
RGBA_ETC2_EAC_Format: RGBA_ETC2_EAC_Format,
|
|
259
|
+
RGBA_PVRTC_4BPPV1_Format: RGBA_PVRTC_4BPPV1_Format,
|
|
260
|
+
RGBA_S3TC_DXT5_Format: RGBA_S3TC_DXT5_Format,
|
|
261
|
+
RGB_ETC1_Format: RGB_ETC1_Format,
|
|
262
|
+
RGB_ETC2_Format: RGB_ETC2_Format,
|
|
263
|
+
RGB_PVRTC_4BPPV1_Format: RGB_PVRTC_4BPPV1_Format,
|
|
264
|
+
RGBA_S3TC_DXT1_Format: RGBA_S3TC_DXT1_Format
|
|
265
|
+
};
|
|
266
|
+
KTX2Loader.EngineType = {
|
|
267
|
+
UnsignedByteType: UnsignedByteType,
|
|
268
|
+
HalfFloatType: HalfFloatType,
|
|
269
|
+
FloatType: FloatType
|
|
270
|
+
};
|
|
271
|
+
|
|
272
|
+
/* WEB WORKER */
|
|
273
|
+
|
|
274
|
+
KTX2Loader.BasisWorker = function () {
|
|
275
|
+
let config;
|
|
276
|
+
let transcoderPending;
|
|
277
|
+
let BasisModule;
|
|
278
|
+
const EngineFormat = _EngineFormat; // eslint-disable-line no-undef
|
|
279
|
+
const EngineType = _EngineType; // eslint-disable-line no-undef
|
|
280
|
+
const TranscoderFormat = _TranscoderFormat; // eslint-disable-line no-undef
|
|
281
|
+
const BasisFormat = _BasisFormat; // eslint-disable-line no-undef
|
|
282
|
+
|
|
283
|
+
self.addEventListener('message', function (e) {
|
|
284
|
+
const message = e.data;
|
|
285
|
+
switch (message.type) {
|
|
286
|
+
case 'init':
|
|
287
|
+
config = message.config;
|
|
288
|
+
init(message.transcoderBinary);
|
|
289
|
+
break;
|
|
290
|
+
case 'transcode':
|
|
291
|
+
transcoderPending.then(() => {
|
|
292
|
+
try {
|
|
293
|
+
const {
|
|
294
|
+
faces,
|
|
295
|
+
buffers,
|
|
296
|
+
width,
|
|
297
|
+
height,
|
|
298
|
+
hasAlpha,
|
|
299
|
+
format,
|
|
300
|
+
type,
|
|
301
|
+
dfdFlags
|
|
302
|
+
} = transcode(message.buffer);
|
|
303
|
+
self.postMessage({
|
|
304
|
+
type: 'transcode',
|
|
305
|
+
id: message.id,
|
|
306
|
+
data: {
|
|
307
|
+
faces,
|
|
308
|
+
width,
|
|
309
|
+
height,
|
|
310
|
+
hasAlpha,
|
|
311
|
+
format,
|
|
312
|
+
type,
|
|
313
|
+
dfdFlags
|
|
314
|
+
}
|
|
315
|
+
}, buffers);
|
|
316
|
+
} catch (error) {
|
|
317
|
+
console.error(error);
|
|
318
|
+
self.postMessage({
|
|
319
|
+
type: 'error',
|
|
320
|
+
id: message.id,
|
|
321
|
+
error: error.message
|
|
322
|
+
});
|
|
323
|
+
}
|
|
324
|
+
});
|
|
325
|
+
break;
|
|
326
|
+
}
|
|
327
|
+
});
|
|
328
|
+
function init(wasmBinary) {
|
|
329
|
+
transcoderPending = new Promise(resolve => {
|
|
330
|
+
BasisModule = {
|
|
331
|
+
wasmBinary,
|
|
332
|
+
onRuntimeInitialized: resolve
|
|
333
|
+
};
|
|
334
|
+
BASIS(BasisModule); // eslint-disable-line no-undef
|
|
335
|
+
}).then(() => {
|
|
336
|
+
BasisModule.initializeBasis();
|
|
337
|
+
if (BasisModule.KTX2File === undefined) {
|
|
338
|
+
console.warn('THREE.KTX2Loader: Please update Basis Universal transcoder.');
|
|
339
|
+
}
|
|
340
|
+
});
|
|
341
|
+
}
|
|
342
|
+
function transcode(buffer) {
|
|
343
|
+
const ktx2File = new BasisModule.KTX2File(new Uint8Array(buffer));
|
|
344
|
+
function cleanup() {
|
|
345
|
+
ktx2File.close();
|
|
346
|
+
ktx2File.delete();
|
|
347
|
+
}
|
|
348
|
+
if (!ktx2File.isValid()) {
|
|
349
|
+
cleanup();
|
|
350
|
+
throw new Error('THREE.KTX2Loader: Invalid or unsupported .ktx2 file');
|
|
351
|
+
}
|
|
352
|
+
let basisFormat;
|
|
353
|
+
if (ktx2File.isUASTC()) {
|
|
354
|
+
basisFormat = BasisFormat.UASTC;
|
|
355
|
+
} else if (ktx2File.isETC1S()) {
|
|
356
|
+
basisFormat = BasisFormat.ETC1S;
|
|
357
|
+
} else if (ktx2File.isHDR()) {
|
|
358
|
+
basisFormat = BasisFormat.UASTC_HDR;
|
|
359
|
+
} else {
|
|
360
|
+
throw new Error('THREE.KTX2Loader: Unknown Basis encoding');
|
|
361
|
+
}
|
|
362
|
+
const width = ktx2File.getWidth();
|
|
363
|
+
const height = ktx2File.getHeight();
|
|
364
|
+
const layerCount = ktx2File.getLayers() || 1;
|
|
365
|
+
const levelCount = ktx2File.getLevels();
|
|
366
|
+
const faceCount = ktx2File.getFaces();
|
|
367
|
+
const hasAlpha = ktx2File.getHasAlpha();
|
|
368
|
+
const dfdFlags = ktx2File.getDFDFlags();
|
|
369
|
+
const {
|
|
370
|
+
transcoderFormat,
|
|
371
|
+
engineFormat,
|
|
372
|
+
engineType
|
|
373
|
+
} = getTranscoderFormat(basisFormat, width, height, hasAlpha);
|
|
374
|
+
if (!width || !height || !levelCount) {
|
|
375
|
+
cleanup();
|
|
376
|
+
throw new Error('THREE.KTX2Loader: Invalid texture');
|
|
377
|
+
}
|
|
378
|
+
if (!ktx2File.startTranscoding()) {
|
|
379
|
+
cleanup();
|
|
380
|
+
throw new Error('THREE.KTX2Loader: .startTranscoding failed');
|
|
381
|
+
}
|
|
382
|
+
const faces = [];
|
|
383
|
+
const buffers = [];
|
|
384
|
+
for (let face = 0; face < faceCount; face++) {
|
|
385
|
+
const mipmaps = [];
|
|
386
|
+
for (let mip = 0; mip < levelCount; mip++) {
|
|
387
|
+
const layerMips = [];
|
|
388
|
+
let mipWidth, mipHeight;
|
|
389
|
+
for (let layer = 0; layer < layerCount; layer++) {
|
|
390
|
+
const levelInfo = ktx2File.getImageLevelInfo(mip, layer, face);
|
|
391
|
+
if (face === 0 && mip === 0 && layer === 0 && (levelInfo.origWidth % 4 !== 0 || levelInfo.origHeight % 4 !== 0)) {
|
|
392
|
+
console.warn('THREE.KTX2Loader: ETC1S and UASTC textures should use multiple-of-four dimensions.');
|
|
393
|
+
}
|
|
394
|
+
if (levelCount > 1) {
|
|
395
|
+
mipWidth = levelInfo.origWidth;
|
|
396
|
+
mipHeight = levelInfo.origHeight;
|
|
397
|
+
} else {
|
|
398
|
+
// Handles non-multiple-of-four dimensions in textures without mipmaps. Textures with
|
|
399
|
+
// mipmaps must use multiple-of-four dimensions, for some texture formats and APIs.
|
|
400
|
+
// See mrdoob/three.js#25908.
|
|
401
|
+
mipWidth = levelInfo.width;
|
|
402
|
+
mipHeight = levelInfo.height;
|
|
403
|
+
}
|
|
404
|
+
let dst = new Uint8Array(ktx2File.getImageTranscodedSizeInBytes(mip, layer, 0, transcoderFormat));
|
|
405
|
+
const status = ktx2File.transcodeImage(dst, mip, layer, face, transcoderFormat, 0, -1, -1);
|
|
406
|
+
if (engineType === EngineType.HalfFloatType) {
|
|
407
|
+
dst = new Uint16Array(dst.buffer, dst.byteOffset, dst.byteLength / Uint16Array.BYTES_PER_ELEMENT);
|
|
408
|
+
}
|
|
409
|
+
if (!status) {
|
|
410
|
+
cleanup();
|
|
411
|
+
throw new Error('THREE.KTX2Loader: .transcodeImage failed.');
|
|
412
|
+
}
|
|
413
|
+
layerMips.push(dst);
|
|
414
|
+
}
|
|
415
|
+
const mipData = concat(layerMips);
|
|
416
|
+
mipmaps.push({
|
|
417
|
+
data: mipData,
|
|
418
|
+
width: mipWidth,
|
|
419
|
+
height: mipHeight
|
|
420
|
+
});
|
|
421
|
+
buffers.push(mipData.buffer);
|
|
422
|
+
}
|
|
423
|
+
faces.push({
|
|
424
|
+
mipmaps,
|
|
425
|
+
width,
|
|
426
|
+
height,
|
|
427
|
+
format: engineFormat,
|
|
428
|
+
type: engineType
|
|
429
|
+
});
|
|
430
|
+
}
|
|
431
|
+
cleanup();
|
|
432
|
+
return {
|
|
433
|
+
faces,
|
|
434
|
+
buffers,
|
|
435
|
+
width,
|
|
436
|
+
height,
|
|
437
|
+
hasAlpha,
|
|
438
|
+
dfdFlags,
|
|
439
|
+
format: engineFormat,
|
|
440
|
+
type: engineType
|
|
441
|
+
};
|
|
442
|
+
}
|
|
443
|
+
|
|
444
|
+
//
|
|
445
|
+
|
|
446
|
+
// Optimal choice of a transcoder target format depends on the Basis format (ETC1S, UASTC, or
|
|
447
|
+
// UASTC HDR), device capabilities, and texture dimensions. The list below ranks the formats
|
|
448
|
+
// separately for each format. Currently, priority is assigned based on:
|
|
449
|
+
//
|
|
450
|
+
// high quality > low quality > uncompressed
|
|
451
|
+
//
|
|
452
|
+
// Prioritization may be revisited, or exposed for configuration, in the future.
|
|
453
|
+
//
|
|
454
|
+
// Reference: https://github.com/KhronosGroup/3D-Formats-Guidelines/blob/main/KTXDeveloperGuide.md
|
|
455
|
+
const FORMAT_OPTIONS = [{
|
|
456
|
+
if: 'astcSupported',
|
|
457
|
+
basisFormat: [BasisFormat.UASTC],
|
|
458
|
+
transcoderFormat: [TranscoderFormat.ASTC_4x4, TranscoderFormat.ASTC_4x4],
|
|
459
|
+
engineFormat: [EngineFormat.RGBA_ASTC_4x4_Format, EngineFormat.RGBA_ASTC_4x4_Format],
|
|
460
|
+
engineType: [EngineType.UnsignedByteType],
|
|
461
|
+
priorityETC1S: Infinity,
|
|
462
|
+
priorityUASTC: 1,
|
|
463
|
+
needsPowerOfTwo: false
|
|
464
|
+
}, {
|
|
465
|
+
if: 'bptcSupported',
|
|
466
|
+
basisFormat: [BasisFormat.ETC1S, BasisFormat.UASTC],
|
|
467
|
+
transcoderFormat: [TranscoderFormat.BC7_M5, TranscoderFormat.BC7_M5],
|
|
468
|
+
engineFormat: [EngineFormat.RGBA_BPTC_Format, EngineFormat.RGBA_BPTC_Format],
|
|
469
|
+
engineType: [EngineType.UnsignedByteType],
|
|
470
|
+
priorityETC1S: 3,
|
|
471
|
+
priorityUASTC: 2,
|
|
472
|
+
needsPowerOfTwo: false
|
|
473
|
+
}, {
|
|
474
|
+
if: 'dxtSupported',
|
|
475
|
+
basisFormat: [BasisFormat.ETC1S, BasisFormat.UASTC],
|
|
476
|
+
transcoderFormat: [TranscoderFormat.BC1, TranscoderFormat.BC3],
|
|
477
|
+
engineFormat: [EngineFormat.RGBA_S3TC_DXT1_Format, EngineFormat.RGBA_S3TC_DXT5_Format],
|
|
478
|
+
engineType: [EngineType.UnsignedByteType],
|
|
479
|
+
priorityETC1S: 4,
|
|
480
|
+
priorityUASTC: 5,
|
|
481
|
+
needsPowerOfTwo: false
|
|
482
|
+
}, {
|
|
483
|
+
if: 'etc2Supported',
|
|
484
|
+
basisFormat: [BasisFormat.ETC1S, BasisFormat.UASTC],
|
|
485
|
+
transcoderFormat: [TranscoderFormat.ETC1, TranscoderFormat.ETC2],
|
|
486
|
+
engineFormat: [EngineFormat.RGB_ETC2_Format, EngineFormat.RGBA_ETC2_EAC_Format],
|
|
487
|
+
engineType: [EngineType.UnsignedByteType],
|
|
488
|
+
priorityETC1S: 1,
|
|
489
|
+
priorityUASTC: 3,
|
|
490
|
+
needsPowerOfTwo: false
|
|
491
|
+
}, {
|
|
492
|
+
if: 'etc1Supported',
|
|
493
|
+
basisFormat: [BasisFormat.ETC1S, BasisFormat.UASTC],
|
|
494
|
+
transcoderFormat: [TranscoderFormat.ETC1],
|
|
495
|
+
engineFormat: [EngineFormat.RGB_ETC1_Format],
|
|
496
|
+
engineType: [EngineType.UnsignedByteType],
|
|
497
|
+
priorityETC1S: 2,
|
|
498
|
+
priorityUASTC: 4,
|
|
499
|
+
needsPowerOfTwo: false
|
|
500
|
+
}, {
|
|
501
|
+
if: 'pvrtcSupported',
|
|
502
|
+
basisFormat: [BasisFormat.ETC1S, BasisFormat.UASTC],
|
|
503
|
+
transcoderFormat: [TranscoderFormat.PVRTC1_4_RGB, TranscoderFormat.PVRTC1_4_RGBA],
|
|
504
|
+
engineFormat: [EngineFormat.RGB_PVRTC_4BPPV1_Format, EngineFormat.RGBA_PVRTC_4BPPV1_Format],
|
|
505
|
+
engineType: [EngineType.UnsignedByteType],
|
|
506
|
+
priorityETC1S: 5,
|
|
507
|
+
priorityUASTC: 6,
|
|
508
|
+
needsPowerOfTwo: true
|
|
509
|
+
}, {
|
|
510
|
+
if: 'bptcSupported',
|
|
511
|
+
basisFormat: [BasisFormat.UASTC_HDR],
|
|
512
|
+
transcoderFormat: [TranscoderFormat.BC6H],
|
|
513
|
+
engineFormat: [EngineFormat.RGB_BPTC_UNSIGNED_Format],
|
|
514
|
+
engineType: [EngineType.HalfFloatType],
|
|
515
|
+
priorityHDR: 1,
|
|
516
|
+
needsPowerOfTwo: false
|
|
517
|
+
},
|
|
518
|
+
// Uncompressed fallbacks.
|
|
519
|
+
|
|
520
|
+
{
|
|
521
|
+
basisFormat: [BasisFormat.ETC1S, BasisFormat.UASTC],
|
|
522
|
+
transcoderFormat: [TranscoderFormat.RGBA32, TranscoderFormat.RGBA32],
|
|
523
|
+
engineFormat: [EngineFormat.RGBAFormat, EngineFormat.RGBAFormat],
|
|
524
|
+
engineType: [EngineType.UnsignedByteType, EngineType.UnsignedByteType],
|
|
525
|
+
priorityETC1S: 100,
|
|
526
|
+
priorityUASTC: 100,
|
|
527
|
+
needsPowerOfTwo: false
|
|
528
|
+
}, {
|
|
529
|
+
basisFormat: [BasisFormat.UASTC_HDR],
|
|
530
|
+
transcoderFormat: [TranscoderFormat.RGBA_HALF],
|
|
531
|
+
engineFormat: [EngineFormat.RGBAFormat],
|
|
532
|
+
engineType: [EngineType.HalfFloatType],
|
|
533
|
+
priorityHDR: 100,
|
|
534
|
+
needsPowerOfTwo: false
|
|
535
|
+
}];
|
|
536
|
+
const OPTIONS = {
|
|
537
|
+
// TODO: For ETC1S we intentionally sort by _UASTC_ priority, preserving
|
|
538
|
+
// a historical accident shown to avoid performance pitfalls for Linux with
|
|
539
|
+
// Firefox & AMD GPU (RadeonSI). Further work needed.
|
|
540
|
+
// See https://github.com/mrdoob/three.js/pull/29730.
|
|
541
|
+
[BasisFormat.ETC1S]: FORMAT_OPTIONS.filter(opt => opt.basisFormat.includes(BasisFormat.ETC1S)).sort((a, b) => a.priorityUASTC - b.priorityUASTC),
|
|
542
|
+
[BasisFormat.UASTC]: FORMAT_OPTIONS.filter(opt => opt.basisFormat.includes(BasisFormat.UASTC)).sort((a, b) => a.priorityUASTC - b.priorityUASTC),
|
|
543
|
+
[BasisFormat.UASTC_HDR]: FORMAT_OPTIONS.filter(opt => opt.basisFormat.includes(BasisFormat.UASTC_HDR)).sort((a, b) => a.priorityHDR - b.priorityHDR)
|
|
544
|
+
};
|
|
545
|
+
function getTranscoderFormat(basisFormat, width, height, hasAlpha) {
|
|
546
|
+
const options = OPTIONS[basisFormat];
|
|
547
|
+
for (let i = 0; i < options.length; i++) {
|
|
548
|
+
const opt = options[i];
|
|
549
|
+
if (opt.if && !config[opt.if]) continue;
|
|
550
|
+
if (!opt.basisFormat.includes(basisFormat)) continue;
|
|
551
|
+
if (hasAlpha && opt.transcoderFormat.length < 2) continue;
|
|
552
|
+
if (opt.needsPowerOfTwo && !(isPowerOfTwo(width) && isPowerOfTwo(height))) continue;
|
|
553
|
+
const transcoderFormat = opt.transcoderFormat[hasAlpha ? 1 : 0];
|
|
554
|
+
const engineFormat = opt.engineFormat[hasAlpha ? 1 : 0];
|
|
555
|
+
const engineType = opt.engineType[0];
|
|
556
|
+
return {
|
|
557
|
+
transcoderFormat,
|
|
558
|
+
engineFormat,
|
|
559
|
+
engineType
|
|
560
|
+
};
|
|
561
|
+
}
|
|
562
|
+
throw new Error('THREE.KTX2Loader: Failed to identify transcoding target.');
|
|
563
|
+
}
|
|
564
|
+
function isPowerOfTwo(value) {
|
|
565
|
+
if (value <= 2) return true;
|
|
566
|
+
return (value & value - 1) === 0 && value !== 0;
|
|
567
|
+
}
|
|
568
|
+
|
|
569
|
+
/** Concatenates N byte arrays. */
|
|
570
|
+
function concat(arrays) {
|
|
571
|
+
if (arrays.length === 1) return arrays[0];
|
|
572
|
+
let totalByteLength = 0;
|
|
573
|
+
for (let i = 0; i < arrays.length; i++) {
|
|
574
|
+
const array = arrays[i];
|
|
575
|
+
totalByteLength += array.byteLength;
|
|
576
|
+
}
|
|
577
|
+
const result = new Uint8Array(totalByteLength);
|
|
578
|
+
let byteOffset = 0;
|
|
579
|
+
for (let i = 0; i < arrays.length; i++) {
|
|
580
|
+
const array = arrays[i];
|
|
581
|
+
result.set(array, byteOffset);
|
|
582
|
+
byteOffset += array.byteLength;
|
|
583
|
+
}
|
|
584
|
+
return result;
|
|
585
|
+
}
|
|
586
|
+
};
|
|
587
|
+
|
|
588
|
+
// Parsing for non-Basis textures. These textures may have supercompression
|
|
589
|
+
// like Zstd, but they do not require transcoding.
|
|
590
|
+
|
|
591
|
+
const UNCOMPRESSED_FORMATS = new Set([RGBAFormat, RGFormat, RedFormat]);
|
|
592
|
+
const FORMAT_MAP = {
|
|
593
|
+
[VK_FORMAT_R32G32B32A32_SFLOAT]: RGBAFormat,
|
|
594
|
+
[VK_FORMAT_R16G16B16A16_SFLOAT]: RGBAFormat,
|
|
595
|
+
[VK_FORMAT_R8G8B8A8_UNORM]: RGBAFormat,
|
|
596
|
+
[VK_FORMAT_R8G8B8A8_SRGB]: RGBAFormat,
|
|
597
|
+
[VK_FORMAT_R32G32_SFLOAT]: RGFormat,
|
|
598
|
+
[VK_FORMAT_R16G16_SFLOAT]: RGFormat,
|
|
599
|
+
[VK_FORMAT_R8G8_UNORM]: RGFormat,
|
|
600
|
+
[VK_FORMAT_R8G8_SRGB]: RGFormat,
|
|
601
|
+
[VK_FORMAT_R32_SFLOAT]: RedFormat,
|
|
602
|
+
[VK_FORMAT_R16_SFLOAT]: RedFormat,
|
|
603
|
+
[VK_FORMAT_R8_SRGB]: RedFormat,
|
|
604
|
+
[VK_FORMAT_R8_UNORM]: RedFormat,
|
|
605
|
+
[VK_FORMAT_ASTC_4x4_SFLOAT_BLOCK_EXT]: RGBA_ASTC_4x4_Format,
|
|
606
|
+
[VK_FORMAT_ASTC_6x6_SRGB_BLOCK]: RGBA_ASTC_6x6_Format,
|
|
607
|
+
[VK_FORMAT_ASTC_6x6_UNORM_BLOCK]: RGBA_ASTC_6x6_Format
|
|
608
|
+
};
|
|
609
|
+
const TYPE_MAP = {
|
|
610
|
+
[VK_FORMAT_R32G32B32A32_SFLOAT]: FloatType,
|
|
611
|
+
[VK_FORMAT_R16G16B16A16_SFLOAT]: HalfFloatType,
|
|
612
|
+
[VK_FORMAT_R8G8B8A8_UNORM]: UnsignedByteType,
|
|
613
|
+
[VK_FORMAT_R8G8B8A8_SRGB]: UnsignedByteType,
|
|
614
|
+
[VK_FORMAT_R32G32_SFLOAT]: FloatType,
|
|
615
|
+
[VK_FORMAT_R16G16_SFLOAT]: HalfFloatType,
|
|
616
|
+
[VK_FORMAT_R8G8_UNORM]: UnsignedByteType,
|
|
617
|
+
[VK_FORMAT_R8G8_SRGB]: UnsignedByteType,
|
|
618
|
+
[VK_FORMAT_R32_SFLOAT]: FloatType,
|
|
619
|
+
[VK_FORMAT_R16_SFLOAT]: HalfFloatType,
|
|
620
|
+
[VK_FORMAT_R8_SRGB]: UnsignedByteType,
|
|
621
|
+
[VK_FORMAT_R8_UNORM]: UnsignedByteType,
|
|
622
|
+
[VK_FORMAT_ASTC_4x4_SFLOAT_BLOCK_EXT]: HalfFloatType,
|
|
623
|
+
[VK_FORMAT_ASTC_6x6_SRGB_BLOCK]: UnsignedByteType,
|
|
624
|
+
[VK_FORMAT_ASTC_6x6_UNORM_BLOCK]: UnsignedByteType
|
|
625
|
+
};
|
|
626
|
+
async function createRawTexture(container) {
|
|
627
|
+
const {
|
|
628
|
+
vkFormat
|
|
629
|
+
} = container;
|
|
630
|
+
if (FORMAT_MAP[vkFormat] === undefined) {
|
|
631
|
+
throw new Error('THREE.KTX2Loader: Unsupported vkFormat.');
|
|
632
|
+
}
|
|
633
|
+
|
|
634
|
+
//
|
|
635
|
+
|
|
636
|
+
let zstd;
|
|
637
|
+
if (container.supercompressionScheme === KHR_SUPERCOMPRESSION_ZSTD) {
|
|
638
|
+
if (!_zstd) {
|
|
639
|
+
_zstd = new Promise(async resolve => {
|
|
640
|
+
const zstd = new ZSTDDecoder();
|
|
641
|
+
await zstd.init();
|
|
642
|
+
resolve(zstd);
|
|
643
|
+
});
|
|
644
|
+
}
|
|
645
|
+
zstd = await _zstd;
|
|
646
|
+
}
|
|
647
|
+
|
|
648
|
+
//
|
|
649
|
+
|
|
650
|
+
const mipmaps = [];
|
|
651
|
+
for (let levelIndex = 0; levelIndex < container.levels.length; levelIndex++) {
|
|
652
|
+
const levelWidth = Math.max(1, container.pixelWidth >> levelIndex);
|
|
653
|
+
const levelHeight = Math.max(1, container.pixelHeight >> levelIndex);
|
|
654
|
+
const levelDepth = container.pixelDepth ? Math.max(1, container.pixelDepth >> levelIndex) : 0;
|
|
655
|
+
const level = container.levels[levelIndex];
|
|
656
|
+
let levelData;
|
|
657
|
+
if (container.supercompressionScheme === KHR_SUPERCOMPRESSION_NONE) {
|
|
658
|
+
levelData = level.levelData;
|
|
659
|
+
} else if (container.supercompressionScheme === KHR_SUPERCOMPRESSION_ZSTD) {
|
|
660
|
+
levelData = zstd.decode(level.levelData, level.uncompressedByteLength);
|
|
661
|
+
} else {
|
|
662
|
+
throw new Error('THREE.KTX2Loader: Unsupported supercompressionScheme.');
|
|
663
|
+
}
|
|
664
|
+
let data;
|
|
665
|
+
if (TYPE_MAP[vkFormat] === FloatType) {
|
|
666
|
+
data = new Float32Array(levelData.buffer, levelData.byteOffset, levelData.byteLength / Float32Array.BYTES_PER_ELEMENT);
|
|
667
|
+
} else if (TYPE_MAP[vkFormat] === HalfFloatType) {
|
|
668
|
+
data = new Uint16Array(levelData.buffer, levelData.byteOffset, levelData.byteLength / Uint16Array.BYTES_PER_ELEMENT);
|
|
669
|
+
} else {
|
|
670
|
+
data = levelData;
|
|
671
|
+
}
|
|
672
|
+
mipmaps.push({
|
|
673
|
+
data: data,
|
|
674
|
+
width: levelWidth,
|
|
675
|
+
height: levelHeight,
|
|
676
|
+
depth: levelDepth
|
|
677
|
+
});
|
|
678
|
+
}
|
|
679
|
+
let texture;
|
|
680
|
+
if (UNCOMPRESSED_FORMATS.has(FORMAT_MAP[vkFormat])) {
|
|
681
|
+
texture = container.pixelDepth === 0 ? new DataTexture(mipmaps[0].data, container.pixelWidth, container.pixelHeight) : new Data3DTexture(mipmaps[0].data, container.pixelWidth, container.pixelHeight, container.pixelDepth);
|
|
682
|
+
} else {
|
|
683
|
+
if (container.pixelDepth > 0) throw new Error('THREE.KTX2Loader: Unsupported pixelDepth.');
|
|
684
|
+
texture = new CompressedTexture(mipmaps, container.pixelWidth, container.pixelHeight);
|
|
685
|
+
}
|
|
686
|
+
texture.mipmaps = mipmaps;
|
|
687
|
+
texture.type = TYPE_MAP[vkFormat];
|
|
688
|
+
texture.format = FORMAT_MAP[vkFormat];
|
|
689
|
+
texture.colorSpace = parseColorSpace(container);
|
|
690
|
+
texture.needsUpdate = true;
|
|
691
|
+
|
|
692
|
+
//
|
|
693
|
+
|
|
694
|
+
return Promise.resolve(texture);
|
|
695
|
+
}
|
|
696
|
+
function parseColorSpace(container) {
|
|
697
|
+
const dfd = container.dataFormatDescriptor[0];
|
|
698
|
+
if (dfd.colorPrimaries === KHR_DF_PRIMARIES_BT709) {
|
|
699
|
+
return dfd.transferFunction === KHR_DF_TRANSFER_SRGB ? SRGBColorSpace : LinearSRGBColorSpace;
|
|
700
|
+
} else if (dfd.colorPrimaries === KHR_DF_PRIMARIES_DISPLAYP3) {
|
|
701
|
+
return dfd.transferFunction === KHR_DF_TRANSFER_SRGB ? DisplayP3ColorSpace : LinearDisplayP3ColorSpace;
|
|
702
|
+
} else if (dfd.colorPrimaries === KHR_DF_PRIMARIES_UNSPECIFIED) {
|
|
703
|
+
return NoColorSpace;
|
|
704
|
+
} else {
|
|
705
|
+
console.warn(`THREE.KTX2Loader: Unsupported color primaries, "${dfd.colorPrimaries}"`);
|
|
706
|
+
return NoColorSpace;
|
|
707
|
+
}
|
|
708
|
+
}
|
|
709
|
+
export { KTX2Loader };
|