@forgeax/engine-render 0.1.29 → 0.1.31

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 (350) hide show
  1. package/README.md +248 -21
  2. package/dist/assembly/atmosphere-shader-prewarm.d.ts +1 -1
  3. package/dist/assembly/atmosphere-shader-prewarm.d.ts.map +1 -1
  4. package/dist/assembly/device-feature-admission.d.ts +4 -3
  5. package/dist/assembly/device-feature-admission.d.ts.map +1 -1
  6. package/dist/assembly/dynamic-geometry-host.d.ts +6 -0
  7. package/dist/assembly/dynamic-geometry-host.d.ts.map +1 -1
  8. package/dist/assembly/host-contract.d.ts +6 -0
  9. package/dist/assembly/host-contract.d.ts.map +1 -1
  10. package/dist/assembly/material/assembly.d.ts +26 -3
  11. package/dist/assembly/material/assembly.d.ts.map +1 -1
  12. package/dist/assembly/material/pipeline-helpers.d.ts +24 -0
  13. package/dist/assembly/material/pipeline-helpers.d.ts.map +1 -0
  14. package/dist/assembly/material-shader-policy.d.ts.map +1 -1
  15. package/dist/assembly/recovery/device-loss-fanout.d.ts.map +1 -1
  16. package/dist/assembly/recovery/recovery-attempt.d.ts +1 -6
  17. package/dist/assembly/recovery/recovery-attempt.d.ts.map +1 -1
  18. package/dist/assembly/recovery/renderer-recover.d.ts +1 -0
  19. package/dist/assembly/recovery/renderer-recover.d.ts.map +1 -1
  20. package/dist/assembly/renderer-facade.d.ts.map +1 -1
  21. package/dist/assembly/shader-prewarm-policy.d.ts +1 -1
  22. package/dist/assembly/shader-prewarm-policy.d.ts.map +1 -1
  23. package/dist/assembly/webgpu-ready.d.ts +1 -1
  24. package/dist/assembly/webgpu-ready.d.ts.map +1 -1
  25. package/dist/assembly/webgpu-renderer.d.ts.map +1 -1
  26. package/dist/capture/scene-projection.d.ts +41 -0
  27. package/dist/capture/scene-projection.d.ts.map +1 -0
  28. package/dist/{chunk-BQVQOQJH.mjs → chunk-7MQ3XBSP.mjs} +20 -14
  29. package/dist/chunk-7MQ3XBSP.mjs.map +1 -0
  30. package/dist/{chunk-S4DNKQYQ.mjs → chunk-C3DDSXYK.mjs} +86 -33
  31. package/dist/chunk-C3DDSXYK.mjs.map +1 -0
  32. package/dist/{chunk-BTWH7BP4.mjs → chunk-FUUO4UND.mjs} +73 -29
  33. package/dist/chunk-FUUO4UND.mjs.map +1 -0
  34. package/dist/{chunk-NRNXBLIJ.mjs → chunk-JRBDO2KB.mjs} +46 -6
  35. package/dist/chunk-JRBDO2KB.mjs.map +1 -0
  36. package/dist/{chunk-NICXSHAT.mjs → chunk-MDQJPY3T.mjs} +8 -6
  37. package/dist/chunk-MDQJPY3T.mjs.map +1 -0
  38. package/dist/{chunk-JQTSEI3Z.mjs → chunk-NO4WZCAH.mjs} +3 -3
  39. package/dist/chunk-NO4WZCAH.mjs.map +1 -0
  40. package/dist/{chunk-FUODTTIA.mjs → chunk-PSEQ6QPH.mjs} +621 -108
  41. package/dist/chunk-PSEQ6QPH.mjs.map +1 -0
  42. package/dist/{chunk-33XZFTQU.mjs → chunk-S5UE2T5P.mjs} +48 -6
  43. package/dist/chunk-S5UE2T5P.mjs.map +1 -0
  44. package/dist/components/directional-light.d.ts +2 -2
  45. package/dist/components/dynamic-resolution.d.ts +15 -0
  46. package/dist/components/dynamic-resolution.d.ts.map +1 -0
  47. package/dist/components/index.d.ts +1 -0
  48. package/dist/components/index.d.ts.map +1 -1
  49. package/dist/components/light-helpers.d.ts.map +1 -1
  50. package/dist/components/reflection-probe.d.ts +1 -0
  51. package/dist/components/reflection-probe.d.ts.map +1 -1
  52. package/dist/components/skylight.d.ts +4 -1
  53. package/dist/components/skylight.d.ts.map +1 -1
  54. package/dist/construct-renderer.mjs +2172 -796
  55. package/dist/construct-renderer.mjs.map +1 -1
  56. package/dist/device/device-scope.d.ts +2 -0
  57. package/dist/device/device-scope.d.ts.map +1 -1
  58. package/dist/device/gpu-residency.d.ts +2 -2
  59. package/dist/device/gpu-residency.d.ts.map +1 -1
  60. package/dist/dynamic-geometry.d.ts.map +1 -1
  61. package/dist/environment/background.d.ts +3 -2
  62. package/dist/environment/background.d.ts.map +1 -1
  63. package/dist/environment/ibl.d.ts +11 -0
  64. package/dist/environment/ibl.d.ts.map +1 -0
  65. package/dist/environment/storage.d.ts +14 -0
  66. package/dist/environment/storage.d.ts.map +1 -0
  67. package/dist/errors/gpu-driven.d.ts +2 -2
  68. package/dist/errors/gpu-driven.d.ts.map +1 -1
  69. package/dist/errors/render.d.ts +35 -1
  70. package/dist/errors/render.d.ts.map +1 -1
  71. package/dist/extract/camera.d.ts.map +1 -1
  72. package/dist/extract/contracts.d.ts +7 -0
  73. package/dist/extract/contracts.d.ts.map +1 -1
  74. package/dist/extract/gpu-driven.d.ts +18 -1
  75. package/dist/extract/gpu-driven.d.ts.map +1 -1
  76. package/dist/gpu-driven/batch-topology.d.ts.map +1 -1
  77. package/dist/gpu-driven/material-artifacts.d.ts +24 -0
  78. package/dist/gpu-driven/material-artifacts.d.ts.map +1 -0
  79. package/dist/gpu-driven/material-bindings.d.ts +7 -0
  80. package/dist/gpu-driven/material-bindings.d.ts.map +1 -0
  81. package/dist/gpu-driven/prepared-draw.d.ts +2 -0
  82. package/dist/gpu-driven/prepared-draw.d.ts.map +1 -1
  83. package/dist/gpu-driven/production-raster.d.ts +27 -6
  84. package/dist/gpu-driven/production-raster.d.ts.map +1 -1
  85. package/dist/gpu-resource.d.ts +5 -2
  86. package/dist/gpu-resource.d.ts.map +1 -1
  87. package/dist/gpu-scene-schema.d.ts.map +1 -1
  88. package/dist/gpu-scene.d.ts.map +1 -1
  89. package/dist/hdrp-buffers.d.ts +3 -0
  90. package/dist/hdrp-buffers.d.ts.map +1 -1
  91. package/dist/ibl/IblPipelineCache.d.ts +2 -0
  92. package/dist/ibl/IblPipelineCache.d.ts.map +1 -1
  93. package/dist/ibl/skylight-bind-group.d.ts +3 -1
  94. package/dist/ibl/skylight-bind-group.d.ts.map +1 -1
  95. package/dist/index.d.ts +83 -81
  96. package/dist/index.d.ts.map +1 -1
  97. package/dist/index.mjs +7 -5
  98. package/dist/index.mjs.map +1 -1
  99. package/dist/inspection-types.d.ts +16 -1
  100. package/dist/inspection-types.d.ts.map +1 -1
  101. package/dist/internal.mjs +6 -6
  102. package/dist/material-row.d.ts +10 -0
  103. package/dist/material-row.d.ts.map +1 -1
  104. package/dist/pbr-pipeline.d.ts +3 -1
  105. package/dist/pbr-pipeline.d.ts.map +1 -1
  106. package/dist/pipeline/render-extent.d.ts +51 -0
  107. package/dist/pipeline/render-extent.d.ts.map +1 -0
  108. package/dist/pipeline/standard-build-context.d.ts +7 -0
  109. package/dist/pipeline/standard-build-context.d.ts.map +1 -0
  110. package/dist/pipeline/standard-forward-lane.d.ts +3 -2
  111. package/dist/pipeline/standard-forward-lane.d.ts.map +1 -1
  112. package/dist/pipeline/standard-pipeline.d.ts.map +1 -1
  113. package/dist/pipeline/standard-post.d.ts +1 -1
  114. package/dist/pipeline/standard-post.d.ts.map +1 -1
  115. package/dist/pipeline/standard-profile.d.ts +2 -1
  116. package/dist/pipeline/standard-profile.d.ts.map +1 -1
  117. package/dist/pipeline-builder.d.ts +3 -1
  118. package/dist/pipeline-builder.d.ts.map +1 -1
  119. package/dist/plugin.d.ts.map +1 -1
  120. package/dist/post-process-errors.d.ts +9 -2
  121. package/dist/post-process-errors.d.ts.map +1 -1
  122. package/dist/prepare/extended-lighting/resources.d.ts +3 -3
  123. package/dist/record/frame-lighting.d.ts.map +1 -1
  124. package/dist/record/frame-snapshot.d.ts +3 -8
  125. package/dist/record/frame-snapshot.d.ts.map +1 -1
  126. package/dist/record/frame.d.ts +3 -2
  127. package/dist/record/frame.d.ts.map +1 -1
  128. package/dist/record/main-pass-geometry.d.ts +7 -2
  129. package/dist/record/main-pass-geometry.d.ts.map +1 -1
  130. package/dist/record/main-pass-material.d.ts +6 -3
  131. package/dist/record/main-pass-material.d.ts.map +1 -1
  132. package/dist/record/main-pass.d.ts +2 -0
  133. package/dist/record/main-pass.d.ts.map +1 -1
  134. package/dist/record/prepared-material-bindings.d.ts.map +1 -1
  135. package/dist/record/recovery-pipeline.d.ts +9 -1
  136. package/dist/record/recovery-pipeline.d.ts.map +1 -1
  137. package/dist/record/render-context.d.ts +34 -3
  138. package/dist/record/render-context.d.ts.map +1 -1
  139. package/dist/record/shadow-pass.d.ts +2 -2
  140. package/dist/record/shadow-pass.d.ts.map +1 -1
  141. package/dist/record/typed-frame-graph.d.ts +5 -2
  142. package/dist/record/typed-frame-graph.d.ts.map +1 -1
  143. package/dist/recovery/render-system-candidate.d.ts.map +1 -1
  144. package/dist/reflection/background.d.ts +14 -0
  145. package/dist/reflection/background.d.ts.map +1 -0
  146. package/dist/reflection/filter.d.ts.map +1 -1
  147. package/dist/reflection/projection.d.ts +1 -0
  148. package/dist/reflection/projection.d.ts.map +1 -1
  149. package/dist/reflection/record-owner.d.ts +4 -2
  150. package/dist/reflection/record-owner.d.ts.map +1 -1
  151. package/dist/render-contract.d.ts +47 -32
  152. package/dist/render-contract.d.ts.map +1 -1
  153. package/dist/render-graph-primitives.d.ts.map +1 -1
  154. package/dist/render-pipeline.d.ts +17 -1
  155. package/dist/render-pipeline.d.ts.map +1 -1
  156. package/dist/render-system-extract-tail.d.ts +9 -2
  157. package/dist/render-system-extract-tail.d.ts.map +1 -1
  158. package/dist/render-system-extract.d.ts +29 -2
  159. package/dist/render-system-extract.d.ts.map +1 -1
  160. package/dist/render-system.d.ts.map +1 -1
  161. package/dist/scene/render-scene.d.ts +2 -0
  162. package/dist/scene/render-scene.d.ts.map +1 -1
  163. package/dist/ssao-config.d.ts +8 -6
  164. package/dist/ssao-config.d.ts.map +1 -1
  165. package/dist/ssr/graph.d.ts.map +1 -1
  166. package/dist/temporal/gpu.d.ts.map +1 -1
  167. package/dist/temporal/index.mjs +5 -5
  168. package/dist/temporal/standard-scene-data.d.ts +2 -1
  169. package/dist/temporal/standard-scene-data.d.ts.map +1 -1
  170. package/dist/temporal/target-coverage-attachment.d.ts +15 -0
  171. package/dist/temporal/target-coverage-attachment.d.ts.map +1 -0
  172. package/dist/temporal/temporal-view.d.ts +6 -2
  173. package/dist/temporal/temporal-view.d.ts.map +1 -1
  174. package/dist/temporal/view.d.ts +6 -0
  175. package/dist/temporal/view.d.ts.map +1 -1
  176. package/dist/typed-render-graph-primitives.d.ts +6 -0
  177. package/dist/typed-render-graph-primitives.d.ts.map +1 -1
  178. package/dist/volume/component.d.ts +1 -0
  179. package/dist/volume/component.d.ts.map +1 -1
  180. package/package.json +21 -21
  181. package/src/__tests__/capture-scene-projection.unit.test.ts +24 -0
  182. package/src/__tests__/device-feature-admission.unit.test.ts +15 -24
  183. package/src/__tests__/device-loss-fanout.unit.test.ts +43 -0
  184. package/src/__tests__/dynamic-geometry-batch.unit.test.ts +157 -0
  185. package/src/__tests__/dynamic-geometry.unit.test.ts +36 -0
  186. package/src/__tests__/dynamic-resolution-plugin.integration.test.ts +81 -0
  187. package/src/__tests__/factory-contract.integration.test.ts +164 -1
  188. package/src/__tests__/frame-observation.contract.test.ts +21 -0
  189. package/src/__tests__/gpu-driven-baseline.characterization.test.ts +1 -1
  190. package/src/__tests__/gpu-driven-batch-topology-pbr.unit.test.ts +20 -1
  191. package/src/__tests__/gpu-driven-lod-cache.unit.test.ts +0 -3
  192. package/src/__tests__/gpu-driven-mesh-world-identity.unit.test.ts +0 -3
  193. package/src/__tests__/gpu-driven-pbr.dawn.test.ts +11 -6
  194. package/src/__tests__/gpu-driven-production.integration.test.ts +13 -25
  195. package/src/__tests__/gpu-driven-view.unit.test.ts +1 -0
  196. package/src/__tests__/gpu-pass-timing-browser-runner.ts +15 -0
  197. package/src/__tests__/gpu-pass-timing.browser.test.ts +14 -1
  198. package/src/__tests__/gpu-resource-scope.unit.test.ts +71 -0
  199. package/src/__tests__/gpu-scene.unit.test.ts +55 -1
  200. package/src/__tests__/materials-standard-contract.unit.test.ts +5 -1
  201. package/src/__tests__/mesh-submission-lifetime.unit.test.ts +8 -0
  202. package/src/__tests__/morph-neutral-admission.unit.test.ts +19 -0
  203. package/src/__tests__/physical-clearcoat.integration.test.ts +6 -1
  204. package/src/__tests__/post-process-error-policy-owner.unit.test.ts +6 -5
  205. package/src/__tests__/prepared-gpu-driven-pbr.integration.test.ts +216 -5
  206. package/src/__tests__/reflection-fallback-async-publication.unit.test.ts +68 -1
  207. package/src/__tests__/reflection-probe-authoring.unit.test.ts +12 -10
  208. package/src/__tests__/reflection-probe-box.dawn.test.ts +71 -0
  209. package/src/__tests__/reflection-probe-filter.unit.test.ts +9 -0
  210. package/src/__tests__/reflection-probe-orientation.dawn.test.ts +294 -0
  211. package/src/__tests__/reflection-probe-record-owner.characterization.unit.test.ts +5 -15
  212. package/src/__tests__/reflection-probe-updates.unit.test.ts +129 -0
  213. package/src/__tests__/render-error-code-owner.test-d.ts +3 -0
  214. package/src/__tests__/render-error-detail-ssot.test-d.ts +5 -1
  215. package/src/__tests__/render-extent.unit.test.ts +63 -0
  216. package/src/__tests__/render-scene-projection.unit.test.ts +3 -2
  217. package/src/__tests__/renderer-factory-material-contract.unit.test.ts +173 -9
  218. package/src/__tests__/shader-manifest-fixture.ts +6 -0
  219. package/src/__tests__/skinned-shadow-caster.test.ts +8 -1
  220. package/src/__tests__/specular-environment-scale.dawn.test.ts +4 -2
  221. package/src/__tests__/ssao-config.unit.test.ts +7 -0
  222. package/src/__tests__/ssao-surface.dawn.test.ts +252 -0
  223. package/src/__tests__/ssr-cube-silhouette.dawn.test.ts +270 -0
  224. package/src/__tests__/ssr-gpu-dispatch.browser.test.ts +51 -43
  225. package/src/__tests__/ssr-gpu-dispatch.dawn.test.ts +4 -0
  226. package/src/__tests__/ssr-gpu-dispatch.ts +10 -5
  227. package/src/__tests__/ssr-graph-topology.unit.test.ts +2 -2
  228. package/src/__tests__/ssr-hiz.browser.test.ts +1 -1
  229. package/src/__tests__/ssr-hiz.dawn.test.ts +1 -1
  230. package/src/__tests__/ssr-spatial.integration.test.ts +1 -1
  231. package/src/__tests__/standard-cluster-variant-resolution.unit.test.ts +40 -0
  232. package/src/__tests__/standard-pbr-artifact-assembly.unit.test.ts +238 -1
  233. package/src/__tests__/standard-profile-oracle.unit.test.ts +27 -0
  234. package/src/__tests__/taa-coverage-edge.dawn.test.ts +6 -0
  235. package/src/__tests__/taa-neighborhood-equivalence.dawn.test.ts +5 -1
  236. package/src/__tests__/taa-stability-feedback.ts +1 -0
  237. package/src/__tests__/temporal-reset-matrix.unit.test.ts +2 -2
  238. package/src/__tests__/temporal-view.unit.test.ts +17 -0
  239. package/src/__tests__/transmission-prewarm.unit.test.ts +57 -0
  240. package/src/__tests__/volumetric-fog-stage-readback.dawn.test.ts +62 -13
  241. package/src/__tests__/volumetric-fog-topology.unit.test.ts +7 -7
  242. package/src/assembly/atmosphere-shader-prewarm.ts +3 -2
  243. package/src/assembly/device-feature-admission.ts +9 -4
  244. package/src/assembly/dynamic-geometry-host.ts +236 -163
  245. package/src/assembly/host-contract.ts +9 -0
  246. package/src/assembly/material/assembly.ts +350 -6
  247. package/src/assembly/material/pipeline-helpers.ts +100 -0
  248. package/src/assembly/material-shader-policy.ts +39 -18
  249. package/src/assembly/recovery/device-loss-fanout.ts +5 -0
  250. package/src/assembly/recovery/recovery-attempt.ts +2 -29
  251. package/src/assembly/recovery/renderer-recover.ts +6 -9
  252. package/src/assembly/renderer-facade.ts +22 -1
  253. package/src/assembly/shader-prewarm-policy.ts +14 -1
  254. package/src/assembly/webgpu-ready.ts +28 -19
  255. package/src/assembly/webgpu-renderer.ts +95 -95
  256. package/src/capture/scene-projection.ts +37 -0
  257. package/src/components/__tests__/dynamic-resolution-schema.unit.test.ts +65 -0
  258. package/src/components/__tests__/light-radius.integration.test.ts +59 -0
  259. package/src/components/directional-light.ts +3 -3
  260. package/src/components/dynamic-resolution.ts +67 -0
  261. package/src/components/index.ts +1 -0
  262. package/src/components/light-helpers.ts +6 -1
  263. package/src/components/reflection-probe.ts +1 -0
  264. package/src/components/skylight.ts +4 -1
  265. package/src/device/device-scope.ts +13 -7
  266. package/src/device/gpu-residency.ts +11 -11
  267. package/src/dynamic-geometry.ts +13 -8
  268. package/src/environment/background.ts +30 -12
  269. package/src/environment/ibl.ts +211 -0
  270. package/src/environment/storage.ts +63 -0
  271. package/src/errors/gpu-driven.ts +10 -3
  272. package/src/errors/render.ts +64 -0
  273. package/src/extract/camera.ts +12 -1
  274. package/src/extract/contracts.ts +10 -0
  275. package/src/extract/gpu-driven.ts +72 -17
  276. package/src/gpu-driven/batch-topology.ts +33 -11
  277. package/src/gpu-driven/material-artifacts.ts +179 -0
  278. package/src/gpu-driven/material-bindings.ts +41 -0
  279. package/src/gpu-driven/prepared-draw.ts +13 -2
  280. package/src/gpu-driven/production-raster.ts +681 -164
  281. package/src/gpu-resource.ts +21 -2
  282. package/src/gpu-scene-schema.ts +11 -2
  283. package/src/gpu-scene.ts +14 -3
  284. package/src/hdrp-buffers.ts +69 -0
  285. package/src/ibl/IblPipelineCache.ts +5 -0
  286. package/src/ibl/skylight-bind-group.ts +27 -17
  287. package/src/index.ts +92 -81
  288. package/src/inspection-types.ts +16 -1
  289. package/src/material-row.ts +60 -11
  290. package/src/pbr-pipeline.ts +13 -2
  291. package/src/pipeline/render-extent.ts +111 -0
  292. package/src/pipeline/standard-build-context.ts +7 -0
  293. package/src/pipeline/standard-forward-lane.ts +41 -24
  294. package/src/pipeline/standard-pipeline.ts +47 -18
  295. package/src/pipeline/standard-post.ts +4 -0
  296. package/src/pipeline/standard-profile.ts +2 -1
  297. package/src/pipeline-builder.ts +12 -3
  298. package/src/plugin.ts +4 -0
  299. package/src/post-process-errors.ts +26 -18
  300. package/src/prepare/__tests__/extended-lighting-capability.unit.test.ts +2 -2
  301. package/src/prepare/extended-lighting/resources.ts +3 -3
  302. package/src/record/__tests__/main-pass-geometry.unit.test.ts +68 -0
  303. package/src/record/__tests__/material-bg-cache.unit.test.ts +45 -0
  304. package/src/record/__tests__/material-slot-plan.unit.test.ts +9 -0
  305. package/src/record/__tests__/recovery-pipeline.unit.test.ts +47 -1
  306. package/src/record/__tests__/sprite-material-abi.unit.test.ts +7 -3
  307. package/src/record/__tests__/temporal-payload.unit.test.ts +2 -0
  308. package/src/record/frame-lighting.ts +3 -1
  309. package/src/record/frame-snapshot.ts +13 -11
  310. package/src/record/frame.ts +150 -74
  311. package/src/record/main-pass-geometry.ts +60 -9
  312. package/src/record/main-pass-material.ts +47 -19
  313. package/src/record/main-pass.ts +63 -4
  314. package/src/record/prepared-material-bindings.ts +4 -0
  315. package/src/record/recovery-pipeline.ts +56 -0
  316. package/src/record/render-context.ts +34 -3
  317. package/src/record/shadow-pass.ts +187 -50
  318. package/src/record/typed-frame-graph.ts +60 -3
  319. package/src/record/view-ubo.ts +1 -1
  320. package/src/recovery/render-system-candidate.ts +54 -11
  321. package/src/reflection/background.ts +151 -0
  322. package/src/reflection/filter.ts +3 -0
  323. package/src/reflection/projection.ts +16 -6
  324. package/src/reflection/record-owner.ts +282 -86
  325. package/src/render-contract.ts +50 -32
  326. package/src/render-graph-primitives.ts +28 -3
  327. package/src/render-pipeline.ts +20 -1
  328. package/src/render-system-extract-tail.ts +23 -3
  329. package/src/render-system-extract.ts +127 -42
  330. package/src/render-system.ts +35 -7
  331. package/src/scene/render-scene.ts +8 -0
  332. package/src/ssao-config.ts +25 -8
  333. package/src/ssr/graph.ts +78 -58
  334. package/src/temporal/gpu.ts +5 -0
  335. package/src/temporal/standard-scene-data.ts +7 -1
  336. package/src/temporal/target-coverage-attachment.ts +72 -0
  337. package/src/temporal/temporal-view.ts +10 -4
  338. package/src/temporal/view.ts +12 -2
  339. package/src/transmission/__tests__/standard-transmission.dawn.test.ts +24 -9
  340. package/src/typed-render-graph-primitives.ts +38 -0
  341. package/src/volume/component.ts +1 -0
  342. package/src/volume/passes.ts +3 -3
  343. package/dist/chunk-33XZFTQU.mjs.map +0 -1
  344. package/dist/chunk-BQVQOQJH.mjs.map +0 -1
  345. package/dist/chunk-BTWH7BP4.mjs.map +0 -1
  346. package/dist/chunk-FUODTTIA.mjs.map +0 -1
  347. package/dist/chunk-JQTSEI3Z.mjs.map +0 -1
  348. package/dist/chunk-NICXSHAT.mjs.map +0 -1
  349. package/dist/chunk-NRNXBLIJ.mjs.map +0 -1
  350. package/dist/chunk-S4DNKQYQ.mjs.map +0 -1
