@woosh/meep-engine 3.69.0 → 3.70.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 (398) hide show
  1. package/CHANGELOG.md +30 -1
  2. package/build/bundle-worker-terrain.js +1 -1
  3. package/package.json +1 -1
  4. package/src/core/bvh8/build/BVH8Converter.d.ts +16 -0
  5. package/src/core/bvh8/build/BVH8Converter.d.ts.map +1 -1
  6. package/src/core/bvh8/build/BVH8Converter.js +64 -37
  7. package/src/core/bvh8/build/bvh8_assign_slots_greedy.d.ts +25 -0
  8. package/src/core/bvh8/build/bvh8_assign_slots_greedy.d.ts.map +1 -0
  9. package/src/core/bvh8/build/bvh8_assign_slots_greedy.js +68 -0
  10. package/src/core/bvh8/build/bvh8_from_proxy.d.ts.map +1 -1
  11. package/src/core/bvh8/build/bvh8_from_proxy.js +2 -33
  12. package/src/core/bvh8/build/bvh8_node_fit_slots.d.ts +22 -0
  13. package/src/core/bvh8/build/bvh8_node_fit_slots.d.ts.map +1 -0
  14. package/src/core/bvh8/build/bvh8_node_fit_slots.js +115 -0
  15. package/src/core/bvh8/bvh8_depth.d.ts +8 -0
  16. package/src/core/bvh8/bvh8_depth.d.ts.map +1 -0
  17. package/src/core/bvh8/bvh8_depth.js +39 -0
  18. package/src/core/math/complex/complex_fft_radix2.d.ts +19 -0
  19. package/src/core/math/complex/complex_fft_radix2.d.ts.map +1 -0
  20. package/src/core/math/complex/complex_fft_radix2.js +71 -0
  21. package/src/engine/graphics3/GPUFluidSystem.d.ts +17 -4
  22. package/src/engine/graphics3/GPUFluidSystem.d.ts.map +1 -1
  23. package/src/engine/graphics3/GPUFluidSystem.js +113 -16
  24. package/src/engine/physics/cloth/playground/wind_main.js +7 -6
  25. package/src/engine/physics/cloth/wind/AbstractClothWind.d.ts +2 -2
  26. package/src/engine/physics/cloth/wind/AbstractClothWind.js +2 -2
  27. package/src/engine/physics/cloth/wind/ClothFluidWind.d.ts +3 -3
  28. package/src/engine/physics/cloth/wind/ClothFluidWind.d.ts.map +1 -1
  29. package/src/engine/physics/cloth/wind/ClothFluidWind.js +7 -9
  30. package/src/engine/physics/cloth/wind/ClothGPUFluidWind.d.ts +10 -10
  31. package/src/engine/physics/cloth/wind/ClothGPUFluidWind.d.ts.map +1 -1
  32. package/src/engine/physics/cloth/wind/ClothGPUFluidWind.js +14 -22
  33. package/src/engine/physics/fluid/FluidAtmosphere.d.ts +16 -2
  34. package/src/engine/physics/fluid/FluidAtmosphere.d.ts.map +1 -1
  35. package/src/engine/physics/fluid/FluidAtmosphere.js +17 -3
  36. package/src/engine/physics/fluid/ecs/FluidEffectorsComponentSerializationAdapter.d.ts +1 -2
  37. package/src/engine/physics/fluid/ecs/FluidEffectorsComponentSerializationAdapter.d.ts.map +1 -1
  38. package/src/engine/physics/fluid/ecs/FluidEffectorsComponentSerializationAdapter.js +1 -2
  39. package/src/engine/physics/fluid/ecs/FluidEffectorsSystem.d.ts +8 -5
  40. package/src/engine/physics/fluid/ecs/FluidEffectorsSystem.d.ts.map +1 -1
  41. package/src/engine/physics/fluid/ecs/FluidEffectorsSystem.js +60 -17
  42. package/src/engine/physics/fluid/effector/AbstractFluidEffector.d.ts +1 -1
  43. package/src/engine/physics/fluid/effector/AbstractFluidEffector.js +1 -1
  44. package/src/engine/physics/fluid/effector/GlobalFluidEffector.d.ts +33 -47
  45. package/src/engine/physics/fluid/effector/GlobalFluidEffector.d.ts.map +1 -1
  46. package/src/engine/physics/fluid/effector/GlobalFluidEffector.js +38 -176
  47. package/src/engine/physics/fluid/effector/GlobalFluidEffectorSerializationAdapter.d.ts +8 -11
  48. package/src/engine/physics/fluid/effector/GlobalFluidEffectorSerializationAdapter.d.ts.map +1 -1
  49. package/src/engine/physics/fluid/effector/GlobalFluidEffectorSerializationAdapter.js +13 -24
  50. package/src/engine/physics/fluid/effector/GlobalFluidEffectorSerializationUpgrader_0_1.d.ts +16 -0
  51. package/src/engine/physics/fluid/effector/GlobalFluidEffectorSerializationUpgrader_0_1.d.ts.map +1 -0
  52. package/src/engine/physics/fluid/effector/GlobalFluidEffectorSerializationUpgrader_0_1.js +35 -0
  53. package/src/engine/physics/fluid/fluid_apply_atmosphere.d.ts +1 -1
  54. package/src/engine/physics/fluid/fluid_apply_atmosphere.js +1 -1
  55. package/src/engine/physics/fluid/turbulence/FLUID_TURBULENCE_TILE.d.ts +28 -0
  56. package/src/engine/physics/fluid/turbulence/FLUID_TURBULENCE_TILE.d.ts.map +1 -0
  57. package/src/engine/physics/fluid/turbulence/FLUID_TURBULENCE_TILE.js +29 -0
  58. package/src/engine/physics/fluid/turbulence/fluid_atmosphere_velocity_at.d.ts +16 -0
  59. package/src/engine/physics/fluid/turbulence/fluid_atmosphere_velocity_at.d.ts.map +1 -0
  60. package/src/engine/physics/fluid/turbulence/fluid_atmosphere_velocity_at.js +49 -0
  61. package/src/engine/physics/fluid/turbulence/fluid_turbulence_inverse_tile_size.d.ts +11 -0
  62. package/src/engine/physics/fluid/turbulence/fluid_turbulence_inverse_tile_size.d.ts.map +1 -0
  63. package/src/engine/physics/fluid/turbulence/fluid_turbulence_inverse_tile_size.js +18 -0
  64. package/src/engine/physics/fluid/turbulence/fluid_turbulence_tile_data.d.ts +25 -0
  65. package/src/engine/physics/fluid/turbulence/fluid_turbulence_tile_data.d.ts.map +1 -0
  66. package/src/engine/physics/fluid/turbulence/fluid_turbulence_tile_data.js +65 -0
  67. package/src/engine/physics/fluid/turbulence/fluid_turbulence_tile_generate.d.ts +56 -0
  68. package/src/engine/physics/fluid/turbulence/fluid_turbulence_tile_generate.d.ts.map +1 -0
  69. package/src/engine/physics/fluid/turbulence/fluid_turbulence_tile_generate.js +313 -0
  70. package/src/engine/physics/fluid/turbulence/fluid_turbulence_tile_sample.d.ts +16 -0
  71. package/src/engine/physics/fluid/turbulence/fluid_turbulence_tile_sample.d.ts.map +1 -0
  72. package/src/engine/physics/fluid/turbulence/fluid_turbulence_tile_sample.js +69 -0
  73. package/src/generation/foliage/mesh/branch_ring_triangulate.d.ts +1 -1
  74. package/src/generation/foliage/mesh/branch_ring_triangulate.js +1 -1
  75. package/src/shade/playground/bvh_repro/README.md +8 -6
  76. package/src/shade/playground/bvh_repro/index.html +125 -124
  77. package/src/shade/playground/bvh_repro/main.js +259 -254
  78. package/src/shade/playground/foliage_wind/foliage_world.d.ts.map +1 -1
  79. package/src/shade/playground/foliage_wind/foliage_world.js +7 -4
  80. package/src/shade/playground/grass_surfaces/main.js +3 -2
  81. package/src/shade/playground/particle_ecs/bonfire_wind.d.ts +23 -13
  82. package/src/shade/playground/particle_ecs/bonfire_wind.d.ts.map +1 -1
  83. package/src/shade/playground/particle_ecs/bonfire_wind.js +30 -33
  84. package/src/shade/playground/skinned_blas_refit/README.md +26 -14
  85. package/src/shade/playground/skinned_blas_refit/shader_blas_audit_leaf_triangles.d.ts +14 -9
  86. package/src/shade/playground/skinned_blas_refit/shader_blas_audit_leaf_triangles.d.ts.map +1 -1
  87. package/src/shade/playground/skinned_blas_refit/shader_blas_audit_leaf_triangles.js +126 -127
  88. package/src/shade/playground/skinned_blas_refit/shader_blas_audit_points.js +95 -95
  89. package/src/shade/playground/skinned_blas_refit/shader_blas_audit_visibility.d.ts +9 -1
  90. package/src/shade/playground/skinned_blas_refit/shader_blas_audit_visibility.d.ts.map +1 -1
  91. package/src/shade/playground/skinned_blas_refit/shader_blas_audit_visibility.js +146 -135
  92. package/src/shade/playground/skinned_blas_refit/verify_clone_leaves.d.ts +6 -6
  93. package/src/shade/playground/skinned_blas_refit/verify_clone_leaves.d.ts.map +1 -1
  94. package/src/shade/playground/skinned_blas_refit/verify_clone_leaves.js +148 -134
  95. package/src/shade/playground/skinned_blas_refit/verify_leaf_triangles.d.ts +11 -8
  96. package/src/shade/playground/skinned_blas_refit/verify_leaf_triangles.d.ts.map +1 -1
  97. package/src/shade/playground/skinned_blas_refit/verify_leaf_triangles.js +342 -202
  98. package/src/shade/playground/skinned_blas_refit/verify_skinned_blas_refit.d.ts +12 -13
  99. package/src/shade/playground/skinned_blas_refit/verify_skinned_blas_refit.d.ts.map +1 -1
  100. package/src/shade/playground/skinned_blas_refit/verify_skinned_blas_refit.js +136 -116
  101. package/src/shade/playground/skinned_blas_refit/verify_traversal_reachability.d.ts +4 -4
  102. package/src/shade/playground/skinned_blas_refit/verify_traversal_reachability.d.ts.map +1 -1
  103. package/src/shade/playground/skinned_blas_refit/verify_traversal_reachability.js +255 -249
  104. package/src/shade/playground/water_surface/main.js +6 -3
  105. package/src/shade/renderer/animation/GPUAnimationManager.js +2 -2
  106. package/src/shade/renderer/animation/skinning/GPUMeshSkinningContext.d.ts.map +1 -1
  107. package/src/shade/renderer/animation/skinning/GPUMeshSkinningContext.js +7 -8
  108. package/src/shade/renderer/fluid/FLUID_FAR_FIELD_STRUCT.d.ts +111 -0
  109. package/src/shade/renderer/fluid/FLUID_FAR_FIELD_STRUCT.d.ts.map +1 -0
  110. package/src/shade/renderer/fluid/FLUID_FAR_FIELD_STRUCT.js +162 -0
  111. package/src/shade/renderer/fluid/GPUFluidCascade.d.ts +37 -8
  112. package/src/shade/renderer/fluid/GPUFluidCascade.d.ts.map +1 -1
  113. package/src/shade/renderer/fluid/GPUFluidCascade.js +149 -47
  114. package/src/shade/renderer/fluid/GPUFluidCascadeStack.d.ts +10 -3
  115. package/src/shade/renderer/fluid/GPUFluidCascadeStack.d.ts.map +1 -1
  116. package/src/shade/renderer/fluid/GPUFluidCascadeStack.js +69 -10
  117. package/src/shade/renderer/fluid/chunk_fluid_far_field.d.ts +19 -0
  118. package/src/shade/renderer/fluid/chunk_fluid_far_field.d.ts.map +1 -0
  119. package/src/shade/renderer/fluid/chunk_fluid_far_field.js +43 -0
  120. package/src/shade/renderer/fluid/coupling/FLUID_CASCADE_PARENT_STRUCT.d.ts +10 -9
  121. package/src/shade/renderer/fluid/coupling/FLUID_CASCADE_PARENT_STRUCT.d.ts.map +1 -1
  122. package/src/shade/renderer/fluid/coupling/FLUID_CASCADE_PARENT_STRUCT.js +14 -12
  123. package/src/shade/renderer/fluid/coupling/FLUID_CASCADE_RESTRICT_STRUCT.d.ts +3 -2
  124. package/src/shade/renderer/fluid/coupling/FLUID_CASCADE_RESTRICT_STRUCT.d.ts.map +1 -1
  125. package/src/shade/renderer/fluid/coupling/FLUID_CASCADE_RESTRICT_STRUCT.js +7 -5
  126. package/src/shade/renderer/fluid/coupling/chunk_fluid_cascade_epilogue.d.ts +17 -9
  127. package/src/shade/renderer/fluid/coupling/chunk_fluid_cascade_epilogue.d.ts.map +1 -1
  128. package/src/shade/renderer/fluid/coupling/chunk_fluid_cascade_epilogue.js +58 -18
  129. package/src/shade/renderer/fluid/coupling/chunk_fluid_cascade_parent.d.ts +23 -11
  130. package/src/shade/renderer/fluid/coupling/chunk_fluid_cascade_parent.d.ts.map +1 -1
  131. package/src/shade/renderer/fluid/coupling/chunk_fluid_cascade_parent.js +371 -335
  132. package/src/shade/renderer/fluid/coupling/shader_fluid_cascade_fill.d.ts.map +1 -1
  133. package/src/shade/renderer/fluid/coupling/shader_fluid_cascade_fill.js +2 -1
  134. package/src/shade/renderer/fluid/coupling/shader_fluid_cascade_ghosts.d.ts.map +1 -1
  135. package/src/shade/renderer/fluid/coupling/shader_fluid_cascade_ghosts.js +109 -108
  136. package/src/shade/renderer/fluid/coupling/shader_fluid_cascade_restrict.d.ts +5 -3
  137. package/src/shade/renderer/fluid/coupling/shader_fluid_cascade_restrict.d.ts.map +1 -1
  138. package/src/shade/renderer/fluid/coupling/shader_fluid_cascade_restrict.js +24 -12
  139. package/src/shade/renderer/fluid/mac/FLUID_MAC_STEP_STRUCT.d.ts +6 -2
  140. package/src/shade/renderer/fluid/mac/FLUID_MAC_STEP_STRUCT.d.ts.map +1 -1
  141. package/src/shade/renderer/fluid/mac/FLUID_MAC_STEP_STRUCT.js +10 -5
  142. package/src/shade/renderer/fluid/mac/FluidMacPasses.d.ts +20 -21
  143. package/src/shade/renderer/fluid/mac/FluidMacPasses.d.ts.map +1 -1
  144. package/src/shade/renderer/fluid/mac/FluidMacPasses.js +453 -427
  145. package/src/shade/renderer/fluid/mac/shader_fluid_mac_advect_correct.d.ts.map +1 -1
  146. package/src/shade/renderer/fluid/mac/shader_fluid_mac_advect_correct.js +2 -1
  147. package/src/shade/renderer/fluid/publish/FluidWindPublish.d.ts +13 -5
  148. package/src/shade/renderer/fluid/publish/FluidWindPublish.d.ts.map +1 -1
  149. package/src/shade/renderer/fluid/publish/FluidWindPublish.js +20 -10
  150. package/src/shade/renderer/fluid/publish/chunk_fluid_wind_publish_cell.d.ts +2 -2
  151. package/src/shade/renderer/fluid/publish/chunk_fluid_wind_publish_cell.js +2 -2
  152. package/src/shade/renderer/fluid/publish/shader_fluid_wind_publish.d.ts +5 -3
  153. package/src/shade/renderer/fluid/publish/shader_fluid_wind_publish.d.ts.map +1 -1
  154. package/src/shade/renderer/fluid/publish/shader_fluid_wind_publish.js +147 -142
  155. package/src/shade/renderer/fluid/query/GPUFluidQueries.js +2 -2
  156. package/src/shade/renderer/geometry/GPUGeometryManager.d.ts.map +1 -1
  157. package/src/shade/renderer/geometry/GPUGeometryManager.js +5 -7
  158. package/src/shade/renderer/geometry/MeshletGeometry.d.ts +4 -1
  159. package/src/shade/renderer/geometry/MeshletGeometry.d.ts.map +1 -1
  160. package/src/shade/renderer/geometry/MeshletGeometry.js +4 -1
  161. package/src/shade/renderer/geometry/MeshletGeometrySerializationAdapter.d.ts +20 -0
  162. package/src/shade/renderer/geometry/MeshletGeometrySerializationAdapter.d.ts.map +1 -1
  163. package/src/shade/renderer/geometry/MeshletGeometrySerializationAdapter.js +35 -3
  164. package/src/shade/renderer/geometry/blas_from_meshlets.d.ts +9 -3
  165. package/src/shade/renderer/geometry/blas_from_meshlets.d.ts.map +1 -1
  166. package/src/shade/renderer/geometry/blas_from_meshlets.js +16 -30
  167. package/src/shade/renderer/geometry/bvh/BLAS8_REFIT_TARGET_STRUCT.d.ts +14 -0
  168. package/src/shade/renderer/geometry/bvh/BLAS8_REFIT_TARGET_STRUCT.d.ts.map +1 -0
  169. package/src/shade/renderer/geometry/bvh/BLAS8_REFIT_TARGET_STRUCT.js +33 -0
  170. package/src/shade/renderer/geometry/bvh/GPUBLASRefitBatch.d.ts +18 -21
  171. package/src/shade/renderer/geometry/bvh/GPUBLASRefitBatch.d.ts.map +1 -1
  172. package/src/shade/renderer/geometry/bvh/GPUBLASRefitBatch.js +78 -158
  173. package/src/shade/renderer/geometry/bvh/GPUGeometryBVHManager.d.ts +18 -39
  174. package/src/shade/renderer/geometry/bvh/GPUGeometryBVHManager.d.ts.map +1 -1
  175. package/src/shade/renderer/geometry/bvh/GPUGeometryBVHManager.js +39 -398
  176. package/src/shade/renderer/geometry/bvh/GPUGeometryMeshletsBVH.d.ts +6 -7
  177. package/src/shade/renderer/geometry/bvh/GPUGeometryMeshletsBVH.d.ts.map +1 -1
  178. package/src/shade/renderer/geometry/bvh/GPUGeometryMeshletsBVH.js +5 -7
  179. package/src/shade/renderer/geometry/bvh/bvh8_build_for_meshlets.d.ts +36 -0
  180. package/src/shade/renderer/geometry/bvh/bvh8_build_for_meshlets.d.ts.map +1 -0
  181. package/src/shade/renderer/geometry/bvh/bvh8_build_for_meshlets.js +179 -0
  182. package/src/shade/renderer/geometry/bvh/meshlet_batch_to_clustered_bvh.d.ts +30 -0
  183. package/src/shade/renderer/geometry/bvh/meshlet_batch_to_clustered_bvh.d.ts.map +1 -0
  184. package/src/shade/renderer/geometry/bvh/meshlet_batch_to_clustered_bvh.js +207 -0
  185. package/src/shade/renderer/geometry/bvh/shader_blas8_refit_batch.d.ts +52 -0
  186. package/src/shade/renderer/geometry/bvh/shader_blas8_refit_batch.d.ts.map +1 -0
  187. package/src/shade/renderer/geometry/bvh/shader_blas8_refit_batch.js +464 -0
  188. package/src/shade/renderer/geometry/meshlet/MeshletBatch.d.ts +12 -0
  189. package/src/shade/renderer/geometry/meshlet/MeshletBatch.d.ts.map +1 -1
  190. package/src/shade/renderer/geometry/meshlet/MeshletBatch.js +37 -0
  191. package/src/shade/renderer/geometry/sdf/bake/shader_mesh_sdf_classify.d.ts.map +1 -1
  192. package/src/shade/renderer/geometry/sdf/bake/shader_mesh_sdf_classify.js +4 -4
  193. package/src/shade/renderer/geometry/sdf/bake/shader_mesh_sdf_evaluate.d.ts.map +1 -1
  194. package/src/shade/renderer/geometry/sdf/bake/shader_mesh_sdf_evaluate.js +2 -2
  195. package/src/shade/renderer/geometry/sdf/chunk_blas_query_band_sdf.d.ts.map +1 -1
  196. package/src/shade/renderer/geometry/sdf/chunk_blas_query_band_sdf.js +2 -2
  197. package/src/shade/renderer/geometry/sdf/shader_sdf_visualize.d.ts.map +1 -1
  198. package/src/shade/renderer/geometry/sdf/shader_sdf_visualize.js +4 -4
  199. package/src/shade/renderer/geometry/sdf/surface/shader_mesh_surface_trace.d.ts.map +1 -1
  200. package/src/shade/renderer/geometry/sdf/surface/shader_mesh_surface_trace.js +2 -2
  201. package/src/shade/renderer/geometry/sr_create_group_RTX.d.ts.map +1 -1
  202. package/src/shade/renderer/geometry/sr_create_group_RTX.js +4 -4
  203. package/src/shade/renderer/global_illumination/brick4/gpu/bake/brick4_bake_basic.d.ts.map +1 -1
  204. package/src/shade/renderer/global_illumination/brick4/gpu/bake/brick4_bake_basic.js +1 -0
  205. package/src/shade/renderer/global_illumination/lpv/bake/GPULightProbeVolumeRenderer.d.ts.map +1 -1
  206. package/src/shade/renderer/global_illumination/lpv/bake/GPULightProbeVolumeRenderer.js +1 -0
  207. package/src/shade/renderer/global_illumination/lpv/placement/graph_generate_probe_locations.d.ts.map +1 -1
  208. package/src/shade/renderer/global_illumination/lpv/placement/graph_generate_probe_locations.js +372 -376
  209. package/src/shade/renderer/global_illumination/probe_clipmap/brick/mesh/MESH_BRICK.d.ts +9 -10
  210. package/src/shade/renderer/global_illumination/probe_clipmap/brick/mesh/MESH_BRICK.d.ts.map +1 -1
  211. package/src/shade/renderer/global_illumination/probe_clipmap/brick/mesh/MESH_BRICK.js +10 -11
  212. package/src/shade/renderer/global_illumination/probe_clipmap/brick/mesh/chunk_mesh_brick_walk.d.ts +2 -2
  213. package/src/shade/renderer/global_illumination/probe_clipmap/brick/mesh/chunk_mesh_brick_walk.js +2 -2
  214. package/src/shade/renderer/global_illumination/probe_clipmap/brick/mesh/shader_mesh_brick_gather.d.ts +12 -8
  215. package/src/shade/renderer/global_illumination/probe_clipmap/brick/mesh/shader_mesh_brick_gather.d.ts.map +1 -1
  216. package/src/shade/renderer/global_illumination/probe_clipmap/brick/mesh/shader_mesh_brick_gather.js +109 -60
  217. package/src/shade/renderer/global_illumination/probe_clipmap/debug/graph_probe_clipmap_debug_mesh_sdf.js +2 -2
  218. package/src/shade/renderer/global_illumination/probe_clipmap/debug/graph_probe_clipmap_debug_mesh_surfaces.js +2 -2
  219. package/src/shade/renderer/gpu_primitive/bvh/BVH_BUFFER_LAYOUT.d.ts +2 -2
  220. package/src/shade/renderer/gpu_primitive/bvh/BVH_BUFFER_LAYOUT.js +70 -70
  221. package/src/shade/renderer/gpu_primitive/bvh/BVH_BUILD_SETTINGS_STRUCT.d.ts +6 -7
  222. package/src/shade/renderer/gpu_primitive/bvh/BVH_BUILD_SETTINGS_STRUCT.d.ts.map +1 -1
  223. package/src/shade/renderer/gpu_primitive/bvh/BVH_BUILD_SETTINGS_STRUCT.js +6 -7
  224. package/src/shade/renderer/gpu_primitive/bvh/graph_bvh_build_lbvh.d.ts +3 -3
  225. package/src/shade/renderer/gpu_primitive/bvh/graph_bvh_build_lbvh.js +3 -3
  226. package/src/shade/renderer/gpu_primitive/bvh/shader_bvh_build_single_workgroup.js +1 -1
  227. package/src/shade/renderer/gpu_primitive/bvh/shader_bvh_emit_hierarchy.d.ts +2 -2
  228. package/src/shade/renderer/gpu_primitive/bvh/shader_bvh_emit_hierarchy.js +3 -3
  229. package/src/shade/renderer/gpu_primitive/bvh8/BVH8_TREE_BUFFER_LAYOUT.d.ts +69 -0
  230. package/src/shade/renderer/gpu_primitive/bvh8/BVH8_TREE_BUFFER_LAYOUT.d.ts.map +1 -0
  231. package/src/shade/renderer/gpu_primitive/bvh8/BVH8_TREE_BUFFER_LAYOUT.js +89 -0
  232. package/src/shade/renderer/gpu_primitive/bvh8/bvh8_encode_from_bvh2.d.ts +41 -0
  233. package/src/shade/renderer/gpu_primitive/bvh8/bvh8_encode_from_bvh2.d.ts.map +1 -0
  234. package/src/shade/renderer/gpu_primitive/bvh8/bvh8_encode_from_bvh2.js +348 -0
  235. package/src/shade/renderer/gpu_primitive/bvh8/check_bvh8_tree.d.ts +34 -0
  236. package/src/shade/renderer/gpu_primitive/bvh8/check_bvh8_tree.d.ts.map +1 -0
  237. package/src/shade/renderer/gpu_primitive/bvh8/check_bvh8_tree.js +291 -0
  238. package/src/shade/renderer/gpu_primitive/bvh8/chunk_bvh8_encode_assign.d.ts +31 -0
  239. package/src/shade/renderer/gpu_primitive/bvh8/chunk_bvh8_encode_assign.d.ts.map +1 -0
  240. package/src/shade/renderer/gpu_primitive/bvh8/chunk_bvh8_encode_assign.js +175 -0
  241. package/src/shade/renderer/gpu_primitive/bvh8/chunk_bvh8_encode_depth.d.ts +27 -0
  242. package/src/shade/renderer/gpu_primitive/bvh8/chunk_bvh8_encode_depth.d.ts.map +1 -0
  243. package/src/shade/renderer/gpu_primitive/bvh8/chunk_bvh8_encode_depth.js +48 -0
  244. package/src/shade/renderer/gpu_primitive/bvh8/chunk_bvh8_encode_gather.d.ts +26 -0
  245. package/src/shade/renderer/gpu_primitive/bvh8/chunk_bvh8_encode_gather.d.ts.map +1 -0
  246. package/src/shade/renderer/gpu_primitive/bvh8/chunk_bvh8_encode_gather.js +118 -0
  247. package/src/shade/renderer/gpu_primitive/bvh8/chunk_bvh8_encode_node.d.ts +22 -0
  248. package/src/shade/renderer/gpu_primitive/bvh8/chunk_bvh8_encode_node.d.ts.map +1 -0
  249. package/src/shade/renderer/gpu_primitive/bvh8/chunk_bvh8_encode_node.js +143 -0
  250. package/src/shade/renderer/gpu_primitive/bvh8/chunk_bvh8_encode_sums.d.ts +36 -0
  251. package/src/shade/renderer/gpu_primitive/bvh8/chunk_bvh8_encode_sums.d.ts.map +1 -0
  252. package/src/shade/renderer/gpu_primitive/bvh8/chunk_bvh8_encode_sums.js +97 -0
  253. package/src/shade/renderer/gpu_primitive/bvh8/graph_bvh8_encode_from_bvh2.d.ts +49 -0
  254. package/src/shade/renderer/gpu_primitive/bvh8/graph_bvh8_encode_from_bvh2.d.ts.map +1 -0
  255. package/src/shade/renderer/gpu_primitive/bvh8/graph_bvh8_encode_from_bvh2.js +265 -0
  256. package/src/shade/renderer/gpu_primitive/bvh8/shader_bvh8_encode_assign.d.ts +37 -0
  257. package/src/shade/renderer/gpu_primitive/bvh8/shader_bvh8_encode_assign.d.ts.map +1 -0
  258. package/src/shade/renderer/gpu_primitive/bvh8/shader_bvh8_encode_assign.js +109 -0
  259. package/src/shade/renderer/gpu_primitive/bvh8/shader_bvh8_encode_count.d.ts +15 -0
  260. package/src/shade/renderer/gpu_primitive/bvh8/shader_bvh8_encode_count.d.ts.map +1 -0
  261. package/src/shade/renderer/gpu_primitive/bvh8/shader_bvh8_encode_count.js +85 -0
  262. package/src/shade/renderer/gpu_primitive/bvh8/shader_bvh8_encode_count_single_workgroup.d.ts +26 -0
  263. package/src/shade/renderer/gpu_primitive/bvh8/shader_bvh8_encode_count_single_workgroup.d.ts.map +1 -0
  264. package/src/shade/renderer/gpu_primitive/bvh8/shader_bvh8_encode_count_single_workgroup.js +200 -0
  265. package/src/shade/renderer/gpu_primitive/bvh8/shader_bvh8_encode_parents.d.ts +19 -0
  266. package/src/shade/renderer/gpu_primitive/bvh8/shader_bvh8_encode_parents.d.ts.map +1 -0
  267. package/src/shade/renderer/gpu_primitive/bvh8/shader_bvh8_encode_parents.js +81 -0
  268. package/src/shade/renderer/gpu_primitive/bvh8/shader_bvh8_encode_write.d.ts +14 -0
  269. package/src/shade/renderer/gpu_primitive/bvh8/shader_bvh8_encode_write.d.ts.map +1 -0
  270. package/src/shade/renderer/gpu_primitive/bvh8/shader_bvh8_encode_write.js +101 -0
  271. package/src/shade/renderer/gpu_primitive/bvh8/verify_gpu_bvh8_encode.d.ts +19 -0
  272. package/src/shade/renderer/gpu_primitive/bvh8/verify_gpu_bvh8_encode.d.ts.map +1 -0
  273. package/src/shade/renderer/gpu_primitive/bvh8/verify_gpu_bvh8_encode.js +361 -0
  274. package/src/shade/renderer/grass/surface/shader_grass_surface_bake.d.ts.map +1 -1
  275. package/src/shade/renderer/grass/surface/shader_grass_surface_bake.js +5 -6
  276. package/src/shade/renderer/lightmap/GPULightMap.d.ts.map +1 -1
  277. package/src/shade/renderer/lightmap/GPULightMap.js +1 -0
  278. package/src/shade/renderer/path_tracer/accumulating/AccumulatingPathTracer.d.ts.map +1 -1
  279. package/src/shade/renderer/path_tracer/accumulating/AccumulatingPathTracer.js +1 -0
  280. package/src/shade/renderer/path_tracer/graph_path_trace_scene.d.ts.map +1 -1
  281. package/src/shade/renderer/path_tracer/graph_path_trace_scene.js +1 -0
  282. package/src/shade/renderer/scene/GPUInstancesAccelerationStructure.d.ts +8 -4
  283. package/src/shade/renderer/scene/GPUInstancesAccelerationStructure.d.ts.map +1 -1
  284. package/src/shade/renderer/scene/GPUInstancesAccelerationStructure.js +60 -33
  285. package/src/shade/renderer/scene/verify_gpu_tlas_build.d.ts +6 -6
  286. package/src/shade/renderer/scene/verify_gpu_tlas_build.d.ts.map +1 -1
  287. package/src/shade/renderer/scene/verify_gpu_tlas_build.js +23 -53
  288. package/src/shade/renderer/shader/chunk/bvh/bvh8/webgpu/BVH8_INODE_STRUCT.d.ts +3 -1
  289. package/src/shade/renderer/shader/chunk/bvh/bvh8/webgpu/BVH8_INODE_STRUCT.d.ts.map +1 -1
  290. package/src/shade/renderer/shader/chunk/bvh/bvh8/webgpu/BVH8_INODE_STRUCT.js +5 -3
  291. package/src/shade/renderer/shader/chunk/bvh/bvh8/webgpu/BVH8_MAX_DEPTH.d.ts +28 -0
  292. package/src/shade/renderer/shader/chunk/bvh/bvh8/webgpu/BVH8_MAX_DEPTH.d.ts.map +1 -0
  293. package/src/shade/renderer/shader/chunk/bvh/bvh8/webgpu/BVH8_MAX_DEPTH.js +29 -0
  294. package/src/shade/renderer/shader/chunk/bvh/bvh8/webgpu/chunk_bvh8_node_grid.d.ts +25 -0
  295. package/src/shade/renderer/shader/chunk/bvh/bvh8/webgpu/chunk_bvh8_node_grid.d.ts.map +1 -0
  296. package/src/shade/renderer/shader/chunk/bvh/bvh8/webgpu/chunk_bvh8_node_grid.js +97 -0
  297. package/src/shade/renderer/shader/chunk/bvh/bvh8/webgpu/chunk_bvh8_node_intersect.d.ts +8 -0
  298. package/src/shade/renderer/shader/chunk/bvh/bvh8/webgpu/chunk_bvh8_node_intersect.d.ts.map +1 -1
  299. package/src/shade/renderer/shader/chunk/bvh/bvh8/webgpu/chunk_bvh8_node_intersect.js +23 -14
  300. package/src/shade/renderer/shader/chunk/bvh/bvh8/webgpu/chunk_bvh8_node_slot_distances.d.ts +36 -0
  301. package/src/shade/renderer/shader/chunk/bvh/bvh8/webgpu/chunk_bvh8_node_slot_distances.d.ts.map +1 -0
  302. package/src/shade/renderer/shader/chunk/bvh/bvh8/webgpu/chunk_bvh8_node_slot_distances.js +222 -0
  303. package/src/shade/renderer/shader/chunk/bvh/bvh8/webgpu/chunk_bvh8_ray_direction_rcp.d.ts +20 -0
  304. package/src/shade/renderer/shader/chunk/bvh/bvh8/webgpu/chunk_bvh8_ray_direction_rcp.d.ts.map +1 -0
  305. package/src/shade/renderer/shader/chunk/bvh/bvh8/webgpu/chunk_bvh8_ray_direction_rcp.js +30 -0
  306. package/src/shade/renderer/shader/chunk/bvh/bvh8/webgpu/chunk_bvh8_tree_read.d.ts +30 -0
  307. package/src/shade/renderer/shader/chunk/bvh/bvh8/webgpu/chunk_bvh8_tree_read.d.ts.map +1 -0
  308. package/src/shade/renderer/shader/chunk/bvh/bvh8/webgpu/chunk_bvh8_tree_read.js +91 -0
  309. package/src/shade/renderer/shader/chunk/bvh/bvh8/webgpu/chunk_bvh8_waiting_slots.d.ts +23 -0
  310. package/src/shade/renderer/shader/chunk/bvh/bvh8/webgpu/chunk_bvh8_waiting_slots.d.ts.map +1 -0
  311. package/src/shade/renderer/shader/chunk/bvh/bvh8/webgpu/chunk_bvh8_waiting_slots.js +40 -0
  312. package/src/shade/renderer/shader/chunk/geometry/ray/chunk_ray_query_blas_nearest.d.ts +22 -0
  313. package/src/shade/renderer/shader/chunk/geometry/ray/chunk_ray_query_blas_nearest.d.ts.map +1 -1
  314. package/src/shade/renderer/shader/chunk/geometry/ray/chunk_ray_query_blas_nearest.js +121 -70
  315. package/src/shade/renderer/shader/chunk/geometry/ray/chunk_ray_query_blas_occluded.d.ts +13 -1
  316. package/src/shade/renderer/shader/chunk/geometry/ray/chunk_ray_query_blas_occluded.d.ts.map +1 -1
  317. package/src/shade/renderer/shader/chunk/geometry/ray/chunk_ray_query_blas_occluded.js +117 -61
  318. package/src/shade/renderer/shader/chunk/geometry/ray/chunk_ray_query_nearest.d.ts +21 -0
  319. package/src/shade/renderer/shader/chunk/geometry/ray/chunk_ray_query_nearest.d.ts.map +1 -1
  320. package/src/shade/renderer/shader/chunk/geometry/ray/chunk_ray_query_nearest.js +111 -72
  321. package/src/shade/renderer/shader/chunk/geometry/ray/chunk_ray_query_nearest_among.d.ts +1 -2
  322. package/src/shade/renderer/shader/chunk/geometry/ray/chunk_ray_query_nearest_among.d.ts.map +1 -1
  323. package/src/shade/renderer/shader/chunk/geometry/ray/chunk_ray_query_nearest_among.js +83 -54
  324. package/src/shade/renderer/shader/chunk/geometry/ray/chunk_ray_query_occluded.d.ts +14 -0
  325. package/src/shade/renderer/shader/chunk/geometry/ray/chunk_ray_query_occluded.d.ts.map +1 -1
  326. package/src/shade/renderer/shader/chunk/geometry/ray/chunk_ray_query_occluded.js +92 -60
  327. package/src/shade/renderer/shader/chunk/sdf/chunk_point_query_blas_nearest.d.ts +22 -0
  328. package/src/shade/renderer/shader/chunk/sdf/chunk_point_query_blas_nearest.d.ts.map +1 -1
  329. package/src/shade/renderer/shader/chunk/sdf/chunk_point_query_blas_nearest.js +153 -106
  330. package/src/shade/renderer/shader/chunk/sdf/chunk_scene_point_query_nearest.d.ts +21 -0
  331. package/src/shade/renderer/shader/chunk/sdf/chunk_scene_point_query_nearest.d.ts.map +1 -1
  332. package/src/shade/renderer/shader/chunk/sdf/chunk_scene_point_query_nearest.js +115 -74
  333. package/src/shade/renderer/shader/chunk/sdf/chunk_scene_sdf_raymarch.d.ts +5 -2
  334. package/src/shade/renderer/shader/chunk/sdf/chunk_scene_sdf_raymarch.d.ts.map +1 -1
  335. package/src/shade/renderer/shader/chunk/sdf/chunk_scene_sdf_raymarch.js +89 -63
  336. package/src/shade/renderer/shader/chunk/sdf/chunk_sdf_query_distance.d.ts +15 -0
  337. package/src/shade/renderer/shader/chunk/sdf/chunk_sdf_query_distance.d.ts.map +1 -1
  338. package/src/shade/renderer/shader/chunk/sdf/chunk_sdf_query_distance.js +108 -63
  339. package/src/shade/renderer/shadow/sdf/chunk_ray_query_sdf_raycast.d.ts +14 -0
  340. package/src/shade/renderer/shadow/sdf/chunk_ray_query_sdf_raycast.d.ts.map +1 -1
  341. package/src/shade/renderer/shadow/sdf/chunk_ray_query_sdf_raycast.js +94 -60
  342. package/src/shade/renderer/shadow/sdf/graph_draw_sdf_shadows.d.ts.map +1 -1
  343. package/src/shade/renderer/shadow/sdf/graph_draw_sdf_shadows.js +4 -4
  344. package/src/shade/renderer/volumetrics/graph_build_volumetrics.js +2 -2
  345. package/src/shade/renderer/water/query/shader_water_surface_query.d.ts.map +1 -1
  346. package/src/shade/renderer/water/query/shader_water_surface_query.js +227 -227
  347. package/src/shade/renderer/water/surface/particles/chunk_water_particle_step.d.ts.map +1 -1
  348. package/src/shade/renderer/water/surface/particles/chunk_water_particle_step.js +7 -4
  349. package/src/shade/renderer/water/surface/particles/shader_water_particles.js +2 -2
  350. package/src/shade/renderer/wind/GPUSceneWind.d.ts +36 -4
  351. package/src/shade/renderer/wind/GPUSceneWind.d.ts.map +1 -1
  352. package/src/shade/renderer/wind/GPUSceneWind.js +150 -4
  353. package/src/shade/renderer/wind/WIND_FIELD_STRUCT.d.ts +9 -3
  354. package/src/shade/renderer/wind/WIND_FIELD_STRUCT.d.ts.map +1 -1
  355. package/src/shade/renderer/wind/WIND_FIELD_STRUCT.js +13 -3
  356. package/src/shade/renderer/wind/WIND_FIELD_UNIFORM.d.ts +6 -6
  357. package/src/shade/renderer/wind/WIND_FIELD_UNIFORM.js +6 -6
  358. package/src/shade/renderer/wind/chunk_fluid_turbulence.d.ts +39 -0
  359. package/src/shade/renderer/wind/chunk_fluid_turbulence.d.ts.map +1 -0
  360. package/src/shade/renderer/wind/chunk_fluid_turbulence.js +63 -0
  361. package/src/shade/renderer/wind/chunk_wind_field_sample_cascades.d.ts +10 -7
  362. package/src/shade/renderer/wind/chunk_wind_field_sample_cascades.d.ts.map +1 -1
  363. package/src/shade/renderer/wind/chunk_wind_field_sample_cascades.js +34 -11
  364. package/src/shade/renderer/wind/chunk_wind_field_sample_uniform.d.ts +2 -2
  365. package/src/shade/renderer/wind/chunk_wind_field_sample_uniform.js +2 -2
  366. package/src/shade/renderer/wind/wind_field_add_resources.d.ts +6 -4
  367. package/src/shade/renderer/wind/wind_field_add_resources.d.ts.map +1 -1
  368. package/src/shade/renderer/wind/wind_field_add_resources.js +9 -6
  369. package/src/shade/renderer/geometry/bvh/BLAS_REFIT_TARGET_STRUCT.d.ts +0 -18
  370. package/src/shade/renderer/geometry/bvh/BLAS_REFIT_TARGET_STRUCT.d.ts.map +0 -1
  371. package/src/shade/renderer/geometry/bvh/BLAS_REFIT_TARGET_STRUCT.js +0 -50
  372. package/src/shade/renderer/geometry/bvh/bvh2_derive_topology.d.ts +0 -23
  373. package/src/shade/renderer/geometry/bvh/bvh2_derive_topology.d.ts.map +0 -1
  374. package/src/shade/renderer/geometry/bvh/bvh2_derive_topology.js +0 -87
  375. package/src/shade/renderer/geometry/bvh/shader_blas_refit_batch.d.ts +0 -42
  376. package/src/shade/renderer/geometry/bvh/shader_blas_refit_batch.d.ts.map +0 -1
  377. package/src/shade/renderer/geometry/bvh/shader_blas_refit_batch.js +0 -141
  378. package/src/shade/renderer/geometry/bvh/shader_blas_refit_batch_seed.d.ts +0 -21
  379. package/src/shade/renderer/geometry/bvh/shader_blas_refit_batch_seed.d.ts.map +0 -1
  380. package/src/shade/renderer/geometry/bvh/shader_blas_refit_batch_seed.js +0 -75
  381. package/src/shade/renderer/geometry/meshlet_batch_to_bvh.d.ts +0 -17
  382. package/src/shade/renderer/geometry/meshlet_batch_to_bvh.d.ts.map +0 -1
  383. package/src/shade/renderer/geometry/meshlet_batch_to_bvh.js +0 -247
  384. package/src/shade/renderer/shader/chunk/bvh/bvh8/webgpu/chunk_bvh8_ray_query_blas_occlusion.d.ts +0 -7
  385. package/src/shade/renderer/shader/chunk/bvh/bvh8/webgpu/chunk_bvh8_ray_query_blas_occlusion.d.ts.map +0 -1
  386. package/src/shade/renderer/shader/chunk/bvh/bvh8/webgpu/chunk_bvh8_ray_query_blas_occlusion.js +0 -226
  387. package/src/shade/renderer/shader/chunk/light/lpv/chunk_lpv_mask_visibility_via_rays.d.ts +0 -8
  388. package/src/shade/renderer/shader/chunk/light/lpv/chunk_lpv_mask_visibility_via_rays.d.ts.map +0 -1
  389. package/src/shade/renderer/shader/chunk/light/lpv/chunk_lpv_mask_visibility_via_rays.js +0 -45
  390. package/src/shade/renderer/shader/chunk/light/sample/chunk_ray_sample_light.d.ts +0 -3
  391. package/src/shade/renderer/shader/chunk/light/sample/chunk_ray_sample_light.d.ts.map +0 -1
  392. package/src/shade/renderer/shader/chunk/light/sample/chunk_ray_sample_light.js +0 -105
  393. package/src/shade/renderer/shadow/sdf/chunk_ray_query_sdf_distance.d.ts +0 -6
  394. package/src/shade/renderer/shadow/sdf/chunk_ray_query_sdf_distance.d.ts.map +0 -1
  395. package/src/shade/renderer/shadow/sdf/chunk_ray_query_sdf_distance.js +0 -86
  396. package/src/shade/renderer/shadow/sdf/chunk_ray_query_sdf_raycast_traversal_count.d.ts +0 -2
  397. package/src/shade/renderer/shadow/sdf/chunk_ray_query_sdf_raycast_traversal_count.d.ts.map +0 -1
  398. package/src/shade/renderer/shadow/sdf/chunk_ray_query_sdf_raycast_traversal_count.js +0 -136
