{
  "schemaVersion": 1,
  "id": "thunderstorm",
  "version": "1.0.0",
  "status": "published",
  "kind": "background",
  "title": "Thunderstorm",
  "summary": "A storm at night over the sea: forked lightning lighting the clouds, rain slanting through the flashes and a lighthouse beam turning in the dark. Loops perfectly.",
  "description": "Banks of cloud that glow from inside when lightning strikes, forked bolts that grow down in a stepped leader and flash in a bright return stroke with two flickering re-strikes, sheets of light in the cloud and crawling discharges across it, rain slanting through the light, a dark heaving sea that catches every flash in a column of glitter, and, on the coast, a striped lighthouse turning its beam through the rain (or, out at sea, a small ship riding the swell). Choose the scenery, how many flashes there are in the loop, how hard it rains, how heavy the cloud is, how bright the lightning is and its colour (cold white, violet, amber or green), and the wind.",
  "role": "Background (WebGL shader, full frame): a dramatic night storm for horror, thriller, weather and moody title content.",
  "collections": [
    "backgrounds",
    "hypnotic-loops"
  ],
  "tags": [
    "thunderstorm",
    "lightning",
    "storm",
    "rain",
    "night",
    "sea",
    "lighthouse",
    "clouds",
    "weather",
    "dramatic",
    "loop",
    "background"
  ],
  "synonyms": [
    "lightning storm",
    "thunder and lightning",
    "stormy night",
    "rainstorm",
    "tempest",
    "lightning bolt animation",
    "storm background",
    "sea storm"
  ],
  "useCases": [
    "A dramatic backdrop for thriller, horror and weather content",
    "A moody title or intro with flashes of light",
    "A sleep or ambience loop with rain and distant thunder"
  ],
  "featured": null,
  "publishedAt": "2026-10-06",
  "implementation": {
    "target": "three",
    "runtime": "browser",
    "language": "javascript",
    "module": "esm",
    "entry": "src/thunderstorm.js",
    "exports": [
      {
        "name": "createThunderstorm",
        "signature": "createThunderstorm({ scenery?, strikes?, rain?, clouds?, brightness?, tint?, wind?, seed?, aspect?, loopSeconds? }) => { scene, camera, events, setSize(width, height), update(time, loopSeconds), dispose() }",
        "description": "The whole storm: a backdrop of cloud, sea, coast and rain, and every bolt as instanced ribbons, in one scene. Render it with its camera, ideally through createBloomPass."
      },
      {
        "name": "createBloomPass",
        "signature": "createBloomPass(renderer, { width, height, glow?, exposure?, grain? }) => { render(scene, camera, output?), dispose() }",
        "description": "A small bloom with filmic tone mapping: draws a scene to the canvas with its glow."
      },
      {
        "name": "planStorm",
        "signature": "planStorm({ strikes?, seed?, loopSeconds?, scenery?, aspect? }) => [{ kind, t0, xTop, yTop, xG, yG, segments }]",
        "description": "The schedule of the lightning: when each flash comes, where, what kind (ground strike, sheet, crawl) and the segments of its channel."
      },
      {
        "name": "TINTS",
        "signature": "TINTS: { storm, violet, amber, green }",
        "description": "The colours of the lightning."
      }
    ],
    "reusable": [
      "src/thunderstorm.js"
    ],
    "demo": "demo.js",
    "harness": "index.html"
  },
  "dependencies": [
    {
      "id": "three",
      "version": "0.185.1",
      "reason": "Renderer, instanced bolts and the bloom targets."
    },
    {
      "id": "apw-runtime",
      "version": "1.0.0",
      "scope": "demo",
      "reason": "Demo harness."
    }
  ],
  "params": [
    {
      "key": "scenery",
      "label": "Scenery",
      "type": "select",
      "default": "lighthouse",
      "options": [
        {
          "value": "lighthouse",
          "label": "Lighthouse on the coast"
        },
        {
          "value": "sea",
          "label": "Open sea"
        }
      ]
    },
    {
      "key": "strikes",
      "label": "Flashes per loop",
      "type": "integer",
      "min": 1,
      "max": 10,
      "step": 1,
      "default": 5
    },
    {
      "key": "rain",
      "label": "Rain",
      "type": "number",
      "min": 0,
      "max": 1.6,
      "step": 0.05,
      "default": 1
    },
    {
      "key": "clouds",
      "label": "Heavy cloud",
      "type": "number",
      "min": 0.7,
      "max": 1.4,
      "step": 0.05,
      "default": 1
    },
    {
      "key": "brightness",
      "label": "Lightning brightness",
      "type": "number",
      "min": 0.5,
      "max": 1.6,
      "step": 0.05,
      "default": 1
    },
    {
      "key": "tint",
      "label": "Lightning colour",
      "type": "select",
      "default": "storm",
      "options": [
        {
          "value": "storm",
          "label": "Cold white"
        },
        {
          "value": "violet",
          "label": "Violet"
        },
        {
          "value": "amber",
          "label": "Amber"
        },
        {
          "value": "green",
          "label": "Green"
        }
      ]
    },
    {
      "key": "wind",
      "label": "Wind",
      "help": "The slant of the rain: negative leans the other way.",
      "type": "number",
      "min": -0.6,
      "max": 0.6,
      "step": 0.05,
      "default": 0.25
    },
    {
      "key": "seed",
      "label": "Seed",
      "help": "Changes when and where the lightning strikes, the shape of its forks and the clouds.",
      "type": "integer",
      "min": 1,
      "max": 999,
      "step": 1,
      "default": 4
    }
  ],
  "presets": [
    {
      "id": "default",
      "label": "Storm over the lighthouse",
      "params": {}
    },
    {
      "id": "tempest",
      "label": "Open-sea tempest",
      "params": {
        "scenery": "sea",
        "strikes": 7,
        "rain": 1.3,
        "clouds": 1.2,
        "wind": 0.4,
        "seed": 9
      }
    },
    {
      "id": "distant",
      "label": "Distant storm",
      "params": {
        "scenery": "sea",
        "strikes": 3,
        "rain": 0.35,
        "clouds": 0.85,
        "brightness": 0.8,
        "wind": 0.1,
        "seed": 14
      }
    },
    {
      "id": "violet",
      "label": "Violet lightning",
      "params": {
        "tint": "violet",
        "strikes": 6,
        "brightness": 1.3,
        "wind": -0.3,
        "seed": 21
      }
    }
  ],
  "output": {
    "width": 1080,
    "height": 1080,
    "fps": 30,
    "durationSeconds": 12,
    "posterSeconds": 4.2,
    "alpha": false,
    "motion": "procedural",
    "loop": {
      "seamless": true,
      "cycleSeconds": 12,
      "method": "Every flash is scheduled round the loop and times itself with a modulo; the rain and the waves scroll through a texture that repeats a whole number of times a loop (every octave's multiplier along the scroll is a whole number); the clouds churn on circles of the noise and the beam and the ship turn and roll in whole cycles, so the last frame meets the first."
    },
    "seed": {
      "param": "seed",
      "behavior": "Seed picks when and where the lightning strikes, the shape of every fork and the pattern of the clouds and waves: same seed, same storm."
    }
  },
  "composition": {
    "inputs": "Time within the loop; the scenery, flashes per loop, rain, cloud, lightning brightness and colour, wind.",
    "outputs": "A full frame: the night, cloud, sea, coast and rain drawn by one shader, and every lightning channel as an instanced ribbon drawn additively over it.",
    "coordinates": "Orthographic: x from -aspect to aspect, y from -1 to 1; the horizon sits at y = -0.28 and the clouds fill the sky above it.",
    "lighting": "Self-lit: each flash lights the clouds, rain, sea and coast in the colour of the lightning by its distance to the channel; the beam of the lighthouse lights the rain and the cloud.",
    "timing": "update(time, loopSeconds) sets the time; each flash is a closed-form function of the seconds since it began, so frames render in any order.",
    "compatibleWith": [
      "kinetic-title",
      "number-reveal"
    ],
    "notes": [
      "A strike is a stepped leader reaching the ground in 85 ms, a return stroke that fades in 70 ms and two more strokes at 0.24 s and 0.40 s, with a weak current flickering on to 0.7 s.",
      "The channels are generated once by midpoint displacement with branches and twigs; the cloud lightning crawls sideways inside the cloud."
    ]
  },
  "reuse": [
    "Thriller or horror opener: Storm over the lighthouse behind a slow title.",
    "Weather or news explainer: Distant storm, rain turned down.",
    "Sleep or ambience loop: Open-sea tempest with the lightning dimmed."
  ],
  "integration": {
    "newProject": "Create a WebGLRenderer, createThunderstorm({ aspect }) and createBloomPass(renderer, { width, height }); call storm.setSize(width, height), then each frame storm.update(time, loopSeconds) and bloom.render(storm.scene, storm.camera).",
    "existingProject": "Copy src/thunderstorm.js; render storm.scene with storm.camera into a render target (or through the bloom pass) as the backdrop or an overlay of your scene."
  },
  "performance": {
    "notes": "One full-screen pass with about 30 texture fetches a pixel, up to ten bolts of about a hundred instanced segments each, and a small bloom. About 14 ms a frame at 1080p on an integrated Intel GPU.",
    "limits": "More than ten flashes per loop need a larger array in the shader."
  },
  "limitations": [
    "The sea, the coast and the clouds are flat layers drawn from noise, not a 3D scene; the lighthouse and the ship are silhouettes.",
    "No thunder: the video has no sound."
  ],
  "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/fire-weather/lightning-storm (with webgpu-lightning-bolt, webgpu-thundercloud and webgpu-supercell-storm, MIT) and rebuilt for AI Pixel Wizard in October 2026 as an original scene: jagged forked channels with a stepped leader and re-strikes, clouds lit from within by each flash, scrolling rain, a heaving sea with glitter columns, a lighthouse with a turning beam, an exact loop and the frame/time contract.",
  "changelog": [
    {
      "version": "1.0.0",
      "date": "2026-10-05",
      "notes": "Initial release."
    }
  ]
}
