@woosh/meep-engine 3.47.0 → 3.49.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 (619) hide show
  1. package/build/bundle-worker-terrain.js +1 -1
  2. package/editor/particles/effect/ParticleReferenceSimulation.d.ts +1 -2
  3. package/editor/particles/effect/ParticleReferenceSimulation.d.ts.map +1 -1
  4. package/editor/particles/effect/ParticleReferenceSimulation.js +2 -4
  5. package/editor/view/particles/effect/ParticleGraphEditorView.js +1 -1
  6. package/package.json +1 -1
  7. package/src/engine/ecs/async/WORKER_SYSTEM_PLAN.md +27 -11
  8. package/src/engine/ecs/storage/populateEngineSerializationRegistry.d.ts.map +1 -1
  9. package/src/engine/ecs/storage/populateEngineSerializationRegistry.js +11 -0
  10. package/src/engine/graphics/ecs/particles/ParticleEffect.d.ts +2 -2
  11. package/src/engine/graphics/ecs/particles/ParticleEffect.d.ts.map +1 -1
  12. package/src/engine/graphics/ecs/particles/ParticleEffect.js +7 -7
  13. package/src/engine/graphics/ecs/particles/ParticleEffectSerializationAdapter.d.ts +8 -0
  14. package/src/engine/graphics/ecs/particles/ParticleEffectSerializationAdapter.d.ts.map +1 -1
  15. package/src/engine/graphics/ecs/particles/ParticleEffectSerializationAdapter.js +11 -3
  16. package/src/engine/graphics/ecs/particles/ParticleEffectSerializationUpgrader_1_2.d.ts +26 -0
  17. package/src/engine/graphics/ecs/particles/ParticleEffectSerializationUpgrader_1_2.d.ts.map +1 -0
  18. package/src/engine/graphics/ecs/particles/ParticleEffectSerializationUpgrader_1_2.js +91 -0
  19. package/src/engine/graphics3/GPUParticleEmitterSystem.js +2 -2
  20. package/src/engine/graphics3/GraphicsEngine.d.ts.map +1 -1
  21. package/src/engine/graphics3/GraphicsEngine.js +8 -1
  22. package/src/engine/graphics3/ParticipatingMedia.d.ts +84 -1
  23. package/src/engine/graphics3/ParticipatingMedia.d.ts.map +1 -1
  24. package/src/engine/graphics3/ParticipatingMedia.js +139 -5
  25. package/src/engine/graphics3/ParticipatingMediaSerializationAdapter.d.ts +6 -2
  26. package/src/engine/graphics3/ParticipatingMediaSerializationAdapter.d.ts.map +1 -1
  27. package/src/engine/graphics3/ParticipatingMediaSerializationAdapter.js +29 -4
  28. package/src/engine/graphics3/ParticipatingMediaSerializationUpgrader_0_1.d.ts +10 -0
  29. package/src/engine/graphics3/ParticipatingMediaSerializationUpgrader_0_1.d.ts.map +1 -0
  30. package/src/engine/graphics3/ParticipatingMediaSerializationUpgrader_0_1.js +38 -0
  31. package/src/engine/graphics3/ParticipatingMediaSystem.d.ts.map +1 -1
  32. package/src/engine/graphics3/ParticipatingMediaSystem.js +46 -3
  33. package/src/engine/network/NetworkSession.d.ts +16 -5
  34. package/src/engine/network/NetworkSession.d.ts.map +1 -1
  35. package/src/engine/network/NetworkSession.js +104 -7
  36. package/src/engine/network/README.md +27 -1
  37. package/src/engine/network/orchestrator/ServerAuthoritativeServer.d.ts +40 -18
  38. package/src/engine/network/orchestrator/ServerAuthoritativeServer.d.ts.map +1 -1
  39. package/src/engine/network/orchestrator/ServerAuthoritativeServer.js +180 -190
  40. package/src/engine/network/replication/Replicator.d.ts +15 -4
  41. package/src/engine/network/replication/Replicator.d.ts.map +1 -1
  42. package/src/engine/network/replication/Replicator.js +50 -16
  43. package/src/engine/network/state/RecordArrivalRing.d.ts +57 -0
  44. package/src/engine/network/state/RecordArrivalRing.d.ts.map +1 -0
  45. package/src/engine/network/state/RecordArrivalRing.js +144 -0
  46. package/src/engine/physics/cloth/MEASUREMENTS.md +354 -0
  47. package/src/engine/physics/cloth/PLAN.md +85 -5
  48. package/src/engine/physics/cloth/ecs/ClothInstance.d.ts +0 -12
  49. package/src/engine/physics/cloth/ecs/ClothInstance.d.ts.map +1 -1
  50. package/src/engine/physics/cloth/ecs/ClothInstance.js +0 -13
  51. package/src/engine/physics/cloth/ecs/ClothSystem.d.ts +2 -1
  52. package/src/engine/physics/cloth/ecs/ClothSystem.d.ts.map +1 -1
  53. package/src/engine/physics/cloth/ecs/ClothSystem.js +7 -1
  54. package/src/engine/physics/cloth/ecs/ClothWorld.d.ts.map +1 -1
  55. package/src/engine/physics/cloth/ecs/ClothWorld.js +4 -15
  56. package/src/engine/physics/cloth/ecs/WorkerClothSystem.d.ts +2 -1
  57. package/src/engine/physics/cloth/ecs/WorkerClothSystem.d.ts.map +1 -1
  58. package/src/engine/physics/cloth/ecs/WorkerClothSystem.js +6 -1
  59. package/src/engine/physics/cloth/ecs/cloth_build_rows.d.ts.map +1 -1
  60. package/src/engine/physics/cloth/ecs/cloth_build_rows.js +20 -10
  61. package/src/engine/physics/cloth/playground/collide.html +5 -3
  62. package/src/engine/physics/cloth/playground/collide_main.js +14 -13
  63. package/src/engine/physics/cloth/solver/ClothState.d.ts +30 -2
  64. package/src/engine/physics/cloth/solver/ClothState.d.ts.map +1 -1
  65. package/src/engine/physics/cloth/solver/ClothState.js +62 -4
  66. package/src/engine/physics/cloth/solver/cloth_self_find.d.ts +11 -3
  67. package/src/engine/physics/cloth/solver/cloth_self_find.d.ts.map +1 -1
  68. package/src/engine/physics/cloth/solver/cloth_self_find.js +52 -11
  69. package/src/engine/physics/cloth/solver/cloth_self_radius.d.ts +42 -0
  70. package/src/engine/physics/cloth/solver/cloth_self_radius.d.ts.map +1 -0
  71. package/src/engine/physics/cloth/solver/cloth_self_radius.js +64 -0
  72. package/src/engine/physics/cloth/solver/cloth_solver_constants.d.ts +99 -24
  73. package/src/engine/physics/cloth/solver/cloth_solver_constants.d.ts.map +1 -1
  74. package/src/engine/physics/cloth/solver/cloth_solver_constants.js +102 -25
  75. package/src/engine/physics/cloth/solver/cloth_step.d.ts +5 -1
  76. package/src/engine/physics/cloth/solver/cloth_step.d.ts.map +1 -1
  77. package/src/engine/physics/cloth/solver/cloth_step.js +13 -3
  78. package/src/engine/physics/cloth/solver/cloth_step_instance.d.ts +0 -1
  79. package/src/engine/physics/cloth/solver/cloth_step_instance.d.ts.map +1 -1
  80. package/src/engine/physics/cloth/solver/cloth_step_instance.js +12 -14
  81. package/src/engine/physics/cloth/solver/constraint/cloth_contact_row.d.ts +23 -4
  82. package/src/engine/physics/cloth/solver/constraint/cloth_contact_row.d.ts.map +1 -1
  83. package/src/engine/physics/cloth/solver/constraint/cloth_contact_row.js +36 -8
  84. package/src/engine/physics/cloth/solver/constraint/cloth_self_row.d.ts.map +1 -1
  85. package/src/engine/physics/cloth/solver/constraint/cloth_self_row.js +4 -2
  86. package/src/engine/physics/fluid/ecs/FluidObstacleSystem.d.ts +4 -4
  87. package/src/shade/device/mock/SoftwareGPUDevice.d.ts +15 -0
  88. package/src/shade/device/mock/SoftwareGPUDevice.d.ts.map +1 -1
  89. package/src/shade/device/mock/SoftwareGPUDevice.js +21 -0
  90. package/src/shade/device/pipeline/ComputePipelineManager.d.ts +20 -0
  91. package/src/shade/device/pipeline/ComputePipelineManager.d.ts.map +1 -1
  92. package/src/shade/device/pipeline/ComputePipelineManager.js +80 -6
  93. package/src/shade/device/pipeline/PipelineEnquiry.d.ts +52 -0
  94. package/src/shade/device/pipeline/PipelineEnquiry.d.ts.map +1 -0
  95. package/src/shade/device/pipeline/PipelineEnquiry.js +63 -0
  96. package/src/shade/device/pipeline/RenderPipelineManager.d.ts +21 -0
  97. package/src/shade/device/pipeline/RenderPipelineManager.d.ts.map +1 -1
  98. package/src/shade/device/pipeline/RenderPipelineManager.js +84 -4
  99. package/src/shade/playground/contact_shadows/ContactShadowLab.d.ts +137 -0
  100. package/src/shade/playground/contact_shadows/ContactShadowLab.d.ts.map +1 -0
  101. package/src/shade/playground/contact_shadows/ContactShadowLab.js +654 -0
  102. package/src/shade/playground/contact_shadows/README.md +126 -0
  103. package/src/shade/playground/contact_shadows/index.html +191 -0
  104. package/src/shade/playground/contact_shadows/main.d.ts +2 -0
  105. package/src/shade/playground/contact_shadows/main.d.ts.map +1 -0
  106. package/src/shade/playground/contact_shadows/main.js +888 -0
  107. package/src/shade/playground/contact_shadows/scenes.d.ts +48 -0
  108. package/src/shade/playground/contact_shadows/scenes.d.ts.map +1 -0
  109. package/src/shade/playground/contact_shadows/scenes.js +620 -0
  110. package/src/shade/playground/contact_shadows/shader_contact_lab_composite.d.ts +36 -0
  111. package/src/shade/playground/contact_shadows/shader_contact_lab_composite.d.ts.map +1 -0
  112. package/src/shade/playground/contact_shadows/shader_contact_lab_composite.js +245 -0
  113. package/src/shade/playground/contact_shadows/shader_contact_lab_reference.d.ts +15 -0
  114. package/src/shade/playground/contact_shadows/shader_contact_lab_reference.d.ts.map +1 -0
  115. package/src/shade/playground/contact_shadows/shader_contact_lab_reference.js +120 -0
  116. package/src/shade/playground/contact_shadows/shader_contact_lab_stats.d.ts +55 -0
  117. package/src/shade/playground/contact_shadows/shader_contact_lab_stats.d.ts.map +1 -0
  118. package/src/shade/playground/contact_shadows/shader_contact_lab_stats.js +216 -0
  119. package/src/shade/playground/contact_shadows/shader_contact_lab_view.d.ts +20 -0
  120. package/src/shade/playground/contact_shadows/shader_contact_lab_view.d.ts.map +1 -0
  121. package/src/shade/playground/contact_shadows/shader_contact_lab_view.js +114 -0
  122. package/src/shade/playground/contact_shadows/shader_contact_shadow_march.d.ts +11 -0
  123. package/src/shade/playground/contact_shadows/shader_contact_shadow_march.d.ts.map +1 -0
  124. package/src/shade/playground/contact_shadows/shader_contact_shadow_march.js +90 -0
  125. package/src/shade/playground/contact_shadows/textures.d.ts +16 -0
  126. package/src/shade/playground/contact_shadows/textures.d.ts.map +1 -0
  127. package/src/shade/playground/contact_shadows/textures.js +123 -0
  128. package/src/shade/playground/particle_ecs/README.md +1 -1
  129. package/src/shade/playground/particle_ecs/effects/flame.json +1932 -1881
  130. package/src/shade/playground/particle_ecs/effects/smoke.json +99 -1
  131. package/src/shade/playground/particle_ecs/effects/soot.json +152 -145
  132. package/src/shade/playground/tonemap_sdr/README.md +90 -0
  133. package/src/shade/playground/tonemap_sdr/ToneMapCompare.d.ts +105 -0
  134. package/src/shade/playground/tonemap_sdr/ToneMapCompare.d.ts.map +1 -0
  135. package/src/shade/playground/tonemap_sdr/ToneMapCompare.js +380 -0
  136. package/src/shade/playground/tonemap_sdr/chunk_tonemap_gt7_sdr_reference.d.ts +32 -0
  137. package/src/shade/playground/tonemap_sdr/chunk_tonemap_gt7_sdr_reference.d.ts.map +1 -0
  138. package/src/shade/playground/tonemap_sdr/chunk_tonemap_gt7_sdr_reference.js +104 -0
  139. package/src/shade/playground/tonemap_sdr/index.html +90 -0
  140. package/src/shade/playground/tonemap_sdr/main.d.ts +2 -0
  141. package/src/shade/playground/tonemap_sdr/main.d.ts.map +1 -0
  142. package/src/shade/playground/tonemap_sdr/main.js +306 -0
  143. package/src/shade/playground/tonemap_sdr/scenes.d.ts +26 -0
  144. package/src/shade/playground/tonemap_sdr/scenes.d.ts.map +1 -0
  145. package/src/shade/playground/tonemap_sdr/scenes.js +404 -0
  146. package/src/shade/playground/volumetrics_froxel/main.d.ts.map +1 -1
  147. package/src/shade/playground/volumetrics_froxel/main.js +85 -4
  148. package/src/shade/playground/water_refraction/README.md +26 -18
  149. package/src/shade/playground/water_refraction/index.html +1 -1
  150. package/src/shade/renderer/Renderer.d.ts +35 -3
  151. package/src/shade/renderer/Renderer.d.ts.map +1 -1
  152. package/src/shade/renderer/Renderer.js +208 -12
  153. package/src/shade/renderer/ShadeToneMappingMode.d.ts +14 -0
  154. package/src/shade/renderer/ShadeToneMappingMode.d.ts.map +1 -0
  155. package/src/shade/renderer/ShadeToneMappingMode.js +30 -0
  156. package/src/shade/renderer/animation/GPUAnimationManager.d.ts +9 -0
  157. package/src/shade/renderer/animation/GPUAnimationManager.d.ts.map +1 -1
  158. package/src/shade/renderer/animation/GPUAnimationManager.js +14 -0
  159. package/src/shade/renderer/animation/skinning/shader_meshlet_apply_skinning.d.ts.map +1 -1
  160. package/src/shade/renderer/animation/skinning/shader_meshlet_apply_skinning.js +5 -3
  161. package/src/shade/renderer/buffer/table/GPUDatabase.d.ts +7 -0
  162. package/src/shade/renderer/buffer/table/GPUDatabase.d.ts.map +1 -1
  163. package/src/shade/renderer/buffer/table/GPUDatabase.js +12 -0
  164. package/src/shade/renderer/buffer/table/single/GPUSingleTypeTable.d.ts +8 -0
  165. package/src/shade/renderer/buffer/table/single/GPUSingleTypeTable.d.ts.map +1 -1
  166. package/src/shade/renderer/buffer/table/single/GPUSingleTypeTable.js +12 -0
  167. package/src/shade/renderer/camera/GPUCameraContext.d.ts.map +1 -1
  168. package/src/shade/renderer/camera/GPUCameraContext.js +19 -8
  169. package/src/shade/renderer/deferred/chunk_read_gBuffer_material.d.ts.map +1 -1
  170. package/src/shade/renderer/deferred/chunk_read_gBuffer_material.js +4 -0
  171. package/src/shade/renderer/deferred/chunk_shade_standard_material_direct.d.ts.map +1 -1
  172. package/src/shade/renderer/deferred/chunk_shade_standard_material_direct.js +4 -0
  173. package/src/shade/renderer/deferred/chunk_shade_standard_material_direct_restir.d.ts.map +1 -1
  174. package/src/shade/renderer/deferred/chunk_shade_standard_material_direct_restir.js +4 -0
  175. package/src/shade/renderer/deferred/shader_deferred_main.d.ts.map +1 -1
  176. package/src/shade/renderer/deferred/shader_deferred_main.js +3 -0
  177. package/src/shade/renderer/deferred/shader_tonemap_HDR.d.ts +6 -0
  178. package/src/shade/renderer/deferred/shader_tonemap_HDR.d.ts.map +1 -1
  179. package/src/shade/renderer/deferred/shader_tonemap_HDR.js +13 -3
  180. package/src/shade/renderer/deferred/shader_tonemap_HDR_none.d.ts +9 -0
  181. package/src/shade/renderer/deferred/shader_tonemap_HDR_none.d.ts.map +1 -0
  182. package/src/shade/renderer/deferred/shader_tonemap_HDR_none.js +63 -0
  183. package/src/shade/renderer/deferred/shader_tonemap_HDR_pbr_neutral.d.ts +10 -0
  184. package/src/shade/renderer/deferred/shader_tonemap_HDR_pbr_neutral.d.ts.map +1 -0
  185. package/src/shade/renderer/deferred/shader_tonemap_HDR_pbr_neutral.js +87 -0
  186. package/src/shade/renderer/deferred/shader_tonemap_LDR.d.ts +6 -0
  187. package/src/shade/renderer/deferred/shader_tonemap_LDR.d.ts.map +1 -1
  188. package/src/shade/renderer/deferred/shader_tonemap_LDR.js +23 -5
  189. package/src/shade/renderer/deferred/shader_tonemap_LDR_none.d.ts +9 -0
  190. package/src/shade/renderer/deferred/shader_tonemap_LDR_none.d.ts.map +1 -0
  191. package/src/shade/renderer/deferred/shader_tonemap_LDR_none.js +68 -0
  192. package/src/shade/renderer/deferred/shader_tonemap_LDR_pbr_neutral.d.ts +10 -0
  193. package/src/shade/renderer/deferred/shader_tonemap_LDR_pbr_neutral.d.ts.map +1 -0
  194. package/src/shade/renderer/deferred/shader_tonemap_LDR_pbr_neutral.js +73 -0
  195. package/src/shade/renderer/geometry/meshlet/MeshletBatch.d.ts.map +1 -1
  196. package/src/shade/renderer/geometry/meshlet/MeshletBatch.js +58 -9
  197. package/src/shade/renderer/geometry/sdf/GPUGeometrySDFManager.d.ts +35 -25
  198. package/src/shade/renderer/geometry/sdf/GPUGeometrySDFManager.d.ts.map +1 -1
  199. package/src/shade/renderer/geometry/sdf/GPUGeometrySDFManager.js +97 -196
  200. package/src/shade/renderer/geometry/sdf/shader_build_sdf.d.ts.map +1 -1
  201. package/src/shade/renderer/geometry/sdf/shader_build_sdf.js +121 -129
  202. package/src/shade/renderer/global_illumination/brick4/gpu/bake/brick4_bake_basic.d.ts.map +1 -1
  203. package/src/shade/renderer/global_illumination/brick4/gpu/bake/brick4_bake_basic.js +3 -0
  204. package/src/shade/renderer/global_illumination/brick4/gpu/bake/shader_brick4_bake_probes.d.ts.map +1 -1
  205. package/src/shade/renderer/global_illumination/brick4/gpu/bake/shader_brick4_bake_probes.js +4 -0
  206. package/src/shade/renderer/global_illumination/brick4/gpu/draw/shader_brick4_indirect_lighting.d.ts.map +1 -1
  207. package/src/shade/renderer/global_illumination/brick4/gpu/draw/shader_brick4_indirect_lighting.js +4 -0
  208. package/src/shade/renderer/global_illumination/lpv/bake/GPULightProbeVolumeRenderer.d.ts.map +1 -1
  209. package/src/shade/renderer/global_illumination/lpv/bake/GPULightProbeVolumeRenderer.js +3 -0
  210. package/src/shade/renderer/global_illumination/lpv/deprecated/probe_trace_compute_shader_code.d.ts.map +1 -1
  211. package/src/shade/renderer/global_illumination/lpv/deprecated/probe_trace_compute_shader_code.js +4 -0
  212. package/src/shade/renderer/global_illumination/probe/octahedral/graph_sample_light_probes.d.ts.map +1 -1
  213. package/src/shade/renderer/global_illumination/probe/octahedral/graph_sample_light_probes.js +4 -0
  214. package/src/shade/renderer/global_illumination/shader_resolve_indirect_lighting.d.ts.map +1 -1
  215. package/src/shade/renderer/global_illumination/shader_resolve_indirect_lighting.js +4 -0
  216. package/src/shade/renderer/gpu_primitive/bvh/GPU_BVH_BUILD_PLAN.md +131 -1
  217. package/src/shade/renderer/gpu_primitive/bvh/chunk_bvh_delta.d.ts +7 -0
  218. package/src/shade/renderer/gpu_primitive/bvh/chunk_bvh_delta.d.ts.map +1 -1
  219. package/src/shade/renderer/gpu_primitive/bvh/chunk_bvh_delta.js +45 -38
  220. package/src/shade/renderer/gpu_primitive/bvh/chunk_bvh_determine_range.d.ts +2 -0
  221. package/src/shade/renderer/gpu_primitive/bvh/chunk_bvh_determine_range.d.ts.map +1 -1
  222. package/src/shade/renderer/gpu_primitive/bvh/chunk_bvh_determine_range.js +81 -79
  223. package/src/shade/renderer/gpu_primitive/bvh/chunk_bvh_find_split.d.ts +2 -0
  224. package/src/shade/renderer/gpu_primitive/bvh/chunk_bvh_find_split.d.ts.map +1 -1
  225. package/src/shade/renderer/gpu_primitive/bvh/chunk_bvh_find_split.js +5 -3
  226. package/src/shade/renderer/gpu_primitive/bvh/chunk_bvh_internal_children.d.ts +21 -0
  227. package/src/shade/renderer/gpu_primitive/bvh/chunk_bvh_internal_children.d.ts.map +1 -0
  228. package/src/shade/renderer/gpu_primitive/bvh/chunk_bvh_internal_children.js +42 -0
  229. package/src/shade/renderer/gpu_primitive/bvh/chunk_bvh_morton_code.d.ts +19 -0
  230. package/src/shade/renderer/gpu_primitive/bvh/chunk_bvh_morton_code.d.ts.map +1 -0
  231. package/src/shade/renderer/gpu_primitive/bvh/chunk_bvh_morton_code.js +44 -0
  232. package/src/shade/renderer/gpu_primitive/bvh/graph_bvh_build_lbvh.d.ts +23 -5
  233. package/src/shade/renderer/gpu_primitive/bvh/graph_bvh_build_lbvh.d.ts.map +1 -1
  234. package/src/shade/renderer/gpu_primitive/bvh/graph_bvh_build_lbvh.js +139 -23
  235. package/src/shade/renderer/gpu_primitive/bvh/shader_bvh_build_single_workgroup.d.ts +25 -0
  236. package/src/shade/renderer/gpu_primitive/bvh/shader_bvh_build_single_workgroup.d.ts.map +1 -0
  237. package/src/shade/renderer/gpu_primitive/bvh/shader_bvh_build_single_workgroup.js +179 -0
  238. package/src/shade/renderer/gpu_primitive/bvh/shader_bvh_emit_hierarchy.d.ts +2 -2
  239. package/src/shade/renderer/gpu_primitive/bvh/shader_bvh_emit_hierarchy.d.ts.map +1 -1
  240. package/src/shade/renderer/gpu_primitive/bvh/shader_bvh_emit_hierarchy.js +7 -16
  241. package/src/shade/renderer/gpu_primitive/bvh/shader_bvh_morton.d.ts +3 -4
  242. package/src/shade/renderer/gpu_primitive/bvh/shader_bvh_morton.d.ts.map +1 -1
  243. package/src/shade/renderer/gpu_primitive/bvh/shader_bvh_morton.js +6 -23
  244. package/src/shade/renderer/gpu_primitive/indirect/IndirectComputeCommandBuildPass.d.ts +11 -0
  245. package/src/shade/renderer/gpu_primitive/indirect/IndirectComputeCommandBuildPass.d.ts.map +1 -1
  246. package/src/shade/renderer/gpu_primitive/indirect/IndirectComputeCommandBuildPass.js +14 -3
  247. package/src/shade/renderer/gpu_primitive/indirect/build_indirect_draw_command.d.ts +10 -0
  248. package/src/shade/renderer/gpu_primitive/indirect/build_indirect_draw_command.d.ts.map +1 -1
  249. package/src/shade/renderer/gpu_primitive/indirect/build_indirect_draw_command.js +13 -3
  250. package/src/shade/renderer/gpu_primitive/prefix_sum/v1/graph_prefix_scan_csdldf.d.ts +10 -0
  251. package/src/shade/renderer/gpu_primitive/prefix_sum/v1/graph_prefix_scan_csdldf.d.ts.map +1 -1
  252. package/src/shade/renderer/gpu_primitive/prefix_sum/v1/graph_prefix_scan_csdldf.js +14 -0
  253. package/src/shade/renderer/gpu_primitive/sort/chunk_sort_bitonic_comparator.d.ts +26 -0
  254. package/src/shade/renderer/gpu_primitive/sort/chunk_sort_bitonic_comparator.d.ts.map +1 -0
  255. package/src/shade/renderer/gpu_primitive/sort/chunk_sort_bitonic_comparator.js +52 -0
  256. package/src/shade/renderer/gpu_primitive/sort/chunk_sort_bitonic_workgroup.d.ts +32 -0
  257. package/src/shade/renderer/gpu_primitive/sort/chunk_sort_bitonic_workgroup.d.ts.map +1 -0
  258. package/src/shade/renderer/gpu_primitive/sort/chunk_sort_bitonic_workgroup.js +89 -0
  259. package/src/shade/renderer/gpu_primitive/sort/graph_radix_sort.d.ts +10 -0
  260. package/src/shade/renderer/gpu_primitive/sort/graph_radix_sort.d.ts.map +1 -1
  261. package/src/shade/renderer/gpu_primitive/sort/graph_radix_sort.js +20 -1
  262. package/src/shade/renderer/hiz/HierarchicalZBuffer.d.ts +10 -0
  263. package/src/shade/renderer/hiz/HierarchicalZBuffer.d.ts.map +1 -1
  264. package/src/shade/renderer/hiz/HierarchicalZBuffer.js +294 -281
  265. package/src/shade/renderer/light/GPULightCollection.d.ts +8 -0
  266. package/src/shade/renderer/light/GPULightCollection.d.ts.map +1 -1
  267. package/src/shade/renderer/light/GPULightCollection.js +18 -1
  268. package/src/shade/renderer/light/cluster/cull/graph_cull_lights.d.ts +8 -0
  269. package/src/shade/renderer/light/cluster/cull/graph_cull_lights.d.ts.map +1 -1
  270. package/src/shade/renderer/light/cluster/cull/graph_cull_lights.js +234 -218
  271. package/src/shade/renderer/light/cluster/graph_assign_clsuters.d.ts +7 -0
  272. package/src/shade/renderer/light/cluster/graph_assign_clsuters.d.ts.map +1 -1
  273. package/src/shade/renderer/light/cluster/graph_assign_clsuters.js +13 -0
  274. package/src/shade/renderer/light/cluster/graph_build_light_clusters.d.ts +7 -0
  275. package/src/shade/renderer/light/cluster/graph_build_light_clusters.d.ts.map +1 -1
  276. package/src/shade/renderer/light/cluster/graph_build_light_clusters.js +16 -2
  277. package/src/shade/renderer/light/environment/execute_filter_environment_map.d.ts +10 -0
  278. package/src/shade/renderer/light/environment/execute_filter_environment_map.d.ts.map +1 -1
  279. package/src/shade/renderer/light/environment/execute_filter_environment_map.js +13 -0
  280. package/src/shade/renderer/lightmap/GPULightMap.d.ts.map +1 -1
  281. package/src/shade/renderer/lightmap/GPULightMap.js +3 -0
  282. package/src/shade/renderer/lightmap/bake/shader_lightmap_viz_to_irradiance_flat.d.ts.map +1 -1
  283. package/src/shade/renderer/lightmap/bake/shader_lightmap_viz_to_irradiance_flat.js +4 -0
  284. package/src/shade/renderer/lightmap/bake/shader_lightmap_viz_to_sh.d.ts.map +1 -1
  285. package/src/shade/renderer/lightmap/bake/shader_lightmap_viz_to_sh.js +4 -0
  286. package/src/shade/renderer/loader/gltf/tiny-gltf.d.ts +1 -1
  287. package/src/shade/renderer/material/GPUMaterialManager.d.ts +16 -4
  288. package/src/shade/renderer/material/GPUMaterialManager.d.ts.map +1 -1
  289. package/src/shade/renderer/material/GPUMaterialManager.js +38 -8
  290. package/src/shade/renderer/particles/DESIGN.md +49 -7
  291. package/src/shade/renderer/particles/ORIENTATION_PLAN_2026_10_15.md +453 -0
  292. package/src/shade/renderer/particles/data/PARTICLE_EMITTER_STRUCT.d.ts +5 -1
  293. package/src/shade/renderer/particles/data/PARTICLE_EMITTER_STRUCT.d.ts.map +1 -1
  294. package/src/shade/renderer/particles/data/PARTICLE_EMITTER_STRUCT.js +13 -5
  295. package/src/shade/renderer/particles/data/particle_emitter_record.js +2 -2
  296. package/src/shade/renderer/particles/graph/groups/particle_builtin_groups.d.ts.map +1 -1
  297. package/src/shade/renderer/particles/graph/groups/particle_builtin_groups.js +12 -0
  298. package/src/shade/renderer/particles/graph/groups/particle_groups_geometry.d.ts +60 -0
  299. package/src/shade/renderer/particles/graph/groups/particle_groups_geometry.d.ts.map +1 -1
  300. package/src/shade/renderer/particles/graph/groups/particle_groups_geometry.js +156 -0
  301. package/src/shade/renderer/particles/runtime/ParticleEmitter.d.ts +2 -2
  302. package/src/shade/renderer/particles/runtime/ParticleEmitter.d.ts.map +1 -1
  303. package/src/shade/renderer/particles/runtime/ParticleEmitter.js +8 -8
  304. package/src/shade/renderer/particles/shaders/chunk_particle_billboard_vertex.d.ts.map +1 -1
  305. package/src/shade/renderer/particles/shaders/chunk_particle_billboard_vertex.js +6 -4
  306. package/src/shade/renderer/particles/shaders/chunk_particle_render_math.d.ts +7 -6
  307. package/src/shade/renderer/particles/shaders/chunk_particle_render_math.d.ts.map +1 -1
  308. package/src/shade/renderer/particles/shaders/chunk_particle_render_math.js +91 -58
  309. package/src/shade/renderer/path_tracer/accumulating/AccumulatingPathTracer.d.ts.map +1 -1
  310. package/src/shade/renderer/path_tracer/accumulating/AccumulatingPathTracer.js +10 -0
  311. package/src/shade/renderer/path_tracer/accumulating/shader_accumulating_path_tracer.d.ts.map +1 -1
  312. package/src/shade/renderer/path_tracer/accumulating/shader_accumulating_path_tracer.js +5 -1
  313. package/src/shade/renderer/path_tracer/graph_path_trace_scene.d.ts.map +1 -1
  314. package/src/shade/renderer/path_tracer/graph_path_trace_scene.js +6 -0
  315. package/src/shade/renderer/postprocess/bloom/graph_postprocess_bloom.d.ts +7 -0
  316. package/src/shade/renderer/postprocess/bloom/graph_postprocess_bloom.d.ts.map +1 -1
  317. package/src/shade/renderer/postprocess/bloom/graph_postprocess_bloom.js +18 -0
  318. package/src/shade/renderer/postprocess/denoise/LigmaDenoiser.d.ts.map +1 -1
  319. package/src/shade/renderer/postprocess/denoise/LigmaDenoiser.js +1 -0
  320. package/src/shade/renderer/postprocess/denoise/shader_temporal_reprojection_luma.d.ts.map +1 -1
  321. package/src/shade/renderer/postprocess/denoise/shader_temporal_reprojection_luma.js +6 -4
  322. package/src/shade/renderer/postprocess/eye/GPUCameraExposureManager.d.ts +11 -0
  323. package/src/shade/renderer/postprocess/eye/GPUCameraExposureManager.d.ts.map +1 -1
  324. package/src/shade/renderer/postprocess/eye/GPUCameraExposureManager.js +16 -0
  325. package/src/shade/renderer/postprocess/gtao/GTAO.d.ts +10 -0
  326. package/src/shade/renderer/postprocess/gtao/GTAO.d.ts.map +1 -1
  327. package/src/shade/renderer/postprocess/gtao/GTAO.js +16 -0
  328. package/src/shade/renderer/postprocess/gtao/fragment_shader_gtao.d.ts.map +1 -1
  329. package/src/shade/renderer/postprocess/gtao/fragment_shader_gtao.js +32 -10
  330. package/src/shade/renderer/postprocess/nss/NSS.d.ts +1 -1
  331. package/src/shade/renderer/postprocess/ssr/reproject/chunk_ssr_temporal_accumulate.d.ts.map +1 -1
  332. package/src/shade/renderer/postprocess/ssr/reproject/chunk_ssr_temporal_accumulate.js +3 -0
  333. package/src/shade/renderer/postprocess/ssr/resolve/build_ssr_resolve_shader.d.ts.map +1 -1
  334. package/src/shade/renderer/postprocess/ssr/resolve/build_ssr_resolve_shader.js +6 -3
  335. package/src/shade/renderer/postprocess/taa/TAA.d.ts +12 -0
  336. package/src/shade/renderer/postprocess/taa/TAA.d.ts.map +1 -1
  337. package/src/shade/renderer/postprocess/taa/TAA.js +15 -0
  338. package/src/shade/renderer/postprocess/velocity/graph_add_per_object_velocity.d.ts +7 -0
  339. package/src/shade/renderer/postprocess/velocity/graph_add_per_object_velocity.d.ts.map +1 -1
  340. package/src/shade/renderer/postprocess/velocity/graph_add_per_object_velocity.js +13 -0
  341. package/src/shade/renderer/rasterize/TemplatePassDescriptor.d.ts +31 -3
  342. package/src/shade/renderer/rasterize/TemplatePassDescriptor.d.ts.map +1 -1
  343. package/src/shade/renderer/rasterize/TemplatePassDescriptor.js +79 -4
  344. package/src/shade/renderer/rasterize/bucket/graph_meshlets_rasterize_by_bucket.d.ts +17 -0
  345. package/src/shade/renderer/rasterize/bucket/graph_meshlets_rasterize_by_bucket.d.ts.map +1 -1
  346. package/src/shade/renderer/rasterize/bucket/graph_meshlets_rasterize_by_bucket.js +35 -4
  347. package/src/shade/renderer/rasterize/compute/graph_mesh_frustum_cull.d.ts +7 -0
  348. package/src/shade/renderer/rasterize/compute/graph_mesh_frustum_cull.d.ts.map +1 -1
  349. package/src/shade/renderer/rasterize/compute/graph_mesh_frustum_cull.js +182 -169
  350. package/src/shade/renderer/rasterize/expand/bucket/mesh/graph_meshes_classify_buckets.d.ts +10 -0
  351. package/src/shade/renderer/rasterize/expand/bucket/mesh/graph_meshes_classify_buckets.d.ts.map +1 -1
  352. package/src/shade/renderer/rasterize/expand/bucket/mesh/graph_meshes_classify_buckets.js +20 -1
  353. package/src/shade/renderer/rasterize/expand/bucket/meshlet/graph_extract_meshlets_from_bucket.d.ts +10 -0
  354. package/src/shade/renderer/rasterize/expand/bucket/meshlet/graph_extract_meshlets_from_bucket.d.ts.map +1 -1
  355. package/src/shade/renderer/rasterize/expand/bucket/meshlet/graph_extract_meshlets_from_bucket.js +18 -1
  356. package/src/shade/renderer/rasterize/expand/bucket/meshlet/graph_sort_meshlets_by_bucket_id.d.ts +10 -0
  357. package/src/shade/renderer/rasterize/expand/bucket/meshlet/graph_sort_meshlets_by_bucket_id.d.ts.map +1 -1
  358. package/src/shade/renderer/rasterize/expand/bucket/meshlet/graph_sort_meshlets_by_bucket_id.js +20 -1
  359. package/src/shade/renderer/rasterize/expand/graph_mesh_filter_one_way.d.ts +7 -0
  360. package/src/shade/renderer/rasterize/expand/graph_mesh_filter_one_way.d.ts.map +1 -1
  361. package/src/shade/renderer/rasterize/expand/graph_mesh_filter_one_way.js +187 -170
  362. package/src/shade/renderer/rasterize/expand/graph_meshlets_filter_one_way.d.ts +10 -0
  363. package/src/shade/renderer/rasterize/expand/graph_meshlets_filter_one_way.d.ts.map +1 -1
  364. package/src/shade/renderer/rasterize/expand/graph_meshlets_filter_one_way.js +19 -1
  365. package/src/shade/renderer/rasterize/expand/graph_meshlets_rasterize.d.ts +13 -0
  366. package/src/shade/renderer/rasterize/expand/graph_meshlets_rasterize.d.ts.map +1 -1
  367. package/src/shade/renderer/rasterize/expand/graph_meshlets_rasterize.js +25 -1
  368. package/src/shade/renderer/rasterize/expand/mesh/graph_expand_meshes_to_meshlets.d.ts +10 -0
  369. package/src/shade/renderer/rasterize/expand/mesh/graph_expand_meshes_to_meshlets.d.ts.map +1 -1
  370. package/src/shade/renderer/rasterize/expand/mesh/graph_expand_meshes_to_meshlets.js +20 -0
  371. package/src/shade/renderer/rasterize/forward/chunk_forward_shade_standard_fragment_brick4.d.ts.map +1 -1
  372. package/src/shade/renderer/rasterize/forward/chunk_forward_shade_standard_fragment_brick4.js +6 -0
  373. package/src/shade/renderer/rasterize/forward/chunk_forward_shade_standard_fragment_ibl.d.ts.map +1 -1
  374. package/src/shade/renderer/rasterize/forward/chunk_forward_shade_standard_fragment_ibl.js +6 -0
  375. package/src/shade/renderer/rasterize/native/avboit/AVBOITSideChannel.d.ts +3 -2
  376. package/src/shade/renderer/rasterize/native/avboit/AVBOITSideChannel.d.ts.map +1 -1
  377. package/src/shade/renderer/rasterize/native/avboit/AVBOITSideChannel.js +3 -2
  378. package/src/shade/renderer/rasterize/native/avboit/graph_rasterize_meshes_transparent_avboit.d.ts +7 -2
  379. package/src/shade/renderer/rasterize/native/avboit/graph_rasterize_meshes_transparent_avboit.d.ts.map +1 -1
  380. package/src/shade/renderer/rasterize/native/avboit/graph_rasterize_meshes_transparent_avboit.js +12 -4
  381. package/src/shade/renderer/rasterize/native/avboit/shader_avboit_draw_brick4.d.ts.map +1 -1
  382. package/src/shade/renderer/rasterize/native/avboit/shader_avboit_draw_brick4.js +4 -3
  383. package/src/shade/renderer/rasterize/native/avboit/shader_avboit_draw_ibl.d.ts.map +1 -1
  384. package/src/shade/renderer/rasterize/native/avboit/shader_avboit_draw_ibl.js +4 -3
  385. package/src/shade/renderer/rasterize/native/oit/graph_rasterize_meshes_transparent_oit.d.ts +2 -1
  386. package/src/shade/renderer/rasterize/native/oit/graph_rasterize_meshes_transparent_oit.d.ts.map +1 -1
  387. package/src/shade/renderer/rasterize/native/oit/graph_rasterize_meshes_transparent_oit.js +11 -3
  388. package/src/shade/renderer/rasterize/native/oit/shader_oit_resolve_moments.d.ts.map +1 -1
  389. package/src/shade/renderer/rasterize/native/oit/shader_oit_resolve_moments.js +4 -3
  390. package/src/shade/renderer/rasterize/native/oit/shader_oit_resolve_moments_ibl.d.ts.map +1 -1
  391. package/src/shade/renderer/rasterize/native/oit/shader_oit_resolve_moments_ibl.js +4 -3
  392. package/src/shade/renderer/rasterize/standard/graph_rasterize_partial_opaque.d.ts +15 -0
  393. package/src/shade/renderer/rasterize/standard/graph_rasterize_partial_opaque.d.ts.map +1 -1
  394. package/src/shade/renderer/rasterize/standard/graph_rasterize_partial_opaque.js +35 -2
  395. package/src/shade/renderer/rasterize/standard/graph_rasterize_remaining_opaque.d.ts +14 -0
  396. package/src/shade/renderer/rasterize/standard/graph_rasterize_remaining_opaque.d.ts.map +1 -1
  397. package/src/shade/renderer/rasterize/standard/graph_rasterize_remaining_opaque.js +32 -4
  398. package/src/shade/renderer/rasterize/standard/graph_rasterize_scene.d.ts +17 -0
  399. package/src/shade/renderer/rasterize/standard/graph_rasterize_scene.d.ts.map +1 -1
  400. package/src/shade/renderer/rasterize/standard/graph_rasterize_scene.js +34 -4
  401. package/src/shade/renderer/restir/di/chunk_restir_resolve.d.ts +5 -3
  402. package/src/shade/renderer/restir/di/chunk_restir_resolve.d.ts.map +1 -1
  403. package/src/shade/renderer/restir/di/chunk_restir_resolve.js +8 -3
  404. package/src/shade/renderer/restir/di/graph_restir_di.d.ts.map +1 -1
  405. package/src/shade/renderer/restir/di/graph_restir_di.js +1 -0
  406. package/src/shade/renderer/restir/di/shader_restir_di_resolve.d.ts.map +1 -1
  407. package/src/shade/renderer/restir/di/shader_restir_di_resolve.js +5 -1
  408. package/src/shade/renderer/restir/reservoir/shader.d.ts.map +1 -1
  409. package/src/shade/renderer/restir/reservoir/shader.js +7 -4
  410. package/src/shade/renderer/scene/GPUInstancesAccelerationStructure.d.ts +7 -0
  411. package/src/shade/renderer/scene/GPUInstancesAccelerationStructure.d.ts.map +1 -1
  412. package/src/shade/renderer/scene/GPUInstancesAccelerationStructure.js +13 -1
  413. package/src/shade/renderer/scene/GPUSceneContext.d.ts +10 -0
  414. package/src/shade/renderer/scene/GPUSceneContext.d.ts.map +1 -1
  415. package/src/shade/renderer/scene/GPUSceneContext.js +19 -0
  416. package/src/shade/renderer/scene/SceneManager.d.ts +9 -0
  417. package/src/shade/renderer/scene/SceneManager.d.ts.map +1 -1
  418. package/src/shade/renderer/scene/SceneManager.js +11 -0
  419. package/src/shade/renderer/scene/hierarchy/graph_nodes_update_transform_hierarchy.d.ts +11 -0
  420. package/src/shade/renderer/scene/hierarchy/graph_nodes_update_transform_hierarchy.d.ts.map +1 -1
  421. package/src/shade/renderer/scene/hierarchy/graph_nodes_update_transform_hierarchy.js +17 -0
  422. package/src/shade/renderer/scene/hierarchy/graph_scene_update_transform_hierarchy.d.ts +11 -0
  423. package/src/shade/renderer/scene/hierarchy/graph_scene_update_transform_hierarchy.d.ts.map +1 -1
  424. package/src/shade/renderer/scene/hierarchy/graph_scene_update_transform_hierarchy.js +18 -1
  425. package/src/shade/renderer/shader/ComputeShader.d.ts +12 -0
  426. package/src/shade/renderer/shader/ComputeShader.d.ts.map +1 -1
  427. package/src/shade/renderer/shader/ComputeShader.js +53 -0
  428. package/src/shade/renderer/shader/ImageShader.d.ts +27 -8
  429. package/src/shade/renderer/shader/ImageShader.d.ts.map +1 -1
  430. package/src/shade/renderer/shader/ImageShader.js +70 -1
  431. package/src/shade/renderer/shader/ShaderDescriptor.d.ts +21 -0
  432. package/src/shade/renderer/shader/ShaderDescriptor.d.ts.map +1 -1
  433. package/src/shade/renderer/shader/ShaderDescriptor.js +71 -1
  434. package/src/shade/renderer/shader/chunk/camera/chunk_project_view_position_from_depth.d.ts +17 -0
  435. package/src/shade/renderer/shader/chunk/camera/chunk_project_view_position_from_depth.d.ts.map +1 -0
  436. package/src/shade/renderer/shader/chunk/camera/chunk_project_view_position_from_depth.js +45 -0
  437. package/src/shade/renderer/shader/chunk/camera/chunk_screen_coordinate_to_view.js +3 -3
  438. package/src/shade/renderer/shader/chunk/color/iCtCp/chunk_eotf_st2084.d.ts +1 -1
  439. package/src/shade/renderer/shader/chunk/color/iCtCp/chunk_eotf_st2084.js +62 -62
  440. package/src/shade/renderer/shader/chunk/color/tonemap/HDR_TONE_MAPPING_FORMS_BRIEF_2026_10_16.md +318 -0
  441. package/src/shade/renderer/shader/chunk/color/tonemap/SDR_TONE_MAPPING_BRIEF_2026_10_16.md +237 -0
  442. package/src/shade/renderer/shader/chunk/color/tonemap/chunk_PAPER_WHITE_NITS.d.ts +17 -0
  443. package/src/shade/renderer/shader/chunk/color/tonemap/chunk_PAPER_WHITE_NITS.d.ts.map +1 -0
  444. package/src/shade/renderer/shader/chunk/color/tonemap/chunk_PAPER_WHITE_NITS.js +22 -0
  445. package/src/shade/renderer/shader/chunk/color/tonemap/chunk_tonemap_khronos_pbr.d.ts +14 -1
  446. package/src/shade/renderer/shader/chunk/color/tonemap/chunk_tonemap_khronos_pbr.d.ts.map +1 -1
  447. package/src/shade/renderer/shader/chunk/color/tonemap/chunk_tonemap_khronos_pbr.js +28 -15
  448. package/src/shade/renderer/shader/chunk/color/tonemap/gt7/chunk_tonemap_gt7.d.ts +12 -0
  449. package/src/shade/renderer/shader/chunk/color/tonemap/gt7/chunk_tonemap_gt7.d.ts.map +1 -1
  450. package/src/shade/renderer/shader/chunk/color/tonemap/gt7/chunk_tonemap_gt7.js +128 -110
  451. package/src/shade/renderer/shader/chunk/geometry/ray/chunk_offset_ray_from_depth.d.ts +20 -0
  452. package/src/shade/renderer/shader/chunk/geometry/ray/chunk_offset_ray_from_depth.d.ts.map +1 -0
  453. package/src/shade/renderer/shader/chunk/geometry/ray/chunk_offset_ray_from_depth.js +33 -0
  454. package/src/shade/renderer/shader/chunk/light/chunk_compute_multiscattering_specular.d.ts +4 -0
  455. package/src/shade/renderer/shader/chunk/light/chunk_compute_multiscattering_specular.d.ts.map +1 -1
  456. package/src/shade/renderer/shader/chunk/light/chunk_compute_multiscattering_specular.js +12 -1
  457. package/src/shade/renderer/shader/chunk/material/MATERIAL_SHADING_INFO_STRUCT.d.ts.map +1 -1
  458. package/src/shade/renderer/shader/chunk/material/MATERIAL_SHADING_INFO_STRUCT.js +7 -0
  459. package/src/shade/renderer/shader/chunk/material/MULTISCATTER.md +108 -0
  460. package/src/shade/renderer/shader/chunk/material/chunk_compute_indirect_specular.d.ts.map +1 -1
  461. package/src/shade/renderer/shader/chunk/material/chunk_compute_indirect_specular.js +23 -4
  462. package/src/shade/renderer/shader/chunk/material/chunk_re_direct_multiscatter.d.ts +18 -0
  463. package/src/shade/renderer/shader/chunk/material/chunk_re_direct_multiscatter.d.ts.map +1 -0
  464. package/src/shade/renderer/shader/chunk/material/chunk_re_direct_multiscatter.js +56 -0
  465. package/src/shade/renderer/shader/chunk/material/chunk_re_indirect_specular_physical.d.ts.map +1 -1
  466. package/src/shade/renderer/shader/chunk/material/chunk_re_indirect_specular_physical.js +2 -0
  467. package/src/shade/renderer/shader/chunk/screen_space/chunk_screen_space_linear_ray.d.ts +43 -0
  468. package/src/shade/renderer/shader/chunk/screen_space/chunk_screen_space_linear_ray.d.ts.map +1 -0
  469. package/src/shade/renderer/shader/chunk/screen_space/chunk_screen_space_linear_ray.js +319 -0
  470. package/src/shade/renderer/shader/compiler/CodeChunk.d.ts +33 -0
  471. package/src/shade/renderer/shader/compiler/CodeChunk.d.ts.map +1 -1
  472. package/src/shade/renderer/shader/compiler/CodeChunk.js +140 -0
  473. package/src/shade/renderer/shader/compiler/CodeChunkChoice.d.ts +74 -0
  474. package/src/shade/renderer/shader/compiler/CodeChunkChoice.d.ts.map +1 -0
  475. package/src/shade/renderer/shader/compiler/CodeChunkChoice.js +166 -0
  476. package/src/shade/renderer/shader/compiler/SHADER_SWITCH_PROPOSAL_2026_10_16.md +680 -0
  477. package/src/shade/renderer/shader/compiler/ShaderSwitch.d.ts +86 -0
  478. package/src/shade/renderer/shader/compiler/ShaderSwitch.d.ts.map +1 -0
  479. package/src/shade/renderer/shader/compiler/ShaderSwitch.js +178 -0
  480. package/src/shade/renderer/shader/compiler/ShaderSwitchSet.d.ts +67 -0
  481. package/src/shade/renderer/shader/compiler/ShaderSwitchSet.d.ts.map +1 -0
  482. package/src/shade/renderer/shader/compiler/ShaderSwitchSet.js +205 -0
  483. package/src/shade/renderer/shadow/contact/CONTACT_SHADOW_WAVE_SIZE.d.ts +14 -0
  484. package/src/shade/renderer/shadow/contact/CONTACT_SHADOW_WAVE_SIZE.d.ts.map +1 -0
  485. package/src/shade/renderer/shadow/contact/CONTACT_SHADOW_WAVE_SIZE.js +13 -0
  486. package/src/shade/renderer/shadow/contact/ContactShadowDispatchList.d.ts +65 -0
  487. package/src/shade/renderer/shadow/contact/ContactShadowDispatchList.d.ts.map +1 -0
  488. package/src/shade/renderer/shadow/contact/ContactShadowDispatchList.js +252 -0
  489. package/src/shade/renderer/shadow/contact/FINDINGS.md +413 -0
  490. package/src/shade/renderer/shadow/contact/chunk_contact_shadow_wavefront_extents.d.ts +29 -0
  491. package/src/shade/renderer/shadow/contact/chunk_contact_shadow_wavefront_extents.d.ts.map +1 -0
  492. package/src/shade/renderer/shadow/contact/chunk_contact_shadow_wavefront_extents.js +105 -0
  493. package/src/shade/renderer/shadow/contact/graph_contact_shadow_linear.d.ts +29 -0
  494. package/src/shade/renderer/shadow/contact/graph_contact_shadow_linear.d.ts.map +1 -0
  495. package/src/shade/renderer/shadow/contact/graph_contact_shadow_linear.js +39 -0
  496. package/src/shade/renderer/shadow/contact/graph_contact_shadow_wavefront.d.ts +29 -0
  497. package/src/shade/renderer/shadow/contact/graph_contact_shadow_wavefront.d.ts.map +1 -0
  498. package/src/shade/renderer/shadow/contact/graph_contact_shadow_wavefront.js +92 -0
  499. package/src/shade/renderer/shadow/contact/shader_contact_shadow_linear.d.ts +29 -0
  500. package/src/shade/renderer/shadow/contact/shader_contact_shadow_linear.d.ts.map +1 -0
  501. package/src/shade/renderer/shadow/contact/shader_contact_shadow_linear.js +128 -0
  502. package/src/shade/renderer/shadow/contact/shader_contact_shadow_wavefront.d.ts +52 -0
  503. package/src/shade/renderer/shadow/contact/shader_contact_shadow_wavefront.d.ts.map +1 -0
  504. package/src/shade/renderer/shadow/contact/shader_contact_shadow_wavefront.js +358 -0
  505. package/src/shade/renderer/shadow/map/ShadowDirectionalTechnique.d.ts +10 -0
  506. package/src/shade/renderer/shadow/map/ShadowDirectionalTechnique.d.ts.map +1 -0
  507. package/src/shade/renderer/shadow/map/ShadowDirectionalTechnique.js +12 -0
  508. package/src/shade/renderer/shadow/map/shader/SHADOW_DIRECTIONAL_TECHNIQUE.d.ts +13 -0
  509. package/src/shade/renderer/shadow/map/shader/SHADOW_DIRECTIONAL_TECHNIQUE.d.ts.map +1 -0
  510. package/src/shade/renderer/shadow/map/shader/SHADOW_DIRECTIONAL_TECHNIQUE.js +14 -0
  511. package/src/shade/renderer/shadow/map/shader/chunk_shadowmap_sample_directional.d.ts +14 -8
  512. package/src/shade/renderer/shadow/map/shader/chunk_shadowmap_sample_directional.d.ts.map +1 -1
  513. package/src/shade/renderer/shadow/map/shader/chunk_shadowmap_sample_directional.js +20 -86
  514. package/src/shade/renderer/shadow/map/shader/chunk_shadowmap_sample_directional_cascades.d.ts +14 -0
  515. package/src/shade/renderer/shadow/map/shader/chunk_shadowmap_sample_directional_cascades.d.ts.map +1 -0
  516. package/src/shade/renderer/shadow/map/shader/chunk_shadowmap_sample_directional_cascades.js +79 -0
  517. package/src/shade/renderer/shadow/ray/shader_ray_shadow_code.d.ts.map +1 -1
  518. package/src/shade/renderer/shadow/ray/shader_ray_shadow_code.js +12 -12
  519. package/src/shade/renderer/shadow/ray/staged/gen/shader_generate_rays.d.ts.map +1 -1
  520. package/src/shade/renderer/shadow/ray/staged/gen/shader_generate_rays.js +153 -151
  521. package/src/shade/renderer/shadow/vsm/shader/chunk_shadowmap_sample_directional_virtual.d.ts +13 -0
  522. package/src/shade/renderer/shadow/vsm/shader/chunk_shadowmap_sample_directional_virtual.d.ts.map +1 -0
  523. package/src/shade/renderer/shadow/vsm/shader/chunk_shadowmap_sample_directional_virtual.js +48 -0
  524. package/src/shade/renderer/texture/GPUTextureContext.d.ts +10 -0
  525. package/src/shade/renderer/texture/GPUTextureContext.d.ts.map +1 -1
  526. package/src/shade/renderer/texture/GPUTextureContext.js +24 -0
  527. package/src/shade/renderer/texture/atlas/GPUTileAtlas3D.d.ts +219 -0
  528. package/src/shade/renderer/texture/atlas/GPUTileAtlas3D.d.ts.map +1 -0
  529. package/src/shade/renderer/texture/atlas/GPUTileAtlas3D.js +671 -0
  530. package/src/shade/renderer/volumetrics/GPUSceneVolumetrics.d.ts +26 -2
  531. package/src/shade/renderer/volumetrics/GPUSceneVolumetrics.d.ts.map +1 -1
  532. package/src/shade/renderer/volumetrics/GPUSceneVolumetrics.js +108 -4
  533. package/src/shade/renderer/volumetrics/GPUViewVolumetrics.d.ts +5 -1
  534. package/src/shade/renderer/volumetrics/GPUViewVolumetrics.d.ts.map +1 -1
  535. package/src/shade/renderer/volumetrics/GPUViewVolumetrics.js +6 -0
  536. package/src/shade/renderer/volumetrics/NOTES.md +50 -0
  537. package/src/shade/renderer/volumetrics/PARTICIPATING_MEDIA_VOLUME_STRUCT.d.ts.map +1 -1
  538. package/src/shade/renderer/volumetrics/PARTICIPATING_MEDIA_VOLUME_STRUCT.js +30 -1
  539. package/src/shade/renderer/volumetrics/ParticipatingMediaVolume.d.ts +51 -13
  540. package/src/shade/renderer/volumetrics/ParticipatingMediaVolume.d.ts.map +1 -1
  541. package/src/shade/renderer/volumetrics/ParticipatingMediaVolume.js +98 -13
  542. package/src/shade/renderer/volumetrics/SceneVolumetrics.d.ts +9 -0
  543. package/src/shade/renderer/volumetrics/SceneVolumetrics.d.ts.map +1 -1
  544. package/src/shade/renderer/volumetrics/SceneVolumetrics.js +78 -68
  545. package/src/shade/renderer/volumetrics/VOLUMETRIC_NOISE_PLAN_2026_10_15.md +326 -0
  546. package/src/shade/renderer/volumetrics/chunk_participating_media_volume_sample.d.ts +7 -4
  547. package/src/shade/renderer/volumetrics/chunk_participating_media_volume_sample.d.ts.map +1 -1
  548. package/src/shade/renderer/volumetrics/chunk_participating_media_volume_sample.js +21 -9
  549. package/src/shade/renderer/volumetrics/chunk_volumetrics_froxel_uvw_from_clip.d.ts +19 -0
  550. package/src/shade/renderer/volumetrics/chunk_volumetrics_froxel_uvw_from_clip.d.ts.map +1 -0
  551. package/src/shade/renderer/volumetrics/chunk_volumetrics_froxel_uvw_from_clip.js +53 -0
  552. package/src/shade/renderer/volumetrics/chunk_volumetrics_sample_froxel_extinction.d.ts +12 -3
  553. package/src/shade/renderer/volumetrics/chunk_volumetrics_sample_froxel_extinction.d.ts.map +1 -1
  554. package/src/shade/renderer/volumetrics/chunk_volumetrics_sample_froxel_extinction.js +85 -48
  555. package/src/shade/renderer/volumetrics/graph_build_froxel_irradiance.d.ts +4 -1
  556. package/src/shade/renderer/volumetrics/graph_build_froxel_irradiance.d.ts.map +1 -1
  557. package/src/shade/renderer/volumetrics/graph_build_froxel_irradiance.js +4 -1
  558. package/src/shade/renderer/volumetrics/graph_build_volumetrics.d.ts +4 -1
  559. package/src/shade/renderer/volumetrics/graph_build_volumetrics.d.ts.map +1 -1
  560. package/src/shade/renderer/volumetrics/graph_build_volumetrics.js +21 -1
  561. package/src/shade/renderer/volumetrics/noise/PARTICIPATING_MEDIA_NOISE.d.ts +98 -0
  562. package/src/shade/renderer/volumetrics/noise/PARTICIPATING_MEDIA_NOISE.d.ts.map +1 -0
  563. package/src/shade/renderer/volumetrics/noise/PARTICIPATING_MEDIA_NOISE.js +115 -0
  564. package/src/shade/renderer/volumetrics/noise/VOLUMETRICS_NOISE_TILE_BAKE_SETTINGS_STRUCT.d.ts +9 -0
  565. package/src/shade/renderer/volumetrics/noise/VOLUMETRICS_NOISE_TILE_BAKE_SETTINGS_STRUCT.d.ts.map +1 -0
  566. package/src/shade/renderer/volumetrics/noise/VOLUMETRICS_NOISE_TILE_BAKE_SETTINGS_STRUCT.js +24 -0
  567. package/src/shade/renderer/volumetrics/noise/bake_volumetrics_noise_tile.d.ts +27 -0
  568. package/src/shade/renderer/volumetrics/noise/bake_volumetrics_noise_tile.d.ts.map +1 -0
  569. package/src/shade/renderer/volumetrics/noise/bake_volumetrics_noise_tile.js +91 -0
  570. package/src/shade/renderer/volumetrics/noise/chunk_participating_media_noise.d.ts +35 -0
  571. package/src/shade/renderer/volumetrics/noise/chunk_participating_media_noise.d.ts.map +1 -0
  572. package/src/shade/renderer/volumetrics/noise/chunk_participating_media_noise.js +92 -0
  573. package/src/shade/renderer/volumetrics/noise/shader_volumetrics_noise_tile_bake.d.ts +10 -0
  574. package/src/shade/renderer/volumetrics/noise/shader_volumetrics_noise_tile_bake.d.ts.map +1 -0
  575. package/src/shade/renderer/volumetrics/noise/shader_volumetrics_noise_tile_bake.js +121 -0
  576. package/src/shade/renderer/volumetrics/shader_volumetrics_build_participating_media.d.ts.map +1 -1
  577. package/src/shade/renderer/volumetrics/shader_volumetrics_build_participating_media.js +38 -3
  578. package/src/shade/renderer/volumetrics/shader_volumetrics_build_sun_shadow_volume.d.ts.map +1 -1
  579. package/src/shade/renderer/volumetrics/shader_volumetrics_build_sun_shadow_volume.js +311 -290
  580. package/src/shade/renderer/volumetrics/volumetrics_position_world_to_froxel_uvw.d.ts.map +1 -1
  581. package/src/shade/renderer/volumetrics/volumetrics_position_world_to_froxel_uvw.js +28 -49
  582. package/src/shade/renderer/water/GPUWaterRenderer.d.ts +3 -1
  583. package/src/shade/renderer/water/GPUWaterRenderer.d.ts.map +1 -1
  584. package/src/shade/renderer/water/GPUWaterRenderer.js +24 -18
  585. package/src/shade/renderer/water/chunk_water_transport.d.ts +0 -1
  586. package/src/shade/renderer/water/chunk_water_transport.d.ts.map +1 -1
  587. package/src/shade/renderer/water/chunk_water_transport.js +0 -17
  588. package/src/shade/renderer/water/shader_water.d.ts +4 -2
  589. package/src/shade/renderer/water/shader_water.d.ts.map +1 -1
  590. package/src/shade/renderer/water/shader_water.js +27 -16
  591. package/src/shade/renderer/water/shader_water_avboit.d.ts +0 -4
  592. package/src/shade/renderer/water/shader_water_avboit.d.ts.map +1 -1
  593. package/src/shade/renderer/water/shader_water_avboit.js +0 -63
  594. package/src/shade/wgsl/emulator/WGSLJavaScriptCompiler.d.ts.map +1 -1
  595. package/src/shade/wgsl/emulator/WGSLJavaScriptCompiler.js +43 -9
  596. package/src/engine/network/transport/Channel.d.ts +0 -85
  597. package/src/engine/network/transport/Channel.d.ts.map +0 -1
  598. package/src/engine/network/transport/ReliableCommandPipeline.d.ts +0 -155
  599. package/src/engine/network/transport/ReliableCommandPipeline.d.ts.map +0 -1
  600. package/src/engine/network/transport/fragments/FragmentAssembler.d.ts +0 -105
  601. package/src/engine/network/transport/fragments/FragmentAssembler.d.ts.map +0 -1
  602. package/src/engine/network/transport/fragments/FragmentRetention.d.ts +0 -103
  603. package/src/engine/network/transport/fragments/FragmentRetention.d.ts.map +0 -1
  604. package/src/engine/network/transport/fragments/fragment_send.d.ts +0 -61
  605. package/src/engine/network/transport/fragments/fragment_send.d.ts.map +0 -1
  606. package/src/engine/network/transport/fragments/packet_size.d.ts +0 -99
  607. package/src/engine/network/transport/fragments/packet_size.d.ts.map +0 -1
  608. package/src/shade/renderer/shader/chunk/color/sRGB/chunk_RRTAndODTFit.d.ts +0 -6
  609. package/src/shade/renderer/shader/chunk/color/sRGB/chunk_RRTAndODTFit.d.ts.map +0 -1
  610. package/src/shade/renderer/shader/chunk/color/sRGB/chunk_RRTAndODTFit.js +0 -16
  611. package/src/shade/renderer/shader/chunk/color/tonemap/chunk_tonemap_aces.d.ts +0 -7
  612. package/src/shade/renderer/shader/chunk/color/tonemap/chunk_tonemap_aces.d.ts.map +0 -1
  613. package/src/shade/renderer/shader/chunk/color/tonemap/chunk_tonemap_aces.js +0 -46
  614. package/src/shade/renderer/shader/chunk/color/tonemap/chunk_tonemap_agx.d.ts +0 -10
  615. package/src/shade/renderer/shader/chunk/color/tonemap/chunk_tonemap_agx.d.ts.map +0 -1
  616. package/src/shade/renderer/shader/chunk/color/tonemap/chunk_tonemap_agx.js +0 -127
  617. package/src/shade/renderer/shader/chunk/color/tonemap/chunk_tonemap_pbr_neutral.d.ts +0 -7
  618. package/src/shade/renderer/shader/chunk/color/tonemap/chunk_tonemap_pbr_neutral.d.ts.map +0 -1
  619. package/src/shade/renderer/shader/chunk/color/tonemap/chunk_tonemap_pbr_neutral.js +0 -39
