gputex 0.0.5 → 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 +35 -4
- package/dist/index.d.ts +226 -5
- package/dist/index.js +745 -143
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# GPUtex
|
|
2
2
|
|
|
3
|
-
Runtime GPU texture compression via WebGPU compute shaders. Feed it a PNG/JPG/WebP/AVIF and get back a GPU-compressed texture (BC7, BC5, ASTC 4x4, or BC1) ready for Three.js or React Three Fiber.
|
|
3
|
+
Runtime GPU texture compression via WebGPU compute shaders, with a WebGL2 fragment-shader fallback. Feed it a PNG/JPG/WebP/AVIF and get back a GPU-compressed texture (BC7, BC5, ASTC 4x4, or BC1) ready for Three.js or React Three Fiber.
|
|
4
4
|
|
|
5
5
|
⚠️: This is 100% vibe-coded. The code is completely unreviewed, under-tested, it will probably crash on many devices, and this library is very likely to go unmaintained. Do not use for anything important.
|
|
6
6
|
|
|
@@ -27,6 +27,18 @@ bun add gputex
|
|
|
27
27
|
|
|
28
28
|
Format selection is automatic: BC7/BC5 on desktop, ASTC on mobile, uncompressed RGBA8 fallback otherwise.
|
|
29
29
|
|
|
30
|
+
## WebGL fallback
|
|
31
|
+
|
|
32
|
+
WebGPU is the primary path. When it's unavailable (older Safari, Firefox without WebGPU, locked-down environments) `compressTexture()` automatically falls back to a **WebGL2** path that runs the same block encoders as fragment shaders — each 4×4 block is computed in one fragment, written to an `RGBA32UI` render target, and read back. The output bytes are identical to the WebGPU encoders, so the resulting `CompressedTexture` looks the same under either renderer.
|
|
33
|
+
|
|
34
|
+
The fallback chain is **WebGPU → WebGL2 → uncompressed RGBA8**. The `backend` field on the result (`'webgpu' | 'webgl' | 'none'`) tells you which path ran.
|
|
35
|
+
|
|
36
|
+
Notes on the WebGL path:
|
|
37
|
+
|
|
38
|
+
- It needs the matching WebGL2 compressed-texture extension to be sampleable: `EXT_texture_compression_bptc` (BC7), `EXT_texture_compression_rgtc` (BC5), `WEBGL_compressed_texture_astc` (ASTC), or `WEBGL_compressed_texture_s3tc` (BC1). Selection mirrors the WebGPU side, with BC1 added as a broadly-available last resort for **opaque** colour when neither BPTC nor ASTC is present.
|
|
39
|
+
- It always uses the **fast** encoders — the `quality: 'high'` option and the `device` / `adapter` options apply to the WebGPU path only.
|
|
40
|
+
- All encoding happens on one shared, off-screen WebGL2 context; nothing is drawn to a visible canvas.
|
|
41
|
+
|
|
30
42
|
## Usage
|
|
31
43
|
|
|
32
44
|
### `compressTexture` — direct API
|
|
@@ -38,11 +50,28 @@ const { texture, format } = await compressTexture('/cobblestone.avif', {
|
|
|
38
50
|
hint: 'color', // 'color' | 'colorWithAlpha' | 'normal'
|
|
39
51
|
colorSpace: 'srgb',
|
|
40
52
|
mipmaps: true,
|
|
53
|
+
quality: 'fast', // 'fast' (default) | 'high'
|
|
41
54
|
})
|
|
42
55
|
|
|
43
56
|
material.map = texture
|
|
44
57
|
```
|
|
45
58
|
|
|
59
|
+
#### Quality
|
|
60
|
+
|
|
61
|
+
`quality` trades encode speed against compression accuracy:
|
|
62
|
+
|
|
63
|
+
- **`'fast'` (default)** — a bounding-box endpoint seed plus projection-based
|
|
64
|
+
index assignment (each pixel is projected onto the colinear endpoint line in
|
|
65
|
+
O(1) instead of searching every palette entry) with a single fused
|
|
66
|
+
least-squares refit. On GPUs that report the `shader-f16` feature the whole
|
|
67
|
+
fast path runs in f16 (≈2× on Apple) — the f32 path is the automatic
|
|
68
|
+
fallback. Net vs `'high'` on an Apple GPU: **BC7 ~50×**, **ASTC ~9×**,
|
|
69
|
+
**BC5 ~5×** faster, for a PSNR cost of **≤0.45 dB** (imperceptible). BC1 is
|
|
70
|
+
single-pass and unaffected.
|
|
71
|
+
- **`'high'`** — exhaustive endpoint search (farthest-pair seed, full nearest
|
|
72
|
+
search, p-bit search); output is byte-for-byte identical to the CPU reference
|
|
73
|
+
encoders.
|
|
74
|
+
|
|
46
75
|
### `GputexLoader` — Three.js Loader
|
|
47
76
|
|
|
48
77
|
```ts
|
|
@@ -154,9 +183,11 @@ encoder.destroy()
|
|
|
154
183
|
|
|
155
184
|
## Requirements
|
|
156
185
|
|
|
157
|
-
-
|
|
158
|
-
-
|
|
159
|
-
-
|
|
186
|
+
- WebGPU (primary) **or** WebGL2 (fallback) — almost every current browser has at least one
|
|
187
|
+
- A compressed-texture capability for compressed output:
|
|
188
|
+
- WebGPU: `texture-compression-bc` (desktop) or `texture-compression-astc` (mobile)
|
|
189
|
+
- WebGL2: `EXT_texture_compression_bptc` / `_rgtc`, `WEBGL_compressed_texture_astc`, or `WEBGL_compressed_texture_s3tc`
|
|
190
|
+
- Falls back to uncompressed RGBA8 when no compressed format is available on either backend
|
|
160
191
|
|
|
161
192
|
## Device-specific workarounds
|
|
162
193
|
|
package/dist/index.d.ts
CHANGED
|
@@ -45,9 +45,18 @@ interface EncoderOptions {
|
|
|
45
45
|
adapter?: GPUAdapter;
|
|
46
46
|
ownsDevice?: boolean;
|
|
47
47
|
}
|
|
48
|
+
/**
|
|
49
|
+
* Encoder quality level. 'fast' (default) uses the cheaper search paths in the
|
|
50
|
+
* shaders — measured ~2–4× faster for ≤0.36 dB PSNR. 'high' runs the exhaustive
|
|
51
|
+
* search, producing output byte-identical to the CPU reference encoders.
|
|
52
|
+
* No effect on BC1 (already single-pass; both levels are identical).
|
|
53
|
+
*/
|
|
54
|
+
type EncodeQuality = 'fast' | 'high';
|
|
48
55
|
interface EncodeCallOptions {
|
|
49
56
|
/** Tags the output color space. Forced 'linear' for encoders with supportsSrgb=false. */
|
|
50
57
|
colorSpace?: 'srgb' | 'linear';
|
|
58
|
+
/** Encode quality / speed trade-off. Default 'fast'. */
|
|
59
|
+
quality?: EncodeQuality;
|
|
51
60
|
}
|
|
52
61
|
interface EncodeResult {
|
|
53
62
|
width: number;
|
|
@@ -110,9 +119,18 @@ declare abstract class Encoder {
|
|
|
110
119
|
readonly adapter?: GPUAdapter;
|
|
111
120
|
readonly ownsDevice: boolean;
|
|
112
121
|
protected _module: GPUShaderModule;
|
|
122
|
+
protected _moduleF16: GPUShaderModule | null;
|
|
123
|
+
protected _pipelineF16: GPUComputePipeline | null;
|
|
113
124
|
protected _pipeline: GPUComputePipeline;
|
|
125
|
+
protected _pipelineCache: Map<EncodeQuality, GPUComputePipeline>;
|
|
114
126
|
constructor({ device, adapter, ownsDevice }: EncoderOptions);
|
|
115
127
|
protected _buildPipeline(): void;
|
|
128
|
+
/**
|
|
129
|
+
* Pipeline for a given quality level. Encoders that don't declare a
|
|
130
|
+
* `QUALITY_HIGH` override (`supportsQuality === false`, e.g. BC1) ignore the
|
|
131
|
+
* argument and reuse the single pipeline. Specialised pipelines are cached.
|
|
132
|
+
*/
|
|
133
|
+
protected _getPipeline(quality: EncodeQuality): GPUComputePipeline;
|
|
116
134
|
destroy(): void;
|
|
117
135
|
/** Short lowercase identifier used in GPU object labels and errors. */
|
|
118
136
|
abstract get label(): string;
|
|
@@ -122,6 +140,20 @@ declare abstract class Encoder {
|
|
|
122
140
|
get workgroupSize(): readonly [number, number, number];
|
|
123
141
|
/** Whether this format has an sRGB variant. Default true. */
|
|
124
142
|
get supportsSrgb(): boolean;
|
|
143
|
+
/**
|
|
144
|
+
* Whether the shader declares a `QUALITY_HIGH` pipeline-overridable constant
|
|
145
|
+
* (i.e. has distinct fast/high search paths). BC1 is already single-pass and
|
|
146
|
+
* leaves this false; BC5/BC7/ASTC override it to true.
|
|
147
|
+
*/
|
|
148
|
+
get supportsQuality(): boolean;
|
|
149
|
+
/**
|
|
150
|
+
* Optional f16 WGSL for the 'fast' path. Used only when the device reports the
|
|
151
|
+
* `shader-f16` feature; the format's f32 `wgslSource()` is the fallback and
|
|
152
|
+
* `'high'` always uses it. Returns null when there's no f16 variant (BC1).
|
|
153
|
+
*/
|
|
154
|
+
wgslSourceFastF16(): string | null;
|
|
155
|
+
/** Whether the f16 fast path is both available and supported on this device. */
|
|
156
|
+
protected get _useF16(): boolean;
|
|
125
157
|
/** WGSL compute-shader source. */
|
|
126
158
|
abstract wgslSource(): string;
|
|
127
159
|
/** e.g. 'bc1-rgba-unorm-srgb'. */
|
|
@@ -134,7 +166,7 @@ declare abstract class Encoder {
|
|
|
134
166
|
* whether the result can actually be sampled.
|
|
135
167
|
*/
|
|
136
168
|
get supportsSampling(): boolean;
|
|
137
|
-
encode(source: EncoderImageSource, { colorSpace }?: EncodeCallOptions): Promise<EncodeResult>;
|
|
169
|
+
encode(source: EncoderImageSource, { colorSpace, quality }?: EncodeCallOptions): Promise<EncodeResult>;
|
|
138
170
|
/**
|
|
139
171
|
* Encode one image source to raw compressed bytes, skipping the
|
|
140
172
|
* `CompressedTexture` wrap. Used by the public `encode()` above and by
|
|
@@ -145,8 +177,9 @@ declare abstract class Encoder {
|
|
|
145
177
|
* encoder boundary. Still safe to call from outside — it just does
|
|
146
178
|
* less work than `encode()` and the caller assembles the texture.
|
|
147
179
|
*/
|
|
148
|
-
encodeToBytes(source: EncoderImageSource, { flipY }?: {
|
|
180
|
+
encodeToBytes(source: EncoderImageSource, { flipY, quality }?: {
|
|
149
181
|
flipY?: boolean;
|
|
182
|
+
quality?: EncodeQuality;
|
|
150
183
|
}): Promise<EncodeBytesResult>;
|
|
151
184
|
/**
|
|
152
185
|
* Assemble a `CompressedTexture` from pre-encoded mip levels. Called
|
|
@@ -178,7 +211,9 @@ declare class BC5Encoder extends Encoder {
|
|
|
178
211
|
get label(): string;
|
|
179
212
|
get bytesPerBlock(): number;
|
|
180
213
|
get supportsSrgb(): boolean;
|
|
214
|
+
get supportsQuality(): boolean;
|
|
181
215
|
wgslSource(): string;
|
|
216
|
+
wgslSourceFastF16(): string;
|
|
182
217
|
gpuTextureFormat(): GPUTextureFormat;
|
|
183
218
|
threeTextureFormat(): CompressedPixelFormat;
|
|
184
219
|
}
|
|
@@ -189,7 +224,9 @@ declare class BC7Encoder extends Encoder {
|
|
|
189
224
|
get label(): string;
|
|
190
225
|
get bytesPerBlock(): number;
|
|
191
226
|
get supportsSrgb(): boolean;
|
|
227
|
+
get supportsQuality(): boolean;
|
|
192
228
|
wgslSource(): string;
|
|
229
|
+
wgslSourceFastF16(): string;
|
|
193
230
|
gpuTextureFormat({ colorSpace }: FormatVariant): GPUTextureFormat;
|
|
194
231
|
threeTextureFormat(): CompressedPixelFormat;
|
|
195
232
|
}
|
|
@@ -200,11 +237,170 @@ declare class ASTC4x4Encoder extends Encoder {
|
|
|
200
237
|
get label(): string;
|
|
201
238
|
get bytesPerBlock(): number;
|
|
202
239
|
get supportsSrgb(): boolean;
|
|
240
|
+
get supportsQuality(): boolean;
|
|
203
241
|
wgslSource(): string;
|
|
242
|
+
wgslSourceFastF16(): string;
|
|
204
243
|
gpuTextureFormat({ colorSpace }: FormatVariant): GPUTextureFormat;
|
|
205
244
|
threeTextureFormat(): CompressedPixelFormat;
|
|
206
245
|
}
|
|
207
246
|
|
|
247
|
+
/** One encoded mip level. The fields both encoder backends already produce. */
|
|
248
|
+
interface EncodedLevel {
|
|
249
|
+
/** Logical (pre-padding) dimensions, surfaced on the texture's userData. */
|
|
250
|
+
width: number;
|
|
251
|
+
height: number;
|
|
252
|
+
/** Block-aligned dimensions the compressed `data` actually covers. */
|
|
253
|
+
paddedWidth: number;
|
|
254
|
+
paddedHeight: number;
|
|
255
|
+
data: Uint8Array;
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
/** Raw RGBA8 pixel data (e.g. a CPU-generated mip level). */
|
|
259
|
+
interface RawPixelSource {
|
|
260
|
+
data: ArrayBufferView;
|
|
261
|
+
width: number;
|
|
262
|
+
height: number;
|
|
263
|
+
}
|
|
264
|
+
/** Anything the WebGL encoders can upload as the source image. */
|
|
265
|
+
type WebGLEncoderImageSource = ImageBitmap | ImageData | HTMLImageElement | HTMLCanvasElement | OffscreenCanvas | RawPixelSource;
|
|
266
|
+
interface WebGLEncodeBytesResult {
|
|
267
|
+
width: number;
|
|
268
|
+
height: number;
|
|
269
|
+
paddedWidth: number;
|
|
270
|
+
paddedHeight: number;
|
|
271
|
+
data: Uint8Array;
|
|
272
|
+
encodeMs: number;
|
|
273
|
+
}
|
|
274
|
+
interface WebGLEncoderOptions {
|
|
275
|
+
gl: WebGL2RenderingContext;
|
|
276
|
+
}
|
|
277
|
+
/**
|
|
278
|
+
* Constructor shape for the concrete subclasses; lets the static `create()`
|
|
279
|
+
* narrow its return type to the subclass (as the WebGPU `EncoderConstructor`
|
|
280
|
+
* does).
|
|
281
|
+
*/
|
|
282
|
+
type WebGLEncoderConstructor<T extends WebGLBlockEncoder = WebGLBlockEncoder> = {
|
|
283
|
+
new (opts: WebGLEncoderOptions): T;
|
|
284
|
+
create(gl?: WebGL2RenderingContext | null): T;
|
|
285
|
+
};
|
|
286
|
+
declare abstract class WebGLBlockEncoder {
|
|
287
|
+
/**
|
|
288
|
+
* Create an encoder on the shared process-wide context (or a caller-supplied
|
|
289
|
+
* one). Throws when WebGL2 is unavailable. The `this:` annotation lets
|
|
290
|
+
* `BC7WebGLEncoder.create()` return `BC7WebGLEncoder`.
|
|
291
|
+
*/
|
|
292
|
+
static create<T extends WebGLBlockEncoder>(this: WebGLEncoderConstructor<T>, gl?: WebGL2RenderingContext | null): T;
|
|
293
|
+
readonly gl: WebGL2RenderingContext;
|
|
294
|
+
protected _program: WebGLProgram;
|
|
295
|
+
protected _vao: WebGLVertexArrayObject;
|
|
296
|
+
protected _uSrc: WebGLUniformLocation | null;
|
|
297
|
+
protected _uSrcSize: WebGLUniformLocation | null;
|
|
298
|
+
protected _uFlipY: WebGLUniformLocation | null;
|
|
299
|
+
constructor({ gl }: WebGLEncoderOptions);
|
|
300
|
+
/** Short lowercase identifier for labels / errors. */
|
|
301
|
+
abstract get label(): string;
|
|
302
|
+
/** 8 for BC1, 16 for BC5/BC7/ASTC 4×4. */
|
|
303
|
+
abstract get bytesPerBlock(): number;
|
|
304
|
+
/** Whether this format has an sRGB variant (false for BC5). */
|
|
305
|
+
abstract get supportsSrgb(): boolean;
|
|
306
|
+
/** GLSL ES 3.00 fragment-shader source. */
|
|
307
|
+
abstract fragSource(): string;
|
|
308
|
+
/** Three.js `CompressedPixelFormat` constant; sRGB is carried by colorSpace. */
|
|
309
|
+
abstract threeTextureFormat(): CompressedPixelFormat;
|
|
310
|
+
protected _buildProgram(): void;
|
|
311
|
+
/** Release the GL program + VAO. The shared context itself is left intact. */
|
|
312
|
+
destroy(): void;
|
|
313
|
+
/**
|
|
314
|
+
* Upload the source image to a freshly created RGBA8 texture bound on unit 0.
|
|
315
|
+
* Raw pixel sources (ImageData / mip levels) go through the typed-array
|
|
316
|
+
* overload; DOM sources (ImageBitmap / canvas / image) through the element
|
|
317
|
+
* overload. No flip / premultiply / colour conversion — flipY is applied in
|
|
318
|
+
* the shader so each mip level flips by its own height.
|
|
319
|
+
*/
|
|
320
|
+
protected _uploadSource(source: WebGLEncoderImageSource, width: number, height: number): WebGLTexture;
|
|
321
|
+
/**
|
|
322
|
+
* Encode one image source to raw compressed bytes. `flipY` samples the source
|
|
323
|
+
* bottom-up (matching Three.js's convention) and is applied in the shader;
|
|
324
|
+
* the high-level mipped path bakes the flip into level 0 and passes false.
|
|
325
|
+
*/
|
|
326
|
+
encodeToBytes(source: WebGLEncoderImageSource, { flipY }?: {
|
|
327
|
+
flipY?: boolean;
|
|
328
|
+
}): WebGLEncodeBytesResult;
|
|
329
|
+
/** Wrap pre-encoded levels into a CompressedTexture. Shared with the WebGPU path. */
|
|
330
|
+
buildMippedTexture(levels: readonly EncodedLevel[], { colorSpace }?: {
|
|
331
|
+
colorSpace?: 'srgb' | 'linear';
|
|
332
|
+
}): CompressedTexture;
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
declare class BC1WebGLEncoder extends WebGLBlockEncoder {
|
|
336
|
+
get label(): string;
|
|
337
|
+
get bytesPerBlock(): number;
|
|
338
|
+
get supportsSrgb(): boolean;
|
|
339
|
+
fragSource(): string;
|
|
340
|
+
threeTextureFormat(): CompressedPixelFormat;
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
declare class BC5WebGLEncoder extends WebGLBlockEncoder {
|
|
344
|
+
get label(): string;
|
|
345
|
+
get bytesPerBlock(): number;
|
|
346
|
+
get supportsSrgb(): boolean;
|
|
347
|
+
fragSource(): string;
|
|
348
|
+
threeTextureFormat(): CompressedPixelFormat;
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
declare class BC7WebGLEncoder extends WebGLBlockEncoder {
|
|
352
|
+
get label(): string;
|
|
353
|
+
get bytesPerBlock(): number;
|
|
354
|
+
get supportsSrgb(): boolean;
|
|
355
|
+
fragSource(): string;
|
|
356
|
+
threeTextureFormat(): CompressedPixelFormat;
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
declare class ASTC4x4WebGLEncoder extends WebGLBlockEncoder {
|
|
360
|
+
get label(): string;
|
|
361
|
+
get bytesPerBlock(): number;
|
|
362
|
+
get supportsSrgb(): boolean;
|
|
363
|
+
fragSource(): string;
|
|
364
|
+
threeTextureFormat(): CompressedPixelFormat;
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
/**
|
|
368
|
+
* Create a fresh WebGL2 context backed by an off-screen 1×1 canvas. Returns
|
|
369
|
+
* null when neither `OffscreenCanvas` nor `document` is available (e.g. a
|
|
370
|
+
* non-DOM worker without OffscreenCanvas) or when the platform has no WebGL2.
|
|
371
|
+
*/
|
|
372
|
+
declare function createWebGLContext(): WebGL2RenderingContext | null;
|
|
373
|
+
/**
|
|
374
|
+
* Lazily-created context shared across the high-level fallback path. Re-created
|
|
375
|
+
* if the previous one was lost (tab backgrounding, GPU reset). Returns null
|
|
376
|
+
* when WebGL2 is unavailable on this platform.
|
|
377
|
+
*/
|
|
378
|
+
declare function getSharedWebGLContext(): WebGL2RenderingContext | null;
|
|
379
|
+
/** True when a WebGL2 context can be created on this platform. */
|
|
380
|
+
declare function isWebGLAvailable(): boolean;
|
|
381
|
+
|
|
382
|
+
/**
|
|
383
|
+
* Minimal structural type for the extension source: only `getExtension` is
|
|
384
|
+
* touched, so tests can pass a `{ getExtension }` stub instead of a real
|
|
385
|
+
* `WebGL2RenderingContext`.
|
|
386
|
+
*/
|
|
387
|
+
interface ExtensionProvider {
|
|
388
|
+
getExtension(name: string): unknown;
|
|
389
|
+
}
|
|
390
|
+
interface WebGLCapabilities {
|
|
391
|
+
/** EXT_texture_compression_bptc → BC7 (BPTC). */
|
|
392
|
+
bptc: boolean;
|
|
393
|
+
/** EXT_texture_compression_rgtc → BC5 (RGTC2). */
|
|
394
|
+
rgtc: boolean;
|
|
395
|
+
/** WEBGL_compressed_texture_s3tc → BC1 (DXT1). */
|
|
396
|
+
s3tc: boolean;
|
|
397
|
+
/** WEBGL_compressed_texture_s3tc_srgb → sRGB DXT1 (separate extension). */
|
|
398
|
+
s3tcSrgb: boolean;
|
|
399
|
+
/** WEBGL_compressed_texture_astc → ASTC 4×4 (and other footprints). */
|
|
400
|
+
astc: boolean;
|
|
401
|
+
}
|
|
402
|
+
declare function detectWebGLCapabilities(gl: ExtensionProvider): WebGLCapabilities;
|
|
403
|
+
|
|
208
404
|
/**
|
|
209
405
|
* How the texture will be used in the renderer. Drives format choice.
|
|
210
406
|
* • 'color' — RGB albedo-like data (alpha optional / ignored).
|
|
@@ -230,6 +426,16 @@ interface FormatSelection {
|
|
|
230
426
|
}
|
|
231
427
|
declare function selectFormat(adapter: FeatureProvider, hint: TextureHint, options?: SelectFormatOptions): FormatSelection;
|
|
232
428
|
|
|
429
|
+
interface WebGLFormatSelection {
|
|
430
|
+
/** null = no compressed path available on this WebGL context. */
|
|
431
|
+
format: TextureFormat | null;
|
|
432
|
+
/** null when `format` is null. */
|
|
433
|
+
encoderClass: WebGLEncoderConstructor | null;
|
|
434
|
+
/** True when the chosen path is ASTC *and* the hint is 'normal' (caller must pre-swizzle). */
|
|
435
|
+
astcNormalRemap: boolean;
|
|
436
|
+
}
|
|
437
|
+
declare function selectWebGLFormat(caps: WebGLCapabilities, hint: TextureHint, options?: SelectFormatOptions): WebGLFormatSelection;
|
|
438
|
+
|
|
233
439
|
/**
|
|
234
440
|
* Everything `compressTexture()` can take as an image source. A superset
|
|
235
441
|
* of `EncoderImageSource` (see Encoder.ts) that also accepts URL strings
|
|
@@ -245,18 +451,31 @@ interface CompressOptions {
|
|
|
245
451
|
flipY?: boolean;
|
|
246
452
|
/** Generate a full mip chain down to 1×1 on the CPU, encode every level. */
|
|
247
453
|
mipmaps?: boolean;
|
|
454
|
+
/**
|
|
455
|
+
* Encode quality / speed trade-off. 'fast' (default) is ~2–4× faster for a
|
|
456
|
+
* ≤0.36 dB PSNR cost; 'high' runs the exhaustive search (output identical to
|
|
457
|
+
* the CPU reference encoders). No effect on BC1 or on the WebGL fallback
|
|
458
|
+
* (which always uses the fast encoders).
|
|
459
|
+
*/
|
|
460
|
+
quality?: EncodeQuality;
|
|
248
461
|
/** Reuse an existing device (e.g. Three.js's renderer device) instead
|
|
249
|
-
* of creating a new one. When provided, the encoder
|
|
462
|
+
* of creating a new one. WebGPU path only. When provided, the encoder
|
|
463
|
+
* never destroys it. */
|
|
250
464
|
device?: GPUDevice;
|
|
251
465
|
adapter?: GPUAdapter;
|
|
252
466
|
}
|
|
253
467
|
interface CompressResult {
|
|
254
|
-
/** CompressedTexture on
|
|
468
|
+
/** CompressedTexture on a compressed path; Texture on RGBA8 fallback. */
|
|
255
469
|
texture: Texture | CompressedTexture;
|
|
256
470
|
/** The compressed format selected, or null when we fell back to RGBA8. */
|
|
257
471
|
format: TextureFormat | null;
|
|
258
472
|
/** True iff we returned an uncompressed Texture because no encoder fit. */
|
|
259
473
|
fallbackUncompressed: boolean;
|
|
474
|
+
/**
|
|
475
|
+
* Which backend produced the result. 'webgpu' = compute path, 'webgl' =
|
|
476
|
+
* fragment-shader fallback, 'none' = uncompressed RGBA8.
|
|
477
|
+
*/
|
|
478
|
+
backend: 'webgpu' | 'webgl' | 'none';
|
|
260
479
|
/**
|
|
261
480
|
* True iff the chosen format is ASTC and the hint was 'normal'. The
|
|
262
481
|
* caller must apply the (R, W) → (x, y) swizzle in the material — ASTC
|
|
@@ -283,6 +502,8 @@ declare class GputexLoader extends Loader<Texture> {
|
|
|
283
502
|
flipY: boolean;
|
|
284
503
|
/** Generate + encode a full mip chain. Default false. */
|
|
285
504
|
mipmaps: boolean;
|
|
505
|
+
/** Encode quality / speed trade-off. Default 'fast' (~2–4× faster, ≤0.36 dB). */
|
|
506
|
+
quality: EncodeQuality;
|
|
286
507
|
/**
|
|
287
508
|
* Optional pre-existing WebGPU device. Reusing the renderer's device
|
|
288
509
|
* avoids spinning up a second WebGPU context for encoding.
|
|
@@ -329,4 +550,4 @@ declare function generateMipChain(level0: MipLevel): MipLevel[];
|
|
|
329
550
|
*/
|
|
330
551
|
declare function padToBlockMultiple(level: MipLevel): MipLevel;
|
|
331
552
|
|
|
332
|
-
export { ASTC4x4Encoder, BC1Encoder, BC5Encoder, BC7Encoder, type Capabilities, type CompressOptions, type CompressResult, type CompressTextureSource, type EncodeBytesResult, type EncodeCallOptions, type EncodeResult, Encoder, type EncoderConstructor, type EncoderImageSource, type EncoderOptions, type FeatureProvider, type FormatSelection, type FormatVariant, GputexLoader, type MipLevel, type SelectFormatOptions, TextureFormat, type TextureHint, WebGPUFeature, compressTexture, detectCapabilities, generateMipChain, padToBlockMultiple, selectFormat };
|
|
553
|
+
export { ASTC4x4Encoder, ASTC4x4WebGLEncoder, BC1Encoder, BC1WebGLEncoder, BC5Encoder, BC5WebGLEncoder, BC7Encoder, BC7WebGLEncoder, type Capabilities, type CompressOptions, type CompressResult, type CompressTextureSource, type EncodeBytesResult, type EncodeCallOptions, type EncodeQuality, type EncodeResult, Encoder, type EncoderConstructor, type EncoderImageSource, type EncoderOptions, type ExtensionProvider, type FeatureProvider, type FormatSelection, type FormatVariant, GputexLoader, type MipLevel, type RawPixelSource, type SelectFormatOptions, TextureFormat, type TextureHint, WebGLBlockEncoder, type WebGLCapabilities, type WebGLEncodeBytesResult, type WebGLEncoderConstructor, type WebGLEncoderImageSource, type WebGLEncoderOptions, type WebGLFormatSelection, WebGPUFeature, compressTexture, createWebGLContext, detectCapabilities, detectWebGLCapabilities, generateMipChain, getSharedWebGLContext, isWebGLAvailable, padToBlockMultiple, selectFormat, selectWebGLFormat };
|