@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,90 @@
1
+ import { HalfFloatType, NearestFilter, RenderTarget, Vector2 } from "three/webgpu";
2
+ import { at } from "../../at.js";
3
+ import { readFloats } from "../../bake.js";
4
+ import { nextTask } from "../../task.js";
5
+ import { OUTPUTS } from "./materials.js";
6
+ // Rendering an atlas mip: its frames side by side in sheets, each read back at once.
7
+ /** Edge of the largest target frames render into side by side, a sheet, which is read back at once. */
8
+ const SHEET = 1024;
9
+ /**
10
+ * Colour attachments one target renders: four half-float targets fill the 32 bytes per
11
+ * sample WebGPU guarantees.
12
+ */
13
+ const PER_TARGET = 4;
14
+ /**
15
+ * Render every frame (`frameCameras`: camera matrices, in atlas order) into `atlas`, at its
16
+ * cell size × `supersample`. Frames render side by side into sheets of up to SHEET square,
17
+ * so that each map is read back once per sheet, into targets of up to PER_TARGET outputs.
18
+ */
19
+ export async function bakeMip(atlas, supersample, renderer, scene, camera, frameCameras) {
20
+ const { frames, maps } = atlas;
21
+ const side = atlas.cell * supersample;
22
+ const buffer = renderer.getDrawingBufferSize(new Vector2());
23
+ if (buffer.x === side && buffer.y === side)
24
+ throw new Error(`bakeImpostor: the renderer's canvas is ${side} px square, a frame's size: three would draw that frame over the whole sheet`);
25
+ const per = Math.max(1, Math.min(frames, Math.floor(SHEET / side)));
26
+ const width = per * side;
27
+ // one output per map, then the second way to store the normals (see ImpostorAtlasMip), then the specular
28
+ const names = OUTPUTS.filter((name) => (name === "emissive" ? maps.includes("emissive") : name !== "specular" || atlas.specular));
29
+ const targets = Array.from({ length: Math.ceil(names.length / PER_TARGET) }, (_, p) => {
30
+ const outputs = names.slice(p * PER_TARGET, (p + 1) * PER_TARGET);
31
+ const target = new RenderTarget(width, width, {
32
+ count: outputs.length,
33
+ type: HalfFloatType,
34
+ minFilter: NearestFilter,
35
+ magFilter: NearestFilter,
36
+ depthBuffer: true,
37
+ });
38
+ outputs.forEach((name, i) => {
39
+ const texture = target.textures[i];
40
+ if (!texture)
41
+ throw new Error("bakeImpostor: a render target lacks a texture");
42
+ texture.name = name;
43
+ });
44
+ return target;
45
+ });
46
+ try {
47
+ for (let row0 = 0; row0 < frames; row0 += per)
48
+ for (let col0 = 0; col0 < frames; col0 += per) {
49
+ const sheet = [];
50
+ for (let row = row0; row < Math.min(row0 + per, frames); row++)
51
+ for (let col = col0; col < Math.min(col0 + per, frames); col++)
52
+ sheet.push({ col, row, x: (col - col0) * side, y: (row - row0) * side });
53
+ const placed = sheet.map(({ col, row, x, y }) => ({ matrix: at(frameCameras, row * frames + col), x, y }));
54
+ for (const target of targets)
55
+ renderSheet(renderer, target, scene, camera, placed, side);
56
+ const pixels = await Promise.all(targets.flatMap((target) => target.textures.map((_, i) => readFloats(renderer, target, i))));
57
+ for (const { col, row, x, y } of sheet)
58
+ atlas.write(pixels, width, supersample, col, row, x, y);
59
+ // Yield to the page between sheets, so that a long bake does not freeze it.
60
+ await nextTask();
61
+ }
62
+ }
63
+ finally {
64
+ for (const target of targets)
65
+ target.dispose();
66
+ }
67
+ }
68
+ /**
69
+ * Clear `target` and render each frame, its camera at `matrix`, into its `side` square at (x, y), counted from the
70
+ * bottom left as the atlas is.
71
+ */
72
+ function renderSheet(renderer, target, scene, camera, frames, side) {
73
+ const previous = renderer.getRenderTarget();
74
+ renderer.setRenderTarget(target);
75
+ try {
76
+ renderer.clear(true, true, true);
77
+ for (const { matrix, x, y } of frames) {
78
+ // WebGPU counts viewport rows from the top; `readFloats` turns the image over.
79
+ const top = target.height - y - side;
80
+ target.viewport.set(x, top, side, side);
81
+ camera.matrix.copy(matrix);
82
+ camera.updateMatrixWorld(true);
83
+ renderer.render(scene, camera);
84
+ }
85
+ }
86
+ finally {
87
+ renderer.setRenderTarget(previous);
88
+ }
89
+ }
90
+ //# sourceMappingURL=sheet.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sheet.js","sourceRoot":"","sources":["../../../src/impostor/bake/sheet.ts"],"names":[],"mappings":"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"}
@@ -1,3 +1,4 @@
1
1
  import type { Object3D } from "three/webgpu";
