@forgeax/engine-render 0.1.20 → 0.1.23

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (645) hide show
  1. package/README.md +365 -29
  2. package/dist/assembly/backend-contract.d.ts +13 -0
  3. package/dist/assembly/backend-contract.d.ts.map +1 -1
  4. package/dist/assembly/device-feature-admission.d.ts +18 -0
  5. package/dist/assembly/device-feature-admission.d.ts.map +1 -0
  6. package/dist/assembly/directional-shadow-inspection.d.ts +38 -0
  7. package/dist/assembly/directional-shadow-inspection.d.ts.map +1 -0
  8. package/dist/assembly/factory.d.ts +30 -19
  9. package/dist/assembly/factory.d.ts.map +1 -1
  10. package/dist/assembly/host-contract.d.ts +19 -0
  11. package/dist/assembly/host-contract.d.ts.map +1 -1
  12. package/dist/assembly/render-target-host.d.ts +46 -0
  13. package/dist/assembly/render-target-host.d.ts.map +1 -0
  14. package/dist/assets/render-asset-port.d.ts.map +1 -1
  15. package/dist/authoring.mjs +4 -1
  16. package/dist/authoring.mjs.map +1 -1
  17. package/dist/capture/cube-views.d.ts +21 -0
  18. package/dist/capture/cube-views.d.ts.map +1 -0
  19. package/dist/capture/scheduler.d.ts +54 -0
  20. package/dist/capture/scheduler.d.ts.map +1 -0
  21. package/dist/{chunk-PCHBPYML.mjs → chunk-4L3P6DT5.mjs} +2 -2
  22. package/dist/chunk-4L3P6DT5.mjs.map +1 -0
  23. package/dist/{chunk-VFPLTKCU.mjs → chunk-4NPUASZR.mjs} +15 -4
  24. package/dist/chunk-4NPUASZR.mjs.map +1 -0
  25. package/dist/chunk-DIYW3M5D.mjs +5085 -0
  26. package/dist/chunk-DIYW3M5D.mjs.map +1 -0
  27. package/dist/chunk-FBC4R44J.mjs +1003 -0
  28. package/dist/chunk-FBC4R44J.mjs.map +1 -0
  29. package/dist/{chunk-CDTWTHZR.mjs → chunk-FF7K3FSO.mjs} +474 -168
  30. package/dist/chunk-FF7K3FSO.mjs.map +1 -0
  31. package/dist/chunk-HZUPSYW7.mjs +1104 -0
  32. package/dist/chunk-HZUPSYW7.mjs.map +1 -0
  33. package/dist/{chunk-TBQJOK2L.mjs → chunk-QODA5UKU.mjs} +321 -269
  34. package/dist/chunk-QODA5UKU.mjs.map +1 -0
  35. package/dist/chunk-YALPS44A.mjs +296 -0
  36. package/dist/chunk-YALPS44A.mjs.map +1 -0
  37. package/dist/{chunk-4XINDLAY.mjs → chunk-ZUWKAZ2I.mjs} +1963 -2178
  38. package/dist/chunk-ZUWKAZ2I.mjs.map +1 -0
  39. package/dist/cluster-binner.d.ts +5 -0
  40. package/dist/cluster-binner.d.ts.map +1 -1
  41. package/dist/components/camera.d.ts +1 -0
  42. package/dist/components/camera.d.ts.map +1 -1
  43. package/dist/components/cube-camera.d.ts +20 -0
  44. package/dist/components/cube-camera.d.ts.map +1 -0
  45. package/dist/components/directional-light.d.ts +11 -2
  46. package/dist/components/directional-light.d.ts.map +1 -1
  47. package/dist/components/directional-shadow-filter.d.ts +25 -0
  48. package/dist/components/directional-shadow-filter.d.ts.map +1 -0
  49. package/dist/components/index.d.ts +5 -0
  50. package/dist/components/index.d.ts.map +1 -1
  51. package/dist/components/light-helpers.d.ts +4 -0
  52. package/dist/components/light-helpers.d.ts.map +1 -1
  53. package/dist/components/light-probe.d.ts +9 -0
  54. package/dist/components/light-probe.d.ts.map +1 -0
  55. package/dist/components/rect-area-light.d.ts +12 -0
  56. package/dist/components/rect-area-light.d.ts.map +1 -0
  57. package/dist/components/reflection-probe.d.ts +17 -0
  58. package/dist/components/reflection-probe.d.ts.map +1 -0
  59. package/dist/components/scene-instance.d.ts +4 -0
  60. package/dist/components/scene-instance.d.ts.map +1 -1
  61. package/dist/components/spot-light.d.ts +3 -0
  62. package/dist/components/spot-light.d.ts.map +1 -1
  63. package/dist/construct-renderer.mjs +14836 -9620
  64. package/dist/construct-renderer.mjs.map +1 -1
  65. package/dist/device/gpu-residency.d.ts +8 -1
  66. package/dist/device/gpu-residency.d.ts.map +1 -1
  67. package/dist/device/lifecycle-transaction.d.ts +2 -0
  68. package/dist/device/lifecycle-transaction.d.ts.map +1 -0
  69. package/dist/environment/frame.d.ts.map +1 -1
  70. package/dist/environment/lifecycle.d.ts +5 -0
  71. package/dist/environment/lifecycle.d.ts.map +1 -1
  72. package/dist/errors/gpu-driven.d.ts +26 -0
  73. package/dist/errors/gpu-driven.d.ts.map +1 -0
  74. package/dist/errors/index.d.ts +1 -0
  75. package/dist/errors/index.d.ts.map +1 -1
  76. package/dist/errors/recover.d.ts +9 -1
  77. package/dist/errors/recover.d.ts.map +1 -1
  78. package/dist/errors/render.d.ts +166 -93
  79. package/dist/errors/render.d.ts.map +1 -1
  80. package/dist/extract/directional-shadow-projection.d.ts +23 -0
  81. package/dist/extract/directional-shadow-projection.d.ts.map +1 -0
  82. package/dist/extract/environment.d.ts +14 -0
  83. package/dist/extract/environment.d.ts.map +1 -1
  84. package/dist/extract/gpu-driven.d.ts +50 -0
  85. package/dist/extract/gpu-driven.d.ts.map +1 -0
  86. package/dist/extract/visibility.d.ts.map +1 -1
  87. package/dist/features/fullscreen.d.ts.map +1 -1
  88. package/dist/features/targets.d.ts.map +1 -1
  89. package/dist/features/types.d.ts +10 -0
  90. package/dist/features/types.d.ts.map +1 -1
  91. package/dist/fullscreen-post-process-pass.d.ts +13 -2
  92. package/dist/fullscreen-post-process-pass.d.ts.map +1 -1
  93. package/dist/gpu-driven/batch-topology.d.ts +34 -0
  94. package/dist/gpu-driven/batch-topology.d.ts.map +1 -1
  95. package/dist/gpu-driven/prepared-draw.d.ts +63 -0
  96. package/dist/gpu-driven/prepared-draw.d.ts.map +1 -0
  97. package/dist/gpu-driven/production-raster.d.ts +97 -2
  98. package/dist/gpu-driven/production-raster.d.ts.map +1 -1
  99. package/dist/gpu-driven/view-gpu.d.ts +64 -1
  100. package/dist/gpu-driven/view-gpu.d.ts.map +1 -1
  101. package/dist/gpu-scene-schema.d.ts +14 -0
  102. package/dist/gpu-scene-schema.d.ts.map +1 -1
  103. package/dist/gpu-scene.d.ts +8 -1
  104. package/dist/gpu-scene.d.ts.map +1 -1
  105. package/dist/gpu-usage.d.ts +0 -1
  106. package/dist/gpu-usage.d.ts.map +1 -1
  107. package/dist/hdrp-buffers.d.ts +21 -19
  108. package/dist/hdrp-buffers.d.ts.map +1 -1
  109. package/dist/ibl/IblPipelineCache.d.ts +4 -0
  110. package/dist/ibl/IblPipelineCache.d.ts.map +1 -1
  111. package/dist/ibl/kernel-cache.d.ts +36 -0
  112. package/dist/ibl/kernel-cache.d.ts.map +1 -0
  113. package/dist/index.d.ts +39 -3
  114. package/dist/index.d.ts.map +1 -1
  115. package/dist/index.mjs +91 -6
  116. package/dist/index.mjs.map +1 -1
  117. package/dist/inspection-types.d.ts +214 -1
  118. package/dist/inspection-types.d.ts.map +1 -1
  119. package/dist/instances-derived-bounds.d.ts +50 -0
  120. package/dist/instances-derived-bounds.d.ts.map +1 -0
  121. package/dist/internal.d.ts +9 -0
  122. package/dist/internal.d.ts.map +1 -1
  123. package/dist/internal.mjs +23 -2
  124. package/dist/internal.mjs.map +1 -1
  125. package/dist/light-buffer-layout.d.ts +58 -140
  126. package/dist/light-buffer-layout.d.ts.map +1 -1
  127. package/dist/materials.d.ts.map +1 -1
  128. package/dist/mesh-material-bindings.d.ts +54 -0
  129. package/dist/mesh-material-bindings.d.ts.map +1 -1
  130. package/dist/pbr-pipeline.d.ts +38 -14
  131. package/dist/pbr-pipeline.d.ts.map +1 -1
  132. package/dist/pipeline/standard-forward-lane.d.ts +2 -1
  133. package/dist/pipeline/standard-forward-lane.d.ts.map +1 -1
  134. package/dist/pipeline/standard-lighting/errors.d.ts +4 -0
  135. package/dist/pipeline/standard-lighting/errors.d.ts.map +1 -0
  136. package/dist/pipeline/standard-lighting/graph.d.ts +24 -0
  137. package/dist/pipeline/standard-lighting/graph.d.ts.map +1 -0
  138. package/dist/pipeline/standard-lighting/inspection.d.ts +38 -0
  139. package/dist/pipeline/standard-lighting/inspection.d.ts.map +1 -0
  140. package/dist/pipeline/standard-lighting/layout.d.ts +28 -0
  141. package/dist/pipeline/standard-lighting/layout.d.ts.map +1 -0
  142. package/dist/pipeline/standard-lighting/light-frame.d.ts +33 -0
  143. package/dist/pipeline/standard-lighting/light-frame.d.ts.map +1 -0
  144. package/dist/pipeline/standard-lighting/membership.d.ts +14 -0
  145. package/dist/pipeline/standard-lighting/membership.d.ts.map +1 -0
  146. package/dist/pipeline/standard-lighting/prepare.d.ts +16 -0
  147. package/dist/pipeline/standard-lighting/prepare.d.ts.map +1 -0
  148. package/dist/pipeline/standard-lighting/topology.d.ts +45 -0
  149. package/dist/pipeline/standard-lighting/topology.d.ts.map +1 -0
  150. package/dist/pipeline/standard-lighting/transport.d.ts +36 -0
  151. package/dist/pipeline/standard-lighting/transport.d.ts.map +1 -0
  152. package/dist/pipeline/standard-pipeline.d.ts +4 -13
  153. package/dist/pipeline/standard-pipeline.d.ts.map +1 -1
  154. package/dist/pipeline/standard-post.d.ts.map +1 -1
  155. package/dist/pipeline/standard-profile.d.ts +5 -26
  156. package/dist/pipeline/standard-profile.d.ts.map +1 -1
  157. package/dist/pipeline-builder.d.ts +2 -0
  158. package/dist/pipeline-builder.d.ts.map +1 -1
  159. package/dist/pipeline-spec.d.ts +40 -7
  160. package/dist/pipeline-spec.d.ts.map +1 -1
  161. package/dist/plugin.d.ts.map +1 -1
  162. package/dist/point-shadow-inspection.d.ts +21 -0
  163. package/dist/point-shadow-inspection.d.ts.map +1 -0
  164. package/dist/prepare/extended-lighting/ltc-resources.d.ts +31 -0
  165. package/dist/prepare/extended-lighting/ltc-resources.d.ts.map +1 -0
  166. package/dist/prepare/extended-lighting/resources.d.ts +72 -0
  167. package/dist/prepare/extended-lighting/resources.d.ts.map +1 -0
  168. package/dist/prepare/extended-lighting/spot-modifiers.d.ts +42 -0
  169. package/dist/prepare/extended-lighting/spot-modifiers.d.ts.map +1 -0
  170. package/dist/prepare/extended-lighting/state.d.ts +24 -0
  171. package/dist/prepare/extended-lighting/state.d.ts.map +1 -0
  172. package/dist/record/frame-lighting.d.ts +33 -36
  173. package/dist/record/frame-lighting.d.ts.map +1 -1
  174. package/dist/record/frame-snapshot.d.ts +78 -24
  175. package/dist/record/frame-snapshot.d.ts.map +1 -1
  176. package/dist/record/frame-targets.d.ts +5 -0
  177. package/dist/record/frame-targets.d.ts.map +1 -1
  178. package/dist/record/frame.d.ts +16 -6
  179. package/dist/record/frame.d.ts.map +1 -1
  180. package/dist/record/gpu-pass-timing/contract.d.ts +96 -0
  181. package/dist/record/gpu-pass-timing/contract.d.ts.map +1 -0
  182. package/dist/record/gpu-pass-timing/errors.d.ts +18 -0
  183. package/dist/record/gpu-pass-timing/errors.d.ts.map +1 -0
  184. package/dist/record/gpu-pass-timing/index.d.ts +8 -0
  185. package/dist/record/gpu-pass-timing/index.d.ts.map +1 -0
  186. package/dist/record/gpu-pass-timing/parser.d.ts +11 -0
  187. package/dist/record/gpu-pass-timing/parser.d.ts.map +1 -0
  188. package/dist/record/gpu-pass-timing/session.d.ts +43 -0
  189. package/dist/record/gpu-pass-timing/session.d.ts.map +1 -0
  190. package/dist/record/gpu-timing.d.ts +20 -3
  191. package/dist/record/gpu-timing.d.ts.map +1 -1
  192. package/dist/record/helpers.d.ts +0 -20
  193. package/dist/record/helpers.d.ts.map +1 -1
  194. package/dist/record/main-pass-geometry.d.ts +6 -1
  195. package/dist/record/main-pass-geometry.d.ts.map +1 -1
  196. package/dist/record/main-pass-material.d.ts +25 -2
  197. package/dist/record/main-pass-material.d.ts.map +1 -1
  198. package/dist/record/main-pass-sprite-draws.d.ts.map +1 -1
  199. package/dist/record/main-pass.d.ts +2 -0
  200. package/dist/record/main-pass.d.ts.map +1 -1
  201. package/dist/record/mesh-ssbo.d.ts.map +1 -1
  202. package/dist/record/render-context.d.ts +98 -6
  203. package/dist/record/render-context.d.ts.map +1 -1
  204. package/dist/record/shadow-pass.d.ts.map +1 -1
  205. package/dist/record/skybox-post-pass.d.ts.map +1 -1
  206. package/dist/record/typed-frame-graph.d.ts +119 -4
  207. package/dist/record/typed-frame-graph.d.ts.map +1 -1
  208. package/dist/record/view-ubo.d.ts +7 -5
  209. package/dist/record/view-ubo.d.ts.map +1 -1
  210. package/dist/reflection/filter.d.ts +22 -0
  211. package/dist/reflection/filter.d.ts.map +1 -0
  212. package/dist/reflection/gpu-table.d.ts +25 -0
  213. package/dist/reflection/gpu-table.d.ts.map +1 -0
  214. package/dist/reflection/inspection.d.ts +10 -0
  215. package/dist/reflection/inspection.d.ts.map +1 -0
  216. package/dist/reflection/projection.d.ts +140 -0
  217. package/dist/reflection/projection.d.ts.map +1 -0
  218. package/dist/reflection/record-owner.d.ts +60 -0
  219. package/dist/reflection/record-owner.d.ts.map +1 -0
  220. package/dist/render-contract.d.ts +62 -14
  221. package/dist/render-contract.d.ts.map +1 -1
  222. package/dist/render-graph-primitives.d.ts +1 -0
  223. package/dist/render-graph-primitives.d.ts.map +1 -1
  224. package/dist/render-pipeline.d.ts +49 -2
  225. package/dist/render-pipeline.d.ts.map +1 -1
  226. package/dist/render-system-extract.d.ts +160 -31
  227. package/dist/render-system-extract.d.ts.map +1 -1
  228. package/dist/render-system.d.ts +28 -2
  229. package/dist/render-system.d.ts.map +1 -1
  230. package/dist/renderer.d.ts +43 -0
  231. package/dist/renderer.d.ts.map +1 -0
  232. package/dist/scene/probe-blend-record.d.ts +22 -0
  233. package/dist/scene/probe-blend-record.d.ts.map +1 -0
  234. package/dist/scene/probe-blend.d.ts +142 -0
  235. package/dist/scene/probe-blend.d.ts.map +1 -0
  236. package/dist/scene/render-scene-types.d.ts +0 -6
  237. package/dist/scene/render-scene-types.d.ts.map +1 -1
  238. package/dist/scene/render-scene.d.ts +117 -9
  239. package/dist/scene/render-scene.d.ts.map +1 -1
  240. package/dist/scene/visibility/bounds.d.ts +20 -0
  241. package/dist/scene/visibility/bounds.d.ts.map +1 -0
  242. package/dist/scene/visibility/budget.d.ts +16 -0
  243. package/dist/scene/visibility/budget.d.ts.map +1 -0
  244. package/dist/scene/visibility/facet.d.ts +73 -0
  245. package/dist/scene/visibility/facet.d.ts.map +1 -0
  246. package/dist/scene/visibility/gpu-frame-timing.d.ts +41 -0
  247. package/dist/scene/visibility/gpu-frame-timing.d.ts.map +1 -0
  248. package/dist/scene/visibility/gpu-lod.d.ts +46 -0
  249. package/dist/scene/visibility/gpu-lod.d.ts.map +1 -0
  250. package/dist/scene/visibility/inspection.d.ts +132 -0
  251. package/dist/scene/visibility/inspection.d.ts.map +1 -0
  252. package/dist/scene/visibility/lod-selector.d.ts +25 -0
  253. package/dist/scene/visibility/lod-selector.d.ts.map +1 -0
  254. package/dist/scene/visibility/occlusion-confidence.d.ts +81 -0
  255. package/dist/scene/visibility/occlusion-confidence.d.ts.map +1 -0
  256. package/dist/scene/visibility/occlusion-pass.d.ts +57 -0
  257. package/dist/scene/visibility/occlusion-pass.d.ts.map +1 -0
  258. package/dist/scene/visibility/occlusion-query-pool.d.ts +57 -0
  259. package/dist/scene/visibility/occlusion-query-pool.d.ts.map +1 -0
  260. package/dist/scene/visibility/occlusion-runtime.d.ts +96 -0
  261. package/dist/scene/visibility/occlusion-runtime.d.ts.map +1 -0
  262. package/dist/scene/visibility/types.d.ts +34 -0
  263. package/dist/scene/visibility/types.d.ts.map +1 -0
  264. package/dist/shadow-atlas.d.ts +3 -3
  265. package/dist/shadow-atlas.d.ts.map +1 -1
  266. package/dist/ssao-buffers.d.ts +3 -0
  267. package/dist/ssao-buffers.d.ts.map +1 -1
  268. package/dist/ssr/admission.d.ts +122 -0
  269. package/dist/ssr/admission.d.ts.map +1 -0
  270. package/dist/ssr/composition.d.ts +32 -0
  271. package/dist/ssr/composition.d.ts.map +1 -0
  272. package/dist/ssr/errors.d.ts +39 -0
  273. package/dist/ssr/errors.d.ts.map +1 -0
  274. package/dist/ssr/identity.d.ts +13 -0
  275. package/dist/ssr/identity.d.ts.map +1 -0
  276. package/dist/systems/skin-palette-allocator.d.ts +1 -1
  277. package/dist/targets/contracts.d.ts +66 -0
  278. package/dist/targets/contracts.d.ts.map +1 -0
  279. package/dist/targets/graph-projection.d.ts +29 -0
  280. package/dist/targets/graph-projection.d.ts.map +1 -0
  281. package/dist/targets/material-source.d.ts +34 -0
  282. package/dist/targets/material-source.d.ts.map +1 -0
  283. package/dist/targets/owner.d.ts +32 -0
  284. package/dist/targets/owner.d.ts.map +1 -0
  285. package/dist/targets/physical.d.ts +18 -0
  286. package/dist/targets/physical.d.ts.map +1 -0
  287. package/dist/targets/readback.d.ts +39 -0
  288. package/dist/targets/readback.d.ts.map +1 -0
  289. package/dist/temporal/frame-coordinator.d.ts +13 -0
  290. package/dist/temporal/frame-coordinator.d.ts.map +1 -1
  291. package/dist/temporal/frame.d.ts +2 -0
  292. package/dist/temporal/frame.d.ts.map +1 -1
  293. package/dist/temporal/index.mjs +6 -5
  294. package/dist/temporal/view.d.ts +7 -0
  295. package/dist/temporal/view.d.ts.map +1 -1
  296. package/dist/tilemap-chunk-extract-system.d.ts +1 -1
  297. package/dist/typed-render-graph-primitives.d.ts +5 -1
  298. package/dist/typed-render-graph-primitives.d.ts.map +1 -1
  299. package/dist/typed-shadow-passes.d.ts +1 -1
  300. package/dist/typed-shadow-passes.d.ts.map +1 -1
  301. package/dist/volume/passes.d.ts +9 -5
  302. package/dist/volume/passes.d.ts.map +1 -1
  303. package/package.json +20 -20
  304. package/src/__tests__/bloom-exact-zero.unit.test.ts +48 -19
  305. package/src/__tests__/bloom-lifecycle.integration.test.ts +41 -13
  306. package/src/__tests__/camera-target-consumption.unit.test.ts +53 -0
  307. package/src/__tests__/cluster-binner.unit.test.ts +35 -0
  308. package/src/__tests__/cluster-grid-default-surface.unit.test.ts +12 -2
  309. package/src/__tests__/cube-camera-scheduler.unit.test.ts +70 -0
  310. package/src/__tests__/cube-camera-single-submit.perf.test.ts +75 -0
  311. package/src/__tests__/cube-camera-view-matrices.unit.test.ts +41 -0
  312. package/src/__tests__/cube-camera-vocabulary.unit.test.ts +47 -0
  313. package/src/__tests__/cube-camera.integration.test.ts +42 -0
  314. package/src/__tests__/detached-inspection.integration.test.ts +6 -0
  315. package/src/__tests__/device-feature-admission.unit.test.ts +85 -0
  316. package/src/__tests__/direct-light-snapshot.unit.test.ts +62 -6
  317. package/src/__tests__/docs-gate-green.unit.test.ts +38 -0
  318. package/src/__tests__/environment-generation.integration.test.ts +16 -0
  319. package/src/__tests__/evidence-identity.ts +13 -0
  320. package/src/__tests__/evidence-identity.unit.test.ts +24 -0
  321. package/src/__tests__/extended-lighting-recovery.browser.test.ts +14 -0
  322. package/src/__tests__/extended-lighting-recovery.dawn.test.ts +14 -0
  323. package/src/__tests__/extended-lighting-recovery.integration.test.ts +81 -0
  324. package/src/__tests__/extended-lighting-resources.unit.test.ts +51 -0
  325. package/src/__tests__/extended-lighting-zero-feature.integration.test.ts +52 -0
  326. package/src/__tests__/factory-contract.integration.test.ts +288 -29
  327. package/src/__tests__/fog-component.unit.test.ts +67 -0
  328. package/src/__tests__/fog.integration.test.ts +86 -0
  329. package/src/__tests__/frame-observation.contract.test.ts +15 -0
  330. package/src/__tests__/fullscreen-feature-plan.unit.test.ts +37 -0
  331. package/src/__tests__/gpu-driven-batch-topology-pbr.unit.test.ts +146 -0
  332. package/src/__tests__/gpu-driven-indirect-raster-evidence.ts +10 -8
  333. package/src/__tests__/gpu-driven-indirect-raster.dawn.test.ts +18 -1
  334. package/src/__tests__/gpu-driven-production.integration.test.ts +579 -17
  335. package/src/__tests__/gpu-driven-scaling.unit.test.ts +66 -2
  336. package/src/__tests__/gpu-driven-view-gpu-evidence.ts +26 -1
  337. package/src/__tests__/gpu-driven-view-graph.integration.test.ts +101 -6
  338. package/src/__tests__/gpu-driven-view.browser.test.ts +3 -3
  339. package/src/__tests__/gpu-driven-view.dawn.test.ts +3 -3
  340. package/src/__tests__/gpu-driven-view.unit.test.ts +50 -0
  341. package/src/__tests__/gpu-lod-evidence.ts +188 -0
  342. package/src/__tests__/gpu-lod-fallback.integration.test.ts +10 -0
  343. package/src/__tests__/gpu-lod-indirect.integration.test.ts +40 -0
  344. package/src/__tests__/gpu-lod-parity.dawn.test.ts +29 -0
  345. package/src/__tests__/gpu-lod-readiness.integration.test.ts +52 -0
  346. package/src/__tests__/gpu-lod-schema.unit.test.ts +66 -0
  347. package/src/__tests__/gpu-lod-selector.unit.test.ts +28 -0
  348. package/src/__tests__/gpu-lod-silhouette.browser.test.ts +13 -0
  349. package/src/__tests__/gpu-pass-timing-browser-runner.ts +281 -0
  350. package/src/__tests__/gpu-pass-timing-coexistence.integration.test.ts +80 -0
  351. package/src/__tests__/gpu-pass-timing-contract.unit.test.ts +243 -0
  352. package/src/__tests__/gpu-pass-timing-exact-zero.unit.test.ts +131 -0
  353. package/src/__tests__/gpu-pass-timing-lifecycle.integration.test.ts +230 -0
  354. package/src/__tests__/gpu-pass-timing-observation.unit.test.ts +233 -0
  355. package/src/__tests__/gpu-pass-timing-session.unit.test.ts +438 -0
  356. package/src/__tests__/gpu-pass-timing.browser.test.ts +26 -0
  357. package/src/__tests__/gpu-pass-timing.rhi-null.unit.test.ts +125 -0
  358. package/src/__tests__/gpu-resource-store-stride.unit.test.ts +66 -1
  359. package/src/__tests__/gpu-scene.dawn.test.ts +8 -1
  360. package/src/__tests__/gpu-scene.unit.test.ts +49 -3
  361. package/src/__tests__/hdrp-group2-visibility.unit.test.ts +24 -0
  362. package/src/__tests__/instances-culling.integration.test.ts +94 -0
  363. package/src/__tests__/instances-derived-bounds.unit.test.ts +118 -0
  364. package/src/__tests__/light-buffer-layout.unit.test.ts +113 -3
  365. package/src/__tests__/light-inspection.unit.test.ts +55 -0
  366. package/src/__tests__/light-resource-error.unit.test.ts +43 -0
  367. package/src/__tests__/lighting-scene-roundtrip.integration.test.ts +109 -0
  368. package/src/__tests__/lod-bounds.unit.test.ts +42 -0
  369. package/src/__tests__/lod-cpu-lane.integration.test.ts +55 -0
  370. package/src/__tests__/lod-cpu-no-change.perf.test.ts +19 -0
  371. package/src/__tests__/lod-gpu-frame-timing.unit.test.ts +49 -0
  372. package/src/__tests__/lod-multi-view.integration.test.ts +63 -0
  373. package/src/__tests__/lod-occlusion-device-loss.integration.test.ts +27 -0
  374. package/src/__tests__/lod-occlusion-final-decision.integration.test.ts +47 -0
  375. package/src/__tests__/lod-occlusion-inspection.integration.test.ts +217 -0
  376. package/src/__tests__/lod-occlusion-inspection.schema.test-d.ts +14 -0
  377. package/src/__tests__/lod-occlusion-inspection.unit.test.ts +72 -0
  378. package/src/__tests__/lod-occlusion-visual-evidence.ts +91 -0
  379. package/src/__tests__/lod-occlusion.browser.test.ts +15 -0
  380. package/src/__tests__/lod-occlusion.dawn.test.ts +20 -0
  381. package/src/__tests__/lod-selector.profile.test.ts +35 -0
  382. package/src/__tests__/lod-selector.unit.test.ts +68 -0
  383. package/src/__tests__/lod-visibility-identity.unit.test.ts +198 -0
  384. package/src/__tests__/lod-visibility-lifecycle.integration.test.ts +132 -0
  385. package/src/__tests__/ltc-resources.unit.test.ts +32 -0
  386. package/src/__tests__/material-contract-inventory.unit.test.ts +17 -0
  387. package/src/__tests__/material-observation.integration.test.ts +101 -0
  388. package/src/__tests__/occlusion-confidence.unit.test.ts +168 -0
  389. package/src/__tests__/occlusion-invalidation.integration.test.ts +37 -0
  390. package/src/__tests__/occlusion-pass-routing.unit.test.ts +16 -0
  391. package/src/__tests__/occlusion-pass.dawn.test.ts +20 -0
  392. package/src/__tests__/occlusion-pass.integration.test.ts +43 -0
  393. package/src/__tests__/occlusion-pass.rhi-null.test.ts +22 -0
  394. package/src/__tests__/occlusion-query-pool.rhi-null.test.ts +21 -0
  395. package/src/__tests__/occlusion-query-pool.unit.test.ts +95 -0
  396. package/src/__tests__/occlusion-query-ticket.integration.test.ts +47 -0
  397. package/src/__tests__/occlusion-query.dawn.test.ts +16 -0
  398. package/src/__tests__/occlusion-query.evidence.ts +178 -0
  399. package/src/__tests__/occlusion-query.rhi-null.test.ts +31 -0
  400. package/src/__tests__/occlusion-runtime.unit.test.ts +120 -0
  401. package/src/__tests__/pbr-view-layout.unit.test.ts +16 -0
  402. package/src/__tests__/point-shadow-inspection.unit.test.ts +60 -0
  403. package/src/__tests__/prepared-gpu-driven-pbr.integration.test.ts +196 -0
  404. package/src/__tests__/probe-bindings.unit.test.ts +200 -0
  405. package/src/__tests__/probe-blend-numeric.unit.test.ts +67 -0
  406. package/src/__tests__/probe-blend-oracle.unit.test.ts +136 -0
  407. package/src/__tests__/probe-capacity.integration.test.ts +97 -0
  408. package/src/__tests__/probe-recovery.integration.test.ts +104 -0
  409. package/src/__tests__/probe-scene-dirty.integration.test.ts +211 -0
  410. package/src/__tests__/profiler-phase-catalog.test.ts +4 -1
  411. package/src/__tests__/profiler-phase-token.test.ts +1 -0
  412. package/src/__tests__/public-surface.test-d.ts +10 -0
  413. package/src/__tests__/rect-area-boundary.unit.test.ts +24 -0
  414. package/src/__tests__/reflection-fallback-graph.unit.test.ts +67 -0
  415. package/src/__tests__/reflection-fallback-inspection.unit.test.ts +77 -0
  416. package/src/__tests__/reflection-fallback-lifecycle.integration.test.ts +21 -0
  417. package/src/__tests__/reflection-fallback-projection.unit.test.ts +90 -0
  418. package/src/__tests__/reflection-fallback-source.unit.test.ts +32 -0
  419. package/src/__tests__/reflection-probe-authoring.unit.test.ts +71 -0
  420. package/src/__tests__/reflection-probe-filter.unit.test.ts +54 -0
  421. package/src/__tests__/reflection-probe-ibl-topology.unit.test.ts +45 -0
  422. package/src/__tests__/reflection-probe-owner-placement.unit.test.ts +39 -0
  423. package/src/__tests__/reflection-probe-pass-encode.integration.test.ts +101 -0
  424. package/src/__tests__/reflection-probe-performance.perf.test.ts +60 -0
  425. package/src/__tests__/reflection-probe-record-owner.characterization.unit.test.ts +120 -0
  426. package/src/__tests__/reflection-probe-recovery.integration.test.ts +55 -0
  427. package/src/__tests__/reflection-probe-selection.unit.test.ts +46 -0
  428. package/src/__tests__/render-error-code-owner.test-d.ts +19 -3
  429. package/src/__tests__/render-feature-docs.unit.test.ts +12 -7
  430. package/src/__tests__/render-graph-fallback.integration.test.ts +24 -0
  431. package/src/__tests__/render-perf/extended-lighting.bench.test.ts +66 -0
  432. package/src/__tests__/render-scene-projection.unit.test.ts +447 -18
  433. package/src/__tests__/render-target-admission.unit.test.ts +80 -0
  434. package/src/__tests__/render-target-graph-projection.unit.test.ts +102 -0
  435. package/src/__tests__/render-target-inspection.unit.test.ts +52 -0
  436. package/src/__tests__/render-target-material-source.test-d.ts +30 -0
  437. package/src/__tests__/render-target-material-source.unit.test.ts +97 -0
  438. package/src/__tests__/render-target-owner-placement.unit.test.ts +203 -0
  439. package/src/__tests__/render-target-owner.unit.test.ts +122 -0
  440. package/src/__tests__/render-target-probe-soak.perf.test.ts +94 -0
  441. package/src/__tests__/render-target-public-schema.json +107 -0
  442. package/src/__tests__/render-target-public-schema.unit.test.ts +91 -0
  443. package/src/__tests__/render-target-public-surface.test-d.ts +83 -0
  444. package/src/__tests__/render-target-readback.integration.test.ts +90 -0
  445. package/src/__tests__/render-target-recovery.integration.test.ts +85 -0
  446. package/src/__tests__/renderer-factory-material-contract.unit.test.ts +124 -0
  447. package/src/__tests__/renderer-lifecycle.integration.test.ts +14 -0
  448. package/src/__tests__/shader-stage-surface.unit.test.ts +19 -4
  449. package/src/__tests__/skin-motion-regression.unit.test.ts +154 -0
  450. package/src/__tests__/skinned-shadow-caster.test.ts +13 -4
  451. package/src/__tests__/spot-modifier-projection.unit.test.ts +70 -0
  452. package/src/__tests__/ssr-admission-matrix.integration.test.ts +206 -0
  453. package/src/__tests__/ssr-composition.unit.test.ts +46 -0
  454. package/src/__tests__/ssr-fallback-zero-work.bench.test.ts +94 -0
  455. package/src/__tests__/ssr-recovery-errors.unit.test.ts +58 -0
  456. package/src/__tests__/standard-cluster-capability.integration.test.ts +63 -0
  457. package/src/__tests__/standard-cluster-transport.unit.test.ts +121 -0
  458. package/src/__tests__/standard-cluster-variant-resolution.unit.test.ts +299 -0
  459. package/src/__tests__/standard-clustered-pipeline.unit.test.ts +15 -5
  460. package/src/__tests__/standard-lighting-inspection.integration.test.ts +138 -0
  461. package/src/__tests__/standard-lighting-ssot.unit.test.ts +18 -0
  462. package/src/__tests__/standard-lighting-write.unit.test.ts +441 -0
  463. package/src/__tests__/standard-lighting.integration.test.ts +67 -0
  464. package/src/__tests__/standard-pipeline.dawn.test.ts +206 -5
  465. package/src/__tests__/standard-pipeline.integration.test.ts +181 -150
  466. package/src/__tests__/standard-probe-binding.unit.test.ts +25 -0
  467. package/src/__tests__/standard-profile-oracle.unit.test.ts +23 -38
  468. package/src/__tests__/temporal-fallback-generation.integration.test.ts +16 -0
  469. package/src/__tests__/temporal-view.unit.test.ts +3 -3
  470. package/src/__tests__/transmission-prewarm.unit.test.ts +69 -0
  471. package/src/__tests__/typed-pipeline-topology.unit.test.ts +395 -14
  472. package/src/__tests__/urp-pipeline-targets.unit.test.ts +2 -2
  473. package/src/__tests__/visibility-budget.integration.test.ts +140 -0
  474. package/src/__tests__/visibility-budget.unit.test.ts +70 -0
  475. package/src/__tests__/visibility-extract.integration.test.ts +11 -6
  476. package/src/__tests__/visibility-resolver.unit.test.ts +15 -0
  477. package/src/__tests__/volumetric-fog-point-spot-accumulation.integration.test.ts +6 -3
  478. package/src/__tests__/volumetric-fog-stage-readback.dawn.test.ts +31 -28
  479. package/src/assembly/backend-contract.ts +13 -0
  480. package/src/assembly/device-feature-admission.ts +80 -0
  481. package/src/assembly/directional-shadow-inspection.ts +122 -0
  482. package/src/assembly/factory.ts +1411 -366
  483. package/src/assembly/host-contract.ts +35 -0
  484. package/src/assembly/render-target-host.ts +847 -0
  485. package/src/assets/asset-decoders.ts +1 -1
  486. package/src/assets/render-asset-port.ts +7 -1
  487. package/src/capture/cube-views.ts +69 -0
  488. package/src/capture/scheduler.ts +265 -0
  489. package/src/cluster-binner.ts +31 -0
  490. package/src/components/__tests__/lighting-authoring.unit.test.ts +39 -0
  491. package/src/components/__tests__/rect-area-light.unit.test.ts +33 -0
  492. package/src/components/__tests__/schema-contract.unit.test.ts +12 -0
  493. package/src/components/__tests__/schema-parity.unit.test.ts +9 -0
  494. package/src/components/camera.ts +4 -0
  495. package/src/components/cube-camera.ts +52 -0
  496. package/src/components/directional-light.ts +22 -2
  497. package/src/components/directional-shadow-filter.ts +57 -0
  498. package/src/components/index.ts +5 -0
  499. package/src/components/light-helpers.ts +133 -8
  500. package/src/components/light-probe.ts +13 -0
  501. package/src/components/rect-area-light.ts +15 -0
  502. package/src/components/reflection-probe.ts +49 -0
  503. package/src/components/scene-instance.ts +6 -0
  504. package/src/components/spot-light.ts +3 -0
  505. package/src/device/__tests__/extended-lighting-recovery.unit.test.ts +24 -0
  506. package/src/device/gpu-residency.ts +140 -9
  507. package/src/device/lifecycle-transaction.ts +12 -0
  508. package/src/environment/frame.ts +6 -24
  509. package/src/environment/lifecycle.ts +20 -1
  510. package/src/errors/gpu-driven.ts +92 -0
  511. package/src/errors/index.ts +1 -0
  512. package/src/errors/recover.ts +32 -0
  513. package/src/errors/render.ts +341 -143
  514. package/src/extract/camera.ts +3 -3
  515. package/src/extract/directional-shadow-projection.ts +61 -0
  516. package/src/extract/environment.ts +57 -0
  517. package/src/extract/gpu-driven.ts +108 -0
  518. package/src/extract/visibility.ts +2 -1
  519. package/src/features/fullscreen.ts +3 -0
  520. package/src/features/targets.ts +4 -1
  521. package/src/features/types.ts +10 -0
  522. package/src/fullscreen-post-process-pass.ts +43 -2
  523. package/src/gpu-driven/batch-topology.ts +207 -28
  524. package/src/gpu-driven/prepared-draw.ts +208 -0
  525. package/src/gpu-driven/production-raster.ts +953 -43
  526. package/src/gpu-driven/view-gpu.ts +411 -29
  527. package/src/gpu-scene-schema.ts +13 -0
  528. package/src/gpu-scene.ts +140 -64
  529. package/src/gpu-usage.ts +0 -1
  530. package/src/hdrp-buffers.ts +169 -63
  531. package/src/ibl/IblPipelineCache.ts +11 -0
  532. package/src/ibl/kernel-cache.ts +88 -0
  533. package/src/index.ts +222 -0
  534. package/src/inspection-types.ts +276 -1
  535. package/src/instances-derived-bounds.ts +171 -0
  536. package/src/internal.ts +38 -0
  537. package/src/light-buffer-layout.ts +155 -310
  538. package/src/materials.ts +16 -2
  539. package/src/mesh-material-bindings.ts +132 -0
  540. package/src/pbr-pipeline.ts +255 -60
  541. package/src/pipeline/standard-forward-lane.ts +93 -16
  542. package/src/pipeline/standard-lighting/errors.ts +6 -0
  543. package/src/pipeline/standard-lighting/graph.ts +158 -0
  544. package/src/pipeline/standard-lighting/inspection.ts +88 -0
  545. package/src/pipeline/standard-lighting/layout.ts +31 -0
  546. package/src/pipeline/standard-lighting/light-frame.ts +35 -0
  547. package/src/pipeline/standard-lighting/membership.ts +43 -0
  548. package/src/pipeline/standard-lighting/prepare.ts +37 -0
  549. package/src/pipeline/standard-lighting/topology.ts +120 -0
  550. package/src/pipeline/standard-lighting/transport.ts +78 -0
  551. package/src/pipeline/standard-pipeline.ts +124 -193
  552. package/src/pipeline/standard-post.ts +26 -7
  553. package/src/pipeline/standard-profile.ts +17 -47
  554. package/src/pipeline-builder.ts +5 -2
  555. package/src/pipeline-spec.ts +95 -21
  556. package/src/plugin.ts +4 -0
  557. package/src/point-shadow-inspection.ts +55 -0
  558. package/src/prepare/__tests__/extended-lighting-capability.unit.test.ts +56 -0
  559. package/src/prepare/extended-lighting/ltc-resources.ts +136 -0
  560. package/src/prepare/extended-lighting/resources.ts +389 -0
  561. package/src/prepare/extended-lighting/spot-modifiers.ts +194 -0
  562. package/src/prepare/extended-lighting/state.ts +92 -0
  563. package/src/record/__tests__/gpu-timing.unit.test.ts +177 -0
  564. package/src/record/__tests__/temporal-payload.unit.test.ts +64 -1
  565. package/src/record/__tests__/transparent-group2-selection.unit.test.ts +73 -0
  566. package/src/record/__tests__/typed-frame-graph-plan.unit.test.ts +20 -1
  567. package/src/record/__tests__/view-ubo-layout.unit.test.ts +40 -0
  568. package/src/record/frame-lighting.ts +591 -452
  569. package/src/record/frame-snapshot.ts +92 -39
  570. package/src/record/frame-targets.ts +17 -0
  571. package/src/record/frame.ts +662 -158
  572. package/src/record/gpu-pass-timing/contract.ts +180 -0
  573. package/src/record/gpu-pass-timing/errors.ts +34 -0
  574. package/src/record/gpu-pass-timing/index.ts +37 -0
  575. package/src/record/gpu-pass-timing/parser.ts +97 -0
  576. package/src/record/gpu-pass-timing/session.ts +938 -0
  577. package/src/record/gpu-timing.ts +112 -39
  578. package/src/record/helpers.ts +0 -58
  579. package/src/record/main-pass-geometry.ts +324 -119
  580. package/src/record/main-pass-material.ts +103 -10
  581. package/src/record/main-pass-sprite-draws.ts +99 -103
  582. package/src/record/main-pass.ts +71 -15
  583. package/src/record/mesh-ssbo.ts +47 -36
  584. package/src/record/render-context.ts +136 -3
  585. package/src/record/shadow-pass.ts +83 -68
  586. package/src/record/skybox-post-pass.ts +20 -4
  587. package/src/record/typed-frame-graph.ts +1034 -43
  588. package/src/record/view-ubo.ts +72 -47
  589. package/src/reflection/filter.ts +81 -0
  590. package/src/reflection/gpu-table.ts +44 -0
  591. package/src/reflection/inspection.ts +67 -0
  592. package/src/reflection/projection.ts +476 -0
  593. package/src/reflection/record-owner.ts +1283 -0
  594. package/src/render-contract.ts +93 -10
  595. package/src/render-graph-primitives.ts +9 -4
  596. package/src/render-pipeline.ts +122 -2
  597. package/src/render-system-extract.ts +1041 -225
  598. package/src/render-system.ts +1310 -85
  599. package/src/renderer.ts +222 -0
  600. package/src/scene/__tests__/changed-block-summary.candidate.test.ts +36 -0
  601. package/src/scene/probe-blend-record.ts +54 -0
  602. package/src/scene/probe-blend.ts +813 -0
  603. package/src/scene/render-scene-types.ts +0 -7
  604. package/src/scene/render-scene.ts +942 -171
  605. package/src/scene/visibility/bounds.ts +57 -0
  606. package/src/scene/visibility/budget.ts +40 -0
  607. package/src/scene/visibility/facet.ts +400 -0
  608. package/src/scene/visibility/gpu-frame-timing.ts +101 -0
  609. package/src/scene/visibility/gpu-lod.ts +119 -0
  610. package/src/scene/visibility/inspection.ts +313 -0
  611. package/src/scene/visibility/lod-selector.ts +84 -0
  612. package/src/scene/visibility/occlusion-confidence.ts +478 -0
  613. package/src/scene/visibility/occlusion-pass.ts +165 -0
  614. package/src/scene/visibility/occlusion-query-pool.ts +178 -0
  615. package/src/scene/visibility/occlusion-runtime.ts +672 -0
  616. package/src/scene/visibility/types.ts +50 -0
  617. package/src/shadow-atlas.ts +5 -5
  618. package/src/ssao-buffers.ts +9 -2
  619. package/src/ssr/admission.ts +451 -0
  620. package/src/ssr/composition.ts +73 -0
  621. package/src/ssr/errors.ts +76 -0
  622. package/src/ssr/identity.ts +12 -0
  623. package/src/systems/skin-palette-allocator.ts +1 -1
  624. package/src/targets/contracts.ts +182 -0
  625. package/src/targets/graph-projection.ts +169 -0
  626. package/src/targets/material-source.ts +143 -0
  627. package/src/targets/owner.ts +214 -0
  628. package/src/targets/physical.ts +18 -0
  629. package/src/targets/readback.ts +153 -0
  630. package/src/temporal/frame-coordinator.ts +26 -0
  631. package/src/temporal/frame.ts +14 -1
  632. package/src/temporal/view.ts +11 -0
  633. package/src/tilemap-chunk-extract-system.ts +4 -4
  634. package/src/transmission/__tests__/standard-transmission.dawn.test.ts +59 -20
  635. package/src/typed-render-graph-primitives.ts +53 -3
  636. package/src/typed-shadow-passes.ts +46 -40
  637. package/src/volume/passes.ts +61 -58
  638. package/dist/.tsbuildinfo +0 -1
  639. package/dist/chunk-4XINDLAY.mjs.map +0 -1
  640. package/dist/chunk-CDTWTHZR.mjs.map +0 -1
  641. package/dist/chunk-M2MP4ZOU.mjs +0 -73
  642. package/dist/chunk-M2MP4ZOU.mjs.map +0 -1
  643. package/dist/chunk-PCHBPYML.mjs.map +0 -1
  644. package/dist/chunk-TBQJOK2L.mjs.map +0 -1
  645. package/dist/chunk-VFPLTKCU.mjs.map +0 -1
