@forgeax/engine-render 0.0.0-dev.8d955ade1c79

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 (891) hide show
  1. package/LICENSE +202 -0
  2. package/README.md +647 -0
  3. package/dist/.tsbuildinfo +1 -0
  4. package/dist/__tests__/authoring-path.unit.test.d.ts +2 -0
  5. package/dist/__tests__/authoring-path.unit.test.d.ts.map +1 -0
  6. package/dist/__tests__/backend-selection-rhi-capture.test-d.d.ts +2 -0
  7. package/dist/__tests__/backend-selection-rhi-capture.test-d.d.ts.map +1 -0
  8. package/dist/__tests__/callback-inference.test-d.d.ts +2 -0
  9. package/dist/__tests__/callback-inference.test-d.d.ts.map +1 -0
  10. package/dist/__tests__/cluster-binner.test.d.ts +2 -0
  11. package/dist/__tests__/cluster-binner.test.d.ts.map +1 -0
  12. package/dist/__tests__/cluster-grid-default-surface.unit.test.d.ts +2 -0
  13. package/dist/__tests__/cluster-grid-default-surface.unit.test.d.ts.map +1 -0
  14. package/dist/__tests__/construct-renderer-identity.unit.test.d.ts +2 -0
  15. package/dist/__tests__/construct-renderer-identity.unit.test.d.ts.map +1 -0
  16. package/dist/__tests__/device-scope-lifecycle.unit.test.d.ts +2 -0
  17. package/dist/__tests__/device-scope-lifecycle.unit.test.d.ts.map +1 -0
  18. package/dist/__tests__/device-scope-stale-matrix.unit.test.d.ts +2 -0
  19. package/dist/__tests__/device-scope-stale-matrix.unit.test.d.ts.map +1 -0
  20. package/dist/__tests__/direct-extract-consumer-contract.test-d.d.ts +2 -0
  21. package/dist/__tests__/direct-extract-consumer-contract.test-d.d.ts.map +1 -0
  22. package/dist/__tests__/direct-light-snapshot.unit.test.d.ts +2 -0
  23. package/dist/__tests__/direct-light-snapshot.unit.test.d.ts.map +1 -0
  24. package/dist/__tests__/factory-contract.integration.test.d.ts +2 -0
  25. package/dist/__tests__/factory-contract.integration.test.d.ts.map +1 -0
  26. package/dist/__tests__/fallback-row-stride-surface.unit.test.d.ts +2 -0
  27. package/dist/__tests__/fallback-row-stride-surface.unit.test.d.ts.map +1 -0
  28. package/dist/__tests__/frame-observation.contract.test.d.ts +2 -0
  29. package/dist/__tests__/frame-observation.contract.test.d.ts.map +1 -0
  30. package/dist/__tests__/fullscreen-feature-plan.unit.test.d.ts +2 -0
  31. package/dist/__tests__/fullscreen-feature-plan.unit.test.d.ts.map +1 -0
  32. package/dist/__tests__/glyph-text-layout-recovery.unit.test.d.ts +2 -0
  33. package/dist/__tests__/glyph-text-layout-recovery.unit.test.d.ts.map +1 -0
  34. package/dist/__tests__/gpu-driven-indirect-raster-evidence.d.ts +6 -0
  35. package/dist/__tests__/gpu-driven-indirect-raster-evidence.d.ts.map +1 -0
  36. package/dist/__tests__/gpu-driven-indirect-raster.browser.test.d.ts +2 -0
  37. package/dist/__tests__/gpu-driven-indirect-raster.browser.test.d.ts.map +1 -0
  38. package/dist/__tests__/gpu-driven-indirect-raster.dawn.test.d.ts +2 -0
  39. package/dist/__tests__/gpu-driven-indirect-raster.dawn.test.d.ts.map +1 -0
  40. package/dist/__tests__/gpu-driven-production.integration.test.d.ts +2 -0
  41. package/dist/__tests__/gpu-driven-production.integration.test.d.ts.map +1 -0
  42. package/dist/__tests__/gpu-driven-scaling.unit.test.d.ts +2 -0
  43. package/dist/__tests__/gpu-driven-scaling.unit.test.d.ts.map +1 -0
  44. package/dist/__tests__/gpu-driven-view-gpu-evidence.d.ts +18 -0
  45. package/dist/__tests__/gpu-driven-view-gpu-evidence.d.ts.map +1 -0
  46. package/dist/__tests__/gpu-driven-view-graph.integration.test.d.ts +2 -0
  47. package/dist/__tests__/gpu-driven-view-graph.integration.test.d.ts.map +1 -0
  48. package/dist/__tests__/gpu-driven-view-reference.d.ts +15 -0
  49. package/dist/__tests__/gpu-driven-view-reference.d.ts.map +1 -0
  50. package/dist/__tests__/gpu-driven-view.browser.test.d.ts +2 -0
  51. package/dist/__tests__/gpu-driven-view.browser.test.d.ts.map +1 -0
  52. package/dist/__tests__/gpu-driven-view.dawn.test.d.ts +2 -0
  53. package/dist/__tests__/gpu-driven-view.dawn.test.d.ts.map +1 -0
  54. package/dist/__tests__/gpu-driven-view.unit.test.d.ts +2 -0
  55. package/dist/__tests__/gpu-driven-view.unit.test.d.ts.map +1 -0
  56. package/dist/__tests__/gpu-resource-store-stride.unit.test.d.ts +2 -0
  57. package/dist/__tests__/gpu-resource-store-stride.unit.test.d.ts.map +1 -0
  58. package/dist/__tests__/gpu-scene-render-graph-gpu.d.ts +7 -0
  59. package/dist/__tests__/gpu-scene-render-graph-gpu.d.ts.map +1 -0
  60. package/dist/__tests__/gpu-scene-render-graph.browser.test.d.ts +2 -0
  61. package/dist/__tests__/gpu-scene-render-graph.browser.test.d.ts.map +1 -0
  62. package/dist/__tests__/gpu-scene-render-graph.dawn.test.d.ts +2 -0
  63. package/dist/__tests__/gpu-scene-render-graph.dawn.test.d.ts.map +1 -0
  64. package/dist/__tests__/gpu-scene-schema.unit.test.d.ts +2 -0
  65. package/dist/__tests__/gpu-scene-schema.unit.test.d.ts.map +1 -0
  66. package/dist/__tests__/gpu-scene.dawn.test.d.ts +2 -0
  67. package/dist/__tests__/gpu-scene.dawn.test.d.ts.map +1 -0
  68. package/dist/__tests__/gpu-scene.unit.test.d.ts +2 -0
  69. package/dist/__tests__/gpu-scene.unit.test.d.ts.map +1 -0
  70. package/dist/__tests__/ibl/face-uniforms.unit.test.d.ts +2 -0
  71. package/dist/__tests__/ibl/face-uniforms.unit.test.d.ts.map +1 -0
  72. package/dist/__tests__/infinite-grid-no-vertex-probe.unit.test.d.ts +2 -0
  73. package/dist/__tests__/infinite-grid-no-vertex-probe.unit.test.d.ts.map +1 -0
  74. package/dist/__tests__/injection-kind-owner.test-d.d.ts +2 -0
  75. package/dist/__tests__/injection-kind-owner.test-d.d.ts.map +1 -0
  76. package/dist/__tests__/ktx2-basis-gpu-consumer.dawn.test.d.ts +2 -0
  77. package/dist/__tests__/ktx2-basis-gpu-consumer.dawn.test.d.ts.map +1 -0
  78. package/dist/__tests__/light-buffer-layout.unit.test.d.ts +2 -0
  79. package/dist/__tests__/light-buffer-layout.unit.test.d.ts.map +1 -0
  80. package/dist/__tests__/material-contract-inventory.unit.test.d.ts +2 -0
  81. package/dist/__tests__/material-contract-inventory.unit.test.d.ts.map +1 -0
  82. package/dist/__tests__/material-cooked-projection.unit.test.d.ts +2 -0
  83. package/dist/__tests__/material-cooked-projection.unit.test.d.ts.map +1 -0
  84. package/dist/__tests__/material-snapshot-mutation.integration.test.d.ts +2 -0
  85. package/dist/__tests__/material-snapshot-mutation.integration.test.d.ts.map +1 -0
  86. package/dist/__tests__/material-static-dynamic-route.unit.test.d.ts +2 -0
  87. package/dist/__tests__/material-static-dynamic-route.unit.test.d.ts.map +1 -0
  88. package/dist/__tests__/material-stride-surface.unit.test.d.ts +2 -0
  89. package/dist/__tests__/material-stride-surface.unit.test.d.ts.map +1 -0
  90. package/dist/__tests__/mesh-buffer-usage-surface.unit.test.d.ts +2 -0
  91. package/dist/__tests__/mesh-buffer-usage-surface.unit.test.d.ts.map +1 -0
  92. package/dist/__tests__/mesh-material-bindings.unit.test.d.ts +2 -0
  93. package/dist/__tests__/mesh-material-bindings.unit.test.d.ts.map +1 -0
  94. package/dist/__tests__/mesh-stride-surface.unit.test.d.ts +2 -0
  95. package/dist/__tests__/mesh-stride-surface.unit.test.d.ts.map +1 -0
  96. package/dist/__tests__/morph-culling-reentry.dawn.test.d.ts +2 -0
  97. package/dist/__tests__/morph-culling-reentry.dawn.test.d.ts.map +1 -0
  98. package/dist/__tests__/morph-feature-gpu-work.integration.test.d.ts +2 -0
  99. package/dist/__tests__/morph-feature-gpu-work.integration.test.d.ts.map +1 -0
  100. package/dist/__tests__/morph-feature-plan.unit.test.d.ts +2 -0
  101. package/dist/__tests__/morph-feature-plan.unit.test.d.ts.map +1 -0
  102. package/dist/__tests__/morph-visual-evidence.integration.test.d.ts +2 -0
  103. package/dist/__tests__/morph-visual-evidence.integration.test.d.ts.map +1 -0
  104. package/dist/__tests__/nineslice-handle-surface.unit.test.d.ts +2 -0
  105. package/dist/__tests__/nineslice-handle-surface.unit.test.d.ts.map +1 -0
  106. package/dist/__tests__/post-process-error-policy-owner.unit.test.d.ts +2 -0
  107. package/dist/__tests__/post-process-error-policy-owner.unit.test.d.ts.map +1 -0
  108. package/dist/__tests__/prepared-buffer-kind-owner.test-d.d.ts +2 -0
  109. package/dist/__tests__/prepared-buffer-kind-owner.test-d.d.ts.map +1 -0
  110. package/dist/__tests__/prepared-graphics-capability.unit.test.d.ts +2 -0
  111. package/dist/__tests__/prepared-graphics-capability.unit.test.d.ts.map +1 -0
  112. package/dist/__tests__/prepared-graphics-generation.unit.test.d.ts +2 -0
  113. package/dist/__tests__/prepared-graphics-generation.unit.test.d.ts.map +1 -0
  114. package/dist/__tests__/prepared-graphics-lifecycle.unit.test.d.ts +2 -0
  115. package/dist/__tests__/prepared-graphics-lifecycle.unit.test.d.ts.map +1 -0
  116. package/dist/__tests__/prepared-graphics-pipeline-warmup.unit.test.d.ts +2 -0
  117. package/dist/__tests__/prepared-graphics-pipeline-warmup.unit.test.d.ts.map +1 -0
  118. package/dist/__tests__/prepared-graphics-resolver.unit.test.d.ts +2 -0
  119. package/dist/__tests__/prepared-graphics-resolver.unit.test.d.ts.map +1 -0
  120. package/dist/__tests__/prepared-graphics-snapshot.unit.test.d.ts +2 -0
  121. package/dist/__tests__/prepared-graphics-snapshot.unit.test.d.ts.map +1 -0
  122. package/dist/__tests__/prepared-graphics-store.unit.test.d.ts +2 -0
  123. package/dist/__tests__/prepared-graphics-store.unit.test.d.ts.map +1 -0
  124. package/dist/__tests__/prepared-graphics-validation.unit.test.d.ts +2 -0
  125. package/dist/__tests__/prepared-graphics-validation.unit.test.d.ts.map +1 -0
  126. package/dist/__tests__/profiler-default-off.test.d.ts +2 -0
  127. package/dist/__tests__/profiler-default-off.test.d.ts.map +1 -0
  128. package/dist/__tests__/profiler-phase-catalog.test.d.ts +2 -0
  129. package/dist/__tests__/profiler-phase-catalog.test.d.ts.map +1 -0
  130. package/dist/__tests__/profiler-phase-integration.test.d.ts +2 -0
  131. package/dist/__tests__/profiler-phase-integration.test.d.ts.map +1 -0
  132. package/dist/__tests__/profiler-phase-token.test.d.ts +2 -0
  133. package/dist/__tests__/profiler-phase-token.test.d.ts.map +1 -0
  134. package/dist/__tests__/public-surface.test-d.d.ts +2 -0
  135. package/dist/__tests__/public-surface.test-d.d.ts.map +1 -0
  136. package/dist/__tests__/recover-error-policy-owner.unit.test.d.ts +2 -0
  137. package/dist/__tests__/recover-error-policy-owner.unit.test.d.ts.map +1 -0
  138. package/dist/__tests__/render-error-code-owner.test-d.d.ts +2 -0
  139. package/dist/__tests__/render-error-code-owner.test-d.d.ts.map +1 -0
  140. package/dist/__tests__/render-error-detail-ssot.test-d.d.ts +2 -0
  141. package/dist/__tests__/render-error-detail-ssot.test-d.d.ts.map +1 -0
  142. package/dist/__tests__/render-error-exhaustive.test-d.d.ts +2 -0
  143. package/dist/__tests__/render-error-exhaustive.test-d.d.ts.map +1 -0
  144. package/dist/__tests__/render-feature-assembly.test-d.d.ts +2 -0
  145. package/dist/__tests__/render-feature-assembly.test-d.d.ts.map +1 -0
  146. package/dist/__tests__/render-feature-context.test-d.d.ts +2 -0
  147. package/dist/__tests__/render-feature-context.test-d.d.ts.map +1 -0
  148. package/dist/__tests__/render-feature-contract.test-d.d.ts +2 -0
  149. package/dist/__tests__/render-feature-contract.test-d.d.ts.map +1 -0
  150. package/dist/__tests__/render-feature-diagnostics.unit.test.d.ts +2 -0
  151. package/dist/__tests__/render-feature-diagnostics.unit.test.d.ts.map +1 -0
  152. package/dist/__tests__/render-feature-docs.unit.test.d.ts +2 -0
  153. package/dist/__tests__/render-feature-docs.unit.test.d.ts.map +1 -0
  154. package/dist/__tests__/render-feature-errors.unit.test.d.ts +2 -0
  155. package/dist/__tests__/render-feature-errors.unit.test.d.ts.map +1 -0
  156. package/dist/__tests__/render-feature-gpu-work.integration.test.d.ts +2 -0
  157. package/dist/__tests__/render-feature-gpu-work.integration.test.d.ts.map +1 -0
  158. package/dist/__tests__/render-feature-plan.test-d.d.ts +2 -0
  159. package/dist/__tests__/render-feature-plan.test-d.d.ts.map +1 -0
  160. package/dist/__tests__/render-feature-plan.unit.test.d.ts +2 -0
  161. package/dist/__tests__/render-feature-plan.unit.test.d.ts.map +1 -0
  162. package/dist/__tests__/render-feature-prepared-diagnostics.unit.test.d.ts +2 -0
  163. package/dist/__tests__/render-feature-prepared-diagnostics.unit.test.d.ts.map +1 -0
  164. package/dist/__tests__/render-feature-prepared-errors.test-d.d.ts +2 -0
  165. package/dist/__tests__/render-feature-prepared-errors.test-d.d.ts.map +1 -0
  166. package/dist/__tests__/render-feature-prepared-graphics-docs.unit.test.d.ts +2 -0
  167. package/dist/__tests__/render-feature-prepared-graphics-docs.unit.test.d.ts.map +1 -0
  168. package/dist/__tests__/render-feature-prepared-graphics-isolation.unit.test.d.ts +2 -0
  169. package/dist/__tests__/render-feature-prepared-graphics-isolation.unit.test.d.ts.map +1 -0
  170. package/dist/__tests__/render-feature-prepared-graphics-negative.test-d.d.ts +2 -0
  171. package/dist/__tests__/render-feature-prepared-graphics-negative.test-d.d.ts.map +1 -0
  172. package/dist/__tests__/render-feature-prepared-graphics.test-d.d.ts +2 -0
  173. package/dist/__tests__/render-feature-prepared-graphics.test-d.d.ts.map +1 -0
  174. package/dist/__tests__/render-feature-prepared-graphics.unit.test.d.ts +2 -0
  175. package/dist/__tests__/render-feature-prepared-graphics.unit.test.d.ts.map +1 -0
  176. package/dist/__tests__/render-feature-public-surface.test-d.d.ts +2 -0
  177. package/dist/__tests__/render-feature-public-surface.test-d.d.ts.map +1 -0
  178. package/dist/__tests__/render-feature-retry.unit.test.d.ts +2 -0
  179. package/dist/__tests__/render-feature-retry.unit.test.d.ts.map +1 -0
  180. package/dist/__tests__/render-feature-scheduling.unit.test.d.ts +2 -0
  181. package/dist/__tests__/render-feature-scheduling.unit.test.d.ts.map +1 -0
  182. package/dist/__tests__/render-feature-stage-failed-policy-owner.unit.test.d.ts +2 -0
  183. package/dist/__tests__/render-feature-stage-failed-policy-owner.unit.test.d.ts.map +1 -0
  184. package/dist/__tests__/render-feature-stage-fault-recovery.unit.test.d.ts +2 -0
  185. package/dist/__tests__/render-feature-stage-fault-recovery.unit.test.d.ts.map +1 -0
  186. package/dist/__tests__/render-feature-visibility-context.test-d.d.ts +2 -0
  187. package/dist/__tests__/render-feature-visibility-context.test-d.d.ts.map +1 -0
  188. package/dist/__tests__/render-feature-visibility-context.unit.test.d.ts +2 -0
  189. package/dist/__tests__/render-feature-visibility-context.unit.test.d.ts.map +1 -0
  190. package/dist/__tests__/render-feature-zero-work.unit.test.d.ts +2 -0
  191. package/dist/__tests__/render-feature-zero-work.unit.test.d.ts.map +1 -0
  192. package/dist/__tests__/render-graph-compute-raster-gpu.d.ts +7 -0
  193. package/dist/__tests__/render-graph-compute-raster-gpu.d.ts.map +1 -0
  194. package/dist/__tests__/render-graph-compute-raster.browser.test.d.ts +2 -0
  195. package/dist/__tests__/render-graph-compute-raster.browser.test.d.ts.map +1 -0
  196. package/dist/__tests__/render-graph-compute-raster.dawn.test.d.ts +2 -0
  197. package/dist/__tests__/render-graph-compute-raster.dawn.test.d.ts.map +1 -0
  198. package/dist/__tests__/render-graph-hzb-gpu.d.ts +7 -0
  199. package/dist/__tests__/render-graph-hzb-gpu.d.ts.map +1 -0
  200. package/dist/__tests__/render-graph-hzb.browser.test.d.ts +2 -0
  201. package/dist/__tests__/render-graph-hzb.browser.test.d.ts.map +1 -0
  202. package/dist/__tests__/render-graph-hzb.dawn.test.d.ts +2 -0
  203. package/dist/__tests__/render-graph-hzb.dawn.test.d.ts.map +1 -0
  204. package/dist/__tests__/render-graph-primitives.unit.test.d.ts +2 -0
  205. package/dist/__tests__/render-graph-primitives.unit.test.d.ts.map +1 -0
  206. package/dist/__tests__/render-graph-storage-indirect-gpu.d.ts +12 -0
  207. package/dist/__tests__/render-graph-storage-indirect-gpu.d.ts.map +1 -0
  208. package/dist/__tests__/render-graph-storage-indirect.browser.test.d.ts +2 -0
  209. package/dist/__tests__/render-graph-storage-indirect.browser.test.d.ts.map +1 -0
  210. package/dist/__tests__/render-graph-storage-indirect.dawn.test.d.ts +2 -0
  211. package/dist/__tests__/render-graph-storage-indirect.dawn.test.d.ts.map +1 -0
  212. package/dist/__tests__/render-scene-projection.unit.test.d.ts +2 -0
  213. package/dist/__tests__/render-scene-projection.unit.test.d.ts.map +1 -0
  214. package/dist/__tests__/renderer-factory-material-contract.unit.test.d.ts +2 -0
  215. package/dist/__tests__/renderer-factory-material-contract.unit.test.d.ts.map +1 -0
  216. package/dist/__tests__/renderer-lifecycle.integration.test.d.ts +2 -0
  217. package/dist/__tests__/renderer-lifecycle.integration.test.d.ts.map +1 -0
  218. package/dist/__tests__/rhi-backend-package-boundary.unit.test.d.ts +2 -0
  219. package/dist/__tests__/rhi-backend-package-boundary.unit.test.d.ts.map +1 -0
  220. package/dist/__tests__/scriptable-pack-consumer.test-d.d.ts +2 -0
  221. package/dist/__tests__/scriptable-pack-consumer.test-d.d.ts.map +1 -0
  222. package/dist/__tests__/shader-stage-surface.unit.test.d.ts +2 -0
  223. package/dist/__tests__/shader-stage-surface.unit.test.d.ts.map +1 -0
  224. package/dist/__tests__/ssao-config.unit.test.d.ts +2 -0
  225. package/dist/__tests__/ssao-config.unit.test.d.ts.map +1 -0
  226. package/dist/__tests__/ssao-kernel-surface.unit.test.d.ts +2 -0
  227. package/dist/__tests__/ssao-kernel-surface.unit.test.d.ts.map +1 -0
  228. package/dist/__tests__/standard-clustered-pipeline.unit.test.d.ts +2 -0
  229. package/dist/__tests__/standard-clustered-pipeline.unit.test.d.ts.map +1 -0
  230. package/dist/__tests__/standard-descriptors.test-d.d.ts +2 -0
  231. package/dist/__tests__/standard-descriptors.test-d.d.ts.map +1 -0
  232. package/dist/__tests__/standard-pipeline.dawn.test.d.ts +2 -0
  233. package/dist/__tests__/standard-pipeline.dawn.test.d.ts.map +1 -0
  234. package/dist/__tests__/standard-pipeline.integration.test.d.ts +2 -0
  235. package/dist/__tests__/standard-pipeline.integration.test.d.ts.map +1 -0
  236. package/dist/__tests__/standard-profile-oracle.unit.test.d.ts +2 -0
  237. package/dist/__tests__/standard-profile-oracle.unit.test.d.ts.map +1 -0
  238. package/dist/__tests__/surface-configuration.unit.test.d.ts +2 -0
  239. package/dist/__tests__/surface-configuration.unit.test.d.ts.map +1 -0
  240. package/dist/__tests__/texture-usage-surface.unit.test.d.ts +2 -0
  241. package/dist/__tests__/texture-usage-surface.unit.test.d.ts.map +1 -0
  242. package/dist/__tests__/typed-pipeline-topology.unit.test.d.ts +2 -0
  243. package/dist/__tests__/typed-pipeline-topology.unit.test.d.ts.map +1 -0
  244. package/dist/__tests__/urp-pipeline-targets.unit.test.d.ts +2 -0
  245. package/dist/__tests__/urp-pipeline-targets.unit.test.d.ts.map +1 -0
  246. package/dist/__tests__/urp-pipeline.unit.test.d.ts +2 -0
  247. package/dist/__tests__/urp-pipeline.unit.test.d.ts.map +1 -0
  248. package/dist/__tests__/vertex-color-pipeline.unit.test.d.ts +2 -0
  249. package/dist/__tests__/vertex-color-pipeline.unit.test.d.ts.map +1 -0
  250. package/dist/__tests__/vertex-layout-consumer.unit.test.d.ts +2 -0
  251. package/dist/__tests__/vertex-layout-consumer.unit.test.d.ts.map +1 -0
  252. package/dist/__tests__/visibility-diagnostics.integration.test.d.ts +2 -0
  253. package/dist/__tests__/visibility-diagnostics.integration.test.d.ts.map +1 -0
  254. package/dist/__tests__/visibility-extract.integration.test.d.ts +2 -0
  255. package/dist/__tests__/visibility-extract.integration.test.d.ts.map +1 -0
  256. package/dist/__tests__/visibility-extract.perf.test.d.ts +2 -0
  257. package/dist/__tests__/visibility-extract.perf.test.d.ts.map +1 -0
  258. package/dist/__tests__/visibility-feature-dedup.integration.test.d.ts +2 -0
  259. package/dist/__tests__/visibility-feature-dedup.integration.test.d.ts.map +1 -0
  260. package/dist/__tests__/visibility-hidden-report.unit.test.d.ts +2 -0
  261. package/dist/__tests__/visibility-hidden-report.unit.test.d.ts.map +1 -0
  262. package/dist/__tests__/visibility-instances.integration.test.d.ts +2 -0
  263. package/dist/__tests__/visibility-instances.integration.test.d.ts.map +1 -0
  264. package/dist/__tests__/visibility-multi-world.integration.test.d.ts +2 -0
  265. package/dist/__tests__/visibility-multi-world.integration.test.d.ts.map +1 -0
  266. package/dist/__tests__/visibility-producer-matrix.integration.test.d.ts +2 -0
  267. package/dist/__tests__/visibility-producer-matrix.integration.test.d.ts.map +1 -0
  268. package/dist/__tests__/visibility-producer-matrix.unit.test.d.ts +2 -0
  269. package/dist/__tests__/visibility-producer-matrix.unit.test.d.ts.map +1 -0
  270. package/dist/__tests__/visibility-public-surface.test-d.d.ts +2 -0
  271. package/dist/__tests__/visibility-public-surface.test-d.d.ts.map +1 -0
  272. package/dist/__tests__/visibility-resolver.unit.test.d.ts +2 -0
  273. package/dist/__tests__/visibility-resolver.unit.test.d.ts.map +1 -0
  274. package/dist/__tests__/visibility-resource-short-circuit.unit.test.d.ts +2 -0
  275. package/dist/__tests__/visibility-resource-short-circuit.unit.test.d.ts.map +1 -0
  276. package/dist/__tests__/visibility-snapshot-contract.unit.test.d.ts +2 -0
  277. package/dist/__tests__/visibility-snapshot-contract.unit.test.d.ts.map +1 -0
  278. package/dist/__tests__/vocabulary.unit.test.d.ts +2 -0
  279. package/dist/__tests__/vocabulary.unit.test.d.ts.map +1 -0
  280. package/dist/assembly/backend-contract.d.ts +37 -0
  281. package/dist/assembly/backend-contract.d.ts.map +1 -0
  282. package/dist/assembly/factory.d.ts +207 -0
  283. package/dist/assembly/factory.d.ts.map +1 -0
  284. package/dist/assembly/host-contract.d.ts +84 -0
  285. package/dist/assembly/host-contract.d.ts.map +1 -0
  286. package/dist/assembly/material/assembly.d.ts +21 -0
  287. package/dist/assembly/material/assembly.d.ts.map +1 -0
  288. package/dist/assembly/material/pipeline-projection.d.ts +30 -0
  289. package/dist/assembly/material/pipeline-projection.d.ts.map +1 -0
  290. package/dist/assets/asset-decoders.d.ts +5 -0
  291. package/dist/assets/asset-decoders.d.ts.map +1 -0
  292. package/dist/assets/render-asset-port.d.ts +17 -0
  293. package/dist/assets/render-asset-port.d.ts.map +1 -0
  294. package/dist/assets/resolve-render-asset.d.ts +6 -0
  295. package/dist/assets/resolve-render-asset.d.ts.map +1 -0
  296. package/dist/authoring.d.ts +12 -0
  297. package/dist/authoring.d.ts.map +1 -0
  298. package/dist/authoring.mjs +27 -0
  299. package/dist/authoring.mjs.map +1 -0
  300. package/dist/chunk-CQXZC5XI.mjs +182 -0
  301. package/dist/chunk-CQXZC5XI.mjs.map +1 -0
  302. package/dist/chunk-HCOGPHKS.mjs +93 -0
  303. package/dist/chunk-HCOGPHKS.mjs.map +1 -0
  304. package/dist/chunk-YEJIUW7D.mjs +1152 -0
  305. package/dist/chunk-YEJIUW7D.mjs.map +1 -0
  306. package/dist/cluster-binner.d.ts +152 -0
  307. package/dist/cluster-binner.d.ts.map +1 -0
  308. package/dist/components/__tests__/points-lines-admission.unit.test.d.ts +2 -0
  309. package/dist/components/__tests__/points-lines-admission.unit.test.d.ts.map +1 -0
  310. package/dist/components/__tests__/points-lines-schema.unit.test.d.ts +2 -0
  311. package/dist/components/__tests__/points-lines-schema.unit.test.d.ts.map +1 -0
  312. package/dist/components/__tests__/schema-contract.unit.test.d.ts +2 -0
  313. package/dist/components/__tests__/schema-contract.unit.test.d.ts.map +1 -0
  314. package/dist/components/__tests__/schema-parity.unit.test.d.ts +2 -0
  315. package/dist/components/__tests__/schema-parity.unit.test.d.ts.map +1 -0
  316. package/dist/components/__tests__/visibility-schema.unit.test.d.ts +2 -0
  317. package/dist/components/__tests__/visibility-schema.unit.test.d.ts.map +1 -0
  318. package/dist/components/camera.d.ts +311 -0
  319. package/dist/components/camera.d.ts.map +1 -0
  320. package/dist/components/directional-light.d.ts +76 -0
  321. package/dist/components/directional-light.d.ts.map +1 -0
  322. package/dist/components/glyph-text.d.ts +26 -0
  323. package/dist/components/glyph-text.d.ts.map +1 -0
  324. package/dist/components/index.d.ts +24 -0
  325. package/dist/components/index.d.ts.map +1 -0
  326. package/dist/components/instances.d.ts +41 -0
  327. package/dist/components/instances.d.ts.map +1 -0
  328. package/dist/components/layer.d.ts +34 -0
  329. package/dist/components/layer.d.ts.map +1 -0
  330. package/dist/components/light-helpers.d.ts +53 -0
  331. package/dist/components/light-helpers.d.ts.map +1 -0
  332. package/dist/components/lines.d.ts +5 -0
  333. package/dist/components/lines.d.ts.map +1 -0
  334. package/dist/components/mesh-filter.d.ts +24 -0
  335. package/dist/components/mesh-filter.d.ts.map +1 -0
  336. package/dist/components/mesh-renderer.d.ts +33 -0
  337. package/dist/components/mesh-renderer.d.ts.map +1 -0
  338. package/dist/components/point-light-shadow.d.ts +27 -0
  339. package/dist/components/point-light-shadow.d.ts.map +1 -0
  340. package/dist/components/point-light.d.ts +35 -0
  341. package/dist/components/point-light.d.ts.map +1 -0
  342. package/dist/components/points.d.ts +15 -0
  343. package/dist/components/points.d.ts.map +1 -0
  344. package/dist/components/post-process-params.d.ts +5 -0
  345. package/dist/components/post-process-params.d.ts.map +1 -0
  346. package/dist/components/scene-instance.d.ts +140 -0
  347. package/dist/components/scene-instance.d.ts.map +1 -0
  348. package/dist/components/skybox-background.d.ts +56 -0
  349. package/dist/components/skybox-background.d.ts.map +1 -0
  350. package/dist/components/skylight.d.ts +55 -0
  351. package/dist/components/skylight.d.ts.map +1 -0
  352. package/dist/components/sort-key.d.ts +44 -0
  353. package/dist/components/sort-key.d.ts.map +1 -0
  354. package/dist/components/spot-light.d.ts +81 -0
  355. package/dist/components/spot-light.d.ts.map +1 -0
  356. package/dist/components/sprite-animation.d.ts +74 -0
  357. package/dist/components/sprite-animation.d.ts.map +1 -0
  358. package/dist/components/sprite-instances.d.ts +51 -0
  359. package/dist/components/sprite-instances.d.ts.map +1 -0
  360. package/dist/components/sprite-playback-mode.d.ts +42 -0
  361. package/dist/components/sprite-playback-mode.d.ts.map +1 -0
  362. package/dist/components/sprite-region-override.d.ts +46 -0
  363. package/dist/components/sprite-region-override.d.ts.map +1 -0
  364. package/dist/components/tile-layer.d.ts +106 -0
  365. package/dist/components/tile-layer.d.ts.map +1 -0
  366. package/dist/components/tilemap.d.ts +25 -0
  367. package/dist/components/tilemap.d.ts.map +1 -0
  368. package/dist/components/visibility.d.ts +22 -0
  369. package/dist/components/visibility.d.ts.map +1 -0
  370. package/dist/construct-renderer.d.ts +19 -0
  371. package/dist/construct-renderer.d.ts.map +1 -0
  372. package/dist/construct-renderer.mjs +27462 -0
  373. package/dist/construct-renderer.mjs.map +1 -0
  374. package/dist/debug-draw-glue.d.ts +5 -0
  375. package/dist/debug-draw-glue.d.ts.map +1 -0
  376. package/dist/device/device-scope.d.ts +83 -0
  377. package/dist/device/device-scope.d.ts.map +1 -0
  378. package/dist/device/gpu-residency.d.ts +337 -0
  379. package/dist/device/gpu-residency.d.ts.map +1 -0
  380. package/dist/device/resource-types.d.ts +8 -0
  381. package/dist/device/resource-types.d.ts.map +1 -0
  382. package/dist/engine-metrics.d.ts +23 -0
  383. package/dist/engine-metrics.d.ts.map +1 -0
  384. package/dist/errors/ecs-validation.d.ts +3 -0
  385. package/dist/errors/ecs-validation.d.ts.map +1 -0
  386. package/dist/errors/index.d.ts +4 -0
  387. package/dist/errors/index.d.ts.map +1 -0
  388. package/dist/errors/recover.d.ts +105 -0
  389. package/dist/errors/recover.d.ts.map +1 -0
  390. package/dist/errors/render.d.ts +705 -0
  391. package/dist/errors/render.d.ts.map +1 -0
  392. package/dist/extract/visibility.d.ts +26 -0
  393. package/dist/extract/visibility.d.ts.map +1 -0
  394. package/dist/features/fullscreen.d.ts +19 -0
  395. package/dist/features/fullscreen.d.ts.map +1 -0
  396. package/dist/features/host.d.ts +106 -0
  397. package/dist/features/host.d.ts.map +1 -0
  398. package/dist/features/morph/morph-feature.d.ts +79 -0
  399. package/dist/features/morph/morph-feature.d.ts.map +1 -0
  400. package/dist/features/plan.d.ts +182 -0
  401. package/dist/features/plan.d.ts.map +1 -0
  402. package/dist/features/prepared-gpu-work.d.ts +117 -0
  403. package/dist/features/prepared-gpu-work.d.ts.map +1 -0
  404. package/dist/features/prepared-graphics-store.d.ts +66 -0
  405. package/dist/features/prepared-graphics-store.d.ts.map +1 -0
  406. package/dist/features/prepared-graphics.d.ts +215 -0
  407. package/dist/features/prepared-graphics.d.ts.map +1 -0
  408. package/dist/features/render-graph-compute.d.ts +13 -0
  409. package/dist/features/render-graph-compute.d.ts.map +1 -0
  410. package/dist/features/render-graph-contribution.d.ts +12 -0
  411. package/dist/features/render-graph-contribution.d.ts.map +1 -0
  412. package/dist/features/render-graph-raster.d.ts +38 -0
  413. package/dist/features/render-graph-raster.d.ts.map +1 -0
  414. package/dist/features/render-graph-resources.d.ts +11 -0
  415. package/dist/features/render-graph-resources.d.ts.map +1 -0
  416. package/dist/features/targets.d.ts +32 -0
  417. package/dist/features/targets.d.ts.map +1 -0
  418. package/dist/features/types.d.ts +68 -0
  419. package/dist/features/types.d.ts.map +1 -0
  420. package/dist/features/vocabulary.d.ts +14 -0
  421. package/dist/features/vocabulary.d.ts.map +1 -0
  422. package/dist/fullscreen-post-process-pass.d.ts +157 -0
  423. package/dist/fullscreen-post-process-pass.d.ts.map +1 -0
  424. package/dist/glyph-text-layout-system.d.ts +19 -0
  425. package/dist/glyph-text-layout-system.d.ts.map +1 -0
  426. package/dist/gpu-driven/batch-topology.d.ts +55 -0
  427. package/dist/gpu-driven/batch-topology.d.ts.map +1 -0
  428. package/dist/gpu-driven/production-raster.d.ts +51 -0
  429. package/dist/gpu-driven/production-raster.d.ts.map +1 -0
  430. package/dist/gpu-driven/view-gpu.d.ts +85 -0
  431. package/dist/gpu-driven/view-gpu.d.ts.map +1 -0
  432. package/dist/gpu-resource.d.ts +73 -0
  433. package/dist/gpu-resource.d.ts.map +1 -0
  434. package/dist/gpu-scene-schema.d.ts +78 -0
  435. package/dist/gpu-scene-schema.d.ts.map +1 -0
  436. package/dist/gpu-scene.d.ts +55 -0
  437. package/dist/gpu-scene.d.ts.map +1 -0
  438. package/dist/gpu-stage.d.ts +4 -0
  439. package/dist/gpu-stage.d.ts.map +1 -0
  440. package/dist/gpu-texture-usage.d.ts +6 -0
  441. package/dist/gpu-texture-usage.d.ts.map +1 -0
  442. package/dist/gpu-usage.d.ts +9 -0
  443. package/dist/gpu-usage.d.ts.map +1 -0
  444. package/dist/hdrp-buffers.d.ts +163 -0
  445. package/dist/hdrp-buffers.d.ts.map +1 -0
  446. package/dist/ibl/IblPipelineCache.d.ts +168 -0
  447. package/dist/ibl/IblPipelineCache.d.ts.map +1 -0
  448. package/dist/ibl/skylight-bind-group.d.ts +130 -0
  449. package/dist/ibl/skylight-bind-group.d.ts.map +1 -0
  450. package/dist/index.d.ts +31 -0
  451. package/dist/index.d.ts.map +1 -0
  452. package/dist/index.mjs +169 -0
  453. package/dist/index.mjs.map +1 -0
  454. package/dist/inspection-types.d.ts +72 -0
  455. package/dist/inspection-types.d.ts.map +1 -0
  456. package/dist/instance-buffer-cache.d.ts +56 -0
  457. package/dist/instance-buffer-cache.d.ts.map +1 -0
  458. package/dist/internal.d.ts +2 -0
  459. package/dist/internal.d.ts.map +1 -0
  460. package/dist/internal.mjs +3 -0
  461. package/dist/internal.mjs.map +1 -0
  462. package/dist/lifecycle.d.ts +62 -0
  463. package/dist/lifecycle.d.ts.map +1 -0
  464. package/dist/light-buffer-layout.d.ts +164 -0
  465. package/dist/light-buffer-layout.d.ts.map +1 -0
  466. package/dist/materials.d.ts +47 -0
  467. package/dist/materials.d.ts.map +1 -0
  468. package/dist/mesh-material-bindings.d.ts +43 -0
  469. package/dist/mesh-material-bindings.d.ts.map +1 -0
  470. package/dist/pbr-pipeline.d.ts +301 -0
  471. package/dist/pbr-pipeline.d.ts.map +1 -0
  472. package/dist/pipeline/standard-forward-lane.d.ts +5 -0
  473. package/dist/pipeline/standard-forward-lane.d.ts.map +1 -0
  474. package/dist/pipeline/standard-pipeline.d.ts +31 -0
  475. package/dist/pipeline/standard-pipeline.d.ts.map +1 -0
  476. package/dist/pipeline/standard-profile.d.ts +40 -0
  477. package/dist/pipeline/standard-profile.d.ts.map +1 -0
  478. package/dist/pipeline-builder.d.ts +122 -0
  479. package/dist/pipeline-builder.d.ts.map +1 -0
  480. package/dist/pipeline-spec-types.d.ts +24 -0
  481. package/dist/pipeline-spec-types.d.ts.map +1 -0
  482. package/dist/pipeline-spec.d.ts +367 -0
  483. package/dist/pipeline-spec.d.ts.map +1 -0
  484. package/dist/plugin.d.ts +4 -0
  485. package/dist/plugin.d.ts.map +1 -0
  486. package/dist/points-lines/__tests__/bounds.unit.test.d.ts +2 -0
  487. package/dist/points-lines/__tests__/bounds.unit.test.d.ts.map +1 -0
  488. package/dist/points-lines/__tests__/cache-recovery.unit.test.d.ts +2 -0
  489. package/dist/points-lines/__tests__/cache-recovery.unit.test.d.ts.map +1 -0
  490. package/dist/points-lines/__tests__/inspection-lanes.integration.test.d.ts +2 -0
  491. package/dist/points-lines/__tests__/inspection-lanes.integration.test.d.ts.map +1 -0
  492. package/dist/points-lines/__tests__/inspection.unit.test.d.ts +2 -0
  493. package/dist/points-lines/__tests__/inspection.unit.test.d.ts.map +1 -0
  494. package/dist/points-lines/__tests__/lane-structural.integration.test.d.ts +2 -0
  495. package/dist/points-lines/__tests__/lane-structural.integration.test.d.ts.map +1 -0
  496. package/dist/points-lines/__tests__/points-lines.bench.d.ts +2 -0
  497. package/dist/points-lines/__tests__/points-lines.bench.d.ts.map +1 -0
  498. package/dist/points-lines/__tests__/raster-lane.integration.test.d.ts +2 -0
  499. package/dist/points-lines/__tests__/raster-lane.integration.test.d.ts.map +1 -0
  500. package/dist/points-lines/__tests__/snapshot.unit.test.d.ts +2 -0
  501. package/dist/points-lines/__tests__/snapshot.unit.test.d.ts.map +1 -0
  502. package/dist/points-lines/__tests__/view-ubo.unit.test.d.ts +2 -0
  503. package/dist/points-lines/__tests__/view-ubo.unit.test.d.ts.map +1 -0
  504. package/dist/points-lines/admission.d.ts +36 -0
  505. package/dist/points-lines/admission.d.ts.map +1 -0
  506. package/dist/points-lines/bounds.d.ts +8 -0
  507. package/dist/points-lines/bounds.d.ts.map +1 -0
  508. package/dist/points-lines/expansion-cache.d.ts +28 -0
  509. package/dist/points-lines/expansion-cache.d.ts.map +1 -0
  510. package/dist/points-lines/inspection.d.ts +53 -0
  511. package/dist/points-lines/inspection.d.ts.map +1 -0
  512. package/dist/points-lines/prepare.d.ts +67 -0
  513. package/dist/points-lines/prepare.d.ts.map +1 -0
  514. package/dist/points-lines/record.d.ts +60 -0
  515. package/dist/points-lines/record.d.ts.map +1 -0
  516. package/dist/points-lines/snapshot.d.ts +49 -0
  517. package/dist/points-lines/snapshot.d.ts.map +1 -0
  518. package/dist/post-process-errors.d.ts +182 -0
  519. package/dist/post-process-errors.d.ts.map +1 -0
  520. package/dist/prepare/prepared-graphics-resolver.d.ts +59 -0
  521. package/dist/prepare/prepared-graphics-resolver.d.ts.map +1 -0
  522. package/dist/record/__tests__/material-bg-cache.unit.test.d.ts +2 -0
  523. package/dist/record/__tests__/material-bg-cache.unit.test.d.ts.map +1 -0
  524. package/dist/record/__tests__/material-slot-plan.unit.test.d.ts +2 -0
  525. package/dist/record/__tests__/material-slot-plan.unit.test.d.ts.map +1 -0
  526. package/dist/record/__tests__/typed-frame-graph-plan.unit.test.d.ts +2 -0
  527. package/dist/record/__tests__/typed-frame-graph-plan.unit.test.d.ts.map +1 -0
  528. package/dist/record/__tests__/video-texture-view.unit.test.d.ts +2 -0
  529. package/dist/record/__tests__/video-texture-view.unit.test.d.ts.map +1 -0
  530. package/dist/record/frame-lighting.d.ts +121 -0
  531. package/dist/record/frame-lighting.d.ts.map +1 -0
  532. package/dist/record/frame-snapshot.d.ts +429 -0
  533. package/dist/record/frame-snapshot.d.ts.map +1 -0
  534. package/dist/record/frame-targets.d.ts +20 -0
  535. package/dist/record/frame-targets.d.ts.map +1 -0
  536. package/dist/record/frame.d.ts +71 -0
  537. package/dist/record/frame.d.ts.map +1 -0
  538. package/dist/record/helpers.d.ts +102 -0
  539. package/dist/record/helpers.d.ts.map +1 -0
  540. package/dist/record/main-pass-geometry.d.ts +28 -0
  541. package/dist/record/main-pass-geometry.d.ts.map +1 -0
  542. package/dist/record/main-pass-material.d.ts +204 -0
  543. package/dist/record/main-pass-material.d.ts.map +1 -0
  544. package/dist/record/main-pass-sprite-draws.d.ts +43 -0
  545. package/dist/record/main-pass-sprite-draws.d.ts.map +1 -0
  546. package/dist/record/main-pass.d.ts +20 -0
  547. package/dist/record/main-pass.d.ts.map +1 -0
  548. package/dist/record/mesh-ssbo.d.ts +446 -0
  549. package/dist/record/mesh-ssbo.d.ts.map +1 -0
  550. package/dist/record/render-context.d.ts +252 -0
  551. package/dist/record/render-context.d.ts.map +1 -0
  552. package/dist/record/shadow-pass.d.ts +52 -0
  553. package/dist/record/shadow-pass.d.ts.map +1 -0
  554. package/dist/record/skybox-post-pass.d.ts +33 -0
  555. package/dist/record/skybox-post-pass.d.ts.map +1 -0
  556. package/dist/record/typed-frame-graph.d.ts +35 -0
  557. package/dist/record/typed-frame-graph.d.ts.map +1 -0
  558. package/dist/record/view-ubo.d.ts +45 -0
  559. package/dist/record/view-ubo.d.ts.map +1 -0
  560. package/dist/render-contract.d.ts +424 -0
  561. package/dist/render-contract.d.ts.map +1 -0
  562. package/dist/render-data.d.ts +143 -0
  563. package/dist/render-data.d.ts.map +1 -0
  564. package/dist/render-graph-primitives.d.ts +76 -0
  565. package/dist/render-graph-primitives.d.ts.map +1 -0
  566. package/dist/render-pipeline.d.ts +110 -0
  567. package/dist/render-pipeline.d.ts.map +1 -0
  568. package/dist/render-system-extract.d.ts +868 -0
  569. package/dist/render-system-extract.d.ts.map +1 -0
  570. package/dist/render-system.d.ts +125 -0
  571. package/dist/render-system.d.ts.map +1 -0
  572. package/dist/scene/render-scene-types.d.ts +61 -0
  573. package/dist/scene/render-scene-types.d.ts.map +1 -0
  574. package/dist/scene/render-scene.d.ts +112 -0
  575. package/dist/scene/render-scene.d.ts.map +1 -0
  576. package/dist/scene-instances/post-spawn-resolve-joints.d.ts +30 -0
  577. package/dist/scene-instances/post-spawn-resolve-joints.d.ts.map +1 -0
  578. package/dist/shadow-atlas.d.ts +117 -0
  579. package/dist/shadow-atlas.d.ts.map +1 -0
  580. package/dist/ssao-buffers.d.ts +50 -0
  581. package/dist/ssao-buffers.d.ts.map +1 -0
  582. package/dist/ssao-config.d.ts +28 -0
  583. package/dist/ssao-config.d.ts.map +1 -0
  584. package/dist/systems/active-camera.d.ts +53 -0
  585. package/dist/systems/active-camera.d.ts.map +1 -0
  586. package/dist/systems/pass-selector.d.ts +24 -0
  587. package/dist/systems/pass-selector.d.ts.map +1 -0
  588. package/dist/systems/skin-palette-allocator.d.ts +49 -0
  589. package/dist/systems/skin-palette-allocator.d.ts.map +1 -0
  590. package/dist/systems/skin-palette-types.d.ts +14 -0
  591. package/dist/systems/skin-palette-types.d.ts.map +1 -0
  592. package/dist/systems/transparent-sort-config.d.ts +112 -0
  593. package/dist/systems/transparent-sort-config.d.ts.map +1 -0
  594. package/dist/tilemap-chunk-extract-system.d.ts +143 -0
  595. package/dist/tilemap-chunk-extract-system.d.ts.map +1 -0
  596. package/dist/typed-render-graph-primitives.d.ts +57 -0
  597. package/dist/typed-render-graph-primitives.d.ts.map +1 -0
  598. package/dist/typed-shadow-passes.d.ts +11 -0
  599. package/dist/typed-shadow-passes.d.ts.map +1 -0
  600. package/package.json +94 -0
  601. package/src/__tests__/authoring-path.unit.test.ts +23 -0
  602. package/src/__tests__/backend-selection-rhi-capture.test-d.ts +21 -0
  603. package/src/__tests__/callback-inference.test-d.ts +8 -0
  604. package/src/__tests__/cluster-binner.test.ts +272 -0
  605. package/src/__tests__/cluster-grid-default-surface.unit.test.ts +20 -0
  606. package/src/__tests__/construct-renderer-identity.unit.test.ts +23 -0
  607. package/src/__tests__/device-scope-lifecycle.unit.test.ts +151 -0
  608. package/src/__tests__/device-scope-stale-matrix.unit.test.ts +42 -0
  609. package/src/__tests__/direct-extract-consumer-contract.test-d.ts +23 -0
  610. package/src/__tests__/direct-light-snapshot.unit.test.ts +61 -0
  611. package/src/__tests__/factory-contract.integration.test.ts +280 -0
  612. package/src/__tests__/fallback-row-stride-surface.unit.test.ts +15 -0
  613. package/src/__tests__/frame-observation.contract.test.ts +112 -0
  614. package/src/__tests__/fullscreen-feature-plan.unit.test.ts +32 -0
  615. package/src/__tests__/glyph-text-layout-recovery.unit.test.ts +167 -0
  616. package/src/__tests__/gpu-driven-indirect-raster-evidence.ts +350 -0
  617. package/src/__tests__/gpu-driven-indirect-raster.browser.test.ts +12 -0
  618. package/src/__tests__/gpu-driven-indirect-raster.dawn.test.ts +16 -0
  619. package/src/__tests__/gpu-driven-production.integration.test.ts +436 -0
  620. package/src/__tests__/gpu-driven-scaling.unit.test.ts +87 -0
  621. package/src/__tests__/gpu-driven-view-gpu-evidence.ts +271 -0
  622. package/src/__tests__/gpu-driven-view-graph.integration.test.ts +290 -0
  623. package/src/__tests__/gpu-driven-view-reference.ts +111 -0
  624. package/src/__tests__/gpu-driven-view.browser.test.ts +30 -0
  625. package/src/__tests__/gpu-driven-view.dawn.test.ts +28 -0
  626. package/src/__tests__/gpu-driven-view.unit.test.ts +199 -0
  627. package/src/__tests__/gpu-resource-store-stride.unit.test.ts +59 -0
  628. package/src/__tests__/gpu-scene-render-graph-gpu.ts +308 -0
  629. package/src/__tests__/gpu-scene-render-graph.browser.test.ts +19 -0
  630. package/src/__tests__/gpu-scene-render-graph.dawn.test.ts +19 -0
  631. package/src/__tests__/gpu-scene-schema.unit.test.ts +16 -0
  632. package/src/__tests__/gpu-scene.dawn.test.ts +205 -0
  633. package/src/__tests__/gpu-scene.unit.test.ts +147 -0
  634. package/src/__tests__/ibl/face-uniforms.unit.test.ts +46 -0
  635. package/src/__tests__/infinite-grid-no-vertex-probe.unit.test.ts +92 -0
  636. package/src/__tests__/injection-kind-owner.test-d.ts +14 -0
  637. package/src/__tests__/ktx2-basis-gpu-consumer.dawn.test.ts +728 -0
  638. package/src/__tests__/light-buffer-layout.unit.test.ts +40 -0
  639. package/src/__tests__/material-contract-inventory.unit.test.ts +24 -0
  640. package/src/__tests__/material-cooked-projection.unit.test.ts +150 -0
  641. package/src/__tests__/material-snapshot-mutation.integration.test.ts +53 -0
  642. package/src/__tests__/material-static-dynamic-route.unit.test.ts +94 -0
  643. package/src/__tests__/material-stride-surface.unit.test.ts +32 -0
  644. package/src/__tests__/mesh-buffer-usage-surface.unit.test.ts +106 -0
  645. package/src/__tests__/mesh-material-bindings.unit.test.ts +89 -0
  646. package/src/__tests__/mesh-stride-surface.unit.test.ts +16 -0
  647. package/src/__tests__/morph-culling-reentry.dawn.test.ts +157 -0
  648. package/src/__tests__/morph-feature-gpu-work.integration.test.ts +80 -0
  649. package/src/__tests__/morph-feature-plan.unit.test.ts +53 -0
  650. package/src/__tests__/morph-visual-evidence.integration.test.ts +80 -0
  651. package/src/__tests__/nineslice-handle-surface.unit.test.ts +19 -0
  652. package/src/__tests__/post-process-error-policy-owner.unit.test.ts +201 -0
  653. package/src/__tests__/prepared-buffer-kind-owner.test-d.ts +29 -0
  654. package/src/__tests__/prepared-graphics-capability.unit.test.ts +65 -0
  655. package/src/__tests__/prepared-graphics-generation.unit.test.ts +161 -0
  656. package/src/__tests__/prepared-graphics-lifecycle.unit.test.ts +138 -0
  657. package/src/__tests__/prepared-graphics-pipeline-warmup.unit.test.ts +29 -0
  658. package/src/__tests__/prepared-graphics-resolver.unit.test.ts +285 -0
  659. package/src/__tests__/prepared-graphics-snapshot.unit.test.ts +105 -0
  660. package/src/__tests__/prepared-graphics-store.unit.test.ts +154 -0
  661. package/src/__tests__/prepared-graphics-validation.unit.test.ts +176 -0
  662. package/src/__tests__/profiler-default-off.test.ts +22 -0
  663. package/src/__tests__/profiler-phase-catalog.test.ts +66 -0
  664. package/src/__tests__/profiler-phase-integration.test.ts +62 -0
  665. package/src/__tests__/profiler-phase-token.test.ts +79 -0
  666. package/src/__tests__/public-surface.test-d.ts +94 -0
  667. package/src/__tests__/recover-error-policy-owner.unit.test.ts +107 -0
  668. package/src/__tests__/render-error-code-owner.test-d.ts +116 -0
  669. package/src/__tests__/render-error-detail-ssot.test-d.ts +139 -0
  670. package/src/__tests__/render-error-exhaustive.test-d.ts +110 -0
  671. package/src/__tests__/render-feature-assembly.test-d.ts +43 -0
  672. package/src/__tests__/render-feature-context.test-d.ts +57 -0
  673. package/src/__tests__/render-feature-contract.test-d.ts +49 -0
  674. package/src/__tests__/render-feature-diagnostics.unit.test.ts +149 -0
  675. package/src/__tests__/render-feature-docs.unit.test.ts +89 -0
  676. package/src/__tests__/render-feature-errors.unit.test.ts +47 -0
  677. package/src/__tests__/render-feature-gpu-work.integration.test.ts +316 -0
  678. package/src/__tests__/render-feature-plan.test-d.ts +161 -0
  679. package/src/__tests__/render-feature-plan.unit.test.ts +170 -0
  680. package/src/__tests__/render-feature-prepared-diagnostics.unit.test.ts +90 -0
  681. package/src/__tests__/render-feature-prepared-errors.test-d.ts +79 -0
  682. package/src/__tests__/render-feature-prepared-graphics-docs.unit.test.ts +80 -0
  683. package/src/__tests__/render-feature-prepared-graphics-isolation.unit.test.ts +72 -0
  684. package/src/__tests__/render-feature-prepared-graphics-negative.test-d.ts +36 -0
  685. package/src/__tests__/render-feature-prepared-graphics.test-d.ts +74 -0
  686. package/src/__tests__/render-feature-prepared-graphics.unit.test.ts +121 -0
  687. package/src/__tests__/render-feature-public-surface.test-d.ts +57 -0
  688. package/src/__tests__/render-feature-retry.unit.test.ts +87 -0
  689. package/src/__tests__/render-feature-scheduling.unit.test.ts +110 -0
  690. package/src/__tests__/render-feature-stage-failed-policy-owner.unit.test.ts +137 -0
  691. package/src/__tests__/render-feature-stage-fault-recovery.unit.test.ts +146 -0
  692. package/src/__tests__/render-feature-visibility-context.test-d.ts +33 -0
  693. package/src/__tests__/render-feature-visibility-context.unit.test.ts +37 -0
  694. package/src/__tests__/render-feature-zero-work.unit.test.ts +76 -0
  695. package/src/__tests__/render-graph-compute-raster-gpu.ts +342 -0
  696. package/src/__tests__/render-graph-compute-raster.browser.test.ts +16 -0
  697. package/src/__tests__/render-graph-compute-raster.dawn.test.ts +22 -0
  698. package/src/__tests__/render-graph-hzb-gpu.ts +239 -0
  699. package/src/__tests__/render-graph-hzb.browser.test.ts +16 -0
  700. package/src/__tests__/render-graph-hzb.dawn.test.ts +23 -0
  701. package/src/__tests__/render-graph-primitives.unit.test.ts +22 -0
  702. package/src/__tests__/render-graph-storage-indirect-gpu.ts +162 -0
  703. package/src/__tests__/render-graph-storage-indirect.browser.test.ts +21 -0
  704. package/src/__tests__/render-graph-storage-indirect.dawn.test.ts +28 -0
  705. package/src/__tests__/render-scene-projection.unit.test.ts +168 -0
  706. package/src/__tests__/renderer-factory-material-contract.unit.test.ts +121 -0
  707. package/src/__tests__/renderer-lifecycle.integration.test.ts +58 -0
  708. package/src/__tests__/rhi-backend-package-boundary.unit.test.ts +11 -0
  709. package/src/__tests__/scriptable-pack-consumer.test-d.ts +14 -0
  710. package/src/__tests__/shader-stage-surface.unit.test.ts +43 -0
  711. package/src/__tests__/ssao-config.unit.test.ts +36 -0
  712. package/src/__tests__/ssao-kernel-surface.unit.test.ts +14 -0
  713. package/src/__tests__/standard-clustered-pipeline.unit.test.ts +28 -0
  714. package/src/__tests__/standard-descriptors.test-d.ts +22 -0
  715. package/src/__tests__/standard-pipeline.dawn.test.ts +61 -0
  716. package/src/__tests__/standard-pipeline.integration.test.ts +124 -0
  717. package/src/__tests__/standard-profile-oracle.unit.test.ts +62 -0
  718. package/src/__tests__/surface-configuration.unit.test.ts +91 -0
  719. package/src/__tests__/texture-usage-surface.unit.test.ts +58 -0
  720. package/src/__tests__/typed-pipeline-topology.unit.test.ts +223 -0
  721. package/src/__tests__/urp-pipeline-targets.unit.test.ts +42 -0
  722. package/src/__tests__/urp-pipeline.unit.test.ts +14 -0
  723. package/src/__tests__/vertex-color-pipeline.unit.test.ts +132 -0
  724. package/src/__tests__/vertex-layout-consumer.unit.test.ts +25 -0
  725. package/src/__tests__/visibility-diagnostics.integration.test.ts +62 -0
  726. package/src/__tests__/visibility-extract.integration.test.ts +98 -0
  727. package/src/__tests__/visibility-extract.perf.test.ts +130 -0
  728. package/src/__tests__/visibility-feature-dedup.integration.test.ts +55 -0
  729. package/src/__tests__/visibility-hidden-report.unit.test.ts +36 -0
  730. package/src/__tests__/visibility-instances.integration.test.ts +46 -0
  731. package/src/__tests__/visibility-multi-world.integration.test.ts +86 -0
  732. package/src/__tests__/visibility-producer-matrix.integration.test.ts +168 -0
  733. package/src/__tests__/visibility-producer-matrix.unit.test.ts +96 -0
  734. package/src/__tests__/visibility-public-surface.test-d.ts +27 -0
  735. package/src/__tests__/visibility-resolver.unit.test.ts +85 -0
  736. package/src/__tests__/visibility-resource-short-circuit.unit.test.ts +80 -0
  737. package/src/__tests__/visibility-snapshot-contract.unit.test.ts +60 -0
  738. package/src/__tests__/vocabulary.unit.test.ts +21 -0
  739. package/src/assembly/backend-contract.ts +57 -0
  740. package/src/assembly/factory.ts +8130 -0
  741. package/src/assembly/host-contract.ts +101 -0
  742. package/src/assembly/material/assembly.ts +48 -0
  743. package/src/assembly/material/pipeline-projection.ts +63 -0
  744. package/src/assets/asset-decoders.ts +158 -0
  745. package/src/assets/render-asset-port.ts +44 -0
  746. package/src/assets/resolve-render-asset.ts +13 -0
  747. package/src/authoring.ts +17 -0
  748. package/src/cluster-binner.ts +700 -0
  749. package/src/components/__tests__/points-lines-admission.unit.test.ts +219 -0
  750. package/src/components/__tests__/points-lines-schema.unit.test.ts +56 -0
  751. package/src/components/__tests__/schema-contract.unit.test.ts +10 -0
  752. package/src/components/__tests__/schema-parity.unit.test.ts +25 -0
  753. package/src/components/__tests__/visibility-schema.unit.test.ts +35 -0
  754. package/src/components/camera.ts +512 -0
  755. package/src/components/directional-light.ts +120 -0
  756. package/src/components/glyph-text.ts +64 -0
  757. package/src/components/index.ts +54 -0
  758. package/src/components/instances.ts +206 -0
  759. package/src/components/layer.ts +69 -0
  760. package/src/components/light-helpers.ts +188 -0
  761. package/src/components/lines.ts +18 -0
  762. package/src/components/mesh-filter.ts +60 -0
  763. package/src/components/mesh-renderer.ts +61 -0
  764. package/src/components/point-light-shadow.ts +43 -0
  765. package/src/components/point-light.ts +65 -0
  766. package/src/components/points.ts +40 -0
  767. package/src/components/post-process-params.ts +35 -0
  768. package/src/components/scene-instance.ts +193 -0
  769. package/src/components/skybox-background.ts +103 -0
  770. package/src/components/skylight.ts +97 -0
  771. package/src/components/sort-key.ts +75 -0
  772. package/src/components/spot-light.ts +124 -0
  773. package/src/components/sprite-animation.ts +168 -0
  774. package/src/components/sprite-instances.ts +179 -0
  775. package/src/components/sprite-playback-mode.ts +79 -0
  776. package/src/components/sprite-region-override.ts +105 -0
  777. package/src/components/tile-layer.ts +167 -0
  778. package/src/components/tilemap.ts +48 -0
  779. package/src/components/visibility.ts +53 -0
  780. package/src/construct-renderer.ts +67 -0
  781. package/src/debug-draw-glue.ts +48 -0
  782. package/src/device/device-scope.ts +306 -0
  783. package/src/device/gpu-residency.ts +1822 -0
  784. package/src/device/resource-types.ts +20 -0
  785. package/src/engine-metrics.ts +82 -0
  786. package/src/errors/ecs-validation.ts +16 -0
  787. package/src/errors/index.ts +3 -0
  788. package/src/errors/recover.ts +161 -0
  789. package/src/errors/render.ts +1284 -0
  790. package/src/extract/visibility.ts +120 -0
  791. package/src/features/fullscreen.ts +46 -0
  792. package/src/features/host.ts +1363 -0
  793. package/src/features/morph/morph-feature.ts +377 -0
  794. package/src/features/plan.ts +447 -0
  795. package/src/features/prepared-gpu-work.ts +959 -0
  796. package/src/features/prepared-graphics-store.ts +449 -0
  797. package/src/features/prepared-graphics.ts +420 -0
  798. package/src/features/render-graph-compute.ts +69 -0
  799. package/src/features/render-graph-contribution.ts +75 -0
  800. package/src/features/render-graph-raster.ts +332 -0
  801. package/src/features/render-graph-resources.ts +38 -0
  802. package/src/features/targets.ts +70 -0
  803. package/src/features/types.ts +103 -0
  804. package/src/features/vocabulary.ts +24 -0
  805. package/src/fullscreen-post-process-pass.ts +363 -0
  806. package/src/glyph-text-layout-system.ts +421 -0
  807. package/src/gpu-driven/batch-topology.ts +245 -0
  808. package/src/gpu-driven/production-raster.ts +695 -0
  809. package/src/gpu-driven/view-gpu.ts +703 -0
  810. package/src/gpu-resource.ts +159 -0
  811. package/src/gpu-scene-schema.ts +136 -0
  812. package/src/gpu-scene.ts +722 -0
  813. package/src/gpu-stage.ts +9 -0
  814. package/src/gpu-texture-usage.ts +12 -0
  815. package/src/gpu-usage.ts +14 -0
  816. package/src/hdrp-buffers.ts +480 -0
  817. package/src/ibl/IblPipelineCache.ts +1006 -0
  818. package/src/ibl/skylight-bind-group.ts +513 -0
  819. package/src/index.ts +129 -0
  820. package/src/inspection-types.ts +80 -0
  821. package/src/instance-buffer-cache.ts +95 -0
  822. package/src/internal.ts +9 -0
  823. package/src/lifecycle.ts +168 -0
  824. package/src/light-buffer-layout.ts +346 -0
  825. package/src/materials.ts +214 -0
  826. package/src/mesh-material-bindings.ts +103 -0
  827. package/src/pbr-pipeline.ts +1137 -0
  828. package/src/pipeline/standard-forward-lane.ts +229 -0
  829. package/src/pipeline/standard-pipeline.ts +555 -0
  830. package/src/pipeline/standard-profile.ts +65 -0
  831. package/src/pipeline-builder.ts +382 -0
  832. package/src/pipeline-spec-types.ts +28 -0
  833. package/src/pipeline-spec.ts +1231 -0
  834. package/src/plugin.ts +69 -0
  835. package/src/points-lines/__tests__/bounds.unit.test.ts +21 -0
  836. package/src/points-lines/__tests__/cache-recovery.unit.test.ts +157 -0
  837. package/src/points-lines/__tests__/inspection-lanes.integration.test.ts +146 -0
  838. package/src/points-lines/__tests__/inspection.unit.test.ts +173 -0
  839. package/src/points-lines/__tests__/lane-structural.integration.test.ts +122 -0
  840. package/src/points-lines/__tests__/points-lines.bench.ts +400 -0
  841. package/src/points-lines/__tests__/raster-lane.integration.test.ts +44 -0
  842. package/src/points-lines/__tests__/snapshot.unit.test.ts +101 -0
  843. package/src/points-lines/__tests__/view-ubo.unit.test.ts +73 -0
  844. package/src/points-lines/admission.ts +238 -0
  845. package/src/points-lines/bounds.ts +23 -0
  846. package/src/points-lines/expansion-cache.ts +215 -0
  847. package/src/points-lines/inspection.ts +97 -0
  848. package/src/points-lines/prepare.ts +177 -0
  849. package/src/points-lines/record.ts +125 -0
  850. package/src/points-lines/snapshot.ts +130 -0
  851. package/src/post-process-errors.ts +302 -0
  852. package/src/prepare/prepared-graphics-resolver.ts +456 -0
  853. package/src/record/__tests__/material-bg-cache.unit.test.ts +41 -0
  854. package/src/record/__tests__/material-slot-plan.unit.test.ts +44 -0
  855. package/src/record/__tests__/typed-frame-graph-plan.unit.test.ts +41 -0
  856. package/src/record/__tests__/video-texture-view.unit.test.ts +90 -0
  857. package/src/record/frame-lighting.ts +1074 -0
  858. package/src/record/frame-snapshot.ts +500 -0
  859. package/src/record/frame-targets.ts +137 -0
  860. package/src/record/frame.ts +1598 -0
  861. package/src/record/helpers.ts +284 -0
  862. package/src/record/main-pass-geometry.ts +1065 -0
  863. package/src/record/main-pass-material.ts +1043 -0
  864. package/src/record/main-pass-sprite-draws.ts +1137 -0
  865. package/src/record/main-pass.ts +610 -0
  866. package/src/record/mesh-ssbo.ts +885 -0
  867. package/src/record/render-context.ts +384 -0
  868. package/src/record/shadow-pass.ts +698 -0
  869. package/src/record/skybox-post-pass.ts +593 -0
  870. package/src/record/typed-frame-graph.ts +461 -0
  871. package/src/record/view-ubo.ts +222 -0
  872. package/src/render-contract.ts +582 -0
  873. package/src/render-data.ts +385 -0
  874. package/src/render-graph-primitives.ts +811 -0
  875. package/src/render-pipeline.ts +259 -0
  876. package/src/render-system-extract.ts +4585 -0
  877. package/src/render-system.ts +1933 -0
  878. package/src/scene/render-scene-types.ts +67 -0
  879. package/src/scene/render-scene.ts +1087 -0
  880. package/src/scene-instances/post-spawn-resolve-joints.ts +165 -0
  881. package/src/shadow-atlas.ts +244 -0
  882. package/src/ssao-buffers.ts +334 -0
  883. package/src/ssao-config.ts +61 -0
  884. package/src/systems/active-camera.ts +116 -0
  885. package/src/systems/pass-selector.ts +49 -0
  886. package/src/systems/skin-palette-allocator.ts +251 -0
  887. package/src/systems/skin-palette-types.ts +14 -0
  888. package/src/systems/transparent-sort-config.ts +233 -0
  889. package/src/tilemap-chunk-extract-system.ts +1290 -0
  890. package/src/typed-render-graph-primitives.ts +541 -0
  891. package/src/typed-shadow-passes.ts +165 -0
