@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,3 +1,4 @@
1
+ import type { GpuDrivenPbrProgram } from '../gpu-driven/pbr-program';
1
2
  // WebGPU generation-scoped ready-state builder.
2
3
  // This owner performs one complete device-generation promotion; it receives
3
4
  // policy/adapters and returns a fully prepared PipelineState.
@@ -10,7 +11,7 @@ import {
10
11
  HANDLE_SPHERE,
11
12
  HANDLE_TRIANGLE,
12
13
  } from '@forgeax/engine-assets-runtime';
13
- import { deriveVertexLayoutProjection } from '@forgeax/engine-geometry';
14
+ import { deriveVertexCount, deriveVertexLayoutProjection } from '@forgeax/engine-geometry';
14
15
  import type {
15
16
  BindGroupLayout,
16
17
  Buffer,
@@ -26,6 +27,8 @@ import { ok, RhiError } from '@forgeax/engine-rhi';
26
27
  import { findVariantByKey, type ShaderCatalog } from '@forgeax/engine-shader';
27
28
  import type { ManifestEntry } from '@forgeax/engine-types';
28
29
  import { handleSlot } from '@forgeax/engine-types';
30
+ import { prewarmAtmosphereShaders } from './atmosphere-shader-prewarm';
31
+ import { prewarmSsrShaders } from './ssr-shader-prewarm';
29
32
 
30
33
  export type { MaterialShaderManifestEntry } from '@forgeax/engine-shader';
31
34
 
@@ -54,12 +57,13 @@ import {
54
57
  } from '../ibl/skylight-bind-group';
55
58
  import type { BloomInspection } from '../inspection-types';
56
59
  import type { DeviceScope, RhiErrorListenerRegistry } from '../lifecycle';
60
+ import { assertStorageBufferCap } from '../light-buffer-layout';
57
61
  import {
58
62
  buildPbrPipelineLayouts,
59
- buildPbrSkinLayouts,
60
63
  createHdrpSkinBindGroupLayoutDescriptor,
61
64
  type PipelineGroup2Contract,
62
65
  resolvePipelineGroup2Contract,
66
+ SKIN_MATERIAL_SHADER_ID,
63
67
  } from '../pbr-pipeline';
64
68
  import { STANDARD_CLUSTER_MEMBERSHIP_WGSL } from '../pipeline/standard-pipeline';
65
69
  import { inspectStandardBloomGraph } from '../pipeline/standard-post';
@@ -80,6 +84,8 @@ import type { BloomPersistentBundle } from '../record/render-context';
80
84
  import { SHADOW_CASTER_BUFFER_SIZE } from '../record/shadow-pass';
81
85
  import { POINTS_LINES_VIEW_BUFFER_SIZE } from '../record/view-ubo';
82
86
  import {
87
+ type AtmosphereShaderSources,
88
+ type SsrShaderSources,
83
89
  STANDARD_OUTPUT_TRANSFORM_FEATURE_ID,
84
90
  type VolumetricFogShaderSources,
85
91
  } from '../render-contract';
@@ -111,14 +117,15 @@ import {
111
117
  selectProbePrewarmVariants,
112
118
  selectStandardPbrTransmissionPrewarmVariants,
113
119
  } from './shader-prewarm-policy';
120
+ import { buildGpuDrivenPbrReadyLayouts, buildGpuDrivenPbrReadyModules } from './webgpu-pbr-ready';
114
121
  import {
115
122
  BLUR_PARAMS_BYTES,
116
123
  BRIGHT_PARAMS_BYTES,
117
124
  COMPOSITE_PARAMS_BYTES,
118
125
  HDR_COLOR_ATTACHMENT_FORMAT,
119
- MIPMAP_PREWARM_FORMATS,
120
126
  VIEW_UBO_BYTES,
121
127
  } from './webgpu-ready-contract';
128
+ import { prewarmMipmapPipeline } from './webgpu-ready-mipmap';
122
129
 
123
130
  /**
124
131
  * Build the `Renderer.initialization` Promise (D-S3 three-step strict-serial chain).
@@ -160,6 +167,7 @@ export async function buildReadyWebGPU(
160
167
  * frame while the shared async shader adapter is still warming up.
161
168
  */
162
169
  requiredMaterialShaders: readonly string[],
170
+ standardPbrShaderUvSetCount: number,
163
171
  /** Fullscreen feature modules compiled before the first synchronous frame. */
164
172
  requiredFullscreenPostProcesses: readonly {
165
173
  readonly identity: string;
@@ -215,12 +223,29 @@ export async function buildReadyWebGPU(
215
223
  }) => void,
216
224
  /** Install manifest-owned volume utility sources only after all four modules compile. */
217
225
  setVolumetricFogShaderSources: (sources: VolumetricFogShaderSources) => void,
226
+ /** Install manifest-owned SSR utility sources only after all five modules compile. */
227
+ setSsrShaderSources: (sources: SsrShaderSources) => void,
228
+ /** Install manifest-owned atmosphere utility sources only after both modules compile. */
229
+ setAtmosphereShaderSources: (sources: AtmosphereShaderSources) => void,
218
230
  ): Promise<PipelineState> {
219
231
  const extendedLightingShaderAvailable = deriveExtendedLightingCapability(rhiDevice).admitted;
220
- // Shader layouts and record-stage buffer usage share the RHI capability.
221
- // Backend names and numeric limits must not independently re-enable storage.
222
- const storageBufferCapable = rhiDevice.caps.storageBuffer;
232
+ // bug-20260610: WebGL2 fallback path read storage-buffer capability up
233
+ // front so both Step 2 (shader-module compile, where we patch engine
234
+ // entries to the STORAGE_BUFFER_AVAILABLE=false variant) and Step 3
235
+ // (buildPbrPipelineLayouts, which switches between read-only-storage
236
+ // and uniform BGL entries) walk the same axis. Step 0 already ran in
237
+ // `prepareMaterialShaders`; this is an idempotent re-read driven by
238
+ // `device.limits.maxStorageBuffersPerShaderStage`, which is 0 on the
239
+ // wgpu-wasm WebGL2 backend (downlevel_webgl2_defaults).
240
+ const capValue = (rhiDevice.limits as Readonly<Record<string, number>>)
241
+ .maxStorageBuffersPerShaderStage;
223
242
  const webgl2Downlevel = rhiDevice.caps.backendKind === 'wgpu-webgl2';
243
+ let storageBufferCapable = !webgl2Downlevel && rhiDevice.caps.storageBuffer;
244
+ if (typeof capValue === 'number') {
245
+ const capCheck = assertStorageBufferCap(capValue);
246
+ storageBufferCapable =
247
+ capCheck.ok && !webgl2Downlevel && rhiDevice.caps.storageBuffer && capCheck.value;
248
+ }
224
249
  const directionalPcssAvailable =
225
250
  rhiDevice.caps.backendKind === 'webgpu' || rhiDevice.caps.backendKind === 'wgpu-native';
226
251
  const projectorAvailable =
@@ -292,6 +317,8 @@ export async function buildReadyWebGPU(
292
317
  manifestEntries.push(entry);
293
318
  }
294
319
  let pbrModule: ShaderModule | null = null;
320
+ let pbrSkinModule: ShaderModule | null = null;
321
+ let gpuDrivenPbrPrograms: ReadonlyMap<string, GpuDrivenPbrProgram> = new Map();
295
322
  let unlitModule: ShaderModule | null = null;
296
323
  let spriteModule: ShaderModule | null = null;
297
324
  let spriteLitModule: ShaderModule | null = null;
@@ -339,6 +366,9 @@ export async function buildReadyWebGPU(
339
366
  // brdfLutBake_fs) which survive naga_oil composition unchanged.
340
367
  // - unlit.wgsl: none of the above markers → falls into the unlit slot.
341
368
  let pbrEntry = findEngineManifestEntry('forgeax::default-standard-pbr');
369
+ let pbrSkinEntry =
370
+ findEngineManifestEntry(SKIN_MATERIAL_SHADER_ID) ??
371
+ findEngineManifestEntry('forgeax::default-standard-pbr-skin');
342
372
  let unlitEntry = findEngineManifestEntry('forgeax::default-unlit');
343
373
  let tonemapEntry: ManifestEntry | undefined;
344
374
  let motionBlurEntry: ManifestEntry | undefined;
@@ -562,6 +592,12 @@ export async function buildReadyWebGPU(
562
592
  return wgsl !== undefined ? { ...entry, wgsl } : entry;
563
593
  };
564
594
  pbrEntry = patchRuntimeVariant(pbrEntry, 'forgeax::default-standard-pbr');
595
+ if (pbrSkinEntry !== undefined) {
596
+ pbrSkinEntry = patchRuntimeVariant(
597
+ patchRuntimeVariant(pbrSkinEntry, SKIN_MATERIAL_SHADER_ID),
598
+ 'forgeax::default-standard-pbr-skin',
599
+ );
600
+ }
565
601
  unlitEntry = patchRuntimeVariant(unlitEntry, 'forgeax::default-unlit');
566
602
  if (shadowCasterEntry !== undefined) {
567
603
  shadowCasterEntry = patchRuntimeVariant(shadowCasterEntry, 'forgeax::default-shadow-caster');
@@ -675,6 +711,23 @@ export async function buildReadyWebGPU(
675
711
  if (!shaderResult.ok) throw shaderResult.error;
676
712
  seedShaderModule(label, shaderResult.value);
677
713
  }
714
+ const compileUtilityShader = async (
715
+ label: string,
716
+ source: string,
717
+ context: string,
718
+ ): Promise<ShaderModule> => {
719
+ const result = await runShimStep(
720
+ () =>
721
+ asyncCreateShaderModule
722
+ ? asyncCreateShaderModule(rhiDevice, { code: source, label })
723
+ : invokeDeviceCreateShaderModule(rhiDevice, { code: source, label }),
724
+ 'shader-compile-failed',
725
+ `${context} shader module '${label}' compiled`,
726
+ `inspect manifest WGSL for '${label}' and check device.features`,
727
+ );
728
+ if (!result.ok) throw result.error;
729
+ return result.value;
730
+ };
678
731
  if (rhiDevice.caps.compute && rhiDevice.caps.storageTexture) {
679
732
  const volumeSources = [
680
733
  ['inject', 'volume_inject', (source: string) => source.includes('fn volume_inject(')],
@@ -709,17 +762,12 @@ export async function buildReadyWebGPU(
709
762
  }> = [];
710
763
  for (const { stage, label, entry } of resolved) {
711
764
  if (entry === undefined) throw new Error(`missing volumetric shader ${label}`);
712
- const shaderResult = await runShimStep(
713
- () =>
714
- asyncCreateShaderModule
715
- ? asyncCreateShaderModule(rhiDevice, { code: entry.wgsl, label })
716
- : invokeDeviceCreateShaderModule(rhiDevice, { code: entry.wgsl, label }),
717
- 'shader-compile-failed',
718
- `volumetric fog shader module '${label}' compiled`,
719
- `inspect manifest WGSL for '${label}' and check device.features`,
720
- );
721
- if (!shaderResult.ok) throw shaderResult.error;
722
- compiled.push({ stage, label, source: entry.wgsl, module: shaderResult.value });
765
+ compiled.push({
766
+ stage,
767
+ label,
768
+ source: entry.wgsl,
769
+ module: await compileUtilityShader(label, entry.wgsl, 'volumetric fog'),
770
+ });
723
771
  }
724
772
  for (const { label, module } of compiled) seedShaderModule(label, module);
725
773
  setVolumetricFogShaderSources({
@@ -730,6 +778,20 @@ export async function buildReadyWebGPU(
730
778
  });
731
779
  }
732
780
  }
781
+ if (rhiDevice.caps.compute && rhiDevice.caps.storageTexture) {
782
+ const sources = await prewarmSsrShaders(
783
+ manifestEntries,
784
+ (label, source) => compileUtilityShader(label, source, 'SSR'),
785
+ seedShaderModule,
786
+ );
787
+ if (sources !== undefined) setSsrShaderSources(sources);
788
+ }
789
+ const atmosphereSources = await prewarmAtmosphereShaders(
790
+ manifestEntries,
791
+ (label, source) => compileUtilityShader(label, source, 'Atmosphere'),
792
+ seedShaderModule,
793
+ );
794
+ if (atmosphereSources !== undefined) setAtmosphereShaderSources(atmosphereSources);
733
795
  const pbrShaderResult = await runShimStep(
734
796
  () =>
735
797
  asyncCreateShaderModule
@@ -751,6 +813,27 @@ export async function buildReadyWebGPU(
751
813
  const pbrManifestEntry = [...registry.materialShaderManifestEntries()].find(
752
814
  (entry) => entry.identifier === 'forgeax::default-standard-pbr',
753
815
  );
816
+ const pbrSkinManifestEntry =
817
+ [...registry.materialShaderManifestEntries()].find(
818
+ (entry) => entry.identifier === SKIN_MATERIAL_SHADER_ID,
819
+ ) ??
820
+ [...registry.materialShaderManifestEntries()].find(
821
+ (entry) => entry.identifier === 'forgeax::default-standard-pbr-skin',
822
+ );
823
+ const gpuDrivenModules = await buildGpuDrivenPbrReadyModules({
824
+ device: rhiDevice,
825
+ storageBufferCapable,
826
+ asyncCreateShaderModule,
827
+ pbrSkinEntry,
828
+ pbrManifestEntry,
829
+ pbrSkinManifestEntry,
830
+ extendedLightingShaderAvailable,
831
+ directionalPcssAvailable,
832
+ projectorAvailable,
833
+ seedShaderModule,
834
+ });
835
+ pbrSkinModule = gpuDrivenModules.pbrSkinModule;
836
+ gpuDrivenPbrPrograms = gpuDrivenModules.gpuDrivenPbrPrograms;
754
837
  const pbrVariant = pbrManifestEntry?.variants.find(
755
838
  (variant) => variant.composedWgsl === pbrEntry.wgsl,
756
839
  );
@@ -1487,45 +1570,16 @@ export async function buildReadyWebGPU(
1487
1570
  }
1488
1571
  }
1489
1572
 
1490
- // bug-20260611-skin-pipeline-layout-mesh-array-bgl-2bindings: boot-time
1491
- // build of the skin-variant PipelineLayout. Mirrors the HDRP block above
1492
- // (D-2 / D-3 in plan-strategy): reuse view / material / instances BGLs
1493
- // from `pbrLayouts` and only create a 2-entry mesh-array BGL (binding 0
1494
- // meshes + binding 1 palette) so the `forgeax::pbr-skin` shader's
1495
- // `@group(2) @binding(1) palette` declaration validates. Stays null when
1496
- // createBindGroupLayout / createPipelineLayout fails;
1497
- // selectPipelineLayoutForVariant returns null in that case (charter P3
1498
- // explicit failure -- no silent fallback to URP layout, mirroring memory
1499
- // anchor `hdrp-active-must-not-fallback-to-urp-pipeline`).
1500
- let pbrSkinPipelineLayoutHandle: PipelineLayout | null = null;
1501
- let pbrSkinProbePipelineLayoutHandle: PipelineLayout | null = null;
1502
- // feat-20260611 R2 / M8 / w28: capture the 2-binding skin mesh-array BGL
1503
- // produced by `buildPbrSkinLayouts` so the record stage can build a BG
1504
- // matching `pbr-skin-pl` (pipeline-layout BGL[2] is this 2-entry skin
1505
- // BGL, NOT the 1-entry `pbr-mesh-array-bgl`). The BGL handle stays null
1506
- // when the skin pipeline layout itself failed to build, keeping the skin
1507
- // path explicitly disabled (charter P3 — record-stage falls back to URP
1508
- // path which is correct for non-skin entries; skin entries hit the
1509
- // explicit-failure branch).
1510
- let pbrSkinMeshBindGroupLayoutHandle: BindGroupLayout | null = null;
1573
+ const {
1574
+ pbrSkinPipelineLayout: pbrSkinPipelineLayoutHandle,
1575
+ pbrSkinProbePipelineLayout: pbrSkinProbePipelineLayoutHandle,
1576
+ pbrSkinMeshBindGroupLayout: pbrSkinMeshBindGroupLayoutHandle,
1577
+ gpuDrivenInstancesBindGroupLayout: gpuDrivenInstancesBindGroupLayoutHandle,
1578
+ gpuDrivenPbrPipelineLayout: gpuDrivenPbrPipelineLayoutHandle,
1579
+ gpuDrivenPbrSkinPipelineLayout: gpuDrivenPbrSkinPipelineLayoutHandle,
1580
+ } = buildGpuDrivenPbrReadyLayouts(rhiDevice, storageBufferCapable, pbrLayouts.value);
1511
1581
  let hdrpSkinPipelineLayoutHandle: PipelineLayout | null = null;
1512
1582
  let hdrpSkinMeshBindGroupLayoutHandle: BindGroupLayout | null = null;
1513
- {
1514
- const skinLayoutsResult = runShimSyncStep(
1515
- () =>
1516
- ok(
1517
- buildPbrSkinLayouts(rhiDevice, { storageBuffer: storageBufferCapable }, pbrLayouts.value),
1518
- ),
1519
- 'webgpu-runtime-error',
1520
- 'buildPbrSkinLayouts succeeded',
1521
- 'check device.limits.maxBindingsPerBindGroup (need >=14) and maxBindGroupsPerPipelineLayout',
1522
- );
1523
- if (skinLayoutsResult.ok) {
1524
- pbrSkinPipelineLayoutHandle = skinLayoutsResult.value.pipelineLayout;
1525
- pbrSkinProbePipelineLayoutHandle = skinLayoutsResult.value.probePipelineLayout;
1526
- pbrSkinMeshBindGroupLayoutHandle = skinLayoutsResult.value.meshArrayBgl;
1527
- }
1528
- }
1529
1583
  if (storageBufferCapable) {
1530
1584
  const skinBglResult = rhiDevice.createBindGroupLayout(
1531
1585
  createHdrpSkinBindGroupLayoutDescriptor(),
@@ -1733,6 +1787,13 @@ export async function buildReadyWebGPU(
1733
1787
  // M-3 / w12: builtin direct-upload fallback path mirrors the gpuStore
1734
1788
  // mesh entry shape -- raw RHI Buffer handles are wrapped in GpuBuffer so
1735
1789
  // the dispose chain (M-5) can walk them via `.destroy()`.
1790
+ const layoutProjection = deriveVertexLayoutProjection(asset.attributes);
1791
+ const vertexCount = deriveVertexCount(asset.vertices, layoutProjection);
1792
+ if (vertexCount === undefined) {
1793
+ throw new Error(
1794
+ `builtin mesh ${id} has vertex bytes that do not match its layout projection`,
1795
+ );
1796
+ }
1736
1797
  meshHandles.set(id, {
1737
1798
  vertexBuffer: new GpuBuffer(rhiDevice, vboResult.value),
1738
1799
  indexBuffer: ibo === null ? null : new GpuBuffer(rhiDevice, ibo),
@@ -1740,17 +1801,10 @@ export async function buildReadyWebGPU(
1740
1801
  iboBytes: meshIndices === undefined ? 0 : indexBytes,
1741
1802
  indexCount: meshIndices?.length ?? 0,
1742
1803
  indexFormat: meshIndices instanceof Uint32Array ? 'uint32' : 'uint16',
1743
- // bug-20260519: BUILTIN_CUBE / BUILTIN_TRIANGLE migrated to 12F
1744
- // (position + normal + uv + tangent), so the fallback literal mirrors
1745
- // every other mesh upload site.
1746
- layout: '12F',
1747
- layoutProjection: deriveVertexLayoutProjection(asset.attributes),
1804
+ layoutProjection,
1748
1805
  // BUILTIN_CUBE / BUILTIN_TRIANGLE are single-UV (set 0 only).
1749
1806
  uvSetCount: 1,
1750
- vertexCount:
1751
- asset.vertices.length /
1752
- (deriveVertexLayoutProjection(asset.attributes).arrayStride /
1753
- Float32Array.BYTES_PER_ELEMENT),
1807
+ vertexCount,
1754
1808
  indexed: meshIndices !== undefined,
1755
1809
  topology: asset.submeshes[0]?.topology ?? 'triangle-list',
1756
1810
  submeshes: asset.submeshes,
@@ -1968,22 +2022,6 @@ export async function buildReadyWebGPU(
1968
2022
  );
1969
2023
  if (!defaultSamplerResult.ok) throw defaultSamplerResult.error;
1970
2024
 
1971
- const nearestSamplerResult = runShimSyncStep(
1972
- () =>
1973
- rhiDevice.createSampler({
1974
- label: 'nearest-sampler',
1975
- magFilter: 'nearest',
1976
- minFilter: 'nearest',
1977
- mipmapFilter: 'nearest',
1978
- addressModeU: 'clamp-to-edge',
1979
- addressModeV: 'clamp-to-edge',
1980
- }),
1981
- 'webgpu-runtime-error',
1982
- 'createSampler (nearest) succeeded',
1983
- 'check device.limits.maxSamplersPerShaderStage',
1984
- );
1985
- if (!nearestSamplerResult.ok) throw nearestSamplerResult.error;
1986
-
1987
2025
  // feat-20260520-directional-light-shadow-mapping M1c / w8 + M2 / w14:
1988
2026
  // shadow comparison sampler — clamp-to-edge, linear filter, compare:'less'.
1989
2027
  // Used for shadow map sampling in M2/M3 and shadow depth pass. comparison
@@ -2070,9 +2108,9 @@ export async function buildReadyWebGPU(
2070
2108
  extendedLightingShaderAvailable,
2071
2109
  );
2072
2110
 
2073
- // Normal-slot fallback: 1x1 RGBA8 (128, 128, 255, 255). pbr.wgsl decodes
2074
- // sample.rg * 2 - 1 + z = sqrt(1 - x^2 - y^2), so RG=(128,128)=0.5 maps
2075
- // to tangent (0, 0, 1) -- zero perturbation when normalTexture is absent.
2111
+ // A declared normal map that is not ready needs an exactly neutral sample.
2112
+ // RGBA8 cannot encode 0.5: 128/255 perturbs the reflected ray even on a
2113
+ // perfectly flat surface. Half float stores (0.5, 0.5, 1, 1) exactly.
2076
2114
  // Cannot share the white fallback (255,255,...) because RG=(255,255)=1.0
2077
2115
  // gives tangent.xy=(1,1) -> 1 - 2 = -1 under the sqrt -> NaN (saturate
2078
2116
  // clamps to 0 z=0, still wrong). White-on-missing semantics for baseColor
@@ -2086,7 +2124,7 @@ export async function buildReadyWebGPU(
2086
2124
  mipLevelCount: 1,
2087
2125
  sampleCount: 1,
2088
2126
  dimension: '2d',
2089
- format: 'rgba8unorm',
2127
+ format: 'rgba16float',
2090
2128
  usage: GPU_TEXTURE_USAGE_TEXTURE_BINDING | GPU_TEXTURE_USAGE_COPY_DST,
2091
2129
  viewFormats: [],
2092
2130
  textureBindingViewDimension: undefined,
@@ -2098,10 +2136,7 @@ export async function buildReadyWebGPU(
2098
2136
  if (!fallbackNormalTextureResult.ok) throw fallbackNormalTextureResult.error;
2099
2137
 
2100
2138
  const fallbackNormalPixel = new Uint8Array(FALLBACK_BYTES_PER_ROW);
2101
- fallbackNormalPixel[0] = 128;
2102
- fallbackNormalPixel[1] = 128;
2103
- fallbackNormalPixel[2] = 255;
2104
- fallbackNormalPixel[3] = 255;
2139
+ new Uint16Array(fallbackNormalPixel.buffer).set([0x3800, 0x3800, 0x3c00, 0x3c00]);
2105
2140
  const fallbackNormalWriteResult = runShimSyncStep(
2106
2141
  () =>
2107
2142
  queue.writeTexture(
@@ -2650,9 +2685,10 @@ export async function buildReadyWebGPU(
2650
2685
  // - fragment.targets[0].blend: premultiplied alpha (vs no blend)
2651
2686
  // - depthStencil.depthWriteEnabled: false (vs true)
2652
2687
  // - depthStencil.depthCompare: 'less-equal' (vs 'less')
2653
- // The vertex stride stays 12F (HANDLE_QUAD passes through the same
2654
- // 12-float interleaved layout as procedural meshes), so no new vertex
2655
- // pipeline branch is needed in the record stage (plan-strategy §3 RT4).
2688
+ // The vertex stride comes from the geometry-owned projection (HANDLE_QUAD
2689
+ // passes through the same 12-float interleaved layout as procedural meshes),
2690
+ // so no new vertex pipeline branch is needed in the record stage
2691
+ // (plan-strategy §3 RT4).
2656
2692
  //
2657
2693
  // Premultiplied alpha blend op (`{ srcFactor: 'one', dstFactor:
2658
2694
  // 'one-minus-src-alpha', operation: 'add' }`) is the industry-default for
@@ -3833,37 +3869,14 @@ export async function buildReadyWebGPU(
3833
3869
  }
3834
3870
  }
3835
3871
 
3836
- // feat-20260601-device/gpu-residency-extraction M1 (D-9 sub-contract 1): prewarm
3837
- // the mipmap pipeline cache for the smoke texture formats while still on the
3838
- // async `renderer.initialization` path. This builds the one-time mipmap shader module +
3839
- // per-format pipeline into the deviceCache so the record-stage texture
3840
- // ensureResident (sync) reproduces the pre-extraction async uploadTexture
3841
- // byte-for-byte without an async stall in the synchronous draw frame. A build
3842
- // failure here is surfaced through ready's reject channel (structured RhiError).
3843
- //
3844
- // Gated on `manifestEntries.length > 0` (the same Camera-only / clear-pass
3845
- // skip as the Step-2 pipeline compile, bug-20260519 D-3): a zero-manifest
3846
- // world renders no material geometry, so no texture is ever made resident and
3847
- // the mipmap shader-module build (a `createShaderModule` call) must not fire
3848
- // -- preserving the zero-manifest "0 createShaderModule" invariant
3849
- // (renderer-ready.test.ts AC-02).
3850
- if (manifestEntries.length > 0) {
3851
- const prewarmRes = await gpuStore.prewarmMipmapPipeline(rhiDevice, MIPMAP_PREWARM_FORMATS);
3852
- if (!prewarmRes.ok) throw prewarmRes.error;
3853
- }
3872
+ await prewarmMipmapPipeline(rhiDevice, gpuStore, manifestEntries.length > 0);
3854
3873
 
3855
3874
  const pipelineState: PipelineState = {
3856
3875
  device: rhiDevice,
3857
- // feat-20260518-pbr-direct-lighting-mvp M5 / w22.10 (AC-06 dual->triple
3858
- // pipeline + D-2 + D-10): three distinct GPU render-pipeline handles
3859
- // backed by 2 distinct shader modules (unlit + pbr) x 2 vertex stride
3860
- // configurations (6F builtin + 12F procedural; the 6F + pbr combination
3861
- // does not exist per D-2). All three share the identical 4-BindGroupLayout
3862
- // chain so material BG entries built once compose for each of the three
3863
- // pipelines (charter P5 consistent abstraction). The legacy `pipeline`
3864
- // alias field has been retired; consumers select per
3865
- // (mat.materialShaderId, mesh.layout) tuple via the record-stage three-way
3866
- // setPipeline branch (w22.11).
3876
+ // The ready state keeps one canonical mesh vertex projection from the
3877
+ // geometry owner. Material selection and feature layout identity are
3878
+ // derived from that projection; no legacy stride discriminator participates
3879
+ // in pipeline or record routing.
3867
3880
  // bug-20260519: BUILTIN cube migrated to 12F so the legacy
3868
3881
  // `unlitBuiltinPipeline` (+ its zero-stride `unlitBuiltinDummyAttrBuffer`)
3869
3882
  // is gone; consumers pick per `mat.materialShaderId` only via the record-stage
@@ -3876,6 +3889,9 @@ export async function buildReadyWebGPU(
3876
3889
  // (see definition near SPEC_CONST boot-time pre-warm block above)
3877
3890
  unlitPipeline: getCachedPipelineOrNull('forgeax::default-unlit', false, 1),
3878
3891
  standardPipeline: getCachedPipelineOrNull('forgeax::default-standard-pbr', false, 1),
3892
+ standardPbrShaderModule: pbrModule,
3893
+ pbrSkinShaderModule: pbrSkinModule,
3894
+ standardPbrShaderUvSetCount,
3879
3895
  unlitPipelineMsaa: getCachedPipelineOrNull('forgeax::default-unlit', false, 4),
3880
3896
  // feat-20260625-refactor-sprite-as-transparent-mesh M3 / w14 (D-7):
3881
3897
  // four sprite-dedicated boot-time pre-warms are gone. Sprite PSO now
@@ -3893,6 +3909,13 @@ export async function buildReadyWebGPU(
3893
3909
  // standard pipeline fields above).
3894
3910
  pbrPipelineLayout:
3895
3911
  unlitModule !== null && pbrModule !== null ? pipelineLayoutResult.value : null,
3912
+ gpuDrivenInstancesBindGroupLayout:
3913
+ unlitModule !== null && pbrModule !== null ? gpuDrivenInstancesBindGroupLayoutHandle : null,
3914
+ gpuDrivenPbrPipelineLayout:
3915
+ unlitModule !== null && pbrModule !== null ? gpuDrivenPbrPipelineLayoutHandle : null,
3916
+ gpuDrivenPbrPrograms,
3917
+ gpuDrivenPbrSkinPipelineLayout:
3918
+ unlitModule !== null && pbrModule !== null ? gpuDrivenPbrSkinPipelineLayoutHandle : null,
3896
3919
  // HDRP variant uses the unified group(2) layout built above.
3897
3920
  hdrpPbrPipelineLayout:
3898
3921
  unlitModule !== null && pbrModule !== null ? hdrpPbrPipelineLayoutHandle : null,
@@ -3937,11 +3960,9 @@ export async function buildReadyWebGPU(
3937
3960
  probeInstancesBindGroupLayout: probeInstancesBglResult.value,
3938
3961
  identityInstanceBuffer: identityInstanceResult.value,
3939
3962
  defaultSampler: defaultSamplerResult.value,
3940
- nearestSampler: nearestSamplerResult.value,
3941
3963
  fallbackTextureView: fallbackTextureViewResult.value,
3942
3964
  defaultWhiteTextureView: fallbackTextureViewResult.value,
3943
- // Normal-slot fallback view (1x1 RGBA8 (128,128,255,255)). RG=(128,128)
3944
- // decodes to tangent (0,0,1) under pbr.wgsl's RG-only normal decoder.
3965
+ // Exactly neutral half-float RG=(0.5,0.5) decodes to tangent (0,0,1).
3945
3966
  // Distinct from defaultWhiteTextureView because RG=(255,255)=1.0 gives
3946
3967
  // sqrt(1 - 1 - 1) = NaN, breaking the no-normal-map case.
3947
3968
  defaultNormalTextureView: fallbackNormalTextureViewResult.value,
@@ -0,0 +1,85 @@
1
+ import type { RhiCanvasContext, RhiDevice } from '@forgeax/engine-rhi';
2
+ import {
3
+ HealthListenerRegistry,
4
+ LostListenerRegistry,
5
+ RhiErrorListenerRegistry,
6
+ } from '../lifecycle';
7
+ import type { RendererOptions } from '../render-contract';
8
+ import type { RhiBackendPack } from './backend-contract';
9
+ import type { BundlerOptions } from './bundler-contract';
10
+ import { deviceOptionsForAdapter } from './device-feature-admission';
11
+ import type { RendererAssemblyImplementation } from './host-contract';
12
+ import { attachDeviceLostFanout } from './recovery/device-loss-fanout';
13
+ import type { WebGPUOutcome, WebGPURendererInternals } from './webgpu-renderer-contract';
14
+
15
+ export type { WebGPUOutcome, WebGPURendererInternals } from './webgpu-renderer-contract';
16
+
17
+ export type WebGPURendererFactory = (
18
+ internals: WebGPURendererInternals,
19
+ ) => Promise<RendererAssemblyImplementation>;
20
+
21
+ /** Acquire the selected backend and build one renderer generation. */
22
+ export async function tryCreateWebGPURenderer(
23
+ canvas: HTMLCanvasElement | OffscreenCanvas,
24
+ options: RendererOptions | undefined,
25
+ pack: RhiBackendPack,
26
+ bundler: BundlerOptions | undefined,
27
+ createRenderer: WebGPURendererFactory,
28
+ ): Promise<WebGPUOutcome> {
29
+ const importTransport = bundler?.importTransport;
30
+ const adapterResult = await pack.rhi.requestAdapter(undefined, canvas);
31
+ if (!adapterResult.ok) return { kind: 'rhi-err', error: adapterResult.error };
32
+ const adapter = adapterResult.value;
33
+ const deviceOpts = deviceOptionsForAdapter(adapter, options);
34
+ const result = await adapter.requestDevice(deviceOpts);
35
+ if (!result.ok) return { kind: 'rhi-err', error: result.error };
36
+ const device: RhiDevice = result.value;
37
+ const ctxResult = pack.rhi.acquireCanvasContext(canvas);
38
+ if (!ctxResult.ok) return { kind: 'rhi-err', error: ctxResult.error };
39
+ const context: RhiCanvasContext = ctxResult.value;
40
+
41
+ const lostRegistry = new LostListenerRegistry();
42
+ const errorRegistry = new RhiErrorListenerRegistry();
43
+ const healthRegistry = new HealthListenerRegistry();
44
+ const lossObserver: { current?: (detail: string) => void } = {};
45
+ const generationState: { current: number; onStaleLoss?: () => void } = { current: 0 };
46
+ attachDeviceLostFanout(device, pack, {
47
+ lostRegistry,
48
+ errorRegistry,
49
+ healthRegistry,
50
+ generation: 0,
51
+ currentGeneration: () => generationState.current,
52
+ onStaleLoss: () => generationState.onStaleLoss?.(),
53
+ onDeviceLost: (detail) => lossObserver.current?.(detail),
54
+ });
55
+
56
+ if (pack._internal_getRawDevice && pack.translateErrorEventToRhiError) {
57
+ const backendDevice = pack._internal_getRawDevice(device);
58
+ if (backendDevice && typeof backendDevice === 'object') {
59
+ const target = backendDevice as {
60
+ onuncapturederror?: ((event: unknown) => void) | null;
61
+ };
62
+ target.onuncapturederror = (event: unknown): void => {
63
+ const translated = pack.translateErrorEventToRhiError?.(event);
64
+ if (translated && !translated.ok) errorRegistry.fire(translated.error);
65
+ };
66
+ }
67
+ }
68
+ return {
69
+ kind: 'ok',
70
+ renderer: await createRenderer({
71
+ canvas,
72
+ device,
73
+ context,
74
+ options,
75
+ bundler,
76
+ lostRegistry,
77
+ errorRegistry,
78
+ healthRegistry,
79
+ pack,
80
+ importTransport,
81
+ lossObserver,
82
+ generationState,
83
+ }),
84
+ };
85
+ }
@@ -0,0 +1,69 @@
1
+ import type { RhiCanvasContext, RhiDevice, RhiError } from '@forgeax/engine-rhi';
2
+ import type { ImportTransport } from '@forgeax/engine-types';
3
+ import type { RenderFeatureHost } from '../features/host';
4
+ import type {
5
+ HealthListenerRegistry,
6
+ LostListenerRegistry,
7
+ RhiErrorListenerRegistry,
8
+ } from '../lifecycle';
9
+ import type { GpuPassTimingReason } from '../record/gpu-pass-timing/errors.js';
10
+ import type {
11
+ GpuPassTimingCapture,
12
+ GpuPassTimingFrameIdentity,
13
+ } from '../record/gpu-pass-timing/index.js';
14
+ import type {
15
+ AtmosphereShaderSources,
16
+ FrameObservationDomain,
17
+ RenderDebugOverlay,
18
+ RendererOptions,
19
+ SsrShaderSources,
20
+ VolumetricFogShaderSources,
21
+ } from '../render-contract';
22
+ import type { TypedFrameObservationCapture } from '../typed-render-graph-primitives';
23
+ import type { RhiBackendPack } from './backend-contract';
24
+ import type { BundlerOptions } from './bundler-contract';
25
+ import type { RendererAssemblyImplementation } from './host-contract';
26
+ import type { MeshSsboGrowResult, MeshSsboState } from './mesh-ssbo-grow';
27
+
28
+ export type WebGPUOutcome =
29
+ | { kind: 'ok'; renderer: RendererAssemblyImplementation }
30
+ | { kind: 'rhi-err'; error: RhiError }
31
+ | { kind: 'throw'; error: Error };
32
+
33
+ export interface WebGPURendererInternals {
34
+ canvas: HTMLCanvasElement | OffscreenCanvas;
35
+ device: RhiDevice;
36
+ context: RhiCanvasContext;
37
+ options: RendererOptions | undefined;
38
+ bundler: BundlerOptions | undefined;
39
+ lostRegistry: LostListenerRegistry;
40
+ errorRegistry: RhiErrorListenerRegistry;
41
+ healthRegistry: HealthListenerRegistry;
42
+ pack: RhiBackendPack;
43
+ importTransport?: ImportTransport | undefined;
44
+ growMeshSsbo?: (neededSlots: number) => MeshSsboGrowResult;
45
+ meshSsboState?: MeshSsboState;
46
+ featureHost?: RenderFeatureHost;
47
+ debugOverlay?: RenderDebugOverlay;
48
+ volumetricFogShaders?: VolumetricFogShaderSources | undefined;
49
+ ssrShaders?: SsrShaderSources | undefined;
50
+ atmosphereShaders?: AtmosphereShaderSources | undefined;
51
+ gpuPassTimingSubmittedWork?: Promise<void> | undefined;
52
+ lossObserver: { current?: (detail: string) => void };
53
+ generationState: {
54
+ current: number;
55
+ onStaleLoss?: () => void;
56
+ };
57
+ getMaterialShaderUvSetCount?: (materialShaderId: string) => number | undefined;
58
+ gpuPassTimingFrameIdentity?: GpuPassTimingFrameIdentity | undefined;
59
+ gpuPassTimingCapture?: GpuPassTimingCapture | undefined;
60
+ gpuPassTimingBeginReason?: GpuPassTimingReason | undefined;
61
+ observationCaptureOwner?: {
62
+ register(capture: TypedFrameObservationCapture): void;
63
+ consume(frameNumber: number): readonly TypedFrameObservationCapture[];
64
+ drain(): readonly TypedFrameObservationCapture[];
65
+ };
66
+ observationCaptureDomains?: readonly FrameObservationDomain[] | undefined;
67
+ observationFrameId?: number | undefined;
68
+ observationGraphGeneration?: number | undefined;
69
+ }
@@ -0,0 +1,32 @@
1
+ import type { World } from '@forgeax/engine-ecs';
2
+ import { RendererContractFailureError, RendererOperationError } from '../errors/render';
3
+
4
+ /**
5
+ * Derived geometry and voxel physics publish together. A draw is rejected
6
+ * until that pair has completed its fixed-step writeback, so the renderer
7
+ * never consumes a half-published World snapshot.
8
+ */
9
+ export function derivedPhysicsFrameError(
10
+ worlds: readonly World[],
11
+ ): RendererOperationError<'frame-input-invalid'> | undefined {
12
+ for (const world of worlds) {
13
+ if (!world.hasResource('PhysicsWorld')) continue;
14
+ const physics = world.getResource<{
15
+ readonly getDerivedAdmission?: () => unknown;
16
+ readonly getDerivedRecoveryState?: () => string;
17
+ }>('PhysicsWorld');
18
+ if (
19
+ physics?.getDerivedAdmission?.() !== undefined ||
20
+ physics?.getDerivedRecoveryState?.() === 'rebuild-required'
21
+ ) {
22
+ return new RendererOperationError('frame-input-invalid', {
23
+ operation: 'draw',
24
+ cause: new RendererContractFailureError(
25
+ 'draw',
26
+ 'paired geometry admission must finish physics step and writeback in a healthy World before draw',
27
+ ),
28
+ });
29
+ }
30
+ }
31
+ return undefined;
32
+ }