@woosh/meep-engine 3.64.0 → 3.65.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 (370) 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/graphics/texture/sampler/exr_to_sampler2d.d.ts +27 -0
  29. package/src/engine/graphics/texture/sampler/exr_to_sampler2d.d.ts.map +1 -0
  30. package/src/engine/graphics/texture/sampler/exr_to_sampler2d.js +91 -0
  31. package/src/engine/graphics/texture/sampler/sampler2d_to_exr.d.ts +23 -0
  32. package/src/engine/graphics/texture/sampler/sampler2d_to_exr.d.ts.map +1 -0
  33. package/src/engine/graphics/texture/sampler/sampler2d_to_exr.js +64 -0
  34. package/src/engine/graphics3/GrassSurfaceSystem.d.ts +153 -0
  35. package/src/engine/graphics3/GrassSurfaceSystem.d.ts.map +1 -0
  36. package/src/engine/graphics3/GrassSurfaceSystem.js +1076 -0
  37. package/src/engine/graphics3/GroundCoverSystem.d.ts +33 -0
  38. package/src/engine/graphics3/GroundCoverSystem.d.ts.map +1 -0
  39. package/src/engine/graphics3/GroundCoverSystem.js +58 -0
  40. package/src/engine/network/NetworkSession.d.ts.map +1 -1
  41. package/src/engine/network/NetworkSession.js +372 -110
  42. package/src/engine/network/orchestrator/NetworkPeer.d.ts.map +1 -1
  43. package/src/engine/network/orchestrator/NetworkPeer.js +6 -1
  44. package/src/engine/network/orchestrator/ServerAuthoritativeClient.d.ts.map +1 -1
  45. package/src/engine/network/orchestrator/ServerAuthoritativeClient.js +9 -2
  46. package/src/engine/network/orchestrator/ServerAuthoritativeServer.d.ts.map +1 -1
  47. package/src/engine/network/orchestrator/ServerAuthoritativeServer.js +325 -140
  48. package/src/engine/network/sim/SimActionExecutor.d.ts +4 -1
  49. package/src/engine/network/sim/SimActionExecutor.d.ts.map +1 -1
  50. package/src/engine/network/sim/SimActionExecutor.js +65 -9
  51. package/src/engine/network/state/PredictionHistory.d.ts.map +1 -1
  52. package/src/engine/network/state/PredictionHistory.js +6 -1
  53. package/src/engine/network/time/AdaptiveRenderDelay.d.ts +25 -14
  54. package/src/engine/network/time/AdaptiveRenderDelay.d.ts.map +1 -1
  55. package/src/engine/network/time/AdaptiveRenderDelay.js +38 -20
  56. package/src/engine/network/time/RenderPlayout.d.ts +23 -3
  57. package/src/engine/network/time/RenderPlayout.d.ts.map +1 -1
  58. package/src/engine/network/time/RenderPlayout.js +40 -4
  59. package/src/engine/physics/fluid/ecs/FluidObstacleSystem.d.ts +4 -4
  60. package/src/engine/physics/fluid/obstacle/chunk_fluid_obstacle_record.d.ts +5 -1
  61. package/src/engine/physics/fluid/obstacle/chunk_fluid_obstacle_record.d.ts.map +1 -1
  62. package/src/engine/physics/fluid/obstacle/chunk_fluid_obstacle_record.js +27 -1
  63. package/src/format/image/exr/ExrCompression.d.ts +22 -0
  64. package/src/format/image/exr/ExrCompression.d.ts.map +1 -0
  65. package/src/format/image/exr/ExrCompression.js +27 -0
  66. package/src/format/image/exr/ExrImage.d.ts +32 -0
  67. package/src/format/image/exr/ExrImage.d.ts.map +1 -0
  68. package/src/format/image/exr/ExrImage.js +32 -0
  69. package/src/format/image/exr/ExrPixelType.d.ts +13 -0
  70. package/src/format/image/exr/ExrPixelType.d.ts.map +1 -0
  71. package/src/format/image/exr/ExrPixelType.js +18 -0
  72. package/src/format/image/exr/exr_compare_names.d.ts +16 -0
  73. package/src/format/image/exr/exr_compare_names.d.ts.map +1 -0
  74. package/src/format/image/exr/exr_compare_names.js +25 -0
  75. package/src/format/image/exr/exr_constants.d.ts +49 -0
  76. package/src/format/image/exr/exr_constants.d.ts.map +1 -0
  77. package/src/format/image/exr/exr_constants.js +56 -0
  78. package/src/format/image/exr/exr_read.d.ts +32 -0
  79. package/src/format/image/exr/exr_read.d.ts.map +1 -0
  80. package/src/format/image/exr/exr_read.js +531 -0
  81. package/src/format/image/exr/exr_sample_bits.d.ts +16 -0
  82. package/src/format/image/exr/exr_sample_bits.d.ts.map +1 -0
  83. package/src/format/image/exr/exr_sample_bits.js +21 -0
  84. package/src/format/image/exr/exr_scanlines_per_chunk.d.ts +17 -0
  85. package/src/format/image/exr/exr_scanlines_per_chunk.d.ts.map +1 -0
  86. package/src/format/image/exr/exr_scanlines_per_chunk.js +31 -0
  87. package/src/format/image/exr/exr_write.d.ts +27 -0
  88. package/src/format/image/exr/exr_write.d.ts.map +1 -0
  89. package/src/format/image/exr/exr_write.js +378 -0
  90. package/src/shade/device/shader/ShaderModuleCompiler.d.ts +2 -0
  91. package/src/shade/device/shader/ShaderModuleCompiler.d.ts.map +1 -1
  92. package/src/shade/device/shader/ShaderModuleCompiler.js +25 -2
  93. package/src/shade/playground/grass_surfaces/index.html +75 -0
  94. package/src/shade/playground/grass_surfaces/main.d.ts +2 -0
  95. package/src/shade/playground/grass_surfaces/main.d.ts.map +1 -0
  96. package/src/shade/playground/grass_surfaces/main.js +593 -0
  97. package/src/shade/playground/grass_surfaces/read_grass_surfaces.d.ts +62 -0
  98. package/src/shade/playground/grass_surfaces/read_grass_surfaces.d.ts.map +1 -0
  99. package/src/shade/playground/grass_surfaces/read_grass_surfaces.js +188 -0
  100. package/src/shade/playground/probe_clipmap/index.html +5 -0
  101. package/src/shade/playground/probe_clipmap/main.d.ts.map +1 -1
  102. package/src/shade/playground/probe_clipmap/main.js +34 -1
  103. package/src/shade/playground/probe_clipmap_box/README.md +5 -1
  104. package/src/shade/playground/probe_clipmap_box/index.html +12 -0
  105. package/src/shade/playground/probe_clipmap_box/main.d.ts.map +1 -1
  106. package/src/shade/playground/probe_clipmap_box/main.js +15 -0
  107. package/src/shade/playground/probe_clipmap_box/scene.d.ts +8 -1
  108. package/src/shade/playground/probe_clipmap_box/scene.d.ts.map +1 -1
  109. package/src/shade/playground/probe_clipmap_box/scene.js +74 -6
  110. package/src/shade/renderer/Renderer.d.ts.map +1 -1
  111. package/src/shade/renderer/Renderer.js +47 -43
  112. package/src/shade/renderer/extension/ViewTextures.d.ts +12 -5
  113. package/src/shade/renderer/extension/ViewTextures.d.ts.map +1 -1
  114. package/src/shade/renderer/extension/ViewTextures.js +19 -5
  115. package/src/shade/renderer/fluid/GPUFluidCascadeStack.d.ts +3 -1
  116. package/src/shade/renderer/fluid/GPUFluidCascadeStack.d.ts.map +1 -1
  117. package/src/shade/renderer/fluid/GPUFluidCascadeStack.js +6 -1
  118. package/src/shade/renderer/fluid/forcing/GPUFluidForcing.d.ts +7 -0
  119. package/src/shade/renderer/fluid/forcing/GPUFluidForcing.d.ts.map +1 -1
  120. package/src/shade/renderer/fluid/forcing/GPUFluidForcing.js +10 -0
  121. package/src/shade/renderer/geometry/sdf/GPUGeometrySDFManager.d.ts +7 -1
  122. package/src/shade/renderer/geometry/sdf/GPUGeometrySDFManager.d.ts.map +1 -1
  123. package/src/shade/renderer/geometry/sdf/GPUGeometrySDFManager.js +46 -15
  124. package/src/shade/renderer/geometry/sdf/bundle/ModelCacheBundle.d.ts +3 -2
  125. package/src/shade/renderer/geometry/sdf/bundle/ModelCacheBundle.d.ts.map +1 -1
  126. package/src/shade/renderer/geometry/sdf/bundle/ModelCacheBundle.js +3 -2
  127. package/src/shade/renderer/geometry/sdf/bundle/model_cache_bundle_sort_morton.d.ts +22 -0
  128. package/src/shade/renderer/geometry/sdf/bundle/model_cache_bundle_sort_morton.d.ts.map +1 -0
  129. package/src/shade/renderer/geometry/sdf/bundle/model_cache_bundle_sort_morton.js +247 -0
  130. package/src/shade/renderer/global_illumination/probe_clipmap/GPUProbeClipmapGI.d.ts +50 -0
  131. package/src/shade/renderer/global_illumination/probe_clipmap/GPUProbeClipmapGI.d.ts.map +1 -1
  132. package/src/shade/renderer/global_illumination/probe_clipmap/GPUProbeClipmapGI.js +101 -0
  133. package/src/shade/renderer/global_illumination/probe_clipmap/ProbeClipmapSettings.d.ts +2 -1
  134. package/src/shade/renderer/global_illumination/probe_clipmap/ProbeClipmapSettings.d.ts.map +1 -1
  135. package/src/shade/renderer/global_illumination/probe_clipmap/ProbeClipmapSettings.js +2 -1
  136. package/src/shade/renderer/global_illumination/probe_clipmap/brick/GPUBrickClipmap.d.ts +8 -0
  137. package/src/shade/renderer/global_illumination/probe_clipmap/brick/GPUBrickClipmap.d.ts.map +1 -1
  138. package/src/shade/renderer/global_illumination/probe_clipmap/brick/GPUBrickClipmap.js +12 -0
  139. package/src/shade/renderer/global_illumination/probe_clipmap/brick/chunk_brick_clipmap_trace.d.ts +12 -6
  140. package/src/shade/renderer/global_illumination/probe_clipmap/brick/chunk_brick_clipmap_trace.d.ts.map +1 -1
  141. package/src/shade/renderer/global_illumination/probe_clipmap/brick/chunk_brick_clipmap_trace.js +35 -29
  142. package/src/shade/renderer/global_illumination/probe_clipmap/debug/graph_probe_clipmap_debug_brick_clipmap.d.ts.map +1 -1
  143. package/src/shade/renderer/global_illumination/probe_clipmap/debug/graph_probe_clipmap_debug_brick_clipmap.js +4 -2
  144. package/src/shade/renderer/global_illumination/probe_clipmap/debug/graph_probe_clipmap_debug_brick_material.d.ts.map +1 -1
  145. package/src/shade/renderer/global_illumination/probe_clipmap/debug/graph_probe_clipmap_debug_brick_material.js +6 -4
  146. package/src/shade/renderer/global_illumination/probe_clipmap/material/GPUBrickMaterial.d.ts.map +1 -1
  147. package/src/shade/renderer/global_illumination/probe_clipmap/material/GPUBrickMaterial.js +2 -1
  148. package/src/shade/renderer/global_illumination/probe_clipmap/material/chunk_brick_material.d.ts +6 -5
  149. package/src/shade/renderer/global_illumination/probe_clipmap/material/chunk_brick_material.d.ts.map +1 -1
  150. package/src/shade/renderer/global_illumination/probe_clipmap/material/chunk_brick_material.js +15 -14
  151. package/src/shade/renderer/global_illumination/probe_clipmap/material/shader_brick_material_gather.d.ts.map +1 -1
  152. package/src/shade/renderer/global_illumination/probe_clipmap/material/shader_brick_material_gather.js +4 -2
  153. package/src/shade/renderer/global_illumination/probe_clipmap/probe/GPUProbeClipmap.d.ts +19 -2
  154. package/src/shade/renderer/global_illumination/probe_clipmap/probe/GPUProbeClipmap.d.ts.map +1 -1
  155. package/src/shade/renderer/global_illumination/probe_clipmap/probe/GPUProbeClipmap.js +128 -10
  156. package/src/shade/renderer/global_illumination/probe_clipmap/probe/PROBE_CLIPMAP.d.ts +19 -13
  157. package/src/shade/renderer/global_illumination/probe_clipmap/probe/PROBE_CLIPMAP.d.ts.map +1 -1
  158. package/src/shade/renderer/global_illumination/probe_clipmap/probe/PROBE_CLIPMAP.js +27 -15
  159. package/src/shade/renderer/global_illumination/probe_clipmap/probe/ProbeClipmapScreenWants.d.ts +19 -11
  160. package/src/shade/renderer/global_illumination/probe_clipmap/probe/ProbeClipmapScreenWants.d.ts.map +1 -1
  161. package/src/shade/renderer/global_illumination/probe_clipmap/probe/ProbeClipmapScreenWants.js +35 -11
  162. package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap.d.ts +3 -3
  163. package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap.d.ts.map +1 -1
  164. package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap.js +18 -14
  165. package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap_box_cages.d.ts +40 -0
  166. package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap_box_cages.d.ts.map +1 -0
  167. package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap_box_cages.js +174 -0
  168. package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap_hit_material.d.ts +4 -4
  169. package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap_hit_material.js +10 -10
  170. package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap_parallax.d.ts +31 -0
  171. package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap_parallax.d.ts.map +1 -0
  172. package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap_parallax.js +54 -0
  173. package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap_sample_radiance.d.ts +8 -4
  174. package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap_sample_radiance.d.ts.map +1 -1
  175. package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap_sample_radiance.js +10 -21
  176. package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap_want.d.ts +7 -2
  177. package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap_want.d.ts.map +1 -1
  178. package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap_want.js +33 -29
  179. package/src/shade/renderer/global_illumination/probe_clipmap/probe/graph_probe_clipmap_want_meshlets.d.ts +28 -0
  180. package/src/shade/renderer/global_illumination/probe_clipmap/probe/graph_probe_clipmap_want_meshlets.d.ts.map +1 -0
  181. package/src/shade/renderer/global_illumination/probe_clipmap/probe/graph_probe_clipmap_want_meshlets.js +138 -0
  182. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_accumulate.d.ts +7 -3
  183. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_accumulate.d.ts.map +1 -1
  184. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_accumulate.js +28 -17
  185. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_due.d.ts +13 -9
  186. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_due.d.ts.map +1 -1
  187. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_due.js +18 -11
  188. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_light.js +1 -1
  189. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_project.d.ts +18 -18
  190. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_project.d.ts.map +1 -1
  191. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_project.js +44 -48
  192. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_relocate.d.ts.map +1 -1
  193. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_relocate.js +4 -2
  194. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_retire.d.ts.map +1 -1
  195. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_retire.js +2 -3
  196. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_schedule.d.ts +5 -3
  197. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_schedule.d.ts.map +1 -1
  198. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_schedule.js +15 -30
  199. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_shade.js +1 -1
  200. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_trace.d.ts.map +1 -1
  201. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_trace.js +4 -2
  202. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_want.d.ts +11 -0
  203. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_want.d.ts.map +1 -1
  204. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_want.js +29 -2
  205. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_want_late.d.ts +40 -0
  206. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_want_late.d.ts.map +1 -0
  207. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_want_late.js +126 -0
  208. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_want_meshlets.d.ts +36 -0
  209. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_want_meshlets.d.ts.map +1 -0
  210. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_want_meshlets.js +221 -0
  211. package/src/shade/renderer/gpu_primitive/age_eviction/chunk_age_eviction.d.ts +40 -0
  212. package/src/shade/renderer/gpu_primitive/age_eviction/chunk_age_eviction.d.ts.map +1 -0
  213. package/src/shade/renderer/gpu_primitive/age_eviction/chunk_age_eviction.js +86 -0
  214. package/src/shade/renderer/grass/blade/GPUGrassBlades.d.ts +135 -0
  215. package/src/shade/renderer/grass/blade/GPUGrassBlades.d.ts.map +1 -0
  216. package/src/shade/renderer/grass/blade/GPUGrassBlades.js +676 -0
  217. package/src/shade/renderer/grass/blade/GRASS_BLADE.d.ts +145 -0
  218. package/src/shade/renderer/grass/blade/GRASS_BLADE.d.ts.map +1 -0
  219. package/src/shade/renderer/grass/blade/GRASS_BLADE.js +179 -0
  220. package/src/shade/renderer/grass/blade/chunk_grass_blade.d.ts +63 -0
  221. package/src/shade/renderer/grass/blade/chunk_grass_blade.d.ts.map +1 -0
  222. package/src/shade/renderer/grass/blade/chunk_grass_blade.js +244 -0
  223. package/src/shade/renderer/grass/blade/chunk_grass_blade_wind.d.ts +58 -0
  224. package/src/shade/renderer/grass/blade/chunk_grass_blade_wind.d.ts.map +1 -0
  225. package/src/shade/renderer/grass/blade/chunk_grass_blade_wind.js +174 -0
  226. package/src/shade/renderer/grass/blade/grass_blade_id_draw.d.ts +25 -0
  227. package/src/shade/renderer/grass/blade/grass_blade_id_draw.d.ts.map +1 -0
  228. package/src/shade/renderer/grass/blade/grass_blade_id_draw.js +133 -0
  229. package/src/shade/renderer/grass/blade/grass_blade_mechanics.d.ts +80 -0
  230. package/src/shade/renderer/grass/blade/grass_blade_mechanics.d.ts.map +1 -0
  231. package/src/shade/renderer/grass/blade/grass_blade_mechanics.js +92 -0
  232. package/src/shade/renderer/grass/blade/grass_blade_resolve.d.ts +29 -0
  233. package/src/shade/renderer/grass/blade/grass_blade_resolve.d.ts.map +1 -0
  234. package/src/shade/renderer/grass/blade/grass_blade_resolve.js +175 -0
  235. package/src/shade/renderer/grass/blade/shader_grass_blade_draw_args.d.ts +14 -0
  236. package/src/shade/renderer/grass/blade/shader_grass_blade_draw_args.d.ts.map +1 -0
  237. package/src/shade/renderer/grass/blade/shader_grass_blade_draw_args.js +45 -0
  238. package/src/shade/renderer/grass/blade/shader_grass_blade_expand.d.ts +61 -0
  239. package/src/shade/renderer/grass/blade/shader_grass_blade_expand.d.ts.map +1 -0
  240. package/src/shade/renderer/grass/blade/shader_grass_blade_expand.js +340 -0
  241. package/src/shade/renderer/grass/blade/shader_grass_cell_count.d.ts +46 -0
  242. package/src/shade/renderer/grass/blade/shader_grass_cell_count.d.ts.map +1 -0
  243. package/src/shade/renderer/grass/blade/shader_grass_cell_count.js +280 -0
  244. package/src/shade/renderer/grass/population/chunk_grass_population.d.ts +60 -0
  245. package/src/shade/renderer/grass/population/chunk_grass_population.d.ts.map +1 -0
  246. package/src/shade/renderer/grass/population/chunk_grass_population.js +171 -0
  247. package/src/shade/renderer/grass/press/GPUGrassPress.d.ts +99 -0
  248. package/src/shade/renderer/grass/press/GPUGrassPress.d.ts.map +1 -0
  249. package/src/shade/renderer/grass/press/GPUGrassPress.js +436 -0
  250. package/src/shade/renderer/grass/press/GRASS_PRESS.d.ts +179 -0
  251. package/src/shade/renderer/grass/press/GRASS_PRESS.d.ts.map +1 -0
  252. package/src/shade/renderer/grass/press/GRASS_PRESS.js +217 -0
  253. package/src/shade/renderer/grass/press/chunk_grass_press.d.ts +65 -0
  254. package/src/shade/renderer/grass/press/chunk_grass_press.d.ts.map +1 -0
  255. package/src/shade/renderer/grass/press/chunk_grass_press.js +296 -0
  256. package/src/shade/renderer/grass/press/shader_grass_press_mark.d.ts +31 -0
  257. package/src/shade/renderer/grass/press/shader_grass_press_mark.d.ts.map +1 -0
  258. package/src/shade/renderer/grass/press/shader_grass_press_mark.js +169 -0
  259. package/src/shade/renderer/grass/press/shader_grass_press_stamp.d.ts +27 -0
  260. package/src/shade/renderer/grass/press/shader_grass_press_stamp.d.ts.map +1 -0
  261. package/src/shade/renderer/grass/press/shader_grass_press_stamp.js +183 -0
  262. package/src/shade/renderer/grass/surface/GPUGrassSurfaces.d.ts +193 -0
  263. package/src/shade/renderer/grass/surface/GPUGrassSurfaces.d.ts.map +1 -0
  264. package/src/shade/renderer/grass/surface/GPUGrassSurfaces.js +1253 -0
  265. package/src/shade/renderer/grass/surface/GRASS_SURFACE.d.ts +211 -0
  266. package/src/shade/renderer/grass/surface/GRASS_SURFACE.d.ts.map +1 -0
  267. package/src/shade/renderer/grass/surface/GRASS_SURFACE.js +241 -0
  268. package/src/shade/renderer/grass/surface/GRASS_SURFACE_VIEW.d.ts +82 -0
  269. package/src/shade/renderer/grass/surface/GRASS_SURFACE_VIEW.d.ts.map +1 -0
  270. package/src/shade/renderer/grass/surface/GRASS_SURFACE_VIEW.js +111 -0
  271. package/src/shade/renderer/grass/surface/chunk_grass_column_cross.d.ts +39 -0
  272. package/src/shade/renderer/grass/surface/chunk_grass_column_cross.d.ts.map +1 -0
  273. package/src/shade/renderer/grass/surface/chunk_grass_column_cross.js +85 -0
  274. package/src/shade/renderer/grass/surface/chunk_grass_directory.d.ts +29 -0
  275. package/src/shade/renderer/grass/surface/chunk_grass_directory.d.ts.map +1 -0
  276. package/src/shade/renderer/grass/surface/chunk_grass_directory.js +112 -0
  277. package/src/shade/renderer/grass/surface/chunk_grass_slot.d.ts +27 -0
  278. package/src/shade/renderer/grass/surface/chunk_grass_slot.d.ts.map +1 -0
  279. package/src/shade/renderer/grass/surface/chunk_grass_slot.js +50 -0
  280. package/src/shade/renderer/grass/surface/chunk_grass_surface_frame.d.ts +21 -0
  281. package/src/shade/renderer/grass/surface/chunk_grass_surface_frame.d.ts.map +1 -0
  282. package/src/shade/renderer/grass/surface/chunk_grass_surface_frame.js +41 -0
  283. package/src/shade/renderer/grass/surface/chunk_grass_surface_window.d.ts +32 -0
  284. package/src/shade/renderer/grass/surface/chunk_grass_surface_window.d.ts.map +1 -0
  285. package/src/shade/renderer/grass/surface/chunk_grass_surface_window.js +136 -0
  286. package/src/shade/renderer/grass/surface/chunk_grass_surfel.d.ts +37 -0
  287. package/src/shade/renderer/grass/surface/chunk_grass_surfel.d.ts.map +1 -0
  288. package/src/shade/renderer/grass/surface/chunk_grass_surfel.js +85 -0
  289. package/src/shade/renderer/grass/surface/chunk_grass_tile.d.ts +25 -0
  290. package/src/shade/renderer/grass/surface/chunk_grass_tile.d.ts.map +1 -0
  291. package/src/shade/renderer/grass/surface/chunk_grass_tile.js +52 -0
  292. package/src/shade/renderer/grass/surface/shader_grass_directory_fill.d.ts +23 -0
  293. package/src/shade/renderer/grass/surface/shader_grass_directory_fill.d.ts.map +1 -0
  294. package/src/shade/renderer/grass/surface/shader_grass_directory_fill.js +87 -0
  295. package/src/shade/renderer/grass/surface/shader_grass_surface_bake.d.ts +43 -0
  296. package/src/shade/renderer/grass/surface/shader_grass_surface_bake.d.ts.map +1 -0
  297. package/src/shade/renderer/grass/surface/shader_grass_surface_bake.js +265 -0
  298. package/src/shade/renderer/grass/surface/shader_grass_surface_bake_command.d.ts +13 -0
  299. package/src/shade/renderer/grass/surface/shader_grass_surface_bake_command.d.ts.map +1 -0
  300. package/src/shade/renderer/grass/surface/shader_grass_surface_bake_command.js +49 -0
  301. package/src/shade/renderer/grass/surface/shader_grass_surface_invalidate.d.ts +62 -0
  302. package/src/shade/renderer/grass/surface/shader_grass_surface_invalidate.d.ts.map +1 -0
  303. package/src/shade/renderer/grass/surface/shader_grass_surface_invalidate.js +162 -0
  304. package/src/shade/renderer/grass/surface/shader_grass_surface_retire.d.ts +40 -0
  305. package/src/shade/renderer/grass/surface/shader_grass_surface_retire.d.ts.map +1 -0
  306. package/src/shade/renderer/grass/surface/shader_grass_surface_retire.js +155 -0
  307. package/src/shade/renderer/grass/surface/shader_grass_surface_schedule.d.ts +19 -0
  308. package/src/shade/renderer/grass/surface/shader_grass_surface_schedule.d.ts.map +1 -0
  309. package/src/shade/renderer/grass/surface/shader_grass_surface_schedule.js +58 -0
  310. package/src/shade/renderer/grass/surface/shader_grass_surface_want.d.ts +30 -0
  311. package/src/shade/renderer/grass/surface/shader_grass_surface_want.d.ts.map +1 -0
  312. package/src/shade/renderer/grass/surface/shader_grass_surface_want.js +251 -0
  313. package/src/shade/renderer/grass/surface/shader_grass_surface_window_count.d.ts +21 -0
  314. package/src/shade/renderer/grass/surface/shader_grass_surface_window_count.d.ts.map +1 -0
  315. package/src/shade/renderer/grass/surface/shader_grass_surface_window_count.js +75 -0
  316. package/src/shade/renderer/postprocess/velocity/graph_add_per_object_velocity.d.ts.map +1 -1
  317. package/src/shade/renderer/postprocess/velocity/graph_add_per_object_velocity.js +4 -23
  318. package/src/shade/renderer/postprocess/velocity/view_velocity_matrices.d.ts +12 -0
  319. package/src/shade/renderer/postprocess/velocity/view_velocity_matrices.d.ts.map +1 -0
  320. package/src/shade/renderer/postprocess/velocity/view_velocity_matrices.js +29 -0
  321. package/src/shade/renderer/rasterize/native/avboit/graph_rasterize_meshes_transparent_avboit.d.ts.map +1 -1
  322. package/src/shade/renderer/rasterize/native/avboit/graph_rasterize_meshes_transparent_avboit.js +22 -0
  323. package/src/shade/renderer/scene/GPUSceneContext.d.ts.map +1 -1
  324. package/src/shade/renderer/scene/GPUSceneContext.js +3 -0
  325. package/src/shade/renderer/scene/GRASS_SURFACE_PARAMS_STRUCT.d.ts +27 -0
  326. package/src/shade/renderer/scene/GRASS_SURFACE_PARAMS_STRUCT.d.ts.map +1 -0
  327. package/src/shade/renderer/scene/GRASS_SURFACE_PARAMS_STRUCT.js +38 -0
  328. package/src/shade/renderer/scene/MESH_GROUND_COVER_STRUCT.d.ts +28 -0
  329. package/src/shade/renderer/scene/MESH_GROUND_COVER_STRUCT.d.ts.map +1 -0
  330. package/src/shade/renderer/scene/MESH_GROUND_COVER_STRUCT.js +58 -0
  331. package/src/shade/renderer/scene/SCENE_DATABASE_SPEC.d.ts.map +1 -1
  332. package/src/shade/renderer/scene/SCENE_DATABASE_SPEC.js +8 -0
  333. package/src/shade/renderer/shader/chunk/filter/chunk_multiscale_mean.d.ts +8 -0
  334. package/src/shade/renderer/shader/chunk/filter/chunk_multiscale_mean.d.ts.map +1 -1
  335. package/src/shade/renderer/shader/chunk/filter/chunk_multiscale_mean.js +21 -3
  336. package/src/shade/renderer/shader/chunk/geometry/ray/chunk_ray_query_nearest_among.d.ts +37 -0
  337. package/src/shade/renderer/shader/chunk/geometry/ray/chunk_ray_query_nearest_among.d.ts.map +1 -0
  338. package/src/shade/renderer/shader/chunk/geometry/ray/chunk_ray_query_nearest_among.js +148 -0
  339. package/src/shade/renderer/shader/chunk/sdf/chunk_shape_record_line_span.d.ts +20 -0
  340. package/src/shade/renderer/shader/chunk/sdf/chunk_shape_record_line_span.d.ts.map +1 -0
  341. package/src/shade/renderer/shader/chunk/sdf/chunk_shape_record_line_span.js +169 -0
  342. package/src/shade/renderer/texture/atlas/chunk_tile_atlas_slot_origin.d.ts +18 -0
  343. package/src/shade/renderer/texture/atlas/chunk_tile_atlas_slot_origin.d.ts.map +1 -1
  344. package/src/shade/renderer/texture/atlas/chunk_tile_atlas_slot_origin.js +28 -0
  345. package/src/shade/renderer/texture/atlas/tile_atlas_slot_shift.d.ts +13 -0
  346. package/src/shade/renderer/texture/atlas/tile_atlas_slot_shift.d.ts.map +1 -0
  347. package/src/shade/renderer/texture/atlas/tile_atlas_slot_shift.js +22 -0
  348. package/src/shade/renderer/water/GPUWaterRenderer.d.ts.map +1 -1
  349. package/src/shade/renderer/water/GPUWaterRenderer.js +4 -0
  350. package/src/shade/renderer/wind/GPUSceneWind.d.ts +52 -5
  351. package/src/shade/renderer/wind/GPUSceneWind.d.ts.map +1 -1
  352. package/src/shade/renderer/wind/GPUSceneWind.js +164 -8
  353. package/src/shade/renderer/wind/WIND_FIELD_UNIFORM.d.ts +3 -1
  354. package/src/shade/renderer/wind/WIND_FIELD_UNIFORM.d.ts.map +1 -1
  355. package/src/shade/renderer/wind/WIND_FIELD_UNIFORM.js +3 -1
  356. package/src/shade/renderer/wind/chunk_wind_field_sample_cascades.d.ts +2 -1
  357. package/src/shade/renderer/wind/chunk_wind_field_sample_cascades.d.ts.map +1 -1
  358. package/src/shade/renderer/wind/chunk_wind_field_sample_cascades.js +18 -13
  359. package/src/shade/renderer/wind/chunk_wind_field_sample_previous.d.ts +13 -0
  360. package/src/shade/renderer/wind/chunk_wind_field_sample_previous.d.ts.map +1 -0
  361. package/src/shade/renderer/wind/chunk_wind_field_sample_previous.js +23 -0
  362. package/src/shade/renderer/wind/chunk_wind_field_sample_uniform.d.ts +1 -0
  363. package/src/shade/renderer/wind/chunk_wind_field_sample_uniform.d.ts.map +1 -1
  364. package/src/shade/renderer/wind/chunk_wind_field_sample_uniform.js +6 -1
  365. package/src/shade/renderer/wind/wind_field_add_resources.d.ts +11 -0
  366. package/src/shade/renderer/wind/wind_field_add_resources.d.ts.map +1 -1
  367. package/src/shade/renderer/wind/wind_field_add_resources.js +15 -0
  368. package/src/shade/wgsl/emulator/WGSLJavaScriptCompiler.js +1 -1
  369. package/src/shade/wgsl/emulator/WGSLLanguageCore.d.ts.map +1 -1
  370. package/src/shade/wgsl/emulator/WGSLLanguageCore.js +2 -0
