@woosh/meep-engine 3.60.3 → 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.
- package/CHANGELOG.md +2602 -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/editor/ecs/component/editors/ecs/Trail3DEditor.d.ts +3 -0
- package/editor/ecs/component/editors/ecs/Trail3DEditor.d.ts.map +1 -1
- package/editor/ecs/component/editors/ecs/Trail3DEditor.js +6 -0
- 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/mesh-v2/ShadedGeometryFlags.js +1 -2
- package/src/engine/graphics/ecs/trail3d/TRAIL3D_FADE_LINEAR.d.ts +14 -0
- package/src/engine/graphics/ecs/trail3d/TRAIL3D_FADE_LINEAR.d.ts.map +1 -0
- package/src/engine/graphics/ecs/trail3d/TRAIL3D_FADE_LINEAR.js +22 -0
- package/src/engine/graphics/ecs/trail3d/Trail3D.d.ts +19 -3
- package/src/engine/graphics/ecs/trail3d/Trail3D.d.ts.map +1 -1
- package/src/engine/graphics/ecs/trail3d/Trail3D.js +31 -4
- package/src/engine/graphics/ecs/trail3d/advance_trail.js +1 -1
- 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/graphics/trail/tube/simulator/TubeXFixedPhysicsSimulator.d.ts +5 -5
- package/src/engine/graphics/trail/tube/simulator/TubeXFixedPhysicsSimulator.d.ts.map +1 -1
- package/src/engine/graphics/trail/tube/simulator/TubeXFixedPhysicsSimulator.js +6 -6
- 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/graphics3/trail/trail_tube_write_geometry.d.ts +10 -0
- package/src/engine/graphics3/trail/trail_tube_write_geometry.d.ts.map +1 -1
- package/src/engine/graphics3/trail/trail_tube_write_geometry.js +13 -1
- 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/cloth/ecs/cloth_geodesic.d.ts +2 -2
- package/src/engine/physics/cloth/ecs/cloth_geodesic.js +2 -2
- package/src/engine/physics/fluid/ecs/FluidObstacleSystem.d.ts +4 -4
- package/src/shade/playground/probe_clipmap/README.md +1 -0
- package/src/shade/playground/probe_clipmap/index.html +5 -0
- package/src/shade/playground/probe_clipmap/main.d.ts.map +1 -1
- package/src/shade/playground/probe_clipmap/main.js +16 -2
- package/src/shade/playground/vgeo_scene/README.md +1 -1
- 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.map +1 -1
- package/src/shade/renderer/Renderer.js +7 -5
- package/src/shade/renderer/atmosphere/MULTISCATTER_LUT_CONFIG.d.ts +4 -6
- package/src/shade/renderer/atmosphere/MULTISCATTER_LUT_CONFIG.d.ts.map +1 -1
- package/src/shade/renderer/atmosphere/MULTISCATTER_LUT_CONFIG.js +34 -36
- package/src/shade/renderer/atmosphere/chunk_get_multiscatter_values.d.ts +1 -1
- package/src/shade/renderer/atmosphere/chunk_get_multiscatter_values.d.ts.map +1 -1
- package/src/shade/renderer/atmosphere/chunk_get_multiscatter_values.js +162 -163
- package/src/shade/renderer/atmosphere/compute_mie_absorption.d.ts +1 -1
- package/src/shade/renderer/atmosphere/compute_mie_absorption.js +1 -1
- package/src/shade/renderer/atmosphere/hillaire/ATMOSPHERE_EARTH.js +1 -1
- package/src/shade/renderer/atmosphere/hillaire/ATMOSPHERE_PARAMETERS_STRUCT.js +1 -1
- package/src/shade/renderer/atmosphere/shader_multiscatter_lut.js +164 -164
- package/src/shade/renderer/atmosphere/shader_sky_irradiance_lut.js +1 -1
- 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 +4 -4
- package/src/shade/renderer/geometry/sdf/GPUGeometrySDFManager.js +4 -4
- package/src/shade/renderer/geometry/sdf/cards/GPUMeshCardSets.d.ts +2 -1
- package/src/shade/renderer/geometry/sdf/cards/GPUMeshCardSets.d.ts.map +1 -1
- package/src/shade/renderer/geometry/sdf/cards/GPUMeshCardSets.js +18 -1
- package/src/shade/renderer/geometry/sdf/cards/mesh_cards_raster_pass_descriptor.js +2 -2
- package/src/shade/renderer/geometry/sdf/cards/shader_mesh_cards_histogram.d.ts +1 -1
- package/src/shade/renderer/geometry/sdf/cards/shader_mesh_cards_histogram.js +1 -1
- package/src/shade/renderer/geometry/sdf/chunk_blas_query_band_sdf.d.ts +4 -5
- package/src/shade/renderer/geometry/sdf/chunk_blas_query_band_sdf.d.ts.map +1 -1
- package/src/shade/renderer/geometry/sdf/chunk_blas_query_band_sdf.js +6 -7
- 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/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/global_illumination/probe_clipmap/GPUProbeClipmapGI.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/GPUProbeClipmapGI.js +2 -8
- package/src/shade/renderer/global_illumination/probe_clipmap/ProbeClipmapSceneHolds.d.ts +5 -5
- package/src/shade/renderer/global_illumination/probe_clipmap/ProbeClipmapSceneHolds.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/ProbeClipmapSceneHolds.js +10 -10
- package/src/shade/renderer/global_illumination/probe_clipmap/ProbeClipmapSettings.d.ts +12 -0
- package/src/shade/renderer/global_illumination/probe_clipmap/ProbeClipmapSettings.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/ProbeClipmapSettings.js +22 -0
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/GPUProbeClipmap.d.ts +4 -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 +50 -13
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/PROBE_CLIPMAP.d.ts +6 -0
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/PROBE_CLIPMAP.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/PROBE_CLIPMAP.js +7 -0
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/PROBE_CLIPMAP_RESAMPLING.d.ts +13 -0
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/PROBE_CLIPMAP_RESAMPLING.d.ts.map +1 -0
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/PROBE_CLIPMAP_RESAMPLING.js +13 -0
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap.d.ts +17 -0
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap.js +20 -0
- 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/chunk_probe_clipmap_resampled.d.ts +18 -0
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap_resampled.d.ts.map +1 -0
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap_resampled.js +42 -0
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap_sample_radiance.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap_sample_radiance.js +5 -4
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_accumulate.d.ts +4 -0
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_accumulate.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_accumulate.js +13 -2
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_resample.d.ts +52 -0
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_resample.d.ts.map +1 -0
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_resample.js +250 -0
- 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/light/environment/environment_level_1_blur_plan.d.ts +39 -0
- package/src/shade/renderer/light/environment/environment_level_1_blur_plan.d.ts.map +1 -0
- package/src/shade/renderer/light/environment/environment_level_1_blur_plan.js +119 -0
- package/src/shade/renderer/light/environment/execute_filter_environment_map.d.ts +15 -7
- package/src/shade/renderer/light/environment/execute_filter_environment_map.d.ts.map +1 -1
- package/src/shade/renderer/light/environment/execute_filter_environment_map.js +66 -83
- package/src/shade/renderer/light/environment/graph_filter_environment_map.d.ts.map +1 -1
- package/src/shade/renderer/light/environment/graph_filter_environment_map.js +15 -6
- package/src/shade/renderer/light/environment/shader_blur_environment_map.d.ts +3 -0
- package/src/shade/renderer/light/environment/shader_blur_environment_map.d.ts.map +1 -0
- package/src/shade/renderer/light/environment/shader_blur_environment_map.js +111 -0
- package/src/shade/renderer/light/environment/shader_convolve_reflection_map_from_blurred.d.ts +3 -0
- package/src/shade/renderer/light/environment/shader_convolve_reflection_map_from_blurred.d.ts.map +1 -0
- package/src/shade/renderer/light/environment/shader_convolve_reflection_map_from_blurred.js +128 -0
- package/src/shade/renderer/light/environment/shader_downsample_environment_map.d.ts.map +1 -1
- package/src/shade/renderer/light/environment/shader_downsample_environment_map.js +0 -1
- package/src/shade/renderer/loader/gltf/tiny-gltf.d.ts +1 -1
- package/src/shade/renderer/material/GPUMaterialManager.d.ts +7 -0
- package/src/shade/renderer/material/GPUMaterialManager.d.ts.map +1 -1
- package/src/shade/renderer/material/GPUMaterialManager.js +11 -0
- 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/nss/NSS.d.ts +1 -3
- package/src/shade/renderer/postprocess/nss/NSS.d.ts.map +1 -1
- package/src/shade/renderer/postprocess/nss/NSS.js +1 -3
- package/src/shade/renderer/postprocess/nss/NSS_NETWORK_SCHEMA.d.ts +5 -6
- package/src/shade/renderer/postprocess/nss/NSS_NETWORK_SCHEMA.d.ts.map +1 -1
- package/src/shade/renderer/postprocess/nss/NSS_NETWORK_SCHEMA.js +9 -10
- package/src/shade/renderer/postprocess/nss/shader_nss_extract_feedback.d.ts.map +1 -1
- package/src/shade/renderer/postprocess/nss/shader_nss_extract_feedback.js +48 -49
- package/src/shade/renderer/postprocess/nss/shader_nss_postprocess.d.ts.map +1 -1
- package/src/shade/renderer/postprocess/nss/shader_nss_postprocess.js +12 -16
- package/src/shade/renderer/postprocess/nss/shader_nss_preprocess.js +246 -246
- package/src/shade/renderer/rasterize/chunk_triangle_winding_is_reversed.d.ts +1 -2
- package/src/shade/renderer/rasterize/chunk_triangle_winding_is_reversed.d.ts.map +1 -1
- package/src/shade/renderer/rasterize/chunk_triangle_winding_is_reversed.js +34 -35
- package/src/shade/renderer/shader/chunk/atmosphere/C_MIE_SCATTERING_DECLARATION.d.ts +2 -2
- package/src/shade/renderer/shader/chunk/atmosphere/C_MIE_SCATTERING_DECLARATION.js +2 -2
- package/src/shade/renderer/shader/chunk/atmosphere/chunk_compute_extinction.js +1 -1
- package/src/shade/renderer/shader/chunk/atmosphere/hillaire/DENSITY_PROFILE_LAYER_STRUCT.d.ts +1 -1
- package/src/shade/renderer/shader/chunk/atmosphere/hillaire/DENSITY_PROFILE_LAYER_STRUCT.js +1 -1
- package/src/shade/renderer/shader/chunk/brdf/fresnel/chunk_F_Schlick.d.ts +3 -3
- package/src/shade/renderer/shader/chunk/brdf/fresnel/chunk_F_Schlick.js +3 -3
- package/src/shade/renderer/shader/chunk/color/tonemap/aces/chunk_aces_ue_matrices.d.ts +9 -10
- package/src/shade/renderer/shader/chunk/color/tonemap/aces/chunk_aces_ue_matrices.d.ts.map +1 -1
- package/src/shade/renderer/shader/chunk/color/tonemap/aces/chunk_aces_ue_matrices.js +9 -10
- package/src/shade/renderer/shader/chunk/color/tonemap/aces/chunk_tonemap_ue_filmic.d.ts +4 -4
- package/src/shade/renderer/shader/chunk/color/tonemap/aces/chunk_tonemap_ue_filmic.js +5 -5
- package/src/shade/renderer/shader/chunk/math/chunk_f16_round_stochastic.d.ts +1 -2
- package/src/shade/renderer/shader/chunk/math/chunk_f16_round_stochastic.d.ts.map +1 -1
- package/src/shade/renderer/shader/chunk/math/chunk_f16_round_stochastic.js +1 -2
- package/src/shade/renderer/shader/chunk/noise/chunk_stbn_sample_vec2.d.ts +14 -1
- package/src/shade/renderer/shader/chunk/noise/chunk_stbn_sample_vec2.d.ts.map +1 -1
- package/src/shade/renderer/shader/chunk/noise/chunk_stbn_sample_vec2.js +19 -6
- package/src/shade/renderer/shader/chunk/noise/chunk_stbn_sample_vec3.d.ts +10 -1
- package/src/shade/renderer/shader/chunk/noise/chunk_stbn_sample_vec3.d.ts.map +1 -1
- package/src/shade/renderer/shader/chunk/noise/chunk_stbn_sample_vec3.js +14 -6
- package/src/shade/renderer/shader/chunk/random/murmur/chunk_murmur3_vec3u.d.ts +1 -1
- package/src/shade/renderer/shader/chunk/random/murmur/chunk_murmur3_vec3u.js +1 -1
- 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/shadow/vsm/DEFAULT_VSM_MAX_DYNAMIC_LOD_BIAS.d.ts +2 -3
- package/src/shade/renderer/shadow/vsm/DEFAULT_VSM_MAX_DYNAMIC_LOD_BIAS.d.ts.map +1 -1
- package/src/shade/renderer/shadow/vsm/DEFAULT_VSM_MAX_DYNAMIC_LOD_BIAS.js +7 -8
- package/src/shade/renderer/shadow/vsm/DEFAULT_VSM_MAX_LOAD_FACTOR.d.ts +1 -1
- package/src/shade/renderer/shadow/vsm/DEFAULT_VSM_MAX_LOAD_FACTOR.js +12 -12
- package/src/shade/renderer/shadow/vsm/VSMPageManager.d.ts +2 -2
- package/src/shade/renderer/shadow/vsm/VSMPageManager.d.ts.map +1 -1
- package/src/shade/renderer/shadow/vsm/VSMPageManager.js +3 -4
- 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/src/view/elements/progress/segmented/SegmentedResourceBarView.d.ts +0 -19
- package/src/view/elements/progress/segmented/SegmentedResourceBarView.d.ts.map +1 -1
- package/src/view/elements/progress/segmented/SegmentedResourceBarView.js +2 -52
- 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 -483
- 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 -536
- 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 -4225
- 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/light/environment/shader_convolve_reflection_map_from_averages.d.ts +0 -13
- package/src/shade/renderer/light/environment/shader_convolve_reflection_map_from_averages.d.ts.map +0 -1
- package/src/shade/renderer/light/environment/shader_convolve_reflection_map_from_averages.js +0 -198
- 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 -283
- 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 -339
- 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 -394
- package/src/shade/renderer/shader/chunk/color/tonemap/ACES_TONE_MAPPING_BRIEF_2026_10_17.md +0 -160
- 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 -932
- 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 -4
- 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
- package/src/view/elements/progress/segmented/segment_frame_transform.d.ts +0 -15
- package/src/view/elements/progress/segmented/segment_frame_transform.d.ts.map +0 -1
- package/src/view/elements/progress/segmented/segment_frame_transform.js +0 -69
|
@@ -1,483 +0,0 @@
|
|
|
1
|
-
# Virtual Geometry — plan
|
|
2
|
-
|
|
3
|
-
Scheduled and deferred work. [VIRTUAL_GEOMETRY_DESIGN.md](./VIRTUAL_GEOMETRY_DESIGN.md) pins
|
|
4
|
-
what has been *decided*; [VGEO_FORMAT.md](./VGEO_FORMAT.md) specifies what is *written*.
|
|
5
|
-
This file holds what is *next*, and — more usefully — the reasoning and the source for
|
|
6
|
-
ideas that are accepted but not yet scheduled, so that picking one up does not mean
|
|
7
|
-
rediscovering it.
|
|
8
|
-
|
|
9
|
-
The GPU runtime is **built** — `runtime/`, and
|
|
10
|
-
[runtime/RUNTIME_PLAN.md](./runtime/RUNTIME_PLAN.md) is its design and its adversarial review. The
|
|
11
|
-
cut runs on the device, the VRAM tier holds pages under a budget, wants and touches come back
|
|
12
|
-
through a readback, and a VG instance enters the meshlet pipeline through a door of its own. §3's
|
|
13
|
-
items are no longer blocked on "a runtime"; each names what it is actually waiting for now.
|
|
14
|
-
|
|
15
|
-
Items carry their provenance. `[M §x]` is a section of
|
|
16
|
-
[MICRON_COMPARISON_2026_08_20.md](./MICRON_COMPARISON_2026_08_20.md), the review of the
|
|
17
|
-
prior WebGL implementation at
|
|
18
|
-
`H:\git\moicon\prime\src\components\Viewer\Viewer.Meep\Micron\`. `[V §x]` is a section of
|
|
19
|
-
[VK_LOD_CLUSTERS_COMPARISON_2026_08_20.md](./VK_LOD_CLUSTERS_COMPARISON_2026_08_20.md), the
|
|
20
|
-
review of [nvpro-samples/vk_lod_clusters](https://github.com/nvpro-samples/vk_lod_clusters).
|
|
21
|
-
|
|
22
|
-
## 1. Landed
|
|
23
|
-
|
|
24
|
-
For the record, so that a later reader can tell an accepted-and-done item from an
|
|
25
|
-
accepted-and-waiting one.
|
|
26
|
-
|
|
27
|
-
- **Accumulated quadrics carried from the source to the root** `[M §2.1]`, `[V §3.1]`.
|
|
28
|
-
Vertex quadrics are built once from the source triangles and threaded through every
|
|
29
|
-
round; error is the accumulated quadric evaluated at the vertex's final position,
|
|
30
|
-
normalized by its weight, which makes it an object-space distance from the *source*
|
|
31
|
-
rather than a sum of per-round residuals. `bt_mesh_simplify_with_quadrics` in
|
|
32
|
-
`core/geom/3d/topology/struct/binary/io/bt_mesh_simplify.js`; `Quadric3.distance`.
|
|
33
|
-
- **Cluster-count simplification target** `[M §2.2]`, and a minimum cluster fill through the
|
|
34
|
-
generalized leaf repack `[V §3.3]`.
|
|
35
|
-
- **Compactness-weighted cluster adjacency** `[M §2.3]` — `compactness()` in
|
|
36
|
-
`build/level/vgeo_build_levels.js`.
|
|
37
|
-
- **Speculative groups, rejected individually** `[M §2.4]`.
|
|
38
|
-
- **Per-level summary table in the file head** `[V §4.1, §6.1]` — VGEO_FORMAT §4.1.
|
|
39
|
-
- **A traversal metric on the page DAG, and a group tree inside each page** `[V §2.1, §6.3]` —
|
|
40
|
-
VGEO_FORMAT §6.1–6.2. See §2.2 below for why, which is worth keeping: the reasoning corrects
|
|
41
|
-
an error this file previously made.
|
|
42
|
-
- **Boundary constraint quadrics** — see §4.1, which was the blocking item.
|
|
43
|
-
- **A partitioning fallback** `[M §3.3]`, `[V §3.2]` — see §2.1.
|
|
44
|
-
- **An incremental reader, and residency with it** — `format/read/`. A container opens in its
|
|
45
|
-
header, level table and root frame; after that a page arrives only because something asked for
|
|
46
|
-
it, from exactly the byte range the page pointing at it wrote down. `VGeoContainerReader`
|
|
47
|
-
holds residency, activation and eviction; `VGeoByteSource` is the seam — an `ArrayBuffer`, a
|
|
48
|
-
dropped `Blob`, or HTTP ranges that refuse a `200` where they asked for a range. The
|
|
49
|
-
whole-file audit is a tool in `format/read/tool/` and nothing on the runtime path can reach it;
|
|
50
|
-
format §4/§5's reject rules always run.
|
|
51
|
-
VGEO_FORMAT §10 marks, requirement by requirement, what this covers and what it leaves to a
|
|
52
|
-
budget owner.
|
|
53
|
-
- **The reader hardened for 1000 assets, and the budget owner it was waiting for** —
|
|
54
|
-
`virtual/residency/`. Measured first, and three of the audit's suspicions did not survive the
|
|
55
|
-
measurement, which is the more useful half of the result: the per-page allocation the reader adds
|
|
56
|
-
on top of a decoded page is 6.4–11.9 KB, which is 1.2% of a 544 KB page and not worth a rewrite;
|
|
57
|
-
the reverse-reference index tracks the residency frontier rather than the session's history, so it
|
|
58
|
-
does not leak; and the pinned root page is one cluster by invariant §11.7, measured at 1,472 and
|
|
59
|
-
1,732 B, so a thousand of them is under 2 MB and no builder-side cap is wanted. What *was* real:
|
|
60
|
-
a 256 KiB head prefix retained for the reader's life outside every budget (released now, and the
|
|
61
|
-
default cut to 64 KiB), no retry/backoff/quarantine so one bad page threw (now §10's full
|
|
62
|
-
sequence, with telemetry), no cancellation at all (now a per-read `AbortSignal` end to end), and a
|
|
63
|
-
whole-file audit and install-every-page sweep reachable from a reader a renderer holds (now tools,
|
|
64
|
-
with a 1 GiB bound and a message instead of an allocator failure). Above the reader,
|
|
65
|
-
`VGeoResidencyManager` owns the byte budget, the touch stamps, the eviction order and — through
|
|
66
|
-
one `core/process/ConcurrencyGate` — one fetch cap across every reader, because a per-reader cap
|
|
67
|
-
does not compose, measured at sixteen concurrent requests from four readers capped at four.
|
|
68
|
-
- **Activation, and the double-draw it prevents** — format §10's selectable invariant, as one
|
|
69
|
-
live-reference counter per resident group with cascades on install and evict. The clamp reads
|
|
70
|
-
*selectable*, not *resident*: a group whose parents are split across pages must not be refined
|
|
71
|
-
into through the parents that happen to have arrived. Measured on a 19-page bunny, 21 of whose
|
|
72
|
-
362 non-root groups have split parents: 355 of 576 camera positions double-drew, up to 10.7%
|
|
73
|
-
of drawn triangles, before. Zero after. It reads as corrupt geometry rather than as a missing
|
|
74
|
-
page, which is why the tool that found it could not name it.
|
|
75
|
-
- **A CPU cut against a partially resident container** —
|
|
76
|
-
`runtime/cut/__fixtures__/vgeo_select_cut.js`. It is the runtime's rule rather than a debug
|
|
77
|
-
approximation of it, and `vgeo_select_cut.spec.js` holds it to the format's guarantees. A
|
|
78
|
-
`vgeo_viewer` playground used to draw it on screen through Shade's direct geometry path, which is
|
|
79
|
-
what made clamping, streaming and eviction watchable; once `playground/vgeo_runtime/` could show
|
|
80
|
-
all of that through the meshlet pipeline, the page was a second renderer and a second streaming
|
|
81
|
-
loop for no gain, and it was retired. The traversal stayed, because it is the oracle.
|
|
82
|
-
|
|
83
|
-
- **The GPU runtime** — `runtime/`, and [runtime/RUNTIME_PLAN.md](./runtime/RUNTIME_PLAN.md) for the
|
|
84
|
-
design and the adversarial review that reshaped it. The cut is a wavefront BFS over the page DAG
|
|
85
|
-
with a per-cluster predicate at the leaves, and that combination is the whole design: the
|
|
86
|
-
hierarchy decides which clusters to *look at*, the predicate decides whether to *draw* them, and
|
|
87
|
-
because the predicate is a pure function of one row, a page visited twice costs a duplicate record
|
|
88
|
-
rather than a wrong answer — so dedup is one bit per (instance, resident page) and never per
|
|
89
|
-
cluster, which is the number design §4 is trying not to pay.
|
|
90
|
-
|
|
91
|
-
Three things the review found, in descending order of how much they cost to rediscover:
|
|
92
|
-
|
|
93
|
-
- **Design §4's per-cluster rule double-draws as written.** A group that is resident but not
|
|
94
|
-
selectable has clusters satisfying it while their coarse stand-in is drawn over the same
|
|
95
|
-
surface. The rule needs an *own group selectable* term that a traversal gets for free and an
|
|
96
|
-
evaluator does not. §6 states the fact without stating it as a term of the rule, because §4 was
|
|
97
|
-
written for a traversal.
|
|
98
|
-
- **Page size decides whether that state is even reachable.** At the 8 KB pages
|
|
99
|
-
`vgeo_select_cut.spec.js` uses, a torus puts exactly one group in every page — so a blocked group is
|
|
100
|
-
a blocked page, no page is ever mixed, and no page is ever entered twice. Measured: 40 pages
|
|
101
|
-
withheld one at a time and 60 random residency subsets produced *no* mixed page. At 64 KB the
|
|
102
|
-
median page holds eight groups and it is ordinary. A spec for anything about mixed selectability
|
|
103
|
-
has to be written at a page size that produces it.
|
|
104
|
-
- **Every bound degrades in one direction.** A full meshlet collection drops records; a claim
|
|
105
|
-
allocation that does not fit drops the *instance*, because an instance run unclaimed draws its
|
|
106
|
-
whole cut once per parent page that reaches it.
|
|
107
|
-
|
|
108
|
-
Held against mutation: removing the own-group term, the claim, the child selectability check or
|
|
109
|
-
the parent projection each turns the agreement suite red. Proved on a device in
|
|
110
|
-
`playground/vgeo_runtime/` — a 13-page container opened holding only its root page, streamed to 9
|
|
111
|
-
by its own wants, 50 drawn clusters at τ=0.5 falling monotonically to 8 at τ=16, clamping to zero,
|
|
112
|
-
dropping nothing.
|
|
113
|
-
|
|
114
|
-
## 2. Next
|
|
115
|
-
|
|
116
|
-
§2.1 and §2.2 both landed. They are kept because their notes are the reasoning behind decisions
|
|
117
|
-
that are now only visible in code, and rediscovering them is the expensive part. §2.3 **half**
|
|
118
|
-
closed, and the half that did not is the more interesting one — read it before building a
|
|
119
|
-
prefetch.
|
|
120
|
-
|
|
121
|
-
### 2.1 A partitioning fallback for when METIS fails `[M §3.3]`, `[V §3.2]` — LANDED
|
|
122
|
-
|
|
123
|
-
`core/graph/graph_partition_spectral.js` — recursive spectral bisection over CSR, matrix-free,
|
|
124
|
-
signature-compatible with `metis_partition_kway`. `build/partition/vgeo_partition_graph.js` tries METIS
|
|
125
|
-
and falls back to it; both of the builder's partitioning sites go through that wrapper.
|
|
126
|
-
|
|
127
|
-
Notes worth keeping:
|
|
128
|
-
|
|
129
|
-
- **Matrix-free, deliberately.** The Fiedler vector comes from power iteration on `d·I − L`
|
|
130
|
-
with the constant projected out each step; `L` is applied, never built. A dense
|
|
131
|
-
formulation — which is what made Micron's third partitioner unattractive to port — is
|
|
132
|
-
O(n²) in memory and unusable at the sizes that make a fallback necessary.
|
|
133
|
-
- **It is a floor, not a competitor, and the code says so.** The shift needed to make the
|
|
134
|
-
operator positive leaves the eigenvalues of interest within a fraction of a per cent of
|
|
135
|
-
each other, so a graph with no real bottleneck converges only approximately. Measured: a
|
|
136
|
-
20×20 grid cuts at 23 edges against an optimum of 20. Iterations are 256, chosen where the
|
|
137
|
-
curve flattens — the same grid's four-way cut is 82 edges at 64 iterations, 47 at 256, 48
|
|
138
|
-
at 1024. Balance is exact at every setting; only the cut moves.
|
|
139
|
-
- **METIS is much harder to make fail than expected**, and this is insurance rather than a fix
|
|
140
|
-
for an observed problem. Probing it with NaN and negative edge weights, adjacency indices
|
|
141
|
-
past the end of the graph, more parts than vertices, zero parts, and edgeless graphs
|
|
142
|
-
returned a partition every time. The only inputs that stop it malform the CSR itself, which
|
|
143
|
-
is a caller bug. Worth knowing before anyone spends effort here again.
|
|
144
|
-
|
|
145
|
-
Still open, and related: meshopt's builder treats a group as **stuck** when simplification
|
|
146
|
-
leaves more than `merged.size() * simplify_threshold` faces, and escalates to permissive, then
|
|
147
|
-
sloppy modes, inflating the recorded error to pay for it. We have no middle rung between
|
|
148
|
-
"simplified" and "refused". This is now safe to build — it was not before, because a sloppy
|
|
149
|
-
mode that erodes boundaries needed §4.1 first, and §4.1 has landed.
|
|
150
|
-
|
|
151
|
-
### 2.2 A traversal metric on the page DAG, then nodes within a page `[V §2.1, §6.3]` — LANDED
|
|
152
|
-
|
|
153
|
-
**Correcting an earlier framing in this file.** A previous revision called paging "the open
|
|
154
|
-
question" for a node hierarchy, on the grounds that nvpro never had to answer it — their node
|
|
155
|
-
array is per-geometry and resident, and at 1 G triangles ours would be tens of megabytes.
|
|
156
|
-
Both halves of that were wrong, and the second one was wrong in a way that hid the actual
|
|
157
|
-
work.
|
|
158
|
-
|
|
159
|
-
**The pages already form a rooted DAG, and it is already validated.** Every one of the
|
|
160
|
-
properties a traversal wants from a hierarchy is a rule the format states and
|
|
161
|
-
`vgeo_validate_container` enforces:
|
|
162
|
-
|
|
163
|
-
- rooted at page 0, and *every page is reachable from it through child tables* (§11.3);
|
|
164
|
-
- acyclic — a child table's `frame_offset` is strictly greater than the referencing page's,
|
|
165
|
-
so file order is a topological order (§11.3);
|
|
166
|
-
- levelled — a cluster's child group is always in a page whose band tops out strictly below
|
|
167
|
-
its own page's (§11.4);
|
|
168
|
-
- and a group never spans a page, so an edge is a whole LOD decision, not part of one.
|
|
169
|
-
|
|
170
|
-
It is a DAG rather than a tree, and measurably so. On a 98k-triangle sphere at 32 KB pages:
|
|
171
|
-
**91 pages, 291 edges, in-degree up to 7, 82 of the 91 pages have more than one parent, none
|
|
172
|
-
unreachable, longest path from the root 12.** At 8 KB pages a 24k sphere gives 102 pages and
|
|
173
|
-
182 edges with 68 multi-parent pages. It degenerates to a chain only when every band fits in
|
|
174
|
-
one page, which is to say only on assets too small for any of this to matter.
|
|
175
|
-
|
|
176
|
-
That the page DAG is a *useful* coarsening rather than an arbitrary one rests on something
|
|
177
|
-
already in the builder: groups are laid into pages in Morton order of their centroid within a
|
|
178
|
-
band (`vgeo_assemble_pages`). A page is therefore spatially local, and a bounding volume over
|
|
179
|
-
one means something. Pack pages arbitrarily and every page bound covers the model.
|
|
180
|
-
|
|
181
|
-
**Nanite does exactly this combination**, which settles the compatibility question outright.
|
|
182
|
-
Cluster data lives in a paged, streamed virtual byte buffer
|
|
183
|
-
(`Nanite.StreamingManager.ClusterPageData`) with the BVH in
|
|
184
|
-
`Nanite.StreamingManager.Hierarchy`; nodes form a BVH within a mesh connecting clusters
|
|
185
|
-
across detail levels; `PersistentNodeAndClusterCull` in `NaniteHierarchyTraversal.ush` walks
|
|
186
|
-
it on the GPU from an MPMC queue, where only nodes generate new work and clusters are only
|
|
187
|
-
consumed. And when a child's memory is not present, **processing stops at the parent and a
|
|
188
|
-
request is made for the child** — a lower-detail LOD is what you see until it arrives. That
|
|
189
|
-
is the same mechanism as nvpro's invalid-address-is-the-request-slot (§2.3 of the
|
|
190
|
-
vk_lod_clusters review), and it is the answer to "what does a traversal do about paging":
|
|
191
|
-
nothing special. It stops.
|
|
192
|
-
|
|
193
|
-
#### What is actually missing
|
|
194
|
-
|
|
195
|
-
Not a hierarchy. A **metric on the one we have**. A child-table entry today carries
|
|
196
|
-
`frame_offset`, `page_index`, `fetch_size`, `decoded_size` and four reserved bytes — enough
|
|
197
|
-
to fetch a page, and nothing at all with which to decide whether to. So the DAG is
|
|
198
|
-
traversable but not *cullable*: the only way to learn that a page was not wanted is to fetch
|
|
199
|
-
it and decode it, which is precisely backwards. The decision worth making cheaply is the one
|
|
200
|
-
before the fetch.
|
|
201
|
-
|
|
202
|
-
The work is two steps, and both are natively paged because they live inside structures that
|
|
203
|
-
already are:
|
|
204
|
-
|
|
205
|
-
**Step 1 — a traversal metric per child-table entry.** The child page's LOD-metric sphere and
|
|
206
|
-
its error range, 24 bytes, taking the entry from 24 to 48. It buys, in one change: frustum and
|
|
207
|
-
LOD culling of a whole page and everything reachable only through it; a want-list that is
|
|
208
|
-
exactly the pages that passed the test and are not resident; and prefetch depth as a policy
|
|
209
|
-
dial instead of a guess. The page header carries the same metric for its own content, so an
|
|
210
|
-
installed page can be re-tested without walking back to its parent.
|
|
211
|
-
|
|
212
|
-
**Step 2 — a node tree within a page, over that page's own groups.** Finer culling and more
|
|
213
|
-
width at the top. This one has *no* paging question by construction: it is inside a page, it
|
|
214
|
-
ships and evicts with it, and it cannot dangle.
|
|
215
|
-
|
|
216
|
-
Both landed together; VGEO_FORMAT §6.1–6.2 specifies them, `build/page/vgeo_build_page_nodes.js`
|
|
217
|
-
builds them. Notes worth keeping:
|
|
218
|
-
|
|
219
|
-
- The tree needs no partitioner. A page's groups arrive in Morton order of their centroid, so
|
|
220
|
-
a balanced split of that order is already a spatial split.
|
|
221
|
-
- A node's metric comes from the groups under it and needs no new geometry: every cluster of a
|
|
222
|
-
group shares the sphere and error of the step that consumed it — the same fact that makes
|
|
223
|
-
the group the atomic LOD decision — and monotonicity makes that one sphere cover everything
|
|
224
|
-
in it.
|
|
225
|
-
- Fanout 4, breadth-first, children contiguous, parents at lower indices than children.
|
|
226
|
-
Measured across spheres from 3k to 98k triangles at 8 KB–256 KB pages: **0.3%–1.6% of asset
|
|
227
|
-
size, trees one to three deep**.
|
|
228
|
-
- The validator earns its keep here. A node whose sphere does not cover its subtree drops
|
|
229
|
-
geometry that nothing downstream would notice, and a child-table metric is a *copy* that can
|
|
230
|
-
drift from the page it describes without that page being wrong. Both are checked, and both
|
|
231
|
-
checks have corruption tests behind them (VGEO_FORMAT §11.10–11.11).
|
|
232
|
-
|
|
233
|
-
#### On width at the root
|
|
234
|
-
|
|
235
|
-
The concern that a descent from one root cluster starves a GPU dispatch was overstated.
|
|
236
|
-
Nanite's queue is seeded with *the root cluster for each instance*, so width comes from the
|
|
237
|
-
instance count first and from fan-out immediately after — measured out-degree reaches 10 by
|
|
238
|
-
the middle bands of the 98k sphere. It bites only for a single instance in close-up, and only
|
|
239
|
-
for the first few bands, which are also the cheapest to walk.
|
|
240
|
-
|
|
241
|
-
### 2.3 The node tree has a reader; the child-table metric still does not — LANDED (half)
|
|
242
|
-
|
|
243
|
-
§2.2 built both, and the format specifies both: every child-table entry carries the child page's
|
|
244
|
-
LOD-metric sphere and error range (VGEO_FORMAT §5, §6.2), and every page carries a fanout-4 tree
|
|
245
|
-
over its own groups (§6.1). The writer emits them, `vgeo_validate_container` checks them
|
|
246
|
-
(§11.10–11.11) with corruption tests behind both checks, and **nothing reads either**.
|
|
247
|
-
`VGeoPage` records `node_count` and stops; `vgeo_select_cut` descends group by group.
|
|
248
|
-
|
|
249
|
-
This is not a defect to fix on its own account. Building a consumer for its own sake would fix
|
|
250
|
-
the interface before the pass that has to live with it, and the CPU traversal does not need the
|
|
251
|
-
acceleration — it walks a resident page set on a machine with branches. It is written down here
|
|
252
|
-
for two reasons: because "the validator checks it" reads exactly like "something uses it", and
|
|
253
|
-
because the cost is already paid — 0.3%–1.6% of asset size, on disk, in every asset already
|
|
254
|
-
built, earning nothing.
|
|
255
|
-
|
|
256
|
-
What it buys when the pass arrives, and what to hold it to:
|
|
257
|
-
|
|
258
|
-
- **Before the fetch.** A page can be frustum- and LOD-culled from its parent's child-table
|
|
259
|
-
entry, so a want list is exactly the pages that passed the test and are not resident, rather
|
|
260
|
-
than everything a descent happened to reach. Today the only way to learn a page was not wanted
|
|
261
|
-
is to fetch and decode it, which is backwards.
|
|
262
|
-
- **Below the page.** A node discards a region rather than a cluster, and gives the top of the
|
|
263
|
-
descent width it does not otherwise have.
|
|
264
|
-
|
|
265
|
-
Neither is measurable until there is a GPU traversal to measure, which is the honest reason it
|
|
266
|
-
has waited.
|
|
267
|
-
|
|
268
|
-
**What happened when the traversal arrived**, and it is not what this section predicted.
|
|
269
|
-
|
|
270
|
-
*Below the page*, the node tree has its reader. `runtime/cut/shader_vgeo_cut_traverse` descends it,
|
|
271
|
-
tests each node's sphere and `max_parent_error`, and discards a region rather than a cluster. The
|
|
272
|
-
cull fires across the whole agreement sweep and changes not one selected cluster, which is what
|
|
273
|
-
sound means for an accelerator. The 0.3%–1.6% of asset size is earning something now.
|
|
274
|
-
|
|
275
|
-
*Before the fetch*, the child-table metric **still has no reader, and now for a reason rather than
|
|
276
|
-
for want of a consumer.** Held against the cut, it buys nothing. A want is emitted from a cluster
|
|
277
|
-
that has already passed `project(parent) > τ` and `project(self) > τ`; the child page's metric
|
|
278
|
-
covers that cluster's child group among others, so its `max_parent_error` is at least that group's
|
|
279
|
-
`parent_error` and its sphere contains that group's `parent_sphere` — and the projection is monotone
|
|
280
|
-
in both. The page-level test is therefore **always** above τ at exactly the moment the question is
|
|
281
|
-
asked. It cannot reject what a per-cluster test has just accepted, because the per-cluster test is
|
|
282
|
-
strictly tighter. The frustum half dies the same way: the cluster's own `self_sphere` is a tighter
|
|
283
|
-
test than the child page's union sphere, available locally, for free.
|
|
284
|
-
|
|
285
|
-
Where the copy *is* load-bearing is **prefetch** — ranking and bounding pages nobody has asked for
|
|
286
|
-
yet, which by definition has no cluster-level evidence to be tighter than. `min_self_error` is in
|
|
287
|
-
the same position: it ranks a want and the cut never asks it anything. So the field is not dead, it
|
|
288
|
-
is early, and the thing it is early for is §3's territory rather than the cut's. Anyone building a
|
|
289
|
-
prefetch should start here.
|
|
290
|
-
|
|
291
|
-
## 3. Was waiting on a GPU runtime
|
|
292
|
-
|
|
293
|
-
Accepted, documented here so the reasoning is not lost. "Waiting on a runtime" used to mean waiting
|
|
294
|
-
on all of it; the runtime exists now (`runtime/`), so §3.1 has landed with it and the rest name what
|
|
295
|
-
they are actually waiting for.
|
|
296
|
-
|
|
297
|
-
### 3.1 Object-space refinement `[M §2.7]` — LANDED
|
|
298
|
-
|
|
299
|
-
`RefinementSpec.build` in `Micron/render/refinement/RefinementSpec.js`: multiply the camera's
|
|
300
|
-
view-projection by the instance transform once, derive the frustum planes from the result,
|
|
301
|
-
and run every cull and error test in **object space** against untransformed cluster bounds.
|
|
302
|
-
One matrix multiply per instance instead of transforming every cluster's bounds to world
|
|
303
|
-
space. With thousands of instances sharing one geometry that difference is the entire cost.
|
|
304
|
-
|
|
305
|
-
**Landed** with the cut. `runtime/cut/shader_vgeo_cut_collect` is the one place a VG transform is
|
|
306
|
-
touched: it multiplies the camera's view-projection by the instance transform, extracts the frustum
|
|
307
|
-
from the result, inverts the transform once for the eye, and writes both into the instance record.
|
|
308
|
-
Every cull and error test downstream runs against untransformed cluster bounds.
|
|
309
|
-
|
|
310
|
-
One thing fell out that `RefinementSpec.build` never had to face, because object space is not free
|
|
311
|
-
when an instance is scaled: error and distance are **both** object-space, so a *uniform* scale
|
|
312
|
-
cancels out of `r_e · k / d` exactly and needs no term at all. A non-uniform one does not, and the
|
|
313
|
-
correction is the ratio of the largest axis scale to the smallest — conservative, so it over-refines
|
|
314
|
-
rather than under-refines, and exactly 1 for every instance that is not stretched. Worth knowing
|
|
315
|
-
before anyone adds a scale term that does nothing in the common case.
|
|
316
|
-
|
|
317
|
-
### 3.2 Proxy geometry from a DAG cut `[M §2.6]`
|
|
318
|
-
|
|
319
|
-
`Micron/format/micron_build_proxy_geometry.js`: refine from the root with a heap keyed on
|
|
320
|
-
`-patch.lod` until a target polygon fraction is reached, and emit the result as an ordinary
|
|
321
|
-
mesh. Shadows, physics, raycasts, editor previews and impostors all want a cheap whole-object
|
|
322
|
-
mesh, and a cluster DAG hands one over for the cost of a heap walk.
|
|
323
|
-
|
|
324
|
-
Two consumers make this more than a convenience:
|
|
325
|
-
|
|
326
|
-
- A **shadow or secondary view** that does not justify its own cut can take a proxy instead
|
|
327
|
-
(§3.3).
|
|
328
|
-
- Anything outside the renderer — physics, navigation — that wants geometry without
|
|
329
|
-
understanding clusters.
|
|
330
|
-
|
|
331
|
-
### 3.3 One cut per view, and proxies where a cut is not worth it
|
|
332
|
-
|
|
333
|
-
**Correcting the design.** VIRTUAL_GEOMETRY_DESIGN §4 claimed the cut is "view-agnostic in
|
|
334
|
-
*coverage*" and that keeping it so is "what lets shadow views reuse it". That is wrong, and
|
|
335
|
-
the design has been corrected: virtual geometry is view-*dependent* by construction. A cut
|
|
336
|
-
selected for the main camera is selected at the main camera's distances and pixel budget, and
|
|
337
|
-
is simply the wrong cut for a shadow view — a light a hundred metres behind the camera wants
|
|
338
|
-
different clusters, and a cascade wants a different set again. Epic acknowledge computing
|
|
339
|
-
several cuts per frame for exactly this reason.
|
|
340
|
-
|
|
341
|
-
So the plan is **a cut per view**, with the setup shared rather than the result: the traversal
|
|
342
|
-
kernel, the residency state, and the page working set are all view-independent, and only the
|
|
343
|
-
projection and threshold differ. That half is built — a cut runs per expansion site per view, and
|
|
344
|
-
what it costs is measured in CUT_PLAN_2026_09_14 §0, which also plans to keep each view's cut
|
|
345
|
-
between frames rather than re-walking it from the root. And where a view does not justify a cut
|
|
346
|
-
at all — a distant cascade, a low-resolution reflection — it should be able to take a proxy
|
|
347
|
-
(§3.2) instead. That choice belongs to the view, not to the geometry.
|
|
348
|
-
|
|
349
|
-
### 3.4 GPU-driven allocation `[V §4.3]`
|
|
350
|
-
|
|
351
|
-
**Narrower now, and the runtime says exactly how much.** A VG page is one arena allocation holding
|
|
352
|
-
its node, group and cluster rows back to back, and an eviction frees one allocation and writes one
|
|
353
|
-
lookup word. Nothing inside a resident page can move, growth appends through `OffsetAllocator#grow`
|
|
354
|
-
and relocates nothing, and no address migrates. What VG's churn *does* still reach is
|
|
355
|
-
`GPUMeshletManager`: a page install is an `add_batch` and an eviction a `remove_batch`, so the holes
|
|
356
|
-
accumulate in that pool and closing them is still a CPU-side rebuild with the unhandled
|
|
357
|
-
address-migration TODO downstream of it. Pages are near-uniform in size, so a hole is usually
|
|
358
|
-
re-usable by the next install — which narrows the problem without closing it, and is the reason this
|
|
359
|
-
is still an item rather than an incident.
|
|
360
|
-
|
|
361
|
-
Worth pursuing **beyond virtual geometry** — this is a GPU-driven engine and CPU-side
|
|
362
|
-
allocation for GPU-resident data is a standing mismatch.
|
|
363
|
-
|
|
364
|
-
`vk_lod_clusters/docs/clas_allocation.md` reports host-side size estimates running "often 3-5x
|
|
365
|
-
bigger than actual" and moves allocation on-device, reading back true sizes. Two designs are
|
|
366
|
-
given: naive dense compaction (discouraged — "high memory movement bursts") and a
|
|
367
|
-
**device-resident allocator that relocates an allocation once, after construction**, with a
|
|
368
|
-
free-gap list maintained on the GPU —
|
|
369
|
-
`shaders/stream_allocator_build_freegaps.comp.glsl`,
|
|
370
|
-
`shaders/stream_allocator_freegaps_insert.comp.glsl`,
|
|
371
|
-
`shaders/stream_allocator_load_groups.comp.glsl`,
|
|
372
|
-
`shaders/stream_allocator_unload_groups.comp.glsl`.
|
|
373
|
-
|
|
374
|
-
The mirror-image problem on our side is recorded in design §2: `GPUMeshletManager`'s
|
|
375
|
-
*compaction* is a CPU-side rebuild costing ~2× VRAM transiently, and meshlet-address migration
|
|
376
|
-
is an acknowledged unhandled TODO in `GPUGeometryManager`. Growth has stopped being a rebuild
|
|
377
|
-
since this was written — it appends through `OffsetAllocator#grow` and moves no record — which
|
|
378
|
-
narrows the problem to exactly the case VG churn produces: closing holes, not adding room.
|
|
379
|
-
|
|
380
|
-
## 4. Was blocking
|
|
381
|
-
|
|
382
|
-
### 4.1 Boundary constraint quadrics — LANDED
|
|
383
|
-
|
|
384
|
-
Was the single most important open item, and had been listed as a required simplifier
|
|
385
|
-
extension in design §2 from the start. It became load-bearing rather than latent once the
|
|
386
|
-
round loop began converging through boundary erosion: an asset built over open geometry
|
|
387
|
-
recorded error that was not merely optimistic but wrong. Measured before the fix: 400 loose
|
|
388
|
-
triangles built a root of 25 triangles carrying `self_error = 0`, and `project((s, 0)) ≡ 0`
|
|
389
|
-
means such a root is selected at any distance and never refined. Nothing downstream could
|
|
390
|
-
catch it — the validator checks monotonicity, and zero is monotonic.
|
|
391
|
-
|
|
392
|
-
`bt_mesh_compute_vertex_quadrics` now adds, for every edge whose face count is not two, the
|
|
393
|
-
plane through it perpendicular to its face, weighted. A face-plane quadric says only how far a
|
|
394
|
-
vertex has moved *off* the surface and by construction says nothing about it sliding *along*
|
|
395
|
-
one; for an interior vertex that is right, and for a vertex on a border it is exactly wrong.
|
|
396
|
-
Non-manifold edges are treated the same way and for the same reason — a seam is no freer to
|
|
397
|
-
move than a border.
|
|
398
|
-
|
|
399
|
-
Two things fell out that are worth knowing:
|
|
400
|
-
|
|
401
|
-
- **Weight 3, measured.** The error a vertex reports is the mean over its planes, so a border
|
|
402
|
-
vertex with a handful of faces and two constraint planes has the retreat diluted threefold
|
|
403
|
-
at weight one. Three brings it back to roughly the displacement itself while leaving the
|
|
404
|
-
border free enough to erode at all — which it must, or a mesh of open shells has no coarse
|
|
405
|
-
form and no root.
|
|
406
|
-
- **The measurement had a second hole, and it was the larger one.** Taking the error as the
|
|
407
|
-
max over *surviving* vertices misses geometry that vanished outright: a patch consumed
|
|
408
|
-
whole leaves a vertex belonging to no face, which is swept away by cleanup, and that vertex
|
|
409
|
-
is the only thing still holding the quadric of what used to be there. A triangle soup
|
|
410
|
-
simplifies by *deleting* triangles, so this reported the loss of most of a model as free
|
|
411
|
-
even with boundary quadrics in place. `bt_mesh_simplify` now measures before the cleanup
|
|
412
|
-
and returns the object-space distance the surface moved — which is also a better return
|
|
413
|
-
value than the raw squared residual it used to give, and nothing outside its own specs was
|
|
414
|
-
reading that.
|
|
415
|
-
|
|
416
|
-
Result: the 400-triangle soup now reports 0.22 at its first merge rising to 0.39 at the root,
|
|
417
|
-
on triangles about a unit across. A **flat** sheet still reports exactly zero at every level,
|
|
418
|
-
which is the other half of the contract — a flat surface is exactly representable at any
|
|
419
|
-
triangle count, and a vertex partway along a straight border slides off without changing the
|
|
420
|
-
outline. Its corners are not free, which is what stops it collapsing to nothing.
|
|
421
|
-
|
|
422
|
-
### 4.2 Payload size
|
|
423
|
-
|
|
424
|
-
Deferred deliberately; it is a separate campaign. Two threads, in the order they should be
|
|
425
|
-
attacked:
|
|
426
|
-
|
|
427
|
-
- **Mantissa-bit dropping** `[V §3.5, §6.6]`. The nvpro README recommends dropping low
|
|
428
|
-
mantissa bits of positions and UVs ahead of its lossless group compression. It keeps the
|
|
429
|
-
float32 layout, the metadata struct and every decode shader exactly as they are, and simply
|
|
430
|
-
makes the bytes compress. A fraction of the work of quantization for a real share of the
|
|
431
|
-
benefit, and it composes with the page codec, which has since shipped: LZ4 finds only
|
|
432
|
-
1.12x–1.18x on today's payloads *because* float32 positions give an LZ matcher nothing, and
|
|
433
|
-
dropping mantissa bits is how you give it something.
|
|
434
|
-
- **Cluster-local position quantization**, as design §2 describes — invasive, spanning
|
|
435
|
-
encode, the metadata struct and every decode shader.
|
|
436
|
-
|
|
437
|
-
## 5. Considered and declined
|
|
438
|
-
|
|
439
|
-
- **Backface normal-cone culling** `[M §2.3]` — the `cone_reserved` field, a producer for it,
|
|
440
|
-
and the cull pass that would read it. **Declined: the HZB already rejects what a cone would,
|
|
441
|
-
and it does it on evidence rather than on a bound.** On a closed surface backfacing *is*
|
|
442
|
-
occluded, and §7's two-pass HZB sees that; what a cone adds over it is pre-emption by one
|
|
443
|
-
pass, bought with per-cluster data and a per-cluster test in the cull pass, every frame and
|
|
444
|
-
per view. It pays best where cones are tight — flat clusters, which are also the cheapest
|
|
445
|
-
to raster — and degrades exactly where a cut spends its clusters, because a group's cone
|
|
446
|
-
widens toward hemispherical as the levels coarsen. Micron paid for tight cones by scoring
|
|
447
|
-
merges on cone angle (`[M §2.3]`), which is the real price: grouping stops being a purely
|
|
448
|
-
spatial criterion in order to feed a cull that the HZB was already doing.
|
|
449
|
-
|
|
450
|
-
This is not our finding alone, which is why it is a decline rather than an experiment: Epic
|
|
451
|
-
did not ship it in Nanite, meshoptimizer's author argues against the payoff despite the
|
|
452
|
-
library exposing cone data, and Remedy report the same for Northlight. Taken together with
|
|
453
|
-
the mechanism above, there is nothing left to measure.
|
|
454
|
-
|
|
455
|
-
Consequences, so that nobody re-derives them: `cone_reserved` was a zeroed reserved u32 until
|
|
456
|
-
`format_version` 5 (format §7) — reclaiming 4 bytes of 112 was never worth a version move on its
|
|
457
|
-
own, and it went when `subtree_aabb` needed 24 and the version moved anyway. `bt_face_cluster_compute_normal_bounding_cone`
|
|
458
|
-
has no consumer and no prospect of one.
|
|
459
|
-
- **Fixed-size residency slots** `[M §2.5]`. Micron gives every resident patch one slot of
|
|
460
|
-
`MICRON_PATCH_SIZE_MAX × 3` vertices with occupancy in a BitSet: no allocator, no
|
|
461
|
-
fragmentation, no address migration, at the cost of internal fragmentation proportional to
|
|
462
|
-
`1 − fill`. **Declined: pages already are the compaction mechanism.** A page is fixed-size
|
|
463
|
-
and carries whole groups; the lever to pull is page waste, by keeping clusters full — which
|
|
464
|
-
§1's cluster-count target and repack are for — not by giving up variable-size allocation.
|
|
465
|
-
|
|
466
|
-
*(2026-09-12: "by construction" was the original wording and it was not true — the builder
|
|
467
|
-
overran `nominal_page_size` whenever a group did not fit, and the format told readers not to
|
|
468
|
-
assume the number at all. It is true now, by enforcement rather than by construction:
|
|
469
|
-
FORMAT §11.14, the builder refusing a page size no group fits, and the validator behind it.
|
|
470
|
-
The conclusion this bullet reaches is unchanged; the premise had to be made real first.)*
|
|
471
|
-
- **Shape-aware greedy leaf clustering** `[M §2.8]`. Micron grows leaf patches with a heap
|
|
472
|
-
scored on perimeter change, added-neighbour count, and "open face freedom" — how many of a
|
|
473
|
-
candidate face's neighbours are about to be stranded
|
|
474
|
-
(`Micron/build/clustering/computeOpenFaceFreedom.js`). **Declined: we lean on METIS
|
|
475
|
-
heavily**, and replacing it with a bespoke region grower is a large step away from a
|
|
476
|
-
partitioner that is tested and shared with the navmesh and graph code. We get the
|
|
477
|
-
anti-stranding effect structurally instead, in `absorb_singleton_pieces` — after the
|
|
478
|
-
partition rather than before it, which is weaker but far cheaper to own.
|
|
479
|
-
- **Spectral partitioning as a primary partitioner** `[M §3.3]`. Dense Laplacian
|
|
480
|
-
eigen-decomposition is O(n²) in memory. Kept only as the failure fallback in §2.1.
|
|
481
|
-
- **Crack repair instead of crack prevention** `[M §3.2]`. `patch_fill_holes_by_uncollapse`
|
|
482
|
-
and `patch_stitch_parent_border` are dead code in Micron — a road already walked. Locked
|
|
483
|
-
perimeters won.
|