@mkbabb/glass-ui 4.1.0 → 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-8whJrLWt.js → CardAction-DlVP2evz.js} +58 -54
- package/dist/{CommandShortcut-D3yxgHNn.js → CommandShortcut-By-VQcLO.js} +3 -3
- package/dist/{ConfiguratorRow-CaP7U3ZA.js → ConfiguratorRow-YMXdINHx.js} +3 -3
- package/dist/{ContextMenuContent-B3ZsheLV.js → ContextMenuContent-CMWn6huB.js} +1 -1
- package/dist/{ContextMenuSubContent-DDRID3qC.js → ContextMenuSubContent-DvwWCUc0.js} +1 -1
- package/dist/{DataTable-Bc9kUtu_.js → DataTable-C4tG3eIJ.js} +4 -4
- package/dist/DialogContent-D8U9ZfWS.js +121 -0
- package/dist/{DialogScrollContent-TTuovQst.js → DialogScrollContent-BMekN7gq.js} +1 -1
- package/dist/{FadingScroll-DLRbH5Xr.js → FadingScroll-P8B30rAD.js} +1 -1
- package/dist/{HoverCardContent-Bel1gdLZ.js → HoverCardContent-DAmGYglo.js} +1 -1
- package/dist/{HoverPopover-BcIxvyqZ.js → HoverPopover-DYpBOzzF.js} +1 -1
- package/dist/{IconChip-DhbdGdFQ.js → IconChip-CQa7XZYc.js} +7 -5
- package/dist/{IconTooltip-B0zimd2H.js → IconTooltip-_df8M3xm.js} +1 -1
- package/dist/{Input-Cg9DF62r.js → Input-CyU4_hIC.js} +2 -2
- package/dist/{MetricBadge-RHdBP72w.js → MetricBadge-DQt_dGah.js} +1 -1
- package/dist/{Notification-CphK7AAm.js → Notification-BlSPJhtZ.js} +1 -1
- package/dist/{NumberFieldContent-D8cXeyO4.js → NumberFieldContent-Z3VxGu_6.js} +3 -3
- 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-CnqB7gLm.js → Progress-C9SsdwIZ.js} +1 -1
- package/dist/{ScrollingText-CTZbA_cG.js → ScrollingText-DY3W1Jfh.js} +2 -2
- package/dist/{SelectScrollDownButton-DAKCBEdW.js → SelectScrollDownButton-3mFHX_R-.js} +15 -12
- package/dist/{Switch-B8RscmRu.js → Switch-uf-UKPA2.js} +1 -1
- package/dist/{Toaster-D9qIHjBI.js → Toaster-ozrsR4mP.js} +1 -1
- package/dist/{ToggleGroupItem-BLtr3TJq.js → ToggleGroupItem-BpzaVzNm.js} +4 -4
- package/dist/{TooltipProvider-BJ_Y5EGX.js → TooltipProvider-QQVM_80r.js} +1 -1
- package/dist/animated-digit.js +2 -2
- package/dist/api/index.d.ts +1 -0
- package/dist/api/types-extra.d.ts +3 -1
- package/dist/api.js +2 -2
- package/dist/aurora.js +163 -131
- package/dist/badge-Bt14yURi.js +72 -0
- package/dist/badge.js +1 -1
- package/dist/border-progress.js +1 -1
- package/dist/button-D1W9PrzI.js +130 -0
- package/dist/button.js +1 -1
- package/dist/canvas.js +1 -1
- package/dist/card.js +1 -1
- package/dist/carousel.js +227 -98
- package/dist/chipVariants-BJQ0I2kB.js +18 -0
- package/dist/collapsible.js +1 -1
- package/dist/color.js +1 -1
- package/dist/command.js +1 -1
- package/dist/components/custom/aurora/composables/glSetup.d.ts +1 -1
- package/dist/components/custom/aurora/composables/uniformBridgeWGPU.d.ts +1 -1
- package/dist/components/custom/aurora/constants/presets.d.ts +29 -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/concentric/Concentric.vue.d.ts +15 -12
- package/dist/components/custom/concentric/composables/concentricGLSetup.d.ts +8 -3
- package/dist/components/custom/concentric/composables/concentricWGPUSetup.d.ts +8 -4
- package/dist/components/custom/concentric/composables/levelField.d.ts +50 -0
- package/dist/components/custom/concentric/composables/uniformBridgeWGPU.d.ts +7 -4
- package/dist/components/custom/concentric/composables/useConcentric.d.ts +3 -3
- package/dist/components/custom/concentric/constants.d.ts +62 -41
- 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/dock/DockDropdownTrigger.vue.d.ts +4 -3
- package/dist/components/custom/dock/DockIconButton.vue.d.ts +10 -0
- package/dist/components/custom/dock/DockPopoverTrigger.vue.d.ts +19 -0
- package/dist/components/custom/dock/DockStack.vue.d.ts +35 -22
- package/dist/components/custom/dock/GlassDock.vue.d.ts +19 -3
- package/dist/components/custom/dock/composables/dockMorphContext.d.ts +18 -32
- package/dist/components/custom/dock/composables/dockMorphMeasure.d.ts +76 -145
- package/dist/components/custom/dock/composables/index.d.ts +1 -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/useDockShellProps.d.ts +38 -0
- package/dist/components/custom/dock/constants.d.ts +14 -3
- package/dist/components/custom/dock/index.d.ts +3 -0
- package/dist/components/custom/dot-flow-field/composables/flowField.d.ts +21 -0
- 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 +28 -2
- package/dist/components/custom/dot-flow-field/composables/useFlowParticles.d.ts +18 -17
- package/dist/components/custom/dot-flow-field/constants.d.ts +51 -0
- package/dist/components/custom/dot-flow-field/index.d.ts +1 -1
- 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 +29 -0
- package/dist/components/custom/dot-flow-field/shaders/flow-field.render.wgsl.d.ts +2 -1
- package/dist/components/custom/dot-matrix/composables/uniformBridgeWGPU.d.ts +10 -1
- package/dist/components/custom/dot-matrix/composables/useDotSphere.d.ts +7 -0
- package/dist/components/custom/dot-matrix/constants.d.ts +14 -0
- package/dist/components/custom/dot-matrix/index.d.ts +1 -1
- package/dist/components/custom/dot-matrix/shaders/dot-matrix.glsl.d.ts +2 -2
- package/dist/components/custom/dot-matrix/shaders/dot-matrix.wgsl.d.ts +1 -1
- package/dist/components/custom/fourier-field/FourierField.vue.d.ts +4 -0
- package/dist/components/custom/fourier-field/composables/fourierFieldGLSetup.d.ts +9 -0
- package/dist/components/custom/fourier-field/composables/fourierFieldWGPUSetup.d.ts +11 -0
- package/dist/components/custom/fourier-field/composables/uniformBridgeWGPU.d.ts +16 -1
- package/dist/components/custom/fourier-field/composables/useFourierField.d.ts +22 -1
- package/dist/components/custom/fourier-field/constants.d.ts +53 -0
- package/dist/components/custom/fourier-field/shaders/fourier-field.glsl.d.ts +1 -1
- package/dist/components/custom/fourier-field/shaders/fourier-field.render.wgsl.d.ts +1 -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/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 +50 -1
- package/dist/components/custom/goo-dot-matrix/composables/gooDotSetup.d.ts +32 -3
- package/dist/components/custom/goo-dot-matrix/composables/uniformBridgeWGPU.d.ts +14 -4
- package/dist/components/custom/goo-dot-matrix/constants.d.ts +55 -16
- package/dist/components/custom/goo-dot-matrix/index.d.ts +1 -1
- package/dist/components/custom/goo-dot-matrix/shaders/goo-dot.frag.d.ts +2 -0
- package/dist/components/custom/goo-dot-matrix/shaders/goo-dot.wgsl.d.ts +1 -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/paper-backdrop/PaperBackdrop.vue.d.ts +18 -0
- package/dist/components/custom/paper-grid/composables/paperGrid.d.ts +44 -29
- package/dist/components/custom/paper-grid/composables/paperGridGLSetup.d.ts +2 -0
- package/dist/components/custom/paper-grid/composables/paperGridWGPUSetup.d.ts +3 -1
- package/dist/components/custom/paper-grid/composables/uniformBridgeWGPU.d.ts +2 -2
- package/dist/components/custom/paper-grid/constants.d.ts +44 -6
- package/dist/components/custom/paper-grid/index.d.ts +2 -2
- package/dist/components/custom/paper-grid/shaders/paper-grid.glsl.d.ts +1 -1
- package/dist/components/custom/paper-grid/shaders/paper-grid.wgsl.d.ts +1 -1
- package/dist/components/custom/selectable-chip/chipVariants.d.ts +39 -0
- package/dist/components/custom/selectable-chip/selectableChipVariants.d.ts +12 -20
- package/dist/components/custom/tabs/constants.d.ts +16 -8
- 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 +12 -10
- 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/card/Card.vue.d.ts +1 -1
- package/dist/components/ui/card/ScrollCard.vue.d.ts +1 -1
- package/dist/components/ui/carousel/CarouselContent.vue.d.ts +2 -4
- 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/select/SelectContent.vue.d.ts +9 -0
- package/dist/components/ui/slider/Slider.vue.d.ts +9 -0
- package/dist/composables/dom/index.d.ts +1 -0
- package/dist/composables/dom/useDragVelocity.d.ts +46 -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 +95 -2
- package/dist/composables/glass/webgl/useWebGLCanvas.d.ts +40 -2
- package/dist/composables/glass/webgpu/index.d.ts +1 -0
- package/dist/composables/glass/webgpu/useGpuSubstrate.d.ts +37 -0
- package/dist/composables/glass/webgpu/useWebGPUCanvas.d.ts +49 -2
- package/dist/composables/glass/webgpu/webgpuDevice.d.ts +1 -1
- package/dist/composables/motion/core/index.d.ts +4 -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/springPresets.d.ts +16 -17
- 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/useDockCtaReceive.d.ts +10 -28
- 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/useScrollPin.d.ts +49 -0
- package/dist/composables/motion/useScrollScene.d.ts +67 -0
- package/dist/concentric.js +532 -563
- package/dist/configurator.js +2 -2
- package/dist/confirm-dialog.js +3 -3
- package/dist/constellation.js +4 -4
- 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.js +1 -1
- package/dist/dialog.js +3 -3
- package/dist/dock.js +1163 -618
- package/dist/dockContext-gFVS2gMg.js +18 -0
- package/dist/dom.js +7 -6
- package/dist/dot-flow-field.js +1114 -523
- package/dist/dot-matrix.js +348 -204
- package/dist/drawer.js +106 -96
- package/dist/{dropdown-menu-aJmV5SqE.js → dropdown-menu-CCfcCQ68.js} +3 -3
- package/dist/dropdown-menu.js +1 -1
- package/dist/easing.js +3 -3
- package/dist/expandable-container.js +2 -2
- package/dist/fading-scroll.js +1 -1
- package/dist/forms.js +6 -6
- package/dist/fourier-field.js +441 -197
- 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 +139 -135
- package/dist/goo-blob.js +11 -9
- package/dist/goo-dot-matrix.js +418 -198
- 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 +3 -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 +7 -7
- package/dist/metric-badge.js +1 -1
- package/dist/metric-cell.js +1 -1
- package/dist/metric-stack.js +1 -1
- package/dist/motion-core.js +42 -39
- package/dist/motion-curves.js +20 -14
- package/dist/motion.js +226 -26
- package/dist/notification.js +1 -1
- package/dist/number-field.js +1 -1
- package/dist/pager-dots.js +1 -1
- package/dist/paper-backdrop.js +1 -1
- package/dist/paper-grid.js +315 -342
- package/dist/paperGrid-CXCSMbZ1.js +191 -0
- package/dist/popover.js +1 -1
- package/dist/{presets-CvOUqtdY.js → presets-QvYgnFIZ.js} +13 -12
- package/dist/progress.js +1 -1
- package/dist/pulse.js +1 -1
- package/dist/reactive.js +2 -2
- package/dist/{resolveCanvasColor-yPyIpJt9.js → resolveCanvasColor-DsSJk06I.js} +5 -5
- package/dist/scrolling-text.js +1 -1
- package/dist/search.js +7 -7
- package/dist/select.js +3 -3
- package/dist/selectable-chip.js +18 -35
- package/dist/separator.js +1 -1
- package/dist/{sheet-B2flBfLH.js → sheet-DUCIoOe0.js} +3 -3
- package/dist/sheet.js +1 -1
- package/dist/sidebar.js +1 -1
- package/dist/slider-CcICPe3u.js +149 -0
- package/dist/slider.js +1 -1
- package/dist/sortable-list.js +3 -3
- package/dist/{spectrum-walk-BVzA7Biz.js → spectrum-walk-cBNSx_zm.js} +1 -1
- package/dist/springPresets-DfoQ6XRY.js +64 -0
- package/dist/stacked-icons.js +54 -39
- package/dist/styles/cards.css +202 -2
- package/dist/styles/components.css +1 -3
- package/dist/styles/configurator.css +172 -7
- package/dist/styles/critical-partition.mjs +35 -2
- package/dist/styles/deferred.css +2 -0
- package/dist/styles/dock/adaptive-legibility.css +119 -0
- package/dist/styles/dock/density.css +18 -10
- package/dist/styles/dock/fission-bridge.css +552 -0
- package/dist/styles/dock/layers.css +88 -124
- package/dist/styles/dock/morph-bridge.css +15 -2
- package/dist/styles/dock/morph.css +45 -114
- package/dist/styles/dock/shape.css +137 -11
- package/dist/styles/dock/shell.css +1 -3
- package/dist/styles/dock/stack-rail.css +95 -7
- package/dist/styles/dock-controls/icon-button.css +34 -2
- package/dist/styles/dock-controls/triggers.css +23 -1
- package/dist/styles/dock-controls.css +18 -0
- package/dist/styles/dock.css +16 -1
- package/dist/styles/drawer.css +166 -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/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 +13 -1
- package/dist/styles/glass/surfaces.css +18 -8
- package/dist/styles/glass.css +11 -0
- package/dist/styles/icon-chip.css +45 -0
- package/dist/styles/index.css +11 -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/segmented-tabs.css +85 -51
- package/dist/styles/select.css +151 -0
- package/dist/styles/tokens/color-radius.css +1 -1
- package/dist/styles/tokens/dark-arm.css +57 -8
- package/dist/styles/tokens/glass-deep.css +8 -4
- package/dist/styles/tokens/glass-fx.css +80 -2
- package/dist/styles/tokens/glass.css +140 -8
- package/dist/styles/tokens/light-dark.css +2 -2
- package/dist/styles/tokens/property-regs.css +144 -0
- package/dist/styles/tokens/scale-paper.css +20 -8
- package/dist/styles/tokens/scheme-motion.css +92 -157
- 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.css +9 -2
- package/dist/styles/utilities/btn.css +70 -0
- package/dist/switch.js +1 -1
- package/dist/tabs.js +198 -181
- 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 +1 -1
- package/dist/{uniformBridgeWGPU-CtAKl45L.js → uniformBridgeWGPU-BCse1SHU.js} +191 -127
- package/dist/{useAnimatedNumber-CLrxicG9.js → useAnimatedNumber-BntskVdQ.js} +1 -1
- package/dist/{useConfiguratorState-4xblKfwd.js → useConfiguratorState-22BcULzF.js} +37 -35
- package/dist/useDockCtaReceive-DX7RDb6_.js +88 -0
- package/dist/{useDragMorph-BUgAC-zK.js → useDragMorph-DGLSewwB.js} +2 -2
- package/dist/useDragVelocity-CjcfX3dA.js +57 -0
- package/dist/useGooMorph-Cs13NgYL.js +104 -0
- package/dist/useGpuSubstrate-Ceet70xq.js +347 -0
- package/dist/{useViewTransition-CUI1nAgn.js → useHaptic-CPz5BT9I.js} +40 -1
- package/dist/{useLiquidFlex-UmA6LMZu.js → useLiquidFlex-Cc6PjVJD.js} +8 -3
- package/dist/useLiquidPress-CtOQ8Z0_.js +43 -0
- package/dist/useMorphField-ogBM7ubT.js +141 -0
- package/dist/{useScrollChrome-D66AVP7C.js → useScrollChrome-JuImi1DM.js} +2 -2
- package/dist/{useSpringMount-BWDnKIwh.js → useSpringMount-DFxtzmkR.js} +1 -1
- package/dist/{useSpringPress-B1-Czp-V.js → useSpringPress-VM9RgVq3.js} +1 -1
- package/dist/{useSurfaceAxis-g0NloYEF.js → useSurfaceAxis-Ci7Dnaw2.js} +1 -1
- package/dist/{useTouchGate-CBZTD4SD.js → useTouchGate-B1Lf9XqN.js} +1 -1
- package/dist/virtual.js +1 -1
- package/dist/watercolor-dot.js +16 -26
- package/dist/writeVelocityWeight-Bh83xZfs.js +19 -0
- package/package.json +14 -3
- package/src/styles/cards.css +202 -2
- package/src/styles/configurator.css +172 -7
- package/src/styles/critical-partition.mjs +35 -2
- package/src/styles/dock/adaptive-legibility.css +119 -0
- package/src/styles/dock/density.css +18 -10
- package/src/styles/dock/fission-bridge.css +552 -0
- package/src/styles/dock/layers.css +88 -124
- package/src/styles/dock/morph-bridge.css +15 -2
- package/src/styles/dock/morph.css +45 -114
- package/src/styles/dock/shape.css +137 -11
- package/src/styles/dock/shell.css +1 -3
- package/src/styles/dock/stack-rail.css +95 -7
- package/src/styles/dock-controls/icon-button.css +34 -2
- package/src/styles/dock-controls/triggers.css +23 -1
- package/src/styles/dock-controls.css +18 -0
- package/src/styles/dock.css +16 -1
- package/src/styles/drawer.css +164 -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/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 +13 -1
- package/src/styles/glass/surfaces.css +18 -8
- package/src/styles/glass.css +11 -0
- package/src/styles/icon-chip.css +45 -0
- package/src/styles/index.css +11 -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/segmented-tabs.css +85 -47
- package/src/styles/select.css +151 -0
- package/src/styles/tokens/color-radius.css +1 -1
- package/src/styles/tokens/dark-arm.css +57 -8
- package/src/styles/tokens/glass-deep.css +8 -4
- package/src/styles/tokens/glass-fx.css +80 -2
- package/src/styles/tokens/glass.css +140 -8
- package/src/styles/tokens/light-dark.css +2 -2
- package/src/styles/tokens/property-regs.css +144 -0
- package/src/styles/tokens/scale-paper.css +20 -8
- package/src/styles/tokens/scheme-motion.css +92 -157
- 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.css +9 -2
- package/src/styles/utilities/btn.css +70 -0
- package/dist/DialogContent-6JtTB5x2.js +0 -106
- package/dist/PagerDots-Cjx96la-.js +0 -98
- package/dist/PaperBackdrop-CqwjnfLv.js +0 -31
- package/dist/badge-D9XWW4GT.js +0 -53
- package/dist/button-5dY1Dvhd.js +0 -125
- package/dist/components/custom/concentric/composables/ringField.d.ts +0 -85
- package/dist/createCanvasLifecycle-Gh45Ce-p.js +0 -93
- package/dist/dockContext-BNfyPLe9.js +0 -17
- package/dist/slider-2A0rPn79.js +0 -142
- package/dist/springPresets-Ce7OYCm9.js +0 -46
- package/dist/useDockCtaReceive-DfFkmgL1.js +0 -82
- package/dist/useGpuSubstrate-4pTcp6mX.js +0 -294
- package/dist/useLiquidPress-BooG97RY.js +0 -39
- /package/dist/{CollapsibleContent-68dEXIAl.js → CollapsibleContent-D7UNsXQr.js} +0 -0
- /package/dist/{DialogFooter-9phqcRIS.js → DialogFooter-DoLy0ewI.js} +0 -0
- /package/dist/{InstrumentChassis-CxsHSyMj.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-BFiod7X2.js → SelectGroup-Dcczq44n.js} +0 -0
- /package/dist/{SelectSeparator-C2UGOkXF.js → SelectSeparator-CNRGG7Ew.js} +0 -0
- /package/dist/{Separator-DQcwC2TR.js → Separator-Cf9-JFgi.js} +0 -0
- /package/dist/{_plugin-vue_export-helper-C1je1s0u.js → _plugin-vue_export-helper-gLzyemvl.js} +0 -0
- /package/dist/{color-Cs0-oxYL.js → color-B9jZdhJX.js} +0 -0
- /package/dist/{compile-nZ1xVYTp.js → compile-INR_tPk_.js} +0 -0
- /package/dist/{constants--C2DkLW8.js → constants-BWj7DkMn.js} +0 -0
- /package/dist/{createContext-CpBNTRMI.js → createContext-Cd23P9j0.js} +0 -0
- /package/dist/{dotMatrixField-D_x9_1qq.js → dotMatrixField-CRO0ZFk4.js} +0 -0
- /package/dist/{flow.glsl-B2P7e0MT.js → flow.glsl-DqEGRpl4.js} +0 -0
- /package/dist/{math-Eb0w3LqU.js → math-5RcIgCB4.js} +0 -0
- /package/dist/{menuItemVariants-D8VNHq22.js → menuItemVariants-DAXquKja.js} +0 -0
- /package/dist/{prng-B-d9eYX8.js → prng-B5tIXTtj.js} +0 -0
- /package/dist/{procedural-color.wgsl-m7Zgv35j.js → procedural-color.wgsl-C1Y5PkM6.js} +0 -0
- /package/dist/{scrollReader-DI1NWxUw.js → scrollReader-rc3Ns_NM.js} +0 -0
- /package/dist/{useControlSize-SH1UmJCi.js → useControlSize-DAZ062x7.js} +0 -0
- /package/dist/{useFuzzySearch-DIhcYtcw.js → useFuzzySearch-0fTYOhS4.js} +0 -0
- /package/dist/{useGlobalDark-CmjB9E32.js → useGlobalDark-B4HO9LXG.js} +0 -0
- /package/dist/{useIntersectionPause-Dbozzjgm.js → useIntersectionPause-DO8Vl4gs.js} +0 -0
- /package/dist/{useInterval-CNdua40W.js → useInterval-BVUI-sez.js} +0 -0
- /package/dist/{useKeyboardShortcuts-BPRp33Im.js → useKeyboardShortcuts-BEut54Tk.js} +0 -0
- /package/dist/{usePointerVelocityField-QLsy3_kv.js → usePointerVelocityField-BrkqZFhj.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-c3yxmH6a.js → useScrollProgress-A0M6qRl7.js} +0 -0
- /package/dist/{useSortable-BVqlJRBR.js → useSortable-DQV_UNDw.js} +0 -0
- /package/dist/{useTextHighlight-NmBM5V_4.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-D9k0jADx.js → vReveal-CT1KtwZA.js} +0 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const METABALL_WGSL = "\nconst MAX_SATS: i32 = 4;\nconst TRAIL_N: i32 = 15;\nconst MAX_BLOB_STOPS: i32 = 4;\nconst PI: f32 = 3.141592653589793;\n\n// \u2500\u2500 Uniforms (the typed-struct source-of-truth \u2014 see uniformBridgeWGPU.ts) \u2500\u2500\n// Scalars packed into vec4 lanes; per-satellite / per-trail / per-palette rows packed\n// into a vec4 so the array stride is the natural 16 bytes (no std140 stride trap \u2014 the\n// parity-blowout suspect the wave's \u00A7Triumvirate names).\nstruct Uniforms {\n // s0: (uTime, uBodyRadius, uPulsePhase, uPulseAmp)\n s0: vec4<f32>,\n // s1: (uNoiseAmp, uNoiseFreq, uNoiseSpeed, uWarpAmp)\n s1: vec4<f32>,\n // s2: (uSmoothK, uMerge, uMaxReach, uLit)\n s2: vec4<f32>,\n // s3: (uSpecStrength, uSpecShininess, uRimPower, uRimStrength)\n s3: vec4<f32>,\n // s4: (uIridescence, uIridHue, uIridSpeed, uSssScale)\n s4: vec4<f32>,\n // s5: (uSssPower, uCoreGlow, uHueRange, uSatShift)\n s5: vec4<f32>,\n // s6: (uBrightnessShift, uColorNoiseFreq, uColorNoiseSpeed, uStretch)\n s6: vec4<f32>,\n // s7: (uPointerActive, uPointerAttraction, uPointerStrength, uStage)\n // BC.W-GOOBLOB-PLAIN \u2014 uStage gates the STAGE-1 stripped floor: 1.0 = the plain\n // shadowless lightless fill-only floor (variant=\"blob\"); 0.0 = the full lit\n // pipeline (variant=\"meatball\" / STAGE 2). It rides the spare s7.w lane the typed-\n // struct SoT (uniformBridgeWGPU.ts) reserved.\n s7: vec4<f32>,\n // ptr: (uPointer.x, uPointer.y, uVelocity.x, uVelocity.y)\n ptr: vec4<f32>,\n // base: (uBaseColor.rgb, _pad)\n base: vec4<f32>,\n // rim: (uRimColor.rgb, _pad)\n rim: vec4<f32>,\n // light: (uLightDir.xyz, _pad)\n light: vec4<f32>,\n // res: (uResolution.x, uResolution.y, uShadow, uShadowSoftness)\n // BC.W-GOOBLOB-MEATBALL \u2014 the soft-shadow march rides the spare res.z/res.w lanes the\n // typed-struct SoT (uniformBridgeWGPU.ts) reserved (the EXTEND, never a re-fork): res.z\n // = uShadow (1.0 = the variant=meatball shadow ON), res.w = uShadowSoftness (the\n // penumbra hardness, inverse light-source size \u2192 4-48).\n res: vec4<f32>,\n // ints: (uStopCount, uSatCount, uTrailCount, _pad)\n ints: vec4<i32>,\n palette: array<vec4<f32>, 4>,\n satPos: array<vec4<f32>, 4>, // (pos.x, pos.y, radius, opacity)\n trailPos: array<vec4<f32>, 15>, // (pos.x, pos.y, radius, _pad)\n};\n\n@group(0) @binding(0) var<uniform> u: Uniforms;\n\n// Noise + FBM (BC.W-CARVE6 \u2192 metaball-noise.wgsl) \u2014 spliced AFTER const FBM_ROT: mat2x2<f32> = mat2x2<f32>(0.8, 0.6, -0.6, 0.8);.\nconst FBM_ROT: mat2x2<f32> = mat2x2<f32>(0.8, 0.6, -0.6, 0.8);\n\nconst FBM_LACUNARITY: f32 = 1.8;\nconst FBM_GAIN: f32 = 0.42;\n\n// \u2500\u2500 Noise (blob-LOCAL 3D-p3 hash + IQ analytic-derivative gradient noise) \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\n// IQ analytic-derivative gradient noise \u2014 value in .x, ANALYTIC gradient (d/dx, d/dy) in\n// .yz, from one eval. The quintic fade has a continuous 2nd derivative.\nfn noised(p: vec2<f32>) -> vec3<f32> {\n let i = floor(p);\n let f = fract(p);\n let uu = f * f * f * (f * (f * 6.0 - 15.0) + 10.0);\n let du = 30.0 * f * f * (f * (f - 2.0) + 1.0);\n\n let ga = -1.0 + 2.0 * vec2<f32>(hash21(i + vec2<f32>(0.0, 0.0)), hash21(i + vec2<f32>(7.3, 0.0)));\n let gb = -1.0 + 2.0 * vec2<f32>(hash21(i + vec2<f32>(1.0, 0.0)), hash21(i + vec2<f32>(8.3, 0.0)));\n let gc = -1.0 + 2.0 * vec2<f32>(hash21(i + vec2<f32>(0.0, 1.0)), hash21(i + vec2<f32>(7.3, 1.0)));\n let gd = -1.0 + 2.0 * vec2<f32>(hash21(i + vec2<f32>(1.0, 1.0)), hash21(i + vec2<f32>(8.3, 1.0)));\n\n let va = dot(ga, f - vec2<f32>(0.0, 0.0));\n let vb = dot(gb, f - vec2<f32>(1.0, 0.0));\n let vc = dot(gc, f - vec2<f32>(0.0, 1.0));\n let vd = dot(gd, f - vec2<f32>(1.0, 1.0));\n\n let n = va + uu.x * (vb - va) + uu.y * (vc - va) + uu.x * uu.y * (va - vb - vc + vd);\n let value = 0.5 + 0.5 * n;\n\n let grad =\n ga + uu.x * (gb - ga) + uu.y * (gc - ga) + uu.x * uu.y * (ga - gb - gc + gd) +\n du * (vec2<f32>(uu.y, uu.x) * (va - vb - vc + vd) + vec2<f32>(vb, vc) - va);\n return vec3<f32>(value, 0.5 * grad);\n}\n\nfn fbm(p0: vec2<f32>, octaves: i32) -> f32 {\n var value = 0.0;\n var amp = 0.5;\n var freq = 1.0;\n var p = p0;\n for (var i = 0; i < 4; i = i + 1) {\n if (i >= octaves) { break; }\n value = value + amp * noised(p * freq).x;\n p = FBM_ROT * p;\n freq = freq * FBM_LACUNARITY;\n amp = amp * FBM_GAIN;\n }\n return value;\n}\n\n// FBM with ANALYTIC GRADIENT \u2014 value in .x, \u2202/\u2202x, \u2202/\u2202y in .yz. The gradient accumulates\n// noised()'s analytic gradient per octave, chain-ruled through the per-octave frequency\n// scale AND the FBM_ROT rotation (the keystone feed for the analytic surface normal).\nfn fbmG(p: vec2<f32>, octaves: i32) -> vec3<f32> {\n var value = 0.0;\n var grad = vec2<f32>(0.0, 0.0);\n var amp = 0.5;\n var freq = 1.0;\n var rotAccum = mat2x2<f32>(1.0, 0.0, 0.0, 1.0);\n var pp = p;\n for (var i = 0; i < 4; i = i + 1) {\n if (i >= octaves) { break; }\n let n = noised(pp * freq);\n value = value + amp * n.x;\n grad = grad + amp * freq * (transpose(rotAccum) * n.yz);\n pp = FBM_ROT * pp;\n freq = freq * FBM_LACUNARITY;\n amp = amp * FBM_GAIN;\n rotAccum = FBM_ROT * rotAccum;\n }\n return vec3<f32>(value, grad);\n}\n\n// One domain-warp pass with the ANALYTIC GRADIENT carried (warp-Jacobian approximation).\nfn fbmWarpedG(p: vec2<f32>, octaves: i32, warpAmp: f32) -> vec3<f32> {\n if (warpAmp <= 0.0) { return fbmG(p, octaves); }\n let q = vec2<f32>(fbm(p + vec2<f32>(0.0, 0.0), octaves),\n fbm(p + vec2<f32>(5.2, 1.3), octaves));\n return fbmG(p + warpAmp * (q - 0.5), octaves);\n}\n\n\n// \u2500\u2500 SDF body (value+gradient circle + the IQ normalized smin, value+gradient form) \u2500\u2500\nfn sdgCircle(p: vec2<f32>, center: vec2<f32>, radius: f32) -> vec3<f32> {\n let d = p - center;\n let len = length(d);\n var grad = vec2<f32>(0.0, 1.0);\n if (len > 1e-6) { grad = d / len; }\n return vec3<f32>(len - radius, grad);\n}\n\nfn sminQuadraticG(a: vec3<f32>, b: vec3<f32>, k0: f32) -> vec3<f32> {\n let k = k0 * 4.0;\n let h = max(k - abs(a.x - b.x), 0.0) / k;\n let m = h * h * k * 0.25;\n var w = 1.0 - 0.5 * h * h;\n if (a.x < b.x) { w = 0.5 * h * h; }\n let dist = min(a.x, b.x) - m;\n let grad = mix(a.yz, b.yz, w);\n return vec3<f32>(dist, grad);\n}\n\nfn sminCircularG(a: vec3<f32>, b: vec3<f32>, k0: f32) -> vec3<f32> {\n let k = k0 * (1.0 / (1.0 - sqrt(0.5)));\n let h = max(k - abs(a.x - b.x), 0.0) / k;\n let m = k * 0.5 * (1.0 + h - sqrt(1.0 - h * (h - 2.0)));\n var w = 1.0 - 0.5 * h;\n if (a.x < b.x) { w = 0.5 * h; }\n let dist = min(a.x, b.x) - m;\n let grad = mix(a.yz, b.yz, w);\n return vec3<f32>(dist, grad);\n}\n\nfn sminG(a: vec3<f32>, b: vec3<f32>, k: f32) -> vec3<f32> {\n if (u.s2.y > 0.5) { return sminCircularG(a, b, k); }\n return sminQuadraticG(a, b, k);\n}\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// OKLCh gamut clamp + palette sample + breath (BC.W-CARVE6 \u2192 metaball-palette.wgsl)\n// \u2014 spliced AFTER \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} (its matrix source).\n\n// \u2500\u2500 OKLCh gamut clamp (hue-preserving inward chroma clamp \u2014 blob-local) \u2500\u2500\nfn inGamut(lin: vec3<f32>) -> bool {\n return all(lin >= vec3<f32>(0.0)) && all(lin <= vec3<f32>(1.0));\n}\nfn gamutClampOklch(lch: vec3<f32>) -> vec3<f32> {\n let lin = oklabToLinearSrgb(oklchToOklab(lch));\n if (inGamut(lin)) { return lch; }\n var lo = 0.0;\n var hi = lch.y;\n for (var i = 0; i < 16; i = i + 1) {\n let mid = 0.5 * (lo + hi);\n let test = vec3<f32>(lch.x, mid, lch.z);\n if (inGamut(oklabToLinearSrgb(oklchToOklab(test)))) { lo = mid; } else { hi = mid; }\n }\n return vec3<f32>(lch.x, lo, lch.z);\n}\n\n// W11.b \u2014 sample the multi-stop palette at t, OKLab mix + midpoint chroma-bump. Returns\n// an OKLCh stop [L, C, h(rad)]. Falls back to uBaseColor when uStopCount <= 1.\nfn samplePaletteOklch(t: f32) -> vec3<f32> {\n let uStopCount = u.ints.x;\n if (uStopCount <= 1) { return oklabToOklch(srgbToOklab(u.base.rgb)); }\n let n = f32(uStopCount);\n let ft = clamp(t, 0.0, 1.0) * (n - 1.0);\n let i0 = i32(floor(ft));\n let i1 = min(i0 + 1, uStopCount - 1);\n let f = ft - f32(i0);\n let labA = srgbToOklab(u.palette[i0].rgb);\n let labB = srgbToOklab(u.palette[i1].rgb);\n let lab = mix(labA, labB, f);\n var lch = oklabToOklch(lab);\n lch.y = lch.y + 0.03 * sin(PI * f);\n return lch;\n}\n\n// AX.W15 \u2014 de-synced breath (three DETUNED sines at irrational ratios).\nfn breath(phase: f32) -> f32 {\n return (sin(phase) + 0.5 * sin(phase * 1.4444 + 1.7) + 0.28 * sin(phase * 0.31 + 4.1)) / 1.78;\n}\n\n\n// AX.W15 \u2014 the composite SDF field WITH its ANALYTIC GRADIENT vec3(dist, \u2202/\u2202x, \u2202/\u2202y).\nfn sceneDistG(uv: vec2<f32>) -> vec3<f32> {\n let uBodyRadius = u.s0.y;\n let uPulsePhase = u.s0.z;\n let uPulseAmp = u.s0.w;\n let uNoiseAmp = u.s1.x;\n let uNoiseFreq = u.s1.y;\n let uNoiseSpeed = u.s1.z;\n let uWarpAmp = u.s1.w;\n let uSmoothK = u.s2.x;\n let uTime = u.s0.x;\n let uVelocity = u.ptr.zw;\n let uStretch = u.s6.w;\n let uSatCount = u.ints.y;\n let uTrailCount = u.ints.z;\n\n let bodyR = uBodyRadius + breath(uPulsePhase) * uPulseAmp;\n\n // Velocity-driven VOLUME-PRESERVING squash-and-stretch (tanh-saturated).\n var bodyUv = uv;\n var ax = vec2<f32>(1.0, 0.0);\n var perp = vec2<f32>(0.0, 1.0);\n var sa = 1.0;\n let speed = length(uVelocity);\n let squashed = uStretch > 0.0 && speed > 1e-4;\n if (squashed) {\n ax = uVelocity / speed;\n perp = vec2<f32>(-ax.y, ax.x);\n sa = 1.0 + tanh(speed * 1.6) * uStretch;\n bodyUv = vec2<f32>(dot(uv, ax) / sa, dot(uv, perp) * sa);\n }\n\n // Domain-warped FBM displacement WITH its analytic gradient.\n let fbmv = fbmWarpedG(bodyUv * uNoiseFreq + uTime * uNoiseSpeed, 3, uWarpAmp);\n let bodyDisplacement = (fbmv.x - 0.5) * uNoiseAmp;\n let dispGradBody = uNoiseAmp * uNoiseFreq * fbmv.yz;\n\n let bodyG = sdgCircle(bodyUv, vec2<f32>(0.0), bodyR + bodyDisplacement);\n let bodyGradBody = bodyG.yz - dispGradBody;\n\n var bodyGradUv: vec2<f32>;\n if (squashed) {\n let scaled = vec2<f32>(bodyGradBody.x / sa, bodyGradBody.y * sa);\n bodyGradUv = scaled.x * ax + scaled.y * perp;\n } else {\n bodyGradUv = bodyGradBody;\n }\n var d = vec3<f32>(bodyG.x, bodyGradUv);\n\n // Satellites \u2014 smin-merged into the body.\n for (var i = 0; i < MAX_SATS; i = i + 1) {\n if (i >= uSatCount) { break; }\n let s = u.satPos[i];\n var satG = sdgCircle(uv, s.xy, s.z);\n satG.x = satG.x + (1.0 - s.w) * 0.3;\n d = sminG(d, satG, uSmoothK);\n }\n\n // Pointer trail \u2014 a decaying-radius pseudopod.\n for (var i = 0; i < TRAIL_N; i = i + 1) {\n if (i >= uTrailCount) { break; }\n let tp = u.trailPos[i];\n let trailG = sdgCircle(uv, tp.xy, tp.z);\n d = sminG(d, trailG, uSmoothK);\n }\n return d;\n}\n\n// AX.W15 \u2014 the analytic surface normal from the field gradient.\nfn surfaceNormalFromGrad(grad2d: vec2<f32>, d: f32, bodyR: f32) -> vec3<f32> {\n let g = normalize(grad2d + vec2<f32>(1e-6));\n let interior = clamp(-d / max(bodyR, 1e-4), 0.0, 1.0);\n let z = sqrt(max(0.0, 1.0 - (1.0 - interior) * (1.0 - interior)));\n return normalize(vec3<f32>(g * (1.0 - z), z) + vec3<f32>(0.0, 0.0, 1e-6));\n}\n\n// \u2500\u2500 BC.W-GOOBLOB-MEATBALL \u2014 the 2D SDF soft-shadow march (IQ rmshadows improved-penumbra,\n// research/viz/goo-blob.md \u00A72.3). A procedural soft contact shadow that FOLLOWS the\n// irregular metaball silhouette (NOT a hard disc / box shadow). Marches a ray from ro\n// along rd (the in-plane projection of uLightDir), accumulating the closest miss via\n// the Aaltonen penumbra (y = h*h/(2*ph) + d = sqrt(h*h - y*y)) that kills the\n// banding the naive res = min(res, h/(w*t)) shows. CHEAP: 24 steps, re-uses the SAME\n// sceneDistG().x field (NO separate field re-eval, NO FBO/multi-pass \u2014 the procedural\n// field needs none, \u00A72.3). w is the penumbra hardness (inverse light-source size \u2192\n// uShadowSoftness). It is derivative-FREE (no fwidth/dpdx/dpdy), so it is fragment-safe\n// here. Returns 1.0 (fully lit) \u2192 0.0 (fully occluded). \u2500\u2500\nfn softShadow2D(ro: vec2<f32>, rd: vec2<f32>, mint: f32, maxt: f32, w: f32) -> f32 {\n var res = 1.0;\n var ph = 1e20;\n var t = mint;\n for (var i = 0; i < 24; i = i + 1) {\n if (t >= maxt) { break; }\n let h = sceneDistG(ro + rd * t).x;\n if (h < 0.001) { return 0.0; }\n let y = h * h / (2.0 * ph);\n let dd = sqrt(max(h * h - y * y, 0.0));\n res = min(res, dd / (w * max(0.001, t - y)));\n ph = h;\n t = t + h;\n }\n return clamp(res, 0.0, 1.0);\n}\n\n// \u2500\u2500 Full-screen triangle vertex stage (the pilot idiom \u2014 no vertex buffer) \u2500\u2500\nstruct VSOut {\n @builtin(position) pos: vec4<f32>,\n @location(0) uv: vec2<f32>,\n};\n\n@vertex\nfn vs_main(@builtin(vertex_index) vi: u32) -> VSOut {\n var p = vec2<f32>(-1.0, -1.0);\n if (vi == 1u) { p = vec2<f32>(3.0, -1.0); }\n else if (vi == 2u) { p = vec2<f32>(-1.0, 3.0); }\n var out: VSOut;\n out.pos = vec4<f32>(p, 0.0, 1.0);\n // vUv = aPos * 0.5 + 0.5 (the metaball.vert convention).\n out.uv = p * 0.5 + 0.5;\n return out;\n}\n\n// \u2500\u2500 Fragment stage (the main() transcription) \u2500\u2500\n@fragment\nfn fs_main(in: VSOut) -> @location(0) vec4<f32> {\n let uTime = u.s0.x;\n let uBodyRadius = u.s0.y;\n let uPulsePhase = u.s0.z;\n let uPulseAmp = u.s0.w;\n let uMaxReach = u.s2.z;\n let uLit = u.s2.w;\n let uPointerActive = u.s7.x;\n let uPointerAttraction = u.s7.y;\n let uPointerStrength = u.s7.z;\n // BC.W-GOOBLOB-PLAIN \u2014 the STAGE-1 gate (1.0 = the plain shadowless fill-only floor).\n let uStage = u.s7.w;\n let uPointer = u.ptr.xy;\n let uHueRange = u.s5.z;\n let uSatShift = u.s5.w;\n let uBrightnessShift = u.s6.x;\n let uColorNoiseFreq = u.s6.y;\n let uColorNoiseSpeed = u.s6.z;\n let uIridescence = u.s4.x;\n let uIridHue = u.s4.y;\n let uIridSpeed = u.s4.z;\n let uSssScale = u.s4.w;\n let uSssPower = u.s5.x;\n let uCoreGlow = u.s5.y;\n let uSpecStrength = u.s3.x;\n let uSpecShininess = u.s3.y;\n let uRimPower = u.s3.z;\n let uRimStrength = u.s3.w;\n let uLightDir = u.light.xyz;\n let uRimColor = u.rim.rgb;\n // BC.W-GOOBLOB-MEATBALL \u2014 the soft-shadow gate + penumbra hardness (res.z/res.w lanes).\n let uShadow = u.res.z;\n let uShadowSoftness = u.res.w;\n\n var uv = in.uv - 0.5;\n\n // PRE-FBM bounding early-out \u2014 transparent WRITE (not a discard).\n if (dot(uv, uv) > uMaxReach * uMaxReach) {\n return vec4<f32>(0.0);\n }\n\n // Pointer deformation \u2014 sign per AY.W-BLOB-CONFIG D2.\n if (uPointerActive > 0.5) {\n let pointerDir = uPointer - uv;\n let pointerDist = length(pointerDir);\n let influence = smoothstep(0.5, 0.0, pointerDist) * uPointerAttraction * uPointerStrength;\n uv = uv + normalize(pointerDir + vec2<f32>(1e-6)) * influence;\n }\n\n let bodyR = uBodyRadius + breath(uPulsePhase) * uPulseAmp;\n\n // Composite domain-warped membrane field WITH its analytic gradient.\n let scene = sceneDistG(uv);\n let d = scene.x;\n let fieldGrad = scene.yz;\n\n // \u2500\u2500 fwidth SITE #1 (metaball.frag.ts line 266) \u2014 AA-edge half-width from the SDF\n // screen-space gradient. The WGSL fragment-stage fwidth() transcription. \u2500\u2500\n let aa = max(fwidth(d), 1e-6);\n let alpha = 1.0 - smoothstep(-aa, aa, d);\n\n // \u2500\u2500 BC.W-GOOBLOB-MEATBALL \u2014 the WGSL uniformity STRUCTURAL fix (the meatball-armer).\n // The Toksvig screen-space derivative (fwidth SITE #2) is hoisted HERE, into the SAME\n // uniform control flow fwidth(d) above already arms in (top-level fs_main, before the\n // per-fragment alpha < 0.001 early-return and the uLit/uShadow non-uniform branches).\n // WGSL uniformity analysis rejects a fwidth() reached only through a return predicated\n // on a per-fragment value (the alpha < 0.001 early-out) nested under further branches\n // \u2014 exactly the BB residual that kept the normal-derivative inside the lit branch from\n // compiling, so the WGSL primary never armed and GooBlob fell to the WebGL2 net. Nh is\n // the uniform-flow surface normal computed for this derivative ONLY (byte-identical to\n // the lit block's own N = surfaceNormalFromGrad(...) below \u2014 the SAME inputs, so\n // nVar = length(fwidth(Nh)) IS the Toksvig clamp the lit block reads); the named lit-\n // block N stays AFTER the uStage early-return (the STAGE-1 floor reaches no lit work).\n // nVar is a pure uniform-flow value the lit block READS \u2014 no derivative in non-uniform\n // flow; the math is byte-identical to the GLSL fallback's Toksvig clamp, only its\n // EVALUATION POINT moved. The shadow march (T2) reuses d (the same sceneDistG().x).\n let Nh = surfaceNormalFromGrad(fieldGrad, d, bodyR);\n // \u2500\u2500 fwidth SITE #2 (metaball.frag.ts line 364) \u2014 Toksvig normal-variance specular\n // clamp, the WGSL fragment-stage fwidth() of the surface normal. NOW in uniform\n // control flow (the structural fix), so the WGSL primary ARMS + paints the full lit\n // creature instead of falling to the stripped WebGL2 fallback. \u2500\u2500\n let nVar = length(fwidth(Nh));\n\n if (alpha < 0.001) {\n return vec4<f32>(0.0);\n }\n\n // Edit #4 \u2014 perceptually-uniform OKLCh variation.\n let colorNoise = fbm(uv * uColorNoiseFreq + uTime * uColorNoiseSpeed, 3);\n var oklch = samplePaletteOklch(colorNoise);\n\n oklch.z = oklch.z + (colorNoise - 0.5) * uHueRange * (PI / 180.0);\n oklch.y = max(oklch.y + (colorNoise - 0.5) * uSatShift, 0.0);\n oklch.x = clamp(oklch.x + uBrightnessShift, 0.0, 1.0);\n\n // \u2500\u2500 BC.W-GOOBLOB-PLAIN \u2014 the STAGE-1 stripped floor (variant=blob). \u2500\u2500\n // The minimal verifiable floor: SDF + smin (the meatball field, already in d/\n // alpha above) + fwidth-AA (the crisp alpha above) + warm-cream fill. NO surface\n // normal, NO Fresnel, NO lit glint, NO iridescence, NO fake-SSS, NO shadow \u2014\n // deliberately FLAT. It returns BEFORE any of the STAGE-2 dressing is reached. The\n // STAGE-1 path simply never READS the hoisted Nh/nVar or the lit/shadow blocks; the\n // normal-derivative is now in UNIFORM control flow above (BC.W-GOOBLOB-MEATBALL \u2014 the\n // structural armer), so BOTH the STAGE-1 floor AND the STAGE-2 lit path arm on Metal\n // (the BB residual that kept STAGE 2 falling to the WebGL2 net is CLOSED). The\n // teaching contrast: this is the \"it renders, it meatballs, it works on Safari\"\n // floor STAGE 2 layers the lit/shadow onto via the SAME uniforms.\n if (uStage > 0.5) {\n let okl1 = gamutClampOklch(oklch);\n var lin1 = oklabToLinearSrgb(oklchToOklab(okl1));\n var rgb1 = clamp(linearToSrgb(lin1), vec3<f32>(0.0), vec3<f32>(1.0));\n let fc1 = in.pos.xy;\n let ign1 = fract(52.9829189 * fract(dot(fc1, vec2<f32>(0.06711056, 0.00583715))));\n rgb1 = clamp(rgb1 + (ign1 - 0.5) / 255.0, vec3<f32>(0.0), vec3<f32>(1.0));\n return vec4<f32>(rgb1 * alpha, alpha);\n }\n\n // The named surface normal the lit/iridescence/SSS blocks read (byte-identical inputs to\n // the hoisted Nh above \u2014 the Toksvig nVar = length(fwidth(Nh)) IS this N's screen-space\n // variance). It sits AFTER the uStage early-return so the STAGE-1 floor reaches no lit work.\n let N = surfaceNormalFromGrad(fieldGrad, d, bodyR);\n let V = vec3<f32>(0.0, 0.0, 1.0);\n let thickness = clamp(-d / max(bodyR, 1e-4), 0.0, 1.0);\n let fres = pow(1.0 - max(dot(N, V), 0.0), 2.5);\n\n // \u2500\u2500 W11.a iridescence \u2014 warm-biased IQ cosine palette driving OKLCh HUE \u2500\u2500\n if (uIridescence > 0.0) {\n let t = fres + 0.3 * colorNoise + uTime * uIridSpeed;\n let iridHue = uIridHue + 0.18 * PI * cos(2.0 * PI * t);\n let w = fres * uIridescence;\n oklch.z = mix(oklch.z, iridHue, w);\n oklch.y = min(oklch.y + 0.04 * w, oklch.y + 0.08);\n oklch.x = min(oklch.x + 0.05 * w, 1.0);\n }\n\n // \u2500\u2500 W11.a fake subsurface translucency \u2014 thickness inner-glow + back-light \u2500\u2500\n if (uCoreGlow > 0.0 || uSssScale > 0.0) {\n oklch.x = min(oklch.x + uCoreGlow * (1.0 - exp(-3.0 * thickness)), 1.0);\n let L = normalize(uLightDir + vec3<f32>(1e-6));\n let back = pow(clamp(dot(V, -(L + N * thickness)), 0.0, 1.0), uSssPower);\n let sss = back * uSssScale * (1.0 - thickness);\n oklch.x = min(oklch.x + sss, 1.0);\n oklch.z = oklch.z + sss * 0.1 * (1.0 - thickness);\n }\n\n // \u2500\u2500 BC.W-GOOBLOB-MEATBALL \u2014 the soft contact shadow (T2). A procedural soft shadow that\n // FOLLOWS the irregular silhouette: march from this fragment's uv toward the in-plane\n // projection of uLightDir; where the metaball field occludes the light (the body\n // shadows itself opposite the light, a satellite shadows the body across the neck), the\n // march returns < 1 and DARKENS the OKLCh L \u2014 a soft grounded contact band UNDER the\n // dome, congruent with (but PROCEDURAL, silhouette-following, unlike) the CSS gel-dome\n // drop-shadow. Concentrated on the AWAY-facing lower rim (an away-facing weight \u00D7 a\n // thin-rim Gaussian band) so the deep-lit interior + the light-facing edge stay bright\n // and the grounded shadow reads at the lower silhouette edge \u2014 the warm-cream body mean\n // holds. Gated uShadow > 0.5; variant=blob (STAGE 1) ships shadowless. \u2500\u2500\n if (uShadow > 0.5) {\n let L2 = normalize(uLightDir.xy + vec2<f32>(1e-6));\n // w increases with the inverse light-source size \u2192 uShadowSoftness (a harder penumbra at a\n // higher value). Start the march just off the surface so a fragment never self-shadows\n // at t=0; cap the reach at the body span.\n let sh = softShadow2D(uv, L2, max(aa, 0.004), bodyR * 1.5, max(uShadowSoftness, 4.0));\n // The contact band sits on the LOWER rim (the side AWAY from the light) \u2014 gated by\n // dot(fieldGrad, L2) < 0 (the rim facing away from L2) AND the thin-rim weight\n // (a Gaussian band peaking at thickness \u2248 0.18 so the deep-lit interior + the\n // light-facing edge stay BRIGHT \u2014 the warm-cream body mean holds). The 0.20 cap keeps\n // it a soft GROUNDING whisper, never a gouge (the warm-cream identity + the\n // proof:blob-warm-default floor hold).\n let away = clamp(-dot(normalize(fieldGrad + vec2<f32>(1e-6)), L2), 0.0, 1.0);\n let band = exp(-pow((thickness - 0.18) / 0.16, 2.0));\n let shadowDarken = (1.0 - sh) * away * band * 0.20;\n oklch.x = max(oklch.x - shadowDarken, 0.0);\n }\n\n oklch = gamutClampOklch(oklch);\n\n var lin = oklabToLinearSrgb(oklchToOklab(oklch));\n\n // \u2500\u2500 W9.b lit glass surface \u2014 Blinn-Phong glint + Fresnel rim, in LINEAR \u2500\u2500\n if (uLit > 0.5) {\n let L = normalize(uLightDir + vec3<f32>(1e-6));\n let H = normalize(L + V);\n\n let warmCream = oklabToLinearSrgb(oklchToOklab(vec3<f32>(0.97, 0.03, radians(85.0))));\n\n // \u2500\u2500 fwidth SITE #2 \u2014 Toksvig normal-variance specular clamp. nVar is the HOISTED\n // length(fwidth(N)) (BC.W-GOOBLOB-MEATBALL \u2014 computed once at the top of fs_main\n // in uniform control flow, so the WGSL primary ARMS on Metal). The math is\n // byte-identical to the GLSL fallback (length(fwidth(N))); only its evaluation\n // point moved out of this non-uniform if (uLit > 0.5) branch. \u2500\u2500\n let shininess = uSpecShininess / (1.0 + 24.0 * nVar);\n let energyNorm = (shininess + 2.0) / 8.0;\n let spec = pow(max(dot(N, H), 0.0), shininess) * uSpecStrength * energyNorm;\n\n var rimOkl = oklabToOklch(srgbToOklab(uRimColor));\n let bodyL = oklch.x;\n let dL = abs(rimOkl.x - bodyL);\n let lack = clamp((0.22 - dL) / 0.22, 0.0, 1.0);\n // target is a WGSL RESERVED word (W3C WGSL 16.2) so a \"var target\" declaration is an\n // invalid identifier: the shader module fails to compile and the WGSL primary never\n // arms (the GooBlob reserved-keyword bug BC.W-WEBGPU-EVERYWHERE W7 catches). Renamed to\n // a valid identifier; the math + the value are byte-identical.\n var targetL = 0.18;\n if (bodyL < 0.5) { targetL = 0.92; }\n rimOkl.x = clamp(mix(rimOkl.x, targetL, lack), 0.0, 1.0);\n rimOkl.y = rimOkl.y * mix(1.0, 0.5, lack);\n let rimLin = oklabToLinearSrgb(oklchToOklab(rimOkl));\n\n let rimFres = pow(1.0 - max(dot(N, V), 0.0), uRimPower);\n let rim = rimFres * uRimStrength * (1.0 - 0.6 * thickness);\n\n var highlight = max(warmCream * spec, rimLin * rim);\n highlight = min(highlight, vec3<f32>(0.85));\n lin = lin + highlight;\n }\n\n var rgb = clamp(linearToSrgb(lin), vec3<f32>(0.0), vec3<f32>(1.0));\n\n // IGN dither \u2014 1-LSB triangular dither in DISPLAY space, AFTER linearToSrgb.\n let fragCoord = in.pos.xy;\n let ign = fract(52.9829189 * fract(dot(fragCoord, vec2<f32>(0.06711056, 0.00583715))));\n rgb = clamp(rgb + (ign - 0.5) / 255.0, vec3<f32>(0.0), vec3<f32>(1.0));\n\n // premultiply AFTER the OETF: straight-alpha gamma \u2192 premultiplied.\n return vec4<f32>(rgb * alpha, alpha);\n}\n";
|
|
1
|
+
export declare const METABALL_WGSL = "\nconst MAX_SATS: i32 = 4;\nconst TRAIL_N: i32 = 15;\nconst MAX_BLOB_STOPS: i32 = 4;\nconst PI: f32 = 3.141592653589793;\n\n// \u2500\u2500 Uniforms (the typed-struct source-of-truth \u2014 see uniformBridgeWGPU.ts) \u2500\u2500\n// Scalars packed into vec4 lanes; per-satellite / per-trail / per-palette rows packed\n// into a vec4 so the array stride is the natural 16 bytes (no std140 stride trap \u2014 the\n// parity-blowout suspect the wave's \u00A7Triumvirate names).\nstruct Uniforms {\n // s0: (uTime, uBodyRadius, uPulsePhase, uPulseAmp)\n s0: vec4<f32>,\n // s1: (uNoiseAmp, uNoiseFreq, uNoiseSpeed, uWarpAmp)\n s1: vec4<f32>,\n // s2: (uSmoothK, uMerge, uMaxReach, uLit)\n s2: vec4<f32>,\n // s3: (uSpecStrength, uSpecShininess, uRimPower, uRimStrength)\n s3: vec4<f32>,\n // s4: (uIridescence, uIridHue, uIridSpeed, uSssScale)\n s4: vec4<f32>,\n // s5: (uSssPower, uCoreGlow, uHueRange, uSatShift)\n s5: vec4<f32>,\n // s6: (uBrightnessShift, uColorNoiseFreq, uColorNoiseSpeed, uStretch)\n s6: vec4<f32>,\n // s7: (uPointerActive, uPointerAttraction, uPointerStrength, uStage)\n // BC.W-GOOBLOB-PLAIN \u2014 uStage gates the STAGE-1 stripped floor: 1.0 = the plain\n // shadowless lightless fill-only floor (variant=\"blob\"); 0.0 = the full lit\n // pipeline (variant=\"meatball\" / STAGE 2). It rides the spare s7.w lane the typed-\n // struct SoT (uniformBridgeWGPU.ts) reserved.\n s7: vec4<f32>,\n // ptr: (uPointer.x, uPointer.y, uVelocity.x, uVelocity.y)\n ptr: vec4<f32>,\n // base: (uBaseColor.rgb, _pad)\n base: vec4<f32>,\n // rim: (uRimColor.rgb, _pad)\n rim: vec4<f32>,\n // light: (uLightDir.xyz, _pad)\n light: vec4<f32>,\n // res: (uResolution.x, uResolution.y, uShadow, uShadowSoftness)\n // BC.W-GOOBLOB-MEATBALL \u2014 the soft-shadow march rides the spare res.z/res.w lanes the\n // typed-struct SoT (uniformBridgeWGPU.ts) reserved (the EXTEND, never a re-fork): res.z\n // = uShadow (1.0 = the variant=meatball shadow ON), res.w = uShadowSoftness (the\n // penumbra hardness, inverse light-source size \u2192 4-48).\n res: vec4<f32>,\n // ints: (uStopCount, uSatCount, uTrailCount, _pad)\n ints: vec4<i32>,\n palette: array<vec4<f32>, 4>,\n satPos: array<vec4<f32>, 4>, // (pos.x, pos.y, radius, opacity)\n trailPos: array<vec4<f32>, 15>, // (pos.x, pos.y, radius, _pad)\n};\n\n@group(0) @binding(0) var<uniform> u: Uniforms;\n\n// Noise + FBM (BC.W-CARVE6 -> metaball-noise.wgsl) \u2014 spliced AFTER the FBM_ROT_WGSL chunk\n// below. NB: do NOT name the chunk with a template-interpolation form in a WGSL comment \u2014\n// it injects the whole multi-line chunk into this // comment line and breaks the parse\n// (BD.W-VIZ-BROKEN-FIX D3c).\nconst FBM_ROT: mat2x2<f32> = mat2x2<f32>(0.8, 0.6, -0.6, 0.8);\n\nconst FBM_LACUNARITY: f32 = 1.8;\nconst FBM_GAIN: f32 = 0.42;\n\n// \u2500\u2500 Noise (blob-LOCAL 3D-p3 hash + IQ analytic-derivative gradient noise) \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\n// IQ analytic-derivative gradient noise \u2014 value in .x, ANALYTIC gradient (d/dx, d/dy) in\n// .yz, from one eval. The quintic fade has a continuous 2nd derivative.\nfn noised(p: vec2<f32>) -> vec3<f32> {\n let i = floor(p);\n let f = fract(p);\n let uu = f * f * f * (f * (f * 6.0 - 15.0) + 10.0);\n let du = 30.0 * f * f * (f * (f - 2.0) + 1.0);\n\n let ga = -1.0 + 2.0 * vec2<f32>(hash21(i + vec2<f32>(0.0, 0.0)), hash21(i + vec2<f32>(7.3, 0.0)));\n let gb = -1.0 + 2.0 * vec2<f32>(hash21(i + vec2<f32>(1.0, 0.0)), hash21(i + vec2<f32>(8.3, 0.0)));\n let gc = -1.0 + 2.0 * vec2<f32>(hash21(i + vec2<f32>(0.0, 1.0)), hash21(i + vec2<f32>(7.3, 1.0)));\n let gd = -1.0 + 2.0 * vec2<f32>(hash21(i + vec2<f32>(1.0, 1.0)), hash21(i + vec2<f32>(8.3, 1.0)));\n\n let va = dot(ga, f - vec2<f32>(0.0, 0.0));\n let vb = dot(gb, f - vec2<f32>(1.0, 0.0));\n let vc = dot(gc, f - vec2<f32>(0.0, 1.0));\n let vd = dot(gd, f - vec2<f32>(1.0, 1.0));\n\n let n = va + uu.x * (vb - va) + uu.y * (vc - va) + uu.x * uu.y * (va - vb - vc + vd);\n let value = 0.5 + 0.5 * n;\n\n let grad =\n ga + uu.x * (gb - ga) + uu.y * (gc - ga) + uu.x * uu.y * (ga - gb - gc + gd) +\n du * (vec2<f32>(uu.y, uu.x) * (va - vb - vc + vd) + vec2<f32>(vb, vc) - va);\n return vec3<f32>(value, 0.5 * grad);\n}\n\nfn fbm(p0: vec2<f32>, octaves: i32) -> f32 {\n var value = 0.0;\n var amp = 0.5;\n var freq = 1.0;\n var p = p0;\n for (var i = 0; i < 4; i = i + 1) {\n if (i >= octaves) { break; }\n value = value + amp * noised(p * freq).x;\n p = FBM_ROT * p;\n freq = freq * FBM_LACUNARITY;\n amp = amp * FBM_GAIN;\n }\n return value;\n}\n\n// FBM with ANALYTIC GRADIENT \u2014 value in .x, \u2202/\u2202x, \u2202/\u2202y in .yz. The gradient accumulates\n// noised()'s analytic gradient per octave, chain-ruled through the per-octave frequency\n// scale AND the FBM_ROT rotation (the keystone feed for the analytic surface normal).\nfn fbmG(p: vec2<f32>, octaves: i32) -> vec3<f32> {\n var value = 0.0;\n var grad = vec2<f32>(0.0, 0.0);\n var amp = 0.5;\n var freq = 1.0;\n var rotAccum = mat2x2<f32>(1.0, 0.0, 0.0, 1.0);\n var pp = p;\n for (var i = 0; i < 4; i = i + 1) {\n if (i >= octaves) { break; }\n let n = noised(pp * freq);\n value = value + amp * n.x;\n grad = grad + amp * freq * (transpose(rotAccum) * n.yz);\n pp = FBM_ROT * pp;\n freq = freq * FBM_LACUNARITY;\n amp = amp * FBM_GAIN;\n rotAccum = FBM_ROT * rotAccum;\n }\n return vec3<f32>(value, grad);\n}\n\n// One domain-warp pass with the ANALYTIC GRADIENT carried (warp-Jacobian approximation).\nfn fbmWarpedG(p: vec2<f32>, octaves: i32, warpAmp: f32) -> vec3<f32> {\n if (warpAmp <= 0.0) { return fbmG(p, octaves); }\n let q = vec2<f32>(fbm(p + vec2<f32>(0.0, 0.0), octaves),\n fbm(p + vec2<f32>(5.2, 1.3), octaves));\n return fbmG(p + warpAmp * (q - 0.5), octaves);\n}\n\n\n// \u2500\u2500 SDF body (value+gradient circle + the IQ normalized smin, value+gradient form) \u2500\u2500\nfn sdgCircle(p: vec2<f32>, center: vec2<f32>, radius: f32) -> vec3<f32> {\n let d = p - center;\n let len = length(d);\n var grad = vec2<f32>(0.0, 1.0);\n if (len > 1e-6) { grad = d / len; }\n return vec3<f32>(len - radius, grad);\n}\n\nfn sminQuadraticG(a: vec3<f32>, b: vec3<f32>, k0: f32) -> vec3<f32> {\n let k = k0 * 4.0;\n let h = max(k - abs(a.x - b.x), 0.0) / k;\n let m = h * h * k * 0.25;\n var w = 1.0 - 0.5 * h * h;\n if (a.x < b.x) { w = 0.5 * h * h; }\n let dist = min(a.x, b.x) - m;\n let grad = mix(a.yz, b.yz, w);\n return vec3<f32>(dist, grad);\n}\n\nfn sminCircularG(a: vec3<f32>, b: vec3<f32>, k0: f32) -> vec3<f32> {\n let k = k0 * (1.0 / (1.0 - sqrt(0.5)));\n let h = max(k - abs(a.x - b.x), 0.0) / k;\n let m = k * 0.5 * (1.0 + h - sqrt(1.0 - h * (h - 2.0)));\n var w = 1.0 - 0.5 * h;\n if (a.x < b.x) { w = 0.5 * h; }\n let dist = min(a.x, b.x) - m;\n let grad = mix(a.yz, b.yz, w);\n return vec3<f32>(dist, grad);\n}\n\nfn sminG(a: vec3<f32>, b: vec3<f32>, k: f32) -> vec3<f32> {\n if (u.s2.y > 0.5) { return sminCircularG(a, b, k); }\n return sminQuadraticG(a, b, k);\n}\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// OKLCh gamut clamp + palette sample + breath (BC.W-CARVE6 -> metaball-palette.wgsl)\n// \u2014 spliced AFTER the OKLCH_MATRICES_WGSL chunk above (its matrix source). NB: do NOT\n// write the chunk's identifier with a template-interpolation form in a WGSL comment \u2014 it\n// would inject the whole multi-line matrices chunk INTO this // comment line and break the\n// parse at the first injected newline (BD.W-VIZ-BROKEN-FIX D3c \u2014 the live WGSL syntax error\n// that silently fell every metaball/goo-dot to the WebGL2 net, masking the WGSL primary).\n\n// \u2500\u2500 OKLCh gamut clamp (hue-preserving inward chroma clamp \u2014 blob-local) \u2500\u2500\nfn inGamut(lin: vec3<f32>) -> bool {\n return all(lin >= vec3<f32>(0.0)) && all(lin <= vec3<f32>(1.0));\n}\nfn gamutClampOklch(lch: vec3<f32>) -> vec3<f32> {\n let lin = oklabToLinearSrgb(oklchToOklab(lch));\n if (inGamut(lin)) { return lch; }\n var lo = 0.0;\n var hi = lch.y;\n for (var i = 0; i < 16; i = i + 1) {\n let mid = 0.5 * (lo + hi);\n let test = vec3<f32>(lch.x, mid, lch.z);\n if (inGamut(oklabToLinearSrgb(oklchToOklab(test)))) { lo = mid; } else { hi = mid; }\n }\n return vec3<f32>(lch.x, lo, lch.z);\n}\n\n// W11.b \u2014 sample the multi-stop palette at t, OKLab mix + midpoint chroma-bump. Returns\n// an OKLCh stop [L, C, h(rad)]. Falls back to uBaseColor when uStopCount <= 1.\nfn samplePaletteOklch(t: f32) -> vec3<f32> {\n let uStopCount = u.ints.x;\n if (uStopCount <= 1) { return oklabToOklch(srgbToOklab(u.base.rgb)); }\n let n = f32(uStopCount);\n let ft = clamp(t, 0.0, 1.0) * (n - 1.0);\n let i0 = i32(floor(ft));\n let i1 = min(i0 + 1, uStopCount - 1);\n let f = ft - f32(i0);\n let labA = srgbToOklab(u.palette[i0].rgb);\n let labB = srgbToOklab(u.palette[i1].rgb);\n let lab = mix(labA, labB, f);\n var lch = oklabToOklch(lab);\n lch.y = lch.y + 0.03 * sin(PI * f);\n return lch;\n}\n\n// AX.W15 \u2014 de-synced breath (three DETUNED sines at irrational ratios).\nfn breath(phase: f32) -> f32 {\n return (sin(phase) + 0.5 * sin(phase * 1.4444 + 1.7) + 0.28 * sin(phase * 0.31 + 4.1)) / 1.78;\n}\n\n\n// AX.W15 \u2014 the composite SDF field WITH its ANALYTIC GRADIENT vec3(dist, \u2202/\u2202x, \u2202/\u2202y).\nfn sceneDistG(uv: vec2<f32>) -> vec3<f32> {\n let uBodyRadius = u.s0.y;\n let uPulsePhase = u.s0.z;\n let uPulseAmp = u.s0.w;\n let uNoiseAmp = u.s1.x;\n let uNoiseFreq = u.s1.y;\n let uNoiseSpeed = u.s1.z;\n let uWarpAmp = u.s1.w;\n let uSmoothK = u.s2.x;\n let uTime = u.s0.x;\n let uVelocity = u.ptr.zw;\n let uStretch = u.s6.w;\n let uSatCount = u.ints.y;\n let uTrailCount = u.ints.z;\n\n let bodyR = uBodyRadius + breath(uPulsePhase) * uPulseAmp;\n\n // Velocity-driven VOLUME-PRESERVING squash-and-stretch (tanh-saturated).\n var bodyUv = uv;\n var ax = vec2<f32>(1.0, 0.0);\n var perp = vec2<f32>(0.0, 1.0);\n var sa = 1.0;\n let speed = length(uVelocity);\n let squashed = uStretch > 0.0 && speed > 1e-4;\n if (squashed) {\n ax = uVelocity / speed;\n perp = vec2<f32>(-ax.y, ax.x);\n sa = 1.0 + tanh(speed * 1.6) * uStretch;\n bodyUv = vec2<f32>(dot(uv, ax) / sa, dot(uv, perp) * sa);\n }\n\n // Domain-warped FBM displacement WITH its analytic gradient.\n let fbmv = fbmWarpedG(bodyUv * uNoiseFreq + uTime * uNoiseSpeed, 3, uWarpAmp);\n let bodyDisplacement = (fbmv.x - 0.5) * uNoiseAmp;\n let dispGradBody = uNoiseAmp * uNoiseFreq * fbmv.yz;\n\n let bodyG = sdgCircle(bodyUv, vec2<f32>(0.0), bodyR + bodyDisplacement);\n let bodyGradBody = bodyG.yz - dispGradBody;\n\n var bodyGradUv: vec2<f32>;\n if (squashed) {\n let scaled = vec2<f32>(bodyGradBody.x / sa, bodyGradBody.y * sa);\n bodyGradUv = scaled.x * ax + scaled.y * perp;\n } else {\n bodyGradUv = bodyGradBody;\n }\n var d = vec3<f32>(bodyG.x, bodyGradUv);\n\n // Satellites \u2014 smin-merged into the body.\n for (var i = 0; i < MAX_SATS; i = i + 1) {\n if (i >= uSatCount) { break; }\n let s = u.satPos[i];\n var satG = sdgCircle(uv, s.xy, s.z);\n satG.x = satG.x + (1.0 - s.w) * 0.3;\n d = sminG(d, satG, uSmoothK);\n }\n\n // Pointer trail \u2014 a decaying-radius pseudopod.\n for (var i = 0; i < TRAIL_N; i = i + 1) {\n if (i >= uTrailCount) { break; }\n let tp = u.trailPos[i];\n let trailG = sdgCircle(uv, tp.xy, tp.z);\n d = sminG(d, trailG, uSmoothK);\n }\n return d;\n}\n\n// AX.W15 \u2014 the analytic surface normal from the field gradient.\nfn surfaceNormalFromGrad(grad2d: vec2<f32>, d: f32, bodyR: f32) -> vec3<f32> {\n let g = normalize(grad2d + vec2<f32>(1e-6));\n let interior = clamp(-d / max(bodyR, 1e-4), 0.0, 1.0);\n let z = sqrt(max(0.0, 1.0 - (1.0 - interior) * (1.0 - interior)));\n return normalize(vec3<f32>(g * (1.0 - z), z) + vec3<f32>(0.0, 0.0, 1e-6));\n}\n\n// \u2500\u2500 BC.W-GOOBLOB-MEATBALL \u2014 the 2D SDF soft-shadow march (IQ rmshadows improved-penumbra,\n// research/viz/goo-blob.md \u00A72.3). A procedural soft contact shadow that FOLLOWS the\n// irregular metaball silhouette (NOT a hard disc / box shadow). Marches a ray from ro\n// along rd (the in-plane projection of uLightDir), accumulating the closest miss via\n// the Aaltonen penumbra (y = h*h/(2*ph) + d = sqrt(h*h - y*y)) that kills the\n// banding the naive res = min(res, h/(w*t)) shows. CHEAP: 24 steps, re-uses the SAME\n// sceneDistG().x field (NO separate field re-eval, NO FBO/multi-pass \u2014 the procedural\n// field needs none, \u00A72.3). w is the penumbra hardness (inverse light-source size \u2192\n// uShadowSoftness). It is derivative-FREE (no fwidth/dpdx/dpdy), so it is fragment-safe\n// here. Returns 1.0 (fully lit) \u2192 0.0 (fully occluded). \u2500\u2500\nfn softShadow2D(ro: vec2<f32>, rd: vec2<f32>, mint: f32, maxt: f32, w: f32) -> f32 {\n var res = 1.0;\n var ph = 1e20;\n var t = mint;\n for (var i = 0; i < 24; i = i + 1) {\n if (t >= maxt) { break; }\n let h = sceneDistG(ro + rd * t).x;\n if (h < 0.001) { return 0.0; }\n let y = h * h / (2.0 * ph);\n let dd = sqrt(max(h * h - y * y, 0.0));\n res = min(res, dd / (w * max(0.001, t - y)));\n ph = h;\n t = t + h;\n }\n return clamp(res, 0.0, 1.0);\n}\n\n// \u2500\u2500 Full-screen triangle vertex stage (the pilot idiom \u2014 no vertex buffer) \u2500\u2500\nstruct VSOut {\n @builtin(position) pos: vec4<f32>,\n @location(0) uv: vec2<f32>,\n};\n\n@vertex\nfn vs_main(@builtin(vertex_index) vi: u32) -> VSOut {\n var p = vec2<f32>(-1.0, -1.0);\n if (vi == 1u) { p = vec2<f32>(3.0, -1.0); }\n else if (vi == 2u) { p = vec2<f32>(-1.0, 3.0); }\n var out: VSOut;\n out.pos = vec4<f32>(p, 0.0, 1.0);\n // vUv = aPos * 0.5 + 0.5 (the metaball.vert convention).\n out.uv = p * 0.5 + 0.5;\n return out;\n}\n\n// \u2500\u2500 Fragment stage (the main() transcription) \u2500\u2500\n@fragment\nfn fs_main(in: VSOut) -> @location(0) vec4<f32> {\n let uTime = u.s0.x;\n let uBodyRadius = u.s0.y;\n let uPulsePhase = u.s0.z;\n let uPulseAmp = u.s0.w;\n let uMaxReach = u.s2.z;\n let uLit = u.s2.w;\n let uPointerActive = u.s7.x;\n let uPointerAttraction = u.s7.y;\n let uPointerStrength = u.s7.z;\n // BC.W-GOOBLOB-PLAIN \u2014 the STAGE-1 gate (1.0 = the plain shadowless fill-only floor).\n let uStage = u.s7.w;\n // BD.W-GOO-CAROUSEL-DECK \u2014 the blob to meatball SHADING-MORPH scalar (the base.w pad\n // lane; the typed-struct SoT writes it). 0 = flat blob, 1 = lit meatball, in-between\n // lerps the surface shading (the smin geometry is shared).\n let uMorphT = clamp(u.base.w, 0.0, 1.0);\n let uPointer = u.ptr.xy;\n let uHueRange = u.s5.z;\n let uSatShift = u.s5.w;\n let uBrightnessShift = u.s6.x;\n let uColorNoiseFreq = u.s6.y;\n let uColorNoiseSpeed = u.s6.z;\n let uIridescence = u.s4.x;\n let uIridHue = u.s4.y;\n let uIridSpeed = u.s4.z;\n let uSssScale = u.s4.w;\n let uSssPower = u.s5.x;\n let uCoreGlow = u.s5.y;\n let uSpecStrength = u.s3.x;\n let uSpecShininess = u.s3.y;\n let uRimPower = u.s3.z;\n let uRimStrength = u.s3.w;\n let uLightDir = u.light.xyz;\n let uRimColor = u.rim.rgb;\n // BC.W-GOOBLOB-MEATBALL \u2014 the soft-shadow gate + penumbra hardness (res.z/res.w lanes).\n let uShadow = u.res.z;\n let uShadowSoftness = u.res.w;\n\n var uv = in.uv - 0.5;\n\n // PRE-FBM bounding test (BD.W-VIZ-BROKEN-FIX D3c \u2014 the uniformity fix). The GLSL fallback\n // EARLY-RETURNS transparent here (a perf skip of the FBM border); WGSL CANNOT \u2014 an early\n // return predicated on the per-fragment uv makes the fwidth(d)/fwidth(Nh) calls below\n // reachable only through non-uniform control flow, which the WGSL uniformity analyzer\n // REJECTS (fwidth must only be called from uniform control flow) so the metaball WGSL\n // module never compiled and every GooBlob + goo-dot fell silently to the WebGL2 net (the\n // \"broken TOTALLY\" the user reports, the un-exercised Safari-primary surface). So the\n // bound is folded into the FINAL alpha (a flag, NOT a control-flow return): the derivative\n // builtins stay in UNIFORM control flow, and an outside fragment writes transparent at the\n // end \u2014 gestalt-identical to the GLSL early-out, just without the WGSL-illegal pre-\n // derivative return. sceneDistG is derivative-FREE so running it on the border costs only\n // ALU (no correctness hazard); the real GPU swallows it.\n let inBounds = dot(uv, uv) <= uMaxReach * uMaxReach;\n\n // Pointer deformation \u2014 sign per AY.W-BLOB-CONFIG D2.\n if (uPointerActive > 0.5) {\n let pointerDir = uPointer - uv;\n let pointerDist = length(pointerDir);\n let influence = smoothstep(0.5, 0.0, pointerDist) * uPointerAttraction * uPointerStrength;\n uv = uv + normalize(pointerDir + vec2<f32>(1e-6)) * influence;\n }\n\n let bodyR = uBodyRadius + breath(uPulsePhase) * uPulseAmp;\n\n // Composite domain-warped membrane field WITH its analytic gradient.\n let scene = sceneDistG(uv);\n let d = scene.x;\n let fieldGrad = scene.yz;\n\n // \u2500\u2500 fwidth SITE #1 (metaball.frag.ts line 266) \u2014 AA-edge half-width from the SDF\n // screen-space gradient. The WGSL fragment-stage fwidth() transcription. In UNIFORM\n // control flow (no early return precedes it \u2014 the bounding test above is a flag). \u2500\u2500\n let aa = max(fwidth(d), 1e-6);\n // The bounding test (D3c) folds in here: an out-of-bounds fragment is forced transparent\n // (the GLSL early-out's transparent WRITE, expressed as an alpha gate, not a return).\n let alpha = (1.0 - smoothstep(-aa, aa, d)) * select(0.0, 1.0, inBounds);\n\n // \u2500\u2500 BC.W-GOOBLOB-MEATBALL \u2014 the WGSL uniformity STRUCTURAL fix (the meatball-armer).\n // The Toksvig screen-space derivative (fwidth SITE #2) is hoisted HERE, into the SAME\n // uniform control flow fwidth(d) above already arms in (top-level fs_main, before the\n // per-fragment alpha < 0.001 early-return and the uLit/uShadow non-uniform branches).\n // WGSL uniformity analysis rejects a fwidth() reached only through a return predicated\n // on a per-fragment value (the alpha < 0.001 early-out) nested under further branches\n // \u2014 exactly the BB residual that kept the normal-derivative inside the lit branch from\n // compiling, so the WGSL primary never armed and GooBlob fell to the WebGL2 net. Nh is\n // the uniform-flow surface normal computed for this derivative ONLY (byte-identical to\n // the lit block's own N = surfaceNormalFromGrad(...) below \u2014 the SAME inputs, so\n // nVar = length(fwidth(Nh)) IS the Toksvig clamp the lit block reads); the named lit-\n // block N stays AFTER the uStage early-return (the STAGE-1 floor reaches no lit work).\n // nVar is a pure uniform-flow value the lit block READS \u2014 no derivative in non-uniform\n // flow; the math is byte-identical to the GLSL fallback's Toksvig clamp, only its\n // EVALUATION POINT moved. The shadow march (T2) reuses d (the same sceneDistG().x).\n let Nh = surfaceNormalFromGrad(fieldGrad, d, bodyR);\n // \u2500\u2500 fwidth SITE #2 (metaball.frag.ts line 364) \u2014 Toksvig normal-variance specular\n // clamp, the WGSL fragment-stage fwidth() of the surface normal. NOW in uniform\n // control flow (the structural fix), so the WGSL primary ARMS + paints the full lit\n // creature instead of falling to the stripped WebGL2 fallback. \u2500\u2500\n let nVar = length(fwidth(Nh));\n\n if (alpha < 0.001) {\n return vec4<f32>(0.0);\n }\n\n // Edit #4 \u2014 perceptually-uniform OKLCh variation.\n let colorNoise = fbm(uv * uColorNoiseFreq + uTime * uColorNoiseSpeed, 3);\n var oklch = samplePaletteOklch(colorNoise);\n\n oklch.z = oklch.z + (colorNoise - 0.5) * uHueRange * (PI / 180.0);\n oklch.y = max(oklch.y + (colorNoise - 0.5) * uSatShift, 0.0);\n oklch.x = clamp(oklch.x + uBrightnessShift, 0.0, 1.0);\n\n // \u2500\u2500 BC.W-GOOBLOB-PLAIN \u2014 the STAGE-1 stripped floor (variant=blob). \u2500\u2500\n // The minimal verifiable floor: SDF + smin (the meatball field, already in d/\n // alpha above) + fwidth-AA (the crisp alpha above) + warm-cream fill. NO surface\n // normal, NO Fresnel, NO lit glint, NO iridescence, NO fake-SSS, NO shadow \u2014\n // deliberately FLAT. It returns BEFORE any of the STAGE-2 dressing is reached. The\n // STAGE-1 path simply never READS the hoisted Nh/nVar or the lit/shadow blocks; the\n // normal-derivative is now in UNIFORM control flow above (BC.W-GOOBLOB-MEATBALL \u2014 the\n // structural armer), so BOTH the STAGE-1 floor AND the STAGE-2 lit path arm on Metal\n // (the BB residual that kept STAGE 2 falling to the WebGL2 net is CLOSED). The\n // teaching contrast: this is the \"it renders, it meatballs, it works on Safari\"\n // floor STAGE 2 layers the lit/shadow onto via the SAME uniforms.\n // BD.W-GOO-CAROUSEL-DECK \u2014 the flat blob fill is snapshotted from the PRE-dressing\n // oklch (the dressing mutates oklch below). At morphT <= 0 (a pure blob) emit the\n // flat fill + dither and return \u2014 the byte-identical STAGE-1 floor, zero dressing cost.\n let flatOkl = gamutClampOklch(oklch);\n let flatLin = oklabToLinearSrgb(oklchToOklab(flatOkl));\n let flatRgbBase = clamp(linearToSrgb(flatLin), vec3<f32>(0.0), vec3<f32>(1.0));\n if (uMorphT <= 0.0) {\n let fc1 = in.pos.xy;\n let ign1 = fract(52.9829189 * fract(dot(fc1, vec2<f32>(0.06711056, 0.00583715))));\n let rgb1 = clamp(flatRgbBase + (ign1 - 0.5) / 255.0, vec3<f32>(0.0), vec3<f32>(1.0));\n return vec4<f32>(rgb1 * alpha, alpha);\n }\n\n // The named surface normal the lit/iridescence/SSS blocks read (byte-identical inputs to\n // the hoisted Nh above \u2014 the Toksvig nVar = length(fwidth(Nh)) IS this N's screen-space\n // variance). It sits AFTER the uStage early-return so the STAGE-1 floor reaches no lit work.\n let N = surfaceNormalFromGrad(fieldGrad, d, bodyR);\n let V = vec3<f32>(0.0, 0.0, 1.0);\n let thickness = clamp(-d / max(bodyR, 1e-4), 0.0, 1.0);\n let fres = pow(1.0 - max(dot(N, V), 0.0), 2.5);\n\n // \u2500\u2500 W11.a iridescence \u2014 warm-biased IQ cosine palette driving OKLCh HUE \u2500\u2500\n if (uIridescence > 0.0) {\n let t = fres + 0.3 * colorNoise + uTime * uIridSpeed;\n let iridHue = uIridHue + 0.18 * PI * cos(2.0 * PI * t);\n let w = fres * uIridescence;\n oklch.z = mix(oklch.z, iridHue, w);\n oklch.y = min(oklch.y + 0.04 * w, oklch.y + 0.08);\n oklch.x = min(oklch.x + 0.05 * w, 1.0);\n }\n\n // \u2500\u2500 W11.a fake subsurface translucency \u2014 thickness inner-glow + back-light \u2500\u2500\n if (uCoreGlow > 0.0 || uSssScale > 0.0) {\n oklch.x = min(oklch.x + uCoreGlow * (1.0 - exp(-3.0 * thickness)), 1.0);\n let L = normalize(uLightDir + vec3<f32>(1e-6));\n let back = pow(clamp(dot(V, -(L + N * thickness)), 0.0, 1.0), uSssPower);\n let sss = back * uSssScale * (1.0 - thickness);\n oklch.x = min(oklch.x + sss, 1.0);\n oklch.z = oklch.z + sss * 0.1 * (1.0 - thickness);\n }\n\n // \u2500\u2500 BC.W-GOOBLOB-MEATBALL \u2014 the soft contact shadow (T2). A procedural soft shadow that\n // FOLLOWS the irregular silhouette: march from this fragment's uv toward the in-plane\n // projection of uLightDir; where the metaball field occludes the light (the body\n // shadows itself opposite the light, a satellite shadows the body across the neck), the\n // march returns < 1 and DARKENS the OKLCh L \u2014 a soft grounded contact band UNDER the\n // dome, congruent with (but PROCEDURAL, silhouette-following, unlike) the CSS gel-dome\n // drop-shadow. Concentrated on the AWAY-facing lower rim (an away-facing weight \u00D7 a\n // thin-rim Gaussian band) so the deep-lit interior + the light-facing edge stay bright\n // and the grounded shadow reads at the lower silhouette edge \u2014 the warm-cream body mean\n // holds. Gated uShadow > 0.5; variant=blob (STAGE 1) ships shadowless. \u2500\u2500\n if (uShadow > 0.5) {\n let L2 = normalize(uLightDir.xy + vec2<f32>(1e-6));\n // w increases with the inverse light-source size \u2192 uShadowSoftness (a harder penumbra at a\n // higher value). Start the march just off the surface so a fragment never self-shadows\n // at t=0; cap the reach at the body span.\n let sh = softShadow2D(uv, L2, max(aa, 0.004), bodyR * 1.5, max(uShadowSoftness, 4.0));\n // The contact band sits on the LOWER rim (the side AWAY from the light) \u2014 gated by\n // dot(fieldGrad, L2) < 0 (the rim facing away from L2) AND the thin-rim weight\n // (a Gaussian band peaking at thickness \u2248 0.18 so the deep-lit interior + the\n // light-facing edge stay BRIGHT \u2014 the warm-cream body mean holds). The 0.20 cap keeps\n // it a soft GROUNDING whisper, never a gouge (the warm-cream identity + the\n // proof:blob-warm-default floor hold).\n let away = clamp(-dot(normalize(fieldGrad + vec2<f32>(1e-6)), L2), 0.0, 1.0);\n let band = exp(-pow((thickness - 0.18) / 0.16, 2.0));\n let shadowDarken = (1.0 - sh) * away * band * 0.20;\n oklch.x = max(oklch.x - shadowDarken, 0.0);\n }\n\n oklch = gamutClampOklch(oklch);\n\n var lin = oklabToLinearSrgb(oklchToOklab(oklch));\n\n // \u2500\u2500 W9.b lit glass surface \u2014 Blinn-Phong glint + Fresnel rim, in LINEAR \u2500\u2500\n if (uLit > 0.5) {\n let L = normalize(uLightDir + vec3<f32>(1e-6));\n let H = normalize(L + V);\n\n let warmCream = oklabToLinearSrgb(oklchToOklab(vec3<f32>(0.97, 0.03, radians(85.0))));\n\n // \u2500\u2500 fwidth SITE #2 \u2014 Toksvig normal-variance specular clamp. nVar is the HOISTED\n // length(fwidth(N)) (BC.W-GOOBLOB-MEATBALL \u2014 computed once at the top of fs_main\n // in uniform control flow, so the WGSL primary ARMS on Metal). The math is\n // byte-identical to the GLSL fallback (length(fwidth(N))); only its evaluation\n // point moved out of this non-uniform if (uLit > 0.5) branch. \u2500\u2500\n let shininess = uSpecShininess / (1.0 + 24.0 * nVar);\n let energyNorm = (shininess + 2.0) / 8.0;\n let spec = pow(max(dot(N, H), 0.0), shininess) * uSpecStrength * energyNorm;\n\n var rimOkl = oklabToOklch(srgbToOklab(uRimColor));\n let bodyL = oklch.x;\n let dL = abs(rimOkl.x - bodyL);\n let lack = clamp((0.22 - dL) / 0.22, 0.0, 1.0);\n // target is a WGSL RESERVED word (W3C WGSL 16.2) so a \"var target\" declaration is an\n // invalid identifier: the shader module fails to compile and the WGSL primary never\n // arms (the GooBlob reserved-keyword bug BC.W-WEBGPU-EVERYWHERE W7 catches). Renamed to\n // a valid identifier; the math + the value are byte-identical.\n var targetL = 0.18;\n if (bodyL < 0.5) { targetL = 0.92; }\n rimOkl.x = clamp(mix(rimOkl.x, targetL, lack), 0.0, 1.0);\n rimOkl.y = rimOkl.y * mix(1.0, 0.5, lack);\n let rimLin = oklabToLinearSrgb(oklchToOklab(rimOkl));\n\n let rimFres = pow(1.0 - max(dot(N, V), 0.0), uRimPower);\n let rim = rimFres * uRimStrength * (1.0 - 0.6 * thickness);\n\n var highlight = max(warmCream * spec, rimLin * rim);\n highlight = min(highlight, vec3<f32>(0.85));\n lin = lin + highlight;\n }\n\n var rgb = clamp(linearToSrgb(lin), vec3<f32>(0.0), vec3<f32>(1.0));\n\n // BD.W-GOO-CAROUSEL-DECK \u2014 the blob\u2194meatball SHADING-MORPH compose: lerp the flat blob\n // fill -> the dressed meatball surface on uMorphT (the geometry/alpha is shared; only\n // the surface shading interpolates). morphT == 1 is byte-identical to the dressed\n // meatball; the morphT == 0 case already returned the flat fill above.\n rgb = mix(flatRgbBase, rgb, uMorphT);\n\n // IGN dither \u2014 1-LSB triangular dither in DISPLAY space, AFTER linearToSrgb.\n let fragCoord = in.pos.xy;\n let ign = fract(52.9829189 * fract(dot(fragCoord, vec2<f32>(0.06711056, 0.00583715))));\n rgb = clamp(rgb + (ign - 0.5) / 255.0, vec3<f32>(0.0), vec3<f32>(1.0));\n\n // premultiply AFTER the OETF: straight-alpha gamma \u2192 premultiplied.\n return vec4<f32>(rgb * alpha, alpha);\n}\n";
|
|
@@ -44,8 +44,16 @@ export interface MetaballSource {
|
|
|
44
44
|
y: number;
|
|
45
45
|
radius: number;
|
|
46
46
|
opacity: number;
|
|
47
|
+
/**
|
|
48
|
+
* BD.W-GOOBLOB-MERCURY-COLONY — the per-source SPLIT token (default `false`). When a
|
|
49
|
+
* satellite is mid-`fissioning`, this is `true` and the uniform packers DROP the
|
|
50
|
+
* `orbitWiden` bridge to nominal for it ALONE, so its neck thins past the smin reach
|
|
51
|
+
* and SNAPS into a free bead. Every non-fissioning source keeps the full bridge (the
|
|
52
|
+
* R8-07 "instant fully-detached disc" cure). Trail sources never fission (`false`).
|
|
53
|
+
*/
|
|
54
|
+
fissioning?: boolean;
|
|
47
55
|
}
|
|
48
|
-
export type SatellitePhase = "orbiting" | "merging" | "absorbed" | "emerging";
|
|
56
|
+
export type SatellitePhase = "orbiting" | "merging" | "absorbed" | "emerging" | "fissioning";
|
|
49
57
|
export interface SatelliteInternal {
|
|
50
58
|
phase: SatellitePhase;
|
|
51
59
|
phaseStart: number;
|
|
@@ -69,6 +77,20 @@ export interface SatelliteInternal {
|
|
|
69
77
|
startY: number;
|
|
70
78
|
endX: number;
|
|
71
79
|
endY: number;
|
|
80
|
+
/**
|
|
81
|
+
* The live phase token the uniform packers READ to phase-scope `orbitWiden`. Mirrors
|
|
82
|
+
* `phase`, but exposed on the published `MetaballSource` (below) so the GL leaves can
|
|
83
|
+
* gate the bridge widen per-satellite WITHOUT importing the satellite internals. A
|
|
84
|
+
* fissioning satellite drops to nominal bridge (its neck snaps); every other
|
|
85
|
+
* satellite keeps the full+capped widen (R8-07 cured).
|
|
86
|
+
*/
|
|
87
|
+
fissioning: boolean;
|
|
88
|
+
/**
|
|
89
|
+
* BD.W-GOOBLOB-MERCURY-COLONY — the phase-local SNAP latch: false at the fission
|
|
90
|
+
* beat start, set true once the neck crosses the snap band (so the body-pulse recoil
|
|
91
|
+
* kick fires EXACTLY ONCE per pinch, not every frame across the snap window).
|
|
92
|
+
*/
|
|
93
|
+
snapFired: boolean;
|
|
72
94
|
}
|
|
73
95
|
/** Body / orbit / satellite geometry — the contained-droplet length cohort (W15). */
|
|
74
96
|
export interface BlobGeometry {
|
|
@@ -149,6 +171,21 @@ export interface BlobSurface {
|
|
|
149
171
|
sssPower: number;
|
|
150
172
|
/** Thickness-driven inner-luminosity (core glow) lift. */
|
|
151
173
|
coreGlow: number;
|
|
174
|
+
/**
|
|
175
|
+
* BD.W-GOOBLOB-MERCURY-COLONY — the MERCURY-COLONY split register (the OPT-IN scalar,
|
|
176
|
+
* 0..1, default the calm floor `0`). At `0` the shipped `variant:"blob"` default stays
|
|
177
|
+
* calm + gate-faithful: a permanently-bonded merge/un-merge breath, NO pinch (so
|
|
178
|
+
* `proof:blob-render`/`-studio`/`-page` are UNMOVED — `orbitRadius 0.17` is NOT
|
|
179
|
+
* re-based). Lifting it toward `1` arms the `fissioning` beat: the colony breathes a
|
|
180
|
+
* satellite OUT through a thinning neck whose gap exceeds the smin reach so it SNAPS
|
|
181
|
+
* into a free orbiting bead (the mercury pinch), then re-merges next cycle. This is a
|
|
182
|
+
* DERIVED bundling over the EXISTING `surface` atom (the variant IS the bundle) — NOT
|
|
183
|
+
* a 9th geometry atom; the split rides MOTION (the satellite moves) on the EXISTING
|
|
184
|
+
* phase machine, NOT a global smin-band re-base (which would lean-regress per
|
|
185
|
+
* AZ.W-BLOB-STUDIO D2). Mood-coupled: `excited` splits more, `sleepy` barely. The
|
|
186
|
+
* `colony`/`mercury` register a consumer/studio opts into.
|
|
187
|
+
*/
|
|
188
|
+
fissionAmp: number;
|
|
152
189
|
}
|
|
153
190
|
/** Pointer interaction — lean / squash-stretch / click-impulse. */
|
|
154
191
|
export interface BlobInteraction {
|
|
@@ -188,6 +225,18 @@ export interface BlobConfig {
|
|
|
188
225
|
* pre-STAGE-1 default (the `surface.lit` flag still owns the lit-on/off within it).
|
|
189
226
|
*/
|
|
190
227
|
variant: BlobVariant;
|
|
228
|
+
/**
|
|
229
|
+
* BD.W-GOO-CAROUSEL-DECK — the blob↔meatball SHADING-MORPH scalar (0..1). The user's
|
|
230
|
+
* "MORPH BLOB and MEATBALL from one to another" — a CONTINUOUS in-between, not a hard
|
|
231
|
+
* `variant` cut. `0` = the flat warm-cream blob (byte-identical to `variant: "blob"`);
|
|
232
|
+
* `1` = the fully-dressed lit meatball (byte-identical to `variant: "meatball"`);
|
|
233
|
+
* `0 < morphT < 1` lerps the SURFACE shading (the smin GEOMETRY is shared, so only the
|
|
234
|
+
* fill→lit/shadow/iridescence dressing interpolates). UNSET (the default) → the value
|
|
235
|
+
* is resolved from `variant` (blob → 0, meatball → 1), so the existing `variant` prop
|
|
236
|
+
* is byte-back-compat. A consumer ANIMATING this (a `useSpring`/registered-scalar) gets
|
|
237
|
+
* the live morph.
|
|
238
|
+
*/
|
|
239
|
+
morphT?: number;
|
|
191
240
|
quality: BlobQuality;
|
|
192
241
|
tempo: number;
|
|
193
242
|
}
|
|
@@ -2,10 +2,18 @@ import { type BlobWGPUUniformScratch } from "../../goo-blob/composables/uniformB
|
|
|
2
2
|
import { type MetaballUniformLocations } from "../../goo-blob/composables/uploadBlobUniforms";
|
|
3
3
|
import { type GooDotUniformScratch } from "./uniformBridgeWGPU";
|
|
4
4
|
export declare const GOO_DOT_LABEL = "[GooDotMatrix]";
|
|
5
|
-
/** The
|
|
5
|
+
/** The ground uniform buffer byte size — ONE vec4 (uGroundTime, aspect, pad, pad). */
|
|
6
|
+
export declare const GOO_DOT_GROUND_BYTES = 16;
|
|
7
|
+
/** The one-time WGPU resources the per-frame closure reads (the dot pipeline + the ground
|
|
8
|
+
* pipeline (Move 4a, pass-1) + the buffers + scratch). */
|
|
6
9
|
export interface GooDotWGPUResources {
|
|
7
10
|
pipeline: GPURenderPipeline;
|
|
8
11
|
bindGroup: GPUBindGroup;
|
|
12
|
+
/** Move 4a — the warm-ground pass-1 pipeline (its own minimal shader, NOT Aurora). */
|
|
13
|
+
groundPipeline: GPURenderPipeline;
|
|
14
|
+
groundBindGroup: GPUBindGroup;
|
|
15
|
+
groundBuffer: GPUBuffer;
|
|
16
|
+
groundScratch: Float32Array;
|
|
9
17
|
fieldBuffer: GPUBuffer;
|
|
10
18
|
dotBuffer: GPUBuffer;
|
|
11
19
|
fieldScratch: BlobWGPUUniformScratch;
|
|
@@ -17,7 +25,8 @@ export interface GooDotWGPUResources {
|
|
|
17
25
|
* per-frame closure writes the scratch via the pack helpers then submits the draw.
|
|
18
26
|
*/
|
|
19
27
|
export declare function createGooDotWGPUResources(device: GPUDevice, format: GPUTextureFormat): GooDotWGPUResources;
|
|
20
|
-
/** The dot-grid uniform locations (the dot extend, beside the field locations).
|
|
28
|
+
/** The dot-grid uniform locations (the dot extend, beside the field locations). The N named
|
|
29
|
+
* scalars are the GLSL twin of the WGSL s8–s13 lane-fields; a unit asserts count parity. */
|
|
21
30
|
export interface GooDotGLUniforms {
|
|
22
31
|
mode: WebGLUniformLocation | null;
|
|
23
32
|
pix: WebGLUniformLocation | null;
|
|
@@ -30,8 +39,27 @@ export interface GooDotGLUniforms {
|
|
|
30
39
|
pa: WebGLUniformLocation | null;
|
|
31
40
|
cursor: WebGLUniformLocation | null;
|
|
32
41
|
bloom: WebGLUniformLocation | null;
|
|
42
|
+
shadowGate: WebGLUniformLocation | null;
|
|
43
|
+
presenceFloor: WebGLUniformLocation | null;
|
|
44
|
+
weldLo: WebGLUniformLocation | null;
|
|
45
|
+
weldHi: WebGLUniformLocation | null;
|
|
46
|
+
time: WebGLUniformLocation | null;
|
|
47
|
+
weldSwell: WebGLUniformLocation | null;
|
|
48
|
+
weldSpecular: WebGLUniformLocation | null;
|
|
49
|
+
flowAmt: WebGLUniformLocation | null;
|
|
50
|
+
latticeSquash: WebGLUniformLocation | null;
|
|
33
51
|
}
|
|
34
|
-
/** The
|
|
52
|
+
/** The Move 4a warm-ground GL program (the WebGL2/Safari tail of pass-1). */
|
|
53
|
+
export interface GooDotGroundGLResources {
|
|
54
|
+
prog: WebGLProgram;
|
|
55
|
+
vs: WebGLShader;
|
|
56
|
+
fs: WebGLShader;
|
|
57
|
+
vao: WebGLVertexArrayObject;
|
|
58
|
+
buf: WebGLBuffer;
|
|
59
|
+
uTime: WebGLUniformLocation | null;
|
|
60
|
+
}
|
|
61
|
+
/** The one-time GL resources the per-frame closure reads (program + VAO + the field + dot
|
|
62
|
+
* locations + the Move 4a ground program). */
|
|
35
63
|
export interface GooDotGLResources {
|
|
36
64
|
prog: WebGLProgram;
|
|
37
65
|
vs: WebGLShader;
|
|
@@ -40,6 +68,7 @@ export interface GooDotGLResources {
|
|
|
40
68
|
vao: WebGLVertexArrayObject;
|
|
41
69
|
locs: MetaballUniformLocations;
|
|
42
70
|
dU: GooDotGLUniforms;
|
|
71
|
+
ground: GooDotGroundGLResources;
|
|
43
72
|
}
|
|
44
73
|
/**
|
|
45
74
|
* Build the WebGL2 dot-stamp program + the full-quad VAO + the field uniform-location cache
|
|
@@ -1,19 +1,29 @@
|
|
|
1
1
|
import type { GooDotConfig } from "../constants";
|
|
2
|
-
/** The total dot-grid uniform-buffer byte size (16-aligned). */
|
|
3
|
-
export declare const GOO_DOT_UNIFORM_BYTES =
|
|
2
|
+
/** The total dot-grid uniform-buffer byte size (16-aligned — 6 vec4 lanes). */
|
|
3
|
+
export declare const GOO_DOT_UNIFORM_BYTES = 96;
|
|
4
|
+
export declare const WELD_LO = 0.1;
|
|
5
|
+
export declare const WELD_HI = 0.45;
|
|
4
6
|
/** The dot-mode int the shader branches on (0 = smooth field dot, 1 = Bayer dither). */
|
|
5
7
|
export declare function dotModeFor(variant: GooDotConfig["variant"]): number;
|
|
6
8
|
/** The repel/attract sign for a pointer mode (repel pushes out, attract pulls in). */
|
|
7
9
|
export declare function pointerModeSign(mode: GooDotConfig["pointerMode"]): number;
|
|
8
|
-
/** The transient dot-cursor state the
|
|
10
|
+
/** The transient dot-cursor + liquid-field state the renderer writes per-frame (closed over,
|
|
11
|
+
* never the config). The cursor push (Move 3 shadow offset, the cursor swell) AND the
|
|
12
|
+
* liquid-lattice clock (Move 4b twinkle + squash) ride here so the per-frame pack reads ONE
|
|
13
|
+
* transient struct. */
|
|
9
14
|
export interface GooDotPointerState {
|
|
10
15
|
/** Field-uv cursor [-0.5, 0.5] (0,0 = canvas center). */
|
|
11
16
|
x: number;
|
|
12
17
|
y: number;
|
|
13
18
|
/** 1 while the pointer is over the host, 0 at rest (decays the influence). */
|
|
14
19
|
active: number;
|
|
15
|
-
/** The accel-burst brightness/scale bloom 0..1 (the flick term). */
|
|
20
|
+
/** The accel-burst brightness/scale bloom 0..1 (the flick term, the velocity tell). */
|
|
16
21
|
bloom: number;
|
|
22
|
+
/** The live sim clock (s) for the φ-twinkle breathing — the field's `breath`/`hash21` phase. */
|
|
23
|
+
timeSec: number;
|
|
24
|
+
/** The volume-preserving lattice squash (Move 4b): the X scale on the pulse + a fast drag;
|
|
25
|
+
* the shader applies `1/squash` on Y so the cell area ≈ 1 (a liquid lean, not a balloon). */
|
|
26
|
+
latticeSquash: number;
|
|
17
27
|
}
|
|
18
28
|
/** A fresh resting dot-cursor state. */
|
|
19
29
|
export declare function restingDotPointer(): GooDotPointerState;
|
|
@@ -4,14 +4,17 @@ import { type BlobConfig } from "../goo-blob";
|
|
|
4
4
|
export type GooDotVariant = "dot-field" | "dot-dither" | "dot-lattice" | "dot-sphere";
|
|
5
5
|
/** Pointer interaction mode — repel pushes dots off the field, attract pulls them in. */
|
|
6
6
|
export type GooDotPointerMode = "repel" | "attract";
|
|
7
|
+
/** The warm ground modes — `"warm"` paints a living warm-amber gradient pass-1 BEHIND the
|
|
8
|
+
* dots in the SAME GL context (the §3 colourful ground, an opaque field to read over);
|
|
9
|
+
* `"transparent"` skips the ground pass (the library composable default — the dots ride the
|
|
10
|
+
* consumer's own host, e.g. the global `[data-paper-field]` backdrop). */
|
|
11
|
+
export type GooDotFieldGround = "warm" | "transparent";
|
|
7
12
|
/**
|
|
8
13
|
* Compile-time dot-stamp cell cap (px) — the device-px cell SIZE the fragment quantizes the
|
|
9
14
|
* grid to; mirrors the §T1 `uDotPixelSize` band (a floor so a tiny cell never hangs the
|
|
10
15
|
* fragment over a huge grid). Register-A only.
|
|
11
16
|
*/
|
|
12
17
|
export declare const MIN_DOT_PIXEL_SIZE = 4;
|
|
13
|
-
/** Compile-time lattice column cap — mirrors the Register-B `uCols` instance fan-out. */
|
|
14
|
-
export declare const MAX_LATTICE_COLS = 96;
|
|
15
18
|
/**
|
|
16
19
|
* The full author schema — the studio's `useConfiguratorState` model. The FIELD atoms are
|
|
17
20
|
* REUSED from the goo-blob `BlobConfig` (the metaball field is the byte-untouched goo half),
|
|
@@ -36,21 +39,47 @@ export interface GooDotConfig {
|
|
|
36
39
|
dotMin: number;
|
|
37
40
|
/** Dot radius MAX (the core dot, fraction of the cell, §T1 `uDotMax`). */
|
|
38
41
|
dotMax: number;
|
|
39
|
-
/** The field floor
|
|
42
|
+
/** The field floor at which the meniscus rise begins (§T1 `uFieldFloor`). */
|
|
40
43
|
fieldFloor: number;
|
|
41
44
|
/** The dim-outside brightness floor (the dots dim at the rim, §T1 `uDotBrightFloor`). */
|
|
42
45
|
dotBrightFloor: number;
|
|
43
46
|
/**
|
|
44
|
-
*
|
|
45
|
-
*
|
|
47
|
+
* The φ-banded PRESENCE FLOOR (BD.W-GOODOT-LIQUID-FIELD Move 1, `uPresenceFloor`). The
|
|
48
|
+
* base-lattice opacity the field NEVER drops below — the dot is always present and the
|
|
49
|
+
* metaball MODULATES it (it never gates it). At `0` the read is byte-identical to the old
|
|
50
|
+
* `step()` discard (the calm escape hatch); the default fills the card corner-to-corner.
|
|
51
|
+
*/
|
|
52
|
+
presenceFloor: number;
|
|
53
|
+
/**
|
|
54
|
+
* The NECK-RIDGE swell (Move 2, `uWeldSwell`). At a weld (the shallow-gradient membrane
|
|
55
|
+
* where two bodies meet) the dot radius swells by `1 + weldSwell·weld`. Pinned so the
|
|
56
|
+
* swelled rim dot stays a sub-cell ROUND circle (`dotMax·(1+weldSwell) < 1`), never a
|
|
57
|
+
* clipped square (the √φ cell-clip ceiling).
|
|
58
|
+
*/
|
|
59
|
+
weldSwell: number;
|
|
60
|
+
/**
|
|
61
|
+
* The NECK-RIDGE specular (Move 2, `uWeldSpecular`). A MULTIPLICATIVE HDR brightness pop on
|
|
62
|
+
* the weld dots (`bright *= 1 + weldSpecular·weld`) — it can exceed the core ceiling so the
|
|
63
|
+
* waist is the BRIGHTEST band in the field a beat before the bodies fuse.
|
|
64
|
+
*/
|
|
65
|
+
weldSpecular: number;
|
|
66
|
+
/**
|
|
67
|
+
* The liquid-lattice flow (Move 4b, `uFlowAmt`). The cell sample advects down the field
|
|
68
|
+
* gradient toward the forming core (`sampleUv -= normalize(scene.yz)·flowAmt·core`) so the
|
|
69
|
+
* lattice migrates INTO the goo rather than sitting screen-locked. A real net-new lane.
|
|
46
70
|
*/
|
|
47
|
-
cols: number;
|
|
48
|
-
/** Register-B flow displacement toward the merging core (§T3 `uFlowAmt`; capped < 0.5 pitch). */
|
|
49
71
|
flowAmt: number;
|
|
50
|
-
/** The dot-color ramp (resolved via the ColorResolver; default warm
|
|
72
|
+
/** The dot-color ramp (resolved via the ColorResolver; default warm technicolor). */
|
|
51
73
|
palette: OklchStop[];
|
|
52
|
-
/** The ground color (default transparent so the glass card shows through). */
|
|
74
|
+
/** The ground color (default transparent so the glass card / paper-field shows through). */
|
|
53
75
|
background: OklchStop | "transparent";
|
|
76
|
+
/**
|
|
77
|
+
* The §3 warm GROUND pass (Move 4a, `fieldGround`). `"warm"` draws a living warm-amber
|
|
78
|
+
* gradient pass-1 behind the dots in the SAME context (an opaque field to read over, the
|
|
79
|
+
* cartoon shadow's casting surface); `"transparent"` skips it (the library composable
|
|
80
|
+
* default — the dots ride the consumer's own host).
|
|
81
|
+
*/
|
|
82
|
+
fieldGround: GooDotFieldGround;
|
|
54
83
|
/** Pointer parallax + repel + accel-burst (the §T7 dot-cursor influence). */
|
|
55
84
|
interactive: boolean;
|
|
56
85
|
/** repel ↔ attract (the dot-influence direction). */
|
|
@@ -61,16 +90,26 @@ export interface GooDotConfig {
|
|
|
61
90
|
respectReducedMotion: boolean;
|
|
62
91
|
}
|
|
63
92
|
/**
|
|
64
|
-
* The warm
|
|
65
|
-
*
|
|
66
|
-
*
|
|
67
|
-
*
|
|
93
|
+
* The warm TECHNICOLOR identity palette (the library default — warm-fire/amber/gold, NEVER
|
|
94
|
+
* teal/cyan). A 3-stop liquid ramp the read maps CORE→NECK→RIM (the `tone = 1 - fCell` sample,
|
|
95
|
+
* so stop[0] is the deep CORE, stop[2] the base-lattice RIM):
|
|
96
|
+
*
|
|
97
|
+
* CORE — hot butter-gold (`fCell→1`, the bright cream membrane at the body core),
|
|
98
|
+
* NECK — molten coral (the weld climax, the fattest+brightest dots at the merge waist),
|
|
99
|
+
* RIM — deep amber (`fCell≈floor`, the resting base lattice — it carries chroma, never gray).
|
|
100
|
+
*
|
|
101
|
+
* BD.W-GOODOT-LIQUID-FIELD Move 3 — the near-mono cream-on-cream identity (ΔL 0.08 ΔC 0.04,
|
|
102
|
+
* invisible separation) re-graded to real chroma (C_core ≥ 0.13, the no-gray warm floor cleared
|
|
103
|
+
* with room). A consumer themes it mono-warm-white-on-near-black through a PRESET, never a token
|
|
104
|
+
* edit (presets-in-consumers — the library identity sharpens as a token evolution).
|
|
68
105
|
*/
|
|
69
106
|
export declare const WARM_IDENTITY_PALETTE: OklchStop[];
|
|
70
107
|
/**
|
|
71
108
|
* The shipped warm-identity default — the §T6 default table: the Register-A field-driven dot
|
|
72
|
-
* stamp over the byte-untouched goo-blob field (the cream metaball), warm
|
|
73
|
-
*
|
|
74
|
-
*
|
|
109
|
+
* stamp over the byte-untouched goo-blob field (the cream metaball), warm technicolor dots that
|
|
110
|
+
* FILL the card corner-to-corner (the presence floor), the weld a ridge of the fattest+brightest
|
|
111
|
+
* coral dots, over a transparent ground (the composable default — the dots ride the consumer's
|
|
112
|
+
* own host). The demo turns the warm ground ON; the near-dark reference is a DEMO preset
|
|
113
|
+
* (presets-in-consumers).
|
|
75
114
|
*/
|
|
76
115
|
export declare const DEFAULT_GOO_DOT_CONFIG: GooDotConfig;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export { default as GooDotMatrix } from "./GooDotMatrix.vue";
|
|
2
2
|
export { useGooDotMatrix, type GooDotMatrixHandle, type UseGooDotMatrixOptions, } from "./composables/useGooDotMatrix";
|
|
3
|
-
export { type GooDotConfig, type GooDotVariant, type GooDotPointerMode, DEFAULT_GOO_DOT_CONFIG, WARM_IDENTITY_PALETTE, MIN_DOT_PIXEL_SIZE,
|
|
3
|
+
export { type GooDotConfig, type GooDotVariant, type GooDotPointerMode, type GooDotFieldGround, DEFAULT_GOO_DOT_CONFIG, WARM_IDENTITY_PALETTE, MIN_DOT_PIXEL_SIZE, } from "./constants";
|
|
4
4
|
export { gridOrigin, latticeInstanceCount, fibonacciDot, type Vec2, type Vec3, } from "./composables/gooDotLattice";
|
|
5
5
|
export type { OklchStop } from "../../../composables/color";
|
|
@@ -9,3 +9,5 @@ export declare const GOO_DOT_FIELD_GLSL: string;
|
|
|
9
9
|
export declare const GOO_DOT_VERT_GLSL = "#version 300 es\nprecision highp float;\nin vec2 aPosition;\nout vec2 vUv;\nvoid main() {\n vUv = aPosition * 0.5 + 0.5;\n gl_Position = vec4(aPosition, 0.0, 1.0);\n}";
|
|
10
10
|
/** The Register-A dot-stamp fragment — the GLSL twin of the WGSL `fs_main`. */
|
|
11
11
|
export declare const GOO_DOT_FRAG_GLSL: string;
|
|
12
|
+
export declare const GOO_DOT_GROUND_VERT_GLSL = "#version 300 es\nprecision highp float;\nin vec2 aPosition;\nout vec2 vUv;\nvoid main() {\n vUv = aPosition * 0.5 + 0.5;\n gl_Position = vec4(aPosition, 0.0, 1.0);\n}";
|
|
13
|
+
export declare const GOO_DOT_GROUND_FRAG_GLSL = "#version 300 es\nprecision highp float;\nin vec2 vUv;\nout vec4 fragColor;\nuniform float uGroundTime;\nvoid main() {\n float d1 = 0.5 + 0.5 * sin(uGroundTime * 0.11 + vUv.x * 2.1);\n float d2 = 0.5 + 0.5 * sin(uGroundTime * 0.07 - vUv.y * 1.7 + 1.3);\n vec3 amber = vec3(0.99, 0.86, 0.62);\n vec3 coral = vec3(0.95, 0.62, 0.42);\n vec3 deep = vec3(0.86, 0.50, 0.30);\n vec3 g = mix(deep, coral, d1);\n vec3 rgb = mix(g, amber, d2 * (1.0 - vUv.y) * 0.8);\n fragColor = vec4(rgb, 1.0);\n}";
|
|
@@ -1,3 +1,4 @@
|
|
|
1
1
|
/** The spliced goo-blob field (struct + bindings + sceneDistG/breath/samplePaletteOklch). */
|
|
2
2
|
export declare const GOO_DOT_FIELD_WGSL: string;
|
|
3
3
|
export declare const GOO_DOT_WGSL: string;
|
|
4
|
+
export declare const GOO_DOT_GROUND_WGSL = "\nstruct GroundUniforms {\n // g0: (uGroundTime, uGroundAspect, _pad, _pad)\n g0: vec4<f32>,\n};\n@group(0) @binding(0) var<uniform> gu: GroundUniforms;\n\nstruct GVSOut {\n @builtin(position) pos: vec4<f32>,\n @location(0) uv: vec2<f32>,\n};\n\n@vertex\nfn vs_main(@builtin(vertex_index) vi: u32) -> GVSOut {\n var p = vec2<f32>(-1.0, -1.0);\n if (vi == 1u) { p = vec2<f32>(3.0, -1.0); }\n else if (vi == 2u) { p = vec2<f32>(-1.0, 3.0); }\n var out: GVSOut;\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_main(in: GVSOut) -> @location(0) vec4<f32> {\n let t = gu.g0.x;\n let uv = in.uv;\n // Two slow warm drifts \u2014 the centroid moves so the ground is LIVING (G3c).\n let d1 = 0.5 + 0.5 * sin(t * 0.11 + uv.x * 2.1);\n let d2 = 0.5 + 0.5 * sin(t * 0.07 - uv.y * 1.7 + 1.3);\n let amber = vec3<f32>(0.99, 0.86, 0.62); // warm gold high\n let coral = vec3<f32>(0.95, 0.62, 0.42); // molten coral mid\n let deep = vec3<f32>(0.86, 0.50, 0.30); // deep amber low\n let g = mix(deep, coral, d1);\n let rgb = mix(g, amber, d2 * (1.0 - uv.y) * 0.8);\n return vec4<f32>(rgb, 1.0);\n}";
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
interface GooSpec {
|
|
2
|
+
/** The filter id consumers reference (`url(#<id>)`). */
|
|
3
|
+
id: string;
|
|
4
|
+
/** feGaussianBlur stdDeviation — the alpha-bleed radius (per-scale). */
|
|
5
|
+
blur: number;
|
|
6
|
+
/** feColorMatrix A-channel slope — the threshold steepness (the gooey shoulder). */
|
|
7
|
+
slope: number;
|
|
8
|
+
/** feColorMatrix A-channel offset (negative) — the alpha cut point. */
|
|
9
|
+
offset: number;
|
|
10
|
+
}
|
|
11
|
+
type __VLS_Props = {
|
|
12
|
+
/**
|
|
13
|
+
* Extra bespoke `<filter>` instances beyond the library register (a consumer
|
|
14
|
+
* tuning a one-off scale). Each is the SAME graph at its own knobs.
|
|
15
|
+
*/
|
|
16
|
+
extra?: GooSpec[];
|
|
17
|
+
};
|
|
18
|
+
declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {
|
|
19
|
+
extra: GooSpec[];
|
|
20
|
+
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
21
|
+
declare const _default: typeof __VLS_export;
|
|
22
|
+
export default _default;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default as GooFilter } from "./GooFilter.vue";
|
|
@@ -10,13 +10,13 @@
|
|
|
10
10
|
* Field-count discipline (SPEC §2): resist a 13th scalar per new instrument —
|
|
11
11
|
* `blend` earned its place only because highlighter genuinely needed `multiply`.
|
|
12
12
|
*
|
|
13
|
-
* The shipped register: PEN is the default (clean ink, grain:0 ⇒ no filter
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
* `ribbon:'
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
13
|
+
* The shipped register: PEN is the default (clean ink, grain:0 ⇒ no filter, the one
|
|
14
|
+
* `ribbon:'stroke'` clean voice). The variable-width VOICES — boil (the pressured
|
|
15
|
+
* pen-line), crayon (the waxy swell), marker (the juicy core), highlighter (the wide
|
|
16
|
+
* slab) — all ENGAGE `ribbon:'hull'`, the vendored perfect-freehand body, sharing the
|
|
17
|
+
* one curvature-coupled pressure profile (ink.ts `addPressure`). pen/pencil/ring stay
|
|
18
|
+
* `ribbon:'stroke'` by intent (pen clean, pencil's dry tooth-grain is its character,
|
|
19
|
+
* ring a thin whisper). The pf body ships whenever any hull brush does.
|
|
20
20
|
*/
|
|
21
21
|
export type BlendMode = "source-over" | "multiply" | "darken" | "screen";
|
|
22
22
|
export interface TaperSpec {
|
|
@@ -88,9 +88,9 @@ export interface InkPath {
|
|
|
88
88
|
cap?: "round" | "square" | "butt";
|
|
89
89
|
}
|
|
90
90
|
/**
|
|
91
|
-
* The named points in the continuum. `pen` is the DEFAULT (clean ink, grain:0
|
|
92
|
-
* `crayon`
|
|
93
|
-
* `pencil`/`
|
|
91
|
+
* The named points in the continuum. `pen` is the DEFAULT (clean ink, grain:0,
|
|
92
|
+
* `ribbon:'stroke'`). `boil`/`crayon`/`marker`/`highlighter` engage `ribbon:'hull'`
|
|
93
|
+
* (the curvature-coupled variable-width body); `pencil`/`ring` stay clean stroke.
|
|
94
94
|
*/
|
|
95
95
|
export declare const BRUSHES: {
|
|
96
96
|
readonly pen: {
|
|
@@ -117,15 +117,15 @@ export declare const BRUSHES: {
|
|
|
117
117
|
readonly cap: "round";
|
|
118
118
|
};
|
|
119
119
|
readonly boil: {
|
|
120
|
-
readonly weight:
|
|
120
|
+
readonly weight: 7;
|
|
121
121
|
readonly weightJitter: 0.12;
|
|
122
|
-
readonly thinning: 0.
|
|
122
|
+
readonly thinning: 0.55;
|
|
123
123
|
readonly taper: {
|
|
124
|
-
readonly start:
|
|
125
|
-
readonly end:
|
|
124
|
+
readonly start: 14;
|
|
125
|
+
readonly end: 18;
|
|
126
126
|
readonly ease: "out-cubic";
|
|
127
127
|
};
|
|
128
|
-
readonly ribbon: "
|
|
128
|
+
readonly ribbon: "hull";
|
|
129
129
|
readonly opacity: 1;
|
|
130
130
|
readonly blend: "source-over";
|
|
131
131
|
readonly passes: 1;
|
|
@@ -171,7 +171,7 @@ export declare const BRUSHES: {
|
|
|
171
171
|
readonly end: 6;
|
|
172
172
|
readonly ease: "linear";
|
|
173
173
|
};
|
|
174
|
-
readonly ribbon: "
|
|
174
|
+
readonly ribbon: "hull";
|
|
175
175
|
readonly opacity: 0.8;
|
|
176
176
|
readonly blend: "source-over";
|
|
177
177
|
readonly passes: 2;
|
|
@@ -217,7 +217,7 @@ export declare const BRUSHES: {
|
|
|
217
217
|
readonly end: 10;
|
|
218
218
|
readonly ease: "out-cubic";
|
|
219
219
|
};
|
|
220
|
-
readonly ribbon: "
|
|
220
|
+
readonly ribbon: "hull";
|
|
221
221
|
readonly opacity: 0.92;
|
|
222
222
|
readonly blend: "source-over";
|
|
223
223
|
readonly passes: 1;
|
|
@@ -28,12 +28,32 @@ export declare const HIGHLIGHT_RISE = 0.22;
|
|
|
28
28
|
/** Pre-measure fallback for the highlight band's low seat (null baselineFrac). */
|
|
29
29
|
export declare const HIGHLIGHT_FALLBACK_FRAC = 0.66;
|
|
30
30
|
/**
|
|
31
|
-
*
|
|
32
|
-
*
|
|
33
|
-
*
|
|
34
|
-
*
|
|
35
|
-
*
|
|
36
|
-
*
|
|
31
|
+
* The boil voice — φ-incommensurate fractal value-noise (the masthead morphology).
|
|
32
|
+
* ─────────────────────────────────────────────────────────────────────────────
|
|
33
|
+
* The boil centerline is a 1-D fractal value-noise displacement off the HOUSE
|
|
34
|
+
* `mulberry32`, NOT a seeded sinusoid. A sinusoid (the prior body) self-correlates
|
|
35
|
+
* into a near-period — it reads as a spell-check squiggle and a clean sine fails any
|
|
36
|
+
* honest non-periodicity discriminator (a sine's extrema are near-uniformly spaced).
|
|
37
|
+
* The value-noise sums octaves at φ-stepped frequencies (mutually irrational → the
|
|
38
|
+
* sum NEVER closes into a period); each octave's amplitude decays by 1/φ. The result
|
|
39
|
+
* is a hump-to-hump-IRREGULAR hand line whose inter-extremum spacing-CV is the honest
|
|
40
|
+
* teeth (measured: ~0.41 at the paint's segment count, ~0.71 resampled at RES=64,
|
|
41
|
+
* over 400 seeds — vs the prior sinusoid's ~0.14; a clean separation either side of a
|
|
42
|
+
* 0.30 floor). The amplitude is SCALE-RELATIVE (a fraction of the rendered span), so
|
|
43
|
+
* a long word and a short word wobble in proportion. FILTER-FREE — the wander lives
|
|
44
|
+
* in the control points + the hull width, never a feTurbulence.
|
|
45
|
+
*
|
|
46
|
+
* Constants pinned against a 400-seed spacing-CV spike (NOT the seed-overfit autocorr
|
|
47
|
+
* peak the prior gate keyed — autocorr cannot separate smooth low-frequency value-
|
|
48
|
+
* noise from a sinusoid at any resolution).
|
|
37
49
|
*/
|
|
38
|
-
|
|
39
|
-
export declare const
|
|
50
|
+
/** φ — the per-octave frequency step (mutually irrational → never periodic). */
|
|
51
|
+
export declare const NOISE_PHI = 1.618033988749895;
|
|
52
|
+
/** octave count of the fractal value-noise sum. */
|
|
53
|
+
export declare const NOISE_OCTAVES = 4;
|
|
54
|
+
/** base octave frequency (humps across the unit span); octave k rides F0·φ^k. */
|
|
55
|
+
export declare const NOISE_F0 = 2.5;
|
|
56
|
+
/** displacement amplitude as a fraction of the rendered span (scale-relative). */
|
|
57
|
+
export declare const NOISE_AMP_FRAC = 0.05;
|
|
58
|
+
/** endpoint-only cosine taper width (the ends settle to baseline; the BODY stays irregular). */
|
|
59
|
+
export declare const NOISE_EDGE = 0.12;
|