@@ -0,0 +1,361 @@
1
+ import { BVH8 } from "../../../../core/bvh8/BVH8.js";
2
+ import { bvh8_depth } from "../../../../core/bvh8/bvh8_depth.js";
3
+ import { FrameGraph } from "../../../../engine/graphics/render/frame_graph/FrameGraph.js";
4
+ import { ShadeGPUCommandContext } from "../../../device/ShadeGPUCommandContext.js";
5
+ import { GPUFrameRecorder } from "../../../device/timing/profile/GPUFrameRecorder.js";
6
+ import { graph_inspect_gpu_buffer } from "../../buffer/graph_inspect_gpu_buffer.js";
7
+ import { BVH8_TLAS_MAX_DEPTH } from "../../shader/chunk/bvh/bvh8/webgpu/BVH8_MAX_DEPTH.js";
8
+ import { graph_import_typed_buffer } from "../../shader/graph/graph_import_typed_buffer.js";
9
+ import { f32, u32 } from "../../shader/type/WEBGPU_WGSL_PRIMITIVE_TYPES.js";
10
+ import { WebGPUArray } from "../../shader/type/WebGPUArray.js";
11
+ import { bvh_buffer_size } from "../bvh/BVH_BUFFER_LAYOUT.js";
12
+ import { graph_bvh_build_lbvh } from "../bvh/graph_bvh_build_lbvh.js";
13
+ import {
14
+ BVH8_TREE_HEADER_WORDS,
15
+ BVH8_TREE_NODE_STRIDE_WORDS,
16
+ BVH8_TREE_ORDER_OFFSET_WORD,
17
+ bvh8_tree_buffer_size
18
+ } from "./BVH8_TREE_BUFFER_LAYOUT.js";
19
+ import { bvh8_encode_from_bvh2 } from "./bvh8_encode_from_bvh2.js";
20
+ import { graph_bvh8_encode_from_bvh2 } from "./graph_bvh8_encode_from_bvh2.js";
21
+
22
+ // The cases whose passes are timed: the most leaves the one-workgroup recordings take, the fewest the
23
+ // multi-pass ones do, and a hundred thousand.
24
+ const TIMED = ['n=1024 scattered', 'n=1025 scattered', 'n=100003 scattered'];
25
+
26
+ // what the output holds before the encode, so that a word it should have written and did not shows
27
+ const UNWRITTEN = 0xDEADBEEF;
28
+
29
+ /**
30
+ * @param {number} seed
31
+ * @returns {function(): number} LCG, so a failing case is reproducible
32
+ */
33
+ function make_random(seed) {
34
+ let state = seed >>> 0;
35
+
36
+ return () => (state = (state * 1664525 + 1013904223) >>> 0);
37
+ }
38
+
39
+ /**
40
+ * The leaf sets one run covers: the shapes `verify_gpu_bvh_build` builds, for what each does to the
41
+ * binary tree the encode is handed — an ordinary cloud, leaves no Morton code tells apart, which
42
+ * make the deepest trees and boxes whose centres cost every slot the same, and boxes with no volume.
43
+ *
44
+ * @returns {{name: string, count: number, make: function(function(): number, number): {low: number[], high: number[]}}[]}
45
+ */
46
+ function cases() {
47
+ /**
48
+ * A box around a random point.
49
+ * @param {number} spread
50
+ * @returns {function(function(): number): {low: number[], high: number[]}}
51
+ */
52
+ function scattered(spread) {
53
+ return random => {
54
+ const unit = () => (random() / 0x100000000) * 2 - 1;
55
+
56
+ const centre = [unit() * spread, unit() * spread, unit() * spread];
57
+ const half = [0.5 + Math.abs(unit()), 0.5 + Math.abs(unit()), 0.5 + Math.abs(unit())];
58
+
59
+ return {
60
+ low: centre.map((c, a) => c - half[a]),
61
+ high: centre.map((c, a) => c + half[a]),
62
+ };
63
+ };
64
+ }
65
+
66
+ /**
67
+ * A box with no volume at all — a point.
68
+ * @param {function(): number} random
69
+ * @returns {{low: number[], high: number[]}}
70
+ */
71
+ function degenerate(random) {
72
+ const unit = () => (random() / 0x100000000) * 2 - 1;
73
+
74
+ const point = [unit() * 50, unit() * 50, unit() * 50];
75
+
76
+ return { low: point.slice(), high: point.slice() };
77
+ }
78
+
79
+ const shapes = [
80
+ ['scattered', scattered(100)],
81
+ ['coincident', () => ({ low: [1, 2, 3], high: [4, 5, 6] })],
82
+ ['clustered', scattered(0.0004)],
83
+ ['degenerate', degenerate],
84
+ ['mixed', (random, i) => (i % 2 === 0 ? { low: [0, 0, 0], high: [0, 0, 0] } : scattered(100)(random))],
85
+ ];
86
+
87
+ // Counts either side of every boundary the encode has: its 64-wide workgroups, the four nodes a
88
+ // thread of the one-workgroup encode takes, and the 1,024 leaves that encode stops at.
89
+ const counts = [1, 2, 3, 4, 5, 8, 9, 63, 64, 65, 66, 1023, 1024, 1025, 1026, 100003];
90
+
91
+ const result = [];
92
+
93
+ for (const count of counts) {
94
+ for (const [shape_name, make] of shapes) {
95
+ // every shape where a case costs nothing; above that an ordinary cloud and the one that
96
+ // makes the deepest tree
97
+ if (count > 200 && shape_name !== 'scattered' && shape_name !== 'coincident') {
98
+ continue;
99
+ }
100
+
101
+ result.push({ name: `n=${count} ${shape_name}`, count, make });
102
+ }
103
+ }
104
+
105
+ return result;
106
+ }
107
+
108
+ /**
109
+ * @param {{count: number, make: function}} test_case
110
+ * @returns {{bounds: Float32Array, payload: Uint32Array, scene: Float32Array}}
111
+ */
112
+ function build_input(test_case) {
113
+ const { count, make } = test_case;
114
+
115
+ const random = make_random(0x1234567 ^ (count * 2654435761));
116
+
117
+ const bounds = new Float32Array(count * 6);
118
+ const payload = new Uint32Array(count);
119
+
120
+ for (let i = 0; i < count; i++) {
121
+ const box = make(random, i);
122
+
123
+ bounds.set([...box.low, ...box.high], i * 6);
124
+
125
+ // sparse, unordered rows — never the leaf index, so a mixed-up payload shows
126
+ payload[i] = 11 + i * 7;
127
+ }
128
+
129
+ const scene = new Float32Array(6);
130
+
131
+ scene.set([Infinity, Infinity, Infinity, -Infinity, -Infinity, -Infinity]);
132
+
133
+ for (let i = 0; i < count; i++) {
134
+ for (let axis = 0; axis < 3; axis++) {
135
+ scene[axis] = Math.min(scene[axis], bounds[i * 6 + axis]);
136
+ scene[3 + axis] = Math.max(scene[3 + axis], bounds[i * 6 + 3 + axis]);
137
+ }
138
+ }
139
+
140
+ return { bounds, payload, scene };
141
+ }
142
+
143
+ /**
144
+ * Hold what the device encoded to what {@link bvh8_encode_from_bvh2} makes of the same binary tree.
145
+ *
146
+ * @param {number} count
147
+ * @param {Uint32Array} tree the binary tree the device built, as words
148
+ * @param {Uint32Array} encoded the BVH8 the device made of it, as words
149
+ * @returns {{problems: string[], node_count: number, depth: number}}
150
+ */
151
+ function check(count, tree, encoded) {
152
+ const problems = [];
153
+
154
+ const expected = new Uint32Array(bvh8_tree_buffer_size(count) / Uint32Array.BYTES_PER_ELEMENT).fill(UNWRITTEN);
155
+
156
+ const node_count = bvh8_encode_from_bvh2(expected, Uint32Array.from(tree), count);
157
+
158
+ const order_offset = expected[BVH8_TREE_ORDER_OFFSET_WORD];
159
+
160
+ let differing = 0;
161
+
162
+ for (let word = 0; word < expected.length; word++) {
163
+ if (encoded[word] === expected[word]) {
164
+ continue;
165
+ }
166
+
167
+ differing++;
168
+
169
+ if (differing > 4) {
170
+ continue;
171
+ }
172
+
173
+ let where = `header word ${word}`;
174
+
175
+ if (word >= order_offset + count) {
176
+ where = `word ${word}, past the tree`;
177
+ } else if (word >= order_offset) {
178
+ where = `payload ${word - order_offset}`;
179
+ } else if (word >= BVH8_TREE_HEADER_WORDS) {
180
+ const at = word - BVH8_TREE_HEADER_WORDS;
181
+
182
+ where = `node ${Math.floor(at / BVH8_TREE_NODE_STRIDE_WORDS)} word ${at % BVH8_TREE_NODE_STRIDE_WORDS}`;
183
+ }
184
+
185
+ problems.push(`${where}: the device wrote 0x${(encoded[word] >>> 0).toString(16)}, the reference 0x${expected[word].toString(16)}`);
186
+ }
187
+
188
+ if (differing > 4) {
189
+ problems.push(`… ${differing} words differ in all`);
190
+ }
191
+
192
+ // the depth a walk's stack has to hold, of the reference: the device's tree is that tree or has failed above
193
+ const bvh8 = new BVH8();
194
+
195
+ bvh8.nodes.fromArrayBuffer(
196
+ expected.buffer.slice(BVH8_TREE_HEADER_WORDS * 4, (BVH8_TREE_HEADER_WORDS + node_count * BVH8_TREE_NODE_STRIDE_WORDS) * 4),
197
+ node_count
198
+ );
199
+
200
+ return { problems, node_count, depth: bvh8_depth(bvh8) };
201
+ }
202
+
203
+ /**
204
+ * On-device verification of the BVH8 encode.
205
+ *
206
+ * For each of a set of leaf sets it builds the binary tree as the scene's is built
207
+ * (`graph_bvh_build_lbvh`), encodes it ({@link graph_bvh8_encode_from_bvh2}), reads both back, and
208
+ * holds the encoded tree to {@link bvh8_encode_from_bvh2} run over the binary tree the device built:
209
+ * every word of the header, the nodes and the payloads, and the words past them left alone. The
210
+ * counts sit either side of where the encode changes recording and of its workgroups' edges.
211
+ *
212
+ * It reports each tree's depth against what a walk's stack holds, and the per-pass GPU time of the
213
+ * build and the encode together at three counts: one workgroup's worth of leaves, one leaf more —
214
+ * the same work as many dispatches — and a hundred thousand.
215
+ *
216
+ * One graph and one submission per case, as `verify_gpu_bvh_build` has it.
217
+ *
218
+ * @param {GraphicsContext} graphics
219
+ */
220
+ export function verify_gpu_bvh8_encode(graphics) {
221
+ for (const test_case of cases()) {
222
+ run_case(graphics, test_case);
223
+ }
224
+ }
225
+
226
+ /**
227
+ * @param {GraphicsContext} graphics
228
+ * @param {{name: string, count: number, make: function}} test_case
229
+ */
230
+ function run_case(graphics, test_case) {
231
+ const { count, name } = test_case;
232
+
233
+ const graph = new FrameGraph(`verify gpu bvh8 encode/${name}`);
234
+
235
+ const cmd = ShadeGPUCommandContext.create(graphics, `verify/gpu bvh8 encode/${name}`);
236
+
237
+ /** @type {GPUFrameRecorder|null} */
238
+ let recorder = null;
239
+
240
+ if (TIMED.includes(name)) {
241
+ recorder = new GPUFrameRecorder(0, performance.now());
242
+
243
+ recorder.enable_work_capture();
244
+
245
+ cmd.enable_profiling(recorder, 0);
246
+ }
247
+
248
+ const storage_usage = GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_SRC;
249
+
250
+ const input = build_input(test_case);
251
+
252
+ const leaf_bounds = graph_import_typed_buffer({
253
+ graph, type: WebGPUArray.from(f32, count * 6), value: input.bounds,
254
+ label: `verify bvh8 bounds ${name}`, usage: storage_usage
255
+ });
256
+
257
+ const leaf_payload = graph_import_typed_buffer({
258
+ graph, type: WebGPUArray.from(u32, count), value: input.payload,
259
+ label: `verify bvh8 payload ${name}`, usage: storage_usage
260
+ });
261
+
262
+ const scene_bounds = graph_import_typed_buffer({
263
+ graph, type: WebGPUArray.from(f32, 6), value: input.scene,
264
+ label: `verify bvh8 scene bounds ${name}`, usage: storage_usage
265
+ });
266
+
267
+ const tree_words = bvh_buffer_size(count) / Uint32Array.BYTES_PER_ELEMENT;
268
+
269
+ const nodes = graph_import_typed_buffer({
270
+ graph,
271
+ type: WebGPUArray.from(u32, tree_words),
272
+ value: new Uint32Array(tree_words),
273
+ label: `verify bvh8 binary tree ${name}`,
274
+ usage: GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_SRC | GPUBufferUsage.COPY_DST,
275
+ });
276
+
277
+ const out_words = bvh8_tree_buffer_size(count) / Uint32Array.BYTES_PER_ELEMENT;
278
+
279
+ const out = graph_import_typed_buffer({
280
+ graph,
281
+ type: WebGPUArray.from(u32, out_words),
282
+ value: new Uint32Array(out_words).fill(UNWRITTEN),
283
+ label: `verify bvh8 tree ${name}`,
284
+ usage: GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_SRC | GPUBufferUsage.COPY_DST,
285
+ });
286
+
287
+ const built = graph_bvh_build_lbvh({
288
+ graph, leaf_bounds, leaf_payload, scene_bounds, element_count: count, nodes,
289
+ });
290
+
291
+ const encoded_tree = graph_bvh8_encode_from_bvh2({
292
+ graph, tree: built.nodes, leaf_count: count, out,
293
+ });
294
+
295
+ /** @type {Uint32Array|undefined} */
296
+ let tree;
297
+ /** @type {Uint32Array|undefined} */
298
+ let encoded;
299
+
300
+ function validate() {
301
+ if (tree === undefined || encoded === undefined) {
302
+ // wait for both readbacks
303
+ return;
304
+ }
305
+
306
+ const result = check(count, tree, encoded);
307
+
308
+ const headline = `${name} — ${result.node_count} nodes, depth ${result.depth}/${BVH8_TLAS_MAX_DEPTH}`;
309
+
310
+ if (result.problems.length === 0) {
311
+ console.log(`%c[BVH8] PASS ${headline}`, 'color: #0c0');
312
+ } else {
313
+ console.error(`[BVH8] FAIL ${headline}\n ${result.problems.join('\n ')}`);
314
+ }
315
+
316
+ if (result.depth > BVH8_TLAS_MAX_DEPTH) {
317
+ console.warn(`[BVH8] ${name}: the tree is deeper than a walk's stack holds`);
318
+ }
319
+ }
320
+
321
+ graph_inspect_gpu_buffer({
322
+ graph, type: WebGPUArray.from(u32, tree_words), buffer: built.nodes,
323
+ callback([data]) {
324
+ tree = data;
325
+ validate();
326
+ }
327
+ });
328
+
329
+ graph_inspect_gpu_buffer({
330
+ graph, type: WebGPUArray.from(u32, out_words), buffer: encoded_tree,
331
+ callback([data]) {
332
+ encoded = data;
333
+ validate();
334
+ }
335
+ });
336
+
337
+ if (recorder !== null) {
338
+ // subscribed before the graph runs, so each pass is attributed to the node that opened it
339
+ recorder.attach_graph(graph);
340
+ }
341
+
342
+ cmd.encodeGraph(graph);
343
+ cmd.finish();
344
+
345
+ if (recorder !== null) {
346
+ const captured = recorder;
347
+
348
+ // once the timestamps have been read back, which is after the submission resolves
349
+ cmd.profiling_absorbed.then(() => {
350
+ const frame = captured.close(performance.now());
351
+
352
+ console.log(`[BVH8] GPU timings — ${name}`);
353
+ console.table(frame.spans.map(span => ({
354
+ label: span.label,
355
+ duration_ms: span.duration_ns * 1e-6,
356
+ dispatches: span.work?.dispatch_count ?? 0,
357
+ invocations: span.work?.invocation_count ?? 0
358
+ })));
359
+ });
360
+ }
361
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"shader_grass_surface_bake.d.ts","sourceRoot":"","sources":["../../../../../../src/shade/renderer/grass/surface/shader_grass_surface_bake.js"],"names":[],"mappings":"AAyCA;;GAEG;AACH,uHAAsF;AAEtF;;;;;;GAMG;AACH,0CAFU,YAAY,CAIS;AAa/B;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,wCAFU,aAAa,CA2KpB;6BAxP0B,mCAAmC;8BAHlC,+BAA+B"}
1
+ {"version":3,"file":"shader_grass_surface_bake.d.ts","sourceRoot":"","sources":["../../../../../../src/shade/renderer/grass/surface/shader_grass_surface_bake.js"],"names":[],"mappings":"AAyCA;;GAEG;AACH,uHAAsF;AAEtF;;;;;;GAMG;AACH,0CAFU,YAAY,CAIS;AAa/B;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,wCAFU,aAAa,CA0KpB;6BAvP0B,mCAAmC;8BAHlC,+BAA+B"}
@@ -3,7 +3,7 @@ import { COLLECTION_U32_STRUCT_READ } from "../../gpu_primitive/COLLECTION_U32_S
3
3
  import { TRANSFORMS_TABLE } from "../../scene/chunk_scene_database_access.js";
