@woosh/meep-engine 3.59.0 → 3.60.1

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 (326) hide show
  1. package/package.json +1 -1
  2. package/src/shade/playground/probe_clipmap/index.html +12 -0
  3. package/src/shade/playground/probe_clipmap/main.d.ts.map +1 -1
  4. package/src/shade/playground/probe_clipmap/main.js +5 -0
  5. package/src/shade/renderer/Renderer.d.ts.map +1 -1
  6. package/src/shade/renderer/Renderer.js +4 -6
  7. package/src/shade/renderer/geometry/sdf/GPUGeometrySDFManager.d.ts +63 -1
  8. package/src/shade/renderer/geometry/sdf/GPUGeometrySDFManager.d.ts.map +1 -1
  9. package/src/shade/renderer/geometry/sdf/GPUGeometrySDFManager.js +228 -16
  10. package/src/shade/renderer/geometry/sdf/cards/GPUMeshCardSets.d.ts +27 -4
  11. package/src/shade/renderer/geometry/sdf/cards/GPUMeshCardSets.d.ts.map +1 -1
  12. package/src/shade/renderer/geometry/sdf/cards/GPUMeshCardSets.js +526 -23
  13. package/src/shade/renderer/geometry/sdf/cards/MeshCardCaptureMode.d.ts +11 -0
  14. package/src/shade/renderer/geometry/sdf/cards/MeshCardCaptureMode.d.ts.map +1 -0
  15. package/src/shade/renderer/geometry/sdf/cards/MeshCardCaptureMode.js +21 -0
  16. package/src/shade/renderer/geometry/sdf/cards/mesh_cards_raster_pass_descriptor.d.ts +65 -0
  17. package/src/shade/renderer/geometry/sdf/cards/mesh_cards_raster_pass_descriptor.d.ts.map +1 -0
  18. package/src/shade/renderer/geometry/sdf/cards/mesh_cards_raster_pass_descriptor.js +376 -0
  19. package/src/shade/renderer/geometry/sdf/cards/shader_mesh_cards_capture.d.ts +7 -3
  20. package/src/shade/renderer/geometry/sdf/cards/shader_mesh_cards_capture.d.ts.map +1 -1
  21. package/src/shade/renderer/geometry/sdf/cards/shader_mesh_cards_capture.js +70 -6
  22. package/src/shade/renderer/geometry/sdf/cards/shader_mesh_cards_raster_args.d.ts +20 -0
  23. package/src/shade/renderer/geometry/sdf/cards/shader_mesh_cards_raster_args.d.ts.map +1 -0
  24. package/src/shade/renderer/geometry/sdf/cards/shader_mesh_cards_raster_args.js +80 -0
  25. package/src/shade/renderer/geometry/sdf/cards/shader_mesh_cards_raster_scatter.d.ts +18 -0
  26. package/src/shade/renderer/geometry/sdf/cards/shader_mesh_cards_raster_scatter.d.ts.map +1 -0
  27. package/src/shade/renderer/geometry/sdf/cards/shader_mesh_cards_raster_scatter.js +113 -0
  28. package/src/shade/renderer/geometry/virtual/sdf/VGEO_SDF.d.ts +47 -0
  29. package/src/shade/renderer/geometry/virtual/sdf/VGEO_SDF.d.ts.map +1 -0
  30. package/src/shade/renderer/geometry/virtual/sdf/VGEO_SDF.js +80 -0
  31. package/src/shade/renderer/geometry/virtual/sdf/VGeoSDFProxies.d.ts +91 -0
  32. package/src/shade/renderer/geometry/virtual/sdf/VGeoSDFProxies.d.ts.map +1 -0
  33. package/src/shade/renderer/geometry/virtual/sdf/VGeoSDFProxies.js +902 -0
  34. package/src/shade/renderer/geometry/virtual/sdf/shader_vgeo_sdf_collect.d.ts +16 -0
  35. package/src/shade/renderer/geometry/virtual/sdf/shader_vgeo_sdf_collect.d.ts.map +1 -0
  36. package/src/shade/renderer/geometry/virtual/sdf/shader_vgeo_sdf_collect.js +67 -0
  37. package/src/shade/renderer/geometry/virtual/sdf/shader_vgeo_sdf_decode.d.ts +17 -0
  38. package/src/shade/renderer/geometry/virtual/sdf/shader_vgeo_sdf_decode.d.ts.map +1 -0
  39. package/src/shade/renderer/geometry/virtual/sdf/shader_vgeo_sdf_decode.js +145 -0
  40. package/src/shade/renderer/geometry/virtual/sdf/shader_vgeo_sdf_traverse.d.ts +12 -0
  41. package/src/shade/renderer/geometry/virtual/sdf/shader_vgeo_sdf_traverse.d.ts.map +1 -0
  42. package/src/shade/renderer/geometry/virtual/sdf/shader_vgeo_sdf_traverse.js +105 -0
  43. package/src/shade/renderer/global_illumination/probe/octahedral/shader_lpv_build_gbuffer.d.ts.map +1 -1
  44. package/src/shade/renderer/global_illumination/probe/octahedral/shader_lpv_build_gbuffer.js +2 -1
  45. package/src/shade/renderer/global_illumination/probe_clipmap/GPUProbeClipmapGI.d.ts +3 -9
  46. package/src/shade/renderer/global_illumination/probe_clipmap/GPUProbeClipmapGI.d.ts.map +1 -1
  47. package/src/shade/renderer/global_illumination/probe_clipmap/GPUProbeClipmapGI.js +13 -31
  48. package/src/shade/renderer/global_illumination/probe_clipmap/PROBE_CLIPMAP_PROPOSAL_2026_10_27.md +764 -48
  49. package/src/shade/renderer/global_illumination/probe_clipmap/PROBE_RAYS_VARIABLE_AND_SORTED_SCOPE_2026_10_30.md +410 -0
  50. package/src/shade/renderer/global_illumination/probe_clipmap/ProbeClipmapSceneHolds.d.ts +3 -2
  51. package/src/shade/renderer/global_illumination/probe_clipmap/ProbeClipmapSceneHolds.d.ts.map +1 -1
  52. package/src/shade/renderer/global_illumination/probe_clipmap/ProbeClipmapSceneHolds.js +4 -3
  53. package/src/shade/renderer/global_illumination/probe_clipmap/ProbeClipmapSettings.d.ts +41 -17
  54. package/src/shade/renderer/global_illumination/probe_clipmap/ProbeClipmapSettings.d.ts.map +1 -1
  55. package/src/shade/renderer/global_illumination/probe_clipmap/ProbeClipmapSettings.js +57 -33
  56. package/src/shade/renderer/global_illumination/probe_clipmap/brick/BRICK_CLIPMAP.d.ts +11 -3
  57. package/src/shade/renderer/global_illumination/probe_clipmap/brick/BRICK_CLIPMAP.d.ts.map +1 -1
  58. package/src/shade/renderer/global_illumination/probe_clipmap/brick/BRICK_CLIPMAP.js +13 -4
  59. package/src/shade/renderer/global_illumination/probe_clipmap/brick/GPUBrickClipmap.d.ts +9 -18
  60. package/src/shade/renderer/global_illumination/probe_clipmap/brick/GPUBrickClipmap.d.ts.map +1 -1
  61. package/src/shade/renderer/global_illumination/probe_clipmap/brick/GPUBrickClipmap.js +8 -10
  62. package/src/shade/renderer/global_illumination/probe_clipmap/brick/chunk_brick_clipmap.d.ts +12 -0
  63. package/src/shade/renderer/global_illumination/probe_clipmap/brick/chunk_brick_clipmap.d.ts.map +1 -1
  64. package/src/shade/renderer/global_illumination/probe_clipmap/brick/chunk_brick_clipmap.js +28 -0
  65. package/src/shade/renderer/global_illumination/probe_clipmap/brick/chunk_brick_clipmap_trace.d.ts +1 -29
  66. package/src/shade/renderer/global_illumination/probe_clipmap/brick/chunk_brick_clipmap_trace.d.ts.map +1 -1
  67. package/src/shade/renderer/global_illumination/probe_clipmap/brick/chunk_brick_clipmap_trace.js +1 -74
  68. package/src/shade/renderer/global_illumination/probe_clipmap/brick/mesh/MESH_BRICK.d.ts +161 -0
  69. package/src/shade/renderer/global_illumination/probe_clipmap/brick/mesh/MESH_BRICK.d.ts.map +1 -0
  70. package/src/shade/renderer/global_illumination/probe_clipmap/brick/mesh/MESH_BRICK.js +219 -0
  71. package/src/shade/renderer/global_illumination/probe_clipmap/brick/mesh/MESH_BRICK_INSTANCE_STRUCT.d.ts +1 -8
  72. package/src/shade/renderer/global_illumination/probe_clipmap/brick/mesh/MESH_BRICK_INSTANCE_STRUCT.d.ts.map +1 -1
  73. package/src/shade/renderer/global_illumination/probe_clipmap/brick/mesh/MESH_BRICK_INSTANCE_STRUCT.js +1 -9
  74. package/src/shade/renderer/global_illumination/probe_clipmap/brick/mesh/MeshSDFBrickProvider.d.ts +40 -12
  75. package/src/shade/renderer/global_illumination/probe_clipmap/brick/mesh/MeshSDFBrickProvider.d.ts.map +1 -1
  76. package/src/shade/renderer/global_illumination/probe_clipmap/brick/mesh/MeshSDFBrickProvider.js +373 -31
  77. package/src/shade/renderer/global_illumination/probe_clipmap/brick/mesh/chunk_mesh_brick_instance.d.ts +2 -1
  78. package/src/shade/renderer/global_illumination/probe_clipmap/brick/mesh/chunk_mesh_brick_instance.d.ts.map +1 -1
  79. package/src/shade/renderer/global_illumination/probe_clipmap/brick/mesh/chunk_mesh_brick_instance.js +2 -1
  80. package/src/shade/renderer/global_illumination/probe_clipmap/brick/mesh/chunk_mesh_brick_texel.d.ts +15 -8
  81. package/src/shade/renderer/global_illumination/probe_clipmap/brick/mesh/chunk_mesh_brick_texel.d.ts.map +1 -1
  82. package/src/shade/renderer/global_illumination/probe_clipmap/brick/mesh/chunk_mesh_brick_texel.js +28 -14
  83. package/src/shade/renderer/global_illumination/probe_clipmap/brick/mesh/chunk_mesh_brick_walk.d.ts +23 -0
  84. package/src/shade/renderer/global_illumination/probe_clipmap/brick/mesh/chunk_mesh_brick_walk.d.ts.map +1 -0
  85. package/src/shade/renderer/global_illumination/probe_clipmap/brick/mesh/chunk_mesh_brick_walk.js +66 -0
  86. package/src/shade/renderer/global_illumination/probe_clipmap/brick/mesh/shader_mesh_brick_batch.d.ts +29 -0
  87. package/src/shade/renderer/global_illumination/probe_clipmap/brick/mesh/shader_mesh_brick_batch.d.ts.map +1 -0
  88. package/src/shade/renderer/global_illumination/probe_clipmap/brick/mesh/shader_mesh_brick_batch.js +210 -0
  89. package/src/shade/renderer/global_illumination/probe_clipmap/brick/mesh/shader_mesh_brick_command.d.ts +29 -0
  90. package/src/shade/renderer/global_illumination/probe_clipmap/brick/mesh/shader_mesh_brick_command.d.ts.map +1 -0
  91. package/src/shade/renderer/global_illumination/probe_clipmap/brick/mesh/shader_mesh_brick_command.js +86 -0
  92. package/src/shade/renderer/global_illumination/probe_clipmap/brick/mesh/shader_mesh_brick_gather.d.ts +41 -0
  93. package/src/shade/renderer/global_illumination/probe_clipmap/brick/mesh/shader_mesh_brick_gather.d.ts.map +1 -0
  94. package/src/shade/renderer/global_illumination/probe_clipmap/brick/mesh/shader_mesh_brick_gather.js +439 -0
  95. package/src/shade/renderer/global_illumination/probe_clipmap/brick/mesh/shader_mesh_brick_resolve.d.ts +23 -0
  96. package/src/shade/renderer/global_illumination/probe_clipmap/brick/mesh/shader_mesh_brick_resolve.d.ts.map +1 -0
  97. package/src/shade/renderer/global_illumination/probe_clipmap/brick/mesh/shader_mesh_brick_resolve.js +135 -0
  98. package/src/shade/renderer/global_illumination/probe_clipmap/brick/shader_brick_clipmap_free.d.ts +3 -1
  99. package/src/shade/renderer/global_illumination/probe_clipmap/brick/shader_brick_clipmap_free.d.ts.map +1 -1
  100. package/src/shade/renderer/global_illumination/probe_clipmap/brick/shader_brick_clipmap_free.js +12 -3
  101. package/src/shade/renderer/global_illumination/probe_clipmap/probe/GPUProbeClipmap.d.ts +21 -18
  102. package/src/shade/renderer/global_illumination/probe_clipmap/probe/GPUProbeClipmap.d.ts.map +1 -1
  103. package/src/shade/renderer/global_illumination/probe_clipmap/probe/GPUProbeClipmap.js +254 -73
  104. package/src/shade/renderer/global_illumination/probe_clipmap/probe/PROBE_CLIPMAP.d.ts +149 -8
  105. package/src/shade/renderer/global_illumination/probe_clipmap/probe/PROBE_CLIPMAP.d.ts.map +1 -1
  106. package/src/shade/renderer/global_illumination/probe_clipmap/probe/PROBE_CLIPMAP.js +181 -13
  107. package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap.d.ts +179 -7
  108. package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap.d.ts.map +1 -1
  109. package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap.js +412 -31
  110. package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap_pick.js +4 -4
  111. package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap_sample_radiance.d.ts.map +1 -1
  112. package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap_sample_radiance.js +4 -3
  113. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_accumulate.d.ts +36 -10
  114. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_accumulate.d.ts.map +1 -1
  115. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_accumulate.js +218 -29
  116. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_admit.d.ts +5 -1
  117. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_admit.d.ts.map +1 -1
  118. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_admit.js +24 -14
  119. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_due.d.ts +15 -6
  120. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_due.d.ts.map +1 -1
  121. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_due.js +21 -22
  122. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_guide.d.ts +36 -0
  123. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_guide.d.ts.map +1 -0
  124. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_guide.js +257 -0
  125. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_light.d.ts +18 -7
  126. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_light.d.ts.map +1 -1
  127. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_light.js +157 -51
  128. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_order.d.ts +23 -0
  129. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_order.d.ts.map +1 -0
  130. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_order.js +110 -0
  131. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_project.d.ts +24 -2
  132. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_project.d.ts.map +1 -1
  133. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_project.js +90 -10
  134. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_ray_layout.d.ts +45 -0
  135. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_ray_layout.d.ts.map +1 -0
  136. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_ray_layout.js +205 -0
  137. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_relocate.js +1 -1
  138. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_retire.d.ts +16 -3
  139. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_retire.d.ts.map +1 -1
  140. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_retire.js +55 -10
  141. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_schedule.d.ts +19 -4
  142. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_schedule.d.ts.map +1 -1
  143. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_schedule.js +60 -6
  144. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_shade.d.ts +10 -9
  145. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_shade.d.ts.map +1 -1
  146. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_shade.js +32 -39
  147. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_trace.d.ts +21 -14
  148. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_trace.d.ts.map +1 -1
  149. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_trace.js +100 -30
  150. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_trace_command.d.ts +6 -2
  151. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_trace_command.d.ts.map +1 -1
  152. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_trace_command.js +26 -10
  153. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_want_hits.d.ts +3 -2
  154. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_want_hits.d.ts.map +1 -1
  155. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_want_hits.js +12 -12
  156. package/src/shade/renderer/gpu_primitive/sort/SORT_DIGIT_SETTINGS_STRUCT.d.ts +10 -0
  157. package/src/shade/renderer/gpu_primitive/sort/SORT_DIGIT_SETTINGS_STRUCT.d.ts.map +1 -0
  158. package/src/shade/renderer/gpu_primitive/sort/SORT_DIGIT_SETTINGS_STRUCT.js +21 -0
  159. package/src/shade/renderer/gpu_primitive/sort/SORT_PASS_SETTINGS_STRUCT.d.ts +5 -2
  160. package/src/shade/renderer/gpu_primitive/sort/SORT_PASS_SETTINGS_STRUCT.d.ts.map +1 -1
  161. package/src/shade/renderer/gpu_primitive/sort/SORT_PASS_SETTINGS_STRUCT.js +31 -23
  162. package/src/shade/renderer/gpu_primitive/sort/SORT_SIZE_STRUCT.d.ts +10 -0
  163. package/src/shade/renderer/gpu_primitive/sort/SORT_SIZE_STRUCT.d.ts.map +1 -0
  164. package/src/shade/renderer/gpu_primitive/sort/SORT_SIZE_STRUCT.js +22 -0
  165. package/src/shade/renderer/gpu_primitive/sort/chunk_sort_constants.d.ts +9 -0
  166. package/src/shade/renderer/gpu_primitive/sort/chunk_sort_constants.d.ts.map +1 -0
  167. package/src/shade/renderer/gpu_primitive/sort/chunk_sort_constants.js +18 -0
  168. package/src/shade/renderer/gpu_primitive/sort/chunk_sort_digit.d.ts +8 -3
  169. package/src/shade/renderer/gpu_primitive/sort/chunk_sort_digit.d.ts.map +1 -1
  170. package/src/shade/renderer/gpu_primitive/sort/chunk_sort_digit.js +41 -32
  171. package/src/shade/renderer/gpu_primitive/sort/chunk_sort_histogram_tile.d.ts +31 -0
  172. package/src/shade/renderer/gpu_primitive/sort/chunk_sort_histogram_tile.d.ts.map +1 -0
  173. package/src/shade/renderer/gpu_primitive/sort/chunk_sort_histogram_tile.js +71 -0
  174. package/src/shade/renderer/gpu_primitive/sort/chunk_sort_scatter_tile.d.ts +47 -0
  175. package/src/shade/renderer/gpu_primitive/sort/chunk_sort_scatter_tile.d.ts.map +1 -0
  176. package/src/shade/renderer/gpu_primitive/sort/chunk_sort_scatter_tile.js +210 -0
  177. package/src/shade/renderer/gpu_primitive/sort/defs.d.ts +5 -4
  178. package/src/shade/renderer/gpu_primitive/sort/defs.d.ts.map +1 -1
  179. package/src/shade/renderer/gpu_primitive/sort/defs.js +5 -4
  180. package/src/shade/renderer/gpu_primitive/sort/graph_radix_sort.d.ts +56 -15
  181. package/src/shade/renderer/gpu_primitive/sort/graph_radix_sort.d.ts.map +1 -1
  182. package/src/shade/renderer/gpu_primitive/sort/graph_radix_sort.js +410 -61
  183. package/src/shade/renderer/gpu_primitive/sort/shader_radix_sort_histogram.d.ts +4 -1
  184. package/src/shade/renderer/gpu_primitive/sort/shader_radix_sort_histogram.d.ts.map +1 -1
  185. package/src/shade/renderer/gpu_primitive/sort/shader_radix_sort_histogram.js +16 -42
  186. package/src/shade/renderer/gpu_primitive/sort/shader_radix_sort_histogram_indirect.d.ts +15 -0
  187. package/src/shade/renderer/gpu_primitive/sort/shader_radix_sort_histogram_indirect.d.ts.map +1 -0
  188. package/src/shade/renderer/gpu_primitive/sort/shader_radix_sort_histogram_indirect.js +60 -0
  189. package/src/shade/renderer/gpu_primitive/sort/shader_radix_sort_prepare.d.ts +25 -0
  190. package/src/shade/renderer/gpu_primitive/sort/shader_radix_sort_prepare.d.ts.map +1 -0
  191. package/src/shade/renderer/gpu_primitive/sort/shader_radix_sort_prepare.js +89 -0
  192. package/src/shade/renderer/gpu_primitive/sort/shader_radix_sort_scatter.d.ts +3 -8
  193. package/src/shade/renderer/gpu_primitive/sort/shader_radix_sort_scatter.d.ts.map +1 -1
  194. package/src/shade/renderer/gpu_primitive/sort/shader_radix_sort_scatter.js +28 -160
  195. package/src/shade/renderer/gpu_primitive/sort/shader_radix_sort_scatter_indirect.d.ts +12 -0
  196. package/src/shade/renderer/gpu_primitive/sort/shader_radix_sort_scatter_indirect.d.ts.map +1 -0
  197. package/src/shade/renderer/gpu_primitive/sort/shader_radix_sort_scatter_indirect.js +74 -0
  198. package/src/shade/renderer/gpu_primitive/sort/verify_radix_sort.d.ts +3 -1
  199. package/src/shade/renderer/gpu_primitive/sort/verify_radix_sort.d.ts.map +1 -1
  200. package/src/shade/renderer/gpu_primitive/sort/verify_radix_sort.js +387 -188
  201. package/src/shade/renderer/lightmap/bake/shader_lightmap_viz_to_irradiance_flat.js +1 -1
  202. package/src/shade/renderer/lightmap/bake/shader_lightmap_viz_to_sh.js +1 -1
  203. package/src/shade/renderer/material/resident/GPUResidentMaterialContext.d.ts.map +1 -1
  204. package/src/shade/renderer/material/resident/GPUResidentMaterialContext.js +90 -72
  205. package/src/shade/renderer/material/resident/RESIDENT_MATERIAL_TEXTURE_LAYOUT.d.ts +5 -0
  206. package/src/shade/renderer/material/resident/RESIDENT_MATERIAL_TEXTURE_LAYOUT.d.ts.map +1 -1
  207. package/src/shade/renderer/material/resident/RESIDENT_MATERIAL_TEXTURE_LAYOUT.js +9 -0
  208. package/src/shade/renderer/path_tracer/shader/INDIRECT_TEXTURE_FILTER.d.ts +13 -0
  209. package/src/shade/renderer/path_tracer/shader/INDIRECT_TEXTURE_FILTER.d.ts.map +1 -0
  210. package/src/shade/renderer/path_tracer/shader/INDIRECT_TEXTURE_FILTER.js +14 -0
  211. package/src/shade/renderer/path_tracer/shader/IndirectTextureFilter.d.ts +10 -0
  212. package/src/shade/renderer/path_tracer/shader/IndirectTextureFilter.d.ts.map +1 -0
  213. package/src/shade/renderer/path_tracer/shader/IndirectTextureFilter.js +15 -0
  214. package/src/shade/renderer/path_tracer/shader/chunk_indirect_sample_tangent_normal.d.ts +4 -3
  215. package/src/shade/renderer/path_tracer/shader/chunk_indirect_sample_tangent_normal.d.ts.map +1 -1
  216. package/src/shade/renderer/path_tracer/shader/chunk_indirect_sample_tangent_normal.js +6 -5
  217. package/src/shade/renderer/path_tracer/shader/chunk_indirect_sample_texture.d.ts +17 -2
  218. package/src/shade/renderer/path_tracer/shader/chunk_indirect_sample_texture.d.ts.map +1 -1
  219. package/src/shade/renderer/path_tracer/shader/chunk_indirect_sample_texture.js +25 -57
  220. package/src/shade/renderer/path_tracer/shader/chunk_indirect_sample_texture_exact.d.ts +13 -0
  221. package/src/shade/renderer/path_tracer/shader/chunk_indirect_sample_texture_exact.d.ts.map +1 -0
  222. package/src/shade/renderer/path_tracer/shader/chunk_indirect_sample_texture_exact.js +70 -0
  223. package/src/shade/renderer/path_tracer/shader/chunk_indirect_sample_texture_stochastic.d.ts +10 -0
  224. package/src/shade/renderer/path_tracer/shader/chunk_indirect_sample_texture_stochastic.d.ts.map +1 -0
  225. package/src/shade/renderer/path_tracer/shader/chunk_indirect_sample_texture_stochastic.js +59 -0
  226. package/src/shade/renderer/path_tracer/shader/chunk_indirect_texture_load.d.ts +12 -0
  227. package/src/shade/renderer/path_tracer/shader/chunk_indirect_texture_load.d.ts.map +1 -0
  228. package/src/shade/renderer/path_tracer/shader/chunk_indirect_texture_load.js +49 -0
  229. package/src/shade/renderer/path_tracer/shader/chunk_ray_hit_to_opacity.d.ts.map +1 -1
  230. package/src/shade/renderer/path_tracer/shader/chunk_ray_hit_to_opacity.js +1 -0
  231. package/src/shade/renderer/path_tracer/shader/chunk_render_trace_path.d.ts.map +1 -1
  232. package/src/shade/renderer/path_tracer/shader/chunk_render_trace_path.js +1 -0
  233. package/src/shade/renderer/path_tracer/shader/chunk_sample_material.d.ts.map +1 -1
  234. package/src/shade/renderer/path_tracer/shader/chunk_sample_material.js +2 -1
  235. package/src/shade/renderer/path_tracer/shader/chunk_sample_material_data.d.ts +7 -0
  236. package/src/shade/renderer/path_tracer/shader/chunk_sample_material_data.d.ts.map +1 -1
  237. package/src/shade/renderer/path_tracer/shader/chunk_sample_material_data.js +15 -6
  238. package/src/shade/renderer/scene/GPUSceneContext.d.ts +7 -1
  239. package/src/shade/renderer/scene/GPUSceneContext.d.ts.map +1 -1
  240. package/src/shade/renderer/scene/GPUSceneContext.js +26 -1
  241. package/src/shade/renderer/shader/chunk/bvh/chunk_bvh_query_aabb_cooperative.d.ts +7 -7
  242. package/src/shade/renderer/shader/chunk/bvh/chunk_bvh_query_aabb_cooperative.d.ts.map +1 -1
  243. package/src/shade/renderer/shader/chunk/bvh/chunk_bvh_query_aabb_cooperative.js +262 -294
  244. package/src/shade/renderer/shader/chunk/filter/MULTISCALE_MEAN_STRUCT.d.ts +9 -0
  245. package/src/shade/renderer/shader/chunk/filter/MULTISCALE_MEAN_STRUCT.d.ts.map +1 -0
  246. package/src/shade/renderer/shader/chunk/filter/MULTISCALE_MEAN_STRUCT.js +21 -0
  247. package/src/shade/renderer/shader/chunk/filter/chunk_multiscale_mean.d.ts +43 -0
  248. package/src/shade/renderer/shader/chunk/filter/chunk_multiscale_mean.d.ts.map +1 -0
  249. package/src/shade/renderer/shader/chunk/filter/chunk_multiscale_mean.js +87 -0
  250. package/src/shade/renderer/shader/chunk/noise/r/chunk_r2_canonical.d.ts +7 -1
  251. package/src/shade/renderer/shader/chunk/noise/r/chunk_r2_canonical.d.ts.map +1 -1
  252. package/src/shade/renderer/shader/chunk/noise/r/chunk_r2_canonical.js +1 -1
  253. package/src/shade/renderer/shader/chunk/subgroup/chunk_subgroup_reserve_workgroup.d.ts +21 -0
  254. package/src/shade/renderer/shader/chunk/subgroup/chunk_subgroup_reserve_workgroup.d.ts.map +1 -0
  255. package/src/shade/renderer/shader/chunk/subgroup/chunk_subgroup_reserve_workgroup.js +42 -0
  256. package/src/shade/renderer/wind/GPUSceneWind.d.ts +1 -1
  257. package/src/shade/wgsl/emulator/CPUBitmapData.d.ts +19 -0
  258. package/src/shade/wgsl/emulator/CPUBitmapData.d.ts.map +1 -1
  259. package/src/shade/wgsl/emulator/CPUBitmapData.js +27 -0
  260. package/src/shade/wgsl/emulator/WGSLLanguageCore.d.ts.map +1 -1
  261. package/src/shade/wgsl/emulator/WGSLLanguageCore.js +65 -19
  262. package/src/view/elements/progress/segmented/GhostTrail.d.ts +116 -0
  263. package/src/view/elements/progress/segmented/GhostTrail.d.ts.map +1 -0
  264. package/src/view/elements/progress/segmented/GhostTrail.js +280 -0
  265. package/src/view/elements/progress/segmented/RESOURCE_BAR_SEGMENTS.d.ts +3 -1
  266. package/src/view/elements/progress/segmented/RESOURCE_BAR_SEGMENTS.d.ts.map +1 -1
  267. package/src/view/elements/progress/segmented/RESOURCE_BAR_SEGMENTS.js +3 -1
  268. package/src/view/elements/progress/segmented/SEGMENT_TIERS_DEFAULT.d.ts +11 -0
  269. package/src/view/elements/progress/segmented/SEGMENT_TIERS_DEFAULT.d.ts.map +1 -0
  270. package/src/view/elements/progress/segmented/SEGMENT_TIERS_DEFAULT.js +15 -0
  271. package/src/view/elements/progress/segmented/SegmentDefinition.d.ts +3 -0
  272. package/src/view/elements/progress/segmented/SegmentDefinition.d.ts.map +1 -1
  273. package/src/view/elements/progress/segmented/SegmentDefinition.js +3 -0
  274. package/src/view/elements/progress/segmented/SegmentTier.d.ts +38 -0
  275. package/src/view/elements/progress/segmented/SegmentTier.d.ts.map +1 -0
  276. package/src/view/elements/progress/segmented/SegmentTier.js +50 -0
  277. package/src/view/elements/progress/segmented/SegmentedResourceBarView.d.ts +163 -10
  278. package/src/view/elements/progress/segmented/SegmentedResourceBarView.d.ts.map +1 -1
  279. package/src/view/elements/progress/segmented/SegmentedResourceBarView.js +442 -101
  280. package/src/view/elements/progress/segmented/playground/index.html +78 -0
  281. package/src/view/elements/progress/segmented/playground/main.d.ts +2 -0
  282. package/src/view/elements/progress/segmented/playground/main.d.ts.map +1 -0
  283. package/src/view/elements/progress/segmented/playground/main.js +173 -0
  284. package/src/view/elements/progress/segmented/segment_cell_layout.d.ts +48 -0
  285. package/src/view/elements/progress/segmented/segment_cell_layout.d.ts.map +1 -0
  286. package/src/view/elements/progress/segmented/segment_cell_layout.js +75 -0
  287. package/src/view/elements/progress/segmented/segment_notch_place.d.ts +18 -0
  288. package/src/view/elements/progress/segmented/segment_notch_place.d.ts.map +1 -0
  289. package/src/view/elements/progress/segmented/segment_notch_place.js +28 -0
  290. package/src/view/elements/progress/segmented/segment_tick_positions.d.ts +32 -0
  291. package/src/view/elements/progress/segmented/segment_tick_positions.d.ts.map +1 -0
  292. package/src/view/elements/progress/segmented/segment_tick_positions.js +103 -0
  293. package/src/view/elements/progress/segmented/segmented-resource-bar.css +142 -0
  294. package/src/shade/renderer/global_illumination/probe_clipmap/brick/mesh/shader_mesh_brick_provider.d.ts +0 -35
  295. package/src/shade/renderer/global_illumination/probe_clipmap/brick/mesh/shader_mesh_brick_provider.d.ts.map +0 -1
  296. package/src/shade/renderer/global_illumination/probe_clipmap/brick/mesh/shader_mesh_brick_provider.js +0 -238
  297. package/src/shade/renderer/global_illumination/probe_clipmap/brick/vgeo/VGEO_BRICK.d.ts +0 -99
  298. package/src/shade/renderer/global_illumination/probe_clipmap/brick/vgeo/VGEO_BRICK.d.ts.map +0 -1
  299. package/src/shade/renderer/global_illumination/probe_clipmap/brick/vgeo/VGEO_BRICK.js +0 -139
  300. package/src/shade/renderer/global_illumination/probe_clipmap/brick/vgeo/VGeoBrickProvider.d.ts +0 -65
  301. package/src/shade/renderer/global_illumination/probe_clipmap/brick/vgeo/VGeoBrickProvider.d.ts.map +0 -1
  302. package/src/shade/renderer/global_illumination/probe_clipmap/brick/vgeo/VGeoBrickProvider.js +0 -393
  303. package/src/shade/renderer/global_illumination/probe_clipmap/brick/vgeo/chunk_vgeo_brick_box.d.ts +0 -17
  304. package/src/shade/renderer/global_illumination/probe_clipmap/brick/vgeo/chunk_vgeo_brick_box.d.ts.map +0 -1
  305. package/src/shade/renderer/global_illumination/probe_clipmap/brick/vgeo/chunk_vgeo_brick_box.js +0 -36
  306. package/src/shade/renderer/global_illumination/probe_clipmap/brick/vgeo/chunk_vgeo_brick_pair.d.ts +0 -29
  307. package/src/shade/renderer/global_illumination/probe_clipmap/brick/vgeo/chunk_vgeo_brick_pair.d.ts.map +0 -1
  308. package/src/shade/renderer/global_illumination/probe_clipmap/brick/vgeo/chunk_vgeo_brick_pair.js +0 -108
  309. package/src/shade/renderer/global_illumination/probe_clipmap/brick/vgeo/chunk_vgeo_brick_texel.d.ts +0 -31
  310. package/src/shade/renderer/global_illumination/probe_clipmap/brick/vgeo/chunk_vgeo_brick_texel.d.ts.map +0 -1
  311. package/src/shade/renderer/global_illumination/probe_clipmap/brick/vgeo/chunk_vgeo_brick_texel.js +0 -113
  312. package/src/shade/renderer/global_illumination/probe_clipmap/brick/vgeo/chunk_vgeo_brick_triangle.d.ts +0 -36
  313. package/src/shade/renderer/global_illumination/probe_clipmap/brick/vgeo/chunk_vgeo_brick_triangle.d.ts.map +0 -1
  314. package/src/shade/renderer/global_illumination/probe_clipmap/brick/vgeo/chunk_vgeo_brick_triangle.js +0 -85
  315. package/src/shade/renderer/global_illumination/probe_clipmap/brick/vgeo/shader_vgeo_brick_distance.d.ts +0 -23
  316. package/src/shade/renderer/global_illumination/probe_clipmap/brick/vgeo/shader_vgeo_brick_distance.d.ts.map +0 -1
  317. package/src/shade/renderer/global_illumination/probe_clipmap/brick/vgeo/shader_vgeo_brick_distance.js +0 -273
  318. package/src/shade/renderer/global_illumination/probe_clipmap/brick/vgeo/shader_vgeo_brick_gather.d.ts +0 -13
  319. package/src/shade/renderer/global_illumination/probe_clipmap/brick/vgeo/shader_vgeo_brick_gather.d.ts.map +0 -1
  320. package/src/shade/renderer/global_illumination/probe_clipmap/brick/vgeo/shader_vgeo_brick_gather.js +0 -151
  321. package/src/shade/renderer/global_illumination/probe_clipmap/brick/vgeo/shader_vgeo_brick_traverse.d.ts +0 -13
  322. package/src/shade/renderer/global_illumination/probe_clipmap/brick/vgeo/shader_vgeo_brick_traverse.d.ts.map +0 -1
  323. package/src/shade/renderer/global_illumination/probe_clipmap/brick/vgeo/shader_vgeo_brick_traverse.js +0 -133
  324. package/src/shade/renderer/global_illumination/probe_clipmap/brick/vgeo/shader_vgeo_brick_wait.d.ts +0 -22
  325. package/src/shade/renderer/global_illumination/probe_clipmap/brick/vgeo/shader_vgeo_brick_wait.d.ts.map +0 -1
  326. package/src/shade/renderer/global_illumination/probe_clipmap/brick/vgeo/shader_vgeo_brick_wait.js +0 -135
