@forgeax/engine-render 0.1.28 → 0.1.30

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 (768) hide show
  1. package/README.md +856 -126
  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/device-feature-admission.d.ts +4 -3
  5. package/dist/assembly/device-feature-admission.d.ts.map +1 -1
  6. package/dist/assembly/dynamic-geometry-host.d.ts +27 -0
  7. package/dist/assembly/dynamic-geometry-host.d.ts.map +1 -1
  8. package/dist/assembly/dynamic-geometry-runtime.d.ts +20 -0
  9. package/dist/assembly/dynamic-geometry-runtime.d.ts.map +1 -0
  10. package/dist/assembly/factory.d.ts +3 -1
  11. package/dist/assembly/factory.d.ts.map +1 -1
  12. package/dist/assembly/gpu-driven-owner.d.ts +10 -0
  13. package/dist/assembly/gpu-driven-owner.d.ts.map +1 -0
  14. package/dist/assembly/host-contract.d.ts +14 -0
  15. package/dist/assembly/host-contract.d.ts.map +1 -1
  16. package/dist/assembly/material/assembly.d.ts +31 -1
  17. package/dist/assembly/material/assembly.d.ts.map +1 -1
  18. package/dist/assembly/material/pipeline-helpers.d.ts +24 -0
  19. package/dist/assembly/material/pipeline-helpers.d.ts.map +1 -0
  20. package/dist/assembly/material-shader-policy.d.ts +3 -1
  21. package/dist/assembly/material-shader-policy.d.ts.map +1 -1
  22. package/dist/assembly/recovery/device-loss-fanout.d.ts.map +1 -1
  23. package/dist/assembly/recovery/failure-location.d.ts +12 -0
  24. package/dist/assembly/recovery/failure-location.d.ts.map +1 -0
  25. package/dist/assembly/recovery/recovery-attempt.d.ts +1 -6
  26. package/dist/assembly/recovery/recovery-attempt.d.ts.map +1 -1
  27. package/dist/assembly/recovery/renderer-recover.d.ts +7 -4
  28. package/dist/assembly/recovery/renderer-recover.d.ts.map +1 -1
  29. package/dist/assembly/renderer-facade.d.ts.map +1 -1
  30. package/dist/assembly/renderer-feature-inspection.d.ts +5 -0
  31. package/dist/assembly/renderer-feature-inspection.d.ts.map +1 -0
  32. package/dist/assembly/renderer-frame-transaction.d.ts +19 -0
  33. package/dist/assembly/renderer-frame-transaction.d.ts.map +1 -1
  34. package/dist/assembly/renderer-helpers.d.ts +3 -0
  35. package/dist/assembly/renderer-helpers.d.ts.map +1 -1
  36. package/dist/assembly/renderer-inspection.d.ts +4 -0
  37. package/dist/assembly/renderer-inspection.d.ts.map +1 -1
  38. package/dist/assembly/shader-prewarm-policy.d.ts +7 -1
  39. package/dist/assembly/shader-prewarm-policy.d.ts.map +1 -1
  40. package/dist/assembly/skin-palette-owner.d.ts +8 -0
  41. package/dist/assembly/skin-palette-owner.d.ts.map +1 -0
  42. package/dist/assembly/ssr-shader-prewarm.d.ts +6 -0
  43. package/dist/assembly/ssr-shader-prewarm.d.ts.map +1 -0
  44. package/dist/assembly/webgpu-device-loss.d.ts +15 -0
  45. package/dist/assembly/webgpu-device-loss.d.ts.map +1 -0
  46. package/dist/assembly/webgpu-pbr-ready.d.ts +38 -0
  47. package/dist/assembly/webgpu-pbr-ready.d.ts.map +1 -0
  48. package/dist/assembly/webgpu-ready-mipmap.d.ts +11 -0
  49. package/dist/assembly/webgpu-ready-mipmap.d.ts.map +1 -0
  50. package/dist/assembly/webgpu-ready.d.ts +7 -3
  51. package/dist/assembly/webgpu-ready.d.ts.map +1 -1
  52. package/dist/assembly/webgpu-renderer-bootstrap.d.ts +10 -0
  53. package/dist/assembly/webgpu-renderer-bootstrap.d.ts.map +1 -0
  54. package/dist/assembly/webgpu-renderer-contract.d.ts +62 -0
  55. package/dist/assembly/webgpu-renderer-contract.d.ts.map +1 -0
  56. package/dist/assembly/webgpu-renderer-guards.d.ts +9 -0
  57. package/dist/assembly/webgpu-renderer-guards.d.ts.map +1 -0
  58. package/dist/assembly/webgpu-renderer-observation.d.ts +6 -0
  59. package/dist/assembly/webgpu-renderer-observation.d.ts.map +1 -0
  60. package/dist/assembly/webgpu-renderer-recovery-failure.d.ts +12 -0
  61. package/dist/assembly/webgpu-renderer-recovery-failure.d.ts.map +1 -0
  62. package/dist/assembly/webgpu-renderer.d.ts +7 -141
  63. package/dist/assembly/webgpu-renderer.d.ts.map +1 -1
  64. package/dist/assembly/webgpu-vertex-layouts.d.ts +28 -84
  65. package/dist/assembly/webgpu-vertex-layouts.d.ts.map +1 -1
  66. package/dist/authoring.mjs +2 -2
  67. package/dist/capture/scene-projection.d.ts +41 -0
  68. package/dist/capture/scene-projection.d.ts.map +1 -0
  69. package/dist/{chunk-J52NMQKR.mjs → chunk-7MQ3XBSP.mjs} +1098 -844
  70. package/dist/chunk-7MQ3XBSP.mjs.map +1 -0
  71. package/dist/{chunk-GF523LHF.mjs → chunk-BLXGONR2.mjs} +30 -12
  72. package/dist/chunk-BLXGONR2.mjs.map +1 -0
  73. package/dist/{chunk-VSL23LZE.mjs → chunk-C3DDSXYK.mjs} +1188 -463
  74. package/dist/chunk-C3DDSXYK.mjs.map +1 -0
  75. package/dist/{chunk-IQMKJLNU.mjs → chunk-FUUO4UND.mjs} +443 -30
  76. package/dist/chunk-FUUO4UND.mjs.map +1 -0
  77. package/dist/{chunk-J6KACNOH.mjs → chunk-JRBDO2KB.mjs} +617 -7
  78. package/dist/chunk-JRBDO2KB.mjs.map +1 -0
  79. package/dist/{chunk-GE3SDD72.mjs → chunk-MDQJPY3T.mjs} +20 -40
  80. package/dist/chunk-MDQJPY3T.mjs.map +1 -0
  81. package/dist/{chunk-MYJ5RPJO.mjs → chunk-NO4WZCAH.mjs} +3 -3
  82. package/dist/chunk-NO4WZCAH.mjs.map +1 -0
  83. package/dist/{chunk-RBDBZ5R7.mjs → chunk-PA5DRJNI.mjs} +2 -2
  84. package/dist/chunk-PA5DRJNI.mjs.map +1 -0
  85. package/dist/{chunk-MBU4ZVE7.mjs → chunk-PSEQ6QPH.mjs} +4655 -892
  86. package/dist/chunk-PSEQ6QPH.mjs.map +1 -0
  87. package/dist/{chunk-JAASCMXA.mjs → chunk-S5UE2T5P.mjs} +289 -41
  88. package/dist/chunk-S5UE2T5P.mjs.map +1 -0
  89. package/dist/components/camera.d.ts +62 -2
  90. package/dist/components/camera.d.ts.map +1 -1
  91. package/dist/components/directional-light.d.ts +2 -2
  92. package/dist/components/dynamic-resolution.d.ts +15 -0
  93. package/dist/components/dynamic-resolution.d.ts.map +1 -0
  94. package/dist/components/index.d.ts +2 -0
  95. package/dist/components/index.d.ts.map +1 -1
  96. package/dist/components/instances.d.ts +6 -20
  97. package/dist/components/instances.d.ts.map +1 -1
  98. package/dist/components/light-helpers.d.ts.map +1 -1
  99. package/dist/components/reflection-probe.d.ts +1 -0
  100. package/dist/components/reflection-probe.d.ts.map +1 -1
  101. package/dist/components/scene-instance.d.ts +2 -1
  102. package/dist/components/scene-instance.d.ts.map +1 -1
  103. package/dist/components/screen-space-reflection.d.ts +14 -0
  104. package/dist/components/screen-space-reflection.d.ts.map +1 -0
  105. package/dist/components/skylight.d.ts +4 -1
  106. package/dist/components/skylight.d.ts.map +1 -1
  107. package/dist/construct-renderer.mjs +14809 -7570
  108. package/dist/construct-renderer.mjs.map +1 -1
  109. package/dist/device/device-scope.d.ts +2 -0
  110. package/dist/device/device-scope.d.ts.map +1 -1
  111. package/dist/device/gpu-residency.d.ts +3 -14
  112. package/dist/device/gpu-residency.d.ts.map +1 -1
  113. package/dist/dynamic-geometry.d.ts.map +1 -1
  114. package/dist/environment/background.d.ts +7 -0
  115. package/dist/environment/background.d.ts.map +1 -0
  116. package/dist/environment/ibl.d.ts +11 -0
  117. package/dist/environment/ibl.d.ts.map +1 -0
  118. package/dist/environment/storage.d.ts +14 -0
  119. package/dist/environment/storage.d.ts.map +1 -0
  120. package/dist/errors/gpu-driven.d.ts +6 -3
  121. package/dist/errors/gpu-driven.d.ts.map +1 -1
  122. package/dist/errors/render.d.ts +41 -4
  123. package/dist/errors/render.d.ts.map +1 -1
  124. package/dist/extract/camera.d.ts.map +1 -1
  125. package/dist/extract/contracts.d.ts +7 -0
  126. package/dist/extract/contracts.d.ts.map +1 -1
  127. package/dist/extract/gpu-driven.d.ts +50 -3
  128. package/dist/extract/gpu-driven.d.ts.map +1 -1
  129. package/dist/features/host.d.ts +23 -1
  130. package/dist/features/host.d.ts.map +1 -1
  131. package/dist/features/noise-texture.d.ts +17 -0
  132. package/dist/features/noise-texture.d.ts.map +1 -0
  133. package/dist/features/plan.d.ts +83 -2
  134. package/dist/features/plan.d.ts.map +1 -1
  135. package/dist/features/prepared-gpu-work.d.ts +37 -4
  136. package/dist/features/prepared-gpu-work.d.ts.map +1 -1
  137. package/dist/features/prepared-graphics-store.d.ts.map +1 -1
  138. package/dist/features/prepared-graphics.d.ts +5 -0
  139. package/dist/features/prepared-graphics.d.ts.map +1 -1
  140. package/dist/features/render-graph-compute.d.ts +5 -3
  141. package/dist/features/render-graph-compute.d.ts.map +1 -1
  142. package/dist/features/render-graph-contribution.d.ts +11 -3
  143. package/dist/features/render-graph-contribution.d.ts.map +1 -1
  144. package/dist/features/render-graph-raster.d.ts +19 -3
  145. package/dist/features/render-graph-raster.d.ts.map +1 -1
  146. package/dist/features/types.d.ts +11 -0
  147. package/dist/features/types.d.ts.map +1 -1
  148. package/dist/fullscreen-post-process-pass.d.ts +2 -0
  149. package/dist/fullscreen-post-process-pass.d.ts.map +1 -1
  150. package/dist/gpu-driven/batch-topology.d.ts +34 -1
  151. package/dist/gpu-driven/batch-topology.d.ts.map +1 -1
  152. package/dist/gpu-driven/material-artifacts.d.ts +24 -0
  153. package/dist/gpu-driven/material-artifacts.d.ts.map +1 -0
  154. package/dist/gpu-driven/material-bindings.d.ts +7 -0
  155. package/dist/gpu-driven/material-bindings.d.ts.map +1 -0
  156. package/dist/gpu-driven/pbr-program.d.ts +10 -0
  157. package/dist/gpu-driven/pbr-program.d.ts.map +1 -0
  158. package/dist/gpu-driven/prepared-draw.d.ts +2 -0
  159. package/dist/gpu-driven/prepared-draw.d.ts.map +1 -1
  160. package/dist/gpu-driven/production-raster.d.ts +169 -27
  161. package/dist/gpu-driven/production-raster.d.ts.map +1 -1
  162. package/dist/gpu-driven/shadow-views.d.ts +126 -0
  163. package/dist/gpu-driven/shadow-views.d.ts.map +1 -0
  164. package/dist/gpu-driven/view-gpu.d.ts +18 -2
  165. package/dist/gpu-driven/view-gpu.d.ts.map +1 -1
  166. package/dist/gpu-resource.d.ts +5 -2
  167. package/dist/gpu-resource.d.ts.map +1 -1
  168. package/dist/gpu-scene-schema.d.ts +2 -8
  169. package/dist/gpu-scene-schema.d.ts.map +1 -1
  170. package/dist/gpu-scene.d.ts +14 -0
  171. package/dist/gpu-scene.d.ts.map +1 -1
  172. package/dist/gpu-texture-usage.d.ts +1 -0
  173. package/dist/gpu-texture-usage.d.ts.map +1 -1
  174. package/dist/hdrp-buffers.d.ts +9 -0
  175. package/dist/hdrp-buffers.d.ts.map +1 -1
  176. package/dist/ibl/IblPipelineCache.d.ts +2 -0
  177. package/dist/ibl/IblPipelineCache.d.ts.map +1 -1
  178. package/dist/ibl/frame-resources.d.ts +8 -0
  179. package/dist/ibl/frame-resources.d.ts.map +1 -0
  180. package/dist/ibl/skylight-bind-group.d.ts +3 -1
  181. package/dist/ibl/skylight-bind-group.d.ts.map +1 -1
  182. package/dist/index.d.ts +87 -75
  183. package/dist/index.d.ts.map +1 -1
  184. package/dist/index.mjs +10 -8
  185. package/dist/index.mjs.map +1 -1
  186. package/dist/inspection-types.d.ts +180 -1
  187. package/dist/inspection-types.d.ts.map +1 -1
  188. package/dist/instances-derived-bounds.d.ts +11 -0
  189. package/dist/instances-derived-bounds.d.ts.map +1 -1
  190. package/dist/instances.d.ts +89 -44
  191. package/dist/instances.d.ts.map +1 -1
  192. package/dist/internal.d.ts +3 -0
  193. package/dist/internal.d.ts.map +1 -1
  194. package/dist/internal.mjs +117 -9
  195. package/dist/internal.mjs.map +1 -1
  196. package/dist/lifecycle.d.ts +2 -1
  197. package/dist/lifecycle.d.ts.map +1 -1
  198. package/dist/material-row.d.ts +15 -0
  199. package/dist/material-row.d.ts.map +1 -0
  200. package/dist/materials.d.ts +15 -0
  201. package/dist/materials.d.ts.map +1 -1
  202. package/dist/pbr-pipeline.d.ts +23 -5
  203. package/dist/pbr-pipeline.d.ts.map +1 -1
  204. package/dist/pipeline/render-extent.d.ts +51 -0
  205. package/dist/pipeline/render-extent.d.ts.map +1 -0
  206. package/dist/pipeline/standard-build-context.d.ts +7 -0
  207. package/dist/pipeline/standard-build-context.d.ts.map +1 -0
  208. package/dist/pipeline/standard-forward-lane.d.ts +3 -2
  209. package/dist/pipeline/standard-forward-lane.d.ts.map +1 -1
  210. package/dist/pipeline/standard-output/auto-exposure/capability.d.ts +12 -0
  211. package/dist/pipeline/standard-output/auto-exposure/capability.d.ts.map +1 -0
  212. package/dist/pipeline/standard-output/auto-exposure/gpu.d.ts +70 -0
  213. package/dist/pipeline/standard-output/auto-exposure/gpu.d.ts.map +1 -0
  214. package/dist/pipeline/standard-output/auto-exposure/graph.d.ts +75 -0
  215. package/dist/pipeline/standard-output/auto-exposure/graph.d.ts.map +1 -0
  216. package/dist/pipeline/standard-output/auto-exposure/inspection.d.ts +111 -0
  217. package/dist/pipeline/standard-output/auto-exposure/inspection.d.ts.map +1 -0
  218. package/dist/pipeline/standard-output/auto-exposure/oracle.d.ts +16 -0
  219. package/dist/pipeline/standard-output/auto-exposure/oracle.d.ts.map +1 -0
  220. package/dist/pipeline/standard-output/auto-exposure/preset.d.ts +14 -0
  221. package/dist/pipeline/standard-output/auto-exposure/preset.d.ts.map +1 -0
  222. package/dist/pipeline/standard-output/auto-exposure/state.d.ts +46 -0
  223. package/dist/pipeline/standard-output/auto-exposure/state.d.ts.map +1 -0
  224. package/dist/pipeline/standard-output/color-transform.d.ts +27 -0
  225. package/dist/pipeline/standard-output/color-transform.d.ts.map +1 -0
  226. package/dist/pipeline/standard-output/graph.d.ts +15 -0
  227. package/dist/pipeline/standard-output/graph.d.ts.map +1 -0
  228. package/dist/pipeline/standard-output/lut-admission.d.ts +29 -0
  229. package/dist/pipeline/standard-output/lut-admission.d.ts.map +1 -0
  230. package/dist/pipeline/standard-output/lut-gpu.d.ts +48 -0
  231. package/dist/pipeline/standard-output/lut-gpu.d.ts.map +1 -0
  232. package/dist/pipeline/standard-output/lut-state.d.ts +68 -0
  233. package/dist/pipeline/standard-output/lut-state.d.ts.map +1 -0
  234. package/dist/pipeline/standard-output/resources.d.ts +10 -0
  235. package/dist/pipeline/standard-output/resources.d.ts.map +1 -0
  236. package/dist/pipeline/standard-output/types.d.ts +39 -0
  237. package/dist/pipeline/standard-output/types.d.ts.map +1 -0
  238. package/dist/pipeline/standard-pipeline.d.ts.map +1 -1
  239. package/dist/pipeline/standard-post.d.ts +2 -2
  240. package/dist/pipeline/standard-post.d.ts.map +1 -1
  241. package/dist/pipeline/standard-profile.d.ts +2 -1
  242. package/dist/pipeline/standard-profile.d.ts.map +1 -1
  243. package/dist/pipeline-builder.d.ts +5 -2
  244. package/dist/pipeline-builder.d.ts.map +1 -1
  245. package/dist/pipeline-spec-types.d.ts +4 -0
  246. package/dist/pipeline-spec-types.d.ts.map +1 -1
  247. package/dist/pipeline-spec.d.ts +1 -9
  248. package/dist/pipeline-spec.d.ts.map +1 -1
  249. package/dist/plugin.d.ts.map +1 -1
  250. package/dist/points-lines/standard-owner.d.ts +1 -1
  251. package/dist/points-lines/standard-owner.d.ts.map +1 -1
  252. package/dist/post-process-errors.d.ts +9 -2
  253. package/dist/post-process-errors.d.ts.map +1 -1
  254. package/dist/prepare/extended-lighting/resources.d.ts +3 -3
  255. package/dist/prepare/prepared-graphics-resolver.d.ts +6 -1
  256. package/dist/prepare/prepared-graphics-resolver.d.ts.map +1 -1
  257. package/dist/record/dynamic-geometry-consumption.d.ts +15 -0
  258. package/dist/record/dynamic-geometry-consumption.d.ts.map +1 -0
  259. package/dist/record/frame-lighting.d.ts +3 -3
  260. package/dist/record/frame-lighting.d.ts.map +1 -1
  261. package/dist/record/frame-snapshot.d.ts +109 -13
  262. package/dist/record/frame-snapshot.d.ts.map +1 -1
  263. package/dist/record/frame-targets.d.ts.map +1 -1
  264. package/dist/record/frame.d.ts +41 -5
  265. package/dist/record/frame.d.ts.map +1 -1
  266. package/dist/record/main-pass-geometry.d.ts +13 -9
  267. package/dist/record/main-pass-geometry.d.ts.map +1 -1
  268. package/dist/record/main-pass-material.d.ts +43 -3
  269. package/dist/record/main-pass-material.d.ts.map +1 -1
  270. package/dist/record/main-pass-sprite-draws.d.ts +2 -10
  271. package/dist/record/main-pass-sprite-draws.d.ts.map +1 -1
  272. package/dist/record/main-pass.d.ts +14 -2
  273. package/dist/record/main-pass.d.ts.map +1 -1
  274. package/dist/record/mesh-ssbo.d.ts +15 -6
  275. package/dist/record/mesh-ssbo.d.ts.map +1 -1
  276. package/dist/record/prepared-material-bindings.d.ts +19 -0
  277. package/dist/record/prepared-material-bindings.d.ts.map +1 -0
  278. package/dist/record/recovery-pipeline.d.ts +1 -0
  279. package/dist/record/recovery-pipeline.d.ts.map +1 -1
  280. package/dist/record/render-context.d.ts +101 -22
  281. package/dist/record/render-context.d.ts.map +1 -1
  282. package/dist/record/shadow-pass.d.ts +62 -7
  283. package/dist/record/shadow-pass.d.ts.map +1 -1
  284. package/dist/record/skybox-post-pass.d.ts +1 -1
  285. package/dist/record/skybox-post-pass.d.ts.map +1 -1
  286. package/dist/record/typed-frame-graph.d.ts +39 -8
  287. package/dist/record/typed-frame-graph.d.ts.map +1 -1
  288. package/dist/record/view-ubo.d.ts +1 -0
  289. package/dist/record/view-ubo.d.ts.map +1 -1
  290. package/dist/recovery/render-system-candidate.d.ts +10 -2
  291. package/dist/recovery/render-system-candidate.d.ts.map +1 -1
  292. package/dist/recovery/render-system-roots.d.ts +11 -0
  293. package/dist/recovery/render-system-roots.d.ts.map +1 -0
  294. package/dist/recovery/types.d.ts +76 -0
  295. package/dist/recovery/types.d.ts.map +1 -0
  296. package/dist/reflection/background.d.ts +14 -0
  297. package/dist/reflection/background.d.ts.map +1 -0
  298. package/dist/reflection/filter.d.ts.map +1 -1
  299. package/dist/reflection/projection.d.ts +1 -0
  300. package/dist/reflection/projection.d.ts.map +1 -1
  301. package/dist/reflection/record-owner.d.ts +4 -4
  302. package/dist/reflection/record-owner.d.ts.map +1 -1
  303. package/dist/render-contract.d.ts +211 -53
  304. package/dist/render-contract.d.ts.map +1 -1
  305. package/dist/render-graph-primitives.d.ts +1 -0
  306. package/dist/render-graph-primitives.d.ts.map +1 -1
  307. package/dist/render-pipeline.d.ts +81 -6
  308. package/dist/render-pipeline.d.ts.map +1 -1
  309. package/dist/render-system-extract-tail.d.ts +15 -6
  310. package/dist/render-system-extract-tail.d.ts.map +1 -1
  311. package/dist/render-system-extract.d.ts +128 -41
  312. package/dist/render-system-extract.d.ts.map +1 -1
  313. package/dist/render-system-projections.d.ts +22 -0
  314. package/dist/render-system-projections.d.ts.map +1 -0
  315. package/dist/render-system.d.ts +27 -77
  316. package/dist/render-system.d.ts.map +1 -1
  317. package/dist/scene/render-scene-types.d.ts +14 -7
  318. package/dist/scene/render-scene-types.d.ts.map +1 -1
  319. package/dist/scene/render-scene.d.ts +31 -11
  320. package/dist/scene/render-scene.d.ts.map +1 -1
  321. package/dist/scene/shadow-visibility.d.ts +5 -0
  322. package/dist/scene/shadow-visibility.d.ts.map +1 -0
  323. package/dist/ssao-config.d.ts +8 -6
  324. package/dist/ssao-config.d.ts.map +1 -1
  325. package/dist/ssr/admission.d.ts +70 -1
  326. package/dist/ssr/admission.d.ts.map +1 -1
  327. package/dist/ssr/compose.d.ts +13 -0
  328. package/dist/ssr/compose.d.ts.map +1 -0
  329. package/dist/ssr/errors.d.ts +35 -0
  330. package/dist/ssr/errors.d.ts.map +1 -1
  331. package/dist/ssr/graph.d.ts +60 -0
  332. package/dist/ssr/graph.d.ts.map +1 -0
  333. package/dist/ssr/history.d.ts +97 -0
  334. package/dist/ssr/history.d.ts.map +1 -0
  335. package/dist/ssr/hiz.d.ts +37 -0
  336. package/dist/ssr/hiz.d.ts.map +1 -0
  337. package/dist/ssr/inspection.d.ts +42 -0
  338. package/dist/ssr/inspection.d.ts.map +1 -0
  339. package/dist/ssr/resources.d.ts +58 -0
  340. package/dist/ssr/resources.d.ts.map +1 -0
  341. package/dist/ssr/temporal.d.ts +38 -0
  342. package/dist/ssr/temporal.d.ts.map +1 -0
  343. package/dist/systems/skin-palette-allocator.d.ts +32 -10
  344. package/dist/systems/skin-palette-allocator.d.ts.map +1 -1
  345. package/dist/systems/skin-palette-types.d.ts +15 -0
  346. package/dist/systems/skin-palette-types.d.ts.map +1 -1
  347. package/dist/systems/transparent-dispatch.d.ts +9 -0
  348. package/dist/systems/transparent-dispatch.d.ts.map +1 -0
  349. package/dist/targets/material-source.d.ts +7 -0
  350. package/dist/targets/material-source.d.ts.map +1 -1
  351. package/dist/temporal/frame-coordinator.d.ts +7 -0
  352. package/dist/temporal/frame-coordinator.d.ts.map +1 -1
  353. package/dist/temporal/gpu.d.ts +8 -0
  354. package/dist/temporal/gpu.d.ts.map +1 -1
  355. package/dist/temporal/history.d.ts.map +1 -1
  356. package/dist/temporal/index.mjs +6 -6
  357. package/dist/temporal/inspection.d.ts.map +1 -1
  358. package/dist/temporal/standard-scene-data.d.ts +4 -2
  359. package/dist/temporal/standard-scene-data.d.ts.map +1 -1
  360. package/dist/temporal/target-coverage-attachment.d.ts +15 -0
  361. package/dist/temporal/target-coverage-attachment.d.ts.map +1 -0
  362. package/dist/temporal/temporal-view.d.ts +6 -0
  363. package/dist/temporal/temporal-view.d.ts.map +1 -1
  364. package/dist/temporal/view.d.ts +6 -0
  365. package/dist/temporal/view.d.ts.map +1 -1
  366. package/dist/typed-render-graph-primitives.d.ts +41 -1
  367. package/dist/typed-render-graph-primitives.d.ts.map +1 -1
  368. package/dist/typed-shadow-passes.d.ts +3 -1
  369. package/dist/typed-shadow-passes.d.ts.map +1 -1
  370. package/dist/volume/component.d.ts +1 -0
  371. package/dist/volume/component.d.ts.map +1 -1
  372. package/dist/volume/temporal.d.ts +6 -0
  373. package/dist/volume/temporal.d.ts.map +1 -1
  374. package/package.json +21 -20
  375. package/src/__tests__/auto-exposure-gpu-evidence.ts +291 -0
  376. package/src/__tests__/auto-exposure-inspection.unit.test.ts +80 -0
  377. package/src/__tests__/auto-exposure-transaction.integration.test.ts +99 -0
  378. package/src/__tests__/auto-exposure.browser.test.ts +33 -0
  379. package/src/__tests__/auto-exposure.dawn.test.ts +33 -0
  380. package/src/__tests__/capture-scene-projection.unit.test.ts +24 -0
  381. package/src/__tests__/detached-inspection.integration.test.ts +5 -0
  382. package/src/__tests__/device-feature-admission.unit.test.ts +15 -24
  383. package/src/__tests__/device-loss-fanout.unit.test.ts +43 -0
  384. package/src/__tests__/device-scope-lifecycle.unit.test.ts +18 -0
  385. package/src/__tests__/device-scope-stale-matrix.unit.test.ts +18 -0
  386. package/src/__tests__/docs-gate-green.unit.test.ts +3 -3
  387. package/src/__tests__/dynamic-geometry-batch.unit.test.ts +157 -0
  388. package/src/__tests__/dynamic-geometry.unit.test.ts +36 -0
  389. package/src/__tests__/dynamic-resolution-plugin.integration.test.ts +81 -0
  390. package/src/__tests__/factory-contract.integration.test.ts +231 -9
  391. package/src/__tests__/fallback-row-stride-surface.unit.test.ts +19 -0
  392. package/src/__tests__/feature-depth-input.dawn.test.ts +121 -0
  393. package/src/__tests__/feature-noise.unit.test.ts +38 -0
  394. package/src/__tests__/fixtures/taa-resolve-pinned-baseline.wgsl +301 -0
  395. package/src/__tests__/frame-camera-selection.unit.test.ts +131 -0
  396. package/src/__tests__/frame-observation.contract.test.ts +21 -0
  397. package/src/__tests__/frame-plan-contract.unit.test.ts +24 -0
  398. package/src/__tests__/frame-targets.unit.test.ts +24 -0
  399. package/src/__tests__/fullscreen-feature-plan.unit.test.ts +3 -0
  400. package/src/__tests__/gpu-driven-baseline.characterization.test.ts +79 -0
  401. package/src/__tests__/gpu-driven-batch-topology-pbr.unit.test.ts +307 -7
  402. package/src/__tests__/gpu-driven-indirect-raster-evidence.ts +122 -142
  403. package/src/__tests__/gpu-driven-indirect-raster.browser.test.ts +10 -1
  404. package/src/__tests__/gpu-driven-lod-cache.unit.test.ts +261 -0
  405. package/src/__tests__/gpu-driven-mesh-world-identity.unit.test.ts +346 -0
  406. package/src/__tests__/gpu-driven-pbr.dawn.test.ts +1422 -0
  407. package/src/__tests__/gpu-driven-pbr.integration.test.ts +21 -0
  408. package/src/__tests__/gpu-driven-production-fixture.ts +96 -0
  409. package/src/__tests__/gpu-driven-production.integration.test.ts +1076 -106
  410. package/src/__tests__/gpu-driven-scaling.unit.test.ts +1 -3
  411. package/src/__tests__/gpu-driven-shadow-views.browser.test.ts +63 -0
  412. package/src/__tests__/gpu-driven-shadow-views.dawn.test.ts +294 -0
  413. package/src/__tests__/gpu-driven-shadow-views.integration.test.ts +97 -0
  414. package/src/__tests__/gpu-driven-shadow-views.unit.test.ts +168 -0
  415. package/src/__tests__/gpu-driven-skin-contract.test-d.ts +11 -0
  416. package/src/__tests__/gpu-driven-view-gpu-evidence.ts +72 -20
  417. package/src/__tests__/gpu-driven-view-graph.integration.test.ts +30 -9
  418. package/src/__tests__/gpu-driven-view.unit.test.ts +160 -52
  419. package/src/__tests__/gpu-pass-timing-browser-runner.ts +15 -0
  420. package/src/__tests__/gpu-pass-timing.browser.test.ts +20 -2
  421. package/src/__tests__/gpu-resource-scope.unit.test.ts +71 -0
  422. package/src/__tests__/gpu-resource-store-stride.unit.test.ts +42 -0
  423. package/src/__tests__/gpu-scene-render-graph-gpu.ts +19 -5
  424. package/src/__tests__/gpu-scene.dawn.test.ts +40 -13
  425. package/src/__tests__/gpu-scene.unit.test.ts +613 -33
  426. package/src/__tests__/instances-culling.integration.test.ts +36 -10
  427. package/src/__tests__/instances-derived-bounds.unit.test.ts +54 -0
  428. package/src/__tests__/instances-store.unit.test.ts +242 -39
  429. package/src/__tests__/ktx2-basis-gpu-consumer.dawn.test.ts +6 -0
  430. package/src/__tests__/lighting-scene-roundtrip.integration.test.ts +13 -16
  431. package/src/__tests__/lut-lkg-transaction.integration.test.ts +122 -0
  432. package/src/__tests__/material-contract-inventory.unit.test.ts +5 -6
  433. package/src/__tests__/material-dispatch-shader-id.unit.test.ts +51 -0
  434. package/src/__tests__/material-lane-selection.unit.test.ts +60 -0
  435. package/src/__tests__/material-numeric-upload.unit.test.ts +53 -0
  436. package/src/__tests__/material-texture-handles.unit.test.ts +18 -0
  437. package/src/__tests__/material-texture-source.unit.test.ts +87 -0
  438. package/src/__tests__/materials-authoring-validation.unit.test.ts +41 -0
  439. package/src/__tests__/materials-standard-contract.unit.test.ts +57 -3
  440. package/src/__tests__/mesh-buffer-usage-surface.unit.test.ts +4 -0
  441. package/src/__tests__/mesh-submission-lifetime.unit.test.ts +8 -0
  442. package/src/__tests__/morph-neutral-admission.unit.test.ts +19 -0
  443. package/src/__tests__/normal-fallback.dawn.test.ts +122 -0
  444. package/src/__tests__/particle-material-input-layout.unit.test.ts +104 -0
  445. package/src/__tests__/physical-clearcoat.integration.test.ts +42 -3
  446. package/src/__tests__/pipeline-texture-specialization.unit.test.ts +138 -0
  447. package/src/__tests__/point-shadow-inspection.unit.test.ts +2 -0
  448. package/src/__tests__/post-process-error-policy-owner.unit.test.ts +6 -5
  449. package/src/__tests__/prepared-gpu-driven-pbr-contract.test-d.ts +31 -0
  450. package/src/__tests__/prepared-gpu-driven-pbr-contract.unit.test.ts +39 -0
  451. package/src/__tests__/prepared-gpu-driven-pbr.integration.test.ts +251 -9
  452. package/src/__tests__/prepared-graphics-capability.unit.test.ts +21 -0
  453. package/src/__tests__/prepared-graphics-pipeline-warmup.unit.test.ts +6 -2
  454. package/src/__tests__/profiler-phase-catalog.test.ts +5 -0
  455. package/src/__tests__/public-surface.test-d.ts +3 -0
  456. package/src/__tests__/recovery-candidate-prepare.contract.test.ts +30 -12
  457. package/src/__tests__/reflection-fallback-async-publication.unit.test.ts +171 -0
  458. package/src/__tests__/reflection-probe-authoring.unit.test.ts +12 -10
  459. package/src/__tests__/reflection-probe-box.dawn.test.ts +71 -0
  460. package/src/__tests__/reflection-probe-filter.unit.test.ts +9 -0
  461. package/src/__tests__/reflection-probe-orientation.dawn.test.ts +294 -0
  462. package/src/__tests__/reflection-probe-record-owner.characterization.unit.test.ts +5 -14
  463. package/src/__tests__/reflection-probe-updates.unit.test.ts +129 -0
  464. package/src/__tests__/render-error-code-owner.test-d.ts +7 -0
  465. package/src/__tests__/render-error-detail-ssot.test-d.ts +27 -1
  466. package/src/__tests__/render-error-exhaustive.test-d.ts +15 -0
  467. package/src/__tests__/render-extent.unit.test.ts +63 -0
  468. package/src/__tests__/render-feature-gpu-work.integration.test.ts +285 -2
  469. package/src/__tests__/render-feature-plan.unit.test.ts +245 -0
  470. package/src/__tests__/render-feature-shadow-order.unit.test.ts +228 -0
  471. package/src/__tests__/render-feature-zero-work.unit.test.ts +35 -1
  472. package/src/__tests__/render-graph-fallback.integration.test.ts +2 -2
  473. package/src/__tests__/render-owner-cohesion.unit.test.ts +55 -0
  474. package/src/__tests__/render-scene-mixed-updates.integration.test.ts +426 -0
  475. package/src/__tests__/render-scene-projection.unit.test.ts +915 -23
  476. package/src/__tests__/render-scene-resource-updates.integration.test.ts +214 -0
  477. package/src/__tests__/render-scene-skin-lifecycle.integration.test.ts +173 -0
  478. package/src/__tests__/render-scene-temporal-retry.unit.test.ts +133 -0
  479. package/src/__tests__/render-target-material-source.test-d.ts +27 -3
  480. package/src/__tests__/renderer-factory-material-contract.unit.test.ts +233 -9
  481. package/src/__tests__/renderer-frame-transaction.integration.test.ts +923 -5
  482. package/src/__tests__/shader-manifest-fixture.ts +45 -0
  483. package/src/__tests__/skin-motion-regression.unit.test.ts +0 -33
  484. package/src/__tests__/skin-palette-persistent.integration.test.ts +28 -0
  485. package/src/__tests__/skin-palette-persistent.unit.test.ts +247 -0
  486. package/src/__tests__/skinned-shadow-caster.test.ts +125 -14
  487. package/src/__tests__/specular-environment-scale.dawn.test.ts +158 -0
  488. package/src/__tests__/ssao-config.unit.test.ts +7 -0
  489. package/src/__tests__/ssao-surface.dawn.test.ts +252 -0
  490. package/src/__tests__/ssr-admission-matrix.integration.test.ts +7 -1
  491. package/src/__tests__/ssr-confidence-compose.unit.test.ts +84 -0
  492. package/src/__tests__/ssr-coordinate-oracle.unit.test.ts +28 -0
  493. package/src/__tests__/ssr-cube-silhouette.dawn.test.ts +270 -0
  494. package/src/__tests__/ssr-format-probe-gating.integration.test.ts +82 -0
  495. package/src/__tests__/ssr-gpu-dispatch.browser.test.ts +99 -0
  496. package/src/__tests__/ssr-gpu-dispatch.dawn.test.ts +116 -0
  497. package/src/__tests__/ssr-gpu-dispatch.ts +951 -0
  498. package/src/__tests__/ssr-graph-topology.unit.test.ts +104 -0
  499. package/src/__tests__/ssr-history-filter.dawn.test.ts +198 -0
  500. package/src/__tests__/ssr-hit-color.dawn.test.ts +273 -0
  501. package/src/__tests__/ssr-hiz-odd-reduction.dawn.test.ts +569 -0
  502. package/src/__tests__/ssr-hiz-rescue.dawn.test.ts +279 -0
  503. package/src/__tests__/ssr-hiz.browser.test.ts +150 -0
  504. package/src/__tests__/ssr-hiz.dawn.test.ts +150 -0
  505. package/src/__tests__/ssr-hiz.unit.test.ts +56 -0
  506. package/src/__tests__/ssr-inspection.unit.test.ts +105 -0
  507. package/src/__tests__/ssr-memory-budget.unit.test.ts +45 -0
  508. package/src/__tests__/ssr-performance-sequence-aggregation.unit.test.ts +15 -0
  509. package/src/__tests__/ssr-public-surface.test-d.ts +37 -0
  510. package/src/__tests__/ssr-receiver-coverage.dawn.test.ts +387 -0
  511. package/src/__tests__/ssr-reflection-mip-reducer.dawn.test.ts +309 -0
  512. package/src/__tests__/ssr-reprojection-probe.ts +90 -0
  513. package/src/__tests__/ssr-roughness-mip.dawn.test.ts +163 -0
  514. package/src/__tests__/ssr-shader-prewarm.unit.test.ts +59 -0
  515. package/src/__tests__/ssr-spatial.integration.test.ts +141 -0
  516. package/src/__tests__/ssr-stable-lattice.dawn.test.ts +475 -0
  517. package/src/__tests__/ssr-temporal-history.unit.test.ts +202 -0
  518. package/src/__tests__/ssr-texel-crossing.dawn.test.ts +448 -0
  519. package/src/__tests__/ssr-zero-work.integration.test.ts +87 -0
  520. package/src/__tests__/standard-cluster-variant-resolution.unit.test.ts +84 -12
  521. package/src/__tests__/standard-clustered-pipeline.unit.test.ts +29 -0
  522. package/src/__tests__/standard-output-chain-contract.unit.test.ts +99 -0
  523. package/src/__tests__/standard-output-chain.integration.test.ts +73 -0
  524. package/src/__tests__/standard-output-gpu-evidence.ts +205 -0
  525. package/src/__tests__/standard-output.browser.test.ts +15 -0
  526. package/src/__tests__/standard-output.dawn.test.ts +15 -0
  527. package/src/__tests__/standard-pbr-artifact-assembly.unit.test.ts +275 -0
  528. package/src/__tests__/standard-pipeline.integration.test.ts +320 -3
  529. package/src/__tests__/standard-profile-oracle.unit.test.ts +49 -0
  530. package/src/__tests__/standard-surface-lighting.unit.test.ts +41 -0
  531. package/src/__tests__/standard-texture-specialization.dawn.test.ts +141 -0
  532. package/src/__tests__/surface-adjacent-regressions.integration.test.ts +6 -3
  533. package/src/__tests__/taa-coverage-edge.dawn.test.ts +199 -0
  534. package/src/__tests__/taa-history-clipping.dawn.test.ts +328 -0
  535. package/src/__tests__/taa-neighborhood-equivalence.dawn.test.ts +782 -0
  536. package/src/__tests__/taa-stability-feedback.browser.test.ts +23 -0
  537. package/src/__tests__/taa-stability-feedback.dawn.test.ts +68 -0
  538. package/src/__tests__/taa-stability-feedback.ts +342 -0
  539. package/src/__tests__/temporal-history-lifecycle.unit.test.ts +49 -7
  540. package/src/__tests__/temporal-reset-matrix.unit.test.ts +9 -0
  541. package/src/__tests__/temporal-transaction.integration.test.ts +28 -0
  542. package/src/__tests__/temporal-view.unit.test.ts +17 -0
  543. package/src/__tests__/texture-usage-surface.unit.test.ts +4 -2
  544. package/src/__tests__/transmission-prewarm.unit.test.ts +57 -0
  545. package/src/__tests__/typed-pipeline-topology.unit.test.ts +109 -4
  546. package/src/__tests__/typed-scene-pass-material-cache.integration.test.ts +126 -0
  547. package/src/__tests__/vertex-layouts-ssot.unit.test.ts +47 -0
  548. package/src/__tests__/visibility-extract.perf.test.ts +20 -8
  549. package/src/__tests__/visibility-instances.integration.test.ts +19 -7
  550. package/src/__tests__/visibility-producer-matrix.integration.test.ts +20 -9
  551. package/src/__tests__/volumetric-fog-stage-readback.dawn.test.ts +62 -13
  552. package/src/__tests__/volumetric-fog-topology.unit.test.ts +7 -7
  553. package/src/assembly/atmosphere-shader-prewarm.ts +39 -0
  554. package/src/assembly/device-feature-admission.ts +9 -4
  555. package/src/assembly/dynamic-geometry-host.ts +284 -163
  556. package/src/assembly/dynamic-geometry-runtime.ts +71 -0
  557. package/src/assembly/factory.ts +4 -0
  558. package/src/assembly/gpu-driven-owner.ts +29 -0
  559. package/src/assembly/host-contract.ts +19 -0
  560. package/src/assembly/material/assembly.ts +383 -1
  561. package/src/assembly/material/pipeline-helpers.ts +100 -0
  562. package/src/assembly/material-shader-policy.ts +110 -46
  563. package/src/assembly/recovery/device-loss-fanout.ts +5 -0
  564. package/src/assembly/recovery/failure-location.ts +62 -0
  565. package/src/assembly/recovery/recovery-attempt.ts +2 -29
  566. package/src/assembly/recovery/renderer-recover.ts +16 -17
  567. package/src/assembly/renderer-facade.ts +34 -1
  568. package/src/assembly/renderer-feature-inspection.ts +13 -0
  569. package/src/assembly/renderer-frame-transaction.ts +63 -0
  570. package/src/assembly/renderer-helpers.ts +26 -0
  571. package/src/assembly/renderer-inspection.ts +6 -0
  572. package/src/assembly/shader-prewarm-policy.ts +46 -1
  573. package/src/assembly/skin-palette-owner.ts +21 -0
  574. package/src/assembly/ssr-shader-prewarm.ts +41 -0
  575. package/src/assembly/webgpu-device-loss.ts +75 -0
  576. package/src/assembly/webgpu-pbr-ready.ts +232 -0
  577. package/src/assembly/webgpu-ready-mipmap.ts +26 -0
  578. package/src/assembly/webgpu-ready.ts +161 -131
  579. package/src/assembly/webgpu-renderer-bootstrap.ts +85 -0
  580. package/src/assembly/webgpu-renderer-contract.ts +69 -0
  581. package/src/assembly/webgpu-renderer-guards.ts +32 -0
  582. package/src/assembly/webgpu-renderer-observation.ts +43 -0
  583. package/src/assembly/webgpu-renderer-recovery-failure.ts +62 -0
  584. package/src/assembly/webgpu-renderer.ts +744 -730
  585. package/src/assembly/webgpu-vertex-layouts.ts +233 -87
  586. package/src/capture/scene-projection.ts +37 -0
  587. package/src/components/__tests__/camera-exposure.contract.unit.test.ts +153 -0
  588. package/src/components/__tests__/dynamic-resolution-schema.unit.test.ts +65 -0
  589. package/src/components/__tests__/light-radius.integration.test.ts +59 -0
  590. package/src/components/camera.ts +287 -7
  591. package/src/components/directional-light.ts +3 -3
  592. package/src/components/dynamic-resolution.ts +67 -0
  593. package/src/components/index.ts +2 -0
  594. package/src/components/instances.ts +45 -18
  595. package/src/components/light-helpers.ts +6 -1
  596. package/src/components/reflection-probe.ts +1 -0
  597. package/src/components/scene-instance.ts +2 -1
  598. package/src/components/screen-space-reflection.ts +21 -0
  599. package/src/components/skylight.ts +4 -1
  600. package/src/components/sprite-animation.ts +2 -2
  601. package/src/components/sprite-instances.ts +1 -1
  602. package/src/device/device-scope.ts +13 -7
  603. package/src/device/gpu-residency.ts +45 -42
  604. package/src/dynamic-geometry.ts +13 -8
  605. package/src/environment/background.ts +281 -0
  606. package/src/environment/ibl.ts +211 -0
  607. package/src/environment/storage.ts +63 -0
  608. package/src/errors/gpu-driven.ts +49 -8
  609. package/src/errors/render.ts +91 -3
  610. package/src/extract/camera.ts +37 -1
  611. package/src/extract/contracts.ts +10 -0
  612. package/src/extract/gpu-driven.ts +240 -10
  613. package/src/features/host.ts +237 -19
  614. package/src/features/noise-texture.ts +91 -0
  615. package/src/features/plan.ts +553 -24
  616. package/src/features/prepared-gpu-work.ts +631 -49
  617. package/src/features/prepared-graphics-store.ts +31 -0
  618. package/src/features/prepared-graphics.ts +5 -0
  619. package/src/features/render-graph-compute.ts +41 -8
  620. package/src/features/render-graph-contribution.ts +141 -3
  621. package/src/features/render-graph-raster.ts +143 -30
  622. package/src/features/types.ts +11 -0
  623. package/src/fullscreen-post-process-pass.ts +3 -0
  624. package/src/gpu-driven/batch-topology.ts +452 -108
  625. package/src/gpu-driven/material-artifacts.ts +179 -0
  626. package/src/gpu-driven/material-bindings.ts +41 -0
  627. package/src/gpu-driven/pbr-program.ts +31 -0
  628. package/src/gpu-driven/prepared-draw.ts +42 -6
  629. package/src/gpu-driven/production-raster.ts +2806 -716
  630. package/src/gpu-driven/shadow-views.ts +539 -0
  631. package/src/gpu-driven/view-gpu.ts +188 -41
  632. package/src/gpu-resource.ts +21 -2
  633. package/src/gpu-scene-schema.ts +61 -11
  634. package/src/gpu-scene.ts +197 -99
  635. package/src/gpu-texture-usage.ts +1 -0
  636. package/src/hdrp-buffers.ts +141 -36
  637. package/src/ibl/IblPipelineCache.ts +5 -0
  638. package/src/ibl/frame-resources.ts +38 -0
  639. package/src/ibl/skylight-bind-group.ts +32 -21
  640. package/src/index.ts +194 -75
  641. package/src/inspection-types.ts +207 -1
  642. package/src/instances-derived-bounds.ts +258 -34
  643. package/src/instances.ts +459 -150
  644. package/src/internal.ts +22 -0
  645. package/src/lifecycle.ts +2 -0
  646. package/src/material-row.ts +194 -0
  647. package/src/materials.ts +44 -8
  648. package/src/pbr-pipeline.ts +172 -19
  649. package/src/pipeline/render-extent.ts +111 -0
  650. package/src/pipeline/standard-build-context.ts +7 -0
  651. package/src/pipeline/standard-forward-lane.ts +74 -29
  652. package/src/pipeline/standard-output/__tests__/lut-admission.unit.test.ts +103 -0
  653. package/src/pipeline/standard-output/auto-exposure/__tests__/capability.unit.test.ts +40 -0
  654. package/src/pipeline/standard-output/auto-exposure/__tests__/gpu.contract.unit.test.ts +125 -0
  655. package/src/pipeline/standard-output/auto-exposure/__tests__/graph.contract.unit.test.ts +94 -0
  656. package/src/pipeline/standard-output/auto-exposure/__tests__/oracle.test.ts +108 -0
  657. package/src/pipeline/standard-output/auto-exposure/__tests__/preset.test.ts +26 -0
  658. package/src/pipeline/standard-output/auto-exposure/capability.ts +38 -0
  659. package/src/pipeline/standard-output/auto-exposure/gpu.ts +567 -0
  660. package/src/pipeline/standard-output/auto-exposure/graph.ts +221 -0
  661. package/src/pipeline/standard-output/auto-exposure/inspection.ts +231 -0
  662. package/src/pipeline/standard-output/auto-exposure/oracle.ts +291 -0
  663. package/src/pipeline/standard-output/auto-exposure/preset.ts +28 -0
  664. package/src/pipeline/standard-output/auto-exposure/state.ts +156 -0
  665. package/src/pipeline/standard-output/color-transform.ts +124 -0
  666. package/src/pipeline/standard-output/graph.ts +139 -0
  667. package/src/pipeline/standard-output/lut-admission.ts +121 -0
  668. package/src/pipeline/standard-output/lut-gpu.ts +399 -0
  669. package/src/pipeline/standard-output/lut-state.ts +176 -0
  670. package/src/pipeline/standard-output/resources.ts +121 -0
  671. package/src/pipeline/standard-output/types.ts +58 -0
  672. package/src/pipeline/standard-pipeline.ts +232 -70
  673. package/src/pipeline/standard-post.ts +190 -27
  674. package/src/pipeline/standard-profile.ts +2 -1
  675. package/src/pipeline-builder.ts +28 -9
  676. package/src/pipeline-spec-types.ts +4 -0
  677. package/src/pipeline-spec.ts +37 -29
  678. package/src/plugin.ts +4 -0
  679. package/src/points-lines/standard-owner.ts +6 -14
  680. package/src/post-process-errors.ts +26 -18
  681. package/src/prepare/__tests__/extended-lighting-capability.unit.test.ts +2 -2
  682. package/src/prepare/extended-lighting/resources.ts +3 -3
  683. package/src/prepare/prepared-graphics-resolver.ts +9 -2
  684. package/src/record/__tests__/main-pass-geometry.unit.test.ts +68 -0
  685. package/src/record/__tests__/material-bg-cache.unit.test.ts +45 -0
  686. package/src/record/__tests__/material-slot-plan.unit.test.ts +57 -0
  687. package/src/record/__tests__/mesh-ssbo.unit.test.ts +40 -1
  688. package/src/record/__tests__/recovery-pipeline.unit.test.ts +20 -1
  689. package/src/record/__tests__/sprite-material-abi.unit.test.ts +41 -6
  690. package/src/record/__tests__/temporal-payload.unit.test.ts +2 -0
  691. package/src/record/__tests__/typed-frame-graph-plan.unit.test.ts +45 -0
  692. package/src/record/__tests__/view-ubo-layout.unit.test.ts +5 -0
  693. package/src/record/dynamic-geometry-consumption.ts +59 -0
  694. package/src/record/frame-lighting.ts +15 -12
  695. package/src/record/frame-snapshot.ts +146 -34
  696. package/src/record/frame-targets.ts +9 -0
  697. package/src/record/frame.ts +838 -170
  698. package/src/record/main-pass-geometry.ts +209 -103
  699. package/src/record/main-pass-material.ts +157 -40
  700. package/src/record/main-pass-sprite-draws.ts +16 -107
  701. package/src/record/main-pass.ts +141 -12
  702. package/src/record/material-uniforms.ts +1 -1
  703. package/src/record/mesh-ssbo.ts +59 -15
  704. package/src/record/prepared-material-bindings.ts +238 -0
  705. package/src/record/recovery-pipeline.ts +69 -90
  706. package/src/record/render-context.ts +123 -24
  707. package/src/record/shadow-pass.ts +1389 -230
  708. package/src/record/skybox-post-pass.ts +14 -3
  709. package/src/record/typed-frame-graph.ts +1064 -47
  710. package/src/record/view-ubo.ts +12 -1
  711. package/src/recovery/render-system-candidate.ts +135 -68
  712. package/src/recovery/render-system-roots.ts +113 -0
  713. package/src/recovery/types.ts +77 -0
  714. package/src/reflection/background.ts +151 -0
  715. package/src/reflection/filter.ts +3 -0
  716. package/src/reflection/projection.ts +16 -6
  717. package/src/reflection/record-owner.ts +308 -140
  718. package/src/render-contract.ts +237 -49
  719. package/src/render-graph-primitives.ts +34 -5
  720. package/src/render-pipeline.ts +90 -2
  721. package/src/render-system-extract-tail.ts +431 -162
  722. package/src/render-system-extract.ts +478 -119
  723. package/src/render-system-projections.ts +241 -0
  724. package/src/render-system.ts +715 -828
  725. package/src/scene/render-scene-types.ts +13 -4
  726. package/src/scene/render-scene.ts +577 -355
  727. package/src/scene/shadow-visibility.ts +21 -0
  728. package/src/ssao-config.ts +25 -8
  729. package/src/ssr/admission.ts +380 -14
  730. package/src/ssr/compose.ts +144 -0
  731. package/src/ssr/errors.ts +48 -0
  732. package/src/ssr/graph.ts +797 -0
  733. package/src/ssr/history.ts +436 -0
  734. package/src/ssr/hiz.ts +124 -0
  735. package/src/ssr/inspection.ts +124 -0
  736. package/src/ssr/resources.ts +202 -0
  737. package/src/ssr/temporal.ts +164 -0
  738. package/src/systems/skin-palette-allocator.ts +495 -148
  739. package/src/systems/skin-palette-types.ts +17 -0
  740. package/src/systems/transparent-dispatch.ts +90 -0
  741. package/src/targets/material-source.ts +34 -0
  742. package/src/temporal/coverage.ts +1 -1
  743. package/src/temporal/frame-coordinator.ts +23 -2
  744. package/src/temporal/gpu.ts +79 -12
  745. package/src/temporal/history.ts +3 -1
  746. package/src/temporal/inspection.ts +2 -1
  747. package/src/temporal/standard-scene-data.ts +10 -2
  748. package/src/temporal/target-coverage-attachment.ts +72 -0
  749. package/src/temporal/temporal-view.ts +11 -2
  750. package/src/temporal/view.ts +12 -2
  751. package/src/transmission/__tests__/standard-transmission.dawn.test.ts +219 -139
  752. package/src/typed-render-graph-primitives.ts +304 -74
  753. package/src/typed-shadow-passes.ts +122 -12
  754. package/src/volume/component.ts +1 -0
  755. package/src/volume/passes.ts +3 -3
  756. package/src/volume/temporal.ts +10 -0
  757. package/dist/chunk-GE3SDD72.mjs.map +0 -1
  758. package/dist/chunk-GF523LHF.mjs.map +0 -1
  759. package/dist/chunk-IQMKJLNU.mjs.map +0 -1
  760. package/dist/chunk-J52NMQKR.mjs.map +0 -1
  761. package/dist/chunk-J6KACNOH.mjs.map +0 -1
  762. package/dist/chunk-JAASCMXA.mjs.map +0 -1
  763. package/dist/chunk-MBU4ZVE7.mjs.map +0 -1
  764. package/dist/chunk-MYJ5RPJO.mjs.map +0 -1
  765. package/dist/chunk-RBDBZ5R7.mjs.map +0 -1
  766. package/dist/chunk-VSL23LZE.mjs.map +0 -1
  767. package/src/__tests__/instances-world-ownership.integration.test.ts +0 -62
  768. package/src/scene/__tests__/changed-block-summary.candidate.test.ts +0 -36
