@drawcall/lod 0.2.0 → 0.3.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 (364) hide show
  1. package/README.md +8 -6
  2. package/dist/bake.d.ts +22 -0
  3. package/dist/bake.js +88 -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 +12 -6
  15. package/dist/baked/index.js +22 -20
  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 +13 -10
  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.js +1 -1
  24. package/dist/baked/interior/rooms.js.map +1 -1
  25. package/dist/baked/low.js +5 -4
  26. package/dist/baked/low.js.map +1 -1
  27. package/dist/baked/raster.js +6 -6
  28. package/dist/baked/raster.js.map +1 -1
  29. package/dist/baked/textures.d.ts +17 -0
  30. package/dist/baked/textures.js +95 -0
  31. package/dist/baked/textures.js.map +1 -0
  32. package/dist/baked/transfer.js +19 -18
  33. package/dist/baked/transfer.js.map +1 -1
  34. package/dist/baked/unwrap.js +4 -3
  35. package/dist/baked/unwrap.js.map +1 -1
  36. package/dist/baked/xatlas.js.map +1 -1
  37. package/dist/codec/container.d.ts +8 -0
  38. package/dist/codec/container.js +63 -0
  39. package/dist/codec/container.js.map +1 -0
  40. package/dist/codec/mesh.d.ts +8 -0
  41. package/dist/{mesh/codec.js → codec/mesh.js} +80 -52
  42. package/dist/codec/mesh.js.map +1 -0
  43. package/dist/dispose.d.ts +7 -4
  44. package/dist/dispose.js +20 -22
  45. package/dist/dispose.js.map +1 -1
  46. package/dist/gpu.d.ts +39 -0
  47. package/dist/gpu.js +41 -0
  48. package/dist/gpu.js.map +1 -0
  49. package/dist/impostor/bake/atlas.d.ts +4 -4
  50. package/dist/impostor/bake/atlas.js +12 -12
  51. package/dist/impostor/bake/atlas.js.map +1 -1
  52. package/dist/impostor/bake/fit.d.ts +8 -0
  53. package/dist/impostor/bake/fit.js +28 -0
  54. package/dist/impostor/bake/fit.js.map +1 -0
  55. package/dist/impostor/bake/index.d.ts +22 -14
  56. package/dist/impostor/bake/index.js +41 -134
  57. package/dist/impostor/bake/index.js.map +1 -1
  58. package/dist/impostor/bake/materials.d.ts +3 -3
  59. package/dist/impostor/bake/materials.js +51 -13
  60. package/dist/impostor/bake/materials.js.map +1 -1
  61. package/dist/impostor/bake/sheet.d.ts +8 -0
  62. package/dist/impostor/bake/sheet.js +90 -0
  63. package/dist/impostor/bake/sheet.js.map +1 -0
  64. package/dist/impostor/bake/source.d.ts +2 -2
  65. package/dist/impostor/bake/source.js +8 -19
  66. package/dist/impostor/bake/source.js.map +1 -1
  67. package/dist/impostor/codec.d.ts +4 -5
  68. package/dist/impostor/codec.js +36 -109
  69. package/dist/impostor/codec.js.map +1 -1
  70. package/dist/impostor/impostor.d.ts +31 -7
  71. package/dist/impostor/impostor.js +21 -6
  72. package/dist/impostor/impostor.js.map +1 -1
  73. package/dist/impostor/ktx2/encode.d.ts +26 -0
  74. package/dist/impostor/ktx2/encode.js +117 -0
  75. package/dist/impostor/ktx2/encode.js.map +1 -0
  76. package/dist/impostor/ktx2/transcode.d.ts +3 -0
  77. package/dist/impostor/ktx2/transcode.js +99 -0
  78. package/dist/impostor/ktx2/transcode.js.map +1 -0
  79. package/dist/impostor/ktx2/uastc.d.ts +7 -0
  80. package/dist/impostor/ktx2/uastc.js +64 -0
  81. package/dist/impostor/ktx2/uastc.js.map +1 -0
  82. package/dist/impostor/ktx2/wasm/encoder.d.ts +4 -0
  83. package/dist/impostor/ktx2/wasm/encoder.js +10 -0
  84. package/dist/impostor/ktx2/wasm/encoder.js.map +1 -0
  85. package/dist/impostor/ktx2/wasm/transcoder.d.ts +3 -0
  86. package/dist/impostor/ktx2/wasm/transcoder.js +9 -0
  87. package/dist/impostor/ktx2/wasm/transcoder.js.map +1 -0
  88. package/dist/impostor/ktx2/worker.d.ts +1 -0
  89. package/dist/impostor/ktx2/worker.js +12 -0
  90. package/dist/impostor/ktx2/worker.js.map +1 -0
  91. package/dist/impostor/mesh/card.d.ts +3 -3
  92. package/dist/impostor/mesh/card.js +7 -7
  93. package/dist/impostor/mesh/card.js.map +1 -1
  94. package/dist/impostor/mesh/index.d.ts +5 -4
  95. package/dist/impostor/mesh/index.js +8 -9
  96. package/dist/impostor/mesh/index.js.map +1 -1
  97. package/dist/impostor/mesh/material.d.ts +18 -9
  98. package/dist/impostor/mesh/material.js +40 -27
  99. package/dist/impostor/mesh/material.js.map +1 -1
  100. package/dist/impostor/mesh/surface.d.ts +1 -1
  101. package/dist/impostor/mesh/surface.js +13 -9
  102. package/dist/impostor/mesh/surface.js.map +1 -1
  103. package/dist/impostor/mesh/textures.d.ts +3 -3
  104. package/dist/impostor/mesh/textures.js +24 -34
  105. package/dist/impostor/mesh/textures.js.map +1 -1
  106. package/dist/index.d.ts +15 -10
  107. package/dist/index.js +13 -8
  108. package/dist/index.js.map +1 -1
  109. package/dist/instanced/camera.d.ts +46 -0
  110. package/dist/instanced/camera.js +70 -0
  111. package/dist/instanced/camera.js.map +1 -0
  112. package/dist/instanced/chunk.d.ts +97 -0
  113. package/dist/instanced/chunk.js +156 -0
  114. package/dist/instanced/chunk.js.map +1 -0
  115. package/dist/instanced/chunks.d.ts +60 -0
  116. package/dist/instanced/chunks.js +208 -0
  117. package/dist/instanced/chunks.js.map +1 -0
  118. package/dist/instanced/cull.d.ts +28 -0
  119. package/dist/instanced/cull.js +22 -0
  120. package/dist/instanced/cull.js.map +1 -0
  121. package/dist/instanced/index.d.ts +96 -66
  122. package/dist/instanced/index.js +229 -288
  123. package/dist/instanced/index.js.map +1 -1
  124. package/dist/instanced/key.d.ts +19 -0
  125. package/dist/instanced/key.js +45 -0
  126. package/dist/instanced/key.js.map +1 -0
  127. package/dist/instanced/levels.d.ts +60 -0
  128. package/dist/instanced/levels.js +130 -0
  129. package/dist/instanced/levels.js.map +1 -0
  130. package/dist/instanced/lists.d.ts +70 -0
  131. package/dist/instanced/lists.js +133 -0
  132. package/dist/instanced/lists.js.map +1 -0
  133. package/dist/instanced/measure.d.ts +28 -0
  134. package/dist/instanced/measure.js +203 -0
  135. package/dist/instanced/measure.js.map +1 -0
  136. package/dist/instanced/meshes.d.ts +42 -51
  137. package/dist/instanced/meshes.js +158 -180
  138. package/dist/instanced/meshes.js.map +1 -1
  139. package/dist/instanced/mirror.d.ts +20 -0
  140. package/dist/instanced/mirror.js +37 -0
  141. package/dist/instanced/mirror.js.map +1 -0
  142. package/dist/instanced/pages/buffers.d.ts +37 -0
  143. package/dist/instanced/pages/buffers.js +15 -0
  144. package/dist/instanced/pages/buffers.js.map +1 -0
  145. package/dist/instanced/pages/chunk.d.ts +51 -0
  146. package/dist/instanced/pages/chunk.js +81 -0
  147. package/dist/instanced/pages/chunk.js.map +1 -0
  148. package/dist/instanced/pages/index.d.ts +74 -0
  149. package/dist/instanced/pages/index.js +269 -0
  150. package/dist/instanced/pages/index.js.map +1 -0
  151. package/dist/instanced/pages/passes.d.ts +21 -0
  152. package/dist/instanced/pages/passes.js +52 -0
  153. package/dist/instanced/pages/passes.js.map +1 -0
  154. package/dist/instanced/pages/slots.d.ts +11 -0
  155. package/dist/instanced/pages/slots.js +90 -0
  156. package/dist/instanced/pages/slots.js.map +1 -0
  157. package/dist/instanced/pages/workgroup.d.ts +14 -0
  158. package/dist/instanced/pages/workgroup.js +38 -0
  159. package/dist/instanced/pages/workgroup.js.map +1 -0
  160. package/dist/instanced/raycast.d.ts +13 -11
  161. package/dist/instanced/raycast.js +33 -40
  162. package/dist/instanced/raycast.js.map +1 -1
  163. package/dist/instanced/rows.d.ts +108 -0
  164. package/dist/instanced/rows.js +209 -0
  165. package/dist/instanced/rows.js.map +1 -0
  166. package/dist/instanced/shape.d.ts +25 -0
  167. package/dist/instanced/shape.js +51 -0
  168. package/dist/instanced/shape.js.map +1 -0
  169. package/dist/instanced/sort.d.ts +63 -0
  170. package/dist/instanced/sort.js +162 -0
  171. package/dist/instanced/sort.js.map +1 -0
  172. package/dist/instanced/update.d.ts +30 -0
  173. package/dist/instanced/update.js +207 -0
  174. package/dist/instanced/update.js.map +1 -0
  175. package/dist/levels/bounds.d.ts +21 -0
  176. package/dist/levels/bounds.js +42 -0
  177. package/dist/levels/bounds.js.map +1 -0
  178. package/dist/levels/cameras.d.ts +48 -0
  179. package/dist/levels/cameras.js +122 -0
  180. package/dist/levels/cameras.js.map +1 -0
  181. package/dist/levels/compile/contexts.d.ts +30 -0
  182. package/dist/levels/compile/contexts.js +18 -0
  183. package/dist/levels/compile/contexts.js.map +1 -0
  184. package/dist/levels/compile/index.d.ts +39 -0
  185. package/dist/levels/compile/index.js +185 -0
  186. package/dist/levels/compile/index.js.map +1 -0
  187. package/dist/levels/compile/pipelines.d.ts +26 -0
  188. package/dist/levels/compile/pipelines.js +177 -0
  189. package/dist/levels/compile/pipelines.js.map +1 -0
  190. package/dist/levels/compiles.d.ts +29 -0
  191. package/dist/levels/compiles.js +50 -0
  192. package/dist/levels/compiles.js.map +1 -0
  193. package/dist/levels/draw.d.ts +102 -0
  194. package/dist/levels/draw.js +401 -0
  195. package/dist/levels/draw.js.map +1 -0
  196. package/dist/levels/fade.d.ts +69 -0
  197. package/dist/levels/fade.js +150 -0
  198. package/dist/levels/fade.js.map +1 -0
  199. package/dist/levels/index.d.ts +99 -0
  200. package/dist/levels/index.js +155 -0
  201. package/dist/levels/index.js.map +1 -0
  202. package/dist/levels/item.d.ts +38 -0
  203. package/dist/levels/item.js +97 -0
  204. package/dist/levels/item.js.map +1 -0
  205. package/dist/levels/load.d.ts +31 -0
  206. package/dist/levels/load.js +142 -0
  207. package/dist/levels/load.js.map +1 -0
  208. package/dist/levels/manager.d.ts +159 -0
  209. package/dist/levels/manager.js +339 -0
  210. package/dist/levels/manager.js.map +1 -0
  211. package/dist/{material.js → levels/material.js} +4 -3
  212. package/dist/levels/material.js.map +1 -0
  213. package/dist/levels/renderer.d.ts +29 -0
  214. package/dist/levels/renderer.js +41 -0
  215. package/dist/levels/renderer.js.map +1 -0
  216. package/dist/levels/requests.d.ts +49 -0
  217. package/dist/levels/requests.js +95 -0
  218. package/dist/levels/requests.js.map +1 -0
  219. package/dist/levels/screen.d.ts +14 -0
  220. package/dist/levels/screen.js +21 -0
  221. package/dist/levels/screen.js.map +1 -0
  222. package/dist/levels/wait.d.ts +27 -0
  223. package/dist/levels/wait.js +61 -0
  224. package/dist/levels/wait.js.map +1 -0
  225. package/dist/loader/build.d.ts +10 -0
  226. package/dist/loader/build.js +28 -0
  227. package/dist/loader/build.js.map +1 -0
  228. package/dist/loader/cache.d.ts +6 -9
  229. package/dist/loader/cache.js +17 -24
  230. package/dist/loader/cache.js.map +1 -1
  231. package/dist/loader/context.d.ts +46 -0
  232. package/dist/loader/context.js +91 -0
  233. package/dist/loader/context.js.map +1 -0
  234. package/dist/loader/{provenance.d.ts → dependencies.d.ts} +5 -3
  235. package/dist/loader/{provenance.js → dependencies.js} +12 -4
  236. package/dist/loader/dependencies.js.map +1 -0
  237. package/dist/loader/index.d.ts +62 -0
  238. package/dist/loader/index.js +284 -0
  239. package/dist/loader/index.js.map +1 -0
  240. package/dist/loader/level.d.ts +41 -0
  241. package/dist/loader/level.js +140 -0
  242. package/dist/loader/level.js.map +1 -0
  243. package/dist/loader/request.d.ts +87 -0
  244. package/dist/loader/request.js +59 -0
  245. package/dist/loader/request.js.map +1 -0
  246. package/dist/loader/url.d.ts +5 -2
  247. package/dist/loader/url.js +10 -6
  248. package/dist/loader/url.js.map +1 -1
  249. package/dist/lod.d.ts +81 -40
  250. package/dist/lod.js +196 -149
  251. package/dist/lod.js.map +1 -1
  252. package/dist/meshopt.d.ts +6 -0
  253. package/dist/meshopt.js +19 -0
  254. package/dist/meshopt.js.map +1 -0
  255. package/dist/simplify/cards.d.ts +14 -0
  256. package/dist/simplify/cards.js +128 -0
  257. package/dist/simplify/cards.js.map +1 -0
  258. package/dist/{simplify.d.ts → simplify/index.d.ts} +7 -4
  259. package/dist/{simplify.js → simplify/index.js} +41 -23
  260. package/dist/simplify/index.js.map +1 -0
  261. package/dist/{bounds.d.ts → source/detail.d.ts} +4 -23
  262. package/dist/{bounds.js → source/detail.js} +19 -51
  263. package/dist/source/detail.js.map +1 -0
  264. package/dist/source/deviation.js +6 -6
  265. package/dist/source/deviation.js.map +1 -1
  266. package/dist/source/{shading.d.ts → evaluator.d.ts} +10 -10
  267. package/dist/source/{shading.js → evaluator.js} +5 -5
  268. package/dist/source/evaluator.js.map +1 -0
  269. package/dist/source/{trace.d.ts → raycaster.d.ts} +6 -6
  270. package/dist/source/{trace.js → raycaster.js} +8 -8
  271. package/dist/source/raycaster.js.map +1 -0
  272. package/dist/source/{texels.d.ts → sampler.d.ts} +1 -1
  273. package/dist/source/{texels.js → sampler.js} +3 -3
  274. package/dist/source/sampler.js.map +1 -0
  275. package/dist/source/source.d.ts +1 -1
  276. package/dist/source/source.js +1 -1
  277. package/dist/source/source.js.map +1 -1
  278. package/dist/source/surface.js +1 -1
  279. package/dist/source/surface.js.map +1 -1
  280. package/dist/task.d.ts +6 -0
  281. package/dist/{pause.js → task.js} +5 -5
  282. package/dist/task.js.map +1 -0
  283. package/dist/three.d.ts +13 -24
  284. package/dist/three.js +26 -53
  285. package/dist/three.js.map +1 -1
  286. package/dist/tsl.d.ts +8 -12
  287. package/dist/tsl.js +11 -39
  288. package/dist/tsl.js.map +1 -1
  289. package/dist/typegpu.d.ts +37 -0
  290. package/dist/typegpu.js +37 -0
  291. package/dist/typegpu.js.map +1 -0
  292. package/dist/wind/bounds.js +2 -2
  293. package/dist/wind/bounds.js.map +1 -1
  294. package/dist/wind/hooks.d.ts +7 -4
  295. package/dist/wind/hooks.js +5 -2
  296. package/dist/wind/hooks.js.map +1 -1
  297. package/dist/wind/index.d.ts +2 -2
  298. package/dist/wind/index.js +15 -15
  299. package/dist/wind/index.js.map +1 -1
  300. package/dist/wind/sway.d.ts +2 -0
  301. package/dist/wind/sway.js +4 -1
  302. package/dist/wind/sway.js.map +1 -1
  303. package/package.json +18 -8
  304. package/skills/lod/SKILL.md +108 -31
  305. package/dist/bounds.js.map +0 -1
  306. package/dist/compile.d.ts +0 -4
  307. package/dist/compile.js +0 -100
  308. package/dist/compile.js.map +0 -1
  309. package/dist/deferred.d.ts +0 -12
  310. package/dist/deferred.js +0 -27
  311. package/dist/deferred.js.map +0 -1
  312. package/dist/fade.d.ts +0 -36
  313. package/dist/fade.js +0 -112
  314. package/dist/fade.js.map +0 -1
  315. package/dist/instanced/args.d.ts +0 -20
  316. package/dist/instanced/args.js +0 -77
  317. package/dist/instanced/args.js.map +0 -1
  318. package/dist/instanced/blocks.d.ts +0 -66
  319. package/dist/instanced/blocks.js +0 -294
  320. package/dist/instanced/blocks.js.map +0 -1
  321. package/dist/instanced/dirty.d.ts +0 -15
  322. package/dist/instanced/dirty.js +0 -96
  323. package/dist/instanced/dirty.js.map +0 -1
  324. package/dist/instanced/parts.d.ts +0 -14
  325. package/dist/instanced/parts.js +0 -79
  326. package/dist/instanced/parts.js.map +0 -1
  327. package/dist/instanced/select.d.ts +0 -92
  328. package/dist/instanced/select.js +0 -315
  329. package/dist/instanced/select.js.map +0 -1
  330. package/dist/instanced/store.d.ts +0 -31
  331. package/dist/instanced/store.js +0 -96
  332. package/dist/instanced/store.js.map +0 -1
  333. package/dist/levels.d.ts +0 -95
  334. package/dist/levels.js +0 -171
  335. package/dist/levels.js.map +0 -1
  336. package/dist/loader/bundle.d.ts +0 -25
  337. package/dist/loader/bundle.js +0 -241
  338. package/dist/loader/bundle.js.map +0 -1
  339. package/dist/loader/provenance.js.map +0 -1
  340. package/dist/loader.d.ts +0 -55
  341. package/dist/loader.js +0 -239
  342. package/dist/loader.js.map +0 -1
  343. package/dist/material.js.map +0 -1
  344. package/dist/mesh/codec.d.ts +0 -4
  345. package/dist/mesh/codec.js.map +0 -1
  346. package/dist/pause.d.ts +0 -6
  347. package/dist/pause.js.map +0 -1
  348. package/dist/queue.d.ts +0 -2
  349. package/dist/queue.js +0 -33
  350. package/dist/queue.js.map +0 -1
  351. package/dist/renderer.d.ts +0 -21
  352. package/dist/renderer.js +0 -83
  353. package/dist/renderer.js.map +0 -1
  354. package/dist/residency.d.ts +0 -44
  355. package/dist/residency.js +0 -205
  356. package/dist/residency.js.map +0 -1
  357. package/dist/simplify.js.map +0 -1
  358. package/dist/source/shading.js.map +0 -1
  359. package/dist/source/texels.js.map +0 -1
  360. package/dist/source/trace.js.map +0 -1
  361. package/dist/view.d.ts +0 -45
  362. package/dist/view.js +0 -131
  363. package/dist/view.js.map +0 -1
  364. /package/dist/{material.d.ts → levels/material.d.ts} +0 -0
