@woosh/meep-engine 3.17.2 → 3.18.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 (263) hide show
  1. package/editor/actions/concrete/ComponentAddAction.d.ts +1 -0
  2. package/editor/actions/concrete/ComponentAddAction.d.ts.map +1 -1
  3. package/editor/actions/concrete/ComponentAddAction.js +4 -0
  4. package/editor/actions/concrete/ComponentRemoveAction.d.ts +1 -0
  5. package/editor/actions/concrete/ComponentRemoveAction.d.ts.map +1 -1
  6. package/editor/actions/concrete/ComponentRemoveAction.js +4 -0
  7. package/editor/actions/concrete/EntityCreateAction.d.ts +1 -0
  8. package/editor/actions/concrete/EntityCreateAction.d.ts.map +1 -1
  9. package/editor/actions/concrete/EntityCreateAction.js +7 -0
  10. package/editor/actions/concrete/EntityRemoveAction.d.ts +1 -0
  11. package/editor/actions/concrete/EntityRemoveAction.d.ts.map +1 -1
  12. package/editor/actions/concrete/EntityRemoveAction.js +4 -0
  13. package/editor/actions/concrete/PatchTerrainHeightAction.d.ts +10 -0
  14. package/editor/actions/concrete/PatchTerrainHeightAction.d.ts.map +1 -1
  15. package/editor/actions/concrete/PatchTerrainHeightAction.js +107 -85
  16. package/editor/actions/concrete/TransformModifyAction.d.ts +1 -0
  17. package/editor/actions/concrete/TransformModifyAction.d.ts.map +1 -1
  18. package/editor/actions/concrete/TransformModifyAction.js +4 -0
  19. package/editor/particles/effect/ParticleEffectDocument.d.ts.map +1 -1
  20. package/editor/particles/effect/ParticleEffectDocument.js +10 -6
  21. package/editor/particles/effect/ParticleReferenceSimulation.d.ts.map +1 -1
  22. package/editor/particles/effect/ParticleReferenceSimulation.js +98 -4
  23. package/editor/particles/effect/make_starter_particle_effect.d.ts.map +1 -1
  24. package/editor/particles/effect/make_starter_particle_effect.js +0 -2
  25. package/editor/tools/engine/ToolEngine.d.ts +30 -0
  26. package/editor/tools/engine/ToolEngine.d.ts.map +1 -1
  27. package/editor/tools/engine/ToolEngine.js +257 -188
  28. package/editor/view/ecs/EntityList.d.ts.map +1 -1
  29. package/editor/view/ecs/EntityList.js +6 -5
  30. package/editor/view/particles/effect/ParticleEmitterInspectorView.d.ts.map +1 -1
  31. package/editor/view/particles/effect/ParticleEmitterInspectorView.js +17 -9
  32. package/package.json +1 -1
  33. package/src/CODEC_LAYOUT_VERIFICATION.md +1 -2
  34. package/src/core/binary/meshopt/MESHOPT_VERTEX_BLOCK.d.ts +56 -0
  35. package/src/core/binary/meshopt/MESHOPT_VERTEX_BLOCK.d.ts.map +1 -0
  36. package/src/core/binary/meshopt/MESHOPT_VERTEX_BLOCK.js +73 -0
  37. package/src/core/binary/meshopt/meshopt_decode_vertex_buffer.d.ts.map +1 -1
  38. package/src/core/binary/meshopt/meshopt_decode_vertex_buffer.js +18 -63
  39. package/src/core/binary/meshopt/meshopt_encode_byte_group.d.ts +53 -0
  40. package/src/core/binary/meshopt/meshopt_encode_byte_group.d.ts.map +1 -0
  41. package/src/core/binary/meshopt/meshopt_encode_byte_group.js +140 -0
  42. package/src/core/binary/meshopt/meshopt_encode_data_block.d.ts +32 -0
  43. package/src/core/binary/meshopt/meshopt_encode_data_block.d.ts.map +1 -0
  44. package/src/core/binary/meshopt/meshopt_encode_data_block.js +77 -0
  45. package/src/core/binary/meshopt/meshopt_encode_index_sequence.d.ts +46 -0
  46. package/src/core/binary/meshopt/meshopt_encode_index_sequence.d.ts.map +1 -0
  47. package/src/core/binary/meshopt/meshopt_encode_index_sequence.js +146 -0
  48. package/src/core/binary/meshopt/meshopt_encode_vertex_buffer.d.ts +40 -0
  49. package/src/core/binary/meshopt/meshopt_encode_vertex_buffer.d.ts.map +1 -0
  50. package/src/core/binary/meshopt/meshopt_encode_vertex_buffer.js +700 -0
  51. package/src/core/binary/meshopt/meshopt_write_uint_var.d.ts +24 -0
  52. package/src/core/binary/meshopt/meshopt_write_uint_var.d.ts.map +1 -0
  53. package/src/core/binary/meshopt/meshopt_write_uint_var.js +39 -0
  54. package/src/core/math/random/seededRandom_Mulberry32.d.ts.map +1 -1
  55. package/src/core/math/random/seededRandom_Mulberry32.js +4 -2
  56. package/src/core/process/undo/Action.d.ts +19 -0
  57. package/src/core/process/undo/Action.d.ts.map +1 -1
  58. package/src/core/process/undo/Action.js +17 -0
  59. package/src/engine/graphics3/GPUParticleEmitterSystem.d.ts +78 -0
  60. package/src/engine/graphics3/GPUParticleEmitterSystem.d.ts.map +1 -0
  61. package/src/engine/graphics3/GPUParticleEmitterSystem.js +310 -0
  62. package/src/engine/graphics3/GraphicsEngine.d.ts +17 -0
  63. package/src/engine/graphics3/GraphicsEngine.d.ts.map +1 -1
  64. package/src/engine/graphics3/GraphicsEngine.js +30 -10
  65. package/src/engine/graphics3/particles/particle_gpu_records.d.ts.map +1 -1
  66. package/src/engine/graphics3/particles/particle_gpu_records.js +0 -2
  67. package/src/engine/interpolation/InterpolationSystem.d.ts +7 -0
  68. package/src/engine/interpolation/InterpolationSystem.d.ts.map +1 -1
  69. package/src/engine/interpolation/InterpolationSystem.js +10 -0
  70. package/src/engine/network/NetworkSession.d.ts.map +1 -1
  71. package/src/engine/network/NetworkSession.js +14 -34
  72. package/src/engine/network/time/RenderPlayout.d.ts +76 -0
  73. package/src/engine/network/time/RenderPlayout.d.ts.map +1 -0
  74. package/src/engine/network/time/RenderPlayout.js +163 -0
  75. package/src/engine/network/transport/adapters/WebSocketTransport.d.ts.map +1 -1
  76. package/src/engine/network/transport/adapters/WebSocketTransport.js +11 -4
  77. package/src/engine/physics/ecs/PhysicsSystem.d.ts +4 -12
  78. package/src/engine/physics/ecs/PhysicsSystem.d.ts.map +1 -1
  79. package/src/engine/physics/ecs/PhysicsSystem.js +39 -13
  80. package/src/engine/physics/fluid/ecs/FluidObstacleSystem.d.ts +4 -4
  81. package/src/engine/sound/simulation/core/VolumeField.d.ts.map +1 -1
  82. package/src/engine/sound/simulation/core/VolumeField.js +4 -1
  83. package/src/format/scene/gltf/MESHOPT_COMPRESSION_PLAN.md +23 -2
  84. package/src/shade/playground/particle_system/README.md +139 -139
  85. package/src/shade/playground/particle_system/particle_prototype.d.ts.map +1 -1
  86. package/src/shade/playground/particle_system/particle_prototype.js +0 -2
  87. package/src/shade/playground/particle_system/particle_scene.d.ts +6 -9
  88. package/src/shade/playground/particle_system/particle_scene.d.ts.map +1 -1
  89. package/src/shade/playground/particle_system/particle_scene.js +6 -13
  90. package/src/shade/playground/ssr_reprojection/README.md +103 -0
  91. package/src/shade/playground/ssr_reprojection/SpatialFilterProbe.d.ts +17 -0
  92. package/src/shade/playground/ssr_reprojection/SpatialFilterProbe.d.ts.map +1 -0
  93. package/src/shade/playground/ssr_reprojection/SpatialFilterProbe.js +68 -0
  94. package/src/shade/playground/ssr_reprojection/index.html +79 -0
  95. package/src/shade/playground/ssr_reprojection/main.d.ts +2 -0
  96. package/src/shade/playground/ssr_reprojection/main.d.ts.map +1 -0
  97. package/src/shade/playground/ssr_reprojection/main.js +245 -0
  98. package/src/shade/playground/ssr_reprojection/scene.d.ts +18 -0
  99. package/src/shade/playground/ssr_reprojection/scene.d.ts.map +1 -0
  100. package/src/shade/playground/ssr_reprojection/scene.js +51 -0
  101. package/src/shade/renderer/Renderer.d.ts +2 -23
  102. package/src/shade/renderer/Renderer.d.ts.map +1 -1
  103. package/src/shade/renderer/Renderer.js +185 -218
  104. package/src/shade/renderer/animation/GPUAnimationManager.d.ts +5 -8
  105. package/src/shade/renderer/animation/GPUAnimationManager.d.ts.map +1 -1
  106. package/src/shade/renderer/animation/GPUAnimationManager.js +12 -12
  107. package/src/shade/renderer/buffer/table/GPUTypedTable.d.ts.map +1 -1
  108. package/src/shade/renderer/buffer/table/GPUTypedTable.js +6 -0
  109. package/src/shade/renderer/buffer/table/single/GPUSingleTypeTable.d.ts.map +1 -1
  110. package/src/shade/renderer/buffer/table/single/GPUSingleTypeTable.js +7 -0
  111. package/src/shade/renderer/global_illumination/brick4/gpu/draw/chunk_brick4_sample_specular.d.ts +4 -0
  112. package/src/shade/renderer/global_illumination/brick4/gpu/draw/chunk_brick4_sample_specular.d.ts.map +1 -0
  113. package/src/shade/renderer/global_illumination/brick4/gpu/draw/chunk_brick4_sample_specular.js +51 -0
  114. package/src/shade/renderer/global_illumination/brick4/gpu/draw/shader_brick4_specular.d.ts.map +1 -1
  115. package/src/shade/renderer/global_illumination/brick4/gpu/draw/shader_brick4_specular.js +5 -35
  116. package/src/shade/renderer/particles/DESIGN.md +703 -514
  117. package/src/shade/renderer/particles/GPUParticleSystem.d.ts +16 -4
  118. package/src/shade/renderer/particles/GPUParticleSystem.d.ts.map +1 -1
  119. package/src/shade/renderer/particles/GPUParticleSystem.js +1189 -991
  120. package/src/shade/renderer/particles/ParticleConstants.d.ts +64 -0
  121. package/src/shade/renderer/particles/ParticleConstants.d.ts.map +1 -1
  122. package/src/shade/renderer/particles/ParticleConstants.js +71 -0
  123. package/src/shade/renderer/particles/bounds/chunk_particle_bounds.d.ts +57 -0
  124. package/src/shade/renderer/particles/bounds/chunk_particle_bounds.d.ts.map +1 -0
  125. package/src/shade/renderer/particles/bounds/chunk_particle_bounds.js +181 -0
  126. package/src/shade/renderer/particles/bounds/chunk_particle_bounds_unknown.d.ts +7 -0
  127. package/src/shade/renderer/particles/bounds/chunk_particle_bounds_unknown.d.ts.map +1 -0
  128. package/src/shade/renderer/particles/bounds/chunk_particle_bounds_unknown.js +12 -0
  129. package/src/shade/renderer/particles/bounds/graph_particle_bounds.d.ts +33 -0
  130. package/src/shade/renderer/particles/bounds/graph_particle_bounds.d.ts.map +1 -0
  131. package/src/shade/renderer/particles/bounds/graph_particle_bounds.js +67 -0
  132. package/src/shade/renderer/particles/bounds/shader_particle_bounds.d.ts +40 -0
  133. package/src/shade/renderer/particles/bounds/shader_particle_bounds.d.ts.map +1 -0
  134. package/src/shade/renderer/particles/bounds/shader_particle_bounds.js +187 -0
  135. package/src/shade/renderer/particles/coherence/graph_particle_bucket.d.ts +15 -2
  136. package/src/shade/renderer/particles/coherence/graph_particle_bucket.d.ts.map +1 -1
  137. package/src/shade/renderer/particles/coherence/graph_particle_bucket.js +14 -8
  138. package/src/shade/renderer/particles/data/PARTICLE_COUNTERS.d.ts +58 -4
  139. package/src/shade/renderer/particles/data/PARTICLE_COUNTERS.d.ts.map +1 -1
  140. package/src/shade/renderer/particles/data/PARTICLE_COUNTERS.js +79 -4
  141. package/src/shade/renderer/particles/data/PARTICLE_EMITTER_STATE.d.ts +23 -1
  142. package/src/shade/renderer/particles/data/PARTICLE_EMITTER_STATE.d.ts.map +1 -1
  143. package/src/shade/renderer/particles/data/PARTICLE_EMITTER_STATE.js +35 -2
  144. package/src/shade/renderer/particles/data/PARTICLE_EMITTER_STRUCT.d.ts +4 -2
  145. package/src/shade/renderer/particles/data/PARTICLE_EMITTER_STRUCT.d.ts.map +1 -1
  146. package/src/shade/renderer/particles/data/PARTICLE_EMITTER_STRUCT.js +5 -8
  147. package/src/shade/renderer/particles/data/particle_emitter_record.d.ts.map +1 -1
  148. package/src/shade/renderer/particles/data/particle_emitter_record.js +0 -6
  149. package/src/shade/renderer/particles/graph_particles.d.ts +25 -3
  150. package/src/shade/renderer/particles/graph_particles.d.ts.map +1 -1
  151. package/src/shade/renderer/particles/graph_particles.js +108 -31
  152. package/src/shade/renderer/particles/graph_particles_avboit.d.ts +6 -4
  153. package/src/shade/renderer/particles/graph_particles_avboit.d.ts.map +1 -1
  154. package/src/shade/renderer/particles/graph_particles_avboit.js +5 -5
  155. package/src/shade/renderer/particles/runtime/EmitterRegistry.d.ts +5 -0
  156. package/src/shade/renderer/particles/runtime/EmitterRegistry.d.ts.map +1 -1
  157. package/src/shade/renderer/particles/runtime/EmitterRegistry.js +27 -6
  158. package/src/shade/renderer/particles/runtime/GPUParticleEmitterContext.d.ts +4 -0
  159. package/src/shade/renderer/particles/runtime/GPUParticleEmitterContext.d.ts.map +1 -1
  160. package/src/shade/renderer/particles/runtime/GPUParticleEmitterContext.js +6 -1
  161. package/src/shade/renderer/particles/runtime/ParticleEmitter.d.ts +35 -27
  162. package/src/shade/renderer/particles/runtime/ParticleEmitter.d.ts.map +1 -1
  163. package/src/shade/renderer/particles/runtime/ParticleEmitter.js +424 -425
  164. package/src/shade/renderer/particles/shaders/chunk_particle_emitter_warmup.d.ts +20 -0
  165. package/src/shade/renderer/particles/shaders/chunk_particle_emitter_warmup.d.ts.map +1 -0
  166. package/src/shade/renderer/particles/shaders/chunk_particle_render_math.d.ts +4 -0
  167. package/src/shade/renderer/particles/shaders/chunk_particle_render_math.d.ts.map +1 -1
  168. package/src/shade/renderer/particles/shaders/chunk_particle_render_math.js +38 -2
  169. package/src/shade/renderer/particles/shaders/chunk_particle_spawn_budget.d.ts +22 -0
  170. package/src/shade/renderer/particles/shaders/chunk_particle_spawn_budget.d.ts.map +1 -0
  171. package/src/shade/renderer/particles/shaders/chunk_particle_spawn_budget.js +42 -0
  172. package/src/shade/renderer/particles/shaders/shader_particle_avboit_draw.js +1 -1
  173. package/src/shade/renderer/particles/shaders/shader_particle_avboit_occupancy.d.ts.map +1 -1
  174. package/src/shade/renderer/particles/shaders/shader_particle_avboit_occupancy.js +53 -22
  175. package/src/shade/renderer/particles/shaders/shader_particle_emitter_tick.d.ts.map +1 -1
  176. package/src/shade/renderer/particles/shaders/shader_particle_emitter_tick.js +213 -216
  177. package/src/shade/renderer/particles/shaders/shader_particle_reclaim.d.ts +50 -0
  178. package/src/shade/renderer/particles/shaders/shader_particle_reclaim.d.ts.map +1 -0
  179. package/src/shade/renderer/particles/shaders/shader_particle_render.js +1 -1
  180. package/src/shade/renderer/particles/warmup/chunk_particle_warmup_step.d.ts +36 -0
  181. package/src/shade/renderer/particles/warmup/chunk_particle_warmup_step.d.ts.map +1 -0
  182. package/src/shade/renderer/particles/warmup/chunk_particle_warmup_step.js +102 -0
  183. package/src/shade/renderer/particles/warmup/graph_particle_warmup.d.ts +102 -0
  184. package/src/shade/renderer/particles/warmup/graph_particle_warmup.d.ts.map +1 -0
  185. package/src/shade/renderer/particles/warmup/graph_particle_warmup.js +329 -0
  186. package/src/shade/renderer/particles/warmup/shader_particle_warmup.d.ts +112 -0
  187. package/src/shade/renderer/particles/warmup/shader_particle_warmup.d.ts.map +1 -0
  188. package/src/shade/renderer/particles/warmup/shader_particle_warmup.js +318 -0
  189. package/src/shade/renderer/particles/warmup/shader_particle_warmup_advance.d.ts +35 -0
  190. package/src/shade/renderer/particles/warmup/shader_particle_warmup_advance.d.ts.map +1 -0
  191. package/src/shade/renderer/particles/warmup/shader_particle_warmup_advance.js +108 -0
  192. package/src/shade/renderer/particles/warmup/shader_particle_warmup_advance_wide.d.ts +3 -0
  193. package/src/shade/renderer/particles/warmup/shader_particle_warmup_advance_wide.d.ts.map +1 -0
  194. package/src/shade/renderer/particles/warmup/shader_particle_warmup_advance_wide.js +70 -0
  195. package/src/shade/renderer/particles/warmup/warmup_schedule.d.ts +62 -0
  196. package/src/shade/renderer/particles/warmup/warmup_schedule.d.ts.map +1 -0
  197. package/src/shade/renderer/particles/warmup/warmup_schedule.js +55 -0
  198. package/src/shade/renderer/postprocess/PostProcess.d.ts.map +1 -1
  199. package/src/shade/renderer/postprocess/PostProcess.js +2 -1
  200. package/src/shade/renderer/postprocess/ssr/REPROJECTION_PROPOSAL.md +286 -0
  201. package/src/shade/renderer/postprocess/ssr/SSR.d.ts +57 -21
  202. package/src/shade/renderer/postprocess/ssr/SSR.d.ts.map +1 -1
  203. package/src/shade/renderer/postprocess/ssr/SSR.js +230 -129
  204. package/src/shade/renderer/postprocess/ssr/SSRReprojectionMode.d.ts +11 -0
  205. package/src/shade/renderer/postprocess/ssr/SSRReprojectionMode.d.ts.map +1 -0
  206. package/src/shade/renderer/postprocess/ssr/SSRReprojectionMode.js +6 -0
  207. package/src/shade/renderer/postprocess/ssr/chunk_ssr_metadata.d.ts +4 -0
  208. package/src/shade/renderer/postprocess/ssr/chunk_ssr_metadata.d.ts.map +1 -0
  209. package/src/shade/renderer/postprocess/ssr/chunk_ssr_metadata.js +32 -0
  210. package/src/shade/renderer/postprocess/ssr/chunk_ssr_spatial_variance.d.ts +4 -0
  211. package/src/shade/renderer/postprocess/ssr/chunk_ssr_spatial_variance.d.ts.map +1 -0
  212. package/src/shade/renderer/postprocess/ssr/chunk_ssr_spatial_variance.js +41 -0
  213. package/src/shade/renderer/postprocess/ssr/reproject/chunk_ssr_reprojection.d.ts +3 -0
  214. package/src/shade/renderer/postprocess/ssr/reproject/chunk_ssr_reprojection.d.ts.map +1 -0
  215. package/src/shade/renderer/postprocess/ssr/reproject/chunk_ssr_reprojection.js +30 -0
  216. package/src/shade/renderer/postprocess/ssr/reproject/chunk_ssr_sample_history.d.ts +4 -0
  217. package/src/shade/renderer/postprocess/ssr/reproject/chunk_ssr_sample_history.d.ts.map +1 -0
  218. package/src/shade/renderer/postprocess/ssr/reproject/chunk_ssr_sample_history.js +70 -0
  219. package/src/shade/renderer/postprocess/ssr/resolve/build_ssr_resolve_shader.d.ts +21 -0
  220. package/src/shade/renderer/postprocess/ssr/resolve/build_ssr_resolve_shader.d.ts.map +1 -0
  221. package/src/shade/renderer/postprocess/ssr/resolve/build_ssr_resolve_shader.js +363 -0
  222. package/src/shade/renderer/postprocess/ssr/resolve/chunk_get_neighbour_weight.js +1 -1
  223. package/src/shade/renderer/postprocess/ssr/resolve/ssr_resolve_shader_Brick4.d.ts +2 -0
  224. package/src/shade/renderer/postprocess/ssr/resolve/ssr_resolve_shader_Brick4.d.ts.map +1 -0
  225. package/src/shade/renderer/postprocess/ssr/resolve/ssr_resolve_shader_Brick4.js +24 -0
  226. package/src/shade/renderer/postprocess/ssr/resolve/ssr_resolve_shader_IBL.d.ts +1 -6
  227. package/src/shade/renderer/postprocess/ssr/resolve/ssr_resolve_shader_IBL.d.ts.map +1 -1
  228. package/src/shade/renderer/postprocess/ssr/resolve/ssr_resolve_shader_IBL.js +16 -332
  229. package/src/shade/renderer/postprocess/ssr/resolve/ssr_resolve_shader_LPV.d.ts +1 -6
  230. package/src/shade/renderer/postprocess/ssr/resolve/ssr_resolve_shader_LPV.d.ts.map +1 -1
  231. package/src/shade/renderer/postprocess/ssr/resolve/ssr_resolve_shader_LPV.js +25 -358
  232. package/src/shade/renderer/postprocess/ssr/ssr_reproject_shader.d.ts +0 -5
  233. package/src/shade/renderer/postprocess/ssr/ssr_reproject_shader.d.ts.map +1 -1
  234. package/src/shade/renderer/postprocess/ssr/ssr_reproject_shader.js +201 -276
  235. package/src/shade/renderer/postprocess/ssr/ssr_spatial_denoise_shader.d.ts +1 -0
  236. package/src/shade/renderer/postprocess/ssr/ssr_spatial_denoise_shader.d.ts.map +1 -1
  237. package/src/shade/renderer/postprocess/ssr/ssr_spatial_denoise_shader.js +167 -143
  238. package/src/shade/renderer/shader/graph/graph_create_buffer.d.ts +15 -0
  239. package/src/shade/renderer/shader/graph/graph_create_buffer.d.ts.map +1 -0
  240. package/src/shade/renderer/shader/graph/graph_create_buffer.js +20 -0
  241. package/src/shade/renderer/view/GPUViewContext.d.ts +3 -4
  242. package/src/shade/renderer/view/GPUViewContext.d.ts.map +1 -1
  243. package/src/shade/renderer/view/GPUViewContext.js +5 -5
  244. package/src/core/binary/meshopt/__meshopt_test_streams.d.ts +0 -24
  245. package/src/core/binary/meshopt/__meshopt_test_streams.d.ts.map +0 -1
  246. package/src/core/binary/meshopt/__meshopt_test_streams.js +0 -237
  247. package/src/core/geom/3d/atlas/atlas_test_fixtures.d.ts +0 -84
  248. package/src/core/geom/3d/atlas/atlas_test_fixtures.d.ts.map +0 -1
  249. package/src/core/geom/3d/atlas/atlas_test_fixtures.js +0 -266
  250. package/src/engine/asset/loaders/gltf_test_fixtures.d.ts +0 -97
  251. package/src/engine/asset/loaders/gltf_test_fixtures.d.ts.map +0 -1
  252. package/src/engine/asset/loaders/gltf_test_fixtures.js +0 -359
  253. package/src/shade/renderer/animation/skin_test_fixtures.d.ts +0 -86
  254. package/src/shade/renderer/animation/skin_test_fixtures.d.ts.map +0 -1
  255. package/src/shade/renderer/animation/skin_test_fixtures.js +0 -250
  256. package/src/shade/renderer/geometry/virtual/format/attribute/vgeo_layers_test_fixtures.d.ts +0 -16
  257. package/src/shade/renderer/geometry/virtual/format/attribute/vgeo_layers_test_fixtures.d.ts.map +0 -1
  258. package/src/shade/renderer/geometry/virtual/format/attribute/vgeo_layers_test_fixtures.js +0 -27
  259. package/src/shade/renderer/particles/particle_test_fixtures.d.ts +0 -151
  260. package/src/shade/renderer/particles/particle_test_fixtures.d.ts.map +0 -1
  261. package/src/shade/renderer/particles/particle_test_fixtures.js +0 -229
  262. package/src/shade/renderer/particles/shaders/chunk_particle_emitter_world_sphere.js +0 -23
  263. package/src/shade/renderer/postprocess/ssr/reproject/shader_ffx_denoiser_reflections_reproject.js +0 -457
