@woosh/meep-engine 3.26.0 → 3.28.0

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 (449) hide show
  1. package/build/bundle-worker-terrain.js +1 -1
  2. package/package.json +1 -1
  3. package/src/core/binary/lz4/LZ4_HIGH_COMPRESSION_PLAN_2026_09_14.md +542 -0
  4. package/src/core/binary/lz4/LZ4_LEVEL.d.ts +33 -0
  5. package/src/core/binary/lz4/LZ4_LEVEL.d.ts.map +1 -0
  6. package/src/core/binary/lz4/LZ4_LEVEL.js +32 -0
  7. package/src/core/binary/lz4/lz4_compress_block_at_level.d.ts +33 -0
  8. package/src/core/binary/lz4/lz4_compress_block_at_level.d.ts.map +1 -0
  9. package/src/core/binary/lz4/lz4_compress_block_at_level.js +47 -0
  10. package/src/core/binary/lz4/lz4_compress_block_hc.d.ts +40 -0
  11. package/src/core/binary/lz4/lz4_compress_block_hc.d.ts.map +1 -0
  12. package/src/core/binary/lz4/lz4_compress_block_hc.js +1382 -0
  13. package/src/core/binary/lz4/lz4_decompress_block.d.ts +2 -1
  14. package/src/core/binary/lz4/lz4_decompress_block.d.ts.map +1 -1
  15. package/src/core/binary/lz4/lz4_decompress_block.js +31 -6
  16. package/src/core/geom/3d/mat4/m4_linear_determinant.d.ts +15 -0
  17. package/src/core/geom/3d/mat4/m4_linear_determinant.d.ts.map +1 -0
  18. package/src/core/geom/3d/mat4/m4_linear_determinant.js +24 -0
  19. package/src/core/geom/3d/mat4/m4_normal_matrix3.d.ts +4 -2
  20. package/src/core/geom/3d/mat4/m4_normal_matrix3.d.ts.map +1 -1
  21. package/src/core/geom/3d/mat4/m4_normal_matrix3.js +21 -11
  22. package/src/core/geom/3d/shape/HeightMapShape3D.d.ts +14 -7
  23. package/src/core/geom/3d/shape/HeightMapShape3D.d.ts.map +1 -1
  24. package/src/core/geom/3d/shape/HeightMapShape3D.js +87 -78
  25. package/src/engine/Engine.d.ts.map +1 -1
  26. package/src/engine/Engine.js +38 -1
  27. package/src/engine/graphics3/GraphicsEngine.d.ts +5 -1
  28. package/src/engine/graphics3/GraphicsEngine.d.ts.map +1 -1
  29. package/src/engine/graphics3/GraphicsEngine.js +834 -830
  30. package/src/engine/physics/fluid/ecs/FluidObstacleSystem.d.ts +4 -4
  31. package/src/shade/RENDERER_CONTRACT.md +19 -10
  32. package/src/shade/device/timing/GPU_PROFILER_PROPOSAL_2026_08_28.md +1 -1
  33. package/src/shade/playground/vgeo_runtime/README.md +186 -27
  34. package/src/shade/playground/vgeo_runtime/index.html +112 -62
  35. package/src/shade/playground/vgeo_runtime/main.js +678 -88
  36. package/src/shade/playground/vgeo_runtime/sample_asset.d.ts +18 -0
  37. package/src/shade/playground/vgeo_runtime/sample_asset.d.ts.map +1 -0
  38. package/src/shade/playground/{vgeo_viewer → vgeo_runtime}/sample_asset.js +23 -5
  39. package/src/shade/playground/vgeo_scene/README.md +408 -0
  40. package/src/shade/playground/vgeo_scene/index.html +144 -0
  41. package/src/shade/playground/vgeo_scene/main.d.ts +2 -0
  42. package/src/shade/playground/vgeo_scene/main.d.ts.map +1 -0
  43. package/src/shade/playground/vgeo_scene/main.js +1716 -0
  44. package/src/shade/playground/vgeo_viewer/sample_asset.d.ts.map +1 -1
  45. package/src/shade/renderer/Renderer.d.ts +4 -1
  46. package/src/shade/renderer/Renderer.d.ts.map +1 -1
  47. package/src/shade/renderer/Renderer.js +5 -2
  48. package/src/shade/renderer/extension/RENDER_EXTENSION_DESIGN.md +1 -2
  49. package/src/shade/renderer/geometry/bvh/GPUGeometryBVHManager.d.ts +11 -0
  50. package/src/shade/renderer/geometry/bvh/GPUGeometryBVHManager.d.ts.map +1 -1
  51. package/src/shade/renderer/geometry/bvh/GPUGeometryBVHManager.js +16 -8
  52. package/src/shade/renderer/geometry/meshlet/GPUMeshletManager.d.ts.map +1 -1
  53. package/src/shade/renderer/geometry/meshlet/GPUMeshletManager.js +16 -11
  54. package/src/shade/renderer/geometry/meshlet/MeshletBatch.d.ts.map +1 -1
  55. package/src/shade/renderer/geometry/meshlet/MeshletBatch.js +3 -29
  56. package/src/shade/renderer/geometry/meshlet/encoding/ENCODED_ATTRIBUTE_DEFAULT_VALUES.d.ts +22 -0
  57. package/src/shade/renderer/geometry/meshlet/encoding/ENCODED_ATTRIBUTE_DEFAULT_VALUES.d.ts.map +1 -0
  58. package/src/shade/renderer/geometry/meshlet/encoding/ENCODED_ATTRIBUTE_DEFAULT_VALUES.js +49 -0
  59. package/src/shade/renderer/geometry/virtual/VGEO_FORMAT.md +77 -7
  60. package/src/shade/renderer/geometry/virtual/VIRTUAL_GEOMETRY_DESIGN.md +36 -23
  61. package/src/shade/renderer/geometry/virtual/VIRTUAL_GEOMETRY_PLAN.md +17 -14
  62. package/src/shade/renderer/geometry/virtual/build/VGeoBuildOptions.d.ts +19 -1
  63. package/src/shade/renderer/geometry/virtual/build/VGeoBuildOptions.d.ts.map +1 -1
  64. package/src/shade/renderer/geometry/virtual/build/VGeoBuildOptions.js +21 -1
  65. package/src/shade/renderer/geometry/virtual/build/gltf/gltf_open_document.d.ts.map +1 -1
  66. package/src/shade/renderer/geometry/virtual/build/gltf/gltf_open_document.js +5 -9
  67. package/src/shade/renderer/geometry/virtual/build/level/VGeoLevel.d.ts +32 -0
  68. package/src/shade/renderer/geometry/virtual/build/level/VGeoLevel.d.ts.map +1 -0
  69. package/src/shade/renderer/geometry/virtual/build/level/VGeoLevelOptions.d.ts +59 -0
  70. package/src/shade/renderer/geometry/virtual/build/level/VGeoLevelOptions.d.ts.map +1 -0
  71. package/src/shade/renderer/geometry/virtual/build/level/VGeoLevelSummary.d.ts +44 -0
  72. package/src/shade/renderer/geometry/virtual/build/level/VGeoLevelSummary.d.ts.map +1 -0
  73. package/src/shade/renderer/geometry/virtual/build/level/vgeo_build_levels.d.ts +36 -0
  74. package/src/shade/renderer/geometry/virtual/build/level/vgeo_build_levels.d.ts.map +1 -0
  75. package/src/shade/renderer/geometry/virtual/build/{vgeo_build_levels.js → level/vgeo_build_levels.js} +61 -95
  76. package/src/shade/renderer/geometry/virtual/build/level/vgeo_build_root_group.d.ts +19 -0
  77. package/src/shade/renderer/geometry/virtual/build/level/vgeo_build_root_group.d.ts.map +1 -0
  78. package/src/shade/renderer/geometry/virtual/build/{vgeo_build_root_group.js → level/vgeo_build_root_group.js} +1 -1
  79. package/src/shade/renderer/geometry/virtual/build/mesh/VirtualGeometryMesh.d.ts +73 -0
  80. package/src/shade/renderer/geometry/virtual/build/mesh/VirtualGeometryMesh.d.ts.map +1 -0
  81. package/src/shade/renderer/geometry/virtual/build/{VirtualGeometryMesh.js → mesh/VirtualGeometryMesh.js} +7 -7
  82. package/src/shade/renderer/geometry/virtual/build/mesh/vgeo_compute_vertex_normals.d.ts +29 -0
  83. package/src/shade/renderer/geometry/virtual/build/mesh/vgeo_compute_vertex_normals.d.ts.map +1 -0
  84. package/src/shade/renderer/geometry/virtual/build/{vgeo_compute_vertex_normals.js → mesh/vgeo_compute_vertex_normals.js} +3 -3
  85. package/src/shade/renderer/geometry/virtual/build/mesh/vgeo_compute_vertex_tangents.d.ts +31 -0
  86. package/src/shade/renderer/geometry/virtual/build/mesh/vgeo_compute_vertex_tangents.d.ts.map +1 -0
  87. package/src/shade/renderer/geometry/virtual/build/{vgeo_compute_vertex_tangents.js → mesh/vgeo_compute_vertex_tangents.js} +5 -5
  88. package/src/shade/renderer/geometry/virtual/build/mesh/vgeo_normalize_source.d.ts +46 -0
  89. package/src/shade/renderer/geometry/virtual/build/mesh/vgeo_normalize_source.d.ts.map +1 -0
  90. package/src/shade/renderer/geometry/virtual/build/{vgeo_normalize_source.js → mesh/vgeo_normalize_source.js} +9 -9
  91. package/src/shade/renderer/geometry/virtual/build/page/vgeo_assemble_pages.d.ts +13 -0
  92. package/src/shade/renderer/geometry/virtual/build/page/vgeo_assemble_pages.d.ts.map +1 -0
  93. package/src/shade/renderer/geometry/virtual/build/{vgeo_assemble_pages.js → page/vgeo_assemble_pages.js} +63 -16
  94. package/src/shade/renderer/geometry/virtual/build/page/vgeo_build_page_nodes.d.ts +13 -0
  95. package/src/shade/renderer/geometry/virtual/build/page/vgeo_build_page_nodes.d.ts.map +1 -0
  96. package/src/shade/renderer/geometry/virtual/build/{vgeo_build_page_nodes.js → page/vgeo_build_page_nodes.js} +4 -4
  97. package/src/shade/renderer/geometry/virtual/build/page/vgeo_page_node_count.d.ts +22 -0
  98. package/src/shade/renderer/geometry/virtual/build/page/vgeo_page_node_count.d.ts.map +1 -0
  99. package/src/shade/renderer/geometry/virtual/build/{vgeo_page_node_count.js → page/vgeo_page_node_count.js} +2 -2
  100. package/src/shade/renderer/geometry/virtual/build/partition/VGeoFaceGraph.d.ts +52 -0
  101. package/src/shade/renderer/geometry/virtual/build/partition/VGeoFaceGraph.d.ts.map +1 -0
  102. package/src/shade/renderer/geometry/virtual/build/{VGeoFaceGraph.js → partition/VGeoFaceGraph.js} +1 -1
  103. package/src/shade/renderer/geometry/virtual/build/partition/vgeo_graph_components.d.ts +14 -0
  104. package/src/shade/renderer/geometry/virtual/build/partition/vgeo_graph_components.d.ts.map +1 -0
  105. package/src/shade/renderer/geometry/virtual/build/partition/vgeo_partition_graph.d.ts +29 -0
  106. package/src/shade/renderer/geometry/virtual/build/partition/vgeo_partition_graph.d.ts.map +1 -0
  107. package/src/shade/renderer/geometry/virtual/build/{vgeo_partition_graph.js → partition/vgeo_partition_graph.js} +2 -2
  108. package/src/shade/renderer/geometry/virtual/build/partition/vgeo_partition_subgraph.d.ts +41 -0
  109. package/src/shade/renderer/geometry/virtual/build/partition/vgeo_partition_subgraph.d.ts.map +1 -0
  110. package/src/shade/renderer/geometry/virtual/build/partition/vgeo_partition_subgraph.js +92 -0
  111. package/src/shade/renderer/geometry/virtual/build/partition/vgeo_split_face_set.d.ts +10 -0
  112. package/src/shade/renderer/geometry/virtual/build/partition/vgeo_split_face_set.d.ts.map +1 -0
  113. package/src/shade/renderer/geometry/virtual/build/{vgeo_split_face_set.js → partition/vgeo_split_face_set.js} +12 -55
  114. package/src/shade/renderer/geometry/virtual/build/partition/vgeo_split_face_set_packed.d.ts +15 -0
  115. package/src/shade/renderer/geometry/virtual/build/partition/vgeo_split_face_set_packed.d.ts.map +1 -0
  116. package/src/shade/renderer/geometry/virtual/build/{vgeo_split_face_set_packed.js → partition/vgeo_split_face_set_packed.js} +3 -3
  117. package/src/shade/renderer/geometry/virtual/build/sphere/vgeo_bounding_sphere.d.ts +12 -0
  118. package/src/shade/renderer/geometry/virtual/build/sphere/vgeo_bounding_sphere.d.ts.map +1 -0
  119. package/src/shade/renderer/geometry/virtual/build/{vgeo_bounding_sphere.js → sphere/vgeo_bounding_sphere.js} +3 -3
  120. package/src/shade/renderer/geometry/virtual/build/sphere/vgeo_containing_sphere.d.ts +18 -0
  121. package/src/shade/renderer/geometry/virtual/build/sphere/vgeo_containing_sphere.d.ts.map +1 -0
  122. package/src/shade/renderer/geometry/virtual/build/{vgeo_containing_sphere.js → sphere/vgeo_containing_sphere.js} +3 -3
  123. package/src/shade/renderer/geometry/virtual/build/sphere/vgeo_sphere_inflate_to_contain.d.ts +9 -0
  124. package/src/shade/renderer/geometry/virtual/build/sphere/vgeo_sphere_inflate_to_contain.d.ts.map +1 -0
  125. package/src/shade/renderer/geometry/virtual/build/{vgeo_sphere_inflate_to_contain.js → sphere/vgeo_sphere_inflate_to_contain.js} +1 -1
  126. package/src/shade/renderer/geometry/virtual/build/submesh/VGeoGatheredFaces.d.ts +24 -0
  127. package/src/shade/renderer/geometry/virtual/build/submesh/VGeoGatheredFaces.d.ts.map +1 -0
  128. package/src/shade/renderer/geometry/virtual/build/submesh/VGeoSubmesh.d.ts +20 -0
  129. package/src/shade/renderer/geometry/virtual/build/submesh/VGeoSubmesh.d.ts.map +1 -0
  130. package/src/shade/renderer/geometry/virtual/build/submesh/vgeo_extract_submesh.d.ts +14 -0
  131. package/src/shade/renderer/geometry/virtual/build/submesh/vgeo_extract_submesh.d.ts.map +1 -0
  132. package/src/shade/renderer/geometry/virtual/build/{vgeo_extract_submesh.js → submesh/vgeo_extract_submesh.js} +5 -5
  133. package/src/shade/renderer/geometry/virtual/build/submesh/vgeo_gather_faces.d.ts +12 -0
  134. package/src/shade/renderer/geometry/virtual/build/submesh/vgeo_gather_faces.d.ts.map +1 -0
  135. package/src/shade/renderer/geometry/virtual/build/{vgeo_gather_faces.js → submesh/vgeo_gather_faces.js} +2 -2
  136. package/src/shade/renderer/geometry/virtual/build/submesh/vgeo_narrow_indices.d.ts +11 -0
  137. package/src/shade/renderer/geometry/virtual/build/submesh/vgeo_narrow_indices.d.ts.map +1 -0
  138. package/src/shade/renderer/geometry/virtual/build/{vgeo_narrow_indices.js → submesh/vgeo_narrow_indices.js} +3 -3
  139. package/src/shade/renderer/geometry/virtual/build/vgeo_assemble_pages.d.ts.map +1 -1
  140. package/src/shade/renderer/geometry/virtual/build/vgeo_build.d.ts.map +1 -1
  141. package/src/shade/renderer/geometry/virtual/build/vgeo_build.js +10 -11
  142. package/src/shade/renderer/geometry/virtual/format/VGeoWriteOptions.d.ts +22 -0
  143. package/src/shade/renderer/geometry/virtual/format/VGeoWriteOptions.d.ts.map +1 -1
  144. package/src/shade/renderer/geometry/virtual/format/VGeoWriteOptions.js +24 -0
  145. package/src/shade/renderer/geometry/virtual/format/attribute/vgeo_attributes_read.d.ts +8 -2
  146. package/src/shade/renderer/geometry/virtual/format/attribute/vgeo_attributes_read.d.ts.map +1 -1
  147. package/src/shade/renderer/geometry/virtual/format/attribute/vgeo_attributes_read.js +8 -2
  148. package/src/shade/renderer/geometry/virtual/format/dag/VirtualGeometryCluster.d.ts +12 -0
  149. package/src/shade/renderer/geometry/virtual/format/dag/VirtualGeometryCluster.d.ts.map +1 -1
  150. package/src/shade/renderer/geometry/virtual/format/dag/VirtualGeometryCluster.js +13 -0
  151. package/src/shade/renderer/geometry/virtual/format/frame/vgeo_encode_frame_blob.d.ts +8 -1
  152. package/src/shade/renderer/geometry/virtual/format/frame/vgeo_encode_frame_blob.d.ts.map +1 -1
  153. package/src/shade/renderer/geometry/virtual/format/frame/vgeo_encode_frame_blob.js +11 -3
  154. package/src/shade/renderer/geometry/virtual/format/header/VGEO_FORMAT_VERSION.d.ts +9 -0
  155. package/src/shade/renderer/geometry/virtual/format/header/VGEO_FORMAT_VERSION.d.ts.map +1 -1
  156. package/src/shade/renderer/geometry/virtual/format/header/VGEO_FORMAT_VERSION.js +10 -1
  157. package/src/shade/renderer/geometry/virtual/format/page/VGEO_GROUP_OFFSET.d.ts +15 -0
  158. package/src/shade/renderer/geometry/virtual/format/page/VGEO_GROUP_OFFSET.d.ts.map +1 -0
  159. package/src/shade/renderer/geometry/virtual/format/page/VGEO_GROUP_OFFSET.js +15 -0
  160. package/src/shade/renderer/geometry/virtual/format/page/VGEO_MAX_PARENT_ENTRY_COUNT.d.ts +18 -0
  161. package/src/shade/renderer/geometry/virtual/format/page/VGEO_MAX_PARENT_ENTRY_COUNT.d.ts.map +1 -0
  162. package/src/shade/renderer/geometry/virtual/format/page/VGEO_MAX_PARENT_ENTRY_COUNT.js +17 -0
  163. package/src/shade/renderer/geometry/virtual/format/page/VGEO_MAX_PARENT_REF.d.ts +8 -0
  164. package/src/shade/renderer/geometry/virtual/format/page/VGEO_MAX_PARENT_REF.d.ts.map +1 -0
  165. package/src/shade/renderer/geometry/virtual/format/page/VGEO_MAX_PARENT_REF.js +7 -0
  166. package/src/shade/renderer/geometry/virtual/format/page/VGEO_PAGE_OFFSET.d.ts +3 -0
  167. package/src/shade/renderer/geometry/virtual/format/page/VGEO_PAGE_OFFSET.js +16 -0
  168. package/src/shade/renderer/geometry/virtual/format/page/VGEO_PARENT_ENTRY_SIZE.d.ts +14 -0
  169. package/src/shade/renderer/geometry/virtual/format/page/VGEO_PARENT_ENTRY_SIZE.d.ts.map +1 -0
  170. package/src/shade/renderer/geometry/virtual/format/page/VGEO_PARENT_ENTRY_SIZE.js +13 -0
  171. package/src/shade/renderer/geometry/virtual/format/page/VGEO_PARENT_PAGE_ENTRY_SIZE.d.ts +11 -0
  172. package/src/shade/renderer/geometry/virtual/format/page/VGEO_PARENT_PAGE_ENTRY_SIZE.d.ts.map +1 -0
  173. package/src/shade/renderer/geometry/virtual/format/page/VGEO_PARENT_PAGE_ENTRY_SIZE.js +10 -0
  174. package/src/shade/renderer/geometry/virtual/format/payload/vgeo_encode_cluster_payload.d.ts +28 -0
  175. package/src/shade/renderer/geometry/virtual/format/payload/vgeo_encode_cluster_payload.d.ts.map +1 -1
  176. package/src/shade/renderer/geometry/virtual/format/payload/vgeo_encode_cluster_payload.js +7 -3
  177. package/src/shade/renderer/geometry/virtual/format/read/VGeoByteSource.d.ts +20 -0
  178. package/src/shade/renderer/geometry/virtual/format/read/VGeoByteSource.d.ts.map +1 -1
  179. package/src/shade/renderer/geometry/virtual/format/read/VGeoByteSource.js +20 -2
  180. package/src/shade/renderer/geometry/virtual/format/read/VGeoContainerHeader.d.ts +4 -0
  181. package/src/shade/renderer/geometry/virtual/format/read/VGeoContainerHeader.d.ts.map +1 -1
  182. package/src/shade/renderer/geometry/virtual/format/read/VGeoContainerHeader.js +4 -0
  183. package/src/shade/renderer/geometry/virtual/format/read/VGeoContainerReader.d.ts +29 -3
  184. package/src/shade/renderer/geometry/virtual/format/read/VGeoContainerReader.d.ts.map +1 -1
  185. package/src/shade/renderer/geometry/virtual/format/read/VGeoContainerReader.js +81 -122
  186. package/src/shade/renderer/geometry/virtual/format/read/VGeoPage.d.ts +40 -0
  187. package/src/shade/renderer/geometry/virtual/format/read/VGeoPage.d.ts.map +1 -1
  188. package/src/shade/renderer/geometry/virtual/format/read/VGeoPage.js +44 -0
  189. package/src/shade/renderer/geometry/virtual/format/read/VGeoPageFetcherCore.d.ts +69 -0
  190. package/src/shade/renderer/geometry/virtual/format/read/VGeoPageFetcherCore.d.ts.map +1 -0
  191. package/src/shade/renderer/geometry/virtual/format/read/VGeoPageFetcherCore.js +236 -0
  192. package/src/shade/renderer/geometry/virtual/format/read/VGeoReadOptions.d.ts +14 -0
  193. package/src/shade/renderer/geometry/virtual/format/read/VGeoReadOptions.d.ts.map +1 -1
  194. package/src/shade/renderer/geometry/virtual/format/read/VGeoReadOptions.js +15 -0
  195. package/src/shade/renderer/geometry/virtual/format/read/vgeo_byte_source_from_descriptor.d.ts +31 -0
  196. package/src/shade/renderer/geometry/virtual/format/read/vgeo_byte_source_from_descriptor.d.ts.map +1 -0
  197. package/src/shade/renderer/geometry/virtual/format/read/vgeo_byte_source_from_descriptor.js +32 -0
  198. package/src/shade/renderer/geometry/virtual/format/read/vgeo_fetch_byte_source.d.ts +10 -0
  199. package/src/shade/renderer/geometry/virtual/format/read/vgeo_fetch_byte_source.d.ts.map +1 -1
  200. package/src/shade/renderer/geometry/virtual/format/read/vgeo_fetch_byte_source.js +21 -1
  201. package/src/shade/renderer/geometry/virtual/format/read/vgeo_page_transfer.d.ts +15 -0
  202. package/src/shade/renderer/geometry/virtual/format/read/vgeo_page_transfer.d.ts.map +1 -0
  203. package/src/shade/renderer/geometry/virtual/format/read/vgeo_page_transfer.js +84 -0
  204. package/src/shade/renderer/geometry/virtual/format/read/vgeo_page_worker_serve.d.ts +22 -0
  205. package/src/shade/renderer/geometry/virtual/format/read/vgeo_page_worker_serve.d.ts.map +1 -0
  206. package/src/shade/renderer/geometry/virtual/format/read/vgeo_page_worker_serve.js +96 -0
  207. package/src/shade/renderer/geometry/virtual/format/read/vgeo_read_page.d.ts.map +1 -1
  208. package/src/shade/renderer/geometry/virtual/format/read/vgeo_read_page.js +63 -3
  209. package/src/shade/renderer/geometry/virtual/format/vgeo_validate_container.d.ts.map +1 -1
  210. package/src/shade/renderer/geometry/virtual/format/vgeo_validate_container.js +219 -17
  211. package/src/shade/renderer/geometry/virtual/format/vgeo_write_container.d.ts.map +1 -1
  212. package/src/shade/renderer/geometry/virtual/format/vgeo_write_container.js +156 -11
  213. package/src/shade/renderer/geometry/virtual/runtime/CUT_PLAN_2026_09_14.md +656 -0
  214. package/src/shade/renderer/geometry/virtual/runtime/GPUVirtualGeometryPool.d.ts +33 -36
  215. package/src/shade/renderer/geometry/virtual/runtime/GPUVirtualGeometryPool.d.ts.map +1 -1
  216. package/src/shade/renderer/geometry/virtual/runtime/GPUVirtualGeometryPool.js +109 -193
  217. package/src/shade/renderer/geometry/virtual/runtime/GPUVirtualGeometryRuntime.d.ts +109 -29
  218. package/src/shade/renderer/geometry/virtual/runtime/GPUVirtualGeometryRuntime.d.ts.map +1 -1
  219. package/src/shade/renderer/geometry/virtual/runtime/GPUVirtualGeometryRuntime.js +173 -105
  220. package/src/shade/renderer/geometry/virtual/runtime/REVIEW_LEDGER.md +37 -0
  221. package/src/shade/renderer/geometry/virtual/runtime/RUNTIME_PLAN.md +109 -26
  222. package/src/shade/renderer/geometry/virtual/runtime/RUNTIME_PLAN_2026_09_14.md +548 -0
  223. package/src/shade/renderer/geometry/virtual/runtime/VGeoFeedbackLoop.d.ts +29 -50
  224. package/src/shade/renderer/geometry/virtual/runtime/VGeoFeedbackLoop.d.ts.map +1 -1
  225. package/src/shade/renderer/geometry/virtual/runtime/VGeoFeedbackLoop.js +55 -487
  226. package/src/shade/renderer/geometry/virtual/runtime/VGeoPageFetcher.d.ts +84 -0
  227. package/src/shade/renderer/geometry/virtual/runtime/VGeoPageFetcher.d.ts.map +1 -0
  228. package/src/shade/renderer/geometry/virtual/runtime/VGeoPageFetcher.js +393 -0
  229. package/src/shade/renderer/geometry/virtual/runtime/VGeoResidency.d.ts +234 -0
  230. package/src/shade/renderer/geometry/virtual/runtime/VGeoResidency.d.ts.map +1 -0
  231. package/src/shade/renderer/geometry/virtual/runtime/VGeoResidency.js +1388 -0
  232. package/src/shade/renderer/geometry/virtual/runtime/VGeoResidencyOptions.d.ts +81 -0
  233. package/src/shade/renderer/geometry/virtual/runtime/VGeoResidencyOptions.d.ts.map +1 -0
  234. package/src/shade/renderer/geometry/virtual/runtime/VGeoResidencyOptions.js +89 -0
  235. package/src/shade/renderer/geometry/virtual/runtime/VGeoRuntimeTables.d.ts +53 -34
  236. package/src/shade/renderer/geometry/virtual/runtime/VGeoRuntimeTables.d.ts.map +1 -1
  237. package/src/shade/renderer/geometry/virtual/runtime/VGeoRuntimeTables.js +407 -124
  238. package/src/shade/renderer/geometry/virtual/runtime/VGeoViewCut.d.ts +100 -0
  239. package/src/shade/renderer/geometry/virtual/runtime/VGeoViewCut.d.ts.map +1 -0
  240. package/src/shade/renderer/geometry/virtual/runtime/VGeoViewCut.js +219 -0
  241. package/src/shade/renderer/geometry/virtual/runtime/cut/VGEO_CUT_EXPAND.d.ts +17 -0
  242. package/src/shade/renderer/geometry/virtual/runtime/cut/VGEO_CUT_EXPAND.d.ts.map +1 -0
  243. package/src/shade/renderer/geometry/virtual/runtime/cut/VGEO_CUT_EXPAND.js +47 -0
  244. package/src/shade/renderer/geometry/virtual/runtime/cut/VGEO_CUT_FLAG_COARSEN.d.ts +20 -0
  245. package/src/shade/renderer/geometry/virtual/runtime/cut/VGEO_CUT_FLAG_COARSEN.d.ts.map +1 -0
  246. package/src/shade/renderer/geometry/virtual/runtime/cut/VGEO_CUT_FLAG_COARSEN.js +19 -0
  247. package/src/shade/renderer/geometry/virtual/runtime/cut/VGEO_CUT_PARAMS_STRUCT.d.ts.map +1 -1
  248. package/src/shade/renderer/geometry/virtual/runtime/cut/VGEO_CUT_PARAMS_STRUCT.js +30 -12
  249. package/src/shade/renderer/geometry/virtual/runtime/cut/chunk_vgeo_cut_access.d.ts +8 -8
  250. package/src/shade/renderer/geometry/virtual/runtime/cut/chunk_vgeo_cut_access.d.ts.map +1 -1
  251. package/src/shade/renderer/geometry/virtual/runtime/cut/chunk_vgeo_cut_access.js +11 -73
  252. package/src/shade/renderer/geometry/virtual/runtime/cut/chunk_vgeo_cut_arena.d.ts +19 -0
  253. package/src/shade/renderer/geometry/virtual/runtime/cut/chunk_vgeo_cut_arena.d.ts.map +1 -0
  254. package/src/shade/renderer/geometry/virtual/runtime/cut/chunk_vgeo_cut_arena.js +98 -0
  255. package/src/shade/renderer/geometry/virtual/runtime/cut/chunk_vgeo_cut_claim.d.ts +31 -0
  256. package/src/shade/renderer/geometry/virtual/runtime/cut/chunk_vgeo_cut_claim.d.ts.map +1 -0
  257. package/src/shade/renderer/geometry/virtual/runtime/cut/chunk_vgeo_cut_claim.js +99 -0
  258. package/src/shade/renderer/geometry/virtual/runtime/cut/chunk_vgeo_cut_queue.d.ts +17 -0
  259. package/src/shade/renderer/geometry/virtual/runtime/cut/chunk_vgeo_cut_queue.d.ts.map +1 -0
  260. package/src/shade/renderer/geometry/virtual/runtime/cut/chunk_vgeo_cut_queue.js +39 -0
  261. package/src/shade/renderer/geometry/virtual/runtime/cut/shader_vgeo_cut_collect.d.ts.map +1 -1
  262. package/src/shade/renderer/geometry/virtual/runtime/cut/shader_vgeo_cut_collect.js +18 -1
  263. package/src/shade/renderer/geometry/virtual/runtime/cut/shader_vgeo_cut_queue_prepare.d.ts.map +1 -1
  264. package/src/shade/renderer/geometry/virtual/runtime/cut/shader_vgeo_cut_queue_prepare.js +5 -15
  265. package/src/shade/renderer/geometry/virtual/runtime/cut/shader_vgeo_cut_queue_remainder.d.ts +3 -0
  266. package/src/shade/renderer/geometry/virtual/runtime/cut/shader_vgeo_cut_queue_remainder.d.ts.map +1 -0
  267. package/src/shade/renderer/geometry/virtual/runtime/cut/shader_vgeo_cut_queue_remainder.js +77 -0
  268. package/src/shade/renderer/geometry/virtual/runtime/cut/shader_vgeo_cut_reseed.d.ts +3 -0
  269. package/src/shade/renderer/geometry/virtual/runtime/cut/shader_vgeo_cut_reseed.d.ts.map +1 -0
  270. package/src/shade/renderer/geometry/virtual/runtime/cut/shader_vgeo_cut_reseed.js +130 -0
  271. package/src/shade/renderer/geometry/virtual/runtime/cut/shader_vgeo_cut_seed.d.ts.map +1 -1
  272. package/src/shade/renderer/geometry/virtual/runtime/cut/shader_vgeo_cut_seed.js +32 -37
  273. package/src/shade/renderer/geometry/virtual/runtime/cut/shader_vgeo_cut_traverse.d.ts.map +1 -1
  274. package/src/shade/renderer/geometry/virtual/runtime/cut/shader_vgeo_cut_traverse.js +576 -230
  275. package/src/shade/renderer/geometry/virtual/runtime/cut/vgeo_cut_feedback_layout.d.ts +15 -18
  276. package/src/shade/renderer/geometry/virtual/runtime/cut/vgeo_cut_feedback_layout.d.ts.map +1 -1
  277. package/src/shade/renderer/geometry/virtual/runtime/cut/vgeo_cut_feedback_layout.js +19 -28
  278. package/src/shade/renderer/geometry/virtual/runtime/graph_vgeo_expand_instances_to_meshlets.d.ts.map +1 -1
  279. package/src/shade/renderer/geometry/virtual/runtime/graph_vgeo_expand_instances_to_meshlets.js +45 -25
  280. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_CUT_STAT.d.ts +1 -0
  281. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_CUT_STAT.js +11 -0
  282. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_CUT_STAT_COUNT.js +1 -1
  283. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_FEEDBACK_OFFSET.d.ts +0 -1
  284. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_FEEDBACK_OFFSET.js +12 -10
  285. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_GROUP_ROW_OFFSET.d.ts +1 -0
  286. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_GROUP_ROW_OFFSET.js +8 -0
  287. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_GROUP_ROW_WORDS.d.ts +7 -2
  288. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_GROUP_ROW_WORDS.d.ts.map +1 -1
  289. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_GROUP_ROW_WORDS.js +8 -3
  290. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_PAGE_ROW_OFFSET.d.ts +2 -0
  291. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_PAGE_ROW_OFFSET.js +19 -0
  292. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_PAGE_ROW_WORDS.d.ts.map +1 -1
  293. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_PAGE_ROW_WORDS.js +1 -1
  294. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_PARENT_ROW_OFFSET.d.ts +5 -0
  295. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_PARENT_ROW_OFFSET.d.ts.map +1 -0
  296. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_PARENT_ROW_OFFSET.js +22 -0
  297. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_PARENT_ROW_WORDS.d.ts +14 -0
  298. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_PARENT_ROW_WORDS.d.ts.map +1 -0
  299. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_PARENT_ROW_WORDS.js +13 -0
  300. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_QUEUE_TARGET_PARENT_BIT.d.ts +17 -0
  301. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_QUEUE_TARGET_PARENT_BIT.d.ts.map +1 -0
  302. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_QUEUE_TARGET_PARENT_BIT.js +16 -0
  303. package/src/shade/renderer/geometry/virtual/runtime/make_vgeo_page_worker.d.ts +15 -0
  304. package/src/shade/renderer/geometry/virtual/runtime/make_vgeo_page_worker.d.ts.map +1 -0
  305. package/src/shade/renderer/geometry/virtual/runtime/make_vgeo_page_worker.js +16 -0
  306. package/src/shade/renderer/geometry/virtual/runtime/vgeo_frontier_words.d.ts +23 -0
  307. package/src/shade/renderer/geometry/virtual/runtime/vgeo_frontier_words.d.ts.map +1 -0
  308. package/src/shade/renderer/geometry/virtual/runtime/vgeo_frontier_words.js +28 -0
  309. package/src/shade/renderer/geometry/virtual/runtime/vgeo_page.worker.d.ts +2 -0
  310. package/src/shade/renderer/geometry/virtual/runtime/vgeo_page.worker.d.ts.map +1 -0
  311. package/src/shade/renderer/geometry/virtual/runtime/vgeo_page.worker.js +13 -0
  312. package/src/shade/renderer/geometry/virtual/runtime/vgeo_runtime_page_block_words.d.ts +10 -5
  313. package/src/shade/renderer/geometry/virtual/runtime/vgeo_runtime_page_block_words.d.ts.map +1 -1
  314. package/src/shade/renderer/geometry/virtual/runtime/vgeo_runtime_page_block_words.js +15 -6
  315. package/src/shade/renderer/geometry/virtual/runtime/vgeo_runtime_write_page_block.d.ts +6 -1
  316. package/src/shade/renderer/geometry/virtual/runtime/vgeo_runtime_write_page_block.d.ts.map +1 -1
  317. package/src/shade/renderer/geometry/virtual/runtime/vgeo_runtime_write_page_block.js +38 -1
  318. package/src/shade/renderer/global_illumination/sharc/shader/shader_sharc_evict.d.ts.map +1 -1
  319. package/src/shade/renderer/global_illumination/sharc/shader/shader_sharc_evict.js +4 -3
  320. package/src/shade/renderer/loader/gltf/load_gltf.d.ts.map +1 -1
  321. package/src/shade/renderer/loader/gltf/load_gltf.js +0 -19
  322. package/src/shade/renderer/loader/gltf/tiny-gltf.d.ts +1 -1
  323. package/src/shade/renderer/material/chunk_material_draw_side.d.ts +14 -0
  324. package/src/shade/renderer/material/chunk_material_draw_side.d.ts.map +1 -0
  325. package/src/shade/renderer/material/chunk_material_draw_side.js +34 -0
  326. package/src/shade/renderer/material/standard/fragment_gbuffer.d.ts.map +1 -1
  327. package/src/shade/renderer/material/standard/fragment_gbuffer.js +8 -1
  328. package/src/shade/renderer/particles/shaders/shader_particle_emit.d.ts.map +1 -1
  329. package/src/shade/renderer/particles/shaders/shader_particle_emit.js +6 -3
  330. package/src/shade/renderer/particles/shaders/shader_particle_simulate.d.ts.map +1 -1
  331. package/src/shade/renderer/particles/shaders/shader_particle_simulate.js +6 -3
  332. package/src/shade/renderer/path_tracer/shader/chunk_sample_material_data.d.ts.map +1 -1
  333. package/src/shade/renderer/path_tracer/shader/chunk_sample_material_data.js +13 -1
  334. package/src/shade/renderer/postprocess/nss/NSS.d.ts +1 -1
  335. package/src/shade/renderer/rasterize/bucket/construct_primitive_state.d.ts +19 -5
  336. package/src/shade/renderer/rasterize/bucket/construct_primitive_state.d.ts.map +1 -1
  337. package/src/shade/renderer/rasterize/bucket/construct_primitive_state.js +23 -5
  338. package/src/shade/renderer/rasterize/bucket/filter_materials_by_bucket.d.ts.map +1 -1
  339. package/src/shade/renderer/rasterize/bucket/filter_materials_by_bucket.js +12 -5
  340. package/src/shade/renderer/rasterize/bucket/prepare_meshlet_draw_commands_by_material.d.ts.map +1 -1
  341. package/src/shade/renderer/rasterize/bucket/prepare_meshlet_draw_commands_by_material.js +12 -4
  342. package/src/shade/renderer/rasterize/bucket/rasterization_opaque_buckets.d.ts +22 -0
  343. package/src/shade/renderer/rasterize/bucket/rasterization_opaque_buckets.d.ts.map +1 -0
  344. package/src/shade/renderer/rasterize/bucket/rasterization_opaque_buckets.js +36 -0
  345. package/src/shade/renderer/rasterize/bucket/shader_read_out_bucket.d.ts +2 -0
  346. package/src/shade/renderer/rasterize/bucket/shader_read_out_bucket.d.ts.map +1 -1
  347. package/src/shade/renderer/rasterize/bucket/shader_read_out_bucket.js +58 -57
  348. package/src/shade/renderer/rasterize/chunk_triangle_winding_is_reversed.d.ts +15 -0
  349. package/src/shade/renderer/rasterize/chunk_triangle_winding_is_reversed.d.ts.map +1 -0
  350. package/src/shade/renderer/rasterize/chunk_triangle_winding_is_reversed.js +35 -0
  351. package/src/shade/renderer/rasterize/cull/hzb/shader_hzb_mesh_filter_2way.d.ts.map +1 -1
  352. package/src/shade/renderer/rasterize/cull/hzb/shader_hzb_mesh_filter_2way.js +3 -5
  353. package/src/shade/renderer/rasterize/cull/hzb/shader_hzb_meshlet_filter_1way_full.d.ts.map +1 -1
  354. package/src/shade/renderer/rasterize/cull/hzb/shader_hzb_meshlet_filter_1way_full.js +3 -4
  355. package/src/shade/renderer/rasterize/expand/bucket/RASTERIZATION_BUCKET_LIMIT.d.ts +10 -1
  356. package/src/shade/renderer/rasterize/expand/bucket/RASTERIZATION_BUCKET_LIMIT.d.ts.map +1 -1
  357. package/src/shade/renderer/rasterize/expand/bucket/RASTERIZATION_BUCKET_LIMIT.js +38 -29
  358. package/src/shade/renderer/rasterize/expand/bucket/chunk_rasterization_material_bucket.d.ts +5 -0
  359. package/src/shade/renderer/rasterize/expand/bucket/chunk_rasterization_material_bucket.d.ts.map +1 -1
  360. package/src/shade/renderer/rasterize/expand/bucket/chunk_rasterization_material_bucket.js +63 -55
  361. package/src/shade/renderer/rasterize/expand/bucket/meshlet/shader_meshlets_extract_bucket.d.ts.map +1 -1
  362. package/src/shade/renderer/rasterize/expand/bucket/meshlet/shader_meshlets_extract_bucket.js +3 -4
  363. package/src/shade/renderer/rasterize/expand/graph_meshlets_rasterize.d.ts.map +1 -1
  364. package/src/shade/renderer/rasterize/expand/graph_meshlets_rasterize.js +1 -0
  365. package/src/shade/renderer/rasterize/expand/pass0/pass_mesh_cull.d.ts.map +1 -1
  366. package/src/shade/renderer/rasterize/expand/pass0/pass_mesh_cull.js +7 -7
  367. package/src/shade/renderer/rasterize/fast/graph_extract_meshes_from_bucket.d.ts.map +1 -1
  368. package/src/shade/renderer/rasterize/fast/graph_extract_meshes_from_bucket.js +83 -78
  369. package/src/shade/renderer/rasterize/fast/graph_rasterize_scene_fast.d.ts.map +1 -1
  370. package/src/shade/renderer/rasterize/fast/graph_rasterize_scene_fast.js +44 -53
  371. package/src/shade/renderer/rasterize/forward/chunk_forward_shade_standard_fragment_brick4.d.ts.map +1 -1
  372. package/src/shade/renderer/rasterize/forward/chunk_forward_shade_standard_fragment_brick4.js +6 -2
  373. package/src/shade/renderer/rasterize/forward/chunk_forward_shade_standard_fragment_ibl.d.ts.map +1 -1
  374. package/src/shade/renderer/rasterize/forward/chunk_forward_shade_standard_fragment_ibl.js +6 -2
  375. package/src/shade/renderer/rasterize/forward/vertex_shader_chunk.d.ts.map +1 -1
  376. package/src/shade/renderer/rasterize/forward/vertex_shader_chunk.js +19 -2
  377. package/src/shade/renderer/rasterize/native/avboit/AVBOIT_PLAN_2026_09_03.md +7 -4
  378. package/src/shade/renderer/rasterize/native/avboit/graph_rasterize_meshes_transparent_avboit.d.ts.map +1 -1
  379. package/src/shade/renderer/rasterize/native/avboit/graph_rasterize_meshes_transparent_avboit.js +3 -2
  380. package/src/shade/renderer/rasterize/native/chunk_rasterize_triangle.d.ts.map +1 -1
  381. package/src/shade/renderer/rasterize/native/chunk_rasterize_triangle.js +15 -4
  382. package/src/shade/renderer/rasterize/native/depth/shadow_rasterization_alpha_tested_pass_descriptor.d.ts.map +1 -1
  383. package/src/shade/renderer/rasterize/native/depth/shadow_rasterization_alpha_tested_pass_descriptor.js +16 -5
  384. package/src/shade/renderer/rasterize/native/depth/shadow_rasterization_pass_descriptor.d.ts.map +1 -1
  385. package/src/shade/renderer/rasterize/native/depth/shadow_rasterization_pass_descriptor.js +16 -5
  386. package/src/shade/renderer/rasterize/native/oit/graph_rasterize_meshes_transparent_oit.d.ts.map +1 -1
  387. package/src/shade/renderer/rasterize/native/oit/graph_rasterize_meshes_transparent_oit.js +2 -1
  388. package/src/shade/renderer/rasterize/native/rasterization_shader_resources.d.ts.map +1 -1
  389. package/src/shade/renderer/rasterize/native/rasterization_shader_resources.js +4 -0
  390. package/src/shade/renderer/rasterize/native/viz/viz_rasterization_alpha_tested_pass_descriptor.d.ts.map +1 -1
  391. package/src/shade/renderer/rasterize/native/viz/viz_rasterization_alpha_tested_pass_descriptor.js +16 -7
  392. package/src/shade/renderer/rasterize/standard/graph_rasterize_partial_opaque.d.ts.map +1 -1
  393. package/src/shade/renderer/rasterize/standard/graph_rasterize_partial_opaque.js +85 -89
  394. package/src/shade/renderer/rasterize/standard/graph_rasterize_remaining_opaque.d.ts.map +1 -1
  395. package/src/shade/renderer/rasterize/standard/graph_rasterize_remaining_opaque.js +28 -32
  396. package/src/shade/renderer/scene/GPUSceneContext.d.ts +22 -2
  397. package/src/shade/renderer/scene/GPUSceneContext.d.ts.map +1 -1
  398. package/src/shade/renderer/scene/GPUSceneContext.js +61 -4
  399. package/src/shade/renderer/scene/NODE3D_STRUCT.d.ts +19 -0
  400. package/src/shade/renderer/scene/NODE3D_STRUCT.d.ts.map +1 -1
  401. package/src/shade/renderer/scene/NODE3D_STRUCT.js +34 -0
  402. package/src/shade/renderer/scene/chunk_node3d_flags.d.ts +9 -0
  403. package/src/shade/renderer/scene/chunk_node3d_flags.d.ts.map +1 -0
  404. package/src/shade/renderer/scene/chunk_node3d_flags.js +23 -0
  405. package/src/shade/renderer/scene/chunk_scene_database_access.d.ts.map +1 -1
  406. package/src/shade/renderer/scene/chunk_scene_database_access.js +15 -1
  407. package/src/shade/renderer/scene/rows/GPUSceneRows.d.ts.map +1 -1
  408. package/src/shade/renderer/scene/rows/GPUSceneRows.js +9 -1
  409. package/src/shade/renderer/shader/chunk/geometry/mat4/chunk_compute_normal_matrix_from_m4.d.ts +7 -0
  410. package/src/shade/renderer/shader/chunk/geometry/mat4/chunk_compute_normal_matrix_from_m4.d.ts.map +1 -1
  411. package/src/shade/renderer/shader/chunk/geometry/mat4/chunk_compute_normal_matrix_from_m4.js +16 -4
  412. package/src/shade/renderer/shader/chunk/geometry/mat4/chunk_mat4_linear_determinant.d.ts +12 -0
  413. package/src/shade/renderer/shader/chunk/geometry/mat4/chunk_mat4_linear_determinant.d.ts.map +1 -0
  414. package/src/shade/renderer/shader/chunk/geometry/mat4/chunk_mat4_linear_determinant.js +18 -0
  415. package/src/shade/renderer/shader/chunk/geometry/triangle/chunk_triangle_list_reverse_winding.d.ts +24 -0
  416. package/src/shade/renderer/shader/chunk/geometry/triangle/chunk_triangle_list_reverse_winding.d.ts.map +1 -0
  417. package/src/shade/renderer/shader/chunk/geometry/triangle/chunk_triangle_list_reverse_winding.js +33 -0
  418. package/src/shade/renderer/shader/resource/ShaderResourceSetDescriptor.d.ts.map +1 -1
  419. package/src/shade/renderer/shader/resource/ShaderResourceSetDescriptor.js +92 -16
  420. package/src/shade/renderer/view/GPUViewContext.d.ts +5 -0
  421. package/src/shade/renderer/view/GPUViewContext.d.ts.map +1 -1
  422. package/src/shade/renderer/view/GPUViewContext.js +21 -0
  423. package/src/shade/wgsl/emulator/WGSLLanguageCore.d.ts.map +1 -1
  424. package/src/shade/wgsl/emulator/WGSLLanguageCore.js +74 -3
  425. package/src/shade/playground/vgeo_viewer/README.md +0 -150
  426. package/src/shade/playground/vgeo_viewer/cut_geometry.js +0 -460
  427. package/src/shade/playground/vgeo_viewer/index.html +0 -77
  428. package/src/shade/playground/vgeo_viewer/main.js +0 -1343
  429. package/src/shade/playground/vgeo_viewer/select_cut.js +0 -481
  430. package/src/shade/renderer/geometry/virtual/residency/VGeoResidencyManager.d.ts +0 -258
  431. package/src/shade/renderer/geometry/virtual/residency/VGeoResidencyManager.d.ts.map +0 -1
  432. package/src/shade/renderer/geometry/virtual/residency/VGeoResidencyManager.js +0 -723
  433. package/src/shade/renderer/geometry/virtual/residency/VGeoResidencyOptions.d.ts +0 -49
  434. package/src/shade/renderer/geometry/virtual/residency/VGeoResidencyOptions.d.ts.map +0 -1
  435. package/src/shade/renderer/geometry/virtual/residency/VGeoResidencyOptions.js +0 -50
  436. package/src/shade/renderer/loader/gltf/fix_up_material_sides.js +0 -109
  437. package/src/shade/renderer/rasterize/expand/graph_triangles_filter_by_material_side.js +0 -78
  438. package/src/shade/renderer/rasterize/expand/shader_filter_triangle_by_material_side.js +0 -100
  439. package/src/shade/renderer/rasterize/forward/chunk_material_side_should_draw.js +0 -26
  440. package/src/shade/renderer/shader/chunk/jobs/NOTES.md +0 -47
  441. package/src/shade/renderer/shader/chunk/jobs/chunk_job_system.d.ts +0 -3
  442. package/src/shade/renderer/shader/chunk/jobs/chunk_job_system.d.ts.map +0 -1
  443. package/src/shade/renderer/shader/chunk/jobs/chunk_job_system.js +0 -102
  444. /package/src/shade/renderer/geometry/virtual/build/{VGeoLevel.js → level/VGeoLevel.js} +0 -0
  445. /package/src/shade/renderer/geometry/virtual/build/{VGeoLevelOptions.js → level/VGeoLevelOptions.js} +0 -0
  446. /package/src/shade/renderer/geometry/virtual/build/{VGeoLevelSummary.js → level/VGeoLevelSummary.js} +0 -0
  447. /package/src/shade/renderer/geometry/virtual/build/{vgeo_graph_components.js → partition/vgeo_graph_components.js} +0 -0
  448. /package/src/shade/renderer/geometry/virtual/build/{VGeoGatheredFaces.js → submesh/VGeoGatheredFaces.js} +0 -0
  449. /package/src/shade/renderer/geometry/virtual/build/{VGeoSubmesh.js → submesh/VGeoSubmesh.js} +0 -0