@@ -1,26 +1,31 @@
1
1
  ---
2
2
  name: lod
3
- description: Use @drawcall/lod for cached, progressively loaded levels of detail in three.js WebGPURenderer scenes. Covers model and procedural assets, mesh simplification, baked meshes, impostors, instanced crowds, wind and interior mapping; not WebGLRenderer or skinned animation.
3
+ description: Use @drawcall/lod for cached, progressively loaded levels of detail in three.js WebGPURenderer scenes. Covers model and procedural assets, mesh simplification, baked meshes, impostors, instanced copies, wind, interior mapping, asset preparation and capturing fully loaded frames; not WebGLRenderer or skinned animation.
4
4
  ---
5
5
 
6
6
  # Level of detail with @drawcall/lod
7
7
 
8
8
  ## Start with the loader
9
9
 
10
- Give the host's `LodLoader` an asset URL and the representations to derive from it. Use `.glb` or `.gltf` for stored models and `.glts` for procedural assets. Put generation parameters in the asset URL's query: each distinct query is a distinct cache identity. Build a `Lod` from the returned levels for an independently placed object, or an `InstancedLod` for repeated objects with per-instance matrices and colours.
10
+ Give the host's `LodLoader` an asset URL and the representations to derive from it. Use `.glb` or `.gltf` for stored models and `.glts` for procedural assets. Put generation parameters in the asset URL's query: each distinct query is a distinct cache identity. Build a `Lod` from the returned levels for an independently placed object, or an `InstancedLod` for repeated objects, whose instances arrive and leave in chunks of matrices and colours, from the CPU or from a compute pass of yours.
11
11
 
