@woosh/meep-engine 3.16.0 → 3.17.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 (410) hide show
  1. package/editor/particles/effect/ParticleEffectDocument.d.ts +21 -6
  2. package/editor/particles/effect/ParticleEffectDocument.d.ts.map +1 -1
  3. package/editor/particles/effect/ParticleEffectDocument.js +38 -17
  4. package/editor/view/node-graph/NodeGraphClipboard.d.ts +186 -0
  5. package/editor/view/node-graph/NodeGraphClipboard.d.ts.map +1 -0
  6. package/editor/view/node-graph/NodeGraphClipboard.js +231 -0
  7. package/editor/view/node-graph/NodeGraphEditorView.d.ts +59 -1
  8. package/editor/view/node-graph/NodeGraphEditorView.d.ts.map +1 -1
  9. package/editor/view/node-graph/NodeGraphEditorView.js +248 -5
  10. package/editor/view/node-graph/NodeGraphView.d.ts.map +1 -1
  11. package/editor/view/node-graph/NodeGraphView.js +84 -8
  12. package/editor/view/node-graph/actions/connection_bind_actions.d.ts +23 -0
  13. package/editor/view/node-graph/actions/connection_bind_actions.d.ts.map +1 -0
  14. package/editor/view/node-graph/actions/connection_bind_actions.js +39 -0
  15. package/editor/view/particles/effect/ParticleCodeEditorView.d.ts.map +1 -1
  16. package/editor/view/particles/effect/ParticleCodeEditorView.js +4 -3
  17. package/editor/view/particles/effect/ParticleCurveEditorView.d.ts +20 -0
  18. package/editor/view/particles/effect/ParticleCurveEditorView.d.ts.map +1 -0
  19. package/editor/view/particles/effect/ParticleCurveEditorView.js +574 -0
  20. package/editor/view/particles/effect/ParticleEmitterInspectorView.d.ts.map +1 -1
  21. package/editor/view/particles/effect/ParticleEmitterInspectorView.js +27 -1
  22. package/editor/view/particles/effect/ParticleGradientEditorView.d.ts +24 -0
  23. package/editor/view/particles/effect/ParticleGradientEditorView.d.ts.map +1 -0
  24. package/editor/view/particles/effect/ParticleGradientEditorView.js +472 -0
  25. package/editor/view/particles/effect/ParticleGraphEditorView.d.ts +5 -0
  26. package/editor/view/particles/effect/ParticleGraphEditorView.d.ts.map +1 -1
  27. package/editor/view/particles/effect/ParticleGraphEditorView.js +61 -31
  28. package/editor/view/particles/effect/ParticleNodeParametersView.d.ts.map +1 -1
  29. package/editor/view/particles/effect/ParticleNodeParametersView.js +33 -0
  30. package/editor/view/particles/effect/particle-editor.css +123 -35
  31. package/package.json +1 -1
  32. package/src/core/binary/allocator/OffsetAllocator.d.ts +25 -16
  33. package/src/core/binary/allocator/OffsetAllocator.d.ts.map +1 -1
  34. package/src/core/binary/allocator/OffsetAllocator.js +10 -1
  35. package/src/core/collection/array/typed/float32_array_hash.d.ts +21 -0
  36. package/src/core/collection/array/typed/float32_array_hash.d.ts.map +1 -0
  37. package/src/core/collection/array/typed/float32_array_hash.js +38 -0
  38. package/src/core/graph/csr/CSRGraph.d.ts +8 -1
  39. package/src/core/graph/csr/CSRGraph.d.ts.map +1 -1
  40. package/src/core/graph/csr/CSRGraph.js +14 -6
  41. package/src/core/model/node-graph/visual/layout/LayoutProblem.d.ts +24 -0
  42. package/src/core/model/node-graph/visual/layout/LayoutProblem.d.ts.map +1 -1
  43. package/src/core/model/node-graph/visual/layout/LayoutProblem.js +27 -0
  44. package/src/core/model/node-graph/visual/layout/NodeGraphLayoutOptions.d.ts +26 -0
  45. package/src/core/model/node-graph/visual/layout/NodeGraphLayoutOptions.d.ts.map +1 -1
  46. package/src/core/model/node-graph/visual/layout/NodeGraphLayoutOptions.js +28 -0
  47. package/src/core/model/node-graph/visual/layout/RouteGrid.d.ts +92 -3
  48. package/src/core/model/node-graph/visual/layout/RouteGrid.d.ts.map +1 -1
  49. package/src/core/model/node-graph/visual/layout/RouteGrid.js +405 -242
  50. package/src/core/model/node-graph/visual/layout/RouteSearch.d.ts +50 -5
  51. package/src/core/model/node-graph/visual/layout/RouteSearch.d.ts.map +1 -1
  52. package/src/core/model/node-graph/visual/layout/RouteSearch.js +160 -24
  53. package/src/core/model/node-graph/visual/layout/RouteSet.d.ts +7 -0
  54. package/src/core/model/node-graph/visual/layout/RouteSet.d.ts.map +1 -1
  55. package/src/core/model/node-graph/visual/layout/RouteSet.js +8 -0
  56. package/src/core/model/node-graph/visual/layout/layout_assign_coordinates.js +9 -3
  57. package/src/core/model/node-graph/visual/layout/layout_build_problem.d.ts.map +1 -1
  58. package/src/core/model/node-graph/visual/layout/layout_build_problem.js +7 -0
  59. package/src/core/model/node-graph/visual/layout/layout_insert_lanes.d.ts +9 -3
  60. package/src/core/model/node-graph/visual/layout/layout_insert_lanes.d.ts.map +1 -1
  61. package/src/core/model/node-graph/visual/layout/layout_insert_lanes.js +17 -3
  62. package/src/core/model/node-graph/visual/layout/layout_node_graph.d.ts +9 -6
  63. package/src/core/model/node-graph/visual/layout/layout_node_graph.d.ts.map +1 -1
  64. package/src/core/model/node-graph/visual/layout/layout_node_graph.js +49 -7
  65. package/src/core/model/node-graph/visual/layout/layout_order_layers.d.ts +11 -1
  66. package/src/core/model/node-graph/visual/layout/layout_order_layers.d.ts.map +1 -1
  67. package/src/core/model/node-graph/visual/layout/layout_order_layers.js +135 -16
  68. package/src/core/model/node-graph/visual/layout/route_connections.d.ts +29 -0
  69. package/src/core/model/node-graph/visual/layout/route_connections.d.ts.map +1 -1
  70. package/src/core/model/node-graph/visual/layout/route_connections.js +716 -309
  71. package/src/core/model/node-graph/visual/layout/route_grid_build.d.ts +3 -2
  72. package/src/core/model/node-graph/visual/layout/route_grid_build.d.ts.map +1 -1
  73. package/src/core/model/node-graph/visual/layout/route_grid_build.js +7 -15
  74. package/src/core/model/node-graph/visual/layout/route_nudge.d.ts +6 -0
  75. package/src/core/model/node-graph/visual/layout/route_nudge.d.ts.map +1 -1
  76. package/src/core/model/node-graph/visual/layout/route_nudge.js +42 -13
  77. package/src/engine/animation/AnimationUtils.js +246 -246
  78. package/src/engine/animation/Animations.js +74 -74
  79. package/src/engine/control/first-person/FirstPersonPlayerControllerSystem.js +2078 -2078
  80. package/src/engine/ecs/EventType.d.ts +0 -1
  81. package/src/engine/ecs/EventType.js +1 -26
  82. package/src/engine/ecs/ik/ik_write_local_rotation.d.ts +1 -1
  83. package/src/engine/ecs/ik/ik_write_local_rotation.d.ts.map +1 -1
  84. package/src/engine/ecs/ik/ik_write_local_rotation.js +3 -7
  85. package/src/engine/ecs/parent/EntityNode.d.ts.map +1 -1
  86. package/src/engine/ecs/parent/EntityNode.js +4 -9
  87. package/src/engine/ecs/terrain/ecs/cling/ClingToTerrainSystem.d.ts.map +1 -1
  88. package/src/engine/ecs/terrain/ecs/cling/ClingToTerrainSystem.js +360 -364
  89. package/src/engine/ecs/transform/TRANSFORM64_EVENT_CHANGE.d.ts +41 -0
  90. package/src/engine/ecs/transform/TRANSFORM64_EVENT_CHANGE.d.ts.map +1 -0
  91. package/src/engine/ecs/transform/TRANSFORM64_EVENT_CHANGE.js +40 -0
  92. package/src/engine/ecs/transform/TRANSFORM64_MIGRATION_PLAN_2026_09_04.md +8 -0
  93. package/src/engine/ecs/transform/t64_announce_change.d.ts +10 -7
  94. package/src/engine/ecs/transform/t64_announce_change.d.ts.map +1 -1
  95. package/src/engine/ecs/transform/t64_announce_change.js +12 -12
  96. package/src/engine/ecs/transform-attachment/TRANSFORM_ATTACHMENT_EVENT_CHANGE.d.ts +30 -0
  97. package/src/engine/ecs/transform-attachment/TRANSFORM_ATTACHMENT_EVENT_CHANGE.d.ts.map +1 -0
  98. package/src/engine/ecs/transform-attachment/TRANSFORM_ATTACHMENT_EVENT_CHANGE.js +29 -0
  99. package/src/engine/ecs/transform-attachment/TransformAttachmentSystem.d.ts.map +1 -1
  100. package/src/engine/ecs/transform-attachment/TransformAttachmentSystem.js +13 -21
  101. package/src/engine/graphics/ecs/sprite/SpriteSystemPE.d.ts.map +1 -1
  102. package/src/engine/graphics/ecs/sprite/SpriteSystemPE.js +4 -8
  103. package/src/engine/graphics3/LightSystem.d.ts.map +1 -1
  104. package/src/engine/graphics3/LightSystem.js +4 -8
  105. package/src/engine/graphics3/MeshSystem.d.ts.map +1 -1
  106. package/src/engine/graphics3/MeshSystem.js +9 -19
  107. package/src/engine/graphics3/ParticleEmitterSystem.d.ts.map +1 -1
  108. package/src/engine/graphics3/ParticleEmitterSystem.js +4 -8
  109. package/src/engine/graphics3/ShadedGeometrySystem.d.ts.map +1 -1
  110. package/src/engine/graphics3/ShadedGeometrySystem.js +4 -10
  111. package/src/engine/grid/transform2grid/Transform2GridPositionSystem.d.ts +1 -1
  112. package/src/engine/grid/transform2grid/Transform2GridPositionSystem.d.ts.map +1 -1
  113. package/src/engine/grid/transform2grid/Transform2GridPositionSystem.js +4 -8
  114. package/src/engine/intelligence/behavior/ecs/OrbitingBehavior.js +218 -218
  115. package/src/engine/physics/ecs/PhysicsSystem.d.ts.map +1 -1
  116. package/src/engine/physics/ecs/PhysicsSystem.js +2 -5
  117. package/src/engine/sound/ecs/SoundListenerSystem.d.ts.map +1 -1
  118. package/src/engine/sound/ecs/SoundListenerSystem.js +6 -8
  119. package/src/engine/sound/simulation/ecs/AcousticSimulationSystem.d.ts +0 -4
  120. package/src/engine/sound/simulation/ecs/AcousticSimulationSystem.d.ts.map +1 -1
  121. package/src/engine/sound/simulation/ecs/AcousticSimulationSystem.js +5 -11
  122. package/src/shade/playground/particle_editor/README.md +43 -2
  123. package/src/shade/playground/particle_system/particle_prototype.d.ts.map +1 -1
  124. package/src/shade/playground/particle_system/particle_prototype.js +4 -5
  125. package/src/shade/playground/particle_system/particle_scene.js +4 -4
  126. package/src/shade/renderer/Renderer.d.ts.map +1 -1
  127. package/src/shade/renderer/Renderer.js +13 -1
  128. package/src/shade/renderer/particles/DESIGN.md +104 -19
  129. package/src/shade/renderer/particles/GPUParticleSystem.d.ts +64 -50
  130. package/src/shade/renderer/particles/GPUParticleSystem.d.ts.map +1 -1
  131. package/src/shade/renderer/particles/GPUParticleSystem.js +176 -78
  132. package/src/shade/renderer/particles/ParticleConstants.d.ts +59 -23
  133. package/src/shade/renderer/particles/ParticleConstants.d.ts.map +1 -1
  134. package/src/shade/renderer/particles/ParticleConstants.js +66 -23
  135. package/src/shade/renderer/particles/ParticleRenderMode.d.ts +19 -0
  136. package/src/shade/renderer/particles/ParticleRenderMode.d.ts.map +1 -0
  137. package/src/shade/renderer/particles/ParticleRenderMode.js +33 -0
  138. package/src/shade/renderer/particles/data/PARTICLE_EMITTER_STRUCT.d.ts.map +1 -1
  139. package/src/shade/renderer/particles/data/PARTICLE_EMITTER_STRUCT.js +167 -166
  140. package/src/shade/renderer/particles/data/particle_emitter_record.d.ts +37 -0
  141. package/src/shade/renderer/particles/data/particle_emitter_record.d.ts.map +1 -0
  142. package/src/shade/renderer/particles/data/particle_emitter_record.js +109 -0
  143. package/src/shade/renderer/particles/graph/ParticleGroupBuilder.d.ts +3 -3
  144. package/src/shade/renderer/particles/graph/ParticleGroupBuilder.js +303 -303
  145. package/src/shade/renderer/particles/graph/ParticleNodeDescription.d.ts +18 -0
  146. package/src/shade/renderer/particles/graph/ParticleNodeDescription.d.ts.map +1 -1
  147. package/src/shade/renderer/particles/graph/ParticleNodeDescription.js +152 -133
  148. package/src/shade/renderer/particles/graph/ParticleNodeRegistry.d.ts +0 -11
  149. package/src/shade/renderer/particles/graph/ParticleNodeRegistry.d.ts.map +1 -1
  150. package/src/shade/renderer/particles/graph/ParticleNodeRegistry.js +720 -621
  151. package/src/shade/renderer/particles/graph/compile_particle_graph.d.ts.map +1 -1
  152. package/src/shade/renderer/particles/graph/compile_particle_graph.js +8 -3
  153. package/src/shade/renderer/particles/graph/flatten_particle_graph.d.ts.map +1 -1
  154. package/src/shade/renderer/particles/graph/flatten_particle_graph.js +244 -213
  155. package/src/shade/renderer/particles/graph/groups/particle_builtin_groups.d.ts.map +1 -1
  156. package/src/shade/renderer/particles/graph/groups/particle_builtin_groups.js +6 -0
  157. package/src/shade/renderer/particles/graph/groups/particle_groups_geometry.d.ts.map +1 -1
  158. package/src/shade/renderer/particles/graph/groups/particle_groups_geometry.js +294 -319
  159. package/src/shade/renderer/particles/graph/groups/particle_groups_noise.d.ts.map +1 -1
  160. package/src/shade/renderer/particles/graph/groups/particle_groups_noise.js +524 -517
  161. package/src/shade/renderer/particles/graph/groups/particle_groups_psrdnoise.d.ts +22 -0
  162. package/src/shade/renderer/particles/graph/groups/particle_groups_psrdnoise.d.ts.map +1 -0
  163. package/src/shade/renderer/particles/graph/groups/particle_groups_psrdnoise.js +517 -0
  164. package/src/shade/renderer/particles/graph/groups/simplex_reference.d.ts.map +1 -1
  165. package/src/shade/renderer/particles/graph/groups/simplex_reference.js +185 -159
  166. package/src/shade/renderer/particles/graph/make_particle_group.d.ts.map +1 -1
  167. package/src/shade/renderer/particles/graph/make_particle_group.js +2 -20
  168. package/src/shade/renderer/particles/graph/particle_compare_ops.d.ts +17 -0
  169. package/src/shade/renderer/particles/graph/particle_compare_ops.d.ts.map +1 -0
  170. package/src/shade/renderer/particles/graph/particle_compare_ops.js +22 -0
  171. package/src/shade/renderer/particles/graph/particle_graph_diagnostic.d.ts +28 -8
  172. package/src/shade/renderer/particles/graph/particle_graph_diagnostic.d.ts.map +1 -1
  173. package/src/shade/renderer/particles/graph/particle_graph_diagnostic.js +49 -25
  174. package/src/shade/renderer/particles/graph/particle_node_parameters.d.ts +40 -0
  175. package/src/shade/renderer/particles/graph/particle_node_parameters.d.ts.map +1 -1
  176. package/src/shade/renderer/particles/graph/particle_node_parameters.js +312 -234
  177. package/src/shade/renderer/particles/graph/particle_node_presentation.d.ts.map +1 -1
  178. package/src/shade/renderer/particles/graph/particle_node_presentation.js +59 -3
  179. package/src/shade/renderer/particles/graph/particle_ramp.d.ts +230 -0
  180. package/src/shade/renderer/particles/graph/particle_ramp.d.ts.map +1 -0
  181. package/src/shade/renderer/particles/graph/particle_ramp.js +403 -0
  182. package/src/shade/renderer/particles/graph/validate_particle_graph.d.ts +7 -1
  183. package/src/shade/renderer/particles/graph/validate_particle_graph.d.ts.map +1 -1
  184. package/src/shade/renderer/particles/graph/validate_particle_graph.js +66 -10
  185. package/src/shade/renderer/particles/graph_particles.d.ts +23 -69
  186. package/src/shade/renderer/particles/graph_particles.d.ts.map +1 -1
  187. package/src/shade/renderer/particles/graph_particles.js +105 -262
  188. package/src/shade/renderer/particles/graph_particles_avboit.d.ts.map +1 -1
  189. package/src/shade/renderer/particles/graph_particles_avboit.js +3 -2
  190. package/src/shade/renderer/particles/graph_particles_billboard.d.ts +37 -0
  191. package/src/shade/renderer/particles/graph_particles_billboard.d.ts.map +1 -0
  192. package/src/shade/renderer/particles/graph_particles_billboard.js +93 -0
  193. package/src/shade/renderer/particles/isa/InstructionStream.d.ts +51 -22
  194. package/src/shade/renderer/particles/isa/InstructionStream.d.ts.map +1 -1
  195. package/src/shade/renderer/particles/isa/InstructionStream.js +98 -38
  196. package/src/shade/renderer/particles/isa/ParticleProgram.d.ts +49 -8
  197. package/src/shade/renderer/particles/isa/ParticleProgram.d.ts.map +1 -1
  198. package/src/shade/renderer/particles/isa/ParticleProgram.js +95 -150
  199. package/src/shade/renderer/particles/isa/ParticleVMISA.d.ts +306 -64
  200. package/src/shade/renderer/particles/isa/ParticleVMISA.d.ts.map +1 -1
  201. package/src/shade/renderer/particles/isa/ParticleVMISA.js +505 -136
  202. package/src/shade/renderer/particles/isa/particle_assembly.d.ts +36 -12
  203. package/src/shade/renderer/particles/isa/particle_assembly.d.ts.map +1 -1
  204. package/src/shade/renderer/particles/isa/particle_assembly.js +354 -139
  205. package/src/shade/renderer/particles/isa/validate_particle_program.d.ts +9 -0
  206. package/src/shade/renderer/particles/isa/validate_particle_program.d.ts.map +1 -0
  207. package/src/shade/renderer/particles/isa/validate_particle_program.js +128 -0
  208. package/src/shade/renderer/particles/layout/ParticleLayout.d.ts +23 -0
  209. package/src/shade/renderer/particles/layout/ParticleLayout.d.ts.map +1 -1
  210. package/src/shade/renderer/particles/layout/ParticleLayout.js +68 -0
  211. package/src/shade/renderer/particles/optimizer/dag/optimize_particle_program_vector.d.ts +77 -0
  212. package/src/shade/renderer/particles/optimizer/dag/optimize_particle_program_vector.d.ts.map +1 -0
  213. package/src/shade/renderer/particles/optimizer/dag/optimize_particle_program_vector.js +219 -0
  214. package/src/shade/renderer/particles/optimizer/dag/particle_vector_extract.d.ts +83 -0
  215. package/src/shade/renderer/particles/optimizer/dag/particle_vector_extract.d.ts.map +1 -0
  216. package/src/shade/renderer/particles/optimizer/dag/particle_vector_extract.js +283 -0
  217. package/src/shade/renderer/particles/optimizer/dag/particle_vector_graph.d.ts +133 -0
  218. package/src/shade/renderer/particles/optimizer/dag/particle_vector_graph.d.ts.map +1 -0
  219. package/src/shade/renderer/particles/optimizer/dag/particle_vector_graph.js +334 -0
  220. package/src/shade/renderer/particles/optimizer/dag/particle_vector_groups.d.ts +117 -0
  221. package/src/shade/renderer/particles/optimizer/dag/particle_vector_groups.d.ts.map +1 -0
  222. package/src/shade/renderer/particles/optimizer/dag/particle_vector_groups.js +70 -0
  223. package/src/shade/renderer/particles/optimizer/dag/particle_vector_lift.d.ts +97 -0
  224. package/src/shade/renderer/particles/optimizer/dag/particle_vector_lift.d.ts.map +1 -0
  225. package/src/shade/renderer/particles/optimizer/dag/particle_vector_lift.js +462 -0
  226. package/src/shade/renderer/particles/optimizer/dag/particle_vector_lower.d.ts +116 -0
  227. package/src/shade/renderer/particles/optimizer/dag/particle_vector_lower.d.ts.map +1 -0
  228. package/src/shade/renderer/particles/optimizer/dag/particle_vector_lower.js +687 -0
  229. package/src/shade/renderer/particles/optimizer/dag/particle_vector_pack.d.ts +57 -0
  230. package/src/shade/renderer/particles/optimizer/dag/particle_vector_pack.d.ts.map +1 -0
  231. package/src/shade/renderer/particles/optimizer/dag/particle_vector_pack.js +860 -0
  232. package/src/shade/renderer/particles/optimizer/dag/particle_vector_rules.d.ts +115 -0
  233. package/src/shade/renderer/particles/optimizer/dag/particle_vector_rules.d.ts.map +1 -0
  234. package/src/shade/renderer/particles/optimizer/dag/particle_vector_rules.js +264 -0
  235. package/src/shade/renderer/particles/optimizer/optimize_particle_program.d.ts +81 -42
  236. package/src/shade/renderer/particles/optimizer/optimize_particle_program.d.ts.map +1 -1
  237. package/src/shade/renderer/particles/optimizer/optimize_particle_program.js +477 -478
  238. package/src/shade/renderer/particles/optimizer/particle_integer_bounds.d.ts +100 -0
  239. package/src/shade/renderer/particles/optimizer/particle_integer_bounds.d.ts.map +1 -0
  240. package/src/shade/renderer/particles/optimizer/particle_integer_bounds.js +236 -0
  241. package/src/shade/renderer/particles/optimizer/particle_program_analysis.d.ts +139 -59
  242. package/src/shade/renderer/particles/optimizer/particle_program_analysis.d.ts.map +1 -1
  243. package/src/shade/renderer/particles/optimizer/particle_program_analysis.js +764 -647
  244. package/src/shade/renderer/particles/optimizer/particle_program_equivalence.d.ts +40 -7
  245. package/src/shade/renderer/particles/optimizer/particle_program_equivalence.d.ts.map +1 -1
  246. package/src/shade/renderer/particles/optimizer/particle_program_equivalence.js +376 -213
  247. package/src/shade/renderer/particles/optimizer/particle_program_fuzz.d.ts +30 -3
  248. package/src/shade/renderer/particles/optimizer/particle_program_fuzz.d.ts.map +1 -1
  249. package/src/shade/renderer/particles/optimizer/particle_program_fuzz.js +337 -223
  250. package/src/shade/renderer/particles/optimizer/particle_vm_semantics.d.ts +24 -38
  251. package/src/shade/renderer/particles/optimizer/particle_vm_semantics.d.ts.map +1 -1
  252. package/src/shade/renderer/particles/optimizer/particle_vm_semantics.js +166 -206
  253. package/src/shade/renderer/particles/optimizer/pass_allocate_registers.d.ts +99 -0
  254. package/src/shade/renderer/particles/optimizer/pass_allocate_registers.d.ts.map +1 -0
  255. package/src/shade/renderer/particles/optimizer/pass_allocate_registers.js +313 -0
  256. package/src/shade/renderer/particles/optimizer/pass_dedup_constants.d.ts +3 -2
  257. package/src/shade/renderer/particles/optimizer/pass_dedup_constants.d.ts.map +1 -1
  258. package/src/shade/renderer/particles/optimizer/pass_dedup_constants.js +198 -197
  259. package/src/shade/renderer/particles/optimizer/pass_eliminate_dead_code.d.ts.map +1 -1
  260. package/src/shade/renderer/particles/optimizer/pass_fold_constants.d.ts +19 -0
  261. package/src/shade/renderer/particles/optimizer/pass_fold_constants.d.ts.map +1 -1
  262. package/src/shade/renderer/particles/optimizer/pass_fold_constants.js +678 -561
  263. package/src/shade/renderer/particles/optimizer/pass_inline_constants.d.ts +22 -0
  264. package/src/shade/renderer/particles/optimizer/pass_inline_constants.d.ts.map +1 -0
  265. package/src/shade/renderer/particles/optimizer/pass_inline_constants.js +221 -0
  266. package/src/shade/renderer/particles/optimizer/pass_narrow_widths.d.ts.map +1 -1
  267. package/src/shade/renderer/particles/optimizer/pass_narrow_widths.js +63 -72
  268. package/src/shade/renderer/particles/optimizer/pass_pack_registers.d.ts.map +1 -1
  269. package/src/shade/renderer/particles/optimizer/pass_pack_registers.js +87 -86
  270. package/src/shade/renderer/particles/optimizer/pass_peephole.d.ts.map +1 -1
  271. package/src/shade/renderer/particles/optimizer/pass_peephole.js +392 -271
  272. package/src/shade/renderer/particles/optimizer/pass_propagate_copies.d.ts.map +1 -1
  273. package/src/shade/renderer/particles/optimizer/pass_propagate_copies.js +361 -268
  274. package/src/shade/renderer/particles/optimizer/pass_schedule.d.ts +4 -0
  275. package/src/shade/renderer/particles/optimizer/pass_schedule.d.ts.map +1 -0
  276. package/src/shade/renderer/particles/optimizer/pass_schedule.js +244 -0
  277. package/src/shade/renderer/particles/optimizer/pass_share_subexpressions.d.ts.map +1 -1
  278. package/src/shade/renderer/particles/optimizer/pass_share_subexpressions.js +154 -151
  279. package/src/shade/renderer/particles/particle_test_fixtures.d.ts +20 -0
  280. package/src/shade/renderer/particles/particle_test_fixtures.d.ts.map +1 -1
  281. package/src/shade/renderer/particles/particle_test_fixtures.js +229 -203
  282. package/src/shade/renderer/particles/runtime/EmitterRegistry.d.ts +99 -25
  283. package/src/shade/renderer/particles/runtime/EmitterRegistry.d.ts.map +1 -1
  284. package/src/shade/renderer/particles/runtime/EmitterRegistry.js +438 -286
  285. package/src/shade/renderer/particles/runtime/GPUParticleEmitterContext.d.ts +109 -0
  286. package/src/shade/renderer/particles/runtime/GPUParticleEmitterContext.d.ts.map +1 -0
  287. package/src/shade/renderer/particles/runtime/GPUParticleEmitterContext.js +127 -0
  288. package/src/shade/renderer/particles/runtime/ParticleEmitter.d.ts +87 -102
  289. package/src/shade/renderer/particles/runtime/ParticleEmitter.d.ts.map +1 -1
  290. package/src/shade/renderer/particles/runtime/ParticleEmitter.js +184 -163
  291. package/src/shade/renderer/particles/runtime/ProgramArena.d.ts +26 -0
  292. package/src/shade/renderer/particles/runtime/ProgramArena.d.ts.map +1 -1
  293. package/src/shade/renderer/particles/runtime/ProgramHeap.d.ts +130 -0
  294. package/src/shade/renderer/particles/runtime/ProgramHeap.d.ts.map +1 -0
  295. package/src/shade/renderer/particles/runtime/ProgramHeap.js +595 -0
  296. package/src/shade/renderer/particles/runtime/ProgramPlacement.d.ts +91 -0
  297. package/src/shade/renderer/particles/runtime/ProgramPlacement.d.ts.map +1 -0
  298. package/src/shade/renderer/particles/runtime/ProgramPlacement.js +106 -0
  299. package/src/shade/renderer/particles/runtime/create_particle_effect.d.ts +5 -2
  300. package/src/shade/renderer/particles/runtime/create_particle_effect.d.ts.map +1 -1
  301. package/src/shade/renderer/particles/runtime/create_particle_effect.js +22 -19
  302. package/src/shade/renderer/particles/shaders/chunk_particle_emit_step.d.ts +28 -0
  303. package/src/shade/renderer/particles/shaders/chunk_particle_emit_step.d.ts.map +1 -0
  304. package/src/shade/renderer/particles/shaders/chunk_particle_emit_step.js +136 -0
  305. package/src/shade/renderer/particles/shaders/chunk_particle_simulate_step.d.ts +35 -0
  306. package/src/shade/renderer/particles/shaders/chunk_particle_simulate_step.d.ts.map +1 -0
  307. package/src/shade/renderer/particles/shaders/chunk_particle_simulate_step.js +133 -0
  308. package/src/shade/renderer/particles/shaders/shader_particle_emit.d.ts +18 -9
  309. package/src/shade/renderer/particles/shaders/shader_particle_emit.d.ts.map +1 -1
  310. package/src/shade/renderer/particles/shaders/shader_particle_emit.js +20 -80
  311. package/src/shade/renderer/particles/shaders/shader_particle_emit_wide.d.ts +33 -0
  312. package/src/shade/renderer/particles/shaders/shader_particle_emit_wide.d.ts.map +1 -0
  313. package/src/shade/renderer/particles/shaders/shader_particle_emit_wide.js +114 -0
  314. package/src/shade/renderer/particles/shaders/shader_particle_simulate.d.ts +8 -0
  315. package/src/shade/renderer/particles/shaders/shader_particle_simulate.d.ts.map +1 -1
  316. package/src/shade/renderer/particles/shaders/shader_particle_simulate.js +33 -101
  317. package/src/shade/renderer/particles/shaders/shader_particle_simulate_wide.d.ts +45 -0
  318. package/src/shade/renderer/particles/shaders/shader_particle_simulate_wide.d.ts.map +1 -0
  319. package/src/shade/renderer/particles/shaders/shader_particle_simulate_wide.js +123 -0
  320. package/src/shade/renderer/particles/sort/graph_particle_sort.d.ts +51 -0
  321. package/src/shade/renderer/particles/sort/graph_particle_sort.d.ts.map +1 -0
  322. package/src/shade/renderer/particles/sort/graph_particle_sort.js +120 -0
  323. package/src/shade/renderer/particles/vm/PARTICLE_VM_CONTEXT_STRUCT.d.ts +6 -0
  324. package/src/shade/renderer/particles/vm/PARTICLE_VM_CONTEXT_STRUCT.d.ts.map +1 -0
  325. package/src/shade/renderer/particles/vm/PARTICLE_VM_CONTEXT_STRUCT.js +16 -0
  326. package/src/shade/renderer/particles/vm/ParticleVMReference.d.ts +4 -1
  327. package/src/shade/renderer/particles/vm/ParticleVMReference.d.ts.map +1 -1
  328. package/src/shade/renderer/particles/vm/ParticleVMReference.js +261 -140
  329. package/src/shade/renderer/particles/vm/chunk_particle_vm.d.ts.map +1 -1
  330. package/src/shade/renderer/particles/vm/chunk_particle_vm.js +217 -255
  331. package/src/shade/renderer/particles/vm/chunk_particle_vm_registers_fast.d.ts +43 -0
  332. package/src/shade/renderer/particles/vm/chunk_particle_vm_registers_fast.d.ts.map +1 -0
  333. package/src/shade/renderer/particles/vm/chunk_particle_vm_registers_fast.js +55 -0
  334. package/src/shade/renderer/particles/vm/chunk_particle_vm_registers_wide.d.ts +62 -0
  335. package/src/shade/renderer/particles/vm/chunk_particle_vm_registers_wide.d.ts.map +1 -0
  336. package/src/shade/renderer/particles/vm/chunk_particle_vm_registers_wide.js +86 -0
  337. package/src/shade/renderer/shader/chunk/math/chunk_mod_v3f.d.ts +22 -0
  338. package/src/shade/renderer/shader/chunk/math/chunk_mod_v3f.d.ts.map +1 -0
  339. package/src/shade/renderer/shader/chunk/math/chunk_mod_v3f.js +32 -0
  340. package/src/shade/renderer/shader/chunk/math/chunk_mod_v4f.d.ts +9 -0
  341. package/src/shade/renderer/shader/chunk/math/chunk_mod_v4f.d.ts.map +1 -0
  342. package/src/shade/renderer/shader/chunk/math/chunk_mod_v4f.js +19 -0
  343. package/src/shade/renderer/shader/chunk/noise/psrdnoise/README.md +65 -0
  344. package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise2.d.ts +24 -0
  345. package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise2.d.ts.map +1 -0
  346. package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise2.js +83 -0
  347. package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise2_hash.d.ts +25 -0
  348. package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise2_hash.d.ts.map +1 -0
  349. package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise2_hash.js +42 -0
  350. package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise2_kernel.d.ts +31 -0
  351. package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise2_kernel.d.ts.map +1 -0
  352. package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise2_kernel.js +80 -0
  353. package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise3.d.ts +26 -0
  354. package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise3.d.ts.map +1 -0
  355. package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise3.js +109 -0
  356. package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise3_kernel.d.ts +38 -0
  357. package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise3_kernel.d.ts.map +1 -0
  358. package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise3_kernel.js +129 -0
  359. package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise3_permute.d.ts +21 -0
  360. package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise3_permute.d.ts.map +1 -0
  361. package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise3_permute.js +35 -0
  362. package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise3_skew.d.ts +19 -0
  363. package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise3_skew.d.ts.map +1 -0
  364. package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise3_skew.js +28 -0
  365. package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise3_unskew.d.ts +13 -0
  366. package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise3_unskew.d.ts.map +1 -0
  367. package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise3_unskew.js +22 -0
  368. package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_srdnoise2.d.ts +22 -0
  369. package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_srdnoise2.d.ts.map +1 -0
  370. package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_srdnoise2.js +59 -0
  371. package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_srdnoise3.d.ts +23 -0
  372. package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_srdnoise3.d.ts.map +1 -0
  373. package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_srdnoise3.js +74 -0
  374. package/src/shade/wgsl/emulator/ComputeShaderEmulator.d.ts +34 -1
  375. package/src/shade/wgsl/emulator/ComputeShaderEmulator.d.ts.map +1 -1
  376. package/src/shade/wgsl/emulator/ComputeShaderEmulator.js +41 -1
  377. package/src/shade/wgsl/emulator/WGSLJavaScriptCompiler.d.ts +3 -2
  378. package/src/shade/wgsl/emulator/WGSLJavaScriptCompiler.d.ts.map +1 -1
  379. package/src/shade/wgsl/emulator/WGSLJavaScriptCompiler.js +49 -10
  380. package/src/view/minimap/dom/MinimapCameraView.d.ts.map +1 -1
  381. package/src/view/minimap/dom/MinimapCameraView.js +4 -9
  382. package/src/core/model/node-graph/visual/layout/BoxLayoutSpec.d.ts +0 -15
  383. package/src/core/model/node-graph/visual/layout/BoxLayoutSpec.d.ts.map +0 -1
  384. package/src/core/model/node-graph/visual/layout/ConnectedBoxLayouter.d.ts +0 -45
  385. package/src/core/model/node-graph/visual/layout/ConnectedBoxLayouter.d.ts.map +0 -1
  386. package/src/core/model/node-graph/visual/layout/ConnectionEndpointLayoutSpec.d.ts +0 -24
  387. package/src/core/model/node-graph/visual/layout/ConnectionEndpointLayoutSpec.d.ts.map +0 -1
  388. package/src/core/model/node-graph/visual/layout/ConnectionLayoutSpec.d.ts +0 -19
  389. package/src/core/model/node-graph/visual/layout/ConnectionLayoutSpec.d.ts.map +0 -1
  390. package/src/engine/ecs/transform/__probe.d.ts +0 -4
  391. package/src/engine/ecs/transform/__probe.d.ts.map +0 -1
  392. package/src/engine/ecs/util/hideEntityGracefully.d.ts +0 -9
  393. package/src/engine/ecs/util/hideEntityGracefully.d.ts.map +0 -1
  394. package/src/shade/renderer/buffer/table/gpu_database_emulator_image.d.ts +0 -27
  395. package/src/shade/renderer/buffer/table/gpu_database_emulator_image.d.ts.map +0 -1
  396. package/src/shade/renderer/particles/cull/chunk_particle_cull.d.ts +0 -14
  397. package/src/shade/renderer/particles/cull/chunk_particle_cull.d.ts.map +0 -1
  398. package/src/shade/renderer/particles/data/PARTICLE_EMITTER_LAYOUT.d.ts +0 -156
  399. package/src/shade/renderer/particles/data/PARTICLE_EMITTER_LAYOUT.d.ts.map +0 -1
  400. package/src/shade/renderer/particles/runtime/Emitter.d.ts +0 -219
  401. package/src/shade/renderer/particles/runtime/Emitter.d.ts.map +0 -1
  402. package/src/shade/renderer/particles/runtime/ParticleSpawnScheduler.d.ts +0 -77
  403. package/src/shade/renderer/particles/runtime/ParticleSpawnScheduler.d.ts.map +0 -1
  404. package/src/shade/renderer/particles/runtime/ProgramArena.js +0 -155
  405. package/src/shade/renderer/particles/runtime/emitter_database_image.d.ts +0 -15
  406. package/src/shade/renderer/particles/runtime/emitter_database_image.d.ts.map +0 -1
  407. package/src/shade/renderer/particles/runtime/spawn_request_encoding.d.ts +0 -34
  408. package/src/shade/renderer/particles/runtime/spawn_request_encoding.d.ts.map +0 -1
  409. package/src/shade/renderer/particles/shaders/chunk_particle_context.d.ts +0 -32
  410. package/src/shade/renderer/particles/shaders/chunk_particle_context.d.ts.map +0 -1
