@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,1065 @@
1
+ // @forgeax/engine-runtime - RenderSystem record stage: main-pass geometry draws.
2
+ // feat-20260704 M5/w31: further-split from main-pass.ts (AC-05 <=1500 lines/file).
3
+ // recordGeometryDraws + resolveGeometryInstanceBuffer, moved verbatim.
4
+
5
+ import type { World } from '@forgeax/engine-ecs';
6
+ import {
7
+ type BindGroup,
8
+ type Buffer,
9
+ type RenderPipeline,
10
+ RhiError,
11
+ type RhiRenderPassEncoder,
12
+ } from '@forgeax/engine-rhi';
13
+ import type { PassKind, PrimitiveTopology } from '@forgeax/engine-types';
14
+ import { GpuBuffer } from '../gpu-resource';
15
+ import {
16
+ GPU_BUFFER_USAGE_COPY_DST,
17
+ GPU_BUFFER_USAGE_STORAGE,
18
+ GPU_BUFFER_USAGE_UNIFORM,
19
+ } from '../gpu-usage';
20
+ import type { InstanceBufferCacheEntry } from '../instance-buffer-cache';
21
+ import { SPRITE_PREMULTIPLIED_ALPHA_BLEND } from '../materials';
22
+ import { SKIN_MATERIAL_SHADER_ID } from '../pbr-pipeline';
23
+ import { renderStateHash, variantSetFromVertexLayoutProjection } from '../pipeline-spec';
24
+ import type { PointsLinesRecordPlan } from '../points-lines/record';
25
+ import { POINTS_LINES_MATERIAL_SHADER_ID } from '../points-lines/record';
26
+ import type { RenderRecordPhase } from '../render-contract';
27
+ import type { MaterialSnapshot } from '../render-system-extract';
28
+ import { worldEntityKey } from './frame-snapshot';
29
+ import {
30
+ geometryRenderStateForTopology,
31
+ isEntityFullyTransparent,
32
+ selectGeometryPipeline,
33
+ } from './main-pass-material';
34
+ import {
35
+ getOrCreateFromChain,
36
+ INSTANCE_UBO_FULL_ARRAY_BYTES,
37
+ MAX_UNIFORM_INSTANCES,
38
+ MESH_PER_ENTITY_STRIDE,
39
+ MESH_SSBO_BYTES,
40
+ MESH_UBO_FULL_ARRAY_BYTES,
41
+ packInstanceStorageBuffer,
42
+ } from './mesh-ssbo';
43
+ import type { _InternalRenderPipelineContext } from './render-context';
44
+ import { MATERIAL_PER_ENTITY_STRIDE } from './render-context';
45
+ import { POINTS_LINES_VIEW_SLOT_STRIDE, writePointsLinesViewUbo } from './view-ubo';
46
+
47
+ type GeometryInstanceDraw = {
48
+ readonly instanceBuffer: Buffer;
49
+ readonly instanceBindGroup: BindGroup;
50
+ readonly instanceCount: number;
51
+ };
52
+
53
+ type GeometryBindingState = {
54
+ pipeline: RenderPipeline | null;
55
+ instancesBuffer: Buffer | null;
56
+ };
57
+
58
+ type MaterialPipelineLookup = {
59
+ readonly materialShaderId: string;
60
+ readonly tonemapActive: boolean;
61
+ readonly renderStateKey: string;
62
+ readonly topology: PrimitiveTopology;
63
+ readonly indexFormat: 'uint16' | 'uint32';
64
+ readonly variantSet: string | undefined;
65
+ readonly passKind: PassKind;
66
+ readonly layoutProjection: import('@forgeax/engine-geometry').VertexLayoutProjection;
67
+ readonly sampleCount: number;
68
+ readonly colorFormatOverride: GPUTextureFormat | undefined;
69
+ readonly handle: RenderPipeline | null;
70
+ };
71
+
72
+ type GeometryRecordProfileSegment = 'material-bind-groups' | 'pipeline-selection' | 'draw-submit';
73
+
74
+ function geometryRecordPhase(
75
+ passKind: PassKind,
76
+ segment: GeometryRecordProfileSegment,
77
+ ): RenderRecordPhase {
78
+ const pass = passKind === 'deferred' ? 'g-buffer' : 'forward';
79
+ return `record/graph-execute/${pass}/${segment}` as RenderRecordPhase;
80
+ }
81
+
82
+ function profileGeometrySegment<T>(
83
+ c: _InternalRenderPipelineContext,
84
+ passKind: PassKind,
85
+ segment: GeometryRecordProfileSegment,
86
+ action: () => T,
87
+ ): T {
88
+ const profilePhase = c.profilePhase;
89
+ return profilePhase === undefined
90
+ ? action()
91
+ : profilePhase(geometryRecordPhase(passKind, segment), action);
92
+ }
93
+
94
+ function submitSubmeshDraws(
95
+ pass: RhiRenderPassEncoder,
96
+ state: GeometryBindingState,
97
+ pipeline: RenderPipeline,
98
+ instanceDraws: readonly GeometryInstanceDraw[],
99
+ indexed: boolean,
100
+ indexCount: number,
101
+ vertexCount: number,
102
+ indexOffset: number,
103
+ ): void {
104
+ if (state.pipeline !== pipeline) {
105
+ pass.setPipeline(pipeline);
106
+ state.pipeline = pipeline;
107
+ }
108
+ for (const instanceDraw of instanceDraws) {
109
+ if (instanceDraw.instanceBuffer !== state.instancesBuffer) {
110
+ pass.setBindGroup(3, instanceDraw.instanceBindGroup);
111
+ state.instancesBuffer = instanceDraw.instanceBuffer;
112
+ }
113
+ if (indexed) {
114
+ pass.drawIndexed(indexCount, instanceDraw.instanceCount, indexOffset, 0, 0);
115
+ } else {
116
+ pass.draw(vertexCount, instanceDraw.instanceCount, 0, 0);
117
+ }
118
+ }
119
+ }
120
+
121
+ /**
122
+ * Issues a prepared Points/Lines draw into the already-open geometry pass.
123
+ * Pass lifetime, attachments, bind groups, and submission remain owned by the
124
+ * existing main-pass interpreter.
125
+ */
126
+ export function recordPointsLinesDraw(
127
+ pass: RhiRenderPassEncoder,
128
+ plan: PointsLinesRecordPlan,
129
+ ): void {
130
+ if (plan.drawCount === 0) return;
131
+ if (plan.indexCount > 0) {
132
+ pass.drawIndexed(plan.indexCount, 1, 0, 0, 0);
133
+ return;
134
+ }
135
+ pass.draw(plan.vertexCount, 1, 0, 0);
136
+ }
137
+
138
+ /**
139
+ * feat-20260704 M3/w19: per-entity geometry (main colour) draw loop, extracted
140
+ * verbatim from recordMainPass. Walks `c.validatedOrdered`, selects the
141
+ * per-entity / per-submesh PBR / unlit / skin pipeline, uploads the per-submesh
142
+ * material UBO slices, binds view / material / mesh / instances bind groups, and
143
+ * issues the per-submesh draws into the already-begun geometry `pass`. Fully-
144
+ * transparent entities are skipped here (drawn in the LDR blend sub-pass);
145
+ * mixed meshes draw their opaque submeshes here and skip transparent submeshes.
146
+ * The pass-selector match set, per-entity material-slot start table, MSAA sample
147
+ * count, Standard group(2) bind group, fallback mesh group(2) bind group, and
148
+ * the shared per-submesh material BG builder are threaded in explicitly.
149
+ *
150
+ * @internal
151
+ */
152
+ export function recordGeometryDraws(
153
+ c: _InternalRenderPipelineContext,
154
+ pass: RhiRenderPassEncoder,
155
+ matchedMaterials: ReadonlyMap<number, ReadonlySet<number>> | null,
156
+ materialSlotIndices: readonly (readonly number[])[],
157
+ sampleCount: number,
158
+ meshGroup2: BindGroup | null,
159
+ meshBindGroup: BindGroup | null,
160
+ resolveMaterialBindGroup: (
161
+ materialSlot: number,
162
+ submeshMaterial: MaterialSnapshot,
163
+ entityKey: number,
164
+ materialWorld: World,
165
+ ) => BindGroup,
166
+ passKind: PassKind = 'forward',
167
+ ): void {
168
+ const {
169
+ runtime,
170
+ pipelineState,
171
+ frameState,
172
+ bindGroupCounts,
173
+ dispatchCounts,
174
+ tonemapActive,
175
+ msaaActive,
176
+ validatedOrdered,
177
+ splitLdrSprite,
178
+ viewBindGroup,
179
+ } = c;
180
+ const colorFormatOverride = c.transparentColorFormat as GPUTextureFormat | undefined;
181
+ let lastVertexBuffer: GpuBuffer | null = null;
182
+ let lastIndexBuffer: GpuBuffer | null = null;
183
+ const bindingState: GeometryBindingState = {
184
+ pipeline: null,
185
+ instancesBuffer: null,
186
+ };
187
+ const identityInstanceBuffer = pipelineState.identityInstanceBuffer;
188
+ const identityInstanceDraws: readonly GeometryInstanceDraw[] = [
189
+ {
190
+ instanceBuffer: identityInstanceBuffer,
191
+ instanceBindGroup: resolveGeometryInstancesBindGroup(c, identityInstanceBuffer),
192
+ instanceCount: 1,
193
+ },
194
+ ];
195
+ const profilePhase = c.profilePhase;
196
+ const materialGroup1DynamicOffsets = new Uint32Array(1);
197
+ const meshGroup2DynamicOffsets = [0];
198
+ const skinGroup2DynamicOffsets = [0, 0];
199
+ let lastStencilReference: number | null = null;
200
+ // feat-20260625-refactor-sprite-as-transparent-mesh M3 / w14 (D-7):
201
+ // sprite PSO selection no longer maintains a dedicated tag — the
202
+ // generic materialShaderId path covers sprite via the same per-
203
+ // MaterialShader pipeline cache PBR / unlit use. The 4-placeholder
204
+ // BG bindings (D-1 candidate b) still apply via the generic per-
205
+ // submesh BG construction below; sprite's `forgeax::sprite` shader
206
+ // module ships through the same cache key formula.
207
+ // Pipeline identity does not include material parameters or the material
208
+ // asset handle. Keying this cache by material handle therefore misses for
209
+ // every distinct asset even when all assets use the same PSO. The nested
210
+ // table keeps lookup O(1) by shader and immutable render-state identity; the
211
+ // renderer's authoritative cache still owns lifetime/invalidation, while
212
+ // this frame-local table removes the hot call/lookup overhead.
213
+ const materialPipelineLookupCache = new Map<string, Map<string, MaterialPipelineLookup[]>>();
214
+ const resolveMaterialPipeline = (
215
+ materialShaderId: string,
216
+ renderState: MaterialSnapshot['renderState'],
217
+ topology: PrimitiveTopology,
218
+ indexFormat: 'uint16' | 'uint32',
219
+ variantSet: string | undefined,
220
+ colorFormat: GPUTextureFormat | undefined,
221
+ layoutProjection: import('@forgeax/engine-geometry').VertexLayoutProjection,
222
+ ): RenderPipeline | null => {
223
+ const renderStateKey = renderStateHash(renderState);
224
+ const shaderLookupCache = materialPipelineLookupCache.get(materialShaderId);
225
+ const cachedLookups = shaderLookupCache?.get(renderStateKey);
226
+ if (cachedLookups !== undefined) {
227
+ for (const cached of cachedLookups) {
228
+ if (
229
+ cached.tonemapActive === tonemapActive &&
230
+ cached.renderStateKey === renderStateKey &&
231
+ cached.topology === topology &&
232
+ cached.indexFormat === indexFormat &&
233
+ cached.variantSet === variantSet &&
234
+ cached.passKind === passKind &&
235
+ cached.layoutProjection.digest === layoutProjection.digest &&
236
+ cached.sampleCount === sampleCount &&
237
+ cached.colorFormatOverride === colorFormat
238
+ ) {
239
+ return cached.handle;
240
+ }
241
+ }
242
+ }
243
+ const resolvedVariantSetResult = variantSetFromVertexLayoutProjection(
244
+ layoutProjection,
245
+ variantSet,
246
+ );
247
+ if (!resolvedVariantSetResult.ok) {
248
+ runtime.errorRegistry.fire(resolvedVariantSetResult.error);
249
+ return null;
250
+ }
251
+ const resolvedVariantSet = resolvedVariantSetResult.value;
252
+ const resolvePipeline = () =>
253
+ runtime.getMaterialShaderPipeline?.(
254
+ materialShaderId,
255
+ tonemapActive,
256
+ renderState,
257
+ topology,
258
+ indexFormat,
259
+ resolvedVariantSet,
260
+ passKind,
261
+ undefined,
262
+ sampleCount,
263
+ colorFormat,
264
+ undefined,
265
+ undefined,
266
+ undefined,
267
+ layoutProjection,
268
+ ) ?? null;
269
+ const handle =
270
+ profilePhase === undefined
271
+ ? resolvePipeline()
272
+ : profileGeometrySegment(c, passKind, 'pipeline-selection', resolvePipeline);
273
+ const nextLookup: MaterialPipelineLookup = {
274
+ materialShaderId,
275
+ tonemapActive,
276
+ renderStateKey,
277
+ topology,
278
+ indexFormat,
279
+ variantSet,
280
+ passKind,
281
+ layoutProjection,
282
+ sampleCount,
283
+ colorFormatOverride: colorFormat,
284
+ handle,
285
+ };
286
+ if (shaderLookupCache === undefined) {
287
+ materialPipelineLookupCache.set(materialShaderId, new Map([[renderStateKey, [nextLookup]]]));
288
+ } else if (cachedLookups === undefined) {
289
+ shaderLookupCache.set(renderStateKey, [nextLookup]);
290
+ } else {
291
+ cachedLookups.push(nextLookup);
292
+ }
293
+ return handle;
294
+ };
295
+
296
+ for (let i = 0; i < validatedOrdered.length; i++) {
297
+ const entry = validatedOrdered[i];
298
+ if (entry === undefined) continue;
299
+
300
+ // Points/Lines share the Standard geometry pass. Their retained source
301
+ // is prepared once by the renderer owner, while this loop remains the
302
+ // sole pass/draw submission owner and preserves the authored topology.
303
+ const pointsLinesSubmission = c.pointsLines?.prepare(entry, frameState.isHdrpActive);
304
+ if (entry.source.pointsLines !== undefined && pointsLinesSubmission?.plan.drawCount !== 1)
305
+ continue;
306
+
307
+ if (
308
+ passKind === 'forward' &&
309
+ c.gpuDrivenEntityKeys.has(worldEntityKey(entry.source.worldId, entry.source.entityKey))
310
+ ) {
311
+ continue;
312
+ }
313
+
314
+ // feat-20260609 M2: skip entities that don't match the pass selector.
315
+ if (matchedMaterials !== null && !matchedMaterials.has(entry.renderableIndex)) continue;
316
+
317
+ // D-2 generalised feat-20260625 M2 / w7: transparent entities are
318
+ // dispatched in the separate sub-pass (bgra8unorm unorm view,
319
+ // loadOp=load) so they must NOT be drawn here in the geometry pass
320
+ // (bgra8unorm-srgb sRGB view, loadOp=clear). In the HDR path
321
+ // (tonemapActive=true) or when there are no transparent entries,
322
+ // splitLdrSprite=false and this guard is a no-op. Post-w13 the
323
+ // legacy shadingModel arm is gone; transparent is the single SSOT
324
+ // mirrored on `computeSplitLdrSprite`.
325
+ //
326
+ // feat-city-glb Bug 5 (per-submesh transparency): only skip the WHOLE
327
+ // entity here when EVERY submesh is transparent (the sprite / fully-
328
+ // transparent-mesh fast path, byte-identical to the pre-fix behavior for
329
+ // single-material entities). A mixed mesh (opaque road submesh + BLEND
330
+ // decal submesh) is NOT skipped at the entity level; its opaque submeshes
331
+ // draw here and the per-submesh loop below skips the transparent ones
332
+ // (they are drawn in the blend sub-pass instead).
333
+ if (splitLdrSprite && isEntityFullyTransparent(entry.source)) continue;
334
+
335
+ const pipelineTag: 'unlit' = 'unlit';
336
+
337
+ // w10: setStencilReference per draw when the dispatch entry carries
338
+ // a stencil reference value (plan-strategy D-3: draw-call dynamic
339
+ // state after setPipeline). Defaults to 0 when no reference is set
340
+ // (WebGPU stencil reference default, semantically a no-op).
341
+ const stencilReference = entry.stencilReference ?? 0;
342
+ if (stencilReference !== lastStencilReference) {
343
+ pass.setStencilReference(stencilReference);
344
+ lastStencilReference = stencilReference;
345
+ }
346
+
347
+ if (pointsLinesSubmission !== undefined && entry.source.pointsLines !== undefined) {
348
+ const pointsLinesMaterial: MaterialSnapshot = {
349
+ ...entry.source.material,
350
+ materialShaderId: POINTS_LINES_MATERIAL_SHADER_ID,
351
+ materialParamSchema:
352
+ runtime.getParamSchema?.(POINTS_LINES_MATERIAL_SHADER_ID) ??
353
+ entry.source.material.materialParamSchema,
354
+ };
355
+ const materialSlot = materialSlotIndices[i]?.[0] ?? 0;
356
+ const pointsLinesBindGroup = resolveMaterialBindGroup(
357
+ materialSlot,
358
+ pointsLinesMaterial,
359
+ entry.source.entityKey,
360
+ entry.world ?? c.world,
361
+ );
362
+ const pointsLinesPipeline = resolveMaterialPipeline(
363
+ POINTS_LINES_MATERIAL_SHADER_ID,
364
+ {
365
+ ...pointsLinesMaterial.renderState,
366
+ cullMode: 'none',
367
+ },
368
+ 'triangle-list',
369
+ 'uint32',
370
+ undefined,
371
+ colorFormatOverride,
372
+ pointsLinesSubmission.layoutProjection,
373
+ );
374
+ if (pointsLinesPipeline === null) continue;
375
+ if (pipelineState.pointsLinesViewBuffer === undefined) continue;
376
+ writePointsLinesViewUbo(
377
+ runtime.device.queue,
378
+ pipelineState.pointsLinesViewBuffer,
379
+ c.camera,
380
+ c.targetW,
381
+ c.targetH,
382
+ entry.source.transform.world,
383
+ entry.source.pointsLines.style,
384
+ i * POINTS_LINES_VIEW_SLOT_STRIDE,
385
+ );
386
+ pass.setBindGroup(
387
+ 0,
388
+ viewBindGroup as BindGroup,
389
+ new Uint32Array([i * POINTS_LINES_VIEW_SLOT_STRIDE]),
390
+ 0,
391
+ 1,
392
+ );
393
+ pass.setPipeline(pointsLinesPipeline);
394
+ pass.setVertexBuffer(0, pointsLinesSubmission.vertexBuffer);
395
+ pass.setIndexBuffer(pointsLinesSubmission.indexBuffer, 'uint32');
396
+ materialGroup1DynamicOffsets[0] = materialSlot * MATERIAL_PER_ENTITY_STRIDE;
397
+ pass.setBindGroup(1, pointsLinesBindGroup, materialGroup1DynamicOffsets, 0, 1);
398
+ const pointsLinesMeshGroup = meshBindGroup ?? meshGroup2;
399
+ if (pointsLinesMeshGroup === null) continue;
400
+ pass.setBindGroup(2, pointsLinesMeshGroup, meshGroup2DynamicOffsets);
401
+ pass.setBindGroup(
402
+ 3,
403
+ identityInstanceDraws[0]?.instanceBindGroup ??
404
+ resolveGeometryInstancesBindGroup(c, identityInstanceBuffer),
405
+ );
406
+ recordPointsLinesDraw(pass, pointsLinesSubmission.plan);
407
+ pass.setBindGroup(0, viewBindGroup as BindGroup, [0]);
408
+ continue;
409
+ }
410
+
411
+ if (entry.mesh.vertexBuffer !== lastVertexBuffer) {
412
+ pass.setVertexBuffer(0, entry.mesh.vertexBuffer.handle);
413
+ lastVertexBuffer = entry.mesh.vertexBuffer;
414
+ }
415
+ // feat-20260604 M4 / w11: vertex-only meshes (indexed === false) carry no
416
+ // index buffer; skip setIndexBuffer entirely and dispatch via pass.draw
417
+ // below. Indexed meshes keep the existing setIndexBuffer path unchanged.
418
+ if (entry.mesh.indexed && entry.mesh.indexBuffer !== lastIndexBuffer) {
419
+ if (entry.mesh.indexBuffer !== null) {
420
+ pass.setIndexBuffer(entry.mesh.indexBuffer.handle, entry.mesh.indexFormat);
421
+ lastIndexBuffer = entry.mesh.indexBuffer;
422
+ }
423
+ }
424
+
425
+ // Dispatch counter bump — sprite folds into the same 2-bucket
426
+ // surface for now (`pipelineDispatchCounts.{unlit, standard}`
427
+ // mirror the original 2-pipeline scope; sprite-bucket counters
428
+ // can land in a follow-up if AI users need them separately).
429
+ // sprite entries do not bump either counter — the bench (M-4)
430
+ // can read sprite render counts via the transparent bucket
431
+ // length instead.
432
+ if (pipelineTag === 'unlit') dispatchCounts.unlit += 1;
433
+
434
+ const instanceDraws = resolveGeometryInstanceBuffer(c, entry, identityInstanceDraws);
435
+ if (instanceDraws === null) continue;
436
+
437
+ // feat-20260611 R2 / M8 / w28 (IS-14): skin entries need a 2-binding
438
+ // group(2) BG matching `pbr-skin-pl` (binding 0 mesh-array UBO +
439
+ // binding 1 palette UBO). Building this here -- not in the
440
+ // `meshBindGroup` factory above -- because the binding-shape
441
+ // (1-entry vs 2-entry) is per-entry, not per-frame. URP / HDRP
442
+ // entries keep using `meshGroup2` (1-entry mesh-array or HDRP
443
+ // unified). The skin-variant cache key includes both buffer
444
+ // identities so a future allocator-driven palette buffer rotation
445
+ // invalidates the BG without manual eviction.
446
+ //
447
+ // PSO-availability gate: only swap to the skin BG when (a) the
448
+ // skin pipeline layout itself was built (charter P3 fail-stop on
449
+ // BGL-build failure), AND (b) the skin PSO cache returns a non-null
450
+ // pipeline for this entry. Without (b), the per-submesh selector
451
+ // below falls back to URP `standardPipeline` (`pbr-pl` layout,
452
+ // 1-entry mesh-array BGL); binding the 2-entry skin BG against
453
+ // that pipeline reproduces the exact `pbr-mesh-array-bgl ... does
454
+ // not match layout pbr-skin-mesh-array-bgl` device error R1
455
+ // captured. Mirrors the uniform null skip-draw pattern (M6-T1).
456
+ let group2BindGroup: BindGroup = meshGroup2 as BindGroup;
457
+ // feat-20260612-skin-palette-per-frame-upload M3 / m3-2: dyn-offset
458
+ // tuple follows the skin group2 offset contract. Defaults to the
459
+ // length-1 non-skin shape; the skin branch below re-computes with the
460
+ // per-entity `entry.source.skin.byteOffset` cursor.
461
+ meshGroup2DynamicOffsets[0] = i * MESH_PER_ENTITY_STRIDE;
462
+ let group2DynamicOffsets: readonly number[] = meshGroup2DynamicOffsets;
463
+ const isSkinEntry = entry.source.skin !== undefined;
464
+ // feat-20260612-skin-palette-per-frame-upload M1 / m1-3 + M6: the
465
+ // record stage reads the GPU buffer reference through
466
+ // `entry.source.skin.buffer` (per-slice carrier set at extract time
467
+ // by allocateSlice). On the storage path every slice carries the
468
+ // same shared buffer pointer, so the BG cache key collapses to one
469
+ // entry per frame (miss=1 + hit=N-1). On the uniform fallback path
470
+ // each slice carries its own per-entity 16320 B UBO, so the BG
471
+ // cache key naturally splits per entity (one BG per buffer pointer)
472
+ // -- there is no shared-buffer assumption to break under
473
+ // 16 KiB UBO cap. Charter P3 explicit failure preserved: skin
474
+ // entries skip when the pipeline layout is missing OR the slice
475
+ // failed to allocate (no buffer field). dynOffset[1] = byteOffset
476
+ // is 0 on the uniform path (entry already covers the full buffer)
477
+ // and walks 0, 1536, 3072, ... on the storage path.
478
+ const skinAllocator = pipelineState.skinPaletteAllocator;
479
+ const skinSlice = entry.source.skin;
480
+ const skinResources =
481
+ isSkinEntry &&
482
+ pipelineState.pbrSkinMeshBindGroupLayout !== null &&
483
+ skinAllocator !== null &&
484
+ skinSlice !== undefined
485
+ ? {
486
+ meshArrayBgl: pipelineState.pbrSkinMeshBindGroupLayout,
487
+ paletteBuffer: skinSlice.buffer,
488
+ paletteBindingWindowBytes: skinAllocator.bindingWindowBytes,
489
+ }
490
+ : null;
491
+ // Probe the skin PSO cache up front so we can decide whether to swap
492
+ // to the 2-binding skin BG. The same probe + selector is repeated in
493
+ // the per-submesh loop below (the loop's variantSet derivation is
494
+ // identical -- skin shader registers a single all-true variant so
495
+ // the canonical empty-key rule applies on HDRP and the URP key is
496
+ // the explicit expanded form, mirroring the standard PBR path).
497
+ const skinVariantSetResult = variantSetFromVertexLayoutProjection(
498
+ entry.mesh.layoutProjection,
499
+ frameState.isHdrpActive
500
+ ? ''
501
+ : 'CLUSTER_FORWARD_AVAILABLE=false+STORAGE_BUFFER_AVAILABLE=true',
502
+ );
503
+ if (!skinVariantSetResult.ok) runtime.errorRegistry.fire(skinVariantSetResult.error);
504
+ const skinVariantSet = skinVariantSetResult.ok ? skinVariantSetResult.value : undefined;
505
+ const skinPsoProbe =
506
+ skinResources !== null && skinVariantSetResult.ok
507
+ ? (runtime.getMaterialShaderPipeline?.(
508
+ SKIN_MATERIAL_SHADER_ID,
509
+ tonemapActive,
510
+ entry.source.material.renderState,
511
+ entry.mesh.submeshes[0]?.topology ?? 'triangle-list',
512
+ entry.mesh.indexFormat,
513
+ skinVariantSet,
514
+ passKind,
515
+ undefined, // meshAttributes — skin probe uses first submesh, derive from entry
516
+ sampleCount,
517
+ colorFormatOverride,
518
+ undefined,
519
+ undefined,
520
+ undefined,
521
+ entry.mesh.layoutProjection,
522
+ ) ?? null)
523
+ : null;
524
+ if (skinResources !== null && skinPsoProbe !== null) {
525
+ const meshBindSize = runtime.device.caps.storageBuffer
526
+ ? MESH_SSBO_BYTES
527
+ : MESH_UBO_FULL_ARRAY_BYTES;
528
+ // m3-2 / D-8: skin BG cache miss / hit instrumentation. The chain
529
+ // walk no longer exposes a string key to `.has()`, so we derive
530
+ // hit/miss from the w7 `bindGroupCounts.createBindGroup` accounting:
531
+ // snapshot the counter, run `getOrCreateFromChain`, and compare. A
532
+ // delta of 1 means the factory ran (miss); 0 means a chain hit. This
533
+ // publishes the per-frame counter the m3-1 acceptanceCheck reads
534
+ // (miss=1 + hit=N-1 across N skin entries sharing one allocator
535
+ // buffer + mesh SSBO). Field is optional + opt-in (read via
536
+ // structural cast so prod paths that omit the counter pay nothing).
537
+ const skinStats = (pipelineState as { _skinBgCacheStats?: { miss: number; hit: number } })
538
+ ._skinBgCacheStats;
539
+ const skinMissesBefore = bindGroupCounts.createBindGroup;
540
+ const skinBindGroup: BindGroup = getOrCreateFromChain(
541
+ frameState.meshBindGroupCache,
542
+ [pipelineState.meshStorageBuffer.buffer, skinResources.paletteBuffer],
543
+ 'pbr-skin-mesh',
544
+ () => {
545
+ const result = runtime.device.createBindGroup({
546
+ label: 'pbr-skin-mesh-bg',
547
+ layout: skinResources.meshArrayBgl,
548
+ entries: [
549
+ {
550
+ binding: 0,
551
+ resource: {
552
+ kind: 'buffer',
553
+ value: {
554
+ buffer: pipelineState.meshStorageBuffer.buffer,
555
+ offset: 0,
556
+ size: meshBindSize,
557
+ },
558
+ },
559
+ },
560
+ {
561
+ binding: 1,
562
+ resource: {
563
+ kind: 'buffer',
564
+ value: {
565
+ buffer: skinResources.paletteBuffer,
566
+ offset: 0,
567
+ // M6 SSOT: static BG entry size (= MAX_JOINTS * 64 =
568
+ // 16320 B) sourced from the allocator. The per-draw
569
+ // window slides via `group2DynamicOffsets[1]`
570
+ // (= entry.source.skin.byteOffset) so this size
571
+ // stays at the worst case across all skin entries
572
+ // -- one BG covers every skinned draw in the frame
573
+ // (m3-1b miss=1 + hit=N-1 contract). The allocator
574
+ // guarantees `buffer.size >= byteOffset + this size`
575
+ // so dynOffset[1] passes WebGPU validation.
576
+ size: skinResources.paletteBindingWindowBytes,
577
+ },
578
+ },
579
+ },
580
+ ],
581
+ });
582
+ if (!result.ok) throw result.error;
583
+ return result.value;
584
+ },
585
+ bindGroupCounts,
586
+ );
587
+ if (skinStats !== undefined) {
588
+ if (bindGroupCounts.createBindGroup > skinMissesBefore) skinStats.miss += 1;
589
+ else skinStats.hit += 1;
590
+ }
591
+ group2BindGroup = skinBindGroup;
592
+ // m3-2: dyn-offset tuple uses the per-entity palette cursor M2 m2-6
593
+ // wrote at the extract stage.
594
+ // Replaces the prior PR #353 hard-coded `0` second slot -- every
595
+ // skin entry now points the palette window at its own slice while
596
+ // sharing the worst-case BG entry size above.
597
+ skinGroup2DynamicOffsets[0] = i * MESH_PER_ENTITY_STRIDE;
598
+ skinGroup2DynamicOffsets[1] = entry.source.skin?.byteOffset ?? 0;
599
+ group2DynamicOffsets = skinGroup2DynamicOffsets;
600
+ } else if (isSkinEntry) {
601
+ // Skin entry but skin PSO not ready (cache miss / async build pending,
602
+ // or skin pipeline layout failed at boot). Skip the draw rather than
603
+ // fall back to URP `pbr-pl` against the 6-attribute skin VBO -- that
604
+ // path produced the layer-3 / layer-4 device errors R1 captured. Once
605
+ // the async PSO compile resolves the cache hits and the next frame
606
+ // routes the skin BG + skin pipeline together. Mirrors the uniform
607
+ // null skip-draw shape (M6-T1, charter P3 explicit failure).
608
+ continue;
609
+ }
610
+ // feat-20260520-2d-sprite-layer-mvp M-3 / w25 (@fallback sprite
611
+ // bucket): sprite entries get a per-entity material BindGroup so
612
+ // each sprite carries its own texture binding at @group(1) @binding(2).
613
+ // Bindings 3..6 (metallicRoughness sampler/texture + normal
614
+ // sampler/texture) bind `pipelineState.defaultSampler` +
615
+ // `pipelineState.defaultWhiteTextureView` placeholders (D-1
616
+ // candidate b — zero new GPU resource; the 1x1 white view was
617
+ // already provisioned for unlit / standard fallback so the sprite
618
+ // path adds 4 binding references, no new resource code).
619
+ //
620
+ // Missing-texture fallback (AC-18 path 4 + R7 isolation): when the
621
+ // sprite texture has no GPU view, the binding uses
622
+ // `defaultWhiteTextureView` as the fallback texture and the
623
+ // material UBO upload above wrote debug-pink colorTint so the
624
+ // sprite is visually distinct. The warn-once + RhiError surface
625
+ // fires inside the upload loop. R7 isolation: this does NOT change
626
+ // the existing unlit / standard bucket missing-texture handling —
627
+ // those keep their silent-white fallback (a future
628
+ // `feat-future-pbr-missing-texture-fallback-explicit` will retrofit).
629
+ // bug-20260610 layer 7d: BG is per-submesh — each iteration of
630
+ // the submesh draw loop below builds (or cache-hits) a BG with
631
+ // matsForRebind[smIdx]'s 5 textureViews (baseColor / MR / normal /
632
+ // emissive / occlusion). Cache key is 14-handle-id only (entityKey
633
+ // dropped) so identical-material submeshes / entities dedup
634
+ // globally. Sprite path is unchanged (single spriteBg, sprite
635
+ // per-submesh OOS-1). The non-sprite branch leaves perSubmeshBg
636
+ // declared but null; the submesh loop reassigns it per iteration
637
+ // and the source-grep gate in skylight-fallback-path.test.ts /
638
+ // systems.unit.test.ts continues to match
639
+ // `setBindGroup\s*\(\s*1\s*,\s*perSubmeshBg\b` on the in-loop call.
640
+ // feat-20260625-refactor-sprite-as-transparent-mesh M3 / w13 (D-1
641
+ // candidate b): the sprite-specific BG construction is gone — sprite
642
+ // materials reuse the same per-submesh BG path PBR / unlit use. The
643
+ // 7-entry BGL is byte-for-byte shared (binding 0 = Material UBO,
644
+ // 1 = baseColorSampler, 2 = baseColorTexture, 3-6 = filler samplers /
645
+ // textureViews). Sprite's "no metallic/normal/emissive/occlusion
646
+ // texture" simply falls through to `defaultWhite` / `defaultNormal`
647
+ // — the same placeholders the unlit path already used. The generic
648
+ // branch below builds the per-submesh BG.
649
+ let perSubmeshBg: BindGroup | null = null;
650
+ // feat-20260608 M4 / w16: per-submesh pipeline selection + draw loop.
651
+ // Each submesh carries its own topology, so pipeline selection is per-submesh.
652
+ // Vertex/index buffers and bind groups are set once (shared across all submeshes).
653
+ // feat-20260608 M5 amend / w16-a: the material UBO bind (group=1)
654
+ // ALSO moves into the loop -- the j-th submesh sees the j-th
655
+ // material slot via dynamic offset (entitySlotStart + j) * 256.
656
+ const matsForRebind = entry.source.materials;
657
+ for (let smIdx = 0; smIdx < entry.mesh.submeshes.length; smIdx++) {
658
+ const sm = entry.mesh.submeshes[smIdx];
659
+ if (sm === undefined) continue;
660
+ const matSlotIdx = sm.materialSlot;
661
+ const submeshMaterial = matsForRebind[matSlotIdx] ?? entry.source.material;
662
+ if (matchedMaterials !== null) {
663
+ const materialHandles = matchedMaterials.get(entry.renderableIndex);
664
+ const materialHandle = submeshMaterial.materialHandle ?? 0;
665
+ if (materialHandles === undefined || !materialHandles.has(materialHandle)) continue;
666
+ }
667
+ // feat-city-glb Bug 5 (per-submesh transparency): in the LDR split, a
668
+ // transparent submesh is drawn in the blend sub-pass (non-sRGB view),
669
+ // NOT here in the sRGB geometry pass. Skip it. Opaque submeshes of the
670
+ // same (mixed) mesh still draw here. Single-material / fully-opaque
671
+ // meshes are unaffected (their submesh materials are not transparent).
672
+ if (splitLdrSprite && submeshMaterial.transparent === true) {
673
+ continue;
674
+ }
675
+ // bug-20260610 layer 7d: per-submesh BG construction. Texture
676
+ // views resolve from `matsForRebind[smIdx]` so the j-th submesh
677
+ // sees its own materials[j] textures (baseColor / MR / normal /
678
+ // emissive / occlusion). Pick slot j when materials.length covers
679
+ // smIdx; otherwise fall back to slot 0 (count-mismatch already
680
+ // filtered by extract; this guard handles the materials.length=1
681
+ // single-material path mapped over multi-submesh meshes safely).
682
+ // This BG drops entityKey: identical-texture-set submeshes
683
+ // (whether on the same entity or different ones) share one BG via
684
+ // the shaderId-outer `materialBgShared` cache. The 14 handle
685
+ // objects form the WeakMap chain and fully discriminate the
686
+ // binding state since sampler/textureView/buffer handle identities
687
+ // are stable across frames.
688
+ //
689
+ // feat-20260625-refactor-sprite-as-transparent-mesh M3 / w13:
690
+ // sprite materials now use the same per-submesh BG construction
691
+ // (the sprite-specific BG branch above is deleted; sprite per-
692
+ // submesh single-slot is still enforced via materialSlotIndices
693
+ // and the sprite-shaped paramSnapshot fills the PBR-shaped BGL
694
+ // bindings via fallback textures for the 4 unused slots).
695
+ // feat-city-glb Bug 5: per-submesh material BG assembly extracted to
696
+ // the shared `buildPerSubmeshMaterialBg` closure (also called by the
697
+ // LDR blend sub-pass). Resolves the shader's user-region textures
698
+ // (baseColor/MR/normal + a custom Nth texture), emissive/occlusion
699
+ // injection, and Skylight merge; deduped cross-entity via the
700
+ // shaderId-outer `materialBgShared` cache.
701
+ const materialSlot = materialSlotIndices[i]?.[matSlotIdx] ?? materialSlotIndices[i]?.[0] ?? 0;
702
+ perSubmeshBg =
703
+ profilePhase === undefined
704
+ ? resolveMaterialBindGroup(
705
+ materialSlot,
706
+ submeshMaterial,
707
+ entry.source.entityKey,
708
+ entry.world ?? c.world,
709
+ )
710
+ : profileGeometrySegment(c, passKind, 'material-bind-groups', () =>
711
+ resolveMaterialBindGroup(
712
+ materialSlot,
713
+ submeshMaterial,
714
+ entry.source.entityKey,
715
+ entry.world ?? c.world,
716
+ ),
717
+ );
718
+ materialGroup1DynamicOffsets[0] = materialSlot * MATERIAL_PER_ENTITY_STRIDE;
719
+ pass.setBindGroup(1, perSubmeshBg, materialGroup1DynamicOffsets, 0, 1);
720
+ const smTopology = sm.topology;
721
+ const smMaterialShaderId =
722
+ entry.source.skin !== undefined
723
+ ? SKIN_MATERIAL_SHADER_ID
724
+ : submeshMaterial.materialShaderId;
725
+ const isSpriteShader =
726
+ smMaterialShaderId === 'forgeax::sprite' || smMaterialShaderId === 'forgeax::sprite-lit';
727
+ // Preserve the dedicated sprite-pass state when the linear-LDR graph
728
+ // routes a sprite through this generic geometry path. Negative scale
729
+ // flips winding, so back-face culling would erase the quad.
730
+ const pipelineRenderState = isSpriteShader
731
+ ? {
732
+ ...submeshMaterial.renderState,
733
+ depthWriteEnabled: false,
734
+ depthCompare: 'less-equal' as const,
735
+ cullMode: 'none' as const,
736
+ blend: submeshMaterial.renderState?.blend ?? SPRITE_PREMULTIPLIED_ALPHA_BLEND,
737
+ }
738
+ : geometryRenderStateForTopology(smTopology, submeshMaterial.renderState);
739
+ let smPipelineHandle: typeof pipelineState.unlitPipeline;
740
+ if (smMaterialShaderId === undefined || smMaterialShaderId === 'forgeax::default-unlit') {
741
+ const unlitShaderId = smMaterialShaderId ?? 'forgeax::default-unlit';
742
+ const unlitProjectionVariantResult = variantSetFromVertexLayoutProjection(
743
+ entry.mesh.layoutProjection,
744
+ undefined,
745
+ );
746
+ if (!unlitProjectionVariantResult.ok) {
747
+ runtime.errorRegistry.fire(unlitProjectionVariantResult.error);
748
+ continue;
749
+ }
750
+ const unlitHasColor = unlitProjectionVariantResult.value === 'VERTEX_COLOR_AVAILABLE=true';
751
+ const unlitVariantSet = unlitHasColor
752
+ ? ''
753
+ : 'STORAGE_BUFFER_AVAILABLE=true+VERTEX_COLOR_AVAILABLE=false';
754
+ const unlitRsp = resolveMaterialPipeline(
755
+ unlitShaderId,
756
+ pipelineRenderState,
757
+ smTopology,
758
+ entry.mesh.indexFormat,
759
+ unlitVariantSet,
760
+ colorFormatOverride,
761
+ entry.mesh.layoutProjection,
762
+ );
763
+ smPipelineHandle =
764
+ unlitRsp ??
765
+ (colorFormatOverride === undefined
766
+ ? selectGeometryPipeline(pipelineState, tonemapActive, msaaActive)
767
+ : null);
768
+ } else if (smMaterialShaderId !== undefined) {
769
+ // feat-20260609 M4.5 / w38 (D-11): the variantSet handed to
770
+ // getMaterialShaderPipeline MUST mirror the boot-time
771
+ // `definesKey` rule at createRenderer.ts:2483-2485 (sortedEntries
772
+ // .every(v=>v===true) ? '' : 'A=v+...'). manifest variant.definesKey
773
+ // is `''` for the all-true variant, so HDRP (both axes true) must
774
+ // pass the canonical empty key to hit that variant via
775
+ // findVariantByKey. Passing the expanded form would produce a
776
+ // miss and silently fall back to the registered default WGSL,
777
+ // creating a layout/binding mismatch under HDRP.
778
+ //
779
+ // URP path passes the explicit expanded form because the URP
780
+ // variant's manifest definesKey IS that exact non-empty string
781
+ // (CLUSTER_FORWARD_AVAILABLE=false+STORAGE_BUFFER_AVAILABLE=true)
782
+ // -- the canonical-empty rule only applies to the all-true case.
783
+ const hasVertexColor = entry.mesh.layoutProjection.attributes.some(
784
+ (attribute) => attribute.key === 'color',
785
+ );
786
+ // The all-true HDRP variant uses the canonical empty key only when
787
+ // every variant axis is true. A plain mesh adds the geometry-owned
788
+ // VERTEX_COLOR_AVAILABLE=false axis, so retain the two capability
789
+ // axes explicitly or the selector would silently choose the URP
790
+ // group(2) layout for an HDRP cluster bind group.
791
+ const capabilityVariantSet = frameState.isHdrpActive
792
+ ? hasVertexColor
793
+ ? ''
794
+ : 'CLUSTER_FORWARD_AVAILABLE=true+STORAGE_BUFFER_AVAILABLE=true'
795
+ : 'CLUSTER_FORWARD_AVAILABLE=false+STORAGE_BUFFER_AVAILABLE=true';
796
+ const authoredVariantSet =
797
+ isSpriteShader && entry.source.spriteInstances !== undefined ? '' : entry.variantSet;
798
+ const variantSet =
799
+ authoredVariantSet === undefined
800
+ ? capabilityVariantSet
801
+ : capabilityVariantSet === ''
802
+ ? authoredVariantSet
803
+ : `${capabilityVariantSet}+${authoredVariantSet}`;
804
+ const projectionVariantSetResult = variantSetFromVertexLayoutProjection(
805
+ entry.mesh.layoutProjection,
806
+ variantSet,
807
+ );
808
+ if (!projectionVariantSetResult.ok) {
809
+ runtime.errorRegistry.fire(projectionVariantSetResult.error);
810
+ continue;
811
+ }
812
+ const cachedPipeline = resolveMaterialPipeline(
813
+ smMaterialShaderId,
814
+ pipelineRenderState,
815
+ smTopology,
816
+ entry.mesh.indexFormat,
817
+ projectionVariantSetResult.value,
818
+ colorFormatOverride,
819
+ entry.mesh.layoutProjection,
820
+ );
821
+ // feat-20260615-pipeline-spec-ssot M6-T1: cache miss resolves to
822
+ // null uniformly across URP / HDRP / skin shaders. Charter P3
823
+ // explicit failure: the pre-M6 URP-path silent fallback to the
824
+ // boot-time `pipelineState.standardPipeline*` (M4.5-followup w43)
825
+ // masked real PipelineSpecError build failures behind a
826
+ // layout-compatible-but-wrong PSO. The per-submesh
827
+ // `if (smPipelineHandle === null) continue` skip-draw (which
828
+ // already covered HDRP-active and skin miss paths) is now the
829
+ // single uniform recovery shape -- one frame of skip-draw on
830
+ // first-touch, then the cached PSO flows in once the async
831
+ // build resolves. The pre-loop skin-PSO probe still skips the
832
+ // entire entry on first-submesh probe miss; this site only
833
+ // fires on per-submesh topology variance miss.
834
+ smPipelineHandle = cachedPipeline ?? null;
835
+ } else {
836
+ smPipelineHandle = selectGeometryPipeline(pipelineState, tonemapActive, msaaActive);
837
+ }
838
+
839
+ if (smPipelineHandle === null) {
840
+ continue;
841
+ }
842
+ // Standard clustered PBR variants declare the unified cluster/SSAO
843
+ // group(2) layout. Unlit and other URP-layout materials must bind the
844
+ // ordinary mesh group instead; choosing one group for the whole pass
845
+ // makes Dawn reject an otherwise valid unlit pipeline and invalidates
846
+ // the command buffer before it reaches the surface.
847
+ const usesStandardClusterBindings = smMaterialShaderId === 'forgeax::default-standard-pbr';
848
+ if (!isSkinEntry) {
849
+ if (usesStandardClusterBindings) {
850
+ if (meshGroup2 === null) continue;
851
+ group2BindGroup = meshGroup2;
852
+ } else {
853
+ const fallbackGroup = meshBindGroup ?? meshGroup2;
854
+ if (fallbackGroup === null) continue;
855
+ group2BindGroup = fallbackGroup;
856
+ }
857
+ }
858
+ pass.setBindGroup(2, group2BindGroup, group2DynamicOffsets);
859
+
860
+ if (profilePhase === undefined) {
861
+ submitSubmeshDraws(
862
+ pass,
863
+ bindingState,
864
+ smPipelineHandle,
865
+ instanceDraws,
866
+ entry.mesh.indexed,
867
+ sm.indexCount,
868
+ sm.vertexCount,
869
+ sm.indexOffset,
870
+ );
871
+ } else {
872
+ profileGeometrySegment(c, passKind, 'draw-submit', () =>
873
+ submitSubmeshDraws(
874
+ pass,
875
+ bindingState,
876
+ smPipelineHandle,
877
+ instanceDraws,
878
+ entry.mesh.indexed,
879
+ sm.indexCount,
880
+ sm.vertexCount,
881
+ sm.indexOffset,
882
+ ),
883
+ );
884
+ }
885
+ }
886
+ }
887
+ }
888
+
889
+ /**
890
+ * Resolve the per-entity @group(3) instance buffers for the geometry pass.
891
+ *
892
+ * @internal
893
+ */
894
+ function resolveGeometryInstanceBuffer(
895
+ c: _InternalRenderPipelineContext,
896
+ entry: _InternalRenderPipelineContext['validatedOrdered'][number],
897
+ identityInstanceDraws: readonly GeometryInstanceDraw[],
898
+ ): readonly GeometryInstanceDraw[] | null {
899
+ const { runtime, pipelineState, frameState } = c;
900
+ const inst = entry.source.instances;
901
+ if (inst === undefined) return identityInstanceDraws;
902
+ let instanceBuffer: Buffer = pipelineState.identityInstanceBuffer;
903
+ let instanceCount = 1;
904
+ {
905
+ // feat-20260526-pbr-uniform-fallback-no-storage-buffer M3 / w13:
906
+ // caps.storageBuffer===false -> uniform fallback with 128-instance
907
+ // cap (128 * 64B = 8192B < WebGL2 min 16384B UBO limit).
908
+ // caps.storageBuffer===true -> existing storage buffer path unchanged.
909
+ const uniformFallback = runtime.device.caps.storageBuffer === false;
910
+ let instanceBufferUsage = GPU_BUFFER_USAGE_STORAGE | GPU_BUFFER_USAGE_COPY_DST;
911
+
912
+ if (uniformFallback && inst.instanceCount > MAX_UNIFORM_INSTANCES) {
913
+ const draws: GeometryInstanceDraw[] = [];
914
+ for (let start = 0; start < inst.instanceCount; start += MAX_UNIFORM_INSTANCES) {
915
+ const count = Math.min(MAX_UNIFORM_INSTANCES, inst.instanceCount - start);
916
+ const chunk = inst.transforms.subarray(start * 16, (start + count) * 16);
917
+ const bufRes = runtime.device.createBuffer({
918
+ size: INSTANCE_UBO_FULL_ARRAY_BYTES,
919
+ usage: GPU_BUFFER_USAGE_UNIFORM | GPU_BUFFER_USAGE_COPY_DST,
920
+ mappedAtCreation: false,
921
+ });
922
+ if (!bufRes.ok) {
923
+ runtime.errorRegistry.fire(bufRes.error);
924
+ return null;
925
+ }
926
+ const buffer = new GpuBuffer(runtime.device, bufRes.value);
927
+ frameState.transientInstanceBuffers.push({
928
+ buffer,
929
+ uploadedArchVersion: inst.archVersion,
930
+ uploadedByteLength: chunk.byteLength,
931
+ });
932
+ const writeRes = runtime.device.queue.writeBuffer(buffer.handle, 0, chunk);
933
+ if (!writeRes.ok) {
934
+ runtime.errorRegistry.fire(writeRes.error);
935
+ return null;
936
+ }
937
+ draws.push({
938
+ instanceBuffer: buffer.handle,
939
+ instanceBindGroup: resolveGeometryInstancesBindGroup(c, buffer.handle),
940
+ instanceCount: count,
941
+ });
942
+ }
943
+ return draws;
944
+ }
945
+ if (uniformFallback) {
946
+ instanceBufferUsage = GPU_BUFFER_USAGE_UNIFORM | GPU_BUFFER_USAGE_COPY_DST;
947
+ }
948
+
949
+ {
950
+ // Cap-gate (LimitExceededDetail single emit point — feat-20260514
951
+ // M3 / w15 anchor): `requestedBytes <= maxStorageBufferBindingSize`.
952
+ const instancePayload = uniformFallback
953
+ ? inst.transforms
954
+ : packInstanceStorageBuffer(inst.transforms);
955
+ const requestedBytes = instancePayload.byteLength;
956
+ const cap = runtime.device.limits.maxStorageBufferBindingSize;
957
+ if (!uniformFallback && typeof cap === 'number' && cap > 0 && requestedBytes > cap) {
958
+ runtime.errorRegistry.fire(
959
+ new RhiError({
960
+ code: 'limit-exceeded',
961
+ expected: `requestedBytes (${requestedBytes}) <= maxStorageBufferBindingSize (${cap})`,
962
+ hint: 'reduce instance count to fit within device.limits.maxStorageBufferBindingSize, or split transforms across multiple Instances entries',
963
+ detail: {
964
+ maxStorageBufferBindingSize: cap,
965
+ requestedBytes,
966
+ },
967
+ }),
968
+ );
969
+ return null;
970
+ } else {
971
+ // Look up the cached GPU buffer or create a fresh one when the
972
+ // archetype version bumped or the byte length changed.
973
+ const cached = frameState.instanceBuffers.get(
974
+ worldEntityKey(entry.source.worldId, inst.cacheKey),
975
+ );
976
+ let active: InstanceBufferCacheEntry | null = null;
977
+ if (
978
+ cached !== undefined &&
979
+ cached.uploadedArchVersion === inst.archVersion &&
980
+ cached.uploadedByteLength === requestedBytes
981
+ ) {
982
+ active = cached;
983
+ } else if (requestedBytes > 0) {
984
+ const bufRes = runtime.device.createBuffer({
985
+ size: uniformFallback ? INSTANCE_UBO_FULL_ARRAY_BYTES : requestedBytes,
986
+ usage: instanceBufferUsage,
987
+ mappedAtCreation: false,
988
+ });
989
+ if (!bufRes.ok) {
990
+ runtime.errorRegistry.fire(bufRes.error);
991
+ } else {
992
+ // feat-20260619 M4 / F12: destroy the old cached buffer
993
+ // before replacing it with the new one (D-6).
994
+ if (cached !== undefined && !cached.buffer.isDestroyed) {
995
+ const r = cached.buffer.destroy();
996
+ if (!r.ok) runtime.errorRegistry.fire(r.error);
997
+ }
998
+ const newBuffer = new GpuBuffer(runtime.device, bufRes.value);
999
+ active = {
1000
+ buffer: newBuffer,
1001
+ uploadedArchVersion: inst.archVersion,
1002
+ uploadedByteLength: requestedBytes,
1003
+ };
1004
+ frameState.instanceBuffers.set(
1005
+ worldEntityKey(entry.source.worldId, inst.cacheKey),
1006
+ active,
1007
+ );
1008
+ }
1009
+ }
1010
+ if (active !== null) {
1011
+ const writeRes = runtime.device.queue.writeBuffer(
1012
+ active.buffer.handle,
1013
+ 0,
1014
+ instancePayload,
1015
+ );
1016
+ if (!writeRes.ok) {
1017
+ runtime.errorRegistry.fire(writeRes.error);
1018
+ } else {
1019
+ instanceBuffer = active.buffer.handle;
1020
+ instanceCount = Math.max(1, inst.instanceCount);
1021
+ }
1022
+ }
1023
+ }
1024
+ // The cache write above is keyed by worldEntityKey(worldId, cacheKey)
1025
+ // so separate worlds cannot alias their instance buffers.
1026
+ }
1027
+ }
1028
+ return [
1029
+ {
1030
+ instanceBuffer,
1031
+ instanceBindGroup: resolveGeometryInstancesBindGroup(c, instanceBuffer),
1032
+ instanceCount,
1033
+ },
1034
+ ];
1035
+ }
1036
+
1037
+ function resolveGeometryInstancesBindGroup(
1038
+ c: _InternalRenderPipelineContext,
1039
+ instanceBuffer: Buffer,
1040
+ ): BindGroup {
1041
+ const { runtime, pipelineState, frameState, bindGroupCounts } = c;
1042
+ return getOrCreateFromChain(
1043
+ frameState.instancesBgShared,
1044
+ [pipelineState.instancesBindGroupLayout, instanceBuffer],
1045
+ 'instances',
1046
+ () => {
1047
+ const result = runtime.device.createBindGroup({
1048
+ label: 'pbr-instances-bg',
1049
+ layout: pipelineState.instancesBindGroupLayout,
1050
+ entries: [
1051
+ {
1052
+ binding: 0,
1053
+ resource: {
1054
+ kind: 'buffer',
1055
+ value: { buffer: instanceBuffer },
1056
+ },
1057
+ },
1058
+ ],
1059
+ });
1060
+ if (!result.ok) throw result.error;
1061
+ return result.value;
1062
+ },
1063
+ bindGroupCounts,
1064
+ );
1065
+ }