@@ -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);
@@ -189,8 +189,8 @@ export const PROBE_RAY_SUMS_WRITE_RESOURCE: ShaderResourceDescriptor;
189
189
  */
190
190
  export const PROBE_RAY_SUMS_READ_RESOURCE: ShaderResourceDescriptor;
191
191
  /**
192
- * A slot's ray request (§8.6), as projection writes it after each update: the rays its next guided update
193
- * asks for, and what tells it the probe's light moved.
192
+ * A slot's request (§8.6, §8.8), as projection writes it after each update: what the probe's next update takes,
193
+ * by its L0 estimator, a multi-scale mean estimator over the probe's whole light (`shader_probe_clipmap_project`).
194
194
  *
195
195
  * @type {WebGPUStruct}
196
196
  */
@@ -201,7 +201,7 @@ export const PROBE_REQUEST_STRUCT: WebGPUStruct;
201
201
  */
202
202
  export const PROBE_REQUESTS_WRITE_RESOURCE: ShaderResourceDescriptor;
203
203
  /**
204
- * Each slot's ray request, as the ray counts pass reads it.
204
+ * Each slot's request, as the ray counts and accumulation read it.
205
205
  * @type {ShaderResourceDescriptor}
206
206
  */
207
207
  export const PROBE_REQUESTS_READ_RESOURCE: ShaderResourceDescriptor;
