Version 3 — © 1996-1999 Christian Cohnen
The ParticleFire applet uses a particle system to create a real-time fire effect. Particles spawn at the bottom of the applet area with random positions, velocities and luminance values. Each particle rises upward at an individual speed while following a configurable sinus wave oscillation for horizontal movement. As a particle travels, its luminance fades over time until it expires and respawns. The resulting intensity field is smoothed each frame by a weighted averaging filter that blends each pixel with its left, right and lower neighbors — this convolution kernel produces the characteristic soft, glowing flame shape. The final pixel colors are looked up from a 128-entry gradient palette that interpolates across five user-definable color stops.
Each frame, every pixel is recalculated from its neighbors using the following steps:
f = pixel_below * 252
f = f >> 7 // ≈ pixel_below × 1.97
f = f + pixel_left
f = f + pixel_right
f = f >> 2 // divide sum by 4
This produces an asymmetric kernel where the pixel below dominates — pulling heat upward — while left and right neighbors provide horizontal diffusion:
| row | left | center | right |
|---|---|---|---|
| current row | 0.25 | – | 0.25 |
| row below | – | 0.492 | – |
| total | 0.992 | ||
The pixel below carries weight 252 / 128 / 4 = 0.4921875, not exactly 1/2.
Because the total (0.992) stays below 1.0, the field loses roughly 0.8% of its energy each frame — flames cool down automatically as they rise.
The only multiplication (* 252) can be decomposed into (val << 8) − (val << 2), meaning the entire filter runs on shifts and additions alone.
The underlying technique has its roots in the demoscene of the late 1980s and early 1990s, where fire effects were hand-coded in assembly language on home computers like the Atari ST and Amiga.
Even the C64 ran variations of the effect using ASCII characters.
Key tricks were to avoid expensive multiplications in the convolution filter entirely — all weighting and averaging was done with bit-shift operators (>>) instead, which cost only a single CPU cycle compared to dozens for a multiply on these processors — and to use loop unrolling, where the inner filter loop was manually expanded to process multiple pixels per iteration, eliminating branch overhead and keeping the CPU pipeline filled.
This applet preserves the classic shift-based approach in its filter kernel.
What once required cycle-counted 68000 or 6502 assembly to run in real time has since evolved into a staple of modern video editing and motion graphics, where particle-based fire simulations appear in far more complex forms.
Color values use hex notation, e.g. #FF8800. The five color parameters define a gradient from background to flame tip.
| Name | Type | Description | Default | Required |
|---|---|---|---|---|
link | URL | Link target when applet is clicked | null | no |
targetWindow | String | Target window for link (_blank, _parent, etc.) | _self | no |
image | URL | Overlay image (use a transparent GIF) | – | no |
image2 | URL | Overlay image on mouseover | – | no |
particles | int | Number of particles (max 2048) | 500 | no |
sinus | int | Sinus movement amplitude of particles | 16 | no |
backColor | Color | Background color | #000000 | no |
lowColor | Color | Low intensity color | #202040 | no |
midColor | Color | Mid intensity color | #805050 | no |
upColor | Color | High intensity color | #FFD0B0 | no |
endColor | Color | Tip/end color | #FFFFFF | no |
<applet archive="ParticleFire.jar"
code="ParticleFire.class" height="120" width="100">
<param name="sinus" value="16">
<param name="particles" value="512">
</applet>