@woosh/meep-engine 3.60.4 → 3.60.6

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 (419) hide show
  1. package/CHANGELOG.md +2621 -0
  2. package/CONTRIBUTING.md +7 -0
  3. package/MIGRATION_2_TO_3.md +136 -0
  4. package/SECURITY.md +4 -0
  5. package/editor/EditorCameraNavigation.d.ts +2 -1
  6. package/editor/EditorCameraNavigation.d.ts.map +1 -1
  7. package/editor/EditorCameraNavigation.js +51 -57
  8. package/package.json +6 -2
  9. package/src/engine/EngineHarness.d.ts +3 -9
  10. package/src/engine/EngineHarness.d.ts.map +1 -1
  11. package/src/engine/EngineHarness.js +6 -8
  12. package/src/engine/graphics/camera/makeOrbitalCameraController.d.ts +9 -6
  13. package/src/engine/graphics/camera/makeOrbitalCameraController.d.ts.map +1 -1
  14. package/src/engine/graphics/camera/makeOrbitalCameraController.js +44 -71
  15. package/src/engine/graphics/camera/orbital/MomentumAxis.d.ts +64 -0
  16. package/src/engine/graphics/camera/orbital/MomentumAxis.d.ts.map +1 -0
  17. package/src/engine/graphics/camera/orbital/MomentumAxis.js +187 -0
  18. package/src/engine/graphics/camera/orbital/OrbitalCameraRig.d.ts +86 -0
  19. package/src/engine/graphics/camera/orbital/OrbitalCameraRig.d.ts.map +1 -0
  20. package/src/engine/graphics/camera/orbital/OrbitalCameraRig.js +319 -0
  21. package/src/engine/graphics/ecs/camera/topdown/TopDownCameraController.d.ts +34 -10
  22. package/src/engine/graphics/ecs/camera/topdown/TopDownCameraController.d.ts.map +1 -1
  23. package/src/engine/graphics/ecs/camera/topdown/TopDownCameraController.js +116 -30
  24. package/src/engine/graphics/ecs/camera/topdown/TopDownCameraControllerSystem.d.ts +1 -7
  25. package/src/engine/graphics/ecs/camera/topdown/TopDownCameraControllerSystem.d.ts.map +1 -1
  26. package/src/engine/graphics/ecs/camera/topdown/TopDownCameraControllerSystem.js +1 -37
  27. package/src/engine/graphics/ecs/water/Water.d.ts +8 -0
  28. package/src/engine/graphics/ecs/water/Water.d.ts.map +1 -1
  29. package/src/engine/graphics/ecs/water/Water.js +8 -0
  30. package/src/engine/graphics3/WaterSystem.d.ts.map +1 -1
  31. package/src/engine/graphics3/WaterSystem.js +731 -734
  32. package/src/engine/graphics3/decal/DecalTileShader.d.ts +61 -0
  33. package/src/engine/graphics3/decal/DecalTileShader.d.ts.map +1 -0
  34. package/src/engine/graphics3/decal/DecalTileShader.js +138 -0
  35. package/src/engine/graphics3/decal/GPUDecalRenderer.d.ts +10 -4
  36. package/src/engine/graphics3/decal/GPUDecalRenderer.d.ts.map +1 -1
  37. package/src/engine/graphics3/decal/GPUDecalRenderer.js +149 -44
  38. package/src/engine/graphics3/decal/chunk_decal_tile_vertex.d.ts +25 -0
  39. package/src/engine/graphics3/decal/chunk_decal_tile_vertex.d.ts.map +1 -0
  40. package/src/engine/graphics3/decal/chunk_decal_tile_vertex.js +55 -0
  41. package/src/engine/graphics3/decal/graph_gather_decal_tiles.d.ts +22 -0
  42. package/src/engine/graphics3/decal/graph_gather_decal_tiles.d.ts.map +1 -0
  43. package/src/engine/graphics3/decal/graph_gather_decal_tiles.js +70 -0
  44. package/src/engine/graphics3/decal/shader_decal_composite.d.ts +7 -5
  45. package/src/engine/graphics3/decal/shader_decal_composite.d.ts.map +1 -1
  46. package/src/engine/graphics3/decal/shader_decal_composite.js +48 -44
  47. package/src/engine/graphics3/decal/shader_decal_tile_copy.d.ts +12 -0
  48. package/src/engine/graphics3/decal/shader_decal_tile_copy.d.ts.map +1 -0
  49. package/src/engine/graphics3/decal/shader_decal_tile_copy.js +78 -0
  50. package/src/engine/graphics3/decal/shader_gather_decal_tiles.d.ts +11 -0
  51. package/src/engine/graphics3/decal/shader_gather_decal_tiles.d.ts.map +1 -0
  52. package/src/engine/graphics3/decal/shader_gather_decal_tiles.js +80 -0
  53. package/src/engine/input/devices/mouse/MouseEventButtons.d.ts +13 -0
  54. package/src/engine/input/devices/mouse/MouseEventButtons.d.ts.map +1 -0
  55. package/src/engine/input/devices/mouse/MouseEventButtons.js +23 -0
  56. package/src/engine/input/ecs/controllers/KeyboardCameraController.d.ts +4 -0
  57. package/src/engine/input/ecs/controllers/KeyboardCameraController.d.ts.map +1 -1
  58. package/src/engine/input/ecs/controllers/KeyboardCameraController.js +9 -45
  59. package/src/engine/physics/fluid/ecs/FluidObstacleSystem.d.ts +4 -4
  60. package/src/shade/playground/water_refraction/README.md +5 -6
  61. package/src/shade/playground/water_refraction/index.html +1 -1
  62. package/src/shade/renderer/Renderer.d.ts +11 -0
  63. package/src/shade/renderer/Renderer.d.ts.map +1 -1
  64. package/src/shade/renderer/Renderer.js +50 -6
  65. package/src/shade/renderer/camera/orbital/OrbitalCameraController.d.ts +40 -80
  66. package/src/shade/renderer/camera/orbital/OrbitalCameraController.d.ts.map +1 -1
  67. package/src/shade/renderer/camera/orbital/OrbitalCameraController.js +197 -147
  68. package/src/shade/renderer/fluid/GPUFluidCascade.d.ts +3 -3
  69. package/src/shade/renderer/fluid/GPUFluidCascadeStack.d.ts +1 -1
  70. package/src/shade/renderer/fluid/forcing/GPUFluidForcing.d.ts +6 -6
  71. package/src/shade/renderer/fluid/pressure/GPUFluidPressureSolve.d.ts +1 -1
  72. package/src/shade/renderer/fluid/query/GPUFluidQueries.d.ts +1 -1
  73. package/src/shade/renderer/geometry/sdf/GPUGeometrySDFManager.d.ts +28 -45
  74. package/src/shade/renderer/geometry/sdf/GPUGeometrySDFManager.d.ts.map +1 -1
  75. package/src/shade/renderer/geometry/sdf/GPUGeometrySDFManager.js +111 -119
  76. package/src/shade/renderer/geometry/sdf/cards/GPUMeshCardSets.d.ts +22 -3
  77. package/src/shade/renderer/geometry/sdf/cards/GPUMeshCardSets.d.ts.map +1 -1
  78. package/src/shade/renderer/geometry/sdf/cards/GPUMeshCardSets.js +84 -3
  79. package/src/shade/renderer/geometry/virtual/proxy/vgeo_proxy_triangle_limit.d.ts +19 -0
  80. package/src/shade/renderer/geometry/virtual/proxy/vgeo_proxy_triangle_limit.d.ts.map +1 -0
  81. package/src/shade/renderer/geometry/virtual/proxy/vgeo_proxy_triangle_limit.js +25 -0
  82. package/src/shade/renderer/geometry/virtual/proxy/vgeo_to_proxy_mesh.d.ts +31 -0
  83. package/src/shade/renderer/geometry/virtual/proxy/vgeo_to_proxy_mesh.d.ts.map +1 -0
  84. package/src/shade/renderer/geometry/virtual/proxy/vgeo_to_proxy_mesh.js +343 -0
  85. package/src/shade/renderer/geometry/virtual/runtime/VirtualGeometry.d.ts +15 -0
  86. package/src/shade/renderer/geometry/virtual/runtime/VirtualGeometry.d.ts.map +1 -1
  87. package/src/shade/renderer/geometry/virtual/runtime/VirtualGeometry.js +38 -0
  88. package/src/shade/renderer/geometry/virtual/runtime/vgeo_meshlet_metadata_write.d.ts +17 -0
  89. package/src/shade/renderer/geometry/virtual/runtime/vgeo_meshlet_metadata_write.d.ts.map +1 -0
  90. package/src/shade/renderer/geometry/virtual/runtime/vgeo_meshlet_metadata_write.js +29 -0
  91. package/src/shade/renderer/geometry/virtual/runtime/vgeo_runtime_meshlet_batch.d.ts.map +1 -1
  92. package/src/shade/renderer/geometry/virtual/runtime/vgeo_runtime_meshlet_batch.js +7 -13
  93. package/src/shade/renderer/geometry/virtual/sdf/VGeoSDFProxies.d.ts +28 -59
  94. package/src/shade/renderer/geometry/virtual/sdf/VGeoSDFProxies.d.ts.map +1 -1
  95. package/src/shade/renderer/geometry/virtual/sdf/VGeoSDFProxies.js +84 -789
  96. package/src/shade/renderer/global_illumination/probe_clipmap/GPUProbeClipmapGI.d.ts.map +1 -1
  97. package/src/shade/renderer/global_illumination/probe_clipmap/GPUProbeClipmapGI.js +1 -8
  98. package/src/shade/renderer/global_illumination/probe_clipmap/ProbeClipmapSceneHolds.d.ts +7 -6
  99. package/src/shade/renderer/global_illumination/probe_clipmap/ProbeClipmapSceneHolds.d.ts.map +1 -1
  100. package/src/shade/renderer/global_illumination/probe_clipmap/ProbeClipmapSceneHolds.js +12 -11
  101. package/src/shade/renderer/global_illumination/probe_clipmap/brick/mesh/chunk_mesh_brick_instance.d.ts +2 -2
  102. package/src/shade/renderer/global_illumination/probe_clipmap/brick/mesh/chunk_mesh_brick_instance.js +2 -2
  103. package/src/shade/renderer/global_illumination/probe_clipmap/probe/GPUProbeClipmap.d.ts +1 -4
  104. package/src/shade/renderer/global_illumination/probe_clipmap/probe/GPUProbeClipmap.d.ts.map +1 -1
  105. package/src/shade/renderer/global_illumination/probe_clipmap/probe/GPUProbeClipmap.js +1 -10
  106. package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap_hit_surface.d.ts +5 -15
  107. package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap_hit_surface.d.ts.map +1 -1
  108. package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap_hit_surface.js +6 -34
  109. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_shade.d.ts.map +1 -1
  110. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_shade.js +1 -7
  111. package/src/shade/renderer/hiz/HZBFootprint.d.ts +14 -0
  112. package/src/shade/renderer/hiz/HZBFootprint.d.ts.map +1 -0
  113. package/src/shade/renderer/hiz/HZBFootprint.js +16 -0
  114. package/src/shade/renderer/hiz/HZB_FOOTPRINT_X.d.ts +10 -0
  115. package/src/shade/renderer/hiz/HZB_FOOTPRINT_X.d.ts.map +1 -0
  116. package/src/shade/renderer/hiz/HZB_FOOTPRINT_X.js +11 -0
  117. package/src/shade/renderer/hiz/HZB_FOOTPRINT_Y.d.ts +10 -0
  118. package/src/shade/renderer/hiz/HZB_FOOTPRINT_Y.d.ts.map +1 -0
  119. package/src/shade/renderer/hiz/HZB_FOOTPRINT_Y.js +11 -0
  120. package/src/shade/renderer/hiz/HierarchicalZBuffer.d.ts +0 -7
  121. package/src/shade/renderer/hiz/HierarchicalZBuffer.d.ts.map +1 -1
  122. package/src/shade/renderer/hiz/HierarchicalZBuffer.js +405 -350
  123. package/src/shade/renderer/hiz/chunk_hzb_footprint_x.d.ts +12 -0
  124. package/src/shade/renderer/hiz/chunk_hzb_footprint_x.d.ts.map +1 -0
  125. package/src/shade/renderer/hiz/chunk_hzb_footprint_x.js +27 -0
  126. package/src/shade/renderer/hiz/chunk_hzb_footprint_y.d.ts +12 -0
  127. package/src/shade/renderer/hiz/chunk_hzb_footprint_y.d.ts.map +1 -0
  128. package/src/shade/renderer/hiz/chunk_hzb_footprint_y.js +27 -0
  129. package/src/shade/renderer/hiz/hzb_footprint_texels.d.ts +14 -0
  130. package/src/shade/renderer/hiz/hzb_footprint_texels.d.ts.map +1 -0
  131. package/src/shade/renderer/hiz/hzb_footprint_texels.js +34 -0
  132. package/src/shade/renderer/hiz/shader_hzb_reduce_any.d.ts +0 -5
  133. package/src/shade/renderer/hiz/shader_hzb_reduce_any.d.ts.map +1 -1
  134. package/src/shade/renderer/hiz/shader_hzb_reduce_any.js +37 -57
  135. package/src/shade/renderer/hiz/shader_hzb_reduce_mip0.d.ts +11 -0
  136. package/src/shade/renderer/hiz/shader_hzb_reduce_mip0.d.ts.map +1 -0
  137. package/src/shade/renderer/hiz/{shader_hzb_reduce_mip0_clip.js → shader_hzb_reduce_mip0.js} +120 -111
  138. package/src/shade/renderer/loader/gltf/tiny-gltf.d.ts +1 -1
  139. package/src/shade/renderer/material/GPUMaterialManager.d.ts +11 -1
  140. package/src/shade/renderer/material/GPUMaterialManager.d.ts.map +1 -1
  141. package/src/shade/renderer/material/GPUMaterialManager.js +16 -8
  142. package/src/shade/renderer/material/resident/GPUResidentMaterialContext.d.ts +12 -12
  143. package/src/shade/renderer/material/resident/GPUResidentMaterialContext.d.ts.map +1 -1
  144. package/src/shade/renderer/material/resident/GPUResidentMaterialContext.js +17 -118
  145. package/src/shade/renderer/postprocess/gtao/GTAO.d.ts +7 -3
  146. package/src/shade/renderer/postprocess/gtao/GTAO.d.ts.map +1 -1
  147. package/src/shade/renderer/postprocess/gtao/GTAO.js +26 -13
  148. package/src/shade/renderer/postprocess/gtao/ao_reproject_shader.d.ts +14 -0
  149. package/src/shade/renderer/postprocess/gtao/ao_reproject_shader.d.ts.map +1 -1
  150. package/src/shade/renderer/postprocess/gtao/ao_reproject_shader.js +196 -68
  151. package/src/shade/renderer/postprocess/gtao/fragment_shader_gtao.d.ts.map +1 -1
  152. package/src/shade/renderer/postprocess/gtao/fragment_shader_gtao.js +42 -28
  153. package/src/shade/renderer/postprocess/gtao/fragment_shader_gtao_with_irradiance.d.ts.map +1 -1
  154. package/src/shade/renderer/postprocess/gtao/fragment_shader_gtao_with_irradiance.js +429 -414
  155. package/src/shade/renderer/postprocess/gtao/shader_gtao_spatial_denoise.d.ts +16 -0
  156. package/src/shade/renderer/postprocess/gtao/shader_gtao_spatial_denoise.d.ts.map +1 -0
  157. package/src/shade/renderer/postprocess/gtao/shader_gtao_spatial_denoise.js +156 -0
  158. package/src/shade/renderer/scene/GPUSceneContext.d.ts +2 -2
  159. package/src/shade/renderer/scene/GPUSceneContext.js +5 -5
  160. package/src/shade/renderer/shadow/map/GPUSceneShadowmapContext.d.ts.map +1 -1
  161. package/src/shade/renderer/shadow/map/GPUSceneShadowmapContext.js +7 -2
  162. package/src/shade/renderer/water/GPUWaterRenderer.d.ts +0 -6
  163. package/src/shade/renderer/water/GPUWaterRenderer.d.ts.map +1 -1
  164. package/src/shade/renderer/water/GPUWaterRenderer.js +12 -17
  165. package/src/shade/renderer/water/medium/graph_water_meshlets.d.ts +35 -0
  166. package/src/shade/renderer/water/medium/graph_water_meshlets.d.ts.map +1 -0
  167. package/src/shade/renderer/water/medium/graph_water_meshlets.js +89 -0
  168. package/src/shade/renderer/water/query/GPUWaterQueries.d.ts +1 -1
  169. package/src/shade/renderer/water/shader_water.d.ts.map +1 -1
  170. package/src/shade/renderer/water/shader_water.js +22 -13
  171. package/src/shade/renderer/water/shader_water_avboit.d.ts.map +1 -1
  172. package/src/shade/renderer/water/shader_water_avboit.js +7 -7
  173. package/src/shade/renderer/water/surface/graph_water_tessellation.d.ts +1 -1
  174. package/src/shade/renderer/water/surface/graph_water_tessellation.js +1 -1
  175. package/src/shade/wgsl/emulator/WGSLJavaScriptCompiler.js +9 -1
  176. package/editor/REWORK_PLAN_2026_08.md +0 -692
  177. package/src/CODEC_LAYOUT_VERIFICATION.md +0 -419
  178. package/src/CORRECTNESS_HUNT_2026_07_24.md +0 -142
  179. package/src/DUPLICATION_AUDIT_2026_08_07/00_core_reuse_surface.md +0 -738
  180. package/src/DUPLICATION_AUDIT_2026_08_07/A_core_math_geom.md +0 -79
  181. package/src/DUPLICATION_AUDIT_2026_08_07/B_core_data.md +0 -93
  182. package/src/DUPLICATION_AUDIT_2026_08_07/C_gfx_render.md +0 -80
  183. package/src/DUPLICATION_AUDIT_2026_08_07/D_gfx_features.md +0 -164
  184. package/src/DUPLICATION_AUDIT_2026_08_07/E_physics.md +0 -69
  185. package/src/DUPLICATION_AUDIT_2026_08_07/F_sound.md +0 -110
  186. package/src/DUPLICATION_AUDIT_2026_08_07/G_net_save.md +0 -129
  187. package/src/DUPLICATION_AUDIT_2026_08_07/H_engine_misc.md +0 -72
  188. package/src/DUPLICATION_AUDIT_2026_08_07/I_generation_view.md +0 -74
  189. package/src/DUPLICATION_AUDIT_2026_08_07/K_crosscutting.md +0 -169
  190. package/src/DUPLICATION_AUDIT_2026_08_07.md +0 -254
  191. package/src/DUPLICATION_AUDIT_REMEDIATION.md +0 -250
  192. package/src/DUPLICATION_REVIEW_2026_10_24.md +0 -1072
  193. package/src/REVIEW_2026_08_06/adv-core.md +0 -511
  194. package/src/REVIEW_2026_08_06/adv-gfx.md +0 -480
  195. package/src/REVIEW_2026_08_06/adv-view.md +0 -446
  196. package/src/REVIEW_2026_08_06/api-core.md +0 -296
  197. package/src/REVIEW_2026_08_06/api-engine.md +0 -195
  198. package/src/REVIEW_2026_08_06/bvh-phys-sound-net.md +0 -507
  199. package/src/REVIEW_2026_08_06/core-binary.md +0 -348
  200. package/src/REVIEW_2026_08_06/core-collection.md +0 -376
  201. package/src/REVIEW_2026_08_06/core-math.md +0 -221
  202. package/src/REVIEW_2026_08_06/core-process.md +0 -266
  203. package/src/REVIEW_2026_08_06/core-science.md +0 -223
  204. package/src/REVIEW_2026_08_06/engine-ai-nav.md +0 -279
  205. package/src/REVIEW_2026_08_06/engine-animation.md +0 -167
  206. package/src/REVIEW_2026_08_06/engine-asset.md +0 -166
  207. package/src/REVIEW_2026_08_06/engine-ecs.md +0 -920
  208. package/src/REVIEW_2026_08_06/engine-input.md +0 -197
  209. package/src/REVIEW_2026_08_06/engine-misc.md +0 -248
  210. package/src/REVIEW_2026_08_06/engine-terrain.md +0 -52
  211. package/src/REVIEW_2026_08_06/generation.md +0 -176
  212. package/src/REVIEW_2026_08_06/geom-2d.md +0 -434
  213. package/src/REVIEW_2026_08_06/geom-3d.md +0 -117
  214. package/src/REVIEW_2026_08_06/gfx-gi.md +0 -143
  215. package/src/REVIEW_2026_08_06/gfx-render.md +0 -740
  216. package/src/REVIEW_2026_08_06/gfx-texture.md +0 -690
  217. package/src/REVIEW_2026_08_06/prior-criticals.md +0 -49
  218. package/src/REVIEW_2026_08_06/prior-highs.md +0 -138
  219. package/src/REVIEW_2026_08_06/test-gaps.md +0 -364
  220. package/src/REVIEW_2026_08_06/view.md +0 -667
  221. package/src/REVIEW_2026_08_06.md +0 -610
  222. package/src/core/binary/lz4/LZ4_HIGH_COMPRESSION_PLAN_2026_09_14.md +0 -542
  223. package/src/core/bvh2/bvh3/NOTES.md +0 -2
  224. package/src/core/bvh8/NOTES.md +0 -63
  225. package/src/core/cache/wtinylfu/benchmark/CacheWTinylfu.bench.md +0 -243
  226. package/src/core/color/COLOR_FIX_PLAN_2026_08_28.md +0 -417
  227. package/src/core/color/COLOR_REVIEW_2026_08_28.md +0 -779
  228. package/src/core/geom/2d/polygon/TRIANGULATION_DESIGN.md +0 -433
  229. package/src/core/geom/3d/atlas/ATLAS_PORT_PLAN.md +0 -486
  230. package/src/core/geom/3d/atlas/BFF_PLAN.md +0 -174
  231. package/src/core/geom/3d/atlas/REVIEW_02.md +0 -392
  232. package/src/core/geom/3d/gjk/GJK_REVIEW_NOTES.md +0 -146
  233. package/src/core/geom/3d/gjk/NOTES.md +0 -8
  234. package/src/core/geom/3d/topology/TOPO_MESH_RETIREMENT_PLAN.md +0 -135
  235. package/src/core/geom/GEOMETRY_REVIEW_002_API_ISSUES.md +0 -381
  236. package/src/core/geom/GEOMETRY_REVIEW_002_NAMING.md +0 -684
  237. package/src/core/geom/MANIFOLD_COMPARISON_2026_08_01.md +0 -554
  238. package/src/core/model/reactive/evaluation/PREDICATE_APPLICABILITY_PROPOSAL.md +0 -446
  239. package/src/engine/REVIEW_2026_07_03.md +0 -211
  240. package/src/engine/asset/loaders/image/IMAGE_CODEC_REVIEW_2026_08_28.md +0 -815
  241. package/src/engine/control/first-person/DESIGN.md +0 -658
  242. package/src/engine/control/first-person/DESIGN_COLLISION.md +0 -382
  243. package/src/engine/control/first-person/DESIGN_EXTENSIONS.md +0 -563
  244. package/src/engine/control/first-person/TODO.md +0 -160
  245. package/src/engine/ecs/ASYNC_SYSTEMS_PROPOSAL.md +0 -531
  246. package/src/engine/ecs/HIERARCHY_REVIEW.md +0 -717
  247. package/src/engine/ecs/async/WORKER_SYSTEM_PLAN.md +0 -262
  248. package/src/engine/ecs/ik/PLAN.md +0 -179
  249. package/src/engine/ecs/storage/binary/SERIALIZATION_COVERAGE.md +0 -272
  250. package/src/engine/ecs/storage/binary/object-v2/DESIGN.md +0 -199
  251. package/src/engine/ecs/transform/TRANSFORM64_MIGRATION_PLAN_2026_09_04.md +0 -521
  252. package/src/engine/graphics/CONTEXT_LOSS_RECOVERY_PLAN.md +0 -463
  253. package/src/engine/graphics/ecs/camera/pp/NOTES.md +0 -48
  254. package/src/engine/graphics/render/frame_graph/CORRECTNESS_FIXES_2026_09_04.md +0 -659
  255. package/src/engine/graphics/render/frame_graph/FRAME_GRAPH_RECOMMENDATIONS.md +0 -235
  256. package/src/engine/graphics/sh3/path_tracer/REVIEW_001_ACTION_PLAN.md +0 -490
  257. package/src/engine/graphics/texture/sampler/compare/FLIP_IMPLEMENTATION_PLAN.md +0 -466
  258. package/src/engine/input/GAMEPAD_API_PROPOSAL.md +0 -717
  259. package/src/engine/input/ecs/ism/ISM_DESIGN.md +0 -1523
  260. package/src/engine/input/ecs/ism/ISM_IMPLEMENTATION_PLAN.md +0 -627
  261. package/src/engine/navigation/mesh/OVERLAPPING_SURFACES_2026_08_25.md +0 -661
  262. package/src/engine/navigation/mesh/PATHFINDING_PLAN.md +0 -229
  263. package/src/engine/network/CONGESTION_CONTROL.md +0 -87
  264. package/src/engine/network/MESSAGE_TRANSPORT.md +0 -364
  265. package/src/engine/network/SMOOTHNESS_DESIGN.md +0 -400
  266. package/src/engine/physics/cloth/MEASUREMENTS.md +0 -5304
  267. package/src/engine/physics/cloth/PLAN.md +0 -3056
  268. package/src/engine/physics/fluid/GPU_FLUID_CASCADES_PROPOSAL_2026_10_16.md +0 -1382
  269. package/src/engine/physics/fluid/REVIEW_02_PLAN.md +0 -243
  270. package/src/engine/physics/fluid/solver/NOTES.md +0 -46
  271. package/src/engine/sound/SOUND_EMITTER_RETIREMENT_PLAN.md +0 -536
  272. package/src/engine/sound/simulation/IMPLEMENTATION_PLAN.md +0 -432
  273. package/src/engine/sound/simulation/PROBE_PLACEMENT.md +0 -250
  274. package/src/engine/sound/simulation/PROBE_TRANSFER_RESEARCH.md +0 -322
  275. package/src/engine/sound/simulation/REFLECTION_IR_PLAN.md +0 -261
  276. package/src/engine/sound/simulation/VISIBILITY_GRAPH_PLAN.md +0 -121
  277. package/src/engine/sound/sopra/IMPLEMENTATION_PLAN.md +0 -999
  278. package/src/format/image/avif/DECISIONS.md +0 -545
  279. package/src/format/image/jpeg/NOTES.md +0 -3
  280. package/src/format/scene/gltf/MESHOPT_COMPRESSION_PLAN.md +0 -814
  281. package/src/generation/COORDINATES.md +0 -54
  282. package/src/generation/REVIEW_01_ACTION_PLAN.md +0 -628
  283. package/src/generation/foliage/ANNUAL_SHOOTS_BRIEF_2026_10_25.md +0 -220
  284. package/src/generation/foliage/CROWN_FILLING_BRIEF_2026_10_26.md +0 -172
  285. package/src/generation/foliage/CROWN_FULLNESS_BRIEF_2026_10_26.md +0 -86
  286. package/src/generation/foliage/FOLIAGE_DESIGN.md +0 -547
  287. package/src/generation/foliage/FOLIAGE_PLAN.md +0 -198
  288. package/src/generation/foliage/LEAF_ARCHITECTURE_BRIEF_2026_10_26.md +0 -158
  289. package/src/generation/foliage/LOD_REWORK_BRIEF_2026_10_27.md +0 -521
  290. package/src/generation/foliage/REAL_TIME_TREES_BRIEF_2026_10_27.md +0 -86
  291. package/src/generation/foliage/SELF_ORGANIZING_FRAMEWORK_BRIEF_2026_10_26.md +0 -347
  292. package/src/generation/foliage/SHOOT_SYSTEMS_ALL_SPECIES_BRIEF_2026_10_26.md +0 -248
  293. package/src/generation/foliage/SPEEDTREE_COMPARISON_2026_10_24.md +0 -694
  294. package/src/generation/foliage/TWO_FRONT_ENDS_BRIEF_2026_10_28.md +0 -552
  295. package/src/shade/RENDERER_CONTRACT.md +0 -697
  296. package/src/shade/SHADER_F16_PROPOSAL_2026_10_24.md +0 -263
  297. package/src/shade/device/IMMEDIATE_DATA_PLAN_2026_08_28.md +0 -569
  298. package/src/shade/device/PASS_ENCODER_PROPOSAL_2026_08_31.md +0 -755
  299. package/src/shade/device/mock/EXTENSION_PROPOSAL_2026_08_22.md +0 -458
  300. package/src/shade/device/mock/IMPLEMENTATION_PLAN.md +0 -255
  301. package/src/shade/device/mock/REVIEW_2026_08_22.md +0 -527
  302. package/src/shade/device/timing/GPU_PROFILER_PROPOSAL_2026_08_28.md +0 -894
  303. package/src/shade/device/timing/profile/SGPT_FORMAT.md +0 -345
  304. package/src/shade/renderer/NOTES.md +0 -78
  305. package/src/shade/renderer/PLAN.md +0 -8
  306. package/src/shade/renderer/animation/ADDITIVE_BLENDING_PLAN.md +0 -145
  307. package/src/shade/renderer/animation/SKINNING_FRAME_PLAN.md +0 -357
  308. package/src/shade/renderer/atmosphere/NOTES.md +0 -6
  309. package/src/shade/renderer/camera/orbital/MomentumAxis.d.ts +0 -76
  310. package/src/shade/renderer/camera/orbital/MomentumAxis.d.ts.map +0 -1
  311. package/src/shade/renderer/camera/orbital/MomentumAxis.js +0 -164
  312. package/src/shade/renderer/camera/orbital/OrbitalCameraConfig.d.ts +0 -45
  313. package/src/shade/renderer/camera/orbital/OrbitalCameraConfig.d.ts.map +0 -1
  314. package/src/shade/renderer/camera/orbital/OrbitalCameraConfig.js +0 -66
  315. package/src/shade/renderer/camera/orbital/OrbitalCameraInput.d.ts +0 -98
  316. package/src/shade/renderer/camera/orbital/OrbitalCameraInput.d.ts.map +0 -1
  317. package/src/shade/renderer/camera/orbital/OrbitalCameraInput.js +0 -184
  318. package/src/shade/renderer/camera/orbital/OrbitalCameraRig.d.ts +0 -175
  319. package/src/shade/renderer/camera/orbital/OrbitalCameraRig.d.ts.map +0 -1
  320. package/src/shade/renderer/camera/orbital/OrbitalCameraRig.js +0 -411
  321. package/src/shade/renderer/camera/orbital/README.md +0 -81
  322. package/src/shade/renderer/camera/orbital/index.d.ts +0 -6
  323. package/src/shade/renderer/camera/orbital/index.d.ts.map +0 -1
  324. package/src/shade/renderer/camera/orbital/index.js +0 -9
  325. package/src/shade/renderer/extension/RENDER_EXTENSION_DESIGN.md +0 -964
  326. package/src/shade/renderer/fluid/GPU_FLUID_OCCUPANCY_AND_SOTA_REVIEW_2026_10_26.md +0 -361
  327. package/src/shade/renderer/geometry/bvh/BLAS_REFIT_BATCH_PLAN.md +0 -619
  328. package/src/shade/renderer/geometry/meshlet/COMPACTION_PLAN_2026_09_16.md +0 -674
  329. package/src/shade/renderer/geometry/sdf/NOTES.md +0 -6
  330. package/src/shade/renderer/geometry/virtual/ATTRIBUTE_PLAN_2026_09_18.md +0 -540
  331. package/src/shade/renderer/geometry/virtual/MICRON_COMPARISON_2026_08_20.md +0 -305
  332. package/src/shade/renderer/geometry/virtual/VGEO_FORMAT.md +0 -913
  333. package/src/shade/renderer/geometry/virtual/VIRTUAL_GEOMETRY_DESIGN.md +0 -787
  334. package/src/shade/renderer/geometry/virtual/VIRTUAL_GEOMETRY_PLAN.md +0 -481
  335. package/src/shade/renderer/geometry/virtual/VK_LOD_CLUSTERS_COMPARISON_2026_08_20.md +0 -301
  336. package/src/shade/renderer/geometry/virtual/WEDGE_PLAN_2026_09_18.md +0 -448
  337. package/src/shade/renderer/geometry/virtual/runtime/CULL_PLAN_2026_09_16.md +0 -385
  338. package/src/shade/renderer/geometry/virtual/runtime/CUT_PLAN_2026_09_14.md +0 -656
  339. package/src/shade/renderer/geometry/virtual/runtime/REVIEW_LEDGER.md +0 -308
  340. package/src/shade/renderer/geometry/virtual/runtime/RUNTIME_PLAN.md +0 -657
  341. package/src/shade/renderer/geometry/virtual/runtime/RUNTIME_PLAN_2026_09_14.md +0 -551
  342. package/src/shade/renderer/geometry/virtual/runtime/SHADOW_PLAN_2026_09_28.md +0 -529
  343. package/src/shade/renderer/geometry/virtual/sdf/VGEO_SDF.d.ts +0 -47
  344. package/src/shade/renderer/geometry/virtual/sdf/VGEO_SDF.d.ts.map +0 -1
  345. package/src/shade/renderer/geometry/virtual/sdf/VGEO_SDF.js +0 -80
  346. package/src/shade/renderer/geometry/virtual/sdf/shader_vgeo_sdf_collect.d.ts +0 -16
  347. package/src/shade/renderer/geometry/virtual/sdf/shader_vgeo_sdf_collect.d.ts.map +0 -1
  348. package/src/shade/renderer/geometry/virtual/sdf/shader_vgeo_sdf_collect.js +0 -67
  349. package/src/shade/renderer/geometry/virtual/sdf/shader_vgeo_sdf_decode.d.ts +0 -17
  350. package/src/shade/renderer/geometry/virtual/sdf/shader_vgeo_sdf_decode.d.ts.map +0 -1
  351. package/src/shade/renderer/geometry/virtual/sdf/shader_vgeo_sdf_decode.js +0 -145
  352. package/src/shade/renderer/geometry/virtual/sdf/shader_vgeo_sdf_traverse.d.ts +0 -12
  353. package/src/shade/renderer/geometry/virtual/sdf/shader_vgeo_sdf_traverse.d.ts.map +0 -1
  354. package/src/shade/renderer/geometry/virtual/sdf/shader_vgeo_sdf_traverse.js +0 -105
  355. package/src/shade/renderer/global_illumination/lpv/NOTES.md +0 -3
  356. package/src/shade/renderer/global_illumination/probe_clipmap/PROBE_CLIPMAP_PROPOSAL_2026_10_27.md +0 -4306
  357. package/src/shade/renderer/global_illumination/probe_clipmap/PROBE_RAYS_VARIABLE_AND_SORTED_SCOPE_2026_10_30.md +0 -410
  358. package/src/shade/renderer/global_illumination/sharc/NOTES.md +0 -8
  359. package/src/shade/renderer/gpu_primitive/bvh/GPU_BVH_BUILD_PLAN.md +0 -1369
  360. package/src/shade/renderer/gpu_primitive/bvh/PHASE1_HANDOVER.md +0 -202
  361. package/src/shade/renderer/gpu_primitive/indirect/NOTES.md +0 -94
  362. package/src/shade/renderer/hiz/NOTES.md +0 -3
  363. package/src/shade/renderer/hiz/shader_hzb_reduce_mip0_clip.d.ts +0 -8
  364. package/src/shade/renderer/hiz/shader_hzb_reduce_mip0_clip.d.ts.map +0 -1
  365. package/src/shade/renderer/light/cluster/NOTES.md +0 -11
  366. package/src/shade/renderer/light/cluster/PROPOSAL_ALGORITHM_2026_10_16.md +0 -524
  367. package/src/shade/renderer/light/cluster/PROPOSAL_HIERARCHICAL_2026_10_16.md +0 -1101
  368. package/src/shade/renderer/material/resident/shader_resident_texture_means.d.ts +0 -24
  369. package/src/shade/renderer/material/resident/shader_resident_texture_means.d.ts.map +0 -1
  370. package/src/shade/renderer/material/resident/shader_resident_texture_means.js +0 -120
  371. package/src/shade/renderer/particles/DESIGN.md +0 -1011
  372. package/src/shade/renderer/particles/EMITTER_GLOBAL_STATE_PLAN_2026_10_29.md +0 -280
  373. package/src/shade/renderer/particles/ORIENTATION_PLAN_2026_10_15.md +0 -453
  374. package/src/shade/renderer/path_tracer/PATH_TRACED_MEDIA_PLAN_2026_10_02.md +0 -520
  375. package/src/shade/renderer/postprocess/bloom/NOTES.md +0 -6
  376. package/src/shade/renderer/postprocess/fsr/NOTES.md +0 -4
  377. package/src/shade/renderer/postprocess/gtao/NOTES.md +0 -6
  378. package/src/shade/renderer/postprocess/nss/NOTES.md +0 -332
  379. package/src/shade/renderer/postprocess/perspective/NOTES.md +0 -3
  380. package/src/shade/renderer/postprocess/sscs/NOTES.md +0 -5
  381. package/src/shade/renderer/postprocess/ssr/NOTES.md +0 -14
  382. package/src/shade/renderer/postprocess/ssr/REPROJECTION_PROPOSAL.md +0 -286
  383. package/src/shade/renderer/postprocess/ssr/prefilter/NOTES.md +0 -39
  384. package/src/shade/renderer/postprocess/taa/NOTES.md +0 -11
  385. package/src/shade/renderer/postprocess/upscale-dither/NOTES.md +0 -78
  386. package/src/shade/renderer/postprocess/vrs/NOTES.md +0 -4
  387. package/src/shade/renderer/rasterize/native/avboit/AVBOIT_LEDGER.md +0 -1218
  388. package/src/shade/renderer/rasterize/native/avboit/AVBOIT_PLAN_2026_09_03.md +0 -600
  389. package/src/shade/renderer/restir/reservoir/NOTES.md +0 -6
  390. package/src/shade/renderer/shader/chunk/atmosphere/NOTES.md +0 -6
  391. package/src/shade/renderer/shader/chunk/brdf/FRESNEL_BRIEF_2026_10_16.md +0 -391
  392. package/src/shade/renderer/shader/chunk/color/tonemap/ACES_TONE_MAPPING_BRIEF_2026_10_17.md +0 -153
  393. package/src/shade/renderer/shader/chunk/color/tonemap/HDR_TONE_MAPPING_FORMS_BRIEF_2026_10_16.md +0 -322
  394. package/src/shade/renderer/shader/chunk/color/tonemap/SDR_TONE_MAPPING_BRIEF_2026_10_16.md +0 -247
  395. package/src/shade/renderer/shader/chunk/fsr/NOTES.md +0 -3
  396. package/src/shade/renderer/shader/chunk/fsr/spd/NOTES.md +0 -4
  397. package/src/shade/renderer/shader/chunk/geometry/ray/NOTES.md +0 -4
  398. package/src/shade/renderer/shader/chunk/material/MULTISCATTER.md +0 -159
  399. package/src/shade/renderer/shader/chunk/mboit/NOTES.md +0 -38
  400. package/src/shade/renderer/shader/chunk/spherical_harmonics/l1i/NOTES.md +0 -3
  401. package/src/shade/renderer/shader/chunk/spherical_harmonics/sampling/NOTES.md +0 -8
  402. package/src/shade/renderer/shader/compiler/SHADER_SWITCH_PROPOSAL_2026_10_16.md +0 -927
  403. package/src/shade/renderer/shadow/contact/FINDINGS.md +0 -413
  404. package/src/shade/renderer/shadow/map/csm/NOTES.md +0 -5
  405. package/src/shade/renderer/shadow/ray/NOTES.md +0 -31
  406. package/src/shade/renderer/shadow/sdf/NOTES.md +0 -9
  407. package/src/shade/renderer/shadow/sdf/brixelizer/NOTES.md +0 -5
  408. package/src/shade/renderer/shadow/sdf/cascade/NOTES.md +0 -9
  409. package/src/shade/renderer/shadow/vsm/NOTES.md +0 -12
  410. package/src/shade/renderer/shadow/vsm/PLAN.md +0 -442
  411. package/src/shade/renderer/shadow/vsm/REVIEW_LEDGER.md +0 -43
  412. package/src/shade/renderer/texture/COMPRESSED_TEXTURE_PLAN_2026_09_01.md +0 -2444
  413. package/src/shade/renderer/texture/mipmaps/NOTES.md +0 -3
  414. package/src/shade/renderer/volumetrics/NOTES.md +0 -1329
  415. package/src/shade/renderer/volumetrics/VOLUMETRIC_NOISE_PLAN_2026_10_15.md +0 -336
  416. package/src/shade/renderer/water/medium/GPUWaterBodies.d.ts +0 -23
  417. package/src/shade/renderer/water/medium/GPUWaterBodies.d.ts.map +0 -1
  418. package/src/shade/renderer/water/medium/GPUWaterBodies.js +0 -75
  419. package/src/shade/wgsl/NOTES.md +0 -4
