@woosh/meep-engine 3.12.0 → 3.13.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (301) hide show
  1. package/package.json +1 -1
  2. package/src/core/geom/3d/shape/ConvexHullShape3D.d.ts.map +1 -1
  3. package/src/core/geom/3d/shape/ConvexHullShape3D.js +41 -25
  4. package/src/core/geom/3d/shape/PosedShape3D.d.ts.map +1 -1
  5. package/src/core/geom/3d/shape/PosedShape3D.js +7 -2
  6. package/src/engine/graphics3/decal/GPUDecalRenderer.js +3 -3
  7. package/src/engine/graphics3/decal/shader_decal_composite.d.ts.map +1 -1
  8. package/src/engine/graphics3/decal/shader_decal_composite.js +4 -2
  9. package/src/engine/graphics3/highlight/GPUHighlightRenderer.d.ts.map +1 -1
  10. package/src/engine/graphics3/highlight/GPUHighlightRenderer.js +2 -3
  11. package/src/engine/graphics3/highlight/shader_highlight_outline.js +150 -150
  12. package/src/engine/physics/fluid/ecs/FluidObstacleSystem.d.ts +4 -4
  13. package/src/shade/RENDERER_CONTRACT.md +2 -1
  14. package/src/shade/descriptor/pipeline/compute/ComputePipelineDescriptor.d.ts +18 -0
  15. package/src/shade/descriptor/pipeline/compute/ComputePipelineDescriptor.d.ts.map +1 -1
  16. package/src/shade/descriptor/pipeline/compute/ComputePipelineDescriptor.js +73 -0
  17. package/src/shade/device/PASS_ENCODER_PROPOSAL_2026_08_31.md +755 -0
  18. package/src/shade/device/ShadeGPUCommandContext.d.ts +10 -16
  19. package/src/shade/device/ShadeGPUCommandContext.d.ts.map +1 -1
  20. package/src/shade/device/ShadeGPUCommandContext.js +801 -994
  21. package/src/shade/device/pass/ShadeGPUComputePassEncoder.d.ts +107 -0
  22. package/src/shade/device/pass/ShadeGPUComputePassEncoder.d.ts.map +1 -0
  23. package/src/shade/device/pass/ShadeGPUComputePassEncoder.js +222 -0
  24. package/src/shade/device/pass/ShadeGPURenderPassEncoder.d.ts +168 -0
  25. package/src/shade/device/pass/ShadeGPURenderPassEncoder.d.ts.map +1 -0
  26. package/src/shade/device/pass/ShadeGPURenderPassEncoder.js +317 -0
  27. package/src/shade/device/timing/GPUTimerArray.d.ts +4 -9
  28. package/src/shade/device/timing/GPUTimerArray.d.ts.map +1 -1
  29. package/src/shade/device/timing/GPUTimerArray.js +261 -289
  30. package/src/shade/device/timing/GPU_PROFILER_PROPOSAL_2026_08_28.md +20 -2
  31. package/src/shade/device/timing/ShadeGPUContextProfiler.d.ts +59 -0
  32. package/src/shade/device/timing/ShadeGPUContextProfiler.d.ts.map +1 -0
  33. package/src/shade/device/timing/ShadeGPUContextProfiler.js +182 -0
  34. package/src/shade/device/timing/profile/GPUProfileSession.d.ts +4 -4
  35. package/src/shade/device/timing/profile/GPUProfileSession.js +4 -4
  36. package/src/shade/playground/skinned_blas_refit/shader_blas_audit_leaf_triangles.d.ts.map +1 -1
  37. package/src/shade/playground/skinned_blas_refit/shader_blas_audit_leaf_triangles.js +3 -1
  38. package/src/shade/playground/skinned_blas_refit/shader_blas_audit_points.d.ts.map +1 -1
  39. package/src/shade/playground/skinned_blas_refit/shader_blas_audit_points.js +3 -1
  40. package/src/shade/playground/skinned_blas_refit/shader_blas_audit_visibility.d.ts.map +1 -1
  41. package/src/shade/playground/skinned_blas_refit/shader_blas_audit_visibility.js +3 -1
  42. package/src/shade/playground/skinned_blas_refit/verify_leaf_triangles.js +2 -2
  43. package/src/shade/playground/skinned_blas_refit/verify_traversal_reachability.js +2 -2
  44. package/src/shade/renderer/Renderer.d.ts +0 -6
  45. package/src/shade/renderer/Renderer.d.ts.map +1 -1
  46. package/src/shade/renderer/Renderer.js +0 -29
  47. package/src/shade/renderer/animation/GPUAnimationManager.d.ts.map +1 -1
  48. package/src/shade/renderer/animation/GPUAnimationManager.js +1 -3
  49. package/src/shade/renderer/animation/shader_animation_tick.d.ts.map +1 -1
  50. package/src/shade/renderer/animation/shader_animation_tick.js +128 -125
  51. package/src/shade/renderer/animation/skinning/GPUMeshSkinningContext.d.ts.map +1 -1
  52. package/src/shade/renderer/animation/skinning/GPUMeshSkinningContext.js +8 -18
  53. package/src/shade/renderer/animation/skinning/bounds_refresh/shader_geometry_sphere_derive.d.ts.map +1 -1
  54. package/src/shade/renderer/animation/skinning/bounds_refresh/shader_geometry_sphere_derive.js +100 -98
  55. package/src/shade/renderer/animation/skinning/bounds_refresh/shader_meshlet_bounds_reduce.d.ts.map +1 -1
  56. package/src/shade/renderer/animation/skinning/bounds_refresh/shader_meshlet_bounds_reduce.js +215 -212
  57. package/src/shade/renderer/animation/skinning/bounds_refresh/shader_meshlet_bounds_scatter.d.ts +1 -1
  58. package/src/shade/renderer/animation/skinning/bounds_refresh/shader_meshlet_bounds_scatter.d.ts.map +1 -1
  59. package/src/shade/renderer/animation/skinning/bounds_refresh/shader_meshlet_bounds_scatter.js +135 -120
  60. package/src/shade/renderer/animation/skinning/bounds_refresh/shader_skinned_mesh_bounds_refresh.d.ts.map +1 -1
  61. package/src/shade/renderer/animation/skinning/bounds_refresh/shader_skinned_mesh_bounds_refresh.js +77 -75
  62. package/src/shade/renderer/animation/skinning/shader_meshlet_apply_skinning.d.ts.map +1 -1
  63. package/src/shade/renderer/animation/skinning/shader_meshlet_apply_skinning.js +375 -371
  64. package/src/shade/renderer/atmosphere/shader_transmittance_lut.js +3 -3
  65. package/src/shade/renderer/buffer/graph_inspect_gpu_buffer.js +1 -1
  66. package/src/shade/renderer/buffer/table/GPUDatabase.d.ts.map +1 -1
  67. package/src/shade/renderer/buffer/table/GPUDatabase.js +14 -19
  68. package/src/shade/renderer/buffer/table/gpu_table_element_upload_shader.d.ts.map +1 -1
  69. package/src/shade/renderer/buffer/table/gpu_table_element_upload_shader.js +7 -2
  70. package/src/shade/renderer/buffer/table/single/GPUSingleTypeTable.d.ts.map +1 -1
  71. package/src/shade/renderer/buffer/table/single/GPUSingleTypeTable.js +325 -319
  72. package/src/shade/renderer/buffer/util/shader_buffer_copy_storage_to_storage.d.ts.map +1 -1
  73. package/src/shade/renderer/buffer/util/shader_buffer_copy_storage_to_storage.js +3 -1
  74. package/src/shade/renderer/deferred/shader_tonemap_HDR.d.ts.map +1 -1
  75. package/src/shade/renderer/deferred/shader_tonemap_HDR.js +4 -1
  76. package/src/shade/renderer/dynamic/GPUDynamicMeshResidency.d.ts +2 -2
  77. package/src/shade/renderer/dynamic/GPUDynamicMeshResidency.d.ts.map +1 -1
  78. package/src/shade/renderer/dynamic/GPUDynamicMeshResidency.js +167 -167
  79. package/src/shade/renderer/fow/GPUFogOfWarRenderer.js +3 -3
  80. package/src/shade/renderer/fow/shader_fog_of_war.d.ts.map +1 -1
  81. package/src/shade/renderer/fow/shader_fog_of_war.js +3 -1
  82. package/src/shade/renderer/geometry/bvh/record_blas_refit.js +102 -102
  83. package/src/shade/renderer/geometry/bvh/shader_blas_refit_leaf_bounds.d.ts.map +1 -1
  84. package/src/shade/renderer/geometry/bvh/shader_blas_refit_leaf_bounds.js +125 -121
  85. package/src/shade/renderer/geometry/meshlet/GPUMeshletManager.d.ts.map +1 -1
  86. package/src/shade/renderer/geometry/meshlet/GPUMeshletManager.js +766 -774
  87. package/src/shade/renderer/geometry/meshlet/shader_meshlet_metadata_address_patch.d.ts.map +1 -1
  88. package/src/shade/renderer/geometry/meshlet/shader_meshlet_metadata_address_patch.js +72 -69
  89. package/src/shade/renderer/geometry/sdf/GPUGeometrySDFManager.d.ts.map +1 -1
  90. package/src/shade/renderer/geometry/sdf/GPUGeometrySDFManager.js +5 -10
  91. package/src/shade/renderer/geometry/sdf/shader_build_sdf.js +129 -129
  92. package/src/shade/renderer/geometry/sdf/shader_sdf_visualize.d.ts.map +1 -1
  93. package/src/shade/renderer/geometry/sdf/shader_sdf_visualize.js +5 -3
  94. package/src/shade/renderer/global_illumination/brick4/gpu/bake/shader_brick4_bake_probes.d.ts.map +1 -1
  95. package/src/shade/renderer/global_illumination/brick4/gpu/bake/shader_brick4_bake_probes.js +4 -1
  96. package/src/shade/renderer/global_illumination/brick4/gpu/bake/shader_brick4_bake_resolve_probes.d.ts.map +1 -1
  97. package/src/shade/renderer/global_illumination/brick4/gpu/bake/shader_brick4_bake_resolve_probes.js +3 -1
  98. package/src/shade/renderer/global_illumination/clipmap/shader_update_clipmap_cascade.d.ts.map +1 -1
  99. package/src/shade/renderer/global_illumination/clipmap/shader_update_clipmap_cascade.js +114 -112
  100. package/src/shade/renderer/global_illumination/probe/octahedral/convolve/graph_lpv_store_sh.d.ts.map +1 -1
  101. package/src/shade/renderer/global_illumination/probe/octahedral/convolve/graph_lpv_store_sh.js +4 -1
  102. package/src/shade/renderer/global_illumination/probe/octahedral/convolve/graph_lvp_atlas_to_sh.d.ts.map +1 -1
  103. package/src/shade/renderer/global_illumination/probe/octahedral/convolve/graph_lvp_atlas_to_sh.js +187 -184
  104. package/src/shade/renderer/global_illumination/probe/octahedral/convolve/graph_reduce_atlas_to_sh.d.ts.map +1 -1
  105. package/src/shade/renderer/global_illumination/probe/octahedral/convolve/graph_reduce_atlas_to_sh.js +4 -1
  106. package/src/shade/renderer/global_illumination/sharc/SpatialHashRadianceCache.d.ts.map +1 -1
  107. package/src/shade/renderer/global_illumination/sharc/SpatialHashRadianceCache.js +6 -8
  108. package/src/shade/renderer/global_illumination/sharc/shader/shader_sharc_evict.d.ts.map +1 -1
  109. package/src/shade/renderer/global_illumination/sharc/shader/shader_sharc_evict.js +3 -1
  110. package/src/shade/renderer/global_illumination/sharc/shader/shader_sharc_update.d.ts.map +1 -1
  111. package/src/shade/renderer/global_illumination/sharc/shader/shader_sharc_update.js +3 -1
  112. package/src/shade/renderer/gpu_primitive/bvh/GPU_BVH_BUILD_PLAN.md +3 -3
  113. package/src/shade/renderer/gpu_primitive/bvh/PHASE1_HANDOVER.md +3 -3
  114. package/src/shade/renderer/gpu_primitive/bvh/graph_bvh_build_lbvh.js +217 -217
  115. package/src/shade/renderer/gpu_primitive/bvh/shader_bvh_emit_hierarchy.d.ts.map +1 -1
  116. package/src/shade/renderer/gpu_primitive/bvh/shader_bvh_emit_hierarchy.js +145 -142
  117. package/src/shade/renderer/gpu_primitive/bvh/shader_bvh_morton.d.ts.map +1 -1
  118. package/src/shade/renderer/gpu_primitive/bvh/shader_bvh_morton.js +87 -82
  119. package/src/shade/renderer/gpu_primitive/bvh/shader_bvh_refit.d.ts.map +1 -1
  120. package/src/shade/renderer/gpu_primitive/bvh/shader_bvh_refit.js +143 -140
  121. package/src/shade/renderer/gpu_primitive/bvh/verify_gpu_bvh_build.d.ts +2 -2
  122. package/src/shade/renderer/gpu_primitive/bvh/verify_gpu_bvh_build.d.ts.map +1 -1
  123. package/src/shade/renderer/gpu_primitive/bvh/verify_gpu_bvh_build.js +43 -8
  124. package/src/shade/renderer/gpu_primitive/sort/graph_radix_sort.d.ts.map +1 -1
  125. package/src/shade/renderer/gpu_primitive/sort/graph_radix_sort.js +4 -5
  126. package/src/shade/renderer/gpu_primitive/sort/shader_radix_sort_histogram.d.ts.map +1 -1
  127. package/src/shade/renderer/gpu_primitive/sort/shader_radix_sort_histogram.js +88 -84
  128. package/src/shade/renderer/gpu_primitive/sort/shader_radix_sort_scatter.d.ts.map +1 -1
  129. package/src/shade/renderer/gpu_primitive/sort/shader_radix_sort_scatter.js +194 -191
  130. package/src/shade/renderer/hiz/HierarchicalZBuffer.d.ts.map +1 -1
  131. package/src/shade/renderer/hiz/HierarchicalZBuffer.js +33 -69
  132. package/src/shade/renderer/hiz/shader_hzb_reduce_any.d.ts.map +1 -1
  133. package/src/shade/renderer/hiz/shader_hzb_reduce_any.js +6 -1
  134. package/src/shade/renderer/hiz/shader_hzb_reduce_mip0_clip.d.ts.map +1 -1
  135. package/src/shade/renderer/hiz/shader_hzb_reduce_mip0_clip.js +23 -7
  136. package/src/shade/renderer/light/environment/execute_filter_environment_map.d.ts.map +1 -1
  137. package/src/shade/renderer/light/environment/execute_filter_environment_map.js +1 -2
  138. package/src/shade/renderer/light/environment/shader_convolve_reflection_map.d.ts.map +1 -1
  139. package/src/shade/renderer/light/environment/shader_convolve_reflection_map.js +6 -1
  140. package/src/shade/renderer/lightmap/bake/raster/graph_draw_lightmap_viz_buffer.d.ts.map +1 -1
  141. package/src/shade/renderer/lightmap/bake/raster/graph_draw_lightmap_viz_buffer.js +234 -219
  142. package/src/shade/renderer/lightmap/bake/raster/shader_lightmap_to_viz_buffer.js +2 -2
  143. package/src/shade/renderer/lightmap/bake/shader_lightmap_denoise_sh.js +191 -191
  144. package/src/shade/renderer/lightmap/bake/tile/shader_lightmap_accummulate_tile.d.ts.map +1 -1
  145. package/src/shade/renderer/lightmap/bake/tile/shader_lightmap_accummulate_tile.js +85 -82
  146. package/src/shade/renderer/particles/graph_particles.d.ts.map +1 -1
  147. package/src/shade/renderer/particles/graph_particles.js +5 -3
  148. package/src/shade/renderer/particles/prototypeParticleSystem.js +3 -4
  149. package/src/shade/renderer/particles/shaders/shader_particle_emit.d.ts.map +1 -1
  150. package/src/shade/renderer/particles/shaders/shader_particle_emit.js +132 -117
  151. package/src/shade/renderer/particles/shaders/shader_particle_finalize.d.ts.map +1 -1
  152. package/src/shade/renderer/particles/shaders/shader_particle_finalize.js +79 -77
  153. package/src/shade/renderer/particles/shaders/shader_particle_simulate.d.ts.map +1 -1
  154. package/src/shade/renderer/particles/shaders/shader_particle_simulate.js +111 -99
  155. package/src/shade/renderer/particles/sort/shader_particle_sort.d.ts.map +1 -1
  156. package/src/shade/renderer/particles/sort/shader_particle_sort.js +187 -158
  157. package/src/shade/renderer/path_tracer/accumulating/AccumulatingPathTracer.d.ts.map +1 -1
  158. package/src/shade/renderer/path_tracer/accumulating/AccumulatingPathTracer.js +7 -10
  159. package/src/shade/renderer/path_tracer/accumulating/shader_accumulating_path_tracer.d.ts.map +1 -1
  160. package/src/shade/renderer/path_tracer/accumulating/shader_accumulating_path_tracer.js +4 -1
  161. package/src/shade/renderer/postprocess/bloom/shader_bloom_mix.d.ts.map +1 -1
  162. package/src/shade/renderer/postprocess/bloom/shader_bloom_mix.js +3 -1
  163. package/src/shade/renderer/postprocess/cas/shader_ffx_rcas.d.ts.map +1 -1
  164. package/src/shade/renderer/postprocess/cas/shader_ffx_rcas.js +4 -2
  165. package/src/shade/renderer/postprocess/denoise/fragment_shader_denoise_ao.js +147 -147
  166. package/src/shade/renderer/postprocess/denoise/graph_atorus_denoise_luma.d.ts.map +1 -1
  167. package/src/shade/renderer/postprocess/denoise/graph_atorus_denoise_luma.js +121 -119
  168. package/src/shade/renderer/postprocess/dof/gather/graph_postprocess_dof2.d.ts.map +1 -1
  169. package/src/shade/renderer/postprocess/dof/gather/graph_postprocess_dof2.js +1 -2
  170. package/src/shade/renderer/postprocess/dof/gather/shader_dof2_gather_far.d.ts.map +1 -1
  171. package/src/shade/renderer/postprocess/dof/gather/shader_dof2_gather_far.js +4 -1
  172. package/src/shade/renderer/postprocess/dof/gather/shader_dof2_gather_near.d.ts.map +1 -1
  173. package/src/shade/renderer/postprocess/dof/gather/shader_dof2_gather_near.js +4 -1
  174. package/src/shade/renderer/postprocess/dof/gather/shader_dof2_recombine.d.ts.map +1 -1
  175. package/src/shade/renderer/postprocess/dof/gather/shader_dof2_recombine.js +4 -1
  176. package/src/shade/renderer/postprocess/dof/gather/shader_dof2_setup.d.ts.map +1 -1
  177. package/src/shade/renderer/postprocess/dof/gather/shader_dof2_setup.js +4 -1
  178. package/src/shade/renderer/postprocess/dof/raymarch/graph_postprocess_dof.d.ts.map +1 -1
  179. package/src/shade/renderer/postprocess/dof/raymarch/graph_postprocess_dof.js +2 -4
  180. package/src/shade/renderer/postprocess/dof/raymarch/shader_dof_composite.d.ts.map +1 -1
  181. package/src/shade/renderer/postprocess/dof/raymarch/shader_dof_composite.js +4 -1
  182. package/src/shade/renderer/postprocess/dof/raymarch/shader_dof_prefilter.d.ts.map +1 -1
  183. package/src/shade/renderer/postprocess/dof/raymarch/shader_dof_prefilter.js +4 -1
  184. package/src/shade/renderer/postprocess/dof/raymarch/shader_dof_raymarch.d.ts.map +1 -1
  185. package/src/shade/renderer/postprocess/dof/raymarch/shader_dof_raymarch.js +4 -1
  186. package/src/shade/renderer/postprocess/dof/raymarch/shader_dof_raymarch_compute.d.ts.map +1 -1
  187. package/src/shade/renderer/postprocess/dof/raymarch/shader_dof_raymarch_compute.js +269 -266
  188. package/src/shade/renderer/postprocess/dof/raymarch/shader_dof_slice_compute.d.ts.map +1 -1
  189. package/src/shade/renderer/postprocess/dof/raymarch/shader_dof_slice_compute.js +273 -270
  190. package/src/shade/renderer/postprocess/dof/shader_dof_autofocus.d.ts.map +1 -1
  191. package/src/shade/renderer/postprocess/dof/shader_dof_autofocus.js +4 -1
  192. package/src/shade/renderer/postprocess/eye/GPUCameraExposureManager.d.ts.map +1 -1
  193. package/src/shade/renderer/postprocess/eye/GPUCameraExposureManager.js +8 -11
  194. package/src/shade/renderer/postprocess/eye/shader_autoexposure_adapt.d.ts.map +1 -1
  195. package/src/shade/renderer/postprocess/eye/shader_autoexposure_adapt.js +5 -1
  196. package/src/shade/renderer/postprocess/gtao/fragment_shader_gtao.d.ts.map +1 -1
  197. package/src/shade/renderer/postprocess/gtao/fragment_shader_gtao.js +11 -8
  198. package/src/shade/renderer/postprocess/gtao/fragment_shader_gtao_with_irradiance.d.ts.map +1 -1
  199. package/src/shade/renderer/postprocess/gtao/fragment_shader_gtao_with_irradiance.js +7 -8
  200. package/src/shade/renderer/postprocess/motion_blur/shader_motion_blur_reconstruct.d.ts.map +1 -1
  201. package/src/shade/renderer/postprocess/motion_blur/shader_motion_blur_reconstruct.js +3 -1
  202. package/src/shade/renderer/postprocess/nss/NSS.d.ts +1 -1
  203. package/src/shade/renderer/postprocess/nss/shader_nss_concat.d.ts.map +1 -1
  204. package/src/shade/renderer/postprocess/nss/shader_nss_concat.js +70 -68
  205. package/src/shade/renderer/postprocess/ssr/depth_max_shader.d.ts.map +1 -1
  206. package/src/shade/renderer/postprocess/ssr/depth_max_shader.js +70 -68
  207. package/src/shade/renderer/postprocess/ssr/resolve/ssr_resolve_shader_IBL.d.ts.map +1 -1
  208. package/src/shade/renderer/postprocess/ssr/resolve/ssr_resolve_shader_IBL.js +3 -1
  209. package/src/shade/renderer/postprocess/ssr/resolve/ssr_resolve_shader_LPV.d.ts.map +1 -1
  210. package/src/shade/renderer/postprocess/ssr/resolve/ssr_resolve_shader_LPV.js +4 -1
  211. package/src/shade/renderer/postprocess/ssr/shader_downsample_encoded_normal.d.ts.map +1 -1
  212. package/src/shade/renderer/postprocess/ssr/shader_downsample_encoded_normal.js +103 -101
  213. package/src/shade/renderer/postprocess/ssr/ssr_spatial_denoise_shader.d.ts.map +1 -1
  214. package/src/shade/renderer/postprocess/ssr/ssr_spatial_denoise_shader.js +4 -2
  215. package/src/shade/renderer/postprocess/ssr/ssr_trace_shader.d.ts.map +1 -1
  216. package/src/shade/renderer/postprocess/ssr/ssr_trace_shader.js +3 -1
  217. package/src/shade/renderer/postprocess/taa/shader_taa.d.ts.map +1 -1
  218. package/src/shade/renderer/postprocess/taa/shader_taa.js +4 -1
  219. package/src/shade/renderer/postprocess/upscale-dither/fragment_shader_upscale_dither.js +5 -5
  220. package/src/shade/renderer/rasterize/bucket/prepare_meshlet_draw_commands_by_material.d.ts.map +1 -1
  221. package/src/shade/renderer/rasterize/bucket/prepare_meshlet_draw_commands_by_material.js +339 -341
  222. package/src/shade/renderer/rasterize/cull/hzb/shader_hzb_mesh_filter_2way.d.ts.map +1 -1
  223. package/src/shade/renderer/rasterize/cull/hzb/shader_hzb_mesh_filter_2way.js +114 -109
  224. package/src/shade/renderer/rasterize/cull/hzb/shader_hzb_meshlet_filter_1way_full.d.ts.map +1 -1
  225. package/src/shade/renderer/rasterize/cull/hzb/shader_hzb_meshlet_filter_1way_full.js +118 -115
  226. package/src/shade/renderer/rasterize/expand/bucket/meshlet/shader_meshlets_extract_bucket.d.ts.map +1 -1
  227. package/src/shade/renderer/rasterize/expand/bucket/meshlet/shader_meshlets_extract_bucket.js +69 -65
  228. package/src/shade/renderer/rasterize/native/oit/graph_rasterize_meshes_transparent_oit.js +722 -722
  229. package/src/shade/renderer/rasterize/standard/graph_rasterize_partial_opaque.d.ts.map +1 -1
  230. package/src/shade/renderer/rasterize/standard/graph_rasterize_partial_opaque.js +1 -9
  231. package/src/shade/renderer/rasterize/standard/graph_rasterize_remaining_opaque.d.ts.map +1 -1
  232. package/src/shade/renderer/rasterize/standard/graph_rasterize_remaining_opaque.js +1 -6
  233. package/src/shade/renderer/restir/di/graph_restir_di.d.ts.map +1 -1
  234. package/src/shade/renderer/restir/di/graph_restir_di.js +2 -3
  235. package/src/shade/renderer/restir/di/graph_restir_di_denoise.d.ts.map +1 -1
  236. package/src/shade/renderer/restir/di/graph_restir_di_denoise.js +1 -2
  237. package/src/shade/renderer/restir/di/shader_restir_di_denoise.d.ts.map +1 -1
  238. package/src/shade/renderer/restir/di/shader_restir_di_denoise.js +139 -136
  239. package/src/shade/renderer/restir/di/shader_restir_di_resample.d.ts.map +1 -1
  240. package/src/shade/renderer/restir/di/shader_restir_di_resample.js +131 -129
  241. package/src/shade/renderer/restir/di/shader_restir_di_resolve.d.ts.map +1 -1
  242. package/src/shade/renderer/restir/di/shader_restir_di_resolve.js +101 -99
  243. package/src/shade/renderer/scene/GPUInstancesAccelerationStructure.d.ts.map +1 -1
  244. package/src/shade/renderer/scene/GPUInstancesAccelerationStructure.js +379 -383
  245. package/src/shade/renderer/scene/Mesh.d.ts.map +1 -1
  246. package/src/shade/renderer/scene/Mesh.js +4 -6
  247. package/src/shade/renderer/scene/shader_bvh_extract_instance_leaves.d.ts.map +1 -1
  248. package/src/shade/renderer/scene/shader_bvh_extract_instance_leaves.js +147 -144
  249. package/src/shade/renderer/shader/ComputeShader.d.ts +2 -2
  250. package/src/shade/renderer/shader/ComputeShader.d.ts.map +1 -1
  251. package/src/shade/renderer/shader/ComputeShader.js +14 -17
  252. package/src/shade/renderer/shader/pass/RenderPassDescriptor.d.ts +2 -2
  253. package/src/shade/renderer/shader/pass/RenderPassDescriptor.d.ts.map +1 -1
  254. package/src/shade/renderer/shader/pass/RenderPassDescriptor.js +189 -189
  255. package/src/shade/renderer/shader/resource/ShaderResourceSetDescriptor.d.ts.map +1 -1
  256. package/src/shade/renderer/shader/resource/ShaderResourceSetDescriptor.js +3 -1
  257. package/src/shade/renderer/shadow/map/GPUSceneShadowmapContext.d.ts +16 -7
  258. package/src/shade/renderer/shadow/map/GPUSceneShadowmapContext.d.ts.map +1 -1
  259. package/src/shade/renderer/shadow/map/GPUSceneShadowmapContext.js +1342 -1326
  260. package/src/shade/renderer/shadow/map/Shadowmap.d.ts +13 -0
  261. package/src/shade/renderer/shadow/map/Shadowmap.d.ts.map +1 -1
  262. package/src/shade/renderer/shadow/map/Shadowmap.js +14 -0
  263. package/src/shade/renderer/shadow/map/ShadowmapDrawSelector.d.ts +79 -0
  264. package/src/shade/renderer/shadow/map/ShadowmapDrawSelector.d.ts.map +1 -0
  265. package/src/shade/renderer/shadow/map/ShadowmapDrawSelector.js +196 -0
  266. package/src/shade/renderer/shadow/map/ShadowmapRegistry.d.ts +91 -0
  267. package/src/shade/renderer/shadow/map/ShadowmapRegistry.d.ts.map +1 -0
  268. package/src/shade/renderer/shadow/map/ShadowmapRegistry.js +156 -0
  269. package/src/shade/renderer/shadow/map/shader/shader_shadowmap_remap_cube_to_octahedral.d.ts.map +1 -1
  270. package/src/shade/renderer/shadow/map/shader/shader_shadowmap_remap_cube_to_octahedral.js +5 -1
  271. package/src/shade/renderer/shadow/ray/shader_shadow_upscale.d.ts.map +1 -1
  272. package/src/shade/renderer/shadow/ray/shader_shadow_upscale.js +3 -1
  273. package/src/shade/renderer/shadow/ray/staged/gen/graph_gen_rays.js +73 -73
  274. package/src/shade/renderer/shadow/ray/staged/gen/shader_generate_rays.d.ts.map +1 -1
  275. package/src/shade/renderer/shadow/ray/staged/gen/shader_generate_rays.js +151 -148
  276. package/src/shade/renderer/shadow/ray/staged/trace/graph_trace_rays.d.ts.map +1 -1
  277. package/src/shade/renderer/shadow/ray/staged/trace/graph_trace_rays.js +4 -2
  278. package/src/shade/renderer/shadow/ray/staged/trace/shader_trace_rays.d.ts.map +1 -1
  279. package/src/shade/renderer/shadow/ray/staged/trace/shader_trace_rays.js +18 -4
  280. package/src/shade/renderer/shadow/sdf/cascade/CascadedSceneSDF.d.ts.map +1 -1
  281. package/src/shade/renderer/shadow/sdf/cascade/CascadedSceneSDF.js +7 -8
  282. package/src/shade/renderer/shadow/sdf/cascade/shader_build_scene_sdf_f32.d.ts.map +1 -1
  283. package/src/shade/renderer/shadow/sdf/cascade/shader_build_scene_sdf_f32.js +6 -2
  284. package/src/shade/renderer/shadow/sdf/cascade/shader_scene_sdf_debug_viz.d.ts.map +1 -1
  285. package/src/shade/renderer/shadow/sdf/cascade/shader_scene_sdf_debug_viz.js +129 -127
  286. package/src/shade/renderer/shadow/sdf/graph_draw_sdf_shadows.d.ts.map +1 -1
  287. package/src/shade/renderer/shadow/sdf/graph_draw_sdf_shadows.js +5 -3
  288. package/src/shade/renderer/texture/virtual/VirtualTextureManager.d.ts.map +1 -1
  289. package/src/shade/renderer/texture/virtual/VirtualTextureManager.js +2 -5
  290. package/src/shade/renderer/texture/virtual/build_shader_vt_feedback.d.ts.map +1 -1
  291. package/src/shade/renderer/texture/virtual/build_shader_vt_feedback.js +233 -231
  292. package/src/shade/renderer/volumetrics/graph_build_volumetrics.d.ts.map +1 -1
  293. package/src/shade/renderer/volumetrics/graph_build_volumetrics.js +2 -4
  294. package/src/shade/wgsl/validate_wgsl_source.d.ts.map +1 -1
  295. package/src/shade/wgsl/validate_wgsl_source.js +8 -3
  296. package/src/shade/device/timing/profile/make_profiling_pass_encoder.d.ts +0 -21
  297. package/src/shade/device/timing/profile/make_profiling_pass_encoder.d.ts.map +0 -1
  298. package/src/shade/device/timing/profile/make_profiling_pass_encoder.js +0 -114
  299. package/src/shade/device/timing/profile/parse_workgroup_size.d.ts +0 -20
  300. package/src/shade/device/timing/profile/parse_workgroup_size.d.ts.map +0 -1
  301. package/src/shade/device/timing/profile/parse_workgroup_size.js +0 -43
