@woosh/meep-engine 3.27.0 → 3.29.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 (648) hide show
  1. package/build/bundle-worker-terrain.js +1 -1
  2. package/package.json +1 -1
  3. package/src/core/binary/BitSet.d.ts +16 -0
  4. package/src/core/binary/BitSet.d.ts.map +1 -1
  5. package/src/core/binary/BitSet.js +159 -49
  6. package/src/core/binary/allocator/OffsetAllocator.d.ts +48 -0
  7. package/src/core/binary/allocator/OffsetAllocator.d.ts.map +1 -1
  8. package/src/core/binary/allocator/OffsetAllocator.js +208 -9
  9. package/src/core/binary/compression/compress_bytes.d.ts +20 -0
  10. package/src/core/binary/compression/compress_bytes.d.ts.map +1 -0
  11. package/src/core/binary/compression/compress_bytes.js +35 -0
  12. package/src/core/binary/compression/decompress_bytes_into.d.ts +30 -0
  13. package/src/core/binary/compression/decompress_bytes_into.d.ts.map +1 -0
  14. package/src/core/binary/compression/decompress_bytes_into.js +87 -0
  15. package/src/core/binary/compression/deflate_decompress_bound.d.ts +27 -0
  16. package/src/core/binary/compression/deflate_decompress_bound.d.ts.map +1 -0
  17. package/src/core/binary/compression/deflate_decompress_bound.js +32 -0
  18. package/src/core/geom/3d/mat4/m4_linear_determinant.d.ts +15 -0
  19. package/src/core/geom/3d/mat4/m4_linear_determinant.d.ts.map +1 -0
  20. package/src/core/geom/3d/mat4/m4_linear_determinant.js +24 -0
  21. package/src/core/geom/3d/mat4/m4_normal_matrix3.d.ts +4 -2
  22. package/src/core/geom/3d/mat4/m4_normal_matrix3.d.ts.map +1 -1
  23. package/src/core/geom/3d/mat4/m4_normal_matrix3.js +21 -11
  24. package/src/core/geom/3d/quadric/quadric_attribute_add.d.ts +24 -0
  25. package/src/core/geom/3d/quadric/quadric_attribute_add.d.ts.map +1 -0
  26. package/src/core/geom/3d/quadric/quadric_attribute_add.js +31 -0
  27. package/src/core/geom/3d/quadric/quadric_attribute_reduce.d.ts +46 -0
  28. package/src/core/geom/3d/quadric/quadric_attribute_reduce.d.ts.map +1 -0
  29. package/src/core/geom/3d/quadric/quadric_attribute_reduce.js +104 -0
  30. package/src/core/geom/3d/quadric/quadric_attribute_set_from_triangle.d.ts +62 -0
  31. package/src/core/geom/3d/quadric/quadric_attribute_set_from_triangle.d.ts.map +1 -0
  32. package/src/core/geom/3d/quadric/quadric_attribute_set_from_triangle.js +158 -0
  33. package/src/core/geom/3d/quadric/quadric_attribute_size.d.ts +21 -0
  34. package/src/core/geom/3d/quadric/quadric_attribute_size.d.ts.map +1 -0
  35. package/src/core/geom/3d/quadric/quadric_attribute_size.js +24 -0
  36. package/src/core/geom/3d/quadric/quadric_attribute_solve.d.ts +34 -0
  37. package/src/core/geom/3d/quadric/quadric_attribute_solve.d.ts.map +1 -0
  38. package/src/core/geom/3d/quadric/quadric_attribute_solve.js +55 -0
  39. package/src/core/geom/3d/quadric/quadric_attribute_sub.d.ts +28 -0
  40. package/src/core/geom/3d/quadric/quadric_attribute_sub.d.ts.map +1 -0
  41. package/src/core/geom/3d/quadric/quadric_attribute_sub.js +35 -0
  42. package/src/core/geom/3d/topology/struct/binary/BinaryDataBlock.d.ts +15 -0
  43. package/src/core/geom/3d/topology/struct/binary/BinaryDataBlock.d.ts.map +1 -1
  44. package/src/core/geom/3d/topology/struct/binary/BinaryDataBlock.js +35 -0
  45. package/src/core/geom/3d/topology/struct/binary/BtWedgeSet.d.ts +93 -0
  46. package/src/core/geom/3d/topology/struct/binary/BtWedgeSet.d.ts.map +1 -0
  47. package/src/core/geom/3d/topology/struct/binary/BtWedgeSet.js +128 -0
  48. package/src/core/geom/3d/topology/struct/binary/io/bt_mesh_compute_wedge_attribute_quadrics.d.ts +38 -0
  49. package/src/core/geom/3d/topology/struct/binary/io/bt_mesh_compute_wedge_attribute_quadrics.d.ts.map +1 -0
  50. package/src/core/geom/3d/topology/struct/binary/io/bt_mesh_compute_wedge_attribute_quadrics.js +113 -0
  51. package/src/core/geom/3d/topology/struct/binary/io/bt_mesh_simplify.d.ts +47 -1
  52. package/src/core/geom/3d/topology/struct/binary/io/bt_mesh_simplify.d.ts.map +1 -1
  53. package/src/core/geom/3d/topology/struct/binary/io/bt_mesh_simplify.js +677 -8
  54. package/src/core/geom/3d/topology/struct/binary/io/bt_wedges_live_count.d.ts +22 -0
  55. package/src/core/geom/3d/topology/struct/binary/io/bt_wedges_live_count.d.ts.map +1 -0
  56. package/src/core/geom/3d/topology/struct/binary/io/bt_wedges_live_count.js +46 -0
  57. package/src/core/geom/3d/topology/struct/binary/io/bt_wedges_per_vertex.d.ts +19 -0
  58. package/src/core/geom/3d/topology/struct/binary/io/bt_wedges_per_vertex.d.ts.map +1 -0
  59. package/src/core/geom/3d/topology/struct/binary/io/bt_wedges_per_vertex.js +49 -0
  60. package/src/core/graph/layout/layered/BoxLayoutOptions.d.ts +63 -0
  61. package/src/core/graph/layout/layered/BoxLayoutOptions.d.ts.map +1 -0
  62. package/src/core/graph/layout/layered/BoxLayoutOptions.js +80 -0
  63. package/src/core/{model/node-graph/visual/layout → graph/layout/layered}/LayoutBoxGraph.d.ts +35 -0
  64. package/src/core/graph/layout/layered/LayoutBoxGraph.d.ts.map +1 -0
  65. package/src/core/{model/node-graph/visual/layout → graph/layout/layered}/LayoutBoxGraph.js +53 -1
  66. package/src/core/graph/layout/layered/layout_assign_coordinates.d.ts.map +1 -0
  67. package/src/core/{model/node-graph/visual/layout → graph/layout/layered}/layout_assign_coordinates.js +72 -68
  68. package/src/core/graph/layout/layered/layout_assign_layers.d.ts.map +1 -0
  69. package/src/core/{model/node-graph/visual/layout → graph/layout/layered}/layout_assign_layers.js +4 -2
  70. package/src/core/graph/layout/layered/layout_break_cycles.d.ts.map +1 -0
  71. package/src/core/graph/layout/layered/layout_insert_lanes.d.ts.map +1 -0
  72. package/src/core/graph/layout/layered/layout_order_layers.d.ts.map +1 -0
  73. package/src/core/graph/layout/layered/layout_orient_links.d.ts.map +1 -0
  74. package/src/core/model/node-graph/visual/layout/NodeGraphLayoutOptions.d.ts +7 -51
  75. package/src/core/model/node-graph/visual/layout/NodeGraphLayoutOptions.d.ts.map +1 -1
  76. package/src/core/model/node-graph/visual/layout/NodeGraphLayoutOptions.js +8 -69
  77. package/src/core/model/node-graph/visual/layout/layout_build_problem.js +1 -1
  78. package/src/core/model/node-graph/visual/layout/layout_node_graph.js +6 -6
  79. package/src/core/model/node-graph/visual/layout/route_grid_build.js +1 -1
  80. package/src/engine/Engine.d.ts.map +1 -1
  81. package/src/engine/Engine.js +38 -1
  82. package/src/engine/graphics3/DebugDrawSystem.d.ts +7 -5
  83. package/src/engine/graphics3/DebugDrawSystem.d.ts.map +1 -1
  84. package/src/engine/graphics3/DebugDrawSystem.js +206 -203
  85. package/src/engine/graphics3/DecalSystem.d.ts +4 -5
  86. package/src/engine/graphics3/DecalSystem.d.ts.map +1 -1
  87. package/src/engine/graphics3/DecalSystem.js +5 -5
  88. package/src/engine/graphics3/FogOfWarSystem.d.ts +7 -12
  89. package/src/engine/graphics3/FogOfWarSystem.d.ts.map +1 -1
  90. package/src/engine/graphics3/FogOfWarSystem.js +8 -12
  91. package/src/engine/graphics3/GraphicsEngine.d.ts +5 -1
  92. package/src/engine/graphics3/GraphicsEngine.d.ts.map +1 -1
  93. package/src/engine/graphics3/GraphicsEngine.js +834 -830
  94. package/src/engine/graphics3/prefab/prefab_instantiate.js +230 -230
  95. package/src/shade/RENDERER_CONTRACT.md +31 -17
  96. package/src/shade/device/timing/GPU_PROFILER_PROPOSAL_2026_08_28.md +1 -1
  97. package/src/shade/playground/caldera/README.md +529 -0
  98. package/src/shade/playground/caldera/caldera_format.d.ts +151 -0
  99. package/src/shade/playground/caldera/caldera_format.d.ts.map +1 -0
  100. package/src/shade/playground/caldera/caldera_format.js +241 -0
  101. package/src/shade/playground/caldera/index.html +126 -0
  102. package/src/shade/playground/caldera/main.d.ts.map +1 -0
  103. package/src/shade/playground/caldera/main.js +1565 -0
  104. package/src/shade/playground/mesh_row_ceiling/README.md +85 -0
  105. package/src/shade/playground/mesh_row_ceiling/index.html +31 -0
  106. package/src/shade/playground/mesh_row_ceiling/main.d.ts +2 -0
  107. package/src/shade/playground/mesh_row_ceiling/main.d.ts.map +1 -0
  108. package/src/shade/playground/mesh_row_ceiling/main.js +389 -0
  109. package/src/shade/playground/vgeo_runtime/README.md +32 -16
  110. package/src/shade/playground/vgeo_runtime/main.js +21 -7
  111. package/src/shade/playground/{vgeo_viewer → vgeo_runtime}/sample_asset.d.ts +3 -3
  112. package/src/shade/playground/vgeo_runtime/sample_asset.d.ts.map +1 -0
  113. package/src/shade/playground/{vgeo_viewer → vgeo_runtime}/sample_asset.js +12 -11
  114. package/src/shade/playground/vgeo_scene/README.md +487 -0
  115. package/src/shade/playground/vgeo_scene/index.html +144 -0
  116. package/src/shade/playground/vgeo_scene/main.d.ts +2 -0
  117. package/src/shade/playground/vgeo_scene/main.d.ts.map +1 -0
  118. package/src/shade/playground/vgeo_scene/main.js +2217 -0
  119. package/src/shade/renderer/GraphicsContext.d.ts.map +1 -1
  120. package/src/shade/renderer/GraphicsContext.js +6 -0
  121. package/src/shade/renderer/Renderer.d.ts +6 -1
  122. package/src/shade/renderer/Renderer.d.ts.map +1 -1
  123. package/src/shade/renderer/Renderer.js +28 -2
  124. package/src/shade/renderer/animation/skinning/GPUMeshSkinningContext.d.ts.map +1 -1
  125. package/src/shade/renderer/animation/skinning/GPUMeshSkinningContext.js +100 -8
  126. package/src/shade/renderer/extension/RENDER_EXTENSION_DESIGN.md +70 -35
  127. package/src/shade/renderer/extension/RenderExtension.d.ts +15 -18
  128. package/src/shade/renderer/extension/RenderExtension.d.ts.map +1 -1
  129. package/src/shade/renderer/extension/RenderExtension.js +15 -19
  130. package/src/shade/renderer/extension/RenderExtensionRegistry.d.ts +5 -5
  131. package/src/shade/renderer/extension/RenderExtensionRegistry.d.ts.map +1 -1
  132. package/src/shade/renderer/extension/RenderExtensionRegistry.js +29 -166
  133. package/src/shade/renderer/geometry/GPUGeometryManager.d.ts.map +1 -1
  134. package/src/shade/renderer/geometry/GPUGeometryManager.js +73 -16
  135. package/src/shade/renderer/geometry/bvh/GPUGeometryBVHManager.d.ts.map +1 -1
  136. package/src/shade/renderer/geometry/bvh/GPUGeometryBVHManager.js +18 -3
  137. package/src/shade/renderer/geometry/meshlet/COMPACTION_PLAN_2026_09_16.md +663 -0
  138. package/src/shade/renderer/geometry/meshlet/GPUMeshletManager.d.ts +100 -5
  139. package/src/shade/renderer/geometry/meshlet/GPUMeshletManager.d.ts.map +1 -1
  140. package/src/shade/renderer/geometry/meshlet/GPUMeshletManager.js +688 -81
  141. package/src/shade/renderer/geometry/meshlet/MeshletBatch.d.ts.map +1 -1
  142. package/src/shade/renderer/geometry/meshlet/MeshletBatch.js +3 -29
  143. package/src/shade/renderer/geometry/meshlet/encoding/ENCODED_ATTRIBUTE_DEFAULT_VALUES.d.ts +22 -0
  144. package/src/shade/renderer/geometry/meshlet/encoding/ENCODED_ATTRIBUTE_DEFAULT_VALUES.d.ts.map +1 -0
  145. package/src/shade/renderer/geometry/meshlet/encoding/ENCODED_ATTRIBUTE_DEFAULT_VALUES.js +49 -0
  146. package/src/shade/renderer/geometry/virtual/ATTRIBUTE_PLAN_2026_09_18.md +540 -0
  147. package/src/shade/renderer/geometry/virtual/VGEO_FORMAT.md +159 -66
  148. package/src/shade/renderer/geometry/virtual/VIRTUAL_GEOMETRY_DESIGN.md +40 -21
  149. package/src/shade/renderer/geometry/virtual/VIRTUAL_GEOMETRY_PLAN.md +15 -14
  150. package/src/shade/renderer/geometry/virtual/WEDGE_PLAN_2026_09_18.md +358 -0
  151. package/src/shade/renderer/geometry/virtual/build/VGeoBuildOptions.d.ts +58 -8
  152. package/src/shade/renderer/geometry/virtual/build/VGeoBuildOptions.d.ts.map +1 -1
  153. package/src/shade/renderer/geometry/virtual/build/VGeoBuildOptions.js +64 -10
  154. package/src/shade/renderer/geometry/virtual/build/gltf/gltf_open_document.d.ts.map +1 -1
  155. package/src/shade/renderer/geometry/virtual/build/gltf/gltf_open_document.js +5 -9
  156. package/src/shade/renderer/geometry/virtual/build/level/VGeoContribution.d.ts +40 -0
  157. package/src/shade/renderer/geometry/virtual/build/level/VGeoContribution.d.ts.map +1 -0
  158. package/src/shade/renderer/geometry/virtual/build/level/VGeoContribution.js +24 -0
  159. package/src/shade/renderer/geometry/virtual/build/level/VGeoFrontier.d.ts +91 -0
  160. package/src/shade/renderer/geometry/virtual/build/level/VGeoFrontier.d.ts.map +1 -0
  161. package/src/shade/renderer/geometry/virtual/build/level/VGeoFrontier.js +91 -0
  162. package/src/shade/renderer/geometry/virtual/build/level/VGeoGroupRepack.d.ts +24 -0
  163. package/src/shade/renderer/geometry/virtual/build/level/VGeoGroupRepack.d.ts.map +1 -0
  164. package/src/shade/renderer/geometry/virtual/build/level/VGeoGroupRepack.js +25 -0
  165. package/src/shade/renderer/geometry/virtual/build/level/VGeoGroupStep.d.ts +77 -0
  166. package/src/shade/renderer/geometry/virtual/build/level/VGeoGroupStep.d.ts.map +1 -0
  167. package/src/shade/renderer/geometry/virtual/build/level/VGeoGroupStep.js +84 -0
  168. package/src/shade/renderer/geometry/virtual/build/level/VGeoLevel.d.ts.map +1 -0
  169. package/src/shade/renderer/geometry/virtual/build/{VGeoLevelOptions.d.ts → level/VGeoLevelOptions.d.ts} +19 -6
  170. package/src/shade/renderer/geometry/virtual/build/level/VGeoLevelOptions.d.ts.map +1 -0
  171. package/src/shade/renderer/geometry/virtual/build/{VGeoLevelOptions.js → level/VGeoLevelOptions.js} +20 -7
  172. package/src/shade/renderer/geometry/virtual/build/level/VGeoLevelSummary.d.ts.map +1 -0
  173. package/src/shade/renderer/geometry/virtual/build/level/vgeo_build_cluster.d.ts +19 -0
  174. package/src/shade/renderer/geometry/virtual/build/level/vgeo_build_cluster.d.ts.map +1 -0
  175. package/src/shade/renderer/geometry/virtual/build/level/vgeo_build_cluster.js +58 -0
  176. package/src/shade/renderer/geometry/virtual/build/level/vgeo_build_cluster_graph.d.ts +18 -0
  177. package/src/shade/renderer/geometry/virtual/build/level/vgeo_build_cluster_graph.d.ts.map +1 -0
  178. package/src/shade/renderer/geometry/virtual/build/level/vgeo_build_cluster_graph.js +116 -0
  179. package/src/shade/renderer/geometry/virtual/build/level/vgeo_build_group_step.d.ts +18 -0
  180. package/src/shade/renderer/geometry/virtual/build/level/vgeo_build_group_step.d.ts.map +1 -0
  181. package/src/shade/renderer/geometry/virtual/build/level/vgeo_build_group_step.js +545 -0
  182. package/src/shade/renderer/geometry/virtual/build/level/vgeo_build_leaf_frontier.d.ts +16 -0
  183. package/src/shade/renderer/geometry/virtual/build/level/vgeo_build_leaf_frontier.d.ts.map +1 -0
  184. package/src/shade/renderer/geometry/virtual/build/level/vgeo_build_leaf_frontier.js +110 -0
  185. package/src/shade/renderer/geometry/virtual/build/level/vgeo_build_levels.d.ts +11 -0
  186. package/src/shade/renderer/geometry/virtual/build/level/vgeo_build_levels.d.ts.map +1 -0
  187. package/src/shade/renderer/geometry/virtual/build/level/vgeo_build_levels.js +308 -0
  188. package/src/shade/renderer/geometry/virtual/build/{vgeo_build_root_group.d.ts → level/vgeo_build_root_group.d.ts} +1 -1
  189. package/src/shade/renderer/geometry/virtual/build/level/vgeo_build_root_group.d.ts.map +1 -0
  190. package/src/shade/renderer/geometry/virtual/build/{vgeo_build_root_group.js → level/vgeo_build_root_group.js} +1 -1
  191. package/src/shade/renderer/geometry/virtual/build/level/vgeo_compute_group_boundary.d.ts +26 -0
  192. package/src/shade/renderer/geometry/virtual/build/level/vgeo_compute_group_boundary.d.ts.map +1 -0
  193. package/src/shade/renderer/geometry/virtual/build/level/vgeo_compute_group_boundary.js +123 -0
  194. package/src/shade/renderer/geometry/virtual/build/level/vgeo_error_bands.d.ts +26 -0
  195. package/src/shade/renderer/geometry/virtual/build/level/vgeo_error_bands.d.ts.map +1 -0
  196. package/src/shade/renderer/geometry/virtual/build/level/vgeo_error_bands.js +78 -0
  197. package/src/shade/renderer/geometry/virtual/build/level/vgeo_partition_into_groups.d.ts +24 -0
  198. package/src/shade/renderer/geometry/virtual/build/level/vgeo_partition_into_groups.d.ts.map +1 -0
  199. package/src/shade/renderer/geometry/virtual/build/level/vgeo_partition_into_groups.js +337 -0
  200. package/src/shade/renderer/geometry/virtual/build/level/vgeo_run_round.d.ts +29 -0
  201. package/src/shade/renderer/geometry/virtual/build/level/vgeo_run_round.d.ts.map +1 -0
  202. package/src/shade/renderer/geometry/virtual/build/level/vgeo_run_round.js +147 -0
  203. package/src/shade/renderer/geometry/virtual/build/level/vgeo_stitch_frontier.d.ts +37 -0
  204. package/src/shade/renderer/geometry/virtual/build/level/vgeo_stitch_frontier.d.ts.map +1 -0
  205. package/src/shade/renderer/geometry/virtual/build/level/vgeo_stitch_frontier.js +243 -0
  206. package/src/shade/renderer/geometry/virtual/build/level/vgeo_try_repack.d.ts +29 -0
  207. package/src/shade/renderer/geometry/virtual/build/level/vgeo_try_repack.d.ts.map +1 -0
  208. package/src/shade/renderer/geometry/virtual/build/level/vgeo_try_repack.js +117 -0
  209. package/src/shade/renderer/geometry/virtual/build/mesh/VGEO_CREASE_ANGLE.d.ts +46 -0
  210. package/src/shade/renderer/geometry/virtual/build/mesh/VGEO_CREASE_ANGLE.d.ts.map +1 -0
  211. package/src/shade/renderer/geometry/virtual/build/mesh/VGEO_CREASE_ANGLE.js +45 -0
  212. package/src/shade/renderer/geometry/virtual/build/mesh/VGEO_DEFAULT_ATTRIBUTE_WEIGHT_RATIOS.d.ts +64 -0
  213. package/src/shade/renderer/geometry/virtual/build/mesh/VGEO_DEFAULT_ATTRIBUTE_WEIGHT_RATIOS.d.ts.map +1 -0
  214. package/src/shade/renderer/geometry/virtual/build/mesh/VGEO_DEFAULT_ATTRIBUTE_WEIGHT_RATIOS.js +68 -0
  215. package/src/shade/renderer/geometry/virtual/build/{VirtualGeometryMesh.d.ts → mesh/VirtualGeometryMesh.d.ts} +13 -8
  216. package/src/shade/renderer/geometry/virtual/build/mesh/VirtualGeometryMesh.d.ts.map +1 -0
  217. package/src/shade/renderer/geometry/virtual/build/{VirtualGeometryMesh.js → mesh/VirtualGeometryMesh.js} +40 -18
  218. package/src/shade/renderer/geometry/virtual/build/mesh/vgeo_attribute_vector_layout.d.ts +58 -0
  219. package/src/shade/renderer/geometry/virtual/build/mesh/vgeo_attribute_vector_layout.d.ts.map +1 -0
  220. package/src/shade/renderer/geometry/virtual/build/mesh/vgeo_attribute_vector_layout.js +79 -0
  221. package/src/shade/renderer/geometry/virtual/build/mesh/vgeo_attribute_vector_read.d.ts +39 -0
  222. package/src/shade/renderer/geometry/virtual/build/mesh/vgeo_attribute_vector_read.d.ts.map +1 -0
  223. package/src/shade/renderer/geometry/virtual/build/mesh/vgeo_attribute_vector_read.js +68 -0
  224. package/src/shade/renderer/geometry/virtual/build/mesh/vgeo_attribute_vector_write.d.ts +53 -0
  225. package/src/shade/renderer/geometry/virtual/build/mesh/vgeo_attribute_vector_write.d.ts.map +1 -0
  226. package/src/shade/renderer/geometry/virtual/build/mesh/vgeo_attribute_vector_write.js +243 -0
  227. package/src/shade/renderer/geometry/virtual/build/mesh/vgeo_compute_vertex_normals.d.ts +45 -0
  228. package/src/shade/renderer/geometry/virtual/build/mesh/vgeo_compute_vertex_normals.d.ts.map +1 -0
  229. package/src/shade/renderer/geometry/virtual/build/mesh/vgeo_compute_vertex_normals.js +300 -0
  230. package/src/shade/renderer/geometry/virtual/build/{vgeo_compute_vertex_tangents.d.ts → mesh/vgeo_compute_vertex_tangents.d.ts} +12 -8
  231. package/src/shade/renderer/geometry/virtual/build/mesh/vgeo_compute_vertex_tangents.d.ts.map +1 -0
  232. package/src/shade/renderer/geometry/virtual/build/mesh/vgeo_compute_vertex_tangents.js +151 -0
  233. package/src/shade/renderer/geometry/virtual/build/{vgeo_normalize_source.d.ts → mesh/vgeo_normalize_source.d.ts} +8 -1
  234. package/src/shade/renderer/geometry/virtual/build/mesh/vgeo_normalize_source.d.ts.map +1 -0
  235. package/src/shade/renderer/geometry/virtual/build/{vgeo_normalize_source.js → mesh/vgeo_normalize_source.js} +27 -12
  236. package/src/shade/renderer/geometry/virtual/build/mesh/vgeo_resolve_attribute_weights.d.ts +38 -0
  237. package/src/shade/renderer/geometry/virtual/build/mesh/vgeo_resolve_attribute_weights.d.ts.map +1 -0
  238. package/src/shade/renderer/geometry/virtual/build/mesh/vgeo_resolve_attribute_weights.js +81 -0
  239. package/src/shade/renderer/geometry/virtual/build/{vgeo_assemble_pages.d.ts → page/vgeo_assemble_pages.d.ts} +1 -1
  240. package/src/shade/renderer/geometry/virtual/build/page/vgeo_assemble_pages.d.ts.map +1 -0
  241. package/src/shade/renderer/geometry/virtual/build/{vgeo_assemble_pages.js → page/vgeo_assemble_pages.js} +9 -9
  242. package/src/shade/renderer/geometry/virtual/build/{vgeo_build_page_nodes.d.ts → page/vgeo_build_page_nodes.d.ts} +1 -1
  243. package/src/shade/renderer/geometry/virtual/build/page/vgeo_build_page_nodes.d.ts.map +1 -0
  244. package/src/shade/renderer/geometry/virtual/build/{vgeo_build_page_nodes.js → page/vgeo_build_page_nodes.js} +4 -4
  245. package/src/shade/renderer/geometry/virtual/build/page/vgeo_page_node_count.d.ts.map +1 -0
  246. package/src/shade/renderer/geometry/virtual/build/{vgeo_page_node_count.js → page/vgeo_page_node_count.js} +2 -2
  247. package/src/shade/renderer/geometry/virtual/build/{VGeoFaceGraph.d.ts → partition/VGeoFaceGraph.d.ts} +23 -5
  248. package/src/shade/renderer/geometry/virtual/build/partition/VGeoFaceGraph.d.ts.map +1 -0
  249. package/src/shade/renderer/geometry/virtual/build/{VGeoFaceGraph.js → partition/VGeoFaceGraph.js} +28 -21
  250. package/src/shade/renderer/geometry/virtual/build/partition/vgeo_graph_components.d.ts.map +1 -0
  251. package/src/shade/renderer/geometry/virtual/build/partition/vgeo_partition_graph.d.ts.map +1 -0
  252. package/src/shade/renderer/geometry/virtual/build/{vgeo_partition_graph.js → partition/vgeo_partition_graph.js} +2 -2
  253. package/src/shade/renderer/geometry/virtual/build/partition/vgeo_partition_subgraph.d.ts +41 -0
  254. package/src/shade/renderer/geometry/virtual/build/partition/vgeo_partition_subgraph.d.ts.map +1 -0
  255. package/src/shade/renderer/geometry/virtual/build/partition/vgeo_partition_subgraph.js +92 -0
  256. package/src/shade/renderer/geometry/virtual/build/partition/vgeo_split_face_set.d.ts.map +1 -0
  257. package/src/shade/renderer/geometry/virtual/build/{vgeo_split_face_set.js → partition/vgeo_split_face_set.js} +13 -56
  258. package/src/shade/renderer/geometry/virtual/build/partition/vgeo_split_face_set_packed.d.ts.map +1 -0
  259. package/src/shade/renderer/geometry/virtual/build/partition/vgeo_split_face_set_packed.js +371 -0
  260. package/src/shade/renderer/geometry/virtual/build/sphere/vgeo_bounding_sphere.d.ts.map +1 -0
  261. package/src/shade/renderer/geometry/virtual/build/{vgeo_bounding_sphere.js → sphere/vgeo_bounding_sphere.js} +3 -3
  262. package/src/shade/renderer/geometry/virtual/build/sphere/vgeo_containing_sphere.d.ts.map +1 -0
  263. package/src/shade/renderer/geometry/virtual/build/{vgeo_containing_sphere.js → sphere/vgeo_containing_sphere.js} +3 -3
  264. package/src/shade/renderer/geometry/virtual/build/sphere/vgeo_sphere_inflate_to_contain.d.ts.map +1 -0
  265. package/src/shade/renderer/geometry/virtual/build/{vgeo_sphere_inflate_to_contain.js → sphere/vgeo_sphere_inflate_to_contain.js} +1 -1
  266. package/src/shade/renderer/geometry/virtual/build/submesh/VGeoGatheredFaces.d.ts +39 -0
  267. package/src/shade/renderer/geometry/virtual/build/submesh/VGeoGatheredFaces.d.ts.map +1 -0
  268. package/src/shade/renderer/geometry/virtual/build/submesh/VGeoGatheredFaces.js +42 -0
  269. package/src/shade/renderer/geometry/virtual/build/submesh/VGeoSubmesh.d.ts +37 -0
  270. package/src/shade/renderer/geometry/virtual/build/submesh/VGeoSubmesh.d.ts.map +1 -0
  271. package/src/shade/renderer/geometry/virtual/build/submesh/VGeoSubmesh.js +39 -0
  272. package/src/shade/renderer/geometry/virtual/build/submesh/vgeo_extract_submesh.d.ts +23 -0
  273. package/src/shade/renderer/geometry/virtual/build/submesh/vgeo_extract_submesh.d.ts.map +1 -0
  274. package/src/shade/renderer/geometry/virtual/build/submesh/vgeo_extract_submesh.js +135 -0
  275. package/src/shade/renderer/geometry/virtual/build/submesh/vgeo_gather_faces.d.ts +24 -0
  276. package/src/shade/renderer/geometry/virtual/build/submesh/vgeo_gather_faces.d.ts.map +1 -0
  277. package/src/shade/renderer/geometry/virtual/build/submesh/vgeo_gather_faces.js +95 -0
  278. package/src/shade/renderer/geometry/virtual/build/submesh/vgeo_narrow_indices.d.ts.map +1 -0
  279. package/src/shade/renderer/geometry/virtual/build/{vgeo_narrow_indices.js → submesh/vgeo_narrow_indices.js} +3 -3
  280. package/src/shade/renderer/geometry/virtual/build/vgeo_build.d.ts +6 -2
  281. package/src/shade/renderer/geometry/virtual/build/vgeo_build.d.ts.map +1 -1
  282. package/src/shade/renderer/geometry/virtual/build/vgeo_build.js +37 -16
  283. package/src/shade/renderer/geometry/virtual/build/vgeo_subtree_bounds.d.ts +32 -0
  284. package/src/shade/renderer/geometry/virtual/build/vgeo_subtree_bounds.d.ts.map +1 -0
  285. package/src/shade/renderer/geometry/virtual/build/vgeo_subtree_bounds.js +93 -0
  286. package/src/shade/renderer/geometry/virtual/format/VGeoWriteOptions.d.ts +20 -6
  287. package/src/shade/renderer/geometry/virtual/format/VGeoWriteOptions.d.ts.map +1 -1
  288. package/src/shade/renderer/geometry/virtual/format/VGeoWriteOptions.js +22 -8
  289. package/src/shade/renderer/geometry/virtual/format/attribute/vgeo_attributes_read.d.ts +8 -2
  290. package/src/shade/renderer/geometry/virtual/format/attribute/vgeo_attributes_read.d.ts.map +1 -1
  291. package/src/shade/renderer/geometry/virtual/format/attribute/vgeo_attributes_read.js +8 -2
  292. package/src/shade/renderer/geometry/virtual/format/attribute/vgeo_layers_copy_corner.d.ts +16 -0
  293. package/src/shade/renderer/geometry/virtual/format/attribute/vgeo_layers_copy_corner.d.ts.map +1 -0
  294. package/src/shade/renderer/geometry/virtual/format/attribute/{vgeo_layers_copy_vertex.js → vgeo_layers_copy_corner.js} +8 -8
  295. package/src/shade/renderer/geometry/virtual/format/attribute/vgeo_layers_declare.d.ts +18 -7
  296. package/src/shade/renderer/geometry/virtual/format/attribute/vgeo_layers_declare.d.ts.map +1 -1
  297. package/src/shade/renderer/geometry/virtual/format/attribute/vgeo_layers_declare.js +19 -8
  298. package/src/shade/renderer/geometry/virtual/format/attribute/vgeo_layers_like.d.ts +3 -3
  299. package/src/shade/renderer/geometry/virtual/format/attribute/vgeo_layers_like.js +3 -3
  300. package/src/shade/renderer/geometry/virtual/format/attribute/vgeo_mesh_wedges.d.ts +27 -0
  301. package/src/shade/renderer/geometry/virtual/format/attribute/vgeo_mesh_wedges.d.ts.map +1 -0
  302. package/src/shade/renderer/geometry/virtual/format/attribute/vgeo_mesh_wedges.js +97 -0
  303. package/src/shade/renderer/geometry/virtual/format/cluster/VGEO_CLUSTER_OFFSET.d.ts +7 -3
  304. package/src/shade/renderer/geometry/virtual/format/cluster/VGEO_CLUSTER_OFFSET.d.ts.map +1 -1
  305. package/src/shade/renderer/geometry/virtual/format/cluster/VGEO_CLUSTER_OFFSET.js +21 -11
  306. package/src/shade/renderer/geometry/virtual/format/cluster/VGEO_CLUSTER_OFFSET_V4.d.ts +21 -0
  307. package/src/shade/renderer/geometry/virtual/format/cluster/VGEO_CLUSTER_OFFSET_V4.d.ts.map +1 -0
  308. package/src/shade/renderer/geometry/virtual/format/cluster/VGEO_CLUSTER_OFFSET_V4.js +41 -0
  309. package/src/shade/renderer/geometry/virtual/format/dag/VirtualGeometryCluster.d.ts +19 -1
  310. package/src/shade/renderer/geometry/virtual/format/dag/VirtualGeometryCluster.d.ts.map +1 -1
  311. package/src/shade/renderer/geometry/virtual/format/dag/VirtualGeometryCluster.js +20 -1
  312. package/src/shade/renderer/geometry/virtual/format/frame/VGEO_CODEC_DEFLATE.d.ts +25 -0
  313. package/src/shade/renderer/geometry/virtual/format/frame/VGEO_CODEC_DEFLATE.d.ts.map +1 -0
  314. package/src/shade/renderer/geometry/virtual/format/frame/VGEO_CODEC_DEFLATE.js +24 -0
  315. package/src/shade/renderer/geometry/virtual/format/frame/VGEO_CODEC_LZ4.d.ts +5 -0
  316. package/src/shade/renderer/geometry/virtual/format/frame/VGEO_CODEC_LZ4.d.ts.map +1 -1
  317. package/src/shade/renderer/geometry/virtual/format/frame/VGEO_CODEC_LZ4.js +5 -0
  318. package/src/shade/renderer/geometry/virtual/format/frame/vgeo_codec_name.d.ts.map +1 -1
  319. package/src/shade/renderer/geometry/virtual/format/frame/vgeo_codec_name.js +5 -0
  320. package/src/shade/renderer/geometry/virtual/format/frame/vgeo_decode_frame_blob.d.ts +10 -3
  321. package/src/shade/renderer/geometry/virtual/format/frame/vgeo_decode_frame_blob.d.ts.map +1 -1
  322. package/src/shade/renderer/geometry/virtual/format/frame/vgeo_decode_frame_blob.js +37 -3
  323. package/src/shade/renderer/geometry/virtual/format/frame/vgeo_encode_frame_blob.d.ts +21 -13
  324. package/src/shade/renderer/geometry/virtual/format/frame/vgeo_encode_frame_blob.d.ts.map +1 -1
  325. package/src/shade/renderer/geometry/virtual/format/frame/vgeo_encode_frame_blob.js +37 -13
  326. package/src/shade/renderer/geometry/virtual/format/frame/vgeo_frame_decode_bound.d.ts +8 -2
  327. package/src/shade/renderer/geometry/virtual/format/frame/vgeo_frame_decode_bound.d.ts.map +1 -1
  328. package/src/shade/renderer/geometry/virtual/format/frame/vgeo_frame_decode_bound.js +14 -2
  329. package/src/shade/renderer/geometry/virtual/format/header/VGEO_FORMAT_VERSION.d.ts +18 -0
  330. package/src/shade/renderer/geometry/virtual/format/header/VGEO_FORMAT_VERSION.d.ts.map +1 -1
  331. package/src/shade/renderer/geometry/virtual/format/header/VGEO_FORMAT_VERSION.js +19 -1
  332. package/src/shade/renderer/geometry/virtual/format/header/VGEO_HEADER_OFFSET.js +6 -0
  333. package/src/shade/renderer/geometry/virtual/format/header/VGEO_MAX_LEVEL_COUNT.d.ts +21 -0
  334. package/src/shade/renderer/geometry/virtual/format/header/VGEO_MAX_LEVEL_COUNT.d.ts.map +1 -0
  335. package/src/shade/renderer/geometry/virtual/format/header/VGEO_MAX_LEVEL_COUNT.js +20 -0
  336. package/src/shade/renderer/geometry/virtual/format/header/VGEO_MIN_READER_VERSION.d.ts +9 -0
  337. package/src/shade/renderer/geometry/virtual/format/header/VGEO_MIN_READER_VERSION.d.ts.map +1 -1
  338. package/src/shade/renderer/geometry/virtual/format/header/VGEO_MIN_READER_VERSION.js +10 -1
  339. package/src/shade/renderer/geometry/virtual/format/page/VGEO_GROUP_OFFSET.d.ts +15 -0
  340. package/src/shade/renderer/geometry/virtual/format/page/VGEO_GROUP_OFFSET.d.ts.map +1 -0
  341. package/src/shade/renderer/geometry/virtual/format/page/VGEO_GROUP_OFFSET.js +15 -0
  342. package/src/shade/renderer/geometry/virtual/format/page/VGEO_PAGE_OFFSET.d.ts +1 -2
  343. package/src/shade/renderer/geometry/virtual/format/page/VGEO_PAGE_OFFSET.js +10 -3
  344. package/src/shade/renderer/geometry/virtual/format/page/VGEO_PAGE_OFFSET_V5.d.ts +20 -0
  345. package/src/shade/renderer/geometry/virtual/format/page/VGEO_PAGE_OFFSET_V5.d.ts.map +1 -0
  346. package/src/shade/renderer/geometry/virtual/format/page/VGEO_PAGE_OFFSET_V5.js +43 -0
  347. package/src/shade/renderer/geometry/virtual/format/payload/vgeo_encode_cluster_payload.d.ts +32 -2
  348. package/src/shade/renderer/geometry/virtual/format/payload/vgeo_encode_cluster_payload.d.ts.map +1 -1
  349. package/src/shade/renderer/geometry/virtual/format/payload/vgeo_encode_cluster_payload.js +15 -7
  350. package/src/shade/renderer/geometry/virtual/format/read/VGeoContainerReader.d.ts.map +1 -1
  351. package/src/shade/renderer/geometry/virtual/format/read/VGeoContainerReader.js +2 -2
  352. package/src/shade/renderer/geometry/virtual/format/read/VGeoDirectory.d.ts +6 -4
  353. package/src/shade/renderer/geometry/virtual/format/read/VGeoDirectory.d.ts.map +1 -1
  354. package/src/shade/renderer/geometry/virtual/format/read/VGeoDirectory.js +6 -4
  355. package/src/shade/renderer/geometry/virtual/format/read/VGeoPage.d.ts +13 -2
  356. package/src/shade/renderer/geometry/virtual/format/read/VGeoPage.d.ts.map +1 -1
  357. package/src/shade/renderer/geometry/virtual/format/read/VGeoPage.js +13 -2
  358. package/src/shade/renderer/geometry/virtual/format/read/VGeoPageFetcherCore.d.ts +5 -1
  359. package/src/shade/renderer/geometry/virtual/format/read/VGeoPageFetcherCore.d.ts.map +1 -1
  360. package/src/shade/renderer/geometry/virtual/format/read/VGeoPageFetcherCore.js +14 -1
  361. package/src/shade/renderer/geometry/virtual/format/read/vgeo_page_worker_serve.d.ts.map +1 -1
  362. package/src/shade/renderer/geometry/virtual/format/read/vgeo_page_worker_serve.js +1 -0
  363. package/src/shade/renderer/geometry/virtual/format/read/vgeo_read_directory.d.ts +4 -1
  364. package/src/shade/renderer/geometry/virtual/format/read/vgeo_read_directory.d.ts.map +1 -1
  365. package/src/shade/renderer/geometry/virtual/format/read/vgeo_read_directory.js +53 -11
  366. package/src/shade/renderer/geometry/virtual/format/read/vgeo_read_header.d.ts.map +1 -1
  367. package/src/shade/renderer/geometry/virtual/format/read/vgeo_read_header.js +7 -3
  368. package/src/shade/renderer/geometry/virtual/format/read/vgeo_read_page.d.ts +12 -2
  369. package/src/shade/renderer/geometry/virtual/format/read/vgeo_read_page.d.ts.map +1 -1
  370. package/src/shade/renderer/geometry/virtual/format/read/vgeo_read_page.js +120 -37
  371. package/src/shade/renderer/geometry/virtual/format/vgeo_validate_container.d.ts +6 -2
  372. package/src/shade/renderer/geometry/virtual/format/vgeo_validate_container.d.ts.map +1 -1
  373. package/src/shade/renderer/geometry/virtual/format/vgeo_validate_container.js +130 -47
  374. package/src/shade/renderer/geometry/virtual/format/vgeo_write_container.d.ts +2 -2
  375. package/src/shade/renderer/geometry/virtual/format/vgeo_write_container.d.ts.map +1 -1
  376. package/src/shade/renderer/geometry/virtual/format/vgeo_write_container.js +60 -22
  377. package/src/shade/renderer/geometry/virtual/runtime/CULL_PLAN_2026_09_16.md +385 -0
  378. package/src/shade/renderer/geometry/virtual/runtime/CUT_PLAN_2026_09_14.md +21 -2
  379. package/src/shade/renderer/geometry/virtual/runtime/GPUVirtualGeometryRuntime.d.ts +52 -2
  380. package/src/shade/renderer/geometry/virtual/runtime/GPUVirtualGeometryRuntime.d.ts.map +1 -1
  381. package/src/shade/renderer/geometry/virtual/runtime/GPUVirtualGeometryRuntime.js +97 -1
  382. package/src/shade/renderer/geometry/virtual/runtime/RUNTIME_PLAN.md +4 -4
  383. package/src/shade/renderer/geometry/virtual/runtime/VGeoFeedbackLoop.d.ts.map +1 -1
  384. package/src/shade/renderer/geometry/virtual/runtime/VGeoFeedbackLoop.js +10 -0
  385. package/src/shade/renderer/geometry/virtual/runtime/VGeoPageFetcher.d.ts.map +1 -1
  386. package/src/shade/renderer/geometry/virtual/runtime/VGeoPageFetcher.js +9 -0
  387. package/src/shade/renderer/geometry/virtual/runtime/VGeoResidency.d.ts.map +1 -1
  388. package/src/shade/renderer/geometry/virtual/runtime/VGeoResidency.js +59 -34
  389. package/src/shade/renderer/geometry/virtual/runtime/cut/chunk_vgeo_cut_access.d.ts +8 -8
  390. package/src/shade/renderer/geometry/virtual/runtime/cut/chunk_vgeo_cut_access.d.ts.map +1 -1
  391. package/src/shade/renderer/geometry/virtual/runtime/cut/chunk_vgeo_cut_access.js +45 -88
  392. package/src/shade/renderer/geometry/virtual/runtime/cut/chunk_vgeo_cut_arena.d.ts +19 -0
  393. package/src/shade/renderer/geometry/virtual/runtime/cut/chunk_vgeo_cut_arena.d.ts.map +1 -0
  394. package/src/shade/renderer/geometry/virtual/runtime/cut/chunk_vgeo_cut_arena.js +116 -0
  395. package/src/shade/renderer/geometry/virtual/runtime/cut/chunk_vgeo_cut_claim.d.ts +31 -0
  396. package/src/shade/renderer/geometry/virtual/runtime/cut/chunk_vgeo_cut_claim.d.ts.map +1 -0
  397. package/src/shade/renderer/geometry/virtual/runtime/cut/chunk_vgeo_cut_claim.js +99 -0
  398. package/src/shade/renderer/geometry/virtual/runtime/cut/chunk_vgeo_cut_queue.d.ts +17 -0
  399. package/src/shade/renderer/geometry/virtual/runtime/cut/chunk_vgeo_cut_queue.d.ts.map +1 -0
  400. package/src/shade/renderer/geometry/virtual/runtime/cut/chunk_vgeo_cut_queue.js +39 -0
  401. package/src/shade/renderer/geometry/virtual/runtime/cut/shader_vgeo_cut_reseed.d.ts.map +1 -1
  402. package/src/shade/renderer/geometry/virtual/runtime/cut/shader_vgeo_cut_reseed.js +7 -63
  403. package/src/shade/renderer/geometry/virtual/runtime/cut/shader_vgeo_cut_seed.d.ts.map +1 -1
  404. package/src/shade/renderer/geometry/virtual/runtime/cut/shader_vgeo_cut_seed.js +13 -30
  405. package/src/shade/renderer/geometry/virtual/runtime/cut/shader_vgeo_cut_traverse.d.ts.map +1 -1
  406. package/src/shade/renderer/geometry/virtual/runtime/cut/shader_vgeo_cut_traverse.js +53 -71
  407. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_CLUSTER_ROW_OFFSET.d.ts +1 -0
  408. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_CLUSTER_ROW_OFFSET.js +22 -4
  409. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_CLUSTER_ROW_WORDS.d.ts +7 -2
  410. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_CLUSTER_ROW_WORDS.d.ts.map +1 -1
  411. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_CLUSTER_ROW_WORDS.js +8 -3
  412. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_CUT_STAT.d.ts +1 -0
  413. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_CUT_STAT.js +10 -0
  414. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_CUT_STAT_COUNT.js +1 -1
  415. package/src/shade/renderer/geometry/virtual/runtime/vgeo_runtime_page_slot_words.d.ts +13 -11
  416. package/src/shade/renderer/geometry/virtual/runtime/vgeo_runtime_page_slot_words.d.ts.map +1 -1
  417. package/src/shade/renderer/geometry/virtual/runtime/vgeo_runtime_page_slot_words.js +13 -11
  418. package/src/shade/renderer/geometry/virtual/runtime/vgeo_runtime_write_page_block.d.ts.map +1 -1
  419. package/src/shade/renderer/geometry/virtual/runtime/vgeo_runtime_write_page_block.js +4 -0
  420. package/src/shade/renderer/global_illumination/sharc/shader/shader_sharc_evict.d.ts.map +1 -1
  421. package/src/shade/renderer/global_illumination/sharc/shader/shader_sharc_evict.js +3 -4
  422. package/src/shade/renderer/gpu_primitive/indirect/IndirectComputeCommandBuildPass.d.ts +6 -2
  423. package/src/shade/renderer/gpu_primitive/indirect/IndirectComputeCommandBuildPass.d.ts.map +1 -1
  424. package/src/shade/renderer/gpu_primitive/indirect/IndirectComputeCommandBuildPass.js +90 -12
  425. package/src/shade/renderer/gpu_primitive/indirect/WEBGPU_GUARANTEED_MAX_COMPUTE_WORKGROUPS_PER_DIMENSION.d.ts +22 -0
  426. package/src/shade/renderer/gpu_primitive/indirect/WEBGPU_GUARANTEED_MAX_COMPUTE_WORKGROUPS_PER_DIMENSION.d.ts.map +1 -0
  427. package/src/shade/renderer/gpu_primitive/indirect/WEBGPU_GUARANTEED_MAX_COMPUTE_WORKGROUPS_PER_DIMENSION.js +21 -0
  428. package/src/shade/renderer/loader/gltf/load_gltf.d.ts.map +1 -1
  429. package/src/shade/renderer/loader/gltf/load_gltf.js +0 -19
  430. package/src/shade/renderer/material/chunk_material_draw_side.d.ts +14 -0
  431. package/src/shade/renderer/material/chunk_material_draw_side.d.ts.map +1 -0
  432. package/src/shade/renderer/material/chunk_material_draw_side.js +34 -0
  433. package/src/shade/renderer/material/standard/fragment_gbuffer.d.ts.map +1 -1
  434. package/src/shade/renderer/material/standard/fragment_gbuffer.js +8 -1
  435. package/src/shade/renderer/particles/shaders/shader_particle_emit.d.ts.map +1 -1
  436. package/src/shade/renderer/particles/shaders/shader_particle_emit.js +13 -8
  437. package/src/shade/renderer/particles/shaders/shader_particle_simulate.d.ts.map +1 -1
  438. package/src/shade/renderer/particles/shaders/shader_particle_simulate.js +3 -6
  439. package/src/shade/renderer/path_tracer/shader/chunk_sample_material_data.d.ts.map +1 -1
  440. package/src/shade/renderer/path_tracer/shader/chunk_sample_material_data.js +13 -1
  441. package/src/shade/renderer/rasterize/bucket/construct_primitive_state.d.ts +19 -5
  442. package/src/shade/renderer/rasterize/bucket/construct_primitive_state.d.ts.map +1 -1
  443. package/src/shade/renderer/rasterize/bucket/construct_primitive_state.js +23 -5
  444. package/src/shade/renderer/rasterize/bucket/filter_materials_by_bucket.d.ts.map +1 -1
  445. package/src/shade/renderer/rasterize/bucket/filter_materials_by_bucket.js +12 -5
  446. package/src/shade/renderer/rasterize/bucket/prepare_meshlet_draw_commands_by_material.d.ts.map +1 -1
  447. package/src/shade/renderer/rasterize/bucket/prepare_meshlet_draw_commands_by_material.js +4 -12
  448. package/src/shade/renderer/rasterize/bucket/rasterization_opaque_buckets.d.ts +22 -0
  449. package/src/shade/renderer/rasterize/bucket/rasterization_opaque_buckets.d.ts.map +1 -0
  450. package/src/shade/renderer/rasterize/bucket/rasterization_opaque_buckets.js +36 -0
  451. package/src/shade/renderer/rasterize/bucket/shader_read_out_bucket.d.ts +0 -2
  452. package/src/shade/renderer/rasterize/bucket/shader_read_out_bucket.d.ts.map +1 -1
  453. package/src/shade/renderer/rasterize/bucket/shader_read_out_bucket.js +4 -5
  454. package/src/shade/renderer/rasterize/chunk_triangle_winding_is_reversed.d.ts +15 -0
  455. package/src/shade/renderer/rasterize/chunk_triangle_winding_is_reversed.d.ts.map +1 -0
  456. package/src/shade/renderer/rasterize/chunk_triangle_winding_is_reversed.js +35 -0
  457. package/src/shade/renderer/rasterize/cull/hzb/shader_hzb_mesh_filter_2way.d.ts.map +1 -1
  458. package/src/shade/renderer/rasterize/cull/hzb/shader_hzb_mesh_filter_2way.js +5 -3
  459. package/src/shade/renderer/rasterize/cull/hzb/shader_hzb_meshlet_filter_1way.d.ts.map +1 -1
  460. package/src/shade/renderer/rasterize/cull/hzb/shader_hzb_meshlet_filter_1way.js +11 -4
  461. package/src/shade/renderer/rasterize/cull/hzb/shader_hzb_meshlet_filter_1way_full.d.ts.map +1 -1
  462. package/src/shade/renderer/rasterize/cull/hzb/shader_hzb_meshlet_filter_1way_full.js +4 -3
  463. package/src/shade/renderer/rasterize/expand/bucket/RASTERIZATION_BUCKET_LIMIT.d.ts +10 -1
  464. package/src/shade/renderer/rasterize/expand/bucket/RASTERIZATION_BUCKET_LIMIT.d.ts.map +1 -1
  465. package/src/shade/renderer/rasterize/expand/bucket/RASTERIZATION_BUCKET_LIMIT.js +38 -29
  466. package/src/shade/renderer/rasterize/expand/bucket/chunk_rasterization_material_bucket.d.ts +5 -0
  467. package/src/shade/renderer/rasterize/expand/bucket/chunk_rasterization_material_bucket.d.ts.map +1 -1
  468. package/src/shade/renderer/rasterize/expand/bucket/chunk_rasterization_material_bucket.js +63 -55
  469. package/src/shade/renderer/rasterize/expand/bucket/meshlet/graph_sort_meshlets_by_bucket_id.d.ts.map +1 -1
  470. package/src/shade/renderer/rasterize/expand/bucket/meshlet/graph_sort_meshlets_by_bucket_id.js +3 -0
  471. package/src/shade/renderer/rasterize/expand/bucket/meshlet/shader_meshlets_count_by_rasterization_bucket.d.ts.map +1 -1
  472. package/src/shade/renderer/rasterize/expand/bucket/meshlet/shader_meshlets_count_by_rasterization_bucket.js +94 -90
  473. package/src/shade/renderer/rasterize/expand/bucket/meshlet/shader_meshlets_extract_bucket.d.ts.map +1 -1
  474. package/src/shade/renderer/rasterize/expand/bucket/meshlet/shader_meshlets_extract_bucket.js +13 -5
  475. package/src/shade/renderer/rasterize/expand/bucket/meshlet/shader_meshlets_rasterization_bucket_sort.d.ts.map +1 -1
  476. package/src/shade/renderer/rasterize/expand/bucket/meshlet/shader_meshlets_rasterization_bucket_sort.js +96 -89
  477. package/src/shade/renderer/rasterize/expand/graph_meshlets_filter_one_way.d.ts.map +1 -1
  478. package/src/shade/renderer/rasterize/expand/graph_meshlets_filter_one_way.js +3 -1
  479. package/src/shade/renderer/rasterize/expand/graph_meshlets_filter_two_way.d.ts.map +1 -1
  480. package/src/shade/renderer/rasterize/expand/graph_meshlets_filter_two_way.js +4 -1
  481. package/src/shade/renderer/rasterize/expand/graph_meshlets_rasterize.d.ts.map +1 -1
  482. package/src/shade/renderer/rasterize/expand/graph_meshlets_rasterize.js +1 -0
  483. package/src/shade/renderer/rasterize/expand/mesh/shader_mesh_expand_to_meshlets_prefix.d.ts.map +1 -1
  484. package/src/shade/renderer/rasterize/expand/mesh/shader_mesh_expand_to_meshlets_prefix.js +100 -89
  485. package/src/shade/renderer/rasterize/expand/mesh/shader_prefix_sum_to_command.d.ts.map +1 -1
  486. package/src/shade/renderer/rasterize/expand/mesh/shader_prefix_sum_to_command.js +31 -7
  487. package/src/shade/renderer/rasterize/expand/pass0/pass_mesh_cull.d.ts.map +1 -1
  488. package/src/shade/renderer/rasterize/expand/pass0/pass_mesh_cull.js +1 -7
  489. package/src/shade/renderer/rasterize/expand/pass1/filter_meshlets.2-way.compute.d.ts.map +1 -1
  490. package/src/shade/renderer/rasterize/expand/pass1/filter_meshlets.2-way.compute.js +161 -153
  491. package/src/shade/renderer/rasterize/fast/graph_extract_meshes_from_bucket.d.ts.map +1 -1
  492. package/src/shade/renderer/rasterize/fast/graph_extract_meshes_from_bucket.js +2 -7
  493. package/src/shade/renderer/rasterize/fast/graph_rasterize_scene_fast.d.ts.map +1 -1
  494. package/src/shade/renderer/rasterize/fast/graph_rasterize_scene_fast.js +44 -53
  495. package/src/shade/renderer/rasterize/forward/chunk_forward_shade_standard_fragment_brick4.d.ts.map +1 -1
  496. package/src/shade/renderer/rasterize/forward/chunk_forward_shade_standard_fragment_brick4.js +6 -2
  497. package/src/shade/renderer/rasterize/forward/chunk_forward_shade_standard_fragment_ibl.d.ts.map +1 -1
  498. package/src/shade/renderer/rasterize/forward/chunk_forward_shade_standard_fragment_ibl.js +6 -2
  499. package/src/shade/renderer/rasterize/forward/vertex_shader_chunk.d.ts.map +1 -1
  500. package/src/shade/renderer/rasterize/forward/vertex_shader_chunk.js +19 -2
  501. package/src/shade/renderer/rasterize/native/avboit/AVBOIT_PLAN_2026_09_03.md +7 -4
  502. package/src/shade/renderer/rasterize/native/avboit/graph_rasterize_meshes_transparent_avboit.d.ts.map +1 -1
  503. package/src/shade/renderer/rasterize/native/avboit/graph_rasterize_meshes_transparent_avboit.js +3 -2
  504. package/src/shade/renderer/rasterize/native/chunk_rasterize_triangle.d.ts.map +1 -1
  505. package/src/shade/renderer/rasterize/native/chunk_rasterize_triangle.js +15 -4
  506. package/src/shade/renderer/rasterize/native/depth/shadow_rasterization_alpha_tested_pass_descriptor.d.ts.map +1 -1
  507. package/src/shade/renderer/rasterize/native/depth/shadow_rasterization_alpha_tested_pass_descriptor.js +16 -5
  508. package/src/shade/renderer/rasterize/native/depth/shadow_rasterization_pass_descriptor.d.ts.map +1 -1
  509. package/src/shade/renderer/rasterize/native/depth/shadow_rasterization_pass_descriptor.js +16 -5
  510. package/src/shade/renderer/rasterize/native/oit/graph_rasterize_meshes_transparent_oit.d.ts.map +1 -1
  511. package/src/shade/renderer/rasterize/native/oit/graph_rasterize_meshes_transparent_oit.js +2 -1
  512. package/src/shade/renderer/rasterize/native/rasterization_shader_resources.d.ts.map +1 -1
  513. package/src/shade/renderer/rasterize/native/rasterization_shader_resources.js +4 -0
  514. package/src/shade/renderer/rasterize/native/viz/viz_rasterization_alpha_tested_pass_descriptor.d.ts.map +1 -1
  515. package/src/shade/renderer/rasterize/native/viz/viz_rasterization_alpha_tested_pass_descriptor.js +16 -7
  516. package/src/shade/renderer/rasterize/standard/graph_rasterize_partial_opaque.d.ts.map +1 -1
  517. package/src/shade/renderer/rasterize/standard/graph_rasterize_partial_opaque.js +81 -95
  518. package/src/shade/renderer/rasterize/standard/graph_rasterize_remaining_opaque.d.ts.map +1 -1
  519. package/src/shade/renderer/rasterize/standard/graph_rasterize_remaining_opaque.js +26 -39
  520. package/src/shade/renderer/scene/GPUSceneContext.d.ts.map +1 -1
  521. package/src/shade/renderer/scene/GPUSceneContext.js +2 -0
  522. package/src/shade/renderer/scene/NODE3D_STRUCT.d.ts +19 -0
  523. package/src/shade/renderer/scene/NODE3D_STRUCT.d.ts.map +1 -1
  524. package/src/shade/renderer/scene/NODE3D_STRUCT.js +34 -0
  525. package/src/shade/renderer/scene/chunk_node3d_flags.d.ts +9 -0
  526. package/src/shade/renderer/scene/chunk_node3d_flags.d.ts.map +1 -0
  527. package/src/shade/renderer/scene/chunk_node3d_flags.js +23 -0
  528. package/src/shade/renderer/scene/chunk_scene_database_access.d.ts.map +1 -1
  529. package/src/shade/renderer/scene/chunk_scene_database_access.js +15 -1
  530. package/src/shade/renderer/scene/rows/GPUSceneRows.d.ts.map +1 -1
  531. package/src/shade/renderer/scene/rows/GPUSceneRows.js +9 -1
  532. package/src/shade/renderer/shader/chunk/geometry/mat4/chunk_compute_normal_matrix_from_m4.d.ts +7 -0
  533. package/src/shade/renderer/shader/chunk/geometry/mat4/chunk_compute_normal_matrix_from_m4.d.ts.map +1 -1
  534. package/src/shade/renderer/shader/chunk/geometry/mat4/chunk_compute_normal_matrix_from_m4.js +16 -4
  535. package/src/shade/renderer/shader/chunk/geometry/mat4/chunk_mat4_linear_determinant.d.ts +12 -0
  536. package/src/shade/renderer/shader/chunk/geometry/mat4/chunk_mat4_linear_determinant.d.ts.map +1 -0
  537. package/src/shade/renderer/shader/chunk/geometry/mat4/chunk_mat4_linear_determinant.js +18 -0
  538. package/src/shade/renderer/shader/chunk/geometry/triangle/chunk_triangle_list_reverse_winding.d.ts +24 -0
  539. package/src/shade/renderer/shader/chunk/geometry/triangle/chunk_triangle_list_reverse_winding.d.ts.map +1 -0
  540. package/src/shade/renderer/shader/chunk/geometry/triangle/chunk_triangle_list_reverse_winding.js +33 -0
  541. package/src/shade/renderer/shadow/map/DEFAULT_SHADOWMAP_UPDATE_BUDGET.d.ts +25 -0
  542. package/src/shade/renderer/shadow/map/DEFAULT_SHADOWMAP_UPDATE_BUDGET.d.ts.map +1 -0
  543. package/src/shade/renderer/shadow/map/DEFAULT_SHADOWMAP_UPDATE_BUDGET.js +24 -0
  544. package/src/shade/renderer/shadow/map/GPUSceneShadowmapContext.d.ts +10 -0
  545. package/src/shade/renderer/shadow/map/GPUSceneShadowmapContext.d.ts.map +1 -1
  546. package/src/shade/renderer/shadow/map/GPUSceneShadowmapContext.js +30 -21
  547. package/src/core/model/node-graph/visual/layout/LayoutBoxGraph.d.ts.map +0 -1
  548. package/src/core/model/node-graph/visual/layout/layout_assign_coordinates.d.ts.map +0 -1
  549. package/src/core/model/node-graph/visual/layout/layout_assign_layers.d.ts.map +0 -1
  550. package/src/core/model/node-graph/visual/layout/layout_break_cycles.d.ts.map +0 -1
  551. package/src/core/model/node-graph/visual/layout/layout_insert_lanes.d.ts.map +0 -1
  552. package/src/core/model/node-graph/visual/layout/layout_order_layers.d.ts.map +0 -1
  553. package/src/core/model/node-graph/visual/layout/layout_orient_links.d.ts.map +0 -1
  554. package/src/shade/playground/vgeo_viewer/README.md +0 -150
  555. package/src/shade/playground/vgeo_viewer/cut_geometry.d.ts +0 -61
  556. package/src/shade/playground/vgeo_viewer/cut_geometry.d.ts.map +0 -1
  557. package/src/shade/playground/vgeo_viewer/cut_geometry.js +0 -460
  558. package/src/shade/playground/vgeo_viewer/index.html +0 -77
  559. package/src/shade/playground/vgeo_viewer/main.d.ts.map +0 -1
  560. package/src/shade/playground/vgeo_viewer/main.js +0 -1343
  561. package/src/shade/playground/vgeo_viewer/sample_asset.d.ts.map +0 -1
  562. package/src/shade/playground/vgeo_viewer/select_cut.d.ts +0 -173
  563. package/src/shade/playground/vgeo_viewer/select_cut.d.ts.map +0 -1
  564. package/src/shade/playground/vgeo_viewer/select_cut.js +0 -481
  565. package/src/shade/renderer/geometry/virtual/build/VGeoFaceGraph.d.ts.map +0 -1
  566. package/src/shade/renderer/geometry/virtual/build/VGeoGatheredFaces.d.ts +0 -24
  567. package/src/shade/renderer/geometry/virtual/build/VGeoGatheredFaces.d.ts.map +0 -1
  568. package/src/shade/renderer/geometry/virtual/build/VGeoGatheredFaces.js +0 -25
  569. package/src/shade/renderer/geometry/virtual/build/VGeoLevel.d.ts.map +0 -1
  570. package/src/shade/renderer/geometry/virtual/build/VGeoLevelOptions.d.ts.map +0 -1
  571. package/src/shade/renderer/geometry/virtual/build/VGeoLevelSummary.d.ts.map +0 -1
  572. package/src/shade/renderer/geometry/virtual/build/VGeoSubmesh.d.ts +0 -20
  573. package/src/shade/renderer/geometry/virtual/build/VGeoSubmesh.d.ts.map +0 -1
  574. package/src/shade/renderer/geometry/virtual/build/VGeoSubmesh.js +0 -20
  575. package/src/shade/renderer/geometry/virtual/build/VirtualGeometryMesh.d.ts.map +0 -1
  576. package/src/shade/renderer/geometry/virtual/build/vgeo_assemble_pages.d.ts.map +0 -1
  577. package/src/shade/renderer/geometry/virtual/build/vgeo_bounding_sphere.d.ts.map +0 -1
  578. package/src/shade/renderer/geometry/virtual/build/vgeo_build_levels.d.ts +0 -36
  579. package/src/shade/renderer/geometry/virtual/build/vgeo_build_levels.d.ts.map +0 -1
  580. package/src/shade/renderer/geometry/virtual/build/vgeo_build_levels.js +0 -1786
  581. package/src/shade/renderer/geometry/virtual/build/vgeo_build_page_nodes.d.ts.map +0 -1
  582. package/src/shade/renderer/geometry/virtual/build/vgeo_build_root_group.d.ts.map +0 -1
  583. package/src/shade/renderer/geometry/virtual/build/vgeo_compute_vertex_normals.d.ts +0 -29
  584. package/src/shade/renderer/geometry/virtual/build/vgeo_compute_vertex_normals.d.ts.map +0 -1
  585. package/src/shade/renderer/geometry/virtual/build/vgeo_compute_vertex_normals.js +0 -75
  586. package/src/shade/renderer/geometry/virtual/build/vgeo_compute_vertex_tangents.d.ts.map +0 -1
  587. package/src/shade/renderer/geometry/virtual/build/vgeo_compute_vertex_tangents.js +0 -143
  588. package/src/shade/renderer/geometry/virtual/build/vgeo_containing_sphere.d.ts.map +0 -1
  589. package/src/shade/renderer/geometry/virtual/build/vgeo_extract_submesh.d.ts +0 -14
  590. package/src/shade/renderer/geometry/virtual/build/vgeo_extract_submesh.d.ts.map +0 -1
  591. package/src/shade/renderer/geometry/virtual/build/vgeo_extract_submesh.js +0 -41
  592. package/src/shade/renderer/geometry/virtual/build/vgeo_gather_faces.d.ts +0 -12
  593. package/src/shade/renderer/geometry/virtual/build/vgeo_gather_faces.d.ts.map +0 -1
  594. package/src/shade/renderer/geometry/virtual/build/vgeo_gather_faces.js +0 -71
  595. package/src/shade/renderer/geometry/virtual/build/vgeo_graph_components.d.ts.map +0 -1
  596. package/src/shade/renderer/geometry/virtual/build/vgeo_narrow_indices.d.ts.map +0 -1
  597. package/src/shade/renderer/geometry/virtual/build/vgeo_normalize_source.d.ts.map +0 -1
  598. package/src/shade/renderer/geometry/virtual/build/vgeo_page_node_count.d.ts.map +0 -1
  599. package/src/shade/renderer/geometry/virtual/build/vgeo_partition_graph.d.ts.map +0 -1
  600. package/src/shade/renderer/geometry/virtual/build/vgeo_sphere_inflate_to_contain.d.ts.map +0 -1
  601. package/src/shade/renderer/geometry/virtual/build/vgeo_split_face_set.d.ts.map +0 -1
  602. package/src/shade/renderer/geometry/virtual/build/vgeo_split_face_set_packed.d.ts.map +0 -1
  603. package/src/shade/renderer/geometry/virtual/build/vgeo_split_face_set_packed.js +0 -207
  604. package/src/shade/renderer/geometry/virtual/format/attribute/vgeo_layers_copy_vertex.d.ts +0 -16
  605. package/src/shade/renderer/geometry/virtual/format/attribute/vgeo_layers_copy_vertex.d.ts.map +0 -1
  606. package/src/shade/renderer/geometry/virtual/residency/VGeoResidencyManager.d.ts +0 -258
  607. package/src/shade/renderer/geometry/virtual/residency/VGeoResidencyManager.d.ts.map +0 -1
  608. package/src/shade/renderer/geometry/virtual/residency/VGeoResidencyOptions.d.ts +0 -49
  609. package/src/shade/renderer/geometry/virtual/residency/VGeoResidencyOptions.d.ts.map +0 -1
  610. package/src/shade/renderer/loader/gltf/fix_up_material_sides.d.ts +0 -10
  611. package/src/shade/renderer/loader/gltf/fix_up_material_sides.d.ts.map +0 -1
  612. package/src/shade/renderer/loader/gltf/fix_up_material_sides.js +0 -109
  613. package/src/shade/renderer/rasterize/expand/graph_triangles_filter_by_material_side.d.ts +0 -17
  614. package/src/shade/renderer/rasterize/expand/graph_triangles_filter_by_material_side.d.ts.map +0 -1
  615. package/src/shade/renderer/rasterize/expand/graph_triangles_filter_by_material_side.js +0 -78
  616. package/src/shade/renderer/rasterize/expand/shader_filter_triangle_by_material_side.d.ts +0 -3
  617. package/src/shade/renderer/rasterize/expand/shader_filter_triangle_by_material_side.d.ts.map +0 -1
  618. package/src/shade/renderer/rasterize/expand/shader_filter_triangle_by_material_side.js +0 -100
  619. package/src/shade/renderer/rasterize/forward/chunk_material_side_should_draw.d.ts +0 -8
  620. package/src/shade/renderer/rasterize/forward/chunk_material_side_should_draw.d.ts.map +0 -1
  621. package/src/shade/renderer/rasterize/forward/chunk_material_side_should_draw.js +0 -26
  622. package/src/shade/renderer/shader/chunk/jobs/chunk_job_system.d.ts +0 -3
  623. package/src/shade/renderer/shader/chunk/jobs/chunk_job_system.d.ts.map +0 -1
  624. /package/src/core/{model/node-graph/visual/layout → graph/layout/layered}/layout_assign_coordinates.d.ts +0 -0
  625. /package/src/core/{model/node-graph/visual/layout → graph/layout/layered}/layout_assign_layers.d.ts +0 -0
  626. /package/src/core/{model/node-graph/visual/layout → graph/layout/layered}/layout_break_cycles.d.ts +0 -0
  627. /package/src/core/{model/node-graph/visual/layout → graph/layout/layered}/layout_break_cycles.js +0 -0
  628. /package/src/core/{model/node-graph/visual/layout → graph/layout/layered}/layout_insert_lanes.d.ts +0 -0
  629. /package/src/core/{model/node-graph/visual/layout → graph/layout/layered}/layout_insert_lanes.js +0 -0
  630. /package/src/core/{model/node-graph/visual/layout → graph/layout/layered}/layout_order_layers.d.ts +0 -0
  631. /package/src/core/{model/node-graph/visual/layout → graph/layout/layered}/layout_order_layers.js +0 -0
  632. /package/src/core/{model/node-graph/visual/layout → graph/layout/layered}/layout_orient_links.d.ts +0 -0
  633. /package/src/core/{model/node-graph/visual/layout → graph/layout/layered}/layout_orient_links.js +0 -0
  634. /package/src/shade/playground/{vgeo_viewer → caldera}/main.d.ts +0 -0
  635. /package/src/shade/renderer/geometry/virtual/build/{VGeoLevel.d.ts → level/VGeoLevel.d.ts} +0 -0
  636. /package/src/shade/renderer/geometry/virtual/build/{VGeoLevel.js → level/VGeoLevel.js} +0 -0
  637. /package/src/shade/renderer/geometry/virtual/build/{VGeoLevelSummary.d.ts → level/VGeoLevelSummary.d.ts} +0 -0
  638. /package/src/shade/renderer/geometry/virtual/build/{VGeoLevelSummary.js → level/VGeoLevelSummary.js} +0 -0
  639. /package/src/shade/renderer/geometry/virtual/build/{vgeo_page_node_count.d.ts → page/vgeo_page_node_count.d.ts} +0 -0
  640. /package/src/shade/renderer/geometry/virtual/build/{vgeo_graph_components.d.ts → partition/vgeo_graph_components.d.ts} +0 -0
  641. /package/src/shade/renderer/geometry/virtual/build/{vgeo_graph_components.js → partition/vgeo_graph_components.js} +0 -0
  642. /package/src/shade/renderer/geometry/virtual/build/{vgeo_partition_graph.d.ts → partition/vgeo_partition_graph.d.ts} +0 -0
  643. /package/src/shade/renderer/geometry/virtual/build/{vgeo_split_face_set.d.ts → partition/vgeo_split_face_set.d.ts} +0 -0
  644. /package/src/shade/renderer/geometry/virtual/build/{vgeo_split_face_set_packed.d.ts → partition/vgeo_split_face_set_packed.d.ts} +0 -0
  645. /package/src/shade/renderer/geometry/virtual/build/{vgeo_bounding_sphere.d.ts → sphere/vgeo_bounding_sphere.d.ts} +0 -0
  646. /package/src/shade/renderer/geometry/virtual/build/{vgeo_containing_sphere.d.ts → sphere/vgeo_containing_sphere.d.ts} +0 -0
  647. /package/src/shade/renderer/geometry/virtual/build/{vgeo_sphere_inflate_to_contain.d.ts → sphere/vgeo_sphere_inflate_to_contain.d.ts} +0 -0
  648. /package/src/shade/renderer/geometry/virtual/build/{vgeo_narrow_indices.d.ts → submesh/vgeo_narrow_indices.d.ts} +0 -0