@@ -56,9 +56,6 @@ export function write_emitter_record(record, emitter, context) {
56
56
  record.node = context.transform_row;
57
57
  record.generation = context.generation;
58
58
 
59
- record.bounds_center.set(emitter.bounds_center);
60
- record.bounds_radius = emitter.bounds_radius;
61
-
62
59
  record.render_position = emitter.render_position;
63
60
  record.render_size = emitter.render_size;
64
61
  record.render_color = emitter.render_color;
@@ -93,9 +90,6 @@ export function create_emitter_record() {
93
90
  node: 0,
94
91
  generation: 0,
95
92
 
96
- bounds_center: new Float32Array(3),
97
- bounds_radius: 0,
98
-
99
93
  render_position: 0,
100
94
  render_size: 0,
101
95
  render_color: 0,
@@ -6,7 +6,7 @@
6
6
  * {@link graph_particles_simulate} is everything that moves particles:
7
7
  *
8
8
  * reset counters -> spawn commands -> emitter tick -> scan -> spawn args -> emit -> simulate
9
- * -> bucket -> build indirect
9
+ * -> bucket -> bounds -> build indirect
10
10
  *
11
11
  * and it leaves the frame's alive list, the pool and the indirect draw args as graph handles for
12
12
  * whoever draws. Nothing here depends on how they will be drawn, which is why the render mode
@@ -24,6 +24,15 @@
24
24
  * the scan, and the length of the spawn-command list it authored itself. Neither is a count of
25
25
  * anything alive.
26
26
  *
27
+ * ## Bounds are measured at the end, not carried along
28
+ *
29
+ * An emitter has no bounds an author could state — its particles are simulated in world space by
30
+ * arbitrary bytecode — so the box the culling and occupancy passes use is measured from the live
31
+ * particles, by `bounds/`, once emit and simulate have both finished appending. Measuring it there
32
+ * rather than inside those two passes is what makes it a box over ONE population: a merge folded
33
+ * into emit and simulate would union this frame's newborns with last frame's survivors, and would
34
+ * pay six atomics per particle inside the pass whose register pressure sets the system's occupancy.
35
+ *
27
36
  * ## Two orderings, kept apart
28
37
  *
29
38
  * Simulate does NOT read the alive list. It reads `sim_list`, the program-coherent indirection list
@@ -60,7 +69,8 @@
60
69
  * @property {number} counters the atomic counters, after build-indirect
61
70
  * @property {number} draw_args the billboard draw's indirect args: six vertices, one instance per live particle
62
71
  * @property {number} sim_dispatch_args one workgroup per live particle, for a per-particle pass
63
- * @property {number} emitter_database the emitter database, after the tick wrote its state rows
72
+ * @property {number} emitter_database the emitter database, after the bounds pass published the
73
+ * measured box into each emitter's state row
64
74
  */
65
75
  /**
66
76
  * Everything that moves particles, up to the indirect args a draw consumes.
@@ -84,8 +94,15 @@
84
94
  * @param {number} params.frame.dt
85
95
  * @param {number} params.frame.time
86
96
  * @param {number} params.frame.index
97
+ * @param {boolean} [params.frame.rebucket] program assignments changed since the previous frame
87
98
  * @param {number} params.frame.max_catchup seconds of missed spawning a woken emitter makes up
88
99
  * @param {number} params.frame.spawn_command_count entries in `gpu.spawn_commands` this frame
100
+ * @param {number} params.frame.warmup_count entries in `gpu.warmup_queue` this frame — emitters
101
+ * registered this frame with a pre-warm; zero on nearly every frame, and the warm-up is not
102
+ * recorded then
103
+ * @param {number} params.frame.warmup_capacity slots the warm-up's transient pool needs
104
+ * @param {import("./warmup/warmup_schedule.js").WarmupSchedule} params.frame.warmup_schedule how
105
+ * many ticks the warm-up runs and how long each is
89
106
  * @returns {ParticleSimulationHandles}
90
107
  */
91
108
  export function graph_particles_simulate({ graph, camera, scene_database, gpu, emitters, capacity, bucket_count, wide_registers, frame, }: {
@@ -104,8 +121,12 @@ export function graph_particles_simulate({ graph, camera, scene_database, gpu, e
104
121
  dt: number;
105
122
  time: number;
106
123
  index: number;
124
+ rebucket?: boolean;
107
125
  max_catchup: number;
108
126
  spawn_command_count: number;
127
+ warmup_count: number;
128
+ warmup_capacity: number;
129
+ warmup_schedule: import("./warmup/warmup_schedule.js").WarmupSchedule;
109
130
  };
110
131
  }): ParticleSimulationHandles;
111
132
  export type ParticleSimulationHandles = {
@@ -130,7 +151,8 @@ export type ParticleSimulationHandles = {
130
151
  */
131
152
  sim_dispatch_args: number;
132
153
  /**
133
- * the emitter database, after the tick wrote its state rows
154
+ * the emitter database, after the bounds pass published the
155
+ * measured box into each emitter's state row
134
156
  */
135
157
  emitter_database: number;
136
158
  };
@@ -1 +1 @@
1
- {"version":3,"file":"graph_particles.d.ts","sourceRoot":"","sources":["../../../../../src/shade/renderer/particles/graph_particles.js"],"names":[],"mappings":"AAqCA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsDG;AAEH;;;;;;;;GAQG;AAEH;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH;IAtBkG,KAAK,EAA5F,OAAO,2DAA2D,EAAE,UAAU;IAC/D,MAAM,EAArB,MAAM;IACS,cAAc,EAA7B,MAAM;IACS,GAAG,EAAlB,MAAM;IACS,QAAQ;QACC,QAAQ,EAAhC,MAAM;QAEkB,WAAW,EAAnC,MAAM;;IACS,QAAQ,EAAvB,MAAM;IACS,YAAY,EAA3B,MAAM;IAEU,cAAc,EAA9B,OAAO;IAGQ,KAAK;QACC,EAAE,EAAvB,MAAM;QACe,IAAI,EAAzB,MAAM;QACe,KAAK,EAA1B,MAAM;QACe,WAAW,EAAhC,MAAM;QACe,mBAAmB,EAAxC,MAAM;;IACJ,yBAAyB,CA8OrC;;;;;UA9Qa,MAAM;;;;WACN,MAAM;;;;cACN,MAAM;;;;eACN,MAAM;;;;uBACN,MAAM;;;;sBACN,MAAM"}
1
+ {"version":3,"file":"graph_particles.d.ts","sourceRoot":"","sources":["../../../../../src/shade/renderer/particles/graph_particles.js"],"names":[],"mappings":"AAuCA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+DG;AAEH;;;;;;;;;GASG;AAEH;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AACH;IA7BkG,KAAK,EAA5F,OAAO,2DAA2D,EAAE,UAAU;IAC/D,MAAM,EAArB,MAAM;IACS,cAAc,EAA7B,MAAM;IACS,GAAG,EAAlB,MAAM;IACS,QAAQ;QACC,QAAQ,EAAhC,MAAM;QAEkB,WAAW,EAAnC,MAAM;;IACS,QAAQ,EAAvB,MAAM;IACS,YAAY,EAA3B,MAAM;IAEU,cAAc,EAA9B,OAAO;IAGQ,KAAK;QACC,EAAE,EAAvB,MAAM;QACe,IAAI,EAAzB,MAAM;QACe,KAAK,EAA1B,MAAM;QACiB,QAAQ,GAA/B,OAAO;QACc,WAAW,EAAhC,MAAM;QACe,mBAAmB,EAAxC,MAAM;QACe,YAAY,EAAjC,MAAM;QAGe,eAAe,EAApC,MAAM;QAC6D,eAAe,EAAlF,OAAO,6BAA6B,EAAE,cAAc;;IAElD,yBAAyB,CAuTrC;;;;;UA/Va,MAAM;;;;WACN,MAAM;;;;cACN,MAAM;;;;eACN,MAAM;;;;uBACN,MAAM;;;;;sBACN,MAAM"}
@@ -1,13 +1,14 @@
1
1
  import { assert } from "../../../core/assert.js";
2
2
  import { align_4 } from "../../../core/binary/align_4.js";
3
- import { noop } from "../../../core/function/noop.js";
4
3
  import { BufferResourceDescriptor } from "../../device/graph/BufferResourceDescriptor.js";
5
4
  import { INDIRECT_COMPUTE_COMMAND_DESCRIPTOR } from "../gpu_primitive/indirect/IndirectComputeCommandBuildPass.js";
6
5
  import { graph_prefix_scan_csdldf } from "../gpu_primitive/prefix_sum/v1/graph_prefix_scan_csdldf.js";
7
6
  import { PREFIX_SCAN_CSDLDF_HEADER_WORDS } from "../gpu_primitive/prefix_sum/v1/shader_prefix_scan_csdldf.js";
8
7
  import { shader_prefix_sum_to_command } from "../rasterize/expand/mesh/shader_prefix_sum_to_command.js";
8
+ import { graph_particle_bounds } from "./bounds/graph_particle_bounds.js";
9
9
  import { graph_compute_indirect_pass } from "../shader/graph/compute/graph_compute_indirect_pass.js";
10
10
  import { graph_compute_pass } from "../shader/graph/compute/graph_compute_pass.js";
11
+ import { graph_create_buffer } from "../shader/graph/graph_create_buffer.js";
11
12
  import { graph_import_buffer } from "../shader/graph/graph_import_buffer.js";
12
13
  import {
13
14
  PARTICLE_SIMULATE_WORKGROUP_SIZE,
@@ -34,6 +35,7 @@ import {
34
35
  PARTICLE_SPAWN_COMMAND_WORKGROUP_SIZE,
35
36
  shader_particle_spawn_commands,
36
37
  } from "./shaders/shader_particle_spawn_commands.js";
38
+ import { graph_particle_warmup } from "./warmup/graph_particle_warmup.js";
37
39
 
38
40
  /**
39
41
  * The simulation half of the particle system's frame, recorded into the frame graph.
@@ -43,7 +45,7 @@ import {
43
45
  * {@link graph_particles_simulate} is everything that moves particles:
44
46
  *
45
47
  * reset counters -> spawn commands -> emitter tick -> scan -> spawn args -> emit -> simulate
46
- * -> bucket -> build indirect
48
+ * -> bucket -> bounds -> build indirect
47
49
  *
48
50
  * and it leaves the frame's alive list, the pool and the indirect draw args as graph handles for
49
51
  * whoever draws. Nothing here depends on how they will be drawn, which is why the render mode
@@ -61,6 +63,15 @@ import {
61
63
  * the scan, and the length of the spawn-command list it authored itself. Neither is a count of
62
64
  * anything alive.
63
65
  *
66
+ * ## Bounds are measured at the end, not carried along
67
+ *
68
+ * An emitter has no bounds an author could state — its particles are simulated in world space by
69
+ * arbitrary bytecode — so the box the culling and occupancy passes use is measured from the live
70
+ * particles, by `bounds/`, once emit and simulate have both finished appending. Measuring it there
71
+ * rather than inside those two passes is what makes it a box over ONE population: a merge folded
72
+ * into emit and simulate would union this frame's newborns with last frame's survivors, and would
73
+ * pay six atomics per particle inside the pass whose register pressure sets the system's occupancy.
74
+ *
64
75
  * ## Two orderings, kept apart
65
76
  *
66
77
  * Simulate does NOT read the alive list. It reads `sim_list`, the program-coherent indirection list
@@ -98,7 +109,8 @@ import {
98
109
  * @property {number} counters the atomic counters, after build-indirect
99
110
  * @property {number} draw_args the billboard draw's indirect args: six vertices, one instance per live particle
100
111
  * @property {number} sim_dispatch_args one workgroup per live particle, for a per-particle pass
101
- * @property {number} emitter_database the emitter database, after the tick wrote its state rows
112
+ * @property {number} emitter_database the emitter database, after the bounds pass published the
113
+ * measured box into each emitter's state row
102
114
  */
103
115
 
104
116
  /**
@@ -122,9 +134,16 @@ import {
122
134
  * @param {object} params.frame per-frame scalars
123
135
  * @param {number} params.frame.dt
124
136
  * @param {number} params.frame.time
125
- * @param {number} params.frame.index
137
+ * @param {number} params.frame.index
138
+ * @param {boolean} [params.frame.rebucket] program assignments changed since the previous frame
126
139
  * @param {number} params.frame.max_catchup seconds of missed spawning a woken emitter makes up
127
140
  * @param {number} params.frame.spawn_command_count entries in `gpu.spawn_commands` this frame
141
+ * @param {number} params.frame.warmup_count entries in `gpu.warmup_queue` this frame — emitters
142
+ * registered this frame with a pre-warm; zero on nearly every frame, and the warm-up is not
143
+ * recorded then
144
+ * @param {number} params.frame.warmup_capacity slots the warm-up's transient pool needs
145
+ * @param {import("./warmup/warmup_schedule.js").WarmupSchedule} params.frame.warmup_schedule how
146
+ * many ticks the warm-up runs and how long each is
128
147
  * @returns {ParticleSimulationHandles}
129
148
  */
130
149
  export function graph_particles_simulate({
@@ -144,9 +163,9 @@ export function graph_particles_simulate({
144
163
  assert.isPositiveInteger(capacity, "capacity");
145
164
 
146
165
  const gr_program = graph_import_buffer(graph, gpu.program, "particles/program");
147
- const gr_sim_list = graph_import_buffer(graph, gpu.sim_list, "particles/sim_list");
148
- const gr_dispatch = graph_import_buffer(graph, gpu.dispatch_args, "particles/dispatch_args");
149
- const gr_draw = graph_import_buffer(graph, gpu.draw_args, "particles/draw_args");
166
+ let gr_sim_list = graph_import_buffer(graph, gpu.sim_list, "particles/sim_list");
167
+ let gr_dispatch = graph_import_buffer(graph, gpu.dispatch_args, "particles/dispatch_args");
168
+ let gr_draw = graph_import_buffer(graph, gpu.draw_args, "particles/draw_args");
150
169
 
151
170
  // Buffers mutated by more than one pass must be THREADED: each compute pass writing an imported
152
171
  // buffer returns a renamed (versioned) handle, and the next pass must read THAT handle — reading
@@ -158,7 +177,32 @@ export function graph_particles_simulate({
158
177
  // Two tables in one buffer — the emitter records the CPU authors and the state the GPU
159
178
  // integrates — so the passes that write the state rename the handle every reader after them
160
179
  // takes.
161
- let emitter_database = graph_import_buffer(graph, gpu.emitter_database, "particles/emitter_database");
180
+ let emitter_database = graph_import_buffer(graph, gpu.emitter_database, "particles/emitter_database");
181
+
182
+ /** @type {import("./coherence/graph_particle_bucket.js").ParticleBucketScratch|undefined} */
183
+ let bucket_scratch;
184
+ if (frame.rebucket) {
185
+ // Live program edits can split a previously uniform wave. Rebuild from the previous
186
+ // compact alive list BEFORE reset discards its count and before simulate broadcasts code.
187
+ const bucketed = graph_particle_bucket({
188
+ graph, gpu, emitter_database, pool, counters, bucket_count,
189
+ alive: graph_import_buffer(graph, gpu.alive_read, "particles/alive_read"),
190
+ sim_list: gr_sim_list,
191
+ });
192
+ gr_sim_list = bucketed.sim_list;
193
+ bucket_scratch = bucketed.scratch;
194
+ const indirect = graph_compute_pass({
195
+ graph, shader: shader_particle_build_indirect,
196
+ bindings: {
197
+ counters: bucketed.counters, dispatch_args: gr_dispatch, draw_args: gr_draw,
198
+ u_workgroup_size: PARTICLE_SIMULATE_WORKGROUP_SIZE,
199
+ },
200
+ group_count: [1, 1, 1],
201
+ });
202
+ counters = indirect.counters;
203
+ gr_dispatch = indirect.dispatch_args;
204
+ gr_draw = indirect.draw_args;
205
+ }
162
206
 
163
207
  // 1. Reset the alive/sorted/sim-padded counters (dead count + ALIVE_IN snapshot persist) and
164
208
  // seed the frame's spawn budget from the free count.
@@ -188,7 +232,7 @@ export function graph_particles_simulate({
188
232
  const count_words = PREFIX_SCAN_CSDLDF_HEADER_WORDS + align_4(Math.max(1, emitters.capacity));
189
233
  const count_bytes = count_words * Uint32Array.BYTES_PER_ELEMENT;
190
234
 
191
- let spawn_counts = create_buffer(graph, "particles/spawn_counts", BufferResourceDescriptor.from(
235
+ let spawn_counts = graph_create_buffer(graph, "particles/spawn_counts", BufferResourceDescriptor.from(
192
236
  count_bytes,
193
237
  GPUBufferUsage.STORAGE,
194
238
  0, count_bytes,
@@ -203,7 +247,6 @@ export function graph_particles_simulate({
203
247
  shader: shader_particle_emitter_tick,
204
248
  bindings: {
205
249
  camera,
206
- scene_database,
207
250
  emitter_database,
208
251
  counters,
209
252
  spawn_counts,
@@ -237,7 +280,7 @@ export function graph_particles_simulate({
237
280
  // Emit and simulate share it. They cannot overlap (simulate reads the alive list emit appends
238
281
  // to), and the file carries nothing between particles, let alone between passes.
239
282
  let vm_registers = wide_registers
240
- ? create_buffer(graph, "particles/vm_registers", BufferResourceDescriptor.from(
283
+ ? graph_create_buffer(graph, "particles/vm_registers", BufferResourceDescriptor.from(
241
284
  PARTICLE_VM_WIDE_LAUNCH_LANES * PARTICLE_VM_REGISTER_SLOTS * 4,
242
285
  GPUBufferUsage.STORAGE,
243
286
  ))
@@ -249,7 +292,7 @@ export function graph_particles_simulate({
249
292
  shader: shader_prefix_sum_to_command,
250
293
  bindings: {
251
294
  prefix_sums: spawn_prefix,
252
- command: create_buffer(graph, "particles/emit_command", INDIRECT_COMPUTE_COMMAND_DESCRIPTOR),
295
+ command: graph_create_buffer(graph, "particles/emit_command", INDIRECT_COMPUTE_COMMAND_DESCRIPTOR),
253
296
  },
254
297
  group_count: [1, 1, 1],
255
298
  }).command;
@@ -325,6 +368,36 @@ export function graph_particles_simulate({
325
368
  pool = out.pool; alive_write = out.alive_out; dead = out.dead; counters = out.counters;
326
369
  }
327
370
 
371
+ // 7b. Warm-up — on a frame that registered emitters with a pre-warm, and only then: run their
372
+ // simulations forward over a transient population of their own and move what survives into
373
+ // the main pool. A pipeline apart from the one above, sharing its emit pass and nothing else;
374
+ // see `warmup/graph_particle_warmup.js`. After simulate so the frame's own work is done
375
+ // first, before the bucketing so the warmed particles are in next frame's list, measured by
376
+ // this frame's bounds pass and drawn by this frame's draw.
377
+ if (frame.warmup_count > 0) {
378
+ const out = graph_particle_warmup({
379
+ graph,
380
+ scene_database,
381
+ emitter_database,
382
+ program: gr_program,
383
+ pool, alive_out: alive_write, dead, counters,
384
+ vm_registers,
385
+ queue: gpu.warmup_queue,
386
+ queue_count: frame.warmup_count,
387
+ warm_capacity: frame.warmup_capacity,
388
+ capacity,
389
+ emitter_capacity: emitters.capacity,
390
+ schedule: frame.warmup_schedule,
391
+ wide_registers,
392
+ frame,
393
+ });
394
+
395
+ pool = out.pool; alive_write = out.alive_out; dead = out.dead; counters = out.counters;
396
+ emitter_database = out.emitter_database;
397
+
398
+ if (wide_registers) { vm_registers = out.vm_registers; }
399
+ }
400
+
328
401
  // 8. Bucket — regroup the frame's alive list by VM program, padded to whole workgroups, into the
329
402
  // list NEXT frame's simulate consumes. Must follow BOTH emit and simulate, since both append
330
403
  // to the alive list.
@@ -338,13 +411,32 @@ export function graph_particles_simulate({
338
411
  pool,
339
412
  alive: alive_write,
340
413
  counters,
341
- sim_list: gr_sim_list,
342
- bucket_count,
414
+ sim_list: gr_sim_list,
415
+ bucket_count,
416
+ scratch: bucket_scratch,
343
417
  });
344
418
  counters = bucketed.counters;
345
419
 
346
- // 9. Snapshot the padded list length (next frame's simulate input length) and build the indirect
347
- // dispatch args for next frame + the indirect draw args for this frame's render.
420
+ // 9. Measure every emitter's bounding box from the alive list, and publish it into the state
421
+ // rows the tick and the AVBOIT occupancy read. After the bucketing because the dispatch is
422
+ // the one the coherence reset sized from the GPU's own alive count.
423
+ {
424
+ const out = graph_particle_bounds({
425
+ graph,
426
+ emitter_database,
427
+ pool,
428
+ alive: alive_write,
429
+ counters,
430
+ dispatch_args: bucketed.dispatch_args,
431
+ emitter_group_count: emitters.group_count,
432
+ });
433
+
434
+ counters = out.counters;
435
+ emitter_database = out.emitter_database;
436
+ }
437
+
438
+ // 10. Snapshot the padded list length (next frame's simulate input length) and build the indirect
439
+ // dispatch args for next frame + the indirect draw args for this frame's render.
348
440
  const indirect = graph_compute_pass({
349
441
  graph,
350
442
  shader: shader_particle_build_indirect,
@@ -365,18 +457,3 @@ export function graph_particles_simulate({
365
457
  };
366
458
  }
367
459
 
368
- /**
369
- * A transient buffer with no producing pass of its own, for a binding a shader both reads and
370
- * writes — the compute pass helpers create a buffer only for write-only bindings, and a
371
- * read-write one wants a handle.
372
- *
373
- * @param {import("../../../engine/graphics/render/frame_graph/FrameGraph.js").FrameGraph} graph
374
- * @param {string} label
375
- * @param {BufferResourceDescriptor} descriptor
376
- * @returns {number}
377
- */
378
- function create_buffer(graph, label, descriptor) {
379
- const pass = graph.add(`${label} / create`, {}, noop);
380
-
381
- return pass.create(label, descriptor);
382
- }
@@ -1,22 +1,24 @@
1
1
  /**
2
- * Mark the depth slices the emitters' bounds spheres span (`shader_particle_avboit_occupancy`).
2
+ * Mark the depth slices the emitters' measured bounding boxes span
3
+ * (`shader_particle_avboit_occupancy`).
4
+ *
5
+ * The boxes are world-space and live in the emitter state table, so there is no scene database here:
6
+ * the tick already resolved every emitter's node when it published them.
3
7
  *
4
8
  * @param {object} params
5
9
  * @param {import("../../../engine/graphics/render/frame_graph/FrameGraph.js").FrameGraph} params.graph
6
10
  * @param {number} params.camera graph handle
7
11
  * @param {ArrayLike<number>} params.cluster_parameters the frame's depth curve
8
12
  * @param {number} params.occupancy graph handle of the occupancy bits, to add to
9
- * @param {number} params.scene_database graph handle
10
13
  * @param {number} params.emitter_database graph handle, as the simulation left it
11
14
  * @param {number} params.emitter_group_count workgroups that walk every page group of the emitter table
12
15
  * @returns {number} the occupancy handle after the write
13
16
  */
14
- export function graph_particle_avboit_occupancy({ graph, camera, cluster_parameters, occupancy, scene_database, emitter_database, emitter_group_count, }: {
17
+ export function graph_particle_avboit_occupancy({ graph, camera, cluster_parameters, occupancy, emitter_database, emitter_group_count, }: {
15
18
  graph: import("../../../engine/graphics/render/frame_graph/FrameGraph.js").FrameGraph;
16
19
  camera: number;
17
20
  cluster_parameters: ArrayLike<number>;
18
21
  occupancy: number;
19
- scene_database: number;
20
22
  emitter_database: number;
21
23
  emitter_group_count: number;
22
24
  }): number;
@@ -1 +1 @@
1
- {"version":3,"file":"graph_particles_avboit.d.ts","sourceRoot":"","sources":["../../../../../src/shade/renderer/particles/graph_particles_avboit.js"],"names":[],"mappings":"AAqCA;;;;;;;;;;;;GAYG;AACH;IATkG,KAAK,EAA5F,OAAO,2DAA2D,EAAE,UAAU;IAC/D,MAAM,EAArB,MAAM;IACoB,kBAAkB,EAA5C,UAAU,MAAM,CAAC;IACF,SAAS,EAAxB,MAAM;IACS,cAAc,EAA7B,MAAM;IACS,gBAAgB,EAA/B,MAAM;IACS,mBAAmB,EAAlC,MAAM;IACJ,MAAM,CAiDlB;AAED;;;;;;;;;;;;;;;GAeG;AACH;IAZkG,KAAK,EAA5F,OAAO,2DAA2D,EAAE,UAAU;IAC/D,MAAM,EAArB,MAAM;IACS,IAAI,EAAnB,MAAM;IACwD,MAAM,EAApE;QAAC,UAAU,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAC;IAC9B,KAAK;IACT,aAAa;IACjB,IAAI,EAAnB,MAAM;IACS,KAAK,EAApB,MAAM;IACS,gBAAgB,EAA/B,MAAM;IACS,SAAS,EAAxB,MAAM;IACJ;IAAC,UAAU,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAC,CA8EjE;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH;IAjBkG,KAAK,EAA5F,OAAO,2DAA2D,EAAE,UAAU;IACnB,QAAQ,EAAnE,OAAO,2BAA2B,EAAE,cAAc;IACnC,MAAM,EAArB,MAAM;IACS,aAAa,EAA5B,MAAM;IACS,IAAI,EAAnB,MAAM;IACS,QAAQ,EAAvB,MAAM;IACS,eAAe,EAA9B,MAAM;IACS,oBAAoB,EAAnC,MAAM;IACsE,YAAY,EAAxF;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAC;IAC5C,KAAK;IACT,aAAa;IACjB,IAAI,EAAnB,MAAM;IACS,KAAK,EAApB,MAAM;IACS,gBAAgB,EAA/B,MAAM;IACS,SAAS,EAAxB,MAAM;IACJ;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAC,CAoG/E"}
1
+ {"version":3,"file":"graph_particles_avboit.d.ts","sourceRoot":"","sources":["../../../../../src/shade/renderer/particles/graph_particles_avboit.js"],"names":[],"mappings":"AAqCA;;;;;;;;;;;;;;;GAeG;AACH;IARkG,KAAK,EAA5F,OAAO,2DAA2D,EAAE,UAAU;IAC/D,MAAM,EAArB,MAAM;IACoB,kBAAkB,EAA5C,UAAU,MAAM,CAAC;IACF,SAAS,EAAxB,MAAM;IACS,gBAAgB,EAA/B,MAAM;IACS,mBAAmB,EAAlC,MAAM;IACJ,MAAM,CA8ClB;AAED;;;;;;;;;;;;;;;GAeG;AACH;IAZkG,KAAK,EAA5F,OAAO,2DAA2D,EAAE,UAAU;IAC/D,MAAM,EAArB,MAAM;IACS,IAAI,EAAnB,MAAM;IACwD,MAAM,EAApE;QAAC,UAAU,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAC;IAC9B,KAAK;IACT,aAAa;IACjB,IAAI,EAAnB,MAAM;IACS,KAAK,EAApB,MAAM;IACS,gBAAgB,EAA/B,MAAM;IACS,SAAS,EAAxB,MAAM;IACJ;IAAC,UAAU,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAC,CA8EjE;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH;IAjBkG,KAAK,EAA5F,OAAO,2DAA2D,EAAE,UAAU;IACnB,QAAQ,EAAnE,OAAO,2BAA2B,EAAE,cAAc;IACnC,MAAM,EAArB,MAAM;IACS,aAAa,EAA5B,MAAM;IACS,IAAI,EAAnB,MAAM;IACS,QAAQ,EAAvB,MAAM;IACS,eAAe,EAA9B,MAAM;IACS,oBAAoB,EAAnC,MAAM;IACsE,YAAY,EAAxF;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAC;IAC5C,KAAK;IACT,aAAa;IACjB,IAAI,EAAnB,MAAM;IACS,KAAK,EAApB,MAAM;IACS,gBAAgB,EAA/B,MAAM;IACS,SAAS,EAAxB,MAAM;IACJ;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAC,CAoG/E"}
@@ -36,14 +36,17 @@ const COLOR_VIEW = TextureViewDescriptor.from({ mipLevelCount: 1, baseMipLevel:
36
36
  const SAMPLER_LINEAR = SamplerDescriptor.from({ magFilter: "linear" });
37
37
 
38
38
  /**
39
- * Mark the depth slices the emitters' bounds spheres span (`shader_particle_avboit_occupancy`).
39
+ * Mark the depth slices the emitters' measured bounding boxes span
40
+ * (`shader_particle_avboit_occupancy`).
41
+ *
42
+ * The boxes are world-space and live in the emitter state table, so there is no scene database here:
43
+ * the tick already resolved every emitter's node when it published them.
40
44
  *
41
45
  * @param {object} params
42
46
  * @param {import("../../../engine/graphics/render/frame_graph/FrameGraph.js").FrameGraph} params.graph
43
47
  * @param {number} params.camera graph handle
44
48
  * @param {ArrayLike<number>} params.cluster_parameters the frame's depth curve
45
49
  * @param {number} params.occupancy graph handle of the occupancy bits, to add to
46
- * @param {number} params.scene_database graph handle
47
50
  * @param {number} params.emitter_database graph handle, as the simulation left it
48
51
  * @param {number} params.emitter_group_count workgroups that walk every page group of the emitter table
49
52
  * @returns {number} the occupancy handle after the write
@@ -53,7 +56,6 @@ export function graph_particle_avboit_occupancy({
53
56
  camera,
54
57
  cluster_parameters,
55
58
  occupancy,
56
- scene_database,
57
59
  emitter_database,
58
60
  emitter_group_count,
59
61
  }) {
@@ -75,7 +77,6 @@ export function graph_particle_avboit_occupancy({
75
77
  bindings: {
76
78
  camera: resources.get(data.camera),
77
79
  settings: encoder.allocateTransientValueBuffer(AVBOIT_OCCUPANCY_SETTINGS_STRUCT, settings, GPUBufferUsage.UNIFORM),
78
- scene_database: resources.get(data.scene_database),
79
80
  emitter_database: resources.get(data.emitter_database),
80
81
  occupancy: resources.get(data.occupancy),
81
82
  },
@@ -89,7 +90,6 @@ export function graph_particle_avboit_occupancy({
89
90
  const pass = graph.add("Particle AVBOIT Occupancy", pass_data, execute);
90
91
 
91
92
  pass_data.camera = pass.read(camera);
92
- pass_data.scene_database = pass.read(scene_database);
93
93
  pass_data.emitter_database = pass.read(emitter_database);
94
94
  pass.read(occupancy);
95
95
  pass_data.occupancy = pass.write(occupancy);
@@ -42,6 +42,11 @@ export class EmitterRegistry {
42
42
  * @type {ProgramHeap}
43
43
  */
44
44
  programs: ProgramHeap;
45
+ /**
46
+ * Changes when a live emitter moves to different bytecode; invalidates simulation grouping.
47
+ * @type {number}
48
+ */
49
+ program_assignment_version: number;
45
50
  /**
46
51
  * The live emitters, in no particular order — the row in {@link context} is the identity.
47
52
  * @type {ParticleEmitter[]}
@@ -1 +1 @@
1
- {"version":3,"file":"EmitterRegistry.d.ts","sourceRoot":"","sources":["../../../../../../src/shade/renderer/particles/runtime/EmitterRegistry.js"],"names":[],"mappings":"AAsBA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH;IAwEI;;OAEG;IACH,+BASC;IAlFD;;OAEG;IACH,UAFU,WAAW,CAEZ;IAET;;;OAGG;IACH,UAFU,WAAW,CAEQ;IAE7B;;;OAGG;IACH,UAFU,eAAe,EAAE,CAEb;IAEd;;;;;OAKG;IACH,QAFU,eAAe,EAAE,CAEf;IAEZ;;;;;;;;;;OAUG;IACH,8BAEC;IA8CD;;;OAGG;IACH,2BAEC;IAED;;;;OAIG;IACH,iCAEC;IAED;;OAEG;IACH,oBAEC;IAED;;;OAGG;IACH,4BAEC;IAED;;;;;OAKG;IACH,kCAEC;IAED;;;;;;;OAOG;IACH,iCAEC;IAED;;;;;;;;;OASG;IACH,iBAHW,eAAe,GACb,yBAAyB,GAAC,SAAS,CAI/C;IAED;;;;;;;;OAQG;IACH,YANW,eAAe,GAAC,MAAM,kBAEtB,MAAM,GAEJ,eAAe,CA8B3B;IAED;;;;;;;;;;;;;OAaG;IACH,gBAFW,eAAe,QA4BzB;IAED;;;;;;;;;;;;;;;OAeG;IACH,qBAHW,eAAe,WACf,OAAO,2BAA2B,EAAE,eAAe,QAqB7D;IAED;;;;;OAKG;IACH,SAHW,MAAM,GACJ,eAAe,GAAC,SAAS,CAIrC;IAED;;;;;;OAMG;IACH,2BAHW,eAAe,iBACf,MAAM,QAehB;IAED;;;;;;;;;OASG;IACH,0BAHW,eAAe,UACf,UAAU,MAAM,CAAC,QAoB3B;IAED;;;;;;;;;;;;;OAaG;IACH,cAoBC;IAED;;;;;;;;;OASG;IACH,iBAFa,WAAW,CAMvB;;CACJ;4BApb2B,mCAAmC;4BAYnC,kBAAkB;gCADd,sBAAsB;0CADZ,gCAAgC"}
1
+ {"version":3,"file":"EmitterRegistry.d.ts","sourceRoot":"","sources":["../../../../../../src/shade/renderer/particles/runtime/EmitterRegistry.js"],"names":[],"mappings":"AAsBA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH;IA8EI;;OAEG;IACH,+BASC;IAxFD;;OAEG;IACH,UAFU,WAAW,CAEZ;IAET;;;OAGG;IACH,UAFU,WAAW,CAEQ;IAE7B;;;OAGG;IACH,4BAFU,MAAM,CAEe;IAE/B;;;OAGG;IACH,UAFU,eAAe,EAAE,CAEb;IAEd;;;;;OAKG;IACH,QAFU,eAAe,EAAE,CAEf;IAEZ;;;;;;;;;;OAUG;IACH,8BAEC;IA8CD;;;OAGG;IACH,2BAEC;IAED;;;;OAIG;IACH,iCAEC;IAED;;OAEG;IACH,oBAEC;IAED;;;OAGG;IACH,4BAEC;IAED;;;;;OAKG;IACH,kCAEC;IAED;;;;;;;OAOG;IACH,iCAEC;IAED;;;;;;;;;OASG;IACH,iBAHW,eAAe,GACb,yBAAyB,GAAC,SAAS,CAI/C;IAED;;;;;;;;OAQG;IACH,YANW,eAAe,GAAC,MAAM,kBAEtB,MAAM,GAEJ,eAAe,CA+B3B;IAED;;;;;;;;;;;;;OAaG;IACH,gBAFW,eAAe,QA6BzB;IAED;;;;;;;;;;;;;;;OAeG;IACH,qBAHW,eAAe,WACf,OAAO,2BAA2B,EAAE,eAAe,QA0B7D;IAED;;;;;OAKG;IACH,SAHW,MAAM,GACJ,eAAe,GAAC,SAAS,CAIrC;IAED;;;;;;OAMG;IACH,2BAHW,eAAe,iBACf,MAAM,QAehB;IAED;;;;;;;;;OASG;IACH,0BAHW,eAAe,UACf,UAAU,MAAM,CAAC,QAoB3B;IAED;;;;;;;;;;;;;OAaG;IACH,cA4BC;IAED;;;;;;;;;OASG;IACH,iBAFa,WAAW,CAMvB;;CACJ;4BAzc2B,mCAAmC;4BAYnC,kBAAkB;gCADd,sBAAsB;0CADZ,gCAAgC"}
@@ -61,7 +61,13 @@ export class EmitterRegistry {
61
61
  * Packed instruction + constant buffers for every distinct program in the set.
62
62
  * @type {ProgramHeap}
63
63
  */
64
- programs = new ProgramHeap();
64
+ programs = new ProgramHeap();
65
+
66
+ /**
67
+ * Changes when a live emitter moves to different bytecode; invalidates simulation grouping.
68
+ * @type {number}
69
+ */
70
+ program_assignment_version = 0;
65
71
 
66
72
  /**
67
73
  * The live emitters, in no particular order — the row in {@link context} is the identity.
@@ -220,7 +226,8 @@ export class EmitterRegistry {
220
226
 
221
227
  const context = new GPUParticleEmitterContext();
222
228
 
223
- context.placement = this.programs.acquire(emitter.program);
229
+ context.placement = this.programs.acquire(emitter.program);
230
+ context.program = emitter.program;
224
231
 
225
232
  context.generation = this.#generation;
226
233
  this.#generation = particle_generation_next(this.#generation);
@@ -280,7 +287,8 @@ export class EmitterRegistry {
280
287
 
281
288
  this.programs.release(context.placement);
282
289
 
283
- context.placement = null;
290
+ context.placement = null;
291
+ context.program = null;
284
292
 
285
293
  this.#contexts.delete(emitter);
286
294
  }
@@ -315,7 +323,12 @@ export class EmitterRegistry {
315
323
  // unpacks it nor gives it a new id
316
324
  context.placement = this.programs.acquire(program);
317
325
 
318
- emitter.program = program;
326
+ emitter.program = program;
327
+ context.program = program;
328
+
329
+ if (context.placement !== previous) {
330
+ this.program_assignment_version++;
331
+ }
319
332
 
320
333
  this.programs.release(previous);
321
334
 
@@ -398,8 +411,16 @@ export class EmitterRegistry {
398
411
  * Stages through the one module-static record, so a frame's restaging allocates nothing however
399
412
  * many rows it touches.
400
413
  */
401
- flush() {
402
- const table = this.table;
414
+ flush() {
415
+ const table = this.table;
416
+
417
+ // Reconcile plain-field edits before checking relocation: an acquire can repack the heap
418
+ // and move placements of rows we would otherwise have already staged.
419
+ for (const [emitter, context] of this.#contexts) {
420
+ if (emitter.program !== context.program) {
421
+ this.set_program(emitter, emitter.program);
422
+ }
423
+ }
403
424
 
404
425
  const placement_version = this.programs.placement_version;
405
426
 
@@ -56,6 +56,10 @@ export class GPUParticleEmitterContext {
56
56
  * @type {import("./ProgramPlacement.js").ProgramPlacement|null}
57
57
  */
58
58
  placement: import("./ProgramPlacement.js").ProgramPlacement | null;
59
+ /** Author's immutable program reference, distinct from the heap's owned copy.
60
+ * @type {import("../isa/ParticleProgram.js").ParticleProgram|null}
61
+ */
62
+ program: import("../isa/ParticleProgram.js").ParticleProgram | null;
59
63
  /**
60
64
  * Where {@link ./ParticleEmitter.js#texture} landed in the particle system's atlas: uv offset
61
65
  * `.xy`, uv scale `.zw`. Mirrors meep's `AtlasPatch`.
@@ -1 +1 @@
1
- {"version":3,"file":"GPUParticleEmitterContext.d.ts","sourceRoot":"","sources":["../../../../../../src/shade/renderer/particles/runtime/GPUParticleEmitterContext.js"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;;;;;GAoBG;AACH;IAEI;;;;;;;;;OASG;IACH,KAFU,MAAM,CAEP;IAET;;;;;;OAMG;IACH,YAFU,MAAM,CAED;IAEf;;;;;;OAMG;IACH,eAFU,MAAM,CAEE;IAElB;;;;;;;OAOG;IACH,WAFU,OAAO,uBAAuB,EAAE,gBAAgB,GAAC,IAAI,CAE9C;IAEjB;;;;;;;;;;OAUG;IACH,cAFU,YAAY,CAEwB;IAE9C;;;;;;;;;;;;;;;;;;;OAmBG;IACH,gBAFU,MAAM,CAEI;IAEpB;;;OAGG;IACH,kBAHW,OAAO,sBAAsB,EAAE,eAAe,GAC5C,OAAO,CAInB;IAED;;;OAGG;IACH,mBAEC;IAED;;;;OAIG;IACH,gBAFW,OAAO,sBAAsB,EAAE,eAAe,QAMxD;CACJ"}
1
+ {"version":3,"file":"GPUParticleEmitterContext.d.ts","sourceRoot":"","sources":["../../../../../../src/shade/renderer/particles/runtime/GPUParticleEmitterContext.js"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;;;;;GAoBG;AACH;IAEI;;;;;;;;;OASG;IACH,KAFU,MAAM,CAEP;IAET;;;;;;OAMG;IACH,YAFU,MAAM,CAED;IAEf;;;;;;OAMG;IACH,eAFU,MAAM,CAEE;IAElB;;;;;;;OAOG;IACH,WAFU,OAAO,uBAAuB,EAAE,gBAAgB,GAAC,IAAI,CAE9C;IAEjB;;OAEG;IACH,SAFU,OAAO,2BAA2B,EAAE,eAAe,GAAC,IAAI,CAEnD;IAEf;;;;;;;;;;OAUG;IACH,cAFU,YAAY,CAEwB;IAE9C;;;;;;;;;;;;;;;;;;;OAmBG;IACH,gBAFU,MAAM,CAEI;IAEpB;;;OAGG;IACH,kBAHW,OAAO,sBAAsB,EAAE,eAAe,GAC5C,OAAO,CAInB;IAED;;;OAGG;IACH,mBAEC;IAED;;;;OAIG;IACH,gBAFW,OAAO,sBAAsB,EAAE,eAAe,QAMxD;CACJ"}
@@ -61,7 +61,12 @@ export class GPUParticleEmitterContext {
61
61
  *
62
62
  * @type {import("./ProgramPlacement.js").ProgramPlacement|null}
63
63
  */
64
- placement = null;
64
+ placement = null;
65
+
66
+ /** Author's immutable program reference, distinct from the heap's owned copy.
67
+ * @type {import("../isa/ParticleProgram.js").ParticleProgram|null}
68
+ */
69
+ program = null;
65
70
 
66
71
  /**
67
72
  * Where {@link ./ParticleEmitter.js#texture} landed in the particle system's atlas: uv offset