# Rosegold — a shader garden

Eighty original WebGL scenes made for Lars Rocha's Range Arcade, with Codex. The original forty remain, with forty additions in Impossible objects, Wandering worlds, Light instruments, and Hidden patterns. Open `index.html` through any static server or the arcade’s Netlify deployment.

## Explore

Choose a scene, palette, and seed. Thirty artwork sliders cover pace, closeness, intricacy, glow, camera, color, lighting, sculpture shape, and breathing folds. Search all eighty scenes, filter by family, or select New 40. The gallery uses saved images of actual renders and one live canvas.

“Keep this look” remembers the scene, all sliders, viewpoint, and animation time in this browser. The Kept looks filter opens those exact saved moments; “Update kept look” replaces an existing saved look after editing. “Copy this moment’s link” puts a complete version-three recipe in the URL fragment; it opens paused. Version-one and version-two favorites and links upgrade with neutral values for the new controls. Browser data is local, with no accounts or cloud service. If storage is unavailable or unreadable, exports and moment links still work. An invalid existing save is not overwritten.

## Camera and thirty sliders

Drag to orbit the 3D pieces. Shift-drag, right-drag, or choose Pan to reframe; choose Rotate to turn the image plane. Hovering alone never moves the view. Click the canvas first, then use the wheel to zoom. When focused, arrow keys move the view, Shift-arrows pan, plus/minus zoom, and R resets the camera. Front, Side, and Above presets and optional slow auto-orbit work on 3D pieces. Flat works support pan, frame rotation, and zoom; the UI disables 3D-only controls.

On touch screens, Explore view is initially off so the page scrolls normally. Enable it for one-finger movement and two-finger pinch/pan. Pin view keeps a smaller live preview visible above the sliders while scrolling on a phone. Pointer capture ends on release, cancellation, lost capture, blur, or hiding the page. Reset view restores framing without changing colors or folds. Original look restores the scene’s original recipe.

| Panel | Sliders |
| --- | --- |
| Main | Pace, closeness, intricacy, glow |
| Breathing folds | Fold blend, breathing pace, mirror count, fold scale, spin burst |
| View & camera | Yaw, pitch, frame rotation, horizontal/vertical pan, camera distance |
| Color & finish | Palette phase, color variation, saturation, contrast, vignette, shadow lift, film grain |
| Sculpture shape | Size and vertical twist |
| Lighting | Light X/Y/Z, highlight sharpness, highlight strength, fill light |

Sliders modify actual shader uniforms. Shape and lighting apply to distance-field sculptures; camera distance changes the eye position rather than changing the field of view. The original closeness control changes framing on all pieces. Zero-length lighting vectors use a stable upward fallback.

## Breathing folds and spin

The user’s Cosmic Distortion effect inspired a new global coordinate treatment: the image smoothly blends into a polar mirror fold, breathes in and out, and can turn through a quick full spin with a slower return. A cosine controls breathing; smoothstep windows control the spin burst, joining continuously at cycle boundaries. “Try breathing + spin” selects a visible preset. All eighty scenes can use it, including the original forty. Blend and spin default to zero, so old looks stay intact. Pausing freezes all of these effects, and saved/shareable recipes preserve them.

This is an artistic transformation of image coordinates. On a sculpture it changes the camera rays into a mirrored view; it is distinct from the separate geometric Sculpture twist control. It is inspired by Cosmic Distortion, not represented as an identical port of that original shader.

The 24-second tour is optional. Reduced-motion preferences start the artwork paused. Rendering stops while the canvas is offscreen or the page is hidden, and music pauses when leaving the tab. Adaptive resolution limits the work on slower devices. WebGL context loss is handled with a paused recovery. No software renderer fallback is mislabeled as a working shader.

Music is the identical user-provided `1.mp3` shared with both original labs. Audio starts only with the visitor’s action. Optional glow response measures the actual playing song through a Web Audio analyser; it does not claim to detect musical intent or train a model.

## Techniques and inspiration

The supplied **Shader Labs Pro Plus** inspired the emphasis on layered light, mirror folds, orbit traps, volumetric integration, logarithmic distortion, and smoothly changing epochs. Its Floral Thorns, Starfield, Maze Lattice, and Cosmic Distortion were studied locally. The eighty scene bodies are written separately in `shaders.js`. The accompanying Plus Pro collection also informed the large-canvas / adjustable-sidebar layout.

