@woosh/meep-engine 3.64.1 → 3.67.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 (372) hide show
  1. package/CHANGELOG.md +85 -0
  2. package/build/bundle-worker-image-decoder.js +1 -1
  3. package/build/bundle-worker-terrain.js +1 -1
  4. package/package.json +1 -1
  5. package/src/core/binary/BinaryBuffer.d.ts +5 -0
  6. package/src/core/binary/BinaryBuffer.d.ts.map +1 -1
  7. package/src/core/binary/BinaryBuffer.js +39 -5
  8. package/src/core/geom/3d/topology/struct/binary/io/bt_boundary_loop.d.ts +65 -6
  9. package/src/core/geom/3d/topology/struct/binary/io/bt_boundary_loop.d.ts.map +1 -1
  10. package/src/core/geom/3d/topology/struct/binary/io/bt_boundary_loop.js +451 -101
  11. package/src/core/geom/3d/topology/struct/binary/io/bt_mesh_close_boundary_holes.d.ts +4 -2
  12. package/src/core/geom/3d/topology/struct/binary/io/bt_mesh_close_boundary_holes.d.ts.map +1 -1
  13. package/src/core/geom/3d/topology/struct/binary/io/bt_mesh_close_boundary_holes.js +4 -2
  14. package/src/core/geom/3d/topology/struct/binary/io/bt_mesh_fill_small_holes.d.ts +8 -1
  15. package/src/core/geom/3d/topology/struct/binary/io/bt_mesh_fill_small_holes.d.ts.map +1 -1
  16. package/src/core/geom/3d/topology/struct/binary/io/bt_mesh_fill_small_holes.js +45 -10
  17. package/src/core/geom/3d/topology/struct/binary/query/bt_mesh_face_find_path_polyanya.d.ts.map +1 -1
  18. package/src/core/geom/3d/topology/struct/binary/query/bt_mesh_face_find_path_polyanya.js +237 -119
  19. package/src/engine/graphics/ecs/grass/GrassSpecies.d.ts +143 -0
  20. package/src/engine/graphics/ecs/grass/GrassSpecies.d.ts.map +1 -0
  21. package/src/engine/graphics/ecs/grass/GrassSpecies.js +189 -0
  22. package/src/engine/graphics/ecs/grass/GrassSurface.d.ts +25 -0
  23. package/src/engine/graphics/ecs/grass/GrassSurface.d.ts.map +1 -0
  24. package/src/engine/graphics/ecs/grass/GrassSurface.js +32 -0
  25. package/src/engine/graphics/ecs/grass/GroundCover.d.ts +68 -0
  26. package/src/engine/graphics/ecs/grass/GroundCover.d.ts.map +1 -0
  27. package/src/engine/graphics/ecs/grass/GroundCover.js +85 -0
  28. package/src/engine/graphics3/GrassSurfaceSystem.d.ts +153 -0
  29. package/src/engine/graphics3/GrassSurfaceSystem.d.ts.map +1 -0
  30. package/src/engine/graphics3/GrassSurfaceSystem.js +1076 -0
  31. package/src/engine/graphics3/GroundCoverSystem.d.ts +33 -0
  32. package/src/engine/graphics3/GroundCoverSystem.d.ts.map +1 -0
  33. package/src/engine/graphics3/GroundCoverSystem.js +58 -0
  34. package/src/engine/network/NetworkSession.d.ts.map +1 -1
  35. package/src/engine/network/NetworkSession.js +372 -110
  36. package/src/engine/network/orchestrator/NetworkPeer.d.ts.map +1 -1
  37. package/src/engine/network/orchestrator/NetworkPeer.js +6 -1
  38. package/src/engine/network/orchestrator/ServerAuthoritativeClient.d.ts.map +1 -1
  39. package/src/engine/network/orchestrator/ServerAuthoritativeClient.js +9 -2
  40. package/src/engine/network/orchestrator/ServerAuthoritativeServer.d.ts.map +1 -1
  41. package/src/engine/network/orchestrator/ServerAuthoritativeServer.js +325 -140
  42. package/src/engine/network/sim/SimActionExecutor.d.ts +4 -1
  43. package/src/engine/network/sim/SimActionExecutor.d.ts.map +1 -1
  44. package/src/engine/network/sim/SimActionExecutor.js +65 -9
  45. package/src/engine/network/state/PredictionHistory.d.ts.map +1 -1
  46. package/src/engine/network/state/PredictionHistory.js +6 -1
  47. package/src/engine/network/time/AdaptiveRenderDelay.d.ts +25 -14
  48. package/src/engine/network/time/AdaptiveRenderDelay.d.ts.map +1 -1
  49. package/src/engine/network/time/AdaptiveRenderDelay.js +38 -20
  50. package/src/engine/network/time/RenderPlayout.d.ts +23 -3
  51. package/src/engine/network/time/RenderPlayout.d.ts.map +1 -1
  52. package/src/engine/network/time/RenderPlayout.js +40 -4
  53. package/src/engine/physics/fluid/ecs/FluidObstacleSystem.d.ts +4 -4
  54. package/src/engine/physics/fluid/obstacle/chunk_fluid_obstacle_record.d.ts +5 -1
  55. package/src/engine/physics/fluid/obstacle/chunk_fluid_obstacle_record.d.ts.map +1 -1
  56. package/src/engine/physics/fluid/obstacle/chunk_fluid_obstacle_record.js +27 -1
  57. package/src/format/lut/cube/CubeLut.d.ts +38 -0
  58. package/src/format/lut/cube/CubeLut.d.ts.map +1 -0
  59. package/src/format/lut/cube/CubeLut.js +23 -0
  60. package/src/format/lut/cube/cube_read.d.ts +23 -0
  61. package/src/format/lut/cube/cube_read.d.ts.map +1 -0
  62. package/src/format/lut/cube/cube_read.js +199 -0
  63. package/src/format/lut/cube/cube_write.d.ts +15 -0
  64. package/src/format/lut/cube/cube_write.d.ts.map +1 -0
  65. package/src/format/lut/cube/cube_write.js +90 -0
  66. package/src/shade/device/shader/ShaderModuleCompiler.d.ts +2 -0
  67. package/src/shade/device/shader/ShaderModuleCompiler.d.ts.map +1 -1
  68. package/src/shade/device/shader/ShaderModuleCompiler.js +25 -2
  69. package/src/shade/playground/grass_surfaces/index.html +75 -0
  70. package/src/shade/playground/grass_surfaces/main.d.ts +2 -0
  71. package/src/shade/playground/grass_surfaces/main.d.ts.map +1 -0
  72. package/src/shade/playground/grass_surfaces/main.js +593 -0
  73. package/src/shade/playground/grass_surfaces/read_grass_surfaces.d.ts +62 -0
  74. package/src/shade/playground/grass_surfaces/read_grass_surfaces.d.ts.map +1 -0
  75. package/src/shade/playground/grass_surfaces/read_grass_surfaces.js +188 -0
  76. package/src/shade/playground/probe_clipmap/README.md +1 -0
  77. package/src/shade/playground/probe_clipmap/index.html +5 -0
  78. package/src/shade/playground/probe_clipmap/main.d.ts.map +1 -1
  79. package/src/shade/playground/probe_clipmap/main.js +7 -0
  80. package/src/shade/playground/probe_clipmap_box/README.md +5 -1
  81. package/src/shade/playground/probe_clipmap_box/index.html +12 -0
  82. package/src/shade/playground/probe_clipmap_box/main.d.ts.map +1 -1
  83. package/src/shade/playground/probe_clipmap_box/main.js +15 -0
  84. package/src/shade/playground/probe_clipmap_box/scene.d.ts +8 -1
  85. package/src/shade/playground/probe_clipmap_box/scene.d.ts.map +1 -1
  86. package/src/shade/playground/probe_clipmap_box/scene.js +74 -6
  87. package/src/shade/renderer/Renderer.d.ts.map +1 -1
  88. package/src/shade/renderer/Renderer.js +59 -55
  89. package/src/shade/renderer/deferred/tonemap/ColorGrade.d.ts +73 -4
  90. package/src/shade/renderer/deferred/tonemap/ColorGrade.d.ts.map +1 -1
  91. package/src/shade/renderer/deferred/tonemap/ColorGrade.js +113 -7
  92. package/src/shade/renderer/deferred/tonemap/TONEMAP_PURKINJE_SHIFT.d.ts +12 -0
  93. package/src/shade/renderer/deferred/tonemap/TONEMAP_PURKINJE_SHIFT.d.ts.map +1 -0
  94. package/src/shade/renderer/deferred/tonemap/TONEMAP_PURKINJE_SHIFT.js +12 -0
  95. package/src/shade/renderer/deferred/tonemap/ToneMapper.d.ts +15 -1
  96. package/src/shade/renderer/deferred/tonemap/ToneMapper.d.ts.map +1 -1
  97. package/src/shade/renderer/deferred/tonemap/ToneMapper.js +31 -3
  98. package/src/shade/renderer/deferred/tonemap/chunk_tonemap_purkinje.d.ts +25 -0
  99. package/src/shade/renderer/deferred/tonemap/chunk_tonemap_purkinje.d.ts.map +1 -0
  100. package/src/shade/renderer/deferred/tonemap/chunk_tonemap_purkinje.js +51 -0
  101. package/src/shade/renderer/deferred/tonemap/shader_tonemap_HDR_lut.d.ts +2 -2
  102. package/src/shade/renderer/deferred/tonemap/shader_tonemap_HDR_lut.d.ts.map +1 -1
  103. package/src/shade/renderer/deferred/tonemap/shader_tonemap_HDR_lut.js +6 -3
  104. package/src/shade/renderer/deferred/tonemap/shader_tonemap_LDR_lut.d.ts +3 -2
  105. package/src/shade/renderer/deferred/tonemap/shader_tonemap_LDR_lut.d.ts.map +1 -1
  106. package/src/shade/renderer/deferred/tonemap/shader_tonemap_LDR_lut.js +7 -3
  107. package/src/shade/renderer/extension/ViewTextures.d.ts +12 -5
  108. package/src/shade/renderer/extension/ViewTextures.d.ts.map +1 -1
  109. package/src/shade/renderer/extension/ViewTextures.js +19 -5
  110. package/src/shade/renderer/fluid/GPUFluidCascadeStack.d.ts +3 -1
  111. package/src/shade/renderer/fluid/GPUFluidCascadeStack.d.ts.map +1 -1
  112. package/src/shade/renderer/fluid/GPUFluidCascadeStack.js +6 -1
  113. package/src/shade/renderer/fluid/forcing/GPUFluidForcing.d.ts +7 -0
  114. package/src/shade/renderer/fluid/forcing/GPUFluidForcing.d.ts.map +1 -1
  115. package/src/shade/renderer/fluid/forcing/GPUFluidForcing.js +10 -0
  116. package/src/shade/renderer/geometry/sdf/GPUGeometrySDFManager.d.ts +7 -1
  117. package/src/shade/renderer/geometry/sdf/GPUGeometrySDFManager.d.ts.map +1 -1
  118. package/src/shade/renderer/geometry/sdf/GPUGeometrySDFManager.js +46 -15
  119. package/src/shade/renderer/geometry/sdf/bundle/ModelCacheBundle.d.ts +3 -2
  120. package/src/shade/renderer/geometry/sdf/bundle/ModelCacheBundle.d.ts.map +1 -1
  121. package/src/shade/renderer/geometry/sdf/bundle/ModelCacheBundle.js +3 -2
  122. package/src/shade/renderer/geometry/sdf/bundle/model_cache_bundle_sort_morton.d.ts +22 -0
  123. package/src/shade/renderer/geometry/sdf/bundle/model_cache_bundle_sort_morton.d.ts.map +1 -0
  124. package/src/shade/renderer/geometry/sdf/bundle/model_cache_bundle_sort_morton.js +247 -0
  125. package/src/shade/renderer/global_illumination/probe_clipmap/GPUProbeClipmapGI.d.ts +50 -0
  126. package/src/shade/renderer/global_illumination/probe_clipmap/GPUProbeClipmapGI.d.ts.map +1 -1
  127. package/src/shade/renderer/global_illumination/probe_clipmap/GPUProbeClipmapGI.js +101 -0
  128. package/src/shade/renderer/global_illumination/probe_clipmap/ProbeClipmapSettings.d.ts +2 -1
  129. package/src/shade/renderer/global_illumination/probe_clipmap/ProbeClipmapSettings.d.ts.map +1 -1
  130. package/src/shade/renderer/global_illumination/probe_clipmap/ProbeClipmapSettings.js +2 -1
  131. package/src/shade/renderer/global_illumination/probe_clipmap/brick/GPUBrickClipmap.d.ts +8 -0
  132. package/src/shade/renderer/global_illumination/probe_clipmap/brick/GPUBrickClipmap.d.ts.map +1 -1
  133. package/src/shade/renderer/global_illumination/probe_clipmap/brick/GPUBrickClipmap.js +12 -0
  134. package/src/shade/renderer/global_illumination/probe_clipmap/brick/chunk_brick_clipmap_trace.d.ts +12 -6
  135. package/src/shade/renderer/global_illumination/probe_clipmap/brick/chunk_brick_clipmap_trace.d.ts.map +1 -1
  136. package/src/shade/renderer/global_illumination/probe_clipmap/brick/chunk_brick_clipmap_trace.js +35 -29
  137. package/src/shade/renderer/global_illumination/probe_clipmap/debug/graph_probe_clipmap_debug_brick_clipmap.d.ts.map +1 -1
  138. package/src/shade/renderer/global_illumination/probe_clipmap/debug/graph_probe_clipmap_debug_brick_clipmap.js +4 -2
  139. package/src/shade/renderer/global_illumination/probe_clipmap/debug/graph_probe_clipmap_debug_brick_material.d.ts.map +1 -1
  140. package/src/shade/renderer/global_illumination/probe_clipmap/debug/graph_probe_clipmap_debug_brick_material.js +6 -4
  141. package/src/shade/renderer/global_illumination/probe_clipmap/material/GPUBrickMaterial.d.ts.map +1 -1
  142. package/src/shade/renderer/global_illumination/probe_clipmap/material/GPUBrickMaterial.js +2 -1
  143. package/src/shade/renderer/global_illumination/probe_clipmap/material/chunk_brick_material.d.ts +6 -5
  144. package/src/shade/renderer/global_illumination/probe_clipmap/material/chunk_brick_material.d.ts.map +1 -1
  145. package/src/shade/renderer/global_illumination/probe_clipmap/material/chunk_brick_material.js +15 -14
  146. package/src/shade/renderer/global_illumination/probe_clipmap/material/shader_brick_material_gather.d.ts.map +1 -1
  147. package/src/shade/renderer/global_illumination/probe_clipmap/material/shader_brick_material_gather.js +4 -2
  148. package/src/shade/renderer/global_illumination/probe_clipmap/probe/GPUProbeClipmap.d.ts +19 -2
  149. package/src/shade/renderer/global_illumination/probe_clipmap/probe/GPUProbeClipmap.d.ts.map +1 -1
  150. package/src/shade/renderer/global_illumination/probe_clipmap/probe/GPUProbeClipmap.js +128 -10
  151. package/src/shade/renderer/global_illumination/probe_clipmap/probe/PROBE_CLIPMAP.d.ts +19 -1
  152. package/src/shade/renderer/global_illumination/probe_clipmap/probe/PROBE_CLIPMAP.d.ts.map +1 -1
  153. package/src/shade/renderer/global_illumination/probe_clipmap/probe/PROBE_CLIPMAP.js +27 -2
  154. package/src/shade/renderer/global_illumination/probe_clipmap/probe/ProbeClipmapScreenWants.d.ts +19 -11
  155. package/src/shade/renderer/global_illumination/probe_clipmap/probe/ProbeClipmapScreenWants.d.ts.map +1 -1
  156. package/src/shade/renderer/global_illumination/probe_clipmap/probe/ProbeClipmapScreenWants.js +35 -11
  157. package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap.d.ts.map +1 -1
  158. package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap.js +3 -1
  159. package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap_box_cages.d.ts +40 -0
  160. package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap_box_cages.d.ts.map +1 -0
  161. package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap_box_cages.js +174 -0
  162. package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap_hit_material.d.ts +4 -4
  163. package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap_hit_material.js +10 -10
  164. package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap_parallax.d.ts +31 -0
  165. package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap_parallax.d.ts.map +1 -0
  166. package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap_parallax.js +54 -0
  167. package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap_sample_radiance.d.ts +8 -4
  168. package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap_sample_radiance.d.ts.map +1 -1
  169. package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap_sample_radiance.js +10 -21
  170. package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap_want.d.ts +7 -2
  171. package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap_want.d.ts.map +1 -1
  172. package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap_want.js +33 -29
  173. package/src/shade/renderer/global_illumination/probe_clipmap/probe/graph_probe_clipmap_want_meshlets.d.ts +28 -0
  174. package/src/shade/renderer/global_illumination/probe_clipmap/probe/graph_probe_clipmap_want_meshlets.d.ts.map +1 -0
  175. package/src/shade/renderer/global_illumination/probe_clipmap/probe/graph_probe_clipmap_want_meshlets.js +138 -0
  176. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_due.d.ts +13 -9
  177. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_due.d.ts.map +1 -1
  178. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_due.js +18 -11
  179. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_light.js +1 -1
  180. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_relocate.d.ts.map +1 -1
  181. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_relocate.js +4 -2
  182. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_retire.d.ts.map +1 -1
  183. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_retire.js +2 -3
  184. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_schedule.d.ts +5 -3
  185. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_schedule.d.ts.map +1 -1
  186. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_schedule.js +15 -30
  187. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_shade.js +1 -1
  188. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_trace.d.ts.map +1 -1
  189. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_trace.js +4 -2
  190. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_want.d.ts +11 -0
  191. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_want.d.ts.map +1 -1
  192. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_want.js +29 -2
  193. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_want_late.d.ts +40 -0
  194. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_want_late.d.ts.map +1 -0
  195. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_want_late.js +126 -0
  196. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_want_meshlets.d.ts +36 -0
  197. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_want_meshlets.d.ts.map +1 -0
  198. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_want_meshlets.js +221 -0
  199. package/src/shade/renderer/gpu_primitive/age_eviction/chunk_age_eviction.d.ts +40 -0
  200. package/src/shade/renderer/gpu_primitive/age_eviction/chunk_age_eviction.d.ts.map +1 -0
  201. package/src/shade/renderer/gpu_primitive/age_eviction/chunk_age_eviction.js +86 -0
  202. package/src/shade/renderer/grass/blade/GPUGrassBlades.d.ts +135 -0
  203. package/src/shade/renderer/grass/blade/GPUGrassBlades.d.ts.map +1 -0
  204. package/src/shade/renderer/grass/blade/GPUGrassBlades.js +676 -0
  205. package/src/shade/renderer/grass/blade/GRASS_BLADE.d.ts +145 -0
  206. package/src/shade/renderer/grass/blade/GRASS_BLADE.d.ts.map +1 -0
  207. package/src/shade/renderer/grass/blade/GRASS_BLADE.js +179 -0
  208. package/src/shade/renderer/grass/blade/chunk_grass_blade.d.ts +63 -0
  209. package/src/shade/renderer/grass/blade/chunk_grass_blade.d.ts.map +1 -0
  210. package/src/shade/renderer/grass/blade/chunk_grass_blade.js +244 -0
  211. package/src/shade/renderer/grass/blade/chunk_grass_blade_wind.d.ts +58 -0
  212. package/src/shade/renderer/grass/blade/chunk_grass_blade_wind.d.ts.map +1 -0
  213. package/src/shade/renderer/grass/blade/chunk_grass_blade_wind.js +174 -0
  214. package/src/shade/renderer/grass/blade/grass_blade_id_draw.d.ts +25 -0
  215. package/src/shade/renderer/grass/blade/grass_blade_id_draw.d.ts.map +1 -0
  216. package/src/shade/renderer/grass/blade/grass_blade_id_draw.js +133 -0
  217. package/src/shade/renderer/grass/blade/grass_blade_mechanics.d.ts +80 -0
  218. package/src/shade/renderer/grass/blade/grass_blade_mechanics.d.ts.map +1 -0
  219. package/src/shade/renderer/grass/blade/grass_blade_mechanics.js +92 -0
  220. package/src/shade/renderer/grass/blade/grass_blade_resolve.d.ts +29 -0
  221. package/src/shade/renderer/grass/blade/grass_blade_resolve.d.ts.map +1 -0
  222. package/src/shade/renderer/grass/blade/grass_blade_resolve.js +175 -0
  223. package/src/shade/renderer/grass/blade/shader_grass_blade_draw_args.d.ts +14 -0
  224. package/src/shade/renderer/grass/blade/shader_grass_blade_draw_args.d.ts.map +1 -0
  225. package/src/shade/renderer/grass/blade/shader_grass_blade_draw_args.js +45 -0
  226. package/src/shade/renderer/grass/blade/shader_grass_blade_expand.d.ts +61 -0
  227. package/src/shade/renderer/grass/blade/shader_grass_blade_expand.d.ts.map +1 -0
  228. package/src/shade/renderer/grass/blade/shader_grass_blade_expand.js +340 -0
  229. package/src/shade/renderer/grass/blade/shader_grass_cell_count.d.ts +46 -0
  230. package/src/shade/renderer/grass/blade/shader_grass_cell_count.d.ts.map +1 -0
  231. package/src/shade/renderer/grass/blade/shader_grass_cell_count.js +280 -0
  232. package/src/shade/renderer/grass/population/chunk_grass_population.d.ts +60 -0
  233. package/src/shade/renderer/grass/population/chunk_grass_population.d.ts.map +1 -0
  234. package/src/shade/renderer/grass/population/chunk_grass_population.js +171 -0
  235. package/src/shade/renderer/grass/press/GPUGrassPress.d.ts +99 -0
  236. package/src/shade/renderer/grass/press/GPUGrassPress.d.ts.map +1 -0
  237. package/src/shade/renderer/grass/press/GPUGrassPress.js +436 -0
  238. package/src/shade/renderer/grass/press/GRASS_PRESS.d.ts +179 -0
  239. package/src/shade/renderer/grass/press/GRASS_PRESS.d.ts.map +1 -0
  240. package/src/shade/renderer/grass/press/GRASS_PRESS.js +217 -0
  241. package/src/shade/renderer/grass/press/chunk_grass_press.d.ts +65 -0
  242. package/src/shade/renderer/grass/press/chunk_grass_press.d.ts.map +1 -0
  243. package/src/shade/renderer/grass/press/chunk_grass_press.js +296 -0
  244. package/src/shade/renderer/grass/press/shader_grass_press_mark.d.ts +31 -0
  245. package/src/shade/renderer/grass/press/shader_grass_press_mark.d.ts.map +1 -0
  246. package/src/shade/renderer/grass/press/shader_grass_press_mark.js +169 -0
  247. package/src/shade/renderer/grass/press/shader_grass_press_stamp.d.ts +27 -0
  248. package/src/shade/renderer/grass/press/shader_grass_press_stamp.d.ts.map +1 -0
  249. package/src/shade/renderer/grass/press/shader_grass_press_stamp.js +183 -0
  250. package/src/shade/renderer/grass/surface/GPUGrassSurfaces.d.ts +193 -0
  251. package/src/shade/renderer/grass/surface/GPUGrassSurfaces.d.ts.map +1 -0
  252. package/src/shade/renderer/grass/surface/GPUGrassSurfaces.js +1253 -0
  253. package/src/shade/renderer/grass/surface/GRASS_SURFACE.d.ts +211 -0
  254. package/src/shade/renderer/grass/surface/GRASS_SURFACE.d.ts.map +1 -0
  255. package/src/shade/renderer/grass/surface/GRASS_SURFACE.js +241 -0
  256. package/src/shade/renderer/grass/surface/GRASS_SURFACE_VIEW.d.ts +82 -0
  257. package/src/shade/renderer/grass/surface/GRASS_SURFACE_VIEW.d.ts.map +1 -0
  258. package/src/shade/renderer/grass/surface/GRASS_SURFACE_VIEW.js +111 -0
  259. package/src/shade/renderer/grass/surface/chunk_grass_column_cross.d.ts +39 -0
  260. package/src/shade/renderer/grass/surface/chunk_grass_column_cross.d.ts.map +1 -0
  261. package/src/shade/renderer/grass/surface/chunk_grass_column_cross.js +85 -0
  262. package/src/shade/renderer/grass/surface/chunk_grass_directory.d.ts +29 -0
  263. package/src/shade/renderer/grass/surface/chunk_grass_directory.d.ts.map +1 -0
  264. package/src/shade/renderer/grass/surface/chunk_grass_directory.js +112 -0
  265. package/src/shade/renderer/grass/surface/chunk_grass_slot.d.ts +27 -0
  266. package/src/shade/renderer/grass/surface/chunk_grass_slot.d.ts.map +1 -0
  267. package/src/shade/renderer/grass/surface/chunk_grass_slot.js +50 -0
  268. package/src/shade/renderer/grass/surface/chunk_grass_surface_frame.d.ts +21 -0
  269. package/src/shade/renderer/grass/surface/chunk_grass_surface_frame.d.ts.map +1 -0
  270. package/src/shade/renderer/grass/surface/chunk_grass_surface_frame.js +41 -0
  271. package/src/shade/renderer/grass/surface/chunk_grass_surface_window.d.ts +32 -0
  272. package/src/shade/renderer/grass/surface/chunk_grass_surface_window.d.ts.map +1 -0
  273. package/src/shade/renderer/grass/surface/chunk_grass_surface_window.js +136 -0
  274. package/src/shade/renderer/grass/surface/chunk_grass_surfel.d.ts +37 -0
  275. package/src/shade/renderer/grass/surface/chunk_grass_surfel.d.ts.map +1 -0
  276. package/src/shade/renderer/grass/surface/chunk_grass_surfel.js +85 -0
  277. package/src/shade/renderer/grass/surface/chunk_grass_tile.d.ts +25 -0
  278. package/src/shade/renderer/grass/surface/chunk_grass_tile.d.ts.map +1 -0
  279. package/src/shade/renderer/grass/surface/chunk_grass_tile.js +52 -0
  280. package/src/shade/renderer/grass/surface/shader_grass_directory_fill.d.ts +23 -0
  281. package/src/shade/renderer/grass/surface/shader_grass_directory_fill.d.ts.map +1 -0
  282. package/src/shade/renderer/grass/surface/shader_grass_directory_fill.js +87 -0
  283. package/src/shade/renderer/grass/surface/shader_grass_surface_bake.d.ts +43 -0
  284. package/src/shade/renderer/grass/surface/shader_grass_surface_bake.d.ts.map +1 -0
  285. package/src/shade/renderer/grass/surface/shader_grass_surface_bake.js +265 -0
  286. package/src/shade/renderer/grass/surface/shader_grass_surface_bake_command.d.ts +13 -0
  287. package/src/shade/renderer/grass/surface/shader_grass_surface_bake_command.d.ts.map +1 -0
  288. package/src/shade/renderer/grass/surface/shader_grass_surface_bake_command.js +49 -0
  289. package/src/shade/renderer/grass/surface/shader_grass_surface_invalidate.d.ts +62 -0
  290. package/src/shade/renderer/grass/surface/shader_grass_surface_invalidate.d.ts.map +1 -0
  291. package/src/shade/renderer/grass/surface/shader_grass_surface_invalidate.js +162 -0
  292. package/src/shade/renderer/grass/surface/shader_grass_surface_retire.d.ts +40 -0
  293. package/src/shade/renderer/grass/surface/shader_grass_surface_retire.d.ts.map +1 -0
  294. package/src/shade/renderer/grass/surface/shader_grass_surface_retire.js +155 -0
  295. package/src/shade/renderer/grass/surface/shader_grass_surface_schedule.d.ts +19 -0
  296. package/src/shade/renderer/grass/surface/shader_grass_surface_schedule.d.ts.map +1 -0
  297. package/src/shade/renderer/grass/surface/shader_grass_surface_schedule.js +58 -0
  298. package/src/shade/renderer/grass/surface/shader_grass_surface_want.d.ts +30 -0
  299. package/src/shade/renderer/grass/surface/shader_grass_surface_want.d.ts.map +1 -0
  300. package/src/shade/renderer/grass/surface/shader_grass_surface_want.js +251 -0
  301. package/src/shade/renderer/grass/surface/shader_grass_surface_window_count.d.ts +21 -0
  302. package/src/shade/renderer/grass/surface/shader_grass_surface_window_count.d.ts.map +1 -0
  303. package/src/shade/renderer/grass/surface/shader_grass_surface_window_count.js +75 -0
  304. package/src/shade/renderer/postprocess/eye/GPUCameraExposureManager.d.ts +35 -9
  305. package/src/shade/renderer/postprocess/eye/GPUCameraExposureManager.d.ts.map +1 -1
  306. package/src/shade/renderer/postprocess/eye/GPUCameraExposureManager.js +81 -11
  307. package/src/shade/renderer/postprocess/eye/shader_autoexposure_adapt.d.ts.map +1 -1
  308. package/src/shade/renderer/postprocess/eye/shader_autoexposure_adapt.js +4 -1
  309. package/src/shade/renderer/postprocess/velocity/graph_add_per_object_velocity.d.ts.map +1 -1
  310. package/src/shade/renderer/postprocess/velocity/graph_add_per_object_velocity.js +4 -23
  311. package/src/shade/renderer/postprocess/velocity/view_velocity_matrices.d.ts +12 -0
  312. package/src/shade/renderer/postprocess/velocity/view_velocity_matrices.d.ts.map +1 -0
  313. package/src/shade/renderer/postprocess/velocity/view_velocity_matrices.js +29 -0
  314. package/src/shade/renderer/rasterize/native/avboit/graph_rasterize_meshes_transparent_avboit.d.ts.map +1 -1
  315. package/src/shade/renderer/rasterize/native/avboit/graph_rasterize_meshes_transparent_avboit.js +22 -0
  316. package/src/shade/renderer/scene/GPUSceneContext.d.ts.map +1 -1
  317. package/src/shade/renderer/scene/GPUSceneContext.js +3 -0
  318. package/src/shade/renderer/scene/GRASS_SURFACE_PARAMS_STRUCT.d.ts +27 -0
  319. package/src/shade/renderer/scene/GRASS_SURFACE_PARAMS_STRUCT.d.ts.map +1 -0
  320. package/src/shade/renderer/scene/GRASS_SURFACE_PARAMS_STRUCT.js +38 -0
  321. package/src/shade/renderer/scene/MESH_GROUND_COVER_STRUCT.d.ts +28 -0
  322. package/src/shade/renderer/scene/MESH_GROUND_COVER_STRUCT.d.ts.map +1 -0
  323. package/src/shade/renderer/scene/MESH_GROUND_COVER_STRUCT.js +58 -0
  324. package/src/shade/renderer/scene/SCENE_DATABASE_SPEC.d.ts.map +1 -1
  325. package/src/shade/renderer/scene/SCENE_DATABASE_SPEC.js +8 -0
  326. package/src/shade/renderer/shader/chunk/color/conversion/chunk_CRM_REC709_AP1.d.ts +6 -0
  327. package/src/shade/renderer/shader/chunk/color/conversion/chunk_CRM_REC709_AP1.d.ts.map +1 -1
  328. package/src/shade/renderer/shader/chunk/color/conversion/chunk_CRM_REC709_AP1.js +7 -0
  329. package/src/shade/renderer/shader/chunk/color/grade/chunk_color_grade.d.ts +4 -4
  330. package/src/shade/renderer/shader/chunk/color/grade/chunk_color_grade.d.ts.map +1 -1
  331. package/src/shade/renderer/shader/chunk/color/grade/chunk_color_grade.js +86 -5
  332. package/src/shade/renderer/shader/chunk/color/tonemap/purkinje/chunk_apply_purkinje_shift.d.ts +65 -0
  333. package/src/shade/renderer/shader/chunk/color/tonemap/purkinje/chunk_apply_purkinje_shift.d.ts.map +1 -0
  334. package/src/shade/renderer/shader/chunk/color/tonemap/purkinje/chunk_apply_purkinje_shift.js +136 -0
  335. package/src/shade/renderer/shader/chunk/geometry/ray/chunk_ray_query_nearest_among.d.ts +37 -0
  336. package/src/shade/renderer/shader/chunk/geometry/ray/chunk_ray_query_nearest_among.d.ts.map +1 -0
  337. package/src/shade/renderer/shader/chunk/geometry/ray/chunk_ray_query_nearest_among.js +148 -0
  338. package/src/shade/renderer/shader/chunk/sdf/chunk_shape_record_line_span.d.ts +20 -0
  339. package/src/shade/renderer/shader/chunk/sdf/chunk_shape_record_line_span.d.ts.map +1 -0
  340. package/src/shade/renderer/shader/chunk/sdf/chunk_shape_record_line_span.js +169 -0
  341. package/src/shade/renderer/texture/atlas/chunk_tile_atlas_slot_origin.d.ts +18 -0
  342. package/src/shade/renderer/texture/atlas/chunk_tile_atlas_slot_origin.d.ts.map +1 -1
  343. package/src/shade/renderer/texture/atlas/chunk_tile_atlas_slot_origin.js +28 -0
  344. package/src/shade/renderer/texture/atlas/tile_atlas_slot_shift.d.ts +13 -0
  345. package/src/shade/renderer/texture/atlas/tile_atlas_slot_shift.d.ts.map +1 -0
  346. package/src/shade/renderer/texture/atlas/tile_atlas_slot_shift.js +22 -0
  347. package/src/shade/renderer/water/GPUWaterRenderer.d.ts.map +1 -1
  348. package/src/shade/renderer/water/GPUWaterRenderer.js +4 -0
  349. package/src/shade/renderer/wind/GPUSceneWind.d.ts +52 -5
  350. package/src/shade/renderer/wind/GPUSceneWind.d.ts.map +1 -1
  351. package/src/shade/renderer/wind/GPUSceneWind.js +164 -8
  352. package/src/shade/renderer/wind/WIND_FIELD_UNIFORM.d.ts +3 -1
  353. package/src/shade/renderer/wind/WIND_FIELD_UNIFORM.d.ts.map +1 -1
  354. package/src/shade/renderer/wind/WIND_FIELD_UNIFORM.js +3 -1
  355. package/src/shade/renderer/wind/chunk_wind_field_sample_cascades.d.ts +2 -1
  356. package/src/shade/renderer/wind/chunk_wind_field_sample_cascades.d.ts.map +1 -1
  357. package/src/shade/renderer/wind/chunk_wind_field_sample_cascades.js +18 -13
  358. package/src/shade/renderer/wind/chunk_wind_field_sample_previous.d.ts +13 -0
  359. package/src/shade/renderer/wind/chunk_wind_field_sample_previous.d.ts.map +1 -0
  360. package/src/shade/renderer/wind/chunk_wind_field_sample_previous.js +23 -0
  361. package/src/shade/renderer/wind/chunk_wind_field_sample_uniform.d.ts +1 -0
  362. package/src/shade/renderer/wind/chunk_wind_field_sample_uniform.d.ts.map +1 -1
  363. package/src/shade/renderer/wind/chunk_wind_field_sample_uniform.js +6 -1
  364. package/src/shade/renderer/wind/wind_field_add_resources.d.ts +11 -0
  365. package/src/shade/renderer/wind/wind_field_add_resources.d.ts.map +1 -1
  366. package/src/shade/renderer/wind/wind_field_add_resources.js +15 -0
  367. package/src/shade/wgsl/emulator/WGSLJavaScriptCompiler.js +1 -1
  368. package/src/shade/wgsl/emulator/WGSLLanguageCore.d.ts.map +1 -1
  369. package/src/shade/wgsl/emulator/WGSLLanguageCore.js +2 -0
  370. package/src/shade/renderer/shader/chunk/color/tonemap/purkinjie/chunk_apply_purkinjie_shift.d.ts +0 -11
  371. package/src/shade/renderer/shader/chunk/color/tonemap/purkinjie/chunk_apply_purkinjie_shift.d.ts.map +0 -1
  372. package/src/shade/renderer/shader/chunk/color/tonemap/purkinjie/chunk_apply_purkinjie_shift.js +0 -56
