@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.
Files changed (466) hide show
  1. package/build/bundle-worker-terrain.js +1 -1
  2. package/editor/prototypeEditorShell.d.ts.map +1 -1
  3. package/editor/prototypeEditorShell.js +4 -2
  4. package/package.json +1 -1
  5. package/src/core/collection/array/array_sort_insertion_ascending.d.ts +19 -0
  6. package/src/core/collection/array/array_sort_insertion_ascending.d.ts.map +1 -0
  7. package/src/core/collection/array/array_sort_insertion_ascending.js +31 -0
  8. package/src/core/geom/3d/aabb/aabb3_array_round_outward_f32.d.ts +27 -0
  9. package/src/core/geom/3d/aabb/aabb3_array_round_outward_f32.d.ts.map +1 -0
  10. package/src/core/geom/3d/aabb/aabb3_array_round_outward_f32.js +39 -0
  11. package/src/core/geom/3d/aabb/aabb3_from_v3_array.d.ts.map +1 -1
  12. package/src/core/geom/3d/aabb/aabb3_from_v3_array.js +4 -1
  13. package/src/core/geom/3d/aabb/aabb3_transform_oriented.d.ts +2 -2
  14. package/src/core/geom/3d/aabb/aabb3_transform_oriented.d.ts.map +1 -1
  15. package/src/core/geom/3d/aabb/aabb3_transform_oriented.js +1 -1
  16. package/src/core/geom/3d/pose/pose3_apply_inverse_point_array.d.ts +21 -0
  17. package/src/core/geom/3d/pose/pose3_apply_inverse_point_array.d.ts.map +1 -0
  18. package/src/core/geom/3d/pose/pose3_apply_inverse_point_array.js +36 -0
  19. package/src/core/geom/3d/pose/pose3_apply_point_array.d.ts +25 -0
  20. package/src/core/geom/3d/pose/pose3_apply_point_array.d.ts.map +1 -0
  21. package/src/core/geom/3d/pose/pose3_apply_point_array.js +40 -0
  22. package/src/core/geom/3d/pose/pose3_compose_array.d.ts +28 -0
  23. package/src/core/geom/3d/pose/pose3_compose_array.d.ts.map +1 -0
  24. package/src/core/geom/3d/pose/pose3_compose_array.js +41 -0
  25. package/src/core/geom/3d/pose/pose3_to_local_array.d.ts +29 -0
  26. package/src/core/geom/3d/pose/pose3_to_local_array.d.ts.map +1 -0
  27. package/src/core/geom/3d/pose/pose3_to_local_array.js +42 -0
  28. package/src/core/geom/3d/quaternion/quat3_clamp_angle_array.d.ts +28 -0
  29. package/src/core/geom/3d/quaternion/quat3_clamp_angle_array.d.ts.map +1 -0
  30. package/src/core/geom/3d/quaternion/quat3_clamp_angle_array.js +66 -0
  31. package/src/core/geom/3d/quaternion/quat3_multiply_conjugate_left_array.d.ts +22 -0
  32. package/src/core/geom/3d/quaternion/quat3_multiply_conjugate_left_array.d.ts.map +1 -0
  33. package/src/core/geom/3d/quaternion/quat3_multiply_conjugate_left_array.js +30 -0
  34. package/src/core/geom/3d/quaternion/quat3_multiply_conjugate_right_array.d.ts +23 -0
  35. package/src/core/geom/3d/quaternion/quat3_multiply_conjugate_right_array.d.ts.map +1 -0
  36. package/src/core/geom/3d/quaternion/quat3_multiply_conjugate_right_array.js +31 -0
  37. package/src/core/geom/3d/triangle/tri3_compute_normal_area_weighted_array.d.ts +26 -0
  38. package/src/core/geom/3d/triangle/tri3_compute_normal_area_weighted_array.d.ts.map +1 -0
  39. package/src/core/geom/3d/triangle/tri3_compute_normal_area_weighted_array.js +46 -0
  40. package/src/core/geom/vec3/v3_distance_array.d.ts +11 -0
  41. package/src/core/geom/vec3/v3_distance_array.d.ts.map +1 -0
  42. package/src/core/geom/vec3/v3_distance_array.js +19 -0
  43. package/src/core/geom/vec3/v3_normalize_array_checked.d.ts +23 -0
  44. package/src/core/geom/vec3/v3_normalize_array_checked.d.ts.map +1 -0
  45. package/src/core/geom/vec3/v3_normalize_array_checked.js +49 -0
  46. package/src/core/geom/vec3/v3_reject_array.d.ts +15 -0
  47. package/src/core/geom/vec3/v3_reject_array.d.ts.map +1 -0
  48. package/src/core/geom/vec3/v3_reject_array.js +32 -0
  49. package/src/core/graph/csr/csr_build_incidence.d.ts +26 -0
  50. package/src/core/graph/csr/csr_build_incidence.d.ts.map +1 -0
  51. package/src/core/graph/csr/csr_build_incidence.js +71 -0
  52. package/src/core/graph/csr/csr_graph_color_greedy.d.ts +25 -0
  53. package/src/core/graph/csr/csr_graph_color_greedy.d.ts.map +1 -0
  54. package/src/core/graph/csr/csr_graph_color_greedy.js +83 -0
  55. package/src/core/graph/csr/csr_graph_validate_coloring.d.ts +15 -0
  56. package/src/core/graph/csr/csr_graph_validate_coloring.d.ts.map +1 -0
  57. package/src/core/graph/csr/csr_graph_validate_coloring.js +33 -0
  58. package/src/core/math/linalg/matrix_symmetric_3x3_solve_ldlt.d.ts +26 -0
  59. package/src/core/math/linalg/matrix_symmetric_3x3_solve_ldlt.d.ts.map +1 -0
  60. package/src/core/math/linalg/matrix_symmetric_3x3_solve_ldlt.js +71 -0
  61. package/src/core/math/max2_exact.d.ts +15 -0
  62. package/src/core/math/max2_exact.d.ts.map +1 -0
  63. package/src/core/math/max2_exact.js +30 -0
  64. package/src/core/math/min2_exact.d.ts +20 -0
  65. package/src/core/math/min2_exact.d.ts.map +1 -0
  66. package/src/core/math/min2_exact.js +35 -0
  67. package/src/engine/Clock.d.ts +15 -0
  68. package/src/engine/Clock.d.ts.map +1 -1
  69. package/src/engine/Clock.js +29 -5
  70. package/src/engine/Engine.d.ts.map +1 -1
  71. package/src/engine/Engine.js +11 -19
  72. package/src/engine/ecs/ik/IKGoalSystem.d.ts.map +1 -1
  73. package/src/engine/ecs/ik/IKGoalSystem.js +3 -19
  74. package/src/engine/ecs/parent/parent_entity_model_of.d.ts +17 -0
  75. package/src/engine/ecs/parent/parent_entity_model_of.d.ts.map +1 -0
  76. package/src/engine/ecs/parent/parent_entity_model_of.js +26 -0
  77. package/src/engine/ecs/transform/t64_read_pose_array.d.ts +15 -0
  78. package/src/engine/ecs/transform/t64_read_pose_array.d.ts.map +1 -0
  79. package/src/engine/ecs/transform/t64_read_pose_array.js +24 -0
  80. package/src/engine/graphics/ecs/mesh-v2/MeshSkin.d.ts +57 -0
  81. package/src/engine/graphics/ecs/mesh-v2/MeshSkin.d.ts.map +1 -0
  82. package/src/engine/graphics/ecs/mesh-v2/MeshSkin.js +84 -0
  83. package/src/engine/graphics/geometry/geometry_construct_triangle_normal_area_weighted.d.ts +2 -0
  84. package/src/engine/graphics/geometry/geometry_construct_triangle_normal_area_weighted.d.ts.map +1 -1
  85. package/src/engine/graphics/geometry/geometry_construct_triangle_normal_area_weighted.js +10 -21
  86. package/src/engine/graphics3/AnimationGraphSystem.d.ts +28 -13
  87. package/src/engine/graphics3/AnimationGraphSystem.d.ts.map +1 -1
  88. package/src/engine/graphics3/AnimationGraphSystem.js +107 -64
  89. package/src/engine/graphics3/AnimationSystem.d.ts +29 -15
  90. package/src/engine/graphics3/AnimationSystem.d.ts.map +1 -1
  91. package/src/engine/graphics3/AnimationSystem.js +112 -61
  92. package/src/engine/graphics3/MeshSkinSystem.d.ts +56 -0
  93. package/src/engine/graphics3/MeshSkinSystem.d.ts.map +1 -0
  94. package/src/engine/graphics3/MeshSkinSystem.js +317 -0
  95. package/src/engine/graphics3/MeshSystem.d.ts +15 -35
  96. package/src/engine/graphics3/MeshSystem.d.ts.map +1 -1
  97. package/src/engine/graphics3/MeshSystem.js +21 -298
  98. package/src/engine/graphics3/RowChains.d.ts +76 -0
  99. package/src/engine/graphics3/RowChains.d.ts.map +1 -0
  100. package/src/engine/graphics3/RowChains.js +347 -0
  101. package/src/engine/graphics3/ShadedGeometrySystem.d.ts +6 -0
  102. package/src/engine/graphics3/ShadedGeometrySystem.d.ts.map +1 -1
  103. package/src/engine/graphics3/ShadedGeometrySystem.js +329 -309
  104. package/src/engine/graphics3/animation/AnimationClips.d.ts +56 -0
  105. package/src/engine/graphics3/animation/AnimationClips.d.ts.map +1 -0
  106. package/src/engine/graphics3/animation/AnimationClips.js +79 -0
  107. package/src/engine/graphics3/animation/ClipListPlayer.d.ts +13 -14
  108. package/src/engine/graphics3/animation/ClipListPlayer.d.ts.map +1 -1
  109. package/src/engine/graphics3/animation/ClipListPlayer.js +262 -263
  110. package/src/engine/graphics3/animation/write_clip_playback.d.ts +3 -3
  111. package/src/engine/graphics3/animation/write_clip_playback.js +4 -4
  112. package/src/engine/graphics3/pose/query_entity_node_world_pose.d.ts +5 -0
  113. package/src/engine/graphics3/pose/query_entity_node_world_pose.d.ts.map +1 -1
  114. package/src/engine/graphics3/pose/query_entity_node_world_pose.js +80 -75
  115. package/src/engine/graphics3/prefab/PrefabInstance.d.ts +4 -24
  116. package/src/engine/graphics3/prefab/PrefabInstance.d.ts.map +1 -1
  117. package/src/engine/graphics3/prefab/PrefabInstance.js +60 -80
  118. package/src/engine/graphics3/prefab/prefab_instantiate.d.ts +16 -3
  119. package/src/engine/graphics3/prefab/prefab_instantiate.d.ts.map +1 -1
  120. package/src/engine/graphics3/prefab/prefab_instantiate.js +49 -12
  121. package/src/engine/graphics3/prefab/prefab_place.d.ts +31 -17
  122. package/src/engine/graphics3/prefab/prefab_place.d.ts.map +1 -1
  123. package/src/engine/graphics3/prefab/prefab_place.js +175 -130
  124. package/src/engine/graphics3/register_clips.d.ts +93 -0
  125. package/src/engine/graphics3/register_clips.d.ts.map +1 -0
  126. package/src/engine/graphics3/register_clips.js +166 -0
  127. package/src/engine/physics/broadphase/compute_fat_world_aabb.d.ts +9 -0
  128. package/src/engine/physics/broadphase/compute_fat_world_aabb.d.ts.map +1 -1
  129. package/src/engine/physics/broadphase/compute_fat_world_aabb.js +3 -1
  130. package/src/engine/physics/cloth/MEASUREMENTS.md +795 -0
  131. package/src/engine/physics/cloth/PLAN.md +349 -17
  132. package/src/engine/physics/cloth/build/ClothProxy.d.ts +113 -61
  133. package/src/engine/physics/cloth/build/ClothProxy.d.ts.map +1 -1
  134. package/src/engine/physics/cloth/build/ClothProxy.js +142 -77
  135. package/src/engine/physics/cloth/build/cloth_bind_in_frame.d.ts +44 -0
  136. package/src/engine/physics/cloth/build/cloth_bind_in_frame.d.ts.map +1 -0
  137. package/src/engine/physics/cloth/build/cloth_bind_in_frame.js +107 -0
  138. package/src/engine/physics/cloth/build/cloth_proxy_from_joints.d.ts +43 -30
  139. package/src/engine/physics/cloth/build/cloth_proxy_from_joints.d.ts.map +1 -1
  140. package/src/engine/physics/cloth/build/cloth_proxy_from_joints.js +371 -284
  141. package/src/engine/physics/cloth/build/cloth_proxy_from_mesh.d.ts +62 -0
  142. package/src/engine/physics/cloth/build/cloth_proxy_from_mesh.d.ts.map +1 -0
  143. package/src/engine/physics/cloth/build/cloth_proxy_from_mesh.js +275 -0
  144. package/src/engine/physics/cloth/collider/ClothColliderIndex.d.ts +7 -0
  145. package/src/engine/physics/cloth/collider/ClothColliderIndex.d.ts.map +1 -1
  146. package/src/engine/physics/cloth/collider/ClothColliderIndex.js +85 -67
  147. package/src/engine/physics/cloth/collider/cloth_collider_bounds.d.ts.map +1 -1
  148. package/src/engine/physics/cloth/collider/cloth_collider_bounds.js +19 -101
  149. package/src/engine/physics/cloth/collider/cloth_collider_pack.d.ts +2 -5
  150. package/src/engine/physics/cloth/collider/cloth_collider_pack.d.ts.map +1 -1
  151. package/src/engine/physics/cloth/collider/cloth_collider_pack.js +7 -15
  152. package/src/engine/physics/cloth/collider/cloth_collider_sdf.d.ts +1 -1
  153. package/src/engine/physics/cloth/collider/cloth_collider_sdf.d.ts.map +1 -1
  154. package/src/engine/physics/cloth/collider/cloth_collider_sdf.js +17 -62
  155. package/src/engine/physics/cloth/ecs/Cloth.d.ts +17 -9
  156. package/src/engine/physics/cloth/ecs/Cloth.d.ts.map +1 -1
  157. package/src/engine/physics/cloth/ecs/Cloth.js +220 -212
  158. package/src/engine/physics/cloth/ecs/ClothColliderFlags.d.ts +0 -1
  159. package/src/engine/physics/cloth/ecs/ClothColliderFlags.js +6 -19
  160. package/src/engine/physics/cloth/ecs/ClothColliderSystem.d.ts +1 -2
  161. package/src/engine/physics/cloth/ecs/ClothColliderSystem.d.ts.map +1 -1
  162. package/src/engine/physics/cloth/ecs/ClothColliderSystem.js +3 -12
  163. package/src/engine/physics/cloth/ecs/ClothDynamicsFlags.js +6 -0
  164. package/src/engine/physics/cloth/ecs/ClothHold.d.ts +91 -0
  165. package/src/engine/physics/cloth/ecs/ClothHold.d.ts.map +1 -0
  166. package/src/engine/physics/cloth/ecs/ClothHold.js +103 -0
  167. package/src/engine/physics/cloth/ecs/ClothInstance.d.ts +254 -48
  168. package/src/engine/physics/cloth/ecs/ClothInstance.d.ts.map +1 -1
  169. package/src/engine/physics/cloth/ecs/ClothInstance.js +277 -47
  170. package/src/engine/physics/cloth/ecs/ClothPin.d.ts +73 -0
  171. package/src/engine/physics/cloth/ecs/ClothPin.d.ts.map +1 -0
  172. package/src/engine/physics/cloth/ecs/ClothPin.js +92 -0
  173. package/src/engine/physics/cloth/ecs/ClothPinSerializationAdapter.d.ts +36 -0
  174. package/src/engine/physics/cloth/ecs/ClothPinSerializationAdapter.d.ts.map +1 -0
  175. package/src/engine/physics/cloth/ecs/ClothPinSerializationAdapter.js +61 -0
  176. package/src/engine/physics/cloth/ecs/ClothRig.d.ts +23 -17
  177. package/src/engine/physics/cloth/ecs/ClothRig.d.ts.map +1 -1
  178. package/src/engine/physics/cloth/ecs/ClothRig.js +29 -27
  179. package/src/engine/physics/cloth/ecs/ClothSystem.d.ts +12 -14
  180. package/src/engine/physics/cloth/ecs/ClothSystem.d.ts.map +1 -1
  181. package/src/engine/physics/cloth/ecs/ClothSystem.js +20 -15
  182. package/src/engine/physics/cloth/ecs/ClothWorld.d.ts +57 -36
  183. package/src/engine/physics/cloth/ecs/ClothWorld.d.ts.map +1 -1
  184. package/src/engine/physics/cloth/ecs/ClothWorld.js +754 -207
  185. package/src/engine/physics/cloth/ecs/WorkerClothSystem.d.ts +12 -13
  186. package/src/engine/physics/cloth/ecs/WorkerClothSystem.d.ts.map +1 -1
  187. package/src/engine/physics/cloth/ecs/WorkerClothSystem.js +20 -14
  188. package/src/engine/physics/cloth/ecs/cloth_build_rows.d.ts +63 -11
  189. package/src/engine/physics/cloth/ecs/cloth_build_rows.d.ts.map +1 -1
  190. package/src/engine/physics/cloth/ecs/cloth_build_rows.js +297 -101
  191. package/src/engine/physics/cloth/ecs/cloth_dynamics_map.d.ts +9 -7
  192. package/src/engine/physics/cloth/ecs/cloth_dynamics_map.d.ts.map +1 -1
  193. package/src/engine/physics/cloth/ecs/cloth_dynamics_map.js +12 -10
  194. package/src/engine/physics/cloth/ecs/cloth_gather_colliders.d.ts +3 -3
  195. package/src/engine/physics/cloth/ecs/cloth_gather_colliders.d.ts.map +1 -1
  196. package/src/engine/physics/cloth/ecs/cloth_gather_colliders.js +60 -120
  197. package/src/engine/physics/cloth/ecs/cloth_geodesic.d.ts +37 -0
  198. package/src/engine/physics/cloth/ecs/cloth_geodesic.d.ts.map +1 -0
  199. package/src/engine/physics/cloth/ecs/cloth_geodesic.js +135 -0
  200. package/src/engine/physics/cloth/ecs/cloth_holds.d.ts +97 -0
  201. package/src/engine/physics/cloth/ecs/cloth_holds.d.ts.map +1 -0
  202. package/src/engine/physics/cloth/ecs/cloth_holds.js +583 -0
  203. package/src/engine/physics/cloth/ecs/cloth_reconstruct_pose.d.ts +2 -2
  204. package/src/engine/physics/cloth/ecs/cloth_reconstruct_pose.d.ts.map +1 -1
  205. package/src/engine/physics/cloth/ecs/cloth_reconstruct_pose.js +168 -51
  206. package/src/engine/physics/cloth/ecs/cloth_seed_rig.d.ts +17 -22
  207. package/src/engine/physics/cloth/ecs/cloth_seed_rig.d.ts.map +1 -1
  208. package/src/engine/physics/cloth/ecs/cloth_seed_rig.js +55 -117
  209. package/src/engine/physics/cloth/ecs/cloth_seed_subtree.d.ts +21 -6
  210. package/src/engine/physics/cloth/ecs/cloth_seed_subtree.d.ts.map +1 -1
  211. package/src/engine/physics/cloth/ecs/cloth_seed_subtree.js +51 -42
  212. package/src/engine/physics/cloth/ecs/cloth_write_back.d.ts +5 -0
  213. package/src/engine/physics/cloth/ecs/cloth_write_back.d.ts.map +1 -1
  214. package/src/engine/physics/cloth/ecs/cloth_write_back.js +62 -50
  215. package/src/engine/physics/cloth/ecs/cloth_write_back_rig.d.ts.map +1 -1
  216. package/src/engine/physics/cloth/ecs/cloth_write_back_rig.js +65 -58
  217. package/src/engine/physics/cloth/playground/cloth_playground_build.d.ts.map +1 -1
  218. package/src/engine/physics/cloth/playground/cloth_playground_build.js +2 -3
  219. package/src/engine/physics/cloth/playground/collide_main.js +3 -29
  220. package/src/engine/physics/cloth/playground/garment_build.d.ts.map +1 -1
  221. package/src/engine/physics/cloth/playground/garment_build.js +17 -5
  222. package/src/engine/physics/cloth/playground/garment_main.js +5 -20
  223. package/src/engine/physics/cloth/playground/main.js +6 -48
  224. package/src/engine/physics/cloth/playground/rig_build.d.ts.map +1 -1
  225. package/src/engine/physics/cloth/playground/rig_build.js +302 -296
  226. package/src/engine/physics/cloth/playground/rig_main.js +947 -955
  227. package/src/engine/physics/cloth/playground/wind_main.js +8 -7
  228. package/src/engine/physics/cloth/solver/ClothState.d.ts +45 -7
  229. package/src/engine/physics/cloth/solver/ClothState.d.ts.map +1 -1
  230. package/src/engine/physics/cloth/solver/ClothState.js +79 -83
  231. package/src/engine/physics/cloth/solver/cloth_color_particles.d.ts +10 -8
  232. package/src/engine/physics/cloth/solver/cloth_color_particles.d.ts.map +1 -1
  233. package/src/engine/physics/cloth/solver/cloth_color_particles.js +30 -102
  234. package/src/engine/physics/cloth/solver/cloth_contact_find.d.ts +6 -1
  235. package/src/engine/physics/cloth/solver/cloth_contact_find.d.ts.map +1 -1
  236. package/src/engine/physics/cloth/solver/cloth_contact_find.js +9 -3
  237. package/src/engine/physics/cloth/solver/cloth_hold_line.d.ts +114 -0
  238. package/src/engine/physics/cloth/solver/cloth_hold_line.d.ts.map +1 -0
  239. package/src/engine/physics/cloth/solver/cloth_hold_line.js +350 -0
  240. package/src/engine/physics/cloth/solver/cloth_kinetic_energy.d.ts +21 -0
  241. package/src/engine/physics/cloth/solver/cloth_kinetic_energy.d.ts.map +1 -0
  242. package/src/engine/physics/cloth/solver/cloth_kinetic_energy.js +45 -0
  243. package/src/engine/physics/cloth/solver/cloth_particle_coupling.d.ts +32 -0
  244. package/src/engine/physics/cloth/solver/cloth_particle_coupling.d.ts.map +1 -0
  245. package/src/engine/physics/cloth/solver/cloth_particle_coupling.js +133 -0
  246. package/src/engine/physics/cloth/solver/cloth_particle_of_source.d.ts +16 -0
  247. package/src/engine/physics/cloth/solver/cloth_particle_of_source.d.ts.map +1 -0
  248. package/src/engine/physics/cloth/solver/cloth_particle_of_source.js +19 -0
  249. package/src/engine/physics/cloth/solver/cloth_self_find.d.ts +6 -2
  250. package/src/engine/physics/cloth/solver/cloth_self_find.d.ts.map +1 -1
  251. package/src/engine/physics/cloth/solver/cloth_self_find.js +19 -68
  252. package/src/engine/physics/cloth/solver/cloth_solve_vertex.d.ts.map +1 -1
  253. package/src/engine/physics/cloth/solver/cloth_solve_vertex.js +30 -65
  254. package/src/engine/physics/cloth/solver/cloth_solver_constants.d.ts +24 -12
  255. package/src/engine/physics/cloth/solver/cloth_solver_constants.d.ts.map +1 -1
  256. package/src/engine/physics/cloth/solver/cloth_solver_constants.js +24 -12
  257. package/src/engine/physics/cloth/solver/cloth_step.d.ts +16 -0
  258. package/src/engine/physics/cloth/solver/cloth_step.d.ts.map +1 -1
  259. package/src/engine/physics/cloth/solver/cloth_step.js +189 -48
  260. package/src/engine/physics/cloth/solver/cloth_step_instance.d.ts +1 -0
  261. package/src/engine/physics/cloth/solver/cloth_step_instance.d.ts.map +1 -1
  262. package/src/engine/physics/cloth/solver/cloth_step_instance.js +12 -6
  263. package/src/engine/physics/cloth/solver/cloth_stretch_residual.d.ts +21 -0
  264. package/src/engine/physics/cloth/solver/cloth_stretch_residual.d.ts.map +1 -0
  265. package/src/engine/physics/cloth/solver/cloth_stretch_residual.js +54 -0
  266. package/src/engine/physics/cloth/solver/cloth_vertex_accumulator.d.ts +15 -0
  267. package/src/engine/physics/cloth/solver/cloth_vertex_accumulator.d.ts.map +1 -1
  268. package/src/engine/physics/cloth/solver/cloth_vertex_accumulator.js +28 -0
  269. package/src/engine/physics/cloth/solver/cloth_worst_tether_ratio.d.ts +30 -0
  270. package/src/engine/physics/cloth/solver/cloth_worst_tether_ratio.d.ts.map +1 -0
  271. package/src/engine/physics/cloth/solver/cloth_worst_tether_ratio.js +56 -0
  272. package/src/engine/physics/cloth/solver/constraint/cloth_contact_row.d.ts.map +1 -1
  273. package/src/engine/physics/cloth/solver/constraint/cloth_contact_row.js +3 -17
  274. package/src/engine/physics/cloth/solver/constraint/cloth_leash_row.d.ts +1 -1
  275. package/src/engine/physics/cloth/solver/constraint/cloth_leash_row.d.ts.map +1 -1
  276. package/src/engine/physics/cloth/solver/constraint/cloth_leash_row.js +353 -346
  277. package/src/engine/physics/cloth/solver/constraint/cloth_self_row.d.ts +7 -5
  278. package/src/engine/physics/cloth/solver/constraint/cloth_self_row.d.ts.map +1 -1
  279. package/src/engine/physics/cloth/solver/constraint/cloth_self_row.js +7 -5
  280. package/src/engine/physics/cloth/wind/ClothFluidWind.d.ts +2 -1
  281. package/src/engine/physics/cloth/wind/ClothFluidWind.d.ts.map +1 -1
  282. package/src/engine/physics/cloth/wind/ClothFluidWind.js +7 -25
  283. package/src/engine/physics/cloth/wind/cloth_sample_air.d.ts +12 -10
  284. package/src/engine/physics/cloth/wind/cloth_sample_air.d.ts.map +1 -1
  285. package/src/engine/physics/cloth/wind/cloth_sample_air.js +60 -82
  286. package/src/engine/physics/ecs/ContactProbeSystem.d.ts.map +1 -1
  287. package/src/engine/physics/ecs/ContactProbeSystem.js +2 -18
  288. package/src/engine/physics/ecs/PhysicsSystem.d.ts.map +1 -1
  289. package/src/engine/physics/ecs/PhysicsSystem.js +9 -50
  290. package/src/engine/physics/fluid/ecs/FluidObstacleSystem.d.ts +4 -4
  291. package/src/engine/physics/fluid/ecs/fluid_sample_domain_bounds.d.ts +24 -0
  292. package/src/engine/physics/fluid/ecs/fluid_sample_domain_bounds.d.ts.map +1 -0
  293. package/src/engine/physics/fluid/ecs/fluid_sample_domain_bounds.js +42 -0
  294. package/src/engine/physics/fluid/ecs/fluid_sample_velocity_world_mps.d.ts +25 -0
  295. package/src/engine/physics/fluid/ecs/fluid_sample_velocity_world_mps.d.ts.map +1 -0
  296. package/src/engine/physics/fluid/ecs/fluid_sample_velocity_world_mps.js +40 -0
  297. package/src/engine/physics/inverse_kinematics/frame_fabrik/frame_fabrik_solve.d.ts.map +1 -1
  298. package/src/engine/physics/inverse_kinematics/frame_fabrik/frame_fabrik_solve.js +40 -90
  299. package/src/engine/physics/narrowphase/capsule_contacts.d.ts.map +1 -1
  300. package/src/engine/physics/narrowphase/capsule_contacts.js +3 -5
  301. package/src/engine/physics/narrowphase/decomposition/mesh_enumerate_triangles.d.ts.map +1 -1
  302. package/src/engine/physics/narrowphase/decomposition/mesh_enumerate_triangles.js +2 -14
  303. package/src/engine/physics/narrowphase/hull_sphere_contact.d.ts.map +1 -1
  304. package/src/engine/physics/narrowphase/hull_sphere_contact.js +2 -5
  305. package/src/engine/physics/narrowphase/narrowphase_step.d.ts.map +1 -1
  306. package/src/engine/physics/narrowphase/narrowphase_step.js +13 -32
  307. package/src/engine/physics/narrowphase/sphere_box_contact.d.ts.map +1 -1
  308. package/src/engine/physics/narrowphase/sphere_box_contact.js +2 -5
  309. package/src/engine/simulation/Ticker.d.ts +13 -0
  310. package/src/engine/simulation/Ticker.d.ts.map +1 -1
  311. package/src/engine/simulation/Ticker.js +43 -8
  312. package/src/format/texture/basis/transcode/etc1s_to_astc.d.ts.map +1 -1
  313. package/src/format/texture/basis/transcode/etc1s_to_astc.js +2 -1
  314. package/src/shade/RENDERER_CONTRACT.md +8 -2
  315. package/src/shade/playground/image_decode_bench/main.js +2 -1
  316. package/src/shade/playground/mesh_row_ceiling/main.js +2 -1
  317. package/src/shade/playground/skinned_blas_refit/diff_traced_against_rasterized.d.ts.map +1 -1
  318. package/src/shade/playground/skinned_blas_refit/diff_traced_against_rasterized.js +2 -1
  319. package/src/shade/playground/skinned_blas_refit/main.d.ts.map +1 -1
  320. package/src/shade/playground/skinned_blas_refit/main.js +11 -19
  321. package/src/shade/playground/skinned_blas_refit/place_character.d.ts +6 -3
  322. package/src/shade/playground/skinned_blas_refit/place_character.d.ts.map +1 -1
  323. package/src/shade/playground/skinned_blas_refit/place_character.js +90 -90
  324. package/src/shade/playground/skinned_mesh_soup/main.d.ts.map +1 -1
  325. package/src/shade/playground/skinned_mesh_soup/main.js +502 -509
  326. package/src/shade/playground/skinned_mesh_soup/verify_clone_vertices.d.ts.map +1 -1
  327. package/src/shade/playground/skinned_mesh_soup/verify_clone_vertices.js +2 -1
  328. package/src/shade/playground/ssr_variance/statistics.d.ts.map +1 -1
  329. package/src/shade/playground/ssr_variance/statistics.js +2 -1
  330. package/src/shade/playground/texture_encode/README.md +129 -109
  331. package/src/shade/playground/texture_encode/main.d.ts.map +1 -1
  332. package/src/shade/playground/texture_encode/main.js +1431 -1430
  333. package/src/shade/playground/volumetrics_froxel/measure.d.ts.map +1 -1
  334. package/src/shade/playground/volumetrics_froxel/measure.js +2 -1
  335. package/src/shade/renderer/animation/GPUAnimationManager.d.ts +45 -14
  336. package/src/shade/renderer/animation/GPUAnimationManager.d.ts.map +1 -1
  337. package/src/shade/renderer/animation/GPUAnimationManager.js +316 -64
  338. package/src/shade/renderer/animation/skinning/GPUMeshSkinningContext.d.ts +5 -0
  339. package/src/shade/renderer/animation/skinning/GPUMeshSkinningContext.d.ts.map +1 -1
  340. package/src/shade/renderer/animation/skinning/GPUMeshSkinningContext.js +11 -1
  341. package/src/shade/renderer/buffer/table/gpu_database_check_links.d.ts.map +1 -1
  342. package/src/shade/renderer/buffer/table/gpu_database_check_links.js +2 -1
  343. package/src/shade/renderer/geometry/BoxGeometry.d.ts +1 -11
  344. package/src/shade/renderer/geometry/BoxGeometry.d.ts.map +1 -1
  345. package/src/shade/renderer/geometry/BoxGeometry.js +6 -13
  346. package/src/shade/renderer/geometry/CapsuleGeometry.d.ts +19 -0
  347. package/src/shade/renderer/geometry/CapsuleGeometry.d.ts.map +1 -0
  348. package/src/shade/renderer/geometry/CapsuleGeometry.js +24 -0
  349. package/src/shade/renderer/geometry/ConeGeometry.d.ts +20 -0
  350. package/src/shade/renderer/geometry/ConeGeometry.d.ts.map +1 -0
  351. package/src/shade/renderer/geometry/ConeGeometry.js +33 -0
  352. package/src/shade/renderer/geometry/CylinderGeometry.d.ts +21 -0
  353. package/src/shade/renderer/geometry/CylinderGeometry.d.ts.map +1 -0
  354. package/src/shade/renderer/geometry/CylinderGeometry.js +35 -0
  355. package/src/shade/renderer/geometry/PlaneGeometry.d.ts +17 -0
  356. package/src/shade/renderer/geometry/PlaneGeometry.d.ts.map +1 -0
  357. package/src/shade/renderer/geometry/PlaneGeometry.js +22 -0
  358. package/src/shade/renderer/geometry/TorusGeometry.d.ts +18 -0
  359. package/src/shade/renderer/geometry/TorusGeometry.d.ts.map +1 -0
  360. package/src/shade/renderer/geometry/TorusGeometry.js +23 -0
  361. package/src/shade/renderer/geometry/UVSphereGeometry.d.ts +21 -0
  362. package/src/shade/renderer/geometry/UVSphereGeometry.d.ts.map +1 -0
  363. package/src/shade/renderer/geometry/UVSphereGeometry.js +34 -0
  364. package/src/shade/renderer/geometry/primitives/make_capsule_geometry.d.ts +19 -0
  365. package/src/shade/renderer/geometry/primitives/make_capsule_geometry.d.ts.map +1 -0
  366. package/src/shade/renderer/geometry/primitives/make_capsule_geometry.js +205 -0
  367. package/src/shade/renderer/geometry/primitives/make_cone_geometry.d.ts +21 -0
  368. package/src/shade/renderer/geometry/primitives/make_cone_geometry.d.ts.map +1 -0
  369. package/src/shade/renderer/geometry/primitives/make_cone_geometry.js +36 -0
  370. package/src/shade/renderer/geometry/primitives/make_cylinder_geometry.d.ts +1 -1
  371. package/src/shade/renderer/geometry/primitives/make_cylinder_geometry.d.ts.map +1 -1
  372. package/src/shade/renderer/geometry/primitives/make_cylinder_geometry.js +44 -9
  373. package/src/shade/renderer/geometry/primitives/make_uv_sphere_geometry.d.ts +20 -0
  374. package/src/shade/renderer/geometry/primitives/make_uv_sphere_geometry.d.ts.map +1 -0
  375. package/src/shade/renderer/geometry/primitives/make_uv_sphere_geometry.js +190 -0
  376. package/src/shade/renderer/geometry/virtual/build/level/vgeo_build_group_step.d.ts.map +1 -1
  377. package/src/shade/renderer/geometry/virtual/build/level/vgeo_build_group_step.js +3 -2
  378. package/src/shade/renderer/geometry/virtual/build/level/vgeo_build_leaf_frontier.d.ts.map +1 -1
  379. package/src/shade/renderer/geometry/virtual/build/level/vgeo_build_leaf_frontier.js +2 -1
  380. package/src/shade/renderer/geometry/virtual/build/level/vgeo_partition_into_groups.d.ts.map +1 -1
  381. package/src/shade/renderer/geometry/virtual/build/level/vgeo_partition_into_groups.js +2 -1
  382. package/src/shade/renderer/geometry/virtual/build/level/vgeo_run_round.d.ts.map +1 -1
  383. package/src/shade/renderer/geometry/virtual/build/level/vgeo_run_round.js +2 -1
  384. package/src/shade/renderer/geometry/virtual/build/level/vgeo_try_repack.d.ts.map +1 -1
  385. package/src/shade/renderer/geometry/virtual/build/level/vgeo_try_repack.js +3 -2
  386. package/src/shade/renderer/geometry/virtual/build/partition/vgeo_graph_components.d.ts.map +1 -1
  387. package/src/shade/renderer/geometry/virtual/build/partition/vgeo_graph_components.js +2 -1
  388. package/src/shade/renderer/geometry/virtual/build/partition/vgeo_split_face_set_packed.d.ts.map +1 -1
  389. package/src/shade/renderer/geometry/virtual/build/partition/vgeo_split_face_set_packed.js +2 -1
  390. package/src/shade/renderer/geometry/virtual/format/vgeo_write_container.d.ts.map +1 -1
  391. package/src/shade/renderer/geometry/virtual/format/vgeo_write_container.js +3 -2
  392. package/src/shade/renderer/geometry/virtual/runtime/graph_vgeo_expand_instances_to_meshlets.d.ts.map +1 -1
  393. package/src/shade/renderer/geometry/virtual/runtime/graph_vgeo_expand_instances_to_meshlets.js +7 -2
  394. package/src/shade/renderer/gpu_primitive/prefix_sum/v1/graph_prefix_scan_csdldf.d.ts +26 -8
  395. package/src/shade/renderer/gpu_primitive/prefix_sum/v1/graph_prefix_scan_csdldf.d.ts.map +1 -1
  396. package/src/shade/renderer/gpu_primitive/prefix_sum/v1/graph_prefix_scan_csdldf.js +56 -39
  397. package/src/shade/renderer/gpu_primitive/prefix_sum/v1/shader_prefix_scan_csdldf.d.ts +7 -0
  398. package/src/shade/renderer/gpu_primitive/prefix_sum/v1/shader_prefix_scan_csdldf.d.ts.map +1 -1
  399. package/src/shade/renderer/gpu_primitive/prefix_sum/v1/shader_prefix_scan_csdldf.js +46 -4
  400. package/src/shade/renderer/gpu_primitive/prefix_sum/v1/test_prefix_sum.d.ts.map +1 -1
  401. package/src/shade/renderer/gpu_primitive/prefix_sum/v1/test_prefix_sum.js +4 -2
  402. package/src/shade/renderer/gpu_primitive/sort/defs.d.ts +2 -2
  403. package/src/shade/renderer/gpu_primitive/sort/defs.js +79 -79
  404. package/src/shade/renderer/gpu_primitive/sort/graph_radix_sort.d.ts +1 -1
  405. package/src/shade/renderer/gpu_primitive/sort/graph_radix_sort.d.ts.map +1 -1
  406. package/src/shade/renderer/gpu_primitive/sort/graph_radix_sort.js +7 -3
  407. package/src/shade/renderer/particles/GPUParticleSystem.js +1 -1
  408. package/src/shade/renderer/particles/coherence/graph_particle_bucket.d.ts +4 -3
  409. package/src/shade/renderer/particles/coherence/graph_particle_bucket.d.ts.map +1 -1
  410. package/src/shade/renderer/particles/coherence/graph_particle_bucket.js +200 -194
  411. package/src/shade/renderer/particles/graph_particles.d.ts.map +1 -1
  412. package/src/shade/renderer/particles/graph_particles.js +6 -2
  413. package/src/shade/renderer/particles/optimizer/dag/particle_vector_extract.d.ts.map +1 -1
  414. package/src/shade/renderer/particles/optimizer/dag/particle_vector_extract.js +3 -2
  415. package/src/shade/renderer/particles/warmup/graph_particle_warmup.d.ts.map +1 -1
  416. package/src/shade/renderer/particles/warmup/graph_particle_warmup.js +334 -329
  417. package/src/shade/renderer/rasterize/bucket/prepare_meshlet_draw_commands_by_material.d.ts.map +1 -1
  418. package/src/shade/renderer/rasterize/bucket/prepare_meshlet_draw_commands_by_material.js +7 -2
  419. package/src/shade/renderer/rasterize/expand/mesh/graph_expand_meshes_to_meshlets.d.ts.map +1 -1
  420. package/src/shade/renderer/rasterize/expand/mesh/graph_expand_meshes_to_meshlets.js +16 -4
  421. package/src/shade/renderer/texture/COMPRESSED_TEXTURE_PLAN_2026_09_01.md +2444 -2345
  422. package/src/shade/renderer/texture/encode/chunk_astc_encode_block_4x4_rgb.d.ts.map +1 -1
  423. package/src/shade/renderer/texture/encode/chunk_astc_encode_block_4x4_rgb.js +312 -310
  424. package/src/shade/renderer/texture/encode/chunk_bc1_encode_block.d.ts +3 -3
  425. package/src/shade/renderer/texture/encode/chunk_bc1_encode_block.d.ts.map +1 -1
  426. package/src/shade/renderer/texture/encode/chunk_bc1_encode_block.js +383 -375
  427. package/src/shade/renderer/texture/encode/chunk_bc6h_encode_block_mode11.d.ts.map +1 -1
  428. package/src/shade/renderer/texture/encode/chunk_bc6h_encode_block_mode11.js +349 -346
  429. package/src/shade/renderer/texture/encode/chunk_bc7_encode_block.d.ts +58 -0
  430. package/src/shade/renderer/texture/encode/chunk_bc7_encode_block.d.ts.map +1 -0
  431. package/src/shade/renderer/texture/encode/chunk_bc7_encode_block.js +536 -0
  432. package/src/shade/renderer/texture/encode/chunk_bc7_encode_block_mode6.d.ts +21 -7
  433. package/src/shade/renderer/texture/encode/chunk_bc7_encode_block_mode6.d.ts.map +1 -1
  434. package/src/shade/renderer/texture/encode/chunk_bc7_encode_block_mode6.js +291 -327
  435. package/src/shade/renderer/texture/encode/chunk_bc7_pack_mode1.d.ts +25 -0
  436. package/src/shade/renderer/texture/encode/chunk_bc7_pack_mode1.d.ts.map +1 -0
  437. package/src/shade/renderer/texture/encode/chunk_bc7_pack_mode1.js +99 -0
  438. package/src/shade/renderer/texture/encode/chunk_bc7_pack_mode6.d.ts +5 -3
  439. package/src/shade/renderer/texture/encode/chunk_bc7_pack_mode6.d.ts.map +1 -1
  440. package/src/shade/renderer/texture/encode/chunk_bc7_pack_mode6.js +47 -71
  441. package/src/shade/renderer/texture/encode/chunk_bc7_partition_2.d.ts +10 -0
  442. package/src/shade/renderer/texture/encode/chunk_bc7_partition_2.d.ts.map +1 -0
  443. package/src/shade/renderer/texture/encode/chunk_bc7_partition_2.js +50 -0
  444. package/src/shade/renderer/texture/encode/shader_texture_encode_bc7.d.ts +4 -5
  445. package/src/shade/renderer/texture/encode/shader_texture_encode_bc7.d.ts.map +1 -1
  446. package/src/shade/renderer/texture/encode/shader_texture_encode_bc7.js +7 -8
  447. package/src/shade/renderer/water/chunk_water_transport.d.ts.map +1 -1
  448. package/src/shade/renderer/water/chunk_water_transport.js +7 -5
  449. package/src/shade/renderer/water/medium/GPUWaterBodies.d.ts.map +1 -1
  450. package/src/shade/renderer/water/medium/GPUWaterBodies.js +8 -2
  451. package/src/shade/renderer/water/optics/chunk_water_receiver_downwelling.d.ts +3 -2
  452. package/src/shade/renderer/water/optics/chunk_water_receiver_downwelling.d.ts.map +1 -1
  453. package/src/shade/renderer/water/optics/chunk_water_receiver_downwelling.js +3 -2
  454. package/src/shade/renderer/water/shader_water.d.ts.map +1 -1
  455. package/src/shade/renderer/water/shader_water.js +3 -1
  456. package/src/shade/renderer/water/surface/GPUWaterSurface.d.ts.map +1 -1
  457. package/src/shade/renderer/water/surface/GPUWaterSurface.js +3 -1
  458. package/src/shade/renderer/water/surface/graph_water_tessellation.d.ts.map +1 -1
  459. package/src/shade/renderer/water/surface/graph_water_tessellation.js +11 -4
  460. package/src/shade/renderer/water/surface/particles/GPUWaterParticles.d.ts.map +1 -1
  461. package/src/shade/renderer/water/surface/particles/GPUWaterParticles.js +37 -20
  462. package/src/shade/wgsl/validate_wgsl_source.d.ts.map +1 -1
  463. package/src/shade/wgsl/validate_wgsl_source.js +74 -3
  464. package/src/engine/graphics3/register_instance_animation.d.ts +0 -114
  465. package/src/engine/graphics3/register_instance_animation.d.ts.map +0 -1
  466. 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. The partitioned modes
10
- * are a later quality step and a separate chunk, not a change to this one.
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. Two rounds of least squares with the sixteen decode weights shared across channels, each
17
- * texel assigned by its projection and the neighbouring weight checked by distance.
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
- * and the best is kept. Then one round of coordinate descent over the eight stored components,
21
- * stepping by two so the parity holds, keeping any step that lowers the block's error.
22
- * 4. **The anchor.** Texel 0's index is stored a bit short, so its top bit must be zero: when it
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;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AACH,2CAFU,SAAS,CAoSZ;0BAtUmB,oCAAoC"}
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"}