@@ -1 +1 @@
1
- {"version":3,"file":"SpatialHashRadianceCache.d.ts","sourceRoot":"","sources":["../../../../../../src/shade/renderer/global_illumination/sharc/SpatialHashRadianceCache.js"],"names":[],"mappings":"AAcA;IAkDI;;;;OAIG;IACH,8CAFW,MAAM,EAkBhB;IA1DD,qCAEC;IASD,mCAEC;IAQD,mBAEC;IAQD,6BAIC;IARD,0BAEC;IAiCD;;;;;;;;OAQG;IACH,gHAsGC;IAED,gBAEC;IAED,gBAEC;IAED,cAiBC;IAGD,gBAUC;IAED;;;OAqBC;IAED;;;OAGG;IACH,+BAYC;;CACJ"}
1
+ {"version":3,"file":"SpatialHashRadianceCache.d.ts","sourceRoot":"","sources":["../../../../../../src/shade/renderer/global_illumination/sharc/SpatialHashRadianceCache.js"],"names":[],"mappings":"AAaA;IAkDI;;;;OAIG;IACH,8CAFW,MAAM,EAkBhB;IA1DD,qCAEC;IASD,mCAEC;IAQD,mBAEC;IAQD,6BAIC;IARD,0BAEC;IAiCD;;;;;;;;OAQG;IACH,gHAqGC;IAED,gBAEC;IAED,gBAEC;IAED,cAiBC;IAGD,gBAUC;IAED;;;OAqBC;IAED;;;OAGG;IACH,+BAYC;;CACJ"}
@@ -5,7 +5,6 @@ import { inspect_gpu_buffer_typed } from "../../buffer/inspect_gpu_buffer_typed.
5
5
  import { graph_compute_indirect_pass } from "../../shader/graph/compute/graph_compute_indirect_pass.js";
