Skip to content

About

Lovable-branded shader studio with live composition and TypeScript, HTML and PNG export.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Repository files navigation

Pulse Studio

A browser-based WebGL shader composer with a modular effect system, real-time preview, and export to TypeScript, HTML or PNG.

The interface uses Lovable’s Camera Plain Variable font, heart mark and Pulse colour tokens. The font and mark are self-hosted; shader palettes remain independent.

Open Pulse Studio · Source

Features

  • Modular effects — Build shaders by combining self-contained effect blocks (generators, post-processing, UV transforms)
  • Real-time preview — WebGL canvas with play/pause, reset, and adjustable time scale
  • Presets — 7 searchable visual presets with palette variants: Sweep, Ripple, Bloom, Contour, Veil, Ribbon and Love
  • Generator layering — Scalar generators use contrast-based blending; RGB generators such as Flow Bands use layer opacity
  • Code viewer — Read-only CodeMirror 6 editor showing the composed GLSL output
  • Export — Generate self-contained TypeScript functions, standalone HTML files, or PNG images at a chosen size
  • Save/Load — Persist shader projects to localStorage with autosave
  • Share — Copy shareable URLs with encoded shader state

Getting Started

npm install
npm run dev

Open the local URL printed by Vite (default http://localhost:5173).

Deployment

GitHub Actions builds and deploys the site to GitHub Pages after each push to main. The workflow runs npm ci and npm run build; Pages uses the GitHub Actions source.

Production builds use /pulse-studio/ as their asset base. Development stays at /. To check the production build locally:

npm run build
npm run preview

Open http://localhost:4173/pulse-studio/.

Usage

Presets

Choose Sweep, Ripple, Bloom, Contour, Veil, Ribbon or Love from the sidebar to load a pre-configured combination of effects. Start blank clears the composition. Presets are starting points — you can add, remove, or tweak effects after loading one.

Sweep, Ripple and Bloom use Flow Bands for layered color sheets with edge softness and motion. Sweep's travelling folds change local curvature and spacing. Ripple refracts a continuous colour field through a curved glass surface; its normal, thickness and reflected light stay connected as it moves. Bloom's underside follows its upper edge with a delay. Pace or Evolve at zero preserves the rest composition.

Flow Bands also includes Contour, Veil and Ribbon. Contour opens nested colour bands around a quiet field; Veil bends a translucent vertical sheet; Ribbon turns a free strip through space. Their presets include light and dark palettes tuned in OKLCH. Rotation, Center and Scale position each form around page content. Width changes the spacing or thickness of these three new forms.

Edge Softness controls the width of folds and highlights: lower values give sharper edges. Diffuse Blur → Radius softens the full image separately. All six Flow Bands presets include blur at zero, which skips blur sampling. Nonzero blur adds 21 scene samples per pixel; edge softness adds no scene samples.

Effects

Click Add Effect to open the effect catalog. Effects are grouped by category:

  • UV Transform — Pixelate, Kaleidoscope, Polar Coordinates, Wave Warp
  • Generators — Gradient, Ramp, Flow Bands, Noise, Voronoi, Caustics, Chladni, Domain Warp, Wave, Glow Waves, Spiral, LED Bars, Dot Lattice 3D, Moiré Fields, Starfield, Terrain Field
  • Post-Processing — Brightness, Diffuse Blur, Vignette, Film Grain, CRT Scanlines, Dot Grid, ASCII, ASCII Overlay, Dither

Each effect has grouped controls with sliders and editable number values. Effects can be toggled on/off, removed, or reordered within their category. Drag a handle to reorder, or focus it and use the up/down arrow keys. A continuous drag creates one undo step, including when you pause during the drag.

Colors

Up to 12 colors can be added. Generators use these to produce the color gradient via a colorRamp() function. Edit colors with the picker or a hex value, and reorder them by dragging their handles or using the up/down arrow keys. When two or more colors are present, a gradient bar with draggable stop handles controls each color's position. The stop handles also support arrow keys. Closely spaced stops keep their precision when a new color is added.

Some presets include color palettes — named variations in the Colours section. Randomise generates gamut-mapped palettes in OKLCH before converting them to export-safe hex values.

Code Viewer

Toggle the code viewer with the Code button or Ctrl+E to inspect the composed GLSL fragment shader. The editor loads only when opened. Its output updates live as you add effects and adjust parameters. Drag the panel separator or focus it and use the arrow keys to resize the panel.

Export

The export panel generates production-ready code with all parameter values baked in:

  • TypeScript — A single function that mounts a WebGL canvas on a target <div> and returns a cleanup function
  • HTML — A standalone page for quick testing
  • PNG — The current animation frame at a width and height from 1 to 4096 pixels; changing the aspect ratio recomposes the shader at that size

Code exports retain the selected playback speed and follow prefers-reduced-motion. Pass { animate: true } as the final argument to animate explicitly, or { animate: false, time: 12 } for a still frame at 12 seconds. The optional speed value overrides the exported playback speed. Hidden pages pause animation, and the returned cleanup function releases the canvas and GPU resources. The editor starts paused when reduced motion is enabled; paused canvases redraw only after an edit, reset or resize.

Keyboard Shortcuts

Shortcut Action
Ctrl/Cmd + E Toggle code viewer
Ctrl/Cmd + B Toggle controls
Ctrl/Cmd + S Save shader
Ctrl/Cmd + Z Undo
Ctrl/Cmd + Shift + Z Redo
Space Play / Pause

Architecture

Shaders are composed at runtime from effect blocks. Each effect is a self-contained GLSL module with $param placeholders that get replaced with instance-scoped uniform names. The composer (src/composer.ts) assembles the final fragment shader by sorting effects by category and order, deduplicating shared utility functions (hash, noise and fbm in 2-D and 3-D, plus drift for slow quasi-periodic motion), and emitting the combined GLSL.

Tech Stack

  • React 19 — UI layer
  • Zustand — State management with undo/redo
  • Motion — Animations and physical drag-and-drop reorder
  • Vite — Dev server and build
  • TypeScript — Type safety
  • CodeMirror 6 — Code viewer
  • WebGL — Shader rendering

License

MIT

About

Lovable-branded shader studio with live composition and TypeScript, HTML and PNG export.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages