@drawcall/lod 0.2.0 → 0.4.0

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.
Files changed (355) hide show
  1. package/README.md +6 -7
  2. package/dist/bake.d.ts +36 -0
  3. package/dist/bake.js +176 -0
  4. package/dist/bake.js.map +1 -0
  5. package/dist/baked/codec.d.ts +3 -6
  6. package/dist/baked/codec.js +48 -154
  7. package/dist/baked/codec.js.map +1 -1
  8. package/dist/baked/coverage.d.ts +6 -3
  9. package/dist/baked/coverage.js +6 -3
  10. package/dist/baked/coverage.js.map +1 -1
  11. package/dist/baked/fields.d.ts +9 -0
  12. package/dist/baked/fields.js +22 -0
  13. package/dist/baked/fields.js.map +1 -0
  14. package/dist/baked/index.d.ts +14 -8
  15. package/dist/baked/index.js +24 -22
  16. package/dist/baked/index.js.map +1 -1
  17. package/dist/baked/interior/faces.d.ts +4 -3
  18. package/dist/baked/interior/faces.js +16 -11
  19. package/dist/baked/interior/faces.js.map +1 -1
  20. package/dist/baked/interior/material.d.ts +7 -10
  21. package/dist/baked/interior/material.js +29 -36
  22. package/dist/baked/interior/material.js.map +1 -1
  23. package/dist/baked/interior/rooms.d.ts +1 -1
  24. package/dist/baked/interior/rooms.js +2 -2
  25. package/dist/baked/interior/rooms.js.map +1 -1
  26. package/dist/baked/low.js +5 -4
  27. package/dist/baked/low.js.map +1 -1
  28. package/dist/baked/raster.js +6 -6
  29. package/dist/baked/raster.js.map +1 -1
  30. package/dist/baked/textures.d.ts +17 -0
  31. package/dist/baked/textures.js +95 -0
  32. package/dist/baked/textures.js.map +1 -0
  33. package/dist/baked/transfer.js +19 -18
  34. package/dist/baked/transfer.js.map +1 -1
  35. package/dist/baked/unwrap.js +4 -3
  36. package/dist/baked/unwrap.js.map +1 -1
  37. package/dist/baked/xatlas.js.map +1 -1
  38. package/dist/codec/container.d.ts +8 -0
  39. package/dist/codec/container.js +63 -0
  40. package/dist/codec/container.js.map +1 -0
  41. package/dist/codec/mesh.d.ts +8 -0
  42. package/dist/{mesh/codec.js → codec/mesh.js} +80 -52
  43. package/dist/codec/mesh.js.map +1 -0
  44. package/dist/dispose.d.ts +8 -5
  45. package/dist/dispose.js +22 -24
  46. package/dist/dispose.js.map +1 -1
  47. package/dist/foliage.d.ts +32 -0
  48. package/dist/foliage.js +137 -0
  49. package/dist/foliage.js.map +1 -0
  50. package/dist/impostor/bake/atlas.d.ts +4 -4
  51. package/dist/impostor/bake/atlas.js +12 -12
  52. package/dist/impostor/bake/atlas.js.map +1 -1
  53. package/dist/impostor/bake/fit.d.ts +8 -0
  54. package/dist/impostor/bake/fit.js +28 -0
  55. package/dist/impostor/bake/fit.js.map +1 -0
  56. package/dist/impostor/bake/index.d.ts +22 -14
  57. package/dist/impostor/bake/index.js +50 -134
  58. package/dist/impostor/bake/index.js.map +1 -1
  59. package/dist/impostor/bake/materials.d.ts +3 -3
  60. package/dist/impostor/bake/materials.js +51 -13
  61. package/dist/impostor/bake/materials.js.map +1 -1
  62. package/dist/impostor/bake/sheet.d.ts +8 -0
  63. package/dist/impostor/bake/sheet.js +90 -0
  64. package/dist/impostor/bake/sheet.js.map +1 -0
  65. package/dist/impostor/bake/source.d.ts +3 -2
  66. package/dist/impostor/bake/source.js +9 -20
  67. package/dist/impostor/bake/source.js.map +1 -1
  68. package/dist/impostor/codec.d.ts +4 -5
  69. package/dist/impostor/codec.js +36 -109
  70. package/dist/impostor/codec.js.map +1 -1
  71. package/dist/impostor/impostor.d.ts +31 -7
  72. package/dist/impostor/impostor.js +21 -6
  73. package/dist/impostor/impostor.js.map +1 -1
  74. package/dist/impostor/ktx2/encode.d.ts +26 -0
  75. package/dist/impostor/ktx2/encode.js +120 -0
  76. package/dist/impostor/ktx2/encode.js.map +1 -0
  77. package/dist/impostor/ktx2/transcode.d.ts +3 -0
  78. package/dist/impostor/ktx2/transcode.js +99 -0
  79. package/dist/impostor/ktx2/transcode.js.map +1 -0
  80. package/dist/impostor/ktx2/uastc.d.ts +7 -0
  81. package/dist/impostor/ktx2/uastc.js +65 -0
  82. package/dist/impostor/ktx2/uastc.js.map +1 -0
  83. package/dist/impostor/ktx2/wasm/encoder.d.ts +4 -0
  84. package/dist/impostor/ktx2/wasm/encoder.js +10 -0
  85. package/dist/impostor/ktx2/wasm/encoder.js.map +1 -0
  86. package/dist/impostor/ktx2/wasm/transcoder.d.ts +3 -0
  87. package/dist/impostor/ktx2/wasm/transcoder.js +9 -0
  88. package/dist/impostor/ktx2/wasm/transcoder.js.map +1 -0
  89. package/dist/impostor/ktx2/worker.d.ts +1 -0
  90. package/dist/impostor/ktx2/worker.js +10 -0
  91. package/dist/impostor/ktx2/worker.js.map +1 -0
  92. package/dist/impostor/mesh/card.d.ts +4 -4
  93. package/dist/impostor/mesh/card.js +7 -7
  94. package/dist/impostor/mesh/card.js.map +1 -1
  95. package/dist/impostor/mesh/index.d.ts +7 -6
  96. package/dist/impostor/mesh/index.js +10 -11
  97. package/dist/impostor/mesh/index.js.map +1 -1
  98. package/dist/impostor/mesh/material.d.ts +18 -9
  99. package/dist/impostor/mesh/material.js +40 -27
  100. package/dist/impostor/mesh/material.js.map +1 -1
  101. package/dist/impostor/mesh/surface.d.ts +1 -1
  102. package/dist/impostor/mesh/surface.js +13 -9
  103. package/dist/impostor/mesh/surface.js.map +1 -1
  104. package/dist/impostor/mesh/textures.d.ts +3 -3
  105. package/dist/impostor/mesh/textures.js +24 -34
  106. package/dist/impostor/mesh/textures.js.map +1 -1
  107. package/dist/index.d.ts +13 -11
  108. package/dist/index.js +12 -10
  109. package/dist/index.js.map +1 -1
  110. package/dist/instanced/camera.d.ts +34 -0
  111. package/dist/instanced/camera.js +45 -0
  112. package/dist/instanced/camera.js.map +1 -0
  113. package/dist/instanced/clusters.d.ts +54 -0
  114. package/dist/instanced/clusters.js +151 -0
  115. package/dist/instanced/clusters.js.map +1 -0
  116. package/dist/instanced/cull.d.ts +28 -0
  117. package/dist/instanced/cull.js +22 -0
  118. package/dist/instanced/cull.js.map +1 -0
  119. package/dist/instanced/instances.d.ts +39 -0
  120. package/dist/instanced/instances.js +104 -0
  121. package/dist/instanced/instances.js.map +1 -0
  122. package/dist/instanced/key.d.ts +19 -0
  123. package/dist/instanced/key.js +45 -0
  124. package/dist/instanced/key.js.map +1 -0
  125. package/dist/instanced/levels.d.ts +60 -0
  126. package/dist/instanced/levels.js +131 -0
  127. package/dist/instanced/levels.js.map +1 -0
  128. package/dist/instanced/lists.d.ts +57 -0
  129. package/dist/instanced/lists.js +114 -0
  130. package/dist/instanced/lists.js.map +1 -0
  131. package/dist/instanced/measure.d.ts +28 -0
  132. package/dist/instanced/measure.js +203 -0
  133. package/dist/instanced/measure.js.map +1 -0
  134. package/dist/instanced/meshes.d.ts +44 -51
  135. package/dist/instanced/meshes.js +167 -179
  136. package/dist/instanced/meshes.js.map +1 -1
  137. package/dist/instanced/mirror.d.ts +24 -0
  138. package/dist/instanced/mirror.js +76 -0
  139. package/dist/instanced/mirror.js.map +1 -0
  140. package/dist/instanced/raycast.d.ts +10 -11
  141. package/dist/instanced/raycast.js +31 -41
  142. package/dist/instanced/raycast.js.map +1 -1
  143. package/dist/instanced/rows.d.ts +50 -0
  144. package/dist/instanced/rows.js +36 -0
  145. package/dist/instanced/rows.js.map +1 -0
  146. package/dist/instanced/shape.d.ts +27 -0
  147. package/dist/instanced/shape.js +54 -0
  148. package/dist/instanced/shape.js.map +1 -0
  149. package/dist/instanced/sort.d.ts +61 -0
  150. package/dist/instanced/sort.js +192 -0
  151. package/dist/instanced/sort.js.map +1 -0
  152. package/dist/instanced/update.d.ts +34 -0
  153. package/dist/instanced/update.js +180 -0
  154. package/dist/instanced/update.js.map +1 -0
  155. package/dist/levels/bounds.d.ts +21 -0
  156. package/dist/levels/bounds.js +42 -0
  157. package/dist/levels/bounds.js.map +1 -0
  158. package/dist/levels/cameras.d.ts +48 -0
  159. package/dist/levels/cameras.js +122 -0
  160. package/dist/levels/cameras.js.map +1 -0
  161. package/dist/levels/compile/contexts.d.ts +30 -0
  162. package/dist/levels/compile/contexts.js +18 -0
  163. package/dist/levels/compile/contexts.js.map +1 -0
  164. package/dist/levels/compile/index.d.ts +41 -0
  165. package/dist/levels/compile/index.js +193 -0
  166. package/dist/levels/compile/index.js.map +1 -0
  167. package/dist/levels/compile/pipelines.d.ts +26 -0
  168. package/dist/levels/compile/pipelines.js +172 -0
  169. package/dist/levels/compile/pipelines.js.map +1 -0
  170. package/dist/levels/compiles.d.ts +29 -0
  171. package/dist/levels/compiles.js +50 -0
  172. package/dist/levels/compiles.js.map +1 -0
  173. package/dist/levels/draw.d.ts +102 -0
  174. package/dist/levels/draw.js +401 -0
  175. package/dist/levels/draw.js.map +1 -0
  176. package/dist/levels/fade.d.ts +60 -0
  177. package/dist/levels/fade.js +129 -0
  178. package/dist/levels/fade.js.map +1 -0
  179. package/dist/levels/index.d.ts +99 -0
  180. package/dist/levels/index.js +155 -0
  181. package/dist/levels/index.js.map +1 -0
  182. package/dist/levels/item.d.ts +38 -0
  183. package/dist/levels/item.js +89 -0
  184. package/dist/levels/item.js.map +1 -0
  185. package/dist/levels/load.d.ts +31 -0
  186. package/dist/levels/load.js +144 -0
  187. package/dist/levels/load.js.map +1 -0
  188. package/dist/levels/manager.d.ts +158 -0
  189. package/dist/levels/manager.js +352 -0
  190. package/dist/levels/manager.js.map +1 -0
  191. package/dist/{material.d.ts → levels/material.d.ts} +2 -2
  192. package/dist/{material.js → levels/material.js} +6 -5
  193. package/dist/levels/material.js.map +1 -0
  194. package/dist/levels/renderer.d.ts +32 -0
  195. package/dist/levels/renderer.js +57 -0
  196. package/dist/levels/renderer.js.map +1 -0
  197. package/dist/levels/requests.d.ts +52 -0
  198. package/dist/levels/requests.js +97 -0
  199. package/dist/levels/requests.js.map +1 -0
  200. package/dist/levels/screen.d.ts +14 -0
  201. package/dist/levels/screen.js +21 -0
  202. package/dist/levels/screen.js.map +1 -0
  203. package/dist/loader/build.d.ts +10 -0
  204. package/dist/loader/build.js +28 -0
  205. package/dist/loader/build.js.map +1 -0
  206. package/dist/loader/context.d.ts +44 -0
  207. package/dist/loader/context.js +96 -0
  208. package/dist/loader/context.js.map +1 -0
  209. package/dist/loader/entry.d.ts +4 -0
  210. package/dist/loader/entry.js +43 -0
  211. package/dist/loader/entry.js.map +1 -0
  212. package/dist/loader/index.d.ts +76 -0
  213. package/dist/loader/index.js +272 -0
  214. package/dist/loader/index.js.map +1 -0
  215. package/dist/loader/level.d.ts +41 -0
  216. package/dist/loader/level.js +140 -0
  217. package/dist/loader/level.js.map +1 -0
  218. package/dist/loader/node.d.ts +26 -0
  219. package/dist/loader/node.js +199 -0
  220. package/dist/loader/node.js.map +1 -0
  221. package/dist/loader/request.d.ts +54 -0
  222. package/dist/loader/request.js +19 -0
  223. package/dist/loader/request.js.map +1 -0
  224. package/dist/loader/url.d.ts +10 -6
  225. package/dist/loader/url.js +22 -14
  226. package/dist/loader/url.js.map +1 -1
  227. package/dist/lod.d.ts +144 -43
  228. package/dist/lod.js +354 -163
  229. package/dist/lod.js.map +1 -1
  230. package/dist/meshopt.d.ts +6 -0
  231. package/dist/meshopt.js +20 -0
  232. package/dist/meshopt.js.map +1 -0
  233. package/dist/node-process.d.ts +5 -0
  234. package/dist/node-process.js +6 -0
  235. package/dist/node-process.js.map +1 -0
  236. package/dist/node.d.ts +2 -0
  237. package/dist/node.js +5 -0
  238. package/dist/node.js.map +1 -0
  239. package/dist/simplify/cards.d.ts +14 -0
  240. package/dist/simplify/cards.js +128 -0
  241. package/dist/simplify/cards.js.map +1 -0
  242. package/dist/{simplify.d.ts → simplify/index.d.ts} +8 -5
  243. package/dist/{simplify.js → simplify/index.js} +45 -27
  244. package/dist/simplify/index.js.map +1 -0
  245. package/dist/{bounds.d.ts → source/detail.d.ts} +9 -23
  246. package/dist/{bounds.js → source/detail.js} +28 -58
  247. package/dist/source/detail.js.map +1 -0
  248. package/dist/source/deviation.js +6 -6
  249. package/dist/source/deviation.js.map +1 -1
  250. package/dist/source/{shading.d.ts → evaluator.d.ts} +10 -10
  251. package/dist/source/{shading.js → evaluator.js} +5 -5
  252. package/dist/source/evaluator.js.map +1 -0
  253. package/dist/source/{trace.d.ts → raycaster.d.ts} +6 -6
  254. package/dist/source/{trace.js → raycaster.js} +8 -8
  255. package/dist/source/raycaster.js.map +1 -0
  256. package/dist/source/{texels.d.ts → sampler.d.ts} +1 -1
  257. package/dist/source/{texels.js → sampler.js} +8 -5
  258. package/dist/source/sampler.js.map +1 -0
  259. package/dist/source/source.d.ts +1 -1
  260. package/dist/source/source.js +1 -1
  261. package/dist/source/source.js.map +1 -1
  262. package/dist/source/surface.js +1 -1
  263. package/dist/source/surface.js.map +1 -1
  264. package/dist/task.d.ts +6 -0
  265. package/dist/{pause.js → task.js} +5 -5
  266. package/dist/task.js.map +1 -0
  267. package/dist/three.d.ts +19 -30
  268. package/dist/three.js +30 -57
  269. package/dist/three.js.map +1 -1
  270. package/dist/tsl.d.ts +8 -12
  271. package/dist/tsl.js +11 -39
  272. package/dist/tsl.js.map +1 -1
  273. package/dist/typegpu.d.ts +37 -0
  274. package/dist/typegpu.js +37 -0
  275. package/dist/typegpu.js.map +1 -0
  276. package/dist/wind/bounds.js +3 -3
  277. package/dist/wind/bounds.js.map +1 -1
  278. package/dist/wind/hooks.d.ts +7 -4
  279. package/dist/wind/hooks.js +5 -2
  280. package/dist/wind/hooks.js.map +1 -1
  281. package/dist/wind/index.d.ts +4 -4
  282. package/dist/wind/index.js +25 -23
  283. package/dist/wind/index.js.map +1 -1
  284. package/dist/wind/sway.d.ts +2 -0
  285. package/dist/wind/sway.js +4 -1
  286. package/dist/wind/sway.js.map +1 -1
  287. package/package.json +24 -10
  288. package/skills/lod/SKILL.md +120 -32
  289. package/dist/bounds.js.map +0 -1
  290. package/dist/compile.d.ts +0 -4
  291. package/dist/compile.js +0 -100
  292. package/dist/compile.js.map +0 -1
  293. package/dist/deferred.d.ts +0 -12
  294. package/dist/deferred.js +0 -27
  295. package/dist/deferred.js.map +0 -1
  296. package/dist/fade.d.ts +0 -36
  297. package/dist/fade.js +0 -112
  298. package/dist/fade.js.map +0 -1
  299. package/dist/instanced/args.d.ts +0 -20
  300. package/dist/instanced/args.js +0 -77
  301. package/dist/instanced/args.js.map +0 -1
  302. package/dist/instanced/blocks.d.ts +0 -66
  303. package/dist/instanced/blocks.js +0 -294
  304. package/dist/instanced/blocks.js.map +0 -1
  305. package/dist/instanced/dirty.d.ts +0 -15
  306. package/dist/instanced/dirty.js +0 -96
  307. package/dist/instanced/dirty.js.map +0 -1
  308. package/dist/instanced/index.d.ts +0 -90
  309. package/dist/instanced/index.js +0 -349
  310. package/dist/instanced/index.js.map +0 -1
  311. package/dist/instanced/parts.d.ts +0 -14
  312. package/dist/instanced/parts.js +0 -79
  313. package/dist/instanced/parts.js.map +0 -1
  314. package/dist/instanced/select.d.ts +0 -92
  315. package/dist/instanced/select.js +0 -315
  316. package/dist/instanced/select.js.map +0 -1
  317. package/dist/instanced/store.d.ts +0 -31
  318. package/dist/instanced/store.js +0 -96
  319. package/dist/instanced/store.js.map +0 -1
  320. package/dist/levels.d.ts +0 -95
  321. package/dist/levels.js +0 -171
  322. package/dist/levels.js.map +0 -1
  323. package/dist/loader/bundle.d.ts +0 -25
  324. package/dist/loader/bundle.js +0 -241
  325. package/dist/loader/bundle.js.map +0 -1
  326. package/dist/loader/cache.d.ts +0 -15
  327. package/dist/loader/cache.js +0 -75
  328. package/dist/loader/cache.js.map +0 -1
  329. package/dist/loader/provenance.d.ts +0 -30
  330. package/dist/loader/provenance.js +0 -105
  331. package/dist/loader/provenance.js.map +0 -1
  332. package/dist/loader.d.ts +0 -55
  333. package/dist/loader.js +0 -239
  334. package/dist/loader.js.map +0 -1
  335. package/dist/material.js.map +0 -1
  336. package/dist/mesh/codec.d.ts +0 -4
  337. package/dist/mesh/codec.js.map +0 -1
  338. package/dist/pause.d.ts +0 -6
  339. package/dist/pause.js.map +0 -1
  340. package/dist/queue.d.ts +0 -2
  341. package/dist/queue.js +0 -33
  342. package/dist/queue.js.map +0 -1
  343. package/dist/renderer.d.ts +0 -21
  344. package/dist/renderer.js +0 -83
  345. package/dist/renderer.js.map +0 -1
  346. package/dist/residency.d.ts +0 -44
  347. package/dist/residency.js +0 -205
  348. package/dist/residency.js.map +0 -1
  349. package/dist/simplify.js.map +0 -1
  350. package/dist/source/shading.js.map +0 -1
  351. package/dist/source/texels.js.map +0 -1
  352. package/dist/source/trace.js.map +0 -1
  353. package/dist/view.d.ts +0 -45
  354. package/dist/view.js +0 -131
  355. package/dist/view.js.map +0 -1