@@ -12,7 +12,7 @@ const device = {
12
12
  samplerAliasing: true,
13
13
  } as RhiCaps,
14
14
  limits: {
15
- maxSampledTexturesPerShaderStage: 20,
15
+ maxSampledTexturesPerShaderStage: 21,
16
16
  maxTextureDimension2D: 4096,
17
17
  maxTextureArrayLayers: 32,
18
18
  maxUniformBuffersPerShaderStage: 12,
@@ -50,7 +50,7 @@ describe('extended lighting capability admission', () => {
50
50
  expect(deriveExtendedLightingCapability(limited)).toEqual({
51
51
  admitted: false,
52
52
  topology: 'extendedLighting',
53
- reason: 'maxSampledTexturesPerShaderStage 16 < 20',
53
+ reason: 'maxSampledTexturesPerShaderStage 16 < 21',
54
54
  });
55
55
  });
56
56
  });
@@ -19,13 +19,13 @@ export const COOKIE_SLICE_SIZE = 256;
19
19
  export const COOKIE_MATRIX_BYTES = 32 * 16 * Float32Array.BYTES_PER_ELEMENT;
20
20
  /**
21
21
  * Minimum per-stage sampled-texture limit for the shared PBR + extended-
22
- * lighting pipeline-layout topology. The current BGL closure reserves 18
23
- * sampled textures for the URP path and 20 for the HDRP/Probe path after the
22
+ * lighting pipeline-layout topology. The current BGL closure reserves 19
23
+ * sampled textures for the URP path and 21 for the HDRP/Probe path after the
24
24
  * material IBL and transmission injections; WebGPU validates this pipeline-
25
25
  * layout count even when a compiled shader variant does not read every
26
26
  * optional entry.
27
27
  */
