@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.
- package/CHANGELOG.md +2621 -0
- package/CONTRIBUTING.md +7 -0
- package/MIGRATION_2_TO_3.md +136 -0
- package/SECURITY.md +4 -0
- package/editor/EditorCameraNavigation.d.ts +2 -1
- package/editor/EditorCameraNavigation.d.ts.map +1 -1
- package/editor/EditorCameraNavigation.js +51 -57
- package/package.json +6 -2
- package/src/engine/EngineHarness.d.ts +3 -9
- package/src/engine/EngineHarness.d.ts.map +1 -1
- package/src/engine/EngineHarness.js +6 -8
- package/src/engine/graphics/camera/makeOrbitalCameraController.d.ts +9 -6
- package/src/engine/graphics/camera/makeOrbitalCameraController.d.ts.map +1 -1
- package/src/engine/graphics/camera/makeOrbitalCameraController.js +44 -71
- package/src/engine/graphics/camera/orbital/MomentumAxis.d.ts +64 -0
- package/src/engine/graphics/camera/orbital/MomentumAxis.d.ts.map +1 -0
- package/src/engine/graphics/camera/orbital/MomentumAxis.js +187 -0
- package/src/engine/graphics/camera/orbital/OrbitalCameraRig.d.ts +86 -0
- package/src/engine/graphics/camera/orbital/OrbitalCameraRig.d.ts.map +1 -0
- package/src/engine/graphics/camera/orbital/OrbitalCameraRig.js +319 -0
- package/src/engine/graphics/ecs/camera/topdown/TopDownCameraController.d.ts +34 -10
- package/src/engine/graphics/ecs/camera/topdown/TopDownCameraController.d.ts.map +1 -1
- package/src/engine/graphics/ecs/camera/topdown/TopDownCameraController.js +116 -30
- package/src/engine/graphics/ecs/camera/topdown/TopDownCameraControllerSystem.d.ts +1 -7
- package/src/engine/graphics/ecs/camera/topdown/TopDownCameraControllerSystem.d.ts.map +1 -1
- package/src/engine/graphics/ecs/camera/topdown/TopDownCameraControllerSystem.js +1 -37
- package/src/engine/graphics/ecs/water/Water.d.ts +8 -0
- package/src/engine/graphics/ecs/water/Water.d.ts.map +1 -1
- package/src/engine/graphics/ecs/water/Water.js +8 -0
- package/src/engine/graphics3/WaterSystem.d.ts.map +1 -1
- package/src/engine/graphics3/WaterSystem.js +731 -734
- package/src/engine/graphics3/decal/DecalTileShader.d.ts +61 -0
- package/src/engine/graphics3/decal/DecalTileShader.d.ts.map +1 -0
- package/src/engine/graphics3/decal/DecalTileShader.js +138 -0
- package/src/engine/graphics3/decal/GPUDecalRenderer.d.ts +10 -4
- package/src/engine/graphics3/decal/GPUDecalRenderer.d.ts.map +1 -1
- package/src/engine/graphics3/decal/GPUDecalRenderer.js +149 -44
- package/src/engine/graphics3/decal/chunk_decal_tile_vertex.d.ts +25 -0
- package/src/engine/graphics3/decal/chunk_decal_tile_vertex.d.ts.map +1 -0
- package/src/engine/graphics3/decal/chunk_decal_tile_vertex.js +55 -0
- package/src/engine/graphics3/decal/graph_gather_decal_tiles.d.ts +22 -0
- package/src/engine/graphics3/decal/graph_gather_decal_tiles.d.ts.map +1 -0
- package/src/engine/graphics3/decal/graph_gather_decal_tiles.js +70 -0
- package/src/engine/graphics3/decal/shader_decal_composite.d.ts +7 -5
- package/src/engine/graphics3/decal/shader_decal_composite.d.ts.map +1 -1
- package/src/engine/graphics3/decal/shader_decal_composite.js +48 -44
- package/src/engine/graphics3/decal/shader_decal_tile_copy.d.ts +12 -0
- package/src/engine/graphics3/decal/shader_decal_tile_copy.d.ts.map +1 -0
- package/src/engine/graphics3/decal/shader_decal_tile_copy.js +78 -0
- package/src/engine/graphics3/decal/shader_gather_decal_tiles.d.ts +11 -0
- package/src/engine/graphics3/decal/shader_gather_decal_tiles.d.ts.map +1 -0
- package/src/engine/graphics3/decal/shader_gather_decal_tiles.js +80 -0
- package/src/engine/input/devices/mouse/MouseEventButtons.d.ts +13 -0
- package/src/engine/input/devices/mouse/MouseEventButtons.d.ts.map +1 -0
- package/src/engine/input/devices/mouse/MouseEventButtons.js +23 -0
- package/src/engine/input/ecs/controllers/KeyboardCameraController.d.ts +4 -0
- package/src/engine/input/ecs/controllers/KeyboardCameraController.d.ts.map +1 -1
- package/src/engine/input/ecs/controllers/KeyboardCameraController.js +9 -45
- package/src/engine/physics/fluid/ecs/FluidObstacleSystem.d.ts +4 -4
- package/src/shade/playground/water_refraction/README.md +5 -6
- package/src/shade/playground/water_refraction/index.html +1 -1
- package/src/shade/renderer/Renderer.d.ts +11 -0
- package/src/shade/renderer/Renderer.d.ts.map +1 -1
- package/src/shade/renderer/Renderer.js +50 -6
- package/src/shade/renderer/camera/orbital/OrbitalCameraController.d.ts +40 -80
- package/src/shade/renderer/camera/orbital/OrbitalCameraController.d.ts.map +1 -1
- package/src/shade/renderer/camera/orbital/OrbitalCameraController.js +197 -147
- package/src/shade/renderer/fluid/GPUFluidCascade.d.ts +3 -3
- package/src/shade/renderer/fluid/GPUFluidCascadeStack.d.ts +1 -1
- package/src/shade/renderer/fluid/forcing/GPUFluidForcing.d.ts +6 -6
- package/src/shade/renderer/fluid/pressure/GPUFluidPressureSolve.d.ts +1 -1
- package/src/shade/renderer/fluid/query/GPUFluidQueries.d.ts +1 -1
- package/src/shade/renderer/geometry/sdf/GPUGeometrySDFManager.d.ts +28 -45
- package/src/shade/renderer/geometry/sdf/GPUGeometrySDFManager.d.ts.map +1 -1
- package/src/shade/renderer/geometry/sdf/GPUGeometrySDFManager.js +111 -119
- package/src/shade/renderer/geometry/sdf/cards/GPUMeshCardSets.d.ts +22 -3
- package/src/shade/renderer/geometry/sdf/cards/GPUMeshCardSets.d.ts.map +1 -1
- package/src/shade/renderer/geometry/sdf/cards/GPUMeshCardSets.js +84 -3
- package/src/shade/renderer/geometry/virtual/proxy/vgeo_proxy_triangle_limit.d.ts +19 -0
- package/src/shade/renderer/geometry/virtual/proxy/vgeo_proxy_triangle_limit.d.ts.map +1 -0
- package/src/shade/renderer/geometry/virtual/proxy/vgeo_proxy_triangle_limit.js +25 -0
- package/src/shade/renderer/geometry/virtual/proxy/vgeo_to_proxy_mesh.d.ts +31 -0
- package/src/shade/renderer/geometry/virtual/proxy/vgeo_to_proxy_mesh.d.ts.map +1 -0
- package/src/shade/renderer/geometry/virtual/proxy/vgeo_to_proxy_mesh.js +343 -0
- package/src/shade/renderer/geometry/virtual/runtime/VirtualGeometry.d.ts +15 -0
- package/src/shade/renderer/geometry/virtual/runtime/VirtualGeometry.d.ts.map +1 -1
- package/src/shade/renderer/geometry/virtual/runtime/VirtualGeometry.js +38 -0
- package/src/shade/renderer/geometry/virtual/runtime/vgeo_meshlet_metadata_write.d.ts +17 -0
- package/src/shade/renderer/geometry/virtual/runtime/vgeo_meshlet_metadata_write.d.ts.map +1 -0
- package/src/shade/renderer/geometry/virtual/runtime/vgeo_meshlet_metadata_write.js +29 -0
- package/src/shade/renderer/geometry/virtual/runtime/vgeo_runtime_meshlet_batch.d.ts.map +1 -1
- package/src/shade/renderer/geometry/virtual/runtime/vgeo_runtime_meshlet_batch.js +7 -13
- package/src/shade/renderer/geometry/virtual/sdf/VGeoSDFProxies.d.ts +28 -59
- package/src/shade/renderer/geometry/virtual/sdf/VGeoSDFProxies.d.ts.map +1 -1
- package/src/shade/renderer/geometry/virtual/sdf/VGeoSDFProxies.js +84 -789
- package/src/shade/renderer/global_illumination/probe_clipmap/GPUProbeClipmapGI.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/GPUProbeClipmapGI.js +1 -8
- package/src/shade/renderer/global_illumination/probe_clipmap/ProbeClipmapSceneHolds.d.ts +7 -6
- package/src/shade/renderer/global_illumination/probe_clipmap/ProbeClipmapSceneHolds.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/ProbeClipmapSceneHolds.js +12 -11
- package/src/shade/renderer/global_illumination/probe_clipmap/brick/mesh/chunk_mesh_brick_instance.d.ts +2 -2
- package/src/shade/renderer/global_illumination/probe_clipmap/brick/mesh/chunk_mesh_brick_instance.js +2 -2
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/GPUProbeClipmap.d.ts +1 -4
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/GPUProbeClipmap.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/GPUProbeClipmap.js +1 -10
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap_hit_surface.d.ts +5 -15
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap_hit_surface.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap_hit_surface.js +6 -34
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_shade.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_shade.js +1 -7
- package/src/shade/renderer/hiz/HZBFootprint.d.ts +14 -0
- package/src/shade/renderer/hiz/HZBFootprint.d.ts.map +1 -0
- package/src/shade/renderer/hiz/HZBFootprint.js +16 -0
- package/src/shade/renderer/hiz/HZB_FOOTPRINT_X.d.ts +10 -0
- package/src/shade/renderer/hiz/HZB_FOOTPRINT_X.d.ts.map +1 -0
- package/src/shade/renderer/hiz/HZB_FOOTPRINT_X.js +11 -0
- package/src/shade/renderer/hiz/HZB_FOOTPRINT_Y.d.ts +10 -0
- package/src/shade/renderer/hiz/HZB_FOOTPRINT_Y.d.ts.map +1 -0
- package/src/shade/renderer/hiz/HZB_FOOTPRINT_Y.js +11 -0
- package/src/shade/renderer/hiz/HierarchicalZBuffer.d.ts +0 -7
- package/src/shade/renderer/hiz/HierarchicalZBuffer.d.ts.map +1 -1
- package/src/shade/renderer/hiz/HierarchicalZBuffer.js +405 -350
- package/src/shade/renderer/hiz/chunk_hzb_footprint_x.d.ts +12 -0
- package/src/shade/renderer/hiz/chunk_hzb_footprint_x.d.ts.map +1 -0
- package/src/shade/renderer/hiz/chunk_hzb_footprint_x.js +27 -0
- package/src/shade/renderer/hiz/chunk_hzb_footprint_y.d.ts +12 -0
- package/src/shade/renderer/hiz/chunk_hzb_footprint_y.d.ts.map +1 -0
- package/src/shade/renderer/hiz/chunk_hzb_footprint_y.js +27 -0
- package/src/shade/renderer/hiz/hzb_footprint_texels.d.ts +14 -0
- package/src/shade/renderer/hiz/hzb_footprint_texels.d.ts.map +1 -0
- package/src/shade/renderer/hiz/hzb_footprint_texels.js +34 -0
- package/src/shade/renderer/hiz/shader_hzb_reduce_any.d.ts +0 -5
- package/src/shade/renderer/hiz/shader_hzb_reduce_any.d.ts.map +1 -1
- package/src/shade/renderer/hiz/shader_hzb_reduce_any.js +37 -57
- package/src/shade/renderer/hiz/shader_hzb_reduce_mip0.d.ts +11 -0
- package/src/shade/renderer/hiz/shader_hzb_reduce_mip0.d.ts.map +1 -0
- package/src/shade/renderer/hiz/{shader_hzb_reduce_mip0_clip.js → shader_hzb_reduce_mip0.js} +120 -111
- package/src/shade/renderer/loader/gltf/tiny-gltf.d.ts +1 -1
- package/src/shade/renderer/material/GPUMaterialManager.d.ts +11 -1
- package/src/shade/renderer/material/GPUMaterialManager.d.ts.map +1 -1
- package/src/shade/renderer/material/GPUMaterialManager.js +16 -8
- package/src/shade/renderer/material/resident/GPUResidentMaterialContext.d.ts +12 -12
- package/src/shade/renderer/material/resident/GPUResidentMaterialContext.d.ts.map +1 -1
- package/src/shade/renderer/material/resident/GPUResidentMaterialContext.js +17 -118
- package/src/shade/renderer/postprocess/gtao/GTAO.d.ts +7 -3
- package/src/shade/renderer/postprocess/gtao/GTAO.d.ts.map +1 -1
- package/src/shade/renderer/postprocess/gtao/GTAO.js +26 -13
- package/src/shade/renderer/postprocess/gtao/ao_reproject_shader.d.ts +14 -0
- package/src/shade/renderer/postprocess/gtao/ao_reproject_shader.d.ts.map +1 -1
- package/src/shade/renderer/postprocess/gtao/ao_reproject_shader.js +196 -68
- package/src/shade/renderer/postprocess/gtao/fragment_shader_gtao.d.ts.map +1 -1
- package/src/shade/renderer/postprocess/gtao/fragment_shader_gtao.js +42 -28
- package/src/shade/renderer/postprocess/gtao/fragment_shader_gtao_with_irradiance.d.ts.map +1 -1
- package/src/shade/renderer/postprocess/gtao/fragment_shader_gtao_with_irradiance.js +429 -414
- package/src/shade/renderer/postprocess/gtao/shader_gtao_spatial_denoise.d.ts +16 -0
- package/src/shade/renderer/postprocess/gtao/shader_gtao_spatial_denoise.d.ts.map +1 -0
- package/src/shade/renderer/postprocess/gtao/shader_gtao_spatial_denoise.js +156 -0
- package/src/shade/renderer/scene/GPUSceneContext.d.ts +2 -2
- package/src/shade/renderer/scene/GPUSceneContext.js +5 -5
- package/src/shade/renderer/shadow/map/GPUSceneShadowmapContext.d.ts.map +1 -1
- package/src/shade/renderer/shadow/map/GPUSceneShadowmapContext.js +7 -2
- package/src/shade/renderer/water/GPUWaterRenderer.d.ts +0 -6
- package/src/shade/renderer/water/GPUWaterRenderer.d.ts.map +1 -1
- package/src/shade/renderer/water/GPUWaterRenderer.js +12 -17
- package/src/shade/renderer/water/medium/graph_water_meshlets.d.ts +35 -0
- package/src/shade/renderer/water/medium/graph_water_meshlets.d.ts.map +1 -0
- package/src/shade/renderer/water/medium/graph_water_meshlets.js +89 -0
- package/src/shade/renderer/water/query/GPUWaterQueries.d.ts +1 -1
- package/src/shade/renderer/water/shader_water.d.ts.map +1 -1
- package/src/shade/renderer/water/shader_water.js +22 -13
- package/src/shade/renderer/water/shader_water_avboit.d.ts.map +1 -1
- package/src/shade/renderer/water/shader_water_avboit.js +7 -7
- package/src/shade/renderer/water/surface/graph_water_tessellation.d.ts +1 -1
- package/src/shade/renderer/water/surface/graph_water_tessellation.js +1 -1
- package/src/shade/wgsl/emulator/WGSLJavaScriptCompiler.js +9 -1
- package/editor/REWORK_PLAN_2026_08.md +0 -692
- package/src/CODEC_LAYOUT_VERIFICATION.md +0 -419
- package/src/CORRECTNESS_HUNT_2026_07_24.md +0 -142
- package/src/DUPLICATION_AUDIT_2026_08_07/00_core_reuse_surface.md +0 -738
- package/src/DUPLICATION_AUDIT_2026_08_07/A_core_math_geom.md +0 -79
- package/src/DUPLICATION_AUDIT_2026_08_07/B_core_data.md +0 -93
- package/src/DUPLICATION_AUDIT_2026_08_07/C_gfx_render.md +0 -80
- package/src/DUPLICATION_AUDIT_2026_08_07/D_gfx_features.md +0 -164
- package/src/DUPLICATION_AUDIT_2026_08_07/E_physics.md +0 -69
- package/src/DUPLICATION_AUDIT_2026_08_07/F_sound.md +0 -110
- package/src/DUPLICATION_AUDIT_2026_08_07/G_net_save.md +0 -129
- package/src/DUPLICATION_AUDIT_2026_08_07/H_engine_misc.md +0 -72
- package/src/DUPLICATION_AUDIT_2026_08_07/I_generation_view.md +0 -74
- package/src/DUPLICATION_AUDIT_2026_08_07/K_crosscutting.md +0 -169
- package/src/DUPLICATION_AUDIT_2026_08_07.md +0 -254
- package/src/DUPLICATION_AUDIT_REMEDIATION.md +0 -250
- package/src/DUPLICATION_REVIEW_2026_10_24.md +0 -1072
- package/src/REVIEW_2026_08_06/adv-core.md +0 -511
- package/src/REVIEW_2026_08_06/adv-gfx.md +0 -480
- package/src/REVIEW_2026_08_06/adv-view.md +0 -446
- package/src/REVIEW_2026_08_06/api-core.md +0 -296
- package/src/REVIEW_2026_08_06/api-engine.md +0 -195
- package/src/REVIEW_2026_08_06/bvh-phys-sound-net.md +0 -507
- package/src/REVIEW_2026_08_06/core-binary.md +0 -348
- package/src/REVIEW_2026_08_06/core-collection.md +0 -376
- package/src/REVIEW_2026_08_06/core-math.md +0 -221
- package/src/REVIEW_2026_08_06/core-process.md +0 -266
- package/src/REVIEW_2026_08_06/core-science.md +0 -223
- package/src/REVIEW_2026_08_06/engine-ai-nav.md +0 -279
- package/src/REVIEW_2026_08_06/engine-animation.md +0 -167
- package/src/REVIEW_2026_08_06/engine-asset.md +0 -166
- package/src/REVIEW_2026_08_06/engine-ecs.md +0 -920
- package/src/REVIEW_2026_08_06/engine-input.md +0 -197
- package/src/REVIEW_2026_08_06/engine-misc.md +0 -248
- package/src/REVIEW_2026_08_06/engine-terrain.md +0 -52
- package/src/REVIEW_2026_08_06/generation.md +0 -176
- package/src/REVIEW_2026_08_06/geom-2d.md +0 -434
- package/src/REVIEW_2026_08_06/geom-3d.md +0 -117
- package/src/REVIEW_2026_08_06/gfx-gi.md +0 -143
- package/src/REVIEW_2026_08_06/gfx-render.md +0 -740
- package/src/REVIEW_2026_08_06/gfx-texture.md +0 -690
- package/src/REVIEW_2026_08_06/prior-criticals.md +0 -49
- package/src/REVIEW_2026_08_06/prior-highs.md +0 -138
- package/src/REVIEW_2026_08_06/test-gaps.md +0 -364
- package/src/REVIEW_2026_08_06/view.md +0 -667
- package/src/REVIEW_2026_08_06.md +0 -610
- package/src/core/binary/lz4/LZ4_HIGH_COMPRESSION_PLAN_2026_09_14.md +0 -542
- package/src/core/bvh2/bvh3/NOTES.md +0 -2
- package/src/core/bvh8/NOTES.md +0 -63
- package/src/core/cache/wtinylfu/benchmark/CacheWTinylfu.bench.md +0 -243
- package/src/core/color/COLOR_FIX_PLAN_2026_08_28.md +0 -417
- package/src/core/color/COLOR_REVIEW_2026_08_28.md +0 -779
- package/src/core/geom/2d/polygon/TRIANGULATION_DESIGN.md +0 -433
- package/src/core/geom/3d/atlas/ATLAS_PORT_PLAN.md +0 -486
- package/src/core/geom/3d/atlas/BFF_PLAN.md +0 -174
- package/src/core/geom/3d/atlas/REVIEW_02.md +0 -392
- package/src/core/geom/3d/gjk/GJK_REVIEW_NOTES.md +0 -146
- package/src/core/geom/3d/gjk/NOTES.md +0 -8
- package/src/core/geom/3d/topology/TOPO_MESH_RETIREMENT_PLAN.md +0 -135
- package/src/core/geom/GEOMETRY_REVIEW_002_API_ISSUES.md +0 -381
- package/src/core/geom/GEOMETRY_REVIEW_002_NAMING.md +0 -684
- package/src/core/geom/MANIFOLD_COMPARISON_2026_08_01.md +0 -554
- package/src/core/model/reactive/evaluation/PREDICATE_APPLICABILITY_PROPOSAL.md +0 -446
- package/src/engine/REVIEW_2026_07_03.md +0 -211
- package/src/engine/asset/loaders/image/IMAGE_CODEC_REVIEW_2026_08_28.md +0 -815
- package/src/engine/control/first-person/DESIGN.md +0 -658
- package/src/engine/control/first-person/DESIGN_COLLISION.md +0 -382
- package/src/engine/control/first-person/DESIGN_EXTENSIONS.md +0 -563
- package/src/engine/control/first-person/TODO.md +0 -160
- package/src/engine/ecs/ASYNC_SYSTEMS_PROPOSAL.md +0 -531
- package/src/engine/ecs/HIERARCHY_REVIEW.md +0 -717
- package/src/engine/ecs/async/WORKER_SYSTEM_PLAN.md +0 -262
- package/src/engine/ecs/ik/PLAN.md +0 -179
- package/src/engine/ecs/storage/binary/SERIALIZATION_COVERAGE.md +0 -272
- package/src/engine/ecs/storage/binary/object-v2/DESIGN.md +0 -199
- package/src/engine/ecs/transform/TRANSFORM64_MIGRATION_PLAN_2026_09_04.md +0 -521
- package/src/engine/graphics/CONTEXT_LOSS_RECOVERY_PLAN.md +0 -463
- package/src/engine/graphics/ecs/camera/pp/NOTES.md +0 -48
- package/src/engine/graphics/render/frame_graph/CORRECTNESS_FIXES_2026_09_04.md +0 -659
- package/src/engine/graphics/render/frame_graph/FRAME_GRAPH_RECOMMENDATIONS.md +0 -235
- package/src/engine/graphics/sh3/path_tracer/REVIEW_001_ACTION_PLAN.md +0 -490
- package/src/engine/graphics/texture/sampler/compare/FLIP_IMPLEMENTATION_PLAN.md +0 -466
- package/src/engine/input/GAMEPAD_API_PROPOSAL.md +0 -717
- package/src/engine/input/ecs/ism/ISM_DESIGN.md +0 -1523
- package/src/engine/input/ecs/ism/ISM_IMPLEMENTATION_PLAN.md +0 -627
- package/src/engine/navigation/mesh/OVERLAPPING_SURFACES_2026_08_25.md +0 -661
- package/src/engine/navigation/mesh/PATHFINDING_PLAN.md +0 -229
- package/src/engine/network/CONGESTION_CONTROL.md +0 -87
- package/src/engine/network/MESSAGE_TRANSPORT.md +0 -364
- package/src/engine/network/SMOOTHNESS_DESIGN.md +0 -400
- package/src/engine/physics/cloth/MEASUREMENTS.md +0 -5304
- package/src/engine/physics/cloth/PLAN.md +0 -3056
- package/src/engine/physics/fluid/GPU_FLUID_CASCADES_PROPOSAL_2026_10_16.md +0 -1382
- package/src/engine/physics/fluid/REVIEW_02_PLAN.md +0 -243
- package/src/engine/physics/fluid/solver/NOTES.md +0 -46
- package/src/engine/sound/SOUND_EMITTER_RETIREMENT_PLAN.md +0 -536
- package/src/engine/sound/simulation/IMPLEMENTATION_PLAN.md +0 -432
- package/src/engine/sound/simulation/PROBE_PLACEMENT.md +0 -250
- package/src/engine/sound/simulation/PROBE_TRANSFER_RESEARCH.md +0 -322
- package/src/engine/sound/simulation/REFLECTION_IR_PLAN.md +0 -261
- package/src/engine/sound/simulation/VISIBILITY_GRAPH_PLAN.md +0 -121
- package/src/engine/sound/sopra/IMPLEMENTATION_PLAN.md +0 -999
- package/src/format/image/avif/DECISIONS.md +0 -545
- package/src/format/image/jpeg/NOTES.md +0 -3
- package/src/format/scene/gltf/MESHOPT_COMPRESSION_PLAN.md +0 -814
- package/src/generation/COORDINATES.md +0 -54
- package/src/generation/REVIEW_01_ACTION_PLAN.md +0 -628
- package/src/generation/foliage/ANNUAL_SHOOTS_BRIEF_2026_10_25.md +0 -220
- package/src/generation/foliage/CROWN_FILLING_BRIEF_2026_10_26.md +0 -172
- package/src/generation/foliage/CROWN_FULLNESS_BRIEF_2026_10_26.md +0 -86
- package/src/generation/foliage/FOLIAGE_DESIGN.md +0 -547
- package/src/generation/foliage/FOLIAGE_PLAN.md +0 -198
- package/src/generation/foliage/LEAF_ARCHITECTURE_BRIEF_2026_10_26.md +0 -158
- package/src/generation/foliage/LOD_REWORK_BRIEF_2026_10_27.md +0 -521
- package/src/generation/foliage/REAL_TIME_TREES_BRIEF_2026_10_27.md +0 -86
- package/src/generation/foliage/SELF_ORGANIZING_FRAMEWORK_BRIEF_2026_10_26.md +0 -347
- package/src/generation/foliage/SHOOT_SYSTEMS_ALL_SPECIES_BRIEF_2026_10_26.md +0 -248
- package/src/generation/foliage/SPEEDTREE_COMPARISON_2026_10_24.md +0 -694
- package/src/generation/foliage/TWO_FRONT_ENDS_BRIEF_2026_10_28.md +0 -552
- package/src/shade/RENDERER_CONTRACT.md +0 -697
- package/src/shade/SHADER_F16_PROPOSAL_2026_10_24.md +0 -263
- package/src/shade/device/IMMEDIATE_DATA_PLAN_2026_08_28.md +0 -569
- package/src/shade/device/PASS_ENCODER_PROPOSAL_2026_08_31.md +0 -755
- package/src/shade/device/mock/EXTENSION_PROPOSAL_2026_08_22.md +0 -458
- package/src/shade/device/mock/IMPLEMENTATION_PLAN.md +0 -255
- package/src/shade/device/mock/REVIEW_2026_08_22.md +0 -527
- package/src/shade/device/timing/GPU_PROFILER_PROPOSAL_2026_08_28.md +0 -894
- package/src/shade/device/timing/profile/SGPT_FORMAT.md +0 -345
- package/src/shade/renderer/NOTES.md +0 -78
- package/src/shade/renderer/PLAN.md +0 -8
- package/src/shade/renderer/animation/ADDITIVE_BLENDING_PLAN.md +0 -145
- package/src/shade/renderer/animation/SKINNING_FRAME_PLAN.md +0 -357
- package/src/shade/renderer/atmosphere/NOTES.md +0 -6
- package/src/shade/renderer/camera/orbital/MomentumAxis.d.ts +0 -76
- package/src/shade/renderer/camera/orbital/MomentumAxis.d.ts.map +0 -1
- package/src/shade/renderer/camera/orbital/MomentumAxis.js +0 -164
- package/src/shade/renderer/camera/orbital/OrbitalCameraConfig.d.ts +0 -45
- package/src/shade/renderer/camera/orbital/OrbitalCameraConfig.d.ts.map +0 -1
- package/src/shade/renderer/camera/orbital/OrbitalCameraConfig.js +0 -66
- package/src/shade/renderer/camera/orbital/OrbitalCameraInput.d.ts +0 -98
- package/src/shade/renderer/camera/orbital/OrbitalCameraInput.d.ts.map +0 -1
- package/src/shade/renderer/camera/orbital/OrbitalCameraInput.js +0 -184
- package/src/shade/renderer/camera/orbital/OrbitalCameraRig.d.ts +0 -175
- package/src/shade/renderer/camera/orbital/OrbitalCameraRig.d.ts.map +0 -1
- package/src/shade/renderer/camera/orbital/OrbitalCameraRig.js +0 -411
- package/src/shade/renderer/camera/orbital/README.md +0 -81
- package/src/shade/renderer/camera/orbital/index.d.ts +0 -6
- package/src/shade/renderer/camera/orbital/index.d.ts.map +0 -1
- package/src/shade/renderer/camera/orbital/index.js +0 -9
- package/src/shade/renderer/extension/RENDER_EXTENSION_DESIGN.md +0 -964
- package/src/shade/renderer/fluid/GPU_FLUID_OCCUPANCY_AND_SOTA_REVIEW_2026_10_26.md +0 -361
- package/src/shade/renderer/geometry/bvh/BLAS_REFIT_BATCH_PLAN.md +0 -619
- package/src/shade/renderer/geometry/meshlet/COMPACTION_PLAN_2026_09_16.md +0 -674
- package/src/shade/renderer/geometry/sdf/NOTES.md +0 -6
- package/src/shade/renderer/geometry/virtual/ATTRIBUTE_PLAN_2026_09_18.md +0 -540
- package/src/shade/renderer/geometry/virtual/MICRON_COMPARISON_2026_08_20.md +0 -305
- package/src/shade/renderer/geometry/virtual/VGEO_FORMAT.md +0 -913
- package/src/shade/renderer/geometry/virtual/VIRTUAL_GEOMETRY_DESIGN.md +0 -787
- package/src/shade/renderer/geometry/virtual/VIRTUAL_GEOMETRY_PLAN.md +0 -481
- package/src/shade/renderer/geometry/virtual/VK_LOD_CLUSTERS_COMPARISON_2026_08_20.md +0 -301
- package/src/shade/renderer/geometry/virtual/WEDGE_PLAN_2026_09_18.md +0 -448
- package/src/shade/renderer/geometry/virtual/runtime/CULL_PLAN_2026_09_16.md +0 -385
- package/src/shade/renderer/geometry/virtual/runtime/CUT_PLAN_2026_09_14.md +0 -656
- package/src/shade/renderer/geometry/virtual/runtime/REVIEW_LEDGER.md +0 -308
- package/src/shade/renderer/geometry/virtual/runtime/RUNTIME_PLAN.md +0 -657
- package/src/shade/renderer/geometry/virtual/runtime/RUNTIME_PLAN_2026_09_14.md +0 -551
- package/src/shade/renderer/geometry/virtual/runtime/SHADOW_PLAN_2026_09_28.md +0 -529
- package/src/shade/renderer/geometry/virtual/sdf/VGEO_SDF.d.ts +0 -47
- package/src/shade/renderer/geometry/virtual/sdf/VGEO_SDF.d.ts.map +0 -1
- package/src/shade/renderer/geometry/virtual/sdf/VGEO_SDF.js +0 -80
- package/src/shade/renderer/geometry/virtual/sdf/shader_vgeo_sdf_collect.d.ts +0 -16
- package/src/shade/renderer/geometry/virtual/sdf/shader_vgeo_sdf_collect.d.ts.map +0 -1
- package/src/shade/renderer/geometry/virtual/sdf/shader_vgeo_sdf_collect.js +0 -67
- package/src/shade/renderer/geometry/virtual/sdf/shader_vgeo_sdf_decode.d.ts +0 -17
- package/src/shade/renderer/geometry/virtual/sdf/shader_vgeo_sdf_decode.d.ts.map +0 -1
- package/src/shade/renderer/geometry/virtual/sdf/shader_vgeo_sdf_decode.js +0 -145
- package/src/shade/renderer/geometry/virtual/sdf/shader_vgeo_sdf_traverse.d.ts +0 -12
- package/src/shade/renderer/geometry/virtual/sdf/shader_vgeo_sdf_traverse.d.ts.map +0 -1
- package/src/shade/renderer/geometry/virtual/sdf/shader_vgeo_sdf_traverse.js +0 -105
- package/src/shade/renderer/global_illumination/lpv/NOTES.md +0 -3
- package/src/shade/renderer/global_illumination/probe_clipmap/PROBE_CLIPMAP_PROPOSAL_2026_10_27.md +0 -4306
- package/src/shade/renderer/global_illumination/probe_clipmap/PROBE_RAYS_VARIABLE_AND_SORTED_SCOPE_2026_10_30.md +0 -410
- package/src/shade/renderer/global_illumination/sharc/NOTES.md +0 -8
- package/src/shade/renderer/gpu_primitive/bvh/GPU_BVH_BUILD_PLAN.md +0 -1369
- package/src/shade/renderer/gpu_primitive/bvh/PHASE1_HANDOVER.md +0 -202
- package/src/shade/renderer/gpu_primitive/indirect/NOTES.md +0 -94
- package/src/shade/renderer/hiz/NOTES.md +0 -3
- package/src/shade/renderer/hiz/shader_hzb_reduce_mip0_clip.d.ts +0 -8
- package/src/shade/renderer/hiz/shader_hzb_reduce_mip0_clip.d.ts.map +0 -1
- package/src/shade/renderer/light/cluster/NOTES.md +0 -11
- package/src/shade/renderer/light/cluster/PROPOSAL_ALGORITHM_2026_10_16.md +0 -524
- package/src/shade/renderer/light/cluster/PROPOSAL_HIERARCHICAL_2026_10_16.md +0 -1101
- package/src/shade/renderer/material/resident/shader_resident_texture_means.d.ts +0 -24
- package/src/shade/renderer/material/resident/shader_resident_texture_means.d.ts.map +0 -1
- package/src/shade/renderer/material/resident/shader_resident_texture_means.js +0 -120
- package/src/shade/renderer/particles/DESIGN.md +0 -1011
- package/src/shade/renderer/particles/EMITTER_GLOBAL_STATE_PLAN_2026_10_29.md +0 -280
- package/src/shade/renderer/particles/ORIENTATION_PLAN_2026_10_15.md +0 -453
- package/src/shade/renderer/path_tracer/PATH_TRACED_MEDIA_PLAN_2026_10_02.md +0 -520
- package/src/shade/renderer/postprocess/bloom/NOTES.md +0 -6
- package/src/shade/renderer/postprocess/fsr/NOTES.md +0 -4
- package/src/shade/renderer/postprocess/gtao/NOTES.md +0 -6
- package/src/shade/renderer/postprocess/nss/NOTES.md +0 -332
- package/src/shade/renderer/postprocess/perspective/NOTES.md +0 -3
- package/src/shade/renderer/postprocess/sscs/NOTES.md +0 -5
- package/src/shade/renderer/postprocess/ssr/NOTES.md +0 -14
- package/src/shade/renderer/postprocess/ssr/REPROJECTION_PROPOSAL.md +0 -286
- package/src/shade/renderer/postprocess/ssr/prefilter/NOTES.md +0 -39
- package/src/shade/renderer/postprocess/taa/NOTES.md +0 -11
- package/src/shade/renderer/postprocess/upscale-dither/NOTES.md +0 -78
- package/src/shade/renderer/postprocess/vrs/NOTES.md +0 -4
- package/src/shade/renderer/rasterize/native/avboit/AVBOIT_LEDGER.md +0 -1218
- package/src/shade/renderer/rasterize/native/avboit/AVBOIT_PLAN_2026_09_03.md +0 -600
- package/src/shade/renderer/restir/reservoir/NOTES.md +0 -6
- package/src/shade/renderer/shader/chunk/atmosphere/NOTES.md +0 -6
- package/src/shade/renderer/shader/chunk/brdf/FRESNEL_BRIEF_2026_10_16.md +0 -391
- package/src/shade/renderer/shader/chunk/color/tonemap/ACES_TONE_MAPPING_BRIEF_2026_10_17.md +0 -153
- package/src/shade/renderer/shader/chunk/color/tonemap/HDR_TONE_MAPPING_FORMS_BRIEF_2026_10_16.md +0 -322
- package/src/shade/renderer/shader/chunk/color/tonemap/SDR_TONE_MAPPING_BRIEF_2026_10_16.md +0 -247
- package/src/shade/renderer/shader/chunk/fsr/NOTES.md +0 -3
- package/src/shade/renderer/shader/chunk/fsr/spd/NOTES.md +0 -4
- package/src/shade/renderer/shader/chunk/geometry/ray/NOTES.md +0 -4
- package/src/shade/renderer/shader/chunk/material/MULTISCATTER.md +0 -159
- package/src/shade/renderer/shader/chunk/mboit/NOTES.md +0 -38
- package/src/shade/renderer/shader/chunk/spherical_harmonics/l1i/NOTES.md +0 -3
- package/src/shade/renderer/shader/chunk/spherical_harmonics/sampling/NOTES.md +0 -8
- package/src/shade/renderer/shader/compiler/SHADER_SWITCH_PROPOSAL_2026_10_16.md +0 -927
- package/src/shade/renderer/shadow/contact/FINDINGS.md +0 -413
- package/src/shade/renderer/shadow/map/csm/NOTES.md +0 -5
- package/src/shade/renderer/shadow/ray/NOTES.md +0 -31
- package/src/shade/renderer/shadow/sdf/NOTES.md +0 -9
- package/src/shade/renderer/shadow/sdf/brixelizer/NOTES.md +0 -5
- package/src/shade/renderer/shadow/sdf/cascade/NOTES.md +0 -9
- package/src/shade/renderer/shadow/vsm/NOTES.md +0 -12
- package/src/shade/renderer/shadow/vsm/PLAN.md +0 -442
- package/src/shade/renderer/shadow/vsm/REVIEW_LEDGER.md +0 -43
- package/src/shade/renderer/texture/COMPRESSED_TEXTURE_PLAN_2026_09_01.md +0 -2444
- package/src/shade/renderer/texture/mipmaps/NOTES.md +0 -3
- package/src/shade/renderer/volumetrics/NOTES.md +0 -1329
- package/src/shade/renderer/volumetrics/VOLUMETRIC_NOISE_PLAN_2026_10_15.md +0 -336
- package/src/shade/renderer/water/medium/GPUWaterBodies.d.ts +0 -23
- package/src/shade/renderer/water/medium/GPUWaterBodies.d.ts.map +0 -1
- package/src/shade/renderer/water/medium/GPUWaterBodies.js +0 -75
- 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.
|