@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
|
@@ -1,517 +1,524 @@
|
|
|
1
|
-
import { ParticleGroupBuilder } from "../ParticleGroupBuilder.js";
|
|
2
|
-
import { PARTICLE_TYPE_F32, PARTICLE_TYPE_VEC3, PARTICLE_TYPE_VEC4 } from "../ParticleValueType.js";
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* Simplex noise, and the curl fields built out of it.
|
|
6
|
-
*
|
|
7
|
-
* These are the big ones. `simplex3` is around a hundred and thirty instructions and `curl4` is
|
|
8
|
-
* something over two thousand, because a curl needs twelve noise samples and there is no loop to put
|
|
9
|
-
* them in. Nothing here is cheap and nothing here pretends to be; what they are is *correct*, and
|
|
10
|
-
* available as one node instead of as a page of arithmetic an author has to get right themselves.
|
|
11
|
-
*
|
|
12
|
-
* ## Where the algorithm comes from
|
|
13
|
-
*
|
|
14
|
-
* Simplex noise is Ken Perlin's, and the formulation is Stefan Gustavson and Ashima Arts' well-known
|
|
15
|
-
* GLSL one — the same skew, the same permutation polynomial and the same gradient table
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
21
|
-
*
|
|
22
|
-
*
|
|
23
|
-
*
|
|
24
|
-
* and
|
|
25
|
-
*
|
|
26
|
-
*
|
|
27
|
-
*
|
|
28
|
-
*
|
|
29
|
-
*
|
|
30
|
-
*
|
|
31
|
-
*
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
*
|
|
62
|
-
*
|
|
63
|
-
* A
|
|
64
|
-
*
|
|
65
|
-
*
|
|
66
|
-
*
|
|
67
|
-
*
|
|
68
|
-
* @
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
*
|
|
83
|
-
*
|
|
84
|
-
*
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
return g.mad(g.f(
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
/**
|
|
98
|
-
* One corner's contribution to a simplex sum: `max(0.6 - |x|^2, 0)^4 * dot(gradient, x)`.
|
|
99
|
-
*
|
|
100
|
-
* The fourth power of a radial falloff that reaches zero at the edge of a corner's influence, which
|
|
101
|
-
* is what makes the sum continuous and its derivative continuous with it.
|
|
102
|
-
*
|
|
103
|
-
* @param {ParticleGroupBuilder} g
|
|
104
|
-
* @param {*} offset the vector from the corner to the point
|
|
105
|
-
* @param {*} gradient the corner's gradient, already normalised
|
|
106
|
-
* @returns {*} a scalar
|
|
107
|
-
*/
|
|
108
|
-
function corner_contribution(g, offset, gradient) {
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
*
|
|
121
|
-
*
|
|
122
|
-
*
|
|
123
|
-
*
|
|
124
|
-
*
|
|
125
|
-
*
|
|
126
|
-
*
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
const
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
const
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
const
|
|
140
|
-
|
|
141
|
-
const
|
|
142
|
-
const
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
const
|
|
146
|
-
|
|
147
|
-
//
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
const
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
const
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
const
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
g.
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
}
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
*
|
|
221
|
-
*
|
|
222
|
-
*
|
|
223
|
-
*
|
|
224
|
-
*
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
*
|
|
250
|
-
*
|
|
251
|
-
*
|
|
252
|
-
*
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
const
|
|
267
|
-
|
|
268
|
-
const
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
const
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
//
|
|
285
|
-
//
|
|
286
|
-
//
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
}
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
}
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
*
|
|
393
|
-
*
|
|
394
|
-
*
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
*
|
|
415
|
-
*
|
|
416
|
-
*
|
|
417
|
-
*
|
|
418
|
-
* the
|
|
419
|
-
*
|
|
420
|
-
*
|
|
421
|
-
*
|
|
422
|
-
*
|
|
423
|
-
*
|
|
424
|
-
*
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
g
|
|
451
|
-
g
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
1
|
+
import { ParticleGroupBuilder } from "../ParticleGroupBuilder.js";
|
|
2
|
+
import { PARTICLE_TYPE_F32, PARTICLE_TYPE_VEC3, PARTICLE_TYPE_VEC4 } from "../ParticleValueType.js";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Simplex noise, and the curl fields built out of it.
|
|
6
|
+
*
|
|
7
|
+
* These are the big ones. `simplex3` is around a hundred and thirty instructions and `curl4` is
|
|
8
|
+
* something over two thousand, because a curl needs twelve noise samples and there is no loop to put
|
|
9
|
+
* them in. Nothing here is cheap and nothing here pretends to be; what they are is *correct*, and
|
|
10
|
+
* available as one node instead of as a page of arithmetic an author has to get right themselves.
|
|
11
|
+
*
|
|
12
|
+
* ## Where the algorithm comes from
|
|
13
|
+
*
|
|
14
|
+
* Simplex noise is Ken Perlin's, and the formulation is Stefan Gustavson and Ashima Arts' well-known
|
|
15
|
+
* GLSL one — the same skew, the same permutation polynomial and the same gradient table. It is
|
|
16
|
+
* transcribed rather than reinvented: an author who has seen simplex noise in a shader should get
|
|
17
|
+
* the noise they expect, and a hash or a skew of my own would be a different function wearing the
|
|
18
|
+
* same name.
|
|
19
|
+
*
|
|
20
|
+
* One thing is deliberately *not* transcribed. The GLSL normalises each corner's gradient with
|
|
21
|
+
* `taylorInvSqrt` — a straight line through the band the gradient table's squared lengths fall in,
|
|
22
|
+
* because a reciprocal square root was worth avoiding where that shader was written. This VM has
|
|
23
|
+
* `NORMALIZE` as one instruction, and it is exact. So the gradients here are normalised properly,
|
|
24
|
+
* which is four instructions fewer per corner and a field that differs from the GLSL's by that
|
|
25
|
+
* approximation's error — a fraction of a percent, in the direction of the noise the formulation
|
|
26
|
+
* describes rather than away from it. Everything that decides the *shape* of the field, which is to
|
|
27
|
+
* say which simplex a point falls in and which gradient each corner is handed, is transcribed
|
|
28
|
+
* exactly.
|
|
29
|
+
*
|
|
30
|
+
* ## Why it is written the way it is
|
|
31
|
+
*
|
|
32
|
+
* The shader version keeps four corners in flight at once — four offsets, four gradients, four
|
|
33
|
+
* weights — as `vec4`s across corners. Done that way here it needs upwards of forty-five registers,
|
|
34
|
+
* and the fast interpreter's register file is its single largest cost (see
|
|
35
|
+
* {@link ../../ParticleConstants.js PARTICLE_VM_FAST_REGISTER_SLOTS}). So the corners are summed one
|
|
36
|
+
* at a time instead: each corner's offset, gradient and weight are computed, folded into a running
|
|
37
|
+
* total, and dropped. The result is identical and the high-water mark is far lower, which is the
|
|
38
|
+
* difference between a node that runs on the fast interpreter and one that drags the whole system
|
|
39
|
+
* onto the wide one.
|
|
40
|
+
*
|
|
41
|
+
* The permutation itself stays a `vec4` — it is one hash of four corners at once and splitting it
|
|
42
|
+
* would quadruple the work rather than move it.
|
|
43
|
+
*/
|
|
44
|
+
|
|
45
|
+
/** Skew factor for the 3-simplex lattice: `1/3`. @type {number} */
|
|
46
|
+
const F3 = 1 / 3;
|
|
47
|
+
|
|
48
|
+
/** Unskew factor for the 3-simplex lattice: `1/6`. @type {number} */
|
|
49
|
+
const G3 = 1 / 6;
|
|
50
|
+
|
|
51
|
+
/** Skew factor for the 4-simplex lattice: `(sqrt(5) - 1) / 4`. @type {number} */
|
|
52
|
+
const F4 = 0.309016994374947451;
|
|
53
|
+
|
|
54
|
+
/** Unskew factor for the 4-simplex lattice: `(5 - sqrt(5)) / 20`. @type {number} */
|
|
55
|
+
const G4 = 0.138196601125011;
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* `x mod 289`, without a modulo opcode: `x - floor(x / 289) * 289`.
|
|
59
|
+
*
|
|
60
|
+
* 289 is 17 squared, and the permutation polynomial below is built so that its results stay inside
|
|
61
|
+
* `[0, 289)` — which is what keeps the whole hash inside the range a float represents exactly.
|
|
62
|
+
*
|
|
63
|
+
* A multiply-add would spell the tail of this in one instruction rather than two, and it is not used:
|
|
64
|
+
* a `MAD` holds three operands at once where the multiply and the subtract hold two each, and the
|
|
65
|
+
* third is a four-lane literal. Measured, that is four instructions off `simplex3` and four registers
|
|
66
|
+
* onto it — the wrong side of the trade, for the reason the note at the top of this file gives.
|
|
67
|
+
*
|
|
68
|
+
* @param {ParticleGroupBuilder} g
|
|
69
|
+
* @param {*} x
|
|
70
|
+
* @returns {*}
|
|
71
|
+
*/
|
|
72
|
+
function mod289(g, x) {
|
|
73
|
+
return g.sub(x, g.mul(g.floor(g.mul(x, g.f(1 / 289))), g.f(289)));
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* The permutation polynomial: `(34x + 1) x mod 289`.
|
|
78
|
+
*
|
|
79
|
+
* A hash chosen so that composing it over the lattice coordinates spreads corners across the
|
|
80
|
+
* gradient table without a lookup — there are no tables in this VM to look one up in.
|
|
81
|
+
*
|
|
82
|
+
* @param {ParticleGroupBuilder} g
|
|
83
|
+
* @param {*} x
|
|
84
|
+
* @returns {*}
|
|
85
|
+
*/
|
|
86
|
+
function permute(g, x) {
|
|
87
|
+
// `(34x + 1)x` written as `34x*x + x`, which is the same number and costs four fewer registers.
|
|
88
|
+
//
|
|
89
|
+
// A constant meeting a vector has to be broadcast into as many registers as the vector is wide,
|
|
90
|
+
// unless the operation is a multiply — a scalar times a vector lowers to SCALE, which reads its
|
|
91
|
+
// scalar as one lane. Written the obvious way, the `+ 1` is a four-register constant alive at the
|
|
92
|
+
// busiest moment of the function. Written this way there is no additive constant at all, and the
|
|
93
|
+
// `34` is a SCALE operand. See the note about the register file at the top of this file.
|
|
94
|
+
return mod289(g, g.mad(g.mul(x, g.f(34)), x, x));
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* One corner's contribution to a simplex sum: `max(0.6 - |x|^2, 0)^4 * dot(gradient, x)`.
|
|
99
|
+
*
|
|
100
|
+
* The fourth power of a radial falloff that reaches zero at the edge of a corner's influence, which
|
|
101
|
+
* is what makes the sum continuous and its derivative continuous with it.
|
|
102
|
+
*
|
|
103
|
+
* @param {ParticleGroupBuilder} g
|
|
104
|
+
* @param {*} offset the vector from the corner to the point
|
|
105
|
+
* @param {*} gradient the corner's gradient, already normalised
|
|
106
|
+
* @returns {*} a scalar
|
|
107
|
+
*/
|
|
108
|
+
function corner_contribution(g, offset, gradient) {
|
|
109
|
+
// `saturate` rather than `max(_, 0)`: the falloff is 0.6 less a squared length, so it can never
|
|
110
|
+
// reach the upper bound and the two are the same function. One instruction with its bounds in
|
|
111
|
+
// the instruction word, against a literal zero in a register and a `MAX` to compare it with.
|
|
112
|
+
const t = g.saturate(g.sub(g.f(0.6), g.dot(offset, offset)));
|
|
113
|
+
|
|
114
|
+
const t2 = g.mul(t, t);
|
|
115
|
+
|
|
116
|
+
return g.mul(g.mul(t2, t2), g.dot(gradient, offset));
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
/**
|
|
120
|
+
* The 3D gradient for one corner, from its hashed index.
|
|
121
|
+
*
|
|
122
|
+
* The table is the 7x7 grid of points on the faces of an octahedron that Gustavson's formulation
|
|
123
|
+
* uses: the index is split into a row and a column, those become two coordinates, the third is
|
|
124
|
+
* whatever is left of the L1 norm, and the sign of that third one flips the first two. Every step is
|
|
125
|
+
* arithmetic, because there is nowhere to put a table.
|
|
126
|
+
*
|
|
127
|
+
* @param {ParticleGroupBuilder} g
|
|
128
|
+
* @param {*} index a hashed corner index, in `[0, 289)`
|
|
129
|
+
* @returns {*} a `vec3` gradient, not yet normalised
|
|
130
|
+
*/
|
|
131
|
+
function grad3(g, index) {
|
|
132
|
+
const N = 1 / 7;
|
|
133
|
+
|
|
134
|
+
const ns_x = N * 2;
|
|
135
|
+
const ns_y = N * 0.5 - 1;
|
|
136
|
+
const ns_z = N;
|
|
137
|
+
|
|
138
|
+
// j = index mod 49, the 7x7 grid
|
|
139
|
+
const j = g.sub(index, g.mul(g.f(49), g.floor(g.mul(index, g.f(ns_z * ns_z)))));
|
|
140
|
+
|
|
141
|
+
const row = g.floor(g.mul(j, g.f(ns_z)));
|
|
142
|
+
const col = g.floor(g.sub(j, g.mul(g.f(7), row)));
|
|
143
|
+
|
|
144
|
+
const gx = g.mad(row, g.f(ns_x), g.f(ns_y));
|
|
145
|
+
const gy = g.mad(col, g.f(ns_x), g.f(ns_y));
|
|
146
|
+
|
|
147
|
+
// what is left of the unit L1 ball is the third coordinate
|
|
148
|
+
const gz = g.sub(g.sub(1, g.abs(gx)), g.abs(gy));
|
|
149
|
+
|
|
150
|
+
// Outside the ball the point belongs to the opposite face: reflect the first two coordinates.
|
|
151
|
+
// At or below zero, not below — the coordinates land on a seventh and the boundary is reachable
|
|
152
|
+
// exactly, so which side it falls on is a decision rather than a rounding accident.
|
|
153
|
+
// Negated once and shared, so that each reflection is a single multiply-add — `c - k*outside`
|
|
154
|
+
// written as `k*(-outside) + c`. Both halves want it, which is what pays for the negate.
|
|
155
|
+
const inside = g.neg(g.op("compare", [gz, 0], { op: "le" }));
|
|
156
|
+
|
|
157
|
+
return g.vec3(
|
|
158
|
+
g.mad(g.mad(g.floor(gx), 2, 1), inside, gx),
|
|
159
|
+
g.mad(g.mad(g.floor(gy), 2, 1), inside, gy),
|
|
160
|
+
gz
|
|
161
|
+
);
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
/**
|
|
165
|
+
* Simplex noise over three dimensions, in roughly `[-1, 1]`.
|
|
166
|
+
*
|
|
167
|
+
* @param {ParticleGroupBuilder} g
|
|
168
|
+
* @param {*} v a `vec3` position
|
|
169
|
+
* @returns {*} a scalar
|
|
170
|
+
*/
|
|
171
|
+
function simplex3(g, v) {
|
|
172
|
+
// Which cell of the skewed lattice the point is in, and where it sits inside it.
|
|
173
|
+
const cell = g.floor(g.add(v, g.dot(v, g.f(F3))));
|
|
174
|
+
const x0 = g.add(g.sub(v, cell), g.dot(cell, g.f(G3)));
|
|
175
|
+
|
|
176
|
+
// The simplex a point falls in is decided by the order of its coordinates: the two steps from
|
|
177
|
+
// the cell's corner to the point's own are the two largest axes, in order.
|
|
178
|
+
const order = g.step(g.swz(x0, "yzx"), x0);
|
|
179
|
+
const rest = g.sub(g.f(1), order);
|
|
180
|
+
|
|
181
|
+
const step1 = g.min(order, g.swz(rest, "zxy"));
|
|
182
|
+
const step2 = g.max(order, g.swz(rest, "zxy"));
|
|
183
|
+
|
|
184
|
+
const cell289 = mod289(g, cell);
|
|
185
|
+
|
|
186
|
+
// One hash of all four corners at once. Each `permute` folds in one lattice axis.
|
|
187
|
+
const corners = g.vec4(g.f(0), g.z(step1), g.z(step2), g.f(1));
|
|
188
|
+
|
|
189
|
+
let hashed = permute(g, g.add(g.z(cell289), corners));
|
|
190
|
+
|
|
191
|
+
hashed = permute(g, g.add(g.add(hashed, g.y(cell289)),
|
|
192
|
+
g.vec4(g.f(0), g.y(step1), g.y(step2), g.f(1))));
|
|
193
|
+
|
|
194
|
+
hashed = permute(g, g.add(g.add(hashed, g.x(cell289)),
|
|
195
|
+
g.vec4(g.f(0), g.x(step1), g.x(step2), g.f(1))));
|
|
196
|
+
|
|
197
|
+
// Corner by corner, so that one corner's working set is all that is ever live at once.
|
|
198
|
+
const offsets = [
|
|
199
|
+
x0,
|
|
200
|
+
g.add(g.sub(x0, step1), g.f(G3)),
|
|
201
|
+
g.add(g.sub(x0, step2), g.f(G3 * 2)),
|
|
202
|
+
g.sub(x0, g.f(0.5)),
|
|
203
|
+
];
|
|
204
|
+
|
|
205
|
+
let total = null;
|
|
206
|
+
|
|
207
|
+
["x", "y", "z", "w"].forEach((lane, corner) => {
|
|
208
|
+
const gradient = grad3(g, g.swz(hashed, lane));
|
|
209
|
+
|
|
210
|
+
const contribution = corner_contribution(g, offsets[corner], g.normalize(gradient));
|
|
211
|
+
|
|
212
|
+
total = total === null ? contribution : g.add(total, contribution);
|
|
213
|
+
});
|
|
214
|
+
|
|
215
|
+
// scales the sum to about [-1, 1]
|
|
216
|
+
return g.mul(g.f(42), total);
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
/**
|
|
220
|
+
* The 4D gradient for one corner, from its hashed index.
|
|
221
|
+
*
|
|
222
|
+
* The table this time is the 32 vertices of a hypercube's cell centres, reached the same way: three
|
|
223
|
+
* coordinates from base-7 digits of the index, the fourth from what is left of the L1 norm, and its
|
|
224
|
+
* sign flipping the other three.
|
|
225
|
+
*
|
|
226
|
+
* @param {ParticleGroupBuilder} g
|
|
227
|
+
* @param {*} index
|
|
228
|
+
* @returns {*} a `vec4` gradient, not yet normalised
|
|
229
|
+
*/
|
|
230
|
+
function grad4(g, index) {
|
|
231
|
+
// 1/294, 1/49, 1/7: successive base-7 digits of the index
|
|
232
|
+
const digits = g.mul(g.f(1 / 294, 1 / 49, 1 / 7), index);
|
|
233
|
+
|
|
234
|
+
const xyz = g.mad(g.floor(g.mul(g.fract(digits), g.f(7))), g.f(1 / 7), g.f(-1));
|
|
235
|
+
|
|
236
|
+
const w = g.sub(g.f(1.5), g.dot(g.abs(xyz), g.f(1)));
|
|
237
|
+
|
|
238
|
+
const negative = g.op("compare", [w, 0], { op: "lt" });
|
|
239
|
+
|
|
240
|
+
// `2c - 1` over a comparison's 0-or-1: -1 where the coordinate is negative, +1 where it is not
|
|
241
|
+
const sign = g.mad(g.op("compare", [xyz, g.f(0)], { op: "lt" }), g.f(2), g.f(-1));
|
|
242
|
+
|
|
243
|
+
const flipped = g.mad(sign, negative, xyz);
|
|
244
|
+
|
|
245
|
+
return g.vec4(g.x(flipped), g.y(flipped), g.z(flipped), w);
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
/**
|
|
249
|
+
* Simplex noise over four dimensions, in roughly `[-1, 1]`.
|
|
250
|
+
*
|
|
251
|
+
* The fourth dimension is what a moving noise field is made of: hold three of them at a position and
|
|
252
|
+
* walk the fourth with time, and the field changes rather than sliding past.
|
|
253
|
+
*
|
|
254
|
+
* @param {ParticleGroupBuilder} g
|
|
255
|
+
* @param {*} v a `vec4` position
|
|
256
|
+
* @returns {*} a scalar
|
|
257
|
+
*/
|
|
258
|
+
function simplex4(g, v) {
|
|
259
|
+
const cell = g.floor(g.add(v, g.dot(v, g.f(F4))));
|
|
260
|
+
const x0 = g.add(g.sub(v, cell), g.dot(cell, g.f(G4)));
|
|
261
|
+
|
|
262
|
+
// The rank of each coordinate among the four, by comparing every pair once. A coordinate's rank
|
|
263
|
+
// is how many of the others it is at least as large as, and the ranks are the order the four
|
|
264
|
+
// steps from the cell's corner are taken in.
|
|
265
|
+
const isX = g.step(g.swz(x0, "yzw"), g.swz(x0, "xxx"));
|
|
266
|
+
const isYZ = g.step(g.swz(x0, "zww"), g.swz(x0, "yyz"));
|
|
267
|
+
|
|
268
|
+
const one_minus = ref => g.sub(g.f(1), ref);
|
|
269
|
+
|
|
270
|
+
// Three comparison results summed, which is a dot product against ones — one instruction and one
|
|
271
|
+
// literal, rather than two adds and three lanes picked out one at a time. The others mix a
|
|
272
|
+
// comparison with its complement and have nothing so tidy to become.
|
|
273
|
+
const rank_x = g.dot(isX, g.f(1));
|
|
274
|
+
const rank_y = g.add(one_minus(g.x(isX)), g.add(g.x(isYZ), g.y(isYZ)));
|
|
275
|
+
const rank_z = g.add(one_minus(g.y(isX)), g.add(one_minus(g.x(isYZ)), g.z(isYZ)));
|
|
276
|
+
const rank_w = g.add(one_minus(g.z(isX)), g.add(one_minus(g.y(isYZ)), one_minus(g.z(isYZ))));
|
|
277
|
+
|
|
278
|
+
const rank = g.vec4(rank_x, rank_y, rank_z, rank_w);
|
|
279
|
+
|
|
280
|
+
// A rank is a whole number in 0..3, and the three steps from the cell's corner are the
|
|
281
|
+
// coordinates whose rank has been passed: the first step takes rank 3, the second 3 and 2, the
|
|
282
|
+
// third all but rank 0. `saturate(rank - k)` is all three of those. `rank - k` never leaves
|
|
283
|
+
// `[-3, 3]`, so clamping to `[0, 1]` is the same function as the one-sided `max` or `min` each of
|
|
284
|
+
// them would otherwise need — and it is one instruction that holds its bounds in the instruction
|
|
285
|
+
// word. This was `min` and `max` precisely to keep two broadcast literals from being alive at the
|
|
286
|
+
// same moment; `saturate` has no literals to be alive, so the reason is gone along with the cost.
|
|
287
|
+
const step_taken = value => g.saturate(value);
|
|
288
|
+
|
|
289
|
+
// The permutation needs one lane of each of the three steps at a time, so it takes them off the
|
|
290
|
+
// ranks directly rather than off three assembled vectors. Those vectors are twelve registers,
|
|
291
|
+
// and holding them through the permutation — the busiest part of the function — is what put this
|
|
292
|
+
// over the register file. Built this way the ranks are all that has to survive it, and the
|
|
293
|
+
// vectors are assembled afterwards for the corner offsets, by which point the hash is done.
|
|
294
|
+
const steps_of = axis => {
|
|
295
|
+
const r = g.swz(rank, axis);
|
|
296
|
+
|
|
297
|
+
return g.vec4(
|
|
298
|
+
step_taken(g.sub(r, g.f(2))),
|
|
299
|
+
step_taken(g.sub(r, g.f(1))),
|
|
300
|
+
step_taken(r),
|
|
301
|
+
g.f(1)
|
|
302
|
+
);
|
|
303
|
+
};
|
|
304
|
+
|
|
305
|
+
const cell289 = mod289(g, cell);
|
|
306
|
+
|
|
307
|
+
// The corner at the cell's own origin hashes on its own; the other four hash together.
|
|
308
|
+
let origin = permute(g, g.w(cell289));
|
|
309
|
+
|
|
310
|
+
origin = permute(g, g.add(origin, g.z(cell289)));
|
|
311
|
+
origin = permute(g, g.add(origin, g.y(cell289)));
|
|
312
|
+
origin = permute(g, g.add(origin, g.x(cell289)));
|
|
313
|
+
|
|
314
|
+
let hashed = permute(g, g.add(g.w(cell289), steps_of("w")));
|
|
315
|
+
|
|
316
|
+
hashed = permute(g, g.add(g.add(hashed, g.z(cell289)), steps_of("z")));
|
|
317
|
+
hashed = permute(g, g.add(g.add(hashed, g.y(cell289)), steps_of("y")));
|
|
318
|
+
hashed = permute(g, g.add(g.add(hashed, g.x(cell289)), steps_of("x")));
|
|
319
|
+
|
|
320
|
+
const step3 = step_taken(rank);
|
|
321
|
+
const step2 = step_taken(g.sub(rank, g.f(1)));
|
|
322
|
+
const step1 = step_taken(g.sub(rank, g.f(2)));
|
|
323
|
+
|
|
324
|
+
// Each of these is one value read once, so only one of them is ever live however they are
|
|
325
|
+
// written down — the order the compiler emits in comes from the graph rather than from the order
|
|
326
|
+
// they were built in. See the note about corners at the top of this file for the part that *is*
|
|
327
|
+
// a register decision.
|
|
328
|
+
const offsets = [
|
|
329
|
+
x0,
|
|
330
|
+
g.add(g.sub(x0, step1), g.f(G4)),
|
|
331
|
+
g.add(g.sub(x0, step2), g.f(G4 * 2)),
|
|
332
|
+
g.add(g.sub(x0, step3), g.f(G4 * 3)),
|
|
333
|
+
g.add(x0, g.f(G4 * 4 - 1)),
|
|
334
|
+
];
|
|
335
|
+
|
|
336
|
+
const indices = [origin, g.x(hashed), g.y(hashed), g.z(hashed), g.w(hashed)];
|
|
337
|
+
|
|
338
|
+
let total = null;
|
|
339
|
+
|
|
340
|
+
for (let corner = 0; corner < 5; corner++) {
|
|
341
|
+
const gradient = grad4(g, indices[corner]);
|
|
342
|
+
|
|
343
|
+
const contribution = corner_contribution(g, offsets[corner], g.normalize(gradient));
|
|
344
|
+
|
|
345
|
+
total = total === null ? contribution : g.add(total, contribution);
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
return g.mul(g.f(49), total);
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
/**
|
|
352
|
+
* @type {import("../ParticleNodeGroup.js").ParticleNodeGroup}
|
|
353
|
+
*/
|
|
354
|
+
export const PARTICLE_GROUP_SIMPLEX_3 = (() => {
|
|
355
|
+
const g = new ParticleGroupBuilder({
|
|
356
|
+
name: "simplex3",
|
|
357
|
+
label: "Simplex Noise 3D",
|
|
358
|
+
icon: "M12 3l8 4.5v9L12 21l-8-4.5v-9z M12 3v18 M4 7.5l16 9 M20 7.5l-16 9",
|
|
359
|
+
help: "simplex noise at a point in space, about [-1, 1]",
|
|
360
|
+
inputs: [{ name: "p", type: PARTICLE_TYPE_VEC3 }],
|
|
361
|
+
outputs: [{ name: "out", type: PARTICLE_TYPE_F32 }],
|
|
362
|
+
});
|
|
363
|
+
|
|
364
|
+
g.out("out", simplex3(g, g.in.p));
|
|
365
|
+
|
|
366
|
+
return g.build();
|
|
367
|
+
})();
|
|
368
|
+
|
|
369
|
+
/**
|
|
370
|
+
* @type {import("../ParticleNodeGroup.js").ParticleNodeGroup}
|
|
371
|
+
*/
|
|
372
|
+
export const PARTICLE_GROUP_SIMPLEX_4 = (() => {
|
|
373
|
+
const g = new ParticleGroupBuilder({
|
|
374
|
+
name: "simplex4",
|
|
375
|
+
label: "Simplex Noise 4D",
|
|
376
|
+
icon: "M12 3l8 4.5v9L12 21l-8-4.5v-9z M12 3v18 M4 7.5l16 9 M20 7.5l-16 9 M4 7.5l16 0",
|
|
377
|
+
help: "simplex noise at a point in space and time, about [-1, 1]",
|
|
378
|
+
inputs: [{ name: "p", type: PARTICLE_TYPE_VEC4 }],
|
|
379
|
+
outputs: [{ name: "out", type: PARTICLE_TYPE_F32 }],
|
|
380
|
+
});
|
|
381
|
+
|
|
382
|
+
g.out("out", simplex4(g, g.in.p));
|
|
383
|
+
|
|
384
|
+
return g.build();
|
|
385
|
+
})();
|
|
386
|
+
|
|
387
|
+
/**
|
|
388
|
+
* How far apart the samples taken either side of a point are, when differencing the potential.
|
|
389
|
+
*
|
|
390
|
+
* Small enough that the difference is a derivative and large enough that it is not two samples of
|
|
391
|
+
* the same value: simplex noise varies over a unit cell, and a tenth of one is a reasonable step in
|
|
392
|
+
* single precision.
|
|
393
|
+
*
|
|
394
|
+
* @type {number}
|
|
395
|
+
*/
|
|
396
|
+
const CURL_EPSILON = 0.1;
|
|
397
|
+
|
|
398
|
+
/**
|
|
399
|
+
* Offsets that turn one noise field into three independent ones.
|
|
400
|
+
*
|
|
401
|
+
* A curl needs a vector potential, and there is one noise function. Sampling it at three points far
|
|
402
|
+
* enough apart that the values are uncorrelated is the standard way to get three fields out of it —
|
|
403
|
+
* the numbers are arbitrary and only have to be large and unalike.
|
|
404
|
+
*
|
|
405
|
+
* @type {number[][]}
|
|
406
|
+
*/
|
|
407
|
+
const CURL_FIELD_OFFSETS = [
|
|
408
|
+
[0, 0, 0],
|
|
409
|
+
[31.416, 47.853, 12.793],
|
|
410
|
+
[83.147, 19.264, 65.037],
|
|
411
|
+
];
|
|
412
|
+
|
|
413
|
+
/**
|
|
414
|
+
* The curl of a noise field, as a vector.
|
|
415
|
+
*
|
|
416
|
+
* A curl is divergence-free — nothing anywhere is a source or a sink — which is what makes it look
|
|
417
|
+
* like a fluid rather than like noise. Particles advected by one swirl and never pile up, and that
|
|
418
|
+
* is the whole reason to spend this many instructions on it.
|
|
419
|
+
*
|
|
420
|
+
* ## What it costs
|
|
421
|
+
*
|
|
422
|
+
* Twelve noise samples. The curl of a three-component potential needs six partial derivatives, each
|
|
423
|
+
* a difference of two samples, and no two of them are of the same field at the same place. There is
|
|
424
|
+
* no loop to put them in and no way to share them, so the group is twelve copies of the noise and
|
|
425
|
+
* the arithmetic between them — well over a thousand instructions, and worth knowing before it is
|
|
426
|
+
* put in an UPDATE graph that runs on every particle every frame.
|
|
427
|
+
*
|
|
428
|
+
* @param {ParticleGroupBuilder} g
|
|
429
|
+
* @param {function(ParticleGroupBuilder, number, number, number, number): *} sample
|
|
430
|
+
* the potential's `field`th component at `p + (dx, dy, dz)`, as a scalar
|
|
431
|
+
* @returns {*} a `vec3`
|
|
432
|
+
*/
|
|
433
|
+
function curl_of(g, sample) {
|
|
434
|
+
const e = CURL_EPSILON;
|
|
435
|
+
|
|
436
|
+
/**
|
|
437
|
+
* The centred difference of one field along one axis, *not* divided by the step — every one of
|
|
438
|
+
* the six is over the same step, so the division comes out of the sum at the end as a single
|
|
439
|
+
* scale rather than six multiplies.
|
|
440
|
+
*
|
|
441
|
+
* @param {number} field
|
|
442
|
+
* @param {number} axis 0, 1 or 2
|
|
443
|
+
* @returns {*}
|
|
444
|
+
*/
|
|
445
|
+
const difference = (field, axis) => {
|
|
446
|
+
const step = [0, 0, 0];
|
|
447
|
+
|
|
448
|
+
step[axis] = e;
|
|
449
|
+
|
|
450
|
+
const ahead = sample(g, field, step[0], step[1], step[2]);
|
|
451
|
+
const behind = sample(g, field, -step[0], -step[1], -step[2]);
|
|
452
|
+
|
|
453
|
+
return g.sub(ahead, behind);
|
|
454
|
+
};
|
|
455
|
+
|
|
456
|
+
const curl = g.vec3(
|
|
457
|
+
g.sub(difference(2, 1), difference(1, 2)),
|
|
458
|
+
g.sub(difference(0, 2), difference(2, 0)),
|
|
459
|
+
g.sub(difference(1, 0), difference(0, 1))
|
|
460
|
+
);
|
|
461
|
+
|
|
462
|
+
return g.scale(curl, g.f(1 / (2 * e)));
|
|
463
|
+
}
|
|
464
|
+
|
|
465
|
+
/**
|
|
466
|
+
* @type {import("../ParticleNodeGroup.js").ParticleNodeGroup}
|
|
467
|
+
*/
|
|
468
|
+
export const PARTICLE_GROUP_CURL_3 = (() => {
|
|
469
|
+
const g = new ParticleGroupBuilder({
|
|
470
|
+
name: "curl3",
|
|
471
|
+
label: "Curl Noise 3D",
|
|
472
|
+
icon: "M6 15c0-5 5-8 8-5s0 8-3 6-1-6 3-6",
|
|
473
|
+
help: "a divergence-free swirl field — twelve noise samples, so not cheap",
|
|
474
|
+
inputs: [{ name: "p", type: PARTICLE_TYPE_VEC3 }],
|
|
475
|
+
outputs: [{ name: "out", type: PARTICLE_TYPE_VEC3 }],
|
|
476
|
+
});
|
|
477
|
+
|
|
478
|
+
g.out("out", curl_of(g, (builder, field, dx, dy, dz) => {
|
|
479
|
+
const offset = CURL_FIELD_OFFSETS[field];
|
|
480
|
+
|
|
481
|
+
const at = builder.add(builder.in.p, builder.f(offset[0] + dx, offset[1] + dy, offset[2] + dz));
|
|
482
|
+
|
|
483
|
+
return builder.call(PARTICLE_GROUP_SIMPLEX_3, { p: at }).out;
|
|
484
|
+
}));
|
|
485
|
+
|
|
486
|
+
return g.build();
|
|
487
|
+
})();
|
|
488
|
+
|
|
489
|
+
/**
|
|
490
|
+
* The same field, with a fourth coordinate to move it through.
|
|
491
|
+
*
|
|
492
|
+
* Advance `w` with time and the swirl evolves in place instead of drifting past — which is what
|
|
493
|
+
* separates smoke from a conveyor belt of smoke.
|
|
494
|
+
*
|
|
495
|
+
* @type {import("../ParticleNodeGroup.js").ParticleNodeGroup}
|
|
496
|
+
*/
|
|
497
|
+
export const PARTICLE_GROUP_CURL_4 = (() => {
|
|
498
|
+
const g = new ParticleGroupBuilder({
|
|
499
|
+
name: "curl4",
|
|
500
|
+
label: "Curl Noise 4D",
|
|
501
|
+
icon: "M6 15c0-5 5-8 8-5s0 8-3 6-1-6 3-6 M18 5v4 M16 7h4",
|
|
502
|
+
help: "a curl field that evolves along w — twelve 4D noise samples, so expensive",
|
|
503
|
+
inputs: [
|
|
504
|
+
{ name: "p", type: PARTICLE_TYPE_VEC3 },
|
|
505
|
+
{ name: "w", type: PARTICLE_TYPE_F32 },
|
|
506
|
+
],
|
|
507
|
+
outputs: [{ name: "out", type: PARTICLE_TYPE_VEC3 }],
|
|
508
|
+
});
|
|
509
|
+
|
|
510
|
+
g.out("out", curl_of(g, (builder, field, dx, dy, dz) => {
|
|
511
|
+
const offset = CURL_FIELD_OFFSETS[field];
|
|
512
|
+
|
|
513
|
+
const at = builder.vec4(
|
|
514
|
+
builder.add(builder.x(builder.in.p), builder.f(offset[0] + dx)),
|
|
515
|
+
builder.add(builder.y(builder.in.p), builder.f(offset[1] + dy)),
|
|
516
|
+
builder.add(builder.z(builder.in.p), builder.f(offset[2] + dz)),
|
|
517
|
+
builder.in.w
|
|
518
|
+
);
|
|
519
|
+
|
|
520
|
+
return builder.call(PARTICLE_GROUP_SIMPLEX_4, { p: at }).out;
|
|
521
|
+
}));
|
|
522
|
+
|
|
523
|
+
return g.build();
|
|
524
|
+
})();
|