The host's markdown renderer doesn't support <video> tags, so the embed rendered blank. Linking directly works in every viewer. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
20 lines
1.2 KiB
Markdown
20 lines
1.2 KiB
Markdown
# Ember
|
|
|
|
A particle simulation that renders drifting embers carried by a Perlin-noise wind field, recorded to an MP4.
|
|
|
|
Sample output: [`animation.mp4`](animation.mp4) (variants: [`animation-day.mp4`](animation-day.mp4), [`animation-night.mp4`](animation-night.mp4)).
|
|
|
|
## How it works
|
|
|
|
- `ember.py` — each `Ember` spawns at the bottom edge with a randomized size, color offset, lifespan, and updraft, then fades out as its time-to-live expires or it nears a screen border. Drawn as a soft anti-aliased circle blended into the previous frame's trail.
|
|
- `wind.py` — `WindField` samples 3D Perlin noise (x, y, time) on a downscaled grid for each axis, with bilinear interpolation back up to pixel coordinates.
|
|
- `main.py` — drives the loop: fades the previous frame slightly each tick (the trail effect), advances the wind field, updates and draws every ember, and writes each frame to an MP4 via `imageio`.
|
|
|
|
## Run it
|
|
|
|
```sh
|
|
pip install pygame numpy imageio imageio-ffmpeg noise tqdm
|
|
python main.py
|
|
```
|
|
|
|
Tweak `EMBER_COUNT`, `WIND_STRENTH`, `RUNNING_TIME_IN_SECONDS`, or `FRAME_RATE` at the top of `main.py`. Set `IS_DEVELOPMENT = True` to watch the simulation in a window instead of writing to disk. Resolution lives in `config.py`.
|