@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
|
@@ -64,8 +64,42 @@ export const NODE3D_STRUCT = WebGPUStruct.from({
|
|
|
64
64
|
* terminates when it sees this value.
|
|
65
65
|
*/
|
|
66
66
|
parent: u32,
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Properties of `global` that are cheaper to carry than to re-derive
|
|
70
|
+
* per vertex and per pixel — see {@link NODE3D_GLOBAL_FLAG_MIRRORED}.
|
|
71
|
+
*
|
|
72
|
+
* Not an independent field: it is part of how `global` is
|
|
73
|
+
* represented, and whoever writes one writes the other.
|
|
74
|
+
* `scene_write_node_global` is the only publisher and writes both, so
|
|
75
|
+
* the two cannot drift.
|
|
76
|
+
*
|
|
77
|
+
* Free, as it happens — the packed record was 176 bytes with the
|
|
78
|
+
* padding this word now occupies, and is 176 bytes with it.
|
|
79
|
+
*/
|
|
80
|
+
global_flags: u32,
|
|
67
81
|
}).pack();
|
|
68
82
|
|
|
83
|
+
/**
|
|
84
|
+
* `global` reflects: the determinant of its linear part is negative,
|
|
85
|
+
* because an odd number of negative scale axes appears somewhere in the
|
|
86
|
+
* chain that composed it.
|
|
87
|
+
*
|
|
88
|
+
* Two consequences, and the renderer has to act on both. Every triangle
|
|
89
|
+
* drawn under the node comes out of the vertex shader wound backwards,
|
|
90
|
+
* so fixed-function front-face determination culls exactly the faces
|
|
91
|
+
* pointing at the camera unless the draw reverses them. And the node's
|
|
92
|
+
* tangent frame changes handedness, so a bitangent reconstructed as
|
|
93
|
+
* `cross(N, T) * w` needs the other `w`.
|
|
94
|
+
*
|
|
95
|
+
* A node is not necessarily a mesh — bones, empties and particle
|
|
96
|
+
* emitters have rows in the same table — so this says nothing about
|
|
97
|
+
* geometry, only about the transform.
|
|
98
|
+
*
|
|
99
|
+
* @type {number}
|
|
100
|
+
*/
|
|
101
|
+
export const NODE3D_GLOBAL_FLAG_MIRRORED = 1;
|
|
102
|
+
|
|
69
103
|
/**
|
|
70
104
|
* Reserved row id for the scene root in the GPU `transforms` table.
|
|
71
105
|
*
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Readers for {@link NODE3D_STRUCT}'s `global_flags`. Every consumer of the encoding goes through
|
|
3
|
+
* here rather than masking the word itself.
|
|
4
|
+
*
|
|
5
|
+
* @type {CodeChunk}
|
|
6
|
+
*/
|
|
7
|
+
export const chunk_node3d_flags: CodeChunk;
|
|
8
|
+
import { CodeChunk } from "../shader/compiler/CodeChunk.js";
|
|
9
|
+
//# sourceMappingURL=chunk_node3d_flags.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"chunk_node3d_flags.d.ts","sourceRoot":"","sources":["../../../../../src/shade/renderer/scene/chunk_node3d_flags.js"],"names":[],"mappings":"AAGA;;;;;GAKG;AACH,iCAFU,SAAS,CAeb;0BAtBoB,iCAAiC"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { CodeChunk } from "../shader/compiler/CodeChunk.js";
|
|
2
|
+
import { NODE3D_GLOBAL_FLAG_MIRRORED, NODE3D_STRUCT } from "./NODE3D_STRUCT.js";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Readers for {@link NODE3D_STRUCT}'s `global_flags`. Every consumer of the encoding goes through
|
|
6
|
+
* here rather than masking the word itself.
|
|
7
|
+
*
|
|
8
|
+
* @type {CodeChunk}
|
|
9
|
+
*/
|
|
10
|
+
export const chunk_node3d_flags = CodeChunk.from(
|
|
11
|
+
//language=WGSL
|
|
12
|
+
`
|
|
13
|
+
/**
|
|
14
|
+
* Whether the node's world transform reflects — an odd number of negative scale axes anywhere in
|
|
15
|
+
* its ancestry. Triangles drawn under it come out wound backwards unless the draw reverses them,
|
|
16
|
+
* and its tangent frame changes handedness.
|
|
17
|
+
*/
|
|
18
|
+
fn node3d_global_is_mirrored( node: ${NODE3D_STRUCT.wgsl_ref} ) -> bool{
|
|
19
|
+
return ( node.global_flags & ${NODE3D_GLOBAL_FLAG_MIRRORED}u ) != 0u;
|
|
20
|
+
}
|
|
21
|
+
`, [
|
|
22
|
+
NODE3D_STRUCT.declaration_chunk,
|
|
23
|
+
])
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"chunk_scene_database_access.d.ts","sourceRoot":"","sources":["../../../../../src/shade/renderer/scene/chunk_scene_database_access.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"chunk_scene_database_access.d.ts","sourceRoot":"","sources":["../../../../../src/shade/renderer/scene/chunk_scene_database_access.js"],"names":[],"mappings":"AAQA;;;;;GAKG;AACH,wGAA8D;AAC9D,4GAAsE;AAEtE;;;;;;;GAOG;AACH,0CAFU,SAAS,CAqBZ;AAEP;;;;;;;;;;;;;;GAcG;AACH,6CAFU,SAAS,CAiHZ;0BAzKmB,iCAAiC"}
|
|
@@ -1,6 +1,9 @@
|
|
|
1
|
+
import {
|
|
2
|
+
chunk_mat4_linear_determinant
|
|
3
|
+
} from "../shader/chunk/geometry/mat4/chunk_mat4_linear_determinant.js";
|
|
1
4
|
import { CodeChunk } from "../shader/compiler/CodeChunk.js";
|
|
2
5
|
import { MESH_INSTANCE_METADATA_STRUCT } from "./MESH_INSTANCE_METADATA_STRUCT.js";
|
|
3
|
-
import { NODE3D_STRUCT } from "./NODE3D_STRUCT.js";
|
|
6
|
+
import { NODE3D_GLOBAL_FLAG_MIRRORED, NODE3D_STRUCT } from "./NODE3D_STRUCT.js";
|
|
4
7
|
import { SCENE_DATABASE_SPEC } from "./SCENE_DATABASE_SPEC.js";
|
|
5
8
|
|
|
6
9
|
/**
|
|
@@ -113,12 +116,21 @@ fn scene_write_node_local_scale(
|
|
|
113
116
|
${TRANSFORMS_TABLE.marshalling_method_write_field('local_scale')}(database, node_id, value);
|
|
114
117
|
}
|
|
115
118
|
|
|
119
|
+
/**
|
|
120
|
+
* Publishes a node's world transform. Writes \`global_flags\` from the same matrix — the flags are
|
|
121
|
+
* part of how \`global\` is represented, not a field of their own, and deriving them here is what
|
|
122
|
+
* stops a caller from publishing one without the other.
|
|
123
|
+
*/
|
|
116
124
|
fn scene_write_node_global(
|
|
117
125
|
database: ptr<storage, array<u32>, read_write>,
|
|
118
126
|
node_id: u32,
|
|
119
127
|
value: mat4x4<f32>,
|
|
120
128
|
) {
|
|
121
129
|
${TRANSFORMS_TABLE.marshalling_method_write_field('global')}(database, node_id, value);
|
|
130
|
+
|
|
131
|
+
let flags = select(0u, ${NODE3D_GLOBAL_FLAG_MIRRORED}u, mat4_linear_determinant(value) < 0.0);
|
|
132
|
+
|
|
133
|
+
${TRANSFORMS_TABLE.marshalling_method_write_field('global_flags')}(database, node_id, flags);
|
|
122
134
|
}
|
|
123
135
|
|
|
124
136
|
fn scene_write_node_prev_global(
|
|
@@ -153,7 +165,9 @@ fn scene_write_mesh_bounding_sphere(
|
|
|
153
165
|
TRANSFORMS_TABLE.wgsl_gen_write_field_code('local_rotation'),
|
|
154
166
|
TRANSFORMS_TABLE.wgsl_gen_write_field_code('local_scale'),
|
|
155
167
|
TRANSFORMS_TABLE.wgsl_gen_write_field_code('global'),
|
|
168
|
+
TRANSFORMS_TABLE.wgsl_gen_write_field_code('global_flags'),
|
|
156
169
|
TRANSFORMS_TABLE.wgsl_gen_write_field_code('prev_global'),
|
|
170
|
+
chunk_mat4_linear_determinant,
|
|
157
171
|
MESHES_TABLE.wgsl_gen_write_field_code('bounding_box'),
|
|
158
172
|
MESHES_TABLE.wgsl_gen_write_field_code('bounding_sphere'),
|
|
159
173
|
]);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"GPUSceneRows.d.ts","sourceRoot":"","sources":["../../../../../../src/shade/renderer/scene/rows/GPUSceneRows.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"GPUSceneRows.d.ts","sourceRoot":"","sources":["../../../../../../src/shade/renderer/scene/rows/GPUSceneRows.js"],"names":[],"mappings":"AAaA;;;;;;;;;;GAUG;AAEH;;;;;;;;;GASG;AACH,sCAHW,MAAM,GACJ,MAAM,CAIlB;AAED;;;;;;GAMG;AACH,mCAHW,MAAM,GACJ,MAAM,CAIlB;AAoID;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH;IA2II;;;;;;;;;OASG;IACH;QAR2C,OAAO,EAAvC,sBAAsB;QACC,UAAU;QACV,MAAM;QACD,UAAU,EAAtC,kBAAkB;QACU,SAAS,EAArC,kBAAkB;QACyB,IAAI,EAA/C,iCAAiC;QACW,QAAQ,QAAxC,sBAAsB;OAmB5C;IAED;;OAEG;IACH,iGAEC;IAED;;;;;OAKG;IACH,gCAEC;IAED;;;;;OAKG;IACH,YAHW,MAAM,GACJ,OAAO,CAInB;IAED;;;;;OAKG;IACH,iBAHW,MAAM,GACJ,OAAO,CAInB;IAED;;;;;;;OAOG;IACH,8BAHoB,MAAM,QAAE,eAAe,QAAE,aAAa,QAAE,OAAO,KAAG,IAAI,QASzE;IAED;;;;;;;;;OASG;IACH,6BAHW,KAAK,GACH,OAAO,CAyBnB;IAED;;;;;;;;;;OAUG;IACH,gBAFW,MAAM,QAuChB;IAED;;;;;;;;OAQG;IACH,gBAFW,MAAM,QA0BhB;IAED;;;;OAIG;IACH,mBAFW,MAAM,QAIhB;IAED;;;;;OAKG;IACH,mBAFW,MAAM,QAIhB;IAED;;;;;OAKG;IACH,2EAOC;IAED;;;;OAIG;IACH,gCAEC;IAqCD;;;;;;;;;;;;;;OAcG;IACH,oBALW,MAAM,YACN,eAAe,YACf,aAAa,YACb,OAAO,QAgDjB;IAED;;;;;OAKG;IACH,oBAFW,MAAM,QAUhB;IAsCD;;;;OAIG;IACH,SAFa,MAAM,CAsDlB;IAyMD;;;;OAIG;IACH;;;;;;;;OAQG;IACH,4BAHW,MAAM,kBACG,MAAM,KAAG,IAAI,QAiBhC;IAyGD;;OAEG;IACH,gBA+BC;;CACJ;qCA/nCY,OAAO,kDAAkD,EAAE,sBAAsB;;iCAEjF,OAAO,sCAAsC,EAAE,kBAAkB;iCACjE,OAAO,sCAAsC,EAAE,kBAAkB;gDACjE,OAAO,yCAAyC,EAAE,iCAAiC;qCACnF,OAAO,oDAAoD,EAAE,sBAAsB;8BACnF,OAAO,mCAAmC,EAAE,eAAe;4BAC3D,OAAO,iCAAiC,EAAE,aAAa;oBACvD,OAAO,wCAAwC,EAAE,KAAK"}
|
|
@@ -4,10 +4,11 @@ import { GPUStateAuthority } from "../../../../engine/ecs/gpu/GPUStateAuthority.
|
|
|
4
4
|
import { GPUStateAuthorityFlags } from "../../../../engine/ecs/gpu/GPUStateAuthorityFlags.js";
|
|
5
5
|
import { TransformAttachment } from "../../../../engine/ecs/transform-attachment/TransformAttachment.js";
|
|
6
6
|
import { aabb3_matrix4_project } from "../../../../core/geom/3d/aabb/aabb3_matrix4_project.js";
|
|
7
|
+
import { m4_linear_determinant } from "../../../../core/geom/3d/mat4/m4_linear_determinant.js";
|
|
7
8
|
import { Transform64 } from "../../../../engine/ecs/transform/Transform64.js";
|
|
8
9
|
import { generate_record_writer } from "../../buffer/table/serde/generate_record_writer.js";
|
|
9
10
|
import { MESH_INSTANCE_METADATA_STRUCT } from "../MESH_INSTANCE_METADATA_STRUCT.js";
|
|
10
|
-
import { NODE3D_SCENE_ID, NODE3D_STRUCT } from "../NODE3D_STRUCT.js";
|
|
11
|
+
import { NODE3D_GLOBAL_FLAG_MIRRORED, NODE3D_SCENE_ID, NODE3D_STRUCT } from "../NODE3D_STRUCT.js";
|
|
11
12
|
import { TransparencyMode } from "../../material/TransparencyMode.js";
|
|
12
13
|
|
|
13
14
|
/**
|
|
@@ -66,6 +67,7 @@ const TRANSFORM_RECORD = {
|
|
|
66
67
|
global: new Float32Array(16),
|
|
67
68
|
prev_global: new Float32Array(16),
|
|
68
69
|
parent: NODE3D_SCENE_ID,
|
|
70
|
+
global_flags: 0,
|
|
69
71
|
};
|
|
70
72
|
|
|
71
73
|
/**
|
|
@@ -962,6 +964,12 @@ export class GPUSceneRows {
|
|
|
962
964
|
TRANSFORM_RECORD.prev_global[i] = world[i];
|
|
963
965
|
}
|
|
964
966
|
|
|
967
|
+
// seeded alongside `global`, exactly as the hierarchy pass derives it when it recomposes
|
|
968
|
+
// the row next tick — a row that reflects has to read as reflecting on its first frame too
|
|
969
|
+
TRANSFORM_RECORD.global_flags = m4_linear_determinant(world) < 0
|
|
970
|
+
? NODE3D_GLOBAL_FLAG_MIRRORED
|
|
971
|
+
: 0;
|
|
972
|
+
|
|
965
973
|
return TRANSFORM_RECORD;
|
|
966
974
|
}
|
|
967
975
|
|
package/src/shade/renderer/shader/chunk/geometry/mat4/chunk_compute_normal_matrix_from_m4.d.ts
CHANGED
|
@@ -1,6 +1,13 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* This is the transpose adjugate method of computing the normal matrix from a 4x4 matrix
|
|
3
3
|
* Note that the matrix will produce scaled vectors, so you need to normalize them afterward.
|
|
4
|
+
*
|
|
5
|
+
* The adjugate transpose is `det(M) * M^-T`, so under a reflection it points every normal *into*
|
|
6
|
+
* the surface rather than out of it — the one case where the determinant's magnitude being
|
|
7
|
+
* irrelevant does not make its sign irrelevant too. Re-orienting by that sign is what keeps a
|
|
8
|
+
* mirrored instance's shading normal, tangent and geometric normal agreeing with each other and
|
|
9
|
+
* with the winding the rasterizer sees.
|
|
10
|
+
*
|
|
4
11
|
* @source Eric Lengyel, "Transforming Normals", 2024: https://terathon.com/blog/transforming-normals.html
|
|
5
12
|
* @source Ken Turkowski, "Properties of Surface Normal Transformations" (Graphics Gems, 1990)
|
|
6
13
|
* @type {CodeChunk}
|
package/src/shade/renderer/shader/chunk/geometry/mat4/chunk_compute_normal_matrix_from_m4.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"chunk_compute_normal_matrix_from_m4.d.ts","sourceRoot":"","sources":["../../../../../../../../src/shade/renderer/shader/chunk/geometry/mat4/chunk_compute_normal_matrix_from_m4.js"],"names":[],"mappings":"AAEA
|
|
1
|
+
{"version":3,"file":"chunk_compute_normal_matrix_from_m4.d.ts","sourceRoot":"","sources":["../../../../../../../../src/shade/renderer/shader/chunk/geometry/mat4/chunk_compute_normal_matrix_from_m4.js"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;GAaG;AACH,kDAFU,SAAS,CAsBjB;0BApCwB,gCAAgC"}
|
package/src/shade/renderer/shader/chunk/geometry/mat4/chunk_compute_normal_matrix_from_m4.js
CHANGED
|
@@ -3,6 +3,13 @@ import { CodeChunk } from "../../../compiler/CodeChunk.js";
|
|
|
3
3
|
/**
|
|
4
4
|
* This is the transpose adjugate method of computing the normal matrix from a 4x4 matrix
|
|
5
5
|
* Note that the matrix will produce scaled vectors, so you need to normalize them afterward.
|
|
6
|
+
*
|
|
7
|
+
* The adjugate transpose is `det(M) * M^-T`, so under a reflection it points every normal *into*
|
|
8
|
+
* the surface rather than out of it — the one case where the determinant's magnitude being
|
|
9
|
+
* irrelevant does not make its sign irrelevant too. Re-orienting by that sign is what keeps a
|
|
10
|
+
* mirrored instance's shading normal, tangent and geometric normal agreeing with each other and
|
|
11
|
+
* with the winding the rasterizer sees.
|
|
12
|
+
*
|
|
6
13
|
* @source Eric Lengyel, "Transforming Normals", 2024: https://terathon.com/blog/transforming-normals.html
|
|
7
14
|
* @source Ken Turkowski, "Properties of Surface Normal Transformations" (Graphics Gems, 1990)
|
|
8
15
|
* @type {CodeChunk}
|
|
@@ -14,11 +21,16 @@ fn compute_normal_matrix_from_m4( m: mat4x4<f32> ) -> mat3x3<f32>{
|
|
|
14
21
|
let c0 = m[0].xyz;
|
|
15
22
|
let c1 = m[1].xyz;
|
|
16
23
|
let c2 = m[2].xyz;
|
|
17
|
-
|
|
24
|
+
|
|
25
|
+
let cofactor_0 = cross(c1, c2);
|
|
26
|
+
|
|
27
|
+
// dot(c0, cross(c1, c2)) is the determinant, and the cross is already in hand
|
|
28
|
+
let orientation = select(1.0, -1.0, dot(c0, cofactor_0) < 0.0);
|
|
29
|
+
|
|
18
30
|
return mat3x3<f32>(
|
|
19
|
-
|
|
20
|
-
cross(c2, c0),
|
|
21
|
-
cross(c0, c1)
|
|
31
|
+
cofactor_0 * orientation,
|
|
32
|
+
cross(c2, c0) * orientation,
|
|
33
|
+
cross(c0, c1) * orientation
|
|
22
34
|
);
|
|
23
35
|
}
|
|
24
36
|
`, [
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Determinant of the linear (upper-left 3x3) part of a 4x4 transform. WGSL twin of
|
|
3
|
+
* {@link m4_linear_determinant} — keep the two in step.
|
|
4
|
+
*
|
|
5
|
+
* Negative exactly when the transform reflects, which is what reverses triangle winding and
|
|
6
|
+
* tangent-frame handedness under it.
|
|
7
|
+
*
|
|
8
|
+
* @type {CodeChunk}
|
|
9
|
+
*/
|
|
10
|
+
export const chunk_mat4_linear_determinant: CodeChunk;
|
|
11
|
+
import { CodeChunk } from "../../../compiler/CodeChunk.js";
|
|
12
|
+
//# sourceMappingURL=chunk_mat4_linear_determinant.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"chunk_mat4_linear_determinant.d.ts","sourceRoot":"","sources":["../../../../../../../../src/shade/renderer/shader/chunk/geometry/mat4/chunk_mat4_linear_determinant.js"],"names":[],"mappings":"AAEA;;;;;;;;GAQG;AACH,4CAFU,SAAS,CAQb;0BAjBoB,gCAAgC"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { CodeChunk } from "../../../compiler/CodeChunk.js";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Determinant of the linear (upper-left 3x3) part of a 4x4 transform. WGSL twin of
|
|
5
|
+
* {@link m4_linear_determinant} — keep the two in step.
|
|
6
|
+
*
|
|
7
|
+
* Negative exactly when the transform reflects, which is what reverses triangle winding and
|
|
8
|
+
* tangent-frame handedness under it.
|
|
9
|
+
*
|
|
10
|
+
* @type {CodeChunk}
|
|
11
|
+
*/
|
|
12
|
+
export const chunk_mat4_linear_determinant = CodeChunk.from(
|
|
13
|
+
//language=WGSL
|
|
14
|
+
`
|
|
15
|
+
fn mat4_linear_determinant( m: mat4x4<f32> ) -> f32{
|
|
16
|
+
return dot( m[0].xyz, cross( m[1].xyz, m[2].xyz ) );
|
|
17
|
+
}
|
|
18
|
+
`, [])
|
package/src/shade/renderer/shader/chunk/geometry/triangle/chunk_triangle_list_reverse_winding.d.ts
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Programmable winding for a non-indexed `triangle-list` draw.
|
|
3
|
+
*
|
|
4
|
+
* Maps a `@builtin(vertex_index)` to the one that puts the same three vertices on the rasterizer
|
|
5
|
+
* in the opposite order: corners `0,1,2` of a triangle become `2,1,0`. That is an odd permutation,
|
|
6
|
+
* so the emitted winding reverses, and it is the only thing needed to make a reflected instance
|
|
7
|
+
* face the right way — front-face determination is fixed-function and reads screen-space winding
|
|
8
|
+
* alone, and WebGPU has no per-draw `frontFace` state to reach it with.
|
|
9
|
+
*
|
|
10
|
+
* Only the order changes: the same three vertices are emitted, so coverage (the fill rule is
|
|
11
|
+
* defined on the triangle's interior, not its vertex order), depth, and barycentric interpolation
|
|
12
|
+
* are all untouched. `flat` varyings are safe as long as they are constant across the triangle,
|
|
13
|
+
* which for a visibility buffer's mesh/triangle ids they are.
|
|
14
|
+
*
|
|
15
|
+
* Safe to apply to the raw builtin, before any clamp or bounds guard: a meshlet's padding vertices
|
|
16
|
+
* begin at `primitive_count * 3`, always a corner-0 boundary, so the permutation maps each padding
|
|
17
|
+
* triple onto itself and can never move a padding vertex into range or a real one out of it.
|
|
18
|
+
*
|
|
19
|
+
* @see chunk_node3d_flags for where the `reverse` bit comes from
|
|
20
|
+
* @type {CodeChunk}
|
|
21
|
+
*/
|
|
22
|
+
export const chunk_triangle_list_reverse_winding: CodeChunk;
|
|
23
|
+
import { CodeChunk } from "../../../compiler/CodeChunk.js";
|
|
24
|
+
//# sourceMappingURL=chunk_triangle_list_reverse_winding.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"chunk_triangle_list_reverse_winding.d.ts","sourceRoot":"","sources":["../../../../../../../../src/shade/renderer/shader/chunk/geometry/triangle/chunk_triangle_list_reverse_winding.js"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,kDAFU,SAAS,CAWb;0BAhCoB,gCAAgC"}
|
package/src/shade/renderer/shader/chunk/geometry/triangle/chunk_triangle_list_reverse_winding.js
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { CodeChunk } from "../../../compiler/CodeChunk.js";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Programmable winding for a non-indexed `triangle-list` draw.
|
|
5
|
+
*
|
|
6
|
+
* Maps a `@builtin(vertex_index)` to the one that puts the same three vertices on the rasterizer
|
|
7
|
+
* in the opposite order: corners `0,1,2` of a triangle become `2,1,0`. That is an odd permutation,
|
|
8
|
+
* so the emitted winding reverses, and it is the only thing needed to make a reflected instance
|
|
9
|
+
* face the right way — front-face determination is fixed-function and reads screen-space winding
|
|
10
|
+
* alone, and WebGPU has no per-draw `frontFace` state to reach it with.
|
|
11
|
+
*
|
|
12
|
+
* Only the order changes: the same three vertices are emitted, so coverage (the fill rule is
|
|
13
|
+
* defined on the triangle's interior, not its vertex order), depth, and barycentric interpolation
|
|
14
|
+
* are all untouched. `flat` varyings are safe as long as they are constant across the triangle,
|
|
15
|
+
* which for a visibility buffer's mesh/triangle ids they are.
|
|
16
|
+
*
|
|
17
|
+
* Safe to apply to the raw builtin, before any clamp or bounds guard: a meshlet's padding vertices
|
|
18
|
+
* begin at `primitive_count * 3`, always a corner-0 boundary, so the permutation maps each padding
|
|
19
|
+
* triple onto itself and can never move a padding vertex into range or a real one out of it.
|
|
20
|
+
*
|
|
21
|
+
* @see chunk_node3d_flags for where the `reverse` bit comes from
|
|
22
|
+
* @type {CodeChunk}
|
|
23
|
+
*/
|
|
24
|
+
export const chunk_triangle_list_reverse_winding = CodeChunk.from(
|
|
25
|
+
//language=WGSL
|
|
26
|
+
`
|
|
27
|
+
fn triangle_list_reverse_winding( draw_index: u32, reverse: bool ) -> u32{
|
|
28
|
+
// corner 0 -> +2, corner 1 -> +0, corner 2 -> -2
|
|
29
|
+
let reversed = draw_index + 2u - ( draw_index % 3u ) * 2u;
|
|
30
|
+
|
|
31
|
+
return select( draw_index, reversed, reverse );
|
|
32
|
+
}
|
|
33
|
+
`, [])
|
|
@@ -1,150 +0,0 @@
|
|
|
1
|
-
# `.vgeo` viewer
|
|
2
|
-
|
|
3
|
-
An interactive viewer for the virtual-geometry container. Run the dev server and open it:
|
|
4
|
-
|
|
5
|
-
```bash
|
|
6
|
-
npm run dev --workspace @woosh/meep-engine
|
|
7
|
-
```
|
|
8
|
-
|
|
9
|
-
<http://localhost:5173/src/shade/playground/vgeo_viewer/index.html>
|
|
10
|
-
|
|
11
|
-
Nothing loads by itself. **Drop a `.vgeo` anywhere on the page**, pass `?file=/data/models/….vgeo`
|
|
12
|
-
to open one by URL — which is what makes a particular view of a particular asset a bookmark — or
|
|
13
|
-
press **build a sample asset**, which runs the builder in the page over a torus and opens the
|
|
14
|
-
container it produces. `?sample` does the last one on load.
|
|
15
|
-
|
|
16
|
-
## What is on screen
|
|
17
|
-
|
|
18
|
-
Not the asset — the **cut**: the clusters the container's own metric selects for where the camera is
|
|
19
|
-
standing, coloured so the seams between them are visible, with the cluster count on screen.
|
|
20
|
-
|
|
21
|
-
**The cut is frozen until you ask for a new one.** *Adapt to view* re-runs the traversal at wherever
|
|
22
|
-
the camera is now; everything after that is you flying around a decision taken from somewhere else,
|
|
23
|
-
which is the only way to see what a cut actually selected. *Follow the camera* makes it chase
|
|
24
|
-
instead. *tau* is the one quality dial — pixels of permitted error.
|
|
25
|
-
|
|
26
|
-
Drawing goes through Shade's direct geometry path (a `DynamicMesh` from raw attributes, no meshlet
|
|
27
|
-
encode) because a cut is rebuilt from scratch on every adapt, and it is drawn opaque so the depth
|
|
28
|
-
buffer orders its own triangles.
|
|
29
|
-
|
|
30
|
-
## What makes it a streaming viewer
|
|
31
|
-
|
|
32
|
-
The reader under it never holds the whole file. Opening a container reads the header, the level
|
|
33
|
-
table and the root frame — `VGEO_FORMAT.md` §10's always-resident set, two range requests — and
|
|
34
|
-
after that a page arrives only because a traversal asked for it, from exactly the byte range the
|
|
35
|
-
page pointing at it wrote down.
|
|
36
|
-
|
|
37
|
-
So a cut can be taken before the file has finished arriving, and this is the interesting part: it is
|
|
38
|
-
**clamped, not wrong**. Where the page holding a refinement is missing, the coarser cluster is drawn
|
|
39
|
-
and a *want* is recorded, and the surface is watertight either way.
|
|
40
|
-
|
|
41
|
-
"Missing" there means §10's *selectable*, not merely resident: a group is refined into only once
|
|
42
|
-
every page holding one of its parents is here. A group's parents are made by one simplification step
|
|
43
|
-
but grouped for the next one separately, so an asset of more than a page per band puts some of them
|
|
44
|
-
in different pages — and refining into a group because its own page arrived, while a coarse cluster
|
|
45
|
-
still stands in for a parent that has not, draws both over the same surface. Those clamps carry no
|
|
46
|
-
want, because there is nothing to fetch from a cluster that already has the bytes it points at; the
|
|
47
|
-
panel counts them under *of those, on a parent*.
|
|
48
|
-
|
|
49
|
-
Three controls turn that into something you can watch:
|
|
50
|
-
|
|
51
|
-
| control | what it shows |
|
|
52
|
-
|---|---|
|
|
53
|
-
| **colour by clamp** | amber where the surface is standing in for a page that has not arrived, slate where the cut is the one the file selects |
|
|
54
|
-
| **stream *n* wanted page(s)** | installs eight of them, retakes the cut, repeats — refinement happening in steps rather than in one jump |
|
|
55
|
-
| **evict everything but the root** | back to cold, so it arrives again |
|
|
56
|
-
|
|
57
|
-
The **streaming** panel is the measurement: `read so far` against the file's own size, the request
|
|
58
|
-
count, what the cold start cost, and how many pages are resident. On anything larger than a toy the
|
|
59
|
-
first of those is a small fraction, and that is the whole claim.
|
|
60
|
-
|
|
61
|
-
**head prefix** re-opens the current file from cold under a different one. §10 offers a reader two
|
|
62
|
-
cold starts — the 256-byte header and then one exact range per wanted page, or one speculative
|
|
63
|
-
prefix that brings the head and whatever else it happens to cover — and this is the dial between
|
|
64
|
-
them. Coarse-first layout is what makes the second worth doing: a prefix that overshoots the root
|
|
65
|
-
frame has overshot into the pages the traversal is about to want. Watch `read so far` and `requests`
|
|
66
|
-
move against each other. `?head=<bytes>` sets it on load.
|
|
67
|
-
|
|
68
|
-
**head prefix** on the streaming panel is what is still *held*, and it says `released` for most of a
|
|
69
|
-
session: the reader drops the prefix the first time a read falls outside it, because after the pages
|
|
70
|
-
inside it have installed it is bytes nothing will read — and at a thousand open assets a retained
|
|
71
|
-
256 KiB apiece was a quarter of a gigabyte that neither `resident` nor eviction could see. The
|
|
72
|
-
always-resident set is about 2.4 KB, so the prefix is speculation about the next band and 64 KiB is
|
|
73
|
-
enough of it; the dial is there to watch the trade rather than to tune it.
|
|
74
|
-
|
|
75
|
-
**quarantined** is the other new row, and it is the difference between an asset that is coarse
|
|
76
|
-
because the camera just moved and one that is coarse because a page will never arrive — which look
|
|
77
|
-
identical on screen. A page that fails its retries is quarantined with its reason and is not asked
|
|
78
|
-
for again; the clamped cut keeps its surface correct with a coarser ancestor, indefinitely.
|
|
79
|
-
|
|
80
|
-
`read so far` is cumulative and is allowed past 100%: evicting and re-streaming really does fetch
|
|
81
|
-
those pages again, and the audit really does read every byte.
|
|
82
|
-
|
|
83
|
-
## Validation is optional and off
|
|
84
|
-
|
|
85
|
-
**Validation is off by default and is not a precondition for anything.** It reads the whole file —
|
|
86
|
-
every frame, every checksum, the directory against a full frame scan — which is exactly what an
|
|
87
|
-
incremental reader exists to avoid, and it answers a question about whoever *wrote* the file rather
|
|
88
|
-
than about the view being put on screen. Press **validate the whole file** when that is the
|
|
89
|
-
question, or pass `?validate`.
|
|
90
|
-
|
|
91
|
-
It is not a method on the reader, either. `vgeo_audit_container` and `vgeo_install_all_pages` live in
|
|
92
|
-
`format/read/tool/`, and this viewer calls them as the tool it is — a renderer holding a thousand
|
|
93
|
-
containers must not have either within reach of one of them. The audit takes the file as a single
|
|
94
|
-
`ArrayBuffer`, because every build invariant is a cross-check between two places in it, so it refuses
|
|
95
|
-
above 1 GiB naming the size rather than failing in the allocator.
|
|
96
|
-
|
|
97
|
-
What is *not* optional, because it is the difference between refusing a file and misreading one:
|
|
98
|
-
magic, minimum reader version, payload encoding, hash algorithm, unknown required feature bits,
|
|
99
|
-
unknown codecs, a `decoded_size` outside what the stored bytes could physically produce, and a root
|
|
100
|
-
frame that disagrees with the header about its own size. Those are §4 and §10 reject rules and they
|
|
101
|
-
always run.
|
|
102
|
-
|
|
103
|
-
**verify each frame's checksum** sits between the two. A frame's identity-seeded checksum covers
|
|
104
|
-
only that frame, so it is verified from bytes just fetched, with no extra request and no whole-file
|
|
105
|
-
pass — §10 requires it of a runtime, where a quarantined page is the difference between a coarse
|
|
106
|
-
stand-in and a wrong surface. Off here for the same reason the audit is: hashing every installed
|
|
107
|
-
byte costs something, and a tool looking at a file it just built is not defending against a network.
|
|
108
|
-
It is read per fetch, so ticking it applies to the next page rather than to a reopen. `?verify` sets
|
|
109
|
-
it on load.
|
|
110
|
-
|
|
111
|
-
## What lives where
|
|
112
|
-
|
|
113
|
-
The reader is **not** part of this page. It is `renderer/geometry/virtual/format/read/`, it is the
|
|
114
|
-
shape a runtime would use, and it knows nothing about drawing:
|
|
115
|
-
|
|
116
|
-
| | |
|
|
117
|
-
|---|---|
|
|
118
|
-
| `VGeoByteSource` | a range at a time, over an `ArrayBuffer` or a dropped `Blob` |
|
|
119
|
-
| `vgeo_fetch_byte_source` | the same over HTTP, refusing a `200` where it asked for a range |
|
|
120
|
-
| `vgeo_read_header` | header and level table, with §4's reject rules |
|
|
121
|
-
| `vgeo_read_page` | one fetched frame → one `VGeoPage`; needs nothing else |
|
|
122
|
-
| `VGeoPage` | a page's own bytes and its own cluster/group/child tables |
|
|
123
|
-
| `VGeoContainerReader` | residency: open, install, evict, and the optional audit |
|
|
124
|
-
| `VGeoDirectory` | the auxiliary page directory, for reaching pages no traversal leads to |
|
|
125
|
-
|
|
126
|
-
What belongs to the page is everything above the bytes:
|
|
127
|
-
|
|
128
|
-
| | |
|
|
129
|
-
|---|---|
|
|
130
|
-
| `select_cut.js` | the traversal, the residency clamp, and the wants it records |
|
|
131
|
-
| `cut_geometry.js` | decoding selected clusters into one drawable geometry, and the colour modes |
|
|
132
|
-
| `sample_asset.js` | a container built in the page, so there is something to open |
|
|
133
|
-
| `main.js` | renderer, camera, panel, and the streaming loop |
|
|
134
|
-
|
|
135
|
-
## Driving it from a script
|
|
136
|
-
|
|
137
|
-
Everything is reachable from the console, which is what makes the page verifiable in a headless
|
|
138
|
-
browser rather than by a person watching it:
|
|
139
|
-
|
|
140
|
-
```js
|
|
141
|
-
await __open_sample(); // or __open_url('/data/….vgeo')
|
|
142
|
-
__vgeo.set_auto_stream(false);
|
|
143
|
-
__vgeo.reset_residency(); // back to the root page alone
|
|
144
|
-
__state(); // { resident_pages, bytes_read, clusters, clamped, wants, … }
|
|
145
|
-
await __stream(); // one round of eight pages, then a fresh cut
|
|
146
|
-
await __validate(); // the whole-file audit, as an array of defect strings
|
|
147
|
-
```
|
|
148
|
-
|
|
149
|
-
`__state()` is the one to assert on: `clamped` reaching zero is the cut having converged on what the
|
|
150
|
-
container selects, and it converges to the same numbers whatever order the pages arrived in.
|