@woosh/meep-engine 3.22.0 → 3.23.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 (267) hide show
  1. package/package.json +1 -1
  2. package/src/core/geom/3d/hash-grid/PointHashGrid3.d.ts +118 -0
  3. package/src/core/geom/3d/hash-grid/PointHashGrid3.d.ts.map +1 -0
  4. package/src/core/geom/3d/hash-grid/PointHashGrid3.js +283 -0
  5. package/src/core/geom/3d/shape/BoxShape3D.d.ts.map +1 -1
  6. package/src/core/geom/3d/shape/BoxShape3D.js +6 -17
  7. package/src/core/geom/3d/shape/CapsuleShape3D.d.ts.map +1 -1
  8. package/src/core/geom/3d/shape/CapsuleShape3D.js +3 -14
  9. package/src/core/geom/3d/shape/CylinderShape3D.d.ts.map +1 -1
  10. package/src/core/geom/3d/shape/CylinderShape3D.js +3 -21
  11. package/src/core/geom/3d/shape/PlaneShape3D.d.ts +105 -0
  12. package/src/core/geom/3d/shape/PlaneShape3D.d.ts.map +1 -0
  13. package/src/core/geom/3d/shape/PlaneShape3D.js +251 -0
  14. package/src/core/geom/3d/shape/SphereShape3D.js +3 -3
  15. package/src/core/geom/3d/shape/json/shape_to_type.d.ts.map +1 -1
  16. package/src/core/geom/3d/shape/json/shape_to_type.js +3 -0
  17. package/src/core/geom/3d/shape/json/type_adapters.d.ts +14 -0
  18. package/src/core/geom/3d/shape/json/type_adapters.d.ts.map +1 -1
  19. package/src/core/geom/3d/shape/json/type_adapters.js +15 -0
  20. package/src/core/geom/3d/shape/sdf/sdf3_box.d.ts +51 -0
  21. package/src/core/geom/3d/shape/sdf/sdf3_box.d.ts.map +1 -0
  22. package/src/core/geom/3d/shape/sdf/sdf3_box.js +113 -0
  23. package/src/core/geom/3d/shape/sdf/sdf3_capsule.d.ts +46 -0
  24. package/src/core/geom/3d/shape/sdf/sdf3_capsule.d.ts.map +1 -0
  25. package/src/core/geom/3d/shape/sdf/sdf3_capsule.js +82 -0
  26. package/src/core/geom/3d/shape/sdf/sdf3_cylinder.d.ts +60 -0
  27. package/src/core/geom/3d/shape/sdf/sdf3_cylinder.d.ts.map +1 -0
  28. package/src/core/geom/3d/shape/sdf/sdf3_cylinder.js +126 -0
  29. package/src/core/geom/3d/shape/sdf/sdf3_degenerate_normal.d.ts +50 -0
  30. package/src/core/geom/3d/shape/sdf/sdf3_degenerate_normal.d.ts.map +1 -0
  31. package/src/core/geom/3d/shape/sdf/sdf3_degenerate_normal.js +53 -0
  32. package/src/core/geom/3d/shape/sdf/sdf3_plane.d.ts +52 -0
  33. package/src/core/geom/3d/shape/sdf/sdf3_plane.d.ts.map +1 -0
  34. package/src/core/geom/3d/shape/sdf/sdf3_plane.js +61 -0
  35. package/src/core/geom/3d/shape/sdf/sdf3_sphere.d.ts +41 -0
  36. package/src/core/geom/3d/shape/sdf/sdf3_sphere.d.ts.map +1 -0
  37. package/src/core/geom/3d/shape/sdf/sdf3_sphere.js +71 -0
  38. package/src/core/process/ConcurrencyGate.d.ts +103 -0
  39. package/src/core/process/ConcurrencyGate.d.ts.map +1 -0
  40. package/src/core/process/ConcurrencyGate.js +207 -0
  41. package/src/engine/asset/AssetManager.d.ts +10 -0
  42. package/src/engine/asset/AssetManager.d.ts.map +1 -1
  43. package/src/engine/asset/AssetManager.js +10 -0
  44. package/src/engine/graphics/CONTEXT_LOSS_RECOVERY_PLAN.md +30 -13
  45. package/src/engine/graphics3/pose/collect_entity_playbacks.d.ts +26 -0
  46. package/src/engine/graphics3/pose/collect_entity_playbacks.d.ts.map +1 -0
  47. package/src/engine/graphics3/pose/collect_entity_playbacks.js +40 -0
  48. package/src/engine/graphics3/pose/query_entity_node_world_pose.d.ts.map +1 -1
  49. package/src/engine/graphics3/pose/query_entity_node_world_pose.js +74 -101
  50. package/src/engine/physics/cloth/MEASUREMENTS.md +1287 -4
  51. package/src/engine/physics/cloth/PLAN.md +1967 -1581
  52. package/src/engine/physics/cloth/build/ClothProxy.d.ts +147 -0
  53. package/src/engine/physics/cloth/build/ClothProxy.d.ts.map +1 -0
  54. package/src/engine/physics/cloth/build/ClothProxy.js +207 -0
  55. package/src/engine/physics/cloth/build/cloth_proxy_from_joints.d.ts +70 -0
  56. package/src/engine/physics/cloth/build/cloth_proxy_from_joints.d.ts.map +1 -0
  57. package/src/engine/physics/cloth/build/cloth_proxy_from_joints.js +256 -0
  58. package/src/engine/physics/cloth/collider/ClothColliderIndex.d.ts +176 -0
  59. package/src/engine/physics/cloth/collider/ClothColliderIndex.d.ts.map +1 -0
  60. package/src/engine/physics/cloth/collider/ClothColliderIndex.js +435 -0
  61. package/src/engine/physics/cloth/collider/ClothColliderKind.d.ts +12 -0
  62. package/src/engine/physics/cloth/collider/ClothColliderKind.d.ts.map +1 -0
  63. package/src/engine/physics/cloth/collider/ClothColliderKind.js +38 -0
  64. package/src/engine/physics/cloth/collider/ClothColliderRecord.d.ts +120 -0
  65. package/src/engine/physics/cloth/collider/ClothColliderRecord.d.ts.map +1 -0
  66. package/src/engine/physics/cloth/collider/ClothColliderRecord.js +137 -0
  67. package/src/engine/physics/cloth/collider/cloth_collider_bounds.d.ts +25 -0
  68. package/src/engine/physics/cloth/collider/cloth_collider_bounds.d.ts.map +1 -0
  69. package/src/engine/physics/cloth/collider/cloth_collider_bounds.js +190 -0
  70. package/src/engine/physics/cloth/collider/cloth_collider_pack.d.ts +44 -0
  71. package/src/engine/physics/cloth/collider/cloth_collider_pack.d.ts.map +1 -0
  72. package/src/engine/physics/cloth/collider/cloth_collider_pack.js +173 -0
  73. package/src/engine/physics/cloth/collider/cloth_collider_sdf.d.ts +94 -0
  74. package/src/engine/physics/cloth/collider/cloth_collider_sdf.d.ts.map +1 -0
  75. package/src/engine/physics/cloth/collider/cloth_collider_sdf.js +275 -0
  76. package/src/engine/physics/cloth/ecs/ClothCollider.d.ts +126 -0
  77. package/src/engine/physics/cloth/ecs/ClothCollider.d.ts.map +1 -0
  78. package/src/engine/physics/cloth/ecs/ClothCollider.js +199 -0
  79. package/src/engine/physics/cloth/ecs/ClothColliderFlags.d.ts +9 -0
  80. package/src/engine/physics/cloth/ecs/ClothColliderFlags.d.ts.map +1 -0
  81. package/src/engine/physics/cloth/ecs/ClothColliderFlags.js +32 -0
  82. package/src/engine/physics/cloth/ecs/ClothColliderSystem.d.ts +114 -0
  83. package/src/engine/physics/cloth/ecs/ClothColliderSystem.d.ts.map +1 -0
  84. package/src/engine/physics/cloth/ecs/ClothColliderSystem.js +243 -0
  85. package/src/engine/physics/cloth/ecs/ClothDynamicsFlags.js +66 -57
  86. package/src/engine/physics/cloth/ecs/ClothInstance.d.ts +109 -1
  87. package/src/engine/physics/cloth/ecs/ClothInstance.d.ts.map +1 -1
  88. package/src/engine/physics/cloth/ecs/ClothInstance.js +479 -363
  89. package/src/engine/physics/cloth/ecs/ClothRig.d.ts +95 -0
  90. package/src/engine/physics/cloth/ecs/ClothRig.d.ts.map +1 -0
  91. package/src/engine/physics/cloth/ecs/ClothRig.js +140 -0
  92. package/src/engine/physics/cloth/ecs/ClothSystem.d.ts +30 -1
  93. package/src/engine/physics/cloth/ecs/ClothSystem.d.ts.map +1 -1
  94. package/src/engine/physics/cloth/ecs/ClothSystem.js +1021 -773
  95. package/src/engine/physics/cloth/ecs/cloth_build_rows.d.ts +90 -0
  96. package/src/engine/physics/cloth/ecs/cloth_build_rows.d.ts.map +1 -0
  97. package/src/engine/physics/cloth/ecs/cloth_build_rows.js +374 -0
  98. package/src/engine/physics/cloth/ecs/cloth_dynamics_library.d.ts +32 -3
  99. package/src/engine/physics/cloth/ecs/cloth_dynamics_library.d.ts.map +1 -1
  100. package/src/engine/physics/cloth/ecs/cloth_dynamics_library.js +283 -254
  101. package/src/engine/physics/cloth/ecs/cloth_gather_colliders.d.ts +59 -0
  102. package/src/engine/physics/cloth/ecs/cloth_gather_colliders.d.ts.map +1 -0
  103. package/src/engine/physics/cloth/ecs/cloth_gather_colliders.js +328 -0
  104. package/src/engine/physics/cloth/ecs/cloth_reconstruct_pose.d.ts +13 -0
  105. package/src/engine/physics/cloth/ecs/cloth_reconstruct_pose.d.ts.map +1 -0
  106. package/src/engine/physics/cloth/ecs/cloth_reconstruct_pose.js +288 -0
  107. package/src/engine/physics/cloth/ecs/cloth_seed_rig.d.ts +58 -0
  108. package/src/engine/physics/cloth/ecs/cloth_seed_rig.d.ts.map +1 -0
  109. package/src/engine/physics/cloth/ecs/cloth_seed_rig.js +199 -0
  110. package/src/engine/physics/cloth/ecs/cloth_seed_subtree.d.ts +8 -63
  111. package/src/engine/physics/cloth/ecs/cloth_seed_subtree.d.ts.map +1 -1
  112. package/src/engine/physics/cloth/ecs/cloth_seed_subtree.js +317 -645
  113. package/src/engine/physics/cloth/ecs/cloth_write_back.d.ts +61 -0
  114. package/src/engine/physics/cloth/ecs/cloth_write_back.d.ts.map +1 -1
  115. package/src/engine/physics/cloth/ecs/cloth_write_back.js +212 -449
  116. package/src/engine/physics/cloth/ecs/cloth_write_back_rig.d.ts +49 -0
  117. package/src/engine/physics/cloth/ecs/cloth_write_back_rig.d.ts.map +1 -0
  118. package/src/engine/physics/cloth/ecs/cloth_write_back_rig.js +115 -0
  119. package/src/engine/physics/cloth/playground/README.md +155 -1
  120. package/src/engine/physics/cloth/playground/collide.html +178 -0
  121. package/src/engine/physics/cloth/playground/collide_build.d.ts +95 -0
  122. package/src/engine/physics/cloth/playground/collide_build.d.ts.map +1 -0
  123. package/src/engine/physics/cloth/playground/collide_build.js +315 -0
  124. package/src/engine/physics/cloth/playground/collide_main.d.ts +2 -0
  125. package/src/engine/physics/cloth/playground/collide_main.d.ts.map +1 -0
  126. package/src/engine/physics/cloth/playground/collide_main.js +720 -0
  127. package/src/engine/physics/cloth/playground/garment.html +182 -0
  128. package/src/engine/physics/cloth/playground/garment_build.d.ts +78 -0
  129. package/src/engine/physics/cloth/playground/garment_build.d.ts.map +1 -0
  130. package/src/engine/physics/cloth/playground/garment_build.js +359 -0
  131. package/src/engine/physics/cloth/playground/garment_main.d.ts +2 -0
  132. package/src/engine/physics/cloth/playground/garment_main.d.ts.map +1 -0
  133. package/src/engine/physics/cloth/playground/garment_main.js +633 -0
  134. package/src/engine/physics/cloth/solver/ClothState.d.ts +208 -5
  135. package/src/engine/physics/cloth/solver/ClothState.d.ts.map +1 -1
  136. package/src/engine/physics/cloth/solver/ClothState.js +302 -8
  137. package/src/engine/physics/cloth/solver/cloth_contact_find.d.ts +87 -0
  138. package/src/engine/physics/cloth/solver/cloth_contact_find.d.ts.map +1 -0
  139. package/src/engine/physics/cloth/solver/cloth_contact_find.js +343 -0
  140. package/src/engine/physics/cloth/solver/cloth_self_find.d.ts +112 -0
  141. package/src/engine/physics/cloth/solver/cloth_self_find.d.ts.map +1 -0
  142. package/src/engine/physics/cloth/solver/cloth_self_find.js +448 -0
  143. package/src/engine/physics/cloth/solver/cloth_solve_vertex.d.ts +4 -1
  144. package/src/engine/physics/cloth/solver/cloth_solve_vertex.d.ts.map +1 -1
  145. package/src/engine/physics/cloth/solver/cloth_solve_vertex.js +16 -1
  146. package/src/engine/physics/cloth/solver/cloth_solver_constants.d.ts +112 -5
  147. package/src/engine/physics/cloth/solver/cloth_solver_constants.d.ts.map +1 -1
  148. package/src/engine/physics/cloth/solver/cloth_solver_constants.js +117 -6
  149. package/src/engine/physics/cloth/solver/cloth_step.d.ts +40 -9
  150. package/src/engine/physics/cloth/solver/cloth_step.d.ts.map +1 -1
  151. package/src/engine/physics/cloth/solver/cloth_step.js +122 -10
  152. package/src/engine/physics/cloth/solver/constraint/cloth_backstop_row.d.ts +95 -0
  153. package/src/engine/physics/cloth/solver/constraint/cloth_backstop_row.d.ts.map +1 -0
  154. package/src/engine/physics/cloth/solver/constraint/cloth_backstop_row.js +285 -0
  155. package/src/engine/physics/cloth/solver/constraint/cloth_contact_row.d.ts +129 -0
  156. package/src/engine/physics/cloth/solver/constraint/cloth_contact_row.d.ts.map +1 -0
  157. package/src/engine/physics/cloth/solver/constraint/cloth_contact_row.js +501 -0
  158. package/src/engine/physics/cloth/solver/constraint/cloth_self_row.d.ts +75 -0
  159. package/src/engine/physics/cloth/solver/constraint/cloth_self_row.d.ts.map +1 -0
  160. package/src/engine/physics/cloth/solver/constraint/cloth_self_row.js +202 -0
  161. package/src/engine/physics/fluid/ecs/FluidObstacleSystem.d.ts +4 -4
  162. package/src/shade/playground/vgeo_viewer/README.md +18 -0
  163. package/src/shade/playground/vgeo_viewer/main.js +87 -50
  164. package/src/shade/renderer/buffer/table/GPUDatabase.d.ts.map +1 -1
  165. package/src/shade/renderer/buffer/table/GPUDatabase.js +191 -62
  166. package/src/shade/renderer/buffer/table/GPUTypedTable.d.ts +94 -2
  167. package/src/shade/renderer/buffer/table/GPUTypedTable.d.ts.map +1 -1
  168. package/src/shade/renderer/buffer/table/GPUTypedTable.js +414 -2
  169. package/src/shade/renderer/buffer/table/GPU_TABLE_PARTIAL_UPLOAD_DESCRIPTOR_WORDS.d.ts +14 -0
  170. package/src/shade/renderer/buffer/table/GPU_TABLE_PARTIAL_UPLOAD_DESCRIPTOR_WORDS.d.ts.map +1 -0
  171. package/src/shade/renderer/buffer/table/GPU_TABLE_PARTIAL_UPLOAD_DESCRIPTOR_WORDS.js +13 -0
  172. package/src/shade/renderer/buffer/table/gpu_table_partial_upload_shader.d.ts +17 -0
  173. package/src/shade/renderer/buffer/table/gpu_table_partial_upload_shader.d.ts.map +1 -0
  174. package/src/shade/renderer/buffer/table/gpu_table_partial_upload_shader.js +116 -0
  175. package/src/shade/renderer/geometry/bvh/GPUGeometryBVHManager.d.ts +9 -4
  176. package/src/shade/renderer/geometry/bvh/GPUGeometryBVHManager.d.ts.map +1 -1
  177. package/src/shade/renderer/geometry/bvh/GPUGeometryBVHManager.js +843 -734
  178. package/src/shade/renderer/geometry/bvh/GPUGeometryMeshletsBVH.d.ts +12 -0
  179. package/src/shade/renderer/geometry/bvh/GPUGeometryMeshletsBVH.d.ts.map +1 -1
  180. package/src/shade/renderer/geometry/bvh/GPUGeometryMeshletsBVH.js +13 -0
  181. package/src/shade/renderer/geometry/meshlet/GPUMeshletManager.d.ts +17 -0
  182. package/src/shade/renderer/geometry/meshlet/GPUMeshletManager.d.ts.map +1 -1
  183. package/src/shade/renderer/geometry/meshlet/GPUMeshletManager.js +185 -30
  184. package/src/shade/renderer/geometry/virtual/MICRON_COMPARISON_2026_08_20.md +17 -0
  185. package/src/shade/renderer/geometry/virtual/VGEO_FORMAT.md +141 -24
  186. package/src/shade/renderer/geometry/virtual/VIRTUAL_GEOMETRY_DESIGN.md +204 -64
  187. package/src/shade/renderer/geometry/virtual/VIRTUAL_GEOMETRY_PLAN.md +110 -10
  188. package/src/shade/renderer/geometry/virtual/VK_LOD_CLUSTERS_COMPARISON_2026_08_20.md +19 -0
  189. package/src/shade/renderer/geometry/virtual/format/read/VGeoByteSource.d.ts +19 -6
  190. package/src/shade/renderer/geometry/virtual/format/read/VGeoByteSource.d.ts.map +1 -1
  191. package/src/shade/renderer/geometry/virtual/format/read/VGeoByteSource.js +26 -7
  192. package/src/shade/renderer/geometry/virtual/format/read/VGeoContainerReader.d.ts +173 -14
  193. package/src/shade/renderer/geometry/virtual/format/read/VGeoContainerReader.d.ts.map +1 -1
  194. package/src/shade/renderer/geometry/virtual/format/read/VGeoContainerReader.js +458 -51
  195. package/src/shade/renderer/geometry/virtual/format/read/VGeoReadOptions.d.ts +49 -13
  196. package/src/shade/renderer/geometry/virtual/format/read/VGeoReadOptions.d.ts.map +1 -1
  197. package/src/shade/renderer/geometry/virtual/format/read/VGeoReadOptions.js +52 -14
  198. package/src/shade/renderer/geometry/virtual/format/read/tool/VGEO_MAX_AUDIT_BYTES.d.ts +20 -0
  199. package/src/shade/renderer/geometry/virtual/format/read/tool/VGEO_MAX_AUDIT_BYTES.d.ts.map +1 -0
  200. package/src/shade/renderer/geometry/virtual/format/read/tool/VGEO_MAX_AUDIT_BYTES.js +19 -0
  201. package/src/shade/renderer/geometry/virtual/format/read/tool/vgeo_audit_container.d.ts +27 -0
  202. package/src/shade/renderer/geometry/virtual/format/read/tool/vgeo_audit_container.d.ts.map +1 -0
  203. package/src/shade/renderer/geometry/virtual/format/read/tool/vgeo_audit_container.js +48 -0
  204. package/src/shade/renderer/geometry/virtual/format/read/tool/vgeo_install_all_pages.d.ts +29 -0
  205. package/src/shade/renderer/geometry/virtual/format/read/tool/vgeo_install_all_pages.d.ts.map +1 -0
  206. package/src/shade/renderer/geometry/virtual/format/read/tool/vgeo_install_all_pages.js +60 -0
  207. package/src/shade/renderer/geometry/virtual/format/read/vgeo_fetch_byte_source.d.ts +8 -1
  208. package/src/shade/renderer/geometry/virtual/format/read/vgeo_fetch_byte_source.d.ts.map +1 -1
  209. package/src/shade/renderer/geometry/virtual/format/read/vgeo_fetch_byte_source.js +32 -2
  210. package/src/shade/renderer/geometry/virtual/residency/VGeoResidencyManager.d.ts +258 -0
  211. package/src/shade/renderer/geometry/virtual/residency/VGeoResidencyManager.d.ts.map +1 -0
  212. package/src/shade/renderer/geometry/virtual/residency/VGeoResidencyManager.js +723 -0
  213. package/src/shade/renderer/geometry/virtual/residency/VGeoResidencyOptions.d.ts +49 -0
  214. package/src/shade/renderer/geometry/virtual/residency/VGeoResidencyOptions.d.ts.map +1 -0
  215. package/src/shade/renderer/geometry/virtual/residency/VGeoResidencyOptions.js +50 -0
  216. package/src/shade/renderer/loader/gltf/tiny-gltf.d.ts +1 -1
  217. package/src/shade/renderer/postprocess/nss/NSS.d.ts +1 -1
  218. package/src/shade/renderer/texture/bindless/GPUBindlessTextureManager.d.ts +3 -0
  219. package/src/shade/renderer/texture/bindless/GPUBindlessTextureManager.d.ts.map +1 -1
  220. package/src/shade/renderer/texture/bindless/GPUBindlessTextureManager.js +121 -21
  221. package/src/shade/renderer/texture/virtual/README.md +6 -4
  222. package/src/shade/renderer/texture/virtual/VirtualTextureManager.d.ts.map +1 -1
  223. package/src/shade/renderer/texture/virtual/VirtualTextureManager.js +7 -0
  224. package/src/shade/renderer/texture/virtual/source/VTSourceTiled.d.ts +3 -3
  225. package/src/shade/renderer/texture/virtual/source/VTSourceTiled.js +3 -3
  226. package/src/engine/ecs/system/SystemExecutionPhase.d.ts +0 -9
  227. package/src/engine/ecs/system/SystemExecutionPhase.d.ts.map +0 -1
  228. package/src/engine/graphics/texture/virtual/NOTES.md +0 -128
  229. package/src/engine/graphics/texture/virtual/VT_DEFAULT_PAGE_RESOLUTION.d.ts +0 -6
  230. package/src/engine/graphics/texture/virtual/VT_DEFAULT_PAGE_RESOLUTION.d.ts.map +0 -1
  231. package/src/engine/graphics/texture/virtual/VT_DEFAULT_PAGE_RESOLUTION.js +0 -5
  232. package/src/engine/graphics/texture/virtual/VirtualTextureTileLoader.d.ts +0 -49
  233. package/src/engine/graphics/texture/virtual/VirtualTextureTileLoader.d.ts.map +0 -1
  234. package/src/engine/graphics/texture/virtual/VirtualTextureTileLoader.js +0 -264
  235. package/src/engine/graphics/texture/virtual/VirtualTextureUsage.d.ts +0 -44
  236. package/src/engine/graphics/texture/virtual/VirtualTextureUsage.d.ts.map +0 -1
  237. package/src/engine/graphics/texture/virtual/VirtualTextureUsage.js +0 -228
  238. package/src/engine/graphics/texture/virtual/VirtualTextureUsageShader.d.ts +0 -3
  239. package/src/engine/graphics/texture/virtual/VirtualTextureUsageShader.d.ts.map +0 -1
  240. package/src/engine/graphics/texture/virtual/VirtualTextureUsageShader.js +0 -73
  241. package/src/engine/graphics/texture/virtual/debug/ResidencyDebugView.d.ts +0 -14
  242. package/src/engine/graphics/texture/virtual/debug/ResidencyDebugView.d.ts.map +0 -1
  243. package/src/engine/graphics/texture/virtual/debug/ResidencyDebugView.js +0 -85
  244. package/src/engine/graphics/texture/virtual/debug/UsageDebugView.d.ts +0 -12
  245. package/src/engine/graphics/texture/virtual/debug/UsageDebugView.d.ts.map +0 -1
  246. package/src/engine/graphics/texture/virtual/debug/UsageDebugView.js +0 -63
  247. package/src/engine/graphics/texture/virtual/debug/UsagePyramidDebugView.d.ts +0 -12
  248. package/src/engine/graphics/texture/virtual/debug/UsagePyramidDebugView.d.ts.map +0 -1
  249. package/src/engine/graphics/texture/virtual/debug/UsagePyramidDebugView.js +0 -243
  250. package/src/engine/graphics/texture/virtual/tile/VirtualTextureTile.d.ts +0 -30
  251. package/src/engine/graphics/texture/virtual/tile/VirtualTextureTile.d.ts.map +0 -1
  252. package/src/engine/graphics/texture/virtual/tile/VirtualTextureTile.js +0 -39
  253. package/src/engine/graphics/texture/virtual/tile/compose_finger_print.d.ts +0 -9
  254. package/src/engine/graphics/texture/virtual/tile/compose_finger_print.d.ts.map +0 -1
  255. package/src/engine/graphics/texture/virtual/tile/compose_finger_print.js +0 -24
  256. package/src/engine/graphics/texture/virtual/tile/compose_tile_address.d.ts +0 -9
  257. package/src/engine/graphics/texture/virtual/tile/compose_tile_address.d.ts.map +0 -1
  258. package/src/engine/graphics/texture/virtual/tile/compose_tile_address.js +0 -26
  259. package/src/engine/graphics/texture/virtual/tile/decompose_finger_print.d.ts +0 -11
  260. package/src/engine/graphics/texture/virtual/tile/decompose_finger_print.d.ts.map +0 -1
  261. package/src/engine/graphics/texture/virtual/tile/decompose_finger_print.js +0 -12
  262. package/src/engine/graphics/texture/virtual/tile/finger_print_to_tile_address.d.ts +0 -7
  263. package/src/engine/graphics/texture/virtual/tile/finger_print_to_tile_address.d.ts.map +0 -1
  264. package/src/engine/graphics/texture/virtual/tile/finger_print_to_tile_address.js +0 -16
  265. package/src/engine/graphics/texture/virtual/tile/tile_address_to_finger_print.d.ts +0 -7
  266. package/src/engine/graphics/texture/virtual/tile/tile_address_to_finger_print.d.ts.map +0 -1
  267. package/src/engine/graphics/texture/virtual/tile/tile_address_to_finger_print.js +0 -35