@@ -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":"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"}
@@ -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";
@@ -340,20 +341,20 @@ export const PROBE_RAY_SUMS_WRITE_RESOURCE = ShaderResourceDescriptor.storageBuf
340
341
  export const PROBE_RAY_SUMS_READ_RESOURCE = ShaderResourceDescriptor.storageBuffer("probe_ray_sums", COLLECTION_U32_STRUCT_READ);
341
342
 
342
343
  /**
343
- * A slot's ray request (§8.6), as projection writes it after each update: the rays its next guided update
344
- * asks for, and what tells it the probe's light moved.
344
+ * A slot's request (§8.6, §8.8), as projection writes it after each update: what the probe's next update takes,
345
+ * by its L0 estimator, a multi-scale mean estimator over the probe's whole light (`shader_probe_clipmap_project`).
345
346
  *
346
347
  * @type {WebGPUStruct}
347
348
  */
348
349
  export const PROBE_REQUEST_STRUCT = WebGPUStruct.from({
349
350
  /** the rays the probe's next guided update asks for */
350
351
  rays: u32,
351
- /** the running mean of the update's change score: its texels' falls from their means, each in its own deviation, summed over the root of their count */
352
- change_mean: f32,
353
- /** the running variance of the change score */
354
- change_variance: f32,
355
- /** the scores its running statistics hold, up to `PROBE_RADIANCE_SAMPLES_LIMIT` */
356
- changes: u32,
352
+ /** the least blend of every texel's long mean on the next update: the L0 estimator's catch-up */
353
+ blend: f32,
354
+ /** the L0 estimator's inconsistency, the smoothed history of its means' gap over its deviation */
355
+ inconsistency: f32,
356
+ /** the L0 estimator's blend reduction */
357
+ reduction: f32,
357
358
  }, "ProbeRequest").pack();
