@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
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Where a row is, in the arena — and nothing else.
3
+ *
4
+ * Split out of {@link chunk_vgeo_cut_access} because three passes want an address and only one of
5
+ * them wants a projection. Before the split, a pass that needed one field of a page header wrote
6
+ * its own accessor rather than take a chunk that also declares the frustum test, the instance eye
7
+ * and the error projection; `shader_vgeo_cut_reseed` said so where its copy was
8
+ * (`vg_reseed_page_field`). The answer to "the chunk declares more than this pass binds" is a
9
+ * smaller chunk, not a second accessor.
10
+ *
11
+ * Requires the importing shader to declare `params` and `vg_arena`.
12
+ *
13
+ * @author Alex Goldring
14
+ * @copyright Company Named Limited (c) 2026
15
+ * @type {CodeChunk}
16
+ */
17
+ export const chunk_vgeo_cut_arena: CodeChunk;
18
+ import { CodeChunk } from "../../../../shader/compiler/CodeChunk.js";
19
+ //# sourceMappingURL=chunk_vgeo_cut_arena.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chunk_vgeo_cut_arena.d.ts","sourceRoot":"","sources":["../../../../../../../../src/shade/renderer/geometry/virtual/runtime/cut/chunk_vgeo_cut_arena.js"],"names":[],"mappings":"AAWA;;;;;;;;;;;;;;;GAeG;AACH,mCAFU,SAAS,CAwEZ;0BAjGmB,0CAA0C"}
@@ -0,0 +1,98 @@
1
+ import { CodeChunk } from "../../../../shader/compiler/CodeChunk.js";
2
+ import { VGEO_CLUSTER_ROW_WORDS } from "../layout/VGEO_CLUSTER_ROW_WORDS.js";
3
+ import { VGEO_GEOMETRY_ROW_WORDS } from "../layout/VGEO_GEOMETRY_ROW_WORDS.js";
4
+ import { VGEO_GROUP_ROW_WORDS } from "../layout/VGEO_GROUP_ROW_WORDS.js";
5
+ import { VGEO_INSTANCE_WORDS } from "../layout/VGEO_INSTANCE_WORDS.js";
6
+ import { VGEO_NODE_ROW_LEAF_BIT } from "../layout/VGEO_NODE_ROW_LEAF_BIT.js";
7
+ import { VGEO_NODE_ROW_WORDS } from "../layout/VGEO_NODE_ROW_WORDS.js";
8
+ import { VGEO_PAGE_ROW_OFFSET } from "../layout/VGEO_PAGE_ROW_OFFSET.js";
9
+ import { VGEO_PAGE_ROW_WORDS } from "../layout/VGEO_PAGE_ROW_WORDS.js";
10
+ import { VGEO_PARENT_ROW_WORDS } from "../layout/VGEO_PARENT_ROW_WORDS.js";
11
+
12
+ /**
13
+ * Where a row is, in the arena — and nothing else.
14
+ *
15
+ * Split out of {@link chunk_vgeo_cut_access} because three passes want an address and only one of
16
+ * them wants a projection. Before the split, a pass that needed one field of a page header wrote
17
+ * its own accessor rather than take a chunk that also declares the frustum test, the instance eye
18
+ * and the error projection; `shader_vgeo_cut_reseed` said so where its copy was
19
+ * (`vg_reseed_page_field`). The answer to "the chunk declares more than this pass binds" is a
20
+ * smaller chunk, not a second accessor.
21
+ *
22
+ * Requires the importing shader to declare `params` and `vg_arena`.
23
+ *
24
+ * @author Alex Goldring
25
+ * @copyright Company Named Limited (c) 2026
26
+ * @type {CodeChunk}
27
+ */
28
+ export const chunk_vgeo_cut_arena = CodeChunk.from(
29
+ //language=WGSL
30
+ `
31
+ const VG_PAGE_ROW_WORDS = ${VGEO_PAGE_ROW_WORDS}u;
32
+ const VG_NODE_ROW_WORDS = ${VGEO_NODE_ROW_WORDS}u;
33
+ const VG_GROUP_ROW_WORDS = ${VGEO_GROUP_ROW_WORDS}u;
34
+ const VG_CLUSTER_ROW_WORDS = ${VGEO_CLUSTER_ROW_WORDS}u;
35
+ const VG_PARENT_ROW_WORDS = ${VGEO_PARENT_ROW_WORDS}u;
36
+ const VG_INSTANCE_WORDS = ${VGEO_INSTANCE_WORDS}u;
37
+ const VG_GEOMETRY_ROW_WORDS = ${VGEO_GEOMETRY_ROW_WORDS}u;
38
+
39
+ const VG_NODE_LEAF_BIT = ${VGEO_NODE_ROW_LEAF_BIT}u;
40
+ const VG_NODE_CHILD_COUNT_MASK = 0xffu;
41
+
42
+ /**
43
+ * A page's slot: its header, then its node, group and cluster rows.
44
+ *
45
+ * The stride is a uniform rather than a constant because the tier derives it from the page size its
46
+ * containers are bounded at, and it is a **multiply** rather than a table read because format
47
+ * §11.14 made that legal — design §6 asked for fixed-size page slots from the start and the bound
48
+ * is what it was waiting for. There is no page table, no allocator, and no second storage binding
49
+ * to keep coherent with this one.
50
+ */
51
+ fn vg_slot_base(page_row: u32) -> u32 {
52
+ return page_row * params.page_slot_words;
53
+ }
54
+
55
+ fn vg_page_field(page_row: u32, field: u32) -> u32 {
56
+ return vg_arena[vg_slot_base(page_row) + field];
57
+ }
58
+
59
+ fn vg_node_base(page_row: u32) -> u32 {
60
+ return vg_slot_base(page_row) + VG_PAGE_ROW_WORDS;
61
+ }
62
+
63
+ fn vg_group_base(page_row: u32) -> u32 {
64
+ return vg_node_base(page_row)
65
+ + vg_page_field(page_row, ${VGEO_PAGE_ROW_OFFSET.NODE_COUNT}u) * VG_NODE_ROW_WORDS;
66
+ }
67
+
68
+ fn vg_cluster_base(page_row: u32) -> u32 {
69
+ return vg_group_base(page_row)
70
+ + vg_page_field(page_row, ${VGEO_PAGE_ROW_OFFSET.GROUP_COUNT}u) * VG_GROUP_ROW_WORDS;
71
+ }
72
+
73
+ /**
74
+ * The fourth section: this page's parent rows, which is where a walk *up* reads.
75
+ *
76
+ * It may be empty, and a reader has to check rather than assume: the page row's parent
77
+ * entry count is zero for
78
+ * every page of a container written before format 4, which has no upward edge at all. Zero is not a
79
+ * malformed page; it is an asset that can only be re-descended.
80
+ */
81
+ fn vg_parent_base(page_row: u32) -> u32 {
82
+ return vg_cluster_base(page_row)
83
+ + vg_page_field(page_row, ${VGEO_PAGE_ROW_OFFSET.CLUSTER_COUNT}u) * VG_CLUSTER_ROW_WORDS;
84
+ }
85
+
86
+ fn vg_arena_f32(word: u32) -> f32 {
87
+ return bitcast<f32>(vg_arena[word]);
88
+ }
89
+
90
+ fn vg_sphere_at(word: u32) -> vec4<f32> {
91
+ return vec4<f32>(
92
+ bitcast<f32>(vg_arena[word]),
93
+ bitcast<f32>(vg_arena[word + 1u]),
94
+ bitcast<f32>(vg_arena[word + 2u]),
95
+ bitcast<f32>(vg_arena[word + 3u])
96
+ );
97
+ }
98
+ `, []);
@@ -0,0 +1,31 @@
1
+ /**
2
+ * One page, claimed once per instance, and touched when the claim is won.
3
+ *
4
+ * This is the invariant the whole cut rests on — "at most one draw record per (instance, cluster)" —
5
+ * and it was written out three times: here's-the-original in `shader_vgeo_cut_traverse`, a
6
+ * line-for-line copy in `shader_vgeo_cut_reseed`, and inline in `shader_vgeo_cut_seed`. The
7
+ * copies had already begun to differ: the seed pass omitted the `claim_word_count` bound the other
8
+ * two take. It was correct — the seed pass establishes that bound a few lines earlier — but a
9
+ * correctness invariant whose three spellings disagree about which checks it needs is one nobody
10
+ * can read off the source any more.
11
+ *
12
+ * The touch is the other half and travels with it, because a claim that does not stamp the page is
13
+ * a page that ages out of the LRU while it is on screen. LRU on last-**touched**, never on
14
+ * last-wanted: stamping at fetch time freezes the stamp of exactly the pages that are being drawn
15
+ * and evicts them, which is the fallback-chain bug the virtual texture cache already keys on touch
16
+ * to avoid.
17
+ *
18
+ * One bit per page row, because the feedback buffer is per frame rather than per invocation: the
19
+ * bit dedups across every view and bucket of the frame and is the record the host reads, so there
20
+ * is no list to fill and no touch a full list could lose.
21
+ *
22
+ * Requires the importing shader to declare `params`, `vg_arena`, `instances`, `claim` and
23
+ * `feedback`.
24
+ *
25
+ * @author Alex Goldring
26
+ * @copyright Company Named Limited (c) 2026
27
+ * @type {CodeChunk}
28
+ */
29
+ export const chunk_vgeo_cut_claim: CodeChunk;
30
+ import { CodeChunk } from "../../../../shader/compiler/CodeChunk.js";
31
+ //# sourceMappingURL=chunk_vgeo_cut_claim.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chunk_vgeo_cut_claim.d.ts","sourceRoot":"","sources":["../../../../../../../../src/shade/renderer/geometry/virtual/runtime/cut/chunk_vgeo_cut_claim.js"],"names":[],"mappings":"AAOA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,mCAFU,SAAS,CAiEQ;0BAlGD,0CAA0C"}
@@ -0,0 +1,99 @@
1
+ import { CodeChunk } from "../../../../shader/compiler/CodeChunk.js";
2
+ import { VGEO_CUT_STAT } from "../layout/VGEO_CUT_STAT.js";
3
+ import { VGEO_FEEDBACK_OFFSET } from "../layout/VGEO_FEEDBACK_OFFSET.js";
4
+ import { VGEO_INSTANCE_OFFSET } from "../layout/VGEO_INSTANCE_OFFSET.js";
5
+ import { VGEO_PAGE_ROW_OFFSET } from "../layout/VGEO_PAGE_ROW_OFFSET.js";
6
+ import { chunk_vgeo_cut_arena } from "./chunk_vgeo_cut_arena.js";
7
+
8
+ /**
9
+ * One page, claimed once per instance, and touched when the claim is won.
10
+ *
11
+ * This is the invariant the whole cut rests on — "at most one draw record per (instance, cluster)" —
12
+ * and it was written out three times: here's-the-original in `shader_vgeo_cut_traverse`, a
13
+ * line-for-line copy in `shader_vgeo_cut_reseed`, and inline in `shader_vgeo_cut_seed`. The
14
+ * copies had already begun to differ: the seed pass omitted the `claim_word_count` bound the other
15
+ * two take. It was correct — the seed pass establishes that bound a few lines earlier — but a
16
+ * correctness invariant whose three spellings disagree about which checks it needs is one nobody
17
+ * can read off the source any more.
18
+ *
19
+ * The touch is the other half and travels with it, because a claim that does not stamp the page is
20
+ * a page that ages out of the LRU while it is on screen. LRU on last-**touched**, never on
21
+ * last-wanted: stamping at fetch time freezes the stamp of exactly the pages that are being drawn
22
+ * and evicts them, which is the fallback-chain bug the virtual texture cache already keys on touch
23
+ * to avoid.
24
+ *
25
+ * One bit per page row, because the feedback buffer is per frame rather than per invocation: the
26
+ * bit dedups across every view and bucket of the frame and is the record the host reads, so there
27
+ * is no list to fill and no touch a full list could lose.
28
+ *
29
+ * Requires the importing shader to declare `params`, `vg_arena`, `instances`, `claim` and
30
+ * `feedback`.
31
+ *
32
+ * @author Alex Goldring
33
+ * @copyright Company Named Limited (c) 2026
34
+ * @type {CodeChunk}
35
+ */
36
+ export const chunk_vgeo_cut_claim = CodeChunk.from(
37
+ //language=WGSL
38
+ `
39
+ fn vg_stat(slot: u32, amount: u32) {
40
+ atomicAdd(&feedback[${VGEO_FEEDBACK_OFFSET.STATS}u + slot], amount);
41
+ }
42
+
43
+ /**
44
+ * Record that this page was selected from this frame — design §6's eviction key.
45
+ */
46
+ fn vg_touch_page(page_row: u32) {
47
+ atomicOr(&feedback[params.touch_bits_base + (page_row >> 5u)], 1u << (page_row & 31u));
48
+ }
49
+
50
+ /**
51
+ * The claim itself, against a slice of the bitmask the caller already has in hand.
52
+ *
53
+ * Taken this way rather than always through the instance record because the seed pass computes the
54
+ * slice base in the same invocation that claims with it — it has just written it to the instance
55
+ * record, and reading it straight back would be a storage round trip for a value already in a
56
+ * register.
57
+ *
58
+ * @returns whether this invocation is the one that claimed the page
59
+ */
60
+ fn vg_claim_page_at(claim_base: u32, ordinal_capacity: u32, page_row: u32) -> bool {
61
+ let ordinal = vg_page_field(page_row, ${VGEO_PAGE_ROW_OFFSET.ORDINAL}u);
62
+
63
+ if (ordinal >= ordinal_capacity) {
64
+ return false;
65
+ }
66
+
67
+ let bit = claim_base + ordinal;
68
+
69
+ let word = bit >> 5u;
70
+
71
+ if (word >= params.claim_word_count) {
72
+ return false;
73
+ }
74
+
75
+ let mask = 1u << (bit & 31u);
76
+
77
+ if ((atomicOr(&claim[word], mask) & mask) != 0u) {
78
+ return false;
79
+ }
80
+
81
+ vg_stat(${VGEO_CUT_STAT.PAGES}u, 1u);
82
+
83
+ vg_touch_page(page_row);
84
+
85
+ return true;
86
+ }
87
+
88
+ /**
89
+ * The same claim, for a caller holding an instance rather than its slice. An instance whose slice
90
+ * of the bitmask does not fit is refused upstream, in the seed pass, rather than run unclaimed.
91
+ */
92
+ fn vg_claim_page(instance_base: u32, page_row: u32) -> bool {
93
+ return vg_claim_page_at(
94
+ instances[instance_base + ${VGEO_INSTANCE_OFFSET.CLAIM_BASE}u],
95
+ instances[instance_base + ${VGEO_INSTANCE_OFFSET.ORDINAL_CAPACITY}u],
96
+ page_row
97
+ );
98
+ }
99
+ `, [chunk_vgeo_cut_arena]);
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Put one page on the wavefront queue at its root node.
3
+ *
4
+ * Both passes that start a descent — the seed, from an instance's root page, and the reseed, from
5
+ * last frame's frontier — push the same four words and drop on the same bound, and both wrote it
6
+ * out. `shader_vgeo_cut_traverse` does not use this: it reserves a run for a whole workgroup's
7
+ * spill in one `atomicAdd` and writes into it, which is a different thing wearing the same words.
8
+ *
9
+ * Requires the importing shader to declare `params`, `queue_out` and `feedback`.
10
+ *
11
+ * @author Alex Goldring
12
+ * @copyright Company Named Limited (c) 2026
13
+ * @type {CodeChunk}
14
+ */
15
+ export const chunk_vgeo_cut_queue: CodeChunk;
16
+ import { CodeChunk } from "../../../../shader/compiler/CodeChunk.js";
17
+ //# sourceMappingURL=chunk_vgeo_cut_queue.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chunk_vgeo_cut_queue.d.ts","sourceRoot":"","sources":["../../../../../../../../src/shade/renderer/geometry/virtual/runtime/cut/chunk_vgeo_cut_queue.js"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;GAaG;AACH,mCAFU,SAAS,CAsBQ;0BAtCD,0CAA0C"}
@@ -0,0 +1,39 @@
1
+ import { CodeChunk } from "../../../../shader/compiler/CodeChunk.js";
2
+ import { VGEO_CUT_STAT } from "../layout/VGEO_CUT_STAT.js";
3
+ import { chunk_vgeo_cut_claim } from "./chunk_vgeo_cut_claim.js";
4
+
5
+ /**
6
+ * Put one page on the wavefront queue at its root node.
7
+ *
8
+ * Both passes that start a descent — the seed, from an instance's root page, and the reseed, from
9
+ * last frame's frontier — push the same four words and drop on the same bound, and both wrote it
10
+ * out. `shader_vgeo_cut_traverse` does not use this: it reserves a run for a whole workgroup's
11
+ * spill in one `atomicAdd` and writes into it, which is a different thing wearing the same words.
12
+ *
13
+ * Requires the importing shader to declare `params`, `queue_out` and `feedback`.
14
+ *
15
+ * @author Alex Goldring
16
+ * @copyright Company Named Limited (c) 2026
17
+ * @type {CodeChunk}
18
+ */
19
+ export const chunk_vgeo_cut_queue = CodeChunk.from(
20
+ //language=WGSL
21
+ `
22
+ fn vg_queue_push_root(instance_slot: u32, page_row: u32) {
23
+ let slot = atomicAdd(&queue_out.count, 1u);
24
+
25
+ if (slot >= params.queue_capacity) {
26
+ vg_stat(${VGEO_CUT_STAT.QUEUE_DROPPED}u, 1u);
27
+
28
+ return;
29
+ }
30
+
31
+ let base = slot * 4u;
32
+
33
+ queue_out.elements[base] = instance_slot;
34
+ queue_out.elements[base + 1u] = page_row;
35
+ // node 0, which is how every page visit in this runtime begins
36
+ queue_out.elements[base + 2u] = 0u;
37
+ queue_out.elements[base + 3u] = 0u;
38
+ }
39
+ `, [chunk_vgeo_cut_claim]);
@@ -1 +1 @@
1
- {"version":3,"file":"shader_vgeo_cut_collect.d.ts","sourceRoot":"","sources":["../../../../../../../../src/shade/renderer/geometry/virtual/runtime/cut/shader_vgeo_cut_collect.js"],"names":[],"mappings":"AA0PA,oDAIG;8BAxP2B,qCAAqC"}
1
+ {"version":3,"file":"shader_vgeo_cut_collect.d.ts","sourceRoot":"","sources":["../../../../../../../../src/shade/renderer/geometry/virtual/runtime/cut/shader_vgeo_cut_collect.js"],"names":[],"mappings":"AA2QA,oDAIG;8BAzQ2B,qCAAqC"}
@@ -102,7 +102,24 @@ fn vg_store_plane(base: u32, plane: u32, row_w: vec4<f32>, row: vec4<f32>, sign:
102
102
  fn main(@builtin(global_invocation_id) global_id: vec3<u32>) {
103
103
  let input_index = global_id.x;
104
104
 
105
- if (input_index >= input_meshes.count) {
105
+ /*
106
+ The count, against what the collection can actually hold, the way every sibling filter over
107
+ this shape reads it. The producer feeding this seam — \`shader_hzb_mesh_filter_2way\` — reserves
108
+ a slot with an unconditional \`atomicAdd\` and bounds-checks only the element *write*, so a
109
+ bucket whose positive set overflows hands over a count past the end of its own elements. The
110
+ indirect dispatch is built from that same count, so the overshoot arrives here as extra lanes
111
+ rather than as a loop bound this pass could have ignored.
112
+
113
+ Reading past the end is not the failure — robustness bounds that. The failure is what the
114
+ bounded read comes back with: a mesh row this bucket never selected, which the lines below
115
+ treat as a real instance, and if that row's geometry happens to be virtual it is collected and
116
+ cut. Every other bound in this pass degrades toward *fewer* instances; this one degraded into a
117
+ cut of geometry nobody asked for, which is the one direction a silently-wrong picture comes
118
+ from.
119
+ */
120
+ let input_size = min(input_meshes.count, arrayLength(&input_meshes.elements));
121
+
122
+ if (input_index >= input_size) {
106
123
  return;
107
124
  }
108
125
 
@@ -1 +1 @@
1
- {"version":3,"file":"shader_vgeo_cut_queue_prepare.d.ts","sourceRoot":"","sources":["../../../../../../../../src/shade/renderer/geometry/virtual/runtime/cut/shader_vgeo_cut_queue_prepare.js"],"names":[],"mappings":"AA2EA,0DAIG;8BA3E2B,qCAAqC"}
1
+ {"version":3,"file":"shader_vgeo_cut_queue_prepare.d.ts","sourceRoot":"","sources":["../../../../../../../../src/shade/renderer/geometry/virtual/runtime/cut/shader_vgeo_cut_queue_prepare.js"],"names":[],"mappings":"AAiEA,0DAIG;8BAnE2B,qCAAqC"}
@@ -1,5 +1,3 @@
1
- import { atomic_u32 } from "../../../../shader/type/WEBGPU_WGSL_PRIMITIVE_TYPES.js";
2
- import { WebGPUArray } from "../../../../shader/type/WebGPUArray.js";
3
1
  import { CodeChunk } from "../../../../shader/compiler/CodeChunk.js";
4
2
  import { COLLECTION_U32_STRUCT_WRITE } from "../../../../gpu_primitive/COLLECTION_U32_STRUCT_WRITE.js";
5
3
  import { ComputeShader } from "../../../../shader/ComputeShader.js";
@@ -8,8 +6,6 @@ import {
8
6
  } from "../../../../gpu_primitive/indirect/STRUCT_DISPATCH_COMPUTE_COMMAND.js";
9
7
  import { ShaderResourceSetDescriptor } from "../../../../shader/resource/ShaderResourceSetDescriptor.js";
10
8
  import { chunk_divide_round_up_u32 } from "../../../../shader/chunk/math/chunk_divide_round_up_u32.js";
11
- import { VGEO_CUT_STAT } from "../layout/VGEO_CUT_STAT.js";
12
- import { VGEO_FEEDBACK_OFFSET } from "../layout/VGEO_FEEDBACK_OFFSET.js";
13
9
  import { VGEO_CUT_PARAMS_STRUCT } from "./VGEO_CUT_PARAMS_STRUCT.js";
14
10
  import { VGEO_CUT_WORKGROUP_SIZE } from "./VGEO_CUT_WORKGROUP_SIZE.js";
15
11
 
@@ -27,6 +23,11 @@ import { VGEO_CUT_WORKGROUP_SIZE } from "./VGEO_CUT_WORKGROUP_SIZE.js";
27
23
  * the buffer this iteration reads is the one the next iteration writes, and there is exactly one
28
24
  * moment when neither pass is touching it.
29
25
  *
26
+ * **It records no statistic.** There is another wavefront after it, so the count it sees is a
27
+ * frontier rather than a remainder, and it runs once per iteration per expansion site, so anything
28
+ * it stored would be overwritten by the next iteration and then by the next site. What the descent
29
+ * was left holding is {@link shader_vgeo_cut_queue_remainder}, recorded once, after the loop.
30
+ *
30
31
  * @author Alex Goldring
31
32
  * @copyright Company Named Limited (c) 2026
32
33
  */
@@ -40,8 +41,6 @@ resources.createGroup()
40
41
  // what the next wavefront will produce into
41
42
  .addStorageBuffer("queue_spare", COLLECTION_U32_STRUCT_WRITE, true)
42
43
  .addStorageBuffer("command", STRUCT_DISPATCH_COMPUTE_COMMAND, true)
43
- // the frame's counters: this is the only pass that can see how deep the descent went
44
- .addStorageBuffer("feedback", WebGPUArray.from(atomic_u32), true)
45
44
  ;
46
45
 
47
46
  const body = CodeChunk.from(
@@ -56,15 +55,6 @@ fn main() {
56
55
  atomicStore(&queue_ready.count, count);
57
56
  atomicStore(&queue_spare.count, 0u);
58
57
 
59
- /*
60
- What was outstanding when this pass ran. A plain store rather than an add, so the last prepare
61
- of the frame is the one that is read — and the seam records one extra prepare after the
62
- wavefront loop, whose whole purpose is to leave this number behind. A descent that stops with
63
- work still queued is the one degradation that costs a hole rather than coarseness, and until
64
- now nothing anywhere counted it (REVIEW_LEDGER M8).
65
- */
66
- atomicStore(&feedback[${VGEO_FEEDBACK_OFFSET.STATS}u + ${VGEO_CUT_STAT.QUEUE_REMAINING}u], count);
67
-
68
58
  command.workgroupCountX = divide_round_up_u32(count, ${VGEO_CUT_WORKGROUP_SIZE}u);
69
59
  command.workgroupCountY = 1u;
70
60
  command.workgroupCountZ = 1u;
@@ -0,0 +1,3 @@
1
+ export const shader_vgeo_cut_queue_remainder: ComputeShader;
2
+ import { ComputeShader } from "../../../../shader/ComputeShader.js";
3
+ //# sourceMappingURL=shader_vgeo_cut_queue_remainder.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"shader_vgeo_cut_queue_remainder.d.ts","sourceRoot":"","sources":["../../../../../../../../src/shade/renderer/geometry/virtual/runtime/cut/shader_vgeo_cut_queue_remainder.js"],"names":[],"mappings":"AAwEA,4DAIG;8BAxE2B,qCAAqC"}
@@ -0,0 +1,77 @@
1
+ import { atomic_u32 } from "../../../../shader/type/WEBGPU_WGSL_PRIMITIVE_TYPES.js";
2
+ import { WebGPUArray } from "../../../../shader/type/WebGPUArray.js";
3
+ import { CodeChunk } from "../../../../shader/compiler/CodeChunk.js";
4
+ import { COLLECTION_U32_STRUCT_READ } from "../../../../gpu_primitive/COLLECTION_U32_STRUCT_READ.js";
5
+ import { ComputeShader } from "../../../../shader/ComputeShader.js";
6
+ import { ShaderResourceSetDescriptor } from "../../../../shader/resource/ShaderResourceSetDescriptor.js";
7
+ import { VGEO_CUT_STAT } from "../layout/VGEO_CUT_STAT.js";
8
+ import { VGEO_FEEDBACK_OFFSET } from "../layout/VGEO_FEEDBACK_OFFSET.js";
9
+ import { VGEO_CUT_PARAMS_STRUCT } from "./VGEO_CUT_PARAMS_STRUCT.js";
10
+
11
+ /**
12
+ * After the wavefront loop: what the descent stopped with still queued.
13
+ *
14
+ * A queue item never popped is a subtree never descended, and the parent that would have stood in
15
+ * over it was not drawn either — it failed `project(self) <= tau`, which is what sent the descent
16
+ * down there. So this is the one bound of the cut that costs a **hole** rather than coarseness
17
+ * (RUNTIME_PLAN §4.5), and the only one whose reading cannot be inferred from the others.
18
+ *
19
+ * ## Why it is its own pass
20
+ *
21
+ * Only the pass *after the last wavefront* is looking at a remainder. The prepare pass runs
22
+ * between wavefronts, so its count is a frontier, and it runs once per iteration per expansion
23
+ * site, so whatever it stored the next iteration and then the next site would overwrite.
24
+ *
25
+ * An **add** rather than a store, because a frame holds more than one cut — two per view, since the
26
+ * two-way HZB filter splits positive from maybe — and they all record into the frame's one feedback
27
+ * buffer. A store would let the last site to run set the number for the whole frame, an empty cut
28
+ * zeroing a truncation another had just reported. Summing is the same combiner as every other stat
29
+ * in `VGEO_CUT_STAT` and is zero exactly when nothing was left behind, which is the property
30
+ * `VGeoResidencyManager` and anyone lowering `max_iterations` needs of it.
31
+ *
32
+ * The count lives in a transient the graph is about to recycle, so reading it on the CPU would be a
33
+ * readback of a buffer the frame is still writing. Two storage buffers, one uniform and one
34
+ * workgroup is cheaper than the alternative of not knowing.
35
+ *
36
+ * @author Alex Goldring
37
+ * @copyright Company Named Limited (c) 2026
38
+ */
39
+
40
+ const resources = new ShaderResourceSetDescriptor();
41
+
42
+ resources.createGroup()
43
+ .addUniform("params", VGEO_CUT_PARAMS_STRUCT)
44
+ // the queue the last wavefront produced into and nothing consumed
45
+ .addStorageBuffer("queue_ready", COLLECTION_U32_STRUCT_READ, false)
46
+ .addStorageBuffer("feedback", WebGPUArray.from(atomic_u32), true)
47
+ ;
48
+
49
+ const body = CodeChunk.from(
50
+ //language=WGSL
51
+ `
52
+ @compute @workgroup_size(1)
53
+ fn main() {
54
+ /*
55
+ Clamped the way the prepare pass clamps it, and for the same reason: a wavefront reserves its
56
+ output with atomicAdd and lets the count run past capacity, so the raw number counts items that
57
+ were never written. What was dropped at the append is QUEUE_DROPPED and is already counted
58
+ there; counting it here as well would report one lost subtree twice.
59
+ */
60
+ let outstanding = min(queue_ready.count, params.queue_capacity);
61
+
62
+ if (outstanding == 0u) {
63
+ return;
64
+ }
65
+
66
+ atomicAdd(
67
+ &feedback[${VGEO_FEEDBACK_OFFSET.STATS}u + ${VGEO_CUT_STAT.QUEUE_REMAINING}u],
68
+ outstanding
69
+ );
70
+ }
71
+ `);
72
+
73
+ export const shader_vgeo_cut_queue_remainder = ComputeShader.from({
74
+ label: "VGeo cut queue remainder",
75
+ body,
76
+ resources,
77
+ });
@@ -0,0 +1,3 @@
1
+ export const shader_vgeo_cut_reseed: ComputeShader;
2
+ import { ComputeShader } from "../../../../shader/ComputeShader.js";
3
+ //# sourceMappingURL=shader_vgeo_cut_reseed.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"shader_vgeo_cut_reseed.d.ts","sourceRoot":"","sources":["../../../../../../../../src/shade/renderer/geometry/virtual/runtime/cut/shader_vgeo_cut_reseed.js"],"names":[],"mappings":"AA6HA,mDAIG;8BA9H2B,qCAAqC"}
@@ -0,0 +1,130 @@
1
+ import { atomic_u32, u32 } from "../../../../shader/type/WEBGPU_WGSL_PRIMITIVE_TYPES.js";
2
+ import { WebGPUArray } from "../../../../shader/type/WebGPUArray.js";
3
+ import { CodeChunk } from "../../../../shader/compiler/CodeChunk.js";
4
+ import { ComputeShader } from "../../../../shader/ComputeShader.js";
5
+ import { ShaderResourceSetDescriptor } from "../../../../shader/resource/ShaderResourceSetDescriptor.js";
6
+ import { chunk_vgeo_cut_claim } from "./chunk_vgeo_cut_claim.js";
7
+ import { chunk_vgeo_cut_queue } from "./chunk_vgeo_cut_queue.js";
8
+ import { COLLECTION_U32_STRUCT_WRITE } from "../../../../gpu_primitive/COLLECTION_U32_STRUCT_WRITE.js";
9
+ import { VGEO_INSTANCE_OFFSET } from "../layout/VGEO_INSTANCE_OFFSET.js";
10
+ import { VGEO_INSTANCE_WORDS } from "../layout/VGEO_INSTANCE_WORDS.js";
11
+ import { VGEO_PAGE_ROW_NONE } from "../layout/VGEO_PAGE_ROW_NONE.js";
12
+ import { VGEO_PAGE_ROW_OFFSET } from "../layout/VGEO_PAGE_ROW_OFFSET.js";
13
+ import { VGEO_CUT_PARAMS_STRUCT } from "./VGEO_CUT_PARAMS_STRUCT.js";
14
+ import { VGEO_CUT_WORKGROUP_SIZE } from "./VGEO_CUT_WORKGROUP_SIZE.js";
15
+
16
+ /**
17
+ * Seed a cut from where the last one stood, instead of from the root.
18
+ *
19
+ * `shader_vgeo_cut_seed` puts one item per instance on the queue naming node 0 of that instance's
20
+ * root page, and the descent re-derives the whole cut — 39 levels on a converted container, at
21
+ * about half a microsecond a level a dispatch, every frame, for a camera that may not have moved.
22
+ * This pass puts the pages that cut *ended* on back on the queue instead, and the descent starts
23
+ * there: what has to change between two frames is a level or two in either direction, which the
24
+ * existing refinement and `VGEO_CUT_FLAG_COARSEN`'s walk up both reach.
25
+ *
26
+ * ## Pages, not groups
27
+ *
28
+ * `CUT_PLAN_2026_09_14` §1 describes the frontier as a set of groups. This one is a set of **page
29
+ * rows**, which is coarser and very much simpler: a page is the unit the claim is built on and the
30
+ * unit a visit evaluates whole, so a reseeded page needs no new item kind, no entry format and no
31
+ * dedup beyond the claim the descent already takes. Every group of the page is re-tested by the
32
+ * pure rule, and testing a group the cut did not need costs the test and nothing else.
33
+ *
34
+ * ## What makes a stale frontier safe
35
+ *
36
+ * Two things, and neither is a repair. A page row is reused, so a frontier written against one
37
+ * occupant could name another after an eviction — the host compares the pool's eviction count
38
+ * against the one the frontier was captured at and drops the whole view's frontier when they
39
+ * differ, rather than mending it. And a frontier that is merely *old* is not wrong at all: it names
40
+ * pages that are still a consistent place to stand, and the descent leaves them for finer ones
41
+ * while the coarsen path walks up from them.
42
+ *
43
+ * So the failure mode is a cut that costs what today's costs, which is the fallback the seam
44
+ * already has.
45
+ *
46
+ * ## One lane per (instance, page row)
47
+ *
48
+ * The frontier is per view rather than per (view, instance), so every instance is offered every
49
+ * page in it and the claim decides. That is a superset of what each instance needs — correct, and
50
+ * cheap while a view holds a handful of virtual-geometry instances. It is why this is a first form
51
+ * rather than the last one: §1.1 keys a frontier by mesh row precisely so a thousand instances do
52
+ * not each pay for the union, and that is the change this shape is waiting for.
53
+ *
54
+ * @author Alex Goldring
55
+ * @copyright Company Named Limited (c) 2026
56
+ */
57
+
58
+ const resources = new ShaderResourceSetDescriptor();
59
+
60
+ resources.createGroup()
61
+ .addUniform("params", VGEO_CUT_PARAMS_STRUCT)
62
+ .addStorageBuffer("vg_arena", WebGPUArray.from(u32), false)
63
+ .addStorageBuffer("instances", WebGPUArray.from(u32), false)
64
+ .addStorageBuffer("frontier", WebGPUArray.from(u32), false)
65
+ .addStorageBuffer("queue_out", COLLECTION_U32_STRUCT_WRITE, true)
66
+ .addStorageBuffer("claim", WebGPUArray.from(atomic_u32), true)
67
+ .addStorageBuffer("feedback", WebGPUArray.from(atomic_u32), true)
68
+ ;
69
+
70
+ const body = CodeChunk.from(
71
+ //language=WGSL
72
+ `
73
+ @compute @workgroup_size(${VGEO_CUT_WORKGROUP_SIZE})
74
+ fn main(@builtin(global_invocation_id) global_id: vec3<u32>) {
75
+ let rows = params.frontier_word_count * 32u;
76
+
77
+ if (rows == 0u) {
78
+ return;
79
+ }
80
+
81
+ let lane = global_id.x;
82
+
83
+ let instance_slot = lane / rows;
84
+ let page_row = lane - instance_slot * rows;
85
+
86
+ if (instance_slot >= params.instance_capacity) {
87
+ return;
88
+ }
89
+
90
+ if ((frontier[page_row >> 5u] & (1u << (page_row & 31u))) == 0u) {
91
+ return;
92
+ }
93
+
94
+ let instance_base = instance_slot * ${VGEO_INSTANCE_WORDS}u;
95
+
96
+ let root_row = instances[instance_base + ${VGEO_INSTANCE_OFFSET.ROOT_PAGE_ROW}u];
97
+
98
+ if (root_row == ${VGEO_PAGE_ROW_NONE}u) {
99
+ return;
100
+ }
101
+
102
+ /*
103
+ The page must belong to the geometry this instance draws. A frontier is a set of rows of a
104
+ shared tier and an instance of another geometry has no business standing on them — its claim
105
+ would reject the ordinal eventually, but the geometry row is the honest test and it is two
106
+ reads of a header that is already in cache.
107
+ */
108
+ if (vg_page_field(page_row, ${VGEO_PAGE_ROW_OFFSET.GEOMETRY_ROW}u)
109
+ != vg_page_field(root_row, ${VGEO_PAGE_ROW_OFFSET.GEOMETRY_ROW}u)) {
110
+ return;
111
+ }
112
+
113
+ /*
114
+ The claim, for the two reasons the seed takes one on the root: it stamps the page as touched,
115
+ which is the LRU's whole input, and it is what stops a page reached both from the frontier and
116
+ from a descent later in this same cut from being drawn twice.
117
+ */
118
+ if (!vg_claim_page(instance_base, page_row)) {
119
+ return;
120
+ }
121
+
122
+ vg_queue_push_root(instance_slot, page_row);
123
+ }
124
+ `, [chunk_vgeo_cut_claim, chunk_vgeo_cut_queue]);
125
+
126
+ export const shader_vgeo_cut_reseed = ComputeShader.from({
127
+ label: "VGeo cut reseed",
128
+ body,
129
+ resources,
130
+ });
@@ -1 +1 @@
1
- {"version":3,"file":"shader_vgeo_cut_seed.d.ts","sourceRoot":"","sources":["../../../../../../../../src/shade/renderer/geometry/virtual/runtime/cut/shader_vgeo_cut_seed.js"],"names":[],"mappings":"AA2IA,iDAIG;8BA1I2B,qCAAqC"}
1
+ {"version":3,"file":"shader_vgeo_cut_seed.d.ts","sourceRoot":"","sources":["../../../../../../../../src/shade/renderer/geometry/virtual/runtime/cut/shader_vgeo_cut_seed.js"],"names":[],"mappings":"AAsIA,iDAIG;8BArI2B,qCAAqC"}