@@ -0,0 +1,49 @@
1
+ /**
2
+ * What a {@link VGeoResidencyManager} is allowed to spend.
3
+ *
4
+ * @author Alex Goldring
5
+ * @copyright Company Named Limited (c) 2026
6
+ */
7
+ export class VGeoResidencyOptions {
8
+ /**
9
+ * The RAM tier's budget: decoded page bytes, summed over every registered reader.
10
+ *
11
+ * Design §6 pins the tiers — CDN ⊇ RAM ⊇ VRAM — and says residency is a small fraction of the
12
+ * asset in RAM. What makes a number necessary rather than advisory is scale: a thousand assets
13
+ * of a hundred million triangles each are several gigabytes of pages *apiece*, so the resident
14
+ * set has to be a small fraction of *one* of them, and nothing about a single reader can know
15
+ * that. 512 MiB is a default to be overridden by whoever knows the device, not a measurement.
16
+ *
17
+ * It is spent against `VGeoContainerReader.resident_bytes`, which is decoded page images and
18
+ * not what those pages cost in the heap — the reader's own per-page bookkeeping measured
19
+ * 6.4–11.9 KB on top of each image, which is 1.2% at the page sizes design §5 targets. A budget
20
+ * set against unusually small pages should allow for it.
21
+ *
22
+ * @type {number}
23
+ */
24
+ budget_bytes: number;
25
+ /**
26
+ * How many page fetches may be in flight at once, across every registered reader.
27
+ *
28
+ * The number that matters to a browser and to a CDN, and the one no reader can set: eight
29
+ * readers at the per-reader default of 6 were measured issuing 48 concurrent range requests.
30
+ * Twelve is more than one HTTP/1.1 connection pool will give and less than an H2/H3 multiplex
31
+ * will happily carry, which is the range this wants to sit in.
32
+ *
33
+ * @type {number}
34
+ */
35
+ max_concurrent_fetches: number;
36
+ /**
37
+ * How many frames a page is protected from eviction after it was last touched.
38
+ *
39
+ * Design §6: eviction is LRU on **last-touched**, with a protect window no shorter than the
40
+ * feedback latency. The window is what stops the classic fallback-chain bug — feedback arrives a
41
+ * frame or three late, so a page that is on screen right now may not have been reported as
42
+ * touched yet, and evicting on a stamp that has not caught up evicts exactly what is being
43
+ * drawn. Three frames is one `mapAsync` round trip's worth of slack.
44
+ *
45
+ * @type {number}
46
+ */
47
+ protect_frames: number;
48
+ }
49
+ //# sourceMappingURL=VGeoResidencyOptions.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"VGeoResidencyOptions.d.ts","sourceRoot":"","sources":["../../../../../../../src/shade/renderer/geometry/virtual/residency/VGeoResidencyOptions.js"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH;IACI;;;;;;;;;;;;;;;OAeG;IACH,cAFU,MAAM,CAEiB;IAEjC;;;;;;;;;OASG;IACH,wBAFU,MAAM,CAEY;IAE5B;;;;;;;;;;OAUG;IACH,gBAFU,MAAM,CAEG;CACtB"}
@@ -0,0 +1,50 @@
1
+ /**
2
+ * What a {@link VGeoResidencyManager} is allowed to spend.
3
+ *
4
+ * @author Alex Goldring
5
+ * @copyright Company Named Limited (c) 2026
6
+ */
7
+ export class VGeoResidencyOptions {
8
+ /**
9
+ * The RAM tier's budget: decoded page bytes, summed over every registered reader.
10
+ *
11
+ * Design §6 pins the tiers — CDN ⊇ RAM ⊇ VRAM — and says residency is a small fraction of the
12
+ * asset in RAM. What makes a number necessary rather than advisory is scale: a thousand assets
13
+ * of a hundred million triangles each are several gigabytes of pages *apiece*, so the resident
14
+ * set has to be a small fraction of *one* of them, and nothing about a single reader can know
15
+ * that. 512 MiB is a default to be overridden by whoever knows the device, not a measurement.
16
+ *
17
+ * It is spent against `VGeoContainerReader.resident_bytes`, which is decoded page images and
18
+ * not what those pages cost in the heap — the reader's own per-page bookkeeping measured
19
+ * 6.4–11.9 KB on top of each image, which is 1.2% at the page sizes design §5 targets. A budget
20
+ * set against unusually small pages should allow for it.
21
+ *
22
+ * @type {number}
23
+ */
24
+ budget_bytes = 512 * 1024 * 1024;
25
+
26
+ /**
27
+ * How many page fetches may be in flight at once, across every registered reader.
28
+ *
29
+ * The number that matters to a browser and to a CDN, and the one no reader can set: eight
30
+ * readers at the per-reader default of 6 were measured issuing 48 concurrent range requests.
31
+ * Twelve is more than one HTTP/1.1 connection pool will give and less than an H2/H3 multiplex
32
+ * will happily carry, which is the range this wants to sit in.
33
+ *
34
+ * @type {number}
35
+ */
36
+ max_concurrent_fetches = 12;
37
+
38
+ /**
39
+ * How many frames a page is protected from eviction after it was last touched.
40
+ *
41
+ * Design §6: eviction is LRU on **last-touched**, with a protect window no shorter than the
42
+ * feedback latency. The window is what stops the classic fallback-chain bug — feedback arrives a
43
+ * frame or three late, so a page that is on screen right now may not have been reported as
44
+ * touched yet, and evicting on a stamp that has not caught up evicts exactly what is being
45
+ * drawn. Three frames is one `mapAsync` round trip's worth of slack.
46
+ *
47
+ * @type {number}
48
+ */
49
+ protect_frames = 3;
50
+ }
@@ -13,7 +13,7 @@ export class TinyGltf {
13
13
  * @readonly
14
14
  * @type {TextureFormat}
15
15
  */
16
- static readonly "__#230@#UNCOMPRESSED_TARGET": TextureFormat;
16
+ static readonly "__#232@#UNCOMPRESSED_TARGET": TextureFormat;
17
17
  /**
18
18
  * @param {AssetManager} assetManager
19
19
  * @param {AssetRequestScope} [scope]
@@ -53,7 +53,7 @@ export class NSS {
53
53
  * @returns {number}
54
54
  */
55
55
  static recommended_jitter_sequence_size(upscale_ratio: number): number;
56
- static "__#164@#preprocess_tensor_descriptor"(render_w: any, render_h: any): TextureResourceDescriptor;
56
+ static "__#166@#preprocess_tensor_descriptor"(render_w: any, render_h: any): TextureResourceDescriptor;
57
57
  /**
58
58
  * @param {GraphicsContext} graphics
59
59
  */
@@ -3,6 +3,7 @@ export class GPUBindlessTextureManager {
3
3
  initial_size?: number;
4
4
  device: any;
5
5
  });
