{
  "schemaVersion": 1,
  "id": "synthwave-sunset",
  "version": "1.0.0",
  "status": "published",
  "kind": "background",
  "title": "Synthwave Sunset",
  "summary": "An 80s outrun sunset: a striped sun behind neon-edged mountains and a glowing grid racing to the horizon. Loops perfectly.",
  "description": "The retro-futurist sunset of 80s album covers and synthwave videos: a huge sun striped with gaps that slide down towards the horizon, low-poly mountains with glowing ridge lines and a faint wireframe, a neon grid racing over a dark plain into a hazy horizon with the sun's glow lying on it, stars overhead and palm silhouettes either side. Soft VHS scan lines finish it. Choose the palette (outrun pink and cyan, Miami teal and pink, orange haze or pastel vaporwave), the palms, the grid's speed, the sun's size and the scan lines.",
  "role": "Background (WebGL shader, full frame): a retro neon backdrop for titles, music and gaming content.",
  "collections": [
    "backgrounds",
    "hypnotic-loops"
  ],
  "tags": [
    "synthwave",
    "outrun",
    "retrowave",
    "80s",
    "neon",
    "grid",
    "sunset",
    "vaporwave",
    "retro",
    "vhs",
    "loop",
    "background"
  ],
  "synonyms": [
    "retro grid",
    "80s sunset",
    "neon grid background",
    "outrun background",
    "vaporwave sunset",
    "synthwave background",
    "retrowave grid",
    "miami vice sunset"
  ],
  "useCases": [
    "A backdrop for synthwave, retrowave and 80s-inspired music videos",
    "Gaming intros and streams with a retro arcade look",
    "Nostalgic titles and end cards"
  ],
  "featured": null,
  "publishedAt": "2026-10-06",
  "implementation": {
    "target": "three",
    "runtime": "browser",
    "language": "javascript",
    "module": "esm",
    "entry": "src/synthwave-sunset.js",
    "exports": [
      {
        "name": "createSynthwaveSunset",
        "signature": "createSynthwaveSunset({ palette?, palms?, scanlines?, speed?, sun?, seed? }) => { scene, camera, material, setSize(width, height), update(time, loopSeconds), dispose() }",
        "description": "The whole sunset as one full-screen shader: render its scene with its camera, after setSize and update."
      },
      {
        "name": "PALETTES",
        "signature": "PALETTES: { outrun, miami, haze, vapor }",
        "description": "The colour sets: sky, horizon, sun, grid, mountains, ridge light and floor."
      }
    ],
    "reusable": [
      "src/synthwave-sunset.js"
    ],
    "demo": "demo.js",
    "harness": "index.html"
  },
  "dependencies": [
    {
      "id": "three",
      "version": "0.185.1",
      "reason": "Renderer and the full-screen shader."
    },
    {
      "id": "apw-runtime",
      "version": "1.0.0",
      "scope": "demo",
      "reason": "Demo harness."
    }
  ],
  "params": [
    {
      "key": "palette",
      "label": "Palette",
      "type": "select",
      "default": "outrun",
      "options": [
        {
          "value": "outrun",
          "label": "Outrun pink and cyan"
        },
        {
          "value": "miami",
          "label": "Miami teal and pink"
        },
        {
          "value": "haze",
          "label": "Orange haze"
        },
        {
          "value": "vapor",
          "label": "Pastel vaporwave"
        }
      ]
    },
    {
      "key": "palms",
      "label": "Palm trees",
      "type": "boolean",
      "default": true
    },
    {
      "key": "speed",
      "label": "Grid speed",
      "help": "Grid squares passed per loop.",
      "type": "integer",
      "min": 4,
      "max": 32,
      "step": 1,
      "default": 12
    },
    {
      "key": "sun",
      "label": "Sun size",
      "type": "number",
      "min": 0.6,
      "max": 1.4,
      "step": 0.05,
      "default": 1
    },
    {
      "key": "scanlines",
      "label": "Scan lines",
      "type": "number",
      "min": 0,
      "max": 0.4,
      "step": 0.02,
      "default": 0.12
    },
    {
      "key": "seed",
      "label": "Seed",
      "help": "Changes the mountains and the stars.",
      "type": "integer",
      "min": 1,
      "max": 999,
      "step": 1,
      "default": 4
    }
  ],
  "presets": [
    {
      "id": "default",
      "label": "Outrun",
      "params": {}
    },
    {
      "id": "miami",
      "label": "Miami nights",
      "params": {
        "palette": "miami",
        "sun": 1.15,
        "seed": 9
      }
    },
    {
      "id": "haze",
      "label": "Orange haze, no palms",
      "params": {
        "palette": "haze",
        "palms": false,
        "speed": 8,
        "sun": 1.25,
        "scanlines": 0.2,
        "seed": 15
      }
    },
    {
      "id": "vapor",
      "label": "Pastel vaporwave",
      "params": {
        "palette": "vapor",
        "speed": 16,
        "sun": 0.85,
        "scanlines": 0.06,
        "seed": 21
      }
    }
  ],
  "output": {
    "width": 1080,
    "height": 1080,
    "fps": 30,
    "durationSeconds": 8,
    "posterSeconds": 4,
    "alpha": false,
    "motion": "procedural",
    "loop": {
      "seamless": true,
      "cycleSeconds": 8,
      "method": "The grid passes a whole number of squares per loop, the sun's bands slide two whole bands, the stars twinkle whole cycles and the camera's drift is a sine of the loop, so the last frame meets the first."
    },
    "seed": {
      "param": "seed",
      "behavior": "Seed shapes the mountains and places the stars."
    }
  },
  "composition": {
    "inputs": "Time within the loop; the palette, palms, speed, sun size and scan lines.",
    "outputs": "A full frame, drawn by one shader on a full-screen quad.",
    "coordinates": "Screen space: the horizon sits a little below the middle, the sun centred on it.",
    "lighting": "Self-lit: every glow is part of the shader.",
    "timing": "update(time, loopSeconds) sets the loop phase; frames render in any order.",
    "compatibleWith": [
      "kinetic-title",
      "neon-sign",
      "rolling-counter"
    ],
    "notes": [
      "No textures: mountains, stars and palms are drawn from functions, antialiased at any size.",
      "Keep speed a whole number for a seamless loop."
    ]
  },
  "reuse": [
    "Music video: the Outrun preset with your artist name in chrome lettering over the sky.",
    "Stream overlay: Miami nights behind a webcam frame.",
    "Title card: Neon Sign's lettering over Orange haze."
  ],
  "integration": {
    "newProject": "Create a WebGLRenderer, createSynthwaveSunset(), call setSize with the canvas size, then each frame update(time, loopSeconds) and renderer.render(sunset.scene, sunset.camera).",
    "existingProject": "Copy src/synthwave-sunset.js and render it into a render target as the background of your scene, or first with autoClear off."
  },
  "performance": {
    "notes": "One full-screen pass with no textures. Smooth at 1080p on laptop GPUs and most phones.",
    "limits": "Software WebGL (no GPU) renders slowly."
  },
  "limitations": [
    "The camera faces the sun; the view is fixed apart from a gentle drift.",
    "No text: add a title with Kinetic Title or Neon Sign."
  ],
  "license": {
    "spdx": "MIT",
    "notice": "Copyright (c) 2026 AI Pixel Wizard. Released under the MIT License. See LICENSE in this folder.",
    "thirdParty": [
      {
        "name": "three.js",
        "version": "0.185.1",
        "license": "MIT",
        "url": "https://github.com/mrdoob/three.js"
      }
    ]
  },
  "provenance": "Adapted from the owner's threejs-sketches/light-atmosphere/neon-grid (MIT), rebuilt for AI Pixel Wizard in October 2026 as one antialiased shader: a banded sun, low-poly mountains with lit ridges and wireframe, a perspective neon grid with haze and the sun's reflection, stars, palms, scan lines, four palettes and the frame/time contract.",
  "changelog": [
    {
      "version": "1.0.0",
      "date": "2026-10-05",
      "notes": "Initial release."
    }
  ]
}
