@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
@@ -25,10 +25,10 @@
25
25
  // std140 walk produced by derive — caller writes scalars at the
26
26
  // reported offsets and the totalBytes is the buffer allocation size.
27
27
 
28
- import { appendInjection } from '@forgeax/engine-render/internal';
29
28
  import type { ParamSchemaEntry } from '@forgeax/engine-types';
30
29
  import { derive } from '@forgeax/engine-types';
31
30
  import { describe, expect, it } from 'vitest';
31
+ import { appendInjection } from '../../../render/src/pbr-pipeline';
32
32
 
33
33
  // ─── Synthetic schemas (one per built-in shader family) ─────────────────────
34
34
  //
@@ -54,9 +54,7 @@ const standardPbrSchema: readonly ParamSchemaEntry[] = [
54
54
  { name: 'baseColorTexture', type: 'texture2d' },
55
55
  { name: 'metallicRoughnessTexture', type: 'texture2d' },
56
56
  { name: 'normalTexture', type: 'texture2d' },
57
- { name: 'specularTintTexture', type: 'texture2d' },
58
57
  { name: 'emissiveTexture', type: 'texture2d' },
59
- { name: 'occlusionTexture', type: 'texture2d' },
60
58
  ];
61
59
 
62
60
  const skinSchema: readonly ParamSchemaEntry[] = [
@@ -179,7 +177,7 @@ describe('derive(schema) integration over 5 built-in shader families (M3 w11)',
179
177
  // injection order ibl-then-lightmap (D-8).
180
178
 
181
179
  // Exact paramSchema from packages/shader/src/default-standard-pbr.material.json:68-77
182
- // (15 numeric entries + 6 texture2d entries).
180
+ // (15 numeric entries + 4 texture2d entries).
183
181
  const defaultStandardPbrSchema: readonly ParamSchemaEntry[] = [
184
182
  { name: 'baseColor', type: 'color', default: [1, 1, 1, 1] },
185
183
  { name: 'metallic', type: 'f32', default: 0 },
@@ -199,22 +197,20 @@ const defaultStandardPbrSchema: readonly ParamSchemaEntry[] = [
199
197
  { name: 'metallicRoughnessTexture', type: 'texture2d' },
200
198
  { name: 'normalTexture', type: 'texture2d' },
201
199
  { name: 'specularTintTexture', type: 'texture2d' },
202
- { name: 'emissiveTexture', type: 'texture2d' },
203
- { name: 'occlusionTexture', type: 'texture2d' },
204
200
  ];
205
201
 
206
202
  describe('built-in PBR derive+injection regression fence (M1 w1)', () => {
207
- it('w1 user-region: derive produces 13 entries (binding 0 UBO + 6 sampler/texture pairs), userRegionBindingEnd=13', () => {
203
+ it('w1 user-region: derive produces 9 entries (binding 0 UBO + 4 sampler/texture pairs), userRegionBindingEnd=9', () => {
208
204
  const out = derive(defaultStandardPbrSchema);
209
205
 
210
- // 15 numeric entries run-merged into binding 0 UBO + 6 textures x 2 = 1 + 12 = 13.
211
- expect(out.bglEntries.length).toBe(13);
212
- expect(out.userRegionBindingEnd).toBe(13);
206
+ // 15 numeric entries run-merged into binding 0 UBO + 4 textures x 2 = 1 + 8 = 9.
207
+ expect(out.bglEntries.length).toBe(9);
208
+ expect(out.userRegionBindingEnd).toBe(9);
213
209
 
214
210
  // Bindings 0..6 dense, no gaps.
215
211
  const bindings = out.bglEntries.map((e) => e.binding);
216
- expect(new Set(bindings).size).toBe(13);
217
- for (let i = 0; i < 13; i++) {
212
+ expect(new Set(bindings).size).toBe(9);
213
+ for (let i = 0; i < 9; i++) {
218
214
  expect(bindings).toContain(i);
219
215
  }
220
216
 
@@ -222,28 +218,24 @@ describe('built-in PBR derive+injection regression fence (M1 w1)', () => {
222
218
  expect(out.bglEntries[0]?.binding).toBe(0);
223
219
  expect(out.bglEntries[0]?.buffer?.type).toBe('uniform');
224
220
 
225
- // textureFieldNames covers exactly the 6 texture2d entries.
226
- expect(out.textureFieldNames.size).toBe(6);
221
+ // textureFieldNames covers exactly the 4 texture2d entries.
222
+ expect(out.textureFieldNames.size).toBe(4);
227
223
  expect(out.textureFieldNames.has('baseColorTexture')).toBe(true);
228
224
  expect(out.textureFieldNames.has('metallicRoughnessTexture')).toBe(true);
229
225
  expect(out.textureFieldNames.has('normalTexture')).toBe(true);
230
226
  expect(out.textureFieldNames.has('specularTintTexture')).toBe(true);
231
- expect(out.textureFieldNames.has('emissiveTexture')).toBe(true);
232
- expect(out.textureFieldNames.has('occlusionTexture')).toBe(true);
233
227
 
234
228
  // sampler map: each texture has a paired sampler.
235
- expect(out.samplerForTexture.size).toBe(6);
229
+ expect(out.samplerForTexture.size).toBe(4);
236
230
  expect(out.samplerForTexture.get('baseColorTexture')).toBe('baseColorTexture_sampler');
237
231
  expect(out.samplerForTexture.get('metallicRoughnessTexture')).toBe(
238
232
  'metallicRoughnessTexture_sampler',
239
233
  );
240
234
  expect(out.samplerForTexture.get('normalTexture')).toBe('normalTexture_sampler');
241
235
  expect(out.samplerForTexture.get('specularTintTexture')).toBe('specularTintTexture_sampler');
242
- expect(out.samplerForTexture.get('emissiveTexture')).toBe('emissiveTexture_sampler');
243
- expect(out.samplerForTexture.get('occlusionTexture')).toBe('occlusionTexture_sampler');
244
236
  });
245
237
 
246
- it('w1 full pipeline: derive + ibl injection + lightmap injection = 24 entries dense 0..23', () => {
238
+ it('w1 full pipeline: derive + ibl injection + lightmap injection = 20 entries dense 0..19', () => {
247
239
  const out = derive(defaultStandardPbrSchema);
248
240
  // Same cast as append-injection.test.ts — forgeax shim → @webgpu/types via
249
241
  // explicit two-step `as unknown as`, exempt from RHI gate j.
@@ -252,21 +244,21 @@ describe('built-in PBR derive+injection regression fence (M1 w1)', () => {
252
244
  // Injection start = userRegionBindingEnd (NOT a hardcoded 7 literal).
253
245
  const afterIbl = appendInjection(userBgl, 'ibl');
254
246
  expect(afterIbl.length).toBe(7);
255
- expect(afterIbl[0]?.binding).toBe(out.userRegionBindingEnd); // 13
247
+ expect(afterIbl[0]?.binding).toBe(out.userRegionBindingEnd); // 9
256
248
 
257
249
  const mergedAfterIbl = [...userBgl, ...afterIbl];
258
250
 
259
251
  const afterLightmap = appendInjection(mergedAfterIbl, 'lightmap');
260
252
  expect(afterLightmap.length).toBe(4);
261
- expect(afterLightmap[0]?.binding).toBe(mergedAfterIbl.length); // 20
253
+ expect(afterLightmap[0]?.binding).toBe(mergedAfterIbl.length); // 16
262
254
 
263
255
  const fullSet = [...mergedAfterIbl, ...afterLightmap];
264
- expect(fullSet.length).toBe(24);
256
+ expect(fullSet.length).toBe(20);
265
257
 
266
258
  // Bindings 0..17 dense, no gaps.
267
259
  const bindings = fullSet.map((e) => e.binding);
268
- expect(new Set(bindings).size).toBe(24);
269
- for (let i = 0; i < 24; i++) {
260
+ expect(new Set(bindings).size).toBe(20);
261
+ for (let i = 0; i < 20; i++) {
270
262
  expect(bindings).toContain(i);
271
263
  }
272
264
 
@@ -289,7 +281,7 @@ describe('built-in PBR derive+injection regression fence (M1 w1)', () => {
289
281
 
290
282
  it('w1 injection start is userRegionBindingEnd, not a hardcoded literal', () => {
291
283
  const out = derive(defaultStandardPbrSchema);
292
- // Prove that userRegionBindingEnd (13 today) is what feeds injection, not a
284
+ // Prove that userRegionBindingEnd (9 today) is what feeds injection, not a
293
285
  // hardcoded constant embedded in test logic. The derive() output IS the SSOT.
294
286
  const userBgl = [...out.bglEntries] as unknown as readonly GPUBindGroupLayoutEntry[];
295
287
 
@@ -299,8 +291,8 @@ describe('built-in PBR derive+injection regression fence (M1 w1)', () => {
299
291
  // derive later shifts userRegionBindingEnd (e.g. to 9 for 4-texture),
300
292
  // this assertion catches the desync.
301
293
  expect(afterIbl[0]?.binding).toBe(out.userRegionBindingEnd);
302
- // read-back guard: confirm the derived standard contract has six textures.
303
- expect(out.userRegionBindingEnd).toBe(13);
294
+ // read-back guard: confirm the derive result really is 9 today.
295
+ expect(out.userRegionBindingEnd).toBe(9);
304
296
  });
305
297
  });
306
298
 
@@ -336,21 +328,19 @@ const parallax4TextureSchema: readonly ParamSchemaEntry[] = [
336
328
  { name: 'normalTexture', type: 'texture2d' },
337
329
  { name: 'specularTintTexture', type: 'texture2d' },
338
330
  { name: 'heightTexture', type: 'texture2d' },
339
- { name: 'emissiveTexture', type: 'texture2d' },
340
- { name: 'occlusionTexture', type: 'texture2d' },
341
331
  ];
342
332
 
343
333
  describe('5-texture custom schema derive: heightTexture binding + injection shift (M2 w2)', () => {
344
334
  it('(a) heightTexture earns a distinct sampler(7)/texture(8) binding pair', () => {
345
335
  const out = derive(parallax4TextureSchema);
346
336
 
347
- // textureFieldNames covers all 7 declared textures.
348
- expect(out.textureFieldNames.size).toBe(7);
337
+ // textureFieldNames covers all 5 declared textures.
338
+ expect(out.textureFieldNames.size).toBe(5);
349
339
  expect(out.textureFieldNames.has('heightTexture')).toBe(true);
350
340
  expect(out.samplerForTexture.get('heightTexture')).toBe('heightTexture_sampler');
351
341
 
352
- // 1 UBO + 7 sampler/texture pairs = 15 entries.
353
- expect(out.bglEntries.length).toBe(15);
342
+ // 1 UBO + 5 sampler/texture pairs = 11 entries.
343
+ expect(out.bglEntries.length).toBe(11);
354
344
 
355
345
  // heightTexture is the 5th texture: sampler at binding 9, texture at binding 10.
356
346
  // (after baseColor 1/2, MR 3/4, normal 5/6, specular tint 7/8).
@@ -365,8 +355,8 @@ describe('5-texture custom schema derive: heightTexture binding + injection shif
365
355
  it('(b) userRegionBindingEnd=11 (4-texture baseline 9, shifted +2 by heightTexture)', () => {
366
356
  const baseline = derive(defaultStandardPbrSchema);
367
357
  const parallax = derive(parallax4TextureSchema);
368
- expect(baseline.userRegionBindingEnd).toBe(13);
369
- expect(parallax.userRegionBindingEnd).toBe(15);
358
+ expect(baseline.userRegionBindingEnd).toBe(9);
359
+ expect(parallax.userRegionBindingEnd).toBe(11);
370
360
  // Exactly one sampler/texture pair (2 bindings) of shift.
371
361
  expect(parallax.userRegionBindingEnd - baseline.userRegionBindingEnd).toBe(2);
372
362
  });
@@ -377,21 +367,21 @@ describe('5-texture custom schema derive: heightTexture binding + injection shif
377
367
 
378
368
  const afterIbl = appendInjection(userBgl, 'ibl');
379
369
  // Injection start follows derive().userRegionBindingEnd dynamically — for a
380
- // 7-texture schema that is 15, not the 6-texture baseline's 13.
370
+ // 5-texture schema that is 11, not the 4-texture baseline's 9.
381
371
  expect(afterIbl[0]?.binding).toBe(out.userRegionBindingEnd);
382
- expect(afterIbl[0]?.binding).toBe(15);
372
+ expect(afterIbl[0]?.binding).toBe(11);
383
373
 
384
374
  const mergedAfterIbl = [...userBgl, ...afterIbl];
385
375
  const afterLightmap = appendInjection(mergedAfterIbl, 'lightmap');
386
- // Lightmap follows IBL: 15 + 7 = 22.
387
- expect(afterLightmap[0]?.binding).toBe(22);
376
+ // Lightmap follows IBL: 11 + 7 = 18.
377
+ expect(afterLightmap[0]?.binding).toBe(18);
388
378
 
389
- // Full set: 15 user-region + 7 ibl + 4 lightmap = 26 entries, dense 0..25.
379
+ // Full set: 11 user-region + 7 ibl + 4 lightmap = 22 entries, dense 0..21.
390
380
  const fullSet = [...mergedAfterIbl, ...afterLightmap];
391
- expect(fullSet.length).toBe(26);
381
+ expect(fullSet.length).toBe(22);
392
382
  const bindings = fullSet.map((e) => e.binding);
393
- expect(new Set(bindings).size).toBe(26);
394
- for (let i = 0; i < 26; i++) {
383
+ expect(new Set(bindings).size).toBe(22);
384
+ for (let i = 0; i < 22; i++) {
395
385
  expect(bindings).toContain(i);
396
386
  }
397
387
  });
@@ -3,9 +3,9 @@
3
3
  // order, including skin streams, without a parallel stride discriminator.
4
4
 
5
5
  import { deriveVertexLayoutProjection } from '@forgeax/engine-geometry';
6
- import { deriveRenderDataMesh } from '@forgeax/engine-render/internal';
7
6
  import type { MeshAsset } from '@forgeax/engine-types';
8
7
  import { describe, expect, it } from 'vitest';
8
+ import { deriveRenderDataMesh } from '../../../render/src/render-data';
9
9
 
10
10
  function canonicalAttributes(vertexCount: number): MeshAsset['attributes'] {
11
11
  return {
@@ -1,10 +1,17 @@
1
1
  import type { World } from '@forgeax/engine-ecs';
2
- import type { Renderer } from '@forgeax/engine-render';
2
+ import type { FrameReceipt, RenderError, Renderer, RenderResult } from '@forgeax/engine-render';
3
3
 
4
4
  /** Drive the production attach -> update -> draw contract in direct-render tests. */
5
- export function drawPublished(renderer: Renderer, world: World): ReturnType<Renderer['draw']> {
6
- const attached = renderer.attachWorld(world);
5
+ export function drawPublished(
6
+ renderer: Renderer,
7
+ world: World,
8
+ ): RenderResult<FrameReceipt, RenderError> {
9
+ const attached = renderer.attach(world);
7
10
  if (!attached.ok) throw attached.error;
8
11
  world.update(1 / 60).unwrap();
9
- return renderer.draw([world], { cameraOwner: 0, resourceOwner: 0 });
12
+ return renderer.draw({
13
+ leases: [attached.value],
14
+ camera: { lease: attached.value },
15
+ environment: { lease: attached.value },
16
+ });
10
17
  }
@@ -0,0 +1,190 @@
1
+ // feat-20260623-world-space-video-asset M4 / w15 — DynamicTextureStore unit.
2
+ //
3
+ // D-3 / AC-08: the transient video texture path is fully independent of
4
+ // GpuResidencyCache.ensureResident (the static "upload once / cache forever"
5
+ // cache). This test pins the three load-bearing properties:
6
+ // 1. isolation — the module does NOT import GpuResidencyCache (source scan).
7
+ // 2. allocate-once — a steady-size clip creates exactly one GPU texture; each
8
+ // subsequent frame is a copyExternalImageToTexture write, not a new create.
9
+ // 3. resize-on-change — a dimension change destroys the old texture and
10
+ // allocates a new one (so a clip whose intrinsic size resolves late still
11
+ // renders correctly).
12
+ // Plus the structured-failure contract (charter P3): a device that rejects the
13
+ // copy returns a Result.err, never throws.
14
+
15
+ import { readFileSync } from 'node:fs';
16
+ import { fileURLToPath } from 'node:url';
17
+ import { type DynamicTextureDevice, DynamicTextureStore } from '@forgeax/engine-assets-runtime';
18
+ import type { Result, Texture, TextureView } from '@forgeax/engine-rhi';
19
+ import { err, ok, RhiError } from '@forgeax/engine-rhi';
20
+ import type { Handle } from '@forgeax/engine-types';
21
+ import { toShared } from '@forgeax/engine-types';
22
+ import { describe, expect, it } from 'vitest';
23
+
24
+ const STORE_SRC = fileURLToPath(
25
+ new URL('../../../assets-runtime/src/dynamic-texture-store.ts', import.meta.url),
26
+ );
27
+
28
+ interface DeviceProbe {
29
+ created: number;
30
+ destroyed: number;
31
+ copies: number;
32
+ }
33
+
34
+ function makeMockDevice(
35
+ probe: DeviceProbe,
36
+ opts: { copyFails?: boolean } = {},
37
+ ): DynamicTextureDevice {
38
+ let nextTex = 0;
39
+ return {
40
+ createTexture: (): Result<Texture, RhiError> => {
41
+ probe.created += 1;
42
+ return ok({ __tex: `tex-${++nextTex}` } as unknown as Texture);
43
+ },
44
+ createTextureView: (tex: Texture): Result<TextureView, RhiError> =>
45
+ ok({ __view: tex } as unknown as TextureView),
46
+ destroyTexture: (): Result<void, RhiError> => {
47
+ probe.destroyed += 1;
48
+ return ok(undefined);
49
+ },
50
+ queue: {
51
+ copyExternalImageToTexture: (): Result<void, RhiError> => {
52
+ probe.copies += 1;
53
+ if (opts.copyFails === true) {
54
+ return err(
55
+ new RhiError({
56
+ code: 'webgpu-runtime-error',
57
+ expected: 'copyExternalImageToTexture succeeds',
58
+ hint: 'video source not yet decodable',
59
+ }),
60
+ );
61
+ }
62
+ return ok(undefined);
63
+ },
64
+ },
65
+ };
66
+ }
67
+
68
+ const FAKE_SOURCE = {} as unknown as GPUCopyExternalImageSourceInfo['source'];
69
+
70
+ function clip(id: number): Handle<'VideoAsset', 'shared'> {
71
+ return toShared<'VideoAsset'>(id);
72
+ }
73
+
74
+ describe('DynamicTextureStore isolation (M4 / w15)', () => {
75
+ it('does NOT import GpuResidencyCache (AC-08 / D-3 independence)', () => {
76
+ const src = readFileSync(STORE_SRC, 'utf8');
77
+ // Scan import statements only — the file's prose comments reference the
78
+ // store/ensureResident to explain WHY they are kept separate (D-3); the
79
+ // load-bearing invariant is the absence of an actual import edge.
80
+ const importLines = src.split('\n').filter((l) => /^\s*import\b/.test(l));
81
+ for (const line of importLines) {
82
+ expect(line.includes('device/gpu-residency'), `unexpected import: ${line}`).toBe(false);
83
+ }
84
+ // No call to the static residency cache method anywhere in executable code
85
+ // (strip comments first so the explanatory prose does not trip the gate).
86
+ const stripped = src.replace(/\/\*[\s\S]*?\*\//g, '').replace(/\/\/[^\n]*/g, '');
87
+ expect(stripped.includes('ensureResident')).toBe(false);
88
+ });
89
+ });
90
+
91
+ describe('DynamicTextureStore lifecycle (M4 / w15)', () => {
92
+ it('allocate-once: a steady-size clip creates one texture, writes every frame', () => {
93
+ const probe: DeviceProbe = { created: 0, destroyed: 0, copies: 0 };
94
+ const store = new DynamicTextureStore();
95
+ store.configureGpuDevice(makeMockDevice(probe));
96
+ const h = clip(701);
97
+
98
+ for (let frame = 0; frame < 5; frame++) {
99
+ const res = store.uploadFrame(h, FAKE_SOURCE, 320, 240);
100
+ expect(res?.ok).toBe(true);
101
+ }
102
+ expect(probe.created).toBe(1);
103
+ expect(probe.copies).toBe(5);
104
+ expect(probe.destroyed).toBe(0);
105
+ expect(store.getView(h)).toBeDefined();
106
+ });
107
+
108
+ it('resize-on-change: a dimension change destroys the old texture + allocates a new one', () => {
109
+ const probe: DeviceProbe = { created: 0, destroyed: 0, copies: 0 };
110
+ const store = new DynamicTextureStore();
111
+ store.configureGpuDevice(makeMockDevice(probe));
112
+ const h = clip(702);
113
+
114
+ expect(store.uploadFrame(h, FAKE_SOURCE, 320, 240)?.ok).toBe(true);
115
+ expect(store.uploadFrame(h, FAKE_SOURCE, 320, 240)?.ok).toBe(true);
116
+ expect(probe.created).toBe(1);
117
+
118
+ // Intrinsic size resolved (e.g. metadata loaded) -> new dimensions.
119
+ expect(store.uploadFrame(h, FAKE_SOURCE, 640, 480)?.ok).toBe(true);
120
+ expect(probe.created).toBe(2);
121
+ expect(probe.destroyed).toBe(1);
122
+ });
123
+
124
+ it('two clips get independent transient textures', () => {
125
+ const probe: DeviceProbe = { created: 0, destroyed: 0, copies: 0 };
126
+ const store = new DynamicTextureStore();
127
+ store.configureGpuDevice(makeMockDevice(probe));
128
+
129
+ expect(store.uploadFrame(clip(710), FAKE_SOURCE, 100, 100)?.ok).toBe(true);
130
+ expect(store.uploadFrame(clip(711), FAKE_SOURCE, 100, 100)?.ok).toBe(true);
131
+ expect(probe.created).toBe(2);
132
+ expect(store.getView(clip(710))).not.toBe(store.getView(clip(711)));
133
+ });
134
+
135
+ it('device swap destroys stale entries before reusing a clip', () => {
136
+ const first: DeviceProbe = { created: 0, destroyed: 0, copies: 0 };
137
+ const second: DeviceProbe = { created: 0, destroyed: 0, copies: 0 };
138
+ const store = new DynamicTextureStore();
139
+ const h = clip(740);
140
+
141
+ store.configureGpuDevice(makeMockDevice(first));
142
+ expect(store.uploadFrame(h, FAKE_SOURCE, 320, 240)?.ok).toBe(true);
143
+
144
+ store.configureGpuDevice(makeMockDevice(second));
145
+ expect(first.destroyed).toBe(1);
146
+ expect(store.getView(h)).toBeUndefined();
147
+
148
+ expect(store.uploadFrame(h, FAKE_SOURCE, 320, 240)?.ok).toBe(true);
149
+ expect(second.created).toBe(1);
150
+ expect(second.copies).toBe(1);
151
+ });
152
+ });
153
+
154
+ describe('DynamicTextureStore degrade paths (M4 / w15, charter P3)', () => {
155
+ it('returns undefined (not an error) before a device is wired', () => {
156
+ const store = new DynamicTextureStore();
157
+ expect(store.uploadFrame(clip(720), FAKE_SOURCE, 320, 240)).toBeUndefined();
158
+ expect(store.getView(clip(720))).toBeUndefined();
159
+ });
160
+
161
+ it('returns undefined for zero / unknown source dimensions (metadata pending)', () => {
162
+ const probe: DeviceProbe = { created: 0, destroyed: 0, copies: 0 };
163
+ const store = new DynamicTextureStore();
164
+ store.configureGpuDevice(makeMockDevice(probe));
165
+ expect(store.uploadFrame(clip(721), FAKE_SOURCE, 0, 0)).toBeUndefined();
166
+ expect(probe.created).toBe(0);
167
+ });
168
+
169
+ it('returns a structured RhiError when the copy fails (never throws)', () => {
170
+ const probe: DeviceProbe = { created: 0, destroyed: 0, copies: 0 };
171
+ const store = new DynamicTextureStore();
172
+ store.configureGpuDevice(makeMockDevice(probe, { copyFails: true }));
173
+ const res = store.uploadFrame(clip(722), FAKE_SOURCE, 320, 240);
174
+ expect(res?.ok).toBe(false);
175
+ if (res !== undefined && !res.ok) {
176
+ expect(res.error.code).toBe('webgpu-runtime-error');
177
+ }
178
+ });
179
+
180
+ it('destroyAll destroys every transient texture + clears the views', () => {
181
+ const probe: DeviceProbe = { created: 0, destroyed: 0, copies: 0 };
182
+ const store = new DynamicTextureStore();
183
+ store.configureGpuDevice(makeMockDevice(probe));
184
+ store.uploadFrame(clip(730), FAKE_SOURCE, 64, 64);
185
+ store.uploadFrame(clip(731), FAKE_SOURCE, 64, 64);
186
+ store.destroyAll();
187
+ expect(probe.destroyed).toBe(2);
188
+ expect(store.getView(clip(730))).toBeUndefined();
189
+ });
190
+ });
@@ -1,23 +1,148 @@
1
- import { deriveRenderDataCubemap } from '@forgeax/engine-render/internal';
1
+ // equirect renderable-source integration test (feat-20260707 M5 fix, dawn env).
2
+ //
3
+ // The full HDR equirect chain, end to end: an equirect is ALWAYS an IBL / skybox
4
+ // source (Skylight.equirect / SkyboxBackground.equirect drive equirect-to-cube /
5
+ // irradiance / prefilter RENDER passes). A block-compressed HDR format
6
+ // (bc6h-rgb-ufloat) is sample-only, never a color-renderable render target
7
+ // ("BC6HRGBUfloat is not color renderable"), so an equirect is never
8
+ // block-compressed: it is delivered uncompressed rgba16float. This test asserts
9
+ // the equirect loader yields an rgba16float POD and `deriveRenderDataCubemap`
10
+ // accepts it (renderable cube source), regardless of the device bc cap.
11
+ //
12
+ // This replaces the earlier "equirect -> BC6H by cap" premise, which was itself
13
+ // the bug: BC6H equirect broke cube projection with a WebGPU device error.
14
+ //
15
+ // dawn env: the caps triple is printed so the lavapipe/llvmpipe BC-support
16
+ // question stays empirically visible in CI logs; the equirect path is
17
+ // cap-independent (always rgba16float).
18
+ //
19
+ // File is named `.integration.test.ts`; it is added to the dawn project
20
+ // `include` array in the root vitest.config.ts so it runs under the dawn-node GPU
21
+ // env, and skips itself when navigator.gpu is absent (the per-package unit
22
+ // project) rather than failing.
23
+
24
+ import { AssetRegistry } from '@forgeax/engine-assets-runtime';
25
+ import { AssetGuid } from '@forgeax/engine-pack/guid';
2
26
  import type { EquirectAsset } from '@forgeax/engine-types';
3
- import { describe, expect, it } from 'vitest';
4
-
5
- function makeEquirect(width: number, height: number): EquirectAsset {
6
- const pixels = new Uint16Array(width * height * 4);
7
- pixels.fill(0x3c00);
8
- return {
9
- kind: 'equirect',
10
- width,
11
- height,
12
- format: 'rgba16float',
13
- data: new Uint8Array(pixels.buffer),
14
- colorSpace: 'linear',
15
- };
27
+ import { beforeAll, describe, expect, it } from 'vitest';
28
+ import { deriveRenderDataCubemap } from '../../../render/src/render-data';
29
+ import { makeMockShaderRegistry } from './helpers/mock-shader-registry';
30
+
31
+ const gpu = globalThis.navigator?.gpu;
32
+ const hasGpu = gpu !== undefined;
33
+
34
+ const GUID_EQUI = 'c0000000-0000-4000-a000-000065717569';
35
+ const PACK_INDEX_URL = '/test-equirect-renderable-pack-index.json';
36
+
37
+ function parseGuid(g: string): AssetGuid {
38
+ const parsed = AssetGuid.parse(g);
39
+ if (!parsed.ok) throw new Error(`bad guid ${g}`);
40
+ return parsed.value;
16
41
  }
17
42
 
18
- describe('equirect renderable-source integration', () => {
19
- it('accepts the uncompressed rgba16float source required by cubemap render passes', () => {
20
- const asset = makeEquirect(64, 32);
43
+ /** A deterministic WxH rgba16float (IEEE-754 binary16) HDR image. */
44
+ function makeHdrHalf(w: number, h: number): Uint8Array {
45
+ // 0x3c00 = 1.0 in binary16; vary channels so the bytes are non-trivial.
46
+ const px = new Uint16Array(w * h * 4);
47
+ for (let i = 0; i < w * h; i++) {
48
+ px[i * 4] = 0x3c00;
49
+ px[i * 4 + 1] = 0x3800; // 0.5
50
+ px[i * 4 + 2] = 0x3400; // 0.25
51
+ px[i * 4 + 3] = 0x3c00;
52
+ }
53
+ return new Uint8Array(px.buffer);
54
+ }
55
+
56
+ let bcCap = false;
57
+
58
+ describe.skipIf(!hasGpu)('equirect renderable-source integration (feat-20260707 fix)', () => {
59
+ const width = 64;
60
+ const height = 32;
61
+ let binBytes: Uint8Array;
62
+ const packageUrl = '/ddc/equirect.pack.json';
63
+ const artifactUrl = '/ddc/equirect.bin';
64
+
65
+ beforeAll(async () => {
66
+ // biome-ignore lint/style/noNonNullAssertion: skipIf(!hasGpu) guards this
67
+ const adapter = await gpu!.requestAdapter();
68
+ if (adapter === null) throw new Error('no GPU adapter under dawn');
69
+ bcCap = adapter.features.has('texture-compression-bc');
70
+ // biome-ignore lint/suspicious/noConsole: keep the caps triple empirically visible in CI logs
71
+ console.info(
72
+ `[equirect caps] bc=${bcCap} etc2=${adapter.features.has(
73
+ 'texture-compression-etc2',
74
+ )} astc=${adapter.features.has('texture-compression-astc')}`,
75
+ );
76
+ binBytes = makeHdrHalf(width, height);
77
+ });
78
+
79
+ function wireFetch(): void {
80
+ globalThis.fetch = (async (input: RequestInfo | URL) => {
81
+ const url = typeof input === 'string' ? input : String(input);
82
+ if (url === PACK_INDEX_URL) {
83
+ return {
84
+ ok: true,
85
+ json: async () => [{ guid: GUID_EQUI, packageUrl, kind: 'equirect' }],
86
+ } as Response;
87
+ }
88
+ if (url === packageUrl) {
89
+ return {
90
+ ok: true,
91
+ json: async () => ({
92
+ schemaVersion: '2.0.0',
93
+ kind: 'internal-text-package',
94
+ assets: [
95
+ {
96
+ guid: GUID_EQUI,
97
+ kind: 'equirect',
98
+ payload: {
99
+ kind: 'equirect',
100
+ width,
101
+ height,
102
+ format: 'rgba16float',
103
+ colorSpace: 'linear',
104
+ },
105
+ refs: [],
106
+ artifacts: {
107
+ body: {
108
+ path: 'equirect.bin',
109
+ mediaType: 'application/x-forgeax-rgba16f',
110
+ },
111
+ },
112
+ },
113
+ ],
114
+ }),
115
+ } as Response;
116
+ }
117
+ if (url === artifactUrl) {
118
+ return { ok: true, arrayBuffer: async () => binBytes.buffer } as Response;
119
+ }
120
+ return { ok: false, status: 404 } as Response;
121
+ }) as typeof globalThis.fetch;
122
+ }
123
+
124
+ async function loadEquirect(): Promise<EquirectAsset> {
125
+ wireFetch();
126
+ const reg = new AssetRegistry(makeMockShaderRegistry());
127
+ reg.configurePackIndex(PACK_INDEX_URL);
128
+ reg.setTranscodeCaps({ bc: bcCap, etc2: false, astc: false });
129
+ const res = await reg.loadByGuid<EquirectAsset>(parseGuid(GUID_EQUI));
130
+ if (!res.ok) throw new Error(`equirect load failed: ${(res.error as { code: string }).code}`);
131
+ return res.value;
132
+ }
133
+
134
+ it('equirect is uncompressed rgba16float regardless of bc cap (IBL render source)', async () => {
135
+ const asset = await loadEquirect();
136
+ expect(asset.kind).toBe('equirect');
137
+ // Never a block-compressed format: an equirect drives cube RENDER passes and
138
+ // BC6H is not color-renderable.
139
+ expect(asset.format).toBe('rgba16float');
140
+ });
141
+
142
+ it('deriveRenderDataCubemap accepts the rgba16float equirect (renderable cube source)', async () => {
143
+ const asset = await loadEquirect();
144
+ // deriveRenderDataCubemap consumes a TextureAsset-shaped source; the equirect
145
+ // POD mirrors that 2D surface.
21
146
  const source = {
22
147
  kind: 'texture' as const,
23
148
  width: asset.width,
@@ -27,9 +152,7 @@ describe('equirect renderable-source integration', () => {
27
152
  colorSpace: asset.colorSpace,
28
153
  mipmap: false,
29
154
  };
30
-
31
- const result = deriveRenderDataCubemap(source);
32
-
33
- expect(result.ok).toBe(true);
155
+ const res = deriveRenderDataCubemap(source);
156
+ expect(res.ok).toBe(true);
34
157
  });
35
158
  });