@@ -1,301 +0,0 @@
1
- # vk_lod_clusters — what NVIDIA's reference implementation does differently
2
-
3
- Review of [nvpro-samples/vk_lod_clusters](https://github.com/nvpro-samples/vk_lod_clusters)
4
- against the current design and builder. It is the closest thing to a reference
5
- implementation of this design that exists in the open: Nanite-family cluster LOD, GPU cut,
6
- demand streaming inside a memory budget, both raster (mesh shaders) and ray tracing
7
- (`VK_NV_cluster_acceleration_structure`). Its stress scene is Zorah at 18.9 G triangles with
8
- instancing and a 26 GB cache, which is the scale §5 of the design is written for.
9
-
10
- The build side is a fork of meshoptimizer's single-header `clusterlod.h`
11
- (`src/meshopt_clusterlod.h`); the runtime is the sample's own shaders.
12
-
13
- > **Status.** Reviewed and decided. What was taken, what was declined and why, and what is
14
- > scheduled but not yet built, all live in
15
- > [VIRTUAL_GEOMETRY_PLAN.md](./VIRTUAL_GEOMETRY_PLAN.md) — that file is the one to act on.
16
- > This one is kept as the analysis behind those decisions.
17
- >
18
- > It is a **snapshot dated in its filename** and is not maintained against the code. Statements
19
- > about meep that have since gone stale are corrected inline in block quotes like this one,
20
- > rather than edited away — the argument that was made at the time is the reason the decision
21
- > was taken, and rewriting it hides that.
22
-
23
- ## 1. Where it confirms decisions already made
24
-
25
- Corroboration, not findings — but each of these was a judgement call and it is worth knowing
26
- someone else made it the same way.
27
-
28
- | Decision | vk_lod_clusters | meep |
29
- |---|---|---|
30
- | Build terminates at one root | `while (context.pending.size() > 1)`, then emits a final group with `bounds.error = FLT_MAX` | round loop to one cluster, `parent_error = +∞` |
31
- | Group is the LOD and residency atom | groups are "collections of decimated clusters that are seamless with one another"; streaming is per group | group never spans pages, activation is group-atomic |
32
- | Parents inherit the group's bounds | `boundsMerge` computes the group's sphere; the new cluster inherits it rather than recomputing — explicitly "ensuring monotonicity" | `self_sphere = step.sphere`, shared per step |
33
- | Error projection | `errorDistance = max(minDistance, sphereDistance - radius·uniformScale)`; test is `error·scale / errorDistance ≥ threshold` | `r_e · h / (2·tan(fov/2)·d)`, `d` = distance to the sphere's closest point |
34
- | Simplify to a ratio of triangles | `target_size = (merged/3 · simplify_ratio) · 3` | `simplification_ratio = 0.5` |
35
- | Coarsest LOD always resident | lowest-detail group of every geometry loaded persistently, excluded from the budget | root page always resident |
36
- | Age/LRU eviction | `stream_agefilter_groups.comp.glsl` | touch-LRU |
37
- | Blob alignment | group blobs 16-byte aligned, sections relative to the group base | frames 16-byte aligned, page-relative offsets |
38
-
39
- ## 2. The architectural fork: it traverses, and it traverses on the GPU
40
-
41
- Design §4 pins the cut as "evaluated independently per cluster, no traversal". This sample
42
- does the opposite and does it entirely device-side, and the machinery it uses is the answer
43
- to the objection that made meep pick the flat rule.
44
-
45
- ### 2.1 There is a node hierarchy above the DAG
46
-
47
- The thing traversed is **not** the cluster DAG. It is a separate tree of `Node`s whose leaves
48
- are groups:
49
-
50
- ```
51
- Node_packed_nodeChildCountMinusOne
52
- Node_packed_nodeChildOffset // index into geometry.nodes
53
- Node_packed_isGroup
54
- Node_packed_groupIndex // when isGroup
55
- traversalMetric // bounding sphere + maxQuadricError
56
- ```
57
-
58
- Each LOD level gets its own node tree over that level's groups, and "all lod levels' node
59
- trees are then linked together at the root of the hierarchy". Descending is one test per
60
- node: `testForTraversal` on the node's own metric; an inner node enqueues its children, a
61
- group node enqueues the group, whose clusters are then emitted.
62
-
63
- **Correction (later revision).** This section originally said "meep has no equivalent
64
- structure". That is wrong. meep's **pages already form a rooted, acyclic, fully-reachable
65
- DAG** — all three properties stated in VGEO_FORMAT §11.3–11.4 and enforced by the validator
66
- — and it is a real DAG, not a chain: on a 98k-triangle sphere at 32 KB pages, 91 pages, 291
67
- edges, in-degree up to 7, and 82 of the 91 pages have more than one parent. What meep lacks
68
- is not a hierarchy but a **metric on the one it has**: a child-table entry carries enough to
69
- *fetch* a page and nothing with which to decide whether to. See
70
- [VIRTUAL_GEOMETRY_PLAN.md](./VIRTUAL_GEOMETRY_PLAN.md) §2.2, which supersedes this paragraph.
71
-
72
- What remains true is the difference in *granularity*. nvpro's nodes cover groups; a page
73
- covers a band's worth of them. Node granularity is what buys fine culling and width at the
74
- top; page granularity is what buys the decision that actually costs money, which is whether
75
- to fetch. Both now exist: a metric on every child-table entry and page header, and a group
76
- tree inside each page (VGEO_FORMAT §6.1–6.2), at 0.3%–1.6% of asset size.
77
-
78
- ### 2.2 Culling skips subtrees, not clusters
79
-
80
- `processSubTask` frustum-tests each node and, with `USE_TWO_PASS_CULLING`, HiZ-tests it
81
- against the previous frame's depth pyramid. A node that fails takes its whole subtree with
82
- it. The flat rule cannot do this; it has already paid for every cluster by the time the
83
- per-view filters see them.
84
-
85
- (Design §4's claim that the cut is view-agnostic and reusable by shadow views has since been
86
- withdrawn — virtual geometry is view-dependent, and this sample pays for a traversal per view
87
- because that is what the problem costs.)
88
-
89
- ### 2.3 Streaming residency is the traversal's stopping condition
90
-
91
- ```glsl
92
- uint64_t groupAddress = geometry.streamingGroupAddresses.d[groupIndex];
93
- if (groupAddress >= STREAMING_INVALID_ADDRESS_START) {
94
- traverseNode = false; // stop descending here
95
- uint64_t last = atomicMax(geometry.streamingGroupAddresses.d[groupIndex],
96
- streaming.request.frameIndex);
97
- bool triggerRequest = last != streaming.request.frameIndex; // dedupe within the frame
98
- ... // append to request.loadGeometryGroups
99
- }
100
- ```
101
-
102
- Two things fall out of this that meep pays for separately:
103
-
104
- - **The residency clamp is free.** Design §4 needs an explicit "or child group
105
- non-selectable" clause in the cut rule, and calls it "what makes *no holes, ever* true".
106
- A traversal simply stops, and the coarser ancestor it already passed is the stand-in. No
107
- clamp, no selectable bit, no group-atomic flag to keep coherent.
108
- - **The want-list needs no structure of its own.** An invalid address *is* the request slot:
109
- the top bit marks it invalid, the low 63 bits hold the frame index, and `atomicMax` both
110
- records the request and deduplicates it within the frame. meep's design has pages emitting
111
- "wants" resolved from the emitting page; this is finer-grained (per group) and costs one
112
- 64-bit slot per group that had to exist anyway.
113
-
114
- ### 2.4 Persistent threads make DAG traversal data-parallel
115
-
116
- `traversal_run.comp.glsl` runs a fixed thread pool over a producer/consumer queue —
117
- `traversalNodeInfos` with separate atomic read and write counters and an in-flight
118
- `traversalTaskCounter`. Variable child counts are packed densely across a subgroup with a
119
- prefix sum (`subgroupInclusiveAdd`), and enqueues avoid per-thread atomics via ballot:
120
-
121
- ```glsl
122
- uvec4 voteNodes = subgroupBallot(traverseNode);
123
- if (subgroupElect()) { offsetNodes = atomicAdd(buildRW.traversalNodeWriteCounter, countNodes); ... }
124
- offsetNodes = subgroupBroadcastFirst(offsetNodes) + subgroupBallotExclusiveBitCount(voteNodes);
125
- ```
126
-
127
- This is the piece worth taking whichever cut rule wins. "Traversal is serial" is not true of
128
- this shape, and Shade already has the subgroup primitives (the one-sweep radix sort uses
129
- them).
130
-
131
- ## 3. Build-side ideas worth borrowing
132
-
133
- ### 3.1 Error composition is a tunable blend, not pure addition
134
-
135
- ```cpp
136
- bounds.error = std::max(bounds.error * config.simplify_error_merge_previous, error)
137
- + error * config.simplify_error_merge_additive;
138
- ```
139
-
140
- meep composes purely additively: `sqrt(residual) + max(child error)`. Design §4 justifies
141
- that with the triangle inequality and notes that a plain max does not bound cumulative
142
- drift. meshopt splits the difference and exposes both coefficients. Since pure addition
143
- demonstrably over-scales (§4 says so itself), and pure max under-bounds, a blend with the
144
- two coefficients as build options is strictly more expressive than what meep has, and costs
145
- one line.
146
-
147
- ### 3.2 A stuck detector with an escalation ladder
148
-
149
- Simplification is "considered stuck if the result exceeds `merged.size() *
150
- simplify_threshold`", and the builder then falls back from
151
- `meshopt_simplifyWithAttributes` to **permissive**, then to **sloppy** mode, with
152
- `simplify_error_factor_sloppy` inflating the recorded error to pay for the reduced fidelity.
153
-
154
- meep's ladder is: simplify at ratio → if the re-split produced nothing, pass the group
155
- through unchanged → if no band or group size makes progress, throw. There is no middle rung.
156
- A permissive mode (allow non-manifold collapses, allow boundary movement where the boundary
157
- is not a group seam) with an honest error penalty would let the builder reduce in exactly the
158
- cases where it currently gives up — and those cases are real: the boundary-quadric gap in
159
- design §2 means open geometry reduces at recorded-zero error today, which is worse than
160
- reducing at an inflated one.
161
-
162
- > **Since this was written**: boundary constraint quadrics landed (plan §4.1), so that closing
163
- > argument is spent — open geometry no longer reduces at recorded-zero error, and the choice is
164
- > no longer between an honest inflated error and a dishonest zero. The case for a middle rung
165
- > survives it, but it is now the plain one: a group that cannot be reduced is carried forward
166
- > untouched, and enough of those is what makes a build fail to converge and throw. Plan §2.1
167
- > records that the sloppy-mode escalation is *safe* to build now for the same reason.
168
-
169
- ### 3.3 A minimum cluster size
170
-
171
- `meshopt_buildMeshletsFlex` takes `min_triangles` as well as `max_triangles`, so a cluster
172
- can float within a band instead of being whatever the partition left behind.
173
-
174
- meep's splitter caps and never floors. Measured fill on the current builder runs 120
175
- tris/cluster at the leaves down to 67 at the coarse levels. A floor, enforced by merging
176
- under-filled pieces the way `pack_pieces` already does inside a group, would close that.
177
-
178
- > **Since this was written**: the leaf half landed (plan §1). A group of leaves with room to
179
- > spare between them is *re-cut* into fewer and fuller leaves rather than simplified —
180
- > `try_repack` in `vgeo_build_levels.js` — and the re-cut **replaces** them rather than
181
- > becoming their parent, because a step of zero error is a step the cut rule can never take.
182
- > Only leaves: above them the same re-cut would orphan a subtree. So the 120-at-the-leaves half
183
- > of that measurement is addressed and the 67-at-the-coarse-levels half still stands.
184
-
185
- ### 3.4 Spatial variants at every partitioning step
186
-
187
- `clusterize()` picks `meshopt_buildMeshletsSpatial()` or `meshopt_buildMeshletsFlex()` on
188
- `config.cluster_spatial`; `partition()` passes `partition_spatial` to
189
- `meshopt_partitionClusters()`; groups are then reordered with `meshopt_spatialSortRemap()`.
190
- Spatial partitioning is a first-class option at every level, not a fallback.
191
-
192
- meep uses connectivity everywhere and falls back to Morton proximity only when a cluster is
193
- alone in its component. That ordering is defensible — it keeps clusters connected, which the
194
- design pins — but "spatial or connectivity" being a build *option* rather than a hardcoded
195
- policy is worth copying, because the right answer is plainly content-dependent: a scanned
196
- surface wants connectivity, a CAD assembly of loose parts wants space.
197
-
198
- Also note groups are sized "around `partition_size`" but "may be up to 1/3 larger" — soft
199
- group sizes, like meep's.
200
-
201
- ### 3.5 Mantissa-bit dropping instead of quantization
202
-
203
- The README recommends "mantissa-bit dropping for positions and UVs" ahead of the lossless
204
- group compression.
205
-
206
- Design §2 lists cluster-local position quantization as new work "spanning encode, metadata
207
- struct, and every decode shader" — a large, invasive change. Dropping low mantissa bits of
208
- float32 keeps the layout, the struct and every decode shader **exactly as they are** and
209
- simply makes the bytes compress. It is not a substitute for quantization's memory win, but
210
- it is a fraction of the work for a real share of the benefit, and it composes with a page
211
- codec meep has not chosen yet (§12 lists it as open).
212
-
213
- ## 4. Runtime ideas that need a small format change
214
-
215
- ### 4.1 Per-level summary table → conservative instance LOD brackets
216
-
217
- `instance_classify_lod.comp.glsl` computes, per instance, a conservative **minimum and
218
- maximum LOD level**:
219
-
220
- - min: evaluate the metric at the closest point of the instance sphere, using *each level's
221
- maximum error*; take the first level that passes.
222
- - max: place a sphere at the far end of the instance's bounding sphere and use the smallest
223
- cluster group's error and radius as a worst case.
224
-
225
- This is sound because "successive LoD levels have monotonically increasing error/radius", so
226
- the transition cannot happen later than the bracket says.
227
-
228
- What it enables in this sample is BLAS sharing — one instance's acceleration structure
229
- reused by every other instance of that geometry whose bracket allows it. Measured on their
230
- LEGO scene: **3.9 ms → 1.6 ms frame time, 62 MB → 9 MB**. The stated limitation is that
231
- distant objects then render more detail than they need, and that one shared BLAS per
232
- geometry is a simplification they have not lifted.
233
-
234
- The bracket itself is worth more to meep than the BLAS trick. It needs one thing the format
235
- does not have: a **per-level summary table in the header** — `(max_error, max_radius,
236
- cluster_count)` per level, `level_count` entries. The builder already computes exactly this
237
- (`VGeoLevelSummary.max_error`) and throws it away at write time. With it, a runtime can:
238
-
239
- - bracket every instance without touching a single cluster record;
240
- - collapse instances whose bracket is one level onto a single shared cut, which is the whole
241
- ballgame for a CAD scene of ten thousand identical fasteners;
242
- - prefetch precisely the bands a bracket spans, rather than discovering them by traversal.
243
-
244
- This is the cheapest high-leverage format change on this list, and it is additive — a table
245
- after the header, or a reserved-field pointer to it.
246
-
247
- ### 4.2 Clamp the distance rather than special-casing the camera inside the sphere
248
-
249
- `errorDistance = max(minDistance, sphereDistance - radius·uniformScale)`.
250
-
251
- Design §4 handles the same degeneracy with a convention: "the camera-inside-sphere ⇒ +∞
252
- convention applies only when `r_e > 0` (otherwise leaves become undrawable exactly at close
253
- range)". A `minDistance` clamp gets the same behaviour with no qualifier and no branch —
254
- inside the sphere, the error is simply large but finite, and a zero-error leaf still projects
255
- to zero.
256
-
257
- ### 4.3 GPU-driven allocation beats host estimates
258
-
259
- `docs/clas_allocation.md` reports host-side size estimates being "way too conservative (e.g.
260
- often 3-5x bigger than actual)" and moves allocation on-device with a readback for the real
261
- sizes. Two allocator designs are given: naive dense compaction (discouraged — "high memory
262
- movement bursts") and a **persistent device-resident allocator that moves an allocation only
263
- once, after construction**, with a free-gap list maintained on the GPU
264
- (`stream_allocator_build_freegaps.comp.glsl`,
265
- `stream_allocator_freegaps_insert.comp.glsl`).
266
-
267
- Design §2 records the mirror-image problem on meep's side: `GPUMeshletManager`'s
268
- compaction/growth is a CPU-side rebuild costing ~2× VRAM transiently, and meshlet-address
269
- migration is an unhandled TODO. A device-resident free-gap allocator that relocates once is
270
- the shape of the answer, and there is a working one to read.
271
-
272
- ## 5. Not applicable, or deliberately different
273
-
274
- - **Ray tracing (CLAS/BLAS)** — `VK_NV_cluster_acceleration_structure` has no WebGPU
275
- equivalent and will not for years. BLAS caching, merging and sharing are all downstream of
276
- it. The *LOD-bracket* idea behind sharing (§4.1) is the transferable part.
277
- - **DLSS** — vendor-specific.
278
- - **Mesh shaders** — Shade's bucket pipeline issues `drawIndirect` per material with
279
- instanceCount = meshlet count, which is the WebGPU-shaped equivalent; nothing to change.
280
- - **Their scene format** — `.nvsngeo` is a cache, not a streaming container: it has no page
281
- structure, no directory, no integrity model, and no content addressing. `.vgeo` is ahead
282
- here, and deliberately so.
283
-
284
- ## 6. Recommendation
285
-
286
- In order of leverage per unit of work:
287
-
288
- 1. **Write the per-level summary table into the header** (§4.1). Cheap, additive, and it is
289
- the prerequisite for instance bracketing, shared cuts and precise prefetch.
290
- 2. **Blend the error composition** (§3.1) and **clamp the distance** (§4.2). Two lines each,
291
- both strictly better than what is pinned.
292
- 3. **Build a node hierarchy over groups** (§2.1), even if the cut stays flat — it is what
293
- makes subtree culling and prefetch possible at all, and it does not touch cluster records.
294
- 4. **Measure the flat rule against a traversal at scale before treating §4's "no traversal"
295
- as settled** (§2.2, §2.4). The persistent-thread + subgroup-ballot scheme removes the
296
- parallelism objection; the residency clamp and the want-list both get simpler if traversal
297
- wins (§2.3).
298
- 5. **A stuck detector with a permissive fallback** (§3.2) and **a minimum cluster size**
299
- (§3.3) — both address measured weaknesses in the current builder.
300
- 6. **Mantissa-bit dropping** (§3.5) as the cheap first move on payload size, ahead of full
301
- quantization.