@threenative/assets 0.3.3 → 0.3.6
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 +22 -0
- package/dist/apply-worker.js +10245 -7697
- package/dist/blender-gpl/fixtures/make_world_fixture.py +184 -0
- package/dist/blender-gpl/recipes/_common.py +11 -0
- package/dist/blender-gpl/recipes/decimate.py +11 -5
- package/dist/blender-gpl/recipes/export_world.py +699 -0
- package/dist/index.d.ts +280 -95
- package/dist/index.js +13228 -9296
- package/package.json +4 -3
package/dist/index.d.ts
CHANGED
|
@@ -1,12 +1,123 @@
|
|
|
1
1
|
import { Document, Material } from '@gltf-transform/core';
|
|
2
2
|
|
|
3
|
+
interface IImageQualityFloor {
|
|
4
|
+
readonly ssim: number;
|
|
5
|
+
readonly meanDeltaE00: number;
|
|
6
|
+
}
|
|
7
|
+
interface IImageQuality {
|
|
8
|
+
readonly version: string;
|
|
9
|
+
readonly width: number;
|
|
10
|
+
readonly height: number;
|
|
11
|
+
readonly ssim: number;
|
|
12
|
+
readonly meanDeltaE00: number | null;
|
|
13
|
+
readonly slots: readonly string[];
|
|
14
|
+
readonly floor: IImageQualityFloor;
|
|
15
|
+
readonly status: "pass" | "below-floor" | "unvalidated-slots";
|
|
16
|
+
readonly alpha: {
|
|
17
|
+
readonly ssim: number;
|
|
18
|
+
readonly meanAbsoluteError: number;
|
|
19
|
+
readonly coverage: readonly {
|
|
20
|
+
readonly threshold: number;
|
|
21
|
+
readonly source: number;
|
|
22
|
+
readonly decoded: number;
|
|
23
|
+
readonly changedPixels: number;
|
|
24
|
+
}[];
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
interface ITextureQuality extends IImageQuality {
|
|
28
|
+
readonly rung?: string;
|
|
29
|
+
readonly compressionSkipped?: "block-size" | "not-smaller" | "below-floor";
|
|
30
|
+
readonly sourceWidth: number;
|
|
31
|
+
readonly sourceHeight: number;
|
|
32
|
+
readonly codec: string;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Compresses the images embedded *inside* a `.glb` — the half of a model the geometry passes
|
|
37
|
+
* never touched. A prop carrying three 2048x2048 JPEGs is a small file and 67 MB of VRAM once
|
|
38
|
+
* the driver decodes it; meshopt shrinks the other, cheaper half. This stage transcodes each
|
|
39
|
+
* embedded image to KTX2/Basis and declares `KHR_texture_basisu`, so the GPU stores blocks
|
|
40
|
+
* instead of RGBA, and caps the resolution so a 4K texture an image model produced cannot
|
|
41
|
+
* silently eat a phone's whole budget.
|
|
42
|
+
*
|
|
43
|
+
* Slot constraints feed one measured ladder: normal/data slots retain UASTC/none, while
|
|
44
|
+
* colour escalates from ETC1S through RDO and plain UASTC. Alpha coverage is checked separately;
|
|
45
|
+
* a forced codec must still meet the floor. Colour space comes from the slot too — `getTextureColorSpace`
|
|
46
|
+
* knows base colour and emissive are sRGB and that metallic-roughness and normals are data —
|
|
47
|
+
* so a linear map is never encoded through a perceptual metric.
|
|
48
|
+
*
|
|
49
|
+
* The encoder is the same in-process Basis WASM the standalone texture pass uses, so no new
|
|
50
|
+
* dependency and nothing extra to install. Everything fails closed: an image no decoder reads,
|
|
51
|
+
* an image whose dimensions are not a whole number of 4x4 blocks, and a texture whose binding
|
|
52
|
+
* did not survive the round trip all throw naming the model and the image.
|
|
53
|
+
*/
|
|
54
|
+
interface IModelTextureOverride {
|
|
55
|
+
readonly codec: TextureCodec;
|
|
56
|
+
/** glTF slot the override applies to, e.g. `normalTexture` or `baseColorTexture`. */
|
|
57
|
+
readonly slot: string;
|
|
58
|
+
}
|
|
59
|
+
type TextureMaxSize = number | Readonly<Record<string, number>>;
|
|
60
|
+
interface IModelTexturesOptions {
|
|
61
|
+
/** Internal target-selected raw ASTC output. */
|
|
62
|
+
readonly astc?: boolean;
|
|
63
|
+
readonly floor?: Partial<IImageQualityFloor>;
|
|
64
|
+
/** Internal reporting switch; selection still measures and enforces the floor. */
|
|
65
|
+
readonly measureQuality?: boolean;
|
|
66
|
+
/**
|
|
67
|
+
* Resolved by the compiler from the target's runtime capabilities, never by a project: the
|
|
68
|
+
* target has no KTX2 decoder, so an over-cap embedded image is box-resampled and re-emitted as
|
|
69
|
+
* a PNG instead of being encoded. Everything else — authored-byte retention under the cap,
|
|
70
|
+
* per-image deduplication, colour space — is unchanged.
|
|
71
|
+
*/
|
|
72
|
+
readonly decoderFree?: boolean;
|
|
73
|
+
/**
|
|
74
|
+
* Longest edge an embedded image may keep, default 2048. Larger images are box-resampled
|
|
75
|
+
* down preserving aspect ratio; smaller ones are never upscaled.
|
|
76
|
+
*/
|
|
77
|
+
readonly maxSize?: TextureMaxSize;
|
|
78
|
+
readonly overrides?: readonly IModelTextureOverride[];
|
|
79
|
+
/** ETC1S encoder quality 1–255, default 150. Ignored for UASTC. */
|
|
80
|
+
readonly quality?: number;
|
|
81
|
+
}
|
|
82
|
+
/** What the stage did, recorded in the manifest and printed by the size report. */
|
|
83
|
+
interface IEmbeddedTextureSummary {
|
|
84
|
+
readonly quality: Readonly<Record<string, ITextureQuality>>;
|
|
85
|
+
readonly bytesAfter: number;
|
|
86
|
+
readonly bytesBefore: number;
|
|
87
|
+
readonly count: number;
|
|
88
|
+
/** Chosen codec per embedded image, keyed by texture name. */
|
|
89
|
+
readonly formats: Readonly<Record<string, string>>;
|
|
90
|
+
readonly gpuBytesAfter: number;
|
|
91
|
+
readonly gpuBytesBefore: number;
|
|
92
|
+
/** How many images the resolution cap actually downsampled. */
|
|
93
|
+
readonly resized: number;
|
|
94
|
+
/** Images retained at their authored bytes, by name, with the reason each one was not cooked. */
|
|
95
|
+
readonly skippedCompression: Readonly<Record<string, TextureSkipReason>>;
|
|
96
|
+
}
|
|
97
|
+
/** One embedded image as the verification compares it, source against re-read output. */
|
|
98
|
+
interface IModelTextureBinding {
|
|
99
|
+
readonly height: number;
|
|
100
|
+
readonly key: string;
|
|
101
|
+
/** KTX2 mip levels; 1 for a still-uncompressed source image. */
|
|
102
|
+
readonly levels: number;
|
|
103
|
+
readonly mimeType: string;
|
|
104
|
+
readonly slots: readonly string[];
|
|
105
|
+
readonly texCoords: readonly number[];
|
|
106
|
+
readonly width: number;
|
|
107
|
+
}
|
|
108
|
+
interface IModelTextureBindings {
|
|
109
|
+
/** `material -> slot=textureIndex@uvN` for the five core glTF slots, in document order. */
|
|
110
|
+
readonly materials: readonly string[];
|
|
111
|
+
readonly textures: readonly IModelTextureBinding[];
|
|
112
|
+
}
|
|
113
|
+
|
|
3
114
|
/**
|
|
4
115
|
* Encodes compiled textures to KTX2/Basis so the GPU stores them compressed instead of as
|
|
5
116
|
* decoded RGBA (a 2048x2048 PNG is 16 MB in VRAM; BC7/ASTC hold it in a quarter of that).
|
|
6
117
|
*
|
|
7
118
|
* Codec choice is a declared property of the asset, never a guess: a config override wins,
|
|
8
|
-
* then the `*_normal.*` / `_nrm.*` filename convention
|
|
9
|
-
*
|
|
119
|
+
* then the `*_normal.*` / `_nrm.*` filename convention constrains the shared measured ladder.
|
|
120
|
+
* Colour escalates through ETC1S/RDO/UASTC/none; unknown alpha cutoffs require exact alpha. Mip chains are generated at
|
|
10
121
|
* encode time — always — because an uploaded compressed texture without mips looks worse
|
|
11
122
|
* than the PNG it replaced.
|
|
12
123
|
*
|
|
@@ -18,10 +129,10 @@ type TextureCodec = "etc1s" | "none" | "uastc";
|
|
|
18
129
|
/**
|
|
19
130
|
* Why a source shipped uncompressed although its pass ran. `not-smaller` means encoding would
|
|
20
131
|
* have grown the download; `block-size` means no block codec can address the source's
|
|
21
|
-
* dimensions.
|
|
132
|
+
* dimensions; `below-floor` means no compressed rung passed. A capped source retains its resized pixels as PNG; none is a silent decision — the manifest carries
|
|
22
133
|
* the reason and the report prints it.
|
|
23
134
|
*/
|
|
24
|
-
type TextureSkipReason = "block-size" | "not-smaller";
|
|
135
|
+
type TextureSkipReason = "block-size" | "not-smaller" | "below-floor";
|
|
25
136
|
interface ITextureOverride {
|
|
26
137
|
readonly codec: TextureCodec;
|
|
27
138
|
/** First matching override wins; matched against the logical path, e.g. "ui/x.png". */
|
|
@@ -30,8 +141,13 @@ interface ITextureOverride {
|
|
|
30
141
|
readonly quality?: number;
|
|
31
142
|
}
|
|
32
143
|
interface ITexturePassOptions {
|
|
144
|
+
/** Compiler-selected mobile output; the quality ladder measures final ASTC bytes. */
|
|
145
|
+
readonly astc?: boolean;
|
|
146
|
+
readonly floor?: Partial<IImageQualityFloor>;
|
|
147
|
+
/** Internal reporting control; selection still measures and enforces the floor. */
|
|
148
|
+
readonly measureQuality?: boolean;
|
|
33
149
|
/** Longest edge to retain; larger sources are downsampled without upscaling. */
|
|
34
|
-
readonly maxSize?:
|
|
150
|
+
readonly maxSize?: TextureMaxSize;
|
|
35
151
|
readonly overrides?: readonly ITextureOverride[];
|
|
36
152
|
/** ETC1S encoder quality 1–255, default 150. Ignored for UASTC. */
|
|
37
153
|
readonly quality?: number;
|
|
@@ -54,6 +170,15 @@ interface IAssetRuntimeDecoderCapabilities {
|
|
|
54
170
|
readonly meshopt: boolean;
|
|
55
171
|
}
|
|
56
172
|
|
|
173
|
+
interface IModelDedupeSummary {
|
|
174
|
+
/** Distinct cooked outputs among the model sources that took part. */
|
|
175
|
+
readonly cooked: number;
|
|
176
|
+
/** Cooked bytes the duplicates would have written on their own. */
|
|
177
|
+
readonly savedBytes: number;
|
|
178
|
+
/** Model sources that took part, canonicals and duplicates alike. */
|
|
179
|
+
readonly sources: number;
|
|
180
|
+
}
|
|
181
|
+
|
|
57
182
|
type AssetFindingGrade = "fail" | "ok" | "warn";
|
|
58
183
|
interface IAssetFinding {
|
|
59
184
|
readonly asset: string;
|
|
@@ -164,6 +289,7 @@ interface IModelLodRuntimeOptions {
|
|
|
164
289
|
}
|
|
165
290
|
/** A partial override for one asset; nested objects overlay, they never replace. */
|
|
166
291
|
interface IModelLodOverride {
|
|
292
|
+
readonly cutout?: boolean;
|
|
167
293
|
readonly enabled?: boolean;
|
|
168
294
|
readonly generation?: IModelLodGenerationOptions;
|
|
169
295
|
readonly preset?: LodPreset;
|
|
@@ -175,6 +301,12 @@ interface IModelLodOverride {
|
|
|
175
301
|
* re-enable. Resolution is per asset and happens where the asset is known (PRD-377 §3.2, §5).
|
|
176
302
|
*/
|
|
177
303
|
interface IModelLodOptions {
|
|
304
|
+
/**
|
|
305
|
+
* Convert eligible `BLEND` foliage to alpha-tested in the cook (PRD-458 §4). Default `true`,
|
|
306
|
+
* because a needle card exported as `BLEND` is refused a chain by rule and the tree then draws
|
|
307
|
+
* LOD0 forever. `false` keeps the authored blending; per asset, `cutout` in an override entry.
|
|
308
|
+
*/
|
|
309
|
+
readonly cutout?: boolean;
|
|
178
310
|
readonly enabled?: boolean;
|
|
179
311
|
readonly generation?: IModelLodGenerationOptions;
|
|
180
312
|
readonly overrides?: Readonly<Record<string, boolean | IModelLodOverride>>;
|
|
@@ -275,6 +407,74 @@ interface IAudioPassOptions {
|
|
|
275
407
|
/** `"none"` drops the pass; an object configures it; absent means the defaults run. */
|
|
276
408
|
declare function parseAudioConfig(raw: unknown): IAudioPassOptions | undefined;
|
|
277
409
|
|
|
410
|
+
interface IModelCompactInstanceOptions {
|
|
411
|
+
/**
|
|
412
|
+
* Minimum number of nodes that must share one mesh before it is instanced, default 2.
|
|
413
|
+
* gltf-transform's own default is 5; the lower floor is what lets a paired prop instance.
|
|
414
|
+
*/
|
|
415
|
+
readonly min?: number;
|
|
416
|
+
}
|
|
417
|
+
interface IModelCompactOptions {
|
|
418
|
+
readonly flatten?: boolean;
|
|
419
|
+
readonly instance?: boolean | IModelCompactInstanceOptions;
|
|
420
|
+
readonly join?: boolean;
|
|
421
|
+
/** Extra exact node names to protect, on top of the regex and the structural rules. */
|
|
422
|
+
readonly protectedNames?: readonly string[];
|
|
423
|
+
/**
|
|
424
|
+
* Case-insensitive node-name regex source for nodes the game looks up or moves. Defaults to
|
|
425
|
+
* {@link DEFAULT_PROTECTED_PATTERN}; an invalid source throws rather than silently protecting nothing.
|
|
426
|
+
*/
|
|
427
|
+
readonly protectedPattern?: string;
|
|
428
|
+
}
|
|
429
|
+
/** Why a node was kept out of join/instance. */
|
|
430
|
+
type TModelProtectedRule = "allow-list" | "animation-ancestor" | "animation-target" | "regex" | "skin-joint";
|
|
431
|
+
interface IModelProtectedNode {
|
|
432
|
+
readonly name: string;
|
|
433
|
+
readonly rule: TModelProtectedRule;
|
|
434
|
+
}
|
|
435
|
+
interface IModelCompactSummary {
|
|
436
|
+
/** Whether each pass ran and how many primitives/nodes it removed. */
|
|
437
|
+
readonly flatten: {
|
|
438
|
+
readonly enabled: boolean;
|
|
439
|
+
/** Nodes reparented toward the scene root; a node left in place is not counted. */
|
|
440
|
+
readonly reparented: number;
|
|
441
|
+
};
|
|
442
|
+
readonly instance: {
|
|
443
|
+
readonly batches: number;
|
|
444
|
+
readonly enabled: boolean;
|
|
445
|
+
readonly instances: number;
|
|
446
|
+
/** Why no batch was created, when none was. */
|
|
447
|
+
readonly reason?: string;
|
|
448
|
+
};
|
|
449
|
+
readonly join: {
|
|
450
|
+
readonly enabled: boolean;
|
|
451
|
+
readonly primitivesAfter: number;
|
|
452
|
+
readonly primitivesBefore: number;
|
|
453
|
+
};
|
|
454
|
+
readonly nodesAfter: number;
|
|
455
|
+
readonly nodesBefore: number;
|
|
456
|
+
readonly primitivesAfter: number;
|
|
457
|
+
readonly primitivesBefore: number;
|
|
458
|
+
/**
|
|
459
|
+
* Named scene nodes that existed before compaction and are gone after it. Empty is the
|
|
460
|
+
* expected result of a run whose protected set covered every name the game addresses; a
|
|
461
|
+
* non-empty list is the report's warning that a `getObjectByName` can now return undefined.
|
|
462
|
+
*/
|
|
463
|
+
readonly removed: readonly string[];
|
|
464
|
+
/** Every node kept out of compaction, with the rule that protected it, sorted by name. */
|
|
465
|
+
readonly protected: readonly IModelProtectedNode[];
|
|
466
|
+
}
|
|
467
|
+
/** The compaction policy with every default resolved, so it is a stable cache key. */
|
|
468
|
+
interface IResolvedCompactOptions {
|
|
469
|
+
readonly flatten: boolean;
|
|
470
|
+
readonly instance: false | IModelCompactInstanceOptions;
|
|
471
|
+
readonly join: boolean;
|
|
472
|
+
readonly protectedNames: readonly string[];
|
|
473
|
+
readonly protectedPattern: string;
|
|
474
|
+
/** Algorithm identity, so an upgraded pass never re-serves a cache from an older build. */
|
|
475
|
+
readonly version: number;
|
|
476
|
+
}
|
|
477
|
+
|
|
278
478
|
/**
|
|
279
479
|
* Atlas integration follows the mesh → xatlas → remapped-attribute split documented by
|
|
280
480
|
* xatlas-three 0.2.1 (MIT, copyright 2022 Palash Bansal). This implementation uses xatlasjs's
|
|
@@ -325,71 +525,6 @@ interface IModelVirtualOptions {
|
|
|
325
525
|
readonly simplifyRatio?: number;
|
|
326
526
|
}
|
|
327
527
|
|
|
328
|
-
/**
|
|
329
|
-
* Compresses the images embedded *inside* a `.glb` — the half of a model the geometry passes
|
|
330
|
-
* never touched. A prop carrying three 2048x2048 JPEGs is a small file and 67 MB of VRAM once
|
|
331
|
-
* the driver decodes it; meshopt shrinks the other, cheaper half. This stage transcodes each
|
|
332
|
-
* embedded image to KTX2/Basis and declares `KHR_texture_basisu`, so the GPU stores blocks
|
|
333
|
-
* instead of RGBA, and caps the resolution so a 4K texture an image model produced cannot
|
|
334
|
-
* silently eat a phone's whole budget.
|
|
335
|
-
*
|
|
336
|
-
* Codec choice follows the declared use of the image, never a guess: a config override on the
|
|
337
|
-
* glTF slot wins, then normal-map slots (UASTC survives normal data; ETC1S does not), then
|
|
338
|
-
* alpha in the decoded pixels. Colour space comes from the slot too — `getTextureColorSpace`
|
|
339
|
-
* knows base colour and emissive are sRGB and that metallic-roughness and normals are data —
|
|
340
|
-
* so a linear map is never encoded through a perceptual metric.
|
|
341
|
-
*
|
|
342
|
-
* The encoder is the same in-process Basis WASM the standalone texture pass uses, so no new
|
|
343
|
-
* dependency and nothing extra to install. Everything fails closed: an image no decoder reads,
|
|
344
|
-
* an image whose dimensions are not a whole number of 4x4 blocks, and a texture whose binding
|
|
345
|
-
* did not survive the round trip all throw naming the model and the image.
|
|
346
|
-
*/
|
|
347
|
-
interface IModelTextureOverride {
|
|
348
|
-
readonly codec: TextureCodec;
|
|
349
|
-
/** glTF slot the override applies to, e.g. `normalTexture` or `baseColorTexture`. */
|
|
350
|
-
readonly slot: string;
|
|
351
|
-
}
|
|
352
|
-
interface IModelTexturesOptions {
|
|
353
|
-
/**
|
|
354
|
-
* Longest edge an embedded image may keep, default 2048. Larger images are box-resampled
|
|
355
|
-
* down preserving aspect ratio; smaller ones are never upscaled.
|
|
356
|
-
*/
|
|
357
|
-
readonly maxSize?: number;
|
|
358
|
-
readonly overrides?: readonly IModelTextureOverride[];
|
|
359
|
-
/** ETC1S encoder quality 1–255, default 150. Ignored for UASTC. */
|
|
360
|
-
readonly quality?: number;
|
|
361
|
-
}
|
|
362
|
-
/** What the stage did, recorded in the manifest and printed by the size report. */
|
|
363
|
-
interface IEmbeddedTextureSummary {
|
|
364
|
-
readonly bytesAfter: number;
|
|
365
|
-
readonly bytesBefore: number;
|
|
366
|
-
readonly count: number;
|
|
367
|
-
/** Chosen codec per embedded image, keyed by texture name. */
|
|
368
|
-
readonly formats: Readonly<Record<string, string>>;
|
|
369
|
-
readonly gpuBytesAfter: number;
|
|
370
|
-
readonly gpuBytesBefore: number;
|
|
371
|
-
/** How many images the resolution cap actually downsampled. */
|
|
372
|
-
readonly resized: number;
|
|
373
|
-
/** Images retained at their authored bytes, by name, with the reason each one was not cooked. */
|
|
374
|
-
readonly skippedCompression: Readonly<Record<string, TextureSkipReason>>;
|
|
375
|
-
}
|
|
376
|
-
/** One embedded image as the verification compares it, source against re-read output. */
|
|
377
|
-
interface IModelTextureBinding {
|
|
378
|
-
readonly height: number;
|
|
379
|
-
readonly key: string;
|
|
380
|
-
/** KTX2 mip levels; 1 for a still-uncompressed source image. */
|
|
381
|
-
readonly levels: number;
|
|
382
|
-
readonly mimeType: string;
|
|
383
|
-
readonly slots: readonly string[];
|
|
384
|
-
readonly texCoords: readonly number[];
|
|
385
|
-
readonly width: number;
|
|
386
|
-
}
|
|
387
|
-
interface IModelTextureBindings {
|
|
388
|
-
/** `material -> slot=textureIndex@uvN` for the five core glTF slots, in document order. */
|
|
389
|
-
readonly materials: readonly string[];
|
|
390
|
-
readonly textures: readonly IModelTextureBinding[];
|
|
391
|
-
}
|
|
392
|
-
|
|
393
528
|
/**
|
|
394
529
|
* Images that models share, written once and referenced from every model that carries them.
|
|
395
530
|
*
|
|
@@ -404,6 +539,7 @@ interface IModelTextureBindings {
|
|
|
404
539
|
* bytes resolve to one URL and the browser cache, the bundle and the delete-test all see one file.
|
|
405
540
|
*/
|
|
406
541
|
interface ISharedImage {
|
|
542
|
+
readonly quality?: ITextureQuality;
|
|
407
543
|
readonly buffer: Buffer;
|
|
408
544
|
/** `uastc`, `etc1s` or `none`, spelled into the filename so a cache hit knows what it found. */
|
|
409
545
|
readonly codec: string;
|
|
@@ -470,6 +606,12 @@ interface IModelSimplifyOptions {
|
|
|
470
606
|
}
|
|
471
607
|
interface IModelPassOptions {
|
|
472
608
|
readonly passes?: IModelPassesOptions;
|
|
609
|
+
/**
|
|
610
|
+
* Lossless scene-graph compaction (flatten → instance → join) against one protected-node set.
|
|
611
|
+
* Absent means on with defaults; `false` is the kill switch; an object configures the
|
|
612
|
+
* sub-passes, the protected-name allow-list and the name regex. It never decimates geometry.
|
|
613
|
+
*/
|
|
614
|
+
readonly compact?: boolean | IModelCompactOptions;
|
|
473
615
|
/** Native WebGPU rejects interleaved vertex attributes; mobile output uses separate buffers. */
|
|
474
616
|
readonly vertexLayout?: "interleaved" | "separate";
|
|
475
617
|
/** Preserve generated TEXCOORD_1 data that is consumed by a runtime-attached lightmap. */
|
|
@@ -527,6 +669,7 @@ declare function modelPass(options?: IModelPassOptions): IAssetPass;
|
|
|
527
669
|
* so tests can pin the exact lines a build prints.
|
|
528
670
|
*/
|
|
529
671
|
interface ITextureSizeRow {
|
|
672
|
+
readonly quality?: ITextureQuality;
|
|
530
673
|
readonly after: number;
|
|
531
674
|
readonly before: number;
|
|
532
675
|
/** Set when the bytes shipped as authored; printed so a flat row is never left unexplained. */
|
|
@@ -537,6 +680,7 @@ interface ITextureSizeRow {
|
|
|
537
680
|
declare function formatTextureSizes(rows: readonly ITextureSizeRow[]): readonly string[];
|
|
538
681
|
/** What the model pass did to the images inside one `.glb`. */
|
|
539
682
|
interface IEmbeddedTextureRow {
|
|
683
|
+
readonly quality?: Readonly<Record<string, ITextureQuality>>;
|
|
540
684
|
readonly skippedCompression?: Readonly<Record<string, TextureSkipReason>>;
|
|
541
685
|
readonly bytesAfter: number;
|
|
542
686
|
readonly bytesBefore: number;
|
|
@@ -551,6 +695,8 @@ interface IEmbeddedTextureRow {
|
|
|
551
695
|
interface IVirtualRow {
|
|
552
696
|
readonly bakeSeconds: number;
|
|
553
697
|
readonly clusters: number;
|
|
698
|
+
/** Primitives handed back to the discrete ladder because their DAG reduced nothing. */
|
|
699
|
+
readonly declined: number;
|
|
554
700
|
readonly levels: number;
|
|
555
701
|
readonly payloadBytes: number;
|
|
556
702
|
readonly primitives: number;
|
|
@@ -583,6 +729,17 @@ interface ILodJoinedRow {
|
|
|
583
729
|
interface ILodRow {
|
|
584
730
|
/** Bytes the derived index buffers add, before compression. */
|
|
585
731
|
readonly byteOverhead: number;
|
|
732
|
+
/**
|
|
733
|
+
* The foliage cutout conversion the cook ran before generating (PRD-458 §4): the `BLEND`
|
|
734
|
+
* materials that became alpha-tested, and the ones that kept blending and why.
|
|
735
|
+
*/
|
|
736
|
+
readonly cutout?: {
|
|
737
|
+
readonly converted: readonly string[];
|
|
738
|
+
readonly kept: readonly {
|
|
739
|
+
readonly name: string;
|
|
740
|
+
readonly reason: string;
|
|
741
|
+
}[];
|
|
742
|
+
};
|
|
586
743
|
/** Migration/legacy notes the resolver raised, by code. */
|
|
587
744
|
readonly diagnostics: readonly string[];
|
|
588
745
|
/** The resolved increasing geometric-error targets, as the bake consumed them. */
|
|
@@ -717,6 +874,19 @@ interface IAudioRow {
|
|
|
717
874
|
*/
|
|
718
875
|
declare function formatAudioSizes(rows: readonly IAudioRow[]): readonly string[];
|
|
719
876
|
/** One compiled model plus a total, before against after the optimization pass. */
|
|
877
|
+
/** The cook's material merge (PRD-458 §5): what collapsed, and the counts either side of it. */
|
|
878
|
+
interface IMaterialsRow {
|
|
879
|
+
/** Distinct signatures — the count a draw call is bound by. */
|
|
880
|
+
readonly distinct: {
|
|
881
|
+
readonly after: number;
|
|
882
|
+
readonly before: number;
|
|
883
|
+
};
|
|
884
|
+
readonly materials: {
|
|
885
|
+
readonly after: number;
|
|
886
|
+
readonly before: number;
|
|
887
|
+
};
|
|
888
|
+
readonly merged: readonly string[];
|
|
889
|
+
}
|
|
720
890
|
interface IModelSizeRow {
|
|
721
891
|
readonly after: number;
|
|
722
892
|
readonly before: number;
|
|
@@ -739,8 +909,12 @@ interface IModelSizeRow {
|
|
|
739
909
|
readonly simplify?: ISimplifyRow;
|
|
740
910
|
/** Automatic discrete LOD generation (PRD-377), when the effective policy ran. */
|
|
741
911
|
readonly lod?: ILodRow;
|
|
912
|
+
/** Lossless scene-graph compaction (PRD-443), when it ran. */
|
|
913
|
+
readonly compact?: IModelCompactSummary;
|
|
742
914
|
/** The cluster-DAG bake, when it was configured for this model. */
|
|
743
915
|
readonly virtual?: IVirtualRow;
|
|
916
|
+
/** The material merge the cook ran unconditionally, before any other geometry stage. */
|
|
917
|
+
readonly materials?: IMaterialsRow;
|
|
744
918
|
/** Triangle count of the compiled output, recorded in the manifest. */
|
|
745
919
|
readonly triangles?: number;
|
|
746
920
|
}
|
|
@@ -804,6 +978,13 @@ interface IAssetPass {
|
|
|
804
978
|
/** True when this pass's emitted output requires a runtime decoder unavailable on mobile. */
|
|
805
979
|
readonly needsRuntimeDecoder?: boolean;
|
|
806
980
|
readonly name: string;
|
|
981
|
+
/**
|
|
982
|
+
* Input kinds whose bytes this pass can change. The compile hashes only the passes that can
|
|
983
|
+
* change an asset into that asset's digest, so a model-only option edit does not rename every
|
|
984
|
+
* texture. `undefined` (the default for a caller-supplied pass) means any kind, which stays
|
|
985
|
+
* conservative: an unknown pass can change every asset.
|
|
986
|
+
*/
|
|
987
|
+
readonly appliesTo?: readonly AssetKind[];
|
|
807
988
|
/**
|
|
808
989
|
* JSON-serializable snapshot of every option that changes this pass's output. Part of the
|
|
809
990
|
* compile cache key: without it, editing a config value (texture quality, quantize bits, an
|
|
@@ -825,7 +1006,7 @@ interface IAssetSourceConfig {
|
|
|
825
1006
|
readonly audio?: IAudioConfig | "none";
|
|
826
1007
|
/**
|
|
827
1008
|
* The bound on how many workers a bake may use. A direct `concurrency` option overrides it;
|
|
828
|
-
* absent means the driver's default (
|
|
1009
|
+
* absent means the driver's default (cores - 1, bounded by ~2 GB of memory a worker, at most 12). CI boxes and laptops differ, and
|
|
829
1010
|
* a 6.8 GB pack does not get to decide the machine's fate.
|
|
830
1011
|
*/
|
|
831
1012
|
readonly concurrency?: number;
|
|
@@ -840,6 +1021,14 @@ interface IAssetSourceConfig {
|
|
|
840
1021
|
* default-on decision is a later phase (PRD-377 §8).
|
|
841
1022
|
*/
|
|
842
1023
|
readonly lod?: boolean | IModelLodOptions | "none";
|
|
1024
|
+
/**
|
|
1025
|
+
* Also writes the native cooked package (`<output>/native/assets.tnpk`, TNPK v1) beside the
|
|
1026
|
+
* existing outputs: one Buffer entry per cooked binary buffer and one Texture entry per cooked
|
|
1027
|
+
* PNG or JPEG (decoded to RGBA8). Mesh, material and scene entries are out of scope until their
|
|
1028
|
+
* native loaders land.
|
|
1029
|
+
* Absent means off, so a web-only project pays nothing.
|
|
1030
|
+
*/
|
|
1031
|
+
readonly nativePackage?: boolean;
|
|
843
1032
|
readonly output?: string;
|
|
844
1033
|
readonly source?: string;
|
|
845
1034
|
readonly targets?: IAssetTargets;
|
|
@@ -850,6 +1039,11 @@ interface IAssetSourceConfig {
|
|
|
850
1039
|
readonly textures?: ITexturesConfig | "none";
|
|
851
1040
|
}
|
|
852
1041
|
interface IModelsConfig {
|
|
1042
|
+
/**
|
|
1043
|
+
* Lossless scene-graph compaction (flatten → instance → join) against one protected-node set.
|
|
1044
|
+
* Default true ({@link IModelCompactOptions}); `false` ships the scene graph as authored.
|
|
1045
|
+
*/
|
|
1046
|
+
readonly compact?: boolean | IModelCompactOptions;
|
|
853
1047
|
/** Generate standard TEXCOORD_1 lightmap UVs. Absent means no lightmap pass. */
|
|
854
1048
|
readonly lightmap?: ILightmapPassOptions;
|
|
855
1049
|
readonly passes?: IModelPassesOptions;
|
|
@@ -884,7 +1078,8 @@ interface IAudioConfig {
|
|
|
884
1078
|
readonly seamMaxRatio?: number;
|
|
885
1079
|
}
|
|
886
1080
|
interface ITexturesConfig {
|
|
887
|
-
readonly
|
|
1081
|
+
readonly floor?: ITexturePassOptions["floor"];
|
|
1082
|
+
readonly maxSize?: TextureMaxSize;
|
|
888
1083
|
readonly overrides?: readonly ITextureOverride[];
|
|
889
1084
|
readonly quality?: number;
|
|
890
1085
|
}
|
|
@@ -909,31 +1104,16 @@ interface IAssetCompileOptions {
|
|
|
909
1104
|
*/
|
|
910
1105
|
readonly processingOrder?: "reversed" | "sorted";
|
|
911
1106
|
/**
|
|
912
|
-
* The
|
|
913
|
-
*
|
|
914
|
-
*
|
|
915
|
-
*
|
|
916
|
-
* a black screen, and `threenative build` refuses one with `TN_NATIVE_KTX2_UNSUPPORTED`. Web
|
|
917
|
-
* and desktop decode both.
|
|
918
|
-
*
|
|
919
|
-
* Absent means web — a direct `compileAssets` call, or a project that compiles once and serves
|
|
920
|
-
* the result. `threenative build` always names its `--target`, so the passes that a platform
|
|
921
|
-
* cannot decode drop for that build and stay on for every other one. This is the whole reason
|
|
922
|
-
* `assets.textures: "none"` used to be pinned in the scaffolded config: the author was asked to
|
|
923
|
-
* choose one constant for four targets, and every game that wanted Android shipped its web
|
|
924
|
-
* build uncompressed too. The build knows its target; it decides.
|
|
1107
|
+
* The conservative default decoder policy: web/desktop keep the existing loaders;
|
|
1108
|
+
* Android/iOS stay decoder-free until their packaged loaders are qualified. A V8 engine
|
|
1109
|
+
* alone does not establish a working Basis, Meshopt or Draco path. Absent means web.
|
|
1110
|
+
* Native builds provide runtimeDecoders from their selected artifact instead.
|
|
925
1111
|
*/
|
|
926
1112
|
readonly platform?: "android" | "desktop" | "ios" | "web";
|
|
927
|
-
/**
|
|
928
|
-
* What the runtime that will execute this bake can decode, when the caller has probed it.
|
|
929
|
-
*
|
|
930
|
-
* `platform` is a proxy: it answers "android and iOS have no WebAssembly" for the targets this
|
|
931
|
-
* repository ships. A desktop host can also lack WebAssembly — the Linux arm64 lane builds
|
|
932
|
-
* QuickJS over wgpu-native — and then the same meshopt/KTX2 passes it would keep produce an
|
|
933
|
-
* asset nothing can decode. `threenative build` reads the engine from the runtime binary it will
|
|
934
|
-
* package and passes the real capability here; absent, the platform-derived default stands.
|
|
935
|
-
*/
|
|
1113
|
+
/** Which compressed outputs the selected runtime's bundle can decode, independently of WASM. */
|
|
936
1114
|
readonly runtimeDecoders?: IAssetRuntimeDecoderCapabilities;
|
|
1115
|
+
/** Exact selected runtime/cohort identity; changing it invalidates cooked output. */
|
|
1116
|
+
readonly runtimeIdentity?: string;
|
|
937
1117
|
readonly source?: string;
|
|
938
1118
|
/** Overrides resolution of three's Basis transcoder for the copy into the output root. */
|
|
939
1119
|
readonly transcoder?: IBasisTranscoder;
|
|
@@ -955,6 +1135,11 @@ interface IAssetCompileResult {
|
|
|
955
1135
|
readonly skippedCompression: readonly ISkippedReportRow[];
|
|
956
1136
|
readonly receipt?: IBakeReceipt;
|
|
957
1137
|
readonly report?: IAssetHealthReport;
|
|
1138
|
+
/**
|
|
1139
|
+
* What the model cook saved by cooking content-identical sources once, when this project has
|
|
1140
|
+
* any model source. `cooked` is the number of distinct outputs those sources produced.
|
|
1141
|
+
*/
|
|
1142
|
+
readonly dedupe?: IModelDedupeSummary;
|
|
958
1143
|
readonly skipped: number;
|
|
959
1144
|
readonly written: number;
|
|
960
1145
|
}
|
|
@@ -1317,4 +1502,4 @@ declare function censusDocument(model: string, document: Document, pageSize?: nu
|
|
|
1317
1502
|
/** Totals across a set of models, so a scene's census is one line rather than twenty-nine. */
|
|
1318
1503
|
declare function totalCensus(entries: readonly IContentCensus[]): Omit<IContentCensus, "model">;
|
|
1319
1504
|
|
|
1320
|
-
export { type AssetFindingGrade, type AssetKind, type AtlasExclusionReason, type AudioBand, type AudioConditioning, type AudioNormalisation, type IAssetCompileOptions, type IAssetCompileResult, type IAssetFinding, type IAssetHealthEntry, type IAssetHealthInput, type IAssetHealthReport, type IAssetPass, type IAssetPassOutput, type IAssetSourceConfig, type IAssetTargets, type IAssetWatchHandle, type IAssetWatchOptions, type IAssetWatchSummary, type IAtlasExclusion, type IAtlasOptions, type IAtlasPage, type IAtlasPlacement, type IAtlasResult, type IAtlasSource, type IAudioConfig, type IAudioLoopOptions, type IAudioOverride, type IAudioPassOptions, type IAudioRow, type IAudioSpectrumExpectation, type IBakeReceipt, type IBakeReceiptOutput, type IBasisTranscoder, type IContentCensus, type IDedupeCensus, type IEmbeddedTextureRow, type IEmbeddedTextureSummary, type ILightmapPassOptions, type IMaterialBucket, type IMaterialState, type IModelPassOptions, type IModelPassesOptions, type IModelQuantizeOptions, type IModelSimplifyOptions, type IModelSimplifySummary, type IModelSizeRow, type IModelStats, type IModelTextureBinding, type IModelTextureBindings, type IModelTextureOverride, type IModelTexturesOptions, type IModelsConfig, type IPassCostAssetRow, type IPassCostRow, type IPngInfo, type ISimplifyRow, type ITextureOverride, type ITexturePassOptions, type ITextureSizeRow, type ITextureStats, type ITexturesConfig, type PassCostStatus, type TextureCodec, WRAP_CLAMP_TO_EDGE, WRAP_MIRRORED_REPEAT, WRAP_REPEAT, atlasManifest, audioPass, censusDocument, compileAssets, dedupeMaterials, formatAudioSizes, formatHealthReport, formatModelSizes, formatPassCosts, formatTextureSizes, lightmapPass, materialSignature, materialStateOf, modelPass, packAtlas, parseAudioConfig, parsePng, resolveBasisTranscoder, resolveSourceTexel, rewriteUvs, runHealthReport, texturePass, totalCensus, uvsTile, watchAssets, withAtlasTextures, wrapTiles };
|
|
1505
|
+
export { type AssetFindingGrade, type AssetKind, type AtlasExclusionReason, type AudioBand, type AudioConditioning, type AudioNormalisation, type IAssetCompileOptions, type IAssetCompileResult, type IAssetFinding, type IAssetHealthEntry, type IAssetHealthInput, type IAssetHealthReport, type IAssetPass, type IAssetPassOutput, type IAssetSourceConfig, type IAssetTargets, type IAssetWatchHandle, type IAssetWatchOptions, type IAssetWatchSummary, type IAtlasExclusion, type IAtlasOptions, type IAtlasPage, type IAtlasPlacement, type IAtlasResult, type IAtlasSource, type IAudioConfig, type IAudioLoopOptions, type IAudioOverride, type IAudioPassOptions, type IAudioRow, type IAudioSpectrumExpectation, type IBakeReceipt, type IBakeReceiptOutput, type IBasisTranscoder, type IContentCensus, type IDedupeCensus, type IEmbeddedTextureRow, type IEmbeddedTextureSummary, type ILightmapPassOptions, type IMaterialBucket, type IMaterialState, type IModelCompactInstanceOptions, type IModelCompactOptions, type IModelCompactSummary, type IModelPassOptions, type IModelPassesOptions, type IModelProtectedNode, type IModelQuantizeOptions, type IModelSimplifyOptions, type IModelSimplifySummary, type IModelSizeRow, type IModelStats, type IModelTextureBinding, type IModelTextureBindings, type IModelTextureOverride, type IModelTexturesOptions, type IModelsConfig, type IPassCostAssetRow, type IPassCostRow, type IPngInfo, type IResolvedCompactOptions, type ISimplifyRow, type ITextureOverride, type ITexturePassOptions, type ITextureSizeRow, type ITextureStats, type ITexturesConfig, type PassCostStatus, type TModelProtectedRule, type TextureCodec, WRAP_CLAMP_TO_EDGE, WRAP_MIRRORED_REPEAT, WRAP_REPEAT, atlasManifest, audioPass, censusDocument, compileAssets, dedupeMaterials, formatAudioSizes, formatHealthReport, formatModelSizes, formatPassCosts, formatTextureSizes, lightmapPass, materialSignature, materialStateOf, modelPass, packAtlas, parseAudioConfig, parsePng, resolveBasisTranscoder, resolveSourceTexel, rewriteUvs, runHealthReport, texturePass, totalCensus, uvsTile, watchAssets, withAtlasTextures, wrapTiles };
|