@@ -35,6 +35,20 @@ edits it at both altitudes.
35
35
  the moment it arrives. Arrow keys move the choice; Escape closes. Nodes are listed and headed by
36
36
  what they are called rather than by the mnemonic they compile as — "Divide", not `div` — each with
37
37
  the glyph its type carries; both are searched, so looking for either finds it.
38
+ - **Copy, paste, duplicate.** `Ctrl+C` takes a copy of the selected nodes and of every wire they hold
39
+ whole — a wire with one end outside the selection is not brought along, because the node it reached
40
+ is not part of what was copied. `Ctrl+V` puts it in the middle of what you are looking at, keeping
41
+ the arrangement it was copied in; a repeat paste steps aside so copies do not hide each other.
42
+ `Ctrl+D` puts a second of the selection beside it and leaves the clipboard alone. Each is one step
43
+ on the undo timeline, and what lands is what is selected afterwards, ready to be dragged where it
44
+ is wanted. One clipboard serves both phases and every group body, so a copy taken in INIT pastes in
45
+ UPDATE. It is the editor's own clipboard rather than the system one: what it holds is node types,
46
+ which only mean anything to a canvas that shares the library.
47
+ - **An input holds one wire.** Drop a second one on it and it replaces the first, in one step on the
48
+ undo timeline — the editor cannot be made to put two sources on an input. Drag *out* of an input
49
+ that already has one and you are holding that wire rather than making another: let it go on
50
+ another input to move it there, on the port it came from to leave it alone, and on open canvas to
51
+ take it off.
38
52
  - **Drop a wire on empty canvas** and the same menu opens, narrowed to the types that have a port