Shared shader primitives include conservative distance-field marching, torus and box fields, smooth unions, numerical normals, approximate ambient occlusion, cosine color palettes, procedural noise, polar folds, and bounded tone mapping. These are established graphics techniques; the scene combinations and visual mappings are this gallery’s artwork. Apparent refraction, caustics, and gravity are artistic approximations, not physical simulations. Computation is bounded; divisions and glow functions avoid singularities.

Some controls have scene-specific effects: intricacy changes marching depth and Floral Echo's symmetry; the indexed evolution helper changes surface colors and selected shape fields. The UI identifies controls that do not apply to the current scene. Legacy pointer values are retained when opening old recipes, so the original viewpoint remains exact.

## Actual pytoolz, not a training claim

Run from the arcade root, with the user's existing pytoolz environment:

```sh
/home/wiliamrocha/.spenv/bin/python -B tools/shaders/prepare.py
```

This calls the installed library, producing 256 samples in `math-data.js` and source-file hashes in `math-report.json`:

- `pt.nt.rail_walk(256)` supplies flags for 54 primes in 0–255. A safe prime check requires both p and (p−1)/2 prime: 11 safe primes in this interval.
- `pt.nt.ruler(256)` gives v₂(n+1): the number of binary trailing zeros in n+1, with n=0 at the first record.
- `pt.ntd.xor_k_index(30).unrank(n)` supplies indexed XOR addresses. The GPU texture stores their low byte; the math inspector shows the full address.
- `pt.indexrng.Index('shader-garden-v1', backend='blake2b').words('light', 256)` supplies deterministic indexed words. The texture uses their high byte.

The RGBA texture encodes prime/safe status, scaled ruler height, low XOR byte, and high indexed-word byte. It uses nearest-neighbor sampling, without interpolation between records. Visual choices such as color, height, orbit, and glow are artistic mappings of those values. The Square Atlas and Pascal Lace use mathematical identities directly in GLSL; they are not presented as new pytoolz API calls. No WSRF model was trained for this shader update. Existing arcade WSRF training remains documented in the game library.

## Exports and source

- **Save picture:** PNG of the current live render at its current adaptive resolution.
- **Download this artwork:** self-contained HTML with the selected GLSL, renderer, settings, drag/pinch/keyboard interaction, and embedded math texture. Opens paused and runs offline in a WebGL-capable browser. The audio file is not embedded.
- **Download GLSL:** JSON containing vertex and fragment GLSL, exact uniforms, and required RGBA texture bytes. It is a complete WebGL recipe, not a texture-free Shadertoy paste.
- `renderer.js`: renderer and bounded program cache.
- `settings.js`: slider definitions and strict versioned recipe migration.
- `interaction.js`: mouse, touch, wheel, and keyboard view controls.
- `page.js`: gallery, controls, local saves, music, and exports.
- `previews/`: real GPU-rendered scene thumbnails, generated with the browser verification tool.

New gallery code is covered by the arcade’s MIT license. Generated mathematical data is attributed to the existing pytoolz installation; this does not assign a license to that upstream library. The supplied labs retain their own CC0 notices. See `../SOURCE.md` and the arcade’s `NOTICE.md`.

## Verification

`node tools/test-shaders.cjs` verifies all scene definitions, pytoolz records against independent arithmetic, source receipts, links, and script syntax. `tools/test-shaders-browser.cjs` compiles and renders every scene at multiple settings, checks varied pixels and GL errors, and exercises exports, layouts, music, and failure states. `tools/test-rosegold-settings.cjs` checks version-one migration, range rejection, and scoped resets. `tools/test-rosegold-controls-browser.cjs` compares the original forty GPU renders against the preserved first-release definitions, checks that each added slider changes actual pixels, and tests mouse drag/wheel, touch drag/pinch, saved/shared views, and standalone interaction. These are browser checks, not a promise of identical output across every GPU.

## Ruler waves

Six more controls bring the total to 36 artwork sliders. Gentle tides, Carry bloom, and Light cathedral send bounded waves through all eighty scenes. `ruler(256)` supplies counting levels; `mersenne_ruler(256)` and `ruler(256, heights=True)` are recorded in the math inspector and source receipt. Waves start at zero blend, so existing looks stay neutral. See [the update notes](../../../RULER-WORLDS.md) for the mappings and checks.