@@ -4,9 +4,9 @@
4
4
  * @param {VirtualGeometryPage[]} pages in file order, root first; every group's `page` must point
5
5
  * back at the page holding it
6
6
  * @param {VGeoWriteOptions} options
7
- * @returns {BinaryBuffer} the whole file; its capacity is exactly the file's length, so
7
+ * @returns {Promise<BinaryBuffer>} the whole file; its capacity is exactly the file's length, so
8
8
  * `raw_bytes` is the file
9
9
  */
10
- export function vgeo_write_container(pages: VirtualGeometryPage[], options: VGeoWriteOptions): BinaryBuffer;
10
+ export function vgeo_write_container(pages: VirtualGeometryPage[], options: VGeoWriteOptions): Promise<BinaryBuffer>;
11
11
  import { BinaryBuffer } from "../../../../../core/binary/BinaryBuffer.js";
12
12
  //# sourceMappingURL=vgeo_write_container.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"vgeo_write_container.d.ts","sourceRoot":"","sources":["../../../../../../../src/shade/renderer/geometry/virtual/format/vgeo_write_container.js"],"names":[],"mappings":"AA4bA;;;;;;;;GAQG;AACH,4CANW,qBAAqB,8BAGnB,YAAY,CAmNxB;6BAppB4B,4CAA4C"}