39
53
  which could take it — the ones with an input, when the wire came out of an output — and picking one
40
54
  wires it up as it arrives. The node and the wire are one step on the undo timeline, because they
@@ -61,8 +75,20 @@ edits it at both altitudes.
61
75
  - Node parameters are edited in the node: four fields for a vector, a swatch and an alpha field for
62
76
  a colour, a picker for an ISA enum, a picker of the effect's own attributes for an attribute
63
77
  reference, `xyzw` for a swizzle.
64
- - The strip along the bottom lists every problem with the effect, from **both** phases. Click one to
65
- jump to the phase it is in and select the node; the node is outlined in the graph too.
78
+ - Two of them are **ramps**, edited as a picture. An **RGBA Gradient** (and an RGB one) is a strip of
79
+ the colour it produces with its stops underneath: drag a stop, click the lane to add one — in the
80
+ colour the gradient already is there, so adding never changes anything — and middle-click to remove.
81
+ A **Curve** is the unit square with its keys in it, and the picker under it decides the selected
82
+ key's tangents. Neither is sampled from a table at runtime: both are written out into the program as
83
+ arithmetic, which is what the **Code** tab shows. `Curve Table`, which *is* the table, is the other
84
+ node — it takes a row handle rather than a curve.
85
+ - The strip along the bottom lists every problem with the effect, from **both** phases, loudest
86
+ first. Click one to jump to the phase it is in and select the node; the node is outlined in the
87
+ graph too.
88
+ - **A node nothing reads is not a problem.** Only what reaches a sink is compiled, so half-built work
89
+ sitting next to a working graph cannot break it: such a node is dimmed, noted once at the bottom of
90
+ the strip, and nothing else found against it — an unbound input, a mistyped value — is reported at
91
+ all. The strip still says there are no problems, because there are none.
66
92
 