@@ -0,0 +1,120 @@
1
+ import { read, write } from "ktx-parse";
2
+ import { inNode } from "../../node-process.js";
3
+ // Read when the module loads, which also happens in Node, as the vitecache plugin builds levels; Node before 21 has no navigator.
4
+ const cores = globalThis.navigator?.hardwareConcurrency ?? 4;
5
+ /**
6
+ * A worker per core but one, since a cold ladder's encodes take far longer than its bakes; at most 8, since each holds
7
+ * 100 to 250 MB of WebAssembly memory.
8
+ */
9
+ const LIMIT = Math.max(1, Math.min(8, cores - 1));
10
+ /** Largest job first, so that the smaller ones fill the other workers meanwhile. */
11
+ const queue = [];
12
+ /** How many encoder workers run: a process-wide pool, as each holds its own WASM memory and LIMIT bounds them all. */
13
+ let workers = 0;
14
+ /**
15
+ * One map as a KTX2 file of Basis UASTC. Each level encodes as `parts` strips of rows, by default one per worker, so
16
+ * that a map's top level, which holds three quarters of its texels, takes all workers; the strips' and levels' files
17
+ * are then joined. Takes about a second per million texels and worker.
18
+ */
19
+ export async function encodeLayer({ levels, size, srgb }, parts = LIMIT) {
20
+ const files = await Promise.all(levels.map((data, m) => Promise.all(strips(data, size >> m, srgb, parts).map((job) => encodeJob(job).then(read)))));
21
+ const first = files[0]?.[0];
22
+ if (!first)
23
+ throw new Error("encodeImpostorAsync: a map has no mip levels");
24
+ // UASTC encodes each 4x4 block on its own, and a level's Zstandard data may be several frames, which decode as one:
25
+ // a level's strips, each a multiple of four rows high but the last, concatenate to data that decodes as the whole level's.
26
+ first.levels = files.map((parts) => {
27
+ const levels = parts.map((file) => {
28
+ const [level] = file.levels;
29
+ if (!level)
30
+ throw new Error("encodeImpostorAsync: the encoder wrote a file without levels");
31
+ return level;
32
+ });
33
+ const levelData = new Uint8Array(levels.reduce((sum, level) => sum + level.levelData.length, 0));
34
+ let offset = 0;
35
+ for (const level of levels) {
36
+ levelData.set(level.levelData, offset);
37
+ offset += level.levelData.length;
38
+ }
39
+ return { levelData, uncompressedByteLength: levels.reduce((sum, level) => sum + level.uncompressedByteLength, 0) };
40
+ });
41
+ first.pixelHeight = size;
42
+ first.levelCount = files.length;
43
+ return write(first);
44
+ }
45
+ /** A `size`² level's strips: at most `parts`, each a multiple of four rows high but perhaps the last. */
46
+ function strips(data, size, srgb, parts) {
47
+ const rows = 4 * Math.ceil(size / parts / 4);
48
+ const jobs = [];
49
+ // Sliced: each job owns its buffer, which moves to its worker.
50
+ for (let y = 0; y < size; y += rows) {
51
+ const height = Math.min(rows, size - y);
52
+ jobs.push({ data: data.slice(4 * size * y, 4 * size * (y + height)), width: size, height, srgb });
53
+ }
54
+ return jobs;
55
+ }
56
+ async function encodeJob(job) {
57
+ if (inNode)
58
+ return (await import("./uastc.js")).encode(job);
59
+ return new Promise((resolve, reject) => {
60
+ queue.push({ job, resolve, reject });
61
+ queue.sort((a, b) => b.job.width * b.job.height - a.job.width * a.job.height);
62
+ if (workers < LIMIT)
63
+ void work();
64
+ });
65
+ }
66
+ /** One worker, with its own encoder instance, that takes queued jobs until none is left and then ends. */
67
+ async function work() {
68
+ workers++;
69
+ let worker;
70
+ try {
71
+ for (let task = queue.shift(); task; task = queue.shift()) {
72
+ try {
73
+ worker ??= await start();
74
+ const reply = await run(worker, task.job);
75
+ if ("file" in reply)
76
+ task.resolve(reply.file);
77
+ else
78
+ task.reject(new Error(`encodeImpostorAsync: ${reply.error}`));
79
+ }
80
+ catch (error) {
81
+ // The worker failed to load or crashed; the next job gets a fresh one.
82
+ task.reject(error);
83
+ worker?.terminate();
84
+ worker = undefined;
85
+ }
86
+ }
87
+ }
88
+ finally {
89
+ worker?.terminate();
90
+ workers--;
91
+ }
92
+ }
93
+ async function start() {
94
+ const { url } = await import("./worker.js");
95
+ return new Worker(url, { type: "module" });
96
+ }
97
+ /** `job` on `worker`; rejects when the worker fails rather than answers, as one that does not load does. */
98
+ function run(worker, job) {
99
+ return new Promise((resolve, reject) => {
100
+ const settle = () => {
101
+ worker.removeEventListener("message", message);
102
+ worker.removeEventListener("error", error);
103
+ worker.removeEventListener("messageerror", error);
104
+ };
105
+ const message = (event) => {
106
+ settle();
107
+ resolve(event.data);
108
+ };
109
+ const error = (event) => {
110
+ settle();
111
+ const why = event instanceof ErrorEvent ? event.message : `${event.type} event`;
112
+ reject(new Error(`encodeImpostorAsync: the encoder worker failed (${why})`));
113
+ };
114
+ worker.addEventListener("message", message);
115
+ worker.addEventListener("error", error);
116
+ worker.addEventListener("messageerror", error);
117
+ worker.postMessage(job, [job.data.buffer]);
118
+ });
119
+ }
120
+ //# sourceMappingURL=encode.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"encode.js","sourceRoot":"","sources":["../../../src/impostor/ktx2/encode.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import type { ImpostorLayer } from "../impostor.js";
2
+ /** A map's KTX2 file as the blocks of a GPU format, transcoded in three's workers. */
3
+ export declare function transcode(file: Uint8Array): Promise<ImpostorLayer>;
@@ -0,0 +1,99 @@
1
+ import { inflateSync } from "fflate";
2
+ import { KTX2Loader } from "three/addons/loaders/KTX2Loader.js";
3
+ import { LoadingManager } from "three/webgpu";
4
+ /** The page's one KTX2Loader for impostor layers: process-wide, as its transcoder workers are, and freed when idle. */
5
+ let shared;
6
+ /** Transcodes not yet answered, and the timer that disposes the loader once none has been for IDLE_MS. */
7
+ let active = 0;
8
+ let idle;
9
+ /** How long the loader outlives its last transcode. Its workers and their transcoders are freed then, so
10
+ * another library's KTX2Loader (each has one) is the page's only one but while both transcode. */
11
+ const IDLE_MS = 1000;
12
+ /**
13
+ * One KTX2Loader for every impostor at a time, as three asks: made at the first transcode, disposed once idle.
14
+ * It transcodes to the formats the GPU adapter takes, which are those
15
+ * of any WebGPURenderer device on it: three's WebGPURenderer requests every feature the adapter has, unless it is given
16
+ * a `device`, which then needs the same texture-compression features. Without WebGPU it transcodes to RGBA. The loader would fetch the Basis transcoder from three's `libs/basis` folder; it reads the copy
17
+ * this package carries instead (see scripts/basis.ts).
18
+ */
19
+ function loader() {
20
+ shared ??= (async () => {
21
+ const [has, files] = await Promise.all([adapterFeatures(), carriedFiles()]);
22
+ const manager = new LoadingManager().setURLModifier((url) => files.get(url) ?? url);
23
+ // given no path, the loader reads files next to its own module, which a build emits under hashed names
24
+ const loader = new KTX2Loader(manager).setTranscoderPath(BASIS);
25
+ // What detectSupport finds on a WebGPURenderer; WebGPU has no ETC1, S3TC or PVRTC features.
26
+ loader.workerConfig = {
27
+ astcSupported: has("texture-compression-astc"),
28
+ astcHDRSupported: false,
29
+ etc1Supported: false,
30
+ etc2Supported: has("texture-compression-etc2"),
31
+ dxtSupported: false,
32
+ bptcSupported: has("texture-compression-bc"),
33
+ pvrtcSupported: false,
34
+ };
35
+ return loader;
36
+ })();
37
+ return shared;
38
+ }
39
+ /** A map's KTX2 file as the blocks of a GPU format, transcoded in three's workers. */
40
+ export async function transcode(file) {
41
+ const texture = await parse(file);
42
+ const mipmaps = texture.mipmaps.map(({ data }) => {
43
+ if (!(data instanceof Uint8Array))
44
+ throw new Error(`transcoded to ${data.constructor.name}, not bytes`);
45
+ return data;
46
+ });
47
+ return { format: texture.format, mipmaps };
48
+ }
49
+ async function parse(file) {
50
+ clearTimeout(idle);
51
+ active++;
52
+ try {
53
+ const ktx2 = await loader();
54
+ // The loader hands its buffer to a worker.
55
+ return await new Promise((resolve, reject) => ktx2.parse(file.slice().buffer, resolve, reject));
56
+ }
57
+ finally {
58
+ if (--active === 0) {
59
+ idle = setTimeout(release, IDLE_MS);
60
+ // Releasing frees memory; it must not keep Node.js running once nothing else does.
61
+ const timer = idle;
62
+ if (typeof timer === "object" && timer !== null && "unref" in timer && typeof timer.unref === "function")
63
+ timer.unref();
64
+ }
65
+ }
66
+ }
67
+ function release() {
68
+ const released = shared;
69
+ shared = undefined;
70
+ void released?.then((loader) => loader.dispose());
71
+ }
72
+ /** The bundled transcoder's files, inflated once: immutable, and shared by every loader made after. */
73
+ let carried;
74
+ /** The carried transcoder's files by the URLs the loader asks for: made once, for every loader made after. */
75
+ function carriedFiles() {
76
+ carried ??= import("./wasm/transcoder.js").then(({ TRANSCODER_JS, TRANSCODER_WASM }) => new Map([
77
+ [`${BASIS}basis_transcoder.js`, blob(TRANSCODER_JS, "text/javascript")],
78
+ [`${BASIS}basis_transcoder.wasm`, blob(TRANSCODER_WASM, "application/wasm")],
79
+ ]));
80
+ return carried;
81
+ }
82
+ /** Where the loader is told its transcoder lies: the URLs it then asks for map to the carried copy. */
83
+ const BASIS = "lod-basis:/";
84
+ /** A URL of `base64`'s deflated bytes. */
85
+ const blob = (base64, type) => URL.createObjectURL(new Blob([inflateSync(Uint8Array.from(atob(base64), (c) => c.charCodeAt(0)))], { type }));
86
+ /** Whether the default WebGPU adapter has a feature; none without WebGPU. The package's types leave WebGPU's out. */
87
+ async function adapterFeatures() {
88
+ const gpu = typeof navigator === "undefined" ? undefined : Reflect.get(navigator, "gpu");
89
+ const request = typeof gpu === "object" && gpu !== null ? Reflect.get(gpu, "requestAdapter") : undefined;
90
+ if (typeof request !== "function")
91
+ return () => false;
92
+ const adapter = await Reflect.apply(request, gpu, []);
93
+ const features = typeof adapter === "object" && adapter !== null ? Reflect.get(adapter, "features") : undefined;
94
+ const has = typeof features === "object" && features !== null ? Reflect.get(features, "has") : undefined;
95
+ if (typeof has !== "function")
96
+ return () => false;
97
+ return (feature) => Reflect.apply(has, features, [feature]) === true;
98
+ }
99
+ //# sourceMappingURL=transcode.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"transcode.js","sourceRoot":"","sources":["../../../src/impostor/ktx2/transcode.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ import type { Job } from "./encode.js";
2
+ /**
3
+ * Rows of a mip level as a KTX2 file of UASTC LDR 4x4 with Zstandard supercompression, at level 1 (see PACK_FLAGS) and
4
+ * without RDO, which would trade normal accuracy for size. The encoder's own mips would filter level 0, so each baked
5
+ * level is encoded on its own (see `encodeLayer`).
6
+ */
7
+ export declare function encode({ data, width, height, srgb }: Job): Promise<Uint8Array>;
@@ -0,0 +1,65 @@
1
+ import { inflateSync } from "fflate";
2
+ import { ENCODER_JS, ENCODER_WASM } from "./wasm/encoder.js";
3
+ /** basisu's encoder module, instantiated once: a process-wide WASM module, as three's decoders are. */
4
+ let basis;
5
+ /**
6
+ * basisu's pack flags: level 1, which encodes about twice as fast as the default level 2 and loses under 0.1 dB on
7
+ * albedo and normal maps (level 0 loses 1 to 4 dB), with the fastest ETC1 hints (128), which only transcodes to ETC1
8
+ * and ETC2 read; three picks those only on a GPU without ASTC and BC texture compression, which WebGPU adapters on
9
+ * desktops and most phones have.
10
+ */
11
+ const PACK_FLAGS = 1 | 128;
12
+ /**
13
+ * Rows of a mip level as a KTX2 file of UASTC LDR 4x4 with Zstandard supercompression, at level 1 (see PACK_FLAGS) and
14
+ * without RDO, which would trade normal accuracy for size. The encoder's own mips would filter level 0, so each baked
15
+ * level is encoded on its own (see `encodeLayer`).
16
+ */
17
+ export async function encode({ data, width, height, srgb }) {
18
+ const encoder = new (await (basis ??= load())).BasisEncoder();
19
+ try {
20
+ encoder.setCreateKTX2File(true);
21
+ encoder.setUASTC(true);
22
+ // basisu's enums: texture type 0 is a 2D texture; image format 0 is raw RGBA8
23
+ encoder.setTexType(0);
24
+ if (!encoder.setSliceSourceImage(0, data, width, height, 0))
25
+ throw new Error(`the Basis encoder took no ${width}x${height} image`);
26
+ encoder.setPerceptual(srgb);
27
+ encoder.setKTX2AndBasisSRGBTransferFunc(srgb);
28
+ encoder.setMipGen(false);
29
+ encoder.setPackUASTCFlags(PACK_FLAGS);
30
+ encoder.setKTX2UASTCSupercompression(true);
31
+ const out = new Uint8Array(4 * width * height + 65536);
32
+ const length = encoder.encode(out);
33
+ if (length === 0)
34
+ throw new Error(`the Basis encoder failed on a ${width}x${height} image`);
35
+ return out.slice(0, length);
36
+ }
37
+ finally {
38
+ encoder.delete();
39
+ }
40
+ }
41
+ /**
42
+ * The encoder's Emscripten module (see scripts/basis.ts), started on its binary. Imported from a data: URL, which
43
+ * browsers and Node both import, unlike a blob: URL.
44
+ */
45
+ async function load() {
46
+ const url = `data:text/javascript,${encodeURIComponent(new TextDecoder().decode(inflate(ENCODER_JS)))}`;
47
+ const factory = (await import(/* @vite-ignore */ url)).default;
48
+ if (typeof factory !== "function")
49
+ throw new Error("the Basis encoder module has no factory");
50
+ // the module names its binary relative to its own URL, which a data: URL's is not: named, then given. It prints every
51
+ // image's progress, which nothing needs.
52
+ const basis = await factory({ wasmBinary: inflate(ENCODER_WASM), locateFile: (name) => name, print: () => { } });
53
+ if (!isBasis(basis))
54
+ throw new Error("the Basis encoder module lacks its bindings");
55
+ basis.initializeBasis();
56
+ return basis;
57
+ }
58
+ function isBasis(value) {
59
+ return (typeof value === "object" &&
60
+ value !== null &&
61
+ typeof Reflect.get(value, "BasisEncoder") === "function" &&
62
+ typeof Reflect.get(value, "initializeBasis") === "function");
63
+ }
64
+ const inflate = (base64) => inflateSync(Uint8Array.from(atob(base64), (c) => c.charCodeAt(0)));
65
+ //# sourceMappingURL=uastc.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"uastc.js","sourceRoot":"","sources":["../../../src/impostor/ktx2/uastc.ts"],"names":[],"mappings":"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"}