1
+ {"version":3,"file":"vgeo_write_container.d.ts","sourceRoot":"","sources":["../../../../../../../src/shade/renderer/geometry/virtual/format/vgeo_write_container.js"],"names":[],"mappings":"AAkdA;;;;;;;;GAQG;AACH,4CANW,qBAAqB,8BAGnB,QAAQ,YAAY,CAAC,CAmOjC;6BA1rB4B,4CAA4C"}
@@ -17,6 +17,7 @@ import { VGEO_FORMAT_VERSION } from "./header/VGEO_FORMAT_VERSION.js";
17
17
  import { VGEO_FRAME_ALIGNMENT } from "./frame/VGEO_FRAME_ALIGNMENT.js";
18
18
  import { VGEO_FRAME_HEADER_SIZE } from "./frame/VGEO_FRAME_HEADER_SIZE.js";
19
19
  import { VGEO_FRAME_OFFSET } from "./frame/VGEO_FRAME_OFFSET.js";
20
+ import { VGEO_GROUP_OFFSET } from "./page/VGEO_GROUP_OFFSET.js";
20
21
  import { VGEO_GROUP_RECORD_SIZE } from "./page/VGEO_GROUP_RECORD_SIZE.js";
21
22
  import { VGEO_HASH_ALGO_XXH3 } from "./header/VGEO_HASH_ALGO_XXH3.js";