6
+ get buffer_data(): GPUBuffer;
6
7
  /**
7
8
  *
8
9
  * @param {number} slot_id
@@ -23,6 +24,8 @@ import { TextureDescriptor } from "../../../descriptor/texture/TextureDescriptor
23
24
  declare class GPUBindlessTexture {
24
25
  slot: number;
25
26
  /**
27
+ * Byte range inside {@link GPUBindlessTextureManager#buffer_data}. Handed out once and never
28
+ * revised — the manager makes room by appending to the arena, not by re-packing it.
26
29
  * @type {Allocation}
27
30
  */
28
31
  allocation: Allocation;
@@ -1 +1 @@
1
- {"version":3,"file":"GPUBindlessTextureManager.d.ts","sourceRoot":"","sources":["../../../../../../src/shade/renderer/texture/bindless/GPUBindlessTextureManager.js"],"names":[],"mappings":"AA4BA;IAkBI;;;OAeC;IAcD;;;;;OAKG;IACH,aAJW,MAAM,UACN,iBAAiB,GACf,kBAAkB,CAwD9B;IAED;;;;;OAKG;IACH,wCAHW,kBAAkB,cAClB,MAAM,QAKhB;;CAGJ;kCAnJiC,kDAAkD;AAQpF;IACI,aAAS;IAET;;OAEG;IACH,uBAAU;IACV,8BAAqC;CACxC"}
1
+ {"version":3,"file":"GPUBindlessTextureManager.d.ts","sourceRoot":"","sources":["../../../../../../src/shade/renderer/texture/bindless/GPUBindlessTextureManager.js"],"names":[],"mappings":"AAsDA;IA0BI;;;OAuBC;IAhCD,6BAEC;IAmGD;;;;;OAKG;IACH,aAJW,MAAM,UACN,iBAAiB,GACf,kBAAkB,CA2D9B;IAED;;;;;OAKG;IACH,wCAHW,kBAAkB,cAClB,MAAM,QAKhB;;CAGJ;kCAvPiC,kDAAkD;AAgCpF;IACI,aAAS;IAET;;;;OAIG;IACH,uBAAU;IACV,8BAAqC;CACxC"}
@@ -8,10 +8,36 @@ import { parse_gpu_texture_format } from "../../../descriptor/texture/format/par
8
8
 