358
359
 
359
360
  /**
@@ -363,7 +364,7 @@ export const PROBE_REQUEST_STRUCT = WebGPUStruct.from({
363
364
  export const PROBE_REQUESTS_WRITE_RESOURCE = ShaderResourceDescriptor.storageBuffer("probe_requests", WebGPUArray.from(PROBE_REQUEST_STRUCT), true);
364
365
 
365
366
  /**
366
- * Each slot's ray request, as the ray counts pass reads it.
367
+ * Each slot's request, as the ray counts and accumulation read it.
367
368
  * @type {ShaderResourceDescriptor}
368
369
  */
369
370
  export const PROBE_REQUESTS_READ_RESOURCE = ShaderResourceDescriptor.storageBuffer("probe_requests", WebGPUArray.from(PROBE_REQUEST_STRUCT));
@@ -463,10 +464,12 @@ export const PROBE_PROJECTION_ROW_STRUCT = WebGPUStruct.from({
463
464
  resolved: u32,
464
465
  /** of them, the back faces */
465
466
  back_faces: u32,
466
- /** how far the update's samples fell from their texels' means, each in its own deviation, luminance, summed */
467
- change: f32,
468
- /** the texels that blended a sample */
469
- blended: f32,
467
+ /** the texels' short means less their means, luminance, each by its solid angle, summed: L0's gap */
468
+ gap: f32,
469
+ /** the texels' deviations squared, luminance, each by its solid angle squared, summed: L0's variance */
470
+ variance: f32,
471
+ /** the texels' short means, luminance, each by its solid angle, summed: L0's short mean */
472
+ level: f32,
470
473
  }, "ProbeProjectionRow").pack();
