@forgeax/engine-render 0.1.27 → 0.1.29

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 (655) hide show
  1. package/README.md +842 -124
  2. package/dist/assembly/atmosphere-shader-prewarm.d.ts +6 -0
  3. package/dist/assembly/atmosphere-shader-prewarm.d.ts.map +1 -0
  4. package/dist/assembly/dynamic-geometry-host.d.ts +52 -0
  5. package/dist/assembly/dynamic-geometry-host.d.ts.map +1 -0
  6. package/dist/assembly/dynamic-geometry-runtime.d.ts +20 -0
  7. package/dist/assembly/dynamic-geometry-runtime.d.ts.map +1 -0
  8. package/dist/assembly/factory.d.ts +3 -1
  9. package/dist/assembly/factory.d.ts.map +1 -1
  10. package/dist/assembly/gpu-driven-owner.d.ts +10 -0
  11. package/dist/assembly/gpu-driven-owner.d.ts.map +1 -0
  12. package/dist/assembly/host-contract.d.ts +19 -0
  13. package/dist/assembly/host-contract.d.ts.map +1 -1
  14. package/dist/assembly/material/assembly.d.ts +7 -0
  15. package/dist/assembly/material/assembly.d.ts.map +1 -1
  16. package/dist/assembly/material-shader-policy.d.ts +3 -1
  17. package/dist/assembly/material-shader-policy.d.ts.map +1 -1
  18. package/dist/assembly/recovery/failure-location.d.ts +12 -0
  19. package/dist/assembly/recovery/failure-location.d.ts.map +1 -0
  20. package/dist/assembly/recovery/renderer-recover.d.ts +6 -4
  21. package/dist/assembly/recovery/renderer-recover.d.ts.map +1 -1
  22. package/dist/assembly/renderer-facade.d.ts.map +1 -1
  23. package/dist/assembly/renderer-feature-inspection.d.ts +5 -0
  24. package/dist/assembly/renderer-feature-inspection.d.ts.map +1 -0
  25. package/dist/assembly/renderer-frame-transaction.d.ts +19 -0
  26. package/dist/assembly/renderer-frame-transaction.d.ts.map +1 -1
  27. package/dist/assembly/renderer-helpers.d.ts +3 -0
  28. package/dist/assembly/renderer-helpers.d.ts.map +1 -1
  29. package/dist/assembly/renderer-inspection.d.ts +4 -0
  30. package/dist/assembly/renderer-inspection.d.ts.map +1 -1
  31. package/dist/assembly/shader-prewarm-policy.d.ts +6 -0
  32. package/dist/assembly/shader-prewarm-policy.d.ts.map +1 -1
  33. package/dist/assembly/skin-palette-owner.d.ts +8 -0
  34. package/dist/assembly/skin-palette-owner.d.ts.map +1 -0
  35. package/dist/assembly/ssr-shader-prewarm.d.ts +6 -0
  36. package/dist/assembly/ssr-shader-prewarm.d.ts.map +1 -0
  37. package/dist/assembly/webgpu-device-loss.d.ts +15 -0
  38. package/dist/assembly/webgpu-device-loss.d.ts.map +1 -0
  39. package/dist/assembly/webgpu-pbr-ready.d.ts +38 -0
  40. package/dist/assembly/webgpu-pbr-ready.d.ts.map +1 -0
  41. package/dist/assembly/webgpu-ready-mipmap.d.ts +11 -0
  42. package/dist/assembly/webgpu-ready-mipmap.d.ts.map +1 -0
  43. package/dist/assembly/webgpu-ready.d.ts +7 -3
  44. package/dist/assembly/webgpu-ready.d.ts.map +1 -1
  45. package/dist/assembly/webgpu-renderer-bootstrap.d.ts +10 -0
  46. package/dist/assembly/webgpu-renderer-bootstrap.d.ts.map +1 -0
  47. package/dist/assembly/webgpu-renderer-contract.d.ts +62 -0
  48. package/dist/assembly/webgpu-renderer-contract.d.ts.map +1 -0
  49. package/dist/assembly/webgpu-renderer-guards.d.ts +9 -0
  50. package/dist/assembly/webgpu-renderer-guards.d.ts.map +1 -0
  51. package/dist/assembly/webgpu-renderer-observation.d.ts +6 -0
  52. package/dist/assembly/webgpu-renderer-observation.d.ts.map +1 -0
  53. package/dist/assembly/webgpu-renderer-recovery-failure.d.ts +12 -0
  54. package/dist/assembly/webgpu-renderer-recovery-failure.d.ts.map +1 -0
  55. package/dist/assembly/webgpu-renderer.d.ts +7 -141
  56. package/dist/assembly/webgpu-renderer.d.ts.map +1 -1
  57. package/dist/assembly/webgpu-vertex-layouts.d.ts +28 -84
  58. package/dist/assembly/webgpu-vertex-layouts.d.ts.map +1 -1
  59. package/dist/authoring.mjs +3 -3
  60. package/dist/{chunk-ADHHVYLW.mjs → chunk-33XZFTQU.mjs} +245 -39
  61. package/dist/chunk-33XZFTQU.mjs.map +1 -0
  62. package/dist/{chunk-GF523LHF.mjs → chunk-BLXGONR2.mjs} +30 -12
  63. package/dist/chunk-BLXGONR2.mjs.map +1 -0
  64. package/dist/{chunk-KM2NOX2I.mjs → chunk-BQVQOQJH.mjs} +958 -254
  65. package/dist/chunk-BQVQOQJH.mjs.map +1 -0
  66. package/dist/{chunk-HKXTW355.mjs → chunk-BTWH7BP4.mjs} +386 -17
  67. package/dist/chunk-BTWH7BP4.mjs.map +1 -0
  68. package/dist/{chunk-TMIASV2N.mjs → chunk-FUODTTIA.mjs} +3934 -676
  69. package/dist/chunk-FUODTTIA.mjs.map +1 -0
  70. package/dist/{chunk-FJ6P52EE.mjs → chunk-ILQ5MEZF.mjs} +3 -17
  71. package/dist/chunk-ILQ5MEZF.mjs.map +1 -0
  72. package/dist/{chunk-E34VL5VI.mjs → chunk-JQTSEI3Z.mjs} +3 -3
  73. package/dist/{chunk-E34VL5VI.mjs.map → chunk-JQTSEI3Z.mjs.map} +1 -1
  74. package/dist/{chunk-GE3SDD72.mjs → chunk-NICXSHAT.mjs} +16 -38
  75. package/dist/chunk-NICXSHAT.mjs.map +1 -0
  76. package/dist/{chunk-ZZ4YQ474.mjs → chunk-NRNXBLIJ.mjs} +577 -7
  77. package/dist/chunk-NRNXBLIJ.mjs.map +1 -0
  78. package/dist/{chunk-JDWARUOI.mjs → chunk-PA5DRJNI.mjs} +17 -3
  79. package/dist/chunk-PA5DRJNI.mjs.map +1 -0
  80. package/dist/{chunk-XDP6XE5V.mjs → chunk-S4DNKQYQ.mjs} +1118 -446
  81. package/dist/chunk-S4DNKQYQ.mjs.map +1 -0
  82. package/dist/components/camera.d.ts +62 -2
  83. package/dist/components/camera.d.ts.map +1 -1
  84. package/dist/components/index.d.ts +1 -0
  85. package/dist/components/index.d.ts.map +1 -1
  86. package/dist/components/instances.d.ts +6 -20
  87. package/dist/components/instances.d.ts.map +1 -1
  88. package/dist/components/scene-instance.d.ts +2 -1
  89. package/dist/components/scene-instance.d.ts.map +1 -1
  90. package/dist/components/screen-space-reflection.d.ts +14 -0
  91. package/dist/components/screen-space-reflection.d.ts.map +1 -0
  92. package/dist/construct-renderer.mjs +13805 -7186
  93. package/dist/construct-renderer.mjs.map +1 -1
  94. package/dist/device/gpu-residency.d.ts +11 -17
  95. package/dist/device/gpu-residency.d.ts.map +1 -1
  96. package/dist/device/mesh-residency-lifetime.d.ts +21 -0
  97. package/dist/device/mesh-residency-lifetime.d.ts.map +1 -0
  98. package/dist/dynamic-geometry.d.ts +125 -0
  99. package/dist/dynamic-geometry.d.ts.map +1 -0
  100. package/dist/environment/background.d.ts +6 -0
  101. package/dist/environment/background.d.ts.map +1 -0
  102. package/dist/errors/gpu-driven.d.ts +6 -3
  103. package/dist/errors/gpu-driven.d.ts.map +1 -1
  104. package/dist/errors/render.d.ts +7 -4
  105. package/dist/errors/render.d.ts.map +1 -1
  106. package/dist/extract/camera.d.ts.map +1 -1
  107. package/dist/extract/gpu-driven.d.ts +33 -3
  108. package/dist/extract/gpu-driven.d.ts.map +1 -1
  109. package/dist/features/host.d.ts +23 -1
  110. package/dist/features/host.d.ts.map +1 -1
  111. package/dist/features/noise-texture.d.ts +17 -0
  112. package/dist/features/noise-texture.d.ts.map +1 -0
  113. package/dist/features/plan.d.ts +83 -2
  114. package/dist/features/plan.d.ts.map +1 -1
  115. package/dist/features/prepared-gpu-work.d.ts +37 -4
  116. package/dist/features/prepared-gpu-work.d.ts.map +1 -1
  117. package/dist/features/prepared-graphics-store.d.ts.map +1 -1
  118. package/dist/features/prepared-graphics.d.ts +5 -0
  119. package/dist/features/prepared-graphics.d.ts.map +1 -1
  120. package/dist/features/render-graph-compute.d.ts +5 -3
  121. package/dist/features/render-graph-compute.d.ts.map +1 -1
  122. package/dist/features/render-graph-contribution.d.ts +11 -3
  123. package/dist/features/render-graph-contribution.d.ts.map +1 -1
  124. package/dist/features/render-graph-raster.d.ts +19 -3
  125. package/dist/features/render-graph-raster.d.ts.map +1 -1
  126. package/dist/features/types.d.ts +11 -0
  127. package/dist/features/types.d.ts.map +1 -1
  128. package/dist/fullscreen-post-process-pass.d.ts +2 -0
  129. package/dist/fullscreen-post-process-pass.d.ts.map +1 -1
  130. package/dist/gpu-driven/batch-topology.d.ts +34 -1
  131. package/dist/gpu-driven/batch-topology.d.ts.map +1 -1
  132. package/dist/gpu-driven/pbr-program.d.ts +10 -0
  133. package/dist/gpu-driven/pbr-program.d.ts.map +1 -0
  134. package/dist/gpu-driven/prepared-draw.d.ts.map +1 -1
  135. package/dist/gpu-driven/production-raster.d.ts +144 -23
  136. package/dist/gpu-driven/production-raster.d.ts.map +1 -1
  137. package/dist/gpu-driven/shadow-views.d.ts +126 -0
  138. package/dist/gpu-driven/shadow-views.d.ts.map +1 -0
  139. package/dist/gpu-driven/view-gpu.d.ts +18 -2
  140. package/dist/gpu-driven/view-gpu.d.ts.map +1 -1
  141. package/dist/gpu-scene-schema.d.ts +2 -8
  142. package/dist/gpu-scene-schema.d.ts.map +1 -1
  143. package/dist/gpu-scene.d.ts +14 -0
  144. package/dist/gpu-scene.d.ts.map +1 -1
  145. package/dist/gpu-texture-usage.d.ts +1 -0
  146. package/dist/gpu-texture-usage.d.ts.map +1 -1
  147. package/dist/hdrp-buffers.d.ts +6 -0
  148. package/dist/hdrp-buffers.d.ts.map +1 -1
  149. package/dist/ibl/frame-resources.d.ts +8 -0
  150. package/dist/ibl/frame-resources.d.ts.map +1 -0
  151. package/dist/ibl/skylight-bind-group.d.ts.map +1 -1
  152. package/dist/index.d.ts +21 -8
  153. package/dist/index.d.ts.map +1 -1
  154. package/dist/index.mjs +8 -7
  155. package/dist/index.mjs.map +1 -1
  156. package/dist/inspection-types.d.ts +164 -0
  157. package/dist/inspection-types.d.ts.map +1 -1
  158. package/dist/instances-derived-bounds.d.ts +11 -0
  159. package/dist/instances-derived-bounds.d.ts.map +1 -1
  160. package/dist/instances.d.ts +89 -44
  161. package/dist/instances.d.ts.map +1 -1
  162. package/dist/internal.d.ts +3 -0
  163. package/dist/internal.d.ts.map +1 -1
  164. package/dist/internal.mjs +118 -10
  165. package/dist/internal.mjs.map +1 -1
  166. package/dist/lifecycle.d.ts +2 -1
  167. package/dist/lifecycle.d.ts.map +1 -1
  168. package/dist/material-row.d.ts +5 -0
  169. package/dist/material-row.d.ts.map +1 -0
  170. package/dist/materials.d.ts +15 -0
  171. package/dist/materials.d.ts.map +1 -1
  172. package/dist/pbr-pipeline.d.ts +21 -5
  173. package/dist/pbr-pipeline.d.ts.map +1 -1
  174. package/dist/pipeline/standard-forward-lane.d.ts.map +1 -1
  175. package/dist/pipeline/standard-output/auto-exposure/capability.d.ts +12 -0
  176. package/dist/pipeline/standard-output/auto-exposure/capability.d.ts.map +1 -0
  177. package/dist/pipeline/standard-output/auto-exposure/gpu.d.ts +70 -0
  178. package/dist/pipeline/standard-output/auto-exposure/gpu.d.ts.map +1 -0
  179. package/dist/pipeline/standard-output/auto-exposure/graph.d.ts +75 -0
  180. package/dist/pipeline/standard-output/auto-exposure/graph.d.ts.map +1 -0
  181. package/dist/pipeline/standard-output/auto-exposure/inspection.d.ts +111 -0
  182. package/dist/pipeline/standard-output/auto-exposure/inspection.d.ts.map +1 -0
  183. package/dist/pipeline/standard-output/auto-exposure/oracle.d.ts +16 -0
  184. package/dist/pipeline/standard-output/auto-exposure/oracle.d.ts.map +1 -0
  185. package/dist/pipeline/standard-output/auto-exposure/preset.d.ts +14 -0
  186. package/dist/pipeline/standard-output/auto-exposure/preset.d.ts.map +1 -0
  187. package/dist/pipeline/standard-output/auto-exposure/state.d.ts +46 -0
  188. package/dist/pipeline/standard-output/auto-exposure/state.d.ts.map +1 -0
  189. package/dist/pipeline/standard-output/color-transform.d.ts +27 -0
  190. package/dist/pipeline/standard-output/color-transform.d.ts.map +1 -0
  191. package/dist/pipeline/standard-output/graph.d.ts +15 -0
  192. package/dist/pipeline/standard-output/graph.d.ts.map +1 -0
  193. package/dist/pipeline/standard-output/lut-admission.d.ts +29 -0
  194. package/dist/pipeline/standard-output/lut-admission.d.ts.map +1 -0
  195. package/dist/pipeline/standard-output/lut-gpu.d.ts +48 -0
  196. package/dist/pipeline/standard-output/lut-gpu.d.ts.map +1 -0
  197. package/dist/pipeline/standard-output/lut-state.d.ts +68 -0
  198. package/dist/pipeline/standard-output/lut-state.d.ts.map +1 -0
  199. package/dist/pipeline/standard-output/resources.d.ts +10 -0
  200. package/dist/pipeline/standard-output/resources.d.ts.map +1 -0
  201. package/dist/pipeline/standard-output/types.d.ts +39 -0
  202. package/dist/pipeline/standard-output/types.d.ts.map +1 -0
  203. package/dist/pipeline/standard-pipeline.d.ts.map +1 -1
  204. package/dist/pipeline/standard-post.d.ts +2 -2
  205. package/dist/pipeline/standard-post.d.ts.map +1 -1
  206. package/dist/pipeline-builder.d.ts +2 -1
  207. package/dist/pipeline-builder.d.ts.map +1 -1
  208. package/dist/pipeline-spec-types.d.ts +4 -0
  209. package/dist/pipeline-spec-types.d.ts.map +1 -1
  210. package/dist/pipeline-spec.d.ts +1 -9
  211. package/dist/pipeline-spec.d.ts.map +1 -1
  212. package/dist/points-lines/standard-owner.d.ts +1 -1
  213. package/dist/points-lines/standard-owner.d.ts.map +1 -1
  214. package/dist/prepare/prepared-graphics-resolver.d.ts +6 -1
  215. package/dist/prepare/prepared-graphics-resolver.d.ts.map +1 -1
  216. package/dist/record/dynamic-geometry-consumption.d.ts +15 -0
  217. package/dist/record/dynamic-geometry-consumption.d.ts.map +1 -0
  218. package/dist/record/frame-lighting.d.ts +3 -3
  219. package/dist/record/frame-lighting.d.ts.map +1 -1
  220. package/dist/record/frame-snapshot.d.ts +106 -5
  221. package/dist/record/frame-snapshot.d.ts.map +1 -1
  222. package/dist/record/frame-targets.d.ts.map +1 -1
  223. package/dist/record/frame.d.ts +39 -4
  224. package/dist/record/frame.d.ts.map +1 -1
  225. package/dist/record/main-pass-geometry.d.ts +7 -8
  226. package/dist/record/main-pass-geometry.d.ts.map +1 -1
  227. package/dist/record/main-pass-material.d.ts +38 -1
  228. package/dist/record/main-pass-material.d.ts.map +1 -1
  229. package/dist/record/main-pass-sprite-draws.d.ts +2 -10
  230. package/dist/record/main-pass-sprite-draws.d.ts.map +1 -1
  231. package/dist/record/main-pass.d.ts +12 -2
  232. package/dist/record/main-pass.d.ts.map +1 -1
  233. package/dist/record/mesh-ssbo.d.ts +15 -6
  234. package/dist/record/mesh-ssbo.d.ts.map +1 -1
  235. package/dist/record/prepared-material-bindings.d.ts +19 -0
  236. package/dist/record/prepared-material-bindings.d.ts.map +1 -0
  237. package/dist/record/recovery-pipeline.d.ts +2 -9
  238. package/dist/record/recovery-pipeline.d.ts.map +1 -1
  239. package/dist/record/render-context.d.ts +76 -26
  240. package/dist/record/render-context.d.ts.map +1 -1
  241. package/dist/record/shadow-pass.d.ts +62 -7
  242. package/dist/record/shadow-pass.d.ts.map +1 -1
  243. package/dist/record/skybox-post-pass.d.ts +1 -1
  244. package/dist/record/skybox-post-pass.d.ts.map +1 -1
  245. package/dist/record/typed-frame-graph.d.ts +35 -7
  246. package/dist/record/typed-frame-graph.d.ts.map +1 -1
  247. package/dist/record/view-ubo.d.ts +1 -0
  248. package/dist/record/view-ubo.d.ts.map +1 -1
  249. package/dist/recovery/render-system-candidate.d.ts +10 -2
  250. package/dist/recovery/render-system-candidate.d.ts.map +1 -1
  251. package/dist/recovery/render-system-roots.d.ts +11 -0
  252. package/dist/recovery/render-system-roots.d.ts.map +1 -0
  253. package/dist/recovery/types.d.ts +76 -0
  254. package/dist/recovery/types.d.ts.map +1 -0
  255. package/dist/reflection/record-owner.d.ts +0 -2
  256. package/dist/reflection/record-owner.d.ts.map +1 -1
  257. package/dist/render-contract.d.ts +185 -30
  258. package/dist/render-contract.d.ts.map +1 -1
  259. package/dist/render-graph-primitives.d.ts +1 -0
  260. package/dist/render-graph-primitives.d.ts.map +1 -1
  261. package/dist/render-pipeline.d.ts +64 -5
  262. package/dist/render-pipeline.d.ts.map +1 -1
  263. package/dist/render-system-extract-tail.d.ts +7 -5
  264. package/dist/render-system-extract-tail.d.ts.map +1 -1
  265. package/dist/render-system-extract.d.ts +101 -41
  266. package/dist/render-system-extract.d.ts.map +1 -1
  267. package/dist/render-system-projections.d.ts +22 -0
  268. package/dist/render-system-projections.d.ts.map +1 -0
  269. package/dist/render-system.d.ts +34 -77
  270. package/dist/render-system.d.ts.map +1 -1
  271. package/dist/scene/render-scene-types.d.ts +14 -7
  272. package/dist/scene/render-scene-types.d.ts.map +1 -1
  273. package/dist/scene/render-scene.d.ts +29 -11
  274. package/dist/scene/render-scene.d.ts.map +1 -1
  275. package/dist/scene/shadow-visibility.d.ts +5 -0
  276. package/dist/scene/shadow-visibility.d.ts.map +1 -0
  277. package/dist/ssr/admission.d.ts +70 -1
  278. package/dist/ssr/admission.d.ts.map +1 -1
  279. package/dist/ssr/compose.d.ts +13 -0
  280. package/dist/ssr/compose.d.ts.map +1 -0
  281. package/dist/ssr/errors.d.ts +35 -0
  282. package/dist/ssr/errors.d.ts.map +1 -1
  283. package/dist/ssr/graph.d.ts +60 -0
  284. package/dist/ssr/graph.d.ts.map +1 -0
  285. package/dist/ssr/history.d.ts +97 -0
  286. package/dist/ssr/history.d.ts.map +1 -0
  287. package/dist/ssr/hiz.d.ts +37 -0
  288. package/dist/ssr/hiz.d.ts.map +1 -0
  289. package/dist/ssr/inspection.d.ts +42 -0
  290. package/dist/ssr/inspection.d.ts.map +1 -0
  291. package/dist/ssr/resources.d.ts +58 -0
  292. package/dist/ssr/resources.d.ts.map +1 -0
  293. package/dist/ssr/temporal.d.ts +38 -0
  294. package/dist/ssr/temporal.d.ts.map +1 -0
  295. package/dist/systems/skin-palette-allocator.d.ts +32 -10
  296. package/dist/systems/skin-palette-allocator.d.ts.map +1 -1
  297. package/dist/systems/skin-palette-types.d.ts +15 -0
  298. package/dist/systems/skin-palette-types.d.ts.map +1 -1
  299. package/dist/systems/transparent-dispatch.d.ts +9 -0
  300. package/dist/systems/transparent-dispatch.d.ts.map +1 -0
  301. package/dist/targets/material-source.d.ts +7 -0
  302. package/dist/targets/material-source.d.ts.map +1 -1
  303. package/dist/temporal/frame-coordinator.d.ts +7 -0
  304. package/dist/temporal/frame-coordinator.d.ts.map +1 -1
  305. package/dist/temporal/gpu.d.ts +8 -0
  306. package/dist/temporal/gpu.d.ts.map +1 -1
  307. package/dist/temporal/history.d.ts.map +1 -1
  308. package/dist/temporal/index.mjs +6 -6
  309. package/dist/temporal/inspection.d.ts.map +1 -1
  310. package/dist/temporal/standard-scene-data.d.ts +2 -1
  311. package/dist/temporal/standard-scene-data.d.ts.map +1 -1
  312. package/dist/temporal/temporal-view.d.ts +2 -0
  313. package/dist/temporal/temporal-view.d.ts.map +1 -1
  314. package/dist/typed-render-graph-primitives.d.ts +35 -1
  315. package/dist/typed-render-graph-primitives.d.ts.map +1 -1
  316. package/dist/typed-shadow-passes.d.ts +3 -1
  317. package/dist/typed-shadow-passes.d.ts.map +1 -1
  318. package/dist/volume/temporal.d.ts +6 -0
  319. package/dist/volume/temporal.d.ts.map +1 -1
  320. package/package.json +21 -20
  321. package/src/__tests__/auto-exposure-gpu-evidence.ts +291 -0
  322. package/src/__tests__/auto-exposure-inspection.unit.test.ts +80 -0
  323. package/src/__tests__/auto-exposure-transaction.integration.test.ts +99 -0
  324. package/src/__tests__/auto-exposure.browser.test.ts +33 -0
  325. package/src/__tests__/auto-exposure.dawn.test.ts +33 -0
  326. package/src/__tests__/detached-inspection.integration.test.ts +5 -0
  327. package/src/__tests__/device-scope-lifecycle.unit.test.ts +18 -0
  328. package/src/__tests__/device-scope-stale-matrix.unit.test.ts +18 -0
  329. package/src/__tests__/docs-gate-green.unit.test.ts +3 -3
  330. package/src/__tests__/dynamic-geometry-host.unit.test.ts +1123 -0
  331. package/src/__tests__/dynamic-geometry.unit.test.ts +233 -0
  332. package/src/__tests__/factory-contract.integration.test.ts +73 -22
  333. package/src/__tests__/fallback-row-stride-surface.unit.test.ts +19 -0
  334. package/src/__tests__/feature-depth-input.dawn.test.ts +121 -0
  335. package/src/__tests__/feature-noise.unit.test.ts +38 -0
  336. package/src/__tests__/fixtures/taa-resolve-pinned-baseline.wgsl +301 -0
  337. package/src/__tests__/frame-camera-selection.unit.test.ts +131 -0
  338. package/src/__tests__/frame-plan-contract.unit.test.ts +24 -0
  339. package/src/__tests__/frame-targets.unit.test.ts +24 -0
  340. package/src/__tests__/fullscreen-feature-plan.unit.test.ts +3 -0
  341. package/src/__tests__/gpu-driven-baseline.characterization.test.ts +79 -0
  342. package/src/__tests__/gpu-driven-batch-topology-pbr.unit.test.ts +287 -6
  343. package/src/__tests__/gpu-driven-indirect-raster-evidence.ts +122 -142
  344. package/src/__tests__/gpu-driven-indirect-raster.browser.test.ts +10 -1
  345. package/src/__tests__/gpu-driven-lod-cache.unit.test.ts +264 -0
  346. package/src/__tests__/gpu-driven-mesh-world-identity.unit.test.ts +349 -0
  347. package/src/__tests__/gpu-driven-pbr.dawn.test.ts +1417 -0
  348. package/src/__tests__/gpu-driven-pbr.integration.test.ts +21 -0
  349. package/src/__tests__/gpu-driven-production-fixture.ts +96 -0
  350. package/src/__tests__/gpu-driven-production.integration.test.ts +1075 -93
  351. package/src/__tests__/gpu-driven-scaling.unit.test.ts +1 -3
  352. package/src/__tests__/gpu-driven-shadow-views.browser.test.ts +63 -0
  353. package/src/__tests__/gpu-driven-shadow-views.dawn.test.ts +294 -0
  354. package/src/__tests__/gpu-driven-shadow-views.integration.test.ts +97 -0
  355. package/src/__tests__/gpu-driven-shadow-views.unit.test.ts +168 -0
  356. package/src/__tests__/gpu-driven-skin-contract.test-d.ts +11 -0
  357. package/src/__tests__/gpu-driven-view-gpu-evidence.ts +72 -20
  358. package/src/__tests__/gpu-driven-view-graph.integration.test.ts +30 -9
  359. package/src/__tests__/gpu-driven-view.unit.test.ts +159 -52
  360. package/src/__tests__/gpu-pass-timing.browser.test.ts +6 -1
  361. package/src/__tests__/gpu-resource-store-stride.unit.test.ts +42 -0
  362. package/src/__tests__/gpu-scene-render-graph-gpu.ts +19 -5
  363. package/src/__tests__/gpu-scene.dawn.test.ts +40 -13
  364. package/src/__tests__/gpu-scene.unit.test.ts +559 -33
  365. package/src/__tests__/instances-culling.integration.test.ts +36 -10
  366. package/src/__tests__/instances-derived-bounds.unit.test.ts +54 -0
  367. package/src/__tests__/instances-store.unit.test.ts +242 -39
  368. package/src/__tests__/ktx2-basis-gpu-consumer.dawn.test.ts +6 -0
  369. package/src/__tests__/lighting-scene-roundtrip.integration.test.ts +13 -16
  370. package/src/__tests__/lut-lkg-transaction.integration.test.ts +122 -0
  371. package/src/__tests__/material-contract-inventory.unit.test.ts +5 -6
  372. package/src/__tests__/material-dispatch-shader-id.unit.test.ts +51 -0
  373. package/src/__tests__/material-lane-selection.unit.test.ts +60 -0
  374. package/src/__tests__/material-numeric-upload.unit.test.ts +53 -0
  375. package/src/__tests__/material-texture-handles.unit.test.ts +18 -0
  376. package/src/__tests__/material-texture-source.unit.test.ts +87 -0
  377. package/src/__tests__/materials-authoring-validation.unit.test.ts +41 -0
  378. package/src/__tests__/materials-standard-contract.unit.test.ts +52 -2
  379. package/src/__tests__/mesh-buffer-usage-surface.unit.test.ts +4 -0
  380. package/src/__tests__/mesh-submission-lifetime.unit.test.ts +53 -0
  381. package/src/__tests__/normal-fallback.dawn.test.ts +122 -0
  382. package/src/__tests__/particle-material-input-layout.unit.test.ts +104 -0
  383. package/src/__tests__/physical-clearcoat.integration.test.ts +37 -3
  384. package/src/__tests__/pipeline-texture-specialization.unit.test.ts +138 -0
  385. package/src/__tests__/point-shadow-inspection.unit.test.ts +2 -0
  386. package/src/__tests__/prepared-gpu-driven-pbr-contract.test-d.ts +31 -0
  387. package/src/__tests__/prepared-gpu-driven-pbr-contract.unit.test.ts +39 -0
  388. package/src/__tests__/prepared-gpu-driven-pbr.integration.test.ts +35 -4
  389. package/src/__tests__/prepared-graphics-capability.unit.test.ts +21 -0
  390. package/src/__tests__/prepared-graphics-pipeline-warmup.unit.test.ts +6 -2
  391. package/src/__tests__/profiler-phase-catalog.test.ts +5 -0
  392. package/src/__tests__/public-surface.test-d.ts +3 -0
  393. package/src/__tests__/recovery-candidate-prepare.contract.test.ts +30 -12
  394. package/src/__tests__/reflection-fallback-async-publication.unit.test.ts +104 -0
  395. package/src/__tests__/reflection-probe-record-owner.characterization.unit.test.ts +2 -1
  396. package/src/__tests__/render-error-code-owner.test-d.ts +4 -0
  397. package/src/__tests__/render-error-detail-ssot.test-d.ts +22 -0
  398. package/src/__tests__/render-error-exhaustive.test-d.ts +15 -0
  399. package/src/__tests__/render-feature-gpu-work.integration.test.ts +285 -2
  400. package/src/__tests__/render-feature-plan.unit.test.ts +245 -0
  401. package/src/__tests__/render-feature-shadow-order.unit.test.ts +228 -0
  402. package/src/__tests__/render-feature-zero-work.unit.test.ts +35 -1
  403. package/src/__tests__/render-graph-fallback.integration.test.ts +2 -2
  404. package/src/__tests__/render-owner-cohesion.unit.test.ts +55 -0
  405. package/src/__tests__/render-scene-mixed-updates.integration.test.ts +426 -0
  406. package/src/__tests__/render-scene-projection.unit.test.ts +914 -23
  407. package/src/__tests__/render-scene-resource-updates.integration.test.ts +214 -0
  408. package/src/__tests__/render-scene-skin-lifecycle.integration.test.ts +173 -0
  409. package/src/__tests__/render-scene-temporal-retry.unit.test.ts +133 -0
  410. package/src/__tests__/render-target-material-source.test-d.ts +27 -3
  411. package/src/__tests__/renderer-factory-material-contract.unit.test.ts +61 -1
  412. package/src/__tests__/renderer-frame-transaction.integration.test.ts +923 -5
  413. package/src/__tests__/shader-manifest-fixture.ts +39 -0
  414. package/src/__tests__/skin-motion-regression.unit.test.ts +0 -33
  415. package/src/__tests__/skin-palette-persistent.integration.test.ts +28 -0
  416. package/src/__tests__/skin-palette-persistent.unit.test.ts +247 -0
  417. package/src/__tests__/skinned-shadow-caster.test.ts +118 -14
  418. package/src/__tests__/specular-environment-scale.dawn.test.ts +156 -0
  419. package/src/__tests__/ssr-admission-matrix.integration.test.ts +7 -1
  420. package/src/__tests__/ssr-confidence-compose.unit.test.ts +84 -0
  421. package/src/__tests__/ssr-coordinate-oracle.unit.test.ts +28 -0
  422. package/src/__tests__/ssr-format-probe-gating.integration.test.ts +82 -0
  423. package/src/__tests__/ssr-gpu-dispatch.browser.test.ts +91 -0
  424. package/src/__tests__/ssr-gpu-dispatch.dawn.test.ts +112 -0
  425. package/src/__tests__/ssr-gpu-dispatch.ts +946 -0
  426. package/src/__tests__/ssr-graph-topology.unit.test.ts +104 -0
  427. package/src/__tests__/ssr-history-filter.dawn.test.ts +198 -0
  428. package/src/__tests__/ssr-hit-color.dawn.test.ts +273 -0
  429. package/src/__tests__/ssr-hiz-odd-reduction.dawn.test.ts +569 -0
  430. package/src/__tests__/ssr-hiz-rescue.dawn.test.ts +279 -0
  431. package/src/__tests__/ssr-hiz.browser.test.ts +150 -0
  432. package/src/__tests__/ssr-hiz.dawn.test.ts +150 -0
  433. package/src/__tests__/ssr-hiz.unit.test.ts +56 -0
  434. package/src/__tests__/ssr-inspection.unit.test.ts +105 -0
  435. package/src/__tests__/ssr-memory-budget.unit.test.ts +45 -0
  436. package/src/__tests__/ssr-performance-sequence-aggregation.unit.test.ts +15 -0
  437. package/src/__tests__/ssr-public-surface.test-d.ts +37 -0
  438. package/src/__tests__/ssr-receiver-coverage.dawn.test.ts +387 -0
  439. package/src/__tests__/ssr-reflection-mip-reducer.dawn.test.ts +309 -0
  440. package/src/__tests__/ssr-reprojection-probe.ts +90 -0
  441. package/src/__tests__/ssr-roughness-mip.dawn.test.ts +163 -0
  442. package/src/__tests__/ssr-shader-prewarm.unit.test.ts +59 -0
  443. package/src/__tests__/ssr-spatial.integration.test.ts +141 -0
  444. package/src/__tests__/ssr-stable-lattice.dawn.test.ts +475 -0
  445. package/src/__tests__/ssr-temporal-history.unit.test.ts +202 -0
  446. package/src/__tests__/ssr-texel-crossing.dawn.test.ts +448 -0
  447. package/src/__tests__/ssr-zero-work.integration.test.ts +87 -0
  448. package/src/__tests__/standard-cluster-variant-resolution.unit.test.ts +44 -12
  449. package/src/__tests__/standard-clustered-pipeline.unit.test.ts +29 -0
  450. package/src/__tests__/standard-output-chain-contract.unit.test.ts +99 -0
  451. package/src/__tests__/standard-output-chain.integration.test.ts +73 -0
  452. package/src/__tests__/standard-output-gpu-evidence.ts +205 -0
  453. package/src/__tests__/standard-output.browser.test.ts +15 -0
  454. package/src/__tests__/standard-output.dawn.test.ts +15 -0
  455. package/src/__tests__/standard-pbr-artifact-assembly.unit.test.ts +38 -0
  456. package/src/__tests__/standard-pipeline.integration.test.ts +320 -3
  457. package/src/__tests__/standard-profile-oracle.unit.test.ts +22 -0
  458. package/src/__tests__/standard-surface-lighting.unit.test.ts +41 -0
  459. package/src/__tests__/standard-texture-specialization.dawn.test.ts +141 -0
  460. package/src/__tests__/surface-adjacent-regressions.integration.test.ts +6 -3
  461. package/src/__tests__/taa-coverage-edge.dawn.test.ts +193 -0
  462. package/src/__tests__/taa-history-clipping.dawn.test.ts +328 -0
  463. package/src/__tests__/taa-neighborhood-equivalence.dawn.test.ts +778 -0
  464. package/src/__tests__/taa-stability-feedback.browser.test.ts +23 -0
  465. package/src/__tests__/taa-stability-feedback.dawn.test.ts +68 -0
  466. package/src/__tests__/taa-stability-feedback.ts +341 -0
  467. package/src/__tests__/temporal-history-lifecycle.unit.test.ts +49 -7
  468. package/src/__tests__/temporal-reset-matrix.unit.test.ts +9 -0
  469. package/src/__tests__/temporal-transaction.integration.test.ts +28 -0
  470. package/src/__tests__/texture-usage-surface.unit.test.ts +4 -2
  471. package/src/__tests__/typed-pipeline-topology.unit.test.ts +109 -4
  472. package/src/__tests__/typed-scene-pass-material-cache.integration.test.ts +126 -0
  473. package/src/__tests__/vertex-layouts-ssot.unit.test.ts +47 -0
  474. package/src/__tests__/visibility-extract.perf.test.ts +20 -8
  475. package/src/__tests__/visibility-instances.integration.test.ts +19 -7
  476. package/src/__tests__/visibility-producer-matrix.integration.test.ts +20 -9
  477. package/src/assembly/atmosphere-shader-prewarm.ts +38 -0
  478. package/src/assembly/dynamic-geometry-host.ts +887 -0
  479. package/src/assembly/dynamic-geometry-runtime.ts +71 -0
  480. package/src/assembly/factory.ts +4 -0
  481. package/src/assembly/gpu-driven-owner.ts +29 -0
  482. package/src/assembly/host-contract.ts +36 -0
  483. package/src/assembly/material/assembly.ts +38 -0
  484. package/src/assembly/material-shader-policy.ts +71 -28
  485. package/src/assembly/recovery/failure-location.ts +62 -0
  486. package/src/assembly/recovery/renderer-recover.ts +19 -17
  487. package/src/assembly/renderer-facade.ts +29 -0
  488. package/src/assembly/renderer-feature-inspection.ts +13 -0
  489. package/src/assembly/renderer-frame-transaction.ts +63 -0
  490. package/src/assembly/renderer-helpers.ts +26 -0
  491. package/src/assembly/renderer-inspection.ts +6 -0
  492. package/src/assembly/shader-prewarm-policy.ts +32 -0
  493. package/src/assembly/skin-palette-owner.ts +21 -0
  494. package/src/assembly/ssr-shader-prewarm.ts +41 -0
  495. package/src/assembly/webgpu-device-loss.ts +75 -0
  496. package/src/assembly/webgpu-pbr-ready.ts +232 -0
  497. package/src/assembly/webgpu-ready-mipmap.ts +26 -0
  498. package/src/assembly/webgpu-ready.ts +142 -121
  499. package/src/assembly/webgpu-renderer-bootstrap.ts +85 -0
  500. package/src/assembly/webgpu-renderer-contract.ts +69 -0
  501. package/src/assembly/webgpu-renderer-guards.ts +32 -0
  502. package/src/assembly/webgpu-renderer-observation.ts +43 -0
  503. package/src/assembly/webgpu-renderer-recovery-failure.ts +62 -0
  504. package/src/assembly/webgpu-renderer.ts +675 -614
  505. package/src/assembly/webgpu-vertex-layouts.ts +233 -87
  506. package/src/components/__tests__/camera-exposure.contract.unit.test.ts +153 -0
  507. package/src/components/camera.ts +287 -7
  508. package/src/components/index.ts +1 -0
  509. package/src/components/instances.ts +45 -18
  510. package/src/components/scene-instance.ts +2 -1
  511. package/src/components/screen-space-reflection.ts +21 -0
  512. package/src/components/sprite-animation.ts +3 -3
  513. package/src/components/sprite-instances.ts +1 -1
  514. package/src/device/gpu-residency.ts +96 -93
  515. package/src/device/mesh-residency-lifetime.ts +73 -0
  516. package/src/dynamic-geometry.ts +736 -0
  517. package/src/environment/background.ts +263 -0
  518. package/src/errors/gpu-driven.ts +39 -5
  519. package/src/errors/render.ts +27 -3
  520. package/src/extract/camera.ts +26 -1
  521. package/src/extract/gpu-driven.ts +185 -10
  522. package/src/features/host.ts +237 -19
  523. package/src/features/noise-texture.ts +91 -0
  524. package/src/features/plan.ts +553 -24
  525. package/src/features/prepared-gpu-work.ts +631 -49
  526. package/src/features/prepared-graphics-store.ts +31 -0
  527. package/src/features/prepared-graphics.ts +5 -0
  528. package/src/features/render-graph-compute.ts +41 -8
  529. package/src/features/render-graph-contribution.ts +141 -3
  530. package/src/features/render-graph-raster.ts +143 -30
  531. package/src/features/types.ts +11 -0
  532. package/src/fullscreen-post-process-pass.ts +3 -0
  533. package/src/gpu-driven/batch-topology.ts +424 -102
  534. package/src/gpu-driven/pbr-program.ts +31 -0
  535. package/src/gpu-driven/prepared-draw.ts +29 -4
  536. package/src/gpu-driven/production-raster.ts +2267 -694
  537. package/src/gpu-driven/shadow-views.ts +539 -0
  538. package/src/gpu-driven/view-gpu.ts +188 -41
  539. package/src/gpu-scene-schema.ts +52 -11
  540. package/src/gpu-scene.ts +186 -99
  541. package/src/gpu-texture-usage.ts +1 -0
  542. package/src/hdrp-buffers.ts +72 -36
  543. package/src/ibl/frame-resources.ts +38 -0
  544. package/src/ibl/skylight-bind-group.ts +5 -4
  545. package/src/index.ts +125 -1
  546. package/src/inspection-types.ts +191 -0
  547. package/src/instances-derived-bounds.ts +258 -34
  548. package/src/instances.ts +459 -150
  549. package/src/internal.ts +22 -0
  550. package/src/lifecycle.ts +2 -0
  551. package/src/material-row.ts +145 -0
  552. package/src/materials.ts +44 -8
  553. package/src/pbr-pipeline.ts +159 -17
  554. package/src/pipeline/standard-forward-lane.ts +52 -24
  555. package/src/pipeline/standard-output/__tests__/lut-admission.unit.test.ts +103 -0
  556. package/src/pipeline/standard-output/auto-exposure/__tests__/capability.unit.test.ts +40 -0
  557. package/src/pipeline/standard-output/auto-exposure/__tests__/gpu.contract.unit.test.ts +125 -0
  558. package/src/pipeline/standard-output/auto-exposure/__tests__/graph.contract.unit.test.ts +94 -0
  559. package/src/pipeline/standard-output/auto-exposure/__tests__/oracle.test.ts +108 -0
  560. package/src/pipeline/standard-output/auto-exposure/__tests__/preset.test.ts +26 -0
  561. package/src/pipeline/standard-output/auto-exposure/capability.ts +38 -0
  562. package/src/pipeline/standard-output/auto-exposure/gpu.ts +567 -0
  563. package/src/pipeline/standard-output/auto-exposure/graph.ts +221 -0
  564. package/src/pipeline/standard-output/auto-exposure/inspection.ts +231 -0
  565. package/src/pipeline/standard-output/auto-exposure/oracle.ts +291 -0
  566. package/src/pipeline/standard-output/auto-exposure/preset.ts +28 -0
  567. package/src/pipeline/standard-output/auto-exposure/state.ts +156 -0
  568. package/src/pipeline/standard-output/color-transform.ts +124 -0
  569. package/src/pipeline/standard-output/graph.ts +139 -0
  570. package/src/pipeline/standard-output/lut-admission.ts +121 -0
  571. package/src/pipeline/standard-output/lut-gpu.ts +399 -0
  572. package/src/pipeline/standard-output/lut-state.ts +176 -0
  573. package/src/pipeline/standard-output/resources.ts +121 -0
  574. package/src/pipeline/standard-output/types.ts +58 -0
  575. package/src/pipeline/standard-pipeline.ts +192 -59
  576. package/src/pipeline/standard-post.ts +186 -27
  577. package/src/pipeline-builder.ts +16 -6
  578. package/src/pipeline-spec-types.ts +4 -0
  579. package/src/pipeline-spec.ts +37 -29
  580. package/src/points-lines/standard-owner.ts +6 -14
  581. package/src/prepare/prepared-graphics-resolver.ts +9 -2
  582. package/src/record/__tests__/material-slot-plan.unit.test.ts +48 -0
  583. package/src/record/__tests__/mesh-ssbo.unit.test.ts +40 -1
  584. package/src/record/__tests__/recovery-pipeline.unit.test.ts +2 -29
  585. package/src/record/__tests__/sprite-material-abi.unit.test.ts +36 -5
  586. package/src/record/__tests__/typed-frame-graph-plan.unit.test.ts +45 -0
  587. package/src/record/__tests__/view-ubo-layout.unit.test.ts +5 -0
  588. package/src/record/dynamic-geometry-consumption.ts +59 -0
  589. package/src/record/frame-lighting.ts +12 -11
  590. package/src/record/frame-snapshot.ts +133 -23
  591. package/src/record/frame-targets.ts +9 -0
  592. package/src/record/frame.ts +727 -133
  593. package/src/record/main-pass-geometry.ts +162 -98
  594. package/src/record/main-pass-material.ts +115 -26
  595. package/src/record/main-pass-sprite-draws.ts +18 -107
  596. package/src/record/main-pass.ts +78 -8
  597. package/src/record/material-uniforms.ts +1 -1
  598. package/src/record/mesh-ssbo.ts +59 -15
  599. package/src/record/prepared-material-bindings.ts +234 -0
  600. package/src/record/recovery-pipeline.ts +59 -136
  601. package/src/record/render-context.ts +92 -22
  602. package/src/record/shadow-pass.ts +1231 -209
  603. package/src/record/skybox-post-pass.ts +14 -3
  604. package/src/record/typed-frame-graph.ts +1006 -53
  605. package/src/record/view-ubo.ts +11 -0
  606. package/src/recovery/render-system-candidate.ts +90 -66
  607. package/src/recovery/render-system-roots.ts +113 -0
  608. package/src/recovery/types.ts +77 -0
  609. package/src/reflection/record-owner.ts +26 -54
  610. package/src/render-contract.ts +219 -25
  611. package/src/render-graph-primitives.ts +6 -2
  612. package/src/render-pipeline.ts +70 -1
  613. package/src/render-system-extract-tail.ts +409 -160
  614. package/src/render-system-extract.ts +376 -102
  615. package/src/render-system-projections.ts +241 -0
  616. package/src/render-system.ts +692 -791
  617. package/src/scene/render-scene-types.ts +13 -4
  618. package/src/scene/render-scene.ts +569 -355
  619. package/src/scene/shadow-visibility.ts +21 -0
  620. package/src/ssr/admission.ts +380 -14
  621. package/src/ssr/compose.ts +144 -0
  622. package/src/ssr/errors.ts +48 -0
  623. package/src/ssr/graph.ts +777 -0
  624. package/src/ssr/history.ts +436 -0
  625. package/src/ssr/hiz.ts +124 -0
  626. package/src/ssr/inspection.ts +124 -0
  627. package/src/ssr/resources.ts +202 -0
  628. package/src/ssr/temporal.ts +164 -0
  629. package/src/systems/skin-palette-allocator.ts +495 -148
  630. package/src/systems/skin-palette-types.ts +17 -0
  631. package/src/systems/transparent-dispatch.ts +90 -0
  632. package/src/targets/material-source.ts +34 -0
  633. package/src/temporal/coverage.ts +1 -1
  634. package/src/temporal/frame-coordinator.ts +23 -2
  635. package/src/temporal/gpu.ts +74 -12
  636. package/src/temporal/history.ts +3 -1
  637. package/src/temporal/inspection.ts +2 -1
  638. package/src/temporal/standard-scene-data.ts +3 -1
  639. package/src/temporal/temporal-view.ts +3 -0
  640. package/src/transmission/__tests__/standard-transmission.dawn.test.ts +204 -139
  641. package/src/typed-render-graph-primitives.ts +266 -74
  642. package/src/typed-shadow-passes.ts +122 -12
  643. package/src/volume/temporal.ts +10 -0
  644. package/dist/chunk-ADHHVYLW.mjs.map +0 -1
  645. package/dist/chunk-FJ6P52EE.mjs.map +0 -1
  646. package/dist/chunk-GE3SDD72.mjs.map +0 -1
  647. package/dist/chunk-GF523LHF.mjs.map +0 -1
  648. package/dist/chunk-HKXTW355.mjs.map +0 -1
  649. package/dist/chunk-JDWARUOI.mjs.map +0 -1
  650. package/dist/chunk-KM2NOX2I.mjs.map +0 -1
  651. package/dist/chunk-TMIASV2N.mjs.map +0 -1
  652. package/dist/chunk-XDP6XE5V.mjs.map +0 -1
  653. package/dist/chunk-ZZ4YQ474.mjs.map +0 -1
  654. package/src/__tests__/instances-world-ownership.integration.test.ts +0 -62
  655. package/src/scene/__tests__/changed-block-summary.candidate.test.ts +0 -36