9
9
  const DEFAULT_INITIAL_SIZE_BYTES = 1024;
10
10
 
11
+ /**
12
+ * `copyBufferToBuffer` moves whole 4-byte units and the arena is enlarged by copying all of it, so
13
+ * every size this manager gives the device is a multiple of this.
14
+ * @type {number}
15
+ */
16
+ const ARENA_GRANULARITY_BYTES = 4;
17
+
18
+ /**
19
+ * How many times {@link GPUBindlessTextureManager#set} enlarges the arena for one texture before
20
+ * giving up. Growth is sized to fit the request that failed, so the retry after the first one is
21
+ * expected to be the last. The bound is here because an allocator out of nodes refuses a request of
22
+ * any size, and answering that with an unbounded loop would enlarge the buffer forever.
23
+ * @type {number}
24
+ */
25
+ const MAX_GROWTH_ATTEMPTS_PER_TEXTURE = 2;
26
+
27
+ /**
28
+ * @param {number} size in bytes
29
+ * @returns {number}
30
+ */
31
+ function round_up_to_arena_granularity(size) {
32
+ return Math.ceil(size / ARENA_GRANULARITY_BYTES) * ARENA_GRANULARITY_BYTES;
33
+ }
34
+
11
35
  class GPUBindlessTexture {
12
36
  slot = 0;
13
37
 
14
38
  /**
39
+ * Byte range inside {@link GPUBindlessTextureManager#buffer_data}. Handed out once and never
40
+ * revised — the manager makes room by appending to the arena, not by re-packing it.
15
41
  * @type {Allocation}
16
42
  */
17
43
  allocation
@@ -43,34 +69,105 @@ export class GPUBindlessTextureManager {
43
69
  */
44
70
  #data_buffer;
45
71
 
72
+ get buffer_data() {
73
+ return this.#data_buffer;
74
+ }
75
+
76
+ /**
77
+ * @type {GPUDevice}
78
+ */
79
+ #device;
46
80
 
47
81
  constructor({
48
82
  initial_size = DEFAULT_INITIAL_SIZE_BYTES,
49
83
  device
50
84
  }) {
85
+ assert.defined(device, 'device');
86
+ assert.isNonNegativeInteger(initial_size, 'initial_size');
87
+ assert.greaterThan(initial_size, 0, 'initial_size');
88
+
89
+ const arena_size = round_up_to_arena_granularity(initial_size);
51
90
 
52
- this.#allocator = new OffsetAllocator(initial_size);
91
+ this.#device = device;
92
+
93
+ this.#allocator = new OffsetAllocator(arena_size);
53
94
  this.#headers = new GPUSingleTypeTable({
54
95
  device,
55
96
  type: BINDLESS_TEXTURE_HEADER_STRUCT,
56
97
  });
57
98
 
58
99
  this.#data_buffer = device.createBuffer({
59
- size: initial_size,
100
+ label: 'GPUBindlessTextureManager/data',
101
+ size: arena_size,
60
102
  usage: GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_DST | GPUBufferUsage.COPY_SRC,
61
103
  });