22
23
  import { VGEO_HEADER_OFFSET } from "./header/VGEO_HEADER_OFFSET.js";
@@ -24,6 +25,7 @@ import { VGEO_HEADER_SIZE } from "./header/VGEO_HEADER_SIZE.js";
24
25
  import { VGEO_LEVEL_RECORD_SIZE } from "./header/VGEO_LEVEL_RECORD_SIZE.js";
25
26
  import { VGEO_MAGIC } from "./header/VGEO_MAGIC.js";
26
27
  import { VGEO_MAX_CHILD_REF } from "./cluster/VGEO_MAX_CHILD_REF.js";
28
+ import { VGEO_MAX_LEVEL_COUNT } from "./header/VGEO_MAX_LEVEL_COUNT.js";
27
29
  import { VGEO_MAX_PARENT_ENTRY_COUNT } from "./page/VGEO_MAX_PARENT_ENTRY_COUNT.js";
28
30
  import { VGEO_MAX_PARENT_REF } from "./page/VGEO_MAX_PARENT_REF.js";
29
31
  import { VGEO_MIN_READER_VERSION } from "./header/VGEO_MIN_READER_VERSION.js";
@@ -240,15 +242,21 @@ function build_page_blob(page, child_pages, parents) {
240
242
  'page parent-page table must stay within what parent_ref can index'
241
243
  );
