@forgeax/engine-render 0.1.33 → 0.1.35

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 (624) hide show
  1. package/README.md +1062 -127
  2. package/dist/assembly/backend-contract.d.ts +2 -0
  3. package/dist/assembly/backend-contract.d.ts.map +1 -1
  4. package/dist/assembly/barrel-distortion-inspection.d.ts +3 -0
  5. package/dist/assembly/barrel-distortion-inspection.d.ts.map +1 -0
  6. package/dist/assembly/canvas-draw-guard.d.ts +3 -0
  7. package/dist/assembly/canvas-draw-guard.d.ts.map +1 -0
  8. package/dist/assembly/cloud-shadow-entry.d.ts +4 -0
  9. package/dist/assembly/cloud-shadow-entry.d.ts.map +1 -0
  10. package/dist/assembly/device-feature-admission.d.ts +2 -2
  11. package/dist/assembly/dynamic-geometry-host.d.ts +4 -1
  12. package/dist/assembly/dynamic-geometry-host.d.ts.map +1 -1
  13. package/dist/assembly/dynamic-geometry-runtime.d.ts +1 -1
  14. package/dist/assembly/dynamic-geometry-runtime.d.ts.map +1 -1
  15. package/dist/assembly/factory.d.ts +1 -1
  16. package/dist/assembly/factory.d.ts.map +1 -1
  17. package/dist/assembly/host-contract.d.ts +6 -5
  18. package/dist/assembly/host-contract.d.ts.map +1 -1
  19. package/dist/assembly/material/assembly.d.ts.map +1 -1
  20. package/dist/assembly/material/pipeline-helpers.d.ts +5 -0
  21. package/dist/assembly/material/pipeline-helpers.d.ts.map +1 -1
  22. package/dist/assembly/material-shader-policy.d.ts +16 -2
  23. package/dist/assembly/material-shader-policy.d.ts.map +1 -1
  24. package/dist/assembly/material-shader-prewarm.d.ts.map +1 -1
  25. package/dist/assembly/recovery/device-loss-fanout.d.ts.map +1 -1
  26. package/dist/assembly/recovery/renderer-recover.d.ts +2 -0
  27. package/dist/assembly/recovery/renderer-recover.d.ts.map +1 -1
  28. package/dist/assembly/render-feature-post-processes.d.ts +6 -0
  29. package/dist/assembly/render-feature-post-processes.d.ts.map +1 -0
  30. package/dist/assembly/render-target-host.d.ts +5 -0
  31. package/dist/assembly/render-target-host.d.ts.map +1 -1
  32. package/dist/assembly/renderer-facade.d.ts.map +1 -1
  33. package/dist/assembly/renderer-feature-inspection.d.ts +1 -1
  34. package/dist/assembly/renderer-feature-inspection.d.ts.map +1 -1
  35. package/dist/assembly/renderer-frame-transaction.d.ts +12 -0
  36. package/dist/assembly/renderer-frame-transaction.d.ts.map +1 -1
  37. package/dist/assembly/renderer-inspection.d.ts +11 -0
  38. package/dist/assembly/renderer-inspection.d.ts.map +1 -1
  39. package/dist/assembly/webgpu-pbr-ready.d.ts +1 -0
  40. package/dist/assembly/webgpu-pbr-ready.d.ts.map +1 -1
  41. package/dist/assembly/webgpu-ready-per-pass.d.ts +39 -0
  42. package/dist/assembly/webgpu-ready-per-pass.d.ts.map +1 -0
  43. package/dist/assembly/webgpu-ready.d.ts +1 -1
  44. package/dist/assembly/webgpu-ready.d.ts.map +1 -1
  45. package/dist/assembly/webgpu-renderer-bootstrap.d.ts.map +1 -1
  46. package/dist/assembly/webgpu-renderer-observation-owner.d.ts +35 -0
  47. package/dist/assembly/webgpu-renderer-observation-owner.d.ts.map +1 -0
  48. package/dist/assembly/webgpu-renderer.d.ts +2 -1
  49. package/dist/assembly/webgpu-renderer.d.ts.map +1 -1
  50. package/dist/authoring.mjs +2 -4
  51. package/dist/authoring.mjs.map +1 -1
  52. package/dist/barrel-distortion.d.ts +47 -0
  53. package/dist/barrel-distortion.d.ts.map +1 -0
  54. package/dist/chunk-3XUBWRY2.mjs +1842 -0
  55. package/dist/chunk-3XUBWRY2.mjs.map +1 -0
  56. package/dist/{chunk-OO3DRYK7.mjs → chunk-G6HDNGY7.mjs} +2400 -1767
  57. package/dist/chunk-G6HDNGY7.mjs.map +1 -0
  58. package/dist/{chunk-ZDQWGQW7.mjs → chunk-LM5IE7GF.mjs} +4 -4
  59. package/dist/{chunk-ZDQWGQW7.mjs.map → chunk-LM5IE7GF.mjs.map} +1 -1
  60. package/dist/{chunk-VOZWDM3L.mjs → chunk-LNIUIKQ7.mjs} +1514 -498
  61. package/dist/chunk-LNIUIKQ7.mjs.map +1 -0
  62. package/dist/chunk-MXTWKZO4.mjs +3268 -0
  63. package/dist/chunk-MXTWKZO4.mjs.map +1 -0
  64. package/dist/chunk-MZ4C7EHF.mjs +6942 -0
  65. package/dist/chunk-MZ4C7EHF.mjs.map +1 -0
  66. package/dist/chunk-RIPAEGI6.mjs +48 -0
  67. package/dist/chunk-RIPAEGI6.mjs.map +1 -0
  68. package/dist/{chunk-LEAXOMYJ.mjs → chunk-SGPUJW3F.mjs} +117 -5
  69. package/dist/chunk-SGPUJW3F.mjs.map +1 -0
  70. package/dist/{chunk-PA5DRJNI.mjs → chunk-X2KA6WHM.mjs} +29 -4
  71. package/dist/chunk-X2KA6WHM.mjs.map +1 -0
  72. package/dist/{chunk-BLXGONR2.mjs → chunk-XSFB7XXQ.mjs} +51 -4
  73. package/dist/chunk-XSFB7XXQ.mjs.map +1 -0
  74. package/dist/cloud/density.d.ts +55 -0
  75. package/dist/cloud/density.d.ts.map +1 -0
  76. package/dist/cloud/extract.d.ts +25 -0
  77. package/dist/cloud/extract.d.ts.map +1 -0
  78. package/dist/cloud/feature.d.ts +57 -0
  79. package/dist/cloud/feature.d.ts.map +1 -0
  80. package/dist/cloud/frame-context.d.ts +8 -0
  81. package/dist/cloud/frame-context.d.ts.map +1 -0
  82. package/dist/cloud/inspection.d.ts +59 -0
  83. package/dist/cloud/inspection.d.ts.map +1 -0
  84. package/dist/cloud/optics.d.ts +56 -0
  85. package/dist/cloud/optics.d.ts.map +1 -0
  86. package/dist/cloud/parameters.d.ts +73 -0
  87. package/dist/cloud/parameters.d.ts.map +1 -0
  88. package/dist/cloud/resources.d.ts +60 -0
  89. package/dist/cloud/resources.d.ts.map +1 -0
  90. package/dist/cloud/shadow.d.ts +42 -0
  91. package/dist/cloud/shadow.d.ts.map +1 -0
  92. package/dist/cloud/temporal.d.ts +74 -0
  93. package/dist/cloud/temporal.d.ts.map +1 -0
  94. package/dist/components/barrel-distortion.d.ts +13 -0
  95. package/dist/components/barrel-distortion.d.ts.map +1 -0
  96. package/dist/components/cloud-layer.d.ts +29 -0
  97. package/dist/components/cloud-layer.d.ts.map +1 -0
  98. package/dist/components/index.d.ts +2 -0
  99. package/dist/components/index.d.ts.map +1 -1
  100. package/dist/components/instances.d.ts +20 -6
  101. package/dist/components/instances.d.ts.map +1 -1
  102. package/dist/construct-renderer.d.ts +1 -1
  103. package/dist/construct-renderer.d.ts.map +1 -1
  104. package/dist/construct-renderer.mjs +8406 -5785
  105. package/dist/construct-renderer.mjs.map +1 -1
  106. package/dist/device/gpu-residency.d.ts +19 -19
  107. package/dist/device/gpu-residency.d.ts.map +1 -1
  108. package/dist/dynamic-geometry.d.ts +5 -1
  109. package/dist/dynamic-geometry.d.ts.map +1 -1
  110. package/dist/errors/cloud.d.ts +59 -0
  111. package/dist/errors/cloud.d.ts.map +1 -0
  112. package/dist/errors/render.d.ts +20 -5
  113. package/dist/errors/render.d.ts.map +1 -1
  114. package/dist/examples/single-layer-medium-surface.d.ts +47 -0
  115. package/dist/examples/single-layer-medium-surface.d.ts.map +1 -0
  116. package/dist/extract/camera.d.ts.map +1 -1
  117. package/dist/extract/contracts.d.ts +5 -1
  118. package/dist/extract/contracts.d.ts.map +1 -1
  119. package/dist/extract/material-context.d.ts +7 -0
  120. package/dist/extract/material-context.d.ts.map +1 -0
  121. package/dist/features/barrel-distortion.d.ts +29 -0
  122. package/dist/features/barrel-distortion.d.ts.map +1 -0
  123. package/dist/features/error-reporting.d.ts +6 -2
  124. package/dist/features/error-reporting.d.ts.map +1 -1
  125. package/dist/features/host.d.ts +15 -0
  126. package/dist/features/host.d.ts.map +1 -1
  127. package/dist/features/plan.d.ts +10 -0
  128. package/dist/features/plan.d.ts.map +1 -1
  129. package/dist/features/render-graph-contribution.d.ts +5 -0
  130. package/dist/features/render-graph-contribution.d.ts.map +1 -1
  131. package/dist/features/render-graph-raster.d.ts +1 -0
  132. package/dist/features/render-graph-raster.d.ts.map +1 -1
  133. package/dist/features/targets.d.ts +2 -0
  134. package/dist/features/targets.d.ts.map +1 -1
  135. package/dist/features/types.d.ts +48 -0
  136. package/dist/features/types.d.ts.map +1 -1
  137. package/dist/fullscreen-post-process-pass.d.ts +15 -7
  138. package/dist/fullscreen-post-process-pass.d.ts.map +1 -1
  139. package/dist/glyph-text-layout-system.d.ts +1 -1
  140. package/dist/glyph-text-layout-system.d.ts.map +1 -1
  141. package/dist/gpu-dirty-ranges.d.ts +11 -0
  142. package/dist/gpu-dirty-ranges.d.ts.map +1 -0
  143. package/dist/gpu-driven/batch-topology.d.ts +17 -0
  144. package/dist/gpu-driven/batch-topology.d.ts.map +1 -1
  145. package/dist/gpu-driven/material-artifacts.d.ts +6 -0
  146. package/dist/gpu-driven/material-artifacts.d.ts.map +1 -1
  147. package/dist/gpu-driven/prepared-draw.d.ts.map +1 -1
  148. package/dist/gpu-driven/production-raster-material.d.ts +178 -0
  149. package/dist/gpu-driven/production-raster-material.d.ts.map +1 -0
  150. package/dist/gpu-driven/production-raster.d.ts +47 -3
  151. package/dist/gpu-driven/production-raster.d.ts.map +1 -1
  152. package/dist/gpu-driven/resource-allocation.d.ts +31 -0
  153. package/dist/gpu-driven/resource-allocation.d.ts.map +1 -0
  154. package/dist/gpu-driven/shadow-ownership.d.ts +14 -0
  155. package/dist/gpu-driven/shadow-ownership.d.ts.map +1 -0
  156. package/dist/gpu-driven/view-gpu.d.ts +26 -2
  157. package/dist/gpu-driven/view-gpu.d.ts.map +1 -1
  158. package/dist/gpu-scene.d.ts +5 -0
  159. package/dist/gpu-scene.d.ts.map +1 -1
  160. package/dist/hdrp-buffers.d.ts +2 -2
  161. package/dist/hdrp-buffers.d.ts.map +1 -1
  162. package/dist/ibl/frame-resources.d.ts.map +1 -1
  163. package/dist/ibl/skylight-bind-group.d.ts +14 -5
  164. package/dist/ibl/skylight-bind-group.d.ts.map +1 -1
  165. package/dist/index.d.ts +30 -7
  166. package/dist/index.d.ts.map +1 -1
  167. package/dist/index.mjs +780 -9
  168. package/dist/index.mjs.map +1 -1
  169. package/dist/inspection-types.d.ts +135 -1
  170. package/dist/inspection-types.d.ts.map +1 -1
  171. package/dist/instance-buffer-cache.d.ts +4 -4
  172. package/dist/instance-buffer-cache.d.ts.map +1 -1
  173. package/dist/instances.d.ts +47 -100
  174. package/dist/instances.d.ts.map +1 -1
  175. package/dist/internal.mjs +7 -8
  176. package/dist/internal.mjs.map +1 -1
  177. package/dist/pbr-pipeline.d.ts +22 -4
  178. package/dist/pbr-pipeline.d.ts.map +1 -1
  179. package/dist/pipeline/single-layer-medium-passes.d.ts +73 -0
  180. package/dist/pipeline/single-layer-medium-passes.d.ts.map +1 -0
  181. package/dist/pipeline/standard-forward-lane.d.ts.map +1 -1
  182. package/dist/pipeline/standard-output/graph.d.ts.map +1 -1
  183. package/dist/pipeline/standard-output/lut-gpu.d.ts +2 -2
  184. package/dist/pipeline/standard-output/lut-gpu.d.ts.map +1 -1
  185. package/dist/pipeline/standard-output/resources.d.ts +2 -2
  186. package/dist/pipeline/standard-output/resources.d.ts.map +1 -1
  187. package/dist/pipeline/standard-output/types.d.ts +4 -2
  188. package/dist/pipeline/standard-output/types.d.ts.map +1 -1
  189. package/dist/pipeline/standard-pipeline.d.ts.map +1 -1
  190. package/dist/pipeline/standard-post.d.ts.map +1 -1
  191. package/dist/pipeline-builder.d.ts +1 -1
  192. package/dist/pipeline-builder.d.ts.map +1 -1
  193. package/dist/plugin.d.ts.map +1 -1
  194. package/dist/prepare/prepared-graphics-resolver.d.ts +2 -0
  195. package/dist/prepare/prepared-graphics-resolver.d.ts.map +1 -1
  196. package/dist/publication/contract.d.ts +77 -0
  197. package/dist/publication/contract.d.ts.map +1 -0
  198. package/dist/publication/dependencies.d.ts +7 -0
  199. package/dist/publication/dependencies.d.ts.map +1 -0
  200. package/dist/publication/prepare-geometry.d.ts +9 -0
  201. package/dist/publication/prepare-geometry.d.ts.map +1 -0
  202. package/dist/publication/programs.d.ts +5 -0
  203. package/dist/publication/programs.d.ts.map +1 -0
  204. package/dist/publication/publisher.d.ts +33 -0
  205. package/dist/publication/publisher.d.ts.map +1 -0
  206. package/dist/publication/receiver.d.ts +29 -0
  207. package/dist/publication/receiver.d.ts.map +1 -0
  208. package/dist/publication/resource-scope.d.ts +18 -0
  209. package/dist/publication/resource-scope.d.ts.map +1 -0
  210. package/dist/publication/targets.d.ts +33 -0
  211. package/dist/publication/targets.d.ts.map +1 -0
  212. package/dist/publication/video.d.ts +5 -0
  213. package/dist/publication/video.d.ts.map +1 -0
  214. package/dist/record/barrel-distortion-frame.d.ts +15 -0
  215. package/dist/record/barrel-distortion-frame.d.ts.map +1 -0
  216. package/dist/record/dynamic-geometry-consumption.d.ts +10 -2
  217. package/dist/record/dynamic-geometry-consumption.d.ts.map +1 -1
  218. package/dist/record/fold-buckets.d.ts +95 -0
  219. package/dist/record/fold-buckets.d.ts.map +1 -0
  220. package/dist/record/fold-instance-buffer.d.ts +6 -0
  221. package/dist/record/fold-instance-buffer.d.ts.map +1 -0
  222. package/dist/record/frame-lighting.d.ts +1 -0
  223. package/dist/record/frame-lighting.d.ts.map +1 -1
  224. package/dist/record/frame-snapshot.d.ts +43 -9
  225. package/dist/record/frame-snapshot.d.ts.map +1 -1
  226. package/dist/record/frame.d.ts +15 -65
  227. package/dist/record/frame.d.ts.map +1 -1
  228. package/dist/record/gpu-draw-receipts.d.ts +11 -0
  229. package/dist/record/gpu-draw-receipts.d.ts.map +1 -0
  230. package/dist/record/gpu-timing.d.ts +8 -0
  231. package/dist/record/gpu-timing.d.ts.map +1 -1
  232. package/dist/record/helpers.d.ts +2 -2
  233. package/dist/record/helpers.d.ts.map +1 -1
  234. package/dist/record/main-pass-geometry.d.ts +22 -6
  235. package/dist/record/main-pass-geometry.d.ts.map +1 -1
  236. package/dist/record/main-pass-material.d.ts +14 -10
  237. package/dist/record/main-pass-material.d.ts.map +1 -1
  238. package/dist/record/main-pass-sprite-draws.d.ts +3 -16
  239. package/dist/record/main-pass-sprite-draws.d.ts.map +1 -1
  240. package/dist/record/main-pass.d.ts +13 -2
  241. package/dist/record/main-pass.d.ts.map +1 -1
  242. package/dist/record/motion-blur-receipt.d.ts +11 -0
  243. package/dist/record/motion-blur-receipt.d.ts.map +1 -0
  244. package/dist/record/prepared-material-bindings.d.ts +3 -3
  245. package/dist/record/prepared-material-bindings.d.ts.map +1 -1
  246. package/dist/record/probe-blend-buffer.d.ts +16 -0
  247. package/dist/record/probe-blend-buffer.d.ts.map +1 -0
  248. package/dist/record/recovery-pipeline.d.ts.map +1 -1
  249. package/dist/record/render-context.d.ts +24 -5
  250. package/dist/record/render-context.d.ts.map +1 -1
  251. package/dist/record/shadow-pass.d.ts +2 -0
  252. package/dist/record/shadow-pass.d.ts.map +1 -1
  253. package/dist/record/skybox-post-pass.d.ts +1 -1
  254. package/dist/record/skybox-post-pass.d.ts.map +1 -1
  255. package/dist/record/sprite-instance-buffer.d.ts +31 -0
  256. package/dist/record/sprite-instance-buffer.d.ts.map +1 -0
  257. package/dist/record/target-capture-graph.d.ts +19 -0
  258. package/dist/record/target-capture-graph.d.ts.map +1 -0
  259. package/dist/record/typed-frame-graph.d.ts +24 -15
  260. package/dist/record/typed-frame-graph.d.ts.map +1 -1
  261. package/dist/record/view-ubo.d.ts +11 -3
  262. package/dist/record/view-ubo.d.ts.map +1 -1
  263. package/dist/record/volume-params.d.ts +9 -0
  264. package/dist/record/volume-params.d.ts.map +1 -0
  265. package/dist/recovery/render-system-candidate.d.ts +14 -4
  266. package/dist/recovery/render-system-candidate.d.ts.map +1 -1
  267. package/dist/reflection/record-owner.d.ts.map +1 -1
  268. package/dist/render-contract.d.ts +46 -5
  269. package/dist/render-contract.d.ts.map +1 -1
  270. package/dist/render-graph-primitives.d.ts.map +1 -1
  271. package/dist/render-pipeline.d.ts +103 -2
  272. package/dist/render-pipeline.d.ts.map +1 -1
  273. package/dist/render-system-extract-tail.d.ts +3 -2
  274. package/dist/render-system-extract-tail.d.ts.map +1 -1
  275. package/dist/render-system-extract.d.ts +18 -9
  276. package/dist/render-system-extract.d.ts.map +1 -1
  277. package/dist/render-system-presentation.d.ts +23 -0
  278. package/dist/render-system-presentation.d.ts.map +1 -0
  279. package/dist/render-system-producer-roots.d.ts +10 -0
  280. package/dist/render-system-producer-roots.d.ts.map +1 -0
  281. package/dist/render-system-projections.d.ts +3 -2
  282. package/dist/render-system-projections.d.ts.map +1 -1
  283. package/dist/render-system-residency.d.ts +12 -0
  284. package/dist/render-system-residency.d.ts.map +1 -0
  285. package/dist/render-system.d.ts +22 -21
  286. package/dist/render-system.d.ts.map +1 -1
  287. package/dist/scene/probe-blend.d.ts +27 -0
  288. package/dist/scene/probe-blend.d.ts.map +1 -1
  289. package/dist/scene/render-scene.d.ts +18 -7
  290. package/dist/scene/render-scene.d.ts.map +1 -1
  291. package/dist/scene/render-source.d.ts +42 -0
  292. package/dist/scene/render-source.d.ts.map +1 -0
  293. package/dist/scene/source-systems.d.ts +6 -0
  294. package/dist/scene/source-systems.d.ts.map +1 -0
  295. package/dist/ssao-buffers.d.ts +9 -0
  296. package/dist/ssao-buffers.d.ts.map +1 -1
  297. package/dist/surface/dynamic-input.d.ts +133 -0
  298. package/dist/surface/dynamic-input.d.ts.map +1 -0
  299. package/dist/surface/gpu-driven.d.ts +41 -0
  300. package/dist/surface/gpu-driven.d.ts.map +1 -0
  301. package/dist/surface/submission-observation.d.ts +136 -0
  302. package/dist/surface/submission-observation.d.ts.map +1 -0
  303. package/dist/systems/skin-palette-allocator.d.ts.map +1 -1
  304. package/dist/systems/skin-palette-types.d.ts +10 -0
  305. package/dist/systems/skin-palette-types.d.ts.map +1 -1
  306. package/dist/systems/transparent-dispatch.d.ts +2 -2
  307. package/dist/systems/transparent-dispatch.d.ts.map +1 -1
  308. package/dist/systems/transparent-sort-config.d.ts +2 -1
  309. package/dist/systems/transparent-sort-config.d.ts.map +1 -1
  310. package/dist/temporal/gpu.d.ts +13 -1
  311. package/dist/temporal/gpu.d.ts.map +1 -1
  312. package/dist/temporal/index.mjs +6 -7
  313. package/dist/temporal/inspection.d.ts.map +1 -1
  314. package/dist/temporal/standard-scene-data.d.ts.map +1 -1
  315. package/dist/temporal/target-coverage-attachment.d.ts.map +1 -1
  316. package/dist/transmission/single-layer-medium.d.ts +89 -0
  317. package/dist/transmission/single-layer-medium.d.ts.map +1 -0
  318. package/dist/typed-render-graph-primitives.d.ts +14 -2
  319. package/dist/typed-render-graph-primitives.d.ts.map +1 -1
  320. package/dist/volume/component.d.ts +9 -4
  321. package/dist/volume/component.d.ts.map +1 -1
  322. package/dist/volume/extract.d.ts +1 -1
  323. package/dist/volume/extract.d.ts.map +1 -1
  324. package/dist/volume/inspection.d.ts +2 -0
  325. package/dist/volume/inspection.d.ts.map +1 -1
  326. package/dist/volume/passes.d.ts +4 -1
  327. package/dist/volume/passes.d.ts.map +1 -1
  328. package/dist/volume/resources.d.ts.map +1 -1
  329. package/package.json +22 -21
  330. package/src/__tests__/atmosphere-daylight.dawn.test.ts +72 -0
  331. package/src/__tests__/auto-exposure-transaction.integration.test.ts +4 -9
  332. package/src/__tests__/barrel-distortion-lkg.integration.test.ts +353 -0
  333. package/src/__tests__/barrel-distortion.dawn.test.ts +41 -0
  334. package/src/__tests__/barrel-distortion.unit.test.ts +364 -0
  335. package/src/__tests__/construct-renderer-identity.unit.test.ts +49 -0
  336. package/src/__tests__/detached-recovery-graph.unit.test.ts +277 -0
  337. package/src/__tests__/device-feature-admission.unit.test.ts +3 -2
  338. package/src/__tests__/device-loss-fanout.unit.test.ts +36 -1
  339. package/src/__tests__/docs-gate-green.unit.test.ts +112 -1
  340. package/src/__tests__/factory-contract.integration.test.ts +295 -45
  341. package/src/__tests__/feature-depth-input.dawn.test.ts +129 -2
  342. package/src/__tests__/fullscreen-feature-plan.unit.test.ts +14 -3
  343. package/src/__tests__/gpu-dirty-ranges.unit.test.ts +22 -0
  344. package/src/__tests__/gpu-driven-baseline.characterization.test.ts +16 -3
  345. package/src/__tests__/gpu-driven-batch-topology-pbr.unit.test.ts +12 -0
  346. package/src/__tests__/gpu-driven-material-artifacts.unit.test.ts +143 -0
  347. package/src/__tests__/gpu-driven-pbr.dawn.test.ts +5 -6
  348. package/src/__tests__/gpu-driven-production.integration.test.ts +482 -3
  349. package/src/__tests__/gpu-driven-shadow-views.dawn.test.ts +6 -5
  350. package/src/__tests__/gpu-driven-view-gpu-evidence.ts +94 -6
  351. package/src/__tests__/gpu-driven-view-graph.integration.test.ts +18 -2
  352. package/src/__tests__/gpu-driven-view.browser.test.ts +5 -8
  353. package/src/__tests__/gpu-driven-view.dawn.test.ts +6 -2
  354. package/src/__tests__/gpu-driven-view.unit.test.ts +1 -1
  355. package/src/__tests__/gpu-pass-timing-lifecycle.integration.test.ts +1 -0
  356. package/src/__tests__/gpu-pass-timing.browser.test.ts +6 -4
  357. package/src/__tests__/gpu-pass-timing.rhi-null.unit.test.ts +1 -0
  358. package/src/__tests__/gpu-scene.unit.test.ts +119 -9
  359. package/src/__tests__/instance-allocation-failure.unit.test.ts +57 -0
  360. package/src/__tests__/instances-culling.integration.test.ts +10 -36
  361. package/src/__tests__/instances-store.unit.test.ts +97 -305
  362. package/src/__tests__/instances-world-ownership.integration.test.ts +62 -0
  363. package/src/__tests__/ktx2-basis-gpu-consumer.dawn.test.ts +4 -1
  364. package/src/__tests__/main-pass-material-medium-selection.unit.test.ts +145 -0
  365. package/src/__tests__/material-shader-prewarm.unit.test.ts +59 -0
  366. package/src/__tests__/material-snapshot-mutation.integration.test.ts +39 -1
  367. package/src/__tests__/materials-standard-contract.unit.test.ts +0 -1
  368. package/src/__tests__/morph-culling-reentry.dawn.test.ts +5 -5
  369. package/src/__tests__/morph-visual-evidence.integration.test.ts +8 -7
  370. package/src/__tests__/motion-blur-compute.dawn.test.ts +13 -7
  371. package/src/__tests__/motion-blur.pixel.integration.test.ts +2 -2
  372. package/src/__tests__/nineslice-handle-surface.unit.test.ts +4 -4
  373. package/src/__tests__/pbr-view-layout.unit.test.ts +9 -0
  374. package/src/__tests__/physical-clearcoat.integration.test.ts +66 -8
  375. package/src/__tests__/physical-material-budget.unit.test.ts +40 -0
  376. package/src/__tests__/prepared-graphics-capability.unit.test.ts +66 -2
  377. package/src/__tests__/probe-bindings.unit.test.ts +582 -1
  378. package/src/__tests__/probe-scene-dirty.integration.test.ts +28 -1
  379. package/src/__tests__/receipt-observation-retirement.unit.test.ts +65 -0
  380. package/src/__tests__/recovery-candidate-prepare.contract.test.ts +69 -0
  381. package/src/__tests__/render-error-code-owner.test-d.ts +8 -0
  382. package/src/__tests__/render-feature-diagnostics.unit.test.ts +15 -2
  383. package/src/__tests__/render-feature-error-reporting.unit.test.ts +21 -1
  384. package/src/__tests__/render-feature-prepared-diagnostics.unit.test.ts +10 -1
  385. package/src/__tests__/render-feature-retry.unit.test.ts +12 -1
  386. package/src/__tests__/render-scene-mixed-updates.integration.test.ts +145 -19
  387. package/src/__tests__/render-scene-projection.unit.test.ts +36 -11
  388. package/src/__tests__/render-scene-temporal-retry.unit.test.ts +20 -20
  389. package/src/__tests__/render-target-probe-soak.perf.test.ts +2 -2
  390. package/src/__tests__/render-temporal-environment-consumer.browser.test.ts +3 -3
  391. package/src/__tests__/render-temporal-environment-consumer.dawn.test.ts +5 -2
  392. package/src/__tests__/renderer-factory-material-contract.unit.test.ts +42 -8
  393. package/src/__tests__/renderer-frame-generation-fence.integration.test.ts +16 -0
  394. package/src/__tests__/renderer-frame-transaction.integration.test.ts +26 -10
  395. package/src/__tests__/resource-allocation.unit.test.ts +123 -0
  396. package/src/__tests__/single-layer-medium-passes.unit.test.ts +275 -0
  397. package/src/__tests__/skin-motion-regression.unit.test.ts +70 -1
  398. package/src/__tests__/skin-palette-recycling.dawn.test.ts +97 -0
  399. package/src/__tests__/skinned-shadow-caster.test.ts +15 -0
  400. package/src/__tests__/ssr-carrier-public-contract.unit.test.ts +21 -0
  401. package/src/__tests__/ssr-gpu-dispatch.browser.test.ts +4 -4
  402. package/src/__tests__/ssr-gpu-dispatch.dawn.test.ts +2 -2
  403. package/src/__tests__/ssr-gpu-dispatch.ts +1 -1
  404. package/src/__tests__/ssr-receiver-coverage.dawn.test.ts +6 -2
  405. package/src/__tests__/standard-output-chain-contract.unit.test.ts +28 -0
  406. package/src/__tests__/standard-pbr-artifact-assembly.unit.test.ts +46 -1
  407. package/src/__tests__/standard-pipeline.integration.test.ts +182 -1
  408. package/src/__tests__/surface-dynamic-buffer-lifecycle.unit.test.ts +506 -0
  409. package/src/__tests__/surface-submission-observation.unit.test.ts +812 -0
  410. package/src/__tests__/temporal-history-lifecycle.unit.test.ts +32 -0
  411. package/src/__tests__/temporal-performance.integration.test.ts +3 -3
  412. package/src/__tests__/visibility-instances.integration.test.ts +7 -19
  413. package/src/__tests__/visibility-producer-matrix.integration.test.ts +9 -20
  414. package/src/__tests__/volume-optics-oracle.unit.test.ts +4 -2
  415. package/src/__tests__/volumetric-fog-budget-recovery.integration.test.ts +30 -20
  416. package/src/__tests__/volumetric-fog-errors.unit.test.ts +4 -3
  417. package/src/__tests__/volumetric-fog-multiple.unit.test.ts +55 -0
  418. package/src/__tests__/volumetric-fog-spot-frame-optics.integration.test.ts +1 -1
  419. package/src/__tests__/volumetric-fog-stage-readback.dawn.test.ts +113 -9
  420. package/src/__tests__/volumetric-fog-topology.unit.test.ts +5 -3
  421. package/src/assembly/backend-contract.ts +30 -0
  422. package/src/assembly/barrel-distortion-inspection.ts +22 -0
  423. package/src/assembly/canvas-draw-guard.ts +11 -0
  424. package/src/assembly/cloud-shadow-entry.ts +22 -0
  425. package/src/assembly/device-feature-admission.ts +2 -2
  426. package/src/assembly/dynamic-geometry-host.ts +65 -37
  427. package/src/assembly/dynamic-geometry-runtime.ts +7 -1
  428. package/src/assembly/factory.ts +2 -30
  429. package/src/assembly/host-contract.ts +8 -5
  430. package/src/assembly/material/assembly.ts +25 -13
  431. package/src/assembly/material/pipeline-helpers.ts +53 -12
  432. package/src/assembly/material-shader-policy.ts +55 -0
  433. package/src/assembly/material-shader-prewarm.ts +21 -10
  434. package/src/assembly/recovery/device-loss-fanout.ts +13 -0
  435. package/src/assembly/recovery/renderer-recover.ts +50 -18
  436. package/src/assembly/render-feature-post-processes.ts +54 -0
  437. package/src/assembly/render-target-host.ts +57 -47
  438. package/src/assembly/renderer-facade.ts +7 -2
  439. package/src/assembly/renderer-feature-inspection.ts +8 -2
  440. package/src/assembly/renderer-frame-transaction.ts +23 -0
  441. package/src/assembly/renderer-inspection.ts +28 -0
  442. package/src/assembly/skin-palette-owner.ts +1 -1
  443. package/src/assembly/temporal-post-process-prewarm.ts +3 -3
  444. package/src/assembly/webgpu-pbr-ready.ts +9 -1
  445. package/src/assembly/webgpu-ready-per-pass.ts +104 -0
  446. package/src/assembly/webgpu-ready.ts +116 -62
  447. package/src/assembly/webgpu-renderer-bootstrap.ts +0 -12
  448. package/src/assembly/webgpu-renderer-observation-owner.ts +222 -0
  449. package/src/assembly/webgpu-renderer.ts +303 -313
  450. package/src/assembly/webgpu-vertex-layouts.ts +1 -1
  451. package/src/barrel-distortion.ts +247 -0
  452. package/src/cloud/__tests__/cloud-density-parity.dawn.test.ts +173 -0
  453. package/src/cloud/__tests__/cloud-layer-framebuffer-y.dawn.test.ts +265 -0
  454. package/src/cloud/__tests__/cloud-layer.browser.test.ts +432 -0
  455. package/src/cloud/__tests__/cloud-layer.unit.test.ts +634 -0
  456. package/src/cloud/density.ts +600 -0
  457. package/src/cloud/extract.ts +110 -0
  458. package/src/cloud/feature.ts +1810 -0
  459. package/src/cloud/frame-context.ts +42 -0
  460. package/src/cloud/inspection.ts +130 -0
  461. package/src/cloud/optics.ts +285 -0
  462. package/src/cloud/parameters.ts +255 -0
  463. package/src/cloud/resources.ts +122 -0
  464. package/src/cloud/shadow.ts +167 -0
  465. package/src/cloud/temporal.ts +226 -0
  466. package/src/components/barrel-distortion.ts +46 -0
  467. package/src/components/cloud-layer.ts +47 -0
  468. package/src/components/index.ts +2 -0
  469. package/src/components/instances.ts +18 -45
  470. package/src/components/sprite-instances.ts +1 -1
  471. package/src/construct-renderer.ts +1 -1
  472. package/src/device/gpu-residency.ts +26 -25
  473. package/src/dynamic-geometry.ts +12 -1
  474. package/src/errors/cloud.ts +103 -0
  475. package/src/errors/render.ts +47 -8
  476. package/src/examples/single-layer-medium-surface.ts +59 -0
  477. package/src/extract/camera.ts +15 -1
  478. package/src/extract/contracts.ts +5 -0
  479. package/src/extract/material-context.ts +21 -0
  480. package/src/features/barrel-distortion.ts +172 -0
  481. package/src/features/error-reporting.ts +26 -6
  482. package/src/features/host.ts +128 -19
  483. package/src/features/plan.ts +10 -0
  484. package/src/features/render-graph-contribution.ts +9 -0
  485. package/src/features/render-graph-raster.ts +45 -3
  486. package/src/features/targets.ts +66 -0
  487. package/src/features/types.ts +51 -0
  488. package/src/fullscreen-post-process-pass.ts +41 -9
  489. package/src/glyph-text-layout-system.ts +2 -2
  490. package/src/gpu-dirty-ranges.ts +48 -0
  491. package/src/gpu-driven/batch-topology.ts +53 -0
  492. package/src/gpu-driven/material-artifacts.ts +33 -25
  493. package/src/gpu-driven/prepared-draw.ts +12 -4
  494. package/src/gpu-driven/production-raster-material.ts +1894 -0
  495. package/src/gpu-driven/production-raster.ts +825 -784
  496. package/src/gpu-driven/resource-allocation.ts +142 -0
  497. package/src/gpu-driven/shadow-ownership.ts +71 -0
  498. package/src/gpu-driven/view-gpu.ts +164 -10
  499. package/src/gpu-scene.ts +75 -84
  500. package/src/hdrp-buffers.ts +4 -3
  501. package/src/ibl/frame-resources.ts +0 -1
  502. package/src/ibl/skylight-bind-group.ts +62 -32
  503. package/src/index.ts +205 -9
  504. package/src/inspection-types.ts +162 -0
  505. package/src/instance-buffer-cache.ts +4 -4
  506. package/src/instances.ts +152 -569
  507. package/src/pbr-pipeline.ts +230 -30
  508. package/src/pipeline/single-layer-medium-passes.ts +267 -0
  509. package/src/pipeline/standard-forward-lane.ts +313 -57
  510. package/src/pipeline/standard-output/graph.ts +8 -2
  511. package/src/pipeline/standard-output/lut-gpu.ts +3 -3
  512. package/src/pipeline/standard-output/resources.ts +2 -2
  513. package/src/pipeline/standard-output/types.ts +12 -1
  514. package/src/pipeline/standard-pipeline.ts +291 -18
  515. package/src/pipeline/standard-post.ts +90 -24
  516. package/src/pipeline-builder.ts +1 -1
  517. package/src/plugin.ts +4 -0
  518. package/src/points-lines/__tests__/points-lines.bench.ts +17 -8
  519. package/src/prepare/prepared-graphics-resolver.ts +2 -0
  520. package/src/publication/__tests__/derived-geometry.integration.test.ts +177 -0
  521. package/src/publication/__tests__/features.integration.test.ts +122 -0
  522. package/src/publication/__tests__/programs.unit.test.ts +25 -0
  523. package/src/publication/__tests__/publication.integration.test.ts +370 -0
  524. package/src/publication/__tests__/targets.integration.test.ts +120 -0
  525. package/src/publication/__tests__/video.browser.test.ts +50 -0
  526. package/src/publication/contract.ts +104 -0
  527. package/src/publication/dependencies.ts +54 -0
  528. package/src/publication/prepare-geometry.ts +94 -0
  529. package/src/publication/programs.ts +45 -0
  530. package/src/publication/publisher.ts +618 -0
  531. package/src/publication/receiver.ts +297 -0
  532. package/src/publication/resource-scope.ts +31 -0
  533. package/src/publication/targets.ts +182 -0
  534. package/src/publication/video.ts +33 -0
  535. package/src/record/__tests__/main-pass-geometry.unit.test.ts +30 -0
  536. package/src/record/__tests__/material-bg-cache.unit.test.ts +15 -1
  537. package/src/record/__tests__/sprite-material-abi.unit.test.ts +9 -11
  538. package/src/record/__tests__/temporal-payload.unit.test.ts +1 -1
  539. package/src/record/__tests__/transparent-group2-selection.unit.test.ts +11 -0
  540. package/src/record/__tests__/typed-frame-graph-plan.unit.test.ts +1 -0
  541. package/src/record/__tests__/video-texture-view.unit.test.ts +9 -9
  542. package/src/record/__tests__/view-ubo-layout.unit.test.ts +4 -3
  543. package/src/record/barrel-distortion-frame.ts +110 -0
  544. package/src/record/dynamic-geometry-consumption.ts +39 -9
  545. package/src/record/fold-buckets.ts +855 -0
  546. package/src/record/fold-instance-buffer.ts +51 -0
  547. package/src/record/frame-lighting.ts +36 -2
  548. package/src/record/frame-snapshot.ts +45 -9
  549. package/src/record/frame.ts +258 -1105
  550. package/src/record/gpu-draw-receipts.ts +38 -0
  551. package/src/record/gpu-timing.ts +48 -5
  552. package/src/record/helpers.ts +2 -2
  553. package/src/record/main-pass-geometry.ts +272 -84
  554. package/src/record/main-pass-material.ts +102 -36
  555. package/src/record/main-pass-sprite-draws.ts +13 -217
  556. package/src/record/main-pass.ts +164 -27
  557. package/src/record/motion-blur-receipt.ts +91 -0
  558. package/src/record/prepared-material-bindings.ts +11 -6
  559. package/src/record/probe-blend-buffer.ts +180 -0
  560. package/src/record/recovery-pipeline.ts +35 -3
  561. package/src/record/render-context.ts +41 -5
  562. package/src/record/shadow-pass.ts +30 -4
  563. package/src/record/skybox-post-pass.ts +28 -4
  564. package/src/record/sprite-instance-buffer.ts +155 -0
  565. package/src/record/target-capture-graph.ts +258 -0
  566. package/src/record/typed-frame-graph.ts +776 -340
  567. package/src/record/view-ubo.ts +27 -4
  568. package/src/record/volume-params.ts +225 -0
  569. package/src/recovery/render-system-candidate.ts +243 -50
  570. package/src/reflection/record-owner.ts +7 -3
  571. package/src/render-contract.ts +54 -5
  572. package/src/render-graph-primitives.ts +7 -1
  573. package/src/render-pipeline.ts +130 -0
  574. package/src/render-system-extract-tail.ts +90 -78
  575. package/src/render-system-extract.ts +76 -76
  576. package/src/render-system-presentation.ts +56 -0
  577. package/src/render-system-producer-roots.ts +96 -0
  578. package/src/render-system-projections.ts +3 -2
  579. package/src/render-system-residency.ts +159 -0
  580. package/src/render-system.ts +421 -408
  581. package/src/scene/probe-blend.ts +96 -4
  582. package/src/scene/render-scene.ts +416 -337
  583. package/src/scene/render-source.ts +90 -0
  584. package/src/scene/source-systems.ts +33 -0
  585. package/src/ssao-buffers.ts +95 -2
  586. package/src/surface/__tests__/dynamic-input.unit.test.ts +374 -0
  587. package/src/surface/__tests__/gpu-driven.unit.test.ts +87 -0
  588. package/src/surface/dynamic-input.ts +658 -0
  589. package/src/surface/gpu-driven.ts +147 -0
  590. package/src/surface/submission-observation.ts +517 -0
  591. package/src/systems/skin-palette-allocator.ts +5 -1
  592. package/src/systems/skin-palette-types.ts +11 -0
  593. package/src/systems/transparent-dispatch.ts +2 -2
  594. package/src/systems/transparent-sort-config.ts +3 -1
  595. package/src/temporal/gpu.ts +101 -17
  596. package/src/temporal/inspection.ts +7 -1
  597. package/src/temporal/standard-scene-data.ts +5 -0
  598. package/src/temporal/target-coverage-attachment.ts +4 -0
  599. package/src/transmission/__tests__/single-layer-medium.unit.test.ts +149 -0
  600. package/src/transmission/__tests__/standard-transmission.dawn.test.ts +12 -11
  601. package/src/transmission/single-layer-medium.ts +322 -0
  602. package/src/typed-render-graph-primitives.ts +70 -2
  603. package/src/volume/component.ts +10 -9
  604. package/src/volume/extract.ts +11 -5
  605. package/src/volume/inspection.ts +3 -0
  606. package/src/volume/passes.ts +87 -4
  607. package/src/volume/resources.ts +2 -1
  608. package/dist/chunk-3RTCJTH4.mjs +0 -1610
  609. package/dist/chunk-3RTCJTH4.mjs.map +0 -1
  610. package/dist/chunk-BLXGONR2.mjs.map +0 -1
  611. package/dist/chunk-ILQ5MEZF.mjs +0 -32
  612. package/dist/chunk-ILQ5MEZF.mjs.map +0 -1
  613. package/dist/chunk-LEAXOMYJ.mjs.map +0 -1
  614. package/dist/chunk-NB2S7ZRX.mjs +0 -1783
  615. package/dist/chunk-NB2S7ZRX.mjs.map +0 -1
  616. package/dist/chunk-NNQL7CB3.mjs +0 -1713
  617. package/dist/chunk-NNQL7CB3.mjs.map +0 -1
  618. package/dist/chunk-OO3DRYK7.mjs.map +0 -1
  619. package/dist/chunk-PA5DRJNI.mjs.map +0 -1
  620. package/dist/chunk-PLAXOOX5.mjs +0 -1907
  621. package/dist/chunk-PLAXOOX5.mjs.map +0 -1
  622. package/dist/chunk-RXZ3RGOU.mjs +0 -53
  623. package/dist/chunk-RXZ3RGOU.mjs.map +0 -1
  624. package/dist/chunk-VOZWDM3L.mjs.map +0 -1