@@ -1,4 +1,8 @@
1
- import type { CompiledRenderGraphInfo, GraphTextureDescriptor } from '@forgeax/engine-render-graph';
1
+ import type {
2
+ CompiledRenderGraphInfo,
3
+ GraphTextureDescriptor,
4
+ GraphTextureView,
5
+ } from '@forgeax/engine-render-graph';
2
6
  import { RenderGraphError } from '@forgeax/engine-render-graph';
3
7
  import { err, ok, type Result } from '@forgeax/engine-types';
4
8
  import { addTypedDebugOverlayPass } from '../debug-draw-glue';
@@ -25,6 +29,12 @@ import {
25
29
  TYPED_BLOOM_PASS_NAMES,
26
30
  type TypedTemporalResolveTargets,
27
31
  } from '../typed-render-graph-primitives';
32
+ import {
33
+ addAutoExposureExposurePass,
34
+ addAutoExposureGraphPasses,
35
+ } from './standard-output/auto-exposure/gpu';
36
+ import { createStandardOutputPlan } from './standard-output/graph';
37
+ import { addStandardColorLutPass } from './standard-output/lut-gpu';
28
38
 
29
39
  interface StandardPostSurface {
30
40
  readonly display?: RenderPipelineTarget;
@@ -159,20 +169,31 @@ export function addStandardPost(
159
169
  depth: RenderPipelineTarget,
160
170
  surface: StandardPostSurface,
161
171
  sceneTemporal?: RenderPipelineTarget,
172
+ secondaryReactivity?: GraphTextureView,
162
173
  ): Result<void, RenderPipelineBuildError> {
163
174
  const clearOnly = topology.clearOnly === true;
175
+ const outputPlan = createStandardOutputPlan({
176
+ lane: topology.standardProfile?.renderPath === 'deferred' ? 'clustered' : 'direct',
177
+ temporal: !clearOnly && topology.camera.antialias === 'taa',
178
+ meter: topology.output?.autoExposure === true,
179
+ bloom: !clearOnly && topology.camera.bloom === 'on' && topology.camera.tonemap !== 'none',
180
+ exposure: topology.output?.autoExposure === true,
181
+ whiteBalance: topology.output?.whiteBalance === true,
182
+ lut: topology.output?.colorLut === true,
183
+ fxaa: !clearOnly && topology.camera.antialias === 'fxaa',
184
+ outputEncoding: 'explicit-oetf',
185
+ });
164
186
  const hdr =
165
187
  !clearOnly && (topology.camera.tonemap !== 'none' || topology.camera.antialias === 'taa');
166
188
  // Bloom is an HDR-domain effect and its recorders intentionally no-op when
167
189
  // tone mapping is disabled. Keep the graph in the same no-op state for the
168
190
  // TAA + tonemap:none combination; otherwise the declared Bloom composite is
169
191
  // left clear and the following Output Transform presents a black frame.
170
- const bloomActive = hdr && topology.camera.bloom === 'on' && topology.camera.tonemap !== 'none';
171
- const fxaa = !clearOnly && topology.camera.antialias === 'fxaa';
172
- // All non-clear Standard frames use the graph-owned float scene target and
173
- // the shared Output Transform, even when AA is disabled or the backend has
174
- // no storage buffers. This keeps the final dither at one owner-level
175
- // surface boundary instead of making no-AA/WebGL2 a silent bypass.
192
+ const bloomActive = hdr && outputPlan.features.bloom;
193
+ const fxaa = outputPlan.features.fxaa;
194
+ // Keep the graph-owned output transform on every non-HDR frame, including
195
+ // structural lanes without storage buffers; the final writer remains the
196
+ // single display-encoding owner.
176
197
  const linearLdr = !clearOnly && !hdr;
177
198
  const rawOnly = !clearOnly && topology.surface.profile?.kind === 'raw-only';
178
199
  const outputDither = resolveOutputDither(topology.config);
@@ -194,7 +215,19 @@ export function addStandardPost(
194
215
  // single Output Transform performs the first 8-bit quantization.
195
216
  const finalPresent = surface.storage;
196
217
  let postInput = scene;
218
+ let postTemporal = sceneTemporal;
197
219
 
220
+ const autoExposure = context.standardOutput?.autoExposure;
221
+ if (outputPlan.features.exposure && autoExposure === undefined) {
222
+ return err(
223
+ new RenderGraphError({
224
+ code: 'resource-resolution-failed',
225
+ expected: 'a prepared same-frame auto-exposure producer projection',
226
+ hint: 'prepare device-scoped auto-exposure resources before compiling Standard output',
227
+ detail: { resourceLabel: 'standard-auto-exposure' },
228
+ }),
229
+ );
230
+ }
198
231
  if (topology.camera.antialias === 'taa') {
199
232
  if (sceneTemporal === undefined) {
200
233
  return err(missingTemporalContributor(topology, 'forgeax::standard::scene-data'));
@@ -207,14 +240,20 @@ export function addStandardPost(
207
240
  scene,
208
241
  depth,
209
242
  currentTemporal: sceneTemporal,
243
+ ...(secondaryReactivity === undefined ? {} : { secondaryReactivity }),
210
244
  historyColor: history.previousColor,
211
245
  historyTemporal: history.previousTemporal,
246
+ historyStability: history.previousStability,
212
247
  writeColor: history.currentColor,
213
248
  writeTemporal: history.currentTemporal,
249
+ writeStability: history.currentStability,
214
250
  };
215
251
  const resolve = addTypedTemporalResolvePass(context.graph, resolveTargets);
216
252
  if (!resolve.ok) return resolve;
217
253
  postInput = history.currentColor;
254
+ // TAA resolves both outputs to the unjittered lattice. Later effects must
255
+ // consume its matching temporal attachment, not raw jittered coverage.
256
+ postTemporal = history.currentTemporal;
218
257
  }
219
258
 
220
259
  // Feature projection and the built-in fallback share one target contract.
@@ -238,7 +277,7 @@ export function addStandardPost(
238
277
  },
239
278
  ];
240
279
  if (motionBlur) {
241
- if (sceneTemporal === undefined) {
280
+ if (postTemporal === undefined) {
242
281
  return err(
243
282
  new Error('Motion Blur requires the Standard scene-data producer') as RenderGraphError,
244
283
  );
@@ -249,7 +288,7 @@ export function addStandardPost(
249
288
  domain: hdr ? 'linear-hdr' : 'linear-ldr',
250
289
  });
251
290
  if (!blurred.ok) return blurred;
252
- const features = context.contributeFeatures(featureTargets, [sceneTemporal], {
291
+ const features = context.contributeFeatures(featureTargets, [postTemporal], {
253
292
  'motion-input': postInput,
254
293
  'motion-output': blurred.value,
255
294
  });
@@ -257,7 +296,7 @@ export function addStandardPost(
257
296
  if (context.hasFeature?.('forgeax.motion-blur') === true) {
258
297
  postInput = blurred.value;
259
298
  } else {
260
- const fallback = addMotionBlurPass(context.graph, postInput, sceneTemporal, blurred.value);
299
+ const fallback = addMotionBlurPass(context.graph, postInput, postTemporal, blurred.value);
261
300
  if (!fallback.ok) return fallback;
262
301
  postInput = blurred.value;
263
302
  }
@@ -270,6 +309,18 @@ export function addStandardPost(
270
309
  }
271
310
  }
272
311
 
312
+ // Meter the temporally resolved color before Bloom. This preserves the
313
+ // Standard order: temporal -> meter -> bloom -> exposure/WB -> tone -> LUT.
314
+ if (outputPlan.features.exposure && autoExposure !== undefined) {
315
+ const added = addAutoExposureGraphPasses(context, {
316
+ source: postInput,
317
+ resources: autoExposure,
318
+ width: topology.surface.width,
319
+ height: topology.surface.height,
320
+ });
321
+ if (!added.ok) return added;
322
+ }
323
+
273
324
  if (bloomActive) {
274
325
  const composited = target(
275
326
  context,
@@ -306,6 +357,86 @@ export function addStandardPost(
306
357
  postInput = composited.value;
307
358
  }
308
359
 
360
+ if (outputPlan.features.exposure || outputPlan.features.whiteBalance) {
361
+ const exposureOutput = target(context, 'standard-exposure-white-balance', {
362
+ format: 'rgba16float',
363
+ size: 'surface',
364
+ domain: 'linear-hdr',
365
+ });
366
+ if (!exposureOutput.ok) return exposureOutput;
367
+ const exposurePass = addAutoExposureExposurePass(
368
+ context,
369
+ postInput,
370
+ exposureOutput.value,
371
+ outputPlan.features.exposure ? autoExposure : undefined,
372
+ {
373
+ temperature: topology.output?.temperature ?? 6504,
374
+ tint: topology.output?.tint ?? 0,
375
+ },
376
+ );
377
+ if (!exposurePass.ok) return exposurePass;
378
+ postInput = exposureOutput.value;
379
+ }
380
+
381
+ // Auto exposure changes the HDR source before tone mapping, so it needs the
382
+ // same explicit linear-LDR boundary as the LUT route even when no LUT is
383
+ // bound. Keep the manual/LUT0 route combined so disabling auto exposure
384
+ // remains exact-zero.
385
+ const splitOutput =
386
+ outputPlan.features.lut ||
387
+ outputPlan.features.exposure ||
388
+ outputPlan.features.whiteBalance ||
389
+ // A receipt-bound observation request is an explicit producer demand, not
390
+ // a new authored color feature. When a caller asks for the linear-LDR
391
+ // domain on the ordinary ACES path, retain the same tone/output boundary
392
+ // that the LUT and auto-exposure routes already use so the graph can
393
+ // capture it without changing unobserved frames.
394
+ context.observationCaptureDomains?.includes('linear-ldr') === true;
395
+
396
+ // Tone mapping and output encoding are separate entry points when a LUT is
397
+ // enabled or auto exposure is active: the LUT must sample linear LDR, and
398
+ // the single OETF writer runs only after LUT and optional FXAA.
399
+ const toneOutput = splitOutput
400
+ ? target(context, 'standard-tone-output', {
401
+ format: 'rgba16float',
402
+ size: 'surface',
403
+ domain: 'linear-ldr',
404
+ })
405
+ : undefined;
406
+ if (toneOutput !== undefined) {
407
+ if (!toneOutput.ok) return toneOutput;
408
+ const transformed = addTypedOutputTransformPass(context.graph, postInput, toneOutput.value, {
409
+ dither: false,
410
+ name: 'standard-tone',
411
+ fragmentEntryPoint: 'fs_tone_only',
412
+ });
413
+ if (!transformed.ok) return transformed;
414
+ postInput = toneOutput.value;
415
+ }
416
+
417
+ if (outputPlan.features.lut) {
418
+ const colorLut = context.standardOutput?.colorLut;
419
+ if (colorLut === undefined) {
420
+ return err(
421
+ new RenderGraphError({
422
+ code: 'resource-resolution-failed',
423
+ expected: 'a prepared resident Standard color LUT projection',
424
+ hint: 'resolve and admit the TextureAsset LUT before compiling Standard output',
425
+ detail: { resourceLabel: 'standard-color-lut' },
426
+ }),
427
+ );
428
+ }
429
+ const lutOutput = target(context, 'standard-color-lut', {
430
+ format: 'rgba16float',
431
+ size: 'surface',
432
+ domain: 'linear-ldr',
433
+ });
434
+ if (!lutOutput.ok) return lutOutput;
435
+ const lutPass = addStandardColorLutPass(context.graph, postInput, lutOutput.value, colorLut);
436
+ if (!lutPass.ok) return lutPass;
437
+ postInput = lutOutput.value;
438
+ }
439
+
309
440
  if (rawOnly) {
310
441
  const overlay = addTypedDebugOverlayPass(context.graph, postInput);
311
442
  if (!overlay.ok) return overlay;
@@ -313,27 +444,44 @@ export function addStandardPost(
313
444
 
314
445
  if (hdr || linearLdr || fxaa || rawOnly || motionBlur) {
315
446
  if (fxaa) {
316
- const output = target(context, 'standard-output-color', {
317
- format: 'rgba16float',
318
- size: 'surface',
319
- usage: GPU_TEXTURE_USAGE_COPY_SRC,
320
- domain: 'display-encoded',
321
- });
447
+ const output = splitOutput
448
+ ? target(context, 'standard-fxaa-output', {
449
+ format: 'rgba16float',
450
+ size: 'surface',
451
+ domain: 'linear-ldr',
452
+ })
453
+ : target(context, 'standard-output-color', {
454
+ format: 'rgba16float',
455
+ size: 'surface',
456
+ usage: GPU_TEXTURE_USAGE_COPY_SRC,
457
+ domain: 'display-encoded',
458
+ });
322
459
  if (!output.ok) return output;
323
- // FXAA samples this display-encoded intermediate; leave dither to the
324
- // final FXAA writer so the same pixel is not dithered twice.
325
- const outputTransform = addTypedOutputTransformPass(context.graph, postInput, output.value, {
326
- dither: false,
327
- });
328
- if (!outputTransform.ok) return outputTransform;
460
+ if (!splitOutput) {
461
+ // FXAA samples this display-encoded intermediate; leave dither to the
462
+ // final FXAA writer so the same pixel is not dithered twice.
463
+ const outputTransform = addTypedOutputTransformPass(
464
+ context.graph,
465
+ postInput,
466
+ output.value,
467
+ { dither: false },
468
+ );
469
+ if (!outputTransform.ok) return outputTransform;
470
+ }
329
471
  const aa = addTypedFullscreenPass(context.graph, {
330
472
  name: 'fxaa',
331
473
  shader: 'fxaa',
332
- input: output.value,
333
- output: rawOnlyPostInput !== undefined ? rawOnlyPostInput.value : finalPresent,
474
+ input: splitOutput ? postInput : output.value,
475
+ output: splitOutput ? output.value : (rawOnlyPostInput?.value ?? finalPresent),
476
+ ...(splitOutput
477
+ ? {
478
+ paramsTransform: (): Uint8Array => new Uint8Array(16),
479
+ }
480
+ : {}),
334
481
  });
335
482
  if (!aa.ok) return aa;
336
- } else if (rawOnlyPostInput !== undefined) {
483
+ if (splitOutput) postInput = output.value;
484
+ } else if (rawOnlyPostInput !== undefined && !splitOutput) {
337
485
  const transformed = addTypedOutputTransformPass(
338
486
  context.graph,
339
487
  postInput,
@@ -343,12 +491,12 @@ export function addStandardPost(
343
491
  },
344
492
  );
345
493
  if (!transformed.ok) return transformed;
346
- } else if (rawOnly || linearLdr) {
494
+ } else if ((rawOnly || linearLdr) && !splitOutput) {
347
495
  const transformed = addTypedOutputTransformPass(context.graph, postInput, finalPresent, {
348
496
  dither: outputDither,
349
497
  });
350
498
  if (!transformed.ok) return transformed;
351
- } else {
499
+ } else if (!splitOutput) {
352
500
  const outputTransform = addTypedOutputTransformPass(context.graph, postInput, finalPresent, {
353
501
  dither: outputDither,
354
502
  });
@@ -356,6 +504,17 @@ export function addStandardPost(
356
504
  }
357
505
  }
358
506
 
507
+ if (splitOutput) {
508
+ const encodedOutput = rawOnlyPostInput?.value ?? finalPresent;
509
+ const outputTransform = addTypedOutputTransformPass(context.graph, postInput, encodedOutput, {
510
+ dither: outputDither,
511
+ name: 'standard-output-encoding',
512
+ fragmentEntryPoint: 'fs_encode_only',
513
+ });
514
+ if (!outputTransform.ok) return outputTransform;
515
+ postInput = encodedOutput;
516
+ }
517
+
359
518
  if (topology.lane.storageBuffer && postEffects.length > 0) {
360
519
  const postInputTarget = rawOnly
361
520
  ? rawOnlyPostInput?.value
@@ -124,6 +124,7 @@ export interface PipelineBuilderContext {
124
124
  readonly colorFormat: GPUTextureFormat;
125
125
  /** Additional color targets for an MRT pass; the first target is colorFormat. */
126
126
  readonly colorFormats?: readonly GPUTextureFormat[] | undefined;
127
+ readonly fragmentConstants?: Readonly<Record<string, number>> | undefined;
127
128
  /** Depth attachment format, or `undefined` for a color-only pass. */
128
129
  readonly depthFormat: GPUTextureFormat | undefined;
129
130
  /**
@@ -134,7 +135,7 @@ export interface PipelineBuilderContext {
134
135
  */
135
136
  readonly vertexBuffers: readonly GPUVertexBufferLayout[];
136
137
  /** Explicit layout family selected by the renderer assembly. */
137
- readonly layoutKind?: 'pbr-skin' | undefined;
138
+ readonly layoutKind?: 'pbr-skin' | 'gpu-driven-skin' | undefined;
138
139
  /** Pipeline label (for GPU debug captures); defaults to `pbr-pipeline-${id}`. */
139
140
  readonly label?: string | undefined;
140
141
  /**
@@ -367,6 +368,7 @@ export function buildPipelineForMaterialShader(
367
368
  ? {
368
369
  module: shaderModule,
369
370
  entryPoint: fsEntry,
371
+ ...(ctx.fragmentConstants === undefined ? {} : { constants: ctx.fragmentConstants }),
370
372
  targets: [],
371
373
  }
372
374
  : undefined,
@@ -376,11 +378,18 @@ export function buildPipelineForMaterialShader(
376
378
  frontFace: renderState?.frontFace ?? 'ccw',
377
379
  },
378
380
  depthStencil: {
379
- // depth32float (matches shadow RT format), NOT ctx.depthFormat
380
- // (which is depth24plus-stencil8 for the main pass).
381
- format: 'depth32float',
382
- depthWriteEnabled: true,
383
- depthCompare: 'less',
381
+ // Shadow passes default to depth32float, while prepared depth-only
382
+ // feature passes may target the renderer's depth24plus-stencil8
383
+ // attachment. The pipeline context carries the resolved format so
384
+ // the PSO and render pass cannot drift.
385
+ format: ctx.depthFormat ?? 'depth32float',
386
+ // Shadow-caster remains the default policy for the legacy depth pass,
387
+ // while an explicit prepared depth-only feature is allowed to carry
388
+ // its own compare/write contract (for example an occlusion prepass
389
+ // using `always` + write-off). Do not infer policy from the absence of
390
+ // color targets alone.
391
+ depthWriteEnabled: renderState?.depthWriteEnabled ?? true,
392
+ depthCompare: renderState?.depthCompare ?? 'less',
384
393
  },
385
394
  multisample: sampleCount > 1 ? { count: sampleCount } : undefined,
386
395
  });
@@ -430,6 +439,7 @@ export function buildPipelineForMaterialShader(
430
439
  fragment: {
431
440
  module: shaderModule,
432
441
  entryPoint: fsEntry,
442
+ ...(ctx.fragmentConstants === undefined ? {} : { constants: ctx.fragmentConstants }),
433
443
  targets: forwardSpec.attachments.colorFormats.map((format) => ({
434
444
  format,
435
445
  ...(renderState?.blend === undefined ? {} : { blend: renderState.blend }),
@@ -12,6 +12,8 @@ export interface PipelineSpec {
12
12
  readonly variantSet: string | undefined;
13
13
  readonly vertexEntry?: string;
14
14
  readonly fragmentEntry?: string;
15
+ /** Pipeline-time fragment overrides; not runtime WGSL feature defines. */
16
+ readonly fragmentConstants?: Readonly<Record<string, number>> | undefined;
15
17
  };
16
18
  readonly attachments: {
17
19
  readonly colorFormats: readonly GPUTextureFormat[];
@@ -24,6 +26,8 @@ export interface PipelineSpec {
24
26
  readonly vertexLayout: VertexAttributeMap;
25
27
  /** Geometry-owned immutable descriptor projection, when already derived. */
26
28
  readonly vertexLayoutProjection?: VertexLayoutProjection | undefined;
29
+ /** Explicit multi-stream layout supplied by the prepared-graphics owner. */
30
+ readonly vertexBuffers?: readonly GPUVertexBufferLayout[];
27
31
  readonly shaderUvSetCount?: number | undefined;
28
32
  };
29
33
  readonly renderState: MaterialRenderState | undefined;
@@ -18,6 +18,7 @@
18
18
  // P4: consistent abstraction — 4-axis aligns with wgpu/Bevy/Three.js
19
19
 
20
20
  import {
21
+ DEFAULT_VERTEX_ATTRIBUTE_MAP,
21
22
  deriveVertexBufferLayout,
22
23
  deriveVertexBufferLayoutFromProjection,
23
24
  deriveVertexLayoutProjection,
@@ -30,7 +31,6 @@ import {
30
31
  ok,
31
32
  type PrimitiveTopology,
32
33
  type Result,
33
- type VertexAttributeMap,
34
34
  } from '@forgeax/engine-types';
35
35
  import { VertexColorVariantConflictError } from './errors/render';
36
36
 
@@ -226,6 +226,24 @@ export function cacheKeyOf(spec: PipelineSpec): string {
226
226
 
227
227
  const uvSetCountSegment =
228
228
  geometry.shaderUvSetCount !== undefined ? `:uvsc${geometry.shaderUvSetCount}` : '';
229
+ // Prepared graphics may publish an explicit multi-stream layout (particle
230
+ // material-input lanes are the canonical example). The attribute map alone
231
+ // cannot describe those streams or their lane stride, so include the
232
+ // normalized descriptors in the cache identity as well.
233
+ const vertexBuffersSegment =
234
+ geometry.vertexBuffers === undefined
235
+ ? ''
236
+ : `:vbs:${JSON.stringify(
237
+ geometry.vertexBuffers.map((buffer) => ({
238
+ arrayStride: buffer.arrayStride,
239
+ stepMode: buffer.stepMode ?? 'vertex',
240
+ attributes: [...buffer.attributes].map((attribute) => ({
241
+ shaderLocation: attribute.shaderLocation,
242
+ offset: attribute.offset,
243
+ format: attribute.format,
244
+ })),
245
+ })),
246
+ )}`;
229
247
 
230
248
  // bug-20260708 M2 (b): sentinel `~` distinguishes `variantSet=undefined`
231
249
  // (no-variant / default-variant request) from canonical all-true key `''`
@@ -249,7 +267,15 @@ export function cacheKeyOf(spec: PipelineSpec): string {
249
267
  `vl:${vlDigest}`,
250
268
  renderStateHash(renderState),
251
269
  ].join(':') +
270
+ vertexBuffersSegment +
252
271
  uvSetCountSegment +
272
+ (shader.fragmentConstants === undefined
273
+ ? ''
274
+ : `:fragment-constants:${JSON.stringify(
275
+ Object.entries(shader.fragmentConstants).sort(([left], [right]) =>
276
+ left.localeCompare(right),
277
+ ),
278
+ )}`) +
253
279
  (shader.vertexEntry === undefined && shader.fragmentEntry === undefined
254
280
  ? ''
255
281
  : `:entries:${JSON.stringify([shader.vertexEntry ?? null, shader.fragmentEntry ?? null])}`)
@@ -292,22 +318,13 @@ export function variantSetFromVertexLayoutProjection(
292
318
  return ok(parts.join('+'));
293
319
  }
294
320
 
295
- /**
296
- * Derive the capability axes shared by every Standard PBR draw owner.
297
- *
298
- * The all-true key is the canonical empty key used by the shader manifest;
299
- * every other capability pair stays explicit so a no-local-light frame on a
300
- * device without storage buffers cannot accidentally select a storage-backed
301
- * PSO. Vertex-color is supplied here because the empty-key rule is only valid
302
- * when that geometry-owned axis is also true.
303
- */
321
+ /** Explicit geometry and lighting facts survive composition before manifest key canonicalization. */
304
322
  export function standardCapabilityVariantSet(
305
323
  clustered: boolean,
306
324
  storageBuffer: boolean,
307
325
  vertexColorAvailable: boolean,
308
326
  ): string {
309
- if (clustered && storageBuffer && vertexColorAvailable) return '';
310
- return `CLUSTER_FORWARD_AVAILABLE=${clustered}+STORAGE_BUFFER_AVAILABLE=${storageBuffer}`;
327
+ return `CLUSTER_FORWARD_AVAILABLE=${clustered}+STORAGE_BUFFER_AVAILABLE=${storageBuffer}+VERTEX_COLOR_AVAILABLE=${vertexColorAvailable}`;
311
328
  }
312
329
 
313
330
  /**
@@ -332,15 +349,7 @@ export function standardTopologyVariantSet(
332
349
  vertexColorAvailable,
333
350
  );
334
351
  if (!probeBlendAvailable || !storageBuffer) return capabilityVariantSet;
335
- // The canonical empty key cannot carry the clustered=true fact through
336
- // resolveMaterialShaderVariantSet (an omitted cluster axis means false).
337
- // Expand that base before adding the object-level Probe ABI axis so shader,
338
- // group(3) bind group, and pipeline layout remain one exact variant.
339
- const explicitCapabilityVariantSet =
340
- capabilityVariantSet === ''
341
- ? 'CLUSTER_FORWARD_AVAILABLE=true+STORAGE_BUFFER_AVAILABLE=true'
342
- : capabilityVariantSet;
343
- return `${explicitCapabilityVariantSet}+PROBE_BLEND_AVAILABLE=true`;
352
+ return `${capabilityVariantSet}+PROBE_BLEND_AVAILABLE=true`;
344
353
  }
345
354
 
346
355
  /**
@@ -406,7 +415,8 @@ export function buildPipelineDescriptor(
406
415
  // A supplied projection is the geometry owner's immutable GPU descriptor.
407
416
  // Do not re-derive it from a possibly stale attribute map.
408
417
  const vertexBuffers =
409
- geometry.vertexLayoutProjection === undefined
418
+ geometry.vertexBuffers ??
419
+ (geometry.vertexLayoutProjection === undefined
410
420
  ? deriveVertexBufferLayout(geometry.vertexLayout, {
411
421
  ...(geometry.shaderUvSetCount !== undefined
412
422
  ? { shaderUvSetCount: geometry.shaderUvSetCount }
@@ -416,7 +426,7 @@ export function buildPipelineDescriptor(
416
426
  ...(geometry.shaderUvSetCount !== undefined
417
427
  ? { shaderUvSetCount: geometry.shaderUvSetCount }
418
428
  : {}),
419
- });
429
+ }));
420
430
 
421
431
  const descriptor: Record<string, unknown> = {
422
432
  vertex: {
@@ -431,6 +441,9 @@ export function buildPipelineDescriptor(
431
441
  descriptor.fragment = {
432
442
  module: modules.fragment,
433
443
  entryPoint: spec.shader.fragmentEntry ?? modules.fragmentEntryPoint ?? 'fs_main',
444
+ ...(spec.shader.fragmentConstants === undefined
445
+ ? {}
446
+ : { constants: spec.shader.fragmentConstants }),
434
447
  targets: attachments.colorFormats.map((fmt) => {
435
448
  const target: Record<string, unknown> = { format: fmt };
436
449
  if (renderState?.blend !== undefined) {
@@ -952,12 +965,7 @@ export function getOrBuildPipeline(
952
965
  // SPEC_CONST_TABLE — 12 boot-time pre-warm variants (M1-T5)
953
966
  // ══════════════════════════════════════════════════════════════════════════════
954
967
 
955
- const PROCEDURAL_ATTR_LAYOUT: VertexAttributeMap = {
956
- position: new Float32Array(0),
957
- normal: new Float32Array(0),
958
- uv: new Float32Array(0),
959
- tangent: new Float32Array(0),
960
- };
968
+ const PROCEDURAL_ATTR_LAYOUT = DEFAULT_VERTEX_ATTRIBUTE_MAP;
961
969
 
962
970
  const HDR_FORMAT: GPUTextureFormat = 'rgba16float';
963
971
  const DEPTH_DS: GPUTextureFormat = 'depth24plus-stencil8';
@@ -1,5 +1,8 @@
1
1
  import { resolveAssetHandle } from '@forgeax/engine-assets-runtime';
2
- import { deriveVertexLayoutProjection } from '@forgeax/engine-geometry';
2
+ import {
3
+ DEFAULT_VERTEX_ATTRIBUTE_MAP,
4
+ deriveVertexLayoutProjection,
5
+ } from '@forgeax/engine-geometry';
3
6
  import { err, ok } from '@forgeax/engine-rhi';
4
7
  import type { MaterialAsset, MeshAsset } from '@forgeax/engine-types';
5
8
  import { toShared } from '@forgeax/engine-types';
@@ -15,7 +18,7 @@ import type {
15
18
  PointsLinesRecordSubmission,
16
19
  RenderSystemInternals,
17
20
  } from '../record/render-context';
18
- import type { RecoveryPointsLinesCandidate } from '../render-system';
21
+ import type { RecoveryPointsLinesCandidate } from '../recovery/types';
19
22
  import { admitPointsLines } from './admission';
20
23
  import { PointsLinesExpansionCache } from './expansion-cache';
21
24
  import type { PointsLinesInspection, PointsLinesSourceError } from './inspection';
@@ -50,12 +53,7 @@ export class StandardPointsLinesOwner implements PointsLinesRecordOwner {
50
53
  private readonly cache = new PointsLinesExpansionCache();
51
54
  private readonly preparations = new Map<string, PointsLinesPreparationAdapter>();
52
55
  private readonly active = new Map<string, PointsLinesInspection>();
53
- private readonly layoutProjection = deriveVertexLayoutProjection({
54
- position: new Float32Array(0),
55
- normal: new Float32Array(0),
56
- uv: new Float32Array(0),
57
- tangent: new Float32Array(0),
58
- });
56
+ private readonly layoutProjection = deriveVertexLayoutProjection(DEFAULT_VERTEX_ATTRIBUTE_MAP);
59
57
 
60
58
  constructor(private readonly internals: RenderSystemInternals) {}
61
59
 
@@ -193,14 +191,8 @@ export class StandardPointsLinesOwner implements PointsLinesRecordOwner {
193
191
  const prepKey = `${geometryKey}:${lane}:${backend}`;
194
192
  let preparation = preparations.get(prepKey);
195
193
  if (preparation === undefined) {
196
- // A new expansion is visible cold upload work. Candidate preparation
197
- // uses an unarmed runtime and stages the result; the published runtime
198
- // is armed, so a missing staged resource fails before any RHI create.
199
- runtime.recoveryColdWorkGuard?.noteUploadColdWork();
200
194
  preparation = this.createPreparation(runtime, geometryKey, lane, backend);
201
195
  preparations.set(prepKey, preparation);
202
- } else if (preparation.lastKnownGood()?.geometry.key !== geometryKey) {
203
- runtime.recoveryColdWorkGuard?.noteUploadColdWork();
204
196
  }
205
197
  const prepared = preparation.prepare(snapshot, meshResult.value);
206
198
  if (!prepared.ok) {
@@ -44,6 +44,8 @@ export type PreparedGraphicsResolvedResource =
44
44
  readonly kind: 'pipeline';
45
45
  readonly reference: RenderFeaturePreparedRef;
46
46
  readonly handle: RenderPipeline;
47
+ /** Renderer-selected context; never authored by a RenderFeature. */
48
+ readonly standardLighting?: boolean;
47
49
  }
48
50
  | {
49
51
  readonly kind: 'bindings';
@@ -70,7 +72,10 @@ export interface PreparedGraphicsResolverInput {
70
72
  readonly lookup: (reference: RenderFeaturePreparedRef) => PreparedGraphicsItem | undefined;
71
73
  readonly resolvePipeline: (
72
74
  descriptor: PreparedGraphicsNormalizedDescriptor & { readonly kind: 'pipeline' },
73
- ) => Result<RenderPipeline, unknown>;
75
+ ) => Result<
76
+ RenderPipeline | { readonly handle: RenderPipeline; readonly standardLighting: boolean },
77
+ unknown
78
+ >;
74
79
  readonly resolveBindings: (
75
80
  descriptor: RenderFeatureBindingsDescriptor,
76
81
  pipeline: RenderPipeline,
@@ -304,7 +309,9 @@ export function createPreparedGraphicsResolver(
304
309
  const resource: PreparedGraphicsResolvedResource = {
305
310
  kind: 'pipeline',
306
311
  reference,
307
- handle: created.value,
312
+ ...('handle' in created.value
313
+ ? { handle: created.value.handle, standardLighting: created.value.standardLighting }
314
+ : { handle: created.value }),
308
315
  };
309
316
  resolved.set(reference, resource);
310
317
  return ok(resource);