@thunderclap-engine/engine 0.0.0-stage → 1.1.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 (566) hide show
  1. package/CHANGELOG.md +390 -0
  2. package/LICENSE +21 -0
  3. package/README.md +333 -2
  4. package/dist/analytics/analytics.d.ts +80 -0
  5. package/dist/analytics/analytics.js +129 -0
  6. package/dist/analytics/index.d.ts +1 -0
  7. package/dist/analytics/index.js +1 -0
  8. package/dist/anim/aim.d.ts +43 -0
  9. package/dist/anim/aim.js +157 -0
  10. package/dist/anim/clip.d.ts +98 -0
  11. package/dist/anim/clip.js +282 -0
  12. package/dist/anim/compress.d.ts +65 -0
  13. package/dist/anim/compress.js +339 -0
  14. package/dist/anim/foot-ik.d.ts +74 -0
  15. package/dist/anim/foot-ik.js +241 -0
  16. package/dist/anim/graph.d.ts +153 -0
  17. package/dist/anim/graph.js +532 -0
  18. package/dist/anim/ik.d.ts +105 -0
  19. package/dist/anim/ik.js +435 -0
  20. package/dist/anim/index.d.ts +36 -0
  21. package/dist/anim/index.js +21 -0
  22. package/dist/anim/match.d.ts +66 -0
  23. package/dist/anim/match.js +153 -0
  24. package/dist/anim/mixer.d.ts +113 -0
  25. package/dist/anim/mixer.js +314 -0
  26. package/dist/anim/morph.d.ts +41 -0
  27. package/dist/anim/morph.js +94 -0
  28. package/dist/anim/pose.d.ts +74 -0
  29. package/dist/anim/pose.js +254 -0
  30. package/dist/anim/quat.d.ts +44 -0
  31. package/dist/anim/quat.js +187 -0
  32. package/dist/anim/retarget.d.ts +97 -0
  33. package/dist/anim/retarget.js +366 -0
  34. package/dist/anim/root-motion.d.ts +44 -0
  35. package/dist/anim/root-motion.js +224 -0
  36. package/dist/anim/skin-pose.d.ts +39 -0
  37. package/dist/anim/skin-pose.js +53 -0
  38. package/dist/anim/socket.d.ts +47 -0
  39. package/dist/anim/socket.js +84 -0
  40. package/dist/anim/spring-chain.d.ts +73 -0
  41. package/dist/anim/spring-chain.js +294 -0
  42. package/dist/assets/atlas.d.ts +90 -0
  43. package/dist/assets/atlas.js +212 -0
  44. package/dist/assets/baked.d.ts +33 -0
  45. package/dist/assets/baked.js +38 -0
  46. package/dist/assets/bundle.d.ts +88 -0
  47. package/dist/assets/bundle.js +464 -0
  48. package/dist/assets/cache.d.ts +56 -0
  49. package/dist/assets/cache.js +123 -0
  50. package/dist/assets/gltf-load.d.ts +252 -0
  51. package/dist/assets/gltf-load.js +661 -0
  52. package/dist/assets/gltf-skin.d.ts +36 -0
  53. package/dist/assets/gltf-skin.js +109 -0
  54. package/dist/assets/gltf.d.ts +706 -0
  55. package/dist/assets/gltf.js +1376 -0
  56. package/dist/assets/index.d.ts +20 -0
  57. package/dist/assets/index.js +10 -0
  58. package/dist/assets/ktx2.d.ts +71 -0
  59. package/dist/assets/ktx2.js +213 -0
  60. package/dist/assets/manifest.d.ts +79 -0
  61. package/dist/assets/manifest.js +7 -0
  62. package/dist/assets/meshopt.d.ts +23 -0
  63. package/dist/assets/meshopt.js +403 -0
  64. package/dist/audio/audio.d.ts +733 -0
  65. package/dist/audio/audio.js +2013 -0
  66. package/dist/audio/dsp.d.ts +61 -0
  67. package/dist/audio/dsp.js +159 -0
  68. package/dist/audio/duck.d.ts +44 -0
  69. package/dist/audio/duck.js +101 -0
  70. package/dist/audio/envelope.d.ts +53 -0
  71. package/dist/audio/envelope.js +106 -0
  72. package/dist/audio/index.d.ts +13 -0
  73. package/dist/audio/index.js +14 -0
  74. package/dist/audio/music.d.ts +113 -0
  75. package/dist/audio/music.js +548 -0
  76. package/dist/audio/occlusion.d.ts +55 -0
  77. package/dist/audio/occlusion.js +61 -0
  78. package/dist/audio/persist.d.ts +23 -0
  79. package/dist/audio/persist.js +27 -0
  80. package/dist/audio/recipes.d.ts +55 -0
  81. package/dist/audio/recipes.js +227 -0
  82. package/dist/audio/send.d.ts +41 -0
  83. package/dist/audio/send.js +118 -0
  84. package/dist/audio/sprites.d.ts +59 -0
  85. package/dist/audio/sprites.js +43 -0
  86. package/dist/audio/synth.d.ts +103 -0
  87. package/dist/audio/synth.js +197 -0
  88. package/dist/audio/variations.d.ts +25 -0
  89. package/dist/audio/variations.js +55 -0
  90. package/dist/audio/zones.d.ts +100 -0
  91. package/dist/audio/zones.js +167 -0
  92. package/dist/core/detached-surface.d.ts +44 -0
  93. package/dist/core/detached-surface.js +104 -0
  94. package/dist/core/events.d.ts +24 -0
  95. package/dist/core/events.js +43 -0
  96. package/dist/core/game.d.ts +409 -0
  97. package/dist/core/game.js +530 -0
  98. package/dist/core/hash.d.ts +24 -0
  99. package/dist/core/hash.js +49 -0
  100. package/dist/core/index.d.ts +17 -0
  101. package/dist/core/index.js +9 -0
  102. package/dist/core/loop.d.ts +113 -0
  103. package/dist/core/loop.js +185 -0
  104. package/dist/core/math.d.ts +58 -0
  105. package/dist/core/math.js +210 -0
  106. package/dist/core/noise.d.ts +40 -0
  107. package/dist/core/noise.js +247 -0
  108. package/dist/core/pool.d.ts +42 -0
  109. package/dist/core/pool.js +85 -0
  110. package/dist/core/random.d.ts +61 -0
  111. package/dist/core/random.js +199 -0
  112. package/dist/core/scene.d.ts +79 -0
  113. package/dist/core/scene.js +195 -0
  114. package/dist/core/timer.d.ts +66 -0
  115. package/dist/core/timer.js +286 -0
  116. package/dist/fx/billboard-wgsl.d.ts +29 -0
  117. package/dist/fx/billboard-wgsl.js +158 -0
  118. package/dist/fx/billboard.d.ts +249 -0
  119. package/dist/fx/billboard.js +702 -0
  120. package/dist/fx/debug-draw.d.ts +127 -0
  121. package/dist/fx/debug-draw.js +523 -0
  122. package/dist/fx/debug-wgsl.d.ts +7 -0
  123. package/dist/fx/debug-wgsl.js +32 -0
  124. package/dist/fx/decals-wgsl.d.ts +15 -0
  125. package/dist/fx/decals-wgsl.js +173 -0
  126. package/dist/fx/decals.d.ts +216 -0
  127. package/dist/fx/decals.js +607 -0
  128. package/dist/fx/effect.d.ts +129 -0
  129. package/dist/fx/effect.js +349 -0
  130. package/dist/fx/effects/hit-spark.json +48 -0
  131. package/dist/fx/effects/index.d.ts +8 -0
  132. package/dist/fx/effects/index.js +9 -0
  133. package/dist/fx/effects/magic-aura.json +47 -0
  134. package/dist/fx/effects/smoke-puff.json +34 -0
  135. package/dist/fx/emit-surface.d.ts +40 -0
  136. package/dist/fx/emit-surface.js +124 -0
  137. package/dist/fx/flicker.d.ts +30 -0
  138. package/dist/fx/flicker.js +42 -0
  139. package/dist/fx/index.d.ts +31 -0
  140. package/dist/fx/index.js +20 -0
  141. package/dist/fx/particles-wgsl.d.ts +57 -0
  142. package/dist/fx/particles-wgsl.js +828 -0
  143. package/dist/fx/particles.d.ts +566 -0
  144. package/dist/fx/particles.js +1533 -0
  145. package/dist/fx/random.d.ts +15 -0
  146. package/dist/fx/random.js +20 -0
  147. package/dist/fx/sky-wgsl.d.ts +23 -0
  148. package/dist/fx/sky-wgsl.js +127 -0
  149. package/dist/fx/sky.d.ts +96 -0
  150. package/dist/fx/sky.js +175 -0
  151. package/dist/fx/text-atlas.d.ts +143 -0
  152. package/dist/fx/text-atlas.js +327 -0
  153. package/dist/fx/trail-wgsl.d.ts +11 -0
  154. package/dist/fx/trail-wgsl.js +42 -0
  155. package/dist/fx/trail.d.ts +194 -0
  156. package/dist/fx/trail.js +555 -0
  157. package/dist/fx/water-wgsl.d.ts +34 -0
  158. package/dist/fx/water-wgsl.js +197 -0
  159. package/dist/fx/water.d.ts +176 -0
  160. package/dist/fx/water.js +371 -0
  161. package/dist/geom/collide/bvh.d.ts +151 -0
  162. package/dist/geom/collide/bvh.js +493 -0
  163. package/dist/geom/collide/debug.d.ts +14 -0
  164. package/dist/geom/collide/debug.js +74 -0
  165. package/dist/geom/collide/grid.d.ts +26 -0
  166. package/dist/geom/collide/grid.js +91 -0
  167. package/dist/geom/collide/index.d.ts +8 -0
  168. package/dist/geom/collide/index.js +8 -0
  169. package/dist/geom/collide/queries.d.ts +70 -0
  170. package/dist/geom/collide/queries.js +583 -0
  171. package/dist/geom/collide/serialize.d.ts +14 -0
  172. package/dist/geom/collide/serialize.js +145 -0
  173. package/dist/geom/collide/shapes.d.ts +161 -0
  174. package/dist/geom/collide/shapes.js +686 -0
  175. package/dist/geom/collide/slide.d.ts +66 -0
  176. package/dist/geom/collide/slide.js +375 -0
  177. package/dist/geom/collide/tile-slide.d.ts +88 -0
  178. package/dist/geom/collide/tile-slide.js +255 -0
  179. package/dist/geom/geometry.d.ts +95 -0
  180. package/dist/geom/geometry.js +322 -0
  181. package/dist/geom/heightfield.d.ts +72 -0
  182. package/dist/geom/heightfield.js +295 -0
  183. package/dist/geom/hull.d.ts +27 -0
  184. package/dist/geom/hull.js +279 -0
  185. package/dist/geom/index.d.ts +35 -0
  186. package/dist/geom/index.js +23 -0
  187. package/dist/geom/iso.d.ts +74 -0
  188. package/dist/geom/iso.js +89 -0
  189. package/dist/geom/lod.d.ts +29 -0
  190. package/dist/geom/lod.js +27 -0
  191. package/dist/geom/ops.d.ts +47 -0
  192. package/dist/geom/ops.js +285 -0
  193. package/dist/geom/primitives.d.ts +97 -0
  194. package/dist/geom/primitives.js +359 -0
  195. package/dist/geom/shapes.d.ts +43 -0
  196. package/dist/geom/shapes.js +88 -0
  197. package/dist/geom/simplify.d.ts +38 -0
  198. package/dist/geom/simplify.js +519 -0
  199. package/dist/geom/split.d.ts +37 -0
  200. package/dist/geom/split.js +413 -0
  201. package/dist/geom/sweep.d.ts +83 -0
  202. package/dist/geom/sweep.js +534 -0
  203. package/dist/geom/tangents.d.ts +16 -0
  204. package/dist/geom/tangents.js +124 -0
  205. package/dist/geom/triangulate.d.ts +19 -0
  206. package/dist/geom/triangulate.js +147 -0
  207. package/dist/host/default.d.ts +10 -0
  208. package/dist/host/default.js +10 -0
  209. package/dist/host/index.d.ts +4 -0
  210. package/dist/host/index.js +3 -0
  211. package/dist/host/types.d.ts +144 -0
  212. package/dist/host/types.js +1 -0
  213. package/dist/host/web-links.d.ts +38 -0
  214. package/dist/host/web-links.js +110 -0
  215. package/dist/host/web.d.ts +30 -0
  216. package/dist/host/web.js +216 -0
  217. package/dist/host/xr.d.ts +24 -0
  218. package/dist/host/xr.js +59 -0
  219. package/dist/i18n/i18n.d.ts +59 -0
  220. package/dist/i18n/i18n.js +241 -0
  221. package/dist/i18n/index.d.ts +3 -0
  222. package/dist/i18n/index.js +3 -0
  223. package/dist/i18n/message.d.ts +72 -0
  224. package/dist/i18n/message.js +369 -0
  225. package/dist/i18n/negotiate.d.ts +17 -0
  226. package/dist/i18n/negotiate.js +58 -0
  227. package/dist/index.d.ts +7 -0
  228. package/dist/index.js +1 -0
  229. package/dist/input/bindings.d.ts +31 -0
  230. package/dist/input/bindings.js +141 -0
  231. package/dist/input/clock.d.ts +44 -0
  232. package/dist/input/clock.js +49 -0
  233. package/dist/input/follow.d.ts +133 -0
  234. package/dist/input/follow.js +218 -0
  235. package/dist/input/gestures.d.ts +281 -0
  236. package/dist/input/gestures.js +662 -0
  237. package/dist/input/glyphs.d.ts +35 -0
  238. package/dist/input/glyphs.js +216 -0
  239. package/dist/input/gyro.d.ts +85 -0
  240. package/dist/input/gyro.js +140 -0
  241. package/dist/input/index.d.ts +19 -0
  242. package/dist/input/index.js +16 -0
  243. package/dist/input/input.d.ts +543 -0
  244. package/dist/input/input.js +1492 -0
  245. package/dist/input/look.d.ts +327 -0
  246. package/dist/input/look.js +681 -0
  247. package/dist/input/magnify.d.ts +177 -0
  248. package/dist/input/magnify.js +131 -0
  249. package/dist/input/pointer-dispatch.d.ts +138 -0
  250. package/dist/input/pointer-dispatch.js +180 -0
  251. package/dist/input/pointer-router.d.ts +204 -0
  252. package/dist/input/pointer-router.js +533 -0
  253. package/dist/input/pointer-sources.d.ts +164 -0
  254. package/dist/input/pointer-sources.js +306 -0
  255. package/dist/input/rays.d.ts +138 -0
  256. package/dist/input/rays.js +615 -0
  257. package/dist/input/record.d.ts +209 -0
  258. package/dist/input/record.js +601 -0
  259. package/dist/input/touch-zones.d.ts +147 -0
  260. package/dist/input/touch-zones.js +300 -0
  261. package/dist/input/types.d.ts +158 -0
  262. package/dist/input/types.js +1 -0
  263. package/dist/input/xr-source.d.ts +53 -0
  264. package/dist/input/xr-source.js +164 -0
  265. package/dist/nav/astar.d.ts +45 -0
  266. package/dist/nav/astar.js +182 -0
  267. package/dist/nav/corridor.d.ts +40 -0
  268. package/dist/nav/corridor.js +95 -0
  269. package/dist/nav/crowd.d.ts +94 -0
  270. package/dist/nav/crowd.js +624 -0
  271. package/dist/nav/flow.d.ts +61 -0
  272. package/dist/nav/flow.js +193 -0
  273. package/dist/nav/grid.d.ts +108 -0
  274. package/dist/nav/grid.js +210 -0
  275. package/dist/nav/heap.d.ts +22 -0
  276. package/dist/nav/heap.js +92 -0
  277. package/dist/nav/index.d.ts +37 -0
  278. package/dist/nav/index.js +19 -0
  279. package/dist/nav/mesh/areas.d.ts +44 -0
  280. package/dist/nav/mesh/areas.js +98 -0
  281. package/dist/nav/mesh/bake-options.d.ts +33 -0
  282. package/dist/nav/mesh/bake-options.js +76 -0
  283. package/dist/nav/mesh/contour.d.ts +22 -0
  284. package/dist/nav/mesh/contour.js +323 -0
  285. package/dist/nav/mesh/flow3.d.ts +35 -0
  286. package/dist/nav/mesh/flow3.js +229 -0
  287. package/dist/nav/mesh/links.d.ts +38 -0
  288. package/dist/nav/mesh/links.js +72 -0
  289. package/dist/nav/mesh/mesh-path.d.ts +152 -0
  290. package/dist/nav/mesh/mesh-path.js +643 -0
  291. package/dist/nav/mesh/mesh-reach.d.ts +78 -0
  292. package/dist/nav/mesh/mesh-reach.js +450 -0
  293. package/dist/nav/mesh/navmesh.d.ts +117 -0
  294. package/dist/nav/mesh/navmesh.js +647 -0
  295. package/dist/nav/mesh/polymesh.d.ts +24 -0
  296. package/dist/nav/mesh/polymesh.js +384 -0
  297. package/dist/nav/mesh/regions.d.ts +12 -0
  298. package/dist/nav/mesh/regions.js +367 -0
  299. package/dist/nav/mesh/serialize.d.ts +13 -0
  300. package/dist/nav/mesh/serialize.js +197 -0
  301. package/dist/nav/mesh/voxelize.d.ts +111 -0
  302. package/dist/nav/mesh/voxelize.js +552 -0
  303. package/dist/nav/obstacles.d.ts +75 -0
  304. package/dist/nav/obstacles.js +294 -0
  305. package/dist/nav/path.d.ts +59 -0
  306. package/dist/nav/path.js +177 -0
  307. package/dist/nav/query-queue.d.ts +46 -0
  308. package/dist/nav/query-queue.js +308 -0
  309. package/dist/nav/reach.d.ts +53 -0
  310. package/dist/nav/reach.js +148 -0
  311. package/dist/nav/steer.d.ts +36 -0
  312. package/dist/nav/steer.js +78 -0
  313. package/dist/platform/boot.d.ts +28 -0
  314. package/dist/platform/boot.js +43 -0
  315. package/dist/platform/device-mode.d.ts +40 -0
  316. package/dist/platform/device-mode.js +104 -0
  317. package/dist/platform/device.d.ts +31 -0
  318. package/dist/platform/device.js +91 -0
  319. package/dist/platform/environment.d.ts +42 -0
  320. package/dist/platform/environment.js +82 -0
  321. package/dist/platform/gpu.d.ts +40 -0
  322. package/dist/platform/gpu.js +57 -0
  323. package/dist/platform/index.d.ts +18 -0
  324. package/dist/platform/index.js +10 -0
  325. package/dist/platform/letterbox.d.ts +43 -0
  326. package/dist/platform/letterbox.js +57 -0
  327. package/dist/platform/links.d.ts +20 -0
  328. package/dist/platform/links.js +43 -0
  329. package/dist/platform/screens.d.ts +36 -0
  330. package/dist/platform/screens.js +138 -0
  331. package/dist/platform/surface.d.ts +72 -0
  332. package/dist/platform/surface.js +157 -0
  333. package/dist/platform/xr-fake.d.ts +168 -0
  334. package/dist/platform/xr-fake.js +434 -0
  335. package/dist/platform/xr-surface.d.ts +120 -0
  336. package/dist/platform/xr-surface.js +214 -0
  337. package/dist/platform/xr-types.d.ts +262 -0
  338. package/dist/post/ao.d.ts +12 -0
  339. package/dist/post/ao.js +136 -0
  340. package/dist/post/blend.d.ts +27 -0
  341. package/dist/post/blend.js +129 -0
  342. package/dist/post/depth-pass.d.ts +43 -0
  343. package/dist/post/depth-pass.js +118 -0
  344. package/dist/post/dof.d.ts +1 -0
  345. package/dist/post/dof.js +66 -0
  346. package/dist/post/exposure.d.ts +80 -0
  347. package/dist/post/exposure.js +322 -0
  348. package/dist/post/index.d.ts +12 -0
  349. package/dist/post/index.js +11 -0
  350. package/dist/post/lens-dirt.d.ts +13 -0
  351. package/dist/post/lens-dirt.js +91 -0
  352. package/dist/post/lut.d.ts +19 -0
  353. package/dist/post/lut.js +50 -0
  354. package/dist/post/motion-blur.d.ts +9 -0
  355. package/dist/post/motion-blur.js +78 -0
  356. package/dist/post/post-stack.d.ts +302 -0
  357. package/dist/post/post-stack.js +1137 -0
  358. package/dist/post/settings.d.ts +485 -0
  359. package/dist/post/settings.js +416 -0
  360. package/dist/post/shaders.d.ts +25 -0
  361. package/dist/post/shaders.js +410 -0
  362. package/dist/post/ssr.d.ts +16 -0
  363. package/dist/post/ssr.js +155 -0
  364. package/dist/post/taa.d.ts +74 -0
  365. package/dist/post/taa.js +235 -0
  366. package/dist/post/white-balance.d.ts +25 -0
  367. package/dist/post/white-balance.js +98 -0
  368. package/dist/render/bindings.d.ts +98 -0
  369. package/dist/render/bindings.js +281 -0
  370. package/dist/render/blend.d.ts +13 -0
  371. package/dist/render/blend.js +26 -0
  372. package/dist/render/camera-2d.d.ts +72 -0
  373. package/dist/render/camera-2d.js +92 -0
  374. package/dist/render/camera.d.ts +302 -0
  375. package/dist/render/camera.js +671 -0
  376. package/dist/render/color.d.ts +16 -0
  377. package/dist/render/color.js +41 -0
  378. package/dist/render/compressed.d.ts +104 -0
  379. package/dist/render/compressed.js +248 -0
  380. package/dist/render/diagnostics.d.ts +15 -0
  381. package/dist/render/diagnostics.js +43 -0
  382. package/dist/render/dynamic-resolution.d.ts +70 -0
  383. package/dist/render/dynamic-resolution.js +126 -0
  384. package/dist/render/fake-gpu.d.ts +204 -0
  385. package/dist/render/fake-gpu.js +426 -0
  386. package/dist/render/flipbook.d.ts +56 -0
  387. package/dist/render/flipbook.js +87 -0
  388. package/dist/render/frame.d.ts +278 -0
  389. package/dist/render/frame.js +174 -0
  390. package/dist/render/fullscreen.d.ts +54 -0
  391. package/dist/render/fullscreen.js +91 -0
  392. package/dist/render/gpu-timer.d.ts +73 -0
  393. package/dist/render/gpu-timer.js +186 -0
  394. package/dist/render/index.d.ts +53 -0
  395. package/dist/render/index.js +29 -0
  396. package/dist/render/instance-list.d.ts +185 -0
  397. package/dist/render/instance-list.js +547 -0
  398. package/dist/render/lights.d.ts +181 -0
  399. package/dist/render/lights.js +233 -0
  400. package/dist/render/lod.d.ts +54 -0
  401. package/dist/render/lod.js +52 -0
  402. package/dist/render/material.d.ts +165 -0
  403. package/dist/render/material.js +292 -0
  404. package/dist/render/mesh.d.ts +284 -0
  405. package/dist/render/mesh.js +472 -0
  406. package/dist/render/mipmap.d.ts +16 -0
  407. package/dist/render/mipmap.js +121 -0
  408. package/dist/render/parallax.d.ts +50 -0
  409. package/dist/render/parallax.js +47 -0
  410. package/dist/render/pbr-wgsl.d.ts +31 -0
  411. package/dist/render/pbr-wgsl.js +119 -0
  412. package/dist/render/ping-pong.d.ts +42 -0
  413. package/dist/render/ping-pong.js +74 -0
  414. package/dist/render/renderer.d.ts +741 -0
  415. package/dist/render/renderer.js +2486 -0
  416. package/dist/render/scene-pipelines.d.ts +44 -0
  417. package/dist/render/scene-pipelines.js +92 -0
  418. package/dist/render/scene-target.d.ts +170 -0
  419. package/dist/render/scene-target.js +450 -0
  420. package/dist/render/shadow.d.ts +74 -0
  421. package/dist/render/shadow.js +208 -0
  422. package/dist/render/skin.d.ts +112 -0
  423. package/dist/render/skin.js +240 -0
  424. package/dist/render/snapshot.d.ts +36 -0
  425. package/dist/render/snapshot.js +34 -0
  426. package/dist/render/standard.d.ts +162 -0
  427. package/dist/render/standard.js +263 -0
  428. package/dist/render/texture.d.ts +142 -0
  429. package/dist/render/texture.js +228 -0
  430. package/dist/render/tile-layer.d.ts +110 -0
  431. package/dist/render/tile-layer.js +304 -0
  432. package/dist/render/transform.d.ts +115 -0
  433. package/dist/render/transform.js +318 -0
  434. package/dist/render/wgsl.d.ts +131 -0
  435. package/dist/render/wgsl.js +528 -0
  436. package/dist/save/codec.d.ts +49 -0
  437. package/dist/save/codec.js +169 -0
  438. package/dist/save/index.d.ts +8 -0
  439. package/dist/save/index.js +8 -0
  440. package/dist/save/journal.d.ts +24 -0
  441. package/dist/save/journal.js +102 -0
  442. package/dist/save/migrate.d.ts +15 -0
  443. package/dist/save/migrate.js +37 -0
  444. package/dist/save/schema.d.ts +72 -0
  445. package/dist/save/schema.js +154 -0
  446. package/dist/save/settings.d.ts +28 -0
  447. package/dist/save/settings.js +59 -0
  448. package/dist/save/slots.d.ts +56 -0
  449. package/dist/save/slots.js +200 -0
  450. package/dist/save/storage.d.ts +35 -0
  451. package/dist/save/storage.js +62 -0
  452. package/dist/save/store.d.ts +114 -0
  453. package/dist/save/store.js +269 -0
  454. package/dist/testing/fake-host.d.ts +103 -0
  455. package/dist/testing/fake-host.js +163 -0
  456. package/dist/testing/fixed-clock.d.ts +25 -0
  457. package/dist/testing/fixed-clock.js +30 -0
  458. package/dist/testing/index.d.ts +4 -0
  459. package/dist/testing/index.js +5 -0
  460. package/dist/testing/test-game.d.ts +76 -0
  461. package/dist/testing/test-game.js +92 -0
  462. package/dist/tween/ease.d.ts +77 -0
  463. package/dist/tween/ease.js +192 -0
  464. package/dist/tween/index.d.ts +8 -0
  465. package/dist/tween/index.js +7 -0
  466. package/dist/tween/timeline.d.ts +78 -0
  467. package/dist/tween/timeline.js +269 -0
  468. package/dist/tween/tween.d.ts +168 -0
  469. package/dist/tween/tween.js +320 -0
  470. package/dist/ui/anchor.d.ts +206 -0
  471. package/dist/ui/anchor.js +307 -0
  472. package/dist/ui/caption.d.ts +122 -0
  473. package/dist/ui/caption.js +286 -0
  474. package/dist/ui/cursor.d.ts +105 -0
  475. package/dist/ui/cursor.js +261 -0
  476. package/dist/ui/dom.d.ts +30 -0
  477. package/dist/ui/dom.js +92 -0
  478. package/dist/ui/floats.d.ts +86 -0
  479. package/dist/ui/floats.js +260 -0
  480. package/dist/ui/hud.d.ts +198 -0
  481. package/dist/ui/hud.js +431 -0
  482. package/dist/ui/index.d.ts +37 -0
  483. package/dist/ui/index.js +34 -0
  484. package/dist/ui/inventory-card.d.ts +52 -0
  485. package/dist/ui/inventory-card.js +173 -0
  486. package/dist/ui/inventory-context.d.ts +29 -0
  487. package/dist/ui/inventory-context.js +125 -0
  488. package/dist/ui/inventory-drag.d.ts +63 -0
  489. package/dist/ui/inventory-drag.js +394 -0
  490. package/dist/ui/inventory-grid.d.ts +66 -0
  491. package/dist/ui/inventory-grid.js +625 -0
  492. package/dist/ui/inventory-radial.d.ts +39 -0
  493. package/dist/ui/inventory-radial.js +168 -0
  494. package/dist/ui/inventory.d.ts +128 -0
  495. package/dist/ui/inventory.js +154 -0
  496. package/dist/ui/layout.d.ts +356 -0
  497. package/dist/ui/layout.js +856 -0
  498. package/dist/ui/link.d.ts +64 -0
  499. package/dist/ui/link.js +155 -0
  500. package/dist/ui/loading.d.ts +40 -0
  501. package/dist/ui/loading.js +157 -0
  502. package/dist/ui/loupe.d.ts +74 -0
  503. package/dist/ui/loupe.js +164 -0
  504. package/dist/ui/menu-nav.d.ts +33 -0
  505. package/dist/ui/menu-nav.js +28 -0
  506. package/dist/ui/minimap-canvas.d.ts +145 -0
  507. package/dist/ui/minimap-canvas.js +460 -0
  508. package/dist/ui/notify.d.ts +40 -0
  509. package/dist/ui/notify.js +141 -0
  510. package/dist/ui/orb.d.ts +53 -0
  511. package/dist/ui/orb.js +304 -0
  512. package/dist/ui/overlay.d.ts +213 -0
  513. package/dist/ui/overlay.js +394 -0
  514. package/dist/ui/padnav.d.ts +53 -0
  515. package/dist/ui/padnav.js +146 -0
  516. package/dist/ui/perf.d.ts +130 -0
  517. package/dist/ui/perf.js +329 -0
  518. package/dist/ui/rotate-card.d.ts +54 -0
  519. package/dist/ui/rotate-card.js +97 -0
  520. package/dist/ui/stack.d.ts +128 -0
  521. package/dist/ui/stack.js +312 -0
  522. package/dist/ui/styles.d.ts +13 -0
  523. package/dist/ui/styles.js +200 -0
  524. package/dist/ui/text-scale.d.ts +67 -0
  525. package/dist/ui/text-scale.js +102 -0
  526. package/dist/ui/theme.d.ts +70 -0
  527. package/dist/ui/theme.js +98 -0
  528. package/dist/ui/toast.d.ts +23 -0
  529. package/dist/ui/toast.js +46 -0
  530. package/dist/ui/tooltip.d.ts +89 -0
  531. package/dist/ui/tooltip.js +333 -0
  532. package/dist/ui/widgets-2.d.ts +134 -0
  533. package/dist/ui/widgets-2.js +399 -0
  534. package/dist/ui/widgets-3.d.ts +91 -0
  535. package/dist/ui/widgets-3.js +212 -0
  536. package/dist/ui/widgets.d.ts +34 -0
  537. package/dist/ui/widgets.js +50 -0
  538. package/dist/ui/world-panel/index.d.ts +5 -0
  539. package/dist/ui/world-panel/index.js +5 -0
  540. package/dist/ui/world-panel/layout.d.ts +38 -0
  541. package/dist/ui/world-panel/layout.js +68 -0
  542. package/dist/ui/world-panel/paint.d.ts +96 -0
  543. package/dist/ui/world-panel/paint.js +136 -0
  544. package/dist/ui/world-panel/panel.d.ts +235 -0
  545. package/dist/ui/world-panel/panel.js +762 -0
  546. package/dist/ui/world-panel/wgsl.d.ts +10 -0
  547. package/dist/ui/world-panel/wgsl.js +52 -0
  548. package/dist/ui/world-panel/widgets.d.ts +207 -0
  549. package/dist/ui/world-panel/widgets.js +569 -0
  550. package/dist/voxel/chunks.d.ts +77 -0
  551. package/dist/voxel/chunks.js +149 -0
  552. package/dist/voxel/grid.d.ts +84 -0
  553. package/dist/voxel/grid.js +223 -0
  554. package/dist/voxel/index.d.ts +22 -0
  555. package/dist/voxel/index.js +7 -0
  556. package/dist/voxel/mesher-worker.d.ts +14 -0
  557. package/dist/voxel/mesher-worker.js +47 -0
  558. package/dist/voxel/mesher.d.ts +73 -0
  559. package/dist/voxel/mesher.js +306 -0
  560. package/dist/voxel/ray.d.ts +32 -0
  561. package/dist/voxel/ray.js +73 -0
  562. package/dist/voxel/wgsl.d.ts +16 -0
  563. package/dist/voxel/wgsl.js +28 -0
  564. package/dist/voxel/worker-client.d.ts +79 -0
  565. package/dist/voxel/worker-client.js +122 -0
  566. package/package.json +177 -3
