@forgeax/engine-render 0.1.20 → 0.1.23

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 (645) hide show
  1. package/README.md +365 -29
  2. package/dist/assembly/backend-contract.d.ts +13 -0
  3. package/dist/assembly/backend-contract.d.ts.map +1 -1
  4. package/dist/assembly/device-feature-admission.d.ts +18 -0
  5. package/dist/assembly/device-feature-admission.d.ts.map +1 -0
  6. package/dist/assembly/directional-shadow-inspection.d.ts +38 -0
  7. package/dist/assembly/directional-shadow-inspection.d.ts.map +1 -0
  8. package/dist/assembly/factory.d.ts +30 -19
  9. package/dist/assembly/factory.d.ts.map +1 -1
  10. package/dist/assembly/host-contract.d.ts +19 -0
  11. package/dist/assembly/host-contract.d.ts.map +1 -1
  12. package/dist/assembly/render-target-host.d.ts +46 -0
  13. package/dist/assembly/render-target-host.d.ts.map +1 -0
  14. package/dist/assets/render-asset-port.d.ts.map +1 -1
  15. package/dist/authoring.mjs +4 -1
  16. package/dist/authoring.mjs.map +1 -1
  17. package/dist/capture/cube-views.d.ts +21 -0
  18. package/dist/capture/cube-views.d.ts.map +1 -0
  19. package/dist/capture/scheduler.d.ts +54 -0
  20. package/dist/capture/scheduler.d.ts.map +1 -0
  21. package/dist/{chunk-PCHBPYML.mjs → chunk-4L3P6DT5.mjs} +2 -2
  22. package/dist/chunk-4L3P6DT5.mjs.map +1 -0
  23. package/dist/{chunk-VFPLTKCU.mjs → chunk-4NPUASZR.mjs} +15 -4
  24. package/dist/chunk-4NPUASZR.mjs.map +1 -0
  25. package/dist/chunk-DIYW3M5D.mjs +5085 -0
  26. package/dist/chunk-DIYW3M5D.mjs.map +1 -0
  27. package/dist/chunk-FBC4R44J.mjs +1003 -0
  28. package/dist/chunk-FBC4R44J.mjs.map +1 -0
  29. package/dist/{chunk-CDTWTHZR.mjs → chunk-FF7K3FSO.mjs} +474 -168
  30. package/dist/chunk-FF7K3FSO.mjs.map +1 -0
  31. package/dist/chunk-HZUPSYW7.mjs +1104 -0
  32. package/dist/chunk-HZUPSYW7.mjs.map +1 -0
  33. package/dist/{chunk-TBQJOK2L.mjs → chunk-QODA5UKU.mjs} +321 -269
  34. package/dist/chunk-QODA5UKU.mjs.map +1 -0
  35. package/dist/chunk-YALPS44A.mjs +296 -0
  36. package/dist/chunk-YALPS44A.mjs.map +1 -0
  37. package/dist/{chunk-4XINDLAY.mjs → chunk-ZUWKAZ2I.mjs} +1963 -2178
  38. package/dist/chunk-ZUWKAZ2I.mjs.map +1 -0
  39. package/dist/cluster-binner.d.ts +5 -0
  40. package/dist/cluster-binner.d.ts.map +1 -1
  41. package/dist/components/camera.d.ts +1 -0
  42. package/dist/components/camera.d.ts.map +1 -1
  43. package/dist/components/cube-camera.d.ts +20 -0
  44. package/dist/components/cube-camera.d.ts.map +1 -0
  45. package/dist/components/directional-light.d.ts +11 -2
  46. package/dist/components/directional-light.d.ts.map +1 -1
  47. package/dist/components/directional-shadow-filter.d.ts +25 -0
  48. package/dist/components/directional-shadow-filter.d.ts.map +1 -0
  49. package/dist/components/index.d.ts +5 -0
  50. package/dist/components/index.d.ts.map +1 -1
  51. package/dist/components/light-helpers.d.ts +4 -0
  52. package/dist/components/light-helpers.d.ts.map +1 -1
  53. package/dist/components/light-probe.d.ts +9 -0
  54. package/dist/components/light-probe.d.ts.map +1 -0
  55. package/dist/components/rect-area-light.d.ts +12 -0
  56. package/dist/components/rect-area-light.d.ts.map +1 -0
  57. package/dist/components/reflection-probe.d.ts +17 -0
  58. package/dist/components/reflection-probe.d.ts.map +1 -0
  59. package/dist/components/scene-instance.d.ts +4 -0
  60. package/dist/components/scene-instance.d.ts.map +1 -1
  61. package/dist/components/spot-light.d.ts +3 -0
  62. package/dist/components/spot-light.d.ts.map +1 -1
  63. package/dist/construct-renderer.mjs +14836 -9620
  64. package/dist/construct-renderer.mjs.map +1 -1
  65. package/dist/device/gpu-residency.d.ts +8 -1
  66. package/dist/device/gpu-residency.d.ts.map +1 -1
  67. package/dist/device/lifecycle-transaction.d.ts +2 -0
  68. package/dist/device/lifecycle-transaction.d.ts.map +1 -0
  69. package/dist/environment/frame.d.ts.map +1 -1
  70. package/dist/environment/lifecycle.d.ts +5 -0
  71. package/dist/environment/lifecycle.d.ts.map +1 -1
  72. package/dist/errors/gpu-driven.d.ts +26 -0
  73. package/dist/errors/gpu-driven.d.ts.map +1 -0
  74. package/dist/errors/index.d.ts +1 -0
  75. package/dist/errors/index.d.ts.map +1 -1
  76. package/dist/errors/recover.d.ts +9 -1
  77. package/dist/errors/recover.d.ts.map +1 -1
  78. package/dist/errors/render.d.ts +166 -93
  79. package/dist/errors/render.d.ts.map +1 -1
  80. package/dist/extract/directional-shadow-projection.d.ts +23 -0
  81. package/dist/extract/directional-shadow-projection.d.ts.map +1 -0
  82. package/dist/extract/environment.d.ts +14 -0
  83. package/dist/extract/environment.d.ts.map +1 -1
  84. package/dist/extract/gpu-driven.d.ts +50 -0
  85. package/dist/extract/gpu-driven.d.ts.map +1 -0
  86. package/dist/extract/visibility.d.ts.map +1 -1
  87. package/dist/features/fullscreen.d.ts.map +1 -1
  88. package/dist/features/targets.d.ts.map +1 -1
  89. package/dist/features/types.d.ts +10 -0
  90. package/dist/features/types.d.ts.map +1 -1
  91. package/dist/fullscreen-post-process-pass.d.ts +13 -2
  92. package/dist/fullscreen-post-process-pass.d.ts.map +1 -1
  93. package/dist/gpu-driven/batch-topology.d.ts +34 -0
  94. package/dist/gpu-driven/batch-topology.d.ts.map +1 -1
  95. package/dist/gpu-driven/prepared-draw.d.ts +63 -0
  96. package/dist/gpu-driven/prepared-draw.d.ts.map +1 -0
  97. package/dist/gpu-driven/production-raster.d.ts +97 -2
  98. package/dist/gpu-driven/production-raster.d.ts.map +1 -1
  99. package/dist/gpu-driven/view-gpu.d.ts +64 -1
  100. package/dist/gpu-driven/view-gpu.d.ts.map +1 -1
  101. package/dist/gpu-scene-schema.d.ts +14 -0
  102. package/dist/gpu-scene-schema.d.ts.map +1 -1
  103. package/dist/gpu-scene.d.ts +8 -1
  104. package/dist/gpu-scene.d.ts.map +1 -1
  105. package/dist/gpu-usage.d.ts +0 -1
  106. package/dist/gpu-usage.d.ts.map +1 -1
  107. package/dist/hdrp-buffers.d.ts +21 -19
  108. package/dist/hdrp-buffers.d.ts.map +1 -1
  109. package/dist/ibl/IblPipelineCache.d.ts +4 -0
  110. package/dist/ibl/IblPipelineCache.d.ts.map +1 -1
  111. package/dist/ibl/kernel-cache.d.ts +36 -0
  112. package/dist/ibl/kernel-cache.d.ts.map +1 -0
  113. package/dist/index.d.ts +39 -3
  114. package/dist/index.d.ts.map +1 -1
  115. package/dist/index.mjs +91 -6
  116. package/dist/index.mjs.map +1 -1
  117. package/dist/inspection-types.d.ts +214 -1
  118. package/dist/inspection-types.d.ts.map +1 -1
  119. package/dist/instances-derived-bounds.d.ts +50 -0
  120. package/dist/instances-derived-bounds.d.ts.map +1 -0
  121. package/dist/internal.d.ts +9 -0
  122. package/dist/internal.d.ts.map +1 -1
  123. package/dist/internal.mjs +23 -2
  124. package/dist/internal.mjs.map +1 -1
  125. package/dist/light-buffer-layout.d.ts +58 -140
  126. package/dist/light-buffer-layout.d.ts.map +1 -1
  127. package/dist/materials.d.ts.map +1 -1
  128. package/dist/mesh-material-bindings.d.ts +54 -0
  129. package/dist/mesh-material-bindings.d.ts.map +1 -1
  130. package/dist/pbr-pipeline.d.ts +38 -14
  131. package/dist/pbr-pipeline.d.ts.map +1 -1
  132. package/dist/pipeline/standard-forward-lane.d.ts +2 -1
  133. package/dist/pipeline/standard-forward-lane.d.ts.map +1 -1
  134. package/dist/pipeline/standard-lighting/errors.d.ts +4 -0
  135. package/dist/pipeline/standard-lighting/errors.d.ts.map +1 -0
  136. package/dist/pipeline/standard-lighting/graph.d.ts +24 -0
  137. package/dist/pipeline/standard-lighting/graph.d.ts.map +1 -0
  138. package/dist/pipeline/standard-lighting/inspection.d.ts +38 -0
  139. package/dist/pipeline/standard-lighting/inspection.d.ts.map +1 -0
  140. package/dist/pipeline/standard-lighting/layout.d.ts +28 -0
  141. package/dist/pipeline/standard-lighting/layout.d.ts.map +1 -0
  142. package/dist/pipeline/standard-lighting/light-frame.d.ts +33 -0
  143. package/dist/pipeline/standard-lighting/light-frame.d.ts.map +1 -0
  144. package/dist/pipeline/standard-lighting/membership.d.ts +14 -0
  145. package/dist/pipeline/standard-lighting/membership.d.ts.map +1 -0
  146. package/dist/pipeline/standard-lighting/prepare.d.ts +16 -0
  147. package/dist/pipeline/standard-lighting/prepare.d.ts.map +1 -0
  148. package/dist/pipeline/standard-lighting/topology.d.ts +45 -0
  149. package/dist/pipeline/standard-lighting/topology.d.ts.map +1 -0
  150. package/dist/pipeline/standard-lighting/transport.d.ts +36 -0
  151. package/dist/pipeline/standard-lighting/transport.d.ts.map +1 -0
  152. package/dist/pipeline/standard-pipeline.d.ts +4 -13
  153. package/dist/pipeline/standard-pipeline.d.ts.map +1 -1
  154. package/dist/pipeline/standard-post.d.ts.map +1 -1
  155. package/dist/pipeline/standard-profile.d.ts +5 -26
  156. package/dist/pipeline/standard-profile.d.ts.map +1 -1
  157. package/dist/pipeline-builder.d.ts +2 -0
  158. package/dist/pipeline-builder.d.ts.map +1 -1
  159. package/dist/pipeline-spec.d.ts +40 -7
  160. package/dist/pipeline-spec.d.ts.map +1 -1
  161. package/dist/plugin.d.ts.map +1 -1
  162. package/dist/point-shadow-inspection.d.ts +21 -0
  163. package/dist/point-shadow-inspection.d.ts.map +1 -0
  164. package/dist/prepare/extended-lighting/ltc-resources.d.ts +31 -0
  165. package/dist/prepare/extended-lighting/ltc-resources.d.ts.map +1 -0
  166. package/dist/prepare/extended-lighting/resources.d.ts +72 -0
  167. package/dist/prepare/extended-lighting/resources.d.ts.map +1 -0
  168. package/dist/prepare/extended-lighting/spot-modifiers.d.ts +42 -0
  169. package/dist/prepare/extended-lighting/spot-modifiers.d.ts.map +1 -0
  170. package/dist/prepare/extended-lighting/state.d.ts +24 -0
  171. package/dist/prepare/extended-lighting/state.d.ts.map +1 -0
  172. package/dist/record/frame-lighting.d.ts +33 -36
  173. package/dist/record/frame-lighting.d.ts.map +1 -1
  174. package/dist/record/frame-snapshot.d.ts +78 -24
  175. package/dist/record/frame-snapshot.d.ts.map +1 -1
  176. package/dist/record/frame-targets.d.ts +5 -0
  177. package/dist/record/frame-targets.d.ts.map +1 -1
  178. package/dist/record/frame.d.ts +16 -6
  179. package/dist/record/frame.d.ts.map +1 -1
  180. package/dist/record/gpu-pass-timing/contract.d.ts +96 -0
  181. package/dist/record/gpu-pass-timing/contract.d.ts.map +1 -0
  182. package/dist/record/gpu-pass-timing/errors.d.ts +18 -0
  183. package/dist/record/gpu-pass-timing/errors.d.ts.map +1 -0
  184. package/dist/record/gpu-pass-timing/index.d.ts +8 -0
  185. package/dist/record/gpu-pass-timing/index.d.ts.map +1 -0
  186. package/dist/record/gpu-pass-timing/parser.d.ts +11 -0
  187. package/dist/record/gpu-pass-timing/parser.d.ts.map +1 -0
  188. package/dist/record/gpu-pass-timing/session.d.ts +43 -0
  189. package/dist/record/gpu-pass-timing/session.d.ts.map +1 -0
  190. package/dist/record/gpu-timing.d.ts +20 -3
  191. package/dist/record/gpu-timing.d.ts.map +1 -1
  192. package/dist/record/helpers.d.ts +0 -20
  193. package/dist/record/helpers.d.ts.map +1 -1
  194. package/dist/record/main-pass-geometry.d.ts +6 -1
  195. package/dist/record/main-pass-geometry.d.ts.map +1 -1
  196. package/dist/record/main-pass-material.d.ts +25 -2
  197. package/dist/record/main-pass-material.d.ts.map +1 -1
  198. package/dist/record/main-pass-sprite-draws.d.ts.map +1 -1
  199. package/dist/record/main-pass.d.ts +2 -0
  200. package/dist/record/main-pass.d.ts.map +1 -1
  201. package/dist/record/mesh-ssbo.d.ts.map +1 -1
  202. package/dist/record/render-context.d.ts +98 -6
  203. package/dist/record/render-context.d.ts.map +1 -1
  204. package/dist/record/shadow-pass.d.ts.map +1 -1
  205. package/dist/record/skybox-post-pass.d.ts.map +1 -1
  206. package/dist/record/typed-frame-graph.d.ts +119 -4
  207. package/dist/record/typed-frame-graph.d.ts.map +1 -1
  208. package/dist/record/view-ubo.d.ts +7 -5
  209. package/dist/record/view-ubo.d.ts.map +1 -1
  210. package/dist/reflection/filter.d.ts +22 -0
  211. package/dist/reflection/filter.d.ts.map +1 -0
  212. package/dist/reflection/gpu-table.d.ts +25 -0
  213. package/dist/reflection/gpu-table.d.ts.map +1 -0
  214. package/dist/reflection/inspection.d.ts +10 -0
  215. package/dist/reflection/inspection.d.ts.map +1 -0
  216. package/dist/reflection/projection.d.ts +140 -0
  217. package/dist/reflection/projection.d.ts.map +1 -0
  218. package/dist/reflection/record-owner.d.ts +60 -0
  219. package/dist/reflection/record-owner.d.ts.map +1 -0
  220. package/dist/render-contract.d.ts +62 -14
  221. package/dist/render-contract.d.ts.map +1 -1
  222. package/dist/render-graph-primitives.d.ts +1 -0
  223. package/dist/render-graph-primitives.d.ts.map +1 -1
  224. package/dist/render-pipeline.d.ts +49 -2
  225. package/dist/render-pipeline.d.ts.map +1 -1
  226. package/dist/render-system-extract.d.ts +160 -31
  227. package/dist/render-system-extract.d.ts.map +1 -1
  228. package/dist/render-system.d.ts +28 -2
  229. package/dist/render-system.d.ts.map +1 -1
  230. package/dist/renderer.d.ts +43 -0
  231. package/dist/renderer.d.ts.map +1 -0
  232. package/dist/scene/probe-blend-record.d.ts +22 -0
  233. package/dist/scene/probe-blend-record.d.ts.map +1 -0
  234. package/dist/scene/probe-blend.d.ts +142 -0
  235. package/dist/scene/probe-blend.d.ts.map +1 -0
  236. package/dist/scene/render-scene-types.d.ts +0 -6
  237. package/dist/scene/render-scene-types.d.ts.map +1 -1
  238. package/dist/scene/render-scene.d.ts +117 -9
  239. package/dist/scene/render-scene.d.ts.map +1 -1
  240. package/dist/scene/visibility/bounds.d.ts +20 -0
  241. package/dist/scene/visibility/bounds.d.ts.map +1 -0
  242. package/dist/scene/visibility/budget.d.ts +16 -0
  243. package/dist/scene/visibility/budget.d.ts.map +1 -0
  244. package/dist/scene/visibility/facet.d.ts +73 -0
  245. package/dist/scene/visibility/facet.d.ts.map +1 -0
  246. package/dist/scene/visibility/gpu-frame-timing.d.ts +41 -0
  247. package/dist/scene/visibility/gpu-frame-timing.d.ts.map +1 -0
  248. package/dist/scene/visibility/gpu-lod.d.ts +46 -0
  249. package/dist/scene/visibility/gpu-lod.d.ts.map +1 -0
  250. package/dist/scene/visibility/inspection.d.ts +132 -0
  251. package/dist/scene/visibility/inspection.d.ts.map +1 -0
  252. package/dist/scene/visibility/lod-selector.d.ts +25 -0
  253. package/dist/scene/visibility/lod-selector.d.ts.map +1 -0
  254. package/dist/scene/visibility/occlusion-confidence.d.ts +81 -0
  255. package/dist/scene/visibility/occlusion-confidence.d.ts.map +1 -0
  256. package/dist/scene/visibility/occlusion-pass.d.ts +57 -0
  257. package/dist/scene/visibility/occlusion-pass.d.ts.map +1 -0
  258. package/dist/scene/visibility/occlusion-query-pool.d.ts +57 -0
  259. package/dist/scene/visibility/occlusion-query-pool.d.ts.map +1 -0
  260. package/dist/scene/visibility/occlusion-runtime.d.ts +96 -0
  261. package/dist/scene/visibility/occlusion-runtime.d.ts.map +1 -0
  262. package/dist/scene/visibility/types.d.ts +34 -0
  263. package/dist/scene/visibility/types.d.ts.map +1 -0
  264. package/dist/shadow-atlas.d.ts +3 -3
  265. package/dist/shadow-atlas.d.ts.map +1 -1
  266. package/dist/ssao-buffers.d.ts +3 -0
  267. package/dist/ssao-buffers.d.ts.map +1 -1
  268. package/dist/ssr/admission.d.ts +122 -0
  269. package/dist/ssr/admission.d.ts.map +1 -0
  270. package/dist/ssr/composition.d.ts +32 -0
  271. package/dist/ssr/composition.d.ts.map +1 -0
  272. package/dist/ssr/errors.d.ts +39 -0
  273. package/dist/ssr/errors.d.ts.map +1 -0
  274. package/dist/ssr/identity.d.ts +13 -0
  275. package/dist/ssr/identity.d.ts.map +1 -0
  276. package/dist/systems/skin-palette-allocator.d.ts +1 -1
  277. package/dist/targets/contracts.d.ts +66 -0
  278. package/dist/targets/contracts.d.ts.map +1 -0
  279. package/dist/targets/graph-projection.d.ts +29 -0
  280. package/dist/targets/graph-projection.d.ts.map +1 -0
  281. package/dist/targets/material-source.d.ts +34 -0
  282. package/dist/targets/material-source.d.ts.map +1 -0
  283. package/dist/targets/owner.d.ts +32 -0
  284. package/dist/targets/owner.d.ts.map +1 -0
  285. package/dist/targets/physical.d.ts +18 -0
  286. package/dist/targets/physical.d.ts.map +1 -0
  287. package/dist/targets/readback.d.ts +39 -0
  288. package/dist/targets/readback.d.ts.map +1 -0
  289. package/dist/temporal/frame-coordinator.d.ts +13 -0
  290. package/dist/temporal/frame-coordinator.d.ts.map +1 -1
  291. package/dist/temporal/frame.d.ts +2 -0
  292. package/dist/temporal/frame.d.ts.map +1 -1
  293. package/dist/temporal/index.mjs +6 -5
  294. package/dist/temporal/view.d.ts +7 -0
  295. package/dist/temporal/view.d.ts.map +1 -1
  296. package/dist/tilemap-chunk-extract-system.d.ts +1 -1
  297. package/dist/typed-render-graph-primitives.d.ts +5 -1
  298. package/dist/typed-render-graph-primitives.d.ts.map +1 -1
  299. package/dist/typed-shadow-passes.d.ts +1 -1
  300. package/dist/typed-shadow-passes.d.ts.map +1 -1
  301. package/dist/volume/passes.d.ts +9 -5
  302. package/dist/volume/passes.d.ts.map +1 -1
  303. package/package.json +20 -20
  304. package/src/__tests__/bloom-exact-zero.unit.test.ts +48 -19
  305. package/src/__tests__/bloom-lifecycle.integration.test.ts +41 -13
  306. package/src/__tests__/camera-target-consumption.unit.test.ts +53 -0
  307. package/src/__tests__/cluster-binner.unit.test.ts +35 -0
  308. package/src/__tests__/cluster-grid-default-surface.unit.test.ts +12 -2
  309. package/src/__tests__/cube-camera-scheduler.unit.test.ts +70 -0
  310. package/src/__tests__/cube-camera-single-submit.perf.test.ts +75 -0
  311. package/src/__tests__/cube-camera-view-matrices.unit.test.ts +41 -0
  312. package/src/__tests__/cube-camera-vocabulary.unit.test.ts +47 -0
  313. package/src/__tests__/cube-camera.integration.test.ts +42 -0
  314. package/src/__tests__/detached-inspection.integration.test.ts +6 -0
  315. package/src/__tests__/device-feature-admission.unit.test.ts +85 -0
  316. package/src/__tests__/direct-light-snapshot.unit.test.ts +62 -6
  317. package/src/__tests__/docs-gate-green.unit.test.ts +38 -0
  318. package/src/__tests__/environment-generation.integration.test.ts +16 -0
  319. package/src/__tests__/evidence-identity.ts +13 -0
  320. package/src/__tests__/evidence-identity.unit.test.ts +24 -0
  321. package/src/__tests__/extended-lighting-recovery.browser.test.ts +14 -0
  322. package/src/__tests__/extended-lighting-recovery.dawn.test.ts +14 -0
  323. package/src/__tests__/extended-lighting-recovery.integration.test.ts +81 -0
  324. package/src/__tests__/extended-lighting-resources.unit.test.ts +51 -0
  325. package/src/__tests__/extended-lighting-zero-feature.integration.test.ts +52 -0
  326. package/src/__tests__/factory-contract.integration.test.ts +288 -29
  327. package/src/__tests__/fog-component.unit.test.ts +67 -0
  328. package/src/__tests__/fog.integration.test.ts +86 -0
  329. package/src/__tests__/frame-observation.contract.test.ts +15 -0
  330. package/src/__tests__/fullscreen-feature-plan.unit.test.ts +37 -0
  331. package/src/__tests__/gpu-driven-batch-topology-pbr.unit.test.ts +146 -0
  332. package/src/__tests__/gpu-driven-indirect-raster-evidence.ts +10 -8
  333. package/src/__tests__/gpu-driven-indirect-raster.dawn.test.ts +18 -1
  334. package/src/__tests__/gpu-driven-production.integration.test.ts +579 -17
  335. package/src/__tests__/gpu-driven-scaling.unit.test.ts +66 -2
  336. package/src/__tests__/gpu-driven-view-gpu-evidence.ts +26 -1
  337. package/src/__tests__/gpu-driven-view-graph.integration.test.ts +101 -6
  338. package/src/__tests__/gpu-driven-view.browser.test.ts +3 -3
  339. package/src/__tests__/gpu-driven-view.dawn.test.ts +3 -3
  340. package/src/__tests__/gpu-driven-view.unit.test.ts +50 -0
  341. package/src/__tests__/gpu-lod-evidence.ts +188 -0
  342. package/src/__tests__/gpu-lod-fallback.integration.test.ts +10 -0
  343. package/src/__tests__/gpu-lod-indirect.integration.test.ts +40 -0
  344. package/src/__tests__/gpu-lod-parity.dawn.test.ts +29 -0
  345. package/src/__tests__/gpu-lod-readiness.integration.test.ts +52 -0
  346. package/src/__tests__/gpu-lod-schema.unit.test.ts +66 -0
  347. package/src/__tests__/gpu-lod-selector.unit.test.ts +28 -0
  348. package/src/__tests__/gpu-lod-silhouette.browser.test.ts +13 -0
  349. package/src/__tests__/gpu-pass-timing-browser-runner.ts +281 -0
  350. package/src/__tests__/gpu-pass-timing-coexistence.integration.test.ts +80 -0
  351. package/src/__tests__/gpu-pass-timing-contract.unit.test.ts +243 -0
  352. package/src/__tests__/gpu-pass-timing-exact-zero.unit.test.ts +131 -0
  353. package/src/__tests__/gpu-pass-timing-lifecycle.integration.test.ts +230 -0
  354. package/src/__tests__/gpu-pass-timing-observation.unit.test.ts +233 -0
  355. package/src/__tests__/gpu-pass-timing-session.unit.test.ts +438 -0
  356. package/src/__tests__/gpu-pass-timing.browser.test.ts +26 -0
  357. package/src/__tests__/gpu-pass-timing.rhi-null.unit.test.ts +125 -0
  358. package/src/__tests__/gpu-resource-store-stride.unit.test.ts +66 -1
  359. package/src/__tests__/gpu-scene.dawn.test.ts +8 -1
  360. package/src/__tests__/gpu-scene.unit.test.ts +49 -3
  361. package/src/__tests__/hdrp-group2-visibility.unit.test.ts +24 -0
  362. package/src/__tests__/instances-culling.integration.test.ts +94 -0
  363. package/src/__tests__/instances-derived-bounds.unit.test.ts +118 -0
  364. package/src/__tests__/light-buffer-layout.unit.test.ts +113 -3
  365. package/src/__tests__/light-inspection.unit.test.ts +55 -0
  366. package/src/__tests__/light-resource-error.unit.test.ts +43 -0
  367. package/src/__tests__/lighting-scene-roundtrip.integration.test.ts +109 -0
  368. package/src/__tests__/lod-bounds.unit.test.ts +42 -0
  369. package/src/__tests__/lod-cpu-lane.integration.test.ts +55 -0
  370. package/src/__tests__/lod-cpu-no-change.perf.test.ts +19 -0
  371. package/src/__tests__/lod-gpu-frame-timing.unit.test.ts +49 -0
  372. package/src/__tests__/lod-multi-view.integration.test.ts +63 -0
  373. package/src/__tests__/lod-occlusion-device-loss.integration.test.ts +27 -0
  374. package/src/__tests__/lod-occlusion-final-decision.integration.test.ts +47 -0
  375. package/src/__tests__/lod-occlusion-inspection.integration.test.ts +217 -0
  376. package/src/__tests__/lod-occlusion-inspection.schema.test-d.ts +14 -0
  377. package/src/__tests__/lod-occlusion-inspection.unit.test.ts +72 -0
  378. package/src/__tests__/lod-occlusion-visual-evidence.ts +91 -0
  379. package/src/__tests__/lod-occlusion.browser.test.ts +15 -0
  380. package/src/__tests__/lod-occlusion.dawn.test.ts +20 -0
  381. package/src/__tests__/lod-selector.profile.test.ts +35 -0
  382. package/src/__tests__/lod-selector.unit.test.ts +68 -0
  383. package/src/__tests__/lod-visibility-identity.unit.test.ts +198 -0
  384. package/src/__tests__/lod-visibility-lifecycle.integration.test.ts +132 -0
  385. package/src/__tests__/ltc-resources.unit.test.ts +32 -0
  386. package/src/__tests__/material-contract-inventory.unit.test.ts +17 -0
  387. package/src/__tests__/material-observation.integration.test.ts +101 -0
  388. package/src/__tests__/occlusion-confidence.unit.test.ts +168 -0
  389. package/src/__tests__/occlusion-invalidation.integration.test.ts +37 -0
  390. package/src/__tests__/occlusion-pass-routing.unit.test.ts +16 -0
  391. package/src/__tests__/occlusion-pass.dawn.test.ts +20 -0
  392. package/src/__tests__/occlusion-pass.integration.test.ts +43 -0
  393. package/src/__tests__/occlusion-pass.rhi-null.test.ts +22 -0
  394. package/src/__tests__/occlusion-query-pool.rhi-null.test.ts +21 -0
  395. package/src/__tests__/occlusion-query-pool.unit.test.ts +95 -0
  396. package/src/__tests__/occlusion-query-ticket.integration.test.ts +47 -0
  397. package/src/__tests__/occlusion-query.dawn.test.ts +16 -0
  398. package/src/__tests__/occlusion-query.evidence.ts +178 -0
  399. package/src/__tests__/occlusion-query.rhi-null.test.ts +31 -0
  400. package/src/__tests__/occlusion-runtime.unit.test.ts +120 -0
  401. package/src/__tests__/pbr-view-layout.unit.test.ts +16 -0
  402. package/src/__tests__/point-shadow-inspection.unit.test.ts +60 -0
  403. package/src/__tests__/prepared-gpu-driven-pbr.integration.test.ts +196 -0
  404. package/src/__tests__/probe-bindings.unit.test.ts +200 -0
  405. package/src/__tests__/probe-blend-numeric.unit.test.ts +67 -0
  406. package/src/__tests__/probe-blend-oracle.unit.test.ts +136 -0
  407. package/src/__tests__/probe-capacity.integration.test.ts +97 -0
  408. package/src/__tests__/probe-recovery.integration.test.ts +104 -0
  409. package/src/__tests__/probe-scene-dirty.integration.test.ts +211 -0
  410. package/src/__tests__/profiler-phase-catalog.test.ts +4 -1
  411. package/src/__tests__/profiler-phase-token.test.ts +1 -0
  412. package/src/__tests__/public-surface.test-d.ts +10 -0
  413. package/src/__tests__/rect-area-boundary.unit.test.ts +24 -0
  414. package/src/__tests__/reflection-fallback-graph.unit.test.ts +67 -0
  415. package/src/__tests__/reflection-fallback-inspection.unit.test.ts +77 -0
  416. package/src/__tests__/reflection-fallback-lifecycle.integration.test.ts +21 -0
  417. package/src/__tests__/reflection-fallback-projection.unit.test.ts +90 -0
  418. package/src/__tests__/reflection-fallback-source.unit.test.ts +32 -0
  419. package/src/__tests__/reflection-probe-authoring.unit.test.ts +71 -0
  420. package/src/__tests__/reflection-probe-filter.unit.test.ts +54 -0
  421. package/src/__tests__/reflection-probe-ibl-topology.unit.test.ts +45 -0
  422. package/src/__tests__/reflection-probe-owner-placement.unit.test.ts +39 -0
  423. package/src/__tests__/reflection-probe-pass-encode.integration.test.ts +101 -0
  424. package/src/__tests__/reflection-probe-performance.perf.test.ts +60 -0
  425. package/src/__tests__/reflection-probe-record-owner.characterization.unit.test.ts +120 -0
  426. package/src/__tests__/reflection-probe-recovery.integration.test.ts +55 -0
  427. package/src/__tests__/reflection-probe-selection.unit.test.ts +46 -0
  428. package/src/__tests__/render-error-code-owner.test-d.ts +19 -3
  429. package/src/__tests__/render-feature-docs.unit.test.ts +12 -7
  430. package/src/__tests__/render-graph-fallback.integration.test.ts +24 -0
  431. package/src/__tests__/render-perf/extended-lighting.bench.test.ts +66 -0
  432. package/src/__tests__/render-scene-projection.unit.test.ts +447 -18
  433. package/src/__tests__/render-target-admission.unit.test.ts +80 -0
  434. package/src/__tests__/render-target-graph-projection.unit.test.ts +102 -0
  435. package/src/__tests__/render-target-inspection.unit.test.ts +52 -0
  436. package/src/__tests__/render-target-material-source.test-d.ts +30 -0
  437. package/src/__tests__/render-target-material-source.unit.test.ts +97 -0
  438. package/src/__tests__/render-target-owner-placement.unit.test.ts +203 -0
  439. package/src/__tests__/render-target-owner.unit.test.ts +122 -0
  440. package/src/__tests__/render-target-probe-soak.perf.test.ts +94 -0
  441. package/src/__tests__/render-target-public-schema.json +107 -0
  442. package/src/__tests__/render-target-public-schema.unit.test.ts +91 -0
  443. package/src/__tests__/render-target-public-surface.test-d.ts +83 -0
  444. package/src/__tests__/render-target-readback.integration.test.ts +90 -0
  445. package/src/__tests__/render-target-recovery.integration.test.ts +85 -0
  446. package/src/__tests__/renderer-factory-material-contract.unit.test.ts +124 -0
  447. package/src/__tests__/renderer-lifecycle.integration.test.ts +14 -0
  448. package/src/__tests__/shader-stage-surface.unit.test.ts +19 -4
  449. package/src/__tests__/skin-motion-regression.unit.test.ts +154 -0
  450. package/src/__tests__/skinned-shadow-caster.test.ts +13 -4
  451. package/src/__tests__/spot-modifier-projection.unit.test.ts +70 -0
  452. package/src/__tests__/ssr-admission-matrix.integration.test.ts +206 -0
  453. package/src/__tests__/ssr-composition.unit.test.ts +46 -0
  454. package/src/__tests__/ssr-fallback-zero-work.bench.test.ts +94 -0
  455. package/src/__tests__/ssr-recovery-errors.unit.test.ts +58 -0
  456. package/src/__tests__/standard-cluster-capability.integration.test.ts +63 -0
  457. package/src/__tests__/standard-cluster-transport.unit.test.ts +121 -0
  458. package/src/__tests__/standard-cluster-variant-resolution.unit.test.ts +299 -0
  459. package/src/__tests__/standard-clustered-pipeline.unit.test.ts +15 -5
  460. package/src/__tests__/standard-lighting-inspection.integration.test.ts +138 -0
  461. package/src/__tests__/standard-lighting-ssot.unit.test.ts +18 -0
  462. package/src/__tests__/standard-lighting-write.unit.test.ts +441 -0
  463. package/src/__tests__/standard-lighting.integration.test.ts +67 -0
  464. package/src/__tests__/standard-pipeline.dawn.test.ts +206 -5
  465. package/src/__tests__/standard-pipeline.integration.test.ts +181 -150
  466. package/src/__tests__/standard-probe-binding.unit.test.ts +25 -0
  467. package/src/__tests__/standard-profile-oracle.unit.test.ts +23 -38
  468. package/src/__tests__/temporal-fallback-generation.integration.test.ts +16 -0
  469. package/src/__tests__/temporal-view.unit.test.ts +3 -3
  470. package/src/__tests__/transmission-prewarm.unit.test.ts +69 -0
  471. package/src/__tests__/typed-pipeline-topology.unit.test.ts +395 -14
  472. package/src/__tests__/urp-pipeline-targets.unit.test.ts +2 -2
  473. package/src/__tests__/visibility-budget.integration.test.ts +140 -0
  474. package/src/__tests__/visibility-budget.unit.test.ts +70 -0
  475. package/src/__tests__/visibility-extract.integration.test.ts +11 -6
  476. package/src/__tests__/visibility-resolver.unit.test.ts +15 -0
  477. package/src/__tests__/volumetric-fog-point-spot-accumulation.integration.test.ts +6 -3
  478. package/src/__tests__/volumetric-fog-stage-readback.dawn.test.ts +31 -28
  479. package/src/assembly/backend-contract.ts +13 -0
  480. package/src/assembly/device-feature-admission.ts +80 -0
  481. package/src/assembly/directional-shadow-inspection.ts +122 -0
  482. package/src/assembly/factory.ts +1411 -366
  483. package/src/assembly/host-contract.ts +35 -0
  484. package/src/assembly/render-target-host.ts +847 -0
  485. package/src/assets/asset-decoders.ts +1 -1
  486. package/src/assets/render-asset-port.ts +7 -1
  487. package/src/capture/cube-views.ts +69 -0
  488. package/src/capture/scheduler.ts +265 -0
  489. package/src/cluster-binner.ts +31 -0
  490. package/src/components/__tests__/lighting-authoring.unit.test.ts +39 -0
  491. package/src/components/__tests__/rect-area-light.unit.test.ts +33 -0
  492. package/src/components/__tests__/schema-contract.unit.test.ts +12 -0
  493. package/src/components/__tests__/schema-parity.unit.test.ts +9 -0
  494. package/src/components/camera.ts +4 -0
  495. package/src/components/cube-camera.ts +52 -0
  496. package/src/components/directional-light.ts +22 -2
  497. package/src/components/directional-shadow-filter.ts +57 -0
  498. package/src/components/index.ts +5 -0
  499. package/src/components/light-helpers.ts +133 -8
  500. package/src/components/light-probe.ts +13 -0
  501. package/src/components/rect-area-light.ts +15 -0
  502. package/src/components/reflection-probe.ts +49 -0
  503. package/src/components/scene-instance.ts +6 -0
  504. package/src/components/spot-light.ts +3 -0
  505. package/src/device/__tests__/extended-lighting-recovery.unit.test.ts +24 -0
  506. package/src/device/gpu-residency.ts +140 -9
  507. package/src/device/lifecycle-transaction.ts +12 -0
  508. package/src/environment/frame.ts +6 -24
  509. package/src/environment/lifecycle.ts +20 -1
  510. package/src/errors/gpu-driven.ts +92 -0
  511. package/src/errors/index.ts +1 -0
  512. package/src/errors/recover.ts +32 -0
  513. package/src/errors/render.ts +341 -143
  514. package/src/extract/camera.ts +3 -3
  515. package/src/extract/directional-shadow-projection.ts +61 -0
  516. package/src/extract/environment.ts +57 -0
  517. package/src/extract/gpu-driven.ts +108 -0
  518. package/src/extract/visibility.ts +2 -1
  519. package/src/features/fullscreen.ts +3 -0
  520. package/src/features/targets.ts +4 -1
  521. package/src/features/types.ts +10 -0
  522. package/src/fullscreen-post-process-pass.ts +43 -2
  523. package/src/gpu-driven/batch-topology.ts +207 -28
  524. package/src/gpu-driven/prepared-draw.ts +208 -0
  525. package/src/gpu-driven/production-raster.ts +953 -43
  526. package/src/gpu-driven/view-gpu.ts +411 -29
  527. package/src/gpu-scene-schema.ts +13 -0
  528. package/src/gpu-scene.ts +140 -64
  529. package/src/gpu-usage.ts +0 -1
  530. package/src/hdrp-buffers.ts +169 -63
  531. package/src/ibl/IblPipelineCache.ts +11 -0
  532. package/src/ibl/kernel-cache.ts +88 -0
  533. package/src/index.ts +222 -0
  534. package/src/inspection-types.ts +276 -1
  535. package/src/instances-derived-bounds.ts +171 -0
  536. package/src/internal.ts +38 -0
  537. package/src/light-buffer-layout.ts +155 -310
  538. package/src/materials.ts +16 -2
  539. package/src/mesh-material-bindings.ts +132 -0
  540. package/src/pbr-pipeline.ts +255 -60
  541. package/src/pipeline/standard-forward-lane.ts +93 -16
  542. package/src/pipeline/standard-lighting/errors.ts +6 -0
  543. package/src/pipeline/standard-lighting/graph.ts +158 -0
  544. package/src/pipeline/standard-lighting/inspection.ts +88 -0
  545. package/src/pipeline/standard-lighting/layout.ts +31 -0
  546. package/src/pipeline/standard-lighting/light-frame.ts +35 -0
  547. package/src/pipeline/standard-lighting/membership.ts +43 -0
  548. package/src/pipeline/standard-lighting/prepare.ts +37 -0
  549. package/src/pipeline/standard-lighting/topology.ts +120 -0
  550. package/src/pipeline/standard-lighting/transport.ts +78 -0
  551. package/src/pipeline/standard-pipeline.ts +124 -193
  552. package/src/pipeline/standard-post.ts +26 -7
  553. package/src/pipeline/standard-profile.ts +17 -47
  554. package/src/pipeline-builder.ts +5 -2
  555. package/src/pipeline-spec.ts +95 -21
  556. package/src/plugin.ts +4 -0
  557. package/src/point-shadow-inspection.ts +55 -0
  558. package/src/prepare/__tests__/extended-lighting-capability.unit.test.ts +56 -0
  559. package/src/prepare/extended-lighting/ltc-resources.ts +136 -0
  560. package/src/prepare/extended-lighting/resources.ts +389 -0
  561. package/src/prepare/extended-lighting/spot-modifiers.ts +194 -0
  562. package/src/prepare/extended-lighting/state.ts +92 -0
  563. package/src/record/__tests__/gpu-timing.unit.test.ts +177 -0
  564. package/src/record/__tests__/temporal-payload.unit.test.ts +64 -1
  565. package/src/record/__tests__/transparent-group2-selection.unit.test.ts +73 -0
  566. package/src/record/__tests__/typed-frame-graph-plan.unit.test.ts +20 -1
  567. package/src/record/__tests__/view-ubo-layout.unit.test.ts +40 -0
  568. package/src/record/frame-lighting.ts +591 -452
  569. package/src/record/frame-snapshot.ts +92 -39
  570. package/src/record/frame-targets.ts +17 -0
  571. package/src/record/frame.ts +662 -158
  572. package/src/record/gpu-pass-timing/contract.ts +180 -0
  573. package/src/record/gpu-pass-timing/errors.ts +34 -0
  574. package/src/record/gpu-pass-timing/index.ts +37 -0
  575. package/src/record/gpu-pass-timing/parser.ts +97 -0
  576. package/src/record/gpu-pass-timing/session.ts +938 -0
  577. package/src/record/gpu-timing.ts +112 -39
  578. package/src/record/helpers.ts +0 -58
  579. package/src/record/main-pass-geometry.ts +324 -119
  580. package/src/record/main-pass-material.ts +103 -10
  581. package/src/record/main-pass-sprite-draws.ts +99 -103
  582. package/src/record/main-pass.ts +71 -15
  583. package/src/record/mesh-ssbo.ts +47 -36
  584. package/src/record/render-context.ts +136 -3
  585. package/src/record/shadow-pass.ts +83 -68
  586. package/src/record/skybox-post-pass.ts +20 -4
  587. package/src/record/typed-frame-graph.ts +1034 -43
  588. package/src/record/view-ubo.ts +72 -47
  589. package/src/reflection/filter.ts +81 -0
  590. package/src/reflection/gpu-table.ts +44 -0
  591. package/src/reflection/inspection.ts +67 -0
  592. package/src/reflection/projection.ts +476 -0
  593. package/src/reflection/record-owner.ts +1283 -0
  594. package/src/render-contract.ts +93 -10
  595. package/src/render-graph-primitives.ts +9 -4
  596. package/src/render-pipeline.ts +122 -2
  597. package/src/render-system-extract.ts +1041 -225
  598. package/src/render-system.ts +1310 -85
  599. package/src/renderer.ts +222 -0
  600. package/src/scene/__tests__/changed-block-summary.candidate.test.ts +36 -0
  601. package/src/scene/probe-blend-record.ts +54 -0
  602. package/src/scene/probe-blend.ts +813 -0
  603. package/src/scene/render-scene-types.ts +0 -7
  604. package/src/scene/render-scene.ts +942 -171
  605. package/src/scene/visibility/bounds.ts +57 -0
  606. package/src/scene/visibility/budget.ts +40 -0
  607. package/src/scene/visibility/facet.ts +400 -0
  608. package/src/scene/visibility/gpu-frame-timing.ts +101 -0
  609. package/src/scene/visibility/gpu-lod.ts +119 -0
  610. package/src/scene/visibility/inspection.ts +313 -0
  611. package/src/scene/visibility/lod-selector.ts +84 -0
  612. package/src/scene/visibility/occlusion-confidence.ts +478 -0
  613. package/src/scene/visibility/occlusion-pass.ts +165 -0
  614. package/src/scene/visibility/occlusion-query-pool.ts +178 -0
  615. package/src/scene/visibility/occlusion-runtime.ts +672 -0
  616. package/src/scene/visibility/types.ts +50 -0
  617. package/src/shadow-atlas.ts +5 -5
  618. package/src/ssao-buffers.ts +9 -2
  619. package/src/ssr/admission.ts +451 -0
  620. package/src/ssr/composition.ts +73 -0
  621. package/src/ssr/errors.ts +76 -0
  622. package/src/ssr/identity.ts +12 -0
  623. package/src/systems/skin-palette-allocator.ts +1 -1
  624. package/src/targets/contracts.ts +182 -0
  625. package/src/targets/graph-projection.ts +169 -0
  626. package/src/targets/material-source.ts +143 -0
  627. package/src/targets/owner.ts +214 -0
  628. package/src/targets/physical.ts +18 -0
  629. package/src/targets/readback.ts +153 -0
  630. package/src/temporal/frame-coordinator.ts +26 -0
  631. package/src/temporal/frame.ts +14 -1
  632. package/src/temporal/view.ts +11 -0
  633. package/src/tilemap-chunk-extract-system.ts +4 -4
  634. package/src/transmission/__tests__/standard-transmission.dawn.test.ts +59 -20
  635. package/src/typed-render-graph-primitives.ts +53 -3
  636. package/src/typed-shadow-passes.ts +46 -40
  637. package/src/volume/passes.ts +61 -58
  638. package/dist/.tsbuildinfo +0 -1
  639. package/dist/chunk-4XINDLAY.mjs.map +0 -1
  640. package/dist/chunk-CDTWTHZR.mjs.map +0 -1
  641. package/dist/chunk-M2MP4ZOU.mjs +0 -73
  642. package/dist/chunk-M2MP4ZOU.mjs.map +0 -1
  643. package/dist/chunk-PCHBPYML.mjs.map +0 -1
  644. package/dist/chunk-TBQJOK2L.mjs.map +0 -1
  645. package/dist/chunk-VFPLTKCU.mjs.map +0 -1