@@ -1,4 +1,5 @@
1
1
  import type { PrimitiveTopology } from '@forgeax/engine-types';
2
+ import { gpuDrivenSourceDrawItemIndex } from '../extract/gpu-driven';
2
3
  import type { BatchTopologyInspection } from '../inspection-types';
3
4
  import type { CameraSnapshot } from '../render-contract';
4
5
  import type { RenderSceneApplyResult, RenderSceneSlot } from '../scene/render-scene-types';
@@ -8,6 +9,9 @@ import type { PreparedGpuDrivenDraw } from './prepared-draw';
8
9
 
9
10
  export type { BatchTopologyInspection } from '../inspection-types';
10
11
 
12
+ /** High bit in the compact candidate material lane marks a skin palette row. */
13
+ export const GPU_DRIVEN_SKIN_FLAG = 0x80000000;
14
+
11
15
  export interface GpuDrivenBatchKey {
12
16
  readonly assetHandle: number;
13
17
  readonly drawKind: 'indexed' | 'non-indexed';
@@ -31,6 +35,7 @@ export interface GpuDrivenCandidate {
31
35
  readonly generation: number;
32
36
  readonly drawItemIndex: number;
33
37
  readonly instanceOrdinal: number;
38
+ readonly prepared?: PreparedGpuDrivenDraw;
34
39
  /** Absolute coverage rows uploaded to the GPU selector; root is implicit. */
35
40
  readonly lodCoverages?: readonly number[];
36
41
  readonly lodHysteresis?: number;
@@ -40,7 +45,6 @@ export interface GpuDrivenCandidate {
40
45
  readonly count: number;
41
46
  readonly baseVertex: number;
42
47
  }[];
43
- readonly prepared?: PreparedGpuDrivenDraw;
44
48
  }
45
49
 
46
50
  export interface GpuDrivenBatch {
@@ -55,6 +59,8 @@ export interface GpuDrivenBatch {
55
59
 
56
60
  export interface SubmissionPlan {
57
61
  readonly revision: number;
62
+ /** Payload-only updates keep topology revision stable but still invalidate the plan snapshot. */
63
+ readonly payloadRevision: number;
58
64
  readonly batches: readonly GpuDrivenBatch[];
59
65
  readonly candidateCount: number;
60
66
  readonly visibleCapacity: number;
@@ -86,6 +92,88 @@ export function compactGpuLodCandidates(
86
92
  );
87
93
  }
88
94
 
95
+ export interface SubmissionCandidateMembershipEntry {
96
+ readonly batchId: number;
97
+ readonly candidate: GpuDrivenCandidate;
98
+ }
99
+
100
+ /**
101
+ * Immutable reverse membership for one submission topology.
102
+ *
103
+ * Shadow views query the same candidate domain as the main view. Keeping the
104
+ * primitive-to-batch join beside the immutable plan makes that lookup once per
105
+ * topology instead of rescanning every batch for every view.
106
+ */
107
+ export interface SubmissionCandidateMembership {
108
+ readonly source: SubmissionPlan;
109
+ readonly byPrimitiveIndex: ReadonlyMap<number, readonly SubmissionCandidateMembershipEntry[]>;
110
+ }
111
+
112
+ const submissionCandidateMembershipCache = new WeakMap<
113
+ SubmissionPlan,
114
+ SubmissionCandidateMembership
115
+ >();
116
+
117
+ export function buildSubmissionCandidateMembership(
118
+ source: SubmissionPlan,
119
+ ): SubmissionCandidateMembership {
120
+ const cached = submissionCandidateMembershipCache.get(source);
121
+ if (cached !== undefined) return cached;
122
+
123
+ const mutable = new Map<number, SubmissionCandidateMembershipEntry[]>();
124
+ for (const batch of source.batches) {
125
+ for (const candidate of batch.candidates) {
126
+ const entries = mutable.get(candidate.primitiveIndex) ?? [];
127
+ entries.push({ batchId: batch.batchId, candidate });
128
+ mutable.set(candidate.primitiveIndex, entries);
129
+ }
130
+ }
131
+ const byPrimitiveIndex = new Map<number, readonly SubmissionCandidateMembershipEntry[]>();
132
+ for (const [primitiveIndex, entries] of mutable) {
133
+ byPrimitiveIndex.set(primitiveIndex, Object.freeze(entries));
134
+ }
135
+ const membership: SubmissionCandidateMembership = {
136
+ source,
137
+ byPrimitiveIndex,
138
+ };
139
+ submissionCandidateMembershipCache.set(source, membership);
140
+ return membership;
141
+ }
142
+
143
+ /**
144
+ * Re-project one source topology for a view without changing batch identity.
145
+ * The returned plan only changes candidate windows and keeps batch ids,
146
+ * generations, draw ranges, and indirect offsets from the source plan.
147
+ */
148
+ export function buildBatchAlignedSubmission(
149
+ source: SubmissionPlan,
150
+ candidatesByBatch: ReadonlyMap<number, readonly GpuDrivenCandidate[]>,
151
+ ): SubmissionPlan {
152
+ let visibleBase = 0;
153
+ const batches: GpuDrivenBatch[] = [];
154
+ for (const sourceBatch of source.batches) {
155
+ const candidates = candidatesByBatch.get(sourceBatch.batchId) ?? [];
156
+ if (candidates.length === 0) continue;
157
+ visibleBase = alignInstanceBase(visibleBase);
158
+ batches.push(
159
+ Object.freeze({
160
+ ...sourceBatch,
161
+ candidates: Object.freeze([...candidates]),
162
+ visibleBase,
163
+ visibleCapacity: candidates.length,
164
+ }),
165
+ );
166
+ visibleBase += candidates.length;
167
+ }
168
+ return Object.freeze({
169
+ revision: source.revision,
170
+ payloadRevision: source.payloadRevision,
171
+ batches: Object.freeze(batches),
172
+ candidateCount: batches.reduce((total, batch) => total + batch.candidates.length, 0),
173
+ visibleCapacity: visibleBase,
174
+ });
175
+ }
176
+
89
177
  interface MutableBatch {
90
178
  readonly batchId: number;
91
179
  readonly generation: number;
@@ -93,7 +181,57 @@ interface MutableBatch {
93
181
  readonly candidates: Map<string, GpuDrivenCandidate>;
94
182
  }
95
183
 
96
- function eligibleKeys(slot: RenderSceneSlot): readonly GpuDrivenBatchKey[] {
184
+ interface EligibleGpuDrivenDraw {
185
+ readonly sourceDrawIndex: number;
186
+ readonly key: GpuDrivenBatchKey;
187
+ readonly prepared?: PreparedGpuDrivenDraw;
188
+ readonly projectedHeight?: number;
189
+ readonly lodCoverages?: readonly number[];
190
+ readonly lodHysteresis?: number;
191
+ readonly lodRanges?: readonly {
192
+ readonly first: number;
193
+ readonly count: number;
194
+ readonly baseVertex: number;
195
+ }[];
196
+ /** Candidate data that does not change batch compatibility. */
197
+ readonly payloadRevision: string;
198
+ }
199
+
200
+ interface MembershipDraw {
201
+ readonly sourceDrawIndex: number;
202
+ readonly key: GpuDrivenBatchKey;
203
+ readonly batchText: string;
204
+ readonly candidateKeyPrefix: string;
205
+ readonly payloadRevision: string;
206
+ }
207
+
208
+ interface MembershipProjection {
209
+ readonly instanceCount: number;
210
+ readonly hasLod: boolean;
211
+ readonly draws: readonly MembershipDraw[];
212
+ }
213
+
214
+ function hasActiveAlphaMask(
215
+ material: RenderSceneSlot['snapshot']['material'],
216
+ prepared: PreparedGpuDrivenDraw,
217
+ ): boolean {
218
+ const { cutoff, source } = prepared.alphaMask;
219
+ if (cutoff.length === 0 || source.length === 0) return false;
220
+ // Standard's shared receipt describes the alpha-clip interface; the actual
221
+ // mode is selected by its authored cutoff. Custom producers own coverage in
222
+ // their receipt, so a declared clip remains masked without guessing a field.
223
+ if (
224
+ prepared.identity.material === 'forgeax::default-standard-pbr' ||
225
+ prepared.identity.material === 'forgeax::pbr-skin' ||
226
+ prepared.identity.material === 'forgeax::default-standard-pbr-skin'
227
+ ) {
228
+ const value = material.paramSnapshot?.[cutoff];
229
+ return typeof value === 'number' && value > 0;
230
+ }
231
+ return true;
232
+ }
233
+
234
+ function eligibleDraws(slot: RenderSceneSlot): readonly EligibleGpuDrivenDraw[] {
97
235
  const snapshot = slot.snapshot;
98
236
  const draws = snapshot.gpuDrivenDraws;
99
237
  if (
@@ -101,29 +239,53 @@ function eligibleKeys(slot: RenderSceneSlot): readonly GpuDrivenBatchKey[] {
101
239
  draws.length === 0 ||
102
240
  snapshot.instances?.instanceCount === 0 ||
103
241
  snapshot.localAabb === undefined ||
104
- snapshot.skin !== undefined ||
105
242
  snapshot.morph !== undefined ||
106
243
  snapshot.spriteInstances !== undefined
107
244
  ) {
108
245
  return [];
109
246
  }
110
- return draws.flatMap((draw) => {
247
+ const result: EligibleGpuDrivenDraw[] = [];
248
+ for (let compactIndex = 0; compactIndex < draws.length; compactIndex += 1) {
249
+ const draw = draws[compactIndex];
250
+ if (draw === undefined) continue;
251
+ const drawItemIndex = gpuDrivenSourceDrawItemIndex(draw, compactIndex);
111
252
  const prepared = draw.prepared;
112
253
  const material = snapshot.materials[draw.materialSlot] ?? snapshot.material;
113
254
  if (prepared !== undefined) {
114
- const isStandardPbr =
115
- (material.materialShaderId === 'forgeax::default-standard-pbr' &&
116
- prepared.identity.material === 'forgeax::default-standard-pbr') ||
117
- (material.materialShaderId === 'forgeax::default-standard-pbr-skin' &&
118
- prepared.identity.material === 'forgeax::default-standard-pbr-skin');
255
+ // Prepared producer identity is the admission proof; the material
256
+ // identifier is only a consistency check, never a built-in allow-list.
257
+ const materialIdentityMatches =
258
+ material.materialShaderId === undefined ||
259
+ prepared.identity.material === material.materialShaderId;
119
260
  const isAlphaBlend =
120
261
  material.transparent === true || material.renderState?.blend !== undefined;
121
- if (!isStandardPbr || isAlphaBlend || prepared.identity.deformation !== 'rigid') return [];
122
- const preparedIdentity = `${prepared.identity.material}|${prepared.identity.geometry}|${prepared.identity.deformation}`;
123
- const admission =
124
- typeof material.paramSnapshot?.alphaCutoff === 'number' ? 'alpha-mask' : 'opaque';
125
- return [
126
- {
262
+ const cpuOnlyMaterialResources =
263
+ (material.textureSources?.size ?? 0) > 0 || (material.videoTextureFields?.size ?? 0) > 0;
264
+ const skinReady =
265
+ prepared.identity.deformation !== 'skin' ||
266
+ (snapshot.skin?.storageOrUniform === 'storage' &&
267
+ snapshot.skin.customDataStart >= 0 &&
268
+ Number.isInteger(snapshot.skin.customDataStart) &&
269
+ hasFiniteOrderedBounds(snapshot.skin.bounds) &&
270
+ prepared.skinPaletteAddress !== undefined);
271
+ if (
272
+ !materialIdentityMatches ||
273
+ isAlphaBlend ||
274
+ cpuOnlyMaterialResources ||
275
+ (prepared.identity.deformation !== 'rigid' && prepared.identity.deformation !== 'skin') ||
276
+ !skinReady
277
+ )
278
+ continue;
279
+ const preparedIdentity = [
280
+ prepared.identity.material,
281
+ prepared.identity.geometry,
282
+ prepared.identity.deformation,
283
+ ...(prepared.receiptIdentity === undefined ? [] : [prepared.receiptIdentity]),
284
+ ].join('|');
285
+ const admission = hasActiveAlphaMask(material, prepared) ? 'alpha-mask' : 'opaque';
286
+ result.push({
287
+ sourceDrawIndex: drawItemIndex,
288
+ key: {
127
289
  assetHandle: snapshot.assetHandle,
128
290
  drawKind: draw.kind,
129
291
  first: prepared.first,
@@ -137,10 +299,14 @@ function eligibleKeys(slot: RenderSceneSlot): readonly GpuDrivenBatchKey[] {
137
299
  resourceIdentity: draw.materialResourceClass,
138
300
  admission,
139
301
  },
140
- ];
302
+ prepared,
303
+ ...candidatePayload(draw, snapshot),
304
+ });
305
+ continue;
141
306
  }
142
- return [
143
- {
307
+ result.push({
308
+ sourceDrawIndex: drawItemIndex,
309
+ key: {
144
310
  assetHandle: snapshot.assetHandle,
145
311
  drawKind: draw.kind,
146
312
  first: draw.first,
@@ -151,8 +317,66 @@ function eligibleKeys(slot: RenderSceneSlot): readonly GpuDrivenBatchKey[] {
151
317
  pipelineClass: draw.pipelineClass,
152
318
  materialResourceClass: draw.materialResourceClass,
153
319
  },
154
- ];
320
+ ...candidatePayload(draw, snapshot),
321
+ });
322
+ }
323
+ return result;
324
+ }
325
+
326
+ function candidatePayload(
327
+ draw: NonNullable<RenderSceneSlot['snapshot']['gpuDrivenDraws']>[number],
328
+ snapshot: RenderSceneSlot['snapshot'],
329
+ ): Pick<
330
+ EligibleGpuDrivenDraw,
331
+ 'lodCoverages' | 'lodHysteresis' | 'lodRanges' | 'payloadRevision' | 'projectedHeight'
332
+ > {
333
+ const lodCoverages =
334
+ snapshot.lods === undefined
335
+ ? undefined
336
+ : [1, ...snapshot.lods.map((lod) => lod.screenCoverage)];
337
+ const lodRanges = draw.lodRanges as EligibleGpuDrivenDraw['lodRanges'];
338
+ const lodHysteresis = snapshot.lodHysteresis;
339
+ const payloadRevision = JSON.stringify({
340
+ projectedHeight: draw.projectedHeight,
341
+ lodCoverages,
342
+ lodHysteresis,
343
+ lodRanges,
344
+ prepared: draw.prepared,
155
345
  });
346
+ return {
347
+ ...(draw.projectedHeight === undefined ? {} : { projectedHeight: draw.projectedHeight }),
348
+ ...(lodCoverages === undefined ? {} : { lodCoverages }),
349
+ ...(lodHysteresis === undefined ? {} : { lodHysteresis }),
350
+ ...(lodRanges === undefined ? {} : { lodRanges }),
351
+ payloadRevision,
352
+ };
353
+ }
354
+
355
+ function hasFiniteOrderedBounds(bounds: Float32Array | undefined): boolean {
356
+ if (bounds === undefined || bounds.length < 6) return false;
357
+ const minX = bounds[0];
358
+ const minY = bounds[1];
359
+ const minZ = bounds[2];
360
+ const maxX = bounds[3];
361
+ const maxY = bounds[4];
362
+ const maxZ = bounds[5];
363
+ return (
364
+ minX !== undefined &&
365
+ minY !== undefined &&
366
+ minZ !== undefined &&
367
+ maxX !== undefined &&
368
+ maxY !== undefined &&
369
+ maxZ !== undefined &&
370
+ Number.isFinite(minX) &&
371
+ Number.isFinite(minY) &&
372
+ Number.isFinite(minZ) &&
373
+ Number.isFinite(maxX) &&
374
+ Number.isFinite(maxY) &&
375
+ Number.isFinite(maxZ) &&
376
+ minX <= maxX &&
377
+ minY <= maxY &&
378
+ minZ <= maxZ
379
+ );
156
380
  }
157
381
 
158
382
  function keyText(key: GpuDrivenBatchKey): string {
@@ -160,11 +384,9 @@ function keyText(key: GpuDrivenBatchKey): string {
160
384
  }
161
385
 
162
386
  /**
163
- * A GPU indirect draw has one index/vertex range for the whole batch. LOD
387
+ * A GPU indirect draw has one index/vertex range for the whole batch. LOD
164
388
  * selection is per candidate, so sharing a batch between LOD candidates would
165
- * let `finalizeView` pick the first candidate's range for every visible
166
- * instance. Keep LOD candidates in single-candidate batches; ordinary meshes
167
- * retain the existing compatibility batching path.
389
+ * let the first candidate's range serve every visible instance.
168
390
  */
169
391
  function candidateBatchText(
170
392
  key: GpuDrivenBatchKey,
@@ -178,19 +400,32 @@ function candidateBatchText(
178
400
  : keyText(key);
179
401
  }
180
402
 
181
- function membershipTexts(slot: RenderSceneSlot): readonly string[] {
182
- const keys = eligibleKeys(slot);
403
+ function drawBatchText(
404
+ key: GpuDrivenBatchKey,
405
+ primitiveIndex: number,
406
+ drawItemIndex: number,
407
+ hasLod: boolean,
408
+ ): string {
409
+ return hasLod ? `${keyText(key)}|lod:${primitiveIndex}:${drawItemIndex}` : keyText(key);
410
+ }
411
+
412
+ function membershipProjection(
413
+ slot: RenderSceneSlot,
414
+ draws = eligibleDraws(slot),
415
+ ): MembershipProjection {
183
416
  const instanceCount = slot.snapshot.instances?.instanceCount ?? 1;
184
417
  const hasLod = (slot.snapshot.lods?.length ?? 0) > 0;
185
- const texts: string[] = [];
186
- for (let drawItemIndex = 0; drawItemIndex < keys.length; drawItemIndex += 1) {
187
- const key = keys[drawItemIndex];
188
- if (key === undefined) continue;
189
- for (let instanceOrdinal = 0; instanceOrdinal < instanceCount; instanceOrdinal += 1) {
190
- texts.push(candidateBatchText(key, slot.slot, drawItemIndex, instanceOrdinal, hasLod));
191
- }
192
- }
193
- return texts;
418
+ return {
419
+ instanceCount,
420
+ hasLod,
421
+ draws: draws.map((draw) => ({
422
+ sourceDrawIndex: draw.sourceDrawIndex,
423
+ key: draw.key,
424
+ batchText: drawBatchText(draw.key, slot.slot, draw.sourceDrawIndex, hasLod),
425
+ candidateKeyPrefix: `${slot.slot}:${draw.sourceDrawIndex}:`,
426
+ payloadRevision: draw.payloadRevision,
427
+ })),
428
+ };
194
429
  }
195
430
 
196
431
  function alignInstanceBase(value: number): number {
@@ -209,10 +444,6 @@ export function projectedHeightForCandidate(slot: RenderSceneSlot, camera: Camer
209
444
  const halfY = Math.abs((aabb[4] ?? 0) - (aabb[1] ?? 0)) * 0.5;
210
445
  const halfZ = Math.abs((aabb[5] ?? 0) - (aabb[2] ?? 0)) * 0.5;
211
446
  const world = slot.snapshot.transform.world;
212
- // Transform the local AABB's half extents through the absolute value of the
213
- // world 3x3. This is the conservative world-space sphere bound for every
214
- // rotation and signed/non-uniform scale, and keeps CPU projection aligned
215
- // with the world transform uploaded to the GPU selector.
216
447
  const worldHalfX =
217
448
  Math.abs(world[0] ?? 0) * halfX +
218
449
  Math.abs(world[4] ?? 0) * halfY +
@@ -241,16 +472,19 @@ export function projectedHeightForCandidate(slot: RenderSceneSlot, camera: Camer
241
472
  /** Stable compatibility grouping; per-view visibility never mutates this owner. */
242
473
  export class BatchTopology {
243
474
  private readonly batches = new Map<string, MutableBatch>();
244
- private readonly membershipByPrimitive = new Map<
245
- number,
246
- readonly { readonly batchText: string; readonly candidateKey: string }[]
247
- >();
475
+ private readonly membershipByPrimitive = new Map<number, MembershipProjection>();
248
476
  private readonly ineligiblePrimitives = new Set<number>();
249
477
  private readonly generationByBatchId: number[] = [];
250
478
  private readonly freeBatchIds: number[] = [];
251
479
  private revision = 0;
480
+ private payloadRevision = 0;
252
481
  private rebuilds = 0;
253
482
  private patches = 0;
483
+ private payloadPatches = 0;
484
+ private membershipChecks = 0;
485
+ private membershipAllocations = 0;
486
+ private candidateAdds = 0;
487
+ private candidateRemoves = 0;
254
488
  private cachedPlan: SubmissionPlan | undefined;
255
489
 
256
490
  rebuild(slots: readonly RenderSceneSlot[]): void {
@@ -261,37 +495,125 @@ export class BatchTopology {
261
495
  this.freeBatchIds.length = 0;
262
496
  for (const slot of slots) this.add(slot);
263
497
  this.revision += 1;
498
+ this.payloadRevision += 1;
264
499
  this.rebuilds += 1;
265
500
  this.cachedPlan = undefined;
266
501
  }
267
502
 
268
503
  apply(delta: RenderSceneApplyResult): boolean {
269
504
  let changed = false;
270
- for (const removed of delta.removedSlots) changed = this.remove(removed.slot) || changed;
505
+ let topologyChanged = false;
506
+ for (const removed of delta.removedSlots) {
507
+ const removedChanged = this.remove(removed.slot);
508
+ changed = removedChanged || changed;
509
+ topologyChanged = removedChanged || topologyChanged;
510
+ }
271
511
  for (const slot of delta.recreatedSlots) {
272
- changed = this.remove(slot.slot) || changed;
273
- changed = this.add(slot) || changed;
512
+ const removedChanged = this.remove(slot.slot);
513
+ const addedChanged = this.add(slot);
514
+ changed = removedChanged || addedChanged || changed;
515
+ topologyChanged = removedChanged || addedChanged || topologyChanged;
274
516
  }
275
- // Most updated slots are transform-only. A full renderable update can
276
- // still carry a changed material/geometry/draw topology, so compare the
277
- // stable batch memberships and patch only when that key actually changed.
278
- // This keeps moving entities on the zero-work transform lane while making
279
- // same-entity resource edits visible to the GPU-driven owner.
280
- for (const slot of delta.updatedSlots) {
281
- const previous = this.membershipByPrimitive.get(slot.slot) ?? [];
282
- const next = membershipTexts(slot);
283
- if (
284
- previous.length === next.length &&
285
- previous.every((membership, index) => membership.batchText === next[index])
286
- ) {
517
+ // Membership depends on source descriptors and instance cardinality.
518
+ // Root matrices feed visibility without changing this dependency.
519
+ const contentUpdatedSlots = delta.contentUpdatedSlots;
520
+ const instanceUpdatedSlots = delta.instanceUpdatedSlots;
521
+ const membershipUpdates = new Map<number, { slot: RenderSceneSlot; content: boolean }>();
522
+ for (const slot of contentUpdatedSlots) {
523
+ membershipUpdates.set(slot.slot, { slot, content: true });
524
+ }
525
+ // Instance cardinality is a membership input, including in mixed updates.
526
+ for (const slot of instanceUpdatedSlots) {
527
+ if (!membershipUpdates.has(slot.slot)) {
528
+ membershipUpdates.set(slot.slot, { slot, content: false });
529
+ }
530
+ }
531
+ for (const update of membershipUpdates.values()) {
532
+ const { slot, content } = update;
533
+ const eligible = eligibleDraws(slot);
534
+ const next = membershipProjection(slot, eligible);
535
+ // The projection is one descriptor per eligible source draw; candidate
536
+ // identities are derived from the stable ordinal and are not stored as
537
+ // N per-instance comparison records.
538
+ this.membershipAllocations += next.draws.length;
539
+ const previous = this.membershipByPrimitive.get(slot.slot);
540
+ this.membershipChecks += 1;
541
+ const topologyStable =
542
+ previous !== undefined &&
543
+ previous.instanceCount === next.instanceCount &&
544
+ previous.hasLod === next.hasLod &&
545
+ previous.draws.length === next.draws.length &&
546
+ previous.draws.every((membership, index) => {
547
+ const candidate = next.draws[index];
548
+ return (
549
+ candidate !== undefined &&
550
+ membership.sourceDrawIndex === candidate.sourceDrawIndex &&
551
+ membership.batchText === candidate.batchText
552
+ );
553
+ });
554
+ if (!topologyStable) {
555
+ const removedChanged = this.remove(slot.slot);
556
+ const addedChanged = this.add(slot);
557
+ changed = removedChanged || addedChanged || changed;
558
+ topologyChanged = removedChanged || addedChanged || topologyChanged;
559
+ continue;
560
+ }
561
+ if (!content) {
562
+ this.membershipByPrimitive.set(slot.slot, next);
287
563
  continue;
288
564
  }
289
- changed = this.remove(slot.slot) || changed;
290
- changed = this.add(slot) || changed;
565
+ let payloadChanged = false;
566
+ let topologyFallback = false;
567
+ for (let index = 0; index < next.draws.length; index += 1) {
568
+ const oldMembership = previous.draws[index];
569
+ const newMembership = next.draws[index];
570
+ const draw = eligible[index];
571
+ if (oldMembership === undefined || newMembership === undefined || draw === undefined) {
572
+ continue;
573
+ }
574
+ if (oldMembership.payloadRevision === newMembership.payloadRevision) continue;
575
+ for (let instanceOrdinal = 0; instanceOrdinal < next.instanceCount; instanceOrdinal += 1) {
576
+ const batchText = candidateBatchText(
577
+ draw.key,
578
+ slot.slot,
579
+ draw.sourceDrawIndex,
580
+ instanceOrdinal,
581
+ next.hasLod,
582
+ );
583
+ const batch = this.batches.get(batchText);
584
+ const candidateKey = `${newMembership.candidateKeyPrefix}${instanceOrdinal}`;
585
+ if (batch === undefined || !batch.candidates.has(candidateKey)) {
586
+ const removedChanged = this.remove(slot.slot);
587
+ const addedChanged = this.add(slot);
588
+ changed = removedChanged || addedChanged || changed;
589
+ topologyChanged = removedChanged || addedChanged || topologyChanged;
590
+ topologyFallback = true;
591
+ break;
592
+ }
593
+ batch.candidates.set(
594
+ candidateKey,
595
+ this.candidateFromEligible(slot, instanceOrdinal, draw),
596
+ );
597
+ }
598
+ if (topologyFallback) break;
599
+ payloadChanged = true;
600
+ }
601
+ this.membershipByPrimitive.set(slot.slot, next);
602
+ if (payloadChanged) {
603
+ changed = true;
604
+ this.payloadRevision += 1;
605
+ this.payloadPatches += 1;
606
+ this.cachedPlan = undefined;
607
+ }
608
+ }
609
+ for (const slot of delta.createdSlots) {
610
+ const addedChanged = this.add(slot);
611
+ changed = addedChanged || changed;
612
+ topologyChanged = addedChanged || topologyChanged;
291
613
  }
292
- for (const slot of delta.createdSlots) changed = this.add(slot) || changed;
293
- if (changed) {
614
+ if (topologyChanged) {
294
615
  this.revision += 1;
616
+ this.payloadRevision += 1;
295
617
  this.patches += 1;
296
618
  this.cachedPlan = undefined;
297
619
  }
@@ -324,6 +646,7 @@ export class BatchTopology {
324
646
  });
325
647
  this.cachedPlan = Object.freeze({
326
648
  revision: this.revision,
649
+ payloadRevision: this.payloadRevision,
327
650
  batches: Object.freeze(batches),
328
651
  candidateCount: batches.reduce((total, batch) => total + batch.candidates.length, 0),
329
652
  visibleCapacity: visibleBase,
@@ -341,24 +664,34 @@ export class BatchTopology {
341
664
  rebuilds: this.rebuilds,
342
665
  patches: this.patches,
343
666
  ineligible: this.ineligiblePrimitives.size,
667
+ payloadPatches: this.payloadPatches,
668
+ membershipChecks: this.membershipChecks,
669
+ membershipAllocations: this.membershipAllocations,
670
+ candidateAdds: this.candidateAdds,
671
+ candidateRemoves: this.candidateRemoves,
344
672
  };
345
673
  }
346
674
 
347
675
  private add(slot: RenderSceneSlot): boolean {
348
- const keys = eligibleKeys(slot);
349
- if (keys.length === 0) {
676
+ const draws = eligibleDraws(slot);
677
+ if (draws.length === 0) {
350
678
  this.ineligiblePrimitives.add(slot.slot);
351
679
  return false;
352
680
  }
353
681
  this.ineligiblePrimitives.delete(slot.slot);
354
- const memberships: Array<{ batchText: string; candidateKey: string }> = [];
355
- const instanceCount = slot.snapshot.instances?.instanceCount ?? 1;
356
- const hasLod = (slot.snapshot.lods?.length ?? 0) > 0;
357
- for (let drawItemIndex = 0; drawItemIndex < keys.length; drawItemIndex += 1) {
358
- const key = keys[drawItemIndex];
359
- if (key === undefined) continue;
682
+ const memberships = membershipProjection(slot, draws);
683
+ const instanceCount = memberships.instanceCount;
684
+ const hasLod = memberships.hasLod;
685
+ this.membershipAllocations += memberships.draws.length;
686
+ for (const draw of draws) {
360
687
  for (let instanceOrdinal = 0; instanceOrdinal < instanceCount; instanceOrdinal += 1) {
361
- const text = candidateBatchText(key, slot.slot, drawItemIndex, instanceOrdinal, hasLod);
688
+ const text = candidateBatchText(
689
+ draw.key,
690
+ slot.slot,
691
+ draw.sourceDrawIndex,
692
+ instanceOrdinal,
693
+ hasLod,
694
+ );
362
695
  let batch = this.batches.get(text);
363
696
  if (batch === undefined) {
364
697
  const reused = this.freeBatchIds.pop();
@@ -366,39 +699,12 @@ export class BatchTopology {
366
699
  const generation =
367
700
  reused === undefined ? 0 : (this.generationByBatchId[batchId] ?? -1) + 1;
368
701
  this.generationByBatchId[batchId] = generation;
369
- batch = { batchId, generation, key, candidates: new Map() };
702
+ batch = { batchId, generation, key: draw.key, candidates: new Map() };
370
703
  this.batches.set(text, batch);
371
704
  }
372
- const candidateKey = `${slot.slot}:${drawItemIndex}:${instanceOrdinal}`;
373
- const draw = slot.snapshot.gpuDrivenDraws?.[drawItemIndex];
374
- const prepared = draw?.prepared;
375
- batch.candidates.set(candidateKey, {
376
- primitiveIndex: slot.slot,
377
- generation: slot.generation,
378
- drawItemIndex,
379
- instanceOrdinal,
380
- ...(draw?.projectedHeight === undefined ? {} : { projectedHeight: draw.projectedHeight }),
381
- ...(slot.snapshot.lods === undefined
382
- ? {}
383
- : {
384
- lodCoverages: [1, ...slot.snapshot.lods.map((lod) => lod.screenCoverage)],
385
- ...(slot.snapshot.gpuDrivenDraws?.[drawItemIndex]?.lodRanges === undefined
386
- ? {}
387
- : {
388
- lodRanges: slot.snapshot.gpuDrivenDraws[drawItemIndex]
389
- ?.lodRanges as readonly {
390
- readonly first: number;
391
- readonly count: number;
392
- readonly baseVertex: number;
393
- }[],
394
- }),
395
- ...(slot.snapshot.lodHysteresis === undefined
396
- ? {}
397
- : { lodHysteresis: slot.snapshot.lodHysteresis }),
398
- }),
399
- ...(prepared === undefined ? {} : { prepared }),
400
- });
401
- memberships.push({ batchText: text, candidateKey });
705
+ const candidateKey = `${slot.slot}:${draw.sourceDrawIndex}:${instanceOrdinal}`;
706
+ batch.candidates.set(candidateKey, this.candidateFromEligible(slot, instanceOrdinal, draw));
707
+ this.candidateAdds += 1;
402
708
  }
403
709
  }
404
710
  this.membershipByPrimitive.set(slot.slot, memberships);
@@ -410,15 +716,53 @@ export class BatchTopology {
410
716
  const memberships = this.membershipByPrimitive.get(primitiveIndex);
411
717
  this.membershipByPrimitive.delete(primitiveIndex);
412
718
  if (memberships === undefined) return false;
413
- for (const membership of memberships) {
414
- const batch = this.batches.get(membership.batchText);
415
- if (batch === undefined) continue;
416
- batch.candidates.delete(membership.candidateKey);
417
- if (batch.candidates.size === 0) {
418
- this.batches.delete(membership.batchText);
419
- this.freeBatchIds.push(batch.batchId);
719
+ for (const membership of memberships.draws) {
720
+ const batchTexts = new Set<string>();
721
+ for (
722
+ let instanceOrdinal = 0;
723
+ instanceOrdinal < memberships.instanceCount;
724
+ instanceOrdinal += 1
725
+ ) {
726
+ const batchText = candidateBatchText(
727
+ membership.key,
728
+ primitiveIndex,
729
+ membership.sourceDrawIndex,
730
+ instanceOrdinal,
731
+ memberships.hasLod,
732
+ );
733
+ batchTexts.add(batchText);
734
+ const batch = this.batches.get(batchText);
735
+ if (batch === undefined) continue;
736
+ const candidateKey = `${membership.candidateKeyPrefix}${instanceOrdinal}`;
737
+ if (!batch.candidates.delete(candidateKey)) continue;
738
+ this.candidateRemoves += 1;
739
+ }
740
+ for (const batchText of batchTexts) {
741
+ const batch = this.batches.get(batchText);
742
+ if (batch !== undefined && batch.candidates.size === 0) {
743
+ this.batches.delete(batchText);
744
+ this.freeBatchIds.push(batch.batchId);
745
+ }
420
746
  }
421
747
  }
422
748
  return true;
423
749
  }
750
+
751
+ private candidateFromEligible(
752
+ slot: RenderSceneSlot,
753
+ instanceOrdinal: number,
754
+ draw: EligibleGpuDrivenDraw,
755
+ ): GpuDrivenCandidate {
756
+ return {
757
+ primitiveIndex: slot.slot,
758
+ generation: slot.generation,
759
+ drawItemIndex: draw.sourceDrawIndex,
760
+ instanceOrdinal,
761
+ ...(draw.projectedHeight === undefined ? {} : { projectedHeight: draw.projectedHeight }),
762
+ ...(draw.lodCoverages === undefined ? {} : { lodCoverages: draw.lodCoverages }),
763
+ ...(draw.lodRanges === undefined ? {} : { lodRanges: draw.lodRanges }),
764
+ ...(draw.lodHysteresis === undefined ? {} : { lodHysteresis: draw.lodHysteresis }),
765
+ ...(draw.prepared === undefined ? {} : { prepared: draw.prepared }),
766
+ };
767
+ }
424
768
  }