@@ -0,0 +1,129 @@
1
+ import { ease } from '../tween/ease.js';
2
+ export const easeLinear = ease.linear;
3
+ /** Smoothstep: gentle start and end. The default for `blendTo`. */
4
+ export const easeInOut = ease.smoothstep;
5
+ export const easeOut = ease.quadOut;
6
+ export const easeIn = ease.quadIn;
7
+ /**
8
+ * Fields that only make sense as whole values, by `section.key`: `bloom.levels` would resize
9
+ * mid-blend, `lut.texture` is a handle and `lut.size` must match it, `motionBlur.mode` is a
10
+ * choice. They switch when the blend ends (any other non-number does too).
11
+ */
12
+ const SNAP_KEYS = new Set(['bloom.levels', 'lut.texture', 'lut.size', 'motionBlur.mode']);
13
+ /**
14
+ * Interpolates post settings over time. Numbers and RGB triples ease from their value when
15
+ * `blendTo` is called; everything else switches at once (`enabled: true`, so a pass can fade
16
+ * in) or at the end (`enabled: false`, `tonemap`, `dither`, `levels`, so a pass can fade out).
17
+ * Pure: no GPU, no clock. `PostStack` advances it with the frame time.
18
+ */
19
+ export class PostBlender {
20
+ tracks = [];
21
+ /** True while any value is still moving. */
22
+ get active() {
23
+ return this.tracks.length > 0;
24
+ }
25
+ blendTo(target, patch, seconds, ease) {
26
+ const dur = Math.max(0, Number.isFinite(seconds) ? seconds : 0);
27
+ for (const name of Object.keys(patch)) {
28
+ const src = patch[name];
29
+ if (!src)
30
+ continue;
31
+ const section = name;
32
+ const cur = target[section];
33
+ for (const key of Object.keys(src)) {
34
+ const to = src[key];
35
+ if (to === undefined)
36
+ continue;
37
+ this.drop(section, key);
38
+ const from = cur[key];
39
+ const numeric = !SNAP_KEYS.has(`${section}.${key}`) &&
40
+ ((typeof to === 'number' && typeof from === 'number') ||
41
+ (Array.isArray(to) && Array.isArray(from) && to.length === from.length));
42
+ if (!numeric) {
43
+ // Turning something on happens first so its values can ease in; the rest waits.
44
+ if (to === true || dur === 0) {
45
+ cur[key] = to;
46
+ continue;
47
+ }
48
+ }
49
+ if (dur === 0) {
50
+ cur[key] = Array.isArray(to) ? [...to] : to;
51
+ continue;
52
+ }
53
+ // Own the array we animate in place (it may be a preset object shared via `set`).
54
+ if (numeric && Array.isArray(from))
55
+ cur[key] = [...from];
56
+ this.tracks.push({
57
+ section,
58
+ key,
59
+ from: Array.isArray(from) ? [...from] : from,
60
+ to: Array.isArray(to) ? [...to] : to,
61
+ snap: !numeric,
62
+ elapsed: 0,
63
+ seconds: dur,
64
+ ease,
65
+ });
66
+ }
67
+ }
68
+ }
69
+ /** Stop blending the given keys (e.g. after `set` overwrote them). */
70
+ cancel(patch) {
71
+ if (!this.tracks.length)
72
+ return;
73
+ for (const name of Object.keys(patch)) {
74
+ const src = patch[name];
75
+ if (!src)
76
+ continue;
77
+ for (const key of Object.keys(src))
78
+ this.drop(name, key);
79
+ }
80
+ }
81
+ /** Jump every track to its end value. */
82
+ finish(target) {
83
+ for (const t of this.tracks)
84
+ t.elapsed = t.seconds;
85
+ this.advance(target, 0);
86
+ }
87
+ /** Move every track forward by `dt` seconds and write the values into `target`. */
88
+ advance(target, dt) {
89
+ const tracks = this.tracks;
90
+ let w = 0;
91
+ for (let i = 0; i < tracks.length; i++) {
92
+ const t = tracks[i];
93
+ t.elapsed += Math.max(0, dt);
94
+ const p = Math.min(1, t.elapsed / t.seconds);
95
+ const cur = target[t.section];
96
+ if (t.snap) {
97
+ if (p >= 1)
98
+ cur[t.key] = t.to;
99
+ }
100
+ else {
101
+ const k = t.ease(p);
102
+ if (typeof t.to === 'number') {
103
+ const a = t.from;
104
+ cur[t.key] = p >= 1 ? t.to : a + (t.to - a) * k;
105
+ }
106
+ else {
107
+ const out = cur[t.key];
108
+ const a = t.from;
109
+ const b = t.to;
110
+ for (let j = 0; j < b.length; j++)
111
+ out[j] = p >= 1 ? b[j] : a[j] + (b[j] - a[j]) * k;
112
+ }
113
+ }
114
+ if (p < 1)
115
+ tracks[w++] = t;
116
+ }
117
+ tracks.length = w;
118
+ }
119
+ drop(section, key) {
120
+ const tracks = this.tracks;
121
+ let w = 0;
122
+ for (let i = 0; i < tracks.length; i++) {
123
+ const t = tracks[i];
124
+ if (t.section !== section || t.key !== key)
125
+ tracks[w++] = t;
126
+ }
127
+ tracks.length = w;
128
+ }
129
+ }
@@ -0,0 +1,43 @@
1
+ import type { Renderer } from '../render/renderer.js';
2
+ /**
3
+ * A fullscreen pass that reads the scene's depth buffer (ws/post-depth). `FullscreenPass` binds
4
+ * `texture_2d<f32>` only, so the two depth passes build their own layout:
5
+ *
6
+ * - `@binding(0)` the post uniforms (`WGSL_POST_UNIFORMS`),
7
+ * - `@binding(1)` a nearest-clamp sampler, `@binding(2)` a linear-clamp sampler,
8
+ * - `@binding(3)` the depth as `texture_depth_2d`,
9
+ * - `@binding(4 + i)` `textures` further `texture_2d<f32>` inputs.
10
+ *
11
+ * `format` may list several targets (ws/post-5: the TAA resolve also writes its history aux);
12
+ * `encode` then takes the targets after the first in `extraTargets`.
13
+ *
14
+ * One uniform buffer per pass, written with `setUniforms` (or copied into on the encoder,
15
+ * `uniformBuffer`, when several XR eyes share one submit). Bind groups come from
16
+ * `createBindGroup` and are cached by the caller, as with `FullscreenPass`.
17
+ */
18
+ export declare class DepthPass {
19
+ readonly label: string;
20
+ private readonly device;
21
+ private readonly pipeline;
22
+ private readonly layout;
23
+ private readonly uniforms;
24
+ private readonly nearest;
25
+ private readonly linear;
26
+ private readonly textures;
27
+ private readonly colorAttachments;
28
+ private readonly passDesc;
29
+ private readonly entries;
30
+ constructor(renderer: Renderer, desc: {
31
+ label: string;
32
+ wgsl: string;
33
+ format: GPUTextureFormat | readonly GPUTextureFormat[];
34
+ textures: number;
35
+ });
36
+ /** The pass's uniform buffer, for an encoder-ordered copy (ws/render-12: one per XR eye). */
37
+ get uniformBuffer(): GPUBuffer;
38
+ setUniforms(data: Float32Array): void;
39
+ /** A bind group for `depth` and `textures` further inputs (cache it; rebuild on change). */
40
+ createBindGroup(depth: GPUTextureView, views: readonly GPUTextureView[]): GPUBindGroup;
41
+ encode(encoder: GPUCommandEncoder, target: GPUTextureView, group: GPUBindGroup, timestampWrites?: GPURenderPassTimestampWrites, extraTargets?: readonly GPUTextureView[]): void;
42
+ destroy(): void;
43
+ }
@@ -0,0 +1,118 @@
1
+ import { createShaderModule, WGSL_FULLSCREEN_PRELUDE } from '../render/wgsl.js';
2
+ import { POST_UNIFORM_FLOATS } from './settings.js';
3
+ /**
4
+ * A fullscreen pass that reads the scene's depth buffer (ws/post-depth). `FullscreenPass` binds
5
+ * `texture_2d<f32>` only, so the two depth passes build their own layout:
6
+ *
7
+ * - `@binding(0)` the post uniforms (`WGSL_POST_UNIFORMS`),
8
+ * - `@binding(1)` a nearest-clamp sampler, `@binding(2)` a linear-clamp sampler,
9
+ * - `@binding(3)` the depth as `texture_depth_2d`,
10
+ * - `@binding(4 + i)` `textures` further `texture_2d<f32>` inputs.
11
+ *
12
+ * `format` may list several targets (ws/post-5: the TAA resolve also writes its history aux);
13
+ * `encode` then takes the targets after the first in `extraTargets`.
14
+ *
15
+ * One uniform buffer per pass, written with `setUniforms` (or copied into on the encoder,
16
+ * `uniformBuffer`, when several XR eyes share one submit). Bind groups come from
17
+ * `createBindGroup` and are cached by the caller, as with `FullscreenPass`.
18
+ */
19
+ export class DepthPass {
20
+ label;
21
+ device;
22
+ pipeline;
23
+ layout;
24
+ uniforms;
25
+ nearest;
26
+ linear;
27
+ textures;
28
+ colorAttachments;
29
+ passDesc;
30
+ entries;
31
+ constructor(renderer, desc) {
32
+ const formats = typeof desc.format === 'string' ? [desc.format] : desc.format;
33
+ const device = renderer.device;
34
+ this.device = device;
35
+ this.label = desc.label;
36
+ this.textures = desc.textures;
37
+ this.nearest = renderer.samplers['nearest-clamp'];
38
+ this.linear = renderer.samplers['linear-clamp'];
39
+ const frag = GPUShaderStage.FRAGMENT;
40
+ const entries = [
41
+ { binding: 0, visibility: frag, buffer: {} },
42
+ { binding: 1, visibility: frag, sampler: { type: 'non-filtering' } },
43
+ { binding: 2, visibility: frag, sampler: {} },
44
+ { binding: 3, visibility: frag, texture: { sampleType: 'depth' } },
45
+ ];
46
+ for (let i = 0; i < desc.textures; i++) {
47
+ entries.push({ binding: 4 + i, visibility: frag, texture: { sampleType: 'float' } });
48
+ }
49
+ this.layout = device.createBindGroupLayout({ label: `pass:${desc.label}`, entries });
50
+ this.uniforms = device.createBuffer({
51
+ label: `pass:${desc.label}-uniforms`,
52
+ size: POST_UNIFORM_FLOATS * 4,
53
+ usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST,
54
+ });
55
+ const code = `${WGSL_FULLSCREEN_PRELUDE}\n// ---- pass: ${desc.label} ----\n${desc.wgsl}`;
56
+ const module = createShaderModule(device, code, `pass:${desc.label}`);
57
+ this.pipeline = device.createRenderPipeline({
58
+ label: `pass:${desc.label}`,
59
+ layout: device.createPipelineLayout({ bindGroupLayouts: [this.layout] }),
60
+ vertex: { module, entryPoint: 'vs_fullscreen' },
61
+ fragment: { module, entryPoint: 'fs_main', targets: formats.map((format) => ({ format })) },
62
+ primitive: { topology: 'triangle-list' },
63
+ });
64
+ this.entries = [
65
+ { binding: 0, resource: { buffer: this.uniforms } },
66
+ { binding: 1, resource: this.nearest },
67
+ { binding: 2, resource: this.linear },
68
+ ];
69
+ this.colorAttachments = formats.map(() => ({
70
+ view: undefined,
71
+ loadOp: 'clear',
72
+ storeOp: 'store',
73
+ clearValue: { r: 1, g: 1, b: 1, a: 1 },
74
+ }));
75
+ this.passDesc = { label: `pass:${desc.label}`, colorAttachments: this.colorAttachments };
76
+ }
77
+ /** The pass's uniform buffer, for an encoder-ordered copy (ws/render-12: one per XR eye). */
78
+ get uniformBuffer() {
79
+ return this.uniforms;
80
+ }
81
+ setUniforms(data) {
82
+ this.device.queue.writeBuffer(this.uniforms, 0, data.buffer, data.byteOffset, data.byteLength);
83
+ }
84
+ /** A bind group for `depth` and `textures` further inputs (cache it; rebuild on change). */
85
+ createBindGroup(depth, views) {
86
+ if (views.length !== this.textures) {
87
+ throw new Error(`pass ${this.label}: expected ${this.textures} textures, got ${views.length}`);
88
+ }
89
+ const entries = this.entries.slice();
90
+ entries.push({ binding: 3, resource: depth });
91
+ for (let i = 0; i < views.length; i++)
92
+ entries.push({ binding: 4 + i, resource: views[i] });
93
+ return this.device.createBindGroup({
94
+ label: `pass:${this.label}`,
95
+ layout: this.layout,
96
+ entries,
97
+ });
98
+ }
99
+ encode(encoder, target, group, timestampWrites, extraTargets) {
100
+ const atts = this.colorAttachments;
101
+ atts[0].view = target;
102
+ for (let i = 1; i < atts.length; i++) {
103
+ const view = extraTargets?.[i - 1];
104
+ if (!view)
105
+ throw new Error(`pass ${this.label}: expected ${atts.length} targets`);
106
+ atts[i].view = view;
107
+ }
108
+ this.passDesc.timestampWrites = timestampWrites;
109
+ const pass = encoder.beginRenderPass(this.passDesc);
110
+ pass.setPipeline(this.pipeline);
111
+ pass.setBindGroup(0, group);
112
+ pass.draw(3);
113
+ pass.end();
114
+ }
115
+ destroy() {
116
+ this.uniforms.destroy();
117
+ }
118
+ }
@@ -0,0 +1 @@
1
+ export declare const DOF_WGSL = "\n\nstruct PostUniforms {\n frame: vec4f, // time, aspect, 1/width, 1/height\n enables: vec4f, // bloom, fog, rays, vignette\n enables2: vec4f, // grade, tonemap (0 none, 1 aces, 2 reinhard), dither, exposure\n bloom: vec4f, // intensity, threshold, knee, emissiveWeight\n bloom2: vec4f, // scatter, -, -, -\n fogColor: vec4f, // rgb, density\n fog: vec4f, // top, bottom, noiseScale, speed\n fog2: vec4f, // lightScatter, falloff, -, -\n rays: vec4f, // light uv x, y, intensity, decay\n rays2: vec4f, // density, weight, source radius (uv-y units), source intensity\n raysColor: vec4f, // rgb, bloomSource\n vignette: vec4f, // intensity, radius, softness, -\n vignetteColor: vec4f,\n lift: vec4f,\n gamma: vec4f,\n gain: vec4f,\n grade: vec4f, // saturation, contrast, -, -\n quality: vec4f, // ray samples, fog octaves, ortho projection (1, ws/post-4), -\n ao: vec4f, // enabled (0 without depth), radius, intensity, bias\n ao2: vec4f, // power, samples, proj x scale, proj y scale\n dof: vec4f, // enabled (0 without depth), focus distance, focus range, max blur (uv of width)\n dof2: vec4f, // near blur, taps, near plane, far plane\n invProj: mat4x4f, // clip -> view\n fxaa: vec4f, // enabled, subpixel, edgeThreshold, -\n lut: vec4f, // enabled, (size-1)/size, intensity, 0.5/size\n grain: vec4f, // intensity, cell size (px), luminanceResponse, seed\n aberration: vec4f, // intensity (px), radialOnly, -, -\n sharpen: vec4f, // amount, -, -, -\n outline: vec4f, // enabled (0 without depth), thickness (scene px), depthThreshold, normalThreshold\n outlineColor: vec4f, // rgb, intensity\n // Post 3 (ws/post-3).\n taa: vec4f, // enabled (0 without depth), feedback, sharpen, clampMode (0 aabb, 1 variance)\n taa2: vec4f, // view jitter x (uv), view jitter y (uv), reset (1 = copy the current frame), velocity reprojection (1, ws/post-5)\n ssr: vec4f, // enabled (0 without depth), maxSteps, thickness, maxDistance\n ssr2: vec4f, // roughnessCutoff, intensity, fadeEdges (uv), rough-metal target (1)\n exposure: vec4f, // auto (1), histogramLow, histogramHigh, keyValue\n wb0: vec4f, // white-balance matrix row 0 (rgb weights), enabled\n wb1: vec4f, // row 1\n wb2: vec4f, // row 2\n motionBlur: vec4f, // enabled (0 without depth), intensity, samples, velocity target (1 = object)\n dirt: vec4f, // enabled, intensity, -, -\n reproj: mat4x4f, // current clip -> previous frame's clip (identity on a reset)\n // Post 5 (ws/post-5).\n taa3: vec4f, // depthReject (fraction), velocityReject (px), history filter (1 = Catmull-Rom, ws/post-6), -\n};\n@group(0) @binding(0) var<uniform> P: PostUniforms;\n\n@group(0) @binding(1) var nearest: sampler;\n@group(0) @binding(2) var linSamp: sampler;\n@group(0) @binding(3) var depthTex: texture_depth_2d;\n@group(0) @binding(4) var colorTex: texture_2d<f32>;\n\nfn view_pos(uv: vec2f, depth: f32) -> vec3f {\n let ndc = vec3f(uv.x * 2.0 - 1.0, 1.0 - uv.y * 2.0, depth);\n let p = P.invProj * vec4f(ndc, 1.0);\n return p.xyz / p.w;\n}\nfn linear_depth(uv: vec2f, depth: f32) -> f32 {\n return -view_pos(uv, depth).z;\n}\n/** The centre of the depth texel under `uv`: positions must be rebuilt where the depth was read. */\nfn texel_uv(uv: vec2f, dim: vec2f) -> vec2f {\n return (floor(clamp(uv, vec2f(0.0), vec2f(0.9999)) * dim) + 0.5) / dim;\n}\n\n\n/** Signed circle of confusion in uv (fraction of the width). */\nfn coc_at(uv: vec2f) -> f32 {\n let d = textureSampleLevel(depthTex, nearest, uv, 0u);\n var z = P.dof.y + P.dof.z * 4.0; // sky: past the far side of the range\n if (d < 1.0) {\n z = linear_depth(uv, d);\n }\n var c = clamp((z - P.dof.y) / P.dof.z, -1.0, 1.0);\n if (P.dof2.x < 0.5) {\n c = max(c, 0.0);\n }\n return c * P.dof.w;\n}\n\nfn ign(px: vec2f) -> f32 {\n return fract(52.9829189 * fract(0.06711056 * px.x + 0.00583715 * px.y));\n}\n\n@fragment fn fs_main(in: FullscreenIn) -> @location(0) vec4f {\n let uv = in.uv;\n let aspect = P.frame.y;\n let cc = coc_at(uv);\n let r = abs(cc);\n var sum = textureSampleLevel(colorTex, linSamp, uv, 0.0).rgb;\n var wsum = 1.0;\n let count = i32(P.dof2.y);\n let rot = ign(in.pos.xy) * 6.2831853;\n // Taps reach as far as the widest CoC they could meet, so blurred things behind a sharp\n // edge still gather; each tap's own CoC decides whether it belongs.\n let reach = max(r, P.dof.w * 0.5);\n for (var i = 0; i < count; i++) {\n let a = (f32(i) + 0.5) / f32(count);\n let ang = rot + f32(i) * 2.39996323;\n let dist = sqrt(a) * reach;\n let suv = uv + vec2f(cos(ang), sin(ang) * aspect) * dist;\n let sc = coc_at(suv);\n // A sample contributes where its own circle covers this pixel (or ours covers it).\n let cover = max(abs(sc), select(0.0, r, sc > 0.0 && cc > 0.0));\n let w = clamp((cover - dist) / max(P.dof.w * 0.05, 1e-5) + 1.0, 0.0, 1.0);\n sum += textureSampleLevel(colorTex, linSamp, suv, 0.0).rgb * w;\n wsum += w;\n }\n return vec4f(sum / wsum, cc);\n}\n";
@@ -0,0 +1,66 @@
1
+ /**
2
+ * Depth of field (ws/post-depth): a half-res gather over the scene colour weighted by the
3
+ * circle of confusion, which comes from linear depth. The composite blends sharp and blurred
4
+ * by the CoC it reads from this pass's alpha.
5
+ *
6
+ * CoC is signed: negative in front of the focus (near field), positive behind. Without
7
+ * `dof.nearBlur` the near side is clamped to 0. The gather takes `PostQuality.dofTaps` taps on
8
+ * a golden-angle disc (so the pattern has no axis), scaled by the centre's CoC and rotated per
9
+ * pixel by interleaved-gradient noise; each tap counts by how far its own CoC reaches the centre,
10
+ * so a sharp foreground does not bleed into a blurred background.
11
+ */
12
+ import { WGSL_DEPTH_VIEW } from './ao.js';
13
+ import { WGSL_POST_UNIFORMS } from './settings.js';
14
+ export const DOF_WGSL = /* wgsl */ `
15
+ ${WGSL_POST_UNIFORMS}
16
+ @group(0) @binding(1) var nearest: sampler;
17
+ @group(0) @binding(2) var linSamp: sampler;
18
+ @group(0) @binding(3) var depthTex: texture_depth_2d;
19
+ @group(0) @binding(4) var colorTex: texture_2d<f32>;
20
+ ${WGSL_DEPTH_VIEW}
21
+
22
+ /** Signed circle of confusion in uv (fraction of the width). */
23
+ fn coc_at(uv: vec2f) -> f32 {
24
+ let d = textureSampleLevel(depthTex, nearest, uv, 0u);
25
+ var z = P.dof.y + P.dof.z * 4.0; // sky: past the far side of the range
26
+ if (d < 1.0) {
27
+ z = linear_depth(uv, d);
28
+ }
29
+ var c = clamp((z - P.dof.y) / P.dof.z, -1.0, 1.0);
30
+ if (P.dof2.x < 0.5) {
31
+ c = max(c, 0.0);
32
+ }
33
+ return c * P.dof.w;
34
+ }
35
+
36
+ fn ign(px: vec2f) -> f32 {
37
+ return fract(52.9829189 * fract(0.06711056 * px.x + 0.00583715 * px.y));
38
+ }
39
+
40
+ @fragment fn fs_main(in: FullscreenIn) -> @location(0) vec4f {
41
+ let uv = in.uv;
42
+ let aspect = P.frame.y;
43
+ let cc = coc_at(uv);
44
+ let r = abs(cc);
45
+ var sum = textureSampleLevel(colorTex, linSamp, uv, 0.0).rgb;
46
+ var wsum = 1.0;
47
+ let count = i32(P.dof2.y);
48
+ let rot = ign(in.pos.xy) * 6.2831853;
49
+ // Taps reach as far as the widest CoC they could meet, so blurred things behind a sharp
50
+ // edge still gather; each tap's own CoC decides whether it belongs.
51
+ let reach = max(r, P.dof.w * 0.5);
52
+ for (var i = 0; i < count; i++) {
53
+ let a = (f32(i) + 0.5) / f32(count);
54
+ let ang = rot + f32(i) * 2.39996323;
55
+ let dist = sqrt(a) * reach;
56
+ let suv = uv + vec2f(cos(ang), sin(ang) * aspect) * dist;
57
+ let sc = coc_at(suv);
58
+ // A sample contributes where its own circle covers this pixel (or ours covers it).
59
+ let cover = max(abs(sc), select(0.0, r, sc > 0.0 && cc > 0.0));
60
+ let w = clamp((cover - dist) / max(P.dof.w * 0.05, 1e-5) + 1.0, 0.0, 1.0);
61
+ sum += textureSampleLevel(colorTex, linSamp, suv, 0.0).rgb * w;
62
+ wsum += w;
63
+ }
64
+ return vec4f(sum / wsum, cc);
65
+ }
66
+ `;
@@ -0,0 +1,80 @@
1
+ /**
2
+ * Auto-exposure (ws/post-3). Two compute passes over the scene colour: `histogram` bins the
3
+ * log2 luminance of every texel into 64 bins over `EXPOSURE_LOG_MIN..EXPOSURE_LOG_MAX`
4
+ * (workgroup-shared counts, then one atomic add per bin), `average` has one thread walk the
5
+ * bins between the `histogramLow..histogramHigh` percentiles and write the weighted mean log
6
+ * luminance. The stack copies that into a mappable buffer, maps it when the previous frame's
7
+ * copy has landed, and eases its EV toward `exposureTarget(...)` with `adaptExposure` each
8
+ * frame on the CPU. `exposureHistogram` and `exposureAverage` are the same two kernels in
9
+ * TypeScript, for tests and for a CPU reference.
10
+ */
11
+ import type { Renderer } from '../render/renderer.js';
12
+ export declare const EXPOSURE_BINS = 64;
13
+ /** log2 luminance of the first bin's lower edge (2^-10 ≈ 0.001). */
14
+ export declare const EXPOSURE_LOG_MIN = -10;
15
+ /** log2 luminance of the last bin's upper edge (2^6 = 64). */
16
+ export declare const EXPOSURE_LOG_MAX = 6;
17
+ /** The bin (0..63) a luminance falls in; black and anything under the range land in bin 0. */
18
+ export declare function exposureBin(luminance: number): number;
19
+ /** log2 luminance at the centre of bin `i`. */
20
+ export declare function exposureBinLog(i: number): number;
21
+ /**
22
+ * CPU reference of the histogram kernel: `rgba` holds `count` linear RGBA texels (any
23
+ * `ArrayLike`); `out` (64 entries) receives the counts (cleared first).
24
+ */
25
+ export declare function exposureHistogram(rgba: ArrayLike<number>, count: number, out?: Uint32Array): Uint32Array;
26
+ /**
27
+ * CPU reference of the average kernel: the mean log2 luminance of the texels between the
28
+ * `low` and `high` percentiles of `hist` (bins partially inside the range count partially).
29
+ * Returns `EXPOSURE_LOG_MIN` for an empty histogram.
30
+ */
31
+ export declare function exposureAverage(hist: ArrayLike<number>, low: number, high: number): number;
32
+ /** The EV the metered average asks for: `log2(keyValue / average)`, clamped to the range. */
33
+ export declare function exposureTarget(averageLog: number, keyValue: number, minEv: number, maxEv: number): number;
34
+ /**
35
+ * One step of the adaptation: `ev` eased toward `target` over `dt` seconds, at `speedUp`
36
+ * per second when rising and `speedDown` when falling (exponential, so it settles without
37
+ * overshoot and a long `dt` lands on the target).
38
+ */
39
+ export declare function adaptExposure(ev: number, target: number, dt: number, speedUp: number, speedDown: number): number;
40
+ /**
41
+ * The two compute passes and their buffers. `encode` records both (clearing the histogram
42
+ * first) and the copy into the readback buffer; `poll` maps it when free and stores the last
43
+ * average in `averageLog`. On a device without `mapAsync` (the fake one) nothing is read back.
44
+ */
45
+ export declare class ExposurePasses {
46
+ private readonly device;
47
+ private readonly histogram;
48
+ private readonly average;
49
+ private readonly histLayout;
50
+ private readonly histBuffer;
51
+ private readonly resultBuffer;
52
+ private readonly readBuffer;
53
+ private readonly params;
54
+ private readonly paramData;
55
+ private readonly averageGroup;
56
+ private histGroup;
57
+ private boundColor;
58
+ private readonly histDesc;
59
+ private readonly avgDesc;
60
+ /** A copy into the readback buffer is in flight (the next `poll` may map it). */
61
+ private pending;
62
+ private mapping;
63
+ /** The last metered average log2 luminance (`EXPOSURE_LOG_MIN` until the first readback). */
64
+ averageLog: number;
65
+ /** How many readbacks have landed. */
66
+ readbacks: number;
67
+ private readonly onMapped;
68
+ private readonly onMapFailed;
69
+ constructor(renderer: Renderer);
70
+ /**
71
+ * Map the last copy if one is waiting and the buffer is free (call before `encode`, once the
72
+ * previous frame's work has been submitted).
73
+ */
74
+ poll(): void;
75
+ /** Record the histogram, the average and (when the readback buffer is free) the copy. */
76
+ encode(encoder: GPUCommandEncoder, color: GPUTextureView, width: number, height: number, low: number, high: number): void;
77
+ /** Forget a stale bind group (the colour texture was replaced). */
78
+ invalidate(): void;
79
+ destroy(): void;
80
+ }