12
- `loadAsync` resolves with the coarsest drawable level ready; finer levels load when the camera needs them. Include an impostor or baked mesh as the coarsest drawable when an overview should avoid constructing the source. A simplified coarsest level also loads the source for its original materials; a source-only ladder loads its source eagerly. Prefer baked or impostor middle levels for an expensive `.glts`: a simplified level brings the script run forward to that viewing range.
12
+ Make a `LodGpu` once the renderer is initialised and give it to every `Lod` and `InstancedLod` drawing with that renderer. Every InstancedLod of one LodGpu sorts for a camera in one compute call. A camera that draws only a few InstancedLods, such as a minimap's, can give those a LodGpu of their own, which bounds the per-camera list memory. `LodLoader` needs no renderer.
13
13
 
14
- Choose levels from the asset's silhouette, materials and expected viewing range. Alpha-tested leaf cards often work best as source → impostor; simplifying the cards can destroy their shape. Hard-surface props often suit source → simplified → impostor. Detailed structures can use source → baked shell → impostor, with interiors supplied separately for windows. Add an empty final level when the object should disappear at distance.
14
+ `loadAsync` resolves with the ladder before its levels load; each level loads when a camera first needs it. On a cold cache a derived level is built when it first loads, so a cold far camera builds only the coarse levels it needs. Give simplified and baked levels an explicit `maxPixels`: without one, a level is built with the ladder to measure its default. A simplified level also loads the source for its original materials; a source-only ladder loads its source eagerly. Prefer baked or impostor middle levels for an expensive `.glts`: a simplified level brings the script run forward to that viewing range.
15
15
 