@@ -0,0 +1,1043 @@
1
+ // @forgeax/engine-runtime - RenderSystem record stage: main-pass-material.
2
+ // Extracted from render-system-record.ts (feat-20260704 M3/w17, pure move).
3
+
4
+ import { resolveAssetHandle } from '@forgeax/engine-assets-runtime';
5
+ import type { EntityHandle, World } from '@forgeax/engine-ecs';
6
+ import {
7
+ VIDEO_ELEMENT_PROVIDER_KEY,
8
+ type VideoElementProvider,
9
+ } from '@forgeax/engine-graphics-extras';
10
+ import {
11
+ type BindGroup,
12
+ type BindGroupEntry,
13
+ type BindGroupLayout,
14
+ type Buffer,
15
+ type RenderPipeline,
16
+ RhiError,
17
+ type Sampler,
18
+ type TextureView,
19
+ } from '@forgeax/engine-rhi';
20
+ import {
21
+ DEFAULT_MSDF_TEXT_PARAM_SCHEMA,
22
+ DEFAULT_SPRITE_PARAM_SCHEMA,
23
+ DEFAULT_UNLIT_PARAM_SCHEMA,
24
+ } from '@forgeax/engine-shader';
25
+ import type {
26
+ Handle,
27
+ ImageError,
28
+ MaterialRenderState,
29
+ ParamSchemaEntry,
30
+ PrimitiveTopology,
31
+ SamplerAsset,
32
+ TextureAsset,
33
+ } from '@forgeax/engine-types';
34
+ import { derive, handleSlot, resolveMaterialTextureCoordinates } from '@forgeax/engine-types';
35
+ import type { GpuResidencyCache } from '../device/gpu-residency';
36
+ import { VideoUploadUnsupportedError } from '../errors/render';
37
+ import {
38
+ assembleMaterialWithSkylightEntries,
39
+ type EmissiveAoBindGroupResources,
40
+ type SkylightBindGroupResources,
41
+ } from '../ibl/skylight-bind-group';
42
+ import { isStandardPbrMaterialShader } from '../pbr-pipeline';
43
+ import { deriveTextureExtent } from '../render-data';
44
+ import type { MaterialSnapshot } from '../render-system-extract';
45
+ import type { BindGroupCounts, MaterialBgAssemblyCacheEntry } from './frame-snapshot';
46
+ import { extractEntryResourceHandle, getOrCreatePerEntity } from './mesh-ssbo';
47
+ import {
48
+ type PipelineState,
49
+ type RenderSystemRuntime,
50
+ STANDARD_PBR_UBO_SIZE,
51
+ } from './render-context';
52
+
53
+ // Param schemas are immutable runtime contracts: the shader registry installs
54
+ // them once and material snapshots only retain the same array reference. Keep
55
+ // the expensive pure derivation on that identity so the per-submesh record
56
+ // path does not rebuild the same UBO/texture maps for every visible material
57
+ // on every frame. A WeakMap keeps this optimization bounded by the lifetime of
58
+ // the schema owner and adds no global strong-reference lifetime.
59
+ const DERIVED_PARAM_SCHEMA_CACHE = new WeakMap<
60
+ readonly ParamSchemaEntry[],
61
+ ReturnType<typeof derive>
62
+ >();
63
+
64
+ function derivedParamSchema(schema: readonly ParamSchemaEntry[]): ReturnType<typeof derive> {
65
+ const cached = DERIVED_PARAM_SCHEMA_CACHE.get(schema);
66
+ if (cached !== undefined) return cached;
67
+ const derived = derive(schema);
68
+ DERIVED_PARAM_SCHEMA_CACHE.set(schema, derived);
69
+ return derived;
70
+ }
71
+
72
+ // feat-20260601-customizable-render-pipeline-seam M2 / w12: the former
73
+ // `RecordPassContext` (26-field full surface, including the `internals` kitchen-sink and
74
+ // the 0-consumed `skyboxCount` residual) is DELETED. The per-frame shared state injected
75
+ // into the render-graph pass execute closures is now the clean `RenderPipelineContext`
76
+ // (defined in `render-system.ts`): `internals` is gone (replaced by the named
77
+ // `assets` / `store` / `pipelineState` / `runtime` surfaces) so a pipeline author cannot
78
+ // reach the runtime kitchen-sink through the public ctx (AC-08). The graph is
79
+ // `RenderGraph<RenderPipelineContext>` so `execute(ctx)` forwards the object to each
80
+ // closure with no `as` assertion.
81
+ //
82
+ // Encoder ownership (RD-4): `ctx.encoder` is the SHARED frame encoder used by the main /
83
+ // tonemap / FXAA passes (finished + submitted once at frame end); the shadow pass opens
84
+ // its OWN encoder internally + submits independently (the runtime-side manual barrier for
85
+ // the depth write -> sample hazard).
86
+
87
+ // M1 / w7: ensureLazyTexture DELETED — GPU texture ownership moved to render-graph
88
+ // via addColorTarget + compile(device). The graph allocates transient/persistent
89
+ // render targets during the compile allocation phase; pass execute closures resolve
90
+ // TextureViews through resolve(name). PerPassResources texture slots still hold
91
+ // the last-used views for bindgroup-invalidation self-checks (D-3 physical texture
92
+ // identity), but the graph owns the create/destroy lifecycle.
93
+
94
+ /**
95
+ * Keep line primitives visible when they share a depth plane with filled
96
+ * geometry. The same topology policy is consumed by the CPU and GPU-driven
97
+ * raster lanes so a mixed mesh does not change appearance when ownership
98
+ * moves between them.
99
+ */
100
+ export function geometryRenderStateForTopology(
101
+ topology: PrimitiveTopology,
102
+ renderState: MaterialRenderState | undefined,
103
+ ): MaterialRenderState | undefined {
104
+ if (topology !== 'line-list' && topology !== 'line-strip') return renderState;
105
+ return {
106
+ ...renderState,
107
+ depthWriteEnabled: false,
108
+ depthCompare: 'less-equal',
109
+ };
110
+ }
111
+
112
+ /**
113
+ * feat-20260604-learn-render-4.10-anti-aliasing-msaa M2 / w9: pick the static
114
+ * unlit geometry pipeline handle for a (tonemapActive x msaaActive)
115
+ * combination. The four mode axes (LDR/HDR x single/MSAA) map to the 14 static
116
+ * pipeline handles built in createRenderer (7 base + 7 count=4 variants). A
117
+ * pipeline's `multisample.count` must match the colour-attachment sampleCount,
118
+ * so the count=4 variant is required whenever the camera carries
119
+ * `antialias === 'msaa'`. Returns null when the requested pipeline was not
120
+ * built (empty-manifest path / MSAA variant build failure) -- the caller fires
121
+ * a structured `shader-compile-failed` on the null-narrow.
122
+ */
123
+ // feat-20260615-pipeline-spec-ssot M6-T1: the standard-shading fallback
124
+ // selector was deleted. The pre-M6 selector silently substituted the
125
+ // boot-time URP `pipelineState.standardPipeline*` whenever the per-
126
+ // MaterialShader cache returned null and HDRP was inactive -- masking
127
+ // real PipelineSpecError build failures behind a layout-compatible-but-
128
+ // wrong PSO. Charter P3 explicit-failure now governs: a missing cache
129
+ // entry surfaces as null, and the per-submesh
130
+ // `if (smPipelineHandle === null) continue` skip-draw (which already
131
+ // covered the HDRP-active and skin-shader miss-skip paths) is the single
132
+ // uniform recovery shape across URP / HDRP / skin.
133
+
134
+ export function selectGeometryPipeline(
135
+ pipelineState: PipelineState,
136
+ tonemapActive: boolean,
137
+ msaaActive: boolean,
138
+ ): RenderPipeline | null {
139
+ if (tonemapActive) {
140
+ return msaaActive ? pipelineState.unlitPipelineHdrMsaa : pipelineState.unlitPipelineHdr;
141
+ }
142
+ return msaaActive ? pipelineState.unlitPipelineMsaa : pipelineState.unlitPipeline;
143
+ }
144
+
145
+ /**
146
+ * feat-city-glb Bug 5 (per-submesh transparency): true when EVERY submesh
147
+ * material of the entity is transparent (blend). Used by the geometry pass to
148
+ * decide whether to skip the whole entity (fully transparent → deferred to the
149
+ * blend sub-pass) vs. draw its opaque submeshes and skip only the transparent
150
+ * ones per-submesh.
151
+ *
152
+ * Falls back to the entity-level `material.transparent` when `materials` is
153
+ * absent (single-material entities / test fixtures), byte-identical to the
154
+ * pre-fix whole-entity gate.
155
+ *
156
+ * @internal
157
+ */
158
+ export function isEntityFullyTransparent(source: {
159
+ readonly material: MaterialSnapshot;
160
+ readonly materials?: readonly MaterialSnapshot[];
161
+ }): boolean {
162
+ const mats = source.materials;
163
+ if (mats === undefined || mats.length === 0) return source.material.transparent === true;
164
+ for (let j = 0; j < mats.length; j++) {
165
+ if (mats[j]?.transparent !== true) return false;
166
+ }
167
+ return true;
168
+ }
169
+
170
+ /**
171
+ * feat-city-glb Bug 5: true when the entity has at least one transparent AND at
172
+ * least one opaque submesh — i.e. it must be drawn in BOTH the geometry pass
173
+ * (opaque submeshes) and the blend sub-pass (transparent submeshes). A pure-
174
+ * opaque or pure-transparent entity returns false (handled by the whole-entity
175
+ * fast paths).
176
+ *
177
+ * @internal
178
+ */
179
+ export function entityHasTransparentSubmesh(source: {
180
+ readonly material: MaterialSnapshot;
181
+ readonly materials?: readonly MaterialSnapshot[];
182
+ }): boolean {
183
+ const mats = source.materials;
184
+ if (mats === undefined) return source.material.transparent === true;
185
+ for (let j = 0; j < mats.length; j++) {
186
+ if (mats[j]?.transparent === true) return true;
187
+ }
188
+ return false;
189
+ }
190
+
191
+ /**
192
+ * feat-20260601-device/gpu-residency-extraction M1 / D-9: resolve a texture's
193
+ * GPU view through the pull-model residency store. The three steps replace the
194
+ * pre-extraction single-call accessor on the registry:
195
+ * 1. fetch the TextureAsset POD off the registry (CPU; registry keeps PODs)
196
+ * 2. synchronously `ensureResident(handle, pod)` (first access builds the
197
+ * GPU texture + prewarmed mipmap blit; subsequent access is O(1))
198
+ * 3. return the GPU view (or undefined on POD miss / ensureResident err)
199
+ *
200
+ * Returns `undefined` when the POD is absent (handle never registered) or the
201
+ * upload fails (a structured error is fired). Callers then fall back to their
202
+ * existing placeholder view, preserving the pre-extraction fallback semantics.
203
+ */
204
+ function isImageError(error: unknown): error is ImageError {
205
+ if (typeof error !== 'object' || error === null) return false;
206
+ const code = (error as { readonly code?: unknown }).code;
207
+ return typeof code === 'string' && code.startsWith('image-');
208
+ }
209
+
210
+ export function residentTextureView(
211
+ world: World,
212
+ store: GpuResidencyCache,
213
+ runtime: RenderSystemRuntime,
214
+ handle: Handle<'TextureAsset', 'shared'>,
215
+ worldId: World | number = world,
216
+ ): TextureView | undefined {
217
+ const podRes = resolveAssetHandle<TextureAsset>(world, handle);
218
+ if (!podRes.ok) return undefined;
219
+ const residentRes = store.ensureResident(handle, podRes.value, worldId);
220
+ if (!residentRes.ok) {
221
+ // Preserve the concrete asset-capability boundary on the renderer error
222
+ // channel. In particular, WebGL2 texture-dimension refusal must not
223
+ // collapse into the later debug-pink asset-not-registered fallback.
224
+ if (residentRes.error instanceof RhiError || isImageError(residentRes.error)) {
225
+ runtime.errorRegistry.fire(residentRes.error);
226
+ }
227
+ return undefined;
228
+ }
229
+ return store.getTextureGpuView(handle, worldId);
230
+ }
231
+
232
+ function residentSampler(
233
+ world: World,
234
+ store: GpuResidencyCache,
235
+ runtime: RenderSystemRuntime,
236
+ handle: Handle<'SamplerAsset', 'shared'>,
237
+ worldId: World | number = world,
238
+ ): Sampler | undefined {
239
+ const podRes = resolveAssetHandle<SamplerAsset>(world, handle);
240
+ if (!podRes.ok) return undefined;
241
+ const residentRes = store.ensureSamplerResident(handle, podRes.value, worldId);
242
+ if (!residentRes.ok) {
243
+ runtime.errorRegistry.fire(residentRes.error);
244
+ return undefined;
245
+ }
246
+ return residentRes.value;
247
+ }
248
+
249
+ // feat-20260623-world-space-video-asset M4 / w16 (D-3): resolve the
250
+ // current-frame GPU view for a video-sourced texture field through the
251
+ // transient DynamicTextureStore, NOT the static `residentTextureView` /
252
+ // `ensureResident` cache (video never enters that switch; AC-08).
253
+ //
254
+ // Per frame: ask the host-registered VideoElementProvider (World Resource,
255
+ // D-1) for this entity's HTMLVideoElement, upload its current frame via
256
+ // `store.uploadFrame` (copyExternalImageToTexture), and return the resulting
257
+ // view. When the provider is absent / returns no element / the element has no
258
+ // decodable dimensions yet, fall back to a previously-uploaded view and
259
+ // finally to `undefined` (caller binds the default view this frame — charter
260
+ // P3 graceful, no garbage sampling). A failed GPU upload fires the structured
261
+ // RhiError on the engine channel and degrades to the default view.
262
+ //
263
+ // `highPerfAvailable` is the w17 capability probe; the high-perf
264
+ // GPUExternalTexture branch is a reserved hook (OOS-5) — when it ever becomes
265
+ // available the upload would route there. Today it is always false so the
266
+ // general copyExternalImageToTexture path is the only one taken.
267
+ type DynamicTextureStore = import('@forgeax/engine-assets-runtime').DynamicTextureStore;
268
+
269
+ type VideoUploadFailureEpisodes = Map<number, Set<number>>;
270
+
271
+ // The store is renderer-owned, so this keeps one failure episode per
272
+ // renderer/entity/clip without creating a second video system or leaking
273
+ // state across a replacement renderer.
274
+ const VIDEO_UPLOAD_FAILURE_EPISODES = new WeakMap<
275
+ DynamicTextureStore,
276
+ VideoUploadFailureEpisodes
277
+ >();
278
+
279
+ function markVideoUploadFailureEpisode(
280
+ store: DynamicTextureStore,
281
+ entityKey: number,
282
+ clip: Handle<'VideoAsset', 'shared'>,
283
+ ): boolean {
284
+ let clips = VIDEO_UPLOAD_FAILURE_EPISODES.get(store);
285
+ if (clips === undefined) {
286
+ clips = new Map();
287
+ VIDEO_UPLOAD_FAILURE_EPISODES.set(store, clips);
288
+ }
289
+ let episodes = clips.get(entityKey);
290
+ if (episodes === undefined) {
291
+ episodes = new Set();
292
+ clips.set(entityKey, episodes);
293
+ }
294
+ const clipId = handleSlot(clip);
295
+ if (episodes.has(clipId)) return false;
296
+ episodes.add(clipId);
297
+ return true;
298
+ }
299
+
300
+ function clearVideoUploadFailureEpisode(
301
+ store: DynamicTextureStore,
302
+ entityKey: number,
303
+ clip: Handle<'VideoAsset', 'shared'>,
304
+ ): void {
305
+ const clips = VIDEO_UPLOAD_FAILURE_EPISODES.get(store);
306
+ const episodes = clips?.get(entityKey);
307
+ if (episodes === undefined) return;
308
+ episodes.delete(handleSlot(clip));
309
+ if (episodes.size === 0) clips?.delete(entityKey);
310
+ if (clips?.size === 0) VIDEO_UPLOAD_FAILURE_EPISODES.delete(store);
311
+ }
312
+
313
+ export function videoTextureView(
314
+ world: World,
315
+ store: DynamicTextureStore | undefined,
316
+ runtime: RenderSystemRuntime,
317
+ entityKey: number,
318
+ clip: Handle<'VideoAsset', 'shared'>,
319
+ highPerfAvailable: boolean,
320
+ ): TextureView | undefined {
321
+ if (store === undefined) return undefined;
322
+ const provider = world.hasResource(VIDEO_ELEMENT_PROVIDER_KEY)
323
+ ? world.getResource<VideoElementProvider>(VIDEO_ELEMENT_PROVIDER_KEY)
324
+ : undefined;
325
+ const element = provider?.getElement(entityKey as EntityHandle, clip);
326
+ // AC-10 double-miss: a VideoPlayer entity can reach NEITHER upload path this
327
+ // frame — no host HTMLVideoElement (general copyExternalImageToTexture path)
328
+ // AND no high-perf GPUExternalTexture path. This is the genuine "this backend
329
+ // exposes no usable video upload path" case (no provider registered, or the
330
+ // provider yields nothing while the high-perf reserved hook is unavailable —
331
+ // OOS-5 keeps it always false today). Rather than silently binding the
332
+ // default view, fire the structured VideoUploadUnsupportedError on the engine
333
+ // error channel so an AI user can detect the dead path via `.code` / `.hint`
334
+ // (charter P3; AC-10 signal lives on the REAL per-frame upload path, not an
335
+ // orphan system). The default view is still bound this frame so the draw
336
+ // does not crash (graceful degradation), but the failure is no longer silent.
337
+ if (element === undefined && !highPerfAvailable) {
338
+ if (markVideoUploadFailureEpisode(store, entityKey, clip)) {
339
+ runtime.errorRegistry.fire(new VideoUploadUnsupportedError());
340
+ }
341
+ return store.getView(clip);
342
+ }
343
+ // D-2 / w17 high-perf reserved hook: a future GPUExternalTexture import path
344
+ // would key off `highPerfAvailable` here. It is always false today
345
+ // (importExternalTexture absent), so the general copyExternalImageToTexture
346
+ // path below is the sole route end-to-end.
347
+ if (element === undefined) {
348
+ clearVideoUploadFailureEpisode(store, entityKey, clip);
349
+ return store.getView(clip);
350
+ }
351
+ const width = element.videoWidth;
352
+ const height = element.videoHeight;
353
+ // Metadata dimensions can be non-zero before the decoder has produced a
354
+ // current frame. WebGPU rejects copyExternalImageToTexture in that window
355
+ // because the video element has no back resource yet; keep the previous
356
+ // frame/default view until HAVE_CURRENT_DATA (2) is reached.
357
+ if (width <= 0 || height <= 0 || element.readyState < 2) return store.getView(clip);
358
+ const uploaded = store.uploadFrame(clip, element, width, height);
359
+ if (uploaded === undefined) return store.getView(clip);
360
+ if (!uploaded.ok) {
361
+ runtime.errorRegistry.fire(uploaded.error);
362
+ return store.getView(clip);
363
+ }
364
+ clearVideoUploadFailureEpisode(store, entityKey, clip);
365
+ return uploaded.value;
366
+ }
367
+
368
+ // feat-20260621-learn-render-5-5-parallax M2 / w8 (D-3): the built-in
369
+ // standard-PBR user-region texture field order, used when the shader is not
370
+ // resolvable through getParamSchema (cross-worktree late-register). Mirrors
371
+ // derive(default-standard-pbr).textureFieldNames.
372
+ export const BUILTIN_USER_REGION_TEXTURE_FIELDS: readonly string[] = [
373
+ 'baseColorTexture',
374
+ 'metallicRoughnessTexture',
375
+ 'normalTexture',
376
+ 'specularTintTexture',
377
+ 'emissiveTexture',
378
+ 'occlusionTexture',
379
+ ];
380
+
381
+ const LEGACY_MATERIAL_TEXTURE_SCALE_OFFSET = 80;
382
+ const STANDARD_PBR_TEXTURE_SCALE_OFFSET = 96;
383
+ const MATERIAL_TEXTURE_SCALE_FIELDS = [
384
+ 'baseColorTexture',
385
+ 'metallicRoughnessTexture',
386
+ 'normalTexture',
387
+ 'specularTintTexture',
388
+ 'emissiveTexture',
389
+ 'occlusionTexture',
390
+ ] as const;
391
+ const LEGACY_MATERIAL_TEXTURE_SCALE_FIELDS = [
392
+ 'baseColorTexture',
393
+ 'metallicRoughnessTexture',
394
+ 'normalTexture',
395
+ 'emissiveTexture',
396
+ 'occlusionTexture',
397
+ ] as const;
398
+ const STANDARD_PBR_TEXTURE_COORDINATE_OFFSET = 96;
399
+ const STANDARD_PBR_TEXTURE_COORDINATE_STRIDE = 8;
400
+ const DEFAULT_LEGACY_TEXTURE_SCALES = new Float32Array([1, 1, 1, 1, 1, 1, 1, 1, 1, 1]);
401
+ const DEFAULT_STANDARD_TEXTURE_COORDINATES = new Float32Array([
402
+ 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0,
403
+ 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1,
404
+ ]);
405
+
406
+ /** Derives the logical-content UV scale for an uploaded material texture. */
407
+ export function materialTextureUvScale(
408
+ texture: Pick<TextureAsset, 'width' | 'height' | 'format'> | undefined,
409
+ ): readonly [number, number] {
410
+ if (texture === undefined) return [1, 1];
411
+ return deriveTextureExtent(texture.format, texture.width, texture.height).uvScale;
412
+ }
413
+
414
+ function materialTextureForField(
415
+ material: MaterialSnapshot,
416
+ field: string,
417
+ ): Handle<'TextureAsset', 'shared'> | undefined {
418
+ if (field === 'emissiveTexture') return material.emissiveTexture;
419
+ if (field === 'occlusionTexture') return material.occlusionTexture;
420
+ return material.textureHandles?.get(field);
421
+ }
422
+
423
+ /**
424
+ * Appends the engine-owned scale for every built-in material texture binding.
425
+ * Asset dimensions remain logical; this is the sole record-stage projection
426
+ * from a bound texture asset to its shader sampling coordinates.
427
+ */
428
+ type MaterialUboPayload = ArrayBuffer | Uint8Array | Float32Array;
429
+
430
+ function materialUboFloatView(payload: MaterialUboPayload): Float32Array {
431
+ if (payload instanceof Float32Array) return payload;
432
+ return payload instanceof Uint8Array
433
+ ? new Float32Array(payload.buffer, payload.byteOffset, payload.byteLength / 4)
434
+ : new Float32Array(payload);
435
+ }
436
+
437
+ export function applyMaterialTextureUvScales(
438
+ payload: MaterialUboPayload,
439
+ material: MaterialSnapshot,
440
+ world: World,
441
+ ): void {
442
+ const f32 = materialUboFloatView(payload);
443
+ const coordinateSchema = materialCoordinateSchema(material);
444
+ if (coordinateSchema !== undefined) {
445
+ const coordinateRecords = derivedParamSchema(coordinateSchema).coordinateRecords;
446
+ for (const record of coordinateRecords) {
447
+ const field = record.parameter;
448
+ const handle = materialTextureForField(material, field);
449
+ const resolvedTexture =
450
+ handle === undefined ? undefined : resolveAssetHandle<TextureAsset>(world, handle);
451
+ const texture = resolvedTexture?.ok === true ? resolvedTexture.value : undefined;
452
+ const [u, v] = materialTextureUvScale(texture);
453
+ const coordinates = resolveMaterialTextureCoordinates(
454
+ material.textureCoordinates?.get(field),
455
+ );
456
+ const offset = record.offset / 4;
457
+ f32[offset] = coordinates.transform.offset[0];
458
+ f32[offset + 1] = coordinates.transform.offset[1];
459
+ f32[offset + 2] = coordinates.transform.scale[0];
460
+ f32[offset + 3] = coordinates.transform.scale[1];
461
+ f32[offset + 4] = coordinates.set;
462
+ f32[offset + 5] = coordinates.transform.rotation;
463
+ f32[offset + 6] = u;
464
+ f32[offset + 7] = v;
465
+ }
466
+ return;
467
+ }
468
+ // Standard PBR grew two authored coat fields before the engine-owned UV
469
+ // tail. Sprite, sprite-lit, unlit, and text keep their own 80-byte tail
470
+ // position because their WGSL layouts do not carry clearcoat.
471
+ const textureScaleOffset = isStandardPbrMaterialShader(material.materialShaderId)
472
+ ? STANDARD_PBR_TEXTURE_SCALE_OFFSET
473
+ : LEGACY_MATERIAL_TEXTURE_SCALE_OFFSET;
474
+ const isStandardPbr = textureScaleOffset === STANDARD_PBR_TEXTURE_SCALE_OFFSET;
475
+ const hasTextureMetadata =
476
+ material.textureCoordinates !== undefined ||
477
+ material.textureHandles !== undefined ||
478
+ material.videoTextureFields !== undefined ||
479
+ material.baseColorTexture !== undefined ||
480
+ material.metallicRoughnessTexture !== undefined ||
481
+ material.normalTexture !== undefined ||
482
+ material.emissiveTexture !== undefined ||
483
+ material.occlusionTexture !== undefined;
484
+ if (!hasTextureMetadata) {
485
+ f32.set(
486
+ isStandardPbr ? DEFAULT_STANDARD_TEXTURE_COORDINATES : DEFAULT_LEGACY_TEXTURE_SCALES,
487
+ textureScaleOffset / 4,
488
+ );
489
+ return;
490
+ }
491
+ const fields = isStandardPbr
492
+ ? MATERIAL_TEXTURE_SCALE_FIELDS
493
+ : LEGACY_MATERIAL_TEXTURE_SCALE_FIELDS;
494
+ for (let index = 0; index < fields.length; index++) {
495
+ const field = fields[index];
496
+ if (field === undefined) continue;
497
+ const handle = materialTextureForField(material, field);
498
+ const resolved =
499
+ handle === undefined ? undefined : resolveAssetHandle<TextureAsset>(world, handle);
500
+ const texture = resolved?.ok === true ? resolved.value : undefined;
501
+ const [u, v] = materialTextureUvScale(texture);
502
+ if (isStandardPbr) {
503
+ const coordinates = material.textureCoordinates?.get(field);
504
+ const transform = coordinates?.transform;
505
+ const offset =
506
+ STANDARD_PBR_TEXTURE_COORDINATE_OFFSET / 4 + index * STANDARD_PBR_TEXTURE_COORDINATE_STRIDE;
507
+ f32[offset] = transform?.offset?.[0] ?? 0;
508
+ f32[offset + 1] = transform?.offset?.[1] ?? 0;
509
+ f32[offset + 2] = transform?.scale?.[0] ?? 1;
510
+ f32[offset + 3] = transform?.scale?.[1] ?? 1;
511
+ f32[offset + 4] = coordinates?.set ?? 0;
512
+ f32[offset + 5] = transform?.rotation ?? 0;
513
+ f32[offset + 6] = u;
514
+ f32[offset + 7] = v;
515
+ } else {
516
+ const offset = textureScaleOffset / 4 + index * 2;
517
+ f32[offset] = u;
518
+ f32[offset + 1] = v;
519
+ }
520
+ }
521
+ }
522
+
523
+ function materialCoordinateSchema(
524
+ material: MaterialSnapshot,
525
+ ): readonly ParamSchemaEntry[] | undefined {
526
+ if (material.materialParamSchema !== undefined && material.materialParamSchema.length > 0) {
527
+ return material.materialParamSchema;
528
+ }
529
+ switch (material.materialShaderId) {
530
+ case 'forgeax::default-unlit':
531
+ return DEFAULT_UNLIT_PARAM_SCHEMA;
532
+ case 'forgeax::sprite':
533
+ case 'forgeax::sprite-lit':
534
+ return DEFAULT_SPRITE_PARAM_SCHEMA;
535
+ case 'forgeax::msdf-text':
536
+ return DEFAULT_MSDF_TEXT_PARAM_SCHEMA;
537
+ default:
538
+ return undefined;
539
+ }
540
+ }
541
+
542
+ /**
543
+ * feat-20260621-learn-render-5-5-parallax M2 / w8 (D-3): ordered user-region
544
+ * texture field names for a material's bind-group assembly, derived from the
545
+ * shader's paramSchema via the `derive()` SSOT (insertion order = sampler/
546
+ * texture pair order in derive().bglEntries). Falls back to the built-in 4
547
+ * fields when the schema is unavailable.
548
+ */
549
+ export function userRegionTextureFieldOrder(
550
+ schema: Parameters<typeof derive>[0] | undefined,
551
+ ): readonly string[] {
552
+ if (schema === undefined || schema.length === 0) return BUILTIN_USER_REGION_TEXTURE_FIELDS;
553
+ const fields = [...derivedParamSchema(schema).textureFieldNames];
554
+ return fields.length === 0 ? BUILTIN_USER_REGION_TEXTURE_FIELDS : fields;
555
+ }
556
+
557
+ /**
558
+ * feat-20260621-learn-render-5-5-parallax M2 / w8: the fallback texture view
559
+ * for a user-region field when no handle is provided (graceful, charter P3).
560
+ * normalTexture decodes to a flat tangent normal; everything else (baseColor,
561
+ * MR, height, ...) uses the 1x1 white default (height white -> zero displacement).
562
+ */
563
+ export function defaultViewForUserRegionField(
564
+ field: string,
565
+ pipelineState: PipelineState,
566
+ ): TextureView {
567
+ if (field === 'normalTexture') return pipelineState.defaultNormalTextureView;
568
+ if (field === 'baseColorTexture') return pipelineState.fallbackTextureView;
569
+ return pipelineState.defaultWhiteTextureView;
570
+ }
571
+
572
+ /**
573
+ * feat-20260527-sprite-nineslice M4 / w17 (AC-16): once-per-renderable
574
+ * detection of "Transform.scale below the four 9-slice corner anchors". Pure
575
+ * helper extracted out of recordFrame so unit tests can drive it without a
576
+ * GPU device — the recordFrame loop calls this with its `transformWorld` /
577
+ * `slices` / `renderableIndex` / `seenIndices` / `metrics` arguments.
578
+ *
579
+ * The scale-vs-anchor formula mirrors plan-strategy §D-3 — the world x scale must
580
+ * accommodate `|slices.x| + |slices.z|`, and `scaleY` must accommodate
581
+ * `|slices.y| + |slices.w|`. Slices ≡ all zero is a no-op (legacy quad
582
+ * path); a breach increments `nineslice.scale-too-small` exactly once per
583
+ * `renderableIndex` per RenderSystem lifetime via the `seenIndices` Set
584
+ * (the same warn-once anchor pattern used for missing-texture sprites).
585
+ *
586
+ * @param transformWorld The entity's resolved Transform.world mat4 (16 floats column-major).
587
+ * @param slices The four anchor distances `[left, top, right, bottom]`
588
+ * (sentinel `bottom < 0` for tile mode is consumed via abs()).
589
+ * @param renderableIndex The entity index into the validated renderables list.
590
+ * @param seenIndices The per-frame-state guard Set; entries are added on increment.
591
+ * @param metrics The owner-provided EngineMetrics counter.
592
+ * @internal — exported for unit-test access (w17).
593
+ */
594
+ export function detectNineSliceScaleTooSmall(
595
+ transformWorld: Float32Array,
596
+ slices: readonly [number, number, number, number],
597
+ renderableIndex: number,
598
+ seenIndices: Set<number>,
599
+ metrics: { increment(name: string): void },
600
+ ): void {
601
+ const anyNonZero = slices[0] !== 0 || slices[1] !== 0 || slices[2] !== 0 || slices[3] !== 0;
602
+ if (!anyNonZero) return;
603
+ const sx = Math.hypot(transformWorld[0] ?? 1, transformWorld[1] ?? 0, transformWorld[2] ?? 0);
604
+ const sy = Math.hypot(transformWorld[4] ?? 0, transformWorld[5] ?? 1, transformWorld[6] ?? 0);
605
+ const horizontalAnchor = Math.abs(slices[0]) + Math.abs(slices[2]);
606
+ const verticalAnchor = Math.abs(slices[1]) + Math.abs(slices[3]);
607
+ if (sx < horizontalAnchor || sy < verticalAnchor) {
608
+ if (!seenIndices.has(renderableIndex)) {
609
+ seenIndices.add(renderableIndex);
610
+ metrics.increment('nineslice.scale-too-small');
611
+ }
612
+ }
613
+ }
614
+
615
+ /**
616
+ * Build the 128-byte Material UBO payload for a PBR / unlit material entry
617
+ * (feat-20260527-sprite-nineslice M2 / w11; D-7 regression-net helper).
618
+ *
619
+ * Byte-for-byte equivalent to the legacy hard-coded PBR write path; each
620
+ * deviation is caught by `render-system-record-pbr-ubo-stable.test.ts`.
621
+ * The schema-driven paramSnapshot overlay (feat-20260523 M9-T05; AC-14)
622
+ * positions vec4 / f32 slots onto std140 [slot0 vec4, slot1 f32 metallic,
623
+ * slot1 f32 roughness] mirroring the engine-shipped default-standard-pbr
624
+ * Material struct.
625
+ */
626
+ export function buildPbrMaterialUboPayload(material: MaterialSnapshot): Uint8Array {
627
+ const buf = new Uint8Array(STANDARD_PBR_UBO_SIZE);
628
+ writePbrMaterialUboPayload(buf, material);
629
+ return buf;
630
+ }
631
+
632
+ /**
633
+ * Write the standard material payload into caller-owned storage.
634
+ *
635
+ * The allocating wrapper above remains the byte-stable test/helper surface,
636
+ * while the frame recorder reuses one scratch slot for all materials. A
637
+ * scene with thousands of submeshes otherwise allocates one 304-byte
638
+ * Uint8Array per material per frame, creating avoidable GC pressure without
639
+ * changing GPU-visible bytes.
640
+ */
641
+ export function writePbrMaterialUboPayload(
642
+ buf: Uint8Array | Float32Array,
643
+ material: MaterialSnapshot,
644
+ ): void {
645
+ if (buf.byteLength < STANDARD_PBR_UBO_SIZE) {
646
+ throw new RangeError(
647
+ `writePbrMaterialUboPayload: expected at least ${STANDARD_PBR_UBO_SIZE} bytes, got ${buf.byteLength}`,
648
+ );
649
+ }
650
+ buf.fill(0);
651
+ const f32 = materialUboFloatView(buf);
652
+ // Layout (issue-1: channelMap split per D-8) -- byte-equivalent to the
653
+ // post-split sidecar paramSchema for default-standard-pbr (12 numeric
654
+ // entries packed std140 into one merged UBO at binding(0)).
655
+ // f32[0..3] baseColor (offset 0, vec4)
656
+ // f32[4] metallic (offset 16)
657
+ // f32[5] roughness (offset 20)
658
+ // f32[6] metallicChannel (offset 24) -- glTF 2.0 default = B = 2
659
+ // f32[7] roughnessChannel (offset 28) -- glTF 2.0 default = G = 1
660
+ // f32[8] aoChannel (offset 32) -- glTF 2.0 default = R = 0
661
+ // f32[9] extraChannel (offset 36) -- reserved = 0
662
+ // (offset 40..47 implicit pad: vec3 align=16)
663
+ // f32[12..14] emissive (offset 48, vec3)
664
+ // f32[15] emissiveIntensity (offset 60)
665
+ // f32[16] occlusionStrength (offset 64)
666
+ // f32[17] alphaCutoff (offset 68)
667
+ // f32[18] clearcoat (offset 72)
668
+ // f32[19] clearcoatRoughness (offset 76)
669
+ // f32[20..22] specularTint (offset 80, vec3)
670
+ // (offset 92..95 alignment pad)
671
+ // f32[24..71] engine-owned texture coordinate records (offset 96)
672
+ // f32[72] normalScale (offset 288)
673
+ f32[0] = material.baseColor[0] ?? 0;
674
+ f32[1] = material.baseColor[1] ?? 0;
675
+ f32[2] = material.baseColor[2] ?? 0;
676
+ f32[3] = 1;
677
+ f32[4] = material.metallic;
678
+ f32[5] = material.roughness;
679
+ // channelMap default = (B, G, R, _) per AGENTS.md + glTF 2.0
680
+ // KHR_materials_pbrSpecularGlossiness ARM packing -- now 4 independent
681
+ // f32 selectors; fragment casts each to u32 at the pick site.
682
+ f32[6] = 2; // metallicChannel <- B
683
+ f32[7] = 1; // roughnessChannel <- G
684
+ f32[8] = 0; // aoChannel <- R
685
+ f32[9] = 0; // extraChannel <- reserved
686
+ // emissive vec3 + emissiveIntensity (offset 48..63)
687
+ const em = material.emissive;
688
+ f32[12] = em?.[0] ?? 0;
689
+ f32[13] = em?.[1] ?? 0;
690
+ f32[14] = em?.[2] ?? 0;
691
+ f32[15] = material.emissiveIntensity ?? 0;
692
+ // occlusionStrength (offset 64)
693
+ f32[16] = material.occlusionStrength ?? 1;
694
+ // alphaCutoff (offset 68).
695
+ const alphaCutoff = material.paramSnapshot?.alphaCutoff;
696
+ f32[17] = typeof alphaCutoff === 'number' ? alphaCutoff : 0;
697
+ f32[18] = material.clearcoat ?? 0;
698
+ f32[19] = material.clearcoatRoughness ?? 0.5;
699
+ const specularTint = material.specularTint;
700
+ f32[20] = specularTint?.[0] ?? 1;
701
+ f32[21] = specularTint?.[1] ?? 1;
702
+ f32[22] = specularTint?.[2] ?? 1;
703
+ f32[72] = material.normalScale ?? 1;
704
+ // Schema-driven paramSnapshot overlay (feat-20260523 M9-T05, AC-14):
705
+ // for user-shaders with a paramSnapshot, project the first vec4/color
706
+ // entry onto slot 0 and the first two f32 entries onto slot 1's first
707
+ // two floats. The default-standard-pbr path lands on the same offsets
708
+ // via the explicit fields above, so the overlay is a no-op for the
709
+ // engine's stock PBR shader (charter P4 + R-H regression fence).
710
+ const paramSnap = material.paramSnapshot;
711
+ if (paramSnap !== undefined) {
712
+ const f32Snap = (name: string): number | undefined => {
713
+ const v = paramSnap[name];
714
+ return typeof v === 'number' ? v : undefined;
715
+ };
716
+ const colorSnap = (name: string): readonly number[] | undefined => {
717
+ const v = paramSnap[name];
718
+ return Array.isArray(v) && v.every((x) => typeof x === 'number')
719
+ ? (v as readonly number[])
720
+ : undefined;
721
+ };
722
+ // Walk schema in declared order, fill positional UBO slots.
723
+ const materialShaderId = material.materialShaderId;
724
+ // Note: schema lookup is the caller's job (it owns the runtime ref);
725
+ // when the helper has no access to runtime, paramSnap is consumed
726
+ // positionally without a schema walk. The inline caller (recordFrame)
727
+ // still performs the schema-driven walk and writes the overlay before
728
+ // queueing this payload, so this helper is only the byte-stable
729
+ // baseline. To preserve byte-for-byte equivalence in the helper-only
730
+ // unit-test path, the overlay pass is skipped when the helper is
731
+ // called without an external schema reference.
732
+ void materialShaderId;
733
+ void f32Snap;
734
+ void colorSnap;
735
+ }
736
+ }
737
+
738
+ /**
739
+ * Generic std140 UBO writer driven by `derive(paramSchema).uboLayout.entries`
740
+ * (feat-20260625-refactor-sprite-as-transparent-mesh M1 / w3, plan-strategy
741
+ * section 2 D-2).
742
+ *
743
+ * For each numeric entry in the schema, looks up the matching value in
744
+ * `paramSnapshot` and writes it at the std140 offset `derive` computed.
745
+ * Vec / color entries pull from `paramSnapshot[name]` as a `readonly number[]`
746
+ * (writes `min(size/4, value.length)` floats, padding with 0 if shorter for
747
+ * the field's declared width); scalar entries pull a single number.
748
+ *
749
+ * Behaviour:
750
+ * - schema or snapshot `undefined` -> no writes (caller may keep payload
751
+ * baseline).
752
+ * - missing snapshot field -> that field's bytes are left untouched
753
+ * (overlay semantics; same shape the legacy inline overlay had).
754
+ * - field type the writer cannot interpret (texture / sampler / storage_
755
+ * buffer / value-type mismatch) -> skipped silently; `derive` strips
756
+ * non-numeric entries from `uboLayout.entries` so the loop only iterates
757
+ * numeric fields.
758
+ *
759
+ * The writer reads `paramSnapshot` only -- it does NOT call
760
+ * `runtime.assets.get<MaterialAsset>` or cast `firstMaterial`. Gate R-H
761
+ * (plan-strategy section 5.6) bans those paths through
762
+ * `scripts/forgeax/check-render-record-no-material-asset-get.mjs`.
763
+ *
764
+ * standard-pbr remains byte-identical to `buildPbrMaterialUboPayload`: the
765
+ * engine's stock PBR material ships `paramSnapshot: undefined`, so this
766
+ * writer is a no-op on that path; the explicit field writes in the helper
767
+ * above cover every byte. User shaders (sprite-shaped 4 x vec4 or another
768
+ * paramSchema) get their fields written at the offsets declared by derive.
769
+ *
770
+ * @internal export-for-test (consumed inside `recordFrame` + render-system-
771
+ * record.test.ts; not part of the package's public surface).
772
+ */
773
+ export function applyParamSnapshotToUbo(
774
+ payload: MaterialUboPayload,
775
+ paramSchema: readonly ParamSchemaEntry[] | undefined,
776
+ paramSnapshot:
777
+ | Readonly<Record<string, number | readonly number[] | string | undefined>>
778
+ | undefined,
779
+ ): void {
780
+ if (paramSchema === undefined) return;
781
+ if (paramSnapshot === undefined) return;
782
+ const f32 = materialUboFloatView(payload);
783
+ const { uboLayout } = derivedParamSchema(paramSchema);
784
+ for (const entry of uboLayout.entries) {
785
+ const value = paramSnapshot[entry.name];
786
+ if (value === undefined) continue;
787
+ const f32Offset = entry.offset / 4;
788
+ const f32Width = entry.size / 4;
789
+ if (typeof value === 'number') {
790
+ // Scalar f32 / i32 / u32 -- single-slot write. (i32 / u32 still arrive
791
+ // as a JS number; the GPU side reads the four bytes as the declared
792
+ // type, so an f32 write is the correct bit pattern when the caller
793
+ // already produced an integer value.)
794
+ if (f32Width >= 1) f32[f32Offset] = value;
795
+ continue;
796
+ }
797
+ if (Array.isArray(value)) {
798
+ const arr = value as readonly number[];
799
+ const writeCount = Math.min(arr.length, f32Width);
800
+ for (let i = 0; i < writeCount; i++) {
801
+ const v = arr[i];
802
+ if (typeof v === 'number') f32[f32Offset + i] = v;
803
+ }
804
+ }
805
+ // string values (texture GUIDs) belong to texture bindings, not the
806
+ // UBO; derive's uboLayout.entries already strips non-numeric schema
807
+ // entries, so we will not see a uboLayout entry whose snapshot value
808
+ // is a string under normal flow. Skip defensively if we do.
809
+ }
810
+ }
811
+
812
+ /**
813
+ * feat-20260704 M3/w19: shared per-submesh material bind-group assembly, hoisted
814
+ * from the `buildPerSubmeshMaterialBg` closure inside recordMainPass so both the
815
+ * geometry pass and the LDR blend sub-pass (extracted to separate functions)
816
+ * call the identical layout.
817
+ *
818
+ * feat-city-glb Bug 5 (per-submesh transparency): a transparent PBR submesh
819
+ * binds the identical metallic/roughness/normal/emissive/occlusion +
820
+ * Skylight layout the geometry pass uses (the sub-pass previously bound a
821
+ * sprite-only BG, which cannot render a PBR decal). The per-frame closure state
822
+ * (runtime / pipelineState / world / store / skylightResources / the shared
823
+ * material BG cache + counters) is threaded through `deps`; the caller passes
824
+ * the per-submesh material snapshot + entityKey (video texture routing) and sets
825
+ * the dynamic UBO offset itself.
826
+ *
827
+ * @internal
828
+ */
829
+ export interface PerSubmeshMaterialBgDeps {
830
+ readonly runtime: RenderSystemRuntime;
831
+ readonly pipelineState: PipelineState;
832
+ readonly world: World;
833
+ readonly store: GpuResidencyCache;
834
+ readonly materialSlice: number;
835
+ readonly videoHighPerfAvailable: boolean;
836
+ readonly skylightResources: SkylightBindGroupResources;
837
+ readonly materialBgShared: Map<string, WeakMap<object, unknown>>;
838
+ /** Cross-frame final BG reuse keyed by the stable source material handle. */
839
+ readonly materialBgAssemblyCache: Map<string, MaterialBgAssemblyCacheEntry>;
840
+ readonly bindGroupCounts: BindGroupCounts;
841
+ }
842
+
843
+ /** @internal Exported only so buffer-generation invalidation stays regression-tested. */
844
+ export function isMaterialBgAssemblyCacheHit(
845
+ cached: MaterialBgAssemblyCacheEntry | undefined,
846
+ material: MaterialSnapshot,
847
+ materialBgl: BindGroupLayout,
848
+ materialBuffer: Buffer,
849
+ skylightResources: SkylightBindGroupResources,
850
+ materialResourceEpoch: number,
851
+ ): cached is MaterialBgAssemblyCacheEntry {
852
+ return (
853
+ cached?.material === material &&
854
+ cached.materialResourceEpoch === materialResourceEpoch &&
855
+ cached.materialBgl === materialBgl &&
856
+ cached.materialBuffer === materialBuffer &&
857
+ cached.skylightResources.irradianceView === skylightResources.irradianceView &&
858
+ cached.skylightResources.irradianceSampler === skylightResources.irradianceSampler &&
859
+ cached.skylightResources.prefilterView === skylightResources.prefilterView &&
860
+ cached.skylightResources.prefilterSampler === skylightResources.prefilterSampler &&
861
+ cached.skylightResources.brdfLutView === skylightResources.brdfLutView &&
862
+ cached.skylightResources.brdfLutSampler === skylightResources.brdfLutSampler &&
863
+ cached.skylightResources.intensityBuffer === skylightResources.intensityBuffer
864
+ );
865
+ }
866
+
867
+ export function buildPerSubmeshMaterialBg(
868
+ deps: PerSubmeshMaterialBgDeps,
869
+ submeshMaterial: MaterialSnapshot,
870
+ entityKey: number,
871
+ materialWorld: World = deps.world,
872
+ ): BindGroup {
873
+ const {
874
+ runtime,
875
+ pipelineState,
876
+ store,
877
+ materialSlice,
878
+ videoHighPerfAvailable,
879
+ skylightResources,
880
+ materialBgShared,
881
+ materialBgAssemblyCache,
882
+ bindGroupCounts,
883
+ } = deps;
884
+ const smMaterialHandle = submeshMaterial.materialHandle;
885
+ const materialCacheKey =
886
+ smMaterialHandle === undefined ? undefined : `${materialWorld.identity}:${smMaterialHandle}`;
887
+ const smHasVideoFields = (submeshMaterial.videoTextureFields?.size ?? 0) > 0;
888
+ const smShaderId = submeshMaterial.materialShaderId;
889
+ const smPerShaderBgl =
890
+ smShaderId !== undefined ? runtime.getMaterialBindGroupLayout?.(smShaderId) : undefined;
891
+ const smMaterialBgl = smPerShaderBgl ?? pipelineState.materialBindGroupLayout;
892
+ if (smMaterialHandle !== undefined && !smHasVideoFields) {
893
+ const cached =
894
+ materialCacheKey === undefined ? undefined : materialBgAssemblyCache.get(materialCacheKey);
895
+ if (
896
+ isMaterialBgAssemblyCacheHit(
897
+ cached,
898
+ submeshMaterial,
899
+ smMaterialBgl,
900
+ pipelineState.materialUniformBuffer.buffer,
901
+ skylightResources,
902
+ store.materialResourceEpoch,
903
+ )
904
+ ) {
905
+ return cached.bindGroup;
906
+ }
907
+ }
908
+ const smSchema =
909
+ submeshMaterial.materialParamSchema ??
910
+ (smShaderId !== undefined ? runtime.getParamSchema?.(smShaderId) : undefined);
911
+ // The shipped PBR shaders always own the six texture pairs declared by the
912
+ // standard shader artifact. Authored material snapshots may intentionally
913
+ // carry a compact four-field schema because emissive/occlusion are engine
914
+ // injected values, but the runtime PBR BGL still exposes bindings 9..12 for
915
+ // those pairs. Keep the record projection on the shader-owned layout so IBL
916
+ // starts at binding 13 rather than colliding with emissiveSampler.
917
+ const smUserRegionFields =
918
+ smPerShaderBgl === undefined || isStandardPbrMaterialShader(smShaderId)
919
+ ? BUILTIN_USER_REGION_TEXTURE_FIELDS
920
+ : userRegionTextureFieldOrder(smSchema);
921
+ let materialResourcesResident = true;
922
+ const smSamplerForField = (field: string | undefined): Sampler => {
923
+ const handle = field === undefined ? undefined : submeshMaterial.samplerHandles?.get(field);
924
+ if (handle === undefined) return pipelineState.defaultSampler;
925
+ const sampler = residentSampler(materialWorld, store, runtime, handle);
926
+ if (sampler === undefined) materialResourcesResident = false;
927
+ return sampler ?? pipelineState.defaultSampler;
928
+ };
929
+ const smBaseEntries: BindGroupEntry[] = [
930
+ {
931
+ binding: 0,
932
+ resource: {
933
+ kind: 'buffer' as const,
934
+ value: {
935
+ buffer: pipelineState.materialUniformBuffer.buffer,
936
+ offset: 0,
937
+ size: materialSlice,
938
+ },
939
+ },
940
+ },
941
+ ];
942
+ const smBglPairCount = smUserRegionFields.length;
943
+ for (let fi = 0; fi < smBglPairCount; fi++) {
944
+ const field = smUserRegionFields[fi];
945
+ const samplerBinding = 1 + fi * 2;
946
+ const textureBinding = samplerBinding + 1;
947
+ let smView: TextureView =
948
+ field !== undefined
949
+ ? defaultViewForUserRegionField(field, pipelineState)
950
+ : pipelineState.defaultWhiteTextureView;
951
+ const smVideoClip =
952
+ field !== undefined ? submeshMaterial.videoTextureFields?.get(field) : undefined;
953
+ if (smVideoClip !== undefined) {
954
+ const view = videoTextureView(
955
+ materialWorld,
956
+ runtime.dynamicTextureStore,
957
+ runtime,
958
+ entityKey,
959
+ smVideoClip,
960
+ videoHighPerfAvailable,
961
+ );
962
+ if (view !== undefined) smView = view;
963
+ } else {
964
+ const smHandle =
965
+ field === 'emissiveTexture'
966
+ ? submeshMaterial.emissiveTexture
967
+ : field === 'occlusionTexture'
968
+ ? submeshMaterial.occlusionTexture
969
+ : field !== undefined
970
+ ? submeshMaterial.textureHandles?.get(field)
971
+ : undefined;
972
+ if (smHandle !== undefined) {
973
+ const view = residentTextureView(materialWorld, store, runtime, smHandle);
974
+ if (view !== undefined) smView = view;
975
+ else materialResourcesResident = false;
976
+ }
977
+ }
978
+ smBaseEntries.push(
979
+ {
980
+ binding: samplerBinding,
981
+ resource: { kind: 'sampler' as const, value: smSamplerForField(field) },
982
+ },
983
+ {
984
+ binding: textureBinding,
985
+ resource: { kind: 'textureView' as const, value: smView },
986
+ },
987
+ );
988
+ }
989
+ let smEmissiveView: TextureView = pipelineState.defaultWhiteTextureView;
990
+ const smEmissiveHandle = submeshMaterial.emissiveTexture;
991
+ if (smEmissiveHandle !== undefined) {
992
+ const view = residentTextureView(materialWorld, store, runtime, smEmissiveHandle);
993
+ if (view !== undefined) smEmissiveView = view;
994
+ else materialResourcesResident = false;
995
+ }
996
+ let smOcclusionView: TextureView = pipelineState.defaultWhiteTextureView;
997
+ const smOcclusionHandle = submeshMaterial.occlusionTexture;
998
+ if (smOcclusionHandle !== undefined) {
999
+ const view = residentTextureView(materialWorld, store, runtime, smOcclusionHandle);
1000
+ if (view !== undefined) smOcclusionView = view;
1001
+ else materialResourcesResident = false;
1002
+ }
1003
+ const smEmissiveAo: EmissiveAoBindGroupResources = {
1004
+ emissiveSampler: smSamplerForField('emissiveTexture'),
1005
+ emissiveView: smEmissiveView,
1006
+ occlusionSampler: smSamplerForField('occlusionTexture'),
1007
+ occlusionView: smOcclusionView,
1008
+ };
1009
+ const smMergedEntries = assembleMaterialWithSkylightEntries(
1010
+ smBaseEntries,
1011
+ skylightResources,
1012
+ smEmissiveAo,
1013
+ );
1014
+ const smBindGroup = getOrCreatePerEntity(
1015
+ materialBgShared,
1016
+ smShaderId ?? '',
1017
+ smMergedEntries.map((e) => extractEntryResourceHandle(e)),
1018
+ 'material-shared',
1019
+ () => {
1020
+ const result = runtime.device.createBindGroup({
1021
+ label: 'pbr-material-skylight-bg',
1022
+ layout: smMaterialBgl,
1023
+ entries: smMergedEntries,
1024
+ });
1025
+ if (!result.ok) throw result.error;
1026
+ return result.value;
1027
+ },
1028
+ bindGroupCounts,
1029
+ );
1030
+ if (smMaterialHandle !== undefined && !smHasVideoFields && materialResourcesResident) {
1031
+ if (materialCacheKey !== undefined) {
1032
+ materialBgAssemblyCache.set(materialCacheKey, {
1033
+ material: submeshMaterial,
1034
+ materialResourceEpoch: store.materialResourceEpoch,
1035
+ materialBgl: smMaterialBgl,
1036
+ materialBuffer: pipelineState.materialUniformBuffer.buffer,
1037
+ skylightResources,
1038
+ bindGroup: smBindGroup,
1039
+ });
1040
+ }
1041
+ }
1042
+ return smBindGroup;
1043
+ }