{
  "schemaVersion": 1,
  "id": "campfire",
  "version": "1.0.0",
  "status": "published",
  "kind": "background",
  "title": "Campfire",
  "summary": "A campfire at night in a ring of stones: a flickering flame, glowing logs, rising embers and smoke, trees and stars at the edge of the light. Loops perfectly.",
  "description": "Logs leaning together, stacked, or burnt down to a bed of coals, in a ring of stones, with cracks glowing on the bark; a roaring turbulent flame that lights the logs, stones and ground and flickers, throwing soft shadows; embers rising and cooling, smoke drifting up lit from below, trunks and a treeline at the edge of the light and a sky full of stars. Choose the fire (leaning logs, stacked logs or embers), the height of the flame, its colour (a wood fire, green-and-violet driftwood or deep red), the wind, the embers, the smoke, the trees, the moonlight and how far the camera sways.",
  "role": "Background (WebGL shader, full frame): a warm, calming night scene for storytelling, wellness, travel and cosy content.",
  "collections": [
    "backgrounds",
    "hypnotic-loops"
  ],
  "tags": [
    "campfire",
    "fire",
    "flames",
    "embers",
    "night",
    "camping",
    "forest",
    "stars",
    "cozy",
    "warm",
    "loop",
    "background"
  ],
  "synonyms": [
    "bonfire",
    "camp fire",
    "fireplace",
    "burning logs",
    "fire loop",
    "relaxing fire",
    "night fire",
    "driftwood fire"
  ],
  "useCases": [
    "A cosy backdrop for storytelling, sleep and relaxation videos",
    "A camping, travel or outdoor brand scene",
    "An atmospheric game or fantasy campsite"
  ],
  "featured": null,
  "publishedAt": "2026-10-06",
  "implementation": {
    "target": "three",
    "runtime": "browser",
    "language": "javascript",
    "module": "esm",
    "entry": "src/campfire.js",
    "exports": [
      {
        "name": "createCampfire",
        "signature": "createCampfire({ layout?, size?, flame?, wind?, embers?, smoke?, trees?, moon?, sway?, seed?, aspect? }) => { scene, camera, material, pit, setSize(width, height), update(time, loopSeconds), dispose() }",
        "description": "The whole scene: one full-screen shader (fire, logs, stones, ground, trees, sky) and the embers as points. 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": "planFire",
        "signature": "planFire({ layout?, seed? }) => { logs, stones, trees, flame }",
        "description": "The fire pit: the logs as segments, the ring of stones, the trees round the edge of the light, and how big the flame is for the layout."
      },
      {
        "name": "FLAMES",
        "signature": "FLAMES: { natural, driftwood, ember }",
        "description": "Flame colours: its heart, its body, and its edge."
      },
      {
        "name": "LAYOUTS",
        "signature": "LAYOUTS: ['teepee', 'stacked', 'embers']",
        "description": "The ways the logs can be laid."
      }
    ],
    "reusable": [
      "src/campfire.js"
    ],
    "demo": "demo.js",
    "harness": "index.html"
  },
  "dependencies": [
    {
      "id": "three",
      "version": "0.185.1",
      "reason": "Renderer, the full-screen shader, the embers and the bloom targets."
    },
    {
      "id": "apw-runtime",
      "version": "1.0.0",
      "scope": "demo",
      "reason": "Demo harness."
    }
  ],
  "params": [
    {
      "key": "layout",
      "label": "Fire",
      "type": "select",
      "default": "teepee",
      "options": [
        {
          "value": "teepee",
          "label": "Logs leaning together"
        },
        {
          "value": "stacked",
          "label": "Logs stacked"
        },
        {
          "value": "embers",
          "label": "Burnt down to embers"
        }
      ]
    },
    {
      "key": "size",
      "label": "Flame height",
      "type": "number",
      "min": 0.7,
      "max": 1.4,
      "step": 0.05,
      "default": 1
    },
    {
      "key": "flame",
      "label": "Flame colour",
      "type": "select",
      "default": "natural",
      "options": [
        {
          "value": "natural",
          "label": "Wood fire"
        },
        {
          "value": "driftwood",
          "label": "Driftwood (green and violet)"
        },
        {
          "value": "ember",
          "label": "Deep red"
        }
      ]
    },
    {
      "key": "wind",
      "label": "Wind",
      "type": "number",
      "min": -0.6,
      "max": 0.6,
      "step": 0.05,
      "default": 0.2
    },
    {
      "key": "embers",
      "label": "Embers",
      "type": "number",
      "min": 0,
      "max": 1.5,
      "step": 0.05,
      "default": 1
    },
    {
      "key": "smoke",
      "label": "Smoke",
      "type": "number",
      "min": 0,
      "max": 1.5,
      "step": 0.05,
      "default": 0.8
    },
    {
      "key": "trees",
      "label": "Trees",
      "type": "boolean",
      "default": true
    },
    {
      "key": "moon",
      "label": "Moonlight",
      "type": "number",
      "min": 0.4,
      "max": 1.8,
      "step": 0.05,
      "default": 1
    },
    {
      "key": "sway",
      "label": "Camera sway",
      "type": "number",
      "min": 0,
      "max": 1.5,
      "step": 0.05,
      "default": 1
    },
    {
      "key": "seed",
      "label": "Seed",
      "type": "integer",
      "min": 1,
      "max": 999,
      "step": 1,
      "default": 5
    }
  ],
  "presets": [
    {
      "id": "default",
      "label": "Campfire in the woods",
      "params": {}
    },
    {
      "id": "stacked",
      "label": "Stacked logs, windy",
      "params": {
        "layout": "stacked",
        "size": 1.1,
        "wind": 0.4,
        "moon": 0.7,
        "seed": 9
      }
    },
    {
      "id": "driftwood",
      "label": "Driftwood fire on the shore",
      "params": {
        "flame": "driftwood",
        "trees": false,
        "wind": -0.3,
        "embers": 1.2,
        "seed": 7
      }
    },
    {
      "id": "embers",
      "label": "Dying embers",
      "params": {
        "layout": "embers",
        "smoke": 0.5,
        "embers": 1.4,
        "moon": 1.4,
        "seed": 12
      }
    }
  ],
  "output": {
    "width": 1080,
    "height": 1080,
    "fps": 30,
    "durationSeconds": 12,
    "posterSeconds": 3,
    "alpha": false,
    "motion": "procedural",
    "loop": {
      "seamless": true,
      "cycleSeconds": 12,
      "method": "The noise that makes the flame and the smoke scrolls a whole number of its texture's periods per loop (every octave's offset is a whole number of periods); every flicker of the light is a sum of sines with whole numbers of cycles; each ember is born and spent inside the loop, timed with a modulo; the camera sways in a sine of the loop, so the last frame meets the first."
    },
    "seed": {
      "param": "seed",
      "behavior": "Seed shapes the logs, places the stones and trees, and picks the stars, the ground and the pattern of the cracks and the embers: same seed, same fire."
    }
  },
  "composition": {
    "inputs": "Time within the loop; the layout of the fire, flame height and colour, wind, embers, smoke, trees, moonlight and camera sway.",
    "outputs": "A full frame: one ray-tracing shader on a full-screen quad, and the embers as instanced points drawn additively over it.",
    "coordinates": "World units of about a metre: the fire at the origin, the ring of stones 1.5 away, the camera 5.4 back and 1.1 up looking slightly down at the fire; trees stand 6 to 14 away.",
    "lighting": "The fire is the light: a point light at the heart of the flame that flickers, with inverse-square falloff, soft shadows from the logs and stones, and a dim bluish moonlight; the flame, the glowing cracks and the coals are emissive.",
    "timing": "update(time, loopSeconds) sets the loop phase; every part is a closed-form function of it, so frames render in any order.",
    "compatibleWith": [
      "kinetic-title",
      "number-reveal"
    ],
    "notes": [
      "Logs are capsules and stones flattened spheres in a signed-distance field that is sphere-traced only where a ray comes near the pit; the ground is a plane and the trunks are upright cylinders.",
      "The flame is a volume (a teardrop thinning with height, torn into tongues by three octaves of scrolling noise) marched in 26 steps; the smoke is a wider, dimmer column marched in 12."
    ]
  },
  "reuse": [
    "Cosy storytelling or sleep video: Campfire in the woods, slow.",
    "Camping or travel intro: Stacked logs, windy, behind a title.",
    "Fantasy or beach scene: Driftwood fire on the shore."
  ],
  "integration": {
    "newProject": "Create a WebGLRenderer, createCampfire({ aspect }) and createBloomPass(renderer, { width, height }); call fire.setSize(width, height), then each frame fire.update(time, loopSeconds) and bloom.render(fire.scene, fire.camera).",
    "existingProject": "Copy src/campfire.js; render fire.scene with fire.camera into a render target (or through the bloom pass) as the backdrop of your scene."
  },
  "performance": {
    "notes": "One full-screen pass (a bounded sphere trace, two short volume marches, about 40 texture fetches on the flame pixels) plus a few hundred embers and a small bloom. About 23 ms a frame at 1080p on an integrated Intel GPU.",
    "limits": "Software WebGL (no GPU) renders slowly, several seconds a frame."
  },
  "limitations": [
    "The flame is a smooth volume, not a fluid simulation: it flickers and tears but does not curl round the logs.",
    "The ground and trees are dark and simple: the forest is a handful of trunks and a silhouette."
  ],
  "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/nature-organic/campfire (with fire-weather/campfire-embers, MIT) and rebuilt for AI Pixel Wizard in October 2026 as an original ray-traced scene: a signed-distance fire pit with glowing cracks and soft shadows, a volumetric flame and smoke from scrolling noise, closed-form embers, an exact loop and the frame/time contract.",
  "changelog": [
    {
      "version": "1.0.0",
      "date": "2026-10-05",
      "notes": "Initial release."
    }
  ]
}