67
93
  **Code** is the same effect as instructions.
68
94
 
@@ -106,14 +132,27 @@ be gone exactly when it is wanted.
106
132
  and the preview carries on with the last good program.
107
133
  - Add an attribute in the inspector, then bind a render channel to it. Remove one that a channel was
108
134
  bound to: the channel unbinds, and every node that named it is reported against the node.
135
+ - Drag the wire out of a bound input and drop it on the input below. It moves, rather than being
136
+ copied — and `Ctrl+Z` puts it back in one go. Drag it out again and let go over open canvas: it is
137
+ gone, and the menu opens offering what could take the value it was carrying.
109
138
  - Drag a wire out of an output and let go over open canvas. Only the nodes that could take it are
110
139
  offered; pick one and it arrives already wired.
111
140
  - Drag a box around the four or five nodes that build the initial direction and press `Ctrl+G`. The graph gets
112
141
  smaller and the program does not change at all — check it in **Code**. Open the group, rename it in
113
142
  the breadcrumb, and watch the node on the canvas behind it change with it.
143
+ - Select the two or three nodes that make the initial speed, press `Ctrl+D`, and drag the copy
144
+ somewhere. Then `Ctrl+C`, switch to **UPDATE**, and `Ctrl+V`: the same nodes, wired the same way, in
145
+ the other phase. `Ctrl+Z` takes the whole paste back in one go.
114
146
  - Add a `Simplex Noise 3D` and open it. Three hundred instructions of arithmetic, drawn — and read