471
474
 
472
475
  /**
@@ -614,7 +617,7 @@ fn probe_state(kind: u32, updates: u32) -> u32 {
614
617
  }
615
618
 
616
619
  fn probe_clipmap_age_bucket(age: u32) -> u32 {
617
- return min(32u - countLeadingZeros(age), PROBE_AGE_BUCKETS - 1u);
620
+ return age_eviction_bucket(age);
618
621
  }
619
622
 
620
623
  fn probe_record_flags(back_face: f32, cascade: u32) -> u32 {
@@ -659,6 +662,7 @@ fn probe_clipmap_offset_decode(word: u32, spacing: f32) -> vec3<f32> {
659
662
  return vec3<f32>(steps) * (${PROBE_RELOCATION_LIMIT} * spacing / 511.0);
660
663
  }
661
664
  `, [
665
+ chunk_age_eviction,
662
666
  PROBE_RECORD_STRUCT.declaration_chunk,
663
667
  chunk_brick4_sh3_color_pack,
664
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"}
@@ -0,0 +1,174 @@
1
+ import { CLIPMAP_LEVEL_LIMIT, CLIPMAP_LEVEL_STRUCT } from "../../../shader/chunk/clipmap/CLIPMAP_LEVEL_STRUCT.js";
2
+ import { CodeChunk } from "../../../shader/compiler/CodeChunk.js";
3
+ import { chunk_probe_clipmap, PROBE_LEVELS_RESOURCE } from "./chunk_probe_clipmap.js";
4
+ import { PROBE_RECEIVER_BIAS } from "./PROBE_CLIPMAP.js";
5
+
6
+ /**
7
+ * The cages a reader anywhere inside a world box can read (PROBE_CLIPMAP_PROPOSAL_2026_10_27.md §8.3, §9.1), for
8
+ * a want that knows its readers by their bounds alone: a meshlet's, whose fragments pick probes.
9
+ *
10
+ * ```wgsl
11
+ * struct ProbeClipmapBoxCages { first: vec3<i32>, dims: vec3<u32> }
12
+ * fn probe_clipmap_box_cascades(box_min: vec3<f32>, box_max: vec3<f32>, cascade_count: u32, anchor: vec3<f32>, select_half: f32) -> vec2<u32>
13
+ * fn probe_clipmap_box_cages(box_min: vec3<f32>, box_max: vec3<f32>, cascade: u32, anchor: vec3<f32>, select_half: f32) -> ProbeClipmapBoxCages
14
+ * fn probe_clipmap_box_cage_count(box_min: vec3<f32>, box_max: vec3<f32>, cascade_count: u32, anchor: vec3<f32>, select_half: f32) -> u32
15
+ * fn probe_clipmap_cage_is_read(cascade: u32, cage: vec3<i32>, anchor: vec3<f32>, select_half: f32) -> bool
16
+ * fn probe_clipmap_cage_meets_box(cascade: u32, cage: vec3<i32>, local_min: vec3<f32>, local_max: vec3<f32>, transform: mat4x4<f32>) -> bool
17
+ * ```
18
+ *
19
+ * A reader at p reads the cage of p moved by at most {@link PROBE_RECEIVER_BIAS} of a spacing, in the cascade
20
+ * `probe_clipmap_select_in` answers for p and, in its blend skirt, in the next. So over a box:
21
+ *
22
+ * - `probe_clipmap_box_cascades`: the cascades its points can read, the first and one past the last, equal
23
+ * where the box lies outside every selection box. From the cascade its point nearest the anchor selects to
24
+ * the one its farthest does, and one more where the farthest lies in that one's skirt.
25
+ * - `probe_clipmap_box_cages`: in one of those, the block of cages such a reader can read: those of the box's
26
+ * part inside the cascade's selection box, grown by the bias, and kept to the cascade's cage window. `dims`
27
+ * holds a zero where there is none.
28
+ * - `probe_clipmap_box_cage_count`: the cages of every block.
29
+ *
30
+ * The blocks are a superset of what any surface inside the box reads. Two tests a thread a cage can afford
31
+ * narrow them, each still a superset:
32
+ *
33
+ * - `probe_clipmap_cage_is_read`: whether a point within the bias of the cage selects its cascade, or the
34
+ * finer one in its skirt; a block holds cages no point reads where its box crosses a selection box's face.
35
+ * - `probe_clipmap_cage_meets_box`: whether the cage, grown by the bias, meets the box as it lies in its own
36
+ * space, by its three axes: a flat box turned away from the world's axes fills its world box with cages
37
+ * it never crosses.
38
+ *
39
+ * Reads `probe_levels`.
40
+ *
41
+ * @type {CodeChunk}
42
+ */
43
+ export const chunk_probe_clipmap_box_cages = CodeChunk.from(
44
+ //language=WGSL
45
+ `
46
+ struct ProbeClipmapBoxCages {
47
+ // the least cage of the block
48
+ first: vec3<i32>,
49
+ // its cages along each axis
50
+ dims: vec3<u32>,
51
+ }
52
+
53
+ fn probe_clipmap_box_max3(v: vec3<f32>) -> f32 {
54
+ return max(max(v.x, v.y), v.z);
55
+ }
56
+
57
+ // the finest cascade whose selection box holds a point \`reach\` from the anchor along its longest axis, or the count
58
+ fn probe_clipmap_cascade_at_reach(reach: f32, cascade_count: u32, select_half: f32) -> u32 {
59
+ for (var i = 0u; i < ${CLIPMAP_LEVEL_LIMIT}u; i++) {
60
+ if (i >= cascade_count) {
61
+ break;
62
+ }
63
+
64
+ if (select_half * probe_levels[i].cell_size >= reach) {
65
+ return i;
66
+ }
67
+ }
68
+
69
+ return cascade_count;
70
+ }
71
+
72
+ fn probe_clipmap_box_cascades(box_min: vec3<f32>, box_max: vec3<f32>, cascade_count: u32, anchor: vec3<f32>, select_half: f32) -> vec2<u32> {
73
+ let reach_near = probe_clipmap_box_max3(abs(clamp(anchor, box_min, box_max) - anchor));
74
+ let reach_far = probe_clipmap_box_max3(max(abs(box_min - anchor), abs(box_max - anchor)));
75
+
76
+ let first = probe_clipmap_cascade_at_reach(reach_near, cascade_count, select_half);
77
+
78
+ if (first >= cascade_count) {
79
+ return vec2<u32>(cascade_count);
80
+ }
81
+
82
+ let last = min(probe_clipmap_cascade_at_reach(reach_far, cascade_count, select_half), cascade_count - 1u);
83
+ // past the last one's skirt line its farthest points read the next as well
84
+ let skirt = reach_far > (select_half - PROBE_BLEND_SKIRT) * probe_levels[last].cell_size;
85
+
86
+ return vec2<u32>(first, min(last + select(1u, 2u, skirt), cascade_count));
87
+ }
88
+
89
+ fn probe_clipmap_box_cages(box_min: vec3<f32>, box_max: vec3<f32>, cascade: u32, anchor: vec3<f32>, select_half: f32) -> ProbeClipmapBoxCages {
90
+ let level = probe_levels[cascade];
91
+ let cell = level.cell_size;
92
+ let bias = ${PROBE_RECEIVER_BIAS} * cell;
93
+
94
+ // the box's part whose points select this cascade or a finer one
95
+ let half = vec3<f32>(select_half * cell);
96
+ let a = max(box_min, anchor - half);
97
+ let b = min(box_max, anchor + half);
98
+
99
+ // their cages, the bias either way, inside the cage window
100
+ let first = max(vec3<i32>(floor((a - bias) / cell)), level.corner);
101
+ let last = min(vec3<i32>(floor((b + bias) / cell)), level.corner + level.size - vec3<i32>(1));
102
+
103
+ var out: ProbeClipmapBoxCages;
104
+
105
+ out.first = first;
106
+ out.dims = vec3<u32>(max(last - first + vec3<i32>(1), vec3<i32>(0)));
107
+
108
+ if (any(a > b)) {
109
+ out.dims = vec3<u32>(0u);
110
+ }
111
+
112
+ return out;
113
+ }
114
+
115
+ fn probe_clipmap_box_cage_count(box_min: vec3<f32>, box_max: vec3<f32>, cascade_count: u32, anchor: vec3<f32>, select_half: f32) -> u32 {
116
+ let cascades = probe_clipmap_box_cascades(box_min, box_max, cascade_count, anchor, select_half);
117
+
118
+ var count = 0u;
119
+
120
+ for (var i = 0u; i < ${CLIPMAP_LEVEL_LIMIT}u; i++) {
121
+ let cascade = cascades.x + i;
122
+
123
+ if (cascade >= cascades.y) {
124
+ break;
125
+ }
126
+
127
+ let cages = probe_clipmap_box_cages(box_min, box_max, cascade, anchor, select_half);
128
+
129
+ count += cages.dims.x * cages.dims.y * cages.dims.z;
130
+ }
131
+
132
+ return count;
133
+ }
134
+
135
+ fn probe_clipmap_cage_is_read(cascade: u32, cage: vec3<i32>, anchor: vec3<f32>, select_half: f32) -> bool {
136
+ let cell = probe_levels[cascade].cell_size;
137
+ // the points that read the cage lie within the bias of it
138
+ let half = (0.5 + ${PROBE_RECEIVER_BIAS}) * cell;
139
+ let from_anchor = abs((vec3<f32>(cage) + 0.5) * cell - anchor);
140
+
141
+ // one of them selects this cascade or a finer one
142
+ var read = probe_clipmap_box_max3(max(from_anchor - half, vec3<f32>(0.0))) <= select_half * cell;
143
+
144
+ if (cascade > 0u) {
145
+ // and not every one selects a finer one short of its skirt
146
+ read = read && probe_clipmap_box_max3(from_anchor + half) > (select_half - PROBE_BLEND_SKIRT) * probe_levels[cascade - 1u].cell_size;
147
+ }
148
+
149
+ return read;
150
+ }
151
+
152
+ fn probe_clipmap_cage_meets_box(cascade: u32, cage: vec3<i32>, local_min: vec3<f32>, local_max: vec3<f32>, transform: mat4x4<f32>) -> bool {
153
+ let cell = probe_levels[cascade].cell_size;
154
+ let half = (0.5 + ${PROBE_RECEIVER_BIAS}) * cell;
155
+ let local_half = 0.5 * (local_max - local_min);
156
+ let offset = (vec3<f32>(cage) + 0.5) * cell - (transform * vec4<f32>(0.5 * (local_min + local_max), 1.0)).xyz;
157
+
158
+ // each of the box's own axes by name: a dynamic index would put the matrix in local memory
159
+ let x = transform[0].xyz;
160
+ let y = transform[1].xyz;
161
+ let z = transform[2].xyz;
162
+
163
+ // along an axis, the cage's reach and the box's, against how far apart their centres are: the axis is
164
+ // left at the transform's scale, which every term carries
165
+ return abs(dot(offset, x)) <= half * (abs(x.x) + abs(x.y) + abs(x.z)) + local_half.x * dot(x, x)
166
+ && abs(dot(offset, y)) <= half * (abs(y.x) + abs(y.y) + abs(y.z)) + local_half.y * dot(y, y)
167
+ && abs(dot(offset, z)) <= half * (abs(z.x) + abs(z.y) + abs(z.z)) + local_half.z * dot(z, z);
168
+ }
169
+ `, [
170
+ chunk_probe_clipmap,
171
+ CLIPMAP_LEVEL_STRUCT.declaration_chunk,
172
+ ]);
173
+
174
+ chunk_probe_clipmap_box_cages.requireResource(PROBE_LEVELS_RESOURCE);
@@ -3,13 +3,13 @@
3
3
  *
