@woosh/meep-engine 3.64.1 → 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 (324) hide show
  1. package/CHANGELOG.md +85 -0
  2. package/build/bundle-worker-image-decoder.js +1 -1
  3. package/build/bundle-worker-terrain.js +1 -1
  4. package/package.json +1 -1
  5. package/src/core/binary/BinaryBuffer.d.ts +5 -0
  6. package/src/core/binary/BinaryBuffer.d.ts.map +1 -1
  7. package/src/core/binary/BinaryBuffer.js +39 -5
  8. package/src/core/geom/3d/topology/struct/binary/io/bt_boundary_loop.d.ts +65 -6
  9. package/src/core/geom/3d/topology/struct/binary/io/bt_boundary_loop.d.ts.map +1 -1
  10. package/src/core/geom/3d/topology/struct/binary/io/bt_boundary_loop.js +451 -101
  11. package/src/core/geom/3d/topology/struct/binary/io/bt_mesh_close_boundary_holes.d.ts +4 -2
  12. package/src/core/geom/3d/topology/struct/binary/io/bt_mesh_close_boundary_holes.d.ts.map +1 -1
  13. package/src/core/geom/3d/topology/struct/binary/io/bt_mesh_close_boundary_holes.js +4 -2
  14. package/src/core/geom/3d/topology/struct/binary/io/bt_mesh_fill_small_holes.d.ts +8 -1
  15. package/src/core/geom/3d/topology/struct/binary/io/bt_mesh_fill_small_holes.d.ts.map +1 -1
  16. package/src/core/geom/3d/topology/struct/binary/io/bt_mesh_fill_small_holes.js +45 -10
  17. package/src/core/geom/3d/topology/struct/binary/query/bt_mesh_face_find_path_polyanya.d.ts.map +1 -1
  18. package/src/core/geom/3d/topology/struct/binary/query/bt_mesh_face_find_path_polyanya.js +237 -119
  19. package/src/engine/graphics/ecs/grass/GrassSpecies.d.ts +143 -0
  20. package/src/engine/graphics/ecs/grass/GrassSpecies.d.ts.map +1 -0
  21. package/src/engine/graphics/ecs/grass/GrassSpecies.js +189 -0
  22. package/src/engine/graphics/ecs/grass/GrassSurface.d.ts +25 -0
  23. package/src/engine/graphics/ecs/grass/GrassSurface.d.ts.map +1 -0
  24. package/src/engine/graphics/ecs/grass/GrassSurface.js +32 -0
  25. package/src/engine/graphics/ecs/grass/GroundCover.d.ts +68 -0
  26. package/src/engine/graphics/ecs/grass/GroundCover.d.ts.map +1 -0
  27. package/src/engine/graphics/ecs/grass/GroundCover.js +85 -0
  28. package/src/engine/graphics3/GrassSurfaceSystem.d.ts +153 -0
  29. package/src/engine/graphics3/GrassSurfaceSystem.d.ts.map +1 -0
  30. package/src/engine/graphics3/GrassSurfaceSystem.js +1076 -0
  31. package/src/engine/graphics3/GroundCoverSystem.d.ts +33 -0
  32. package/src/engine/graphics3/GroundCoverSystem.d.ts.map +1 -0
  33. package/src/engine/graphics3/GroundCoverSystem.js +58 -0
  34. package/src/engine/network/NetworkSession.d.ts.map +1 -1
  35. package/src/engine/network/NetworkSession.js +372 -110
  36. package/src/engine/network/orchestrator/NetworkPeer.d.ts.map +1 -1
  37. package/src/engine/network/orchestrator/NetworkPeer.js +6 -1
  38. package/src/engine/network/orchestrator/ServerAuthoritativeClient.d.ts.map +1 -1
  39. package/src/engine/network/orchestrator/ServerAuthoritativeClient.js +9 -2
  40. package/src/engine/network/orchestrator/ServerAuthoritativeServer.d.ts.map +1 -1
  41. package/src/engine/network/orchestrator/ServerAuthoritativeServer.js +325 -140
  42. package/src/engine/network/sim/SimActionExecutor.d.ts +4 -1
  43. package/src/engine/network/sim/SimActionExecutor.d.ts.map +1 -1
  44. package/src/engine/network/sim/SimActionExecutor.js +65 -9
  45. package/src/engine/network/state/PredictionHistory.d.ts.map +1 -1
  46. package/src/engine/network/state/PredictionHistory.js +6 -1
  47. package/src/engine/network/time/AdaptiveRenderDelay.d.ts +25 -14
  48. package/src/engine/network/time/AdaptiveRenderDelay.d.ts.map +1 -1
  49. package/src/engine/network/time/AdaptiveRenderDelay.js +38 -20
  50. package/src/engine/network/time/RenderPlayout.d.ts +23 -3
  51. package/src/engine/network/time/RenderPlayout.d.ts.map +1 -1
  52. package/src/engine/network/time/RenderPlayout.js +40 -4
  53. package/src/engine/physics/fluid/ecs/FluidObstacleSystem.d.ts +4 -4
  54. package/src/engine/physics/fluid/obstacle/chunk_fluid_obstacle_record.d.ts +5 -1
  55. package/src/engine/physics/fluid/obstacle/chunk_fluid_obstacle_record.d.ts.map +1 -1
  56. package/src/engine/physics/fluid/obstacle/chunk_fluid_obstacle_record.js +27 -1
  57. package/src/shade/device/shader/ShaderModuleCompiler.d.ts +2 -0
  58. package/src/shade/device/shader/ShaderModuleCompiler.d.ts.map +1 -1
  59. package/src/shade/device/shader/ShaderModuleCompiler.js +25 -2
  60. package/src/shade/playground/grass_surfaces/index.html +75 -0
  61. package/src/shade/playground/grass_surfaces/main.d.ts +2 -0
  62. package/src/shade/playground/grass_surfaces/main.d.ts.map +1 -0
  63. package/src/shade/playground/grass_surfaces/main.js +593 -0
  64. package/src/shade/playground/grass_surfaces/read_grass_surfaces.d.ts +62 -0
  65. package/src/shade/playground/grass_surfaces/read_grass_surfaces.d.ts.map +1 -0
  66. package/src/shade/playground/grass_surfaces/read_grass_surfaces.js +188 -0
  67. package/src/shade/playground/probe_clipmap_box/README.md +5 -1
  68. package/src/shade/playground/probe_clipmap_box/index.html +12 -0
  69. package/src/shade/playground/probe_clipmap_box/main.d.ts.map +1 -1
  70. package/src/shade/playground/probe_clipmap_box/main.js +15 -0
  71. package/src/shade/playground/probe_clipmap_box/scene.d.ts +8 -1
  72. package/src/shade/playground/probe_clipmap_box/scene.d.ts.map +1 -1
  73. package/src/shade/playground/probe_clipmap_box/scene.js +74 -6
  74. package/src/shade/renderer/Renderer.d.ts.map +1 -1
  75. package/src/shade/renderer/Renderer.js +47 -43
  76. package/src/shade/renderer/extension/ViewTextures.d.ts +12 -5
  77. package/src/shade/renderer/extension/ViewTextures.d.ts.map +1 -1
  78. package/src/shade/renderer/extension/ViewTextures.js +19 -5
  79. package/src/shade/renderer/fluid/GPUFluidCascadeStack.d.ts +3 -1
  80. package/src/shade/renderer/fluid/GPUFluidCascadeStack.d.ts.map +1 -1
  81. package/src/shade/renderer/fluid/GPUFluidCascadeStack.js +6 -1
  82. package/src/shade/renderer/fluid/forcing/GPUFluidForcing.d.ts +7 -0
  83. package/src/shade/renderer/fluid/forcing/GPUFluidForcing.d.ts.map +1 -1
  84. package/src/shade/renderer/fluid/forcing/GPUFluidForcing.js +10 -0
  85. package/src/shade/renderer/geometry/sdf/GPUGeometrySDFManager.d.ts +7 -1
  86. package/src/shade/renderer/geometry/sdf/GPUGeometrySDFManager.d.ts.map +1 -1
  87. package/src/shade/renderer/geometry/sdf/GPUGeometrySDFManager.js +46 -15
  88. package/src/shade/renderer/geometry/sdf/bundle/ModelCacheBundle.d.ts +3 -2
  89. package/src/shade/renderer/geometry/sdf/bundle/ModelCacheBundle.d.ts.map +1 -1
  90. package/src/shade/renderer/geometry/sdf/bundle/ModelCacheBundle.js +3 -2
  91. package/src/shade/renderer/geometry/sdf/bundle/model_cache_bundle_sort_morton.d.ts +22 -0
  92. package/src/shade/renderer/geometry/sdf/bundle/model_cache_bundle_sort_morton.d.ts.map +1 -0
  93. package/src/shade/renderer/geometry/sdf/bundle/model_cache_bundle_sort_morton.js +247 -0
  94. package/src/shade/renderer/global_illumination/probe_clipmap/GPUProbeClipmapGI.d.ts +50 -0
  95. package/src/shade/renderer/global_illumination/probe_clipmap/GPUProbeClipmapGI.d.ts.map +1 -1
  96. package/src/shade/renderer/global_illumination/probe_clipmap/GPUProbeClipmapGI.js +101 -0
  97. package/src/shade/renderer/global_illumination/probe_clipmap/ProbeClipmapSettings.d.ts +2 -1
  98. package/src/shade/renderer/global_illumination/probe_clipmap/ProbeClipmapSettings.d.ts.map +1 -1
  99. package/src/shade/renderer/global_illumination/probe_clipmap/ProbeClipmapSettings.js +2 -1
  100. package/src/shade/renderer/global_illumination/probe_clipmap/brick/GPUBrickClipmap.d.ts +8 -0
  101. package/src/shade/renderer/global_illumination/probe_clipmap/brick/GPUBrickClipmap.d.ts.map +1 -1
  102. package/src/shade/renderer/global_illumination/probe_clipmap/brick/GPUBrickClipmap.js +12 -0
  103. package/src/shade/renderer/global_illumination/probe_clipmap/brick/chunk_brick_clipmap_trace.d.ts +12 -6
  104. package/src/shade/renderer/global_illumination/probe_clipmap/brick/chunk_brick_clipmap_trace.d.ts.map +1 -1
  105. package/src/shade/renderer/global_illumination/probe_clipmap/brick/chunk_brick_clipmap_trace.js +35 -29
  106. package/src/shade/renderer/global_illumination/probe_clipmap/debug/graph_probe_clipmap_debug_brick_clipmap.d.ts.map +1 -1
  107. package/src/shade/renderer/global_illumination/probe_clipmap/debug/graph_probe_clipmap_debug_brick_clipmap.js +4 -2
  108. package/src/shade/renderer/global_illumination/probe_clipmap/debug/graph_probe_clipmap_debug_brick_material.d.ts.map +1 -1
  109. package/src/shade/renderer/global_illumination/probe_clipmap/debug/graph_probe_clipmap_debug_brick_material.js +6 -4
  110. package/src/shade/renderer/global_illumination/probe_clipmap/material/GPUBrickMaterial.d.ts.map +1 -1
  111. package/src/shade/renderer/global_illumination/probe_clipmap/material/GPUBrickMaterial.js +2 -1
  112. package/src/shade/renderer/global_illumination/probe_clipmap/material/chunk_brick_material.d.ts +6 -5
  113. package/src/shade/renderer/global_illumination/probe_clipmap/material/chunk_brick_material.d.ts.map +1 -1
  114. package/src/shade/renderer/global_illumination/probe_clipmap/material/chunk_brick_material.js +15 -14
  115. package/src/shade/renderer/global_illumination/probe_clipmap/material/shader_brick_material_gather.d.ts.map +1 -1
  116. package/src/shade/renderer/global_illumination/probe_clipmap/material/shader_brick_material_gather.js +4 -2
  117. package/src/shade/renderer/global_illumination/probe_clipmap/probe/GPUProbeClipmap.d.ts +19 -2
  118. package/src/shade/renderer/global_illumination/probe_clipmap/probe/GPUProbeClipmap.d.ts.map +1 -1
  119. package/src/shade/renderer/global_illumination/probe_clipmap/probe/GPUProbeClipmap.js +128 -10
  120. package/src/shade/renderer/global_illumination/probe_clipmap/probe/PROBE_CLIPMAP.d.ts +19 -1
  121. package/src/shade/renderer/global_illumination/probe_clipmap/probe/PROBE_CLIPMAP.d.ts.map +1 -1
  122. package/src/shade/renderer/global_illumination/probe_clipmap/probe/PROBE_CLIPMAP.js +27 -2
  123. package/src/shade/renderer/global_illumination/probe_clipmap/probe/ProbeClipmapScreenWants.d.ts +19 -11
  124. package/src/shade/renderer/global_illumination/probe_clipmap/probe/ProbeClipmapScreenWants.d.ts.map +1 -1
  125. package/src/shade/renderer/global_illumination/probe_clipmap/probe/ProbeClipmapScreenWants.js +35 -11
  126. package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap.d.ts.map +1 -1
  127. package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap.js +3 -1
  128. package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap_box_cages.d.ts +40 -0
  129. package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap_box_cages.d.ts.map +1 -0
  130. package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap_box_cages.js +174 -0
  131. package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap_hit_material.d.ts +4 -4
  132. package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap_hit_material.js +10 -10
  133. package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap_parallax.d.ts +31 -0
  134. package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap_parallax.d.ts.map +1 -0
  135. package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap_parallax.js +54 -0
  136. package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap_sample_radiance.d.ts +8 -4
  137. package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap_sample_radiance.d.ts.map +1 -1
  138. package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap_sample_radiance.js +10 -21
  139. package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap_want.d.ts +7 -2
  140. package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap_want.d.ts.map +1 -1
  141. package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap_want.js +33 -29
  142. package/src/shade/renderer/global_illumination/probe_clipmap/probe/graph_probe_clipmap_want_meshlets.d.ts +28 -0
  143. package/src/shade/renderer/global_illumination/probe_clipmap/probe/graph_probe_clipmap_want_meshlets.d.ts.map +1 -0
  144. package/src/shade/renderer/global_illumination/probe_clipmap/probe/graph_probe_clipmap_want_meshlets.js +138 -0
  145. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_due.d.ts +13 -9
  146. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_due.d.ts.map +1 -1
  147. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_due.js +18 -11
  148. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_light.js +1 -1
  149. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_relocate.d.ts.map +1 -1
  150. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_relocate.js +4 -2
  151. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_retire.d.ts.map +1 -1
  152. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_retire.js +2 -3
  153. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_schedule.d.ts +5 -3
  154. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_schedule.d.ts.map +1 -1
  155. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_schedule.js +15 -30
  156. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_shade.js +1 -1
  157. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_trace.d.ts.map +1 -1
  158. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_trace.js +4 -2
  159. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_want.d.ts +11 -0
  160. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_want.d.ts.map +1 -1
  161. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_want.js +29 -2
  162. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_want_late.d.ts +40 -0
  163. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_want_late.d.ts.map +1 -0
  164. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_want_late.js +126 -0
  165. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_want_meshlets.d.ts +36 -0
  166. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_want_meshlets.d.ts.map +1 -0
  167. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_want_meshlets.js +221 -0
  168. package/src/shade/renderer/gpu_primitive/age_eviction/chunk_age_eviction.d.ts +40 -0
  169. package/src/shade/renderer/gpu_primitive/age_eviction/chunk_age_eviction.d.ts.map +1 -0
  170. package/src/shade/renderer/gpu_primitive/age_eviction/chunk_age_eviction.js +86 -0
  171. package/src/shade/renderer/grass/blade/GPUGrassBlades.d.ts +135 -0
  172. package/src/shade/renderer/grass/blade/GPUGrassBlades.d.ts.map +1 -0
  173. package/src/shade/renderer/grass/blade/GPUGrassBlades.js +676 -0
  174. package/src/shade/renderer/grass/blade/GRASS_BLADE.d.ts +145 -0
  175. package/src/shade/renderer/grass/blade/GRASS_BLADE.d.ts.map +1 -0
  176. package/src/shade/renderer/grass/blade/GRASS_BLADE.js +179 -0
  177. package/src/shade/renderer/grass/blade/chunk_grass_blade.d.ts +63 -0
  178. package/src/shade/renderer/grass/blade/chunk_grass_blade.d.ts.map +1 -0
  179. package/src/shade/renderer/grass/blade/chunk_grass_blade.js +244 -0
  180. package/src/shade/renderer/grass/blade/chunk_grass_blade_wind.d.ts +58 -0
  181. package/src/shade/renderer/grass/blade/chunk_grass_blade_wind.d.ts.map +1 -0
  182. package/src/shade/renderer/grass/blade/chunk_grass_blade_wind.js +174 -0
  183. package/src/shade/renderer/grass/blade/grass_blade_id_draw.d.ts +25 -0
  184. package/src/shade/renderer/grass/blade/grass_blade_id_draw.d.ts.map +1 -0
  185. package/src/shade/renderer/grass/blade/grass_blade_id_draw.js +133 -0
  186. package/src/shade/renderer/grass/blade/grass_blade_mechanics.d.ts +80 -0
  187. package/src/shade/renderer/grass/blade/grass_blade_mechanics.d.ts.map +1 -0
  188. package/src/shade/renderer/grass/blade/grass_blade_mechanics.js +92 -0
  189. package/src/shade/renderer/grass/blade/grass_blade_resolve.d.ts +29 -0
  190. package/src/shade/renderer/grass/blade/grass_blade_resolve.d.ts.map +1 -0
  191. package/src/shade/renderer/grass/blade/grass_blade_resolve.js +175 -0
  192. package/src/shade/renderer/grass/blade/shader_grass_blade_draw_args.d.ts +14 -0
  193. package/src/shade/renderer/grass/blade/shader_grass_blade_draw_args.d.ts.map +1 -0
  194. package/src/shade/renderer/grass/blade/shader_grass_blade_draw_args.js +45 -0
  195. package/src/shade/renderer/grass/blade/shader_grass_blade_expand.d.ts +61 -0
  196. package/src/shade/renderer/grass/blade/shader_grass_blade_expand.d.ts.map +1 -0
  197. package/src/shade/renderer/grass/blade/shader_grass_blade_expand.js +340 -0
  198. package/src/shade/renderer/grass/blade/shader_grass_cell_count.d.ts +46 -0
  199. package/src/shade/renderer/grass/blade/shader_grass_cell_count.d.ts.map +1 -0
  200. package/src/shade/renderer/grass/blade/shader_grass_cell_count.js +280 -0
  201. package/src/shade/renderer/grass/population/chunk_grass_population.d.ts +60 -0
  202. package/src/shade/renderer/grass/population/chunk_grass_population.d.ts.map +1 -0
  203. package/src/shade/renderer/grass/population/chunk_grass_population.js +171 -0
  204. package/src/shade/renderer/grass/press/GPUGrassPress.d.ts +99 -0
  205. package/src/shade/renderer/grass/press/GPUGrassPress.d.ts.map +1 -0
  206. package/src/shade/renderer/grass/press/GPUGrassPress.js +436 -0
  207. package/src/shade/renderer/grass/press/GRASS_PRESS.d.ts +179 -0
  208. package/src/shade/renderer/grass/press/GRASS_PRESS.d.ts.map +1 -0
  209. package/src/shade/renderer/grass/press/GRASS_PRESS.js +217 -0
  210. package/src/shade/renderer/grass/press/chunk_grass_press.d.ts +65 -0
  211. package/src/shade/renderer/grass/press/chunk_grass_press.d.ts.map +1 -0
  212. package/src/shade/renderer/grass/press/chunk_grass_press.js +296 -0
  213. package/src/shade/renderer/grass/press/shader_grass_press_mark.d.ts +31 -0
  214. package/src/shade/renderer/grass/press/shader_grass_press_mark.d.ts.map +1 -0
  215. package/src/shade/renderer/grass/press/shader_grass_press_mark.js +169 -0
  216. package/src/shade/renderer/grass/press/shader_grass_press_stamp.d.ts +27 -0
  217. package/src/shade/renderer/grass/press/shader_grass_press_stamp.d.ts.map +1 -0
  218. package/src/shade/renderer/grass/press/shader_grass_press_stamp.js +183 -0
  219. package/src/shade/renderer/grass/surface/GPUGrassSurfaces.d.ts +193 -0
  220. package/src/shade/renderer/grass/surface/GPUGrassSurfaces.d.ts.map +1 -0
  221. package/src/shade/renderer/grass/surface/GPUGrassSurfaces.js +1253 -0
  222. package/src/shade/renderer/grass/surface/GRASS_SURFACE.d.ts +211 -0
  223. package/src/shade/renderer/grass/surface/GRASS_SURFACE.d.ts.map +1 -0
  224. package/src/shade/renderer/grass/surface/GRASS_SURFACE.js +241 -0
  225. package/src/shade/renderer/grass/surface/GRASS_SURFACE_VIEW.d.ts +82 -0
  226. package/src/shade/renderer/grass/surface/GRASS_SURFACE_VIEW.d.ts.map +1 -0
  227. package/src/shade/renderer/grass/surface/GRASS_SURFACE_VIEW.js +111 -0
  228. package/src/shade/renderer/grass/surface/chunk_grass_column_cross.d.ts +39 -0
  229. package/src/shade/renderer/grass/surface/chunk_grass_column_cross.d.ts.map +1 -0
  230. package/src/shade/renderer/grass/surface/chunk_grass_column_cross.js +85 -0
  231. package/src/shade/renderer/grass/surface/chunk_grass_directory.d.ts +29 -0
  232. package/src/shade/renderer/grass/surface/chunk_grass_directory.d.ts.map +1 -0
  233. package/src/shade/renderer/grass/surface/chunk_grass_directory.js +112 -0
  234. package/src/shade/renderer/grass/surface/chunk_grass_slot.d.ts +27 -0
  235. package/src/shade/renderer/grass/surface/chunk_grass_slot.d.ts.map +1 -0
  236. package/src/shade/renderer/grass/surface/chunk_grass_slot.js +50 -0
  237. package/src/shade/renderer/grass/surface/chunk_grass_surface_frame.d.ts +21 -0
  238. package/src/shade/renderer/grass/surface/chunk_grass_surface_frame.d.ts.map +1 -0
  239. package/src/shade/renderer/grass/surface/chunk_grass_surface_frame.js +41 -0
  240. package/src/shade/renderer/grass/surface/chunk_grass_surface_window.d.ts +32 -0
  241. package/src/shade/renderer/grass/surface/chunk_grass_surface_window.d.ts.map +1 -0
  242. package/src/shade/renderer/grass/surface/chunk_grass_surface_window.js +136 -0
  243. package/src/shade/renderer/grass/surface/chunk_grass_surfel.d.ts +37 -0
  244. package/src/shade/renderer/grass/surface/chunk_grass_surfel.d.ts.map +1 -0
  245. package/src/shade/renderer/grass/surface/chunk_grass_surfel.js +85 -0
  246. package/src/shade/renderer/grass/surface/chunk_grass_tile.d.ts +25 -0
  247. package/src/shade/renderer/grass/surface/chunk_grass_tile.d.ts.map +1 -0
  248. package/src/shade/renderer/grass/surface/chunk_grass_tile.js +52 -0
  249. package/src/shade/renderer/grass/surface/shader_grass_directory_fill.d.ts +23 -0
  250. package/src/shade/renderer/grass/surface/shader_grass_directory_fill.d.ts.map +1 -0
  251. package/src/shade/renderer/grass/surface/shader_grass_directory_fill.js +87 -0
  252. package/src/shade/renderer/grass/surface/shader_grass_surface_bake.d.ts +43 -0
  253. package/src/shade/renderer/grass/surface/shader_grass_surface_bake.d.ts.map +1 -0
  254. package/src/shade/renderer/grass/surface/shader_grass_surface_bake.js +265 -0
  255. package/src/shade/renderer/grass/surface/shader_grass_surface_bake_command.d.ts +13 -0
  256. package/src/shade/renderer/grass/surface/shader_grass_surface_bake_command.d.ts.map +1 -0
  257. package/src/shade/renderer/grass/surface/shader_grass_surface_bake_command.js +49 -0
  258. package/src/shade/renderer/grass/surface/shader_grass_surface_invalidate.d.ts +62 -0
  259. package/src/shade/renderer/grass/surface/shader_grass_surface_invalidate.d.ts.map +1 -0
  260. package/src/shade/renderer/grass/surface/shader_grass_surface_invalidate.js +162 -0
  261. package/src/shade/renderer/grass/surface/shader_grass_surface_retire.d.ts +40 -0
  262. package/src/shade/renderer/grass/surface/shader_grass_surface_retire.d.ts.map +1 -0
  263. package/src/shade/renderer/grass/surface/shader_grass_surface_retire.js +155 -0
  264. package/src/shade/renderer/grass/surface/shader_grass_surface_schedule.d.ts +19 -0
  265. package/src/shade/renderer/grass/surface/shader_grass_surface_schedule.d.ts.map +1 -0
  266. package/src/shade/renderer/grass/surface/shader_grass_surface_schedule.js +58 -0
  267. package/src/shade/renderer/grass/surface/shader_grass_surface_want.d.ts +30 -0
  268. package/src/shade/renderer/grass/surface/shader_grass_surface_want.d.ts.map +1 -0
  269. package/src/shade/renderer/grass/surface/shader_grass_surface_want.js +251 -0
  270. package/src/shade/renderer/grass/surface/shader_grass_surface_window_count.d.ts +21 -0
  271. package/src/shade/renderer/grass/surface/shader_grass_surface_window_count.d.ts.map +1 -0
  272. package/src/shade/renderer/grass/surface/shader_grass_surface_window_count.js +75 -0
  273. package/src/shade/renderer/postprocess/velocity/graph_add_per_object_velocity.d.ts.map +1 -1
  274. package/src/shade/renderer/postprocess/velocity/graph_add_per_object_velocity.js +4 -23
  275. package/src/shade/renderer/postprocess/velocity/view_velocity_matrices.d.ts +12 -0
  276. package/src/shade/renderer/postprocess/velocity/view_velocity_matrices.d.ts.map +1 -0
  277. package/src/shade/renderer/postprocess/velocity/view_velocity_matrices.js +29 -0
  278. package/src/shade/renderer/rasterize/native/avboit/graph_rasterize_meshes_transparent_avboit.d.ts.map +1 -1
  279. package/src/shade/renderer/rasterize/native/avboit/graph_rasterize_meshes_transparent_avboit.js +22 -0
  280. package/src/shade/renderer/scene/GPUSceneContext.d.ts.map +1 -1
  281. package/src/shade/renderer/scene/GPUSceneContext.js +3 -0
  282. package/src/shade/renderer/scene/GRASS_SURFACE_PARAMS_STRUCT.d.ts +27 -0
  283. package/src/shade/renderer/scene/GRASS_SURFACE_PARAMS_STRUCT.d.ts.map +1 -0
  284. package/src/shade/renderer/scene/GRASS_SURFACE_PARAMS_STRUCT.js +38 -0
  285. package/src/shade/renderer/scene/MESH_GROUND_COVER_STRUCT.d.ts +28 -0
  286. package/src/shade/renderer/scene/MESH_GROUND_COVER_STRUCT.d.ts.map +1 -0
  287. package/src/shade/renderer/scene/MESH_GROUND_COVER_STRUCT.js +58 -0
  288. package/src/shade/renderer/scene/SCENE_DATABASE_SPEC.d.ts.map +1 -1
  289. package/src/shade/renderer/scene/SCENE_DATABASE_SPEC.js +8 -0
  290. package/src/shade/renderer/shader/chunk/geometry/ray/chunk_ray_query_nearest_among.d.ts +37 -0
  291. package/src/shade/renderer/shader/chunk/geometry/ray/chunk_ray_query_nearest_among.d.ts.map +1 -0
  292. package/src/shade/renderer/shader/chunk/geometry/ray/chunk_ray_query_nearest_among.js +148 -0
  293. package/src/shade/renderer/shader/chunk/sdf/chunk_shape_record_line_span.d.ts +20 -0
  294. package/src/shade/renderer/shader/chunk/sdf/chunk_shape_record_line_span.d.ts.map +1 -0
  295. package/src/shade/renderer/shader/chunk/sdf/chunk_shape_record_line_span.js +169 -0
  296. package/src/shade/renderer/texture/atlas/chunk_tile_atlas_slot_origin.d.ts +18 -0
  297. package/src/shade/renderer/texture/atlas/chunk_tile_atlas_slot_origin.d.ts.map +1 -1
  298. package/src/shade/renderer/texture/atlas/chunk_tile_atlas_slot_origin.js +28 -0
  299. package/src/shade/renderer/texture/atlas/tile_atlas_slot_shift.d.ts +13 -0
  300. package/src/shade/renderer/texture/atlas/tile_atlas_slot_shift.d.ts.map +1 -0
  301. package/src/shade/renderer/texture/atlas/tile_atlas_slot_shift.js +22 -0
  302. package/src/shade/renderer/water/GPUWaterRenderer.d.ts.map +1 -1
  303. package/src/shade/renderer/water/GPUWaterRenderer.js +4 -0
  304. package/src/shade/renderer/wind/GPUSceneWind.d.ts +52 -5
  305. package/src/shade/renderer/wind/GPUSceneWind.d.ts.map +1 -1
  306. package/src/shade/renderer/wind/GPUSceneWind.js +164 -8
  307. package/src/shade/renderer/wind/WIND_FIELD_UNIFORM.d.ts +3 -1
  308. package/src/shade/renderer/wind/WIND_FIELD_UNIFORM.d.ts.map +1 -1
  309. package/src/shade/renderer/wind/WIND_FIELD_UNIFORM.js +3 -1
  310. package/src/shade/renderer/wind/chunk_wind_field_sample_cascades.d.ts +2 -1
  311. package/src/shade/renderer/wind/chunk_wind_field_sample_cascades.d.ts.map +1 -1
  312. package/src/shade/renderer/wind/chunk_wind_field_sample_cascades.js +18 -13
  313. package/src/shade/renderer/wind/chunk_wind_field_sample_previous.d.ts +13 -0
  314. package/src/shade/renderer/wind/chunk_wind_field_sample_previous.d.ts.map +1 -0
  315. package/src/shade/renderer/wind/chunk_wind_field_sample_previous.js +23 -0
  316. package/src/shade/renderer/wind/chunk_wind_field_sample_uniform.d.ts +1 -0
  317. package/src/shade/renderer/wind/chunk_wind_field_sample_uniform.d.ts.map +1 -1
  318. package/src/shade/renderer/wind/chunk_wind_field_sample_uniform.js +6 -1
  319. package/src/shade/renderer/wind/wind_field_add_resources.d.ts +11 -0
  320. package/src/shade/renderer/wind/wind_field_add_resources.d.ts.map +1 -1
  321. package/src/shade/renderer/wind/wind_field_add_resources.js +15 -0
  322. package/src/shade/wgsl/emulator/WGSLJavaScriptCompiler.js +1 -1
  323. package/src/shade/wgsl/emulator/WGSLLanguageCore.d.ts.map +1 -1
  324. package/src/shade/wgsl/emulator/WGSLLanguageCore.js +2 -0