@@ -1,294 +1,262 @@
1
- import { WebGPUExtensionType } from "../../../../descriptor/WebGPUExtensionType.js";
2
- import { CodeChunk } from "../../compiler/CodeChunk.js";
3
- import { chunk_sort_bitonic_comparator } from "../../../gpu_primitive/sort/chunk_sort_bitonic_comparator.js";
4
- import { BVH2_NODE_STRUCT } from "./BVH2_NODE_STRUCT.js";
5
- import { BVH_NULL_NODE_DEFINITION } from "./BVH_NULL_NODE_DEFINITION.js";
6
- import { chunk_bvh_query_aabb_frontier } from "./chunk_bvh_query_aabb_frontier.js";
7
-
8
- /**
9
- * Every leaf of a BVH whose box overlaps one query box, found by a whole workgroup together and
10
- * returned as payloads in ascending order.
11
- *
12
- * ## Why not a stack per thread
13
- *
14
- * The engine's traversals (`chunk_sdf_query_distance`, `chunk_ray_query_*`) walk a stack per
15
- * thread with no cap on visits, which is right for one ray per thread and wrong for one box per
16
- * workgroup: the box meets a subtree, not a path, and one thread walking it serially is the slowest
17
- * thread of the dispatch. This expands the tree a **level at a time** instead, as the vgeo cut does
18
- * its descent: every node on the current level is tested by its own invocation, the survivors'
19
- * children are appended to the next level, overlapping leaves to the candidate list, and a barrier
20
- * separates the levels. Per-invocation work is bounded by the depth of the tree, not by the size of
21
- * the answer.
22
- *
23
- * ## The contract
24
- *
25
- * Call `bvh_query_aabb_cooperative(root, query, lane)` from every invocation of a workgroup of
26
- * exactly `BVH_QUERY_AABB_WORKGROUP_SIZE` invocations, in uniform control flow, with `lane` the
27
- * `local_invocation_index` and `root` and `query` the same in every invocation. `root` is the
28
- * tree's root word (word 0 of `BVH_BUFFER_LAYOUT`), and `BVH_NULL_NODE` for an empty tree. `query`
29
- * is `[min.xyz, max.xyz]`; touching counts as overlapping, as in `aabb3_intersects_aabb3`.
30
- *
31
- * It returns a `BVHQueryAABBResult` whose fields are workgroup-uniform, so they can bound the
32
- * caller's loops. The payloads are `bvh_query_aabb_candidates[0, candidate_count)`, ascending, and
33
- * visible to every invocation when the call returns. They stay there until the next query.
34
- *
35
- * The node layout is `BVH_BUFFER_LAYOUT`'s: a node is a leaf exactly when `child_1` is
36
- * `BVH_NULL_NODE`, and then `child_2` is its payload.
37
- *
38
- * ## The seam: two functions the enclosing shader defines
39
- *
40
- * The chunk binds nothing. It reads the tree and filters leaves through two functions the shader
41
- * that includes it must define, in the manner of the particle VM's `vm_reg_read` and
42
- * `vm_reg_write`:
43
- *
44
- * - `fn bvh_query_aabb_node(index: u32) -> BVH2Node` returns node `index`, where `BVH2Node` is
45
- * `BVH2_NODE_STRUCT.wgsl_ref`. A tree bound as `BVH_STRUCT` answers with `tree.nodes[index]`; one
46
- * inside a word arena reads its eight words.
47
- * - `fn bvh_query_aabb_accept_leaf(payload: u32, bounds: array<f32, 6>) -> bool` is asked about
48
- * every leaf that overlaps the box, before it takes a place on the list. A caller with nothing to
49
- * filter returns `true`. The fluid's resolution cull lives here: a leaf too small for the cascade
50
- * is refused before it can crowd out one that is not.
51
- *
52
- * ## Deterministic order
53
- *
54
- * Appends from different subgroups land in whatever order the hardware runs them, so the list is
55
- * sorted by payload before it is returned: the bitonic network of `chunk_sort_bitonic_comparator`
56
- * over the smallest power-of-two prefix that holds the candidates (`sort_bitonic_size`), padded
57
- * with `0xffffffff`, one compare-exchange per invocation per stage. A payload that is a stable row index then makes "the lowest K" the same K every frame for
58
- * the same overlaps, however the traversal was scheduled.
59
- *
60
- * ## Bounds, and what is counted
61
- *
62
- * Nothing is dropped silently. A level whose appends pass `BVH_QUERY_AABB_FRONTIER_CAPACITY`, and a
63
- * list still holding nodes when `BVH_QUERY_AABB_LEVEL_BUDGET` levels have been expanded, add those
64
- * nodes to `nodes_dropped`: subtrees never tested. A leaf that passes the filter when the candidate
65
- * list is full adds to `candidates_dropped`. With both zero the candidates are every overlapping
66
- * leaf the filter accepted; with either non-zero they are a subset, and the lowest K of them need
67
- * not be the lowest K overall.
68
- *
69
- * Per invocation, at most `BVH_QUERY_AABB_LEVEL_BUDGET * BVH_QUERY_AABB_FRONTIER_ROUNDS` = 51 * 4 =
70
- * 204 node reads and filter calls, then two padding writes and 28 compare-exchanges. A query that
71
- * meets nothing costs one level: the root is read, misses, and the loop leaves.
72
- *
73
- * Workgroup memory: two lists of 256 node indices, 128 payloads and five words, 2580 bytes.
74
- *
75
- * ## Subgroups
76
- *
77
- * Appends are aggregated per subgroup: an exclusive add numbers the subgroup's appends, one elected
78
- * invocation reserves them all with one workgroup `atomicAdd`, and a broadcast hands each
79
- * invocation its base. Nothing assumes which invocations share a subgroup or that a subgroup's
80
- * invocations are contiguous in `local_invocation_index`: a subgroup reserves a run of its own
81
- * wherever it lands. Every subgroup operation is reached in uniform control flow; the loops' trip
82
- * counts are literals, and the one early exit is on a value read back through
83
- * `workgroupUniformLoad`.
84
- *
85
- * @type {CodeChunk}
86
- */
87
- export const chunk_bvh_query_aabb_cooperative = CodeChunk.from(
88
- //language=WGSL
89
- `
90
- struct BVHQueryAABBResult {
91
- // payloads in bvh_query_aabb_candidates[0, candidate_count), ascending
92
- candidate_count: u32,
93
- // leaves the filter accepted that found the candidate list full
94
- candidates_dropped: u32,
95
- // nodes never tested: frontier overflow, and what was left when the level budget ran out
96
- nodes_dropped: u32,
97
- }
98
-
99
- // two lists of node indices, alternating by level; bvh_query_aabb_list says which one a level reads
100
- var<workgroup> bvh_query_aabb_frontier: array<array<u32, BVH_QUERY_AABB_FRONTIER_CAPACITY>, 2>;
101
- // appends asked of each list; past the capacity they were counted but not stored
102
- var<workgroup> bvh_query_aabb_frontier_reserved: array<atomic<u32>, 2>;
103
- var<workgroup> bvh_query_aabb_candidates: array<u32, BVH_QUERY_AABB_CANDIDATE_CAPACITY>;
104
- var<workgroup> bvh_query_aabb_candidates_reserved: atomic<u32>;
105
- // written by invocation 0 only
106
- var<workgroup> bvh_query_aabb_nodes_dropped: u32;
107
- // what invocation 0 publishes, read back through workgroupUniformLoad
108
- var<workgroup> bvh_query_aabb_broadcast: u32;
109
-
110
- // This invocation's first slot of count appends to a frontier list, reserved for the whole
111
- // subgroup by one atomic.
112
- fn bvh_query_aabb_reserve_frontier(list: u32, count: u32) -> u32 {
113
- let offset = subgroupExclusiveAdd(count);
114
- let total = subgroupAdd(count);
115
-
116
- // elected before the branch, which then holds no subgroup operation and may be non-uniform
117
- let elected = subgroupElect();
118
-
119
- var base = 0u;
120
-
121
- if (elected && total > 0u) {
122
- base = atomicAdd(&bvh_query_aabb_frontier_reserved[list], total);
123
- }
124
-
125
- return subgroupBroadcastFirst(base) + offset;
126
- }
127
-
128
- // The same, for the candidate list.
129
- fn bvh_query_aabb_reserve_candidates(count: u32) -> u32 {
130
- let offset = subgroupExclusiveAdd(count);
131
- let total = subgroupAdd(count);
132
-
133
- let elected = subgroupElect();
134
-
135
- var base = 0u;
136
-
137
- if (elected && total > 0u) {
138
- base = atomicAdd(&bvh_query_aabb_candidates_reserved, total);
139
- }
140
-
141
- return subgroupBroadcastFirst(base) + offset;
142
- }
143
-
144
- // Test this level's list: the children of overlapping internal nodes go on the next list, the
145
- // payloads of overlapping leaves the filter accepts on the candidate list.
146
- fn bvh_query_aabb_expand(list: u32, expand_count: u32, query: array<f32, 6>, lane: u32) {
147
- let next = list ^ 1u;
148
-
149
- for (var iteration = 0u; iteration < BVH_QUERY_AABB_FRONTIER_ROUNDS; iteration++) {
150
- if (iteration * BVH_QUERY_AABB_WORKGROUP_SIZE >= expand_count) {
151
- break;
152
- }
153
-
154
- let slot = bvh_query_aabb_slot(iteration, lane);
155
-
156
- var node: ${BVH2_NODE_STRUCT.wgsl_ref};
157
- var kind = BVH_QUERY_AABB_SKIP;
158
-
159
- if (slot < expand_count) {
160
- node = bvh_query_aabb_node(bvh_query_aabb_frontier[list][slot]);
161
-
162
- kind = bvh_query_aabb_classify(node.bounds, node.child_1, query);
163
-
164
- if (kind == BVH_QUERY_AABB_LEAF && !bvh_query_aabb_accept_leaf(node.child_2, node.bounds)) {
165
- kind = BVH_QUERY_AABB_SKIP;
166
- }
167
- }
168
-
169
- // every invocation reserves, holding or not, so the subgroup operations stay uniform
170
- let frontier_slot = bvh_query_aabb_reserve_frontier(next, select(0u, 2u, kind == BVH_QUERY_AABB_DESCEND));
171
- let candidate_slot = bvh_query_aabb_reserve_candidates(select(0u, 1u, kind == BVH_QUERY_AABB_LEAF));
172
-
173
- if (kind == BVH_QUERY_AABB_DESCEND) {
174
- if (frontier_slot < BVH_QUERY_AABB_FRONTIER_CAPACITY) {
175
- bvh_query_aabb_frontier[next][frontier_slot] = node.child_1;
176
- }
177
- if (frontier_slot + 1u < BVH_QUERY_AABB_FRONTIER_CAPACITY) {
178
- bvh_query_aabb_frontier[next][frontier_slot + 1u] = node.child_2;
179
- }
180
- }
181
-
182
- if (kind == BVH_QUERY_AABB_LEAF && candidate_slot < BVH_QUERY_AABB_CANDIDATE_CAPACITY) {
183
- bvh_query_aabb_candidates[candidate_slot] = node.child_2;
184
- }
185
- }
186
- }
187
-
188
- // Order the first count candidates ascending, through the power-of-two prefix that holds them.
189
- fn bvh_query_aabb_sort(count: u32, lane: u32) {
190
- if (count <= 1u) {
191
- return;
192
- }
193
-
194
- let span = sort_bitonic_size(count);
195
-
196
- // the prefix past the candidates sorts last
197
- for (var iteration = 0u; iteration < BVH_QUERY_AABB_CANDIDATE_ROUNDS; iteration++) {
198
- let slot = iteration * BVH_QUERY_AABB_WORKGROUP_SIZE + lane;
199
-
200
- if (slot >= count && slot < span) {
201
- bvh_query_aabb_candidates[slot] = 0xffffffffu;
202
- }
203
- }
204
-
205
- // span is workgroup-uniform, so is every bound and exit below
206
- for (var k = 2u; k <= BVH_QUERY_AABB_CANDIDATE_CAPACITY; k = k << 1u) {
207
- if (k > span) {
208
- break;
209
- }
210
-
211
- for (var j = k >> 1u; j > 0u; j = j >> 1u) {
212
- workgroupBarrier();
213
-
214
- // the smaller of the two belongs in pair.x
215
- let pair = sort_bitonic_comparator(lane, k, j);
216
-
217
- // a pair is wholly inside the prefix or wholly past it
218
- if (max(pair.x, pair.y) < span) {
219
- let a = bvh_query_aabb_candidates[pair.x];
220
- let b = bvh_query_aabb_candidates[pair.y];
221
-
222
- if (b < a) {
223
- bvh_query_aabb_candidates[pair.x] = b;
224
- bvh_query_aabb_candidates[pair.y] = a;
225
- }
226
- }
227
- }
228
- }
229
- }
230
-
231
- fn bvh_query_aabb_cooperative(root: u32, query: array<f32, 6>, lane: u32) -> BVHQueryAABBResult {
232
- // whatever the workgroup did with a previous query's candidates is done before they are reset
233
- workgroupBarrier();
234
-
235
- if (lane == 0u) {
236
- bvh_query_aabb_frontier[0][0] = root;
237
- atomicStore(&bvh_query_aabb_frontier_reserved[0], select(1u, 0u, root == BVH_NULL_NODE));
238
- atomicStore(&bvh_query_aabb_frontier_reserved[1], 0u);
239
- atomicStore(&bvh_query_aabb_candidates_reserved, 0u);
240
- bvh_query_aabb_nodes_dropped = 0u;
241
- }
242
-
243
- // one pass past the budget, to count what the last expanded level left on its list; that
244
- // pass publishes nothing to expand, so the loop always leaves through the break
245
- for (var level = 0u; level <= BVH_QUERY_AABB_LEVEL_BUDGET; level++) {
246
- let list = bvh_query_aabb_list(level);
247
-
248
- // every append to this level's list has landed
249
- workgroupBarrier();
250
-
251
- if (lane == 0u) {
252
- let published = bvh_query_aabb_publish(atomicLoad(&bvh_query_aabb_frontier_reserved[list]), level);
253
-
254
- bvh_query_aabb_broadcast = published.x;
255
- bvh_query_aabb_nodes_dropped += published.y;
256
-
257
- // the list this level appends to, read two levels ago and empty again
258
- atomicStore(&bvh_query_aabb_frontier_reserved[list ^ 1u], 0u);
259
- }
260
-
261
- let expand_count = workgroupUniformLoad(&bvh_query_aabb_broadcast);
262
-
263
- if (expand_count == 0u) {
264
- break;
265
- }
266
-
267
- bvh_query_aabb_expand(list, expand_count, query, lane);
268
- }
269
-
270
- // every invocation has read the last broadcast before invocation 0 writes the next
271
- workgroupBarrier();
272
-
273
- if (lane == 0u) {
274
- bvh_query_aabb_broadcast = atomicLoad(&bvh_query_aabb_candidates_reserved);
275
- }
276
-
277
- let reserved = workgroupUniformLoad(&bvh_query_aabb_broadcast);
278
- let count = min(reserved, BVH_QUERY_AABB_CANDIDATE_CAPACITY);
279
-
280
- bvh_query_aabb_sort(count, lane);
281
-
282
- // also the barrier that makes the sorted list visible to every invocation
283
- let nodes_dropped = workgroupUniformLoad(&bvh_query_aabb_nodes_dropped);
284
-
285
- return BVHQueryAABBResult(count, reserved - count, nodes_dropped);
286
- }
287
- `, [
288
- BVH2_NODE_STRUCT.declaration_chunk,
289
- BVH_NULL_NODE_DEFINITION,
290
- chunk_bvh_query_aabb_frontier,
291
- chunk_sort_bitonic_comparator,
292
- ]);
293
-
294
- chunk_bvh_query_aabb_cooperative.addExtension(WebGPUExtensionType.Subgroups);
1
+ import { WebGPUExtensionType } from "../../../../descriptor/WebGPUExtensionType.js";
2
+ import { CodeChunk } from "../../compiler/CodeChunk.js";
3
+ import { chunk_sort_bitonic_comparator } from "../../../gpu_primitive/sort/chunk_sort_bitonic_comparator.js";
4
+ import { chunk_subgroup_reserve_workgroup } from "../subgroup/chunk_subgroup_reserve_workgroup.js";
5
+ import { BVH2_NODE_STRUCT } from "./BVH2_NODE_STRUCT.js";
6
+ import { BVH_NULL_NODE_DEFINITION } from "./BVH_NULL_NODE_DEFINITION.js";
7
+ import { chunk_bvh_query_aabb_frontier } from "./chunk_bvh_query_aabb_frontier.js";
8
+
9
+ /**
10
+ * Every leaf of a BVH whose box overlaps one query box, found by a whole workgroup together and
11
+ * returned as payloads in ascending order.
12
+ *
13
+ * ## Why not a stack per thread
14
+ *
15
+ * The engine's traversals (`chunk_sdf_query_distance`, `chunk_ray_query_*`) walk a stack per
16
+ * thread with no cap on visits, which is right for one ray per thread and wrong for one box per
17
+ * workgroup: the box meets a subtree, not a path, and one thread walking it serially is the slowest
18
+ * thread of the dispatch. This expands the tree a **level at a time** instead, as the vgeo cut does
19
+ * its descent: every node on the current level is tested by its own invocation, the survivors'
20
+ * children are appended to the next level, overlapping leaves to the candidate list, and a barrier
21
+ * separates the levels. Per-invocation work is bounded by the depth of the tree, not by the size of
22
+ * the answer.
23
+ *
24
+ * ## The contract
25
+ *
26
+ * Call `bvh_query_aabb_cooperative(root, query, lane)` from every invocation of a workgroup of
27
+ * exactly `BVH_QUERY_AABB_WORKGROUP_SIZE` invocations, in uniform control flow, with `lane` the
28
+ * `local_invocation_index` and `root` and `query` the same in every invocation. `root` is the
29
+ * tree's root word (word 0 of `BVH_BUFFER_LAYOUT`), and `BVH_NULL_NODE` for an empty tree. `query`
30
+ * is `[min.xyz, max.xyz]`; touching counts as overlapping, as in `aabb3_intersects_aabb3`.
31
+ *
32
+ * It returns a `BVHQueryAABBResult` whose fields are workgroup-uniform, so they can bound the
33
+ * caller's loops. The payloads are `bvh_query_aabb_candidates[0, candidate_count)`, ascending, and
34
+ * visible to every invocation when the call returns. They stay there until the next query.
35
+ *
36
+ * The node layout is `BVH_BUFFER_LAYOUT`'s: a node is a leaf exactly when `child_1` is
37
+ * `BVH_NULL_NODE`, and then `child_2` is its payload.
38
+ *
39
+ * ## The seam: two functions the enclosing shader defines
40
+ *
41
+ * The chunk binds nothing. It reads the tree and filters leaves through two functions the shader
42
+ * that includes it must define, in the manner of the particle VM's `vm_reg_read` and
43
+ * `vm_reg_write`:
44
+ *
45
+ * - `fn bvh_query_aabb_node(index: u32) -> BVH2Node` returns node `index`, where `BVH2Node` is
46
+ * `BVH2_NODE_STRUCT.wgsl_ref`. A tree bound as `BVH_STRUCT` answers with `tree.nodes[index]`; one
47
+ * inside a word arena reads its eight words.
48
+ * - `fn bvh_query_aabb_accept_leaf(payload: u32, bounds: array<f32, 6>) -> bool` is asked about
49
+ * every leaf that overlaps the box, before it takes a place on the list. A caller with nothing to
50
+ * filter returns `true`. The fluid's resolution cull lives here: a leaf too small for the cascade
51
+ * is refused before it can crowd out one that is not.
52
+ *
53
+ * ## Deterministic order
54
+ *
55
+ * Appends from different subgroups land in whatever order the hardware runs them, so the list is
56
+ * sorted by payload before it is returned: the bitonic network of `chunk_sort_bitonic_comparator`
57
+ * over the smallest power-of-two prefix that holds the candidates (`sort_bitonic_size`), padded
58
+ * with `0xffffffff`, one compare-exchange per invocation per stage. A payload that is a stable row index then makes "the lowest K" the same K every frame for
59
+ * the same overlaps, however the traversal was scheduled.
60
+ *
61
+ * ## Bounds, and what is counted
62
+ *
63
+ * Nothing is dropped silently. A level whose appends pass `BVH_QUERY_AABB_FRONTIER_CAPACITY`, and a
64
+ * list still holding nodes when `BVH_QUERY_AABB_LEVEL_BUDGET` levels have been expanded, add those
65
+ * nodes to `nodes_dropped`: subtrees never tested. A leaf that passes the filter when the candidate
66
+ * list is full adds to `candidates_dropped`. With both zero the candidates are every overlapping
67
+ * leaf the filter accepted; with either non-zero they are a subset, and the lowest K of them need
68
+ * not be the lowest K overall.
69
+ *
70
+ * Per invocation, at most `BVH_QUERY_AABB_LEVEL_BUDGET * BVH_QUERY_AABB_FRONTIER_ROUNDS` = 51 * 4 =
71
+ * 204 node reads and filter calls, then two padding writes and 28 compare-exchanges. A query that
72
+ * meets nothing costs one level: the root is read, misses, and the loop leaves.
73
+ *
74
+ * Workgroup memory: two lists of 256 node indices, 128 payloads and five words, 2580 bytes.
75
+ *
76
+ * ## Subgroups
77
+ *
78
+ * Appends are aggregated per subgroup (`chunk_subgroup_reserve_workgroup`): an exclusive add numbers
79
+ * the subgroup's appends, one elected invocation reserves them all with one workgroup `atomicAdd`,
80
+ * and a broadcast hands each invocation its base. Nothing assumes which invocations share a
81
+ * subgroup or that a subgroup's invocations are contiguous in `local_invocation_index`: a subgroup
82
+ * reserves a run of its own wherever it lands. Every subgroup operation is reached in uniform
83
+ * control flow; the loops' trip counts are literals, and the one early exit is on a value read
84
+ * back through `workgroupUniformLoad`.
85
+ *
86
+ * @type {CodeChunk}
87
+ */
88
+ export const chunk_bvh_query_aabb_cooperative = CodeChunk.from(
89
+ //language=WGSL
90
+ `
91
+ struct BVHQueryAABBResult {
92
+ // payloads in bvh_query_aabb_candidates[0, candidate_count), ascending
93
+ candidate_count: u32,
94
+ // leaves the filter accepted that found the candidate list full
95
+ candidates_dropped: u32,
96
+ // nodes never tested: frontier overflow, and what was left when the level budget ran out
97
+ nodes_dropped: u32,
98
+ }
99
+
100
+ // two lists of node indices, alternating by level; bvh_query_aabb_list says which one a level reads
101
+ var<workgroup> bvh_query_aabb_frontier: array<array<u32, BVH_QUERY_AABB_FRONTIER_CAPACITY>, 2>;
102
+ // appends asked of each list; past the capacity they were counted but not stored
103
+ var<workgroup> bvh_query_aabb_frontier_reserved: array<atomic<u32>, 2>;
104
+ var<workgroup> bvh_query_aabb_candidates: array<u32, BVH_QUERY_AABB_CANDIDATE_CAPACITY>;
105
+ var<workgroup> bvh_query_aabb_candidates_reserved: atomic<u32>;
106
+ // written by invocation 0 only
107
+ var<workgroup> bvh_query_aabb_nodes_dropped: u32;
108
+ // what invocation 0 publishes, read back through workgroupUniformLoad
109
+ var<workgroup> bvh_query_aabb_broadcast: u32;
110
+
111
+ // Test this level's list: the children of overlapping internal nodes go on the next list, the
112
+ // payloads of overlapping leaves the filter accepts on the candidate list.
113
+ fn bvh_query_aabb_expand(list: u32, expand_count: u32, query: array<f32, 6>, lane: u32) {
114
+ let next = list ^ 1u;
115
+
116
+ for (var iteration = 0u; iteration < BVH_QUERY_AABB_FRONTIER_ROUNDS; iteration++) {
117
+ if (iteration * BVH_QUERY_AABB_WORKGROUP_SIZE >= expand_count) {
118
+ break;
119
+ }
120
+
121
+ let slot = bvh_query_aabb_slot(iteration, lane);
122
+
123
+ var node: ${BVH2_NODE_STRUCT.wgsl_ref};
124
+ var kind = BVH_QUERY_AABB_SKIP;
125
+
126
+ if (slot < expand_count) {
127
+ node = bvh_query_aabb_node(bvh_query_aabb_frontier[list][slot]);
128
+
129
+ kind = bvh_query_aabb_classify(node.bounds, node.child_1, query);
130
+
131
+ if (kind == BVH_QUERY_AABB_LEAF && !bvh_query_aabb_accept_leaf(node.child_2, node.bounds)) {
132
+ kind = BVH_QUERY_AABB_SKIP;
133
+ }
134
+ }
135
+
136
+ // every invocation reserves, holding or not, so the subgroup operations stay uniform
137
+ let frontier_slot = subgroup_reserve_workgroup(&bvh_query_aabb_frontier_reserved[next], select(0u, 2u, kind == BVH_QUERY_AABB_DESCEND));
138
+ let candidate_slot = subgroup_reserve_workgroup(&bvh_query_aabb_candidates_reserved, select(0u, 1u, kind == BVH_QUERY_AABB_LEAF));
139
+
140
+ if (kind == BVH_QUERY_AABB_DESCEND) {
141
+ if (frontier_slot < BVH_QUERY_AABB_FRONTIER_CAPACITY) {
142
+ bvh_query_aabb_frontier[next][frontier_slot] = node.child_1;
143
+ }
144
+ if (frontier_slot + 1u < BVH_QUERY_AABB_FRONTIER_CAPACITY) {
145
+ bvh_query_aabb_frontier[next][frontier_slot + 1u] = node.child_2;
146
+ }
147
+ }
148
+
149
+ if (kind == BVH_QUERY_AABB_LEAF && candidate_slot < BVH_QUERY_AABB_CANDIDATE_CAPACITY) {
150
+ bvh_query_aabb_candidates[candidate_slot] = node.child_2;
151
+ }
152
+ }
153
+ }
154
+
155
+ // Order the first count candidates ascending, through the power-of-two prefix that holds them.
156
+ fn bvh_query_aabb_sort(count: u32, lane: u32) {
157
+ if (count <= 1u) {
158
+ return;
159
+ }
160
+
161
+ let span = sort_bitonic_size(count);
162
+
163
+ // the prefix past the candidates sorts last
164
+ for (var iteration = 0u; iteration < BVH_QUERY_AABB_CANDIDATE_ROUNDS; iteration++) {
165
+ let slot = iteration * BVH_QUERY_AABB_WORKGROUP_SIZE + lane;
166
+
167
+ if (slot >= count && slot < span) {
168
+ bvh_query_aabb_candidates[slot] = 0xffffffffu;
169
+ }
170
+ }
171
+
172
+ // span is workgroup-uniform, so is every bound and exit below
173
+ for (var k = 2u; k <= BVH_QUERY_AABB_CANDIDATE_CAPACITY; k = k << 1u) {
174
+ if (k > span) {
175
+ break;
176
+ }
177
+
178
+ for (var j = k >> 1u; j > 0u; j = j >> 1u) {
179
+ workgroupBarrier();
180
+
181
+ // the smaller of the two belongs in pair.x
182
+ let pair = sort_bitonic_comparator(lane, k, j);
183
+
184
+ // a pair is wholly inside the prefix or wholly past it
185
+ if (max(pair.x, pair.y) < span) {
186
+ let a = bvh_query_aabb_candidates[pair.x];
187
+ let b = bvh_query_aabb_candidates[pair.y];
188
+
189
+ if (b < a) {
190
+ bvh_query_aabb_candidates[pair.x] = b;
191
+ bvh_query_aabb_candidates[pair.y] = a;
192
+ }
193
+ }
194
+ }
195
+ }
196
+ }
197
+
198
+ fn bvh_query_aabb_cooperative(root: u32, query: array<f32, 6>, lane: u32) -> BVHQueryAABBResult {
199
+ // whatever the workgroup did with a previous query's candidates is done before they are reset
200
+ workgroupBarrier();
201
+
202
+ if (lane == 0u) {
203
+ bvh_query_aabb_frontier[0][0] = root;
204
+ atomicStore(&bvh_query_aabb_frontier_reserved[0], select(1u, 0u, root == BVH_NULL_NODE));
205
+ atomicStore(&bvh_query_aabb_frontier_reserved[1], 0u);
206
+ atomicStore(&bvh_query_aabb_candidates_reserved, 0u);
207
+ bvh_query_aabb_nodes_dropped = 0u;
208
+ }
209
+
210
+ // one pass past the budget, to count what the last expanded level left on its list; that
211
+ // pass publishes nothing to expand, so the loop always leaves through the break
212
+ for (var level = 0u; level <= BVH_QUERY_AABB_LEVEL_BUDGET; level++) {
213
+ let list = bvh_query_aabb_list(level);
214
+
215
+ // every append to this level's list has landed
216
+ workgroupBarrier();
217
+
218
+ if (lane == 0u) {
219
+ let published = bvh_query_aabb_publish(atomicLoad(&bvh_query_aabb_frontier_reserved[list]), level);
220
+
221
+ bvh_query_aabb_broadcast = published.x;
222
+ bvh_query_aabb_nodes_dropped += published.y;
223
+
224
+ // the list this level appends to, read two levels ago and empty again
225
+ atomicStore(&bvh_query_aabb_frontier_reserved[list ^ 1u], 0u);
226
+ }
227
+
228
+ let expand_count = workgroupUniformLoad(&bvh_query_aabb_broadcast);
229
+
230
+ if (expand_count == 0u) {
231
+ break;
232
+ }
233
+
234
+ bvh_query_aabb_expand(list, expand_count, query, lane);
235
+ }
236
+
237
+ // every invocation has read the last broadcast before invocation 0 writes the next
238
+ workgroupBarrier();
239
+
240
+ if (lane == 0u) {
241
+ bvh_query_aabb_broadcast = atomicLoad(&bvh_query_aabb_candidates_reserved);
242
+ }
243
+
244
+ let reserved = workgroupUniformLoad(&bvh_query_aabb_broadcast);
245
+ let count = min(reserved, BVH_QUERY_AABB_CANDIDATE_CAPACITY);
246
+
247
+ bvh_query_aabb_sort(count, lane);
248
+
249
+ // also the barrier that makes the sorted list visible to every invocation
250
+ let nodes_dropped = workgroupUniformLoad(&bvh_query_aabb_nodes_dropped);
251
+
252
+ return BVHQueryAABBResult(count, reserved - count, nodes_dropped);
253
+ }
254
+ `, [
255
+ BVH2_NODE_STRUCT.declaration_chunk,
256
+ BVH_NULL_NODE_DEFINITION,
257
+ chunk_bvh_query_aabb_frontier,
258
+ chunk_sort_bitonic_comparator,
259
+ chunk_subgroup_reserve_workgroup,
260
+ ]);
261
+
262
+ chunk_bvh_query_aabb_cooperative.addExtension(WebGPUExtensionType.Subgroups);
@@ -0,0 +1,9 @@
1
+ /**
2
+ * A multi-scale mean estimator's state, see {@link chunk_multiscale_mean}. Packed, so its fields are not in the
3
+ * order written here: build one with {@link WebGPUStruct#make}, never a positional constructor.
4
+ *
5
+ * @type {WebGPUStruct}
6
+ */
7
+ export const MULTISCALE_MEAN_STRUCT: WebGPUStruct;
8
+ import { WebGPUStruct } from "../../type/WebGPUStruct.js";
9
+ //# sourceMappingURL=MULTISCALE_MEAN_STRUCT.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MULTISCALE_MEAN_STRUCT.d.ts","sourceRoot":"","sources":["../../../../../../../src/shade/renderer/shader/chunk/filter/MULTISCALE_MEAN_STRUCT.js"],"names":[],"mappings":"AAGA;;;;;GAKG;AACH,qCAFU,YAAY,CAaM;6BAnBC,4BAA4B"}
@@ -0,0 +1,21 @@
1
+ import { f32, vec3f } from "../../type/WEBGPU_WGSL_PRIMITIVE_TYPES.js";
2
+ import { WebGPUStruct } from "../../type/WebGPUStruct.js";
3
+
4
+ /**
5
+ * A multi-scale mean estimator's state, see {@link chunk_multiscale_mean}. Packed, so its fields are not in the
6
+ * order written here: build one with {@link WebGPUStruct#make}, never a positional constructor.
7
+ *
8
+ * @type {WebGPUStruct}
9
+ */
10
+ export const MULTISCALE_MEAN_STRUCT = WebGPUStruct.from({
11
+ /** the long mean, the estimate */
12
+ mean: vec3f,
13
+ /** the short mean, blended by the short blend */
14
+ short_mean: vec3f,
15
+ /** a channel's variance about the short mean, blended by the variance blend */
16
+ variance: vec3f,
17
+ /** the blend reduction the long mean's catch-up is scaled by */
18
+ reduction: f32,
19
+ /** the means' gap over the deviation, smoothed by the short blend */
20
+ inconsistency: f32,
21
+ }, "MultiscaleMean").pack();