A real-time demoscene plasma effect — four sine waves summed per pixel produce a never-repeating, organically shifting colour field. Rendered at true colour per pixel via SDL2 with a smooth cosine RGB palette.
No textures, no lookup tables — just analytic trigonometric expressions evaluated fresh every frame.
- Four-wave plasma formula: vertical, horizontal, diagonal, and radial sine terms
- Incommensurable frequencies for non-repeating animation
- Per-pixel evaluation at 960 × 640 resolution
- True 24‑bit color via SDL2 framebuffer
- Cosine RGB palette for smooth, continuous colour cycling
- Animated time offset for fluid motion
- Keyboard and Ctrl-C quit handling
- Written entirely in C
For each of the 614,400 pixels in the window, four sine terms are summed: horizontal stripes (sin(x·0.02 + t)), vertical stripes (sin(y·0.03 + t·1.3)), a diagonal ripple (sin((x+y)·0.015 + t·0.7)), and a radial blob (sin(√(r²)·0.03 − t)). The sum ranges from −4 to +4, normalised to [0, 1], and fed into a three-phase cosine palette that produces the flowing colour.
The heart of the effect is a per-pixel scalar computed from four sine waves:
double v = sin(x * 0.02 + t)
+ sin(y * 0.03 + t * 1.3)
+ sin((x + y) * 0.015 + t * 0.7)
+ sin(sqrt((x - W/2)² + (y - H/2)²) * 0.03 - t);| Term | Pattern | Speed | Description |
|---|---|---|---|
| 1 | Vertical stripes | 1× | sin(x·0.02 + t) |
| 2 | Horizontal bands | 1.3× | sin(y·0.03 + t·1.3) |
| 3 | Diagonal ripples | 0.7× | sin((x+y)·0.015 + t·0.7) |
| 4 | Radial blob | 1× | sin(√(r²)·0.03 − t) (inward) |
Each term has a different spatial frequency and temporal phase, so their sum never repeats. The radial term adds a central swirling focal point.
The sum of four sine waves ranges from −4 to +4. It is mapped to [0, 1] for palette lookup:
float p = (float)((v + 4.0) / 8.0);The normalised scalar drives a three-phase cosine palette for smooth colour cycling:
static void cosine_palette(float t, float *r, float *g, float *b)
{
*r = 0.5f + 0.5f * cosf(6.28318f * (t + 0.00f));
*g = 0.5f + 0.5f * cosf(6.28318f * (t + 0.33f));
*b = 0.5f + 0.5f * cosf(6.28318f * (t + 0.66f));
}Each channel is a cosine wave phase-shifted by 120° (one third of the colour wheel). As p varies from 0 to 1, the output cycles through red → green → blue → red, producing a flowing rainbow-like spectrum.
The formula is evaluated once per pixel in a nested loop. The result is written directly into the SDL2 framebuffer:
for (int y = 0; y < WIN_H; y++) {
Uint32 *row = &pixels[y * pitch];
for (int x = 0; x < WIN_W; x++) {
/* compute v, normalise to p, palette to r,g,b */
row[x] = SDL_MapRGB(fmt,
(Uint8)(r * 255),
(Uint8)(g * 255),
(Uint8)(b * 255));
}
}At 960 × 640 this evaluates 614,400 pixels per frame. With four sinf calls, one sqrtf, and one SDL_MapRGB per pixel, the frame rate is typically 25–30 fps on modern hardware.
The time variable t increments by 0.15 each frame, shifting all four sine terms and producing continuous fluid motion:
t += 0.15;A 30 fps frame cap keeps the animation smooth:
Uint32 elapsed = SDL_GetTicks() - frame_start;
if (elapsed < 33) SDL_Delay(33 - elapsed);git clone <this-repo>
cd plasma
make
Or manually:
gcc plasma.c -o plasma -lm $(sdl2-config --cflags --libs)
Dependencies: SDL2 and a C compiler (gcc/clang).
Install SDL2 via Homebrew:
brew install sdl2
Or apt:
sudo apt install libsdl2-dev
./plasma
Controls:
- ESC or Q — quit
- Ctrl-C — quit (fallback)
Edit constants at the top of plasma.c:
WIN_W,WIN_H— window resolution (higher = smoother, slower)- Wave frequencies (
0.02,0.03,0.015,0.03) — change the pattern - Animation speeds (
1.3,0.7) — alter temporal behaviour tincrement (0.15) — overall animation speed- Cosine palette phases — shift colour bias
- Procedural texture generation via summed trigonometric functions
- Incommensurable frequency mixing for non-repeating animation
- Radial distance field for circular wave propagation
- Cosine-based RGB palette for continuous colour cycling
- Per-pixel framebuffer rendering
- SDL2 surface/pixel-buffer graphics
- Real-time animation with frame-rate capping
SDL.h— window management and pixel bufferstdio.h— stderr diagnosticsstdlib.h—NULLmath.h—sin,cos,sqrt,fmodsignal.h—SIGINThandler