@@ -1,3 +1,7 @@
1
+ /**
2
+ * @typedef {import("./GPUVirtualGeometryPool.js").GPUVirtualGeometryPool} GPUVirtualGeometryPool
3
+ * @typedef {import("../../../../../engine/graphics/render/frame_graph/FrameGraph.js").FrameGraph} FrameGraph
4
+ */
1
5
  /**
2
6
  * What one frame of virtual geometry needs that is not a page: the threshold, the feedback buffer
3
7
  * every view writes into, and the parameters every pass reads.
@@ -19,27 +23,28 @@ export class GPUVirtualGeometryRuntime {
19
23
  /**
20
24
  * @param {Object} options
21
25
  * @param {GPUVirtualGeometryPool} options.pool
22
- * @param {GPUDevice} options.device
23
26
  * @param {number} [options.want_capacity] pages one frame may ask for, across every view
24
- * @param {number} [options.touch_capacity] page rows one frame may report drawing from
25
27
  * @param {number} [options.visible_instance_hint] VG instances one expansion site is expected
26
28
  * to see; what {@link claim_word_capacity} is sized from, and nothing else
27
29
  * @param {number} [options.claim_word_capacity] words of the per-invocation claim bitmask,
28
30
  * overriding the derivation below
29
31
  * @param {number} [options.queue_capacity] traversal items one wavefront may hold
30
- * @param {number} [options.max_iterations] wavefronts before the descent is abandoned
31
- * @param {number} [options.cluster_chunk] clusters one group-chunk item covers
32
+ * @param {number} [options.max_iterations] wavefronts before the descent is abandoned, to start
33
+ * with; the runtime raises it from what the cut reports
34
+ * @param {number} [options.max_iteration_ceiling] as far as that raising may go
35
+ * @param {number} [options.descent_steps] steps of the descent one traversal dispatch runs
36
+ * before handing back what it still holds; see the traversal kernel for why it cannot
37
+ * simply stop when the wave runs dry
32
38
  */