16
- Register the source loaders on the loading manager before loading: a `GLTSLoader` for `.glts` URLs, and for `.glb` or `.gltf` models compressed with Draco or KTX2 a `GLTFLoader` configured with those decoders, since `LodLoader`'s fallback decodes meshopt only. Follow the [GLTS skill](https://github.com/drawcall-ai/glts/blob/main/packages/glts/skills/glts/SKILL.md) for the Vite plugin, script authoring and resource lifetimes.
16
+ Choose levels from the asset's silhouette, materials and expected viewing range. Alpha-tested leaf cards often work best as source → impostor; a simplified level has fewer of them, whole and enlarged to the same coverage, so at a low ratio its foliage reads coarser than the source up close. Hard-surface props often suit source → simplified → impostor. Detailed structures can use source → baked shell → impostor, with interiors supplied separately for windows. A very heavy source, such as a two-million-triangle scan, needs a simplified level between source and impostor, or every copy in mid range draws the full mesh. Add an empty final level when the object should disappear at distance.
17
17
 
18
- This example creates a crowd from one procedural asset. `positions` contains placements in the crowd's space, and `scene` is the application's scene.
18
+ Register the source loaders on the loading manager before loading: a `GLTSLoader` for `.glts` URLs, and a `GLTFLoader` with the decoders for models compressed with Draco or KTX2. Follow the [GLTS skill](https://github.com/drawcall-ai/glts/blob/main/packages/glts/skills/glts/SKILL.md) for the Vite plugin, script authoring and resource lifetimes. The package carries its own workers and WebAssembly; it needs no Vite configuration beyond the vitecache plugin.
19
+
20
+ This example draws many copies of one procedural asset. `positions` contains their placements in the InstancedLod's space, `renderer` is the application's WebGPURenderer and `scene` its scene.
19
21
 
20
22
  ```ts
21
- import { LoadingManager, Matrix4 } from "three/webgpu";
23
+ import { InstancedBufferAttribute, LoadingManager, Matrix4 } from "three/webgpu";
22
24
  import { GLTSLoader } from "@drawcall/glts";
23
- import { InstancedLod, LodLoader } from "@drawcall/lod";
25
+ import { InstancedLod, LodGpu, LodLoader } from "@drawcall/lod";
26
+
27
+ await renderer.init();
28
+ const gpu = new LodGpu(renderer);
24
29
 
25
30
  const manager = new LoadingManager();
26
31
  manager.addHandler(/\.glts$/, new GLTSLoader(manager));
@@ -32,68 +37,140 @@ const levels = await loader.loadAsync({
32
37
  { type: "empty", maxPixels: 4 },
33
38
  ],
34
39
  });
35
- const trees = new InstancedLod(levels, positions.length);
40
+ const trees = new InstancedLod(levels, gpu);
36
41
 
37
42
  const matrix = new Matrix4();
38
- positions.forEach((position, index) => {
39
- trees.setMatrixAt(index, matrix.makeTranslation(position));
40
- });
43
+ const matrices = new Float32Array(positions.flatMap((position) => matrix.makeTranslation(position).toArray()));
44
+ trees.addChunk({ instanceMatrix: new InstancedBufferAttribute(matrices, 16) });
41
45
  scene.add(trees);
42
46
  ```
43
47
 
44
- Supply authored low shells and baking interiors as asset URLs on a baked level; both resolve relative to the source asset as ordinary URLs, so a query-only value replaces the source's whole query. For a variant of the same script, repeat the source's generation parameters, for example the source URL plus `&part=low`. The source asset should be complete at full detail; a baking interior supplies room structure for the distant windows. Keep all three in the same coordinate system.
48
+ Supply authored low shells and baking interiors as asset URLs on a baked level; both resolve relative to the source asset as ordinary URLs, so a query-only value replaces the source's whole query. For a variant of the same script, repeat the source's generation parameters, for example the source URL plus `&part=low`. The source asset should be complete at full detail; a baking interior supplies room structure for the distant windows. Author all three in the same coordinate system.
45
49
 
46
50
  ## Put each cache with its computation
47
51
 
48
- Follow the [vitecache skill](https://github.com/drawcall-ai/vitecache/blob/main/packages/vitecache/skills/vitecache/SKILL.md) to configure the host. `LodLoader` writes a URL's derived levels to the cache directory when the app loads that URL with those levels under the Vite dev server with the vitecache plugin; `vite build` does not generate them, so load every deployed URL and level list during development and deploy the cache directory. A deployed miss builds the levels in the browser on every load without persisting them. When the app is deployed under a sub-path, pass that cache location to `LodLoader`. Deploy the original assets with the cache. Edits to the script, its helpers, packages and loaded files invalidate the derived levels; no dependency list is needed. A script that imports packages from the CDN at runtime, rather than from the app's installed or Vite-bundled packages, rebuilds its levels on every load, as does a source or a resource it loads from another origin, a same-origin URL without a project file such as a server route, or a package the app does not install.
52
+ Follow the [vitecache skill](https://github.com/drawcall-ai/vitecache/blob/main/packages/vitecache/skills/vitecache/SKILL.md) to configure the host. `LodLoader` writes each derived level to the cache directory when the app first loads that level under the Vite dev server with the vitecache plugin. A deployed miss builds the missing level in the browser each time it loads, without persisting it. When the app is deployed under a sub-path, pass that location as `new LodLoader(manager, { basePath })`.
53
+
54
+ To deploy every level prebuilt, load the ladders in a public `.glts` script, which `vite build` runs in Node as the [GLTS skill](https://github.com/drawcall-ai/glts/blob/main/packages/glts/skills/glts/SKILL.md#precomputing-into-the-build) describes. There `LodLoader` builds and saves every level of each ladder it loads, deferred ones included. Request the same URLs and levels as the app, from a helper beside the script that the app imports too; `onLevel` changes nothing cached, so the app adds its effects to the shared requests. Register the contextual `gltsLoader` for `.glts` sources, as the app registers its `GLTSLoader`, and add every level to `scene`: a level can hold a `.glts` source the script loaded, which GLTS requires beneath `scene`.
55
+
56
+ ```ts
57
+ // public/precompute.glts
58
+ import { gltsLoader, loadingManager, scene } from "@drawcall/glts";
59
+ import { LodLoader } from "@drawcall/lod";
60
+ import { ladders } from "./ladders.ts";
61
+
62
+ loadingManager.addHandler(/\.glts$/i, gltsLoader);
63
+ const loader = new LodLoader(loadingManager);
64
+ for (const ladder of ladders) {
65
+ for (const level of await loader.loadAsync(ladder)) scene.add(level.object ?? (await level.load()));
66
+ }
67
+ ```
68
+
69
+ Edits to the script, its helpers, packages and loaded files invalidate the derived levels; no dependency list is needed. A level rebuilds on every load when its source or anything the script loads cannot be tied to a project file: packages imported from a CDN at runtime or not installed by the app, resources from another origin, and same-origin URLs without a file, such as URLs a server answers dynamically. Precomputing such a level fails the build, so install every package the precomputed sources import.
49
70
 
50
- Cache expensive generation inside a `.glts` asset, such as geometry, rooms or generated texture data that would otherwise stall the first approach, as the [GLTS skill](https://github.com/drawcall-ai/glts/blob/main/packages/glts/skills/glts/SKILL.md) describes; leave cheap generation uncached. Use the `encodeMesh` / `decodeMeshAsync` codec for asset-owned geometry caches. The GLTS build does not warm `LodLoader`'s derived levels.
71
+ Cache expensive generation inside a `.glts` asset, such as geometry, rooms or generated texture data that would otherwise stall the first approach, as the GLTS skill describes; leave cheap generation uncached. Use the `encodeMeshAsync` / `decodeMeshAsync` codec for geometry an asset caches itself.
51
72
 
52
73
  ## Place, share and dispose levels
53
74
 
54
- Load an asset once and build spatial crowds from its levels, each with its own instance count, placements and colours; clone a `Lod` for further independently placed copies. Reuse descriptors across owners; adjust each owner's resolved thresholds through its `levels` view. Clones and crowds share geometry, materials, textures and deferred loads. Dispose shared resources only after every copy has stopped drawing; disposal does not count references.
75
+ Load an asset once and build an `InstancedLod` per spatial region from its levels, each with its own chunks of placements and colours; clone a `Lod` for further independently placed copies. Reuse the loaded levels across Lods; adjust each Lod's resolved thresholds through its `levels`. Clones and InstancedLods share geometry, materials, textures and deferred loads. Disposing a `Lod` or `InstancedLod` frees only what it made of its levels: objects you give or load are yours to dispose once every Lod drawing them is disposed, while `LodLoader` frees what it loaded when the last Lod holding its levels is disposed.
76
+
77
+ Use `onLevel` for application effects and shadow settings, `castShadow` and `shadowSide` included. Put source generation and its materials in the asset so that the same URL also loads correctly outside the LOD host.
78
+
79
+ Levels draw with copies of the source's materials, made once through three's `clone`. A custom material class must carry its own state in `copy`, and changes meant to reach drawn levels belong in shared TSL uniforms rather than in properties set on the original afterwards.
80
+
81
+ Apply a shared `Wind` after assembling a LOD and before its first render; arriving levels inherit the effect. A `Lod` or `InstancedLod` that has rendered refuses wind: its shaders would build in a frame. Apply it separately to nested LODs and independently managed batches.
82
+
83
+ Levels are chosen by on-screen size in CSS pixels on the actual render target, so a lower renderer pixel ratio saves shading, not geometry. Compile the initial scene with the actual camera and renderer before revealing it. Render every frame while finer levels load: they upload and compile only inside renders.
84
+
85
+ ## Add instances in chunks and thin them with distance
86
+
87
+ A fixed set of copies is one chunk. For copies that exist only near the camera, such as plants on patches of ground, add a chunk when a patch comes into reach and remove it when the camera moves on; a few chunks a frame cost about what they hold. Prefer whole chunks over parking unused instances at scale 0. When a compute pass of your own writes the copies, give `addChunk` its storage attributes and the bounds the CPU cannot measure (see `InstancedLodChunkParameters`).
55
88
 
56
- Use `onLevel` for application effects or shadow settings that apply when each level arrives. Keep source generation and its materials in the asset so that the same URL also loads correctly outside the LOD host.
89
+ Give an InstancedLod a `cullDistance` to thin it out towards a distance instead of cutting it off. `scaleSurvivors` enlarges the copies that remain so that small things like grass cover about as much; leave it off for objects whose size reads, such as trees. Thinning does not change which levels load: let the ladder's last drawn level end near `far`, or add an empty level there.
57
90
 
58
- Apply a shared `Wind` after assembling a LOD and before rendering; arriving levels inherit the effect. Apply it separately to nested LODs and independently managed batches.
91
+ In this example `grass` is an InstancedLod, `camera` the camera it thins from, and `matrices` a patch's instance matrices, 16 floats each.
59
92
 
60
- Seed the camera with `setViewportHeight` before preparing its first view, and refresh that height after resizing views whose levels may all be culled. Compile the initial scene with the actual camera and renderer before revealing it. Continue drawing while finer levels load so preparation can use the same rendering context.
93
+ ```ts
94
+ grass.cullDistance = { camera, near: 35, far: 60, scaleSurvivors: true };
95
+ const chunk = grass.addChunk({ instanceMatrix: new InstancedBufferAttribute(matrices, 16) });
96
+ // Later, when the patch leaves reach:
97
+ grass.removeChunk(chunk);
98
+ ```
61
99
 
62
100
  ## Assemble levels you already have
63
101
 
64
- Pass levels in finest-to-coarsest order. An empty object can be a deliberate culled level. A ladder needs measurable bounds; when all levels are deferred, it draws nothing until a level is ready.
102
+ Pass levels in finest-to-coarsest order. An empty object can be a deliberate culled level. A ladder needs measurable bounds.
65
103
 
66
- Describe a deferred representation with a load function, bounds and a transition height. The function returns the object already placed in the owner's space; the bounds cover it in that same space, including its children. For a cached impostor, decode the atlas and return an `ImpostorMesh` with the intended draw settings.
104
+ Describe a deferred representation with a load function, bounds and a transition height. The function returns the object already placed in the Lod's space; the bounds cover it in that same space, including its children. For a cached impostor, decode the atlas and return an `ImpostorMesh` with the intended draw settings.
67
105
 
68
- Here, `loadDetailedMesh` loads the detailed object, `sourceBox` describes its bounds in the owner's space, and `coarseMesh` is already available.
106
+ Here, `loadDetailedMesh` loads the detailed object, `sourceBox` describes its bounds in the Lod's space, `coarseMesh` is already available, and `gpu` is the renderer's LodGpu.
69
107
 
70
108
  ```ts
71
109
  import { Lod } from "@drawcall/lod";
72
110
 
73
- const object = new Lod([{ load: loadDetailedMesh, maxPixels: Infinity, box: sourceBox }, { object: coarseMesh }]);
111
+ const object = new Lod([{ load: loadDetailedMesh, maxPixels: Infinity, box: sourceBox }, { object: coarseMesh }], gpu);
74
112
  scene.add(object);
75
113
  ```
76
114
 
77
- A missing level uses the nearest ready finer representation, or the nearest coarser one if none is finer. Requests follow the visible view and begin ahead of the transition. Clones share loading work. Keep the resources used by a deferred load alive until it finishes.
115
+ A level fades in over the coarser one drawn in its place once it arrives. A `Lod` loads the levels its on-screen height needs; an `InstancedLod` loads every level the heights of its chunks' instances can need for a camera, judged from each chunk's bounds, so give chunks tight bounds: a chunk reaching from the camera to the horizon loads every level. The resources a deferred load uses must stay alive until it finishes.
78
116
 
79
- For direct preparation and storage outside `LodLoader`, combine `simplify`, `bakeMesh`, or `bakeImpostor` with the corresponding codecs and drawing objects. Use `ImpostorMesh` directly when copies stay distant throughout their lifetime. For external detail systems, combine an empty near level with a coarse representation and use `levelOf` or level visibility to decide where to supply detail.
117
+ For direct preparation and storage outside `LodLoader`, combine `simplify`, `bakeMesh`, or `bakeImpostor` with the corresponding codecs and drawing objects. Bakes that draw take a renderer made with `createBakeRenderer`, never the application's, whose canvas a bake would draw over. Use `ImpostorMesh` directly when copies stay distant throughout their lifetime. For external detail systems, combine an empty near level with a coarse representation and ask `lod.getLevel(camera)` or `chunk.getLevelAt(index, camera)` where to supply detail.
80
118
 
81
119
  ## Prepare assets that survive transitions
82
120
 
83
- Keep sources, simplified geometry, low shells and interiors in a consistent coordinate system. A ground-level pivot helps upright repeated assets. Use instance colour variation when it can replace separately baked variants.
121
+ Ship source models with deduplicated textures, sized to their on-screen use and GPU-compressed as KTX2, using established tools such as gltf-transform. Uploads are paced per frame, so variants that each carry their own uncompressed 2048² textures add up to gigabytes of uploads and long waits before a close-up is complete. Use instance colour variation when it can replace separately textured variants.
122
+
123
+ Author sources, simplified geometry, low shells and interiors in one coordinate system. A ground-level pivot helps upright repeated assets.
124
+
125
+ Author foliage with alpha-tested cut-outs and colour beyond the visible texture edges. The package supplies no foliage material: give cut-out source materials alpha to coverage and an alpha that holds coverage in smaller mips, for the camera and the shadow maps, or distant leaves thin out and vanish. Fill a cut-out's transparent texels with the mean colour of its opaque texels, as the last step, in a format that preserves colour under zero alpha: lossy webp discards it, PNG preserves it, and a KTX2 encoder needs checking. Mips average those texels in, so left dark they darken the distant source while an impostor, baked from full detail, holds its colour and turns brighter where the two switch. Dilating from the edges instead spreads their often dark fringe. Match visual effects across representations so foliage does not change lighting at a transition.
84
126
 
85
- Author foliage with alpha-tested cutouts and colour beyond the visible texture edges. Inspect the source at distance before baking: dark transparent texels can darken small mips and every derived representation. Match visual effects across representations so foliage does not change lighting at a transition.
127
+ Custom shading on an impostor has little room: an impostor uses close to WebGPU's 16 varyings, so a colour node of your own may find none left; read per pixel what a mesh would carry. An impostor's `normalView` is one unit normal per texel, however many leaves that texel averages. For a lighting term of your own, read `cosine(impostor.material.spread, lightDirection)`, the mean of the clamped cosine over those leaves. Here `impostor` is the level's `ImpostorMesh` and `lightDirection` the view-space direction towards the light.
86
128
 
87
- Match a low shell to the source's occupied shape. Preserve important silhouette features and remove faces that will never be seen. Generate shell and source from the same parameters when possible. Keep rooms separate while authoring, with their boundaries just behind windows and furnishings near visible walls; include rooms in the detailed source when they should appear in the near view too.
129
+ Match a low shell to the source's occupied shape and fit it within the source's bounds: `LodLoader` rejects a level that reaches beyond them. Preserve important silhouette features and remove faces that will never be seen. Generate shell and source from the same parameters when possible. Author rooms separately, with their boundaries just behind windows and furnishings near visible walls; include rooms in the detailed source when they should appear up close too.
88
130
 
89
131
  For dense cover, combine near individuals with a baked distant patch. Jitter position and rotation to avoid aligned gaps, preserve continuity across tile borders, and use side walls only on exposed boundaries. An empty far level can stop drawing individuals once the patch carries their appearance.
90
132
 
133
+ ## Wait for a complete frame before a screenshot
134
+
135
+ Levels load as the camera comes to need them, so a frame drawn soon after loading can lack them. Give the Lods and InstancedLods a `manager` of their own, so that it tracks only them: each holds an item there while the levels its cameras need load, compile or fade in, and ends it once they are complete. Render the `Scene` that holds them each frame, since a Lod loads nothing before such a render.
136
+
137
+ To capture one frame, even with nothing cached, place the camera and render, then wait a frame; while the manager is loading, compile with `renderer.compileAsync(scene, camera)`, render again and wait a frame; capture after a quiet frame, one in which no item started or ended. After moving the camera, wait again. In this example `levels` and `treeLevels` are ladders from `LodLoader`, `gpu` the renderer's LodGpu, `instanceMatrix` an attribute of tree matrices, and `viewpoint` the camera position to capture.
138
+
139
+ ```ts
140
+ import { LoadingManager } from "three/webgpu";
141
+ import { InstancedLod, Lod } from "@drawcall/lod";
142
+
143
+ const manager = new LoadingManager();
144
+ const lod = new Lod(levels, gpu, { manager });
145
+ const trees = new InstancedLod(treeLevels, gpu, { manager });
146
+ trees.addChunk({ instanceMatrix });
147
+ scene.add(lod, trees);
148
+
149
+ camera.position.copy(viewpoint);
150
+ let loading = false;
151
+ manager.onStart = () => (loading = true);
152
+ manager.onLoad = () => (loading = false);
153
+ const frame = () => new Promise((resolve) => requestAnimationFrame(resolve));
154
+ renderer.render(scene, camera);
155
+ await frame();
156
+ while (loading) {
157
+ await renderer.compileAsync(scene, camera);
158
+ renderer.render(scene, camera);
159
+ await frame();
160
+ }
161
+ // The last render drew the complete frame: capture it.
162
+ ```
163
+
164
+ Loaded levels stay until their Lod is disposed, which nothing does for you: in a world larger than memory, dispose the Lods the camera has left far behind.
165
+
91
166
  ## Tune the complete scene
92
167
 
93
- Tune transitions in the intended viewport with `Lod.debug`, then inspect motion through them. Use `Lod.quality` for a scene-wide adjustment and individual thresholds for particular assets. Give an impostor bake the intended screen size at its handover, then inspect its coverage and colour from several angles.
168
+ Tune transitions in the intended viewport with `Lod.debug`, then inspect motion through them. Use `Lod.quality` for a scene-wide adjustment and individual thresholds for particular assets. Give an impostor bake the intended screen size at its switch, then inspect its coverage and colour from several angles. Compare both sides of a switch under one camera, drawing each with the Lod's `forceLevel`, looking toward the sun as well as away: a mismatch can show in one light direction only.
169
+
170
+ Group nearby copies into spatial regions. Broad batches can lose useful culling, while tiny batches spend too much time submitting draws. Add and remove chunks and move changed instances instead of rebuilding whole InstancedLods. Count material groups as well as triangles; an atlas alone does not combine draws. Each distinct material structure costs a pipeline compile on first use, so variants should share material structure.
94
171
 
95
- Group nearby copies into spatial regions. Broad batches can lose useful culling, while tiny batches spend too much time submitting draws. Reuse instance slots and update changed matrices or colours instead of rebuilding whole crowds. Count material groups as well as triangles; an atlas alone does not combine draws. Each distinct material structure costs a pipeline compile on the first view, so variants should share material structure.
172
+ Avoid custom shadow nodes on lights that LOD objects should cast into. An `InstancedLod` draws for each camera, shadow maps' included, only the instances inside its frustum, at the level the map's texels resolve, so shadow casting costs about what the map can show. When it still dominates, turn `castShadow` off in `onLevel` on the levels that matter least to the shadow, such as small plants.
96
173
 
97
174
  Judge impostors by covered screen area and overlap as well as triangle count. Compare individual cards with baked patches for dense cover, and inspect parallax and mip quality during transitions.
98
175
 
99
- Compare cold startup, warm startup and first traversal under the same camera movement, viewport, shadows, wind and thresholds. Keep expensive diagnostic overlays outside measurements. A warm repeat does not reveal first-use work, and fewer draws can still lose to worse culling, shading or memory costs.
176
+ Compare cold startup, warm startup and first traversal under the same camera movement, viewport, shadows, wind and thresholds. Leave expensive diagnostic overlays out of measurements. A warm repeat does not reveal first-use work, and fewer draws can still lose to worse culling, shading or memory costs.
@@ -1 +0,0 @@
1
- {"version":3,"file":"bounds.js","sourceRoot":"","sources":["../src/bounds.ts"],"names":[],"mappings":"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"}
package/dist/compile.d.ts DELETED
@@ -1,4 +0,0 @@
1
- import type { Object3D } from "three/webgpu";
2
- import type { RenderContext } from "./view.js";
3
- /** Prepare the same target and MRT as the viewing draw, even if normal rendering has since restored the canvas. */
4
- export declare function compileLevel(object: Object3D, context: RenderContext): Promise<void>;
package/dist/compile.js DELETED
@@ -1,100 +0,0 @@
1
- import { gpuQueue, isMesh, isNode, isTexture } from "./three.js";
2
- import { pause } from "./pause.js";
3
- /** Prepare the same target and MRT as the viewing draw, even if normal rendering has since restored the canvas. */
4
- export async function compileLevel(object, context) {
5
- // Throttle new uploads behind submitted work instead of blocking inside writeTexture.
6
- const queue = gpuQueue(context.renderer);
7
- for (const texture of textures(object)) {
8
- await queue.onSubmittedWorkDone();
9
- context.renderer.initTexture(texture);
10
- await pause();
11
- }
12
- const meshes = [];
13
- const collect = (node) => {
14
- if (isMesh(node))
15
- meshes.push(node);
16
- };
17
- object.traverse(collect);
18
- for (const mesh of meshes) {
19
- const groups = mesh.geometry.groups;
20
- if (!Array.isArray(mesh.material)) {
21
- await queue.onSubmittedWorkDone();
22
- await compileMesh(mesh, context);
23
- continue;
24
- }
25
- for (const group of groups) {
26
- await queue.onSubmittedWorkDone();
27
- let pending;
28
- try {
29
- mesh.geometry.groups = [group];
30
- pending = compileMesh(mesh, context);
31
- }
32
- finally {
33
- mesh.geometry.groups = groups;
34
- }
35
- await pending;
36
- }
37
- }
38
- }
39
- function compileMesh(mesh, context) {
40
- const { renderer, camera, scene } = context;
41
- const target = renderer.getRenderTarget();
42
- const mrt = renderer.getMRT();
43
- const cubeFace = renderer.getActiveCubeFace();
44
- const mipLevel = renderer.getActiveMipmapLevel();
45
- const culled = mesh.frustumCulled;
46
- const visible = mesh.visible;
47
- const children = mesh.children;
48
- const background = scene.background;
49
- const backgroundNode = scene.backgroundNode;
50
- try {
51
- renderer.setRenderTarget(context.target, context.cubeFace, context.mipLevel);
52
- renderer.setMRT(context.mrt);
53
- // Demanded levels can still be hidden or outside the last view.
54
- mesh.frustumCulled = false;
55
- mesh.visible = true;
56
- mesh.children = [];
57
- // r185 compiles backgrounds first, which would postpone this mesh until after renderer state is restored.
58
- scene.background = null;
59
- scene.backgroundNode = null;
60
- // r185 starts only the first material before yielding; isolate one draw so setup sees its captured target/MRT.
61
- return renderer.compileAsync(mesh, camera, scene);
62
- }
63
- finally {
64
- scene.background = background;
65
- scene.backgroundNode = backgroundNode;
66
- mesh.children = children;
67
- mesh.frustumCulled = culled;
68
- mesh.visible = visible;
69
- renderer.setRenderTarget(target, cubeFace, mipLevel);
70
- renderer.setMRT(mrt);
71
- }
72
- }
73
- function textures(object) {
74
- const found = new Set();
75
- const visited = new Set();
76
- const visit = (node) => {
77
- if (visited.has(node))
78
- return;
79
- visited.add(node);
80
- const value = Reflect.get(node, "value");
81
- if (isTexture(value))
82
- found.add(value);
83
- for (const child of node.getChildren())
84
- visit(child);
85
- };
86
- object.traverse((node) => {
87
- if (!isMesh(node))
88
- return;
89
- for (const material of [node.material].flat()) {
90
- for (const value of Object.values(material)) {
91
- if (isTexture(value))
92
- found.add(value);
93
- else if (isNode(value))
94
- visit(value);
95
- }
96
- }
97
- });
98
- return found;
99
- }
100
- //# sourceMappingURL=compile.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"compile.js","sourceRoot":"","sources":["../src/compile.ts"],"names":[],"mappings":"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"}
@@ -1,12 +0,0 @@
1
- import type { Object3D } from "three/webgpu";
2
- type Load = () => Promise<Object3D>;
3
- interface Loading {
4
- promise: Promise<Object3D>;
5
- object?: Object3D;
6
- error?: Error;
7
- }
8
- /** The load `loadOnce` started for `load`, if any. */
9
- export declare const loading: (load: Load) => Loading | undefined;
10
- /** Material dependencies and owners share one load and one resource lifetime. */
11
- export declare function loadOnce(load: Load): Loading;
12
- export {};
package/dist/deferred.js DELETED
@@ -1,27 +0,0 @@
1
- import { isObject3D } from "./three.js";
2
- const started = new WeakMap();
3
- /** The load `loadOnce` started for `load`, if any. */
4
- export const loading = (load) => started.get(load);
5
- /** Material dependencies and owners share one load and one resource lifetime. */
6
- export function loadOnce(load) {
7
- const existing = started.get(load);
8
- if (existing)
9
- return existing;
10
- const entry = {
11
- promise: Promise.resolve()
12
- .then(load)
13
- .then((object) => {
14
- if (!isObject3D(object))
15
- throw new Error("Lod: load must return an Object3D");
16
- entry.object = object;
17
- return object;
18
- })
19
- .catch((error) => {
20
- entry.error = error instanceof Error ? error : new Error("Lod: load failed", { cause: error });
21
- throw entry.error;
22
- }),
23
- };
24
- started.set(load, entry);
25
- return entry;
26
- }
27
- //# sourceMappingURL=deferred.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"deferred.js","sourceRoot":"","sources":["../src/deferred.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAQxC,MAAM,OAAO,GAAG,IAAI,OAAO,EAAiB,CAAC;AAE7C,sDAAsD;AACtD,MAAM,CAAC,MAAM,OAAO,GAAG,CAAC,IAAU,EAAuB,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;AAE9E,iFAAiF;AACjF,MAAM,UAAU,QAAQ,CAAC,IAAU;IACjC,MAAM,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IACnC,IAAI,QAAQ;QAAE,OAAO,QAAQ,CAAC;IAC9B,MAAM,KAAK,GAAY;QACrB,OAAO,EAAE,OAAO,CAAC,OAAO,EAAE;aACvB,IAAI,CAAC,IAAI,CAAC;aACV,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE;YACf,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC;gBAAE,MAAM,IAAI,KAAK,CAAC,mCAAmC,CAAC,CAAC;YAC9E,KAAK,CAAC,MAAM,GAAG,MAAM,CAAC;YACtB,OAAO,MAAM,CAAC;QAChB,CAAC,CAAC;aACD,KAAK,CAAC,CAAC,KAAc,EAAE,EAAE;YACxB,KAAK,CAAC,KAAK,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,kBAAkB,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC,CAAC;YAC/F,MAAM,KAAK,CAAC,KAAK,CAAC;QACpB,CAAC,CAAC;KACL,CAAC;IACF,OAAO,CAAC,GAAG,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;IACzB,OAAO,KAAK,CAAC;AACf,CAAC"}
package/dist/fade.d.ts DELETED
@@ -1,36 +0,0 @@
1
- import { Color, StorageBufferAttribute, type Node, type NodeBuilder, type Object3D } from "three/webgpu";
2
- /** How a mesh of a level is drawn, which says where its fade and shadow size come from. */
3
- export type Draw = {
4
- kind: "object";
5
- /** the signed fade */
6
- fade: number;
7
- /** the whole object's bounding diameter, world units */
8
- diameter: number;
9
- /** debug tint, white when off */
10
- tint: Color;
11
- } | {
12
- kind: "instances";
13
- /** one signed fade per instance slot; null for none (an ImpostorMesh of its own) */
14
- fades: StorageBufferAttribute | null;
15
- /** one instance's bounding radius in its own space */
16
- radius: number;
17
- tint: Color;
18
- };
19
- /** Draw `mesh` as `draw` says: its materials read it while it renders. */
20
- export declare const setDraw: (mesh: Object3D, draw: Draw) => void;
21
- export declare const drawOf: (mesh: Object3D) => Draw | undefined;
22
- /** This draw's debug tint (see `Lod.debug`). */
23
- export declare const tint: import("three/webgpu").UniformNode<"color", Color>;
24
- /** Interleaved gradient noise over the pixels of the target being drawn. */
25
- export declare const dither: (pixel: Node<"vec2">) => Node<"float">;
26
- /** This draw's instance matrix when its matrices live in storage, else null. */
27
- export declare function instanceMatrixOf(object: Object3D): Node<"mat4"> | null;
28
- export declare const instanceColor: import("three/webgpu").VaryingNode<"vec3">;
29
- /** Apply the level's shared instance bindings before its own deformation, as Three does for InstancedMesh. */
30
- export declare function placeInstances(builder: NodeBuilder): void;
31
- /** This draw's signed fade. */
32
- export declare const fade: import("three/src/nodes/TSL.js").FnNode<[], Node<"float">>;
33
- /** Whether this pixel is this draw's, by its fade: false on the other level's pixels. */
34
- export declare const keepsPixel: import("three/src/nodes/TSL.js").FnNode<[], Node<"bool">>;
35
- /** `position` in shadow passes, or nothing (a point) when the draw is too small to cast. */
36
- export declare const castPosition: (position: Node<"vec3">) => Node<"vec3">;
package/dist/fade.js DELETED
@@ -1,112 +0,0 @@
1
- import { Color, Matrix4, StorageBufferAttribute, StorageInstancedBufferAttribute } from "three/webgpu";
2
- import { Fn, cameraProjectionMatrix, dot, float, fract, instanceIndex, modelWorldMatrix, normalLocal, positionLocal, transformNormal, varyingProperty, screenCoordinate, screenSize, select, storage, uniform, varying, vec2, vec3, } from "three/tsl";
3
- import { isImpostorMesh, isLodInstances, storageMatrices } from "./three.js";
4
- import { column, instanceGroup, isOrthographic, maxScale } from "./tsl.js";
5
- const draws = new WeakMap();
6
- /** Draw `mesh` as `draw` says: its materials read it while it renders. */
7
- export const setDraw = (mesh, draw) => void draws.set(mesh, draw);
8
- export const drawOf = (mesh) => draws.get(mesh);
9
- const WHITE = new Color(1, 1, 1);
10
- const of = (object) => (object ? draws.get(object) : undefined);
11
- // Per-object values, shared by every material: each draw reads its own.
12
- const objectFade = uniform(0).onObjectUpdate(({ object }) => {
13
- const draw = of(object);
14
- return draw?.kind === "object" ? draw.fade : 0;
15
- });
16
- // A mesh no level draws is never too small to cast.
17
- const objectDiameter = uniform(0).onObjectUpdate(({ object }) => {
18
- const draw = of(object);
19
- return draw?.kind === "object" ? draw.diameter : 3.4e38;
20
- });
21
- const instanceRadius = uniform(0).onObjectUpdate(({ object }) => {
22
- const draw = of(object);
23
- return draw?.kind === "instances" ? draw.radius : 0;
24
- });
25
- /** This draw's debug tint (see `Lod.debug`). */
26
- export const tint = uniform(new Color(1, 1, 1)).onObjectUpdate(({ object }) => of(object)?.tint ?? WHITE);
27
- /** Interleaved gradient noise over the pixels of the target being drawn. */
28
- export const dither = (pixel) => fract(float(52.9829189).mul(fract(dot(pixel, vec2(0.06711056, 0.00583715)))));
29
- const identity = new StorageInstancedBufferAttribute(new Float32Array(new Matrix4().elements), 16);
30
- const matrices = storage(identity, "mat4", 0)
31
- .setName("lodInstanceMatrices")
32
- .setGroup(instanceGroup)
33
- .toReadOnly()
34
- .onObjectUpdate(({ object }) => {
35
- const attribute = object && storageMatrices(object);
36
- if (!attribute)
37
- throw new Error("Lod: instance draw has no matrices");
38
- return attribute;
39
- });
40
- const zero = new StorageBufferAttribute(new Float32Array(1), 1);
41
- const fades = storage(zero, "float", 0)
42
- .setName("lodInstanceFades")
43
- .setGroup(instanceGroup)
44
- .toReadOnly()
45
- .onObjectUpdate(({ object }) => {
46
- const draw = of(object);
47
- return draw?.kind === "instances" && draw.fades ? draw.fades : zero;
48
- });
49
- const fadeIndex = uniform(0, "uint").onObjectUpdate(({ object }) => {
50
- const draw = of(object);
51
- return Number(draw?.kind === "instances" && draw.fades !== null);
52
- });
53
- const instanceCaster = uniform(false).onObjectUpdate(({ object }) => of(object)?.kind === "instances");
54
- /** This draw's instance matrix when its matrices live in storage, else null. */
55
- export function instanceMatrixOf(object) {
56
- return storageMatrices(object) ? matrices.element(instanceIndex) : null;
57
- }
58
- const white = new StorageInstancedBufferAttribute(new Float32Array([1, 1, 1, 1]), 4);
59
- const colors = storage(white, "vec4", 0)
60
- .setName("lodInstanceColors")
61
- .setGroup(instanceGroup)
62
- .toReadOnly()
63
- .onObjectUpdate(({ object }) => (object && (isImpostorMesh(object) || isLodInstances(object)) && object.instanceColor) || white);
64
- const colorIndex = uniform(0, "uint").onObjectUpdate(({ object }) => Number(!!object && (isImpostorMesh(object) || isLodInstances(object)) && object.instanceColor !== null));
65
- export const instanceColor = varying(colors.element(instanceIndex.mul(colorIndex)).xyz).setInterpolation("flat");
66
- /** Apply the level's shared instance bindings before its own deformation, as Three does for InstancedMesh. */
67
- export function placeInstances(builder) {
68
- if (!isLodInstances(builder.object))
69
- return;
70
- const matrix = matrices.element(instanceIndex);
71
- positionLocal.assign(matrix.mul(positionLocal).xyz);
72
- if (builder.geometry.hasAttribute("normal"))
73
- normalLocal.assign(transformNormal(normalLocal, matrix));
74
- if (builder.object.instanceColor)
75
- varyingProperty("vec3", "vInstanceColor").assign(instanceColor);
76
- }
77
- /** This draw's signed fade. */
78
- export const fade = Fn((builder) => {
79
- if (isImpostorMesh(builder.object))
80
- return varying(fades.element(instanceIndex.mul(fadeIndex)))
81
- .setInterpolation("flat")
82
- .add(objectFade);
83
- const draw = draws.get(builder.object);
84
- if (draw?.kind !== "instances" || !draw.fades)
85
- return objectFade;
86
- // Constant across the primitive: keep compute-written slots out of fragment bindings.
87
- return varying(fades.element(instanceIndex)).setInterpolation("flat");
88
- });
89
- /** Whether this pixel is this draw's, by its fade: false on the other level's pixels. */
90
- export const keepsPixel = Fn(() => {
91
- const f = fade();
92
- const d = dither(screenCoordinate.xy);
93
- return select(f.greaterThanEqual(0), d.greaterThanEqual(f), d.lessThan(f.negate()));
94
- });
95
- /**
96
- * Whether this draw is too small for the shadow map being drawn: narrower than a texel
97
- * of an orthographic (directional light's) map, it would cover a texel centre only by
98
- * chance, flickering as it or the map moves. Only valid in shadow passes.
99
- */
100
- const tooSmallToCast = Fn((builder) => {
101
- const object = builder.object;
102
- const card = isImpostorMesh(object);
103
- const instance = card || draws.get(object)?.kind === "instances" ? instanceMatrixOf(object) : null;
104
- const instanced = instance ? maxScale(modelWorldMatrix.mul(instance)).mul(instanceRadius).mul(2) : objectDiameter;
105
- const diameter = card ? select(instanceCaster, instanced, objectDiameter) : instanced;
106
- // projection[1][1] is 2 × zoom / (top - bottom)
107
- const texel = float(2).div(column(cameraProjectionMatrix, 1).y.mul(screenSize.y));
108
- return isOrthographic(cameraProjectionMatrix).and(diameter.lessThan(texel));
109
- });
110
- /** `position` in shadow passes, or nothing (a point) when the draw is too small to cast. */
111
- export const castPosition = (position) => select(tooSmallToCast(), vec3(0), position);
112
- //# sourceMappingURL=fade.js.map
package/dist/fade.js.map DELETED
@@ -1 +0,0 @@
1
- {"version":3,"file":"fade.js","sourceRoot":"","sources":["../src/fade.ts"],"names":[],"mappings":"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"}
@@ -1,20 +0,0 @@
1
- import { IndirectStorageBufferAttribute } from "three/webgpu";
2
- /** Bytes per draw, including the unused final word of a non-indexed draw. */
3
- export declare const ARGS_BYTES = 20;
4
- export interface ArgsSlice {
5
- readonly attribute: IndirectStorageBufferAttribute;
6
- readonly offset: number;
7
- dispose(): void;
8
- }
9
- /**
10
- * Stable slices of fixed-size pages. Sharing the indirect buffer lets WebGPU batch
11
- * draw validation; growing a page would replace buffers still used by meshes and kernels.
12
- */
13
- export declare class Args {
14
- private readonly capacity;
15
- private readonly pages;
16
- constructor(capacity?: number);
17
- take(values: Uint32Array): ArgsSlice;
18
- private release;
19
- }
20
- export declare const args: Args;