@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
@@ -26,6 +26,7 @@ import {
26
26
  CLIPMAP_LEVEL_STRUCT
27
27
  } from "../../../shader/chunk/clipmap/CLIPMAP_LEVEL_STRUCT.js";
28
28
  import { ShaderSwitchSet } from "../../../shader/compiler/ShaderSwitchSet.js";
29
+ import { build_indirect_compute_dispatch_command } from "../../../gpu_primitive/indirect/IndirectComputeCommandBuildPass.js";
29
30
  import { graph_import_buffer } from "../../../shader/graph/graph_import_buffer.js";
30
31
  import { GPUTileAtlas2D } from "../../../texture/atlas/GPUTileAtlas2D.js";
31
32
  import {
@@ -39,6 +40,7 @@ import {
39
40
  import { PROBE_SAMPLING_STRUCT } from "./chunk_probe_clipmap_pick.js";
40
41
  import {
41
42
  probe_clipmap_guide_words,
43
+ probe_clipmap_idle_periods,
42
44
  probe_clipmap_maps_words,
43
45
  PROBE_CASCADE_HYSTERESIS,
44
46
  PROBE_CASCADE_STEP,
@@ -92,6 +94,7 @@ import { shader_probe_clipmap_schedule } from "./shader_probe_clipmap_schedule.j
92
94
  import { shader_probe_clipmap_shade } from "./shader_probe_clipmap_shade.js";
93
95
  import { shader_probe_clipmap_trace } from "./shader_probe_clipmap_trace.js";
94
96
  import { shader_probe_clipmap_trace_command } from "./shader_probe_clipmap_trace_command.js";
97
+ import { shader_probe_clipmap_want_late } from "./shader_probe_clipmap_want_late.js";
95
98
 
96
99
  /**
97
100
  * @typedef {import("../ProbeClipmapSettings.js").ProbeClipmapSettings} ProbeClipmapSettings
@@ -153,8 +156,11 @@ const SAMPLING_SELECT_HALF = PROBE_SAMPLING_STRUCT.get("select_half").offset >>>
153
156
  * **A frame's lifetime** ({@link graph_update}, §8.3, §8.5): retire frees the probes whose points left
154
157
  * their windows and those the last frame's schedule evicted, the wants mark the cages they read, admit
155
158
  * gives each wanted point without a probe a NEW one, schedule sets the period T from the probes waiting
156
- * for an update and the next frame's eviction from the pressure on the slots (`PROBE_FREE_SLACK`), and
157
- * the due passes list the frame's updates, NEW probes first.
159
+ * for an update and the idle ones, and the next frame's eviction from the pressure on the slots
160
+ * (`PROBE_FREE_SLACK`), and the due passes list the frame's updates, NEW probes first. Every live probe
161
+ * keeps being updated: one a want waits on every period, an idle one once in
162
+ * `probe_clipmap_idle_periods` of them, so the light a probe holds is no older than that whether or not
163
+ * anything wants it.
158
164
  *
159
165
  * **The frame's rays** (§8.6): the lifetime's last passes lay them out. Each listed probe's rays this update
160
166
  * are a count the budget does not scale (a uniform update's R, a DEAD probe's `PROBE_DEAD_RAYS`) and a request it
@@ -372,6 +378,20 @@ export class GPUProbeClipmap {
372
378
  /** Points the wanted list holds: the fewer of the keys and what the wants can want, as it last grew. */
373
379
  #wanted_capacity = 0;
374
380
 
381
+ /**
382
+ * The late wants (§8.3): a wanted list and its bits, which a reader drawn after the frame's lifetime wants
383
+ * into; the windows its keys were written in; and the launch that takes them into the next frame's wanted
384
+ * set. Made when a reader first asks for them ({@link write_want_bindings}).
385
+ * @type {{list: GPUBuffer, bits: GPUBuffer, levels: GPUBuffer, command: GPUBuffer}|null}
386
+ */
387
+ #late = null;
388
+
389
+ /** Whether a reader has asked for the late set since a lifetime last took it. */
390
+ #late_pending = false;
391
+
392
+ /** Whether the frame's lifetime takes the late set: {@link #late_pending} as the frame was recorded. */
393
+ #late_taken = false;
394
+
375
395
  /** Whether the next frame is the first, which fills the indirection and the free list. */
376
396
  #fill_pending = true;
377
397
 
@@ -403,20 +423,27 @@ export class GPUProbeClipmap {
403
423
  #levels_data = new ArrayBuffer(CLIPMAP_LEVEL_ARRAY.size);
404
424
  #levels_i32 = new Int32Array(this.#levels_data);
405
425
  #levels_f32 = new Float32Array(this.#levels_data);
426
+ #levels_u8 = new Uint8Array(this.#levels_data);
427
+
428
+ /** The levels as the frame before uploaded them: the windows its late wants were written in. */
429
+ #late_levels_u8 = new Uint8Array(CLIPMAP_LEVEL_ARRAY.size);
406
430
 
407
431
  #retire_settings = { capacity: 0, resolution: 0, frame: 0 };
408
432
  #want_settings = { cascade_count: 0, resolution: 0, frame: 0, wanted_capacity: 0, anchor: new Float32Array(3), select_half: 0 };
433
+ /** {@link #want_settings} for the late wants, whose list holds every key. */
434
+ #late_want_settings = { cascade_count: 0, resolution: 0, frame: 0, wanted_capacity: 0, anchor: new Float32Array(3), select_half: 0 };
435
+ #late_settings = { resolution: 0, wanted_capacity: 0, late_capacity: 0 };
409
436
  #admit_command_settings = { wanted_capacity: 0 };
410
437
  #admit_settings = { capacity: 0, resolution: 0, wanted_capacity: 0, frame: 0 };
411
- #schedule_settings = { capacity: 0, wanted_capacity: 0, trace_capacity: 0, slack: 0 };
412
- #due_settings = { capacity: 0, trace_capacity: 0, frame: 0, new_only: 0 };
438
+ #schedule_settings = { capacity: 0, wanted_capacity: 0, trace_capacity: 0, slack: 0, idle_periods: 1 };
439
+ #due_settings = { capacity: 0, trace_capacity: 0, frame: 0, new_only: 0, idle_periods: 1 };
413
440
  #trace_command_settings = { trace_capacity: 0, radiance_resolution: 0, depth_resolution: 0, radiance_skirt: 0 };
414
441
  #order_settings = { trace_capacity: 0, resolution: 0, axis_bits: 0 };
415
442
  #ray_counts_settings = { trace_capacity: 0, rays_per_probe: 0, rays_min: 0, rays_dead: 0, radiance_resolution: 0, uniform_period: PROBE_UNIFORM_PERIOD };
416
443
  #ray_layout_settings = { trace_capacity: 0, ray_budget: 0 };
417
- #relocate_settings = { trace_capacity: 0, brick_cascade_count: 0 };
444
+ #relocate_settings = { trace_capacity: 0, brick_cascade_count: 0, brick_atlas_shift: 0 };
418
445
  #guide_settings = { trace_capacity: 0, rays_per_probe: 0, radiance_resolution: 0, radiance_tiles_per_row: 0, radiance_skirt: 0 };
419
- #trace_settings = { trace_capacity: 0, rays_per_probe: 0, radiance_resolution: 0, brick_cascade_count: 0, t_max: 0, uniform_period: PROBE_UNIFORM_PERIOD };
446
+ #trace_settings = { trace_capacity: 0, rays_per_probe: 0, radiance_resolution: 0, brick_cascade_count: 0, t_max: 0, uniform_period: PROBE_UNIFORM_PERIOD, brick_atlas_shift: 0 };
420
447
  #accumulate_settings = { trace_capacity: 0, rays_per_probe: 0, radiance_resolution: 0, depth_resolution: 0, radiance_tiles_per_row: 0, radiance_skirt: 0, depth_tiles_per_row: 0, uniform_period: PROBE_UNIFORM_PERIOD };
421
448
  #project_settings = { trace_capacity: 0, rays_per_probe: 0, radiance_resolution: 0, depth_resolution: 0, frame: 0, uniform_period: PROBE_UNIFORM_PERIOD, rays_min: 0, rays_max: 0 };
422
449
  #publish_settings = { trace_capacity: 0, radiance_resolution: 0, depth_resolution: 0, radiance_tiles_per_row: 0, radiance_skirt: 0, depth_tiles_per_row: 0 };
@@ -430,6 +457,9 @@ export class GPUProbeClipmap {
430
457
  /** What a want binds of this clipmap: its levels, wanted list and bits, and its want settings. */
431
458
  #want_bindings = {};
432
459
 
460
+ /** What taking the late set binds. */
461
+ #late_bindings = {};
462
+
433
463
  /** The bounce's sets as their clipmaps hold them, under the bounce pass's names. */
434
464
  #set_bindings = {};
435
465
 
@@ -613,6 +643,44 @@ export class GPUProbeClipmap {
613
643
  return bindings;
614
644
  }
615
645
 
646
+ /**
647
+ * Put what a want recorded after the frame's lifetime binds into `bindings`, under the names
648
+ * `chunk_probe_clipmap_want` reads them by, with its settings as `settings`: the levels, and the late
649
+ * wanted list and bits in place of the frame's. The next frame's lifetime takes what was wanted there into its
650
+ * own wanted set, where its windows still hold the point (§8.3): a probe such a want asks for is admitted
651
+ * a frame later than one the frame's own wants ask for.
652
+ *
653
+ * For a pass that runs after this frame's lifetime; take them each frame. Asking is what makes the next
654
+ * lifetime take the late set.
655
+ *
656
+ * @param {Object} bindings
657
+ * @returns {Object} bindings
658
+ */
659
+ write_want_bindings(bindings) {
660
+ if (this.#late === null) {
661
+ this.#late = {
662
+ // every key once: a late want can want any point of the lattice
663
+ list: this.#create_buffer('probe late wanted', LIST_HEADER_BYTES + 4 * this.#key_count, GPUBufferUsage.COPY_DST),
664
+ bits: this.#create_buffer('probe late wanted bits', 4 * Math.ceil(this.#key_count / 32), 0),
665
+ levels: this.#device.createBuffer(BufferDescriptor.fromJSON({
666
+ label: `${this.label} / probe late levels`,
667
+ size: CLIPMAP_LEVEL_ARRAY.size,
668
+ usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST,
669
+ })),
670
+ command: this.#create_buffer('probe late command', 16, GPUBufferUsage.INDIRECT),
671
+ };
672
+ }
673
+
674
+ this.#late_pending = true;
675
+
676
+ bindings.probe_levels = this.#levels;
677
+ bindings.probe_wanted = this.#late.list;
678
+ bindings.probe_wanted_bits = this.#late.bits;
679
+ bindings.settings = this.#late_want_settings;
680
+
681
+ return bindings;
682
+ }
683
+
616
684
  /**
617
685
  * @returns {GPUTexture}
618
686
  */
@@ -848,12 +916,24 @@ export class GPUProbeClipmap {
848
916
  const rays_min = Math.min(PROBE_RAYS_PER_TEXEL_MIN * texels, rays_per_probe);
849
917
  const rays_dead = Math.min(PROBE_DEAD_RAYS, rays_per_probe);
850
918
  const rays_max = PROBE_RAYS_PER_TEXEL_MAX * texels;
919
+ const idle_periods = probe_clipmap_idle_periods(rays_per_probe, this.radiance_resolution);
851
920
 
852
921
  this.#ensure_trace(trace_capacity);
853
922
  // the requests share what the counts leave of the budget, so the frame's rays are at most it
854
923
  this.#ensure_rays(ray_budget);
855
924
 
856
- this.#device.queue.writeBuffer(this.#levels, 0, this.#levels_data, 0, this.cascade_count * CLIPMAP_LEVEL_STRUCT.aligned_size);
925
+ const levels_bytes = this.cascade_count * CLIPMAP_LEVEL_STRUCT.aligned_size;
926
+
927
+ // what was wanted late, in the last frame's windows, is taken in this frame's lifetime
928
+ this.#late_taken = this.#late_pending;
929
+ this.#late_pending = false;
930
+
931
+ if (this.#late_taken) {
932
+ this.#device.queue.writeBuffer(this.#late.levels, 0, this.#late_levels_u8, 0, levels_bytes);
933
+ }
934
+
935
+ this.#device.queue.writeBuffer(this.#levels, 0, this.#levels_data, 0, levels_bytes);
936
+ this.#late_levels_u8.set(this.#levels_u8);
857
937
 
858
938
  // the readers' view of the clipmap: its shape, and the depth and radiance atlases', which grow by rows
859
939
  const depth_texture = this.#depth.texture_at(0);
@@ -884,12 +964,25 @@ export class GPUProbeClipmap {
884
964
  this.#want_settings.cascade_count = this.cascade_count;
885
965
  this.#want_settings.resolution = this.resolution;
886
966
  this.#want_settings.frame = this.#frame;
887
- this.#ensure_wanted(Math.min(this.#key_count, wants.wanted_bound()));
967
+ // the late wants can want any point, so with them the list holds every key
968
+ this.#ensure_wanted(this.#late !== null ? this.#key_count : Math.min(this.#key_count, wants.wanted_bound()));
888
969
 
889
970
  this.#want_settings.wanted_capacity = this.#wanted_capacity;
890
971
  this.#want_settings.anchor.set(this.#anchor);
891
972
  this.#want_settings.select_half = this.#select_half;
892
973
 
974
+ const late_want = this.#late_want_settings;
975
+
976
+ late_want.cascade_count = this.cascade_count;
977
+ late_want.resolution = this.resolution;
978
+ late_want.frame = this.#frame;
979
+ late_want.wanted_capacity = this.#key_count;
980
+ late_want.anchor.set(this.#anchor);
981
+ late_want.select_half = this.#select_half;
982
+
983
+ this.#late_settings.resolution = this.resolution;
984
+ this.#late_settings.wanted_capacity = this.#wanted_capacity;
985
+ this.#late_settings.late_capacity = this.#key_count;
893
986
 
894
987
  this.#admit_command_settings.wanted_capacity = this.#wanted_capacity;
895
988
 
@@ -902,10 +995,12 @@ export class GPUProbeClipmap {
902
995
  this.#schedule_settings.wanted_capacity = this.#wanted_capacity;
903
996
  this.#schedule_settings.trace_capacity = trace_capacity;
904
997
  this.#schedule_settings.slack = Math.ceil(this.#capacity * PROBE_FREE_SLACK);
998
+ this.#schedule_settings.idle_periods = idle_periods;
905
999
 
906
1000
  this.#due_settings.capacity = this.#capacity;
907
1001
  this.#due_settings.trace_capacity = trace_capacity;
908
1002
  this.#due_settings.frame = this.#frame;
1003
+ this.#due_settings.idle_periods = idle_periods;
909
1004
 
910
1005
  this.#trace_command_settings.trace_capacity = trace_capacity;
911
1006
  this.#trace_command_settings.radiance_resolution = this.radiance_resolution;
@@ -942,10 +1037,12 @@ export class GPUProbeClipmap {
942
1037
  this.#trace_settings.rays_per_probe = rays_per_probe;
943
1038
  this.#trace_settings.radiance_resolution = this.radiance_resolution;
944
1039
  this.#trace_settings.brick_cascade_count = brick_clipmap.cascade_count;
1040
+ this.#trace_settings.brick_atlas_shift = brick_clipmap.atlas_shift;
945
1041
  this.#trace_settings.t_max = Math.sqrt(3) * brick_clipmap.resolution * brick_clipmap.cell_size(coarsest);
946
1042
 
947
1043
  this.#relocate_settings.trace_capacity = trace_capacity;
948
1044
  this.#relocate_settings.brick_cascade_count = brick_clipmap.cascade_count;
1045
+ this.#relocate_settings.brick_atlas_shift = brick_clipmap.atlas_shift;
949
1046
 
950
1047
  const accumulate = this.#accumulate_settings;
951
1048
 
@@ -1239,6 +1336,27 @@ export class GPUProbeClipmap {
1239
1336
 
1240
1337
  this.#wants.encode(encoder, data, resources, want);
1241
1338
 
1339
+ if (this.#late_taken) {
1340
+ // and what was wanted after the last frame's lifetime, a thread a key
1341
+ const late = this.#late;
1342
+ const taken = this.#late_bindings;
1343
+
1344
+ build_indirect_compute_dispatch_command(PROBE_THREAD_WORKGROUP_SIZE, encoder, late.list, 0, late.command, 0);
1345
+
1346
+ taken.probe_levels = this.#levels;
1347
+ taken.probe_late_levels = late.levels;
1348
+ taken.probe_late_wanted = late.list;
1349
+ taken.probe_late_wanted_bits = late.bits;
1350
+ taken.probe_wanted = this.#wanted;
1351
+ taken.probe_wanted_bits = this.#wanted_bits;
1352
+ taken.settings = this.#late_settings;
1353
+
1354
+ shader_probe_clipmap_want_late.dispatchIndirect({ encoder, bindings: taken, command: late.command });
1355
+
1356
+ // its bits the threads cleared, key by key
1357
+ encoder.clearBuffer(late.list, 0, 4);
1358
+ }
1359
+
1242
1360
  encoder.clearBuffer(this.#trace, 0, 4);
1243
1361
 
1244
1362
  b.settings = this.#admit_command_settings;
@@ -1258,7 +1376,7 @@ export class GPUProbeClipmap {
1258
1376
 
1259
1377
  shader_probe_clipmap_schedule.dispatch({ encoder, bindings: b });
1260
1378
 
1261
- // the frame's updates: the NEW probes first, then those whose turn it is
1379
+ // the frame's updates: the NEW probes first, then those whose turn it is, waiting or idle
1262
1380
  const due = this.#due_settings;
1263
1381
 
1264
1382
  b.settings = due;
@@ -1581,7 +1699,7 @@ export class GPUProbeClipmap {
1581
1699
  this.#radiance.destroy();
1582
1700
  this.#depth.destroy();
1583
1701
 
1584
- for (const buffer of [this.#levels, this.#states, this.#estimators, this.#records, this.#free, this.#listed, this.#candidates, this.#counters, this.#dispatch, this.#eviction, ...this.#active, this.#wanted, this.#wanted_bits, this.#trace, this.#origins, this.#maps, this.#guide, this.#resamples, this.#projection, this.#requests, this.#ray_counts, this.#ray_requests, this.#ray_count_sums, this.#ray_request_sums, this.#ray_sums, this.#ray_scan_spine, this.#ray_scan_command, this.#rays, this.#sampling]) {
1702
+ for (const buffer of [this.#levels, this.#states, this.#estimators, this.#records, this.#free, this.#listed, this.#candidates, this.#counters, this.#dispatch, this.#eviction, ...this.#active, this.#wanted, this.#wanted_bits, this.#trace, this.#origins, this.#maps, this.#guide, this.#resamples, this.#projection, this.#requests, this.#ray_counts, this.#ray_requests, this.#ray_count_sums, this.#ray_request_sums, this.#ray_sums, this.#ray_scan_spine, this.#ray_scan_command, this.#rays, this.#sampling, this.#late?.list, this.#late?.bits, this.#late?.levels, this.#late?.command]) {
1585
1703
  buffer?.destroy();
1586
1704
  }
1587
1705
  }
@@ -9,6 +9,16 @@
9
9
  * @returns {number}
10
10
  */
11
11
  export function probe_clipmap_maps_words(radiance_resolution: number, depth_resolution: number): number;
12
+ /**
13
+ * Periods between an idle probe's updates, and the idle probes the period counts as one waiting: R over
14
+ * the rays a period an idle probe keeps ({@link PROBE_RAYS_PER_TEXEL_IDLE}), a ray at least. So the
15
+ * period is the probes' rays over the budget: R a waiting probe, those an idle one.
16
+ *
17
+ * @param {number} rays_per_probe rays a uniform update casts, R
18
+ * @param {number} radiance_resolution octahedral radiance texels a side, n_r
19
+ * @returns {number} a positive integer
20
+ */
21
+ export function probe_clipmap_idle_periods(rays_per_probe: number, radiance_resolution: number): number;
12
22
  /**
13
23
  * Words of a listed probe's guide (`probe_guide`), as the guide passes write it, in this order:
14
24
  * - n_r² first rays, by walk position;
@@ -70,7 +80,8 @@ export const PROBE_COUNTER_FREE: number;
70
80
  */
71
81
  export const PROBE_COUNTER_STARVED: number;
72
82
  /**
73
- * The frame's period T, as schedule sets it (§8.5): frames between a wanted probe's updates.
83
+ * The frame's period T, as schedule sets it (§8.5): frames between a wanted probe's updates, and
84
+ * `probe_clipmap_idle_periods` of them between an idle one's.
74
85
  * @type {number}
75
86
  */
76
87
  export const PROBE_COUNTER_PERIOD: number;
@@ -275,6 +286,13 @@ export const PROBE_DEAD_RAYS: number;
275
286
  * @type {number}
276
287
  */
277
288
  export const PROBE_RAYS_PER_TEXEL_MAX: number;
289
+ /**
290
+ * Rays a period an idle probe keeps, of the radiance texels: a sixteenth, Enshrouded's floor of 16 rays on
291
+ * its 16×16 map. An idle probe is a live one no want waits on: past its first update, and not wanted since
292
+ * its last. It keeps them as whole updates, one in {@link probe_clipmap_idle_periods} periods (§8.5).
293
+ * @type {number}
294
+ */
295
+ export const PROBE_RAYS_PER_TEXEL_IDLE: number;
278
296
  /**
279
297
  * Rays a guided update gives one radiance texel at most, the same gather budget as a depth texel's
280
298
  * ({@link PROBE_DEPTH_TEXEL_RAYS}). The guide holds each texel's weight down to it and spreads what it
@@ -1 +1 @@
1
- {"version":3,"file":"PROBE_CLIPMAP.d.ts","sourceRoot":"","sources":["../../../../../../../src/shade/renderer/global_illumination/probe_clipmap/probe/PROBE_CLIPMAP.js"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"PROBE_CLIPMAP.d.ts","sourceRoot":"","sources":["../../../../../../../src/shade/renderer/global_illumination/probe_clipmap/probe/PROBE_CLIPMAP.js"],"names":[],"mappings":"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"}
@@ -1,3 +1,4 @@
1
+ import { AGE_EVICTION_BUCKETS } from "../../../gpu_primitive/age_eviction/chunk_age_eviction.js";
1
2
  import { UINT32_MAX } from "../../../../../core/binary/UINT32_MAX.js";
2
3
 
3
4
  /*
@@ -77,7 +78,8 @@ export const PROBE_COUNTER_FREE = 0;
77
78
  export const PROBE_COUNTER_STARVED = 1;
78
79
 
79
80
  /**
80
- * The frame's period T, as schedule sets it (§8.5): frames between a wanted probe's updates.
81
+ * The frame's period T, as schedule sets it (§8.5): frames between a wanted probe's updates, and
82
+ * `probe_clipmap_idle_periods` of them between an idle one's.
81
83
  * @type {number}
82
84
  */
83
85
  export const PROBE_COUNTER_PERIOD = 2;
@@ -102,7 +104,7 @@ export const PROBE_COUNTER_EVICTED = 4;
102
104
  * middle one, so the first holds 2⁻¹⁶ s and under and the last 2¹⁵ s, about nine hours, and over.
103
105
  * @type {number}
104
106
  */
105
- export const PROBE_AGE_BUCKETS = 32;
107
+ export const PROBE_AGE_BUCKETS = AGE_EVICTION_BUCKETS;
106
108
 
107
109
  /**
108
110
  * The first of {@link PROBE_AGE_BUCKETS} counters: the probes the frame's retire kept and could have evicted,
@@ -336,6 +338,29 @@ export const PROBE_DEAD_RAYS = 16;
336
338
  */
337
339
  export const PROBE_RAYS_PER_TEXEL_MAX = 4;
338
340
 
341
+ /**
342
+ * Rays a period an idle probe keeps, of the radiance texels: a sixteenth, Enshrouded's floor of 16 rays on
343
+ * its 16×16 map. An idle probe is a live one no want waits on: past its first update, and not wanted since
344
+ * its last. It keeps them as whole updates, one in {@link probe_clipmap_idle_periods} periods (§8.5).
345
+ * @type {number}
346
+ */
347
+ export const PROBE_RAYS_PER_TEXEL_IDLE = 1 / 16;
348
+
349
+ /**
350
+ * Periods between an idle probe's updates, and the idle probes the period counts as one waiting: R over
351
+ * the rays a period an idle probe keeps ({@link PROBE_RAYS_PER_TEXEL_IDLE}), a ray at least. So the
352
+ * period is the probes' rays over the budget: R a waiting probe, those an idle one.
353
+ *
354
+ * @param {number} rays_per_probe rays a uniform update casts, R
355
+ * @param {number} radiance_resolution octahedral radiance texels a side, n_r
356
+ * @returns {number} a positive integer
357
+ */
358
+ export function probe_clipmap_idle_periods(rays_per_probe, radiance_resolution) {
359
+ const rays = Math.max(1, PROBE_RAYS_PER_TEXEL_IDLE * radiance_resolution * radiance_resolution);
360
+
361
+ return Math.max(1, Math.ceil(rays_per_probe / rays));
362
+ }
363
+
339
364
  /**
340
365
  * Rays a guided update gives one radiance texel at most, the same gather budget as a depth texel's
341
366
  * ({@link PROBE_DEPTH_TEXEL_RAYS}). The guide holds each texel's weight down to it and spreads what it
@@ -1,27 +1,35 @@
1
1
  /**
2
- * A clipmap's probes wanted by the frame's pixels (PROBE_CLIPMAP_PROPOSAL_2026_10_27.md §8.3): one pixel of
3
- * each screen tile wants the cages its pick reads (`shader_probe_clipmap_want`). The wants of the frustum's
4
- * probes; a {@link GPUProbeClipmap} records them in its lifetime, between retire and admit.
2
+ * A clipmap's probes wanted by the pixels of a screen surface (PROBE_CLIPMAP_PROPOSAL_2026_10_27.md §8.3): one
3
+ * pixel of each screen tile wants the cages its pick reads (`shader_probe_clipmap_want`).
5
4
  *
6
- * Give it the frame's G-buffer with {@link set} before the clipmap's `graph_update`.
5
+ * The frame's G-buffer is the frustum's probes' own wants, which a {@link GPUProbeClipmap} records in its
6
+ * lifetime, between retire and admit: give it the G-buffer with {@link set} before the clipmap's
7
+ * `graph_update`. A surface drawn apart from the G-buffer, whose reader picks probes per pixel, is another
8
+ * one's, encoded once that surface is drawn into what `GPUProbeClipmap.write_want_bindings` binds.
7
9
  */
8
10
  export class ProbeClipmapScreenWants {
9
11
  /**
10
- * The frame's G-buffer and view.
12
+ * The frame's surface and view.
11
13
  *
12
14
  * @param {Object} options
13
- * @param {number} options.depth graph handle of the frame's depth
14
- * @param {number} options.normal graph handle of the G-buffer's normals
15
+ * @param {number} options.depth graph handle of the surface's reverse-Z depth, zero where it has none
16
+ * @param {number} options.normal graph handle of its normals, a `uint` texture: a channel holds a normal
17
+ * octahedral, as the G-buffer packs its own
15
18
  * @param {GPUBuffer} options.camera the view's camera uniform
16
19
  * @param {*} options.stbn the 2-channel spatio-temporal blue noise, `STATIC_GRAPHICS_ENGINE_ASSETS.stbn_vec2`
17
- * @param {ArrayLike<number>} options.resolution the frame's pixels, x and y
20
+ * @param {ArrayLike<number>} options.resolution the surface's pixels, x and y
21
+ * @param {number} [options.normal_channel] the channel that holds the normal, 0 to 3: the G-buffer's is 0
22
+ * @param {boolean} [options.two_sided] whether the surface's reader turns a normal that faces away from the eye
23
+ * to face it, as the reader of a surface seen from both sides does
18
24
  */
19
- set({ depth, normal, camera, stbn, resolution }: {
25
+ set({ depth, normal, camera, stbn, resolution, normal_channel, two_sided }: {
20
26
  depth: number;
21
27
  normal: number;
22
28
  camera: GPUBuffer;
23
29
  stbn: any;
24
30
  resolution: ArrayLike<number>;
31
+ normal_channel?: number;
32
+ two_sided?: boolean;
25
33
  }): void;
26
34
  /**
27
35
  * @returns {number} the most points a frame's wants list: a pixel of each tile, the eight points of a cage in
@@ -29,7 +37,7 @@ export class ProbeClipmapScreenWants {
29
37
  */
30
38
  wanted_bound(): number;
31
39
  /**
32
- * Declare what the wants read on the lifetime's pass.
40
+ * Declare what the wants read on the pass that encodes them.
33
41
  *
34
42
  * @param {import("../../../../../engine/graphics/render/frame_graph/FramePassBuilder.js").FramePassBuilder} pass
35
43
  * @param {Object} data the pass's data, which {@link encode} is given back
@@ -37,7 +45,7 @@ export class ProbeClipmapScreenWants {
37
45
  graph_declare(pass: import("../../../../../engine/graphics/render/frame_graph/FramePassBuilder.js").FramePassBuilder, data: any): void;
38
46
  /**
39
47
  * @param {GPUCommandEncoder} encoder
40
- * @param {Object} data the lifetime pass's data
48
+ * @param {Object} data the encoding pass's data
41
49
  * @param {*} resources the frame graph's resources
42
50
  * @param {Object} clipmap what the wanting clipmap binds: `probe_levels`, `probe_wanted`,
43
51
  * `probe_wanted_bits` and its want settings as `settings`
@@ -1 +1 @@
1
- {"version":3,"file":"ProbeClipmapScreenWants.d.ts","sourceRoot":"","sources":["../../../../../../../src/shade/renderer/global_illumination/probe_clipmap/probe/ProbeClipmapScreenWants.js"],"names":[],"mappings":"AAIA;;;;;;GAMG;AACH;IAeI;;;;;;;;;OASG;IACH;QAN2B,KAAK,EAArB,MAAM;QACU,MAAM,EAAtB,MAAM;QACa,MAAM;QACd,IAAI;QACY,UAAU,EAArC,UAAU,MAAM,CAAC;aAqB3B;IAED;;;OAGG;IACH,gBAHa,MAAM,CAKlB;IAED;;;;;OAKG;IACH,oBAHW,OAAO,uEAAuE,EAAE,gBAAgB,mBAQ1G;IAED;;;;;;OAMG;IACH,kFAcC;;CACJ"}
1
+ {"version":3,"file":"ProbeClipmapScreenWants.d.ts","sourceRoot":"","sources":["../../../../../../../src/shade/renderer/global_illumination/probe_clipmap/probe/ProbeClipmapScreenWants.js"],"names":[],"mappings":"AAIA;;;;;;;;GAQG;AACH;IAsBI;;;;;;;;;;;;;OAaG;IACH;QAV2B,KAAK,EAArB,MAAM;QACU,MAAM,EAAtB,MAAM;QAEa,MAAM;QACd,IAAI;QACY,UAAU,EAArC,UAAU,MAAM,CAAC;QACA,cAAc,GAA/B,MAAM;QACY,SAAS,GAA3B,OAAO;aA2BjB;IAED;;;OAGG;IACH,gBAHa,MAAM,CAKlB;IAED;;;;;OAKG;IACH,oBAHW,OAAO,uEAAuE,EAAE,gBAAgB,mBAQ1G;IAED;;;;;;OAMG;IACH,kFAoBC;;CACJ"}
@@ -3,11 +3,13 @@ import { PROBE_WANT_TILE, PROBE_WANT_WORKGROUP_TILES } from "./PROBE_CLIPMAP.js"
3
3
  import { shader_probe_clipmap_want } from "./shader_probe_clipmap_want.js";
4
4
 
5
5
  /**
6
- * A clipmap's probes wanted by the frame's pixels (PROBE_CLIPMAP_PROPOSAL_2026_10_27.md §8.3): one pixel of
7
- * each screen tile wants the cages its pick reads (`shader_probe_clipmap_want`). The wants of the frustum's
8
- * probes; a {@link GPUProbeClipmap} records them in its lifetime, between retire and admit.
6
+ * A clipmap's probes wanted by the pixels of a screen surface (PROBE_CLIPMAP_PROPOSAL_2026_10_27.md §8.3): one
7
+ * pixel of each screen tile wants the cages its pick reads (`shader_probe_clipmap_want`).
9
8
  *
10
- * Give it the frame's G-buffer with {@link set} before the clipmap's `graph_update`.
9
+ * The frame's G-buffer is the frustum's probes' own wants, which a {@link GPUProbeClipmap} records in its
10
+ * lifetime, between retire and admit: give it the G-buffer with {@link set} before the clipmap's
11
+ * `graph_update`. A surface drawn apart from the G-buffer, whose reader picks probes per pixel, is another
12
+ * one's, encoded once that surface is drawn into what `GPUProbeClipmap.write_want_bindings` binds.
11
13
  */
12
14
  export class ProbeClipmapScreenWants {
13
15
  #depth = -1;
@@ -20,32 +22,48 @@ export class ProbeClipmapScreenWants {
20
22
 
21
23
  #groups = [0, 0];
22
24
 
25
+ #normal_channel = 0;
26
+
27
+ #two_sided = false;
28
+
29
+ /** The wanting clipmap's settings and how this surface's normals are read. */
30
+ #settings = { cascade_count: 0, resolution: 0, frame: 0, wanted_capacity: 0, anchor: null, select_half: 0, normal_channel: 0, two_sided: 0 };
31
+
23
32
  #tiles = 0;
24
33
 
25
34
  #bindings = {};
26
35
 
27
36
  /**
28
- * The frame's G-buffer and view.
37
+ * The frame's surface and view.
29
38
  *
30
39
  * @param {Object} options
31
- * @param {number} options.depth graph handle of the frame's depth
32
- * @param {number} options.normal graph handle of the G-buffer's normals
40
+ * @param {number} options.depth graph handle of the surface's reverse-Z depth, zero where it has none
41
+ * @param {number} options.normal graph handle of its normals, a `uint` texture: a channel holds a normal
42
+ * octahedral, as the G-buffer packs its own
33
43
  * @param {GPUBuffer} options.camera the view's camera uniform
34
44
  * @param {*} options.stbn the 2-channel spatio-temporal blue noise, `STATIC_GRAPHICS_ENGINE_ASSETS.stbn_vec2`
35
- * @param {ArrayLike<number>} options.resolution the frame's pixels, x and y
45
+ * @param {ArrayLike<number>} options.resolution the surface's pixels, x and y
46
+ * @param {number} [options.normal_channel] the channel that holds the normal, 0 to 3: the G-buffer's is 0
47
+ * @param {boolean} [options.two_sided] whether the surface's reader turns a normal that faces away from the eye
48
+ * to face it, as the reader of a surface seen from both sides does
36
49
  */
37
- set({ depth, normal, camera, stbn, resolution }) {
50
+ set({ depth, normal, camera, stbn, resolution, normal_channel = 0, two_sided = false }) {
38
51
  assert.isNonNegativeInteger(depth, 'depth');
39
52
  assert.isNonNegativeInteger(normal, 'normal');
40
53
  assert.defined(camera, 'camera');
41
54
  assert.defined(stbn, 'stbn');
42
55
  assert.isPositiveInteger(resolution[0], 'resolution[0]');
43
56
  assert.isPositiveInteger(resolution[1], 'resolution[1]');
57
+ assert.isNonNegativeInteger(normal_channel, 'normal_channel');
58
+ assert.lessThan(normal_channel, 4, 'normal_channel');
59
+ assert.isBoolean(two_sided, 'two_sided');
44
60
 
45
61
  this.#depth = depth;
46
62
  this.#normal = normal;
47
63
  this.#camera = camera;
48
64
  this.#stbn = stbn;
65
+ this.#normal_channel = normal_channel;
66
+ this.#two_sided = two_sided;
49
67
 
50
68
  const tiles_x = Math.ceil(resolution[0] / PROBE_WANT_TILE);
51
69
  const tiles_y = Math.ceil(resolution[1] / PROBE_WANT_TILE);
@@ -64,7 +82,7 @@ export class ProbeClipmapScreenWants {
64
82
  }
65
83
 
66
84
  /**
67
- * Declare what the wants read on the lifetime's pass.
85
+ * Declare what the wants read on the pass that encodes them.
68
86
  *
69
87
  * @param {import("../../../../../engine/graphics/render/frame_graph/FramePassBuilder.js").FramePassBuilder} pass
70
88
  * @param {Object} data the pass's data, which {@link encode} is given back
@@ -78,13 +96,19 @@ export class ProbeClipmapScreenWants {
78
96
 
79
97
  /**
80
98
  * @param {GPUCommandEncoder} encoder
81
- * @param {Object} data the lifetime pass's data
99
+ * @param {Object} data the encoding pass's data
82
100
  * @param {*} resources the frame graph's resources
83
101
  * @param {Object} clipmap what the wanting clipmap binds: `probe_levels`, `probe_wanted`,
84
102
  * `probe_wanted_bits` and its want settings as `settings`
85
103
  */
86
104
  encode(encoder, data, resources, clipmap) {
87
105
  const b = Object.assign(this.#bindings, clipmap);
106
+ const settings = Object.assign(this.#settings, clipmap.settings);
107
+
108
+ settings.normal_channel = this.#normal_channel;
109
+ settings.two_sided = this.#two_sided ? 1 : 0;
110
+
111
+ b.settings = settings;
88
112
 
89
113
  b.gBufferDepth = resources.get(data.want_depth);
90
114
  b.gBufferNormals = resources.get(data.want_normal);
@@ -1 +1 @@
1
- {"version":3,"file":"chunk_probe_clipmap.d.ts","sourceRoot":"","sources":["../../../../../../../src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap.js"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"chunk_probe_clipmap.d.ts","sourceRoot":"","sources":["../../../../../../../src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap.js"],"names":[],"mappings":"AA0EA;;;;;;GAMG;AACH,kCAFU,YAAY,CAsBG;AAEzB;;;;;GAKG;AACH,+BAFU,YAAY,CAuBA;AAEtB;;;;;;GAMG;AACH,oCAFU,wBAAwB,CAEyE;AAE3G;;;;GAIG;AACH,+CAFU,wBAAwB,CAE0G;AAE5I;;;;GAIG;AACH,0CAFU,wBAAwB,CAE+F;AAEjI;;;GAGG;AACH,yCAFU,wBAAwB,CAEwF;AAE1H;;;GAGG;AACH,2CAFU,wBAAwB,CAE+G;AAEjJ;;;GAGG;AACH,0CAFU,wBAAwB,CAEwG;AAE1I;;;GAGG;AACH,sCAFU,wBAAwB,CAEkG;AAEpI;;;;GAIG;AACH,2CAFU,wBAAwB,CAEoF;AAEtH;;;GAGG;AACH,kCAFU,wBAAwB,CAE6E;AAE/G;;;;;GAKG;AACH,oCAFU,YAAY,CAKK;AAE3B;;;GAGG;AACH,2CAFU,wBAAwB,CAE0F;AAE5H;;;GAGG;AACH,4CAFU,wBAAwB,CAEiG;AAEnI;;;GAGG;AACH,yCAFU,wBAAwB,CAEgG;AAElI;;;GAGG;AACH,0CAFU,wBAAwB,CAEyG;AAE3I;;;GAGG;AACH,4CAFU,wBAAwB,CAEoG;AAEtI;;;GAGG;AACH,yCAFU,wBAAwB,CAEwG;AAE1I;;;GAGG;AACH,yCAFU,wBAAwB,CAEiG;AAEnI;;;GAGG;AACH,wCAFU,wBAAwB,CAEyF;AAE3H;;;;GAIG;AACH,yCAFU,wBAAwB,CAEgG;AAElI;;;GAGG;AACH,0CAFU,wBAAwB,CAEmG;AAErI;;;GAGG;AACH,yCAFU,wBAAwB,CAE2F;AAE7H;;;GAGG;AACH,sCAFU,wBAAwB,CAEqF;AAEvH;;;;GAIG;AACH,2CAFU,wBAAwB,CAEiG;AAEnI;;;GAGG;AACH,0CAFU,wBAAwB,CAE0F;AAE5H;;;GAGG;AACH,wCAFU,wBAAwB,CAEsG;AAExI;;;GAGG;AACH,uCAFU,wBAAwB,CAE+F;AAEjI;;;;;GAKG;AACH,8CAFU,wBAAwB,CAE0G;AAE5I;;;;GAIG;AACH,gDAFU,wBAAwB,CAE8G;AAEhJ;;;GAGG;AACH,iDAFU,wBAAwB,CAE2G;AAE7I;;;GAGG;AACH,mDAFU,wBAAwB,CAE+G;AAEjJ;;;;;GAKG;AACH,4CAFU,wBAAwB,CAEsG;AAExI;;;GAGG;AACH,2CAFU,wBAAwB,CAE+F;AAEjI;;;;;GAKG;AACH,mCAFU,YAAY,CAWI;AAE1B;;;GAGG;AACH,4CAFU,wBAAwB,CAEkH;AAEpJ;;;GAGG;AACH,2CAFU,wBAAwB,CAE2G;AAE7I;;;;GAIG;AACH,wCAFU,wBAAwB,CAEmF;AAErH;;;GAGG;AACH,uCAFU,wBAAwB,CAE4E;AAE9G;;;;;;GAMG;AACH,wCAFU,wBAAwB,CAEiG;AAEnI;;;GAGG;AACH,6CAFU,wBAAwB,CAEgG;AAElI;;;;;GAKG;AACH,6CAFU,wBAAwB,CAEqG;AAEvI;;;GAGG;AACH,4CAFU,wBAAwB,CAE8F;AAEhI;;;;GAIG;AACH,2CAFU,wBAAwB,CAEwG;AAE1I;;;;GAIG;AACH,0CAFU,wBAAwB,CAEuF;AAEzH;;;GAGG;AACH,yCAFU,wBAAwB,CAEgF;AAElH;;;GAGG;AACH,qCAFU,YAAY,CAOD;AAErB;;;GAGG;AACH,8CAFU,wBAAwB,CAEwH;AAE1J;;;GAGG;AACH,6CAFU,wBAAwB,CAEiH;AAEnJ;;;GAGG;AACH,0CAFU,YAAY,CAcU;AAEhC;;;GAGG;AACH,8CAFU,wBAAwB,CAE6H;AAE/J;;;GAGG;AACH,6CAFU,wBAAwB,CAEsH;AAExJ;;;;GAIG;AACH,8CAFU,wBAAwB,CAE+E;AAEjH;;;;GAIG;AACH,2CAFU,wBAAwB,CAEyE;AAE3G;;;GAGG;AACH,4CAFU,wBAAwB,CAEwG;AAE1I;;;GAGG;AACH,yCAFU,wBAAwB,CAEgG;AAElI;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,kCAFU,SAAS,CAiIhB;AAEH;;;;;;;;;;GAUG;AACH,6CAFU,SAAS,CA8BhB;AAIH;;;;;;;;;;;;;;;;;GAiBG;AACH,4CAFU,SAAS,CA+BhB;AAEH;;;;;;;;;;;;;;GAcG;AACH,4CAFU,SAAS,CAehB;AAEH;;;;;;;;;;;;;;GAcG;AACH,6CAFU,SAAS,CAahB;AAEH;;;;;;;;;;;;GAYG;AACH,6CAFU,SAAS,CAehB;AAEH;;;GAGG;AACH,yCAFU,wBAAwB,CAEqF;AAEvH;;;GAGG;AACH,wCAFU,wBAAwB,CAE8E;AAEhH;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AACH,wCAFU,SAAS,CAwDhB;AAEH;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,4CAFU,SAAS,CA6BhB;AAEH;;;;;;;;;GASG;AACH,iDAFU,SAAS,CAahB;AAIH;;;;;;;;;;GAUG;AACH,yCAFU,SAAS,CAgBhB;6BAngC0B,sCAAsC;yCAZ1B,sDAAsD;0BADrE,uCAAuC"}
@@ -1,3 +1,4 @@
1
+ import { chunk_age_eviction } from "../../../gpu_primitive/age_eviction/chunk_age_eviction.js";
1
2
  import { COLLECTION_U32_STRUCT_READ } from "../../../gpu_primitive/COLLECTION_U32_STRUCT_READ.js";
2
3
  import { COLLECTION_U32_STRUCT_WRITE } from "../../../gpu_primitive/COLLECTION_U32_STRUCT_WRITE.js";
3
4
  import { chunk_clipmap_key } from "../../../shader/chunk/clipmap/chunk_clipmap_key.js";
@@ -616,7 +617,7 @@ fn probe_state(kind: u32, updates: u32) -> u32 {
616
617
  }
617
618
 
618
619
  fn probe_clipmap_age_bucket(age: u32) -> u32 {
619
- return min(32u - countLeadingZeros(age), PROBE_AGE_BUCKETS - 1u);
620
+ return age_eviction_bucket(age);
620
621
  }
621
622
 
622
623
  fn probe_record_flags(back_face: f32, cascade: u32) -> u32 {
@@ -661,6 +662,7 @@ fn probe_clipmap_offset_decode(word: u32, spacing: f32) -> vec3<f32> {
661
662
  return vec3<f32>(steps) * (${PROBE_RELOCATION_LIMIT} * spacing / 511.0);
662
663
  }
663
664
  `, [
665
+ chunk_age_eviction,
664
666
  PROBE_RECORD_STRUCT.declaration_chunk,
665
667
  chunk_brick4_sh3_color_pack,
666
668
  chunk_brick4_sh3_color_unpack,
@@ -0,0 +1,40 @@
1
+ /**
2
+ * The cages a reader anywhere inside a world box can read (PROBE_CLIPMAP_PROPOSAL_2026_10_27.md §8.3, §9.1), for
3
+ * a want that knows its readers by their bounds alone: a meshlet's, whose fragments pick probes.
4
+ *
5
+ * ```wgsl
6
+ * struct ProbeClipmapBoxCages { first: vec3<i32>, dims: vec3<u32> }
7
+ * fn probe_clipmap_box_cascades(box_min: vec3<f32>, box_max: vec3<f32>, cascade_count: u32, anchor: vec3<f32>, select_half: f32) -> vec2<u32>
8
+ * fn probe_clipmap_box_cages(box_min: vec3<f32>, box_max: vec3<f32>, cascade: u32, anchor: vec3<f32>, select_half: f32) -> ProbeClipmapBoxCages
9
+ * fn probe_clipmap_box_cage_count(box_min: vec3<f32>, box_max: vec3<f32>, cascade_count: u32, anchor: vec3<f32>, select_half: f32) -> u32
10
+ * fn probe_clipmap_cage_is_read(cascade: u32, cage: vec3<i32>, anchor: vec3<f32>, select_half: f32) -> bool
11
+ * fn probe_clipmap_cage_meets_box(cascade: u32, cage: vec3<i32>, local_min: vec3<f32>, local_max: vec3<f32>, transform: mat4x4<f32>) -> bool
12
+ * ```
13
+ *
14
+ * A reader at p reads the cage of p moved by at most {@link PROBE_RECEIVER_BIAS} of a spacing, in the cascade
15
+ * `probe_clipmap_select_in` answers for p and, in its blend skirt, in the next. So over a box:
16
+ *
17
+ * - `probe_clipmap_box_cascades`: the cascades its points can read, the first and one past the last, equal
18
+ * where the box lies outside every selection box. From the cascade its point nearest the anchor selects to
19
+ * the one its farthest does, and one more where the farthest lies in that one's skirt.
20
+ * - `probe_clipmap_box_cages`: in one of those, the block of cages such a reader can read: those of the box's
21
+ * part inside the cascade's selection box, grown by the bias, and kept to the cascade's cage window. `dims`
22
+ * holds a zero where there is none.
23
+ * - `probe_clipmap_box_cage_count`: the cages of every block.
24
+ *
25
+ * The blocks are a superset of what any surface inside the box reads. Two tests a thread a cage can afford
26
+ * narrow them, each still a superset:
27
+ *
28
+ * - `probe_clipmap_cage_is_read`: whether a point within the bias of the cage selects its cascade, or the
29
+ * finer one in its skirt; a block holds cages no point reads where its box crosses a selection box's face.
30
+ * - `probe_clipmap_cage_meets_box`: whether the cage, grown by the bias, meets the box as it lies in its own
31
+ * space, by its three axes: a flat box turned away from the world's axes fills its world box with cages
32
+ * it never crosses.
33
+ *
34
+ * Reads `probe_levels`.
35
+ *
36
+ * @type {CodeChunk}
37
+ */
38
+ export const chunk_probe_clipmap_box_cages: CodeChunk;
39
+ import { CodeChunk } from "../../../shader/compiler/CodeChunk.js";
40
+ //# sourceMappingURL=chunk_probe_clipmap_box_cages.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chunk_probe_clipmap_box_cages.d.ts","sourceRoot":"","sources":["../../../../../../../src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap_box_cages.js"],"names":[],"mappings":"AAKA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;AACH,4CAFU,SAAS,CAmIZ;0BA1KmB,uCAAuC"}