62
104
  }
63
105
 
64
- #grow() {
65
- throw new Error('Not implemented')
66
- }
67
-
68
106
  /**
107
+ * Enlarge the data arena so that a `required_size` allocation has room, leaving every texture
108
+ * already in it exactly where it is.
69
109
  *
70
- * @param {number} new_size
110
+ * Nothing relocates: a texture is addressed by the offset the allocator handed out,
111
+ * {@link OffsetAllocator#grow} appends the new tail as free space instead of re-packing, and the
112
+ * old bytes are copied into the larger buffer at offset 0 — so every live
113
+ * {@link GPUBindlessTexture#allocation} still names the bytes it named before the call, with no
114
+ * per-texture bookkeeping at all.
115
+ *
116
+ * Stops at the device's `maxBufferSize`, and does nothing at all once there. A texture that
117
+ * cannot be housed is then reported by the failed allocation in {@link set}.
118
+ *
119
+ * @param {number} required_size in bytes, the allocation that did not fit
71
120
  */
72
- #resize(new_size) {
73
- throw new Error('Not implemented')
121
+ #grow(required_size) {
122
+ assert.isNonNegativeInteger(required_size, 'required_size');
123
+
124
+ const device = this.#device;
125
+
126
+ const old_buffer = this.#data_buffer;
127
+ const old_size = old_buffer.size;
128
+
129
+ // The allocator bins free runs by rounding down and requests by rounding up, up to 9/8
130
+ // apart, so room for exactly `required_size` can still be refused — hence the headroom.
131
+ // Doubling on top of that keeps a run of small textures from paying for a copy of the whole
132
+ // arena apiece. The ceiling is the device's: `createBuffer` answers a size past
133
+ // `maxBufferSize` with an *invalid* buffer rather than an exception, and swapping one of
134
+ // those in would destroy the arena and leave the allocator sized for space that is not
135
+ // there, silently.
136
+ const new_size = Math.min(
137
+ round_up_to_arena_granularity(Math.max(
138
+ old_size * 2,
139
+ old_size + required_size * 9 / 8
140
+ )),
141
+ Math.floor(device.limits.maxBufferSize / ARENA_GRANULARITY_BYTES) * ARENA_GRANULARITY_BYTES
142
+ );
143
+
144
+ if (new_size <= old_size) {
145
+ // already as large as this device will allow
146
+ return;
147
+ }
148
+
149
+ const new_buffer = device.createBuffer({
150
+ label: old_buffer.label,
151
+ size: new_size,
152
+ usage: old_buffer.usage,
153
+ });
154
+
155
+ // past the fallible part — `OffsetAllocator#grow` cannot be undone
156
+ this.#allocator.grow(new_size);
157
+
158
+ const encoder = device.createCommandEncoder({
159
+ label: 'GPUBindlessTextureManager/grow',
160
+ });
161
+
162
+ // One copy of the whole old arena at offset 0. Offsets did not move, so the bytes land back
163
+ // under the addresses the textures holding them already have.
164
+ encoder.copyBufferToBuffer(old_buffer, 0, new_buffer, 0, old_size);
165
+
166
+ device.queue.submit([encoder.finish()]);
167
+
168
+ old_buffer.destroy();
169
+
170
+ this.#data_buffer = new_buffer;
74
171
  }