115
147
  only, because it is one of the library's own. `Curl Noise 4D` is twelve of those; the **Code** tab
116
148
  is where to see what that means.
149
+ - Add a `Flow Noise 3D` instead and wire `alpha` to the elapsed time. It is the same kind of field
150
+ with two differences worth the instructions: its gradients turn as `alpha` moves, so the field
151
+ swirls in place rather than sliding past, and it hands back its own derivative alongside the value.
152
+ `Tiling Flow Noise 3D` is that with a period you can name, per axis.
153
+ - Drop an `RGBA Gradient` on a `Write Attribute` bound to `color`, wire `t` to the particle's
154
+ normalised age, and drag the stops while the preview runs. Then look at **Code**: the gradient is a
155
+ literal, a saturate and a multiply-add per stop, and there is no table anywhere.
117
156
  - Set **blend** to `alpha` and back to `additive`. The preview composites accordingly.
118
157
  - `Ctrl+Z` in the graph. Every edit — a wire, a move, a parameter, a node from the menu — is one
119
158
  timeline.
@@ -150,6 +189,8 @@ used only here:
150
189
  | making one out of a selection | `src/shade/renderer/particles/graph/make_particle_group.js` |
151
190
  | a group in a file | `src/shade/renderer/particles/graph/particle_group_json.js` |
152
191
  | the groups the editor ships with | `src/shade/renderer/particles/graph/groups/` |
192
+ | a gradient and a curve, and the arithmetic they become | `src/shade/renderer/particles/graph/particle_ramp.js` |
193
+ | the controls those two are edited with | `editor/view/particles/effect/ParticleGradientEditorView.js`, `ParticleCurveEditorView.js` |
153
194
  | code layer | `editor/view/particles/effect/ParticleCodeEditorView.js` |
154
195
  | emitter + attributes | `editor/view/particles/effect/ParticleEmitterInspectorView.js` |
155
196
  | preview | `editor/view/particles/effect/ParticlePreviewView.js` |
