@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.
- package/editor/particles/effect/ParticleEffectDocument.d.ts +21 -6
- package/editor/particles/effect/ParticleEffectDocument.d.ts.map +1 -1
- package/editor/particles/effect/ParticleEffectDocument.js +38 -17
- package/editor/view/node-graph/NodeGraphClipboard.d.ts +186 -0
- package/editor/view/node-graph/NodeGraphClipboard.d.ts.map +1 -0
- package/editor/view/node-graph/NodeGraphClipboard.js +231 -0
- package/editor/view/node-graph/NodeGraphEditorView.d.ts +59 -1
- package/editor/view/node-graph/NodeGraphEditorView.d.ts.map +1 -1
- package/editor/view/node-graph/NodeGraphEditorView.js +248 -5
- package/editor/view/node-graph/NodeGraphView.d.ts.map +1 -1
- package/editor/view/node-graph/NodeGraphView.js +84 -8
- package/editor/view/node-graph/actions/connection_bind_actions.d.ts +23 -0
- package/editor/view/node-graph/actions/connection_bind_actions.d.ts.map +1 -0
- package/editor/view/node-graph/actions/connection_bind_actions.js +39 -0
- package/editor/view/particles/effect/ParticleCodeEditorView.d.ts.map +1 -1
- package/editor/view/particles/effect/ParticleCodeEditorView.js +4 -3
- package/editor/view/particles/effect/ParticleCurveEditorView.d.ts +20 -0
- package/editor/view/particles/effect/ParticleCurveEditorView.d.ts.map +1 -0
- package/editor/view/particles/effect/ParticleCurveEditorView.js +574 -0
- package/editor/view/particles/effect/ParticleEmitterInspectorView.d.ts.map +1 -1
- package/editor/view/particles/effect/ParticleEmitterInspectorView.js +27 -1
- package/editor/view/particles/effect/ParticleGradientEditorView.d.ts +24 -0
- package/editor/view/particles/effect/ParticleGradientEditorView.d.ts.map +1 -0
- package/editor/view/particles/effect/ParticleGradientEditorView.js +472 -0
- package/editor/view/particles/effect/ParticleGraphEditorView.d.ts +5 -0
- package/editor/view/particles/effect/ParticleGraphEditorView.d.ts.map +1 -1
- package/editor/view/particles/effect/ParticleGraphEditorView.js +61 -31
- package/editor/view/particles/effect/ParticleNodeParametersView.d.ts.map +1 -1
- package/editor/view/particles/effect/ParticleNodeParametersView.js +33 -0
- package/editor/view/particles/effect/particle-editor.css +123 -35
- package/package.json +1 -1
- package/src/core/binary/allocator/OffsetAllocator.d.ts +25 -16
- package/src/core/binary/allocator/OffsetAllocator.d.ts.map +1 -1
- package/src/core/binary/allocator/OffsetAllocator.js +10 -1
- package/src/core/collection/array/typed/float32_array_hash.d.ts +21 -0
- package/src/core/collection/array/typed/float32_array_hash.d.ts.map +1 -0
- package/src/core/collection/array/typed/float32_array_hash.js +38 -0
- package/src/core/graph/csr/CSRGraph.d.ts +8 -1
- package/src/core/graph/csr/CSRGraph.d.ts.map +1 -1
- package/src/core/graph/csr/CSRGraph.js +14 -6
- package/src/core/model/node-graph/visual/layout/LayoutProblem.d.ts +24 -0
- package/src/core/model/node-graph/visual/layout/LayoutProblem.d.ts.map +1 -1
- package/src/core/model/node-graph/visual/layout/LayoutProblem.js +27 -0
- package/src/core/model/node-graph/visual/layout/NodeGraphLayoutOptions.d.ts +26 -0
- package/src/core/model/node-graph/visual/layout/NodeGraphLayoutOptions.d.ts.map +1 -1
- package/src/core/model/node-graph/visual/layout/NodeGraphLayoutOptions.js +28 -0
- package/src/core/model/node-graph/visual/layout/RouteGrid.d.ts +92 -3
- package/src/core/model/node-graph/visual/layout/RouteGrid.d.ts.map +1 -1
- package/src/core/model/node-graph/visual/layout/RouteGrid.js +405 -242
- package/src/core/model/node-graph/visual/layout/RouteSearch.d.ts +50 -5
- package/src/core/model/node-graph/visual/layout/RouteSearch.d.ts.map +1 -1
- package/src/core/model/node-graph/visual/layout/RouteSearch.js +160 -24
- package/src/core/model/node-graph/visual/layout/RouteSet.d.ts +7 -0
- package/src/core/model/node-graph/visual/layout/RouteSet.d.ts.map +1 -1
- package/src/core/model/node-graph/visual/layout/RouteSet.js +8 -0
- package/src/core/model/node-graph/visual/layout/layout_assign_coordinates.js +9 -3
- package/src/core/model/node-graph/visual/layout/layout_build_problem.d.ts.map +1 -1
- package/src/core/model/node-graph/visual/layout/layout_build_problem.js +7 -0
- package/src/core/model/node-graph/visual/layout/layout_insert_lanes.d.ts +9 -3
- package/src/core/model/node-graph/visual/layout/layout_insert_lanes.d.ts.map +1 -1
- package/src/core/model/node-graph/visual/layout/layout_insert_lanes.js +17 -3
- package/src/core/model/node-graph/visual/layout/layout_node_graph.d.ts +9 -6
- package/src/core/model/node-graph/visual/layout/layout_node_graph.d.ts.map +1 -1
- package/src/core/model/node-graph/visual/layout/layout_node_graph.js +49 -7
- package/src/core/model/node-graph/visual/layout/layout_order_layers.d.ts +11 -1
- package/src/core/model/node-graph/visual/layout/layout_order_layers.d.ts.map +1 -1
- package/src/core/model/node-graph/visual/layout/layout_order_layers.js +135 -16
- package/src/core/model/node-graph/visual/layout/route_connections.d.ts +29 -0
- package/src/core/model/node-graph/visual/layout/route_connections.d.ts.map +1 -1
- package/src/core/model/node-graph/visual/layout/route_connections.js +716 -309
- package/src/core/model/node-graph/visual/layout/route_grid_build.d.ts +3 -2
- package/src/core/model/node-graph/visual/layout/route_grid_build.d.ts.map +1 -1
- package/src/core/model/node-graph/visual/layout/route_grid_build.js +7 -15
- package/src/core/model/node-graph/visual/layout/route_nudge.d.ts +6 -0
- package/src/core/model/node-graph/visual/layout/route_nudge.d.ts.map +1 -1
- package/src/core/model/node-graph/visual/layout/route_nudge.js +42 -13
- package/src/engine/animation/AnimationUtils.js +246 -246
- package/src/engine/animation/Animations.js +74 -74
- package/src/engine/control/first-person/FirstPersonPlayerControllerSystem.js +2078 -2078
- package/src/engine/ecs/EventType.d.ts +0 -1
- package/src/engine/ecs/EventType.js +1 -26
- package/src/engine/ecs/ik/ik_write_local_rotation.d.ts +1 -1
- package/src/engine/ecs/ik/ik_write_local_rotation.d.ts.map +1 -1
- package/src/engine/ecs/ik/ik_write_local_rotation.js +3 -7
- package/src/engine/ecs/parent/EntityNode.d.ts.map +1 -1
- package/src/engine/ecs/parent/EntityNode.js +4 -9
- package/src/engine/ecs/terrain/ecs/cling/ClingToTerrainSystem.d.ts.map +1 -1
- package/src/engine/ecs/terrain/ecs/cling/ClingToTerrainSystem.js +360 -364
- package/src/engine/ecs/transform/TRANSFORM64_EVENT_CHANGE.d.ts +41 -0
- package/src/engine/ecs/transform/TRANSFORM64_EVENT_CHANGE.d.ts.map +1 -0
- package/src/engine/ecs/transform/TRANSFORM64_EVENT_CHANGE.js +40 -0
- package/src/engine/ecs/transform/TRANSFORM64_MIGRATION_PLAN_2026_09_04.md +8 -0
- package/src/engine/ecs/transform/t64_announce_change.d.ts +10 -7
- package/src/engine/ecs/transform/t64_announce_change.d.ts.map +1 -1
- package/src/engine/ecs/transform/t64_announce_change.js +12 -12
- package/src/engine/ecs/transform-attachment/TRANSFORM_ATTACHMENT_EVENT_CHANGE.d.ts +30 -0
- package/src/engine/ecs/transform-attachment/TRANSFORM_ATTACHMENT_EVENT_CHANGE.d.ts.map +1 -0
- package/src/engine/ecs/transform-attachment/TRANSFORM_ATTACHMENT_EVENT_CHANGE.js +29 -0
- package/src/engine/ecs/transform-attachment/TransformAttachmentSystem.d.ts.map +1 -1
- package/src/engine/ecs/transform-attachment/TransformAttachmentSystem.js +13 -21
- package/src/engine/graphics/ecs/sprite/SpriteSystemPE.d.ts.map +1 -1
- package/src/engine/graphics/ecs/sprite/SpriteSystemPE.js +4 -8
- package/src/engine/graphics3/LightSystem.d.ts.map +1 -1
- package/src/engine/graphics3/LightSystem.js +4 -8
- package/src/engine/graphics3/MeshSystem.d.ts.map +1 -1
- package/src/engine/graphics3/MeshSystem.js +9 -19
- package/src/engine/graphics3/ParticleEmitterSystem.d.ts.map +1 -1
- package/src/engine/graphics3/ParticleEmitterSystem.js +4 -8
- package/src/engine/graphics3/ShadedGeometrySystem.d.ts.map +1 -1
- package/src/engine/graphics3/ShadedGeometrySystem.js +4 -10
- package/src/engine/grid/transform2grid/Transform2GridPositionSystem.d.ts +1 -1
- package/src/engine/grid/transform2grid/Transform2GridPositionSystem.d.ts.map +1 -1
- package/src/engine/grid/transform2grid/Transform2GridPositionSystem.js +4 -8
- package/src/engine/intelligence/behavior/ecs/OrbitingBehavior.js +218 -218
- package/src/engine/physics/ecs/PhysicsSystem.d.ts.map +1 -1
- package/src/engine/physics/ecs/PhysicsSystem.js +2 -5
- package/src/engine/sound/ecs/SoundListenerSystem.d.ts.map +1 -1
- package/src/engine/sound/ecs/SoundListenerSystem.js +6 -8
- package/src/engine/sound/simulation/ecs/AcousticSimulationSystem.d.ts +0 -4
- package/src/engine/sound/simulation/ecs/AcousticSimulationSystem.d.ts.map +1 -1
- package/src/engine/sound/simulation/ecs/AcousticSimulationSystem.js +5 -11
- package/src/shade/playground/particle_editor/README.md +43 -2
- package/src/shade/playground/particle_system/particle_prototype.d.ts.map +1 -1
- package/src/shade/playground/particle_system/particle_prototype.js +4 -5
- package/src/shade/playground/particle_system/particle_scene.js +4 -4
- package/src/shade/renderer/Renderer.d.ts.map +1 -1
- package/src/shade/renderer/Renderer.js +13 -1
- package/src/shade/renderer/particles/DESIGN.md +104 -19
- package/src/shade/renderer/particles/GPUParticleSystem.d.ts +64 -50
- package/src/shade/renderer/particles/GPUParticleSystem.d.ts.map +1 -1
- package/src/shade/renderer/particles/GPUParticleSystem.js +176 -78
- package/src/shade/renderer/particles/ParticleConstants.d.ts +59 -23
- package/src/shade/renderer/particles/ParticleConstants.d.ts.map +1 -1
- package/src/shade/renderer/particles/ParticleConstants.js +66 -23
- package/src/shade/renderer/particles/ParticleRenderMode.d.ts +19 -0
- package/src/shade/renderer/particles/ParticleRenderMode.d.ts.map +1 -0
- package/src/shade/renderer/particles/ParticleRenderMode.js +33 -0
- package/src/shade/renderer/particles/data/PARTICLE_EMITTER_STRUCT.d.ts.map +1 -1
- package/src/shade/renderer/particles/data/PARTICLE_EMITTER_STRUCT.js +167 -166
- package/src/shade/renderer/particles/data/particle_emitter_record.d.ts +37 -0
- package/src/shade/renderer/particles/data/particle_emitter_record.d.ts.map +1 -0
- package/src/shade/renderer/particles/data/particle_emitter_record.js +109 -0
- package/src/shade/renderer/particles/graph/ParticleGroupBuilder.d.ts +3 -3
- package/src/shade/renderer/particles/graph/ParticleGroupBuilder.js +303 -303
- package/src/shade/renderer/particles/graph/ParticleNodeDescription.d.ts +18 -0
- package/src/shade/renderer/particles/graph/ParticleNodeDescription.d.ts.map +1 -1
- package/src/shade/renderer/particles/graph/ParticleNodeDescription.js +152 -133
- package/src/shade/renderer/particles/graph/ParticleNodeRegistry.d.ts +0 -11
- package/src/shade/renderer/particles/graph/ParticleNodeRegistry.d.ts.map +1 -1
- package/src/shade/renderer/particles/graph/ParticleNodeRegistry.js +720 -621
- package/src/shade/renderer/particles/graph/compile_particle_graph.d.ts.map +1 -1
- package/src/shade/renderer/particles/graph/compile_particle_graph.js +8 -3
- package/src/shade/renderer/particles/graph/flatten_particle_graph.d.ts.map +1 -1
- package/src/shade/renderer/particles/graph/flatten_particle_graph.js +244 -213
- package/src/shade/renderer/particles/graph/groups/particle_builtin_groups.d.ts.map +1 -1
- package/src/shade/renderer/particles/graph/groups/particle_builtin_groups.js +6 -0
- package/src/shade/renderer/particles/graph/groups/particle_groups_geometry.d.ts.map +1 -1
- package/src/shade/renderer/particles/graph/groups/particle_groups_geometry.js +294 -319
- package/src/shade/renderer/particles/graph/groups/particle_groups_noise.d.ts.map +1 -1
- package/src/shade/renderer/particles/graph/groups/particle_groups_noise.js +524 -517
- package/src/shade/renderer/particles/graph/groups/particle_groups_psrdnoise.d.ts +22 -0
- package/src/shade/renderer/particles/graph/groups/particle_groups_psrdnoise.d.ts.map +1 -0
- package/src/shade/renderer/particles/graph/groups/particle_groups_psrdnoise.js +517 -0
- package/src/shade/renderer/particles/graph/groups/simplex_reference.d.ts.map +1 -1
- package/src/shade/renderer/particles/graph/groups/simplex_reference.js +185 -159
- package/src/shade/renderer/particles/graph/make_particle_group.d.ts.map +1 -1
- package/src/shade/renderer/particles/graph/make_particle_group.js +2 -20
- package/src/shade/renderer/particles/graph/particle_compare_ops.d.ts +17 -0
- package/src/shade/renderer/particles/graph/particle_compare_ops.d.ts.map +1 -0
- package/src/shade/renderer/particles/graph/particle_compare_ops.js +22 -0
- package/src/shade/renderer/particles/graph/particle_graph_diagnostic.d.ts +28 -8
- package/src/shade/renderer/particles/graph/particle_graph_diagnostic.d.ts.map +1 -1
- package/src/shade/renderer/particles/graph/particle_graph_diagnostic.js +49 -25
- package/src/shade/renderer/particles/graph/particle_node_parameters.d.ts +40 -0
- package/src/shade/renderer/particles/graph/particle_node_parameters.d.ts.map +1 -1
- package/src/shade/renderer/particles/graph/particle_node_parameters.js +312 -234
- package/src/shade/renderer/particles/graph/particle_node_presentation.d.ts.map +1 -1
- package/src/shade/renderer/particles/graph/particle_node_presentation.js +59 -3
- package/src/shade/renderer/particles/graph/particle_ramp.d.ts +230 -0
- package/src/shade/renderer/particles/graph/particle_ramp.d.ts.map +1 -0
- package/src/shade/renderer/particles/graph/particle_ramp.js +403 -0
- package/src/shade/renderer/particles/graph/validate_particle_graph.d.ts +7 -1
- package/src/shade/renderer/particles/graph/validate_particle_graph.d.ts.map +1 -1
- package/src/shade/renderer/particles/graph/validate_particle_graph.js +66 -10
- package/src/shade/renderer/particles/graph_particles.d.ts +23 -69
- package/src/shade/renderer/particles/graph_particles.d.ts.map +1 -1
- package/src/shade/renderer/particles/graph_particles.js +105 -262
- package/src/shade/renderer/particles/graph_particles_avboit.d.ts.map +1 -1
- package/src/shade/renderer/particles/graph_particles_avboit.js +3 -2
- package/src/shade/renderer/particles/graph_particles_billboard.d.ts +37 -0
- package/src/shade/renderer/particles/graph_particles_billboard.d.ts.map +1 -0
- package/src/shade/renderer/particles/graph_particles_billboard.js +93 -0
- package/src/shade/renderer/particles/isa/InstructionStream.d.ts +51 -22
- package/src/shade/renderer/particles/isa/InstructionStream.d.ts.map +1 -1
- package/src/shade/renderer/particles/isa/InstructionStream.js +98 -38
- package/src/shade/renderer/particles/isa/ParticleProgram.d.ts +49 -8
- package/src/shade/renderer/particles/isa/ParticleProgram.d.ts.map +1 -1
- package/src/shade/renderer/particles/isa/ParticleProgram.js +95 -150
- package/src/shade/renderer/particles/isa/ParticleVMISA.d.ts +306 -64
- package/src/shade/renderer/particles/isa/ParticleVMISA.d.ts.map +1 -1
- package/src/shade/renderer/particles/isa/ParticleVMISA.js +505 -136
- package/src/shade/renderer/particles/isa/particle_assembly.d.ts +36 -12
- package/src/shade/renderer/particles/isa/particle_assembly.d.ts.map +1 -1
- package/src/shade/renderer/particles/isa/particle_assembly.js +354 -139
- package/src/shade/renderer/particles/isa/validate_particle_program.d.ts +9 -0
- package/src/shade/renderer/particles/isa/validate_particle_program.d.ts.map +1 -0
- package/src/shade/renderer/particles/isa/validate_particle_program.js +128 -0
- package/src/shade/renderer/particles/layout/ParticleLayout.d.ts +23 -0
- package/src/shade/renderer/particles/layout/ParticleLayout.d.ts.map +1 -1
- package/src/shade/renderer/particles/layout/ParticleLayout.js +68 -0
- package/src/shade/renderer/particles/optimizer/dag/optimize_particle_program_vector.d.ts +77 -0
- package/src/shade/renderer/particles/optimizer/dag/optimize_particle_program_vector.d.ts.map +1 -0
- package/src/shade/renderer/particles/optimizer/dag/optimize_particle_program_vector.js +219 -0
- package/src/shade/renderer/particles/optimizer/dag/particle_vector_extract.d.ts +83 -0
- package/src/shade/renderer/particles/optimizer/dag/particle_vector_extract.d.ts.map +1 -0
- package/src/shade/renderer/particles/optimizer/dag/particle_vector_extract.js +283 -0
- package/src/shade/renderer/particles/optimizer/dag/particle_vector_graph.d.ts +133 -0
- package/src/shade/renderer/particles/optimizer/dag/particle_vector_graph.d.ts.map +1 -0
- package/src/shade/renderer/particles/optimizer/dag/particle_vector_graph.js +334 -0
- package/src/shade/renderer/particles/optimizer/dag/particle_vector_groups.d.ts +117 -0
- package/src/shade/renderer/particles/optimizer/dag/particle_vector_groups.d.ts.map +1 -0
- package/src/shade/renderer/particles/optimizer/dag/particle_vector_groups.js +70 -0
- package/src/shade/renderer/particles/optimizer/dag/particle_vector_lift.d.ts +97 -0
- package/src/shade/renderer/particles/optimizer/dag/particle_vector_lift.d.ts.map +1 -0
- package/src/shade/renderer/particles/optimizer/dag/particle_vector_lift.js +462 -0
- package/src/shade/renderer/particles/optimizer/dag/particle_vector_lower.d.ts +116 -0
- package/src/shade/renderer/particles/optimizer/dag/particle_vector_lower.d.ts.map +1 -0
- package/src/shade/renderer/particles/optimizer/dag/particle_vector_lower.js +687 -0
- package/src/shade/renderer/particles/optimizer/dag/particle_vector_pack.d.ts +57 -0
- package/src/shade/renderer/particles/optimizer/dag/particle_vector_pack.d.ts.map +1 -0
- package/src/shade/renderer/particles/optimizer/dag/particle_vector_pack.js +860 -0
- package/src/shade/renderer/particles/optimizer/dag/particle_vector_rules.d.ts +115 -0
- package/src/shade/renderer/particles/optimizer/dag/particle_vector_rules.d.ts.map +1 -0
- package/src/shade/renderer/particles/optimizer/dag/particle_vector_rules.js +264 -0
- package/src/shade/renderer/particles/optimizer/optimize_particle_program.d.ts +81 -42
- package/src/shade/renderer/particles/optimizer/optimize_particle_program.d.ts.map +1 -1
- package/src/shade/renderer/particles/optimizer/optimize_particle_program.js +477 -478
- package/src/shade/renderer/particles/optimizer/particle_integer_bounds.d.ts +100 -0
- package/src/shade/renderer/particles/optimizer/particle_integer_bounds.d.ts.map +1 -0
- package/src/shade/renderer/particles/optimizer/particle_integer_bounds.js +236 -0
- package/src/shade/renderer/particles/optimizer/particle_program_analysis.d.ts +139 -59
- package/src/shade/renderer/particles/optimizer/particle_program_analysis.d.ts.map +1 -1
- package/src/shade/renderer/particles/optimizer/particle_program_analysis.js +764 -647
- package/src/shade/renderer/particles/optimizer/particle_program_equivalence.d.ts +40 -7
- package/src/shade/renderer/particles/optimizer/particle_program_equivalence.d.ts.map +1 -1
- package/src/shade/renderer/particles/optimizer/particle_program_equivalence.js +376 -213
- package/src/shade/renderer/particles/optimizer/particle_program_fuzz.d.ts +30 -3
- package/src/shade/renderer/particles/optimizer/particle_program_fuzz.d.ts.map +1 -1
- package/src/shade/renderer/particles/optimizer/particle_program_fuzz.js +337 -223
- package/src/shade/renderer/particles/optimizer/particle_vm_semantics.d.ts +24 -38
- package/src/shade/renderer/particles/optimizer/particle_vm_semantics.d.ts.map +1 -1
- package/src/shade/renderer/particles/optimizer/particle_vm_semantics.js +166 -206
- package/src/shade/renderer/particles/optimizer/pass_allocate_registers.d.ts +99 -0
- package/src/shade/renderer/particles/optimizer/pass_allocate_registers.d.ts.map +1 -0
- package/src/shade/renderer/particles/optimizer/pass_allocate_registers.js +313 -0
- package/src/shade/renderer/particles/optimizer/pass_dedup_constants.d.ts +3 -2
- package/src/shade/renderer/particles/optimizer/pass_dedup_constants.d.ts.map +1 -1
- package/src/shade/renderer/particles/optimizer/pass_dedup_constants.js +198 -197
- package/src/shade/renderer/particles/optimizer/pass_eliminate_dead_code.d.ts.map +1 -1
- package/src/shade/renderer/particles/optimizer/pass_fold_constants.d.ts +19 -0
- package/src/shade/renderer/particles/optimizer/pass_fold_constants.d.ts.map +1 -1
- package/src/shade/renderer/particles/optimizer/pass_fold_constants.js +678 -561
- package/src/shade/renderer/particles/optimizer/pass_inline_constants.d.ts +22 -0
- package/src/shade/renderer/particles/optimizer/pass_inline_constants.d.ts.map +1 -0
- package/src/shade/renderer/particles/optimizer/pass_inline_constants.js +221 -0
- package/src/shade/renderer/particles/optimizer/pass_narrow_widths.d.ts.map +1 -1
- package/src/shade/renderer/particles/optimizer/pass_narrow_widths.js +63 -72
- package/src/shade/renderer/particles/optimizer/pass_pack_registers.d.ts.map +1 -1
- package/src/shade/renderer/particles/optimizer/pass_pack_registers.js +87 -86
- package/src/shade/renderer/particles/optimizer/pass_peephole.d.ts.map +1 -1
- package/src/shade/renderer/particles/optimizer/pass_peephole.js +392 -271
- package/src/shade/renderer/particles/optimizer/pass_propagate_copies.d.ts.map +1 -1
- package/src/shade/renderer/particles/optimizer/pass_propagate_copies.js +361 -268
- package/src/shade/renderer/particles/optimizer/pass_schedule.d.ts +4 -0
- package/src/shade/renderer/particles/optimizer/pass_schedule.d.ts.map +1 -0
- package/src/shade/renderer/particles/optimizer/pass_schedule.js +244 -0
- package/src/shade/renderer/particles/optimizer/pass_share_subexpressions.d.ts.map +1 -1
- package/src/shade/renderer/particles/optimizer/pass_share_subexpressions.js +154 -151
- package/src/shade/renderer/particles/particle_test_fixtures.d.ts +20 -0
- package/src/shade/renderer/particles/particle_test_fixtures.d.ts.map +1 -1
- package/src/shade/renderer/particles/particle_test_fixtures.js +229 -203
- package/src/shade/renderer/particles/runtime/EmitterRegistry.d.ts +99 -25
- package/src/shade/renderer/particles/runtime/EmitterRegistry.d.ts.map +1 -1
- package/src/shade/renderer/particles/runtime/EmitterRegistry.js +438 -286
- package/src/shade/renderer/particles/runtime/GPUParticleEmitterContext.d.ts +109 -0
- package/src/shade/renderer/particles/runtime/GPUParticleEmitterContext.d.ts.map +1 -0
- package/src/shade/renderer/particles/runtime/GPUParticleEmitterContext.js +127 -0
- package/src/shade/renderer/particles/runtime/ParticleEmitter.d.ts +87 -102
- package/src/shade/renderer/particles/runtime/ParticleEmitter.d.ts.map +1 -1
- package/src/shade/renderer/particles/runtime/ParticleEmitter.js +184 -163
- package/src/shade/renderer/particles/runtime/ProgramArena.d.ts +26 -0
- package/src/shade/renderer/particles/runtime/ProgramArena.d.ts.map +1 -1
- package/src/shade/renderer/particles/runtime/ProgramHeap.d.ts +130 -0
- package/src/shade/renderer/particles/runtime/ProgramHeap.d.ts.map +1 -0
- package/src/shade/renderer/particles/runtime/ProgramHeap.js +595 -0
- package/src/shade/renderer/particles/runtime/ProgramPlacement.d.ts +91 -0
- package/src/shade/renderer/particles/runtime/ProgramPlacement.d.ts.map +1 -0
- package/src/shade/renderer/particles/runtime/ProgramPlacement.js +106 -0
- package/src/shade/renderer/particles/runtime/create_particle_effect.d.ts +5 -2
- package/src/shade/renderer/particles/runtime/create_particle_effect.d.ts.map +1 -1
- package/src/shade/renderer/particles/runtime/create_particle_effect.js +22 -19
- package/src/shade/renderer/particles/shaders/chunk_particle_emit_step.d.ts +28 -0
- package/src/shade/renderer/particles/shaders/chunk_particle_emit_step.d.ts.map +1 -0
- package/src/shade/renderer/particles/shaders/chunk_particle_emit_step.js +136 -0
- package/src/shade/renderer/particles/shaders/chunk_particle_simulate_step.d.ts +35 -0
- package/src/shade/renderer/particles/shaders/chunk_particle_simulate_step.d.ts.map +1 -0
- package/src/shade/renderer/particles/shaders/chunk_particle_simulate_step.js +133 -0
- package/src/shade/renderer/particles/shaders/shader_particle_emit.d.ts +18 -9
- package/src/shade/renderer/particles/shaders/shader_particle_emit.d.ts.map +1 -1
- package/src/shade/renderer/particles/shaders/shader_particle_emit.js +20 -80
- package/src/shade/renderer/particles/shaders/shader_particle_emit_wide.d.ts +33 -0
- package/src/shade/renderer/particles/shaders/shader_particle_emit_wide.d.ts.map +1 -0
- package/src/shade/renderer/particles/shaders/shader_particle_emit_wide.js +114 -0
- package/src/shade/renderer/particles/shaders/shader_particle_simulate.d.ts +8 -0
- package/src/shade/renderer/particles/shaders/shader_particle_simulate.d.ts.map +1 -1
- package/src/shade/renderer/particles/shaders/shader_particle_simulate.js +33 -101
- package/src/shade/renderer/particles/shaders/shader_particle_simulate_wide.d.ts +45 -0
- package/src/shade/renderer/particles/shaders/shader_particle_simulate_wide.d.ts.map +1 -0
- package/src/shade/renderer/particles/shaders/shader_particle_simulate_wide.js +123 -0
- package/src/shade/renderer/particles/sort/graph_particle_sort.d.ts +51 -0
- package/src/shade/renderer/particles/sort/graph_particle_sort.d.ts.map +1 -0
- package/src/shade/renderer/particles/sort/graph_particle_sort.js +120 -0
- package/src/shade/renderer/particles/vm/PARTICLE_VM_CONTEXT_STRUCT.d.ts +6 -0
- package/src/shade/renderer/particles/vm/PARTICLE_VM_CONTEXT_STRUCT.d.ts.map +1 -0
- package/src/shade/renderer/particles/vm/PARTICLE_VM_CONTEXT_STRUCT.js +16 -0
- package/src/shade/renderer/particles/vm/ParticleVMReference.d.ts +4 -1
- package/src/shade/renderer/particles/vm/ParticleVMReference.d.ts.map +1 -1
- package/src/shade/renderer/particles/vm/ParticleVMReference.js +261 -140
- package/src/shade/renderer/particles/vm/chunk_particle_vm.d.ts.map +1 -1
- package/src/shade/renderer/particles/vm/chunk_particle_vm.js +217 -255
- package/src/shade/renderer/particles/vm/chunk_particle_vm_registers_fast.d.ts +43 -0
- package/src/shade/renderer/particles/vm/chunk_particle_vm_registers_fast.d.ts.map +1 -0
- package/src/shade/renderer/particles/vm/chunk_particle_vm_registers_fast.js +55 -0
- package/src/shade/renderer/particles/vm/chunk_particle_vm_registers_wide.d.ts +62 -0
- package/src/shade/renderer/particles/vm/chunk_particle_vm_registers_wide.d.ts.map +1 -0
- package/src/shade/renderer/particles/vm/chunk_particle_vm_registers_wide.js +86 -0
- package/src/shade/renderer/shader/chunk/math/chunk_mod_v3f.d.ts +22 -0
- package/src/shade/renderer/shader/chunk/math/chunk_mod_v3f.d.ts.map +1 -0
- package/src/shade/renderer/shader/chunk/math/chunk_mod_v3f.js +32 -0
- package/src/shade/renderer/shader/chunk/math/chunk_mod_v4f.d.ts +9 -0
- package/src/shade/renderer/shader/chunk/math/chunk_mod_v4f.d.ts.map +1 -0
- package/src/shade/renderer/shader/chunk/math/chunk_mod_v4f.js +19 -0
- package/src/shade/renderer/shader/chunk/noise/psrdnoise/README.md +65 -0
- package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise2.d.ts +24 -0
- package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise2.d.ts.map +1 -0
- package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise2.js +83 -0
- package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise2_hash.d.ts +25 -0
- package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise2_hash.d.ts.map +1 -0
- package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise2_hash.js +42 -0
- package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise2_kernel.d.ts +31 -0
- package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise2_kernel.d.ts.map +1 -0
- package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise2_kernel.js +80 -0
- package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise3.d.ts +26 -0
- package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise3.d.ts.map +1 -0
- package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise3.js +109 -0
- package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise3_kernel.d.ts +38 -0
- package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise3_kernel.d.ts.map +1 -0
- package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise3_kernel.js +129 -0
- package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise3_permute.d.ts +21 -0
- package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise3_permute.d.ts.map +1 -0
- package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise3_permute.js +35 -0
- package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise3_skew.d.ts +19 -0
- package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise3_skew.d.ts.map +1 -0
- package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise3_skew.js +28 -0
- package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise3_unskew.d.ts +13 -0
- package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise3_unskew.d.ts.map +1 -0
- package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise3_unskew.js +22 -0
- package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_srdnoise2.d.ts +22 -0
- package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_srdnoise2.d.ts.map +1 -0
- package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_srdnoise2.js +59 -0
- package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_srdnoise3.d.ts +23 -0
- package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_srdnoise3.d.ts.map +1 -0
- package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_srdnoise3.js +74 -0
- package/src/shade/wgsl/emulator/ComputeShaderEmulator.d.ts +34 -1
- package/src/shade/wgsl/emulator/ComputeShaderEmulator.d.ts.map +1 -1
- package/src/shade/wgsl/emulator/ComputeShaderEmulator.js +41 -1
- package/src/shade/wgsl/emulator/WGSLJavaScriptCompiler.d.ts +3 -2
- package/src/shade/wgsl/emulator/WGSLJavaScriptCompiler.d.ts.map +1 -1
- package/src/shade/wgsl/emulator/WGSLJavaScriptCompiler.js +49 -10
- package/src/view/minimap/dom/MinimapCameraView.d.ts.map +1 -1
- package/src/view/minimap/dom/MinimapCameraView.js +4 -9
- package/src/core/model/node-graph/visual/layout/BoxLayoutSpec.d.ts +0 -15
- package/src/core/model/node-graph/visual/layout/BoxLayoutSpec.d.ts.map +0 -1
- package/src/core/model/node-graph/visual/layout/ConnectedBoxLayouter.d.ts +0 -45
- package/src/core/model/node-graph/visual/layout/ConnectedBoxLayouter.d.ts.map +0 -1
- package/src/core/model/node-graph/visual/layout/ConnectionEndpointLayoutSpec.d.ts +0 -24
- package/src/core/model/node-graph/visual/layout/ConnectionEndpointLayoutSpec.d.ts.map +0 -1
- package/src/core/model/node-graph/visual/layout/ConnectionLayoutSpec.d.ts +0 -19
- package/src/core/model/node-graph/visual/layout/ConnectionLayoutSpec.d.ts.map +0 -1
- package/src/engine/ecs/transform/__probe.d.ts +0 -4
- package/src/engine/ecs/transform/__probe.d.ts.map +0 -1
- package/src/engine/ecs/util/hideEntityGracefully.d.ts +0 -9
- package/src/engine/ecs/util/hideEntityGracefully.d.ts.map +0 -1
- package/src/shade/renderer/buffer/table/gpu_database_emulator_image.d.ts +0 -27
- package/src/shade/renderer/buffer/table/gpu_database_emulator_image.d.ts.map +0 -1
- package/src/shade/renderer/particles/cull/chunk_particle_cull.d.ts +0 -14
- package/src/shade/renderer/particles/cull/chunk_particle_cull.d.ts.map +0 -1
- package/src/shade/renderer/particles/data/PARTICLE_EMITTER_LAYOUT.d.ts +0 -156
- package/src/shade/renderer/particles/data/PARTICLE_EMITTER_LAYOUT.d.ts.map +0 -1
- package/src/shade/renderer/particles/runtime/Emitter.d.ts +0 -219
- package/src/shade/renderer/particles/runtime/Emitter.d.ts.map +0 -1
- package/src/shade/renderer/particles/runtime/ParticleSpawnScheduler.d.ts +0 -77
- package/src/shade/renderer/particles/runtime/ParticleSpawnScheduler.d.ts.map +0 -1
- package/src/shade/renderer/particles/runtime/ProgramArena.js +0 -155
- package/src/shade/renderer/particles/runtime/emitter_database_image.d.ts +0 -15
- package/src/shade/renderer/particles/runtime/emitter_database_image.d.ts.map +0 -1
- package/src/shade/renderer/particles/runtime/spawn_request_encoding.d.ts +0 -34
- package/src/shade/renderer/particles/runtime/spawn_request_encoding.d.ts.map +0 -1
- package/src/shade/renderer/particles/shaders/chunk_particle_context.d.ts +0 -32
- package/src/shade/renderer/particles/shaders/chunk_particle_context.d.ts.map +0 -1
|
@@ -4,34 +4,24 @@ import { WebGPUStruct } from "../../shader/type/WebGPUStruct.js";
|
|
|
4
4
|
import { COLLECTION_U32_STRUCT_READ } from "../../gpu_primitive/COLLECTION_U32_STRUCT_READ.js";
|
|
5
5
|
import { COMPUTE_SHADER_DEFAULT_GROUP_SIZE } from "../../shader/COMPUTE_SHADER_DEFAULT_GROUP_SIZE.js";
|
|
6
6
|
import { ComputeShader } from "../../shader/ComputeShader.js";
|
|
7
|
-
import { chunk_lower_bound_branchless } from "../../shader/chunk/math/chunk_lower_bound_branchless.js";
|
|
8
7
|
import { CodeChunk } from "../../shader/compiler/CodeChunk.js";
|
|
9
8
|
import { ShaderResourceSetDescriptor } from "../../shader/resource/ShaderResourceSetDescriptor.js";
|
|
10
|
-
import {
|
|
11
|
-
PARTICLE_RECORD_HEADER_EMITTER,
|
|
12
|
-
PARTICLE_RECORD_USER_WORD_START,
|
|
13
|
-
PARTICLE_RECORD_WORD_COUNT,
|
|
14
|
-
PARTICLE_VM_INSTRUCTION_WORDS,
|
|
15
|
-
} from "../ParticleConstants.js";
|
|
16
9
|
import { PARTICLE_COUNTER } from "../data/PARTICLE_COUNTERS.js";
|
|
17
|
-
import {
|
|
10
|
+
import { chunk_particle_vm_registers_fast } from "../vm/chunk_particle_vm_registers_fast.js";
|
|
18
11
|
import { chunk_particle_curve_disabled } from "./chunk_particle_curve_disabled.js";
|
|
19
|
-
import {
|
|
20
|
-
import { chunk_particle_setup_context } from "./chunk_particle_setup_context.js";
|
|
12
|
+
import { chunk_particle_emit_step } from "./chunk_particle_emit_step.js";
|
|
21
13
|
|
|
22
14
|
/**
|
|
23
15
|
* The particle emit pass: one thread per particle born this frame.
|
|
24
16
|
*
|
|
25
|
-
* Its input is the prefix scan of the emitter tick pass's per-row spawn counts
|
|
26
|
-
*
|
|
27
|
-
*
|
|
28
|
-
*
|
|
29
|
-
* loops, and the dispatch is sized on the GPU from the scan's total.
|
|
17
|
+
* Its input is the prefix scan of the emitter tick pass's per-row spawn counts; thread `i` finds the
|
|
18
|
+
* emitter it belongs to by binary search over the inclusive sums, and its place within that
|
|
19
|
+
* emitter's batch from the sum before. Then: pop a free slot from the dead list, clear the record,
|
|
20
|
+
* stamp the header, run the emitter's INIT program, and append the slot to the new alive list.
|
|
30
21
|
*
|
|
31
|
-
*
|
|
32
|
-
*
|
|
33
|
-
*
|
|
34
|
-
* node, so a particle born of an emitter riding a bone starts where the bone is this frame.
|
|
22
|
+
* The per-newborn work is {@link ./chunk_particle_emit_step.js}, shared with
|
|
23
|
+
* {@link ./shader_particle_emit_wide.js}. What this file is, is the *fast* register backing plus the
|
|
24
|
+
* one-lane-per-newborn dispatch that suits it.
|
|
35
25
|
*
|
|
36
26
|
* Runs before simulate in the frame so newborns join the same alive list survivors are compacted
|
|
37
27
|
* into. Shares the VM + context + emitter chunks with simulate.
|
|
@@ -54,7 +44,7 @@ export const PARTICLE_EMIT_WORKGROUP_SIZE = COMPUTE_SHADER_DEFAULT_GROUP_SIZE;
|
|
|
54
44
|
*
|
|
55
45
|
* @type {WebGPUStruct}
|
|
56
46
|
*/
|
|
57
|
-
const EMIT_SETTINGS = WebGPUStruct.from({
|
|
47
|
+
export const EMIT_SETTINGS = WebGPUStruct.from({
|
|
58
48
|
u_dt: f32,
|
|
59
49
|
u_time: f32,
|
|
60
50
|
u_frame: u32,
|
|
@@ -78,10 +68,6 @@ resources.createGroup()
|
|
|
78
68
|
const body = CodeChunk.from(
|
|
79
69
|
/* language=wgsl */
|
|
80
70
|
`
|
|
81
|
-
const PARTICLE_RECORD_WORDS : u32 = ${PARTICLE_RECORD_WORD_COUNT}u;
|
|
82
|
-
const PARTICLE_USER_WORD_START : u32 = ${PARTICLE_RECORD_USER_WORD_START}u;
|
|
83
|
-
const PARTICLE_HEADER_EMITTER : u32 = ${PARTICLE_RECORD_HEADER_EMITTER}u;
|
|
84
|
-
const PARTICLE_INSTRUCTION_WORDS : u32 = ${PARTICLE_VM_INSTRUCTION_WORDS}u;
|
|
85
71
|
const COUNTER_ALIVE : u32 = ${PARTICLE_COUNTER.ALIVE}u;
|
|
86
72
|
const COUNTER_DEAD : u32 = ${PARTICLE_COUNTER.DEAD}u;
|
|
87
73
|
|
|
@@ -89,77 +75,31 @@ const COUNTER_DEAD : u32 = ${PARTICLE_COUNTER.DEAD}u;
|
|
|
89
75
|
fn main(@builtin(global_invocation_id) gid : vec3<u32>) {
|
|
90
76
|
let i = gid.x;
|
|
91
77
|
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
let emitter_count = spawn_prefix.count;
|
|
95
|
-
if (emitter_count == 0u) { return; }
|
|
96
|
-
let total = spawn_prefix.elements[emitter_count - 1u];
|
|
97
|
-
if (i >= total) { return; }
|
|
78
|
+
let assignment = particle_emit_assignment(&spawn_prefix.elements, spawn_prefix.count, i);
|
|
79
|
+
if (!assignment.valid) { return; }
|
|
98
80
|
|
|
99
|
-
//
|
|
100
|
-
//
|
|
101
|
-
// the search steps over them.
|
|
102
|
-
let emitter_row = lower_bound_branchless(&spawn_prefix.elements, i + 1u, emitter_count);
|
|
103
|
-
var batch_start = 0u;
|
|
104
|
-
if (emitter_row > 0u) {
|
|
105
|
-
batch_start = spawn_prefix.elements[emitter_row - 1u];
|
|
106
|
-
}
|
|
107
|
-
let batch_size = spawn_prefix.elements[emitter_row] - batch_start;
|
|
108
|
-
|
|
109
|
-
// SPAWN_FRACTION contract: this particle's place in its emitter's batch this frame, n / count,
|
|
110
|
-
// for spreading a batch along a spawn curve.
|
|
111
|
-
let spawn_fraction = f32(i - batch_start) / f32(batch_size);
|
|
112
|
-
|
|
113
|
-
// Pop a free slot off the dead-list stack; drop the spawn if the pool is exhausted.
|
|
114
|
-
//
|
|
115
|
-
// The guard must catch WRAPPED values, not just 0: when many threads race an empty stack, the
|
|
116
|
-
// first over-pop wraps the counter to 0xFFFFFFFF before its undo lands, and a concurrent thread
|
|
117
|
-
// then observes a huge old value. Checking only ==0 would let it index dead[old-1] with garbage
|
|
118
|
-
// and hand out a bogus slot, corrupting a live record. The dead count can never legitimately
|
|
119
|
-
// exceed the pool capacity, so >settings.u_capacity identifies every wrapped state; each thread that
|
|
120
|
-
// subtracted also adds back exactly once, so the counter converges to 0.
|
|
81
|
+
// Pop a free slot off the dead-list stack; drop the spawn if the pool is exhausted. The guard
|
|
82
|
+
// catches WRAPPED values, not just 0 — see chunk_particle_emit_step for why that matters.
|
|
121
83
|
let old_dead = atomicSub(&counters[COUNTER_DEAD], 1u);
|
|
122
84
|
if (old_dead == 0u || old_dead > settings.u_capacity) {
|
|
123
85
|
atomicAdd(&counters[COUNTER_DEAD], 1u); // undo the over-pop
|
|
124
86
|
return;
|
|
125
87
|
}
|
|
126
88
|
let slot = dead[old_dead - 1u];
|
|
127
|
-
let record_base = slot * PARTICLE_RECORD_WORDS;
|
|
128
|
-
|
|
129
|
-
let em = particle_emitter_read(&emitter_database, emitter_row);
|
|
130
|
-
let node = scene_read_node(&scene_database, em.node);
|
|
131
89
|
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
pool[record_base + PARTICLE_HEADER_EMITTER] = particle_header_pack(emitter_row, em.generation);
|
|
137
|
-
|
|
138
|
-
particle_vm_reset();
|
|
139
|
-
particle_setup_context(
|
|
140
|
-
em, node, slot,
|
|
141
|
-
settings.u_dt, settings.u_time,
|
|
142
|
-
particle_emitter_age(&emitter_database, emitter_row),
|
|
143
|
-
spawn_fraction, settings.u_frame,
|
|
144
|
-
);
|
|
145
|
-
particle_vm_execute(
|
|
146
|
-
&program,
|
|
147
|
-
em.init_offset * PARTICLE_INSTRUCTION_WORDS,
|
|
148
|
-
em.init_count,
|
|
149
|
-
em.constant_offset,
|
|
150
|
-
&pool,
|
|
151
|
-
record_base,
|
|
90
|
+
particle_emit_one(
|
|
91
|
+
&scene_database, &emitter_database, &program, &pool,
|
|
92
|
+
assignment.emitter_row, slot, assignment.spawn_fraction,
|
|
93
|
+
settings.u_dt, settings.u_time, settings.u_frame,
|
|
152
94
|
);
|
|
153
95
|
|
|
154
96
|
let a = atomicAdd(&counters[COUNTER_ALIVE], 1u);
|
|
155
97
|
alive_out[a] = slot;
|
|
156
98
|
}
|
|
157
99
|
`, [
|
|
158
|
-
|
|
159
|
-
|
|
100
|
+
chunk_particle_emit_step,
|
|
101
|
+
chunk_particle_vm_registers_fast,
|
|
160
102
|
chunk_particle_curve_disabled,
|
|
161
|
-
chunk_particle_header,
|
|
162
|
-
chunk_lower_bound_branchless,
|
|
163
103
|
]);
|
|
164
104
|
|
|
165
105
|
export const shader_particle_emit = ComputeShader.from({
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The emit pass over the WIDE register file — the fallback interpreter's spawn half.
|
|
3
|
+
*
|
|
4
|
+
* Same emission as {@link ./shader_particle_emit.js}, down to the shared
|
|
5
|
+
* {@link ./chunk_particle_emit_step.js}. It differs in the same way
|
|
6
|
+
* {@link ./shader_particle_simulate_wide.js} does: a bounded launch of
|
|
7
|
+
* {@link ../ParticleConstants.js PARTICLE_VM_WIDE_LAUNCH_LANES} lanes with a grid-stride loop, so
|
|
8
|
+
* the storage register file is sized by a constant rather than by how many particles happen to be
|
|
9
|
+
* born this frame.
|
|
10
|
+
*
|
|
11
|
+
* It therefore does not consume the indirect command the prefix scan produces for the fast pass. The
|
|
12
|
+
* scan's total is read in the shader as the loop bound instead, which is the same number from the
|
|
13
|
+
* same buffer — just used as a bound rather than as a dispatch size.
|
|
14
|
+
*
|
|
15
|
+
* The register file is indexed by launch lane, so it is reused across the loop's iterations. That is
|
|
16
|
+
* sound for the same reason it is never cleared: an INIT program writes a register before it reads
|
|
17
|
+
* it, so nothing carries between one newborn and the next. See
|
|
18
|
+
* {@link ../vm/chunk_particle_vm_registers_wide.js}.
|
|
19
|
+
*
|
|
20
|
+
* Emit's waves span emitters by construction, so — unlike simulate — there was never a wave-uniform
|
|
21
|
+
* decode here to lose.
|
|
22
|
+
*
|
|
23
|
+
* @type {ComputeShader}
|
|
24
|
+
*/
|
|
25
|
+
/**
|
|
26
|
+
* Workgroups this pass dispatches. Constant: the launch does not depend on how many particles are
|
|
27
|
+
* born this frame.
|
|
28
|
+
* @type {number}
|
|
29
|
+
*/
|
|
30
|
+
export const PARTICLE_EMIT_WIDE_WORKGROUP_COUNT: number;
|
|
31
|
+
export const shader_particle_emit_wide: ComputeShader;
|
|
32
|
+
import { ComputeShader } from "../../shader/ComputeShader.js";
|
|
33
|
+
//# sourceMappingURL=shader_particle_emit_wide.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shader_particle_emit_wide.d.ts","sourceRoot":"","sources":["../../../../../../src/shade/renderer/particles/shaders/shader_particle_emit_wide.js"],"names":[],"mappings":"AAaA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAEH;;;;GAIG;AACH,iDAFU,MAAM,CAGiD;AAiEjE,sDAIG;8BA9G2B,+BAA+B"}
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
import { atomic_u32, f32 } from "../../shader/type/WEBGPU_WGSL_PRIMITIVE_TYPES.js";
|
|
2
|
+
import { WebGPUArray } from "../../shader/type/WebGPUArray.js";
|
|
3
|
+
import { COLLECTION_U32_STRUCT_READ } from "../../gpu_primitive/COLLECTION_U32_STRUCT_READ.js";
|
|
4
|
+
import { ComputeShader } from "../../shader/ComputeShader.js";
|
|
5
|
+
import { CodeChunk } from "../../shader/compiler/CodeChunk.js";
|
|
6
|
+
import { ShaderResourceSetDescriptor } from "../../shader/resource/ShaderResourceSetDescriptor.js";
|
|
7
|
+
import { PARTICLE_VM_WIDE_LAUNCH_LANES } from "../ParticleConstants.js";
|
|
8
|
+
import { PARTICLE_COUNTER } from "../data/PARTICLE_COUNTERS.js";
|
|
9
|
+
import { chunk_particle_vm_registers_wide } from "../vm/chunk_particle_vm_registers_wide.js";
|
|
10
|
+
import { chunk_particle_curve_disabled } from "./chunk_particle_curve_disabled.js";
|
|
11
|
+
import { chunk_particle_emit_step } from "./chunk_particle_emit_step.js";
|
|
12
|
+
import { EMIT_SETTINGS, PARTICLE_EMIT_WORKGROUP_SIZE } from "./shader_particle_emit.js";
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* The emit pass over the WIDE register file — the fallback interpreter's spawn half.
|
|
16
|
+
*
|
|
17
|
+
* Same emission as {@link ./shader_particle_emit.js}, down to the shared
|
|
18
|
+
* {@link ./chunk_particle_emit_step.js}. It differs in the same way
|
|
19
|
+
* {@link ./shader_particle_simulate_wide.js} does: a bounded launch of
|
|
20
|
+
* {@link ../ParticleConstants.js PARTICLE_VM_WIDE_LAUNCH_LANES} lanes with a grid-stride loop, so
|
|
21
|
+
* the storage register file is sized by a constant rather than by how many particles happen to be
|
|
22
|
+
* born this frame.
|
|
23
|
+
*
|
|
24
|
+
* It therefore does not consume the indirect command the prefix scan produces for the fast pass. The
|
|
25
|
+
* scan's total is read in the shader as the loop bound instead, which is the same number from the
|
|
26
|
+
* same buffer — just used as a bound rather than as a dispatch size.
|
|
27
|
+
*
|
|
28
|
+
* The register file is indexed by launch lane, so it is reused across the loop's iterations. That is
|
|
29
|
+
* sound for the same reason it is never cleared: an INIT program writes a register before it reads
|
|
30
|
+
* it, so nothing carries between one newborn and the next. See
|
|
31
|
+
* {@link ../vm/chunk_particle_vm_registers_wide.js}.
|
|
32
|
+
*
|
|
33
|
+
* Emit's waves span emitters by construction, so — unlike simulate — there was never a wave-uniform
|
|
34
|
+
* decode here to lose.
|
|
35
|
+
*
|
|
36
|
+
* @type {ComputeShader}
|
|
37
|
+
*/
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Workgroups this pass dispatches. Constant: the launch does not depend on how many particles are
|
|
41
|
+
* born this frame.
|
|
42
|
+
* @type {number}
|
|
43
|
+
*/
|
|
44
|
+
export const PARTICLE_EMIT_WIDE_WORKGROUP_COUNT =
|
|
45
|
+
PARTICLE_VM_WIDE_LAUNCH_LANES / PARTICLE_EMIT_WORKGROUP_SIZE;
|
|
46
|
+
|
|
47
|
+
const resources = new ShaderResourceSetDescriptor();
|
|
48
|
+
|
|
49
|
+
resources.setImmediate('settings', EMIT_SETTINGS);
|
|
50
|
+
|
|
51
|
+
resources.createGroup()
|
|
52
|
+
.addStorageBuffer("scene_database", WebGPUArray.u32, false)
|
|
53
|
+
.addStorageBuffer("emitter_database", WebGPUArray.u32, false)
|
|
54
|
+
.addStorageBuffer("program", WebGPUArray.u32, false)
|
|
55
|
+
.addStorageBuffer("spawn_prefix", COLLECTION_U32_STRUCT_READ, false)
|
|
56
|
+
.addStorageBuffer("pool", WebGPUArray.u32, true)
|
|
57
|
+
.addStorageBuffer("alive_out", WebGPUArray.u32, true)
|
|
58
|
+
.addStorageBuffer("dead", WebGPUArray.u32, true)
|
|
59
|
+
.addStorageBuffer("counters", WebGPUArray.from(atomic_u32), true)
|
|
60
|
+
.addStorageBuffer("vm_registers", WebGPUArray.from(f32), true);
|
|
61
|
+
|
|
62
|
+
const body = CodeChunk.from(
|
|
63
|
+
/* language=wgsl */
|
|
64
|
+
`
|
|
65
|
+
const COUNTER_ALIVE : u32 = ${PARTICLE_COUNTER.ALIVE}u;
|
|
66
|
+
const COUNTER_DEAD : u32 = ${PARTICLE_COUNTER.DEAD}u;
|
|
67
|
+
|
|
68
|
+
@compute @workgroup_size(${PARTICLE_EMIT_WORKGROUP_SIZE}, 1, 1)
|
|
69
|
+
fn main(@builtin(global_invocation_id) gid : vec3<u32>) {
|
|
70
|
+
// This invocation's column of the register file. The launch is exactly
|
|
71
|
+
// PARTICLE_VM_WIDE_LAUNCH_LANES wide, so gid.x is in range by construction.
|
|
72
|
+
particle_vm_bind_registers(gid.x);
|
|
73
|
+
|
|
74
|
+
// The scan's last inclusive sum is the number of particles born this frame — the bound this pass
|
|
75
|
+
// walks to, in place of the indirect dispatch the fast pass is sized by.
|
|
76
|
+
let emitter_count = spawn_prefix.count;
|
|
77
|
+
if (emitter_count == 0u) { return; }
|
|
78
|
+
let total = spawn_prefix.elements[emitter_count - 1u];
|
|
79
|
+
|
|
80
|
+
for (var i = gid.x; i < total; i = i + PARTICLE_VM_WIDE_LAUNCH_LANES) {
|
|
81
|
+
let assignment = particle_emit_assignment(&spawn_prefix.elements, emitter_count, i);
|
|
82
|
+
if (!assignment.valid) { continue; }
|
|
83
|
+
|
|
84
|
+
// Pop a free slot off the dead-list stack; drop the spawn if the pool is exhausted. The
|
|
85
|
+
// guard catches WRAPPED values, not just 0 — see chunk_particle_emit_step for why that
|
|
86
|
+
// matters.
|
|
87
|
+
let old_dead = atomicSub(&counters[COUNTER_DEAD], 1u);
|
|
88
|
+
if (old_dead == 0u || old_dead > settings.u_capacity) {
|
|
89
|
+
atomicAdd(&counters[COUNTER_DEAD], 1u); // undo the over-pop
|
|
90
|
+
continue;
|
|
91
|
+
}
|
|
92
|
+
let slot = dead[old_dead - 1u];
|
|
93
|
+
|
|
94
|
+
particle_emit_one(
|
|
95
|
+
&scene_database, &emitter_database, &program, &pool,
|
|
96
|
+
assignment.emitter_row, slot, assignment.spawn_fraction,
|
|
97
|
+
settings.u_dt, settings.u_time, settings.u_frame,
|
|
98
|
+
);
|
|
99
|
+
|
|
100
|
+
let a = atomicAdd(&counters[COUNTER_ALIVE], 1u);
|
|
101
|
+
alive_out[a] = slot;
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
`, [
|
|
105
|
+
chunk_particle_emit_step,
|
|
106
|
+
chunk_particle_vm_registers_wide,
|
|
107
|
+
chunk_particle_curve_disabled,
|
|
108
|
+
]);
|
|
109
|
+
|
|
110
|
+
export const shader_particle_emit_wide = ComputeShader.from({
|
|
111
|
+
label: "Particle Emit (wide registers)",
|
|
112
|
+
resources,
|
|
113
|
+
body,
|
|
114
|
+
});
|
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
export { PARTICLE_SIMULATE_WORKGROUP_SIZE };
|
|
2
|
+
/**
|
|
3
|
+
* Per-dispatch, 12 bytes, read-only — see shader_particle_emit for why the three travel
|
|
4
|
+
* together rather than as three uniforms.
|
|
5
|
+
*
|
|
6
|
+
* @type {WebGPUStruct}
|
|
7
|
+
*/
|
|
8
|
+
export const SIMULATE_SETTINGS: WebGPUStruct;
|
|
2
9
|
export const shader_particle_simulate: ComputeShader;
|
|
3
10
|
import { PARTICLE_SIMULATE_WORKGROUP_SIZE } from "../ParticleConstants.js";
|
|
11
|
+
import { WebGPUStruct } from "../../shader/type/WebGPUStruct.js";
|
|
4
12
|
import { ComputeShader } from "../../shader/ComputeShader.js";
|
|
5
13
|
//# sourceMappingURL=shader_particle_simulate.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"shader_particle_simulate.d.ts","sourceRoot":"","sources":["../../../../../../src/shade/renderer/particles/shaders/shader_particle_simulate.js"],"names":[],"mappings":";
|
|
1
|
+
{"version":3,"file":"shader_particle_simulate.d.ts","sourceRoot":"","sources":["../../../../../../src/shade/renderer/particles/shaders/shader_particle_simulate.js"],"names":[],"mappings":";AA0DA;;;;;GAKG;AACH,gCAFU,YAAY,CAMS;AAuD/B,qDAIG;iDAxH8C,yBAAyB;6BAJ7C,mCAAmC;8BAClC,+BAA+B"}
|
|
@@ -5,27 +5,27 @@ import { WebGPUStruct } from "../../shader/type/WebGPUStruct.js";
|
|
|
5
5
|
import { ComputeShader } from "../../shader/ComputeShader.js";
|
|
6
6
|
import { CodeChunk } from "../../shader/compiler/CodeChunk.js";
|
|
7
7
|
import { ShaderResourceSetDescriptor } from "../../shader/resource/ShaderResourceSetDescriptor.js";
|
|
8
|
-
import {
|
|
9
|
-
PARTICLE_RECORD_HEADER_EMITTER,
|
|
10
|
-
PARTICLE_RECORD_WORD_COUNT,
|
|
11
|
-
PARTICLE_SIMULATE_WORKGROUP_SIZE,
|
|
12
|
-
PARTICLE_SIM_PAD_SLOT,
|
|
13
|
-
PARTICLE_VM_INSTRUCTION_WORDS,
|
|
14
|
-
} from "../ParticleConstants.js";
|
|
8
|
+
import { PARTICLE_SIMULATE_WORKGROUP_SIZE } from "../ParticleConstants.js";
|
|
15
9
|
import { PARTICLE_COUNTER } from "../data/PARTICLE_COUNTERS.js";
|
|
16
|
-
import {
|
|
10
|
+
import { chunk_particle_vm_registers_fast } from "../vm/chunk_particle_vm_registers_fast.js";
|
|
17
11
|
import { chunk_particle_curve_disabled } from "./chunk_particle_curve_disabled.js";
|
|
18
|
-
import {
|
|
19
|
-
import { chunk_particle_setup_context } from "./chunk_particle_setup_context.js";
|
|
12
|
+
import { chunk_particle_simulate_step } from "./chunk_particle_simulate_step.js";
|
|
20
13
|
|
|
21
14
|
/**
|
|
22
15
|
* The particle simulate pass — Destiny-style single execution shader.
|
|
23
16
|
*
|
|
24
|
-
* One dispatch processes every live particle across every emitter
|
|
25
|
-
* emitter, set up the VM context + RNG, run that emitter's compiled UPDATE
|
|
26
|
-
* then compact — killed particles are pushed back to the dead (free) list,
|
|
27
|
-
* the new alive list. There is exactly one pipeline regardless of how many
|
|
28
|
-
* because behaviour is data (the bytecode program), not code.
|
|
17
|
+
* One dispatch processes every live particle across every emitter, one invocation each. Per
|
|
18
|
+
* particle: read its owning emitter, set up the VM context + RNG, run that emitter's compiled UPDATE
|
|
19
|
+
* program over the record, then compact — killed particles are pushed back to the dead (free) list,
|
|
20
|
+
* survivors are appended to the new alive list. There is exactly one pipeline regardless of how many
|
|
21
|
+
* distinct effects exist, because behaviour is data (the bytecode program), not code.
|
|
22
|
+
*
|
|
23
|
+
* The per-particle work is {@link ./chunk_particle_simulate_step.js}, shared with
|
|
24
|
+
* {@link ./shader_particle_simulate_wide.js}. What this file is, is the *fast* register backing plus
|
|
25
|
+
* the one-lane-per-particle dispatch that suits it. See
|
|
26
|
+
* {@link ../vm/chunk_particle_vm_registers_fast.js} for what "fast" costs and buys, and
|
|
27
|
+
* {@link ../ParticleConstants.js PARTICLE_VM_FAST_REGISTER_SLOTS} for when the system runs the other
|
|
28
|
+
* one instead.
|
|
29
29
|
*
|
|
30
30
|
* ## The input list
|
|
31
31
|
*
|
|
@@ -33,23 +33,9 @@ import { chunk_particle_setup_context } from "./chunk_particle_setup_context.js"
|
|
|
33
33
|
* pass (`../coherence/`) built at the end of last frame: the same pool slots, reordered so that
|
|
34
34
|
* particles running one VM program sit together, each run padded out to a whole workgroup. That is
|
|
35
35
|
* what keeps a wave from spanning two programs — and this shader leans on it rather than merely
|
|
36
|
-
* benefiting from it: the section parameters are read from the wave's first lane
|
|
37
|
-
*
|
|
38
|
-
*
|
|
39
|
-
*
|
|
40
|
-
* Padding entries carry {@link PARTICLE_SIM_PAD_SLOT} and are dropped BEFORE the compaction
|
|
41
|
-
* atomics, so a padding lane never appends to the alive list and never pushes a slot onto the free
|
|
42
|
-
* list — pushing the sentinel would put `0xffffffff` on the free list for a later emit to hand out
|
|
43
|
-
* as a record base. Returning early is safe for the lanes that remain: padding only ever appears in
|
|
44
|
-
* the tail of a bucket, and every real lane in that wave belongs to that one bucket, so the `switch`
|
|
45
|
-
* the survivors execute is uniform regardless.
|
|
46
|
-
*
|
|
47
|
-
* ## Orphans
|
|
48
|
-
*
|
|
49
|
-
* A particle whose header generation is not its emitter row's current generation belongs to an
|
|
50
|
-
* emitter that has been removed — the row is either zero-filled or already someone else's. It is
|
|
51
|
-
* killed here, the frame the mismatch appears, before it can run a stranger's program or follow a
|
|
52
|
-
* stranger's node. See `../data/particle_header.js`.
|
|
36
|
+
* benefiting from it: the section parameters are read from the wave's first lane, so a wave that
|
|
37
|
+
* held two programs would run one of them over the other's particles. The coherence pass is part of
|
|
38
|
+
* this shader's correctness, not only of its speed.
|
|
53
39
|
*
|
|
54
40
|
* ## Sizing
|
|
55
41
|
*
|
|
@@ -76,7 +62,7 @@ export { PARTICLE_SIMULATE_WORKGROUP_SIZE };
|
|
|
76
62
|
*
|
|
77
63
|
* @type {WebGPUStruct}
|
|
78
64
|
*/
|
|
79
|
-
const SIMULATE_SETTINGS = WebGPUStruct.from({
|
|
65
|
+
export const SIMULATE_SETTINGS = WebGPUStruct.from({
|
|
80
66
|
u_dt: f32,
|
|
81
67
|
u_time: f32,
|
|
82
68
|
u_frame: u32,
|
|
@@ -98,33 +84,9 @@ resources.createGroup()
|
|
|
98
84
|
|
|
99
85
|
|
|
100
86
|
const body = CodeChunk.from(/* language=wgsl */ `
|
|
101
|
-
const PARTICLE_RECORD_WORDS : u32 = ${PARTICLE_RECORD_WORD_COUNT}u;
|
|
102
|
-
const PARTICLE_HEADER_EMITTER : u32 = ${PARTICLE_RECORD_HEADER_EMITTER}u;
|
|
103
|
-
const PARTICLE_INSTRUCTION_WORDS : u32 = ${PARTICLE_VM_INSTRUCTION_WORDS}u;
|
|
104
87
|
const COUNTER_ALIVE : u32 = ${PARTICLE_COUNTER.ALIVE}u;
|
|
105
88
|
const COUNTER_DEAD : u32 = ${PARTICLE_COUNTER.DEAD}u;
|
|
106
89
|
const COUNTER_ALIVE_IN : u32 = ${PARTICLE_COUNTER.ALIVE_IN}u;
|
|
107
|
-
const PARTICLE_SIM_PAD_SLOT : u32 = ${PARTICLE_SIM_PAD_SLOT}u;
|
|
108
|
-
|
|
109
|
-
// The value the wave's first live lane holds, in every lane.
|
|
110
|
-
//
|
|
111
|
-
// Everything that reaches the interpreter in one wave belongs to one bucket of sim_list: the
|
|
112
|
-
// coherence pass grouped the list by program and padded each group to a whole workgroup, and the
|
|
113
|
-
// padding and orphan lanes have left by the time a program runs. So the three numbers that pick a
|
|
114
|
-
// section are the same in every lane. The compiler cannot see that — they come out of a table row
|
|
115
|
-
// found through a per-lane header, which is as divergent as a value gets — and reading them from
|
|
116
|
-
// the first lane is what tells it. The rest follows on its own: the instruction words are then
|
|
117
|
-
// fetched through the scalar unit, the opcode switch branches on a scalar, and the register file is
|
|
118
|
-
// indexed through M0 directly instead of through a waterfall loop over the lanes' indices. The VM
|
|
119
|
-
// chunk is unchanged, and emit keeps its per-lane decode, because its waves span emitters.
|
|
120
|
-
//
|
|
121
|
-
// The uniformity diagnostic is off because the call sits behind per-lane early returns. That is the
|
|
122
|
-
// situation the builtin is defined for — it reads the first ACTIVE lane — and the one WGSL's
|
|
123
|
-
// analysis over-approximates.
|
|
124
|
-
@diagnostic(off, subgroup_uniformity)
|
|
125
|
-
fn particle_wave_uniform(value : u32) -> u32 {
|
|
126
|
-
return subgroupBroadcastFirst(value);
|
|
127
|
-
}
|
|
128
90
|
|
|
129
91
|
@compute @workgroup_size(${PARTICLE_SIMULATE_WORKGROUP_SIZE}, 1, 1)
|
|
130
92
|
fn main(@builtin(global_invocation_id) gid : vec3<u32>) {
|
|
@@ -134,57 +96,27 @@ fn main(@builtin(global_invocation_id) gid : vec3<u32>) {
|
|
|
134
96
|
|
|
135
97
|
let slot = sim_list[i];
|
|
136
98
|
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
let record_base = slot * PARTICLE_RECORD_WORDS;
|
|
144
|
-
let header = pool[record_base + PARTICLE_HEADER_EMITTER];
|
|
145
|
-
let emitter_index = particle_header_emitter(header);
|
|
146
|
-
|
|
147
|
-
let em = particle_emitter_read(&emitter_database, emitter_index);
|
|
148
|
-
|
|
149
|
-
// An orphan: its emitter is gone and the row is free or somebody else's. Freed without running
|
|
150
|
-
// a program — there is no program of its own left to run.
|
|
151
|
-
var killed = particle_header_generation(header) != em.generation;
|
|
99
|
+
let verdict = particle_simulate_one(
|
|
100
|
+
&scene_database, &emitter_database, &program, &pool,
|
|
101
|
+
slot,
|
|
102
|
+
settings.u_dt, settings.u_time, settings.u_frame,
|
|
103
|
+
);
|
|
152
104
|
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
particle_setup_context(
|
|
158
|
-
em, node, slot,
|
|
159
|
-
settings.u_dt, settings.u_time,
|
|
160
|
-
particle_emitter_age(&emitter_database, emitter_index),
|
|
161
|
-
0.0, settings.u_frame,
|
|
162
|
-
);
|
|
163
|
-
particle_vm_execute(
|
|
164
|
-
&program,
|
|
165
|
-
particle_wave_uniform(em.update_offset) * PARTICLE_INSTRUCTION_WORDS,
|
|
166
|
-
particle_wave_uniform(em.update_count),
|
|
167
|
-
particle_wave_uniform(em.constant_offset),
|
|
168
|
-
&pool,
|
|
169
|
-
record_base,
|
|
170
|
-
);
|
|
171
|
-
|
|
172
|
-
killed = vm_killed;
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
if (killed) {
|
|
176
|
-
let d = atomicAdd(&counters[COUNTER_DEAD], 1u);
|
|
177
|
-
dead[d] = slot;
|
|
178
|
-
} else {
|
|
105
|
+
// A padding lane's verdict is SKIP and books nothing. Appending it would put the padding
|
|
106
|
+
// sentinel on the alive or the free list, and the free list would then hand 0xffffffff to a
|
|
107
|
+
// later emit as a record base.
|
|
108
|
+
if (verdict == PARTICLE_SIM_ALIVE) {
|
|
179
109
|
let a = atomicAdd(&counters[COUNTER_ALIVE], 1u);
|
|
180
110
|
alive_out[a] = slot;
|
|
111
|
+
} else if (verdict == PARTICLE_SIM_KILLED) {
|
|
112
|
+
let d = atomicAdd(&counters[COUNTER_DEAD], 1u);
|
|
113
|
+
dead[d] = slot;
|
|
181
114
|
}
|
|
182
115
|
}
|
|
183
116
|
`, [
|
|
184
|
-
|
|
185
|
-
|
|
117
|
+
chunk_particle_simulate_step,
|
|
118
|
+
chunk_particle_vm_registers_fast,
|
|
186
119
|
chunk_particle_curve_disabled,
|
|
187
|
-
chunk_particle_header,
|
|
188
120
|
]);
|
|
189
121
|
|
|
190
122
|
body.addExtension(WebGPUExtensionType.Subgroups);
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The simulate pass over the WIDE register file — the fallback interpreter.
|
|
3
|
+
*
|
|
4
|
+
* Same simulation as {@link ./shader_particle_simulate.js}, down to the shared
|
|
5
|
+
* {@link ./chunk_particle_simulate_step.js}: one dispatch, every live particle, the emitter's UPDATE
|
|
6
|
+
* program, compaction into the alive and free lists. Two things differ, and both follow from the
|
|
7
|
+
* register file living in a storage buffer.
|
|
8
|
+
*
|
|
9
|
+
* ## The launch is bounded, and the loop is grid-stride
|
|
10
|
+
*
|
|
11
|
+
* The fast pass runs one invocation per particle and sizes its dispatch indirectly from
|
|
12
|
+
* `counters[ALIVE_IN]`. This one cannot: it needs a register file per invocation in flight, so
|
|
13
|
+
* one-lane-per-particle would size the register buffer by pool capacity — a gigabyte at a million
|
|
14
|
+
* particles.
|
|
15
|
+
*
|
|
16
|
+
* So it launches exactly {@link ../ParticleConstants.js PARTICLE_VM_WIDE_LAUNCH_LANES} lanes,
|
|
17
|
+
* whatever the particle count, and each walks `sim_list` in strides of that. The register buffer is
|
|
18
|
+
* then sized by a constant this engine chose rather than by a number the pool decides. There is no
|
|
19
|
+
* indirect command and no CPU-side count: the launch is fixed, and the loop bound is still the
|
|
20
|
+
* on-GPU `counters[ALIVE_IN]` snapshot, read in the shader exactly as before. Every guarantee the
|
|
21
|
+
* fast pass's sizing comment describes holds here for the same reason.
|
|
22
|
+
*
|
|
23
|
+
* The stride is a whole number of workgroups, which is what keeps the coherence pass's bucketing
|
|
24
|
+
* intact: each iteration covers a workgroup-aligned span of `sim_list`, so a wave still sees one
|
|
25
|
+
* program and the wave-uniform section decode is still sound. That decode is worth keeping even
|
|
26
|
+
* here — it is what makes the instruction fetch and the opcode switch scalar. Only the register
|
|
27
|
+
* indexing goes per-lane, because in this backing it always is.
|
|
28
|
+
*
|
|
29
|
+
* ## Nine storage buffers
|
|
30
|
+
*
|
|
31
|
+
* The fast passes fit in the eight a stage gets by default; this one adds `vm_registers` and needs
|
|
32
|
+
* nine. That is inside what the engine already demands of an adapter — {@link
|
|
33
|
+
* ../../Renderer.js} refuses one offering fewer than ten — so it costs no new capability, but it is
|
|
34
|
+
* why the particle system's "everything fits in eight" note does not cover this shader.
|
|
35
|
+
*
|
|
36
|
+
* @type {ComputeShader}
|
|
37
|
+
*/
|
|
38
|
+
/**
|
|
39
|
+
* Workgroups this pass dispatches. Constant: the launch does not depend on the particle count.
|
|
40
|
+
* @type {number}
|
|
41
|
+
*/
|
|
42
|
+
export const PARTICLE_SIMULATE_WIDE_WORKGROUP_COUNT: number;
|
|
43
|
+
export const shader_particle_simulate_wide: ComputeShader;
|
|
44
|
+
import { ComputeShader } from "../../shader/ComputeShader.js";
|
|
45
|
+
//# sourceMappingURL=shader_particle_simulate_wide.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shader_particle_simulate_wide.d.ts","sourceRoot":"","sources":["../../../../../../src/shade/renderer/particles/shaders/shader_particle_simulate_wide.js"],"names":[],"mappings":"AAaA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;AAEH;;;GAGG;AACH,qDAFU,MAAM,CAGqD;AA8DrE,0DAIG;8BAvH2B,+BAA+B"}
|