# Wallive Island Ambient Glow Shader Contract

Wallive custom glow shaders are Metal function snippets. The app supplies:

- `#include <metal_stdlib>`
- `using namespace metal`
- `GlowUniforms`
- vertex and fragment wrappers
- helper functions
- blending, render target, clipping, fallback behavior

## Required Function

```metal
float4 islandCustomGlow(float2 frag, float2 uv, constant GlowUniforms& u) {
    return float4(0.1, 0.35, 1.0, 0.4);
}
```

`frag` is pixel space in the current Metal target. `uv` is normalized `0...1`.

## Uniforms

```metal
struct GlowUniforms {
    float2 resolution;
    float time;
    float2 islandCenter;
    float2 glowSize;
    float2 islandSize;
    float cornerRadius;
    float bass;
    float mid;
    float treble;
    float beat;
    float intensity;
    float hueShift;
    float4 shaderParameters;
};
```

Parameter mapping:

- `u.shaderParameters.x`: Speed
- `u.shaderParameters.y`: Range
- `u.shaderParameters.z`: Edge
- `u.shaderParameters.w`: Hue

Music/activity fields:

- `u.bass`: low-end thickness/reach
- `u.mid`: general activity
- `u.treble`: subtle color edges and light-air variation
- `u.beat`: fast transient flashes
- `u.intensity`: resolved brightness envelope
- `u.hueShift`: runtime hue modulation

Helpers available:

- `float noise(float2 p)`
- `float3 islandHSV(float3 hsv)`
- `float sdRoundedBox(float2 p, float2 halfSize, float radius)`

## Package JSON

```json
{
  "schemaVersion": 1,
  "id": "my-shader",
  "name": "My Shader",
  "enabled": true,
  "mode": "glow",
  "presetID": "vivid",
  "parameters": {
    "intensity": 1.2,
    "hue": 0.58,
    "speed": 1.5,
    "range": 1.0,
    "bassSensitivity": 1.0,
    "beatSensitivity": 1.3,
    "edgeGlint": 1.1
  },
  "renderQuality": "balanced",
  "glowShader": "float4 islandCustomGlow(...) { ... }"
}
```

`mode`:

- Use `glow`.
- Do not use `backdrop` or `both` in packages authored by this skill.
- Do not include `backdropShader`; this skill is intentionally outside ambient glow only.

`renderQuality` is optional:

- `soft`: Wallive's default low-cost ambient scale.
- `balanced`: clearer sampling for broad atmospheric gradients; this is the recommended default for skill-authored packages.
- `sharp`: higher sampling for shaders that still look soft but need extra detail. Avoid using this for particle-like visuals.

Wallive lists installed packages from:

```text
~/Library/Application Support/Wallive/shaders/packages/*.json
```

For compatibility with older local development builds, the CLI also writes the most recently applied package to:

```text
~/Library/Application Support/Wallive/shaders/island-backdrop.json
```

Use `--wallive-root <dir>` in tests to write to another root.

## Conversion Rules

When converting a full Metal shader:

- Remove `#include <metal_stdlib>` and `using namespace metal`.
- Remove custom uniforms and map controls into `GlowUniforms`.
- Remove vertex/fragment functions and return from `islandCustomGlow`.
- Replace custom resolution/time fields with `u.resolution` and `u.time`.
- Replace custom speed/range/edge/hue fields with `u.shaderParameters`.
- Return alpha below `1.0`; transparent areas should be `0.0`.
- Remove any island-internal, object-like, or particle-like layer. Convert the idea into broad outside light.

Do not include:

- `vertex`
- `fragment`
- `[[stage_in]]`, `[[buffer(n)]]`, or other Metal attributes
- textures, samplers, device pointers, file references, includes
- custom uniforms

## Visual Quality Checklist

- The effect should read as atmosphere around the Island, not as a visible object.
- Do not author particles, sparks, lightning, rain, snow, confetti, grids, waveform bars, or sharp moving shapes.
- Keep all fills transparent except soft outside light.
- For music-reactive effects, let beat gently breathe brightness and bass thicken the glow rather than moving layout.
- Use broad alpha falloff; avoid hard cores and high-frequency detail even when choosing `balanced` or `sharp`.