242
244
 
245
+ /*
246
+ Derived here and derived again by the reader, rather than written down: from `format_version`
247
+ 6 the page header has no field for it, and the four bytes it used to occupy carry `node_count`
248
+ and the widened band instead. Nothing is lost by the move — the group table follows the header
249
+ and the node table follows the group table, so this was never free to be anything else.
250
+ */
243
251
  const node_table_offset = VGEO_PAGE_HEADER_SIZE + page.groups.length * VGEO_GROUP_RECORD_SIZE;
244
252
  const cluster_table_offset = node_table_offset + page.nodes.length * VGEO_NODE_RECORD_SIZE;
245
253
 
246
254
  /*
247
255
  The parent section sits between the cluster records and the payload rather than beside the
248
- group table, which keeps `node_table_offset`'s "= 56 + 8·group_count" true and leaves every
249
- offset a reader before format 4 computed exactly where it was. Both tables hold 4-byte entries
250
- and the sections above them are all multiples of four, so the payload stays word-aligned —
251
- format §11.8's promise, which the meshlet batch divides by four without rounding.
256
+ group table, which keeps the node table's "= 56 + 8·group_count" true and leaves every offset a
257
+ reader before format 4 computed exactly where it was. Both tables hold 4-byte entries and the
258
+ sections above them are all multiples of four, so the payload stays word-aligned — format
259
+ §11.8's promise, which the meshlet batch divides by four without rounding.
252
260
  */