@@ -0,0 +1,247 @@
1
+ import { assert } from "../../../../../core/assert.js";
2
+ import { v3_morton_encode_magicbits } from "../../../../../core/geom/3d/morton/v3_morton_encode_magicbits.js";
3
+ import { MESH_SDF_BRICK_TEXEL_COUNT, MESH_SDF_EMPTY } from "../MESH_SDF.js";
4
+ import {
5
+ MESH_SURFACE_PLANE_BLOCK_WORDS,
6
+ MESH_SURFACE_PRESENCE_BLOCK_WORDS,
7
+ MESH_SURFACE_TABLE_MASK_BITS
8
+ } from "../surface/MESH_SURFACE_BLOCK.js";
9
+ import { ModelCacheBundle, ModelCacheBundleCache, ModelCacheBundleField } from "./ModelCacheBundle.js";
10
+
11
+ /**
12
+ * Bricks along an axis a level's Morton code holds: 10 bits an axis.
13
+ * @type {number}
14
+ */
15
+ const MORTON_AXIS_LIMIT = 1 << 10;
16
+
17
+ /**
18
+ * @param {number} v
19
+ * @returns {number}
20
+ */
21
+ function popcount8(v) {
22
+ let c = 0;
23
+
24
+ for (let b = 0; b < 8; b++) {
25
+ c += (v >>> b) & 1;
26
+ }
27
+
28
+ return c;
29
+ }
30
+
31
+ /**
32
+ * Each entry's place in (level, Morton code of its brick) order, levels coarsening as `MeshSDFLayout`'s
33
+ * do: level k has ⌈bricks / 2^k⌉ along each axis, its entries after every finer level's, x fastest.
34
+ *
35
+ * @param {ModelCacheBundleField} field
36
+ * @returns {Float64Array} a key an entry
37
+ */
38
+ function entry_keys(field) {
39
+ const keys = new Float64Array(field.entries.length);
40
+
41
+ let e = 0;
42
+
43
+ for (let level = 0; level < field.level_count; level++) {
44
+ const nx = Math.ceil(field.bricks[0] / 2 ** level);
45
+ const ny = Math.ceil(field.bricks[1] / 2 ** level);
46
+ const nz = Math.ceil(field.bricks[2] / 2 ** level);
47
+
48
+ assert.ok(nx <= MORTON_AXIS_LIMIT && ny <= MORTON_AXIS_LIMIT && nz <= MORTON_AXIS_LIMIT, 'field.bricks: past the 10 bits an axis a Morton code holds');
49
+
50
+ for (let z = 0; z < nz; z++) {
51
+ for (let y = 0; y < ny; y++) {
52
+ for (let x = 0; x < nx; x++) {
53
+ // 30 bits of code under the level: exact in a double
54
+ keys[e++] = level * 2 ** 30 + v3_morton_encode_magicbits(x, y, z);
55
+ }
56
+ }
57
+ }
58
+ }
59
+
60
+ assert.equal(e, field.entries.length, 'field.entries: one a brick of its levels');
61
+
62
+ return keys;
63
+ }
64
+
65
+ /**
66
+ * `words` holding `per_block` words for each block, its blocks moved: run r of `runs` (old first block,
67
+ * new first block, blocks) from its old place to its new.
68
+ *
69
+ * @param {Uint32Array} words
70
+ * @param {number} per_block
71
+ * @param {number} blocks
72
+ * @param {number[]|null} runs null for a field with no table, whose blocks no brick numbers
73
+ * @returns {Uint32Array}
74
+ */
75
+ function move_blocks(words, per_block, blocks, runs) {
76
+ if (words.length === 0 || runs === null) {
77
+ return words.slice();
78
+ }
79
+
80
+ assert.equal(words.length, blocks * per_block, 'a cache\'s blocks: its field\'s, each of its plane\'s words');
81
+
82
+ const out = new Uint32Array(words.length);
83
+
84
+ for (let r = 0; r < runs.length; r += 3) {
85
+ out.set(words.subarray(runs[r] * per_block, (runs[r] + runs[r + 2]) * per_block), runs[r + 1] * per_block);
86
+ }
87
+
88
+ return out;
89
+ }
90
+
91
+ /**
92
+ * A copy of a {@link ModelCacheBundle} laid out for locality, holding the same fields and caches: what
93
+ * every entry reads, the bytes of its brick and its surface blocks, is unchanged.
94
+ *
95
+ * - each field's stored bricks are numbered in (level, Morton code of the brick) order, and its block
96
+ * table and its caches' blocks follow: a brick's blocks keep its mask and come in number order;
97
+ * - the bundle's bricks are ordered as the fields first name them, field by field in that numbering,
98
+ * with bricks no field names after them. `upload_bundle` places a bundle's bricks in that order, and its
99
+ * fresh pass pops their slots in about that order (an atomic a thread), so a field's neighbouring bricks
100
+ * mostly sit in neighbouring slots.
101
+ *
102
+ * Measured (2026-11-11, a 69k-brick library loaded into the probe clipmap on an RTX 4090 and a Radeon
103
+ * RDNA2 iGPU): the SDF batch pass does not change, and the brick material gather is about 0.5% faster.
104
+ * Bake order is already near this one, so the sort is for offline asset preparation, where it costs
105
+ * nothing at load, and is off unless asked for (`GPUGeometrySDFManager.export_bundle`).
106
+ *
107
+ * @param {ModelCacheBundle} bundle
108
+ * @returns {ModelCacheBundle} a new bundle; `bundle` is left as it was
109
+ */
110
+ export function model_cache_bundle_sort_morton(bundle) {
111
+ const out = new ModelCacheBundle();
112
+
113
+ out.voxel_size = bundle.voxel_size;
114
+ out.max_bricks = bundle.max_bricks;
115
+
116
+ const brick_count = bundle.brick_count;
117
+ /** the new index of each old brick, -1 until a field names it */
118
+ const brick_to = new Int32Array(brick_count).fill(-1);
119
+ let next_brick = 0;
120
+
121
+ /** each field's runs of moved blocks, for its caches */
122
+ const field_runs = [];
123
+
124
+ for (let f = 0; f < bundle.fields.length; f++) {
125
+ const field = bundle.fields[f];
126
+ const stored = field.numbered.length;
127
+ const keys = entry_keys(field);
128
+
129
+ // brick n's new number is its place in key order; entries are distinct, so no two keys tie
130
+ const order = Array.from({ length: stored }, (_, n) => n);
131
+
132
+ order.sort((a, b) => keys[field.numbered[a]] - keys[field.numbered[b]]);
133
+
134
+ const sorted = new ModelCacheBundleField();
135
+
136
+ sorted.origin.set(field.origin);
137
+ sorted.voxel = field.voxel;
138
+ sorted.bricks.set(field.bricks);
139
+ sorted.level_count = field.level_count;
140
+ sorted.two_sided = field.two_sided;
141
+ sorted.blocks = field.blocks;
142
+ sorted.numbered = new Uint32Array(stored);
143
+
144
+ for (let m = 0; m < stored; m++) {
145
+ sorted.numbered[m] = field.numbered[order[m]];
146
+ }
147
+
148
+ // without a table no block is numbered by a brick: a cache's blocks, if any, stay where they are
149
+ let runs = null;
150
+
151
+ if (field.table.length > 0) {
152
+ runs = [];
153
+ assert.equal(field.table.length, stored, 'field.table: a word a stored brick, or none');
154
+
155
+ sorted.table = new Uint32Array(stored);
156
+
157
+ // every block in exactly one brick's run, as a survey hands them out: what moves them losslessly
158
+ const covered = new Uint8Array(field.blocks);
159
+
160
+ let first = 0;
161
+
162
+ for (let m = 0; m < stored; m++) {
163
+ const word = field.table[order[m]];
164
+ const mask = word & ((1 << MESH_SURFACE_TABLE_MASK_BITS) - 1);
165
+ const count = popcount8(mask);
166
+ const from = word >>> MESH_SURFACE_TABLE_MASK_BITS;
167
+
168
+ sorted.table[m] = ((first << MESH_SURFACE_TABLE_MASK_BITS) | mask) >>> 0;
169
+
170
+ if (count > 0) {
171
+ assert.lessThanOrEqual(from + count, field.blocks, 'field.table: a run past the field\'s blocks');
172
+
173
+ for (let b = from; b < from + count; b++) {
174
+ assert.equal(covered[b], 0, 'field.table: two bricks\' runs share a block');
175
+ covered[b] = 1;
176
+ }
177
+
178
+ runs.push(from, first, count);
179
+ }
180
+
181
+ first += count;
182
+ }
183
+
184
+ assert.equal(first, field.blocks, 'field.blocks: the blocks its table\'s masks keep');
185
+ }
186
+
187
+ field_runs.push(runs);
188
+
189
+ // the bricks as this field first names them, in its new numbering
190
+ for (let m = 0; m < stored; m++) {
191
+ const brick = field.entries[sorted.numbered[m]];
192
+
193
+ assert.lessThan(brick, brick_count, 'a numbered entry names a brick of the bundle');
194
+
195
+ if (brick_to[brick] === -1) {
196
+ brick_to[brick] = next_brick++;
197
+ }
198
+ }
199
+
200
+ out.fields.push(sorted);
201
+ }
202
+
203
+ // bricks no field numbers: after the rest, as they were
204
+ for (let b = 0; b < brick_count; b++) {
205
+ if (brick_to[b] === -1) {
206
+ brick_to[b] = next_brick++;
207
+ }
208
+ }
209
+
210
+ out.bricks = new Uint8Array(bundle.bricks.length);
211
+
212
+ for (let b = 0; b < brick_count; b++) {
213
+ out.bricks.set(bundle.bricks.subarray(b * MESH_SDF_BRICK_TEXEL_COUNT, (b + 1) * MESH_SDF_BRICK_TEXEL_COUNT), brick_to[b] * MESH_SDF_BRICK_TEXEL_COUNT);
214
+ }
215
+
216
+ for (let f = 0; f < bundle.fields.length; f++) {
217
+ const entries = bundle.fields[f].entries;
218
+ const renamed = new Uint32Array(entries.length);
219
+
220
+ for (let e = 0; e < entries.length; e++) {
221
+ const entry = entries[e];
222
+
223
+ renamed[e] = entry < MESH_SDF_EMPTY ? brick_to[entry] : entry;
224
+ }
225
+
226
+ out.fields[f].entries = renamed;
227
+ }
228
+
229
+ for (const cache of bundle.caches) {
230
+ const sorted = new ModelCacheBundleCache();
231
+ const runs = field_runs[cache.field];
232
+ const blocks = bundle.fields[cache.field].blocks;
233
+
234
+ sorted.field = cache.field;
235
+ sorted.texels = cache.texels;
236
+ sorted.codes.set(cache.codes);
237
+ sorted.presence = move_blocks(cache.presence, MESH_SURFACE_PRESENCE_BLOCK_WORDS, blocks, runs);
238
+
239
+ for (let p = 0; p < cache.planes.length; p++) {
240
+ sorted.planes[p] = move_blocks(cache.planes[p], MESH_SURFACE_PLANE_BLOCK_WORDS[p], blocks, runs);
241
+ }
242
+
243
+ out.caches.push(sorted);
244
+ }
245
+
246
+ return out;
247
+ }
@@ -88,6 +88,56 @@ export class GPUProbeClipmapGI {
88
88
  * @returns {boolean}
89
89
  */
90
90
  get has_probes(): boolean;
91
+ /**
92
+ * Record the wants of a screen surface drawn apart from the G-buffer whose reader picks the frustum's probes a
93
+ * pixel (PROBE_CLIPMAP_PROPOSAL_2026_10_27.md §8.3): the water's interface. A pixel of each screen tile wants
94
+ * the cages its pick reads, as the G-buffer's pixels do (`ProbeClipmapScreenWants`).
95
+ *
96
+ * For a pass after this frame's {@link graph_update}, once the surface is drawn. Its wants are taken by the
97
+ * next frame's lifetime, so a probe the surface newly reads is there a frame after the surface is. Records
98
+ * nothing where there are no probes ({@link has_probes}): out of the mode it costs nothing.
99
+ *
100
+ * @param {Object} options
101
+ * @param {FrameGraph} options.graph
102
+ * @param {number} options.depth graph handle of the surface's reverse-Z depth, zero where it has none
103
+ * @param {number} options.normal graph handle of its normals, a `uint` texture: a channel holds a normal
104
+ * octahedral, as the G-buffer packs its own
105
+ * @param {number} [options.normal_channel] the channel that holds the normal, 0 to 3
106
+ * @param {boolean} [options.two_sided] whether the reader turns a normal that faces away from the eye to face it
107
+ * @param {GPUBuffer} options.camera the camera uniform the surface was drawn with
108
+ * @param {ArrayLike<number>} options.resolution the surface's pixels, x and y
109
+ */
110
+ graph_want_surface({ graph, depth, normal, normal_channel, two_sided, camera, resolution }: {
111
+ graph: FrameGraph;
112
+ depth: number;
113
+ normal: number;
114
+ normal_channel?: number;
115
+ two_sided?: boolean;
116
+ camera: GPUBuffer;
117
+ resolution: ArrayLike<number>;
118
+ }): void;
119
+ /**
120
+ * Record the wants of a list of meshlets a forward pass draws, whose fragments pick the frustum's probes
121
+ * (PROBE_CLIPMAP_PROPOSAL_2026_10_27.md §8.3): each wants the cages a reader anywhere inside its box can
122
+ * read (`graph_probe_clipmap_want_meshlets`).
123
+ *
124
+ * For a pass after this frame's {@link graph_update}; taken by the next frame's lifetime, as
125
+ * {@link graph_want_surface}'s are. Records nothing where there are no probes ({@link has_probes}).
126
+ *
127
+ * @param {Object} options
128
+ * @param {FrameGraph} options.graph
129
+ * @param {import("../../scene/GPUSceneContext.js").GPUSceneContext} options.scene the meshlets' scene
130
+ * @param {number} options.camera graph handle of the view's camera uniform
131
+ * @param {number} options.meshlet_collection graph handle of the list, `MESHLET_COLLECTION_STRUCT`
132
+ * @param {number} options.meshlet_iterator_command graph handle of the indirect dispatch that walks the list
133
+ */
134
+ graph_want_meshlets({ graph, scene, camera, meshlet_collection, meshlet_iterator_command }: {
135
+ graph: FrameGraph;
136
+ scene: import("../../scene/GPUSceneContext.js").GPUSceneContext;
137
+ camera: number;
138
+ meshlet_collection: number;
139
+ meshlet_iterator_command: number;
140
+ }): void;
91
141
  /**
92
142
  * Put what the probes' readers bind into `bindings`, `PROBE_CLIPMAP_SAMPLING_GROUP` but its sampler:
93
143
  * once {@link has_probes}, the probes as this frame's {@link graph_update} left them
@@ -1 +1 @@
1
- {"version":3,"file":"GPUProbeClipmapGI.d.ts","sourceRoot":"","sources":["../../../../../../src/shade/renderer/global_illumination/probe_clipmap/GPUProbeClipmapGI.js"],"names":[],"mappings":"AA8BA;;;;;;GAMG;AAEH;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH;IAwTI;;;;OAIG;IACH,oDAJW,eAAe,YACf,oBAAoB,GAClB,OAAO,CAUnB;IA5OD;;OAEG;IACH,sBAFW,eAAe,EAMzB;IAED;;OAEG;IACH,qCAEC;IAED;;OAEG;IACH,qCAEC;IAED;;OAEG;IACH,mCAEC;IAED;;OAEG;IACH,oCAEC;IAED;;;;;;;;;;;;;;;;;OAiBG;IACH;QAZ+B,KAAK,EAAzB,UAAU;QACc,IAAI,EAA5B,cAAc;QACgB,QAAQ,EAAtC,oBAAoB;QACJ,KAAK,EAArB,MAAM;QACU,MAAM,EAAtB,MAAM;QACK,IAAI;QACE,MAAM,GAAvB,MAAM;QAEU,QAAQ,EAAxB,MAAM;aAsIhB;IAqDD;;;OAGG;IACH,0BAEC;IAED;;;;;;;;;OASG;IACH,4CAUC;IAwDD;;;;;;;;;;;;;;;;OAgBG;IACH;QAR+B,KAAK,EAAzB,UAAU;QACc,IAAI,EAA5B,cAAc;QACgB,QAAQ,EAAtC,oBAAoB;QACF,UAAU,EAA5B,MAAM,EAAE;QACQ,QAAQ;QACtB,MAAM,CA8ClB;IAED;;;;;OAKG;IACH,uBAFW,aAAa,QASvB;IAED;;;OAGG;IACH,0BAHW,aAAa,GACX,OAAO,CAanB;IAqED;;;OAGG;IACH,gBA2BC;IAED,gBAcC;;CACJ;yBA1oBY,OAAO,8DAA8D,EAAE,UAAU;8BACjF,OAAO,0BAA0B,EAAE,eAAe;6BAClD,OAAO,8BAA8B,EAAE,cAAc;mCACrD,OAAO,2BAA2B,EAAE,oBAAoB;4BACxD,OAAO,4BAA4B,EAAE,aAAa;gCA1B/B,4BAA4B;gCAa5B,4BAA4B;uCAKrB,6BAA6B"}
1
+ {"version":3,"file":"GPUProbeClipmapGI.d.ts","sourceRoot":"","sources":["../../../../../../src/shade/renderer/global_illumination/probe_clipmap/GPUProbeClipmapGI.js"],"names":[],"mappings":"AA+BA;;;;;;GAMG;AAEH;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH;IAsUI;;;;OAIG;IACH,oDAJW,eAAe,YACf,oBAAoB,GAClB,OAAO,CAUnB;IA/OD;;OAEG;IACH,sBAFW,eAAe,EAMzB;IAED;;OAEG;IACH,qCAEC;IAED;;OAEG;IACH,qCAEC;IAED;;OAEG;IACH,mCAEC;IAED;;OAEG;IACH,oCAEC;IAED;;;;;;;;;;;;;;;;;OAiBG;IACH;QAZ+B,KAAK,EAAzB,UAAU;QACc,IAAI,EAA5B,cAAc;QACgB,QAAQ,EAAtC,oBAAoB;QACJ,KAAK,EAArB,MAAM;QACU,MAAM,EAAtB,MAAM;QACK,IAAI;QACE,MAAM,GAAvB,MAAM;QAEU,QAAQ,EAAxB,MAAM;aAyIhB;IAqDD;;;OAGG;IACH,0BAEC;IAED;;;;;;;;;;;;;;;;;;OAkBG;IACH;QAT+B,KAAK,EAAzB,UAAU;QACM,KAAK,EAArB,MAAM;QACU,MAAM,EAAtB,MAAM;QAEW,cAAc,GAA/B,MAAM;QACY,SAAS,GAA3B,OAAO;QACY,MAAM;QACE,UAAU,EAArC,UAAU,MAAM,CAAC;aAmC3B;IAED;;;;;;;;;;;;;;OAcG;IACH;QAN+B,KAAK,EAAzB,UAAU;QACwD,KAAK,EAAvE,OAAO,gCAAgC,EAAE,eAAe;QACxC,MAAM,EAAtB,MAAM;QACU,kBAAkB,EAAlC,MAAM;QACU,wBAAwB,EAAxC,MAAM;aAiBhB;IAED;;;;;;;;;OASG;IACH,4CAUC;IAwDD;;;;;;;;;;;;;;;;OAgBG;IACH;QAR+B,KAAK,EAAzB,UAAU;QACc,IAAI,EAA5B,cAAc;QACgB,QAAQ,EAAtC,oBAAoB;QACF,UAAU,EAA5B,MAAM,EAAE;QACQ,QAAQ;QACtB,MAAM,CA8ClB;IAED;;;;;OAKG;IACH,uBAFW,aAAa,QASvB;IAED;;;OAGG;IACH,0BAHW,aAAa,GACX,OAAO,CAanB;IAqED;;;OAGG;IACH,gBA2BC;IAED,gBAcC;;CACJ;yBA9uBY,OAAO,8DAA8D,EAAE,UAAU;8BACjF,OAAO,0BAA0B,EAAE,eAAe;6BAClD,OAAO,8BAA8B,EAAE,cAAc;mCACrD,OAAO,2BAA2B,EAAE,oBAAoB;4BACxD,OAAO,4BAA4B,EAAE,aAAa;gCA3B/B,4BAA4B;gCAa5B,4BAA4B;uCAMrB,6BAA6B"}
@@ -21,6 +21,7 @@ import { ProbeClipmapDebugView } from "./debug/ProbeClipmapDebugView.js";
21
21
  import { PROBE_RECORD_STRUCT } from "./probe/chunk_probe_clipmap.js";
22
22
  import { PROBE_SAMPLING_STRUCT } from "./probe/chunk_probe_clipmap_pick.js";
23
23
  import { GPUProbeClipmap } from "./probe/GPUProbeClipmap.js";
24
+ import { graph_probe_clipmap_want_meshlets } from "./probe/graph_probe_clipmap_want_meshlets.js";
24
25
  import { PROBE_DEPTH_TEXEL_RAYS, PROBE_RAY_CASCADE_MASK, PROBE_TEXEL_RAYS } from "./probe/PROBE_CLIPMAP.js";
25
26
  import { ProbeClipmapHitWants } from "./probe/ProbeClipmapHitWants.js";
26
27
  import { ProbeClipmapIndirectLobe } from "./probe/ProbeClipmapIndirectLobe.js";
@@ -88,6 +89,17 @@ export class GPUProbeClipmapGI {
88
89
  /** The world cache's wants, the frustum's hits. @type {ProbeClipmapHitWants|undefined} */
89
90
  #hit_wants = undefined;
90
91
 
92
+ /**
93
+ * The frustum's wants from surfaces drawn apart from the G-buffer ({@link graph_want_surface}), each with what
94
+ * its pass keeps from frame to frame; the first {@link #surface_wants_used} are this frame's.
95
+ * @type {{wants: ProbeClipmapScreenWants, data: Object, bindings: Object, execute: function}[]}
96
+ */
97
+ #surface_wants = [];
98
+ #surface_wants_used = 0;
99
+
100
+ /** The frame's blue noise, which the surfaces' wants pick their pixels by. */
101
+ #stbn = null;
102
+
91
103
  /** The coarsest brick window's box, metres, which the world light clusters cull lights against. */
92
104
  #clusters_min = [0, 0, 0];
93
105
  #clusters_max = [0, 0, 0];
@@ -316,6 +328,9 @@ export class GPUProbeClipmapGI {
316
328
 
317
329
  this.#screen_wants.set({ depth, normal, camera: view.camera.buffer, stbn, resolution: view.resolution });
318
330
 
331
+ this.#stbn = stbn;
332
+ this.#surface_wants_used = 0;
333
+
319
334
  frustum.graph_update({
320
335
  graph,
321
336
  wants: this.#screen_wants,
@@ -394,6 +409,92 @@ export class GPUProbeClipmapGI {
394
409
  return this.#probe_clipmap !== undefined;
395
410
  }
396
411
 
412
+ /**
413
+ * Record the wants of a screen surface drawn apart from the G-buffer whose reader picks the frustum's probes a
414
+ * pixel (PROBE_CLIPMAP_PROPOSAL_2026_10_27.md §8.3): the water's interface. A pixel of each screen tile wants
415
+ * the cages its pick reads, as the G-buffer's pixels do (`ProbeClipmapScreenWants`).
416
+ *
417
+ * For a pass after this frame's {@link graph_update}, once the surface is drawn. Its wants are taken by the
418
+ * next frame's lifetime, so a probe the surface newly reads is there a frame after the surface is. Records
419
+ * nothing where there are no probes ({@link has_probes}): out of the mode it costs nothing.
420
+ *
421
+ * @param {Object} options
422
+ * @param {FrameGraph} options.graph
423
+ * @param {number} options.depth graph handle of the surface's reverse-Z depth, zero where it has none
424
+ * @param {number} options.normal graph handle of its normals, a `uint` texture: a channel holds a normal
425
+ * octahedral, as the G-buffer packs its own
426
+ * @param {number} [options.normal_channel] the channel that holds the normal, 0 to 3
427
+ * @param {boolean} [options.two_sided] whether the reader turns a normal that faces away from the eye to face it
428
+ * @param {GPUBuffer} options.camera the camera uniform the surface was drawn with
429
+ * @param {ArrayLike<number>} options.resolution the surface's pixels, x and y
430
+ */
431
+ graph_want_surface({ graph, depth, normal, normal_channel = 0, two_sided = false, camera, resolution }) {
432
+ assert.defined(graph, 'graph');
433
+
434
+ if (!this.has_probes) {
435
+ return;
436
+ }
437
+
438
+ const index = this.#surface_wants_used++;
439
+
440
+ if (index === this.#surface_wants.length) {
441
+ const entry = {
442
+ wants: new ProbeClipmapScreenWants(),
443
+ data: {},
444
+ bindings: {},
445
+ execute: (data, resources, context) => {
446
+ // as the frustum's clipmap holds its late set now
447
+ entry.wants.encode(context.encoder, data, resources, this.#probe_clipmap.write_want_bindings(entry.bindings));
448
+ },
449
+ };
450
+
451
+ this.#surface_wants.push(entry);
452
+ }
453
+
454
+ const entry = this.#surface_wants[index];
455
+
456
+ entry.wants.set({ depth, normal, normal_channel, two_sided, camera, stbn: this.#stbn, resolution });
457
+
458
+ const pass = graph.add("Probe Clipmap Want Surface", entry.data, entry.execute);
459
+
460
+ entry.wants.graph_declare(pass, entry.data);
461
+
462
+ // it writes the clipmap's own late set, which the graph does not hold
463
+ pass.make_side_effect();
464
+ }
465
+
466
+ /**
467
+ * Record the wants of a list of meshlets a forward pass draws, whose fragments pick the frustum's probes
468
+ * (PROBE_CLIPMAP_PROPOSAL_2026_10_27.md §8.3): each wants the cages a reader anywhere inside its box can
469
+ * read (`graph_probe_clipmap_want_meshlets`).
470
+ *
471
+ * For a pass after this frame's {@link graph_update}; taken by the next frame's lifetime, as
472
+ * {@link graph_want_surface}'s are. Records nothing where there are no probes ({@link has_probes}).
473
+ *
474
+ * @param {Object} options
475
+ * @param {FrameGraph} options.graph
476
+ * @param {import("../../scene/GPUSceneContext.js").GPUSceneContext} options.scene the meshlets' scene
477
+ * @param {number} options.camera graph handle of the view's camera uniform
478
+ * @param {number} options.meshlet_collection graph handle of the list, `MESHLET_COLLECTION_STRUCT`
479
+ * @param {number} options.meshlet_iterator_command graph handle of the indirect dispatch that walks the list
480
+ */
481
+ graph_want_meshlets({ graph, scene, camera, meshlet_collection, meshlet_iterator_command }) {
482
+ assert.defined(graph, 'graph');
483
+
484
+ if (!this.has_probes) {
485
+ return;
486
+ }
487
+
488
+ graph_probe_clipmap_want_meshlets({
489
+ graph,
490
+ clipmap: this.#probe_clipmap,
491
+ scene,
492
+ camera,
493
+ meshlet_collection,
494
+ meshlet_iterator_command,
495
+ });
496
+ }
497
+
397
498
  /**
398
499
  * Put what the probes' readers bind into `bindings`, `PROBE_CLIPMAP_SAMPLING_GROUP` but its sampler:
399
500
  * once {@link has_probes}, the probes as this frame's {@link graph_update} left them
@@ -210,7 +210,8 @@ export class ProbeClipmapSettings {
210
210
  /**
211
211
  * Rays the frustum's probes trace a frame at most, `FRUSTUM_RAY_BUDGET_FRACTION` of {@link ray_budget}
212
212
  * rounded down, so `floor(frustum_ray_budget / rays_per_probe)` of them update a frame and every wanted one
213
- * is traced again after as many frames as that takes.
213
+ * is traced again after as many frames as that takes, an idle one, live and wanted by nothing, once in
214
+ * `probe_clipmap_idle_periods` of those.
214
215
  * @returns {number}
215
216
  */
216
217
  get frustum_ray_budget(): number;
@@ -1 +1 @@
1
- {"version":3,"file":"ProbeClipmapSettings.d.ts","sourceRoot":"","sources":["../../../../../../src/shade/renderer/global_illumination/probe_clipmap/ProbeClipmapSettings.js"],"names":[],"mappings":"AAMA;;;;;;;;;;;;;;;;GAgBG;AACH;IAaI;;;OAGG;IACH,mCAIC;IAjBD;;;;OAIG;IACH,kCAEC;IAsBD;;;OAGG;IACH,wCAKC;IAjBD;;;OAGG;IACH,uCAEC;IAyBD;;OAEG;IACH,gCAKC;IAlBD;;;;;OAKG;IACH,+BAEC;IAuBD;;OAEG;IACH,kCAIC;IAhBD;;;;OAIG;IACH,iCAEC;IAuBD;;OAEG;IACH,mCAKC;IAlBD;;;;;OAKG;IACH,kCAEC;IAyBD;;;OAGG;IACH,mCAMC;IArBD;;;;;;OAMG;IACH,kCAEC;IAsCD;;;OAGG;IACH,oCAKC;IA/BD;;;;;;;;;;;;;;;;;OAiBG;IACH,mCAEC;IAsCD;;;OAGG;IACH,mCAIC;IA/BD;;;;;;;;;;;;;;;;;;OAkBG;IACH,kCAEC;IAuBD;;;OAGG;IACH,mCAIC;IAjBD;;;;OAIG;IACH,kCAEC;IAsBD;;;OAGG;IACH,wCAKC;IAjBD;;;OAGG;IACH,uCAEC;IAyBD;;OAEG;IACH,6BAKC;IAlBD;;;;;OAKG;IACH,4BAEC;IAuBD;;;OAGG;IACH,mCAMC;IAnBD;;;;OAIG;IACH,kCAEC;IAyBD;;OAEG;IACH,gCAKC;IAjBD;;;;OAIG;IACH,+BAEC;IAuBD;;;;OAIG;IACH,8BAKC;IAnBD;;;;OAIG;IACH,6BAEC;IAyBD;;;OAGG;IACH,0BAIC;IAjBD;;;;OAIG;IACH,yBAEC;IAYD;;;;;OAKG;IACH,iCAEC;IAED;;;OAGG;IACH,+BAEC;IAeD;;;OAGG;IACH,yCAIC;IAnBD;;;;;;OAMG;IACH,wCAEC;IAuBD;;OAEG;IACH,+CAMC;IAlBD;;;;OAIG;IACH,8CAEC;IAwBD;;OAEG;IACH,4CAKC;IAjBD;;;;OAIG;IACH,2CAEC;IAuBD;;;OAGG;IACH,0CAKC;IAlBD;;;;OAIG;IACH,yCAEC;IA2BD;;OAEG;IACH,+BAKC;IApBD;;;;;;;OAOG;IACH,8BAEC;IAyBD;;OAEG;IACH,mCAIC;IAlBD;;;;;;OAMG;IACH,kCAEC;IAwBD;;OAEG;IACH,+BAIC;IAlBD;;;;;;OAMG;IACH,8BAEC;IAsBD;;OAEG;IACH,0BAIC;IAhBD;;;;OAIG;IACH,yBAEC;;CAUJ"}
1
+ {"version":3,"file":"ProbeClipmapSettings.d.ts","sourceRoot":"","sources":["../../../../../../src/shade/renderer/global_illumination/probe_clipmap/ProbeClipmapSettings.js"],"names":[],"mappings":"AAMA;;;;;;;;;;;;;;;;GAgBG;AACH;IAaI;;;OAGG;IACH,mCAIC;IAjBD;;;;OAIG;IACH,kCAEC;IAsBD;;;OAGG;IACH,wCAKC;IAjBD;;;OAGG;IACH,uCAEC;IAyBD;;OAEG;IACH,gCAKC;IAlBD;;;;;OAKG;IACH,+BAEC;IAuBD;;OAEG;IACH,kCAIC;IAhBD;;;;OAIG;IACH,iCAEC;IAuBD;;OAEG;IACH,mCAKC;IAlBD;;;;;OAKG;IACH,kCAEC;IAyBD;;;OAGG;IACH,mCAMC;IArBD;;;;;;OAMG;IACH,kCAEC;IAsCD;;;OAGG;IACH,oCAKC;IA/BD;;;;;;;;;;;;;;;;;OAiBG;IACH,mCAEC;IAsCD;;;OAGG;IACH,mCAIC;IA/BD;;;;;;;;;;;;;;;;;;OAkBG;IACH,kCAEC;IAuBD;;;OAGG;IACH,mCAIC;IAjBD;;;;OAIG;IACH,kCAEC;IAsBD;;;OAGG;IACH,wCAKC;IAjBD;;;OAGG;IACH,uCAEC;IAyBD;;OAEG;IACH,6BAKC;IAlBD;;;;;OAKG;IACH,4BAEC;IAuBD;;;OAGG;IACH,mCAMC;IAnBD;;;;OAIG;IACH,kCAEC;IAyBD;;OAEG;IACH,gCAKC;IAjBD;;;;OAIG;IACH,+BAEC;IAuBD;;;;OAIG;IACH,8BAKC;IAnBD;;;;OAIG;IACH,6BAEC;IAyBD;;;OAGG;IACH,0BAIC;IAjBD;;;;OAIG;IACH,yBAEC;IAYD;;;;;;OAMG;IACH,iCAEC;IAED;;;OAGG;IACH,+BAEC;IAeD;;;OAGG;IACH,yCAIC;IAnBD;;;;;;OAMG;IACH,wCAEC;IAuBD;;OAEG;IACH,+CAMC;IAlBD;;;;OAIG;IACH,8CAEC;IAwBD;;OAEG;IACH,4CAKC;IAjBD;;;;OAIG;IACH,2CAEC;IAuBD;;;OAGG;IACH,0CAKC;IAlBD;;;;OAIG;IACH,yCAEC;IA2BD;;OAEG;IACH,+BAKC;IApBD;;;;;;;OAOG;IACH,8BAEC;IAyBD;;OAEG;IACH,mCAIC;IAlBD;;;;;;OAMG;IACH,kCAEC;IAwBD;;OAEG;IACH,+BAIC;IAlBD;;;;;;OAMG;IACH,8BAEC;IAsBD;;OAEG;IACH,0BAIC;IAhBD;;;;OAIG;IACH,yBAEC;;CAUJ"}
@@ -379,7 +379,8 @@ export class ProbeClipmapSettings {
379
379
  /**
380
380
  * Rays the frustum's probes trace a frame at most, `FRUSTUM_RAY_BUDGET_FRACTION` of {@link ray_budget}
381
381
  * rounded down, so `floor(frustum_ray_budget / rays_per_probe)` of them update a frame and every wanted one
382
- * is traced again after as many frames as that takes.
382
+ * is traced again after as many frames as that takes, an idle one, live and wanted by nothing, once in
383
+ * `probe_clipmap_idle_periods` of those.
383
384
  * @returns {number}
384
385
  */
385
386
  get frustum_ray_budget() {
@@ -121,6 +121,14 @@ export class GPUBrickClipmap {
121
121
  * @returns {Object} bindings
122
122
  */
123
123
  write_bindings(bindings: any): any;
124
+ /**
125
+ * The atlas's footprint as `tile_atlas_slot_shift` packs it: what every reader of the bricks takes in
126
+ * its immediate data as `brick_atlas_shift` and passes to `chunk_brick_clipmap_sample`. It changes
127
+ * only when a grow widens the atlas, in {@link graph_update}: take it after that, each frame, as the
128
+ * atlas itself.
129
+ * @returns {number}
130
+ */
131
+ get atlas_shift(): number;
124
132
  /**
125
133
  * Slots of the atlas.
126
134
  * @returns {number}
@@ -1 +1 @@
1
- {"version":3,"file":"GPUBrickClipmap.d.ts","sourceRoot":"","sources":["../../../../../../../src/shade/renderer/global_illumination/probe_clipmap/brick/GPUBrickClipmap.js"],"names":[],"mappings":"AA6FA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAEH;;;GAGG;AAEH;;;;;;;;GAQG;AAEH;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH;IAkKI;;;;;;;;OAQG;IACH;QAN2B,aAAa,EAA7B,MAAM;QACU,UAAU,EAA1B,MAAM;QAGU,UAAU,EAA1B,MAAM;OAgGhB;IAxQD;;;OAGG;IACH,wBAHU,MAAM,CAGF;IAEd;;;;OAIG;IACH,qBAHU,MAAM,CAGL;IAEX;;;;OAIG;IACH,qBAHU,MAAM,CAGL;IAwPX;;OAEG;IACH,4BAEC;IAED;;OAEG;IACH,4BAEC;IAED;;OAEG;IACH,4BAEC;IAED;;;;OAIG;IACH,wBAEC;IAED;;;;;;;OAOG;IACH,mCAQC;IAED;;;OAGG;IACH,uBAEC;IAED;;;;OAIG;IACH,gBAJW,MAAM,QACN,MAAM,GACJ,MAAM,CAIlB;IAED;;;OAGG;IACH,mBAHW,MAAM,GACJ,MAAM,CAIlB;IAED;;;;;;OAMG;IACH,sBAFW,UAAU,MAAM,CAAC,QAiB3B;IAED;;;OAGG;IACH,oBAHW,oBAAoB,GAClB,OAAO,CAMnB;IAED;;;;;;;;;;;;;;;;;;;OAmBG;IACH;QAb+B,KAAK,EAAzB,UAAU;QACM,CAAC,EAAjB,MAAM;QACU,CAAC,EAAjB,MAAM;QACU,CAAC,EAAjB,MAAM;QACU,MAAM,EAAtB,MAAM;QAC4B,SAAS,EAA3C,UAAU,aAAa,CAAC;QACiB,gBAAgB,GAAzD,UAAU,mBAAmB,CAAC;QACA,KAAK,EAAnC,eAAe,GAAC,IAAI;QACH,MAAM,GAAvB,MAAM;QAEJ,MAAM,CAiHlB;IAgWD,gBAcC;;CACJ;mCAr9BY,OAAO,4BAA4B,EAAE,oBAAoB;yBACzD,OAAO,iEAAiE,EAAE,UAAU;8BACpF,OAAO,mCAAmC,EAAE,eAAe;;;;;;;WA+C1D,UAAU;;;;WACV,MAAM;;;;;;UACN,MAAM;;;;;aAGN,MAAM;;;;sBAEN,MAAM;;;;;mBAEN,MAAM;;;;gBACN,MAAM;mBACN,MAAM;;;;;;;;;;WAGN,eAAe;;;;;;aAEf,eAAe;;;+BAON,UAAU,QAAE,oBAAoB,KAAG,IAAI;;;;;;;;;iCAUvC,UAAU,QAAE,oBAAoB,KAAG,IAAI;;+BA1G/B,0CAA0C"}
1
+ {"version":3,"file":"GPUBrickClipmap.d.ts","sourceRoot":"","sources":["../../../../../../../src/shade/renderer/global_illumination/probe_clipmap/brick/GPUBrickClipmap.js"],"names":[],"mappings":"AA8FA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAEH;;;GAGG;AAEH;;;;;;;;GAQG;AAEH;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH;IAkKI;;;;;;;;OAQG;IACH;QAN2B,aAAa,EAA7B,MAAM;QACU,UAAU,EAA1B,MAAM;QAGU,UAAU,EAA1B,MAAM;OAgGhB;IAxQD;;;OAGG;IACH,wBAHU,MAAM,CAGF;IAEd;;;;OAIG;IACH,qBAHU,MAAM,CAGL;IAEX;;;;OAIG;IACH,qBAHU,MAAM,CAGL;IAwPX;;OAEG;IACH,4BAEC;IAED;;OAEG;IACH,4BAEC;IAED;;OAEG;IACH,4BAEC;IAED;;;;OAIG;IACH,wBAEC;IAED;;;;;;;OAOG;IACH,mCAQC;IAED;;;;;;OAMG;IACH,0BAEC;IAED;;;OAGG;IACH,uBAEC;IAED;;;;OAIG;IACH,gBAJW,MAAM,QACN,MAAM,GACJ,MAAM,CAIlB;IAED;;;OAGG;IACH,mBAHW,MAAM,GACJ,MAAM,CAIlB;IAED;;;;;;OAMG;IACH,sBAFW,UAAU,MAAM,CAAC,QAiB3B;IAED;;;OAGG;IACH,oBAHW,oBAAoB,GAClB,OAAO,CAMnB;IAED;;;;;;;;;;;;;;;;;;;OAmBG;IACH;QAb+B,KAAK,EAAzB,UAAU;QACM,CAAC,EAAjB,MAAM;QACU,CAAC,EAAjB,MAAM;QACU,CAAC,EAAjB,MAAM;QACU,MAAM,EAAtB,MAAM;QAC4B,SAAS,EAA3C,UAAU,aAAa,CAAC;QACiB,gBAAgB,GAAzD,UAAU,mBAAmB,CAAC;QACA,KAAK,EAAnC,eAAe,GAAC,IAAI;QACH,MAAM,GAAvB,MAAM;QAEJ,MAAM,CAiHlB;IAgWD,gBAcC;;CACJ;mCAh+BY,OAAO,4BAA4B,EAAE,oBAAoB;yBACzD,OAAO,iEAAiE,EAAE,UAAU;8BACpF,OAAO,mCAAmC,EAAE,eAAe;;;;;;;WA+C1D,UAAU;;;;WACV,MAAM;;;;;;UACN,MAAM;;;;;aAGN,MAAM;;;;sBAEN,MAAM;;;;;mBAEN,MAAM;;;;gBACN,MAAM;mBACN,MAAM;;;;;;;;;;WAGN,eAAe;;;;;;aAEf,eAAe;;;+BAON,UAAU,QAAE,oBAAoB,KAAG,IAAI;;;;;;;;;iCAUvC,UAAU,QAAE,oBAAoB,KAAG,IAAI;;+BA3G/B,0CAA0C"}
@@ -25,6 +25,7 @@ import {
25
25
  } from "../../../shader/chunk/clipmap/CLIPMAP_LEVEL_STRUCT.js";
26
26
  import { graph_import_buffer } from "../../../shader/graph/graph_import_buffer.js";
27
27
  import { GPUTileAtlas3D } from "../../../texture/atlas/GPUTileAtlas3D.js";
28
+ import { tile_atlas_slot_shift } from "../../../texture/atlas/tile_atlas_slot_shift.js";
28
29
  import {
29
30
  BRICK_OCCUPANCY_BLOCK,
30
31
  BRICK_STAGING_WORDS,
@@ -473,6 +474,17 @@ export class GPUBrickClipmap {
473
474
  return bindings;
474
475
  }
475
476
 
477
+ /**
478
+ * The atlas's footprint as `tile_atlas_slot_shift` packs it: what every reader of the bricks takes in
479
+ * its immediate data as `brick_atlas_shift` and passes to `chunk_brick_clipmap_sample`. It changes
480
+ * only when a grow widens the atlas, in {@link graph_update}: take it after that, each frame, as the
481
+ * atlas itself.
482
+ * @returns {number}
483
+ */
484
+ get atlas_shift() {
485
+ return tile_atlas_slot_shift(this.#atlas.slots_x, this.#atlas.slots_y);
486
+ }
487
+
476
488
  /**
477
489
  * Slots of the atlas.
478
490
  * @returns {number}
@@ -45,15 +45,19 @@ export const BRICK_LEVELS_RESOURCE: ShaderResourceDescriptor;
45
45
  * A brick's distance at a point of its cell, where its slot sits in the atlas, and the field's gradient.
46
46
  *
47
47
  * ```wgsl
48
- * fn brick_clipmap_sample(slot: u32, local: vec3<f32>, voxel: f32) -> f32 // local in voxels from the cell's corner
49
- * fn brick_clipmap_slot_texel(slot: u32) -> vec3<u32> // the slot's texel 0 in the atlas
50
- * fn brick_clipmap_normal(slot: u32, local: vec3<f32>) -> vec3<f32> // out of the solid, unit length
48
+ * fn brick_clipmap_sample(slot: u32, local: vec3<f32>, voxel: f32, atlas_shift: u32) -> f32 // local in voxels from the cell's corner
49
+ * fn brick_clipmap_slot_texel(slot: u32, atlas_shift: u32) -> vec3<u32> // the slot's texel 0 in the atlas
50
+ * fn brick_clipmap_normal(slot: u32, local: vec3<f32>, atlas_shift: u32) -> vec3<f32> // out of the solid, unit length
51
51
  * ```
52
52
  *
53
53
  * One hardware trilinear tap of the atlas at texel `slot_origin + 0.5 + local`, `local` clamped to the
54
54
  * brick's [0, 7]: it never reads a neighbouring slot (§7.2). The gradient is a tetrahedral one, four
55
55
  * taps half a voxel off, each clamped the same way.
56
56
  *
57
+ * `atlas_shift` is the atlas's footprint, `GPUBrickClipmap#atlas_shift`, which every reader takes in its
58
+ * immediate data and passes down: a slot is found with shifts (`tile_atlas_slot_origin_shift`), with no
59
+ * texture query and no divide in front of the tap.
60
+ *
57
61
  * @type {CodeChunk}
58
62
  */
59
63
  export const chunk_brick_clipmap_sample: CodeChunk;
@@ -98,9 +102,11 @@ export const chunk_brick_clipmap_march: CodeChunk;
98
102
  * The first surface along a ray through the brick clipmap (PROBE_CLIPMAP_PROPOSAL_2026_10_27.md §7.9).
99
103
  *
100
104
  * ```wgsl
101
- * fn brick_clipmap_trace(origin: vec3<f32>, direction: vec3<f32>, t_min: f32, t_max: f32, cascade_count: u32) -> BrickClipmapHit
105
+ * fn brick_clipmap_trace(origin: vec3<f32>, direction: vec3<f32>, t_min: f32, t_max: f32, cascade_count: u32, atlas_shift: u32) -> BrickClipmapHit
102
106
  * ```
103
107
  *
108
+ * `atlas_shift` is the atlas's footprint, as {@link chunk_brick_clipmap_sample} takes it.
109
+ *
104
110
  * The march (`brick_clipmap_march`) from `t_min`, at most {@link BRICK_TRACE_STEPS} steps, each
105
111
  * reading in a brick one atlas tap:
106
112
  * - EMPTY inside is a hit where the march stands: the ray is inside a solid, and its hit is a back
@@ -118,7 +124,7 @@ export const chunk_brick_clipmap_trace: CodeChunk;
118
124
  * The finest cascade's signed distance at a point (§7.9), for probe relocation.
119
125
  *
120
126
  * ```wgsl
121
- * fn brick_clipmap_distance(position: vec3<f32>, cascade_count: u32) -> f32
127
+ * fn brick_clipmap_distance(position: vec3<f32>, cascade_count: u32, atlas_shift: u32) -> f32
122
128
  * ```
123
129
  *
124
130
  * The finest window holding the point answers, unless its cell is UNKNOWN, which defers to the
@@ -133,7 +139,7 @@ export const chunk_brick_clipmap_distance: CodeChunk;
133
139
  * no slope: for probe relocation (§8.4).
134
140
  *
135
141
  * ```wgsl
136
- * fn brick_clipmap_gradient(position: vec3<f32>, cascade_count: u32) -> vec3<f32>
142
+ * fn brick_clipmap_gradient(position: vec3<f32>, cascade_count: u32, atlas_shift: u32) -> vec3<f32>
137
143
  * ```
138
144
  *
139
145
  * Four taps of {@link chunk_brick_clipmap_distance} at the corners of a tetrahedron a voxel of the finest
@@ -1 +1 @@
1
- {"version":3,"file":"chunk_brick_clipmap_trace.d.ts","sourceRoot":"","sources":["../../../../../../../src/shade/renderer/global_illumination/probe_clipmap/brick/chunk_brick_clipmap_trace.js"],"names":[],"mappings":"AAoBA;;;;GAIG;AACH,gCAFU,MAAM,CAEoB;AAEpC;;;;GAIG;AACH,gCAFU,MAAM,CAEwB;AAExC;;;;GAIG;AACH,qCAFU,MAAM,CAE0B;AAE1C;;;GAGG;AACH,yCAFU,wBAAwB,CAEoE;AAEtG;;;GAGG;AACH,+CAFU,wBAAwB,CAEgF;AAElH;;;GAGG;AACH,2CAFU,wBAAwB,CAEyE;AAE3G;;;GAGG;AACH,qCAFU,wBAAwB,CAEqF;AAEvH;;;GAGG;AACH,oCAFU,wBAAwB,CAEyE;AAE3G;;;;;;;;;;;;;;GAcG;AACH,yCAFU,SAAS,CAyCZ;AAKP;;;;;;;;;;;;GAYG;AACH,yCAFU,SAAS,CAyBZ;AAIP;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wCAFU,SAAS,CAgFZ;AAKP;;;;;;;;;;;;;;;;;;GAkBG;AACH,wCAFU,SAAS,CAoGZ;AAEP;;;;;;;;;;;;GAYG;AACH,2CAFU,SAAS,CAsCZ;AAIP;;;;;;;;;;;;;;GAcG;AACH,2CAFU,SAAS,CA0BZ;yCA7dkC,sDAAsD;0BADrE,uCAAuC"}
1
+ {"version":3,"file":"chunk_brick_clipmap_trace.d.ts","sourceRoot":"","sources":["../../../../../../../src/shade/renderer/global_illumination/probe_clipmap/brick/chunk_brick_clipmap_trace.js"],"names":[],"mappings":"AAoBA;;;;GAIG;AACH,gCAFU,MAAM,CAEoB;AAEpC;;;;GAIG;AACH,gCAFU,MAAM,CAEwB;AAExC;;;;GAIG;AACH,qCAFU,MAAM,CAE0B;AAE1C;;;GAGG;AACH,yCAFU,wBAAwB,CAEoE;AAEtG;;;GAGG;AACH,+CAFU,wBAAwB,CAEgF;AAElH;;;GAGG;AACH,2CAFU,wBAAwB,CAEyE;AAE3G;;;GAGG;AACH,qCAFU,wBAAwB,CAEqF;AAEvH;;;GAGG;AACH,oCAFU,wBAAwB,CAEyE;AAE3G;;;;;;;;;;;;;;;;;;GAkBG;AACH,yCAFU,SAAS,CAyCZ;AAKP;;;;;;;;;;;;GAYG;AACH,yCAFU,SAAS,CAyBZ;AAIP;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wCAFU,SAAS,CAgFZ;AAKP;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wCAFU,SAAS,CAoGZ;AAEP;;;;;;;;;;;;GAYG;AACH,2CAFU,SAAS,CAsCZ;AAIP;;;;;;;;;;;;;;GAcG;AACH,2CAFU,SAAS,CA0BZ;yCAnekC,sDAAsD;0BADrE,uCAAuC"}