@woosh/meep-engine 3.27.0 → 3.28.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-terrain.js +1 -1
- package/package.json +1 -1
- package/src/core/geom/3d/mat4/m4_linear_determinant.d.ts +15 -0
- package/src/core/geom/3d/mat4/m4_linear_determinant.d.ts.map +1 -0
- package/src/core/geom/3d/mat4/m4_linear_determinant.js +24 -0
- package/src/core/geom/3d/mat4/m4_normal_matrix3.d.ts +4 -2
- package/src/core/geom/3d/mat4/m4_normal_matrix3.d.ts.map +1 -1
- package/src/core/geom/3d/mat4/m4_normal_matrix3.js +21 -11
- package/src/engine/Engine.d.ts.map +1 -1
- package/src/engine/Engine.js +38 -1
- package/src/engine/graphics3/GraphicsEngine.d.ts +5 -1
- package/src/engine/graphics3/GraphicsEngine.d.ts.map +1 -1
- package/src/engine/graphics3/GraphicsEngine.js +834 -830
- package/src/shade/RENDERER_CONTRACT.md +19 -10
- package/src/shade/device/timing/GPU_PROFILER_PROPOSAL_2026_08_28.md +1 -1
- package/src/shade/playground/vgeo_runtime/README.md +27 -13
- package/src/shade/playground/vgeo_runtime/main.js +18 -5
- package/src/shade/playground/vgeo_runtime/sample_asset.d.ts +18 -0
- package/src/shade/playground/vgeo_runtime/sample_asset.d.ts.map +1 -0
- package/src/shade/playground/{vgeo_viewer → vgeo_runtime}/sample_asset.js +9 -8
- package/src/shade/playground/vgeo_scene/README.md +408 -0
- package/src/shade/playground/vgeo_scene/index.html +144 -0
- package/src/shade/playground/vgeo_scene/main.d.ts +2 -0
- package/src/shade/playground/vgeo_scene/main.d.ts.map +1 -0
- package/src/shade/playground/vgeo_scene/main.js +1716 -0
- package/src/shade/renderer/Renderer.d.ts +4 -1
- package/src/shade/renderer/Renderer.d.ts.map +1 -1
- package/src/shade/renderer/Renderer.js +5 -2
- package/src/shade/renderer/extension/RENDER_EXTENSION_DESIGN.md +1 -2
- package/src/shade/renderer/geometry/meshlet/MeshletBatch.d.ts.map +1 -1
- package/src/shade/renderer/geometry/meshlet/MeshletBatch.js +3 -29
- package/src/shade/renderer/geometry/meshlet/encoding/ENCODED_ATTRIBUTE_DEFAULT_VALUES.d.ts +22 -0
- package/src/shade/renderer/geometry/meshlet/encoding/ENCODED_ATTRIBUTE_DEFAULT_VALUES.d.ts.map +1 -0
- package/src/shade/renderer/geometry/meshlet/encoding/ENCODED_ATTRIBUTE_DEFAULT_VALUES.js +49 -0
- package/src/shade/renderer/geometry/virtual/VGEO_FORMAT.md +4 -2
- package/src/shade/renderer/geometry/virtual/VIRTUAL_GEOMETRY_DESIGN.md +10 -8
- package/src/shade/renderer/geometry/virtual/VIRTUAL_GEOMETRY_PLAN.md +12 -11
- package/src/shade/renderer/geometry/virtual/build/VGeoBuildOptions.d.ts +1 -1
- package/src/shade/renderer/geometry/virtual/build/VGeoBuildOptions.d.ts.map +1 -1
- package/src/shade/renderer/geometry/virtual/build/VGeoBuildOptions.js +1 -1
- package/src/shade/renderer/geometry/virtual/build/gltf/gltf_open_document.d.ts.map +1 -1
- package/src/shade/renderer/geometry/virtual/build/gltf/gltf_open_document.js +5 -9
- package/src/shade/renderer/geometry/virtual/build/level/VGeoLevel.d.ts +32 -0
- package/src/shade/renderer/geometry/virtual/build/level/VGeoLevel.d.ts.map +1 -0
- package/src/shade/renderer/geometry/virtual/build/level/VGeoLevelOptions.d.ts +59 -0
- package/src/shade/renderer/geometry/virtual/build/level/VGeoLevelOptions.d.ts.map +1 -0
- package/src/shade/renderer/geometry/virtual/build/level/VGeoLevelSummary.d.ts +44 -0
- package/src/shade/renderer/geometry/virtual/build/level/VGeoLevelSummary.d.ts.map +1 -0
- package/src/shade/renderer/geometry/virtual/build/level/vgeo_build_levels.d.ts +36 -0
- package/src/shade/renderer/geometry/virtual/build/level/vgeo_build_levels.d.ts.map +1 -0
- package/src/shade/renderer/geometry/virtual/build/{vgeo_build_levels.js → level/vgeo_build_levels.js} +61 -95
- package/src/shade/renderer/geometry/virtual/build/level/vgeo_build_root_group.d.ts +19 -0
- package/src/shade/renderer/geometry/virtual/build/level/vgeo_build_root_group.d.ts.map +1 -0
- package/src/shade/renderer/geometry/virtual/build/{vgeo_build_root_group.js → level/vgeo_build_root_group.js} +1 -1
- package/src/shade/renderer/geometry/virtual/build/mesh/VirtualGeometryMesh.d.ts +73 -0
- package/src/shade/renderer/geometry/virtual/build/mesh/VirtualGeometryMesh.d.ts.map +1 -0
- package/src/shade/renderer/geometry/virtual/build/{VirtualGeometryMesh.js → mesh/VirtualGeometryMesh.js} +7 -7
- package/src/shade/renderer/geometry/virtual/build/mesh/vgeo_compute_vertex_normals.d.ts +29 -0
- package/src/shade/renderer/geometry/virtual/build/mesh/vgeo_compute_vertex_normals.d.ts.map +1 -0
- package/src/shade/renderer/geometry/virtual/build/{vgeo_compute_vertex_normals.js → mesh/vgeo_compute_vertex_normals.js} +3 -3
- package/src/shade/renderer/geometry/virtual/build/mesh/vgeo_compute_vertex_tangents.d.ts +31 -0
- package/src/shade/renderer/geometry/virtual/build/mesh/vgeo_compute_vertex_tangents.d.ts.map +1 -0
- package/src/shade/renderer/geometry/virtual/build/{vgeo_compute_vertex_tangents.js → mesh/vgeo_compute_vertex_tangents.js} +5 -5
- package/src/shade/renderer/geometry/virtual/build/mesh/vgeo_normalize_source.d.ts +46 -0
- package/src/shade/renderer/geometry/virtual/build/mesh/vgeo_normalize_source.d.ts.map +1 -0
- package/src/shade/renderer/geometry/virtual/build/{vgeo_normalize_source.js → mesh/vgeo_normalize_source.js} +9 -9
- package/src/shade/renderer/geometry/virtual/build/page/vgeo_assemble_pages.d.ts +13 -0
- package/src/shade/renderer/geometry/virtual/build/page/vgeo_assemble_pages.d.ts.map +1 -0
- package/src/shade/renderer/geometry/virtual/build/{vgeo_assemble_pages.js → page/vgeo_assemble_pages.js} +9 -9
- package/src/shade/renderer/geometry/virtual/build/page/vgeo_build_page_nodes.d.ts +13 -0
- package/src/shade/renderer/geometry/virtual/build/page/vgeo_build_page_nodes.d.ts.map +1 -0
- package/src/shade/renderer/geometry/virtual/build/{vgeo_build_page_nodes.js → page/vgeo_build_page_nodes.js} +4 -4
- package/src/shade/renderer/geometry/virtual/build/page/vgeo_page_node_count.d.ts +22 -0
- package/src/shade/renderer/geometry/virtual/build/page/vgeo_page_node_count.d.ts.map +1 -0
- package/src/shade/renderer/geometry/virtual/build/{vgeo_page_node_count.js → page/vgeo_page_node_count.js} +2 -2
- package/src/shade/renderer/geometry/virtual/build/partition/VGeoFaceGraph.d.ts +52 -0
- package/src/shade/renderer/geometry/virtual/build/partition/VGeoFaceGraph.d.ts.map +1 -0
- package/src/shade/renderer/geometry/virtual/build/{VGeoFaceGraph.js → partition/VGeoFaceGraph.js} +1 -1
- package/src/shade/renderer/geometry/virtual/build/partition/vgeo_graph_components.d.ts +14 -0
- package/src/shade/renderer/geometry/virtual/build/partition/vgeo_graph_components.d.ts.map +1 -0
- package/src/shade/renderer/geometry/virtual/build/partition/vgeo_partition_graph.d.ts +29 -0
- package/src/shade/renderer/geometry/virtual/build/partition/vgeo_partition_graph.d.ts.map +1 -0
- package/src/shade/renderer/geometry/virtual/build/{vgeo_partition_graph.js → partition/vgeo_partition_graph.js} +2 -2
- package/src/shade/renderer/geometry/virtual/build/partition/vgeo_partition_subgraph.d.ts +41 -0
- package/src/shade/renderer/geometry/virtual/build/partition/vgeo_partition_subgraph.d.ts.map +1 -0
- package/src/shade/renderer/geometry/virtual/build/partition/vgeo_partition_subgraph.js +92 -0
- package/src/shade/renderer/geometry/virtual/build/partition/vgeo_split_face_set.d.ts +10 -0
- package/src/shade/renderer/geometry/virtual/build/partition/vgeo_split_face_set.d.ts.map +1 -0
- package/src/shade/renderer/geometry/virtual/build/{vgeo_split_face_set.js → partition/vgeo_split_face_set.js} +12 -55
- package/src/shade/renderer/geometry/virtual/build/partition/vgeo_split_face_set_packed.d.ts +15 -0
- package/src/shade/renderer/geometry/virtual/build/partition/vgeo_split_face_set_packed.d.ts.map +1 -0
- package/src/shade/renderer/geometry/virtual/build/{vgeo_split_face_set_packed.js → partition/vgeo_split_face_set_packed.js} +3 -3
- package/src/shade/renderer/geometry/virtual/build/sphere/vgeo_bounding_sphere.d.ts +12 -0
- package/src/shade/renderer/geometry/virtual/build/sphere/vgeo_bounding_sphere.d.ts.map +1 -0
- package/src/shade/renderer/geometry/virtual/build/{vgeo_bounding_sphere.js → sphere/vgeo_bounding_sphere.js} +3 -3
- package/src/shade/renderer/geometry/virtual/build/sphere/vgeo_containing_sphere.d.ts +18 -0
- package/src/shade/renderer/geometry/virtual/build/sphere/vgeo_containing_sphere.d.ts.map +1 -0
- package/src/shade/renderer/geometry/virtual/build/{vgeo_containing_sphere.js → sphere/vgeo_containing_sphere.js} +3 -3
- package/src/shade/renderer/geometry/virtual/build/sphere/vgeo_sphere_inflate_to_contain.d.ts +9 -0
- package/src/shade/renderer/geometry/virtual/build/sphere/vgeo_sphere_inflate_to_contain.d.ts.map +1 -0
- package/src/shade/renderer/geometry/virtual/build/{vgeo_sphere_inflate_to_contain.js → sphere/vgeo_sphere_inflate_to_contain.js} +1 -1
- package/src/shade/renderer/geometry/virtual/build/submesh/VGeoGatheredFaces.d.ts +24 -0
- package/src/shade/renderer/geometry/virtual/build/submesh/VGeoGatheredFaces.d.ts.map +1 -0
- package/src/shade/renderer/geometry/virtual/build/submesh/VGeoSubmesh.d.ts +20 -0
- package/src/shade/renderer/geometry/virtual/build/submesh/VGeoSubmesh.d.ts.map +1 -0
- package/src/shade/renderer/geometry/virtual/build/submesh/vgeo_extract_submesh.d.ts +14 -0
- package/src/shade/renderer/geometry/virtual/build/submesh/vgeo_extract_submesh.d.ts.map +1 -0
- package/src/shade/renderer/geometry/virtual/build/{vgeo_extract_submesh.js → submesh/vgeo_extract_submesh.js} +5 -5
- package/src/shade/renderer/geometry/virtual/build/submesh/vgeo_gather_faces.d.ts +12 -0
- package/src/shade/renderer/geometry/virtual/build/submesh/vgeo_gather_faces.d.ts.map +1 -0
- package/src/shade/renderer/geometry/virtual/build/{vgeo_gather_faces.js → submesh/vgeo_gather_faces.js} +2 -2
- package/src/shade/renderer/geometry/virtual/build/submesh/vgeo_narrow_indices.d.ts +11 -0
- package/src/shade/renderer/geometry/virtual/build/submesh/vgeo_narrow_indices.d.ts.map +1 -0
- package/src/shade/renderer/geometry/virtual/build/{vgeo_narrow_indices.js → submesh/vgeo_narrow_indices.js} +3 -3
- package/src/shade/renderer/geometry/virtual/build/vgeo_build.d.ts.map +1 -1
- package/src/shade/renderer/geometry/virtual/build/vgeo_build.js +9 -11
- package/src/shade/renderer/geometry/virtual/format/attribute/vgeo_attributes_read.d.ts +8 -2
- package/src/shade/renderer/geometry/virtual/format/attribute/vgeo_attributes_read.d.ts.map +1 -1
- package/src/shade/renderer/geometry/virtual/format/attribute/vgeo_attributes_read.js +8 -2
- package/src/shade/renderer/geometry/virtual/format/page/VGEO_GROUP_OFFSET.d.ts +15 -0
- package/src/shade/renderer/geometry/virtual/format/page/VGEO_GROUP_OFFSET.d.ts.map +1 -0
- package/src/shade/renderer/geometry/virtual/format/page/VGEO_GROUP_OFFSET.js +15 -0
- package/src/shade/renderer/geometry/virtual/format/payload/vgeo_encode_cluster_payload.d.ts +28 -0
- 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 +7 -3
- 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 +9 -4
- 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 +18 -5
- 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 +9 -1
- package/src/shade/renderer/geometry/virtual/runtime/CUT_PLAN_2026_09_14.md +21 -2
- package/src/shade/renderer/geometry/virtual/runtime/GPUVirtualGeometryRuntime.d.ts +52 -2
- package/src/shade/renderer/geometry/virtual/runtime/GPUVirtualGeometryRuntime.d.ts.map +1 -1
- package/src/shade/renderer/geometry/virtual/runtime/GPUVirtualGeometryRuntime.js +97 -1
- package/src/shade/renderer/geometry/virtual/runtime/RUNTIME_PLAN.md +4 -4
- package/src/shade/renderer/geometry/virtual/runtime/VGeoFeedbackLoop.d.ts.map +1 -1
- package/src/shade/renderer/geometry/virtual/runtime/VGeoFeedbackLoop.js +10 -0
- package/src/shade/renderer/geometry/virtual/runtime/VGeoResidency.d.ts.map +1 -1
- package/src/shade/renderer/geometry/virtual/runtime/VGeoResidency.js +59 -34
- package/src/shade/renderer/geometry/virtual/runtime/cut/chunk_vgeo_cut_access.d.ts +8 -8
- 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 +11 -88
- package/src/shade/renderer/geometry/virtual/runtime/cut/chunk_vgeo_cut_arena.d.ts +19 -0
- package/src/shade/renderer/geometry/virtual/runtime/cut/chunk_vgeo_cut_arena.d.ts.map +1 -0
- package/src/shade/renderer/geometry/virtual/runtime/cut/chunk_vgeo_cut_arena.js +98 -0
- package/src/shade/renderer/geometry/virtual/runtime/cut/chunk_vgeo_cut_claim.d.ts +31 -0
- package/src/shade/renderer/geometry/virtual/runtime/cut/chunk_vgeo_cut_claim.d.ts.map +1 -0
- package/src/shade/renderer/geometry/virtual/runtime/cut/chunk_vgeo_cut_claim.js +99 -0
- package/src/shade/renderer/geometry/virtual/runtime/cut/chunk_vgeo_cut_queue.d.ts +17 -0
- package/src/shade/renderer/geometry/virtual/runtime/cut/chunk_vgeo_cut_queue.d.ts.map +1 -0
- package/src/shade/renderer/geometry/virtual/runtime/cut/chunk_vgeo_cut_queue.js +39 -0
- package/src/shade/renderer/geometry/virtual/runtime/cut/shader_vgeo_cut_reseed.d.ts.map +1 -1
- package/src/shade/renderer/geometry/virtual/runtime/cut/shader_vgeo_cut_reseed.js +7 -63
- package/src/shade/renderer/geometry/virtual/runtime/cut/shader_vgeo_cut_seed.d.ts.map +1 -1
- package/src/shade/renderer/geometry/virtual/runtime/cut/shader_vgeo_cut_seed.js +13 -30
- 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 +6 -52
- package/src/shade/renderer/loader/gltf/load_gltf.d.ts.map +1 -1
- package/src/shade/renderer/loader/gltf/load_gltf.js +0 -19
- package/src/shade/renderer/material/chunk_material_draw_side.d.ts +14 -0
- package/src/shade/renderer/material/chunk_material_draw_side.d.ts.map +1 -0
- package/src/shade/renderer/material/chunk_material_draw_side.js +34 -0
- package/src/shade/renderer/material/standard/fragment_gbuffer.d.ts.map +1 -1
- package/src/shade/renderer/material/standard/fragment_gbuffer.js +8 -1
- package/src/shade/renderer/path_tracer/shader/chunk_sample_material_data.d.ts.map +1 -1
- package/src/shade/renderer/path_tracer/shader/chunk_sample_material_data.js +13 -1
- package/src/shade/renderer/rasterize/bucket/construct_primitive_state.d.ts +19 -5
- package/src/shade/renderer/rasterize/bucket/construct_primitive_state.d.ts.map +1 -1
- package/src/shade/renderer/rasterize/bucket/construct_primitive_state.js +23 -5
- package/src/shade/renderer/rasterize/bucket/filter_materials_by_bucket.d.ts.map +1 -1
- package/src/shade/renderer/rasterize/bucket/filter_materials_by_bucket.js +12 -5
- package/src/shade/renderer/rasterize/bucket/rasterization_opaque_buckets.d.ts +22 -0
- package/src/shade/renderer/rasterize/bucket/rasterization_opaque_buckets.d.ts.map +1 -0
- package/src/shade/renderer/rasterize/bucket/rasterization_opaque_buckets.js +36 -0
- package/src/shade/renderer/rasterize/chunk_triangle_winding_is_reversed.d.ts +15 -0
- package/src/shade/renderer/rasterize/chunk_triangle_winding_is_reversed.d.ts.map +1 -0
- package/src/shade/renderer/rasterize/chunk_triangle_winding_is_reversed.js +35 -0
- package/src/shade/renderer/rasterize/expand/bucket/RASTERIZATION_BUCKET_LIMIT.d.ts +10 -1
- package/src/shade/renderer/rasterize/expand/bucket/RASTERIZATION_BUCKET_LIMIT.d.ts.map +1 -1
- package/src/shade/renderer/rasterize/expand/bucket/RASTERIZATION_BUCKET_LIMIT.js +38 -29
- package/src/shade/renderer/rasterize/expand/bucket/chunk_rasterization_material_bucket.d.ts +5 -0
- package/src/shade/renderer/rasterize/expand/bucket/chunk_rasterization_material_bucket.d.ts.map +1 -1
- package/src/shade/renderer/rasterize/expand/bucket/chunk_rasterization_material_bucket.js +63 -55
- package/src/shade/renderer/rasterize/expand/graph_meshlets_rasterize.d.ts.map +1 -1
- package/src/shade/renderer/rasterize/expand/graph_meshlets_rasterize.js +1 -0
- 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 +44 -53
- package/src/shade/renderer/rasterize/forward/chunk_forward_shade_standard_fragment_brick4.d.ts.map +1 -1
- package/src/shade/renderer/rasterize/forward/chunk_forward_shade_standard_fragment_brick4.js +6 -2
- package/src/shade/renderer/rasterize/forward/chunk_forward_shade_standard_fragment_ibl.d.ts.map +1 -1
- package/src/shade/renderer/rasterize/forward/chunk_forward_shade_standard_fragment_ibl.js +6 -2
- package/src/shade/renderer/rasterize/forward/vertex_shader_chunk.d.ts.map +1 -1
- package/src/shade/renderer/rasterize/forward/vertex_shader_chunk.js +19 -2
- package/src/shade/renderer/rasterize/native/avboit/AVBOIT_PLAN_2026_09_03.md +7 -4
- package/src/shade/renderer/rasterize/native/avboit/graph_rasterize_meshes_transparent_avboit.d.ts.map +1 -1
- package/src/shade/renderer/rasterize/native/avboit/graph_rasterize_meshes_transparent_avboit.js +3 -2
- package/src/shade/renderer/rasterize/native/chunk_rasterize_triangle.d.ts.map +1 -1
- package/src/shade/renderer/rasterize/native/chunk_rasterize_triangle.js +15 -4
- package/src/shade/renderer/rasterize/native/depth/shadow_rasterization_alpha_tested_pass_descriptor.d.ts.map +1 -1
- package/src/shade/renderer/rasterize/native/depth/shadow_rasterization_alpha_tested_pass_descriptor.js +16 -5
- package/src/shade/renderer/rasterize/native/depth/shadow_rasterization_pass_descriptor.d.ts.map +1 -1
- package/src/shade/renderer/rasterize/native/depth/shadow_rasterization_pass_descriptor.js +16 -5
- package/src/shade/renderer/rasterize/native/oit/graph_rasterize_meshes_transparent_oit.d.ts.map +1 -1
- package/src/shade/renderer/rasterize/native/oit/graph_rasterize_meshes_transparent_oit.js +2 -1
- package/src/shade/renderer/rasterize/native/rasterization_shader_resources.d.ts.map +1 -1
- package/src/shade/renderer/rasterize/native/rasterization_shader_resources.js +4 -0
- package/src/shade/renderer/rasterize/native/viz/viz_rasterization_alpha_tested_pass_descriptor.d.ts.map +1 -1
- package/src/shade/renderer/rasterize/native/viz/viz_rasterization_alpha_tested_pass_descriptor.js +16 -7
- 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 +78 -88
- 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 +21 -31
- package/src/shade/renderer/scene/GPUSceneContext.d.ts.map +1 -1
- package/src/shade/renderer/scene/GPUSceneContext.js +2 -0
- package/src/shade/renderer/scene/NODE3D_STRUCT.d.ts +19 -0
- package/src/shade/renderer/scene/NODE3D_STRUCT.d.ts.map +1 -1
- package/src/shade/renderer/scene/NODE3D_STRUCT.js +34 -0
- package/src/shade/renderer/scene/chunk_node3d_flags.d.ts +9 -0
- package/src/shade/renderer/scene/chunk_node3d_flags.d.ts.map +1 -0
- package/src/shade/renderer/scene/chunk_node3d_flags.js +23 -0
- package/src/shade/renderer/scene/chunk_scene_database_access.d.ts.map +1 -1
- package/src/shade/renderer/scene/chunk_scene_database_access.js +15 -1
- package/src/shade/renderer/scene/rows/GPUSceneRows.d.ts.map +1 -1
- package/src/shade/renderer/scene/rows/GPUSceneRows.js +9 -1
- package/src/shade/renderer/shader/chunk/geometry/mat4/chunk_compute_normal_matrix_from_m4.d.ts +7 -0
- package/src/shade/renderer/shader/chunk/geometry/mat4/chunk_compute_normal_matrix_from_m4.d.ts.map +1 -1
- package/src/shade/renderer/shader/chunk/geometry/mat4/chunk_compute_normal_matrix_from_m4.js +16 -4
- package/src/shade/renderer/shader/chunk/geometry/mat4/chunk_mat4_linear_determinant.d.ts +12 -0
- package/src/shade/renderer/shader/chunk/geometry/mat4/chunk_mat4_linear_determinant.d.ts.map +1 -0
- package/src/shade/renderer/shader/chunk/geometry/mat4/chunk_mat4_linear_determinant.js +18 -0
- package/src/shade/renderer/shader/chunk/geometry/triangle/chunk_triangle_list_reverse_winding.d.ts +24 -0
- package/src/shade/renderer/shader/chunk/geometry/triangle/chunk_triangle_list_reverse_winding.d.ts.map +1 -0
- package/src/shade/renderer/shader/chunk/geometry/triangle/chunk_triangle_list_reverse_winding.js +33 -0
- package/src/shade/playground/vgeo_viewer/README.md +0 -150
- package/src/shade/playground/vgeo_viewer/cut_geometry.js +0 -460
- package/src/shade/playground/vgeo_viewer/index.html +0 -77
- package/src/shade/playground/vgeo_viewer/main.js +0 -1343
- package/src/shade/playground/vgeo_viewer/select_cut.js +0 -481
- package/src/shade/renderer/geometry/virtual/residency/VGeoResidencyManager.d.ts +0 -258
- package/src/shade/renderer/geometry/virtual/residency/VGeoResidencyManager.d.ts.map +0 -1
- package/src/shade/renderer/geometry/virtual/residency/VGeoResidencyOptions.d.ts +0 -49
- package/src/shade/renderer/geometry/virtual/residency/VGeoResidencyOptions.d.ts.map +0 -1
- package/src/shade/renderer/loader/gltf/fix_up_material_sides.js +0 -109
- package/src/shade/renderer/rasterize/expand/graph_triangles_filter_by_material_side.js +0 -78
- package/src/shade/renderer/rasterize/expand/shader_filter_triangle_by_material_side.js +0 -100
- package/src/shade/renderer/rasterize/forward/chunk_material_side_should_draw.js +0 -26
- package/src/shade/renderer/shader/chunk/jobs/chunk_job_system.d.ts +0 -3
- package/src/shade/renderer/shader/chunk/jobs/chunk_job_system.d.ts.map +0 -1
- /package/src/shade/renderer/geometry/virtual/build/{VGeoLevel.js → level/VGeoLevel.js} +0 -0
- /package/src/shade/renderer/geometry/virtual/build/{VGeoLevelOptions.js → level/VGeoLevelOptions.js} +0 -0
- /package/src/shade/renderer/geometry/virtual/build/{VGeoLevelSummary.js → level/VGeoLevelSummary.js} +0 -0
- /package/src/shade/renderer/geometry/virtual/build/{vgeo_graph_components.js → partition/vgeo_graph_components.js} +0 -0
- /package/src/shade/renderer/geometry/virtual/build/{VGeoGatheredFaces.js → submesh/VGeoGatheredFaces.js} +0 -0
- /package/src/shade/renderer/geometry/virtual/build/{VGeoSubmesh.js → submesh/VGeoSubmesh.js} +0 -0
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Gather a face set: unique vertices in first-use order, local indices, coordinates copied out.
|
|
3
|
+
*
|
|
4
|
+
* First-use order is what makes the result depend only on the face list, not on the pool's history.
|
|
5
|
+
*
|
|
6
|
+
* @param {VirtualGeometryMesh} mesh
|
|
7
|
+
* @param {number[]} face_ids allocated triangular faces
|
|
8
|
+
* @returns {VGeoGatheredFaces}
|
|
9
|
+
*/
|
|
10
|
+
export function vgeo_gather_faces(mesh: VirtualGeometryMesh, face_ids: number[]): VGeoGatheredFaces;
|
|
11
|
+
import { VGeoGatheredFaces } from "./VGeoGatheredFaces.js";
|
|
12
|
+
//# sourceMappingURL=vgeo_gather_faces.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vgeo_gather_faces.d.ts","sourceRoot":"","sources":["../../../../../../../../src/shade/renderer/geometry/virtual/build/submesh/vgeo_gather_faces.js"],"names":[],"mappings":"AAcA;;;;;;;;GAQG;AACH,uEAHW,MAAM,EAAE,GACN,iBAAiB,CAiD7B;kCAlEiC,wBAAwB"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { assert } from "
|
|
1
|
+
import { assert } from "../../../../../../core/assert.js";
|
|
2
2
|
import {
|
|
3
3
|
bt_face_read_triangle_vertices
|
|
4
|
-
} from "
|
|
4
|
+
} from "../../../../../../core/geom/3d/topology/struct/binary/query/bt_face_read_triangle.js";
|
|
5
5
|
import { VGeoGatheredFaces } from "./VGeoGatheredFaces.js";
|
|
6
6
|
|
|
7
7
|
/**
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The 8-bit local index list a cluster payload carries.
|
|
3
|
+
*
|
|
4
|
+
* @param {VGeoGatheredFaces} gathered a face set already within the meshlet limits
|
|
5
|
+
* @returns {Uint8Array}
|
|
6
|
+
*
|
|
7
|
+
* @author Alex Goldring
|
|
8
|
+
* @copyright Company Named Limited (c) 2026
|
|
9
|
+
*/
|
|
10
|
+
export function vgeo_narrow_indices(gathered: VGeoGatheredFaces): Uint8Array;
|
|
11
|
+
//# sourceMappingURL=vgeo_narrow_indices.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vgeo_narrow_indices.d.ts","sourceRoot":"","sources":["../../../../../../../../src/shade/renderer/geometry/virtual/build/submesh/vgeo_narrow_indices.js"],"names":[],"mappings":"AAIA;;;;;;;;GAQG;AACH,kEALa,UAAU,CAiBtB"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { assert } from "
|
|
2
|
-
import { VGEO_MAX_CLUSTER_TRIANGLE_COUNT } from "
|
|
3
|
-
import { VGEO_MAX_CLUSTER_VERTEX_COUNT } from "
|
|
1
|
+
import { assert } from "../../../../../../core/assert.js";
|
|
2
|
+
import { VGEO_MAX_CLUSTER_TRIANGLE_COUNT } from "../../format/cluster/VGEO_MAX_CLUSTER_TRIANGLE_COUNT.js";
|
|
3
|
+
import { VGEO_MAX_CLUSTER_VERTEX_COUNT } from "../../format/cluster/VGEO_MAX_CLUSTER_VERTEX_COUNT.js";
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* The 8-bit local index list a cluster payload carries.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"vgeo_build.d.ts","sourceRoot":"","sources":["../../../../../../../src/shade/renderer/geometry/virtual/build/vgeo_build.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"vgeo_build.d.ts","sourceRoot":"","sources":["../../../../../../../src/shade/renderer/geometry/virtual/build/vgeo_build.js"],"names":[],"mappings":"AA4GA;;;;;;;;;;;;;;;;;;GAkBG;AACH,2EAFa,eAAe,CAyE3B;gCA3L+B,sBAAsB"}
|
|
@@ -1,16 +1,17 @@
|
|
|
1
1
|
import { assert } from "../../../../../core/assert.js";
|
|
2
|
+
import { aabb3_array_combine } from "../../../../../core/geom/3d/aabb/aabb3_array_combine.js";
|
|
2
3
|
import { vgeo_attribute_mask } from "../format/attribute/vgeo_attribute_mask.js";
|
|
3
4
|
import { vgeo_write_container } from "../format/vgeo_write_container.js";
|
|
4
5
|
import { VGeoLevelRecord } from "../format/header/VGeoLevelRecord.js";
|
|
5
6
|
import { VGeoWriteOptions } from "../format/VGeoWriteOptions.js";
|
|
6
|
-
import { vgeo_assemble_pages } from "./vgeo_assemble_pages.js";
|
|
7
|
-
import { vgeo_build_levels } from "./vgeo_build_levels.js";
|
|
8
|
-
import { vgeo_build_root_group } from "./vgeo_build_root_group.js";
|
|
9
|
-
import { vgeo_containing_sphere } from "./vgeo_containing_sphere.js";
|
|
10
|
-
import { vgeo_normalize_source } from "./vgeo_normalize_source.js";
|
|
7
|
+
import { vgeo_assemble_pages } from "./page/vgeo_assemble_pages.js";
|
|
8
|
+
import { vgeo_build_levels } from "./level/vgeo_build_levels.js";
|
|
9
|
+
import { vgeo_build_root_group } from "./level/vgeo_build_root_group.js";
|
|
10
|
+
import { vgeo_containing_sphere } from "./sphere/vgeo_containing_sphere.js";
|
|
11
|
+
import { vgeo_normalize_source } from "./mesh/vgeo_normalize_source.js";
|
|
11
12
|
import { VGeoBuildResult } from "./VGeoBuildResult.js";
|
|
12
|
-
import { VGeoLevelSummary } from "./VGeoLevelSummary.js";
|
|
13
|
-
import { VirtualGeometryMesh } from "./VirtualGeometryMesh.js";
|
|
13
|
+
import { VGeoLevelSummary } from "./level/VGeoLevelSummary.js";
|
|
14
|
+
import { VirtualGeometryMesh } from "./mesh/VirtualGeometryMesh.js";
|
|
14
15
|
|
|
15
16
|
/**
|
|
16
17
|
* The whole builder pipeline, from a triangle soup to `.vgeo` bytes.
|
|
@@ -46,10 +47,7 @@ function compute_object_bounds(levels) {
|
|
|
46
47
|
for (const cluster of level.clusters) {
|
|
47
48
|
spheres.push(cluster.bounds_sphere);
|
|
48
49
|
|
|
49
|
-
|
|
50
|
-
bounds[axis] = Math.min(bounds[axis], cluster.aabb[axis]);
|
|
51
|
-
bounds[axis + 3] = Math.max(bounds[axis + 3], cluster.aabb[axis + 3]);
|
|
52
|
-
}
|
|
50
|
+
aabb3_array_combine(bounds, 0, bounds, 0, cluster.aabb, 0);
|
|
53
51
|
}
|
|
54
52
|
}
|
|
55
53
|
|
|
@@ -1,7 +1,13 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Read one vertex's value for one channel, falling back to the format's default for a channel this
|
|
3
|
-
* geometry does not carry
|
|
4
|
-
*
|
|
3
|
+
* geometry does not carry.
|
|
4
|
+
*
|
|
5
|
+
* These are the **unencoded** defaults, for a caller that is going to encode what it reads.
|
|
6
|
+
* `vgeo_encode_cluster_payload` never reaches them: a channel the geometry lacks takes its
|
|
7
|
+
* `ENCODED_DEFAULTS` path instead, which emits Shade's encoded constant directly. The two are not
|
|
8
|
+
* everywhere the same value — colour's encoded default carries an alpha byte that
|
|
9
|
+
* `encode_colors_to_u32` does not write — so which of the two a caller wants is a real question,
|
|
10
|
+
* and the answer is: this one only when the value is about to be encoded from scratch.
|
|
5
11
|
*
|
|
6
12
|
* @param {Float32Array|number[]} target
|
|
7
13
|
* @param {number} target_offset
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"vgeo_attributes_read.d.ts","sourceRoot":"","sources":["../../../../../../../../src/shade/renderer/geometry/virtual/format/attribute/vgeo_attributes_read.js"],"names":[],"mappings":"AAEA
|
|
1
|
+
{"version":3,"file":"vgeo_attributes_read.d.ts","sourceRoot":"","sources":["../../../../../../../../src/shade/renderer/geometry/virtual/format/attribute/vgeo_attributes_read.js"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;;;;GAmBG;AACH,6CATW,YAAY,GAAC,MAAM,EAAE,iBACrB,MAAM,UACN,CAAC,kBAAgB,IAAI,CAAC,EAAE,aACxB,MAAM,UACN,MAAM,QAmBhB"}
|
|
@@ -2,8 +2,14 @@ import { VGEO_ATTRIBUTES } from "./VGEO_ATTRIBUTES.js";
|
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* Read one vertex's value for one channel, falling back to the format's default for a channel this
|
|
5
|
-
* geometry does not carry
|
|
6
|
-
*
|
|
5
|
+
* geometry does not carry.
|
|
6
|
+
*
|
|
7
|
+
* These are the **unencoded** defaults, for a caller that is going to encode what it reads.
|
|
8
|
+
* `vgeo_encode_cluster_payload` never reaches them: a channel the geometry lacks takes its
|
|
9
|
+
* `ENCODED_DEFAULTS` path instead, which emits Shade's encoded constant directly. The two are not
|
|
10
|
+
* everywhere the same value — colour's encoded default carries an alpha byte that
|
|
11
|
+
* `encode_colors_to_u32` does not write — so which of the two a caller wants is a real question,
|
|
12
|
+
* and the answer is: this one only when the value is about to be encoded from scratch.
|
|
7
13
|
*
|
|
8
14
|
* @param {Float32Array|number[]} target
|
|
9
15
|
* @param {number} target_offset
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Group record field offsets, relative to the record's own start.
|
|
3
|
+
*
|
|
4
|
+
* The record is `VGEO_GROUP_RECORD_SIZE` bytes and `VGEO_FORMAT.md` §6.2 is where the layout is
|
|
5
|
+
* stated; this is that statement in code, so the writer, the reader and the audit address the same
|
|
6
|
+
* bytes by the same names rather than each counting them out again.
|
|
7
|
+
*/
|
|
8
|
+
export type VGEO_GROUP_OFFSET = number;
|
|
9
|
+
export namespace VGEO_GROUP_OFFSET {
|
|
10
|
+
let CLUSTER_FIRST: number;
|
|
11
|
+
let CLUSTER_COUNT: number;
|
|
12
|
+
let PARENT_CLUSTER_COUNT: number;
|
|
13
|
+
let PARENT_FIRST: number;
|
|
14
|
+
}
|
|
15
|
+
//# sourceMappingURL=VGEO_GROUP_OFFSET.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"VGEO_GROUP_OFFSET.d.ts","sourceRoot":"","sources":["../../../../../../../../src/shade/renderer/geometry/virtual/format/page/VGEO_GROUP_OFFSET.js"],"names":[],"mappings":";;;;;;;gCAOU,MAAM"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Group record field offsets, relative to the record's own start.
|
|
3
|
+
*
|
|
4
|
+
* The record is `VGEO_GROUP_RECORD_SIZE` bytes and `VGEO_FORMAT.md` §6.2 is where the layout is
|
|
5
|
+
* stated; this is that statement in code, so the writer, the reader and the audit address the same
|
|
6
|
+
* bytes by the same names rather than each counting them out again.
|
|
7
|
+
*
|
|
8
|
+
* @enum {number}
|
|
9
|
+
*/
|
|
10
|
+
export const VGEO_GROUP_OFFSET = {
|
|
11
|
+
CLUSTER_FIRST: 0,
|
|
12
|
+
CLUSTER_COUNT: 2,
|
|
13
|
+
PARENT_CLUSTER_COUNT: 4,
|
|
14
|
+
PARENT_FIRST: 6,
|
|
15
|
+
};
|
|
@@ -7,5 +7,33 @@
|
|
|
7
7
|
* @returns {VGeoEncodedPayload}
|
|
8
8
|
*/
|
|
9
9
|
export function vgeo_encode_cluster_payload(positions: Float32Array, indices: Uint8Array, vertex_ids: Uint32Array, layers: (BinaryDataLayer | null)[]): VGeoEncodedPayload;
|
|
10
|
+
/**
|
|
11
|
+
* Encode one cluster's geometry into a `SHADE_MESHLET_V1` payload: the local index section, then
|
|
12
|
+
* every attribute section in the frozen order, each either one value per vertex or — when every
|
|
13
|
+
* vertex agrees, or the source simply lacks the attribute — a single constant-compressed value.
|
|
14
|
+
*
|
|
15
|
+
* The encoders themselves are Shade's, unmodified. That is the whole point of the encoding's
|
|
16
|
+
* "byte-compatible with the data pool" claim: uploading a payload is a copy, so it has to be the
|
|
17
|
+
* same bits Shade's own encoder would have produced.
|
|
18
|
+
*
|
|
19
|
+
* @author Alex Goldring
|
|
20
|
+
* @copyright Company Named Limited (c) 2026
|
|
21
|
+
*/
|
|
22
|
+
/**
|
|
23
|
+
* The encoded word a section carries when the source lacks the attribute — Shade's
|
|
24
|
+
* `ENCODED_ATTRIBUTE_DEFAULT_VALUES`, in this format's own attribute order, so that a `.vgeo`
|
|
25
|
+
* payload and a `MeshletBatch` payload of the same geometry differ nowhere.
|
|
26
|
+
*
|
|
27
|
+
* Colour's default is opaque white with its alpha byte set, while `encode_colors_to_u32` writes only
|
|
28
|
+
* three channels and leaves alpha zero. That asymmetry is Shade's, and matching it is the point.
|
|
29
|
+
*
|
|
30
|
+
* Exported so that `vgeo_encode_cluster_payload.spec.js` can hold it against Shade's own table
|
|
31
|
+
* rather than against nothing — it is the fourth of the four tables the byte-compatibility claim
|
|
32
|
+
* rests on, and was for a long time the only one no test compared.
|
|
33
|
+
*
|
|
34
|
+
* @readonly
|
|
35
|
+
* @type {number[][]}
|
|
36
|
+
*/
|
|
37
|
+
export const ENCODED_DEFAULTS: number[][];
|
|
10
38
|
import { VGeoEncodedPayload } from "./VGeoEncodedPayload.js";
|
|
11
39
|
//# sourceMappingURL=vgeo_encode_cluster_payload.d.ts.map
|
package/src/shade/renderer/geometry/virtual/format/payload/vgeo_encode_cluster_payload.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"vgeo_encode_cluster_payload.d.ts","sourceRoot":"","sources":["../../../../../../../../src/shade/renderer/geometry/virtual/format/payload/vgeo_encode_cluster_payload.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"vgeo_encode_cluster_payload.d.ts","sourceRoot":"","sources":["../../../../../../../../src/shade/renderer/geometry/virtual/format/payload/vgeo_encode_cluster_payload.js"],"names":[],"mappings":"AAoHA;;;;;;;GAOG;AACH,uDAPW,YAAY,WACZ,UAAU,cACV,WAAW,UACX,CAAC,kBAAgB,IAAI,CAAC,EAAE,GAEtB,kBAAkB,CAiF9B;AA5LD;;;;;;;;;;;GAWG;AAEH;;;;;;;;;;;;;;GAcG;AACH,+BAFU,MAAM,EAAE,EAAE,CAEe;mCA9BA,yBAAyB"}
|
|
@@ -28,16 +28,20 @@ import { VGeoEncodedPayload } from "./VGeoEncodedPayload.js";
|
|
|
28
28
|
|
|
29
29
|
/**
|
|
30
30
|
* The encoded word a section carries when the source lacks the attribute — Shade's
|
|
31
|
-
* `ENCODED_ATTRIBUTE_DEFAULT_VALUES`,
|
|
32
|
-
* payload of the same geometry differ nowhere.
|
|
31
|
+
* `ENCODED_ATTRIBUTE_DEFAULT_VALUES`, in this format's own attribute order, so that a `.vgeo`
|
|
32
|
+
* payload and a `MeshletBatch` payload of the same geometry differ nowhere.
|
|
33
33
|
*
|
|
34
34
|
* Colour's default is opaque white with its alpha byte set, while `encode_colors_to_u32` writes only
|
|
35
35
|
* three channels and leaves alpha zero. That asymmetry is Shade's, and matching it is the point.
|
|
36
36
|
*
|
|
37
|
+
* Exported so that `vgeo_encode_cluster_payload.spec.js` can hold it against Shade's own table
|
|
38
|
+
* rather than against nothing — it is the fourth of the four tables the byte-compatibility claim
|
|
39
|
+
* rests on, and was for a long time the only one no test compared.
|
|
40
|
+
*
|
|
37
41
|
* @readonly
|
|
38
42
|
* @type {number[][]}
|
|
39
43
|
*/
|
|
40
|
-
const ENCODED_DEFAULTS = [];
|
|
44
|
+
export const ENCODED_DEFAULTS = [];
|
|
41
45
|
|
|
42
46
|
{
|
|
43
47
|
const normal = new Uint32Array(1);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"vgeo_read_page.d.ts","sourceRoot":"","sources":["../../../../../../../../src/shade/renderer/geometry/virtual/format/read/vgeo_read_page.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"vgeo_read_page.d.ts","sourceRoot":"","sources":["../../../../../../../../src/shade/renderer/geometry/virtual/format/read/vgeo_read_page.js"],"names":[],"mappings":"AAsCA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,4CAVW,UAAU,cACV,MAAM,GAEJ,QAAQ,CAiFpB;yBAhHwB,eAAe"}
|
|
@@ -10,6 +10,7 @@ import { vgeo_decode_frame_blob } from "../frame/vgeo_decode_frame_blob.js";
|
|
|
10
10
|
import { VGEO_FRAME_HEADER_SIZE } from "../frame/VGEO_FRAME_HEADER_SIZE.js";
|
|
11
11
|
import { VGEO_FRAME_OFFSET } from "../frame/VGEO_FRAME_OFFSET.js";
|
|
12
12
|
import { vgeo_frame_decode_bound } from "../frame/vgeo_frame_decode_bound.js";
|
|
13
|
+
import { VGEO_GROUP_OFFSET } from "../page/VGEO_GROUP_OFFSET.js";
|
|
13
14
|
import { VGEO_GROUP_RECORD_SIZE } from "../page/VGEO_GROUP_RECORD_SIZE.js";
|
|
14
15
|
import { VGEO_METRIC_OFFSET } from "../page/VGEO_METRIC_OFFSET.js";
|
|
15
16
|
import { VGEO_NODE_OFFSET } from "../page/VGEO_NODE_OFFSET.js";
|
|
@@ -298,10 +299,14 @@ function read_group_table(page) {
|
|
|
298
299
|
for (let i = 0; i < count; i++) {
|
|
299
300
|
const record = VGEO_PAGE_HEADER_SIZE + i * VGEO_GROUP_RECORD_SIZE;
|
|
300
301
|
|
|
301
|
-
page.group_cluster_first[i] =
|
|
302
|
-
|
|
303
|
-
page.
|
|
304
|
-
|
|
302
|
+
page.group_cluster_first[i] =
|
|
303
|
+
data.getUint16(record + VGEO_GROUP_OFFSET.CLUSTER_FIRST, LE);
|
|
304
|
+
page.group_cluster_count[i] =
|
|
305
|
+
data.getUint16(record + VGEO_GROUP_OFFSET.CLUSTER_COUNT, LE);
|
|
306
|
+
page.group_parent_count[i] =
|
|
307
|
+
data.getUint16(record + VGEO_GROUP_OFFSET.PARENT_CLUSTER_COUNT, LE);
|
|
308
|
+
page.group_parent_first[i] =
|
|
309
|
+
data.getUint16(record + VGEO_GROUP_OFFSET.PARENT_FIRST, LE);
|
|
305
310
|
}
|
|
306
311
|
}
|
|
307
312
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"vgeo_validate_container.d.ts","sourceRoot":"","sources":["../../../../../../../src/shade/renderer/geometry/virtual/format/vgeo_validate_container.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"vgeo_validate_container.d.ts","sourceRoot":"","sources":["../../../../../../../src/shade/renderer/geometry/virtual/format/vgeo_validate_container.js"],"names":[],"mappings":"AA6tDA;;;;;GAKG;AACH,gDAHW,YAAY,GACV,UAAU,EAAE,CAqFxB;6BAtzD4B,4CAA4C;2BAmD9C,iBAAiB"}
|
|
@@ -20,6 +20,7 @@ import { VGEO_FRAME_ALIGNMENT } from "./frame/VGEO_FRAME_ALIGNMENT.js";
|
|
|
20
20
|
import { vgeo_frame_decode_bound } from "./frame/vgeo_frame_decode_bound.js";
|
|
21
21
|
import { VGEO_FRAME_HEADER_SIZE } from "./frame/VGEO_FRAME_HEADER_SIZE.js";
|
|
22
22
|
import { VGEO_FRAME_OFFSET } from "./frame/VGEO_FRAME_OFFSET.js";
|
|
23
|
+
import { VGEO_GROUP_OFFSET } from "./page/VGEO_GROUP_OFFSET.js";
|
|
23
24
|
import { VGEO_GROUP_RECORD_SIZE } from "./page/VGEO_GROUP_RECORD_SIZE.js";
|
|
24
25
|
import { VGEO_HASH_ALGO_XXH3 } from "./header/VGEO_HASH_ALGO_XXH3.js";
|
|
25
26
|
import { VGEO_HEADER_OFFSET } from "./header/VGEO_HEADER_OFFSET.js";
|
|
@@ -1071,13 +1072,25 @@ function read_groups(page, out) {
|
|
|
1071
1072
|
let expected_parent_first = 0;
|
|
1072
1073
|
|
|
1073
1074
|
for (let g = 0; g < page.group_count; g++) {
|
|
1074
|
-
|
|
1075
|
+
const record = VGEO_PAGE_HEADER_SIZE + g * VGEO_GROUP_RECORD_SIZE;
|
|
1076
|
+
|
|
1077
|
+
/**
|
|
1078
|
+
* Each field is sought to by name rather than read in a run, so that this audit and
|
|
1079
|
+
* `vgeo_read_page` address the record through the same table — a validator that agreed
|
|
1080
|
+
* with the reader only by having been written in the same order is a validator that stops
|
|
1081
|
+
* agreeing the first time a field moves.
|
|
1082
|
+
*/
|
|
1083
|
+
const read = (field) => {
|
|
1084
|
+
page.seek(record + field);
|
|
1085
|
+
|
|
1086
|
+
return buffer.readUint16();
|
|
1087
|
+
};
|
|
1075
1088
|
|
|
1076
1089
|
const group = {
|
|
1077
|
-
cluster_first:
|
|
1078
|
-
cluster_count:
|
|
1079
|
-
parent_cluster_count:
|
|
1080
|
-
parent_first:
|
|
1090
|
+
cluster_first: read(VGEO_GROUP_OFFSET.CLUSTER_FIRST),
|
|
1091
|
+
cluster_count: read(VGEO_GROUP_OFFSET.CLUSTER_COUNT),
|
|
1092
|
+
parent_cluster_count: read(VGEO_GROUP_OFFSET.PARENT_CLUSTER_COUNT),
|
|
1093
|
+
parent_first: read(VGEO_GROUP_OFFSET.PARENT_FIRST),
|
|
1081
1094
|
};
|
|
1082
1095
|
|
|
1083
1096
|
if (group.cluster_count < 1 || group.cluster_count > VGEO_MAX_GROUP_CLUSTER_COUNT) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"vgeo_write_container.d.ts","sourceRoot":"","sources":["../../../../../../../src/shade/renderer/geometry/virtual/format/vgeo_write_container.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"vgeo_write_container.d.ts","sourceRoot":"","sources":["../../../../../../../src/shade/renderer/geometry/virtual/format/vgeo_write_container.js"],"names":[],"mappings":"AAocA;;;;;;;;GAQG;AACH,4CANW,qBAAqB,8BAGnB,YAAY,CAmNxB;6BA5pB4B,4CAA4C"}
|
|
@@ -17,6 +17,7 @@ import { VGEO_FORMAT_VERSION } from "./header/VGEO_FORMAT_VERSION.js";
|
|
|
17
17
|
import { VGEO_FRAME_ALIGNMENT } from "./frame/VGEO_FRAME_ALIGNMENT.js";
|
|
18
18
|
import { VGEO_FRAME_HEADER_SIZE } from "./frame/VGEO_FRAME_HEADER_SIZE.js";
|
|
19
19
|
import { VGEO_FRAME_OFFSET } from "./frame/VGEO_FRAME_OFFSET.js";
|
|
20
|
+
import { VGEO_GROUP_OFFSET } from "./page/VGEO_GROUP_OFFSET.js";
|
|
20
21
|
import { VGEO_GROUP_RECORD_SIZE } from "./page/VGEO_GROUP_RECORD_SIZE.js";
|
|
21
22
|
import { VGEO_HASH_ALGO_XXH3 } from "./header/VGEO_HASH_ALGO_XXH3.js";
|
|
22
23
|
import { VGEO_HEADER_OFFSET } from "./header/VGEO_HEADER_OFFSET.js";
|
|
@@ -355,11 +356,18 @@ function build_page_blob(page, child_pages, parents) {
|
|
|
355
356
|
buffer.writeUint16(parent.cluster);
|
|
356
357
|
});
|
|
357
358
|
|
|
358
|
-
|
|
359
|
+
const group_record = VGEO_PAGE_HEADER_SIZE + group_index * VGEO_GROUP_RECORD_SIZE;
|
|
359
360
|
|
|
361
|
+
buffer.position = group_record + VGEO_GROUP_OFFSET.CLUSTER_FIRST;
|
|
360
362
|
buffer.writeUint16(cluster_index);
|
|
363
|
+
|
|
364
|
+
buffer.position = group_record + VGEO_GROUP_OFFSET.CLUSTER_COUNT;
|
|
361
365
|
buffer.writeUint16(group.clusters.length);
|
|
366
|
+
|
|
367
|
+
buffer.position = group_record + VGEO_GROUP_OFFSET.PARENT_CLUSTER_COUNT;
|
|
362
368
|
buffer.writeUint16(group.parent_cluster_count);
|
|
369
|
+
|
|
370
|
+
buffer.position = group_record + VGEO_GROUP_OFFSET.PARENT_FIRST;
|
|
363
371
|
buffer.writeUint16(parent_first);
|
|
364
372
|
|
|
365
373
|
parent_first += group_parents.length;
|
|
@@ -435,7 +435,7 @@ the view-dependent half, with the same eviction hooks.
|
|
|
435
435
|
another site already moved.
|
|
436
436
|
|
|
437
437
|
**There are not two sites — and that is a defect, not a shape to design around.** The
|
|
438
|
-
phase-one seam call sits *inside* the
|
|
438
|
+
phase-one seam call sits *inside* the per-opaque-bucket loop of
|
|
439
439
|
`graph_rasterize_partial_opaque`, so a standard view records one cut per **active opaque bucket**
|
|
440
440
|
plus one for phase two. The engine already says so where rev 2 did not read it —
|
|
441
441
|
`GPUVirtualGeometryRuntime`: "once per bucket per HZB pass per view".
|
|
@@ -518,7 +518,26 @@ the view-dependent half, with the same eviction hooks.
|
|
|
518
518
|
checks instead of asking an asset its version — and `GENERATION`. `slot_range` learned the
|
|
519
519
|
section, or the parent rows would never have been uploaded. Still nothing consumes them.
|
|
520
520
|
|
|
521
|
-
**A verification surface went away mid-session
|
|
521
|
+
**A verification surface went away mid-session and came back — steps 1–6 are confirmed in a
|
|
522
|
+
real browser.** Chrome's regression was worked around on master (`b3919f9c3`, `34c836d4d`:
|
|
523
|
+
the four indirectly dispatched culls, and then particles and SHARC, off immediates and onto a
|
|
524
|
+
uniform), and with that in place the `vgeo_runtime` playground draws again. Re-measured
|
|
525
|
+
against it afterwards:
|
|
526
|
+
|
|
527
|
+
- the in-page container, now written at `format_version` 4 with parent tables, builds, loads
|
|
528
|
+
and draws, and the cut shaders — the coarsen path and the tenth binding included — compile
|
|
529
|
+
under Tint with no console error;
|
|
530
|
+
- the deepest converted Zorah container, which is **`format_version` 3 and carries no parent
|
|
531
|
+
tables at all**, loads and draws under the format-4 reader at every camera tried. That is
|
|
532
|
+
§2.1's back-compatibility claim tested rather than argued, on 27.9M faces;
|
|
533
|
+
- §7.1's table reproduces exactly: `descent_steps` 32 takes 5 dispatches and 16 takes 6, both
|
|
534
|
+
with `QUEUE_REMAINING` 0, while 8 takes all 8 and leaves 12–124 items queued. The default
|
|
535
|
+
of 24 sits inside the clean band.
|
|
536
|
+
|
|
537
|
+
What follows is the note written while it was broken, kept because the diagnosis is what
|
|
538
|
+
makes the gap in the record legible:
|
|
539
|
+
|
|
540
|
+
**A verification surface went away mid-session, and §7.5 needed it.** The `vgeo_runtime`
|
|
522
541
|
playground draws nothing in headless Chrome: `begin_frame` runs, the feedback resource is open,
|
|
523
542
|
the adapter is an NVIDIA Lovelace with subgroups, the container builds and its root page installs
|
|
524
543
|
with a selectable group — and `VGEO_CUT_STAT.PAGES` stays 0, so the seed never reaches its first
|
|
@@ -29,18 +29,21 @@ export class GPUVirtualGeometryRuntime {
|
|
|
29
29
|
* @param {number} [options.claim_word_capacity] words of the per-invocation claim bitmask,
|
|
30
30
|
* overriding the derivation below
|
|
31
31
|
* @param {number} [options.queue_capacity] traversal items one wavefront may hold
|
|
32
|
-
* @param {number} [options.max_iterations] wavefronts before the descent is abandoned
|
|
32
|
+
* @param {number} [options.max_iterations] wavefronts before the descent is abandoned, to start
|
|
33
|
+
* with; the runtime raises it from what the cut reports
|
|
34
|
+
* @param {number} [options.max_iteration_ceiling] as far as that raising may go
|
|
33
35
|
* @param {number} [options.descent_steps] steps of the descent one traversal dispatch runs
|
|
34
36
|
* before handing back what it still holds; see the traversal kernel for why it cannot
|
|
35
37
|
* simply stop when the wave runs dry
|
|
36
38
|
*/
|
|
37
|
-
constructor({ pool, want_capacity, visible_instance_hint, claim_word_capacity, queue_capacity, max_iterations, descent_steps, }: {
|
|
39
|
+
constructor({ pool, want_capacity, visible_instance_hint, claim_word_capacity, queue_capacity, max_iterations, max_iteration_ceiling, descent_steps, }: {
|
|
38
40
|
pool: GPUVirtualGeometryPool;
|
|
39
41
|
want_capacity?: number;
|
|
40
42
|
visible_instance_hint?: number;
|
|
41
43
|
claim_word_capacity?: number;
|
|
42
44
|
queue_capacity?: number;
|
|
43
45
|
max_iterations?: number;
|
|
46
|
+
max_iteration_ceiling?: number;
|
|
44
47
|
descent_steps?: number;
|
|
45
48
|
});
|
|
46
49
|
/**
|
|
@@ -71,9 +74,56 @@ export class GPUVirtualGeometryRuntime {
|
|
|
71
74
|
*/
|
|
72
75
|
get claim_word_capacity(): number;
|
|
73
76
|
/**
|
|
77
|
+
* Wavefronts the descent may run, as the runtime currently understands this scene.
|
|
78
|
+
*
|
|
79
|
+
* A **high-water mark**, not a setting: it starts where the host put it and is raised by
|
|
80
|
+
* {@link note_incomplete_descent} from what the cut reports. `graph_vgeo_expand_instances_to_meshlets`
|
|
81
|
+
* reads it while it is recording passes, so a rise lands on the next frame.
|
|
82
|
+
*
|
|
74
83
|
* @returns {number}
|
|
75
84
|
*/
|
|
76
85
|
get max_iterations(): number;
|
|
86
|
+
/**
|
|
87
|
+
* Times the bound has been raised. Zero for the whole life of almost every scene; a small
|
|
88
|
+
* number, once, for one that needed more than it was given.
|
|
89
|
+
*
|
|
90
|
+
* @returns {number}
|
|
91
|
+
*/
|
|
92
|
+
get iteration_escalations(): number;
|
|
93
|
+
/**
|
|
94
|
+
* @returns {number}
|
|
95
|
+
*/
|
|
96
|
+
get iteration_ceiling(): number;
|
|
97
|
+
/**
|
|
98
|
+
* A reading saying the descent stopped with work still queued — raise the bound and keep it
|
|
99
|
+
* raised.
|
|
100
|
+
*
|
|
101
|
+
* **This is the only place the engine can learn it.** How many wavefronts a cut needs is a
|
|
102
|
+
* function of the frontier's *breadth*, which is a function of the scene, the viewpoint and the
|
|
103
|
+
* render target together; the kernel cannot know it before it runs and the host cannot know it
|
|
104
|
+
* at all. So the bound is guessed low, and the one reading that says the guess was wrong —
|
|
105
|
+
* `VGEO_CUT_STAT.QUEUE_REMAINING`, non-zero exactly when items were abandoned — pays for
|
|
106
|
+
* correcting it. It is the same shape as the rasterizer's meshlet counts, which cannot be known
|
|
107
|
+
* before the expansion runs either and are grown from what the frame reported.
|
|
108
|
+
*
|
|
109
|
+
* **Doubling, because the reading does not say how much more was needed.** A remainder is a
|
|
110
|
+
* count of *items*, and what they cost in wavefronts depends on how they spill; there is no
|
|
111
|
+
* ratio to convert one into the other. So it goes up by a factor until it drains, which is at
|
|
112
|
+
* most three steps from 8 to the ceiling.
|
|
113
|
+
*
|
|
114
|
+
* **Never lowered.** A frame that drained is evidence about that frame, not that the scene got
|
|
115
|
+
* smaller — and a bound that fell back would re-learn the same lesson every time the camera
|
|
116
|
+
* turned away and back, at a hole a time. An unused wavefront is an empty indirect dispatch,
|
|
117
|
+
* which is the cheap side of that trade.
|
|
118
|
+
*
|
|
119
|
+
* What it costs when it is wrong is bounded by the readback: the cut is capped at two readings
|
|
120
|
+
* in flight and skips frames when saturated, so the scene draws with a hole for the few frames
|
|
121
|
+
* between the first truncated descent and the reading that reports it — and then never again.
|
|
122
|
+
*
|
|
123
|
+
* @param {number} remaining items the descent still held when it was abandoned
|
|
124
|
+
* @returns {boolean} whether the bound moved
|
|
125
|
+
*/
|
|
126
|
+
note_incomplete_descent(remaining: number): boolean;
|
|
77
127
|
/**
|
|
78
128
|
* Settable, like tau, and for the same reason: it is a quality-of-schedule dial whose right
|
|
79
129
|
* value is a property of the asset's depth and the scene's breadth together rather than of the
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"GPUVirtualGeometryRuntime.d.ts","sourceRoot":"","sources":["../../../../../../../src/shade/renderer/geometry/virtual/runtime/GPUVirtualGeometryRuntime.js"],"names":[],"mappings":"AAKA;;;GAGG;AAEH;;;;;;;;;;;;;;;;GAgBG;AACH;
|
|
1
|
+
{"version":3,"file":"GPUVirtualGeometryRuntime.d.ts","sourceRoot":"","sources":["../../../../../../../src/shade/renderer/geometry/virtual/runtime/GPUVirtualGeometryRuntime.js"],"names":[],"mappings":"AAKA;;;GAGG;AAEH;;;;;;;;;;;;;;;;GAgBG;AACH;IAkFI;;;;;;;;;;;;;;;OAeG;IACH;QAd2C,IAAI,EAApC,sBAAsB;QACL,aAAa,GAA9B,MAAM;QACW,qBAAqB,GAAtC,MAAM;QAEW,mBAAmB,GAApC,MAAM;QAEW,cAAc,GAA/B,MAAM;QACW,cAAc,GAA/B,MAAM;QAEW,qBAAqB,GAAtC,MAAM;QACW,aAAa,GAA9B,MAAM;OAkFhB;IApID;;;OAGG;IACH,KAFU,MAAM,CAER;IAER;;OAEG;IACH,cAFU,OAAO,CAEG;IA6HpB;;OAEG;IACH,yEAEC;IAED;;;;OAIG;IACH,4BAEC;IAED;;OAEG;IACH,6BAEC;IAED;;OAEG;IACH,kCAEC;IAED;;;;;;;;OAQG;IACH,6BAEC;IAED;;;;;OAKG;IACH,oCAEC;IAED;;OAEG;IACH,gCAEC;IAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;OA4BG;IACH,mCAHW,MAAM,GACJ,OAAO,CAanB;IAWD;;;;;;OAMG;IACH,iCAKC;IArBD;;;;OAIG;IACH,4BAEC;IAgBD;;;OAGG;IACH,uBAEC;IAED;;;;;;;;;;;;;;OAcG;IACH,yBAHW,MAAM,GACJ,IAAI,CAMhB;IAED;;OAEG;IACH;;QAvUA;;WAEG;;;4BAIH;;WAEG;MAiUF;IAED;;;;;;;;;;;;;;;;;;;;;;;OAuBG;IACH;QAH+B,KAAK,EAAzB,UAAU;QACR,MAAM,CA+BlB;IAED;;;;;;;;;;;;;;;;;OAiBG;IACH;QAJ2B,iBAAiB,EAAjC,MAAM;QACU,gBAAgB,EAAhC,MAAM;QACJ,IAAI,CAahB;IAED;;OAEG;IACH,gCAEC;IAED;;OAEG;IACH,+BAEC;IAED;;;;;;;;;;OAUG;IACH,wGAEC;IAGD;;;;;OAKG;IACH,aAFa,IAAI,CAKhB;;CACJ;qCAteY,OAAO,6BAA6B,EAAE,sBAAsB;yBAC5D,OAAO,iEAAiE,EAAE,UAAU"}
|
|
@@ -54,6 +54,16 @@ export class GPUVirtualGeometryRuntime {
|
|
|
54
54
|
*/
|
|
55
55
|
#max_iterations;
|
|
56
56
|
|
|
57
|
+
/**
|
|
58
|
+
* @type {number}
|
|
59
|
+
*/
|
|
60
|
+
#iteration_ceiling;
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* @type {number}
|
|
64
|
+
*/
|
|
65
|
+
#iteration_escalations = 0;
|
|
66
|
+
|
|
57
67
|
/**
|
|
58
68
|
* @type {number}
|
|
59
69
|
*/
|
|
@@ -106,7 +116,9 @@ export class GPUVirtualGeometryRuntime {
|
|
|
106
116
|
* @param {number} [options.claim_word_capacity] words of the per-invocation claim bitmask,
|
|
107
117
|
* overriding the derivation below
|
|
108
118
|
* @param {number} [options.queue_capacity] traversal items one wavefront may hold
|
|
109
|
-
* @param {number} [options.max_iterations] wavefronts before the descent is abandoned
|
|
119
|
+
* @param {number} [options.max_iterations] wavefronts before the descent is abandoned, to start
|
|
120
|
+
* with; the runtime raises it from what the cut reports
|
|
121
|
+
* @param {number} [options.max_iteration_ceiling] as far as that raising may go
|
|
110
122
|
* @param {number} [options.descent_steps] steps of the descent one traversal dispatch runs
|
|
111
123
|
* before handing back what it still holds; see the traversal kernel for why it cannot
|
|
112
124
|
* simply stop when the wave runs dry
|
|
@@ -140,7 +152,25 @@ export class GPUVirtualGeometryRuntime {
|
|
|
140
152
|
with work outstanding, which is the one degradation that costs a hole.
|
|
141
153
|
*/
|
|
142
154
|
queue_capacity = 1 << 16,
|
|
155
|
+
/*
|
|
156
|
+
Where the wavefront bound *starts*. It is raised by the runtime itself when a
|
|
157
|
+
reading says the descent could not finish — see {@link note_incomplete_descent}
|
|
158
|
+
— so this is the cost a scene pays until it has been told otherwise rather than
|
|
159
|
+
a limit anyone has to get right in advance.
|
|
160
|
+
|
|
161
|
+
Eight is what almost every cut needs: one container at a modest viewport drains
|
|
162
|
+
in six. A converted scene at 3441×1440 does not, and nothing on the host can
|
|
163
|
+
know that before the kernel has run.
|
|
164
|
+
*/
|
|
143
165
|
max_iterations = 8,
|
|
166
|
+
/*
|
|
167
|
+
And where it stops. A frontier that genuinely cannot be drained inside any
|
|
168
|
+
budget would otherwise climb until the frame graph is nothing but empty
|
|
169
|
+
dispatches; a hole is the better failure, because it is visible and
|
|
170
|
+
`QUEUE_REMAINING` goes on reporting it. Measured peak need on the scene that
|
|
171
|
+
found this was 12 to 13.
|
|
172
|
+
*/
|
|
173
|
+
max_iteration_ceiling = 64,
|
|
144
174
|
/*
|
|
145
175
|
Steps of the in-kernel descent one dispatch runs, and the knob that is *not*
|
|
146
176
|
the safety bound — `max_iterations` is, and lowering this spends it. A wave
|
|
@@ -167,6 +197,7 @@ export class GPUVirtualGeometryRuntime {
|
|
|
167
197
|
this.#claim_word_capacity = claim_word_capacity;
|
|
168
198
|
this.#queue_capacity = queue_capacity;
|
|
169
199
|
this.#max_iterations = max_iterations;
|
|
200
|
+
this.#iteration_ceiling = Math.max(max_iterations, max_iteration_ceiling);
|
|
170
201
|
this.#descent_steps = descent_steps;
|
|
171
202
|
|
|
172
203
|
|
|
@@ -203,12 +234,77 @@ export class GPUVirtualGeometryRuntime {
|
|
|
203
234
|
}
|
|
204
235
|
|
|
205
236
|
/**
|
|
237
|
+
* Wavefronts the descent may run, as the runtime currently understands this scene.
|
|
238
|
+
*
|
|
239
|
+
* A **high-water mark**, not a setting: it starts where the host put it and is raised by
|
|
240
|
+
* {@link note_incomplete_descent} from what the cut reports. `graph_vgeo_expand_instances_to_meshlets`
|
|
241
|
+
* reads it while it is recording passes, so a rise lands on the next frame.
|
|
242
|
+
*
|
|
206
243
|
* @returns {number}
|
|
207
244
|
*/
|
|
208
245
|
get max_iterations() {
|
|
209
246
|
return this.#max_iterations;
|
|
210
247
|
}
|
|
211
248
|
|
|
249
|
+
/**
|
|
250
|
+
* Times the bound has been raised. Zero for the whole life of almost every scene; a small
|
|
251
|
+
* number, once, for one that needed more than it was given.
|
|
252
|
+
*
|
|
253
|
+
* @returns {number}
|
|
254
|
+
*/
|
|
255
|
+
get iteration_escalations() {
|
|
256
|
+
return this.#iteration_escalations;
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
/**
|
|
260
|
+
* @returns {number}
|
|
261
|
+
*/
|
|
262
|
+
get iteration_ceiling() {
|
|
263
|
+
return this.#iteration_ceiling;
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
/**
|
|
267
|
+
* A reading saying the descent stopped with work still queued — raise the bound and keep it
|
|
268
|
+
* raised.
|
|
269
|
+
*
|
|
270
|
+
* **This is the only place the engine can learn it.** How many wavefronts a cut needs is a
|
|
271
|
+
* function of the frontier's *breadth*, which is a function of the scene, the viewpoint and the
|
|
272
|
+
* render target together; the kernel cannot know it before it runs and the host cannot know it
|
|
273
|
+
* at all. So the bound is guessed low, and the one reading that says the guess was wrong —
|
|
274
|
+
* `VGEO_CUT_STAT.QUEUE_REMAINING`, non-zero exactly when items were abandoned — pays for
|
|
275
|
+
* correcting it. It is the same shape as the rasterizer's meshlet counts, which cannot be known
|
|
276
|
+
* before the expansion runs either and are grown from what the frame reported.
|
|
277
|
+
*
|
|
278
|
+
* **Doubling, because the reading does not say how much more was needed.** A remainder is a
|
|
279
|
+
* count of *items*, and what they cost in wavefronts depends on how they spill; there is no
|
|
280
|
+
* ratio to convert one into the other. So it goes up by a factor until it drains, which is at
|
|
281
|
+
* most three steps from 8 to the ceiling.
|
|
282
|
+
*
|
|
283
|
+
* **Never lowered.** A frame that drained is evidence about that frame, not that the scene got
|
|
284
|
+
* smaller — and a bound that fell back would re-learn the same lesson every time the camera
|
|
285
|
+
* turned away and back, at a hole a time. An unused wavefront is an empty indirect dispatch,
|
|
286
|
+
* which is the cheap side of that trade.
|
|
287
|
+
*
|
|
288
|
+
* What it costs when it is wrong is bounded by the readback: the cut is capped at two readings
|
|
289
|
+
* in flight and skips frames when saturated, so the scene draws with a hole for the few frames
|
|
290
|
+
* between the first truncated descent and the reading that reports it — and then never again.
|
|
291
|
+
*
|
|
292
|
+
* @param {number} remaining items the descent still held when it was abandoned
|
|
293
|
+
* @returns {boolean} whether the bound moved
|
|
294
|
+
*/
|
|
295
|
+
note_incomplete_descent(remaining) {
|
|
296
|
+
assert.isNonNegativeInteger(remaining, 'remaining');
|
|
297
|
+
|
|
298
|
+
if (remaining === 0 || this.#max_iterations >= this.#iteration_ceiling) {
|
|
299
|
+
return false;
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
this.#max_iterations = Math.min(this.#max_iterations * 2, this.#iteration_ceiling);
|
|
303
|
+
this.#iteration_escalations++;
|
|
304
|
+
|
|
305
|
+
return true;
|
|
306
|
+
}
|
|
307
|
+
|
|
212
308
|
/**
|
|
213
309
|
* Steps of the descent one traversal dispatch runs.
|
|
214
310
|
*
|