2
- /** Snapshot before validation/bounds, without copying loader-added rooms or their resources. */
3
- export declare function sourceForBake(object: Object3D, excluded?: readonly Object3D[]): Object3D;
2
+ import { type BakeCopy } from "../../bake.js";
3
+ /** A copy of `object` to bake, which the bake may move and change; ImpostorMeshes are refused. */
4
+ export declare function sourceForBake(object: Object3D): Promise<BakeCopy>;
@@ -1,23 +1,12 @@
1
- import { clone } from "three/addons/utils/SkeletonUtils.js";
2
- import { forEachMesh } from "../../bounds.js";
1
+ import { bakeCopy } from "../../bake.js";
2
+ import { forEachMesh } from "../../source/detail.js";
3
3
  import { isImpostorMesh } from "../../three.js";
4
- /** Snapshot before validation/bounds, without copying loader-added rooms or their resources. */
5
- export function sourceForBake(object, excluded = []) {
6
- const children = object.children;
7
- try {
8
- // SkeletonUtils has no exclusion hook. This synchronous view emits no events and
9
- // is restored before any await, even if validation or a custom clone throws.
10
- // Cloning then removing rooms would allocate excluded nested LOD resources.
11
- if (excluded.length > 0)
12
- object.children = children.filter((child) => !excluded.includes(child));
13
- forEachMesh(object, (mesh) => {
14
- if (isImpostorMesh(mesh))
15
- throw new Error(`bakeImpostor: cannot bake an ImpostorMesh ("${mesh.name}"); bake from its source instead`);
16
- });
17
- return clone(object);
18
- }
19
- finally {
20
- object.children = children;
21
- }
4
+ /** A copy of `object` to bake, which the bake may move and change; ImpostorMeshes are refused. */
5
+ export function sourceForBake(object) {
6
+ forEachMesh(object, (mesh) => {
7
+ if (isImpostorMesh(mesh))
8
+ throw new Error(`bakeImpostor: cannot bake an ImpostorMesh ("${mesh.name}"); bake from its source instead`);
9
+ });
10
+ return bakeCopy(object);
22
11
  }
23
12
  //# sourceMappingURL=source.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"source.js","sourceRoot":"","sources":["../../../src/impostor/bake/source.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,EAAE,MAAM,qCAAqC,CAAC;AAC5D,OAAO,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAC9C,OAAO,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAEhD,gGAAgG;AAChG,MAAM,UAAU,aAAa,CAAC,MAAgB,EAAE,WAAgC,EAAE;IAChF,MAAM,QAAQ,GAAG,MAAM,CAAC,QAAQ,CAAC;IACjC,IAAI,CAAC;QACH,iFAAiF;QACjF,6EAA6E;QAC7E,4EAA4E;QAC5E,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC;YAAE,MAAM,CAAC,QAAQ,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC;QACjG,WAAW,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,EAAE;YAC3B,IAAI,cAAc,CAAC,IAAI,CAAC;gBAAE,MAAM,IAAI,KAAK,CAAC,+CAA+C,IAAI,CAAC,IAAI,kCAAkC,CAAC,CAAC;QACxI,CAAC,CAAC,CAAC;QACH,OAAO,KAAK,CAAC,MAAM,CAAC,CAAC;IACvB,CAAC;YAAS,CAAC;QACT,MAAM,CAAC,QAAQ,GAAG,QAAQ,CAAC;IAC7B,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"source.js","sourceRoot":"","sources":["../../../src/impostor/bake/source.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAiB,MAAM,eAAe,CAAC;AACxD,OAAO,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AACrD,OAAO,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAEhD,kGAAkG;AAClG,MAAM,UAAU,aAAa,CAAC,MAAgB;IAC5C,WAAW,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,EAAE;QAC3B,IAAI,cAAc,CAAC,IAAI,CAAC;YAAE,MAAM,IAAI,KAAK,CAAC,+CAA+C,IAAI,CAAC,IAAI,kCAAkC,CAAC,CAAC;IACxI,CAAC,CAAC,CAAC;IACH,OAAO,QAAQ,CAAC,MAAM,CAAC,CAAC;AAC1B,CAAC"}
@@ -1,9 +1,8 @@
1
1
  import { type Impostor } from "./impostor.js";
2
2
  /**
3
- * Serializes `impostor` to a KTX2 file: one RGBA8 UNORM 2D array texture with a layer per
4
- * map and its baked mip levels, zlib-supercompressed, plus the metadata as JSON under the
5
- * "impostor" key.
3
+ * Serializes a baked `impostor`: every field but the layers as JSON, then one KTX2 file per map of GPU-compressible
4
+ * Basis UASTC, encoded in workers. A few seconds for a 1024 atlas.
6
5
  */
7
- export declare function encodeImpostor(impostor: Impostor): Uint8Array;
8
- /** Parses a file written by `encodeImpostor`, inflating its mips off the main thread. */
6
+ export declare function encodeImpostorAsync(impostor: Impostor): Promise<Uint8Array>;
7
+ /** Parses a file written by `encodeImpostorAsync`, transcoding its maps off the main thread to a format the GPU takes. */
9
8
  export declare function decodeImpostorAsync(bytes: Uint8Array): Promise<Impostor>;
@@ -1,126 +1,53 @@
1
- import { unzlib, zlibSync } from "fflate";
2
- import { KHR_DF_CHANNEL_RGBSDA_ALPHA, KHR_DF_CHANNEL_RGBSDA_BLUE, KHR_DF_CHANNEL_RGBSDA_GREEN, KHR_DF_CHANNEL_RGBSDA_RED, KHR_DF_MODEL_RGBSDA, KHR_DF_TRANSFER_LINEAR, KHR_SUPERCOMPRESSION_ZLIB, VK_FORMAT_R8G8B8A8_UNORM, createDefaultContainer, read, write, } from "ktx-parse";
1
+ import { read } from "ktx-parse";
2
+ import { RGBAFormat } from "three/webgpu";
3
+ import { pack, unpack } from "../codec/container.js";
3
4
  import { validateImpostor } from "./impostor.js";
4
- /** Key/value entry holding every non-pixel field as JSON. */
5
- const KEY = "impostor";
5
+ import { encodeLayer } from "./ktx2/encode.js";
6
+ import { transcode } from "./ktx2/transcode.js";
7
+ const srgb = (map) => map === "base" || map === "emissive";
6
8
  /**
7
- * Serializes `impostor` to a KTX2 file: one RGBA8 UNORM 2D array texture with a layer per
8
- * map and its baked mip levels, zlib-supercompressed, plus the metadata as JSON under the
9
- * "impostor" key.
9
+ * Serializes a baked `impostor`: every field but the layers as JSON, then one KTX2 file per map of GPU-compressible
10
+ * Basis UASTC, encoded in workers. A few seconds for a 1024 atlas.
10
11
  */
11
- export function encodeImpostor(impostor) {
12
+ export async function encodeImpostorAsync(impostor) {
12
13
  validateImpostor(impostor);
13
14
  const { layers, ...meta } = impostor;
14
- const levelCount = layers[0]?.length ?? 0;
15
- // KTX2 stores each mip level with all its array layers, layer-major.
16
- const levels = Array.from({ length: levelCount }, (_, m) => {
17
- const bytes = (meta.size >> m) ** 2 * 4;
18
- const raw = new Uint8Array(layers.length * bytes);
19
- layers.forEach((layer, i) => raw.set(layer[m] ?? fail(`layer ${i} has no level ${m}`), i * bytes));
20
- return { levelData: zlibSync(raw, { level: 6 }), uncompressedByteLength: raw.length };
21
- });
22
- const ktx = createDefaultContainer();
23
- ktx.vkFormat = VK_FORMAT_R8G8B8A8_UNORM;
24
- ktx.typeSize = 1;
25
- ktx.pixelWidth = meta.size;
26
- ktx.pixelHeight = meta.size;
27
- ktx.layerCount = layers.length;
28
- ktx.levelCount = levels.length;
29
- ktx.supercompressionScheme = KHR_SUPERCOMPRESSION_ZLIB;
30
- ktx.levels = levels;
31
- // UNORM data must declare a linear transfer; base/emissive are sRGB-encoded but the
32
- // renderer decodes them itself, as it does with the linear normal/orm layers.
33
- const channels = [KHR_DF_CHANNEL_RGBSDA_RED, KHR_DF_CHANNEL_RGBSDA_GREEN, KHR_DF_CHANNEL_RGBSDA_BLUE, KHR_DF_CHANNEL_RGBSDA_ALPHA];
34
- for (const dfd of ktx.dataFormatDescriptor) {
35
- dfd.colorModel = KHR_DF_MODEL_RGBSDA;
36
- dfd.transferFunction = KHR_DF_TRANSFER_LINEAR;
37
- dfd.bytesPlane = [4, 0, 0, 0, 0, 0, 0, 0];
38
- dfd.samples = channels.map((channelType, i) => ({
39
- bitOffset: i * 8,
40
- bitLength: 7, // stored as bits - 1
41
- channelType,
42
- samplePosition: [0, 0, 0, 0],
43
- sampleLower: 0,
44
- sampleUpper: 255,
45
- }));
46
- }
47
- ktx.keyValue[KEY] = JSON.stringify(meta);
48
- return write(ktx);
15
+ const files = await Promise.all(layers.map((layer, i) => {
16
+ const map = impostor.maps[i];
17
+ if (!map || layer.format !== RGBAFormat)
18
+ throw new Error("encodeImpostorAsync: encode a baked impostor; this one holds compressed blocks");
19
+ return encodeLayer({ levels: layer.mipmaps, size: impostor.size, srgb: srgb(map) });
20
+ }));
21
+ return pack(meta, files);
49
22
  }
50
- /** Parses a file written by `encodeImpostor`, inflating its mips off the main thread. */
23
+ /** Parses a file written by `encodeImpostorAsync`, transcoding its maps off the main thread to a format the GPU takes. */
51
24
  export async function decodeImpostorAsync(bytes) {
52
- const file = parse(bytes);
53
- const levels = await Promise.all(file.levels.map(async ({ data, length }, m) => {
25
+ const { header, files } = await unpack(bytes, fail);
26
+ if (typeof header !== "object" || header === null)
27
+ fail("metadata is not an object");
28
+ const size = Reflect.get(header, "size");
29
+ const layers = await Promise.all(files.map(async (file, i) => {
30
+ let ktx;
31
+ try {
32
+ ktx = read(file);
33
+ }
34
+ catch (error) {
35
+ fail(`map ${i} is not a KTX2 file`, error);
36
+ }
37
+ if (ktx.pixelWidth !== size || ktx.pixelHeight !== size)
38
+ fail(`map ${i} is ${ktx.pixelWidth}x${ktx.pixelHeight}, not the atlas size`);
54
39
  try {
55
- // Move large mips off the main thread; small mips avoid worker startup cost.
56
- if (length >= 8 * 1024 * 1024)
57
- return await new Promise((resolve, reject) => {
58
- unzlib(data.slice(), { consume: true }, (error, raw) => {
59
- if (error)
60
- reject(error);
61
- else
62
- resolve(raw);
63
- });
64
- });
65
- const stream = new Blob([data.slice()]).stream().pipeThrough(new DecompressionStream("deflate"));
66
- return new Uint8Array(await new Response(stream).arrayBuffer());
40
+ return await transcode(file);
67
41
  }
68
42
  catch (error) {
69
- throw invalid(`level ${m} does not inflate`, error);
43
+ fail(`map ${i} does not transcode`, error);
70
44
  }
71
45
  }));
72
- return decoded(file, levels);
73
- }
74
- function parse(bytes) {
75
- // ktx-parse reads through `bytes.buffer` without checking the view's end, so a truncated
76
- // view would read past it; give it a buffer of exactly the file instead.
77
- const file = bytes.byteLength === bytes.buffer.byteLength ? bytes : bytes.slice();
78
- const ktx = attempt("not a KTX2 container", () => read(file));
79
- if (ktx.vkFormat !== VK_FORMAT_R8G8B8A8_UNORM)
80
- fail(`vkFormat ${ktx.vkFormat} is not R8G8B8A8_UNORM`);
81
- if (ktx.supercompressionScheme !== KHR_SUPERCOMPRESSION_ZLIB)
82
- fail(`supercompression ${ktx.supercompressionScheme} is not zlib`);
83
- if (ktx.pixelWidth !== ktx.pixelHeight)
84
- fail(`atlas is ${ktx.pixelWidth}x${ktx.pixelHeight}, not square`);
85
- const json = ktx.keyValue[KEY];
86
- if (!(json instanceof Uint8Array))
87
- fail(`missing "${KEY}" metadata`);
88
- // ktx-parse returns values of keys not starting with "KTX" as raw bytes, NUL included.
89
- const meta = attempt("metadata is not JSON", () => JSON.parse(new TextDecoder().decode(json).replace(/\0$/, "")));
90
- if (typeof meta !== "object" || meta === null)
91
- fail("metadata is not an object");
92
- const levels = ktx.levels.map((level, m) => {
93
- const bytes = (ktx.pixelWidth >> m) ** 2 * 4;
94
- if (level.uncompressedByteLength !== bytes * ktx.layerCount)
95
- fail(`level ${m} size does not match the atlas`);
96
- return { data: level.levelData, length: level.uncompressedByteLength };
97
- });
98
- return { meta, layerCount: ktx.layerCount, levels };
99
- }
100
- function decoded(file, levels) {
101
- levels.forEach((raw, m) => {
102
- if (raw.length !== file.levels[m]?.length)
103
- fail(`level ${m} inflates to the wrong size`);
104
- });
105
- // Layers share one inflated buffer per mip, in KTX2's layer-major order.
106
- const layers = Array.from({ length: file.layerCount }, (_, i) => levels.map((raw) => raw.subarray((i * raw.length) / file.layerCount, ((i + 1) * raw.length) / file.layerCount)));
107
- const impostor = { ...file.meta, layers };
46
+ const impostor = { ...header, layers };
108
47
  validateImpostor(impostor);
109
48
  return impostor;
110
49
  }
111
- function fail(why) {
112
- throw new Error(`Invalid impostor file: ${why}`);
113
- }
114
- /** Runs `run`, turning any throw into an "Invalid impostor file" error. */
115
- function attempt(why, run) {
116
- try {
117
- return run();
118
- }
119
- catch (error) {
120
- throw invalid(why, error);
121
- }
122
- }
123
- function invalid(why, error) {
124
- return new Error(`Invalid impostor file: ${why} (${error instanceof Error ? error.message : String(error)})`, { cause: error });
50
+ function fail(why, cause) {
51
+ throw new Error(`Invalid impostor file: ${why}`, { cause });
125
52
  }
126
53
  //# sourceMappingURL=codec.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"codec.js","sourceRoot":"","sources":["../../src/impostor/codec.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"codec.js","sourceRoot":"","sources":["../../src/impostor/codec.ts"],"names":[],"mappings":"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"}
@@ -1,7 +1,8 @@
1
+ import { RGBAFormat, type CompressedPixelFormat } from "three/webgpu";
1
2
  /** Which part of the view sphere the atlas covers. */
2
3
  export type ImpostorLayout = "hemi" | "full";
3
4
  /**
4
- * The atlas maps, in the order they are stored. Each is one RGBA8 layer:
5
+ * The atlas maps, in the order they are stored. Each is one RGBA layer:
5
6
  *
6
7
  * - `base`: base colour (sRGB) in RGB, coverage in A.
7
8
  * - `normalDepth`: an object-space normal n in RGB (`n * 0.5 + 0.5`), depth in A. The
@@ -13,6 +14,18 @@ export type ImpostorLayout = "hemi" | "full";
13
14
  */
14
15
  export declare const MAPS: readonly ["base", "normalDepth", "orm", "emissive"];
15
16
  export type ImpostorMap = (typeof MAPS)[number];
17
+ /**
18
+ * One map's mip chain, `size >> level` square, from `size` down to one texel per frame (`frames` square). The levels
19
+ * are baked, not filtered from level 0.
20
+ */
21
+ export interface ImpostorLayer {
22
+ /**
23
+ * RGBAFormat: 4 bytes a texel, as baked. A decoded impostor holds the block-compressed format its decoder transcoded
24
+ * to for the GPU, or RGBAFormat where the GPU takes none.
25
+ */
26
+ format: typeof RGBAFormat | CompressedPixelFormat;
27
+ mipmaps: Uint8Array[];
28
+ }
16
29
  /**
17
30
  * A baked octahedral impostor: plain data, no GPU resources.
18
31
  *
@@ -25,7 +38,7 @@ export type ImpostorMap = (typeof MAPS)[number];
25
38
  * toward the camera that baked the frame and 0 is away from it.
26
39
  */
27
40
  export interface Impostor {
28
- version: 3;
41
+ version: 4;
29
42
  layout: ImpostorLayout;
30
43
  /** frames per atlas side */
31
44
  frames: number;
@@ -45,22 +58,33 @@ export interface Impostor {
45
58
  */
46
59
  specular?: [number, number, number, number];
47
60
  /**
48
- * One per entry in `maps`: its mip chain of RGBA8 arrays, `size >> level` square, from
49
- * `size` down to one texel per frame (`frames` square). The levels are baked, not
50
- * filtered from level 0. An ImpostorMesh's textures share these arrays, so they stay in
51
- * memory while the impostor is referenced, ready for `encodeImpostor`.
61
+ * One per entry in `maps`. An ImpostorMesh's textures share these arrays, so they stay in memory while the impostor is
62
+ * referenced, ready for `encodeImpostorAsync` when they are RGBAFormat.
52
63
  */
53
- layers: Uint8Array[][];
64
+ layers: ImpostorLayer[];
54
65
  }
55
66
  export declare function boxCentre(b: Impostor["box"]): [number, number, number];
56
67
  /** Half the box's edges. */
57
68
  export declare function boxExtent(b: Impostor["box"]): [number, number, number];
58
69
  /** Radius of the sphere around the box: the depth channel's unit. */
59
70
  export declare function boundingRadius(b: Impostor["box"]): number;
71
+ /**
72
+ * Empty border around the object in every frame, as a fraction of the frame's half
73
+ * size. It keeps mip levels from blending a frame's silhouette into its neighbour.
74
+ */
75
+ export declare const PAD = 0.06;
76
+ /**
77
+ * `texelPixels` of any impostor baked at `resolution`, at least: a frame fitted to the source's bounding sphere, the
78
+ * widest it can be. The default `maxPixels` of an impostor level a loader describes before building it.
79
+ */
80
+ export declare const framePixels: (resolution?: number) => number;
60
81
  /**
61
82
  * On-screen height of the object at which two atlas texels span one pixel: the default
62
83
  * `LodLevel.maxPixels` of an impostor. An impostor blends filtered reads of several
63
84
  * views, so it keeps the source's colour detail only down to about two texels per pixel.
85
+ * A CachedLodLoader describes its levels before baking them, so its impostor levels default to
86
+ * `framePixels` instead: this height for a frame fitted to the bounding sphere, up to about
87
+ * 1.5 times lower than for the frame the bake fits.
64
88
  */
65
89
  export declare function texelPixels(impostor: Pick<Impostor, "size" | "frames" | "box" | "halfSize">): number;
66
90
  /** Throws unless `value` is a usable impostor. */
@@ -1,5 +1,6 @@
1
+ import { RGBAFormat } from "three/webgpu";
1
2
  /**
2
- * The atlas maps, in the order they are stored. Each is one RGBA8 layer:
3
+ * The atlas maps, in the order they are stored. Each is one RGBA layer:
3
4
  *
4
5
  * - `base`: base colour (sRGB) in RGB, coverage in A.
5
6
  * - `normalDepth`: an object-space normal n in RGB (`n * 0.5 + 0.5`), depth in A. The
@@ -21,10 +22,23 @@ export function boxExtent(b) {
21
22
  export function boundingRadius(b) {
22
23
  return Math.hypot(b[3] - b[0], b[4] - b[1], b[5] - b[2]) / 2;
23
24
  }
25
+ /**
26
+ * Empty border around the object in every frame, as a fraction of the frame's half
27
+ * size. It keeps mip levels from blending a frame's silhouette into its neighbour.
28
+ */
29
+ export const PAD = 0.06;
30
+ /**
31
+ * `texelPixels` of any impostor baked at `resolution`, at least: a frame fitted to the source's bounding sphere, the
32
+ * widest it can be. The default `maxPixels` of an impostor level a loader describes before building it.
33
+ */
34
+ export const framePixels = (resolution = 128) => 2 ** Math.floor(Math.log2(resolution)) / (2 * (1 + PAD));
24
35
  /**
25
36
  * On-screen height of the object at which two atlas texels span one pixel: the default
26
37
  * `LodLevel.maxPixels` of an impostor. An impostor blends filtered reads of several
27
38
  * views, so it keeps the source's colour detail only down to about two texels per pixel.
39
+ * A CachedLodLoader describes its levels before baking them, so its impostor levels default to
40
+ * `framePixels` instead: this height for a frame fitted to the bounding sphere, up to about
41
+ * 1.5 times lower than for the frame the bake fits.
28
42
  */
29
43
  export function texelPixels(impostor) {
30
44
  const cell = impostor.size / impostor.frames;
@@ -42,7 +56,7 @@ export function validateImpostor(value) {
42
56
  fail("not an object");
43
57
  const fields = value;
44
58
  const { version, layout, frames, size, box, halfSize, maps, specular, layers } = fields;
45
- if (version !== 3)
59
+ if (version !== 4)
46
60
  fail(`unsupported version ${String(version)}; bake it again`);
47
61
  if (layout !== "hemi" && layout !== "full")
48
62
  fail(`unknown layout "${String(layout)}"`);
@@ -67,12 +81,13 @@ export function validateImpostor(value) {
67
81
  fail(`frame size ${cell} is not a power of two`);
68
82
  const levels = Math.log2(cell) + 1;
69
83
  for (const layer of layers) {
70
- if (!Array.isArray(layer) || layer.length !== levels)
84
+ if (typeof layer !== "object" || layer === null || !Array.isArray(layer.mipmaps) || layer.mipmaps.length !== levels)
71
85
  fail(`every layer must be a mip chain of ${levels} levels`);
72
- layer.forEach((level, m) => {
86
+ const rgba = layer.format === RGBAFormat;
87
+ layer.mipmaps.forEach((level, m) => {
73
88
  const bytes = (size >> m) ** 2 * 4;
74
- if (!(level instanceof Uint8Array) || level.length !== bytes)
75
- fail(`mip level ${m} must be a Uint8Array of ${bytes} bytes`);
89
+ if (!(level instanceof Uint8Array) || (rgba ? level.length !== bytes : !level.length))
90
+ fail(`mip level ${m} must be a Uint8Array${rgba ? ` of ${bytes} bytes` : ""}`);
76
91
  });
77
92
  }
78
93
  }
@@ -1 +1 @@
1
- {"version":3,"file":"impostor.js","sourceRoot":"","sources":["../../src/impostor/impostor.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"impostor.js","sourceRoot":"","sources":["../../src/impostor/impostor.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,26 @@
1
+ /** One map's RGBA8 mip levels, `size >> level` square. */
2
+ export interface Layer {
3
+ levels: Uint8Array[];
4
+ size: number;
5
+ /** Whether the texels are sRGB-encoded colour; otherwise linear data. */
6
+ srgb: boolean;
7
+ }
8
+ /** What the worker encodes: RGBA8 rows of a mip level, `width` wide and `height` high. */
9
+ export interface Job {
10
+ data: Uint8Array;
11
+ width: number;
12
+ height: number;
13
+ srgb: boolean;
14
+ }
15
+ /** What the worker answers a job with. */
16
+ export type Reply = {
17
+ file: Uint8Array;
18
+ } | {
19
+ error: string;
20
+ };
21
+ /**
22
+ * One map as a KTX2 file of Basis UASTC. Each level encodes as `parts` strips of rows, by default one per worker, so
23
+ * that a map's top level, which holds three quarters of its texels, takes all workers; the strips' and levels' files
24
+ * are then joined. Takes about a second per million texels and worker.
25
+ */
26
+ export declare function encodeLayer({ levels, size, srgb }: Layer, parts?: number): Promise<Uint8Array>;