253
261
  const parent_table_offset = cluster_table_offset + clusters.length * VGEO_CLUSTER_RECORD_SIZE;
254
262
 
@@ -272,13 +280,16 @@ function build_page_blob(page, child_pages, parents) {
272
280
 
273
281
  buffer.writeUint16(page.groups.length);
274
282
  buffer.writeUint16(clusters.length);
275
- buffer.writeUint8(page.min_level);
276
- buffer.writeUint8(page.max_level);
277
- buffer.writeUint16(page.nodes.length);
283
+ buffer.writeUint16(page.min_level);
284
+ buffer.writeUint16(page.max_level);
278
285
  buffer.writeUint32(cluster_table_offset);
279
286
  buffer.writeUint32(payload_offset);
280
287
  buffer.writeUint32(payload_size);
281
- buffer.writeUint32(node_table_offset);
288
+ buffer.writeUint16(page.nodes.length);
289
+
290
+ // The two bytes version 6 did not need out of `node_table_offset`, and §11 requires them zero.
291
+ buffer.writeUint16(0);
292
+
282
293
  buffer.writeUint32(parent_table_offset);
283
294
  buffer.writeUint16(parent_entry_count);
284
295
  buffer.writeUint16(parent_pages.length);
@@ -355,11 +366,18 @@ function build_page_blob(page, child_pages, parents) {
355
366
  buffer.writeUint16(parent.cluster);
356
367
  });
357
368
 
358
- buffer.position = VGEO_PAGE_HEADER_SIZE + group_index * VGEO_GROUP_RECORD_SIZE;
369
+ const group_record = VGEO_PAGE_HEADER_SIZE + group_index * VGEO_GROUP_RECORD_SIZE;
359
370
 
371
+ buffer.position = group_record + VGEO_GROUP_OFFSET.CLUSTER_FIRST;
360
372
  buffer.writeUint16(cluster_index);
373
+
374
+ buffer.position = group_record + VGEO_GROUP_OFFSET.CLUSTER_COUNT;
361
375
  buffer.writeUint16(group.clusters.length);
376
+
377
+ buffer.position = group_record + VGEO_GROUP_OFFSET.PARENT_CLUSTER_COUNT;
362
378
  buffer.writeUint16(group.parent_cluster_count);
379
+
380
+ buffer.position = group_record + VGEO_GROUP_OFFSET.PARENT_FIRST;
363
381
  buffer.writeUint16(parent_first);
364
382
 
365
383
  parent_first += group_parents.length;