@@ -1,9 +1,13 @@
1
+ import { mat4, vec3 } from '@forgeax/engine-math';
1
2
  import { RenderGraphBuilder } from '@forgeax/engine-render-graph';
2
3
  import type { RhiDevice } from '@forgeax/engine-rhi';
3
4
  import { rhi } from '@forgeax/engine-rhi-null';
4
5
  import { ok } from '@forgeax/engine-types';
5
6
  import { beforeAll, describe, expect, it } from 'vitest';
6
7
  import { createRenderSurfaceError, type RenderSurfaceExpectedError } from '../errors/render';
8
+ import { prepareStandardLighting } from '../pipeline/standard-lighting/prepare';
9
+ import { deriveStandardTopologyInput } from '../pipeline/standard-lighting/topology';
10
+ import { selectStandardClusterTransport } from '../pipeline/standard-lighting/transport';
7
11
  import { standardPipeline } from '../pipeline/standard-pipeline';
8
12
  import {
9
13
  DEFAULT_STANDARD_PROFILE,
@@ -45,8 +49,8 @@ function topology(
45
49
  },
46
50
  camera: { tonemap: 'aces-filmic', antialias: 'fxaa', bloom: 'on' },
47
51
  shadow: {
48
- mapSize: 64,
49
- cascadeCount: 1,
52
+ directional: { mapSize: 64, cascadeCount: 1 },
53
+ spotMapSize: 64,
50
54
  pointCount: 0,
51
55
  pointFaceSize: 64,
52
56
  spotCount: 0,
@@ -73,12 +77,45 @@ beforeAll(async () => {
73
77
  device = created.value;
74
78
  });
75
79
 
80
+ function standardLightingFor(resolvedTopology: RenderPipelineTopology) {
81
+ const prepared = prepareStandardLighting({
82
+ directional: undefined,
83
+ local: [{ kind: 'point', shadowed: false, position: vec3.create(0, 0, -4), range: 2 }],
84
+ view: mat4.create(),
85
+ projection: mat4.create(),
86
+ near: 0.1,
87
+ far: 100,
88
+ grid: resolvedTopology.config?.clusterGrid ?? { x: 4, y: 3, z: 4 },
89
+ lightCount: resolvedTopology.standardProfile?.lightCount ?? DEFAULT_STANDARD_PROFILE.lightCount,
90
+ renderPath: resolvedTopology.standardProfile?.renderPath ?? DEFAULT_STANDARD_PROFILE.renderPath,
91
+ });
92
+ if (!prepared.ok) return prepared;
93
+ const transport = selectStandardClusterTransport(
94
+ {
95
+ compute: resolvedTopology.lane.compute,
96
+ storageBuffer: resolvedTopology.lane.storageBuffer,
97
+ membershipPipelineReady: resolvedTopology.lane.compute,
98
+ },
99
+ prepared.value,
100
+ );
101
+ if (!transport.ok) return transport;
102
+ const standardLighting = deriveStandardTopologyInput({
103
+ prepared: prepared.value,
104
+ kind: 'clustered',
105
+ transport: transport.value,
106
+ });
107
+ return standardLighting;
108
+ }
109
+
76
110
  async function build(profile: StandardProfile, overrides?: Partial<RenderPipelineTopology>) {
77
111
  const graph = new RenderGraphBuilder<RenderPipelineFrame>();
78
112
  const resolvedTopology = topology(profile, overrides);
113
+ const standardLighting = standardLightingFor(resolvedTopology);
114
+ if (!standardLighting.ok) return standardLighting;
79
115
  const built = standardPipeline.build(
80
116
  {
81
117
  graph,
118
+ standardLighting: standardLighting.value,
82
119
  encodeTransmissionMip: ({ pass }) => pass.draw(3, 1, 0, 0),
83
120
  projectGpuDriven: () => ok(undefined),
84
121
  contributeFeatures: () => ok(undefined),
@@ -123,21 +160,31 @@ function importedTaaHistory(graph: RenderGraphBuilder<RenderPipelineFrame>) {
123
160
  async function buildTaa(profile: StandardProfile, overrides?: Partial<RenderPipelineTopology>) {
124
161
  const graph = new RenderGraphBuilder<RenderPipelineFrame>();
125
162
  const history = importedTaaHistory(graph);
163
+ const resolvedTopology = topology(profile, overrides);
164
+ const standardLighting = standardLightingFor(resolvedTopology);
165
+ if (!standardLighting.ok) return standardLighting;
126
166
  const built = standardPipeline.build(
127
167
  {
128
168
  graph,
169
+ standardLighting: standardLighting.value,
129
170
  capabilities: { rgba16floatRenderable: true },
130
171
  taaHistory: history,
131
172
  projectGpuDriven: () => ok(undefined),
132
173
  contributeFeatures: () => ok(undefined),
133
174
  },
134
- topology(profile, overrides),
175
+ resolvedTopology,
135
176
  );
136
177
  if (!built.ok) return built;
137
178
  return graph.compile({ device, surfaceSize: { width: 1, height: 1 } });
138
179
  }
139
180
 
140
181
  describe('forgeax::standard graph', () => {
182
+ it('does not admit an unsupported four-light budget', async () => {
183
+ const profile = { ...DEFAULT_STANDARD_PROFILE, lightCount: 4 } as unknown as StandardProfile;
184
+ const result = await build(profile);
185
+ expect(result.ok).toBe(false);
186
+ });
187
+
141
188
  it('keeps the last-known-good graph for each explicit surface failure', () => {
142
189
  let activeGraph = 'last-known-good';
143
190
  const failures = ['allocation', 'attachment', 'sampled-read', 'raw-endpoint'] as const;
@@ -160,9 +207,9 @@ describe('forgeax::standard graph', () => {
160
207
  });
161
208
 
162
209
  it.each([
163
- ['direct-1', { ...DEFAULT_STANDARD_PROFILE, lightCount: 1, lighting: 'direct' }],
164
- ['clustered-32', { ...DEFAULT_STANDARD_PROFILE, lightCount: 32, lighting: 'clustered' }],
165
- ['clustered-256', { ...DEFAULT_STANDARD_PROFILE, lightCount: 256, lighting: 'clustered' }],
210
+ ['forward-1', { ...DEFAULT_STANDARD_PROFILE, lightCount: 1, renderPath: 'forward' }],
211
+ ['forward-32', { ...DEFAULT_STANDARD_PROFILE, lightCount: 32, renderPath: 'forward' }],
212
+ ['deferred-256', { ...DEFAULT_STANDARD_PROFILE, lightCount: 256, renderPath: 'deferred' }],
166
213
  ] as const)('preserves the %s light lane under one identity', async (_name, profile) => {
167
214
  const result = await build(profile);
168
215
  expect(result.ok).toBe(true);
@@ -172,7 +219,7 @@ describe('forgeax::standard graph', () => {
172
219
 
173
220
  it('keeps Bloom a no-op when TAA has no active tone mapper', async () => {
174
221
  const result = await buildTaa(
175
- { ...DEFAULT_STANDARD_PROFILE, lighting: 'direct' },
222
+ { ...DEFAULT_STANDARD_PROFILE, renderPath: 'forward' },
176
223
  { camera: { tonemap: 'none', antialias: 'taa', bloom: 'on' } },
177
224
  );
178
225
  expect(result.ok).toBe(true);
@@ -187,7 +234,7 @@ describe('forgeax::standard graph', () => {
187
234
  });
188
235
 
189
236
  it('keeps shadow, lighting, post, and debug work in one ordered graph', async () => {
190
- const result = await build({ ...DEFAULT_STANDARD_PROFILE, lighting: 'clustered' });
237
+ const result = await build({ ...DEFAULT_STANDARD_PROFILE, renderPath: 'deferred' });
191
238
  expect(result.ok).toBe(true);
192
239
  if (!result.ok) return;
193
240
  const names = result.value.inspect().passes.map((pass) => pass.name);
@@ -206,15 +253,27 @@ describe('forgeax::standard graph', () => {
206
253
  }
207
254
  });
208
255
 
209
- it('routes a no-camera clear-only frame directly to the surface', async () => {
256
+ it('keeps one clustered resource layout when compute admission is unavailable', async () => {
210
257
  const result = await build(
211
- { ...DEFAULT_STANDARD_PROFILE, lighting: 'clustered' },
258
+ { ...DEFAULT_STANDARD_PROFILE, renderPath: 'forward' },
212
259
  {
213
- clearOnly: true,
214
- camera: { tonemap: 'none', antialias: 'none', bloom: 'off' },
260
+ lane: {
261
+ compute: false,
262
+ storageBuffer: true,
263
+ multisample: false,
264
+ maxColorAttachments: 4,
265
+ },
215
266
  },
216
267
  );
217
268
  expect(result.ok).toBe(true);
269
+ });
270
+
271
+ it('routes a no-camera clear-only frame directly to the surface', async () => {
272
+ const result = await build(DEFAULT_STANDARD_PROFILE, {
273
+ clearOnly: true,
274
+ camera: { tonemap: 'none', antialias: 'none', bloom: 'off' },
275
+ });
276
+ expect(result.ok).toBe(true);
218
277
  if (!result.ok) return;
219
278
  const info = result.value.inspect();
220
279
  const names = info.passes.map((pass) => pass.name);
@@ -229,9 +288,9 @@ describe('forgeax::standard graph', () => {
229
288
  expect(info.resources.map((resource) => resource.label)).not.toContain('scene-color');
230
289
  });
231
290
 
232
- it('uses the CPU/WebGL2 fallback without clustered resources', async () => {
291
+ it('refuses the clustered transport when storage is unavailable', async () => {
233
292
  const result = await build(
234
- { ...DEFAULT_STANDARD_PROFILE, lighting: 'clustered' },
293
+ { ...DEFAULT_STANDARD_PROFILE, renderPath: 'forward' },
235
294
  {
236
295
  lane: {
237
296
  compute: false,
@@ -241,27 +300,19 @@ describe('forgeax::standard graph', () => {
241
300
  },
242
301
  },
243
302
  );
244
- expect(result.ok).toBe(true);
245
- if (!result.ok) return;
246
- const names = result.value.inspect().passes.map((pass) => pass.name);
247
- expect(names).not.toContain('cluster-membership-producer');
248
- expect(result.value.inspect().resources.map((resource) => resource.label)).not.toContain(
249
- 'hdrp-light-index-list',
250
- );
303
+ expect(result.ok).toBe(false);
304
+ if (result.ok) return;
305
+ expect(result.error.code).toBe('standard-cluster-transport-unavailable');
251
306
  });
252
307
 
253
308
  it.each([
254
- ['direct', 'aces-filmic', 'fxaa'],
255
- ['direct', 'none', 'fxaa'],
256
- ['clustered', 'aces-filmic', 'fxaa'],
257
- ['clustered', 'none', 'fxaa'],
258
- ['direct', 'aces-filmic', 'none'],
259
- ['clustered', 'aces-filmic', 'none'],
260
- ] as const)('uses one explicit post-chain contract for %s/%s/%s', async (lighting, tonemap, antialias) => {
261
- const result = await build(
262
- { ...DEFAULT_STANDARD_PROFILE, lighting },
263
- { camera: { tonemap, antialias, bloom: 'on' } },
264
- );
309
+ ['aces-filmic', 'fxaa'],
310
+ ['none', 'fxaa'],
311
+ ['aces-filmic', 'none'],
312
+ ] as const)('uses one explicit post-chain contract for %s/%s', async (tonemap, antialias) => {
313
+ const result = await build(DEFAULT_STANDARD_PROFILE, {
314
+ camera: { tonemap, antialias, bloom: 'on' },
315
+ });
265
316
  expect(result.ok).toBe(true);
266
317
  if (!result.ok) return;
267
318
  const info = result.value.inspect();
@@ -281,38 +332,31 @@ describe('forgeax::standard graph', () => {
281
332
  expect(info.resources.map((resource) => resource.label)).not.toContain('ldr-color');
282
333
  });
283
334
 
284
- const routeMatrix = (['direct', 'clustered'] as const).flatMap((lighting) =>
285
- (['dual-view', 'raw-only'] as const).flatMap((surfaceKind) =>
286
- (['none', 'aces-filmic'] as const).flatMap((tonemap) =>
287
- (['none', 'fxaa'] as const).map(
288
- (antialias) => [lighting, surfaceKind, tonemap, antialias] as const,
289
- ),
290
- ),
335
+ const routeMatrix = (['dual-view', 'raw-only'] as const).flatMap((surfaceKind) =>
336
+ (['none', 'aces-filmic'] as const).flatMap((tonemap) =>
337
+ (['none', 'fxaa'] as const).map((antialias) => [surfaceKind, tonemap, antialias] as const),
291
338
  ),
292
339
  );
293
340
 
294
341
  it.each(
295
342
  routeMatrix,
296
- )('keeps the output route explicit for %s/%s/%s/%s', async (lighting, surfaceKind, tonemap, antialias) => {
343
+ )('keeps the output route explicit for %s/%s/%s', async (surfaceKind, tonemap, antialias) => {
297
344
  const rawOnly = surfaceKind === 'raw-only';
298
- const result = await build(
299
- { ...DEFAULT_STANDARD_PROFILE, lighting },
300
- {
301
- camera: { tonemap, antialias, bloom: 'off' },
302
- surface: {
303
- width: 1,
304
- height: 1,
305
- storageFormat: rawOnly ? 'rgba8unorm' : 'bgra8unorm',
306
- viewFormat: rawOnly ? 'rgba8unorm' : 'bgra8unorm-srgb',
307
- profile: rawOnly ? rawOnlyProfile : dualViewProfile,
308
- },
345
+ const result = await build(DEFAULT_STANDARD_PROFILE, {
346
+ camera: { tonemap, antialias, bloom: 'off' },
347
+ surface: {
348
+ width: 1,
349
+ height: 1,
350
+ storageFormat: rawOnly ? 'rgba8unorm' : 'bgra8unorm',
351
+ viewFormat: rawOnly ? 'rgba8unorm' : 'bgra8unorm-srgb',
352
+ profile: rawOnly ? rawOnlyProfile : dualViewProfile,
309
353
  },
310
- );
354
+ });
311
355
  expect(result.ok).toBe(true);
312
356
  if (!result.ok) return;
313
357
  const info = result.value.inspect();
314
358
  const names = info.passes.map((pass) => pass.name);
315
- const sceneLabel = lighting === 'direct' ? 'scene-color' : 'hdrp-scene-color';
359
+ const sceneLabel = 'scene-color';
316
360
  const sceneResource = info.resources.find((resource) => resource.label === sceneLabel);
317
361
  expect(sceneResource).toBeDefined();
318
362
  expect(sceneResource?.derivedUsage).toBe(0x15);
@@ -338,11 +382,10 @@ describe('forgeax::standard graph', () => {
338
382
  }
339
383
  });
340
384
 
341
- it('uses one linear target and one output transform for direct storage-buffer LDR output', async () => {
342
- const result = await build(
343
- { ...DEFAULT_STANDARD_PROFILE, lighting: 'direct' },
344
- { camera: { tonemap: 'none', antialias: 'none', bloom: 'off' } },
345
- );
385
+ it('uses one linear target and one output transform for Standard storage-buffer LDR output', async () => {
386
+ const result = await build(DEFAULT_STANDARD_PROFILE, {
387
+ camera: { tonemap: 'none', antialias: 'none', bloom: 'off' },
388
+ });
346
389
  expect(result.ok).toBe(true);
347
390
  if (!result.ok) return;
348
391
  const info = result.value.inspect();
@@ -350,47 +393,39 @@ describe('forgeax::standard graph', () => {
350
393
  expect(names).toContain('output-transform');
351
394
  expect(names).not.toContain('fxaa');
352
395
  expect(info.resources.find((resource) => resource.label === 'scene-color')).toMatchObject({
353
- descriptor: { format: 'rgba16float', domain: 'linear-ldr' },
396
+ descriptor: { format: 'rgba16float' },
397
+ derivedUsage: 0x15,
354
398
  });
355
399
  expect(info.resources.map((resource) => resource.label)).not.toContain('standard-output-color');
356
400
  expect(info.resources.map((resource) => resource.label)).not.toContain('ldr-color');
357
401
  });
358
402
 
359
- it('keeps the direct display fast path when storage buffers are unavailable', async () => {
360
- const result = await build(
361
- { ...DEFAULT_STANDARD_PROFILE, lighting: 'direct' },
362
- {
363
- camera: { tonemap: 'none', antialias: 'none', bloom: 'off' },
364
- lane: {
365
- compute: false,
366
- storageBuffer: false,
367
- multisample: false,
368
- maxColorAttachments: 4,
369
- },
403
+ it('keeps the Standard output route when storage buffers are unavailable', async () => {
404
+ const result = await build(DEFAULT_STANDARD_PROFILE, {
405
+ camera: { tonemap: 'none', antialias: 'none', bloom: 'off' },
406
+ lane: {
407
+ compute: false,
408
+ storageBuffer: false,
409
+ multisample: false,
410
+ maxColorAttachments: 4,
370
411
  },
371
- );
372
- expect(result.ok).toBe(true);
373
- if (!result.ok) return;
374
- const info = result.value.inspect();
375
- const names = info.passes.map((pass) => pass.name);
376
- expect(names).not.toContain('output-transform');
377
- expect(info.resources.map((resource) => resource.label)).not.toContain('scene-color');
412
+ });
413
+ expect(result.ok).toBe(false);
414
+ if (result.ok) return;
415
+ expect(result.error.code).toBe('standard-cluster-transport-unavailable');
378
416
  });
379
417
 
380
418
  it('uses one linear target and one output transform for raw-only no-FXAA', async () => {
381
- const result = await build(
382
- { ...DEFAULT_STANDARD_PROFILE, lighting: 'direct' },
383
- {
384
- camera: { tonemap: 'none', antialias: 'none', bloom: 'off' },
385
- surface: {
386
- width: 1,
387
- height: 1,
388
- storageFormat: 'rgba8unorm',
389
- viewFormat: 'rgba8unorm',
390
- profile: rawOnlyProfile,
391
- },
419
+ const result = await build(DEFAULT_STANDARD_PROFILE, {
420
+ camera: { tonemap: 'none', antialias: 'none', bloom: 'off' },
421
+ surface: {
422
+ width: 1,
423
+ height: 1,
424
+ storageFormat: 'rgba8unorm',
425
+ viewFormat: 'rgba8unorm',
426
+ profile: rawOnlyProfile,
392
427
  },
393
- );
428
+ });
394
429
  expect(result.ok).toBe(true);
395
430
  if (!result.ok) return;
396
431
  const info = result.value.inspect();
@@ -405,19 +440,16 @@ describe('forgeax::standard graph', () => {
405
440
  });
406
441
 
407
442
  it('keeps raw-only FXAA in one display-encoded float intermediate', async () => {
408
- const result = await build(
409
- { ...DEFAULT_STANDARD_PROFILE, lighting: 'direct' },
410
- {
411
- camera: { tonemap: 'none', antialias: 'fxaa', bloom: 'off' },
412
- surface: {
413
- width: 1,
414
- height: 1,
415
- storageFormat: 'rgba8unorm',
416
- viewFormat: 'rgba8unorm',
417
- profile: rawOnlyProfile,
418
- },
443
+ const result = await build(DEFAULT_STANDARD_PROFILE, {
444
+ camera: { tonemap: 'none', antialias: 'fxaa', bloom: 'off' },
445
+ surface: {
446
+ width: 1,
447
+ height: 1,
448
+ storageFormat: 'rgba8unorm',
449
+ viewFormat: 'rgba8unorm',
450
+ profile: rawOnlyProfile,
419
451
  },
420
- );
452
+ });
421
453
  expect(result.ok).toBe(true);
422
454
  if (!result.ok) return;
423
455
  const info = result.value.inspect();
@@ -436,20 +468,17 @@ describe('forgeax::standard graph', () => {
436
468
  'none',
437
469
  'fxaa',
438
470
  ] as const)('routes raw-only registered post effects through an encoded float input target (%s)', async (antialias) => {
439
- const result = await build(
440
- { ...DEFAULT_STANDARD_PROFILE, lighting: 'direct' },
441
- {
442
- camera: { tonemap: 'none', antialias, bloom: 'off' },
443
- config: { postEffects: ['test-effect'] },
444
- surface: {
445
- width: 1,
446
- height: 1,
447
- storageFormat: 'rgba8unorm',
448
- viewFormat: 'rgba8unorm',
449
- profile: rawOnlyProfile,
450
- },
471
+ const result = await build(DEFAULT_STANDARD_PROFILE, {
472
+ camera: { tonemap: 'none', antialias, bloom: 'off' },
473
+ config: { postEffects: ['test-effect'] },
474
+ surface: {
475
+ width: 1,
476
+ height: 1,
477
+ storageFormat: 'rgba8unorm',
478
+ viewFormat: 'rgba8unorm',
479
+ profile: rawOnlyProfile,
451
480
  },
452
- );
481
+ });
453
482
  expect(result.ok).toBe(true);
454
483
  if (!result.ok) return;
455
484
  const info = result.value.inspect();
@@ -480,18 +509,15 @@ describe('forgeax::standard graph', () => {
480
509
  });
481
510
 
482
511
  it('presents a resolved no-tone MSAA scene through the shared output boundary', async () => {
483
- const result = await build(
484
- { ...DEFAULT_STANDARD_PROFILE, lighting: 'direct' },
485
- {
486
- camera: { tonemap: 'none', antialias: 'msaa', bloom: 'off' },
487
- lane: {
488
- compute: true,
489
- storageBuffer: true,
490
- multisample: true,
491
- maxColorAttachments: 8,
492
- },
512
+ const result = await build(DEFAULT_STANDARD_PROFILE, {
513
+ camera: { tonemap: 'none', antialias: 'msaa', bloom: 'off' },
514
+ lane: {
515
+ compute: true,
516
+ storageBuffer: true,
517
+ multisample: true,
518
+ maxColorAttachments: 8,
493
519
  },
494
- );
520
+ });
495
521
  expect(result.ok).toBe(true);
496
522
  if (!result.ok) return;
497
523
  const info = result.value.inspect();
@@ -506,16 +532,20 @@ describe('forgeax::standard graph', () => {
506
532
 
507
533
  it('uses the live rgba16float capability for temporal admission', () => {
508
534
  const graph = new RenderGraphBuilder<RenderPipelineFrame>();
535
+ const resolvedTopology = topology(DEFAULT_STANDARD_PROFILE, {
536
+ camera: { tonemap: 'aces-filmic', antialias: 'taa', bloom: 'off' },
537
+ });
538
+ const standardLighting = standardLightingFor(resolvedTopology);
539
+ if (!standardLighting.ok) throw standardLighting.error;
509
540
  const built = standardPipeline.build(
510
541
  {
511
542
  graph,
543
+ standardLighting: standardLighting.value,
512
544
  capabilities: { rgba16floatRenderable: false },
513
545
  projectGpuDriven: () => ok(undefined),
514
546
  contributeFeatures: () => ok(undefined),
515
547
  },
516
- topology(DEFAULT_STANDARD_PROFILE, {
517
- camera: { tonemap: 'aces-filmic', antialias: 'taa', bloom: 'off' },
518
- }),
548
+ resolvedTopology,
519
549
  );
520
550
  expect(built.ok).toBe(false);
521
551
  if (built.ok) return;
@@ -527,21 +557,25 @@ describe('forgeax::standard graph', () => {
527
557
 
528
558
  it('fails closed when the temporal capability probe is absent', () => {
529
559
  const graph = new RenderGraphBuilder<RenderPipelineFrame>();
560
+ const resolvedTopology = topology(DEFAULT_STANDARD_PROFILE, {
561
+ surface: {
562
+ width: 1,
563
+ height: 1,
564
+ storageFormat: 'rgba16float',
565
+ viewFormat: 'rgba16float',
566
+ },
567
+ camera: { tonemap: 'aces-filmic', antialias: 'taa', bloom: 'off' },
568
+ });
569
+ const standardLighting = standardLightingFor(resolvedTopology);
570
+ if (!standardLighting.ok) throw standardLighting.error;
530
571
  const built = standardPipeline.build(
531
572
  {
532
573
  graph,
574
+ standardLighting: standardLighting.value,
533
575
  projectGpuDriven: () => ok(undefined),
534
576
  contributeFeatures: () => ok(undefined),
535
577
  },
536
- topology(DEFAULT_STANDARD_PROFILE, {
537
- surface: {
538
- width: 1,
539
- height: 1,
540
- storageFormat: 'rgba16float',
541
- viewFormat: 'rgba16float',
542
- },
543
- camera: { tonemap: 'aces-filmic', antialias: 'taa', bloom: 'off' },
544
- }),
578
+ resolvedTopology,
545
579
  );
546
580
  expect(built.ok).toBe(false);
547
581
  if (built.ok) return;
@@ -551,9 +585,9 @@ describe('forgeax::standard graph', () => {
551
585
  });
552
586
  });
553
587
 
554
- it('keeps direct and clustered transmission topology in one graph', async () => {
555
- for (const lighting of ['direct', 'clustered'] as const) {
556
- const result = await build({ ...DEFAULT_STANDARD_PROFILE, lighting }, {
588
+ it('keeps both Standard render paths on one transmission topology', async () => {
589
+ for (const renderPath of ['forward', 'deferred'] as const) {
590
+ const result = await build({ ...DEFAULT_STANDARD_PROFILE, renderPath }, {
557
591
  surface: {
558
592
  width: 8,
559
593
  height: 4,
@@ -577,7 +611,7 @@ describe('forgeax::standard graph', () => {
577
611
 
578
612
  it('uses the resolved single-sample MSAA source for the shared backdrop', async () => {
579
613
  const result = await build(
580
- { ...DEFAULT_STANDARD_PROFILE, lighting: 'direct' },
614
+ { ...DEFAULT_STANDARD_PROFILE, renderPath: 'forward' },
581
615
  {
582
616
  surface: {
583
617
  width: 8,
@@ -611,13 +645,13 @@ describe('forgeax::standard graph', () => {
611
645
  });
612
646
  });
613
647
 
614
- it('keeps the CPU fallback lane on the same transmission phase contract', async () => {
648
+ it('keeps the CPU transport on the same transmission phase contract', async () => {
615
649
  const result = await build(
616
- { ...DEFAULT_STANDARD_PROFILE, lighting: 'clustered', fallback: 'cpu-webgl2' },
650
+ { ...DEFAULT_STANDARD_PROFILE, renderPath: 'deferred' },
617
651
  {
618
652
  lane: {
619
653
  compute: false,
620
- storageBuffer: false,
654
+ storageBuffer: true,
621
655
  multisample: false,
622
656
  maxColorAttachments: 4,
623
657
  },
@@ -645,12 +679,9 @@ describe('forgeax::standard graph', () => {
645
679
  ],
646
680
  ['reversed-phase-order', (names: readonly string[]) => [...names].reverse()],
647
681
  ] as const)('dev falsifier %s rejects the two-lane phase contract', async (_name, falsify) => {
648
- const result = await build(
649
- { ...DEFAULT_STANDARD_PROFILE, lighting: 'direct' },
650
- {
651
- transmissionDemand: { activeCount: 1, needsRoughMips: false },
652
- },
653
- );
682
+ const result = await build(DEFAULT_STANDARD_PROFILE, {
683
+ transmissionDemand: { activeCount: 1, needsRoughMips: false },
684
+ });
654
685
  expect(result.ok).toBe(true);
655
686
  if (!result.ok) return;
656
687
  const names = result.value.inspect().passes.map((pass) => pass.name);
@@ -0,0 +1,25 @@
1
+ import { describe, expect, it } from 'vitest';
2
+ import { resolveReflectionProbeBinding } from '../record/frame-lighting';
3
+ import { standardReflectionProbeIndex } from '../record/main-pass';
4
+
5
+ describe('Standard scene reflection probe binding', () => {
6
+ it('maps a selected scene probe to both Standard lanes', () => {
7
+ const selection = {
8
+ kind: 'probe' as const,
9
+ worldId: 2,
10
+ entityKey: 7,
11
+ normalizedDistance: 0.25,
12
+ };
13
+ expect(resolveReflectionProbeBinding(selection)).toEqual({ probeIndex: 7, useSkylight: false });
14
+ expect(standardReflectionProbeIndex(selection)).toBe(7);
15
+ });
16
+
17
+ it('uses Skylight without a per-material probe identity', () => {
18
+ const selection = { kind: 'skylight' as const };
19
+ expect(resolveReflectionProbeBinding(selection)).toEqual({
20
+ probeIndex: undefined,
21
+ useSkylight: true,
22
+ });
23
+ expect(standardReflectionProbeIndex(selection)).toBeUndefined();
24
+ });
25
+ });
@@ -1,13 +1,20 @@
1
1
  import { describe, expect, it } from 'vitest';
2
2
  import {
3
3
  DEFAULT_STANDARD_PROFILE,
4
- resolveStandardLane,
5
4
  STANDARD_LIGHT_COUNTS,
6
5
  STANDARD_PIPELINE_ID,
7
6
  type StandardProfile,
8
7
  } from '../pipeline/standard-profile';
9
8
 
10
9
  describe('Standard profile oracle', () => {
10
+ it('requires the renderPath-only profile contract', () => {
11
+ const profile: StandardProfile = DEFAULT_STANDARD_PROFILE;
12
+ expect(profile.pipelineId).toBe('forgeax::standard');
13
+ expect(profile.renderPath).toBe('forward');
14
+ expect(profile).not.toHaveProperty('lighting');
15
+ expect(profile).not.toHaveProperty('fallback');
16
+ });
17
+
11
18
  it('keeps one identity across the supported light budgets', () => {
12
19
  expect(STANDARD_LIGHT_COUNTS).toEqual([1, 32, 256]);
13
20
  for (const lightCount of STANDARD_LIGHT_COUNTS) {
@@ -20,34 +27,21 @@ describe('Standard profile oracle', () => {
20
27
  }
21
28
  });
22
29
 
23
- it('selects direct, clustered, and CPU/WebGL2 fallback lanes from profile and caps', () => {
24
- expect(
25
- resolveStandardLane(
26
- { ...DEFAULT_STANDARD_PROFILE, lighting: 'direct' },
27
- {
28
- compute: true,
29
- storageBuffer: true,
30
- },
31
- ),
32
- ).toBe('direct');
33
- expect(
34
- resolveStandardLane(
35
- { ...DEFAULT_STANDARD_PROFILE, lighting: 'clustered' },
36
- {
37
- compute: true,
38
- storageBuffer: true,
39
- },
40
- ),
41
- ).toBe('clustered');
42
- expect(
43
- resolveStandardLane(
44
- { ...DEFAULT_STANDARD_PROFILE, lighting: 'clustered' },
45
- {
46
- compute: false,
47
- storageBuffer: false,
48
- },
49
- ),
50
- ).toBe('cpu-webgl2');
30
+ it('does not model a second lighting or fallback lane', () => {
31
+ const profile = DEFAULT_STANDARD_PROFILE as unknown as Record<string, unknown>;
32
+ expect(profile).not.toHaveProperty('lighting');
33
+ expect(profile).not.toHaveProperty('fallback');
34
+ });
35
+
36
+ it('selects only the graph path; Cluster transport is capability-derived', () => {
37
+ expect({ ...DEFAULT_STANDARD_PROFILE, renderPath: 'forward' }).toMatchObject({
38
+ pipelineId: STANDARD_PIPELINE_ID,
39
+ renderPath: 'forward',
40
+ });
41
+ expect({ ...DEFAULT_STANDARD_PROFILE, renderPath: 'deferred' }).toMatchObject({
42
+ pipelineId: STANDARD_PIPELINE_ID,
43
+ renderPath: 'deferred',
44
+ });
51
45
  });
52
46
 
53
47
  it('keeps the color-domain stage order stable for all profiles', () => {
@@ -60,13 +54,4 @@ describe('Standard profile oracle', () => {
60
54
  'present',
61
55
  ]);
62
56
  });
63
-
64
- it('keeps current-main post-processing defaults in the Standard profile', () => {
65
- expect(DEFAULT_STANDARD_PROFILE).toMatchObject({
66
- tone: 'aces-filmic',
67
- antialias: 'fxaa',
68
- bloom: true,
69
- sky: true,
70
- });
71
- });
72
57
  });