6
6
  import { graph_import_buffer } from "../../shader/graph/graph_import_buffer.js";
7
7
  import { graph_build_indirect_dispatch_command } from "../../gpu_primitive/indirect/IndirectComputeCommandBuildPass.js";
8
- import { HASH_GRID_PARAMETERS_STRUCT } from "./shader/sh/HASH_GRID_PARAMETERS_STRUCT.js";
9
8
  import { shader_sharc_evict } from "./shader/shader_sharc_evict.js";
10
9
  import { shader_sharc_update } from "./shader/shader_sharc_update.js";
11
10
  import { SHARC_EVICTION_PERCENTAGE_LIMIT, SHARC_HASH_GRID_HASH_MAP_BUCKET_SIZE } from "./sharc_constants.js";
@@ -131,13 +130,12 @@ export class SpatialHashRadianceCache {
131
130
  const voxelData = resources.get(data.voxelData);
132
131
  const evictionBuffer = resources.get(data.evictionBuffer);
133
132
 
134
- const gridParameters = context.encoder.allocateTransientValueBuffer(
135
- HASH_GRID_PARAMETERS_STRUCT, {
136
- sceneScale: scene_scale,
137
- capacity,
138
- frame: frame_index,
139
- cameraPosition: camera.camera.transform.position.toArray()
140
- })
133
+ const gridParameters = {
134
+ sceneScale: scene_scale,
135
+ capacity,
136
+ frame: frame_index,
137
+ cameraPosition: camera.camera.transform.position.toArray()
138
+ };
141
139
 
142
140
  // run a compute shader to update the hash table
143
141
 
@@ -1 +1 @@
1
- {"version":3,"file":"shader_sharc_evict.d.ts","sourceRoot":"","sources":["../../../../../../../src/shade/renderer/global_illumination/sharc/shader/shader_sharc_evict.js"],"names":[],"mappings":"AAgGA,+CAIG;8BAhG2B,kCAAkC"}
1
+ {"version":3,"file":"shader_sharc_evict.d.ts","sourceRoot":"","sources":["../../../../../../../src/shade/renderer/global_illumination/sharc/shader/shader_sharc_evict.js"],"names":[],"mappings":"AAkGA,+CAIG;8BAlG2B,kCAAkC"}
@@ -26,8 +26,10 @@ const PUSH_CONSTANTS = WebGPUStruct.from({
26
26
  capacity: u32,
27
27
  });
28
28
 
29
+ // per-dispatch, eight bytes, read-only: immediate data rather than a uniform buffer
30
+ resources.setImmediate("settings", PUSH_CONSTANTS);
31
+
29
32
  resources.createGroup()
30
- .addUniform("settings", PUSH_CONSTANTS)
31
33
  .addStorageBuffer('hashMapData', HASH_MAP_DATA_STRUCT, true)
32
34
  .addStorageBuffer("voxelData", WebGPUArray.from(vec4u))
33
35
  .addStorageBuffer('evictionRequests', EVICTION_STRUCT);
@@ -1 +1 @@
1
- {"version":3,"file":"shader_sharc_update.d.ts","sourceRoot":"","sources":["../../../../../../../src/shade/renderer/global_illumination/sharc/shader/shader_sharc_update.js"],"names":[],"mappings":"AAiLA,gDAIG;8BAtK2B,kCAAkC"}
1
+ {"version":3,"file":"shader_sharc_update.d.ts","sourceRoot":"","sources":["../../../../../../../src/shade/renderer/global_illumination/sharc/shader/shader_sharc_update.js"],"names":[],"mappings":"AAmLA,gDAIG;8BAxK2B,kCAAkC"}
@@ -25,6 +25,9 @@ import { SHARC_VOXEL_DATUM_STRUCT } from "./SHARC_VOXEL_DATUM_STRUCT.js";
25
25
 
26
26
  const resources = new ShaderResourceSetDescriptor()
27
27
 
28
+ // per-dispatch, 32 bytes, read-only: immediate data rather than a uniform buffer
29
+ resources.setImmediate("gridParameters", HASH_GRID_PARAMETERS_STRUCT);
30
+
28
31
  resources.createGroup()
29
32
  .addTexture("tColor")
30
33
  .addTexture("tTrace", "uint")
@@ -38,7 +41,6 @@ const EVICTION_STRUCT = WebGPUStruct.from({
38
41
 
39
42
  resources.createGroup()
40
43
  .addUniform("camera", CAMERA_UNIFORM_STRUCT)
41
- .addUniform("gridParameters", HASH_GRID_PARAMETERS_STRUCT)
42
44
  .addStorageBuffer("evictionRequests", EVICTION_STRUCT, true)
43
45
  .addStorageBuffer("hashMapData", HASH_MAP_DATA_STRUCT, true)
44
46
  .addStorageBuffer("voxelData", WebGPUArray.from(vec4u), true)
@@ -231,9 +231,9 @@ builder is free to choose its own layout (§4.3).
231
231
  sequence, bindings, buffer sizes/usages, and host-written bytes;
232
232
  (d) browser playground verify functions (FrameGraph + `graph_import_typed_buffer` +
233
233
  `graph_inspect_gpu_buffer` readback + CPU assertions, registered as lil-gui "review checks");
234
- `gpu_test.js` offers a standalone device bootstrap. GPU timing via `GPUTimer` +
235
- `encoder.enable_debug_timers` (note: the `timer` argument `graph_compute_pass` forwards is
236
- silently dropped by `ComputeShader.dispatch` — use the debug-timers path).
234
+ `gpu_test.js` offers a standalone device bootstrap. GPU timing via `encoder.enable_profiling`
235
+ with a `GPUFrameRecorder` (note: the `timer` argument `graph_compute_pass` forwards is silently
236
+ dropped by `ComputeShader.dispatch` — use the profiler).
237
237
  - **Morton chunks** (`shader/chunk/bvh/morton/`): the fixed 10-bit `chunk_v3_morton_encode`,
238
238
  spec'd bit-exact against `v3_morton_encode_magicbits`, is what the build uses (§4.2) for exact
239
239
  CPU parity, alongside the 2D encode/decode pairs. A WGSL port of the DXR Fallback's
@@ -144,9 +144,9 @@ for BOTH the legacy compressor and the GPU layout against the same golden bytes.
144
144
  (duplicates, degenerate AABBs, N ∈ {0,1,2,3, 2^k±1, ~100k}), readback, assert structural
145
145
  validity (every leaf exactly once, both children valid, parent AABB ⊇ children, root word),
146
146
  payload permutation, **depth histogram**, SAH cost vs the CPU oracle fed the same sorted order
147
- (topology must match node-for-node modulo the index mapping). Wire `GPUTimer` numbers for the
148
- build via `encoder.enable_debug_timers` (the `timer` param on `graph_compute_pass` is silently
149
- dropped — known quirk, don't use it).
147
+ (topology must match node-for-node modulo the index mapping). Wire GPU timings for the build via
148
+ `encoder.enable_profiling` and a `GPUFrameRecorder` (the `timer` param on `graph_compute_pass` is
149
+ silently dropped — known quirk, don't use it).
150
150
 
151
151
  **M6 — hand back.** You cannot run the browser playground (meep is a library; the host repo
152
152
  mounts it). When `npm test` is green and everything above is in place: update
@@ -1,217 +1,217 @@
1
- import { assert } from "../../../../core/assert.js";
2
- import { round_up } from "../../../../core/math/round_up.js";
3
- import { BufferResourceDescriptor } from "../../../device/graph/BufferResourceDescriptor.js";
4
- import { BVH_HEADER_WORDS, bvh_buffer_size } from "./BVH_BUFFER_LAYOUT.js";
5
- import { graph_radix_sort } from "../sort/graph_radix_sort.js";
6
- import { BVH_BUILD_SETTINGS_STRUCT, BVH_NO_ROOT_WORD } from "./BVH_BUILD_SETTINGS_STRUCT.js";
7
- import { shader_bvh_emit_hierarchy } from "./shader_bvh_emit_hierarchy.js";
8
- import { shader_bvh_morton } from "./shader_bvh_morton.js";
9
- import { shader_bvh_refit } from "./shader_bvh_refit.js";
10
-
11
- /**
12
- * Record a GPU LBVH build over a flat set of leaves: Morton code, sort, Karras emission, bottom-up
13
- * refit. Everything scene- or geometry-specific happens upstream, in whichever extraction pass
14
- * produced `leaf_bounds` / `leaf_payload` / `scene_bounds` — this recorder knows only that it has
15
- * `element_count` boxes with payloads and somewhere to put a tree.
16
- *
17
- * The output honours the format in {@link BVH_BUFFER_LAYOUT}: a `u32` root word, then `2N-1` nodes
18
- * with internal nodes at `[0, N-2]` (root = 0, by Karras's construction) and leaf `j` at `(N-1)+j`.
19
- * That ordering differs from the CPU path's slot-order-with-holes, which is legal because no
20
- * consumer reads node *order* — only the node format and the root word. It is also exactly the
21
- * BLAS convention (root at node 0), which is why the same recorder serves the geometry side later.
22
- *
23
- * `element_count` must be at least 1. A single leaf falls out of the same passes with no special
24
- * case anywhere: the sort has nothing to reorder and returns its input, emission's tail `if` skips
25
- * the internal node and writes leaf 0 at node 0 with `parents[0] = BVH_NULL_NODE`, and the refit's
26
- * one thread reads that terminator and stops. The only thing it needs is a counters buffer WebGPU
27
- * will accept, since a tree of one leaf has no internal node to count arrivals at.
28
- *
29
- * Zero leaves is refused. There is no tree to write and no dispatch to make — the caller writes
30
- * `root = BVH_NULL_NODE` host-side, which is the four bytes consumers already read as "empty".
31
- *
32
- * @param {FrameGraph} graph
33
- * @param {number} leaf_bounds buffer resource ID, `array<f32>`, six floats per leaf: `[min.xyz, max.xyz]`
34
- * @param {number} leaf_payload buffer resource ID, `array<u32>`, one per leaf — becomes the leaf's `child_2`
35
- * @param {number} scene_bounds buffer resource ID, `array<f32>`, six floats bounding every leaf centroid
36
- * @param {number} element_count number of leaves, at least 1
37
- * @param {number} nodes buffer resource ID to write the tree into, at least `bvh_buffer_size(element_count)` bytes
38
- * @param {number} [node_word_offset] u32 word the tree's node 0 starts at. Defaults to
39
- * {@link BVH_HEADER_WORDS} — straight after a root word, which is what a tree that owns its buffer
40
- * wants. A tree living inside a shared arena passes its address there instead.
41
- * @param {number} [root_word_offset] u32 word to write the root index into, or
42
- * {@link BVH_NO_ROOT_WORD} for a format that has no header. Defaults to word 0.
43
- * @returns {{nodes: number, keys: number, values: number}} the written tree, plus the Morton order
44
- * it was built from — `values[i]` is the leaf that sorted to position `i`. The permutation is what a
45
- * refit-only update would rewrite leaves through, and what the verify harness feeds the CPU oracle
46
- * so that a topology comparison tests emission rather than float rounding in the quantiser.
47
- */
48
- export function graph_bvh_build_lbvh({
49
- graph,
50
- leaf_bounds,
51
- leaf_payload,
52
- scene_bounds,
53
- element_count,
54
- nodes,
55
- node_word_offset = BVH_HEADER_WORDS,
56
- root_word_offset = 0,
57
- }) {
58
-
59
- assert.defined(graph, 'graph');
60
- assert.isNonNegativeInteger(leaf_bounds, 'leaf_bounds');
61
- assert.isNonNegativeInteger(leaf_payload, 'leaf_payload');
62
- assert.isNonNegativeInteger(scene_bounds, 'scene_bounds');
63
- assert.isNonNegativeInteger(nodes, 'nodes');
64
- assert.isNonNegativeInteger(element_count, 'element_count');
65
- assert.greaterThanOrEqual(element_count, 1, 'element_count — an empty tree is written host-side');
66
- assert.isNonNegativeInteger(node_word_offset, 'node_word_offset');
67
- assert.isNonNegativeInteger(root_word_offset, 'root_word_offset');
68
-
69
- const node_count = 2 * element_count - 1;
70
-
71
- // aligned on a 1k boundary to lower memory fragmentation, as the sort's own transients are
72
- const KEY_DESCRIPTOR = BufferResourceDescriptor.from(
73
- round_up(element_count * Uint32Array.BYTES_PER_ELEMENT, 1024),
74
- GPUBufferUsage.STORAGE
75
- );
76
-
77
- const PARENTS_DESCRIPTOR = BufferResourceDescriptor.from(
78
- round_up(node_count * Uint32Array.BYTES_PER_ELEMENT, 1024),
79
- GPUBufferUsage.STORAGE
80
- );
81
-
82
- // One per internal node. A single-leaf tree has none, and a zero-sized buffer is not a thing
83
- // WebGPU will hand out, so it gets one cell that nothing ever touches.
84
- const counters_size = Math.max(1, element_count - 1) * Uint32Array.BYTES_PER_ELEMENT;
85
-
86
- // Every build needs these at zero. A fresh buffer arrives zeroed; a pool-reused one carries
87
- // the previous build's arrival counts, which would let a first arrival believe it was a second
88
- // and fit a node from a sibling that has not been written yet.
89
- const COUNTERS_DESCRIPTOR = BufferResourceDescriptor.from(
90
- counters_size,
91
- GPUBufferUsage.STORAGE,
92
- 0, counters_size
93
- );
94
-
95
- // The build owns its `parents` and `leaf_nodes` outright — they are transients of this graph,
96
- // one tree to a buffer — so both start at word 0.
97
- const settings = {
98
- element_count,
99
- node_word_offset,
100
- root_word_offset,
101
- parents_offset: 0,
102
- leaf_nodes_offset: 0,
103
- };
104
-
105
- /**
106
- * @param pass_data
107
- * @param {FramePassResources} resources
108
- * @param {GraphicsExecutionContext} context
109
- */
110
- function execute_morton(pass_data, resources, context) {
111
- const encoder = context.encoder;
112
-
113
- shader_bvh_morton.dispatchThreads({
114
- encoder,
115
- thread_count_x: element_count,
116
- bindings: {
117
- settings: encoder.allocateTransientValueBuffer(BVH_BUILD_SETTINGS_STRUCT, settings),
118
- leaf_bounds: resources.get(pass_data.leaf_bounds),
119
- scene_bounds: resources.get(pass_data.scene_bounds),
120
- keys: resources.get(pass_data.keys),
121
- values: resources.get(pass_data.values),
122
- }
123
- });
124
- }
125
-
126
- /**
127
- * @param pass_data
128
- * @param {FramePassResources} resources
129
- * @param {GraphicsExecutionContext} context
130
- */
131
- function execute_emit(pass_data, resources, context) {
132
- const encoder = context.encoder;
133
-
134
- const output = resources.get(pass_data.nodes);
135
-
136
- // the tree ends at its last node; where it starts is the caller's business
137
- const end_byte = (node_word_offset + (2 * element_count - 1) * 8) * Uint32Array.BYTES_PER_ELEMENT;
138
-
139
- assert.greaterThanOrEqual(output.size, end_byte, 'node buffer underflow');
140
-
141
- shader_bvh_emit_hierarchy.dispatchThreads({
142
- encoder,
143
- thread_count_x: element_count,
144
- bindings: {
145
- settings: encoder.allocateTransientValueBuffer(BVH_BUILD_SETTINGS_STRUCT, settings),
146
- keys: resources.get(pass_data.keys),
147
- values: resources.get(pass_data.values),
148
- leaf_bounds: resources.get(pass_data.leaf_bounds),
149
- leaf_payload: resources.get(pass_data.leaf_payload),
150
- nodes: output,
151
- parents: resources.get(pass_data.parents),
152
- leaf_nodes: resources.get(pass_data.leaf_nodes),
153
- }
154
- });
155
- }
156
-
157
- /**
158
- * @param pass_data
159
- * @param {FramePassResources} resources
160
- * @param {GraphicsExecutionContext} context
161
- */
162
- function execute_refit(pass_data, resources, context) {
163
- const encoder = context.encoder;
164
-
165
- shader_bvh_refit.dispatchThreads({
166
- encoder,
167
- thread_count_x: element_count,
168
- bindings: {
169
- settings: encoder.allocateTransientValueBuffer(BVH_BUILD_SETTINGS_STRUCT, settings),
170
- parents: resources.get(pass_data.parents),
171
- leaf_nodes: resources.get(pass_data.leaf_nodes),
172
- counters: resources.get(pass_data.counters),
173
- nodes: resources.get(pass_data.nodes),
174
- }
175
- });
176
- }
177
-
178
- const morton_data = {};
179
- const morton_pass = graph.add("bvh build/morton", morton_data, execute_morton);
180
-
181
- morton_data.leaf_bounds = morton_pass.read(leaf_bounds);
182
- morton_data.scene_bounds = morton_pass.read(scene_bounds);
183
- morton_data.keys = morton_pass.create("bvh build/morton keys", KEY_DESCRIPTOR);
184
- morton_data.values = morton_pass.create("bvh build/leaf order", KEY_DESCRIPTOR);
185
-
186
- const sorted = graph_radix_sort({
187
- graph,
188
- keys: morton_data.keys,
189
- values: morton_data.values,
190
- element_count,
191
- });
192
-
193
- const emit_data = {};
194
- const emit_pass = graph.add("bvh build/emit hierarchy", emit_data, execute_emit);
195
-
196
- emit_data.keys = emit_pass.read(sorted.keys);
197
- emit_data.values = emit_pass.read(sorted.values);
198
- emit_data.leaf_bounds = emit_pass.read(leaf_bounds);
199
- emit_data.leaf_payload = emit_pass.read(leaf_payload);
200
- emit_data.nodes = emit_pass.write(nodes);
201
- emit_data.parents = emit_pass.create("bvh build/parents", PARENTS_DESCRIPTOR);
202
- emit_data.leaf_nodes = emit_pass.create("bvh build/leaf nodes", KEY_DESCRIPTOR);
203
-
204
- const refit_data = {};
205
- const refit_pass = graph.add("bvh build/refit", refit_data, execute_refit);
206
-
207
- refit_data.parents = refit_pass.read(emit_data.parents);
208
- refit_data.leaf_nodes = refit_pass.read(emit_data.leaf_nodes);
209
- refit_data.counters = refit_pass.create("bvh build/refit counters", COUNTERS_DESCRIPTOR);
210
- refit_data.nodes = refit_pass.write(emit_data.nodes);
211
-
212
- return {
213
- nodes: refit_data.nodes,
214
- keys: sorted.keys,
215
- values: sorted.values,
216
- };
217
- }
1
+ import { assert } from "../../../../core/assert.js";
2
+ import { round_up } from "../../../../core/math/round_up.js";
3
+ import { BufferResourceDescriptor } from "../../../device/graph/BufferResourceDescriptor.js";
4
+ import { BVH_HEADER_WORDS, bvh_buffer_size } from "./BVH_BUFFER_LAYOUT.js";
5
+ import { graph_radix_sort } from "../sort/graph_radix_sort.js";
6
+ import { BVH_NO_ROOT_WORD } from "./BVH_BUILD_SETTINGS_STRUCT.js";
7
+ import { shader_bvh_emit_hierarchy } from "./shader_bvh_emit_hierarchy.js";
8
+ import { shader_bvh_morton } from "./shader_bvh_morton.js";
9
+ import { shader_bvh_refit } from "./shader_bvh_refit.js";
10
+
11
+ /**
12
+ * Record a GPU LBVH build over a flat set of leaves: Morton code, sort, Karras emission, bottom-up
13
+ * refit. Everything scene- or geometry-specific happens upstream, in whichever extraction pass
14
+ * produced `leaf_bounds` / `leaf_payload` / `scene_bounds` — this recorder knows only that it has
15
+ * `element_count` boxes with payloads and somewhere to put a tree.
16
+ *
17
+ * The output honours the format in {@link BVH_BUFFER_LAYOUT}: a `u32` root word, then `2N-1` nodes
18
+ * with internal nodes at `[0, N-2]` (root = 0, by Karras's construction) and leaf `j` at `(N-1)+j`.
19
+ * That ordering differs from the CPU path's slot-order-with-holes, which is legal because no
20
+ * consumer reads node *order* — only the node format and the root word. It is also exactly the
21
+ * BLAS convention (root at node 0), which is why the same recorder serves the geometry side later.
22
+ *
23
+ * `element_count` must be at least 1. A single leaf falls out of the same passes with no special
24
+ * case anywhere: the sort has nothing to reorder and returns its input, emission's tail `if` skips
25
+ * the internal node and writes leaf 0 at node 0 with `parents[0] = BVH_NULL_NODE`, and the refit's
26
+ * one thread reads that terminator and stops. The only thing it needs is a counters buffer WebGPU
27
+ * will accept, since a tree of one leaf has no internal node to count arrivals at.
28
+ *
29
+ * Zero leaves is refused. There is no tree to write and no dispatch to make — the caller writes
30
+ * `root = BVH_NULL_NODE` host-side, which is the four bytes consumers already read as "empty".
31
+ *
32
+ * @param {FrameGraph} graph
33
+ * @param {number} leaf_bounds buffer resource ID, `array<f32>`, six floats per leaf: `[min.xyz, max.xyz]`
34
+ * @param {number} leaf_payload buffer resource ID, `array<u32>`, one per leaf — becomes the leaf's `child_2`
35
+ * @param {number} scene_bounds buffer resource ID, `array<f32>`, six floats bounding every leaf centroid
36
+ * @param {number} element_count number of leaves, at least 1
37
+ * @param {number} nodes buffer resource ID to write the tree into, at least `bvh_buffer_size(element_count)` bytes
38
+ * @param {number} [node_word_offset] u32 word the tree's node 0 starts at. Defaults to
39
+ * {@link BVH_HEADER_WORDS} — straight after a root word, which is what a tree that owns its buffer
40
+ * wants. A tree living inside a shared arena passes its address there instead.
41
+ * @param {number} [root_word_offset] u32 word to write the root index into, or
42
+ * {@link BVH_NO_ROOT_WORD} for a format that has no header. Defaults to word 0.
43
+ * @returns {{nodes: number, keys: number, values: number}} the written tree, plus the Morton order
44
+ * it was built from — `values[i]` is the leaf that sorted to position `i`. The permutation is what a
45
+ * refit-only update would rewrite leaves through, and what the verify harness feeds the CPU oracle
46
+ * so that a topology comparison tests emission rather than float rounding in the quantiser.
47
+ */
48
+ export function graph_bvh_build_lbvh({
49
+ graph,
50
+ leaf_bounds,
51
+ leaf_payload,
52
+ scene_bounds,
53
+ element_count,
54
+ nodes,
55
+ node_word_offset = BVH_HEADER_WORDS,
56
+ root_word_offset = 0,
57
+ }) {
58
+
59
+ assert.defined(graph, 'graph');
60
+ assert.isNonNegativeInteger(leaf_bounds, 'leaf_bounds');
61
+ assert.isNonNegativeInteger(leaf_payload, 'leaf_payload');
62
+ assert.isNonNegativeInteger(scene_bounds, 'scene_bounds');
63
+ assert.isNonNegativeInteger(nodes, 'nodes');
64
+ assert.isNonNegativeInteger(element_count, 'element_count');
65
+ assert.greaterThanOrEqual(element_count, 1, 'element_count — an empty tree is written host-side');
66
+ assert.isNonNegativeInteger(node_word_offset, 'node_word_offset');
67
+ assert.isNonNegativeInteger(root_word_offset, 'root_word_offset');
68
+
69
+ const node_count = 2 * element_count - 1;
70
+
71
+ // aligned on a 1k boundary to lower memory fragmentation, as the sort's own transients are
72
+ const KEY_DESCRIPTOR = BufferResourceDescriptor.from(
73
+ round_up(element_count * Uint32Array.BYTES_PER_ELEMENT, 1024),
74
+ GPUBufferUsage.STORAGE
75
+ );
76
+
77
+ const PARENTS_DESCRIPTOR = BufferResourceDescriptor.from(
78
+ round_up(node_count * Uint32Array.BYTES_PER_ELEMENT, 1024),
79
+ GPUBufferUsage.STORAGE
80
+ );
81
+
82
+ // One per internal node. A single-leaf tree has none, and a zero-sized buffer is not a thing
83
+ // WebGPU will hand out, so it gets one cell that nothing ever touches.
84
+ const counters_size = Math.max(1, element_count - 1) * Uint32Array.BYTES_PER_ELEMENT;
85
+
86
+ // Every build needs these at zero. A fresh buffer arrives zeroed; a pool-reused one carries
87
+ // the previous build's arrival counts, which would let a first arrival believe it was a second
88
+ // and fit a node from a sibling that has not been written yet.
89
+ const COUNTERS_DESCRIPTOR = BufferResourceDescriptor.from(
90
+ counters_size,
91
+ GPUBufferUsage.STORAGE,
92
+ 0, counters_size
93
+ );
94
+
95
+ // The build owns its `parents` and `leaf_nodes` outright — they are transients of this graph,
96
+ // one tree to a buffer — so both start at word 0.
97
+ const settings = {
98
+ element_count,
99
+ node_word_offset,
100
+ root_word_offset,
101
+ parents_offset: 0,
102
+ leaf_nodes_offset: 0,
103
+ };
104
+
105
+ /**
106
+ * @param pass_data
107
+ * @param {FramePassResources} resources
108
+ * @param {GraphicsExecutionContext} context
109
+ */
110
+ function execute_morton(pass_data, resources, context) {
111
+ const encoder = context.encoder;
112
+
113
+ shader_bvh_morton.dispatchThreads({
114
+ encoder,
115
+ thread_count_x: element_count,
116
+ bindings: {
117
+ settings: settings,
118
+ leaf_bounds: resources.get(pass_data.leaf_bounds),
119
+ scene_bounds: resources.get(pass_data.scene_bounds),
120
+ keys: resources.get(pass_data.keys),
121
+ values: resources.get(pass_data.values),
122
+ }
123
+ });
124
+ }
125
+
126
+ /**
127
+ * @param pass_data
128
+ * @param {FramePassResources} resources
129
+ * @param {GraphicsExecutionContext} context
130
+ */
131
+ function execute_emit(pass_data, resources, context) {
132
+ const encoder = context.encoder;
133
+
134
+ const output = resources.get(pass_data.nodes);
135
+
136
+ // the tree ends at its last node; where it starts is the caller's business
137
+ const end_byte = (node_word_offset + (2 * element_count - 1) * 8) * Uint32Array.BYTES_PER_ELEMENT;
138
+
139
+ assert.greaterThanOrEqual(output.size, end_byte, 'node buffer underflow');
140
+
141
+ shader_bvh_emit_hierarchy.dispatchThreads({
142
+ encoder,
143
+ thread_count_x: element_count,
144
+ bindings: {
145
+ settings: settings,
146
+ keys: resources.get(pass_data.keys),
147
+ values: resources.get(pass_data.values),
148
+ leaf_bounds: resources.get(pass_data.leaf_bounds),
149
+ leaf_payload: resources.get(pass_data.leaf_payload),
150
+ nodes: output,
151
+ parents: resources.get(pass_data.parents),
152
+ leaf_nodes: resources.get(pass_data.leaf_nodes),
153
+ }
154
+ });
155
+ }
156
+
157
+ /**
158
+ * @param pass_data
159
+ * @param {FramePassResources} resources
160
+ * @param {GraphicsExecutionContext} context
161
+ */
162
+ function execute_refit(pass_data, resources, context) {
163
+ const encoder = context.encoder;
164
+
165
+ shader_bvh_refit.dispatchThreads({
166
+ encoder,
167
+ thread_count_x: element_count,
168
+ bindings: {
169
+ settings: settings,
170
+ parents: resources.get(pass_data.parents),
171
+ leaf_nodes: resources.get(pass_data.leaf_nodes),
172
+ counters: resources.get(pass_data.counters),
173
+ nodes: resources.get(pass_data.nodes),
174
+ }
175
+ });
176
+ }
177
+
178
+ const morton_data = {};
179
+ const morton_pass = graph.add("bvh build/morton", morton_data, execute_morton);
180
+
181
+ morton_data.leaf_bounds = morton_pass.read(leaf_bounds);
182
+ morton_data.scene_bounds = morton_pass.read(scene_bounds);
183
+ morton_data.keys = morton_pass.create("bvh build/morton keys", KEY_DESCRIPTOR);
184
+ morton_data.values = morton_pass.create("bvh build/leaf order", KEY_DESCRIPTOR);
185
+
186
+ const sorted = graph_radix_sort({
187
+ graph,
188
+ keys: morton_data.keys,
189
+ values: morton_data.values,
190
+ element_count,
191
+ });
192
+
193
+ const emit_data = {};
194
+ const emit_pass = graph.add("bvh build/emit hierarchy", emit_data, execute_emit);
195
+
196
+ emit_data.keys = emit_pass.read(sorted.keys);
197
+ emit_data.values = emit_pass.read(sorted.values);
198
+ emit_data.leaf_bounds = emit_pass.read(leaf_bounds);
199
+ emit_data.leaf_payload = emit_pass.read(leaf_payload);
200
+ emit_data.nodes = emit_pass.write(nodes);
201
+ emit_data.parents = emit_pass.create("bvh build/parents", PARENTS_DESCRIPTOR);
202
+ emit_data.leaf_nodes = emit_pass.create("bvh build/leaf nodes", KEY_DESCRIPTOR);
203
+
204
+ const refit_data = {};
205
+ const refit_pass = graph.add("bvh build/refit", refit_data, execute_refit);
206
+
207
+ refit_data.parents = refit_pass.read(emit_data.parents);
208
+ refit_data.leaf_nodes = refit_pass.read(emit_data.leaf_nodes);
209
+ refit_data.counters = refit_pass.create("bvh build/refit counters", COUNTERS_DESCRIPTOR);
210
+ refit_data.nodes = refit_pass.write(emit_data.nodes);
211
+
212
+ return {
213
+ nodes: refit_data.nodes,
214
+ keys: sorted.keys,
215
+ values: sorted.values,
216
+ };
217
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"shader_bvh_emit_hierarchy.d.ts","sourceRoot":"","sources":["../../../../../../src/shade/renderer/gpu_primitive/bvh/shader_bvh_emit_hierarchy.js"],"names":[],"mappings":"AAgBA,yCAA0C;AAqG1C;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wCAFU,aAAa,CAMpB;8BAzI2B,+BAA+B"}
1
+ {"version":3,"file":"shader_bvh_emit_hierarchy.d.ts","sourceRoot":"","sources":["../../../../../../src/shade/renderer/gpu_primitive/bvh/shader_bvh_emit_hierarchy.js"],"names":[],"mappings":"AAgBA,yCAA0C;AAwG1C;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wCAFU,aAAa,CAMpB;8BA5I2B,+BAA+B"}