@woosh/meep-engine 3.58.0 → 3.59.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 (609) hide show
  1. package/editor/particles/effect/ParticleEffectDocument.d.ts +162 -43
  2. package/editor/particles/effect/ParticleEffectDocument.d.ts.map +1 -1
  3. package/editor/particles/effect/ParticleEffectDocument.js +450 -43
  4. package/editor/particles/effect/ParticleReferenceSimulation.d.ts +12 -3
  5. package/editor/particles/effect/ParticleReferenceSimulation.d.ts.map +1 -1
  6. package/editor/particles/effect/ParticleReferenceSimulation.js +78 -23
  7. package/editor/particles/effect/make_starter_particle_effect.js +17 -17
  8. package/editor/view/particles/effect/ParticleEmitterInspectorView.d.ts +3 -3
  9. package/editor/view/particles/effect/ParticleEmitterInspectorView.d.ts.map +1 -1
  10. package/editor/view/particles/effect/ParticleEmitterInspectorView.js +224 -67
  11. package/editor/view/particles/effect/ParticleGraphEditorView.d.ts.map +1 -1
  12. package/editor/view/particles/effect/ParticleGraphEditorView.js +44 -11
  13. package/editor/view/particles/effect/ParticleNodeParametersView.d.ts +2 -1
  14. package/editor/view/particles/effect/ParticleNodeParametersView.d.ts.map +1 -1
  15. package/editor/view/particles/effect/ParticleNodeParametersView.js +46 -16
  16. package/editor/view/particles/effect/ParticlePreviewView.js +2 -2
  17. package/editor/view/particles/effect/particle-editor.css +77 -68
  18. package/package.json +1 -1
  19. package/src/engine/Engine.d.ts.map +1 -1
  20. package/src/engine/Engine.js +2 -2
  21. package/src/engine/ecs/EntityManager.d.ts +29 -5
  22. package/src/engine/ecs/EntityManager.d.ts.map +1 -1
  23. package/src/engine/ecs/EntityManager.js +37 -1
  24. package/src/engine/ecs/storage/populateEngineSerializationRegistry.d.ts.map +1 -1
  25. package/src/engine/ecs/storage/populateEngineSerializationRegistry.js +4 -0
  26. package/src/engine/graphics/ecs/particles/ParticleEffect.d.ts +74 -17
  27. package/src/engine/graphics/ecs/particles/ParticleEffect.d.ts.map +1 -1
  28. package/src/engine/graphics/ecs/particles/ParticleEffect.js +156 -25
  29. package/src/engine/graphics/ecs/particles/ParticleEffectSerializationAdapter.d.ts +13 -3
  30. package/src/engine/graphics/ecs/particles/ParticleEffectSerializationAdapter.d.ts.map +1 -1
  31. package/src/engine/graphics/ecs/particles/ParticleEffectSerializationAdapter.js +59 -13
  32. package/src/engine/graphics/ecs/particles/ParticleEffectSerializationUpgrader_1_2.d.ts +3 -3
  33. package/src/engine/graphics/ecs/particles/ParticleEffectSerializationUpgrader_1_2.js +9 -9
  34. package/src/engine/graphics/ecs/particles/ParticleEffectSerializationUpgrader_2_3.d.ts +15 -0
  35. package/src/engine/graphics/ecs/particles/ParticleEffectSerializationUpgrader_2_3.d.ts.map +1 -0
  36. package/src/engine/graphics/ecs/particles/ParticleEffectSerializationUpgrader_2_3.js +78 -0
  37. package/src/engine/graphics/ecs/trail3d/Trail3D.d.ts +2 -0
  38. package/src/engine/graphics/ecs/trail3d/Trail3D.d.ts.map +1 -1
  39. package/src/engine/graphics/ecs/trail3d/Trail3D.js +2 -0
  40. package/src/engine/graphics/ecs/trail3d/seed_trail_stroke.js +1 -1
  41. package/src/engine/graphics/ecs/trail3d/seed_trail_tube.js +1 -1
  42. package/src/engine/graphics/trail/tube/TubeX.d.ts +5 -3
  43. package/src/engine/graphics/trail/tube/TubeX.d.ts.map +1 -1
  44. package/src/engine/graphics/trail/tube/TubeX.js +5 -3
  45. package/src/engine/graphics/trail/tube/tube_attributes_spec.d.ts +3 -2
  46. package/src/engine/graphics/trail/tube/tube_attributes_spec.d.ts.map +1 -1
  47. package/src/engine/graphics/trail/tube/tube_attributes_spec.js +9 -8
  48. package/src/engine/graphics3/GPUParticleEmitterSystem.d.ts +65 -4
  49. package/src/engine/graphics3/GPUParticleEmitterSystem.d.ts.map +1 -1
  50. package/src/engine/graphics3/GPUParticleEmitterSystem.js +1351 -904
  51. package/src/engine/graphics3/trail/trail_tube_write_geometry.d.ts +1 -1
  52. package/src/engine/graphics3/trail/trail_tube_write_geometry.js +13 -13
  53. package/src/engine/physics/fluid/ecs/FluidObstacleSystem.d.ts +4 -4
  54. package/src/generation/foliage/FOLIAGE_DESIGN.md +26 -5
  55. package/src/generation/foliage/LOD_REWORK_BRIEF_2026_10_27.md +35 -0
  56. package/src/generation/foliage/SELF_ORGANIZING_FRAMEWORK_BRIEF_2026_10_26.md +2 -1
  57. package/src/generation/foliage/TWO_FRONT_ENDS_BRIEF_2026_10_28.md +552 -0
  58. package/src/generation/foliage/analysis/tree_crown_opacity.d.ts.map +1 -1
  59. package/src/generation/foliage/analysis/tree_crown_opacity.js +2 -1
  60. package/src/generation/foliage/analysis/tree_render_cost.d.ts +5 -3
  61. package/src/generation/foliage/analysis/tree_render_cost.d.ts.map +1 -1
  62. package/src/generation/foliage/analysis/tree_render_cost.js +8 -7
  63. package/src/generation/foliage/asset/TreeAsset.d.ts +17 -0
  64. package/src/generation/foliage/asset/TreeAsset.d.ts.map +1 -1
  65. package/src/generation/foliage/asset/TreeAsset.js +20 -0
  66. package/src/generation/foliage/asset/TreeSpeciesCache.d.ts +69 -0
  67. package/src/generation/foliage/asset/TreeSpeciesCache.d.ts.map +1 -0
  68. package/src/generation/foliage/asset/TreeSpeciesCache.js +147 -0
  69. package/src/generation/foliage/asset/generate_tree.d.ts +10 -0
  70. package/src/generation/foliage/asset/generate_tree.d.ts.map +1 -1
  71. package/src/generation/foliage/asset/generate_tree.js +57 -29
  72. package/src/generation/foliage/asset/place_tree.d.ts +2 -1
  73. package/src/generation/foliage/asset/place_tree.d.ts.map +1 -1
  74. package/src/generation/foliage/asset/place_tree.js +2 -1
  75. package/src/generation/foliage/asset/tree_lod_plan.d.ts +4 -2
  76. package/src/generation/foliage/asset/tree_lod_plan.d.ts.map +1 -1
  77. package/src/generation/foliage/asset/tree_lod_plan.js +12 -14
  78. package/src/generation/foliage/asset/tree_shoot_instances.d.ts +119 -0
  79. package/src/generation/foliage/asset/tree_shoot_instances.d.ts.map +1 -0
  80. package/src/generation/foliage/asset/tree_shoot_instances.js +410 -0
  81. package/src/generation/foliage/asset/tree_shoot_prototypes.d.ts +155 -0
  82. package/src/generation/foliage/asset/tree_shoot_prototypes.d.ts.map +1 -0
  83. package/src/generation/foliage/asset/tree_shoot_prototypes.js +251 -0
  84. package/src/generation/foliage/config/TreeGrowth.d.ts +10 -0
  85. package/src/generation/foliage/config/TreeGrowth.d.ts.map +1 -0
  86. package/src/generation/foliage/config/TreeGrowth.js +18 -0
  87. package/src/generation/foliage/config/TreeLODConfig.d.ts +6 -0
  88. package/src/generation/foliage/config/TreeLODConfig.d.ts.map +1 -1
  89. package/src/generation/foliage/config/TreeLODConfig.js +7 -0
  90. package/src/generation/foliage/index.d.ts +3 -0
  91. package/src/generation/foliage/index.js +3 -0
  92. package/src/generation/foliage/material/foliage_tile.d.ts +6 -6
  93. package/src/generation/foliage/material/foliage_tile.js +3 -3
  94. package/src/generation/foliage/material/tree_cluster_atlas.d.ts +44 -0
  95. package/src/generation/foliage/material/tree_cluster_atlas.d.ts.map +1 -0
  96. package/src/generation/foliage/material/tree_cluster_atlas.js +37 -0
  97. package/src/generation/foliage/mesh/foliage_collect_attachments.js +2 -2
  98. package/src/generation/foliage/mesh/foliage_scale_spread.d.ts +14 -0
  99. package/src/generation/foliage/mesh/foliage_scale_spread.d.ts.map +1 -0
  100. package/src/generation/foliage/mesh/foliage_scale_spread.js +15 -0
  101. package/src/generation/foliage/mesh/tree_cluster_representatives.d.ts +8 -7
  102. package/src/generation/foliage/mesh/tree_cluster_representatives.d.ts.map +1 -1
  103. package/src/generation/foliage/mesh/tree_cluster_representatives.js +85 -40
  104. package/src/generation/foliage/mesh/tree_clusters.d.ts +26 -5
  105. package/src/generation/foliage/mesh/tree_clusters.d.ts.map +1 -1
  106. package/src/generation/foliage/mesh/tree_clusters.js +52 -39
  107. package/src/generation/foliage/mesh/tree_mesh_build_bark.d.ts.map +1 -1
  108. package/src/generation/foliage/mesh/tree_mesh_build_bark.js +32 -54
  109. package/src/generation/foliage/presets/make_tree_species_preset.d.ts +6 -1
  110. package/src/generation/foliage/presets/make_tree_species_preset.d.ts.map +1 -1
  111. package/src/generation/foliage/presets/make_tree_species_preset.js +157 -3
  112. package/src/generation/foliage/skeleton/TreeSkeleton.d.ts +19 -0
  113. package/src/generation/foliage/skeleton/TreeSkeleton.d.ts.map +1 -1
  114. package/src/generation/foliage/skeleton/TreeSkeleton.js +41 -0
  115. package/src/generation/foliage/skeleton/tree_skeleton_compute_joint_mechanics.d.ts +5 -0
  116. package/src/generation/foliage/skeleton/tree_skeleton_compute_joint_mechanics.d.ts.map +1 -1
  117. package/src/generation/foliage/skeleton/tree_skeleton_compute_joint_mechanics.js +8 -1
  118. package/src/generation/foliage/skeleton/tree_skeleton_copy_branches.d.ts +70 -0
  119. package/src/generation/foliage/skeleton/tree_skeleton_copy_branches.d.ts.map +1 -0
  120. package/src/generation/foliage/skeleton/tree_skeleton_copy_branches.js +171 -0
  121. package/src/generation/foliage/skeleton/tree_skeleton_extend_branch.d.ts +17 -0
  122. package/src/generation/foliage/skeleton/tree_skeleton_extend_branch.d.ts.map +1 -0
  123. package/src/generation/foliage/skeleton/tree_skeleton_extend_branch.js +79 -0
  124. package/src/generation/foliage/skeleton/tree_skeleton_fit_crown_frame.d.ts +12 -0
  125. package/src/generation/foliage/skeleton/tree_skeleton_fit_crown_frame.d.ts.map +1 -0
  126. package/src/generation/foliage/skeleton/tree_skeleton_fit_crown_frame.js +56 -0
  127. package/src/generation/foliage/skeleton/tree_skeleton_floor_girth.d.ts +11 -0
  128. package/src/generation/foliage/skeleton/tree_skeleton_floor_girth.d.ts.map +1 -0
  129. package/src/generation/foliage/skeleton/tree_skeleton_floor_girth.js +38 -0
  130. package/src/generation/foliage/skeleton/tree_skeleton_grow.d.ts +4 -11
  131. package/src/generation/foliage/skeleton/tree_skeleton_grow.d.ts.map +1 -1
  132. package/src/generation/foliage/skeleton/tree_skeleton_grow.js +8 -2034
  133. package/src/generation/foliage/skeleton/tree_skeleton_grow_framework.d.ts +22 -0
  134. package/src/generation/foliage/skeleton/tree_skeleton_grow_framework.d.ts.map +1 -0
  135. package/src/generation/foliage/skeleton/tree_skeleton_grow_framework.js +2050 -0
  136. package/src/generation/foliage/skeleton/tree_skeleton_grow_shoots.d.ts +10 -0
  137. package/src/generation/foliage/skeleton/tree_skeleton_grow_shoots.d.ts.map +1 -1
  138. package/src/generation/foliage/skeleton/tree_skeleton_grow_shoots.js +27 -56
  139. package/src/shade/descriptor/pipeline/render/DepthStencilState.d.ts +4 -0
  140. package/src/shade/descriptor/pipeline/render/DepthStencilState.d.ts.map +1 -1
  141. package/src/shade/descriptor/pipeline/render/DepthStencilState.js +170 -144
  142. package/src/shade/descriptor/pipeline/render/MultisampleState.d.ts +4 -0
  143. package/src/shade/descriptor/pipeline/render/MultisampleState.d.ts.map +1 -1
  144. package/src/shade/descriptor/pipeline/render/MultisampleState.js +78 -65
  145. package/src/shade/descriptor/pipeline/render/RenderPipelineDescriptor.d.ts.map +1 -1
  146. package/src/shade/descriptor/pipeline/render/RenderPipelineDescriptor.js +176 -172
  147. package/src/shade/descriptor/pipeline/render/StencilFaceState.d.ts +4 -0
  148. package/src/shade/descriptor/pipeline/render/StencilFaceState.d.ts.map +1 -1
  149. package/src/shade/descriptor/pipeline/render/StencilFaceState.js +107 -88
  150. package/src/shade/playground/particle_ecs/README.md +9 -8
  151. package/src/shade/playground/particle_ecs/bonfire_editor.js +3 -3
  152. package/src/shade/playground/particle_ecs/bonfire_effects.d.ts +6 -6
  153. package/src/shade/playground/particle_ecs/bonfire_effects.js +6 -6
  154. package/src/shade/playground/particle_editor/README.md +14 -11
  155. package/src/shade/playground/particle_system/particle_prototype.js +18 -18
  156. package/src/shade/playground/particle_system/particle_scene.js +13 -13
  157. package/src/shade/playground/probe_clipmap/README.md +42 -0
  158. package/src/shade/playground/probe_clipmap/index.html +178 -0
  159. package/src/shade/playground/probe_clipmap/main.d.ts +8 -0
  160. package/src/shade/playground/probe_clipmap/main.d.ts.map +1 -0
  161. package/src/shade/playground/probe_clipmap/main.js +360 -0
  162. package/src/shade/renderer/Renderer.d.ts +3 -1
  163. package/src/shade/renderer/Renderer.d.ts.map +1 -1
  164. package/src/shade/renderer/Renderer.js +94 -38
  165. package/src/shade/renderer/extension/ViewTextures.d.ts +2 -1
  166. package/src/shade/renderer/extension/ViewTextures.d.ts.map +1 -1
  167. package/src/shade/renderer/extension/ViewTextures.js +2 -1
  168. package/src/shade/renderer/fluid/GPUFluidCascade.d.ts +3 -3
  169. package/src/shade/renderer/fluid/GPUFluidCascadeStack.d.ts +1 -1
  170. package/src/shade/renderer/fluid/forcing/GPUFluidForcing.d.ts +6 -6
  171. package/src/shade/renderer/fluid/pressure/GPUFluidPressureSolve.d.ts +1 -1
  172. package/src/shade/renderer/fluid/query/GPUFluidQueries.d.ts +1 -1
  173. package/src/shade/renderer/geometry/virtual/runtime/GPUVirtualGeometryRuntime.d.ts +34 -12
  174. package/src/shade/renderer/geometry/virtual/runtime/GPUVirtualGeometryRuntime.d.ts.map +1 -1
  175. package/src/shade/renderer/geometry/virtual/runtime/GPUVirtualGeometryRuntime.js +56 -15
  176. package/src/shade/renderer/geometry/virtual/runtime/VGeoFeedbackLoop.d.ts +2 -2
  177. package/src/shade/renderer/geometry/virtual/runtime/VGeoFeedbackLoop.d.ts.map +1 -1
  178. package/src/shade/renderer/geometry/virtual/runtime/VGeoFeedbackLoop.js +13 -26
  179. package/src/shade/renderer/geometry/virtual/runtime/VGeoViewCut.d.ts +25 -2
  180. package/src/shade/renderer/geometry/virtual/runtime/VGeoViewCut.d.ts.map +1 -1
  181. package/src/shade/renderer/geometry/virtual/runtime/VGeoViewCut.js +54 -32
  182. package/src/shade/renderer/geometry/virtual/runtime/cut/VGEO_CUT_VERDICT.d.ts +14 -0
  183. package/src/shade/renderer/geometry/virtual/runtime/cut/VGEO_CUT_VERDICT.d.ts.map +1 -0
  184. package/src/shade/renderer/geometry/virtual/runtime/cut/VGEO_CUT_VERDICT.js +37 -0
  185. package/src/shade/renderer/geometry/virtual/runtime/cut/chunk_vgeo_cut_arena.d.ts.map +1 -1
  186. package/src/shade/renderer/geometry/virtual/runtime/cut/chunk_vgeo_cut_arena.js +16 -0
  187. package/src/shade/renderer/geometry/virtual/runtime/cut/chunk_vgeo_cut_claim.d.ts.map +1 -1
  188. package/src/shade/renderer/geometry/virtual/runtime/cut/chunk_vgeo_cut_claim.js +2 -6
  189. package/src/shade/renderer/geometry/virtual/runtime/cut/chunk_vgeo_cut_descent.d.ts +131 -0
  190. package/src/shade/renderer/geometry/virtual/runtime/cut/chunk_vgeo_cut_descent.d.ts.map +1 -0
  191. package/src/shade/renderer/geometry/virtual/runtime/cut/chunk_vgeo_cut_descent.js +467 -0
  192. package/src/shade/renderer/geometry/virtual/runtime/cut/chunk_vgeo_cut_instance.d.ts +24 -0
  193. package/src/shade/renderer/geometry/virtual/runtime/cut/chunk_vgeo_cut_instance.d.ts.map +1 -0
  194. package/src/shade/renderer/geometry/virtual/runtime/cut/chunk_vgeo_cut_instance.js +111 -0
  195. package/src/shade/renderer/geometry/virtual/runtime/cut/chunk_vgeo_cut_rule.d.ts +42 -0
  196. package/src/shade/renderer/geometry/virtual/runtime/cut/chunk_vgeo_cut_rule.d.ts.map +1 -0
  197. package/src/shade/renderer/geometry/virtual/runtime/cut/chunk_vgeo_cut_rule.js +404 -0
  198. package/src/shade/renderer/geometry/virtual/runtime/cut/chunk_vgeo_cut_stat.d.ts +16 -0
  199. package/src/shade/renderer/geometry/virtual/runtime/cut/chunk_vgeo_cut_stat.d.ts.map +1 -0
  200. package/src/shade/renderer/geometry/virtual/runtime/cut/chunk_vgeo_cut_stat.js +23 -0
  201. package/src/shade/renderer/geometry/virtual/runtime/cut/chunk_vgeo_cut_want.d.ts +17 -0
  202. package/src/shade/renderer/geometry/virtual/runtime/cut/chunk_vgeo_cut_want.d.ts.map +1 -0
  203. package/src/shade/renderer/geometry/virtual/runtime/cut/chunk_vgeo_cut_want.js +65 -0
  204. package/src/shade/renderer/geometry/virtual/runtime/cut/shader_vgeo_cut_collect.d.ts.map +1 -1
  205. package/src/shade/renderer/geometry/virtual/runtime/cut/shader_vgeo_cut_collect.js +14 -70
  206. package/src/shade/renderer/geometry/virtual/runtime/cut/shader_vgeo_cut_traverse.d.ts.map +1 -1
  207. package/src/shade/renderer/geometry/virtual/runtime/cut/shader_vgeo_cut_traverse.js +13 -773
  208. package/src/shade/renderer/geometry/virtual/runtime/graph_vgeo_cut_descent.d.ts +55 -0
  209. package/src/shade/renderer/geometry/virtual/runtime/graph_vgeo_cut_descent.d.ts.map +1 -0
  210. package/src/shade/renderer/geometry/virtual/runtime/graph_vgeo_cut_descent.js +248 -0
  211. package/src/shade/renderer/geometry/virtual/runtime/graph_vgeo_expand_instances_to_meshlets.d.ts.map +1 -1
  212. package/src/shade/renderer/geometry/virtual/runtime/graph_vgeo_expand_instances_to_meshlets.js +15 -174
  213. package/src/shade/renderer/global_illumination/brick4/gpu/draw/chunk_brick4_probe_meta_pick2.d.ts.map +1 -1
  214. package/src/shade/renderer/global_illumination/brick4/gpu/draw/chunk_brick4_probe_meta_pick2.js +8 -24
  215. package/src/shade/renderer/global_illumination/brick4/gpu/draw/chunk_brick4_sample_forward_indirect.d.ts.map +1 -1
  216. package/src/shade/renderer/global_illumination/brick4/gpu/draw/chunk_brick4_sample_forward_indirect.js +1 -25
  217. package/src/shade/renderer/global_illumination/lpv/deprecated/chunk_lpv_get_visibility_mask.d.ts.map +1 -1
  218. package/src/shade/renderer/global_illumination/lpv/deprecated/chunk_lpv_get_visibility_mask.js +5 -23
  219. package/src/shade/renderer/global_illumination/probe_clipmap/GPUProbeClipmapGI.d.ts +25 -4
  220. package/src/shade/renderer/global_illumination/probe_clipmap/GPUProbeClipmapGI.d.ts.map +1 -1
  221. package/src/shade/renderer/global_illumination/probe_clipmap/GPUProbeClipmapGI.js +126 -8
  222. package/src/shade/renderer/global_illumination/probe_clipmap/PROBE_CLIPMAP_PROPOSAL_2026_10_27.md +832 -4
  223. package/src/shade/renderer/global_illumination/probe_clipmap/brick/BRICK_CLIPMAP.d.ts +7 -0
  224. package/src/shade/renderer/global_illumination/probe_clipmap/brick/BRICK_CLIPMAP.d.ts.map +1 -1
  225. package/src/shade/renderer/global_illumination/probe_clipmap/brick/BRICK_CLIPMAP.js +8 -0
  226. package/src/shade/renderer/global_illumination/probe_clipmap/brick/GPUBrickClipmap.d.ts +16 -0
  227. package/src/shade/renderer/global_illumination/probe_clipmap/brick/GPUBrickClipmap.d.ts.map +1 -1
  228. package/src/shade/renderer/global_illumination/probe_clipmap/brick/GPUBrickClipmap.js +9 -0
  229. package/src/shade/renderer/global_illumination/probe_clipmap/brick/{mesh/chunk_mesh_brick_object.d.ts → chunk_brick_object.d.ts} +8 -8
  230. package/src/shade/renderer/global_illumination/probe_clipmap/brick/chunk_brick_object.d.ts.map +1 -0
  231. package/src/shade/renderer/global_illumination/probe_clipmap/brick/chunk_brick_object.js +42 -0
  232. package/src/shade/renderer/global_illumination/probe_clipmap/brick/chunk_brick_provider.d.ts +45 -0
  233. package/src/shade/renderer/global_illumination/probe_clipmap/brick/chunk_brick_provider.d.ts.map +1 -0
  234. package/src/shade/renderer/global_illumination/probe_clipmap/brick/chunk_brick_provider.js +93 -0
  235. package/src/shade/renderer/global_illumination/probe_clipmap/brick/mesh/MESH_BRICK_INSTANCE_STRUCT.d.ts +0 -7
  236. package/src/shade/renderer/global_illumination/probe_clipmap/brick/mesh/MESH_BRICK_INSTANCE_STRUCT.d.ts.map +1 -1
  237. package/src/shade/renderer/global_illumination/probe_clipmap/brick/mesh/MESH_BRICK_INSTANCE_STRUCT.js +0 -8
  238. package/src/shade/renderer/global_illumination/probe_clipmap/brick/mesh/chunk_mesh_brick_instance.d.ts +2 -4
  239. package/src/shade/renderer/global_illumination/probe_clipmap/brick/mesh/chunk_mesh_brick_instance.d.ts.map +1 -1
  240. package/src/shade/renderer/global_illumination/probe_clipmap/brick/mesh/chunk_mesh_brick_instance.js +5 -8
  241. package/src/shade/renderer/global_illumination/probe_clipmap/brick/mesh/shader_mesh_brick_provider.d.ts.map +1 -1
  242. package/src/shade/renderer/global_illumination/probe_clipmap/brick/mesh/shader_mesh_brick_provider.js +13 -22
  243. package/src/shade/renderer/global_illumination/probe_clipmap/brick/vgeo/VGEO_BRICK.d.ts +99 -0
  244. package/src/shade/renderer/global_illumination/probe_clipmap/brick/vgeo/VGEO_BRICK.d.ts.map +1 -0
  245. package/src/shade/renderer/global_illumination/probe_clipmap/brick/vgeo/VGEO_BRICK.js +139 -0
  246. package/src/shade/renderer/global_illumination/probe_clipmap/brick/vgeo/VGeoBrickProvider.d.ts +65 -0
  247. package/src/shade/renderer/global_illumination/probe_clipmap/brick/vgeo/VGeoBrickProvider.d.ts.map +1 -0
  248. package/src/shade/renderer/global_illumination/probe_clipmap/brick/vgeo/VGeoBrickProvider.js +393 -0
  249. package/src/shade/renderer/global_illumination/probe_clipmap/brick/vgeo/chunk_vgeo_brick_box.d.ts +17 -0
  250. package/src/shade/renderer/global_illumination/probe_clipmap/brick/vgeo/chunk_vgeo_brick_box.d.ts.map +1 -0
  251. package/src/shade/renderer/global_illumination/probe_clipmap/brick/vgeo/chunk_vgeo_brick_box.js +36 -0
  252. package/src/shade/renderer/global_illumination/probe_clipmap/brick/vgeo/chunk_vgeo_brick_pair.d.ts +29 -0
  253. package/src/shade/renderer/global_illumination/probe_clipmap/brick/vgeo/chunk_vgeo_brick_pair.d.ts.map +1 -0
  254. package/src/shade/renderer/global_illumination/probe_clipmap/brick/vgeo/chunk_vgeo_brick_pair.js +108 -0
  255. package/src/shade/renderer/global_illumination/probe_clipmap/brick/vgeo/chunk_vgeo_brick_texel.d.ts +31 -0
  256. package/src/shade/renderer/global_illumination/probe_clipmap/brick/vgeo/chunk_vgeo_brick_texel.d.ts.map +1 -0
  257. package/src/shade/renderer/global_illumination/probe_clipmap/brick/vgeo/chunk_vgeo_brick_texel.js +113 -0
  258. package/src/shade/renderer/global_illumination/probe_clipmap/brick/vgeo/chunk_vgeo_brick_triangle.d.ts +36 -0
  259. package/src/shade/renderer/global_illumination/probe_clipmap/brick/vgeo/chunk_vgeo_brick_triangle.d.ts.map +1 -0
  260. package/src/shade/renderer/global_illumination/probe_clipmap/brick/vgeo/chunk_vgeo_brick_triangle.js +85 -0
  261. package/src/shade/renderer/global_illumination/probe_clipmap/brick/vgeo/shader_vgeo_brick_distance.d.ts +23 -0
  262. package/src/shade/renderer/global_illumination/probe_clipmap/brick/vgeo/shader_vgeo_brick_distance.d.ts.map +1 -0
  263. package/src/shade/renderer/global_illumination/probe_clipmap/brick/vgeo/shader_vgeo_brick_distance.js +273 -0
  264. package/src/shade/renderer/global_illumination/probe_clipmap/brick/vgeo/shader_vgeo_brick_gather.d.ts +13 -0
  265. package/src/shade/renderer/global_illumination/probe_clipmap/brick/vgeo/shader_vgeo_brick_gather.d.ts.map +1 -0
  266. package/src/shade/renderer/global_illumination/probe_clipmap/brick/vgeo/shader_vgeo_brick_gather.js +151 -0
  267. package/src/shade/renderer/global_illumination/probe_clipmap/brick/vgeo/shader_vgeo_brick_traverse.d.ts +13 -0
  268. package/src/shade/renderer/global_illumination/probe_clipmap/brick/vgeo/shader_vgeo_brick_traverse.d.ts.map +1 -0
  269. package/src/shade/renderer/global_illumination/probe_clipmap/brick/vgeo/shader_vgeo_brick_traverse.js +133 -0
  270. package/src/shade/renderer/global_illumination/probe_clipmap/brick/vgeo/shader_vgeo_brick_wait.d.ts +22 -0
  271. package/src/shade/renderer/global_illumination/probe_clipmap/brick/vgeo/shader_vgeo_brick_wait.d.ts.map +1 -0
  272. package/src/shade/renderer/global_illumination/probe_clipmap/brick/vgeo/shader_vgeo_brick_wait.js +135 -0
  273. package/src/shade/renderer/global_illumination/probe_clipmap/probe/GPUProbeClipmap.d.ts +20 -6
  274. package/src/shade/renderer/global_illumination/probe_clipmap/probe/GPUProbeClipmap.d.ts.map +1 -1
  275. package/src/shade/renderer/global_illumination/probe_clipmap/probe/GPUProbeClipmap.js +152 -10
  276. package/src/shade/renderer/global_illumination/probe_clipmap/probe/PROBE_CLIPMAP.d.ts +7 -0
  277. package/src/shade/renderer/global_illumination/probe_clipmap/probe/PROBE_CLIPMAP.d.ts.map +1 -1
  278. package/src/shade/renderer/global_illumination/probe_clipmap/probe/PROBE_CLIPMAP.js +8 -0
  279. package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap.d.ts +14 -2
  280. package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap.d.ts.map +1 -1
  281. package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap.js +50 -5
  282. package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap_cage.d.ts +19 -0
  283. package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap_cage.d.ts.map +1 -0
  284. package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap_cage.js +40 -0
  285. package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap_pick.d.ts +72 -0
  286. package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap_pick.d.ts.map +1 -0
  287. package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap_pick.js +343 -0
  288. package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap_sample_radiance.d.ts +29 -0
  289. package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap_sample_radiance.d.ts.map +1 -0
  290. package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap_sample_radiance.js +188 -0
  291. package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap_want.d.ts +26 -0
  292. package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap_want.d.ts.map +1 -0
  293. package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap_want.js +132 -0
  294. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_accumulate.d.ts +4 -0
  295. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_accumulate.d.ts.map +1 -1
  296. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_accumulate.js +26 -3
  297. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_admit.d.ts +3 -0
  298. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_admit.d.ts.map +1 -1
  299. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_admit.js +8 -1
  300. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_diffuse.d.ts +12 -0
  301. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_diffuse.d.ts.map +1 -0
  302. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_diffuse.js +101 -0
  303. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_due.d.ts +1 -1
  304. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_due.js +1 -1
  305. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_indirect_lighting.d.ts +15 -0
  306. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_indirect_lighting.d.ts.map +1 -0
  307. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_indirect_lighting.js +175 -0
  308. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_light.d.ts +26 -0
  309. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_light.d.ts.map +1 -0
  310. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_light.js +210 -0
  311. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_retire.d.ts +3 -3
  312. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_retire.js +3 -3
  313. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_shade.d.ts +2 -1
  314. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_shade.d.ts.map +1 -1
  315. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_shade.js +5 -1
  316. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_trace.d.ts.map +1 -1
  317. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_trace.js +3 -10
  318. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_want.d.ts +5 -9
  319. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_want.d.ts.map +1 -1
  320. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_want.js +9 -110
  321. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_want_hits.d.ts +27 -0
  322. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_want_hits.d.ts.map +1 -0
  323. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_want_hits.js +110 -0
  324. package/src/shade/renderer/light/world_cluster/chunk_world_light_cluster_lookup.d.ts +13 -0
  325. package/src/shade/renderer/light/world_cluster/chunk_world_light_cluster_lookup.d.ts.map +1 -1
  326. package/src/shade/renderer/light/world_cluster/chunk_world_light_cluster_lookup.js +40 -0
  327. package/src/shade/renderer/light/world_cluster/graph_build_world_light_clusters.d.ts +11 -6
  328. package/src/shade/renderer/light/world_cluster/graph_build_world_light_clusters.d.ts.map +1 -1
  329. package/src/shade/renderer/light/world_cluster/graph_build_world_light_clusters.js +15 -8
  330. package/src/shade/renderer/light/world_cluster/shader_world_cluster_assign_lights.d.ts +9 -2
  331. package/src/shade/renderer/light/world_cluster/shader_world_cluster_assign_lights.d.ts.map +1 -1
  332. package/src/shade/renderer/light/world_cluster/shader_world_cluster_assign_lights.js +25 -11
  333. package/src/shade/renderer/loader/gltf/tiny-gltf.d.ts +1 -1
  334. package/src/shade/renderer/particles/DESIGN.md +151 -42
  335. package/src/shade/renderer/particles/EMITTER_GLOBAL_STATE_PLAN_2026_10_29.md +283 -0
  336. package/src/shade/renderer/particles/GPUParticleSystem.d.ts +10 -2
  337. package/src/shade/renderer/particles/GPUParticleSystem.d.ts.map +1 -1
  338. package/src/shade/renderer/particles/GPUParticleSystem.js +46 -8
  339. package/src/shade/renderer/particles/ParticleConstants.d.ts +23 -6
  340. package/src/shade/renderer/particles/ParticleConstants.d.ts.map +1 -1
  341. package/src/shade/renderer/particles/ParticleConstants.js +25 -6
  342. package/src/shade/renderer/particles/bounds/chunk_particle_bounds.js +5 -5
  343. package/src/shade/renderer/particles/bounds/shader_particle_bounds.js +187 -187
  344. package/src/shade/renderer/particles/data/PARTICLE_DATABASE_SPEC.d.ts +20 -9
  345. package/src/shade/renderer/particles/data/PARTICLE_DATABASE_SPEC.d.ts.map +1 -1
  346. package/src/shade/renderer/particles/data/PARTICLE_DATABASE_SPEC.js +36 -10
  347. package/src/shade/renderer/particles/data/PARTICLE_EMITTER_STRUCT.d.ts +8 -7
  348. package/src/shade/renderer/particles/data/PARTICLE_EMITTER_STRUCT.d.ts.map +1 -1
  349. package/src/shade/renderer/particles/data/PARTICLE_EMITTER_STRUCT.js +25 -16
  350. package/src/shade/renderer/particles/data/PARTICLE_FIELD_BINDING.d.ts +51 -0
  351. package/src/shade/renderer/particles/data/PARTICLE_FIELD_BINDING.d.ts.map +1 -0
  352. package/src/shade/renderer/particles/data/PARTICLE_FIELD_BINDING.js +56 -0
  353. package/src/shade/renderer/particles/data/particle_emitter_record.d.ts.map +1 -1
  354. package/src/shade/renderer/particles/data/particle_emitter_record.js +2 -0
  355. package/src/shade/renderer/particles/graph/ParticleGroupBuilder.d.ts +1 -1
  356. package/src/shade/renderer/particles/graph/ParticleGroupBuilder.js +1 -1
  357. package/src/shade/renderer/particles/graph/ParticleNodeDescription.d.ts +22 -11
  358. package/src/shade/renderer/particles/graph/ParticleNodeDescription.d.ts.map +1 -1
  359. package/src/shade/renderer/particles/graph/ParticleNodeDescription.js +14 -11
  360. package/src/shade/renderer/particles/graph/ParticleNodeRegistry.d.ts +4 -4
  361. package/src/shade/renderer/particles/graph/ParticleNodeRegistry.d.ts.map +1 -1
  362. package/src/shade/renderer/particles/graph/ParticleNodeRegistry.js +59 -24
  363. package/src/shade/renderer/particles/graph/ParticleValueType.d.ts +3 -3
  364. package/src/shade/renderer/particles/graph/ParticleValueType.js +287 -287
  365. package/src/shade/renderer/particles/graph/compile_particle_graph.d.ts +13 -6
  366. package/src/shade/renderer/particles/graph/compile_particle_graph.d.ts.map +1 -1
  367. package/src/shade/renderer/particles/graph/compile_particle_graph.js +46 -27
  368. package/src/shade/renderer/particles/graph/infer_particle_graph_types.d.ts +8 -2
  369. package/src/shade/renderer/particles/graph/infer_particle_graph_types.d.ts.map +1 -1
  370. package/src/shade/renderer/particles/graph/infer_particle_graph_types.js +240 -234
  371. package/src/shade/renderer/particles/graph/make_particle_group.d.ts +1 -1
  372. package/src/shade/renderer/particles/graph/make_particle_group.js +1 -1
  373. package/src/shade/renderer/particles/graph/particle_graph_authoring.d.ts +3 -2
  374. package/src/shade/renderer/particles/graph/particle_graph_authoring.d.ts.map +1 -1
  375. package/src/shade/renderer/particles/graph/particle_graph_authoring.js +3 -2
  376. package/src/shade/renderer/particles/graph/particle_graph_distributions.js +170 -170
  377. package/src/shade/renderer/particles/graph/particle_graph_json.d.ts +25 -16
  378. package/src/shade/renderer/particles/graph/particle_graph_json.d.ts.map +1 -1
  379. package/src/shade/renderer/particles/graph/particle_graph_json.js +16 -2
  380. package/src/shade/renderer/particles/graph/particle_node_parameters.d.ts +29 -15
  381. package/src/shade/renderer/particles/graph/particle_node_parameters.d.ts.map +1 -1
  382. package/src/shade/renderer/particles/graph/particle_node_parameters.js +54 -22
  383. package/src/shade/renderer/particles/graph/particle_node_presentation.d.ts.map +1 -1
  384. package/src/shade/renderer/particles/graph/particle_node_presentation.js +18 -8
  385. package/src/shade/renderer/particles/graph/validate_particle_graph.d.ts +9 -2
  386. package/src/shade/renderer/particles/graph/validate_particle_graph.d.ts.map +1 -1
  387. package/src/shade/renderer/particles/graph/validate_particle_graph.js +70 -32
  388. package/src/shade/renderer/particles/graph_particles.d.ts +9 -4
  389. package/src/shade/renderer/particles/graph_particles.d.ts.map +1 -1
  390. package/src/shade/renderer/particles/graph_particles.js +27 -4
  391. package/src/shade/renderer/particles/isa/InstructionStream.d.ts +7 -6
  392. package/src/shade/renderer/particles/isa/InstructionStream.d.ts.map +1 -1
  393. package/src/shade/renderer/particles/isa/InstructionStream.js +17 -16
  394. package/src/shade/renderer/particles/isa/ParticleAssembler.d.ts +17 -0
  395. package/src/shade/renderer/particles/isa/ParticleAssembler.d.ts.map +1 -1
  396. package/src/shade/renderer/particles/isa/ParticleAssembler.js +35 -0
  397. package/src/shade/renderer/particles/isa/ParticleProgram.d.ts +26 -6
  398. package/src/shade/renderer/particles/isa/ParticleProgram.d.ts.map +1 -1
  399. package/src/shade/renderer/particles/isa/ParticleProgram.js +61 -9
  400. package/src/shade/renderer/particles/isa/ParticleVMISA.d.ts +55 -4
  401. package/src/shade/renderer/particles/isa/ParticleVMISA.d.ts.map +1 -1
  402. package/src/shade/renderer/particles/isa/ParticleVMISA.js +79 -10
  403. package/src/shade/renderer/particles/isa/particle_assembly.d.ts +20 -6
  404. package/src/shade/renderer/particles/isa/particle_assembly.d.ts.map +1 -1
  405. package/src/shade/renderer/particles/isa/particle_assembly.js +136 -25
  406. package/src/shade/renderer/particles/isa/particle_link_global_fields.d.ts +20 -0
  407. package/src/shade/renderer/particles/isa/particle_link_global_fields.d.ts.map +1 -0
  408. package/src/shade/renderer/particles/isa/particle_link_global_fields.js +46 -0
  409. package/src/shade/renderer/particles/isa/validate_particle_program.js +8 -8
  410. package/src/shade/renderer/particles/layout/ParticleLayout.d.ts +62 -28
  411. package/src/shade/renderer/particles/layout/ParticleLayout.d.ts.map +1 -1
  412. package/src/shade/renderer/particles/layout/ParticleLayout.js +102 -62
  413. package/src/shade/renderer/particles/optimizer/dag/optimize_particle_program_vector.d.ts.map +1 -1
  414. package/src/shade/renderer/particles/optimizer/dag/optimize_particle_program_vector.js +2 -0
  415. package/src/shade/renderer/particles/optimizer/dag/particle_vector_groups.js +1 -1
  416. package/src/shade/renderer/particles/optimizer/dag/particle_vector_lift.js +4 -3
  417. package/src/shade/renderer/particles/optimizer/dag/particle_vector_lower.js +2 -2
  418. package/src/shade/renderer/particles/optimizer/dag/particle_vector_pack.d.ts +3 -3
  419. package/src/shade/renderer/particles/optimizer/dag/particle_vector_pack.js +11 -11
  420. package/src/shade/renderer/particles/optimizer/optimize_particle_program.d.ts +4 -4
  421. package/src/shade/renderer/particles/optimizer/optimize_particle_program.d.ts.map +1 -1
  422. package/src/shade/renderer/particles/optimizer/optimize_particle_program.js +5 -4
  423. package/src/shade/renderer/particles/optimizer/particle_integer_bounds.d.ts +1 -1
  424. package/src/shade/renderer/particles/optimizer/particle_integer_bounds.js +1 -1
  425. package/src/shade/renderer/particles/optimizer/particle_program_equivalence.d.ts +4 -4
  426. package/src/shade/renderer/particles/optimizer/particle_program_equivalence.d.ts.map +1 -1
  427. package/src/shade/renderer/particles/optimizer/particle_program_equivalence.js +13 -11
  428. package/src/shade/renderer/particles/optimizer/particle_program_fuzz.js +7 -7
  429. package/src/shade/renderer/particles/optimizer/particle_vm_semantics.d.ts +3 -2
  430. package/src/shade/renderer/particles/optimizer/particle_vm_semantics.d.ts.map +1 -1
  431. package/src/shade/renderer/particles/optimizer/particle_vm_semantics.js +5 -4
  432. package/src/shade/renderer/particles/optimizer/pass_allocate_registers.d.ts.map +1 -1
  433. package/src/shade/renderer/particles/optimizer/pass_dedup_constants.d.ts.map +1 -1
  434. package/src/shade/renderer/particles/optimizer/pass_eliminate_dead_code.d.ts.map +1 -1
  435. package/src/shade/renderer/particles/optimizer/pass_eliminate_dead_code.js +51 -51
  436. package/src/shade/renderer/particles/optimizer/pass_fold_constants.d.ts.map +1 -1
  437. package/src/shade/renderer/particles/optimizer/pass_fold_constants.js +5 -5
  438. package/src/shade/renderer/particles/optimizer/pass_inline_constants.d.ts.map +1 -1
  439. package/src/shade/renderer/particles/optimizer/pass_narrow_widths.d.ts.map +1 -1
  440. package/src/shade/renderer/particles/optimizer/pass_pack_registers.d.ts.map +1 -1
  441. package/src/shade/renderer/particles/optimizer/pass_peephole.d.ts.map +1 -1
  442. package/src/shade/renderer/particles/optimizer/pass_propagate_copies.d.ts.map +1 -1
  443. package/src/shade/renderer/particles/optimizer/pass_schedule.d.ts.map +1 -1
  444. package/src/shade/renderer/particles/optimizer/pass_schedule.js +2 -2
  445. package/src/shade/renderer/particles/optimizer/pass_share_subexpressions.d.ts.map +1 -1
  446. package/src/shade/renderer/particles/optimizer/pass_share_subexpressions.js +5 -4
  447. package/src/shade/renderer/particles/runtime/EmitterRegistry.d.ts +93 -22
  448. package/src/shade/renderer/particles/runtime/EmitterRegistry.d.ts.map +1 -1
  449. package/src/shade/renderer/particles/runtime/EmitterRegistry.js +336 -29
  450. package/src/shade/renderer/particles/runtime/GPUParticleEmitterContext.d.ts +43 -3
  451. package/src/shade/renderer/particles/runtime/GPUParticleEmitterContext.d.ts.map +1 -1
  452. package/src/shade/renderer/particles/runtime/GPUParticleEmitterContext.js +43 -3
  453. package/src/shade/renderer/particles/runtime/ParticleEmitter.d.ts +56 -26
  454. package/src/shade/renderer/particles/runtime/ParticleEmitter.d.ts.map +1 -1
  455. package/src/shade/renderer/particles/runtime/ParticleEmitter.js +89 -33
  456. package/src/shade/renderer/particles/runtime/ParticleGlobalFields.d.ts +85 -0
  457. package/src/shade/renderer/particles/runtime/ParticleGlobalFields.d.ts.map +1 -0
  458. package/src/shade/renderer/particles/runtime/ParticleGlobalFields.js +221 -0
  459. package/src/shade/renderer/particles/runtime/ProgramHeap.d.ts +143 -18
  460. package/src/shade/renderer/particles/runtime/ProgramHeap.d.ts.map +1 -1
  461. package/src/shade/renderer/particles/runtime/ProgramHeap.js +378 -28
  462. package/src/shade/renderer/particles/runtime/create_particle_effect.d.ts +19 -7
  463. package/src/shade/renderer/particles/runtime/create_particle_effect.d.ts.map +1 -1
  464. package/src/shade/renderer/particles/runtime/create_particle_effect.js +22 -9
  465. package/src/shade/renderer/particles/shaders/chunk_particle_billboard_vertex.js +8 -8
  466. package/src/shade/renderer/particles/shaders/chunk_particle_render_math.js +1 -1
  467. package/src/shade/renderer/particles/shaders/chunk_particle_setup_context.d.ts +3 -0
  468. package/src/shade/renderer/particles/shaders/chunk_particle_setup_context.d.ts.map +1 -1
  469. package/src/shade/renderer/particles/shaders/chunk_particle_setup_context.js +4 -0
  470. package/src/shade/renderer/particles/shaders/shader_particle_field_bind.d.ts +30 -0
  471. package/src/shade/renderer/particles/shaders/shader_particle_field_bind.d.ts.map +1 -0
  472. package/src/shade/renderer/particles/shaders/shader_particle_field_bind.js +121 -0
  473. package/src/shade/renderer/particles/vm/PARTICLE_VM_CONTEXT_STRUCT.d.ts.map +1 -1
  474. package/src/shade/renderer/particles/vm/PARTICLE_VM_CONTEXT_STRUCT.js +3 -1
  475. package/src/shade/renderer/particles/vm/ParticleVMReference.d.ts +12 -4
  476. package/src/shade/renderer/particles/vm/ParticleVMReference.d.ts.map +1 -1
  477. package/src/shade/renderer/particles/vm/ParticleVMReference.js +48 -11
  478. package/src/shade/renderer/particles/vm/chunk_particle_vm.d.ts.map +1 -1
  479. package/src/shade/renderer/particles/vm/chunk_particle_vm.js +36 -14
  480. package/src/shade/renderer/postprocess/PostProcess.d.ts.map +1 -1
  481. package/src/shade/renderer/postprocess/PostProcess.js +2 -1
  482. package/src/shade/renderer/postprocess/gtao/GTAO.d.ts +31 -19
  483. package/src/shade/renderer/postprocess/gtao/GTAO.d.ts.map +1 -1
  484. package/src/shade/renderer/postprocess/gtao/GTAO.js +44 -30
  485. package/src/shade/renderer/postprocess/gtao/ao_reproject_shader.d.ts.map +1 -1
  486. package/src/shade/renderer/postprocess/gtao/ao_reproject_shader.js +16 -2
  487. package/src/shade/renderer/postprocess/nss/NSS.d.ts +1 -1
  488. package/src/shade/renderer/postprocess/nss/NSS.d.ts.map +1 -1
  489. package/src/shade/renderer/postprocess/nss/NSS.js +4 -3
  490. package/src/shade/renderer/postprocess/ssr/SSR.d.ts +7 -1
  491. package/src/shade/renderer/postprocess/ssr/SSR.d.ts.map +1 -1
  492. package/src/shade/renderer/postprocess/ssr/SSR.js +16 -0
  493. package/src/shade/renderer/postprocess/ssr/resolve/chunk_ssr_add_hit_irradiance.d.ts +20 -2
  494. package/src/shade/renderer/postprocess/ssr/resolve/chunk_ssr_add_hit_irradiance.d.ts.map +1 -1
  495. package/src/shade/renderer/postprocess/ssr/resolve/chunk_ssr_add_hit_irradiance.js +53 -3
  496. package/src/shade/renderer/postprocess/ssr/resolve/chunk_ssr_sample_radiance.d.ts +10 -2
  497. package/src/shade/renderer/postprocess/ssr/resolve/chunk_ssr_sample_radiance.d.ts.map +1 -1
  498. package/src/shade/renderer/postprocess/ssr/resolve/chunk_ssr_sample_radiance.js +31 -3
  499. package/src/shade/renderer/postprocess/ssr/resolve/ssr_resolve_shader.d.ts.map +1 -1
  500. package/src/shade/renderer/postprocess/ssr/resolve/ssr_resolve_shader.js +17 -11
  501. package/src/shade/renderer/postprocess/taa/TAA.d.ts +4 -2
  502. package/src/shade/renderer/postprocess/taa/TAA.d.ts.map +1 -1
  503. package/src/shade/renderer/postprocess/taa/TAA.js +6 -1
  504. package/src/shade/renderer/postprocess/taa/chunk_fsr2_compute_depth_clip.d.ts.map +1 -1
  505. package/src/shade/renderer/postprocess/taa/chunk_fsr2_compute_depth_clip.js +10 -5
  506. package/src/shade/renderer/postprocess/taa/shader_taa.d.ts.map +1 -1
  507. package/src/shade/renderer/postprocess/taa/shader_taa.js +15 -12
  508. package/src/shade/renderer/postprocess/velocity/graph_add_per_object_velocity.d.ts.map +1 -1
  509. package/src/shade/renderer/postprocess/velocity/graph_add_per_object_velocity.js +26 -17
  510. package/src/shade/renderer/rasterize/forward/chunk_forward_sample_indirect.d.ts +4 -3
  511. package/src/shade/renderer/rasterize/forward/chunk_forward_sample_indirect.d.ts.map +1 -1
  512. package/src/shade/renderer/rasterize/forward/chunk_forward_sample_indirect.js +6 -4
  513. package/src/shade/renderer/rasterize/forward/chunk_forward_sample_indirect_probe_clipmap.d.ts +12 -0
  514. package/src/shade/renderer/rasterize/forward/chunk_forward_sample_indirect_probe_clipmap.d.ts.map +1 -0
  515. package/src/shade/renderer/rasterize/forward/chunk_forward_sample_indirect_probe_clipmap.js +57 -0
  516. package/src/shade/renderer/rasterize/native/avboit/AVBOITSideChannel.d.ts +4 -2
  517. package/src/shade/renderer/rasterize/native/avboit/AVBOITSideChannel.d.ts.map +1 -1
  518. package/src/shade/renderer/rasterize/native/avboit/AVBOITSideChannel.js +4 -2
  519. package/src/shade/renderer/rasterize/native/avboit/graph_rasterize_meshes_transparent_avboit.d.ts +8 -2
  520. package/src/shade/renderer/rasterize/native/avboit/graph_rasterize_meshes_transparent_avboit.d.ts.map +1 -1
  521. package/src/shade/renderer/rasterize/native/avboit/graph_rasterize_meshes_transparent_avboit.js +28 -15
  522. package/src/shade/renderer/rasterize/native/avboit/shader_avboit_draw.d.ts +2 -1
  523. package/src/shade/renderer/rasterize/native/avboit/shader_avboit_draw.d.ts.map +1 -1
  524. package/src/shade/renderer/rasterize/native/avboit/shader_avboit_draw.js +19 -3
  525. package/src/shade/renderer/rasterize/native/graph_rasterize_meshes_alpha_tested.d.ts.map +1 -1
  526. package/src/shade/renderer/rasterize/native/graph_rasterize_meshes_alpha_tested.js +4 -2
  527. package/src/shade/renderer/rasterize/native/oit/graph_rasterize_meshes_transparent_oit.d.ts +3 -1
  528. package/src/shade/renderer/rasterize/native/oit/graph_rasterize_meshes_transparent_oit.d.ts.map +1 -1
  529. package/src/shade/renderer/rasterize/native/oit/graph_rasterize_meshes_transparent_oit.js +27 -14
  530. package/src/shade/renderer/rasterize/native/oit/shader_oit_resolve_moments.d.ts +2 -1
  531. package/src/shade/renderer/rasterize/native/oit/shader_oit_resolve_moments.d.ts.map +1 -1
  532. package/src/shade/renderer/rasterize/native/oit/shader_oit_resolve_moments.js +19 -3
  533. package/src/shade/renderer/shader/chunk/geometry/meshlet/chunk_read_meshlet_triangle_bounds.d.ts +2 -8
  534. package/src/shade/renderer/shader/chunk/geometry/meshlet/chunk_read_meshlet_triangle_bounds.d.ts.map +1 -1
  535. package/src/shade/renderer/shader/chunk/geometry/meshlet/chunk_read_meshlet_triangle_bounds.js +25 -52
  536. package/src/shade/renderer/shader/chunk/geometry/meshlet/chunk_read_meshlet_triangle_positions.d.ts +15 -0
  537. package/src/shade/renderer/shader/chunk/geometry/meshlet/chunk_read_meshlet_triangle_positions.d.ts.map +1 -0
  538. package/src/shade/renderer/shader/chunk/geometry/meshlet/chunk_read_meshlet_triangle_positions.js +52 -0
  539. package/src/shade/renderer/shader/chunk/geometry/triangle/TRIANGLE_POSITIONS_STRUCT.d.ts +7 -0
  540. package/src/shade/renderer/shader/chunk/geometry/triangle/TRIANGLE_POSITIONS_STRUCT.d.ts.map +1 -0
  541. package/src/shade/renderer/shader/chunk/geometry/triangle/TRIANGLE_POSITIONS_STRUCT.js +12 -0
  542. package/src/shade/renderer/shader/chunk/grid/chunk_index_to_grid2d_reciprocal.d.ts +22 -0
  543. package/src/shade/renderer/shader/chunk/grid/chunk_index_to_grid2d_reciprocal.d.ts.map +1 -0
  544. package/src/shade/renderer/shader/chunk/grid/chunk_index_to_grid2d_reciprocal.js +37 -0
  545. package/src/shade/renderer/shader/chunk/light/lpv/depth/chunk_lpv_mask_weights_by_visibility.d.ts.map +1 -1
  546. package/src/shade/renderer/shader/chunk/light/lpv/depth/chunk_lpv_mask_weights_by_visibility.js +26 -60
  547. package/src/shade/renderer/shader/chunk/light/probe/chunk_probe_visibility_weight.d.ts +23 -0
  548. package/src/shade/renderer/shader/chunk/light/probe/chunk_probe_visibility_weight.d.ts.map +1 -0
  549. package/src/shade/renderer/shader/chunk/light/probe/chunk_probe_visibility_weight.js +54 -0
  550. package/src/shade/renderer/shader/chunk/math/chunk_f16_round_stochastic.d.ts +25 -0
  551. package/src/shade/renderer/shader/chunk/math/chunk_f16_round_stochastic.d.ts.map +1 -0
  552. package/src/shade/renderer/shader/chunk/math/chunk_f16_round_stochastic.js +43 -0
  553. package/src/shade/renderer/shader/chunk/random/chunk_jitter_from_vectors.d.ts +14 -0
  554. package/src/shade/renderer/shader/chunk/random/chunk_jitter_from_vectors.d.ts.map +1 -0
  555. package/src/shade/renderer/shader/chunk/random/chunk_jitter_from_vectors.js +37 -0
  556. package/src/shade/renderer/shader/chunk/random/reservoir/chunk_pick2_wrs_mat2x4.d.ts +27 -0
  557. package/src/shade/renderer/shader/chunk/random/reservoir/chunk_pick2_wrs_mat2x4.d.ts.map +1 -0
  558. package/src/shade/renderer/shader/chunk/random/reservoir/chunk_pick2_wrs_mat2x4.js +61 -0
  559. package/src/shade/renderer/shader/chunk/spherical_harmonics/l1i/chunk_resolve_irradiance_sh_to_specular.d.ts +21 -0
  560. package/src/shade/renderer/shader/chunk/spherical_harmonics/l1i/chunk_resolve_irradiance_sh_to_specular.d.ts.map +1 -0
  561. package/src/shade/renderer/shader/chunk/spherical_harmonics/l1i/chunk_resolve_irradiance_sh_to_specular.js +41 -0
  562. package/src/shade/renderer/texture/util/texture_fill_rectangle.d.ts.map +1 -1
  563. package/src/shade/renderer/texture/util/texture_fill_rectangle.js +282 -267
  564. package/src/shade/renderer/volumetrics/GPUViewVolumetrics.d.ts +8 -4
  565. package/src/shade/renderer/volumetrics/GPUViewVolumetrics.d.ts.map +1 -1
  566. package/src/shade/renderer/volumetrics/GPUViewVolumetrics.js +36 -36
  567. package/src/shade/renderer/volumetrics/irradiance_clipmap/GPUIrradianceClipmap.d.ts +6 -1
  568. package/src/shade/renderer/volumetrics/irradiance_clipmap/GPUIrradianceClipmap.d.ts.map +1 -1
  569. package/src/shade/renderer/volumetrics/irradiance_clipmap/GPUIrradianceClipmap.js +498 -484
  570. package/src/shade/renderer/volumetrics/irradiance_clipmap/chunk_irradiance_clipmap_gi_sample.d.ts +15 -2
  571. package/src/shade/renderer/volumetrics/irradiance_clipmap/chunk_irradiance_clipmap_gi_sample.d.ts.map +1 -1
  572. package/src/shade/renderer/volumetrics/irradiance_clipmap/chunk_irradiance_clipmap_gi_sample.js +57 -3
  573. package/src/shade/renderer/volumetrics/irradiance_clipmap/shader_irradiance_clipmap_build.d.ts.map +1 -1
  574. package/src/shade/renderer/volumetrics/irradiance_clipmap/shader_irradiance_clipmap_build.js +197 -191
  575. package/src/shade/renderer/volumetrics/taa/shader_volumetrics_taa.js +4 -4
  576. package/src/shade/renderer/water/GPUWaterRenderer.d.ts +2 -1
  577. package/src/shade/renderer/water/GPUWaterRenderer.d.ts.map +1 -1
  578. package/src/shade/renderer/water/GPUWaterRenderer.js +5 -1
  579. package/src/shade/renderer/water/chunk_water_gi.d.ts +13 -3
  580. package/src/shade/renderer/water/chunk_water_gi.d.ts.map +1 -1
  581. package/src/shade/renderer/water/chunk_water_gi.js +47 -5
  582. package/src/shade/renderer/water/query/GPUWaterQueries.d.ts +1 -1
  583. package/src/shade/renderer/water/shader_water.d.ts +3 -2
  584. package/src/shade/renderer/water/shader_water.d.ts.map +1 -1
  585. package/src/shade/renderer/water/shader_water.js +9 -3
  586. package/src/shade/renderer/geometry/sdf/SDF_BUILD_SETTINGS_STRUCT.d.ts +0 -3
  587. package/src/shade/renderer/geometry/sdf/SDF_BUILD_SETTINGS_STRUCT.d.ts.map +0 -1
  588. package/src/shade/renderer/geometry/sdf/SFD_BUILD_WORKGROUP_SIZE.d.ts +0 -2
  589. package/src/shade/renderer/geometry/sdf/SFD_BUILD_WORKGROUP_SIZE.d.ts.map +0 -1
  590. package/src/shade/renderer/geometry/sdf/chunk_blas_query_sdf.d.ts +0 -8
  591. package/src/shade/renderer/geometry/sdf/chunk_blas_query_sdf.d.ts.map +0 -1
  592. package/src/shade/renderer/geometry/sdf/chunk_blas_query_volume_sign.d.ts +0 -3
  593. package/src/shade/renderer/geometry/sdf/chunk_blas_query_volume_sign.d.ts.map +0 -1
  594. package/src/shade/renderer/geometry/sdf/shader_build_sdf.d.ts +0 -3
  595. package/src/shade/renderer/geometry/sdf/shader_build_sdf.d.ts.map +0 -1
  596. package/src/shade/renderer/global_illumination/probe_clipmap/brick/mesh/chunk_mesh_brick_object.d.ts.map +0 -1
  597. package/src/shade/renderer/global_illumination/probe_clipmap/brick/mesh/chunk_mesh_brick_object.js +0 -42
  598. package/src/shade/renderer/particles/shaders/shader_particle_init_free_list.d.ts +0 -31
  599. package/src/shade/renderer/particles/shaders/shader_particle_init_free_list.d.ts.map +0 -1
  600. package/src/shade/renderer/shadow/vsm/VSMMoverTracker.d.ts +0 -42
  601. package/src/shade/renderer/shadow/vsm/VSMMoverTracker.d.ts.map +0 -1
  602. package/src/shade/renderer/shadow/vsm/VSM_MOVER_LAYOUT.d.ts +0 -54
  603. package/src/shade/renderer/shadow/vsm/VSM_MOVER_LAYOUT.d.ts.map +0 -1
  604. package/src/shade/renderer/shadow/vsm/shader/chunk_vsm_append_mover.d.ts +0 -14
  605. package/src/shade/renderer/shadow/vsm/shader/chunk_vsm_append_mover.d.ts.map +0 -1
  606. package/src/shade/renderer/shadow/vsm/shader/shader_vsm_movers.d.ts +0 -30
  607. package/src/shade/renderer/shadow/vsm/shader/shader_vsm_movers.d.ts.map +0 -1
  608. package/src/shade/renderer/shadow/vsm/shader/shader_vsm_skinned_movers.d.ts +0 -23
  609. package/src/shade/renderer/shadow/vsm/shader/shader_vsm_skinned_movers.d.ts.map +0 -1
@@ -2,10 +2,14 @@ import { assert } from "../../../../core/assert.js";
2
2
  import { Allocation, ALLOCATOR_NO_SPACE, OffsetAllocator } from "../../../../core/binary/allocator/OffsetAllocator.js";
3
3
  import { HashMap } from "../../../../core/collection/map/HashMap.js";
4
4
  import {
5
+ PARTICLE_GLOBAL_FIELD_WORDS,
5
6
  PARTICLE_PROGRAM_CODE_BASE_WORD,
7
+ PARTICLE_PROGRAM_FIELD_BASE_WORD,
6
8
  PARTICLE_PROGRAM_HEADER_WORDS,
7
9
  PARTICLE_VM_INSTRUCTION_WORDS,
8
10
  } from "../ParticleConstants.js";
11
+ import { particle_link_global_fields } from "../isa/particle_link_global_fields.js";
12
+ import { ParticleGlobalFields } from "./ParticleGlobalFields.js";
9
13
  import { ProgramPlacement } from "./ProgramPlacement.js";
10
14
 
11
15
  /**
@@ -22,8 +26,15 @@ const INITIAL_CODE_CAPACITY = 128;
22
26
  const INITIAL_CONSTANT_CAPACITY = 128;
23
27
 
24
28
  /**
25
- * Ranges an allocator can describe at once, to begin with. Each live program costs one, plus one for
26
- * the free remainder, and this grows with the set — it is a floor, not a ceiling.
29
+ * Words the field section starts out able to hold: the global reservation, and as much again for
30
+ * emitter blocks.
31
+ * @type {number}
32
+ */
33
+ const INITIAL_FIELD_CAPACITY = PARTICLE_GLOBAL_FIELD_WORDS * 2;
34
+
35
+ /**
36
+ * Ranges an allocator can describe at once, to begin with. Each live program or field block costs
37
+ * one, plus one for the free remainder, and this grows with the set — it is a floor, not a ceiling.
27
38
  * @type {number}
28
39
  */
