@woosh/meep-engine 3.42.0 → 3.44.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 (345) hide show
  1. package/editor/prototypeEditorShell.d.ts.map +1 -1
  2. package/editor/prototypeEditorShell.js +4 -2
  3. package/package.json +91 -96
  4. package/src/engine/Clock.d.ts +15 -0
  5. package/src/engine/Clock.d.ts.map +1 -1
  6. package/src/engine/Clock.js +29 -5
  7. package/src/engine/Engine.d.ts.map +1 -1
  8. package/src/engine/Engine.js +11 -19
  9. package/src/engine/graphics/ecs/mesh-v2/MeshSkin.d.ts +57 -0
  10. package/src/engine/graphics/ecs/mesh-v2/MeshSkin.d.ts.map +1 -0
  11. package/src/engine/graphics/ecs/mesh-v2/MeshSkin.js +84 -0
  12. package/src/engine/graphics3/AnimationGraphSystem.d.ts +23 -13
  13. package/src/engine/graphics3/AnimationGraphSystem.d.ts.map +1 -1
  14. package/src/engine/graphics3/AnimationGraphSystem.js +61 -64
  15. package/src/engine/graphics3/AnimationSystem.d.ts +24 -15
  16. package/src/engine/graphics3/AnimationSystem.d.ts.map +1 -1
  17. package/src/engine/graphics3/AnimationSystem.js +67 -61
  18. package/src/engine/graphics3/MeshSkinSystem.d.ts +56 -0
  19. package/src/engine/graphics3/MeshSkinSystem.d.ts.map +1 -0
  20. package/src/engine/graphics3/MeshSkinSystem.js +317 -0
  21. package/src/engine/graphics3/MeshSystem.d.ts +15 -35
  22. package/src/engine/graphics3/MeshSystem.d.ts.map +1 -1
  23. package/src/engine/graphics3/MeshSystem.js +21 -298
  24. package/src/engine/graphics3/RowChains.d.ts +76 -0
  25. package/src/engine/graphics3/RowChains.d.ts.map +1 -0
  26. package/src/engine/graphics3/RowChains.js +347 -0
  27. package/src/engine/graphics3/ShadedGeometrySystem.d.ts +6 -0
  28. package/src/engine/graphics3/ShadedGeometrySystem.d.ts.map +1 -1
  29. package/src/engine/graphics3/ShadedGeometrySystem.js +329 -309
  30. package/src/engine/graphics3/animation/AnimationClips.d.ts +56 -0
  31. package/src/engine/graphics3/animation/AnimationClips.d.ts.map +1 -0
  32. package/src/engine/graphics3/animation/AnimationClips.js +79 -0
  33. package/src/engine/graphics3/animation/ClipListPlayer.d.ts +13 -14
  34. package/src/engine/graphics3/animation/ClipListPlayer.d.ts.map +1 -1
  35. package/src/engine/graphics3/animation/ClipListPlayer.js +262 -263
  36. package/src/engine/graphics3/animation/write_clip_playback.d.ts +3 -3
  37. package/src/engine/graphics3/animation/write_clip_playback.js +4 -4
  38. package/src/engine/graphics3/pose/query_entity_node_world_pose.d.ts +5 -0
  39. package/src/engine/graphics3/pose/query_entity_node_world_pose.d.ts.map +1 -1
  40. package/src/engine/graphics3/pose/query_entity_node_world_pose.js +80 -75
  41. package/src/engine/graphics3/prefab/PrefabInstance.d.ts +4 -24
  42. package/src/engine/graphics3/prefab/PrefabInstance.d.ts.map +1 -1
  43. package/src/engine/graphics3/prefab/PrefabInstance.js +60 -80
  44. package/src/engine/graphics3/prefab/prefab_instantiate.d.ts +16 -3
  45. package/src/engine/graphics3/prefab/prefab_instantiate.d.ts.map +1 -1
  46. package/src/engine/graphics3/prefab/prefab_instantiate.js +49 -12
  47. package/src/engine/graphics3/prefab/prefab_place.d.ts +31 -17
  48. package/src/engine/graphics3/prefab/prefab_place.d.ts.map +1 -1
  49. package/src/engine/graphics3/prefab/prefab_place.js +175 -130
  50. package/src/engine/graphics3/register_clips.d.ts +64 -0
  51. package/src/engine/graphics3/register_clips.d.ts.map +1 -0
  52. package/src/engine/graphics3/register_clips.js +114 -0
  53. package/src/engine/physics/cloth/MEASUREMENTS.md +795 -0
  54. package/src/engine/physics/cloth/PLAN.md +339 -9
  55. package/src/engine/physics/cloth/build/ClothProxy.d.ts +113 -61
  56. package/src/engine/physics/cloth/build/ClothProxy.d.ts.map +1 -1
  57. package/src/engine/physics/cloth/build/ClothProxy.js +142 -77
  58. package/src/engine/physics/cloth/build/cloth_bind_in_frame.d.ts +22 -0
  59. package/src/engine/physics/cloth/build/cloth_bind_in_frame.d.ts.map +1 -0
  60. package/src/engine/physics/cloth/build/cloth_bind_in_frame.js +75 -0
  61. package/src/engine/physics/cloth/build/cloth_proxy_from_joints.d.ts +43 -30
  62. package/src/engine/physics/cloth/build/cloth_proxy_from_joints.d.ts.map +1 -1
  63. package/src/engine/physics/cloth/build/cloth_proxy_from_joints.js +357 -284
  64. package/src/engine/physics/cloth/build/cloth_proxy_from_mesh.d.ts +62 -0
  65. package/src/engine/physics/cloth/build/cloth_proxy_from_mesh.d.ts.map +1 -0
  66. package/src/engine/physics/cloth/build/cloth_proxy_from_mesh.js +280 -0
  67. package/src/engine/physics/cloth/collider/cloth_collider_sdf.d.ts +1 -1
  68. package/src/engine/physics/cloth/collider/cloth_collider_sdf.js +1 -1
  69. package/src/engine/physics/cloth/ecs/Cloth.d.ts +17 -9
  70. package/src/engine/physics/cloth/ecs/Cloth.d.ts.map +1 -1
  71. package/src/engine/physics/cloth/ecs/Cloth.js +220 -212
  72. package/src/engine/physics/cloth/ecs/ClothDynamicsFlags.js +6 -0
  73. package/src/engine/physics/cloth/ecs/ClothHold.d.ts +91 -0
  74. package/src/engine/physics/cloth/ecs/ClothHold.d.ts.map +1 -0
  75. package/src/engine/physics/cloth/ecs/ClothHold.js +103 -0
  76. package/src/engine/physics/cloth/ecs/ClothInstance.d.ts +254 -48
  77. package/src/engine/physics/cloth/ecs/ClothInstance.d.ts.map +1 -1
  78. package/src/engine/physics/cloth/ecs/ClothInstance.js +277 -47
  79. package/src/engine/physics/cloth/ecs/ClothPin.d.ts +73 -0
  80. package/src/engine/physics/cloth/ecs/ClothPin.d.ts.map +1 -0
  81. package/src/engine/physics/cloth/ecs/ClothPin.js +92 -0
  82. package/src/engine/physics/cloth/ecs/ClothPinSerializationAdapter.d.ts +36 -0
  83. package/src/engine/physics/cloth/ecs/ClothPinSerializationAdapter.d.ts.map +1 -0
  84. package/src/engine/physics/cloth/ecs/ClothPinSerializationAdapter.js +61 -0
  85. package/src/engine/physics/cloth/ecs/ClothRig.d.ts +23 -17
  86. package/src/engine/physics/cloth/ecs/ClothRig.d.ts.map +1 -1
  87. package/src/engine/physics/cloth/ecs/ClothRig.js +29 -27
  88. package/src/engine/physics/cloth/ecs/ClothSystem.d.ts +12 -14
  89. package/src/engine/physics/cloth/ecs/ClothSystem.d.ts.map +1 -1
  90. package/src/engine/physics/cloth/ecs/ClothSystem.js +20 -15
  91. package/src/engine/physics/cloth/ecs/ClothWorld.d.ts +57 -36
  92. package/src/engine/physics/cloth/ecs/ClothWorld.d.ts.map +1 -1
  93. package/src/engine/physics/cloth/ecs/ClothWorld.js +816 -179
  94. package/src/engine/physics/cloth/ecs/WorkerClothSystem.d.ts +12 -13
  95. package/src/engine/physics/cloth/ecs/WorkerClothSystem.d.ts.map +1 -1
  96. package/src/engine/physics/cloth/ecs/WorkerClothSystem.js +20 -14
  97. package/src/engine/physics/cloth/ecs/cloth_build_rows.d.ts +63 -11
  98. package/src/engine/physics/cloth/ecs/cloth_build_rows.d.ts.map +1 -1
  99. package/src/engine/physics/cloth/ecs/cloth_build_rows.js +321 -84
  100. package/src/engine/physics/cloth/ecs/cloth_dynamics_map.d.ts +9 -7
  101. package/src/engine/physics/cloth/ecs/cloth_dynamics_map.d.ts.map +1 -1
  102. package/src/engine/physics/cloth/ecs/cloth_dynamics_map.js +9 -7
  103. package/src/engine/physics/cloth/ecs/cloth_gather_colliders.d.ts +3 -3
  104. package/src/engine/physics/cloth/ecs/cloth_gather_colliders.js +30 -30
  105. package/src/engine/physics/cloth/ecs/cloth_geodesic.d.ts +37 -0
  106. package/src/engine/physics/cloth/ecs/cloth_geodesic.d.ts.map +1 -0
  107. package/src/engine/physics/cloth/ecs/cloth_geodesic.js +142 -0
  108. package/src/engine/physics/cloth/ecs/cloth_holds.d.ts +97 -0
  109. package/src/engine/physics/cloth/ecs/cloth_holds.d.ts.map +1 -0
  110. package/src/engine/physics/cloth/ecs/cloth_holds.js +608 -0
  111. package/src/engine/physics/cloth/ecs/cloth_reconstruct_pose.d.ts +2 -2
  112. package/src/engine/physics/cloth/ecs/cloth_reconstruct_pose.d.ts.map +1 -1
  113. package/src/engine/physics/cloth/ecs/cloth_reconstruct_pose.js +160 -9
  114. package/src/engine/physics/cloth/ecs/cloth_seed_rig.d.ts +17 -22
  115. package/src/engine/physics/cloth/ecs/cloth_seed_rig.d.ts.map +1 -1
  116. package/src/engine/physics/cloth/ecs/cloth_seed_rig.js +55 -117
  117. package/src/engine/physics/cloth/ecs/cloth_seed_subtree.d.ts +21 -6
  118. package/src/engine/physics/cloth/ecs/cloth_seed_subtree.d.ts.map +1 -1
  119. package/src/engine/physics/cloth/ecs/cloth_seed_subtree.js +44 -15
  120. package/src/engine/physics/cloth/ecs/cloth_write_back.d.ts +5 -0
  121. package/src/engine/physics/cloth/ecs/cloth_write_back.d.ts.map +1 -1
  122. package/src/engine/physics/cloth/ecs/cloth_write_back.js +60 -16
  123. package/src/engine/physics/cloth/ecs/cloth_write_back_rig.d.ts.map +1 -1
  124. package/src/engine/physics/cloth/ecs/cloth_write_back_rig.js +65 -58
  125. package/src/engine/physics/cloth/playground/collide_main.js +1 -1
  126. package/src/engine/physics/cloth/playground/garment_build.d.ts.map +1 -1
  127. package/src/engine/physics/cloth/playground/garment_build.js +17 -5
  128. package/src/engine/physics/cloth/playground/garment_main.js +1 -1
  129. package/src/engine/physics/cloth/playground/rig_build.d.ts.map +1 -1
  130. package/src/engine/physics/cloth/playground/rig_build.js +302 -296
  131. package/src/engine/physics/cloth/solver/ClothState.d.ts +45 -7
  132. package/src/engine/physics/cloth/solver/ClothState.d.ts.map +1 -1
  133. package/src/engine/physics/cloth/solver/ClothState.js +63 -7
  134. package/src/engine/physics/cloth/solver/cloth_contact_find.d.ts +6 -1
  135. package/src/engine/physics/cloth/solver/cloth_contact_find.d.ts.map +1 -1
  136. package/src/engine/physics/cloth/solver/cloth_contact_find.js +7 -2
  137. package/src/engine/physics/cloth/solver/cloth_hold_line.d.ts +114 -0
  138. package/src/engine/physics/cloth/solver/cloth_hold_line.d.ts.map +1 -0
  139. package/src/engine/physics/cloth/solver/cloth_hold_line.js +362 -0
  140. package/src/engine/physics/cloth/solver/cloth_self_find.d.ts +6 -2
  141. package/src/engine/physics/cloth/solver/cloth_self_find.d.ts.map +1 -1
  142. package/src/engine/physics/cloth/solver/cloth_self_find.js +13 -13
  143. package/src/engine/physics/cloth/solver/cloth_solver_constants.d.ts +24 -12
  144. package/src/engine/physics/cloth/solver/cloth_solver_constants.d.ts.map +1 -1
  145. package/src/engine/physics/cloth/solver/cloth_solver_constants.js +24 -12
  146. package/src/engine/physics/cloth/solver/cloth_step.d.ts +16 -0
  147. package/src/engine/physics/cloth/solver/cloth_step.d.ts.map +1 -1
  148. package/src/engine/physics/cloth/solver/cloth_step.js +183 -20
  149. package/src/engine/physics/cloth/solver/cloth_step_instance.d.ts +1 -0
  150. package/src/engine/physics/cloth/solver/cloth_step_instance.d.ts.map +1 -1
  151. package/src/engine/physics/cloth/solver/cloth_step_instance.js +10 -3
  152. package/src/engine/physics/cloth/solver/constraint/cloth_leash_row.d.ts +1 -1
  153. package/src/engine/physics/cloth/solver/constraint/cloth_leash_row.d.ts.map +1 -1
  154. package/src/engine/physics/cloth/solver/constraint/cloth_leash_row.js +353 -346
  155. package/src/engine/physics/cloth/solver/constraint/cloth_self_row.d.ts +7 -5
  156. package/src/engine/physics/cloth/solver/constraint/cloth_self_row.d.ts.map +1 -1
  157. package/src/engine/physics/cloth/solver/constraint/cloth_self_row.js +7 -5
  158. package/src/engine/physics/cloth/wind/cloth_sample_air.d.ts +9 -9
  159. package/src/engine/physics/cloth/wind/cloth_sample_air.d.ts.map +1 -1
  160. package/src/engine/physics/cloth/wind/cloth_sample_air.js +26 -26
  161. package/src/engine/physics/fluid/ecs/FluidObstacleSystem.d.ts +4 -4
  162. package/src/engine/simulation/Ticker.d.ts +13 -0
  163. package/src/engine/simulation/Ticker.d.ts.map +1 -1
  164. package/src/engine/simulation/Ticker.js +43 -8
  165. package/src/shade/RENDERER_CONTRACT.md +8 -2
  166. package/src/shade/playground/mesh_row_ceiling/main.js +2 -1
  167. package/src/shade/playground/skinned_blas_refit/main.d.ts.map +1 -1
  168. package/src/shade/playground/skinned_blas_refit/main.js +11 -19
  169. package/src/shade/playground/skinned_blas_refit/place_character.d.ts +6 -3
  170. package/src/shade/playground/skinned_blas_refit/place_character.d.ts.map +1 -1
  171. package/src/shade/playground/skinned_blas_refit/place_character.js +90 -90
  172. package/src/shade/playground/skinned_mesh_soup/main.d.ts.map +1 -1
  173. package/src/shade/playground/skinned_mesh_soup/main.js +502 -509
  174. package/src/shade/playground/texture_encode/README.md +129 -109
  175. package/src/shade/playground/texture_encode/main.js +1430 -1430
  176. package/src/shade/playground/vgeo_runtime/README.md +5 -4
  177. package/src/shade/renderer/Renderer.d.ts.map +1 -1
  178. package/src/shade/renderer/Renderer.js +6 -5
  179. package/src/shade/renderer/animation/GPUAnimationManager.d.ts +45 -14
  180. package/src/shade/renderer/animation/GPUAnimationManager.d.ts.map +1 -1
  181. package/src/shade/renderer/animation/GPUAnimationManager.js +316 -64
  182. package/src/shade/renderer/animation/skinning/GPUMeshSkinningContext.d.ts +5 -0
  183. package/src/shade/renderer/animation/skinning/GPUMeshSkinningContext.d.ts.map +1 -1
  184. package/src/shade/renderer/animation/skinning/GPUMeshSkinningContext.js +11 -1
  185. package/src/shade/renderer/atmosphere/GPUSky.d.ts +12 -0
  186. package/src/shade/renderer/atmosphere/GPUSky.d.ts.map +1 -1
  187. package/src/shade/renderer/atmosphere/GPUSky.js +162 -147
  188. package/src/shade/renderer/geometry/BoxGeometry.d.ts +1 -11
  189. package/src/shade/renderer/geometry/BoxGeometry.d.ts.map +1 -1
  190. package/src/shade/renderer/geometry/BoxGeometry.js +6 -13
  191. package/src/shade/renderer/geometry/CapsuleGeometry.d.ts +19 -0
  192. package/src/shade/renderer/geometry/CapsuleGeometry.d.ts.map +1 -0
  193. package/src/shade/renderer/geometry/CapsuleGeometry.js +24 -0
  194. package/src/shade/renderer/geometry/ConeGeometry.d.ts +20 -0
  195. package/src/shade/renderer/geometry/ConeGeometry.d.ts.map +1 -0
  196. package/src/shade/renderer/geometry/ConeGeometry.js +33 -0
  197. package/src/shade/renderer/geometry/CylinderGeometry.d.ts +21 -0
  198. package/src/shade/renderer/geometry/CylinderGeometry.d.ts.map +1 -0
  199. package/src/shade/renderer/geometry/CylinderGeometry.js +35 -0
  200. package/src/shade/renderer/geometry/PlaneGeometry.d.ts +17 -0
  201. package/src/shade/renderer/geometry/PlaneGeometry.d.ts.map +1 -0
  202. package/src/shade/renderer/geometry/PlaneGeometry.js +22 -0
  203. package/src/shade/renderer/geometry/TorusGeometry.d.ts +18 -0
  204. package/src/shade/renderer/geometry/TorusGeometry.d.ts.map +1 -0
  205. package/src/shade/renderer/geometry/TorusGeometry.js +23 -0
  206. package/src/shade/renderer/geometry/UVSphereGeometry.d.ts +21 -0
  207. package/src/shade/renderer/geometry/UVSphereGeometry.d.ts.map +1 -0
  208. package/src/shade/renderer/geometry/UVSphereGeometry.js +34 -0
  209. package/src/shade/renderer/geometry/primitives/make_capsule_geometry.d.ts +19 -0
  210. package/src/shade/renderer/geometry/primitives/make_capsule_geometry.d.ts.map +1 -0
  211. package/src/shade/renderer/geometry/primitives/make_capsule_geometry.js +205 -0
  212. package/src/shade/renderer/geometry/primitives/make_cone_geometry.d.ts +21 -0
  213. package/src/shade/renderer/geometry/primitives/make_cone_geometry.d.ts.map +1 -0
  214. package/src/shade/renderer/geometry/primitives/make_cone_geometry.js +36 -0
  215. package/src/shade/renderer/geometry/primitives/make_cylinder_geometry.d.ts +1 -1
  216. package/src/shade/renderer/geometry/primitives/make_cylinder_geometry.d.ts.map +1 -1
  217. package/src/shade/renderer/geometry/primitives/make_cylinder_geometry.js +44 -9
  218. package/src/shade/renderer/geometry/primitives/make_uv_sphere_geometry.d.ts +20 -0
  219. package/src/shade/renderer/geometry/primitives/make_uv_sphere_geometry.d.ts.map +1 -0
  220. package/src/shade/renderer/geometry/primitives/make_uv_sphere_geometry.js +190 -0
  221. package/src/shade/renderer/geometry/virtual/runtime/graph_vgeo_expand_instances_to_meshlets.d.ts.map +1 -1
  222. package/src/shade/renderer/geometry/virtual/runtime/graph_vgeo_expand_instances_to_meshlets.js +7 -2
  223. package/src/shade/renderer/gpu_primitive/prefix_sum/v1/graph_prefix_scan_csdldf.d.ts +26 -8
  224. package/src/shade/renderer/gpu_primitive/prefix_sum/v1/graph_prefix_scan_csdldf.d.ts.map +1 -1
  225. package/src/shade/renderer/gpu_primitive/prefix_sum/v1/graph_prefix_scan_csdldf.js +56 -39
  226. package/src/shade/renderer/gpu_primitive/prefix_sum/v1/shader_prefix_scan_csdldf.d.ts +7 -0
  227. package/src/shade/renderer/gpu_primitive/prefix_sum/v1/shader_prefix_scan_csdldf.d.ts.map +1 -1
  228. package/src/shade/renderer/gpu_primitive/prefix_sum/v1/shader_prefix_scan_csdldf.js +46 -4
  229. package/src/shade/renderer/gpu_primitive/prefix_sum/v1/test_prefix_sum.d.ts.map +1 -1
  230. package/src/shade/renderer/gpu_primitive/prefix_sum/v1/test_prefix_sum.js +4 -2
  231. package/src/shade/renderer/gpu_primitive/sort/defs.d.ts +2 -2
  232. package/src/shade/renderer/gpu_primitive/sort/defs.js +79 -79
  233. package/src/shade/renderer/gpu_primitive/sort/graph_radix_sort.d.ts +1 -1
  234. package/src/shade/renderer/gpu_primitive/sort/graph_radix_sort.d.ts.map +1 -1
  235. package/src/shade/renderer/gpu_primitive/sort/graph_radix_sort.js +7 -3
  236. package/src/shade/renderer/lightmap/bake/shader_lightmap_denoise_sh.d.ts.map +1 -1
  237. package/src/shade/renderer/lightmap/bake/shader_lightmap_denoise_sh.js +10 -3
  238. package/src/shade/renderer/loader/gltf/tiny-gltf.d.ts +1 -1
  239. package/src/shade/renderer/particles/DESIGN.md +13 -9
  240. package/src/shade/renderer/particles/GPUParticleSystem.js +1 -1
  241. package/src/shade/renderer/particles/coherence/graph_particle_bucket.d.ts +4 -3
  242. package/src/shade/renderer/particles/coherence/graph_particle_bucket.d.ts.map +1 -1
  243. package/src/shade/renderer/particles/coherence/graph_particle_bucket.js +200 -194
  244. package/src/shade/renderer/particles/graph_particles.d.ts.map +1 -1
  245. package/src/shade/renderer/particles/graph_particles.js +6 -2
  246. package/src/shade/renderer/particles/shaders/chunk_particle_lighting.d.ts +1 -1
  247. package/src/shade/renderer/particles/shaders/chunk_particle_lighting.js +1 -1
  248. package/src/shade/renderer/particles/warmup/graph_particle_warmup.d.ts.map +1 -1
  249. package/src/shade/renderer/particles/warmup/graph_particle_warmup.js +334 -329
  250. package/src/shade/renderer/postprocess/nss/NSS.d.ts +1 -1
  251. package/src/shade/renderer/rasterize/bucket/prepare_meshlet_draw_commands_by_material.d.ts.map +1 -1
  252. package/src/shade/renderer/rasterize/bucket/prepare_meshlet_draw_commands_by_material.js +7 -2
  253. package/src/shade/renderer/rasterize/expand/mesh/graph_expand_meshes_to_meshlets.d.ts.map +1 -1
  254. package/src/shade/renderer/rasterize/expand/mesh/graph_expand_meshes_to_meshlets.js +16 -4
  255. package/src/shade/renderer/rasterize/native/avboit/AVBOITSideChannel.d.ts +3 -2
  256. package/src/shade/renderer/rasterize/native/avboit/AVBOITSideChannel.d.ts.map +1 -1
  257. package/src/shade/renderer/rasterize/native/avboit/AVBOITSideChannel.js +3 -2
  258. package/src/shade/renderer/scene/GPUSceneContext.d.ts +9 -1
  259. package/src/shade/renderer/scene/GPUSceneContext.d.ts.map +1 -1
  260. package/src/shade/renderer/scene/GPUSceneContext.js +23 -1
  261. package/src/shade/renderer/texture/COMPRESSED_TEXTURE_PLAN_2026_09_01.md +2444 -2345
  262. package/src/shade/renderer/texture/encode/chunk_astc_encode_block_4x4_rgb.d.ts.map +1 -1
  263. package/src/shade/renderer/texture/encode/chunk_astc_encode_block_4x4_rgb.js +312 -310
  264. package/src/shade/renderer/texture/encode/chunk_bc1_encode_block.d.ts +3 -3
  265. package/src/shade/renderer/texture/encode/chunk_bc1_encode_block.d.ts.map +1 -1
  266. package/src/shade/renderer/texture/encode/chunk_bc1_encode_block.js +383 -375
  267. package/src/shade/renderer/texture/encode/chunk_bc6h_encode_block_mode11.d.ts.map +1 -1
  268. package/src/shade/renderer/texture/encode/chunk_bc6h_encode_block_mode11.js +349 -346
  269. package/src/shade/renderer/texture/encode/chunk_bc7_encode_block.d.ts +58 -0
  270. package/src/shade/renderer/texture/encode/chunk_bc7_encode_block.d.ts.map +1 -0
  271. package/src/shade/renderer/texture/encode/chunk_bc7_encode_block.js +536 -0
  272. package/src/shade/renderer/texture/encode/chunk_bc7_encode_block_mode6.d.ts +21 -7
  273. package/src/shade/renderer/texture/encode/chunk_bc7_encode_block_mode6.d.ts.map +1 -1
  274. package/src/shade/renderer/texture/encode/chunk_bc7_encode_block_mode6.js +291 -327
  275. package/src/shade/renderer/texture/encode/chunk_bc7_pack_mode1.d.ts +25 -0
  276. package/src/shade/renderer/texture/encode/chunk_bc7_pack_mode1.d.ts.map +1 -0
  277. package/src/shade/renderer/texture/encode/chunk_bc7_pack_mode1.js +99 -0
  278. package/src/shade/renderer/texture/encode/chunk_bc7_pack_mode6.d.ts +5 -3
  279. package/src/shade/renderer/texture/encode/chunk_bc7_pack_mode6.d.ts.map +1 -1
  280. package/src/shade/renderer/texture/encode/chunk_bc7_pack_mode6.js +47 -71
  281. package/src/shade/renderer/texture/encode/chunk_bc7_partition_2.d.ts +10 -0
  282. package/src/shade/renderer/texture/encode/chunk_bc7_partition_2.d.ts.map +1 -0
  283. package/src/shade/renderer/texture/encode/chunk_bc7_partition_2.js +50 -0
  284. package/src/shade/renderer/texture/encode/shader_texture_encode_bc7.d.ts +4 -5
  285. package/src/shade/renderer/texture/encode/shader_texture_encode_bc7.d.ts.map +1 -1
  286. package/src/shade/renderer/texture/encode/shader_texture_encode_bc7.js +7 -8
  287. package/src/shade/renderer/volumetrics/GPUViewVolumetrics.d.ts +4 -1
  288. package/src/shade/renderer/volumetrics/GPUViewVolumetrics.d.ts.map +1 -1
  289. package/src/shade/renderer/volumetrics/GPUViewVolumetrics.js +74 -3
  290. package/src/shade/renderer/volumetrics/NOTES.md +1023 -957
  291. package/src/shade/renderer/volumetrics/chunk_volumetrics_irradiance_sh.d.ts +5 -4
  292. package/src/shade/renderer/volumetrics/chunk_volumetrics_irradiance_sh.d.ts.map +1 -1
  293. package/src/shade/renderer/volumetrics/chunk_volumetrics_irradiance_sh.js +5 -4
  294. package/src/shade/renderer/volumetrics/gi/chunk_volumetrics_gi.d.ts +1 -1
  295. package/src/shade/renderer/volumetrics/gi/chunk_volumetrics_gi.js +1 -1
  296. package/src/shade/renderer/volumetrics/gi/graph_build_froxel_gi.d.ts +1 -1
  297. package/src/shade/renderer/volumetrics/gi/graph_build_froxel_gi.js +1 -1
  298. package/src/shade/renderer/volumetrics/graph_build_froxel_irradiance.d.ts +41 -0
  299. package/src/shade/renderer/volumetrics/graph_build_froxel_irradiance.d.ts.map +1 -0
  300. package/src/shade/renderer/volumetrics/graph_build_froxel_irradiance.js +112 -0
  301. package/src/shade/renderer/volumetrics/graph_build_volumetrics.d.ts +9 -23
  302. package/src/shade/renderer/volumetrics/graph_build_volumetrics.d.ts.map +1 -1
  303. package/src/shade/renderer/volumetrics/graph_build_volumetrics.js +18 -126
  304. package/src/shade/renderer/volumetrics/shader_volumetrics_build_irradiance.d.ts +22 -0
  305. package/src/shade/renderer/volumetrics/shader_volumetrics_build_irradiance.d.ts.map +1 -0
  306. package/src/shade/renderer/volumetrics/shader_volumetrics_build_irradiance.js +228 -0
  307. package/src/shade/renderer/volumetrics/shader_volumetrics_build_lighting.d.ts.map +1 -1
  308. package/src/shade/renderer/volumetrics/shader_volumetrics_build_lighting.js +0 -53
  309. package/src/shade/renderer/water/chunk_water_transport.d.ts.map +1 -1
  310. package/src/shade/renderer/water/chunk_water_transport.js +7 -5
  311. package/src/shade/renderer/water/medium/GPUWaterBodies.d.ts.map +1 -1
  312. package/src/shade/renderer/water/medium/GPUWaterBodies.js +8 -2
  313. package/src/shade/renderer/water/optics/chunk_water_receiver_downwelling.d.ts +3 -2
  314. package/src/shade/renderer/water/optics/chunk_water_receiver_downwelling.d.ts.map +1 -1
  315. package/src/shade/renderer/water/optics/chunk_water_receiver_downwelling.js +3 -2
  316. package/src/shade/renderer/water/shader_water.d.ts.map +1 -1
  317. package/src/shade/renderer/water/shader_water.js +3 -1
  318. package/src/shade/renderer/water/surface/GPUWaterSurface.d.ts.map +1 -1
  319. package/src/shade/renderer/water/surface/GPUWaterSurface.js +3 -1
  320. package/src/shade/renderer/water/surface/chunk_water_surface_sample.d.ts +4 -3
  321. package/src/shade/renderer/water/surface/chunk_water_surface_sample.d.ts.map +1 -1
  322. package/src/shade/renderer/water/surface/chunk_water_surface_sample.js +17 -7
  323. package/src/shade/renderer/water/surface/graph_water_tessellation.d.ts.map +1 -1
  324. package/src/shade/renderer/water/surface/graph_water_tessellation.js +11 -4
  325. package/src/shade/renderer/water/surface/particles/GPUWaterParticles.d.ts.map +1 -1
  326. package/src/shade/renderer/water/surface/particles/GPUWaterParticles.js +93 -30
  327. package/src/shade/renderer/water/surface/particles/WATER_PARTICLE_STRUCT.d.ts.map +1 -1
  328. package/src/shade/renderer/water/surface/particles/WATER_PARTICLE_STRUCT.js +13 -5
  329. package/src/shade/renderer/water/surface/particles/chunk_water_particle.d.ts +29 -8
  330. package/src/shade/renderer/water/surface/particles/chunk_water_particle.d.ts.map +1 -1
  331. package/src/shade/renderer/water/surface/particles/chunk_water_particle.js +155 -30
  332. package/src/shade/renderer/water/surface/particles/chunk_water_particle_step.d.ts +6 -1
  333. package/src/shade/renderer/water/surface/particles/chunk_water_particle_step.d.ts.map +1 -1
  334. package/src/shade/renderer/water/surface/particles/chunk_water_particle_step.js +157 -39
  335. package/src/shade/renderer/water/surface/particles/shader_water_particles.d.ts +91 -21
  336. package/src/shade/renderer/water/surface/particles/shader_water_particles.d.ts.map +1 -1
  337. package/src/shade/renderer/water/surface/particles/shader_water_particles.js +442 -70
  338. package/src/shade/wgsl/emulator/WGSLJavaScriptCompiler.js +11 -3
  339. package/src/shade/wgsl/emulator/WGSLLanguageCore.d.ts.map +1 -1
  340. package/src/shade/wgsl/emulator/WGSLLanguageCore.js +3 -0
  341. package/src/shade/wgsl/validate_wgsl_source.d.ts.map +1 -1
  342. package/src/shade/wgsl/validate_wgsl_source.js +74 -3
  343. package/src/engine/graphics3/register_instance_animation.d.ts +0 -114
  344. package/src/engine/graphics3/register_instance_animation.d.ts.map +0 -1
  345. package/src/engine/graphics3/register_instance_animation.js +0 -201