@@ -1 +1 @@
1
- {"version":3,"file":"particle_prototype.d.ts","sourceRoot":"","sources":["../../../../../src/shade/playground/particle_system/particle_prototype.js"],"names":[],"mappings":"AAYA;;;;;;;;;;;;;;GAcG;AAEH;;;;;;;;;GASG;AACH;IAL4B,UAAU,GAA3B,MAAM;IACW,WAAW,GAA5B,MAAM;IACW,eAAe,GAAhC,MAAM;;YACK,cAAc;YAAU,MAAM;aAAW,MAAM;EAgHpE;AAED;;;;GAIG;AACH;YAFsB,cAAc;YAAU,MAAM;aAAW,MAAM;EAcpE;AAED;;;;;;;;;;;;;GAaG;AACH,yCANW,OAAO,+BAA+B,EAAE,KAAK;IAEa,IAAI,GAA9D,OAAO,gCAAgC,EAAE,MAAM;;UAEtC,eAAe;WAAS,eAAe;EAe1D;+BA5L8B,mDAAmD;gCAElD,qDAAqD"}
1
+ {"version":3,"file":"particle_prototype.d.ts","sourceRoot":"","sources":["../../../../../src/shade/playground/particle_system/particle_prototype.js"],"names":[],"mappings":"AAYA;;;;;;;;;;;;;;GAcG;AAEH;;;;;;;;;GASG;AACH;IAL4B,UAAU,GAA3B,MAAM;IACW,WAAW,GAA5B,MAAM;IACW,eAAe,GAAhC,MAAM;;YACK,cAAc;YAAU,MAAM;aAAW,MAAM;EAgHpE;AAED;;;;GAIG;AACH;YAFsB,cAAc;YAAU,MAAM;aAAW,MAAM;EAapE;AAED;;;;;;;;;;;;;GAaG;AACH,yCANW,OAAO,+BAA+B,EAAE,KAAK;IAEa,IAAI,GAA9D,OAAO,gCAAgC,EAAE,MAAM;;UAEtC,eAAe;WAAS,eAAe;EAe1D;+BA3L8B,mDAAmD;gCAElD,qDAAqD"}
@@ -135,13 +135,13 @@ export function fire_effect({ size_curve, alpha_curve, flipbook_frames = 16 } =
135
135
  const effect = create_particle_effect({ layout, init, update });
136
136
 
137
137
  const emitter = {
138
- effect,
138
+ ...effect,
139
139
  spawn_rate: 120,
140
140
  flags: { blend: EMITTER_BLEND.ADDITIVE, projection: EMITTER_PROJECTION.BILLBOARD },
141
141
  render: { position: "position", size: "size", color: "color", frame: "frame" },
142
142
  bounds: { center: [0, 1.5, 0], radius: 2.5 },
143
- // A 4x4 flipbook packed as the whole atlas here; a real atlas would use a sub-rect.
144
- atlas_region: [0, 0, 1, 1],
143
+ // No texture, so the flipbook runs over the default atlas — one white texel, read as a
144
+ // 4x4 grid of it. A real effect names an image and the system packs it.
145
145
  flipbook: [4, 4],
146
146
  };
147
147
 
@@ -156,12 +156,11 @@ export function fire_effect({ size_curve, alpha_curve, flipbook_frames = 16 } =
156
156
  export function smoke_effect() {
157
157
  const { layout, effect } = fire_effect({ flipbook_frames: 8 });
158
158
  const emitter = {
159
- effect,
159
+ ...effect,
160
160
  spawn_rate: 25,
161
161
  flags: { blend: EMITTER_BLEND.ALPHA, projection: EMITTER_PROJECTION.BILLBOARD, soft_depth: true, lighting: true, sort: true },
162
162
  render: { position: "position", size: "size", color: "color", frame: "frame" },
163
163
  bounds: { center: [0, 3, 0], radius: 5 },
164
- atlas_region: [0, 0, 1, 1],
165
164
  flipbook: [1, 1],
166
165
  };
167
166
  return { layout, effect, emitter };
@@ -115,7 +115,7 @@ export function create_particle_emitters() {
115
115
  // smoke — alpha, soft-depth, a rising column above the fire
116
116
  const smoke = ParticleEmitter.from({
117
117
  name: "smoke",
118
- effect: make_effect(PARTICLE_EMITTER_MOTION.smoke),
118
+ ...make_effect(PARTICLE_EMITTER_MOTION.smoke),
119
119
  spawn_rate: 60,
120
120
  flags: { blend: EMITTER_BLEND.ALPHA, projection: EMITTER_PROJECTION.BILLBOARD, soft_depth: true },
121
121
  render: { position: "position", size: "size", color: "color" },
@@ -127,7 +127,7 @@ export function create_particle_emitters() {
127
127
  // sparks — additive, velocity-stretched, fast, short-lived, under gravity, by the block
128
128
  const sparks = ParticleEmitter.from({
129
129
  name: "sparks",
130
- effect: make_effect(PARTICLE_EMITTER_MOTION.sparks),
130
+ ...make_effect(PARTICLE_EMITTER_MOTION.sparks),
131
131
  spawn_rate: 350,
132
132
  flags: { blend: EMITTER_BLEND.ADDITIVE, projection: EMITTER_PROJECTION.STRETCHED },
133
133
  render: { position: "position", size: "size", color: "color", velocity: "velocity" },
@@ -139,7 +139,7 @@ export function create_particle_emitters() {
139
139
  // dust — alpha, soft-depth, a slow wide drift across the ground
140
140
  const dust = ParticleEmitter.from({
141
141
  name: "dust",
142
- effect: make_effect(PARTICLE_EMITTER_MOTION.dust),
142
+ ...make_effect(PARTICLE_EMITTER_MOTION.dust),
143
143
  spawn_rate: 120,
144
144
  flags: { blend: EMITTER_BLEND.ALPHA, projection: EMITTER_PROJECTION.BILLBOARD, soft_depth: true },
145
145
  render: { position: "position", size: "size", color: "color" },
@@ -155,7 +155,7 @@ export function create_particle_emitters() {
155
155
 
156
156
  const torch = ParticleEmitter.from({
157
157
  name: "torch",
158
- effect: make_effect(PARTICLE_EMITTER_MOTION.torch),
158
+ ...make_effect(PARTICLE_EMITTER_MOTION.torch),
159
159
  spawn_rate: 200,
160
160
  flags: { blend: EMITTER_BLEND.ADDITIVE, projection: EMITTER_PROJECTION.BILLBOARD },
161
161
  render: { position: "position", size: "size", color: "color" },
@@ -1 +1 @@
1
- {"version":3,"file":"Renderer.d.ts","sourceRoot":"","sources":["../../../../src/shade/renderer/Renderer.js"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"Renderer.d.ts","sourceRoot":"","sources":["../../../../src/shade/renderer/Renderer.js"],"names":[],"mappings":"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"}
@@ -67,6 +67,7 @@ import { RasterizationJob } from "./rasterize/RasterizationJob.js";
67
67
  import { graph_rasterize_scene } from "./rasterize/standard/graph_rasterize_scene.js";
68
68
  import { ReSTIRDI } from "./restir/di/ReSTIRDI.js";
69
69
  import { GPUParticleSystem } from "./particles/GPUParticleSystem.js";
70
+ import { ParticleRenderMode } from "./particles/ParticleRenderMode.js";
70
71
  import { SceneManager } from "./scene/SceneManager.js";
71
72
  import { ShadeIndirectLightingMode } from "./ShadeIndirectLightingMode.js";
72
73
  import { ShadeTransparencyMode } from "./ShadeTransparencyMode.js";
@@ -2329,11 +2330,22 @@ export class Renderer {
2329
2330
  if (this.feature_particles_enabled) {
2330
2331
  const particles = this.particles(scene_ctx);
2331
2332
 
2332
- particles.simulate({
2333
+ // The simulation runs here; the drawing is the side channels', below. AVBOIT mode is
2334
+ // what says so: the colour comes back untouched, no sort is recorded, and none of the
2335
+ // sort's scratch is ever allocated, because the accumulators it would feed are sums.
2336
+ //
2337
+ // Not conditional on {@link transparency_mode}. MBOIT has no particle channel, so under
2338
+ // it the particles simulate and are not drawn — the same as before this was a mode, and
2339
+ // the `ShadeTransparencyMode` docs say why the legacy path stays as it is. Giving MBOIT
2340
+ // `BILLBOARD` here would draw them, but over the transparency composite rather than
2341
+ // through it, which is a worse picture than none.
2342
+ current_color_out = particles.execute({
2333
2343
  graph,
2334
2344
  camera: gr_buffer_camera_current,
2335
2345
  scene_database: gr_scene_database_for_velocity,
2346
+ color: current_color_out,
2336
2347
  dt: time_delta_seconds,
2348
+ mode: ParticleRenderMode.AVBOIT,
2337
2349
  });
2338
2350
 
2339
2351
  particle_side_channels.push(particles);
@@ -33,7 +33,7 @@ authoring: NodeGraph (nodes+ports) ──compile──▶ Program (bytec
33
33
  standard node library │
34
34
  ▼
35
35
  runtime CPU: ParticleEmitter (a Node3D) ── Scene ──▶ GPUSceneContext (transforms table)
36
- EmitterRegistry ── GPUDatabase(emitters + emitter_state) ─┤ ProgramArena ([header][constants][code])
36
+ EmitterRegistry ── GPUDatabase(emitters + emitter_state) ─┤ ProgramHeap ([header][constants][code])
37
37
  GPUParticleSystem (owns every buffer, records the frame)
38
38
  ▼
39
39
  runtime GPU: particle pool (array<u32>, uniform stride) + alive/dead lists + counters
@@ -128,8 +128,10 @@ A compute stage gets eight storage buffers by default, and the design does not a
128
128
  things keep every pass under it: the emitter record and the GPU-owned state are two tables of one
129
129
  database buffer, read through one binding; and the VM's constants and code are one packed buffer —
130
130
  `[header][constants][code]`, the header's first word saying where the code starts
131
- (`ParticleConstants.PARTICLE_PROGRAM_HEADER_WORDS`). Emit and simulate bind exactly eight;
132
- `particle_shaders_wgsl_validity.spec` pins the count for every pass.
131
+ (`ParticleConstants.PARTICLE_PROGRAM_HEADER_WORDS`). Emit and simulate bind exactly eight; their
132
+ wide-register variants bind nine, which is the one place the system spends past the default and is
133
+ still inside the ten the engine demands of an adapter. `particle_shaders_wgsl_validity.spec` pins
134
+ the count for every pass.
133
135
 
134
136
  ### The VM (`ParticleVM`)
135
137
 
@@ -137,9 +139,20 @@ Register machine, emulator-safe (bounded instruction loop + big `switch`, no sub
137
139
  recursion, no data-dependent jumps — conditionals are predicated via CMP/SELECT, destruction via
138
140
  `KILL`).
139
141
 
140
- - Register file: `array<vec4f, REG_COUNT>` (default 16). Scalars use `.x`; vectors use `.xyz(w)`.
141
- - Instruction: fixed **5×u32** words `[op, dst, s0, s1, s2]`. Operand meaning is per-opcode
142
- (register index / const-pool index / attribute word-offset+comp / curve handle / builtin id).
142
+ - Register file: `array<f32>`, a register being one slot and a value of width *w* occupying *w*
143
+ consecutive ones. The interpreter reaches it through `vm_reg_read` / `vm_reg_write`, which a
144
+ **backing chunk** supplies, and the two backings are the two interpreters:
145
+ `vm/chunk_particle_vm_registers_fast.js` puts the file in `var<private>`
146
+ (`PARTICLE_VM_FAST_REGISTER_SLOTS`, dynamically indexed, so its size is the shader's register
147
+ footprint), and `vm/chunk_particle_vm_registers_wide.js` puts it in a storage buffer
148
+ (`PARTICLE_VM_REGISTER_SLOTS` — every slot an 8-bit operand base can name). See **Two
149
+ interpreters** below.
150
+ - Instruction: fixed **4×u32** words `[op | width << 8 | kinds << 16 | dst << 24, s0, s1, s2]`.
151
+ Word 0 packs the opcode (bits 0..7), the lane count (8..10), each source's `VM_KIND` (two bits per
152
+ slot at 16..21) and the destination slot (24..31). A source word means what its kind says: `REG`
153
+ is a base slot plus a swizzle, `IMM` is an `f32` bit pattern read in every lane, and `NONE` is a
154
+ raw field the opcode reads for itself (attribute word-offset+comp / curve handle / builtin id /
155
+ pool index).
143
156
  - Constant pool: `array<vec4f>` per program, referenced by `LOAD_CONST`.
144
157
  - Two entry sections per program: **INIT** and **UPDATE** (offsets in the emitter record). INIT
145
158
  gives an already-allocated record its state; it has no say in whether the particle exists.
@@ -149,6 +162,35 @@ recursion, no data-dependent jumps — conditionals are predicated via CMP/SELEC
149
162
  - `CURVE dst, handle, s0`: `dst.x = animation_curve_evaluate(curves[handle], s0.x)` — reuses the
150
163
  engine's GPU AnimationCurve chunk + database.
151
164
 
165
+ #### Two interpreters
166
+
167
+ The register file normally lives in shader registers, which is what makes it fast and what makes it
168
+ small. An effect whose compiled program wants more slots than it holds is not an error and not an
169
+ authoring ceiling: the whole system swaps emit and simulate for variants whose file is a storage
170
+ buffer, and everything runs, slowly.
171
+
172
+ - **The trigger is the set, not the program.** `ProgramHeap` reports `max_register_count` over the
173
+ programs it holds, and `GPUParticleSystem` is where that number is compared against
174
+ `PARTICLE_VM_FAST_REGISTER_SLOTS` — the store has no opinion about what a register budget means,
175
+ and which backing a pass is compiled against is the VM's business. One hungry effect moves every
176
+ emitter onto the wide pair; there is one pipeline per pass and it is chosen once, per frame, in
177
+ `graph_particles`. It moves back when that effect is unregistered: the heap knows what it holds,
178
+ so the number is a maximum over the live set rather than a high-water mark.
179
+ - **The launch is bounded.** The wide passes need a register file per invocation in flight, so they
180
+ do not run one lane per particle — that would size the buffer by pool capacity. They launch
181
+ `PARTICLE_VM_WIDE_LAUNCH_LANES` lanes whatever the workload and walk their input with a grid-stride
182
+ loop, so the file is `LANES * SLOTS * 4` bytes and nothing else. The stride is a whole number of
183
+ workgroups, which is what keeps a wave inside one coherence bucket and the wave-uniform section
184
+ decode sound.
185
+ - **Slot-major, and never cleared.** `vm_registers[slot * LANES + lane]`, so a wave reading one slot
186
+ reads a coalesced run. The buffer is transient and no pass zeroes it: a register is undefined until
187
+ written, and a program that reads one first is corrupt. That is the one place the two backings are
188
+ not interchangeable — the fast file zeroes, so the reference executor and the fast VM agree on a
189
+ value the wide VM has no opinion about.
190
+ - **Held to the same bar.** `vm/chunk_particle_vm.spec.js` runs every parity case, fuzz included,
191
+ against BOTH backings; `shaders/particle_wide_register_passes.spec.js` runs the wide passes against
192
+ the fast ones under the emulator and exercises the grid-stride loop.
193
+
152
194
  **Parity strategy.** The opcode numbers + operand semantics live in one source of truth
153
195
  (`isa/ParticleVMISA.js`). Two executors implement it: a JS reference VM (`vm/ParticleVMReference.js`)
154
196
  and a hand-written WGSL interpreter (`vm/chunk_particle_vm.js`). A spec runs identical programs
@@ -180,13 +222,34 @@ per-frame transform copy, and an emitter under a GPU-animated joint follows it
180
222
  CPU-side copy of `transform_global` could not do, since the CPU never updates that matrix for a
181
223
  node the GPU owns.
182
224
 
225
+ **The node knows nothing about the GPU.** A `ParticleEmitter` is a transform, an attribute
226
+ `layout`, a compiled `program`, a `texture` URL, and the emission parameters — all of it the
227
+ author's, all of it meaning the same thing with no device present, all of it what a saved effect is
228
+ made of. Everything the system assigns is a `GPUParticleEmitterContext`, held by the
229
+ `EmitterRegistry` against the emitter and reached through `registry.context(emitter)`: the table
230
+ row, the generation, the program placement, the node's `transforms` row, the atlas patch. So an
231
+ emitter cannot be saved with a row in it, cannot be given one by hand, and "is this emitter live?"
232
+ is asked of the registry rather than read off a `-1` that anything could have written. The record
233
+ writer is where the two meet — `write_emitter_record(record, emitter, context)`, next to the struct
234
+ it fills.
235
+
236
+ Restaging is driven by `Node3D#version`, the node's own change counter, which the renderer already
237
+ reads to decide whether a transform needs re-uploading; the context remembers the version its row
238
+ was staged from. An author who edits an emitter says so the way they say it for any node —
239
+ `needsUpdate = true` — and there is no second flag to forget. A change to the context itself (a
240
+ `transforms` row, a repacked atlas patch) moves no version, so the context marks itself instead.
241
+
183
242
  ### Emitter table (`GPUDatabase`)
184
243
 
185
244
  One `emitters` table (CPU-managed, low churn). Row = `PARTICLE_EMITTER_STRUCT`: program
186
245
  offsets+lengths, constant-pool offset, seed, spawn rate, **node** (transforms row), **generation**,
187
246
  bounds sphere, flags (lighting/soft/sort/cull/blend/projection), render binding (attr offsets for
188
- position/size/color/rotation/frame/velocity), atlas region + flipbook grid, and the dense program id
189
- the coherence pass buckets on. Programs+constants live in a packed `ProgramArena` buffer
247
+ position/size/color/rotation/frame/velocity), atlas region + flipbook grid, and the program id
248
+ the coherence pass buckets on. The atlas region is resolved, not authored: the emitter names an
249
+ image and the system packs it, the way `ShaderManager` packs the old engine's sprites, so a repack
250
+ moves every patch without any emitter changing. The seed is resolved too — an emitter left at 0 gets
251
+ its registration's generation, which no other emitter of the registry shares, rather than being
252
+ written to. Programs+constants live in a packed `ProgramHeap` buffer
190
253
  (variable length → not a fixed-stride table).
191
254
 
192
255
  The struct is the ONLY statement of that layout. The JS writer is the database's
@@ -209,11 +272,26 @@ or a later tenant's — so a hard removal frees the emitter's particles within a
209
272
  row cannot adopt a stranger's. Graceful retirement (rate to zero, remove once the tail has died)
210
273
  remains an author's choice rather than a correctness rule.
211
274
 
212
- Programs are the exception: the arena is append-only and content-deduplicated, and removing an
213
- emitter does not reclaim its program. The dense `program_id`s are baked into every other emitter's
214
- record, so compacting them would mean rewriting the whole table to recover a few hundred words.
215
- The consequence to know about is that `bucketCount()` only ever grows, and the simulation-order
216
- buffers are sized from it — which the system does itself.
275
+ **Programs are edited the same way.** `ProgramHeap` is a pair of range allocators
276
+ (`OffsetAllocator`) over the two sections of the packed buffer, keyed by a `HashMap` on the bytecode
277
+ itself — `ParticleProgram` answers `equals`/`hash`, so content deduplication is the map's doing
278
+ rather than a stringified key's. `acquire` takes a reference and `release` gives one back, so the
279
+ last emitter of an effect is what unpacks it, and `EmitterRegistry.set_program` swaps an emitter onto
280
+ different bytecode while it is live. What makes that possible is that a program is **relocatable**:
281
+ instructions carry no absolute addresses and constant references are program-local, so the heap can
282
+ move one by copying its words and rewriting the placement.
283
+
284
+ Two things are deliberately NOT reclaimed. **Program ids** are reused rather than renumbered — they
285
+ are baked into every emitter record, so compacting them would mean rewriting the whole table — and
286
+ `bucketCount()` is sized from the id capacity, the set's peak, so it does not move every time an
287
+ effect comes or goes. An id below the peak with nothing in it is an empty bin, which rounds up to
288
+ zero workgroups and shifts nothing after it. **Section capacity** only rises: a repack (which happens
289
+ when a section has no contiguous run long enough) compacts what is live and grows only if it must,
290
+ so a set that peaked at a hundred effects does not pay for a resize every time it returns to three.
291
+
292
+ A repack is the one change no emitter announces, since it is not an edit to any of them.
293
+ `EmitterRegistry.flush` asks the heap once per frame — `placement_version` — and restages every row
294
+ when it has moved.
217
295
 
218
296
  Every row of a frame is staged through one module-static record (`EmitterRegistry`), so a flush
219
297
  allocates nothing however many rows it restages.
@@ -247,8 +325,8 @@ unit, branch the opcode switch on a scalar and index the register file through M
247
325
  waterfall. A wave holding two programs would run one over the other's particles, so the coherence
248
326
  pass is part of simulate's correctness. Emit keeps a per-lane decode: its waves span emitters.
249
327
 
250
- The bucket key is the **program**, not the emitter: `ProgramArena` deduplicates by content and hands
251
- back a dense `program_id` the emitter record carries, so emitters compiled from the same graph share
328
+ The bucket key is the **program**, not the emitter: `ProgramHeap` deduplicates by content and hands
329
+ back a `program_id` the emitter record carries, so emitters compiled from the same graph share
252
330
  one bucket. Each bucket is padded out to `PARTICLE_SIMULATE_WORKGROUP_SIZE` (64 — a multiple of both
253
331
  plausible subgroup widths, so no shader needs to query `subgroup_size`), which is what makes the
254
332
  grouping hold at wave granularity: an unpadded boundary lands mid-wave and that wave spans two
@@ -345,12 +423,17 @@ src/shade/renderer/particles/
345
423
  isa/ParticleAssembler.js tiny assembler (build programs in tests/library)
346
424
  vm/ParticleVMReference.js JS reference executor
347
425
  vm/chunk_particle_vm.js WGSL interpreter CodeChunk (parity target)
426
+ vm/chunk_particle_vm_registers_fast.js register file in var<private> — the interpreter that runs
427
+ vm/chunk_particle_vm_registers_wide.js register file in storage — the fallback
428
+ shaders/chunk_particle_simulate_step.js one particle's simulate, shared by both simulate shaders
429
+ shaders/chunk_particle_emit_step.js one newborn's emit, shared by both emit shaders
348
430
  graph/ParticleNodeDescription.js node type base (ports + lowering)
349
431
  graph/ParticleNodeRegistry.js standard node library (a NodeRegistry)
350
432
  graph/particle_graph_authoring.js authoring sugar over core/model/node-graph
351
433
  graph/compile_particle_graph.js graph → Program (register alloc, const intern)
352
434
  layout/ParticleLayout.js attribute schema ↔ record word offsets
353
435
  data/PARTICLE_EMITTER_STRUCT.js the emitter row + flag/blend/projection encoding
436
+ data/particle_emitter_record.js emitter + context -> one row of that struct
354
437
  data/PARTICLE_EMITTER_STATE.js the GPU-owned per-emitter state row (second table of the database)
355
438
  data/PARTICLE_DATABASE_SPEC.js the GPUDatabase schema, and the emitter table's descriptor
356
439
  data/PARTICLE_COUNTERS.js counter slot indices
@@ -358,9 +441,11 @@ src/shade/renderer/particles/
358
441
  coherence/particle_program_buckets.js CPU reference for the simulation-order bucketing
359
442
  coherence/shader_particle_bucket.js reset / histogram / pad / scatter / fill
360
443
  coherence/graph_particle_bucket.js frame-graph wiring, around graph_prefix_scan_csdldf
361
- runtime/ProgramArena.js the one packed [header][constants][code] buffer
362
- runtime/ParticleEmitter.js one emitter — a Node3D, and the CPU model of one table row
363
- runtime/EmitterRegistry.js GPUDatabase(emitters) + the live emitters + the arena
444
+ runtime/ProgramHeap.js the one packed [header][constants][code] buffer, allocator-backed
445
+ runtime/ProgramPlacement.js where one program sits in it — what an emitter record carries
446
+ runtime/ParticleEmitter.js one emitter — a Node3D and an effect, with no GPU in it
447
+ runtime/GPUParticleEmitterContext.js what a registry assigns one: row, generation, placement, patch
448
+ runtime/EmitterRegistry.js GPUDatabase(emitters) + the live emitters + their contexts + the program heap
364
449
  runtime/create_particle_effect.js layout + INIT/UPDATE graphs → compiled effect
365
450
  shaders/shader_particle_spawn_commands.js CPU bursts → pending spawns
366
451
  shaders/shader_particle_emitter_tick.js per-emitter spawn decision
@@ -384,7 +469,7 @@ src/shade/renderer/particles/
384
469
 
385
470
  ## Testing
386
471
 
387
- - Pure JS: layout packing, assembler, register allocator, node compiler, arena/emitter/registry
472
+ - Pure JS: layout packing, assembler, register allocator, node compiler, heap/emitter/registry
388
473
  bookkeeping (via `SoftwareGPUDevice`), the header encoding.
389
474
  - WGSL via emulator: VM opcode parity (JS vs WGSL), curve sampling, sort key/depth, atlas+flipbook
390
475
  UV math, billboard expansion, soft-depth fade, and every compute pass on small fixtures — the tick
@@ -6,16 +6,29 @@
6
6
  * ## What it owns
7
7
  *
8
8
  * Every piece of persistent GPU state: the particle pool, the ping-pong alive lists, the dead
9
- * free-list, the counters, both indirect-args buffers, the simulation-order (coherence) and
10
- * render-order (sort) scratch, the emitter database (the emitter table and the GPU-owned state
11
- * table, one buffer), the packed program buffer, and the spawn-command ring. Buffers that depend
12
- * on the emitter set — the coherence scratch on the number of distinct programs, the program
13
- * buffer on the arena, the database on its own pages — are grown inside {@link execute}, the way
14
- * ReSTIR's reservoirs follow the resolution.
9
+ * free-list, the counters, both indirect-args buffers, the simulation-order (coherence) scratch,
10
+ * the emitter database (the emitter table and the GPU-owned state table, one buffer), the packed
11
+ * program buffer, and the spawn-command ring. Buffers that depend on the emitter set — the
12
+ * coherence scratch on the number of distinct programs, the program buffer on the heap, the
13
+ * database on its own pages — are grown inside {@link execute}, the way ReSTIR's reservoirs follow
14
+ * the resolution. The render-order (sort) scratch is not in that list because it is not
15
+ * unconditional: see below.
15
16
  *
16
17
  * Every pass stays within the eight storage buffers a stage gets by default: the emitter record
17
18
  * and the GPU-owned state are two tables of one database buffer, and the VM's constants and code
18
- * are one packed buffer.
19
+ * are one packed buffer. The one exception is the wide-register fallback (below), whose emit and
20
+ * simulate passes bind a ninth for the register file — inside the ten the engine already demands of
21
+ * an adapter, but past the default.
22
+ *
23
+ * ## Two interpreters
24
+ *
25
+ * The VM's register file normally lives in shader registers, and is therefore small — see
26
+ * {@link ./ParticleConstants.js PARTICLE_VM_FAST_REGISTER_SLOTS}. An effect whose compiled program
27
+ * needs more than it holds does not fail: the whole system swaps emit and simulate for variants
28
+ * that keep the file in a storage buffer, which is far slower and effectively unbounded. The choice
29
+ * is per-frame, whole-system, and made here — the registry reports `max_register_count` over the
30
+ * effects it holds and this is where that number meets the VM's; nothing about authoring a graph has
31
+ * a register ceiling.
19
32
  *
20
33
  * ## Emitters are scene nodes
21
34
  *
@@ -34,15 +47,20 @@
34
47
  * command list that a pass adds to the emitter's pending spawns, on the same path as everything
35
48
  * else. See `graph_particles.js` for the frame.
36
49
  *
37
- * ## Drawing
50
+ * ## Drawing, and the one thing the mode changes
38
51
  *
39
- * {@link simulate} records everything that moves particles and leaves the alive list and the
40
- * indirect draw args as graph handles. Two things draw them. Under the renderer the system is an
41
- * `AVBOITSideChannel`: the transparency orchestrator asks it for its occupancy, its extinction and
42
- * its draw at the three points where the transparent meshes have contributed theirs
43
- * ({@link avboit_occupancy}, {@link avboit_splat}, {@link avboit_draw}), and the particles
44
- * composite order-independently with them. A page without that pipeline calls {@link execute},
45
- * which sorts and draws the billboards straight over a colour target.
52
+ * {@link execute} is the whole per-frame call, once per frame. It always records everything that
53
+ * moves particles and leaves the alive list and the indirect draw args as graph handles; what it
54
+ * records after that is the {@link ParticleRenderMode} it was given.
55
+ *
56
+ * `BILLBOARD` sorts the alive list back-to-front and draws it over a colour target, because
57
+ * premultiplied over-blending is order-dependent. `AVBOIT` records neither: under the renderer the
58
+ * system is an `AVBOITSideChannel`, and the transparency orchestrator asks it for its occupancy, its
59
+ * extinction and its draw at the three points where the transparent meshes have contributed theirs
60
+ * ({@link avboit_occupancy}, {@link avboit_splat}, {@link avboit_draw}). Those read the same handles
61
+ * and composite into a volume and a set of accumulators that are sums, so an ordering would buy
62
+ * nothing — and the sort is four passes and a scan over every live particle, plus two lists a word
63
+ * per particle each, which is why the mode also decides whether those buffers exist at all.
46
64
  *
47
65
  * ## Allocation
48
66
  *
@@ -99,7 +117,7 @@ export class GPUParticleSystem {
99
117
  max_catchup_seconds: number;
100
118
  /**
101
119
  * View-depth range the render sort quantises: particles nearer than `[0]` share the front bin,
102
- * farther than `[1]` the back one.
120
+ * farther than `[1]` the back one. Read only by {@link ParticleRenderMode.BILLBOARD}.
103
121
  * @type {Float32Array}
104
122
  */
105
123
  sort_depth_range: Float32Array;
@@ -112,7 +130,7 @@ export class GPUParticleSystem {
112
130
  /** @type {GPUSampler} */
113
131
  atlas_sampler: GPUSampler;
114
132
  /**
115
- * The persistent GPU buffers, by the names {@link graph_particles} binds them under. Exposed for
133
+ * The persistent GPU buffers, by the names the graph functions bind them under. Exposed for
116
134
  * inspection — a harness copying the counters out to display them — never for the frame loop,
117
135
  * which reads nothing back. Entries that grow with the emitter set are replaced in place.
118
136
  *
@@ -130,11 +148,15 @@ export class GPUParticleSystem {
130
148
  */
131
149
  get emitters(): import("./runtime/ParticleEmitter.js").ParticleEmitter[];
132
150
  /**
133
- * Number of simulation-order buckets — one per distinct compiled program.
151
+ * Number of simulation-order buckets — one per program id the registry can hand out, which is
152
+ * its peak number of distinct compiled programs rather than its current one.
134
153
  *
135
154
  * This is the coherence pass's only host-provided number, and it is static topology rather than
136
- * per-frame state: it changes when a new effect is registered, not as particles are born and
137
- * die. Everything the pass measures per frame stays on the GPU.
155
+ * per-frame state: it changes when an effect the set has never held is registered, not as
156
+ * particles are born and die. Everything the pass measures per frame stays on the GPU. Sizing it
157
+ * from the peak rather than the live count is what keeps it from moving every time an effect is
158
+ * unregistered — the bins of released ids are empty, and an empty bin rounds up to zero
159
+ * workgroups and shifts nothing after it.
138
160
  *
139
161
  * @returns {number}
140
162
  */
@@ -154,11 +176,16 @@ export class GPUParticleSystem {
154
176
  */
155
177
  spawn(emitter: import("./runtime/ParticleEmitter.js").ParticleEmitter, count: number): void;
156
178
  /**
157
- * The simulation half of the frame: reconcile the emitter set with the scene, push what changed
158
- * to the GPU, and record every pass that moves particles — through to the indirect draw args.
159
- * What it leaves as graph handles is what a draw consumes: {@link execute} draws them
160
- * standalone, and the AVBOIT side-channel methods below draw them through the renderer's
161
- * transparency pipeline.
179
+ * The system's whole contribution to the frame: the simulation, then whatever `mode` says draws
180
+ * it.
181
+ *
182
+ * {@link ParticleRenderMode.BILLBOARD} adds the depth sort and one billboard draw over `color`
183
+ * with fixed-function blending, for a page with no transparency pipeline of its own.
184
+ * {@link ParticleRenderMode.AVBOIT} adds nothing: the orchestrator draws the particles later in
185
+ * the frame through {@link avboit_occupancy}, {@link avboit_splat} and {@link avboit_draw}, off
186
+ * the handles this just produced, and its accumulators are order-independent — so the sort is
187
+ * skipped and its buffers are never allocated. `color` comes straight back either way, so a
188
+ * caller can assign the result unconditionally and let the mode be the only difference.
162
189
  *
163
190
  * Call after the scene context has built for the frame (`GPUSceneContext#update`), so every
164
191
  * emitter node has its `transforms` row, and after the hierarchy pass has run, so the rows'
@@ -176,36 +203,22 @@ export class GPUParticleSystem {
176
203
  * @param {number} params.scene_database graph handle of the scene database — the one the
177
204
  * hierarchy pass returned, so this reads the matrices it composed
178
205
  * @param {number} params.dt seconds since the previous frame
179
- * @returns {import("./graph_particles.js").ParticleSimulationHandles}
180
- */
181
- simulate({ graph, camera, scene_database, dt }: {
182
- graph: import("../../../engine/graphics/render/frame_graph/FrameGraph.js").FrameGraph;
183
- camera: number;
184
- scene_database: number;
185
- dt: number;
186
- }): import("./graph_particles.js").ParticleSimulationHandles;
187
- /**
188
- * The whole standalone frame: {@link simulate}, then the depth sort and one billboard draw over
189
- * a colour target with fixed-function blending. For a page without the renderer's transparency
190
- * pipeline; under the renderer the drawing is AVBOIT's.
191
- *
192
- * @param {object} params every parameter of {@link simulate}, plus a target to draw over
193
- * @param {import("../../../engine/graphics/render/frame_graph/FrameGraph.js").FrameGraph} params.graph
194
- * @param {number} params.camera graph handle of the camera uniform buffer
195
- * @param {number} params.scene_database graph handle of the scene database
196
- * @param {number} params.dt seconds since the previous frame
197
- * @param {number} params.color graph handle of the colour target to draw over
198
- * @param {number} params.depth graph handle of the scene depth (tested, never written)
199
- * @returns {number} the colour handle after the particle draw
206
+ * @param {ParticleRenderMode} [params.mode] who draws, and so whether there is a sort
207
+ * @param {number} [params.color] graph handle of the colour target to draw over. Required by
208
+ * `BILLBOARD`; returned untouched by `AVBOIT`
209
+ * @param {number} [params.depth] graph handle of the scene depth (tested, never written).
210
+ * Required by `BILLBOARD`
211
+ * @returns {number|undefined} the colour handle after the particle draw, or `color` unchanged
200
212
  */
201
- execute({ graph, camera, scene_database, color, depth, dt }: {
213
+ execute({ graph, camera, scene_database, color, depth, dt, mode }: {
202
214
  graph: import("../../../engine/graphics/render/frame_graph/FrameGraph.js").FrameGraph;
203
215
  camera: number;
204
216
  scene_database: number;
205
217
  dt: number;
206
- color: number;
207
- depth: number;
208
- }): number;
218
+ mode?: ParticleRenderMode;
219
+ color?: number;
220
+ depth?: number;
221
+ }): number | undefined;
209
222
  /**
210
223
  * `AVBOITSideChannel#avboit_occupancy`: the emitters' bounds spheres, as depth slices.
211
224
  *
@@ -295,4 +308,5 @@ export class GPUParticleSystem {
295
308
  #private;
296
309
  }
297
310
  import { EmitterRegistry } from "./runtime/EmitterRegistry.js";
311
+ import { ParticleRenderMode } from "./ParticleRenderMode.js";
298
312
  //# sourceMappingURL=GPUParticleSystem.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"GPUParticleSystem.d.ts","sourceRoot":"","sources":["../../../../../src/shade/renderer/particles/GPUParticleSystem.js"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"GPUParticleSystem.d.ts","sourceRoot":"","sources":["../../../../../src/shade/renderer/particles/GPUParticleSystem.js"],"names":[],"mappings":"AA+BA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsEG;AACH;IAyJI;;;;;;OAMG;IACH,sBANW,MAAM,iBACN,OAAO,6BAA6B,EAAE,eAAe;QAEpC,QAAQ,GAAzB,MAAM;QACW,sBAAsB,GAAvC,MAAM;OAoBhB;IAhLD;;;OAGG;IACH,UAFU,MAAM,CAEP;IAET;;;OAGG;IACH,eAFU,OAAO,6BAA6B,EAAE,eAAe,CAEjD;IAEd;;;OAGG;IACH,UAFU,MAAM,CAEP;IAET;;OAEG;IACH,UAFU,eAAe,CAEhB;IAET;;;OAGG;IACH,OAFU,MAAM,CAEN;IAEV;;;OAGG;IACH,MAFU,MAAM,CAEP;IAET;;;OAGG;IACH,qBAFU,MAAM,CAEQ;IAExB;;;;OAIG;IACH,kBAFU,YAAY,CAE0B;IAEhD;;;;OAIG;IACH,sBAAM;IAEN,yBAAyB;IACzB,0BAAc;IAEd;;;;;;OAMG;IACH,SAFU,MAAM,CAEH;IAiHb;;;OAGG;IACH,kCAEC;IAED;;;OAGG;IACH,yEAEC;IAED;;;;;;;;;;;;OAYG;IACH,eAFa,MAAM,CAIlB;IAED;;;OAGG;IACH,gCAEC;IAED;;;;;;;OAOG;IACH,eAHW,OAAO,8BAA8B,EAAE,eAAe,SACtD,MAAM,QAwBhB;IAoED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAkCG;IACH;QAZkG,KAAK,EAA5F,OAAO,2DAA2D,EAAE,UAAU;QAC/D,MAAM,EAArB,MAAM;QACS,cAAc,EAA7B,MAAM;QAES,EAAE,EAAjB,MAAM;QACsB,IAAI,GAAhC,kBAAkB;QACF,KAAK,GAArB,MAAM;QAEU,KAAK,GAArB,MAAM;QAEJ,MAAM,GAAC,SAAS,CA8D5B;IAiBD;;;;;;;;;OASG;IACH;QANgG,KAAK,EAA1F,OAAO,2DAA2D,EAAE,UAAU;QACjE,MAAM,EAAnB,MAAM;QACkB,kBAAkB,EAA1C,UAAU,MAAM,CAAC;QACJ,SAAS,EAAtB,MAAM;QACJ,MAAM,CAclB;IAED;;;;;;;;;;OAUG;IACH;QAPgG,KAAK,EAA1F,OAAO,2DAA2D,EAAE,UAAU;QACjE,MAAM,EAAnB,MAAM;QACO,IAAI,EAAjB,MAAM;QACO,aAAa,EAA1B,MAAM;QACsD,MAAM,EAAlE;YAAC,UAAU,EAAE,MAAM,CAAC;YAAC,QAAQ,EAAE,MAAM,CAAC;YAAC,KAAK,EAAE,MAAM,CAAA;SAAC;QACnD;QAAC,UAAU,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAC,CAkBjE;IAED;;;;;;;;;;;;;;OAcG;IACH;QAXgG,KAAK,EAA1F,OAAO,2DAA2D,EAAE,UAAU;QACrB,QAAQ,EAAjE,OAAO,2BAA2B,EAAE,cAAc;QACrC,MAAM,EAAnB,MAAM;QACO,aAAa,EAA1B,MAAM;QACO,IAAI,EAAjB,MAAM;QACO,QAAQ,EAArB,MAAM;QACO,eAAe,EAA5B,MAAM;QACO,oBAAoB,EAAjC,MAAM;QACoE,YAAY,EAAtF;YAAC,KAAK,EAAE,MAAM,CAAC;YAAC,IAAI,EAAE,MAAM,CAAC;YAAC,UAAU,EAAE,MAAM,CAAC;YAAC,QAAQ,EAAE,MAAM,CAAA;SAAC;QACjE;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAC,CAsB/E;IA6SD;;;OAGG;IACH;YAFoB,MAAM,GAAE,MAAM;MAcjC;IAED,gBA4BC;;CACJ;gCAn7B+B,8BAA8B;mCAD3B,yBAAyB"}