29
40
  const INITIAL_ALLOCATION_CAPACITY = 32;
@@ -45,17 +56,18 @@ const EMPTY_WORDS = new Uint32Array(0);
45
56
  const EMPTY_ALLOCATION = Object.freeze(Allocation.from(0, ALLOCATOR_NO_SPACE));
46
57
 
47
58
  /**
48
- * One of the two sections of the packed buffer: a flat word array, and the
59
+ * One section of the packed buffer — constants, code or fields: a flat word array, and the
49
60
  * {@link ../../../../core/binary/allocator/OffsetAllocator.js OffsetAllocator} that says which parts
50
61
  * of it are in use.
51
62
  *
52
63
  * The unit is the ELEMENT, not the word — instructions for the code section, words for the constant
53
- * pool — because that is the unit the emitter record's offsets are in. `stride` is what converts.
64
+ * pool and the field section — because that is the unit the emitter record's offsets are in.
65
+ * `stride` is what converts.
54
66
  */
55
67
  class ProgramRegion {
56
68
 
57
69
  /**
58
- * Words per element: {@link PARTICLE_VM_INSTRUCTION_WORDS} for code, 1 for constants.
70
+ * Words per element: {@link PARTICLE_VM_INSTRUCTION_WORDS} for code, 1 for constants and fields.
59
71
  * @type {number}
60
72
  */
61
73
  stride;
@@ -67,7 +79,7 @@ class ProgramRegion {
67
79
 
68
80
  /**
69
81
  * The section's words, `capacity * stride` of them. Words outside a live allocation hold
70
- * whatever the program that used to be there left — nothing addresses them.
82
+ * whatever their last tenant left — nothing addresses them.
71
83
  * @type {Uint32Array}
72
84
  */
73
85
  words = EMPTY_WORDS;
@@ -89,7 +101,7 @@ class ProgramRegion {
89
101
 
90
102
  /**
91
103
  * Throw away every allocation and start again at `capacity` elements. The words go with them —
92
- * the caller is expected to write each surviving program back into its new range.
104
+ * the caller is expected to write each survivor back into its new range.
93
105
  *
94
106
  * @param {number} capacity elements
95
107
  * @param {number} max_allocations ranges the allocator can describe at once
@@ -145,21 +157,49 @@ class ProgramRegion {
145
157
  }
146
158
  }
147
159
 
160
+ /**
161
+ * One emitter's block of emitter fields in the heap's field section: an instance's own data, laid
162
+ * out by its effect's {@link ../layout/ParticleLayout.js ParticleLayout.emitter}.
163
+ *
164
+ * Held by the emitter's context and mutated in place by the heap when a repack moves it, as a
165
+ * {@link ./ProgramPlacement.js ProgramPlacement} is — a copy of {@link FieldBlock#offset} would go
166
+ * stale.
167
+ */
168
+ export class FieldBlock {
169
+ /**
170
+ * First word of the block, counted from the field section's base — what the emitter record's
171
+ * `field_offset` carries.
172
+ * @type {number}
173
+ */
174
+ offset = 0;
175
+
176
+ /**
177
+ * @type {number}
178
+ */
179
+ word_count = 0;
180
+
181
+ /**
182
+ * The range the field section's allocator gave it; `null` for an empty or released block.
183
+ * @type {Allocation|null}
184
+ */
185
+ allocation = null;
186
+ }
187
+
148
188
  /**
149
189
  * Holds every distinct compiled {@link ../isa/ParticleProgram.js ParticleProgram} the emitter set
150
- * runs, packs them into one buffer — a header, every constant pool, then every instruction stream —
151
- * and hands back the {@link ./ProgramPlacement.js placement} each emitter records.
190
+ * runs, packs them into one buffer — a header, every constant pool, every instruction stream, then
191
+ * the field values — and hands back the {@link ./ProgramPlacement.js placement} each emitter records.
152
192
  *
153
193
  * Data before code, behind a four-word header whose first word says where the code starts: the VM
154
- * reads both sections through one binding (a storage buffer per stage is not free, and code and
194
+ * reads every section through one binding (a storage buffer per stage is not free, and code and
155
195
  * constants are read together), and an emitter's constant pool sits next to the pools of the
156
196
  * programs it shares a wave with.
157
197
  *
158
198
  * **Programs are placed, not appended.** Each section is a range allocator
159
199
  * ({@link ../../../../core/binary/allocator/OffsetAllocator.js}) over a flat word array, so a
160
- * program that is no longer wanted gives its space back and the next one takes it. This is what the
161
- * emitter table has always been able to do, and what the packed buffer could not: an authoring
162
- * session that adds, edits and drops effects for an hour no longer grows the buffer for an hour.
200
+ * program that is no longer wanted gives its space back and the next one takes it, as a row of the
201
+ * emitter table does: an authoring session that adds, edits and drops effects for an hour does not
202
+ * grow the buffer for an hour.
163
203
  *
164
204
  * Because VM instructions carry no absolute code addresses (control flow is branchless) and constant
165
205
  * references are program-local (the VM adds the emitter's `constant_offset`), a program is
@@ -177,25 +217,40 @@ class ProgramRegion {
177
217
  *
178
218
  * **Sharing is what makes {@link ProgramHeap#release} a reference count** rather than a delete: the
179
219
  * last emitter of an effect frees it, and the ones before it do not.
220
+ *
221
+ * **Fields come after the code**: `[header][constants][code][fields]`. A program is a class and an
222
+ * emitter an instance of it, so the code and constants are shared and the fields are not — every
223
+ * emitter whose effect declares emitter fields has a {@link FieldBlock} of its own, allocated by the
224
+ * same kind of range allocator and repacked the same way. The section opens with
225
+ * {@link ../ParticleConstants.js PARTICLE_GLOBAL_FIELD_WORDS} reserved for global fields, so those
226
+ * are addressed from zero and never move. Header word
227
+ * {@link ../ParticleConstants.js PARTICLE_PROGRAM_FIELD_BASE_WORD} says where the section starts.
228
+ *
229
+ * Field values change with gameplay where code changes with authoring, so a value change does not
230
+ * move {@link ProgramHeap#version}: the section is written back by span instead, and
231
+ * {@link ProgramHeap#fields_dirty_begin} and {@link ProgramHeap#fields_dirty_end} bound what changed
232
+ * since the buffer was last built or the span last cleared.
180
233
  */
181
234
  export class ProgramHeap {
182
235
 
183
236
  /**
184
237
  * Bumped whenever the packed buffer would come out different from the last one
185
- * {@link ProgramHeap#build_buffer} produced — a program was placed, or the sections were
186
- * repacked. A holder that uploads the buffer re-uploads when this moves.
238
+ * {@link ProgramHeap#build_buffer} produced — a program was placed, or a section was repacked.
239
+ * A holder that uploads the buffer re-uploads when this moves.
187
240
  *
188
- * Releasing a program does NOT move it. The words it occupied are dead rather than changed, and
189
- * re-uploading the buffer to remove bytes nothing addresses would be a rebuild for nothing; the
190
- * next program placed there is what makes the buffer differ, and that bumps this.
241
+ * Placing a field block or writing field values does NOT move it: those words go out by the
242
+ * dirty span ({@link ProgramHeap#fields_dirty}). Nor does releasing a program or a block. The
243
+ * words it occupied are dead rather than changed, and re-uploading the buffer to remove bytes
244
+ * nothing addresses would be a rebuild for nothing; whatever is placed there next sends them.
191
245
  *
192
246
  * @type {number}
193
247
  */
194
248
  version = 0;
195
249
 
196
250
  /**
197
- * Bumped when a repack moved programs that were already placed — every existing placement now
198
- * holds different offsets, so every emitter record built from one is out of date.
251
+ * Bumped when a repack moved programs or field blocks that were already placed — every existing
252
+ * placement or block now holds different offsets, so every emitter record built from one is out
253
+ * of date.
199
254
  *
200
255
  * Separate from {@link ProgramHeap#version} because the two ask for different work: that one
201
256
  * says "upload the buffer again", this one says "restage every row". A repack moves both; an
@@ -223,6 +278,42 @@ export class ProgramHeap {
223
278
  */
224
279
  #constants = new ProgramRegion(1);
225
280
 
281
+ /**
282
+ * Global fields, then every emitter's block.
283
+ * @type {ProgramRegion}
284
+ */
285
+ #fields = new ProgramRegion(1);
286
+
287
+ /**
288
+ * Every live non-empty block, so a repack can move them.
289
+ * @type {Set<FieldBlock>}
290
+ */
291
+ #field_blocks = new Set();
292
+
293
+ /**
294
+ * First word of the field section changed since the buffer was built or the span cleared; with
295
+ * {@link ProgramHeap#fields_dirty_end}, an empty range when nothing did.
296
+ * @type {number}
297
+ */
298
+ fields_dirty_begin = 0;
299
+
300
+ /**
301
+ * One past the last word of the field section changed.
302
+ * @type {number}
303
+ */
304
+ fields_dirty_end = 0;
305
+
306
+ /**
307
+ * The system's global fields: the layout programs are linked against as they are placed, and
308
+ * the values, in the words reserved at the start of the field section.
309
+ *
310
+ * @type {ParticleGlobalFields}
311
+ */
312
+ global_fields = new ParticleGlobalFields((index, bits) => {
313
+ this.#fields.words[index] = bits;
314
+ this.#mark_fields_dirty(index, index + 1);
315
+ });
316
+
226
317
  /**
227
318
  * Id the next program gets when {@link ProgramHeap##free_program_ids} is empty. Also the number
228
319
  * of id slots that have ever been in use at once, which is what
@@ -249,6 +340,227 @@ export class ProgramHeap {
249
340
  constructor() {
250
341
  this.#code.reset(INITIAL_CODE_CAPACITY, INITIAL_ALLOCATION_CAPACITY);
251
342
  this.#constants.reset(INITIAL_CONSTANT_CAPACITY, INITIAL_ALLOCATION_CAPACITY);
343
+ this.#reset_fields(INITIAL_FIELD_CAPACITY, INITIAL_ALLOCATION_CAPACITY);
344
+ }
345
+
346
+ /**
347
+ * The field section's words, global fields first. What {@link ProgramHeap#fields_dirty_begin}
348
+ * and {@link ProgramHeap#fields_dirty_end} index.
349
+ *
350
+ * A repack replaces the array, so read it again after any {@link ProgramHeap#acquire_fields}.
351
+ *
352
+ * @returns {Uint32Array}
353
+ */
354
+ get field_words() {
355
+ return this.#fields.words;
356
+ }
357
+
358
+ /**
359
+ * The word of the packed buffer the field section starts at — what header word
360
+ * {@link ../ParticleConstants.js PARTICLE_PROGRAM_FIELD_BASE_WORD} holds.
361
+ * @returns {number}
362
+ */
363
+ get field_base_word() {
364
+ return PARTICLE_PROGRAM_HEADER_WORDS + this.#constants.words.length + this.#code.words.length;
365
+ }
366
+
367
+ /**
368
+ * @returns {boolean} whether any field words changed since the buffer was built or the span cleared
369
+ */
370
+ get fields_dirty() {
371
+ return this.fields_dirty_end > this.fields_dirty_begin;
372
+ }
373
+
374
+ /**
375
+ * Mark words of the field section for upload as they stand on the CPU, without changing them —
376
+ * for a word a transform binding was writing on the GPU, whose CPU value holds again once the
377
+ * binding is gone.
378
+ *
379
+ * @param {number} begin
380
+ * @param {number} end
381
+ */
382
+ resend_fields(begin, end) {
383
+ this.#mark_fields_dirty(begin, end);
384
+ }
385
+
386
+ /**
387
+ * Say the changed span has been written to the device.
388
+ */
389
+ clear_fields_dirty() {
390
+ this.fields_dirty_begin = 0;
391
+ this.fields_dirty_end = 0;
392
+ }
393
+
394
+ /**
395
+ * A block of `word_count` words for one emitter's emitter fields. Its contents are undefined
396
+ * until {@link ProgramHeap#write_fields}.
397
+ *
398
+ * Placing it may repack the field section, which moves every block and so moves
399
+ * {@link ProgramHeap#placement_version} (every emitter record carries its block's offset) and
400
+ * {@link ProgramHeap#version}.
401
+ *
402
+ * @param {number} word_count
403
+ * @returns {FieldBlock} never `null`; a zero-word block holds no allocation
404
+ */
405
+ acquire_fields(word_count) {
406
+ assert.isNonNegativeInteger(word_count, 'word_count');
407
+
408
+ const block = new FieldBlock();
409
+
410
+ block.word_count = word_count;
411
+
412
+ if (word_count === 0) {
413
+ return block;
414
+ }
415
+
416
+ if (!this.#try_place_fields(block)) {
417
+ this.#repack_fields(word_count);
418
+
419
+ const placed = this.#try_place_fields(block);
420
+
421
+ assert.ok(placed, 'a repacked field section had no room for the block it was repacked for');
422
+ }
423
+
424
+ this.#field_blocks.add(block);
425
+
426
+ return block;
427
+ }
428
+
429
+ /**
430
+ * Give a block back. Releasing one twice, or an empty one, does nothing.
431
+ * @param {FieldBlock} block
432
+ */
433
+ release_fields(block) {
434
+ assert.defined(block, 'block');
435
+
436
+ if (block.allocation === null) {
437
+ return;
438
+ }
439
+
440
+ this.#fields.free(block.allocation);
441
+ this.#field_blocks.delete(block);
442
+
443
+ block.allocation = null;
444
+ }
445
+
446
+ /**
447
+ * Write an emitter's field values into its block — `words` from the start, and zero for the rest
448
+ * of the block, so a block that held a previous tenant's values never shows them — and mark the
449
+ * block for upload.
450
+ *
451
+ * @param {FieldBlock} block
452
+ * @param {Uint32Array} words f32 bit patterns, at most {@link FieldBlock#word_count} of them
453
+ */
454
+ write_fields(block, words) {
455
+ assert.lessThanOrEqual(words.length, block.word_count, 'words.length');
456
+
457
+ if (block.word_count === 0) {
458
+ return;
459
+ }
460
+
461
+ const target = this.#fields.words;
462
+ const begin = block.offset;
463
+ const end = begin + block.word_count;
464
+
465
+ // Never past the block, whatever the caller handed over: the next block is somebody
466
+ // else's, and the assert above is stripped from a shipped build.
467
+ const count = Math.min(words.length, block.word_count);
468
+
469
+ for (let i = 0; i < count; i++) {
470
+ target[begin + i] = words[i];
471
+ }
472
+
473
+ target.fill(0, begin + count, end);
474
+
475
+ this.#mark_fields_dirty(begin, end);
476
+ }
477
+
478
+ /**
479
+ * @param {number} begin
480
+ * @param {number} end
481
+ */
482
+ #mark_fields_dirty(begin, end) {
483
+ if (!this.fields_dirty) {
484
+ this.fields_dirty_begin = begin;
485
+ this.fields_dirty_end = end;
486
+ return;
487
+ }
488
+
489
+ this.fields_dirty_begin = Math.min(this.fields_dirty_begin, begin);
490
+ this.fields_dirty_end = Math.max(this.fields_dirty_end, end);
491
+ }
492
+
493
+ /**
494
+ * Start the field section over at `capacity` words with nothing in it but the global
495
+ * reservation, which the first allocation of a fresh allocator puts at offset zero.
496
+ *
497
+ * @param {number} capacity
498
+ * @param {number} max_allocations
499
+ */
500
+ #reset_fields(capacity, max_allocations) {
501
+ this.#fields.reset(capacity, max_allocations);
502
+
503
+ const globals = this.#fields.allocate(PARTICLE_GLOBAL_FIELD_WORDS);
504
+
505
+ assert.ok(globals !== null && globals.offset === 0, 'the global field reservation must open the field section');
506
+ }
507
+
508
+ /**
509
+ * @param {FieldBlock} block
510
+ * @returns {boolean} whether it fit
511
+ */
512
+ #try_place_fields(block) {
513
+ const allocation = this.#fields.allocate(block.word_count);
514
+
515
+ if (allocation === null) {
516
+ return false;
517
+ }
518
+
519
+ block.allocation = allocation;
520
+ block.offset = allocation.offset;
521
+
522
+ return true;
523
+ }
524
+
525
+ /**
526
+ * Lay the field section out again with room for the blocks it holds plus one of
527
+ * `extra_words`, keeping every word: the global fields where they were, and each block's values
528
+ * moved with it.
529
+ *
530
+ * @param {number} extra_words
531
+ */
532
+ #repack_fields(extra_words) {
533
+ const previous = this.#fields.words;
534
+
535
+ let required = PARTICLE_GLOBAL_FIELD_WORDS + extra_words;
536
+
537
+ for (const block of this.#field_blocks) {
538
+ required += block.word_count;
539
+ }
540
+
541
+ const max_allocations = Math.max(INITIAL_ALLOCATION_CAPACITY, (this.#field_blocks.size + 3) * 2);
542
+
543
+ this.#reset_fields(
544
+ grown_capacity(this.#fields.capacity, required, INITIAL_FIELD_CAPACITY),
545
+ max_allocations
546
+ );
547
+
548
+ const words = this.#fields.words;
549
+
550
+ words.set(previous.subarray(0, PARTICLE_GLOBAL_FIELD_WORDS), 0);
551
+
552
+ for (const block of this.#field_blocks) {
553
+ const from = block.offset;
554
+
555
+ const placed = this.#try_place_fields(block);
556
+
557
+ assert.ok(placed, 'a freshly reset field section had no room for a block it already held');
558
+
559
+ words.set(previous.subarray(from, from + block.word_count), block.offset);
560
+ }
561
+
562
+ this.placement_version++;
563
+ this.version++;
252
564
  }
253
565
 
254
566
  /**
@@ -303,8 +615,12 @@ export class ProgramHeap {
303
615
  * in place when it repacks, so a caller keeps the object rather than copying its fields —
304
616
  * copies go stale, the object does not.
305
617
  *
618
+ * Placing a program declares the global fields it imports. A program whose imports the global
619
+ * layout cannot take is refused before anything is claimed for it.
620
+ *
306
621
  * @param {import("../isa/ParticleProgram.js").ParticleProgram} program
307
622
  * @returns {ProgramPlacement}
623
+ * @throws what {@link ./ParticleGlobalFields.js ParticleGlobalFields#check} throws for its imports
308
624
  */
309
625
  acquire(program) {
310
626
  assert.defined(program, 'program');
@@ -317,6 +633,9 @@ export class ProgramHeap {
317
633
  return existing;
318
634
  }
319
635
 
636
+ // asked first, so a refused program leaves no id, no range and no declaration behind
637
+ this.global_fields.check(program.global_imports);
638
+
320
639
  // The heap keeps its own copy, because this is about to become a hash table key and hash
321
640
  // table keys have to be immutable. A compiled program is treated as immutable everywhere,
322
641
  // but nothing enforces it — the optimizer's passes rewrite these arrays in place — and a
@@ -386,28 +705,37 @@ export class ProgramHeap {
386
705
  }
387
706
 
388
707
  /**
389
- * The packed buffer: `[header][constants][code]`. Word
390
- * {@link ../ParticleConstants.js PARTICLE_PROGRAM_CODE_BASE_WORD} of the header is the word index
391
- * the code starts at — the only absolute address in the buffer, and the reason a placement can
392
- * hold section-relative offsets and survive the sections being resized.
708
+ * The packed buffer: `[header][constants][code][fields]`. Header words
709
+ * {@link ../ParticleConstants.js PARTICLE_PROGRAM_CODE_BASE_WORD} and
710
+ * {@link ../ParticleConstants.js PARTICLE_PROGRAM_FIELD_BASE_WORD} are the word indices the code
711
+ * and the field section start at — the only absolute addresses in the buffer, and the reason a
712
+ * placement or a block can hold section-relative offsets and survive the sections being resized.
393
713
  *
394
- * Both sections come out at their full capacity rather than trimmed to what is live: the offsets
714
+ * Every section comes out at its full capacity rather than trimmed to what is live: the offsets
395
715
  * a placement holds are offsets into the capacity, and trimming would mean moving programs to
396
716
  * close the holes, which is what a repack is for and what a buffer rebuild should not silently
397
717
  * become.
398
718
  *
719
+ * Clears the dirty field span: the whole section goes out with the buffer.
720
+ *
399
721
  * @returns {Uint32Array}
400
722
  */
401
723
  build_buffer() {
402
724
  const constants = this.#constants.words;
403
725
  const code = this.#code.words;
726
+ const fields = this.#fields.words;
404
727
 
405
728
  const code_base = PARTICLE_PROGRAM_HEADER_WORDS + constants.length;
406
- const buffer = new Uint32Array(code_base + code.length);
729
+ const field_base = code_base + code.length;
730
+ const buffer = new Uint32Array(field_base + fields.length);
407
731
 
408
732
  buffer[PARTICLE_PROGRAM_CODE_BASE_WORD] = code_base;
733
+ buffer[PARTICLE_PROGRAM_FIELD_BASE_WORD] = field_base;
409
734
  buffer.set(constants, PARTICLE_PROGRAM_HEADER_WORDS);
410
735
  buffer.set(code, code_base);
736
+ buffer.set(fields, field_base);
737
+
738
+ this.clear_fields_dirty();
411
739
 
412
740
  return buffer;
413
741
  }
@@ -503,12 +831,34 @@ export class ProgramHeap {
503
831
  this.#code.write(placement.update_offset, program.update);
504
832
  this.#constants.write(placement.constant_offset, program.constant_words);
505
833
 
834
+ // Placing a program is what links it: its global reads name imports, and the system's
835
+ // layout says where each one is. The layout is append-only, so a link made here stays
836
+ // right for as long as the program is placed, and a repack makes the same one again.
837
+ const imports = program.global_imports;
838
+
839
+ if (imports.length > 0) {
840
+ const offsets = new Array(imports.length);
841
+
842
+ for (let i = 0; i < imports.length; i++) {
843
+ offsets[i] = this.global_fields.declare(imports[i].name, imports[i].components);
844
+ }
845
+
846
+ const begin = placement.init_offset * PARTICLE_VM_INSTRUCTION_WORDS;
847
+
848
+ particle_link_global_fields(
849
+ this.#code.words,
850
+ begin,
851
+ begin + placement.instruction_count * PARTICLE_VM_INSTRUCTION_WORDS,
852
+ offsets
853
+ );
854
+ }
855
+
506
856
  return true;
507
857
  }
508
858
 
509
859
  /**
510
- * Lay both sections out again from scratch, with room for the programs already held plus one
511
- * more of the given size.
860
+ * Lay the code and constant sections out again from scratch, with room for the programs already
861
+ * held plus one more of the given size.
512
862
  *
513
863
  * This is the only thing that moves a program, and it happens for one of two reasons: a section
514
864
  * has no contiguous run long enough (its free space is there but scattered), or its allocator has
@@ -1,25 +1,37 @@
1
1
  /**
2
- * Compile a particle effect: a per-particle attribute {@link ../layout/ParticleLayout.js} plus INIT
2
+ * Compile a particle effect: a particle field {@link ../layout/ParticleLayout.js} plus INIT
3
3
  * and UPDATE node graphs, lowered to VM bytecode.
4
4
  *
5
- * The two halves come back together because they are compiled together, and an emitter takes both:
6
- * the layout is what a render binding resolves a name against, the program is what the heap packs.
7
- * They are not a value in their own right, so they go into an emitter by being spread —
5
+ * The parts come back together because they are compiled together, and an emitter takes all of
6
+ * them: the layout is what a render binding resolves a name against, the program is what the heap
7
+ * packs, and the emitter layout and values are the instance data the program reads. They are not a
8
+ * value in their own right, so they go into an emitter by being spread —
8
9
  * `ParticleEmitter.from({ ...create_particle_effect({ layout, update }), spawn_rate: 100 })` — and
9
- * the emitter keeps them as two fields rather than as one bag.
10
+ * the emitter keeps them as separate fields rather than as one bag.
10
11
  *
11
12
  * @param {object} params
12
13
  * @param {import("../layout/ParticleLayout.js").ParticleLayout} params.layout
13
14
  * @param {NodeGraph} [params.init]
14
15
  * @param {NodeGraph} [params.update]
15
- * @returns {{ layout: import("../layout/ParticleLayout.js").ParticleLayout, program: import("../isa/ParticleProgram.js").ParticleProgram }}
16
+ * @param {import("../layout/ParticleLayout.js").ParticleLayout|null} [params.emitter_layout] the
17
+ * emitter fields every emitter of the effect carries, from {@link ../layout/ParticleLayout.js ParticleLayout.emitter}
18
+ * @param {ArrayLike<number>} [params.emitter_fields] their values, as f32 bit patterns laid out by
19
+ * `emitter_layout` — the defaults each emitter starts from
20
+ * @param {import("../layout/ParticleLayout.js").ParticleLayout|null} [params.global_layout] the
21
+ * global fields the effect may read, by name; what it does read becomes the program's imports
22
+ * @returns {{ layout: import("../layout/ParticleLayout.js").ParticleLayout, program: import("../isa/ParticleProgram.js").ParticleProgram, emitter_layout: import("../layout/ParticleLayout.js").ParticleLayout|null, emitter_fields: Uint32Array }}
16
23
  */
17
- export function create_particle_effect({ layout, init, update }: {
24
+ export function create_particle_effect({ layout, init, update, emitter_layout, emitter_fields, global_layout }: {
18
25
  layout: import("../layout/ParticleLayout.js").ParticleLayout;
19
26
  init?: NodeGraph;
20
27
  update?: NodeGraph;
28
+ emitter_layout?: import("../layout/ParticleLayout.js").ParticleLayout | null;
29
+ emitter_fields?: ArrayLike<number>;
30
+ global_layout?: import("../layout/ParticleLayout.js").ParticleLayout | null;
21
31
  }): {
22
32
  layout: import("../layout/ParticleLayout.js").ParticleLayout;
23
33
  program: import("../isa/ParticleProgram.js").ParticleProgram;
34
+ emitter_layout: import("../layout/ParticleLayout.js").ParticleLayout | null;
35
+ emitter_fields: Uint32Array;
24
36
  };
25
37
  //# sourceMappingURL=create_particle_effect.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"create_particle_effect.d.ts","sourceRoot":"","sources":["../../../../../../src/shade/renderer/particles/runtime/create_particle_effect.js"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;GAeG;AACH;IALwE,MAAM,EAAnE,OAAO,6BAA6B,EAAE,cAAc;IACjC,IAAI;IACJ,MAAM;IACvB;IAAE,MAAM,EAAE,OAAO,6BAA6B,EAAE,cAAc,CAAC;IAAC,OAAO,EAAE,OAAO,2BAA2B,EAAE,eAAe,CAAA;CAAE,CAK1I"}
1
+ {"version":3,"file":"create_particle_effect.d.ts","sourceRoot":"","sources":["../../../../../../src/shade/renderer/particles/runtime/create_particle_effect.js"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH;IAXwE,MAAM,EAAnE,OAAO,6BAA6B,EAAE,cAAc;IACjC,IAAI;IACJ,MAAM;IAC0C,cAAc,GAAjF,OAAO,6BAA6B,EAAE,cAAc,GAAC,IAAI;IAE9B,cAAc,GAAzC,UAAU,MAAM,CAAC;IAEkD,aAAa,GAAhF,OAAO,6BAA6B,EAAE,cAAc,GAAC,IAAI;IAEvD;IAAE,MAAM,EAAE,OAAO,6BAA6B,EAAE,cAAc,CAAC;IAAC,OAAO,EAAE,OAAO,2BAA2B,EAAE,eAAe,CAAC;IAAC,cAAc,EAAE,OAAO,6BAA6B,EAAE,cAAc,GAAC,IAAI,CAAC;IAAC,cAAc,EAAE,WAAW,CAAA;CAAE,CAWlP"}
@@ -1,22 +1,35 @@
1
1
  import { compile_particle_effect } from "../graph/compile_particle_graph.js";
2
2
 
3
3
  /**
4
- * Compile a particle effect: a per-particle attribute {@link ../layout/ParticleLayout.js} plus INIT
4
+ * Compile a particle effect: a particle field {@link ../layout/ParticleLayout.js} plus INIT
5
5
  * and UPDATE node graphs, lowered to VM bytecode.
6
6
  *
7
- * The two halves come back together because they are compiled together, and an emitter takes both:
8
- * the layout is what a render binding resolves a name against, the program is what the heap packs.
9
- * They are not a value in their own right, so they go into an emitter by being spread —
7
+ * The parts come back together because they are compiled together, and an emitter takes all of
8
+ * them: the layout is what a render binding resolves a name against, the program is what the heap
9
+ * packs, and the emitter layout and values are the instance data the program reads. They are not a
10
+ * value in their own right, so they go into an emitter by being spread —
10
11
  * `ParticleEmitter.from({ ...create_particle_effect({ layout, update }), spawn_rate: 100 })` — and
11
- * the emitter keeps them as two fields rather than as one bag.
12
+ * the emitter keeps them as separate fields rather than as one bag.
12
13
  *
13
14
  * @param {object} params
14
15
  * @param {import("../layout/ParticleLayout.js").ParticleLayout} params.layout
15
16
  * @param {NodeGraph} [params.init]
16
17
  * @param {NodeGraph} [params.update]
17
- * @returns {{ layout: import("../layout/ParticleLayout.js").ParticleLayout, program: import("../isa/ParticleProgram.js").ParticleProgram }}
18
+ * @param {import("../layout/ParticleLayout.js").ParticleLayout|null} [params.emitter_layout] the
19
+ * emitter fields every emitter of the effect carries, from {@link ../layout/ParticleLayout.js ParticleLayout.emitter}
20
+ * @param {ArrayLike<number>} [params.emitter_fields] their values, as f32 bit patterns laid out by
21
+ * `emitter_layout` — the defaults each emitter starts from
22
+ * @param {import("../layout/ParticleLayout.js").ParticleLayout|null} [params.global_layout] the
23
+ * global fields the effect may read, by name; what it does read becomes the program's imports
24
+ * @returns {{ layout: import("../layout/ParticleLayout.js").ParticleLayout, program: import("../isa/ParticleProgram.js").ParticleProgram, emitter_layout: import("../layout/ParticleLayout.js").ParticleLayout|null, emitter_fields: Uint32Array }}
18
25
  */
19
- export function create_particle_effect({ layout, init, update }) {
20
- const program = compile_particle_effect({ init, update, layout });
21
- return { layout, program };
26
+ export function create_particle_effect({ layout, init, update, emitter_layout = null, emitter_fields = [], global_layout = null }) {
27
+ const program = compile_particle_effect({
28
+ init,
29
+ update,
30
+ layout,
31
+ emitter_layout: emitter_layout ?? undefined,
32
+ global_layout: global_layout ?? undefined,
33
+ });
34
+ return { layout, program, emitter_layout, emitter_fields: Uint32Array.from(emitter_fields) };
22
35
  }