@woosh/meep-engine 3.26.0 → 3.27.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 (236) hide show
  1. package/package.json +1 -1
  2. package/src/core/binary/lz4/LZ4_HIGH_COMPRESSION_PLAN_2026_09_14.md +542 -0
  3. package/src/core/binary/lz4/LZ4_LEVEL.d.ts +33 -0
  4. package/src/core/binary/lz4/LZ4_LEVEL.d.ts.map +1 -0
  5. package/src/core/binary/lz4/LZ4_LEVEL.js +32 -0
  6. package/src/core/binary/lz4/lz4_compress_block_at_level.d.ts +33 -0
  7. package/src/core/binary/lz4/lz4_compress_block_at_level.d.ts.map +1 -0
  8. package/src/core/binary/lz4/lz4_compress_block_at_level.js +47 -0
  9. package/src/core/binary/lz4/lz4_compress_block_hc.d.ts +40 -0
  10. package/src/core/binary/lz4/lz4_compress_block_hc.d.ts.map +1 -0
  11. package/src/core/binary/lz4/lz4_compress_block_hc.js +1382 -0
  12. package/src/core/binary/lz4/lz4_decompress_block.d.ts +2 -1
  13. package/src/core/binary/lz4/lz4_decompress_block.d.ts.map +1 -1
  14. package/src/core/binary/lz4/lz4_decompress_block.js +31 -6
  15. package/src/core/geom/3d/shape/HeightMapShape3D.d.ts +14 -7
  16. package/src/core/geom/3d/shape/HeightMapShape3D.d.ts.map +1 -1
  17. package/src/core/geom/3d/shape/HeightMapShape3D.js +87 -78
  18. package/src/engine/physics/fluid/ecs/FluidObstacleSystem.d.ts +4 -4
  19. package/src/shade/playground/vgeo_runtime/README.md +167 -22
  20. package/src/shade/playground/vgeo_runtime/index.html +112 -62
  21. package/src/shade/playground/vgeo_runtime/main.js +660 -83
  22. package/src/shade/playground/vgeo_viewer/sample_asset.d.ts.map +1 -1
  23. package/src/shade/playground/vgeo_viewer/sample_asset.js +19 -2
  24. package/src/shade/renderer/geometry/bvh/GPUGeometryBVHManager.d.ts +11 -0
  25. package/src/shade/renderer/geometry/bvh/GPUGeometryBVHManager.d.ts.map +1 -1
  26. package/src/shade/renderer/geometry/bvh/GPUGeometryBVHManager.js +16 -8
  27. package/src/shade/renderer/geometry/meshlet/GPUMeshletManager.d.ts.map +1 -1
  28. package/src/shade/renderer/geometry/meshlet/GPUMeshletManager.js +16 -11
  29. package/src/shade/renderer/geometry/virtual/VGEO_FORMAT.md +73 -5
  30. package/src/shade/renderer/geometry/virtual/VIRTUAL_GEOMETRY_DESIGN.md +26 -15
  31. package/src/shade/renderer/geometry/virtual/VIRTUAL_GEOMETRY_PLAN.md +5 -3
  32. package/src/shade/renderer/geometry/virtual/build/VGeoBuildOptions.d.ts +18 -0
  33. package/src/shade/renderer/geometry/virtual/build/VGeoBuildOptions.d.ts.map +1 -1
  34. package/src/shade/renderer/geometry/virtual/build/VGeoBuildOptions.js +20 -0
  35. package/src/shade/renderer/geometry/virtual/build/vgeo_assemble_pages.d.ts.map +1 -1
  36. package/src/shade/renderer/geometry/virtual/build/vgeo_assemble_pages.js +56 -9
  37. package/src/shade/renderer/geometry/virtual/build/vgeo_build.d.ts.map +1 -1
  38. package/src/shade/renderer/geometry/virtual/build/vgeo_build.js +1 -0
  39. package/src/shade/renderer/geometry/virtual/format/VGeoWriteOptions.d.ts +22 -0
  40. package/src/shade/renderer/geometry/virtual/format/VGeoWriteOptions.d.ts.map +1 -1
  41. package/src/shade/renderer/geometry/virtual/format/VGeoWriteOptions.js +24 -0
  42. package/src/shade/renderer/geometry/virtual/format/dag/VirtualGeometryCluster.d.ts +12 -0
  43. package/src/shade/renderer/geometry/virtual/format/dag/VirtualGeometryCluster.d.ts.map +1 -1
  44. package/src/shade/renderer/geometry/virtual/format/dag/VirtualGeometryCluster.js +13 -0
  45. package/src/shade/renderer/geometry/virtual/format/frame/vgeo_encode_frame_blob.d.ts +8 -1
  46. package/src/shade/renderer/geometry/virtual/format/frame/vgeo_encode_frame_blob.d.ts.map +1 -1
  47. package/src/shade/renderer/geometry/virtual/format/frame/vgeo_encode_frame_blob.js +11 -3
  48. package/src/shade/renderer/geometry/virtual/format/header/VGEO_FORMAT_VERSION.d.ts +9 -0
  49. package/src/shade/renderer/geometry/virtual/format/header/VGEO_FORMAT_VERSION.d.ts.map +1 -1
  50. package/src/shade/renderer/geometry/virtual/format/header/VGEO_FORMAT_VERSION.js +10 -1
  51. package/src/shade/renderer/geometry/virtual/format/page/VGEO_MAX_PARENT_ENTRY_COUNT.d.ts +18 -0
  52. package/src/shade/renderer/geometry/virtual/format/page/VGEO_MAX_PARENT_ENTRY_COUNT.d.ts.map +1 -0
  53. package/src/shade/renderer/geometry/virtual/format/page/VGEO_MAX_PARENT_ENTRY_COUNT.js +17 -0
  54. package/src/shade/renderer/geometry/virtual/format/page/VGEO_MAX_PARENT_REF.d.ts +8 -0
  55. package/src/shade/renderer/geometry/virtual/format/page/VGEO_MAX_PARENT_REF.d.ts.map +1 -0
  56. package/src/shade/renderer/geometry/virtual/format/page/VGEO_MAX_PARENT_REF.js +7 -0
  57. package/src/shade/renderer/geometry/virtual/format/page/VGEO_PAGE_OFFSET.d.ts +3 -0
  58. package/src/shade/renderer/geometry/virtual/format/page/VGEO_PAGE_OFFSET.js +16 -0
  59. package/src/shade/renderer/geometry/virtual/format/page/VGEO_PARENT_ENTRY_SIZE.d.ts +14 -0
  60. package/src/shade/renderer/geometry/virtual/format/page/VGEO_PARENT_ENTRY_SIZE.d.ts.map +1 -0
  61. package/src/shade/renderer/geometry/virtual/format/page/VGEO_PARENT_ENTRY_SIZE.js +13 -0
  62. package/src/shade/renderer/geometry/virtual/format/page/VGEO_PARENT_PAGE_ENTRY_SIZE.d.ts +11 -0
  63. package/src/shade/renderer/geometry/virtual/format/page/VGEO_PARENT_PAGE_ENTRY_SIZE.d.ts.map +1 -0
  64. package/src/shade/renderer/geometry/virtual/format/page/VGEO_PARENT_PAGE_ENTRY_SIZE.js +10 -0
  65. package/src/shade/renderer/geometry/virtual/format/read/VGeoByteSource.d.ts +20 -0
  66. package/src/shade/renderer/geometry/virtual/format/read/VGeoByteSource.d.ts.map +1 -1
  67. package/src/shade/renderer/geometry/virtual/format/read/VGeoByteSource.js +20 -2
  68. package/src/shade/renderer/geometry/virtual/format/read/VGeoContainerHeader.d.ts +4 -0
  69. package/src/shade/renderer/geometry/virtual/format/read/VGeoContainerHeader.d.ts.map +1 -1
  70. package/src/shade/renderer/geometry/virtual/format/read/VGeoContainerHeader.js +4 -0
  71. package/src/shade/renderer/geometry/virtual/format/read/VGeoContainerReader.d.ts +29 -3
  72. package/src/shade/renderer/geometry/virtual/format/read/VGeoContainerReader.d.ts.map +1 -1
  73. package/src/shade/renderer/geometry/virtual/format/read/VGeoContainerReader.js +81 -122
  74. package/src/shade/renderer/geometry/virtual/format/read/VGeoPage.d.ts +40 -0
  75. package/src/shade/renderer/geometry/virtual/format/read/VGeoPage.d.ts.map +1 -1
  76. package/src/shade/renderer/geometry/virtual/format/read/VGeoPage.js +44 -0
  77. package/src/shade/renderer/geometry/virtual/format/read/VGeoPageFetcherCore.d.ts +69 -0
  78. package/src/shade/renderer/geometry/virtual/format/read/VGeoPageFetcherCore.d.ts.map +1 -0
  79. package/src/shade/renderer/geometry/virtual/format/read/VGeoPageFetcherCore.js +236 -0
  80. package/src/shade/renderer/geometry/virtual/format/read/VGeoReadOptions.d.ts +14 -0
  81. package/src/shade/renderer/geometry/virtual/format/read/VGeoReadOptions.d.ts.map +1 -1
  82. package/src/shade/renderer/geometry/virtual/format/read/VGeoReadOptions.js +15 -0
  83. package/src/shade/renderer/geometry/virtual/format/read/vgeo_byte_source_from_descriptor.d.ts +31 -0
  84. package/src/shade/renderer/geometry/virtual/format/read/vgeo_byte_source_from_descriptor.d.ts.map +1 -0
  85. package/src/shade/renderer/geometry/virtual/format/read/vgeo_byte_source_from_descriptor.js +32 -0
  86. package/src/shade/renderer/geometry/virtual/format/read/vgeo_fetch_byte_source.d.ts +10 -0
  87. package/src/shade/renderer/geometry/virtual/format/read/vgeo_fetch_byte_source.d.ts.map +1 -1
  88. package/src/shade/renderer/geometry/virtual/format/read/vgeo_fetch_byte_source.js +21 -1
  89. package/src/shade/renderer/geometry/virtual/format/read/vgeo_page_transfer.d.ts +15 -0
  90. package/src/shade/renderer/geometry/virtual/format/read/vgeo_page_transfer.d.ts.map +1 -0
  91. package/src/shade/renderer/geometry/virtual/format/read/vgeo_page_transfer.js +84 -0
  92. package/src/shade/renderer/geometry/virtual/format/read/vgeo_page_worker_serve.d.ts +22 -0
  93. package/src/shade/renderer/geometry/virtual/format/read/vgeo_page_worker_serve.d.ts.map +1 -0
  94. package/src/shade/renderer/geometry/virtual/format/read/vgeo_page_worker_serve.js +96 -0
  95. package/src/shade/renderer/geometry/virtual/format/read/vgeo_read_page.d.ts.map +1 -1
  96. package/src/shade/renderer/geometry/virtual/format/read/vgeo_read_page.js +55 -0
  97. package/src/shade/renderer/geometry/virtual/format/vgeo_validate_container.d.ts.map +1 -1
  98. package/src/shade/renderer/geometry/virtual/format/vgeo_validate_container.js +202 -13
  99. package/src/shade/renderer/geometry/virtual/format/vgeo_write_container.d.ts.map +1 -1
  100. package/src/shade/renderer/geometry/virtual/format/vgeo_write_container.js +147 -10
  101. package/src/shade/renderer/geometry/virtual/runtime/CUT_PLAN_2026_09_14.md +637 -0
  102. package/src/shade/renderer/geometry/virtual/runtime/GPUVirtualGeometryPool.d.ts +33 -36
  103. package/src/shade/renderer/geometry/virtual/runtime/GPUVirtualGeometryPool.d.ts.map +1 -1
  104. package/src/shade/renderer/geometry/virtual/runtime/GPUVirtualGeometryPool.js +109 -193
  105. package/src/shade/renderer/geometry/virtual/runtime/GPUVirtualGeometryRuntime.d.ts +58 -28
  106. package/src/shade/renderer/geometry/virtual/runtime/GPUVirtualGeometryRuntime.d.ts.map +1 -1
  107. package/src/shade/renderer/geometry/virtual/runtime/GPUVirtualGeometryRuntime.js +77 -105
  108. package/src/shade/renderer/geometry/virtual/runtime/REVIEW_LEDGER.md +37 -0
  109. package/src/shade/renderer/geometry/virtual/runtime/RUNTIME_PLAN.md +105 -22
  110. package/src/shade/renderer/geometry/virtual/runtime/RUNTIME_PLAN_2026_09_14.md +548 -0
  111. package/src/shade/renderer/geometry/virtual/runtime/VGeoFeedbackLoop.d.ts +29 -50
  112. package/src/shade/renderer/geometry/virtual/runtime/VGeoFeedbackLoop.d.ts.map +1 -1
  113. package/src/shade/renderer/geometry/virtual/runtime/VGeoFeedbackLoop.js +47 -489
  114. package/src/shade/renderer/geometry/virtual/runtime/VGeoPageFetcher.d.ts +84 -0
  115. package/src/shade/renderer/geometry/virtual/runtime/VGeoPageFetcher.d.ts.map +1 -0
  116. package/src/shade/renderer/geometry/virtual/runtime/VGeoPageFetcher.js +393 -0
  117. package/src/shade/renderer/geometry/virtual/runtime/VGeoResidency.d.ts +234 -0
  118. package/src/shade/renderer/geometry/virtual/runtime/VGeoResidency.d.ts.map +1 -0
  119. package/src/shade/renderer/geometry/virtual/runtime/VGeoResidency.js +1363 -0
  120. package/src/shade/renderer/geometry/virtual/runtime/VGeoResidencyOptions.d.ts +81 -0
  121. package/src/shade/renderer/geometry/virtual/runtime/VGeoResidencyOptions.d.ts.map +1 -0
  122. package/src/shade/renderer/geometry/virtual/runtime/VGeoResidencyOptions.js +89 -0
  123. package/src/shade/renderer/geometry/virtual/runtime/VGeoRuntimeTables.d.ts +53 -34
  124. package/src/shade/renderer/geometry/virtual/runtime/VGeoRuntimeTables.d.ts.map +1 -1
  125. package/src/shade/renderer/geometry/virtual/runtime/VGeoRuntimeTables.js +407 -124
  126. package/src/shade/renderer/geometry/virtual/runtime/VGeoViewCut.d.ts +100 -0
  127. package/src/shade/renderer/geometry/virtual/runtime/VGeoViewCut.d.ts.map +1 -0
  128. package/src/shade/renderer/geometry/virtual/runtime/VGeoViewCut.js +219 -0
  129. package/src/shade/renderer/geometry/virtual/runtime/cut/VGEO_CUT_EXPAND.d.ts +17 -0
  130. package/src/shade/renderer/geometry/virtual/runtime/cut/VGEO_CUT_EXPAND.d.ts.map +1 -0
  131. package/src/shade/renderer/geometry/virtual/runtime/cut/VGEO_CUT_EXPAND.js +47 -0
  132. package/src/shade/renderer/geometry/virtual/runtime/cut/VGEO_CUT_FLAG_COARSEN.d.ts +20 -0
  133. package/src/shade/renderer/geometry/virtual/runtime/cut/VGEO_CUT_FLAG_COARSEN.d.ts.map +1 -0
  134. package/src/shade/renderer/geometry/virtual/runtime/cut/VGEO_CUT_FLAG_COARSEN.js +19 -0
  135. package/src/shade/renderer/geometry/virtual/runtime/cut/VGEO_CUT_PARAMS_STRUCT.d.ts.map +1 -1
  136. package/src/shade/renderer/geometry/virtual/runtime/cut/VGEO_CUT_PARAMS_STRUCT.js +30 -12
  137. package/src/shade/renderer/geometry/virtual/runtime/cut/chunk_vgeo_cut_access.d.ts.map +1 -1
  138. package/src/shade/renderer/geometry/virtual/runtime/cut/chunk_vgeo_cut_access.js +15 -0
  139. package/src/shade/renderer/geometry/virtual/runtime/cut/shader_vgeo_cut_collect.d.ts.map +1 -1
  140. package/src/shade/renderer/geometry/virtual/runtime/cut/shader_vgeo_cut_collect.js +18 -1
  141. package/src/shade/renderer/geometry/virtual/runtime/cut/shader_vgeo_cut_queue_prepare.d.ts.map +1 -1
  142. package/src/shade/renderer/geometry/virtual/runtime/cut/shader_vgeo_cut_queue_prepare.js +5 -15
  143. package/src/shade/renderer/geometry/virtual/runtime/cut/shader_vgeo_cut_queue_remainder.d.ts +3 -0
  144. package/src/shade/renderer/geometry/virtual/runtime/cut/shader_vgeo_cut_queue_remainder.d.ts.map +1 -0
  145. package/src/shade/renderer/geometry/virtual/runtime/cut/shader_vgeo_cut_queue_remainder.js +77 -0
  146. package/src/shade/renderer/geometry/virtual/runtime/cut/shader_vgeo_cut_reseed.d.ts +3 -0
  147. package/src/shade/renderer/geometry/virtual/runtime/cut/shader_vgeo_cut_reseed.d.ts.map +1 -0
  148. package/src/shade/renderer/geometry/virtual/runtime/cut/shader_vgeo_cut_reseed.js +186 -0
  149. package/src/shade/renderer/geometry/virtual/runtime/cut/shader_vgeo_cut_seed.d.ts.map +1 -1
  150. package/src/shade/renderer/geometry/virtual/runtime/cut/shader_vgeo_cut_seed.js +20 -8
  151. package/src/shade/renderer/geometry/virtual/runtime/cut/shader_vgeo_cut_traverse.d.ts.map +1 -1
  152. package/src/shade/renderer/geometry/virtual/runtime/cut/shader_vgeo_cut_traverse.js +580 -188
  153. package/src/shade/renderer/geometry/virtual/runtime/cut/vgeo_cut_feedback_layout.d.ts +15 -18
  154. package/src/shade/renderer/geometry/virtual/runtime/cut/vgeo_cut_feedback_layout.d.ts.map +1 -1
  155. package/src/shade/renderer/geometry/virtual/runtime/cut/vgeo_cut_feedback_layout.js +19 -28
  156. package/src/shade/renderer/geometry/virtual/runtime/graph_vgeo_expand_instances_to_meshlets.d.ts.map +1 -1
  157. package/src/shade/renderer/geometry/virtual/runtime/graph_vgeo_expand_instances_to_meshlets.js +45 -25
  158. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_CUT_STAT.d.ts +1 -0
  159. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_CUT_STAT.js +11 -0
  160. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_CUT_STAT_COUNT.js +1 -1
  161. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_FEEDBACK_OFFSET.d.ts +0 -1
  162. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_FEEDBACK_OFFSET.js +12 -10
  163. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_GROUP_ROW_OFFSET.d.ts +1 -0
  164. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_GROUP_ROW_OFFSET.js +8 -0
  165. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_GROUP_ROW_WORDS.d.ts +7 -2
  166. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_GROUP_ROW_WORDS.d.ts.map +1 -1
  167. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_GROUP_ROW_WORDS.js +8 -3
  168. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_PAGE_ROW_OFFSET.d.ts +2 -0
  169. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_PAGE_ROW_OFFSET.js +19 -0
  170. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_PAGE_ROW_WORDS.d.ts.map +1 -1
  171. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_PAGE_ROW_WORDS.js +1 -1
  172. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_PARENT_ROW_OFFSET.d.ts +5 -0
  173. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_PARENT_ROW_OFFSET.d.ts.map +1 -0
  174. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_PARENT_ROW_OFFSET.js +22 -0
  175. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_PARENT_ROW_WORDS.d.ts +14 -0
  176. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_PARENT_ROW_WORDS.d.ts.map +1 -0
  177. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_PARENT_ROW_WORDS.js +13 -0
  178. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_QUEUE_TARGET_PARENT_BIT.d.ts +17 -0
  179. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_QUEUE_TARGET_PARENT_BIT.d.ts.map +1 -0
  180. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_QUEUE_TARGET_PARENT_BIT.js +16 -0
  181. package/src/shade/renderer/geometry/virtual/runtime/make_vgeo_page_worker.d.ts +15 -0
  182. package/src/shade/renderer/geometry/virtual/runtime/make_vgeo_page_worker.d.ts.map +1 -0
  183. package/src/shade/renderer/geometry/virtual/runtime/make_vgeo_page_worker.js +16 -0
  184. package/src/shade/renderer/geometry/virtual/runtime/vgeo_frontier_words.d.ts +23 -0
  185. package/src/shade/renderer/geometry/virtual/runtime/vgeo_frontier_words.d.ts.map +1 -0
  186. package/src/shade/renderer/geometry/virtual/runtime/vgeo_frontier_words.js +28 -0
  187. package/src/shade/renderer/geometry/virtual/runtime/vgeo_page.worker.d.ts +2 -0
  188. package/src/shade/renderer/geometry/virtual/runtime/vgeo_page.worker.d.ts.map +1 -0
  189. package/src/shade/renderer/geometry/virtual/runtime/vgeo_page.worker.js +13 -0
  190. package/src/shade/renderer/geometry/virtual/runtime/vgeo_runtime_page_block_words.d.ts +10 -5
  191. package/src/shade/renderer/geometry/virtual/runtime/vgeo_runtime_page_block_words.d.ts.map +1 -1
  192. package/src/shade/renderer/geometry/virtual/runtime/vgeo_runtime_page_block_words.js +15 -6
  193. package/src/shade/renderer/geometry/virtual/runtime/vgeo_runtime_write_page_block.d.ts +6 -1
  194. package/src/shade/renderer/geometry/virtual/runtime/vgeo_runtime_write_page_block.d.ts.map +1 -1
  195. package/src/shade/renderer/geometry/virtual/runtime/vgeo_runtime_write_page_block.js +38 -1
  196. package/src/shade/renderer/global_illumination/sharc/shader/shader_sharc_evict.d.ts.map +1 -1
  197. package/src/shade/renderer/global_illumination/sharc/shader/shader_sharc_evict.js +4 -3
  198. package/src/shade/renderer/loader/gltf/tiny-gltf.d.ts +1 -1
  199. package/src/shade/renderer/particles/shaders/shader_particle_emit.d.ts.map +1 -1
  200. package/src/shade/renderer/particles/shaders/shader_particle_emit.js +6 -3
  201. package/src/shade/renderer/particles/shaders/shader_particle_simulate.d.ts.map +1 -1
  202. package/src/shade/renderer/particles/shaders/shader_particle_simulate.js +6 -3
  203. package/src/shade/renderer/postprocess/nss/NSS.d.ts +1 -1
  204. package/src/shade/renderer/rasterize/bucket/prepare_meshlet_draw_commands_by_material.d.ts.map +1 -1
  205. package/src/shade/renderer/rasterize/bucket/prepare_meshlet_draw_commands_by_material.js +12 -4
  206. package/src/shade/renderer/rasterize/bucket/shader_read_out_bucket.d.ts +2 -0
  207. package/src/shade/renderer/rasterize/bucket/shader_read_out_bucket.d.ts.map +1 -1
  208. package/src/shade/renderer/rasterize/bucket/shader_read_out_bucket.js +58 -57
  209. package/src/shade/renderer/rasterize/cull/hzb/shader_hzb_mesh_filter_2way.d.ts.map +1 -1
  210. package/src/shade/renderer/rasterize/cull/hzb/shader_hzb_mesh_filter_2way.js +3 -5
  211. package/src/shade/renderer/rasterize/cull/hzb/shader_hzb_meshlet_filter_1way_full.d.ts.map +1 -1
  212. package/src/shade/renderer/rasterize/cull/hzb/shader_hzb_meshlet_filter_1way_full.js +3 -4
  213. package/src/shade/renderer/rasterize/expand/bucket/meshlet/shader_meshlets_extract_bucket.d.ts.map +1 -1
  214. package/src/shade/renderer/rasterize/expand/bucket/meshlet/shader_meshlets_extract_bucket.js +3 -4
  215. package/src/shade/renderer/rasterize/expand/pass0/pass_mesh_cull.d.ts.map +1 -1
  216. package/src/shade/renderer/rasterize/expand/pass0/pass_mesh_cull.js +7 -7
  217. package/src/shade/renderer/rasterize/fast/graph_extract_meshes_from_bucket.d.ts.map +1 -1
  218. package/src/shade/renderer/rasterize/fast/graph_extract_meshes_from_bucket.js +83 -78
  219. package/src/shade/renderer/rasterize/standard/graph_rasterize_partial_opaque.d.ts.map +1 -1
  220. package/src/shade/renderer/rasterize/standard/graph_rasterize_partial_opaque.js +7 -1
  221. package/src/shade/renderer/rasterize/standard/graph_rasterize_remaining_opaque.d.ts.map +1 -1
  222. package/src/shade/renderer/rasterize/standard/graph_rasterize_remaining_opaque.js +7 -1
  223. package/src/shade/renderer/scene/GPUSceneContext.d.ts +22 -2
  224. package/src/shade/renderer/scene/GPUSceneContext.d.ts.map +1 -1
  225. package/src/shade/renderer/scene/GPUSceneContext.js +59 -4
  226. package/src/shade/renderer/shader/resource/ShaderResourceSetDescriptor.d.ts.map +1 -1
  227. package/src/shade/renderer/shader/resource/ShaderResourceSetDescriptor.js +92 -16
  228. package/src/shade/renderer/view/GPUViewContext.d.ts +5 -0
  229. package/src/shade/renderer/view/GPUViewContext.d.ts.map +1 -1
  230. package/src/shade/renderer/view/GPUViewContext.js +21 -0
  231. package/src/shade/wgsl/emulator/WGSLLanguageCore.d.ts.map +1 -1
  232. package/src/shade/wgsl/emulator/WGSLLanguageCore.js +74 -3
  233. package/src/shade/renderer/geometry/virtual/residency/VGeoResidencyManager.js +0 -723
  234. package/src/shade/renderer/geometry/virtual/residency/VGeoResidencyOptions.js +0 -50
  235. package/src/shade/renderer/shader/chunk/jobs/NOTES.md +0 -47
  236. package/src/shade/renderer/shader/chunk/jobs/chunk_job_system.js +0 -102
