# Acrylic Paint Pour — `paint-pour@1.0.0`

Glossy acrylic pour painting that slowly swirls, with cells blooming and fine lacing. Loops perfectly.

A wet acrylic pour seen from above: bands of paint folded by a slow swirl, round cells with pale rims opening inside them, fine lacing along the edges and glossy highlights where the paint's surface catches a window light. Choose five colours (one can be metallic gold or silver), how busy the pattern is, how many cells and how glossy it looks. It loops seamlessly and stays sharp at full size.

- Kind: background; status: published; digest sha256:44efb138a01336634aceaf4cf3950666a0bb2253ac106186397fa345d4bf61e1
- Role: Full-frame background (Three.js shader): a satisfying acrylic pour pattern.
- Implementation: three; entry `src/paint-pour.js`
- Files: https://aipixelwizard.com/registry/paint-pour/1.0.0/<path> (`LICENSE`, `asset.json`, `demo.js`, `index.html`, `src/paint-pour.js`)
- Manifest JSON: https://aipixelwizard.com/api/v1/visuals/paint-pour/versions/1.0.0
- Runnable demo: https://aipixelwizard.com/registry/paint-pour/1.0.0/index.html (open over http; it imports sibling packages by relative path)
- Dependencies (exact): `three@0.185.1` (source) — Renderer and shader material.; `apw-runtime@1.0.0` (demo) — Demo harness.

## Exports
- `createPaintPour({ colors?, metallic?, scale?, flow?, bands?, cells?, cellSize?, gloss?, relief?, motion?, seed?, aspect?, lightDir? }) => { mesh, material, update(progress), dispose() }` — The paint on a 2 × 2 plane that fills the screen under OrthographicCamera(-1, 1, 1, -1); update(progress 0…1) every frame.
- `createPaintPourMaterial(options) => THREE.ShaderMaterial` — The same paint as a material for your own plane (uses its UVs); set uniforms.uPhase.value to the loop progress.

## Parameters
- `color1` (color, default "#0b2545") — Colour 1
- `color2` (color, default "#13a89e") — Colour 2
- `color3` (color, default "#f4f1ea") — Colour 3: The cells open mostly in this colour's bands.
- `color4` (color, default "#d4a24c") — Colour 4: Can be metallic (see below).
- `color5` (color, default "#1d4e89") — Colour 5
- `metallic` (boolean, default true) — Colour 4 is metallic
- `scale` (number 0.8–3, default 1.6) — Pattern size: Higher is busier.
- `flow` (number 0.4–2.6, default 1.8) — Swirl
- `bands` (number 1–5, default 2.4) — Colour bands
- `cells` (number 0–1, default 0.55) — Cells
- `cellSize` (number 3–12, default 6) — Cell density: Higher means more, smaller cells.
- `gloss` (number 0–1, default 0.8) — Gloss
- `motion` (number 0.2–1.6, default 0.5) — Movement: How far the paint swirls during one loop.
- `seed` (integer 1–9999, default 1) — Variation

## Composition
- Inputs: Loop progress 0…1. Five colours and the style values at creation.
- Outputs: A THREE.Mesh (2 × 2 plane) with a ShaderMaterial, or the material alone.
- Coordinates: Fills clip space under OrthographicCamera(-1, 1, 1, -1); on your own plane it follows the UVs.
- Lighting: Self-lit: the shader shades its own relief with a soft window light; scene lights do not affect it.
- Timing: update(progress) is a pure function of progress; frames render in any order.
- Works with: kinetic-title, rolling-counter, gradient-background
- Pass the surface's aspect ratio (width / height) so cells stay round on non-square planes.
- Put it on a plane in a 3D scene (a canvas on an easel, a phone screen) with createPaintPourMaterial.

## Output and loop
- 1080×1080, 30 fps, 8 s, procedural
- Seamless loop: yes — The swirl offsets travel once round closed circles in the noise domain per loop, and everything else is a pure function of them, so the last frame meets the first.
- Verified 2026-10-05 in Chrome 154.0.8037.97 headless on Linux 7.0.0-38-generic (x64), Node 22.14.0 (WebGL 2 via SwiftShader (software)); deterministic: yes; loop check: Frame 0 vs end state (progress 1): mean |Δ| 0.0000, max |Δ| 0 of 255.

## Use it
New project: Create a WebGLRenderer, an OrthographicCamera(-1, 1, 1, -1) and add createPaintPour().mesh; call update(frame / totalFrames) and render each frame.

Existing project: Copy src/paint-pour.js. Use createPaintPourMaterial() on any plane, or the full-screen mesh as a background pass, and set the loop progress every frame.

Reuse ideas:
- Satisfying background: render it full frame behind Kinetic Title Reveal for a reel opener.
- Brand texture: set the five colours to a brand palette, one metallic accent, for a loop or a slide background.
- Product scene: apply the material to a canvas, a phone screen or packaging in a Three.js scene.

## Limitations
- A painted look, not a fluid simulation: the paint swirls in place and does not spread from a pour point.
- Seen from straight above; the relief is shading only, not geometry.

## License
MIT. Copyright (c) 2026 AI Pixel Wizard. Released under the MIT License. See LICENSE in this folder.
- three.js 0.185.1: MIT (https://github.com/mrdoob/three.js)

Provenance: Adapted from the owner's threejs-sketches/abstract-artistic/paint-pour (MIT), rebuilt for AI Pixel Wizard in October 2026: new pour pattern (folded bands, round cells, lacing) with antialiased edges, relief lighting, metallic paint, and the frame/time contract.