@@ -5,6 +5,11 @@ import type {
5
5
  } from '@forgeax/engine-render-graph';
6
6
  import { err, ok, type Result } from '@forgeax/engine-types';
7
7
  import { SceneDataUnavailableError } from '../errors/render';
8
+ import {
9
+ GPU_TEXTURE_USAGE_COPY_SRC,
10
+ GPU_TEXTURE_USAGE_RENDER_ATTACHMENT,
11
+ GPU_TEXTURE_USAGE_TEXTURE_BINDING,
12
+ } from '../gpu-texture-usage';
8
13
  import type {
9
14
  RenderPipeline,
10
15
  RenderPipelineBuildContext,
@@ -29,12 +34,19 @@ import {
29
34
  transmissionDemandForTopology,
30
35
  } from '../transmission/backdrop';
31
36
  import {
37
+ addReflectionFallbackObservationPass,
32
38
  addTypedFrameObservationPass,
33
39
  addTypedScenePass,
34
40
  addTypedSkyboxPass,
35
41
  } from '../typed-render-graph-primitives';
36
42
  import { addTypedShadowPasses } from '../typed-shadow-passes';
37
43
  import { addAuthoredVolumetricFogPasses } from '../volume/passes';
44
+ import {
45
+ addStandardClusterMembershipPass,
46
+ importStandardClusterBuffers,
47
+ standardClusterReadAccesses,
48
+ } from './standard-lighting/graph';
49
+ import type { StandardTopologyInputValue } from './standard-lighting/topology';
38
50
  import { addStandardPost } from './standard-post';
39
51
 
40
52
  function target(
@@ -48,6 +60,7 @@ function target(
48
60
  function buildUrp(
49
61
  context: RenderPipelineBuildContext<RenderPipelineFrame>,
50
62
  topology: RenderPipelineTopology,
63
+ lighting: StandardTopologyInputValue,
51
64
  ): ReturnType<RenderPipeline['build']> {
52
65
  const graph = context.graph;
53
66
  const surface = importRenderPipelineSurface(graph, topology);
@@ -60,16 +73,14 @@ function buildUrp(
60
73
  const fxaa = !clearOnly && topology.camera.antialias === 'fxaa';
61
74
  const taa = !clearOnly && topology.camera.antialias === 'taa';
62
75
  const rawOnly = !clearOnly && topology.surface.profile?.kind === 'raw-only';
63
- // A direct no-tone/no-FXAA lane writes the final display view directly;
64
- // keeping a linear-LDR intermediate would add a redundant fullscreen pass.
65
- // FXAA samples the scene before the Output Transform, so its input must
66
- // remain float even when tone mapping is disabled. This prevents an
67
- // eight-bit quantization before the OETF/display-encoded boundary.
76
+ // Every non-clear lane keeps a linear float scene target until the shared
77
+ // Output Transform. This includes no-AA and the no-storage fallback: the
78
+ // final dither and display encoding must have one graph-owned boundary.
68
79
  // MSAA resolves into a separate linear target before presentation. Treat
69
80
  // that resolved target like linear LDR so the shared Output Transform owns
70
81
  // its write into the surface storage view; without this, the resolve is
71
82
  // never presented and MSAA is indistinguishable from the no-AA path.
72
- const linearLdr = !clearOnly && ((!hdr && topology.lane.storageBuffer) || fxaa || msaa);
83
+ const linearLdr = !clearOnly && !hdr;
73
84
  const temporalDemand = aggregateTemporalDemand({
74
85
  taa,
75
86
  motionBlur: !clearOnly && topology.temporal?.motionBlur === true,
@@ -88,7 +99,14 @@ function buildUrp(
88
99
  if (!depth.ok) return depth;
89
100
 
90
101
  const sceneResolved = clearOnly
91
- ? ok(surface.value.display ?? surface.value.storage)
102
+ ? surface.value.display === undefined
103
+ ? target(graph, 'scene-color', {
104
+ format: topology.surface.storageFormat,
105
+ size: 'surface',
106
+ sampleCount: 1,
107
+ domain: 'display-encoded',
108
+ })
109
+ : ok(surface.value.display)
92
110
  : hdr || fxaa || linearLdr || msaa || rawOnly || needsTemporalIntermediate
93
111
  ? target(graph, 'scene-color', {
94
112
  format: sceneFormat,
@@ -123,9 +141,48 @@ function buildUrp(
123
141
  : sceneResolved;
124
142
  if (!scene.ok) return scene;
125
143
 
144
+ const reflectionFallback = topology.reflectionFallback?.enabled
145
+ ? target(graph, 'reflection-fallback-linear-hdr', {
146
+ format: 'rgba16float',
147
+ size: 'surface',
148
+ sampleCount: scene.value.sampleCount,
149
+ domain: 'linear-hdr',
150
+ usage:
151
+ GPU_TEXTURE_USAGE_COPY_SRC |
152
+ GPU_TEXTURE_USAGE_RENDER_ATTACHMENT |
153
+ GPU_TEXTURE_USAGE_TEXTURE_BINDING,
154
+ })
155
+ : ok(undefined);
156
+ if (!reflectionFallback.ok) return reflectionFallback;
157
+ if (reflectionFallback.value !== undefined) {
158
+ const initialized = graph.addRasterPass('reflection-fallback-clear', {
159
+ accesses: [{ resource: reflectionFallback.value.view, usage: 'color-attachment' }],
160
+ colorAttachments: [
161
+ {
162
+ view: reflectionFallback.value.view,
163
+ loadOp: 'clear',
164
+ storeOp: 'store',
165
+ clearValue: { r: 0, g: 0, b: 0, a: 0 },
166
+ },
167
+ ],
168
+ encode: () => {},
169
+ });
170
+ if (!initialized.ok) return initialized;
171
+ }
172
+
126
173
  const shadows = addTypedShadowPasses(graph, topology);
127
174
  if (!shadows.ok) return shadows;
128
175
 
176
+ const clusterBuffers = clearOnly ? ok(null) : importStandardClusterBuffers(graph, lighting);
177
+ if (!clusterBuffers.ok) return clusterBuffers;
178
+ const clusterMembership =
179
+ clusterBuffers.value === null
180
+ ? ok(undefined)
181
+ : addStandardClusterMembershipPass(graph, lighting, clusterBuffers.value);
182
+ if (!clusterMembership.ok) return clusterMembership;
183
+ const clusterReads =
184
+ clusterBuffers.value === null ? [] : standardClusterReadAccesses(clusterBuffers.value);
185
+
129
186
  const skybox = addTypedSkyboxPass(graph, scene.value);
130
187
  if (!skybox.ok) return skybox;
131
188
  const gpuDriven = context.projectGpuDriven({
@@ -141,25 +198,30 @@ function buildUrp(
141
198
  const main = addTypedScenePass(graph, {
142
199
  name: 'main',
143
200
  color: scene.value,
201
+ ...(reflectionFallback.value === undefined
202
+ ? {}
203
+ : { colorTargets: [scene.value, reflectionFallback.value] }),
144
204
  depth: depth.value,
145
205
  ...(msaa ? { resolve: sceneResolved.value } : {}),
146
206
  sampled: [
147
- shadows.value.directional,
207
+ ...(shadows.value.directional === undefined ? [] : [shadows.value.directional]),
148
208
  shadows.value.spot,
149
209
  ...(shadows.value.point === undefined ? [] : [shadows.value.point]),
150
210
  ],
151
- directionalShadow: shadows.value.directional,
211
+ ...(shadows.value.directional === undefined
212
+ ? {}
213
+ : { directionalShadow: shadows.value.directional }),
152
214
  spotShadow: shadows.value.spot,
153
215
  selector: { LightMode: ['Forward'] },
154
216
  colorLoadOp: 'load',
217
+ extraAccesses: clusterReads,
155
218
  ...(transmissionActive ? { recordMode: 'opaque' as const } : {}),
156
219
  ...(gpuDriven.value === undefined ? {} : { gpuDriven: gpuDriven.value }),
220
+ ...(context.occlusion === undefined ? {} : { occlusion: context.occlusion }),
157
221
  });
158
222
  if (!main.ok) return main;
159
223
 
160
- const temporalLane = topology.lane.compute
161
- ? (topology.standardProfile?.lighting ?? 'direct')
162
- : 'cpu-webgl2';
224
+ const temporalLane = topology.lane.compute ? 'clustered' : 'cpu-webgl2';
163
225
  const temporalAdmission = standardTemporalLaneAdmission({
164
226
  lane: temporalLane,
165
227
  demand: temporalDemand,
@@ -191,6 +253,7 @@ function buildUrp(
191
253
  const producer = addStandardSceneDataPass(graph, temporal.value.temporal, depth.value);
192
254
  if (!producer.ok) return producer;
193
255
  }
256
+
194
257
  const transmission = addTransmissionBackdropPasses({
195
258
  graph,
196
259
  source: sceneResolved.value,
@@ -207,7 +270,7 @@ function buildUrp(
207
270
  depth: depth.value,
208
271
  ...(msaa ? { resolve: sceneResolved.value } : {}),
209
272
  sampled: [
210
- shadows.value.directional,
273
+ ...(shadows.value.directional === undefined ? [] : [shadows.value.directional]),
211
274
  shadows.value.spot,
212
275
  ...(shadows.value.point === undefined ? [] : [shadows.value.point]),
213
276
  ],
@@ -217,6 +280,7 @@ function buildUrp(
217
280
  colorLoadOp: 'load',
218
281
  depthLoadOp: 'load',
219
282
  recordMode: 'transmission',
283
+ extraAccesses: clusterReads,
220
284
  // Inject the complete backdrop view so the Standard shader can select
221
285
  // the producer's optional roughness mip level. mipViews[0] is only the
222
286
  // copy destination view and intentionally exposes one level.
@@ -230,7 +294,7 @@ function buildUrp(
230
294
  depth: depth.value,
231
295
  ...(msaa ? { resolve: sceneResolved.value } : {}),
232
296
  sampled: [
233
- shadows.value.directional,
297
+ ...(shadows.value.directional === undefined ? [] : [shadows.value.directional]),
234
298
  shadows.value.spot,
235
299
  ...(shadows.value.point === undefined ? [] : [shadows.value.point]),
236
300
  ],
@@ -240,6 +304,7 @@ function buildUrp(
240
304
  colorLoadOp: 'load',
241
305
  depthLoadOp: 'load',
242
306
  recordMode: 'transparent',
307
+ extraAccesses: clusterReads,
243
308
  });
244
309
  if (!transparentPass.ok) return transparentPass;
245
310
  const temporal = addTransmissionBackdropTemporalPass(graph, sceneResolved.value);
@@ -258,8 +323,9 @@ function buildUrp(
258
323
  topology,
259
324
  sceneResolved.value,
260
325
  depthSample.value,
261
- shadows.value.directional.view,
326
+ shadows.value.directional?.view,
262
327
  shadows.value.spot.view,
328
+ clusterBuffers.value,
263
329
  );
264
330
  if (!volume.ok) return volume;
265
331
  }
@@ -292,8 +358,15 @@ function buildUrp(
292
358
  );
293
359
  if (!observation.ok) return observation;
294
360
  }
361
+ if (reflectionFallback.value?.sampleCount === 1) {
362
+ const fallbackObservation = addReflectionFallbackObservationPass(
363
+ graph,
364
+ reflectionFallback.value,
365
+ );
366
+ if (!fallbackObservation.ok) return fallbackObservation;
367
+ }
295
368
 
296
- return addStandardPost(
369
+ const post = addStandardPost(
297
370
  context,
298
371
  topology,
299
372
  sceneResolved.value,
@@ -301,6 +374,10 @@ function buildUrp(
301
374
  surface.value,
302
375
  temporal.value?.temporal,
303
376
  );
377
+ if (!post.ok) return post;
378
+ const cubeCaptures = context.contributeCubeCaptures?.();
379
+ if (cubeCaptures !== undefined && !cubeCaptures.ok) return cubeCaptures;
380
+ return ok(undefined);
304
381
  }
305
382
 
306
383
  export const buildStandardForwardLane = buildUrp;
@@ -0,0 +1,6 @@
1
+ import type { ClusterBinError } from '../../cluster-binner';
2
+ import { StandardClusterIndexOverflowError } from '../../errors/render';
3
+
4
+ export function fromClusterBinError(error: ClusterBinError): StandardClusterIndexOverflowError {
5
+ return new StandardClusterIndexOverflowError(error.detail.actual, error.detail.capacity);
6
+ }
@@ -0,0 +1,158 @@
1
+ import type {
2
+ GraphAccess,
3
+ GraphBuffer,
4
+ RenderGraphBuilder,
5
+ RenderGraphError,
6
+ } from '@forgeax/engine-render-graph';
7
+ import { ok, type Result } from '@forgeax/engine-types';
8
+ import {
9
+ GPU_BUFFER_USAGE_COPY_DST,
10
+ GPU_BUFFER_USAGE_STORAGE,
11
+ GPU_BUFFER_USAGE_UNIFORM,
12
+ } from '../../gpu-usage';
13
+ import { getOrCreateHdrpBuffers, type HdrpBuffers } from '../../hdrp-buffers';
14
+ import { BYTES_PER_DIRECT_LIGHT_SLOT } from '../../light-buffer-layout';
15
+ import type { _InternalRenderPipelineContext } from '../../record/render-context';
16
+ import type { RenderPipelineFrame } from '../../render-pipeline';
17
+ import type { StandardTopologyInputValue } from './topology';
18
+
19
+ /** Graph resources projected from one Standard lighting topology input. */
20
+ export interface StandardClusterGraphBuffers {
21
+ readonly lightData: GraphBuffer;
22
+ readonly clusterGrid: GraphBuffer;
23
+ readonly lightIndexList: GraphBuffer;
24
+ readonly clusterUniform: GraphBuffer;
25
+ readonly lightBounds: GraphBuffer;
26
+ }
27
+
28
+ /** Stable graph-time projection; never retain a frame's typed-array payload. */
29
+ interface StandardClusterGraphDescriptor {
30
+ readonly grid: { readonly x: number; readonly y: number; readonly z: number };
31
+ }
32
+
33
+ function projectDescriptor(input: StandardTopologyInputValue): StandardClusterGraphDescriptor {
34
+ const { x, y, z } = input.prepared.layout.grid;
35
+ return { grid: { x, y, z } };
36
+ }
37
+
38
+ function resolveBuffers(
39
+ frame: RenderPipelineFrame,
40
+ descriptor: StandardClusterGraphDescriptor,
41
+ ): HdrpBuffers {
42
+ const internal = frame as _InternalRenderPipelineContext;
43
+ const buffers = getOrCreateHdrpBuffers(internal.runtime, descriptor.grid);
44
+ if (buffers === null) throw new Error('Standard persistent buffer allocation failed');
45
+ return buffers;
46
+ }
47
+
48
+ /** Resolve membership execution from the frame's current prepared payload. */
49
+ export function shouldExecuteStandardClusterMembershipPass(frame: RenderPipelineFrame): boolean {
50
+ const standardLighting = (frame as _InternalRenderPipelineContext).standardLighting;
51
+ return (
52
+ standardLighting?.kind === 'clustered' &&
53
+ standardLighting.transport.kind === 'compute-storage' &&
54
+ standardLighting.prepared.local.length > 0
55
+ );
56
+ }
57
+
58
+ /** Import the shared Standard Cluster buffers with sizes derived from layout. */
59
+ export function importStandardClusterBuffers(
60
+ graph: RenderGraphBuilder<RenderPipelineFrame>,
61
+ input: StandardTopologyInputValue,
62
+ ): Result<StandardClusterGraphBuffers | null, RenderGraphError> {
63
+ if (input.kind === 'no-local-lights') return ok(null);
64
+ const layout = input.prepared.layout;
65
+ const descriptor = projectDescriptor(input);
66
+ const usage = GPU_BUFFER_USAGE_STORAGE | GPU_BUFFER_USAGE_COPY_DST;
67
+ const lightData = graph.importBuffer(
68
+ 'hdrp-light-data',
69
+ { size: layout.lightDataSlotCount * BYTES_PER_DIRECT_LIGHT_SLOT, usage },
70
+ (frame) => resolveBuffers(frame, descriptor).lightDataBuffer,
71
+ );
72
+ if (!lightData.ok) return lightData;
73
+ const clusterGrid = graph.importBuffer(
74
+ 'hdrp-cluster-grid',
75
+ { size: layout.clusterGridU32Length * 4, usage },
76
+ (frame) => resolveBuffers(frame, descriptor).clusterGridBuffer,
77
+ );
78
+ if (!clusterGrid.ok) return clusterGrid;
79
+ const lightIndexList = graph.importBuffer(
80
+ 'hdrp-light-index-list',
81
+ { size: layout.lightIndexListCapacity * 4, usage },
82
+ (frame) => resolveBuffers(frame, descriptor).lightIndexListBuffer,
83
+ );
84
+ if (!lightIndexList.ok) return lightIndexList;
85
+ const clusterUniform = graph.importBuffer(
86
+ 'hdrp-cluster-uniform',
87
+ { size: 32, usage: GPU_BUFFER_USAGE_UNIFORM | GPU_BUFFER_USAGE_COPY_DST },
88
+ (frame) => resolveBuffers(frame, descriptor).clusterUniformBuffer,
89
+ );
90
+ if (!clusterUniform.ok) return clusterUniform;
91
+ const lightBounds = graph.importBuffer(
92
+ 'hdrp-light-bounds',
93
+ { size: layout.lightBoundsInt32Length * 4, usage },
94
+ (frame) => resolveBuffers(frame, descriptor).lightBoundsBuffer,
95
+ );
96
+ if (!lightBounds.ok) return lightBounds;
97
+ return ok({
98
+ lightData: lightData.value,
99
+ clusterGrid: clusterGrid.value,
100
+ lightIndexList: lightIndexList.value,
101
+ clusterUniform: clusterUniform.value,
102
+ lightBounds: lightBounds.value,
103
+ });
104
+ }
105
+
106
+ /** Accesses used by raster consumers of the shared Cluster payload. */
107
+ export function standardClusterReadAccesses(
108
+ buffers: StandardClusterGraphBuffers,
109
+ ): readonly GraphAccess[] {
110
+ return [
111
+ { resource: buffers.lightData, usage: 'storage-read' },
112
+ { resource: buffers.clusterGrid, usage: 'storage-read' },
113
+ { resource: buffers.lightIndexList, usage: 'storage-read' },
114
+ { resource: buffers.clusterUniform, usage: 'uniform-read' },
115
+ ];
116
+ }
117
+
118
+ /**
119
+ * Add the sole GPU membership producer. CPU membership is already materialized
120
+ * in PreparedStandardLighting and therefore contributes no second pass.
121
+ */
122
+ export function addStandardClusterMembershipPass(
123
+ graph: RenderGraphBuilder<RenderPipelineFrame>,
124
+ input: StandardTopologyInputValue,
125
+ buffers: StandardClusterGraphBuffers,
126
+ ): Result<void, RenderGraphError> {
127
+ if (input.kind === 'no-local-lights') return ok(undefined);
128
+ if (input.transport.kind !== 'compute-storage') return ok(undefined);
129
+ const descriptor = projectDescriptor(input);
130
+ return graph.addComputePass('cluster-membership-producer', {
131
+ accesses: [
132
+ { resource: buffers.clusterGrid, usage: 'storage-read' },
133
+ { resource: buffers.clusterUniform, usage: 'uniform-read' },
134
+ { resource: buffers.lightBounds, usage: 'storage-read' },
135
+ { resource: buffers.lightIndexList, usage: 'storage-write' },
136
+ ],
137
+ // Keep the clustered graph/ABI stable for a directional-only frame, but
138
+ // do not require a producer bind group when there is no local corpus to
139
+ // bin. The zero-length prepared payload is already the complete result;
140
+ // executing this pass would only turn an otherwise valid frame into a
141
+ // null-backend encode failure.
142
+ executeIf: shouldExecuteStandardClusterMembershipPass,
143
+ encode: ({ pass, frame }) => {
144
+ const internal = frame as _InternalRenderPipelineContext;
145
+ const pipeline = internal.pipelineState.hdrpClusterMembershipPipeline;
146
+ const bindings = internal.hdrpClusterMembershipBindGroup;
147
+ if (pipeline === null || bindings === null) {
148
+ throw new Error(
149
+ 'standard-cluster-transport-unavailable: selected compute Cluster producer is not ready',
150
+ );
151
+ }
152
+ const { x, y, z } = descriptor.grid;
153
+ pass.setPipeline(pipeline);
154
+ pass.setBindGroup(0, bindings);
155
+ pass.dispatchWorkgroups(Math.ceil((x * y * z) / 64));
156
+ },
157
+ });
158
+ }
@@ -0,0 +1,88 @@
1
+ import type { StandardTopologyInputValue } from './topology';
2
+ import type { StandardClusterTransport } from './transport';
3
+
4
+ export interface StandardClusterTransportInspection {
5
+ readonly renderPath: 'forward' | 'deferred';
6
+ readonly transport: StandardClusterTransport['kind'];
7
+ readonly producer: StandardClusterTransport['producer'];
8
+ readonly requested: StandardClusterTransport['requestedLightCount'];
9
+ readonly admitted: StandardClusterTransport['admittedLightCount'];
10
+ readonly shadowed: number;
11
+ readonly maxLights: number;
12
+ readonly indexCount: StandardClusterTransport['membershipEntryCount'];
13
+ readonly occupied: StandardClusterTransport['occupiedClusterCount'];
14
+ readonly clusterGridBytes: number;
15
+ readonly lightIndexListBytes: number;
16
+ readonly lightDataBytes: number;
17
+ readonly lightBoundsBytes: number;
18
+ readonly grid: StandardClusterTransport['layout']['grid'];
19
+ }
20
+
21
+ export interface StandardNoLocalLightingInspection {
22
+ readonly renderPath: 'forward' | 'deferred';
23
+ readonly transport: 'not-required';
24
+ readonly producer: 'none';
25
+ readonly requested: 0;
26
+ readonly admitted: 0;
27
+ readonly shadowed: 0;
28
+ readonly maxLights: number;
29
+ readonly indexCount: 0;
30
+ readonly occupied: 0;
31
+ readonly clusterGridBytes: 0;
32
+ readonly lightIndexListBytes: 0;
33
+ readonly lightDataBytes: 0;
34
+ readonly lightBoundsBytes: 0;
35
+ readonly grid: StandardTopologyInputValue['prepared']['layout']['grid'];
36
+ }
37
+
38
+ export type StandardLightingInspection =
39
+ | StandardClusterTransportInspection
40
+ | StandardNoLocalLightingInspection;
41
+
42
+ export function inspectStandardClusterTransport(
43
+ transport: StandardClusterTransport,
44
+ prepared: StandardTopologyInputValue['prepared'],
45
+ ): StandardClusterTransportInspection {
46
+ return Object.freeze({
47
+ renderPath: prepared.renderPath,
48
+ transport: transport.kind,
49
+ producer: transport.producer,
50
+ requested: transport.requestedLightCount,
51
+ admitted: transport.admittedLightCount,
52
+ shadowed: prepared.local.filter((light) => light.shadowed === true).length,
53
+ maxLights: prepared.maxLights,
54
+ indexCount: transport.membershipEntryCount,
55
+ occupied: transport.occupiedClusterCount,
56
+ clusterGridBytes: transport.clusterGridBytes,
57
+ lightIndexListBytes: transport.lightIndexListBytes,
58
+ lightDataBytes: transport.lightDataBytes,
59
+ lightBoundsBytes: transport.lightBoundsBytes,
60
+ // The inspection boundary is JSON-safe and detached from the mutable
61
+ // layout object carried by a per-frame prepared result.
62
+ grid: Object.freeze({ ...transport.layout.grid }),
63
+ });
64
+ }
65
+
66
+ export function inspectStandardLighting(
67
+ input: StandardTopologyInputValue,
68
+ ): StandardLightingInspection {
69
+ if (input.kind === 'no-local-lights') {
70
+ return Object.freeze({
71
+ renderPath: input.prepared.renderPath,
72
+ transport: 'not-required' as const,
73
+ producer: 'none' as const,
74
+ requested: 0 as const,
75
+ admitted: 0 as const,
76
+ shadowed: 0 as const,
77
+ maxLights: input.prepared.maxLights,
78
+ indexCount: 0 as const,
79
+ occupied: 0 as const,
80
+ clusterGridBytes: 0 as const,
81
+ lightIndexListBytes: 0 as const,
82
+ lightDataBytes: 0 as const,
83
+ lightBoundsBytes: 0 as const,
84
+ grid: Object.freeze({ ...input.prepared.layout.grid }),
85
+ });
86
+ }
87
+ return inspectStandardClusterTransport(input.transport, input.prepared);
88
+ }
@@ -0,0 +1,31 @@
1
+ export const DEFAULT_CLUSTER_GRID = { x: 16, y: 9, z: 24 } as const;
2
+ export const CLUSTER_GRID_STRIDE_U32 = 2 as const;
3
+ export const LIGHT_INDEX_LIST_CAPACITY = 1048576 as const;
4
+ export const MAX_LIGHTS = 256 as const;
5
+
6
+ export interface StandardClusterLayout {
7
+ readonly grid: { readonly x: number; readonly y: number; readonly z: number };
8
+ readonly clusterCount: number;
9
+ readonly clusterGridStrideU32: typeof CLUSTER_GRID_STRIDE_U32;
10
+ readonly clusterGridU32Length: number;
11
+ readonly lightIndexListCapacity: typeof LIGHT_INDEX_LIST_CAPACITY;
12
+ readonly lightDataSlotCount: typeof MAX_LIGHTS;
13
+ readonly lightBoundsInt32Length: number;
14
+ }
15
+
16
+ export function createStandardClusterLayout(
17
+ grid: { readonly x: number; readonly y: number; readonly z: number } = DEFAULT_CLUSTER_GRID,
18
+ ): StandardClusterLayout {
19
+ const clusterCount = grid.x * grid.y * grid.z;
20
+ return Object.freeze({
21
+ grid,
22
+ clusterCount,
23
+ clusterGridStrideU32: CLUSTER_GRID_STRIDE_U32,
24
+ clusterGridU32Length: clusterCount * CLUSTER_GRID_STRIDE_U32,
25
+ lightIndexListCapacity: LIGHT_INDEX_LIST_CAPACITY,
26
+ lightDataSlotCount: MAX_LIGHTS,
27
+ lightBoundsInt32Length: MAX_LIGHTS * 6,
28
+ });
29
+ }
30
+
31
+ export const STANDARD_CLUSTER_LAYOUT = createStandardClusterLayout();
@@ -0,0 +1,35 @@
1
+ import type { Mat4, Vec3 } from '@forgeax/engine-math';
2
+ import type {
3
+ DirectionalLightSnapshot,
4
+ PointLightSnapshot,
5
+ RectAreaDirectLightSnapshot,
6
+ SpotLightSnapshot,
7
+ } from '../../render-system-extract';
8
+ import type { StandardLightCount } from '../standard-profile';
9
+
10
+ export interface StandardLocalLightInput {
11
+ readonly kind: 'point' | 'spot' | 'rect-area';
12
+ readonly position: Vec3;
13
+ readonly range: number;
14
+ /** Whether the shadow producer admitted this local light to its atlas. */
15
+ readonly shadowed: boolean;
16
+ /**
17
+ * The immutable extract snapshot used by the record payload packer. Keeping
18
+ * it on the POD frame prevents Forward/Deferred from rebuilding a second
19
+ * light list while leaving hand-authored unit fixtures source-free.
20
+ */
21
+ readonly source?: PointLightSnapshot | SpotLightSnapshot | RectAreaDirectLightSnapshot;
22
+ }
23
+
24
+ export interface StandardLightFrame {
25
+ readonly directional: DirectionalLightSnapshot | undefined;
26
+ readonly local: readonly StandardLocalLightInput[];
27
+ readonly view: Mat4;
28
+ readonly projection: Mat4;
29
+ readonly near: number;
30
+ readonly far: number;
31
+ readonly grid: { readonly x: number; readonly y: number; readonly z: number };
32
+ readonly lightCount: StandardLightCount;
33
+ /** Graph path carried into inspection from the active Standard profile. */
34
+ readonly renderPath: 'forward' | 'deferred';
35
+ }
@@ -0,0 +1,43 @@
1
+ import { err, ok, type Result } from '@forgeax/engine-types';
2
+ import { bin, type ClusterBinScratch, createClusterBinScratch } from '../../cluster-binner';
3
+ import type { RenderError } from '../../errors/render';
4
+ import { fromClusterBinError } from './errors';
5
+ import type { StandardClusterLayout } from './layout';
6
+ import type { StandardLightFrame } from './light-frame';
7
+
8
+ export interface StandardClusterMembership {
9
+ readonly clusterGrid: Uint32Array;
10
+ readonly lightIndexList: Uint32Array;
11
+ readonly lightBounds: Int32Array;
12
+ readonly membershipEntryCount: number;
13
+ readonly scratch: ClusterBinScratch;
14
+ }
15
+
16
+ export function deriveStandardMembership(
17
+ frame: StandardLightFrame,
18
+ layout: StandardClusterLayout,
19
+ scratch = createClusterBinScratch(),
20
+ ): Result<StandardClusterMembership, RenderError> {
21
+ const clusterGrid = new Uint32Array(layout.clusterGridU32Length);
22
+ const lightIndexList = new Uint32Array(layout.lightIndexListCapacity);
23
+ const result = bin(
24
+ frame.local,
25
+ frame.view,
26
+ frame.projection,
27
+ layout.grid,
28
+ frame.near,
29
+ frame.far,
30
+ clusterGrid,
31
+ lightIndexList,
32
+ layout.lightIndexListCapacity,
33
+ scratch,
34
+ );
35
+ if (!result.ok) return err(fromClusterBinError(result.error));
36
+ return ok({
37
+ clusterGrid,
38
+ lightIndexList,
39
+ lightBounds: scratch.lightBounds.slice(0, frame.local.length * 6),
40
+ membershipEntryCount: result.value,
41
+ scratch,
42
+ });
43
+ }
@@ -0,0 +1,37 @@
1
+ import { err, ok, type Result } from '@forgeax/engine-types';
2
+ import { type RenderError, StandardLightBudgetExceededError } from '../../errors/render';
3
+ import { MAX_LIGHTS } from '../standard-profile';
4
+ import { createStandardClusterLayout, type StandardClusterLayout } from './layout';
5
+ import type { StandardLightFrame } from './light-frame';
6
+ import { deriveStandardMembership, type StandardClusterMembership } from './membership';
7
+
8
+ export type { StandardLightFrame } from './light-frame';
9
+
10
+ export interface PreparedStandardLighting extends StandardClusterMembership {
11
+ readonly directional: StandardLightFrame['directional'];
12
+ readonly local: StandardLightFrame['local'];
13
+ readonly layout: StandardClusterLayout;
14
+ readonly membershipLightCount: number;
15
+ readonly renderPath: NonNullable<StandardLightFrame['renderPath']>;
16
+ readonly maxLights: StandardLightFrame['lightCount'];
17
+ }
18
+
19
+ export function prepareStandardLighting(
20
+ frame: StandardLightFrame,
21
+ ): Result<PreparedStandardLighting, RenderError> {
22
+ if (frame.local.length > frame.lightCount || frame.local.length > MAX_LIGHTS) {
23
+ return err(new StandardLightBudgetExceededError(frame.local.length, frame.lightCount));
24
+ }
25
+ const layout = createStandardClusterLayout(frame.grid);
26
+ const membership = deriveStandardMembership(frame, layout);
27
+ if (!membership.ok) return membership;
28
+ return ok({
29
+ ...membership.value,
30
+ directional: frame.directional,
31
+ local: frame.local,
32
+ layout,
33
+ membershipLightCount: frame.local.length,
34
+ renderPath: frame.renderPath,
35
+ maxLights: frame.lightCount,
36
+ });
37
+ }