4
4
  * ```wgsl
5
5
  * struct ProbeClipmapHitMaterial { found: bool, albedo: vec3<f32>, emissive: vec3<f32> }
6
- * fn probe_clipmap_hit_material(position: vec3<f32>, normal: vec3<f32>, cascade: u32) -> ProbeClipmapHitMaterial
6
+ * fn probe_clipmap_hit_material(position: vec3<f32>, normal: vec3<f32>, cascade: u32, atlas_shift: u32) -> ProbeClipmapHitMaterial
7
7
  * ```
8
8
  *
9
9
  * The hit is at `position` in brick cascade `cascade`, its field's normal `normal`: the brick holding it,
10
10
  * looked up in the brick map at the hit's cascade as the march found it, and its material there
11
11
  * (`brick_material_surface`), albedo and emissive. A hit whose brick carries no material for its surface
12
- * is black, `found` false.
12
+ * is black, `found` false. `atlas_shift` is the brick atlas's footprint, as `chunk_brick_clipmap_sample` takes it.
13
13
  *
14
14
  * @type {CodeChunk}
15
15
  */
@@ -18,7 +18,7 @@ export const chunk_probe_clipmap_hit_material: CodeChunk;
18
18
  * The material a probe ray's hit takes its light with, from one texel of the brick material:
