@damienmortini/three 0.1.193 → 0.1.195
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/copyExamples.js +6 -6
- package/ecs/THREEView.js +7 -7
- package/examples/loaders/BasisTextureLoader.js +659 -788
- package/examples/loaders/DRACOLoader.js +451 -565
- package/examples/loaders/GLTFLoader.js +3361 -4288
- package/examples/loaders/KTX2Loader.js +675 -790
- package/examples/objects/Lensflare.js +353 -376
- package/examples/utils/BufferGeometryUtils.js +1086 -1345
- package/examples/utils/WorkerPool.js +73 -101
- package/gpgpu/THREEGPGPUSystem.js +55 -55
- package/index.js +1 -1
- package/loader/THREELoader.js +72 -67
- package/loader/meshoptimizerdecoder/THREE.EXT_meshopt_compression.js +23 -22
- package/loader/meshoptimizerdecoder/meshopt_decoder.js +53 -50
- package/material/THREEBaseMaterial.js +3 -3
- package/material/THREEPBRMaterial.js +15 -10
- package/material/THREEShaderMaterial.js +33 -32
- package/object/THREELine.js +36 -36
- package/object/THREEMotionVectorObject.js +74 -71
- package/object/THREERibbon.js +16 -17
- package/object/THREESky.js +59 -58
- package/object/THREESprite.js +42 -43
- package/object/THREESpriteAnimation.js +42 -42
- package/object/THREEText.js +106 -104
- package/package.json +4 -4
- package/renderer/THREERenderer.js +64 -60
- package/renderer/THREEStereoRenderer.js +35 -32
- package/renderer/WebGLRenderTarget2D.js +15 -15
- package/shader/THREEBaseShader.js +1 -1
- package/types/index.d.ts +1 -1
- package/types/renderer/WebGLRenderTarget2D.d.ts +22 -22
|
@@ -1,792 +1,677 @@
|
|
|
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
|
-
*/
|
|
13
|
-
|
|
14
|
-
import {
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
} from '../../../../three/src/Three.js';
|
|
41
|
-
import {
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
} from '../libs/
|
|
62
|
-
import {
|
|
63
|
-
|
|
64
|
-
const _taskCache = new WeakMap();
|
|
65
|
-
|
|
66
|
-
let _activeLoaders = 0;
|
|
67
|
-
|
|
68
|
-
let _zstd;
|
|
69
|
-
|
|
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
|
+
*/
|
|
13
|
+
|
|
14
|
+
import {
|
|
15
|
+
CompressedArrayTexture,
|
|
16
|
+
CompressedTexture,
|
|
17
|
+
Data3DTexture,
|
|
18
|
+
DataTexture,
|
|
19
|
+
FileLoader,
|
|
20
|
+
FloatType,
|
|
21
|
+
HalfFloatType,
|
|
22
|
+
LinearEncoding,
|
|
23
|
+
LinearFilter,
|
|
24
|
+
LinearMipmapLinearFilter,
|
|
25
|
+
Loader,
|
|
26
|
+
RedFormat,
|
|
27
|
+
RGB_ETC1_Format,
|
|
28
|
+
RGB_ETC2_Format,
|
|
29
|
+
RGB_PVRTC_4BPPV1_Format,
|
|
30
|
+
RGB_S3TC_DXT1_Format,
|
|
31
|
+
RGBA_ASTC_4x4_Format,
|
|
32
|
+
RGBA_BPTC_Format,
|
|
33
|
+
RGBA_ETC2_EAC_Format,
|
|
34
|
+
RGBA_PVRTC_4BPPV1_Format,
|
|
35
|
+
RGBA_S3TC_DXT5_Format,
|
|
36
|
+
RGBAFormat,
|
|
37
|
+
RGFormat,
|
|
38
|
+
sRGBEncoding,
|
|
39
|
+
UnsignedByteType,
|
|
40
|
+
} from '../../../../three/src/Three.js';
|
|
41
|
+
import {
|
|
42
|
+
KHR_DF_FLAG_ALPHA_PREMULTIPLIED,
|
|
43
|
+
KHR_DF_TRANSFER_SRGB,
|
|
44
|
+
KHR_SUPERCOMPRESSION_NONE,
|
|
45
|
+
KHR_SUPERCOMPRESSION_ZSTD,
|
|
46
|
+
read,
|
|
47
|
+
VK_FORMAT_R8_SRGB,
|
|
48
|
+
VK_FORMAT_R8_UNORM,
|
|
49
|
+
VK_FORMAT_R8G8_SRGB,
|
|
50
|
+
VK_FORMAT_R8G8_UNORM,
|
|
51
|
+
VK_FORMAT_R8G8B8A8_SRGB,
|
|
52
|
+
VK_FORMAT_R8G8B8A8_UNORM,
|
|
53
|
+
VK_FORMAT_R16_SFLOAT,
|
|
54
|
+
VK_FORMAT_R16G16_SFLOAT,
|
|
55
|
+
VK_FORMAT_R16G16B16A16_SFLOAT,
|
|
56
|
+
VK_FORMAT_R32_SFLOAT,
|
|
57
|
+
VK_FORMAT_R32G32_SFLOAT,
|
|
58
|
+
VK_FORMAT_R32G32B32A32_SFLOAT,
|
|
59
|
+
VK_FORMAT_UNDEFINED,
|
|
60
|
+
} from '../libs/ktx-parse.module.js';
|
|
61
|
+
import { ZSTDDecoder } from '../libs/zstddec.module.js';
|
|
62
|
+
import { WorkerPool } from '../utils/WorkerPool.js';
|
|
63
|
+
|
|
64
|
+
const _taskCache = new WeakMap();
|
|
65
|
+
|
|
66
|
+
let _activeLoaders = 0;
|
|
67
|
+
|
|
68
|
+
let _zstd;
|
|
69
|
+
|
|
70
70
|
class KTX2Loader extends Loader {
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
}
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
/* CONSTANTS */
|
|
308
|
-
|
|
309
|
-
KTX2Loader.BasisFormat = {
|
|
310
|
-
ETC1S: 0,
|
|
311
|
-
UASTC_4x4: 1,
|
|
312
|
-
};
|
|
313
|
-
|
|
314
|
-
KTX2Loader.TranscoderFormat = {
|
|
315
|
-
ETC1: 0,
|
|
316
|
-
ETC2: 1,
|
|
317
|
-
BC1: 2,
|
|
318
|
-
BC3: 3,
|
|
319
|
-
BC4: 4,
|
|
320
|
-
BC5: 5,
|
|
321
|
-
BC7_M6_OPAQUE_ONLY: 6,
|
|
322
|
-
BC7_M5: 7,
|
|
323
|
-
PVRTC1_4_RGB: 8,
|
|
324
|
-
PVRTC1_4_RGBA: 9,
|
|
325
|
-
ASTC_4x4: 10,
|
|
326
|
-
ATC_RGB: 11,
|
|
327
|
-
ATC_RGBA_INTERPOLATED_ALPHA: 12,
|
|
328
|
-
RGBA32: 13,
|
|
329
|
-
RGB565: 14,
|
|
330
|
-
BGR565: 15,
|
|
331
|
-
RGBA4444: 16,
|
|
332
|
-
};
|
|
333
|
-
|
|
334
|
-
KTX2Loader.EngineFormat = {
|
|
335
|
-
RGBAFormat: RGBAFormat,
|
|
336
|
-
RGBA_ASTC_4x4_Format: RGBA_ASTC_4x4_Format,
|
|
337
|
-
RGBA_BPTC_Format: RGBA_BPTC_Format,
|
|
338
|
-
RGBA_ETC2_EAC_Format: RGBA_ETC2_EAC_Format,
|
|
339
|
-
RGBA_PVRTC_4BPPV1_Format: RGBA_PVRTC_4BPPV1_Format,
|
|
340
|
-
RGBA_S3TC_DXT5_Format: RGBA_S3TC_DXT5_Format,
|
|
341
|
-
RGB_ETC1_Format: RGB_ETC1_Format,
|
|
342
|
-
RGB_ETC2_Format: RGB_ETC2_Format,
|
|
343
|
-
RGB_PVRTC_4BPPV1_Format: RGB_PVRTC_4BPPV1_Format,
|
|
344
|
-
RGB_S3TC_DXT1_Format: RGB_S3TC_DXT1_Format,
|
|
345
|
-
};
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
/* WEB WORKER */
|
|
349
|
-
|
|
71
|
+
constructor(manager) {
|
|
72
|
+
super(manager);
|
|
73
|
+
|
|
74
|
+
this.transcoderPath = '';
|
|
75
|
+
this.transcoderBinary = null;
|
|
76
|
+
this.transcoderPending = null;
|
|
77
|
+
|
|
78
|
+
this.workerPool = new WorkerPool();
|
|
79
|
+
this.workerSourceURL = '';
|
|
80
|
+
this.workerConfig = null;
|
|
81
|
+
|
|
82
|
+
if (typeof MSC_TRANSCODER !== 'undefined') {
|
|
83
|
+
console.warn(
|
|
84
|
+
|
|
85
|
+
'THREE.KTX2Loader: Please update to latest "basis_transcoder".'
|
|
86
|
+
+ ' "msc_basis_transcoder" is no longer supported in three.js r125+.',
|
|
87
|
+
|
|
88
|
+
);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
setTranscoderPath(path) {
|
|
93
|
+
this.transcoderPath = path;
|
|
94
|
+
|
|
95
|
+
return this;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
setWorkerLimit(num) {
|
|
99
|
+
this.workerPool.setWorkerLimit(num);
|
|
100
|
+
|
|
101
|
+
return this;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
detectSupport(renderer) {
|
|
105
|
+
this.workerConfig = {
|
|
106
|
+
astcSupported: renderer.extensions.has('WEBGL_compressed_texture_astc'),
|
|
107
|
+
etc1Supported: renderer.extensions.has('WEBGL_compressed_texture_etc1'),
|
|
108
|
+
etc2Supported: renderer.extensions.has('WEBGL_compressed_texture_etc'),
|
|
109
|
+
dxtSupported: renderer.extensions.has('WEBGL_compressed_texture_s3tc'),
|
|
110
|
+
bptcSupported: renderer.extensions.has('EXT_texture_compression_bptc'),
|
|
111
|
+
pvrtcSupported: renderer.extensions.has('WEBGL_compressed_texture_pvrtc')
|
|
112
|
+
|| renderer.extensions.has('WEBKIT_WEBGL_compressed_texture_pvrtc'),
|
|
113
|
+
};
|
|
114
|
+
|
|
115
|
+
if (renderer.capabilities.isWebGL2) {
|
|
116
|
+
// https://github.com/mrdoob/three.js/pull/22928
|
|
117
|
+
this.workerConfig.etc1Supported = false;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
return this;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
init() {
|
|
124
|
+
if (!this.transcoderPending) {
|
|
125
|
+
// Load transcoder wrapper.
|
|
126
|
+
const jsLoader = new FileLoader(this.manager);
|
|
127
|
+
jsLoader.setPath(this.transcoderPath);
|
|
128
|
+
jsLoader.setWithCredentials(this.withCredentials);
|
|
129
|
+
const jsContent = jsLoader.loadAsync('basis_transcoder.js');
|
|
130
|
+
|
|
131
|
+
// Load transcoder WASM binary.
|
|
132
|
+
const binaryLoader = new FileLoader(this.manager);
|
|
133
|
+
binaryLoader.setPath(this.transcoderPath);
|
|
134
|
+
binaryLoader.setResponseType('arraybuffer');
|
|
135
|
+
binaryLoader.setWithCredentials(this.withCredentials);
|
|
136
|
+
const binaryContent = binaryLoader.loadAsync('basis_transcoder.wasm');
|
|
137
|
+
|
|
138
|
+
this.transcoderPending = Promise.all([jsContent, binaryContent])
|
|
139
|
+
.then(([jsContent, binaryContent]) => {
|
|
140
|
+
const fn = KTX2Loader.BasisWorker.toString();
|
|
141
|
+
|
|
142
|
+
const body = [
|
|
143
|
+
'/* constants */',
|
|
144
|
+
'let _EngineFormat = ' + JSON.stringify(KTX2Loader.EngineFormat),
|
|
145
|
+
'let _TranscoderFormat = ' + JSON.stringify(KTX2Loader.TranscoderFormat),
|
|
146
|
+
'let _BasisFormat = ' + JSON.stringify(KTX2Loader.BasisFormat),
|
|
147
|
+
'/* basis_transcoder.js */',
|
|
148
|
+
jsContent,
|
|
149
|
+
'/* worker */',
|
|
150
|
+
fn.substring(fn.indexOf('{') + 1, fn.lastIndexOf('}')),
|
|
151
|
+
].join('\n');
|
|
152
|
+
|
|
153
|
+
this.workerSourceURL = URL.createObjectURL(new Blob([body]));
|
|
154
|
+
this.transcoderBinary = binaryContent;
|
|
155
|
+
|
|
156
|
+
this.workerPool.setWorkerCreator(() => {
|
|
157
|
+
const worker = new Worker(this.workerSourceURL);
|
|
158
|
+
const transcoderBinary = this.transcoderBinary.slice(0);
|
|
159
|
+
|
|
160
|
+
worker.postMessage({ type: 'init', config: this.workerConfig, transcoderBinary }, [transcoderBinary]);
|
|
161
|
+
|
|
162
|
+
return worker;
|
|
163
|
+
});
|
|
164
|
+
});
|
|
165
|
+
|
|
166
|
+
if (_activeLoaders > 0) {
|
|
167
|
+
// Each instance loads a transcoder and allocates workers, increasing network and memory cost.
|
|
168
|
+
|
|
169
|
+
console.warn(
|
|
170
|
+
|
|
171
|
+
'THREE.KTX2Loader: Multiple active KTX2 loaders may cause performance issues.'
|
|
172
|
+
+ ' Use a single KTX2Loader instance, or call .dispose() on old instances.',
|
|
173
|
+
|
|
174
|
+
);
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
_activeLoaders++;
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
return this.transcoderPending;
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
load(url, onLoad, onProgress, onError) {
|
|
184
|
+
if (this.workerConfig === null) {
|
|
185
|
+
throw new Error('THREE.KTX2Loader: Missing initialization with `.detectSupport( renderer )`.');
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
const loader = new FileLoader(this.manager);
|
|
189
|
+
|
|
190
|
+
loader.setResponseType('arraybuffer');
|
|
191
|
+
loader.setWithCredentials(this.withCredentials);
|
|
192
|
+
|
|
193
|
+
loader.load(url, (buffer) => {
|
|
194
|
+
// Check for an existing task using this buffer. A transferred buffer cannot be transferred
|
|
195
|
+
// again from this thread.
|
|
196
|
+
if (_taskCache.has(buffer)) {
|
|
197
|
+
const cachedTask = _taskCache.get(buffer);
|
|
198
|
+
|
|
199
|
+
return cachedTask.promise.then(onLoad).catch(onError);
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
this._createTexture(buffer)
|
|
203
|
+
.then(texture => onLoad ? onLoad(texture) : null)
|
|
204
|
+
.catch(onError);
|
|
205
|
+
}, onProgress, onError);
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
_createTextureFrom(transcodeResult, container) {
|
|
209
|
+
const { mipmaps, width, height, format, type, error, dfdTransferFn, dfdFlags } = transcodeResult;
|
|
210
|
+
|
|
211
|
+
if (type === 'error') return Promise.reject(error);
|
|
212
|
+
|
|
213
|
+
const texture = container.layerCount > 1
|
|
214
|
+
? new CompressedArrayTexture(mipmaps, width, height, container.layerCount, format, UnsignedByteType)
|
|
215
|
+
: new CompressedTexture(mipmaps, width, height, format, UnsignedByteType);
|
|
216
|
+
|
|
217
|
+
texture.minFilter = mipmaps.length === 1 ? LinearFilter : LinearMipmapLinearFilter;
|
|
218
|
+
texture.magFilter = LinearFilter;
|
|
219
|
+
texture.generateMipmaps = false;
|
|
220
|
+
|
|
221
|
+
texture.needsUpdate = true;
|
|
222
|
+
texture.encoding = dfdTransferFn === KHR_DF_TRANSFER_SRGB ? sRGBEncoding : LinearEncoding;
|
|
223
|
+
texture.premultiplyAlpha = !!(dfdFlags & KHR_DF_FLAG_ALPHA_PREMULTIPLIED);
|
|
224
|
+
|
|
225
|
+
return texture;
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
/**
|
|
229
|
+
* @param {ArrayBuffer} buffer
|
|
230
|
+
* @param {object?} config
|
|
231
|
+
* @return {Promise<CompressedTexture|CompressedArrayTexture|DataTexture|Data3DTexture>}
|
|
232
|
+
*/
|
|
233
|
+
async _createTexture(buffer, config = {}) {
|
|
234
|
+
const container = read(new Uint8Array(buffer));
|
|
235
|
+
|
|
236
|
+
if (container.vkFormat !== VK_FORMAT_UNDEFINED) {
|
|
237
|
+
return createDataTexture(container);
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
//
|
|
241
|
+
const taskConfig = config;
|
|
242
|
+
const texturePending = this.init().then(() => {
|
|
243
|
+
return this.workerPool.postMessage({ type: 'transcode', buffer, taskConfig: taskConfig }, [buffer]);
|
|
244
|
+
}).then(e => this._createTextureFrom(e.data, container));
|
|
245
|
+
|
|
246
|
+
// Cache the task result.
|
|
247
|
+
_taskCache.set(buffer, { promise: texturePending });
|
|
248
|
+
|
|
249
|
+
return texturePending;
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
dispose() {
|
|
253
|
+
this.workerPool.dispose();
|
|
254
|
+
if (this.workerSourceURL) URL.revokeObjectURL(this.workerSourceURL);
|
|
255
|
+
|
|
256
|
+
_activeLoaders--;
|
|
257
|
+
|
|
258
|
+
return this;
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
/* CONSTANTS */
|
|
263
|
+
|
|
264
|
+
KTX2Loader.BasisFormat = {
|
|
265
|
+
ETC1S: 0,
|
|
266
|
+
UASTC_4x4: 1,
|
|
267
|
+
};
|
|
268
|
+
|
|
269
|
+
KTX2Loader.TranscoderFormat = {
|
|
270
|
+
ETC1: 0,
|
|
271
|
+
ETC2: 1,
|
|
272
|
+
BC1: 2,
|
|
273
|
+
BC3: 3,
|
|
274
|
+
BC4: 4,
|
|
275
|
+
BC5: 5,
|
|
276
|
+
BC7_M6_OPAQUE_ONLY: 6,
|
|
277
|
+
BC7_M5: 7,
|
|
278
|
+
PVRTC1_4_RGB: 8,
|
|
279
|
+
PVRTC1_4_RGBA: 9,
|
|
280
|
+
ASTC_4x4: 10,
|
|
281
|
+
ATC_RGB: 11,
|
|
282
|
+
ATC_RGBA_INTERPOLATED_ALPHA: 12,
|
|
283
|
+
RGBA32: 13,
|
|
284
|
+
RGB565: 14,
|
|
285
|
+
BGR565: 15,
|
|
286
|
+
RGBA4444: 16,
|
|
287
|
+
};
|
|
288
|
+
|
|
289
|
+
KTX2Loader.EngineFormat = {
|
|
290
|
+
RGBAFormat: RGBAFormat,
|
|
291
|
+
RGBA_ASTC_4x4_Format: RGBA_ASTC_4x4_Format,
|
|
292
|
+
RGBA_BPTC_Format: RGBA_BPTC_Format,
|
|
293
|
+
RGBA_ETC2_EAC_Format: RGBA_ETC2_EAC_Format,
|
|
294
|
+
RGBA_PVRTC_4BPPV1_Format: RGBA_PVRTC_4BPPV1_Format,
|
|
295
|
+
RGBA_S3TC_DXT5_Format: RGBA_S3TC_DXT5_Format,
|
|
296
|
+
RGB_ETC1_Format: RGB_ETC1_Format,
|
|
297
|
+
RGB_ETC2_Format: RGB_ETC2_Format,
|
|
298
|
+
RGB_PVRTC_4BPPV1_Format: RGB_PVRTC_4BPPV1_Format,
|
|
299
|
+
RGB_S3TC_DXT1_Format: RGB_S3TC_DXT1_Format,
|
|
300
|
+
};
|
|
301
|
+
|
|
302
|
+
/* WEB WORKER */
|
|
303
|
+
|
|
350
304
|
KTX2Loader.BasisWorker = function () {
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
const
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
levelData = level.levelData;
|
|
726
|
-
|
|
727
|
-
} else if ( container.supercompressionScheme === KHR_SUPERCOMPRESSION_ZSTD ) {
|
|
728
|
-
|
|
729
|
-
if ( ! _zstd ) {
|
|
730
|
-
|
|
731
|
-
_zstd = new Promise( async ( resolve ) => {
|
|
732
|
-
|
|
733
|
-
const zstd = new ZSTDDecoder();
|
|
734
|
-
await zstd.init();
|
|
735
|
-
resolve( zstd );
|
|
736
|
-
|
|
737
|
-
} );
|
|
738
|
-
|
|
739
|
-
}
|
|
740
|
-
|
|
741
|
-
levelData = ( await _zstd ).decode( level.levelData, level.uncompressedByteLength );
|
|
742
|
-
|
|
743
|
-
} else {
|
|
744
|
-
|
|
745
|
-
throw new Error( 'THREE.KTX2Loader: Unsupported supercompressionScheme.' );
|
|
746
|
-
|
|
747
|
-
}
|
|
748
|
-
|
|
749
|
-
if ( TYPE_MAP[ vkFormat ] === FloatType ) {
|
|
750
|
-
|
|
751
|
-
view = new Float32Array(
|
|
752
|
-
|
|
753
|
-
levelData.buffer,
|
|
754
|
-
levelData.byteOffset,
|
|
755
|
-
levelData.byteLength / Float32Array.BYTES_PER_ELEMENT
|
|
756
|
-
|
|
757
|
-
);
|
|
758
|
-
|
|
759
|
-
} else if ( TYPE_MAP[ vkFormat ] === HalfFloatType ) {
|
|
760
|
-
|
|
761
|
-
view = new Uint16Array(
|
|
762
|
-
|
|
763
|
-
levelData.buffer,
|
|
764
|
-
levelData.byteOffset,
|
|
765
|
-
levelData.byteLength / Uint16Array.BYTES_PER_ELEMENT
|
|
766
|
-
|
|
767
|
-
);
|
|
768
|
-
|
|
769
|
-
} else {
|
|
770
|
-
|
|
771
|
-
view = levelData;
|
|
772
|
-
|
|
773
|
-
}
|
|
774
|
-
//
|
|
775
|
-
|
|
776
|
-
const texture = pixelDepth === 0
|
|
777
|
-
? new DataTexture( view, pixelWidth, pixelHeight )
|
|
778
|
-
: new Data3DTexture( view, pixelWidth, pixelHeight, pixelDepth );
|
|
779
|
-
|
|
780
|
-
texture.type = TYPE_MAP[ vkFormat ];
|
|
781
|
-
texture.format = FORMAT_MAP[ vkFormat ];
|
|
782
|
-
texture.encoding = ENCODING_MAP[ vkFormat ] || LinearEncoding;
|
|
783
|
-
|
|
784
|
-
texture.needsUpdate = true;
|
|
785
|
-
|
|
786
|
-
//
|
|
787
|
-
|
|
788
|
-
return Promise.resolve( texture );
|
|
789
|
-
|
|
790
|
-
}
|
|
791
|
-
|
|
792
|
-
export { KTX2Loader };
|
|
305
|
+
let config;
|
|
306
|
+
let transcoderPending;
|
|
307
|
+
let BasisModule;
|
|
308
|
+
|
|
309
|
+
const EngineFormat = _EngineFormat; // eslint-disable-line no-undef
|
|
310
|
+
const TranscoderFormat = _TranscoderFormat; // eslint-disable-line no-undef
|
|
311
|
+
const BasisFormat = _BasisFormat; // eslint-disable-line no-undef
|
|
312
|
+
|
|
313
|
+
self.addEventListener('message', function (e) {
|
|
314
|
+
const message = e.data;
|
|
315
|
+
|
|
316
|
+
switch (message.type) {
|
|
317
|
+
case 'init':
|
|
318
|
+
config = message.config;
|
|
319
|
+
init(message.transcoderBinary);
|
|
320
|
+
break;
|
|
321
|
+
|
|
322
|
+
case 'transcode':
|
|
323
|
+
transcoderPending.then(() => {
|
|
324
|
+
try {
|
|
325
|
+
const { width, height, hasAlpha, mipmaps, format, dfdTransferFn, dfdFlags } = transcode(message.buffer);
|
|
326
|
+
|
|
327
|
+
const buffers = [];
|
|
328
|
+
|
|
329
|
+
for (let i = 0; i < mipmaps.length; ++i) {
|
|
330
|
+
buffers.push(mipmaps[i].data.buffer);
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
self.postMessage({ type: 'transcode', id: message.id, width, height, hasAlpha, mipmaps, format, dfdTransferFn, dfdFlags }, buffers);
|
|
334
|
+
}
|
|
335
|
+
catch (error) {
|
|
336
|
+
console.error(error);
|
|
337
|
+
|
|
338
|
+
self.postMessage({ type: 'error', id: message.id, error: error.message });
|
|
339
|
+
}
|
|
340
|
+
});
|
|
341
|
+
break;
|
|
342
|
+
}
|
|
343
|
+
});
|
|
344
|
+
|
|
345
|
+
function init(wasmBinary) {
|
|
346
|
+
transcoderPending = new Promise((resolve) => {
|
|
347
|
+
BasisModule = { wasmBinary, onRuntimeInitialized: resolve };
|
|
348
|
+
BASIS(BasisModule); // eslint-disable-line no-undef
|
|
349
|
+
}).then(() => {
|
|
350
|
+
BasisModule.initializeBasis();
|
|
351
|
+
|
|
352
|
+
if (BasisModule.KTX2File === undefined) {
|
|
353
|
+
console.warn('THREE.KTX2Loader: Please update Basis Universal transcoder.');
|
|
354
|
+
}
|
|
355
|
+
});
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
function transcode(buffer) {
|
|
359
|
+
const ktx2File = new BasisModule.KTX2File(new Uint8Array(buffer));
|
|
360
|
+
|
|
361
|
+
function cleanup() {
|
|
362
|
+
ktx2File.close();
|
|
363
|
+
ktx2File.delete();
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
if (!ktx2File.isValid()) {
|
|
367
|
+
cleanup();
|
|
368
|
+
throw new Error('THREE.KTX2Loader: Invalid or unsupported .ktx2 file');
|
|
369
|
+
}
|
|
370
|
+
|
|
371
|
+
const basisFormat = ktx2File.isUASTC() ? BasisFormat.UASTC_4x4 : BasisFormat.ETC1S;
|
|
372
|
+
const width = ktx2File.getWidth();
|
|
373
|
+
const height = ktx2File.getHeight();
|
|
374
|
+
const layers = ktx2File.getLayers() || 1;
|
|
375
|
+
const levels = ktx2File.getLevels();
|
|
376
|
+
const hasAlpha = ktx2File.getHasAlpha();
|
|
377
|
+
const dfdTransferFn = ktx2File.getDFDTransferFunc();
|
|
378
|
+
const dfdFlags = ktx2File.getDFDFlags();
|
|
379
|
+
|
|
380
|
+
const { transcoderFormat, engineFormat } = getTranscoderFormat(basisFormat, width, height, hasAlpha);
|
|
381
|
+
|
|
382
|
+
if (!width || !height || !levels) {
|
|
383
|
+
cleanup();
|
|
384
|
+
throw new Error('THREE.KTX2Loader: Invalid texture');
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
if (!ktx2File.startTranscoding()) {
|
|
388
|
+
cleanup();
|
|
389
|
+
throw new Error('THREE.KTX2Loader: .startTranscoding failed');
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
const mipmaps = [];
|
|
393
|
+
|
|
394
|
+
for (let mip = 0; mip < levels; mip++) {
|
|
395
|
+
const layerMips = [];
|
|
396
|
+
|
|
397
|
+
let mipWidth, mipHeight;
|
|
398
|
+
|
|
399
|
+
for (let layer = 0; layer < layers; layer++) {
|
|
400
|
+
const levelInfo = ktx2File.getImageLevelInfo(mip, layer, 0);
|
|
401
|
+
mipWidth = levelInfo.origWidth;
|
|
402
|
+
mipHeight = levelInfo.origHeight;
|
|
403
|
+
const dst = new Uint8Array(ktx2File.getImageTranscodedSizeInBytes(mip, layer, 0, transcoderFormat));
|
|
404
|
+
const status = ktx2File.transcodeImage(
|
|
405
|
+
dst,
|
|
406
|
+
mip,
|
|
407
|
+
layer,
|
|
408
|
+
0,
|
|
409
|
+
transcoderFormat,
|
|
410
|
+
0,
|
|
411
|
+
-1,
|
|
412
|
+
-1,
|
|
413
|
+
);
|
|
414
|
+
|
|
415
|
+
if (!status) {
|
|
416
|
+
cleanup();
|
|
417
|
+
throw new Error('THREE.KTX2Loader: .transcodeImage failed.');
|
|
418
|
+
}
|
|
419
|
+
|
|
420
|
+
layerMips.push(dst);
|
|
421
|
+
}
|
|
422
|
+
|
|
423
|
+
mipmaps.push({ data: concat(layerMips), width: mipWidth, height: mipHeight });
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
cleanup();
|
|
427
|
+
|
|
428
|
+
return { width, height, hasAlpha, mipmaps, format: engineFormat, dfdTransferFn, dfdFlags };
|
|
429
|
+
}
|
|
430
|
+
|
|
431
|
+
//
|
|
432
|
+
|
|
433
|
+
// Optimal choice of a transcoder target format depends on the Basis format (ETC1S or UASTC),
|
|
434
|
+
// device capabilities, and texture dimensions. The list below ranks the formats separately
|
|
435
|
+
// for ETC1S and UASTC.
|
|
436
|
+
//
|
|
437
|
+
// In some cases, transcoding UASTC to RGBA32 might be preferred for higher quality (at
|
|
438
|
+
// significant memory cost) compared to ETC1/2, BC1/3, and PVRTC. The transcoder currently
|
|
439
|
+
// chooses RGBA32 only as a last resort and does not expose that option to the caller.
|
|
440
|
+
const FORMAT_OPTIONS = [
|
|
441
|
+
{
|
|
442
|
+
if: 'astcSupported',
|
|
443
|
+
basisFormat: [BasisFormat.UASTC_4x4],
|
|
444
|
+
transcoderFormat: [TranscoderFormat.ASTC_4x4, TranscoderFormat.ASTC_4x4],
|
|
445
|
+
engineFormat: [EngineFormat.RGBA_ASTC_4x4_Format, EngineFormat.RGBA_ASTC_4x4_Format],
|
|
446
|
+
priorityETC1S: Infinity,
|
|
447
|
+
priorityUASTC: 1,
|
|
448
|
+
needsPowerOfTwo: false,
|
|
449
|
+
},
|
|
450
|
+
{
|
|
451
|
+
if: 'bptcSupported',
|
|
452
|
+
basisFormat: [BasisFormat.ETC1S, BasisFormat.UASTC_4x4],
|
|
453
|
+
transcoderFormat: [TranscoderFormat.BC7_M5, TranscoderFormat.BC7_M5],
|
|
454
|
+
engineFormat: [EngineFormat.RGBA_BPTC_Format, EngineFormat.RGBA_BPTC_Format],
|
|
455
|
+
priorityETC1S: 3,
|
|
456
|
+
priorityUASTC: 2,
|
|
457
|
+
needsPowerOfTwo: false,
|
|
458
|
+
},
|
|
459
|
+
{
|
|
460
|
+
if: 'dxtSupported',
|
|
461
|
+
basisFormat: [BasisFormat.ETC1S, BasisFormat.UASTC_4x4],
|
|
462
|
+
transcoderFormat: [TranscoderFormat.BC1, TranscoderFormat.BC3],
|
|
463
|
+
engineFormat: [EngineFormat.RGB_S3TC_DXT1_Format, EngineFormat.RGBA_S3TC_DXT5_Format],
|
|
464
|
+
priorityETC1S: 4,
|
|
465
|
+
priorityUASTC: 5,
|
|
466
|
+
needsPowerOfTwo: false,
|
|
467
|
+
},
|
|
468
|
+
{
|
|
469
|
+
if: 'etc2Supported',
|
|
470
|
+
basisFormat: [BasisFormat.ETC1S, BasisFormat.UASTC_4x4],
|
|
471
|
+
transcoderFormat: [TranscoderFormat.ETC1, TranscoderFormat.ETC2],
|
|
472
|
+
engineFormat: [EngineFormat.RGB_ETC2_Format, EngineFormat.RGBA_ETC2_EAC_Format],
|
|
473
|
+
priorityETC1S: 1,
|
|
474
|
+
priorityUASTC: 3,
|
|
475
|
+
needsPowerOfTwo: false,
|
|
476
|
+
},
|
|
477
|
+
{
|
|
478
|
+
if: 'etc1Supported',
|
|
479
|
+
basisFormat: [BasisFormat.ETC1S, BasisFormat.UASTC_4x4],
|
|
480
|
+
transcoderFormat: [TranscoderFormat.ETC1],
|
|
481
|
+
engineFormat: [EngineFormat.RGB_ETC1_Format],
|
|
482
|
+
priorityETC1S: 2,
|
|
483
|
+
priorityUASTC: 4,
|
|
484
|
+
needsPowerOfTwo: false,
|
|
485
|
+
},
|
|
486
|
+
{
|
|
487
|
+
if: 'pvrtcSupported',
|
|
488
|
+
basisFormat: [BasisFormat.ETC1S, BasisFormat.UASTC_4x4],
|
|
489
|
+
transcoderFormat: [TranscoderFormat.PVRTC1_4_RGB, TranscoderFormat.PVRTC1_4_RGBA],
|
|
490
|
+
engineFormat: [EngineFormat.RGB_PVRTC_4BPPV1_Format, EngineFormat.RGBA_PVRTC_4BPPV1_Format],
|
|
491
|
+
priorityETC1S: 5,
|
|
492
|
+
priorityUASTC: 6,
|
|
493
|
+
needsPowerOfTwo: true,
|
|
494
|
+
},
|
|
495
|
+
];
|
|
496
|
+
|
|
497
|
+
const ETC1S_OPTIONS = FORMAT_OPTIONS.sort(function (a, b) {
|
|
498
|
+
return a.priorityETC1S - b.priorityETC1S;
|
|
499
|
+
});
|
|
500
|
+
const UASTC_OPTIONS = FORMAT_OPTIONS.sort(function (a, b) {
|
|
501
|
+
return a.priorityUASTC - b.priorityUASTC;
|
|
502
|
+
});
|
|
503
|
+
|
|
504
|
+
function getTranscoderFormat(basisFormat, width, height, hasAlpha) {
|
|
505
|
+
let transcoderFormat;
|
|
506
|
+
let engineFormat;
|
|
507
|
+
|
|
508
|
+
const options = basisFormat === BasisFormat.ETC1S ? ETC1S_OPTIONS : UASTC_OPTIONS;
|
|
509
|
+
|
|
510
|
+
for (let i = 0; i < options.length; i++) {
|
|
511
|
+
const opt = options[i];
|
|
512
|
+
|
|
513
|
+
if (!config[opt.if]) continue;
|
|
514
|
+
if (!opt.basisFormat.includes(basisFormat)) continue;
|
|
515
|
+
if (hasAlpha && opt.transcoderFormat.length < 2) continue;
|
|
516
|
+
if (opt.needsPowerOfTwo && !(isPowerOfTwo(width) && isPowerOfTwo(height))) continue;
|
|
517
|
+
|
|
518
|
+
transcoderFormat = opt.transcoderFormat[hasAlpha ? 1 : 0];
|
|
519
|
+
engineFormat = opt.engineFormat[hasAlpha ? 1 : 0];
|
|
520
|
+
|
|
521
|
+
return { transcoderFormat, engineFormat };
|
|
522
|
+
}
|
|
523
|
+
|
|
524
|
+
console.warn('THREE.KTX2Loader: No suitable compressed texture format found. Decoding to RGBA32.');
|
|
525
|
+
|
|
526
|
+
transcoderFormat = TranscoderFormat.RGBA32;
|
|
527
|
+
engineFormat = EngineFormat.RGBAFormat;
|
|
528
|
+
|
|
529
|
+
return { transcoderFormat, engineFormat };
|
|
530
|
+
}
|
|
531
|
+
|
|
532
|
+
function isPowerOfTwo(value) {
|
|
533
|
+
if (value <= 2) return true;
|
|
534
|
+
|
|
535
|
+
return (value & (value - 1)) === 0 && value !== 0;
|
|
536
|
+
}
|
|
537
|
+
|
|
538
|
+
/** Concatenates N byte arrays. */
|
|
539
|
+
function concat(arrays) {
|
|
540
|
+
let totalByteLength = 0;
|
|
541
|
+
|
|
542
|
+
for (const array of arrays) {
|
|
543
|
+
totalByteLength += array.byteLength;
|
|
544
|
+
}
|
|
545
|
+
|
|
546
|
+
const result = new Uint8Array(totalByteLength);
|
|
547
|
+
|
|
548
|
+
let byteOffset = 0;
|
|
549
|
+
|
|
550
|
+
for (const array of arrays) {
|
|
551
|
+
result.set(array, byteOffset);
|
|
552
|
+
|
|
553
|
+
byteOffset += array.byteLength;
|
|
554
|
+
}
|
|
555
|
+
|
|
556
|
+
return result;
|
|
557
|
+
}
|
|
558
|
+
};
|
|
559
|
+
|
|
560
|
+
//
|
|
561
|
+
// DataTexture and Data3DTexture parsing.
|
|
562
|
+
|
|
563
|
+
const FORMAT_MAP = {
|
|
564
|
+
|
|
565
|
+
[VK_FORMAT_R32G32B32A32_SFLOAT]: RGBAFormat,
|
|
566
|
+
[VK_FORMAT_R16G16B16A16_SFLOAT]: RGBAFormat,
|
|
567
|
+
[VK_FORMAT_R8G8B8A8_UNORM]: RGBAFormat,
|
|
568
|
+
[VK_FORMAT_R8G8B8A8_SRGB]: RGBAFormat,
|
|
569
|
+
|
|
570
|
+
[VK_FORMAT_R32G32_SFLOAT]: RGFormat,
|
|
571
|
+
[VK_FORMAT_R16G16_SFLOAT]: RGFormat,
|
|
572
|
+
[VK_FORMAT_R8G8_UNORM]: RGFormat,
|
|
573
|
+
[VK_FORMAT_R8G8_SRGB]: RGFormat,
|
|
574
|
+
|
|
575
|
+
[VK_FORMAT_R32_SFLOAT]: RedFormat,
|
|
576
|
+
[VK_FORMAT_R16_SFLOAT]: RedFormat,
|
|
577
|
+
[VK_FORMAT_R8_SRGB]: RedFormat,
|
|
578
|
+
[VK_FORMAT_R8_UNORM]: RedFormat,
|
|
579
|
+
|
|
580
|
+
};
|
|
581
|
+
|
|
582
|
+
const TYPE_MAP = {
|
|
583
|
+
|
|
584
|
+
[VK_FORMAT_R32G32B32A32_SFLOAT]: FloatType,
|
|
585
|
+
[VK_FORMAT_R16G16B16A16_SFLOAT]: HalfFloatType,
|
|
586
|
+
[VK_FORMAT_R8G8B8A8_UNORM]: UnsignedByteType,
|
|
587
|
+
[VK_FORMAT_R8G8B8A8_SRGB]: UnsignedByteType,
|
|
588
|
+
|
|
589
|
+
[VK_FORMAT_R32G32_SFLOAT]: FloatType,
|
|
590
|
+
[VK_FORMAT_R16G16_SFLOAT]: HalfFloatType,
|
|
591
|
+
[VK_FORMAT_R8G8_UNORM]: UnsignedByteType,
|
|
592
|
+
[VK_FORMAT_R8G8_SRGB]: UnsignedByteType,
|
|
593
|
+
|
|
594
|
+
[VK_FORMAT_R32_SFLOAT]: FloatType,
|
|
595
|
+
[VK_FORMAT_R16_SFLOAT]: HalfFloatType,
|
|
596
|
+
[VK_FORMAT_R8_SRGB]: UnsignedByteType,
|
|
597
|
+
[VK_FORMAT_R8_UNORM]: UnsignedByteType,
|
|
598
|
+
|
|
599
|
+
};
|
|
600
|
+
|
|
601
|
+
const ENCODING_MAP = {
|
|
602
|
+
|
|
603
|
+
[VK_FORMAT_R8G8B8A8_SRGB]: sRGBEncoding,
|
|
604
|
+
[VK_FORMAT_R8G8_SRGB]: sRGBEncoding,
|
|
605
|
+
[VK_FORMAT_R8_SRGB]: sRGBEncoding,
|
|
606
|
+
|
|
607
|
+
};
|
|
608
|
+
|
|
609
|
+
async function createDataTexture(container) {
|
|
610
|
+
const { vkFormat, pixelWidth, pixelHeight, pixelDepth } = container;
|
|
611
|
+
|
|
612
|
+
if (FORMAT_MAP[vkFormat] === undefined) {
|
|
613
|
+
throw new Error('THREE.KTX2Loader: Unsupported vkFormat.');
|
|
614
|
+
}
|
|
615
|
+
|
|
616
|
+
const level = container.levels[0];
|
|
617
|
+
|
|
618
|
+
let levelData;
|
|
619
|
+
let view;
|
|
620
|
+
|
|
621
|
+
if (container.supercompressionScheme === KHR_SUPERCOMPRESSION_NONE) {
|
|
622
|
+
levelData = level.levelData;
|
|
623
|
+
}
|
|
624
|
+
else if (container.supercompressionScheme === KHR_SUPERCOMPRESSION_ZSTD) {
|
|
625
|
+
if (!_zstd) {
|
|
626
|
+
_zstd = new Promise(async (resolve) => {
|
|
627
|
+
const zstd = new ZSTDDecoder();
|
|
628
|
+
await zstd.init();
|
|
629
|
+
resolve(zstd);
|
|
630
|
+
});
|
|
631
|
+
}
|
|
632
|
+
|
|
633
|
+
levelData = (await _zstd).decode(level.levelData, level.uncompressedByteLength);
|
|
634
|
+
}
|
|
635
|
+
else {
|
|
636
|
+
throw new Error('THREE.KTX2Loader: Unsupported supercompressionScheme.');
|
|
637
|
+
}
|
|
638
|
+
|
|
639
|
+
if (TYPE_MAP[vkFormat] === FloatType) {
|
|
640
|
+
view = new Float32Array(
|
|
641
|
+
|
|
642
|
+
levelData.buffer,
|
|
643
|
+
levelData.byteOffset,
|
|
644
|
+
levelData.byteLength / Float32Array.BYTES_PER_ELEMENT,
|
|
645
|
+
|
|
646
|
+
);
|
|
647
|
+
}
|
|
648
|
+
else if (TYPE_MAP[vkFormat] === HalfFloatType) {
|
|
649
|
+
view = new Uint16Array(
|
|
650
|
+
|
|
651
|
+
levelData.buffer,
|
|
652
|
+
levelData.byteOffset,
|
|
653
|
+
levelData.byteLength / Uint16Array.BYTES_PER_ELEMENT,
|
|
654
|
+
|
|
655
|
+
);
|
|
656
|
+
}
|
|
657
|
+
else {
|
|
658
|
+
view = levelData;
|
|
659
|
+
}
|
|
660
|
+
//
|
|
661
|
+
|
|
662
|
+
const texture = pixelDepth === 0
|
|
663
|
+
? new DataTexture(view, pixelWidth, pixelHeight)
|
|
664
|
+
: new Data3DTexture(view, pixelWidth, pixelHeight, pixelDepth);
|
|
665
|
+
|
|
666
|
+
texture.type = TYPE_MAP[vkFormat];
|
|
667
|
+
texture.format = FORMAT_MAP[vkFormat];
|
|
668
|
+
texture.encoding = ENCODING_MAP[vkFormat] || LinearEncoding;
|
|
669
|
+
|
|
670
|
+
texture.needsUpdate = true;
|
|
671
|
+
|
|
672
|
+
//
|
|
673
|
+
|
|
674
|
+
return Promise.resolve(texture);
|
|
675
|
+
}
|
|
676
|
+
|
|
677
|
+
export { KTX2Loader };
|