@mkbabb/glass-ui 4.0.1 → 4.2.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/dist/{CardAction-CW7a0m8M.js → CardAction-DlVP2evz.js} +72 -53
- package/dist/{CommandShortcut-DvZNQ_HF.js → CommandShortcut-By-VQcLO.js} +25 -14
- package/dist/{ConfiguratorRow-BR4l-ixA.js → ConfiguratorRow-YMXdINHx.js} +14 -14
- package/dist/ContextMenuContent-CMWn6huB.js +90 -0
- package/dist/{ContextMenuSubContent-xol4sD2q.js → ContextMenuSubContent-DvwWCUc0.js} +16 -16
- package/dist/{DataTable-CuKwF7wr.js → DataTable-C4tG3eIJ.js} +4 -4
- package/dist/DialogContent-D8U9ZfWS.js +121 -0
- package/dist/DialogFooter-DoLy0ewI.js +80 -0
- package/dist/DialogScrollContent-BMekN7gq.js +93 -0
- package/dist/{FadingScroll-DI6hQhT9.js → FadingScroll-P8B30rAD.js} +1 -1
- package/dist/HoverCardContent-DAmGYglo.js +88 -0
- package/dist/{HoverPopover-CbqbNwgU.js → HoverPopover-DYpBOzzF.js} +1 -1
- package/dist/{IconChip-BTD-nay5.js → IconChip-CQa7XZYc.js} +7 -5
- package/dist/{IconTooltip-Bl8gFZ8d.js → IconTooltip-_df8M3xm.js} +1 -1
- package/dist/Input-CyU4_hIC.js +57 -0
- package/dist/{MetricBadge-RHdBP72w.js → MetricBadge-DQt_dGah.js} +1 -1
- package/dist/{Notification-VUwexFUf.js → Notification-BlSPJhtZ.js} +4 -4
- package/dist/NumberFieldContent-Z3VxGu_6.js +140 -0
- package/dist/PagerDots-CYlqVFd4.js +196 -0
- package/dist/PaperBackdrop-DYWgrnh8.js +42 -0
- package/dist/{PopoverContent-DL7E6vJP.js → PopoverContent-BuKyHZSz.js} +2 -2
- package/dist/{Progress-DctG61iZ.js → Progress-C9SsdwIZ.js} +1 -1
- package/dist/{ScrollingText-yOpBzFYq.js → ScrollingText-DY3W1Jfh.js} +2 -2
- package/dist/SelectScrollDownButton-3mFHX_R-.js +260 -0
- package/dist/{SelectSeparator-DXswVdRz.js → SelectSeparator-CNRGG7Ew.js} +1 -1
- package/dist/Separator-Cf9-JFgi.js +44 -0
- package/dist/Switch-uf-UKPA2.js +49 -0
- package/dist/{Toaster-Bw4xR8xV.js → Toaster-ozrsR4mP.js} +2 -2
- package/dist/{ToggleGroupItem-pEM9vIhs.js → ToggleGroupItem-BpzaVzNm.js} +6 -6
- package/dist/TooltipProvider-QQVM_80r.js +109 -0
- package/dist/animated-digit.js +2 -2
- package/dist/api/index.d.ts +16 -32
- package/dist/api/types-extra.d.ts +33 -0
- package/dist/api.js +2 -2
- package/dist/aurora.js +629 -269
- package/dist/badge-Bt14yURi.js +72 -0
- package/dist/badge.js +1 -1
- package/dist/border-progress.js +49 -57
- package/dist/button-D1W9PrzI.js +130 -0
- package/dist/button.js +1 -1
- package/dist/canvas.js +2 -3
- package/dist/card.js +1 -1
- package/dist/carousel.js +235 -106
- package/dist/chipVariants-BJQ0I2kB.js +18 -0
- package/dist/collapsible.js +1 -1
- package/dist/color-B9jZdhJX.js +116 -0
- package/dist/color.js +2 -2
- package/dist/command.js +1 -1
- package/dist/completion-seal.d.ts +1 -0
- package/dist/completion-seal.js +89 -0
- package/dist/components/custom/aurora/Aurora.vue.d.ts +10 -5
- package/dist/components/custom/aurora/composables/color.d.ts +13 -0
- package/dist/components/custom/aurora/composables/frameLoop.d.ts +9 -0
- package/dist/components/custom/aurora/composables/glSetup.d.ts +1 -1
- package/dist/components/custom/aurora/composables/runtime.d.ts +12 -0
- package/dist/components/custom/aurora/composables/uniformBridgeWGPU.d.ts +12 -3
- package/dist/components/custom/aurora/composables/wgpuSetup.d.ts +8 -0
- package/dist/components/custom/aurora/constants/presets.d.ts +47 -0
- package/dist/components/custom/aurora/constants/renderMode.d.ts +16 -8
- package/dist/components/custom/aurora/constants/shaders/aurora-mediums.wgsl.d.ts +1 -0
- package/dist/components/custom/aurora/constants/shaders/aurora.wgsl.d.ts +1 -1
- package/dist/components/custom/aurora/index.d.ts +1 -1
- package/dist/components/custom/border-progress/composables/spectrum-walk.d.ts +25 -0
- package/dist/components/custom/border-progress/composables/useBorderSpectrum.d.ts +14 -18
- package/dist/components/custom/border-progress/index.d.ts +1 -1
- package/dist/components/custom/completion-seal/CompletionSeal.vue.d.ts +21 -0
- package/dist/components/custom/completion-seal/composables/useCompletionSeal.d.ts +37 -0
- package/dist/components/custom/completion-seal/constants.d.ts +46 -0
- package/dist/components/custom/completion-seal/index.d.ts +4 -0
- package/dist/components/custom/concentric/Concentric.vue.d.ts +15 -12
- package/dist/components/custom/concentric/composables/concentricGLSetup.d.ts +12 -0
- package/dist/components/custom/concentric/composables/concentricWGPUSetup.d.ts +13 -0
- package/dist/components/custom/concentric/composables/levelField.d.ts +50 -0
- package/dist/components/custom/concentric/composables/uniformBridgeWGPU.d.ts +7 -3
- package/dist/components/custom/concentric/composables/useConcentric.d.ts +3 -3
- package/dist/components/custom/concentric/constants.d.ts +69 -24
- package/dist/components/custom/concentric/index.d.ts +2 -2
- package/dist/components/custom/concentric/shaders/concentric.glsl.d.ts +2 -2
- package/dist/components/custom/concentric/shaders/concentric.wgsl.d.ts +1 -1
- package/dist/components/custom/configurator/Configurator.vue.d.ts +23 -2
- package/dist/components/custom/configurator/index.d.ts +1 -1
- package/dist/components/custom/confirm-dialog/ConfirmDialog.vue.d.ts +3 -3
- package/dist/components/custom/constellation/Constellation.vue.d.ts +5 -4
- package/dist/components/custom/constellation/composables/constellationGLSetup.d.ts +10 -0
- package/dist/components/custom/constellation/composables/constellationWGPUSetup.d.ts +19 -0
- package/dist/components/custom/constellation/composables/uniformBridgeWGPU.d.ts +66 -0
- package/dist/components/custom/constellation/composables/useConstellation.d.ts +3 -10
- package/dist/components/custom/constellation/constants.d.ts +33 -0
- package/dist/components/custom/constellation/constellationField.d.ts +31 -1
- package/dist/components/custom/constellation/constellationInteraction.d.ts +23 -14
- package/dist/components/custom/constellation/constellationRender.d.ts +25 -0
- package/dist/components/custom/constellation/constellationTypes.d.ts +38 -0
- package/dist/components/custom/constellation/constellationWell.d.ts +15 -0
- package/dist/components/custom/constellation/index.d.ts +5 -5
- package/dist/components/custom/constellation/shaders/constellation-lines.glsl.d.ts +2 -0
- package/dist/components/custom/constellation/shaders/constellation-lines.wgsl.d.ts +1 -0
- package/dist/components/custom/constellation/shaders/constellation-points.glsl.d.ts +2 -0
- package/dist/components/custom/constellation/shaders/constellation-points.wgsl.d.ts +1 -0
- package/dist/components/custom/deck/DeckPager.vue.d.ts +29 -0
- package/dist/components/custom/deck/composables/useDeck.d.ts +27 -0
- package/dist/components/custom/deck/composables/useDeckKeyboard.d.ts +25 -0
- package/dist/components/custom/deck/composables/useDeckSpring.d.ts +22 -0
- package/dist/components/custom/deck/constants.d.ts +14 -0
- package/dist/components/custom/deck/index.d.ts +8 -0
- package/dist/components/custom/dock/DockDropdownTrigger.vue.d.ts +4 -3
- package/dist/components/custom/dock/DockIconButton.vue.d.ts +22 -0
- package/dist/components/custom/dock/DockPopoverTrigger.vue.d.ts +19 -0
- package/dist/components/custom/dock/DockStack.vue.d.ts +78 -0
- package/dist/components/custom/dock/GlassDock.vue.d.ts +21 -3
- package/dist/components/custom/dock/composables/dockMorphContext.d.ts +18 -32
- package/dist/components/custom/dock/composables/dockMorphMeasure.d.ts +78 -67
- package/dist/components/custom/dock/composables/index.d.ts +3 -0
- package/dist/components/custom/dock/composables/railProjection.d.ts +45 -0
- package/dist/components/custom/dock/composables/useDockContextSilhouette.d.ts +192 -0
- package/dist/components/custom/dock/composables/useDockFission.d.ts +158 -0
- package/dist/components/custom/dock/composables/useDockItemDrag.d.ts +18 -0
- package/dist/components/custom/dock/composables/useDockSearch.d.ts +85 -0
- package/dist/components/custom/dock/composables/useDockShellProps.d.ts +49 -0
- package/dist/components/custom/dock/constants.d.ts +32 -17
- package/dist/components/custom/dock/index.d.ts +8 -2
- package/dist/components/custom/dot-flow-field/DotFlowField.vue.d.ts +15 -11
- package/dist/components/custom/dot-flow-field/composables/flowField.d.ts +69 -6
- package/dist/components/custom/dot-flow-field/composables/flowGLProgram.d.ts +8 -0
- package/dist/components/custom/dot-flow-field/composables/flowSetupGL.d.ts +9 -0
- package/dist/components/custom/dot-flow-field/composables/flowSetupGLFlow.d.ts +12 -0
- package/dist/components/custom/dot-flow-field/composables/flowSetupWGPU.d.ts +7 -0
- package/dist/components/custom/dot-flow-field/composables/uniformBridgeWGPU.d.ts +50 -9
- package/dist/components/custom/dot-flow-field/composables/useDotFlowField.d.ts +6 -5
- package/dist/components/custom/dot-flow-field/composables/useFlowParticles.d.ts +23 -9
- package/dist/components/custom/dot-flow-field/constants.d.ts +92 -20
- package/dist/components/custom/dot-flow-field/index.d.ts +2 -2
- package/dist/components/custom/dot-flow-field/shaders/flow-field.compute.wgsl.d.ts +1 -1
- package/dist/components/custom/dot-flow-field/shaders/flow-field.glsl.d.ts +31 -18
- package/dist/components/custom/dot-flow-field/shaders/flow-field.render.wgsl.d.ts +2 -1
- package/dist/components/custom/dot-matrix/DotMatrix.vue.d.ts +43 -0
- package/dist/components/custom/dot-matrix/composables/dotMatrixField.d.ts +89 -0
- package/dist/components/custom/dot-matrix/composables/uniformBridgeWGPU.d.ts +61 -0
- package/dist/components/custom/dot-matrix/composables/useDotMatrix.d.ts +34 -0
- package/dist/components/custom/dot-matrix/composables/useDotSphere.d.ts +34 -0
- package/dist/components/custom/dot-matrix/constants.d.ts +72 -0
- package/dist/components/custom/dot-matrix/index.d.ts +5 -0
- package/dist/components/custom/dot-matrix/shaders/dot-matrix.glsl.d.ts +4 -0
- package/dist/components/custom/dot-matrix/shaders/dot-matrix.wgsl.d.ts +1 -0
- package/dist/components/custom/easing/EasingPicker.vue.d.ts +2 -2
- package/dist/components/custom/easing/composables/useEasingPicker.d.ts +5 -0
- package/dist/components/custom/expandable-container/ExpandableContainer.vue.d.ts +11 -0
- package/dist/components/custom/fourier-field/FourierField.vue.d.ts +44 -47
- package/dist/components/custom/fourier-field/composables/fourierFieldGLSetup.d.ts +24 -0
- package/dist/components/custom/fourier-field/composables/fourierFieldWGPUSetup.d.ts +31 -0
- package/dist/components/custom/fourier-field/composables/uniformBridgeWGPU.d.ts +56 -0
- package/dist/components/custom/fourier-field/composables/useFourierField.d.ts +61 -37
- package/dist/components/custom/fourier-field/constants.d.ts +114 -4
- package/dist/components/custom/fourier-field/index.d.ts +23 -18
- package/dist/components/custom/fourier-field/shaders/fourier-field.compute.wgsl.d.ts +1 -0
- package/dist/components/custom/fourier-field/shaders/fourier-field.glsl.d.ts +4 -0
- package/dist/components/custom/fourier-field/shaders/fourier-field.render.wgsl.d.ts +1 -0
- package/dist/components/custom/goo-blob/GooBlob.vue.d.ts +9 -1
- package/dist/components/custom/goo-blob/composables/easing.d.ts +1 -0
- package/dist/components/custom/goo-blob/composables/useBlobSatellites.d.ts +1 -0
- package/dist/components/custom/goo-blob/constants.d.ts +26 -1
- package/dist/components/custom/goo-blob/index.d.ts +1 -1
- package/dist/components/custom/goo-blob/shaders/metaball-noise.wgsl.d.ts +1 -0
- package/dist/components/custom/goo-blob/shaders/metaball-palette.wgsl.d.ts +1 -0
- package/dist/components/custom/goo-blob/shaders/metaball-uniforms.glsl.d.ts +1 -1
- package/dist/components/custom/goo-blob/shaders/metaball.wgsl.d.ts +1 -1
- package/dist/components/custom/goo-blob/types.d.ts +86 -1
- package/dist/components/custom/goo-dot-matrix/GooDotMatrix.vue.d.ts +49 -0
- package/dist/components/custom/goo-dot-matrix/composables/gooDotLattice.d.ts +24 -0
- package/dist/components/custom/goo-dot-matrix/composables/gooDotSetup.d.ts +79 -0
- package/dist/components/custom/goo-dot-matrix/composables/uniformBridgeWGPU.d.ts +45 -0
- package/dist/components/custom/goo-dot-matrix/composables/useGooDotMatrix.d.ts +31 -0
- package/dist/components/custom/goo-dot-matrix/constants.d.ts +115 -0
- package/dist/components/custom/goo-dot-matrix/index.d.ts +5 -0
- package/dist/components/custom/goo-dot-matrix/shaders/goo-dot.frag.d.ts +13 -0
- package/dist/components/custom/goo-dot-matrix/shaders/goo-dot.wgsl.d.ts +4 -0
- package/dist/components/custom/goo-filter/GooFilter.vue.d.ts +22 -0
- package/dist/components/custom/goo-filter/index.d.ts +1 -0
- package/dist/components/custom/handmark/brush.d.ts +17 -17
- package/dist/components/custom/handmark/constants.d.ts +28 -8
- package/dist/components/custom/handmark/geometry.d.ts +34 -1
- package/dist/components/custom/handmark/index.d.ts +1 -1
- package/dist/components/custom/icon-chip/types.d.ts +10 -0
- package/dist/components/custom/labeled-field/LabeledField.vue.d.ts +21 -2
- package/dist/components/custom/metric-stack/MetricRow.vue.d.ts +15 -0
- package/dist/components/custom/pager-dots/PagerDots.vue.d.ts +9 -0
- package/dist/components/custom/pager-dots/index.d.ts +2 -0
- package/dist/components/custom/pager-dots/pagerWindow.d.ts +9 -0
- package/dist/components/custom/paper-backdrop/PaperBackdrop.vue.d.ts +18 -0
- package/dist/components/custom/paper-grid/PaperGrid.vue.d.ts +42 -0
- package/dist/components/custom/paper-grid/composables/paperGrid.d.ts +105 -0
- package/dist/components/custom/paper-grid/composables/paperGridGLSetup.d.ts +18 -0
- package/dist/components/custom/paper-grid/composables/paperGridWGPUSetup.d.ts +21 -0
- package/dist/components/custom/paper-grid/composables/uniformBridgeWGPU.d.ts +16 -0
- package/dist/components/custom/paper-grid/composables/usePaperGrid.d.ts +31 -0
- package/dist/components/custom/paper-grid/constants.d.ts +95 -0
- package/dist/components/custom/paper-grid/index.d.ts +5 -0
- package/dist/components/custom/paper-grid/shaders/paper-grid.glsl.d.ts +4 -0
- package/dist/components/custom/paper-grid/shaders/paper-grid.wgsl.d.ts +1 -0
- package/dist/components/custom/search/FuzzySearch.vue.d.ts +8 -2
- package/dist/components/custom/search/SearchBar.vue.d.ts +8 -0
- package/dist/components/custom/search/index.d.ts +2 -0
- package/dist/components/custom/search/searchVariants.d.ts +19 -0
- package/dist/components/custom/selectable-chip/SelectableChip.vue.d.ts +50 -0
- package/dist/components/custom/selectable-chip/chipVariants.d.ts +39 -0
- package/dist/components/custom/selectable-chip/index.d.ts +2 -0
- package/dist/components/custom/selectable-chip/selectableChipVariants.d.ts +15 -0
- package/dist/components/custom/split-chars/SplitChars.vue.d.ts +39 -0
- package/dist/components/custom/split-chars/index.d.ts +1 -0
- package/dist/components/custom/tabs/SegmentedTabs.vue.d.ts +8 -6
- package/dist/components/custom/tabs/constants.d.ts +28 -2
- package/dist/components/custom/timeline/ScrubberTimeline.vue.d.ts +16 -0
- package/dist/components/custom/timeline/geometry.d.ts +0 -8
- package/dist/components/custom/toggle-chip/index.d.ts +15 -4
- package/dist/components/custom/watercolor-dot/WatercolorDot.vue.d.ts +32 -17
- package/dist/components/custom/watercolor-dot/useWatercolorBlob.d.ts +10 -5
- package/dist/components/ui/_shared/index.d.ts +2 -0
- package/dist/components/ui/_shared/useControlSize.d.ts +46 -0
- package/dist/components/ui/_shared/useSurfaceAxis.d.ts +17 -3
- package/dist/components/ui/badge/Badge.vue.d.ts +14 -0
- package/dist/components/ui/badge/index.d.ts +1 -0
- package/dist/components/ui/button/Button.vue.d.ts +1 -0
- package/dist/components/ui/button/index.d.ts +1 -1
- package/dist/components/ui/card/Card.vue.d.ts +46 -1
- package/dist/components/ui/card/ScrollCard.vue.d.ts +1 -1
- package/dist/components/ui/card/index.d.ts +1 -1
- package/dist/components/ui/carousel/CarouselContent.vue.d.ts +2 -4
- package/dist/components/ui/carousel/CarouselNext.vue.d.ts +1 -1
- package/dist/components/ui/carousel/CarouselPrevious.vue.d.ts +1 -1
- package/dist/components/ui/command/CommandDialog.vue.d.ts +9 -3
- package/dist/components/ui/command/CommandList.vue.d.ts +3 -0
- package/dist/components/ui/context-menu/ContextMenuContent.vue.d.ts +5 -1
- package/dist/components/ui/dialog/DialogContent.vue.d.ts +9 -0
- package/dist/components/ui/drawer/Drawer.vue.d.ts +33 -14
- package/dist/components/ui/drawer/constants.d.ts +8 -6
- package/dist/components/ui/drawer/index.d.ts +12 -2
- package/dist/components/ui/dropdown-menu/DropdownMenuContent.vue.d.ts +4 -0
- package/dist/components/ui/hover-card/HoverCardContent.vue.d.ts +3 -0
- package/dist/components/ui/input/Input.vue.d.ts +3 -0
- package/dist/components/ui/number-field/NumberFieldInput.vue.d.ts +6 -1
- package/dist/components/ui/select/SelectContent.vue.d.ts +12 -0
- package/dist/components/ui/slider/Slider.vue.d.ts +9 -0
- package/dist/components/ui/switch/Switch.vue.d.ts +2 -0
- package/dist/components/ui/textarea/Textarea.vue.d.ts +3 -0
- package/dist/components/ui/tooltip/TooltipContent.vue.d.ts +3 -0
- package/dist/composables/color/index.d.ts +2 -0
- package/dist/composables/color/useAccentTone.d.ts +34 -0
- package/dist/composables/dom/index.d.ts +1 -0
- package/dist/composables/dom/useDragVelocity.d.ts +46 -0
- package/dist/composables/glass/useVizChoreography.d.ts +123 -0
- package/dist/composables/glass/wave/index.d.ts +4 -0
- package/dist/composables/glass/wave/waveField.d.ts +115 -0
- package/dist/composables/glass/wave/waveField.glsl.d.ts +1 -0
- package/dist/composables/glass/wave/waveField.wgsl.d.ts +1 -0
- package/dist/composables/glass/webgl/createCanvasLifecycle.d.ts +105 -2
- package/dist/composables/glass/webgl/shaders/flow.wgsl.d.ts +1 -0
- package/dist/composables/glass/webgl/useWebGLCanvas.d.ts +40 -2
- package/dist/composables/glass/webgpu/index.d.ts +2 -1
- package/dist/composables/glass/webgpu/useGpuSubstrate.d.ts +65 -7
- package/dist/composables/glass/webgpu/useWebGPUCanvas.d.ts +50 -2
- package/dist/composables/glass/webgpu/webgpuDevice.d.ts +42 -0
- package/dist/composables/motion/core/index.d.ts +7 -0
- package/dist/composables/motion/core/useHaptic.d.ts +48 -0
- package/dist/composables/motion/core/writeVelocityWeight.d.ts +31 -0
- package/dist/composables/motion/index.d.ts +2 -0
- package/dist/composables/motion/scrollReader.d.ts +25 -0
- package/dist/composables/motion/springPresets.d.ts +19 -1
- package/dist/composables/motion/suite.d.ts +2 -2
- package/dist/composables/motion/useBloomUp.d.ts +97 -0
- package/dist/composables/motion/useCelebrationBurst.d.ts +50 -0
- package/dist/composables/motion/useCharStagger.d.ts +44 -0
- package/dist/composables/motion/useDockCtaReceive.d.ts +29 -22
- package/dist/composables/motion/useGooMorph.d.ts +72 -0
- package/dist/composables/motion/useLiquidFlex.d.ts +18 -0
- package/dist/composables/motion/useLiquidMorph.d.ts +108 -0
- package/dist/composables/motion/useLiquidPress.d.ts +12 -0
- package/dist/composables/motion/useLiquidReveal.d.ts +7 -4
- package/dist/composables/motion/useMorphField.d.ts +157 -0
- package/dist/composables/motion/useScrollChrome.d.ts +58 -0
- package/dist/composables/motion/useScrollPin.d.ts +49 -0
- package/dist/composables/motion/useScrollScene.d.ts +67 -0
- package/dist/composables/motion/useScrollTrigger.d.ts +67 -0
- package/dist/composables/motion/useSpringPress.d.ts +5 -5
- package/dist/composables/motion/useStaggerReveal.d.ts +24 -0
- package/dist/composables/sidebar/index.d.ts +4 -1
- package/dist/composables/sidebar/types.d.ts +68 -3
- package/dist/composables/sidebar/useClickDelegate.d.ts +4 -0
- package/dist/composables/sidebar/useLazyLoader.d.ts +5 -0
- package/dist/composables/sidebar/useScrollTo.d.ts +5 -0
- package/dist/composables/virtual/index.d.ts +4 -0
- package/dist/composables/virtual/useVirtualSectionWindow.d.ts +72 -0
- package/dist/composables/virtual/useWindowedStore.d.ts +43 -0
- package/dist/composables/virtual/virtualSectionLayout.d.ts +103 -0
- package/dist/concentric.js +552 -309
- package/dist/configurator.js +2 -2
- package/dist/confirm-dialog.js +62 -47
- package/dist/constellation.js +635 -235
- package/dist/context-menu.js +2 -2
- package/dist/controls.js +2 -2
- package/dist/createCanvasLifecycle-CuCrGRfq.js +173 -0
- package/dist/dark.js +1 -1
- package/dist/data-table.js +1 -1
- package/dist/deck.d.ts +1 -0
- package/dist/deck.js +105 -0
- package/dist/dialog.js +4 -3
- package/dist/dock.js +1320 -631
- package/dist/dockContext-gFVS2gMg.js +18 -0
- package/dist/dom.js +7 -6
- package/dist/dot-flow-field.js +1268 -387
- package/dist/dot-matrix.d.ts +1 -0
- package/dist/dot-matrix.js +774 -0
- package/dist/dotMatrixField-CRO0ZFk4.js +48 -0
- package/dist/drawer.js +106 -96
- package/dist/{dropdown-menu-CofSZuk8.js → dropdown-menu-CCfcCQ68.js} +83 -79
- package/dist/dropdown-menu.js +1 -1
- package/dist/easing.js +188 -176
- package/dist/expandable-container.js +43 -21
- package/dist/fading-scroll.js +1 -1
- package/dist/flow.glsl-DqEGRpl4.js +4 -0
- package/dist/forms.js +64 -62
- package/dist/fourier-field.js +1069 -178
- package/dist/fourier-math.js +1 -1
- package/dist/glass-panel.js +2 -2
- package/dist/glass-ui.css +1 -1
- package/dist/glass-ui.js +164 -119
- package/dist/goo-blob.js +175 -1230
- package/dist/goo-dot-matrix.d.ts +1 -0
- package/dist/goo-dot-matrix.js +811 -0
- package/dist/handmark.js +137 -94
- package/dist/header-ribbon.js +1 -1
- package/dist/hover-card.js +1 -1
- package/dist/hover-popover.js +1 -1
- package/dist/icon-chip.js +1 -1
- package/dist/icon-tooltip.js +1 -1
- package/dist/index.d.ts +5 -0
- package/dist/instrument-chassis.js +1 -1
- package/dist/keyboard.js +1 -1
- package/dist/label.js +1 -1
- package/dist/labeled-field.js +70 -60
- package/dist/metric-badge.js +1 -1
- package/dist/metric-cell.js +1 -1
- package/dist/metric-stack.js +12 -3
- package/dist/motion-core.js +59 -34
- package/dist/motion-curves.js +30 -14
- package/dist/motion.js +231 -96
- package/dist/notification.js +1 -1
- package/dist/number-field.js +1 -1
- package/dist/pager-dots.js +2 -91
- package/dist/paper-backdrop.js +1 -1
- package/dist/paper-grid.d.ts +1 -0
- package/dist/paper-grid.js +761 -0
- package/dist/paperGrid-CXCSMbZ1.js +191 -0
- package/dist/popover.js +1 -1
- package/dist/{presets-BW2b-fr1.js → presets-QvYgnFIZ.js} +14 -13
- package/dist/{procedural-color.glsl-CIFsJhwI.js → procedural-color.wgsl-C1Y5PkM6.js} +2 -2
- package/dist/progress.js +1 -1
- package/dist/pulse.js +2 -2
- package/dist/reactive.js +2 -2
- package/dist/{useCanvas2D-B8w_E3Rr.js → resolveCanvasColor-DsSJk06I.js} +16 -6
- package/dist/scrollReader-rc3Ns_NM.js +42 -0
- package/dist/scrolling-text.js +1 -1
- package/dist/search.js +162 -306
- package/dist/select.js +3 -3
- package/dist/selectable-chip.d.ts +1 -0
- package/dist/selectable-chip.js +48 -0
- package/dist/separator.js +1 -1
- package/dist/{sheet-tZMg0E0w.js → sheet-DUCIoOe0.js} +4 -4
- package/dist/sheet.js +1 -1
- package/dist/sidebar.js +216 -114
- package/dist/slider-CcICPe3u.js +149 -0
- package/dist/slider.js +1 -1
- package/dist/sortable-list.js +3 -3
- package/dist/spectrum-walk-cBNSx_zm.js +33 -0
- package/dist/springPresets-DfoQ6XRY.js +64 -0
- package/dist/stacked-icons.js +54 -39
- package/dist/styles/animations.css +13 -3
- package/dist/styles/cards.css +271 -2
- package/dist/styles/completion-seal.css +131 -0
- package/dist/styles/components.css +1 -4
- package/dist/styles/configurator.css +221 -1
- package/dist/styles/critical-partition.mjs +66 -11
- package/dist/styles/deferred.css +4 -0
- package/dist/styles/dock/adaptive-legibility.css +119 -0
- package/dist/styles/dock/cta-seat.css +87 -0
- package/dist/styles/dock/density.css +167 -6
- package/dist/styles/dock/fission-bridge.css +552 -0
- package/dist/styles/dock/layers.css +90 -78
- package/dist/styles/dock/morph-bridge.css +67 -18
- package/dist/styles/dock/morph.css +57 -118
- package/dist/styles/dock/overflow.css +12 -0
- package/dist/styles/dock/search.css +68 -0
- package/dist/styles/dock/shape.css +250 -0
- package/dist/styles/dock/shell.css +24 -8
- package/dist/styles/dock/stack-rail.css +352 -0
- package/dist/styles/dock-controls/dark-mode-toggle.css +17 -4
- package/dist/styles/dock-controls/icon-button.css +46 -0
- package/dist/styles/dock-controls/triggers.css +23 -1
- package/dist/styles/dock-controls.css +18 -0
- package/dist/styles/dock.css +27 -2
- package/dist/styles/drawer.css +166 -0
- package/dist/styles/glass/accent-tone.css +66 -0
- package/dist/styles/glass/control-surfaces.css +167 -0
- package/dist/styles/glass/glass-atom.css +244 -0
- package/dist/styles/glass/glass-capsule.css +143 -0
- package/dist/styles/glass/glass-chip.css +215 -0
- package/dist/styles/glass/ladder.css +67 -17
- package/dist/styles/glass/liquid-enter.css +252 -0
- package/dist/styles/glass/liquid-morph.css +850 -0
- package/dist/styles/glass/material.css +70 -1
- package/dist/styles/glass/reveal.css +22 -2
- package/dist/styles/glass/rim.css +31 -9
- package/dist/styles/glass/surfaces.css +81 -150
- package/dist/styles/glass.css +21 -0
- package/dist/styles/icon-chip.css +45 -0
- package/dist/styles/index.css +26 -0
- package/dist/styles/jubilance.css +65 -0
- package/dist/styles/motion/morph-field.css +229 -0
- package/dist/styles/paper.css +230 -14
- package/dist/styles/scroll-choreography.css +135 -78
- package/dist/styles/scroll-chrome.css +123 -0
- package/dist/styles/scroll-driven.css +38 -0
- package/dist/styles/segmented-tabs.css +110 -40
- package/dist/styles/select.css +151 -0
- package/dist/styles/theme/bridges.css +22 -0
- package/dist/styles/theme/radius.css +18 -1
- package/dist/styles/tokens/color-radius.css +14 -4
- package/dist/styles/tokens/dark-arm.css +94 -12
- package/dist/styles/tokens/glass-deep.css +33 -4
- package/dist/styles/tokens/glass-fx.css +122 -1
- package/dist/styles/tokens/glass.css +226 -34
- package/dist/styles/tokens/light-dark.css +3 -3
- package/dist/styles/tokens/offsets.css +27 -0
- package/dist/styles/tokens/property-regs.css +277 -0
- package/dist/styles/tokens/scale-paper.css +86 -30
- package/dist/styles/tokens/scheme-motion.css +106 -133
- package/dist/styles/tokens/scheme-spring.css +239 -0
- package/dist/styles/tokens/scroll-tokens.css +15 -15
- package/dist/styles/tokens/shadow.css +73 -13
- package/dist/styles/tokens/sizing-config.css +110 -0
- package/dist/styles/tokens/sizing.css +55 -104
- package/dist/styles/tokens.css +14 -2
- package/dist/styles/typography/semantic.css +18 -5
- package/dist/styles/utilities/a11y-overrides.css +20 -5
- package/dist/styles/utilities/base-misc.css +52 -0
- package/dist/styles/utilities/btn.css +84 -3
- package/dist/styles/utilities/components.css +31 -6
- package/dist/styles/utilities/metal.css +26 -0
- package/dist/switch.js +1 -1
- package/dist/tabs.js +199 -182
- package/dist/timeline.js +241 -206
- package/dist/toast.js +1 -1
- package/dist/toggle-chip.js +14 -41
- package/dist/toggle-group.js +1 -1
- package/dist/tooltip.js +1 -1
- package/dist/typewriter.js +2 -2
- package/dist/uniformBridgeWGPU-BCse1SHU.js +1268 -0
- package/dist/{useAnimatedNumber-BfUq2bUM.js → useAnimatedNumber-BntskVdQ.js} +1 -1
- package/dist/{useConfiguratorState-DNlOh6c8.js → useConfiguratorState-22BcULzF.js} +41 -38
- package/dist/useControlSize-DAZ062x7.js +9 -0
- package/dist/useDockCtaReceive-DX7RDb6_.js +88 -0
- package/dist/{useDragMorph-DgxnsVJz.js → useDragMorph-DGLSewwB.js} +4 -4
- package/dist/useDragVelocity-CjcfX3dA.js +57 -0
- package/dist/useFuzzySearch-0fTYOhS4.js +177 -0
- package/dist/useGooMorph-Cs13NgYL.js +104 -0
- package/dist/useGpuSubstrate-Ceet70xq.js +347 -0
- package/dist/useHaptic-CPz5BT9I.js +134 -0
- package/dist/{useLiquidFlex-mZPMiNXh.js → useLiquidFlex-Cc6PjVJD.js} +8 -3
- package/dist/useLiquidPress-CtOQ8Z0_.js +43 -0
- package/dist/useMorphField-ogBM7ubT.js +141 -0
- package/dist/usePointerVelocityField-BrkqZFhj.js +91 -0
- package/dist/useScrollChrome-JuImi1DM.js +258 -0
- package/dist/{useSpringMount-q1amq1SJ.js → useSpringMount-DFxtzmkR.js} +1 -1
- package/dist/useSpringPress-VM9RgVq3.js +36 -0
- package/dist/{useSurfaceAxis-g0NloYEF.js → useSurfaceAxis-Ci7Dnaw2.js} +1 -1
- package/dist/{useTouchGate-CBZTD4SD.js → useTouchGate-B1Lf9XqN.js} +1 -1
- package/dist/{vendor-CKmzio-i.js → vendor-B2qOlYY3.js} +24 -11
- package/dist/virtual.d.ts +1 -0
- package/dist/virtual.js +225 -0
- package/dist/watercolor-dot.js +107 -74
- package/dist/writeVelocityWeight-Bh83xZfs.js +19 -0
- package/package.json +140 -9
- package/src/styles/animations.css +13 -3
- package/src/styles/cards.css +271 -2
- package/src/styles/completion-seal.css +131 -0
- package/src/styles/configurator.css +221 -1
- package/src/styles/critical-partition.mjs +66 -11
- package/src/styles/dock/adaptive-legibility.css +119 -0
- package/src/styles/dock/cta-seat.css +87 -0
- package/src/styles/dock/density.css +167 -6
- package/src/styles/dock/fission-bridge.css +552 -0
- package/src/styles/dock/layers.css +90 -78
- package/src/styles/dock/morph-bridge.css +67 -18
- package/src/styles/dock/morph.css +57 -118
- package/src/styles/dock/overflow.css +12 -0
- package/src/styles/dock/search.css +68 -0
- package/src/styles/dock/shape.css +250 -0
- package/src/styles/dock/shell.css +24 -8
- package/src/styles/dock/stack-rail.css +352 -0
- package/src/styles/dock-controls/dark-mode-toggle.css +17 -4
- package/src/styles/dock-controls/icon-button.css +46 -0
- package/src/styles/dock-controls/triggers.css +23 -1
- package/src/styles/dock-controls.css +18 -0
- package/src/styles/dock.css +27 -2
- package/src/styles/drawer.css +164 -0
- package/src/styles/glass/accent-tone.css +66 -0
- package/src/styles/glass/control-surfaces.css +167 -0
- package/src/styles/glass/glass-atom.css +244 -0
- package/src/styles/glass/glass-capsule.css +143 -0
- package/src/styles/glass/glass-chip.css +215 -0
- package/src/styles/glass/ladder.css +67 -17
- package/src/styles/glass/liquid-enter.css +252 -0
- package/src/styles/glass/liquid-morph.css +850 -0
- package/src/styles/glass/material.css +70 -1
- package/src/styles/glass/reveal.css +22 -2
- package/src/styles/glass/rim.css +31 -9
- package/src/styles/glass/surfaces.css +81 -150
- package/src/styles/glass.css +21 -0
- package/src/styles/icon-chip.css +45 -0
- package/src/styles/index.css +26 -0
- package/src/styles/jubilance.css +65 -0
- package/src/styles/motion/morph-field.css +229 -0
- package/src/styles/paper.css +230 -14
- package/src/styles/scroll-choreography.css +135 -78
- package/src/styles/scroll-chrome.css +123 -0
- package/src/styles/scroll-driven.css +38 -0
- package/src/styles/segmented-tabs.css +110 -36
- package/src/styles/select.css +151 -0
- package/src/styles/theme/bridges.css +22 -0
- package/src/styles/theme/radius.css +18 -1
- package/src/styles/tokens/color-radius.css +14 -4
- package/src/styles/tokens/dark-arm.css +94 -12
- package/src/styles/tokens/glass-deep.css +33 -4
- package/src/styles/tokens/glass-fx.css +122 -1
- package/src/styles/tokens/glass.css +226 -34
- package/src/styles/tokens/light-dark.css +3 -3
- package/src/styles/tokens/offsets.css +27 -0
- package/src/styles/tokens/property-regs.css +277 -0
- package/src/styles/tokens/scale-paper.css +86 -30
- package/src/styles/tokens/scheme-motion.css +106 -133
- package/src/styles/tokens/scheme-spring.css +239 -0
- package/src/styles/tokens/scroll-tokens.css +15 -15
- package/src/styles/tokens/shadow.css +73 -13
- package/src/styles/tokens/sizing-config.css +110 -0
- package/src/styles/tokens/sizing.css +55 -104
- package/src/styles/tokens.css +14 -2
- package/src/styles/typography/semantic.css +18 -5
- package/src/styles/utilities/a11y-overrides.css +20 -5
- package/src/styles/utilities/base-misc.css +52 -0
- package/src/styles/utilities/btn.css +84 -3
- package/src/styles/utilities/components.css +31 -6
- package/src/styles/utilities/metal.css +26 -0
- package/dist/ContextMenuContent-uWnVxDab.js +0 -85
- package/dist/DialogContent-DcKK8k9i.js +0 -103
- package/dist/DialogFooter-BZNX5aVr.js +0 -165
- package/dist/HoverCardContent-b2uaAMRR.js +0 -83
- package/dist/Input-h9v5LeXf.js +0 -55
- package/dist/NumberFieldContent-Cq7EzX-U.js +0 -138
- package/dist/PaperBackdrop-Vf3tlpvd.js +0 -31
- package/dist/SelectScrollDownButton-CrA8F0iV.js +0 -252
- package/dist/Separator-pKF0oA4M.js +0 -37
- package/dist/Switch-CwYNf8bo.js +0 -47
- package/dist/TooltipProvider-rzvnXz60.js +0 -104
- package/dist/badge-D9XWW4GT.js +0 -53
- package/dist/button-DYCUa-tH.js +0 -126
- package/dist/color-DweYl7pE.js +0 -86
- package/dist/components/custom/concentric/composables/ringField.d.ts +0 -44
- package/dist/components/custom/constellation/composables/useConstellationPointer.d.ts +0 -35
- package/dist/components/custom/constellation/constellationDraw.d.ts +0 -30
- package/dist/components/custom/dock/DockRail.vue.d.ts +0 -89
- package/dist/createCanvasLifecycle-CHD5XrDW.js +0 -82
- package/dist/dockContext-BNfyPLe9.js +0 -17
- package/dist/procedural-color.wgsl-CToRHugY.js +0 -224
- package/dist/resolveCanvasColor-CUyHr5Uu.js +0 -11
- package/dist/slider-DVb4HXU-.js +0 -142
- package/dist/springPresets-CFQGQfdl.js +0 -40
- package/dist/styles/dock/rail-extend.css +0 -397
- package/dist/useLiquidPress-kfb4KX79.js +0 -39
- package/dist/usePointerVelocityField-JbRd5CrM.js +0 -137
- package/dist/useRAFLoop-UYa4zoiN.js +0 -109
- package/dist/useSpringPress-BsqPr7FJ.js +0 -34
- package/src/styles/dock/rail-extend.css +0 -397
- /package/dist/{CollapsibleContent-68dEXIAl.js → CollapsibleContent-D7UNsXQr.js} +0 -0
- /package/dist/{InstrumentChassis-Bx0F_q5g.js → InstrumentChassis-UUJX0-mW.js} +0 -0
- /package/dist/{Label-C2ejNWeC.js → Label-B_HPqi_q.js} +0 -0
- /package/dist/{ModalOverlay-D1VrWyoi.js → ModalOverlay-DfAf7o15.js} +0 -0
- /package/dist/{SelectGroup-DwwjicPY.js → SelectGroup-Dcczq44n.js} +0 -0
- /package/dist/{_plugin-vue_export-helper-C1je1s0u.js → _plugin-vue_export-helper-gLzyemvl.js} +0 -0
- /package/dist/{compile-CQEFRTmx.js → compile-INR_tPk_.js} +0 -0
- /package/dist/{constants-BPOqYJAm.js → constants-BWj7DkMn.js} +0 -0
- /package/dist/{createContext-CpBNTRMI.js → createContext-Cd23P9j0.js} +0 -0
- /package/dist/{math-BINYmg5z.js → math-5RcIgCB4.js} +0 -0
- /package/dist/{menuItemVariants-D8VNHq22.js → menuItemVariants-DAXquKja.js} +0 -0
- /package/dist/{prng-Za0Rmgag.js → prng-B5tIXTtj.js} +0 -0
- /package/dist/{useGlobalDark-C28t0VWJ.js → useGlobalDark-B4HO9LXG.js} +0 -0
- /package/dist/{useIntersectionPause-Bj4sPkMh.js → useIntersectionPause-DO8Vl4gs.js} +0 -0
- /package/dist/{useInterval-CvK1mL92.js → useInterval-BVUI-sez.js} +0 -0
- /package/dist/{useKeyboardShortcuts-BXWXOZ-9.js → useKeyboardShortcuts-BEut54Tk.js} +0 -0
- /package/dist/{useResizeObserver-Bpoi7tRE.js → useResizeObserver-DdEn3v2f.js} +0 -0
- /package/dist/{useResolveTokenColor-vAylyR0x.js → useResolveTokenColor-ChOnCckA.js} +0 -0
- /package/dist/{useScrollProgress-D7bYU2RK.js → useScrollProgress-A0M6qRl7.js} +0 -0
- /package/dist/{useSortable-DHjtZSEd.js → useSortable-DQV_UNDw.js} +0 -0
- /package/dist/{useTextHighlight-CWEi25hf.js → useTextHighlight-Bma3UlKA.js} +0 -0
- /package/dist/{useTimer-BHJOKr35.js → useTimer-BBLGPXR8.js} +0 -0
- /package/dist/{useUserInvalidAria-y5namzeE.js → useUserInvalidAria-EmmwWPOl.js} +0 -0
- /package/dist/{useViewportReady-anbac3m6.js → useViewportReady-C9pYnn7K.js} +0 -0
- /package/dist/{vReveal-Czsb7zQC.js → vReveal-CT1KtwZA.js} +0 -0
- /package/dist/{vSpecular-CQFmLNzA.js → vSpecular-EX7loENl.js} +0 -0
|
@@ -1,24 +1,65 @@
|
|
|
1
1
|
import type { OklchStop } from "../../../../composables/color";
|
|
2
2
|
import { type FlowFieldConfig } from "../constants";
|
|
3
|
+
/** The domain half-extent (the lattice spans [-half, half]²; mirrors flowField.ts). */
|
|
4
|
+
export declare const FLOW_DOMAIN_HALF = 0.85;
|
|
5
|
+
export interface FlowGridGeometry {
|
|
6
|
+
cols: number;
|
|
7
|
+
count: number;
|
|
8
|
+
/** The lattice pitch in DOMAIN units (the px pitch mapped to the domain). */
|
|
9
|
+
pitchDomain: number;
|
|
10
|
+
}
|
|
11
|
+
/** Compile-time lattice cap (mirrors the WGSL storage-buffer array bound). */
|
|
12
|
+
export declare const FLOW_MAX_LATTICE = 16384;
|
|
13
|
+
export declare function flowGridGeometry(gridPitchPx: number, canvasCssMin: number): FlowGridGeometry;
|
|
3
14
|
export declare const FLOW_COMPUTE_UNIFORM_BYTES: number;
|
|
15
|
+
/** The live pointer/vortex state the renderer feeds the compute kernel each frame. */
|
|
16
|
+
export interface FlowPointerState {
|
|
17
|
+
/** Cursor in domain space ([-half,half]²). */
|
|
18
|
+
cursorX: number;
|
|
19
|
+
cursorY: number;
|
|
20
|
+
/** Pointer velocity in domain units / sec. */
|
|
21
|
+
velX: number;
|
|
22
|
+
velY: number;
|
|
23
|
+
/** Flick-burst impulse (0..1). */
|
|
24
|
+
burst: number;
|
|
25
|
+
/** Pointer active (1) / inert (0). */
|
|
26
|
+
active: number;
|
|
27
|
+
}
|
|
28
|
+
/** A rest (pointer-inert) state — the vortex is off. */
|
|
29
|
+
export declare const FLOW_POINTER_REST: FlowPointerState;
|
|
4
30
|
export interface FlowUniformScratch {
|
|
5
31
|
buffer: ArrayBuffer;
|
|
6
32
|
f32: Float32Array;
|
|
7
33
|
i32: Int32Array;
|
|
8
34
|
}
|
|
9
35
|
export declare function createFlowComputeScratch(): FlowUniformScratch;
|
|
10
|
-
/**
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
export declare function packFlowComputeUniforms(scratch: FlowUniformScratch, config: FlowFieldConfig, timeSec: number, dt: number, particleCount: number): FlowUniformScratch;
|
|
36
|
+
/** Pack the compute uniforms in place. `count` is the live mote/lattice count (flow mode
|
|
37
|
+
* uses particleCount; field mode uses the lattice geometry count). */
|
|
38
|
+
export declare function packFlowComputeUniforms(scratch: FlowUniformScratch, config: FlowFieldConfig, timeSec: number, dt: number, geometry: FlowGridGeometry, count: number, pointer?: FlowPointerState): FlowUniformScratch;
|
|
14
39
|
export declare const FLOW_RENDER_UNIFORM_BYTES: number;
|
|
40
|
+
/** The speed normalizer (the modal mote speed maps to the ramp MIDDLE — H2: so the full
|
|
41
|
+
* ember→gold→white spread paints, not a unimodal-amber blowout). */
|
|
42
|
+
export declare const FLOW_SPEED_NORM = 0.022;
|
|
15
43
|
export declare function createFlowRenderScratch(): FlowUniformScratch;
|
|
44
|
+
/** The base resting brightness (the calm-lattice floor before the band lights a dot). */
|
|
45
|
+
export declare const FLOW_BASE_BRIGHT = 0.22;
|
|
46
|
+
/** The drift-driven size pulse (a subtle breathing; never a re-seed). */
|
|
47
|
+
export declare const FLOW_SIZE_PULSE = 0.4;
|
|
16
48
|
/** Pack the render uniforms in place. */
|
|
17
|
-
export declare function packFlowRenderUniforms(scratch: FlowUniformScratch, config: FlowFieldConfig, timeSec: number, aspect: number, canvasCssMin: number, palette: OklchStop[]): FlowUniformScratch;
|
|
18
|
-
/** The byte size of one
|
|
49
|
+
export declare function packFlowRenderUniforms(scratch: FlowUniformScratch, config: FlowFieldConfig, timeSec: number, aspect: number, canvasCssMin: number, geometry: FlowGridGeometry, palette: OklchStop[]): FlowUniformScratch;
|
|
50
|
+
/** The byte size of one lattice dot in the storage buffer (vec4<f32>). */
|
|
19
51
|
export declare const FLOW_PARTICLE_BYTES = 16;
|
|
20
52
|
/**
|
|
21
|
-
* Seed the
|
|
22
|
-
*
|
|
53
|
+
* Seed the lattice storage buffer: each dot starts AT its anchor origin (the restoring
|
|
54
|
+
* spring needs no initial offset). `(pos.x, pos.y, height=0, |disp|=0)` per index — the
|
|
55
|
+
* compute kernel re-derives the origin from `gridOrigin(index, cols, pitch)` each frame,
|
|
56
|
+
* so the seed only needs the starting position (the lattice settles on the first frames).
|
|
57
|
+
*/
|
|
58
|
+
export declare function seedLatticeBuffer(geometry: FlowGridGeometry): Float32Array;
|
|
59
|
+
/**
|
|
60
|
+
* BD.W-DOTFLOW-AURORA-CURRENT — seed the FLOW mote buffer: each mote scattered across the
|
|
61
|
+
* domain, life STAGGERED across [0, lifetimeSec) so deaths/respawns don't synchronize (the
|
|
62
|
+
* field never blinks). `(pos.x, pos.y, speed=0, life)` per index. A deterministic hash so
|
|
63
|
+
* the capture path reproduces.
|
|
23
64
|
*/
|
|
24
|
-
export declare function
|
|
65
|
+
export declare function seedFlowBuffer(count: number, lifetimeSec: number): Float32Array;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { type Ref } from "vue";
|
|
2
2
|
import { type GpuBackend } from "../../../../composables/glass/webgpu/useGpuSubstrate";
|
|
3
|
-
import {
|
|
3
|
+
import type { OklchStop } from "../../../../composables/color";
|
|
4
4
|
import type { FlowFieldConfig } from "../constants";
|
|
5
5
|
export interface UseDotFlowFieldOptions {
|
|
6
6
|
config: FlowFieldConfig;
|
|
@@ -11,7 +11,7 @@ export interface UseDotFlowFieldOptions {
|
|
|
11
11
|
}
|
|
12
12
|
/** The uniform handle a consumer wires its lifecycle against (backend-agnostic). */
|
|
13
13
|
export interface DotFlowFieldHandle {
|
|
14
|
-
/** The resolved backend (`"webgpu"` where supported, else the
|
|
14
|
+
/** The resolved backend (`"webgpu"` where supported, else the WebGL2 fragment fallback). */
|
|
15
15
|
readonly backend: GpuBackend;
|
|
16
16
|
/** Park the loop (the WCAG-2.2.2 pause seam — `DockBackgroundToggle` wires this). */
|
|
17
17
|
pause: () => void;
|
|
@@ -23,12 +23,13 @@ export interface DotFlowFieldHandle {
|
|
|
23
23
|
renderAt: (timeSec: number) => void;
|
|
24
24
|
/** The live `prefers-reduced-motion: reduce` state. */
|
|
25
25
|
readonly reducedMotion: boolean;
|
|
26
|
-
/** Tear down the renderer + release GPU/
|
|
26
|
+
/** Tear down the renderer + release GPU/GL resources. */
|
|
27
27
|
dispose: () => void;
|
|
28
28
|
}
|
|
29
29
|
/**
|
|
30
30
|
* Mount the dot-flow-field renderer on `canvasRef`. The WebGPU primary runs the
|
|
31
|
-
* compute+render two-pass; the
|
|
32
|
-
* (the ONE math source). Returns the
|
|
31
|
+
* compute+render two-pass over the anchored lattice; the WebGL2 fallback evaluates the SAME
|
|
32
|
+
* `flowField.ts` field as a fullscreen fragment pass (the ONE math source). Returns the
|
|
33
|
+
* uniform lifecycle handle.
|
|
33
34
|
*/
|
|
34
35
|
export declare function useDotFlowField(canvasRef: Ref<HTMLCanvasElement | null>, options: UseDotFlowFieldOptions): DotFlowFieldHandle;
|
|
@@ -1,18 +1,32 @@
|
|
|
1
|
-
import type { WebGPUCanvasFrame } from "../../../../composables/glass/webgpu/useWebGPUCanvas";
|
|
2
1
|
import type { OklchStop } from "../../../../composables/color";
|
|
3
2
|
import type { FlowFieldConfig } from "../constants";
|
|
4
|
-
|
|
3
|
+
import { type FlowPointerState } from "./uniformBridgeWGPU";
|
|
4
|
+
export { flowGridGeometry } from "./uniformBridgeWGPU";
|
|
5
|
+
/** The deep warm-near-black floor + the warm rose corner-bloom (linear-sRGB), the §3 ground.
|
|
6
|
+
* Resolved off a warm-fire-adjacent OKLCh ground (NOT teal). The demo preset overrides via
|
|
7
|
+
* `config.background`; this is the fallback ground for the flow present-composite. */
|
|
8
|
+
export declare const FLOW_FLOOR_OKLCH: OklchStop;
|
|
9
|
+
export declare const FLOW_BLOOM_OKLCH: OklchStop;
|
|
10
|
+
export interface FlowSetupDeps {
|
|
5
11
|
canvas: HTMLCanvasElement;
|
|
6
12
|
config: FlowFieldConfig;
|
|
7
13
|
/** The resolved (ColorResolver) palette stops as OKLCh — re-read each frame so a live palette edit reaches the buffer. */
|
|
8
14
|
getPalette: () => OklchStop[];
|
|
9
15
|
/** Demand-gate (the renderer's quiescence layer — substrate-agnostic). */
|
|
10
16
|
shouldContinue: () => boolean;
|
|
11
|
-
/**
|
|
12
|
-
|
|
17
|
+
/**
|
|
18
|
+
* The per-frame pointer hook — useDotFlowField advances the shared
|
|
19
|
+
* `usePointerVelocityField` here (the no-own-rAF discipline). ZERO own rAF.
|
|
20
|
+
*/
|
|
21
|
+
onFrame?: (timeSec: number) => void;
|
|
22
|
+
/** The live pointer/vortex state the renderer feeds the flow kernel (rest = inert). */
|
|
23
|
+
getPointer?: () => FlowPointerState;
|
|
13
24
|
}
|
|
14
|
-
/**
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
25
|
+
/** A px-min reader (the lattice density rides the min CSS dimension). */
|
|
26
|
+
export declare function cssMin(canvas: HTMLCanvasElement): number;
|
|
27
|
+
/** The flow mote count, clamped to the storage/state cap. */
|
|
28
|
+
export declare function flowCount(config: FlowFieldConfig): number;
|
|
29
|
+
/** The square state-texture side that holds `count` motes (one texel each). */
|
|
30
|
+
export declare function stateCols(count: number): number;
|
|
31
|
+
export { createFlowWGPUSetup } from "./flowSetupWGPU";
|
|
32
|
+
export { createFlowGLSetup } from "./flowSetupGL";
|
|
@@ -1,48 +1,120 @@
|
|
|
1
1
|
import type { WaveComponent } from "./composables/flowField";
|
|
2
2
|
import type { OklchStop } from "../../../composables/color";
|
|
3
|
-
/** Compile-time
|
|
3
|
+
/** Compile-time lattice cap — mirrors the WGSL storage-buffer array bound. */
|
|
4
4
|
export declare const MAX_PARTICLES = 16384;
|
|
5
5
|
/** Compile-time wave-component cap — mirrors the WGSL `MAX_WAVE_COMPONENTS` #define. */
|
|
6
6
|
export declare const MAX_WAVE_COMPONENTS = 8;
|
|
7
7
|
/** Compile-time palette cap — mirrors the WGSL `MAX_FLOW_STOPS` #define. */
|
|
8
8
|
export declare const MAX_FLOW_STOPS = 4;
|
|
9
|
-
|
|
10
|
-
export declare const
|
|
9
|
+
export declare const PHI = 1.618033988749895;
|
|
10
|
+
export declare const SQRT_PHI: number;
|
|
11
|
+
/**
|
|
12
|
+
* The per-frame trail decay α DERIVED from a half-life in seconds (DRY — `trailDecay` is
|
|
13
|
+
* NOT a free knob; the streak persistence is a proportion of `trailHalfLife`). At a 60fps
|
|
14
|
+
* reference cadence, α = 2^(−dtRef / halfLife) so the trail fades to ½ over `halfLife`.
|
|
15
|
+
*/
|
|
16
|
+
export declare function flowTrailDecay(halfLifeSec: number, dtRef?: number): number;
|
|
11
17
|
/**
|
|
12
18
|
* The full author schema — the studio's `useConfiguratorState` model. Every field is a
|
|
13
19
|
* tunable the demo configurator drives; the SFC resolves it into the uniform table.
|
|
20
|
+
*
|
|
21
|
+
* RETOPOLOGY: the lattice density is derived from `gridPitch` (a clean break from the free
|
|
22
|
+
* `particleCount` — README MIGRATION row `particleCount → gridPitch`). The brightness/scale
|
|
23
|
+
* shape rides `contrast`/`waveBandCenter`/`waveBandWidth`; the sub-cell drift rides
|
|
24
|
+
* `displaceAmp`/`springK`; `coherence` maps the octave count + persistence.
|
|
14
25
|
*/
|
|
15
26
|
export interface FlowFieldConfig {
|
|
16
|
-
/**
|
|
27
|
+
/**
|
|
28
|
+
* BD.W-DOTFLOW-AURORA-CURRENT — the topology discriminator (the dock `dim`-idiom
|
|
29
|
+
* discipline: ONE schema, two orthogonal lever sets, no fork). `"flow"` (default) is
|
|
30
|
+
* the AURORA CURRENT — a dense population ADVECTED along the curl current, trailing
|
|
31
|
+
* fading ribbons of warm-fire light, the cursor a live vortex. `"field"` is the calm
|
|
32
|
+
* anchored halftone (the rebuild's content-deferential backdrop — the kept register).
|
|
33
|
+
*/
|
|
34
|
+
mode: "flow" | "field";
|
|
35
|
+
/** Mote population (flow mode) — re-introduced, mode-scoped (field keeps gridPitch). */
|
|
17
36
|
particleCount: number;
|
|
18
|
-
/**
|
|
37
|
+
/** Trail streak half-life in seconds (the √φ τ₀ anchor); `trailDecay` derives from it. */
|
|
38
|
+
trailHalfLife: number;
|
|
39
|
+
/** Half-res trail buffer scale (R-D — quarters the float fillrate at 0.5). */
|
|
40
|
+
trailScale: number;
|
|
41
|
+
/** Inertia 0..1: the velocity lerp rate (LOW = weighty arcs, eases into the field). */
|
|
42
|
+
turnRate: number;
|
|
43
|
+
/** Advection speed gain (|V| → displacement-per-frame). */
|
|
44
|
+
speedScale: number;
|
|
45
|
+
/** Brightness-from-speed gain (the velocity-map glow). */
|
|
46
|
+
speedGlow: number;
|
|
47
|
+
/** Mote lifetime in seconds before respawn (the √φ τ₀·φ rung). */
|
|
48
|
+
lifetimeSec: number;
|
|
49
|
+
/** Density-vignette strength (shared with field; thins spawns behind the content rect). */
|
|
50
|
+
edgeBias: number;
|
|
51
|
+
/** The clear content region (the v4 content-deferential vignette; shared with field). */
|
|
52
|
+
contentMask: {
|
|
53
|
+
cx: number;
|
|
54
|
+
cy: number;
|
|
55
|
+
rx: number;
|
|
56
|
+
ry: number;
|
|
57
|
+
} | null;
|
|
58
|
+
/** Cursor-vortex fall-off radius (the √φ r₀ anchor). */
|
|
59
|
+
vortexRadius: number;
|
|
60
|
+
/** Cursor-vortex tangential spin gain (the swirl). */
|
|
61
|
+
vortexSpin: number;
|
|
62
|
+
/** Cursor-drag advection gain (the streamlines follow the gesture). */
|
|
63
|
+
dragGain: number;
|
|
64
|
+
/** Flick-burst radial shove gain (the shockwave). */
|
|
65
|
+
burstShove: number;
|
|
66
|
+
/** WebGPU cartoon-cast shadow offset (drops on WebGL2/PRM/PRT). */
|
|
67
|
+
shadowOffset: number;
|
|
68
|
+
/** WebGPU velocity-anisotropic squash-stretch amount (drops on WebGL2/PRM/PRT). */
|
|
69
|
+
stretchAmp: number;
|
|
70
|
+
/** The Gerstner sum-of-sines table (1..MAX_WAVE_COMPONENTS) — the LARGE-wave ladder. */
|
|
19
71
|
waveComponents: WaveComponent[];
|
|
20
|
-
/** The
|
|
21
|
-
windDirection: number;
|
|
22
|
-
/** The dispersion-driven travel speed (scales ω). */
|
|
72
|
+
/** The dispersion-driven sweep speed (scales ω). LOW = slow sweep (default 0.3). */
|
|
23
73
|
windSpeed: number;
|
|
24
|
-
/** The fbm curl-noise braiding
|
|
74
|
+
/** The fbm curl-noise braiding-break weight (0..0.4 — keep low; default 0.12). */
|
|
25
75
|
curlStrength: number;
|
|
26
|
-
/** The
|
|
76
|
+
/** The lattice spacing in CSS-px (drives N = view/pitch²). ~26px ≈ the reference. */
|
|
77
|
+
gridPitch: number;
|
|
78
|
+
/** The dot billboard base radius in px @ 1×. */
|
|
27
79
|
dotSize: number;
|
|
28
|
-
/** How
|
|
29
|
-
|
|
30
|
-
/** The
|
|
80
|
+
/** How far a dot drifts from its anchor, in pitch fractions (capped < 0.5 pitch). */
|
|
81
|
+
displaceAmp: number;
|
|
82
|
+
/** The restoring-spring rate (the pull-to-anchor stiffness; higher = stiffer). */
|
|
83
|
+
springK: number;
|
|
84
|
+
/** The sweeping-band center over the normalized height (the iso-band the wave rides). */
|
|
85
|
+
waveBandCenter: number;
|
|
86
|
+
/** The sweeping bright-stripe thickness (`waveBand` width over the normalized height). */
|
|
87
|
+
waveBandWidth: number;
|
|
88
|
+
/** The brightness modulation depth (subtle ↔ bold; 0..1). */
|
|
89
|
+
contrast: number;
|
|
90
|
+
/** The Coherence axis (0..1; high = few coarse octaves coherent, low = many fine). */
|
|
91
|
+
coherence: number;
|
|
92
|
+
/** The soft-disc globe mask (the reference's two-sphere composition); off by default. */
|
|
93
|
+
globeMask: boolean;
|
|
94
|
+
/** The dot-color ramp (the demo themes it mono-white); resolved via the ColorResolver. */
|
|
31
95
|
palette: OklchStop[];
|
|
32
|
-
/** The ground color (the demo sets
|
|
96
|
+
/** The ground color (the demo sets near-black; default transparent). */
|
|
33
97
|
background: OklchStop | "transparent";
|
|
34
|
-
/** Pointer-warp the
|
|
98
|
+
/** Pointer-warp the lattice (a local displacement ripple about the cursor). */
|
|
35
99
|
interactive: boolean;
|
|
36
100
|
/** ONE static frame then park under `prefers-reduced-motion: reduce`. */
|
|
37
101
|
respectReducedMotion: boolean;
|
|
38
102
|
}
|
|
39
103
|
/**
|
|
40
|
-
* The warm-cream identity palette (the library default — NOT teal). A two-stop
|
|
41
|
-
*
|
|
42
|
-
*
|
|
104
|
+
* The warm-cream identity palette (the library default — NOT teal). A two-stop warm-amber
|
|
105
|
+
* ramp over the warm-cream foreground family, resolved via the ColorResolver. A consumer
|
|
106
|
+
* (the demo) themes it mono-white-on-near-black through a PRESET, never a token edit.
|
|
43
107
|
*/
|
|
44
108
|
export declare const WARM_IDENTITY_PALETTE: OklchStop[];
|
|
45
|
-
/**
|
|
109
|
+
/**
|
|
110
|
+
* The default LARGE-wave ladder about a 35° diagonal wind — 3 coherent octaves, λ₀ at
|
|
111
|
+
* 2.5× the domain extent (ONE dominant sweeping wave). The §1 regime inversion.
|
|
112
|
+
*/
|
|
46
113
|
export declare const DEFAULT_WAVE_COMPONENTS: WaveComponent[];
|
|
47
|
-
/**
|
|
114
|
+
/**
|
|
115
|
+
* The shipped warm-identity default config — the SUBTLE + LARGE regime (the §1/§2
|
|
116
|
+
* topology+regime targets): a calm warm-cream lattice (~26px pitch) a slow LARGE wave
|
|
117
|
+
* sweeps through, the dots only breathing a hair off their anchors. globeMask OFF (the
|
|
118
|
+
* neutral register — the reference's soft-disc is a DEMO preset).
|
|
119
|
+
*/
|
|
48
120
|
export declare const DEFAULT_FLOW_CONFIG: FlowFieldConfig;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export { default as DotFlowField } from "./DotFlowField.vue";
|
|
2
2
|
export { useDotFlowField, type DotFlowFieldHandle, type UseDotFlowFieldOptions, } from "./composables/useDotFlowField";
|
|
3
|
-
export { type FlowFieldConfig, DEFAULT_FLOW_CONFIG, DEFAULT_WAVE_COMPONENTS, WARM_IDENTITY_PALETTE, MAX_PARTICLES, MAX_WAVE_COMPONENTS, MAX_FLOW_STOPS,
|
|
4
|
-
export { type WaveComponent, type Vec2, sampleVelocity, gerstnerVelocity, curlFBM, buildWaveLadder, FLOW_GRAVITY, } from "./composables/flowField";
|
|
3
|
+
export { type FlowFieldConfig, DEFAULT_FLOW_CONFIG, DEFAULT_WAVE_COMPONENTS, WARM_IDENTITY_PALETTE, MAX_PARTICLES, MAX_WAVE_COMPONENTS, MAX_FLOW_STOPS, } from "./constants";
|
|
4
|
+
export { type WaveComponent, type Vec2, sampleVelocity, gerstnerVelocity, curlFBM, pointerVortex, type VortexParams, buildWaveLadder, gridOrigin, sampleHeight, sampleDisplacement, waveBand, FLOW_GRAVITY, FLOW_DOMAIN_HALF, } from "./composables/flowField";
|
|
5
5
|
export type { OklchStop } from "../../../composables/color";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const FLOW_FIELD_COMPUTE_WGSL = "\nconst MAX_WAVE_COMPONENTS: i32 = 8;\nconst PI: f32 = 3.141592653589793;\nconst TAU: f32 = 6.283185307179586;\nconst FLOW_GRAVITY: f32 = 9.81;\nconst CURL_EPS: f32 = 0.012;\nconst FBM_ROT: mat2x2<f32> = mat2x2<f32>(0.8, 0.6, -0.6, 0.8);\n\nstruct Particle {\n // (pos.x, pos.y, age, seed)\n data: vec4<f32>,\n};\n\n// \u2500\u2500 Uniforms (the typed-struct source-of-truth \u2014 see uniformBridgeWGPU.ts) \u2500\u2500\nstruct FlowUniforms {\n // p0: (uTime, uDt, uWindSpeed, uCurlStrength)\n p0: vec4<f32>,\n // p1: (uDomainHalf, uReseedJitter, _pad, _pad)\n p1: vec4<f32>,\n // ints: (uWaveCount, uParticleCount, _pad, _pad)\n ints: vec4<i32>,\n // each wave row: (amplitude, wavelength, directionDeg, phase)\n waves: array<vec4<f32>, 8>,\n};\n\n@group(0) @binding(0) var<uniform> u: FlowUniforms;\n@group(0) @binding(1) var<storage, read_write> particles: array<Particle>;\n\n// \u2500\u2500 The Gerstner-sum analytic \u2207\u22A5h velocity (transcribes flowField.ts gerstnerVelocity) \u2500\u2500\nfn gerstnerVelocity(p: vec2<f32>, t: f32) -> vec2<f32> {\n var dhdx = 0.0;\n var dhdy = 0.0;\n let windSpeed = u.p0.z;\n let waveCount = u.ints.x;\n for (var i = 0; i < MAX_WAVE_COMPONENTS; i = i + 1) {\n if (i >= waveCount) { break; }\n let w = u.waves[i];\n let amplitude = w.x;\n let wavelength = max(w.y, 1e-4);\n let dirRad = w.z * PI / 180.0;\n let phase = w.w;\n let k = TAU / wavelength;\n let d = vec2<f32>(cos(dirRad), sin(dirRad));\n let omega = sqrt(FLOW_GRAVITY * k) * windSpeed;\n let theta = k * (d.x * p.x + d.y * p.y) - omega * t + phase;\n let akc = amplitude * k * cos(theta);\n dhdx = dhdx + akc * d.x;\n dhdy = dhdy + akc * d.y;\n }\n // v = \u2207\u22A5h = (\u2202h/\u2202y, \u2212\u2202h/\u2202x).\n return vec2<f32>(dhdy, -dhdx);\n}\n\n// \u2500\u2500 Shared curl-noise basis (the WGSL twin of flow.glsl.ts curlFBM) \u2500\u2500\nfn hash21(p: vec2<f32>) -> f32 {\n var p3 = fract(vec3<f32>(p.x, p.y, p.x) * 0.1031);\n p3 = p3 + dot(p3, p3.yzx + 33.33);\n return fract((p3.x + p3.y) * p3.z);\n}\n\nfn valueNoise(p: vec2<f32>) -> f32 {\n let i = floor(p);\n let f = fract(p);\n let u2 = f * f * f * (f * (f * 6.0 - 15.0) + 10.0);\n let a = hash21(i + vec2<f32>(0.0, 0.0));\n let b = hash21(i + vec2<f32>(1.0, 0.0));\n let c = hash21(i + vec2<f32>(0.0, 1.0));\n let d = hash21(i + vec2<f32>(1.0, 1.0));\n return mix(mix(a, b, u2.x), mix(c, d, u2.x), u2.y);\n}\n\nfn potentialFBM(p0: vec2<f32>) -> f32 {\n var v = 0.0;\n var amp = 0.5;\n var freq = 1.0;\n var p = p0;\n for (var i = 0; i < 3; i = i + 1) {\n v = v + amp * valueNoise(p * freq);\n p = FBM_ROT * p;\n freq = freq * 2.0;\n amp = amp * 0.5;\n }\n return v;\n}\n\nfn curlFBM(p: vec2<f32>) -> vec2<f32> {\n let dx = potentialFBM(p + vec2<f32>(CURL_EPS, 0.0)) - potentialFBM(p - vec2<f32>(CURL_EPS, 0.0));\n let dy = potentialFBM(p + vec2<f32>(0.0, CURL_EPS)) - potentialFBM(p - vec2<f32>(0.0, CURL_EPS));\n let g = vec2<f32>(dx, dy) / (2.0 * CURL_EPS);\n return vec2<f32>(g.y, -g.x);\n}\n\n// The composite flow velocity (transcribes flowField.ts sampleVelocity EXACTLY).\nfn sampleVelocity(p: vec2<f32>, t: f32) -> vec2<f32> {\n let curlStrength = u.p0.w;\n var v = gerstnerVelocity(p, t);\n if (curlStrength > 0.0) {\n let c = curlFBM(vec2<f32>(p.x * 1.7 + t * 0.15, p.y * 1.7));\n v = v + c * curlStrength;\n }\n return v;\n}\n\n// A particle that leaves the bounds re-spawns at a seed-derived position (so coverage\n// stays steady \u2014 the \u00A73 re-seed-at-edge rule). The seed advances each re-spawn so a\n// re-seeded particle does not pile on the previous spawn.\nfn reseed(seed: f32, age: f32) -> vec2<f32> {\n let half = u.p1.x;\n let r1 = hash21(vec2<f32>(seed * 71.13, age * 13.7));\n let r2 = hash21(vec2<f32>(seed * 19.31 + 4.0, age * 7.3 + 2.0));\n return (vec2<f32>(r1, r2) * 2.0 - 1.0) * half;\n}\n\n@compute @workgroup_size(64)\nfn cs_main(@builtin(global_invocation_id) gid: vec3<u32>) {\n let idx = gid.x;\n let count = u32(u.ints.y);\n if (idx >= count) { return; } // bounds-guard the dispatch tail\n\n let t = u.p0.x;\n let dt = u.p0.y;\n let half = u.p1.x;\n\n var pr = particles[idx];\n var pos = pr.data.xy;\n var age = pr.data.z;\n let seed = pr.data.w;\n\n let v = sampleVelocity(pos, t);\n // Forward Euler \u2014 p_{n+1} = p_n + v\u00B7dt.\n pos = pos + v * dt;\n age = age + dt;\n\n // Wrap / re-seed at the domain edge (re-spawn from the seed at a fresh position).\n if (abs(pos.x) > half || abs(pos.y) > half || age > 6.0) {\n pos = reseed(seed, age);\n age = 0.0;\n }\n\n particles[idx] = Particle(vec4<f32>(pos, age, seed));\n}\n";
|
|
1
|
+
export declare const FLOW_FIELD_COMPUTE_WGSL = "\nconst MAX_WAVE_COMPONENTS: i32 = 8;\nconst PI: f32 = 3.141592653589793;\nconst TAU: f32 = 6.283185307179586;\nconst FLOW_GRAVITY: f32 = 9.81;\nconst CURL_EPS: f32 = 0.012;\nconst FBM_ROT: mat2x2<f32> = mat2x2<f32>(0.8, 0.6, -0.6, 0.8);\n\nstruct Particle {\n // field: (pos.x, pos.y, height, |disp|) \u2014 the anchored-lattice live state\n // flow: (pos.x, pos.y, speed, life) \u2014 the advected-mote live state\n data: vec4<f32>,\n};\n\n// \u2500\u2500 Uniforms (the typed-struct source-of-truth \u2014 see uniformBridgeWGPU.ts) \u2500\u2500\nstruct FlowUniforms {\n // p0: (uTime, uDt, uWindSpeed, uCurlStrength)\n p0: vec4<f32>,\n // p1: (uGridPitch, uDisplaceAmp, uSpringK, uGridCols) \u2014 the lattice geometry (field)\n p1: vec4<f32>,\n // ints: (uWaveCount, uParticleCount, uGridColsI, uMode) \u2014 uMode: 0=field, 1=flow\n ints: vec4<i32>,\n // f0: (uTurnRate, uSpeedScale, uLifetimeSec, uDomainHalf) \u2014 the flow advection levers\n f0: vec4<f32>,\n // f1: (uVortexRadius, uVortexSpin, uDragGain, uBurstShove) \u2014 the cursor vortex\n f1: vec4<f32>,\n // ptr: (cursor.x, cursor.y, vel.x, vel.y) \u2014 the pointer in domain space + its velocity\n ptr: vec4<f32>,\n // ptr2: (burst, pointerActive, edgeBias, _pad)\n ptr2: vec4<f32>,\n // each wave row: (amplitude, wavelength, directionDeg, phase)\n waves: array<vec4<f32>, 8>,\n};\n\n@group(0) @binding(0) var<uniform> u: FlowUniforms;\n@group(0) @binding(1) var<storage, read_write> particles: array<Particle>;\n\n// \u2500\u2500 The deterministic lattice origin (transcribes flowField.ts gridOrigin) \u2500\u2500\nfn gridOrigin(index: u32, cols: i32, pitch: f32) -> vec2<f32> {\n let c = max(cols, 1);\n let col = i32(index) % c;\n let row = i32(index) / c;\n let half = f32(c - 1) * pitch * 0.5;\n return vec2<f32>(f32(col) * pitch - half, f32(row) * pitch - half);\n}\n\n// \u2500\u2500 The Gerstner-sum analytic \u2207\u22A5h velocity (transcribes flowField.ts gerstnerVelocity) \u2500\u2500\nfn gerstnerVelocity(p: vec2<f32>, t: f32) -> vec2<f32> {\n var dhdx = 0.0;\n var dhdy = 0.0;\n let windSpeed = u.p0.z;\n let waveCount = u.ints.x;\n for (var i = 0; i < MAX_WAVE_COMPONENTS; i = i + 1) {\n if (i >= waveCount) { break; }\n let w = u.waves[i];\n let amplitude = w.x;\n let wavelength = max(w.y, 1e-4);\n let dirRad = w.z * PI / 180.0;\n let phase = w.w;\n let k = TAU / wavelength;\n let d = vec2<f32>(cos(dirRad), sin(dirRad));\n let omega = sqrt(FLOW_GRAVITY * k) * windSpeed;\n let theta = k * (d.x * p.x + d.y * p.y) - omega * t + phase;\n let akc = amplitude * k * cos(theta);\n dhdx = dhdx + akc * d.x;\n dhdy = dhdy + akc * d.y;\n }\n // v = \u2207\u22A5h = (\u2202h/\u2202y, \u2212\u2202h/\u2202x).\n return vec2<f32>(dhdy, -dhdx);\n}\n\n// \u2500\u2500 The scalar Gerstner HEIGHT (transcribes flowField.ts sampleHeight \u2014 the brightness\n// driver, normalized to \u2248[-1,1] by the total amplitude so the band thresholds are\n// wave-table-independent). \u2500\u2500\nfn sampleHeight(o: vec2<f32>, t: f32) -> f32 {\n var h = 0.0;\n var ampSum = 0.0;\n let windSpeed = u.p0.z;\n let waveCount = u.ints.x;\n for (var i = 0; i < MAX_WAVE_COMPONENTS; i = i + 1) {\n if (i >= waveCount) { break; }\n let w = u.waves[i];\n let k = TAU / max(w.y, 1e-4);\n let dirRad = w.z * PI / 180.0;\n let d = vec2<f32>(cos(dirRad), sin(dirRad));\n let omega = sqrt(FLOW_GRAVITY * k) * windSpeed;\n let theta = k * (d.x * o.x + d.y * o.y) - omega * t + w.w;\n h = h + w.x * sin(theta);\n ampSum = ampSum + abs(w.x);\n }\n return h / max(ampSum, 1e-4);\n}\n\n// \u2500\u2500 Shared curl-noise basis (the WGSL twin of flow.glsl.ts curlFBM) \u2500\u2500\nfn hash21(p: vec2<f32>) -> f32 {\n var p3 = fract(vec3<f32>(p.x, p.y, p.x) * 0.1031);\n p3 = p3 + dot(p3, p3.yzx + 33.33);\n return fract((p3.x + p3.y) * p3.z);\n}\n\nfn valueNoise(p: vec2<f32>) -> f32 {\n let i = floor(p);\n let f = fract(p);\n let u2 = f * f * f * (f * (f * 6.0 - 15.0) + 10.0);\n let a = hash21(i + vec2<f32>(0.0, 0.0));\n let b = hash21(i + vec2<f32>(1.0, 0.0));\n let c = hash21(i + vec2<f32>(0.0, 1.0));\n let d = hash21(i + vec2<f32>(1.0, 1.0));\n return mix(mix(a, b, u2.x), mix(c, d, u2.x), u2.y);\n}\n\nfn potentialFBM(p0: vec2<f32>) -> f32 {\n var v = 0.0;\n var amp = 0.5;\n var freq = 1.0;\n var p = p0;\n for (var i = 0; i < 3; i = i + 1) {\n v = v + amp * valueNoise(p * freq);\n p = FBM_ROT * p;\n freq = freq * 2.0;\n amp = amp * 0.5;\n }\n return v;\n}\n\nfn curlFBM(p: vec2<f32>) -> vec2<f32> {\n let dx = potentialFBM(p + vec2<f32>(CURL_EPS, 0.0)) - potentialFBM(p - vec2<f32>(CURL_EPS, 0.0));\n let dy = potentialFBM(p + vec2<f32>(0.0, CURL_EPS)) - potentialFBM(p - vec2<f32>(0.0, CURL_EPS));\n let g = vec2<f32>(dx, dy) / (2.0 * CURL_EPS);\n return vec2<f32>(g.y, -g.x);\n}\n\n// The composite flow velocity (transcribes flowField.ts sampleVelocity EXACTLY \u2014 the\n// coarse \u00D70.55 curl domain-scale, the \u00A73.2 inversion).\nfn sampleVelocity(p: vec2<f32>, t: f32) -> vec2<f32> {\n let curlStrength = u.p0.w;\n var v = gerstnerVelocity(p, t);\n if (curlStrength > 0.0) {\n let c = curlFBM(vec2<f32>(p.x * 0.55 + t * 0.15, p.y * 0.55));\n v = v + c * curlStrength;\n }\n return v;\n}\n\n// The sub-cell DISPLACEMENT (transcribes flowField.ts sampleDisplacement \u2014 \u2207\u22A5h + the\n// coarse curl break, soft-clamped through tanh so the magnitude rides into [0,1)).\nfn sampleDisplacement(o: vec2<f32>, t: f32) -> vec2<f32> {\n let v = sampleVelocity(o, t);\n let mag = length(v);\n if (mag < 1e-5) { return vec2<f32>(0.0, 0.0); }\n let bounded = tanh(mag);\n return v * (bounded / mag);\n}\n\n// \u2500\u2500 The cursor VORTEX injected into the velocity field (transcribes flowField.ts\n// pointerVortex). r = p \u2212 cursor; a gaussian fall-off; a TRUE tangential \u2207\u22A5 swirl +\n// a drag-along term + a radial burst shove. Inert when the pointer is inactive. \u2500\u2500\nfn pointerVortex(p: vec2<f32>) -> vec2<f32> {\n if (u.ptr2.y < 0.5) { return vec2<f32>(0.0, 0.0); } // pointer inactive \u2192 no vortex\n let cursor = u.ptr.xy;\n let vel = u.ptr.zw;\n let burst = u.ptr2.x;\n let radius = max(u.f1.x, 1e-3);\n let r = p - cursor;\n let d = length(r);\n let fall = exp(-(d * d) / (radius * radius));\n let swirl = normalize(vec2<f32>(-r.y, r.x) + vec2<f32>(1e-6, 0.0)); // tangential \u2207\u22A5\n let radial = r / max(d, 1e-4);\n let v = swirl * u.f1.y // the spin\n + vel * u.f1.z // the drag (streamlines follow the gesture)\n + radial * burst * u.f1.w; // the flick shockwave\n return v * fall;\n}\n\n// \u2500\u2500 density-weighted respawn: a hash-stratified seed inside the domain, biased toward the\n// edges by edgeBias (a faint vignette \u2014 the field never thins to a hole). \u2500\u2500\nfn respawn(idx: u32, t: f32) -> vec2<f32> {\n let half = u.f0.w;\n let s = f32(idx) * 0.013 + t * 0.37;\n let rx = hash21(vec2<f32>(s, 1.7)) * 2.0 - 1.0;\n let ry = hash21(vec2<f32>(3.1, s)) * 2.0 - 1.0;\n // edgeBias>0 pushes the seed toward the perimeter (a power-curve on |coord|).\n let bias = clamp(u.ptr2.z, 0.0, 1.0);\n let bx = sign(rx) * pow(abs(rx), mix(1.0, 0.5, bias));\n let by = sign(ry) * pow(abs(ry), mix(1.0, 0.5, bias));\n return vec2<f32>(bx, by) * half;\n}\n\n// \u2500\u2500 cs_field \u2014 the ANCHORED-LATTICE evaluator (BYTE-MOVED from cs_main; the field-mode\n// fence-scoped unit; F1 greps the no-advection/no-reseed witness WITHIN this brace-span).\nfn cs_field(idx: u32, t: f32, dt: f32) {\n let pitch = u.p1.x;\n let displaceAmp = u.p1.y;\n let springK = u.p1.z;\n let cols = u.ints.z;\n\n // The PERMANENT anchor \u2014 no wrap, no re-seed (the coherence fix).\n let o = gridOrigin(idx, cols, pitch);\n let disp = sampleDisplacement(o, t);\n let anchorTarget = o + disp * (displaceAmp * pitch);\n\n var pr = particles[idx];\n var pos = pr.data.xy;\n // Framerate-independent critically-damped pull-to-anchor:\n // p \u2190 mix(p, anchorTarget, 1 - exp(-springK\u00B7dt)) (the GPGPU influence-pull pattern).\n let k = 1.0 - exp(-springK * dt);\n pos = mix(pos, anchorTarget, k);\n\n let h = sampleHeight(o, t);\n particles[idx] = Particle(vec4<f32>(pos, h, length(disp)));\n}\n\n// \u2500\u2500 cs_flow \u2014 the AURORA CURRENT (the RE-INVENT register). Momentum-integrated advection\n// along the curl current + the live cursor vortex, with lifetime decay + density-weighted\n// respawn. F1b greps the pos+=v*dt + respawn( + pointerVortex( witness in THIS function.\nfn cs_flow(idx: u32, t: f32, dt: f32) {\n let half = u.f0.w;\n let turnRate = u.f0.x;\n let speedScale = u.f0.y;\n let lifetimeSec = max(u.f0.z, 1e-3);\n\n var pr = particles[idx];\n var pos = pr.data.xy;\n var life = pr.data.w;\n\n // First-frame / dead / out-of-domain seed (the density-weighted respawn).\n let outOfDomain = max(abs(pos.x), abs(pos.y)) > half * 1.05;\n if (life <= 0.0 || outOfDomain) {\n pos = respawn(idx, t);\n // stratify the initial life across [0,lifetime] so deaths don't synchronize.\n life = lifetimeSec * hash21(vec2<f32>(f32(idx) * 0.027, t * 0.11));\n }\n\n // The target velocity: the divergence-free curl current + the cursor vortex.\n let vField = sampleVelocity(pos, t) + pointerVortex(pos);\n // Momentum/inertia: the low turnRate scales how hard the mote commits to the field\n // each step \u2014 a weighty ease into the current's turns (arcs, not snaps), the\n // overlapping-action/follow-through on a particle (R4-motion).\n let v = vField * turnRate * speedScale;\n // Forward-Euler advection step (the integrator \u2014 F1b's witness pos = pos + v*dt).\n pos = pos + v * dt * 60.0;\n\n life = life - dt;\n let speed = length(v);\n particles[idx] = Particle(vec4<f32>(pos, speed, life));\n}\n\n@compute @workgroup_size(64)\nfn cs_main(@builtin(global_invocation_id) gid: vec3<u32>) {\n let idx = gid.x;\n let count = u32(u.ints.y);\n if (idx >= count) { return; } // bounds-guard the dispatch tail\n\n let t = u.p0.x;\n let dt = u.p0.y;\n let mode = u.ints.w;\n\n if (mode == 1) {\n cs_flow(idx, t, dt);\n } else {\n cs_field(idx, t, dt);\n }\n}\n";
|
|
@@ -1,20 +1,33 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
export
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
seed: number;
|
|
8
|
-
}
|
|
1
|
+
/** The full-screen-triangle vertex shader (the substrate's standard fullscreen pass). */
|
|
2
|
+
export declare const FLOW_FIELD_VERT_GLSL = "#version 300 es\nprecision highp float;\nin vec2 aPosition;\nout vec2 vUv;\nvoid main() {\n vUv = aPosition; // [-1,1]\u00B2 domain\n gl_Position = vec4(aPosition, 0.0, 1.0);\n}";
|
|
3
|
+
/** The dot-lattice + sweeping-brightness fragment source (the anchored-grid model). */
|
|
4
|
+
export declare const FLOW_FIELD_FRAG_GLSL = "#version 300 es\nprecision highp float;\n\n#define PI 3.141592653589793\n#define TAU 6.283185307179586\n#define FLOW_GRAVITY 9.81\n#define CURL_EPS 0.012\n#define MAX_WAVE_COMPONENTS 8\n#define MAX_FLOW_STOPS 4\n\nin vec2 vUv;\nout vec4 fragColor;\n\nuniform float uTime;\nuniform float uWindSpeed;\nuniform float uCurlStrength;\nuniform float uDomainHalf;\nuniform float uAspect;\nuniform float uGridPitchDomain; // lattice pitch in DOMAIN units\nuniform float uDotRadiusDomain; // dot radius in DOMAIN units\nuniform float uDisplaceAmp; // sub-cell drift in pitch fractions\nuniform float uContrast;\nuniform float uBaseBright;\nuniform float uWaveBandCenter;\nuniform float uWaveBandWidth;\nuniform float uGlobeMask;\nuniform int uWaveCount;\nuniform int uStopCount;\nuniform float uHasBackground;\nuniform vec3 uBg;\nuniform vec4 uWaves[MAX_WAVE_COMPONENTS]; // (amplitude, wavelength, directionDeg, phase)\nuniform vec3 uPalette[MAX_FLOW_STOPS]; // linear-sRGB stops\n\nconst mat2 FBM_ROT = mat2(0.8, 0.6, -0.6, 0.8);\n\n\nfloat srgbToLinearCh(float c) {\n return c <= 0.04045 ? c / 12.92 : pow((c + 0.055) / 1.055, 2.4);\n}\nvec3 srgbToLinear(vec3 c) {\n return vec3(srgbToLinearCh(c.r), srgbToLinearCh(c.g), srgbToLinearCh(c.b));\n}\n\nfloat linearToSrgbCh(float c) {\n return c <= 0.0031308 ? c * 12.92 : 1.055 * pow(c, 1.0 / 2.4) - 0.055;\n}\nvec3 linearToSrgb(vec3 c) {\n return vec3(linearToSrgbCh(c.r), linearToSrgbCh(c.g), linearToSrgbCh(c.b));\n}\n\n// value.js LINEAR_SRGB_TO_LMS (constants.ts), row-major; written here as GLSL\n// columns (= the transpose) so mat3 * vec3 evaluates the row-major M\u00B7v.\nconst mat3 LINEAR_SRGB_TO_LMS = mat3(\n 0.4122214708, 0.2119034982, 0.0883024619,\n 0.5363325363, 0.6806995451, 0.2817188376,\n 0.0514459929, 0.1073969566, 0.6299787005\n);\n\n// value.js srgbToOKLab's INLINE LMS\u2192OKLab coefficients (gamut.ts lines 295-297 \u2014\n// these differ at the ~1e-9 digit from LMS_TO_OKLAB_MATRIX; use the inline ones to\n// mirror the exact value.js path), row-major \u2192 GLSL columns.\nconst mat3 LMS_TO_OKLAB = mat3(\n 0.2104542553, 1.9779984951, 0.0259040371,\n 0.7936177850, -2.4285922050, 0.7827717662,\n -0.0040720468, 0.4505937099, -0.8086757660\n);\n\n// value.js OKLAB_TO_LMS_COEFF (constants.ts), row-major \u2192 GLSL columns. Rows:\n// l = [1, 0.3963377774, 0.2158037573], m = [1, -0.1055613458, -0.0638541728],\n// s = [1, -0.0894841775, -1.2914855480].\nconst mat3 OKLAB_TO_LMS = mat3(\n 1.0, 1.0, 1.0,\n 0.3963377774, -0.1055613458, -0.0894841775,\n 0.2158037573, -0.0638541728, -1.2914855480\n);\n\n// value.js LMS_TO_LINEAR_SRGB (constants.ts), row-major \u2192 GLSL columns.\nconst mat3 LMS_TO_LINEAR_SRGB = mat3(\n 4.0767416621, -1.2684380046, -0.0041960863,\n -3.3077115913, 2.6097574011, -0.7034186147,\n 0.2309699292, -0.3413193965, 1.7076147010\n);\n\n// Gamma sRGB \u2192 raw OKLab (L, a, b). Mirrors value.js srgbToOKLab.\nvec3 srgbToOklab(vec3 c) {\n vec3 lin = srgbToLinear(c);\n vec3 lms = LINEAR_SRGB_TO_LMS * lin;\n vec3 lmsCbrt = sign(lms) * pow(abs(lms), vec3(1.0 / 3.0));\n return LMS_TO_OKLAB * lmsCbrt;\n}\n\n// Raw OKLab (L, a, b) \u2192 linear sRGB. Mirrors value.js oklabToLinearSRGB.\nvec3 oklabToLinearSrgb(vec3 lab) {\n vec3 lms_ = OKLAB_TO_LMS * lab;\n vec3 lms = lms_ * lms_ * lms_;\n return LMS_TO_LINEAR_SRGB * lms;\n}\n\n// OKLab \u2192 OKLCh: H in RADIANS. Mirrors value.js rawOklabToOklch (which returns\n// degrees; we stay in radians and only fold to [0, 2pi)).\nvec3 oklabToOklch(vec3 lab) {\n float C = length(lab.yz);\n float H = atan(lab.z, lab.y);\n if (H < 0.0) H += 2.0 * PI;\n return vec3(lab.x, C, H);\n}\n\n// OKLCh (H radians) \u2192 OKLab. Mirrors value.js rawOklchToOklab.\nvec3 oklchToOklab(vec3 lch) {\n return vec3(lch.x, lch.y * cos(lch.z), lch.y * sin(lch.z));\n}\n\n// \u2500\u2500 The Gerstner-sum analytic \u2207\u22A5h velocity (transcribes flowField.ts gerstnerVelocity) \u2500\u2500\nvec2 gerstnerVelocity(vec2 p, float t) {\n float dhdx = 0.0;\n float dhdy = 0.0;\n for (int i = 0; i < MAX_WAVE_COMPONENTS; i++) {\n if (i >= uWaveCount) break;\n vec4 w = uWaves[i];\n float k = TAU / max(w.y, 1e-4);\n float dirRad = w.z * PI / 180.0;\n vec2 d = vec2(cos(dirRad), sin(dirRad));\n float omega = sqrt(FLOW_GRAVITY * k) * uWindSpeed;\n float theta = k * (d.x * p.x + d.y * p.y) - omega * t + w.w;\n float akc = w.x * k * cos(theta);\n dhdx += akc * d.x;\n dhdy += akc * d.y;\n }\n return vec2(dhdy, -dhdx);\n}\n\n// \u2500\u2500 The scalar Gerstner HEIGHT (transcribes flowField.ts sampleHeight) \u2500\u2500\nfloat sampleHeight(vec2 o, float t) {\n float h = 0.0;\n float ampSum = 0.0;\n for (int i = 0; i < MAX_WAVE_COMPONENTS; i++) {\n if (i >= uWaveCount) break;\n vec4 w = uWaves[i];\n float k = TAU / max(w.y, 1e-4);\n float dirRad = w.z * PI / 180.0;\n vec2 d = vec2(cos(dirRad), sin(dirRad));\n float omega = sqrt(FLOW_GRAVITY * k) * uWindSpeed;\n float theta = k * (d.x * o.x + d.y * o.y) - omega * t + w.w;\n h += w.x * sin(theta);\n ampSum += abs(w.x);\n }\n return h / max(ampSum, 1e-4);\n}\n\n// \u2500\u2500 Shared curl-noise basis (the GLSL twin of flow.glsl.ts curlFBM) \u2500\u2500\nfloat hash21(vec2 p) {\n vec3 p3 = fract(vec3(p.x, p.y, p.x) * 0.1031);\n p3 += dot(p3, p3.yzx + 33.33);\n return fract((p3.x + p3.y) * p3.z);\n}\nfloat valueNoise(vec2 p) {\n vec2 i = floor(p);\n vec2 f = fract(p);\n vec2 u2 = f * f * f * (f * (f * 6.0 - 15.0) + 10.0);\n float a = hash21(i + vec2(0.0, 0.0));\n float b = hash21(i + vec2(1.0, 0.0));\n float c = hash21(i + vec2(0.0, 1.0));\n float d = hash21(i + vec2(1.0, 1.0));\n return mix(mix(a, b, u2.x), mix(c, d, u2.x), u2.y);\n}\nfloat potentialFBM(vec2 p0) {\n float v = 0.0;\n float amp = 0.5;\n float freq = 1.0;\n vec2 p = p0;\n for (int i = 0; i < 3; i++) {\n v += amp * valueNoise(p * freq);\n p = FBM_ROT * p;\n freq *= 2.0;\n amp *= 0.5;\n }\n return v;\n}\nvec2 curlFBM(vec2 p) {\n float dx = potentialFBM(p + vec2(CURL_EPS, 0.0)) - potentialFBM(p - vec2(CURL_EPS, 0.0));\n float dy = potentialFBM(p + vec2(0.0, CURL_EPS)) - potentialFBM(p - vec2(0.0, CURL_EPS));\n vec2 g = vec2(dx, dy) / (2.0 * CURL_EPS);\n return vec2(g.y, -g.x);\n}\nvec2 sampleVelocity(vec2 p, float t) {\n vec2 v = gerstnerVelocity(p, t);\n if (uCurlStrength > 0.0) {\n vec2 c = curlFBM(vec2(p.x * 0.55 + t * 0.15, p.y * 0.55));\n v += c * uCurlStrength;\n }\n return v;\n}\n// sub-cell displacement (transcribes flowField.ts sampleDisplacement \u2014 tanh soft-clamp).\nvec2 sampleDisplacement(vec2 o, float t) {\n vec2 v = sampleVelocity(o, t);\n float mag = length(v);\n if (mag < 1e-5) return vec2(0.0);\n return v * (tanh(mag) / mag);\n}\n\n// The sweeping bright-stripe band (transcribes flowField.ts waveBand).\nfloat waveBand(float h, float center, float width) {\n float w = max(width, 1e-3);\n float d = abs(h - center);\n return 1.0 - smoothstep(0.0, w, d);\n}\n\n// The optional soft-disc globe mask (the reference's two-sphere composition).\nfloat globeMask(vec2 o, float t, float on) {\n if (on <= 0.5) return 1.0;\n float cx = 0.35 * sin(t * 0.13);\n float cy = 0.28 * cos(t * 0.11);\n float d = length(o - vec2(cx, cy));\n return 1.0 - smoothstep(0.45, 0.75, d);\n}\n\nvec3 samplePaletteLin(float t) {\n if (uStopCount <= 1) return uPalette[0];\n float n = float(uStopCount);\n float ft = clamp(t, 0.0, 1.0) * (n - 1.0);\n int i0 = int(floor(ft));\n int i1 = min(i0 + 1, uStopCount - 1);\n float f = ft - float(i0);\n vec3 lmsA = LINEAR_SRGB_TO_LMS * uPalette[i0];\n vec3 lmsB = LINEAR_SRGB_TO_LMS * uPalette[i1];\n vec3 labA = LMS_TO_OKLAB * (sign(lmsA) * pow(abs(lmsA), vec3(1.0 / 3.0)));\n vec3 labB = LMS_TO_OKLAB * (sign(lmsB) * pow(abs(lmsB), vec3(1.0 / 3.0)));\n return oklabToLinearSrgb(mix(labA, labB, f));\n}\n\nvoid main() {\n float aspect = max(uAspect, 1e-4);\n // Domain-space pixel (aspect-corrected x so the lattice stays square).\n vec2 p = vec2(vUv.x * aspect, vUv.y);\n float pitch = max(uGridPitchDomain, 1e-3);\n\n // The nearest lattice cell ORIGIN (the anchored grid \u2014 the deterministic gridOrigin\n // mapping, evaluated per-pixel: round p/pitch to the nearest cell center).\n vec2 cell = floor(p / pitch + 0.5);\n vec2 o = cell * pitch;\n\n // The dot DRIFTS toward o + disp\u00B7displaceAmp\u00B7pitch (the same sub-cell offset the\n // compute kernel writes \u2014 here evaluated analytically per pixel).\n vec2 disp = sampleDisplacement(o, uTime);\n vec2 dotCenter = o + disp * (uDisplaceAmp * pitch);\n\n // The soft circle around the (drifted) dot center.\n float dist = length(p - dotCenter);\n float radius = max(uDotRadiusDomain, 1e-4);\n float mask = 1.0 - smoothstep(radius * 0.6, radius, dist);\n if (mask < 0.002) {\n if (uHasBackground > 0.5) {\n fragColor = vec4(clamp(linearToSrgb(uBg), vec3(0.0), vec3(1.0)), 1.0);\n } else {\n fragColor = vec4(0.0);\n }\n return;\n }\n\n // The brightness lights the dot \u2014 the SWEEPING band over the height at the anchor.\n float h = sampleHeight(o, uTime);\n float band = waveBand(h, uWaveBandCenter, uWaveBandWidth);\n float bright = (uBaseBright + band * uContrast) * globeMask(o, uTime, uGlobeMask);\n bright = clamp(bright, 0.0, 1.6);\n\n float tone = clamp(bright, 0.0, 1.0);\n vec3 lin = samplePaletteLin(tone) * bright;\n vec3 rgb = clamp(linearToSrgb(lin), vec3(0.0), vec3(1.0));\n float alpha = mask * clamp(bright * 0.8 + 0.12, 0.0, 1.0);\n\n if (uHasBackground > 0.5) {\n vec3 bg = clamp(linearToSrgb(uBg), vec3(0.0), vec3(1.0));\n fragColor = vec4(mix(bg, rgb, alpha), 1.0);\n return;\n }\n fragColor = vec4(rgb * alpha, alpha);\n}";
|
|
5
|
+
/** The fullscreen-quad vertex pass for the GPGPU/trail passes (a [-1,1] clip quad). */
|
|
6
|
+
export declare const FLOW_FIELD_QUAD_VERT_GLSL = "#version 300 es\nprecision highp float;\nin vec2 aPosition;\nout vec2 vUv;\nvoid main() {\n vUv = aPosition * 0.5 + 0.5; // [0,1] texel space\n gl_Position = vec4(aPosition, 0.0, 1.0);\n}";
|
|
9
7
|
/**
|
|
10
|
-
* The
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
8
|
+
* The STATE-TEXTURE GPGPU advect pass (proof:dotflow-fence F4 — the GPGPU export replacing
|
|
9
|
+
* the FLOW_FIELD_FRAG_GLSL mandate). One texel per mote, RGBA = (pos.x, pos.y, speed, life).
|
|
10
|
+
* Each frame: read prev state, advect along the curl current + the cursor VORTEX with
|
|
11
|
+
* momentum (turnRate), decrement life, density-weighted respawn on death/out-of-domain.
|
|
12
|
+
* The math twin of cs_flow (WGSL) — F3 round-trips the SAME sampleVelocity.
|
|
15
13
|
*/
|
|
16
|
-
export declare
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
14
|
+
export declare const FLOW_FIELD_STATE_GLSL = "#version 300 es\nprecision highp float;\nin vec2 vUv;\nout vec4 fragColor;\n\nuniform sampler2D uState; // prev particle state (RGBA = pos.xy, speed, life)\nuniform float uDt;\nuniform float uDomainHalf;\nuniform float uTurnRate;\nuniform float uSpeedScale;\nuniform float uLifetimeSec;\nuniform float uEdgeBias;\nuniform vec2 uCursor; // pointer in domain space\nuniform vec2 uPointerVel; // pointer velocity (domain/s)\nuniform float uBurst; // flick-burst impulse\nuniform float uPointerActive; // 0/1\nuniform float uVortexRadius;\nuniform float uVortexSpin;\nuniform float uDragGain;\nuniform float uBurstShove;\n\n\n#define PI 3.141592653589793\n#define TAU 6.283185307179586\n#define FLOW_GRAVITY 9.81\n#define CURL_EPS 0.012\n#define MAX_WAVE_COMPONENTS 8\nconst mat2 FBM_ROT = mat2(0.8, 0.6, -0.6, 0.8);\n\nuniform float uTime;\nuniform float uWindSpeed;\nuniform float uCurlStrength;\nuniform int uWaveCount;\nuniform vec4 uWaves[MAX_WAVE_COMPONENTS]; // (amplitude, wavelength, directionDeg, phase)\n\nvec2 gerstnerVelocity(vec2 p, float t) {\n float dhdx = 0.0; float dhdy = 0.0;\n for (int i = 0; i < MAX_WAVE_COMPONENTS; i++) {\n if (i >= uWaveCount) break;\n vec4 w = uWaves[i];\n float k = TAU / max(w.y, 1e-4);\n float dirRad = w.z * PI / 180.0;\n vec2 d = vec2(cos(dirRad), sin(dirRad));\n float omega = sqrt(FLOW_GRAVITY * k) * uWindSpeed;\n float theta = k * (d.x * p.x + d.y * p.y) - omega * t + w.w;\n float akc = w.x * k * cos(theta);\n dhdx += akc * d.x; dhdy += akc * d.y;\n }\n return vec2(dhdy, -dhdx);\n}\nfloat hash21f(vec2 p) {\n vec3 p3 = fract(vec3(p.x, p.y, p.x) * 0.1031);\n p3 += dot(p3, p3.yzx + 33.33);\n return fract((p3.x + p3.y) * p3.z);\n}\nfloat valueNoiseF(vec2 p) {\n vec2 i = floor(p); vec2 f = fract(p);\n vec2 u2 = f * f * f * (f * (f * 6.0 - 15.0) + 10.0);\n float a = hash21f(i + vec2(0.0, 0.0));\n float b = hash21f(i + vec2(1.0, 0.0));\n float c = hash21f(i + vec2(0.0, 1.0));\n float d = hash21f(i + vec2(1.0, 1.0));\n return mix(mix(a, b, u2.x), mix(c, d, u2.x), u2.y);\n}\nfloat potentialFBMf(vec2 p0) {\n float v = 0.0; float amp = 0.5; float freq = 1.0; vec2 p = p0;\n for (int i = 0; i < 3; i++) { v += amp * valueNoiseF(p * freq); p = FBM_ROT * p; freq *= 2.0; amp *= 0.5; }\n return v;\n}\nvec2 curlFBMf(vec2 p) {\n float dx = potentialFBMf(p + vec2(CURL_EPS, 0.0)) - potentialFBMf(p - vec2(CURL_EPS, 0.0));\n float dy = potentialFBMf(p + vec2(0.0, CURL_EPS)) - potentialFBMf(p - vec2(0.0, CURL_EPS));\n vec2 g = vec2(dx, dy) / (2.0 * CURL_EPS);\n return vec2(g.y, -g.x);\n}\nvec2 sampleVelocityF(vec2 p, float t) {\n vec2 v = gerstnerVelocity(p, t);\n if (uCurlStrength > 0.0) { v += curlFBMf(vec2(p.x * 0.55 + t * 0.15, p.y * 0.55)) * uCurlStrength; }\n return v;\n}\n\n\nvec2 pointerVortex(vec2 p) {\n if (uPointerActive < 0.5) return vec2(0.0);\n vec2 r = p - uCursor;\n float d = length(r);\n float radius = max(uVortexRadius, 1e-3);\n float fall = exp(-(d * d) / (radius * radius));\n vec2 swirl = normalize(vec2(-r.y, r.x) + vec2(1e-6, 0.0));\n vec2 radial = r / max(d, 1e-4);\n vec2 v = swirl * uVortexSpin + uPointerVel * uDragGain + radial * uBurst * uBurstShove;\n return v * fall;\n}\n\nvec2 respawn(vec2 seed, float t) {\n float rx = hash21f(seed + vec2(t * 0.37, 1.7)) * 2.0 - 1.0;\n float ry = hash21f(seed.yx + vec2(3.1, t * 0.37)) * 2.0 - 1.0;\n float bias = clamp(uEdgeBias, 0.0, 1.0);\n float bx = sign(rx) * pow(abs(rx), mix(1.0, 0.5, bias));\n float by = sign(ry) * pow(abs(ry), mix(1.0, 0.5, bias));\n return vec2(bx, by) * uDomainHalf;\n}\n\nvoid main() {\n vec4 st = texture(uState, vUv);\n vec2 pos = st.xy;\n float life = st.w;\n float half = uDomainHalf;\n\n bool dead = life <= 0.0;\n bool outOfDomain = max(abs(pos.x), abs(pos.y)) > half * 1.05;\n if (dead || outOfDomain) {\n pos = respawn(vUv, uTime);\n life = max(uLifetimeSec, 1e-3) * hash21f(vUv * 7.0 + uTime * 0.11);\n }\n\n vec2 vField = sampleVelocityF(pos, uTime) + pointerVortex(pos);\n // momentum: low turnRate = weighty arcs (eases into the current's turns).\n vec2 v = vField * uTurnRate * uSpeedScale;\n // forward-Euler advection (pos = pos + v*dt \u2014 the integrand twin of cs_flow).\n pos = pos + v * uDt * 60.0;\n life = life - uDt;\n\n fragColor = vec4(pos, length(v), life);\n}";
|
|
15
|
+
/**
|
|
16
|
+
* The MOTE point-sprite pass — reads the advected state texture by gl_VertexID, places a
|
|
17
|
+
* point sprite at the mote, sizes/brightens/hues it by SPEED·life (the velocity-map). Drawn
|
|
18
|
+
* additively into the trail FBO. The warm-fire palette is spliced via the shared color seam.
|
|
19
|
+
*/
|
|
20
|
+
export declare const FLOW_FIELD_POINT_VERT_GLSL = "#version 300 es\nprecision highp float;\nuniform sampler2D uState;\nuniform int uStateCols;\nuniform float uDomainHalf;\nuniform float uPointSize;\nuniform float uSpeedNorm; // the speed\u2192[0,1] normalizer (modal-speed at ramp middle)\nuniform float uStretchAmp;\nout float vSpeedNorm;\nout float vFade;\nvoid main() {\n int id = gl_VertexID;\n int col = id % uStateCols;\n int row = id / uStateCols;\n vec2 uv = (vec2(float(col), float(row)) + 0.5) / float(uStateCols);\n vec4 st = texture(uState, uv);\n vec2 pos = st.xy;\n float speed = st.z;\n float life = st.w;\n float sn = clamp(speed / max(uSpeedNorm, 1e-4), 0.0, 1.0);\n vSpeedNorm = sn;\n vFade = clamp(life * 3.0, 0.0, 1.0);\n // NDC: domain [-half,half] \u2192 [-1,1].\n gl_Position = vec4(pos / uDomainHalf, 0.0, 1.0);\n // faster motes read as larger hot speed-cores (the cartoon \"more\" as point size).\n gl_PointSize = max(uPointSize * (1.0 + sn * (uStretchAmp + 1.0)), 1.0);\n}";
|
|
21
|
+
export declare const FLOW_FIELD_POINT_FRAG_GLSL = "#version 300 es\nprecision highp float;\n#define MAX_FLOW_STOPS 4\nin float vSpeedNorm;\nin float vFade;\nout vec4 fragColor;\nuniform int uStopCount;\nuniform vec3 uPalette[MAX_FLOW_STOPS];\nuniform float uSpeedGlow;\n\n\nfloat srgbToLinearCh(float c) {\n return c <= 0.04045 ? c / 12.92 : pow((c + 0.055) / 1.055, 2.4);\n}\nvec3 srgbToLinear(vec3 c) {\n return vec3(srgbToLinearCh(c.r), srgbToLinearCh(c.g), srgbToLinearCh(c.b));\n}\n\nfloat linearToSrgbCh(float c) {\n return c <= 0.0031308 ? c * 12.92 : 1.055 * pow(c, 1.0 / 2.4) - 0.055;\n}\nvec3 linearToSrgb(vec3 c) {\n return vec3(linearToSrgbCh(c.r), linearToSrgbCh(c.g), linearToSrgbCh(c.b));\n}\n\n// value.js LINEAR_SRGB_TO_LMS (constants.ts), row-major; written here as GLSL\n// columns (= the transpose) so mat3 * vec3 evaluates the row-major M\u00B7v.\nconst mat3 LINEAR_SRGB_TO_LMS = mat3(\n 0.4122214708, 0.2119034982, 0.0883024619,\n 0.5363325363, 0.6806995451, 0.2817188376,\n 0.0514459929, 0.1073969566, 0.6299787005\n);\n\n// value.js srgbToOKLab's INLINE LMS\u2192OKLab coefficients (gamut.ts lines 295-297 \u2014\n// these differ at the ~1e-9 digit from LMS_TO_OKLAB_MATRIX; use the inline ones to\n// mirror the exact value.js path), row-major \u2192 GLSL columns.\nconst mat3 LMS_TO_OKLAB = mat3(\n 0.2104542553, 1.9779984951, 0.0259040371,\n 0.7936177850, -2.4285922050, 0.7827717662,\n -0.0040720468, 0.4505937099, -0.8086757660\n);\n\n// value.js OKLAB_TO_LMS_COEFF (constants.ts), row-major \u2192 GLSL columns. Rows:\n// l = [1, 0.3963377774, 0.2158037573], m = [1, -0.1055613458, -0.0638541728],\n// s = [1, -0.0894841775, -1.2914855480].\nconst mat3 OKLAB_TO_LMS = mat3(\n 1.0, 1.0, 1.0,\n 0.3963377774, -0.1055613458, -0.0894841775,\n 0.2158037573, -0.0638541728, -1.2914855480\n);\n\n// value.js LMS_TO_LINEAR_SRGB (constants.ts), row-major \u2192 GLSL columns.\nconst mat3 LMS_TO_LINEAR_SRGB = mat3(\n 4.0767416621, -1.2684380046, -0.0041960863,\n -3.3077115913, 2.6097574011, -0.7034186147,\n 0.2309699292, -0.3413193965, 1.7076147010\n);\n\n// Gamma sRGB \u2192 raw OKLab (L, a, b). Mirrors value.js srgbToOKLab.\nvec3 srgbToOklab(vec3 c) {\n vec3 lin = srgbToLinear(c);\n vec3 lms = LINEAR_SRGB_TO_LMS * lin;\n vec3 lmsCbrt = sign(lms) * pow(abs(lms), vec3(1.0 / 3.0));\n return LMS_TO_OKLAB * lmsCbrt;\n}\n\n// Raw OKLab (L, a, b) \u2192 linear sRGB. Mirrors value.js oklabToLinearSRGB.\nvec3 oklabToLinearSrgb(vec3 lab) {\n vec3 lms_ = OKLAB_TO_LMS * lab;\n vec3 lms = lms_ * lms_ * lms_;\n return LMS_TO_LINEAR_SRGB * lms;\n}\n\n// OKLab \u2192 OKLCh: H in RADIANS. Mirrors value.js rawOklabToOklch (which returns\n// degrees; we stay in radians and only fold to [0, 2pi)).\nvec3 oklabToOklch(vec3 lab) {\n float C = length(lab.yz);\n float H = atan(lab.z, lab.y);\n if (H < 0.0) H += 2.0 * PI;\n return vec3(lab.x, C, H);\n}\n\n// OKLCh (H radians) \u2192 OKLab. Mirrors value.js rawOklchToOklab.\nvec3 oklchToOklab(vec3 lch) {\n return vec3(lch.x, lch.y * cos(lch.z), lch.y * sin(lch.z));\n}\n\nvec3 samplePaletteLin(float t) {\n if (uStopCount <= 1) return uPalette[0];\n float n = float(uStopCount);\n float ft = clamp(t, 0.0, 1.0) * (n - 1.0);\n int i0 = int(floor(ft));\n int i1 = min(i0 + 1, uStopCount - 1);\n float f = ft - float(i0);\n vec3 lmsA = LINEAR_SRGB_TO_LMS * uPalette[i0];\n vec3 lmsB = LINEAR_SRGB_TO_LMS * uPalette[i1];\n vec3 labA = LMS_TO_OKLAB * (sign(lmsA) * pow(abs(lmsA), vec3(1.0 / 3.0)));\n vec3 labB = LMS_TO_OKLAB * (sign(lmsB) * pow(abs(lmsB), vec3(1.0 / 3.0)));\n return oklabToLinearSrgb(mix(labA, labB, f));\n}\n\nvoid main() {\n // soft round sprite \u2014 a tight hot core (mask\u00B2 caps the white wash, H2).\n vec2 pc = gl_PointCoord * 2.0 - 1.0;\n float r = length(pc);\n float mask = 1.0 - smoothstep(0.55, 1.0, r);\n if (mask < 0.002) discard;\n float core = mask * mask;\n float bright = (0.35 + vSpeedNorm * uSpeedGlow) * vFade;\n vec3 lin = samplePaletteLin(vSpeedNorm) * bright;\n vec3 rgb = clamp(linearToSrgb(lin), vec3(0.0), vec3(1.0));\n float a = core * clamp(bright, 0.0, 1.0);\n fragColor = vec4(rgb * a, a); // additive premultiplied (the trail braids the ribbons)\n}";
|
|
22
|
+
/**
|
|
23
|
+
* The TRAIL decay-blit — draws the PREVIOUS trail frame back at the derived decay α (toward
|
|
24
|
+
* the warm floor), so the motes drawn additively after it leave fading ribbons of light.
|
|
25
|
+
* The headline gestalt lever. Pinned NEAREST (no half-float-linear extension dependency).
|
|
26
|
+
*/
|
|
27
|
+
export declare const FLOW_FIELD_TRAIL_FRAG_GLSL = "#version 300 es\nprecision highp float;\nin vec2 vUv;\nout vec4 fragColor;\nuniform sampler2D uPrev;\nuniform float uDecay; // per-frame trail persistence (DERIVED from trailHalfLife)\nvoid main() {\n vec4 prev = texture(uPrev, vUv);\n fragColor = prev * uDecay; // fade toward black; the warm floor is the present-blit's\n}";
|
|
28
|
+
/**
|
|
29
|
+
* The PRESENT blit — composites the trail buffer over the warm-near-black floor + the
|
|
30
|
+
* colorful corner-bloom (the §3 colorful-field-behind-glass ground), tone-mapped so the hot
|
|
31
|
+
* cores read without a white wash. The full-bleed ground is HERE, not a parallel plane.
|
|
32
|
+
*/
|
|
33
|
+
export declare const FLOW_FIELD_PRESENT_FRAG_GLSL = "#version 300 es\nprecision highp float;\nin vec2 vUv;\nout vec4 fragColor;\nuniform sampler2D uTrail;\nuniform vec3 uFloor; // the deep warm-near-black floor (linear-sRGB)\nuniform vec3 uBloomColor; // the warm rose/magenta corner-bloom (linear-sRGB)\nuniform float uHasGround; // 0 \u2192 transparent (compose over the page field); 1 \u2192 opaque floor\n\n\nfloat srgbToLinearCh(float c) {\n return c <= 0.04045 ? c / 12.92 : pow((c + 0.055) / 1.055, 2.4);\n}\nvec3 srgbToLinear(vec3 c) {\n return vec3(srgbToLinearCh(c.r), srgbToLinearCh(c.g), srgbToLinearCh(c.b));\n}\n\nfloat linearToSrgbCh(float c) {\n return c <= 0.0031308 ? c * 12.92 : 1.055 * pow(c, 1.0 / 2.4) - 0.055;\n}\nvec3 linearToSrgb(vec3 c) {\n return vec3(linearToSrgbCh(c.r), linearToSrgbCh(c.g), linearToSrgbCh(c.b));\n}\n\nvoid main() {\n vec3 trail = texture(uTrail, vUv).rgb;\n // soft tone-map the accumulated additive trail (Reinhard \u2014 hot cores, not white wash).\n vec3 mapped = trail / (trail + vec3(0.85));\n if (uHasGround < 0.5) {\n // compose OVER the page's warm field: emit the lit ribbons premultiplied, no floor.\n vec3 rgb = clamp(linearToSrgb(mapped), vec3(0.0), vec3(1.0));\n float a = clamp(max(mapped.r, max(mapped.g, mapped.b)), 0.0, 1.0);\n fragColor = vec4(rgb * a, a);\n return;\n }\n // the corner-bloom: a faint warm rose radial in one corner (NOT teal).\n float bloom = smoothstep(1.3, 0.0, distance(vUv, vec2(0.12, 0.88)));\n vec3 floorLin = uFloor + uBloomColor * bloom * 0.5;\n vec3 lin = floorLin + mapped; // the ribbons sit OVER the warm floor\n vec3 rgb = clamp(linearToSrgb(lin), vec3(0.0), vec3(1.0));\n fragColor = vec4(rgb, 1.0);\n}";
|
|
@@ -1 +1,2 @@
|
|
|
1
|
-
export declare const FLOW_FIELD_RENDER_WGSL = "\nconst PI: f32 = 3.141592653589793;\nconst TAU: f32 = 6.283185307179586;\nconst
|
|
1
|
+
export declare const FLOW_FIELD_RENDER_WGSL = "\nconst PI: f32 = 3.141592653589793;\nconst TAU: f32 = 6.283185307179586;\nconst MAX_FLOW_STOPS: i32 = 4;\n\nstruct Particle {\n // field: (pos.x, pos.y, height, |disp|) flow: (pos.x, pos.y, speed, life)\n data: vec4<f32>,\n};\n\n// \u2500\u2500 Render uniforms (the typed-struct source-of-truth \u2014 see uniformBridgeWGPU.ts) \u2500\u2500\nstruct RenderUniforms {\n // r0: (uTime, uContrast, uBaseBright, uDomainHalf)\n r0: vec4<f32>,\n // r1: (uDotSize, uSizePulse, uAspect, uGridPitch)\n r1: vec4<f32>,\n // r2: (uWaveBandCenter, uWaveBandWidth, uGlobeMask, uMode) \u2014 uMode: 0=field, 1=flow\n r2: vec4<f32>,\n // ints: (uStopCount, uParticleCount, _pad, _pad)\n ints: vec4<i32>,\n // bg: (background.rgb, hasBackground)\n bg: vec4<f32>,\n // f0: (uSpeedGlow, uSpeedNorm, uShadowOffset, uStretchAmp) \u2014 the flow velocity-map levers\n f0: vec4<f32>,\n // each palette stop: linear-sRGB rgb + _pad\n palette: array<vec4<f32>, 4>,\n};\n\n@group(0) @binding(0) var<uniform> u: RenderUniforms;\n@group(0) @binding(1) var<storage, read> particles: array<Particle>;\n\n\nfn srgbToLinearCh(c: f32) -> f32 {\n if (c <= 0.04045) { return c / 12.92; }\n return pow((c + 0.055) / 1.055, 2.4);\n}\nfn srgbToLinear(c: vec3<f32>) -> vec3<f32> {\n return vec3<f32>(srgbToLinearCh(c.r), srgbToLinearCh(c.g), srgbToLinearCh(c.b));\n}\n\nfn linearToSrgbCh(c: f32) -> f32 {\n if (c <= 0.0031308) { return c * 12.92; }\n return 1.055 * pow(c, 1.0 / 2.4) - 0.055;\n}\nfn linearToSrgb(c: vec3<f32>) -> vec3<f32> {\n return vec3<f32>(linearToSrgbCh(c.r), linearToSrgbCh(c.g), linearToSrgbCh(c.b));\n}\n\n// value.js LINEAR_SRGB_TO_LMS, row-major \u2192 WGSL columns (= the transpose).\nconst LINEAR_SRGB_TO_LMS: mat3x3<f32> = mat3x3<f32>(\n 0.4122214708, 0.2119034982, 0.0883024619,\n 0.5363325363, 0.6806995451, 0.2817188376,\n 0.0514459929, 0.1073969566, 0.6299787005\n);\n\n// value.js srgbToOKLab's INLINE LMS\u2192OKLab coefficients, row-major \u2192 WGSL columns.\nconst LMS_TO_OKLAB: mat3x3<f32> = mat3x3<f32>(\n 0.2104542553, 1.9779984951, 0.0259040371,\n 0.7936177850, -2.4285922050, 0.7827717662,\n -0.0040720468, 0.4505937099, -0.8086757660\n);\n\n// value.js OKLAB_TO_LMS_COEFF, row-major \u2192 WGSL columns.\nconst OKLAB_TO_LMS: mat3x3<f32> = mat3x3<f32>(\n 1.0, 1.0, 1.0,\n 0.3963377774, -0.1055613458, -0.0894841775,\n 0.2158037573, -0.0638541728, -1.2914855480\n);\n\n// value.js LMS_TO_LINEAR_SRGB, row-major \u2192 WGSL columns.\nconst LMS_TO_LINEAR_SRGB: mat3x3<f32> = mat3x3<f32>(\n 4.0767416621, -1.2684380046, -0.0041960863,\n -3.3077115913, 2.6097574011, -0.7034186147,\n 0.2309699292, -0.3413193965, 1.7076147010\n);\n\nfn cbrt3(v: vec3<f32>) -> vec3<f32> {\n return sign(v) * pow(abs(v), vec3<f32>(1.0 / 3.0));\n}\n\n// Gamma sRGB \u2192 raw OKLab (L, a, b). Mirrors value.js srgbToOKLab.\nfn srgbToOklab(c: vec3<f32>) -> vec3<f32> {\n let lin = srgbToLinear(c);\n let lms = LINEAR_SRGB_TO_LMS * lin;\n return LMS_TO_OKLAB * cbrt3(lms);\n}\n\n// Raw OKLab (L, a, b) \u2192 linear sRGB. Mirrors value.js oklabToLinearSRGB.\nfn oklabToLinearSrgb(lab: vec3<f32>) -> vec3<f32> {\n let lms_ = OKLAB_TO_LMS * lab;\n let lms = lms_ * lms_ * lms_;\n return LMS_TO_LINEAR_SRGB * lms;\n}\n\n// OKLab \u2192 OKLCh: H in RADIANS, folded to [0, 2pi). Mirrors value.js rawOklabToOklch.\nfn oklabToOklch(lab: vec3<f32>) -> vec3<f32> {\n let C = length(lab.yz);\n var H = atan2(lab.z, lab.y);\n if (H < 0.0) { H = H + 2.0 * PI; }\n return vec3<f32>(lab.x, C, H);\n}\n\n// OKLCh (H radians) \u2192 OKLab. Mirrors value.js rawOklchToOklab.\nfn oklchToOklab(lch: vec3<f32>) -> vec3<f32> {\n return vec3<f32>(lch.x, lch.y * cos(lch.z), lch.y * sin(lch.z));\n}\n\n// The sweeping bright-stripe band (transcribes flowField.ts waveBand): a soft two-sided\n// ridge over the normalized height \u2014 1 at the band center, falling to 0 at \u00B1width.\nfn waveBand(h: f32, center: f32, width: f32) -> f32 {\n let w = max(width, 1e-3);\n let d = abs(h - center);\n return 1.0 - smoothstep(0.0, w, d);\n}\n\n// The optional soft-disc globe mask \u2014 a slow Lissajous-drifting radial field (the\n// reference's two-sphere composition). OFF when uGlobeMask <= 0.5 (returns 1).\nfn globeMask(o: vec2<f32>, t: f32, on: f32) -> f32 {\n if (on <= 0.5) { return 1.0; }\n // a slow Lissajous center drift within the domain\n let cx = 0.35 * sin(t * 0.13);\n let cy = 0.28 * cos(t * 0.11);\n let d = length(o - vec2<f32>(cx, cy));\n // a soft disc of radius ~0.6 with a feathered edge\n return 1.0 - smoothstep(0.45, 0.75, d);\n}\n\n// Sample the multi-stop palette (linear-sRGB stops, OKLab mix). t in [0,1].\nfn samplePaletteLin(t: f32) -> vec3<f32> {\n let stopCount = u.ints.x;\n if (stopCount <= 1) { return u.palette[0].rgb; }\n let n = f32(stopCount);\n let ft = clamp(t, 0.0, 1.0) * (n - 1.0);\n let i0 = i32(floor(ft));\n let i1 = min(i0 + 1, stopCount - 1);\n let f = ft - f32(i0);\n let labA = LMS_TO_OKLAB * cbrt3(LINEAR_SRGB_TO_LMS * u.palette[i0].rgb);\n let labB = LMS_TO_OKLAB * cbrt3(LINEAR_SRGB_TO_LMS * u.palette[i1].rgb);\n return oklabToLinearSrgb(mix(labA, labB, f));\n}\n\nstruct VSOut {\n @builtin(position) pos: vec4<f32>,\n @location(0) local: vec2<f32>, // [-1,1] billboard-local coords for the soft circle\n @location(1) bright: f32, // brightness [0, ~1.6]\n @location(2) ramp: f32, // palette-ramp coord (field: tone, flow: speedNorm)\n @location(3) flowFade: f32, // flow life-fade [0,1] (field: 1)\n};\n\n@vertex\nfn vs_main(\n @builtin(vertex_index) vi: u32,\n @builtin(instance_index) ii: u32,\n) -> VSOut {\n // Two-triangle quad corners in billboard-local space.\n var corners = array<vec2<f32>, 6>(\n vec2<f32>(-1.0, -1.0), vec2<f32>(1.0, -1.0), vec2<f32>(-1.0, 1.0),\n vec2<f32>(-1.0, 1.0), vec2<f32>(1.0, -1.0), vec2<f32>(1.0, 1.0),\n );\n let local = corners[vi];\n\n let pr = particles[ii].data;\n let p = pr.xy;\n let half = u.r0.w;\n let aspect = u.r1.z;\n let mode = i32(u.r2.w + 0.5);\n\n var bright: f32;\n var ramp: f32;\n var sizeWorld: f32;\n var flowFade: f32 = 1.0;\n\n if (mode == 1) {\n // \u2500\u2500 flow (AURORA CURRENT): speed\u2192hue, speed\u00B7life\u2192brightness, speed\u2192size bloom \u2500\u2500\n let speed = pr.z;\n let life = pr.w;\n let speedNorm = clamp(speed / max(u.f0.y, 1e-4), 0.0, 1.0);\n // life fades the mote over its last third (the trail's tail / overlapping-action).\n flowFade = clamp(life * 3.0, 0.0, 1.0);\n ramp = speedNorm;\n bright = (0.35 + speedNorm * u.f0.x) * flowFade;\n // a speed bloom (the cartoon \"more\" on WGPU \u2014 faster motes read as hot speed-cores) +\n // the \u221A\u03C6 stretch lever scales the bloom (the squash-stretch as an isotropic core here).\n sizeWorld = u.r1.x * (1.0 + speedNorm * (u.f0.w + 1.0));\n } else {\n // \u2500\u2500 field: the sweeping bright band over the anchored lattice (BC.W-VIZ-DOTFLOW) \u2500\u2500\n let h = pr.z;\n let dispMag = pr.w;\n let band = waveBand(h, u.r2.x, u.r2.y);\n bright = (u.r0.z + band * u.r0.y) * globeMask(p, u.r0.x, u.r2.z);\n ramp = clamp(bright, 0.0, 1.0);\n sizeWorld = u.r1.x * (1.0 + dispMag * u.r1.y);\n }\n\n // Position the quad at the dot in clip space. Domain [-half,half] \u2192 NDC [-1,1];\n // the quad half-extent rides sizeWorld (in domain units, aspect-corrected x).\n let ndc = p / half;\n let off = local * sizeWorld / half;\n let offX = off.x / max(aspect, 1e-4);\n\n var out: VSOut;\n out.pos = vec4<f32>(ndc.x + offX, ndc.y + off.y, 0.0, 1.0);\n out.local = local;\n out.bright = bright;\n out.ramp = ramp;\n out.flowFade = flowFade;\n return out;\n}\n\n@fragment\nfn fs_main(in: VSOut) -> @location(0) vec4<f32> {\n // Soft circle \u2014 radial smoothstep over the billboard-local radius.\n let r = length(in.local);\n let feather = 0.4;\n let mask = 1.0 - smoothstep(1.0 - feather, 1.0, r);\n if (mask < 0.002) { return vec4<f32>(0.0); }\n\n let mode = i32(u.r2.w + 0.5);\n let bright = clamp(in.bright, 0.0, 1.6);\n let lin = samplePaletteLin(in.ramp) * bright;\n let rgb = clamp(linearToSrgb(lin), vec3<f32>(0.0), vec3<f32>(1.0));\n\n if (mode == 1) {\n // flow: additive premultiplied \u2014 a soft glowing core, alpha rides speed\u00B7life.\n let coreAlpha = mask * mask; // a tighter hot core (less white wash \u2014 H2 cap)\n let a = coreAlpha * clamp(bright, 0.0, 1.0);\n return vec4<f32>(rgb * a, a);\n }\n // field: a floor alpha so even an off-band dot stays a faint lattice point.\n let alpha = mask * clamp(bright * 0.8 + 0.12, 0.0, 1.0);\n return vec4<f32>(rgb * alpha, alpha);\n}\n";
|
|
2
|
+
export declare const FLOW_FIELD_TRAIL_WGSL = "\nstruct TrailUniforms {\n // (decay, hasGround, time, _pad)\n p: vec4<f32>,\n // floor.rgb (linear-sRGB) + _pad\n floorC: vec4<f32>,\n // bloom.rgb (linear-sRGB) + _pad\n bloomC: vec4<f32>,\n};\n@group(0) @binding(0) var<uniform> u: TrailUniforms;\n@group(0) @binding(1) var samp: sampler;\n@group(0) @binding(2) var tex: texture_2d<f32>;\n\n\nfn srgbToLinearCh(c: f32) -> f32 {\n if (c <= 0.04045) { return c / 12.92; }\n return pow((c + 0.055) / 1.055, 2.4);\n}\nfn srgbToLinear(c: vec3<f32>) -> vec3<f32> {\n return vec3<f32>(srgbToLinearCh(c.r), srgbToLinearCh(c.g), srgbToLinearCh(c.b));\n}\n\nfn linearToSrgbCh(c: f32) -> f32 {\n if (c <= 0.0031308) { return c * 12.92; }\n return 1.055 * pow(c, 1.0 / 2.4) - 0.055;\n}\nfn linearToSrgb(c: vec3<f32>) -> vec3<f32> {\n return vec3<f32>(linearToSrgbCh(c.r), linearToSrgbCh(c.g), linearToSrgbCh(c.b));\n}\n\nstruct FSQ { @builtin(position) pos: vec4<f32>, @location(0) uv: vec2<f32> };\n\n@vertex\nfn vs_fsq(@builtin(vertex_index) vi: u32) -> FSQ {\n var c = array<vec2<f32>, 3>(\n vec2<f32>(-1.0, -1.0), vec2<f32>(3.0, -1.0), vec2<f32>(-1.0, 3.0),\n );\n let p = c[vi];\n var out: FSQ;\n out.pos = vec4<f32>(p, 0.0, 1.0);\n out.uv = p * 0.5 + 0.5;\n return out;\n}\n\n@fragment\nfn fs_decay(in: FSQ) -> @location(0) vec4<f32> {\n let prev = textureSample(tex, samp, in.uv);\n return prev * u.p.x; // fade toward black\n}\n\n@fragment\nfn fs_present(in: FSQ) -> @location(0) vec4<f32> {\n let trail = textureSample(tex, samp, in.uv).rgb;\n let mapped = trail / (trail + vec3<f32>(0.85)); // Reinhard \u2014 hot cores, not white wash\n if (u.p.y < 0.5) {\n let rgb = clamp(linearToSrgb(mapped), vec3<f32>(0.0), vec3<f32>(1.0));\n let a = clamp(max(mapped.r, max(mapped.g, mapped.b)), 0.0, 1.0);\n return vec4<f32>(rgb * a, a);\n }\n let bloom = smoothstep(1.3, 0.0, distance(in.uv, vec2<f32>(0.12, 0.88)));\n let floorLin = u.floorC.rgb + u.bloomC.rgb * bloom * 0.5;\n let lin = floorLin + mapped;\n let rgb = clamp(linearToSrgb(lin), vec3<f32>(0.0), vec3<f32>(1.0));\n return vec4<f32>(rgb, 1.0);\n}\n";
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import type { DotMatrixConfig } from "./constants";
|
|
2
|
+
/**
|
|
3
|
+
* DotMatrix — a globe of fine warm-cream dots on a sphere SURFACE (BC.W-VIZ-DOTMATRIX —
|
|
4
|
+
* the Claude co-work "fine-dot spheres on dark" reference).
|
|
5
|
+
*
|
|
6
|
+
* The dots are laid via the Fibonacci phyllotaxis spiral (even-by-area, no pole-pinching)
|
|
7
|
+
* and depth-shaded so the globe reads as a translucent dot-SHELL — the near hemisphere
|
|
8
|
+
* brighter + larger, the rim/far side fading toward near-invisible (the shape is painted
|
|
9
|
+
* by BRIGHTNESS + DEPTH, not motion; stop the spin and it STILL reads as a sphere). It
|
|
10
|
+
* spins slowly on a gently tilted axis. WebGPU-FIRST: the render pass draws instanced
|
|
11
|
+
* billboard quads + the crisp `fwidth` SDF fragment; a WebGL2 instanced-billboard fallback
|
|
12
|
+
* draws the SAME dots where WebGPU is absent (born-GPU — no Canvas2D). It composes
|
|
13
|
+
* `useDotMatrix` → the `createGpuSubstrate` picker over the ONE canvas lifecycle leaf
|
|
14
|
+
* (offscreen-pause, live-PRM freeze, the shared pointer field) — it never bootstraps its
|
|
15
|
+
* own context.
|
|
16
|
+
*
|
|
17
|
+
* The DEFAULT palette is the warm-cream library identity over a transparent ground (the
|
|
18
|
+
* glass card shows through); the mono-warm-white-on-near-black reference + the two-globe
|
|
19
|
+
* composition are DEMO presets (presets-in-consumers — never a library token). The
|
|
20
|
+
* teal-on-navy is GONE entirely.
|
|
21
|
+
*/
|
|
22
|
+
type __VLS_Props = {
|
|
23
|
+
/** The full author schema (the studio's `useConfiguratorState` model). */
|
|
24
|
+
config?: DotMatrixConfig;
|
|
25
|
+
/**
|
|
26
|
+
* The declarative WCAG-2.2.2 pause seam. `v-model:paused` parks the render loop
|
|
27
|
+
* (the substrate's `manual` suspend) when `true`. Wire `<DockBackgroundToggle>`'s
|
|
28
|
+
* `@update:paused` to this `v-model`.
|
|
29
|
+
*/
|
|
30
|
+
paused?: boolean;
|
|
31
|
+
};
|
|
32
|
+
declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {
|
|
33
|
+
pause: () => void;
|
|
34
|
+
resume: () => void;
|
|
35
|
+
wake: () => void;
|
|
36
|
+
renderAt: (timeSec: number) => void;
|
|
37
|
+
}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
38
|
+
"update:paused": (value: boolean) => any;
|
|
39
|
+
}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
|
|
40
|
+
"onUpdate:paused"?: ((value: boolean) => any) | undefined;
|
|
41
|
+
}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
42
|
+
declare const _default: typeof __VLS_export;
|
|
43
|
+
export default _default;
|