19
19
  *
20
20
  * ```wgsl
21
- * fn probe_clipmap_hit_material_pick(position: vec3<f32>, normal: vec3<f32>, cascade: u32, u: f32) -> ProbeClipmapHitMaterial
21
+ * fn probe_clipmap_hit_material_pick(position: vec3<f32>, normal: vec3<f32>, cascade: u32, u: f32, atlas_shift: u32) -> ProbeClipmapHitMaterial
22
22
  * ```
23
23
  *
24
24
  * As {@link chunk_probe_clipmap_hit_material} finds the hit's brick, one of the texels its blend weighs
@@ -33,7 +33,7 @@ export const chunk_probe_clipmap_hit_material_pick: CodeChunk;
33
33
  * surface, for the debug views: the GI's light takes none of it yet.
34
34
  *
35
35
  * ```wgsl
36
- * fn probe_clipmap_hit_metal_rough(position: vec3<f32>, normal: vec3<f32>, cascade: u32) -> vec3<f32> // (metalness, roughness, 1 if found)
36
+ * fn probe_clipmap_hit_metal_rough(position: vec3<f32>, normal: vec3<f32>, cascade: u32, atlas_shift: u32) -> vec3<f32> // (metalness, roughness, 1 if found)
37
37
  * ```
38
38
  *