@@ -1,327 +1,291 @@
1
- import { CodeChunk } from "../../shader/compiler/CodeChunk.js";
2
- import { chunk_bc7_pack_mode6 } from "./chunk_bc7_pack_mode6.js";
3
-
4
- /**
5
- * Encode sixteen RGBA texels as one BC7 block in mode 6.
6
- *
7
- * **Mode 6 is BC1's line with everything turned up**: one subset, so one line through colour
8
- * space, but in four dimensions with alpha, sixteen points on it instead of four, and the ends
9
- * stored at seven bits plus a parity bit each — an eight-bit value whose low bit is shared by the
10
- * endpoint's four channels. It is the mode `bc7enc`'s "mode 6 only" setting, DirectXTex's
11
- * `BC7_QUICK`, and the mode the UASTC transcoder carries single-subset blocks into, and on its own
12
- * it beats BC1 by a wide margin on everything but sharply partitioned blocks. The partitioned modes
13
- * are a later quality step and a separate chunk, not a change to this one.
14
- *
15
- * The fit is {@link chunk_bc1_encode_block}'s in four dimensions:
16
- *
17
- * 1. The principal axis by power iteration on the 4x4 covariance, seeded with the box diagonal;
18
- * the extreme projections as the ends.
19
- * 2. Two rounds of least squares with the sixteen decode weights shared across channels, each
20
- * texel assigned by its projection and the neighbouring weight checked by distance.
21
- * 3. **Quantisation with every parity.** Each end's low bit is one of two values, so the pair has
22
- * four parity combinations; each is rounded to and scored against the decoder's own palette,
23
- * and the best is kept. Then one round of coordinate descent over the eight stored components,
24
- * stepping by two so the parity holds, keeping any step that lowers the block's error.
25
- * 4. **The anchor.** Texel 0's index is stored a bit short, so its top bit must be zero: when it
26
- * is not, the ends are swapped and every index inverted, which is the same block the other way
27
- * up.
28
- *
29
- * Every score is against the palette the decoder builds — `(a (64 - w) + b w + 32) >> 6` on the
30
- * eight-bit ends, with BC7's own four-bit weights, which are not evenly spaced — and alpha counts
31
- * like any other channel: an opaque source's alpha is a constant the fit may land a level off
32
- * where that buys colour, as the reference transcoder does (plan §9.12), because this encoder does
33
- * not know what its consumer will do with alpha and is not the place to decide it.
34
- *
35
- * @type {CodeChunk}
36
- */
37
- export const chunk_bc7_encode_block_mode6 = CodeChunk.from(
38
- //language=WGSL
39
- `
40
- // BC7's four-bit interpolation weights, out of 64 — nearly but not exactly four and a quarter apart
41
- fn bc7_weight4(index: u32) -> u32 {
42
- var weights = array<u32, 16>(0u, 4u, 9u, 13u, 17u, 21u, 26u, 30u, 34u, 38u, 43u, 47u, 51u, 55u, 60u, 64u);
43
-
44
- return weights[index];
45
- }
46
-
47
- // a palette entry as the decoder computes it, from eight-bit ends
48
- fn bc7_interpolate(e0: vec4<f32>, e1: vec4<f32>, index: u32) -> vec4<f32> {
49
- let w = f32(bc7_weight4(index));
50
-
51
- return floor((e0 * (64.0 - w) + e1 * w + 32.0) / 64.0);
52
- }
53
-
54
- // the index whose palette entry is nearest a texel, and the squared distance: the projection's
55
- // index, checked against its two neighbours because the weights are not evenly spaced and the
56
- // entries are rounded
57
- fn bc7_nearest(e0: vec4<f32>, e1: vec4<f32>, texel: vec4<f32>) -> vec2<f32> {
58
- let direction = e1 - e0;
59
- let span = dot(direction, direction);
60
-
61
- var estimate = 0.0;
62
-
63
- if (span > 0.0) {
64
- estimate = clamp(round(dot(texel - e0, direction) / span * 15.0), 0.0, 15.0);
65
- }
66
-
67
- var best = estimate;
68
- var best_distance = 1e30;
69
-
70
- for (var offset = -1.0; offset <= 1.0; offset += 1.0) {
71
- let candidate = clamp(estimate + offset, 0.0, 15.0);
72
-
73
- let delta = bc7_interpolate(e0, e1, u32(candidate)) - texel;
74
- let distance = dot(delta, delta);
75
-
76
- if (distance < best_distance) {
77
- best_distance = distance;
78
- best = candidate;
79
- }
80
- }
81
-
82
- return vec2<f32>(best, best_distance);
83
- }
84
-
85
- fn bc7_score(texels: array<vec4<f32>, 16>, e0: vec4<f32>, e1: vec4<f32>) -> f32 {
86
- var error = 0.0;
87
-
88
- for (var i = 0u; i < 16u; i++) {
89
- error += bc7_nearest(e0, e1, texels[i]).y;
90
- }
91
-
92
- return error;
93
- }
94
-
95
- // the ends that best reproduce the texels at the weights they are nearest to on a real line: the
96
- // two-by-two normal equations, shared across the four channels
97
- fn bc7_refine(texels: array<vec4<f32>, 16>, e0: vec4<f32>, e1: vec4<f32>) -> array<vec4<f32>, 2> {
98
- let direction = e1 - e0;
99
- let span = dot(direction, direction);
100
-
101
- var aa = 0.0;
102
- var ab = 0.0;
103
- var bb = 0.0;
104
- var ap = vec4<f32>(0.0);
105
- var bp = vec4<f32>(0.0);
106
-
107
- for (var i = 0u; i < 16u; i++) {
108
- var estimate = 0.0;
109
-
110
- if (span > 0.0) {
111
- estimate = clamp(round(dot(texels[i] - e0, direction) / span * 15.0), 0.0, 15.0);
112
- }
113
-
114
- // the nearest of the three real points around the projection
115
- var best_weight = 0.0;
116
- var best_distance = 1e30;
117
-
118
- for (var offset = -1.0; offset <= 1.0; offset += 1.0) {
119
- let candidate = clamp(estimate + offset, 0.0, 15.0);
120
- let weight = f32(bc7_weight4(u32(candidate))) / 64.0;
121
-
122
- let delta = mix(e0, e1, weight) - texels[i];
123
- let distance = dot(delta, delta);
124
-
125
- if (distance < best_distance) {
126
- best_distance = distance;
127
- best_weight = weight;
128
- }
129
- }
130
-
131
- let b = best_weight;
132
- let a = 1.0 - b;
133
-
134
- aa += a * a;
135
- ab += a * b;
136
- bb += b * b;
137
- ap += a * texels[i];
138
- bp += b * texels[i];
139
- }
140
-
141
- let determinant = aa * bb - ab * ab;
142
-
143
- var out: array<vec4<f32>, 2>;
144
-
145
- if (abs(determinant) < 1e-6) {
146
- out[0] = e0;
147
- out[1] = e1;
148
-
149
- return out;
150
- }
151
-
152
- out[0] = (bb * ap - ab * bp) / determinant;
153
- out[1] = (aa * bp - ab * ap) / determinant;
154
-
155
- return out;
156
- }
157
-
158
- // an end rounded to eight bits with every channel's low bit set to the parity
159
- fn bc7_quantise(e: vec4<f32>, parity: f32) -> vec4<f32> {
160
- let even = round((clamp(e, vec4<f32>(0.0), vec4<f32>(255.0)) - parity) * 0.5) * 2.0 + parity;
161
-
162
- return clamp(even, vec4<f32>(parity), vec4<f32>(254.0 + parity));
163
- }
164
-
165
- // a vector with one component replaced, built rather than assigned into a copy — the same code
166
- // means the same thing on a device, where a copy is a value, and in the emulator, where it is not
167
- fn bc7_with_component(v: vec4<f32>, channel: u32, value: f32) -> vec4<f32> {
168
- return vec4<f32>(
169
- select(v.x, value, channel == 0u),
170
- select(v.y, value, channel == 1u),
171
- select(v.z, value, channel == 2u),
172
- select(v.w, value, channel == 3u)
173
- );
174
- }
175
-
176
- fn bc7_encode_block_mode6(texels: array<vec4<f32>, 16>) -> vec4<u32> {
177
- var scaled: array<vec4<f32>, 16>;
178
-
179
- var low = vec4<f32>(255.0);
180
- var high = vec4<f32>(0.0);
181
- var mean = vec4<f32>(0.0);
182
-
183
- for (var i = 0u; i < 16u; i++) {
184
- let v = clamp(texels[i], vec4<f32>(0.0), vec4<f32>(1.0)) * 255.0;
185
-
186
- scaled[i] = v;
187
- low = min(low, v);
188
- high = max(high, v);
189
- mean += v;
190
- }
191
-
192
- mean = mean / 16.0;
193
-
194
- let extent = high - low;
195
-
196
- var e0 = mean;
197
- var e1 = mean;
198
-
199
- if (max(max(extent.x, extent.y), max(extent.z, extent.w)) >= 0.5) {
200
- // the ten distinct terms of the 4x4 covariance
201
- var cov = array<f32, 10>(0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0);
202
-
203
- for (var i = 0u; i < 16u; i++) {
204
- let d = scaled[i] - mean;
205
-
206
- cov[0] += d.x * d.x;
207
- cov[1] += d.x * d.y;
208
- cov[2] += d.x * d.z;
209
- cov[3] += d.x * d.w;
210
- cov[4] += d.y * d.y;
211
- cov[5] += d.y * d.z;
212
- cov[6] += d.y * d.w;
213
- cov[7] += d.z * d.z;
214
- cov[8] += d.z * d.w;
215
- cov[9] += d.w * d.w;
216
- }
217
-
218
- var axis = extent;
219
-
220
- for (var iteration = 0u; iteration < 4u; iteration++) {
221
- let next = vec4<f32>(
222
- cov[0] * axis.x + cov[1] * axis.y + cov[2] * axis.z + cov[3] * axis.w,
223
- cov[1] * axis.x + cov[4] * axis.y + cov[5] * axis.z + cov[6] * axis.w,
224
- cov[2] * axis.x + cov[5] * axis.y + cov[7] * axis.z + cov[8] * axis.w,
225
- cov[3] * axis.x + cov[6] * axis.y + cov[8] * axis.z + cov[9] * axis.w
226
- );
227
-
228
- let magnitude = length(next);
229
-
230
- if (magnitude < 1e-3) {
231
- break;
232
- }
233
-
234
- axis = next / magnitude;
235
- }
236
-
237
- axis = normalize(axis);
238
-
239
- var t_min = 1e30;
240
- var t_max = -1e30;
241
-
242
- for (var i = 0u; i < 16u; i++) {
243
- let t = dot(scaled[i] - mean, axis);
244
-
245
- t_min = min(t_min, t);
246
- t_max = max(t_max, t);
247
- }
248
-
249
- e0 = mean + axis * t_min;
250
- e1 = mean + axis * t_max;
251
-
252
- for (var round = 0u; round < 2u; round++) {
253
- let refined = bc7_refine(scaled, e0, e1);
254
-
255
- e0 = clamp(refined[0], vec4<f32>(0.0), vec4<f32>(255.0));
256
- e1 = clamp(refined[1], vec4<f32>(0.0), vec4<f32>(255.0));
257
- }
258
- }
259
-
260
- // every parity combination, rounded to and scored
261
- var best = 1e30;
262
- var q0 = bc7_quantise(e0, 0.0);
263
- var q1 = bc7_quantise(e1, 0.0);
264
-
265
- for (var combination = 0u; combination < 4u; combination++) {
266
- let c0 = bc7_quantise(e0, f32(combination & 1u));
267
- let c1 = bc7_quantise(e1, f32(combination >> 1u));
268
-
269
- let error = bc7_score(scaled, c0, c1);
270
-
271
- if (error < best) {
272
- best = error;
273
- q0 = c0;
274
- q1 = c1;
275
- }
276
- }
277
-
278
- // coordinate descent over the eight stored components, stepping by two so the parity holds.
279
- // One round: a second was measured on every fixture and moved nothing, to two decimals of a
280
- // decibel — the eight-bit ends leave the least-squares answer little to correct
281
- for (var component = 0u; component < 8u; component++) {
282
- let channel = component % 4u;
283
-
284
- for (var direction = -2.0; direction <= 2.0; direction += 4.0) {
285
- var c0 = q0;
286
- var c1 = q1;
287
-
288
- if (component < 4u) {
289
- c0 = bc7_with_component(q0, channel, clamp(q0[channel] + direction, q0[channel] % 2.0, 254.0 + q0[channel] % 2.0));
290
- } else {
291
- c1 = bc7_with_component(q1, channel, clamp(q1[channel] + direction, q1[channel] % 2.0, 254.0 + q1[channel] % 2.0));
292
- }
293
-
294
- let error = bc7_score(scaled, c0, c1);
295
-
296
- if (error < best) {
297
- best = error;
298
- q0 = c0;
299
- q1 = c1;
300
- }
301
- }
302
- }
303
-
304
- var indices: array<u32, 16>;
305
-
306
- for (var i = 0u; i < 16u; i++) {
307
- indices[i] = u32(bc7_nearest(q0, q1, scaled[i]).x);
308
- }
309
-
310
- // the anchor: texel 0's top bit is implied zero, so a block with it set is written the other
311
- // way up, which decodes identically
312
- if (indices[0] >= 8u) {
313
- let swap = q0;
314
-
315
- q0 = q1;
316
- q1 = swap;
317
-
318
- for (var i = 0u; i < 16u; i++) {
319
- indices[i] = 15u - indices[i];
320
- }
321
- }
322
-
323
- return bc7_pack_mode6(vec4<u32>(q0), vec4<u32>(q1), indices);
324
- }
325
- `, [
326
- chunk_bc7_pack_mode6,
327
- ]);
1
+ import { CodeChunk } from "../../shader/compiler/CodeChunk.js";
2
+ import { chunk_bc7_pack_mode6 } from "./chunk_bc7_pack_mode6.js";
3
+
4
+ /**
5
+ * Encode sixteen RGBA texels as one BC7 block in mode 6.
6
+ *
7
+ * **Mode 6 is BC1's line with everything turned up**: one subset, so one line through colour
8
+ * space, but in four dimensions with alpha, sixteen points on it instead of four, and the ends
9
+ * stored at seven bits plus a parity bit each — an eight-bit value whose low bit is shared by the
10
+ * endpoint's four channels. It is the mode `bc7enc`'s "mode 6 only" setting, DirectXTex's
11
+ * `BC7_QUICK`, and the mode the UASTC transcoder carries single-subset blocks into, and on its own
12
+ * it beats BC1 by a wide margin on everything but sharply partitioned blocks. Those are mode 1's, in
13
+ * `chunk_bc7_encode_block`, which the kernel calls and which chooses between the two; this chunk is
14
+ * mode 6 on its own.
15
+ *
16
+ * The fit is {@link chunk_bc1_encode_block}'s in four dimensions:
17
+ *
18
+ * 1. The principal axis by power iteration on the 4x4 covariance, seeded with the box diagonal;
19
+ * the extreme projections as the ends.
20
+ * 2. One round of least squares with the sixteen decode weights shared across channels, each
21
+ * texel at the weight it projects to.
22
+ * 3. **Quantisation with every parity.** Each end's low bit is one of two values, so the pair has
23
+ * four parity combinations; each is rounded to and scored against the decoder's own palette,
24
+ * each texel at the entry its projection names, and the best is kept.
25
+ * 4. **The indices**, each texel's nearest entry of that palette: the projection's index and the
26
+ * two beside it, by distance, because the weights are not evenly spaced and the entries are
27
+ * rounded.
28
+ * 5. **The anchor.** Texel 0's index is stored a bit short, so its top bit must be zero: when it
29
+ * is not, the ends are swapped and every index inverted, which is the same block the other way
30
+ * up.
31
+ *
32
+ * **The search is the leanest that holds the line**, by measurement (plan §9.20). The one it
33
+ * replaced scored each texel at its nearest entry rather than its projection's, ran a second round
34
+ * of least squares and a round of coordinate descent over the stored ends, and held the block as
35
+ * floats: 0.17 dB better over twenty photographs, at six times the time. Sixteen points on the line
36
+ * leave the projection little to miss; the quality BC7 still lacks is in the partitioned modes, and
37
+ * that is where the budget goes.
38
+ *
39
+ * Every score is against the palette the decoder builds — `(a (64 - w) + b w + 32) >> 6` on the
40
+ * eight-bit ends, with BC7's own four-bit weights, which are not evenly spaced — and alpha counts
41
+ * like any other channel: an opaque source's alpha is a constant the fit may land a level off
42
+ * where that buys colour, as the reference transcoder does (plan §9.12), because this encoder does
43
+ * not know what its consumer will do with alpha and is not the place to decide it.
44
+ *
45
+ * The block is held as sixteen packed eight-bit words and unpacked where it is read, which is
46
+ * sixteen registers instead of sixty-four. A source with more than eight bits a channel is rounded
47
+ * to eight first: what the format's ends and palette hold.
48
+ *
49
+ * @type {CodeChunk}
50
+ */
51
+ export const chunk_bc7_encode_block_mode6 = CodeChunk.from(
52
+ //language=WGSL
53
+ `
54
+ // BC7's four-bit interpolation weights, out of 64 — nearly but not exactly four and a quarter apart:
55
+ // 0, 4, 9, 13, 17, 21, 26, 30, 34, 38, 43, 47, 51, 55, 60, 64, every one of which this computes.
56
+ // Computed rather than looked up: a function-local table indexed at run time lives in local memory
57
+ // rather than registers, and a 4096² encode on a 4090 spent 15% of its time on that lookup
58
+ fn bc7_weight4(index: u32) -> u32 {
59
+ return (index * 64u + 7u) / 15u;
60
+ }
61
+
62
+ // a palette entry as the decoder computes it, from eight-bit ends
63
+ fn bc7_interpolate(e0: vec4<f32>, e1: vec4<f32>, index: u32) -> vec4<f32> {
64
+ let w = f32(bc7_weight4(index));
65
+
66
+ return floor((e0 * (64.0 - w) + e1 * w + 32.0) / 64.0);
67
+ }
68
+
69
+ // a texel of the block, held packed, in the [0, 255] the fit works in
70
+ fn bc7_texel(packed: u32) -> vec4<f32> {
71
+ return unpack4x8unorm(packed) * 255.0;
72
+ }
73
+
74
+ // the index a texel projects to on the line between the ends: the nearest of sixteen evenly spaced
75
+ // points, which the decoder's palette — rounded, and not evenly spaced — can move by one
76
+ fn bc7_project(e0: vec4<f32>, e1: vec4<f32>, texel: vec4<f32>) -> f32 {
77
+ let direction = e1 - e0;
78
+ let span = dot(direction, direction);
79
+
80
+ if (span > 0.0) {
81
+ return clamp(round(dot(texel - e0, direction) / span * 15.0), 0.0, 15.0);
82
+ }
83
+
84
+ return 0.0;
85
+ }
86
+
87
+ // the index whose palette entry is nearest a texel: the projection's, or one beside it
88
+ fn bc7_nearest(e0: vec4<f32>, e1: vec4<f32>, texel: vec4<f32>) -> u32 {
89
+ let estimate = bc7_project(e0, e1, texel);
90
+
91
+ var best = estimate;
92
+ var best_distance = 1e30;
93
+
94
+ for (var offset = -1.0; offset <= 1.0; offset += 1.0) {
95
+ let candidate = clamp(estimate + offset, 0.0, 15.0);
96
+
97
+ let delta = bc7_interpolate(e0, e1, u32(candidate)) - texel;
98
+ let distance = dot(delta, delta);
99
+
100
+ if (distance < best_distance) {
101
+ best_distance = distance;
102
+ best = candidate;
103
+ }
104
+ }
105
+
106
+ return u32(best);
107
+ }
108
+
109
+ // the block's squared error against a pair of ends, each texel at the palette entry its projection
110
+ // names — its nearest, or one beside the nearest, which is close enough to rank pairs by
111
+ fn bc7_score(texels: array<u32, 16>, e0: vec4<f32>, e1: vec4<f32>) -> f32 {
112
+ var error = 0.0;
113
+
114
+ for (var i = 0u; i < 16u; i++) {
115
+ let texel = bc7_texel(texels[i]);
116
+ let delta = bc7_interpolate(e0, e1, u32(bc7_project(e0, e1, texel))) - texel;
117
+
118
+ error += dot(delta, delta);
119
+ }
120
+
121
+ return error;
122
+ }
123
+
124
+ // the ends that best reproduce the texels at the weights they project to: the two-by-two normal
125
+ // equations, shared across the four channels
126
+ fn bc7_refine(texels: array<u32, 16>, e0: vec4<f32>, e1: vec4<f32>) -> array<vec4<f32>, 2> {
127
+ var aa = 0.0;
128
+ var ab = 0.0;
129
+ var bb = 0.0;
130
+ var ap = vec4<f32>(0.0);
131
+ var bp = vec4<f32>(0.0);
132
+
133
+ for (var i = 0u; i < 16u; i++) {
134
+ let texel = bc7_texel(texels[i]);
135
+
136
+ let b = f32(bc7_weight4(u32(bc7_project(e0, e1, texel)))) / 64.0;
137
+ let a = 1.0 - b;
138
+
139
+ aa += a * a;
140
+ ab += a * b;
141
+ bb += b * b;
142
+ ap += a * texel;
143
+ bp += b * texel;
144
+ }
145
+
146
+ let determinant = aa * bb - ab * ab;
147
+
148
+ var out: array<vec4<f32>, 2>;
149
+
150
+ if (abs(determinant) < 1e-6) {
151
+ out[0] = e0;
152
+ out[1] = e1;
153
+
154
+ return out;
155
+ }
156
+
157
+ out[0] = (bb * ap - ab * bp) / determinant;
158
+ out[1] = (aa * bp - ab * ap) / determinant;
159
+
160
+ return out;
161
+ }
162
+
163
+ // an end rounded to eight bits with every channel's low bit set to the parity
164
+ fn bc7_quantise(e: vec4<f32>, parity: f32) -> vec4<f32> {
165
+ let even = round((clamp(e, vec4<f32>(0.0), vec4<f32>(255.0)) - parity) * 0.5) * 2.0 + parity;
166
+
167
+ return clamp(even, vec4<f32>(parity), vec4<f32>(254.0 + parity));
168
+ }
169
+
170
+ fn bc7_encode_block_mode6(texels: array<vec4<f32>, 16>) -> vec4<u32> {
171
+ var packed: array<u32, 16>;
172
+
173
+ var low = vec4<f32>(255.0);
174
+ var high = vec4<f32>(0.0);
175
+ var mean = vec4<f32>(0.0);
176
+
177
+ for (var i = 0u; i < 16u; i++) {
178
+ packed[i] = pack4x8unorm(texels[i]);
179
+
180
+ let v = bc7_texel(packed[i]);
181
+
182
+ low = min(low, v);
183
+ high = max(high, v);
184
+ mean += v;
185
+ }
186
+
187
+ mean = mean / 16.0;
188
+
189
+ let extent = high - low;
190
+
191
+ var e0 = mean;
192
+ var e1 = mean;
193
+
194
+ if (max(max(extent.x, extent.y), max(extent.z, extent.w)) >= 0.5) {
195
+ // the ten distinct terms of the 4x4 covariance
196
+ var cov = array<f32, 10>(0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0);
197
+
198
+ for (var i = 0u; i < 16u; i++) {
199
+ let d = bc7_texel(packed[i]) - mean;
200
+
201
+ cov[0] += d.x * d.x;
202
+ cov[1] += d.x * d.y;
203
+ cov[2] += d.x * d.z;
204
+ cov[3] += d.x * d.w;
205
+ cov[4] += d.y * d.y;
206
+ cov[5] += d.y * d.z;
207
+ cov[6] += d.y * d.w;
208
+ cov[7] += d.z * d.z;
209
+ cov[8] += d.z * d.w;
210
+ cov[9] += d.w * d.w;
211
+ }
212
+
213
+ var axis = extent;
214
+
215
+ for (var iteration = 0u; iteration < 4u; iteration++) {
216
+ let next = vec4<f32>(
217
+ cov[0] * axis.x + cov[1] * axis.y + cov[2] * axis.z + cov[3] * axis.w,
218
+ cov[1] * axis.x + cov[4] * axis.y + cov[5] * axis.z + cov[6] * axis.w,
219
+ cov[2] * axis.x + cov[5] * axis.y + cov[7] * axis.z + cov[8] * axis.w,
220
+ cov[3] * axis.x + cov[6] * axis.y + cov[8] * axis.z + cov[9] * axis.w
221
+ );
222
+
223
+ let magnitude = length(next);
224
+
225
+ if (magnitude < 1e-3) {
226
+ break;
227
+ }
228
+
229
+ axis = next / magnitude;
230
+ }
231
+
232
+ axis = normalize(axis);
233
+
234
+ var t_min = 1e30;
235
+ var t_max = -1e30;
236
+
237
+ for (var i = 0u; i < 16u; i++) {
238
+ let t = dot(bc7_texel(packed[i]) - mean, axis);
239
+
240
+ t_min = min(t_min, t);
241
+ t_max = max(t_max, t);
242
+ }
243
+
244
+ let refined = bc7_refine(packed, mean + axis * t_min, mean + axis * t_max);
245
+
246
+ e0 = clamp(refined[0], vec4<f32>(0.0), vec4<f32>(255.0));
247
+ e1 = clamp(refined[1], vec4<f32>(0.0), vec4<f32>(255.0));
248
+ }
249
+
250
+ // every parity combination, rounded to and scored
251
+ var best = 1e30;
252
+ var q0 = bc7_quantise(e0, 0.0);
253
+ var q1 = bc7_quantise(e1, 0.0);
254
+
255
+ for (var combination = 0u; combination < 4u; combination++) {
256
+ let c0 = bc7_quantise(e0, f32(combination & 1u));
257
+ let c1 = bc7_quantise(e1, f32(combination >> 1u));
258
+
259
+ let error = bc7_score(packed, c0, c1);
260
+
261
+ if (error < best) {
262
+ best = error;
263
+ q0 = c0;
264
+ q1 = c1;
265
+ }
266
+ }
267
+
268
+ var indices: array<u32, 16>;
269
+
270
+ for (var i = 0u; i < 16u; i++) {
271
+ indices[i] = bc7_nearest(q0, q1, bc7_texel(packed[i]));
272
+ }
273
+
274
+ // the anchor: texel 0's top bit is implied zero, so a block with it set is written the other
275
+ // way up, which decodes identically
276
+ if (indices[0] >= 8u) {
277
+ let swap = q0;
278
+
279
+ q0 = q1;
280
+ q1 = swap;
281
+
282
+ for (var i = 0u; i < 16u; i++) {
283
+ indices[i] = 15u - indices[i];
284
+ }
285
+ }
286
+
287
+ return bc7_pack_mode6(vec4<u32>(q0), vec4<u32>(q1), indices);
288
+ }
289
+ `, [
290
+ chunk_bc7_pack_mode6,
291
+ ]);