75
172
 
76
173
  /**
@@ -115,24 +212,27 @@ export class GPUBindlessTextureManager {
115
212
 
116
213
  const allocation_size = texel_count * attribute.getByteSize();
117
214
 
215
+ let allocation = this.#allocator.allocate(allocation_size);
118
216
 
119
- while (true) {
120
- // attempt allocation
121
- const allocation = this.#allocator.allocate(allocation_size);
122
-
123
- if (allocation.offset === ALLOCATOR_NO_SPACE) {
124
- // try to enlarge the buffer
125
- this.#grow();
126
- continue;
127
- }
217
+ for (
218
+ let attempt = 0;
219
+ allocation.offset === ALLOCATOR_NO_SPACE && attempt < MAX_GROWTH_ATTEMPTS_PER_TEXTURE;
220
+ attempt++
221
+ ) {
222
+ this.#grow(allocation_size);
128
223
 
129
- texture.allocation = allocation;
224
+ allocation = this.#allocator.allocate(allocation_size);
225
+ }
130
226
 
131
- break;
227
+ if (allocation.offset === ALLOCATOR_NO_SPACE) {
228
+ throw new Error(`Failed to allocate ${allocation_size} bytes for bindless texture in slot ${slot_id}`);
132
229
  }
133
230
 
231
+ texture.allocation = allocation;
232
+
134
233
  this.#headers.set(slot_id, {});
135
234
 
235
+ return texture;
136
236
  }
137
237
 
138
238
  /**
@@ -147,4 +247,4 @@ export class GPUBindlessTextureManager {
147
247
  }
148
248
 
149
249
 
150
- }
250
+ }
@@ -6,10 +6,12 @@ textures, with GPU memory bounded by what is visible instead of what is
6
6
  loaded. Built for **hundreds of simultaneous virtual textures** sharing one
7
7
  page table, one physical cache and one feedback pass.
8
8
 
9
- This README covers adopting the system, configuration and the working
10
- design. The extended design document — literature survey,
11
- decision log, scale math, future work — is [`VIRTUAL_TEXTURES.md`](../../../../VIRTUAL_TEXTURES.md)
12
- in the repo root.
9
+ This README is the design document: adopting the system, configuration and
10
+ how it works. It used to defer the extended treatment — literature survey,
11
+ decision log, scale math, future work — to a `VIRTUAL_TEXTURES.md` in the
12
+ repo root, but that file belonged to the repository Shade was vendored from
13
+ and never came across. The decision log is under "How it works" below; the
14
+ scale numbers are in the configuration table.
13
15
 
14
16
  ---
15
17
 
@@ -1 +1 @@
1
- {"version":3,"file":"VirtualTextureManager.d.ts","sourceRoot":"","sources":["../../../../../../src/shade/renderer/texture/virtual/VirtualTextureManager.js"],"names":[],"mappings":"AAgHA;;;;;;;;;;;;;;;;;;;;GAoBG;AACH;IA4KI;;;OAGG;IACH,+BAIC;IAvBD;;OAEG;IACH;;;;;;;;;;MAUE;IAYF;;;OAGG;IACH,8BAIC;IAED;;OAEG;IACH,sBAEC;IAED;;OAEG;IACH,kBAEC;IAED;;;OAGG;IACH,2EAIC;IAED;;OAEG;IACH,qCAIC;IAED;;OAEG;IACH,mCAIC;IAED;;OAEG;IACH,6BAIC;IAED;;OAEG;IACH,sCAIC;IAED;;OAEG;IACH,gCAIC;IAED;;;;OAIG;IACH,uIAQC;IA8DD;;;;;;;OAOG;IACH,sBAHW,mBAAmB,GACjB,MAAM,CA6FlB;IAED;;;;;OAKG;IACH,wBAFW,mBAAmB,QAgF7B;IA8ED;;;;;;;;;OASG;IACH,wBAFW,WAAW,QAoFrB;IA8KD;;;;;;OAMG;IACH,wBAqBC;IAED;;;OAGG;IACH,eA2GC;IAID;;;;;;;;;;;;OAYG;IACH;QAN4B,KAAK,EAAtB,UAAU;QACW,IAAI,EAAzB,cAAc;QACD,gBAAgB,EAA7B,MAAM;QACO,oBAAoB,EAAjC,MAAM;QACU,wBAAwB;aA6FlD;IAED,gBA8BC;;CACJ;yBAruCY,OAAO,8DAA8D,EAAE,UAAU;uCACjF,OAAO,iEAAiE,EAAE,wBAAwB;wBAClG,OAAO,oCAAoC,EAAE,SAAS;6BACtD,OAAO,8BAA8B,EAAE,cAAc;kCACrD,OAAO,0BAA0B,EAAE,mBAAmB;gCAPnC,sBAAsB"}
1
+ {"version":3,"file":"VirtualTextureManager.d.ts","sourceRoot":"","sources":["../../../../../../src/shade/renderer/texture/virtual/VirtualTextureManager.js"],"names":[],"mappings":"AAgHA;;;;;;;;;;;;;;;;;;;;GAoBG;AACH;IA4KI;;;OAGG;IACH,+BAIC;IAvBD;;OAEG;IACH;;;;;;;;;;MAUE;IAYF;;;OAGG;IACH,8BAIC;IAED;;OAEG;IACH,sBAEC;IAED;;OAEG;IACH,kBAEC;IAED;;;OAGG;IACH,2EAIC;IAED;;OAEG;IACH,qCAIC;IAED;;OAEG;IACH,mCAIC;IAED;;OAEG;IACH,6BAIC;IAED;;OAEG;IACH,sCAIC;IAED;;OAEG;IACH,gCAIC;IAED;;;;OAIG;IACH,uIAQC;IA8DD;;;;;;;OAOG;IACH,sBAHW,mBAAmB,GACjB,MAAM,CA6FlB;IAED;;;;;OAKG;IACH,wBAFW,mBAAmB,QAgF7B;IA8ED;;;;;;;;;OASG;IACH,wBAFW,WAAW,QAoFrB;IA8KD;;;;;;OAMG;IACH,wBAqBC;IAED;;;OAGG;IACH,eAkHC;IAID;;;;;;;;;;;;OAYG;IACH;QAN4B,KAAK,EAAtB,UAAU;QACW,IAAI,EAAzB,cAAc;QACD,gBAAgB,EAA7B,MAAM;QACO,oBAAoB,EAAjC,MAAM;QACU,wBAAwB;aA6FlD;IAED,gBA8BC;;CACJ;yBA5uCY,OAAO,8DAA8D,EAAE,UAAU;uCACjF,OAAO,iEAAiE,EAAE,wBAAwB;wBAClG,OAAO,oCAAoC,EAAE,SAAS;6BACtD,OAAO,8BAA8B,EAAE,cAAc;kCACrD,OAAO,0BAA0B,EAAE,mBAAmB;gCAPnC,sBAAsB"}
@@ -1100,6 +1100,13 @@ export class VirtualTextureManager {
1100
1100
  }
1101
1101
 
1102
1102
  // 5. issue loads, coarse mips first (they unblock the most screen area)
1103
+ //
1104
+ // Deliberately not a `core/process/ConcurrencyGate`. That gate orders by a priority
1105
+ // captured at submission and runs every closure it accepts. This order is not a
1106
+ // priority: coarse-first is the residency property that keeps the cache correct as it
1107
+ // fills, and it is re-derived from the live pending records here rather than fixed when
1108
+ // the request was made. Step 4 above then *drops* queued work that stopped being
1109
+ // touched, which a queue of closures has no way to express.
1103
1110
  if (this.#queue.length > 0 && this.#loads_in_flight < config.max_concurrent_loads) {
1104
1111
  this.#queue.sort((a, b) => {
1105
1112
  const pa = this.#pending.get(a);
@@ -11,9 +11,9 @@
11
11
  * through the HTTP cache at memory speed).
12
12
  *
13
13
  * `legacy_meep_mips: true` maps mip indices to the original meep
14
- * virtual-texture converter's naming, where 0 is the *coarsest* level
15
- * (`${mip}-${x}-${y}.png`, see meep src/engine/graphics/texture/virtual):
16
- * pair it with url_template "{mip}-{x}-{y}.png" and per-layer base paths.
14
+ * virtual-texture converter's naming, where 0 is the *coarsest* level and
15
+ * tiles are written as `${mip}-${x}-${y}.png`: pair it with url_template
16
+ * "{mip}-{x}-{y}.png" and per-layer base paths.
17
17
  *
18
18
  * Decode notes: `colorSpaceConversion: 'none'` keeps browser colour
19
19
  * management from rewriting texels (tile seams, corrupted normal maps);
@@ -13,9 +13,9 @@ import { assert } from "../../../../../core/assert.js";
13
13
  * through the HTTP cache at memory speed).
14
14
  *
15
15
  * `legacy_meep_mips: true` maps mip indices to the original meep
16
- * virtual-texture converter's naming, where 0 is the *coarsest* level
17
- * (`${mip}-${x}-${y}.png`, see meep src/engine/graphics/texture/virtual):
18
- * pair it with url_template "{mip}-{x}-{y}.png" and per-layer base paths.
16
+ * virtual-texture converter's naming, where 0 is the *coarsest* level and
17
+ * tiles are written as `${mip}-${x}-${y}.png`: pair it with url_template
18
+ * "{mip}-{x}-{y}.png" and per-layer base paths.
19
19
  *
20
20
  * Decode notes: `colorSpaceConversion: 'none'` keeps browser colour
21
21
  * management from rewriting texels (tile seams, corrupted normal maps);
@@ -1,9 +0,0 @@
1
- /**
2
- * *
3
- */
4
- export type SystemExecutionPhase = number;
5
- export namespace SystemExecutionPhase {
6
- let Simulation: number;
7
- let PostPose: number;
8
- }
9
- //# sourceMappingURL=SystemExecutionPhase.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"SystemExecutionPhase.d.ts","sourceRoot":"","sources":["../../../../../src/engine/ecs/system/SystemExecutionPhase.js"],"names":[],"mappings":";;;mCA2CU,MAAM;;oBASF,MAAM;kBAYN,MAAM"}
@@ -1,128 +0,0 @@
1
- # Sparse Virtual Texture
2
-
3
- This tech is based on popular Megatexture technique developed for Rage by John Carmack, working at id software.
4
-
5
- The key idea boils down to having a very large texture that is impractical to keep in memory, and only load and keep in memory pieces of it that are relevant to the current view.
6
-
7
- There are 2 parts to this technique, offline and online.
8
-
9
- ## Offline
10
-
11
- The original texture is mip-mapped, down to the size of a single tile, for the sake of this document let it be 128x128 pixels. Each mip level is then cut into tiles and stored on disk. A good intuition for this is to think of each tile as a separate pixel, representing non-color data.
12
-
13
- ## Online
14
-
15
- This is achieved by pre-rendering the scene with a special shader that records UV and mip-level information, which we call `Usage`, this is then analysed to build a list of used tiles (mip level, x, y) and by counting occurrence of this tile in the `Usage` texture we get a much more useful data structure.
16
-
17
- Based on the `Usage` data, we populate our `Physical` texture of pages, and based on what's currently in the `Physical` texture - we populate the `Reference` texture that stores information about the entire mip pyramid, and for each tile contains a pointer to the `Physical` texture, where representative tile can be found.
18
-
19
-
20
- ## Considerations
21
-
22
-
23
- ### Filtering
24
-
25
- Most papers suggest introducing a border into each tile of ~4 pixels.
26
- 4 pixel border on a 128x128 pixel tile is going to take up 12.1% of space, which is quite a lot.
27
- We can do filtering in software, that is - sample individual pixels and perform interpolation inside the shader.
28
-
29
- ### Speeding up WebGL read-back
30
-
31
- From [Babylon](https://github.com/BabylonJS/Babylon.js/blob/90dbafed8de9de752cdc399604f9c7c51116d630/src/Engines/engine.ts#L1772)
32
- ```ts
33
- public _readPixelsAsync(x: number, y: number, w: number, h: number, format: number, type: number, outputBuffer: ArrayBufferView) {
34
- if (this._webGLVersion < 2) {
35
- throw new Error("_readPixelsAsync only work on WebGL2+");
36
- }
37
-
38
- let gl = <WebGL2RenderingContext>(this._gl as any);
39
- const buf = gl.createBuffer();
40
- gl.bindBuffer(gl.PIXEL_PACK_BUFFER, buf);
41
- gl.bufferData(gl.PIXEL_PACK_BUFFER, outputBuffer.byteLength, gl.STREAM_READ);
42
- gl.readPixels(x, y, w, h, format, type, 0);
43
- gl.bindBuffer(gl.PIXEL_PACK_BUFFER, null);
44
-
45
- const sync = gl.fenceSync(gl.SYNC_GPU_COMMANDS_COMPLETE, 0);
46
- if (!sync) {
47
- return null;
48
- }
49
-
50
- gl.flush();
51
-
52
- return this._clientWaitAsync(sync, 0, 10).then(() => {
53
- gl.deleteSync(sync);
54
-
55
- gl.bindBuffer(gl.PIXEL_PACK_BUFFER, buf);
56
- gl.getBufferSubData(gl.PIXEL_PACK_BUFFER, 0, outputBuffer);
57
- gl.bindBuffer(gl.PIXEL_PACK_BUFFER, null);
58
- gl.deleteBuffer(buf);
59
-
60
- return outputBuffer;
61
- });
62
- }
63
-
64
- private _clientWaitAsync(sync: WebGLSync, flags = 0, intervalms = 10): Promise<void> {
65
- const gl = <WebGL2RenderingContext>(this._gl as any);
66
- return new Promise((resolve, reject) => {
67
- const check = () => {
68
- const res = gl.clientWaitSync(sync, flags, 0);
69
- if (res == gl.WAIT_FAILED) {
70
- reject();
71
- return;
72
- }
73
- if (res == gl.TIMEOUT_EXPIRED) {
74
- setTimeout(check, intervalms);
75
- return;
76
- }
77
- resolve();
78
- };
79
-
80
- check();
81
- });
82
- }
83
- ```
84
-
85
- more links:
86
- https://forum.babylonjs.com/t/speeding-up-readpixels/12739
87
-
88
-
89
- ## References
90
-
91
- * [Shadertoy: Anisotropic filtering in a shader](https://www.shadertoy.com/view/4lXfzn)
92
- * ["Adaptive Virtual Texture Rendering in Far Cry 4" by Ka Chen, Ubisoft. 2015](https://ubm-twvideo01.s3.amazonaws.com/o1/vault/gdc2015/presentations/Chen_Ka_AdaptiveVirtualTexture.pdf)
93
- * "id Tech 5 Challenges: From Texture Virtualization to Massive Parallelization" by J.M.P. van Waveren, id Software, SIGGRAPH 2009
94
- * "Using Virtual Texturing to Handle Massive Texture Data" by J.M.P. van Waveren, id Software, 2010
95
- * "Software Virtual Textures" by J.M.P. van Waveren, id Software, 2012
96
- * "Advanced Virtual Texture Topics" by Matrin Mittring, Crytek GmbH, SIGGRAPH 2008
97
- * "Atlas Shrugged: Device-agnostic Radiance Megatextures" by Mark Magro et al, University of Malta, VISIGRAPP 2020
98
- * ["Sparse virtual textures" by Nathan Gauër, 2022](https://studiopixl.com/2022-04-27/sparse-virtual-textures)
99
- * "Terrain in Battlefield 3: A modern, complete and scalable system" by Mattias Widmark, EA Digital Illusions (DICE), GDC 2012
100
- * "Virtual Texturing in Software and Hardware" by Juraj Obert (AMD) et al, SIGGRAPH 2012
101
- * "Virtual Texturing" by Albert Julian Mayer, 2010
102
-
103
- ## WebGL fails
104
-
105
- WebGL doesn't seem to support mipmaps on integer textures
106
-
107
- ## Anisotropic filtering:
108
-
109
- ```glsl
110
- // R is viewport resolution
111
- // p is UV
112
- vec4 textureAniso(sampler2D T, vec2 R, vec2 p) {
113
- mat2 J = inverse(mat2(dFdx(p),dFdy(p))); // dFdxy: pixel footprint in texture space
114
- J = transpose(J)*J; // quadratic form
115
- float d = determinant(J), t = J[0][0]+J[1][1], // find ellipse: eigenvalues, max eigenvector
116
- D = sqrt(abs(t*t-4.*d)), // abs() fix a bug: in weird view angles 0 can be slightly negative
117
- V = (t-D)/2., v = (t+D)/2., // eigenvalues. ( ATTENTION: not sorted )
118
- M = 1./sqrt(V), m = 1./sqrt(v), l =log2(m*R.y); // = 1./radii^2
119
-
120
- //if (M/m>16.) l = log2(M/16.*R.y); // optional
121
-
122
- vec2 A = M * normalize(vec2( -J[0][1] , J[0][0]-V )); // max eigenvector = main axis
123
- vec4 O = vec4(0);
124
- for (float i = -7.5; i<8.; i++) // sample x16 along main axis at LOD min-radius
125
- O += textureLod(T, p+(i/16.)*A, l);
126
- return O/16.;
127
- }
128
- ```
@@ -1,6 +0,0 @@
1
- /**
2
- * Default resolution of virtual page texture
3
- * @type {number}
4
- */
5
- export const VT_DEFAULT_PAGE_RESOLUTION: number;
6
- //# sourceMappingURL=VT_DEFAULT_PAGE_RESOLUTION.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"VT_DEFAULT_PAGE_RESOLUTION.d.ts","sourceRoot":"","sources":["../../../../../../src/engine/graphics/texture/virtual/VT_DEFAULT_PAGE_RESOLUTION.js"],"names":[],"mappings":"AAAA;;;GAGG;AACH,yCAFU,MAAM,CAE+B"}
@@ -1,5 +0,0 @@
1
- /**
2
- * Default resolution of virtual page texture
3
- * @type {number}
4
- */
5
- export const VT_DEFAULT_PAGE_RESOLUTION = 4096;
@@ -1,49 +0,0 @@
1
- /**
2
- * Facilitates prioritized queueing and loading of individual texture tiles
3
- */
4
- export class VirtualTextureTileLoader {
5
- /**
6
- *
7
- * @param {(mip: number, x: number, y: number) => string} builder
8
- */
9
- set file_name_builder(builder: (arg0: number, arg1: number, arg2: number) => string);
10
- /**
11
- *
12
- * @return {function(number, number, number): string}
13
- */
14
- get file_name_builder(): (arg0: number, arg1: number, arg2: number) => string;
15
- set path(v: any);
16
- /**
17
- * When queue gets larger than this, we start discarding elements
18
- * @type {number}
19
- */
20
- queue_limit: number;
21
- set asset_manager(v: any);
22
- /**
23
- * @readonly
24
- */
25
- readonly on: {
26
- /**
27
- * @type {Signal<VirtualTextureTile>}
28
- */
29
- loaded: any;
30
- };
31
- /**
32
- *
33
- * @param {number} fingerprint
34
- */
35
- enqueue(fingerprint: number): boolean;
36
- /**
37
- *
38
- * @param {number} fingerprint
39
- * @returns {boolean}
40
- */
41
- is_queued(fingerprint: number): boolean;
42
- /**
43
- *
44
- * @param {VirtualTextureUsage} usage
45
- */
46
- update_usage(usage: VirtualTextureUsage): void;
47
- #private;
48
- }
49
- //# sourceMappingURL=VirtualTextureTileLoader.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"VirtualTextureTileLoader.d.ts","sourceRoot":"","sources":["../../../../../../src/engine/graphics/texture/virtual/VirtualTextureTileLoader.js"],"names":[],"mappings":"AAYA;;GAEG;AACH;IA6BI;;;OAGG;IACH,sCAVqB,MAAM,QAAE,MAAM,QAAE,MAAM,KAAG,MAAM,EAcnD;IAhBD;;;OAGG;IACH,gCAFqB,MAAM,QAAE,MAAM,QAAE,MAAM,KAAG,MAAM,CAInD;IAYD,iBAEC;IAED;;;OAGG;IACH,aAFU,MAAM,CAEO;IAQvB,0BAEC;IAsBD;;OAEG;IACH;QACI;;WAEG;;MAEL;IAkCF;;;OAGG;IACH,qBAFW,MAAM,WAchB;IAED;;;;OAIG;IACH,uBAHW,MAAM,GACJ,OAAO,CAMnB;IAsBD;;;OAGG;IACH,+CASC;;CAiEJ"}