@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
|
@@ -35,6 +35,20 @@ edits it at both altitudes.
|
|
|
35
35
|
the moment it arrives. Arrow keys move the choice; Escape closes. Nodes are listed and headed by
|
|
36
36
|
what they are called rather than by the mnemonic they compile as — "Divide", not `div` — each with
|
|
37
37
|
the glyph its type carries; both are searched, so looking for either finds it.
|
|
38
|
+
- **Copy, paste, duplicate.** `Ctrl+C` takes a copy of the selected nodes and of every wire they hold
|
|
39
|
+
whole — a wire with one end outside the selection is not brought along, because the node it reached
|
|
40
|
+
is not part of what was copied. `Ctrl+V` puts it in the middle of what you are looking at, keeping
|
|
41
|
+
the arrangement it was copied in; a repeat paste steps aside so copies do not hide each other.
|
|
42
|
+
`Ctrl+D` puts a second of the selection beside it and leaves the clipboard alone. Each is one step
|
|
43
|
+
on the undo timeline, and what lands is what is selected afterwards, ready to be dragged where it
|
|
44
|
+
is wanted. One clipboard serves both phases and every group body, so a copy taken in INIT pastes in
|
|
45
|
+
UPDATE. It is the editor's own clipboard rather than the system one: what it holds is node types,
|
|
46
|
+
which only mean anything to a canvas that shares the library.
|
|
47
|
+
- **An input holds one wire.** Drop a second one on it and it replaces the first, in one step on the
|
|
48
|
+
undo timeline — the editor cannot be made to put two sources on an input. Drag *out* of an input
|
|
49
|
+
that already has one and you are holding that wire rather than making another: let it go on
|
|
50
|
+
another input to move it there, on the port it came from to leave it alone, and on open canvas to
|
|
51
|
+
take it off.
|
|
38
52
|
- **Drop a wire on empty canvas** and the same menu opens, narrowed to the types that have a port
|
|
39
53
|
which could take it — the ones with an input, when the wire came out of an output — and picking one
|
|
40
54
|
wires it up as it arrives. The node and the wire are one step on the undo timeline, because they
|
|
@@ -61,8 +75,20 @@ edits it at both altitudes.
|
|
|
61
75
|
- Node parameters are edited in the node: four fields for a vector, a swatch and an alpha field for
|
|
62
76
|
a colour, a picker for an ISA enum, a picker of the effect's own attributes for an attribute
|
|
63
77
|
reference, `xyzw` for a swizzle.
|
|
64
|
-
-
|
|
65
|
-
|
|
78
|
+
- Two of them are **ramps**, edited as a picture. An **RGBA Gradient** (and an RGB one) is a strip of
|
|
79
|
+
the colour it produces with its stops underneath: drag a stop, click the lane to add one — in the
|
|
80
|
+
colour the gradient already is there, so adding never changes anything — and middle-click to remove.
|
|
81
|
+
A **Curve** is the unit square with its keys in it, and the picker under it decides the selected
|
|
82
|
+
key's tangents. Neither is sampled from a table at runtime: both are written out into the program as
|
|
83
|
+
arithmetic, which is what the **Code** tab shows. `Curve Table`, which *is* the table, is the other
|
|
84
|
+
node — it takes a row handle rather than a curve.
|
|
85
|
+
- The strip along the bottom lists every problem with the effect, from **both** phases, loudest
|
|
86
|
+
first. Click one to jump to the phase it is in and select the node; the node is outlined in the
|
|
87
|
+
graph too.
|
|
88
|
+
- **A node nothing reads is not a problem.** Only what reaches a sink is compiled, so half-built work
|
|
89
|
+
sitting next to a working graph cannot break it: such a node is dimmed, noted once at the bottom of
|
|
90
|
+
the strip, and nothing else found against it — an unbound input, a mistyped value — is reported at
|
|
91
|
+
all. The strip still says there are no problems, because there are none.
|
|
66
92
|
|
|
67
93
|
**Code** is the same effect as instructions.
|
|
68
94
|
|
|
@@ -106,14 +132,27 @@ be gone exactly when it is wanted.
|
|
|
106
132
|
and the preview carries on with the last good program.
|
|
107
133
|
- Add an attribute in the inspector, then bind a render channel to it. Remove one that a channel was
|
|
108
134
|
bound to: the channel unbinds, and every node that named it is reported against the node.
|
|
135
|
+
- Drag the wire out of a bound input and drop it on the input below. It moves, rather than being
|
|
136
|
+
copied — and `Ctrl+Z` puts it back in one go. Drag it out again and let go over open canvas: it is
|
|
137
|
+
gone, and the menu opens offering what could take the value it was carrying.
|
|
109
138
|
- Drag a wire out of an output and let go over open canvas. Only the nodes that could take it are
|
|
110
139
|
offered; pick one and it arrives already wired.
|
|
111
140
|
- Drag a box around the four or five nodes that build the initial direction and press `Ctrl+G`. The graph gets
|
|
112
141
|
smaller and the program does not change at all — check it in **Code**. Open the group, rename it in
|
|
113
142
|
the breadcrumb, and watch the node on the canvas behind it change with it.
|
|
143
|
+
- Select the two or three nodes that make the initial speed, press `Ctrl+D`, and drag the copy
|
|
144
|
+
somewhere. Then `Ctrl+C`, switch to **UPDATE**, and `Ctrl+V`: the same nodes, wired the same way, in
|
|
145
|
+
the other phase. `Ctrl+Z` takes the whole paste back in one go.
|
|
114
146
|
- Add a `Simplex Noise 3D` and open it. Three hundred instructions of arithmetic, drawn — and read
|
|
115
147
|
only, because it is one of the library's own. `Curl Noise 4D` is twelve of those; the **Code** tab
|
|
116
148
|
is where to see what that means.
|
|
149
|
+
- Add a `Flow Noise 3D` instead and wire `alpha` to the elapsed time. It is the same kind of field
|
|
150
|
+
with two differences worth the instructions: its gradients turn as `alpha` moves, so the field
|
|
151
|
+
swirls in place rather than sliding past, and it hands back its own derivative alongside the value.
|
|
152
|
+
`Tiling Flow Noise 3D` is that with a period you can name, per axis.
|
|
153
|
+
- Drop an `RGBA Gradient` on a `Write Attribute` bound to `color`, wire `t` to the particle's
|
|
154
|
+
normalised age, and drag the stops while the preview runs. Then look at **Code**: the gradient is a
|
|
155
|
+
literal, a saturate and a multiply-add per stop, and there is no table anywhere.
|
|
117
156
|
- Set **blend** to `alpha` and back to `additive`. The preview composites accordingly.
|
|
118
157
|
- `Ctrl+Z` in the graph. Every edit — a wire, a move, a parameter, a node from the menu — is one
|
|
119
158
|
timeline.
|
|
@@ -150,6 +189,8 @@ used only here:
|
|
|
150
189
|
| making one out of a selection | `src/shade/renderer/particles/graph/make_particle_group.js` |
|
|
151
190
|
| a group in a file | `src/shade/renderer/particles/graph/particle_group_json.js` |
|
|
152
191
|
| the groups the editor ships with | `src/shade/renderer/particles/graph/groups/` |
|
|
192
|
+
| a gradient and a curve, and the arithmetic they become | `src/shade/renderer/particles/graph/particle_ramp.js` |
|
|
193
|
+
| the controls those two are edited with | `editor/view/particles/effect/ParticleGradientEditorView.js`, `ParticleCurveEditorView.js` |
|
|
153
194
|
| code layer | `editor/view/particles/effect/ParticleCodeEditorView.js` |
|
|
154
195
|
| emitter + attributes | `editor/view/particles/effect/ParticleEmitterInspectorView.js` |
|
|
155
196
|
| preview | `editor/view/particles/effect/ParticlePreviewView.js` |
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"particle_prototype.d.ts","sourceRoot":"","sources":["../../../../../src/shade/playground/particle_system/particle_prototype.js"],"names":[],"mappings":"AAYA;;;;;;;;;;;;;;GAcG;AAEH;;;;;;;;;GASG;AACH;IAL4B,UAAU,GAA3B,MAAM;IACW,WAAW,GAA5B,MAAM;IACW,eAAe,GAAhC,MAAM;;YACK,cAAc;YAAU,MAAM;aAAW,MAAM;EAgHpE;AAED;;;;GAIG;AACH;YAFsB,cAAc;YAAU,MAAM;aAAW,MAAM;
|
|
1
|
+
{"version":3,"file":"particle_prototype.d.ts","sourceRoot":"","sources":["../../../../../src/shade/playground/particle_system/particle_prototype.js"],"names":[],"mappings":"AAYA;;;;;;;;;;;;;;GAcG;AAEH;;;;;;;;;GASG;AACH;IAL4B,UAAU,GAA3B,MAAM;IACW,WAAW,GAA5B,MAAM;IACW,eAAe,GAAhC,MAAM;;YACK,cAAc;YAAU,MAAM;aAAW,MAAM;EAgHpE;AAED;;;;GAIG;AACH;YAFsB,cAAc;YAAU,MAAM;aAAW,MAAM;EAapE;AAED;;;;;;;;;;;;;GAaG;AACH,yCANW,OAAO,+BAA+B,EAAE,KAAK;IAEa,IAAI,GAA9D,OAAO,gCAAgC,EAAE,MAAM;;UAEtC,eAAe;WAAS,eAAe;EAe1D;+BA3L8B,mDAAmD;gCAElD,qDAAqD"}
|
|
@@ -135,13 +135,13 @@ export function fire_effect({ size_curve, alpha_curve, flipbook_frames = 16 } =
|
|
|
135
135
|
const effect = create_particle_effect({ layout, init, update });
|
|
136
136
|
|
|
137
137
|
const emitter = {
|
|
138
|
-
effect,
|
|
138
|
+
...effect,
|
|
139
139
|
spawn_rate: 120,
|
|
140
140
|
flags: { blend: EMITTER_BLEND.ADDITIVE, projection: EMITTER_PROJECTION.BILLBOARD },
|
|
141
141
|
render: { position: "position", size: "size", color: "color", frame: "frame" },
|
|
142
142
|
bounds: { center: [0, 1.5, 0], radius: 2.5 },
|
|
143
|
-
//
|
|
144
|
-
|
|
143
|
+
// No texture, so the flipbook runs over the default atlas — one white texel, read as a
|
|
144
|
+
// 4x4 grid of it. A real effect names an image and the system packs it.
|
|
145
145
|
flipbook: [4, 4],
|
|
146
146
|
};
|
|
147
147
|
|
|
@@ -156,12 +156,11 @@ export function fire_effect({ size_curve, alpha_curve, flipbook_frames = 16 } =
|
|
|
156
156
|
export function smoke_effect() {
|
|
157
157
|
const { layout, effect } = fire_effect({ flipbook_frames: 8 });
|
|
158
158
|
const emitter = {
|
|
159
|
-
effect,
|
|
159
|
+
...effect,
|
|
160
160
|
spawn_rate: 25,
|
|
161
161
|
flags: { blend: EMITTER_BLEND.ALPHA, projection: EMITTER_PROJECTION.BILLBOARD, soft_depth: true, lighting: true, sort: true },
|
|
162
162
|
render: { position: "position", size: "size", color: "color", frame: "frame" },
|
|
163
163
|
bounds: { center: [0, 3, 0], radius: 5 },
|
|
164
|
-
atlas_region: [0, 0, 1, 1],
|
|
165
164
|
flipbook: [1, 1],
|
|
166
165
|
};
|
|
167
166
|
return { layout, effect, emitter };
|
|
@@ -115,7 +115,7 @@ export function create_particle_emitters() {
|
|
|
115
115
|
// smoke — alpha, soft-depth, a rising column above the fire
|
|
116
116
|
const smoke = ParticleEmitter.from({
|
|
117
117
|
name: "smoke",
|
|
118
|
-
|
|
118
|
+
...make_effect(PARTICLE_EMITTER_MOTION.smoke),
|
|
119
119
|
spawn_rate: 60,
|
|
120
120
|
flags: { blend: EMITTER_BLEND.ALPHA, projection: EMITTER_PROJECTION.BILLBOARD, soft_depth: true },
|
|
121
121
|
render: { position: "position", size: "size", color: "color" },
|
|
@@ -127,7 +127,7 @@ export function create_particle_emitters() {
|
|
|
127
127
|
// sparks — additive, velocity-stretched, fast, short-lived, under gravity, by the block
|
|
128
128
|
const sparks = ParticleEmitter.from({
|
|
129
129
|
name: "sparks",
|
|
130
|
-
|
|
130
|
+
...make_effect(PARTICLE_EMITTER_MOTION.sparks),
|
|
131
131
|
spawn_rate: 350,
|
|
132
132
|
flags: { blend: EMITTER_BLEND.ADDITIVE, projection: EMITTER_PROJECTION.STRETCHED },
|
|
133
133
|
render: { position: "position", size: "size", color: "color", velocity: "velocity" },
|
|
@@ -139,7 +139,7 @@ export function create_particle_emitters() {
|
|
|
139
139
|
// dust — alpha, soft-depth, a slow wide drift across the ground
|
|
140
140
|
const dust = ParticleEmitter.from({
|
|
141
141
|
name: "dust",
|
|
142
|
-
|
|
142
|
+
...make_effect(PARTICLE_EMITTER_MOTION.dust),
|
|
143
143
|
spawn_rate: 120,
|
|
144
144
|
flags: { blend: EMITTER_BLEND.ALPHA, projection: EMITTER_PROJECTION.BILLBOARD, soft_depth: true },
|
|
145
145
|
render: { position: "position", size: "size", color: "color" },
|
|
@@ -155,7 +155,7 @@ export function create_particle_emitters() {
|
|
|
155
155
|
|
|
156
156
|
const torch = ParticleEmitter.from({
|
|
157
157
|
name: "torch",
|
|
158
|
-
|
|
158
|
+
...make_effect(PARTICLE_EMITTER_MOTION.torch),
|
|
159
159
|
spawn_rate: 200,
|
|
160
160
|
flags: { blend: EMITTER_BLEND.ADDITIVE, projection: EMITTER_PROJECTION.BILLBOARD },
|
|
161
161
|
render: { position: "position", size: "size", color: "color" },
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Renderer.d.ts","sourceRoot":"","sources":["../../../../src/shade/renderer/Renderer.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"Renderer.d.ts","sourceRoot":"","sources":["../../../../src/shade/renderer/Renderer.js"],"names":[],"mappings":"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"}
|
|
@@ -67,6 +67,7 @@ import { RasterizationJob } from "./rasterize/RasterizationJob.js";
|
|
|
67
67
|
import { graph_rasterize_scene } from "./rasterize/standard/graph_rasterize_scene.js";
|
|
68
68
|
import { ReSTIRDI } from "./restir/di/ReSTIRDI.js";
|
|
69
69
|
import { GPUParticleSystem } from "./particles/GPUParticleSystem.js";
|
|
70
|
+
import { ParticleRenderMode } from "./particles/ParticleRenderMode.js";
|
|
70
71
|
import { SceneManager } from "./scene/SceneManager.js";
|
|
71
72
|
import { ShadeIndirectLightingMode } from "./ShadeIndirectLightingMode.js";
|
|
72
73
|
import { ShadeTransparencyMode } from "./ShadeTransparencyMode.js";
|
|
@@ -2329,11 +2330,22 @@ export class Renderer {
|
|
|
2329
2330
|
if (this.feature_particles_enabled) {
|
|
2330
2331
|
const particles = this.particles(scene_ctx);
|
|
2331
2332
|
|
|
2332
|
-
|
|
2333
|
+
// The simulation runs here; the drawing is the side channels', below. AVBOIT mode is
|
|
2334
|
+
// what says so: the colour comes back untouched, no sort is recorded, and none of the
|
|
2335
|
+
// sort's scratch is ever allocated, because the accumulators it would feed are sums.
|
|
2336
|
+
//
|
|
2337
|
+
// Not conditional on {@link transparency_mode}. MBOIT has no particle channel, so under
|
|
2338
|
+
// it the particles simulate and are not drawn — the same as before this was a mode, and
|
|
2339
|
+
// the `ShadeTransparencyMode` docs say why the legacy path stays as it is. Giving MBOIT
|
|
2340
|
+
// `BILLBOARD` here would draw them, but over the transparency composite rather than
|
|
2341
|
+
// through it, which is a worse picture than none.
|
|
2342
|
+
current_color_out = particles.execute({
|
|
2333
2343
|
graph,
|
|
2334
2344
|
camera: gr_buffer_camera_current,
|
|
2335
2345
|
scene_database: gr_scene_database_for_velocity,
|
|
2346
|
+
color: current_color_out,
|
|
2336
2347
|
dt: time_delta_seconds,
|
|
2348
|
+
mode: ParticleRenderMode.AVBOIT,
|
|
2337
2349
|
});
|
|
2338
2350
|
|
|
2339
2351
|
particle_side_channels.push(particles);
|
|
@@ -33,7 +33,7 @@ authoring: NodeGraph (nodes+ports) ──compile──▶ Program (bytec
|
|
|
33
33
|
standard node library │
|
|
34
34
|
▼
|
|
35
35
|
runtime CPU: ParticleEmitter (a Node3D) ── Scene ──▶ GPUSceneContext (transforms table)
|
|
36
|
-
EmitterRegistry ── GPUDatabase(emitters + emitter_state) ─┤
|
|
36
|
+
EmitterRegistry ── GPUDatabase(emitters + emitter_state) ─┤ ProgramHeap ([header][constants][code])
|
|
37
37
|
GPUParticleSystem (owns every buffer, records the frame)
|
|
38
38
|
▼
|
|
39
39
|
runtime GPU: particle pool (array<u32>, uniform stride) + alive/dead lists + counters
|
|
@@ -128,8 +128,10 @@ A compute stage gets eight storage buffers by default, and the design does not a
|
|
|
128
128
|
things keep every pass under it: the emitter record and the GPU-owned state are two tables of one
|
|
129
129
|
database buffer, read through one binding; and the VM's constants and code are one packed buffer —
|
|
130
130
|
`[header][constants][code]`, the header's first word saying where the code starts
|
|
131
|
-
(`ParticleConstants.PARTICLE_PROGRAM_HEADER_WORDS`). Emit and simulate bind exactly eight;
|
|
132
|
-
|
|
131
|
+
(`ParticleConstants.PARTICLE_PROGRAM_HEADER_WORDS`). Emit and simulate bind exactly eight; their
|
|
132
|
+
wide-register variants bind nine, which is the one place the system spends past the default and is
|
|
133
|
+
still inside the ten the engine demands of an adapter. `particle_shaders_wgsl_validity.spec` pins
|
|
134
|
+
the count for every pass.
|
|
133
135
|
|
|
134
136
|
### The VM (`ParticleVM`)
|
|
135
137
|
|
|
@@ -137,9 +139,20 @@ Register machine, emulator-safe (bounded instruction loop + big `switch`, no sub
|
|
|
137
139
|
recursion, no data-dependent jumps — conditionals are predicated via CMP/SELECT, destruction via
|
|
138
140
|
`KILL`).
|
|
139
141
|
|
|
140
|
-
- Register file: `array<
|
|
141
|
-
|
|
142
|
-
|
|
142
|
+
- Register file: `array<f32>`, a register being one slot and a value of width *w* occupying *w*
|
|
143
|
+
consecutive ones. The interpreter reaches it through `vm_reg_read` / `vm_reg_write`, which a
|
|
144
|
+
**backing chunk** supplies, and the two backings are the two interpreters:
|
|
145
|
+
`vm/chunk_particle_vm_registers_fast.js` puts the file in `var<private>`
|
|
146
|
+
(`PARTICLE_VM_FAST_REGISTER_SLOTS`, dynamically indexed, so its size is the shader's register
|
|
147
|
+
footprint), and `vm/chunk_particle_vm_registers_wide.js` puts it in a storage buffer
|
|
148
|
+
(`PARTICLE_VM_REGISTER_SLOTS` — every slot an 8-bit operand base can name). See **Two
|
|
149
|
+
interpreters** below.
|
|
150
|
+
- Instruction: fixed **4×u32** words `[op | width << 8 | kinds << 16 | dst << 24, s0, s1, s2]`.
|
|
151
|
+
Word 0 packs the opcode (bits 0..7), the lane count (8..10), each source's `VM_KIND` (two bits per
|
|
152
|
+
slot at 16..21) and the destination slot (24..31). A source word means what its kind says: `REG`
|
|
153
|
+
is a base slot plus a swizzle, `IMM` is an `f32` bit pattern read in every lane, and `NONE` is a
|
|
154
|
+
raw field the opcode reads for itself (attribute word-offset+comp / curve handle / builtin id /
|
|
155
|
+
pool index).
|
|
143
156
|
- Constant pool: `array<vec4f>` per program, referenced by `LOAD_CONST`.
|
|
144
157
|
- Two entry sections per program: **INIT** and **UPDATE** (offsets in the emitter record). INIT
|
|
145
158
|
gives an already-allocated record its state; it has no say in whether the particle exists.
|
|
@@ -149,6 +162,35 @@ recursion, no data-dependent jumps — conditionals are predicated via CMP/SELEC
|
|
|
149
162
|
- `CURVE dst, handle, s0`: `dst.x = animation_curve_evaluate(curves[handle], s0.x)` — reuses the
|
|
150
163
|
engine's GPU AnimationCurve chunk + database.
|
|
151
164
|
|
|
165
|
+
#### Two interpreters
|
|
166
|
+
|
|
167
|
+
The register file normally lives in shader registers, which is what makes it fast and what makes it
|
|
168
|
+
small. An effect whose compiled program wants more slots than it holds is not an error and not an
|
|
169
|
+
authoring ceiling: the whole system swaps emit and simulate for variants whose file is a storage
|
|
170
|
+
buffer, and everything runs, slowly.
|
|
171
|
+
|
|
172
|
+
- **The trigger is the set, not the program.** `ProgramHeap` reports `max_register_count` over the
|
|
173
|
+
programs it holds, and `GPUParticleSystem` is where that number is compared against
|
|
174
|
+
`PARTICLE_VM_FAST_REGISTER_SLOTS` — the store has no opinion about what a register budget means,
|
|
175
|
+
and which backing a pass is compiled against is the VM's business. One hungry effect moves every
|
|
176
|
+
emitter onto the wide pair; there is one pipeline per pass and it is chosen once, per frame, in
|
|
177
|
+
`graph_particles`. It moves back when that effect is unregistered: the heap knows what it holds,
|
|
178
|
+
so the number is a maximum over the live set rather than a high-water mark.
|
|
179
|
+
- **The launch is bounded.** The wide passes need a register file per invocation in flight, so they
|
|
180
|
+
do not run one lane per particle — that would size the buffer by pool capacity. They launch
|
|
181
|
+
`PARTICLE_VM_WIDE_LAUNCH_LANES` lanes whatever the workload and walk their input with a grid-stride
|
|
182
|
+
loop, so the file is `LANES * SLOTS * 4` bytes and nothing else. The stride is a whole number of
|
|
183
|
+
workgroups, which is what keeps a wave inside one coherence bucket and the wave-uniform section
|
|
184
|
+
decode sound.
|
|
185
|
+
- **Slot-major, and never cleared.** `vm_registers[slot * LANES + lane]`, so a wave reading one slot
|
|
186
|
+
reads a coalesced run. The buffer is transient and no pass zeroes it: a register is undefined until
|
|
187
|
+
written, and a program that reads one first is corrupt. That is the one place the two backings are
|
|
188
|
+
not interchangeable — the fast file zeroes, so the reference executor and the fast VM agree on a
|
|
189
|
+
value the wide VM has no opinion about.
|
|
190
|
+
- **Held to the same bar.** `vm/chunk_particle_vm.spec.js` runs every parity case, fuzz included,
|
|
191
|
+
against BOTH backings; `shaders/particle_wide_register_passes.spec.js` runs the wide passes against
|
|
192
|
+
the fast ones under the emulator and exercises the grid-stride loop.
|
|
193
|
+
|
|
152
194
|
**Parity strategy.** The opcode numbers + operand semantics live in one source of truth
|
|
153
195
|
(`isa/ParticleVMISA.js`). Two executors implement it: a JS reference VM (`vm/ParticleVMReference.js`)
|
|
154
196
|
and a hand-written WGSL interpreter (`vm/chunk_particle_vm.js`). A spec runs identical programs
|
|
@@ -180,13 +222,34 @@ per-frame transform copy, and an emitter under a GPU-animated joint follows it
|
|
|
180
222
|
CPU-side copy of `transform_global` could not do, since the CPU never updates that matrix for a
|
|
181
223
|
node the GPU owns.
|
|
182
224
|
|
|
225
|
+
**The node knows nothing about the GPU.** A `ParticleEmitter` is a transform, an attribute
|
|
226
|
+
`layout`, a compiled `program`, a `texture` URL, and the emission parameters — all of it the
|
|
227
|
+
author's, all of it meaning the same thing with no device present, all of it what a saved effect is
|
|
228
|
+
made of. Everything the system assigns is a `GPUParticleEmitterContext`, held by the
|
|
229
|
+
`EmitterRegistry` against the emitter and reached through `registry.context(emitter)`: the table
|
|
230
|
+
row, the generation, the program placement, the node's `transforms` row, the atlas patch. So an
|
|
231
|
+
emitter cannot be saved with a row in it, cannot be given one by hand, and "is this emitter live?"
|
|
232
|
+
is asked of the registry rather than read off a `-1` that anything could have written. The record
|
|
233
|
+
writer is where the two meet — `write_emitter_record(record, emitter, context)`, next to the struct
|
|
234
|
+
it fills.
|
|
235
|
+
|
|
236
|
+
Restaging is driven by `Node3D#version`, the node's own change counter, which the renderer already
|
|
237
|
+
reads to decide whether a transform needs re-uploading; the context remembers the version its row
|
|
238
|
+
was staged from. An author who edits an emitter says so the way they say it for any node —
|
|
239
|
+
`needsUpdate = true` — and there is no second flag to forget. A change to the context itself (a
|
|
240
|
+
`transforms` row, a repacked atlas patch) moves no version, so the context marks itself instead.
|
|
241
|
+
|
|
183
242
|
### Emitter table (`GPUDatabase`)
|
|
184
243
|
|
|
185
244
|
One `emitters` table (CPU-managed, low churn). Row = `PARTICLE_EMITTER_STRUCT`: program
|
|
186
245
|
offsets+lengths, constant-pool offset, seed, spawn rate, **node** (transforms row), **generation**,
|
|
187
246
|
bounds sphere, flags (lighting/soft/sort/cull/blend/projection), render binding (attr offsets for
|
|
188
|
-
position/size/color/rotation/frame/velocity), atlas region + flipbook grid, and the
|
|
189
|
-
the coherence pass buckets on.
|
|
247
|
+
position/size/color/rotation/frame/velocity), atlas region + flipbook grid, and the program id
|
|
248
|
+
the coherence pass buckets on. The atlas region is resolved, not authored: the emitter names an
|
|
249
|
+
image and the system packs it, the way `ShaderManager` packs the old engine's sprites, so a repack
|
|
250
|
+
moves every patch without any emitter changing. The seed is resolved too — an emitter left at 0 gets
|
|
251
|
+
its registration's generation, which no other emitter of the registry shares, rather than being
|
|
252
|
+
written to. Programs+constants live in a packed `ProgramHeap` buffer
|
|
190
253
|
(variable length → not a fixed-stride table).
|
|
191
254
|
|
|
192
255
|
The struct is the ONLY statement of that layout. The JS writer is the database's
|
|
@@ -209,11 +272,26 @@ or a later tenant's — so a hard removal frees the emitter's particles within a
|
|
|
209
272
|
row cannot adopt a stranger's. Graceful retirement (rate to zero, remove once the tail has died)
|
|
210
273
|
remains an author's choice rather than a correctness rule.
|
|
211
274
|
|
|
212
|
-
Programs are the
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
275
|
+
**Programs are edited the same way.** `ProgramHeap` is a pair of range allocators
|
|
276
|
+
(`OffsetAllocator`) over the two sections of the packed buffer, keyed by a `HashMap` on the bytecode
|
|
277
|
+
itself — `ParticleProgram` answers `equals`/`hash`, so content deduplication is the map's doing
|
|
278
|
+
rather than a stringified key's. `acquire` takes a reference and `release` gives one back, so the
|
|
279
|
+
last emitter of an effect is what unpacks it, and `EmitterRegistry.set_program` swaps an emitter onto
|
|
280
|
+
different bytecode while it is live. What makes that possible is that a program is **relocatable**:
|
|
281
|
+
instructions carry no absolute addresses and constant references are program-local, so the heap can
|
|
282
|
+
move one by copying its words and rewriting the placement.
|
|
283
|
+
|
|
284
|
+
Two things are deliberately NOT reclaimed. **Program ids** are reused rather than renumbered — they
|
|
285
|
+
are baked into every emitter record, so compacting them would mean rewriting the whole table — and
|
|
286
|
+
`bucketCount()` is sized from the id capacity, the set's peak, so it does not move every time an
|
|
287
|
+
effect comes or goes. An id below the peak with nothing in it is an empty bin, which rounds up to
|
|
288
|
+
zero workgroups and shifts nothing after it. **Section capacity** only rises: a repack (which happens
|
|
289
|
+
when a section has no contiguous run long enough) compacts what is live and grows only if it must,
|
|
290
|
+
so a set that peaked at a hundred effects does not pay for a resize every time it returns to three.
|
|
291
|
+
|
|
292
|
+
A repack is the one change no emitter announces, since it is not an edit to any of them.
|
|
293
|
+
`EmitterRegistry.flush` asks the heap once per frame — `placement_version` — and restages every row
|
|
294
|
+
when it has moved.
|
|
217
295
|
|
|
218
296
|
Every row of a frame is staged through one module-static record (`EmitterRegistry`), so a flush
|
|
219
297
|
allocates nothing however many rows it restages.
|
|
@@ -247,8 +325,8 @@ unit, branch the opcode switch on a scalar and index the register file through M
|
|
|
247
325
|
waterfall. A wave holding two programs would run one over the other's particles, so the coherence
|
|
248
326
|
pass is part of simulate's correctness. Emit keeps a per-lane decode: its waves span emitters.
|
|
249
327
|
|
|
250
|
-
The bucket key is the **program**, not the emitter: `
|
|
251
|
-
back a
|
|
328
|
+
The bucket key is the **program**, not the emitter: `ProgramHeap` deduplicates by content and hands
|
|
329
|
+
back a `program_id` the emitter record carries, so emitters compiled from the same graph share
|
|
252
330
|
one bucket. Each bucket is padded out to `PARTICLE_SIMULATE_WORKGROUP_SIZE` (64 — a multiple of both
|
|
253
331
|
plausible subgroup widths, so no shader needs to query `subgroup_size`), which is what makes the
|
|
254
332
|
grouping hold at wave granularity: an unpadded boundary lands mid-wave and that wave spans two
|
|
@@ -345,12 +423,17 @@ src/shade/renderer/particles/
|
|
|
345
423
|
isa/ParticleAssembler.js tiny assembler (build programs in tests/library)
|
|
346
424
|
vm/ParticleVMReference.js JS reference executor
|
|
347
425
|
vm/chunk_particle_vm.js WGSL interpreter CodeChunk (parity target)
|
|
426
|
+
vm/chunk_particle_vm_registers_fast.js register file in var<private> — the interpreter that runs
|
|
427
|
+
vm/chunk_particle_vm_registers_wide.js register file in storage — the fallback
|
|
428
|
+
shaders/chunk_particle_simulate_step.js one particle's simulate, shared by both simulate shaders
|
|
429
|
+
shaders/chunk_particle_emit_step.js one newborn's emit, shared by both emit shaders
|
|
348
430
|
graph/ParticleNodeDescription.js node type base (ports + lowering)
|
|
349
431
|
graph/ParticleNodeRegistry.js standard node library (a NodeRegistry)
|
|
350
432
|
graph/particle_graph_authoring.js authoring sugar over core/model/node-graph
|
|
351
433
|
graph/compile_particle_graph.js graph → Program (register alloc, const intern)
|
|
352
434
|
layout/ParticleLayout.js attribute schema ↔ record word offsets
|
|
353
435
|
data/PARTICLE_EMITTER_STRUCT.js the emitter row + flag/blend/projection encoding
|
|
436
|
+
data/particle_emitter_record.js emitter + context -> one row of that struct
|
|
354
437
|
data/PARTICLE_EMITTER_STATE.js the GPU-owned per-emitter state row (second table of the database)
|
|
355
438
|
data/PARTICLE_DATABASE_SPEC.js the GPUDatabase schema, and the emitter table's descriptor
|
|
356
439
|
data/PARTICLE_COUNTERS.js counter slot indices
|
|
@@ -358,9 +441,11 @@ src/shade/renderer/particles/
|
|
|
358
441
|
coherence/particle_program_buckets.js CPU reference for the simulation-order bucketing
|
|
359
442
|
coherence/shader_particle_bucket.js reset / histogram / pad / scatter / fill
|
|
360
443
|
coherence/graph_particle_bucket.js frame-graph wiring, around graph_prefix_scan_csdldf
|
|
361
|
-
runtime/
|
|
362
|
-
runtime/
|
|
363
|
-
runtime/
|
|
444
|
+
runtime/ProgramHeap.js the one packed [header][constants][code] buffer, allocator-backed
|
|
445
|
+
runtime/ProgramPlacement.js where one program sits in it — what an emitter record carries
|
|
446
|
+
runtime/ParticleEmitter.js one emitter — a Node3D and an effect, with no GPU in it
|
|
447
|
+
runtime/GPUParticleEmitterContext.js what a registry assigns one: row, generation, placement, patch
|
|
448
|
+
runtime/EmitterRegistry.js GPUDatabase(emitters) + the live emitters + their contexts + the program heap
|
|
364
449
|
runtime/create_particle_effect.js layout + INIT/UPDATE graphs → compiled effect
|
|
365
450
|
shaders/shader_particle_spawn_commands.js CPU bursts → pending spawns
|
|
366
451
|
shaders/shader_particle_emitter_tick.js per-emitter spawn decision
|
|
@@ -384,7 +469,7 @@ src/shade/renderer/particles/
|
|
|
384
469
|
|
|
385
470
|
## Testing
|
|
386
471
|
|
|
387
|
-
- Pure JS: layout packing, assembler, register allocator, node compiler,
|
|
472
|
+
- Pure JS: layout packing, assembler, register allocator, node compiler, heap/emitter/registry
|
|
388
473
|
bookkeeping (via `SoftwareGPUDevice`), the header encoding.
|
|
389
474
|
- WGSL via emulator: VM opcode parity (JS vs WGSL), curve sampling, sort key/depth, atlas+flipbook
|
|
390
475
|
UV math, billboard expansion, soft-depth fade, and every compute pass on small fixtures — the tick
|
|
@@ -6,16 +6,29 @@
|
|
|
6
6
|
* ## What it owns
|
|
7
7
|
*
|
|
8
8
|
* Every piece of persistent GPU state: the particle pool, the ping-pong alive lists, the dead
|
|
9
|
-
* free-list, the counters, both indirect-args buffers, the simulation-order (coherence)
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
9
|
+
* free-list, the counters, both indirect-args buffers, the simulation-order (coherence) scratch,
|
|
10
|
+
* the emitter database (the emitter table and the GPU-owned state table, one buffer), the packed
|
|
11
|
+
* program buffer, and the spawn-command ring. Buffers that depend on the emitter set — the
|
|
12
|
+
* coherence scratch on the number of distinct programs, the program buffer on the heap, the
|
|
13
|
+
* database on its own pages — are grown inside {@link execute}, the way ReSTIR's reservoirs follow
|
|
14
|
+
* the resolution. The render-order (sort) scratch is not in that list because it is not
|
|
15
|
+
* unconditional: see below.
|
|
15
16
|
*
|
|
16
17
|
* Every pass stays within the eight storage buffers a stage gets by default: the emitter record
|
|
17
18
|
* and the GPU-owned state are two tables of one database buffer, and the VM's constants and code
|
|
18
|
-
* are one packed buffer.
|
|
19
|
+
* are one packed buffer. The one exception is the wide-register fallback (below), whose emit and
|
|
20
|
+
* simulate passes bind a ninth for the register file — inside the ten the engine already demands of
|
|
21
|
+
* an adapter, but past the default.
|
|
22
|
+
*
|
|
23
|
+
* ## Two interpreters
|
|
24
|
+
*
|
|
25
|
+
* The VM's register file normally lives in shader registers, and is therefore small — see
|
|
26
|
+
* {@link ./ParticleConstants.js PARTICLE_VM_FAST_REGISTER_SLOTS}. An effect whose compiled program
|
|
27
|
+
* needs more than it holds does not fail: the whole system swaps emit and simulate for variants
|
|
28
|
+
* that keep the file in a storage buffer, which is far slower and effectively unbounded. The choice
|
|
29
|
+
* is per-frame, whole-system, and made here — the registry reports `max_register_count` over the
|
|
30
|
+
* effects it holds and this is where that number meets the VM's; nothing about authoring a graph has
|
|
31
|
+
* a register ceiling.
|
|
19
32
|
*
|
|
20
33
|
* ## Emitters are scene nodes
|
|
21
34
|
*
|
|
@@ -34,15 +47,20 @@
|
|
|
34
47
|
* command list that a pass adds to the emitter's pending spawns, on the same path as everything
|
|
35
48
|
* else. See `graph_particles.js` for the frame.
|
|
36
49
|
*
|
|
37
|
-
* ## Drawing
|
|
50
|
+
* ## Drawing, and the one thing the mode changes
|
|
38
51
|
*
|
|
39
|
-
* {@link
|
|
40
|
-
*
|
|
41
|
-
*
|
|
42
|
-
*
|
|
43
|
-
*
|
|
44
|
-
*
|
|
45
|
-
*
|
|
52
|
+
* {@link execute} is the whole per-frame call, once per frame. It always records everything that
|
|
53
|
+
* moves particles and leaves the alive list and the indirect draw args as graph handles; what it
|
|
54
|
+
* records after that is the {@link ParticleRenderMode} it was given.
|
|
55
|
+
*
|
|
56
|
+
* `BILLBOARD` sorts the alive list back-to-front and draws it over a colour target, because
|
|
57
|
+
* premultiplied over-blending is order-dependent. `AVBOIT` records neither: under the renderer the
|
|
58
|
+
* system is an `AVBOITSideChannel`, and the transparency orchestrator asks it for its occupancy, its
|
|
59
|
+
* extinction and its draw at the three points where the transparent meshes have contributed theirs
|
|
60
|
+
* ({@link avboit_occupancy}, {@link avboit_splat}, {@link avboit_draw}). Those read the same handles
|
|
61
|
+
* and composite into a volume and a set of accumulators that are sums, so an ordering would buy
|
|
62
|
+
* nothing — and the sort is four passes and a scan over every live particle, plus two lists a word
|
|
63
|
+
* per particle each, which is why the mode also decides whether those buffers exist at all.
|
|
46
64
|
*
|
|
47
65
|
* ## Allocation
|
|
48
66
|
*
|
|
@@ -99,7 +117,7 @@ export class GPUParticleSystem {
|
|
|
99
117
|
max_catchup_seconds: number;
|
|
100
118
|
/**
|
|
101
119
|
* View-depth range the render sort quantises: particles nearer than `[0]` share the front bin,
|
|
102
|
-
* farther than `[1]` the back one.
|
|
120
|
+
* farther than `[1]` the back one. Read only by {@link ParticleRenderMode.BILLBOARD}.
|
|
103
121
|
* @type {Float32Array}
|
|
104
122
|
*/
|
|
105
123
|
sort_depth_range: Float32Array;
|
|
@@ -112,7 +130,7 @@ export class GPUParticleSystem {
|
|
|
112
130
|
/** @type {GPUSampler} */
|
|
113
131
|
atlas_sampler: GPUSampler;
|
|
114
132
|
/**
|
|
115
|
-
* The persistent GPU buffers, by the names
|
|
133
|
+
* The persistent GPU buffers, by the names the graph functions bind them under. Exposed for
|
|
116
134
|
* inspection — a harness copying the counters out to display them — never for the frame loop,
|
|
117
135
|
* which reads nothing back. Entries that grow with the emitter set are replaced in place.
|
|
118
136
|
*
|
|
@@ -130,11 +148,15 @@ export class GPUParticleSystem {
|
|
|
130
148
|
*/
|
|
131
149
|
get emitters(): import("./runtime/ParticleEmitter.js").ParticleEmitter[];
|
|
132
150
|
/**
|
|
133
|
-
* Number of simulation-order buckets — one per
|
|
151
|
+
* Number of simulation-order buckets — one per program id the registry can hand out, which is
|
|
152
|
+
* its peak number of distinct compiled programs rather than its current one.
|
|
134
153
|
*
|
|
135
154
|
* This is the coherence pass's only host-provided number, and it is static topology rather than
|
|
136
|
-
* per-frame state: it changes when
|
|
137
|
-
* die. Everything the pass measures per frame stays on the GPU.
|
|
155
|
+
* per-frame state: it changes when an effect the set has never held is registered, not as
|
|
156
|
+
* particles are born and die. Everything the pass measures per frame stays on the GPU. Sizing it
|
|
157
|
+
* from the peak rather than the live count is what keeps it from moving every time an effect is
|
|
158
|
+
* unregistered — the bins of released ids are empty, and an empty bin rounds up to zero
|
|
159
|
+
* workgroups and shifts nothing after it.
|
|
138
160
|
*
|
|
139
161
|
* @returns {number}
|
|
140
162
|
*/
|
|
@@ -154,11 +176,16 @@ export class GPUParticleSystem {
|
|
|
154
176
|
*/
|
|
155
177
|
spawn(emitter: import("./runtime/ParticleEmitter.js").ParticleEmitter, count: number): void;
|
|
156
178
|
/**
|
|
157
|
-
* The
|
|
158
|
-
*
|
|
159
|
-
*
|
|
160
|
-
*
|
|
161
|
-
* transparency pipeline.
|
|
179
|
+
* The system's whole contribution to the frame: the simulation, then whatever `mode` says draws
|
|
180
|
+
* it.
|
|
181
|
+
*
|
|
182
|
+
* {@link ParticleRenderMode.BILLBOARD} adds the depth sort and one billboard draw over `color`
|
|
183
|
+
* with fixed-function blending, for a page with no transparency pipeline of its own.
|
|
184
|
+
* {@link ParticleRenderMode.AVBOIT} adds nothing: the orchestrator draws the particles later in
|
|
185
|
+
* the frame through {@link avboit_occupancy}, {@link avboit_splat} and {@link avboit_draw}, off
|
|
186
|
+
* the handles this just produced, and its accumulators are order-independent — so the sort is
|
|
187
|
+
* skipped and its buffers are never allocated. `color` comes straight back either way, so a
|
|
188
|
+
* caller can assign the result unconditionally and let the mode be the only difference.
|
|
162
189
|
*
|
|
163
190
|
* Call after the scene context has built for the frame (`GPUSceneContext#update`), so every
|
|
164
191
|
* emitter node has its `transforms` row, and after the hierarchy pass has run, so the rows'
|
|
@@ -176,36 +203,22 @@ export class GPUParticleSystem {
|
|
|
176
203
|
* @param {number} params.scene_database graph handle of the scene database — the one the
|
|
177
204
|
* hierarchy pass returned, so this reads the matrices it composed
|
|
178
205
|
* @param {number} params.dt seconds since the previous frame
|
|
179
|
-
* @
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
dt: number;
|
|
186
|
-
}): import("./graph_particles.js").ParticleSimulationHandles;
|
|
187
|
-
/**
|
|
188
|
-
* The whole standalone frame: {@link simulate}, then the depth sort and one billboard draw over
|
|
189
|
-
* a colour target with fixed-function blending. For a page without the renderer's transparency
|
|
190
|
-
* pipeline; under the renderer the drawing is AVBOIT's.
|
|
191
|
-
*
|
|
192
|
-
* @param {object} params every parameter of {@link simulate}, plus a target to draw over
|
|
193
|
-
* @param {import("../../../engine/graphics/render/frame_graph/FrameGraph.js").FrameGraph} params.graph
|
|
194
|
-
* @param {number} params.camera graph handle of the camera uniform buffer
|
|
195
|
-
* @param {number} params.scene_database graph handle of the scene database
|
|
196
|
-
* @param {number} params.dt seconds since the previous frame
|
|
197
|
-
* @param {number} params.color graph handle of the colour target to draw over
|
|
198
|
-
* @param {number} params.depth graph handle of the scene depth (tested, never written)
|
|
199
|
-
* @returns {number} the colour handle after the particle draw
|
|
206
|
+
* @param {ParticleRenderMode} [params.mode] who draws, and so whether there is a sort
|
|
207
|
+
* @param {number} [params.color] graph handle of the colour target to draw over. Required by
|
|
208
|
+
* `BILLBOARD`; returned untouched by `AVBOIT`
|
|
209
|
+
* @param {number} [params.depth] graph handle of the scene depth (tested, never written).
|
|
210
|
+
* Required by `BILLBOARD`
|
|
211
|
+
* @returns {number|undefined} the colour handle after the particle draw, or `color` unchanged
|
|
200
212
|
*/
|
|
201
|
-
execute({ graph, camera, scene_database, color, depth, dt }: {
|
|
213
|
+
execute({ graph, camera, scene_database, color, depth, dt, mode }: {
|
|
202
214
|
graph: import("../../../engine/graphics/render/frame_graph/FrameGraph.js").FrameGraph;
|
|
203
215
|
camera: number;
|
|
204
216
|
scene_database: number;
|
|
205
217
|
dt: number;
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
218
|
+
mode?: ParticleRenderMode;
|
|
219
|
+
color?: number;
|
|
220
|
+
depth?: number;
|
|
221
|
+
}): number | undefined;
|
|
209
222
|
/**
|
|
210
223
|
* `AVBOITSideChannel#avboit_occupancy`: the emitters' bounds spheres, as depth slices.
|
|
211
224
|
*
|
|
@@ -295,4 +308,5 @@ export class GPUParticleSystem {
|
|
|
295
308
|
#private;
|
|
296
309
|
}
|
|
297
310
|
import { EmitterRegistry } from "./runtime/EmitterRegistry.js";
|
|
311
|
+
import { ParticleRenderMode } from "./ParticleRenderMode.js";
|
|
298
312
|
//# sourceMappingURL=GPUParticleSystem.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"GPUParticleSystem.d.ts","sourceRoot":"","sources":["../../../../../src/shade/renderer/particles/GPUParticleSystem.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"GPUParticleSystem.d.ts","sourceRoot":"","sources":["../../../../../src/shade/renderer/particles/GPUParticleSystem.js"],"names":[],"mappings":"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"}
|