@@ -372,7 +390,14 @@ function build_page_blob(page, child_pages, parents) {
372
390
  buffer.writeFloat32(cluster.self_error);
373
391
  buffer.writeFloat32(cluster.parent_error);
374
392
  buffer.writeFloat32Array(cluster.parent_sphere, 0, 4);
375
- buffer.writeFloat32Array(cluster.bounds_sphere, 0, 4);
393
+
394
+ /*
395
+ Where `bounds_sphere` and `cone_reserved` were before `format_version` 5: the cut culls
396
+ a cluster and its whole subtree on this box, and the sphere it replaced was read by
397
+ nothing at runtime. The record is the same 112 bytes.
398
+ */
399
+ buffer.writeFloat32Array(cluster.subtree_aabb, 0, 6);
400
+
376
401
  buffer.writeFloat32Array(cluster.aabb, 0, 6);
377
402
 
378
403
  if (cluster.child_group === undefined) {
@@ -383,9 +408,6 @@ function build_page_blob(page, child_pages, parents) {
383
408
  buffer.writeUint16(cluster.child_group.index_in_page);
384
409
  }
385
410
 
386
- // cone_reserved
387
- buffer.writeUint32(0);
388
-
389
411
  buffer.writeUint32(cluster.encoding_flags);
390
412
  buffer.writeUint32(cursor);
391
413
  buffer.writeUint32(cluster.payload.byteLength);
@@ -448,10 +470,10 @@ function page_size_guarantee(blobs, nominal_page_size) {
448
470
  * @param {VirtualGeometryPage[]} pages in file order, root first; every group's `page` must point
449
471
  * back at the page holding it
450
472
  * @param {VGeoWriteOptions} options
451
- * @returns {BinaryBuffer} the whole file; its capacity is exactly the file's length, so
473
+ * @returns {Promise<BinaryBuffer>} the whole file; its capacity is exactly the file's length, so
452
474
  * `raw_bytes` is the file
453
475
  */
454
- export function vgeo_write_container(pages, options) {
476
+ export async function vgeo_write_container(pages, options) {
455
477
  assert.isArray(pages, 'pages');
456
478
  assert.greaterThan(pages.length, 0, 'pages.length');
457
479
 
@@ -459,9 +481,25 @@ export function vgeo_write_container(pages, options) {
459
481
  assert.equal(page.index, index, `page ${index} carries index ${page.index}`);
460
482
  });
461
483
 
484
+ assert.lessThanOrEqual(
485
+ options.levels.length, VGEO_MAX_LEVEL_COUNT,
486
+ 'level_count must stay within what the header and the page bands can name (format §4)'
487
+ );
488
+
462
489
  const parents = resolve_group_references(pages);
463
490
 
464
- const blobs = pages.map((page) => {
491
+ /**
492
+ * @type {PageBlob[]}
493
+ */
494
+ const blobs = [];
495
+
496
+ /*
497
+ One page at a time rather than a `Promise.all` over the list. Under a stream codec that would
498
+ be one live `CompressionStream` per page of the container — thousands of zlib instances for a
499
+ conversion that is builder-bound anyway — and under the synchronous codecs it would be the
500
+ same loop with a promise around each step.
501
+ */
502
+ for (const page of pages) {
465
503
  const blob = new PageBlob();
466
504
 
467
505
  blob.child_pages = collect_child_pages(page);
@@ -471,7 +509,7 @@ export function vgeo_write_container(pages, options) {
471
509
  // Compression happens here, before a single offset is known, and that is what keeps the
472
510
  // layout non-circular: a frame's extent follows from its *stored* size and its child count,
473
511
  // and neither depends on any offset value, because the child table is plaintext.
474
- const encoded = vgeo_encode_frame_blob(decoded, options.codec, options.codec_level);
512
+ const encoded = await vgeo_encode_frame_blob(decoded, options.codec, options.codec_level);
475
513
 
476
514
  blob.codec = encoded.codec;
477
515
  blob.stored = encoded.bytes;
@@ -483,8 +521,8 @@ export function vgeo_write_container(pages, options) {
483
521
 
484
522
  blob.fetch_size = round_up(blob.extent, VGEO_FRAME_ALIGNMENT);
485
523
 
486
- return blob;
487
- });
524
+ blobs.push(blob);
525
+ }
488
526
 
489
527
  const feature_flags_ignorable = page_size_guarantee(blobs, options.nominal_page_size);
490
528
 
@@ -548,7 +586,7 @@ export function vgeo_write_container(pages, options) {
548
586
  buffer.writeUint32(options.nominal_page_size);
549
587
 
550
588
  buffer.position = VGEO_HEADER_OFFSET.LEVEL_COUNT;
551
- buffer.writeUint8(options.levels.length);
589
+ buffer.writeUint16(options.levels.length);
552
590
 
553
591
  buffer.position = VGEO_HEADER_OFFSET.SOURCE_VERTEX_COUNT;
554
592
  buffer.writeUint64(BigInt(options.source_vertex_count));
@@ -617,8 +655,8 @@ export function vgeo_write_container(pages, options) {
617
655
  buffer.writeUint64(BigInt(blob.frame_offset));
618
656
  buffer.writeUint32(blob.fetch_size);
619
657
  buffer.writeUint32(blob.decoded_size);
620
- buffer.writeUint8(pages[page_index].min_level);
621
- buffer.writeUint8(pages[page_index].max_level);
658
+ buffer.writeUint16(pages[page_index].min_level);
659
+ buffer.writeUint16(pages[page_index].max_level);
622
660
  buffer.writeUint16(page_index === 0 ? VGEO_DIRECTORY_FLAG_ROOT_PAGE : 0);
623
661
  buffer.writeUint16(pages[page_index].groups.length);
624
662
  buffer.writeUint16(page_cluster_count);
@@ -0,0 +1,385 @@
1
+ # Virtual Geometry cut — the per-cluster frustum test, measured and tightened
2
+
3
+ **2026-09-16.** Follows `RUNTIME_PLAN_2026_09_14.md` §2.1 and §7, which left `pages visited` at half
4
+ to three quarters of the resident tier when zoomed in and named the LOD sphere's looseness as the
5
+ cause. This document measures that claim before acting on it, and the measurement changes what is
6
+ worth building. Everything measured here was measured on the real asset in node
7
+ (`measure_spheres*.mjs`, `measure3_breakdown.mjs`, `measure4_extents.mjs`, `measure5_reach.mjs`,
8
+ `measure6_error_bound.mjs`, `measure7_containment.mjs`, `measure8_lod_vertices.mjs` of the
9
+ building session).
10
+
11
+ ## 0. What the symptom is made of
12
+
13
+ The container is the Zorah rosette panel, mesh 2023 primitive 0, as rebuilt on 2026-09-14
14
+ (`5d4baf9e9ab4a0ea2bb6b3bcf48829f2.vgeo`, `format_version` 4, 942 MB): 17,213 pages, 590,858
15
+ clusters, 160,441 groups, 34.3 clusters a page. Its DAG is 42 levels deep counted as the longest
16
+ chain from a cluster down to a leaf, with 277,659 leaves. The tour of §7 saw, zoomed in at rest,
17
+ 3,220 pages visited of 4,096 resident against 4,060 clusters drawn.
18
+
19
+ A CPU cut over the whole container — every page resident, camera on the panel's normal at the
20
+ tour's poses, 50° fov, 1258×646, τ = 1 — reproduces that: 3,091 pages visited at rest with the
21
+ cluster test on the LOD sphere, 4,537 with no frustum test at all. Where those pages are is the
22
+ finding. At rest, of the 3,091:
23
+
24
+ | | pages | of which drew a cluster | transit only |
25
+ |---|---:|---:|---:|
26
+ | levels 0–3 (the surface on screen and one step above) | 1,326 | 661 | 665 |
27
+ | levels 4–19 | 1,665 | 7 | 1,658 |
28
+ | levels 20–41 | 100 | 0 | 100 |
29
+
30
+ A page is placed at the lowest level of any cluster it holds; 8,166 pages hold more than one level.
31
+ Levels 4 and up hold 1,836 pages of the file. **1,765 of them are entered at rest with the LOD
32
+ sphere and 1,650 with the exact subtree box** (levels 4–9: 415/466, 319/333, 247/251, 165/167,
33
+ 121/121, 80/80 visited with the sphere; 353, 293, 229, 160, 120, 78 with the box). Seven of them draw
34
+ anything. They are the way down.
35
+
36
+ ## 1. Why the coarse pages cannot be culled, by any bound
37
+
38
+ The cluster test decides whether a cluster refines into its child group. Culling it has to be
39
+ conservative for **everything reachable below it**, because the child group is reached through it
40
+ and a parent culled with an on-screen descendant is a hole. What is reachable below a cluster is
41
+ not "the geometry this cluster approximates". Every simplification step consumes one group and
42
+ produces two or more parents; every parent's `child_group` is the **whole** consumed group, so a
43
+ parent's subtree carries its sibling's half of the surface too, and each child's subtree carries
44
+ *its* sibling's, and so on down. The region below a cluster doubles per level. Measured, as the
45
+ median diagonal of the exact subtree AABB against the object's diagonal, with the cluster's own AABB
46
+ beside it:
47
+
48
+ | level | clusters | own AABB diagonal | subtree AABB diagonal |
49
+ |---:|---:|---:|---:|
50
+ | 0 | 277,659 | 0.3% | 0.3% |
51
+ | 4 | 18,783 | 0.7% | 1.1% |
52
+ | 7 | 5,405 | 1.1% | 9.2% |
53
+ | 10 | 2,919 | 1.2% | 23% |
54
+ | 14 | 1,531 | 1.6% | 43% |
55
+ | 20 | 948 | 1.9% | 64% |
56
+ | 28 | 574 | 3.5% | 97% |
57
+
58
+ A zoomed view covers one to two percent of the panel. From level 7 up the median cluster's subtree
59
+ is bigger than the view, and from level 12 up it is a third of the object. No sphere and no box
60
+ around that region is outside any zoomed frustum, and the coarse pages get visited because they
61
+ hold clusters like that. The LOD sphere's looseness is real — below — but it is not what fills the
62
+ tier.
63
+
64
+ **The DAG's shape makes it worse than it need be.** Below level 4 each level halves the cluster
65
+ count; above it the ratio decays to 0.6, 0.8 and by level 10 about 0.9 a level, so 58,000 clusters
66
+ and 1,800 pages sit in a long thin tail above the surface anyone draws. That tail is the transit set.
67
+ Pages also mix levels — 8,166 of 17,213 span more than one — so a coarse page's groups are
68
+ spatially wherever the assembler found room.
69
+
70
+ ## 2. What was measured, against the four questions asked
71
+
72
+ ### 2.1 Where a subtree sphere could come from, and how tight it gets
73
+
74
+ Install-derived is out by construction, not by measurement: `self_sphere` **is** a subtree bound.
75
+ The builder's step sphere contains the consumed clusters' own step spheres and the produced
76
+ clusters' vertices, so by induction it contains every vertex under it; a sample of 1,160 clusters
77
+ across levels 0–28 found no subtree vertex outside its `self_sphere` (worst excess −3·10⁻⁹ of the
78
+ radius, a leaf touching its own miniball). Nothing else a page carries is tighter for the subtree:
79
+ node spheres and child-table metrics are unions of these same spheres.
80
+
81
+ So the question is how much tighter a builder-computed bound is. Volume of the candidate over the
82
+ volume of the LOD sphere, medians per level:
83
+
84
+ | level | exact subtree AABB, as a box | its circumsphere | miniball over children's subtree boxes | miniball over every subtree AABB corner | miniball over every subtree vertex |
85
+ |---:|---:|---:|---:|---:|---:|
86
+ | 0 | — | 1.39 | 1.39 | 1.47 | 1.00 |
87
+ | 2 | — | 0.82 | 0.79 | 0.70 | 0.49 |
88
+ | 4 | — | 0.51 | 0.49 | 0.52 | 0.30 |
89
+ | 8 | — | 0.31 | 0.30 | 0.28 | 0.22 |
90
+ | 12 | — | 0.22 | 0.22 | 0.15 | 0.17 |
91
+ | 16 | — | 0.18 | 0.18 | 0.15 | 0.14 |
92
+ | 20 | — | 0.12 | 0.12 | 0.10 | — |
93
+
94
+ The last two columns are medians over samples of 300 and 40 clusters a level drawn with different
95
+ seeds, which is why the vertex miniball can read larger than the corner miniball at one level; the
96
+ first three are exhaustive. The LOD sphere compounds: 1.5× the exact volume at level 1, 3–5× from
97
+ level 4, 7× at level 20. A tight sphere is 0.55–0.6 of its radius at the levels that matter. The composable
98
+ children's-boxes miniball is within 5–15% of the exhaustive reference at every level and is O(N)
99
+ to build; the exact vertex miniball is the tightest and costs O(N·depth) points through a miniball,
100
+ which on this container is ten billion points.
101
+
102
+ ### 2.2 What the tighter bound buys the cut
103
+
104
+ Pages visited by the CPU cut, full residency, the tour's poses. `none` has the frustum test off
105
+ entirely; `lod` is today's kernel; the exact AABB is tested as a box (p-vertex against each plane):
106
+
107
+ | pose | none | LOD sphere | subtree-box circumsphere | children's-boxes miniball | exact subtree AABB |
108
+ |---|---:|---:|---:|---:|---:|
109
+ | rest (0.12 r) | 4,537 | 3,091 | 2,924 | 2,916 | **2,521** |
110
+ | stop 0 | 4,583 | 3,051 | 2,856 | 2,847 | 2,478 |
111
+ | stop 3 | 4,204 | 2,495 | 2,185 | 2,179 | **1,639** |
112
+ | stop 4 | 4,261 | 2,599 | 2,190 | 2,183 | **1,649** |
113
+ | stop 5 | 3,609 | 1,748 | 1,312 | 1,306 | **1,052** |
114
+ | stop 7 | 4,000 | 2,245 | 1,890 | 1,887 | 1,452 |
115
+ | framing (2.8 r) | 1,441 | 1,441 | 1,441 | 1,441 | 1,441 |
116
+
117
+ A tight **sphere** takes 5–6% off at rest and up to 25% at a stop. The exact **box** takes 18% off at
118
+ rest and 35–40% at stops 3, 4 and 5, and draws fewer clusters too (2,115 against 2,734 at rest: those
119
+ were on-screen by the sphere and off-screen in fact). The CPU cut's camera is not the tour's — its
120
+ orientation is the panel's normal and the tour's is the orbit controller's, and it drew 2,734 where the
121
+ tour drew 4,060 — so the tables compare candidates against each other, and §5's tour is what compares
122
+ before with after. The box wins because a subtree here is a flat
123
+ patch of a flat panel — its AABB is thin along the normal and its circumsphere is not.
124
+
125
+ ### 2.3 The one test that would have hit the target, and why it is not sound
126
+
127
+ A cluster's **own** bounds inflated by the error accumulated down its chain — `reach(P) =
128
+ P.self_error + max over the child group of reach(c)`, leaves 0 — is the Nanite-shaped argument: an
129
+ on-screen point of the fine surface is within the step's error of some parent's surface, so some
130
+ chain of parents each passing that test exists. It visits 1,444 pages at rest and 358–1,300 at the
131
+ stops, the two-to-fourfold cut the task hoped for. And it leaves **14 to 37 in-frustum clusters of
132
+ the open cut undrawn at every pose**, some with their box six diagonals inside the frustum — holes
133
+ in the middle of the screen, not slivers at its edge. Scaling the reach by 6 still leaves 10–20.
134
+
135
+ The reason is measurable and is a finding on its own: **the stored error is not a distance bound.**
136
+ Per step, the farthest any consumed vertex lies from the produced parents' triangles, over the step's
137
+ `self_error`:
138
+
139
+ | group level | steps sampled | ratio median | p90 | max | steps over 1 |
140
+ |---:|---:|---:|---:|---:|---:|
141
+ | 0 | 60 | 1.30 | 2.50 | 4.9 | 97% |
142
+ | 3 | 60 | 1.29 | 2.07 | 5.6 | 75% |
143
+ | 5 | 60 | 1.08 | 2.79 | 1,696 | 55% |
144
+ | 10 | 60 | 0.77 | 2.39 | 10.5 | 33% |
145
+ | 20 | 60 | 0.51 | 4.20 | 35.0 | 27% |
146
+ | 32 | 46 | 5.60 | 16.8 | 33.0 | 85% |
147
+
148
+ `self_error` is the quadric's conformance to the source, normalised by its weight (`vgeo_build_levels`
149
+ §"Error is conformance to the source") — a plane-distance statistic, which is the right thing for a
150
+ screen-space LOD threshold and the wrong thing to build a cull on. A cull that is right for most
151
+ steps is a hole for the rest. Rejected; the number is recorded so nobody measures it again.
152
+
153
+ ### 2.4 Row cost and slot fit
154
+
155
+ The exact subtree AABB is six words a cluster row: 13 → 19. `SELF_SPHERE` stays — the projection
156
+ reads it — and the existing sphere test stays in front of the box test (§3.4). On this container the
157
+ widest page is 52 clusters, 5 nodes, 15 groups, 25 parent entries: 851 words today, 1,163 at 19 words,
158
+ 56.8% of the 2,048-word slot a 64 KB page gets. `slot_words_for` and the install refusal are
159
+ unchanged in form. At the million resident clusters design §4 targets the arena is 76 MB rather than
160
+ 52.
161
+
162
+ ## 3. What is built
163
+
164
+ ### 3.1 Format — `subtree_aabb` in the cluster record, as `format_version` 5
165
+
166
+ The record stays 112 bytes. `bounds_sphere` goes: nothing at runtime read it (the row's doc said
167
+ so), the AABB already serves the meshlet metadata and every downstream cull, and its 16 bytes plus
168
+ `cone_reserved`'s 4 and the 6 that shift down make room for a 24-byte box in one place. Everything
169
+ from offset 40 moves, so `min_reader_version` moves to 5 with it — a version-4 reader would read a
170
+ version-5 record's `child_ref` out of its box.
171
+
172
+ | offset | type | field | |
173
+ |---:|---|---|---|
174
+ | 0 | [f32; 4] | self_sphere | unchanged |
175
+ | 16 | f32 | self_error | unchanged |
176
+ | 20 | f32 | parent_error | unchanged |
177
+ | 24 | [f32; 4] | parent_sphere | unchanged |
178
+ | 40 | [f32; 6] | **subtree_aabb** | object-space AABB of this cluster's vertices and of every cluster reachable below it through child groups; leaves: equals `aabb` |
179
+ | 64 | [f32; 6] | aabb | was 56 |
180
+ | 88 | u16 | child_ref | was 80 |
181
+ | 90 | u16 | child_group | was 82 |
182
+ | 92 | u32 | encoding_flags | was 88; `cone_reserved` (was 84) is gone |
183
+ | 96 | u32 | payload_offset | was 92 |
184
+ | 100 | u32 | payload_size | was 96 |
185
+ | 104 | u8 | vertex_count | was 100 |
186
+ | 105 | u8 | triangle_count | was 101 |
187
+ | 106 | [u8; 6] | reserved | was ten bytes at 102; the validator's zero check follows |
188
+
189
+ The writer and the validator read and write the record **positionally** (`vgeo_write_container` after
190
+ `SELF_SPHERE`, `read_clusters` in the validator), so both are re-sequenced, not just the offset table.
191
+ `VirtualGeometryCluster.bounds_sphere` stays as a **builder-only** field — the object sphere, the
192
+ group centroids and the leaf `self_sphere` are built from it — and its doc says it is no longer
193
+ written. `VIRTUAL_GEOMETRY_DESIGN.md` and `VIRTUAL_GEOMETRY_PLAN.md` mention `cone_reserved` as a
194
+ zeroed column and are corrected.
195
+
196
+ **Build invariant §11.17.** `subtree_aabb` contains the cluster's `aabb` and, for every cluster of its
197
+ child group, that cluster's `subtree_aabb`. Exact on stored values, no tolerance: the builder computes
198
+ the union of float32 extremes, which is exactly representable. By induction it contains every vertex
199
+ below the cluster, which is the whole of what the cull needs, and it needs no sphere nesting — the
200
+ containment that made §7's LOD pair compound is not asked of it.
201
+
202
+ **§11.7 gains what dropping `bounds_sphere` would have lost.** The validator checked
203
+ `bounds_sphere ∋ vertices` and never `self_sphere ∋ vertices`; the latter is what the sphere test and
204
+ the version-4 cube in §3.4 rest on, and it was only ever true by construction (`vgeo_build_levels`
205
+ sets a leaf's `self_sphere` to its miniball and inflates every step sphere to contain the produced
206
+ vertices). It is now stated in §11.7 and checked per cluster against the payload.
207
+
208
+ **Builder.** A memoised walk over `child_group` after `vgeo_build_levels`: a leaf's box is its `aabb`;
209
+ a parent's is its `aabb` unioned with each child-group member's `subtree_aabb`. Not a pass by level:
210
+ a round leaves unmerged clusters in the frontier, so a group formed at round L holds members created
211
+ at any lower level, and `group.level` says where the group was formed, not where its members were.
212
+ The walk is O(N) either way.
213
+
214
+ **Reader.** `VGeoPage.subtree_aabb` (`6 · cluster_count`) replaces `bounds_sphere`. The page decoder
215
+ is handed the container's `format_version` — through `VGeoPageFetcherCore`, whose three construction
216
+ sites (reader, in-process fetcher, worker) all have the header — and reads a version-4 record by the
217
+ old offsets, synthesising `subtree_aabb` as the cube around `self_sphere`: a conservative subtree
218
+ bound, so a container nobody has rebuilt still culls correctly. §3.4 says why it also culls no worse.
219
+ The validator accepts only the current version, as it always has.
220
+
221
+ ### 3.2 Runtime — `CULL_BOX` in the row, tested after the sphere and after the election
222
+
223
+ `VGEO_CLUSTER_ROW_OFFSET.CULL_BOX = 13`, six words, `VGEO_CLUSTER_ROW_WORDS = 19`;
224
+ `vgeo_runtime_write_page_block` copies `page.subtree_aabb`. `vg_visit_cluster` keeps its
225
+ `SELF_SPHERE` test and adds `vg_box_outside_frustum` on the row's box: a p-vertex per plane, five
226
+ planes, the same `VGEO_CUT_FLAG_CULL` bit. Clusters the sphere rejects count in `CULLED_CLUSTER` as
227
+ before; clusters the sphere passed and the box rejected count in a new `CULLED_CLUSTER_BOX`, so a
228
+ version-4 container reading zero there is §3.4's promise made visible. Two conservative bounds on the
229
+ same subtree; a cluster outside either is outside.
230
+
231
+ **The frustum tests move below the walk-up election.** Today the cull runs before the
232
+ `parent_projected <= tau` branch, so with the coarsen flag on a frontier cluster the frustum rejects
233
+ never elects the walk to its parents — and the parent's own `aabb` can protrude on screen beyond the
234
+ children's union, which is exactly why §3.1 adds it. A tighter bound fires that more often. A cluster
235
+ below the cut refines into nothing and claims nothing, so culling it buys residency nothing; the
236
+ election is evaluated first, unconditionally, and the frustum tests gate only what follows: drawing,
237
+ clamping and refining. The production caller never sets coarsen today; the spec does.
238
+
239
+ ### 3.3 The CPU reference cut
240
+
241
+ `vgeo_select_cut` culls on `page.subtree_aabb` with the same box test, so the fixture and the kernel
242
+ answer the same question, and its spec's claims ("never a hole while a page is missing", "a fully
243
+ resident cut is a whole-file reader's cut") run against the new bound.
244
+
245
+ ### 3.4 Why the sphere test stays
246
+
247
+ For a version-5 page the box is inside the sphere's cube and usually inside the sphere; the sphere
248
+ test culls almost nothing the box would not. For a version-4 page the synthesised box **is** the
249
+ sphere's cube, and a cube culls less than its inscribed sphere: the CPU cut visits 6–10% more pages
250
+ on the cube alone (3,292 against 3,091 at rest). With both tests a version-4 container culls exactly
251
+ what it culls today and a version-5 container culls what the box allows. No version reaches the
252
+ kernel.
253
+
254
+ ## 4. The proof, and where it lives
255
+
256
+ **Claim.** With culling on, the cut draws every cluster the open cut draws that has a vertex inside
257
+ the frustum, and no cluster the open cut does not draw — descending from the root, and walking up
258
+ from a kept frontier with the coarsen flag on. Parents of one group may decide differently —
259
+ a group is claimed and drawn once by whichever parent reaches it first — so no group-uniformity is
260
+ needed and none is argued; §2.1 of the 2026-09-14 plan leaned on it and did not need to.
261
+
262
+ **Argument.** A culled cluster's `CULL_BOX` (or `SELF_SPHERE`) is outside a frustum plane. Both
263
+ contain every vertex of every cluster reachable below it (§3.1's invariant for the box; §7's
264
+ construction for the sphere), so every such cluster is outside the same plane, and so is every
265
+ triangle they carry. Nothing on screen was under it. The LOD half of the rule is untouched, so
266
+ RUNTIME_PLAN §4.4's second proof — every cluster the flat rule draws is reached — holds for every
267
+ on-screen cluster: each ancestor along its chain contains it and so passes both tests.
268
+
269
+ **Where it is checked.** `vgeo_cut_agreement.spec.js`, `frustum culling removes only what is outside
270
+ the frustum`, rewritten to hold the kernel against the **reader's pages** and not against any bound
271
+ the row carries. For each cluster the open cut drew and the culled cut did not, it walks the child
272
+ groups through the reader and asserts every **vertex** of every cluster it reaches — decoded from the
273
+ payload, the same witness `vgeo_read_page.spec` uses for the `aabb` — is outside the frustum. Not the
274
+ descendants' boxes: a sphere that contains every vertex need not contain a box corner, so a
275
+ sphere-culled cluster with a straddling box would fail a box oracle on a correct kernel. For every
276
+ touched page but the root it asserts some cluster refining into it passes the kernel's own predicate
277
+ on bounds the spec computes itself — `self_sphere` not rejected and the union box of its subtree
278
+ not rejected — because a union box the frustum cuts through the gap between two members passes the
279
+ kernel's test with no member inside, and a p-vertex test admits a box just past an edge, so no
280
+ assertion about member boxes is implied by the design. The same test runs with the coarsen flag on
281
+ over a frontier seeded below the cut, against the open coarsen cut. That the **stored**
282
+ `subtree_aabb` equals the union the spec computes is `vgeo_read_page.spec.js`'s to check, and it does,
283
+ exactly. A child group whose page the reader does not hold is a leaf to the walk: nothing below a
284
+ missing page can be drawn, and the parent's own vertices are already in the check.
285
+
286
+ ## 5. What it reads after — measured 2026-09-16
287
+
288
+ The rosette panel rebuilt at version 5 (`5a01cc81…`, 17,213 pages, 590,858 clusters and 160,441
289
+ groups — identical to the version-4 build, and 940,215,784 bytes against 941,905,000), validated
290
+ clean including §11.17 and the new §11.7 check. The tour of RUNTIME_PLAN §7, same driver, same eight
291
+ stops twice round, 4,096 slots, 1258×646, then the rosette at rest. Both containers were driven
292
+ through **this** runtime, so the version-4 column is the §3.4 promise rather than an old reading.
293
+
294
+ | | version 4 (cube from the LOD sphere) | version 5 (subtree box) |
295
+ |---|---:|---:|
296
+ | pages visited, rosette at rest | 3,231 | **2,854** |
297
+ | pages visited, stops 3, 4, 5, 7 | 2,908 / 2,502 / 2,005 / 2,322 | **2,169 / 1,763 / 1,341 / 1,633** |
298
+ | pages visited, framing distance | 1,445 | 1,445 |
299
+ | pages visited, summed over the tour | 48,563 | **39,075** |
300
+ | clusters drawn at rest | 4,055 | 3,471 |
301
+ | clusters the box culled and the sphere did not, at rest | 0 | 5,520 |
302
+ | `clamped`, every stop | 0 | 0 |
303
+ | pages evicted over the run | 3,040 | **1,908** |
304
+ | installs refused over the run | 1,640 | **483** |
305
+ | pages fetched | 4,895 | 4,653 |
306
+
307
+ Against the same stop the box takes 12% off at rest, 14–18% at the three stops facing the panel
308
+ squarely, and 25–33% at the four oblique ones — where §2.2's node measurement said 35–40%, and the
309
+ difference is the sphere test still running in front of it. At the framing distance, where nothing
310
+ is off screen, it costs and saves nothing and the box culls zero. `culled (box)` is zero at every
311
+ stop of the version-4 run, which is §3.4 measured rather than argued.
312
+
313
+ **Drawn falls with visited**, 4,055 to 3,471 at rest, and that is the other half of the same fact:
314
+ those clusters passed a sphere that reaches well outside the geometry it stands for, and they were
315
+ off screen. The rest-pose screenshot is the same picture — same ornament, same shading, same depth
316
+ of detail; only the panel's own counters differ.
317
+
318
+ **What it is worth is residency, not the cut's own cost.** Evictions over the run fall by 37% and
319
+ refused installs by 71%, which is the LRU being handed a working set closer to what the view needs.
320
+ `clamped` stays zero throughout, so nothing is drawn coarse to pay for it.
321
+
322
+ ## 6. What this does not do, and what would
323
+
324
+ - **It does not get visited pages to a few hundred, and nothing conservative on a DAG edge can.** §1
325
+ is the floor: ~1,550 transit pages at every zoomed pose. That floor is the traversal's, not the
326
+ bound's. A descent that reaches groups through a **spatial** hierarchy — a BVH whose leaves are
327
+ groups at every level placed by their own bounds, the LOD range of what is beneath a node deciding
328
+ whether to enter it, the flat rule of §4.4 evaluated at each group reached — needs no subtree
329
+ bound at all, because nothing is reached *through* a coarse cluster; and it enumerates each group
330
+ once, which retires the claim. That is Nanite's shape and a different document: it replaces the
331
+ child-table descent, the claim, the frontier and the coarsen path of CUT_PLAN_2026_09_14.
332
+ - **It does not fix the builder's tail.** Convergence decaying from 0.5 to 0.9 a level above level
333
+ 4 is where the 1,700 transit pages come from, and the assembler mixing levels in a page is why a
334
+ zoomed view touches most of them. Both are the builder's, measured here and left open.
335
+ - **It does not make the error a bound.** §2.3's table is a property of the LOD metric, not of this
336
+ cull; whether the LOD switch should carry a geometric bound beside the quadric is its own question.
337
+ - **It does not touch the node test**, which culls inside an already-claimed page and does not move
338
+ residency.
339
+
340
+ ## 7. Order, and what each step leaves green
341
+
342
+ Each change carries a spec that fails before it and passes after; no spies, no mocks.
343
+
344
+ 1. **Format.** `VGEO_CLUSTER_OFFSET` v5 layout and a v4 table kept for the reader;
345
+ `VGEO_FORMAT_VERSION`/`VGEO_MIN_READER_VERSION` 5; writer re-sequenced and writing `subtree_aabb`;
346
+ builder computes it; reader reads it through `format_version` handed to `VGeoPageFetcherCore` at
347
+ its four construction sites (and synthesises the cube for v4); validator re-sequenced, checks §11.17
348
+ and `self_sphere ∋ vertices`, stops after a version defect. Pins: `vgeo_read_page.spec` — every
349
+ cluster's `subtree_aabb` is exactly the union of its `aabb` and its child group's boxes, and a
350
+ leaf's equals its `aabb`; `vgeo_validate_container.spec` — a shrunk `subtree_aabb` is caught, and so
351
+ is a `self_sphere` that leaves a vertex out; `VGeoContainerReader.spec` — a version-4 record layout
352
+ reads through the legacy offsets with the cube synthesised. `VGEO_FORMAT.md` §4, §7, §11 follow.
353
+ 2. **Rebuild the container** with the new builder, in the background, while the runtime lands.
354
+ 3. **Runtime.** Row layout, page block, kernel (box test, the new counter, the election ahead of the
355
+ culls), fixture cut. Pins: `VGeoRuntimeTables.spec` — the row carries the page's box;
356
+ `vgeo_cut_agreement.spec` — §4's rewritten test, descending and coarsening; the compile spec stays
357
+ at ten storage buffers.
358
+ 4. **Tour** on the rebuilt container and on its version-4 form; §5's table filled in; screenshot
359
+ compared. Done 2026-09-16.
360
+
361
+ ## 8. Review — folded in
362
+
363
+ One adversarial pass over the draft against the code, fifteen findings, the ones that changed the
364
+ document:
365
+
366
+ - **The spec's oracle was wrong for the sphere test (finding 1)** and its claim assertion was not
367
+ implied by the design (2). §4 now tests vertices and the kernel's own predicate on spec-computed
368
+ bounds.
369
+ - **"One level below" is false (3):** unmerged clusters ride the frontier upward. §3.1 memoises.
370
+ - **The coarsen path was unproven and the tighter bound widens its hole (4).** §3.2 moves the
371
+ frustum tests below the election and §4's claim now covers walking up.
372
+ - **`self_sphere ∋ vertices` was never a stated invariant (5)** and dropping `bounds_sphere` deleted
373
+ the only vertex-in-sphere check. §3.1 adds it to §11.7 and the validator.
374
+ - **`payload_offset`/`payload_size` move (6)** and both the writer and the validator are positional.
375
+ §3.1's table and step 1 say so.
376
+ - **Two tables disagreed (7):** §0's per-level split and §1's totals now use one classification, the
377
+ §2.1 caption names its samples, and §5 no longer transfers a CPU delta onto the GPU's count.
378
+ - **Four construction sites, not three (8)**, and the version rides the worker's first request with
379
+ the descriptor. The validator stops after a version defect (10) rather than misreading v4 records
380
+ positionally. `bounds_sphere` is scoped to the record (11). The slot-words doc is rewritten for 76
381
+ bytes a cluster (12). A separate counter tells box culls from sphere culls (15).
382
+
383
+ Confirmed by the pass and left as written: the object-space frustum makes the p-vertex test and the
384
+ version-4 cube conservative under instance scale (14); §2.4's arithmetic (12); `vgeo_read_header`'s
385
+ check admits both versions (9).
@@ -435,7 +435,7 @@ the view-dependent half, with the same eviction hooks.
435
435
  another site already moved.
436
436
 
437
437
  **There are not two sites — and that is a defect, not a shape to design around.** The
438
- phase-one seam call sits *inside* the `ShadeDrawMode × ShadeDrawSide` loop of
438
+ phase-one seam call sits *inside* the per-opaque-bucket loop of
439
439
  `graph_rasterize_partial_opaque`, so a standard view records one cut per **active opaque bucket**
440
440
  plus one for phase two. The engine already says so where rev 2 did not read it —
441
441
  `GPUVirtualGeometryRuntime`: "once per bucket per HZB pass per view".
@@ -518,7 +518,26 @@ the view-dependent half, with the same eviction hooks.
518
518
  checks instead of asking an asset its version — and `GENERATION`. `slot_range` learned the
519
519
  section, or the parent rows would never have been uploaded. Still nothing consumes them.
520
520
 
521
- **A verification surface went away mid-session, and §7.5 needs it.** The `vgeo_runtime`
521
+ **A verification surface went away mid-session and came back — steps 1–6 are confirmed in a
522
+ real browser.** Chrome's regression was worked around on master (`b3919f9c3`, `34c836d4d`:
523
+ the four indirectly dispatched culls, and then particles and SHARC, off immediates and onto a
524
+ uniform), and with that in place the `vgeo_runtime` playground draws again. Re-measured
525
+ against it afterwards:
526
+
527
+ - the in-page container, now written at `format_version` 4 with parent tables, builds, loads
528
+ and draws, and the cut shaders — the coarsen path and the tenth binding included — compile
529
+ under Tint with no console error;
530
+ - the deepest converted Zorah container, which is **`format_version` 3 and carries no parent
531
+ tables at all**, loads and draws under the format-4 reader at every camera tried. That is
532
+ §2.1's back-compatibility claim tested rather than argued, on 27.9M faces;
533
+ - §7.1's table reproduces exactly: `descent_steps` 32 takes 5 dispatches and 16 takes 6, both
534
+ with `QUEUE_REMAINING` 0, while 8 takes all 8 and leaves 12–124 items queued. The default
535
+ of 24 sits inside the clean band.
536
+
537
+ What follows is the note written while it was broken, kept because the diagnosis is what
538
+ makes the gap in the record legible:
539
+
540
+ **A verification surface went away mid-session, and §7.5 needed it.** The `vgeo_runtime`
522
541
  playground draws nothing in headless Chrome: `begin_frame` runs, the feedback resource is open,
523
542
  the adapter is an NVIDIA Lovelace with subgroups, the container builds and its root page installs
524
543
  with a selectable group — and `VGEO_CUT_STAT.PAGES` stays 0, so the seed never reaches its first