@woosh/meep-engine 3.60.4 → 3.60.5

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 (379) hide show
  1. package/CHANGELOG.md +2602 -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.map +1 -1
  63. package/src/shade/renderer/Renderer.js +7 -5
  64. package/src/shade/renderer/camera/orbital/OrbitalCameraController.d.ts +40 -80
  65. package/src/shade/renderer/camera/orbital/OrbitalCameraController.d.ts.map +1 -1
  66. package/src/shade/renderer/camera/orbital/OrbitalCameraController.js +197 -147
  67. package/src/shade/renderer/fluid/GPUFluidCascade.d.ts +3 -3
  68. package/src/shade/renderer/fluid/GPUFluidCascadeStack.d.ts +1 -1
  69. package/src/shade/renderer/fluid/forcing/GPUFluidForcing.d.ts +6 -6
  70. package/src/shade/renderer/fluid/pressure/GPUFluidPressureSolve.d.ts +1 -1
  71. package/src/shade/renderer/fluid/query/GPUFluidQueries.d.ts +1 -1
  72. package/src/shade/renderer/geometry/sdf/GPUGeometrySDFManager.d.ts +2 -2
  73. package/src/shade/renderer/geometry/sdf/GPUGeometrySDFManager.js +2 -2
  74. package/src/shade/renderer/geometry/sdf/cards/GPUMeshCardSets.d.ts +2 -1
  75. package/src/shade/renderer/geometry/sdf/cards/GPUMeshCardSets.d.ts.map +1 -1
  76. package/src/shade/renderer/geometry/sdf/cards/GPUMeshCardSets.js +18 -1
  77. package/src/shade/renderer/geometry/virtual/proxy/vgeo_to_proxy_mesh.d.ts +31 -0
  78. package/src/shade/renderer/geometry/virtual/proxy/vgeo_to_proxy_mesh.d.ts.map +1 -0
  79. package/src/shade/renderer/geometry/virtual/proxy/vgeo_to_proxy_mesh.js +343 -0
  80. package/src/shade/renderer/geometry/virtual/runtime/vgeo_meshlet_metadata_write.d.ts +17 -0
  81. package/src/shade/renderer/geometry/virtual/runtime/vgeo_meshlet_metadata_write.d.ts.map +1 -0
  82. package/src/shade/renderer/geometry/virtual/runtime/vgeo_meshlet_metadata_write.js +29 -0
  83. package/src/shade/renderer/geometry/virtual/runtime/vgeo_runtime_meshlet_batch.d.ts.map +1 -1
  84. package/src/shade/renderer/geometry/virtual/runtime/vgeo_runtime_meshlet_batch.js +7 -13
  85. package/src/shade/renderer/global_illumination/probe_clipmap/GPUProbeClipmapGI.d.ts.map +1 -1
  86. package/src/shade/renderer/global_illumination/probe_clipmap/GPUProbeClipmapGI.js +1 -8
  87. package/src/shade/renderer/global_illumination/probe_clipmap/ProbeClipmapSceneHolds.d.ts +5 -5
  88. package/src/shade/renderer/global_illumination/probe_clipmap/ProbeClipmapSceneHolds.d.ts.map +1 -1
  89. package/src/shade/renderer/global_illumination/probe_clipmap/ProbeClipmapSceneHolds.js +10 -10
  90. package/src/shade/renderer/global_illumination/probe_clipmap/probe/GPUProbeClipmap.d.ts +1 -4
  91. package/src/shade/renderer/global_illumination/probe_clipmap/probe/GPUProbeClipmap.d.ts.map +1 -1
  92. package/src/shade/renderer/global_illumination/probe_clipmap/probe/GPUProbeClipmap.js +1 -10
  93. package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap_hit_surface.d.ts +5 -15
  94. package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap_hit_surface.d.ts.map +1 -1
  95. package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap_hit_surface.js +6 -34
  96. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_shade.d.ts.map +1 -1
  97. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_shade.js +1 -7
  98. package/src/shade/renderer/hiz/HZBFootprint.d.ts +14 -0
  99. package/src/shade/renderer/hiz/HZBFootprint.d.ts.map +1 -0
  100. package/src/shade/renderer/hiz/HZBFootprint.js +16 -0
  101. package/src/shade/renderer/hiz/HZB_FOOTPRINT_X.d.ts +10 -0
  102. package/src/shade/renderer/hiz/HZB_FOOTPRINT_X.d.ts.map +1 -0
  103. package/src/shade/renderer/hiz/HZB_FOOTPRINT_X.js +11 -0
  104. package/src/shade/renderer/hiz/HZB_FOOTPRINT_Y.d.ts +10 -0
  105. package/src/shade/renderer/hiz/HZB_FOOTPRINT_Y.d.ts.map +1 -0
  106. package/src/shade/renderer/hiz/HZB_FOOTPRINT_Y.js +11 -0
  107. package/src/shade/renderer/hiz/HierarchicalZBuffer.d.ts +0 -7
  108. package/src/shade/renderer/hiz/HierarchicalZBuffer.d.ts.map +1 -1
  109. package/src/shade/renderer/hiz/HierarchicalZBuffer.js +405 -350
  110. package/src/shade/renderer/hiz/chunk_hzb_footprint_x.d.ts +12 -0
  111. package/src/shade/renderer/hiz/chunk_hzb_footprint_x.d.ts.map +1 -0
  112. package/src/shade/renderer/hiz/chunk_hzb_footprint_x.js +27 -0
  113. package/src/shade/renderer/hiz/chunk_hzb_footprint_y.d.ts +12 -0
  114. package/src/shade/renderer/hiz/chunk_hzb_footprint_y.d.ts.map +1 -0
  115. package/src/shade/renderer/hiz/chunk_hzb_footprint_y.js +27 -0
  116. package/src/shade/renderer/hiz/hzb_footprint_texels.d.ts +14 -0
  117. package/src/shade/renderer/hiz/hzb_footprint_texels.d.ts.map +1 -0
  118. package/src/shade/renderer/hiz/hzb_footprint_texels.js +34 -0
  119. package/src/shade/renderer/hiz/shader_hzb_reduce_any.d.ts +0 -5
  120. package/src/shade/renderer/hiz/shader_hzb_reduce_any.d.ts.map +1 -1
  121. package/src/shade/renderer/hiz/shader_hzb_reduce_any.js +37 -57
  122. package/src/shade/renderer/hiz/shader_hzb_reduce_mip0.d.ts +11 -0
  123. package/src/shade/renderer/hiz/shader_hzb_reduce_mip0.d.ts.map +1 -0
  124. package/src/shade/renderer/hiz/{shader_hzb_reduce_mip0_clip.js → shader_hzb_reduce_mip0.js} +120 -111
  125. package/src/shade/renderer/loader/gltf/tiny-gltf.d.ts +1 -1
  126. package/src/shade/renderer/material/GPUMaterialManager.d.ts +7 -0
  127. package/src/shade/renderer/material/GPUMaterialManager.d.ts.map +1 -1
  128. package/src/shade/renderer/material/GPUMaterialManager.js +11 -0
  129. package/src/shade/renderer/material/resident/GPUResidentMaterialContext.d.ts +12 -12
  130. package/src/shade/renderer/material/resident/GPUResidentMaterialContext.d.ts.map +1 -1
  131. package/src/shade/renderer/material/resident/GPUResidentMaterialContext.js +17 -118
  132. package/src/shade/renderer/shadow/map/GPUSceneShadowmapContext.d.ts.map +1 -1
  133. package/src/shade/renderer/shadow/map/GPUSceneShadowmapContext.js +7 -2
  134. package/src/shade/renderer/water/GPUWaterRenderer.d.ts +0 -6
  135. package/src/shade/renderer/water/GPUWaterRenderer.d.ts.map +1 -1
  136. package/src/shade/renderer/water/GPUWaterRenderer.js +12 -17
  137. package/src/shade/renderer/water/medium/graph_water_meshlets.d.ts +35 -0
  138. package/src/shade/renderer/water/medium/graph_water_meshlets.d.ts.map +1 -0
  139. package/src/shade/renderer/water/medium/graph_water_meshlets.js +89 -0
  140. package/src/shade/renderer/water/query/GPUWaterQueries.d.ts +1 -1
  141. package/src/shade/renderer/water/shader_water.d.ts.map +1 -1
  142. package/src/shade/renderer/water/shader_water.js +22 -13
  143. package/src/shade/renderer/water/shader_water_avboit.d.ts.map +1 -1
  144. package/src/shade/renderer/water/shader_water_avboit.js +7 -7
  145. package/src/shade/renderer/water/surface/graph_water_tessellation.d.ts +1 -1
  146. package/src/shade/renderer/water/surface/graph_water_tessellation.js +1 -1
  147. package/src/shade/wgsl/emulator/WGSLJavaScriptCompiler.js +9 -1
  148. package/editor/REWORK_PLAN_2026_08.md +0 -692
  149. package/src/CODEC_LAYOUT_VERIFICATION.md +0 -419
  150. package/src/CORRECTNESS_HUNT_2026_07_24.md +0 -142
  151. package/src/DUPLICATION_AUDIT_2026_08_07/00_core_reuse_surface.md +0 -738
  152. package/src/DUPLICATION_AUDIT_2026_08_07/A_core_math_geom.md +0 -79
  153. package/src/DUPLICATION_AUDIT_2026_08_07/B_core_data.md +0 -93
  154. package/src/DUPLICATION_AUDIT_2026_08_07/C_gfx_render.md +0 -80
  155. package/src/DUPLICATION_AUDIT_2026_08_07/D_gfx_features.md +0 -164
  156. package/src/DUPLICATION_AUDIT_2026_08_07/E_physics.md +0 -69
  157. package/src/DUPLICATION_AUDIT_2026_08_07/F_sound.md +0 -110
  158. package/src/DUPLICATION_AUDIT_2026_08_07/G_net_save.md +0 -129
  159. package/src/DUPLICATION_AUDIT_2026_08_07/H_engine_misc.md +0 -72
  160. package/src/DUPLICATION_AUDIT_2026_08_07/I_generation_view.md +0 -74
  161. package/src/DUPLICATION_AUDIT_2026_08_07/K_crosscutting.md +0 -169
  162. package/src/DUPLICATION_AUDIT_2026_08_07.md +0 -254
  163. package/src/DUPLICATION_AUDIT_REMEDIATION.md +0 -250
  164. package/src/DUPLICATION_REVIEW_2026_10_24.md +0 -1072
  165. package/src/REVIEW_2026_08_06/adv-core.md +0 -511
  166. package/src/REVIEW_2026_08_06/adv-gfx.md +0 -480
  167. package/src/REVIEW_2026_08_06/adv-view.md +0 -446
  168. package/src/REVIEW_2026_08_06/api-core.md +0 -296
  169. package/src/REVIEW_2026_08_06/api-engine.md +0 -195
  170. package/src/REVIEW_2026_08_06/bvh-phys-sound-net.md +0 -507
  171. package/src/REVIEW_2026_08_06/core-binary.md +0 -348
  172. package/src/REVIEW_2026_08_06/core-collection.md +0 -376
  173. package/src/REVIEW_2026_08_06/core-math.md +0 -221
  174. package/src/REVIEW_2026_08_06/core-process.md +0 -266
  175. package/src/REVIEW_2026_08_06/core-science.md +0 -223
  176. package/src/REVIEW_2026_08_06/engine-ai-nav.md +0 -279
  177. package/src/REVIEW_2026_08_06/engine-animation.md +0 -167
  178. package/src/REVIEW_2026_08_06/engine-asset.md +0 -166
  179. package/src/REVIEW_2026_08_06/engine-ecs.md +0 -920
  180. package/src/REVIEW_2026_08_06/engine-input.md +0 -197
  181. package/src/REVIEW_2026_08_06/engine-misc.md +0 -248
  182. package/src/REVIEW_2026_08_06/engine-terrain.md +0 -52
  183. package/src/REVIEW_2026_08_06/generation.md +0 -176
  184. package/src/REVIEW_2026_08_06/geom-2d.md +0 -434
  185. package/src/REVIEW_2026_08_06/geom-3d.md +0 -117
  186. package/src/REVIEW_2026_08_06/gfx-gi.md +0 -143
  187. package/src/REVIEW_2026_08_06/gfx-render.md +0 -740
  188. package/src/REVIEW_2026_08_06/gfx-texture.md +0 -690
  189. package/src/REVIEW_2026_08_06/prior-criticals.md +0 -49
  190. package/src/REVIEW_2026_08_06/prior-highs.md +0 -138
  191. package/src/REVIEW_2026_08_06/test-gaps.md +0 -364
  192. package/src/REVIEW_2026_08_06/view.md +0 -667
  193. package/src/REVIEW_2026_08_06.md +0 -610
  194. package/src/core/binary/lz4/LZ4_HIGH_COMPRESSION_PLAN_2026_09_14.md +0 -542
  195. package/src/core/bvh2/bvh3/NOTES.md +0 -2
  196. package/src/core/bvh8/NOTES.md +0 -63
  197. package/src/core/cache/wtinylfu/benchmark/CacheWTinylfu.bench.md +0 -243
  198. package/src/core/color/COLOR_FIX_PLAN_2026_08_28.md +0 -417
  199. package/src/core/color/COLOR_REVIEW_2026_08_28.md +0 -779
  200. package/src/core/geom/2d/polygon/TRIANGULATION_DESIGN.md +0 -433
  201. package/src/core/geom/3d/atlas/ATLAS_PORT_PLAN.md +0 -486
  202. package/src/core/geom/3d/atlas/BFF_PLAN.md +0 -174
  203. package/src/core/geom/3d/atlas/REVIEW_02.md +0 -392
  204. package/src/core/geom/3d/gjk/GJK_REVIEW_NOTES.md +0 -146
  205. package/src/core/geom/3d/gjk/NOTES.md +0 -8
  206. package/src/core/geom/3d/topology/TOPO_MESH_RETIREMENT_PLAN.md +0 -135
  207. package/src/core/geom/GEOMETRY_REVIEW_002_API_ISSUES.md +0 -381
  208. package/src/core/geom/GEOMETRY_REVIEW_002_NAMING.md +0 -684
  209. package/src/core/geom/MANIFOLD_COMPARISON_2026_08_01.md +0 -554
  210. package/src/core/model/reactive/evaluation/PREDICATE_APPLICABILITY_PROPOSAL.md +0 -446
  211. package/src/engine/REVIEW_2026_07_03.md +0 -211
  212. package/src/engine/asset/loaders/image/IMAGE_CODEC_REVIEW_2026_08_28.md +0 -815
  213. package/src/engine/control/first-person/DESIGN.md +0 -658
  214. package/src/engine/control/first-person/DESIGN_COLLISION.md +0 -382
  215. package/src/engine/control/first-person/DESIGN_EXTENSIONS.md +0 -563
  216. package/src/engine/control/first-person/TODO.md +0 -160
  217. package/src/engine/ecs/ASYNC_SYSTEMS_PROPOSAL.md +0 -531
  218. package/src/engine/ecs/HIERARCHY_REVIEW.md +0 -717
  219. package/src/engine/ecs/async/WORKER_SYSTEM_PLAN.md +0 -262
  220. package/src/engine/ecs/ik/PLAN.md +0 -179
  221. package/src/engine/ecs/storage/binary/SERIALIZATION_COVERAGE.md +0 -272
  222. package/src/engine/ecs/storage/binary/object-v2/DESIGN.md +0 -199
  223. package/src/engine/ecs/transform/TRANSFORM64_MIGRATION_PLAN_2026_09_04.md +0 -521
  224. package/src/engine/graphics/CONTEXT_LOSS_RECOVERY_PLAN.md +0 -463
  225. package/src/engine/graphics/ecs/camera/pp/NOTES.md +0 -48
  226. package/src/engine/graphics/render/frame_graph/CORRECTNESS_FIXES_2026_09_04.md +0 -659
  227. package/src/engine/graphics/render/frame_graph/FRAME_GRAPH_RECOMMENDATIONS.md +0 -235
  228. package/src/engine/graphics/sh3/path_tracer/REVIEW_001_ACTION_PLAN.md +0 -490
  229. package/src/engine/graphics/texture/sampler/compare/FLIP_IMPLEMENTATION_PLAN.md +0 -466
  230. package/src/engine/input/GAMEPAD_API_PROPOSAL.md +0 -717
  231. package/src/engine/input/ecs/ism/ISM_DESIGN.md +0 -1523
  232. package/src/engine/input/ecs/ism/ISM_IMPLEMENTATION_PLAN.md +0 -627
  233. package/src/engine/navigation/mesh/OVERLAPPING_SURFACES_2026_08_25.md +0 -661
  234. package/src/engine/navigation/mesh/PATHFINDING_PLAN.md +0 -229
  235. package/src/engine/network/CONGESTION_CONTROL.md +0 -87
  236. package/src/engine/network/MESSAGE_TRANSPORT.md +0 -364
  237. package/src/engine/network/SMOOTHNESS_DESIGN.md +0 -400
  238. package/src/engine/physics/cloth/MEASUREMENTS.md +0 -5304
  239. package/src/engine/physics/cloth/PLAN.md +0 -3056
  240. package/src/engine/physics/fluid/GPU_FLUID_CASCADES_PROPOSAL_2026_10_16.md +0 -1382
  241. package/src/engine/physics/fluid/REVIEW_02_PLAN.md +0 -243
  242. package/src/engine/physics/fluid/solver/NOTES.md +0 -46
  243. package/src/engine/sound/SOUND_EMITTER_RETIREMENT_PLAN.md +0 -536
  244. package/src/engine/sound/simulation/IMPLEMENTATION_PLAN.md +0 -432
  245. package/src/engine/sound/simulation/PROBE_PLACEMENT.md +0 -250
  246. package/src/engine/sound/simulation/PROBE_TRANSFER_RESEARCH.md +0 -322
  247. package/src/engine/sound/simulation/REFLECTION_IR_PLAN.md +0 -261
  248. package/src/engine/sound/simulation/VISIBILITY_GRAPH_PLAN.md +0 -121
  249. package/src/engine/sound/sopra/IMPLEMENTATION_PLAN.md +0 -999
  250. package/src/format/image/avif/DECISIONS.md +0 -545
  251. package/src/format/image/jpeg/NOTES.md +0 -3
  252. package/src/format/scene/gltf/MESHOPT_COMPRESSION_PLAN.md +0 -814
  253. package/src/generation/COORDINATES.md +0 -54
  254. package/src/generation/REVIEW_01_ACTION_PLAN.md +0 -628
  255. package/src/generation/foliage/ANNUAL_SHOOTS_BRIEF_2026_10_25.md +0 -220
  256. package/src/generation/foliage/CROWN_FILLING_BRIEF_2026_10_26.md +0 -172
  257. package/src/generation/foliage/CROWN_FULLNESS_BRIEF_2026_10_26.md +0 -86
  258. package/src/generation/foliage/FOLIAGE_DESIGN.md +0 -547
  259. package/src/generation/foliage/FOLIAGE_PLAN.md +0 -198
  260. package/src/generation/foliage/LEAF_ARCHITECTURE_BRIEF_2026_10_26.md +0 -158
  261. package/src/generation/foliage/LOD_REWORK_BRIEF_2026_10_27.md +0 -521
  262. package/src/generation/foliage/REAL_TIME_TREES_BRIEF_2026_10_27.md +0 -86
  263. package/src/generation/foliage/SELF_ORGANIZING_FRAMEWORK_BRIEF_2026_10_26.md +0 -347
  264. package/src/generation/foliage/SHOOT_SYSTEMS_ALL_SPECIES_BRIEF_2026_10_26.md +0 -248
  265. package/src/generation/foliage/SPEEDTREE_COMPARISON_2026_10_24.md +0 -694
  266. package/src/generation/foliage/TWO_FRONT_ENDS_BRIEF_2026_10_28.md +0 -552
  267. package/src/shade/RENDERER_CONTRACT.md +0 -697
  268. package/src/shade/SHADER_F16_PROPOSAL_2026_10_24.md +0 -263
  269. package/src/shade/device/IMMEDIATE_DATA_PLAN_2026_08_28.md +0 -569
  270. package/src/shade/device/PASS_ENCODER_PROPOSAL_2026_08_31.md +0 -755
  271. package/src/shade/device/mock/EXTENSION_PROPOSAL_2026_08_22.md +0 -458
  272. package/src/shade/device/mock/IMPLEMENTATION_PLAN.md +0 -255
  273. package/src/shade/device/mock/REVIEW_2026_08_22.md +0 -527
  274. package/src/shade/device/timing/GPU_PROFILER_PROPOSAL_2026_08_28.md +0 -894
  275. package/src/shade/device/timing/profile/SGPT_FORMAT.md +0 -345
  276. package/src/shade/renderer/NOTES.md +0 -78
  277. package/src/shade/renderer/PLAN.md +0 -8
  278. package/src/shade/renderer/animation/ADDITIVE_BLENDING_PLAN.md +0 -145
  279. package/src/shade/renderer/animation/SKINNING_FRAME_PLAN.md +0 -357
  280. package/src/shade/renderer/atmosphere/NOTES.md +0 -6
  281. package/src/shade/renderer/camera/orbital/MomentumAxis.d.ts +0 -76
  282. package/src/shade/renderer/camera/orbital/MomentumAxis.d.ts.map +0 -1
  283. package/src/shade/renderer/camera/orbital/MomentumAxis.js +0 -164
  284. package/src/shade/renderer/camera/orbital/OrbitalCameraConfig.d.ts +0 -45
  285. package/src/shade/renderer/camera/orbital/OrbitalCameraConfig.d.ts.map +0 -1
  286. package/src/shade/renderer/camera/orbital/OrbitalCameraConfig.js +0 -66
  287. package/src/shade/renderer/camera/orbital/OrbitalCameraInput.d.ts +0 -98
  288. package/src/shade/renderer/camera/orbital/OrbitalCameraInput.d.ts.map +0 -1
  289. package/src/shade/renderer/camera/orbital/OrbitalCameraInput.js +0 -184
  290. package/src/shade/renderer/camera/orbital/OrbitalCameraRig.d.ts +0 -175
  291. package/src/shade/renderer/camera/orbital/OrbitalCameraRig.d.ts.map +0 -1
  292. package/src/shade/renderer/camera/orbital/OrbitalCameraRig.js +0 -411
  293. package/src/shade/renderer/camera/orbital/README.md +0 -81
  294. package/src/shade/renderer/camera/orbital/index.d.ts +0 -6
  295. package/src/shade/renderer/camera/orbital/index.d.ts.map +0 -1
  296. package/src/shade/renderer/camera/orbital/index.js +0 -9
  297. package/src/shade/renderer/extension/RENDER_EXTENSION_DESIGN.md +0 -964
  298. package/src/shade/renderer/fluid/GPU_FLUID_OCCUPANCY_AND_SOTA_REVIEW_2026_10_26.md +0 -361
  299. package/src/shade/renderer/geometry/bvh/BLAS_REFIT_BATCH_PLAN.md +0 -619
  300. package/src/shade/renderer/geometry/meshlet/COMPACTION_PLAN_2026_09_16.md +0 -674
  301. package/src/shade/renderer/geometry/sdf/NOTES.md +0 -6
  302. package/src/shade/renderer/geometry/virtual/ATTRIBUTE_PLAN_2026_09_18.md +0 -540
  303. package/src/shade/renderer/geometry/virtual/MICRON_COMPARISON_2026_08_20.md +0 -305
  304. package/src/shade/renderer/geometry/virtual/VGEO_FORMAT.md +0 -913
  305. package/src/shade/renderer/geometry/virtual/VIRTUAL_GEOMETRY_DESIGN.md +0 -787
  306. package/src/shade/renderer/geometry/virtual/VIRTUAL_GEOMETRY_PLAN.md +0 -481
  307. package/src/shade/renderer/geometry/virtual/VK_LOD_CLUSTERS_COMPARISON_2026_08_20.md +0 -301
  308. package/src/shade/renderer/geometry/virtual/WEDGE_PLAN_2026_09_18.md +0 -448
  309. package/src/shade/renderer/geometry/virtual/runtime/CULL_PLAN_2026_09_16.md +0 -385
  310. package/src/shade/renderer/geometry/virtual/runtime/CUT_PLAN_2026_09_14.md +0 -656
  311. package/src/shade/renderer/geometry/virtual/runtime/REVIEW_LEDGER.md +0 -308
  312. package/src/shade/renderer/geometry/virtual/runtime/RUNTIME_PLAN.md +0 -657
  313. package/src/shade/renderer/geometry/virtual/runtime/RUNTIME_PLAN_2026_09_14.md +0 -551
  314. package/src/shade/renderer/geometry/virtual/runtime/SHADOW_PLAN_2026_09_28.md +0 -529
  315. package/src/shade/renderer/global_illumination/lpv/NOTES.md +0 -3
  316. package/src/shade/renderer/global_illumination/probe_clipmap/PROBE_CLIPMAP_PROPOSAL_2026_10_27.md +0 -4306
  317. package/src/shade/renderer/global_illumination/probe_clipmap/PROBE_RAYS_VARIABLE_AND_SORTED_SCOPE_2026_10_30.md +0 -410
  318. package/src/shade/renderer/global_illumination/sharc/NOTES.md +0 -8
  319. package/src/shade/renderer/gpu_primitive/bvh/GPU_BVH_BUILD_PLAN.md +0 -1369
  320. package/src/shade/renderer/gpu_primitive/bvh/PHASE1_HANDOVER.md +0 -202
  321. package/src/shade/renderer/gpu_primitive/indirect/NOTES.md +0 -94
  322. package/src/shade/renderer/hiz/NOTES.md +0 -3
  323. package/src/shade/renderer/hiz/shader_hzb_reduce_mip0_clip.d.ts +0 -8
  324. package/src/shade/renderer/hiz/shader_hzb_reduce_mip0_clip.d.ts.map +0 -1
  325. package/src/shade/renderer/light/cluster/NOTES.md +0 -11
  326. package/src/shade/renderer/light/cluster/PROPOSAL_ALGORITHM_2026_10_16.md +0 -524
  327. package/src/shade/renderer/light/cluster/PROPOSAL_HIERARCHICAL_2026_10_16.md +0 -1101
  328. package/src/shade/renderer/material/resident/shader_resident_texture_means.d.ts +0 -24
  329. package/src/shade/renderer/material/resident/shader_resident_texture_means.d.ts.map +0 -1
  330. package/src/shade/renderer/material/resident/shader_resident_texture_means.js +0 -120
  331. package/src/shade/renderer/particles/DESIGN.md +0 -1011
  332. package/src/shade/renderer/particles/EMITTER_GLOBAL_STATE_PLAN_2026_10_29.md +0 -280
  333. package/src/shade/renderer/particles/ORIENTATION_PLAN_2026_10_15.md +0 -453
  334. package/src/shade/renderer/path_tracer/PATH_TRACED_MEDIA_PLAN_2026_10_02.md +0 -520
  335. package/src/shade/renderer/postprocess/bloom/NOTES.md +0 -6
  336. package/src/shade/renderer/postprocess/fsr/NOTES.md +0 -4
  337. package/src/shade/renderer/postprocess/gtao/NOTES.md +0 -6
  338. package/src/shade/renderer/postprocess/nss/NOTES.md +0 -332
  339. package/src/shade/renderer/postprocess/perspective/NOTES.md +0 -3
  340. package/src/shade/renderer/postprocess/sscs/NOTES.md +0 -5
  341. package/src/shade/renderer/postprocess/ssr/NOTES.md +0 -14
  342. package/src/shade/renderer/postprocess/ssr/REPROJECTION_PROPOSAL.md +0 -286
  343. package/src/shade/renderer/postprocess/ssr/prefilter/NOTES.md +0 -39
  344. package/src/shade/renderer/postprocess/taa/NOTES.md +0 -11
  345. package/src/shade/renderer/postprocess/upscale-dither/NOTES.md +0 -78
  346. package/src/shade/renderer/postprocess/vrs/NOTES.md +0 -4
  347. package/src/shade/renderer/rasterize/native/avboit/AVBOIT_LEDGER.md +0 -1218
  348. package/src/shade/renderer/rasterize/native/avboit/AVBOIT_PLAN_2026_09_03.md +0 -600
  349. package/src/shade/renderer/restir/reservoir/NOTES.md +0 -6
  350. package/src/shade/renderer/shader/chunk/atmosphere/NOTES.md +0 -6
  351. package/src/shade/renderer/shader/chunk/brdf/FRESNEL_BRIEF_2026_10_16.md +0 -391
  352. package/src/shade/renderer/shader/chunk/color/tonemap/ACES_TONE_MAPPING_BRIEF_2026_10_17.md +0 -153
  353. package/src/shade/renderer/shader/chunk/color/tonemap/HDR_TONE_MAPPING_FORMS_BRIEF_2026_10_16.md +0 -322
  354. package/src/shade/renderer/shader/chunk/color/tonemap/SDR_TONE_MAPPING_BRIEF_2026_10_16.md +0 -247
  355. package/src/shade/renderer/shader/chunk/fsr/NOTES.md +0 -3
  356. package/src/shade/renderer/shader/chunk/fsr/spd/NOTES.md +0 -4
  357. package/src/shade/renderer/shader/chunk/geometry/ray/NOTES.md +0 -4
  358. package/src/shade/renderer/shader/chunk/material/MULTISCATTER.md +0 -159
  359. package/src/shade/renderer/shader/chunk/mboit/NOTES.md +0 -38
  360. package/src/shade/renderer/shader/chunk/spherical_harmonics/l1i/NOTES.md +0 -3
  361. package/src/shade/renderer/shader/chunk/spherical_harmonics/sampling/NOTES.md +0 -8
  362. package/src/shade/renderer/shader/compiler/SHADER_SWITCH_PROPOSAL_2026_10_16.md +0 -927
  363. package/src/shade/renderer/shadow/contact/FINDINGS.md +0 -413
  364. package/src/shade/renderer/shadow/map/csm/NOTES.md +0 -5
  365. package/src/shade/renderer/shadow/ray/NOTES.md +0 -31
  366. package/src/shade/renderer/shadow/sdf/NOTES.md +0 -9
  367. package/src/shade/renderer/shadow/sdf/brixelizer/NOTES.md +0 -5
  368. package/src/shade/renderer/shadow/sdf/cascade/NOTES.md +0 -9
  369. package/src/shade/renderer/shadow/vsm/NOTES.md +0 -12
  370. package/src/shade/renderer/shadow/vsm/PLAN.md +0 -442
  371. package/src/shade/renderer/shadow/vsm/REVIEW_LEDGER.md +0 -43
  372. package/src/shade/renderer/texture/COMPRESSED_TEXTURE_PLAN_2026_09_01.md +0 -2444
  373. package/src/shade/renderer/texture/mipmaps/NOTES.md +0 -3
  374. package/src/shade/renderer/volumetrics/NOTES.md +0 -1329
  375. package/src/shade/renderer/volumetrics/VOLUMETRIC_NOISE_PLAN_2026_10_15.md +0 -336
  376. package/src/shade/renderer/water/medium/GPUWaterBodies.d.ts +0 -23
  377. package/src/shade/renderer/water/medium/GPUWaterBodies.d.ts.map +0 -1
  378. package/src/shade/renderer/water/medium/GPUWaterBodies.js +0 -75
  379. 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.