33
- constructor({ pool, device, want_capacity, touch_capacity, visible_instance_hint, claim_word_capacity, queue_capacity, max_iterations, cluster_chunk, }: {
39
+ constructor({ pool, want_capacity, visible_instance_hint, claim_word_capacity, queue_capacity, max_iterations, max_iteration_ceiling, descent_steps, }: {
34
40
  pool: GPUVirtualGeometryPool;
35
- device: GPUDevice;
36
41
  want_capacity?: number;
37
- touch_capacity?: number;
38
42
  visible_instance_hint?: number;
39
43
  claim_word_capacity?: number;
40
44
  queue_capacity?: number;
41
45
  max_iterations?: number;
42
- cluster_chunk?: number;
46
+ max_iteration_ceiling?: number;
47
+ descent_steps?: number;
43
48
  });
44
49
  /**
45
50
  * Pixels of permitted error — the single quality/perf lever, and a runtime dial by design §4.
@@ -53,11 +58,13 @@ export class GPUVirtualGeometryRuntime {
53
58
  /**
54
59
  * @returns {GPUVirtualGeometryPool}
55
60
  */
56
- get pool(): GPUVirtualGeometryPool;
61
+ get pool(): import("./GPUVirtualGeometryPool.js").GPUVirtualGeometryPool;
57
62
  /**
58
- * @returns {GPUBuffer}
63
+ * Pages one frame may ask for, across every view.
64
+ *
65
+ * @returns {number}
59
66
  */
60
- get params_buffer(): GPUBuffer;
67
+ get want_capacity(): number;
61
68
  /**
62
69
  * @returns {number}
63
70
  */
@@ -67,9 +74,70 @@ export class GPUVirtualGeometryRuntime {
67
74
  */
68
75
  get claim_word_capacity(): number;
69
76
  /**
77
+ * Wavefronts the descent may run, as the runtime currently understands this scene.
78
+ *
79
+ * A **high-water mark**, not a setting: it starts where the host put it and is raised by
80
+ * {@link note_incomplete_descent} from what the cut reports. `graph_vgeo_expand_instances_to_meshlets`
81
+ * reads it while it is recording passes, so a rise lands on the next frame.
82
+ *
70
83
  * @returns {number}
71
84
  */
72
85
  get max_iterations(): number;
86
+ /**
87
+ * Times the bound has been raised. Zero for the whole life of almost every scene; a small
88
+ * number, once, for one that needed more than it was given.
89
+ *
90
+ * @returns {number}
91
+ */
92
+ get iteration_escalations(): number;
93
+ /**
94
+ * @returns {number}
95
+ */
96
+ get iteration_ceiling(): number;
97
+ /**
98
+ * A reading saying the descent stopped with work still queued — raise the bound and keep it
99
+ * raised.
100
+ *
101
+ * **This is the only place the engine can learn it.** How many wavefronts a cut needs is a
102
+ * function of the frontier's *breadth*, which is a function of the scene, the viewpoint and the
103
+ * render target together; the kernel cannot know it before it runs and the host cannot know it
104
+ * at all. So the bound is guessed low, and the one reading that says the guess was wrong —
105
+ * `VGEO_CUT_STAT.QUEUE_REMAINING`, non-zero exactly when items were abandoned — pays for
106
+ * correcting it. It is the same shape as the rasterizer's meshlet counts, which cannot be known
107
+ * before the expansion runs either and are grown from what the frame reported.
108
+ *
109
+ * **Doubling, because the reading does not say how much more was needed.** A remainder is a
110
+ * count of *items*, and what they cost in wavefronts depends on how they spill; there is no
111
+ * ratio to convert one into the other. So it goes up by a factor until it drains, which is at
112
+ * most three steps from 8 to the ceiling.
113
+ *
114
+ * **Never lowered.** A frame that drained is evidence about that frame, not that the scene got
115
+ * smaller — and a bound that fell back would re-learn the same lesson every time the camera
116
+ * turned away and back, at a hole a time. An unused wavefront is an empty indirect dispatch,
117
+ * which is the cheap side of that trade.
118
+ *
119
+ * What it costs when it is wrong is bounded by the readback: the cut is capped at two readings
120
+ * in flight and skips frames when saturated, so the scene draws with a hole for the few frames
121
+ * between the first truncated descent and the reading that reports it — and then never again.
122
+ *
123
+ * @param {number} remaining items the descent still held when it was abandoned
124
+ * @returns {boolean} whether the bound moved
125
+ */
126
+ note_incomplete_descent(remaining: number): boolean;
127
+ /**
128
+ * Settable, like tau, and for the same reason: it is a quality-of-schedule dial whose right
129
+ * value is a property of the asset's depth and the scene's breadth together rather than of the
130
+ * engine. `begin_frame` re-writes the params every frame, so a change lands on the next one.
131
+ *
132
+ * @param {number} value
133
+ */
134
+ set descent_steps(value: number);
135
+ /**
136
+ * Steps of the descent one traversal dispatch runs.
137
+ *
138
+ * @returns {number}
139
+ */
140
+ get descent_steps(): number;
73
141
  /**
74
142
  * This frame's feedback resource. Every expansion site writes into it and one readback reads it.
75
143
  * @returns {number}
@@ -95,31 +163,42 @@ export class GPUVirtualGeometryRuntime {
95
163
  * @returns {ReturnType<vgeo_cut_feedback_layout>}
96
164
  */
97
165
  get feedback_layout(): {
98
- touch_stamp_base: number;
99
- want_stamp_base: number;
166
+ touch_bits_base: number;
167
+ /**
168
+ * @type {number}
169
+ */
170
+ touch_word_count: number;
100
171
  want_base: number;
101
- touch_base: number;
102
- word_count: number;
172
+ word_count: number; /**
173
+ * @type {number}
174
+ */
103
175
  };
104
176
  /**
105
177
  * Open a frame: publish the page tables, size the feedback buffer against what is resident, and
106
178
  * write the parameters every pass of every view will read.
107
179
  *
108
- * The sizing happens here rather than at construction because two of its terms move with
109
- * residency — one touch stamp per page-table row, one want stamp per lookup word — and a frame
110
- * is the coarsest granularity at which they hold still.
180
+ * The sizing happens here rather than at construction because one of its terms moves with
181
+ * residency — one touch bit per page-table row — and a frame is the coarsest granularity at
182
+ * which it holds still.
111
183
  *
112
- * @param {FrameGraph} graph
113
- * @param {Object} view
114
- * @param {number} view.screen_height pixels of the render target
115
- * @param {number} view.fov_y radians
116
- * @param {number} [view.meshlet_capacity] records the shared meshlet collection holds
184
+ * **The pool's frame advances here, before the flush**, and not at `end_frame`. The frame
185
+ * number is what stamps a page row's `visible_from` — the frame whose flush publishes the
186
+ * row's occupant — and what a reading compares it against. With the advance here, an install
187
+ * landing anywhere after this frame's flush is stamped for the next one and rejected by this
188
+ * frame's reading, exactly (RUNTIME_PLAN_2026_09_14 §2.4). It is also the clock both tiers'
189
+ * protect windows read, and it moves whether or not a readback is scheduled this frame.
190
+ *
191
+ * **A frame has no projection.** It used to take one, and wrote it into a params buffer
192
+ * every view then shared — so a shadow cascade cut against whichever view opened the
193
+ * frame. `projection_k` is a property of a render target and a camera, which is to say of
194
+ * a view, and it lives on {@link VGeoViewCut} with the rest of what a view owns alone.
195
+ *
196
+ * @param {Object} options
197
+ * @param {FrameGraph} options.graph
117
198
  * @returns {number} the feedback resource
118
199
  */
119
- begin_frame(graph: FrameGraph, { screen_height, fov_y }: {
120
- screen_height: number;
121
- fov_y: number;
122
- meshlet_capacity?: number;
200
+ begin_frame({ graph }: {
201
+ graph: FrameGraph;
123
202
  }): number;
124
203
  /**
125
204
  * What one expansion site was handed, folded into the parameters every pass of the frame reads.
@@ -162,7 +241,7 @@ export class GPUVirtualGeometryRuntime {
162
241
  *
163
242
  * @returns {FrameGraph|undefined}
164
243
  */
165
- get frame_graph(): any;
244
+ get frame_graph(): import("../../../../../engine/graphics/render/frame_graph/FrameGraph.js").FrameGraph;
166
245
  /**
167
246
  * Close a frame. The feedback resource stops being valid; reading it is
168
247
  * {@link VGeoFeedbackLoop}'s, which schedules the readback while the graph is still being built.
@@ -170,7 +249,8 @@ export class GPUVirtualGeometryRuntime {
170
249
  * @returns {void}
171
250
  */
172
251
  end_frame(): void;
173
- destroy(): void;
174
252
  #private;
175
253
  }
254
+ export type GPUVirtualGeometryPool = import("./GPUVirtualGeometryPool.js").GPUVirtualGeometryPool;
255
+ export type FrameGraph = import("../../../../../engine/graphics/render/frame_graph/FrameGraph.js").FrameGraph;
176
256
  //# sourceMappingURL=GPUVirtualGeometryRuntime.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"GPUVirtualGeometryRuntime.d.ts","sourceRoot":"","sources":["../../../../../../../src/shade/renderer/geometry/virtual/runtime/GPUVirtualGeometryRuntime.js"],"names":[],"mappings":"AAQA;;;;;;;;;;;;;;;;GAgBG;AACH;IAwFI;;;;;;;;;;;;;OAaG;IACH;QAZ2C,IAAI;QACjB,MAAM;QACR,aAAa,GAA9B,MAAM;QACW,cAAc,GAA/B,MAAM;QACW,qBAAqB,GAAtC,MAAM;QAEW,mBAAmB,GAApC,MAAM;QAEW,cAAc,GAA/B,MAAM;QACW,cAAc,GAA/B,MAAM;QACW,aAAa,GAA9B,MAAM;OAqDhB;IA3GD;;;OAGG;IACH,KAFU,MAAM,CAER;IAER;;OAEG;IACH,cAFU,OAAO,CAEG;IAoGpB;;OAEG;IACH,mCAEC;IAED;;OAEG;IACH,+BAEC;IAED;;OAEG;IACH,6BAEC;IAED;;OAEG;IACH,kCAEC;IAED;;OAEG;IACH,6BAEC;IAED;;;OAGG;IACH,uBAEC;IAED;;;;;;;;;;;;;;OAcG;IACH,yBAHW,MAAM,GACJ,IAAI,CAMhB;IAED;;OAEG;IACH;;;;;;MAEC;IAED;;;;;;;;;;;;;;OAcG;IACH;QALwB,aAAa,EAA1B,MAAM;QACO,KAAK,EAAlB,MAAM;QACQ,gBAAgB,GAA9B,MAAM;QACJ,MAAM,CAqClB;IAED;;;;;;;;;;;;;;;;;OAiBG;IACH;QAJ2B,iBAAiB,EAAjC,MAAM;QACU,gBAAgB,EAAhC,MAAM;QACJ,IAAI,CAehB;IAED;;OAEG;IACH,gCAEC;IAED;;OAEG;IACH,+BAEC;IAED;;;;;;;;;;OAUG;IACH,uBAEC;IAyBD;;;;;OAKG;IACH,aAFa,IAAI,CAOhB;IAED,gBAEC;;CACJ"}
1
+ {"version":3,"file":"GPUVirtualGeometryRuntime.d.ts","sourceRoot":"","sources":["../../../../../../../src/shade/renderer/geometry/virtual/runtime/GPUVirtualGeometryRuntime.js"],"names":[],"mappings":"AAKA;;;GAGG;AAEH;;;;;;;;;;;;;;;;GAgBG;AACH;IAkFI;;;;;;;;;;;;;;;OAeG;IACH;QAd2C,IAAI,EAApC,sBAAsB;QACL,aAAa,GAA9B,MAAM;QACW,qBAAqB,GAAtC,MAAM;QAEW,mBAAmB,GAApC,MAAM;QAEW,cAAc,GAA/B,MAAM;QACW,cAAc,GAA/B,MAAM;QAEW,qBAAqB,GAAtC,MAAM;QACW,aAAa,GAA9B,MAAM;OAkFhB;IApID;;;OAGG;IACH,KAFU,MAAM,CAER;IAER;;OAEG;IACH,cAFU,OAAO,CAEG;IA6HpB;;OAEG;IACH,yEAEC;IAED;;;;OAIG;IACH,4BAEC;IAED;;OAEG;IACH,6BAEC;IAED;;OAEG;IACH,kCAEC;IAED;;;;;;;;OAQG;IACH,6BAEC;IAED;;;;;OAKG;IACH,oCAEC;IAED;;OAEG;IACH,gCAEC;IAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;OA4BG;IACH,mCAHW,MAAM,GACJ,OAAO,CAanB;IAWD;;;;;;OAMG;IACH,iCAKC;IArBD;;;;OAIG;IACH,4BAEC;IAgBD;;;OAGG;IACH,uBAEC;IAED;;;;;;;;;;;;;;OAcG;IACH,yBAHW,MAAM,GACJ,IAAI,CAMhB;IAED;;OAEG;IACH;;QAvUA;;WAEG;;;4BAIH;;WAEG;MAiUF;IAED;;;;;;;;;;;;;;;;;;;;;;;OAuBG;IACH;QAH+B,KAAK,EAAzB,UAAU;QACR,MAAM,CA+BlB;IAED;;;;;;;;;;;;;;;;;OAiBG;IACH;QAJ2B,iBAAiB,EAAjC,MAAM;QACU,gBAAgB,EAAhC,MAAM;QACJ,IAAI,CAahB;IAED;;OAEG;IACH,gCAEC;IAED;;OAEG;IACH,+BAEC;IAED;;;;;;;;;;OAUG;IACH,wGAEC;IAGD;;;;;OAKG;IACH,aAFa,IAAI,CAKhB;;CACJ;qCAteY,OAAO,6BAA6B,EAAE,sBAAsB;yBAC5D,OAAO,iEAAiE,EAAE,UAAU"}
@@ -1,11 +1,13 @@
1
1
  import { assert } from "../../../../../core/assert.js";
2
2
  import { BufferResourceDescriptor } from "../../../../device/graph/BufferResourceDescriptor.js";
3
3
  import { noop } from "../../../../../core/function/noop.js";
4
- import { write_gpu_typed_buffer } from "../../../shader/type/serde/write_gpu_typed_buffer.js";
5
- import { VGEO_CUT_FLAG_CULL } from "./cut/VGEO_CUT_FLAG_CULL.js";
6
- import { VGEO_CUT_PARAMS_STRUCT } from "./cut/VGEO_CUT_PARAMS_STRUCT.js";
7
4
  import { vgeo_cut_feedback_layout } from "./cut/vgeo_cut_feedback_layout.js";
8
5
 
6
+ /**
7
+ * @typedef {import("./GPUVirtualGeometryPool.js").GPUVirtualGeometryPool} GPUVirtualGeometryPool
8
+ * @typedef {import("../../../../../engine/graphics/render/frame_graph/FrameGraph.js").FrameGraph} FrameGraph
9
+ */
10
+
9
11
  /**
10
12
  * What one frame of virtual geometry needs that is not a page: the threshold, the feedback buffer
11
13
  * every view writes into, and the parameters every pass reads.
@@ -29,45 +31,43 @@ export class GPUVirtualGeometryRuntime {
29
31
  */
30
32
  #pool;
31
33
 
32
- /**
33
- * @type {GPUDevice}
34
- */
35
- #device;
34
+
36
35
 
37
36
  /**
38
- * @type {GPUBuffer}
37
+ * @type {number}
39
38
  */
40
- #params;
39
+ #want_capacity;
40
+
41
41
 
42
42
  /**
43
43
  * @type {number}
44
44
  */
45
- #want_capacity;
45
+ #claim_word_capacity;
46
46
 
47
47
  /**
48
48
  * @type {number}
49
49
  */
50
- #touch_capacity;
50
+ #queue_capacity;
51
51
 
52
52
  /**
53
53
  * @type {number}
54
54
  */
55
- #claim_word_capacity;
55
+ #max_iterations;
56
56
 
57
57
  /**
58
58
  * @type {number}
59
59
  */
60
- #queue_capacity;
60
+ #iteration_ceiling;
61
61
 
62
62
  /**
63
63
  * @type {number}
64
64
  */
65
- #max_iterations;
65
+ #iteration_escalations = 0;
66
66
 
67
67
  /**
68
68
  * @type {number}
69
69
  */
70
- #cluster_chunk;
70
+ #descent_steps;
71
71
 
72
72
  /**
73
73
  * Pixels of permitted error — the single quality/perf lever, and a runtime dial by design §4.
@@ -96,10 +96,6 @@ export class GPUVirtualGeometryRuntime {
96
96
  */
97
97
  #graph;
98
98
 
99
- /**
100
- * @type {number}
101
- */
102
- #projection_k = 1;
103
99
 
104
100
  /**
105
101
  * @type {number}
@@ -114,22 +110,22 @@ export class GPUVirtualGeometryRuntime {
114
110
  /**
115
111
  * @param {Object} options
116
112
  * @param {GPUVirtualGeometryPool} options.pool
117
- * @param {GPUDevice} options.device
118
113
  * @param {number} [options.want_capacity] pages one frame may ask for, across every view
119
- * @param {number} [options.touch_capacity] page rows one frame may report drawing from
120
114
  * @param {number} [options.visible_instance_hint] VG instances one expansion site is expected
121
115
  * to see; what {@link claim_word_capacity} is sized from, and nothing else
122
116
  * @param {number} [options.claim_word_capacity] words of the per-invocation claim bitmask,
123
117
  * overriding the derivation below
124
118
  * @param {number} [options.queue_capacity] traversal items one wavefront may hold
125
- * @param {number} [options.max_iterations] wavefronts before the descent is abandoned
126
- * @param {number} [options.cluster_chunk] clusters one group-chunk item covers
119
+ * @param {number} [options.max_iterations] wavefronts before the descent is abandoned, to start
120
+ * with; the runtime raises it from what the cut reports
121
+ * @param {number} [options.max_iteration_ceiling] as far as that raising may go
122
+ * @param {number} [options.descent_steps] steps of the descent one traversal dispatch runs
123
+ * before handing back what it still holds; see the traversal kernel for why it cannot
124
+ * simply stop when the wave runs dry
127
125
  */
128
126
  constructor({
129
127
  pool,
130
- device,
131
128
  want_capacity = 2048,
132
- touch_capacity = 8192,
133
129
  visible_instance_hint = 1024,
134
130
  /*
135
131
  One bit per (instance, page ordinal), and the two terms are the *pool's* page
@@ -156,26 +152,55 @@ export class GPUVirtualGeometryRuntime {
156
152
  with work outstanding, which is the one degradation that costs a hole.
157
153
  */
158
154
  queue_capacity = 1 << 16,
159
- max_iterations = 64,
160
- cluster_chunk = 8,
155
+ /*
156
+ Where the wavefront bound *starts*. It is raised by the runtime itself when a
157
+ reading says the descent could not finish — see {@link note_incomplete_descent}
158
+ — so this is the cost a scene pays until it has been told otherwise rather than
159
+ a limit anyone has to get right in advance.
160
+
161
+ Eight is what almost every cut needs: one container at a modest viewport drains
162
+ in six. A converted scene at 3441×1440 does not, and nothing on the host can
163
+ know that before the kernel has run.
164
+ */
165
+ max_iterations = 8,
166
+ /*
167
+ And where it stops. A frontier that genuinely cannot be drained inside any
168
+ budget would otherwise climb until the frame graph is nothing but empty
169
+ dispatches; a hole is the better failure, because it is visible and
170
+ `QUEUE_REMAINING` goes on reporting it. Measured peak need on the scene that
171
+ found this was 12 to 13.
172
+ */
173
+ max_iteration_ceiling = 64,
174
+ /*
175
+ Steps of the in-kernel descent one dispatch runs, and the knob that is *not*
176
+ the safety bound — `max_iterations` is, and lowering this spends it. A wave
177
+ keeps one child per lane and spills the rest, so a dispatch advances what it
178
+ held by `descent_steps` levels and hands the rest to the next one: the
179
+ dispatches a cut needs are `ceil(depth / descent_steps)` plus its spill
180
+ generations, not `depth / descent_steps`. Running out of dispatches is
181
+ `VGEO_CUT_STAT.QUEUE_REMAINING`, and that is a hole rather than coarseness.
182
+
183
+ Measured over a full orbit of the deepest converted Zorah container — 27.9M
184
+ faces, 17,172 pages, 39 levels — at tau 1, the dispatches it needs are 6 at 32
185
+ and at 24, 7 at 20, all 8 at 16 and at 12, and more than 8 below that. So 24 is
186
+ the most this can be lowered for nothing: the same six dispatches 32 needs,
187
+ with a quarter fewer idle steps inside each. `DRAWN` is bit-identical at every
188
+ value that drains, which is what makes this a schedule knob and not a quality
189
+ one.
190
+ */
191
+ descent_steps = 24,
161
192
  }) {
162
193
  assert.defined(pool, 'pool');
163
- assert.defined(device, 'device');
164
194
 
165
195
  this.#pool = pool;
166
- this.#device = device;
167
196
  this.#want_capacity = want_capacity;
168
- this.#touch_capacity = touch_capacity;
169
197
  this.#claim_word_capacity = claim_word_capacity;
170
198
  this.#queue_capacity = queue_capacity;
171
199
  this.#max_iterations = max_iterations;
172
- this.#cluster_chunk = cluster_chunk;
200
+ this.#iteration_ceiling = Math.max(max_iterations, max_iteration_ceiling);
201
+ this.#descent_steps = descent_steps;
202
+
173
203
 
174
- this.#params = device.createBuffer({
175
- label: 'GPUVirtualGeometryRuntime/params',
176
- size: VGEO_CUT_PARAMS_STRUCT.aligned_size,
177
- usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST,
178
- });
179
204
  }
180
205
 
181
206
  /**
@@ -186,10 +211,12 @@ export class GPUVirtualGeometryRuntime {
186
211
  }
187
212
 
188
213
  /**
189
- * @returns {GPUBuffer}
214
+ * Pages one frame may ask for, across every view.
215
+ *
216
+ * @returns {number}
190
217
  */
191
- get params_buffer() {
192
- return this.#params;
218
+ get want_capacity() {
219
+ return this.#want_capacity;
193
220
  }
194
221
 
195
222
  /**
@@ -207,12 +234,100 @@ export class GPUVirtualGeometryRuntime {
207
234
  }
208
235
 
209
236
  /**
237
+ * Wavefronts the descent may run, as the runtime currently understands this scene.
238
+ *
239
+ * A **high-water mark**, not a setting: it starts where the host put it and is raised by
240
+ * {@link note_incomplete_descent} from what the cut reports. `graph_vgeo_expand_instances_to_meshlets`
241
+ * reads it while it is recording passes, so a rise lands on the next frame.
242
+ *
210
243
  * @returns {number}
211
244
  */
212
245
  get max_iterations() {
213
246
  return this.#max_iterations;
214
247
  }
215
248
 
249
+ /**
250
+ * Times the bound has been raised. Zero for the whole life of almost every scene; a small
251
+ * number, once, for one that needed more than it was given.
252
+ *
253
+ * @returns {number}
254
+ */
255
+ get iteration_escalations() {
256
+ return this.#iteration_escalations;
257
+ }
258
+
259
+ /**
260
+ * @returns {number}
261
+ */
262
+ get iteration_ceiling() {
263
+ return this.#iteration_ceiling;
264
+ }
265
+
266
+ /**
267
+ * A reading saying the descent stopped with work still queued — raise the bound and keep it
268
+ * raised.
269
+ *
270
+ * **This is the only place the engine can learn it.** How many wavefronts a cut needs is a
271
+ * function of the frontier's *breadth*, which is a function of the scene, the viewpoint and the
272
+ * render target together; the kernel cannot know it before it runs and the host cannot know it
273
+ * at all. So the bound is guessed low, and the one reading that says the guess was wrong —
274
+ * `VGEO_CUT_STAT.QUEUE_REMAINING`, non-zero exactly when items were abandoned — pays for
275
+ * correcting it. It is the same shape as the rasterizer's meshlet counts, which cannot be known
276
+ * before the expansion runs either and are grown from what the frame reported.
277
+ *
278
+ * **Doubling, because the reading does not say how much more was needed.** A remainder is a
279
+ * count of *items*, and what they cost in wavefronts depends on how they spill; there is no
280
+ * ratio to convert one into the other. So it goes up by a factor until it drains, which is at
281
+ * most three steps from 8 to the ceiling.
282
+ *
283
+ * **Never lowered.** A frame that drained is evidence about that frame, not that the scene got
284
+ * smaller — and a bound that fell back would re-learn the same lesson every time the camera
285
+ * turned away and back, at a hole a time. An unused wavefront is an empty indirect dispatch,
286
+ * which is the cheap side of that trade.
287
+ *
288
+ * What it costs when it is wrong is bounded by the readback: the cut is capped at two readings
289
+ * in flight and skips frames when saturated, so the scene draws with a hole for the few frames
290
+ * between the first truncated descent and the reading that reports it — and then never again.
291
+ *
292
+ * @param {number} remaining items the descent still held when it was abandoned
293
+ * @returns {boolean} whether the bound moved
294
+ */
295
+ note_incomplete_descent(remaining) {
296
+ assert.isNonNegativeInteger(remaining, 'remaining');
297
+
298
+ if (remaining === 0 || this.#max_iterations >= this.#iteration_ceiling) {
299
+ return false;
300
+ }
301
+
302
+ this.#max_iterations = Math.min(this.#max_iterations * 2, this.#iteration_ceiling);
303
+ this.#iteration_escalations++;
304
+
305
+ return true;
306
+ }
307
+
308
+ /**
309
+ * Steps of the descent one traversal dispatch runs.
310
+ *
311
+ * @returns {number}
312
+ */
313
+ get descent_steps() {
314
+ return this.#descent_steps;
315
+ }
316
+
317
+ /**
318
+ * Settable, like tau, and for the same reason: it is a quality-of-schedule dial whose right
319
+ * value is a property of the asset's depth and the scene's breadth together rather than of the
320
+ * engine. `begin_frame` re-writes the params every frame, so a change lands on the next one.
321
+ *
322
+ * @param {number} value
323
+ */
324
+ set descent_steps(value) {
325
+ assert.isNonNegativeInteger(value, 'descent_steps');
326
+ assert.greaterThan(value, 0, 'descent_steps');
327
+
328
+ this.#descent_steps = value;
329
+ }
330
+
216
331
  /**
217
332
  * This frame's feedback resource. Every expansion site writes into it and one readback reads it.
218
333
  * @returns {number}
@@ -253,28 +368,35 @@ export class GPUVirtualGeometryRuntime {
253
368
  * Open a frame: publish the page tables, size the feedback buffer against what is resident, and
254
369
  * write the parameters every pass of every view will read.
255
370
  *
256
- * The sizing happens here rather than at construction because two of its terms move with
257
- * residency — one touch stamp per page-table row, one want stamp per lookup word — and a frame
258
- * is the coarsest granularity at which they hold still.
371
+ * The sizing happens here rather than at construction because one of its terms moves with
372
+ * residency — one touch bit per page-table row — and a frame is the coarsest granularity at
373
+ * which it holds still.
374
+ *
375
+ * **The pool's frame advances here, before the flush**, and not at `end_frame`. The frame
376
+ * number is what stamps a page row's `visible_from` — the frame whose flush publishes the
377
+ * row's occupant — and what a reading compares it against. With the advance here, an install
378
+ * landing anywhere after this frame's flush is stamped for the next one and rejected by this
379
+ * frame's reading, exactly (RUNTIME_PLAN_2026_09_14 §2.4). It is also the clock both tiers'
380
+ * protect windows read, and it moves whether or not a readback is scheduled this frame.
381
+ *
382
+ * **A frame has no projection.** It used to take one, and wrote it into a params buffer
383
+ * every view then shared — so a shadow cascade cut against whichever view opened the
384
+ * frame. `projection_k` is a property of a render target and a camera, which is to say of
385
+ * a view, and it lives on {@link VGeoViewCut} with the rest of what a view owns alone.
259
386
  *
260
- * @param {FrameGraph} graph
261
- * @param {Object} view
262
- * @param {number} view.screen_height pixels of the render target
263
- * @param {number} view.fov_y radians
264
- * @param {number} [view.meshlet_capacity] records the shared meshlet collection holds
387
+ * @param {Object} options
388
+ * @param {FrameGraph} options.graph
265
389
  * @returns {number} the feedback resource
266
390
  */
267
- begin_frame(graph, { screen_height, fov_y }) {
391
+ begin_frame({ graph }) {
268
392
  assert.defined(graph, 'graph');
269
- assert.greaterThan(screen_height, 0, 'screen_height');
270
393
 
394
+ this.#pool.advance_frame();
271
395
  this.#pool.flush();
272
396
 
273
397
  this.#layout = vgeo_cut_feedback_layout({
274
398
  page_row_capacity: this.#pool.page_row_capacity,
275
- lookup_word_count: this.#pool.lookup_word_count,
276
399
  want_capacity: this.#want_capacity,
277
- touch_capacity: this.#touch_capacity,
278
400
  });
279
401
 
280
402
  const spawn = graph.add('vgeo/frame', {}, noop);
@@ -294,10 +416,6 @@ export class GPUVirtualGeometryRuntime {
294
416
  this.#instance_capacity = 0;
295
417
  this.#meshlet_capacity = 0;
296
418
 
297
- this.#projection_k = screen_height / (2 * Math.tan(fov_y * 0.5));
298
-
299
- this.#write_params();
300
-
301
419
  return this.#feedback;
302
420
  }
303
421
 
@@ -330,8 +448,6 @@ export class GPUVirtualGeometryRuntime {
330
448
  this.#meshlet_capacity = this.#meshlet_capacity === 0
331
449
  ? meshlet_capacity
332
450
  : Math.min(this.#meshlet_capacity, meshlet_capacity);
333
-
334
- this.#write_params();
335
451
  }
336
452
 
337
453
  /**
@@ -363,28 +479,6 @@ export class GPUVirtualGeometryRuntime {
363
479
  return this.#graph;
364
480
  }
365
481
 
366
- /**
367
- * @returns {void}
368
- */
369
- #write_params() {
370
- write_gpu_typed_buffer_to_device(this.#device, this.#params, {
371
- tau: this.tau,
372
- projection_k: this.#projection_k,
373
- queue_capacity: this.#queue_capacity,
374
- claim_word_count: this.#claim_word_capacity,
375
- cluster_chunk: this.#cluster_chunk,
376
- page_slot_words: this.#pool.page_slot_words,
377
- touch_stamp_base: this.#layout.touch_stamp_base,
378
- want_stamp_base: this.#layout.want_stamp_base,
379
- want_base: this.#layout.want_base,
380
- want_capacity: this.#want_capacity,
381
- touch_base: this.#layout.touch_base,
382
- touch_capacity: this.#touch_capacity,
383
- instance_capacity: this.#instance_capacity,
384
- meshlet_capacity: this.#meshlet_capacity,
385
- flags: this.cull_enabled ? VGEO_CUT_FLAG_CULL : 0,
386
- });
387
- }
388
482
 
389
483
  /**
390
484
  * Close a frame. The feedback resource stops being valid; reading it is
@@ -395,31 +489,5 @@ export class GPUVirtualGeometryRuntime {
395
489
  end_frame() {
396
490
  this.#feedback = -1;
397
491
  this.#graph = undefined;
398
-
399
- this.#pool.advance_frame();
400
492
  }
401
-
402
- destroy() {
403
- this.#params.destroy();
404
- }
405
- }
406
-
407
- /**
408
- * `write_gpu_typed_buffer` writes into an `ArrayBuffer`; a uniform wants bytes on a device. One
409
- * scratch buffer rather than one per frame, because the params block is forty-odd bytes written
410
- * once a frame and allocating for it would be the expensive half.
411
- *
412
- * @type {ArrayBuffer}
413
- */
414
- const PARAMS_SCRATCH = new ArrayBuffer(VGEO_CUT_PARAMS_STRUCT.aligned_size);
415
-
416
- /**
417
- * @param {GPUDevice} device
418
- * @param {GPUBuffer} buffer
419
- * @param {Object} value
420
- */
421
- function write_gpu_typed_buffer_to_device(device, buffer, value) {
422
- write_gpu_typed_buffer(value, VGEO_CUT_PARAMS_STRUCT, PARAMS_SCRATCH, 0);
423
-
424
- device.queue.writeBuffer(buffer, 0, PARAMS_SCRATCH, 0, VGEO_CUT_PARAMS_STRUCT.aligned_size);
425
493
  }