@@ -1 +1 @@
1
- {"version":3,"file":"chunk_bvh_find_split.d.ts","sourceRoot":"","sources":["../../../../../../src/shade/renderer/gpu_primitive/bvh/chunk_bvh_find_split.js"],"names":[],"mappings":"AAGA;;;;;;;;;;;;GAYG;AACH,mCAFU,SAAS,CAkChB;0BAhDuB,oCAAoC"}
1
+ {"version":3,"file":"chunk_bvh_find_split.d.ts","sourceRoot":"","sources":["../../../../../../src/shade/renderer/gpu_primitive/bvh/chunk_bvh_find_split.js"],"names":[],"mappings":"AAGA;;;;;;;;;;;;;;GAcG;AACH,mCAFU,SAAS,CAkChB;0BAlDuB,oCAAoC"}
@@ -12,14 +12,16 @@ import { chunk_bvh_delta } from "./chunk_bvh_delta.js";
12
12
  * and its child then both claim the same leaf — a shared node, which is not a tree, and which only
13
13
  * shows up when duplicate codes appear mid-range.
14
14
  *
15
+ * Reads the sorted codes through {@link chunk_bvh_delta}, so from the module-scope array `keys`.
16
+ *
15
17
  * @type {CodeChunk}
16
18
  */
17
19
  export const chunk_bvh_find_split = CodeChunk.from(
18
20
  //language=WGSL
19
21
  `
20
- fn bvh_find_split(codes: ptr<storage, array<u32>>, n: u32, first: u32, last: u32) -> u32 {
22
+ fn bvh_find_split(n: u32, first: u32, last: u32) -> u32 {
21
23
  // Number of highest bits that match between first and last (index-tiebroken).
22
- let common_prefix = bvh_delta(codes, n, first, i32(last));
24
+ let common_prefix = bvh_delta(n, first, i32(last));
23
25
 
24
26
  // Binary search for the highest index that still shares more than common_prefix bits with
25
27
  // the code at 'first'.
@@ -32,7 +34,7 @@ fn bvh_find_split(codes: ptr<storage, array<u32>>, n: u32, first: u32, last: u32
32
34
  let candidate = split + step;
33
35
 
34
36
  if (candidate < last) {
35
- if (bvh_delta(codes, n, first, i32(candidate)) > common_prefix) {
37
+ if (bvh_delta(n, first, i32(candidate)) > common_prefix) {
36
38
  split = candidate;
37
39
  }
38
40
  }
@@ -0,0 +1,21 @@
1
+ /**
2
+ * The two children of Karras internal node `i` over `n` sorted codes, as node indices in the
3
+ * builder's layout: internal node `k` at node `k`, leaf `j` at node `(n-1)+j`.
4
+ *
5
+ * Its range comes from {@link bvh_determine_range} and its split from {@link bvh_find_split}. The
6
+ * subrange either side of the split is a leaf when it holds one code, and otherwise the internal
7
+ * node whose boundary sits at that code index.
8
+ *
9
+ * Shared by both builders, {@link shader_bvh_emit_hierarchy} and
10
+ * {@link shader_bvh_build_single_workgroup}. The two have to wire the same tree, and this is the
11
+ * part of the wiring that encodes the layout. Each builder does its own stores, because one writes
12
+ * the node buffer plainly and the other atomically.
13
+ *
14
+ * `i` must be an internal node, `i < n - 1`. The sorted codes are the module-scope array `keys`
15
+ * (see {@link chunk_bvh_delta}).
16
+ *
17
+ * @type {CodeChunk}
18
+ */
19
+ export const chunk_bvh_internal_children: CodeChunk;
20
+ import { CodeChunk } from "../../shader/compiler/CodeChunk.js";
21
+ //# sourceMappingURL=chunk_bvh_internal_children.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chunk_bvh_internal_children.d.ts","sourceRoot":"","sources":["../../../../../../src/shade/renderer/gpu_primitive/bvh/chunk_bvh_internal_children.js"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;;;;;GAiBG;AACH,0CAFU,SAAS,CAqBhB;0BAzCuB,oCAAoC"}
@@ -0,0 +1,42 @@
1
+ import { CodeChunk } from "../../shader/compiler/CodeChunk.js";
2
+ import { chunk_bvh_determine_range } from "./chunk_bvh_determine_range.js";
3
+ import { chunk_bvh_find_split } from "./chunk_bvh_find_split.js";
4
+
5
+ /**
6
+ * The two children of Karras internal node `i` over `n` sorted codes, as node indices in the
7
+ * builder's layout: internal node `k` at node `k`, leaf `j` at node `(n-1)+j`.
8
+ *
9
+ * Its range comes from {@link bvh_determine_range} and its split from {@link bvh_find_split}. The
10
+ * subrange either side of the split is a leaf when it holds one code, and otherwise the internal
11
+ * node whose boundary sits at that code index.
12
+ *
13
+ * Shared by both builders, {@link shader_bvh_emit_hierarchy} and
14
+ * {@link shader_bvh_build_single_workgroup}. The two have to wire the same tree, and this is the
15
+ * part of the wiring that encodes the layout. Each builder does its own stores, because one writes
16
+ * the node buffer plainly and the other atomically.
17
+ *
18
+ * `i` must be an internal node, `i < n - 1`. The sorted codes are the module-scope array `keys`
19
+ * (see {@link chunk_bvh_delta}).
20
+ *
21
+ * @type {CodeChunk}
22
+ */
23
+ export const chunk_bvh_internal_children = CodeChunk.from(
24
+ //language=WGSL
25
+ `
26
+ fn bvh_internal_children(n: u32, i: u32) -> vec2<u32> {
27
+ let range = bvh_determine_range(n, i);
28
+
29
+ let first = range.x;
30
+ let last = range.y;
31
+
32
+ let split = bvh_find_split(n, first, last);
33
+
34
+ let child_1 = select(split, (n - 1u) + split, split == first);
35
+ let child_2 = select(split + 1u, (n - 1u) + split + 1u, split + 1u == last);
36
+
37
+ return vec2<u32>(child_1, child_2);
38
+ }
39
+ `, [
40
+ chunk_bvh_determine_range,
41
+ chunk_bvh_find_split,
42
+ ]);
@@ -0,0 +1,19 @@
1
+ /**
2
+ * The Morton code a leaf box sorts by in the GPU LBVH build: its centroid, quantised to ten bits per
3
+ * axis inside the scene bounds and interleaved into a 30-bit code. It matches
4
+ * `v3_morton_encode_bounded` + `v3_morton_encode_normalized` on the CPU term for term
5
+ * (`round(1023 * t)`, zero-extent axes scaled by zero).
6
+ *
7
+ * One function, called by every builder that sorts leaves by it. The multi-pass build's
8
+ * {@link shader_bvh_morton} and the one-workgroup {@link shader_bvh_build_single_workgroup} must
9
+ * produce the same code for the same leaf, bit for bit, because the tree is a function of the
10
+ * sorted codes and the two paths have to build the same tree.
11
+ *
12
+ * A pure function of its arguments. That is what lets the emulator tier run it against the CPU
13
+ * encoder directly.
14
+ *
15
+ * @type {CodeChunk}
16
+ */
17
+ export const chunk_bvh_morton_code: CodeChunk;
18
+ import { CodeChunk } from "../../shader/compiler/CodeChunk.js";
19
+ //# sourceMappingURL=chunk_bvh_morton_code.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chunk_bvh_morton_code.d.ts","sourceRoot":"","sources":["../../../../../../src/shade/renderer/gpu_primitive/bvh/chunk_bvh_morton_code.js"],"names":[],"mappings":"AAGA;;;;;;;;;;;;;;;GAeG;AACH,oCAFU,SAAS,CA0BhB;0BA1CuB,oCAAoC"}
@@ -0,0 +1,44 @@
1
+ import { chunk_v3_morton_encode } from "../../shader/chunk/bvh/morton/chunk_v3_morton_encode.js";
2
+ import { CodeChunk } from "../../shader/compiler/CodeChunk.js";
3
+
4
+ /**
5
+ * The Morton code a leaf box sorts by in the GPU LBVH build: its centroid, quantised to ten bits per
6
+ * axis inside the scene bounds and interleaved into a 30-bit code. It matches
7
+ * `v3_morton_encode_bounded` + `v3_morton_encode_normalized` on the CPU term for term
8
+ * (`round(1023 * t)`, zero-extent axes scaled by zero).
9
+ *
10
+ * One function, called by every builder that sorts leaves by it. The multi-pass build's
11
+ * {@link shader_bvh_morton} and the one-workgroup {@link shader_bvh_build_single_workgroup} must
12
+ * produce the same code for the same leaf, bit for bit, because the tree is a function of the
13
+ * sorted codes and the two paths have to build the same tree.
14
+ *
15
+ * A pure function of its arguments. That is what lets the emulator tier run it against the CPU
16
+ * encoder directly.
17
+ *
18
+ * @type {CodeChunk}
19
+ */
20
+ export const chunk_bvh_morton_code = CodeChunk.from(
21
+ //language=WGSL
22
+ `
23
+ fn bvh_morton_code(low: vec3<f32>, high: vec3<f32>, scene_low: vec3<f32>, scene_high: vec3<f32>) -> u32 {
24
+ let centroid = (low + high) * 0.5;
25
+
26
+ let span = scene_high - scene_low;
27
+
28
+ // An axis of zero extent contributes nothing to the code, exactly as it does in
29
+ // v3_morton_encode_bounded — every centroid quantises to 0 along it rather than to a division
30
+ // by zero.
31
+ let scale = select(vec3<f32>(0.0), vec3<f32>(1.0) / span, span != vec3<f32>(0.0));
32
+
33
+ // The centroid of a leaf box is inside the union of every leaf box by construction, so the
34
+ // clamp never binds on well-formed input; it is here so that a rounding error at the extreme,
35
+ // or a NaN-free degenerate box, cannot produce an out-of-range quantised coordinate.
36
+ let normalized = clamp((centroid - scene_low) * scale, vec3<f32>(0.0), vec3<f32>(1.0));
37
+
38
+ let quantised = vec3<u32>(round(normalized * 1023.0));
39
+
40
+ return v3_morton_encode(quantised.x, quantised.y, quantised.z);
41
+ }
42
+ `, [
43
+ chunk_v3_morton_encode,
44
+ ]);
@@ -1,20 +1,37 @@
1
+ /**
2
+ * @typedef {import("../../../device/pipeline/PipelineEnquiry.js").PipelineEnquiry} PipelineEnquiry
3
+ */
4
+ /**
5
+ * Offer the pipelines {@link graph_bvh_build_lbvh} dispatches — see {@link PipelineEnquiry}.
6
+ *
7
+ * @param {PipelineEnquiry} enquiry
8
+ */
9
+ export function enquire_bvh_build_lbvh_pipelines(enquiry: PipelineEnquiry): void;
1
10
  /**
2
11
  * Record a GPU LBVH build over a flat set of leaves: Morton code, sort, Karras emission, bottom-up
3
12
  * refit. Everything scene- or geometry-specific happens upstream, in whichever extraction pass
4
13
  * produced `leaf_bounds` / `leaf_payload` / `scene_bounds` — this recorder knows only that it has
5
14
  * `element_count` boxes with payloads and somewhere to put a tree.
6
15
  *
16
+ * Two recordings, chosen by `element_count` and nothing else. Up to one sort tile of leaves
17
+ * ({@link SORT_TILE_SIZE}), the whole build is one dispatch of one workgroup,
18
+ * {@link shader_bvh_build_single_workgroup}. Above it the build is 19 dispatches: Morton, the four
19
+ * digit passes of {@link graph_radix_sort}, emission and refit. Over a few leaves each of those 19 is
20
+ * nearly empty and costs its fixed overhead, and a rebuild per spawn or despawn pays it every time.
21
+ * Both write the same tree and the same Morton order, word for word. The single-workgroup path sorts
22
+ * by code and then leaf index, which is the stable radix sort's order.
23
+ *
7
24
  * The output honours the format in {@link BVH_BUFFER_LAYOUT}: a `u32` root word, then `2N-1` nodes
8
25
  * with internal nodes at `[0, N-2]` (root = 0, by Karras's construction) and leaf `j` at `(N-1)+j`.
9
26
  * That ordering differs from the CPU path's slot-order-with-holes, which is legal because no
10
27
  * consumer reads node *order* — only the node format and the root word. It is also exactly the
11
28
  * BLAS convention (root at node 0), which is why the same recorder serves the geometry side later.
12
29
  *
13
- * `element_count` must be at least 1. A single leaf falls out of the same passes with no special
14
- * case anywhere: the sort has nothing to reorder and returns its input, emission's tail `if` skips
15
- * the internal node and writes leaf 0 at node 0 with `parents[0] = BVH_NULL_NODE`, and the refit's
16
- * one thread reads that terminator and stops. The only thing it needs is a counters buffer WebGPU
17
- * will accept, since a tree of one leaf has no internal node to count arrivals at.
30
+ * `element_count` must be at least 1. A single leaf needs no special case on either path: there
31
+ * is nothing to sort, emission skips the internal node and writes leaf 0 at node 0 with
32
+ * `parents[0] = BVH_NULL_NODE`, and the refit's one climb reads that terminator and stops. The only
33
+ * thing it needs is a counters buffer WebGPU will accept, since a tree of one leaf has no internal
34
+ * node to count arrivals at.
18
35
  *
19
36
  * Zero leaves is refused. There is no tree to write and no dispatch to make — the caller writes
20
37
  * `root = BVH_NULL_NODE` host-side, which is the four bytes consumers already read as "empty".
@@ -50,4 +67,5 @@ export function graph_bvh_build_lbvh({ graph, leaf_bounds, leaf_payload, scene_b
50
67
  keys: number;
51
68
  values: number;
52
69
  };
70
+ export type PipelineEnquiry = import("../../../device/pipeline/PipelineEnquiry.js").PipelineEnquiry;
53
71
  //# sourceMappingURL=graph_bvh_build_lbvh.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"graph_bvh_build_lbvh.d.ts","sourceRoot":"","sources":["../../../../../../src/shade/renderer/gpu_primitive/bvh/graph_bvh_build_lbvh.js"],"names":[],"mappings":"AAUA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqCG;AACH;IAhB+B,KAAK;IACT,WAAW,EAA3B,MAAM;IACU,YAAY,EAA5B,MAAM;IACU,YAAY,EAA5B,MAAM;IACU,aAAa,EAA7B,MAAM;IACU,KAAK,EAArB,MAAM;IACW,gBAAgB,GAAjC,MAAM;IAGW,gBAAgB,GAAjC,MAAM;IAEJ;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAC,CA8KzD"}
1
+ {"version":3,"file":"graph_bvh_build_lbvh.d.ts","sourceRoot":"","sources":["../../../../../../src/shade/renderer/gpu_primitive/bvh/graph_bvh_build_lbvh.js"],"names":[],"mappings":"AAYA;;GAEG;AAEH;;;;GAIG;AACH,0DAFW,eAAe,QAQzB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6CG;AACH;IAhB+B,KAAK;IACT,WAAW,EAA3B,MAAM;IACU,YAAY,EAA5B,MAAM;IACU,YAAY,EAA5B,MAAM;IACU,aAAa,EAA7B,MAAM;IACU,KAAK,EAArB,MAAM;IACW,gBAAgB,GAAjC,MAAM;IAGW,gBAAgB,GAAjC,MAAM;IAEJ;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAC,CA6LzD;8BAtPY,OAAO,6CAA6C,EAAE,eAAe"}
@@ -2,29 +2,56 @@ import { assert } from "../../../../core/assert.js";
2
2
  import { round_up } from "../../../../core/math/round_up.js";
3
3
  import { BufferResourceDescriptor } from "../../../device/graph/BufferResourceDescriptor.js";
4
4
  import { BVH_HEADER_WORDS, bvh_buffer_size } from "./BVH_BUFFER_LAYOUT.js";
5
- import { graph_radix_sort } from "../sort/graph_radix_sort.js";
5
+ import { SORT_TILE_SIZE } from "../sort/defs.js";
6
+ import { enquire_radix_sort_pipelines, graph_radix_sort } from "../sort/graph_radix_sort.js";
6
7
  import { BVH_NO_ROOT_WORD } from "./BVH_BUILD_SETTINGS_STRUCT.js";
8
+ import { shader_bvh_build_single_workgroup } from "./shader_bvh_build_single_workgroup.js";
7
9
  import { shader_bvh_emit_hierarchy } from "./shader_bvh_emit_hierarchy.js";
8
10
  import { shader_bvh_morton } from "./shader_bvh_morton.js";
9
11
  import { shader_bvh_refit } from "./shader_bvh_refit.js";
10
12
 
13
+ /**
14
+ * @typedef {import("../../../device/pipeline/PipelineEnquiry.js").PipelineEnquiry} PipelineEnquiry
15
+ */
16
+
17
+ /**
18
+ * Offer the pipelines {@link graph_bvh_build_lbvh} dispatches — see {@link PipelineEnquiry}.
19
+ *
20
+ * @param {PipelineEnquiry} enquiry
21
+ */
22
+ export function enquire_bvh_build_lbvh_pipelines(enquiry) {
23
+ enquiry.compute.push(shader_bvh_build_single_workgroup.pipeline);
24
+ enquiry.compute.push(shader_bvh_morton.pipeline);
25
+ enquire_radix_sort_pipelines(enquiry);
26
+ enquiry.compute.push(shader_bvh_emit_hierarchy.pipeline);
27
+ enquiry.compute.push(shader_bvh_refit.pipeline);
28
+ }
29
+
11
30
  /**
12
31
  * Record a GPU LBVH build over a flat set of leaves: Morton code, sort, Karras emission, bottom-up
13
32
  * refit. Everything scene- or geometry-specific happens upstream, in whichever extraction pass
14
33
  * produced `leaf_bounds` / `leaf_payload` / `scene_bounds` — this recorder knows only that it has
15
34
  * `element_count` boxes with payloads and somewhere to put a tree.
16
35
  *
36
+ * Two recordings, chosen by `element_count` and nothing else. Up to one sort tile of leaves
37
+ * ({@link SORT_TILE_SIZE}), the whole build is one dispatch of one workgroup,
38
+ * {@link shader_bvh_build_single_workgroup}. Above it the build is 19 dispatches: Morton, the four
39
+ * digit passes of {@link graph_radix_sort}, emission and refit. Over a few leaves each of those 19 is
40
+ * nearly empty and costs its fixed overhead, and a rebuild per spawn or despawn pays it every time.
41
+ * Both write the same tree and the same Morton order, word for word. The single-workgroup path sorts
42
+ * by code and then leaf index, which is the stable radix sort's order.
43
+ *
17
44
  * The output honours the format in {@link BVH_BUFFER_LAYOUT}: a `u32` root word, then `2N-1` nodes
18
45
  * with internal nodes at `[0, N-2]` (root = 0, by Karras's construction) and leaf `j` at `(N-1)+j`.
19
46
  * That ordering differs from the CPU path's slot-order-with-holes, which is legal because no
20
47
  * consumer reads node *order* — only the node format and the root word. It is also exactly the
21
48
  * BLAS convention (root at node 0), which is why the same recorder serves the geometry side later.
22
49
  *
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.
50
+ * `element_count` must be at least 1. A single leaf needs no special case on either path: there
51
+ * is nothing to sort, emission skips the internal node and writes leaf 0 at node 0 with
52
+ * `parents[0] = BVH_NULL_NODE`, and the refit's one climb reads that terminator and stops. The only
53
+ * thing it needs is a counters buffer WebGPU will accept, since a tree of one leaf has no internal
54
+ * node to count arrivals at.
28
55
  *
29
56
  * Zero leaves is refused. There is no tree to write and no dispatch to make — the caller writes
30
57
  * `root = BVH_NULL_NODE` host-side, which is the four bytes consumers already read as "empty".
@@ -69,30 +96,19 @@ export function graph_bvh_build_lbvh({
69
96
 
70
97
  const node_count = 2 * element_count - 1;
71
98
 
99
+ // the tree ends at its last node; where it starts is the caller's business
100
+ const end_byte = (node_word_offset + node_count * 8) * Uint32Array.BYTES_PER_ELEMENT;
101
+
72
102
  // aligned on a 1k boundary to lower memory fragmentation, as the sort's own transients are
73
103
  const KEY_DESCRIPTOR = BufferResourceDescriptor.from(
74
104
  round_up(element_count * Uint32Array.BYTES_PER_ELEMENT, 1024),
75
105
  GPUBufferUsage.STORAGE
76
106
  );
77
107
 
78
- const PARENTS_DESCRIPTOR = BufferResourceDescriptor.from(
79
- round_up(node_count * Uint32Array.BYTES_PER_ELEMENT, 1024),
80
- GPUBufferUsage.STORAGE
81
- );
82
-
83
108
  // One per internal node. A single-leaf tree has none, and a zero-sized buffer is not a thing
84
109
  // WebGPU will hand out, so it gets one cell that nothing ever touches.
85
110
  const counters_size = Math.max(1, element_count - 1) * Uint32Array.BYTES_PER_ELEMENT;
86
111
 
87
- // Every build needs these at zero. A fresh buffer arrives zeroed; a pool-reused one carries
88
- // the previous build's arrival counts, which would let a first arrival believe it was a second
89
- // and fit a node from a sibling that has not been written yet.
90
- const COUNTERS_DESCRIPTOR = BufferResourceDescriptor.from(
91
- counters_size,
92
- GPUBufferUsage.STORAGE,
93
- 0, counters_size
94
- );
95
-
96
112
  // The build owns its `parents` and `leaf_nodes` outright — they are transients of this graph,
97
113
  // one tree to a buffer — so both start at word 0.
98
114
  const settings = {
@@ -103,6 +119,35 @@ export function graph_bvh_build_lbvh({
103
119
  leaf_nodes_offset: 0,
104
120
  };
105
121
 
122
+ if (element_count <= SORT_TILE_SIZE) {
123
+ return record_single_workgroup_build({
124
+ graph,
125
+ leaf_bounds,
126
+ leaf_payload,
127
+ scene_bounds,
128
+ nodes,
129
+ settings,
130
+ end_byte,
131
+ KEY_DESCRIPTOR,
132
+ // the shader zeroes its own counters, so a pooled buffer needs no clear
133
+ COUNTERS_DESCRIPTOR: BufferResourceDescriptor.from(counters_size, GPUBufferUsage.STORAGE),
134
+ });
135
+ }
136
+
137
+ const PARENTS_DESCRIPTOR = BufferResourceDescriptor.from(
138
+ round_up(node_count * Uint32Array.BYTES_PER_ELEMENT, 1024),
139
+ GPUBufferUsage.STORAGE
140
+ );
141
+
142
+ // Every build needs these at zero. A fresh buffer arrives zeroed; a pool-reused one carries
143
+ // the previous build's arrival counts, which would let a first arrival believe it was a second
144
+ // and fit a node from a sibling that has not been written yet.
145
+ const COUNTERS_DESCRIPTOR = BufferResourceDescriptor.from(
146
+ counters_size,
147
+ GPUBufferUsage.STORAGE,
148
+ 0, counters_size
149
+ );
150
+
106
151
  /**
107
152
  * @param pass_data
108
153
  * @param {FramePassResources} resources
@@ -134,9 +179,6 @@ export function graph_bvh_build_lbvh({
134
179
 
135
180
  const output = resources.get(pass_data.nodes);
136
181
 
137
- // the tree ends at its last node; where it starts is the caller's business
138
- const end_byte = (node_word_offset + (2 * element_count - 1) * 8) * Uint32Array.BYTES_PER_ELEMENT;
139
-
140
182
  assert.greaterThanOrEqual(output.size, end_byte, 'node buffer underflow');
141
183
 
142
184
  shader_bvh_emit_hierarchy.dispatchThreads({
@@ -216,3 +258,77 @@ export function graph_bvh_build_lbvh({
216
258
  values: sorted.values,
217
259
  };
218
260
  }
261
+
262
+ /**
263
+ * The build over at most one sort tile of leaves, as one pass: {@link shader_bvh_build_single_workgroup}
264
+ * dispatched as a single workgroup. It publishes what the multi-pass build publishes: the tree, and
265
+ * the sorted keys and leaf order in transients of the same size.
266
+ *
267
+ * @param {Object} options
268
+ * @param {FrameGraph} options.graph
269
+ * @param {number} options.leaf_bounds
270
+ * @param {number} options.leaf_payload
271
+ * @param {number} options.scene_bounds
272
+ * @param {number} options.nodes
273
+ * @param {Object} options.settings {@link BVH_BUILD_SETTINGS_STRUCT}
274
+ * @param {number} options.end_byte where the tree ends in `nodes`
275
+ * @param {BufferResourceDescriptor} options.KEY_DESCRIPTOR
276
+ * @param {BufferResourceDescriptor} options.COUNTERS_DESCRIPTOR
277
+ * @returns {{nodes: number, keys: number, values: number}}
278
+ */
279
+ function record_single_workgroup_build({
280
+ graph,
281
+ leaf_bounds,
282
+ leaf_payload,
283
+ scene_bounds,
284
+ nodes,
285
+ settings,
286
+ end_byte,
287
+ KEY_DESCRIPTOR,
288
+ COUNTERS_DESCRIPTOR,
289
+ }) {
290
+
291
+ /**
292
+ * @param pass_data
293
+ * @param {FramePassResources} resources
294
+ * @param {GraphicsExecutionContext} context
295
+ */
296
+ function execute(pass_data, resources, context) {
297
+ const output = resources.get(pass_data.nodes);
298
+
299
+ assert.greaterThanOrEqual(output.size, end_byte, 'node buffer underflow');
300
+
301
+ shader_bvh_build_single_workgroup.dispatch({
302
+ encoder: context.encoder,
303
+ // one workgroup holds the whole build, so nothing in it waits on another
304
+ group_count_x: 1,
305
+ bindings: {
306
+ settings,
307
+ leaf_bounds: resources.get(pass_data.leaf_bounds),
308
+ leaf_payload: resources.get(pass_data.leaf_payload),
309
+ scene_bounds: resources.get(pass_data.scene_bounds),
310
+ sorted_keys: resources.get(pass_data.keys),
311
+ sorted_values: resources.get(pass_data.values),
312
+ nodes: output,
313
+ counters: resources.get(pass_data.counters),
314
+ }
315
+ });
316
+ }
317
+
318
+ const data = {};
319
+ const pass = graph.add("bvh build/single workgroup", data, execute);
320
+
321
+ data.leaf_bounds = pass.read(leaf_bounds);
322
+ data.leaf_payload = pass.read(leaf_payload);
323
+ data.scene_bounds = pass.read(scene_bounds);
324
+ data.nodes = pass.write(nodes);
325
+ data.keys = pass.create("bvh build/morton keys", KEY_DESCRIPTOR);
326
+ data.values = pass.create("bvh build/leaf order", KEY_DESCRIPTOR);
327
+ data.counters = pass.create("bvh build/refit counters", COUNTERS_DESCRIPTOR);
328
+
329
+ return {
330
+ nodes: data.nodes,
331
+ keys: data.keys,
332
+ values: data.values,
333
+ };
334
+ }
@@ -0,0 +1,25 @@
1
+ /**
2
+ * The whole LBVH build over at most one sort tile of leaves ({@link SORT_TILE_SIZE}), in one
3
+ * workgroup and one dispatch: Morton codes, a bitonic sort in workgroup memory, Karras emission and
4
+ * the bottom-up refit. {@link graph_bvh_build_lbvh} records this in place of its 19 dispatches
5
+ * when the leaves fit, because over that few leaves every one of those dispatches is nearly empty
6
+ * and the build costs their fixed overhead.
7
+ *
8
+ * Its output is the multi-pass build's, word for word. It computes the same Morton code
9
+ * ({@link chunk_bvh_morton_code}) and sorts into the same order (by code, then leaf index, which
10
+ * is what the stable radix sort produces). It wires the same children
11
+ * ({@link chunk_bvh_internal_children}) and fits each node with the same climb
12
+ * ({@link chunk_bvh_refit_climb}). It publishes the same sorted keys and leaf order.
13
+ *
14
+ * Nothing in it waits on another workgroup, because there is no other workgroup. The phases are
15
+ * fenced by barriers, every per-thread loop is bounded by the tile constants, and the climb is the
16
+ * multi-pass refit's: counters and node words stay storage atomics, as there.
17
+ *
18
+ * Workgroup memory is 16,380 bytes: the keys, the values and the parents. That fits the default
19
+ * 16 KiB `maxComputeWorkgroupStorageSize` with four bytes to spare.
20
+ *
21
+ * @type {ComputeShader}
22
+ */
23
+ export const shader_bvh_build_single_workgroup: ComputeShader;
24
+ import { ComputeShader } from "../../shader/ComputeShader.js";
25
+ //# sourceMappingURL=shader_bvh_build_single_workgroup.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"shader_bvh_build_single_workgroup.d.ts","sourceRoot":"","sources":["../../../../../../src/shade/renderer/gpu_primitive/bvh/shader_bvh_build_single_workgroup.js"],"names":[],"mappings":"AAwJA;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,gDAFU,aAAa,CAMpB;8BAhL2B,+BAA+B"}
@@ -0,0 +1,179 @@
1
+ import { BVH_NULL_NODE_DEFINITION } from "../../shader/chunk/bvh/BVH_NULL_NODE_DEFINITION.js";
2
+ import { CodeChunk } from "../../shader/compiler/CodeChunk.js";
3
+ import { ComputeShader } from "../../shader/ComputeShader.js";
4
+ import { ShaderResourceSetDescriptor } from "../../shader/resource/ShaderResourceSetDescriptor.js";
5
+ import { atomic_u32, f32, u32 } from "../../shader/type/WEBGPU_WGSL_PRIMITIVE_TYPES.js";
6
+ import { WebGPUArray } from "../../shader/type/WebGPUArray.js";
7
+ import { chunk_sort_bitonic_workgroup } from "../sort/chunk_sort_bitonic_workgroup.js";
8
+ import { SORT_KEYS_PER_THREAD, SORT_TILE_SIZE, SORT_WORKGROUP_SIZE } from "../sort/defs.js";
9
+ import { BVH_BUILD_SETTINGS_STRUCT, BVH_NO_ROOT_WORD } from "./BVH_BUILD_SETTINGS_STRUCT.js";
10
+ import { BVH_NODE_LAYOUT_DEFINITION } from "./BVH_NODE_LAYOUT_DEFINITION.js";
11
+ import { chunk_bvh_internal_children } from "./chunk_bvh_internal_children.js";
12
+ import { chunk_bvh_morton_code } from "./chunk_bvh_morton_code.js";
13
+ import { chunk_bvh_refit_climb } from "./chunk_bvh_refit_climb.js";
14
+
15
+ const resources = new ShaderResourceSetDescriptor();
16
+
17
+ // see shader_bvh_morton — the same build settings, carried as immediate data
18
+ resources.setImmediate("settings", BVH_BUILD_SETTINGS_STRUCT);
19
+
20
+ resources.createGroup()
21
+ // six floats per leaf: [min.xyz, max.xyz]
22
+ .addStorageBuffer("leaf_bounds", WebGPUArray.from(f32), false)
23
+ .addStorageBuffer("leaf_payload", WebGPUArray.from(u32), false)
24
+ // the same six floats over the whole set, produced by the extraction pass
25
+ .addStorageBuffer("scene_bounds", WebGPUArray.from(f32), false)
26
+ // the Morton order the tree was built from, published as the multi-pass build publishes it
27
+ .addStorageBuffer("sorted_keys", WebGPUArray.from(u32), true)
28
+ .addStorageBuffer("sorted_values", WebGPUArray.from(u32), true)
29
+ // `{root: u32, nodes: array<BVH2_NODE_STRUCT>}`, bound flat and atomic, as the refit binds it
30
+ .addStorageBuffer("nodes", WebGPUArray.from(atomic_u32), true)
31
+ // one arrival counter per internal node; zeroed here, so they can arrive with anything in them
32
+ .addStorageBuffer("counters", WebGPUArray.from(atomic_u32), true);
33
+
34
+ const body = CodeChunk.from(
35
+ //language=WGSL
36
+ `
37
+ const WORKGROUP_SIZE = ${SORT_WORKGROUP_SIZE}u;
38
+ const KEYS_PER_THREAD = ${SORT_KEYS_PER_THREAD}u;
39
+ const NO_ROOT_WORD = ${BVH_NO_ROOT_WORD}u;
40
+
41
+ // Each leaf's Morton code, and beside it the leaf it came from. The bitonic sort orders them in
42
+ // place, and emission reads the sorted codes from here by name.
43
+ var<workgroup> keys: array<u32, ${SORT_TILE_SIZE}>;
44
+ var<workgroup> values: array<u32, ${SORT_TILE_SIZE}>;
45
+
46
+ // Parent of every node, indexed as the node buffer is, 2N-1 of them. With the two arrays above that
47
+ // is 16,380 bytes, inside the 16 KiB default limit. The climb reads it once per step, so it is
48
+ // here rather than one more storage round trip.
49
+ var<workgroup> parents: array<u32, ${2 * SORT_TILE_SIZE - 1}>;
50
+
51
+ @compute @workgroup_size(WORKGROUP_SIZE, 1, 1)
52
+ fn main(@builtin(local_invocation_index) thread_id: u32) {
53
+ let n = settings.element_count;
54
+
55
+ let scene_low = vec3<f32>(scene_bounds[0], scene_bounds[1], scene_bounds[2]);
56
+ let scene_high = vec3<f32>(scene_bounds[3], scene_bounds[4], scene_bounds[5]);
57
+
58
+ // Morton code per leaf, striped so neighbouring threads read neighbouring leaves, and a zero
59
+ // arrival count for each of the n - 1 internal nodes.
60
+ for (var k = 0u; k < KEYS_PER_THREAD; k += 1u) {
61
+ let leaf = k * WORKGROUP_SIZE + thread_id;
62
+
63
+ if (leaf < n) {
64
+ let base = leaf * 6u;
65
+
66
+ let low = vec3<f32>(leaf_bounds[base], leaf_bounds[base + 1u], leaf_bounds[base + 2u]);
67
+ let high = vec3<f32>(leaf_bounds[base + 3u], leaf_bounds[base + 4u], leaf_bounds[base + 5u]);
68
+
69
+ keys[leaf] = bvh_morton_code(low, high, scene_low, scene_high);
70
+ values[leaf] = leaf;
71
+ }
72
+
73
+ if (leaf + 1u < n) {
74
+ atomicStore(&counters[leaf], 0u);
75
+ }
76
+ }
77
+
78
+ // Ascending by (code, leaf), which is a stable sort by code: the order the multi-pass radix
79
+ // sort produces, so both paths build the same tree.
80
+ sort_bitonic_workgroup(thread_id, n);
81
+
82
+ // Emission, as shader_bvh_emit_hierarchy does it. Leaf j lives at node (n-1)+j, internal node
83
+ // k at node k, and the root is internal node 0. The node words are stored atomically because
84
+ // the refit below reads them atomically.
85
+ for (var k = 0u; k < KEYS_PER_THREAD; k += 1u) {
86
+ let i = k * WORKGROUP_SIZE + thread_id;
87
+
88
+ if (i < n) {
89
+ let leaf_source = values[i];
90
+
91
+ sorted_keys[i] = keys[i];
92
+ sorted_values[i] = leaf_source;
93
+
94
+ let leaf_word = settings.node_word_offset + ((n - 1u) + i) * BVH_NODE_STRIDE;
95
+ let bounds_source = leaf_source * 6u;
96
+
97
+ for (var w = 0u; w < 6u; w += 1u) {
98
+ atomicStore(&nodes[leaf_word + BVH_NODE_BOUNDS + w], bitcast<u32>(leaf_bounds[bounds_source + w]));
99
+ }
100
+
101
+ atomicStore(&nodes[leaf_word + BVH_NODE_CHILD_1], BVH_NULL_NODE);
102
+ atomicStore(&nodes[leaf_word + BVH_NODE_CHILD_2], leaf_payload[leaf_source]);
103
+
104
+ // n leaves, n-1 internal nodes — the last leaf has no internal node to go with it
105
+ if (i < n - 1u) {
106
+ let children = bvh_internal_children(n, i);
107
+
108
+ let node_word = settings.node_word_offset + i * BVH_NODE_STRIDE;
109
+
110
+ atomicStore(&nodes[node_word + BVH_NODE_CHILD_1], children.x);
111
+ atomicStore(&nodes[node_word + BVH_NODE_CHILD_2], children.y);
112
+
113
+ parents[children.x] = i;
114
+ parents[children.y] = i;
115
+ }
116
+ }
117
+ }
118
+
119
+ if (thread_id == 0u) {
120
+ // see shader_bvh_emit_hierarchy: a BLAS has no root word and says so with NO_ROOT_WORD
121
+ if (settings.root_word_offset != NO_ROOT_WORD) {
122
+ atomicStore(&nodes[settings.root_word_offset], 0u);
123
+ }
124
+
125
+ // where the climb stops
126
+ parents[0] = BVH_NULL_NODE;
127
+ }
128
+
129
+ // Every word the climb reads was written above by some other thread of this workgroup: the
130
+ // parents in workgroup memory, and the counters and child words in storage.
131
+ workgroupBarrier();
132
+ storageBarrier();
133
+
134
+ // Refit, as shader_bvh_refit does it: one climb per leaf, and the second arrival at a node fits
135
+ // it. Nothing waits, so which thread climbs which leaf does not matter.
136
+ for (var k = 0u; k < KEYS_PER_THREAD; k += 1u) {
137
+ let i = k * WORKGROUP_SIZE + thread_id;
138
+
139
+ if (i < n) {
140
+ bvh_refit_climb(settings.node_word_offset, 0u, 0u, (n - 1u) + i);
141
+ }
142
+ }
143
+ }
144
+ `, [
145
+ BVH_NULL_NODE_DEFINITION,
146
+ BVH_NODE_LAYOUT_DEFINITION,
147
+ chunk_bvh_morton_code,
148
+ chunk_sort_bitonic_workgroup,
149
+ chunk_bvh_internal_children,
150
+ chunk_bvh_refit_climb,
151
+ ]);
152
+
153
+ /**
154
+ * The whole LBVH build over at most one sort tile of leaves ({@link SORT_TILE_SIZE}), in one
155
+ * workgroup and one dispatch: Morton codes, a bitonic sort in workgroup memory, Karras emission and
156
+ * the bottom-up refit. {@link graph_bvh_build_lbvh} records this in place of its 19 dispatches
157
+ * when the leaves fit, because over that few leaves every one of those dispatches is nearly empty
158
+ * and the build costs their fixed overhead.
159
+ *
160
+ * Its output is the multi-pass build's, word for word. It computes the same Morton code
161
+ * ({@link chunk_bvh_morton_code}) and sorts into the same order (by code, then leaf index, which
162
+ * is what the stable radix sort produces). It wires the same children
163
+ * ({@link chunk_bvh_internal_children}) and fits each node with the same climb
164
+ * ({@link chunk_bvh_refit_climb}). It publishes the same sorted keys and leaf order.
165
+ *
166
+ * Nothing in it waits on another workgroup, because there is no other workgroup. The phases are
167
+ * fenced by barriers, every per-thread loop is bounded by the tile constants, and the climb is the
168
+ * multi-pass refit's: counters and node words stay storage atomics, as there.
169
+ *
170
+ * Workgroup memory is 16,380 bytes: the keys, the values and the parents. That fits the default
171
+ * 16 KiB `maxComputeWorkgroupStorageSize` with four bytes to spare.
172
+ *
173
+ * @type {ComputeShader}
174
+ */
175
+ export const shader_bvh_build_single_workgroup = ComputeShader.from({
176
+ label: "BVHBuild/SingleWorkgroup",
177
+ resources,
178
+ body,
179
+ });