package/src/gpu-scene.ts CHANGED
@@ -1,6 +1,7 @@
1
1
  import type { Buffer, Result, RhiDevice } from '@forgeax/engine-rhi';
2
2
  import { err, ok, RhiError } from '@forgeax/engine-rhi';
3
3
  import { createStandardPbrArtifactReceipt } from '@forgeax/engine-shader';
4
+ import { GpuDirtyRanges } from './gpu-dirty-ranges';
4
5
  import {
5
6
  GPU_SCENE_LAYOUTS,
6
7
  type GpuSceneTableLayout,
@@ -13,6 +14,7 @@ import {
13
14
  } from './gpu-usage';
14
15
  import type { GpuSceneInspection } from './inspection-types';
15
16
  import { packMaterialProgramRow, packStandardPbrMaterialRow } from './material-row';
17
+ import type { MaterialSnapshot } from './render-system-extract';
16
18
  import type { RenderSceneApplyResult, RenderSceneSlot } from './scene/render-scene-types';
17
19
 
18
20
  export type { GpuSceneInspection } from './inspection-types';
@@ -206,22 +208,6 @@ function stableU32(value: string): number {
206
208
  return hash >>> 0;
207
209
  }
208
210
 
209
- function coalesceSlots(
210
- slots: readonly number[],
211
- ): readonly { readonly start: number; readonly end: number }[] {
212
- const ordered = [...new Set(slots)].sort((a, b) => a - b);
213
- const ranges: Array<{ start: number; end: number }> = [];
214
- for (const slot of ordered) {
215
- const previous = ranges.at(-1);
216
- if (previous !== undefined && previous.end === slot) {
217
- previous.end = slot + 1;
218
- } else {
219
- ranges.push({ start: slot, end: slot + 1 });
220
- }
221
- }
222
- return ranges;
223
- }
224
-
225
211
  /**
226
212
  * Build a lookup from the current instance identity to its submitted ordinal.
227
213
  * The GPU table is physically compacted by ordinal, so this small CPU lookup
@@ -274,6 +260,9 @@ function instanceIdentityChanged(
274
260
 
275
261
  /** Persistent GPU tables derived only from renderer projection slots. */
276
262
  export class GpuScene {
263
+ private readonly dirtyRanges = new GpuDirtyRanges();
264
+ private readonly rowScratch = new Uint8Array(Math.max(PRIMITIVE.stride, DRAW_TEMPLATE.stride));
265
+ private readonly rowScratchView = new DataView(this.rowScratch.buffer);
277
266
  private disposed = false;
278
267
  private tableBytes: Record<GpuSceneTableName, ArrayBuffer>;
279
268
  private transformBytes: Uint8Array;
@@ -444,6 +433,9 @@ export class GpuScene {
444
433
  if (!grown.ok) return grown;
445
434
  }
446
435
 
436
+ // A shared material has one packed value per publication, independent of
437
+ // how many primitives reference it. Do not retain mutable caller snapshots.
438
+ const materialRows = new Map<MaterialSnapshot, Uint8Array>();
447
439
  const publications = [...delta.createdSlots, ...delta.updatedSlots, ...delta.recreatedSlots];
448
440
  const newSlots = new Set(
449
441
  [...delta.createdSlots, ...delta.recreatedSlots].map((record) => record.slot),
@@ -451,7 +443,7 @@ export class GpuScene {
451
443
  for (const record of publications) {
452
444
  const reset = newSlots.has(record.slot) || allocationResets.has(record.slot);
453
445
  if (reset || contentUpdatedSlotIds.has(record.slot)) {
454
- this.writeSlot(record, reset, writesByTable, temporalResolver?.(record));
446
+ this.writeSlot(record, reset, writesByTable, materialRows, temporalResolver?.(record));
455
447
  continue;
456
448
  }
457
449
  if (instanceUpdatedSlotIds.has(record.slot))
@@ -483,7 +475,7 @@ export class GpuScene {
483
475
  if (this.pendingTemporalTransforms.size === 0) return ok(undefined);
484
476
  const currentOffset = offset(TRANSFORM, 'currentWorld');
485
477
  const previousOffset = offset(TRANSFORM, 'previousWorld');
486
- const ranges = coalesceSlots([...this.pendingTemporalTransforms]);
478
+ const ranges = this.dirtyRanges.coalesce([...this.pendingTemporalTransforms]);
487
479
  for (const range of ranges) {
488
480
  for (let index = range.start; index < range.end; index += 1) {
489
481
  this.pendingTemporalUploads.add(index);
@@ -549,7 +541,8 @@ export class GpuScene {
549
541
  }
550
542
  for (const bytes of Object.values(this.tableBytes)) new Uint8Array(bytes).fill(0);
551
543
  this.writeIdentityTransform();
552
- for (const slot of slots) this.writeSlot(slot, true, writesByTable);
544
+ const materialRows = new Map<MaterialSnapshot, Uint8Array>();
545
+ for (const slot of slots) this.writeSlot(slot, true, writesByTable, materialRows);
553
546
  let bytes = 0;
554
547
  for (const name of TABLE_NAMES) {
555
548
  const table = this.tableBytes[name];
@@ -610,64 +603,44 @@ export class GpuScene {
610
603
  record: RenderSceneSlot,
611
604
  resetPrevious: boolean,
612
605
  writes: Record<GpuSceneTableName, number[]>,
606
+ materialRows: Map<MaterialSnapshot, Uint8Array>,
613
607
  temporal?: GpuSceneTemporalSnapshot,
614
608
  ): void {
615
609
  const allocation = this.allocations.get(record.slot);
616
610
  if (allocation === undefined) throw new RangeError('GPU Scene allocation unavailable');
617
- const primitiveOffset = record.slot * PRIMITIVE.stride;
618
- const primitive = new DataView(this.tableBytes.primitive);
611
+ this.rowScratch.fill(0);
612
+ const primitive = this.rowScratchView;
619
613
  const bounds = record.snapshot.localAabb;
620
- primitive.setUint32(primitiveOffset + offset(PRIMITIVE, 'generation'), record.generation, true);
614
+ primitive.setUint32(offset(PRIMITIVE, 'generation'), record.generation, true);
621
615
  primitive.setUint32(
622
- primitiveOffset + offset(PRIMITIVE, 'flags'),
616
+ offset(PRIMITIVE, 'flags'),
623
617
  PRIMITIVE_ACTIVE |
624
618
  (bounds === undefined ? 0 : PRIMITIVE_HAS_BOUNDS) |
625
619
  (record.snapshot.gpuDrivenDraws === undefined ? 0 : PRIMITIVE_GPU_DRIVEN),
626
620
  true,
627
621
  );
628
- primitive.setUint32(
629
- primitiveOffset + offset(PRIMITIVE, 'transformIndex'),
630
- allocation.transformStart,
631
- true,
632
- );
633
- primitive.setUint32(
634
- primitiveOffset + offset(PRIMITIVE, 'materialIndex'),
635
- allocation.materialStart,
636
- true,
637
- );
638
- primitive.setUint32(
639
- primitiveOffset + offset(PRIMITIVE, 'drawTemplateIndex'),
640
- allocation.drawStart,
641
- true,
642
- );
643
- primitive.setUint32(
644
- primitiveOffset + offset(PRIMITIVE, 'instanceStart'),
645
- allocation.instanceStart,
646
- true,
647
- );
648
- primitive.setUint32(
649
- primitiveOffset + offset(PRIMITIVE, 'instanceCount'),
650
- allocation.instanceCount,
651
- true,
652
- );
653
- primitive.setUint32(
654
- primitiveOffset + offset(PRIMITIVE, 'assetHandle'),
655
- record.snapshot.assetHandle,
656
- true,
657
- );
658
- writeVec4(primitive, primitiveOffset + offset(PRIMITIVE, 'localBoundsMin'), [
622
+ primitive.setUint32(offset(PRIMITIVE, 'transformIndex'), allocation.transformStart, true);
623
+ primitive.setUint32(offset(PRIMITIVE, 'materialIndex'), allocation.materialStart, true);
624
+ primitive.setUint32(offset(PRIMITIVE, 'drawTemplateIndex'), allocation.drawStart, true);
625
+ primitive.setUint32(offset(PRIMITIVE, 'instanceStart'), allocation.instanceStart, true);
626
+ primitive.setUint32(offset(PRIMITIVE, 'instanceCount'), allocation.instanceCount, true);
627
+ primitive.setUint32(offset(PRIMITIVE, 'assetHandle'), record.snapshot.assetHandle, true);
628
+ writeVec4(primitive, offset(PRIMITIVE, 'localBoundsMin'), [
659
629
  bounds?.[0] ?? 0,
660
630
  bounds?.[1] ?? 0,
661
631
  bounds?.[2] ?? 0,
662
632
  0,
663
633
  ]);
664
- writeVec4(primitive, primitiveOffset + offset(PRIMITIVE, 'localBoundsMax'), [
634
+ writeVec4(primitive, offset(PRIMITIVE, 'localBoundsMax'), [
665
635
  bounds?.[3] ?? 0,
666
636
  bounds?.[4] ?? 0,
667
637
  bounds?.[5] ?? 0,
668
638
  0,
669
639
  ]);
670
640
 
641
+ if (this.writeRow('primitive', record.slot, this.rowScratch) || resetPrevious)
642
+ writes.primitive.push(record.slot);
643
+
671
644
  const instance = new DataView(this.tableBytes.instance);
672
645
  const transform = this.transformView;
673
646
  const instances = record.snapshot.instances;
@@ -773,16 +746,15 @@ export class GpuScene {
773
746
  this.rememberInstanceGenerations(record.slot, currentGenerations, allocation.instanceCount);
774
747
 
775
748
  this.writeRootTransform(record, resetPrevious, writes);
776
- writes.primitive.push(record.slot);
777
749
 
778
- const draw = new DataView(this.tableBytes.drawTemplate);
750
+ const draw = this.rowScratchView;
779
751
  const drawSnapshots = record.snapshot.gpuDrivenDraws ?? [];
780
752
  for (let ordinal = 0; ordinal < allocation.drawCount; ordinal += 1) {
781
753
  const drawIndex = allocation.drawStart + ordinal;
782
- const drawOffset = drawIndex * DRAW_TEMPLATE.stride;
754
+ this.rowScratch.fill(0);
783
755
  const drawSnapshot = drawSnapshots[ordinal];
784
756
  draw.setUint32(
785
- drawOffset + offset(DRAW_TEMPLATE, 'pipelineClass'),
757
+ offset(DRAW_TEMPLATE, 'pipelineClass'),
786
758
  drawSnapshot === undefined
787
759
  ? 0
788
760
  : stableU32(
@@ -793,58 +765,77 @@ export class GpuScene {
793
765
  true,
794
766
  );
795
767
  draw.setUint32(
796
- drawOffset + offset(DRAW_TEMPLATE, 'materialIndex'),
768
+ offset(DRAW_TEMPLATE, 'materialIndex'),
797
769
  allocation.materialStart + (drawSnapshot?.materialSlot ?? 0),
798
770
  true,
799
771
  );
800
772
  draw.setUint32(
801
- drawOffset + offset(DRAW_TEMPLATE, 'firstIndex'),
773
+ offset(DRAW_TEMPLATE, 'firstIndex'),
802
774
  drawSnapshot?.prepared?.first ?? drawSnapshot?.first ?? 0,
803
775
  true,
804
776
  );
805
777
  draw.setUint32(
806
- drawOffset + offset(DRAW_TEMPLATE, 'indexCount'),
778
+ offset(DRAW_TEMPLATE, 'indexCount'),
807
779
  drawSnapshot?.prepared?.count ?? drawSnapshot?.count ?? 0,
808
780
  true,
809
781
  );
810
782
  draw.setInt32(
811
- drawOffset + offset(DRAW_TEMPLATE, 'baseVertex'),
783
+ offset(DRAW_TEMPLATE, 'baseVertex'),
812
784
  drawSnapshot?.prepared?.baseVertex ?? drawSnapshot?.baseVertex ?? 0,
813
785
  true,
814
786
  );
815
- draw.setUint32(drawOffset + offset(DRAW_TEMPLATE, 'firstInstance'), 0, true);
816
- draw.setUint32(drawOffset + offset(DRAW_TEMPLATE, 'passFlags'), 0, true);
817
- draw.setUint32(drawOffset + offset(DRAW_TEMPLATE, 'reserved'), 0, true);
818
- writes.drawTemplate.push(drawIndex);
787
+ draw.setUint32(offset(DRAW_TEMPLATE, 'firstInstance'), 0, true);
788
+ draw.setUint32(offset(DRAW_TEMPLATE, 'passFlags'), 0, true);
789
+ draw.setUint32(offset(DRAW_TEMPLATE, 'reserved'), 0, true);
790
+ if (this.writeRow('drawTemplate', drawIndex, this.rowScratch) || resetPrevious)
791
+ writes.drawTemplate.push(drawIndex);
819
792
  }
820
793
 
821
- this.writeMaterialSlot(record, writes);
794
+ this.writeMaterialSlot(record, writes, materialRows, resetPrevious);
795
+ }
796
+
797
+ /** Compare against the resident CPU bytes; pending upload rows survive failure. */
798
+ private writeRow(table: GpuSceneTableName, index: number, row: Uint8Array): boolean {
799
+ const stride = TABLE_LAYOUTS[table].stride;
800
+ const destination = new Uint8Array(this.tableBytes[table], index * stride, stride);
801
+ let changed = false;
802
+ for (let byte = 0; byte < stride; byte += 1) {
803
+ const value = row[byte] ?? 0;
804
+ if (destination[byte] === value) continue;
805
+ destination[byte] = value;
806
+ changed = true;
807
+ }
808
+ return changed;
822
809
  }
823
810
 
824
811
  private writeMaterialSlot(
825
812
  record: RenderSceneSlot,
826
813
  writes: Record<GpuSceneTableName, number[]>,
814
+ materialRows: Map<MaterialSnapshot, Uint8Array>,
815
+ reset: boolean,
827
816
  ): void {
828
817
  const allocation = this.allocations.get(record.slot);
829
818
  if (allocation === undefined) throw new RangeError('GPU Scene allocation unavailable');
830
819
  for (let ordinal = 0; ordinal < allocation.materialCount; ordinal += 1) {
831
820
  const materialIndex = allocation.materialStart + ordinal;
832
- const materialOffset = materialIndex * MATERIAL.stride;
833
821
  const snapshot = record.snapshot.materials[ordinal] ?? record.snapshot.material;
834
- const shaderId = snapshot.materialShaderId;
835
- const schema = snapshot.materialParamSchema;
836
- const row =
837
- shaderId !== undefined &&
838
- shaderId !== 'forgeax::default-standard-pbr' &&
839
- shaderId !== 'forgeax::pbr-skin' &&
840
- shaderId !== 'forgeax::default-standard-pbr-skin' &&
841
- schema !== undefined
842
- ? packMaterialProgramRow(schema, snapshot, MATERIAL.stride)
843
- : packStandardPbrMaterialRow(STANDARD_PBR_RECEIPT, snapshot);
844
- const destination = new Uint8Array(this.tableBytes.material, materialOffset, MATERIAL.stride);
845
- destination.fill(0);
846
- if (row !== undefined) destination.set(row.subarray(0, MATERIAL.stride));
847
- writes.material.push(materialIndex);
822
+ let row = materialRows.get(snapshot);
823
+ if (row === undefined) {
824
+ const shaderId = snapshot.materialShaderId;
825
+ const schema = snapshot.materialParamSchema;
826
+ row =
827
+ shaderId !== undefined &&
828
+ shaderId !== 'forgeax::default-standard-pbr' &&
829
+ shaderId !== 'forgeax::pbr-skin' &&
830
+ shaderId !== 'forgeax::default-standard-pbr-skin' &&
831
+ schema !== undefined
832
+ ? packMaterialProgramRow(schema, snapshot, MATERIAL.stride)
833
+ : packStandardPbrMaterialRow(STANDARD_PBR_RECEIPT, snapshot);
834
+ row ??= new Uint8Array(MATERIAL.stride);
835
+ materialRows.set(snapshot, row);
836
+ }
837
+ if (this.writeRow('material', materialIndex, row) || reset)
838
+ writes.material.push(materialIndex);
848
839
  }
849
840
  }
850
841
 
@@ -972,7 +963,7 @@ export class GpuScene {
972
963
  let rangeCount = 0;
973
964
  let bytes = 0;
974
965
  for (const name of TABLE_NAMES) {
975
- const ranges = coalesceSlots(rows[name]);
966
+ const ranges = this.dirtyRanges.coalesce(rows[name]);
976
967
  rangeCount += ranges.length;
977
968
  for (const range of ranges) {
978
969
  const layout = TABLE_LAYOUTS[name];
@@ -559,6 +559,7 @@ export function createHdrpUnifiedBindGroup(
559
559
  hdrpBuffers: HdrpBuffers,
560
560
  meshStorageBuffer: Buffer,
561
561
  ssaoOptions: SsaoBindOptions = { enabled: false },
562
+ meshBindingBytes = MESH_PER_ENTITY_STRIDE,
562
563
  ): BindGroup | null {
563
564
  const fallback = getOrCreateSsaoFallbackTexture(runtime);
564
565
  if (fallback === null) return null;
@@ -579,7 +580,7 @@ export function createHdrpUnifiedBindGroup(
579
580
  value: {
580
581
  buffer: meshStorageBuffer,
581
582
  offset: 0,
582
- size: MESH_PER_ENTITY_STRIDE,
583
+ size: meshBindingBytes,
583
584
  },
584
585
  },
585
586
  },
@@ -602,17 +603,17 @@ export function createHdrpSkinUnifiedBindGroup(
602
603
  paletteBuffer: Buffer,
603
604
  paletteBindingWindowBytes: number,
604
605
  ssaoOptions: SsaoBindOptions = { enabled: false },
606
+ meshBindingBytes = MESH_PER_ENTITY_STRIDE,
605
607
  ): BindGroup | null {
606
608
  const fallback = getOrCreateSsaoFallbackTexture(runtime);
607
609
  if (fallback === null) return null;
608
- const meshSize = MESH_PER_ENTITY_STRIDE;
609
610
  const result = runtime.device.createBindGroup({
610
611
  label: 'hdrp-skin-unified-bg-group2',
611
612
  layout,
612
613
  entries: [
613
614
  ...createPbrSkinMeshBindGroupEntries(
614
615
  meshStorageBuffer,
615
- meshSize,
616
+ meshBindingBytes,
616
617
  paletteBuffer,
617
618
  paletteBindingWindowBytes,
618
619
  ),
@@ -32,7 +32,6 @@ export function resolveFrameSkylightResources(
32
32
  prefilterView: resident?.prefilterView ?? fallback.prefilterView,
33
33
  prefilterSampler: fallback.sampler,
34
34
  brdfLutView: resident?.brdfLutView ?? fallback.brdfLutView,
35
- brdfLutSampler: fallback.sampler,
36
35
  intensityBuffer: fallback.intensityBuffer,
37
36
  });
38
37
  }
@@ -1,20 +1,20 @@
1
1
  // skylight-bind-group.ts -- Skylight resources merged into @group(1) PBR
2
- // material BGL (binding 7..13) + fallback identity resource bundle. The
2
+ // material BGL (binding 7..12) + fallback identity resource bundle. The
3
3
  // complete Standard material group appends transmission entries.
4
4
  //
5
5
  // Plan-strategy D-5 (round-4 REVISED): the round-2 stand-alone @group(4)
6
6
  // Skylight BindGroupLayout collided with WebGPU's default maxBindGroups=4
7
7
  // limit, blocking pbr-pl pipeline-layout creation in chrome-beta. Round-4
8
- // rewrites the contract: Skylight 7 entries are **appended** to the
9
- // existing PBR material BindGroupLayout at bindings 7..13; pipeline layout
8
+ // rewrites the contract: Skylight 6 entries are **appended** to the
9
+ // existing PBR material BindGroupLayout at bindings 7..12; pipeline layout
10
10
  // stays at 4 slots `[view, material, mesh, instances]`; unlit pipeline is
11
11
  // untouched (it uses its own material BGL).
12
12
  //
13
13
  // Surface (M2 round-4 / t40 amend):
14
14
  // - mergeSkylightIntoMaterialBgl(materialBglEntries): given the existing
15
15
  // 7 PBR material BindGroupLayout entries (binding 0..6), returns the
16
- // merged 14-entry array with Skylight resources at binding 7..13
17
- // [irrTex, irrSampler, prefTex, prefSampler, brdfTex, brdfSampler,
16
+ // merged 13-entry array with Skylight resources at binding 7..12
17
+ // [irrTex, irrSampler, prefTex, prefSampler, brdfTex,
18
18
  // uniform { intensity: f32 }]. The merge is a pure function -- caller
19
19
  // (createRenderer) is responsible for passing the result to
20
20
  // `device.createBindGroupLayout`.
@@ -124,13 +124,13 @@ export interface SkylightQueue {
124
124
  */
125
125
  export interface SkylightBindGroupResources {
126
126
  readonly irradianceView: TextureView;
127
+ /** Shared by diffuse irradiance and the BRDF lookup table. */
127
128
  readonly irradianceSampler: Sampler;
128
129
  readonly prefilterView: TextureView;
129
130
  /** Present only when the per-draw prefilter slot was replaced by a local probe. */
130
131
  readonly skylightPrefilterView?: TextureView;
131
132
  readonly prefilterSampler: Sampler;
132
133
  readonly brdfLutView: TextureView;
133
- readonly brdfLutSampler: Sampler;
134
134
  readonly intensityBuffer: Buffer;
135
135
  }
136
136
 
@@ -143,7 +143,7 @@ export interface SkylightBindGroupResources {
143
143
  *
144
144
  * No stand-alone `bindGroup` field: the round-2 stand-alone Skylight BG
145
145
  * is gone (D-5 round-4); the fallback resources flow into the PBR
146
- * material BG at binding 7..13.
146
+ * material BG at binding 7..12.
147
147
  */
148
148
  export interface SkylightFallback {
149
149
  readonly irradianceTexture: Texture;
@@ -159,7 +159,7 @@ export interface SkylightFallback {
159
159
  // ─── Pure merger: BindGroupLayout entries (D-5 round-4) ─────────────────────
160
160
 
161
161
  /**
162
- * Append the 7 Skylight BindGroupLayout entries after the existing PBR
162
+ * Append the 6 Skylight BindGroupLayout entries after the existing PBR
163
163
  * user-region entries. Pure function -- the
164
164
  * caller passes the result to `device.createBindGroupLayout`. Charter P4
165
165
  * consistent abstraction: one BGL holds material + Skylight together,
@@ -208,16 +208,10 @@ export function mergeSkylightIntoMaterialBgl(
208
208
  visibility: GPU_SHADER_STAGE_FRAGMENT,
209
209
  texture: { sampleType: 'float', viewDimension: '2d' },
210
210
  } as BglEntry);
211
- // binding 12: brdfLutSampler
211
+ // binding 12: uniform { intensity: f32 }
212
212
  merged.push({
213
213
  binding: skylightBindingStart + 5,
214
214
  visibility: GPU_SHADER_STAGE_FRAGMENT,
215
- sampler: { type: 'filtering' },
216
- } as BglEntry);
217
- // binding 13: uniform { intensity: f32 }
218
- merged.push({
219
- binding: skylightBindingStart + 6,
220
- visibility: GPU_SHADER_STAGE_FRAGMENT,
221
215
  buffer: { type: 'uniform' },
222
216
  } as BglEntry);
223
217
  return merged;
@@ -226,7 +220,7 @@ export function mergeSkylightIntoMaterialBgl(
226
220
  // ─── Pure merger: BindGroupEntry values (assembly site) ─────────────────────
227
221
 
228
222
  /**
229
- * Append the 7 Skylight BindGroupEntry resources (binding 7..13) onto the
223
+ * Append the 6 Skylight BindGroupEntry resources (binding 7..12) onto the
230
224
  * existing PBR material BindGroupEntry values (binding 0..6). The caller
231
225
  * passes the result to `device.createBindGroup` as part of the merged
232
226
  * material BG.
@@ -242,6 +236,16 @@ export interface TransmissionBindGroupResources {
242
236
  readonly backdropView?: TextureView | null;
243
237
  }
244
238
 
239
+ /** Renderer-owned sampled resources consumed by the single-layer medium. */
240
+ export interface SurfaceMediumBindGroupResources {
241
+ readonly rawDepthSampler: Sampler;
242
+ readonly rawDepthView: TextureView;
243
+ readonly nearestLayerSampler: Sampler;
244
+ readonly nearestLayerView: TextureView;
245
+ readonly nearestDepthSampler: Sampler;
246
+ readonly nearestDepthView: TextureView;
247
+ }
248
+
245
249
  /** Engine-owned texture injection resources derived from material parameters. */
246
250
  export interface TextureInjectionResource {
247
251
  readonly slot: number;
@@ -258,6 +262,7 @@ export function assembleMaterialWithSkylightEntries(
258
262
  skylight: SkylightBindGroupResources,
259
263
  transmission?: TransmissionBindGroupResources | null | undefined,
260
264
  textureInjections: readonly TextureInjectionResource[] = [],
265
+ surfaceMedium?: SurfaceMediumBindGroupResources | undefined,
261
266
  ): BindGroupEntry[] {
262
267
  // IBL injection start = end of the user-region. The user-region IS
263
268
  // `materialEntries` (UBO binding 0 + N sampler/texture pairs), so its length
@@ -290,10 +295,6 @@ export function assembleMaterialWithSkylightEntries(
290
295
  },
291
296
  {
292
297
  binding: iblStart + 5,
293
- resource: { kind: 'sampler', value: skylight.brdfLutSampler },
294
- },
295
- {
296
- binding: iblStart + 6,
297
298
  resource: { kind: 'buffer', value: { buffer: skylight.intensityBuffer } },
298
299
  },
299
300
  ];
@@ -314,6 +315,35 @@ export function assembleMaterialWithSkylightEntries(
314
315
  resource: { kind: 'textureView', value: transmissionView },
315
316
  },
316
317
  );
318
+ if (surfaceMedium !== undefined) {
319
+ const surfaceStart = result.length;
320
+ result.push(
321
+ {
322
+ binding: surfaceStart,
323
+ resource: { kind: 'sampler', value: surfaceMedium.rawDepthSampler },
324
+ },
325
+ {
326
+ binding: surfaceStart + 1,
327
+ resource: { kind: 'textureView', value: surfaceMedium.rawDepthView },
328
+ },
329
+ {
330
+ binding: surfaceStart + 2,
331
+ resource: { kind: 'sampler', value: surfaceMedium.nearestLayerSampler },
332
+ },
333
+ {
334
+ binding: surfaceStart + 3,
335
+ resource: { kind: 'textureView', value: surfaceMedium.nearestLayerView },
336
+ },
337
+ {
338
+ binding: surfaceStart + 4,
339
+ resource: { kind: 'sampler', value: surfaceMedium.nearestDepthSampler },
340
+ },
341
+ {
342
+ binding: surfaceStart + 5,
343
+ resource: { kind: 'textureView', value: surfaceMedium.nearestDepthView },
344
+ },
345
+ );
346
+ }
317
347
  // Standard physical maps occupy fixed bindings 26..45. The `slot` value
318
348
  // is the canonical index from STANDARD_PHYSICAL_TEXTURE_FIELDS; preserve
319
349
  // gaps for omitted authored maps instead of compacting this tail.
@@ -333,13 +363,15 @@ export function assembleMaterialWithSkylightEntries(
333
363
  },
334
364
  );
335
365
  }
336
- result.push({
337
- binding: 47,
338
- resource: {
339
- kind: 'textureView',
340
- value: skylight.skylightPrefilterView ?? skylight.prefilterView,
341
- },
342
- });
366
+ if (surfaceMedium === undefined) {
367
+ result.push({
368
+ binding: 47,
369
+ resource: {
370
+ kind: 'textureView',
371
+ value: skylight.skylightPrefilterView ?? skylight.prefilterView,
372
+ },
373
+ });
374
+ }
343
375
  return result;
344
376
  }
345
377
 
@@ -371,11 +403,9 @@ export function createSkylightFallback(
371
403
  device: SkylightDevice,
372
404
  queue: SkylightQueue,
373
405
  ): SkylightFallback {
374
- // One sampler shared across the three texture slots. The PBR material
375
- // BindGroup still declares 3 separate sampler bindings (D-5 round-4
376
- // ordering at binding 8/10/12), so we pass the same handle three times
377
- // in assembleMaterialWithSkylightEntries; WebGPU spec permits sampler
378
- // reuse across BindGroupEntry slots.
406
+ // Diffuse IBL and the BRDF LUT share one binding; prefilter remains a
407
+ // separate binding so per-draw reflection probes can replace it. Both
408
+ // bindings use this linear-clamp sampler for the global environment.
379
409
  const samplerResult = device.createSampler({
380
410
  label: 'skylight-fallback-sampler',
381
411
  magFilter: 'linear',