├── .browserslistrc
├── .editorconfig
├── .eslintrc.js
├── .gitattributes
├── .github
├── FUNDING.yml
├── ISSUE_TEMPLATE
│ ├── bug_report.md
│ └── feature_request.md
├── PULL_REQUEST_TEMPLATE
│ └── pull_request_template.md
└── workflows
│ ├── browserslist.yml
│ ├── build.yml
│ └── release.yml
├── .gitignore
├── .releaserc
├── .vscode
└── extensions.json
├── CODE_OF_CONDUCT.md
├── LICENSE
├── README.md
├── babel.config.js
├── build
├── entitlements.mac.plist
├── icon.ico
├── icon.png
└── icon@2x.png
├── jsconfig.json
├── lib
└── BeatDetektor.js
├── notarize.js
├── package.json
├── patches
├── hapticjs+1.0.7.patch
└── smooth-dnd+0.12.1.patch
├── playwright.config.js
├── postcss.config.js
├── public
├── favicon.ico
├── index.html
└── output-window.html
├── sample-preset.json
├── src
├── App.vue
├── application
│ ├── constants.js
│ ├── createWebcodecVideo.js
│ ├── index.js
│ ├── install-plugin.js
│ ├── plugins
│ │ ├── feature-assignment
│ │ │ ├── index.js
│ │ │ └── store.js
│ │ └── grab-canvas.js
│ ├── renderers
│ │ ├── 2d.js
│ │ ├── isf.js
│ │ ├── shader.js
│ │ ├── shader
│ │ │ ├── default-shader.js
│ │ │ └── index.js
│ │ └── three.js
│ ├── sample-modules
│ │ ├── Ball.js
│ │ ├── Bar.js
│ │ ├── ChromaticAbberation.js
│ │ ├── ChromaticAbberation
│ │ │ └── chromaticAbberation.frag
│ │ ├── Concentrics.js
│ │ ├── Counter.js
│ │ ├── Cube.js
│ │ ├── Fisheye.js
│ │ ├── Fisheye
│ │ │ └── fisheye.frag
│ │ ├── GreatBallOfFire.js
│ │ ├── GridStretch.js
│ │ ├── Line.js
│ │ ├── MattiasCRT-2.0.js
│ │ ├── MattiasCRT
│ │ │ └── mattiasCrt.frag
│ │ ├── Pixelate.js
│ │ ├── Plasma.js
│ │ ├── Plasma
│ │ │ └── plasma.frag
│ │ ├── Polygon.js
│ │ ├── Smear.js
│ │ ├── Text.js
│ │ ├── Texture2d.js
│ │ ├── Triangles.js
│ │ ├── Waveform.js
│ │ ├── Webcam.js
│ │ ├── Wobble.js
│ │ ├── Wobble
│ │ │ └── wobble.frag
│ │ ├── X-Drips.js
│ │ └── isf
│ │ │ ├── ASCII Art.fs
│ │ │ ├── Angular.fs
│ │ │ ├── Auto Color Tone.fs
│ │ │ ├── Auto Levels.fs
│ │ │ ├── Auto Levels.vs
│ │ │ ├── Bloom.fs
│ │ │ ├── Bloom.vs
│ │ │ ├── Bounce.fs
│ │ │ ├── Bow Tie Horizontal.fs
│ │ │ ├── Bow Tie Vertical.fs
│ │ │ ├── Boxinator.fs
│ │ │ ├── Brick Pattern.fs
│ │ │ ├── Bright.fs
│ │ │ ├── BrightnessContrast.fs
│ │ │ ├── Broken LCD.fs
│ │ │ ├── Bump Distortion.fs
│ │ │ ├── Burn.fs
│ │ │ ├── Butterfly Wave Scrawler.fs
│ │ │ ├── CMYK Halftone-Lookaround.fs
│ │ │ ├── CMYK Halftone.fs
│ │ │ ├── Channel Slide.fs
│ │ │ ├── Checkerboard.fs
│ │ │ ├── Chroma Zoom.fs
│ │ │ ├── Circle Crop.fs
│ │ │ ├── Circle Open.fs
│ │ │ ├── Circle Splash Distortion.fs
│ │ │ ├── Circle Trails.fs
│ │ │ ├── Circle Warp.fs
│ │ │ ├── Circle Wrap Distortion.fs
│ │ │ ├── Circle.fs
│ │ │ ├── Circuits.fs
│ │ │ ├── Circular Feedback Mask.fs
│ │ │ ├── Circular Screen.fs
│ │ │ ├── Circular Screen.vs
│ │ │ ├── City Lights.fs
│ │ │ ├── City Lights.vs
│ │ │ ├── Collage.fs
│ │ │ ├── CollapsingArchitecture.fs
│ │ │ ├── Color Blowout.fs
│ │ │ ├── Color Blowout.vs
│ │ │ ├── Color Controls.fs
│ │ │ ├── Color History.fs
│ │ │ ├── Color Invert.fs
│ │ │ ├── Color Levels.fs
│ │ │ ├── Color Monochrome.fs
│ │ │ ├── Color Phase.fs
│ │ │ ├── Color Posterize.fs
│ │ │ ├── Color Relookup.fs
│ │ │ ├── Color Scales.fs
│ │ │ ├── Color Schemes.fs
│ │ │ ├── Color Test Grid.fs
│ │ │ ├── Colour Distance.fs
│ │ │ ├── Comet Tails.fs
│ │ │ ├── Convergence.fs
│ │ │ ├── Corner Color Tint.fs
│ │ │ ├── Corner Colors.fs
│ │ │ ├── Crazy Parametric Fun.fs
│ │ │ ├── CrossZoom.fs
│ │ │ ├── Crosshatch.fs
│ │ │ ├── Crosswarp.fs
│ │ │ ├── Cubic Warp.fs
│ │ │ ├── Deinterlace.fs
│ │ │ ├── Diagonal Blur.fs
│ │ │ ├── Diagonalize.fs
│ │ │ ├── Digital Clock.fs
│ │ │ ├── Directional Warp.fs
│ │ │ ├── Directional Wipe.fs
│ │ │ ├── Directional.fs
│ │ │ ├── Dirty Lens.fs
│ │ │ ├── Displace.fs
│ │ │ ├── Displacement.fs
│ │ │ ├── Dither-Bayer.fs
│ │ │ ├── Doom Screen Transition.fs
│ │ │ ├── Doorway.fs
│ │ │ ├── Dot Screen.fs
│ │ │ ├── Dot Screen.vs
│ │ │ ├── Double Vision.fs
│ │ │ ├── Dreamy Zoom.fs
│ │ │ ├── Dreamy.fs
│ │ │ ├── Dual Side Scroller And Flip.fs
│ │ │ ├── Duotone.fs
│ │ │ ├── Echo Trace.fs
│ │ │ ├── Edge Blowout.fs
│ │ │ ├── Edge Blur.fs
│ │ │ ├── Edge Blur.vs
│ │ │ ├── Edge Distort.fs
│ │ │ ├── Edge Distort.vs
│ │ │ ├── Edge Trace.fs
│ │ │ ├── Edge Trace.vs
│ │ │ ├── Edges.fs
│ │ │ ├── Edges.vs
│ │ │ ├── Emboss.fs
│ │ │ ├── Emboss.vs
│ │ │ ├── Etch-a-Sketch.fs
│ │ │ ├── Exposure Adjust.fs
│ │ │ ├── Fade Color.fs
│ │ │ ├── Fade Gray Scale.fs
│ │ │ ├── Fade.fs
│ │ │ ├── False Color.fs
│ │ │ ├── Fast Blur.fs
│ │ │ ├── Fast Blur.vs
│ │ │ ├── FastMosh.fs
│ │ │ ├── FastMosh.vs
│ │ │ ├── Film Burn.fs
│ │ │ ├── Flip H.fs
│ │ │ ├── Flip V.fs
│ │ │ ├── Flipbook.fs
│ │ │ ├── Fly Eye.fs
│ │ │ ├── FractilianParabolicCircleInversion.fs
│ │ │ ├── Freeze Frame.fs
│ │ │ ├── Frosted Glass.fs
│ │ │ ├── Gamma Correction.fs
│ │ │ ├── Ghosting.fs
│ │ │ ├── Glitch Displace.fs
│ │ │ ├── Glitch Memories.fs
│ │ │ ├── Glitch Shifter.fs
│ │ │ ├── Gloom.fs
│ │ │ ├── Gloom.vs
│ │ │ ├── Glow-Fast.fs
│ │ │ ├── Glow-Fast.vs
│ │ │ ├── Glow.fs
│ │ │ ├── Glow.vs
│ │ │ ├── Graph Paper.fs
│ │ │ ├── GreatBallOfFire.fs
│ │ │ ├── Grid Flip.fs
│ │ │ ├── Grid Warp.fs
│ │ │ ├── HSVtoRGB.fs
│ │ │ ├── Hatch Blur.fs
│ │ │ ├── Heart Transition.fs
│ │ │ ├── Heart.fs
│ │ │ ├── HexVortex.fs
│ │ │ ├── Hexagonalize.fs
│ │ │ ├── Histogram Viewer.fs
│ │ │ ├── HorizVertHold.fs
│ │ │ ├── Hue-Saturation.fs
│ │ │ ├── Hyperspace.fs
│ │ │ ├── Interlace Mirror.fs
│ │ │ ├── Interlace.fs
│ │ │ ├── Inverted Page Curl.fs
│ │ │ ├── Kaleidoscope Tile.fs
│ │ │ ├── Kaleidoscope Transition.fs
│ │ │ ├── Kaleidoscope.fs
│ │ │ ├── Key Frame Artifacts.fs
│ │ │ ├── Layer Mask.fs
│ │ │ ├── Layer Position.fs
│ │ │ ├── Lens Flare.fs
│ │ │ ├── Lens Flare.vs
│ │ │ ├── Life.fs
│ │ │ ├── Life.vs
│ │ │ ├── Line Screen.fs
│ │ │ ├── Line Screen.vs
│ │ │ ├── Linear Blur.fs
│ │ │ ├── Linear Gradient.fs
│ │ │ ├── Lines.fs
│ │ │ ├── LogTransWarpSpiral.fs
│ │ │ ├── Long Exposure.fs
│ │ │ ├── Luma Transition.fs
│ │ │ ├── Luminance Melt.fs
│ │ │ ├── Luminance Posterize.fs
│ │ │ ├── MBOX3.fs
│ │ │ ├── Maximum Component.fs
│ │ │ ├── Median.fs
│ │ │ ├── Meta Image.fs
│ │ │ ├── Micro Buffer RGB.fs
│ │ │ ├── Micro Buffer.fs
│ │ │ ├── Minimum Component.fs
│ │ │ ├── Mirror Edge.fs
│ │ │ ├── Mirror Edge.vs
│ │ │ ├── Mirror.fs
│ │ │ ├── Morph.fs
│ │ │ ├── Mosaic.fs
│ │ │ ├── Multi Gradient.fs
│ │ │ ├── Multi Hue Shift.fs
│ │ │ ├── Multi Pass Gaussian Blur.fs
│ │ │ ├── Multi Pass Gaussian Blur.vs
│ │ │ ├── Multi-Pixellate.fs
│ │ │ ├── MultiFrame 2x2.fs
│ │ │ ├── MultiFrame 3x3.fs
│ │ │ ├── Multiply Blend.fs
│ │ │ ├── Neon.fs
│ │ │ ├── Neon.vs
│ │ │ ├── Night Vision.fs
│ │ │ ├── Noise Adapt.fs
│ │ │ ├── Noise Displace.fs
│ │ │ ├── Noise Pixellate.fs
│ │ │ ├── Noise.fs
│ │ │ ├── Optical Flow Distort.fs
│ │ │ ├── Optical Flow Distort.vs
│ │ │ ├── Optical Flow Generator.fs
│ │ │ ├── Perlin Transition.fs
│ │ │ ├── Pinch.fs
│ │ │ ├── Pinwheel.fs
│ │ │ ├── Pixel Shifter.fs
│ │ │ ├── Pixelize.fs
│ │ │ ├── Pixellate.fs
│ │ │ ├── Polar Function.fs
│ │ │ ├── Polka Dots Curtain.fs
│ │ │ ├── Poly Star.fs
│ │ │ ├── Posterize.fs
│ │ │ ├── Power Warp.fs
│ │ │ ├── Quad Mask.fs
│ │ │ ├── Quad Tile.fs
│ │ │ ├── RE RGB Gradient Generator.fs
│ │ │ ├── RGB EQ.fs
│ │ │ ├── RGB Halftone-lookaround.fs
│ │ │ ├── RGB Halftone.fs
│ │ │ ├── RGB Invert.fs
│ │ │ ├── RGB Strobe.fs
│ │ │ ├── RGB Trails 3.0.fs
│ │ │ ├── RGBA Swap.fs
│ │ │ ├── RGBtoHSV.fs
│ │ │ ├── Radial Gradient.fs
│ │ │ ├── Radial Replicate.fs
│ │ │ ├── Radial.fs
│ │ │ ├── Random Checkerboard.fs
│ │ │ ├── Random Freeze.fs
│ │ │ ├── Random Lines.fs
│ │ │ ├── Random Shape Blast.fs
│ │ │ ├── Random Shape.fs
│ │ │ ├── Random Squares Mask.fs
│ │ │ ├── Random Squares.fs
│ │ │ ├── Random Stripes.fs
│ │ │ ├── Replicate Random.fs
│ │ │ ├── Replicate.fs
│ │ │ ├── Resize Glitch.fs
│ │ │ ├── Ripple Transition.fs
│ │ │ ├── Ripples.fs
│ │ │ ├── Rotate Scale Fade.fs
│ │ │ ├── Rotate.fs
│ │ │ ├── Rotate.vs
│ │ │ ├── Saturation Bleed.fs
│ │ │ ├── Saturation Bleed.vs
│ │ │ ├── Sepia Tone.fs
│ │ │ ├── Set Alpha.fs
│ │ │ ├── Shake.fs
│ │ │ ├── Shape Mask.fs
│ │ │ ├── Shape Morph Feedback Mask.fs
│ │ │ ├── Shape Morph Wrap.fs
│ │ │ ├── Sharpen Luminance.fs
│ │ │ ├── Sharpen Luminance.vs
│ │ │ ├── Sharpen RGB.fs
│ │ │ ├── Sharpen RGB.vs
│ │ │ ├── Shockwave Pulse.fs
│ │ │ ├── Shockwave.fs
│ │ │ ├── Show Alpha.fs
│ │ │ ├── Side Scroller And Flip.fs
│ │ │ ├── Simple Zoom Transition.fs
│ │ │ ├── Sine Warp Gradient.fs
│ │ │ ├── Sine Warp Tile.fs
│ │ │ ├── Sketch.fs
│ │ │ ├── Sketch.vs
│ │ │ ├── Slice.fs
│ │ │ ├── Sliding Strips.fs
│ │ │ ├── Slit Scan Mask.fs
│ │ │ ├── Slit Scan.fs
│ │ │ ├── Smoke Screen.fs
│ │ │ ├── Smudged Lens.fs
│ │ │ ├── Smudged Lens.vs
│ │ │ ├── Soft Blur.fs
│ │ │ ├── Soft Blur.vs
│ │ │ ├── Soft Flip.fs
│ │ │ ├── Solarize.fs
│ │ │ ├── Solid Color.fs
│ │ │ ├── Sorting Smear.fs
│ │ │ ├── Sorting Smear.vs
│ │ │ ├── Sphere Map.fs
│ │ │ ├── Spiral.fs
│ │ │ ├── Squares Wire.fs
│ │ │ ├── Squeeze.fs
│ │ │ ├── Star.fs
│ │ │ ├── Stereo Viewer.fs
│ │ │ ├── Stripes.fs
│ │ │ ├── Strobe.fs
│ │ │ ├── Swap Transition.fs
│ │ │ ├── Swirl.fs
│ │ │ ├── TV Static.fs
│ │ │ ├── Time Glitch RGB.fs
│ │ │ ├── Toon.fs
│ │ │ ├── Trail Mask.fs
│ │ │ ├── Trapezoid Distortion.fs
│ │ │ ├── Triangle Warp.fs
│ │ │ ├── Triangle.fs
│ │ │ ├── Triangles.fs
│ │ │ ├── Trio Tone.fs
│ │ │ ├── Triple Rotate.fs
│ │ │ ├── Truchet Tile.fs
│ │ │ ├── Twirl.fs
│ │ │ ├── UltimateFlame.fs
│ │ │ ├── UltimateSpiral.fs
│ │ │ ├── Undulating Burn Out.fs
│ │ │ ├── Unsharp Mask.fs
│ │ │ ├── Unsharp Mask.vs
│ │ │ ├── VHS Glitch.fs
│ │ │ ├── VHS Glitch.fs.fs
│ │ │ ├── VU Meter.fs
│ │ │ ├── VVMotionBlur 3.0.fs
│ │ │ ├── Vertex Manipulator.fs
│ │ │ ├── Vertex Manipulator.vs
│ │ │ ├── Vertical Tearing.fs
│ │ │ ├── Vibrance.fs
│ │ │ ├── Vignette.fs
│ │ │ ├── Water Drop.fs
│ │ │ ├── WaveLines.fs
│ │ │ ├── White Point Adjust.fs
│ │ │ ├── Wind.fs
│ │ │ ├── Window Blinds.fs
│ │ │ ├── Window Slice.fs
│ │ │ ├── Wipe Down.fs
│ │ │ ├── Wipe Left.fs
│ │ │ ├── Wipe Right.fs
│ │ │ ├── Wipe Up.fs
│ │ │ ├── XYZoom.fs
│ │ │ ├── Y-C Time Blur.fs
│ │ │ ├── Zebre.fs
│ │ │ ├── Zoom In Circles.fs
│ │ │ ├── Zoom.fs
│ │ │ ├── Zooming Feedback.fs
│ │ │ ├── badtv.fs
│ │ │ ├── block-color.fs
│ │ │ ├── cube.fs
│ │ │ ├── digital-crystal-tunnel.fs
│ │ │ ├── feedback.fs
│ │ │ ├── film-grain.fs
│ │ │ ├── hexagons.fs
│ │ │ ├── plasma.fs
│ │ │ ├── rgbglitchmod.fs
│ │ │ ├── rgbtimeglitch.fs
│ │ │ ├── rotozoomer.fs
│ │ │ ├── scale.fs
│ │ │ ├── spherical-shader-tut.fs
│ │ │ ├── st_Ms2SD1.fs.fs
│ │ │ ├── st_lsfGDH.fs
│ │ │ ├── tapestryfract.fs
│ │ │ ├── v002 Bleach Bypass.fs
│ │ │ ├── v002 Crosshatch.fs
│ │ │ ├── v002 Dilate.fs
│ │ │ ├── v002 Dilate.vs
│ │ │ ├── v002 Erode.fs
│ │ │ ├── v002 Erode.vs
│ │ │ ├── v002 Light Leak.fs
│ │ │ ├── v002 Light Leak.vs
│ │ │ ├── v002 Technicolor.fs
│ │ │ ├── v002 Vignette.fs
│ │ │ ├── v002-CRT-Displacement.fs
│ │ │ ├── v002-CRT-Mask-RGB-Shadow.png
│ │ │ ├── v002-CRT-Mask-RGB-Staggered.png
│ │ │ ├── v002-CRT-Mask-RGB-Straight.png
│ │ │ ├── v002-CRT-Mask-Scanline-Staggered.png
│ │ │ └── v002-CRT-Mask.fs
│ ├── setup-beat-detektor.js
│ ├── setup-grandiose.js
│ ├── setup-media.js
│ ├── setup-midi.js
│ ├── setup-tweens.js
│ ├── use.js
│ ├── utils
│ │ ├── apply-expression.js
│ │ ├── conform-file-path.js
│ │ ├── get-next-name.js
│ │ ├── get-prop-default.js
│ │ ├── lerp.js
│ │ └── map.js
│ ├── window-handler.js
│ └── worker
│ │ ├── audio-features.js
│ │ ├── frame-counter.js
│ │ ├── index.worker.js
│ │ ├── loop.js
│ │ └── store
│ │ ├── index.js
│ │ └── modules
│ │ ├── beats.js
│ │ ├── common
│ │ └── swap.js
│ │ ├── dataTypes.js
│ │ ├── errors.js
│ │ ├── expressions.js
│ │ ├── fonts.js
│ │ ├── fps.js
│ │ ├── groups.js
│ │ ├── images.js
│ │ ├── inputs.js
│ │ ├── media.js
│ │ ├── mediaStream.js
│ │ ├── metrics.js
│ │ ├── meyda.js
│ │ ├── midi.js
│ │ ├── modules.js
│ │ ├── ndi.js
│ │ ├── outputs.js
│ │ ├── plugins.js
│ │ ├── projects.js
│ │ ├── renderers.js
│ │ ├── size.js
│ │ ├── tweens.js
│ │ ├── videos.js
│ │ └── windows.js
├── assets
│ ├── fonts
│ │ ├── Inter-italic.var.woff2
│ │ ├── Inter-roman.var.woff2
│ │ ├── iaw-mono-Bold.woff
│ │ ├── iaw-mono-Bold.woff2
│ │ ├── iaw-mono-BoldItalic.woff
│ │ ├── iaw-mono-BoldItalic.woff2
│ │ ├── iaw-mono-Italic.woff
│ │ ├── iaw-mono-Italic.woff2
│ │ ├── iaw-mono-Regular.woff
│ │ └── iaw-mono-Regular.woff2
│ └── graphics
│ │ ├── Arrow-vertical.svg
│ │ └── Arrow.svg
├── background
│ ├── background-constants.js
│ ├── background.js
│ ├── check-media-permission.js
│ ├── media-manager.js
│ ├── menu-bar.js
│ ├── open-file.js
│ ├── projects.js
│ ├── window-prefs.js
│ └── windows.js
├── components
│ ├── ABSwap.vue
│ ├── ActiveModule.vue
│ ├── CollapsibleRow.vue
│ ├── Control.vue
│ ├── Controls
│ │ ├── CollapsibleControl.vue
│ │ ├── ColorControl.vue
│ │ ├── FontControl.vue
│ │ ├── PaletteControl.vue
│ │ ├── RangeControl.vue
│ │ ├── TextureControl.vue
│ │ ├── TweenControl.vue
│ │ ├── Vec2DControl.vue
│ │ ├── Vec2DXY.vue
│ │ ├── Vec3Control.vue
│ │ ├── Vec4Control.vue
│ │ └── VideoControl.vue
│ ├── Dialog.vue
│ ├── ElectronLink.vue
│ ├── ErrorWatcher.vue
│ ├── Gallery.vue
│ ├── GalleryItem.vue
│ ├── Group.vue
│ ├── Groups.vue
│ ├── InfoView.vue
│ ├── InputConfig.vue
│ ├── InputDeviceConfig
│ │ ├── AudioVideo.vue
│ │ ├── BPM.vue
│ │ ├── MIDI.vue
│ │ └── NDI.vue
│ ├── InputLinkComponents
│ │ ├── AudioFeatures.vue
│ │ ├── Expression.vue
│ │ ├── MIDI.vue
│ │ └── Tween.vue
│ ├── ModuleControl.vue
│ ├── ModuleInspector.vue
│ ├── PluginControl.vue
│ ├── Plugins.vue
│ ├── Preview.vue
│ ├── Search.vue
│ ├── StatusBar
│ │ ├── BPMDisplay.vue
│ │ ├── FPSDisplay.vue
│ │ ├── SizeDisplay.vue
│ │ ├── StatusBarItem.vue
│ │ └── index.vue
│ ├── TooltipDisplay.vue
│ ├── dialogs
│ │ └── FrameRateDialog.vue
│ ├── directives
│ │ ├── ContextMenu.js
│ │ ├── InfoView.js
│ │ ├── Search.js
│ │ └── ValueTooltip.js
│ ├── inputs
│ │ ├── Button.vue
│ │ ├── Checkbox.vue
│ │ ├── Number.vue
│ │ ├── Range.vue
│ │ ├── RightClickNumberInput.vue
│ │ ├── Select.vue
│ │ ├── TextInput.vue
│ │ ├── Textarea.vue
│ │ └── index.js
│ └── mixins
│ │ ├── has-input-link.js
│ │ └── input-is-focused.js
├── css
│ ├── golden-layout_theme.css
│ ├── iaw.css
│ ├── inter.css
│ └── raster.css
├── main.js
├── media-manager
│ ├── add-read-handler.js
│ ├── add-save-handler.js
│ ├── create-watcher.js
│ ├── fs-create-profile.js
│ ├── index.js
│ ├── log.js
│ ├── media-manager-utils
│ │ └── stream-to-string.js
│ ├── parse-message.js
│ ├── read-file.js
│ ├── read-handlers
│ │ ├── image.js
│ │ ├── isf.js
│ │ ├── module.js
│ │ ├── palette.js
│ │ ├── preset.js
│ │ └── video.js
│ ├── save-handlers
│ │ └── preset.js
│ └── store
│ │ ├── index.js
│ │ └── modules
│ │ ├── media.js
│ │ ├── plugins.js
│ │ ├── read-handlers.js
│ │ └── save-handlers.js
├── menus
│ └── context
│ │ ├── activeModuleContextMenu.js
│ │ ├── activeModuleControlContextMenu.js
│ │ ├── bpmContextMenu.js
│ │ ├── galleryItemContextMenu.js
│ │ └── groupContextMenu.js
├── subpages
│ ├── color-picker
│ │ ├── App.vue
│ │ └── main.js
│ └── splash-screen
│ │ ├── App.vue
│ │ └── main.js
├── ui-store
│ ├── index.js
│ └── modules
│ │ ├── dialogs.js
│ │ ├── focus.js
│ │ ├── infoView.js
│ │ ├── search.js
│ │ ├── ui-groups.js
│ │ └── ui-modules.js
└── util
│ ├── composite-operations.js
│ └── font-family.js
├── tests
└── e2e
│ ├── extentions
│ ├── index.js
│ └── toBeJSON.js
│ ├── main.spec.js
│ ├── pageObjectModel
│ ├── gallery.js
│ ├── groups.js
│ ├── index.js
│ ├── modules.js
│ └── tabs.js
│ ├── spec
│ ├── general
│ │ ├── defaultGroupIsFocusedByDefault.spec.js
│ │ ├── renderersAreRegistered.spec.js
│ │ ├── rendersTheMainWindow.spec.js
│ │ └── searchGalleryAndAddModuleToGroup.spec.js
│ ├── groups
│ │ ├── alphaStateCanBeSet.spec.js
│ │ ├── backspaceRemovesFocusedGroup.spec.js
│ │ ├── blendModeStateCanBeSet.spec.js
│ │ ├── clearingStateCanBeToggledBetween0and1.spec.js
│ │ ├── createsADefaultGroup.spec.js
│ │ ├── enabledStateCanBeToggledBetween01and2.spec.js
│ │ ├── groupNameCanBeChanged.spec.js
│ │ ├── groupsCanBeRearranged.spec.js
│ │ ├── inheritAndInheritFromStateCanBeSet.spec.js
│ │ ├── newGroupButtonCreatesANewGroup.spec.js
│ │ └── pipelineStateCanBeToggledBetween0and1.spec.js
│ ├── inputLinks
│ │ └── inputConfigUpdatesWhenControlIsFocused.spec.js
│ └── presets
│ │ └── generatesAPresetWithExpectedKeys.spec.js
│ └── utils
│ └── setRangeValue.js
├── vue.config.js
└── yarn.lock
/.browserslistrc:
--------------------------------------------------------------------------------
1 | electron >= 11.2.0
2 |
--------------------------------------------------------------------------------
/.editorconfig:
--------------------------------------------------------------------------------
1 | root = true
2 |
3 | [*]
4 | charset = utf-8
5 | indent_style = space
6 | indent_size = 2
7 | end_of_line = lf
8 | insert_final_newline = true
9 | trim_trailing_whitespace = true
10 |
--------------------------------------------------------------------------------
/.eslintrc.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | root: true,
3 | env: {
4 | node: true
5 | },
6 | extends: ["plugin:vue/essential", "@vue/prettier"],
7 | plugins: ["no-for-each"],
8 | rules: {
9 | "no-console": "off",
10 | "no-debugger": process.env.NODE_ENV === "production" ? "error" : "off",
11 | "no-for-each/no-for-each": 2,
12 | "no-for-each/no-for-of": 2,
13 | "no-for-each/no-for-in": 2,
14 | "prefer-const": [
15 | "error",
16 | {
17 | destructuring: "any",
18 | ignoreReadBeforeAssign: false
19 | }
20 | ],
21 | curly: "error"
22 | },
23 | parserOptions: {
24 | parser: "babel-eslint"
25 | }
26 | };
27 |
--------------------------------------------------------------------------------
/.gitattributes:
--------------------------------------------------------------------------------
1 | * text=auto eol=lf
2 |
--------------------------------------------------------------------------------
/.github/FUNDING.yml:
--------------------------------------------------------------------------------
1 | github: 2xAA
2 | ko_fi: twoxAA
3 | patreon: vcync
4 | custom: ["https://www.paypal.me/2xAA"]
5 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/bug_report.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Bug report
3 | about: Create a report to help us improve
4 | title: ''
5 | labels: ''
6 | assignees: ''
7 |
8 | ---
9 |
10 | **Operating system and application version**
11 | - OS: [e.g. macOS]
12 | - Version [e.g. 3.0.8]
13 |
14 | **Describe the bug**
15 | A clear and concise description of what the bug is.
16 |
17 | **To Reproduce**
18 | Steps to reproduce the behavior:
19 | 1. Go to '...'
20 | 2. Click on '....'
21 | 3. Scroll down to '....'
22 | 4. See error
23 |
24 | **Expected behavior**
25 | A clear and concise description of what you expected to happen.
26 |
27 | **Screenshots**
28 | If applicable, add screenshots to help explain your problem.
29 |
30 | **Additional context**
31 | Add any other context about the problem here.
32 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/feature_request.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Feature request
3 | about: Suggest an idea for modV
4 | title: ''
5 | labels: ''
6 | assignees: ''
7 |
8 | ---
9 |
10 | **Is your feature request related to a problem? Please describe.**
11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
12 |
13 | **Describe the solution you'd like**
14 | A clear and concise description of what you want to happen.
15 |
16 | **Describe alternatives you've considered**
17 | A clear and concise description of any alternative solutions or features you've considered.
18 |
19 | **Additional context**
20 | Add any other context or screenshots about the feature request here.
21 |
--------------------------------------------------------------------------------
/.github/PULL_REQUEST_TEMPLATE/pull_request_template.md:
--------------------------------------------------------------------------------
1 | ### All Submissions:
2 |
3 | * [ ] Does this fix an issue? If so have you added the issue number? (fixes #000)
4 | * [ ] Have you checked to ensure there aren't other open [Pull Requests](https://github.com/vcync/modV/pulls) for the same update/change?
5 |
6 |
7 |
8 | ### New Feature Submissions:
9 |
10 | * [ ] Have you lint your code locally prior to submission? (either with `yarn run lint` or using git hooks)
11 | * [ ] If the feature is a UI element, have you added [`v-infoView`](https://modv.vcync.gl/v3/development/directives.html#infoview) with relevant documentation or added a [`v-searchTerms`](https://modv.vcync.gl/v3/development/directives.html#searchterms) search term?
12 |
13 | ### Changes to Core Features:
14 |
15 | * [ ] Have you added an explanation of what your changes do and why you'd like us to include them?
16 | * [ ] If the feature is a UI element, have you updated [`v-infoView`](https://modv.vcync.gl/v3/development/directives.html#infoview) with relevant documentation or added a [`v-searchTerms`](https://modv.vcync.gl/v3/development/directives.html#searchterms) search term?
17 |
--------------------------------------------------------------------------------
/.github/workflows/browserslist.yml:
--------------------------------------------------------------------------------
1 | name: Update Browserslist database
2 |
3 | on:
4 | schedule:
5 | - cron: '0 2 1,15 * *'
6 |
7 | permissions:
8 | contents: write
9 | pull-requests: write
10 |
11 | jobs:
12 | update-browserslist-database:
13 | runs-on: ubuntu-latest
14 | steps:
15 | - name: Checkout repository
16 | uses: actions/checkout@v3
17 | with:
18 | fetch-depth: 0
19 |
20 | - name: Configure git
21 | run: |
22 | git config --global user.email "action@github.com"
23 | git config --global user.name "GitHub Action"
24 |
25 | - name: Install libndi4_4.5.1-1_amd64.deb
26 | run: wget https://github.com/Palakis/obs-ndi/releases/download/4.9.0/libndi4_4.5.1-1_amd64.deb && sudo dpkg -i libndi4_4.5.1-1_amd64.deb
27 |
28 | - name: Update Browserslist database and create PR if applies
29 | uses: c2corg/browserslist-update-action@v2
30 | with:
31 | github_token: ${{ secrets.GITHUB_TOKEN }}
32 | branch: browserslist-update
33 | base_branch: next
34 | commit_message: 'build: update Browserslist db'
35 | title: 'build: update Browserslist db'
36 | body: Auto-generated by [browserslist-update-action](https://github.com/c2corg/browserslist-update-action/)
37 | labels: 'chores, github action'
38 |
--------------------------------------------------------------------------------
/.github/workflows/release.yml:
--------------------------------------------------------------------------------
1 | name: Release
2 | on:
3 | push:
4 | branches:
5 | - main
6 |
7 | env:
8 | EP_GH_IGNORE_TIME: true
9 |
10 | jobs:
11 | release:
12 | name: Release
13 |
14 | # specify the environment to select the right env variables
15 | environment: build
16 |
17 | runs-on: ubuntu-latest
18 |
19 | if: "!contains(github.event.head_commit.message, 'chore(release)')"
20 |
21 | steps:
22 | - name: Checkout
23 | uses: actions/checkout@v2
24 | with:
25 | fetch-depth: 0
26 |
27 | # required to use our own personal access token
28 | # we need to use a custom PAT as other workflows
29 | # aren't triggered using secrets.GITHUB_TOKEN
30 | persist-credentials: false
31 |
32 | - name: Setup Node.js
33 | uses: actions/setup-node@v1
34 | with:
35 | node-version: 20
36 |
37 | - name: Install libndi4_4.5.1-1_amd64.deb
38 | run: wget https://github.com/Palakis/obs-ndi/releases/download/4.9.0/libndi4_4.5.1-1_amd64.deb && sudo dpkg -i libndi4_4.5.1-1_amd64.deb
39 |
40 | - name: Install dependencies
41 | run: yarn install --frozen-lockfile
42 |
43 | - name: Release
44 | env:
45 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
46 |
47 | run: npx semantic-release
48 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | node_modules
3 | /dist
4 |
5 | # npm lockfile
6 | package-lock.json
7 |
8 | # local env files
9 | .env.local
10 | .env.*.local
11 |
12 | # Log files
13 | npm-debug.log*
14 | yarn-debug.log*
15 | yarn-error.log*
16 |
17 | # Editor directories and files
18 | .idea
19 | *.suo
20 | *.ntvs*
21 | *.njsproj
22 | *.sln
23 | *.sw?
24 |
25 | #Electron-builder output
26 | /dist_electron
27 | .env
28 |
--------------------------------------------------------------------------------
/.releaserc:
--------------------------------------------------------------------------------
1 | {
2 | "branches": ["main"],
3 | "tagFormat": "${version}",
4 | "plugins": [
5 | "@semantic-release/commit-analyzer",
6 | "@semantic-release/release-notes-generator",
7 | "@semantic-release/npm",
8 | ["@semantic-release/git", {
9 | "assets": ["package.json"],
10 | "message": "chore(release): ${nextRelease.version} \n\n${nextRelease.notes}"
11 | }],
12 | "@semantic-release/github"
13 | ]
14 | }
15 |
--------------------------------------------------------------------------------
/.vscode/extensions.json:
--------------------------------------------------------------------------------
1 | {
2 | "recommendations": [
3 | "vue.volar",
4 | "esbenp.prettier-vscode",
5 | "dbaeumer.vscode-eslint"
6 | ]
7 | }
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2020 vcync
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/babel.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | presets: [
3 | "@vue/app",
4 | {
5 | exclude: ["transform-regenerator"]
6 | }
7 | ],
8 | plugins: [
9 | "@babel/plugin-proposal-nullish-coalescing-operator",
10 | "@babel/plugin-proposal-optional-chaining"
11 | ]
12 | };
13 |
--------------------------------------------------------------------------------
/build/entitlements.mac.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | com.apple.security.cs.allow-unsigned-executable-memory
6 |
7 | com.apple.security.cs.allow-jit
8 |
9 | com.apple.security.device.audio-input
10 |
11 | com.apple.security.device.camera
12 |
13 | com.apple.security.cs.disable-library-validation
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/build/icon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vcync/modV/c606793d54d00f5a56e1121f3593f9585b20623f/build/icon.ico
--------------------------------------------------------------------------------
/build/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vcync/modV/c606793d54d00f5a56e1121f3593f9585b20623f/build/icon.png
--------------------------------------------------------------------------------
/build/icon@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vcync/modV/c606793d54d00f5a56e1121f3593f9585b20623f/build/icon@2x.png
--------------------------------------------------------------------------------
/jsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extensions": [
3 | ".vue"
4 | ],
5 | "vueCompilerOptions": {
6 | "target": 2
7 | }
8 | }
--------------------------------------------------------------------------------
/notarize.js:
--------------------------------------------------------------------------------
1 | require("dotenv").config();
2 | const { notarize } = require("electron-notarize");
3 |
4 | exports.default = async function notarizing(context) {
5 | const { electronPlatformName, appOutDir } = context;
6 | if (
7 | electronPlatformName !== "darwin" ||
8 | !process.env.APPLEID ||
9 | !process.env.APPLEIDPASS
10 | ) {
11 | return;
12 | }
13 |
14 | const appName = context.packager.appInfo.productFilename;
15 |
16 | console.log(" • notarizing");
17 |
18 | return await notarize({
19 | tool: "notarytool",
20 | appPath: `${appOutDir}/${appName}.app`,
21 | appleId: process.env.APPLEID,
22 | appleIdPassword: process.env.APPLEIDPASS,
23 | teamId: process.env.APPLE_TEAM_ID
24 | });
25 | };
26 |
--------------------------------------------------------------------------------
/playwright.config.js:
--------------------------------------------------------------------------------
1 | import { defineConfig, expect } from "@playwright/test";
2 | import extensions from "./tests/e2e/extentions";
3 |
4 | expect.extend(extensions);
5 |
6 | export default defineConfig({
7 | testDir: "./tests/e2e/spec",
8 | workers: process.env.CI ? 1 : 2
9 | });
10 |
--------------------------------------------------------------------------------
/postcss.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | plugins: {
3 | autoprefixer: {}
4 | }
5 | };
6 |
--------------------------------------------------------------------------------
/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vcync/modV/c606793d54d00f5a56e1121f3593f9585b20623f/public/favicon.ico
--------------------------------------------------------------------------------
/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
18 |
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/public/output-window.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
22 |
23 |
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/src/application/constants.js:
--------------------------------------------------------------------------------
1 | export default {
2 | get GALLERY_GROUP_NAME() {
3 | return "modV internal Gallery Group";
4 | },
5 |
6 | get LAYOUT_STATE_KEY() {
7 | return "layoutState";
8 | },
9 |
10 | get LAYOUT_LOAD_ERROR() {
11 | return "layoutLoadError";
12 | },
13 |
14 | get AUDIO_BUFFER_SIZE() {
15 | return 512;
16 | }
17 | };
18 |
19 | export const GROUP_DISABLED = 0;
20 | export const GROUP_ENABLED = 1;
21 | export const GROUP_DRAW_TO_OUTPUT = 2;
22 |
--------------------------------------------------------------------------------
/src/application/install-plugin.js:
--------------------------------------------------------------------------------
1 | import store from "./worker/store";
2 | import uiStore from "../ui-store";
3 | import Vue from "vue";
4 |
5 | function camelize(str) {
6 | return str.replace(/(?:^\w|[A-Z]|\b\w|\s+)/g, (match, index) => {
7 | if (+match === 0) {
8 | return "";
9 | } // or if (/\s+/.test(match)) for white spaces
10 | return index === 0 ? match.toLowerCase() : match.toUpperCase();
11 | });
12 | }
13 |
14 | export default function installPlugin(plugin) {
15 | if (!("name" in plugin)) {
16 | throw new Error("Plugin requires a name");
17 | }
18 |
19 | store.dispatch("plugins/add", plugin);
20 |
21 | if ("store" in plugin) {
22 | const storeName = plugin.storeName || camelize(plugin.name);
23 | store.registerModule(storeName, plugin.store);
24 | }
25 |
26 | if ("uiStore" in plugin) {
27 | const uiStoreName = plugin.uiStoreName || camelize(plugin.name);
28 | uiStore.registerModule(uiStoreName, plugin.uiStore);
29 | }
30 |
31 | if ("galleryTabComponent" in plugin) {
32 | Vue.component(plugin.galleryTabComponent.name, plugin.galleryTabComponent);
33 | }
34 |
35 | if ("controlPanelComponent" in plugin) {
36 | Vue.component(
37 | plugin.controlPanelComponent.name,
38 | plugin.controlPanelComponent
39 | );
40 | }
41 |
42 | if ("install" in plugin) {
43 | plugin.install(Vue, store, uiStore);
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/src/application/plugins/feature-assignment/index.js:
--------------------------------------------------------------------------------
1 | import featureStoreModule from "./store";
2 |
3 | export default {
4 | name: "Feature Assignment",
5 | store: featureStoreModule,
6 |
7 | preProcessFrame({ features, store }) {
8 | if (!features) {
9 | return;
10 | }
11 |
12 | const availableFeatures = Object.keys(features);
13 | const availableFeaturesLength = availableFeatures.length;
14 |
15 | for (let i = 0; i < availableFeaturesLength; ++i) {
16 | const feature = availableFeatures[i];
17 | if (featureStoreModule.state[feature]) {
18 | const featureData = features[feature];
19 | const modulesToUpdate = Object.keys(featureStoreModule.state[feature]);
20 | const modulesToUpdateLength = modulesToUpdate.length;
21 |
22 | for (let j = 0; j < modulesToUpdateLength; ++j) {
23 | const moduleId = modulesToUpdate[j];
24 | const props = featureStoreModule.state[feature][moduleId];
25 |
26 | for (let k = 0; k < props.length; ++k) {
27 | const prop = props[k];
28 | store.dispatch("modules/updateProp", {
29 | moduleId,
30 | prop,
31 | data: featureData
32 | });
33 | }
34 | }
35 | }
36 | }
37 | }
38 | };
39 |
--------------------------------------------------------------------------------
/src/application/plugins/feature-assignment/store.js:
--------------------------------------------------------------------------------
1 | const state = {
2 | feature: {
3 | moduleId: ["prop"]
4 | }
5 | };
6 |
7 | const mutations = {
8 | ADD_FEATURE_ASSIGNMENT(state, { moduleId, prop, feature }) {
9 | if (!state[feature]) {
10 | state[feature] = {};
11 | }
12 |
13 | if (!state[feature][moduleId]) {
14 | state[feature][moduleId] = [];
15 | }
16 |
17 | state[feature][moduleId].push(prop);
18 | },
19 |
20 | REMOVE_FEATURE_ASSIGNMENT(state, { moduleId, prop, feature }) {
21 | if (!state[feature] || !state[feature][moduleId]) {
22 | return;
23 | }
24 |
25 | const index = state[feature][moduleId].indexOf(prop);
26 | if (index > -1) {
27 | state[feature][moduleId].splice(index, 1);
28 | }
29 | }
30 | };
31 |
32 | export default {
33 | namespaced: true,
34 | state,
35 | mutations
36 | };
37 |
--------------------------------------------------------------------------------
/src/application/renderers/shader.js:
--------------------------------------------------------------------------------
1 | import * as shader from "./shader/index";
2 | export default shader;
3 |
--------------------------------------------------------------------------------
/src/application/sample-modules/ChromaticAbberation.js:
--------------------------------------------------------------------------------
1 | import chromaticAbberationFrag from "./ChromaticAbberation/chromaticAbberation.frag";
2 |
3 | export default {
4 | meta: {
5 | name: "Chromatic Abberation",
6 | author: "2xAA",
7 | version: "1.0.0",
8 | previewWithOutput: true,
9 | meyda: [], // returned variables passed to the shader individually as uniforms
10 | type: "shader"
11 | },
12 | fragmentShader: chromaticAbberationFrag,
13 |
14 | props: {
15 | rOffset: {
16 | type: "float",
17 | label: "Red Offset",
18 | min: 1.0,
19 | max: 2.0,
20 | step: 0.001,
21 | default: 1.0
22 | },
23 | gOffset: {
24 | type: "float",
25 | label: "Green Offset",
26 | min: 1.0,
27 | max: 2.0,
28 | step: 0.001,
29 | default: 1.015
30 | },
31 | bOffset: {
32 | type: "float",
33 | label: "Blue Offset",
34 | min: 1.0,
35 | max: 2.0,
36 | step: 0.001,
37 | default: 1.03
38 | }
39 | }
40 | };
41 |
--------------------------------------------------------------------------------
/src/application/sample-modules/ChromaticAbberation/chromaticAbberation.frag:
--------------------------------------------------------------------------------
1 | // from here: https://www.shadertoy.com/view/MtXXDr
2 |
3 | precision mediump float;
4 | uniform float rOffset; //1.0
5 | uniform float gOffset; //1.015
6 | uniform float bOffset; //1.03
7 |
8 | void mainImage( out vec4 fragColor, in vec2 fragCoord ) {
9 | vec3 refractiveIndex = vec3(rOffset, gOffset, bOffset);
10 | vec2 uv = vUv;
11 | vec2 normalizedTexCoord = vec2(2.0, 2.0) * uv - vec2(1.0, 1.0); // [0, 1] -> [-1, 1]
12 | vec3 texVec = vec3(normalizedTexCoord, 1.0);
13 | vec3 normalVec = vec3(0.0, 0.0, -1.0);
14 | vec3 redRefractionVec = refract(texVec, normalVec, refractiveIndex.r);
15 | vec3 greenRefractionVec = refract(texVec, normalVec, refractiveIndex.g);
16 | vec3 blueRefractionVec = refract(texVec, normalVec, refractiveIndex.b);
17 | vec2 redTexCoord = ((redRefractionVec / redRefractionVec.z).xy + vec2(1.0, 1.0)) / vec2(2.0, 2.0);
18 | vec2 greenTexCoord = ((greenRefractionVec / greenRefractionVec.z).xy + vec2(1.0, 1.0)) / vec2(2.0, 2.0);
19 | vec2 blueTexCoord = ((blueRefractionVec / blueRefractionVec.z).xy + vec2(1.0, 1.0)) / vec2(2.0, 2.0);
20 |
21 | fragColor = vec4
22 | (
23 | texture(u_modVCanvas, redTexCoord).r,
24 | texture(u_modVCanvas, greenTexCoord).g,
25 | texture(u_modVCanvas, blueTexCoord).b,
26 | texture(u_modVCanvas, vUv).a
27 | );
28 | }
--------------------------------------------------------------------------------
/src/application/sample-modules/Counter.js:
--------------------------------------------------------------------------------
1 | export default {
2 | meta: {
3 | name: "Counter",
4 | type: "2d"
5 | },
6 |
7 | props: {
8 | input1: {
9 | default: 0.5,
10 | min: 0,
11 | max: 1,
12 | type: "float"
13 | }
14 | },
15 |
16 | data: {
17 | counter: 0
18 | },
19 |
20 | multiply(value, multiplier) {
21 | return value * multiplier;
22 | },
23 |
24 | update({ data, props }) {
25 | data.counter += this.multiply(props.input1, 2);
26 | return data;
27 | },
28 |
29 | draw({ data, context, canvas: { width, height } }) {
30 | context.fillStyle = "white";
31 | context.fillRect(0, 0, width, height);
32 | context.fillStyle = "black";
33 | context.fillText(data.counter, width / 2, height / 2);
34 | }
35 | };
36 |
--------------------------------------------------------------------------------
/src/application/sample-modules/Fisheye.js:
--------------------------------------------------------------------------------
1 | import fragmentShader from "./Fisheye/fisheye.frag";
2 |
3 | export default {
4 | meta: {
5 | name: "Fisheye",
6 | type: "shader",
7 | version: "1.0.0",
8 | author: "???",
9 | previewWithOutput: true
10 | },
11 |
12 | fragmentShader,
13 |
14 | props: {
15 | aperture: {
16 | type: "float",
17 | label: "Aperture",
18 | default: 180.0,
19 | min: 1.0,
20 | max: 360.0,
21 | step: 0.5
22 | }
23 | }
24 | };
25 |
--------------------------------------------------------------------------------
/src/application/sample-modules/Fisheye/fisheye.frag:
--------------------------------------------------------------------------------
1 | // Inspired by the "Angular Fisheye à la Bourke" sketch from
2 | // Jonathan Cremieux, as shown in the OpenProcessing website:
3 | // http://openprocessing.org/visuals/?visualID=12140
4 | // Using the inverse transform of the angular fisheye as
5 | // explained in Paul Bourke's website:
6 | // http://paulbourke.net/miscellaneous/domefisheye/fisheye/
7 |
8 | precision mediump float;
9 |
10 | uniform sampler2D u_modVCanvas;
11 | uniform float aperture;
12 |
13 | varying vec2 vUv;
14 |
15 | const float PI = 3.1415926535;
16 |
17 | void main(void) {
18 | float apertureHalf = 0.5 * aperture * (PI / 180.0);
19 |
20 | // This factor ajusts the coordinates in the case that
21 | // the aperture angle is less than 180 degrees, in which
22 | // case the area displayed is not the entire half-sphere.
23 | float maxFactor = sin(apertureHalf);
24 |
25 | vec2 pos = 2.0 * vUv - 1.0;
26 |
27 | float l = length(pos);
28 | if (l > 1.0) {
29 | gl_FragColor = vec4(0, 0, 0, 1);
30 | } else {
31 | float x = maxFactor * pos.x;
32 | float y = maxFactor * pos.y;
33 |
34 | float n = length(vec2(x, y));
35 |
36 | float z = sqrt(1.0 - n * n);
37 |
38 | float r = atan(n, z) / PI;
39 |
40 | float phi = atan(y, x);
41 |
42 | float u = r * cos(phi) + 0.5;
43 | float v = r * sin(phi) + 0.5;
44 |
45 | gl_FragColor = texture2D(u_modVCanvas, vec2(u, v));
46 | }
47 | }
--------------------------------------------------------------------------------
/src/application/sample-modules/MattiasCRT-2.0.js:
--------------------------------------------------------------------------------
1 | import crtFrag from "./MattiasCRT/mattiasCrt.frag";
2 |
3 | export default {
4 | meta: {
5 | name: "MattiasCRT",
6 | author: "Mattias",
7 | version: "1.0.0",
8 | previewWithOutput: true,
9 | type: "shader"
10 | },
11 | fragmentShader: crtFrag
12 | };
13 |
--------------------------------------------------------------------------------
/src/application/sample-modules/Plasma.js:
--------------------------------------------------------------------------------
1 | import plasmaFrag from "./Plasma/plasma.frag";
2 |
3 | export default {
4 | meta: {
5 | name: "Plasma",
6 | author: "2xAA",
7 | version: 0.1,
8 | meyda: [], // returned variables passed to the shader individually as uniforms
9 | type: "shader"
10 | },
11 | fragmentShader: plasmaFrag,
12 | props: {
13 | u_scaleX: {
14 | type: "float",
15 | label: "Scale X",
16 | min: 1.0,
17 | max: 150.0,
18 | step: 1.0,
19 | default: 50.0
20 | },
21 |
22 | u_scaleY: {
23 | type: "float",
24 | label: "Scale Y",
25 | min: 1.0,
26 | max: 150.0,
27 | step: 1.0,
28 | default: 50.0
29 | },
30 |
31 | u_timeScale: {
32 | type: "float",
33 | label: "Time Scale",
34 | min: 1.0,
35 | max: 1000.0,
36 | step: 1.0,
37 | default: 100.0
38 | }
39 | }
40 | };
41 |
--------------------------------------------------------------------------------
/src/application/sample-modules/Plasma/plasma.frag:
--------------------------------------------------------------------------------
1 | /* spec: webgl */
2 | precision mediump float;
3 |
4 | #define PI 3.1415926535897932384626433832795
5 |
6 | uniform float u_time;
7 | uniform float u_scaleX;
8 | uniform float u_scaleY;
9 | uniform float u_timeScale;
10 | uniform vec3 iResolution;
11 | varying vec2 vUv;
12 |
13 | void main() {
14 | float time = u_time / u_timeScale;
15 | vec2 u_scale = vec2(iResolution.x / u_scaleX, iResolution.y / u_scaleY);
16 | float v = 0.0;
17 | vec2 c = vUv * u_scale - u_scale/2.0;
18 | v += sin((c.x+time));
19 | v += sin((c.y+time)/2.0);
20 | v += sin((c.x+c.y+time)/2.0);
21 | c += u_scale/2.0 * vec2(sin(time/3.0), cos(time/2.0));
22 | v += sin(sqrt(c.x*c.x+c.y*c.y+1.0)+time);
23 | v = v/2.0;
24 | vec3 col = vec3(1, sin(PI*v), cos(PI*v));
25 | gl_FragColor = vec4(col*.5 + .5, 1);
26 | }
--------------------------------------------------------------------------------
/src/application/sample-modules/Smear.js:
--------------------------------------------------------------------------------
1 | export default {
2 | meta: {
3 | name: "Smear",
4 | type: "2d",
5 | audioFeatures: ["rms", "energy"]
6 | },
7 |
8 | props: {
9 | speedX: {
10 | type: "int",
11 | min: -20,
12 | max: 20,
13 | default: 0
14 | },
15 | speedY: {
16 | type: "int",
17 | min: -20,
18 | max: 20,
19 | default: 10
20 | },
21 | sizeX: {
22 | type: "int",
23 | min: -20,
24 | max: 20,
25 | default: 0
26 | },
27 | sizeY: {
28 | type: "int",
29 | min: -20,
30 | max: 20,
31 | default: 0
32 | }
33 | },
34 |
35 | draw({ context, canvas, props }) {
36 | const { width, height } = canvas;
37 | const { speedX, speedY, sizeX, sizeY } = props;
38 |
39 | context.drawImage(canvas, -speedX, -speedY, width + sizeX, height + sizeY);
40 | }
41 | };
42 |
--------------------------------------------------------------------------------
/src/application/sample-modules/Webcam.js:
--------------------------------------------------------------------------------
1 | export default {
2 | meta: {
3 | type: "2d",
4 | name: "Webcam",
5 | author: "2xAA",
6 | version: "1.0.0"
7 | },
8 |
9 | props: {
10 | scale: {
11 | type: "float",
12 | min: 0,
13 | max: 10,
14 | default: 1
15 | },
16 |
17 | position: {
18 | type: "vec2",
19 | default: [0.5, 0.5],
20 | min: 0,
21 | max: 1
22 | },
23 |
24 | imageSmoothing: {
25 | type: "bool",
26 | default: true
27 | }
28 | },
29 |
30 | draw({ canvas, context, video: { canvas: video }, props }) {
31 | const { position, scale, imageSmoothing } = props;
32 | const { width: videoWidth, height: videoHeight } = video;
33 | const { width, height } = canvas;
34 |
35 | context.imageSmoothingEnabled = imageSmoothing;
36 |
37 | context.drawImage(
38 | video,
39 | width * position[0] - (videoWidth * scale) / 2,
40 | height * (1 - position[1]) - (videoHeight * scale) / 2,
41 | videoWidth * scale,
42 | videoHeight * scale
43 | );
44 | }
45 | };
46 |
--------------------------------------------------------------------------------
/src/application/sample-modules/Wobble.js:
--------------------------------------------------------------------------------
1 | import fragmentShader from "./Wobble/wobble.frag";
2 |
3 | export default {
4 | meta: {
5 | type: "shader",
6 | name: "Wobble",
7 | author: "2xAA",
8 | version: "1.0.0",
9 | previewWithOutput: true
10 | },
11 |
12 | fragmentShader,
13 |
14 | props: {
15 | strength: {
16 | type: "float",
17 | label: "Float",
18 | min: 0.0,
19 | max: 0.05,
20 | step: 0.001,
21 | default: 0.001
22 | },
23 |
24 | size: {
25 | type: "float",
26 | label: "Size",
27 | min: 1.0,
28 | max: 50.0,
29 | step: 1.0,
30 | default: 1.0
31 | }
32 | }
33 | };
34 |
--------------------------------------------------------------------------------
/src/application/sample-modules/Wobble/wobble.frag:
--------------------------------------------------------------------------------
1 | /* spec: webgl */
2 | // from here: https://getmosh.io/
3 |
4 | precision mediump float;
5 |
6 | uniform sampler2D u_modVCanvas;
7 | uniform float iGlobalTime;
8 | uniform float strength;
9 | uniform float size;
10 | float speed = 1.0;
11 | varying vec2 vUv;
12 |
13 | void main() {
14 | vec2 p = -1.0 + 2.0 * vUv;
15 | gl_FragColor = texture2D(
16 | u_modVCanvas,
17 | vUv + strength * vec2(
18 | cos(iGlobalTime * speed + length(p * size)),
19 | sin(iGlobalTime * speed + length(p * size))
20 | )
21 | );
22 | }
--------------------------------------------------------------------------------
/src/application/sample-modules/isf/ASCII Art.fs:
--------------------------------------------------------------------------------
1 | /*{
2 | "DESCRIPTION": "ASCII Art",
3 | "CREDIT": "by IMIMOT (Ported from https://www.shadertoy.com/view/lssGDj)",
4 | "CATEGORIES": [
5 | "Stylize"
6 | ],
7 | "INPUTS": [
8 | {
9 | "NAME": "inputImage",
10 | "TYPE": "image"
11 | },
12 | {
13 | "NAME": "amount",
14 | "TYPE": "float",
15 | "DEFAULT": 0.0
16 | }
17 | ]
18 |
19 | }*/
20 |
21 | float character(float n, vec2 p) // some compilers have the word "char" reserved
22 | {
23 | p = floor(p*vec2(4.0, -4.0) + 2.5);
24 | if (clamp(p.x, 0.0, 4.0) == p.x && clamp(p.y, 0.0, 4.0) == p.y)
25 | {
26 | if (int(mod(n/exp2(p.x + 5.0*p.y), 2.0)) == 1) return 1.0;
27 | }
28 | return 0.0;
29 | }
30 |
31 |
32 |
33 | void main() {
34 | float _amount = amount*36.0+8.0;
35 | vec2 uv = gl_FragCoord.xy;
36 | vec3 col = IMG_NORM_PIXEL(inputImage, (floor(uv/_amount)*_amount/RENDERSIZE.xy)).rgb;
37 |
38 |
39 | float gray = (col.r + col.g + col.b)/3.0;
40 |
41 | float n = 65536.0; // .
42 | if (gray > 0.2) n = 65600.0; // :
43 | if (gray > 0.3) n = 332772.0; // *
44 | if (gray > 0.4) n = 15255086.0; // o
45 | if (gray > 0.5) n = 23385164.0; // &
46 | if (gray > 0.6) n = 15252014.0; // 8
47 | if (gray > 0.7) n = 13199452.0; // @
48 | if (gray > 0.8) n = 11512810.0; // #
49 |
50 | vec2 p = mod(uv/(_amount/2.0), 2.0) - vec2(1.0);
51 | col = col*character(n, p);
52 | gl_FragColor = vec4(col, 1.0);
53 |
54 | }
55 |
--------------------------------------------------------------------------------
/src/application/sample-modules/isf/Auto Levels.vs:
--------------------------------------------------------------------------------
1 | #if __VERSION__ <= 120
2 | varying vec2 left_coord;
3 | varying vec2 right_coord;
4 | varying vec2 above_coord;
5 | varying vec2 below_coord;
6 |
7 | varying vec2 lefta_coord;
8 | varying vec2 righta_coord;
9 | varying vec2 leftb_coord;
10 | varying vec2 rightb_coord;
11 | #else
12 | out vec2 left_coord;
13 | out vec2 right_coord;
14 | out vec2 above_coord;
15 | out vec2 below_coord;
16 |
17 | out vec2 lefta_coord;
18 | out vec2 righta_coord;
19 | out vec2 leftb_coord;
20 | out vec2 rightb_coord;
21 | #endif
22 |
23 | void main()
24 | {
25 | isf_vertShaderInit();
26 | vec2 texc = vec2(isf_FragNormCoord[0],isf_FragNormCoord[1]);
27 | vec2 d = 1.0/RENDERSIZE;
28 |
29 | left_coord = clamp(vec2(texc.xy + vec2(-d.x , 0)),0.0,1.0);
30 | right_coord = clamp(vec2(texc.xy + vec2(d.x , 0)),0.0,1.0);
31 | above_coord = clamp(vec2(texc.xy + vec2(0,d.y)),0.0,1.0);
32 | below_coord = clamp(vec2(texc.xy + vec2(0,-d.y)),0.0,1.0);
33 |
34 | d = 1.0/RENDERSIZE;
35 | lefta_coord = clamp(vec2(texc.xy + vec2(-d.x , d.x)),0.0,1.0);
36 | righta_coord = clamp(vec2(texc.xy + vec2(d.x , d.x)),0.0,1.0);
37 | leftb_coord = clamp(vec2(texc.xy + vec2(-d.x , -d.x)),0.0,1.0);
38 | rightb_coord = clamp(vec2(texc.xy + vec2(d.x , -d.x)),0.0,1.0);
39 | }
--------------------------------------------------------------------------------
/src/application/sample-modules/isf/Bright.fs:
--------------------------------------------------------------------------------
1 | /*{
2 | "CREDIT": "by zoidberg",
3 | "ISFVSN": "2",
4 | "CATEGORIES": [
5 | "Color Adjustment"
6 | ],
7 | "INPUTS": [
8 | {
9 | "NAME": "inputImage",
10 | "TYPE": "image"
11 | },
12 | {
13 | "NAME": "bright",
14 | "TYPE": "float",
15 | "MIN": -1.0,
16 | "MAX": 1.0,
17 | "DEFAULT": 0.0
18 | }
19 | ]
20 | }*/
21 |
22 | void main() {
23 | gl_FragColor = clamp(IMG_THIS_PIXEL(inputImage) + vec4(bright,bright,bright,0.0), 0.0, 1.0);
24 | }
--------------------------------------------------------------------------------
/src/application/sample-modules/isf/BrightnessContrast.fs:
--------------------------------------------------------------------------------
1 | /*
2 | {
3 | "DESCRIPTION" : "Brightness\/Contrast adjustment",
4 | "ISFVSN" : "2",
5 | "INPUTS" : [
6 | {
7 | "NAME" : "inputImage",
8 | "TYPE" : "image"
9 | },
10 | {
11 | "NAME" : "brightness",
12 | "TYPE" : "float",
13 | "MAX" : 1,
14 | "DEFAULT" : 0,
15 | "MIN" : -1
16 | },
17 | {
18 | "NAME" : "contrast",
19 | "TYPE" : "float",
20 | "MAX" : 2,
21 | "DEFAULT" : 1,
22 | "MIN" : 0
23 | }
24 | ],
25 | "CREDIT" : ""
26 | }
27 | */
28 |
29 | void main() {
30 | vec3 color = IMG_PIXEL(inputImage, gl_FragCoord.xy).rgb;
31 | vec3 colorContrasted = (color) * contrast;
32 | vec3 bright = colorContrasted + vec3(brightness,brightness,brightness);
33 | gl_FragColor = vec4(bright, IMG_PIXEL(inputImage, gl_FragCoord.xy).a);
34 | }
35 |
--------------------------------------------------------------------------------
/src/application/sample-modules/isf/Burn.fs:
--------------------------------------------------------------------------------
1 | /*{
2 | "CATEGORIES": [
3 | "Dissolve"
4 | ],
5 | "CREDIT": "Automatically converted from https://www.github.com/gl-transitions/gl-transitions/tree/master/burn.glsl",
6 | "DESCRIPTION": "",
7 | "INPUTS": [
8 | {
9 | "NAME": "startImage",
10 | "TYPE": "image"
11 | },
12 | {
13 | "NAME": "endImage",
14 | "TYPE": "image"
15 | },
16 | {
17 | "DEFAULT": 0,
18 | "MAX": 1,
19 | "MIN": 0,
20 | "NAME": "progress",
21 | "TYPE": "float"
22 | },
23 | {
24 | "DEFAULT": [
25 | 1,
26 | 1,
27 | 1,
28 | 1
29 | ],
30 | "NAME": "color",
31 | "TYPE": "color"
32 | }
33 | ],
34 | "ISFVSN": "2"
35 | }
36 | */
37 |
38 |
39 |
40 | vec4 getFromColor(vec2 inUV) {
41 | return IMG_NORM_PIXEL(startImage, inUV);
42 | }
43 | vec4 getToColor(vec2 inUV) {
44 | return IMG_NORM_PIXEL(endImage, inUV);
45 | }
46 |
47 |
48 |
49 | // author: gre
50 | // License: MIT
51 | vec4 transition (vec2 uv) {
52 | return mix(
53 | getFromColor(uv) + progress*color,
54 | getToColor(uv) + (1.0-progress)*color,
55 | progress
56 | );
57 | }
58 |
59 |
60 |
61 | void main() {
62 | gl_FragColor = transition(isf_FragNormCoord.xy);
63 | }
--------------------------------------------------------------------------------
/src/application/sample-modules/isf/Circular Screen.vs:
--------------------------------------------------------------------------------
1 | #if __VERSION__ <= 120
2 | varying vec2 left_coord;
3 | varying vec2 right_coord;
4 | varying vec2 above_coord;
5 | varying vec2 below_coord;
6 |
7 | varying vec2 lefta_coord;
8 | varying vec2 righta_coord;
9 | varying vec2 leftb_coord;
10 | varying vec2 rightb_coord;
11 | #else
12 | out vec2 left_coord;
13 | out vec2 right_coord;
14 | out vec2 above_coord;
15 | out vec2 below_coord;
16 |
17 | out vec2 lefta_coord;
18 | out vec2 righta_coord;
19 | out vec2 leftb_coord;
20 | out vec2 rightb_coord;
21 | #endif
22 |
23 |
24 | void main()
25 | {
26 | isf_vertShaderInit();
27 | vec2 texc = vec2(isf_FragNormCoord[0],isf_FragNormCoord[1]);
28 | vec2 d = 1.0/RENDERSIZE;
29 |
30 | left_coord = clamp(vec2(texc.xy + vec2(-d.x , 0)),0.0,1.0);
31 | right_coord = clamp(vec2(texc.xy + vec2(d.x , 0)),0.0,1.0);
32 | above_coord = clamp(vec2(texc.xy + vec2(0,d.y)),0.0,1.0);
33 | below_coord = clamp(vec2(texc.xy + vec2(0,-d.y)),0.0,1.0);
34 |
35 | lefta_coord = clamp(vec2(texc.xy + vec2(-d.x , d.x)),0.0,1.0);
36 | righta_coord = clamp(vec2(texc.xy + vec2(d.x , d.x)),0.0,1.0);
37 | leftb_coord = clamp(vec2(texc.xy + vec2(-d.x , -d.x)),0.0,1.0);
38 | rightb_coord = clamp(vec2(texc.xy + vec2(d.x , -d.x)),0.0,1.0);
39 | }
--------------------------------------------------------------------------------
/src/application/sample-modules/isf/Color Blowout.vs:
--------------------------------------------------------------------------------
1 | #if __VERSION__ <= 120
2 | varying vec2 left_coord;
3 | varying vec2 right_coord;
4 | varying vec2 above_coord;
5 | varying vec2 below_coord;
6 |
7 | varying vec2 lefta_coord;
8 | varying vec2 righta_coord;
9 | varying vec2 leftb_coord;
10 | varying vec2 rightb_coord;
11 | #else
12 | out vec2 left_coord;
13 | out vec2 right_coord;
14 | out vec2 above_coord;
15 | out vec2 below_coord;
16 |
17 | out vec2 lefta_coord;
18 | out vec2 righta_coord;
19 | out vec2 leftb_coord;
20 | out vec2 rightb_coord;
21 | #endif
22 |
23 |
24 | void main()
25 | {
26 | isf_vertShaderInit();
27 | vec2 texc = vec2(isf_FragNormCoord[0],isf_FragNormCoord[1]);
28 | vec2 d = 1.0/RENDERSIZE;
29 |
30 | left_coord = clamp(vec2(texc.xy + vec2(-d.x , 0)),0.0,1.0);
31 | right_coord = clamp(vec2(texc.xy + vec2(d.x , 0)),0.0,1.0);
32 | above_coord = clamp(vec2(texc.xy + vec2(0,d.y)),0.0,1.0);
33 | below_coord = clamp(vec2(texc.xy + vec2(0,-d.y)),0.0,1.0);
34 |
35 | lefta_coord = clamp(vec2(texc.xy + vec2(-d.x , d.x)),0.0,1.0);
36 | righta_coord = clamp(vec2(texc.xy + vec2(d.x , d.x)),0.0,1.0);
37 | leftb_coord = clamp(vec2(texc.xy + vec2(-d.x , -d.x)),0.0,1.0);
38 | rightb_coord = clamp(vec2(texc.xy + vec2(d.x , -d.x)),0.0,1.0);
39 | }
--------------------------------------------------------------------------------
/src/application/sample-modules/isf/Color Invert.fs:
--------------------------------------------------------------------------------
1 | /*{
2 | "CREDIT": "by zoidberg",
3 | "ISFVSN": "2",
4 | "DESCRIPTION": "Inverts the RGB channels of the input",
5 | "CATEGORIES": [
6 | "Color Effect", "Utility"
7 | ],
8 | "INPUTS": [
9 | {
10 | "NAME": "inputImage",
11 | "TYPE": "image"
12 | }
13 | ]
14 | }*/
15 |
16 | void main() {
17 | vec4 srcPixel = IMG_THIS_PIXEL(inputImage);
18 | gl_FragColor = vec4(1.0-srcPixel.r, 1.0-srcPixel.g, 1.0-srcPixel.b, srcPixel.a);
19 | }
--------------------------------------------------------------------------------
/src/application/sample-modules/isf/Color Monochrome.fs:
--------------------------------------------------------------------------------
1 | /*{
2 | "CATEGORIES": [
3 | "Color Effect",
4 | "Retro"
5 | ],
6 | "CREDIT": "by zoidberg",
7 | "INPUTS": [
8 | {
9 | "NAME": "inputImage",
10 | "TYPE": "image"
11 | },
12 | {
13 | "DEFAULT": 1,
14 | "MAX": 1,
15 | "MIN": 0,
16 | "NAME": "intensity",
17 | "TYPE": "float"
18 | },
19 | {
20 | "DEFAULT": [
21 | 0.6,
22 | 0.45,
23 | 0.3,
24 | 1
25 | ],
26 | "NAME": "color",
27 | "TYPE": "color"
28 | }
29 | ],
30 | "ISFVSN": "2"
31 | }
32 | */
33 |
34 |
35 | //const vec4 lumcoeff = vec4(0.299, 0.587, 0.114, 0.0);
36 | const vec4 lumcoeff = vec4(0.2126, 0.7152, 0.0722, 0.0);
37 |
38 | void main() {
39 | vec4 srcPixel = IMG_THIS_PIXEL(inputImage);
40 | float luminance = dot(srcPixel,lumcoeff);
41 | //float luminance = (srcPixel.r + srcPixel.g + srcPixel.b)/3.0;
42 | vec4 dstPixel = (luminance >= 0.50)
43 | ? mix(color, vec4(1,1,1,srcPixel.a), (luminance-0.5)*2.0)
44 | : mix(vec4(0,0,0,srcPixel.a), color, luminance*2.0);
45 | gl_FragColor = mix(srcPixel, dstPixel, intensity);
46 | }
--------------------------------------------------------------------------------
/src/application/sample-modules/isf/Color Posterize.fs:
--------------------------------------------------------------------------------
1 | /*{
2 | "CATEGORIES": [
3 | "Color Effect",
4 | "Retro"
5 | ],
6 | "CREDIT": "by zoidberg",
7 | "INPUTS": [
8 | {
9 | "NAME": "inputImage",
10 | "TYPE": "image"
11 | },
12 | {
13 | "DEFAULT": 30,
14 | "MAX": 30,
15 | "MIN": 2,
16 | "NAME": "levels",
17 | "TYPE": "float"
18 | }
19 | ],
20 | "ISFVSN": "2"
21 | }
22 | */
23 |
24 | void main() {
25 | // get the src pixel, convert to HSL, posterize the 'L', convert back to RGB
26 | vec4 srcPixel = IMG_THIS_PIXEL(inputImage);
27 | vec4 amountPerLevel = vec4(1.0/levels);
28 | vec4 numOfLevels = floor(srcPixel/amountPerLevel);
29 | vec4 outColor = numOfLevels * (vec4(1.0) / (vec4(levels) - vec4(1.0)));
30 | outColor.a = srcPixel.a;
31 | gl_FragColor = outColor;
32 | }
33 |
--------------------------------------------------------------------------------
/src/application/sample-modules/isf/Color Relookup.fs:
--------------------------------------------------------------------------------
1 | /*{
2 | "CREDIT": "by VIDVOX",
3 | "ISFVSN": "2",
4 | "CATEGORIES": [
5 | "Glitch"
6 | ],
7 | "INPUTS": [
8 | {
9 | "NAME": "inputImage",
10 | "TYPE": "image"
11 | },
12 | {
13 | "NAME": "lookupImage",
14 | "TYPE": "image"
15 | },
16 | {
17 | "NAME": "mix_amount",
18 | "TYPE": "float",
19 | "MIN": 0.0,
20 | "MAX": 1.0,
21 | "DEFAULT": 0.5
22 | }
23 | ]
24 | }*/
25 |
26 | void main() {
27 | vec4 thisColor = IMG_THIS_PIXEL(inputImage);
28 | vec2 lookupCoord;
29 | lookupCoord.x = mix (thisColor.r, thisColor.g, mix_amount);
30 | lookupCoord.x = mix (lookupCoord.x, thisColor.b, mix_amount);
31 | lookupCoord.x = RENDERSIZE.x * lookupCoord.x / 255.0;
32 |
33 | lookupCoord.y = mix (thisColor.r, thisColor.g, mix_amount);
34 | lookupCoord.y = mix (lookupCoord.y, thisColor.b, mix_amount);
35 | lookupCoord.y = RENDERSIZE.y * lookupCoord.y / 255.0;
36 |
37 | gl_FragColor = IMG_NORM_PIXEL(lookupImage, lookupCoord);
38 | }
--------------------------------------------------------------------------------
/src/application/sample-modules/isf/Crosswarp.fs:
--------------------------------------------------------------------------------
1 | /*{
2 | "CATEGORIES": [
3 | "Distortion"
4 | ],
5 | "CREDIT": "Automatically converted from https://www.github.com/gl-transitions/gl-transitions/tree/master/crosswarp.glsl",
6 | "DESCRIPTION": "",
7 | "INPUTS": [
8 | {
9 | "NAME": "startImage",
10 | "TYPE": "image"
11 | },
12 | {
13 | "NAME": "endImage",
14 | "TYPE": "image"
15 | },
16 | {
17 | "DEFAULT": 0,
18 | "MAX": 1,
19 | "MIN": 0,
20 | "NAME": "progress",
21 | "TYPE": "float"
22 | }
23 | ],
24 | "ISFVSN": "2"
25 | }
26 | */
27 |
28 |
29 |
30 | vec4 getFromColor(vec2 inUV) {
31 | return IMG_NORM_PIXEL(startImage, inUV);
32 | }
33 | vec4 getToColor(vec2 inUV) {
34 | return IMG_NORM_PIXEL(endImage, inUV);
35 | }
36 |
37 |
38 |
39 | // Author: Eke Péter
40 | // License: MIT
41 | vec4 transition(vec2 p) {
42 | float x = progress;
43 | x=smoothstep(.0,1.0,(x*2.0+p.x-1.0));
44 | return mix(getFromColor((p-.5)*(1.-x)+.5), getToColor((p-.5)*x+.5), x);
45 | }
46 |
47 |
48 |
49 | void main() {
50 | gl_FragColor = transition(isf_FragNormCoord.xy);
51 | }
--------------------------------------------------------------------------------
/src/application/sample-modules/isf/Deinterlace.fs:
--------------------------------------------------------------------------------
1 | /*{
2 | "CATEGORIES": [
3 | "Utility"
4 | ],
5 | "CREDIT": "by zoidberg",
6 | "INPUTS": [
7 | {
8 | "NAME": "inputImage",
9 | "TYPE": "image"
10 | }
11 | ],
12 | "ISFVSN": "2"
13 | }
14 | */
15 |
16 | const vec2 pointOffset = vec2(0.0, 1.0);
17 |
18 | void main() {
19 | vec4 outColor;
20 | // "upper" (a.k.a. "the top row")
21 | if (fract((gl_FragCoord.y+0.5)/2.0) == 0.0) {
22 | //gl_FragColor = vec4(1,0,0,1);
23 | outColor = (IMG_PIXEL(inputImage, gl_FragCoord.xy) + IMG_PIXEL(inputImage, gl_FragCoord.xy - pointOffset))/2.0;
24 | gl_FragColor = outColor;
25 | }
26 | // "lower" (a.k.a. "the bottom row")
27 | else {
28 | //gl_FragColor = vec4(0,1,0,1);
29 | outColor = (IMG_PIXEL(inputImage, gl_FragCoord.xy) + IMG_PIXEL(inputImage, gl_FragCoord.xy + pointOffset))/2.0;
30 | gl_FragColor = outColor;
31 | }
32 | }
--------------------------------------------------------------------------------
/src/application/sample-modules/isf/Dot Screen.vs:
--------------------------------------------------------------------------------
1 | #if __VERSION__ <= 120
2 | varying vec2 left_coord;
3 | varying vec2 right_coord;
4 | varying vec2 above_coord;
5 | varying vec2 below_coord;
6 |
7 | varying vec2 lefta_coord;
8 | varying vec2 righta_coord;
9 | varying vec2 leftb_coord;
10 | varying vec2 rightb_coord;
11 | #else
12 | out vec2 left_coord;
13 | out vec2 right_coord;
14 | out vec2 above_coord;
15 | out vec2 below_coord;
16 |
17 | out vec2 lefta_coord;
18 | out vec2 righta_coord;
19 | out vec2 leftb_coord;
20 | out vec2 rightb_coord;
21 | #endif
22 |
23 |
24 | void main()
25 | {
26 | isf_vertShaderInit();
27 | vec2 texc = vec2(isf_FragNormCoord[0],isf_FragNormCoord[1]);
28 | vec2 d = 1.0/RENDERSIZE;
29 |
30 | left_coord = clamp(vec2(texc.xy + vec2(-d.x , 0)),0.0,1.0);
31 | right_coord = clamp(vec2(texc.xy + vec2(d.x , 0)),0.0,1.0);
32 | above_coord = clamp(vec2(texc.xy + vec2(0,d.y)),0.0,1.0);
33 | below_coord = clamp(vec2(texc.xy + vec2(0,-d.y)),0.0,1.0);
34 |
35 | lefta_coord = clamp(vec2(texc.xy + vec2(-d.x , d.x)),0.0,1.0);
36 | righta_coord = clamp(vec2(texc.xy + vec2(d.x , d.x)),0.0,1.0);
37 | leftb_coord = clamp(vec2(texc.xy + vec2(-d.x , -d.x)),0.0,1.0);
38 | rightb_coord = clamp(vec2(texc.xy + vec2(d.x , -d.x)),0.0,1.0);
39 | }
--------------------------------------------------------------------------------
/src/application/sample-modules/isf/Dreamy.fs:
--------------------------------------------------------------------------------
1 | /*
2 | {
3 | "ISFVSN" : "2",
4 | "INPUTS" : [
5 | {
6 | "TYPE" : "image",
7 | "NAME" : "startImage"
8 | },
9 | {
10 | "NAME" : "endImage",
11 | "TYPE" : "image"
12 | },
13 | {
14 | "TYPE" : "float",
15 | "NAME" : "progress",
16 | "MIN" : 0,
17 | "MAX" : 1,
18 | "DEFAULT" : 0
19 | }
20 | ],
21 | "CATEGORIES" : [
22 | "Distortion"
23 | ],
24 | "CREDIT": "Automatically converted from https://www.github.com/gl-transitions/gl-transitions/tree/master/Dreamy.glsl",
25 | "DESCRIPTION" : "Automatically converted from https://gl-transitions.com/"
26 | }
27 | */
28 |
29 |
30 |
31 | vec4 getFromColor(vec2 inUV) {
32 | return IMG_NORM_PIXEL(startImage, inUV);
33 | }
34 | vec4 getToColor(vec2 inUV) {
35 | return IMG_NORM_PIXEL(endImage, inUV);
36 | }
37 |
38 |
39 |
40 | // Author: mikolalysenko
41 | // License: MIT
42 |
43 | vec2 offset(float progress, float x, float theta) {
44 | float phase = progress*progress + progress + theta;
45 | float shifty = 0.03*progress*cos(10.0*(progress+x));
46 | return vec2(0, shifty);
47 | }
48 | vec4 transition(vec2 p) {
49 | return mix(getFromColor(p + offset(progress, p.x, 0.0)), getToColor(p + offset(1.0-progress, p.x, 3.14)), progress);
50 | }
51 |
52 |
53 |
54 | void main() {
55 | gl_FragColor = transition(isf_FragNormCoord.xy);
56 | }
--------------------------------------------------------------------------------
/src/application/sample-modules/isf/Edge Distort.vs:
--------------------------------------------------------------------------------
1 | varying vec2 left_coord;
2 | varying vec2 right_coord;
3 | varying vec2 above_coord;
4 | varying vec2 below_coord;
5 |
6 | varying vec2 lefta_coord;
7 | varying vec2 righta_coord;
8 | varying vec2 leftb_coord;
9 | varying vec2 rightb_coord;
10 |
11 |
12 | void main()
13 | {
14 | isf_vertShaderInit();
15 | vec2 texc = vec2(isf_FragNormCoord[0],isf_FragNormCoord[1]);
16 | vec2 d = 1.0/RENDERSIZE;
17 |
18 | left_coord = clamp(vec2(texc.xy + vec2(-d.x , 0)),0.0,1.0);
19 | right_coord = clamp(vec2(texc.xy + vec2(d.x , 0)),0.0,1.0);
20 | above_coord = clamp(vec2(texc.xy + vec2(0,d.y)),0.0,1.0);
21 | below_coord = clamp(vec2(texc.xy + vec2(0,-d.y)),0.0,1.0);
22 |
23 | lefta_coord = clamp(vec2(texc.xy + vec2(-d.x , d.x)),0.0,1.0);
24 | righta_coord = clamp(vec2(texc.xy + vec2(d.x , d.x)),0.0,1.0);
25 | leftb_coord = clamp(vec2(texc.xy + vec2(-d.x , -d.x)),0.0,1.0);
26 | rightb_coord = clamp(vec2(texc.xy + vec2(d.x , -d.x)),0.0,1.0);
27 | }
--------------------------------------------------------------------------------
/src/application/sample-modules/isf/Edge Trace.vs:
--------------------------------------------------------------------------------
1 | #if __VERSION__ <= 120
2 | varying vec2 left_coord;
3 | varying vec2 right_coord;
4 | varying vec2 above_coord;
5 | varying vec2 below_coord;
6 |
7 | varying vec2 lefta_coord;
8 | varying vec2 righta_coord;
9 | varying vec2 leftb_coord;
10 | varying vec2 rightb_coord;
11 | #else
12 | out vec2 left_coord;
13 | out vec2 right_coord;
14 | out vec2 above_coord;
15 | out vec2 below_coord;
16 |
17 | out vec2 lefta_coord;
18 | out vec2 righta_coord;
19 | out vec2 leftb_coord;
20 | out vec2 rightb_coord;
21 | #endif
22 |
23 |
24 | void main()
25 | {
26 | isf_vertShaderInit();
27 | vec2 texc = vec2(isf_FragNormCoord[0],isf_FragNormCoord[1]);
28 | vec2 d = spread/RENDERSIZE;
29 |
30 | left_coord = clamp(vec2(texc.xy + vec2(-d.x , 0)),0.0,1.0);
31 | right_coord = clamp(vec2(texc.xy + vec2(d.x , 0)),0.0,1.0);
32 | above_coord = clamp(vec2(texc.xy + vec2(0,d.y)),0.0,1.0);
33 | below_coord = clamp(vec2(texc.xy + vec2(0,-d.y)),0.0,1.0);
34 |
35 | lefta_coord = clamp(vec2(texc.xy + vec2(-d.x , d.x)),0.0,1.0);
36 | righta_coord = clamp(vec2(texc.xy + vec2(d.x , d.x)),0.0,1.0);
37 | leftb_coord = clamp(vec2(texc.xy + vec2(-d.x , -d.x)),0.0,1.0);
38 | rightb_coord = clamp(vec2(texc.xy + vec2(d.x , -d.x)),0.0,1.0);
39 | }
--------------------------------------------------------------------------------
/src/application/sample-modules/isf/Edges.vs:
--------------------------------------------------------------------------------
1 | #if __VERSION__ <= 120
2 | varying vec2 left_coord;
3 | varying vec2 right_coord;
4 | varying vec2 above_coord;
5 | varying vec2 below_coord;
6 |
7 | varying vec2 lefta_coord;
8 | varying vec2 righta_coord;
9 | varying vec2 leftb_coord;
10 | varying vec2 rightb_coord;
11 | #else
12 | out vec2 left_coord;
13 | out vec2 right_coord;
14 | out vec2 above_coord;
15 | out vec2 below_coord;
16 |
17 | out vec2 lefta_coord;
18 | out vec2 righta_coord;
19 | out vec2 leftb_coord;
20 | out vec2 rightb_coord;
21 | #endif
22 |
23 |
24 | void main()
25 | {
26 | isf_vertShaderInit();
27 | vec2 texc = vec2(isf_FragNormCoord[0],isf_FragNormCoord[1]);
28 | vec2 d = 1.0/RENDERSIZE;
29 |
30 | left_coord = clamp(vec2(texc.xy + vec2(-d.x , 0)),0.0,1.0);
31 | right_coord = clamp(vec2(texc.xy + vec2(d.x , 0)),0.0,1.0);
32 | above_coord = clamp(vec2(texc.xy + vec2(0,d.y)),0.0,1.0);
33 | below_coord = clamp(vec2(texc.xy + vec2(0,-d.y)),0.0,1.0);
34 |
35 | lefta_coord = clamp(vec2(texc.xy + vec2(-d.x , d.x)),0.0,1.0);
36 | righta_coord = clamp(vec2(texc.xy + vec2(d.x , d.x)),0.0,1.0);
37 | leftb_coord = clamp(vec2(texc.xy + vec2(-d.x , -d.x)),0.0,1.0);
38 | rightb_coord = clamp(vec2(texc.xy + vec2(d.x , -d.x)),0.0,1.0);
39 | }
--------------------------------------------------------------------------------
/src/application/sample-modules/isf/Emboss.vs:
--------------------------------------------------------------------------------
1 | varying vec2 left_coord;
2 | varying vec2 right_coord;
3 | varying vec2 above_coord;
4 | varying vec2 below_coord;
5 |
6 | varying vec2 lefta_coord;
7 | varying vec2 rightb_coord;
8 |
9 |
10 | void main()
11 | {
12 | isf_vertShaderInit();
13 | vec2 texc = vec2(isf_FragNormCoord[0],isf_FragNormCoord[1]);
14 | vec2 d = 1.0/RENDERSIZE;
15 |
16 | left_coord = clamp(vec2(texc.xy + vec2(-d.x , 0)),0.0,1.0);
17 | right_coord = clamp(vec2(texc.xy + vec2(d.x , 0)),0.0,1.0);
18 | above_coord = clamp(vec2(texc.xy + vec2(0,d.y)),0.0,1.0);
19 | below_coord = clamp(vec2(texc.xy + vec2(0,-d.y)),0.0,1.0);
20 |
21 | lefta_coord = clamp(vec2(texc.xy + vec2(-d.x , d.x)),0.0,1.0);
22 | rightb_coord = clamp(vec2(texc.xy + vec2(d.x , -d.x)),0.0,1.0);
23 | }
--------------------------------------------------------------------------------
/src/application/sample-modules/isf/Exposure Adjust.fs:
--------------------------------------------------------------------------------
1 | /*{
2 | "CREDIT": "by carter rosenberg",
3 | "ISFVSN": "2",
4 | "CATEGORIES": [
5 | "Color Adjustment"
6 | ],
7 | "INPUTS": [
8 | {
9 | "NAME": "inputImage",
10 | "TYPE": "image"
11 | },
12 | {
13 | "NAME": "inputEV",
14 | "TYPE": "float",
15 | "MIN": -10.0,
16 | "MAX": 10.0,
17 | "DEFAULT": 0.5
18 | }
19 | ]
20 | }*/
21 |
22 |
23 |
24 | void main() {
25 | // based on
26 | // https://developer.apple.com/library/mac/documentation/graphicsimaging/reference/CoreImageFilterReference/Reference/reference.html#//apple_ref/doc/filter/ci/CIExposureAdjust
27 | vec4 tmpColorA = IMG_THIS_PIXEL(inputImage);
28 | tmpColorA.rgb = tmpColorA.rgb * pow(2.0, inputEV);
29 | gl_FragColor = tmpColorA;
30 | }
31 |
--------------------------------------------------------------------------------
/src/application/sample-modules/isf/Fade.fs:
--------------------------------------------------------------------------------
1 | /*
2 | {
3 | "INPUTS" : [
4 | {
5 | "TYPE" : "image",
6 | "NAME" : "startImage"
7 | },
8 | {
9 | "NAME" : "endImage",
10 | "TYPE" : "image"
11 | },
12 | {
13 | "MAX" : 1,
14 | "TYPE" : "float",
15 | "MIN" : 0,
16 | "NAME" : "progress",
17 | "DEFAULT" : 0
18 | }
19 | ],
20 | "CREDIT": "Automatically converted from https://www.github.com/gl-transitions/gl-transitions/tree/master/fade.glsl",
21 | "DESCRIPTION": "",
22 | "CATEGORIES" : [
23 | "Dissolve"
24 | ],
25 | "ISFVSN" : "2"
26 | }
27 | */
28 |
29 |
30 |
31 | vec4 getFromColor(vec2 inUV) {
32 | return IMG_NORM_PIXEL(startImage, inUV);
33 | }
34 | vec4 getToColor(vec2 inUV) {
35 | return IMG_NORM_PIXEL(endImage, inUV);
36 | }
37 |
38 |
39 |
40 | // author: gre
41 | // license: MIT
42 |
43 | vec4 transition (vec2 uv) {
44 | return mix(
45 | getFromColor(uv),
46 | getToColor(uv),
47 | progress
48 | );
49 | }
50 |
51 |
52 |
53 | void main() {
54 | gl_FragColor = transition(isf_FragNormCoord.xy);
55 | }
--------------------------------------------------------------------------------
/src/application/sample-modules/isf/False Color.fs:
--------------------------------------------------------------------------------
1 | /*{
2 | "CREDIT": "by zoidberg",
3 | "ISFVSN": "2",
4 | "CATEGORIES": [
5 | "Color Effect"
6 | ],
7 | "INPUTS": [
8 | {
9 | "NAME": "inputImage",
10 | "TYPE": "image"
11 | },
12 | {
13 | "NAME": "brightColor",
14 | "TYPE": "color",
15 | "DEFAULT": [
16 | 1.0,
17 | 0.9,
18 | 0.8,
19 | 1.0
20 | ]
21 | },
22 | {
23 | "NAME": "darkColor",
24 | "TYPE": "color",
25 | "DEFAULT": [
26 | 0.3,
27 | 0.0,
28 | 0.0,
29 | 1.0
30 | ]
31 | }
32 | ]
33 | }*/
34 |
35 | //const vec4 lumcoeff = vec4(0.299, 0.587, 0.114, 0.0);
36 | const vec4 lumcoeff = vec4(0.2126, 0.7152, 0.0722, 0.0);
37 |
38 | void main() {
39 | vec4 srcPixel = IMG_THIS_PIXEL(inputImage);
40 | float luminance = dot(srcPixel,lumcoeff);
41 | gl_FragColor = mix(vec4(darkColor.rgb, srcPixel.a), vec4(brightColor.rgb, srcPixel.a), luminance);
42 | }
43 |
--------------------------------------------------------------------------------
/src/application/sample-modules/isf/FastMosh.vs:
--------------------------------------------------------------------------------
1 | #if __VERSION__ <= 120
2 | varying vec2 left_coord;
3 | varying vec2 right_coord;
4 | varying vec2 above_coord;
5 | varying vec2 below_coord;
6 |
7 | varying vec2 lefta_coord;
8 | varying vec2 righta_coord;
9 | varying vec2 leftb_coord;
10 | varying vec2 rightb_coord;
11 | #else
12 | out vec2 left_coord;
13 | out vec2 right_coord;
14 | out vec2 above_coord;
15 | out vec2 below_coord;
16 |
17 | out vec2 lefta_coord;
18 | out vec2 righta_coord;
19 | out vec2 leftb_coord;
20 | out vec2 rightb_coord;
21 | #endif
22 |
23 |
24 | void main()
25 | {
26 | isf_vertShaderInit();
27 | vec2 texc = vec2(isf_FragNormCoord[0],isf_FragNormCoord[1]);
28 | vec2 d = 1.0/RENDERSIZE;
29 |
30 | left_coord = clamp(vec2(texc.xy + vec2(-d.x , 0)),0.0,1.0);
31 | right_coord = clamp(vec2(texc.xy + vec2(d.x , 0)),0.0,1.0);
32 | above_coord = clamp(vec2(texc.xy + vec2(0,d.y)),0.0,1.0);
33 | below_coord = clamp(vec2(texc.xy + vec2(0,-d.y)),0.0,1.0);
34 |
35 | lefta_coord = clamp(vec2(texc.xy + vec2(-d.x , d.x)),0.0,1.0);
36 | righta_coord = clamp(vec2(texc.xy + vec2(d.x , d.x)),0.0,1.0);
37 | leftb_coord = clamp(vec2(texc.xy + vec2(-d.x , -d.x)),0.0,1.0);
38 | rightb_coord = clamp(vec2(texc.xy + vec2(d.x , -d.x)),0.0,1.0);
39 | }
--------------------------------------------------------------------------------
/src/application/sample-modules/isf/Flip H.fs:
--------------------------------------------------------------------------------
1 | /*{
2 | "CREDIT": "by VIDVOX",
3 | "ISFVSN": "2",
4 | "CATEGORIES": [
5 | "Geometry Adjustment"
6 | ],
7 | "INPUTS": [
8 | {
9 | "NAME": "inputImage",
10 | "TYPE": "image"
11 | }
12 | ]
13 | }*/
14 |
15 | void main() {
16 | vec2 normSrcCoord;
17 |
18 | normSrcCoord.x = isf_FragNormCoord[0];
19 | normSrcCoord.y = isf_FragNormCoord[1];
20 |
21 | normSrcCoord.x = (1.0-normSrcCoord.x);
22 |
23 | gl_FragColor = IMG_NORM_PIXEL(inputImage, normSrcCoord);
24 | }
--------------------------------------------------------------------------------
/src/application/sample-modules/isf/Flip V.fs:
--------------------------------------------------------------------------------
1 | /*{
2 | "CREDIT": "by VIDVOX",
3 | "ISFVSN": "2",
4 | "CATEGORIES": [
5 | "Geometry Adjustment"
6 | ],
7 | "INPUTS": [
8 | {
9 | "NAME": "inputImage",
10 | "TYPE": "image"
11 | }
12 | ]
13 | }*/
14 |
15 | void main() {
16 | vec2 normSrcCoord;
17 |
18 | normSrcCoord.x = isf_FragNormCoord[0];
19 | normSrcCoord.y = isf_FragNormCoord[1];
20 |
21 | normSrcCoord.y = (1.0-normSrcCoord.y);
22 |
23 | gl_FragColor = IMG_NORM_PIXEL(inputImage, normSrcCoord);
24 | }
--------------------------------------------------------------------------------
/src/application/sample-modules/isf/Freeze Frame.fs:
--------------------------------------------------------------------------------
1 | /*{
2 | "DESCRIPTION": "Holds the output on the captured freeze frame",
3 | "CREDIT": "by VIDVOX",
4 | "ISFVSN": "2",
5 | "CATEGORIES": [
6 | "Utility"
7 | ],
8 | "INPUTS": [
9 | {
10 | "NAME": "inputImage",
11 | "TYPE": "image"
12 | },
13 | {
14 | "NAME": "freeze",
15 | "TYPE": "bool",
16 | "DEFAULT": 0.0
17 | }
18 | ],
19 | "PASSES": [
20 | {
21 | "TARGET":"freezeBuffer",
22 | "PERSISTENT": true
23 | }
24 | ]
25 |
26 | }*/
27 |
28 | // Essentially the same as a feedback buffer where you can only set it to a mix of 1.0
29 |
30 | void main()
31 | {
32 | if (freeze) {
33 | gl_FragColor = IMG_THIS_PIXEL(freezeBuffer);
34 | }
35 | else {
36 | gl_FragColor = IMG_THIS_PIXEL(inputImage);
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/src/application/sample-modules/isf/Gamma Correction.fs:
--------------------------------------------------------------------------------
1 | /*{
2 | "CREDIT": "by zoidberg",
3 | "ISFVSN": "2",
4 | "CATEGORIES": [
5 | "Color Adjustment", "Utility"
6 | ],
7 | "INPUTS": [
8 | {
9 | "NAME": "inputImage",
10 | "TYPE": "image"
11 | },
12 | {
13 | "NAME": "gamma",
14 | "TYPE": "float",
15 | "MIN": 0.0,
16 | "MAX": 1.0,
17 | "DEFAULT": 0.5
18 | }
19 | ]
20 | }*/
21 |
22 |
23 |
24 | void main() {
25 | // the input gamma range is 0.0-1.0 (normalized). the actual gamma range i want to use is 0.0 - 5.0.
26 | // however, actual gamma 0.0-1.0 is just as interesting as actual gamma 1.0-5.0, so we scale the normalized input to match...
27 | float realGamma = (gamma<=0.5) ? (gamma * 2.0) : (((gamma-0.5) * 2.0 * 4.0) + 1.0);
28 | vec4 tmpColorA = IMG_THIS_PIXEL(inputImage);
29 | vec4 tmpColorB;
30 | tmpColorB.rgb = pow(tmpColorA.rgb, vec3(1.0/realGamma));
31 | tmpColorB.a = tmpColorA.a;
32 | gl_FragColor = tmpColorB;
33 | }
34 |
--------------------------------------------------------------------------------
/src/application/sample-modules/isf/Glow.vs:
--------------------------------------------------------------------------------
1 | #if __VERSION__ <= 120
2 | varying vec2 texOffsets[3];
3 | #else
4 | out vec2 texOffsets[3];
5 | #endif
6 |
7 | const float radius = 10.0;
8 |
9 | void main(void) {
10 | // load the main shader stuff
11 | isf_vertShaderInit();
12 |
13 | if (PASSINDEX==0 || PASSINDEX==2 || PASSINDEX==4 || PASSINDEX==6 || PASSINDEX==8) {
14 | float pixelWidth = 1.0/RENDERSIZE[0]*radius;
15 | if (PASSINDEX >= 2)
16 | pixelWidth *= .7;
17 | else if (PASSINDEX >= 6)
18 | pixelWidth *= 1.0;
19 | texOffsets[0] = isf_FragNormCoord;
20 | texOffsets[1] = clamp(vec2(isf_FragNormCoord[0]-pixelWidth, isf_FragNormCoord[1]),0.0,1.0);
21 | texOffsets[2] = clamp(vec2(isf_FragNormCoord[0]+pixelWidth, isf_FragNormCoord[1]),0.0,1.0);
22 | }
23 | else if (PASSINDEX==1 || PASSINDEX==3 || PASSINDEX==5 || PASSINDEX==7 || PASSINDEX==9) {
24 | float pixelHeight = 1.0/RENDERSIZE[1]*radius;
25 | if (PASSINDEX >= 3)
26 | pixelHeight *= .7;
27 | else if (PASSINDEX >= 6)
28 | pixelHeight *= 1.0;
29 | texOffsets[0] = isf_FragNormCoord;
30 | texOffsets[1] = clamp(vec2(isf_FragNormCoord[0], isf_FragNormCoord[1]-pixelHeight),0.0,1.0);
31 | texOffsets[2] = clamp(vec2(isf_FragNormCoord[0], isf_FragNormCoord[1]+pixelHeight),0.0,1.0);
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/src/application/sample-modules/isf/HSVtoRGB.fs:
--------------------------------------------------------------------------------
1 | /*{
2 | "CATEGORIES": [
3 | "Color Effect",
4 | "Utility"
5 | ],
6 | "CREDIT": "by zoidberg",
7 | "DESCRIPTION": "swizzles RGBA to BGRA and vice versa",
8 | "INPUTS": [
9 | {
10 | "NAME": "inputImage",
11 | "TYPE": "image"
12 | }
13 | ],
14 | "ISFVSN": "2"
15 | }
16 | */
17 |
18 |
19 |
20 |
21 | vec3 rgb2hsv(vec3 c) {
22 | vec4 K = vec4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0);
23 | //vec4 p = mix(vec4(c.bg, K.wz), vec4(c.gb, K.xy), step(c.b, c.g));
24 | //vec4 q = mix(vec4(p.xyw, c.r), vec4(c.r, p.yzx), step(p.x, c.r));
25 | vec4 p = c.g < c.b ? vec4(c.bg, K.wz) : vec4(c.gb, K.xy);
26 | vec4 q = c.r < p.x ? vec4(p.xyw, c.r) : vec4(c.r, p.yzx);
27 |
28 | float d = q.x - min(q.w, q.y);
29 | float e = 1.0e-10;
30 | return vec3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x);
31 | }
32 |
33 | vec3 hsv2rgb(vec3 c) {
34 | vec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);
35 | vec3 p = abs(fract(c.xxx + K.xyz) * 6.0 - K.www);
36 | return c.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y);
37 | }
38 |
39 |
40 |
41 |
42 | void main()
43 | {
44 | vec4 inColor = IMG_NORM_PIXEL(inputImage, isf_FragNormCoord);
45 | gl_FragColor = vec4(hsv2rgb(inColor.rgb), inColor.a);
46 | }
47 |
--------------------------------------------------------------------------------
/src/application/sample-modules/isf/Heart Transition.fs:
--------------------------------------------------------------------------------
1 | /*{
2 | "CATEGORIES": [
3 | "Wipe",
4 | "Retro"
5 | ],
6 | "CREDIT": "Automatically converted from https://www.github.com/gl-transitions/gl-transitions/tree/master/heart.glsl",
7 | "DESCRIPTION": "",
8 | "INPUTS": [
9 | {
10 | "NAME": "startImage",
11 | "TYPE": "image"
12 | },
13 | {
14 | "NAME": "endImage",
15 | "TYPE": "image"
16 | },
17 | {
18 | "DEFAULT": 0,
19 | "MAX": 1,
20 | "MIN": 0,
21 | "NAME": "progress",
22 | "TYPE": "float"
23 | }
24 | ],
25 | "ISFVSN": "2"
26 | }
27 | */
28 |
29 |
30 |
31 | vec4 getFromColor(vec2 inUV) {
32 | return IMG_NORM_PIXEL(startImage, inUV);
33 | }
34 | vec4 getToColor(vec2 inUV) {
35 | return IMG_NORM_PIXEL(endImage, inUV);
36 | }
37 |
38 |
39 |
40 | // Author: gre
41 | // License: MIT
42 |
43 | float inHeart (vec2 p, vec2 center, float size) {
44 | if (size==0.0) return 0.0;
45 | vec2 o = (p-center)/(1.6*size);
46 | float a = o.x*o.x+o.y*o.y-0.3;
47 | return step(a*a*a, o.x*o.x*o.y*o.y*o.y);
48 | }
49 | vec4 transition (vec2 uv) {
50 | return mix(
51 | getFromColor(uv),
52 | getToColor(uv),
53 | inHeart(uv, vec2(0.5, 0.4), progress)
54 | );
55 | }
56 |
57 |
58 |
59 | void main() {
60 | gl_FragColor = transition(isf_FragNormCoord.xy);
61 | }
--------------------------------------------------------------------------------
/src/application/sample-modules/isf/Heart.fs:
--------------------------------------------------------------------------------
1 | /*{
2 | "CREDIT": "by VIDVOX",
3 | "ISFVSN": "2",
4 | "CATEGORIES": [
5 | "Geometry"
6 | ],
7 | "INPUTS": [
8 | {
9 | "NAME": "size",
10 | "LABEL": "Size",
11 | "TYPE": "float",
12 | "MIN": 0.0,
13 | "MAX": 1.0,
14 | "DEFAULT": 0.25
15 | },
16 | {
17 | "NAME": "color",
18 | "LABEL": "Fill Color",
19 | "TYPE": "color",
20 | "DEFAULT": [
21 | 1.0,
22 | 0.0,
23 | 0.0,
24 | 1.0
25 | ]
26 | }
27 | ]
28 | }*/
29 |
30 |
31 | // Adapted from https://glsl.io/transition/d71472a550601b96d69d
32 |
33 |
34 | bool inHeart (vec2 p, vec2 center, float size) {
35 | if (size == 0.0) return false;
36 | vec2 o = (p-center)/(1.6*size);
37 | return pow(o.x*o.x+o.y*o.y-0.3, 3.0) < o.x*o.x*pow(o.y, 3.0);
38 | }
39 |
40 | void main() {
41 | vec2 p = isf_FragNormCoord;
42 | float m = inHeart(p, vec2(0.5, 0.4), size) ? 1.0 : 0.0;
43 | gl_FragColor = mix(vec4(0.0), color, m);
44 | }
--------------------------------------------------------------------------------
/src/application/sample-modules/isf/Histogram Viewer.fs:
--------------------------------------------------------------------------------
1 | /*{
2 | "CATEGORIES" : [
3 | "Histogram", "Utility"
4 | ],
5 | "DESCRIPTION": "Draws an RGB histogram from a provided histogram image",
6 | "CREDIT": "by VIDVOX",
7 | "ISFVSN": "2",
8 | "INPUTS": [
9 | {
10 | "NAME": "histogramImage",
11 | "TYPE": "image"
12 | }
13 | ]
14 | }*/
15 |
16 |
17 | void main() {
18 | vec4 outColor = vec4(0., 0., 0., 0.);
19 | vec4 histoVals = IMG_NORM_PIXEL(histogramImage, vec2(isf_FragNormCoord.x, 0.5));
20 | if (histoVals.r >= isf_FragNormCoord.y) {
21 | outColor.r = 1.0;
22 | outColor.a = 1.0;
23 | }
24 | if (histoVals.g >= isf_FragNormCoord.y) {
25 | outColor.g = 1.0;
26 | outColor.a = 1.0;
27 | }
28 | if (histoVals.b >= isf_FragNormCoord.y) {
29 | outColor.b = 1.0;
30 | outColor.a = 1.0;
31 | }
32 |
33 | gl_FragColor = outColor;
34 |
35 | }
36 |
--------------------------------------------------------------------------------
/src/application/sample-modules/isf/Hue-Saturation.fs:
--------------------------------------------------------------------------------
1 | /*
2 | {
3 | "DESCRIPTION" : "Hue\/Saturation adjustment",
4 | "ISFVSN" : "2",
5 | "INPUTS" : [
6 | {
7 | "NAME" : "inputImage",
8 | "TYPE" : "image"
9 | },
10 | {
11 | "NAME" : "hue",
12 | "TYPE" : "float",
13 | "MAX" : 1,
14 | "DEFAULT" : 0,
15 | "MIN" : -1,
16 | "LABEL" : "Hue"
17 | },
18 | {
19 | "NAME" : "saturation",
20 | "TYPE" : "float",
21 | "MAX" : 1,
22 | "DEFAULT" : 0,
23 | "LABEL" : "Saturation",
24 | "MIN" : -1
25 | }
26 | ],
27 | "CREDIT" : "2xAA"
28 | }
29 | */
30 |
31 | void main() {
32 | vec4 color = IMG_NORM_PIXEL(inputImage, isf_FragNormCoord.xy);
33 |
34 | /* hue adjustment */
35 | float angle = hue * 3.14159265;
36 | float s = sin(angle), c = cos(angle);
37 | vec3 weights = (vec3(2.0 * c, -sqrt(3.0) * s - c, sqrt(3.0) * s - c) + 1.0) / 3.0;
38 | float len = length(color.rgb);
39 | color.rgb = vec3(
40 | dot(color.rgb, weights.xyz),
41 | dot(color.rgb, weights.zxy),
42 | dot(color.rgb, weights.yzx)
43 | );
44 |
45 | /* saturation adjustment */
46 | float average = (color.r + color.g + color.b) / 3.0;
47 | if (saturation > 0.0) {
48 | color.rgb += (average - color.rgb) * (1.0 - 1.0 / (1.001 - saturation));
49 | } else {
50 | color.rgb += (average - color.rgb) * (-saturation);
51 | }
52 |
53 | gl_FragColor = color;
54 | }
55 |
--------------------------------------------------------------------------------
/src/application/sample-modules/isf/Interlace Mirror.fs:
--------------------------------------------------------------------------------
1 | /*{
2 | "CATEGORIES": [
3 | "Glitch",
4 | "Retro"
5 | ],
6 | "CREDIT": "by Carter Rosenberg",
7 | "DESCRIPTION": "",
8 | "INPUTS": [
9 | {
10 | "NAME": "inputImage",
11 | "TYPE": "image"
12 | },
13 | {
14 | "DEFAULT": 1,
15 | "LABEL": "Horizontal",
16 | "NAME": "horizontal",
17 | "TYPE": "bool"
18 | },
19 | {
20 | "DEFAULT": 0,
21 | "LABEL": "Vertical",
22 | "NAME": "vertical",
23 | "TYPE": "bool"
24 | }
25 | ],
26 | "ISFVSN": "2"
27 | }
28 | */
29 |
30 | void main()
31 | {
32 | vec2 pixelCoord = isf_FragNormCoord * RENDERSIZE;
33 | vec2 loc = pixelCoord;
34 | if (vertical) {
35 | if (mod(pixelCoord.x,2.0)>1.0) {
36 | loc.y = RENDERSIZE.y - pixelCoord.y;
37 | }
38 | }
39 | if (horizontal) {
40 | if (mod(pixelCoord.y,2.0)>1.0) {
41 | loc.x = RENDERSIZE.x - pixelCoord.x;
42 | }
43 | }
44 | gl_FragColor = IMG_PIXEL(inputImage,loc);
45 | }
46 |
--------------------------------------------------------------------------------
/src/application/sample-modules/isf/Kaleidoscope.fs:
--------------------------------------------------------------------------------
1 | /*
2 | {
3 | "CATEGORIES" : [
4 | "effect"
5 | ],
6 | "DESCRIPTION" : "Kaleidoscope",
7 | "ISFVSN" : "2",
8 | "INPUTS" : [
9 | {
10 | "NAME" : "inputImage",
11 | "TYPE" : "image"
12 | },
13 | {
14 | "NAME" : "sides",
15 | "TYPE" : "float",
16 | "MAX" : 60,
17 | "DEFAULT" : 5,
18 | "MIN" : 2
19 | }
20 | ],
21 | "CREDIT" : "2xAA"
22 | }
23 | */
24 |
25 | void main() {
26 |
27 | vec2 uv = gl_FragCoord.xy/RENDERSIZE.xy;
28 |
29 | // normalize to the center
30 | uv = uv - 0.5;
31 |
32 | // cartesian to polar coordinates
33 | float r = length(uv);
34 | float a = atan(uv.y, uv.x);
35 |
36 | // kaleidoscope
37 | //float sides = 5.;
38 | float tau = 2. * 3.1416;
39 | a = mod(a, tau/sides);
40 | a = abs(a - tau/sides/2.);
41 |
42 | // polar to cartesian coordinates
43 | uv = r * vec2(cos(a), sin(a));
44 |
45 | // recenter
46 | uv = uv + 0.5;
47 |
48 | vec4 c = IMG_NORM_PIXEL(inputImage, uv);
49 | gl_FragColor = c;
50 | }
--------------------------------------------------------------------------------
/src/application/sample-modules/isf/Layer Position.fs:
--------------------------------------------------------------------------------
1 | /*{
2 | "DESCRIPTION": "",
3 | "CREDIT": "",
4 | "ISFVSN": "2",
5 | "CATEGORIES": [
6 | "Geometry Adjustment", "Utility"
7 | ],
8 | "INPUTS": [
9 | {
10 | "NAME": "inputImage",
11 | "TYPE": "image"
12 | },
13 | {
14 | "NAME": "offset",
15 | "TYPE": "point2D",
16 | "DEFAULT": [
17 | 0.5,
18 | 0.5
19 | ],
20 | "MIN": [
21 | 0.0,
22 | 0.0
23 | ],
24 | "MAX": [
25 | 1.0,
26 | 1.0
27 | ]
28 | },
29 | {
30 | "NAME": "repeatImage",
31 | "TYPE": "bool",
32 | "DEFAULT": 0.0
33 | }
34 | ]
35 |
36 | }*/
37 |
38 | void main() {
39 | vec4 outputColor = vec4(0.0);
40 | vec2 newLoc = offset;
41 | vec2 topSize = RENDERSIZE;
42 |
43 | newLoc = offset * RENDERSIZE;
44 | newLoc.x = topSize.x - newLoc.x;
45 | newLoc.y = topSize.y - newLoc.y;
46 | newLoc = (gl_FragCoord.xy + 2.0*newLoc) - topSize;
47 |
48 | if (repeatImage) {
49 | newLoc = mod(newLoc, RENDERSIZE);
50 | }
51 |
52 | if ((newLoc.x >= 0.0)&&(newLoc.x < RENDERSIZE.x)&&(newLoc.y >= 0.0)&&(newLoc.y <= RENDERSIZE.y)) {
53 | outputColor = IMG_PIXEL(inputImage, newLoc);
54 | }
55 |
56 | gl_FragColor = outputColor;
57 | }
58 |
--------------------------------------------------------------------------------
/src/application/sample-modules/isf/Lens Flare.vs:
--------------------------------------------------------------------------------
1 | #if __VERSION__ <= 120
2 | varying vec2 left_coord;
3 | varying vec2 right_coord;
4 | varying vec2 above_coord;
5 | varying vec2 below_coord;
6 |
7 | varying vec2 lefta_coord;
8 | varying vec2 righta_coord;
9 | varying vec2 leftb_coord;
10 | varying vec2 rightb_coord;
11 | #else
12 | out vec2 left_coord;
13 | out vec2 right_coord;
14 | out vec2 above_coord;
15 | out vec2 below_coord;
16 |
17 | out vec2 lefta_coord;
18 | out vec2 righta_coord;
19 | out vec2 leftb_coord;
20 | out vec2 rightb_coord;
21 | #endif
22 |
23 |
24 | void main()
25 | {
26 | isf_vertShaderInit();
27 | vec2 texc = vec2(isf_FragNormCoord[0],isf_FragNormCoord[1]);
28 | vec2 d = 1.0/RENDERSIZE;
29 |
30 | left_coord = clamp(vec2(texc.xy + vec2(-d.x , 0)),0.0,1.0);
31 | right_coord = clamp(vec2(texc.xy + vec2(d.x , 0)),0.0,1.0);
32 | above_coord = clamp(vec2(texc.xy + vec2(0,d.y)),0.0,1.0);
33 | below_coord = clamp(vec2(texc.xy + vec2(0,-d.y)),0.0,1.0);
34 |
35 | lefta_coord = clamp(vec2(texc.xy + vec2(-d.x , d.x)),0.0,1.0);
36 | righta_coord = clamp(vec2(texc.xy + vec2(d.x , d.x)),0.0,1.0);
37 | leftb_coord = clamp(vec2(texc.xy + vec2(-d.x , -d.x)),0.0,1.0);
38 | rightb_coord = clamp(vec2(texc.xy + vec2(d.x , -d.x)),0.0,1.0);
39 | }
--------------------------------------------------------------------------------
/src/application/sample-modules/isf/Life.vs:
--------------------------------------------------------------------------------
1 | #if __VERSION__ <= 120
2 | varying vec2 left_coord;
3 | varying vec2 right_coord;
4 | varying vec2 above_coord;
5 | varying vec2 below_coord;
6 |
7 | varying vec2 lefta_coord;
8 | varying vec2 righta_coord;
9 | varying vec2 leftb_coord;
10 | varying vec2 rightb_coord;
11 | #else
12 | out vec2 left_coord;
13 | out vec2 right_coord;
14 | out vec2 above_coord;
15 | out vec2 below_coord;
16 |
17 | out vec2 lefta_coord;
18 | out vec2 righta_coord;
19 | out vec2 leftb_coord;
20 | out vec2 rightb_coord;
21 | #endif
22 |
23 |
24 | void main()
25 | {
26 | isf_vertShaderInit();
27 | vec2 texc = vec2(isf_FragNormCoord[0],isf_FragNormCoord[1]) * RENDERSIZE;
28 |
29 | left_coord = vec2(texc.xy + vec2(-1.0 , 0));
30 | right_coord = vec2(texc.xy + vec2(1.0 , 0));
31 | above_coord = vec2(texc.xy + vec2(0,1.0));
32 | below_coord = vec2(texc.xy + vec2(0,-1.0));
33 |
34 | lefta_coord = vec2(texc.xy + vec2(-1.0 , 1.0));
35 | righta_coord = vec2(texc.xy + vec2(1.0 , 1.0));
36 | leftb_coord = vec2(texc.xy + vec2(-1.0 , -1.0));
37 | rightb_coord = vec2(texc.xy + vec2(1.0 , -1.0));
38 | }
--------------------------------------------------------------------------------
/src/application/sample-modules/isf/Line Screen.vs:
--------------------------------------------------------------------------------
1 | #if __VERSION__ <= 120
2 | varying vec2 left_coord;
3 | varying vec2 right_coord;
4 | varying vec2 above_coord;
5 | varying vec2 below_coord;
6 |
7 | varying vec2 lefta_coord;
8 | varying vec2 righta_coord;
9 | varying vec2 leftb_coord;
10 | varying vec2 rightb_coord;
11 | #else
12 | out vec2 left_coord;
13 | out vec2 right_coord;
14 | out vec2 above_coord;
15 | out vec2 below_coord;
16 |
17 | out vec2 lefta_coord;
18 | out vec2 righta_coord;
19 | out vec2 leftb_coord;
20 | out vec2 rightb_coord;
21 | #endif
22 |
23 |
24 | void main()
25 | {
26 | isf_vertShaderInit();
27 | vec2 texc = vec2(isf_FragNormCoord[0],isf_FragNormCoord[1]);
28 | vec2 d = 1.0/RENDERSIZE;
29 |
30 | left_coord = clamp(vec2(texc.xy + vec2(-d.x , 0)),0.0,1.0);
31 | right_coord = clamp(vec2(texc.xy + vec2(d.x , 0)),0.0,1.0);
32 | above_coord = clamp(vec2(texc.xy + vec2(0,d.y)),0.0,1.0);
33 | below_coord = clamp(vec2(texc.xy + vec2(0,-d.y)),0.0,1.0);
34 |
35 | lefta_coord = clamp(vec2(texc.xy + vec2(-d.x , d.x)),0.0,1.0);
36 | righta_coord = clamp(vec2(texc.xy + vec2(d.x , d.x)),0.0,1.0);
37 | leftb_coord = clamp(vec2(texc.xy + vec2(-d.x , -d.x)),0.0,1.0);
38 | rightb_coord = clamp(vec2(texc.xy + vec2(d.x , -d.x)),0.0,1.0);
39 | }
--------------------------------------------------------------------------------
/src/application/sample-modules/isf/Luma Transition.fs:
--------------------------------------------------------------------------------
1 | /*
2 | {
3 | "ISFVSN" : "2",
4 | "CATEGORIES" : [
5 | "Dissolve"
6 | ],
7 | "INPUTS" : [
8 | {
9 | "TYPE" : "image",
10 | "NAME" : "startImage"
11 | },
12 | {
13 | "NAME" : "endImage",
14 | "TYPE" : "image"
15 | },
16 | {
17 | "TYPE" : "float",
18 | "MIN" : 0,
19 | "DEFAULT" : 0,
20 | "NAME" : "progress",
21 | "MAX" : 1
22 | },
23 | {
24 | "NAME" : "luma",
25 | "TYPE" : "image"
26 | }
27 | ],
28 | "CREDIT": "Automatically converted from https://www.github.com/gl-transitions/gl-transitions/tree/master/luma.glsl",
29 | "DESCRIPTION" : "Automatically converted from https://gl-transitions.com/"
30 | }
31 | */
32 |
33 |
34 |
35 | vec4 getFromColor(vec2 inUV) {
36 | return IMG_NORM_PIXEL(startImage, inUV);
37 | }
38 | vec4 getToColor(vec2 inUV) {
39 | return IMG_NORM_PIXEL(endImage, inUV);
40 | }
41 |
42 |
43 |
44 | // Author: gre
45 | // License: MIT
46 |
47 |
48 | vec4 transition(vec2 uv) {
49 | return mix(
50 | getToColor(uv),
51 | getFromColor(uv),
52 | step(progress, IMG_NORM_PIXEL(luma, uv).r-0.001)
53 | );
54 | }
55 |
56 |
57 |
58 | void main() {
59 | gl_FragColor = transition(isf_FragNormCoord.xy);
60 | }
--------------------------------------------------------------------------------
/src/application/sample-modules/isf/Maximum Component.fs:
--------------------------------------------------------------------------------
1 | /*{
2 | "CREDIT": "by zoidberg",
3 | "ISFVSN": "2",
4 | "CATEGORIES": [
5 | "Color Effect", "Utility"
6 | ],
7 | "INPUTS": [
8 | {
9 | "NAME": "inputImage",
10 | "TYPE": "image"
11 | }
12 | ]
13 | }*/
14 |
15 | void main() {
16 | vec4 srcPixel = IMG_THIS_PIXEL(inputImage);
17 | float maxComponent = max(srcPixel.r, max(srcPixel.g, srcPixel.b));
18 | gl_FragColor = vec4(maxComponent, maxComponent, maxComponent, srcPixel.a);
19 | }
--------------------------------------------------------------------------------
/src/application/sample-modules/isf/Minimum Component.fs:
--------------------------------------------------------------------------------
1 | /*{
2 | "CATEGORIES": [
3 | "Color Effect",
4 | "Utility"
5 | ],
6 | "CREDIT": "by zoidberg",
7 | "INPUTS": [
8 | {
9 | "NAME": "inputImage",
10 | "TYPE": "image"
11 | }
12 | ],
13 | "ISFVSN": "2"
14 | }
15 | */
16 |
17 | void main() {
18 | vec4 srcPixel = IMG_THIS_PIXEL(inputImage);
19 | float minComponent = min(srcPixel.r, min(srcPixel.g, srcPixel.b));
20 | gl_FragColor = vec4(minComponent, minComponent, minComponent, srcPixel.a);
21 | }
--------------------------------------------------------------------------------
/src/application/sample-modules/isf/Mirror Edge.fs:
--------------------------------------------------------------------------------
1 | /*{
2 | "CREDIT": "by VIDVOX",
3 | "ISFVSN": "2",
4 | "CATEGORIES": [
5 | "Tile Effect"
6 | ],
7 | "INPUTS": [
8 | {
9 | "NAME": "inputImage",
10 | "TYPE": "image"
11 | },
12 | {
13 | "NAME": "angle",
14 | "LABEL": "Angle",
15 | "TYPE": "float",
16 | "MIN": 0.0,
17 | "MAX": 1.0,
18 | "DEFAULT": 0.0
19 | },
20 | {
21 | "NAME": "shift",
22 | "LABEL": "Shift",
23 | "TYPE": "point2D",
24 | "DEFAULT": [
25 | 0.0,
26 | 0.5
27 | ]
28 | }
29 | ]
30 | }*/
31 |
32 |
33 | varying vec2 translated_coord;
34 |
35 |
36 | void main() {
37 | vec2 loc = translated_coord;
38 | vec2 modifiedCenter = shift / RENDERSIZE;
39 |
40 | loc = mod(loc + modifiedCenter, 1.0);
41 |
42 | // mirror the image so it's repeated 4 times at different reflections
43 | loc = 2.0 * abs(loc - 0.5);
44 |
45 | gl_FragColor = IMG_NORM_PIXEL(inputImage, loc);
46 | }
--------------------------------------------------------------------------------
/src/application/sample-modules/isf/Mirror Edge.vs:
--------------------------------------------------------------------------------
1 | varying vec2 translated_coord;
2 |
3 | const float pi = 3.14159265359;
4 |
5 | void main() {
6 | isf_vertShaderInit();
7 |
8 | vec2 loc = RENDERSIZE * vec2(isf_FragNormCoord[0],isf_FragNormCoord[1]);
9 |
10 | float r = distance(RENDERSIZE/2.0, loc);
11 | float a = atan ((loc.y-RENDERSIZE.y/2.0),(loc.x-RENDERSIZE.x/2.0));
12 |
13 | loc.x = r * cos(a + 2.0 * pi * angle) + 0.5;
14 | loc.y = r * sin(a + 2.0 * pi * angle) + 0.5;
15 |
16 | translated_coord = loc / RENDERSIZE + vec2(0.5);
17 |
18 | }
--------------------------------------------------------------------------------
/src/application/sample-modules/isf/Mirror.fs:
--------------------------------------------------------------------------------
1 | /*{
2 | "CREDIT": "by VIDVOX",
3 | "ISFVSN": "2",
4 | "CATEGORIES": [
5 | "Geometry Adjustment"
6 | ],
7 | "INPUTS": [
8 | {
9 | "NAME": "inputImage",
10 | "TYPE": "image"
11 | },
12 | {
13 | "NAME": "horizontal",
14 | "TYPE": "bool",
15 | "DEFAULT": 1.0
16 | },
17 | {
18 | "NAME": "vertical",
19 | "TYPE": "bool",
20 | "DEFAULT": 0.0
21 | }
22 | ]
23 | }*/
24 |
25 | void main() {
26 | // isf_FragNormCoord[0] and isf_FragNormCoord[1] are my normalized x/y coordinates
27 | // if we're not doing a flip in either direction we can just pass thru
28 | vec2 normSrcCoord;
29 |
30 | normSrcCoord.x = isf_FragNormCoord[0];
31 | normSrcCoord.y = isf_FragNormCoord[1];
32 |
33 | if ((normSrcCoord.x > 0.5)&&(horizontal)) {
34 | normSrcCoord.x = (1.0-normSrcCoord.x);
35 | }
36 | if ((normSrcCoord.y > 0.5)&&(vertical)) {
37 | normSrcCoord.y = (1.0-normSrcCoord.y);
38 | }
39 |
40 | gl_FragColor = IMG_NORM_PIXEL(inputImage, normSrcCoord);
41 | }
--------------------------------------------------------------------------------
/src/application/sample-modules/isf/Multiply Blend.fs:
--------------------------------------------------------------------------------
1 | /*
2 | {
3 | "ISFVSN" : "2",
4 | "CREDIT": "Automatically converted from https://www.github.com/gl-transitions/gl-transitions/tree/master/multiply_blend.glsl",
5 | "DESCRIPTION": "",
6 | "CATEGORIES" : [
7 | "Dissolve"
8 | ],
9 | "INPUTS" : [
10 | {
11 | "NAME" : "startImage",
12 | "TYPE" : "image"
13 | },
14 | {
15 | "NAME" : "endImage",
16 | "TYPE" : "image"
17 | },
18 | {
19 | "MAX" : 1,
20 | "DEFAULT" : 0,
21 | "MIN" : 0,
22 | "TYPE" : "float",
23 | "NAME" : "progress"
24 | }
25 | ]
26 | }
27 | */
28 |
29 |
30 |
31 | vec4 getFromColor(vec2 inUV) {
32 | return IMG_NORM_PIXEL(startImage, inUV);
33 | }
34 | vec4 getToColor(vec2 inUV) {
35 | return IMG_NORM_PIXEL(endImage, inUV);
36 | }
37 |
38 |
39 |
40 | // Author: Fernando Kuteken
41 | // License: MIT
42 |
43 | vec4 blend(vec4 a, vec4 b) {
44 | return a * b;
45 | }
46 |
47 | vec4 transition (vec2 uv) {
48 |
49 | vec4 blended = blend(getFromColor(uv), getToColor(uv));
50 |
51 | if (progress < 0.5)
52 | return mix(getFromColor(uv), blended, 2.0 * progress);
53 | else
54 | return mix(blended, getToColor(uv), 2.0 * progress - 1.0);
55 | }
56 |
57 |
58 |
59 |
60 | void main() {
61 | gl_FragColor = transition(isf_FragNormCoord.xy);
62 | }
--------------------------------------------------------------------------------
/src/application/sample-modules/isf/Neon.vs:
--------------------------------------------------------------------------------
1 | varying vec2 left_coord;
2 | varying vec2 right_coord;
3 | varying vec2 above_coord;
4 | varying vec2 below_coord;
5 |
6 | varying vec2 lefta_coord;
7 | varying vec2 righta_coord;
8 | varying vec2 leftb_coord;
9 | varying vec2 rightb_coord;
10 |
11 |
12 | void main()
13 | {
14 | isf_vertShaderInit();
15 | vec2 texc = vec2(isf_FragNormCoord[0],isf_FragNormCoord[1]);
16 | vec2 d = 1.0/RENDERSIZE;
17 |
18 | left_coord = clamp(vec2(texc.xy + vec2(-d.x , 0)),0.0,1.0);
19 | right_coord = clamp(vec2(texc.xy + vec2(d.x , 0)),0.0,1.0);
20 | above_coord = clamp(vec2(texc.xy + vec2(0,d.y)),0.0,1.0);
21 | below_coord = clamp(vec2(texc.xy + vec2(0,-d.y)),0.0,1.0);
22 |
23 | d = 1.0/RENDERSIZE;
24 | lefta_coord = clamp(vec2(texc.xy + vec2(-d.x , d.x)),0.0,1.0);
25 | righta_coord = clamp(vec2(texc.xy + vec2(d.x , d.x)),0.0,1.0);
26 | leftb_coord = clamp(vec2(texc.xy + vec2(-d.x , -d.x)),0.0,1.0);
27 | rightb_coord = clamp(vec2(texc.xy + vec2(d.x , -d.x)),0.0,1.0);
28 | }
--------------------------------------------------------------------------------
/src/application/sample-modules/isf/Optical Flow Distort.vs:
--------------------------------------------------------------------------------
1 | varying vec2 left_coord;
2 | varying vec2 right_coord;
3 | varying vec2 above_coord;
4 | varying vec2 below_coord;
5 |
6 | varying vec2 lefta_coord;
7 | varying vec2 righta_coord;
8 | varying vec2 leftb_coord;
9 | varying vec2 rightb_coord;
10 |
11 |
12 | void main()
13 | {
14 | isf_vertShaderInit();
15 | vec2 texc = vec2(isf_FragNormCoord[0],isf_FragNormCoord[1]);
16 | vec2 d = 4.0/RENDERSIZE;
17 |
18 | left_coord = clamp(vec2(texc.xy + vec2(-d.x , 0)),0.0,1.0);
19 | right_coord = clamp(vec2(texc.xy + vec2(d.x , 0)),0.0,1.0);
20 | above_coord = clamp(vec2(texc.xy + vec2(0,d.y)),0.0,1.0);
21 | below_coord = clamp(vec2(texc.xy + vec2(0,-d.y)),0.0,1.0);
22 |
23 | lefta_coord = clamp(vec2(texc.xy + vec2(-d.x , d.x)),0.0,1.0);
24 | righta_coord = clamp(vec2(texc.xy + vec2(d.x , d.x)),0.0,1.0);
25 | leftb_coord = clamp(vec2(texc.xy + vec2(-d.x , -d.x)),0.0,1.0);
26 | rightb_coord = clamp(vec2(texc.xy + vec2(d.x , -d.x)),0.0,1.0);
27 | }
--------------------------------------------------------------------------------
/src/application/sample-modules/isf/Pinch.fs:
--------------------------------------------------------------------------------
1 | /*
2 | {
3 | "CATEGORIES" : [
4 | "effect"
5 | ],
6 | "DESCRIPTION" : "Pinch",
7 | "ISFVSN" : "2",
8 | "INPUTS" : [
9 | {
10 | "NAME" : "inputImage",
11 | "TYPE" : "image"
12 | },
13 | {
14 | "NAME" : "center",
15 | "TYPE" : "point2D",
16 | "DEFAULT": [0.5,0.5],
17 | "MIN": [0,0],
18 | "MAX": [1,1]
19 | },
20 | {
21 | "NAME" : "amount",
22 | "TYPE" : "float",
23 | "MAX" : 4.0,
24 | "DEFAULT" : 2.0,
25 | "MIN" : 0
26 | }
27 | ],
28 | "CREDIT" : "2xAA"
29 | }
30 | */
31 |
32 | precision mediump float;
33 |
34 | void main() {
35 |
36 | vec2 uv = gl_FragCoord.xy / RENDERSIZE.xy;
37 |
38 | // normalize to the center
39 | uv = uv - center;
40 |
41 | // cartesian to polar coordinates
42 | float r = length(uv);
43 | float a = atan(uv.y, uv.x);
44 |
45 | // distort
46 | r = sqrt(r/amount); // pinch
47 |
48 | // polar to cartesian coordinates
49 | uv = r * vec2(cos(a), sin(a));
50 |
51 | uv = uv + center;
52 |
53 | vec4 c = IMG_NORM_PIXEL(inputImage, uv);
54 | gl_FragColor = c;
55 | }
--------------------------------------------------------------------------------
/src/application/sample-modules/isf/Posterize.fs:
--------------------------------------------------------------------------------
1 | /*{
2 | "CATEGORIES": [
3 | "Retro",
4 | "Stylize",
5 | "Color Effect"
6 | ],
7 | "CREDIT": "VIDVOX",
8 | "DESCRIPTION": "Posterizes an image",
9 | "INPUTS": [
10 | {
11 | "NAME": "inputImage",
12 | "TYPE": "image"
13 | },
14 | {
15 | "DEFAULT": 1.25,
16 | "LABEL": "Gamma",
17 | "MAX": 2,
18 | "MIN": 0.5,
19 | "NAME": "gamma",
20 | "TYPE": "float"
21 | },
22 | {
23 | "DEFAULT": 6,
24 | "LABEL": "Quality",
25 | "MAX": 32,
26 | "MIN": 3,
27 | "NAME": "numColors",
28 | "TYPE": "float"
29 | }
30 | ],
31 | "ISFVSN": "2"
32 | }
33 | */
34 |
35 | void main() {
36 |
37 | vec4 c = IMG_THIS_PIXEL(inputImage);
38 |
39 | c.rgb = pow(c.rgb, vec3(gamma, gamma, gamma));
40 | c.rgb = c.rgb * numColors;
41 | c.rgb = floor(c.rgb);
42 | c.rgb = c.rgb / numColors;
43 | c.rgb = pow(c.rgb, vec3(1.0/gamma));
44 |
45 | gl_FragColor = c;
46 | }
47 |
--------------------------------------------------------------------------------
/src/application/sample-modules/isf/RGB EQ.fs:
--------------------------------------------------------------------------------
1 | /*{
2 | "CREDIT": "by VIDVOX",
3 | "ISFVSN": "2",
4 | "CATEGORIES": [
5 | "Color Adjustment"
6 | ],
7 | "INPUTS": [
8 | {
9 | "NAME": "inputImage",
10 | "TYPE": "image"
11 | },
12 | {
13 | "NAME": "red",
14 | "TYPE": "float",
15 | "MIN": 0.0,
16 | "MAX": 2.0,
17 | "DEFAULT": 1.0
18 | },
19 | {
20 | "NAME": "green",
21 | "TYPE": "float",
22 | "MIN": 0.0,
23 | "MAX": 2.0,
24 | "DEFAULT": 1.0
25 | },
26 | {
27 | "NAME": "blue",
28 | "TYPE": "float",
29 | "MIN": 0.0,
30 | "MAX": 2.0,
31 | "DEFAULT": 1.0
32 | },
33 | {
34 | "NAME": "gain",
35 | "TYPE": "float",
36 | "MIN": -1.0,
37 | "MAX": 1.0,
38 | "DEFAULT": 0.0
39 | }
40 | ]
41 | }*/
42 |
43 |
44 |
45 |
46 | void main() {
47 | vec4 pixel = IMG_THIS_PIXEL(inputImage);
48 | float brightness = (pixel.r * red + pixel.g * green + pixel.b * blue) / 3.0;
49 |
50 | pixel.r = pixel.r * red;
51 | pixel.g = pixel.g * green;
52 | pixel.b = pixel.b * blue;
53 |
54 | if (gain >= 0.0) {
55 | pixel.a = (brightness >= gain) ? pixel.a : 0.0;
56 | }
57 | else {
58 | pixel.a = (brightness <= 1.0-abs(gain)) ? pixel.a : 0.0;
59 | }
60 | gl_FragColor = pixel;
61 | }
62 |
--------------------------------------------------------------------------------
/src/application/sample-modules/isf/RGB Invert.fs:
--------------------------------------------------------------------------------
1 | /*{
2 | "CATEGORIES": [
3 | "Color Effect",
4 | "Utility"
5 | ],
6 | "CREDIT": "by VIDVOX",
7 | "INPUTS": [
8 | {
9 | "NAME": "inputImage",
10 | "TYPE": "image"
11 | },
12 | {
13 | "DEFAULT": 1,
14 | "NAME": "r",
15 | "TYPE": "bool"
16 | },
17 | {
18 | "DEFAULT": 1,
19 | "NAME": "g",
20 | "TYPE": "bool"
21 | },
22 | {
23 | "DEFAULT": 1,
24 | "NAME": "b",
25 | "TYPE": "bool"
26 | },
27 | {
28 | "DEFAULT": 0,
29 | "NAME": "a",
30 | "TYPE": "bool"
31 | }
32 | ],
33 | "ISFVSN": "2"
34 | }
35 | */
36 |
37 | void main() {
38 | vec4 srcPixel = IMG_THIS_PIXEL(inputImage);
39 | if (r)
40 | srcPixel.r = 1.0-srcPixel.r;
41 | if (g)
42 | srcPixel.g = 1.0-srcPixel.g;
43 | if (b)
44 | srcPixel.b = 1.0-srcPixel.b;
45 | if (a)
46 | srcPixel.a = 1.0-srcPixel.a;
47 | gl_FragColor = srcPixel;
48 | }
--------------------------------------------------------------------------------
/src/application/sample-modules/isf/RGB Trails 3.0.fs:
--------------------------------------------------------------------------------
1 | /*{
2 | "CREDIT": "by zoidberg",
3 | "ISFVSN": "2",
4 | "DESCRIPTION": "a persistent buffer is used to maintain an image which is constantly updated. Similar to VVMotionBlur, but each channel has its own weight",
5 | "CATEGORIES": [
6 | "Color Effect"
7 | ],
8 | "INPUTS": [
9 | {
10 | "NAME": "inputImage",
11 | "TYPE": "image"
12 | },
13 | {
14 | "NAME": "rWeight",
15 | "TYPE": "float"
16 | },
17 | {
18 | "NAME": "gWeight",
19 | "TYPE": "float"
20 | },
21 | {
22 | "NAME": "bWeight",
23 | "TYPE": "float"
24 | },
25 | {
26 | "NAME": "aWeight",
27 | "TYPE": "float",
28 | "DEFAULT": 0.0
29 | }
30 | ],
31 | "PASSES": [
32 | {
33 | "TARGET":"accum",
34 | "PERSISTENT": true,
35 | "FLOAT": true
36 | },
37 | {
38 |
39 | }
40 | ]
41 |
42 | }*/
43 |
44 | void main()
45 | {
46 | if (PASSINDEX==0) {
47 | vec4 freshPixel = IMG_THIS_PIXEL(inputImage);
48 | vec4 stalePixel = IMG_THIS_PIXEL(accum);
49 | gl_FragColor = vec4(mix(freshPixel.r,stalePixel.r,rWeight), mix(freshPixel.g,stalePixel.g,gWeight), mix(freshPixel.b,stalePixel.b,bWeight), mix(freshPixel.a,stalePixel.a,aWeight));
50 | }
51 | else
52 | gl_FragColor = IMG_THIS_PIXEL(accum);
53 | }
54 |
--------------------------------------------------------------------------------
/src/application/sample-modules/isf/RGBtoHSV.fs:
--------------------------------------------------------------------------------
1 | /*{
2 | "CATEGORIES": [
3 | "Color Effect",
4 | "Utility"
5 | ],
6 | "CREDIT": "by zoidberg",
7 | "DESCRIPTION": "swizzles RGBA to BGRA and vice versa",
8 | "INPUTS": [
9 | {
10 | "NAME": "inputImage",
11 | "TYPE": "image"
12 | }
13 | ],
14 | "ISFVSN": "2"
15 | }
16 | */
17 |
18 |
19 |
20 |
21 | vec3 rgb2hsv(vec3 c) {
22 | vec4 K = vec4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0);
23 | //vec4 p = mix(vec4(c.bg, K.wz), vec4(c.gb, K.xy), step(c.b, c.g));
24 | //vec4 q = mix(vec4(p.xyw, c.r), vec4(c.r, p.yzx), step(p.x, c.r));
25 | vec4 p = c.g < c.b ? vec4(c.bg, K.wz) : vec4(c.gb, K.xy);
26 | vec4 q = c.r < p.x ? vec4(p.xyw, c.r) : vec4(c.r, p.yzx);
27 |
28 | float d = q.x - min(q.w, q.y);
29 | float e = 1.0e-10;
30 | return vec3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x);
31 | }
32 |
33 | vec3 hsv2rgb(vec3 c) {
34 | vec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);
35 | vec3 p = abs(fract(c.xxx + K.xyz) * 6.0 - K.www);
36 | return c.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y);
37 | }
38 |
39 |
40 |
41 |
42 | void main()
43 | {
44 | vec4 inColor = IMG_NORM_PIXEL(inputImage, isf_FragNormCoord);
45 | gl_FragColor = vec4(rgb2hsv(inColor.rgb), inColor.a);
46 | }
47 |
--------------------------------------------------------------------------------
/src/application/sample-modules/isf/Rotate.fs:
--------------------------------------------------------------------------------
1 | /*{
2 | "CATEGORIES": [
3 | "Geometry Adjustment",
4 | "Utility"
5 | ],
6 | "CREDIT": "by VIDVOX",
7 | "INPUTS": [
8 | {
9 | "NAME": "inputImage",
10 | "TYPE": "image"
11 | },
12 | {
13 | "DEFAULT": 0,
14 | "MAX": 1,
15 | "MIN": 0,
16 | "NAME": "angle",
17 | "TYPE": "float"
18 | }
19 | ],
20 | "ISFVSN": "2"
21 | }
22 | */
23 |
24 | #if __VERSION__ <= 120
25 | varying vec2 translated_coord;
26 | #else
27 | in vec2 translated_coord;
28 | #endif
29 |
30 | void main() {
31 | vec2 loc = translated_coord;
32 | // if out of range draw black
33 | if ((loc.x < 0.0)||(loc.y < 0.0)||(loc.x > 1.0)||(loc.y > 1.0)) {
34 | gl_FragColor = vec4(0.0);
35 | }
36 | else {
37 | gl_FragColor = IMG_NORM_PIXEL(inputImage,loc);
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/src/application/sample-modules/isf/Rotate.vs:
--------------------------------------------------------------------------------
1 | #if __VERSION__ <= 120
2 | varying vec2 translated_coord;
3 | #else
4 | out vec2 translated_coord;
5 | #endif
6 |
7 | const float pi = 3.14159265359;
8 |
9 | void main() {
10 | isf_vertShaderInit();
11 |
12 | vec2 loc = RENDERSIZE * vec2(vv_FragNormCoord[0],vv_FragNormCoord[1]);
13 | float r = distance(RENDERSIZE/2.0, loc);
14 | float a = atan ((loc.y-RENDERSIZE.y/2.0),(loc.x-RENDERSIZE.x/2.0));
15 |
16 | loc.x = r * cos(a + 2.0 * pi * angle) + 0.5;
17 | loc.y = r * sin(a + 2.0 * pi * angle) + 0.5;
18 |
19 | translated_coord = loc / RENDERSIZE + vec2(0.5);
20 |
21 | }
--------------------------------------------------------------------------------
/src/application/sample-modules/isf/Saturation Bleed.vs:
--------------------------------------------------------------------------------
1 | #if __VERSION__ <= 120
2 | varying vec2 left_coord;
3 | varying vec2 right_coord;
4 | varying vec2 above_coord;
5 | varying vec2 below_coord;
6 |
7 | varying vec2 lefta_coord;
8 | varying vec2 righta_coord;
9 | varying vec2 leftb_coord;
10 | varying vec2 rightb_coord;
11 | #else
12 | out vec2 left_coord;
13 | out vec2 right_coord;
14 | out vec2 above_coord;
15 | out vec2 below_coord;
16 |
17 | out vec2 lefta_coord;
18 | out vec2 righta_coord;
19 | out vec2 leftb_coord;
20 | out vec2 rightb_coord;
21 | #endif
22 |
23 |
24 | void main()
25 | {
26 | isf_vertShaderInit();
27 | vec2 texc = vec2(isf_FragNormCoord[0],isf_FragNormCoord[1]);
28 | vec2 d = 1.0/RENDERSIZE;
29 |
30 | left_coord = clamp(vec2(texc.xy + vec2(-d.x , 0)),0.0,1.0);
31 | right_coord = clamp(vec2(texc.xy + vec2(d.x , 0)),0.0,1.0);
32 | above_coord = clamp(vec2(texc.xy + vec2(0,d.y)),0.0,1.0);
33 | below_coord = clamp(vec2(texc.xy + vec2(0,-d.y)),0.0,1.0);
34 |
35 | lefta_coord = clamp(vec2(texc.xy + vec2(-d.x , d.x)),0.0,1.0);
36 | righta_coord = clamp(vec2(texc.xy + vec2(d.x , d.x)),0.0,1.0);
37 | leftb_coord = clamp(vec2(texc.xy + vec2(-d.x , -d.x)),0.0,1.0);
38 | rightb_coord = clamp(vec2(texc.xy + vec2(d.x , -d.x)),0.0,1.0);
39 | }
--------------------------------------------------------------------------------
/src/application/sample-modules/isf/Sepia Tone.fs:
--------------------------------------------------------------------------------
1 | /*{
2 | "CATEGORIES": [
3 | "Color Effect",
4 | "Retro"
5 | ],
6 | "CREDIT": "by VIDVOX",
7 | "INPUTS": [
8 | {
9 | "NAME": "inputImage",
10 | "TYPE": "image"
11 | },
12 | {
13 | "DEFAULT": 0.8,
14 | "MAX": 1.2,
15 | "MIN": 0.8,
16 | "NAME": "contrast",
17 | "TYPE": "float"
18 | }
19 | ],
20 | "ISFVSN": "2"
21 | }
22 | */
23 |
24 |
25 | // Adapted from https://www.omniref.com/ruby/gems/essytas/0.0.1/files/lib/glsl/sepia.frag
26 |
27 | void main() {
28 |
29 | vec4 rawColor = IMG_THIS_PIXEL(inputImage);
30 | vec4 color = rawColor;
31 | vec4 sepia1 = vec4( 0.2, 0.05, 0.0, 1.0 );
32 | vec4 sepia2 = vec4( 1.0, 0.9, 0.5, 1.0 );
33 | float sepiaMix = dot(vec3(0.3, 0.59, 0.11), color.rgb);
34 | color = mix(color, vec4(sepiaMix), 0.5);
35 | vec4 sepia = mix(sepia1, sepia2, sepiaMix);
36 | sepia = vec4( min( vec3( 1.0 ), sepia.rgb ), color.a );
37 |
38 | float bright = 0.05;
39 | sepia = sepia + vec4(bright, bright, bright, 0.0);
40 | sepia.rgb = ((vec3(2.0) * (sepia.rgb - vec3(0.5))) * vec3(contrast) / vec3(2.0)) + vec3(0.5);
41 | sepia.a = rawColor.a;
42 | gl_FragColor = sepia;
43 |
44 | }
45 |
--------------------------------------------------------------------------------
/src/application/sample-modules/isf/Set Alpha.fs:
--------------------------------------------------------------------------------
1 | /*{
2 | "CATEGORIES": [
3 | "Color Adjustment",
4 | "Utility"
5 | ],
6 | "CREDIT": "VIDVOX",
7 | "DESCRIPTION": "Sets the alpha channel of the image",
8 | "INPUTS": [
9 | {
10 | "NAME": "inputImage",
11 | "TYPE": "image"
12 | },
13 | {
14 | "DEFAULT": 0.5,
15 | "LABEL": "New Alpha",
16 | "MAX": 1,
17 | "MIN": 0,
18 | "NAME": "newAlpha",
19 | "TYPE": "float"
20 | }
21 | ],
22 | "ISFVSN": "2"
23 | }
24 | */
25 |
26 | void main() {
27 | vec4 inputPixelColor = IMG_THIS_NORM_PIXEL(inputImage);
28 |
29 | inputPixelColor.a = newAlpha;
30 |
31 | gl_FragColor = inputPixelColor;
32 | }
33 |
--------------------------------------------------------------------------------
/src/application/sample-modules/isf/Shake.fs:
--------------------------------------------------------------------------------
1 | /*{
2 | "CATEGORIES": [
3 | "Noise",
4 | "Geometry Adjustment"
5 | ],
6 | "CREDIT": "by VIDVOX",
7 | "INPUTS": [
8 | {
9 | "NAME": "inputImage",
10 | "TYPE": "image"
11 | },
12 | {
13 | "DEFAULT": 0,
14 | "MAX": 2,
15 | "MIN": 0,
16 | "NAME": "magnitude",
17 | "TYPE": "float"
18 | },
19 | {
20 | "DEFAULT": 1,
21 | "MAX": 10,
22 | "MIN": 0,
23 | "NAME": "intensity",
24 | "TYPE": "float"
25 | }
26 | ],
27 | "ISFVSN": "2"
28 | }
29 | */
30 |
31 |
32 | const float pi = 3.14159265359;
33 |
34 |
35 | float rand(vec2 co) {
36 | return fract(sin(dot(co.xy, vec2(12.9898,78.233))) * 43758.5453);
37 | }
38 |
39 | void main(void) {
40 | float offset = 0.1 * magnitude;
41 | vec2 uv = gl_FragCoord.xy / RENDERSIZE.xy;
42 | float rotation = intensity * 2.0 * pi * rand(vec2(magnitude, TIME));
43 | float yOffset = offset * sin(TIME * 1.0 * cos(TIME * intensity) + rotation) * rand(vec2(magnitude, TIME));
44 | float xOffset = offset * cos(TIME * 1.0 * cos(TIME * intensity) + rotation) * rand(vec2(1.0-magnitude, TIME));;
45 |
46 | float zoom = 1.0 + offset;
47 |
48 | uv = (uv - 0.5) / zoom + 0.5;
49 |
50 | uv.y += yOffset;
51 | uv.x += xOffset;
52 |
53 | gl_FragColor = IMG_NORM_PIXEL(inputImage, uv);
54 | }
--------------------------------------------------------------------------------
/src/application/sample-modules/isf/Sharpen Luminance.vs:
--------------------------------------------------------------------------------
1 | #if __VERSION__ <= 120
2 | varying vec2 left_coord;
3 | varying vec2 right_coord;
4 | varying vec2 above_coord;
5 | varying vec2 below_coord;
6 |
7 | varying vec2 lefta_coord;
8 | varying vec2 righta_coord;
9 | varying vec2 leftb_coord;
10 | varying vec2 rightb_coord;
11 | #else
12 | out vec2 left_coord;
13 | out vec2 right_coord;
14 | out vec2 above_coord;
15 | out vec2 below_coord;
16 |
17 | out vec2 lefta_coord;
18 | out vec2 righta_coord;
19 | out vec2 leftb_coord;
20 | out vec2 rightb_coord;
21 | #endif
22 |
23 |
24 | void main()
25 | {
26 | isf_vertShaderInit();
27 | vec2 texc = vec2(isf_FragNormCoord[0],isf_FragNormCoord[1]);
28 | vec2 d = 1.0/RENDERSIZE;
29 |
30 | left_coord = clamp(vec2(texc.xy + vec2(-d.x , 0)),0.0,1.0);
31 | right_coord = clamp(vec2(texc.xy + vec2(d.x , 0)),0.0,1.0);
32 | above_coord = clamp(vec2(texc.xy + vec2(0,d.y)),0.0,1.0);
33 | below_coord = clamp(vec2(texc.xy + vec2(0,-d.y)),0.0,1.0);
34 |
35 | lefta_coord = clamp(vec2(texc.xy + vec2(-d.x , d.x)),0.0,1.0);
36 | righta_coord = clamp(vec2(texc.xy + vec2(d.x , d.x)),0.0,1.0);
37 | leftb_coord = clamp(vec2(texc.xy + vec2(-d.x , -d.x)),0.0,1.0);
38 | rightb_coord = clamp(vec2(texc.xy + vec2(d.x , -d.x)),0.0,1.0);
39 | }
--------------------------------------------------------------------------------
/src/application/sample-modules/isf/Sharpen RGB.vs:
--------------------------------------------------------------------------------
1 | #if __VERSION__ <= 120
2 | varying vec2 left_coord;
3 | varying vec2 right_coord;
4 | varying vec2 above_coord;
5 | varying vec2 below_coord;
6 |
7 | varying vec2 lefta_coord;
8 | varying vec2 righta_coord;
9 | varying vec2 leftb_coord;
10 | varying vec2 rightb_coord;
11 | #else
12 | out vec2 left_coord;
13 | out vec2 right_coord;
14 | out vec2 above_coord;
15 | out vec2 below_coord;
16 |
17 | out vec2 lefta_coord;
18 | out vec2 righta_coord;
19 | out vec2 leftb_coord;
20 | out vec2 rightb_coord;
21 | #endif
22 |
23 |
24 | void main()
25 | {
26 | isf_vertShaderInit();
27 | vec2 texc = vec2(isf_FragNormCoord[0],isf_FragNormCoord[1]);
28 | vec2 d = 1.0/RENDERSIZE;
29 |
30 | left_coord = clamp(vec2(texc.xy + vec2(-d.x , 0)),0.0,1.0);
31 | right_coord = clamp(vec2(texc.xy + vec2(d.x , 0)),0.0,1.0);
32 | above_coord = clamp(vec2(texc.xy + vec2(0,d.y)),0.0,1.0);
33 | below_coord = clamp(vec2(texc.xy + vec2(0,-d.y)),0.0,1.0);
34 |
35 | lefta_coord = clamp(vec2(texc.xy + vec2(-d.x , d.x)),0.0,1.0);
36 | righta_coord = clamp(vec2(texc.xy + vec2(d.x , d.x)),0.0,1.0);
37 | leftb_coord = clamp(vec2(texc.xy + vec2(-d.x , -d.x)),0.0,1.0);
38 | rightb_coord = clamp(vec2(texc.xy + vec2(d.x , -d.x)),0.0,1.0);
39 | }
--------------------------------------------------------------------------------
/src/application/sample-modules/isf/Show Alpha.fs:
--------------------------------------------------------------------------------
1 | /*{
2 | "CATEGORIES": [
3 | "Utility"
4 | ],
5 | "CREDIT": "VIDVOX",
6 | "DESCRIPTION": "Maps the alpha to grayscale",
7 | "INPUTS": [
8 | {
9 | "NAME": "inputImage",
10 | "TYPE": "image"
11 | }
12 | ],
13 | "ISFVSN": "2"
14 | }
15 | */
16 |
17 | void main() {
18 | vec4 inputPixelColor = IMG_THIS_PIXEL(inputImage);
19 | inputPixelColor.rgb = vec3(inputPixelColor.a);
20 | inputPixelColor.a = 1.0;
21 | gl_FragColor = inputPixelColor;
22 | }
23 |
--------------------------------------------------------------------------------
/src/application/sample-modules/isf/Side Scroller And Flip.fs:
--------------------------------------------------------------------------------
1 | /*{
2 | "CREDIT": "BrianChasalow",
3 | "ISFVSN": "2",
4 | "CATEGORIES": [
5 | "Geometry Adjustment"
6 | ],
7 | "INPUTS": [
8 | {
9 | "NAME": "inputImage",
10 | "TYPE": "image"
11 | },
12 | {
13 | "NAME": "slide",
14 | "TYPE": "float",
15 | "MIN": 0.0,
16 | "MAX": 2.0,
17 | "DEFAULT": 0.0
18 | },
19 | {
20 | "NAME": "shift",
21 | "TYPE": "float",
22 | "MIN": 0.0,
23 | "MAX": 2.0,
24 | "DEFAULT": 0.0
25 | },
26 | {
27 | "NAME": "mirrorHorizontal",
28 | "TYPE": "bool",
29 | "MIN": false,
30 | "MAX": true,
31 | "DEFAULT": true
32 | },
33 | {
34 | "NAME": "mirrorVertical",
35 | "TYPE": "bool",
36 | "MIN": false,
37 | "MAX": true,
38 | "DEFAULT": true
39 | }
40 |
41 | ]
42 | }*/
43 |
44 | void main(void)
45 | {
46 | vec2 retard = isf_FragNormCoord;
47 | retard.x += slide;
48 | retard.y += shift;
49 | vec2 moddedRetard = mod(retard,1.0);
50 |
51 | if(mirrorHorizontal && retard.x >= 1.0 && retard.x <= 2.0)
52 | moddedRetard = vec2(1.0-moddedRetard.x, moddedRetard.y);
53 | if(mirrorVertical && retard.y >= 1.0 && retard.y <= 2.0)
54 | moddedRetard = vec2(moddedRetard.x, 1.0-moddedRetard.y);
55 |
56 | vec4 pixel = IMG_NORM_PIXEL(inputImage, moddedRetard);
57 | gl_FragColor = pixel;
58 | }
--------------------------------------------------------------------------------
/src/application/sample-modules/isf/Sketch.vs:
--------------------------------------------------------------------------------
1 | #if __VERSION__ <= 120
2 | varying vec2 left_coord;
3 | varying vec2 right_coord;
4 | varying vec2 above_coord;
5 | varying vec2 below_coord;
6 |
7 | varying vec2 lefta_coord;
8 | varying vec2 righta_coord;
9 | varying vec2 leftb_coord;
10 | varying vec2 rightb_coord;
11 | #else
12 | out vec2 left_coord;
13 | out vec2 right_coord;
14 | out vec2 above_coord;
15 | out vec2 below_coord;
16 |
17 | out vec2 lefta_coord;
18 | out vec2 righta_coord;
19 | out vec2 leftb_coord;
20 | out vec2 rightb_coord;
21 | #endif
22 |
23 |
24 | void main()
25 | {
26 | isf_vertShaderInit();
27 | vec2 texc = vec2(isf_FragNormCoord[0],isf_FragNormCoord[1]);
28 | vec2 d = 1.0/RENDERSIZE;
29 |
30 | left_coord = clamp(vec2(texc.xy + vec2(-d.x , 0)),0.0,1.0);
31 | right_coord = clamp(vec2(texc.xy + vec2(d.x , 0)),0.0,1.0);
32 | above_coord = clamp(vec2(texc.xy + vec2(0,d.y)),0.0,1.0);
33 | below_coord = clamp(vec2(texc.xy + vec2(0,-d.y)),0.0,1.0);
34 |
35 | lefta_coord = clamp(vec2(texc.xy + vec2(-d.x , d.x)),0.0,1.0);
36 | righta_coord = clamp(vec2(texc.xy + vec2(d.x , d.x)),0.0,1.0);
37 | leftb_coord = clamp(vec2(texc.xy + vec2(-d.x , -d.x)),0.0,1.0);
38 | rightb_coord = clamp(vec2(texc.xy + vec2(d.x , -d.x)),0.0,1.0);
39 | }
--------------------------------------------------------------------------------
/src/application/sample-modules/isf/Slice.fs:
--------------------------------------------------------------------------------
1 | /*
2 | {
3 | "CATEGORIES" : [
4 | "effect"
5 | ],
6 | "DESCRIPTION" : "Slice",
7 | "ISFVSN" : "2",
8 | "INPUTS" : [
9 | {
10 | "NAME" : "inputImage",
11 | "TYPE" : "image"
12 | },
13 | {
14 | "NAME" : "slices",
15 | "TYPE" : "float",
16 | "MAX" : 200,
17 | "DEFAULT" : 10,
18 | "MIN" : 1
19 | },
20 | {
21 | "NAME" : "offset",
22 | "TYPE" : "float",
23 | "MAX" : 0.5,
24 | "DEFAULT" : 0.03,
25 | "MIN" : 0
26 | },
27 | {
28 | "NAME" : "timeMultiplier",
29 | "TYPE" : "float",
30 | "MAX" : 3.0,
31 | "DEFAULT" : 1.0,
32 | "MIN" : 0.0
33 | }
34 | ],
35 | "CREDIT" : "https://getmosh.io/"
36 | }
37 | */
38 |
39 | precision mediump float;
40 |
41 | varying vec2 vUv;
42 |
43 | float rand(vec2 co){
44 | return fract(sin(dot(co.xy ,vec2(12.9898,78.233))) * 43758.5453);
45 | }
46 |
47 | void main() {
48 | vec2 p = gl_FragCoord.xy / RENDERSIZE.xy;
49 | float yInt = floor(p.y * slices) / slices;
50 | float rnd = rand(vec2(yInt, yInt));
51 | p.x += sin((TIME * timeMultiplier) * rnd / 5.0) * offset - offset / 2.0;
52 | p.x = fract(p.x);
53 | gl_FragColor = texture2D(inputImage, p);
54 | }
--------------------------------------------------------------------------------
/src/application/sample-modules/isf/Smudged Lens.vs:
--------------------------------------------------------------------------------
1 | #if __VERSION__ <= 120
2 | varying vec2 left_coord;
3 | varying vec2 right_coord;
4 | varying vec2 above_coord;
5 | varying vec2 below_coord;
6 |
7 | varying vec2 lefta_coord;
8 | varying vec2 righta_coord;
9 | varying vec2 leftb_coord;
10 | varying vec2 rightb_coord;
11 | #else
12 | out vec2 left_coord;
13 | out vec2 right_coord;
14 | out vec2 above_coord;
15 | out vec2 below_coord;
16 |
17 | out vec2 lefta_coord;
18 | out vec2 righta_coord;
19 | out vec2 leftb_coord;
20 | out vec2 rightb_coord;
21 | #endif
22 |
23 |
24 | void main()
25 | {
26 | isf_vertShaderInit();
27 | vec2 texc = vec2(isf_FragNormCoord[0],isf_FragNormCoord[1]);
28 | vec2 d = 1.0/RENDERSIZE;
29 |
30 | left_coord = clamp(vec2(texc.xy + vec2(-d.x , 0)),0.0,1.0);
31 | right_coord = clamp(vec2(texc.xy + vec2(d.x , 0)),0.0,1.0);
32 | above_coord = clamp(vec2(texc.xy + vec2(0,d.y)),0.0,1.0);
33 | below_coord = clamp(vec2(texc.xy + vec2(0,-d.y)),0.0,1.0);
34 |
35 | lefta_coord = clamp(vec2(texc.xy + vec2(-d.x , d.x)),0.0,1.0);
36 | righta_coord = clamp(vec2(texc.xy + vec2(d.x , d.x)),0.0,1.0);
37 | leftb_coord = clamp(vec2(texc.xy + vec2(-d.x , -d.x)),0.0,1.0);
38 | rightb_coord = clamp(vec2(texc.xy + vec2(d.x , -d.x)),0.0,1.0);
39 | }
--------------------------------------------------------------------------------
/src/application/sample-modules/isf/Soft Blur.vs:
--------------------------------------------------------------------------------
1 | #if __VERSION__ <= 120
2 | varying vec2 left_coord;
3 | varying vec2 right_coord;
4 | varying vec2 above_coord;
5 | varying vec2 below_coord;
6 |
7 | varying vec2 lefta_coord;
8 | varying vec2 righta_coord;
9 | varying vec2 leftb_coord;
10 | varying vec2 rightb_coord;
11 | #else
12 | out vec2 left_coord;
13 | out vec2 right_coord;
14 | out vec2 above_coord;
15 | out vec2 below_coord;
16 |
17 | out vec2 lefta_coord;
18 | out vec2 righta_coord;
19 | out vec2 leftb_coord;
20 | out vec2 rightb_coord;
21 | #endif
22 |
23 |
24 | void main()
25 | {
26 | isf_vertShaderInit();
27 | vec2 texc = vec2(isf_FragNormCoord[0],isf_FragNormCoord[1]);
28 | vec2 d = 1.0/RENDERSIZE;
29 |
30 | left_coord = clamp(vec2(texc.xy + vec2(-d.x , 0)),0.0,1.0);
31 | right_coord = clamp(vec2(texc.xy + vec2(d.x , 0)),0.0,1.0);
32 | above_coord = clamp(vec2(texc.xy + vec2(0,d.y)),0.0,1.0);
33 | below_coord = clamp(vec2(texc.xy + vec2(0,-d.y)),0.0,1.0);
34 |
35 | lefta_coord = clamp(vec2(texc.xy + vec2(-d.x , d.x)),0.0,1.0);
36 | righta_coord = clamp(vec2(texc.xy + vec2(d.x , d.x)),0.0,1.0);
37 | leftb_coord = clamp(vec2(texc.xy + vec2(-d.x , -d.x)),0.0,1.0);
38 | rightb_coord = clamp(vec2(texc.xy + vec2(d.x , -d.x)),0.0,1.0);
39 | }
--------------------------------------------------------------------------------
/src/application/sample-modules/isf/Solid Color.fs:
--------------------------------------------------------------------------------
1 | /*{
2 | "CATEGORIES": [
3 | "Color",
4 | "Utility"
5 | ],
6 | "CREDIT": "by Carter Rosenberg",
7 | "DESCRIPTION": "demonstrates the use of color-type image inputs",
8 | "INPUTS": [
9 | {
10 | "DEFAULT": [
11 | 1,
12 | 0,
13 | 0,
14 | 1
15 | ],
16 | "NAME": "Color",
17 | "TYPE": "color"
18 | }
19 | ],
20 | "ISFVSN": "2"
21 | }
22 | */
23 |
24 | void main()
25 | {
26 | gl_FragColor = Color;
27 | }
28 |
--------------------------------------------------------------------------------
/src/application/sample-modules/isf/Sorting Smear.vs:
--------------------------------------------------------------------------------
1 | #if __VERSION__ <= 120
2 | varying vec2 left_coord;
3 | varying vec2 right_coord;
4 | varying vec2 above_coord;
5 | varying vec2 below_coord;
6 | #else
7 | out vec2 left_coord;
8 | out vec2 right_coord;
9 | out vec2 above_coord;
10 | out vec2 below_coord;
11 | #endif
12 |
13 |
14 | void main()
15 | {
16 | isf_vertShaderInit();
17 | vec2 texc = vec2(isf_FragNormCoord[0],isf_FragNormCoord[1]);
18 | vec2 d = 1.0/RENDERSIZE;
19 |
20 | left_coord = clamp(vec2(texc.xy + vec2(-d.x , 0)),0.0,1.0);
21 | right_coord = clamp(vec2(texc.xy + vec2(d.x , 0)),0.0,1.0);
22 | above_coord = clamp(vec2(texc.xy + vec2(0,d.y)),0.0,1.0);
23 | below_coord = clamp(vec2(texc.xy + vec2(0,-d.y)),0.0,1.0);
24 | }
--------------------------------------------------------------------------------
/src/application/sample-modules/isf/Unsharp Mask.vs:
--------------------------------------------------------------------------------
1 | #if __VERSION__ <= 120
2 | varying vec2 left_coord;
3 | varying vec2 right_coord;
4 | varying vec2 above_coord;
5 | varying vec2 below_coord;
6 |
7 | varying vec2 lefta_coord;
8 | varying vec2 righta_coord;
9 | varying vec2 leftb_coord;
10 | varying vec2 rightb_coord;
11 | #else
12 | out vec2 left_coord;
13 | out vec2 right_coord;
14 | out vec2 above_coord;
15 | out vec2 below_coord;
16 |
17 | out vec2 lefta_coord;
18 | out vec2 righta_coord;
19 | out vec2 leftb_coord;
20 | out vec2 rightb_coord;
21 | #endif
22 |
23 |
24 | void main()
25 | {
26 | isf_vertShaderInit();
27 | vec2 texc = vec2(isf_FragNormCoord[0],isf_FragNormCoord[1]);
28 | vec2 d = 1.0/RENDERSIZE;
29 |
30 | left_coord = clamp(vec2(texc.xy + vec2(-d.x , 0)),0.0,1.0);
31 | right_coord = clamp(vec2(texc.xy + vec2(d.x , 0)),0.0,1.0);
32 | above_coord = clamp(vec2(texc.xy + vec2(0,d.y)),0.0,1.0);
33 | below_coord = clamp(vec2(texc.xy + vec2(0,-d.y)),0.0,1.0);
34 |
35 | lefta_coord = clamp(vec2(texc.xy + vec2(-d.x , d.x)),0.0,1.0);
36 | righta_coord = clamp(vec2(texc.xy + vec2(d.x , d.x)),0.0,1.0);
37 | leftb_coord = clamp(vec2(texc.xy + vec2(-d.x , -d.x)),0.0,1.0);
38 | rightb_coord = clamp(vec2(texc.xy + vec2(d.x , -d.x)),0.0,1.0);
39 | }
--------------------------------------------------------------------------------
/src/application/sample-modules/isf/VVMotionBlur 3.0.fs:
--------------------------------------------------------------------------------
1 | /*{
2 | "DESCRIPTION": "this is basically identical to the demonstration of a persistent buffer",
3 | "CREDIT": "by zoidberg",
4 | "ISFVSN": "2",
5 | "CATEGORIES": [
6 | "Blur"
7 | ],
8 | "INPUTS": [
9 | {
10 | "NAME": "inputImage",
11 | "TYPE": "image"
12 | },
13 | {
14 | "NAME": "blurAmount",
15 | "TYPE": "float",
16 | "DEFAULT": 0.0
17 | }
18 | ],
19 | "PASSES": [
20 | {
21 | "TARGET":"bufferVariableNameA",
22 | "PERSISTENT": true,
23 | "FLOAT": true
24 | },
25 | {
26 |
27 | }
28 | ]
29 |
30 | }*/
31 |
32 | void main()
33 | {
34 | vec4 freshPixel = IMG_PIXEL(inputImage,gl_FragCoord.xy);
35 | vec4 stalePixel = IMG_PIXEL(bufferVariableNameA,gl_FragCoord.xy);
36 | gl_FragColor = mix(freshPixel,stalePixel,blurAmount);
37 | }
38 |
--------------------------------------------------------------------------------
/src/application/sample-modules/isf/Vertex Manipulator.fs:
--------------------------------------------------------------------------------
1 | /*{
2 | "CATEGORIES": [
3 | "Geometry Adjustment"
4 | ],
5 | "CREDIT": "VIDVOX",
6 | "DESCRIPTION": "Moves the vertex points to the specified locations without correction",
7 | "INPUTS": [
8 | {
9 | "NAME": "inputImage",
10 | "TYPE": "image"
11 | },
12 | {
13 | "DEFAULT": [
14 | 0,
15 | 1
16 | ],
17 | "LABEL": "Top Left",
18 | "NAME": "topleft",
19 | "TYPE": "point2D"
20 | },
21 | {
22 | "DEFAULT": [
23 | 0,
24 | 0
25 | ],
26 | "LABEL": "Bottom Left",
27 | "NAME": "bottomleft",
28 | "TYPE": "point2D"
29 | },
30 | {
31 | "DEFAULT": [
32 | 1,
33 | 1
34 | ],
35 | "LABEL": "Top Right",
36 | "NAME": "topright",
37 | "TYPE": "point2D"
38 | },
39 | {
40 | "DEFAULT": [
41 | 1,
42 | 0
43 | ],
44 | "LABEL": "Bottom Right",
45 | "NAME": "bottomright",
46 | "TYPE": "point2D"
47 | }
48 | ],
49 | "ISFVSN": "2"
50 | }
51 | */
52 |
53 |
54 | void main()
55 | {
56 | vec4 test = IMG_THIS_PIXEL(inputImage);
57 | gl_FragColor = test;
58 | }
59 |
--------------------------------------------------------------------------------
/src/application/sample-modules/isf/Vertex Manipulator.vs:
--------------------------------------------------------------------------------
1 |
2 |
3 | void main()
4 | {
5 | isf_vertShaderInit();
6 |
7 | vec4 position = gl_Position;
8 | vec4 coord;
9 | if ((position.x<0.0)&&(position.y<0.0)) {
10 | coord.xy = bottomleft / RENDERSIZE;
11 | coord.x = coord.x * 2.0;
12 | coord.y = coord.y * 2.0;
13 | }
14 | else if ((position.x>0.0)&&(position.y<0.0)) {
15 | coord.xy = bottomright / RENDERSIZE;
16 | coord.x = (1.0-coord.x) * -2.0;
17 | coord.y = coord.y * 2.0;
18 | }
19 | else if (position.x<0.0) {
20 | coord.xy = topleft / RENDERSIZE;
21 | coord.x = coord.x * 2.0;
22 | coord.y = (1.0-coord.y) * -2.0;
23 | }
24 | else {
25 | coord.xy = topright / RENDERSIZE;
26 | coord.x = (1.0-coord.x) * -2.0;
27 | coord.y = (1.0-coord.y) * -2.0;
28 | }
29 | gl_Position.xy = position.xy + coord.xy;
30 |
31 | }
32 |
--------------------------------------------------------------------------------
/src/application/sample-modules/isf/Vertical Tearing.fs:
--------------------------------------------------------------------------------
1 | /*
2 | {
3 | "CATEGORIES" : [
4 | "Glitch"
5 | ],
6 | "DESCRIPTION" : "This introduces a vertical tearing effect similar to when GL VBL sync is off.",
7 | "ISFVSN" : "2",
8 | "INPUTS" : [
9 | {
10 | "NAME" : "inputImage",
11 | "TYPE" : "image"
12 | },
13 | {
14 | "NAME" : "tearPosition",
15 | "TYPE" : "float",
16 | "MAX" : 1,
17 | "DEFAULT" : 0.5,
18 | "MIN" : 0
19 | }
20 | ],
21 | "PASSES" : [
22 | {
23 | "TARGET" : "oldImage"
24 | },
25 | {
26 | "TARGET" : "newImage",
27 | "PERSISTENT" : true
28 | },
29 | {
30 |
31 | }
32 | ],
33 | "CREDIT" : "by VIDVOX"
34 | }
35 | */
36 |
37 | void main()
38 | {
39 | // write the previous buffer into here
40 | if (PASSINDEX == 0) {
41 | gl_FragColor = IMG_NORM_PIXEL(newImage,isf_FragNormCoord.xy);
42 | }
43 | else if (PASSINDEX == 1) {
44 | gl_FragColor = IMG_NORM_PIXEL(inputImage,isf_FragNormCoord.xy);
45 | }
46 | else if (PASSINDEX == 2) {
47 | vec4 freshPixel = IMG_NORM_PIXEL(inputImage,isf_FragNormCoord.xy);
48 | vec4 stalePixel = IMG_NORM_PIXEL(oldImage,isf_FragNormCoord.xy);
49 | gl_FragColor = (isf_FragNormCoord.y > tearPosition) ? freshPixel : stalePixel;
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/src/application/sample-modules/isf/Vignette.fs:
--------------------------------------------------------------------------------
1 | /*
2 | {
3 | "DESCRIPTION" : "A simple Vignette",
4 | "ISFVSN" : "2",
5 | "INPUTS" : [
6 | {
7 | "NAME" : "inputImage",
8 | "TYPE" : "image"
9 | },
10 | {
11 | "NAME" : "intensity",
12 | "TYPE" : "float",
13 | "MAX" : 100,
14 | "DEFAULT" : 15,
15 | "MIN" : 1,
16 | "LABEL" : "Intensity"
17 | },
18 | {
19 | "NAME" : "extension",
20 | "TYPE" : "float",
21 | "MAX" : 2.5,
22 | "DEFAULT" : 0.25,
23 | "MIN" : 0.05,
24 | "LABEL" : "Extension"
25 | }
26 | ],
27 | "CREDIT" : "2xAA"
28 | }
29 | */
30 |
31 | void mainImage( out vec4 fragColor, in vec2 fragCoord ) {
32 | vec2 uv = fragCoord.xy / RENDERSIZE.xy;
33 | uv *= 1.0 - uv.yx; //vec2(1.0)- uv.yx; -> 1.-u.yx; Thanks FabriceNeyret !
34 | float vig = uv.x * uv.y * intensity; // multiply with sth for intensity
35 | vig = pow(vig, extension); // change pow for modifying the extend of the vignette
36 | fragColor = vec4(IMG_NORM_PIXEL(inputImage, isf_FragNormCoord).rgb * (clamp(vig, 0., 1.)), 1.0);
37 | }
38 |
39 | void main(void) {
40 | mainImage(gl_FragColor, gl_FragCoord.xy);
41 | }
--------------------------------------------------------------------------------
/src/application/sample-modules/isf/White Point Adjust.fs:
--------------------------------------------------------------------------------
1 | /*{
2 | "CREDIT": "by zoidberg",
3 | "ISFVSN": "2",
4 | "DESCRIPTION": "Modifies the white point by multiplying the src pixel by the color value",
5 | "CATEGORIES": [
6 | "Color Adjustment"
7 | ],
8 | "INPUTS": [
9 | {
10 | "NAME": "inputImage",
11 | "TYPE": "image"
12 | },
13 | {
14 | "NAME": "newWhite",
15 | "TYPE": "color",
16 | "DEFAULT": [
17 | 1.0,
18 | 1.0,
19 | 1.0,
20 | 1.0
21 | ]
22 | }
23 | ]
24 | }*/
25 |
26 |
27 |
28 | void main() {
29 | vec4 tmpColorA = IMG_THIS_PIXEL(inputImage);
30 | gl_FragColor = tmpColorA * newWhite;
31 | }
--------------------------------------------------------------------------------
/src/application/sample-modules/isf/Window Blinds.fs:
--------------------------------------------------------------------------------
1 | /*
2 | {
3 | "CATEGORIES" : [
4 | "Dissolve"
5 | ],
6 | "INPUTS" : [
7 | {
8 | "TYPE" : "image",
9 | "NAME" : "startImage"
10 | },
11 | {
12 | "NAME" : "endImage",
13 | "TYPE" : "image"
14 | },
15 | {
16 | "NAME" : "progress",
17 | "MIN" : 0,
18 | "TYPE" : "float",
19 | "MAX" : 1,
20 | "DEFAULT" : 0
21 | }
22 | ],
23 | "CREDIT": "Automatically converted from https://www.github.com/gl-transitions/gl-transitions/tree/master/windowblinds.glsl",
24 | "DESCRIPTION": "",
25 | "ISFVSN" : "2"
26 | }
27 | */
28 |
29 |
30 |
31 | vec4 getFromColor(vec2 inUV) {
32 | return IMG_NORM_PIXEL(startImage, inUV);
33 | }
34 | vec4 getToColor(vec2 inUV) {
35 | return IMG_NORM_PIXEL(endImage, inUV);
36 | }
37 |
38 |
39 |
40 | // Author: Fabien Benetou
41 | // License: MIT
42 |
43 | vec4 transition (vec2 uv) {
44 | float t = progress;
45 |
46 | if (mod(floor(uv.y*100.*progress),2.)==0.)
47 | t*=2.-.5;
48 |
49 | return mix(
50 | getFromColor(uv),
51 | getToColor(uv),
52 | mix(t, progress, smoothstep(0.8, 1.0, progress))
53 | );
54 | }
55 |
56 |
57 |
58 | void main() {
59 | gl_FragColor = transition(isf_FragNormCoord.xy);
60 | }
--------------------------------------------------------------------------------
/src/application/sample-modules/isf/Wipe Down.fs:
--------------------------------------------------------------------------------
1 | /*
2 | {
3 | "ISFVSN" : "2",
4 | "INPUTS" : [
5 | {
6 | "TYPE" : "image",
7 | "NAME" : "startImage"
8 | },
9 | {
10 | "TYPE" : "image",
11 | "NAME" : "endImage"
12 | },
13 | {
14 | "TYPE" : "float",
15 | "NAME" : "progress",
16 | "MIN" : 0,
17 | "MAX" : 1,
18 | "DEFAULT" : 0
19 | }
20 | ],
21 | "CATEGORIES" : [
22 | "Wipe"
23 | ],
24 | "CREDIT": "Automatically converted from https://www.github.com/gl-transitions/gl-transitions/tree/master/wipeDown.glsl",
25 | "DESCRIPTION" : "Automatically converted from https://gl-transitions.com/"
26 | }
27 | */
28 |
29 |
30 |
31 | vec4 getFromColor(vec2 inUV) {
32 | return IMG_NORM_PIXEL(startImage, inUV);
33 | }
34 | vec4 getToColor(vec2 inUV) {
35 | return IMG_NORM_PIXEL(endImage, inUV);
36 | }
37 |
38 |
39 |
40 | // Author: Jake Nelson
41 | // License: MIT
42 |
43 | vec4 transition(vec2 uv) {
44 | vec2 p=uv.xy/vec2(1.0).xy;
45 | vec4 a=getFromColor(p);
46 | vec4 b=getToColor(p);
47 | return mix(a, b, step(1.0-p.y,progress));
48 | }
49 |
50 |
51 |
52 | void main() {
53 | gl_FragColor = transition(isf_FragNormCoord.xy);
54 | }
--------------------------------------------------------------------------------
/src/application/sample-modules/isf/Wipe Left.fs:
--------------------------------------------------------------------------------
1 | /*
2 | {
3 | "INPUTS" : [
4 | {
5 | "TYPE" : "image",
6 | "NAME" : "startImage"
7 | },
8 | {
9 | "TYPE" : "image",
10 | "NAME" : "endImage"
11 | },
12 | {
13 | "TYPE" : "float",
14 | "MAX" : 1,
15 | "NAME" : "progress",
16 | "MIN" : 0,
17 | "DEFAULT" : 0
18 | }
19 | ],
20 | "CATEGORIES" : [
21 | "Wipe"
22 | ],
23 | "CREDIT": "Automatically converted from https://www.github.com/gl-transitions/gl-transitions/tree/master/wipeLeft.glsl",
24 | "DESCRIPTION": "",
25 | "ISFVSN" : "2"
26 | }
27 | */
28 |
29 |
30 |
31 | vec4 getFromColor(vec2 inUV) {
32 | return IMG_NORM_PIXEL(startImage, inUV);
33 | }
34 | vec4 getToColor(vec2 inUV) {
35 | return IMG_NORM_PIXEL(endImage, inUV);
36 | }
37 |
38 |
39 |
40 | // Author: Jake Nelson
41 | // License: MIT
42 |
43 | vec4 transition(vec2 uv) {
44 | vec2 p=uv.xy/vec2(1.0).xy;
45 | vec4 a=getFromColor(p);
46 | vec4 b=getToColor(p);
47 | return mix(a, b, step(1.0-p.x,progress));
48 | }
49 |
50 |
51 |
52 | void main() {
53 | gl_FragColor = transition(isf_FragNormCoord.xy);
54 | }
--------------------------------------------------------------------------------
/src/application/sample-modules/isf/Wipe Right.fs:
--------------------------------------------------------------------------------
1 | /*
2 | {
3 | "INPUTS" : [
4 | {
5 | "TYPE" : "image",
6 | "NAME" : "startImage"
7 | },
8 | {
9 | "TYPE" : "image",
10 | "NAME" : "endImage"
11 | },
12 | {
13 | "TYPE" : "float",
14 | "MAX" : 1,
15 | "NAME" : "progress",
16 | "MIN" : 0,
17 | "DEFAULT" : 0
18 | }
19 | ],
20 | "CATEGORIES" : [
21 | "Wipe"
22 | ],
23 | "CREDIT": "Automatically converted from https://www.github.com/gl-transitions/gl-transitions/tree/master/wipeRight.glsl",
24 | "DESCRIPTION": "",
25 | "ISFVSN" : "2"
26 | }
27 | */
28 |
29 |
30 |
31 | vec4 getFromColor(vec2 inUV) {
32 | return IMG_NORM_PIXEL(startImage, inUV);
33 | }
34 | vec4 getToColor(vec2 inUV) {
35 | return IMG_NORM_PIXEL(endImage, inUV);
36 | }
37 |
38 |
39 |
40 | // Author: Jake Nelson
41 | // License: MIT
42 |
43 | vec4 transition(vec2 uv) {
44 | vec2 p=uv.xy/vec2(1.0).xy;
45 | vec4 a=getFromColor(p);
46 | vec4 b=getToColor(p);
47 | return mix(a, b, step(0.0+p.x,progress));
48 | }
49 |
50 |
51 |
52 | void main() {
53 | gl_FragColor = transition(isf_FragNormCoord.xy);
54 | }
--------------------------------------------------------------------------------
/src/application/sample-modules/isf/Wipe Up.fs:
--------------------------------------------------------------------------------
1 | /*
2 | {
3 | "CATEGORIES" : [
4 | "Wipe"
5 | ],
6 | "CREDIT": "Automatically converted from https://www.github.com/gl-transitions/gl-transitions/tree/master/wipeUp.glsl",
7 | "DESCRIPTION": "",
8 | "ISFVSN" : "2",
9 | "INPUTS" : [
10 | {
11 | "TYPE" : "image",
12 | "NAME" : "startImage"
13 | },
14 | {
15 | "NAME" : "endImage",
16 | "TYPE" : "image"
17 | },
18 | {
19 | "MIN" : 0,
20 | "TYPE" : "float",
21 | "NAME" : "progress",
22 | "MAX" : 1,
23 | "DEFAULT" : 0
24 | }
25 | ]
26 | }
27 | */
28 |
29 |
30 |
31 | vec4 getFromColor(vec2 inUV) {
32 | return IMG_NORM_PIXEL(startImage, inUV);
33 | }
34 | vec4 getToColor(vec2 inUV) {
35 | return IMG_NORM_PIXEL(endImage, inUV);
36 | }
37 |
38 |
39 |
40 | // Author: Jake Nelson
41 | // License: MIT
42 |
43 | vec4 transition(vec2 uv) {
44 | vec2 p=uv.xy/vec2(1.0).xy;
45 | vec4 a=getFromColor(p);
46 | vec4 b=getToColor(p);
47 | return mix(a, b, step(0.0+p.y,progress));
48 | }
49 |
50 |
51 |
52 | void main() {
53 | gl_FragColor = transition(isf_FragNormCoord.xy);
54 | }
--------------------------------------------------------------------------------
/src/application/sample-modules/isf/Zoom.fs:
--------------------------------------------------------------------------------
1 | /*{
2 | "CATEGORIES": [
3 | "Geometry Adjustment"
4 | ],
5 | "CREDIT": "by VIDVOX",
6 | "INPUTS": [
7 | {
8 | "NAME": "inputImage",
9 | "TYPE": "image"
10 | },
11 | {
12 | "DEFAULT": 1,
13 | "MAX": 10,
14 | "MIN": 0.01,
15 | "NAME": "level",
16 | "TYPE": "float"
17 | },
18 | {
19 | "DEFAULT": [
20 | 0,
21 | 0
22 | ],
23 | "MAX": [
24 | 1,
25 | 1
26 | ],
27 | "MIN": [
28 | 0,
29 | 0
30 | ],
31 | "NAME": "center",
32 | "TYPE": "point2D"
33 | }
34 | ],
35 | "ISFVSN": "2"
36 | }
37 | */
38 |
39 | void main() {
40 | vec2 loc;
41 | vec2 modifiedCenter;
42 |
43 | loc = isf_FragNormCoord;
44 | modifiedCenter = center;
45 | loc.x = (loc.x - modifiedCenter.x)*(1.0/level) + modifiedCenter.x;
46 | loc.y = (loc.y - modifiedCenter.y)*(1.0/level) + modifiedCenter.y;
47 | if ((loc.x < 0.0)||(loc.y < 0.0)||(loc.x > 1.0)||(loc.y > 1.0)) {
48 | gl_FragColor = vec4(0.0);
49 | }
50 | else {
51 | gl_FragColor = IMG_NORM_PIXEL(inputImage,loc);
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/src/application/sample-modules/isf/block-color.fs:
--------------------------------------------------------------------------------
1 | /*
2 | {
3 | "CATEGORIES" : [
4 | "color"
5 | ],
6 | "DESCRIPTION" : "Solid color block",
7 | "ISFVSN" : "2",
8 | "INPUTS" : [
9 | {
10 | "NAME" : "r",
11 | "TYPE" : "float",
12 | "MAX" : 1,
13 | "DEFAULT" : 0,
14 | "MIN" : 0,
15 | "LABEL" : "Red"
16 | },
17 | {
18 | "NAME" : "g",
19 | "TYPE" : "float",
20 | "MAX" : 1,
21 | "DEFAULT" : 0,
22 | "LABEL" : "Green",
23 | "MIN" : 0
24 | },
25 | {
26 | "NAME" : "b",
27 | "TYPE" : "float",
28 | "MAX" : 1,
29 | "DEFAULT" : 0,
30 | "LABEL" : "Blue",
31 | "MIN" : 0
32 | },
33 | {
34 | "NAME" : "a",
35 | "TYPE" : "float",
36 | "MAX" : 1,
37 | "DEFAULT" : 0,
38 | "LABEL" : "Alpha",
39 | "MIN" : 0
40 | }
41 | ],
42 | "VSN" : "1.0",
43 | "CREDIT" : "2xAA"
44 | }
45 | */
46 |
47 | void main() {
48 | gl_FragColor = vec4(r, g, b, a);
49 | }
--------------------------------------------------------------------------------
/src/application/sample-modules/isf/feedback.fs:
--------------------------------------------------------------------------------
1 | /*{
2 | "DESCRIPTION": "RGB GLitchMod",
3 | "CREDIT": "by dantheman",
4 | "CATEGORIES": [
5 | "Distortion Effect"
6 | ],
7 | "INPUTS": [
8 | {
9 | "NAME": "inputImage",
10 | "TYPE": "image"
11 | },
12 | {
13 | "NAME": "offset",
14 | "TYPE": "float",
15 | "MIN":0.0,
16 | "MAX":0.5,
17 | "DEFAULT": 0.25
18 | },
19 | {
20 | "NAME": "offset_right",
21 | "TYPE": "float",
22 | "MIN":0.0,
23 | "MAX":0.1,
24 | "DEFAULT": 0
25 | },
26 | {
27 | "NAME": "mix_var",
28 | "TYPE":"float",
29 | "MIN":0.0,
30 | "MAX":1.0,
31 | "DEFAULT": 1.0
32 | }
33 | ],
34 | "PERSISTENT_BUFFERS": [
35 | "one"
36 | ],
37 | "PASSES": [
38 | {
39 | "TARGET":"one",
40 | "WIDTH": "$WIDTH",
41 | "HEIGHT": "$HEIGHT",
42 | "DESCRIPTION": "buffer"
43 | }
44 | ]
45 |
46 | }*/
47 |
48 |
49 | void main() {
50 |
51 | vec2 pos = isf_FragNormCoord;
52 | vec4 old = IMG_NORM_PIXEL(one, pos);
53 | vec4 new = IMG_NORM_PIXEL(inputImage, pos);
54 |
55 | gl_FragColor = (new + old * mix_var * 10.0) / (1.0 + mix_var * 10.0);
56 | }
57 |
--------------------------------------------------------------------------------
/src/application/sample-modules/isf/film-grain.fs:
--------------------------------------------------------------------------------
1 | /*
2 | {
3 | "CATEGORIES" : [
4 | "XXX"
5 | ],
6 | "DESCRIPTION" : "",
7 | "INPUTS" : [
8 | {
9 | "NAME": "inputImage",
10 | "TYPE": "image"
11 | },
12 | {
13 | "NAME" : "strength",
14 | "TYPE" : "float",
15 | "DEFAULT" : 16.0,
16 | "MIN": 0.0,
17 | "MAX": 50.0,
18 | "LABEL" : "Strength"
19 | },
20 | {
21 | "NAME": "secondaryOperation",
22 | "TYPE": "long",
23 | "VALUES": [
24 | 0,
25 | 1
26 | ],
27 | "LABELS": [
28 | "One",
29 | "Two"
30 | ],
31 | "DEFAULT": 0
32 | }
33 | ],
34 | "CREDIT" : ""
35 | }
36 | */
37 |
38 | void main() {
39 | vec2 uv = gl_FragCoord.xy;
40 | vec4 color = IMG_THIS_PIXEL(inputImage);
41 |
42 | float x = (uv.x + 4.0) * (uv.y + 4.0) * TIME;
43 | vec4 grain = vec4(mod((mod(x, 13.0) + 1.0) * (mod(x, 123.0) + 1.0), 0.01)-0.005) * strength;
44 |
45 | // if(abs(uv.x - 0.5) < 0.002)
46 | // color = vec4(0.0);
47 |
48 | if(secondaryOperation == 0) {
49 | grain = 1.0 - grain;
50 | gl_FragColor = color * grain;
51 | } else {
52 | gl_FragColor = color + grain;
53 | }
54 | }
--------------------------------------------------------------------------------
/src/application/sample-modules/isf/plasma.fs:
--------------------------------------------------------------------------------
1 | /*
2 | {
3 | "CATEGORIES" : [
4 | "XXX"
5 | ],
6 | "DESCRIPTION" : "",
7 | "INPUTS" : [
8 | {
9 | "NAME" : "timeScale",
10 | "TYPE" : "float",
11 | "DEFAULT" : 0.18,
12 | "MIN": 0.001,
13 | "MAX": 2.0,
14 | "LABEL" : "Time Scale"
15 | },
16 | {
17 | "NAME": "uScale",
18 | "TYPE": "point2D",
19 | "LABEL" : "Scale",
20 | "DEFAULT": [
21 | 10.5,
22 | 10.5
23 | ],
24 | "MAX": 50.0,
25 | "MIN": 0.001
26 | }
27 | ],
28 | "CREDIT" : ""
29 | }
30 | */
31 |
32 | const float PI = 3.1415926535897932384626433832795;
33 |
34 | void main() {
35 | float time = TIME / timeScale;
36 | vec2 scale = vec2(RENDERSIZE.x / uScale.x, RENDERSIZE.y / uScale.y);
37 | float v = 0.0;
38 | vec2 c = isf_FragNormCoord * scale - scale/2.0;
39 | v += sin((c.x+time));
40 | v += sin((c.y+time)/2.0);
41 | v += sin((c.x+c.y+time)/2.0);
42 | c += scale/2.0 * vec2(sin(time/3.0), cos(time/2.0));
43 | v += sin(sqrt(c.x*c.x+c.y*c.y+1.0)+time);
44 | v = v/2.0;
45 | vec3 col = vec3(1, sin(PI*v), cos(PI*v));
46 | gl_FragColor = vec4(col*.5 + .5, 1);
47 | }
--------------------------------------------------------------------------------
/src/application/sample-modules/isf/rgbglitchmod.fs:
--------------------------------------------------------------------------------
1 | /*{
2 | "DESCRIPTION": "RGB GLitchMod",
3 | "CREDIT": "by dantheman",
4 | "CATEGORIES": [
5 | "Distortion Effect"
6 | ],
7 | "INPUTS": [
8 | {
9 | "NAME": "inputImage",
10 | "TYPE": "image"
11 | }
12 | ],
13 | "PERSISTENT_BUFFERS": [
14 | "one"
15 | ],
16 | "PASSES": [
17 | {
18 | "TARGET":"one",
19 | "WIDTH": "$WIDTH",
20 | "HEIGHT": "$HEIGHT",
21 | "DESCRIPTION": "buffer"
22 | }
23 | ]
24 |
25 | }*/
26 |
27 |
28 |
29 | void main()
30 | {
31 | vec2 uv = isf_FragNormCoord.xy;
32 | vec2 texCoord = uv;
33 | // if this is the first pass, i'm going to read the position from the "lastPosition" image, and write a new position based on this and the hold variables
34 |
35 | vec4 srcPixel = IMG_NORM_PIXEL(inputImage,texCoord);
36 | vec4 newPixel = IMG_NORM_PIXEL(one, texCoord);
37 | srcPixel = mod((srcPixel+newPixel), vec4(1.0));
38 | srcPixel *= 0.50;
39 |
40 | // i'm only using the X, which is the last render time we reset
41 | gl_FragColor = vec4(srcPixel.rgb, 1.0);
42 | }
43 |
--------------------------------------------------------------------------------
/src/application/sample-modules/isf/scale.fs:
--------------------------------------------------------------------------------
1 | /*
2 | {
3 | "CATEGORIES" : [
4 | "transform"
5 | ],
6 | "DESCRIPTION" : "Scale",
7 | "ISFVSN" : "2",
8 | "INPUTS" : [
9 | {
10 | "NAME" : "inputImage",
11 | "TYPE" : "image"
12 | },
13 | {
14 | "NAME" : "scale",
15 | "TYPE" : "float",
16 | "MAX" : 2.0,
17 | "DEFAULT" : 0.0,
18 | "MIN" : -2.0
19 | }
20 | ],
21 | "CREDIT" : "2xAA"
22 | }
23 | */
24 |
25 | void main() {
26 | vec2 uv = gl_FragCoord.xy / RENDERSIZE.xy;
27 |
28 | uv -= 0.5;
29 |
30 | uv.x = uv.x / (1.0 + scale);
31 | uv.y = uv.y / (1.0 + scale);
32 |
33 | uv += 0.5;
34 |
35 | gl_FragColor = IMG_NORM_PIXEL(inputImage, uv);
36 | }
37 |
--------------------------------------------------------------------------------
/src/application/sample-modules/isf/st_lsfGDH.fs:
--------------------------------------------------------------------------------
1 | /*
2 | {
3 | "CATEGORIES" : [
4 | "zoomer"
5 | ],
6 | "DESCRIPTION" : "simple rotozoomer",
7 | "INPUTS" : [
8 | {
9 | "NAME" : "inputImage",
10 | "TYPE" : "image"
11 | }
12 | ],
13 | "ISFVSN" : "2",
14 | "CREDIT" : "triggerHLM "
15 | }
16 | */
17 |
18 | float pi = 3.14159265;
19 |
20 | vec4 mainImage( vec2 fragCoord ) {
21 | float time= TIME * 0.2;
22 |
23 | vec2 position = vec2(640.0/2.0+640.0/2.0*sin(time*2.0), 360.0/2.0+360.0/2.0*cos(time*3.0));
24 | vec2 position2 = vec2(640.0/2.0+640.0/2.0*sin((time+2000.0)*2.0), 360.0/2.0+360.0/2.0*cos((time+2000.0)*3.0));
25 |
26 |
27 | vec2 offset = vec2(640.0/2.0, 360.0/2.0) ;
28 | vec2 offset2 = vec2(6.0*sin(time*1.1), 3.0*cos(time*1.1));
29 |
30 | vec2 oldPos = (fragCoord.xy);
31 |
32 | float angle = time*2.0;
33 |
34 | vec2 newPos = vec2(oldPos.x *cos(angle) - oldPos.y *sin(angle),
35 | oldPos.y *cos(angle) + oldPos.x *sin(angle));
36 |
37 |
38 | newPos = (newPos)*(0.0044+0.004*sin(time*3.0))-offset2;
39 | vec2 temp = newPos;
40 | newPos.x = temp.x + 0.4*sin(temp.y*2.0+time*8.0);
41 | newPos.y = (-temp.y + 0.4*sin(temp.x*2.0+time*8.0));
42 | vec4 final = IMG_NORM_PIXEL(inputImage, newPos);
43 | return final;
44 | }
45 |
46 | void main(void) {
47 | gl_FragColor = mainImage(gl_FragCoord.xy);
48 | }
--------------------------------------------------------------------------------
/src/application/sample-modules/isf/tapestryfract.fs:
--------------------------------------------------------------------------------
1 | /*{
2 | "CREDIT": "by echophons",
3 | "DESCRIPTION": "",
4 | "CATEGORIES": [ "generator"
5 | ],
6 | "INPUTS": [
7 | {
8 | "NAME": "h",
9 | "TYPE": "float",
10 | "DEFAULT": 0.5,
11 | "MIN": 0.0,
12 | "MAX": 1.0
13 | },
14 | {
15 | "NAME": "j",
16 | "TYPE": "float",
17 | "DEFAULT": 0.5,
18 | "MIN": 0.0,
19 | "MAX": 1.0
20 | }
21 | ]
22 | }*/
23 |
24 | // edit of http://glslsandbox.com/e#18752.0
25 | uniform vec2 mouse;
26 |
27 | vec3 iResolution = vec3(RENDERSIZE, 1.0);
28 | float iGlobalTime = TIME;
29 |
30 | float gTime = iGlobalTime*0.5;
31 |
32 | void main( void )
33 | {
34 | float f = 3.0;
35 | float g = 3.0;
36 | vec2 res = iResolution.xy;
37 | vec2 mou = mouse.xy;
38 |
39 | //if (mouse.x < 0.5)
40 | //{
41 | mou.x = sin(gTime * .3)*sin(gTime * .17) * 1. + sin(gTime * .3);
42 | mou.y = (1.0-cos(gTime * .632))*sin(gTime * .131)*1.0+cos(gTime * .3);
43 | mou = (mou+1.0) * res;
44 | //}
45 | vec2 z = ((-res+2.0 * gl_FragCoord.xy) / res.y);
46 | vec2 p = ((-res+2.0+mou) / res.y) * j;
47 | for( int i = 0; i < 25; i++)
48 | {
49 | float d = dot(z,z);
50 | z = (vec2( z.x, -z.y ) / d) + p * h;
51 | z.x = 1.0-abs(z.x);
52 | f = max( f-d, (dot(z-p,z-p) ));
53 | g = min( g*d, sin(dot(z+p,z+p))+1.0);
54 | }
55 | f = abs(-log(f) / 3.5);
56 | g = abs(-log(g) / 8.0);
57 | gl_FragColor = vec4(min(vec3(g, g*f, f), 1.0),1.0);
58 | }
59 |
--------------------------------------------------------------------------------
/src/application/sample-modules/isf/v002 Dilate.vs:
--------------------------------------------------------------------------------
1 |
2 | #if __VERSION__ <= 120
3 | varying vec2 texcoord0;
4 | varying vec2 texcoord1;
5 | varying vec2 texcoord2;
6 | varying vec2 texcoord3;
7 | varying vec2 texcoord4;
8 | varying vec2 texcoord5;
9 | varying vec2 texcoord6;
10 | varying vec2 texcoord7;
11 | #else
12 | out vec2 texcoord0;
13 | out vec2 texcoord1;
14 | out vec2 texcoord2;
15 | out vec2 texcoord3;
16 | out vec2 texcoord4;
17 | out vec2 texcoord5;
18 | out vec2 texcoord6;
19 | out vec2 texcoord7;
20 | #endif
21 |
22 | void main()
23 | {
24 | isf_vertShaderInit();
25 | // perform standard transform on vertex
26 | //gl_Position = ftransform();
27 |
28 | // transform texcoord
29 | vec2 texcoord = vec2(isf_FragNormCoord[0],isf_FragNormCoord[1]);
30 |
31 | // get sample positions
32 | texcoord0 = texcoord + vec2(-amount, -amount);
33 | texcoord1 = texcoord + vec2( 0, -amount);
34 | texcoord2 = texcoord + vec2( amount, -amount);
35 | texcoord3 = texcoord + vec2(-amount, 0);
36 | texcoord4 = texcoord + vec2( amount, 0);
37 | texcoord5 = texcoord + vec2(-amount, amount);
38 | texcoord6 = texcoord + vec2( 0, amount);
39 | texcoord7 = texcoord + vec2( amount, amount);
40 | }
41 |
--------------------------------------------------------------------------------
/src/application/sample-modules/isf/v002 Erode.vs:
--------------------------------------------------------------------------------
1 |
2 | #if __VERSION__ <= 120
3 | varying vec2 texcoord0;
4 | varying vec2 texcoord1;
5 | varying vec2 texcoord2;
6 | varying vec2 texcoord3;
7 | varying vec2 texcoord4;
8 | varying vec2 texcoord5;
9 | varying vec2 texcoord6;
10 | varying vec2 texcoord7;
11 | #else
12 | out vec2 texcoord0;
13 | out vec2 texcoord1;
14 | out vec2 texcoord2;
15 | out vec2 texcoord3;
16 | out vec2 texcoord4;
17 | out vec2 texcoord5;
18 | out vec2 texcoord6;
19 | out vec2 texcoord7;
20 | #endif
21 |
22 | void main()
23 | {
24 | isf_vertShaderInit();
25 | // perform standard transform on vertex
26 | //gl_Position = ftransform();
27 |
28 | // transform texcoord
29 | vec2 texcoord = vec2(isf_FragNormCoord[0],isf_FragNormCoord[1]);
30 |
31 | // get sample positions
32 | texcoord0 = texcoord + vec2(-amount, -amount);
33 | texcoord1 = texcoord + vec2( 0, -amount);
34 | texcoord2 = texcoord + vec2( amount, -amount);
35 | texcoord3 = texcoord + vec2(-amount, 0);
36 | texcoord4 = texcoord + vec2( amount, 0);
37 | texcoord5 = texcoord + vec2(-amount, amount);
38 | texcoord6 = texcoord + vec2( 0, amount);
39 | texcoord7 = texcoord + vec2( amount, amount);
40 | }
41 |
--------------------------------------------------------------------------------
/src/application/sample-modules/isf/v002 Light Leak.vs:
--------------------------------------------------------------------------------
1 |
2 | #if __VERSION__ <= 120
3 | varying mat2 rotmat;
4 | #else
5 | out mat2 rotmat;
6 | #endif
7 |
8 | void main()
9 | {
10 | isf_vertShaderInit();
11 |
12 | // setup basic rotation matrix here
13 | float theta = radians(angle);
14 |
15 | // dont need to compute this more than once..
16 | float c = cos(theta);
17 | float s = sin(theta);
18 |
19 | // rotation matrix
20 | rotmat = mat2(c,s,-s,c);
21 | }
--------------------------------------------------------------------------------
/src/application/sample-modules/isf/v002-CRT-Displacement.fs:
--------------------------------------------------------------------------------
1 | /*{
2 | "CATEGORIES": [
3 | "Distortion Effect",
4 | "Retro",
5 | "v002"
6 | ],
7 | "CREDIT": "by vade",
8 | "DESCRIPTION": "CRT Displacement, emulating the look of curved CRT Displays",
9 | "INPUTS": [
10 | {
11 | "NAME": "inputImage",
12 | "TYPE": "image"
13 | },
14 | {
15 | "DEFAULT": 0.5,
16 | "MAX": 1,
17 | "MIN": 0,
18 | "NAME": "Amount",
19 | "TYPE": "float"
20 | }
21 | ],
22 | "ISFVSN": "2"
23 | }
24 | */
25 |
26 | void main (void)
27 | {
28 | vec2 t1, t2;
29 | vec2 ctr = RENDERSIZE / 2.0;
30 |
31 | t1 = gl_FragCoord.xy;
32 |
33 | float a = -0.0;
34 | float b = -.1 * Amount;
35 | float c = -.0;
36 | float d = 1.0 - 1.1 * ( a + b + c );
37 | float r1, r2;
38 | float unit = length(ctr) / 2.0;
39 |
40 | r1 = distance( t1, ctr )/unit;
41 | r2 = r1 *( r1*( r1 * (a*r1 + b) + c) + d );
42 | float sc = step( 0.0 , r1) * ( r1/(r2 + .000001)) + (1.0 - step( 0.0 , r1));
43 |
44 | t2 = ctr + ( t1 - ctr) * sc;
45 |
46 | gl_FragColor = IMG_PIXEL(inputImage, t2);
47 |
48 | if ((t2.x < 0.0)
49 | ||(t2.y < 0.0)
50 | ||(t2.x > RENDERSIZE.x)
51 | ||(t2.y > RENDERSIZE.y))
52 | {
53 | gl_FragColor = vec4(0.0);
54 | }
55 | }
--------------------------------------------------------------------------------
/src/application/sample-modules/isf/v002-CRT-Mask-RGB-Shadow.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vcync/modV/c606793d54d00f5a56e1121f3593f9585b20623f/src/application/sample-modules/isf/v002-CRT-Mask-RGB-Shadow.png
--------------------------------------------------------------------------------
/src/application/sample-modules/isf/v002-CRT-Mask-RGB-Staggered.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vcync/modV/c606793d54d00f5a56e1121f3593f9585b20623f/src/application/sample-modules/isf/v002-CRT-Mask-RGB-Staggered.png
--------------------------------------------------------------------------------
/src/application/sample-modules/isf/v002-CRT-Mask-RGB-Straight.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vcync/modV/c606793d54d00f5a56e1121f3593f9585b20623f/src/application/sample-modules/isf/v002-CRT-Mask-RGB-Straight.png
--------------------------------------------------------------------------------
/src/application/sample-modules/isf/v002-CRT-Mask-Scanline-Staggered.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vcync/modV/c606793d54d00f5a56e1121f3593f9585b20623f/src/application/sample-modules/isf/v002-CRT-Mask-Scanline-Staggered.png
--------------------------------------------------------------------------------
/src/application/setup-beat-detektor.js:
--------------------------------------------------------------------------------
1 | import BeatDetektor from "../../lib/BeatDetektor";
2 |
3 | export default function() {
4 | const beatDetektor = new BeatDetektor(85, 169);
5 | const beatDetektorKick = new BeatDetektor.modules.vis.BassKick();
6 |
7 | this.updateBeatDetektor = (delta, features) => {
8 | if (!features) {
9 | return;
10 | }
11 |
12 | beatDetektor.process(delta / 1000.0, features.complexSpectrum.real);
13 | beatDetektorKick.process(beatDetektor);
14 | const kick = beatDetektorKick.isKick();
15 | const bpm = beatDetektor.win_bpm_int_lo;
16 |
17 | this.store.commit("beats/SET_KICK", { kick });
18 | if (this.store.state.beats.bpm !== bpm) {
19 | this.store.dispatch("beats/setBpm", { bpm, source: "beatdetektor" });
20 | }
21 | };
22 | }
23 |
--------------------------------------------------------------------------------
/src/application/setup-grandiose.js:
--------------------------------------------------------------------------------
1 | /* globals __dirname */
2 |
3 | import store from "./worker/store/index";
4 |
5 | let grandiose = undefined;
6 |
7 | export default function setupGrandiose() {
8 | if (grandiose === undefined) {
9 | /* eslint-disable */
10 | __dirname = `${__dirname}/node_modules/grandiose`;
11 | __dirname = __dirname.replace("app.asar", "app.asar.unpacked");
12 | /* eslint-enable */
13 |
14 | try {
15 | grandiose = require("grandiose");
16 | } catch (error) {
17 | if (error.message.includes("libndi.so")) {
18 | store.dispatch("errors/createMessage", {
19 | message:
20 | "libndi is not installed, please see \"Ubuntu/Debian\" in the modV README."
21 | });
22 | } else {
23 | console.error(error);
24 | }
25 | }
26 |
27 | // eslint-disable-next-line
28 | __dirname = __dirname.replace("/node_modules/grandiose", "");
29 | }
30 |
31 | // Make sure to set grandiose to undefined as it will be an empty object otherwise
32 | if (!grandiose.isSupportedCPU) {
33 | grandiose = undefined;
34 | }
35 |
36 | return grandiose;
37 | }
38 |
--------------------------------------------------------------------------------
/src/application/setup-tweens.js:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vcync/modV/c606793d54d00f5a56e1121f3593f9585b20623f/src/application/setup-tweens.js
--------------------------------------------------------------------------------
/src/application/use.js:
--------------------------------------------------------------------------------
1 | import installPlugin from "./install-plugin";
2 |
3 | export default function use(type, extension) {
4 | switch (type) {
5 | case "plugin": {
6 | installPlugin(extension);
7 | break;
8 | }
9 |
10 | case "control": {
11 | this.store.dispatch("controls/addControl", extension);
12 | break;
13 | }
14 |
15 | // case 'renderer': {
16 | // store.commit('renderers/addRenderer', extension)
17 | // break
18 | // }
19 |
20 | default: {
21 | installPlugin(type || extension);
22 | break;
23 | }
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/src/application/utils/apply-expression.js:
--------------------------------------------------------------------------------
1 | import get from "lodash.get";
2 | import store from "../worker/store";
3 |
4 | export function applyExpression({ value, inputId }) {
5 | const expressionAssignment = store.getters["expressions/getByInputId"](
6 | inputId
7 | );
8 |
9 | const input = store.state.inputs.inputs[inputId];
10 |
11 | let dataOut = value;
12 |
13 | if (expressionAssignment) {
14 | const scope = {
15 | value: dataOut,
16 | time: Date.now(),
17 | inputValue: get(store.state, input.getLocation)
18 | };
19 |
20 | dataOut = expressionAssignment.func.evaluate(scope);
21 | }
22 |
23 | return dataOut;
24 | }
25 |
--------------------------------------------------------------------------------
/src/application/utils/conform-file-path.js:
--------------------------------------------------------------------------------
1 | import path from "path";
2 |
3 | export const conformFilePath = (filePath = "") =>
4 | filePath
5 | .split(process.platform === "win32" ? path.posix.sep : path.win32.sep)
6 | .join(path.sep);
7 |
--------------------------------------------------------------------------------
/src/application/utils/get-next-name.js:
--------------------------------------------------------------------------------
1 | function nameTemplate(name, count) {
2 | if (count < 1) {
3 | return name;
4 | }
5 |
6 | return `${name} (${count})`;
7 | }
8 |
9 | export default function findBestName(nameIn, names) {
10 | return new Promise(resolve => {
11 | if (names.indexOf(nameIn) < 0) {
12 | resolve(nameIn);
13 | }
14 |
15 | const nameRe = new RegExp(`\\b^${nameIn}\\s\\((\\d+?)\\)$`, "g");
16 |
17 | let count = 1;
18 | let newName = nameTemplate(nameIn, count);
19 |
20 | const filteredNames = names.filter(arrName => arrName.match(nameRe));
21 |
22 | while (filteredNames.indexOf(newName) > -1) {
23 | count += 1;
24 | newName = nameTemplate(nameIn, count);
25 | }
26 |
27 | resolve(newName);
28 | });
29 | }
30 |
--------------------------------------------------------------------------------
/src/application/utils/lerp.js:
--------------------------------------------------------------------------------
1 | export default function lerp(start, end, amt) {
2 | return (1 - amt) * start + amt * end;
3 | }
4 |
--------------------------------------------------------------------------------
/src/application/utils/map.js:
--------------------------------------------------------------------------------
1 | export default function map(value, low1, high1, low2, high2) {
2 | // eslint-disable-next-line
3 | return low2 + (high2 - low2) * (value - low1) / (high1 - low1);
4 | }
5 |
--------------------------------------------------------------------------------
/src/application/worker/audio-features.js:
--------------------------------------------------------------------------------
1 | import lerp from "../utils/lerp";
2 |
3 | const MAX_SMOOTHING = 1;
4 | const SMOOTHING_STEP = 0.001;
5 |
6 | let features = {};
7 | const smoothedFeatures = {};
8 |
9 | function getFeatures() {
10 | return features;
11 | }
12 |
13 | function getFeature(key) {
14 | return features[key];
15 | }
16 |
17 | function setFeatures(newFeatures) {
18 | features = newFeatures;
19 | }
20 |
21 | function addSmoothingId(id) {
22 | smoothedFeatures[id] = 0;
23 | }
24 |
25 | function removeSmoothingId(id) {
26 | delete smoothedFeatures[id];
27 | }
28 |
29 | function getSmoothedFeature(feature, id, smoothingValue) {
30 | smoothedFeatures[id] = lerp(
31 | smoothedFeatures[id] || 0,
32 | features[feature],
33 | smoothingValue
34 | );
35 |
36 | return smoothedFeatures[id];
37 | }
38 |
39 | export {
40 | getFeature,
41 | getFeatures,
42 | setFeatures,
43 | addSmoothingId,
44 | removeSmoothingId,
45 | getSmoothedFeature,
46 | MAX_SMOOTHING,
47 | SMOOTHING_STEP
48 | };
49 |
--------------------------------------------------------------------------------
/src/application/worker/frame-counter.js:
--------------------------------------------------------------------------------
1 | /*
2 | * In relation to: https://github.com/vcync/modv-3/issues/129
3 | *
4 | * The frame-counter will not overflow in a normal session of modV.
5 | *
6 | * We can determine the maximum safe integer in JavaScript with `Number.MAX_SAFE_INTEGER`.
7 | * In V8 at the time of writing this is 9007199254740991.
8 | *
9 | * That's nine quadrillion, seven trillion, one hundred and ninety-nine billion,
10 | * two hundred and fifty-four million, seven hundred and forty thousand and nine hundred
11 | * and ninety-one.
12 | *
13 | * We use the following formula to calculate when, in days, this will reach the max safe int:
14 | * max_int / (frames_per_second * (seconds_in_a_minute * minutes_in_an_hour) / hours_in_a_day)
15 | *
16 | * At an average screen refresh of 60fps:
17 | * Number.MAX_SAFE_INTEGER / (60 * (60 * 60) / 24)
18 | * = 1000799917193.4435
19 | *
20 | * In years, this is:
21 | * 1000799917193.4435 / 365
22 | * = 2741917581.3519
23 | *
24 | * Of course this doesn't account for leap years, but we're pretty safe.
25 | * Unless you have a time-machine and somewhere safe to hide a computer running modV…
26 | */
27 |
28 | let _frames = 0;
29 |
30 | function tick() {
31 | return _frames++;
32 | }
33 |
34 | function frames() {
35 | return _frames;
36 | }
37 |
38 | export { tick, frames };
39 |
--------------------------------------------------------------------------------
/src/application/worker/store/index.js:
--------------------------------------------------------------------------------
1 | import Vue from "vue";
2 | import Vuex from "vuex";
3 | import createPersistedState from "vuex-persistedstate";
4 |
5 | const requireModule = require.context("./modules/", false, /\.js$/);
6 | const modules = {};
7 |
8 | const moduleKeys = requireModule.keys();
9 | for (let i = 0, len = moduleKeys.length; i < len; i++) {
10 | const moduleName = moduleKeys[i];
11 |
12 | modules[moduleName.replace(/(\.\/|\.js)/g, "")] = requireModule(
13 | moduleName
14 | ).default;
15 | }
16 |
17 | Vue.use(Vuex);
18 |
19 | const plugins = [];
20 |
21 | // createPersistedState doesn't work in the worker store, so don't run it there.
22 | // That's okay as the worker doesn't need to know about mediaStream.
23 | // If we want other persisted items that the worker needs to know about
24 | // we'll need to implement something more complex to commit via postMessage.
25 | if (self.document !== undefined) {
26 | const dataState = createPersistedState({
27 | paths: ["mediaStream"]
28 | });
29 |
30 | plugins.push(dataState);
31 | }
32 |
33 | export default new Vuex.Store({
34 | modules,
35 | plugins,
36 | strict: false
37 | });
38 |
--------------------------------------------------------------------------------
/src/application/worker/store/modules/beats.js:
--------------------------------------------------------------------------------
1 | import Vue from "vue";
2 |
3 | const state = {
4 | bpm: 0,
5 | bpmSource: "beatdetektor",
6 | kick: false,
7 | bpmSources: ["beatdetektor", "midi", "tap"]
8 | };
9 |
10 | const actions = {
11 | setBpm({ commit, state }, { bpm, source }) {
12 | if (!source) {
13 | throw new Error("Setting the BPM requires a source to be given");
14 | }
15 |
16 | if (source === state.bpmSource) {
17 | commit("SET_BPM", { bpm });
18 | }
19 | }
20 | };
21 |
22 | const mutations = {
23 | SET_BPM(state, { bpm }) {
24 | state.bpm = bpm;
25 | },
26 |
27 | SET_KICK(state, { kick }) {
28 | state.kick = kick;
29 | },
30 |
31 | ADD_BPM_SOURCE(state, { source }) {
32 | state.bpmSources.push(source);
33 | },
34 |
35 | SET_BPM_SOURCE(state, { source }) {
36 | Vue.set(state, "bpmSource", source);
37 | }
38 | };
39 |
40 | export default {
41 | namespaced: true,
42 | state,
43 | mutations,
44 | actions
45 | };
46 |
--------------------------------------------------------------------------------
/src/application/worker/store/modules/errors.js:
--------------------------------------------------------------------------------
1 | import Vue from "vue";
2 | import { v4 as uuidv4 } from "uuid";
3 |
4 | const state = {
5 | messages: {}
6 | };
7 |
8 | const actions = {
9 | createMessage({ commit }, { message }) {
10 | if (!message) {
11 | throw new Error("No message given");
12 | }
13 |
14 | commit("CREATE_MESSAGE", { message, id: uuidv4() });
15 | },
16 |
17 | deleteMessage({ commit }, { id }) {
18 | commit("REMOVE_MESSAGE", { id });
19 | }
20 | };
21 |
22 | const mutations = {
23 | CREATE_MESSAGE(state, { message, id }) {
24 | Vue.set(state.messages, id, message);
25 | },
26 |
27 | REMOVE_MESSAGE(state, { id }) {
28 | Vue.delete(state.messages, id);
29 | }
30 | };
31 |
32 | export default {
33 | namespaced: true,
34 | state,
35 | mutations,
36 | actions
37 | };
38 |
--------------------------------------------------------------------------------
/src/application/worker/store/modules/fonts.js:
--------------------------------------------------------------------------------
1 | const state = {
2 | defaultFonts: ["serif", "sans-serif", "cursive", "monospace"],
3 | localFonts: []
4 | };
5 |
6 | const getters = {
7 | fonts: state => [
8 | ...state.defaultFonts,
9 | ...state.localFonts
10 | .filter(
11 | (value, index, self) =>
12 | index === self.findIndex(t => t.family === value.family)
13 | )
14 | .map(font => font.family)
15 | .sort((a, b) => a.localeCompare(b))
16 | ]
17 | };
18 |
19 | const mutations = {
20 | SET_LOCAL_FONTS(state, fonts = []) {
21 | state.localFonts = fonts;
22 | }
23 | };
24 |
25 | export default {
26 | namespaced: true,
27 | state,
28 | getters,
29 | mutations
30 | };
31 |
--------------------------------------------------------------------------------
/src/application/worker/store/modules/fps.js:
--------------------------------------------------------------------------------
1 | const state = {
2 | fps: 60
3 | };
4 |
5 | const getters = {
6 | interval: state => 1000 / state.fps
7 | };
8 |
9 | const actions = {
10 | setFPS({ commit }, { fps }) {
11 | if (!fps) {
12 | throw new Error("No FPS given");
13 | }
14 |
15 | commit("SET_FPS", { fps });
16 | }
17 | };
18 |
19 | const mutations = {
20 | SET_FPS(state, { fps }) {
21 | state.fps = fps;
22 | }
23 | };
24 |
25 | export default {
26 | namespaced: true,
27 | state,
28 | getters,
29 | mutations,
30 | actions
31 | };
32 |
--------------------------------------------------------------------------------
/src/application/worker/store/modules/images.js:
--------------------------------------------------------------------------------
1 | import streamToBlob from "stream-to-blob";
2 | import fs from "fs";
3 | import path from "path";
4 |
5 | import Vue from "vue";
6 | import { v4 as uuidv4 } from "uuid";
7 |
8 | import store from "../";
9 | import { conformFilePath } from "../../../utils/conform-file-path";
10 |
11 | const state = {};
12 |
13 | const getters = {
14 | image: state => id => state[id]
15 | };
16 |
17 | const actions = {
18 | async createImageFromPath({ commit }, { path: filePath }) {
19 | let stream;
20 | let joinedFilePath;
21 |
22 | try {
23 | joinedFilePath = path.join(
24 | store.state.media.path,
25 | conformFilePath(filePath)
26 | );
27 | } catch (e) {
28 | console.log(e);
29 | }
30 |
31 | try {
32 | stream = fs.createReadStream(joinedFilePath);
33 | } catch (error) {
34 | throw error;
35 | }
36 |
37 | if (!stream) {
38 | return {};
39 | }
40 |
41 | const blob = await streamToBlob(stream);
42 | const imageBitmap = await createImageBitmap(blob);
43 |
44 | const id = uuidv4();
45 | commit("SAVE_IMAGE", { id, imageBitmap });
46 | return { id };
47 | }
48 | };
49 |
50 | const mutations = {
51 | SAVE_IMAGE(state, { id, imageBitmap }) {
52 | Vue.set(state, id, imageBitmap);
53 | }
54 | };
55 |
56 | export default {
57 | namespaced: true,
58 | state,
59 | getters,
60 | actions,
61 | mutations
62 | };
63 |
--------------------------------------------------------------------------------
/src/application/worker/store/modules/mediaStream.js:
--------------------------------------------------------------------------------
1 | const state = {
2 | audio: [],
3 | video: [],
4 |
5 | currentAudioSource: null,
6 | currentVideoSource: null
7 | };
8 |
9 | const mutations = {
10 | ADD_AUDIO_SOURCE(state, { source }) {
11 | state.audio.push(source);
12 | },
13 |
14 | ADD_VIDEO_SOURCE(state, { source }) {
15 | state.video.push(source);
16 | },
17 |
18 | CLEAR_AUDIO_SOURCES(state) {
19 | state.audio = [];
20 | },
21 |
22 | CLEAR_VIDEO_SOURCES(state) {
23 | state.video = [];
24 | },
25 |
26 | SET_CURRENT_AUDIO_SOURCE(state, { audioId }) {
27 | state.currentAudioSource = audioId;
28 | },
29 |
30 | SET_CURRENT_VIDEO_SOURCE(state, { videoId }) {
31 | state.currentVideoSource = videoId;
32 | }
33 | };
34 |
35 | export default {
36 | namespaced: true,
37 | state,
38 | mutations
39 | };
40 |
--------------------------------------------------------------------------------
/src/application/worker/store/modules/metrics.js:
--------------------------------------------------------------------------------
1 | const state = {
2 | fps: 0
3 | };
4 |
5 | const mutations = {
6 | SET_FPS_MEASURE(state, fps) {
7 | state.fps = fps;
8 | }
9 | };
10 |
11 | export default {
12 | namespaced: true,
13 | state,
14 | mutations
15 | };
16 |
--------------------------------------------------------------------------------
/src/application/worker/store/modules/projects.js:
--------------------------------------------------------------------------------
1 | const state = {
2 | currentProject: "default"
3 | };
4 |
5 | const actions = {
6 | setCurrentProject({ commit }, projectName) {
7 | commit("SET_CURRENT_PROJECT", projectName);
8 | }
9 | };
10 |
11 | const mutations = {
12 | SET_CURRENT_PROJECT(state, currentProject) {
13 | state.currentProject = currentProject;
14 | }
15 | };
16 |
17 | export default {
18 | namespaced: true,
19 | state,
20 | actions,
21 | mutations
22 | };
23 |
--------------------------------------------------------------------------------
/src/application/worker/store/modules/renderers.js:
--------------------------------------------------------------------------------
1 | const state = {};
2 |
3 | const getters = {
4 | renderersWithTick: state => {
5 | const keys = Object.keys(state);
6 | return keys
7 | .map(key => state[key].tick && state[key])
8 | .filter(renderer => renderer);
9 | }
10 | };
11 |
12 | const mutations = {
13 | ADD_RENDERER(state, renderer) {
14 | state[renderer.name] = renderer;
15 | },
16 | REMOVE_RENDERER(state, name) {
17 | delete state[name];
18 | }
19 | };
20 |
21 | export default {
22 | namespaced: true,
23 | getters,
24 | state,
25 | mutations
26 | };
27 |
--------------------------------------------------------------------------------
/src/application/worker/store/modules/size.js:
--------------------------------------------------------------------------------
1 | import store from "../index";
2 |
3 | const state = {
4 | width: 0,
5 | height: 0,
6 | dpr: 1
7 | };
8 |
9 | const getters = {
10 | area: state => state.width * state.height
11 | };
12 |
13 | const actions = {
14 | async setSize({ commit }, { width, height, dpr }) {
15 | await store.dispatch("outputs/resize", { width, height });
16 |
17 | const modulesValues = Object.values(store.state.modules.active);
18 | const modulesLength = modulesValues.length;
19 | for (let i = 0; i < modulesLength; ++i) {
20 | const module = modulesValues[i];
21 | store.dispatch("modules/resize", { moduleId: module.$id, width, height });
22 | }
23 |
24 | const renderersValues = Object.values(store.state.renderers);
25 | const renderersLength = renderersValues.length;
26 | for (let i = 0; i < renderersLength; ++i) {
27 | const renderer = renderersValues[i];
28 | if (renderer.resize) {
29 | renderer.resize({ width, height });
30 | }
31 | }
32 |
33 | commit("SET_SIZE", { width, height, dpr });
34 | }
35 | };
36 |
37 | const mutations = {
38 | SET_SIZE(state, { width, height, dpr = 1 }) {
39 | state.width = width;
40 | state.height = height;
41 | state.dpr = dpr;
42 | }
43 | };
44 |
45 | export default {
46 | namespaced: true,
47 | state,
48 | getters,
49 | actions,
50 | mutations
51 | };
52 |
--------------------------------------------------------------------------------
/src/application/worker/store/modules/windows.js:
--------------------------------------------------------------------------------
1 | import Vue from "vue";
2 |
3 | import { v4 as uuidv4 } from "uuid";
4 |
5 | const state = {};
6 |
7 | const actions = {
8 | createWindow({ commit }) {
9 | const win = {
10 | width: 300,
11 | height: 300,
12 | title: "modV Output",
13 | pixelRatio: 1,
14 | x: 0,
15 | y: 0,
16 | fullscreen: false,
17 | backgroundColor: "#000",
18 | outputId: ""
19 | };
20 |
21 | win.id = uuidv4();
22 | commit("ADD_WINDOW", win);
23 |
24 | return win.id;
25 | }
26 | };
27 |
28 | const mutations = {
29 | ADD_WINDOW(state, window) {
30 | Vue.set(state, window.id, window);
31 | },
32 |
33 | UPDATE_WINDOW(state, { id, key, value }) {
34 | Vue.set(state[id], key, value);
35 | }
36 |
37 | // REMOVE_WINDOW(state, id) {}
38 | };
39 |
40 | export default {
41 | namespaced: true,
42 | state,
43 | // getters,
44 | actions,
45 | mutations
46 | };
47 |
--------------------------------------------------------------------------------
/src/assets/fonts/Inter-italic.var.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vcync/modV/c606793d54d00f5a56e1121f3593f9585b20623f/src/assets/fonts/Inter-italic.var.woff2
--------------------------------------------------------------------------------
/src/assets/fonts/Inter-roman.var.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vcync/modV/c606793d54d00f5a56e1121f3593f9585b20623f/src/assets/fonts/Inter-roman.var.woff2
--------------------------------------------------------------------------------
/src/assets/fonts/iaw-mono-Bold.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vcync/modV/c606793d54d00f5a56e1121f3593f9585b20623f/src/assets/fonts/iaw-mono-Bold.woff
--------------------------------------------------------------------------------
/src/assets/fonts/iaw-mono-Bold.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vcync/modV/c606793d54d00f5a56e1121f3593f9585b20623f/src/assets/fonts/iaw-mono-Bold.woff2
--------------------------------------------------------------------------------
/src/assets/fonts/iaw-mono-BoldItalic.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vcync/modV/c606793d54d00f5a56e1121f3593f9585b20623f/src/assets/fonts/iaw-mono-BoldItalic.woff
--------------------------------------------------------------------------------
/src/assets/fonts/iaw-mono-BoldItalic.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vcync/modV/c606793d54d00f5a56e1121f3593f9585b20623f/src/assets/fonts/iaw-mono-BoldItalic.woff2
--------------------------------------------------------------------------------
/src/assets/fonts/iaw-mono-Italic.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vcync/modV/c606793d54d00f5a56e1121f3593f9585b20623f/src/assets/fonts/iaw-mono-Italic.woff
--------------------------------------------------------------------------------
/src/assets/fonts/iaw-mono-Italic.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vcync/modV/c606793d54d00f5a56e1121f3593f9585b20623f/src/assets/fonts/iaw-mono-Italic.woff2
--------------------------------------------------------------------------------
/src/assets/fonts/iaw-mono-Regular.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vcync/modV/c606793d54d00f5a56e1121f3593f9585b20623f/src/assets/fonts/iaw-mono-Regular.woff
--------------------------------------------------------------------------------
/src/assets/fonts/iaw-mono-Regular.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vcync/modV/c606793d54d00f5a56e1121f3593f9585b20623f/src/assets/fonts/iaw-mono-Regular.woff2
--------------------------------------------------------------------------------
/src/assets/graphics/Arrow-vertical.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/src/assets/graphics/Arrow.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/src/background/background-constants.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | APP_SCHEME: "app"
3 | };
4 |
--------------------------------------------------------------------------------
/src/background/media-manager.js:
--------------------------------------------------------------------------------
1 | import MediaManager from "../media-manager";
2 | import { updateMenu } from "./menu-bar";
3 | import { setProjectNames } from "./projects";
4 |
5 | let mediaManager;
6 |
7 | export function getMediaManager() {
8 | if (!mediaManager) {
9 | mediaManager = new MediaManager({
10 | update(message) {
11 | window.webContents.send("media-manager-update", message);
12 |
13 | setProjectNames(mediaManager.$store.getters["media/projects"]);
14 | updateMenu();
15 | },
16 |
17 | pathChanged(message) {
18 | window.webContents.send("media-manager-path-changed", message);
19 | }
20 | });
21 | }
22 |
23 | return mediaManager;
24 | }
25 |
--------------------------------------------------------------------------------
/src/background/open-file.js:
--------------------------------------------------------------------------------
1 | import { app } from "electron";
2 | import { windows } from "./windows";
3 |
4 | export function openFile(filePath) {
5 | app.addRecentDocument(filePath);
6 |
7 | windows["mainWindow"].webContents.send("open-preset", filePath);
8 | }
9 |
--------------------------------------------------------------------------------
/src/background/projects.js:
--------------------------------------------------------------------------------
1 | import { windows } from "./windows";
2 |
3 | let projectNames = ["default"];
4 | let currentProject = "default";
5 |
6 | export function setCurrentProject(name) {
7 | currentProject = name;
8 | windows["mainWindow"].webContents.send("set-current-project", name);
9 | }
10 |
11 | export function setProjectNames(names = ["default"]) {
12 | projectNames = names;
13 | }
14 |
15 | export { projectNames, currentProject };
16 |
--------------------------------------------------------------------------------
/src/components/ABSwap.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
17 |
--------------------------------------------------------------------------------
/src/components/CollapsibleRow.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
45 |
46 |
60 |
--------------------------------------------------------------------------------
/src/components/Controls/CollapsibleControl.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
37 |
38 |
52 |
--------------------------------------------------------------------------------
/src/components/ElectronLink.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
23 |
24 |
30 |
--------------------------------------------------------------------------------
/src/components/ErrorWatcher.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
16 |
17 |
18 |
43 |
--------------------------------------------------------------------------------
/src/components/InfoView.vue:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 | {{ focused && focused.title }}
8 | {{ focused && focused.body }}
9 |
10 |
11 |
12 |
13 |
31 |
32 |
43 |
--------------------------------------------------------------------------------
/src/components/StatusBar/BPMDisplay.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 | {{ Math.round($modV.store.state.beats.bpm) }} BPM
4 | ({{ $modV.store.state.beats.bpmSource }})
5 |
6 |
7 |
8 |
19 |
20 |
29 |
--------------------------------------------------------------------------------
/src/components/StatusBar/FPSDisplay.vue:
--------------------------------------------------------------------------------
1 |
2 |
13 | {{ Math.round($modV.store.state.metrics.fps) }} FPS
14 |
15 |
16 |
17 |
32 |
--------------------------------------------------------------------------------
/src/components/StatusBar/SizeDisplay.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 | {{ $modV.store.state.size.width }} × {{ $modV.store.state.size.height }}
4 |
5 |
6 |
--------------------------------------------------------------------------------
/src/components/StatusBar/StatusBarItem.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
34 |
--------------------------------------------------------------------------------
/src/components/TooltipDisplay.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
17 |
--------------------------------------------------------------------------------
/src/components/dialogs/FrameRateDialog.vue:
--------------------------------------------------------------------------------
1 |
2 |
16 |
17 |
18 |
47 |
--------------------------------------------------------------------------------
/src/components/directives/ContextMenu.js:
--------------------------------------------------------------------------------
1 | import { Menu } from "@electron/remote";
2 | import Vue from "vue";
3 |
4 | function openContextMenu(e, template) {
5 | const { clientX: x, clientY: y } = e;
6 |
7 | if (template) {
8 | const menu = Menu.buildFromTemplate(template);
9 | menu.popup({ x, y });
10 | }
11 | }
12 |
13 | Vue.directive("contextMenu", {
14 | inserted(el, { value: template }) {
15 | el.addEventListener("contextmenu", async e =>
16 | openContextMenu(e, await template())
17 | );
18 | },
19 |
20 | unbind() {
21 | // el.removeEventListener("click", e => openContextMenu(e, template));
22 | }
23 | });
24 |
--------------------------------------------------------------------------------
/src/components/directives/InfoView.js:
--------------------------------------------------------------------------------
1 | import Vue from "vue";
2 |
3 | const INFO_VIEW_ID_VAR = "$iVID";
4 |
5 | function mouseover(id, $store) {
6 | return () => {
7 | $store.dispatch("infoView/setFocused", {
8 | id
9 | });
10 | };
11 | }
12 |
13 | Vue.directive("infoView", {
14 | // When the bound element is inserted into the DOM...
15 | async inserted(el, binding, vnode) {
16 | const { value } = binding;
17 | const {
18 | context: { $store }
19 | } = vnode;
20 |
21 | const id = await $store.dispatch("infoView/addDictionaryItem", {
22 | id: value.id,
23 | title: value.title,
24 | body: value.body
25 | });
26 |
27 | vnode[INFO_VIEW_ID_VAR] = id;
28 |
29 | el.addEventListener("mouseover", mouseover(id, $store), true);
30 | },
31 |
32 | async unbind(el, binding, vnode) {
33 | const {
34 | context: { $store }
35 | } = vnode;
36 |
37 | await $store.dispatch("infoView/removeDictionaryItem", {
38 | id: vnode[INFO_VIEW_ID_VAR]
39 | });
40 | }
41 | });
42 |
--------------------------------------------------------------------------------
/src/components/directives/Search.js:
--------------------------------------------------------------------------------
1 | import Vue from "vue";
2 |
3 | const SEARCH_ID_VAR = "$searchId";
4 |
5 | Vue.directive("searchTerms", {
6 | // When the bound element is inserted into the DOM...
7 | async inserted(el, binding, vnode) {
8 | const { value } = binding;
9 | const {
10 | context: { $store }
11 | } = vnode;
12 |
13 | const id = await $store.dispatch("search/addTerms", {
14 | ...value
15 | });
16 |
17 | vnode[SEARCH_ID_VAR] = id;
18 | el.setAttribute("data-searchId", id);
19 | },
20 |
21 | async unbind(el, binding, vnode) {
22 | const {
23 | context: { $store }
24 | } = vnode;
25 |
26 | await $store.dispatch("search/removeId", {
27 | id: vnode[SEARCH_ID_VAR]
28 | });
29 | }
30 | });
31 |
--------------------------------------------------------------------------------
/src/components/inputs/Button.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
39 |
--------------------------------------------------------------------------------
/src/components/inputs/Number.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
10 |
11 |
12 |
32 |
33 |
45 |
--------------------------------------------------------------------------------
/src/components/inputs/Select.vue:
--------------------------------------------------------------------------------
1 |
2 |
11 |
12 |
13 |
29 |
30 |
65 |
--------------------------------------------------------------------------------
/src/components/inputs/TextInput.vue:
--------------------------------------------------------------------------------
1 |
2 |
9 |
10 |
11 |
31 |
32 |
44 |
--------------------------------------------------------------------------------
/src/components/inputs/Textarea.vue:
--------------------------------------------------------------------------------
1 |
2 |
9 |
10 |
11 |
22 |
23 |
36 |
--------------------------------------------------------------------------------
/src/components/inputs/index.js:
--------------------------------------------------------------------------------
1 | import Vue from "vue";
2 | import Button from "./Button.vue";
3 | import Checkbox from "./Checkbox.vue";
4 | import Number from "./Number.vue";
5 | import Range from "./Range.vue";
6 | import Select from "./Select.vue";
7 | import Textarea from "./Textarea.vue";
8 | import TextInput from "./TextInput.vue";
9 |
10 | Vue.component("Button", Button);
11 | Vue.component("Checkbox", Checkbox);
12 | Vue.component("Number", Number);
13 | Vue.component("Range", Range);
14 | Vue.component("Select", Select);
15 | Vue.component("Textarea", Textarea);
16 | Vue.component("TextInput", TextInput);
17 |
--------------------------------------------------------------------------------
/src/components/mixins/has-input-link.js:
--------------------------------------------------------------------------------
1 | export default {
2 | computed: {
3 | hasLink() {
4 | return this.$modV.store.state.inputs.inputLinks[this.inputId];
5 | }
6 | }
7 | };
8 |
--------------------------------------------------------------------------------
/src/components/mixins/input-is-focused.js:
--------------------------------------------------------------------------------
1 | export default {
2 | computed: {
3 | inputIsFocused() {
4 | return this.$modV.store.state.inputs.focusedInput.id === this.inputId;
5 | }
6 | }
7 | };
8 |
--------------------------------------------------------------------------------
/src/css/iaw.css:
--------------------------------------------------------------------------------
1 | /* mono */
2 | @font-face {
3 | font-family: 'iaw-mono';
4 | font-style: normal;
5 | font-weight: 400;
6 | src: url("../assets/fonts/iaw-mono-Regular.woff2") format("woff2"),
7 | url("../assets/fonts/iaw-mono-Regular.woff") format("woff");
8 | }
9 | @font-face {
10 | font-family: 'iaw-mono';
11 | font-style: italic;
12 | font-weight: 400;
13 | src: url("../assets/fonts/iaw-mono-Italic.woff2") format("woff2"),
14 | url("../assets/fonts/iaw-mono-Italic.woff") format("woff");
15 | }
16 | @font-face {
17 | font-family: 'iaw-mono';
18 | font-style: normal;
19 | font-weight: 700;
20 | src: url("../assets/fonts/iaw-mono-Bold.woff2") format("woff2"),
21 | url("../assets/fonts/iaw-mono-Bold.woff") format("woff");
22 | }
23 | @font-face {
24 | font-family: 'iaw-mono';
25 | font-style: italic;
26 | font-weight: 700;
27 | src: url("../assets/fonts/iaw-mono-BoldItalic.woff2") format("woff2"),
28 | url("../assets/fonts/iaw-mono-BoldItalic.woff") format("woff");
29 | }
30 |
--------------------------------------------------------------------------------
/src/css/inter.css:
--------------------------------------------------------------------------------
1 |
2 | /*
3 | Font families defined by this CSS:
4 |
5 | - "Inter" static "traditional" fonts for older web browsers
6 | - "Inter var" single-axis variable fonts for all modern browsers
7 | - "Inter var experimental" multi-axis variable fonts for modern web browsers
8 |
9 | Use like this in your CSS:
10 |
11 | :root { font-family: 'Inter', sans-serif; }
12 | @supports (font-variation-settings: normal) {
13 | :root { font-family: 'Inter var', sans-serif; }
14 | }
15 |
16 | ------------------------- static ------------------------- */
17 | /* ----------------------- variable ----------------------- */
18 |
19 | @font-face {
20 | font-family: 'Inter var';
21 | font-style: normal;
22 | font-weight: 100 900;
23 | font-display: swap;
24 | src: url('../assets/fonts/Inter-roman.var.woff2?v=3.19') format('woff2');
25 | font-named-instance: 'Regular';
26 | }
27 |
28 | @font-face {
29 | font-family: 'Inter var';
30 | font-style: italic;
31 | font-weight: 100 900;
32 | font-display: swap;
33 | src: url('../assets/fonts/Inter-italic.var.woff2?v=3.19') format('woff2');
34 | font-named-instance: 'Italic';
35 | }
36 |
--------------------------------------------------------------------------------
/src/media-manager/add-read-handler.js:
--------------------------------------------------------------------------------
1 | import { log, logError } from "./log";
2 | import store from "./store";
3 |
4 | const fs = require("fs");
5 | const path = require("path");
6 |
7 | export default async function addReadHandler({ readHandler }) {
8 | let ok = true;
9 |
10 | if (typeof readHandler.init === "function") {
11 | try {
12 | ok = await readHandler.init(
13 | {
14 | binaryPath: this.binaryPath,
15 |
16 | join: (...args) => path.join.call(args),
17 |
18 | exists: file =>
19 | new Promise((resolve, reject) => {
20 | fs.access(file, fs.constants.F_OK, err => {
21 | if (err) {
22 | resolve();
23 | } else {
24 | reject();
25 | }
26 | });
27 | })
28 | },
29 | {
30 | log
31 | }
32 | );
33 | } catch (e) {
34 | ok = false;
35 | logError(e);
36 | }
37 | }
38 |
39 | if (ok) {
40 | await store.dispatch("readHandlers/addHandler", { readHandler });
41 | log(`Added ReadHandler for ${readHandler.folder}`);
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/src/media-manager/add-save-handler.js:
--------------------------------------------------------------------------------
1 | import { log } from "./log";
2 | import store from "./store";
3 |
4 | export default async function addReadHandler({ saveHandler }) {
5 | await store.dispatch("saveHandlers/addHandler", { saveHandler });
6 | log(`Added SaveHandler for ${saveHandler.folder}`);
7 | }
8 |
--------------------------------------------------------------------------------
/src/media-manager/log.js:
--------------------------------------------------------------------------------
1 | /* eslint-disable no-console */
2 | const consoleLog = console.log;
3 | const consoleError = console.error;
4 |
5 | function log(...argsIn) {
6 | const delta = new Date();
7 | const args = [];
8 | args.push(`[${delta.toLocaleTimeString()}]:`);
9 |
10 | for (let i = 0; i < argsIn.length; i += 1) {
11 | args.push(argsIn[i]);
12 | }
13 | consoleLog.apply(console, args);
14 | }
15 |
16 | function logError(...argsIn) {
17 | const delta = new Date();
18 | const args = [];
19 | args.push(`[${delta.toLocaleTimeString()}]:`);
20 |
21 | for (let i = 0; i < argsIn.length; i += 1) {
22 | args.push(argsIn[i]);
23 | }
24 | consoleError.apply(console, args);
25 | }
26 |
27 | export { log, logError };
28 |
--------------------------------------------------------------------------------
/src/media-manager/media-manager-utils/stream-to-string.js:
--------------------------------------------------------------------------------
1 | // https://stackoverflow.com/a/49428486
2 | module.exports = function streamToString(stream) {
3 | const chunks = [];
4 | return new Promise((resolve, reject) => {
5 | stream.on("data", chunk => chunks.push(Buffer.from(chunk)));
6 | stream.on("error", err => reject(err));
7 | stream.on("end", () => resolve(Buffer.concat(chunks).toString("utf8")));
8 | });
9 | };
10 |
--------------------------------------------------------------------------------
/src/media-manager/read-handlers/palette.js:
--------------------------------------------------------------------------------
1 | export default {
2 | folder: "palette",
3 | identifier: "🎨",
4 |
5 | fileTypes: ["json"],
6 |
7 | process() {
8 | return new Promise(resolve => {
9 | resolve(true);
10 | });
11 | }
12 | };
13 |
--------------------------------------------------------------------------------
/src/media-manager/read-handlers/preset.js:
--------------------------------------------------------------------------------
1 | export default {
2 | folder: "preset",
3 | identifier: "📜",
4 |
5 | fileTypes: ["json"],
6 |
7 | process() {
8 | return new Promise(resolve => {
9 | resolve(true);
10 | });
11 | }
12 | };
13 |
--------------------------------------------------------------------------------
/src/media-manager/save-handlers/preset.js:
--------------------------------------------------------------------------------
1 | export default {
2 | folder: "preset",
3 | identifier: "📜",
4 |
5 | fileTypes: ["json"],
6 |
7 | process() {
8 | return new Promise(resolve => {
9 | resolve(true);
10 | });
11 | }
12 | };
13 |
--------------------------------------------------------------------------------
/src/media-manager/store/index.js:
--------------------------------------------------------------------------------
1 | import Vue from "vue";
2 | import Vuex from "vuex";
3 |
4 | import readHandlers from "./modules/read-handlers";
5 | import saveHandlers from "./modules/save-handlers";
6 | import media from "./modules/media";
7 | import plugins from "./modules/plugins";
8 |
9 | Vue.use(Vuex);
10 |
11 | const modules = {
12 | readHandlers,
13 | saveHandlers,
14 | media,
15 | plugins
16 | };
17 |
18 | const store = new Vuex.Store({
19 | strict: false,
20 | modules,
21 |
22 | actions: {
23 | resetAll({ commit }) {
24 | const moduleKeys = Object.keys(modules);
25 | for (let i = 0, len = moduleKeys.length; i < len; i++) {
26 | const moduleKey = moduleKeys[i];
27 |
28 | commit(`${moduleKey}/RESET_STATE`);
29 | }
30 | }
31 | }
32 | });
33 |
34 | export default store;
35 |
--------------------------------------------------------------------------------
/src/media-manager/store/modules/plugins.js:
--------------------------------------------------------------------------------
1 | import Vue from "vue";
2 |
3 | function initialState() {
4 | /**
5 | * Holds Plugins
6 | *
7 | * @type {Object}
8 | */
9 | return {
10 | plugins: {},
11 | pluginData: {}
12 | };
13 | }
14 |
15 | const getters = {};
16 |
17 | const actions = {
18 | addMedia({ commit }, { project, folder, item }) {
19 | return new Promise(resolve => {
20 | commit("ADD", { project, folder, item });
21 | resolve();
22 | });
23 | }
24 | };
25 |
26 | const mutations = {
27 | ADD(state, { project, folder, item }) {
28 | if (!state[project]) {
29 | Vue.set(state, project, {});
30 | }
31 |
32 | if (!state[project][folder]) {
33 | Vue.set(state[project], folder, []);
34 | }
35 |
36 | state[project][folder].push(item);
37 | },
38 |
39 | RESET_STATE(state) {
40 | const s = initialState();
41 | const stateKeys = Object.keys(s);
42 | for (let i = 0, len = stateKeys.length; i < len; i++) {
43 | const key = stateKeys[i];
44 |
45 | state[key] = s[key];
46 | }
47 | }
48 | };
49 |
50 | export default {
51 | namespaced: true,
52 | state: initialState,
53 | getters,
54 | actions,
55 | mutations
56 | };
57 |
--------------------------------------------------------------------------------
/src/menus/context/activeModuleControlContextMenu.js:
--------------------------------------------------------------------------------
1 | import modV from "../../application/index";
2 | import getPropDefault from "../../application/utils/get-prop-default";
3 |
4 | export const ActiveModuleControlContextMenu = async ({
5 | moduleId,
6 | propName,
7 | title
8 | }) => {
9 | const activeModule = modV.store.state.modules.active[moduleId];
10 | const prop = activeModule.$props[propName];
11 | const defaultPropValue = await getPropDefault(activeModule, propName, prop);
12 |
13 | if (typeof defaultPropValue === "object") {
14 | return undefined;
15 | }
16 |
17 | return [
18 | {
19 | label: title,
20 | enabled: false
21 | },
22 | {
23 | type: "separator"
24 | },
25 | {
26 | label: `Reset to "${defaultPropValue}"`,
27 | async click() {
28 | modV.store.dispatch("modules/updateProp", {
29 | moduleId,
30 | prop: propName,
31 | data: defaultPropValue
32 | });
33 | }
34 | }
35 | ];
36 | };
37 |
--------------------------------------------------------------------------------
/src/menus/context/bpmContextMenu.js:
--------------------------------------------------------------------------------
1 | import store from "../../application/worker/store";
2 |
3 | export const BPMContextMenu = () => {
4 | const currentSource = store.state.beats.bpmSource;
5 |
6 | return store.state.beats.bpmSources.map(source => ({
7 | label: source,
8 | checked: source === currentSource,
9 | type: "radio",
10 | click() {
11 | store.commit("beats/SET_BPM_SOURCE", { source });
12 | }
13 | }));
14 | };
15 |
--------------------------------------------------------------------------------
/src/menus/context/galleryItemContextMenu.js:
--------------------------------------------------------------------------------
1 | import modV from "../../application/index";
2 | import constants from "../../application/constants";
3 |
4 | export const GalleryItemContextMenu = ({ moduleName }) => [
5 | {
6 | label: moduleName,
7 | enabled: false
8 | },
9 | {
10 | type: "separator"
11 | },
12 | {
13 | label: "Add to Group",
14 | submenu: modV.store.state.groups.groups
15 | .filter(group => group.name !== constants.GALLERY_GROUP_NAME)
16 | .map(({ name: groupName, id: groupId }) => ({
17 | label: groupName,
18 | async click() {
19 | const { $id: moduleId } = await modV.store.dispatch(
20 | "modules/makeActiveModule",
21 | {
22 | moduleName
23 | }
24 | );
25 |
26 | modV.store.commit("groups/ADD_MODULE_TO_GROUP", {
27 | moduleId,
28 | groupId,
29 | position: modV.store.state.groups.groups.find(
30 | group => group.id === groupId
31 | ).modules.length
32 | });
33 | }
34 | }))
35 | }
36 | ];
37 |
--------------------------------------------------------------------------------
/src/menus/context/groupContextMenu.js:
--------------------------------------------------------------------------------
1 | import modV from "../../application/index";
2 |
3 | export const GroupContextMenu = ({ group: { name, id: groupId } }) => [
4 | {
5 | label: name,
6 | enabled: false
7 | },
8 | {
9 | type: "separator"
10 | },
11 | {
12 | label: "Delete",
13 | async click() {
14 | modV.store.dispatch("groups/removeGroup", { groupId });
15 | }
16 | }
17 | ];
18 |
--------------------------------------------------------------------------------
/src/subpages/color-picker/main.js:
--------------------------------------------------------------------------------
1 | import Vue from "vue";
2 |
3 | import App from "./App.vue";
4 |
5 | window.Vue = new Vue({
6 | render: h => h(App)
7 | }).$mount("#app");
8 |
--------------------------------------------------------------------------------
/src/subpages/splash-screen/App.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |

4 |
5 |
6 |
7 |
35 |
--------------------------------------------------------------------------------
/src/subpages/splash-screen/main.js:
--------------------------------------------------------------------------------
1 | import Vue from "vue";
2 | import App from "./App.vue";
3 |
4 | window.Vue = new Vue({
5 | render: h => h(App)
6 | }).$mount("#app");
7 |
--------------------------------------------------------------------------------
/src/ui-store/index.js:
--------------------------------------------------------------------------------
1 | import Vue from "vue";
2 | import Vuex from "vuex";
3 |
4 | const requireModule = require.context("./modules/", false, /\.js$/);
5 | const modules = {};
6 |
7 | const moduleKeys = requireModule.keys();
8 | for (let i = 0, len = moduleKeys.length; i < len; i++) {
9 | const moduleName = moduleKeys[i];
10 |
11 | modules[moduleName.replace(/(\.\/|\.js)/g, "")] = requireModule(
12 | moduleName
13 | ).default;
14 | }
15 |
16 | Vue.use(Vuex);
17 |
18 | export default new Vuex.Store({
19 | modules,
20 | strict: false
21 | });
22 |
--------------------------------------------------------------------------------
/src/ui-store/modules/dialogs.js:
--------------------------------------------------------------------------------
1 | const state = {
2 | open: []
3 | };
4 |
5 | const mutations = {
6 | ADD_OPEN(state, id) {
7 | if (Array.isArray(id)) {
8 | state.open = state.open.concat(id);
9 | } else {
10 | state.open.push(id);
11 | }
12 | },
13 |
14 | REMOVE_OPEN(state, id) {
15 | const index = state.open.indexOf(id);
16 |
17 | if (index > -1) {
18 | state.open.splice(index, 1);
19 | }
20 | }
21 | };
22 |
23 | export default {
24 | namespaced: true,
25 | state,
26 | mutations
27 | };
28 |
--------------------------------------------------------------------------------
/src/ui-store/modules/focus.js:
--------------------------------------------------------------------------------
1 | const state = {
2 | id: null,
3 | type: null
4 | };
5 |
6 | const actions = {
7 | setFocus({ commit }, args) {
8 | if (!args.id) {
9 | throw new Error("Missing ID");
10 | }
11 |
12 | if (!args.type) {
13 | throw new Error("Missing type");
14 | }
15 |
16 | commit("SET_FOCUS", args);
17 | }
18 | };
19 |
20 | const mutations = {
21 | SET_FOCUS(state, { id, type }) {
22 | state.id = id;
23 | state.type = type;
24 | }
25 | };
26 |
27 | export default {
28 | namespaced: true,
29 | state,
30 | actions,
31 | mutations
32 | };
33 |
--------------------------------------------------------------------------------
/src/ui-store/modules/infoView.js:
--------------------------------------------------------------------------------
1 | import Vue from "vue";
2 | import { v4 as uuidv4 } from "uuid";
3 |
4 | const state = {
5 | focused: "",
6 | dictionary: {}
7 | };
8 |
9 | const actions = {
10 | addDictionaryItem({ commit }, item) {
11 | let id = item.id;
12 | let singular = true;
13 |
14 | if (!state.dictionary.id === id) {
15 | return id;
16 | }
17 |
18 | if (!id) {
19 | id = uuidv4();
20 | singular = false;
21 | }
22 |
23 | commit("ADD_TO_DICTIONARY", { ...item, id, singular });
24 |
25 | return id;
26 | },
27 |
28 | removeDictionaryItem({ commit }, { id }) {
29 | if (!id) {
30 | return;
31 | }
32 |
33 | commit("REMOVE_FROM_DICTIONARY", id);
34 | },
35 |
36 | setFocused({ commit }, { id }) {
37 | commit("SET_FOCUSED", id);
38 | }
39 | };
40 |
41 | const mutations = {
42 | SET_FOCUSED(state, id) {
43 | state.focused = id;
44 | },
45 |
46 | CLEAR_FOCUSED(state) {
47 | state.focused = "";
48 | },
49 |
50 | ADD_TO_DICTIONARY(state, item) {
51 | state.dictionary[item.id] = item;
52 | },
53 |
54 | REMOVE_FROM_DICTIONARY(state, id) {
55 | if (state.dictionary[id].singular) {
56 | return;
57 | }
58 |
59 | Vue.delete(state.dictionary, id);
60 | }
61 | };
62 |
63 | export default {
64 | namespaced: true,
65 | state,
66 | actions,
67 | mutations
68 | };
69 |
--------------------------------------------------------------------------------
/src/ui-store/modules/ui-groups.js:
--------------------------------------------------------------------------------
1 | const state = {
2 | pinned: [],
3 | lastFocused: null
4 | };
5 |
6 | const mutations = {
7 | ADD_PINNED(state, id) {
8 | if (Array.isArray(id)) {
9 | state.pinned = state.pinned.concat(id);
10 | } else {
11 | state.pinned.push(id);
12 | }
13 | },
14 |
15 | REMOVE_PINNED(state, id) {
16 | const index = state.pinned.indexOf(id);
17 |
18 | if (index > -1) {
19 | state.splice(index, 1);
20 | }
21 | },
22 |
23 | SET_LAST_FOCUSED(state, id) {
24 | state.lastFocused = id;
25 | },
26 |
27 | CLEAR_LAST_FOCUSED(state) {
28 | state.lastFocused = null;
29 | }
30 | };
31 |
32 | export default {
33 | namespaced: true,
34 | state,
35 | mutations
36 | };
37 |
--------------------------------------------------------------------------------
/src/ui-store/modules/ui-modules.js:
--------------------------------------------------------------------------------
1 | import modV from "../../application/index";
2 |
3 | const state = {
4 | focused: null,
5 | pinned: []
6 | };
7 |
8 | const getters = {
9 | focusedOrPinned: state => {
10 | const arr = [...state.pinned];
11 |
12 | if (state.focused && arr.indexOf(state.focused) < 0) {
13 | arr.push(state.focused);
14 | }
15 |
16 | return arr;
17 | }
18 | };
19 |
20 | const actions = {
21 | async removeActiveModule({ commit }, { moduleId, groupId }) {
22 | commit("SET_FOCUSED", null);
23 |
24 | modV.store.commit("groups/REMOVE_MODULE_FROM_GROUP", {
25 | moduleId,
26 | groupId
27 | });
28 |
29 | return modV.store.dispatch("modules/removeActiveModule", { moduleId });
30 | }
31 | };
32 |
33 | const mutations = {
34 | SET_FOCUSED(state, id) {
35 | state.focused = id;
36 | },
37 |
38 | CLEAR_FOCUSED(state) {
39 | state.focused = null;
40 | },
41 |
42 | ADD_PINNED(state, id) {
43 | if (Array.isArray(id)) {
44 | state.pinned = state.pinned.concat(id);
45 | } else {
46 | state.pinned.push(id);
47 | }
48 | },
49 |
50 | REMOVE_PINNED(state, id) {
51 | const index = state.pinned.indexOf(id);
52 |
53 | if (index > -1) {
54 | state.pinned.splice(index, 1);
55 | }
56 | }
57 | };
58 |
59 | export default {
60 | namespaced: true,
61 | state,
62 | getters,
63 | actions,
64 | mutations
65 | };
66 |
--------------------------------------------------------------------------------
/src/util/font-family.js:
--------------------------------------------------------------------------------
1 | export default `-apple-system, BlinkMacSystemFont, sans-serif`;
2 |
--------------------------------------------------------------------------------
/tests/e2e/extentions/index.js:
--------------------------------------------------------------------------------
1 | import { toBeJSON } from "./toBeJSON.js";
2 |
3 | export default { toBeJSON };
4 |
--------------------------------------------------------------------------------
/tests/e2e/extentions/toBeJSON.js:
--------------------------------------------------------------------------------
1 | export function toBeJSON(received) {
2 | const pass = JSON.parse(received);
3 |
4 | if (pass) {
5 | return {
6 | message: () => "passed",
7 | pass: true
8 | };
9 | } else {
10 | return {
11 | message: () => "failed",
12 | pass: false
13 | };
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/tests/e2e/pageObjectModel/tabs.js:
--------------------------------------------------------------------------------
1 | import { modVApp } from ".";
2 |
3 | const tab = strings => `.lm_tab[title="${[...strings].join("")}"]`;
4 |
5 | export const tabs = {
6 | getLocators() {
7 | const { page } = modVApp;
8 | return {
9 | inputConfig: page.locator(tab`Input Config`)
10 | };
11 | }
12 | };
13 |
--------------------------------------------------------------------------------
/tests/e2e/spec/general/defaultGroupIsFocusedByDefault.spec.js:
--------------------------------------------------------------------------------
1 | import { expect, test } from "@playwright/test";
2 | import { modVApp } from "../../pageObjectModel";
3 |
4 | test("default group is focused by default", async () => {
5 | const { page } = modVApp;
6 |
7 | const firstGroupEl = page.locator(".group").first();
8 | const firstGroupElId = (await firstGroupEl.getAttribute("id")).replace(
9 | "group-",
10 | ""
11 | );
12 | const focusIndicator = firstGroupEl.locator(".group__focusIndicator");
13 |
14 | await expect(focusIndicator).toHaveCount(1);
15 |
16 | const { focus } = await modVApp.evaluateUIState();
17 |
18 | expect(focus.id).toBe(firstGroupElId);
19 | });
20 |
--------------------------------------------------------------------------------
/tests/e2e/spec/general/renderersAreRegistered.spec.js:
--------------------------------------------------------------------------------
1 | import { expect, test } from "@playwright/test";
2 | import { modVApp } from "../../pageObjectModel";
3 |
4 | test("renderers are registered", async () => {
5 | const expectedRenderers = ["2d", "isf", "shader", "three"];
6 |
7 | const { renderers } = await modVApp.evaluateMainState();
8 |
9 | expect(expectedRenderers.sort()).toEqual(Object.keys(renderers).sort());
10 | });
11 |
--------------------------------------------------------------------------------
/tests/e2e/spec/general/rendersTheMainWindow.spec.js:
--------------------------------------------------------------------------------
1 | import { expect, test } from "@playwright/test";
2 | import { modVApp } from "../../pageObjectModel";
3 |
4 | test("renders the main window", async () => {
5 | const { page } = modVApp;
6 |
7 | const title = await page.title();
8 | expect(title).toBe("Untitled");
9 | });
10 |
--------------------------------------------------------------------------------
/tests/e2e/spec/general/searchGalleryAndAddModuleToGroup.spec.js:
--------------------------------------------------------------------------------
1 | import { expect, test } from "@playwright/test";
2 | import { modVApp } from "../../pageObjectModel";
3 |
4 | test("search gallery and add module to group", async () => {
5 | const { page } = modVApp;
6 |
7 | const searchInput = await page.locator("input.gallery-search");
8 | await searchInput.click();
9 |
10 | await searchInput.fill("ball");
11 |
12 | // Double click c:nth-child(2) > .smooth-dnd-container > div > .gallery-item > canvas >> nth=0
13 | await page
14 | .locator("c:nth-child(2) > .smooth-dnd-container > div > .gallery-item ", {
15 | hasText: "Ball"
16 | })
17 | .first()
18 | .dblclick({
19 | position: {
20 | x: 98,
21 | y: 27
22 | }
23 | });
24 |
25 | await page.waitForSelector(".group__modules .active-module");
26 | const activeModules = await page.locator(".group__modules .active-module");
27 | expect(await activeModules.count()).toBe(1);
28 |
29 | const activeModule = await activeModules
30 | .first()
31 | .locator(".active-module__name");
32 | const activeModuleTitle = await activeModule.textContent();
33 | expect(activeModuleTitle.trim()).toBe("Ball");
34 | });
35 |
--------------------------------------------------------------------------------
/tests/e2e/spec/groups/alphaStateCanBeSet.spec.js:
--------------------------------------------------------------------------------
1 | import { test } from "@playwright/test";
2 | import { modVApp } from "../../pageObjectModel";
3 | import { setRangeValue } from "../../utils/setRangeValue";
4 |
5 | test("alpha state can be set", async () => {
6 | test.setTimeout(60 * 1000);
7 |
8 | const {
9 | groupIndex,
10 | groupId
11 | } = await modVApp.groups.getFirstUserGroupIdAndIndex();
12 |
13 | const { alphaRange } = modVApp.groups.getLocators(groupId);
14 |
15 | await modVApp.groups.showControls(groupId);
16 |
17 | for (let i = 0; i < 5; i += 1) {
18 | const value = Math.random();
19 | await setRangeValue(alphaRange, value);
20 |
21 | await modVApp.checkWorkerAndMainState(
22 | [[state => state, e => e.toBeCloseTo(value)]],
23 | `groups.groups[${groupIndex}].alpha`
24 | );
25 | }
26 | });
27 |
--------------------------------------------------------------------------------
/tests/e2e/spec/groups/blendModeStateCanBeSet.spec.js:
--------------------------------------------------------------------------------
1 | import { test } from "@playwright/test";
2 | import { modVApp } from "../../pageObjectModel";
3 | import compositeOperations from "../../../../src/util/composite-operations";
4 |
5 | test("blend mode state can be set", async () => {
6 | const {
7 | groupIndex,
8 | groupId
9 | } = await modVApp.groups.getFirstUserGroupIdAndIndex();
10 |
11 | const { blendModeSelect } = modVApp.groups.getLocators(groupId);
12 |
13 | await modVApp.groups.showControls(groupId);
14 |
15 | const values = [
16 | ...compositeOperations[0].children.map(({ value }) => value),
17 | ...compositeOperations[1].children.map(({ value }) => value)
18 | ];
19 |
20 | for (let i = 0; i < values.length; i += 1) {
21 | const value = values[i];
22 | await blendModeSelect.selectOption(String(value));
23 |
24 | await modVApp.checkWorkerAndMainState(
25 | [[state => state, e => e.toBe(value)]],
26 | `groups.groups[${groupIndex}].compositeOperation`
27 | );
28 | }
29 | });
30 |
--------------------------------------------------------------------------------
/tests/e2e/spec/groups/clearingStateCanBeToggledBetween0and1.spec.js:
--------------------------------------------------------------------------------
1 | import { test } from "@playwright/test";
2 | import { modVApp } from "../../pageObjectModel";
3 |
4 | test("clearing state can be toggled beween 0 and 1", async () => {
5 | const {
6 | groupIndex,
7 | groupId
8 | } = await modVApp.groups.getFirstUserGroupIdAndIndex();
9 |
10 | const { clearingCheckbox } = modVApp.groups.getLocators(groupId);
11 |
12 | await modVApp.groups.showControls(groupId);
13 |
14 | for (let i = 0; i < 2; i += 1) {
15 | await clearingCheckbox.click();
16 |
17 | await modVApp.checkWorkerAndMainState(
18 | [[state => state[groupIndex].clearing, e => e.toBe(Number(!i))]],
19 | `groups.groups`
20 | );
21 | }
22 | });
23 |
--------------------------------------------------------------------------------
/tests/e2e/spec/groups/createsADefaultGroup.spec.js:
--------------------------------------------------------------------------------
1 | import { expect, test } from "@playwright/test";
2 | import { modVApp } from "../../pageObjectModel";
3 |
4 | test("creates a default group", async () => {
5 | await expect(modVApp.groups.elements).toHaveCount(1);
6 |
7 | await modVApp.checkWorkerAndMainState(
8 | [[state => state.length, e => e.toBe(2)]],
9 | `groups.groups`
10 | );
11 | });
12 |
--------------------------------------------------------------------------------
/tests/e2e/spec/groups/groupNameCanBeChanged.spec.js:
--------------------------------------------------------------------------------
1 | import { expect, test } from "@playwright/test";
2 | import { modVApp } from "../../pageObjectModel";
3 |
4 | test("group name can be changed", async () => {
5 | const {
6 | groupIndex,
7 | groupId
8 | } = await modVApp.groups.getFirstUserGroupIdAndIndex();
9 |
10 | const { nameDisplay, nameInput } = modVApp.groups.getLocators(groupId);
11 |
12 | await nameDisplay.dblclick();
13 | await expect(nameInput).toBeFocused();
14 |
15 | const newGroupName = "Post FX";
16 |
17 | await nameInput.type(newGroupName);
18 | await nameInput.press("Enter");
19 |
20 | await expect(nameDisplay).toHaveText(newGroupName);
21 |
22 | await modVApp.checkWorkerAndMainState(
23 | [[state => state, e => e.toBe(newGroupName)]],
24 | `groups.groups[${groupIndex}].name`
25 | );
26 | });
27 |
--------------------------------------------------------------------------------
/tests/e2e/spec/groups/groupsCanBeRearranged.spec.js:
--------------------------------------------------------------------------------
1 | import { expect, test } from "@playwright/test";
2 | import { modVApp } from "../../pageObjectModel";
3 |
4 | test("groups can be rearranged", async () => {
5 | const {
6 | groups: { elements, getLocators, getUserGroups, newGroupButton },
7 | page
8 | } = modVApp;
9 |
10 | let groups = await getUserGroups();
11 |
12 | if (groups.length < 2) {
13 | await newGroupButton.click();
14 | await expect(elements).toHaveCount(2);
15 | }
16 |
17 | groups = await getUserGroups();
18 |
19 | // https://playwright.dev/docs/input#dragging-manually
20 | await getLocators(groups[0].id).name.hover();
21 | await page.mouse.down();
22 | await page.mouse.move(200, 200);
23 | await page.mouse.move(200, 200);
24 | await page.mouse.up();
25 |
26 | await modVApp.checkWorkerAndMainState(
27 | [
28 | [
29 | async state => (await getUserGroups(state))[0].id,
30 | e => e.toBe(groups[1].id)
31 | ],
32 | [
33 | async state => (await getUserGroups(state))[1].id,
34 | e => e.toBe(groups[0].id)
35 | ]
36 | ],
37 | `groups.groups`
38 | );
39 | });
40 |
--------------------------------------------------------------------------------
/tests/e2e/spec/groups/inheritAndInheritFromStateCanBeSet.spec.js:
--------------------------------------------------------------------------------
1 | import { test } from "@playwright/test";
2 | import { modVApp } from "../../pageObjectModel";
3 |
4 | test("inherit and inheritFrom state can be set", async () => {
5 | const userGroups = modVApp.groups.getUserGroups();
6 | const {
7 | groupIndex,
8 | groupId
9 | } = await modVApp.groups.getFirstUserGroupIdAndIndex();
10 |
11 | const { inheritSelect } = modVApp.groups.getLocators(groupId);
12 |
13 | await modVApp.groups.showControls(groupId);
14 |
15 | const values = [-2, -1];
16 | for (let i = 0; i < userGroups.length; i += 1) {
17 | values.push(i);
18 | }
19 |
20 | for (let i = 0; i < values.length; i += 1) {
21 | const value = values[i];
22 | await inheritSelect.selectOption(String(value));
23 |
24 | if (value === -2) {
25 | await modVApp.checkWorkerAndMainState(
26 | [[state => state[groupIndex].inherit, e => e.toBe(false)]],
27 | `groups.groups`
28 | );
29 | } else {
30 | await modVApp.checkWorkerAndMainState(
31 | [[state => state[groupIndex].inherit, e => e.toBe(true)]],
32 | `groups.groups`
33 | );
34 |
35 | await modVApp.checkWorkerAndMainState(
36 | [[state => state[groupIndex].inheritFrom, e => e.toBe(value)]],
37 | `groups.groups`
38 | );
39 | }
40 | }
41 | });
42 |
--------------------------------------------------------------------------------
/tests/e2e/spec/groups/newGroupButtonCreatesANewGroup.spec.js:
--------------------------------------------------------------------------------
1 | import { expect, test } from "@playwright/test";
2 | import { modVApp } from "../../pageObjectModel";
3 |
4 | test("new group button creates a new group", async () => {
5 | const { length: groupsLength } = (await modVApp.groups.mainState()).groups;
6 |
7 | await modVApp.groups.newGroupButton.click();
8 |
9 | await expect(modVApp.groups.elements).toHaveCount(groupsLength);
10 |
11 | await modVApp.checkWorkerAndMainState(
12 | [[state => state.length, e => e.toBe(groupsLength + 1)]],
13 | `groups.groups`
14 | );
15 | });
16 |
--------------------------------------------------------------------------------
/tests/e2e/spec/groups/pipelineStateCanBeToggledBetween0and1.spec.js:
--------------------------------------------------------------------------------
1 | import { test } from "@playwright/test";
2 | import { modVApp } from "../../pageObjectModel";
3 |
4 | test("pipeline state can be toggled beween 0 and 1", async () => {
5 | const {
6 | groupIndex,
7 | groupId
8 | } = await modVApp.groups.getFirstUserGroupIdAndIndex();
9 |
10 | const { pipelineCheckbox } = modVApp.groups.getLocators(groupId);
11 |
12 | await modVApp.groups.showControls(groupId);
13 |
14 | for (let i = 0; i < 2; i += 1) {
15 | await pipelineCheckbox.click();
16 |
17 | await modVApp.checkWorkerAndMainState(
18 | [[state => state[groupIndex].pipeline, e => e.toBe(i === 0 ? 1 : 0)]],
19 | `groups.groups`
20 | );
21 | }
22 | });
23 |
--------------------------------------------------------------------------------
/tests/e2e/spec/inputLinks/inputConfigUpdatesWhenControlIsFocused.spec.js:
--------------------------------------------------------------------------------
1 | import { expect, test } from "@playwright/test";
2 | import { modVApp } from "../../pageObjectModel";
3 |
4 | test("input config updates when control is focused", async () => {
5 | const moduleId = await modVApp.gallery.addModuleToGroupByName("Ball");
6 |
7 | const { name } = modVApp.modules.getLocators(moduleId);
8 | await name.waitFor("visible");
9 | await name.click();
10 |
11 | const inspector = modVApp.page.locator(`#module-inspector-${moduleId}`);
12 | await expect(inspector.locator(".module-inspector__title")).toHaveText(
13 | "Ball"
14 | );
15 |
16 | const { inputConfig } = modVApp.tabs.getLocators();
17 | await inputConfig.click();
18 |
19 | const inputIds = await modVApp.modules.getInputIds(moduleId);
20 |
21 | const amountControl = modVApp.page.locator(
22 | `#module-control-${inputIds.props.amount}`
23 | );
24 | await amountControl.click();
25 |
26 | await expect(modVApp.page.locator(".input-config__title")).toHaveText(
27 | "Ball: Amount"
28 | );
29 | });
30 |
--------------------------------------------------------------------------------
/tests/e2e/spec/presets/generatesAPresetWithExpectedKeys.spec.js:
--------------------------------------------------------------------------------
1 | import { expect, test } from "@playwright/test";
2 | import { modVApp } from "../../pageObjectModel";
3 |
4 | test("generates a preset with expected keys", async () => {
5 | const preset = await modVApp.generatePreset();
6 |
7 | const expectedPresetKeys = [
8 | "expressions",
9 | "groups",
10 | "inputs",
11 | "midi",
12 | "modules",
13 | "tweens"
14 | ];
15 |
16 | expect(preset).toBeDefined();
17 | expect(preset).toBeJSON();
18 | expect(expectedPresetKeys.sort()).toEqual(
19 | Object.keys(JSON.parse(preset)).sort()
20 | );
21 | });
22 |
--------------------------------------------------------------------------------
/tests/e2e/utils/setRangeValue.js:
--------------------------------------------------------------------------------
1 | export function setRangeValue(locator, value) {
2 | return locator.evaluate((e, value) => {
3 | e.value = value;
4 | e.dispatchEvent(new Event("input", { bubbles: true }));
5 | e.dispatchEvent(new Event("change", { bubbles: true }));
6 | }, value);
7 | }
8 |
--------------------------------------------------------------------------------