@ludicon/spark.js 0.0.15 → 0.1.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/README.md +33 -11
- package/dist/spark.esm.js +996 -475
- package/dist/spark_astc_rgb-CTmg8wnA.js +4 -0
- package/dist/spark_astc_rgba-CDMNWH6H.js +4 -0
- package/dist/spark_bc1_rgb-C0pbbQPO.js +4 -0
- package/dist/spark_bc4_r-YQ6i79H9.js +4 -0
- package/dist/spark_bc5_rg-BqzKgeMU.js +4 -0
- package/dist/spark_bc7_rgb-DBkDHCzE.js +4 -0
- package/dist/spark_bc7_rgba-DQUk89UX.js +4 -0
- package/dist/spark_eac_r-Dvy2qUxf.js +4 -0
- package/dist/spark_eac_rg-DKLVL9co.js +4 -0
- package/dist/spark_etc2_rgb-BpnNweVx.js +4 -0
- package/dist/{utils-_0JXKkpk.js → utils-D_dYVlAC.js} +170 -17
- package/package.json +15 -5
- package/src/index.d.ts +301 -0
- package/src/three-gltf.d.ts +62 -0
- package/src/three-gltf.js +29 -14
package/dist/spark.esm.js
CHANGED
|
@@ -1,6 +1,53 @@
|
|
|
1
|
-
const
|
|
2
|
-
Object.entries(
|
|
3
|
-
)
|
|
1
|
+
const ge = /* @__PURE__ */ Object.assign({ "./spark_astc_rgb.wgsl": () => import("./spark_astc_rgb-DaSIMKXW.js"), "./spark_astc_rgba.wgsl": () => import("./spark_astc_rgba-BToA2Rcq.js"), "./spark_bc1_rgb.wgsl": () => import("./spark_bc1_rgb-DZwuM1tO.js"), "./spark_bc4_r.wgsl": () => import("./spark_bc4_r-DjThizCH.js"), "./spark_bc5_rg.wgsl": () => import("./spark_bc5_rg-6bO0Gvo9.js"), "./spark_bc7_rgb.wgsl": () => import("./spark_bc7_rgb-FXpBw9fE.js"), "./spark_bc7_rgba.wgsl": () => import("./spark_bc7_rgba-C8Hi2pUY.js"), "./spark_eac_r.wgsl": () => import("./spark_eac_r-D8HGiglc.js"), "./spark_eac_rg.wgsl": () => import("./spark_eac_rg-DvsrLP9h.js"), "./spark_etc2_rgb.wgsl": () => import("./spark_etc2_rgb-C-j5FZpn.js"), "./utils.wgsl": () => import("./utils-D_dYVlAC.js") }), Z = Object.fromEntries(
|
|
2
|
+
Object.entries(ge).map(([i, t]) => [i.replace("./", ""), async () => (await t()).default])
|
|
3
|
+
);
|
|
4
|
+
function O(i, t) {
|
|
5
|
+
if (!i)
|
|
6
|
+
throw new Error(t);
|
|
7
|
+
}
|
|
8
|
+
function he() {
|
|
9
|
+
const i = navigator.userAgent;
|
|
10
|
+
if (i.includes("Chrome") || i.includes("Chromium"))
|
|
11
|
+
return null;
|
|
12
|
+
const t = i.match(/Safari\/(\d+(\.\d+)?)/);
|
|
13
|
+
return t && parseFloat(t[1]);
|
|
14
|
+
}
|
|
15
|
+
function J() {
|
|
16
|
+
const i = navigator.userAgent.match(/Firefox\/(\d+(\.\d+)?)/);
|
|
17
|
+
return i && parseFloat(i[1]);
|
|
18
|
+
}
|
|
19
|
+
function pe(i) {
|
|
20
|
+
return /\.svg(?:$|\?)/i.test(i) || /^data:image\/svg\+xml[,;]/i.test(i);
|
|
21
|
+
}
|
|
22
|
+
function ee(i) {
|
|
23
|
+
return new Promise((t, r) => {
|
|
24
|
+
const e = new Image();
|
|
25
|
+
e.crossOrigin = "anonymous", e.decoding = "async", e.onload = () => t(e), e.onerror = r, e.src = i;
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
async function _e(i, t = {}) {
|
|
29
|
+
const r = await fetch(i, { mode: "cors" });
|
|
30
|
+
if (!r.ok) throw new Error(`HTTP ${r.status} for ${i}`);
|
|
31
|
+
const e = await r.blob();
|
|
32
|
+
return createImageBitmap(e, {
|
|
33
|
+
imageOrientation: t.flipY ? "flipY" : "none",
|
|
34
|
+
colorSpaceConversion: t.colorSpaceConversion ?? "none",
|
|
35
|
+
premultiplyAlpha: "none"
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
const j = he(), Te = 619.1, Ee = j && j < Te;
|
|
39
|
+
async function be(i) {
|
|
40
|
+
const t = document.createElement("canvas");
|
|
41
|
+
return t.width = i.naturalWidth || i.width, t.height = i.naturalHeight || i.height, t.getContext("2d").drawImage(i, 0, 0), createImageBitmap(t);
|
|
42
|
+
}
|
|
43
|
+
async function K(i, t = {}) {
|
|
44
|
+
const r = pe(i);
|
|
45
|
+
if (r && Ee) {
|
|
46
|
+
const e = await ee(i);
|
|
47
|
+
return be(e);
|
|
48
|
+
} else return r || j ? ee(i) : _e(i, t);
|
|
49
|
+
}
|
|
50
|
+
const a = {
|
|
4
51
|
ASTC_4x4_RGB: 0,
|
|
5
52
|
ASTC_4x4_RGBA: 1,
|
|
6
53
|
// ASTC_4x4_RGBM: 2,
|
|
@@ -19,7 +66,7 @@ const V = /* @__PURE__ */ Object.assign({ "./spark_astc_rgb.wgsl": () => import(
|
|
|
19
66
|
// BC6H_RGB: 15,
|
|
20
67
|
BC7_RGB: 16,
|
|
21
68
|
BC7_RGBA: 17
|
|
22
|
-
},
|
|
69
|
+
}, N = [
|
|
23
70
|
/* 0 */
|
|
24
71
|
"astc-4x4-rgb",
|
|
25
72
|
// ASTC_4x4_RGB
|
|
@@ -66,7 +113,7 @@ const V = /* @__PURE__ */ Object.assign({ "./spark_astc_rgb.wgsl": () => import(
|
|
|
66
113
|
/* 17 */
|
|
67
114
|
"bc7-rgba"
|
|
68
115
|
// BC7_RGBA
|
|
69
|
-
],
|
|
116
|
+
], Re = [
|
|
70
117
|
/* 0 */
|
|
71
118
|
"spark_astc_rgb.wgsl",
|
|
72
119
|
// ASTC_4x4_RGB
|
|
@@ -113,7 +160,7 @@ const V = /* @__PURE__ */ Object.assign({ "./spark_astc_rgb.wgsl": () => import(
|
|
|
113
160
|
/* 17 */
|
|
114
161
|
"spark_bc7_rgba.wgsl"
|
|
115
162
|
// BC7_RGBA
|
|
116
|
-
],
|
|
163
|
+
], Be = [
|
|
117
164
|
/* 0 */
|
|
118
165
|
16,
|
|
119
166
|
// ASTC_4x4_RGB
|
|
@@ -160,81 +207,39 @@ const V = /* @__PURE__ */ Object.assign({ "./spark_astc_rgb.wgsl": () => import(
|
|
|
160
207
|
/* 17 */
|
|
161
208
|
16
|
|
162
209
|
// BC7_RGB
|
|
163
|
-
],
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
// EAC_RG
|
|
180
|
-
/* 6 */
|
|
181
|
-
8,
|
|
182
|
-
// ETC2_RGB
|
|
183
|
-
/* 7 */
|
|
184
|
-
0,
|
|
185
|
-
/* 8 */
|
|
186
|
-
0,
|
|
187
|
-
/* 9 */
|
|
188
|
-
8,
|
|
189
|
-
// BC1_RGB
|
|
190
|
-
/* 10 */
|
|
191
|
-
0,
|
|
192
|
-
/* 11 */
|
|
193
|
-
0,
|
|
194
|
-
/* 12 */
|
|
195
|
-
0,
|
|
196
|
-
/* 13 */
|
|
197
|
-
2,
|
|
198
|
-
// BC4_R
|
|
199
|
-
/* 14 */
|
|
200
|
-
2,
|
|
201
|
-
// BC5_RG
|
|
202
|
-
/* 15 */
|
|
203
|
-
0,
|
|
204
|
-
/* 16 */
|
|
205
|
-
4,
|
|
206
|
-
// BC7_RGB
|
|
207
|
-
/* 17 */
|
|
208
|
-
4
|
|
209
|
-
// BC7_RGB
|
|
210
|
-
], P = Object.freeze({
|
|
211
|
-
"astc-4x4-rgb": i.ASTC_4x4_RGB,
|
|
212
|
-
"astc-4x4-rgba": i.ASTC_4x4_RGBA,
|
|
213
|
-
"eac-r": i.EAC_R,
|
|
214
|
-
"eac-rg": i.EAC_RG,
|
|
215
|
-
"etc2-rgb": i.ETC2_RGB,
|
|
216
|
-
"bc1-rgb": i.BC1_RGB,
|
|
217
|
-
"bc4-r": i.BC4_R,
|
|
218
|
-
"bc5-rg": i.BC5_RG,
|
|
219
|
-
"bc7-rgb": i.BC7_RGB,
|
|
220
|
-
"bc7-rgba": i.BC7_RGBA,
|
|
210
|
+
], A = {
|
|
211
|
+
Linear: 0,
|
|
212
|
+
sRGB: 1,
|
|
213
|
+
Alpha: 2,
|
|
214
|
+
Normal: 4
|
|
215
|
+
}, z = Object.freeze({
|
|
216
|
+
"astc-4x4-rgb": a.ASTC_4x4_RGB,
|
|
217
|
+
"astc-4x4-rgba": a.ASTC_4x4_RGBA,
|
|
218
|
+
"eac-r": a.EAC_R,
|
|
219
|
+
"eac-rg": a.EAC_RG,
|
|
220
|
+
"etc2-rgb": a.ETC2_RGB,
|
|
221
|
+
"bc1-rgb": a.BC1_RGB,
|
|
222
|
+
"bc4-r": a.BC4_R,
|
|
223
|
+
"bc5-rg": a.BC5_RG,
|
|
224
|
+
"bc7-rgb": a.BC7_RGB,
|
|
225
|
+
"bc7-rgba": a.BC7_RGBA,
|
|
221
226
|
// aliases:
|
|
222
|
-
"astc-rgb":
|
|
223
|
-
"astc-rgba":
|
|
227
|
+
"astc-rgb": a.ASTC_4x4_RGB,
|
|
228
|
+
"astc-rgba": a.ASTC_4x4_RGBA,
|
|
224
229
|
// webgpu aliases:
|
|
225
|
-
"bc1-rgba-unorm":
|
|
226
|
-
"bc1-rgba-unorm-srgb":
|
|
227
|
-
"bc4-r-unorm":
|
|
228
|
-
"bc5-rg-unorm":
|
|
229
|
-
"bc7-rgba-unorm":
|
|
230
|
-
"bc7-rgba-unorm-srgb":
|
|
231
|
-
"etc2-rgb8unorm":
|
|
232
|
-
"etc2-rgb8unorm-srgb":
|
|
233
|
-
"eac-r11unorm":
|
|
234
|
-
"eac-rg11unorm":
|
|
235
|
-
"astc-4x4-unorm":
|
|
236
|
-
"astc-4x4-unorm-srgb":
|
|
237
|
-
}),
|
|
230
|
+
"bc1-rgba-unorm": a.BC1_RGB,
|
|
231
|
+
"bc1-rgba-unorm-srgb": a.BC1_RGB,
|
|
232
|
+
"bc4-r-unorm": a.BC4_R,
|
|
233
|
+
"bc5-rg-unorm": a.BC5_RG,
|
|
234
|
+
"bc7-rgba-unorm": a.BC7_RGBA,
|
|
235
|
+
"bc7-rgba-unorm-srgb": a.BC7_RGBA,
|
|
236
|
+
"etc2-rgb8unorm": a.ETC2_RGB,
|
|
237
|
+
"etc2-rgb8unorm-srgb": a.ETC2_RGB,
|
|
238
|
+
"eac-r11unorm": a.EAC_R,
|
|
239
|
+
"eac-rg11unorm": a.EAC_RG,
|
|
240
|
+
"astc-4x4-unorm": a.ASTC_4x4_RGBA,
|
|
241
|
+
"astc-4x4-unorm-srgb": a.ASTC_4x4_RGBA
|
|
242
|
+
}), xe = [
|
|
238
243
|
/* 0 */
|
|
239
244
|
"astc-4x4-unorm",
|
|
240
245
|
// ASTC_4x4_RGB
|
|
@@ -281,7 +286,7 @@ const V = /* @__PURE__ */ Object.assign({ "./spark_astc_rgb.wgsl": () => import(
|
|
|
281
286
|
/* 17 */
|
|
282
287
|
"bc7-rgba-unorm"
|
|
283
288
|
// BC7_RGB
|
|
284
|
-
],
|
|
289
|
+
], Ge = [
|
|
285
290
|
/* 0 */
|
|
286
291
|
!0,
|
|
287
292
|
// ASTC_4x4_RGB
|
|
@@ -329,113 +334,113 @@ const V = /* @__PURE__ */ Object.assign({ "./spark_astc_rgb.wgsl": () => import(
|
|
|
329
334
|
!0
|
|
330
335
|
// BC7_RGB
|
|
331
336
|
];
|
|
332
|
-
function
|
|
333
|
-
|
|
334
|
-
|
|
337
|
+
function Ce(i) {
|
|
338
|
+
return Ge[i];
|
|
339
|
+
}
|
|
340
|
+
function Se(i) {
|
|
341
|
+
return i == a.ASTC_4x4_RGBA || i == a.BC7_RGBA;
|
|
335
342
|
}
|
|
336
|
-
function
|
|
337
|
-
return typeof GPUDevice < "u" &&
|
|
343
|
+
function Pe(i) {
|
|
344
|
+
return typeof GPUDevice < "u" && i instanceof GPUDevice;
|
|
338
345
|
}
|
|
339
|
-
function
|
|
346
|
+
function Ae() {
|
|
340
347
|
return ["iPad Simulator", "iPhone Simulator", "iPod Simulator", "iPad", "iPhone", "iPod"].includes(navigator.platform) || // iPad on iOS 13 detection
|
|
341
348
|
navigator.userAgent.includes("Mac") && "ontouchend" in document;
|
|
342
349
|
}
|
|
343
|
-
function
|
|
344
|
-
const
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
return e && parseFloat(e[1]);
|
|
349
|
-
}
|
|
350
|
-
function k() {
|
|
351
|
-
const u = navigator.userAgent.match(/Firefox\/(\d+(\.\d+)?)/);
|
|
352
|
-
return u && parseFloat(u[1]);
|
|
353
|
-
}
|
|
354
|
-
function Q(u) {
|
|
355
|
-
const e = /* @__PURE__ */ new Set(), r = {
|
|
356
|
-
"texture-compression-bc": [
|
|
357
|
-
i.BC1_RGB,
|
|
358
|
-
i.BC4_R,
|
|
359
|
-
i.BC5_RG,
|
|
360
|
-
i.BC7_RGB,
|
|
361
|
-
i.BC7_RGBA
|
|
362
|
-
],
|
|
363
|
-
"texture-compression-etc2": [i.ETC2_RGB, i.EAC_R, i.EAC_RG],
|
|
364
|
-
"texture-compression-astc": [i.ASTC_4x4_RGB, i.ASTC_4x4_RGBA]
|
|
350
|
+
function Ue(i) {
|
|
351
|
+
const t = /* @__PURE__ */ new Set(), r = {
|
|
352
|
+
"texture-compression-bc": [a.BC1_RG, a.BC4_R, a.BC5_RG, a.BC7_RGB, a.BC7_RGBA],
|
|
353
|
+
"texture-compression-etc2": [a.ETC2_RGB, a.EAC_R, a.EAC_RG],
|
|
354
|
+
"texture-compression-astc": [a.ASTC_4x4_RGB, a.ASTC_4x4_RGBA]
|
|
365
355
|
};
|
|
366
|
-
for (const [
|
|
367
|
-
if (
|
|
368
|
-
for (const
|
|
369
|
-
|
|
370
|
-
return
|
|
356
|
+
for (const [e, s] of Object.entries(r))
|
|
357
|
+
if (i.features.has(e))
|
|
358
|
+
for (const o of s)
|
|
359
|
+
t.add(o);
|
|
360
|
+
return t;
|
|
371
361
|
}
|
|
372
|
-
function
|
|
373
|
-
const
|
|
374
|
-
|
|
375
|
-
const r =
|
|
376
|
-
r.drawImage(
|
|
377
|
-
const
|
|
378
|
-
return new Uint8Array(
|
|
362
|
+
function we(i) {
|
|
363
|
+
const t = document.createElement("canvas");
|
|
364
|
+
t.width = i.width, t.height = i.height;
|
|
365
|
+
const r = t.getContext("2d");
|
|
366
|
+
r.drawImage(i, 0, 0);
|
|
367
|
+
const e = r.getImageData(0, 0, i.width, i.height);
|
|
368
|
+
return new Uint8Array(e.data.buffer);
|
|
379
369
|
}
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
return new Promise((e, r) => {
|
|
385
|
-
const t = new Image();
|
|
386
|
-
t.crossOrigin = "anonymous", t.decoding = "async", t.onload = () => e(t), t.onerror = r, t.src = u;
|
|
387
|
-
});
|
|
388
|
-
}
|
|
389
|
-
async function ee(u, e = {}) {
|
|
390
|
-
const r = await fetch(u, { mode: "cors" });
|
|
391
|
-
if (!r.ok) throw new Error(`HTTP ${r.status} for ${u}`);
|
|
392
|
-
const t = await r.blob();
|
|
393
|
-
return createImageBitmap(t, {
|
|
394
|
-
imageOrientation: e.flipY ? "flipY" : "none",
|
|
395
|
-
colorSpaceConversion: e.colorSpaceConversion ?? "none",
|
|
396
|
-
premultiplyAlpha: "none"
|
|
397
|
-
});
|
|
398
|
-
}
|
|
399
|
-
const te = O();
|
|
400
|
-
function N(u) {
|
|
401
|
-
return J(u) || te ? K(u) : ee(u);
|
|
402
|
-
}
|
|
403
|
-
const L = 256, F = 4;
|
|
404
|
-
function re(u, e, r, t) {
|
|
405
|
-
let s = 0, n = 0;
|
|
406
|
-
const a = [];
|
|
370
|
+
const te = 256, re = 4;
|
|
371
|
+
function ye(i, t, r, e) {
|
|
372
|
+
let s = 0, o = 0;
|
|
373
|
+
const c = [];
|
|
407
374
|
do {
|
|
408
|
-
const
|
|
409
|
-
s++,
|
|
410
|
-
} while (
|
|
411
|
-
return { mipmapCount: s, outputSize:
|
|
375
|
+
const n = Math.ceil(i / 4), f = Math.ceil(t / 4), u = Math.ceil(n * r / te) * te, l = f * u;
|
|
376
|
+
s++, c.push({ offset: o, alignedSize: l, w: i, h: t, bw: n, bh: f, bytesPerRow: u }), o += l, i = Math.max(1, Math.floor(i / 2)), t = Math.max(1, Math.floor(t / 2));
|
|
377
|
+
} while (e && (i >= re || t >= re));
|
|
378
|
+
return { mipmapCount: s, outputSize: o, bufferRanges: c };
|
|
412
379
|
}
|
|
413
|
-
class
|
|
380
|
+
class me {
|
|
414
381
|
#e;
|
|
415
|
-
#
|
|
416
|
-
#
|
|
382
|
+
#l;
|
|
383
|
+
#T;
|
|
384
|
+
#h = !1;
|
|
385
|
+
#f = [];
|
|
417
386
|
#g;
|
|
418
|
-
#
|
|
387
|
+
#d;
|
|
388
|
+
#p;
|
|
389
|
+
#a;
|
|
390
|
+
#E;
|
|
419
391
|
#s;
|
|
420
|
-
#o;
|
|
421
|
-
#u;
|
|
422
|
-
#m;
|
|
423
392
|
#i;
|
|
424
|
-
#n
|
|
425
|
-
#
|
|
426
|
-
#
|
|
427
|
-
#
|
|
428
|
-
#
|
|
393
|
+
#n;
|
|
394
|
+
#_;
|
|
395
|
+
#u;
|
|
396
|
+
#t = !1;
|
|
397
|
+
#o = null;
|
|
398
|
+
#c = null;
|
|
399
|
+
#m = null;
|
|
400
|
+
#B = 0;
|
|
401
|
+
#b = !1;
|
|
429
402
|
/**
|
|
430
403
|
* Initialize the encoder by detecting available compression formats.
|
|
431
404
|
* @param {GPUDevice} device - WebGPU device.
|
|
432
405
|
* @param {Object} options - Encoder options.
|
|
433
406
|
* @param {boolean} options.preload - Whether to preload all encoder pipelines (false by default).
|
|
407
|
+
* @param {boolean} options.cacheTempResources - Whether to cache temporary resources for reuse across encodeTexture calls (false by default).
|
|
408
|
+
* @param {boolean} options.verbose - Whether to enable verbose logging (false by default).
|
|
434
409
|
* @returns {Promise<void>} Resolves when initialization is complete.
|
|
435
410
|
*/
|
|
436
|
-
static async create(
|
|
437
|
-
const
|
|
438
|
-
return await
|
|
411
|
+
static async create(t, r = {}) {
|
|
412
|
+
const e = new me();
|
|
413
|
+
return await e.#w(
|
|
414
|
+
t,
|
|
415
|
+
r.preload ?? !1,
|
|
416
|
+
r.useTimestampQueries ?? !1,
|
|
417
|
+
r.verbose ?? !1,
|
|
418
|
+
r.cacheTempResources ?? !1
|
|
419
|
+
), e;
|
|
420
|
+
}
|
|
421
|
+
dispose() {
|
|
422
|
+
for (const t of this.#f)
|
|
423
|
+
t.destroy();
|
|
424
|
+
this.#g.destroy(), this.#p.destroy(), this.#a.destroy(), this.#E.destroy(), this.#s.destroy();
|
|
425
|
+
for (let t = 0; t < 3; t++)
|
|
426
|
+
this.#i[t].destroy();
|
|
427
|
+
this.#n.destroy(), this.#_.destroy(), this.#u.destroy(), this.freeTempResources();
|
|
428
|
+
}
|
|
429
|
+
#x(...t) {
|
|
430
|
+
this.#b && console.log(...t);
|
|
431
|
+
}
|
|
432
|
+
#G(t) {
|
|
433
|
+
this.#b && console.time(t);
|
|
434
|
+
}
|
|
435
|
+
#C(t) {
|
|
436
|
+
this.#b && console.timeEnd(t);
|
|
437
|
+
}
|
|
438
|
+
/**
|
|
439
|
+
* Free cached temporary resources used by encodeTexture.
|
|
440
|
+
* Call this when you're done encoding textures to free up GPU memory.
|
|
441
|
+
*/
|
|
442
|
+
freeTempResources() {
|
|
443
|
+
this.#o && (this.#o.destroy(), this.#o = null), this.#c && (this.#c.destroy(), this.#c = null), this.#m && (this.#m.destroy(), this.#m = null);
|
|
439
444
|
}
|
|
440
445
|
/**
|
|
441
446
|
* Returns a list of supported texture compression format names.
|
|
@@ -444,34 +449,25 @@ class D {
|
|
|
444
449
|
* (ASTC, ETC2, EAC, BCn) and filters it based on the formats actually supported
|
|
445
450
|
* by the current device as determined by `Spark.supportedFormats`.
|
|
446
451
|
*
|
|
447
|
-
* @returns {string[]} An array of format names (e.g., "bc1-rgb", "astc-4x4-rgba") that are supported on the current
|
|
452
|
+
* @returns {string[]} An array of format names (e.g., "bc1-rgb", "astc-4x4-rgba") that are supported on the current device.
|
|
448
453
|
*
|
|
449
454
|
* @example
|
|
450
455
|
* const spark = await Spark.create(device);
|
|
451
|
-
* const formats = spark.
|
|
456
|
+
* const formats = spark.getSupportedFormats();
|
|
452
457
|
* console.log("Supported formats:", formats);
|
|
453
458
|
*/
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
], r = [];
|
|
467
|
-
for (const t of e) {
|
|
468
|
-
const s = P[t];
|
|
469
|
-
if (this.#t(s)) {
|
|
470
|
-
const n = Y[s];
|
|
471
|
-
r.push({ format: t, ratio: n });
|
|
472
|
-
}
|
|
473
|
-
}
|
|
474
|
-
return r;
|
|
459
|
+
getSupportedFormats() {
|
|
460
|
+
return Array.from(this.#l).map((t) => N[t]).filter(Boolean);
|
|
461
|
+
}
|
|
462
|
+
/**
|
|
463
|
+
* Returns whether the given format is supported on the current device.
|
|
464
|
+
*
|
|
465
|
+
* @param {string} format
|
|
466
|
+
* @returns {boolean} `true` if the format is supported, `false` otherwise.
|
|
467
|
+
*/
|
|
468
|
+
isFormatSupported(t) {
|
|
469
|
+
const r = typeof t == "string" ? z[t] : t;
|
|
470
|
+
return this.#l.has(r);
|
|
475
471
|
}
|
|
476
472
|
/**
|
|
477
473
|
* Determines the set of WebGPU features to request when initializing the device.
|
|
@@ -491,9 +487,9 @@ class D {
|
|
|
491
487
|
* // Create spark object for the given device.
|
|
492
488
|
* const spark = Spark.create(device)
|
|
493
489
|
*/
|
|
494
|
-
static getRequiredFeatures(
|
|
490
|
+
static getRequiredFeatures(t) {
|
|
495
491
|
const r = [];
|
|
496
|
-
return !
|
|
492
|
+
return !Ae() && t.features.has("texture-compression-bc") && r.push("texture-compression-bc"), t.features.has("texture-compression-etc2") && r.push("texture-compression-etc2"), t.features.has("texture-compression-astc") && r.push("texture-compression-astc"), t.features.has("shader-f16") && r.push("shader-f16"), t.features.has("timestamp-query") && r.push("timestamp-query"), r;
|
|
497
493
|
}
|
|
498
494
|
/**
|
|
499
495
|
* Try to determine the best compression options automatically. Do not use this in production, this is
|
|
@@ -503,12 +499,12 @@ class D {
|
|
|
503
499
|
* @param {Object} options - Encoding options.
|
|
504
500
|
* @returns {Object} - Recommended encoding options with an explicit encoding format.
|
|
505
501
|
*/
|
|
506
|
-
async selectPreferredOptions(
|
|
502
|
+
async selectPreferredOptions(t, r = {}) {
|
|
507
503
|
if (r.format == null || r.format == "auto") {
|
|
508
|
-
const
|
|
504
|
+
const e = t instanceof Image || t instanceof ImageBitmap || t instanceof GPUTexture ? t : await K(t);
|
|
509
505
|
r.format = "auto";
|
|
510
|
-
const s = await this.#
|
|
511
|
-
r.format =
|
|
506
|
+
const s = await this.#A(r, e);
|
|
507
|
+
r.format = N[s], e instanceof GPUTexture && e.format.endsWith("-srgb") && (r.srgb = !0), (s == a.EAC_RG || s == a.BC5_RG) && (r.normal = !0);
|
|
512
508
|
}
|
|
513
509
|
return r;
|
|
514
510
|
}
|
|
@@ -530,13 +526,18 @@ class D {
|
|
|
530
526
|
* - "auto" to analyze the input texture and detect the required channels.
|
|
531
527
|
* This has some overhead, so specifying a format explicitly is preferred.
|
|
532
528
|
*
|
|
533
|
-
* @param {boolean} [options.alpha]
|
|
534
|
-
* Hint for the automatic format selector. When no explicit format is provided,
|
|
535
|
-
* the format is assumed to be "rgb". Supplying `alpha: true` will favor RGBA formats.
|
|
536
|
-
*
|
|
537
529
|
* @param {boolean} [options.mips=false] | [options.generateMipmaps=false]
|
|
538
|
-
* Whether to generate mipmaps.
|
|
539
|
-
*
|
|
530
|
+
* Whether to generate mipmaps.
|
|
531
|
+
*
|
|
532
|
+
* @param {string} [options.mipmapFilter="magic"]
|
|
533
|
+
* The filter to use for mipmap generation. Can be "box" for a simple box filter,
|
|
534
|
+
* or "magic" for a higher-quality 4-tap filter with sharpening properties.
|
|
535
|
+
*
|
|
536
|
+
* @param {number[]} [options.mipsAlphaScale]
|
|
537
|
+
* Optional array of alpha scale values to apply to each generated mipmap level.
|
|
538
|
+
* The array should contain one value per mipmap level (starting with mip level 1,
|
|
539
|
+
* since level 0 is the base image). Each value multiplies the alpha channel of
|
|
540
|
+
* the corresponding mipmap level.
|
|
540
541
|
*
|
|
541
542
|
* @param {boolean} [options.srgb=false]
|
|
542
543
|
* Whether to encode the image in an sRGB format. Also affects mipmap generation.
|
|
@@ -551,97 +552,111 @@ class D {
|
|
|
551
552
|
*
|
|
552
553
|
* @returns {Promise<GPUTexture>} A promise resolving to the encoded GPU texture.
|
|
553
554
|
*/
|
|
554
|
-
async encodeTexture(
|
|
555
|
-
|
|
556
|
-
const
|
|
557
|
-
|
|
558
|
-
const s = await this.#
|
|
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
|
-
|
|
555
|
+
async encodeTexture(t, r = {}) {
|
|
556
|
+
O(this.#e, "Spark is not initialized");
|
|
557
|
+
const e = t instanceof Image || t instanceof ImageBitmap || t instanceof GPUTexture ? t : await K(t);
|
|
558
|
+
this.#x("Loaded image", e);
|
|
559
|
+
const s = await this.#A(r, e), o = this.#S(s), c = Math.ceil(e.width / 4) * 4, n = Math.ceil(e.height / 4) * 4, f = Be[s], u = r.generateMipmaps || r.mips, { mipmapCount: l, outputSize: h, bufferRanges: m } = ye(c, n, f, u), R = (r.srgb || r.format?.endsWith("srgb")) && Ce(s);
|
|
560
|
+
let T = R ? A.sRGB : A.Linear;
|
|
561
|
+
Se(s) && (T |= A.Alpha), r.normal && (T = A.Normal);
|
|
562
|
+
const d = xe[s] + (R ? "-srgb" : ""), V = R ? ["rgba8unorm", "rgba8unorm-srgb"] : ["rgba8unorm"], x = this.#B++;
|
|
563
|
+
this.#G("create input texture #" + x);
|
|
564
|
+
let y = GPUTextureUsage.TEXTURE_BINDING | GPUTextureUsage.COPY_DST;
|
|
565
|
+
this.#h ? y |= GPUTextureUsage.RENDER_ATTACHMENT : y |= GPUTextureUsage.STORAGE_BINDING;
|
|
566
|
+
const S = r.flipY || c != e.width || n != e.height;
|
|
567
|
+
!S && !(e instanceof GPUTexture) && (y |= GPUTextureUsage.RENDER_ATTACHMENT);
|
|
568
|
+
const _ = this.#e.createCommandEncoder();
|
|
569
|
+
_.pushDebugGroup?.("spark process texture"), this.#n && typeof _.writeTimestamp == "function" && _.writeTimestamp(this.#n, 0);
|
|
570
|
+
let E;
|
|
571
|
+
if (S || !(e instanceof GPUTexture && !u)) {
|
|
572
|
+
const g = !this.#t || !this.#o || this.#o.width < c || this.#o.height < n || this.#o.mipLevelCount < l;
|
|
573
|
+
this.#t && this.#o && !g ? E = this.#o : (this.#t && this.#o && this.#o.destroy(), E = this.#e.createTexture({
|
|
574
|
+
size: [c, n, 1],
|
|
575
|
+
mipLevelCount: l,
|
|
576
|
+
format: "rgba8unorm",
|
|
577
|
+
usage: y,
|
|
578
|
+
viewFormats: V
|
|
579
|
+
}), this.#t && (this.#o = E));
|
|
580
|
+
}
|
|
581
|
+
let P;
|
|
582
|
+
if (S)
|
|
583
|
+
if (e instanceof GPUTexture)
|
|
584
|
+
this.#U(_, e, E, c, n, R, r.flipY);
|
|
585
|
+
else {
|
|
586
|
+
const g = !this.#t || !this.#c || this.#c.width < e.width || this.#c.height < e.height;
|
|
587
|
+
this.#t && this.#c && !g ? P = this.#c : (this.#t && this.#c && this.#c.destroy(), P = this.#e.createTexture({
|
|
588
|
+
size: [e.width, e.height, 1],
|
|
589
|
+
mipLevelCount: 1,
|
|
590
|
+
format: "rgba8unorm",
|
|
591
|
+
// RENDER_ATTACHMENT usage is necessary for copyExternalImageToTexture
|
|
592
|
+
usage: GPUTextureUsage.TEXTURE_BINDING | GPUTextureUsage.COPY_DST | GPUTextureUsage.RENDER_ATTACHMENT,
|
|
593
|
+
viewFormats: V
|
|
594
|
+
}), this.#t && (this.#c = P)), this.#e.queue.copyExternalImageToTexture({ source: e }, { texture: P }, { width: e.width, height: e.height }), this.#U(_, P, E, c, n, T, r.flipY);
|
|
595
|
+
}
|
|
596
|
+
else
|
|
597
|
+
e instanceof GPUTexture ? u ? _.copyTextureToTexture({ texture: e }, { texture: E }, { width: c, height: n }) : E = e : this.#e.queue.copyExternalImageToTexture({ source: e }, { texture: E }, { width: c, height: n });
|
|
598
|
+
u && this.#L(_, E, l, c, n, T, r.mipsAlphaScale, r.mipmapFilter), _.popDebugGroup?.(), this.#C("create input texture #" + x);
|
|
599
|
+
const W = r.outputTexture && r.outputTexture.width == c && r.outputTexture.height == n && r.outputTexture.mipLevelCount == l && r.outputTexture.format == d ? r.outputTexture : this.#e.createTexture({
|
|
600
|
+
size: [c, n, 1],
|
|
601
|
+
mipLevelCount: l,
|
|
602
|
+
format: d,
|
|
591
603
|
usage: GPUTextureUsage.TEXTURE_BINDING | GPUTextureUsage.COPY_DST
|
|
592
|
-
})
|
|
604
|
+
});
|
|
605
|
+
let C;
|
|
606
|
+
this.#t && this.#m && this.#m.size >= h ? C = this.#m : (this.#t && this.#m && this.#m.destroy(), C = this.#e.createBuffer({
|
|
593
607
|
size: h,
|
|
594
608
|
usage: GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_SRC
|
|
595
|
-
}),
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
609
|
+
}), this.#t && (this.#m = C));
|
|
610
|
+
const k = `dispatch compute shader '${N[s]}' #${x}`;
|
|
611
|
+
this.#G(k), _.pushDebugGroup?.("spark encode texture");
|
|
612
|
+
let b = {};
|
|
613
|
+
this.#n && typeof _.writeTimestamp != "function" && (b = {
|
|
599
614
|
writeTimestamps: {
|
|
600
|
-
querySet: this.#
|
|
615
|
+
querySet: this.#n,
|
|
601
616
|
beginningOfPassWriteIndex: 0,
|
|
602
617
|
endOfPassWriteIndex: 1
|
|
603
618
|
}
|
|
604
619
|
});
|
|
605
|
-
const
|
|
606
|
-
|
|
607
|
-
for (let g = 0; g <
|
|
608
|
-
const
|
|
609
|
-
layout:
|
|
620
|
+
const U = await o, B = _.beginComputePass(b);
|
|
621
|
+
B.setPipeline(U);
|
|
622
|
+
for (let g = 0; g < l; g++) {
|
|
623
|
+
const L = this.#e.createBindGroup({
|
|
624
|
+
layout: U.getBindGroupLayout(0),
|
|
610
625
|
entries: [
|
|
611
626
|
{
|
|
612
627
|
binding: 0,
|
|
613
|
-
resource:
|
|
628
|
+
resource: E.createView({
|
|
614
629
|
baseMipLevel: g,
|
|
615
630
|
mipLevelCount: 1
|
|
616
631
|
})
|
|
617
632
|
},
|
|
618
633
|
{
|
|
619
634
|
binding: 1,
|
|
620
|
-
resource: this.#
|
|
635
|
+
resource: this.#s
|
|
621
636
|
},
|
|
622
637
|
{
|
|
623
638
|
binding: 2,
|
|
624
639
|
resource: {
|
|
625
|
-
buffer:
|
|
640
|
+
buffer: C,
|
|
626
641
|
offset: m[g].offset,
|
|
627
642
|
size: m[g].size
|
|
628
643
|
}
|
|
629
644
|
}
|
|
630
645
|
]
|
|
631
646
|
});
|
|
632
|
-
|
|
647
|
+
B.setBindGroup(0, L), B.dispatchWorkgroups(Math.ceil(m[g].bw / 16), Math.ceil(m[g].bh / 16));
|
|
633
648
|
}
|
|
634
|
-
|
|
635
|
-
for (let g = 0; g <
|
|
636
|
-
|
|
649
|
+
B.end();
|
|
650
|
+
for (let g = 0; g < l; g++)
|
|
651
|
+
_.copyBufferToTexture(
|
|
637
652
|
{
|
|
638
|
-
buffer:
|
|
653
|
+
buffer: C,
|
|
639
654
|
offset: m[g].offset,
|
|
640
655
|
bytesPerRow: m[g].bytesPerRow,
|
|
641
656
|
rowsPerImage: m[g].bh
|
|
642
657
|
},
|
|
643
658
|
{
|
|
644
|
-
texture:
|
|
659
|
+
texture: W,
|
|
645
660
|
mipLevel: g
|
|
646
661
|
},
|
|
647
662
|
{
|
|
@@ -650,7 +665,7 @@ class D {
|
|
|
650
665
|
depthOrArrayLayers: 1
|
|
651
666
|
}
|
|
652
667
|
);
|
|
653
|
-
return this.#
|
|
668
|
+
return this.#n && typeof _.writeTimestamp == "function" && _.writeTimestamp(this.#n, 1), _.popDebugGroup?.(), this.#e.queue.submit([_.finish()]), this.#C(k), this.#t || (P?.destroy(), E != e && E?.destroy(), C?.destroy()), W;
|
|
654
669
|
}
|
|
655
670
|
/**
|
|
656
671
|
* Returns the time (in milliseconds) it took to perform the most recent `encodeTexture()` call.
|
|
@@ -672,74 +687,71 @@ class D {
|
|
|
672
687
|
* @throws {Error} If the GPU work has not been submitted, or if timestamp queries fail.
|
|
673
688
|
*/
|
|
674
689
|
async getTimeElapsed() {
|
|
675
|
-
if (!this.#
|
|
690
|
+
if (!this.#n)
|
|
676
691
|
return 0;
|
|
677
|
-
const
|
|
678
|
-
|
|
679
|
-
const r = this.#
|
|
680
|
-
return this.#
|
|
692
|
+
const t = this.#e.createCommandEncoder();
|
|
693
|
+
t.resolveQuerySet(this.#n, 0, 2, this.#_, 0), t.copyBufferToBuffer(this.#_, 0, this.#u, 0, 16), this.#e.queue.submit([t.finish()]), await this.#e.queue.onSubmittedWorkDone(), await this.#u.mapAsync(GPUMapMode.READ);
|
|
694
|
+
const r = this.#u.getMappedRange(), e = new BigUint64Array(r), s = e[0], o = e[1];
|
|
695
|
+
return this.#u.unmap(), Number(o - s) / 1e6;
|
|
681
696
|
}
|
|
682
|
-
async #
|
|
683
|
-
|
|
697
|
+
async #w(t, r, e, s, o) {
|
|
698
|
+
if (O(t, "device is required"), O(Pe(t), "device is not a WebGPU device"), this.#e = t, this.#b = s, this.#t = o, this.#l = Ue(this.#e), this.#s = this.#e.createSampler({
|
|
684
699
|
magFilter: "linear",
|
|
685
700
|
minFilter: "linear"
|
|
686
|
-
})
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
if (t && this.#e.features.has("timestamp-query")) {
|
|
693
|
-
const s = O(), n = k();
|
|
694
|
-
(!s || s >= 26) && !n && (this.#r = this.#e.createQuerySet({
|
|
701
|
+
}), this.#i = this.#e.createBuffer({
|
|
702
|
+
size: 16,
|
|
703
|
+
usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST
|
|
704
|
+
}), e && this.#e.features.has("timestamp-query")) {
|
|
705
|
+
const c = he(), n = J();
|
|
706
|
+
(!c || c >= 26) && !n && (this.#n = this.#e.createQuerySet({
|
|
695
707
|
type: "timestamp",
|
|
696
708
|
count: 2
|
|
697
|
-
}), this.#
|
|
709
|
+
}), this.#_ = this.#e.createBuffer({
|
|
698
710
|
size: 16,
|
|
699
711
|
// 2 timestamps × 8 bytes each
|
|
700
712
|
usage: GPUBufferUsage.COPY_SRC | GPUBufferUsage.QUERY_RESOLVE
|
|
701
|
-
}), this.#
|
|
713
|
+
}), this.#u = this.#e.createBuffer({
|
|
702
714
|
size: 16,
|
|
703
715
|
// 2 timestamps × 8 bytes each
|
|
704
716
|
usage: GPUBufferUsage.COPY_DST | GPUBufferUsage.MAP_READ
|
|
705
717
|
}));
|
|
706
718
|
}
|
|
707
|
-
if (this.#
|
|
708
|
-
let
|
|
709
|
-
Array.isArray(r) ?
|
|
710
|
-
for (const n of
|
|
711
|
-
n !== void 0 && !this.#
|
|
712
|
-
console.error(`Failed to preload pipeline for format ${n}:`,
|
|
719
|
+
if (this.#T = this.#e.features.has("shader-f16"), await this.#y(), r) {
|
|
720
|
+
let c;
|
|
721
|
+
Array.isArray(r) ? c = r.map((n) => this.#P(n, !1)) : c = this.#l;
|
|
722
|
+
for (const n of c)
|
|
723
|
+
n !== void 0 && !this.#f[n] && this.#S(n).catch((f) => {
|
|
724
|
+
console.error(`Failed to preload pipeline for format ${n}:`, f);
|
|
713
725
|
});
|
|
714
726
|
}
|
|
715
727
|
}
|
|
716
|
-
async #
|
|
717
|
-
const
|
|
718
|
-
code: await
|
|
728
|
+
async #y() {
|
|
729
|
+
const t = this.#e.createShaderModule({
|
|
730
|
+
code: await Z["utils.wgsl"](),
|
|
719
731
|
label: "utils"
|
|
720
732
|
});
|
|
721
|
-
if (typeof
|
|
722
|
-
const
|
|
723
|
-
if (
|
|
733
|
+
if (typeof t.compilationInfo == "function") {
|
|
734
|
+
const e = await t.compilationInfo();
|
|
735
|
+
if (e.messages.some((s) => s.type == "error")) {
|
|
724
736
|
console.error("WGSL compilation errors:");
|
|
725
|
-
for (const s of
|
|
737
|
+
for (const s of e.messages)
|
|
726
738
|
console.error(s);
|
|
727
739
|
throw new Error("Shader compilation failed");
|
|
728
740
|
}
|
|
729
741
|
}
|
|
730
|
-
if (
|
|
731
|
-
this.#
|
|
732
|
-
const
|
|
733
|
-
for (const s of
|
|
734
|
-
this.#
|
|
742
|
+
if (J() && (this.#h = !0), this.#h) {
|
|
743
|
+
this.#g = {}, this.#p = {}, this.#a = {};
|
|
744
|
+
const e = ["rgba8unorm-srgb", "rgba8unorm"];
|
|
745
|
+
for (const s of e)
|
|
746
|
+
this.#g[s] = this.#e.createRenderPipeline({
|
|
735
747
|
label: `mipmap-pipeline-${s}`,
|
|
736
748
|
layout: "auto",
|
|
737
749
|
vertex: {
|
|
738
|
-
module:
|
|
750
|
+
module: t,
|
|
739
751
|
entryPoint: "fullscreen_vs"
|
|
740
752
|
},
|
|
741
753
|
fragment: {
|
|
742
|
-
module:
|
|
754
|
+
module: t,
|
|
743
755
|
entryPoint: "mipmap_fs",
|
|
744
756
|
targets: [{ format: s }]
|
|
745
757
|
},
|
|
@@ -747,15 +759,15 @@ class D {
|
|
|
747
759
|
topology: "triangle-strip",
|
|
748
760
|
stripIndexFormat: "uint32"
|
|
749
761
|
}
|
|
750
|
-
}), this.#
|
|
762
|
+
}), this.#p[s] = this.#e.createRenderPipeline({
|
|
751
763
|
label: `resize-pipeline-${s}`,
|
|
752
764
|
layout: "auto",
|
|
753
765
|
vertex: {
|
|
754
|
-
module:
|
|
766
|
+
module: t,
|
|
755
767
|
entryPoint: "fullscreen_vs"
|
|
756
768
|
},
|
|
757
769
|
fragment: {
|
|
758
|
-
module:
|
|
770
|
+
module: t,
|
|
759
771
|
entryPoint: "resize_fs",
|
|
760
772
|
targets: [{ format: s }]
|
|
761
773
|
},
|
|
@@ -763,15 +775,15 @@ class D {
|
|
|
763
775
|
topology: "triangle-strip",
|
|
764
776
|
stripIndexFormat: "uint32"
|
|
765
777
|
}
|
|
766
|
-
}), this.#
|
|
778
|
+
}), this.#a[s] = this.#e.createRenderPipeline({
|
|
767
779
|
label: `flip-y-pipeline-${s}`,
|
|
768
780
|
layout: "auto",
|
|
769
781
|
vertex: {
|
|
770
|
-
module:
|
|
782
|
+
module: t,
|
|
771
783
|
entryPoint: "fullscreen_vs"
|
|
772
784
|
},
|
|
773
785
|
fragment: {
|
|
774
|
-
module:
|
|
786
|
+
module: t,
|
|
775
787
|
entryPoint: "flipy_fs",
|
|
776
788
|
targets: [{ format: s }]
|
|
777
789
|
},
|
|
@@ -781,204 +793,186 @@ class D {
|
|
|
781
793
|
}
|
|
782
794
|
});
|
|
783
795
|
} else
|
|
784
|
-
this.#
|
|
796
|
+
this.#g = this.#e.createComputePipeline({
|
|
785
797
|
layout: "auto",
|
|
786
798
|
compute: {
|
|
787
|
-
module:
|
|
799
|
+
module: t,
|
|
788
800
|
entryPoint: "mipmap"
|
|
789
801
|
}
|
|
790
|
-
}), this.#
|
|
802
|
+
}), this.#d = this.#e.createComputePipeline({
|
|
803
|
+
layout: "auto",
|
|
804
|
+
compute: {
|
|
805
|
+
module: t,
|
|
806
|
+
entryPoint: "magic_mipmap"
|
|
807
|
+
}
|
|
808
|
+
}), this.#p = this.#e.createComputePipeline({
|
|
791
809
|
layout: "auto",
|
|
792
810
|
compute: {
|
|
793
|
-
module:
|
|
811
|
+
module: t,
|
|
794
812
|
entryPoint: "resize"
|
|
795
813
|
}
|
|
796
|
-
}), this.#
|
|
814
|
+
}), this.#a = this.#e.createComputePipeline({
|
|
797
815
|
layout: "auto",
|
|
798
816
|
compute: {
|
|
799
|
-
module:
|
|
817
|
+
module: t,
|
|
800
818
|
entryPoint: "flipy"
|
|
801
819
|
}
|
|
802
820
|
});
|
|
803
|
-
this.#
|
|
821
|
+
this.#E = await this.#e.createComputePipelineAsync({
|
|
804
822
|
layout: "auto",
|
|
805
823
|
compute: {
|
|
806
|
-
module:
|
|
824
|
+
module: t,
|
|
807
825
|
entryPoint: "detect_channel_count"
|
|
808
826
|
}
|
|
809
827
|
});
|
|
810
828
|
}
|
|
811
|
-
|
|
812
|
-
if (this.#
|
|
813
|
-
return this.#
|
|
829
|
+
#S(t) {
|
|
830
|
+
if (this.#f[t])
|
|
831
|
+
return this.#f[t];
|
|
814
832
|
const r = (async () => {
|
|
815
|
-
|
|
816
|
-
const
|
|
817
|
-
|
|
818
|
-
let s = await
|
|
819
|
-
this.#
|
|
820
|
-
const
|
|
833
|
+
this.#G("loadPipeline " + N[t]);
|
|
834
|
+
const e = Re[t];
|
|
835
|
+
O(e, `No shader available for format ${N[t]}`);
|
|
836
|
+
let s = await Z[e]();
|
|
837
|
+
this.#T || (s = s.replace(/^enable f16;\s*/m, "").replace(/\bf16\b/g, "f32").replace(/\bvec([234])h\b/g, "vec$1f").replace(/\bmat([234]x[234])h/g, "mat$1f").replace(/\b(\d*\.\d+|\d+\.)h\b/g, "$1"));
|
|
838
|
+
const o = this.#e.createShaderModule({
|
|
821
839
|
code: s,
|
|
822
|
-
label:
|
|
840
|
+
label: N[t]
|
|
823
841
|
});
|
|
824
|
-
if (typeof
|
|
825
|
-
const
|
|
826
|
-
if (
|
|
842
|
+
if (typeof o.getCompilationInfo == "function") {
|
|
843
|
+
const n = await o.getCompilationInfo();
|
|
844
|
+
if (n.messages.some((f) => f.type == "error")) {
|
|
827
845
|
console.error("WGSL compilation errors:");
|
|
828
|
-
for (const
|
|
829
|
-
console.error(
|
|
846
|
+
for (const f of n.messages)
|
|
847
|
+
console.error(f);
|
|
830
848
|
throw new Error("Shader compilation failed");
|
|
831
849
|
}
|
|
832
850
|
}
|
|
833
|
-
const
|
|
851
|
+
const c = await this.#e.createComputePipelineAsync({
|
|
834
852
|
layout: "auto",
|
|
835
853
|
compute: {
|
|
836
|
-
module:
|
|
854
|
+
module: o,
|
|
837
855
|
entryPoint: "main"
|
|
838
856
|
}
|
|
839
857
|
});
|
|
840
|
-
return
|
|
858
|
+
return this.#C("loadPipeline " + N[t]), c;
|
|
841
859
|
})();
|
|
842
|
-
return this.#
|
|
860
|
+
return this.#f[t] = r, r;
|
|
843
861
|
}
|
|
844
|
-
#t
|
|
845
|
-
return this.#
|
|
862
|
+
#r(t) {
|
|
863
|
+
return this.#l.has(t);
|
|
846
864
|
}
|
|
847
|
-
#
|
|
848
|
-
const
|
|
849
|
-
if (
|
|
850
|
-
return
|
|
851
|
-
const s = r ? [
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
"eac-rg",
|
|
856
|
-
"bc1-rgb",
|
|
857
|
-
"etc2-rgb",
|
|
858
|
-
"bc7-rgb",
|
|
859
|
-
"astc-rgb",
|
|
860
|
-
"astc-4x4-rgb",
|
|
861
|
-
"bc7-rgba",
|
|
862
|
-
"astc-rgba",
|
|
863
|
-
"astc-4x4-rgba"
|
|
864
|
-
] : [
|
|
865
|
-
"bc4-r",
|
|
866
|
-
"eac-r",
|
|
867
|
-
"bc5-rg",
|
|
868
|
-
"eac-rg",
|
|
869
|
-
"bc7-rgb",
|
|
870
|
-
"bc1-rgb",
|
|
871
|
-
"astc-rgb",
|
|
872
|
-
"astc-4x4-rgb",
|
|
873
|
-
"etc2-rgb",
|
|
874
|
-
"bc7-rgba",
|
|
875
|
-
"astc-rgba",
|
|
876
|
-
"astc-4x4-rgba"
|
|
877
|
-
];
|
|
878
|
-
for (const n of s)
|
|
879
|
-
if (n.includes(e) && this.#t(P[n]))
|
|
880
|
-
return P[n];
|
|
865
|
+
#P(t, r) {
|
|
866
|
+
const e = z[t];
|
|
867
|
+
if (e != null && this.#r(e))
|
|
868
|
+
return e;
|
|
869
|
+
const s = r ? ["bc4-r", "eac-r", "bc5-rg", "eac-rg", "bc1-rgb", "etc2-rgb", "bc7-rgb", "astc-rgb", "astc-4x4-rgb", "bc7-rgba", "astc-rgba", "astc-4x4-rgba"] : ["bc4-r", "eac-r", "bc5-rg", "eac-rg", "bc7-rgb", "astc-rgb", "astc-4x4-rgb", "bc1-rgb", "etc2-rgb", "bc7-rgba", "astc-rgba", "astc-4x4-rgba"];
|
|
870
|
+
for (const o of s)
|
|
871
|
+
if (o.includes(t) && this.#r(z[o]))
|
|
872
|
+
return z[o];
|
|
881
873
|
}
|
|
882
|
-
async #
|
|
883
|
-
if (
|
|
884
|
-
|
|
885
|
-
else if (
|
|
886
|
-
if (
|
|
887
|
-
if (this.#
|
|
888
|
-
if (this.#
|
|
889
|
-
|
|
890
|
-
if (this.#
|
|
891
|
-
|
|
892
|
-
if (this.#
|
|
893
|
-
if (this.#
|
|
894
|
-
} else if (e.normal) {
|
|
895
|
-
if (this.#t(i.BC5_RG)) return i.BC5_RG;
|
|
896
|
-
if (this.#t(i.EAC_RG)) return i.EAC_RG;
|
|
874
|
+
async #A(t, r) {
|
|
875
|
+
if (t.format == null)
|
|
876
|
+
t.format = "rgb";
|
|
877
|
+
else if (t.format == "auto") {
|
|
878
|
+
if (t.srgb) {
|
|
879
|
+
if (this.#r(a.BC7_RGB)) return a.BC7_RGB;
|
|
880
|
+
if (this.#r(a.ASTC_4x4_RGB)) return a.ASTC_4x4_RGB;
|
|
881
|
+
if (this.#r(a.BC1_RGB)) return a.BC1_RGB;
|
|
882
|
+
if (this.#r(a.ETC2_RGB)) return a.ETC2_RGB;
|
|
883
|
+
} else if (t.normal) {
|
|
884
|
+
if (this.#r(a.BC5_RG)) return a.BC5_RG;
|
|
885
|
+
if (this.#r(a.EAC_RG)) return a.EAC_RG;
|
|
897
886
|
} else {
|
|
898
887
|
let s;
|
|
899
888
|
if (r instanceof GPUTexture)
|
|
900
|
-
r.format == "r8unorm" || r.format == "r16unorm" ? s = 1 : r.format == "rg8unorm" || r.format == "rg16unorm" ? s = 2 : s = await this.#
|
|
889
|
+
r.format == "r8unorm" || r.format == "r16unorm" ? s = 1 : r.format == "rg8unorm" || r.format == "rg16unorm" ? s = 2 : s = await this.#F(r);
|
|
901
890
|
else {
|
|
902
|
-
const
|
|
903
|
-
s = this.#
|
|
891
|
+
const o = we(r);
|
|
892
|
+
s = this.#I(o);
|
|
904
893
|
}
|
|
905
894
|
if (s == 4) {
|
|
906
|
-
if (this.#
|
|
907
|
-
if (this.#
|
|
895
|
+
if (this.#r(a.BC7_RGBA)) return a.BC7_RGBA;
|
|
896
|
+
if (this.#r(a.ASTC_4x4_RGBA)) return a.ASTC_4x4_RGBA;
|
|
908
897
|
} else if (s == 3) {
|
|
909
|
-
if (this.#
|
|
910
|
-
if (this.#
|
|
911
|
-
if (this.#
|
|
912
|
-
if (this.#
|
|
898
|
+
if (this.#r(a.BC7_RGB)) return a.BC7_RGB;
|
|
899
|
+
if (this.#r(a.ASTC_4x4_RGB)) return a.ASTC_4x4_RGB;
|
|
900
|
+
if (this.#r(a.BC1_RGB)) return a.BC1_RGB;
|
|
901
|
+
if (this.#r(a.ETC2_RGB)) return a.ETC2_RGB;
|
|
913
902
|
} else if (s == 2) {
|
|
914
|
-
if (this.#
|
|
915
|
-
if (this.#
|
|
903
|
+
if (this.#r(a.BC5_RG)) return a.BC5_RG;
|
|
904
|
+
if (this.#r(a.EAC_RG)) return a.EAC_RG;
|
|
916
905
|
} else if (s == 1) {
|
|
917
|
-
if (this.#
|
|
918
|
-
if (this.#
|
|
906
|
+
if (this.#r(a.BC4_R)) return a.BC4_R;
|
|
907
|
+
if (this.#r(a.EAC_R)) return a.EAC_R;
|
|
919
908
|
}
|
|
920
909
|
}
|
|
921
910
|
throw new Error("No supported format found.");
|
|
922
911
|
}
|
|
923
|
-
const
|
|
924
|
-
if (
|
|
925
|
-
throw new Error(`Unsupported format: ${
|
|
926
|
-
return
|
|
912
|
+
const e = this.#P(t.format, t.preferLowQuality);
|
|
913
|
+
if (e === void 0)
|
|
914
|
+
throw new Error(`Unsupported format: ${t.format}`);
|
|
915
|
+
return e;
|
|
927
916
|
}
|
|
928
|
-
#
|
|
929
|
-
let r = !0,
|
|
930
|
-
const
|
|
931
|
-
for (let
|
|
932
|
-
const
|
|
933
|
-
|
|
934
|
-
const h = 2 *
|
|
935
|
-
(Math.abs(
|
|
917
|
+
#I(t) {
|
|
918
|
+
let r = !0, e = !0, s = 0;
|
|
919
|
+
const o = Math.min(1024 * 128, t.length);
|
|
920
|
+
for (let c = 0; c < o; c += 4) {
|
|
921
|
+
const n = t[c] / 255, f = t[c + 1] / 255, u = t[c + 2] / 255;
|
|
922
|
+
t[c + 3] < 255 && (r = !1), (n != f || f != u) && (e = !1);
|
|
923
|
+
const h = 2 * n - 1, m = 2 * f - 1, R = 2 * u - 1, T = h * h + m * m + R * R, d = Math.sqrt(T);
|
|
924
|
+
(Math.abs(d - 1) > 0.2 || R < -0.1) && (s += 1);
|
|
936
925
|
}
|
|
937
|
-
return r ?
|
|
926
|
+
return r ? e ? 1 : 16 * s < o ? 2 : 3 : 4;
|
|
938
927
|
}
|
|
939
|
-
async #
|
|
940
|
-
const
|
|
928
|
+
async #F(t) {
|
|
929
|
+
const e = this.#e.createBuffer({
|
|
941
930
|
size: 12,
|
|
942
931
|
usage: GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_SRC
|
|
943
932
|
}), s = this.#e.createBuffer({
|
|
944
933
|
size: 12,
|
|
945
934
|
usage: GPUBufferUsage.COPY_DST | GPUBufferUsage.MAP_READ
|
|
946
|
-
}),
|
|
947
|
-
layout: this.#
|
|
935
|
+
}), o = this.#e.createBindGroup({
|
|
936
|
+
layout: this.#E.getBindGroupLayout(0),
|
|
948
937
|
entries: [
|
|
949
|
-
{ binding: 0, resource:
|
|
950
|
-
{ binding: 1, resource: { buffer:
|
|
938
|
+
{ binding: 0, resource: t.createView() },
|
|
939
|
+
{ binding: 1, resource: { buffer: e } }
|
|
951
940
|
]
|
|
952
|
-
}),
|
|
953
|
-
|
|
954
|
-
const { width:
|
|
955
|
-
|
|
956
|
-
const m = new Uint32Array(s.getMappedRange()),
|
|
957
|
-
return s.unmap(), s.destroy(),
|
|
941
|
+
}), c = this.#e.createCommandEncoder(), n = c.beginComputePass();
|
|
942
|
+
n.setPipeline(this.#E), n.setBindGroup(0, o);
|
|
943
|
+
const { width: f, height: u } = t, l = Math.ceil(f / 8), h = Math.ceil(u / 8);
|
|
944
|
+
n.dispatchWorkgroups(l, h), n.end(), c.copyBufferToBuffer(e, 0, s, 0, 12), this.#e.queue.submit([c.finish()]), await this.#e.queue.onSubmittedWorkDone(), await s.mapAsync(GPUMapMode.READ);
|
|
945
|
+
const m = new Uint32Array(s.getMappedRange()), R = m[0] == 0, T = m[1] == 0, d = m[2];
|
|
946
|
+
return s.unmap(), s.destroy(), e.destroy(), R ? T ? 1 : 4 * d < f * u ? 2 : 3 : 4;
|
|
947
|
+
}
|
|
948
|
+
#R(t, r, e) {
|
|
949
|
+
const s = r && r.length > 0 ? e < r.length ? r[e] : r[r.length - 1] : 1, o = new ArrayBuffer(8), c = new DataView(o);
|
|
950
|
+
c.setUint32(0, t, !0), c.setFloat32(4, s, !0), this.#e.queue.writeBuffer(this.#i, 0, o);
|
|
958
951
|
}
|
|
959
952
|
// Apply scaling and flipY transform.
|
|
960
|
-
#
|
|
961
|
-
if (this.#
|
|
962
|
-
this.#
|
|
953
|
+
#U(t, r, e, s, o, c, n) {
|
|
954
|
+
if (this.#h) {
|
|
955
|
+
this.#M(t, r, e, s, o, c, n);
|
|
963
956
|
return;
|
|
964
957
|
}
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
958
|
+
this.#R(c);
|
|
959
|
+
const f = t.beginComputePass(), u = n ? this.#a : this.#p;
|
|
960
|
+
f.setPipeline(u);
|
|
961
|
+
const l = this.#e.createBindGroup({
|
|
962
|
+
layout: u.getBindGroupLayout(0),
|
|
969
963
|
entries: [
|
|
970
964
|
{
|
|
971
965
|
binding: 0,
|
|
972
966
|
resource: r.createView({
|
|
973
967
|
baseMipLevel: 0,
|
|
974
968
|
mipLevelCount: 1,
|
|
975
|
-
format:
|
|
969
|
+
format: (c & A.sRGB) != 0 ? "rgba8unorm-srgb" : "rgba8unorm",
|
|
976
970
|
usage: GPUTextureUsage.TEXTURE_BINDING
|
|
977
971
|
})
|
|
978
972
|
},
|
|
979
973
|
{
|
|
980
974
|
binding: 1,
|
|
981
|
-
resource:
|
|
975
|
+
resource: e.createView({
|
|
982
976
|
baseMipLevel: 0,
|
|
983
977
|
mipLevelCount: 1,
|
|
984
978
|
dimension: "2d",
|
|
@@ -988,35 +982,37 @@ class D {
|
|
|
988
982
|
},
|
|
989
983
|
{
|
|
990
984
|
binding: 2,
|
|
991
|
-
resource: this.#
|
|
985
|
+
resource: this.#s
|
|
992
986
|
},
|
|
993
987
|
{
|
|
994
988
|
binding: 3,
|
|
995
|
-
resource: { buffer: this.#
|
|
989
|
+
resource: { buffer: this.#i }
|
|
996
990
|
}
|
|
997
991
|
]
|
|
998
992
|
});
|
|
999
|
-
|
|
993
|
+
f.setBindGroup(0, l), f.dispatchWorkgroups(Math.ceil(s / 8), Math.ceil(o / 8)), f.end();
|
|
1000
994
|
}
|
|
1001
995
|
// Apply scaling and flipY transform.
|
|
1002
|
-
#
|
|
1003
|
-
const
|
|
996
|
+
#M(t, r, e, s, o, c, n) {
|
|
997
|
+
const f = (c & A.sRGB) != 0 ? "rgba8unorm-srgb" : "rgba8unorm", u = e.createView({
|
|
1004
998
|
baseMipLevel: 0,
|
|
1005
999
|
mipLevelCount: 1,
|
|
1006
1000
|
dimension: "2d",
|
|
1007
|
-
format:
|
|
1001
|
+
format: f,
|
|
1008
1002
|
usage: GPUTextureUsage.RENDER_ATTACHMENT
|
|
1009
|
-
}),
|
|
1003
|
+
}), l = t.beginRenderPass({
|
|
1010
1004
|
colorAttachments: [
|
|
1011
1005
|
{
|
|
1012
|
-
view:
|
|
1006
|
+
view: u,
|
|
1013
1007
|
loadOp: "clear",
|
|
1014
1008
|
storeOp: "store",
|
|
1015
1009
|
clearValue: [0, 0, 0, 0]
|
|
1016
1010
|
}
|
|
1017
1011
|
]
|
|
1018
|
-
})
|
|
1019
|
-
|
|
1012
|
+
});
|
|
1013
|
+
this.#R(c);
|
|
1014
|
+
const h = n ? this.#a[f] : this.#p[f];
|
|
1015
|
+
l.setPipeline(h);
|
|
1020
1016
|
const m = this.#e.createBindGroup({
|
|
1021
1017
|
layout: h.getBindGroupLayout(0),
|
|
1022
1018
|
entries: [
|
|
@@ -1025,52 +1021,53 @@ class D {
|
|
|
1025
1021
|
resource: r.createView({
|
|
1026
1022
|
baseMipLevel: 0,
|
|
1027
1023
|
mipLevelCount: 1,
|
|
1028
|
-
format:
|
|
1024
|
+
format: (c & A.sRGB) != 0 ? "rgba8unorm-srgb" : "rgba8unorm",
|
|
1029
1025
|
usage: GPUTextureUsage.TEXTURE_BINDING
|
|
1030
1026
|
})
|
|
1031
1027
|
},
|
|
1032
1028
|
{
|
|
1033
1029
|
binding: 2,
|
|
1034
|
-
resource: this.#
|
|
1030
|
+
resource: this.#s
|
|
1035
1031
|
},
|
|
1036
1032
|
{
|
|
1037
1033
|
binding: 3,
|
|
1038
|
-
resource: { buffer: this.#
|
|
1034
|
+
resource: { buffer: this.#i }
|
|
1039
1035
|
}
|
|
1040
1036
|
]
|
|
1041
1037
|
});
|
|
1042
|
-
|
|
1038
|
+
l.setBindGroup(0, m), l.draw(4, 1, 0, 0), l.end();
|
|
1043
1039
|
}
|
|
1044
|
-
async #
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
1040
|
+
async #L(t, r, e, s, o, c, n, f) {
|
|
1041
|
+
n == null && this.#R(c);
|
|
1042
|
+
let u = s, l = o;
|
|
1043
|
+
if (this.#h)
|
|
1044
|
+
for (let h = 0; h < e - 1; h++)
|
|
1045
|
+
n != null && this.#R(c, n, h), u = Math.max(1, Math.floor(u / 2)), l = Math.max(1, Math.floor(l / 2)), this.#N(t, r, h, h + 1, u, l, c);
|
|
1049
1046
|
else {
|
|
1050
|
-
const
|
|
1051
|
-
|
|
1052
|
-
for (let
|
|
1053
|
-
|
|
1054
|
-
|
|
1047
|
+
const h = t.beginComputePass(), m = f === "box" || (c & A.Alpha) != 0 ? this.#g : this.#d, R = m.getBindGroupLayout(0);
|
|
1048
|
+
h.setPipeline(m);
|
|
1049
|
+
for (let T = 0; T < e - 1; T++)
|
|
1050
|
+
n != null && this.#R(c, n, T), u = Math.max(1, Math.floor(u / 2)), l = Math.max(1, Math.floor(l / 2)), this.#D(h, R, r, T, T + 1, u, l, c);
|
|
1051
|
+
h.end();
|
|
1055
1052
|
}
|
|
1056
1053
|
}
|
|
1057
|
-
#
|
|
1058
|
-
const
|
|
1059
|
-
layout:
|
|
1054
|
+
#D(t, r, e, s, o, c, n, f) {
|
|
1055
|
+
const u = this.#e.createBindGroup({
|
|
1056
|
+
layout: r,
|
|
1060
1057
|
entries: [
|
|
1061
1058
|
{
|
|
1062
1059
|
binding: 0,
|
|
1063
|
-
resource:
|
|
1064
|
-
baseMipLevel:
|
|
1060
|
+
resource: e.createView({
|
|
1061
|
+
baseMipLevel: s,
|
|
1065
1062
|
mipLevelCount: 1,
|
|
1066
|
-
format:
|
|
1063
|
+
format: (f & A.sRGB) != 0 ? "rgba8unorm-srgb" : "rgba8unorm",
|
|
1067
1064
|
usage: GPUTextureUsage.TEXTURE_BINDING
|
|
1068
1065
|
})
|
|
1069
1066
|
},
|
|
1070
1067
|
{
|
|
1071
1068
|
binding: 1,
|
|
1072
|
-
resource:
|
|
1073
|
-
baseMipLevel:
|
|
1069
|
+
resource: e.createView({
|
|
1070
|
+
baseMipLevel: o,
|
|
1074
1071
|
mipLevelCount: 1,
|
|
1075
1072
|
dimension: "2d",
|
|
1076
1073
|
format: "rgba8unorm",
|
|
@@ -1079,57 +1076,581 @@ class D {
|
|
|
1079
1076
|
},
|
|
1080
1077
|
{
|
|
1081
1078
|
binding: 2,
|
|
1082
|
-
resource: this.#
|
|
1079
|
+
resource: this.#s
|
|
1083
1080
|
},
|
|
1084
1081
|
{
|
|
1085
1082
|
binding: 3,
|
|
1086
|
-
resource: { buffer: this.#
|
|
1083
|
+
resource: { buffer: this.#i }
|
|
1087
1084
|
}
|
|
1088
1085
|
]
|
|
1089
1086
|
});
|
|
1090
|
-
|
|
1087
|
+
t.setBindGroup(0, u), t.dispatchWorkgroups(Math.ceil(c / 8), Math.ceil(n / 8));
|
|
1091
1088
|
}
|
|
1092
|
-
#
|
|
1093
|
-
const
|
|
1089
|
+
#N(t, r, e, s, o, c, n) {
|
|
1090
|
+
const f = (n & A.sRGB) != 0 ? "rgba8unorm-srgb" : "rgba8unorm", u = r.createView({
|
|
1094
1091
|
baseMipLevel: s,
|
|
1095
1092
|
mipLevelCount: 1,
|
|
1096
1093
|
dimension: "2d",
|
|
1097
|
-
format:
|
|
1094
|
+
format: f,
|
|
1098
1095
|
usage: GPUTextureUsage.RENDER_ATTACHMENT
|
|
1099
|
-
}),
|
|
1096
|
+
}), l = t.beginRenderPass({
|
|
1100
1097
|
colorAttachments: [
|
|
1101
1098
|
{
|
|
1102
|
-
view:
|
|
1099
|
+
view: u,
|
|
1103
1100
|
loadOp: "clear",
|
|
1104
1101
|
storeOp: "store",
|
|
1105
1102
|
clearValue: [0, 0, 0, 0]
|
|
1106
1103
|
}
|
|
1107
1104
|
]
|
|
1108
1105
|
}), h = this.#e.createBindGroup({
|
|
1109
|
-
layout: this.#
|
|
1106
|
+
layout: this.#g[f].getBindGroupLayout(0),
|
|
1110
1107
|
entries: [
|
|
1111
1108
|
{
|
|
1112
1109
|
binding: 0,
|
|
1113
1110
|
resource: r.createView({
|
|
1114
|
-
baseMipLevel:
|
|
1111
|
+
baseMipLevel: e,
|
|
1115
1112
|
mipLevelCount: 1,
|
|
1116
|
-
format:
|
|
1113
|
+
format: f,
|
|
1117
1114
|
usage: GPUTextureUsage.TEXTURE_BINDING
|
|
1118
1115
|
})
|
|
1119
1116
|
},
|
|
1120
1117
|
{
|
|
1121
1118
|
binding: 2,
|
|
1122
|
-
resource: this.#
|
|
1119
|
+
resource: this.#s
|
|
1123
1120
|
},
|
|
1124
1121
|
{
|
|
1125
1122
|
binding: 3,
|
|
1126
|
-
resource: { buffer: this.#
|
|
1123
|
+
resource: { buffer: this.#i }
|
|
1127
1124
|
}
|
|
1128
1125
|
]
|
|
1129
1126
|
});
|
|
1130
|
-
|
|
1127
|
+
l.setPipeline(this.#g[f]), l.setBindGroup(0, h), l.draw(4, 1, 0, 0), l.end();
|
|
1128
|
+
}
|
|
1129
|
+
}
|
|
1130
|
+
const Ie = /* @__PURE__ */ Object.assign({ "./spark_astc_rgb.glsl": () => import("./spark_astc_rgb-CTmg8wnA.js").then((i) => i.default), "./spark_astc_rgba.glsl": () => import("./spark_astc_rgba-CDMNWH6H.js").then((i) => i.default), "./spark_bc1_rgb.glsl": () => import("./spark_bc1_rgb-C0pbbQPO.js").then((i) => i.default), "./spark_bc4_r.glsl": () => import("./spark_bc4_r-YQ6i79H9.js").then((i) => i.default), "./spark_bc5_rg.glsl": () => import("./spark_bc5_rg-BqzKgeMU.js").then((i) => i.default), "./spark_bc7_rgb.glsl": () => import("./spark_bc7_rgb-DBkDHCzE.js").then((i) => i.default), "./spark_bc7_rgba.glsl": () => import("./spark_bc7_rgba-DQUk89UX.js").then((i) => i.default), "./spark_eac_r.glsl": () => import("./spark_eac_r-Dvy2qUxf.js").then((i) => i.default), "./spark_eac_rg.glsl": () => import("./spark_eac_rg-DKLVL9co.js").then((i) => i.default), "./spark_etc2_rgb.glsl": () => import("./spark_etc2_rgb-BpnNweVx.js").then((i) => i.default) }), Fe = Object.fromEntries(
|
|
1131
|
+
Object.entries(Ie).map(([i, t]) => [i.replace("./", ""), async () => await t()])
|
|
1132
|
+
), p = {
|
|
1133
|
+
ASTC_4x4_RGB: 0,
|
|
1134
|
+
ASTC_4x4_RGBA: 1,
|
|
1135
|
+
EAC_R: 4,
|
|
1136
|
+
EAC_RG: 5,
|
|
1137
|
+
ETC2_RGB: 6,
|
|
1138
|
+
BC1_RGB: 9,
|
|
1139
|
+
BC4_R: 13,
|
|
1140
|
+
BC5_RG: 14,
|
|
1141
|
+
BC7_RGB: 16,
|
|
1142
|
+
BC7_RGBA: 17
|
|
1143
|
+
}, v = [
|
|
1144
|
+
/* 0 */
|
|
1145
|
+
"astc-4x4-rgb",
|
|
1146
|
+
/* 1 */
|
|
1147
|
+
"astc-4x4-rgba",
|
|
1148
|
+
/* 2 */
|
|
1149
|
+
null,
|
|
1150
|
+
/* 3 */
|
|
1151
|
+
null,
|
|
1152
|
+
/* 4 */
|
|
1153
|
+
"eac-r",
|
|
1154
|
+
/* 5 */
|
|
1155
|
+
"eac-rg",
|
|
1156
|
+
/* 6 */
|
|
1157
|
+
"etc2-rgb",
|
|
1158
|
+
/* 7 */
|
|
1159
|
+
null,
|
|
1160
|
+
/* 8 */
|
|
1161
|
+
null,
|
|
1162
|
+
/* 9 */
|
|
1163
|
+
"bc1-rgb",
|
|
1164
|
+
/* 10 */
|
|
1165
|
+
null,
|
|
1166
|
+
/* 11 */
|
|
1167
|
+
null,
|
|
1168
|
+
/* 12 */
|
|
1169
|
+
null,
|
|
1170
|
+
/* 13 */
|
|
1171
|
+
"bc4-r",
|
|
1172
|
+
/* 14 */
|
|
1173
|
+
"bc5-rg",
|
|
1174
|
+
/* 15 */
|
|
1175
|
+
null,
|
|
1176
|
+
/* 16 */
|
|
1177
|
+
"bc7-rgb",
|
|
1178
|
+
/* 17 */
|
|
1179
|
+
"bc7-rgba"
|
|
1180
|
+
], Me = [
|
|
1181
|
+
/* 0 */
|
|
1182
|
+
"spark_astc_rgb.glsl",
|
|
1183
|
+
/* 1 */
|
|
1184
|
+
"spark_astc_rgba.glsl",
|
|
1185
|
+
/* 2 */
|
|
1186
|
+
null,
|
|
1187
|
+
/* 3 */
|
|
1188
|
+
null,
|
|
1189
|
+
/* 4 */
|
|
1190
|
+
"spark_eac_r.glsl",
|
|
1191
|
+
/* 5 */
|
|
1192
|
+
"spark_eac_rg.glsl",
|
|
1193
|
+
/* 6 */
|
|
1194
|
+
"spark_etc2_rgb.glsl",
|
|
1195
|
+
/* 7 */
|
|
1196
|
+
null,
|
|
1197
|
+
/* 8 */
|
|
1198
|
+
null,
|
|
1199
|
+
/* 9 */
|
|
1200
|
+
"spark_bc1_rgb.glsl",
|
|
1201
|
+
/* 10 */
|
|
1202
|
+
null,
|
|
1203
|
+
/* 11 */
|
|
1204
|
+
null,
|
|
1205
|
+
/* 12 */
|
|
1206
|
+
null,
|
|
1207
|
+
/* 13 */
|
|
1208
|
+
"spark_bc4_r.glsl",
|
|
1209
|
+
/* 14 */
|
|
1210
|
+
"spark_bc5_rg.glsl",
|
|
1211
|
+
/* 15 */
|
|
1212
|
+
null,
|
|
1213
|
+
/* 16 */
|
|
1214
|
+
"spark_bc7_rgb.glsl",
|
|
1215
|
+
/* 17 */
|
|
1216
|
+
"spark_bc7_rgba.glsl"
|
|
1217
|
+
], Le = [
|
|
1218
|
+
/* 0 */
|
|
1219
|
+
16,
|
|
1220
|
+
/* 1 */
|
|
1221
|
+
16,
|
|
1222
|
+
/* 2 */
|
|
1223
|
+
0,
|
|
1224
|
+
/* 3 */
|
|
1225
|
+
0,
|
|
1226
|
+
/* 4 */
|
|
1227
|
+
8,
|
|
1228
|
+
/* 5 */
|
|
1229
|
+
16,
|
|
1230
|
+
/* 6 */
|
|
1231
|
+
8,
|
|
1232
|
+
/* 7 */
|
|
1233
|
+
0,
|
|
1234
|
+
/* 8 */
|
|
1235
|
+
0,
|
|
1236
|
+
/* 9 */
|
|
1237
|
+
8,
|
|
1238
|
+
/* 10 */
|
|
1239
|
+
0,
|
|
1240
|
+
/* 11 */
|
|
1241
|
+
0,
|
|
1242
|
+
/* 12 */
|
|
1243
|
+
0,
|
|
1244
|
+
/* 13 */
|
|
1245
|
+
8,
|
|
1246
|
+
/* 14 */
|
|
1247
|
+
16,
|
|
1248
|
+
/* 15 */
|
|
1249
|
+
0,
|
|
1250
|
+
/* 16 */
|
|
1251
|
+
16,
|
|
1252
|
+
/* 17 */
|
|
1253
|
+
16
|
|
1254
|
+
], De = [
|
|
1255
|
+
/* 0 */
|
|
1256
|
+
!0,
|
|
1257
|
+
// ASTC_4x4_RGB
|
|
1258
|
+
/* 1 */
|
|
1259
|
+
!0,
|
|
1260
|
+
// ASTC_4x4_RGBA
|
|
1261
|
+
/* 2 */
|
|
1262
|
+
null,
|
|
1263
|
+
/* 3 */
|
|
1264
|
+
null,
|
|
1265
|
+
/* 4 */
|
|
1266
|
+
!1,
|
|
1267
|
+
// EAC_R
|
|
1268
|
+
/* 5 */
|
|
1269
|
+
!1,
|
|
1270
|
+
// EAC_RG
|
|
1271
|
+
/* 6 */
|
|
1272
|
+
!0,
|
|
1273
|
+
// ETC2_RGB
|
|
1274
|
+
/* 7 */
|
|
1275
|
+
null,
|
|
1276
|
+
/* 8 */
|
|
1277
|
+
null,
|
|
1278
|
+
/* 9 */
|
|
1279
|
+
!0,
|
|
1280
|
+
// BC1_RGB
|
|
1281
|
+
/* 10 */
|
|
1282
|
+
null,
|
|
1283
|
+
/* 11 */
|
|
1284
|
+
null,
|
|
1285
|
+
/* 12 */
|
|
1286
|
+
null,
|
|
1287
|
+
/* 13 */
|
|
1288
|
+
!1,
|
|
1289
|
+
// BC4_R
|
|
1290
|
+
/* 14 */
|
|
1291
|
+
!1,
|
|
1292
|
+
// BC5_RG
|
|
1293
|
+
/* 15 */
|
|
1294
|
+
null,
|
|
1295
|
+
/* 16 */
|
|
1296
|
+
!0,
|
|
1297
|
+
// BC7_RGB
|
|
1298
|
+
/* 17 */
|
|
1299
|
+
!0
|
|
1300
|
+
// BC7_RGBA
|
|
1301
|
+
], se = 37808, ie = 37840, ae = 36492, ne = 36493, Ne = 33776, ve = 35916, oe = 36283, ce = 36285, Xe = 37492, ke = 37493, ue = 37488, le = 37490, X = 36208, $ = 36214, Oe = [
|
|
1302
|
+
/* 0 */
|
|
1303
|
+
[se, ie],
|
|
1304
|
+
/* 1 */
|
|
1305
|
+
[se, ie],
|
|
1306
|
+
/* 2 */
|
|
1307
|
+
null,
|
|
1308
|
+
/* 3 */
|
|
1309
|
+
null,
|
|
1310
|
+
/* 4 */
|
|
1311
|
+
[ue, ue],
|
|
1312
|
+
/* 5 */
|
|
1313
|
+
[le, le],
|
|
1314
|
+
/* 6 */
|
|
1315
|
+
[Xe, ke],
|
|
1316
|
+
/* 7 */
|
|
1317
|
+
null,
|
|
1318
|
+
/* 8 */
|
|
1319
|
+
null,
|
|
1320
|
+
/* 9 */
|
|
1321
|
+
[Ne, ve],
|
|
1322
|
+
/* 10 */
|
|
1323
|
+
null,
|
|
1324
|
+
/* 11 */
|
|
1325
|
+
null,
|
|
1326
|
+
/* 12 */
|
|
1327
|
+
null,
|
|
1328
|
+
/* 13 */
|
|
1329
|
+
[oe, oe],
|
|
1330
|
+
/* 14 */
|
|
1331
|
+
[ce, ce],
|
|
1332
|
+
/* 15 */
|
|
1333
|
+
null,
|
|
1334
|
+
/* 16 */
|
|
1335
|
+
[ae, ne],
|
|
1336
|
+
/* 17 */
|
|
1337
|
+
[ae, ne]
|
|
1338
|
+
], Ve = [
|
|
1339
|
+
/* 0 */
|
|
1340
|
+
X,
|
|
1341
|
+
/* 1 */
|
|
1342
|
+
X,
|
|
1343
|
+
/* 2 */
|
|
1344
|
+
null,
|
|
1345
|
+
/* 3 */
|
|
1346
|
+
null,
|
|
1347
|
+
/* 4 */
|
|
1348
|
+
$,
|
|
1349
|
+
/* 5 */
|
|
1350
|
+
X,
|
|
1351
|
+
/* 6 */
|
|
1352
|
+
$,
|
|
1353
|
+
/* 7 */
|
|
1354
|
+
null,
|
|
1355
|
+
/* 8 */
|
|
1356
|
+
null,
|
|
1357
|
+
/* 9 */
|
|
1358
|
+
$,
|
|
1359
|
+
/* 10 */
|
|
1360
|
+
null,
|
|
1361
|
+
/* 11 */
|
|
1362
|
+
null,
|
|
1363
|
+
/* 12 */
|
|
1364
|
+
null,
|
|
1365
|
+
/* 13 */
|
|
1366
|
+
$,
|
|
1367
|
+
/* 14 */
|
|
1368
|
+
X,
|
|
1369
|
+
/* 15 */
|
|
1370
|
+
null,
|
|
1371
|
+
/* 16 */
|
|
1372
|
+
X,
|
|
1373
|
+
/* 17 */
|
|
1374
|
+
X
|
|
1375
|
+
], H = Object.freeze({
|
|
1376
|
+
"astc-4x4-rgb": p.ASTC_4x4_RGB,
|
|
1377
|
+
"astc-4x4-rgba": p.ASTC_4x4_RGBA,
|
|
1378
|
+
"eac-r": p.EAC_R,
|
|
1379
|
+
"eac-rg": p.EAC_RG,
|
|
1380
|
+
"etc2-rgb": p.ETC2_RGB,
|
|
1381
|
+
"bc1-rgb": p.BC1_RGB,
|
|
1382
|
+
"bc4-r": p.BC4_R,
|
|
1383
|
+
"bc5-rg": p.BC5_RG,
|
|
1384
|
+
"bc7-rgb": p.BC7_RGB,
|
|
1385
|
+
"bc7-rgba": p.BC7_RGBA,
|
|
1386
|
+
"astc-rgb": p.ASTC_4x4_RGB,
|
|
1387
|
+
"astc-rgba": p.ASTC_4x4_RGBA
|
|
1388
|
+
});
|
|
1389
|
+
function We(i, t = !1) {
|
|
1390
|
+
const r = /* @__PURE__ */ new Set();
|
|
1391
|
+
if (t) {
|
|
1392
|
+
const u = i.getSupportedExtensions();
|
|
1393
|
+
console.log("Available WebGL extensions:"), u && u.sort().forEach((l) => {
|
|
1394
|
+
console.log(` ${l}`);
|
|
1395
|
+
}), console.log(`Total: ${u ? u.length : 0} extensions`), console.log("");
|
|
1396
|
+
}
|
|
1397
|
+
(i.getExtension("EXT_texture_compression_bptc") || i.getExtension("WEBGL_texture_compression_bptc")) && (r.add(p.BC7_RGB), r.add(p.BC7_RGBA));
|
|
1398
|
+
const s = i.getExtension("WEBGL_compressed_texture_s3tc"), o = i.getExtension("WEBGL_compressed_texture_s3tc_srgb");
|
|
1399
|
+
if ((s || o) && r.add(p.BC1_RGB), i.getExtension("EXT_texture_compression_rgtc") && (r.add(p.BC4_R), r.add(p.BC5_RG)), i.getExtension("WEBGL_compressed_texture_etc") && (r.add(p.ETC2_RGB), r.add(p.EAC_R), r.add(p.EAC_RG)), i.getExtension("WEBGL_compressed_texture_astc") && (r.add(p.ASTC_4x4_RGB), r.add(p.ASTC_4x4_RGBA)), t) {
|
|
1400
|
+
console.log("Supported compression formats:");
|
|
1401
|
+
const u = Array.from(r).map((l) => v[l]).filter(Boolean);
|
|
1402
|
+
u.forEach((l) => {
|
|
1403
|
+
console.log(` ${l}`);
|
|
1404
|
+
}), console.log(`Total: ${u.length} formats`), console.log("");
|
|
1405
|
+
}
|
|
1406
|
+
return r;
|
|
1407
|
+
}
|
|
1408
|
+
async function ze(i) {
|
|
1409
|
+
const t = Fe[i];
|
|
1410
|
+
if (!t)
|
|
1411
|
+
throw new Error(`Shader not found: ${i}`);
|
|
1412
|
+
let r = await t();
|
|
1413
|
+
return r = `#version 300 es
|
|
1414
|
+
precision highp float;
|
|
1415
|
+
precision highp int;
|
|
1416
|
+
` + r, r;
|
|
1417
|
+
}
|
|
1418
|
+
const Y = `#version 300 es
|
|
1419
|
+
void main() {
|
|
1420
|
+
vec2 uv = vec2((gl_VertexID << 1) & 2, gl_VertexID & 2);
|
|
1421
|
+
gl_Position = vec4(uv * 2.0 - 1.0, 0.0, 1.0);
|
|
1422
|
+
}
|
|
1423
|
+
`;
|
|
1424
|
+
function q(i, t, r, e) {
|
|
1425
|
+
const s = i.createShader(t);
|
|
1426
|
+
if (i.shaderSource(s, r), i.compileShader(s), e && !i.getShaderParameter(s, i.COMPILE_STATUS)) {
|
|
1427
|
+
const o = i.getShaderInfoLog(s);
|
|
1428
|
+
throw i.deleteShader(s), new Error(`Shader compilation failed: ${o}`);
|
|
1429
|
+
}
|
|
1430
|
+
return s;
|
|
1431
|
+
}
|
|
1432
|
+
function fe(i, t, r, e) {
|
|
1433
|
+
const s = i.createProgram();
|
|
1434
|
+
if (i.attachShader(s, t), i.attachShader(s, r), i.linkProgram(s), e && !i.getProgramParameter(s, i.LINK_STATUS)) {
|
|
1435
|
+
const o = i.getProgramInfoLog(s);
|
|
1436
|
+
throw i.deleteProgram(s), new Error(`Program linking failed: ${o}`);
|
|
1437
|
+
}
|
|
1438
|
+
return s;
|
|
1439
|
+
}
|
|
1440
|
+
class de {
|
|
1441
|
+
#e;
|
|
1442
|
+
#l;
|
|
1443
|
+
#T = [];
|
|
1444
|
+
#h = !1;
|
|
1445
|
+
#f = !1;
|
|
1446
|
+
#g = 0;
|
|
1447
|
+
#d;
|
|
1448
|
+
#p = !1;
|
|
1449
|
+
// Cached temporary resources for encodeTexture
|
|
1450
|
+
#a = null;
|
|
1451
|
+
#E = 0;
|
|
1452
|
+
#s = null;
|
|
1453
|
+
// For 8-byte per block formats
|
|
1454
|
+
#i = null;
|
|
1455
|
+
// For 16-byte per block formats
|
|
1456
|
+
#n = 0;
|
|
1457
|
+
#_ = 0;
|
|
1458
|
+
#u = null;
|
|
1459
|
+
constructor(t, r = {}) {
|
|
1460
|
+
if (!t)
|
|
1461
|
+
throw new Error("WebGL2 context is required");
|
|
1462
|
+
this.#e = t, this.#h = r.verbose ?? !1, this.#f = r.validateShaders ?? !1, this.#p = r.cacheTempResources ?? !1, this.#l = We(t, this.#h), r.preload && this.#m(r.preload);
|
|
1463
|
+
}
|
|
1464
|
+
dispose() {
|
|
1465
|
+
const t = this.#e;
|
|
1466
|
+
this.#d && t.deleteShader(this.#d);
|
|
1467
|
+
for (const r of this.#T)
|
|
1468
|
+
t.deleteProgram(r);
|
|
1469
|
+
this.freeTempResources();
|
|
1470
|
+
}
|
|
1471
|
+
/**
|
|
1472
|
+
* Initialize the encoder by detecting available compression formats.
|
|
1473
|
+
* @param {WebGL2RenderingContext} gl - WebGL2 context.
|
|
1474
|
+
* @param {Object} options - Encoder options.
|
|
1475
|
+
* @param {boolean|string[]} options.preload - Whether to preload all encoder pipelines, or an array of format names to preload (false by default).
|
|
1476
|
+
* @param {boolean} options.verbose - Whether to enable verbose logging (false by default).
|
|
1477
|
+
* @param {boolean} options.cacheTempResources - Whether to cache temporary resources for reuse across encodeTexture calls (false by default).
|
|
1478
|
+
* @returns {SparkGL} A new SparkGL instance.
|
|
1479
|
+
*/
|
|
1480
|
+
static create(t, r = {}) {
|
|
1481
|
+
return new de(t, r);
|
|
1482
|
+
}
|
|
1483
|
+
#t(...t) {
|
|
1484
|
+
this.#h && console.log(...t);
|
|
1485
|
+
}
|
|
1486
|
+
#o(t) {
|
|
1487
|
+
this.#h && console.time(t);
|
|
1488
|
+
}
|
|
1489
|
+
#c(t) {
|
|
1490
|
+
this.#h && console.timeEnd(t);
|
|
1491
|
+
}
|
|
1492
|
+
async #m(t) {
|
|
1493
|
+
let r;
|
|
1494
|
+
Array.isArray(t) ? r = t.map((e) => this.#b(e, !1)) : r = this.#l;
|
|
1495
|
+
for (const e of r)
|
|
1496
|
+
e !== void 0 && !this.#T[e] && this.#x(e).catch((s) => {
|
|
1497
|
+
console.error(`Failed to preload program for format ${v[e]}:`, s);
|
|
1498
|
+
});
|
|
1499
|
+
}
|
|
1500
|
+
getSupportedFormats() {
|
|
1501
|
+
return Array.from(this.#l).map((t) => v[t]).filter(Boolean);
|
|
1502
|
+
}
|
|
1503
|
+
isFormatSupported(t) {
|
|
1504
|
+
const r = typeof t == "string" ? H[t] : t;
|
|
1505
|
+
return this.#l.has(r);
|
|
1506
|
+
}
|
|
1507
|
+
/**
|
|
1508
|
+
* Free cached temporary resources used by encodeTexture.
|
|
1509
|
+
* Call this when you're done encoding textures to free up GPU memory.
|
|
1510
|
+
*/
|
|
1511
|
+
freeTempResources() {
|
|
1512
|
+
const t = this.#e;
|
|
1513
|
+
this.#a && (t.deleteBuffer(this.#a), this.#a = null, this.#E = 0), this.#s && (t.deleteTexture(this.#s), this.#s = null), this.#i && (t.deleteTexture(this.#i), this.#i = null), this.#u && (t.deleteFramebuffer(this.#u), this.#u = null), this.#n = 0, this.#_ = 0;
|
|
1514
|
+
}
|
|
1515
|
+
#B(t) {
|
|
1516
|
+
return this.#l.has(t);
|
|
1517
|
+
}
|
|
1518
|
+
#b(t, r = !1) {
|
|
1519
|
+
const e = H[t];
|
|
1520
|
+
if (e != null && this.#B(e))
|
|
1521
|
+
return e;
|
|
1522
|
+
const s = r ? ["bc4-r", "eac-r", "bc5-rg", "eac-rg", "bc1-rgb", "etc2-rgb", "bc7-rgb", "astc-rgb", "astc-4x4-rgb", "bc7-rgba", "astc-rgba", "astc-4x4-rgba"] : ["bc4-r", "eac-r", "bc5-rg", "eac-rg", "bc7-rgb", "astc-rgb", "astc-4x4-rgb", "bc1-rgb", "etc2-rgb", "bc7-rgba", "astc-rgba", "astc-4x4-rgba"];
|
|
1523
|
+
for (const o of s)
|
|
1524
|
+
if (o.includes(t) && this.#B(H[o]))
|
|
1525
|
+
return H[o];
|
|
1526
|
+
}
|
|
1527
|
+
#x(t) {
|
|
1528
|
+
if (this.#T[t])
|
|
1529
|
+
return this.#T[t];
|
|
1530
|
+
const r = (async () => {
|
|
1531
|
+
const e = "Loading program for format: " + v[t];
|
|
1532
|
+
this.#o(e);
|
|
1533
|
+
const s = this.#e, o = Me[t];
|
|
1534
|
+
this.#d || (this.#d = q(s, s.VERTEX_SHADER, Y, this.#f));
|
|
1535
|
+
const c = await ze(o), n = q(s, s.FRAGMENT_SHADER, c, this.#f), f = fe(s, this.#d, n, this.#f);
|
|
1536
|
+
return s.deleteShader(n), this.#c(e), f;
|
|
1537
|
+
})();
|
|
1538
|
+
return this.#T[t] = r, r;
|
|
1539
|
+
}
|
|
1540
|
+
async encodeTexture(t, r = {}) {
|
|
1541
|
+
const e = this.#e;
|
|
1542
|
+
typeof t == "string" && (t = await K(t)), this.#t(`Image type: ${t.constructor.name}`);
|
|
1543
|
+
const s = t.width || t.videoWidth, o = t.height || t.videoHeight;
|
|
1544
|
+
O(s && o);
|
|
1545
|
+
const c = r.format ?? "rgb";
|
|
1546
|
+
let n;
|
|
1547
|
+
if (typeof c == "string") {
|
|
1548
|
+
if (n = this.#b(c, r.preferLowQuality), n === void 0)
|
|
1549
|
+
throw new Error(`Unsupported format: ${c}`);
|
|
1550
|
+
} else if (n = c, !this.#l.has(n))
|
|
1551
|
+
throw new Error(`Format not supported: ${v[n]}`);
|
|
1552
|
+
const f = await this.#x(n);
|
|
1553
|
+
this.#t(`Selected format: ${v[n]}`);
|
|
1554
|
+
const u = Le[n], l = (r.srgb || r.format?.endsWith("srgb")) && De[n], h = Oe[n], m = h ? l ? h[1] : h[0] : null, R = Ve[n];
|
|
1555
|
+
this.#t(`Using ${l ? "sRGB" : "linear"} color space`);
|
|
1556
|
+
const T = `encodeTexture #${++this.#g}`;
|
|
1557
|
+
this.#o(T);
|
|
1558
|
+
const d = {
|
|
1559
|
+
program: e.getParameter(e.CURRENT_PROGRAM),
|
|
1560
|
+
activeTexture: e.getParameter(e.ACTIVE_TEXTURE),
|
|
1561
|
+
textureBinding: e.getParameter(e.TEXTURE_BINDING_2D),
|
|
1562
|
+
framebuffer: e.getParameter(e.FRAMEBUFFER_BINDING),
|
|
1563
|
+
readFramebuffer: e.getParameter(e.READ_FRAMEBUFFER_BINDING),
|
|
1564
|
+
viewport: e.getParameter(e.VIEWPORT),
|
|
1565
|
+
blend: e.getParameter(e.BLEND),
|
|
1566
|
+
depthTest: e.getParameter(e.DEPTH_TEST),
|
|
1567
|
+
stencilTest: e.getParameter(e.STENCIL_TEST),
|
|
1568
|
+
cullFace: e.getParameter(e.CULL_FACE),
|
|
1569
|
+
scissorTest: e.getParameter(e.SCISSOR_TEST),
|
|
1570
|
+
pixelPackBuffer: e.getParameter(e.PIXEL_PACK_BUFFER_BINDING),
|
|
1571
|
+
pixelUnpackBuffer: e.getParameter(e.PIXEL_UNPACK_BUFFER_BINDING),
|
|
1572
|
+
arrayBuffer: e.getParameter(e.ARRAY_BUFFER_BINDING),
|
|
1573
|
+
vertexArray: e.getParameter(e.VERTEX_ARRAY_BINDING)
|
|
1574
|
+
};
|
|
1575
|
+
e.activeTexture(e.TEXTURE0), e.disable(e.BLEND), e.disable(e.DEPTH_TEST), e.disable(e.STENCIL_TEST), e.disable(e.CULL_FACE), e.disable(e.SCISSOR_TEST);
|
|
1576
|
+
const V = r.wrap || "repeat";
|
|
1577
|
+
let x;
|
|
1578
|
+
switch (V) {
|
|
1579
|
+
case "repeat":
|
|
1580
|
+
x = e.REPEAT;
|
|
1581
|
+
break;
|
|
1582
|
+
case "mirror":
|
|
1583
|
+
x = e.MIRRORED_REPEAT;
|
|
1584
|
+
break;
|
|
1585
|
+
case "clamp":
|
|
1586
|
+
default:
|
|
1587
|
+
x = e.CLAMP_TO_EDGE;
|
|
1588
|
+
break;
|
|
1589
|
+
}
|
|
1590
|
+
const y = r.generateMipmaps || r.mips;
|
|
1591
|
+
let S = 1;
|
|
1592
|
+
if (y) {
|
|
1593
|
+
let w = s, I = o;
|
|
1594
|
+
for (; w > 4 || I > 4; )
|
|
1595
|
+
S++, w = Math.max(1, Math.floor(w / 2)), I = Math.max(1, Math.floor(I / 2));
|
|
1596
|
+
}
|
|
1597
|
+
const _ = e.createTexture();
|
|
1598
|
+
e.bindTexture(e.TEXTURE_2D, _), e.texParameteri(e.TEXTURE_2D, e.TEXTURE_MIN_FILTER, e.NEAREST), e.texParameteri(e.TEXTURE_2D, e.TEXTURE_MAG_FILTER, e.NEAREST), e.texParameteri(e.TEXTURE_2D, e.TEXTURE_WRAP_S, x), e.texParameteri(e.TEXTURE_2D, e.TEXTURE_WRAP_T, x), e.texParameteri(e.TEXTURE_2D, e.TEXTURE_MAX_LEVEL, 0), e.texImage2D(e.TEXTURE_2D, 0, e.RGBA8, s, o, 0, e.RGBA, e.UNSIGNED_BYTE, t);
|
|
1599
|
+
let E = _;
|
|
1600
|
+
if (r.flipY) {
|
|
1601
|
+
this.#t("Flipping texture vertically");
|
|
1602
|
+
const G = e.createTexture();
|
|
1603
|
+
e.bindTexture(e.TEXTURE_2D, G), e.texParameteri(e.TEXTURE_2D, e.TEXTURE_MIN_FILTER, e.NEAREST), e.texParameteri(e.TEXTURE_2D, e.TEXTURE_MAG_FILTER, e.NEAREST), e.texParameteri(e.TEXTURE_2D, e.TEXTURE_WRAP_S, x), e.texParameteri(e.TEXTURE_2D, e.TEXTURE_WRAP_T, x), e.texStorage2D(e.TEXTURE_2D, 1, e.RGBA8, s, o);
|
|
1604
|
+
const w = e.createFramebuffer();
|
|
1605
|
+
e.bindFramebuffer(e.FRAMEBUFFER, w), e.framebufferTexture2D(e.FRAMEBUFFER, e.COLOR_ATTACHMENT0, e.TEXTURE_2D, G, 0), this.#d || (this.#d = q(e, e.VERTEX_SHADER, Y, this.#f));
|
|
1606
|
+
const I = `#version 300 es
|
|
1607
|
+
precision mediump float;
|
|
1608
|
+
uniform sampler2D uTexture;
|
|
1609
|
+
uniform ivec2 uTextureSize;
|
|
1610
|
+
out vec4 fragColor;
|
|
1611
|
+
void main() {
|
|
1612
|
+
ivec2 coord = ivec2(gl_FragCoord.xy);
|
|
1613
|
+
// Flip Y coordinate
|
|
1614
|
+
coord.y = uTextureSize.y - 1 - coord.y;
|
|
1615
|
+
fragColor = texelFetch(uTexture, coord, 0);
|
|
1616
|
+
}`, F = e.createShader(e.VERTEX_SHADER);
|
|
1617
|
+
e.shaderSource(F, Y), e.compileShader(F);
|
|
1618
|
+
const M = e.createShader(e.FRAGMENT_SHADER);
|
|
1619
|
+
e.shaderSource(M, I), e.compileShader(M);
|
|
1620
|
+
const D = fe(e, F, M, this.#f);
|
|
1621
|
+
e.useProgram(D), e.viewport(0, 0, s, o), e.activeTexture(e.TEXTURE0), e.bindTexture(e.TEXTURE_2D, _), e.uniform1i(e.getUniformLocation(D, "uTexture"), 0), e.uniform2i(e.getUniformLocation(D, "uTextureSize"), s, o), e.drawArrays(e.TRIANGLES, 0, 3), e.deleteShader(F), e.deleteShader(M), e.deleteProgram(D), e.deleteFramebuffer(w), e.deleteTexture(_), E = G;
|
|
1622
|
+
}
|
|
1623
|
+
y && (e.bindTexture(e.TEXTURE_2D, E), e.texParameteri(e.TEXTURE_2D, e.TEXTURE_MIN_FILTER, e.LINEAR_MIPMAP_LINEAR), e.texParameteri(e.TEXTURE_2D, e.TEXTURE_MAX_LEVEL, S - 1), e.generateMipmap(e.TEXTURE_2D), this.#t(`Generated ${S} mipmap levels`));
|
|
1624
|
+
const P = e.createTexture();
|
|
1625
|
+
e.bindTexture(e.TEXTURE_2D, P), e.texStorage2D(e.TEXTURE_2D, S, m, s, o), y ? (e.texParameteri(e.TEXTURE_2D, e.TEXTURE_MIN_FILTER, e.LINEAR_MIPMAP_LINEAR), e.texParameteri(e.TEXTURE_2D, e.TEXTURE_MAG_FILTER, e.LINEAR)) : (e.texParameteri(e.TEXTURE_2D, e.TEXTURE_MIN_FILTER, e.LINEAR), e.texParameteri(e.TEXTURE_2D, e.TEXTURE_MAG_FILTER, e.LINEAR)), e.texParameteri(e.TEXTURE_2D, e.TEXTURE_WRAP_S, x), e.texParameteri(e.TEXTURE_2D, e.TEXTURE_WRAP_T, x);
|
|
1626
|
+
const Q = Math.ceil(s / 4), W = Math.ceil(o / 4), C = u * Q * W;
|
|
1627
|
+
let k = C;
|
|
1628
|
+
const b = this.#p;
|
|
1629
|
+
let U;
|
|
1630
|
+
b && this.#a && this.#E >= C ? U = this.#a : (b && this.#a && e.deleteBuffer(this.#a), U = e.createBuffer(), b && (this.#a = U, this.#E = C)), e.bindBuffer(e.PIXEL_PACK_BUFFER, U), e.bindBuffer(e.PIXEL_UNPACK_BUFFER, U), e.bufferData(e.PIXEL_PACK_BUFFER, C, e.STREAM_COPY);
|
|
1631
|
+
let B;
|
|
1632
|
+
const g = !b || this.#n < s || this.#_ < o;
|
|
1633
|
+
u === 8 ? b && this.#s && !g ? B = this.#s : (b && this.#s && e.deleteTexture(this.#s), B = e.createTexture(), e.bindTexture(e.TEXTURE_2D, B), e.texStorage2D(e.TEXTURE_2D, 1, R, s, o), b && (this.#s = B, this.#n = s, this.#_ = o)) : b && this.#i && !g ? B = this.#i : (b && this.#i && e.deleteTexture(this.#i), B = e.createTexture(), e.bindTexture(e.TEXTURE_2D, B), e.texStorage2D(e.TEXTURE_2D, 1, R, s, o), b && (this.#i = B, this.#n = s, this.#_ = o));
|
|
1634
|
+
let L;
|
|
1635
|
+
b && this.#u ? L = this.#u : (L = e.createFramebuffer(), b && (this.#u = L)), e.bindFramebuffer(e.FRAMEBUFFER, L), e.readBuffer(e.COLOR_ATTACHMENT0), e.framebufferTexture2D(e.FRAMEBUFFER, e.COLOR_ATTACHMENT0, e.TEXTURE_2D, B, 0), e.useProgram(f);
|
|
1636
|
+
for (let G = 0; G < S; G++) {
|
|
1637
|
+
const w = Math.max(1, Math.floor(s >> G)), I = Math.max(1, Math.floor(o >> G)), F = Math.ceil(w / 4), M = Math.ceil(I / 4), D = u * F * M;
|
|
1638
|
+
k += D, e.bindTexture(e.TEXTURE_2D, E), e.texParameteri(e.TEXTURE_2D, e.TEXTURE_BASE_LEVEL, G), e.texParameteri(e.TEXTURE_2D, e.TEXTURE_MAX_LEVEL, G), e.viewport(0, 0, F, M), e.drawArrays(e.TRIANGLES, 0, 3), e.readPixels(0, 0, F, M, e.RGBA_INTEGER, u === 16 ? e.UNSIGNED_INT : e.UNSIGNED_SHORT, 0), e.bindTexture(e.TEXTURE_2D, P), e.compressedTexSubImage2D(e.TEXTURE_2D, G, 0, 0, w, I, m, D, 0);
|
|
1639
|
+
}
|
|
1640
|
+
return b || (e.deleteTexture(B), e.deleteBuffer(U), e.deleteFramebuffer(L)), e.deleteTexture(E), e.bindFramebuffer(e.FRAMEBUFFER, d.framebuffer), e.bindFramebuffer(e.READ_FRAMEBUFFER, d.readFramebuffer), e.bindTexture(e.TEXTURE_2D, d.textureBinding), e.useProgram(d.program), e.activeTexture(d.activeTexture), e.viewport(d.viewport[0], d.viewport[1], d.viewport[2], d.viewport[3]), e.bindBuffer(e.PIXEL_PACK_BUFFER, d.pixelPackBuffer), e.bindBuffer(e.PIXEL_UNPACK_BUFFER, d.pixelUnpackBuffer), d.blend ? e.enable(e.BLEND) : e.disable(e.BLEND), d.depthTest ? e.enable(e.DEPTH_TEST) : e.disable(e.DEPTH_TEST), d.stencilTest ? e.enable(e.STENCIL_TEST) : e.disable(e.STENCIL_TEST), d.cullFace ? e.enable(e.CULL_FACE) : e.disable(e.CULL_FACE), d.scissorTest ? e.enable(e.SCISSOR_TEST) : e.disable(e.SCISSOR_TEST), e.bindBuffer(e.ARRAY_BUFFER, d.arrayBuffer), e.bindVertexArray(d.vertexArray), this.#c(T), {
|
|
1641
|
+
texture: P,
|
|
1642
|
+
width: s,
|
|
1643
|
+
height: o,
|
|
1644
|
+
format: m,
|
|
1645
|
+
sparkFormat: n,
|
|
1646
|
+
sparkFormatName: v[n],
|
|
1647
|
+
srgb: l,
|
|
1648
|
+
mipmapCount: S,
|
|
1649
|
+
byteLength: k
|
|
1650
|
+
};
|
|
1131
1651
|
}
|
|
1132
1652
|
}
|
|
1133
1653
|
export {
|
|
1134
|
-
|
|
1654
|
+
me as Spark,
|
|
1655
|
+
de as SparkGL
|
|
1135
1656
|
};
|