@woosh/meep-engine 3.28.0 → 3.30.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/bundle-worker-image-decoder.js +1 -1
- package/build/bundle-worker-terrain.js +1 -1
- package/package.json +1 -1
- package/src/core/binary/BinaryBuffer.d.ts.map +1 -1
- package/src/core/binary/BinaryBuffer.js +14 -2
- package/src/core/binary/BitSet.d.ts +16 -0
- package/src/core/binary/BitSet.d.ts.map +1 -1
- package/src/core/binary/BitSet.js +159 -49
- package/src/core/binary/allocator/OffsetAllocator.d.ts +48 -0
- package/src/core/binary/allocator/OffsetAllocator.d.ts.map +1 -1
- package/src/core/binary/allocator/OffsetAllocator.js +208 -9
- package/src/core/binary/compression/compress_bytes.d.ts +20 -0
- package/src/core/binary/compression/compress_bytes.d.ts.map +1 -0
- package/src/core/binary/compression/compress_bytes.js +35 -0
- package/src/core/binary/compression/decompress_bytes_into.d.ts +30 -0
- package/src/core/binary/compression/decompress_bytes_into.d.ts.map +1 -0
- package/src/core/binary/compression/decompress_bytes_into.js +87 -0
- package/src/core/binary/compression/deflate_decompress_bound.d.ts +27 -0
- package/src/core/binary/compression/deflate_decompress_bound.d.ts.map +1 -0
- package/src/core/binary/compression/deflate_decompress_bound.js +32 -0
- package/src/core/bvh2/bvh3/BVH.d.ts.map +1 -1
- package/src/core/bvh2/bvh3/BVH.js +14 -1
- package/src/core/cache/FrequencySketch.d.ts +3 -1
- package/src/core/cache/FrequencySketch.d.ts.map +1 -1
- package/src/core/cache/FrequencySketch.js +10 -4
- package/src/core/cache/wtinylfu/CacheWTinylfu.d.ts.map +1 -1
- package/src/core/cache/wtinylfu/CacheWTinylfu.js +24 -2
- package/src/core/geom/3d/quadric/quadric_attribute_add.d.ts +24 -0
- package/src/core/geom/3d/quadric/quadric_attribute_add.d.ts.map +1 -0
- package/src/core/geom/3d/quadric/quadric_attribute_add.js +31 -0
- package/src/core/geom/3d/quadric/quadric_attribute_reduce.d.ts +46 -0
- package/src/core/geom/3d/quadric/quadric_attribute_reduce.d.ts.map +1 -0
- package/src/core/geom/3d/quadric/quadric_attribute_reduce.js +104 -0
- package/src/core/geom/3d/quadric/quadric_attribute_set_from_triangle.d.ts +62 -0
- package/src/core/geom/3d/quadric/quadric_attribute_set_from_triangle.d.ts.map +1 -0
- package/src/core/geom/3d/quadric/quadric_attribute_set_from_triangle.js +158 -0
- package/src/core/geom/3d/quadric/quadric_attribute_size.d.ts +21 -0
- package/src/core/geom/3d/quadric/quadric_attribute_size.d.ts.map +1 -0
- package/src/core/geom/3d/quadric/quadric_attribute_size.js +24 -0
- package/src/core/geom/3d/quadric/quadric_attribute_solve.d.ts +34 -0
- package/src/core/geom/3d/quadric/quadric_attribute_solve.d.ts.map +1 -0
- package/src/core/geom/3d/quadric/quadric_attribute_solve.js +55 -0
- package/src/core/geom/3d/quadric/quadric_attribute_sub.d.ts +28 -0
- package/src/core/geom/3d/quadric/quadric_attribute_sub.d.ts.map +1 -0
- package/src/core/geom/3d/quadric/quadric_attribute_sub.js +35 -0
- package/src/core/geom/3d/topology/struct/binary/BinaryDataBlock.d.ts +15 -0
- package/src/core/geom/3d/topology/struct/binary/BinaryDataBlock.d.ts.map +1 -1
- package/src/core/geom/3d/topology/struct/binary/BinaryDataBlock.js +35 -0
- package/src/core/geom/3d/topology/struct/binary/BtWedgeSet.d.ts +93 -0
- package/src/core/geom/3d/topology/struct/binary/BtWedgeSet.d.ts.map +1 -0
- package/src/core/geom/3d/topology/struct/binary/BtWedgeSet.js +128 -0
- package/src/core/geom/3d/topology/struct/binary/io/bt_mesh_compute_vertex_quadrics.d.ts +20 -0
- package/src/core/geom/3d/topology/struct/binary/io/bt_mesh_compute_vertex_quadrics.d.ts.map +1 -1
- package/src/core/geom/3d/topology/struct/binary/io/bt_mesh_compute_vertex_quadrics.js +69 -4
- package/src/core/geom/3d/topology/struct/binary/io/bt_mesh_compute_wedge_attribute_quadrics.d.ts +38 -0
- package/src/core/geom/3d/topology/struct/binary/io/bt_mesh_compute_wedge_attribute_quadrics.d.ts.map +1 -0
- package/src/core/geom/3d/topology/struct/binary/io/bt_mesh_compute_wedge_attribute_quadrics.js +113 -0
- package/src/core/geom/3d/topology/struct/binary/io/bt_mesh_simplify.d.ts +93 -17
- package/src/core/geom/3d/topology/struct/binary/io/bt_mesh_simplify.d.ts.map +1 -1
- package/src/core/geom/3d/topology/struct/binary/io/bt_mesh_simplify.js +930 -69
- package/src/core/geom/3d/topology/struct/binary/io/bt_wedges_live_count.d.ts +22 -0
- package/src/core/geom/3d/topology/struct/binary/io/bt_wedges_live_count.d.ts.map +1 -0
- package/src/core/geom/3d/topology/struct/binary/io/bt_wedges_live_count.js +46 -0
- package/src/core/geom/3d/topology/struct/binary/io/bt_wedges_per_vertex.d.ts +19 -0
- package/src/core/geom/3d/topology/struct/binary/io/bt_wedges_per_vertex.d.ts.map +1 -0
- package/src/core/geom/3d/topology/struct/binary/io/bt_wedges_per_vertex.js +49 -0
- package/src/core/geom/3d/topology/struct/binary/query/bt_edge_collapse_fold_limit.d.ts +25 -0
- package/src/core/geom/3d/topology/struct/binary/query/bt_edge_collapse_fold_limit.d.ts.map +1 -0
- package/src/core/geom/3d/topology/struct/binary/query/bt_edge_collapse_fold_limit.js +228 -0
- package/src/core/geom/3d/topology/struct/binary/query/bt_edge_collapse_would_fold.d.ts +13 -0
- package/src/core/geom/3d/topology/struct/binary/query/bt_edge_collapse_would_fold.d.ts.map +1 -1
- package/src/core/geom/3d/topology/struct/binary/query/bt_edge_collapse_would_fold.js +10 -128
- package/src/core/geom/3d/topology/struct/binary/query/bt_mesh_build_face_bvh.d.ts.map +1 -1
- package/src/core/geom/3d/topology/struct/binary/query/bt_mesh_build_face_bvh.js +11 -1
- package/src/core/graph/layout/layered/BoxLayoutOptions.d.ts +63 -0
- package/src/core/graph/layout/layered/BoxLayoutOptions.d.ts.map +1 -0
- package/src/core/graph/layout/layered/BoxLayoutOptions.js +80 -0
- package/src/core/{model/node-graph/visual/layout → graph/layout/layered}/LayoutBoxGraph.d.ts +35 -0
- package/src/core/graph/layout/layered/LayoutBoxGraph.d.ts.map +1 -0
- package/src/core/{model/node-graph/visual/layout → graph/layout/layered}/LayoutBoxGraph.js +53 -1
- package/src/core/graph/layout/layered/layout_assign_coordinates.d.ts.map +1 -0
- package/src/core/{model/node-graph/visual/layout → graph/layout/layered}/layout_assign_coordinates.js +72 -68
- package/src/core/graph/layout/layered/layout_assign_layers.d.ts.map +1 -0
- package/src/core/{model/node-graph/visual/layout → graph/layout/layered}/layout_assign_layers.js +4 -2
- package/src/core/graph/layout/layered/layout_break_cycles.d.ts.map +1 -0
- package/src/core/graph/layout/layered/layout_insert_lanes.d.ts.map +1 -0
- package/src/core/graph/layout/layered/layout_order_layers.d.ts.map +1 -0
- package/src/core/graph/layout/layered/layout_orient_links.d.ts.map +1 -0
- package/src/core/graph/mn_graph_collapse_weighted_edge.js +6 -6
- package/src/core/math/lookup/ParameterLookupTable.d.ts.map +1 -1
- package/src/core/math/lookup/ParameterLookupTable.js +10 -5
- package/src/core/math/noise/sdnoise.d.ts.map +1 -1
- package/src/core/math/noise/sdnoise.js +16 -10
- package/src/core/model/node-graph/visual/layout/NodeGraphLayoutOptions.d.ts +7 -51
- package/src/core/model/node-graph/visual/layout/NodeGraphLayoutOptions.d.ts.map +1 -1
- package/src/core/model/node-graph/visual/layout/NodeGraphLayoutOptions.js +8 -69
- package/src/core/model/node-graph/visual/layout/layout_build_problem.js +1 -1
- package/src/core/model/node-graph/visual/layout/layout_node_graph.js +6 -6
- package/src/core/model/node-graph/visual/layout/route_grid_build.js +1 -1
- package/src/core/model/object/ImmutableObjectPool.d.ts.map +1 -1
- package/src/core/model/object/ImmutableObjectPool.js +17 -7
- package/src/core/process/executor/ConcurrentExecutor.d.ts +1 -5
- package/src/core/process/executor/ConcurrentExecutor.d.ts.map +1 -1
- package/src/core/process/executor/ConcurrentExecutor.js +95 -1
- package/src/core/process/task/task_find_dependency_cycle.d.ts +17 -0
- package/src/core/process/task/task_find_dependency_cycle.d.ts.map +1 -0
- package/src/core/process/task/task_find_dependency_cycle.js +81 -0
- package/src/core/wfc/WFCCellChoice.d.ts +17 -0
- package/src/core/wfc/WFCCellChoice.d.ts.map +1 -0
- package/src/core/wfc/WFCCellChoice.js +36 -0
- package/src/core/wfc/WFCLattice.d.ts +105 -0
- package/src/core/wfc/WFCLattice.d.ts.map +1 -0
- package/src/core/wfc/WFCLattice.js +235 -0
- package/src/core/wfc/WFCRuleTable.d.ts +172 -0
- package/src/core/wfc/WFCRuleTable.d.ts.map +1 -0
- package/src/core/wfc/WFCRuleTable.js +334 -0
- package/src/core/wfc/WFCState.d.ts +273 -0
- package/src/core/wfc/WFCState.d.ts.map +1 -0
- package/src/core/wfc/WFCState.js +552 -0
- package/src/core/wfc/WFCStatus.d.ts +11 -0
- package/src/core/wfc/WFCStatus.d.ts.map +1 -0
- package/src/core/wfc/WFCStatus.js +28 -0
- package/src/core/wfc/WFCTileWeights.d.ts +48 -0
- package/src/core/wfc/WFCTileWeights.d.ts.map +1 -0
- package/src/core/wfc/WFCTileWeights.js +86 -0
- package/src/core/wfc/WFC_UNRESOLVED.d.ts +12 -0
- package/src/core/wfc/WFC_UNRESOLVED.d.ts.map +1 -0
- package/src/core/wfc/WFC_UNRESOLVED.js +11 -0
- package/src/core/wfc/wfc_estimate_bytes.d.ts +24 -0
- package/src/core/wfc/wfc_estimate_bytes.d.ts.map +1 -0
- package/src/core/wfc/wfc_estimate_bytes.js +47 -0
- package/src/core/wfc/wfc_rule_table_tile_components.d.ts +27 -0
- package/src/core/wfc/wfc_rule_table_tile_components.d.ts.map +1 -0
- package/src/core/wfc/wfc_rule_table_tile_components.js +80 -0
- package/src/core/wfc/wfc_solve.d.ts +21 -0
- package/src/core/wfc/wfc_solve.d.ts.map +1 -0
- package/src/core/wfc/wfc_solve.js +154 -0
- package/src/core/wfc/wfc_state_apply_boundary.d.ts +18 -0
- package/src/core/wfc/wfc_state_apply_boundary.d.ts.map +1 -0
- package/src/core/wfc/wfc_state_apply_boundary.js +61 -0
- package/src/core/wfc/wfc_state_assign.d.ts +11 -0
- package/src/core/wfc/wfc_state_assign.d.ts.map +1 -0
- package/src/core/wfc/wfc_state_assign.js +36 -0
- package/src/core/wfc/wfc_state_ban_bits.d.ts +17 -0
- package/src/core/wfc/wfc_state_ban_bits.d.ts.map +1 -0
- package/src/core/wfc/wfc_state_ban_bits.js +81 -0
- package/src/core/wfc/wfc_state_collapse.d.ts +12 -0
- package/src/core/wfc/wfc_state_collapse.d.ts.map +1 -0
- package/src/core/wfc/wfc_state_collapse.js +73 -0
- package/src/core/wfc/wfc_state_flush_dirty.d.ts +12 -0
- package/src/core/wfc/wfc_state_flush_dirty.d.ts.map +1 -0
- package/src/core/wfc/wfc_state_flush_dirty.js +39 -0
- package/src/core/wfc/wfc_state_propagate.d.ts +14 -0
- package/src/core/wfc/wfc_state_propagate.d.ts.map +1 -0
- package/src/core/wfc/wfc_state_propagate.js +155 -0
- package/src/core/wfc/wfc_state_read.d.ts +11 -0
- package/src/core/wfc/wfc_state_read.d.ts.map +1 -0
- package/src/core/wfc/wfc_state_read.js +38 -0
- package/src/core/wfc/wfc_state_restrict.d.ts +18 -0
- package/src/core/wfc/wfc_state_restrict.d.ts.map +1 -0
- package/src/core/wfc/wfc_state_restrict.js +39 -0
- package/src/core/wfc/wfc_state_set_eligible.d.ts +24 -0
- package/src/core/wfc/wfc_state_set_eligible.d.ts.map +1 -0
- package/src/core/wfc/wfc_state_set_eligible.js +49 -0
- package/src/core/wfc/wfc_state_undo_to.d.ts +13 -0
- package/src/core/wfc/wfc_state_undo_to.d.ts.map +1 -0
- package/src/core/wfc/wfc_state_undo_to.js +84 -0
- package/src/core/wfc/wfc_words_per_cell.d.ts +11 -0
- package/src/core/wfc/wfc_words_per_cell.d.ts.map +1 -0
- package/src/core/wfc/wfc_words_per_cell.js +16 -0
- package/src/engine/ecs/EntityComponentDataset.d.ts +8 -0
- package/src/engine/ecs/EntityComponentDataset.d.ts.map +1 -1
- package/src/engine/ecs/EntityComponentDataset.js +37 -14
- package/src/engine/ecs/fow/FogOfWarRevealerSystem.d.ts +8 -1
- package/src/engine/ecs/fow/FogOfWarRevealerSystem.d.ts.map +1 -1
- package/src/engine/ecs/fow/FogOfWarRevealerSystem.js +37 -2
- package/src/engine/ecs/guid/UUID.d.ts.map +1 -1
- package/src/engine/ecs/guid/UUID.js +45 -17
- package/src/engine/ecs/ik/OneBoneSurfaceAlignmentSolver.d.ts.map +1 -1
- package/src/engine/ecs/ik/OneBoneSurfaceAlignmentSolver.js +3 -1
- package/src/engine/ecs/terrain/ecs/cling/ClingToTerrainSystem.d.ts.map +1 -1
- package/src/engine/ecs/terrain/ecs/cling/ClingToTerrainSystem.js +366 -360
- package/src/engine/graphics/texture/sampler/resize/sampler2d_scale_down_linear.d.ts.map +1 -1
- package/src/engine/graphics/texture/sampler/resize/sampler2d_scale_down_linear.js +24 -10
- package/src/engine/graphics3/DebugDrawSystem.d.ts +7 -5
- package/src/engine/graphics3/DebugDrawSystem.d.ts.map +1 -1
- package/src/engine/graphics3/DebugDrawSystem.js +206 -203
- package/src/engine/graphics3/DecalSystem.d.ts +4 -5
- package/src/engine/graphics3/DecalSystem.d.ts.map +1 -1
- package/src/engine/graphics3/DecalSystem.js +5 -5
- package/src/engine/graphics3/FogOfWarSystem.d.ts +7 -12
- package/src/engine/graphics3/FogOfWarSystem.d.ts.map +1 -1
- package/src/engine/graphics3/FogOfWarSystem.js +8 -12
- package/src/engine/graphics3/prefab/prefab_instantiate.js +230 -230
- package/src/engine/grid/grid2transform/GridPosition2TransformSystem.d.ts.map +1 -1
- package/src/engine/grid/grid2transform/GridPosition2TransformSystem.js +24 -5
- package/src/engine/interpolation/Interpoland.d.ts +7 -1
- package/src/engine/interpolation/Interpoland.d.ts.map +1 -1
- package/src/engine/interpolation/Interpoland.js +8 -1
- package/src/engine/interpolation/InterpolationSystem.d.ts.map +1 -1
- package/src/engine/interpolation/InterpolationSystem.js +3 -0
- package/src/engine/interpolation/TransformPoseSerializationAdapter.d.ts +5 -3
- package/src/engine/interpolation/TransformPoseSerializationAdapter.d.ts.map +1 -1
- package/src/engine/interpolation/TransformPoseSerializationAdapter.js +14 -3
- package/src/engine/interpolation/pose_interpoland.d.ts.map +1 -1
- package/src/engine/interpolation/pose_interpoland.js +2 -0
- package/src/engine/network/orchestrator/NetworkPeer.d.ts.map +1 -1
- package/src/engine/network/orchestrator/NetworkPeer.js +15 -10
- package/src/engine/physics/cloth/ecs/ClothWorld.d.ts.map +1 -1
- package/src/engine/physics/cloth/ecs/ClothWorld.js +17 -0
- package/src/engine/physics/mls-mpm/MLS_MPM.d.ts.map +1 -1
- package/src/engine/physics/mls-mpm/MLS_MPM.js +14 -0
- package/src/engine/sound/sopra/definition/clip/AbstractAudioClip.d.ts +2 -1
- package/src/engine/sound/sopra/definition/clip/AbstractAudioClip.d.ts.map +1 -1
- package/src/engine/sound/sopra/definition/clip/AbstractAudioClip.js +1 -1
- package/src/engine/sound/sopra/definition/clip/BlendContainerAudioClip.d.ts +1 -0
- package/src/engine/sound/sopra/definition/clip/BlendContainerAudioClip.d.ts.map +1 -1
- package/src/engine/sound/sopra/definition/clip/RandomContainerAudioClip.d.ts +1 -0
- package/src/engine/sound/sopra/definition/clip/RandomContainerAudioClip.d.ts.map +1 -1
- package/src/engine/sound/sopra/definition/clip/SampleAudioClip.d.ts +2 -1
- package/src/engine/sound/sopra/definition/clip/SampleAudioClip.d.ts.map +1 -1
- package/src/engine/sound/sopra/definition/clip/SampleAudioClip.js +12 -3
- package/src/engine/sound/sopra/definition/clip/SequenceContainerAudioClip.d.ts +1 -0
- package/src/engine/sound/sopra/definition/clip/SequenceContainerAudioClip.d.ts.map +1 -1
- package/src/engine/sound/sopra/definition/clip/SwitchContainerAudioClip.d.ts +1 -0
- package/src/engine/sound/sopra/definition/clip/SwitchContainerAudioClip.d.ts.map +1 -1
- package/src/engine/sound/sopra/runtime/EventInstance.d.ts.map +1 -1
- package/src/engine/sound/sopra/runtime/EventInstance.js +4 -1
- package/src/format/image/avif/av1/decode/decode_coefficients.d.ts.map +1 -1
- package/src/format/image/avif/av1/decode/decode_coefficients.js +248 -259
- package/src/format/image/avif/av1/decode/read_golomb.d.ts +21 -0
- package/src/format/image/avif/av1/decode/read_golomb.d.ts.map +1 -0
- package/src/format/image/avif/av1/decode/read_golomb.js +49 -0
- package/src/format/image/avif/av1/filter/loop_restoration.js +461 -451
- package/src/format/image/avif/av1/util/round2.d.ts +19 -2
- package/src/format/image/avif/av1/util/round2.d.ts.map +1 -1
- package/src/format/image/avif/av1/util/round2.js +51 -27
- package/src/format/image/avif/heif/parse_avif_file.js +24 -0
- package/src/shade/RENDERER_CONTRACT.md +12 -7
- package/src/shade/playground/caldera/README.md +529 -0
- package/src/shade/playground/caldera/caldera_format.d.ts +151 -0
- package/src/shade/playground/caldera/caldera_format.d.ts.map +1 -0
- package/src/shade/playground/caldera/caldera_format.js +241 -0
- package/src/shade/playground/caldera/index.html +126 -0
- package/src/shade/playground/caldera/main.d.ts.map +1 -0
- package/src/shade/playground/caldera/main.js +1565 -0
- package/src/shade/playground/mesh_row_ceiling/README.md +85 -0
- package/src/shade/playground/mesh_row_ceiling/index.html +31 -0
- package/src/shade/playground/mesh_row_ceiling/main.d.ts +2 -0
- package/src/shade/playground/mesh_row_ceiling/main.d.ts.map +1 -0
- package/src/shade/playground/mesh_row_ceiling/main.js +389 -0
- package/src/shade/playground/vgeo_runtime/README.md +5 -3
- package/src/shade/playground/vgeo_runtime/main.js +3 -2
- package/src/shade/playground/vgeo_runtime/sample_asset.d.ts +3 -3
- package/src/shade/playground/vgeo_runtime/sample_asset.d.ts.map +1 -1
- package/src/shade/playground/vgeo_runtime/sample_asset.js +3 -3
- package/src/shade/playground/vgeo_scene/README.md +103 -24
- package/src/shade/playground/vgeo_scene/main.js +525 -24
- package/src/shade/renderer/GraphicsContext.d.ts.map +1 -1
- package/src/shade/renderer/GraphicsContext.js +6 -0
- package/src/shade/renderer/Renderer.d.ts +2 -0
- package/src/shade/renderer/Renderer.d.ts.map +1 -1
- package/src/shade/renderer/Renderer.js +23 -0
- package/src/shade/renderer/animation/skinning/GPUMeshSkinningContext.d.ts.map +1 -1
- package/src/shade/renderer/animation/skinning/GPUMeshSkinningContext.js +100 -8
- package/src/shade/renderer/buffer/table/GPUTypedTable.d.ts.map +1 -1
- package/src/shade/renderer/buffer/table/GPUTypedTable.js +14 -0
- package/src/shade/renderer/extension/RENDER_EXTENSION_DESIGN.md +69 -33
- package/src/shade/renderer/extension/RenderExtension.d.ts +15 -18
- package/src/shade/renderer/extension/RenderExtension.d.ts.map +1 -1
- package/src/shade/renderer/extension/RenderExtension.js +15 -19
- package/src/shade/renderer/extension/RenderExtensionRegistry.d.ts +5 -5
- package/src/shade/renderer/extension/RenderExtensionRegistry.d.ts.map +1 -1
- package/src/shade/renderer/extension/RenderExtensionRegistry.js +29 -166
- package/src/shade/renderer/geometry/GPUGeometryManager.d.ts.map +1 -1
- package/src/shade/renderer/geometry/GPUGeometryManager.js +73 -16
- package/src/shade/renderer/geometry/bvh/GPUGeometryBVHManager.d.ts.map +1 -1
- package/src/shade/renderer/geometry/bvh/GPUGeometryBVHManager.js +18 -3
- package/src/shade/renderer/geometry/meshlet/COMPACTION_PLAN_2026_09_16.md +663 -0
- package/src/shade/renderer/geometry/meshlet/GPUMeshletManager.d.ts +100 -5
- package/src/shade/renderer/geometry/meshlet/GPUMeshletManager.d.ts.map +1 -1
- package/src/shade/renderer/geometry/meshlet/GPUMeshletManager.js +688 -81
- package/src/shade/renderer/geometry/virtual/ATTRIBUTE_PLAN_2026_09_18.md +540 -0
- package/src/shade/renderer/geometry/virtual/VGEO_FORMAT.md +155 -64
- package/src/shade/renderer/geometry/virtual/VIRTUAL_GEOMETRY_DESIGN.md +76 -16
- package/src/shade/renderer/geometry/virtual/VIRTUAL_GEOMETRY_PLAN.md +3 -3
- package/src/shade/renderer/geometry/virtual/WEDGE_PLAN_2026_09_18.md +448 -0
- package/src/shade/renderer/geometry/virtual/build/VGeoBuildOptions.d.ts +44 -7
- package/src/shade/renderer/geometry/virtual/build/VGeoBuildOptions.d.ts.map +1 -1
- package/src/shade/renderer/geometry/virtual/build/VGeoBuildOptions.js +48 -9
- package/src/shade/renderer/geometry/virtual/build/level/VGeoContribution.d.ts +40 -0
- package/src/shade/renderer/geometry/virtual/build/level/VGeoContribution.d.ts.map +1 -0
- package/src/shade/renderer/geometry/virtual/build/level/VGeoContribution.js +24 -0
- package/src/shade/renderer/geometry/virtual/build/level/VGeoFrontier.d.ts +91 -0
- package/src/shade/renderer/geometry/virtual/build/level/VGeoFrontier.d.ts.map +1 -0
- package/src/shade/renderer/geometry/virtual/build/level/VGeoFrontier.js +91 -0
- package/src/shade/renderer/geometry/virtual/build/level/VGeoGroupRepack.d.ts +24 -0
- package/src/shade/renderer/geometry/virtual/build/level/VGeoGroupRepack.d.ts.map +1 -0
- package/src/shade/renderer/geometry/virtual/build/level/VGeoGroupRepack.js +25 -0
- package/src/shade/renderer/geometry/virtual/build/level/VGeoGroupStep.d.ts +77 -0
- package/src/shade/renderer/geometry/virtual/build/level/VGeoGroupStep.d.ts.map +1 -0
- package/src/shade/renderer/geometry/virtual/build/level/VGeoGroupStep.js +84 -0
- package/src/shade/renderer/geometry/virtual/build/level/VGeoLevelOptions.d.ts +19 -6
- package/src/shade/renderer/geometry/virtual/build/level/VGeoLevelOptions.d.ts.map +1 -1
- package/src/shade/renderer/geometry/virtual/build/level/VGeoLevelOptions.js +20 -7
- package/src/shade/renderer/geometry/virtual/build/level/vgeo_build_cluster.d.ts +19 -0
- package/src/shade/renderer/geometry/virtual/build/level/vgeo_build_cluster.d.ts.map +1 -0
- package/src/shade/renderer/geometry/virtual/build/level/vgeo_build_cluster.js +58 -0
- package/src/shade/renderer/geometry/virtual/build/level/vgeo_build_cluster_graph.d.ts +18 -0
- package/src/shade/renderer/geometry/virtual/build/level/vgeo_build_cluster_graph.d.ts.map +1 -0
- package/src/shade/renderer/geometry/virtual/build/level/vgeo_build_cluster_graph.js +116 -0
- package/src/shade/renderer/geometry/virtual/build/level/vgeo_build_group_step.d.ts +18 -0
- package/src/shade/renderer/geometry/virtual/build/level/vgeo_build_group_step.d.ts.map +1 -0
- package/src/shade/renderer/geometry/virtual/build/level/vgeo_build_group_step.js +545 -0
- package/src/shade/renderer/geometry/virtual/build/level/vgeo_build_leaf_frontier.d.ts +16 -0
- package/src/shade/renderer/geometry/virtual/build/level/vgeo_build_leaf_frontier.d.ts.map +1 -0
- package/src/shade/renderer/geometry/virtual/build/level/vgeo_build_leaf_frontier.js +110 -0
- package/src/shade/renderer/geometry/virtual/build/level/vgeo_build_levels.d.ts +2 -27
- package/src/shade/renderer/geometry/virtual/build/level/vgeo_build_levels.d.ts.map +1 -1
- package/src/shade/renderer/geometry/virtual/build/level/vgeo_build_levels.js +120 -1564
- package/src/shade/renderer/geometry/virtual/build/level/vgeo_compute_group_boundary.d.ts +26 -0
- package/src/shade/renderer/geometry/virtual/build/level/vgeo_compute_group_boundary.d.ts.map +1 -0
- package/src/shade/renderer/geometry/virtual/build/level/vgeo_compute_group_boundary.js +123 -0
- package/src/shade/renderer/geometry/virtual/build/level/vgeo_error_bands.d.ts +26 -0
- package/src/shade/renderer/geometry/virtual/build/level/vgeo_error_bands.d.ts.map +1 -0
- package/src/shade/renderer/geometry/virtual/build/level/vgeo_error_bands.js +78 -0
- package/src/shade/renderer/geometry/virtual/build/level/vgeo_partition_into_groups.d.ts +24 -0
- package/src/shade/renderer/geometry/virtual/build/level/vgeo_partition_into_groups.d.ts.map +1 -0
- package/src/shade/renderer/geometry/virtual/build/level/vgeo_partition_into_groups.js +337 -0
- package/src/shade/renderer/geometry/virtual/build/level/vgeo_run_round.d.ts +29 -0
- package/src/shade/renderer/geometry/virtual/build/level/vgeo_run_round.d.ts.map +1 -0
- package/src/shade/renderer/geometry/virtual/build/level/vgeo_run_round.js +147 -0
- package/src/shade/renderer/geometry/virtual/build/level/vgeo_stitch_frontier.d.ts +37 -0
- package/src/shade/renderer/geometry/virtual/build/level/vgeo_stitch_frontier.d.ts.map +1 -0
- package/src/shade/renderer/geometry/virtual/build/level/vgeo_stitch_frontier.js +243 -0
- package/src/shade/renderer/geometry/virtual/build/level/vgeo_try_repack.d.ts +29 -0
- package/src/shade/renderer/geometry/virtual/build/level/vgeo_try_repack.d.ts.map +1 -0
- package/src/shade/renderer/geometry/virtual/build/level/vgeo_try_repack.js +117 -0
- package/src/shade/renderer/geometry/virtual/build/mesh/VGEO_CREASE_ANGLE.d.ts +46 -0
- package/src/shade/renderer/geometry/virtual/build/mesh/VGEO_CREASE_ANGLE.d.ts.map +1 -0
- package/src/shade/renderer/geometry/virtual/build/mesh/VGEO_DEFAULT_ATTRIBUTE_WEIGHT_RATIOS.d.ts +74 -0
- package/src/shade/renderer/geometry/virtual/build/mesh/VGEO_DEFAULT_ATTRIBUTE_WEIGHT_RATIOS.d.ts.map +1 -0
- package/src/shade/renderer/geometry/virtual/build/mesh/VGEO_DEFAULT_ATTRIBUTE_WEIGHT_RATIOS.js +78 -0
- package/src/shade/renderer/geometry/virtual/build/mesh/VirtualGeometryMesh.d.ts +12 -7
- package/src/shade/renderer/geometry/virtual/build/mesh/VirtualGeometryMesh.d.ts.map +1 -1
- package/src/shade/renderer/geometry/virtual/build/mesh/VirtualGeometryMesh.js +33 -11
- package/src/shade/renderer/geometry/virtual/build/mesh/vgeo_attribute_vector_layout.d.ts +58 -0
- package/src/shade/renderer/geometry/virtual/build/mesh/vgeo_attribute_vector_layout.d.ts.map +1 -0
- package/src/shade/renderer/geometry/virtual/build/mesh/vgeo_attribute_vector_layout.js +79 -0
- package/src/shade/renderer/geometry/virtual/build/mesh/vgeo_attribute_vector_read.d.ts +39 -0
- package/src/shade/renderer/geometry/virtual/build/mesh/vgeo_attribute_vector_read.d.ts.map +1 -0
- package/src/shade/renderer/geometry/virtual/build/mesh/vgeo_attribute_vector_read.js +68 -0
- package/src/shade/renderer/geometry/virtual/build/mesh/vgeo_attribute_vector_write.d.ts +53 -0
- package/src/shade/renderer/geometry/virtual/build/mesh/vgeo_attribute_vector_write.d.ts.map +1 -0
- package/src/shade/renderer/geometry/virtual/build/mesh/vgeo_attribute_vector_write.js +243 -0
- package/src/shade/renderer/geometry/virtual/build/mesh/vgeo_compute_vertex_normals.d.ts +32 -7
- package/src/shade/renderer/geometry/virtual/build/mesh/vgeo_compute_vertex_normals.d.ts.map +1 -1
- package/src/shade/renderer/geometry/virtual/build/mesh/vgeo_compute_vertex_normals.js +243 -24
- package/src/shade/renderer/geometry/virtual/build/mesh/vgeo_compute_vertex_tangents.d.ts +12 -8
- package/src/shade/renderer/geometry/virtual/build/mesh/vgeo_compute_vertex_tangents.d.ts.map +1 -1
- package/src/shade/renderer/geometry/virtual/build/mesh/vgeo_compute_vertex_tangents.js +58 -50
- package/src/shade/renderer/geometry/virtual/build/mesh/vgeo_normalize_source.d.ts +5 -0
- package/src/shade/renderer/geometry/virtual/build/mesh/vgeo_normalize_source.d.ts.map +1 -1
- package/src/shade/renderer/geometry/virtual/build/mesh/vgeo_normalize_source.js +13 -1
- package/src/shade/renderer/geometry/virtual/build/mesh/vgeo_resolve_attribute_weights.d.ts +38 -0
- package/src/shade/renderer/geometry/virtual/build/mesh/vgeo_resolve_attribute_weights.d.ts.map +1 -0
- package/src/shade/renderer/geometry/virtual/build/mesh/vgeo_resolve_attribute_weights.js +81 -0
- package/src/shade/renderer/geometry/virtual/build/partition/VGeoFaceGraph.d.ts +23 -5
- package/src/shade/renderer/geometry/virtual/build/partition/VGeoFaceGraph.d.ts.map +1 -1
- package/src/shade/renderer/geometry/virtual/build/partition/VGeoFaceGraph.js +28 -21
- package/src/shade/renderer/geometry/virtual/build/partition/vgeo_split_face_set.js +1 -1
- package/src/shade/renderer/geometry/virtual/build/partition/vgeo_split_face_set_packed.d.ts.map +1 -1
- package/src/shade/renderer/geometry/virtual/build/partition/vgeo_split_face_set_packed.js +224 -60
- package/src/shade/renderer/geometry/virtual/build/submesh/VGeoGatheredFaces.d.ts +15 -0
- package/src/shade/renderer/geometry/virtual/build/submesh/VGeoGatheredFaces.d.ts.map +1 -1
- package/src/shade/renderer/geometry/virtual/build/submesh/VGeoGatheredFaces.js +17 -0
- package/src/shade/renderer/geometry/virtual/build/submesh/VGeoSubmesh.d.ts +17 -0
- package/src/shade/renderer/geometry/virtual/build/submesh/VGeoSubmesh.d.ts.map +1 -1
- package/src/shade/renderer/geometry/virtual/build/submesh/VGeoSubmesh.js +19 -0
- package/src/shade/renderer/geometry/virtual/build/submesh/vgeo_extract_submesh.d.ts +10 -1
- package/src/shade/renderer/geometry/virtual/build/submesh/vgeo_extract_submesh.d.ts.map +1 -1
- package/src/shade/renderer/geometry/virtual/build/submesh/vgeo_extract_submesh.js +103 -9
- package/src/shade/renderer/geometry/virtual/build/submesh/vgeo_gather_faces.d.ts +14 -2
- package/src/shade/renderer/geometry/virtual/build/submesh/vgeo_gather_faces.d.ts.map +1 -1
- package/src/shade/renderer/geometry/virtual/build/submesh/vgeo_gather_faces.js +38 -14
- package/src/shade/renderer/geometry/virtual/build/vgeo_build.d.ts +6 -2
- package/src/shade/renderer/geometry/virtual/build/vgeo_build.d.ts.map +1 -1
- package/src/shade/renderer/geometry/virtual/build/vgeo_build.js +27 -4
- package/src/shade/renderer/geometry/virtual/build/vgeo_subtree_bounds.d.ts +32 -0
- package/src/shade/renderer/geometry/virtual/build/vgeo_subtree_bounds.d.ts.map +1 -0
- package/src/shade/renderer/geometry/virtual/build/vgeo_subtree_bounds.js +93 -0
- package/src/shade/renderer/geometry/virtual/format/VGeoWriteOptions.d.ts +20 -6
- package/src/shade/renderer/geometry/virtual/format/VGeoWriteOptions.d.ts.map +1 -1
- package/src/shade/renderer/geometry/virtual/format/VGeoWriteOptions.js +22 -8
- package/src/shade/renderer/geometry/virtual/format/attribute/vgeo_layers_copy_corner.d.ts +16 -0
- package/src/shade/renderer/geometry/virtual/format/attribute/vgeo_layers_copy_corner.d.ts.map +1 -0
- package/src/shade/renderer/geometry/virtual/format/attribute/{vgeo_layers_copy_vertex.js → vgeo_layers_copy_corner.js} +8 -8
- package/src/shade/renderer/geometry/virtual/format/attribute/vgeo_layers_declare.d.ts +18 -7
- package/src/shade/renderer/geometry/virtual/format/attribute/vgeo_layers_declare.d.ts.map +1 -1
- package/src/shade/renderer/geometry/virtual/format/attribute/vgeo_layers_declare.js +19 -8
- package/src/shade/renderer/geometry/virtual/format/attribute/vgeo_layers_like.d.ts +3 -3
- package/src/shade/renderer/geometry/virtual/format/attribute/vgeo_layers_like.js +3 -3
- package/src/shade/renderer/geometry/virtual/format/attribute/vgeo_mesh_wedges.d.ts +27 -0
- package/src/shade/renderer/geometry/virtual/format/attribute/vgeo_mesh_wedges.d.ts.map +1 -0
- package/src/shade/renderer/geometry/virtual/format/attribute/vgeo_mesh_wedges.js +97 -0
- package/src/shade/renderer/geometry/virtual/format/cluster/VGEO_CLUSTER_OFFSET.d.ts +7 -3
- package/src/shade/renderer/geometry/virtual/format/cluster/VGEO_CLUSTER_OFFSET.d.ts.map +1 -1
- package/src/shade/renderer/geometry/virtual/format/cluster/VGEO_CLUSTER_OFFSET.js +21 -11
- package/src/shade/renderer/geometry/virtual/format/cluster/VGEO_CLUSTER_OFFSET_V4.d.ts +21 -0
- package/src/shade/renderer/geometry/virtual/format/cluster/VGEO_CLUSTER_OFFSET_V4.d.ts.map +1 -0
- package/src/shade/renderer/geometry/virtual/format/cluster/VGEO_CLUSTER_OFFSET_V4.js +41 -0
- package/src/shade/renderer/geometry/virtual/format/dag/VirtualGeometryCluster.d.ts +19 -1
- package/src/shade/renderer/geometry/virtual/format/dag/VirtualGeometryCluster.d.ts.map +1 -1
- package/src/shade/renderer/geometry/virtual/format/dag/VirtualGeometryCluster.js +20 -1
- package/src/shade/renderer/geometry/virtual/format/frame/VGEO_CODEC_DEFLATE.d.ts +25 -0
- package/src/shade/renderer/geometry/virtual/format/frame/VGEO_CODEC_DEFLATE.d.ts.map +1 -0
- package/src/shade/renderer/geometry/virtual/format/frame/VGEO_CODEC_DEFLATE.js +24 -0
- package/src/shade/renderer/geometry/virtual/format/frame/VGEO_CODEC_LZ4.d.ts +5 -0
- package/src/shade/renderer/geometry/virtual/format/frame/VGEO_CODEC_LZ4.d.ts.map +1 -1
- package/src/shade/renderer/geometry/virtual/format/frame/VGEO_CODEC_LZ4.js +5 -0
- package/src/shade/renderer/geometry/virtual/format/frame/vgeo_codec_name.d.ts.map +1 -1
- package/src/shade/renderer/geometry/virtual/format/frame/vgeo_codec_name.js +5 -0
- package/src/shade/renderer/geometry/virtual/format/frame/vgeo_decode_frame_blob.d.ts +10 -3
- package/src/shade/renderer/geometry/virtual/format/frame/vgeo_decode_frame_blob.d.ts.map +1 -1
- package/src/shade/renderer/geometry/virtual/format/frame/vgeo_decode_frame_blob.js +37 -3
- package/src/shade/renderer/geometry/virtual/format/frame/vgeo_encode_frame_blob.d.ts +21 -13
- package/src/shade/renderer/geometry/virtual/format/frame/vgeo_encode_frame_blob.d.ts.map +1 -1
- package/src/shade/renderer/geometry/virtual/format/frame/vgeo_encode_frame_blob.js +37 -13
- package/src/shade/renderer/geometry/virtual/format/frame/vgeo_frame_decode_bound.d.ts +8 -2
- package/src/shade/renderer/geometry/virtual/format/frame/vgeo_frame_decode_bound.d.ts.map +1 -1
- package/src/shade/renderer/geometry/virtual/format/frame/vgeo_frame_decode_bound.js +14 -2
- package/src/shade/renderer/geometry/virtual/format/header/VGEO_FORMAT_VERSION.d.ts +18 -0
- package/src/shade/renderer/geometry/virtual/format/header/VGEO_FORMAT_VERSION.d.ts.map +1 -1
- package/src/shade/renderer/geometry/virtual/format/header/VGEO_FORMAT_VERSION.js +19 -1
- package/src/shade/renderer/geometry/virtual/format/header/VGEO_HEADER_OFFSET.js +6 -0
- package/src/shade/renderer/geometry/virtual/format/header/VGEO_MAX_LEVEL_COUNT.d.ts +21 -0
- package/src/shade/renderer/geometry/virtual/format/header/VGEO_MAX_LEVEL_COUNT.d.ts.map +1 -0
- package/src/shade/renderer/geometry/virtual/format/header/VGEO_MAX_LEVEL_COUNT.js +20 -0
- package/src/shade/renderer/geometry/virtual/format/header/VGEO_MIN_READER_VERSION.d.ts +9 -0
- package/src/shade/renderer/geometry/virtual/format/header/VGEO_MIN_READER_VERSION.d.ts.map +1 -1
- package/src/shade/renderer/geometry/virtual/format/header/VGEO_MIN_READER_VERSION.js +10 -1
- package/src/shade/renderer/geometry/virtual/format/page/VGEO_PAGE_OFFSET.d.ts +1 -2
- package/src/shade/renderer/geometry/virtual/format/page/VGEO_PAGE_OFFSET.js +10 -3
- package/src/shade/renderer/geometry/virtual/format/page/VGEO_PAGE_OFFSET_V5.d.ts +20 -0
- package/src/shade/renderer/geometry/virtual/format/page/VGEO_PAGE_OFFSET_V5.d.ts.map +1 -0
- package/src/shade/renderer/geometry/virtual/format/page/VGEO_PAGE_OFFSET_V5.js +43 -0
- package/src/shade/renderer/geometry/virtual/format/payload/vgeo_encode_cluster_payload.d.ts +4 -2
- package/src/shade/renderer/geometry/virtual/format/payload/vgeo_encode_cluster_payload.d.ts.map +1 -1
- package/src/shade/renderer/geometry/virtual/format/payload/vgeo_encode_cluster_payload.js +8 -4
- package/src/shade/renderer/geometry/virtual/format/read/VGeoContainerReader.d.ts.map +1 -1
- package/src/shade/renderer/geometry/virtual/format/read/VGeoContainerReader.js +2 -2
- package/src/shade/renderer/geometry/virtual/format/read/VGeoDirectory.d.ts +6 -4
- package/src/shade/renderer/geometry/virtual/format/read/VGeoDirectory.d.ts.map +1 -1
- package/src/shade/renderer/geometry/virtual/format/read/VGeoDirectory.js +6 -4
- package/src/shade/renderer/geometry/virtual/format/read/VGeoPage.d.ts +13 -2
- package/src/shade/renderer/geometry/virtual/format/read/VGeoPage.d.ts.map +1 -1
- package/src/shade/renderer/geometry/virtual/format/read/VGeoPage.js +13 -2
- package/src/shade/renderer/geometry/virtual/format/read/VGeoPageFetcherCore.d.ts +5 -1
- package/src/shade/renderer/geometry/virtual/format/read/VGeoPageFetcherCore.d.ts.map +1 -1
- package/src/shade/renderer/geometry/virtual/format/read/VGeoPageFetcherCore.js +14 -1
- package/src/shade/renderer/geometry/virtual/format/read/vgeo_page_worker_serve.d.ts.map +1 -1
- package/src/shade/renderer/geometry/virtual/format/read/vgeo_page_worker_serve.js +1 -0
- package/src/shade/renderer/geometry/virtual/format/read/vgeo_read_directory.d.ts +4 -1
- package/src/shade/renderer/geometry/virtual/format/read/vgeo_read_directory.d.ts.map +1 -1
- package/src/shade/renderer/geometry/virtual/format/read/vgeo_read_directory.js +53 -11
- package/src/shade/renderer/geometry/virtual/format/read/vgeo_read_header.d.ts.map +1 -1
- package/src/shade/renderer/geometry/virtual/format/read/vgeo_read_header.js +7 -3
- package/src/shade/renderer/geometry/virtual/format/read/vgeo_read_page.d.ts +12 -2
- package/src/shade/renderer/geometry/virtual/format/read/vgeo_read_page.d.ts.map +1 -1
- package/src/shade/renderer/geometry/virtual/format/read/vgeo_read_page.js +111 -33
- package/src/shade/renderer/geometry/virtual/format/vgeo_validate_container.d.ts +6 -2
- package/src/shade/renderer/geometry/virtual/format/vgeo_validate_container.d.ts.map +1 -1
- package/src/shade/renderer/geometry/virtual/format/vgeo_validate_container.js +112 -42
- package/src/shade/renderer/geometry/virtual/format/vgeo_write_container.d.ts +2 -2
- package/src/shade/renderer/geometry/virtual/format/vgeo_write_container.d.ts.map +1 -1
- package/src/shade/renderer/geometry/virtual/format/vgeo_write_container.js +51 -21
- package/src/shade/renderer/geometry/virtual/runtime/CULL_PLAN_2026_09_16.md +385 -0
- package/src/shade/renderer/geometry/virtual/runtime/VGeoPageFetcher.d.ts.map +1 -1
- package/src/shade/renderer/geometry/virtual/runtime/VGeoPageFetcher.js +9 -0
- package/src/shade/renderer/geometry/virtual/runtime/VGeoResidency.d.ts.map +1 -1
- package/src/shade/renderer/geometry/virtual/runtime/VGeoResidency.js +14 -1
- package/src/shade/renderer/geometry/virtual/runtime/cut/chunk_vgeo_cut_access.d.ts.map +1 -1
- package/src/shade/renderer/geometry/virtual/runtime/cut/chunk_vgeo_cut_access.js +34 -0
- package/src/shade/renderer/geometry/virtual/runtime/cut/chunk_vgeo_cut_arena.d.ts.map +1 -1
- package/src/shade/renderer/geometry/virtual/runtime/cut/chunk_vgeo_cut_arena.js +18 -0
- package/src/shade/renderer/geometry/virtual/runtime/cut/shader_vgeo_cut_traverse.d.ts.map +1 -1
- package/src/shade/renderer/geometry/virtual/runtime/cut/shader_vgeo_cut_traverse.js +47 -19
- package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_CLUSTER_ROW_OFFSET.d.ts +1 -0
- package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_CLUSTER_ROW_OFFSET.js +22 -4
- package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_CLUSTER_ROW_WORDS.d.ts +7 -2
- package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_CLUSTER_ROW_WORDS.d.ts.map +1 -1
- package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_CLUSTER_ROW_WORDS.js +8 -3
- package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_CUT_STAT.d.ts +1 -0
- package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_CUT_STAT.js +10 -0
- package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_CUT_STAT_COUNT.js +1 -1
- package/src/shade/renderer/geometry/virtual/runtime/vgeo_runtime_page_slot_words.d.ts +13 -11
- package/src/shade/renderer/geometry/virtual/runtime/vgeo_runtime_page_slot_words.d.ts.map +1 -1
- package/src/shade/renderer/geometry/virtual/runtime/vgeo_runtime_page_slot_words.js +13 -11
- package/src/shade/renderer/geometry/virtual/runtime/vgeo_runtime_write_page_block.d.ts.map +1 -1
- package/src/shade/renderer/geometry/virtual/runtime/vgeo_runtime_write_page_block.js +4 -0
- package/src/shade/renderer/global_illumination/probe/octahedral/GPUProbeAtlas.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/probe/octahedral/GPUProbeAtlas.js +12 -3
- package/src/shade/renderer/global_illumination/sharc/shader/shader_sharc_evict.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/sharc/shader/shader_sharc_evict.js +3 -4
- package/src/shade/renderer/gpu_primitive/indirect/IndirectComputeCommandBuildPass.d.ts +6 -2
- package/src/shade/renderer/gpu_primitive/indirect/IndirectComputeCommandBuildPass.d.ts.map +1 -1
- package/src/shade/renderer/gpu_primitive/indirect/IndirectComputeCommandBuildPass.js +90 -12
- package/src/shade/renderer/gpu_primitive/indirect/WEBGPU_GUARANTEED_MAX_COMPUTE_WORKGROUPS_PER_DIMENSION.d.ts +22 -0
- package/src/shade/renderer/gpu_primitive/indirect/WEBGPU_GUARANTEED_MAX_COMPUTE_WORKGROUPS_PER_DIMENSION.d.ts.map +1 -0
- package/src/shade/renderer/gpu_primitive/indirect/WEBGPU_GUARANTEED_MAX_COMPUTE_WORKGROUPS_PER_DIMENSION.js +21 -0
- package/src/shade/renderer/light/environment/rgbe/RGBE_ReadPixels_RLE.d.ts.map +1 -1
- package/src/shade/renderer/light/environment/rgbe/RGBE_ReadPixels_RLE.js +7 -1
- package/src/shade/renderer/lightmap/GPULightMap.d.ts.map +1 -1
- package/src/shade/renderer/lightmap/GPULightMap.js +349 -336
- package/src/shade/renderer/loader/gltf/load_gltf.d.ts.map +1 -1
- package/src/shade/renderer/loader/gltf/load_gltf.js +1137 -1128
- package/src/shade/renderer/particles/DESIGN.md +14 -5
- package/src/shade/renderer/particles/GPUParticleSystem.d.ts +25 -10
- package/src/shade/renderer/particles/GPUParticleSystem.d.ts.map +1 -1
- package/src/shade/renderer/particles/GPUParticleSystem.js +182 -38
- package/src/shade/renderer/particles/graph/groups/simplex_reference.d.ts.map +1 -1
- package/src/shade/renderer/particles/graph/groups/simplex_reference.js +16 -10
- package/src/shade/renderer/particles/graph_particles.d.ts +4 -2
- package/src/shade/renderer/particles/graph_particles.d.ts.map +1 -1
- package/src/shade/renderer/particles/graph_particles.js +8 -2
- package/src/shade/renderer/particles/optimizer/particle_vm_semantics.d.ts.map +1 -1
- package/src/shade/renderer/particles/optimizer/particle_vm_semantics.js +8 -2
- package/src/shade/renderer/particles/optimizer/pass_fold_constants.d.ts.map +1 -1
- package/src/shade/renderer/particles/optimizer/pass_fold_constants.js +10 -4
- package/src/shade/renderer/particles/shaders/shader_particle_emit.d.ts.map +1 -1
- package/src/shade/renderer/particles/shaders/shader_particle_emit.js +13 -8
- package/src/shade/renderer/particles/shaders/shader_particle_init_free_list.d.ts +31 -0
- package/src/shade/renderer/particles/shaders/shader_particle_init_free_list.d.ts.map +1 -0
- package/src/shade/renderer/particles/shaders/shader_particle_init_free_list.js +62 -0
- package/src/shade/renderer/particles/shaders/shader_particle_simulate.d.ts.map +1 -1
- package/src/shade/renderer/particles/shaders/shader_particle_simulate.js +3 -6
- package/src/shade/renderer/particles/vm/ParticleVMReference.d.ts +13 -0
- package/src/shade/renderer/particles/vm/ParticleVMReference.d.ts.map +1 -1
- package/src/shade/renderer/particles/vm/ParticleVMReference.js +95 -17
- package/src/shade/renderer/rasterize/bucket/prepare_meshlet_draw_commands_by_material.d.ts.map +1 -1
- package/src/shade/renderer/rasterize/bucket/prepare_meshlet_draw_commands_by_material.js +4 -12
- package/src/shade/renderer/rasterize/bucket/rasterization_has_opaque_bucket.d.ts +21 -0
- package/src/shade/renderer/rasterize/bucket/rasterization_has_opaque_bucket.d.ts.map +1 -0
- package/src/shade/renderer/rasterize/bucket/rasterization_has_opaque_bucket.js +28 -0
- package/src/shade/renderer/rasterize/bucket/shader_read_out_bucket.d.ts +0 -2
- package/src/shade/renderer/rasterize/bucket/shader_read_out_bucket.d.ts.map +1 -1
- package/src/shade/renderer/rasterize/bucket/shader_read_out_bucket.js +4 -5
- package/src/shade/renderer/rasterize/cull/hzb/shader_hzb_mesh_filter_2way.d.ts.map +1 -1
- package/src/shade/renderer/rasterize/cull/hzb/shader_hzb_mesh_filter_2way.js +5 -3
- package/src/shade/renderer/rasterize/cull/hzb/shader_hzb_meshlet_filter_1way.d.ts.map +1 -1
- package/src/shade/renderer/rasterize/cull/hzb/shader_hzb_meshlet_filter_1way.js +11 -4
- package/src/shade/renderer/rasterize/cull/hzb/shader_hzb_meshlet_filter_1way_full.d.ts.map +1 -1
- package/src/shade/renderer/rasterize/cull/hzb/shader_hzb_meshlet_filter_1way_full.js +4 -3
- package/src/shade/renderer/rasterize/expand/bucket/meshlet/graph_sort_meshlets_by_bucket_id.d.ts.map +1 -1
- package/src/shade/renderer/rasterize/expand/bucket/meshlet/graph_sort_meshlets_by_bucket_id.js +3 -0
- package/src/shade/renderer/rasterize/expand/bucket/meshlet/shader_meshlets_count_by_rasterization_bucket.d.ts.map +1 -1
- package/src/shade/renderer/rasterize/expand/bucket/meshlet/shader_meshlets_count_by_rasterization_bucket.js +94 -90
- package/src/shade/renderer/rasterize/expand/bucket/meshlet/shader_meshlets_extract_bucket.d.ts.map +1 -1
- package/src/shade/renderer/rasterize/expand/bucket/meshlet/shader_meshlets_extract_bucket.js +13 -5
- package/src/shade/renderer/rasterize/expand/bucket/meshlet/shader_meshlets_rasterization_bucket_sort.d.ts.map +1 -1
- package/src/shade/renderer/rasterize/expand/bucket/meshlet/shader_meshlets_rasterization_bucket_sort.js +96 -89
- package/src/shade/renderer/rasterize/expand/graph_meshlets_filter_one_way.d.ts.map +1 -1
- package/src/shade/renderer/rasterize/expand/graph_meshlets_filter_one_way.js +3 -1
- package/src/shade/renderer/rasterize/expand/graph_meshlets_filter_two_way.d.ts.map +1 -1
- package/src/shade/renderer/rasterize/expand/graph_meshlets_filter_two_way.js +4 -1
- package/src/shade/renderer/rasterize/expand/mesh/shader_mesh_expand_to_meshlets_prefix.d.ts.map +1 -1
- package/src/shade/renderer/rasterize/expand/mesh/shader_mesh_expand_to_meshlets_prefix.js +100 -89
- package/src/shade/renderer/rasterize/expand/mesh/shader_prefix_sum_to_command.d.ts.map +1 -1
- package/src/shade/renderer/rasterize/expand/mesh/shader_prefix_sum_to_command.js +31 -7
- package/src/shade/renderer/rasterize/expand/pass0/pass_mesh_cull.d.ts.map +1 -1
- package/src/shade/renderer/rasterize/expand/pass0/pass_mesh_cull.js +1 -7
- package/src/shade/renderer/rasterize/expand/pass1/filter_meshlets.2-way.compute.d.ts.map +1 -1
- package/src/shade/renderer/rasterize/expand/pass1/filter_meshlets.2-way.compute.js +161 -153
- package/src/shade/renderer/rasterize/fast/graph_extract_meshes_from_bucket.d.ts.map +1 -1
- package/src/shade/renderer/rasterize/fast/graph_extract_meshes_from_bucket.js +2 -7
- package/src/shade/renderer/rasterize/fast/graph_rasterize_scene_fast.d.ts.map +1 -1
- package/src/shade/renderer/rasterize/fast/graph_rasterize_scene_fast.js +19 -2
- package/src/shade/renderer/rasterize/standard/graph_rasterize_partial_opaque.d.ts.map +1 -1
- package/src/shade/renderer/rasterize/standard/graph_rasterize_partial_opaque.js +4 -8
- package/src/shade/renderer/rasterize/standard/graph_rasterize_remaining_opaque.d.ts.map +1 -1
- package/src/shade/renderer/rasterize/standard/graph_rasterize_remaining_opaque.js +5 -8
- package/src/shade/renderer/rasterize/standard/graph_rasterize_scene.d.ts.map +1 -1
- package/src/shade/renderer/rasterize/standard/graph_rasterize_scene.js +19 -2
- package/src/shade/renderer/shader/type/WebGPUStruct.d.ts.map +1 -1
- package/src/shade/renderer/shader/type/WebGPUStruct.js +12 -0
- package/src/shade/renderer/shadow/map/DEFAULT_SHADOWMAP_UPDATE_BUDGET.d.ts +25 -0
- package/src/shade/renderer/shadow/map/DEFAULT_SHADOWMAP_UPDATE_BUDGET.d.ts.map +1 -0
- package/src/shade/renderer/shadow/map/DEFAULT_SHADOWMAP_UPDATE_BUDGET.js +24 -0
- package/src/shade/renderer/shadow/map/GPUSceneShadowmapContext.d.ts +10 -0
- package/src/shade/renderer/shadow/map/GPUSceneShadowmapContext.d.ts.map +1 -1
- package/src/shade/renderer/shadow/map/GPUSceneShadowmapContext.js +30 -21
- package/src/shade/renderer/texture/mipmaps/WebGPUMipmapGenerator.d.ts +8 -2
- package/src/shade/renderer/texture/mipmaps/WebGPUMipmapGenerator.d.ts.map +1 -1
- package/src/shade/renderer/texture/mipmaps/WebGPUMipmapGenerator.js +41 -6
- package/src/shade/wgsl/emulator/WGSLJavaScriptCompiler.js +2383 -2356
- package/src/view/tooltip/DomTooltipManager.d.ts +7 -0
- package/src/view/tooltip/DomTooltipManager.d.ts.map +1 -1
- package/src/view/tooltip/DomTooltipManager.js +22 -0
- package/src/view/tooltip/DomTooltipObserver.d.ts.map +1 -1
- package/src/view/tooltip/DomTooltipObserver.js +13 -3
- package/src/core/model/node-graph/visual/layout/LayoutBoxGraph.d.ts.map +0 -1
- package/src/core/model/node-graph/visual/layout/layout_assign_coordinates.d.ts.map +0 -1
- package/src/core/model/node-graph/visual/layout/layout_assign_layers.d.ts.map +0 -1
- package/src/core/model/node-graph/visual/layout/layout_break_cycles.d.ts.map +0 -1
- package/src/core/model/node-graph/visual/layout/layout_insert_lanes.d.ts.map +0 -1
- package/src/core/model/node-graph/visual/layout/layout_order_layers.d.ts.map +0 -1
- package/src/core/model/node-graph/visual/layout/layout_orient_links.d.ts.map +0 -1
- package/src/shade/playground/vgeo_viewer/cut_geometry.d.ts +0 -61
- package/src/shade/playground/vgeo_viewer/cut_geometry.d.ts.map +0 -1
- package/src/shade/playground/vgeo_viewer/main.d.ts.map +0 -1
- package/src/shade/playground/vgeo_viewer/sample_asset.d.ts +0 -18
- package/src/shade/playground/vgeo_viewer/sample_asset.d.ts.map +0 -1
- package/src/shade/playground/vgeo_viewer/select_cut.d.ts +0 -173
- package/src/shade/playground/vgeo_viewer/select_cut.d.ts.map +0 -1
- package/src/shade/renderer/geometry/virtual/build/VGeoFaceGraph.d.ts +0 -52
- package/src/shade/renderer/geometry/virtual/build/VGeoFaceGraph.d.ts.map +0 -1
- package/src/shade/renderer/geometry/virtual/build/VGeoGatheredFaces.d.ts +0 -24
- package/src/shade/renderer/geometry/virtual/build/VGeoGatheredFaces.d.ts.map +0 -1
- package/src/shade/renderer/geometry/virtual/build/VGeoLevel.d.ts +0 -32
- package/src/shade/renderer/geometry/virtual/build/VGeoLevel.d.ts.map +0 -1
- package/src/shade/renderer/geometry/virtual/build/VGeoLevelOptions.d.ts +0 -59
- package/src/shade/renderer/geometry/virtual/build/VGeoLevelOptions.d.ts.map +0 -1
- package/src/shade/renderer/geometry/virtual/build/VGeoLevelSummary.d.ts +0 -44
- package/src/shade/renderer/geometry/virtual/build/VGeoLevelSummary.d.ts.map +0 -1
- package/src/shade/renderer/geometry/virtual/build/VGeoSubmesh.d.ts +0 -20
- package/src/shade/renderer/geometry/virtual/build/VGeoSubmesh.d.ts.map +0 -1
- package/src/shade/renderer/geometry/virtual/build/VirtualGeometryMesh.d.ts +0 -73
- package/src/shade/renderer/geometry/virtual/build/VirtualGeometryMesh.d.ts.map +0 -1
- package/src/shade/renderer/geometry/virtual/build/vgeo_assemble_pages.d.ts +0 -13
- package/src/shade/renderer/geometry/virtual/build/vgeo_assemble_pages.d.ts.map +0 -1
- package/src/shade/renderer/geometry/virtual/build/vgeo_bounding_sphere.d.ts +0 -12
- package/src/shade/renderer/geometry/virtual/build/vgeo_bounding_sphere.d.ts.map +0 -1
- package/src/shade/renderer/geometry/virtual/build/vgeo_build_levels.d.ts +0 -36
- package/src/shade/renderer/geometry/virtual/build/vgeo_build_levels.d.ts.map +0 -1
- package/src/shade/renderer/geometry/virtual/build/vgeo_build_page_nodes.d.ts +0 -13
- package/src/shade/renderer/geometry/virtual/build/vgeo_build_page_nodes.d.ts.map +0 -1
- package/src/shade/renderer/geometry/virtual/build/vgeo_build_root_group.d.ts +0 -19
- package/src/shade/renderer/geometry/virtual/build/vgeo_build_root_group.d.ts.map +0 -1
- package/src/shade/renderer/geometry/virtual/build/vgeo_compute_vertex_normals.d.ts +0 -29
- package/src/shade/renderer/geometry/virtual/build/vgeo_compute_vertex_normals.d.ts.map +0 -1
- package/src/shade/renderer/geometry/virtual/build/vgeo_compute_vertex_tangents.d.ts +0 -31
- package/src/shade/renderer/geometry/virtual/build/vgeo_compute_vertex_tangents.d.ts.map +0 -1
- package/src/shade/renderer/geometry/virtual/build/vgeo_containing_sphere.d.ts +0 -18
- package/src/shade/renderer/geometry/virtual/build/vgeo_containing_sphere.d.ts.map +0 -1
- package/src/shade/renderer/geometry/virtual/build/vgeo_extract_submesh.d.ts +0 -14
- package/src/shade/renderer/geometry/virtual/build/vgeo_extract_submesh.d.ts.map +0 -1
- package/src/shade/renderer/geometry/virtual/build/vgeo_gather_faces.d.ts +0 -12
- package/src/shade/renderer/geometry/virtual/build/vgeo_gather_faces.d.ts.map +0 -1
- package/src/shade/renderer/geometry/virtual/build/vgeo_graph_components.d.ts +0 -14
- package/src/shade/renderer/geometry/virtual/build/vgeo_graph_components.d.ts.map +0 -1
- package/src/shade/renderer/geometry/virtual/build/vgeo_narrow_indices.d.ts +0 -11
- package/src/shade/renderer/geometry/virtual/build/vgeo_narrow_indices.d.ts.map +0 -1
- package/src/shade/renderer/geometry/virtual/build/vgeo_normalize_source.d.ts +0 -46
- package/src/shade/renderer/geometry/virtual/build/vgeo_normalize_source.d.ts.map +0 -1
- package/src/shade/renderer/geometry/virtual/build/vgeo_page_node_count.d.ts +0 -22
- package/src/shade/renderer/geometry/virtual/build/vgeo_page_node_count.d.ts.map +0 -1
- package/src/shade/renderer/geometry/virtual/build/vgeo_partition_graph.d.ts +0 -29
- package/src/shade/renderer/geometry/virtual/build/vgeo_partition_graph.d.ts.map +0 -1
- package/src/shade/renderer/geometry/virtual/build/vgeo_sphere_inflate_to_contain.d.ts +0 -9
- package/src/shade/renderer/geometry/virtual/build/vgeo_sphere_inflate_to_contain.d.ts.map +0 -1
- package/src/shade/renderer/geometry/virtual/build/vgeo_split_face_set.d.ts +0 -10
- package/src/shade/renderer/geometry/virtual/build/vgeo_split_face_set.d.ts.map +0 -1
- package/src/shade/renderer/geometry/virtual/build/vgeo_split_face_set_packed.d.ts +0 -15
- package/src/shade/renderer/geometry/virtual/build/vgeo_split_face_set_packed.d.ts.map +0 -1
- package/src/shade/renderer/geometry/virtual/format/attribute/vgeo_layers_copy_vertex.d.ts +0 -16
- package/src/shade/renderer/geometry/virtual/format/attribute/vgeo_layers_copy_vertex.d.ts.map +0 -1
- package/src/shade/renderer/loader/gltf/fix_up_material_sides.d.ts +0 -10
- package/src/shade/renderer/loader/gltf/fix_up_material_sides.d.ts.map +0 -1
- package/src/shade/renderer/rasterize/expand/graph_triangles_filter_by_material_side.d.ts +0 -17
- package/src/shade/renderer/rasterize/expand/graph_triangles_filter_by_material_side.d.ts.map +0 -1
- package/src/shade/renderer/rasterize/expand/shader_filter_triangle_by_material_side.d.ts +0 -3
- package/src/shade/renderer/rasterize/expand/shader_filter_triangle_by_material_side.d.ts.map +0 -1
- package/src/shade/renderer/rasterize/forward/chunk_material_side_should_draw.d.ts +0 -8
- package/src/shade/renderer/rasterize/forward/chunk_material_side_should_draw.d.ts.map +0 -1
- /package/src/core/{model/node-graph/visual/layout → graph/layout/layered}/layout_assign_coordinates.d.ts +0 -0
- /package/src/core/{model/node-graph/visual/layout → graph/layout/layered}/layout_assign_layers.d.ts +0 -0
- /package/src/core/{model/node-graph/visual/layout → graph/layout/layered}/layout_break_cycles.d.ts +0 -0
- /package/src/core/{model/node-graph/visual/layout → graph/layout/layered}/layout_break_cycles.js +0 -0
- /package/src/core/{model/node-graph/visual/layout → graph/layout/layered}/layout_insert_lanes.d.ts +0 -0
- /package/src/core/{model/node-graph/visual/layout → graph/layout/layered}/layout_insert_lanes.js +0 -0
- /package/src/core/{model/node-graph/visual/layout → graph/layout/layered}/layout_order_layers.d.ts +0 -0
- /package/src/core/{model/node-graph/visual/layout → graph/layout/layered}/layout_order_layers.js +0 -0
- /package/src/core/{model/node-graph/visual/layout → graph/layout/layered}/layout_orient_links.d.ts +0 -0
- /package/src/core/{model/node-graph/visual/layout → graph/layout/layered}/layout_orient_links.js +0 -0
- /package/src/shade/playground/{vgeo_viewer → caldera}/main.d.ts +0 -0
|
@@ -0,0 +1,385 @@
|
|
|
1
|
+
# Virtual Geometry cut — the per-cluster frustum test, measured and tightened
|
|
2
|
+
|
|
3
|
+
**2026-09-16.** Follows `RUNTIME_PLAN_2026_09_14.md` §2.1 and §7, which left `pages visited` at half
|
|
4
|
+
to three quarters of the resident tier when zoomed in and named the LOD sphere's looseness as the
|
|
5
|
+
cause. This document measures that claim before acting on it, and the measurement changes what is
|
|
6
|
+
worth building. Everything measured here was measured on the real asset in node
|
|
7
|
+
(`measure_spheres*.mjs`, `measure3_breakdown.mjs`, `measure4_extents.mjs`, `measure5_reach.mjs`,
|
|
8
|
+
`measure6_error_bound.mjs`, `measure7_containment.mjs`, `measure8_lod_vertices.mjs` of the
|
|
9
|
+
building session).
|
|
10
|
+
|
|
11
|
+
## 0. What the symptom is made of
|
|
12
|
+
|
|
13
|
+
The container is the Zorah rosette panel, mesh 2023 primitive 0, as rebuilt on 2026-09-14
|
|
14
|
+
(`5d4baf9e9ab4a0ea2bb6b3bcf48829f2.vgeo`, `format_version` 4, 942 MB): 17,213 pages, 590,858
|
|
15
|
+
clusters, 160,441 groups, 34.3 clusters a page. Its DAG is 42 levels deep counted as the longest
|
|
16
|
+
chain from a cluster down to a leaf, with 277,659 leaves. The tour of §7 saw, zoomed in at rest,
|
|
17
|
+
3,220 pages visited of 4,096 resident against 4,060 clusters drawn.
|
|
18
|
+
|
|
19
|
+
A CPU cut over the whole container — every page resident, camera on the panel's normal at the
|
|
20
|
+
tour's poses, 50° fov, 1258×646, τ = 1 — reproduces that: 3,091 pages visited at rest with the
|
|
21
|
+
cluster test on the LOD sphere, 4,537 with no frustum test at all. Where those pages are is the
|
|
22
|
+
finding. At rest, of the 3,091:
|
|
23
|
+
|
|
24
|
+
| | pages | of which drew a cluster | transit only |
|
|
25
|
+
|---|---:|---:|---:|
|
|
26
|
+
| levels 0–3 (the surface on screen and one step above) | 1,326 | 661 | 665 |
|
|
27
|
+
| levels 4–19 | 1,665 | 7 | 1,658 |
|
|
28
|
+
| levels 20–41 | 100 | 0 | 100 |
|
|
29
|
+
|
|
30
|
+
A page is placed at the lowest level of any cluster it holds; 8,166 pages hold more than one level.
|
|
31
|
+
Levels 4 and up hold 1,836 pages of the file. **1,765 of them are entered at rest with the LOD
|
|
32
|
+
sphere and 1,650 with the exact subtree box** (levels 4–9: 415/466, 319/333, 247/251, 165/167,
|
|
33
|
+
121/121, 80/80 visited with the sphere; 353, 293, 229, 160, 120, 78 with the box). Seven of them draw
|
|
34
|
+
anything. They are the way down.
|
|
35
|
+
|
|
36
|
+
## 1. Why the coarse pages cannot be culled, by any bound
|
|
37
|
+
|
|
38
|
+
The cluster test decides whether a cluster refines into its child group. Culling it has to be
|
|
39
|
+
conservative for **everything reachable below it**, because the child group is reached through it
|
|
40
|
+
and a parent culled with an on-screen descendant is a hole. What is reachable below a cluster is
|
|
41
|
+
not "the geometry this cluster approximates". Every simplification step consumes one group and
|
|
42
|
+
produces two or more parents; every parent's `child_group` is the **whole** consumed group, so a
|
|
43
|
+
parent's subtree carries its sibling's half of the surface too, and each child's subtree carries
|
|
44
|
+
*its* sibling's, and so on down. The region below a cluster doubles per level. Measured, as the
|
|
45
|
+
median diagonal of the exact subtree AABB against the object's diagonal, with the cluster's own AABB
|
|
46
|
+
beside it:
|
|
47
|
+
|
|
48
|
+
| level | clusters | own AABB diagonal | subtree AABB diagonal |
|
|
49
|
+
|---:|---:|---:|---:|
|
|
50
|
+
| 0 | 277,659 | 0.3% | 0.3% |
|
|
51
|
+
| 4 | 18,783 | 0.7% | 1.1% |
|
|
52
|
+
| 7 | 5,405 | 1.1% | 9.2% |
|
|
53
|
+
| 10 | 2,919 | 1.2% | 23% |
|
|
54
|
+
| 14 | 1,531 | 1.6% | 43% |
|
|
55
|
+
| 20 | 948 | 1.9% | 64% |
|
|
56
|
+
| 28 | 574 | 3.5% | 97% |
|
|
57
|
+
|
|
58
|
+
A zoomed view covers one to two percent of the panel. From level 7 up the median cluster's subtree
|
|
59
|
+
is bigger than the view, and from level 12 up it is a third of the object. No sphere and no box
|
|
60
|
+
around that region is outside any zoomed frustum, and the coarse pages get visited because they
|
|
61
|
+
hold clusters like that. The LOD sphere's looseness is real — below — but it is not what fills the
|
|
62
|
+
tier.
|
|
63
|
+
|
|
64
|
+
**The DAG's shape makes it worse than it need be.** Below level 4 each level halves the cluster
|
|
65
|
+
count; above it the ratio decays to 0.6, 0.8 and by level 10 about 0.9 a level, so 58,000 clusters
|
|
66
|
+
and 1,800 pages sit in a long thin tail above the surface anyone draws. That tail is the transit set.
|
|
67
|
+
Pages also mix levels — 8,166 of 17,213 span more than one — so a coarse page's groups are
|
|
68
|
+
spatially wherever the assembler found room.
|
|
69
|
+
|
|
70
|
+
## 2. What was measured, against the four questions asked
|
|
71
|
+
|
|
72
|
+
### 2.1 Where a subtree sphere could come from, and how tight it gets
|
|
73
|
+
|
|
74
|
+
Install-derived is out by construction, not by measurement: `self_sphere` **is** a subtree bound.
|
|
75
|
+
The builder's step sphere contains the consumed clusters' own step spheres and the produced
|
|
76
|
+
clusters' vertices, so by induction it contains every vertex under it; a sample of 1,160 clusters
|
|
77
|
+
across levels 0–28 found no subtree vertex outside its `self_sphere` (worst excess −3·10⁻⁹ of the
|
|
78
|
+
radius, a leaf touching its own miniball). Nothing else a page carries is tighter for the subtree:
|
|
79
|
+
node spheres and child-table metrics are unions of these same spheres.
|
|
80
|
+
|
|
81
|
+
So the question is how much tighter a builder-computed bound is. Volume of the candidate over the
|
|
82
|
+
volume of the LOD sphere, medians per level:
|
|
83
|
+
|
|
84
|
+
| level | exact subtree AABB, as a box | its circumsphere | miniball over children's subtree boxes | miniball over every subtree AABB corner | miniball over every subtree vertex |
|
|
85
|
+
|---:|---:|---:|---:|---:|---:|
|
|
86
|
+
| 0 | — | 1.39 | 1.39 | 1.47 | 1.00 |
|
|
87
|
+
| 2 | — | 0.82 | 0.79 | 0.70 | 0.49 |
|
|
88
|
+
| 4 | — | 0.51 | 0.49 | 0.52 | 0.30 |
|
|
89
|
+
| 8 | — | 0.31 | 0.30 | 0.28 | 0.22 |
|
|
90
|
+
| 12 | — | 0.22 | 0.22 | 0.15 | 0.17 |
|
|
91
|
+
| 16 | — | 0.18 | 0.18 | 0.15 | 0.14 |
|
|
92
|
+
| 20 | — | 0.12 | 0.12 | 0.10 | — |
|
|
93
|
+
|
|
94
|
+
The last two columns are medians over samples of 300 and 40 clusters a level drawn with different
|
|
95
|
+
seeds, which is why the vertex miniball can read larger than the corner miniball at one level; the
|
|
96
|
+
first three are exhaustive. The LOD sphere compounds: 1.5× the exact volume at level 1, 3–5× from
|
|
97
|
+
level 4, 7× at level 20. A tight sphere is 0.55–0.6 of its radius at the levels that matter. The composable
|
|
98
|
+
children's-boxes miniball is within 5–15% of the exhaustive reference at every level and is O(N)
|
|
99
|
+
to build; the exact vertex miniball is the tightest and costs O(N·depth) points through a miniball,
|
|
100
|
+
which on this container is ten billion points.
|
|
101
|
+
|
|
102
|
+
### 2.2 What the tighter bound buys the cut
|
|
103
|
+
|
|
104
|
+
Pages visited by the CPU cut, full residency, the tour's poses. `none` has the frustum test off
|
|
105
|
+
entirely; `lod` is today's kernel; the exact AABB is tested as a box (p-vertex against each plane):
|
|
106
|
+
|
|
107
|
+
| pose | none | LOD sphere | subtree-box circumsphere | children's-boxes miniball | exact subtree AABB |
|
|
108
|
+
|---|---:|---:|---:|---:|---:|
|
|
109
|
+
| rest (0.12 r) | 4,537 | 3,091 | 2,924 | 2,916 | **2,521** |
|
|
110
|
+
| stop 0 | 4,583 | 3,051 | 2,856 | 2,847 | 2,478 |
|
|
111
|
+
| stop 3 | 4,204 | 2,495 | 2,185 | 2,179 | **1,639** |
|
|
112
|
+
| stop 4 | 4,261 | 2,599 | 2,190 | 2,183 | **1,649** |
|
|
113
|
+
| stop 5 | 3,609 | 1,748 | 1,312 | 1,306 | **1,052** |
|
|
114
|
+
| stop 7 | 4,000 | 2,245 | 1,890 | 1,887 | 1,452 |
|
|
115
|
+
| framing (2.8 r) | 1,441 | 1,441 | 1,441 | 1,441 | 1,441 |
|
|
116
|
+
|
|
117
|
+
A tight **sphere** takes 5–6% off at rest and up to 25% at a stop. The exact **box** takes 18% off at
|
|
118
|
+
rest and 35–40% at stops 3, 4 and 5, and draws fewer clusters too (2,115 against 2,734 at rest: those
|
|
119
|
+
were on-screen by the sphere and off-screen in fact). The CPU cut's camera is not the tour's — its
|
|
120
|
+
orientation is the panel's normal and the tour's is the orbit controller's, and it drew 2,734 where the
|
|
121
|
+
tour drew 4,060 — so the tables compare candidates against each other, and §5's tour is what compares
|
|
122
|
+
before with after. The box wins because a subtree here is a flat
|
|
123
|
+
patch of a flat panel — its AABB is thin along the normal and its circumsphere is not.
|
|
124
|
+
|
|
125
|
+
### 2.3 The one test that would have hit the target, and why it is not sound
|
|
126
|
+
|
|
127
|
+
A cluster's **own** bounds inflated by the error accumulated down its chain — `reach(P) =
|
|
128
|
+
P.self_error + max over the child group of reach(c)`, leaves 0 — is the Nanite-shaped argument: an
|
|
129
|
+
on-screen point of the fine surface is within the step's error of some parent's surface, so some
|
|
130
|
+
chain of parents each passing that test exists. It visits 1,444 pages at rest and 358–1,300 at the
|
|
131
|
+
stops, the two-to-fourfold cut the task hoped for. And it leaves **14 to 37 in-frustum clusters of
|
|
132
|
+
the open cut undrawn at every pose**, some with their box six diagonals inside the frustum — holes
|
|
133
|
+
in the middle of the screen, not slivers at its edge. Scaling the reach by 6 still leaves 10–20.
|
|
134
|
+
|
|
135
|
+
The reason is measurable and is a finding on its own: **the stored error is not a distance bound.**
|
|
136
|
+
Per step, the farthest any consumed vertex lies from the produced parents' triangles, over the step's
|
|
137
|
+
`self_error`:
|
|
138
|
+
|
|
139
|
+
| group level | steps sampled | ratio median | p90 | max | steps over 1 |
|
|
140
|
+
|---:|---:|---:|---:|---:|---:|
|
|
141
|
+
| 0 | 60 | 1.30 | 2.50 | 4.9 | 97% |
|
|
142
|
+
| 3 | 60 | 1.29 | 2.07 | 5.6 | 75% |
|
|
143
|
+
| 5 | 60 | 1.08 | 2.79 | 1,696 | 55% |
|
|
144
|
+
| 10 | 60 | 0.77 | 2.39 | 10.5 | 33% |
|
|
145
|
+
| 20 | 60 | 0.51 | 4.20 | 35.0 | 27% |
|
|
146
|
+
| 32 | 46 | 5.60 | 16.8 | 33.0 | 85% |
|
|
147
|
+
|
|
148
|
+
`self_error` is the quadric's conformance to the source, normalised by its weight (`vgeo_build_levels`
|
|
149
|
+
§"Error is conformance to the source") — a plane-distance statistic, which is the right thing for a
|
|
150
|
+
screen-space LOD threshold and the wrong thing to build a cull on. A cull that is right for most
|
|
151
|
+
steps is a hole for the rest. Rejected; the number is recorded so nobody measures it again.
|
|
152
|
+
|
|
153
|
+
### 2.4 Row cost and slot fit
|
|
154
|
+
|
|
155
|
+
The exact subtree AABB is six words a cluster row: 13 → 19. `SELF_SPHERE` stays — the projection
|
|
156
|
+
reads it — and the existing sphere test stays in front of the box test (§3.4). On this container the
|
|
157
|
+
widest page is 52 clusters, 5 nodes, 15 groups, 25 parent entries: 851 words today, 1,163 at 19 words,
|
|
158
|
+
56.8% of the 2,048-word slot a 64 KB page gets. `slot_words_for` and the install refusal are
|
|
159
|
+
unchanged in form. At the million resident clusters design §4 targets the arena is 76 MB rather than
|
|
160
|
+
52.
|
|
161
|
+
|
|
162
|
+
## 3. What is built
|
|
163
|
+
|
|
164
|
+
### 3.1 Format — `subtree_aabb` in the cluster record, as `format_version` 5
|
|
165
|
+
|
|
166
|
+
The record stays 112 bytes. `bounds_sphere` goes: nothing at runtime read it (the row's doc said
|
|
167
|
+
so), the AABB already serves the meshlet metadata and every downstream cull, and its 16 bytes plus
|
|
168
|
+
`cone_reserved`'s 4 and the 6 that shift down make room for a 24-byte box in one place. Everything
|
|
169
|
+
from offset 40 moves, so `min_reader_version` moves to 5 with it — a version-4 reader would read a
|
|
170
|
+
version-5 record's `child_ref` out of its box.
|
|
171
|
+
|
|
172
|
+
| offset | type | field | |
|
|
173
|
+
|---:|---|---|---|
|
|
174
|
+
| 0 | [f32; 4] | self_sphere | unchanged |
|
|
175
|
+
| 16 | f32 | self_error | unchanged |
|
|
176
|
+
| 20 | f32 | parent_error | unchanged |
|
|
177
|
+
| 24 | [f32; 4] | parent_sphere | unchanged |
|
|
178
|
+
| 40 | [f32; 6] | **subtree_aabb** | object-space AABB of this cluster's vertices and of every cluster reachable below it through child groups; leaves: equals `aabb` |
|
|
179
|
+
| 64 | [f32; 6] | aabb | was 56 |
|
|
180
|
+
| 88 | u16 | child_ref | was 80 |
|
|
181
|
+
| 90 | u16 | child_group | was 82 |
|
|
182
|
+
| 92 | u32 | encoding_flags | was 88; `cone_reserved` (was 84) is gone |
|
|
183
|
+
| 96 | u32 | payload_offset | was 92 |
|
|
184
|
+
| 100 | u32 | payload_size | was 96 |
|
|
185
|
+
| 104 | u8 | vertex_count | was 100 |
|
|
186
|
+
| 105 | u8 | triangle_count | was 101 |
|
|
187
|
+
| 106 | [u8; 6] | reserved | was ten bytes at 102; the validator's zero check follows |
|
|
188
|
+
|
|
189
|
+
The writer and the validator read and write the record **positionally** (`vgeo_write_container` after
|
|
190
|
+
`SELF_SPHERE`, `read_clusters` in the validator), so both are re-sequenced, not just the offset table.
|
|
191
|
+
`VirtualGeometryCluster.bounds_sphere` stays as a **builder-only** field — the object sphere, the
|
|
192
|
+
group centroids and the leaf `self_sphere` are built from it — and its doc says it is no longer
|
|
193
|
+
written. `VIRTUAL_GEOMETRY_DESIGN.md` and `VIRTUAL_GEOMETRY_PLAN.md` mention `cone_reserved` as a
|
|
194
|
+
zeroed column and are corrected.
|
|
195
|
+
|
|
196
|
+
**Build invariant §11.17.** `subtree_aabb` contains the cluster's `aabb` and, for every cluster of its
|
|
197
|
+
child group, that cluster's `subtree_aabb`. Exact on stored values, no tolerance: the builder computes
|
|
198
|
+
the union of float32 extremes, which is exactly representable. By induction it contains every vertex
|
|
199
|
+
below the cluster, which is the whole of what the cull needs, and it needs no sphere nesting — the
|
|
200
|
+
containment that made §7's LOD pair compound is not asked of it.
|
|
201
|
+
|
|
202
|
+
**§11.7 gains what dropping `bounds_sphere` would have lost.** The validator checked
|
|
203
|
+
`bounds_sphere ∋ vertices` and never `self_sphere ∋ vertices`; the latter is what the sphere test and
|
|
204
|
+
the version-4 cube in §3.4 rest on, and it was only ever true by construction (`vgeo_build_levels`
|
|
205
|
+
sets a leaf's `self_sphere` to its miniball and inflates every step sphere to contain the produced
|
|
206
|
+
vertices). It is now stated in §11.7 and checked per cluster against the payload.
|
|
207
|
+
|
|
208
|
+
**Builder.** A memoised walk over `child_group` after `vgeo_build_levels`: a leaf's box is its `aabb`;
|
|
209
|
+
a parent's is its `aabb` unioned with each child-group member's `subtree_aabb`. Not a pass by level:
|
|
210
|
+
a round leaves unmerged clusters in the frontier, so a group formed at round L holds members created
|
|
211
|
+
at any lower level, and `group.level` says where the group was formed, not where its members were.
|
|
212
|
+
The walk is O(N) either way.
|
|
213
|
+
|
|
214
|
+
**Reader.** `VGeoPage.subtree_aabb` (`6 · cluster_count`) replaces `bounds_sphere`. The page decoder
|
|
215
|
+
is handed the container's `format_version` — through `VGeoPageFetcherCore`, whose three construction
|
|
216
|
+
sites (reader, in-process fetcher, worker) all have the header — and reads a version-4 record by the
|
|
217
|
+
old offsets, synthesising `subtree_aabb` as the cube around `self_sphere`: a conservative subtree
|
|
218
|
+
bound, so a container nobody has rebuilt still culls correctly. §3.4 says why it also culls no worse.
|
|
219
|
+
The validator accepts only the current version, as it always has.
|
|
220
|
+
|
|
221
|
+
### 3.2 Runtime — `CULL_BOX` in the row, tested after the sphere and after the election
|
|
222
|
+
|
|
223
|
+
`VGEO_CLUSTER_ROW_OFFSET.CULL_BOX = 13`, six words, `VGEO_CLUSTER_ROW_WORDS = 19`;
|
|
224
|
+
`vgeo_runtime_write_page_block` copies `page.subtree_aabb`. `vg_visit_cluster` keeps its
|
|
225
|
+
`SELF_SPHERE` test and adds `vg_box_outside_frustum` on the row's box: a p-vertex per plane, five
|
|
226
|
+
planes, the same `VGEO_CUT_FLAG_CULL` bit. Clusters the sphere rejects count in `CULLED_CLUSTER` as
|
|
227
|
+
before; clusters the sphere passed and the box rejected count in a new `CULLED_CLUSTER_BOX`, so a
|
|
228
|
+
version-4 container reading zero there is §3.4's promise made visible. Two conservative bounds on the
|
|
229
|
+
same subtree; a cluster outside either is outside.
|
|
230
|
+
|
|
231
|
+
**The frustum tests move below the walk-up election.** Today the cull runs before the
|
|
232
|
+
`parent_projected <= tau` branch, so with the coarsen flag on a frontier cluster the frustum rejects
|
|
233
|
+
never elects the walk to its parents — and the parent's own `aabb` can protrude on screen beyond the
|
|
234
|
+
children's union, which is exactly why §3.1 adds it. A tighter bound fires that more often. A cluster
|
|
235
|
+
below the cut refines into nothing and claims nothing, so culling it buys residency nothing; the
|
|
236
|
+
election is evaluated first, unconditionally, and the frustum tests gate only what follows: drawing,
|
|
237
|
+
clamping and refining. The production caller never sets coarsen today; the spec does.
|
|
238
|
+
|
|
239
|
+
### 3.3 The CPU reference cut
|
|
240
|
+
|
|
241
|
+
`vgeo_select_cut` culls on `page.subtree_aabb` with the same box test, so the fixture and the kernel
|
|
242
|
+
answer the same question, and its spec's claims ("never a hole while a page is missing", "a fully
|
|
243
|
+
resident cut is a whole-file reader's cut") run against the new bound.
|
|
244
|
+
|
|
245
|
+
### 3.4 Why the sphere test stays
|
|
246
|
+
|
|
247
|
+
For a version-5 page the box is inside the sphere's cube and usually inside the sphere; the sphere
|
|
248
|
+
test culls almost nothing the box would not. For a version-4 page the synthesised box **is** the
|
|
249
|
+
sphere's cube, and a cube culls less than its inscribed sphere: the CPU cut visits 6–10% more pages
|
|
250
|
+
on the cube alone (3,292 against 3,091 at rest). With both tests a version-4 container culls exactly
|
|
251
|
+
what it culls today and a version-5 container culls what the box allows. No version reaches the
|
|
252
|
+
kernel.
|
|
253
|
+
|
|
254
|
+
## 4. The proof, and where it lives
|
|
255
|
+
|
|
256
|
+
**Claim.** With culling on, the cut draws every cluster the open cut draws that has a vertex inside
|
|
257
|
+
the frustum, and no cluster the open cut does not draw — descending from the root, and walking up
|
|
258
|
+
from a kept frontier with the coarsen flag on. Parents of one group may decide differently —
|
|
259
|
+
a group is claimed and drawn once by whichever parent reaches it first — so no group-uniformity is
|
|
260
|
+
needed and none is argued; §2.1 of the 2026-09-14 plan leaned on it and did not need to.
|
|
261
|
+
|
|
262
|
+
**Argument.** A culled cluster's `CULL_BOX` (or `SELF_SPHERE`) is outside a frustum plane. Both
|
|
263
|
+
contain every vertex of every cluster reachable below it (§3.1's invariant for the box; §7's
|
|
264
|
+
construction for the sphere), so every such cluster is outside the same plane, and so is every
|
|
265
|
+
triangle they carry. Nothing on screen was under it. The LOD half of the rule is untouched, so
|
|
266
|
+
RUNTIME_PLAN §4.4's second proof — every cluster the flat rule draws is reached — holds for every
|
|
267
|
+
on-screen cluster: each ancestor along its chain contains it and so passes both tests.
|
|
268
|
+
|
|
269
|
+
**Where it is checked.** `vgeo_cut_agreement.spec.js`, `frustum culling removes only what is outside
|
|
270
|
+
the frustum`, rewritten to hold the kernel against the **reader's pages** and not against any bound
|
|
271
|
+
the row carries. For each cluster the open cut drew and the culled cut did not, it walks the child
|
|
272
|
+
groups through the reader and asserts every **vertex** of every cluster it reaches — decoded from the
|
|
273
|
+
payload, the same witness `vgeo_read_page.spec` uses for the `aabb` — is outside the frustum. Not the
|
|
274
|
+
descendants' boxes: a sphere that contains every vertex need not contain a box corner, so a
|
|
275
|
+
sphere-culled cluster with a straddling box would fail a box oracle on a correct kernel. For every
|
|
276
|
+
touched page but the root it asserts some cluster refining into it passes the kernel's own predicate
|
|
277
|
+
on bounds the spec computes itself — `self_sphere` not rejected and the union box of its subtree
|
|
278
|
+
not rejected — because a union box the frustum cuts through the gap between two members passes the
|
|
279
|
+
kernel's test with no member inside, and a p-vertex test admits a box just past an edge, so no
|
|
280
|
+
assertion about member boxes is implied by the design. The same test runs with the coarsen flag on
|
|
281
|
+
over a frontier seeded below the cut, against the open coarsen cut. That the **stored**
|
|
282
|
+
`subtree_aabb` equals the union the spec computes is `vgeo_read_page.spec.js`'s to check, and it does,
|
|
283
|
+
exactly. A child group whose page the reader does not hold is a leaf to the walk: nothing below a
|
|
284
|
+
missing page can be drawn, and the parent's own vertices are already in the check.
|
|
285
|
+
|
|
286
|
+
## 5. What it reads after — measured 2026-09-16
|
|
287
|
+
|
|
288
|
+
The rosette panel rebuilt at version 5 (`5a01cc81…`, 17,213 pages, 590,858 clusters and 160,441
|
|
289
|
+
groups — identical to the version-4 build, and 940,215,784 bytes against 941,905,000), validated
|
|
290
|
+
clean including §11.17 and the new §11.7 check. The tour of RUNTIME_PLAN §7, same driver, same eight
|
|
291
|
+
stops twice round, 4,096 slots, 1258×646, then the rosette at rest. Both containers were driven
|
|
292
|
+
through **this** runtime, so the version-4 column is the §3.4 promise rather than an old reading.
|
|
293
|
+
|
|
294
|
+
| | version 4 (cube from the LOD sphere) | version 5 (subtree box) |
|
|
295
|
+
|---|---:|---:|
|
|
296
|
+
| pages visited, rosette at rest | 3,231 | **2,854** |
|
|
297
|
+
| pages visited, stops 3, 4, 5, 7 | 2,908 / 2,502 / 2,005 / 2,322 | **2,169 / 1,763 / 1,341 / 1,633** |
|
|
298
|
+
| pages visited, framing distance | 1,445 | 1,445 |
|
|
299
|
+
| pages visited, summed over the tour | 48,563 | **39,075** |
|
|
300
|
+
| clusters drawn at rest | 4,055 | 3,471 |
|
|
301
|
+
| clusters the box culled and the sphere did not, at rest | 0 | 5,520 |
|
|
302
|
+
| `clamped`, every stop | 0 | 0 |
|
|
303
|
+
| pages evicted over the run | 3,040 | **1,908** |
|
|
304
|
+
| installs refused over the run | 1,640 | **483** |
|
|
305
|
+
| pages fetched | 4,895 | 4,653 |
|
|
306
|
+
|
|
307
|
+
Against the same stop the box takes 12% off at rest, 14–18% at the three stops facing the panel
|
|
308
|
+
squarely, and 25–33% at the four oblique ones — where §2.2's node measurement said 35–40%, and the
|
|
309
|
+
difference is the sphere test still running in front of it. At the framing distance, where nothing
|
|
310
|
+
is off screen, it costs and saves nothing and the box culls zero. `culled (box)` is zero at every
|
|
311
|
+
stop of the version-4 run, which is §3.4 measured rather than argued.
|
|
312
|
+
|
|
313
|
+
**Drawn falls with visited**, 4,055 to 3,471 at rest, and that is the other half of the same fact:
|
|
314
|
+
those clusters passed a sphere that reaches well outside the geometry it stands for, and they were
|
|
315
|
+
off screen. The rest-pose screenshot is the same picture — same ornament, same shading, same depth
|
|
316
|
+
of detail; only the panel's own counters differ.
|
|
317
|
+
|
|
318
|
+
**What it is worth is residency, not the cut's own cost.** Evictions over the run fall by 37% and
|
|
319
|
+
refused installs by 71%, which is the LRU being handed a working set closer to what the view needs.
|
|
320
|
+
`clamped` stays zero throughout, so nothing is drawn coarse to pay for it.
|
|
321
|
+
|
|
322
|
+
## 6. What this does not do, and what would
|
|
323
|
+
|
|
324
|
+
- **It does not get visited pages to a few hundred, and nothing conservative on a DAG edge can.** §1
|
|
325
|
+
is the floor: ~1,550 transit pages at every zoomed pose. That floor is the traversal's, not the
|
|
326
|
+
bound's. A descent that reaches groups through a **spatial** hierarchy — a BVH whose leaves are
|
|
327
|
+
groups at every level placed by their own bounds, the LOD range of what is beneath a node deciding
|
|
328
|
+
whether to enter it, the flat rule of §4.4 evaluated at each group reached — needs no subtree
|
|
329
|
+
bound at all, because nothing is reached *through* a coarse cluster; and it enumerates each group
|
|
330
|
+
once, which retires the claim. That is Nanite's shape and a different document: it replaces the
|
|
331
|
+
child-table descent, the claim, the frontier and the coarsen path of CUT_PLAN_2026_09_14.
|
|
332
|
+
- **It does not fix the builder's tail.** Convergence decaying from 0.5 to 0.9 a level above level
|
|
333
|
+
4 is where the 1,700 transit pages come from, and the assembler mixing levels in a page is why a
|
|
334
|
+
zoomed view touches most of them. Both are the builder's, measured here and left open.
|
|
335
|
+
- **It does not make the error a bound.** §2.3's table is a property of the LOD metric, not of this
|
|
336
|
+
cull; whether the LOD switch should carry a geometric bound beside the quadric is its own question.
|
|
337
|
+
- **It does not touch the node test**, which culls inside an already-claimed page and does not move
|
|
338
|
+
residency.
|
|
339
|
+
|
|
340
|
+
## 7. Order, and what each step leaves green
|
|
341
|
+
|
|
342
|
+
Each change carries a spec that fails before it and passes after; no spies, no mocks.
|
|
343
|
+
|
|
344
|
+
1. **Format.** `VGEO_CLUSTER_OFFSET` v5 layout and a v4 table kept for the reader;
|
|
345
|
+
`VGEO_FORMAT_VERSION`/`VGEO_MIN_READER_VERSION` 5; writer re-sequenced and writing `subtree_aabb`;
|
|
346
|
+
builder computes it; reader reads it through `format_version` handed to `VGeoPageFetcherCore` at
|
|
347
|
+
its four construction sites (and synthesises the cube for v4); validator re-sequenced, checks §11.17
|
|
348
|
+
and `self_sphere ∋ vertices`, stops after a version defect. Pins: `vgeo_read_page.spec` — every
|
|
349
|
+
cluster's `subtree_aabb` is exactly the union of its `aabb` and its child group's boxes, and a
|
|
350
|
+
leaf's equals its `aabb`; `vgeo_validate_container.spec` — a shrunk `subtree_aabb` is caught, and so
|
|
351
|
+
is a `self_sphere` that leaves a vertex out; `VGeoContainerReader.spec` — a version-4 record layout
|
|
352
|
+
reads through the legacy offsets with the cube synthesised. `VGEO_FORMAT.md` §4, §7, §11 follow.
|
|
353
|
+
2. **Rebuild the container** with the new builder, in the background, while the runtime lands.
|
|
354
|
+
3. **Runtime.** Row layout, page block, kernel (box test, the new counter, the election ahead of the
|
|
355
|
+
culls), fixture cut. Pins: `VGeoRuntimeTables.spec` — the row carries the page's box;
|
|
356
|
+
`vgeo_cut_agreement.spec` — §4's rewritten test, descending and coarsening; the compile spec stays
|
|
357
|
+
at ten storage buffers.
|
|
358
|
+
4. **Tour** on the rebuilt container and on its version-4 form; §5's table filled in; screenshot
|
|
359
|
+
compared. Done 2026-09-16.
|
|
360
|
+
|
|
361
|
+
## 8. Review — folded in
|
|
362
|
+
|
|
363
|
+
One adversarial pass over the draft against the code, fifteen findings, the ones that changed the
|
|
364
|
+
document:
|
|
365
|
+
|
|
366
|
+
- **The spec's oracle was wrong for the sphere test (finding 1)** and its claim assertion was not
|
|
367
|
+
implied by the design (2). §4 now tests vertices and the kernel's own predicate on spec-computed
|
|
368
|
+
bounds.
|
|
369
|
+
- **"One level below" is false (3):** unmerged clusters ride the frontier upward. §3.1 memoises.
|
|
370
|
+
- **The coarsen path was unproven and the tighter bound widens its hole (4).** §3.2 moves the
|
|
371
|
+
frustum tests below the election and §4's claim now covers walking up.
|
|
372
|
+
- **`self_sphere ∋ vertices` was never a stated invariant (5)** and dropping `bounds_sphere` deleted
|
|
373
|
+
the only vertex-in-sphere check. §3.1 adds it to §11.7 and the validator.
|
|
374
|
+
- **`payload_offset`/`payload_size` move (6)** and both the writer and the validator are positional.
|
|
375
|
+
§3.1's table and step 1 say so.
|
|
376
|
+
- **Two tables disagreed (7):** §0's per-level split and §1's totals now use one classification, the
|
|
377
|
+
§2.1 caption names its samples, and §5 no longer transfers a CPU delta onto the GPU's count.
|
|
378
|
+
- **Four construction sites, not three (8)**, and the version rides the worker's first request with
|
|
379
|
+
the descriptor. The validator stops after a version defect (10) rather than misreading v4 records
|
|
380
|
+
positionally. `bounds_sphere` is scoped to the record (11). The slot-words doc is rewritten for 76
|
|
381
|
+
bytes a cluster (12). A separate counter tells box culls from sphere culls (15).
|
|
382
|
+
|
|
383
|
+
Confirmed by the pass and left as written: the object-space frustum makes the p-vertex test and the
|
|
384
|
+
version-4 cube conservative under instance scale (14); §2.4's arithmetic (12); `vgeo_read_header`'s
|
|
385
|
+
check admits both versions (9).
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"VGeoPageFetcher.d.ts","sourceRoot":"","sources":["../../../../../../../src/shade/renderer/geometry/virtual/runtime/VGeoPageFetcher.js"],"names":[],"mappings":"AAIA;;;GAGG;AAEH;;;;;;;;;;;;;;;;GAgBG;AACH;IA0EI;;;;;;OAMG;IACH;QAL4B,YAAY,GAA7B,MAAM;QACuB,WAAW,SAA5B,MAAM;OAS5B;IAED;;OAEG;IACH,2BAEC;IAED;;;OAGG;IACH,iCAEC;IAED;;;OAGG;IACH,qCAEC;IAED;;OAEG;IACH,4BAEC;IAED;;;OAGG;IACH,gCAEC;IAED;;;;;;;OAOG;IACH,cAPW,mBAAmB,cACnB,MAAM,gBACN,MAAM,cACN,MAAM,WACN,WAAW,GACT,QAAQ,QAAQ,CAAC,CAc7B;IAED;;;;;;OAMG;IACH,eAHW,mBAAmB,GACjB,MAAM,CAuBlB;IAED;;;;OAIG;IACH,WAFa,IAAI,CAiBhB;;
|
|
1
|
+
{"version":3,"file":"VGeoPageFetcher.d.ts","sourceRoot":"","sources":["../../../../../../../src/shade/renderer/geometry/virtual/runtime/VGeoPageFetcher.js"],"names":[],"mappings":"AAIA;;;GAGG;AAEH;;;;;;;;;;;;;;;;GAgBG;AACH;IA0EI;;;;;;OAMG;IACH;QAL4B,YAAY,GAA7B,MAAM;QACuB,WAAW,SAA5B,MAAM;OAS5B;IAED;;OAEG;IACH,2BAEC;IAED;;;OAGG;IACH,iCAEC;IAED;;;OAGG;IACH,qCAEC;IAED;;OAEG;IACH,4BAEC;IAED;;;OAGG;IACH,gCAEC;IAED;;;;;;;OAOG;IACH,cAPW,mBAAmB,cACnB,MAAM,gBACN,MAAM,cACN,MAAM,WACN,WAAW,GACT,QAAQ,QAAQ,CAAC,CAc7B;IAED;;;;;;OAMG;IACH,eAHW,mBAAmB,GACjB,MAAM,CAuBlB;IAED;;;;OAIG;IACH,WAFa,IAAI,CAiBhB;;CAiLJ;kCA5YY,OAAO,uCAAuC,EAAE,mBAAmB;uBACnE,OAAO,4BAA4B,EAAE,QAAQ"}
|
|
@@ -301,6 +301,14 @@ export class VGeoPageFetcher {
|
|
|
301
301
|
id,
|
|
302
302
|
source_id,
|
|
303
303
|
asset_id_low64: reader.header.asset_id_low64,
|
|
304
|
+
/*
|
|
305
|
+
The worker decodes cluster records and their layout is the container's (§7), so the
|
|
306
|
+
version travels with the identity. It rides every request rather than only the one
|
|
307
|
+
carrying the descriptor: the worker builds its core from whichever request arrives
|
|
308
|
+
first for a source, and a field that is only sometimes there is a field that is
|
|
309
|
+
sometimes undefined.
|
|
310
|
+
*/
|
|
311
|
+
format_version: reader.header.format_version,
|
|
304
312
|
verify_frames: options.verify_frames,
|
|
305
313
|
fetch_retries: options.fetch_retries,
|
|
306
314
|
fetch_retry_backoff_ms: options.fetch_retry_backoff_ms,
|
|
@@ -378,6 +386,7 @@ export class VGeoPageFetcher {
|
|
|
378
386
|
core = new VGeoPageFetcherCore({
|
|
379
387
|
read: (offset, length, abort) => source.read(offset, length, abort),
|
|
380
388
|
asset_id_low64: () => reader.header.asset_id_low64,
|
|
389
|
+
format_version: () => reader.header.format_version,
|
|
381
390
|
verify_frames: options.verify_frames,
|
|
382
391
|
fetch_retries: options.fetch_retries,
|
|
383
392
|
fetch_retry_backoff_ms: options.fetch_retry_backoff_ms,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"VGeoResidency.d.ts","sourceRoot":"","sources":["../../../../../../../src/shade/renderer/geometry/virtual/runtime/VGeoResidency.js"],"names":[],"mappings":"AA2GA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA0CG;AACH;IAiKI;;;;;;;OAOG;IACH;QAN2C,IAAI,EAApC,sBAAsB;QACS,OAAO,GAAtC,oBAAoB;QACM,IAAI,GAA9B,eAAe;QACW,OAAO,GAAjC,eAAe;OA8BzB;IAID;;OAEG;IACH,oCAEC;IAED;;OAEG;IACH,4BAEC;IAED;;OAEG;IACH,+BAEC;IAED;;OAEG;IACH,yEAEC;IAED;;;;OAIG;IACH,oBAEC;IAED;;;;OAIG;IACH,gCAGC;IAED,+BAEC;IAED,iCAEC;IAED,6BAEC;IAED,2BAEC;IAED,iCAEC;IAED,gCAEC;IAED;;;;OAIG;IACH,oCAEC;IAED;;;OAGG;IACH,kCAEC;IAED;;;OAGG;IACH,kCAEC;IAED;;;OAGG;IACH,iCAEC;IAED;;;OAGG;IACH,iCAEC;IAED;;;OAGG;IACH,gCAEC;IAED;;;;;OAKG;IACH,gCAEC;IAED;;;OAGG;IACH,iCAEC;IAED,gCAEC;IAED,+BAEC;IAED,8BAEC;IAED;;OAEG;IACH,qCAQC;IAID;;;;;;;;;;OAUG;IACH,iBAHW,mBAAmB,GACjB,MAAM,CA8ClB;IAED;;;;;;OAMG;IACH,mBAHW,mBAAmB,GACjB,OAAO,CAgBnB;IAED;;;OAGG;IACH,sBAHW,mBAAmB,GACjB,OAAO,CAInB;IAED;;;;;;OAMG;IACH,cAJW,mBAAmB,cACnB,MAAM,GACJ,QAAQ,GAAC,UAAU,GAAC,aAAa,GAAC,KAAK,GAAC,MAAM,GAAC,cAAc,CAqBzE;
|
|
1
|
+
{"version":3,"file":"VGeoResidency.d.ts","sourceRoot":"","sources":["../../../../../../../src/shade/renderer/geometry/virtual/runtime/VGeoResidency.js"],"names":[],"mappings":"AA2GA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA0CG;AACH;IAiKI;;;;;;;OAOG;IACH;QAN2C,IAAI,EAApC,sBAAsB;QACS,OAAO,GAAtC,oBAAoB;QACM,IAAI,GAA9B,eAAe;QACW,OAAO,GAAjC,eAAe;OA8BzB;IAID;;OAEG;IACH,oCAEC;IAED;;OAEG;IACH,4BAEC;IAED;;OAEG;IACH,+BAEC;IAED;;OAEG;IACH,yEAEC;IAED;;;;OAIG;IACH,oBAEC;IAED;;;;OAIG;IACH,gCAGC;IAED,+BAEC;IAED,iCAEC;IAED,6BAEC;IAED,2BAEC;IAED,iCAEC;IAED,gCAEC;IAED;;;;OAIG;IACH,oCAEC;IAED;;;OAGG;IACH,kCAEC;IAED;;;OAGG;IACH,kCAEC;IAED;;;OAGG;IACH,iCAEC;IAED;;;OAGG;IACH,iCAEC;IAED;;;OAGG;IACH,gCAEC;IAED;;;;;OAKG;IACH,gCAEC;IAED;;;OAGG;IACH,iCAEC;IAED,gCAEC;IAED,+BAEC;IAED,8BAEC;IAED;;OAEG;IACH,qCAQC;IAID;;;;;;;;;;OAUG;IACH,iBAHW,mBAAmB,GACjB,MAAM,CA8ClB;IAED;;;;;;OAMG;IACH,mBAHW,mBAAmB,GACjB,OAAO,CAgBnB;IAED;;;OAGG;IACH,sBAHW,mBAAmB,GACjB,OAAO,CAInB;IAED;;;;;;OAMG;IACH,cAJW,mBAAmB,cACnB,MAAM,GACJ,QAAQ,GAAC,UAAU,GAAC,aAAa,GAAC,KAAK,GAAC,MAAM,GAAC,cAAc,CAqBzE;IA6CD;;;;OAIG;IACH,SAFa,IAAI,CAOhB;IAED;;;;OAIG;IACH,WAFa,IAAI,CAUhB;IAED;;;;OAIG;IACH,qBAFa,MAAM,CAkBlB;IAID;;;;;;;;;OASG;IACH,aANW,WAAW,UACX;QAAC,eAAe,EAAE,MAAM,CAAC;QAAC,gBAAgB,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAC;QAChF,UAAgB,EAAE,MAAM,CAAA;KAAC,iBACf,MAAM,GACJ,IAAI,CA6HhB;IA2FD;;;;;;OAMG;IACH,yBAHW,MAAM,GACJ,OAAO,CAgBnB;IAED;;;;;;OAMG;IACH,oBAHW,MAAM,GACJ,OAAO,CAoCnB;;CAqXJ;kCAl2CY,OAAO,uCAAuC,EAAE,mBAAmB;uBACnE,OAAO,4BAA4B,EAAE,QAAQ;qCAC7C,OAAO,6BAA6B,EAAE,sBAAsB;qCALpC,2BAA2B;gCALhC,gDAAgD;gCAIhD,sBAAsB"}
|
|
@@ -645,7 +645,20 @@ export class VGeoResidency {
|
|
|
645
645
|
this.#vram_last_used[row] = 0;
|
|
646
646
|
}
|
|
647
647
|
|
|
648
|
-
|
|
648
|
+
/**
|
|
649
|
+
* TAG_PENDING too. `#fetch` reserves the slot and charges its bytes before the read goes
|
|
650
|
+
* out, and a fetching page is TAG_PENDING — so leaving it out here meant the slot and
|
|
651
|
+
* its reserved bytes were never given back: both settle handlers return on
|
|
652
|
+
* `#geometries.get(reader) !== geometry` before they would free it, and `unregister`
|
|
653
|
+
* drops the geometry synchronously right after cancelling, so that is the branch that
|
|
654
|
+
* always runs. A scene that swaps assets leaked a slot per fetch on the wire until
|
|
655
|
+
* `#make_ram_room` refused everything, while `ram_resident_bytes` and `ram_page_count`
|
|
656
|
+
* both went on reporting the tier as empty.
|
|
657
|
+
*
|
|
658
|
+
* `#free_ram_slot` is a no-op for NO_SLOT and for a slot already given back, so the
|
|
659
|
+
* quarantined half of TAG_PENDING costs nothing here.
|
|
660
|
+
*/
|
|
661
|
+
if (tag === TAG_VRAM || tag === TAG_RAM || tag === TAG_PENDING) {
|
|
649
662
|
this.#free_ram_slot(geometry.slot[page_index]);
|
|
650
663
|
}
|
|
651
664
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"chunk_vgeo_cut_access.d.ts","sourceRoot":"","sources":["../../../../../../../../src/shade/renderer/geometry/virtual/runtime/cut/chunk_vgeo_cut_access.js"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;;;GAeG;AACH,oCAFU,SAAS,
|
|
1
|
+
{"version":3,"file":"chunk_vgeo_cut_access.d.ts","sourceRoot":"","sources":["../../../../../../../../src/shade/renderer/geometry/virtual/runtime/cut/chunk_vgeo_cut_access.js"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;;;GAeG;AACH,oCAFU,SAAS,CAiHQ;0BAnID,0CAA0C"}
|
|
@@ -95,4 +95,38 @@ fn vg_sphere_outside_frustum(instance_base: u32, sphere: vec4<f32>) -> bool {
|
|
|
95
95
|
|
|
96
96
|
return false;
|
|
97
97
|
}
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* Whether a box is entirely outside the instance's object-space frustum.
|
|
101
|
+
*
|
|
102
|
+
* The same five planes, and one corner per plane rather than eight: the corner furthest along the
|
|
103
|
+
* plane's normal is the last of the box to leave the half-space, so if *it* is behind the plane the
|
|
104
|
+
* whole box is. Picking it per axis by the normal's sign is three selects and no branch.
|
|
105
|
+
*
|
|
106
|
+
* Unlike the sphere test this one does not care whether the planes are normalized — it compares a
|
|
107
|
+
* signed distance against zero rather than against a radius — which matters because the planes are
|
|
108
|
+
* the instance's own, pulled into object space through a transform that may not be a rotation.
|
|
109
|
+
*
|
|
110
|
+
* It is conservative in the direction that costs a visit rather than a hole: a box that lies past a
|
|
111
|
+
* frustum edge without crossing any single plane's half-space passes, and is descended into.
|
|
112
|
+
*/
|
|
113
|
+
fn vg_box_outside_frustum(instance_base: u32, lower: vec3<f32>, upper: vec3<f32>) -> bool {
|
|
114
|
+
for (var plane = 0u; plane < 5u; plane = plane + 1u) {
|
|
115
|
+
let word = instance_base + ${VGEO_INSTANCE_OFFSET.FRUSTUM}u + plane * 4u;
|
|
116
|
+
|
|
117
|
+
let normal = vec3<f32>(
|
|
118
|
+
bitcast<f32>(instances[word]),
|
|
119
|
+
bitcast<f32>(instances[word + 1u]),
|
|
120
|
+
bitcast<f32>(instances[word + 2u])
|
|
121
|
+
);
|
|
122
|
+
|
|
123
|
+
let far_corner = select(lower, upper, normal >= vec3<f32>(0.0));
|
|
124
|
+
|
|
125
|
+
if (dot(normal, far_corner) + bitcast<f32>(instances[word + 3u]) < 0.0) {
|
|
126
|
+
return true;
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
return false;
|
|
131
|
+
}
|
|
98
132
|
`, [chunk_vgeo_cut_arena]);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"chunk_vgeo_cut_arena.d.ts","sourceRoot":"","sources":["../../../../../../../../src/shade/renderer/geometry/virtual/runtime/cut/chunk_vgeo_cut_arena.js"],"names":[],"mappings":"AAWA;;;;;;;;;;;;;;;GAeG;AACH,mCAFU,SAAS,
|
|
1
|
+
{"version":3,"file":"chunk_vgeo_cut_arena.d.ts","sourceRoot":"","sources":["../../../../../../../../src/shade/renderer/geometry/virtual/runtime/cut/chunk_vgeo_cut_arena.js"],"names":[],"mappings":"AAWA;;;;;;;;;;;;;;;GAeG;AACH,mCAFU,SAAS,CA0FZ;0BAnHmB,0CAA0C"}
|
|
@@ -95,4 +95,22 @@ fn vg_sphere_at(word: u32) -> vec4<f32> {
|
|
|
95
95
|
bitcast<f32>(vg_arena[word + 3u])
|
|
96
96
|
);
|
|
97
97
|
}
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* Six consecutive words as an axis-aligned box: the lower corner, then the upper.
|
|
101
|
+
*/
|
|
102
|
+
fn vg_box_at(word: u32) -> array<vec3<f32>, 2> {
|
|
103
|
+
return array<vec3<f32>, 2>(
|
|
104
|
+
vec3<f32>(
|
|
105
|
+
bitcast<f32>(vg_arena[word]),
|
|
106
|
+
bitcast<f32>(vg_arena[word + 1u]),
|
|
107
|
+
bitcast<f32>(vg_arena[word + 2u])
|
|
108
|
+
),
|
|
109
|
+
vec3<f32>(
|
|
110
|
+
bitcast<f32>(vg_arena[word + 3u]),
|
|
111
|
+
bitcast<f32>(vg_arena[word + 4u]),
|
|
112
|
+
bitcast<f32>(vg_arena[word + 5u])
|
|
113
|
+
)
|
|
114
|
+
);
|
|
115
|
+
}
|
|
98
116
|
`, []);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"shader_vgeo_cut_traverse.d.ts","sourceRoot":"","sources":["../../../../../../../../src/shade/renderer/geometry/virtual/runtime/cut/shader_vgeo_cut_traverse.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"shader_vgeo_cut_traverse.d.ts","sourceRoot":"","sources":["../../../../../../../../src/shade/renderer/geometry/virtual/runtime/cut/shader_vgeo_cut_traverse.js"],"names":[],"mappings":"AAm4BA,qDAIG;8BAp4B2B,qCAAqC"}
|
|
@@ -123,8 +123,14 @@ import { VGEO_CUT_WORKGROUP_SIZE } from "./VGEO_CUT_WORKGROUP_SIZE.js";
|
|
|
123
123
|
* induction its page is visited. `P` fails `project(self) <= tau`, so it either enqueues `C`'s
|
|
124
124
|
* page or clamps, and it clamps only when `C`'s group is not selectable, in which case `C` must
|
|
125
125
|
* not be drawn. Neither cull intervenes: a node's sphere contains `P.parent_sphere` and its
|
|
126
|
-
* `max_parent_error` is at least `P.parent_error`, so the LOD cull cannot fire, and
|
|
127
|
-
*
|
|
126
|
+
* `max_parent_error` is at least `P.parent_error`, so the LOD cull cannot fire, and both frustum
|
|
127
|
+
* culls are on bounds of `P`'s whole subtree, which contains `C` — so they fire only where `C`
|
|
128
|
+
* is off-screen anyway.
|
|
129
|
+
*
|
|
130
|
+
* Note that the per-cluster frustum tests do **not** have to agree across a group's several
|
|
131
|
+
* parents, and nothing here asks them to. A group is claimed and descended once, by whichever
|
|
132
|
+
* parent reaches it first; a parent that culls itself out simply is not that one. What each test
|
|
133
|
+
* promises is about its own subtree and nothing else.
|
|
128
134
|
*
|
|
129
135
|
* Descent crosses a page boundary by producing the child page's **node 0**: uniform items, one
|
|
130
136
|
* kernel, no special case for "entering a page". `SAME_PAGE` needs no special case either, because
|
|
@@ -472,23 +478,6 @@ fn vg_visit_cluster(
|
|
|
472
478
|
|
|
473
479
|
vg_stat(${VGEO_CUT_STAT.CLUSTERS_TESTED}u, 1u);
|
|
474
480
|
|
|
475
|
-
/*
|
|
476
|
-
Before the cluster can refine, and the reason is residency rather than the draw: refining
|
|
477
|
-
claims the child page, and a claim is a touch — the LRU's whole input — so an off-screen
|
|
478
|
-
cluster that refined anyway would keep pages nobody can see hot and the tier full of them.
|
|
479
|
-
self_sphere contains the cluster's own vertices (FORMAT §7), so this rejects nothing on
|
|
480
|
-
screen; and every parent of a group shares one self_sphere, so a group's parents decide this
|
|
481
|
-
uniformly and the cut's proofs stand (RUNTIME_PLAN §4.4).
|
|
482
|
-
*/
|
|
483
|
-
if ((params.flags & ${VGEO_CUT_FLAG_CULL}u) != 0u
|
|
484
|
-
&& vg_sphere_outside_frustum(
|
|
485
|
-
instance_base, vg_sphere_at(row + ${VGEO_CLUSTER_ROW_OFFSET.SELF_SPHERE}u)
|
|
486
|
-
)) {
|
|
487
|
-
vg_stat(${VGEO_CUT_STAT.CULLED_CLUSTER}u, 1u);
|
|
488
|
-
|
|
489
|
-
return vg_expand_none();
|
|
490
|
-
}
|
|
491
|
-
|
|
492
481
|
let parent_projected = vg_project(
|
|
493
482
|
vg_arena_f32(row + ${VGEO_CLUSTER_ROW_OFFSET.PARENT_ERROR}u),
|
|
494
483
|
vg_sphere_at(row + ${VGEO_CLUSTER_ROW_OFFSET.PARENT_SPHERE}u),
|
|
@@ -525,6 +514,45 @@ fn vg_visit_cluster(
|
|
|
525
514
|
);
|
|
526
515
|
}
|
|
527
516
|
|
|
517
|
+
/*
|
|
518
|
+
The frustum, on two bounds of this cluster's whole subtree, and **below the election above**.
|
|
519
|
+
|
|
520
|
+
Why here and not at the top of the function. The reason to cull is residency rather than the
|
|
521
|
+
draw: refining claims the child page, and a claim is a touch — the LRU's whole input — so an
|
|
522
|
+
off-screen cluster that refined anyway would keep pages nobody can see hot and the tier full of
|
|
523
|
+
them. A cluster that took the branch above is below the cut: it refines into nothing, claims
|
|
524
|
+
nothing and draws nothing, so culling it buys residency exactly nothing, while skipping its
|
|
525
|
+
election costs a coarsen its walk up. The parent that election reaches can protrude on screen
|
|
526
|
+
past everything under it — that is what a coarser surface covering the same region looks like —
|
|
527
|
+
and with the test above the election it was never reached, so it was neither drawn nor stood in
|
|
528
|
+
for. A hole, and the tighter the bound the more often.
|
|
529
|
+
|
|
530
|
+
Why two bounds. Both contain every vertex reachable below this cluster, which is what makes
|
|
531
|
+
either safe to cull a subtree on: self_sphere by the builder's construction and FORMAT §11.7,
|
|
532
|
+
CULL_BOX by §11.17. The box is much the tighter of the two on real geometry — a subtree is a
|
|
533
|
+
patch of surface and its box is thin where a sphere is round — and the sphere stays because a
|
|
534
|
+
container written before the box existed has its cube there instead, and a cube culls less than
|
|
535
|
+
the sphere inside it.
|
|
536
|
+
*/
|
|
537
|
+
if ((params.flags & ${VGEO_CUT_FLAG_CULL}u) != 0u) {
|
|
538
|
+
if (vg_sphere_outside_frustum(
|
|
539
|
+
instance_base, vg_sphere_at(row + ${VGEO_CLUSTER_ROW_OFFSET.SELF_SPHERE}u)
|
|
540
|
+
)) {
|
|
541
|
+
vg_stat(${VGEO_CUT_STAT.CULLED_CLUSTER}u, 1u);
|
|
542
|
+
|
|
543
|
+
return vg_expand_none();
|
|
544
|
+
}
|
|
545
|
+
|
|
546
|
+
let cull_box = vg_box_at(row + ${VGEO_CLUSTER_ROW_OFFSET.CULL_BOX}u);
|
|
547
|
+
|
|
548
|
+
if (vg_box_outside_frustum(instance_base, cull_box[0], cull_box[1])) {
|
|
549
|
+
vg_stat(${VGEO_CUT_STAT.CULLED_CLUSTER}u, 1u);
|
|
550
|
+
vg_stat(${VGEO_CUT_STAT.CULLED_CLUSTER_BOX}u, 1u);
|
|
551
|
+
|
|
552
|
+
return vg_expand_none();
|
|
553
|
+
}
|
|
554
|
+
}
|
|
555
|
+
|
|
528
556
|
let self_projected = vg_project(
|
|
529
557
|
vg_arena_f32(row + ${VGEO_CLUSTER_ROW_OFFSET.SELF_ERROR}u),
|
|
530
558
|
vg_sphere_at(row + ${VGEO_CLUSTER_ROW_OFFSET.SELF_SPHERE}u),
|