@@ -0,0 +1,46 @@
1
+ /**
2
+ * The scene database's `grass_surface_params` table.
3
+ */
4
+ export const GRASS_SURFACE_PARAMS_TABLE: import("../../buffer/table/GPUTypedTableDescriptor.js").GPUTypedTableDescriptor;
5
+ /**
6
+ * Threads in a workgroup of {@link shader_grass_cell_count}.
7
+ *
8
+ * @type {number}
9
+ */
10
+ export const GRASS_CELL_COUNT_WORKGROUP_SIZE: number;
11
+ /**
12
+ * Lattice points along a side of a tile of level 0 of a surface with no lattice bits, as a power of two.
13
+ *
14
+ * @type {number}
15
+ */
16
+ export const GRASS_TILE_COLUMNS_LOG2: number;
17
+ /**
18
+ * Counts the blades each slot of the grass surfaces' pool can owe a view, a thread a slot, and writes the
19
+ * slot's cell (`GRASS_CELL_STRUCT`) for the threads that make them.
20
+ *
21
+ * A slot owes none unless it is baked (or stale, which reads as it was), holds a surfel, lies on a
22
+ * surface something grows on, and its ground, with a blade's length over it, touches the view's frustum
23
+ * and the distances its level serves (`grass_level_ring`).
24
+ *
25
+ * **Which level makes a blade.** A blade is made by the tile of the level whose ring holds its distance
26
+ * from the view. Where that tile is not baked, the baked tile a level up makes it, and where the tile a
27
+ * level up is not baked, the tile a level down makes the blades past its own ring: the cell's flags say
28
+ * which of its neighbours in level are missing, read here from the directory, so no blade is made twice
29
+ * and a ring's edge has no gap while a tile waits for its bake.
30
+ *
31
+ * **How many.** The cell's count is the points of its block of the surface's blade lattice
32
+ * (`chunk_grass_population`) whose rank is under the greatest density any blade in the cell can be shown at
33
+ * (`grass_blade_density`): the surface's densest species, nearest the view, at the steepest the view can
34
+ * look down on the slot's ground. The steepness is bounded by the eye's height over the slot's lowest
35
+ * ground at its nearest, and by how far the slot's normals lean (`GRASS_SLOT_NORMAL_SPREAD`). A blade's
36
+ * thread applies the density where the blade stands; the count only bounds it.
37
+ *
38
+ * `grass_cell_counts` is a list of `settings.slot_capacity` counts, slot `s` at `s`; its count is written
39
+ * by thread 0. Dispatch `ceil(slot_capacity / GRASS_CELL_COUNT_WORKGROUP_SIZE)` groups. A tile whose block
40
+ * is past level `GRASS_POPULATION_BLOCK_LEVEL_MAX` owes none.
41
+ *
42
+ * @type {ComputeShader}
43
+ */
44
+ export const shader_grass_cell_count: ComputeShader;
45
+ import { ComputeShader } from "../../shader/ComputeShader.js";
46
+ //# sourceMappingURL=shader_grass_cell_count.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"shader_grass_cell_count.d.ts","sourceRoot":"","sources":["../../../../../../src/shade/renderer/grass/blade/shader_grass_cell_count.js"],"names":[],"mappings":"AA0CA;;GAEG;AACH,yHAA0F;AAE1F;;;;GAIG;AACH,8CAFU,MAAM,CAEkC;AAElD;;;;GAIG;AACH,sCAFU,MAAM,CAEqD;AAcrE;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,sCAFU,aAAa,CAqLpB;8BA/Q2B,+BAA+B"}
@@ -0,0 +1,280 @@
1
+ import { CAMERA_RESOURCE } from "../../camera/CAMERA_RESOURCE.js";
2
+ import { COLLECTION_U32_STRUCT_READ } from "../../gpu_primitive/COLLECTION_U32_STRUCT_READ.js";
3
+ import { TRANSFORMS_TABLE } from "../../scene/chunk_scene_database_access.js";
4
+ import { SCENE_DATABASE_RESOURCE } from "../../scene/SCENE_DATABASE_RESOURCE.js";
5
+ import { SCENE_DATABASE_SPEC } from "../../scene/SCENE_DATABASE_SPEC.js";
6
+ import { chunk_aabb3_from_transformed_corners } from "../../shader/chunk/geometry/aabb3/chunk_aabb3_from_transformed_corners.js";
7
+ import { chunk_aabb3_intersects_frustum } from "../../shader/chunk/geometry/aabb3/chunk_aabb3_intersects_frustum.js";
8
+ import { CodeChunk } from "../../shader/compiler/CodeChunk.js";
9
+ import { ComputeShader } from "../../shader/ComputeShader.js";
10
+ import { ShaderResourceSetDescriptor } from "../../shader/resource/ShaderResourceSetDescriptor.js";
11
+ import { WebGPUArray } from "../../shader/type/WebGPUArray.js";
12
+ import { chunk_grass_population, GRASS_POPULATION_BLOCK_LEVEL_MAX } from "../population/chunk_grass_population.js";
13
+ import { chunk_grass_directory } from "../surface/chunk_grass_directory.js";
14
+ import { chunk_grass_surface_frame } from "../surface/chunk_grass_surface_frame.js";
15
+ import { chunk_grass_surface_window } from "../surface/chunk_grass_surface_window.js";
16
+ import {
17
+ GRASS_SLOT_HEIGHT_MAX,
18
+ GRASS_SLOT_HEIGHT_MIN,
19
+ GRASS_SLOT_LEVEL_LAYER,
20
+ GRASS_SLOT_NORMAL_SPREAD,
21
+ GRASS_SLOT_STATE,
22
+ GRASS_SLOT_STATE_BAKED,
23
+ GRASS_SLOT_STATE_STALE,
24
+ GRASS_SLOT_SURFACE,
25
+ GRASS_SLOT_SURFEL_COUNT,
26
+ GRASS_SLOT_TILE_X,
27
+ GRASS_SLOT_TILE_Z,
28
+ GRASS_TILE_COLUMNS
29
+ } from "../surface/GRASS_SURFACE.js";
30
+ import {
31
+ GRASS_DIRECTORY_RESOURCE,
32
+ GRASS_POOL_RESOURCE,
33
+ GRASS_SURFACE_VIEW_SETTINGS
34
+ } from "../surface/GRASS_SURFACE_VIEW.js";
35
+ import { chunk_grass_blade } from "./chunk_grass_blade.js";
36
+ import {
37
+ GRASS_CELL_CHILD_MISSING,
38
+ GRASS_CELL_LATTICE_SHIFT,
39
+ GRASS_CELL_PARENT_MISSING,
40
+ GRASS_CELL_STRUCT
41
+ } from "./GRASS_BLADE.js";
42
+
43
+ /**
44
+ * The scene database's `grass_surface_params` table.
45
+ */
46
+ export const GRASS_SURFACE_PARAMS_TABLE = SCENE_DATABASE_SPEC.get('grass_surface_params');
47
+
48
+ /**
49
+ * Threads in a workgroup of {@link shader_grass_cell_count}.
50
+ *
51
+ * @type {number}
52
+ */
53
+ export const GRASS_CELL_COUNT_WORKGROUP_SIZE = 64;
54
+
55
+ /**
56
+ * Lattice points along a side of a tile of level 0 of a surface with no lattice bits, as a power of two.
57
+ *
58
+ * @type {number}
59
+ */
60
+ export const GRASS_TILE_COLUMNS_LOG2 = Math.log2(GRASS_TILE_COLUMNS);
61
+
62
+ const resources = new ShaderResourceSetDescriptor();
63
+
64
+ resources.setImmediate("settings", GRASS_SURFACE_VIEW_SETTINGS);
65
+
66
+ resources.createGroup()
67
+ .add(CAMERA_RESOURCE)
68
+ .add(SCENE_DATABASE_RESOURCE)
69
+ .add(GRASS_POOL_RESOURCE)
70
+ .add(GRASS_DIRECTORY_RESOURCE)
71
+ .addStorageBuffer("grass_cell_counts", COLLECTION_U32_STRUCT_READ, true)
72
+ .addStorageBuffer("grass_cells", WebGPUArray.from(GRASS_CELL_STRUCT), true);
73
+
74
+ /**
75
+ * Counts the blades each slot of the grass surfaces' pool can owe a view, a thread a slot, and writes the
76
+ * slot's cell (`GRASS_CELL_STRUCT`) for the threads that make them.
77
+ *
78
+ * A slot owes none unless it is baked (or stale, which reads as it was), holds a surfel, lies on a
79
+ * surface something grows on, and its ground, with a blade's length over it, touches the view's frustum
80
+ * and the distances its level serves (`grass_level_ring`).
81
+ *
82
+ * **Which level makes a blade.** A blade is made by the tile of the level whose ring holds its distance
83
+ * from the view. Where that tile is not baked, the baked tile a level up makes it, and where the tile a
84
+ * level up is not baked, the tile a level down makes the blades past its own ring: the cell's flags say
85
+ * which of its neighbours in level are missing, read here from the directory, so no blade is made twice
86
+ * and a ring's edge has no gap while a tile waits for its bake.
87
+ *
88
+ * **How many.** The cell's count is the points of its block of the surface's blade lattice
89
+ * (`chunk_grass_population`) whose rank is under the greatest density any blade in the cell can be shown at
90
+ * (`grass_blade_density`): the surface's densest species, nearest the view, at the steepest the view can
91
+ * look down on the slot's ground. The steepness is bounded by the eye's height over the slot's lowest
92
+ * ground at its nearest, and by how far the slot's normals lean (`GRASS_SLOT_NORMAL_SPREAD`). A blade's
93
+ * thread applies the density where the blade stands; the count only bounds it.
94
+ *
95
+ * `grass_cell_counts` is a list of `settings.slot_capacity` counts, slot `s` at `s`; its count is written
96
+ * by thread 0. Dispatch `ceil(slot_capacity / GRASS_CELL_COUNT_WORKGROUP_SIZE)` groups. A tile whose block
97
+ * is past level `GRASS_POPULATION_BLOCK_LEVEL_MAX` owes none.
98
+ *
99
+ * @type {ComputeShader}
100
+ */
101
+ export const shader_grass_cell_count = ComputeShader.from({
102
+ label: "Grass Cell Count",
103
+ resources,
104
+ body: CodeChunk.from(
105
+ //language=WGSL
106
+ `
107
+ fn grass_cell_layer_baked(surface: u32, level_layer: u32, tile: vec2<i32>) -> bool {
108
+ let slot = grass_directory_find(surface, level_layer, tile);
109
+
110
+ if (slot == GRASS_SLOT_NONE) {
111
+ return false;
112
+ }
113
+
114
+ let state = atomicLoad(&grass_pool[grass_slot_record(slot) + ${GRASS_SLOT_STATE}u]);
115
+
116
+ return state == ${GRASS_SLOT_STATE_BAKED}u || state == ${GRASS_SLOT_STATE_STALE}u;
117
+ }
118
+
119
+ fn grass_cell_count(slot: u32, cell: ptr<function, ${GRASS_CELL_STRUCT.wgsl_ref}>) -> u32 {
120
+ let record = grass_slot_record(slot);
121
+ let state = atomicLoad(&grass_pool[record + ${GRASS_SLOT_STATE}u]);
122
+
123
+ if (state != ${GRASS_SLOT_STATE_BAKED}u && state != ${GRASS_SLOT_STATE_STALE}u) {
124
+ return 0u;
125
+ }
126
+
127
+ if (atomicLoad(&grass_pool[record + ${GRASS_SLOT_SURFEL_COUNT}u]) == 0u) {
128
+ return 0u;
129
+ }
130
+
131
+ let surface = atomicLoad(&grass_pool[record + ${GRASS_SLOT_SURFACE}u]);
132
+ let params = ${GRASS_SURFACE_PARAMS_TABLE.marshalling_method_read}(&scene_database, surface);
133
+
134
+ if (params.density <= 0.0 || params.blade_length <= 0.0) {
135
+ return 0u;
136
+ }
137
+
138
+ let level_layer = atomicLoad(&grass_pool[record + ${GRASS_SLOT_LEVEL_LAYER}u]);
139
+ let level = level_layer & 0xFFu;
140
+ let layer = level_layer >> 8u;
141
+
142
+ let block_level = ${GRASS_TILE_COLUMNS_LOG2}u + params.lattice_bits + level;
143
+
144
+ if (block_level > ${GRASS_POPULATION_BLOCK_LEVEL_MAX}u) {
145
+ return 0u;
146
+ }
147
+
148
+ let tile = vec2<i32>(
149
+ bitcast<i32>(atomicLoad(&grass_pool[record + ${GRASS_SLOT_TILE_X}u])),
150
+ bitcast<i32>(atomicLoad(&grass_pool[record + ${GRASS_SLOT_TILE_Z}u])),
151
+ );
152
+
153
+ // the slot's ground, and the grass over it, in the surface's frame
154
+ let edge = grass_level_spacing(settings.finest_spacing, level) * f32(GRASS_TILE_COLUMNS);
155
+ let corner = vec2<f32>(tile) * edge;
156
+
157
+ let ground_low = grass_height_of_key(atomicLoad(&grass_pool[record + ${GRASS_SLOT_HEIGHT_MIN}u]));
158
+ let ground_high = grass_height_of_key(atomicLoad(&grass_pool[record + ${GRASS_SLOT_HEIGHT_MAX}u]));
159
+
160
+ let low = vec3<f32>(corner.x, ground_low, corner.y);
161
+ let high = vec3<f32>(corner.x + edge, ground_high + params.blade_length, corner.y + edge);
162
+
163
+ let frame = grass_surface_frame(${TRANSFORMS_TABLE.marshalling_method_read_field('global')}(&scene_database, surface));
164
+
165
+ let box = aabb3_from_transformed_corners(array<vec3<f32>, 8>(
166
+ vec3<f32>(low.x, low.y, low.z),
167
+ vec3<f32>(high.x, low.y, low.z),
168
+ vec3<f32>(low.x, high.y, low.z),
169
+ vec3<f32>(high.x, high.y, low.z),
170
+ vec3<f32>(low.x, low.y, high.z),
171
+ vec3<f32>(high.x, low.y, high.z),
172
+ vec3<f32>(low.x, high.y, high.z),
173
+ vec3<f32>(high.x, high.y, high.z),
174
+ ), frame);
175
+
176
+ if (!aabb3_intersects_frustum(box, camera.frustum)) {
177
+ return 0u;
178
+ }
179
+
180
+ let eye = grass_world_to_frame(frame, camera.transform[3].xyz);
181
+
182
+ let nearest = length(max(max(low - eye, eye - high), vec3<f32>(0.0)));
183
+ let farthest = length(max(abs(low - eye), abs(high - eye)));
184
+
185
+ // which of the cell's neighbours in level are not there to make their share
186
+ var flags = params.lattice_bits << ${GRASS_CELL_LATTICE_SHIFT}u;
187
+
188
+ let layer_bits = layer << 8u;
189
+
190
+ if (level + 1u >= settings.level_count || !grass_cell_layer_baked(surface, (level + 1u) | layer_bits, tile >> vec2<u32>(1u))) {
191
+ flags |= ${GRASS_CELL_PARENT_MISSING}u;
192
+ }
193
+
194
+ if (level > 0u) {
195
+ for (var quarter = 0u; quarter < 4u; quarter++) {
196
+ let child = tile * 2 + vec2<i32>(i32(quarter & 1u), i32(quarter >> 1u));
197
+
198
+ if (!grass_cell_layer_baked(surface, (level - 1u) | layer_bits, child)) {
199
+ flags |= ${GRASS_CELL_CHILD_MISSING}u << quarter;
200
+ }
201
+ }
202
+ }
203
+
204
+ // the distances it makes blades at: its ring, and its missing neighbours' share on either side
205
+ let ring = grass_level_ring(settings, level, params.blade_length);
206
+ let reach = params.blade_length * settings.focal / settings.shortest_blade;
207
+
208
+ let makes_from = select(ring.x, 0.0, (flags & ${GRASS_CELL_CHILD_MISSING * 15}u) != 0u);
209
+ let makes_to = select(ring.y, reach, (flags & ${GRASS_CELL_PARENT_MISSING}u) != 0u);
210
+
211
+ if (makes_from >= makes_to || nearest >= makes_to || farthest < makes_from) {
212
+ return 0u;
213
+ }
214
+
215
+ // the steepest the view can look at the slot's ground: from over its nearest edge, at its lowest or highest
216
+ let rise = max(abs(eye.y - ground_low), abs(eye.y - ground_high));
217
+ let run = length(max(max(low.xz - eye.xz, eye.xz - high.xz), vec2<f32>(0.0)));
218
+
219
+ let spread = bitcast<f32>(atomicLoad(&grass_pool[record + ${GRASS_SLOT_NORMAL_SPREAD}u]));
220
+
221
+ let sin_elevation = min(rise / max(length(vec2<f32>(rise, run)), 1e-6) + spread, 1.0);
222
+
223
+ // a normal that far from upright is at least this upright: |n - up|² = 2 - 2 n.y
224
+ let ground_up = max(1.0 - 0.5 * spread * spread, 0.0);
225
+
226
+ // the densest it can be shown: the least any blade is drawn at, nearest, and what covers most
227
+ let drawn = grass_blade_drawn_width(settings, params.blade_width_min, nearest);
228
+
229
+ let dense = grass_blade_density(settings, params.density, drawn, params.blade_length_min, nearest, sin_elevation, ground_up);
230
+ let covering = params.cover / drawn;
231
+
232
+ let lattice_side = f32(1u << params.lattice_bits) / settings.finest_spacing;
233
+
234
+ let share = min(dense, covering) / (lattice_side * lattice_side);
235
+
236
+ (*cell).rank = grass_population_block_rank(block_level, tile, surface);
237
+ (*cell).flags = flags;
238
+ (*cell).surface = surface;
239
+ (*cell).level_layer = level_layer;
240
+ (*cell).tile = tile;
241
+ (*cell).ring_inner = ring.x;
242
+ (*cell).ring_outer = ring.y;
243
+
244
+ if (share >= 1.0) {
245
+ return 1u << (2u * block_level);
246
+ }
247
+
248
+ return grass_population_count(block_level, (*cell).rank, grass_population_threshold(share));
249
+ }
250
+
251
+ @compute @workgroup_size(${GRASS_CELL_COUNT_WORKGROUP_SIZE})
252
+ fn main(@builtin(global_invocation_id) id: vec3<u32>) {
253
+ let slot = id.x;
254
+
255
+ if (slot == 0u) {
256
+ grass_cell_counts.count = settings.slot_capacity;
257
+ }
258
+
259
+ if (slot >= settings.slot_capacity) {
260
+ return;
261
+ }
262
+
263
+ var cell: ${GRASS_CELL_STRUCT.wgsl_ref};
264
+
265
+ grass_cell_counts.elements[slot] = grass_cell_count(slot, &cell);
266
+ grass_cells[slot] = cell;
267
+ }
268
+ `, [
269
+ GRASS_CELL_STRUCT.declaration_chunk,
270
+ chunk_aabb3_from_transformed_corners,
271
+ chunk_aabb3_intersects_frustum,
272
+ chunk_grass_surface_frame,
273
+ chunk_grass_surface_window,
274
+ chunk_grass_directory,
275
+ chunk_grass_population,
276
+ chunk_grass_blade,
277
+ TRANSFORMS_TABLE.chunk_read_field('global'),
278
+ GRASS_SURFACE_PARAMS_TABLE.chunk_read,
279
+ ]),
280
+ });
@@ -0,0 +1,60 @@
1
+ /**
2
+ * The level of the blocks the population's order starts from: a block of level `l` is a square of `2^l`
3
+ * lattice points a side, and blocks of this level are ordered each on their own.
4
+ *
5
+ * A rank has two bits a level below this one, 32 in all, so no block above level
6
+ * {@link GRASS_POPULATION_BLOCK_LEVEL_MAX} is enumerated.
7
+ *
8
+ * @type {number}
9
+ */
10
+ export const GRASS_POPULATION_ROOT_LEVEL: number;
11
+ /**
12
+ * The highest level of a block {@link chunk_grass_population} enumerates: the count of a block of the root
13
+ * level does not fit a word.
14
+ *
15
+ * @type {number}
16
+ */
17
+ export const GRASS_POPULATION_BLOCK_LEVEL_MAX: number;
18
+ /**
19
+ * Which points of a lattice are populated, at any density, with no list of them kept: a fixed order of the
20
+ * lattice's points in which every prefix is spread evenly, and the means to walk a block's points in that
21
+ * order.
22
+ *
23
+ * The lattice is the integer points of a plane. A **block** of level `l` at `block` holds the points
24
+ * `[block * 2^l, (block + 1) * 2^l)` on each axis, and has four children of level `l - 1`. Every block puts
25
+ * its children in an order of its own, a hash of the block and a seed. A point's **rank** is read off the
26
+ * orders of the blocks that hold it: the place of the point among its parent's children is the rank's
27
+ * most significant two bits, the place of that parent among its own parent's the next two, up to the block
28
+ * of {@link GRASS_POPULATION_ROOT_LEVEL}. A point is populated at density `t`, a fraction of the lattice's
29
+ * own, when its rank is under `t * 2^32`.
30
+ *
31
+ * Because the first split of any block is the last thing a rank orders by, the `4^m` lowest-ranked points
32
+ * of a block are one in each of its blocks `m` levels down: a thinned population is a stratified one, at
33
+ * every density, and thinning further only removes points. A rank is the lattice's and not a block's:
34
+ * a point has the same rank whichever block it is reached through.
35
+ *
36
+ * ```wgsl
37
+ * fn grass_population_block_rank(level: u32, block: vec2<i32>, seed: u32) -> u32
38
+ * fn grass_population_point(level: u32, block: vec2<i32>, index: u32, seed: u32) -> vec2<i32>
39
+ * fn grass_population_rank(level: u32, block_rank: u32, index: u32) -> u32
40
+ * fn grass_population_count(level: u32, block_rank: u32, threshold: u32) -> u32
41
+ * fn grass_population_threshold(density: f32) -> u32
42
+ * ```
43
+ *
44
+ * `level` is a block's, in `[1, GRASS_POPULATION_BLOCK_LEVEL_MAX]`; `index` counts a block's points in the
45
+ * order of their ranks, from 0, and is under `4^level`.
46
+ *
47
+ * - `grass_population_block_rank`: the bits every rank in the block ends with, those the blocks above it
48
+ * decide: `2 * (GRASS_POPULATION_ROOT_LEVEL - level)` of them.
49
+ * - `grass_population_point`: the lattice point that is the block's `index`-th.
50
+ * - `grass_population_rank`: the rank of the block's `index`-th point.
51
+ * - `grass_population_count`: how many of the block's points have a rank under `threshold`. They are the
52
+ * indices under the count.
53
+ * - `grass_population_threshold`: the threshold of a density, a fraction of the lattice's. At 1 and over it
54
+ * keeps all but the 256 highest ranks of the 2^32, which a `f32` cannot tell from all.
55
+ *
56
+ * @type {CodeChunk}
57
+ */
58
+ export const chunk_grass_population: CodeChunk;
59
+ import { CodeChunk } from "../../shader/compiler/CodeChunk.js";
60
+ //# sourceMappingURL=chunk_grass_population.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chunk_grass_population.d.ts","sourceRoot":"","sources":["../../../../../../src/shade/renderer/grass/population/chunk_grass_population.js"],"names":[],"mappings":"AAGA;;;;;;;;GAQG;AACH,0CAFU,MAAM,CAE8B;AAE9C;;;;;GAKG;AACH,+CAFU,MAAM,CAEgE;AA2BhF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuCG;AACH,qCAFU,SAAS,CAqFjB;0BAzKwB,oCAAoC"}
@@ -0,0 +1,171 @@
1
+ import { chunk_hash_lowbias32 } from "../../shader/chunk/random/chunk_hash_lowbias32.js";
2
+ import { CodeChunk } from "../../shader/compiler/CodeChunk.js";
3
+
4
+ /**
5
+ * The level of the blocks the population's order starts from: a block of level `l` is a square of `2^l`
6
+ * lattice points a side, and blocks of this level are ordered each on their own.
7
+ *
8
+ * A rank has two bits a level below this one, 32 in all, so no block above level
9
+ * {@link GRASS_POPULATION_BLOCK_LEVEL_MAX} is enumerated.
10
+ *
11
+ * @type {number}
12
+ */
13
+ export const GRASS_POPULATION_ROOT_LEVEL = 16;
14
+
15
+ /**
16
+ * The highest level of a block {@link chunk_grass_population} enumerates: the count of a block of the root
17
+ * level does not fit a word.
18
+ *
19
+ * @type {number}
20
+ */
21
+ export const GRASS_POPULATION_BLOCK_LEVEL_MAX = GRASS_POPULATION_ROOT_LEVEL - 1;
22
+
23
+ /**
24
+ * Every order of four children, a child two bits: place `d` of an order is the child `(order >> 2d) & 3`.
25
+ *
26
+ * @returns {number[]} 24 bytes
27
+ */
28
+ function child_orders() {
29
+ const out = [];
30
+
31
+ for (let a = 0; a < 4; a++) {
32
+ for (let b = 0; b < 4; b++) {
33
+ for (let c = 0; c < 4; c++) {
34
+ for (let d = 0; d < 4; d++) {
35
+ if (new Set([a, b, c, d]).size === 4) {
36
+ out.push(a | (b << 2) | (c << 4) | (d << 6));
37
+ }
38
+ }
39
+ }
40
+ }
41
+ }
42
+
43
+ return out;
44
+ }
45
+
46
+ const ORDERS = child_orders();
47
+
48
+ /**
49
+ * Which points of a lattice are populated, at any density, with no list of them kept: a fixed order of the
50
+ * lattice's points in which every prefix is spread evenly, and the means to walk a block's points in that
51
+ * order.
52
+ *
53
+ * The lattice is the integer points of a plane. A **block** of level `l` at `block` holds the points
54
+ * `[block * 2^l, (block + 1) * 2^l)` on each axis, and has four children of level `l - 1`. Every block puts
55
+ * its children in an order of its own, a hash of the block and a seed. A point's **rank** is read off the
56
+ * orders of the blocks that hold it: the place of the point among its parent's children is the rank's
57
+ * most significant two bits, the place of that parent among its own parent's the next two, up to the block
58
+ * of {@link GRASS_POPULATION_ROOT_LEVEL}. A point is populated at density `t`, a fraction of the lattice's
59
+ * own, when its rank is under `t * 2^32`.
60
+ *
61
+ * Because the first split of any block is the last thing a rank orders by, the `4^m` lowest-ranked points
62
+ * of a block are one in each of its blocks `m` levels down: a thinned population is a stratified one, at
63
+ * every density, and thinning further only removes points. A rank is the lattice's and not a block's:
64
+ * a point has the same rank whichever block it is reached through.
65
+ *
66
+ * ```wgsl
67
+ * fn grass_population_block_rank(level: u32, block: vec2<i32>, seed: u32) -> u32
68
+ * fn grass_population_point(level: u32, block: vec2<i32>, index: u32, seed: u32) -> vec2<i32>
69
+ * fn grass_population_rank(level: u32, block_rank: u32, index: u32) -> u32
70
+ * fn grass_population_count(level: u32, block_rank: u32, threshold: u32) -> u32
71
+ * fn grass_population_threshold(density: f32) -> u32
72
+ * ```
73
+ *
74
+ * `level` is a block's, in `[1, GRASS_POPULATION_BLOCK_LEVEL_MAX]`; `index` counts a block's points in the
75
+ * order of their ranks, from 0, and is under `4^level`.
76
+ *
77
+ * - `grass_population_block_rank`: the bits every rank in the block ends with, those the blocks above it
78
+ * decide: `2 * (GRASS_POPULATION_ROOT_LEVEL - level)` of them.
79
+ * - `grass_population_point`: the lattice point that is the block's `index`-th.
80
+ * - `grass_population_rank`: the rank of the block's `index`-th point.
81
+ * - `grass_population_count`: how many of the block's points have a rank under `threshold`. They are the
82
+ * indices under the count.
83
+ * - `grass_population_threshold`: the threshold of a density, a fraction of the lattice's. At 1 and over it
84
+ * keeps all but the 256 highest ranks of the 2^32, which a `f32` cannot tell from all.
85
+ *
86
+ * @type {CodeChunk}
87
+ */
88
+ export const chunk_grass_population = CodeChunk.from(
89
+ //language=WGSL
90
+ `
91
+ const GRASS_POPULATION_ROOT_LEVEL: u32 = ${GRASS_POPULATION_ROOT_LEVEL}u;
92
+
93
+ const GRASS_POPULATION_ORDERS = array<u32, 24>(${ORDERS.map(order => order + "u").join(", ")});
94
+
95
+ // the order a block puts its four children in: child (order >> 2d) & 3 is its d-th
96
+ fn grass_population_order(level: u32, block: vec2<i32>, seed: u32) -> u32 {
97
+ var h = hash_lowbias32(seed ^ (level * 0x9E3779B9u));
98
+
99
+ h = hash_lowbias32(h ^ bitcast<u32>(block.x));
100
+ h = hash_lowbias32(h ^ bitcast<u32>(block.y));
101
+
102
+ return GRASS_POPULATION_ORDERS[h % 24u];
103
+ }
104
+
105
+ fn grass_population_block_rank(level: u32, block: vec2<i32>, seed: u32) -> u32 {
106
+ var rank = 0u;
107
+ var node = block;
108
+
109
+ // a block's place among its parent's children is the most significant of the bits the blocks above decide,
110
+ // its parent's place the next
111
+ for (var l = level; l < GRASS_POPULATION_ROOT_LEVEL; l++) {
112
+ let parent = node >> vec2<u32>(1u);
113
+ let child = u32(node.x & 1) | (u32(node.y & 1) << 1u);
114
+
115
+ let order = grass_population_order(l + 1u, parent, seed);
116
+
117
+ // the place of the child in the order
118
+ var place = 0u;
119
+
120
+ for (var d = 1u; d < 4u; d++) {
121
+ if (((order >> (2u * d)) & 3u) == child) {
122
+ place = d;
123
+ }
124
+ }
125
+
126
+ rank |= place << (2u * (GRASS_POPULATION_ROOT_LEVEL - 1u - l));
127
+
128
+ node = parent;
129
+ }
130
+
131
+ return rank;
132
+ }
133
+
134
+ fn grass_population_point(level: u32, block: vec2<i32>, index: u32, seed: u32) -> vec2<i32> {
135
+ var node = block;
136
+
137
+ // the index's lowest two bits choose among the block's own children, the next two among theirs
138
+ for (var i = 0u; i < GRASS_POPULATION_ROOT_LEVEL; i++) {
139
+ if (i >= level) {
140
+ break;
141
+ }
142
+
143
+ let order = grass_population_order(level - i, node, seed);
144
+ let child = (order >> (2u * ((index >> (2u * i)) & 3u))) & 3u;
145
+
146
+ node = node * 2 + vec2<i32>(i32(child & 1u), i32(child >> 1u));
147
+ }
148
+
149
+ return node;
150
+ }
151
+
152
+ fn grass_population_rank(level: u32, block_rank: u32, index: u32) -> u32 {
153
+ // the index's lowest two bits are the block's own split, the least significant of its own: the index as it is
154
+ return (index << (2u * (GRASS_POPULATION_ROOT_LEVEL - level))) | block_rank;
155
+ }
156
+
157
+ fn grass_population_count(level: u32, block_rank: u32, threshold: u32) -> u32 {
158
+ let shift = 2u * (GRASS_POPULATION_ROOT_LEVEL - level);
159
+
160
+ // the block's own bits under the threshold's, and one more where the threshold's own bits are met and its rest is past the block's
161
+ return (threshold >> shift) + u32((threshold & ((1u << shift) - 1u)) > block_rank);
162
+ }
163
+
164
+ fn grass_population_threshold(density: f32) -> u32 {
165
+ // the largest f32 under 1 is 2^-24 short of it
166
+ return u32(clamp(density, 0.0, 0.99999994) * 4294967296.0);
167
+ }
168
+ `, [
169
+ chunk_hash_lowbias32,
170
+ ]
171
+ );
@@ -0,0 +1,99 @@
1
+ /**
2
+ * The press field on the device (`GRASS_PRESS.js`): the field, its window and clock, and the passes that
3
+ * write it from the scene's fluid obstacles.
4
+ *
5
+ * Each frame: {@link update} once, with the scene's clock; then {@link graph_stamp} for every view that
6
+ * reads the field, before the pass that reads it, which reads the resource it answers with and takes the
7
+ * window from {@link bind}.
8
+ *
9
+ * The obstacles are the GPU fluid's: the rows of its forcing's obstacle table, whose database the passes
10
+ * bind. While a scene has no fluid, or its fluid no obstacle, nothing is stamped and the field keeps what
11
+ * it holds.
12
+ *
13
+ * The field has one window, which follows the first view a frame stamps for. It lies where that view
14
+ * looks: about the eye for a view that looks straight down, and ahead of it, the eye on its near edge, for
15
+ * one that looks level, moved along the way the view looks over the ground by that much of half its side.
16
+ */
17
+ export class GPUGrassPress {
18
+ /**
19
+ * Offer the pipelines the field's passes run — see {@link PipelineEnquiry}.
20
+ *
21
+ * @param {PipelineEnquiry} enquiry
22
+ */
23
+ static enquirePipelines(enquiry: PipelineEnquiry): void;
24
+ /**
25
+ * @param {GraphicsContext} graphics
26
+ */
27
+ constructor(graphics: GraphicsContext);
28
+ /**
29
+ * Whether obstacles press grass. While false nothing is stamped and nothing reads as pressed.
30
+ * @type {boolean}
31
+ */
32
+ enabled: boolean;
33
+ /**
34
+ * A cell's side, metres: how fine the edge of a press is. The window is
35
+ * `GRASS_PRESS_WINDOW_CELLS` of them a side. Changing it empties the field.
36
+ * @type {number}
37
+ */
38
+ spacing: number;
39
+ /**
40
+ * The field on the device. Null before the first {@link update}, and replaced when {@link spacing}
41
+ * changes.
42
+ *
43
+ * @returns {GPUBuffer|null}
44
+ */
45
+ get field_buffer(): any;
46
+ /**
47
+ * The window and clock on the device. Null before the first {@link update}.
48
+ *
49
+ * @returns {GPUBuffer|null}
50
+ */
51
+ get window_buffer(): any;
52
+ /**
53
+ * Begin a frame: move the press's clock on, and make the field if there is none or its cells have
54
+ * another size than {@link spacing}, which leaves it with no press.
55
+ *
56
+ * @param {number} time_delta_seconds how far the scene's clock has moved since the last call
57
+ */
58
+ update(time_delta_seconds: number): void;
59
+ /**
60
+ * Record the frame's stamp, and answer with the field as a resource of `graph` for the passes that
61
+ * read it.
62
+ *
63
+ * The first call of a frame puts the window about its view, lists the fluid's obstacles by the
64
+ * window's tiles, and writes the cells under them. Later calls, other views', record nothing and
65
+ * answer with the same field.
66
+ *
67
+ * Nothing is stamped while the field is off, or `forcing` is null or holds no obstacle.
68
+ *
69
+ * @param {object} options
70
+ * @param {FrameGraph} options.graph
71
+ * @param {GPUViewContext} options.view the view the window follows; its scene is the obstacles' scene
72
+ * @param {GPUFluidForcing|null} options.forcing the scene's GPU fluid forcing, whose obstacle table is read
73
+ * @returns {number} the field, a resource of `graph`
74
+ */
75
+ graph_stamp({ graph, view, forcing }: {
76
+ graph: FrameGraph;
77
+ view: GPUViewContext;
78
+ forcing: GPUFluidForcing | null;
79
+ }): number;
80
+ /**
81
+ * Put the field's window and clock into a dispatch's bindings as `grass_press_window`, which
82
+ * `chunk_grass_press` reads. The field itself, `grass_press`, is the resource {@link graph_stamp}
83
+ * answered with.
84
+ *
85
+ * @param {Object} bindings
86
+ */
87
+ bind(bindings: any): void;
88
+ /**
89
+ * Let go of everything on the device. The field's presses go with it.
90
+ */
91
+ destroy(): void;
92
+ #private;
93
+ }
94
+ export type FrameGraph = import("../../../../engine/graphics/render/frame_graph/FrameGraph.js").FrameGraph;
95
+ export type PipelineEnquiry = import("../../../device/pipeline/PipelineEnquiry.js").PipelineEnquiry;
96
+ export type GPUFluidForcing = import("../../fluid/forcing/GPUFluidForcing.js").GPUFluidForcing;
97
+ export type GraphicsContext = import("../../GraphicsContext.js").GraphicsContext;
98
+ export type GPUViewContext = import("../../view/GPUViewContext.js").GPUViewContext;
99
+ //# sourceMappingURL=GPUGrassPress.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"GPUGrassPress.d.ts","sourceRoot":"","sources":["../../../../../../src/shade/renderer/grass/press/GPUGrassPress.js"],"names":[],"mappings":"AAyCA;;;;;;;;;;;;;;;GAeG;AACH;IAEI;;;;OAIG;IACH,iCAFW,eAAe,QAKzB;IAgFD;;OAEG;IACH,sBAFW,eAAe,EAOzB;IAtFD;;;OAGG;IACH,SAFU,OAAO,CAEF;IAEf;;;;OAIG;IACH,SAFU,MAAM,CAEA;IA6EhB;;;;;OAKG;IACH,wBAEC;IAED;;;;OAIG;IACH,yBAEC;IAED;;;;;OAKG;IACH,2BAFW,MAAM,QAgDhB;IAED;;;;;;;;;;;;;;;OAeG;IACH;QAL+B,KAAK,EAAzB,UAAU;QACc,IAAI,EAA5B,cAAc;QACgB,OAAO,EAArC,eAAe,GAAC,IAAI;QAClB,MAAM,CAiHlB;IAoDD;;;;;;OAMG;IACH,0BAEC;IAED;;OAEG;IACH,gBAWC;;CACJ;yBAlaY,OAAO,8DAA8D,EAAE,UAAU;8BACjF,OAAO,6CAA6C,EAAE,eAAe;8BACrE,OAAO,wCAAwC,EAAE,eAAe;8BAChE,OAAO,0BAA0B,EAAE,eAAe;6BAClD,OAAO,8BAA8B,EAAE,cAAc"}