@woosh/meep-engine 3.43.0 → 3.45.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/editor/prototypeEditorShell.d.ts.map +1 -1
- package/editor/prototypeEditorShell.js +4 -2
- package/package.json +1 -1
- package/src/core/collection/array/array_sort_insertion_ascending.d.ts +19 -0
- package/src/core/collection/array/array_sort_insertion_ascending.d.ts.map +1 -0
- package/src/core/collection/array/array_sort_insertion_ascending.js +31 -0
- package/src/core/geom/3d/aabb/aabb3_array_round_outward_f32.d.ts +27 -0
- package/src/core/geom/3d/aabb/aabb3_array_round_outward_f32.d.ts.map +1 -0
- package/src/core/geom/3d/aabb/aabb3_array_round_outward_f32.js +39 -0
- package/src/core/geom/3d/aabb/aabb3_from_v3_array.d.ts.map +1 -1
- package/src/core/geom/3d/aabb/aabb3_from_v3_array.js +4 -1
- package/src/core/geom/3d/aabb/aabb3_transform_oriented.d.ts +2 -2
- package/src/core/geom/3d/aabb/aabb3_transform_oriented.d.ts.map +1 -1
- package/src/core/geom/3d/aabb/aabb3_transform_oriented.js +1 -1
- package/src/core/geom/3d/pose/pose3_apply_inverse_point_array.d.ts +21 -0
- package/src/core/geom/3d/pose/pose3_apply_inverse_point_array.d.ts.map +1 -0
- package/src/core/geom/3d/pose/pose3_apply_inverse_point_array.js +36 -0
- package/src/core/geom/3d/pose/pose3_apply_point_array.d.ts +25 -0
- package/src/core/geom/3d/pose/pose3_apply_point_array.d.ts.map +1 -0
- package/src/core/geom/3d/pose/pose3_apply_point_array.js +40 -0
- package/src/core/geom/3d/pose/pose3_compose_array.d.ts +28 -0
- package/src/core/geom/3d/pose/pose3_compose_array.d.ts.map +1 -0
- package/src/core/geom/3d/pose/pose3_compose_array.js +41 -0
- package/src/core/geom/3d/pose/pose3_to_local_array.d.ts +29 -0
- package/src/core/geom/3d/pose/pose3_to_local_array.d.ts.map +1 -0
- package/src/core/geom/3d/pose/pose3_to_local_array.js +42 -0
- package/src/core/geom/3d/quaternion/quat3_clamp_angle_array.d.ts +28 -0
- package/src/core/geom/3d/quaternion/quat3_clamp_angle_array.d.ts.map +1 -0
- package/src/core/geom/3d/quaternion/quat3_clamp_angle_array.js +66 -0
- package/src/core/geom/3d/quaternion/quat3_multiply_conjugate_left_array.d.ts +22 -0
- package/src/core/geom/3d/quaternion/quat3_multiply_conjugate_left_array.d.ts.map +1 -0
- package/src/core/geom/3d/quaternion/quat3_multiply_conjugate_left_array.js +30 -0
- package/src/core/geom/3d/quaternion/quat3_multiply_conjugate_right_array.d.ts +23 -0
- package/src/core/geom/3d/quaternion/quat3_multiply_conjugate_right_array.d.ts.map +1 -0
- package/src/core/geom/3d/quaternion/quat3_multiply_conjugate_right_array.js +31 -0
- package/src/core/geom/3d/triangle/tri3_compute_normal_area_weighted_array.d.ts +26 -0
- package/src/core/geom/3d/triangle/tri3_compute_normal_area_weighted_array.d.ts.map +1 -0
- package/src/core/geom/3d/triangle/tri3_compute_normal_area_weighted_array.js +46 -0
- package/src/core/geom/vec3/v3_distance_array.d.ts +11 -0
- package/src/core/geom/vec3/v3_distance_array.d.ts.map +1 -0
- package/src/core/geom/vec3/v3_distance_array.js +19 -0
- package/src/core/geom/vec3/v3_normalize_array_checked.d.ts +23 -0
- package/src/core/geom/vec3/v3_normalize_array_checked.d.ts.map +1 -0
- package/src/core/geom/vec3/v3_normalize_array_checked.js +49 -0
- package/src/core/geom/vec3/v3_reject_array.d.ts +15 -0
- package/src/core/geom/vec3/v3_reject_array.d.ts.map +1 -0
- package/src/core/geom/vec3/v3_reject_array.js +32 -0
- package/src/core/graph/csr/csr_build_incidence.d.ts +26 -0
- package/src/core/graph/csr/csr_build_incidence.d.ts.map +1 -0
- package/src/core/graph/csr/csr_build_incidence.js +71 -0
- package/src/core/graph/csr/csr_graph_color_greedy.d.ts +25 -0
- package/src/core/graph/csr/csr_graph_color_greedy.d.ts.map +1 -0
- package/src/core/graph/csr/csr_graph_color_greedy.js +83 -0
- package/src/core/graph/csr/csr_graph_validate_coloring.d.ts +15 -0
- package/src/core/graph/csr/csr_graph_validate_coloring.d.ts.map +1 -0
- package/src/core/graph/csr/csr_graph_validate_coloring.js +33 -0
- package/src/core/math/linalg/matrix_symmetric_3x3_solve_ldlt.d.ts +26 -0
- package/src/core/math/linalg/matrix_symmetric_3x3_solve_ldlt.d.ts.map +1 -0
- package/src/core/math/linalg/matrix_symmetric_3x3_solve_ldlt.js +71 -0
- package/src/core/math/max2_exact.d.ts +15 -0
- package/src/core/math/max2_exact.d.ts.map +1 -0
- package/src/core/math/max2_exact.js +30 -0
- package/src/core/math/min2_exact.d.ts +20 -0
- package/src/core/math/min2_exact.d.ts.map +1 -0
- package/src/core/math/min2_exact.js +35 -0
- package/src/engine/Clock.d.ts +15 -0
- package/src/engine/Clock.d.ts.map +1 -1
- package/src/engine/Clock.js +29 -5
- package/src/engine/Engine.d.ts.map +1 -1
- package/src/engine/Engine.js +11 -19
- package/src/engine/ecs/ik/IKGoalSystem.d.ts.map +1 -1
- package/src/engine/ecs/ik/IKGoalSystem.js +3 -19
- package/src/engine/ecs/parent/parent_entity_model_of.d.ts +17 -0
- package/src/engine/ecs/parent/parent_entity_model_of.d.ts.map +1 -0
- package/src/engine/ecs/parent/parent_entity_model_of.js +26 -0
- package/src/engine/ecs/transform/t64_read_pose_array.d.ts +15 -0
- package/src/engine/ecs/transform/t64_read_pose_array.d.ts.map +1 -0
- package/src/engine/ecs/transform/t64_read_pose_array.js +24 -0
- package/src/engine/graphics/ecs/mesh-v2/MeshSkin.d.ts +57 -0
- package/src/engine/graphics/ecs/mesh-v2/MeshSkin.d.ts.map +1 -0
- package/src/engine/graphics/ecs/mesh-v2/MeshSkin.js +84 -0
- package/src/engine/graphics/geometry/geometry_construct_triangle_normal_area_weighted.d.ts +2 -0
- package/src/engine/graphics/geometry/geometry_construct_triangle_normal_area_weighted.d.ts.map +1 -1
- package/src/engine/graphics/geometry/geometry_construct_triangle_normal_area_weighted.js +10 -21
- package/src/engine/graphics3/AnimationGraphSystem.d.ts +28 -13
- package/src/engine/graphics3/AnimationGraphSystem.d.ts.map +1 -1
- package/src/engine/graphics3/AnimationGraphSystem.js +107 -64
- package/src/engine/graphics3/AnimationSystem.d.ts +29 -15
- package/src/engine/graphics3/AnimationSystem.d.ts.map +1 -1
- package/src/engine/graphics3/AnimationSystem.js +112 -61
- package/src/engine/graphics3/MeshSkinSystem.d.ts +56 -0
- package/src/engine/graphics3/MeshSkinSystem.d.ts.map +1 -0
- package/src/engine/graphics3/MeshSkinSystem.js +317 -0
- package/src/engine/graphics3/MeshSystem.d.ts +15 -35
- package/src/engine/graphics3/MeshSystem.d.ts.map +1 -1
- package/src/engine/graphics3/MeshSystem.js +21 -298
- package/src/engine/graphics3/RowChains.d.ts +76 -0
- package/src/engine/graphics3/RowChains.d.ts.map +1 -0
- package/src/engine/graphics3/RowChains.js +347 -0
- package/src/engine/graphics3/ShadedGeometrySystem.d.ts +6 -0
- package/src/engine/graphics3/ShadedGeometrySystem.d.ts.map +1 -1
- package/src/engine/graphics3/ShadedGeometrySystem.js +329 -309
- package/src/engine/graphics3/animation/AnimationClips.d.ts +56 -0
- package/src/engine/graphics3/animation/AnimationClips.d.ts.map +1 -0
- package/src/engine/graphics3/animation/AnimationClips.js +79 -0
- package/src/engine/graphics3/animation/ClipListPlayer.d.ts +13 -14
- package/src/engine/graphics3/animation/ClipListPlayer.d.ts.map +1 -1
- package/src/engine/graphics3/animation/ClipListPlayer.js +262 -263
- package/src/engine/graphics3/animation/write_clip_playback.d.ts +3 -3
- package/src/engine/graphics3/animation/write_clip_playback.js +4 -4
- package/src/engine/graphics3/pose/query_entity_node_world_pose.d.ts +5 -0
- package/src/engine/graphics3/pose/query_entity_node_world_pose.d.ts.map +1 -1
- package/src/engine/graphics3/pose/query_entity_node_world_pose.js +80 -75
- package/src/engine/graphics3/prefab/PrefabInstance.d.ts +4 -24
- package/src/engine/graphics3/prefab/PrefabInstance.d.ts.map +1 -1
- package/src/engine/graphics3/prefab/PrefabInstance.js +60 -80
- package/src/engine/graphics3/prefab/prefab_instantiate.d.ts +16 -3
- package/src/engine/graphics3/prefab/prefab_instantiate.d.ts.map +1 -1
- package/src/engine/graphics3/prefab/prefab_instantiate.js +49 -12
- package/src/engine/graphics3/prefab/prefab_place.d.ts +31 -17
- package/src/engine/graphics3/prefab/prefab_place.d.ts.map +1 -1
- package/src/engine/graphics3/prefab/prefab_place.js +175 -130
- package/src/engine/graphics3/register_clips.d.ts +93 -0
- package/src/engine/graphics3/register_clips.d.ts.map +1 -0
- package/src/engine/graphics3/register_clips.js +166 -0
- package/src/engine/physics/broadphase/compute_fat_world_aabb.d.ts +9 -0
- package/src/engine/physics/broadphase/compute_fat_world_aabb.d.ts.map +1 -1
- package/src/engine/physics/broadphase/compute_fat_world_aabb.js +3 -1
- package/src/engine/physics/cloth/MEASUREMENTS.md +795 -0
- package/src/engine/physics/cloth/PLAN.md +349 -17
- package/src/engine/physics/cloth/build/ClothProxy.d.ts +113 -61
- package/src/engine/physics/cloth/build/ClothProxy.d.ts.map +1 -1
- package/src/engine/physics/cloth/build/ClothProxy.js +142 -77
- package/src/engine/physics/cloth/build/cloth_bind_in_frame.d.ts +44 -0
- package/src/engine/physics/cloth/build/cloth_bind_in_frame.d.ts.map +1 -0
- package/src/engine/physics/cloth/build/cloth_bind_in_frame.js +107 -0
- package/src/engine/physics/cloth/build/cloth_proxy_from_joints.d.ts +43 -30
- package/src/engine/physics/cloth/build/cloth_proxy_from_joints.d.ts.map +1 -1
- package/src/engine/physics/cloth/build/cloth_proxy_from_joints.js +371 -284
- package/src/engine/physics/cloth/build/cloth_proxy_from_mesh.d.ts +62 -0
- package/src/engine/physics/cloth/build/cloth_proxy_from_mesh.d.ts.map +1 -0
- package/src/engine/physics/cloth/build/cloth_proxy_from_mesh.js +275 -0
- package/src/engine/physics/cloth/collider/ClothColliderIndex.d.ts +7 -0
- package/src/engine/physics/cloth/collider/ClothColliderIndex.d.ts.map +1 -1
- package/src/engine/physics/cloth/collider/ClothColliderIndex.js +85 -67
- package/src/engine/physics/cloth/collider/cloth_collider_bounds.d.ts.map +1 -1
- package/src/engine/physics/cloth/collider/cloth_collider_bounds.js +19 -101
- package/src/engine/physics/cloth/collider/cloth_collider_pack.d.ts +2 -5
- package/src/engine/physics/cloth/collider/cloth_collider_pack.d.ts.map +1 -1
- package/src/engine/physics/cloth/collider/cloth_collider_pack.js +7 -15
- package/src/engine/physics/cloth/collider/cloth_collider_sdf.d.ts +1 -1
- package/src/engine/physics/cloth/collider/cloth_collider_sdf.d.ts.map +1 -1
- package/src/engine/physics/cloth/collider/cloth_collider_sdf.js +17 -62
- package/src/engine/physics/cloth/ecs/Cloth.d.ts +17 -9
- package/src/engine/physics/cloth/ecs/Cloth.d.ts.map +1 -1
- package/src/engine/physics/cloth/ecs/Cloth.js +220 -212
- package/src/engine/physics/cloth/ecs/ClothColliderFlags.d.ts +0 -1
- package/src/engine/physics/cloth/ecs/ClothColliderFlags.js +6 -19
- package/src/engine/physics/cloth/ecs/ClothColliderSystem.d.ts +1 -2
- package/src/engine/physics/cloth/ecs/ClothColliderSystem.d.ts.map +1 -1
- package/src/engine/physics/cloth/ecs/ClothColliderSystem.js +3 -12
- package/src/engine/physics/cloth/ecs/ClothDynamicsFlags.js +6 -0
- package/src/engine/physics/cloth/ecs/ClothHold.d.ts +91 -0
- package/src/engine/physics/cloth/ecs/ClothHold.d.ts.map +1 -0
- package/src/engine/physics/cloth/ecs/ClothHold.js +103 -0
- package/src/engine/physics/cloth/ecs/ClothInstance.d.ts +254 -48
- package/src/engine/physics/cloth/ecs/ClothInstance.d.ts.map +1 -1
- package/src/engine/physics/cloth/ecs/ClothInstance.js +277 -47
- package/src/engine/physics/cloth/ecs/ClothPin.d.ts +73 -0
- package/src/engine/physics/cloth/ecs/ClothPin.d.ts.map +1 -0
- package/src/engine/physics/cloth/ecs/ClothPin.js +92 -0
- package/src/engine/physics/cloth/ecs/ClothPinSerializationAdapter.d.ts +36 -0
- package/src/engine/physics/cloth/ecs/ClothPinSerializationAdapter.d.ts.map +1 -0
- package/src/engine/physics/cloth/ecs/ClothPinSerializationAdapter.js +61 -0
- package/src/engine/physics/cloth/ecs/ClothRig.d.ts +23 -17
- package/src/engine/physics/cloth/ecs/ClothRig.d.ts.map +1 -1
- package/src/engine/physics/cloth/ecs/ClothRig.js +29 -27
- package/src/engine/physics/cloth/ecs/ClothSystem.d.ts +12 -14
- package/src/engine/physics/cloth/ecs/ClothSystem.d.ts.map +1 -1
- package/src/engine/physics/cloth/ecs/ClothSystem.js +20 -15
- package/src/engine/physics/cloth/ecs/ClothWorld.d.ts +57 -36
- package/src/engine/physics/cloth/ecs/ClothWorld.d.ts.map +1 -1
- package/src/engine/physics/cloth/ecs/ClothWorld.js +754 -207
- package/src/engine/physics/cloth/ecs/WorkerClothSystem.d.ts +12 -13
- package/src/engine/physics/cloth/ecs/WorkerClothSystem.d.ts.map +1 -1
- package/src/engine/physics/cloth/ecs/WorkerClothSystem.js +20 -14
- package/src/engine/physics/cloth/ecs/cloth_build_rows.d.ts +63 -11
- package/src/engine/physics/cloth/ecs/cloth_build_rows.d.ts.map +1 -1
- package/src/engine/physics/cloth/ecs/cloth_build_rows.js +297 -101
- package/src/engine/physics/cloth/ecs/cloth_dynamics_map.d.ts +9 -7
- package/src/engine/physics/cloth/ecs/cloth_dynamics_map.d.ts.map +1 -1
- package/src/engine/physics/cloth/ecs/cloth_dynamics_map.js +12 -10
- package/src/engine/physics/cloth/ecs/cloth_gather_colliders.d.ts +3 -3
- package/src/engine/physics/cloth/ecs/cloth_gather_colliders.d.ts.map +1 -1
- package/src/engine/physics/cloth/ecs/cloth_gather_colliders.js +60 -120
- package/src/engine/physics/cloth/ecs/cloth_geodesic.d.ts +37 -0
- package/src/engine/physics/cloth/ecs/cloth_geodesic.d.ts.map +1 -0
- package/src/engine/physics/cloth/ecs/cloth_geodesic.js +135 -0
- package/src/engine/physics/cloth/ecs/cloth_holds.d.ts +97 -0
- package/src/engine/physics/cloth/ecs/cloth_holds.d.ts.map +1 -0
- package/src/engine/physics/cloth/ecs/cloth_holds.js +583 -0
- package/src/engine/physics/cloth/ecs/cloth_reconstruct_pose.d.ts +2 -2
- package/src/engine/physics/cloth/ecs/cloth_reconstruct_pose.d.ts.map +1 -1
- package/src/engine/physics/cloth/ecs/cloth_reconstruct_pose.js +168 -51
- package/src/engine/physics/cloth/ecs/cloth_seed_rig.d.ts +17 -22
- package/src/engine/physics/cloth/ecs/cloth_seed_rig.d.ts.map +1 -1
- package/src/engine/physics/cloth/ecs/cloth_seed_rig.js +55 -117
- package/src/engine/physics/cloth/ecs/cloth_seed_subtree.d.ts +21 -6
- package/src/engine/physics/cloth/ecs/cloth_seed_subtree.d.ts.map +1 -1
- package/src/engine/physics/cloth/ecs/cloth_seed_subtree.js +51 -42
- package/src/engine/physics/cloth/ecs/cloth_write_back.d.ts +5 -0
- package/src/engine/physics/cloth/ecs/cloth_write_back.d.ts.map +1 -1
- package/src/engine/physics/cloth/ecs/cloth_write_back.js +62 -50
- package/src/engine/physics/cloth/ecs/cloth_write_back_rig.d.ts.map +1 -1
- package/src/engine/physics/cloth/ecs/cloth_write_back_rig.js +65 -58
- package/src/engine/physics/cloth/playground/cloth_playground_build.d.ts.map +1 -1
- package/src/engine/physics/cloth/playground/cloth_playground_build.js +2 -3
- package/src/engine/physics/cloth/playground/collide_main.js +3 -29
- package/src/engine/physics/cloth/playground/garment_build.d.ts.map +1 -1
- package/src/engine/physics/cloth/playground/garment_build.js +17 -5
- package/src/engine/physics/cloth/playground/garment_main.js +5 -20
- package/src/engine/physics/cloth/playground/main.js +6 -48
- package/src/engine/physics/cloth/playground/rig_build.d.ts.map +1 -1
- package/src/engine/physics/cloth/playground/rig_build.js +302 -296
- package/src/engine/physics/cloth/playground/rig_main.js +947 -955
- package/src/engine/physics/cloth/playground/wind_main.js +8 -7
- package/src/engine/physics/cloth/solver/ClothState.d.ts +45 -7
- package/src/engine/physics/cloth/solver/ClothState.d.ts.map +1 -1
- package/src/engine/physics/cloth/solver/ClothState.js +79 -83
- package/src/engine/physics/cloth/solver/cloth_color_particles.d.ts +10 -8
- package/src/engine/physics/cloth/solver/cloth_color_particles.d.ts.map +1 -1
- package/src/engine/physics/cloth/solver/cloth_color_particles.js +30 -102
- package/src/engine/physics/cloth/solver/cloth_contact_find.d.ts +6 -1
- package/src/engine/physics/cloth/solver/cloth_contact_find.d.ts.map +1 -1
- package/src/engine/physics/cloth/solver/cloth_contact_find.js +9 -3
- package/src/engine/physics/cloth/solver/cloth_hold_line.d.ts +114 -0
- package/src/engine/physics/cloth/solver/cloth_hold_line.d.ts.map +1 -0
- package/src/engine/physics/cloth/solver/cloth_hold_line.js +350 -0
- package/src/engine/physics/cloth/solver/cloth_kinetic_energy.d.ts +21 -0
- package/src/engine/physics/cloth/solver/cloth_kinetic_energy.d.ts.map +1 -0
- package/src/engine/physics/cloth/solver/cloth_kinetic_energy.js +45 -0
- package/src/engine/physics/cloth/solver/cloth_particle_coupling.d.ts +32 -0
- package/src/engine/physics/cloth/solver/cloth_particle_coupling.d.ts.map +1 -0
- package/src/engine/physics/cloth/solver/cloth_particle_coupling.js +133 -0
- package/src/engine/physics/cloth/solver/cloth_particle_of_source.d.ts +16 -0
- package/src/engine/physics/cloth/solver/cloth_particle_of_source.d.ts.map +1 -0
- package/src/engine/physics/cloth/solver/cloth_particle_of_source.js +19 -0
- package/src/engine/physics/cloth/solver/cloth_self_find.d.ts +6 -2
- package/src/engine/physics/cloth/solver/cloth_self_find.d.ts.map +1 -1
- package/src/engine/physics/cloth/solver/cloth_self_find.js +19 -68
- package/src/engine/physics/cloth/solver/cloth_solve_vertex.d.ts.map +1 -1
- package/src/engine/physics/cloth/solver/cloth_solve_vertex.js +30 -65
- package/src/engine/physics/cloth/solver/cloth_solver_constants.d.ts +24 -12
- package/src/engine/physics/cloth/solver/cloth_solver_constants.d.ts.map +1 -1
- package/src/engine/physics/cloth/solver/cloth_solver_constants.js +24 -12
- package/src/engine/physics/cloth/solver/cloth_step.d.ts +16 -0
- package/src/engine/physics/cloth/solver/cloth_step.d.ts.map +1 -1
- package/src/engine/physics/cloth/solver/cloth_step.js +189 -48
- package/src/engine/physics/cloth/solver/cloth_step_instance.d.ts +1 -0
- package/src/engine/physics/cloth/solver/cloth_step_instance.d.ts.map +1 -1
- package/src/engine/physics/cloth/solver/cloth_step_instance.js +12 -6
- package/src/engine/physics/cloth/solver/cloth_stretch_residual.d.ts +21 -0
- package/src/engine/physics/cloth/solver/cloth_stretch_residual.d.ts.map +1 -0
- package/src/engine/physics/cloth/solver/cloth_stretch_residual.js +54 -0
- package/src/engine/physics/cloth/solver/cloth_vertex_accumulator.d.ts +15 -0
- package/src/engine/physics/cloth/solver/cloth_vertex_accumulator.d.ts.map +1 -1
- package/src/engine/physics/cloth/solver/cloth_vertex_accumulator.js +28 -0
- package/src/engine/physics/cloth/solver/cloth_worst_tether_ratio.d.ts +30 -0
- package/src/engine/physics/cloth/solver/cloth_worst_tether_ratio.d.ts.map +1 -0
- package/src/engine/physics/cloth/solver/cloth_worst_tether_ratio.js +56 -0
- package/src/engine/physics/cloth/solver/constraint/cloth_contact_row.d.ts.map +1 -1
- package/src/engine/physics/cloth/solver/constraint/cloth_contact_row.js +3 -17
- package/src/engine/physics/cloth/solver/constraint/cloth_leash_row.d.ts +1 -1
- package/src/engine/physics/cloth/solver/constraint/cloth_leash_row.d.ts.map +1 -1
- package/src/engine/physics/cloth/solver/constraint/cloth_leash_row.js +353 -346
- package/src/engine/physics/cloth/solver/constraint/cloth_self_row.d.ts +7 -5
- package/src/engine/physics/cloth/solver/constraint/cloth_self_row.d.ts.map +1 -1
- package/src/engine/physics/cloth/solver/constraint/cloth_self_row.js +7 -5
- package/src/engine/physics/cloth/wind/ClothFluidWind.d.ts +2 -1
- package/src/engine/physics/cloth/wind/ClothFluidWind.d.ts.map +1 -1
- package/src/engine/physics/cloth/wind/ClothFluidWind.js +7 -25
- package/src/engine/physics/cloth/wind/cloth_sample_air.d.ts +12 -10
- package/src/engine/physics/cloth/wind/cloth_sample_air.d.ts.map +1 -1
- package/src/engine/physics/cloth/wind/cloth_sample_air.js +60 -82
- package/src/engine/physics/ecs/ContactProbeSystem.d.ts.map +1 -1
- package/src/engine/physics/ecs/ContactProbeSystem.js +2 -18
- package/src/engine/physics/ecs/PhysicsSystem.d.ts.map +1 -1
- package/src/engine/physics/ecs/PhysicsSystem.js +9 -50
- package/src/engine/physics/fluid/ecs/FluidObstacleSystem.d.ts +4 -4
- package/src/engine/physics/fluid/ecs/fluid_sample_domain_bounds.d.ts +24 -0
- package/src/engine/physics/fluid/ecs/fluid_sample_domain_bounds.d.ts.map +1 -0
- package/src/engine/physics/fluid/ecs/fluid_sample_domain_bounds.js +42 -0
- package/src/engine/physics/fluid/ecs/fluid_sample_velocity_world_mps.d.ts +25 -0
- package/src/engine/physics/fluid/ecs/fluid_sample_velocity_world_mps.d.ts.map +1 -0
- package/src/engine/physics/fluid/ecs/fluid_sample_velocity_world_mps.js +40 -0
- package/src/engine/physics/inverse_kinematics/frame_fabrik/frame_fabrik_solve.d.ts.map +1 -1
- package/src/engine/physics/inverse_kinematics/frame_fabrik/frame_fabrik_solve.js +40 -90
- package/src/engine/physics/narrowphase/capsule_contacts.d.ts.map +1 -1
- package/src/engine/physics/narrowphase/capsule_contacts.js +3 -5
- package/src/engine/physics/narrowphase/decomposition/mesh_enumerate_triangles.d.ts.map +1 -1
- package/src/engine/physics/narrowphase/decomposition/mesh_enumerate_triangles.js +2 -14
- package/src/engine/physics/narrowphase/hull_sphere_contact.d.ts.map +1 -1
- package/src/engine/physics/narrowphase/hull_sphere_contact.js +2 -5
- package/src/engine/physics/narrowphase/narrowphase_step.d.ts.map +1 -1
- package/src/engine/physics/narrowphase/narrowphase_step.js +13 -32
- package/src/engine/physics/narrowphase/sphere_box_contact.d.ts.map +1 -1
- package/src/engine/physics/narrowphase/sphere_box_contact.js +2 -5
- package/src/engine/simulation/Ticker.d.ts +13 -0
- package/src/engine/simulation/Ticker.d.ts.map +1 -1
- package/src/engine/simulation/Ticker.js +43 -8
- package/src/format/texture/basis/transcode/etc1s_to_astc.d.ts.map +1 -1
- package/src/format/texture/basis/transcode/etc1s_to_astc.js +2 -1
- package/src/shade/RENDERER_CONTRACT.md +8 -2
- package/src/shade/playground/image_decode_bench/main.js +2 -1
- package/src/shade/playground/mesh_row_ceiling/main.js +2 -1
- package/src/shade/playground/skinned_blas_refit/diff_traced_against_rasterized.d.ts.map +1 -1
- package/src/shade/playground/skinned_blas_refit/diff_traced_against_rasterized.js +2 -1
- package/src/shade/playground/skinned_blas_refit/main.d.ts.map +1 -1
- package/src/shade/playground/skinned_blas_refit/main.js +11 -19
- package/src/shade/playground/skinned_blas_refit/place_character.d.ts +6 -3
- package/src/shade/playground/skinned_blas_refit/place_character.d.ts.map +1 -1
- package/src/shade/playground/skinned_blas_refit/place_character.js +90 -90
- package/src/shade/playground/skinned_mesh_soup/main.d.ts.map +1 -1
- package/src/shade/playground/skinned_mesh_soup/main.js +502 -509
- package/src/shade/playground/skinned_mesh_soup/verify_clone_vertices.d.ts.map +1 -1
- package/src/shade/playground/skinned_mesh_soup/verify_clone_vertices.js +2 -1
- package/src/shade/playground/ssr_variance/statistics.d.ts.map +1 -1
- package/src/shade/playground/ssr_variance/statistics.js +2 -1
- package/src/shade/playground/texture_encode/README.md +129 -109
- package/src/shade/playground/texture_encode/main.d.ts.map +1 -1
- package/src/shade/playground/texture_encode/main.js +1431 -1430
- package/src/shade/playground/volumetrics_froxel/measure.d.ts.map +1 -1
- package/src/shade/playground/volumetrics_froxel/measure.js +2 -1
- package/src/shade/renderer/animation/GPUAnimationManager.d.ts +45 -14
- package/src/shade/renderer/animation/GPUAnimationManager.d.ts.map +1 -1
- package/src/shade/renderer/animation/GPUAnimationManager.js +316 -64
- package/src/shade/renderer/animation/skinning/GPUMeshSkinningContext.d.ts +5 -0
- package/src/shade/renderer/animation/skinning/GPUMeshSkinningContext.d.ts.map +1 -1
- package/src/shade/renderer/animation/skinning/GPUMeshSkinningContext.js +11 -1
- package/src/shade/renderer/buffer/table/gpu_database_check_links.d.ts.map +1 -1
- package/src/shade/renderer/buffer/table/gpu_database_check_links.js +2 -1
- package/src/shade/renderer/geometry/BoxGeometry.d.ts +1 -11
- package/src/shade/renderer/geometry/BoxGeometry.d.ts.map +1 -1
- package/src/shade/renderer/geometry/BoxGeometry.js +6 -13
- package/src/shade/renderer/geometry/CapsuleGeometry.d.ts +19 -0
- package/src/shade/renderer/geometry/CapsuleGeometry.d.ts.map +1 -0
- package/src/shade/renderer/geometry/CapsuleGeometry.js +24 -0
- package/src/shade/renderer/geometry/ConeGeometry.d.ts +20 -0
- package/src/shade/renderer/geometry/ConeGeometry.d.ts.map +1 -0
- package/src/shade/renderer/geometry/ConeGeometry.js +33 -0
- package/src/shade/renderer/geometry/CylinderGeometry.d.ts +21 -0
- package/src/shade/renderer/geometry/CylinderGeometry.d.ts.map +1 -0
- package/src/shade/renderer/geometry/CylinderGeometry.js +35 -0
- package/src/shade/renderer/geometry/PlaneGeometry.d.ts +17 -0
- package/src/shade/renderer/geometry/PlaneGeometry.d.ts.map +1 -0
- package/src/shade/renderer/geometry/PlaneGeometry.js +22 -0
- package/src/shade/renderer/geometry/TorusGeometry.d.ts +18 -0
- package/src/shade/renderer/geometry/TorusGeometry.d.ts.map +1 -0
- package/src/shade/renderer/geometry/TorusGeometry.js +23 -0
- package/src/shade/renderer/geometry/UVSphereGeometry.d.ts +21 -0
- package/src/shade/renderer/geometry/UVSphereGeometry.d.ts.map +1 -0
- package/src/shade/renderer/geometry/UVSphereGeometry.js +34 -0
- package/src/shade/renderer/geometry/primitives/make_capsule_geometry.d.ts +19 -0
- package/src/shade/renderer/geometry/primitives/make_capsule_geometry.d.ts.map +1 -0
- package/src/shade/renderer/geometry/primitives/make_capsule_geometry.js +205 -0
- package/src/shade/renderer/geometry/primitives/make_cone_geometry.d.ts +21 -0
- package/src/shade/renderer/geometry/primitives/make_cone_geometry.d.ts.map +1 -0
- package/src/shade/renderer/geometry/primitives/make_cone_geometry.js +36 -0
- package/src/shade/renderer/geometry/primitives/make_cylinder_geometry.d.ts +1 -1
- package/src/shade/renderer/geometry/primitives/make_cylinder_geometry.d.ts.map +1 -1
- package/src/shade/renderer/geometry/primitives/make_cylinder_geometry.js +44 -9
- package/src/shade/renderer/geometry/primitives/make_uv_sphere_geometry.d.ts +20 -0
- package/src/shade/renderer/geometry/primitives/make_uv_sphere_geometry.d.ts.map +1 -0
- package/src/shade/renderer/geometry/primitives/make_uv_sphere_geometry.js +190 -0
- package/src/shade/renderer/geometry/virtual/build/level/vgeo_build_group_step.d.ts.map +1 -1
- package/src/shade/renderer/geometry/virtual/build/level/vgeo_build_group_step.js +3 -2
- package/src/shade/renderer/geometry/virtual/build/level/vgeo_build_leaf_frontier.d.ts.map +1 -1
- package/src/shade/renderer/geometry/virtual/build/level/vgeo_build_leaf_frontier.js +2 -1
- package/src/shade/renderer/geometry/virtual/build/level/vgeo_partition_into_groups.d.ts.map +1 -1
- package/src/shade/renderer/geometry/virtual/build/level/vgeo_partition_into_groups.js +2 -1
- package/src/shade/renderer/geometry/virtual/build/level/vgeo_run_round.d.ts.map +1 -1
- package/src/shade/renderer/geometry/virtual/build/level/vgeo_run_round.js +2 -1
- package/src/shade/renderer/geometry/virtual/build/level/vgeo_try_repack.d.ts.map +1 -1
- package/src/shade/renderer/geometry/virtual/build/level/vgeo_try_repack.js +3 -2
- package/src/shade/renderer/geometry/virtual/build/partition/vgeo_graph_components.d.ts.map +1 -1
- package/src/shade/renderer/geometry/virtual/build/partition/vgeo_graph_components.js +2 -1
- package/src/shade/renderer/geometry/virtual/build/partition/vgeo_split_face_set_packed.d.ts.map +1 -1
- package/src/shade/renderer/geometry/virtual/build/partition/vgeo_split_face_set_packed.js +2 -1
- 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 +3 -2
- package/src/shade/renderer/geometry/virtual/runtime/graph_vgeo_expand_instances_to_meshlets.d.ts.map +1 -1
- package/src/shade/renderer/geometry/virtual/runtime/graph_vgeo_expand_instances_to_meshlets.js +7 -2
- package/src/shade/renderer/gpu_primitive/prefix_sum/v1/graph_prefix_scan_csdldf.d.ts +26 -8
- package/src/shade/renderer/gpu_primitive/prefix_sum/v1/graph_prefix_scan_csdldf.d.ts.map +1 -1
- package/src/shade/renderer/gpu_primitive/prefix_sum/v1/graph_prefix_scan_csdldf.js +56 -39
- package/src/shade/renderer/gpu_primitive/prefix_sum/v1/shader_prefix_scan_csdldf.d.ts +7 -0
- package/src/shade/renderer/gpu_primitive/prefix_sum/v1/shader_prefix_scan_csdldf.d.ts.map +1 -1
- package/src/shade/renderer/gpu_primitive/prefix_sum/v1/shader_prefix_scan_csdldf.js +46 -4
- package/src/shade/renderer/gpu_primitive/prefix_sum/v1/test_prefix_sum.d.ts.map +1 -1
- package/src/shade/renderer/gpu_primitive/prefix_sum/v1/test_prefix_sum.js +4 -2
- package/src/shade/renderer/gpu_primitive/sort/defs.d.ts +2 -2
- package/src/shade/renderer/gpu_primitive/sort/defs.js +79 -79
- package/src/shade/renderer/gpu_primitive/sort/graph_radix_sort.d.ts +1 -1
- package/src/shade/renderer/gpu_primitive/sort/graph_radix_sort.d.ts.map +1 -1
- package/src/shade/renderer/gpu_primitive/sort/graph_radix_sort.js +7 -3
- package/src/shade/renderer/particles/GPUParticleSystem.js +1 -1
- package/src/shade/renderer/particles/coherence/graph_particle_bucket.d.ts +4 -3
- package/src/shade/renderer/particles/coherence/graph_particle_bucket.d.ts.map +1 -1
- package/src/shade/renderer/particles/coherence/graph_particle_bucket.js +200 -194
- package/src/shade/renderer/particles/graph_particles.d.ts.map +1 -1
- package/src/shade/renderer/particles/graph_particles.js +6 -2
- package/src/shade/renderer/particles/optimizer/dag/particle_vector_extract.d.ts.map +1 -1
- package/src/shade/renderer/particles/optimizer/dag/particle_vector_extract.js +3 -2
- package/src/shade/renderer/particles/warmup/graph_particle_warmup.d.ts.map +1 -1
- package/src/shade/renderer/particles/warmup/graph_particle_warmup.js +334 -329
- package/src/shade/renderer/rasterize/bucket/prepare_meshlet_draw_commands_by_material.d.ts.map +1 -1
- package/src/shade/renderer/rasterize/bucket/prepare_meshlet_draw_commands_by_material.js +7 -2
- package/src/shade/renderer/rasterize/expand/mesh/graph_expand_meshes_to_meshlets.d.ts.map +1 -1
- package/src/shade/renderer/rasterize/expand/mesh/graph_expand_meshes_to_meshlets.js +16 -4
- package/src/shade/renderer/texture/COMPRESSED_TEXTURE_PLAN_2026_09_01.md +2444 -2345
- package/src/shade/renderer/texture/encode/chunk_astc_encode_block_4x4_rgb.d.ts.map +1 -1
- package/src/shade/renderer/texture/encode/chunk_astc_encode_block_4x4_rgb.js +312 -310
- package/src/shade/renderer/texture/encode/chunk_bc1_encode_block.d.ts +3 -3
- package/src/shade/renderer/texture/encode/chunk_bc1_encode_block.d.ts.map +1 -1
- package/src/shade/renderer/texture/encode/chunk_bc1_encode_block.js +383 -375
- package/src/shade/renderer/texture/encode/chunk_bc6h_encode_block_mode11.d.ts.map +1 -1
- package/src/shade/renderer/texture/encode/chunk_bc6h_encode_block_mode11.js +349 -346
- package/src/shade/renderer/texture/encode/chunk_bc7_encode_block.d.ts +58 -0
- package/src/shade/renderer/texture/encode/chunk_bc7_encode_block.d.ts.map +1 -0
- package/src/shade/renderer/texture/encode/chunk_bc7_encode_block.js +536 -0
- package/src/shade/renderer/texture/encode/chunk_bc7_encode_block_mode6.d.ts +21 -7
- package/src/shade/renderer/texture/encode/chunk_bc7_encode_block_mode6.d.ts.map +1 -1
- package/src/shade/renderer/texture/encode/chunk_bc7_encode_block_mode6.js +291 -327
- package/src/shade/renderer/texture/encode/chunk_bc7_pack_mode1.d.ts +25 -0
- package/src/shade/renderer/texture/encode/chunk_bc7_pack_mode1.d.ts.map +1 -0
- package/src/shade/renderer/texture/encode/chunk_bc7_pack_mode1.js +99 -0
- package/src/shade/renderer/texture/encode/chunk_bc7_pack_mode6.d.ts +5 -3
- package/src/shade/renderer/texture/encode/chunk_bc7_pack_mode6.d.ts.map +1 -1
- package/src/shade/renderer/texture/encode/chunk_bc7_pack_mode6.js +47 -71
- package/src/shade/renderer/texture/encode/chunk_bc7_partition_2.d.ts +10 -0
- package/src/shade/renderer/texture/encode/chunk_bc7_partition_2.d.ts.map +1 -0
- package/src/shade/renderer/texture/encode/chunk_bc7_partition_2.js +50 -0
- package/src/shade/renderer/texture/encode/shader_texture_encode_bc7.d.ts +4 -5
- package/src/shade/renderer/texture/encode/shader_texture_encode_bc7.d.ts.map +1 -1
- package/src/shade/renderer/texture/encode/shader_texture_encode_bc7.js +7 -8
- package/src/shade/renderer/water/chunk_water_transport.d.ts.map +1 -1
- package/src/shade/renderer/water/chunk_water_transport.js +7 -5
- package/src/shade/renderer/water/medium/GPUWaterBodies.d.ts.map +1 -1
- package/src/shade/renderer/water/medium/GPUWaterBodies.js +8 -2
- package/src/shade/renderer/water/optics/chunk_water_receiver_downwelling.d.ts +3 -2
- package/src/shade/renderer/water/optics/chunk_water_receiver_downwelling.d.ts.map +1 -1
- package/src/shade/renderer/water/optics/chunk_water_receiver_downwelling.js +3 -2
- package/src/shade/renderer/water/shader_water.d.ts.map +1 -1
- package/src/shade/renderer/water/shader_water.js +3 -1
- package/src/shade/renderer/water/surface/GPUWaterSurface.d.ts.map +1 -1
- package/src/shade/renderer/water/surface/GPUWaterSurface.js +3 -1
- package/src/shade/renderer/water/surface/graph_water_tessellation.d.ts.map +1 -1
- package/src/shade/renderer/water/surface/graph_water_tessellation.js +11 -4
- package/src/shade/renderer/water/surface/particles/GPUWaterParticles.d.ts.map +1 -1
- package/src/shade/renderer/water/surface/particles/GPUWaterParticles.js +37 -20
- package/src/shade/wgsl/validate_wgsl_source.d.ts.map +1 -1
- package/src/shade/wgsl/validate_wgsl_source.js +74 -3
- package/src/engine/graphics3/register_instance_animation.d.ts +0 -114
- package/src/engine/graphics3/register_instance_animation.d.ts.map +0 -1
- package/src/engine/graphics3/register_instance_animation.js +0 -201
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Encode sixteen RGBA texels as one BC7 block, in mode 6 or in mode 1 — whichever an estimate says
|
|
3
|
+
* loses less — fitting and writing only that one.
|
|
4
|
+
*
|
|
5
|
+
* **Mode 1 is two lines.** Mode 6 (`chunk_bc7_encode_block_mode6`) puts one line through the
|
|
6
|
+
* block in four channels; a block holding two colour regions, each varying its own way, is two lines
|
|
7
|
+
* that point different ways, and no single line holds both. Mode 1 splits the block by one of BC7's
|
|
8
|
+
* sixty-four two-subset partitions and gives each subset a line of its own: colour only, six bits a
|
|
9
|
+
* channel and a parity bit shared by the subset's two ends, eight levels on each line. It decodes
|
|
10
|
+
* opaque.
|
|
11
|
+
*
|
|
12
|
+
* **Chosen by estimate, not by search.** Each candidate's squared error is predicted from the block's
|
|
13
|
+
* statistics without encoding it — the approach of Geldreich's bc7f — and only the winner is fitted:
|
|
14
|
+
*
|
|
15
|
+
* 1. A line's distance from its texels is the lesser eigenvalues of their scatter about their mean,
|
|
16
|
+
* the trace less the largest. It is read here as the sum of the scatter's principal two-by-two
|
|
17
|
+
* minors over its trace: exact as the line thins, half the truth for a ball, and on Spark.js's
|
|
18
|
+
* twenty report images within 0.02 dB of solving for the eigenvalue, at well under its cost.
|
|
19
|
+
* 2. To that, what quantisation adds: the spread along the line over the squared steps between its
|
|
20
|
+
* levels, by a share calibrated on those images (0.5; flat within 0.01 dB from 0.35 to 0.5), and
|
|
21
|
+
* a term per block for the ends, larger for mode 1's coarser ones (8 and 18; flat from 18 to 25).
|
|
22
|
+
* 3. Mode 1 is estimated at **every** partition. A partition's second subset is the same texels in
|
|
23
|
+
* every invocation, so its sums are taken over exactly those, by a branch that does not diverge,
|
|
24
|
+
* and the first subset's are the block's less the second's. Ranking the partitions by how many
|
|
25
|
+
* texels they put across the block's principal split, and estimating the best four, measured
|
|
26
|
+
* 0.8 dB worse.
|
|
27
|
+
* 4. Mode 1 is charged each texel's distance from opaque in alpha, which keeps it off blocks that
|
|
28
|
+
* are not.
|
|
29
|
+
*
|
|
30
|
+
* Choosing the mode by the estimate rather than by each one's actual error costs 0.12 dB at the
|
|
31
|
+
* estimate's partition; fitting mode 1 at all sixty-four and keeping the best by actual error,
|
|
32
|
+
* sixty-five fits a block, was 0.3 dB better at forty to eighty times the time.
|
|
33
|
+
*
|
|
34
|
+
* **One fit for both modes.** The chosen mode reaches the fit as data — which texels are in the
|
|
35
|
+
* second subset, the levels, the bits an end keeps, whether alpha is held — so a group of
|
|
36
|
+
* invocations holding both modes runs one fit rather than both. Per subset: the principal axis by
|
|
37
|
+
* power iteration, the extreme projections as the ends, one round of least squares with each texel
|
|
38
|
+
* at the weight it projects to; then the parities, rounded to and **scored by the least squares'
|
|
39
|
+
* own quadratic form**: at its optimum the error grows by `aa |d0|² + 2 ab d0·d1 + bb |d1|²` for
|
|
40
|
+
* ends moved by `d0` and `d1`, so no combination needs a pass over the texels — 0.1 dB below scoring
|
|
41
|
+
* each against the decoder's palette, at about two fifths of the fit's time. Then each texel's exact
|
|
42
|
+
* nearest entry, once, and the anchors: texel 0 and the partition's second anchor are stored a bit
|
|
43
|
+
* short, and a subset whose anchor lands in the upper half is written the other way up.
|
|
44
|
+
*
|
|
45
|
+
* **Modes 3 and 7 are not here, by measurement.** Mode 3, two subsets of four levels on eight-bit
|
|
46
|
+
* ends, chosen by the same estimate at mode 1's partition, bought 0.05 dB over the twenty images and
|
|
47
|
+
* nothing on the graphic ones; mode 7 is mode 3 with alpha, and those images are opaque. A block
|
|
48
|
+
* with alpha that varies is mode 6's.
|
|
49
|
+
*
|
|
50
|
+
* Measured on an RTX 4090, 4096² tiled from Spark.js's twenty report images, one level, kernel
|
|
51
|
+
* minimum: 0.47 ms and 40.86 dB mean PSNR for mode 6 alone, 0.83 ms and 44.07 dB for this — and on
|
|
52
|
+
* the two graphic images Spark leads on, RMSE 5.15 to 2.89 (`hype`) and 7.30 to 4.00 (`paint2`).
|
|
53
|
+
*
|
|
54
|
+
* @type {CodeChunk}
|
|
55
|
+
*/
|
|
56
|
+
export const chunk_bc7_encode_block: CodeChunk;
|
|
57
|
+
import { CodeChunk } from "../../shader/compiler/CodeChunk.js";
|
|
58
|
+
//# sourceMappingURL=chunk_bc7_encode_block.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"chunk_bc7_encode_block.d.ts","sourceRoot":"","sources":["../../../../../../src/shade/renderer/texture/encode/chunk_bc7_encode_block.js"],"names":[],"mappings":"AAKA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsDG;AACH,qCAFU,SAAS,CA6dZ;0BAvhBmB,oCAAoC"}
|
|
@@ -0,0 +1,536 @@
|
|
|
1
|
+
import { CodeChunk } from "../../shader/compiler/CodeChunk.js";
|
|
2
|
+
import { chunk_bc7_pack_mode1 } from "./chunk_bc7_pack_mode1.js";
|
|
3
|
+
import { chunk_bc7_pack_mode6 } from "./chunk_bc7_pack_mode6.js";
|
|
4
|
+
import { chunk_bc7_partition_2 } from "./chunk_bc7_partition_2.js";
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Encode sixteen RGBA texels as one BC7 block, in mode 6 or in mode 1 — whichever an estimate says
|
|
8
|
+
* loses less — fitting and writing only that one.
|
|
9
|
+
*
|
|
10
|
+
* **Mode 1 is two lines.** Mode 6 (`chunk_bc7_encode_block_mode6`) puts one line through the
|
|
11
|
+
* block in four channels; a block holding two colour regions, each varying its own way, is two lines
|
|
12
|
+
* that point different ways, and no single line holds both. Mode 1 splits the block by one of BC7's
|
|
13
|
+
* sixty-four two-subset partitions and gives each subset a line of its own: colour only, six bits a
|
|
14
|
+
* channel and a parity bit shared by the subset's two ends, eight levels on each line. It decodes
|
|
15
|
+
* opaque.
|
|
16
|
+
*
|
|
17
|
+
* **Chosen by estimate, not by search.** Each candidate's squared error is predicted from the block's
|
|
18
|
+
* statistics without encoding it — the approach of Geldreich's bc7f — and only the winner is fitted:
|
|
19
|
+
*
|
|
20
|
+
* 1. A line's distance from its texels is the lesser eigenvalues of their scatter about their mean,
|
|
21
|
+
* the trace less the largest. It is read here as the sum of the scatter's principal two-by-two
|
|
22
|
+
* minors over its trace: exact as the line thins, half the truth for a ball, and on Spark.js's
|
|
23
|
+
* twenty report images within 0.02 dB of solving for the eigenvalue, at well under its cost.
|
|
24
|
+
* 2. To that, what quantisation adds: the spread along the line over the squared steps between its
|
|
25
|
+
* levels, by a share calibrated on those images (0.5; flat within 0.01 dB from 0.35 to 0.5), and
|
|
26
|
+
* a term per block for the ends, larger for mode 1's coarser ones (8 and 18; flat from 18 to 25).
|
|
27
|
+
* 3. Mode 1 is estimated at **every** partition. A partition's second subset is the same texels in
|
|
28
|
+
* every invocation, so its sums are taken over exactly those, by a branch that does not diverge,
|
|
29
|
+
* and the first subset's are the block's less the second's. Ranking the partitions by how many
|
|
30
|
+
* texels they put across the block's principal split, and estimating the best four, measured
|
|
31
|
+
* 0.8 dB worse.
|
|
32
|
+
* 4. Mode 1 is charged each texel's distance from opaque in alpha, which keeps it off blocks that
|
|
33
|
+
* are not.
|
|
34
|
+
*
|
|
35
|
+
* Choosing the mode by the estimate rather than by each one's actual error costs 0.12 dB at the
|
|
36
|
+
* estimate's partition; fitting mode 1 at all sixty-four and keeping the best by actual error,
|
|
37
|
+
* sixty-five fits a block, was 0.3 dB better at forty to eighty times the time.
|
|
38
|
+
*
|
|
39
|
+
* **One fit for both modes.** The chosen mode reaches the fit as data — which texels are in the
|
|
40
|
+
* second subset, the levels, the bits an end keeps, whether alpha is held — so a group of
|
|
41
|
+
* invocations holding both modes runs one fit rather than both. Per subset: the principal axis by
|
|
42
|
+
* power iteration, the extreme projections as the ends, one round of least squares with each texel
|
|
43
|
+
* at the weight it projects to; then the parities, rounded to and **scored by the least squares'
|
|
44
|
+
* own quadratic form**: at its optimum the error grows by `aa |d0|² + 2 ab d0·d1 + bb |d1|²` for
|
|
45
|
+
* ends moved by `d0` and `d1`, so no combination needs a pass over the texels — 0.1 dB below scoring
|
|
46
|
+
* each against the decoder's palette, at about two fifths of the fit's time. Then each texel's exact
|
|
47
|
+
* nearest entry, once, and the anchors: texel 0 and the partition's second anchor are stored a bit
|
|
48
|
+
* short, and a subset whose anchor lands in the upper half is written the other way up.
|
|
49
|
+
*
|
|
50
|
+
* **Modes 3 and 7 are not here, by measurement.** Mode 3, two subsets of four levels on eight-bit
|
|
51
|
+
* ends, chosen by the same estimate at mode 1's partition, bought 0.05 dB over the twenty images and
|
|
52
|
+
* nothing on the graphic ones; mode 7 is mode 3 with alpha, and those images are opaque. A block
|
|
53
|
+
* with alpha that varies is mode 6's.
|
|
54
|
+
*
|
|
55
|
+
* Measured on an RTX 4090, 4096² tiled from Spark.js's twenty report images, one level, kernel
|
|
56
|
+
* minimum: 0.47 ms and 40.86 dB mean PSNR for mode 6 alone, 0.83 ms and 44.07 dB for this — and on
|
|
57
|
+
* the two graphic images Spark leads on, RMSE 5.15 to 2.89 (`hype`) and 7.30 to 4.00 (`paint2`).
|
|
58
|
+
*
|
|
59
|
+
* @type {CodeChunk}
|
|
60
|
+
*/
|
|
61
|
+
export const chunk_bc7_encode_block = CodeChunk.from(
|
|
62
|
+
//language=WGSL
|
|
63
|
+
`
|
|
64
|
+
// the estimate's quantisation terms: the indices' error as a share of the spread along the line over
|
|
65
|
+
// the squared steps between levels, and the ends' error per block, by mode
|
|
66
|
+
const BC7_ESTIMATE_INDEX: f32 = 0.5;
|
|
67
|
+
const BC7_ESTIMATE_END_6: f32 = 8.0;
|
|
68
|
+
const BC7_ESTIMATE_END_1: f32 = 18.0;
|
|
69
|
+
|
|
70
|
+
// a partition's second subset, as sums over its texels' offsets from the block's mean, colour only
|
|
71
|
+
struct Bc7Subset {
|
|
72
|
+
sum: vec3<f32>,
|
|
73
|
+
c00: f32,
|
|
74
|
+
c01: f32,
|
|
75
|
+
c02: f32,
|
|
76
|
+
c11: f32,
|
|
77
|
+
c12: f32,
|
|
78
|
+
c22: f32,
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
// a texel of the block, held packed, in the [0, 255] the fit works in
|
|
82
|
+
fn bc7_block_texel(packed: u32) -> vec4<f32> {
|
|
83
|
+
return unpack4x8unorm(packed) * 255.0;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
// the ten distinct terms of a four-channel scatter, for one offset
|
|
87
|
+
fn bc7_scatter_terms(d: vec4<f32>) -> array<f32, 10> {
|
|
88
|
+
return array<f32, 10>(
|
|
89
|
+
d.x * d.x, d.x * d.y, d.x * d.z, d.x * d.w,
|
|
90
|
+
d.y * d.y, d.y * d.z, d.y * d.w,
|
|
91
|
+
d.z * d.z, d.z * d.w,
|
|
92
|
+
d.w * d.w
|
|
93
|
+
);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
fn bc7_scatter_times(c: array<f32, 10>, v: vec4<f32>) -> vec4<f32> {
|
|
97
|
+
return vec4<f32>(
|
|
98
|
+
c[0] * v.x + c[1] * v.y + c[2] * v.z + c[3] * v.w,
|
|
99
|
+
c[1] * v.x + c[4] * v.y + c[5] * v.z + c[6] * v.w,
|
|
100
|
+
c[2] * v.x + c[5] * v.y + c[7] * v.z + c[8] * v.w,
|
|
101
|
+
c[3] * v.x + c[6] * v.y + c[8] * v.z + c[9] * v.w
|
|
102
|
+
);
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
// the principal axis of a scatter, by power iteration from its widest channel; that channel's unit
|
|
106
|
+
// vector when the scatter is zero
|
|
107
|
+
fn bc7_principal_axis(c: array<f32, 10>) -> vec4<f32> {
|
|
108
|
+
let diagonal = vec4<f32>(c[0], c[4], c[7], c[9]);
|
|
109
|
+
let widest = max(max(diagonal.x, diagonal.y), max(diagonal.z, diagonal.w));
|
|
110
|
+
|
|
111
|
+
var axis = select(
|
|
112
|
+
select(
|
|
113
|
+
select(vec4<f32>(0.0, 0.0, 0.0, 1.0), vec4<f32>(0.0, 0.0, 1.0, 0.0), diagonal.z == widest),
|
|
114
|
+
vec4<f32>(0.0, 1.0, 0.0, 0.0),
|
|
115
|
+
diagonal.y == widest
|
|
116
|
+
),
|
|
117
|
+
vec4<f32>(1.0, 0.0, 0.0, 0.0),
|
|
118
|
+
diagonal.x == widest
|
|
119
|
+
);
|
|
120
|
+
|
|
121
|
+
for (var iteration = 0u; iteration < 4u; iteration++) {
|
|
122
|
+
let next = bc7_scatter_times(c, axis);
|
|
123
|
+
let magnitude = length(next);
|
|
124
|
+
|
|
125
|
+
if (magnitude < 1e-3) {
|
|
126
|
+
break;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
axis = next / magnitude;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
return axis;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
// the estimated squared error of texels on one line, from the trace of their scatter about their mean
|
|
136
|
+
// and the sum of its principal two-by-two minors: the distance from the line, which is the scatter's
|
|
137
|
+
// lesser eigenvalues and is read as minors over trace — exact as the line thins, half of it for a
|
|
138
|
+
// ball — and the spread along the line over the squared steps between levels
|
|
139
|
+
fn bc7_estimate_line(trace: f32, minors: f32, steps: f32) -> f32 {
|
|
140
|
+
let off = clamp(minors / max(trace, 1e-6), 0.0, trace);
|
|
141
|
+
|
|
142
|
+
return off + (trace - off) * BC7_ESTIMATE_INDEX / (steps * steps);
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
fn bc7_estimate_line3(xx: f32, xy: f32, xz: f32, yy: f32, yz: f32, zz: f32, steps: f32) -> f32 {
|
|
146
|
+
return bc7_estimate_line(
|
|
147
|
+
xx + yy + zz,
|
|
148
|
+
xx * yy - xy * xy + xx * zz - xz * xz + yy * zz - yz * yz,
|
|
149
|
+
steps
|
|
150
|
+
);
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
fn bc7_estimate_line4(c: array<f32, 10>, steps: f32) -> f32 {
|
|
154
|
+
return bc7_estimate_line(
|
|
155
|
+
c[0] + c[4] + c[7] + c[9],
|
|
156
|
+
c[0] * c[4] - c[1] * c[1] + c[0] * c[7] - c[2] * c[2] + c[0] * c[9] - c[3] * c[3]
|
|
157
|
+
+ c[4] * c[7] - c[5] * c[5] + c[4] * c[9] - c[6] * c[6] + c[7] * c[9] - c[8] * c[8],
|
|
158
|
+
steps
|
|
159
|
+
);
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
// a palette entry as the decoder computes it from eight-bit ends: an index's weight out of 64 is
|
|
163
|
+
// round(64 i / steps), which is BC7's own table for two-, three- and four-bit indices
|
|
164
|
+
fn bc7_palette_entry(e0: vec4<f32>, e1: vec4<f32>, index: f32, steps: f32) -> vec4<f32> {
|
|
165
|
+
let w = round(index * 64.0 / steps);
|
|
166
|
+
|
|
167
|
+
return floor((e0 * (64.0 - w) + e1 * w + 32.0) / 64.0);
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
// the index a texel projects to on the line between the ends, of steps + 1 evenly spaced
|
|
171
|
+
fn bc7_projected_index(e0: vec4<f32>, e1: vec4<f32>, texel: vec4<f32>, steps: f32) -> f32 {
|
|
172
|
+
let direction = e1 - e0;
|
|
173
|
+
let span = dot(direction, direction);
|
|
174
|
+
|
|
175
|
+
if (span > 0.0) {
|
|
176
|
+
return clamp(round(dot(texel - e0, direction) / span * steps), 0.0, steps);
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
return 0.0;
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
// the index whose palette entry is nearest a texel: the projection's, or one beside it
|
|
183
|
+
fn bc7_nearest_index(e0: vec4<f32>, e1: vec4<f32>, texel: vec4<f32>, steps: f32) -> u32 {
|
|
184
|
+
let estimate = bc7_projected_index(e0, e1, texel, steps);
|
|
185
|
+
|
|
186
|
+
var best = estimate;
|
|
187
|
+
var best_distance = 1e30;
|
|
188
|
+
|
|
189
|
+
for (var offset = -1.0; offset <= 1.0; offset += 1.0) {
|
|
190
|
+
let candidate = clamp(estimate + offset, 0.0, steps);
|
|
191
|
+
|
|
192
|
+
let delta = bc7_palette_entry(e0, e1, candidate, steps) - texel;
|
|
193
|
+
let distance = dot(delta, delta);
|
|
194
|
+
|
|
195
|
+
if (distance < best_distance) {
|
|
196
|
+
best_distance = distance;
|
|
197
|
+
best = candidate;
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
return u32(best);
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
// an end rounded to what a mode stores, \`bits\` a channel with the parity as the lowest, and widened
|
|
205
|
+
// back to the eight bits the decoder interpolates, by its bit replication
|
|
206
|
+
fn bc7_quantise_end(e: vec4<f32>, bits: u32, parity: u32) -> vec4<f32> {
|
|
207
|
+
let top = f32((1u << bits) - 1u);
|
|
208
|
+
let p = f32(parity);
|
|
209
|
+
|
|
210
|
+
let code = clamp(
|
|
211
|
+
round((clamp(e, vec4<f32>(0.0), vec4<f32>(255.0)) * (top / 255.0) - p) * 0.5) * 2.0 + p,
|
|
212
|
+
vec4<f32>(p),
|
|
213
|
+
vec4<f32>(top - 1.0 + p)
|
|
214
|
+
);
|
|
215
|
+
|
|
216
|
+
let q = vec4<u32>(code);
|
|
217
|
+
|
|
218
|
+
return vec4<f32>((q << vec4<u32>(8u - bits)) | (q >> vec4<u32>(2u * bits - 8u)));
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
fn bc7_encode_block(texels: array<vec4<f32>, 16>) -> vec4<u32> {
|
|
222
|
+
var packed: array<u32, 16>;
|
|
223
|
+
|
|
224
|
+
var mean = vec4<f32>(0.0);
|
|
225
|
+
|
|
226
|
+
// what mode 1, which decodes opaque, costs in alpha
|
|
227
|
+
var alpha_error = 0.0;
|
|
228
|
+
|
|
229
|
+
for (var i = 0u; i < 16u; i++) {
|
|
230
|
+
packed[i] = pack4x8unorm(texels[i]);
|
|
231
|
+
|
|
232
|
+
let v = bc7_block_texel(packed[i]);
|
|
233
|
+
|
|
234
|
+
mean += v;
|
|
235
|
+
alpha_error += (255.0 - v.w) * (255.0 - v.w);
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
mean = mean / 16.0;
|
|
239
|
+
|
|
240
|
+
var block = array<f32, 10>(0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0);
|
|
241
|
+
|
|
242
|
+
// the texels' colour about the block's mean, held for the sixty-four partitions
|
|
243
|
+
var offsets: array<vec3<f32>, 16>;
|
|
244
|
+
|
|
245
|
+
for (var i = 0u; i < 16u; i++) {
|
|
246
|
+
let d = bc7_block_texel(packed[i]) - mean;
|
|
247
|
+
|
|
248
|
+
offsets[i] = d.xyz;
|
|
249
|
+
|
|
250
|
+
let t = bc7_scatter_terms(d);
|
|
251
|
+
|
|
252
|
+
for (var k = 0u; k < 10u; k++) {
|
|
253
|
+
block[k] += t[k];
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
// mode 6: one line through all four channels, sixteen levels on it
|
|
258
|
+
let estimate6 = bc7_estimate_line4(block, 15.0) + BC7_ESTIMATE_END_6;
|
|
259
|
+
|
|
260
|
+
// mode 1: two lines through the colour, eight levels on each, over every partition. The second
|
|
261
|
+
// subset's sums are taken over its texels — the same texels in every invocation, so the branch
|
|
262
|
+
// does not diverge — and the first's are the block's less the second's
|
|
263
|
+
var estimate1 = 1e30;
|
|
264
|
+
var pattern = 0u;
|
|
265
|
+
var second = Bc7Subset(vec3<f32>(0.0), 0.0, 0.0, 0.0, 0.0, 0.0, 0.0);
|
|
266
|
+
|
|
267
|
+
for (var p = 0u; p < 64u; p++) {
|
|
268
|
+
let mask = bc7_partition_2_mask(p);
|
|
269
|
+
|
|
270
|
+
var s = Bc7Subset(vec3<f32>(0.0), 0.0, 0.0, 0.0, 0.0, 0.0, 0.0);
|
|
271
|
+
|
|
272
|
+
for (var i = 0u; i < 16u; i++) {
|
|
273
|
+
if (((mask >> i) & 1u) != 0u) {
|
|
274
|
+
let d = offsets[i];
|
|
275
|
+
|
|
276
|
+
s.sum += d;
|
|
277
|
+
s.c00 += d.x * d.x;
|
|
278
|
+
s.c01 += d.x * d.y;
|
|
279
|
+
s.c02 += d.x * d.z;
|
|
280
|
+
s.c11 += d.y * d.y;
|
|
281
|
+
s.c12 += d.y * d.z;
|
|
282
|
+
s.c22 += d.z * d.z;
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
let n1 = f32(countOneBits(mask));
|
|
287
|
+
|
|
288
|
+
// each subset's scatter about its own mean: the second's sum, negated, is the first's
|
|
289
|
+
let m1 = s.sum / n1;
|
|
290
|
+
let m0 = s.sum / (16.0 - n1);
|
|
291
|
+
|
|
292
|
+
let estimate = BC7_ESTIMATE_END_1
|
|
293
|
+
+ bc7_estimate_line3(
|
|
294
|
+
s.c00 - s.sum.x * m1.x, s.c01 - s.sum.x * m1.y, s.c02 - s.sum.x * m1.z,
|
|
295
|
+
s.c11 - s.sum.y * m1.y, s.c12 - s.sum.y * m1.z,
|
|
296
|
+
s.c22 - s.sum.z * m1.z,
|
|
297
|
+
7.0
|
|
298
|
+
)
|
|
299
|
+
+ bc7_estimate_line3(
|
|
300
|
+
block[0] - s.c00 - s.sum.x * m0.x,
|
|
301
|
+
block[1] - s.c01 - s.sum.x * m0.y,
|
|
302
|
+
block[2] - s.c02 - s.sum.x * m0.z,
|
|
303
|
+
block[4] - s.c11 - s.sum.y * m0.y,
|
|
304
|
+
block[5] - s.c12 - s.sum.y * m0.z,
|
|
305
|
+
block[7] - s.c22 - s.sum.z * m0.z,
|
|
306
|
+
7.0
|
|
307
|
+
);
|
|
308
|
+
|
|
309
|
+
if (estimate < estimate1) {
|
|
310
|
+
estimate1 = estimate;
|
|
311
|
+
pattern = p;
|
|
312
|
+
second = s;
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
return bc7_encode_fit(packed, mean, block, estimate1 + alpha_error < estimate6, pattern, second);
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
// fit and write the chosen mode: one or two lines, each through its subset, by the same steps for
|
|
320
|
+
// both modes so a group of invocations holding both runs one fit
|
|
321
|
+
fn bc7_encode_fit(
|
|
322
|
+
packed: array<u32, 16>,
|
|
323
|
+
block_mean: vec4<f32>,
|
|
324
|
+
block_scatter: array<f32, 10>,
|
|
325
|
+
two: bool,
|
|
326
|
+
pattern: u32,
|
|
327
|
+
second: Bc7Subset
|
|
328
|
+
) -> vec4<u32> {
|
|
329
|
+
let mask = select(0u, bc7_partition_2_mask(pattern), two);
|
|
330
|
+
let anchor = select(0u, bc7_partition_2_anchor(pattern), two);
|
|
331
|
+
|
|
332
|
+
let steps = select(15.0, 7.0, two);
|
|
333
|
+
let bits = select(8u, 7u, two);
|
|
334
|
+
|
|
335
|
+
// mode 1 decodes opaque: its fit sees every texel as opaque, which leaves alpha out of it
|
|
336
|
+
let held = select(vec4<f32>(1.0), vec4<f32>(1.0, 1.0, 1.0, 0.0), two);
|
|
337
|
+
let opaque = select(vec4<f32>(0.0), vec4<f32>(0.0, 0.0, 0.0, 255.0), two);
|
|
338
|
+
|
|
339
|
+
// each subset's mean and scatter about it, from the second subset's sums; mode 6 has no second
|
|
340
|
+
let n1 = f32(countOneBits(mask));
|
|
341
|
+
let n0 = 16.0 - n1;
|
|
342
|
+
|
|
343
|
+
let k = select(0.0, 1.0, two);
|
|
344
|
+
|
|
345
|
+
let s = second.sum * k;
|
|
346
|
+
|
|
347
|
+
let q = array<f32, 6>(
|
|
348
|
+
second.c00 * k, second.c01 * k, second.c02 * k,
|
|
349
|
+
second.c11 * k, second.c12 * k,
|
|
350
|
+
second.c22 * k
|
|
351
|
+
);
|
|
352
|
+
|
|
353
|
+
let m1 = s / max(n1, 1.0);
|
|
354
|
+
let m0 = s / n0;
|
|
355
|
+
|
|
356
|
+
let mean0 = block_mean * held + opaque - vec4<f32>(m0, 0.0);
|
|
357
|
+
let mean1 = block_mean * held + opaque + vec4<f32>(m1, 0.0);
|
|
358
|
+
|
|
359
|
+
let c0 = array<f32, 10>(
|
|
360
|
+
block_scatter[0] - q[0] - s.x * m0.x,
|
|
361
|
+
block_scatter[1] - q[1] - s.x * m0.y,
|
|
362
|
+
block_scatter[2] - q[2] - s.x * m0.z,
|
|
363
|
+
block_scatter[3] * held.w,
|
|
364
|
+
block_scatter[4] - q[3] - s.y * m0.y,
|
|
365
|
+
block_scatter[5] - q[4] - s.y * m0.z,
|
|
366
|
+
block_scatter[6] * held.w,
|
|
367
|
+
block_scatter[7] - q[5] - s.z * m0.z,
|
|
368
|
+
block_scatter[8] * held.w,
|
|
369
|
+
block_scatter[9] * held.w
|
|
370
|
+
);
|
|
371
|
+
|
|
372
|
+
let c1 = array<f32, 10>(
|
|
373
|
+
q[0] - s.x * m1.x, q[1] - s.x * m1.y, q[2] - s.x * m1.z, 0.0,
|
|
374
|
+
q[3] - s.y * m1.y, q[4] - s.y * m1.z, 0.0,
|
|
375
|
+
q[5] - s.z * m1.z, 0.0,
|
|
376
|
+
0.0
|
|
377
|
+
);
|
|
378
|
+
|
|
379
|
+
let axis0 = bc7_principal_axis(c0);
|
|
380
|
+
let axis1 = bc7_principal_axis(c1);
|
|
381
|
+
|
|
382
|
+
// each subset's extreme projections onto its axis
|
|
383
|
+
var low = vec2<f32>(1e30);
|
|
384
|
+
var high = vec2<f32>(-1e30);
|
|
385
|
+
|
|
386
|
+
for (var i = 0u; i < 16u; i++) {
|
|
387
|
+
let in_second = ((mask >> i) & 1u) != 0u;
|
|
388
|
+
let texel = bc7_block_texel(packed[i]) * held + opaque;
|
|
389
|
+
|
|
390
|
+
let t = dot(texel - select(mean0, mean1, in_second), select(axis0, axis1, in_second));
|
|
391
|
+
|
|
392
|
+
low = select(vec2<f32>(min(low.x, t), low.y), vec2<f32>(low.x, min(low.y, t)), in_second);
|
|
393
|
+
high = select(vec2<f32>(max(high.x, t), high.y), vec2<f32>(high.x, max(high.y, t)), in_second);
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
// a subset with no texels — mode 6's second — gets a point, not an infinite line
|
|
397
|
+
let empty = high < low;
|
|
398
|
+
|
|
399
|
+
low = select(low, vec2<f32>(0.0), empty);
|
|
400
|
+
high = select(high, vec2<f32>(0.0), empty);
|
|
401
|
+
|
|
402
|
+
var a0 = mean0 + axis0 * low.x;
|
|
403
|
+
var a1 = mean0 + axis0 * high.x;
|
|
404
|
+
var b0 = mean1 + axis1 * low.y;
|
|
405
|
+
var b1 = mean1 + axis1 * high.y;
|
|
406
|
+
|
|
407
|
+
// one round of least squares per subset, each texel at the weight it projects to
|
|
408
|
+
var aa = vec2<f32>(0.0);
|
|
409
|
+
var ab = vec2<f32>(0.0);
|
|
410
|
+
var bb = vec2<f32>(0.0);
|
|
411
|
+
var ap0 = vec4<f32>(0.0);
|
|
412
|
+
var bp0 = vec4<f32>(0.0);
|
|
413
|
+
var ap1 = vec4<f32>(0.0);
|
|
414
|
+
var bp1 = vec4<f32>(0.0);
|
|
415
|
+
|
|
416
|
+
for (var i = 0u; i < 16u; i++) {
|
|
417
|
+
let in_second = ((mask >> i) & 1u) != 0u;
|
|
418
|
+
let texel = bc7_block_texel(packed[i]) * held + opaque;
|
|
419
|
+
|
|
420
|
+
let index = bc7_projected_index(select(a0, b0, in_second), select(a1, b1, in_second), texel, steps);
|
|
421
|
+
|
|
422
|
+
let wb = round(index * 64.0 / steps) / 64.0;
|
|
423
|
+
let wa = 1.0 - wb;
|
|
424
|
+
|
|
425
|
+
let into = select(vec2<f32>(1.0, 0.0), vec2<f32>(0.0, 1.0), in_second);
|
|
426
|
+
|
|
427
|
+
aa += into * (wa * wa);
|
|
428
|
+
ab += into * (wa * wb);
|
|
429
|
+
bb += into * (wb * wb);
|
|
430
|
+
|
|
431
|
+
ap0 += texel * (wa * into.x);
|
|
432
|
+
bp0 += texel * (wb * into.x);
|
|
433
|
+
ap1 += texel * (wa * into.y);
|
|
434
|
+
bp1 += texel * (wb * into.y);
|
|
435
|
+
}
|
|
436
|
+
|
|
437
|
+
let determinant = aa * bb - ab * ab;
|
|
438
|
+
|
|
439
|
+
if (abs(determinant.x) >= 1e-6) {
|
|
440
|
+
a0 = (bb.x * ap0 - ab.x * bp0) / determinant.x;
|
|
441
|
+
a1 = (aa.x * bp0 - ab.x * ap0) / determinant.x;
|
|
442
|
+
}
|
|
443
|
+
|
|
444
|
+
if (abs(determinant.y) >= 1e-6) {
|
|
445
|
+
b0 = (bb.y * ap1 - ab.y * bp1) / determinant.y;
|
|
446
|
+
b1 = (aa.y * bp1 - ab.y * ap1) / determinant.y;
|
|
447
|
+
}
|
|
448
|
+
|
|
449
|
+
// the parities, by what each combination adds to the least squares' error without a pass over the
|
|
450
|
+
// texels: at its optimum the error grows by aa |d0|² + 2 ab d0·d1 + bb |d1|² for ends moved by d0
|
|
451
|
+
// and d1. Mode 1 shares one parity between a subset's two ends
|
|
452
|
+
var best = vec2<f32>(1e30);
|
|
453
|
+
|
|
454
|
+
var qa0 = vec4<f32>(0.0);
|
|
455
|
+
var qa1 = vec4<f32>(0.0);
|
|
456
|
+
var qb0 = vec4<f32>(0.0);
|
|
457
|
+
var qb1 = vec4<f32>(0.0);
|
|
458
|
+
|
|
459
|
+
for (var combination = 0u; combination < 4u; combination++) {
|
|
460
|
+
let p0 = combination & 1u;
|
|
461
|
+
let p1 = combination >> 1u;
|
|
462
|
+
|
|
463
|
+
let ca0 = bc7_quantise_end(a0, bits, p0) * held + opaque;
|
|
464
|
+
let ca1 = bc7_quantise_end(a1, bits, p1) * held + opaque;
|
|
465
|
+
let cb0 = bc7_quantise_end(b0, bits, p0) * held + opaque;
|
|
466
|
+
let cb1 = bc7_quantise_end(b1, bits, p1) * held + opaque;
|
|
467
|
+
|
|
468
|
+
let da0 = (ca0 - a0) * held;
|
|
469
|
+
let da1 = (ca1 - a1) * held;
|
|
470
|
+
let db0 = (cb0 - b0) * held;
|
|
471
|
+
let db1 = (cb1 - b1) * held;
|
|
472
|
+
|
|
473
|
+
let error = vec2<f32>(
|
|
474
|
+
aa.x * dot(da0, da0) + 2.0 * ab.x * dot(da0, da1) + bb.x * dot(da1, da1),
|
|
475
|
+
aa.y * dot(db0, db0) + 2.0 * ab.y * dot(db0, db1) + bb.y * dot(db1, db1)
|
|
476
|
+
) + select(vec2<f32>(0.0), vec2<f32>(1e30), two && p0 != p1);
|
|
477
|
+
|
|
478
|
+
if (error.x < best.x) {
|
|
479
|
+
best.x = error.x;
|
|
480
|
+
qa0 = ca0;
|
|
481
|
+
qa1 = ca1;
|
|
482
|
+
}
|
|
483
|
+
|
|
484
|
+
if (error.y < best.y) {
|
|
485
|
+
best.y = error.y;
|
|
486
|
+
qb0 = cb0;
|
|
487
|
+
qb1 = cb1;
|
|
488
|
+
}
|
|
489
|
+
}
|
|
490
|
+
|
|
491
|
+
// each texel's nearest entry of its subset's palette
|
|
492
|
+
var indices: array<u32, 16>;
|
|
493
|
+
|
|
494
|
+
for (var i = 0u; i < 16u; i++) {
|
|
495
|
+
let in_second = ((mask >> i) & 1u) != 0u;
|
|
496
|
+
let texel = bc7_block_texel(packed[i]) * held + opaque;
|
|
497
|
+
|
|
498
|
+
indices[i] = bc7_nearest_index(select(qa0, qb0, in_second), select(qa1, qb1, in_second), texel, steps);
|
|
499
|
+
}
|
|
500
|
+
|
|
501
|
+
// the anchors, texel 0 and the second subset's, are stored a bit short: a subset whose anchor
|
|
502
|
+
// lands in the upper half is written the other way up, which decodes identically
|
|
503
|
+
let top = u32(steps);
|
|
504
|
+
let upper = (top + 1u) / 2u;
|
|
505
|
+
|
|
506
|
+
var anchor_index = 0u;
|
|
507
|
+
|
|
508
|
+
for (var i = 0u; i < 16u; i++) {
|
|
509
|
+
anchor_index = select(anchor_index, indices[i], i == anchor);
|
|
510
|
+
}
|
|
511
|
+
|
|
512
|
+
let flip0 = indices[0] >= upper;
|
|
513
|
+
let flip1 = two && anchor_index >= upper;
|
|
514
|
+
|
|
515
|
+
for (var i = 0u; i < 16u; i++) {
|
|
516
|
+
let in_second = ((mask >> i) & 1u) != 0u;
|
|
517
|
+
|
|
518
|
+
indices[i] = select(indices[i], top - indices[i], select(flip0, flip1, in_second));
|
|
519
|
+
}
|
|
520
|
+
|
|
521
|
+
let ea0 = select(qa0, qa1, flip0);
|
|
522
|
+
let ea1 = select(qa1, qa0, flip0);
|
|
523
|
+
let eb0 = select(qb0, qb1, flip1);
|
|
524
|
+
let eb1 = select(qb1, qb0, flip1);
|
|
525
|
+
|
|
526
|
+
if (two) {
|
|
527
|
+
return bc7_pack_mode1(pattern, vec3<u32>(ea0.xyz), vec3<u32>(ea1.xyz), vec3<u32>(eb0.xyz), vec3<u32>(eb1.xyz), indices);
|
|
528
|
+
}
|
|
529
|
+
|
|
530
|
+
return bc7_pack_mode6(vec4<u32>(ea0), vec4<u32>(ea1), indices);
|
|
531
|
+
}
|
|
532
|
+
`, [
|
|
533
|
+
chunk_bc7_partition_2,
|
|
534
|
+
chunk_bc7_pack_mode1,
|
|
535
|
+
chunk_bc7_pack_mode6,
|
|
536
|
+
]);
|
|
@@ -6,29 +6,43 @@
|
|
|
6
6
|
* stored at seven bits plus a parity bit each — an eight-bit value whose low bit is shared by the
|
|
7
7
|
* endpoint's four channels. It is the mode `bc7enc`'s "mode 6 only" setting, DirectXTex's
|
|
8
8
|
* `BC7_QUICK`, and the mode the UASTC transcoder carries single-subset blocks into, and on its own
|
|
9
|
-
* it beats BC1 by a wide margin on everything but sharply partitioned blocks.
|
|
10
|
-
*
|
|
9
|
+
* it beats BC1 by a wide margin on everything but sharply partitioned blocks. Those are mode 1's, in
|
|
10
|
+
* `chunk_bc7_encode_block`, which the kernel calls and which chooses between the two; this chunk is
|
|
11
|
+
* mode 6 on its own.
|
|
11
12
|
*
|
|
12
13
|
* The fit is {@link chunk_bc1_encode_block}'s in four dimensions:
|
|
13
14
|
*
|
|
14
15
|
* 1. The principal axis by power iteration on the 4x4 covariance, seeded with the box diagonal;
|
|
15
16
|
* the extreme projections as the ends.
|
|
16
|
-
* 2.
|
|
17
|
-
* texel
|
|
17
|
+
* 2. One round of least squares with the sixteen decode weights shared across channels, each
|
|
18
|
+
* texel at the weight it projects to.
|
|
18
19
|
* 3. **Quantisation with every parity.** Each end's low bit is one of two values, so the pair has
|
|
19
20
|
* four parity combinations; each is rounded to and scored against the decoder's own palette,
|
|
20
|
-
*
|
|
21
|
-
*
|
|
22
|
-
*
|
|
21
|
+
* each texel at the entry its projection names, and the best is kept.
|
|
22
|
+
* 4. **The indices**, each texel's nearest entry of that palette: the projection's index and the
|
|
23
|
+
* two beside it, by distance, because the weights are not evenly spaced and the entries are
|
|
24
|
+
* rounded.
|
|
25
|
+
* 5. **The anchor.** Texel 0's index is stored a bit short, so its top bit must be zero: when it
|
|
23
26
|
* is not, the ends are swapped and every index inverted, which is the same block the other way
|
|
24
27
|
* up.
|
|
25
28
|
*
|
|
29
|
+
* **The search is the leanest that holds the line**, by measurement (plan §9.20). The one it
|
|
30
|
+
* replaced scored each texel at its nearest entry rather than its projection's, ran a second round
|
|
31
|
+
* of least squares and a round of coordinate descent over the stored ends, and held the block as
|
|
32
|
+
* floats: 0.17 dB better over twenty photographs, at six times the time. Sixteen points on the line
|
|
33
|
+
* leave the projection little to miss; the quality BC7 still lacks is in the partitioned modes, and
|
|
34
|
+
* that is where the budget goes.
|
|
35
|
+
*
|
|
26
36
|
* Every score is against the palette the decoder builds — `(a (64 - w) + b w + 32) >> 6` on the
|
|
27
37
|
* eight-bit ends, with BC7's own four-bit weights, which are not evenly spaced — and alpha counts
|
|
28
38
|
* like any other channel: an opaque source's alpha is a constant the fit may land a level off
|
|
29
39
|
* where that buys colour, as the reference transcoder does (plan §9.12), because this encoder does
|
|
30
40
|
* not know what its consumer will do with alpha and is not the place to decide it.
|
|
31
41
|
*
|
|
42
|
+
* The block is held as sixteen packed eight-bit words and unpacked where it is read, which is
|
|
43
|
+
* sixteen registers instead of sixty-four. A source with more than eight bits a channel is rounded
|
|
44
|
+
* to eight first: what the format's ends and palette hold.
|
|
45
|
+
*
|
|
32
46
|
* @type {CodeChunk}
|
|
33
47
|
*/
|
|
34
48
|
export const chunk_bc7_encode_block_mode6: CodeChunk;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"chunk_bc7_encode_block_mode6.d.ts","sourceRoot":"","sources":["../../../../../../src/shade/renderer/texture/encode/chunk_bc7_encode_block_mode6.js"],"names":[],"mappings":"AAGA
|
|
1
|
+
{"version":3,"file":"chunk_bc7_encode_block_mode6.d.ts","sourceRoot":"","sources":["../../../../../../src/shade/renderer/texture/encode/chunk_bc7_encode_block_mode6.js"],"names":[],"mappings":"AAGA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8CG;AACH,2CAFU,SAAS,CAkPZ;0BAlSmB,oCAAoC"}
|