@@ -0,0 +1,77 @@
1
+ import { atomic_u32 } from "../../../../shader/type/WEBGPU_WGSL_PRIMITIVE_TYPES.js";
2
+ import { WebGPUArray } from "../../../../shader/type/WebGPUArray.js";
3
+ import { CodeChunk } from "../../../../shader/compiler/CodeChunk.js";
4
+ import { COLLECTION_U32_STRUCT_READ } from "../../../../gpu_primitive/COLLECTION_U32_STRUCT_READ.js";
5
+ import { ComputeShader } from "../../../../shader/ComputeShader.js";
6
+ import { ShaderResourceSetDescriptor } from "../../../../shader/resource/ShaderResourceSetDescriptor.js";
7
+ import { VGEO_CUT_STAT } from "../layout/VGEO_CUT_STAT.js";
8
+ import { VGEO_FEEDBACK_OFFSET } from "../layout/VGEO_FEEDBACK_OFFSET.js";
9
+ import { VGEO_CUT_PARAMS_STRUCT } from "./VGEO_CUT_PARAMS_STRUCT.js";
10
+
11
+ /**
12
+ * After the wavefront loop: what the descent stopped with still queued.
13
+ *
14
+ * A queue item never popped is a subtree never descended, and the parent that would have stood in
15
+ * over it was not drawn either — it failed `project(self) <= tau`, which is what sent the descent
16
+ * down there. So this is the one bound of the cut that costs a **hole** rather than coarseness
17
+ * (RUNTIME_PLAN §4.5), and the only one whose reading cannot be inferred from the others.
18
+ *
19
+ * ## Why it is its own pass
20
+ *
21
+ * Only the pass *after the last wavefront* is looking at a remainder. The prepare pass runs
22
+ * between wavefronts, so its count is a frontier, and it runs once per iteration per expansion
23
+ * site, so whatever it stored the next iteration and then the next site would overwrite.
24
+ *
25
+ * An **add** rather than a store, because a frame holds more than one cut — two per view, since the
26
+ * two-way HZB filter splits positive from maybe — and they all record into the frame's one feedback
27
+ * buffer. A store would let the last site to run set the number for the whole frame, an empty cut
28
+ * zeroing a truncation another had just reported. Summing is the same combiner as every other stat
29
+ * in `VGEO_CUT_STAT` and is zero exactly when nothing was left behind, which is the property
30
+ * `VGeoResidencyManager` and anyone lowering `max_iterations` needs of it.
31
+ *
32
+ * The count lives in a transient the graph is about to recycle, so reading it on the CPU would be a
33
+ * readback of a buffer the frame is still writing. Two storage buffers, one uniform and one
34
+ * workgroup is cheaper than the alternative of not knowing.
35
+ *
36
+ * @author Alex Goldring
37
+ * @copyright Company Named Limited (c) 2026
38
+ */
39
+
40
+ const resources = new ShaderResourceSetDescriptor();
41
+
42
+ resources.createGroup()
43
+ .addUniform("params", VGEO_CUT_PARAMS_STRUCT)
44
+ // the queue the last wavefront produced into and nothing consumed
45
+ .addStorageBuffer("queue_ready", COLLECTION_U32_STRUCT_READ, false)
46
+ .addStorageBuffer("feedback", WebGPUArray.from(atomic_u32), true)
47
+ ;
48
+
49
+ const body = CodeChunk.from(
50
+ //language=WGSL
51
+ `
52
+ @compute @workgroup_size(1)
53
+ fn main() {
54
+ /*
55
+ Clamped the way the prepare pass clamps it, and for the same reason: a wavefront reserves its
56
+ output with atomicAdd and lets the count run past capacity, so the raw number counts items that
57
+ were never written. What was dropped at the append is QUEUE_DROPPED and is already counted
58
+ there; counting it here as well would report one lost subtree twice.
59
+ */
60
+ let outstanding = min(queue_ready.count, params.queue_capacity);
61
+
62
+ if (outstanding == 0u) {
63
+ return;
64
+ }
65
+
66
+ atomicAdd(
67
+ &feedback[${VGEO_FEEDBACK_OFFSET.STATS}u + ${VGEO_CUT_STAT.QUEUE_REMAINING}u],
68
+ outstanding
69
+ );
70
+ }
71
+ `);
72
+
73
+ export const shader_vgeo_cut_queue_remainder = ComputeShader.from({
74
+ label: "VGeo cut queue remainder",
75
+ body,
76
+ resources,
77
+ });
@@ -0,0 +1,3 @@
1
+ export const shader_vgeo_cut_reseed: ComputeShader;
2
+ import { ComputeShader } from "../../../../shader/ComputeShader.js";
3
+ //# sourceMappingURL=shader_vgeo_cut_reseed.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"shader_vgeo_cut_reseed.d.ts","sourceRoot":"","sources":["../../../../../../../../src/shade/renderer/geometry/virtual/runtime/cut/shader_vgeo_cut_reseed.js"],"names":[],"mappings":"AAqLA,mDAIG;8BAtL2B,qCAAqC"}
@@ -0,0 +1,186 @@
1
+ import { atomic_u32, u32 } from "../../../../shader/type/WEBGPU_WGSL_PRIMITIVE_TYPES.js";
2
+ import { WebGPUArray } from "../../../../shader/type/WebGPUArray.js";
3
+ import { CodeChunk } from "../../../../shader/compiler/CodeChunk.js";
4
+ import { ComputeShader } from "../../../../shader/ComputeShader.js";
5
+ import { ShaderResourceSetDescriptor } from "../../../../shader/resource/ShaderResourceSetDescriptor.js";
6
+ import { COLLECTION_U32_STRUCT_WRITE } from "../../../../gpu_primitive/COLLECTION_U32_STRUCT_WRITE.js";
7
+ import { VGEO_CUT_STAT } from "../layout/VGEO_CUT_STAT.js";
8
+ import { VGEO_FEEDBACK_OFFSET } from "../layout/VGEO_FEEDBACK_OFFSET.js";
9
+ import { VGEO_INSTANCE_OFFSET } from "../layout/VGEO_INSTANCE_OFFSET.js";
10
+ import { VGEO_INSTANCE_WORDS } from "../layout/VGEO_INSTANCE_WORDS.js";
11
+ import { VGEO_PAGE_ROW_NONE } from "../layout/VGEO_PAGE_ROW_NONE.js";
12
+ import { VGEO_PAGE_ROW_OFFSET } from "../layout/VGEO_PAGE_ROW_OFFSET.js";
13
+ import { VGEO_CUT_PARAMS_STRUCT } from "./VGEO_CUT_PARAMS_STRUCT.js";
14
+ import { VGEO_CUT_WORKGROUP_SIZE } from "./VGEO_CUT_WORKGROUP_SIZE.js";
15
+
16
+ /**
17
+ * Seed a cut from where the last one stood, instead of from the root.
18
+ *
19
+ * `shader_vgeo_cut_seed` puts one item per instance on the queue naming node 0 of that instance's
20
+ * root page, and the descent re-derives the whole cut — 39 levels on a converted container, at
21
+ * about half a microsecond a level a dispatch, every frame, for a camera that may not have moved.
22
+ * This pass puts the pages that cut *ended* on back on the queue instead, and the descent starts
23
+ * there: what has to change between two frames is a level or two in either direction, which the
24
+ * existing refinement and `VGEO_CUT_FLAG_COARSEN`'s walk up both reach.
25
+ *
26
+ * ## Pages, not groups
27
+ *
28
+ * `CUT_PLAN_2026_09_14` §1 describes the frontier as a set of groups. This one is a set of **page
29
+ * rows**, which is coarser and very much simpler: a page is the unit the claim is built on and the
30
+ * unit a visit evaluates whole, so a reseeded page needs no new item kind, no entry format and no
31
+ * dedup beyond the claim the descent already takes. Every group of the page is re-tested by the
32
+ * pure rule, and testing a group the cut did not need costs the test and nothing else.
33
+ *
34
+ * ## What makes a stale frontier safe
35
+ *
36
+ * Two things, and neither is a repair. A page row is reused, so a frontier written against one
37
+ * occupant could name another after an eviction — the host compares the pool's eviction count
38
+ * against the one the frontier was captured at and drops the whole view's frontier when they
39
+ * differ, rather than mending it. And a frontier that is merely *old* is not wrong at all: it names
40
+ * pages that are still a consistent place to stand, and the descent leaves them for finer ones
41
+ * while the coarsen path walks up from them.
42
+ *
43
+ * So the failure mode is a cut that costs what today's costs, which is the fallback the seam
44
+ * already has.
45
+ *
46
+ * ## One lane per (instance, page row)
47
+ *
48
+ * The frontier is per view rather than per (view, instance), so every instance is offered every
49
+ * page in it and the claim decides. That is a superset of what each instance needs — correct, and
50
+ * cheap while a view holds a handful of virtual-geometry instances. It is why this is a first form
51
+ * rather than the last one: §1.1 keys a frontier by mesh row precisely so a thousand instances do
52
+ * not each pay for the union, and that is the change this shape is waiting for.
53
+ *
54
+ * @author Alex Goldring
55
+ * @copyright Company Named Limited (c) 2026
56
+ */
57
+
58
+ const resources = new ShaderResourceSetDescriptor();
59
+
60
+ resources.createGroup()
61
+ .addUniform("params", VGEO_CUT_PARAMS_STRUCT)
62
+ .addStorageBuffer("vg_arena", WebGPUArray.from(u32), false)
63
+ .addStorageBuffer("instances", WebGPUArray.from(u32), false)
64
+ .addStorageBuffer("frontier", WebGPUArray.from(u32), false)
65
+ .addStorageBuffer("queue_out", COLLECTION_U32_STRUCT_WRITE, true)
66
+ .addStorageBuffer("claim", WebGPUArray.from(atomic_u32), true)
67
+ .addStorageBuffer("feedback", WebGPUArray.from(atomic_u32), true)
68
+ ;
69
+
70
+ const body = CodeChunk.from(
71
+ //language=WGSL
72
+ `
73
+ /**
74
+ * A field of a page's slot header. Indexed rather than read through the traversal's accessors,
75
+ * because those come with a chunk that declares rather more than this pass binds.
76
+ */
77
+ fn vg_reseed_page_field(page_row: u32, field: u32) -> u32 {
78
+ return vg_arena[page_row * params.page_slot_words + field];
79
+ }
80
+
81
+ /**
82
+ * The claim, and the touch that goes with it — the seed pass's, taken against a page row that came
83
+ * off a bitmask rather than off a reference already resolved.
84
+ */
85
+ fn vg_reseed_claim(instance_base: u32, page_row: u32) -> bool {
86
+ let ordinal = vg_reseed_page_field(page_row, ${VGEO_PAGE_ROW_OFFSET.ORDINAL}u);
87
+
88
+ if (ordinal >= instances[instance_base + ${VGEO_INSTANCE_OFFSET.ORDINAL_CAPACITY}u]) {
89
+ return false;
90
+ }
91
+
92
+ let bit = instances[instance_base + ${VGEO_INSTANCE_OFFSET.CLAIM_BASE}u] + ordinal;
93
+
94
+ let word = bit >> 5u;
95
+
96
+ if (word >= params.claim_word_count) {
97
+ return false;
98
+ }
99
+
100
+ let mask = 1u << (bit & 31u);
101
+
102
+ if ((atomicOr(&claim[word], mask) & mask) != 0u) {
103
+ return false;
104
+ }
105
+
106
+ atomicAdd(&feedback[${VGEO_FEEDBACK_OFFSET.STATS}u + ${VGEO_CUT_STAT.PAGES}u], 1u);
107
+
108
+ atomicOr(&feedback[params.touch_bits_base + (page_row >> 5u)], 1u << (page_row & 31u));
109
+
110
+ return true;
111
+ }
112
+
113
+ @compute @workgroup_size(${VGEO_CUT_WORKGROUP_SIZE})
114
+ fn main(@builtin(global_invocation_id) global_id: vec3<u32>) {
115
+ let rows = params.frontier_word_count * 32u;
116
+
117
+ if (rows == 0u) {
118
+ return;
119
+ }
120
+
121
+ let lane = global_id.x;
122
+
123
+ let instance_slot = lane / rows;
124
+ let page_row = lane - instance_slot * rows;
125
+
126
+ if (instance_slot >= params.instance_capacity) {
127
+ return;
128
+ }
129
+
130
+ if ((frontier[page_row >> 5u] & (1u << (page_row & 31u))) == 0u) {
131
+ return;
132
+ }
133
+
134
+ let instance_base = instance_slot * ${VGEO_INSTANCE_WORDS}u;
135
+
136
+ let root_row = instances[instance_base + ${VGEO_INSTANCE_OFFSET.ROOT_PAGE_ROW}u];
137
+
138
+ if (root_row == ${VGEO_PAGE_ROW_NONE}u) {
139
+ return;
140
+ }
141
+
142
+ /*
143
+ The page must belong to the geometry this instance draws. A frontier is a set of rows of a
144
+ shared tier and an instance of another geometry has no business standing on them — its claim
145
+ would reject the ordinal eventually, but the geometry row is the honest test and it is two
146
+ reads of a header that is already in cache.
147
+ */
148
+ if (vg_reseed_page_field(page_row, ${VGEO_PAGE_ROW_OFFSET.GEOMETRY_ROW}u)
149
+ != vg_reseed_page_field(root_row, ${VGEO_PAGE_ROW_OFFSET.GEOMETRY_ROW}u)) {
150
+ return;
151
+ }
152
+
153
+ /*
154
+ The claim, for the two reasons the seed takes one on the root: it stamps the page as touched,
155
+ which is the LRU's whole input, and it is what stops a page reached both from the frontier and
156
+ from a descent later in this same cut from being drawn twice.
157
+ */
158
+ if (!vg_reseed_claim(instance_base, page_row)) {
159
+ return;
160
+ }
161
+
162
+ let slot = atomicAdd(&queue_out.count, 1u);
163
+
164
+ if (slot >= params.queue_capacity) {
165
+ atomicAdd(
166
+ &feedback[${VGEO_FEEDBACK_OFFSET.STATS}u + ${VGEO_CUT_STAT.QUEUE_DROPPED}u], 1u
167
+ );
168
+
169
+ return;
170
+ }
171
+
172
+ let base = slot * 4u;
173
+
174
+ queue_out.elements[base] = instance_slot;
175
+ queue_out.elements[base + 1u] = page_row;
176
+ // node 0, which is how every page visit in this runtime begins
177
+ queue_out.elements[base + 2u] = 0u;
178
+ queue_out.elements[base + 3u] = 0u;
179
+ }
180
+ `, []);
181
+
182
+ export const shader_vgeo_cut_reseed = ComputeShader.from({
183
+ label: "VGeo cut reseed",
184
+ body,
185
+ resources,
186
+ });
@@ -1 +1 @@
1
- {"version":3,"file":"shader_vgeo_cut_seed.d.ts","sourceRoot":"","sources":["../../../../../../../../src/shade/renderer/geometry/virtual/runtime/cut/shader_vgeo_cut_seed.js"],"names":[],"mappings":"AA2IA,iDAIG;8BA1I2B,qCAAqC"}
1
+ {"version":3,"file":"shader_vgeo_cut_seed.d.ts","sourceRoot":"","sources":["../../../../../../../../src/shade/renderer/geometry/virtual/runtime/cut/shader_vgeo_cut_seed.js"],"names":[],"mappings":"AAuJA,iDAIG;8BAtJ2B,qCAAqC"}
@@ -53,7 +53,25 @@ const body = CodeChunk.from(
53
53
  fn main(@builtin(global_invocation_id) global_id: vec3<u32>) {
54
54
  let instance_slot = global_id.x;
55
55
 
56
- if (instance_slot >= prefix_sums.count) {
56
+ /*
57
+ The same clamp the collect pass puts on its own input, one pass further along, because the
58
+ count that arrives here is produced the same way: \`shader_vgeo_cut_collect\` reserves a claim
59
+ width with an unconditional \`atomicAdd\` and bounds-checks only the element write, and the
60
+ prefix scan rewrites the elements and leaves the count untouched. So a frame that offered more
61
+ virtual instances than the collection holds hands this pass a count past the end of it, and —
62
+ as everywhere in the cut — the indirect dispatch is built from that count, so the overshoot
63
+ arrives as lanes.
64
+
65
+ One clamp covers both of this pass's reads: the scanned elements and the instance records are
66
+ sized from the same \`instance_capacity\`, so a slot past the end of one is past the end of the
67
+ other. A lane that ran anyway would take its root page row from whatever the bound range gives
68
+ it back rather than from an instance, and put *that* into the queue — a wavefront descending a
69
+ page on behalf of an instance the collect pass never wrote, claiming and touching it. The LRU
70
+ would then hold pages up for geometry nobody is looking at.
71
+ */
72
+ let instance_count = min(prefix_sums.count, arrayLength(&prefix_sums.elements));
73
+
74
+ if (instance_slot >= instance_count) {
57
75
  return;
58
76
  }
59
77
 
@@ -110,13 +128,7 @@ fn main(@builtin(global_invocation_id) global_id: vec3<u32>) {
110
128
 
111
129
  atomicAdd(&feedback[${VGEO_FEEDBACK_OFFSET.STATS}u + ${VGEO_CUT_STAT.PAGES}u], 1u);
112
130
 
113
- if (atomicExchange(&feedback[params.touch_stamp_base + page_row], 1u) == 0u) {
114
- let touch_slot = atomicAdd(&feedback[${VGEO_FEEDBACK_OFFSET.TOUCH_COUNT}u], 1u);
115
-
116
- if (touch_slot < params.touch_capacity) {
117
- atomicStore(&feedback[params.touch_base + touch_slot], page_row);
118
- }
119
- }
131
+ atomicOr(&feedback[params.touch_bits_base + (page_row >> 5u)], 1u << (page_row & 31u));
120
132
 
121
133
  let slot = atomicAdd(&queue_out.count, 1u);
122
134
 
@@ -1 +1 @@
1
- {"version":3,"file":"shader_vgeo_cut_traverse.d.ts","sourceRoot":"","sources":["../../../../../../../../src/shade/renderer/geometry/virtual/runtime/cut/shader_vgeo_cut_traverse.js"],"names":[],"mappings":"AA6gBA,qDAIG;8BA9gB2B,qCAAqC"}
1
+ {"version":3,"file":"shader_vgeo_cut_traverse.d.ts","sourceRoot":"","sources":["../../../../../../../../src/shade/renderer/geometry/virtual/runtime/cut/shader_vgeo_cut_traverse.js"],"names":[],"mappings":"AAq5BA,qDAIG;8BAt5B2B,qCAAqC"}