Skip to content

Corg-Labs/plasma

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

3 Commits
 
 
 
 
 
 
 
 

Classic Plasma Effect in C

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.


Features

  • 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

How It Works

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.


Tutorial / Rendering Pipeline

1. The Plasma Formula

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 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 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.


2. Normalisation

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);

3. Cosine RGB Palette

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.


4. Per-Pixel Rendering

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.


5. Animation

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);

Build

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

Run

./plasma

Controls:

  • ESC or Q — quit
  • Ctrl-C — quit (fallback)

Customizing

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
  • t increment (0.15) — overall animation speed
  • Cosine palette phases — shift colour bias

Concepts Practiced

  • 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

Dependencies

  • SDL.h — window management and pixel buffer
  • stdio.h — stderr diagnostics
  • stdlib.hNULL
  • math.hsin, cos, sqrt, fmod
  • signal.hSIGINT handler

About

► Old-school demoscene plasma effect.

Topics

Resources

License

Code of conduct

Contributing

Security policy

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors