@forgeax/engine-runtime 0.1.4 → 0.1.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (606) hide show
  1. package/README.md +49 -83
  2. package/dist/.tsbuildinfo +1 -1
  3. package/dist/__tests__/animation-graph-collect-roundtrip.test.d.ts +2 -0
  4. package/dist/__tests__/animation-graph-collect-roundtrip.test.d.ts.map +1 -0
  5. package/dist/__tests__/animation-graph-serialize.unit.test.d.ts +2 -0
  6. package/dist/__tests__/animation-graph-serialize.unit.test.d.ts.map +1 -0
  7. package/dist/__tests__/asset-brand-and-name-retirement.test.d.ts +2 -0
  8. package/dist/__tests__/asset-brand-and-name-retirement.test.d.ts.map +1 -0
  9. package/dist/__tests__/asset-error-exhaustive.test-d.d.ts +11 -0
  10. package/dist/__tests__/asset-error-exhaustive.test-d.d.ts.map +1 -0
  11. package/dist/__tests__/asset-registry-guid-reverse.test.d.ts +2 -0
  12. package/dist/__tests__/asset-registry-guid-reverse.test.d.ts.map +1 -0
  13. package/dist/__tests__/asset-registry-hdr-equirect.test.d.ts +2 -0
  14. package/dist/__tests__/asset-registry-hdr-equirect.test.d.ts.map +1 -0
  15. package/dist/__tests__/asset-registry-mesh-pack-payload.dawn.test.d.ts +2 -0
  16. package/dist/__tests__/asset-registry-mesh-pack-payload.dawn.test.d.ts.map +1 -0
  17. package/dist/__tests__/asset-registry-mounts.test.d.ts +2 -0
  18. package/dist/__tests__/asset-registry-mounts.test.d.ts.map +1 -0
  19. package/dist/__tests__/asset-registry.browser.test.d.ts +2 -0
  20. package/dist/__tests__/asset-registry.browser.test.d.ts.map +1 -0
  21. package/dist/__tests__/asset-registry.dawn.test.d.ts +2 -0
  22. package/dist/__tests__/asset-registry.dawn.test.d.ts.map +1 -0
  23. package/dist/__tests__/asset-registry.listCatalog.test.d.ts +2 -0
  24. package/dist/__tests__/asset-registry.listCatalog.test.d.ts.map +1 -0
  25. package/dist/__tests__/asset-registry.mesh-bin.test.d.ts +2 -0
  26. package/dist/__tests__/asset-registry.mesh-bin.test.d.ts.map +1 -0
  27. package/dist/__tests__/asset-registry.pack-cache.test.d.ts +2 -0
  28. package/dist/__tests__/asset-registry.pack-cache.test.d.ts.map +1 -0
  29. package/dist/__tests__/asset-registry.raw-container-failfast.test.d.ts +2 -0
  30. package/dist/__tests__/asset-registry.raw-container-failfast.test.d.ts.map +1 -0
  31. package/dist/__tests__/asset-registry.recursive.spec.d.ts +2 -0
  32. package/dist/__tests__/asset-registry.recursive.spec.d.ts.map +1 -0
  33. package/dist/__tests__/asset-registry.unit.test.d.ts +2 -0
  34. package/dist/__tests__/asset-registry.unit.test.d.ts.map +1 -0
  35. package/dist/__tests__/asset.unit.test.d.ts +2 -0
  36. package/dist/__tests__/asset.unit.test.d.ts.map +1 -0
  37. package/dist/__tests__/audio-load-by-guid.unit.test.d.ts +2 -0
  38. package/dist/__tests__/audio-load-by-guid.unit.test.d.ts.map +1 -0
  39. package/dist/__tests__/backend-selection.integration.test.d.ts +2 -0
  40. package/dist/__tests__/backend-selection.integration.test.d.ts.map +1 -0
  41. package/dist/__tests__/basis-catalog-dispatch.integration.test.d.ts +2 -0
  42. package/dist/__tests__/basis-catalog-dispatch.integration.test.d.ts.map +1 -0
  43. package/dist/__tests__/builtin-asset-registry.unit.test.d.ts +2 -0
  44. package/dist/__tests__/builtin-asset-registry.unit.test.d.ts.map +1 -0
  45. package/dist/__tests__/collect-scene-asset.test.d.ts +1 -2
  46. package/dist/__tests__/collect-scene-asset.test.d.ts.map +1 -1
  47. package/dist/__tests__/collect-scene-mount-collapse.test.d.ts +2 -0
  48. package/dist/__tests__/collect-scene-mount-collapse.test.d.ts.map +1 -0
  49. package/dist/__tests__/collect-transient-roundtrip.test.d.ts +1 -1
  50. package/dist/__tests__/collect-transient-roundtrip.test.d.ts.map +1 -1
  51. package/dist/__tests__/collect-transient-skip.test.d.ts +1 -2
  52. package/dist/__tests__/collect-transient-skip.test.d.ts.map +1 -1
  53. package/dist/__tests__/compressed-texture-physical-extent.integration.test.d.ts +2 -0
  54. package/dist/__tests__/compressed-texture-physical-extent.integration.test.d.ts.map +1 -0
  55. package/dist/__tests__/dawn/mesh-update-dawn.test.d.ts +2 -0
  56. package/dist/__tests__/dawn/mesh-update-dawn.test.d.ts.map +1 -0
  57. package/dist/__tests__/dawn/upload-texture.dawn.test.d.ts +2 -0
  58. package/dist/__tests__/dawn/upload-texture.dawn.test.d.ts.map +1 -0
  59. package/dist/__tests__/draw-published.d.ts +2 -2
  60. package/dist/__tests__/draw-published.d.ts.map +1 -1
  61. package/dist/__tests__/dynamic-texture-store.unit.test.d.ts +2 -0
  62. package/dist/__tests__/dynamic-texture-store.unit.test.d.ts.map +1 -0
  63. package/dist/__tests__/errors.unit.test.d.ts +2 -0
  64. package/dist/__tests__/errors.unit.test.d.ts.map +1 -0
  65. package/dist/__tests__/extract-skin-mismatch.unit.test.d.ts +2 -0
  66. package/dist/__tests__/extract-skin-mismatch.unit.test.d.ts.map +1 -0
  67. package/dist/__tests__/fetch-binary-decompress.test.d.ts +2 -0
  68. package/dist/__tests__/fetch-binary-decompress.test.d.ts.map +1 -0
  69. package/dist/__tests__/four-path-compression.integration.test.d.ts +2 -0
  70. package/dist/__tests__/four-path-compression.integration.test.d.ts.map +1 -0
  71. package/dist/__tests__/fullscreen-feature-host.dawn.test.d.ts +2 -0
  72. package/dist/__tests__/fullscreen-feature-host.dawn.test.d.ts.map +1 -0
  73. package/dist/__tests__/guid-for-asset.unit.test.d.ts +2 -0
  74. package/dist/__tests__/guid-for-asset.unit.test.d.ts.map +1 -0
  75. package/dist/__tests__/handle-migration.test.d.ts +2 -0
  76. package/dist/__tests__/handle-migration.test.d.ts.map +1 -0
  77. package/dist/__tests__/helpers/register-runtime-components.d.ts.map +1 -1
  78. package/dist/__tests__/host-custom-kind-contract.test-d.d.ts +2 -0
  79. package/dist/__tests__/host-custom-kind-contract.test-d.d.ts.map +1 -0
  80. package/dist/__tests__/host-custom-kind-contract.test.d.ts +2 -0
  81. package/dist/__tests__/host-custom-kind-contract.test.d.ts.map +1 -0
  82. package/dist/__tests__/inspect-name.test.d.ts +2 -0
  83. package/dist/__tests__/inspect-name.test.d.ts.map +1 -0
  84. package/dist/__tests__/instantiate-mount-deferred-wiring.test.d.ts +2 -0
  85. package/dist/__tests__/instantiate-mount-deferred-wiring.test.d.ts.map +1 -0
  86. package/dist/__tests__/loadbyguid-payload.unit.test.d.ts +2 -0
  87. package/dist/__tests__/loadbyguid-payload.unit.test.d.ts.map +1 -0
  88. package/dist/__tests__/loadbyguid-texture-intern.unit.test.d.ts +2 -0
  89. package/dist/__tests__/loadbyguid-texture-intern.unit.test.d.ts.map +1 -0
  90. package/dist/__tests__/loader-extract-graceful.test.d.ts +2 -0
  91. package/dist/__tests__/loader-extract-graceful.test.d.ts.map +1 -0
  92. package/dist/__tests__/loader-name-survival.test.d.ts +2 -0
  93. package/dist/__tests__/loader-name-survival.test.d.ts.map +1 -0
  94. package/dist/__tests__/mesh-bin-contract.test.d.ts +2 -0
  95. package/dist/__tests__/mesh-bin-contract.test.d.ts.map +1 -0
  96. package/dist/__tests__/mesh-bin-skin-roundtrip.unit.test.d.ts +2 -0
  97. package/dist/__tests__/mesh-bin-skin-roundtrip.unit.test.d.ts.map +1 -0
  98. package/dist/__tests__/mesh-bin.test.d.ts +2 -0
  99. package/dist/__tests__/mesh-bin.test.d.ts.map +1 -0
  100. package/dist/__tests__/mesh-loader-skin-contract.unit.test.d.ts +2 -0
  101. package/dist/__tests__/mesh-loader-skin-contract.unit.test.d.ts.map +1 -0
  102. package/dist/__tests__/new-kind-refs-contract.test.d.ts +2 -0
  103. package/dist/__tests__/new-kind-refs-contract.test.d.ts.map +1 -0
  104. package/dist/__tests__/package-promotion.test.d.ts +2 -0
  105. package/dist/__tests__/package-promotion.test.d.ts.map +1 -0
  106. package/dist/__tests__/package-rename.test.d.ts +2 -0
  107. package/dist/__tests__/package-rename.test.d.ts.map +1 -0
  108. package/dist/__tests__/recover-error-exhaustive.test-d.d.ts +1 -1
  109. package/dist/__tests__/recover-error-exhaustive.test-d.d.ts.map +1 -1
  110. package/dist/__tests__/render-error-exhaustive.test-d.d.ts +1 -1
  111. package/dist/__tests__/render-error-exhaustive.test-d.d.ts.map +1 -1
  112. package/dist/__tests__/render-feature-prepared-graphics.fixture.d.ts +10 -0
  113. package/dist/__tests__/render-feature-prepared-graphics.fixture.d.ts.map +1 -0
  114. package/dist/__tests__/render-system-extract.unit.test.d.ts +2 -0
  115. package/dist/__tests__/render-system-extract.unit.test.d.ts.map +1 -0
  116. package/dist/__tests__/renderer-test-utils.d.ts +10 -0
  117. package/dist/__tests__/renderer-test-utils.d.ts.map +1 -0
  118. package/dist/__tests__/renderer.test-d.d.ts +2 -0
  119. package/dist/__tests__/renderer.test-d.d.ts.map +1 -0
  120. package/dist/__tests__/resolve-asset-handle-err.test.d.ts +2 -0
  121. package/dist/__tests__/resolve-asset-handle-err.test.d.ts.map +1 -0
  122. package/dist/__tests__/resolve-asset-handle.unit.test.d.ts +2 -0
  123. package/dist/__tests__/resolve-asset-handle.unit.test.d.ts.map +1 -0
  124. package/dist/__tests__/resolveName-fallback.test.d.ts +2 -0
  125. package/dist/__tests__/resolveName-fallback.test.d.ts.map +1 -0
  126. package/dist/__tests__/resolveName-null-package.test.d.ts +2 -0
  127. package/dist/__tests__/resolveName-null-package.test.d.ts.map +1 -0
  128. package/dist/__tests__/resolveName-unified-entry.test.d.ts +2 -0
  129. package/dist/__tests__/resolveName-unified-entry.test.d.ts.map +1 -0
  130. package/dist/__tests__/resolveName.test.d.ts +2 -0
  131. package/dist/__tests__/resolveName.test.d.ts.map +1 -0
  132. package/dist/__tests__/roots-to-scene-asset.test.d.ts +1 -1
  133. package/dist/__tests__/roots-to-scene-asset.test.d.ts.map +1 -1
  134. package/dist/__tests__/roundtrip-primitive.test.d.ts +2 -0
  135. package/dist/__tests__/roundtrip-primitive.test.d.ts.map +1 -0
  136. package/dist/__tests__/scene-bare-guid-refs-instantiate.test.d.ts +2 -0
  137. package/dist/__tests__/scene-bare-guid-refs-instantiate.test.d.ts.map +1 -0
  138. package/dist/__tests__/scene-instance-authoring.integration.test.d.ts +2 -0
  139. package/dist/__tests__/scene-instance-authoring.integration.test.d.ts.map +1 -0
  140. package/dist/__tests__/scene-mount-fixed-point.test.d.ts +2 -0
  141. package/dist/__tests__/scene-mount-fixed-point.test.d.ts.map +1 -0
  142. package/dist/__tests__/scene-mount-roundtrip.test.d.ts +2 -0
  143. package/dist/__tests__/scene-mount-roundtrip.test.d.ts.map +1 -0
  144. package/dist/__tests__/scene-mount-wrapper-roundtrip.test.d.ts +2 -0
  145. package/dist/__tests__/scene-mount-wrapper-roundtrip.test.d.ts.map +1 -0
  146. package/dist/__tests__/scene-sugar-instantiate.test.d.ts +2 -0
  147. package/dist/__tests__/scene-sugar-instantiate.test.d.ts.map +1 -0
  148. package/dist/__tests__/serialize-mounts-roundtrip.test.d.ts +2 -0
  149. package/dist/__tests__/serialize-mounts-roundtrip.test.d.ts.map +1 -0
  150. package/dist/__tests__/serialize-scene-asset.test.d.ts +1 -1
  151. package/dist/__tests__/serialize-scene-asset.test.d.ts.map +1 -1
  152. package/dist/__tests__/template-game-default-api-contract.test.d.ts +2 -0
  153. package/dist/__tests__/template-game-default-api-contract.test.d.ts.map +1 -0
  154. package/dist/__tests__/tileset-asset-validate.test.d.ts +2 -0
  155. package/dist/__tests__/tileset-asset-validate.test.d.ts.map +1 -0
  156. package/dist/__tests__/transcode-fallback.unit.test.d.ts +2 -0
  157. package/dist/__tests__/transcode-fallback.unit.test.d.ts.map +1 -0
  158. package/dist/__tests__/transient-runtime-behavior.test.d.ts +2 -0
  159. package/dist/__tests__/transient-runtime-behavior.test.d.ts.map +1 -0
  160. package/dist/__tests__/video-loader-consumption.test.d.ts +2 -0
  161. package/dist/__tests__/video-loader-consumption.test.d.ts.map +1 -0
  162. package/dist/__tests__/video-loader-smoke.dawn.test.d.ts +2 -0
  163. package/dist/__tests__/video-loader-smoke.dawn.test.d.ts.map +1 -0
  164. package/dist/backend-selection.d.ts +13 -0
  165. package/dist/backend-selection.d.ts.map +1 -0
  166. package/dist/collect-scene-asset.d.ts +3 -3
  167. package/dist/collect-scene-asset.d.ts.map +1 -1
  168. package/dist/createRenderer.d.ts +14 -2
  169. package/dist/createRenderer.d.ts.map +1 -1
  170. package/dist/errors/environment.d.ts +1 -1
  171. package/dist/errors/environment.d.ts.map +1 -1
  172. package/dist/index.d.ts +19 -81
  173. package/dist/index.d.ts.map +1 -1
  174. package/dist/index.mjs +105 -108
  175. package/dist/index.mjs.map +1 -1
  176. package/dist/renderer-host.d.ts +9 -0
  177. package/dist/renderer-host.d.ts.map +1 -0
  178. package/dist/renderer-host.mjs +62 -0
  179. package/dist/renderer-host.mjs.map +1 -0
  180. package/dist/scene-instances/index.d.ts +2 -0
  181. package/dist/scene-instances/index.d.ts.map +1 -0
  182. package/dist/scene-utils/mount-override-fold.d.ts +1 -2
  183. package/dist/scene-utils/mount-override-fold.d.ts.map +1 -1
  184. package/dist/systems/sprite-animation-tick.d.ts +1 -1
  185. package/dist/systems/sprite-animation-tick.d.ts.map +1 -1
  186. package/dist/systems/transparent-sort.d.ts +1 -2
  187. package/dist/systems/transparent-sort.d.ts.map +1 -1
  188. package/dist/tilemap-register-validate.d.ts.map +1 -1
  189. package/package.json +34 -33
  190. package/src/__tests__/active-camera.unit.test.ts +19 -9
  191. package/src/__tests__/animation-graph-collect-roundtrip.test.ts +213 -0
  192. package/src/__tests__/animation-graph-serialize.unit.test.ts +171 -0
  193. package/src/__tests__/append-injection.test.ts +1 -1
  194. package/src/__tests__/asset-brand-and-name-retirement.test.ts +102 -0
  195. package/src/__tests__/asset-error-exhaustive.test-d.ts +62 -0
  196. package/src/__tests__/asset-registry-guid-reverse.test.ts +575 -0
  197. package/src/__tests__/asset-registry-hdr-equirect.test.ts +78 -0
  198. package/src/__tests__/asset-registry-mesh-pack-payload.dawn.test.ts +232 -0
  199. package/src/__tests__/asset-registry-mounts.test.ts +806 -0
  200. package/src/__tests__/asset-registry.browser.test.ts +81 -0
  201. package/src/__tests__/asset-registry.dawn.test.ts +94 -0
  202. package/src/__tests__/asset-registry.listCatalog.test.ts +170 -0
  203. package/src/__tests__/asset-registry.mesh-bin.test.ts +316 -0
  204. package/src/__tests__/asset-registry.pack-cache.test.ts +969 -0
  205. package/src/__tests__/asset-registry.raw-container-failfast.test.ts +225 -0
  206. package/src/__tests__/asset-registry.recursive.spec.ts +1397 -0
  207. package/src/__tests__/asset-registry.unit.test.ts +1030 -0
  208. package/src/__tests__/asset.unit.test.ts +7107 -0
  209. package/src/__tests__/audio-load-by-guid.unit.test.ts +126 -0
  210. package/src/__tests__/backend-selection.integration.test.ts +11 -0
  211. package/src/__tests__/basis-catalog-dispatch.integration.test.ts +320 -0
  212. package/src/__tests__/bind-group-cache-keying.test.ts +4 -4
  213. package/src/__tests__/block-upload-math.unit.test.ts +2 -2
  214. package/src/__tests__/builtin-asset-registry.unit.test.ts +112 -0
  215. package/src/__tests__/builtin-shader-register-e2e.test.ts +1 -1
  216. package/src/__tests__/cache-false-eviction.test.ts +2 -1
  217. package/src/__tests__/cache-isolation-matrix.test.ts +2 -1
  218. package/src/__tests__/camera-clear-snapshot-equivalence.unit.test.ts +5 -6
  219. package/src/__tests__/clamp-to-last.e2e.browser.test.ts +29 -19
  220. package/src/__tests__/collect-scene-asset.test.ts +49 -52
  221. package/src/__tests__/collect-scene-mount-collapse.test.ts +391 -0
  222. package/src/__tests__/collect-subtree.unit.test.ts +1 -2
  223. package/src/__tests__/collect-transient-children-absent.test.ts +24 -10
  224. package/src/__tests__/collect-transient-roundtrip.test.ts +44 -20
  225. package/src/__tests__/collect-transient-skip.test.ts +24 -13
  226. package/src/__tests__/components.test-d.ts +1 -6
  227. package/src/__tests__/components.unit.test.ts +20 -19
  228. package/src/__tests__/composite-skybox-cross-world.browser.test.ts +59 -27
  229. package/src/__tests__/compressed-texture-physical-extent.integration.test.ts +139 -0
  230. package/src/__tests__/create-renderer-assembly.integration.test.ts +42 -29
  231. package/src/__tests__/createRenderer-dispose.test.ts +35 -402
  232. package/src/__tests__/createRenderer.browser-no-webgpu.test.ts +25 -30
  233. package/src/__tests__/createRenderer.unit.test.ts +1 -1
  234. package/src/__tests__/dawn/hello-sprite-nineslice-section.dawn.test.ts +27 -63
  235. package/src/__tests__/dawn/ibl-precompute-readback.dawn.test.ts +56 -47
  236. package/src/__tests__/dawn/instances-per-instance-pbr.dawn.test.ts +49 -29
  237. package/src/__tests__/dawn/instances-shadow.dawn.test.ts +26 -15
  238. package/src/__tests__/dawn/instances-uniform-fallback.dawn.test.ts +13 -14
  239. package/src/__tests__/dawn/material-alpha.dawn.test.ts +23 -31
  240. package/src/__tests__/dawn/material-cooked-fixture.dawn.test.ts +0 -18
  241. package/src/__tests__/dawn/{mesh-update.dawn.test.ts → mesh-update-dawn.test.ts} +42 -134
  242. package/src/__tests__/dawn/mipmap-srgb-linear.dawn.test.ts +14 -7
  243. package/src/__tests__/dawn/per-entity-material-texture-isolation.dawn.test.ts +16 -28
  244. package/src/__tests__/dawn/sprite-nineslice-mesh-bind.dawn.test.ts +23 -39
  245. package/src/__tests__/dawn/upload-texture.dawn.test.ts +198 -0
  246. package/src/__tests__/dawn/user-handle-mesh-render.dawn.test.ts +12 -14
  247. package/src/__tests__/dawn/user-mesh-upload.dawn.test.ts +27 -22
  248. package/src/__tests__/dawn/zero-manifest-mesh-fail.dawn.test.ts +25 -28
  249. package/src/__tests__/dawn/zero-manifest-ready.dawn.test.ts +10 -11
  250. package/src/__tests__/demo-sortscope-migration.unit.test.ts +5 -5
  251. package/src/__tests__/derive-bgl-integration.test.ts +34 -44
  252. package/src/__tests__/derive-render-data-skin.unit.test.ts +1 -1
  253. package/src/__tests__/draw-published.ts +11 -4
  254. package/src/__tests__/dynamic-texture-store.unit.test.ts +190 -0
  255. package/src/__tests__/equirect-bc6h.integration.test.ts +144 -21
  256. package/src/__tests__/errors.unit.test.ts +1203 -0
  257. package/src/__tests__/extract-frames-graceful-degradation.test.ts +3 -7
  258. package/src/__tests__/extract-frames-merge.test.ts +35 -22
  259. package/src/__tests__/extract-record-no-hardcoded-texture-fields.test.ts +5 -16
  260. package/src/__tests__/extract-skin-mismatch.unit.test.ts +322 -0
  261. package/src/__tests__/fetch-binary-decompress.test.ts +356 -0
  262. package/src/__tests__/four-path-compression.integration.test.ts +395 -0
  263. package/src/__tests__/frame-targets-shadow-regression.unit.test.ts +1 -1
  264. package/src/__tests__/fullscreen-feature-host.dawn.test.ts +80 -0
  265. package/src/__tests__/fullscreen-post-bgl-depth.test.ts +4 -2
  266. package/src/__tests__/fullscreen-post-depth-params-arity.test.ts +3 -3
  267. package/src/__tests__/fullscreen-post-process-pass.dawn.test.ts +39 -23
  268. package/src/__tests__/fullscreen-post-process-pass.unit.test.ts +4 -2
  269. package/src/__tests__/fxaa-pixel-diff.dawn.test.ts +28 -17
  270. package/src/__tests__/fxaa-validation-and-resize.dawn.test.ts +29 -18
  271. package/src/__tests__/fxaa-zero-overhead.dawn.test.ts +16 -12
  272. package/src/__tests__/geometry.unit.test.ts +525 -159
  273. package/src/__tests__/glyph-tilemap-worldid.test.ts +1 -1
  274. package/src/__tests__/gpu-resource-cow-survivor.test.ts +6 -4
  275. package/src/__tests__/guid-for-asset.unit.test.ts +102 -0
  276. package/src/__tests__/handle-migration.test.ts +136 -0
  277. package/src/__tests__/helpers/register-runtime-components.ts +4 -2
  278. package/src/__tests__/helpers/register-scene-components.ts +1 -1
  279. package/src/__tests__/host-custom-kind-contract.test-d.ts +47 -0
  280. package/src/__tests__/host-custom-kind-contract.test.ts +578 -0
  281. package/src/__tests__/inspect-name.test.ts +139 -0
  282. package/src/__tests__/instances.test-d.ts +1 -1
  283. package/src/__tests__/instantiate-mount-deferred-wiring.test.ts +112 -0
  284. package/src/__tests__/light-casters-9-light.browser.test.ts +73 -76
  285. package/src/__tests__/light-gpu-byte-neutral.unit.test.ts +7 -10
  286. package/src/__tests__/light-snapshot.test-d.ts +2 -2
  287. package/src/__tests__/lights-vec-negative.unit.test.ts +1 -1
  288. package/src/__tests__/lights.unit.test.ts +16 -500
  289. package/src/__tests__/loadbyguid-payload.unit.test.ts +117 -0
  290. package/src/__tests__/loadbyguid-texture-intern.unit.test.ts +213 -0
  291. package/src/__tests__/loader-extract-graceful.test.ts +146 -0
  292. package/src/__tests__/loader-name-survival.test.ts +213 -0
  293. package/src/__tests__/m3-vec-negative.unit.test.ts +3 -2
  294. package/src/__tests__/material-texture-uv-scale.unit.test.ts +101 -31
  295. package/src/__tests__/materials.unit.test.ts +10 -27
  296. package/src/__tests__/mesh-bin-contract.test.ts +28 -0
  297. package/src/__tests__/mesh-bin-skin-roundtrip.unit.test.ts +149 -0
  298. package/src/__tests__/mesh-bin.test.ts +38 -0
  299. package/src/__tests__/mesh-loader-skin-contract.unit.test.ts +120 -0
  300. package/src/__tests__/mesh-ssbo-grow.unit.test.ts +3 -3
  301. package/src/__tests__/mip-gate.unit.test.ts +1 -1
  302. package/src/__tests__/msaa-sprite-pixel-diff.dawn.test.ts +29 -68
  303. package/src/__tests__/new-kind-refs-contract.test.ts +132 -0
  304. package/src/__tests__/node-shims.d.ts +4 -6
  305. package/src/__tests__/package-promotion.test.ts +88 -0
  306. package/src/__tests__/package-rename.test.ts +103 -0
  307. package/src/__tests__/pass-selector.unit.test.ts +2 -2
  308. package/src/__tests__/pbr-pipeline.unit.test.ts +14 -21
  309. package/src/__tests__/pipeline-builder-msaa.unit.test.ts +6 -9
  310. package/src/__tests__/pipeline-cache-keying.unit.test.ts +6 -9
  311. package/src/__tests__/pipeline-spec.test.ts +16 -177
  312. package/src/__tests__/pipeline.unit.test.ts +154 -1693
  313. package/src/__tests__/point-light-shadow.dawn.test.ts +33 -42
  314. package/src/__tests__/point-light-shadow.unit.test.ts +19 -60
  315. package/src/__tests__/post-process-error-codes.unit.test.ts +4 -1
  316. package/src/__tests__/post-process-params-component.unit.test.ts +1 -1
  317. package/src/__tests__/post-process-params-extract.unit.test.ts +2 -5
  318. package/src/__tests__/postprocess-camera-consistency.test.ts +4 -7
  319. package/src/__tests__/profiler-assembly.integration.test.ts +1 -1
  320. package/src/__tests__/propagate-transforms.dawn.test.ts +12 -11
  321. package/src/__tests__/record-worldid-isolation.test.ts +7 -29
  322. package/src/__tests__/recover-error-exhaustive.test-d.ts +1 -1
  323. package/src/__tests__/render-error-exhaustive.test-d.ts +81 -71
  324. package/src/__tests__/render-feature-assembly.test-d.ts +20 -9
  325. package/src/__tests__/render-feature-prepared-graphics-docs.unit.test.ts +8 -6
  326. package/src/__tests__/render-feature-prepared-graphics.browser.test.ts +60 -558
  327. package/src/__tests__/render-feature-prepared-graphics.dawn.test.ts +57 -544
  328. package/src/__tests__/render-feature-prepared-graphics.fixture.ts +104 -0
  329. package/src/__tests__/render-feature-prepared-graphics.integration.test.ts +40 -248
  330. package/src/__tests__/render-feature-prepared-graphics.regression.integration.test.ts +83 -340
  331. package/src/__tests__/render-feature-recover.integration.test.ts +9 -49
  332. package/src/__tests__/render-feature-runtime-surface.test-d.ts +17 -20
  333. package/src/__tests__/render-schema-consumer.integration.test.ts +20 -13
  334. package/src/__tests__/render-schema-owner-boundary.unit.test.ts +2 -6
  335. package/src/__tests__/render-system-cross-world-overlay-queue.test.ts +5 -5
  336. package/src/__tests__/render-system-extract-dispatch-ordering.test.ts +16 -31
  337. package/src/__tests__/render-system-extract.test.ts +36 -51
  338. package/src/__tests__/render-system-extract.unit.test.ts +360 -0
  339. package/src/__tests__/render-system-fold-bucket.unit.test.ts +3 -5
  340. package/src/__tests__/render-system-fold-fallback.unit.test.ts +6 -3
  341. package/src/__tests__/render-system-fold-material.unit.test.ts +3 -5
  342. package/src/__tests__/render-system-fold-metrics.unit.test.ts +5 -5
  343. package/src/__tests__/render-system-fold-modegate.unit.test.ts +6 -6
  344. package/src/__tests__/render-system-fold.dawn.test.ts +7 -5
  345. package/src/__tests__/render-system-mega.test.ts +292 -190
  346. package/src/__tests__/render-system-owner-split-contract.test.ts +10 -32
  347. package/src/__tests__/render-system-record-multi-material-textureview.test.ts +59 -45
  348. package/src/__tests__/render-system-record-per-submesh-transparency.test.ts +23 -29
  349. package/src/__tests__/render-system-record.test.ts +398 -235
  350. package/src/__tests__/render-system-record.unit.test.ts +25 -26
  351. package/src/__tests__/render-system-skin-bg.unit.test.ts +8 -12
  352. package/src/__tests__/renderer-consumer.test-d.ts +16 -3
  353. package/src/__tests__/renderer-health.unit.test.ts +26 -916
  354. package/src/__tests__/renderer-lifecycle.integration.test.ts +19 -6
  355. package/src/__tests__/renderer-recover.unit.test.ts +49 -1069
  356. package/src/__tests__/renderer-result.test-d.ts +19 -9
  357. package/src/__tests__/renderer-surface.unit.test.ts +3 -5
  358. package/src/__tests__/renderer-test-utils.ts +56 -0
  359. package/src/__tests__/renderer.test-d.ts +59 -0
  360. package/src/__tests__/resolve-asset-handle-err.test.ts +111 -0
  361. package/src/__tests__/resolve-asset-handle.unit.test.ts +64 -0
  362. package/src/__tests__/resolve-depth-only-view.test.ts +1 -1
  363. package/src/__tests__/resolveName-fallback.test.ts +64 -0
  364. package/src/__tests__/resolveName-null-package.test.ts +38 -0
  365. package/src/__tests__/resolveName-unified-entry.test.ts +65 -0
  366. package/src/__tests__/resolveName.test.ts +64 -0
  367. package/src/__tests__/rhi-null-command-flow.unit.test.ts +43 -261
  368. package/src/__tests__/rhi-null-renderer-lifecycle.unit.test.ts +41 -169
  369. package/src/__tests__/roots-to-scene-asset.test.ts +199 -93
  370. package/src/__tests__/roundtrip-primitive.test.ts +351 -0
  371. package/src/__tests__/scene-bare-guid-refs-instantiate.test.ts +123 -0
  372. package/src/__tests__/scene-equirect-roundtrip.test.ts +103 -16
  373. package/src/__tests__/scene-instance-authoring.integration.test.ts +8 -0
  374. package/src/__tests__/scene-instance-bridge.integration.test.ts +1 -1
  375. package/src/__tests__/scene-instance-component.test.ts +1 -1
  376. package/src/__tests__/scene-mount-fixed-point.test.ts +257 -0
  377. package/src/__tests__/scene-mount-roundtrip.test.ts +987 -0
  378. package/src/__tests__/scene-mount-wrapper-roundtrip.test.ts +202 -0
  379. package/src/__tests__/scene-sugar-instantiate.test.ts +324 -0
  380. package/src/__tests__/serialize-mounts-roundtrip.test.ts +533 -0
  381. package/src/__tests__/serialize-scene-asset.test.ts +219 -22
  382. package/src/__tests__/shadow-caster-empty-schema.test.ts +3 -3
  383. package/src/__tests__/shadow-csm-cascade-loadop.test.ts +37 -17
  384. package/src/__tests__/shadow-csm-component.test.ts +3 -5
  385. package/src/__tests__/shadow-csm-extract.test.ts +2 -100
  386. package/src/__tests__/shadow-csm-orthoz.test.ts +2 -16
  387. package/src/__tests__/shadow-csm-runtime-vary.dawn.test.ts +19 -14
  388. package/src/__tests__/shadow-csm-tile-consistency.test.ts +32 -26
  389. package/src/__tests__/shadow-csm-ubo.dawn.test.ts +8 -49
  390. package/src/__tests__/shadow-csm-ubo.test.ts +3 -25
  391. package/src/__tests__/shadow-csm-viewport.browser.test.ts +1 -1
  392. package/src/__tests__/shadow-fields-observable.dawn.test.ts +67 -56
  393. package/src/__tests__/shadow-m1.dawn.test.ts +8 -9
  394. package/src/__tests__/shadow-mesh-ssbo-order.test.ts +11 -27
  395. package/src/__tests__/skin-errors.unit.test.ts +1 -1
  396. package/src/__tests__/skin-extract-getarrayview-count.unit.test.ts +7 -5
  397. package/src/__tests__/skylight-lazy-projection.test.ts +36 -15
  398. package/src/__tests__/sparse-tag-scene-roundtrip.test.ts +5 -5
  399. package/src/__tests__/sprite-cullmode-flip.dawn.test.ts +47 -64
  400. package/src/__tests__/sprite-lit-bgl-byte-identical.test.ts +12 -11
  401. package/src/__tests__/sprite-lit-extract-branch.test.ts +1 -1
  402. package/src/__tests__/sprite-lit-pipeline-cache-key.test.ts +1 -1
  403. package/src/__tests__/ssao-bgl.test.ts +16 -9
  404. package/src/__tests__/ssao-buffers.test.ts +2 -2
  405. package/src/__tests__/ssao-data.test.ts +2 -2
  406. package/src/__tests__/ssao-errors.test.ts +1 -1
  407. package/src/__tests__/ssao-passes.test.ts +64 -392
  408. package/src/__tests__/ssao-pipelines.test.ts +1 -1
  409. package/src/__tests__/ssao-uniform-layout.test.ts +8 -6
  410. package/src/__tests__/stencil-outline-pixel.dawn.test.ts +25 -17
  411. package/src/__tests__/swap-chain-format.unit.test.ts +5 -7
  412. package/src/__tests__/systems.unit.test.ts +536 -1326
  413. package/src/__tests__/template-game-default-api-contract.test.ts +362 -0
  414. package/src/__tests__/text.unit.test.ts +56 -33
  415. package/src/__tests__/tilemap-childed-despawn.test.ts +8 -14
  416. package/src/__tests__/tilemap-chunk-extract.overhang-bounds.test.ts +8 -12
  417. package/src/__tests__/tilemap-chunk-extract.propagate-order.test.ts +2 -1
  418. package/src/__tests__/tilemap-chunk-extract.test.ts +13 -17
  419. package/src/__tests__/tilemap-dirty-rebuild.test.ts +7 -11
  420. package/src/__tests__/tilemap-material-cache.test.ts +8 -13
  421. package/src/__tests__/tilemap-multi-atlas.test.ts +12 -32
  422. package/src/__tests__/tilemap-owner-boundary.unit.test.ts +5 -2
  423. package/src/__tests__/tilemap-region-pack.test.ts +8 -12
  424. package/src/__tests__/tilemap-spawn-flip-pivot.test.ts +8 -12
  425. package/src/__tests__/tilemap-uv-inset.test.ts +11 -14
  426. package/src/__tests__/tilemap-validate.test.ts +1 -1
  427. package/src/__tests__/tileset-asset-validate.test.ts +638 -0
  428. package/src/__tests__/transcode-fallback.unit.test.ts +207 -0
  429. package/src/__tests__/transform-hierarchy-pixel-diff.dawn.test.ts +36 -28
  430. package/src/__tests__/transient-fields-collect.test.ts +28 -21
  431. package/src/__tests__/transient-runtime-behavior.test.ts +227 -0
  432. package/src/__tests__/transparent-sort-tilemap-sprite-interleave.test.ts +4 -4
  433. package/src/__tests__/variant-selection.unit.test.ts +1 -1
  434. package/src/__tests__/video-extract-bindgroup.dawn.test.ts +89 -136
  435. package/src/__tests__/video-loader-consumption.test.ts +86 -0
  436. package/src/__tests__/video-loader-smoke.dawn.test.ts +60 -0
  437. package/src/__tests__/view-ubo-layout.browser.test.ts +0 -22
  438. package/src/__tests__/world-entity-key.test.ts +1 -1
  439. package/src/__tests__/world-scene-despawn.test.ts +1 -1
  440. package/src/__tests__/world-scene-instantiate.test.ts +2 -36
  441. package/src/__tests__/world-scene-nested.test.ts +1 -1
  442. package/src/__tests__/world-scene-override.test.ts +1 -1
  443. package/src/backend-selection.ts +69 -0
  444. package/src/collect-scene-asset.ts +28 -23
  445. package/src/components/__tests__/camera.test-d.ts +1 -1
  446. package/src/components/__tests__/camera.test.ts +1 -1
  447. package/src/components/__tests__/sprite-animation.test-d.ts +2 -2
  448. package/src/components/__tests__/tile-layer.test-d.ts +1 -1
  449. package/src/components/__tests__/tile-layer.unit.test.ts +2 -2
  450. package/src/createRenderer.ts +24 -36
  451. package/src/errors/environment.ts +1 -1
  452. package/src/index.ts +47 -113
  453. package/src/renderer-host.ts +33 -0
  454. package/src/scene-instances/__tests__/post-spawn-resolve-joints.unit.test.ts +1 -1
  455. package/src/scene-instances/index.ts +4 -0
  456. package/src/scene-utils/mount-override-fold.ts +3 -7
  457. package/src/systems/__tests__/transparent-sort.bench.ts +3 -3
  458. package/src/systems/sprite-animation-tick.ts +1 -1
  459. package/src/systems/transparent-sort.ts +38 -38
  460. package/src/tilemap-register-validate.ts +4 -4
  461. package/dist/__tests__/bind-group-cache-binding.test.d.ts +0 -2
  462. package/dist/__tests__/bind-group-cache-binding.test.d.ts.map +0 -1
  463. package/dist/__tests__/bind-group-cache-frame.test.d.ts +0 -2
  464. package/dist/__tests__/bind-group-cache-frame.test.d.ts.map +0 -1
  465. package/dist/__tests__/dawn/mesh-update.dawn.test.d.ts +0 -2
  466. package/dist/__tests__/dawn/mesh-update.dawn.test.d.ts.map +0 -1
  467. package/dist/__tests__/dispatch-fullscreen-pass-composite-swapchain.dawn.test.d.ts +0 -2
  468. package/dist/__tests__/dispatch-fullscreen-pass-composite-swapchain.dawn.test.d.ts.map +0 -1
  469. package/dist/__tests__/dispatch-fullscreen-pass-custom-reads.dawn.test.d.ts +0 -2
  470. package/dist/__tests__/dispatch-fullscreen-pass-custom-reads.dawn.test.d.ts.map +0 -1
  471. package/dist/__tests__/dispatch-fullscreen-pass-depth-composite.dawn.test.d.ts +0 -2
  472. package/dist/__tests__/dispatch-fullscreen-pass-depth-composite.dawn.test.d.ts.map +0 -1
  473. package/dist/__tests__/dispatch-fullscreen-pass-params.unit.test.d.ts +0 -2
  474. package/dist/__tests__/dispatch-fullscreen-pass-params.unit.test.d.ts.map +0 -1
  475. package/dist/__tests__/fog-producer-manifest.d.ts +0 -131
  476. package/dist/__tests__/fog-producer-manifest.d.ts.map +0 -1
  477. package/dist/__tests__/fog-producer-pixel-probe.d.ts +0 -42
  478. package/dist/__tests__/fog-producer-pixel-probe.d.ts.map +0 -1
  479. package/dist/__tests__/fog-producer-pixel.browser.test.d.ts +0 -2
  480. package/dist/__tests__/fog-producer-pixel.browser.test.d.ts.map +0 -1
  481. package/dist/__tests__/fog-producer-pixel.dawn.test.d.ts +0 -2
  482. package/dist/__tests__/fog-producer-pixel.dawn.test.d.ts.map +0 -1
  483. package/dist/__tests__/fog-producer-real-fixture.d.ts +0 -5
  484. package/dist/__tests__/fog-producer-real-fixture.d.ts.map +0 -1
  485. package/dist/__tests__/fog-producer-vfx-effect.d.ts +0 -3
  486. package/dist/__tests__/fog-producer-vfx-effect.d.ts.map +0 -1
  487. package/dist/__tests__/fog-scene-asset.integration.test.d.ts +0 -2
  488. package/dist/__tests__/fog-scene-asset.integration.test.d.ts.map +0 -1
  489. package/dist/__tests__/gpu-resource-store-cubemap-status.test.d.ts +0 -2
  490. package/dist/__tests__/gpu-resource-store-cubemap-status.test.d.ts.map +0 -1
  491. package/dist/__tests__/gpu-resource.test.d.ts +0 -2
  492. package/dist/__tests__/gpu-resource.test.d.ts.map +0 -1
  493. package/dist/__tests__/hdrp-bgl-slots.browser.test.d.ts +0 -2
  494. package/dist/__tests__/hdrp-bgl-slots.browser.test.d.ts.map +0 -1
  495. package/dist/__tests__/hdrp-buffers.unit.test.d.ts +0 -2
  496. package/dist/__tests__/hdrp-buffers.unit.test.d.ts.map +0 -1
  497. package/dist/__tests__/hdrp-execute-filter.unit.test.d.ts +0 -2
  498. package/dist/__tests__/hdrp-execute-filter.unit.test.d.ts.map +0 -1
  499. package/dist/__tests__/hdrp-gbuffer-attachments.browser.test.d.ts +0 -2
  500. package/dist/__tests__/hdrp-gbuffer-attachments.browser.test.d.ts.map +0 -1
  501. package/dist/__tests__/hdrp-pipeline-asset-type.test-d.d.ts +0 -2
  502. package/dist/__tests__/hdrp-pipeline-asset-type.test-d.d.ts.map +0 -1
  503. package/dist/__tests__/hdrp-ssao-boundary.test.d.ts +0 -2
  504. package/dist/__tests__/hdrp-ssao-boundary.test.d.ts.map +0 -1
  505. package/dist/__tests__/hdrp-ssao-falsification.test.d.ts +0 -2
  506. package/dist/__tests__/hdrp-ssao-falsification.test.d.ts.map +0 -1
  507. package/dist/__tests__/helpers/primitive-world.d.ts +0 -8
  508. package/dist/__tests__/helpers/primitive-world.d.ts.map +0 -1
  509. package/dist/__tests__/helpers/render-asset-port.d.ts +0 -15
  510. package/dist/__tests__/helpers/render-asset-port.d.ts.map +0 -1
  511. package/dist/__tests__/helpers/scene-asset-port.d.ts +0 -9
  512. package/dist/__tests__/helpers/scene-asset-port.d.ts.map +0 -1
  513. package/dist/__tests__/material-derived-coordinates.integration.test.d.ts +0 -2
  514. package/dist/__tests__/material-derived-coordinates.integration.test.d.ts.map +0 -1
  515. package/dist/__tests__/pipeline-layout-selection.test.d.ts +0 -2
  516. package/dist/__tests__/pipeline-layout-selection.test.d.ts.map +0 -1
  517. package/dist/__tests__/post-process-reads-narrowing.test-d.d.ts +0 -2
  518. package/dist/__tests__/post-process-reads-narrowing.test-d.d.ts.map +0 -1
  519. package/dist/__tests__/post-process-register-roundtrip.dawn.test.d.ts +0 -2
  520. package/dist/__tests__/post-process-register-roundtrip.dawn.test.d.ts.map +0 -1
  521. package/dist/__tests__/render-feature-zero-feature.browser.test.d.ts +0 -2
  522. package/dist/__tests__/render-feature-zero-feature.browser.test.d.ts.map +0 -1
  523. package/dist/__tests__/render-pipeline-trivial.dawn.test.d.ts +0 -2
  524. package/dist/__tests__/render-pipeline-trivial.dawn.test.d.ts.map +0 -1
  525. package/dist/__tests__/shadow-csm-caster-membership.test.d.ts +0 -2
  526. package/dist/__tests__/shadow-csm-caster-membership.test.d.ts.map +0 -1
  527. package/dist/__tests__/shadow-csm-pssm.test.d.ts +0 -2
  528. package/dist/__tests__/shadow-csm-pssm.test.d.ts.map +0 -1
  529. package/dist/__tests__/shadow-csm-temporal.browser.test.d.ts +0 -2
  530. package/dist/__tests__/shadow-csm-temporal.browser.test.d.ts.map +0 -1
  531. package/dist/__tests__/shadow-csm-viewport.test.d.ts +0 -2
  532. package/dist/__tests__/shadow-csm-viewport.test.d.ts.map +0 -1
  533. package/dist/__tests__/shadow-m2.dawn.test.d.ts +0 -2
  534. package/dist/__tests__/shadow-m2.dawn.test.d.ts.map +0 -1
  535. package/dist/__tests__/shadow-m3-calibrate-run.dawn.test.d.ts +0 -2
  536. package/dist/__tests__/shadow-m3-calibrate-run.dawn.test.d.ts.map +0 -1
  537. package/dist/__tests__/shadow-m3-calibrate.d.ts +0 -83
  538. package/dist/__tests__/shadow-m3-calibrate.d.ts.map +0 -1
  539. package/dist/__tests__/shadow-m3.dawn.test.d.ts +0 -2
  540. package/dist/__tests__/shadow-m3.dawn.test.d.ts.map +0 -1
  541. package/dist/__tests__/shadow-probe-control-flow.dawn.test.d.ts +0 -2
  542. package/dist/__tests__/shadow-probe-control-flow.dawn.test.d.ts.map +0 -1
  543. package/dist/__tests__/shadow-quality-metrics.dawn.test.d.ts +0 -2
  544. package/dist/__tests__/shadow-quality-metrics.dawn.test.d.ts.map +0 -1
  545. package/dist/__tests__/temporal-off-path.unit.test.d.ts +0 -2
  546. package/dist/__tests__/temporal-off-path.unit.test.d.ts.map +0 -1
  547. package/dist/__tests__/video-cache-regression.unit.test.d.ts +0 -2
  548. package/dist/__tests__/video-cache-regression.unit.test.d.ts.map +0 -1
  549. package/dist/asset-kind.d.ts +0 -4
  550. package/dist/asset-kind.d.ts.map +0 -1
  551. package/dist/errors/sprite-animation.d.ts +0 -3
  552. package/dist/errors/sprite-animation.d.ts.map +0 -1
  553. package/dist/scene-asset-port.d.ts +0 -17
  554. package/dist/scene-asset-port.d.ts.map +0 -1
  555. package/dist/scene-collect-errors.d.ts +0 -22
  556. package/dist/scene-collect-errors.d.ts.map +0 -1
  557. package/dist/shadow-m3-calibrate.d.ts +0 -40
  558. package/dist/shadow-m3-calibrate.d.ts.map +0 -1
  559. package/src/__tests__/bind-group-cache-binding.test.ts +0 -2513
  560. package/src/__tests__/bind-group-cache-frame.test.ts +0 -1511
  561. package/src/__tests__/dispatch-fullscreen-pass-composite-swapchain.dawn.test.ts +0 -204
  562. package/src/__tests__/dispatch-fullscreen-pass-custom-reads.dawn.test.ts +0 -297
  563. package/src/__tests__/dispatch-fullscreen-pass-depth-composite.dawn.test.ts +0 -271
  564. package/src/__tests__/dispatch-fullscreen-pass-params.unit.test.ts +0 -321
  565. package/src/__tests__/fog-producer-manifest.ts +0 -162
  566. package/src/__tests__/fog-producer-pixel-probe.ts +0 -263
  567. package/src/__tests__/fog-producer-pixel.browser.test.ts +0 -26
  568. package/src/__tests__/fog-producer-pixel.dawn.test.ts +0 -55
  569. package/src/__tests__/fog-producer-real-fixture.ts +0 -805
  570. package/src/__tests__/fog-producer-vfx-effect.ts +0 -272
  571. package/src/__tests__/fog-scene-asset.integration.test.ts +0 -123
  572. package/src/__tests__/gpu-resource-store-cubemap-status.test.ts +0 -207
  573. package/src/__tests__/gpu-resource.test.ts +0 -1206
  574. package/src/__tests__/hdrp-bgl-slots.browser.test.ts +0 -50
  575. package/src/__tests__/hdrp-buffers.unit.test.ts +0 -70
  576. package/src/__tests__/hdrp-execute-filter.unit.test.ts +0 -200
  577. package/src/__tests__/hdrp-gbuffer-attachments.browser.test.ts +0 -64
  578. package/src/__tests__/hdrp-pipeline-asset-type.test-d.ts +0 -139
  579. package/src/__tests__/hdrp-ssao-boundary.test.ts +0 -237
  580. package/src/__tests__/hdrp-ssao-falsification.test.ts +0 -289
  581. package/src/__tests__/helpers/primitive-world.ts +0 -91
  582. package/src/__tests__/helpers/render-asset-port.ts +0 -65
  583. package/src/__tests__/helpers/scene-asset-port.ts +0 -23
  584. package/src/__tests__/material-derived-coordinates.integration.test.ts +0 -100
  585. package/src/__tests__/pipeline-layout-selection.test.ts +0 -298
  586. package/src/__tests__/post-process-reads-narrowing.test-d.ts +0 -52
  587. package/src/__tests__/post-process-register-roundtrip.dawn.test.ts +0 -230
  588. package/src/__tests__/render-feature-zero-feature.browser.test.ts +0 -152
  589. package/src/__tests__/render-pipeline-trivial.dawn.test.ts +0 -525
  590. package/src/__tests__/shadow-csm-caster-membership.test.ts +0 -232
  591. package/src/__tests__/shadow-csm-pssm.test.ts +0 -142
  592. package/src/__tests__/shadow-csm-temporal.browser.test.ts +0 -145
  593. package/src/__tests__/shadow-csm-viewport.test.ts +0 -74
  594. package/src/__tests__/shadow-m2.dawn.test.ts +0 -394
  595. package/src/__tests__/shadow-m3-calibrate-run.dawn.test.ts +0 -248
  596. package/src/__tests__/shadow-m3-calibrate.ts +0 -203
  597. package/src/__tests__/shadow-m3.dawn.test.ts +0 -288
  598. package/src/__tests__/shadow-probe-control-flow.dawn.test.ts +0 -264
  599. package/src/__tests__/shadow-quality-metrics.dawn.test.ts +0 -324
  600. package/src/__tests__/temporal-off-path.unit.test.ts +0 -69
  601. package/src/__tests__/video-cache-regression.unit.test.ts +0 -186
  602. package/src/asset-kind.ts +0 -7
  603. package/src/errors/sprite-animation.ts +0 -5
  604. package/src/scene-asset-port.ts +0 -32
  605. package/src/scene-collect-errors.ts +0 -30
  606. package/src/shadow-m3-calibrate.ts +0 -171
@@ -1,394 +0,0 @@
1
- // shadow-m2.dawn.test.ts - feat-20260520-directional-light-shadow-mapping
2
- // M2 / w12+fix: AC-12 naive shadow factor sampling, fixture with occluder
3
- // cube above ground plane, acne expected as M2 baseline artifact.
4
- //
5
- // AC anchor: requirements AC-12 (shadow factor < 1 for occluded, approx 1
6
- // for non-occluded, acne presence as M2 expected artifact). plan-strategy
7
- // D-6 (M2 red-green gate), research F3 (ShadowCalculation 5 steps, acne is
8
- // contractual).
9
- //
10
- // Fixture: single DirectionalLight pointing straight down + ground plane at
11
- // y=0 + cube occluder centred at y=1.3 (1x1x1). Shadow factor is sampled
12
- // via renderer.debugSampleShadowFactor which reads the GPU shadow depth
13
- // texture (copyTextureToBuffer + mapAsync) and computes the projection +
14
- // depth comparison on the CPU.
15
- //
16
- // The test reads the pre-built hello-triangle shader manifest (with real
17
- // composed WGSL for pbr + unlit + tonemap + shadow_caster) so dawn-node's
18
- // real WebGPU device can compile the shadow pipeline and populate the
19
- // shadow depth texture on the first draw() call.
20
-
21
- import { readFileSync } from 'node:fs';
22
- import { resolve } from 'node:path';
23
- import { fileURLToPath } from 'node:url';
24
- import { World } from '@forgeax/engine-ecs';
25
- import { createPrimitiveMesh } from '@forgeax/engine-geometry';
26
- import {
27
- Camera,
28
- DirectionalLight,
29
- MeshFilter,
30
- MeshRenderer,
31
- } from '@forgeax/engine-render/internal';
32
- import { createRenderer } from '@forgeax/engine-runtime';
33
- import { Transform } from '@forgeax/engine-scene';
34
- import { describe, expect, it } from 'vitest';
35
- import { drawPublished } from './draw-published';
36
-
37
- // ── Fixture constants SSOT (plan-strategy section 8.1 test anchor) ─────────
38
-
39
- /** Canvas size for the mock HTMLCanvasElement. */
40
- const WIDTH = 256;
41
- const HEIGHT = 256;
42
-
43
- /** Directional light points approximately down with a slight horizontal tilt to avoid lookAt degeneracy (dir parallel to up vector). See shadow-m1.dawn.test.ts AC-11 comment on the (0,-1,0) degeneracy. */
44
- const FIXTURE_LIGHT_DIR: [number, number, number] = [0.2, -0.98, 0];
45
-
46
- /** Shadow map resolution. */
47
- const FIXTURE_MAP_SIZE = 1024;
48
-
49
- /** Ground-plane scale (flattened cube, top face at y=0). */
50
- const GROUND_SIZE = 20;
51
-
52
- /**
53
- * World-space sample positions. Light direction (0.2, -0.98, 0) = mostly
54
- * down with a slight +X tilt. 2x2 cube occluder at (0, 1.5, 0) casts
55
- * shadow toward +X on the ground (y=0). Ground points at -X are lit;
56
- * ground points near x=0 within the cube footprint are occluded.
57
- *
58
- * M3 probe upgrade (feat-20260520 w16): PCF with 3x3 kernel replaces the
59
- * naive comparison sampler; positions use ground-plane sampling to detect
60
- * shadow from the 2x2 cube.
61
- *
62
- * - SAMPLE_LIT_*: ground (-X, 0.0, *) — outside the cube's shadow.
63
- * - SAMPLE_OCCLUDED_*: ground (0, 0.0, 0) — inside the cube's shadow core.
64
- */
65
- const SAMPLE_LIT_A: [number, number, number] = [-3, 0.0, 0];
66
- const SAMPLE_LIT_B: [number, number, number] = [-2, 0.0, 1];
67
- const SAMPLE_LIT_C: [number, number, number] = [-1.5, 0.0, -1];
68
- const SAMPLE_OCCLUDED_A: [number, number, number] = [0.2, 0.0, 0];
69
- const SAMPLE_OCCLUDED_B: [number, number, number] = [0.5, 0.0, 0];
70
-
71
- // ── Manifest: pre-built hello-triangle composed WGSL ──────────────────────
72
-
73
- /**
74
- * The shadow depth pass needs a valid shader manifest with WGSL for
75
- * `shadow_caster`. We read the hello-triangle demo's `pnpm build` output
76
- * `dist/shaders/manifest.json`. The manifest is loaded once per vitest
77
- * module via vitest's native ESM `import()` (supports both JSON and
78
- * top-level await in vitest's pool). We then encode it as a `data:` URL
79
- * so ShaderRegistry can fetch it via Node.js native fetch().
80
- *
81
- * Precondition: `pnpm -r build` (or `pnpm -F hello-triangle build`).
82
- *
83
- * Vitest dawn runs tests in Node.js ESM context, so `import()` resolves
84
- * relative to the source file. The relative path goes up 4 levels from
85
- * `packages/runtime/src/__tests__/` to the repo root, then down into
86
- * `apps/hello/triangle/dist/shaders/`.
87
- */
88
- async function loadManifestDataUrl(): Promise<string | null> {
89
- // fs.readFileSync (not `await import('...json')`) so tsc does not try
90
- // to statically resolve the path — the manifest is a build artifact only
91
- // present after `pnpm -F hello-triangle build` and CI's typecheck phase
92
- // runs before any app build (would error TS2307 on dynamic JSON import).
93
- try {
94
- const here = fileURLToPath(import.meta.url);
95
- const manifestPath = resolve(
96
- here,
97
- '../../../../../apps/hello/triangle/dist/shaders/manifest.json',
98
- );
99
- const text = readFileSync(manifestPath, 'utf8');
100
- return `data:application/json,${encodeURIComponent(text)}`;
101
- } catch {
102
- return null;
103
- }
104
- }
105
-
106
- // ── Helpers ────────────────────────────────────────────────────────────────
107
-
108
- const TEXTURE_USAGE_RENDER_ATTACHMENT = 0x10;
109
- const TEXTURE_USAGE_COPY_SRC = 0x01;
110
-
111
- // biome-ignore lint/suspicious/noExplicitAny: dawn-node detection guard
112
- const dawnReady = typeof navigator !== 'undefined' && (navigator as any).gpu !== undefined;
113
-
114
- /** Shared GPUDevice captured during adapter hook for render target creation. */
115
- let sharedDevice: GPUDevice | undefined;
116
-
117
- /**
118
- * Create a minimal offscreen render target so dawn-node can run beginRenderPass.
119
- */
120
- function createMockCanvas(width: number, height: number): HTMLCanvasElement {
121
- let renderTarget: GPUTexture | undefined;
122
- const originalRequestAdapter = globalThis.navigator.gpu.requestAdapter.bind(
123
- globalThis.navigator.gpu,
124
- );
125
- globalThis.navigator.gpu.requestAdapter = async (opts) => {
126
- const rawAdapter = await originalRequestAdapter(opts);
127
- if (rawAdapter === null) return rawAdapter;
128
- const originalRequestDevice = rawAdapter.requestDevice.bind(rawAdapter);
129
- rawAdapter.requestDevice = async (desc) => {
130
- const dev = await originalRequestDevice(desc);
131
- if (sharedDevice === undefined) sharedDevice = dev;
132
- return dev;
133
- };
134
- return rawAdapter;
135
- };
136
-
137
- const ensureRenderTarget = (device: GPUDevice, format: GPUTextureFormat): GPUTexture => {
138
- if (renderTarget !== undefined) return renderTarget;
139
- renderTarget = device.createTexture({
140
- size: { width, height, depthOrArrayLayers: 1 },
141
- format,
142
- usage: TEXTURE_USAGE_RENDER_ATTACHMENT | TEXTURE_USAGE_COPY_SRC,
143
- viewFormats: ['rgba8unorm-srgb'],
144
- });
145
- return renderTarget;
146
- };
147
-
148
- return {
149
- width,
150
- height,
151
- // biome-ignore lint/suspicious/noExplicitAny: HTMLCanvasElement mock for dawn-node
152
- getContext(kind: string): any {
153
- if (kind !== 'webgpu') return null;
154
- return {
155
- configure(desc: { device: GPUDevice; format?: GPUTextureFormat }) {
156
- ensureRenderTarget(desc.device, desc.format ?? 'rgba8unorm');
157
- },
158
- unconfigure() {},
159
- getCurrentTexture(): GPUTexture {
160
- if (renderTarget === undefined) {
161
- if (sharedDevice === undefined)
162
- throw new Error('render target requested before device captured');
163
- return ensureRenderTarget(sharedDevice, 'rgba8unorm');
164
- }
165
- return renderTarget;
166
- },
167
- };
168
- },
169
- addEventListener() {},
170
- removeEventListener() {},
171
- } as unknown as HTMLCanvasElement;
172
- }
173
-
174
- /**
175
- * Spawn the full fixture world: light + shadow, camera, ground plane, cube
176
- * occluder. Components are registered, entities spawned, ready for
177
- * `renderer.draw(world)`.
178
- */
179
- function buildFixtureWorld(): World {
180
- const world = new World();
181
- const cubeHandle = world.internSharedRef('MeshAsset', createPrimitiveMesh('cube').unwrap());
182
-
183
- // Light + shadow on same entity.
184
- world.spawn({
185
- component: DirectionalLight,
186
- data: {
187
- direction: [FIXTURE_LIGHT_DIR[0], FIXTURE_LIGHT_DIR[1], FIXTURE_LIGHT_DIR[2]],
188
- color: [1, 1, 1],
189
- intensity: 1,
190
- // feat-20260613-csm M6 / w22: shadow-m2 fixture predates CSM and
191
- // expects all geometry to land in cascade 0 (the test reads
192
- // debug.center, which always samples the cascade-0 tile -- see
193
- // debugReadbackShadowDepth in createRenderer.ts). With cascadeCount=4
194
- // (CSM default), PSSM splits between [camera near,
195
- // shadowDistance=50] place cascade 0 in view-space z [~0.1, 3.5];
196
- // the fixture's geometry sits at world z=0 (camera at z=10), which
197
- // is in view-space z=10 -> cascade 2/3, leaving cascade 0 empty.
198
- // Pinning cascadeCount=1 keeps the AC-12 single-shadow contract.
199
- cascadeCount: 1,
200
- mapSize: FIXTURE_MAP_SIZE,
201
- shadowDistance: 50,
202
- },
203
- });
204
-
205
- // Camera at (0, 0, 10) identity quat looking along -Z, orthographic
206
- // projection wide enough to capture the ground plane (y in [-5, 5]) and
207
- // the cube occluder at y=1.5. feat-20260613-csm M6 / w20 fixture
208
- // migration: CSM fits the light-space AABB to the camera frustum, so
209
- // the camera must SEE the shadowable geometry for the atlas to capture
210
- // it (the prior fixture sat at (0,10,0) identity quat looking -Z, which
211
- // missed both the ground and the cube). An orthographic camera at the
212
- // origin's z+10 plane with extents [-5,5] x [-5,5] gives camera-space
213
- // frustum x in [-5,5], y in [-5,5], z in [-99.9, 9.9] -> contains the
214
- // cube and the ground.
215
- world.spawn(
216
- {
217
- component: Transform,
218
- data: {
219
- pos: [0, 0, 10],
220
- quat: [0, 0, 0, 1],
221
- scale: [1, 1, 1],
222
- },
223
- },
224
- {
225
- component: Camera,
226
- data: {
227
- projection: 1, // orthographic
228
- left: -5,
229
- right: 5,
230
- bottom: -5,
231
- top: 5,
232
- near: 0.1,
233
- far: 100,
234
- fov: 0,
235
- aspect: 1,
236
- },
237
- },
238
- );
239
-
240
- // Ground plane -- flattened cube, top face at y=0.
241
- world.spawn(
242
- {
243
- component: Transform,
244
- data: {
245
- pos: [0, -0.005, 0],
246
- quat: [0, 0, 0, 1],
247
- scale: [GROUND_SIZE, 0.01, GROUND_SIZE],
248
- },
249
- },
250
- {
251
- component: MeshFilter,
252
- data: { assetHandle: cubeHandle },
253
- },
254
- {
255
- component: MeshRenderer,
256
- data: {},
257
- },
258
- );
259
-
260
- // Cube occluder: 2x2x2 centred at y=1.5 (matches M3 fixture).
261
- world.spawn(
262
- {
263
- component: Transform,
264
- data: {
265
- pos: [0, 1.5, 0],
266
- quat: [0, 0, 0, 1],
267
- scale: [2, 2, 2],
268
- },
269
- },
270
- {
271
- component: MeshFilter,
272
- data: { assetHandle: cubeHandle },
273
- },
274
- {
275
- component: MeshRenderer,
276
- data: {},
277
- },
278
- );
279
-
280
- return world;
281
- }
282
-
283
- // ── Tests ──────────────────────────────────────────────────────────────────
284
-
285
- describe('shadow M2 dawn (AC-12 real)', () => {
286
- it.skipIf(!dawnReady)("'dawn-binding-missing' -- dawn.node binding injection failed", () => {
287
- expect(dawnReady).toBe(true);
288
- });
289
-
290
- describe('AC-12 naive shadow factor sampling', () => {
291
- it('occluded positions measurably darker than lit, lit approx 1.0', async () => {
292
- const manifestUrl = await loadManifestDataUrl();
293
- if (manifestUrl === null) {
294
- // manifest not built; skip gracefully
295
- console.warn('[AC-12] hello-triangle manifest not found -- skipping shadow test');
296
- return;
297
- }
298
- const canvas = createMockCanvas(WIDTH, HEIGHT);
299
- const renderer = await createRenderer(canvas, {}, { shaderManifestUrl: manifestUrl });
300
- expect(renderer.backend).toBe('webgpu');
301
-
302
- const ready = await renderer.ready;
303
- expect(ready.ok).toBe(true);
304
-
305
- // Build fixture world and render at least one frame to populate
306
- // the shadow depth texture.
307
- const world = buildFixtureWorld();
308
- const drawResult = drawPublished(renderer, world);
309
- expect(drawResult.ok).toBe(true);
310
-
311
- // Verify the shadow RT exists (shadow pass ran).
312
- const debug = await renderer.debugReadback?.();
313
- expect(debug).not.toBeNull();
314
- if (debug !== null && debug !== undefined) {
315
- expect(debug.mapSize).toBe(FIXTURE_MAP_SIZE);
316
- expect(debug.center).toBeGreaterThanOrEqual(0);
317
- expect(debug.center).toBeLessThanOrEqual(1);
318
- console.warn('[AC-12 debug] debugReadback:', JSON.stringify(debug));
319
-
320
- // ── Core fix (M1c gap): shadow depth must have non-zero, non-
321
- // uniform values. These are load-bearing — they prove the
322
- // shadow depth pass wrote real geometry to the depth32float
323
- // attachment.
324
- // feat-20260613-csm M6 / w22: the legacy fixed-extent path placed
325
- // the cube at the tile centre; CSM AABB-fits the camera frustum
326
- // so the cube lands wherever its world-space projection maps under
327
- // the per-cascade ortho. The substantive AC-12 check is the
328
- // lit/occluded factor gap below (probe path is shader-identical
329
- // to the main pass). Replace centre/corner pixel checks with a
330
- // non-uniformity probe: at least one of the 5 sampled pixels must
331
- // have written cube depth (< 1), proving the depth pass ran.
332
- const samples = [
333
- debug.center,
334
- debug.corners.tl,
335
- debug.corners.tr,
336
- debug.corners.bl,
337
- debug.corners.br,
338
- ];
339
- expect(samples.some((s) => s < 0.99)).toBe(true);
340
- expect(samples.some((s) => s > 0.5)).toBe(true);
341
- }
342
-
343
- // Sample shadow factor at lit positions.
344
- const litPositions = [SAMPLE_LIT_A, SAMPLE_LIT_B, SAMPLE_LIT_C];
345
- const litResults = await renderer.debugSampleShadowFactor?.(litPositions);
346
- expect(litResults).not.toBeNull();
347
- if (!litResults) throw new Error('unreachable: debugSampleShadowFactor returned null');
348
- expect(litResults.length).toBe(3);
349
-
350
- // Sample shadow factor at occluded positions.
351
- const occPositions = [SAMPLE_OCCLUDED_A, SAMPLE_OCCLUDED_B];
352
- const occResults = await renderer.debugSampleShadowFactor?.(occPositions);
353
- expect(occResults).not.toBeNull();
354
- if (!occResults) throw new Error('unreachable: occluded debugSampleShadowFactor null');
355
- expect(occResults.length).toBe(2);
356
-
357
- const litFactors = litResults.map((r) => r.shadowFactor);
358
- const occFactors = occResults.map((r) => r.shadowFactor);
359
-
360
- console.warn('[AC-12 debug] litFactors:', JSON.stringify(litFactors));
361
- console.warn('[AC-12 debug] occFactors:', JSON.stringify(occFactors));
362
-
363
- // Also check directionalShadow for lightSpaceMatrix
364
- const ds = renderer.directionalShadow;
365
- console.warn('[AC-12 debug] directionalShadow mapSize:', ds?.mapSize);
366
- console.warn('[AC-12 debug] directionalShadow lightSpaceMatrix:', ds?.lightSpaceMatrix);
367
-
368
- // ── AC-12 numerical assertion (OOS-7 retired by feat-20260520 M2/w15).
369
- //
370
- // debugSampleShadowFactor now drives a fragment-stage GPU probe
371
- // pipeline that runs textureSampleCompareLevel byte-for-byte mirroring
372
- // pbr.wgsl::evalDirectional() — same UV remap, same OOB guard, same
373
- // PipelineState.shadowSampler. The factor returned for a world
374
- // position is the exact factor a fragment at that worldPos receives
375
- // in the main pass, so the lit-vs-occluded gap is load-bearing
376
- // semantic evidence the M2 shadow lookup is wired correctly.
377
- //
378
- // Lit positions land on the -X side of the light frustum where the
379
- // cube does not project; comparison returns 1 (fully lit). Occluded
380
- // positions land on the +X side under the cube's projected shadow;
381
- // comparison returns 0 (fully shadowed). M2 has no PCF (M3 work),
382
- // so values cluster at the discrete 0/1 endpoints and the gap is
383
- // the full unit interval.
384
- const litMin = Math.min(...litFactors);
385
- const occMax = Math.max(...occFactors);
386
- expect(litMin).toBeGreaterThan(0.5);
387
- expect(occMax).toBeLessThan(0.2);
388
- // The lit/occluded gap is the AC-12 semantic guarantee — that the
389
- // shadow term in the main pass actually responds to occluder
390
- // geometry (M3 probe with PCF preserves this gap).
391
- expect(litMin - occMax).toBeGreaterThan(0.3);
392
- });
393
- });
394
- });
@@ -1,248 +0,0 @@
1
- // shadow-m3-calibrate-run.dawn.test.ts - feat-20260520-directional-light-shadow-mapping
2
- // M3 / w15+w16: one-off calibration runner. Not part of the normal CI suite —
3
- // run explicitly with `npx vitest run <this-file>` after w16 bias+PCF lands
4
- // to measure shadow factor improvements and freeze AC_13_THRESHOLD_X.
5
- //
6
- // This file IS a .dawn.test.ts (so vitest gives it a dawn-node WebGPU device)
7
- // but it is intentionally gated behind `dawnReady` and prints a calibration
8
- // report rather than performing pass/fail assertions.
9
-
10
- import { readFileSync } from 'node:fs';
11
- import { resolve } from 'node:path';
12
- import { fileURLToPath } from 'node:url';
13
- import { World } from '@forgeax/engine-ecs';
14
- import { createPrimitiveMesh } from '@forgeax/engine-geometry';
15
- import {
16
- Camera,
17
- DirectionalLight,
18
- MeshFilter,
19
- MeshRenderer,
20
- } from '@forgeax/engine-render/internal';
21
- import { createRenderer } from '@forgeax/engine-runtime';
22
- import { Transform } from '@forgeax/engine-scene';
23
- import { describe, expect, it } from 'vitest';
24
- import { drawPublished } from './draw-published';
25
- import {
26
- CALIBRATION_POSITIONS,
27
- calibrateThresholdX,
28
- measureShadowFactors,
29
- printCalibrationReport,
30
- } from './shadow-m3-calibrate';
31
-
32
- // ── Fixture (same as shadow-m3.dawn.test.ts SSOT) ───────────────────────────
33
-
34
- const WIDTH = 256;
35
- const HEIGHT = 256;
36
- const FIXTURE_LIGHT_DIR: [number, number, number] = [0.2, -0.98, 0];
37
- const FIXTURE_MAP_SIZE = 1024;
38
- const GROUND_SIZE = 20;
39
-
40
- // biome-ignore lint/suspicious/noExplicitAny: dawn-node detection guard
41
- const dawnReady = typeof navigator !== 'undefined' && (navigator as any).gpu !== undefined;
42
-
43
- async function loadManifestDataUrl(): Promise<string | null> {
44
- // fs.readFileSync (not dynamic JSON import) so tsc does not statically
45
- // resolve the path — manifest only exists after `pnpm -F hello-triangle build`.
46
- try {
47
- const here = fileURLToPath(import.meta.url);
48
- const manifestPath = resolve(
49
- here,
50
- '../../../../../apps/hello/triangle/dist/shaders/manifest.json',
51
- );
52
- const text = readFileSync(manifestPath, 'utf8');
53
- return `data:application/json,${encodeURIComponent(text)}`;
54
- } catch {
55
- return null;
56
- }
57
- }
58
-
59
- const TEXTURE_USAGE_RENDER_ATTACHMENT = 0x10;
60
- const TEXTURE_USAGE_COPY_SRC = 0x01;
61
- let sharedDevice: GPUDevice | undefined;
62
-
63
- function createMockCanvas(width: number, height: number): HTMLCanvasElement {
64
- let renderTarget: GPUTexture | undefined;
65
- const originalRequestAdapter = globalThis.navigator.gpu.requestAdapter.bind(
66
- globalThis.navigator.gpu,
67
- );
68
- globalThis.navigator.gpu.requestAdapter = async (opts) => {
69
- const rawAdapter = await originalRequestAdapter(opts);
70
- if (rawAdapter === null) return rawAdapter;
71
- const originalRequestDevice = rawAdapter.requestDevice.bind(rawAdapter);
72
- rawAdapter.requestDevice = async (desc) => {
73
- const dev = await originalRequestDevice(desc);
74
- if (sharedDevice === undefined) sharedDevice = dev;
75
- return dev;
76
- };
77
- return rawAdapter;
78
- };
79
-
80
- const ensureRenderTarget = (device: GPUDevice, format: GPUTextureFormat): GPUTexture => {
81
- if (renderTarget !== undefined) return renderTarget;
82
- renderTarget = device.createTexture({
83
- size: { width, height, depthOrArrayLayers: 1 },
84
- format,
85
- usage: TEXTURE_USAGE_RENDER_ATTACHMENT | TEXTURE_USAGE_COPY_SRC,
86
- viewFormats: ['rgba8unorm-srgb'],
87
- });
88
- return renderTarget;
89
- };
90
-
91
- return {
92
- width,
93
- height,
94
- // biome-ignore lint/suspicious/noExplicitAny: HTMLCanvasElement mock for dawn-node
95
- getContext(kind: string): any {
96
- if (kind !== 'webgpu') return null;
97
- return {
98
- configure(desc: { device: GPUDevice; format?: GPUTextureFormat }) {
99
- ensureRenderTarget(desc.device, desc.format ?? 'rgba8unorm');
100
- },
101
- unconfigure() {},
102
- getCurrentTexture(): GPUTexture {
103
- if (renderTarget === undefined) {
104
- if (sharedDevice === undefined)
105
- throw new Error('render target requested before device captured');
106
- return ensureRenderTarget(sharedDevice, 'rgba8unorm');
107
- }
108
- return renderTarget;
109
- },
110
- };
111
- },
112
- addEventListener() {},
113
- removeEventListener() {},
114
- } as unknown as HTMLCanvasElement;
115
- }
116
-
117
- function buildFixtureWorld(): World {
118
- const world = new World();
119
- const cubeHandle = world.internSharedRef('MeshAsset', createPrimitiveMesh('cube').unwrap());
120
-
121
- world.spawn({
122
- component: DirectionalLight,
123
- data: {
124
- direction: [FIXTURE_LIGHT_DIR[0], FIXTURE_LIGHT_DIR[1], FIXTURE_LIGHT_DIR[2]],
125
- color: [1, 1, 1],
126
- intensity: 1,
127
- mapSize: FIXTURE_MAP_SIZE,
128
- shadowDistance: 50,
129
- },
130
- });
131
-
132
- world.spawn(
133
- {
134
- component: Transform,
135
- data: {
136
- pos: [0, 10, 0],
137
- quat: [0, 0, 0, 1],
138
- scale: [1, 1, 1],
139
- },
140
- },
141
- {
142
- component: Camera,
143
- data: {
144
- projection: 1,
145
- left: -5,
146
- right: 5,
147
- bottom: -5,
148
- top: 5,
149
- near: 0.1,
150
- far: 100,
151
- fov: 0,
152
- aspect: 1,
153
- },
154
- },
155
- );
156
-
157
- world.spawn(
158
- {
159
- component: Transform,
160
- data: {
161
- pos: [0, -0.005, 0],
162
- quat: [0, 0, 0, 1],
163
- scale: [GROUND_SIZE, 0.01, GROUND_SIZE],
164
- },
165
- },
166
- {
167
- component: MeshFilter,
168
- data: { assetHandle: cubeHandle },
169
- },
170
- {
171
- component: MeshRenderer,
172
- data: {},
173
- },
174
- );
175
-
176
- world.spawn(
177
- {
178
- component: Transform,
179
- data: {
180
- pos: [0, 1.3, 0],
181
- quat: [0, 0, 0, 1],
182
- scale: [1, 1, 1],
183
- },
184
- },
185
- {
186
- component: MeshFilter,
187
- data: { assetHandle: cubeHandle },
188
- },
189
- {
190
- component: MeshRenderer,
191
- data: {},
192
- },
193
- );
194
-
195
- return world;
196
- }
197
-
198
- describe('M3 calibration runner (one-off)', () => {
199
- it.skipIf(!dawnReady)("'dawn-binding-missing' -- dawn.node binding injection failed", () => {
200
- expect(dawnReady).toBe(true);
201
- });
202
-
203
- it('calibrate AC-13 threshold X', async () => {
204
- const manifestUrl = await loadManifestDataUrl();
205
- if (manifestUrl === null) {
206
- console.warn('[calibrate] manifest not found -- skipping');
207
- return;
208
- }
209
- const canvas = createMockCanvas(WIDTH, HEIGHT);
210
- const renderer = await createRenderer(canvas, {}, { shaderManifestUrl: manifestUrl });
211
- expect(renderer.backend).toBe('webgpu');
212
-
213
- const ready = await renderer.ready;
214
- expect(ready.ok).toBe(true);
215
-
216
- // Draw one frame to populate the shadow depth texture.
217
- const world = buildFixtureWorld();
218
- const drawResult = drawPublished(renderer, world);
219
- expect(drawResult.ok).toBe(true);
220
-
221
- // In the single-session calibration workflow, M2 and M3 measurements
222
- // happen on the SAME renderer, but at different points in time.
223
- // Pre-w16: both read the same (naive) shadow factors → diffs = 0.
224
- // Post-w16: re-run this runner after rebuilding; diffs reflect the
225
- // bias+PCF improvement.
226
- //
227
- // The "M2 baseline" is recorded first, then w16 is applied (pbr.wgsl
228
- // edit + rebuild), then this runner is called again — the M3 factors
229
- // will be the post-change values. For the single-session case both are
230
- // the same (the renderer reflects the CURRENT shader), so the implementer
231
- // must record M2 factors before the w16 commit, then re-measure after.
232
- const result = await calibrateThresholdX(
233
- CALIBRATION_POSITIONS,
234
- // measureM2: current factors (pre-w16 = same as M3, diffs 0)
235
- // In the actual two-step workflow this records before w16 commit.
236
- async () => measureShadowFactors(renderer, CALIBRATION_POSITIONS),
237
- // measureM3: current factors (post-w16 = bias+PCF active)
238
- async () => measureShadowFactors(renderer, CALIBRATION_POSITIONS),
239
- );
240
-
241
- printCalibrationReport(result);
242
-
243
- // In the RED phase (pre-w16), maxDiff == 0 and suggestedX == 0.02.
244
- // That's expected — calibration is aspirational until w16 lands.
245
- // Post-w16, maxDiff > 0 and the implementer copies suggestedX into
246
- // shadow-m3.dawn.test.ts AC_13_THRESHOLD_X and re-runs pnpm test:dawn.
247
- });
248
- });