28
- export const EXTENDED_LIGHTING_REQUIRED_SAMPLED_TEXTURES = 20;
28
+ export const EXTENDED_LIGHTING_REQUIRED_SAMPLED_TEXTURES = 21;
29
29
 
30
30
  /**
31
31
  * Keep shader-variant selection and resource admission on one capability fact.
@@ -1,7 +1,9 @@
1
1
  import { describe, expect, it } from 'vitest';
2
+ import type { DispatchEntry } from '../../render-system-extract';
2
3
  import {
3
4
  geometryRenderStateForPass,
4
5
  requestsStandardTransmissionVariant,
6
+ sameOpaqueTemporalDraw,
5
7
  } from '../main-pass-geometry';
6
8
 
7
9
  describe('geometry pass render state', () => {
@@ -70,3 +72,69 @@ describe('Standard transmission variant selection', () => {
70
72
  ).toBe(false);
71
73
  });
72
74
  });
75
+
76
+ describe('temporal projection of multipass materials', () => {
77
+ const forward: DispatchEntry = {
78
+ entityIndex: 0,
79
+ materialHandle: 1,
80
+ renderableIndex: 0,
81
+ passIndex: 0,
82
+ queue: 2000,
83
+ layer: 0,
84
+ tags: { LightMode: 'Forward' },
85
+ renderState: { cullMode: 'back' },
86
+ defines: undefined,
87
+ vertexEntry: 'vs_main',
88
+ fragmentEntry: 'fs_forward',
89
+ materialShaderId: 'forgeax::default-standard-pbr',
90
+ paramSnapshot: undefined,
91
+ };
92
+ const deferred = {
93
+ ...forward,
94
+ passIndex: 1,
95
+ tags: { LightMode: 'Deferred' },
96
+ fragmentEntry: 'fs_gbuffer',
97
+ };
98
+ it('projects identical opaque Forward and Deferred geometry only once', () => {
99
+ expect(sameOpaqueTemporalDraw(forward, deferred)).toBe(true);
100
+ const surface = {
101
+ ...forward,
102
+ materialShaderId: 'generated::surface',
103
+ tags: {
104
+ LightMode: 'Forward',
105
+ SurfaceKind: 'standard',
106
+ SurfaceModule: 'author::surface',
107
+ },
108
+ };
109
+ expect(
110
+ sameOpaqueTemporalDraw(surface, {
111
+ ...surface,
112
+ tags: { ...surface.tags, LightMode: 'Deferred' },
113
+ }),
114
+ ).toBe(true);
115
+ const fullCustom = { ...forward, materialShaderId: 'custom::full' };
116
+ expect(sameOpaqueTemporalDraw(fullCustom, fullCustom)).toBe(false);
117
+ });
118
+ it('preserves different shader, culling, stencil and blending semantics', () => {
119
+ expect(sameOpaqueTemporalDraw(forward, { ...deferred, materialShaderId: 'other' })).toBe(false);
120
+ expect(
121
+ sameOpaqueTemporalDraw(forward, { ...deferred, renderState: { cullMode: 'front' } }),
122
+ ).toBe(false);
123
+ expect(sameOpaqueTemporalDraw(forward, { ...deferred, stencilReference: 1 })).toBe(false);
124
+ const blended = {
125
+ ...forward,
126
+ renderState: {
127
+ blend: {
128
+ color: { srcFactor: 'src-alpha', dstFactor: 'one-minus-src-alpha' },
129
+ alpha: { srcFactor: 'one', dstFactor: 'one-minus-src-alpha' },
130
+ },
131
+ },
132
+ } as const;
133
+ expect(sameOpaqueTemporalDraw(blended, blended)).toBe(false);
134
+ const stencil = {
135
+ ...forward,
136
+ renderState: { stencil: { passOp: 'increment-clamp' } },
137
+ } as const;
138
+ expect(sameOpaqueTemporalDraw(stencil, stencil)).toBe(false);
139
+ });
140
+ });
@@ -34,6 +34,51 @@ describe('material bind-group assembly cache', () => {
34
34
  expect(
35
35
  isMaterialBgAssemblyCacheHit(cached, material, materialBgl, newBuffer, skylightResources, 7),
36
36
  ).toBe(false);
37
+ expect(
38
+ isMaterialBgAssemblyCacheHit(
39
+ cached,
40
+ material,
41
+ materialBgl,
42
+ oldBuffer,
43
+ { ...skylightResources, skylightPrefilterView: {} as TextureView },
44
+ 7,
45
+ ),
46
+ ).toBe(false);
47
+ const sceneCached = { ...cached, sceneMaterialBuffer: oldBuffer };
48
+ expect(
49
+ isMaterialBgAssemblyCacheHit(
50
+ sceneCached,
51
+ material,
52
+ materialBgl,
53
+ oldBuffer,
54
+ skylightResources,
55
+ 7,
56
+ undefined,
57
+ oldBuffer,
58
+ ),
59
+ ).toBe(true);
60
+ expect(
61
+ isMaterialBgAssemblyCacheHit(
62
+ sceneCached,
63
+ material,
64
+ materialBgl,
65
+ oldBuffer,
66
+ skylightResources,
67
+ 7,
68
+ undefined,
69
+ newBuffer,
70
+ ),
71
+ ).toBe(false);
72
+ expect(
73
+ isMaterialBgAssemblyCacheHit(
74
+ sceneCached,
75
+ material,
76
+ materialBgl,
77
+ oldBuffer,
78
+ skylightResources,
79
+ 7,
80
+ ),
81
+ ).toBe(false);
37
82
  expect(
38
83
  isMaterialBgAssemblyCacheHit(cached, material, materialBgl, oldBuffer, skylightResources, 8),
39
84
  ).toBe(false);
@@ -52,6 +52,15 @@ describe('material slot plan', () => {
52
52
  });
53
53
  });
54
54
 
55
+ it('separates per-object probe/pass bindings while interning the same resource class', () => {
56
+ const material = {};
57
+ expect(
58
+ buildMaterialSlotPlan([[material], [material], [material]], (_, owner) =>
59
+ owner === 1 ? 'probe:1' : 'probe:0',
60
+ ),
61
+ ).toEqual({ slotIndices: [[0], [1], [0]], slots: [material, material], slotOwners: [0, 1] });
62
+ });
63
+
55
64
  it('does not merge equal-looking snapshots with distinct identities', () => {
56
65
  expect(buildMaterialSlotPlan([[{}], [{}]])).toMatchObject({
57
66
  slotIndices: [[0], [1]],
@@ -1,7 +1,10 @@
1
1
  import { deriveVertexLayoutProjection } from '@forgeax/engine-geometry';
2
2
  import { describe, expect, it } from 'vitest';
3
3
  import { makeZeroCameraFallbackSnapshot, type ValidatedRenderable } from '../frame-snapshot';
4
- import { prepareRecoveryPipelineReadiness } from '../recovery-pipeline';
4
+ import {
5
+ createRecoveryColdWorkGuard,
6
+ prepareRecoveryPipelineReadiness,
7
+ } from '../recovery-pipeline';
5
8
  import type { PipelineState, RenderSystemInternals } from '../render-context';
6
9
 
7
10
  function probeRenderable(probe: boolean): ValidatedRenderable {
@@ -94,4 +97,47 @@ describe('recovery prepared pipeline cache', () => {
94
97
  expect(standardPbr?.shader.variantSet).toContain('REFLECTION_FALLBACK_AVAILABLE=true');
95
98
  expect(standardPbr?.attachments.colorFormats).toEqual(['rgba16float', 'rgba16float']);
96
99
  });
100
+ it('allows explicit candidate uploads between recovery publication and the first draw', () => {
101
+ const guard = createRecoveryColdWorkGuard();
102
+ guard.arm();
103
+ expect(() => guard.noteUploadColdWork()).not.toThrow();
104
+ });
105
+
106
+ it('keeps the first-submit assertion across a skipped draw and releases its recording scope', () => {
107
+ const guard = createRecoveryColdWorkGuard();
108
+ guard.arm();
109
+ guard.beginFrame();
110
+ guard.endFrame();
111
+ expect(() => guard.noteUploadColdWork()).not.toThrow();
112
+ guard.beginFrame();
113
+ expect(() => guard.noteUploadColdWork()).toThrow(/cold upload/);
114
+ guard.endFrame();
115
+ expect(() => guard.noteUploadColdWork()).not.toThrow();
116
+ });
117
+
118
+ it('accepts a prepared candidate with no first-frame cold work', () => {
119
+ const guard = createRecoveryColdWorkGuard();
120
+
121
+ guard.arm();
122
+ guard.beginFrame();
123
+ expect(() => guard.finish()).not.toThrow();
124
+ expect(() => guard.finish()).not.toThrow();
125
+ });
126
+
127
+ it.each([
128
+ [
129
+ 'pipeline',
130
+ (guard: ReturnType<typeof createRecoveryColdWorkGuard>) => guard.notePipelineColdWork(),
131
+ ],
132
+ [
133
+ 'upload',
134
+ (guard: ReturnType<typeof createRecoveryColdWorkGuard>) => guard.noteUploadColdWork(),
135
+ ],
136
+ ] as const)('hard-fails a first-frame %s miss before submission', (_kind, note) => {
137
+ const guard = createRecoveryColdWorkGuard();
138
+
139
+ guard.arm();
140
+ guard.beginFrame();
141
+ expect(() => note(guard)).toThrow(/recovery first frame performed cold/);
142
+ });
97
143
  });
@@ -87,7 +87,8 @@ describe('sprite Standard material ABI', () => {
87
87
  binding: 23,
88
88
  resource: { kind: 'textureView' },
89
89
  });
90
- expect(merged).toHaveLength(24);
90
+ expect(merged).toHaveLength(25);
91
+ expect(merged.find((entry) => entry.binding === 47)?.resource.kind).toBe('textureView');
91
92
 
92
93
  const complete = [
93
94
  ...merged,
@@ -96,8 +97,11 @@ describe('sprite Standard material ABI', () => {
96
97
  resource: { kind: 'buffer' as const, value: { buffer: {} as Buffer } },
97
98
  },
98
99
  ];
99
- expect(complete).toHaveLength(25);
100
- expect(complete[24]).toMatchObject({ binding: 46, resource: { kind: 'buffer' } });
100
+ expect(complete).toHaveLength(26);
101
+ expect(complete.find((entry) => entry.binding === 46)).toMatchObject({
102
+ binding: 46,
103
+ resource: { kind: 'buffer' },
104
+ });
101
105
 
102
106
  const backdrop = {} as TextureView;
103
107
  const active = assembleMaterialWithSkylightEntries(
@@ -84,6 +84,8 @@ function temporalView(): TemporalView {
84
84
  viewId: '0:1:0',
85
85
  historyVersion: 0,
86
86
  temporalFrameIndex: 1,
87
+ internalWidth: 4,
88
+ internalHeight: 4,
87
89
  historyValid: true,
88
90
  resetReason: undefined,
89
91
  currentJitterUv: [0, 0],
@@ -58,7 +58,7 @@ import {
58
58
  ShadowAtlas,
59
59
  } from '../shadow-atlas';
60
60
  import { getOrCreateSsaoBuffers } from '../ssao-buffers';
61
- import { getSsaoParameters } from '../ssao-config';
61
+ import { getSsaoParameters, SSAO_SAMPLE_COUNTS } from '../ssao-config';
62
62
  // extendedLighting keeps Spot modifier factors on the existing light record
63
63
  // path; no additional render pass or submit owner is introduced.
64
64
  import type { BindGroupCounts, RenderFrameState } from './frame-snapshot';
@@ -1128,6 +1128,7 @@ export function writeHdrpClusterAndSsaoBuffers(
1128
1128
  profilePhase,
1129
1129
  'record/scene-state/hdrp-cluster/buffer-upload',
1130
1130
  (): Result<void, RenderError> => {
1131
+ if (frameState.installedPipelineConfig?.ssao?.enabled !== true) return ok(undefined);
1131
1132
  const ssaoBufs = getOrCreateSsaoBuffers(internals);
1132
1133
  if (ssaoBufs === null) return ok(undefined);
1133
1134
  const sProj = computeProjectionMatrix(camera);
@@ -1152,6 +1153,7 @@ export function writeHdrpClusterAndSsaoBuffers(
1152
1153
  ssaoUniformPayload[48] = parameters.intensity;
1153
1154
  ssaoUniformPayload[49] = parameters.radius;
1154
1155
  ssaoUniformPayload[50] = parameters.bias;
1156
+ ssaoUniformPayload[51] = SSAO_SAMPLE_COUNTS[parameters.quality];
1155
1157
 
1156
1158
  const ssaoUniformRes = internals.device.queue.writeBuffer(
1157
1159
  ssaoBufs.uniformBuffer,
@@ -107,6 +107,7 @@ export interface MaterialBgAssemblyCacheEntry {
107
107
  readonly materialBgl: BindGroupLayout;
108
108
  /** Buffer identity changes when the shared material capacity grows. */