39
39
  * @type {CodeChunk}
@@ -48,26 +48,26 @@ brick_at.requireResource(BRICK_MAP_TEXTURE_RESOURCE);
48
48
  *
49
49
  * ```wgsl
50
50
  * struct ProbeClipmapHitMaterial { found: bool, albedo: vec3<f32>, emissive: vec3<f32> }
51
- * fn probe_clipmap_hit_material(position: vec3<f32>, normal: vec3<f32>, cascade: u32) -> ProbeClipmapHitMaterial
51
+ * fn probe_clipmap_hit_material(position: vec3<f32>, normal: vec3<f32>, cascade: u32, atlas_shift: u32) -> ProbeClipmapHitMaterial
52
52
  * ```
53
53
  *
54
54
  * The hit is at `position` in brick cascade `cascade`, its field's normal `normal`: the brick holding it,
55
55
  * looked up in the brick map at the hit's cascade as the march found it, and its material there
56
56
  * (`brick_material_surface`), albedo and emissive. A hit whose brick carries no material for its surface
57
- * is black, `found` false.
57
+ * is black, `found` false. `atlas_shift` is the brick atlas's footprint, as `chunk_brick_clipmap_sample` takes it.
58
58
  *
59
59
  * @type {CodeChunk}
60
60
  */
61
61
  export const chunk_probe_clipmap_hit_material = CodeChunk.from(
62
62
  //language=WGSL
63
63
  `
64
- fn probe_clipmap_hit_material(position: vec3<f32>, normal: vec3<f32>, cascade: u32) -> ProbeClipmapHitMaterial {
64
+ fn probe_clipmap_hit_material(position: vec3<f32>, normal: vec3<f32>, cascade: u32, atlas_shift: u32) -> ProbeClipmapHitMaterial {
65
65
  var out: ProbeClipmapHitMaterial;
66
66
 
67
67
  let brick = probe_clipmap_hit_brick(position, cascade);
68
68
 
69
69
  if (brick_clipmap_entry_holds_slot(brick.entry)) {
70
- let seen = brick_material_surface(brick.entry, brick.local, normal);
70
+ let seen = brick_material_surface(brick.entry, brick.local, normal, atlas_shift);
71
71
 
72
72
  out.found = seen.found;
73
73
  out.albedo = seen.albedo;
@@ -82,7 +82,7 @@ fn probe_clipmap_hit_material(position: vec3<f32>, normal: vec3<f32>, cascade: u
82
82
  * The material a probe ray's hit takes its light with, from one texel of the brick material:
83
83
  *
84
84
  * ```wgsl
85
- * fn probe_clipmap_hit_material_pick(position: vec3<f32>, normal: vec3<f32>, cascade: u32, u: f32) -> ProbeClipmapHitMaterial
85
+ * fn probe_clipmap_hit_material_pick(position: vec3<f32>, normal: vec3<f32>, cascade: u32, u: f32, atlas_shift: u32) -> ProbeClipmapHitMaterial
86
86
  * ```
87
87
  *
88
88
  * As {@link chunk_probe_clipmap_hit_material} finds the hit's brick, one of the texels its blend weighs
@@ -94,13 +94,13 @@ fn probe_clipmap_hit_material(position: vec3<f32>, normal: vec3<f32>, cascade: u
94
94
  export const chunk_probe_clipmap_hit_material_pick = CodeChunk.from(
95
95
  //language=WGSL
96
96
  `
97
- fn probe_clipmap_hit_material_pick(position: vec3<f32>, normal: vec3<f32>, cascade: u32, u: f32) -> ProbeClipmapHitMaterial {
97
+ fn probe_clipmap_hit_material_pick(position: vec3<f32>, normal: vec3<f32>, cascade: u32, u: f32, atlas_shift: u32) -> ProbeClipmapHitMaterial {
98
98
  var out: ProbeClipmapHitMaterial;
99
99
 
100
100
  let brick = probe_clipmap_hit_brick(position, cascade);
101
101
 
102
102
  if (brick_clipmap_entry_holds_slot(brick.entry)) {
103
- let seen = brick_material_surface_pick(brick.entry, brick.local, normal, u);
103
+ let seen = brick_material_surface_pick(brick.entry, brick.local, normal, u, atlas_shift);
104
104
 
105
105
  out.found = seen.found;
106
106
  out.albedo = seen.albedo;
@@ -116,7 +116,7 @@ fn probe_clipmap_hit_material_pick(position: vec3<f32>, normal: vec3<f32>, casca
116
116
  * surface, for the debug views: the GI's light takes none of it yet.
117
117
  *
118
118
  * ```wgsl
119
- * fn probe_clipmap_hit_metal_rough(position: vec3<f32>, normal: vec3<f32>, cascade: u32) -> vec3<f32> // (metalness, roughness, 1 if found)
119
+ * fn probe_clipmap_hit_metal_rough(position: vec3<f32>, normal: vec3<f32>, cascade: u32, atlas_shift: u32) -> vec3<f32> // (metalness, roughness, 1 if found)
120
120
  * ```
121
121
  *
122
122
  * @type {CodeChunk}
@@ -124,14 +124,14 @@ fn probe_clipmap_hit_material_pick(position: vec3<f32>, normal: vec3<f32>, casca
124
124
  export const chunk_probe_clipmap_hit_metal_rough = CodeChunk.from(
125
125
  //language=WGSL
126
126
  `
127
- fn probe_clipmap_hit_metal_rough(position: vec3<f32>, normal: vec3<f32>, cascade: u32) -> vec3<f32> {
127
+ fn probe_clipmap_hit_metal_rough(position: vec3<f32>, normal: vec3<f32>, cascade: u32, atlas_shift: u32) -> vec3<f32> {
128
128
  let brick = probe_clipmap_hit_brick(position, cascade);
129
129
 
130
130
  if (!brick_clipmap_entry_holds_slot(brick.entry)) {
131
131
  return vec3<f32>(0.0);
132
132
  }
133
133
 
134
- let seen = brick_material_metal_rough(brick.entry, brick.local, normal);
134
+ let seen = brick_material_metal_rough(brick.entry, brick.local, normal, atlas_shift);
135
135
 
136
136
  return vec3<f32>(seen.metal_rough, select(0.0, 1.0, seen.found));
137
137
  }