4
4
  import { MESH_GROUND_COVER_FLAG_MEMBER } from "../../scene/MESH_GROUND_COVER_STRUCT.js";
5
5
  import { SCENE_DATABASE_SPEC } from "../../scene/SCENE_DATABASE_SPEC.js";
6
- import { BVH_NULL_NODE_DEFINITION } from "../../shader/chunk/bvh/BVH_NULL_NODE_DEFINITION.js";
6
+ import { chunk_bvh8_tree_read } from "../../shader/chunk/bvh/bvh8/webgpu/chunk_bvh8_tree_read.js";
7
7
  import { chunk_geometry_read_triangle_vertices } from "../../shader/chunk/geometry/format/chunk_geometry_read_triangle_vertices.js";
8
8
  import { chunk_compute_normal_matrix_from_m4 } from "../../shader/chunk/geometry/mat4/chunk_compute_normal_matrix_from_m4.js";
9
9
  import { chunk_offset_ray } from "../../shader/chunk/geometry/ray/chunk_offset_ray.js";
@@ -150,16 +150,15 @@ fn main(
150
150
  // the surfel's height, and how far its normal is from the frame's up axis
151
151
  var found = vec2<f32>(0.0);
152
152
 
153
- if (tlas.root != BVH_NULL_NODE) {
153
+ if (bvh8_tree_leaf_count(&tlas) != 0u) {
154
154
  grass_bake_surface = surface;
155
155
 
156
156
  let frame = grass_surface_frame(${TRANSFORMS_TABLE.marshalling_method_read_field('global')}(&scene_database, surface));
157
157
  let up = frame[1].xyz;
158
158
 
159
159
  // the scene's reach along the frame's up axis: its box's centre, and the box's half extent along it
160
- let bounds = tlas.nodes[tlas.root].bounds;
161
- let low = vec3<f32>(bounds[0], bounds[1], bounds[2]);
162
- let high = vec3<f32>(bounds[3], bounds[4], bounds[5]);
160
+ let low = bvh8_tree_bounds_low(&tlas);
161
+ let high = bvh8_tree_bounds_high(&tlas);
163
162
  let half_reach = dot(0.5 * (high - low), abs(up));
164
163
  let top = dot(0.5 * (high + low), up) + half_reach;
165
164
 
@@ -247,7 +246,7 @@ fn main(
247
246
  }
248
247
  }
249
248
  `, [
250
- BVH_NULL_NODE_DEFINITION,
249
+ chunk_bvh8_tree_read,
251
250
  RAY_STRUCT.declaration_chunk,
252
251
  chunk_folded_workgroup_index,
253
252
  chunk_compute_normal_matrix_from_m4,
@@ -1 +1 @@
1
- {"version":3,"file":"GPULightMap.d.ts","sourceRoot":"","sources":["../../../../../src/shade/renderer/lightmap/GPULightMap.js"],"names":[],"mappings":"AAoBA;IAgCI;;;OAGG;IACH,+BA6CC;IA/ED;;;OAGG;IACH,WAFU,iBAAiB,GAAC,IAAI,CAEf;IACjB;;;OAGG;IACH,cAFU,iBAAiB,GAAC,IAAI,CAEZ;IACpB;;;OAGG;IACH,cAFU,iBAAiB,GAAC,IAAI,CAEZ;IAEpB;;;OAGG;IACH,aAFU,iBAAiB,GAAC,IAAI,CAEb;IAEnB;;;OAGG;IACH,yBAEC;IA2ED;;;;OAIG;IACH,wEAmCC;IA6BD;;OAEG;IACH,oBA+DC;IAED,iBA4EC;IAED;;;;OAIG;IACH,kEAQC;;CAEJ;kCA9ViC,iCAAiC"}
1
+ {"version":3,"file":"GPULightMap.d.ts","sourceRoot":"","sources":["../../../../../src/shade/renderer/lightmap/GPULightMap.js"],"names":[],"mappings":"AAoBA;IAgCI;;;OAGG;IACH,+BA6CC;IA/ED;;;OAGG;IACH,WAFU,iBAAiB,GAAC,IAAI,CAEf;IACjB;;;OAGG;IACH,cAFU,iBAAiB,GAAC,IAAI,CAEZ;IACpB;;;OAGG;IACH,cAFU,iBAAiB,GAAC,IAAI,CAEZ;IAEpB;;;OAGG;IACH,aAFU,iBAAiB,GAAC,IAAI,CAEb;IAEnB;;;OAGG;IACH,yBAEC;IA2ED;;;;OAIG;IACH,wEAmCC;IA6BD;;OAEG;IACH,oBAgEC;IAED,iBA4EC;IAED;;;;OAIG;IACH,kEAQC;;CAEJ;kCA/ViC,iCAAiC"}
@@ -238,6 +238,7 @@ export class GPULightMap {
238
238
  sParticipatingMediaNoise: graphics.samplers.obtain(PARTICIPATING_MEDIA_NOISE_SAMPLER_DESCRIPTOR),
239
239
  wind_field: scene_ctx.wind.uniform,
240
240
  wind_field_atlas: scene_ctx.wind.atlas.texture,
241
+ fluid_turbulence: scene_ctx.wind.turbulence,
241
242
 
242
243
  tlas: scene_ctx.tlas.buffer,
243
244
  blas_lookup: scene_ctx.geometries.blas.buffer_metadata,
@@ -1 +1 @@
1
- {"version":3,"file":"AccumulatingPathTracer.d.ts","sourceRoot":"","sources":["../../../../../../src/shade/renderer/path_tracer/accumulating/AccumulatingPathTracer.js"],"names":[],"mappings":"AAsBA;;;;;;;;;;;;;;GAcG;AACH;IA8EI;;;OAGG;IACH,sBAFW,eAAe,EAkBzB;IAhGD;;;;OAIG;IACH,kBAFU,MAAM,CAEO;IAEvB;;;;OAIG;IACH,wBAFU,MAAM,CAEc;IAE9B;;;;OAIG;IACH,eAFU,OAAO,CAEK;IA+NtB;;;;;;;OAOG;IACH,+BAgBC;IAED;;;;;;;OAOG;IACH;QAJmC,IAAI,EAA5B,cAAc;QACM,KAAK,EAAzB,UAAU;QACR,MAAM,CA8JlB;;CACJ;yBA7cY,OAAO,8DAA8D,EAAE,UAAU;8BAIjF,OAAO,0BAA0B,EAAE,eAAe;6BAClD,OAAO,8BAA8B,EAAE,cAAc"}
1
+ {"version":3,"file":"AccumulatingPathTracer.d.ts","sourceRoot":"","sources":["../../../../../../src/shade/renderer/path_tracer/accumulating/AccumulatingPathTracer.js"],"names":[],"mappings":"AAsBA;;;;;;;;;;;;;;GAcG;AACH;IA8EI;;;OAGG;IACH,sBAFW,eAAe,EAkBzB;IAhGD;;;;OAIG;IACH,kBAFU,MAAM,CAEO;IAEvB;;;;OAIG;IACH,wBAFU,MAAM,CAEc;IAE9B;;;;OAIG;IACH,eAFU,OAAO,CAEK;IA+NtB;;;;;;;OAOG;IACH,+BAgBC;IAED;;;;;;;OAOG;IACH;QAJmC,IAAI,EAA5B,cAAc;QACM,KAAK,EAAzB,UAAU;QACR,MAAM,CA+JlB;;CACJ;yBA9cY,OAAO,8DAA8D,EAAE,UAAU;8BAIjF,OAAO,0BAA0B,EAAE,eAAe;6BAClD,OAAO,8BAA8B,EAAE,cAAc"}
@@ -429,6 +429,7 @@ export class AccumulatingPathTracer {
429
429
  sParticipatingMediaNoise: graphics.samplers.obtain(PARTICIPATING_MEDIA_NOISE_SAMPLER_DESCRIPTOR),
430
430
  wind_field: scene_ctx.wind.uniform,
431
431
  wind_field_atlas: scene_ctx.wind.atlas.texture,
432
+ fluid_turbulence: scene_ctx.wind.turbulence,
432
433
 
433
434
  settings,
434
435
  camera: view.camera.gpu_buffer,
@@ -1 +1 @@
1
- {"version":3,"file":"graph_path_trace_scene.d.ts","sourceRoot":"","sources":["../../../../../src/shade/renderer/path_tracer/graph_path_trace_scene.js"],"names":[],"mappings":"AA0GA;;;;;;GAMG;AACH;IAJ+B,KAAK;IACD,IAAI;IAC1B,MAAM,CAyFlB"}
1
+ {"version":3,"file":"graph_path_trace_scene.d.ts","sourceRoot":"","sources":["../../../../../src/shade/renderer/path_tracer/graph_path_trace_scene.js"],"names":[],"mappings":"AA0GA;;;;;;GAMG;AACH;IAJ+B,KAAK;IACD,IAAI;IAC1B,MAAM,CA0FlB"}
@@ -178,6 +178,7 @@ export function graph_path_trace_scene({
178
178
  sParticipatingMediaNoise: graphics.samplers.obtain(PARTICIPATING_MEDIA_NOISE_SAMPLER_DESCRIPTOR),
179
179
  wind_field: scene_ctx.wind.uniform,
180
180
  wind_field_atlas: scene_ctx.wind.atlas.texture,
181
+ fluid_turbulence: scene_ctx.wind.turbulence,
181
182
 
182
183
  common_uniforms: rt_uniforms,
183
184
  camera: view.camera.gpu_buffer,
@@ -1,5 +1,9 @@
1
1
  /**
2
- * Top-Level Acceleration Structure (TLAS)
2
+ * Top-Level Acceleration Structure (TLAS): a BVH8 over the scene's instances, in the layout of
3
+ * {@link BVH8_TREE_BUFFER_LAYOUT}. A leaf's payload is a row of the scene database's `meshes` table.
4
+ *
5
+ * A build makes a binary tree over the rows' world boxes (`graph_bvh_build_lbvh`), which lives for
6
+ * the length of the build, and encodes it three levels to a node (`graph_bvh8_encode_from_bvh2`).
3
7
  */
4
8
  export class GPUInstancesAccelerationStructure {
5
9
  /**
@@ -49,9 +53,9 @@ export class GPUInstancesAccelerationStructure {
49
53
  */
50
54
  invalidate(): void;
51
55
  /**
52
- * The bounds of everything in the tree, read back from its root node: the box the GPU built
53
- * the tree under, the union of every live row's bounds as the bounds pass derived them — the
54
- * whole scene, whoever placed what. For a consumer that sizes work by the scene once, a probe
56
+ * The bounds of everything in the tree, read back from its header: the box the GPU built the
57
+ * tree under, the union of every live row's bounds as the bounds pass derived them — the whole
58
+ * scene, whoever placed what. For a consumer that sizes work by the scene once, a probe
55
59
  * placement or a bake; a frame-loop reader wants the scene database's readback service.
56
60
  *
57
61
  * Resolves once the copy has landed and been mapped, which is after the device has finished
@@ -1 +1 @@
1
- {"version":3,"file":"GPUInstancesAccelerationStructure.d.ts","sourceRoot":"","sources":["../../../../../src/shade/renderer/scene/GPUInstancesAccelerationStructure.js"],"names":[],"mappings":"AAoCA;;GAEG;AACH;IAEI;;;;OAIG;IACH,iCAFW,eAAe,QAKzB;IA+DD;;;OAGG;IACH,sBAFW,eAAe,EAqBzB;IAzED,cAIC;IAOD;;;OAGG;IACH,wBAEC;IAmED;;;;OAIG;IACH,oBAFW,MAAM,QAUhB;IAED;;;;;OAKG;IACH,uBAFW,MAAM,QAUhB;IAED;;;;OAIG;IACH,uBAFW,MAAM,QAOhB;IA8CD;;;;OAIG;IACH;;;OAGG;IACH,mBAEC;IAiGD;;;;;;;;;;;;OAYG;IACH,0BAHW,YAAY,GAAC,YAAY,GAAC,MAAM,EAAE,GAChC,QAAQ,OAAO,CAAC,CA0C5B;IAED;;;OAGG;IACH,wDAFW,sBAAsB,QAMhC;IAED;;;;;;OAMG;IACH,mDAHW,sBAAsB,QAShC;IAED;;;OAGG;IACH,gBAKC;;CACJ;8BApaY,OAAO,0CAA0C,EAAE,eAAe;8BAClE,OAAO,uBAAuB,EAAE,eAAe;uCATrB,wCAAwC"}
1
+ {"version":3,"file":"GPUInstancesAccelerationStructure.d.ts","sourceRoot":"","sources":["../../../../../src/shade/renderer/scene/GPUInstancesAccelerationStructure.js"],"names":[],"mappings":"AAqDA;;;;;;GAMG;AACH;IAEI;;;;OAIG;IACH,iCAFW,eAAe,QAMzB;IA+DD;;;OAGG;IACH,sBAFW,eAAe,EAoBzB;IAxED,cAIC;IAOD;;;OAGG;IACH,wBAEC;IAkED;;;;OAIG;IACH,oBAFW,MAAM,QAUhB;IAED;;;;;OAKG;IACH,uBAFW,MAAM,QAUhB;IAED;;;;OAIG;IACH,uBAFW,MAAM,QAOhB;IA8CD;;;;OAIG;IACH;;;OAGG;IACH,mBAEC;IA4GD;;;;;;;;;;;;OAYG;IACH,0BAHW,YAAY,GAAC,YAAY,GAAC,MAAM,EAAE,GAChC,QAAQ,OAAO,CAAC,CAqC5B;IAED;;;OAGG;IACH,wDAFW,sBAAsB,QAMhC;IAED;;;;;;OAMG;IACH,mDAHW,sBAAsB,QAShC;IAED;;;OAGG;IACH,gBAKC;;CACJ;8BAlbY,OAAO,0CAA0C,EAAE,eAAe;8BAClE,OAAO,uBAAuB,EAAE,eAAe;uCAtBrB,wCAAwC"}
@@ -3,9 +3,22 @@ import { FrameGraph } from "../../../engine/graphics/render/frame_graph/FrameGra
3
3
  import { BufferResourceDescriptor } from "../../device/graph/BufferResourceDescriptor.js";
4
4
  import { ShadeGPUCommandContext } from "../../device/ShadeGPUCommandContext.js";
5
5
  import { ensure_buffer_capacity } from "../geometry/make_temp_gpu_buffer.js";
6
- import { BVH_HEADER_WORDS, BVH_NODE_STRIDE_WORDS, bvh_buffer_size } from "../gpu_primitive/bvh/BVH_BUFFER_LAYOUT.js";
7
- import { BVH_NULL_NODE, bvh_tree_views, read_bvh_node } from "../gpu_primitive/bvh/check_bvh_structure.js";
6
+ import { bvh_buffer_size } from "../gpu_primitive/bvh/BVH_BUFFER_LAYOUT.js";
8
7
  import { enquire_bvh_build_lbvh_pipelines, graph_bvh_build_lbvh } from "../gpu_primitive/bvh/graph_bvh_build_lbvh.js";
8
+ import {
9
+ BVH8_TREE_BOUNDS_HIGH_WORD,
10
+ BVH8_TREE_BOUNDS_LOW_WORD,
11
+ BVH8_TREE_HEADER_WORDS,
12
+ BVH8_TREE_LEAF_COUNT_WORD,
13
+ BVH8_TREE_NODE_STRIDE_WORDS,
14
+ BVH8_TREE_ORDER_OFFSET_WORD,
15
+ bvh8_tree_buffer_size
16
+ } from "../gpu_primitive/bvh8/BVH8_TREE_BUFFER_LAYOUT.js";
17
+ import {
18
+ enquire_bvh8_encode_pipelines,
19
+ graph_bvh8_encode_from_bvh2
20
+ } from "../gpu_primitive/bvh8/graph_bvh8_encode_from_bvh2.js";
21
+ import { graph_create_buffer } from "../shader/graph/graph_create_buffer.js";
9
22
  import { shader_bvh_extract_instance_leaves } from "./shader_bvh_extract_instance_leaves.js";
10
23
 
11
24
  /**
@@ -14,10 +27,14 @@ import { shader_bvh_extract_instance_leaves } from "./shader_bvh_extract_instanc
14
27
  */
15
28
 
16
29
  /**
17
- * `root = BVH_NULL_NODE` — an empty tree, in the four bytes every consumer already reads that way.
30
+ * A tree of no instances, as every walk reads it: a header that counts none, and one node with every
31
+ * slot empty. The payloads would start behind that node.
32
+ *
18
33
  * @type {Uint32Array}
19
34
  */
20
- const EMPTY_TREE = Uint32Array.from([0xffffffff]);
35
+ const EMPTY_TREE = new Uint32Array(BVH8_TREE_HEADER_WORDS + BVH8_TREE_NODE_STRIDE_WORDS);
36
+
37
+ EMPTY_TREE[BVH8_TREE_ORDER_OFFSET_WORD] = BVH8_TREE_HEADER_WORDS + BVH8_TREE_NODE_STRIDE_WORDS;
21
38
 
22
39
  /**
23
40
  * The scene-bounds cell before anything has been merged into it: +inf for the three minima, -inf
@@ -35,7 +52,11 @@ const SCENE_BOUNDS_SEED = Uint32Array.from([
35
52
  ]);
36
53
 
37
54
  /**
38
- * Top-Level Acceleration Structure (TLAS)
55
+ * Top-Level Acceleration Structure (TLAS): a BVH8 over the scene's instances, in the layout of
56
+ * {@link BVH8_TREE_BUFFER_LAYOUT}. A leaf's payload is a row of the scene database's `meshes` table.
57
+ *
58
+ * A build makes a binary tree over the rows' world boxes (`graph_bvh_build_lbvh`), which lives for
59
+ * the length of the build, and encodes it three levels to a node (`graph_bvh8_encode_from_bvh2`).
39
60
  */
40
61
  export class GPUInstancesAccelerationStructure {
41
62
 
@@ -47,6 +68,7 @@ export class GPUInstancesAccelerationStructure {
47
68
  static enquirePipelines(enquiry) {
48
69
  enquiry.compute.push(shader_bvh_extract_instance_leaves.pipeline);
49
70
  enquire_bvh_build_lbvh_pipelines(enquiry);
71
+ enquire_bvh8_encode_pipelines(enquiry);
50
72
  }
51
73
 
52
74
 
@@ -129,9 +151,8 @@ export class GPUInstancesAccelerationStructure {
129
151
  usage: GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_DST | GPUBufferUsage.COPY_SRC
130
152
  });
131
153
 
132
- // A fresh buffer holds zeroes, and zero is a root word naming node 0 — a tree that was never
133
- // built would read as one with a root of zero bounds. Empty, until the first build says
134
- // otherwise.
154
+ // A fresh buffer holds zeroes, which is a tree of no instances but for where its payloads start.
155
+ // Empty, until the first build says otherwise.
135
156
  device.queue.writeBuffer(this.#buffer, 0, EMPTY_TREE);
136
157
  }
137
158
 
@@ -262,7 +283,7 @@ export class GPUInstancesAccelerationStructure {
262
283
  this.#buffer = ensure_buffer_capacity(
263
284
  device,
264
285
  this.#buffer,
265
- bvh_buffer_size(Math.max(1, element_count)),
286
+ bvh8_tree_buffer_size(element_count),
266
287
  1024,
267
288
  1024,
268
289
  1.2
@@ -290,8 +311,8 @@ export class GPUInstancesAccelerationStructure {
290
311
  scene_database_buffer
291
312
  );
292
313
 
293
- const nodes = graph.import_resource(
294
- "tlas/nodes",
314
+ const tree = graph.import_resource(
315
+ "tlas/tree",
295
316
  BufferResourceDescriptor.fromBuffer(this.#buffer),
296
317
  this.#buffer
297
318
  );
@@ -318,13 +339,24 @@ export class GPUInstancesAccelerationStructure {
318
339
  GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_DST
319
340
  ));
320
341
 
321
- graph_bvh_build_lbvh({
342
+ // the binary tree is this build's alone
343
+ const binary = graph_bvh_build_lbvh({
322
344
  graph,
323
345
  leaf_bounds: extract_data.leaf_bounds,
324
346
  leaf_payload: extract_data.leaf_payload,
325
347
  scene_bounds: extract_data.scene_bounds,
326
348
  element_count,
327
- nodes,
349
+ nodes: graph_create_buffer(graph, "tlas/binary tree", BufferResourceDescriptor.from(
350
+ bvh_buffer_size(element_count),
351
+ GPUBufferUsage.STORAGE
352
+ )),
353
+ });
354
+
355
+ graph_bvh8_encode_from_bvh2({
356
+ graph,
357
+ tree: binary.nodes,
358
+ leaf_count: element_count,
359
+ out: tree,
328
360
  });
329
361
 
330
362
  if (cmd_ctx !== undefined) {
@@ -340,9 +372,9 @@ export class GPUInstancesAccelerationStructure {
340
372
  }
341
373
 
342
374
  /**
343
- * The bounds of everything in the tree, read back from its root node: the box the GPU built
344
- * the tree under, the union of every live row's bounds as the bounds pass derived them — the
345
- * whole scene, whoever placed what. For a consumer that sizes work by the scene once, a probe
375
+ * The bounds of everything in the tree, read back from its header: the box the GPU built the
376
+ * tree under, the union of every live row's bounds as the bounds pass derived them — the whole
377
+ * scene, whoever placed what. For a consumer that sizes work by the scene once, a probe
346
378
  * placement or a bake; a frame-loop reader wants the scene database's readback service.
347
379
  *
348
380
  * Resolves once the copy has landed and been mapped, which is after the device has finished
@@ -356,8 +388,7 @@ export class GPUInstancesAccelerationStructure {
356
388
  assert.isArrayLike(target, 'target');
357
389
  assert.greaterThanOrEqual(target.length, 6, 'target.length < 6');
358
390
 
359
- // the root word and node 0 — the root by the builder's construction
360
- const byte_size = (BVH_HEADER_WORDS + BVH_NODE_STRIDE_WORDS) * Uint32Array.BYTES_PER_ELEMENT;
391
+ const byte_size = BVH8_TREE_HEADER_WORDS * Uint32Array.BYTES_PER_ELEMENT;
361
392
 
362
393
  const allocator = this.#graphics.buffer_allocator_readback;
363
394
  const staging = allocator.get(byte_size);
@@ -369,24 +400,20 @@ export class GPUInstancesAccelerationStructure {
369
400
 
370
401
  await staging.mapAsync(GPUMapMode.READ, 0, byte_size);
371
402
 
372
- const { words, floats } = bvh_tree_views(new Uint32Array(staging.getMappedRange(0, byte_size)));
373
- const root = words[0];
374
-
375
- let found = false;
376
-
377
- if (root !== BVH_NULL_NODE) {
378
- assert.equal(root, 0, 'the tree\'s root is not node 0');
403
+ const mapped = staging.getMappedRange(0, byte_size);
379
404
 
380
- const node = read_bvh_node(words, floats, root);
405
+ const words = new Uint32Array(mapped);
406
+ const floats = new Float32Array(mapped);
381
407
 
382
- target[0] = node.low[0];
383
- target[1] = node.low[1];
384
- target[2] = node.low[2];
385
- target[3] = node.high[0];
386
- target[4] = node.high[1];
387
- target[5] = node.high[2];
408
+ const found = words[BVH8_TREE_LEAF_COUNT_WORD] !== 0;
388
409
 
389
- found = true;
410
+ if (found) {
411
+ target[0] = floats[BVH8_TREE_BOUNDS_LOW_WORD];
412
+ target[1] = floats[BVH8_TREE_BOUNDS_LOW_WORD + 1];
413
+ target[2] = floats[BVH8_TREE_BOUNDS_LOW_WORD + 2];
414
+ target[3] = floats[BVH8_TREE_BOUNDS_HIGH_WORD];
415
+ target[4] = floats[BVH8_TREE_BOUNDS_HIGH_WORD + 1];
416
+ target[5] = floats[BVH8_TREE_BOUNDS_HIGH_WORD + 2];
390
417
  }
391
418
 
392
419
  allocator.release(staging);