109
109
  readonly materialBuffer: Buffer;
110
+ readonly sceneMaterialBuffer?: Buffer;
110
111
  readonly skylightResources: SkylightBindGroupResources;
111
112
  readonly bindGroup: BindGroup;
112
113
  }
@@ -234,10 +235,17 @@ export function validateGraphTargetCaptureReadback(input: {
234
235
  if (!allowZero && bytes.every((value) => value === 0)) {
235
236
  return { ok: false, code: 'capture-readback-empty' };
236
237
  }
237
- for (let index = 0; index + 1 < bytes.length; index += 2) {
238
- const exponent = ((bytes[index + 1] ?? 0) >>> 2) & 0x1f;
239
- if (exponent === 0x1f) return { ok: false, code: 'capture-readback-non-finite' };
238
+ const view = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);
239
+ let index = 0;
240
+ // Inspect both half-float exponents per word. DataView also preserves
241
+ // little-endian capture semantics for unaligned slices and host byte orders.
242
+ for (; index + 3 < bytes.byteLength; index += 4) {
243
+ const word = view.getUint32(index, true);
244
+ if ((word & 0x7c00) === 0x7c00 || (word & 0x7c000000) === 0x7c000000)
245
+ return { ok: false, code: 'capture-readback-non-finite' };
240
246
  }
247
+ if (index + 1 < bytes.byteLength && (view.getUint16(index, true) & 0x7c00) === 0x7c00)
248
+ return { ok: false, code: 'capture-readback-non-finite' };
241
249
  return { ok: true };
242
250
  }
243
251
 
@@ -658,14 +666,8 @@ export interface RenderFrameState {
658
666
  readonly materialBgShared: Map<string, WeakMap<object, unknown>>;
659
667
  /** Cross-frame fast path for fully-resident, immutable material snapshots. */
660
668
  readonly materialBgAssemblyCache: Map<string, MaterialBgAssemblyCacheEntry>;
661
- /**
662
- * feat-20260622-handle-to-id-allocator-elimination M1 / w2: singleton
663
- * material bind group cache (D-6). Single flat Map<variant, BindGroup>
664
- * for the one true singleton in production: shadow-material-singleton.
665
- * shadow-instances-singleton is a test fixture fiction (research F3);
666
- * no second singleton field is needed.
667
- */
668
- readonly singletonMaterialCache: Map<string, BindGroup>;
669
+ /** Opaque shadow fallback bindings follow physical resources across scene replacement. */
670
+ shadowMaterialBindGroups: WeakMap<object, unknown>;
669
671
  /**
670
672
  * Post-process bind group cache: nested WeakMap chain root shared by the
671
673
  * built-in bloom (bright / blur-H / blur-V / composite), FXAA, and HDRP SSAO