Multi-Layer Plasma
Classic plasma effect combining multiple sine waves with color cycling. This is a foundational demoscene technique that creates smooth, flowing patterns through wave superposition.
Mathematical Formula
P(x, y, t) = \frac{\sin(x + \omega_1 t) + \sin(y + \omega_2 t) + \sin(\frac{x+y}{2} + \omega_3 t) + \sin(\frac{x-y}{2} + \omega_4 t)}{4}
Where:
x, yare spatial coordinates (0 to2\pi)tis time\omega_1, \omega_2, \omega_3, \omega_4are temporal frequencies- Division by 4 normalizes the sum
How It Works
Plasma effects rely on the principle of superposition: adding multiple simple waves creates complex patterns. Each sine wave contributes a different spatial and temporal frequency, and their sum creates interference patterns that appear to flow smoothly.
Implementation
import torch
width, height = 512, 512
frames = []
for t in range(30):
x = torch.linspace(0, 2*torch.pi, width)
y = torch.linspace(0, 2*torch.pi, height)
X, Y = torch.meshgrid(x, y, indexing='ij')
# Multi-layer plasma based on demoscene techniques
p1 = torch.sin(X + t/5)
p2 = torch.sin(Y + t/4)
p3 = torch.sin((X + Y) / 2 + t/6)
p4 = torch.sin((X - Y) / 2 + t/7)
plasma = (p1 + p2 + p3 + p4) / 4
# Earthbound-style warm sunset palette
r = plasma * 0.8 + 0.2
g = plasma * 0.4 + 0.3
b = plasma * 0.2 + 0.6
rgb = torch.stack([r, g, b], dim=-1).clamp(0, 1)
frames.append(rgb)
output_image = torch.stack(frames, dim=0)
Line-by-Line Explanation
p1 = torch.sin(X + t/5)
Horizontal wave moving right over time. t/5 controls speed.
p2 = torch.sin(Y + t/4)
Vertical wave moving down over time. Different speed (t/4) creates variation.
p3 = torch.sin((X + Y) / 2 + t/6)
Diagonal wave (sum of coordinates) moving at different speed.
p4 = torch.sin((X - Y) / 2 + t/7)
Anti-diagonal wave (difference of coordinates) for additional complexity.
plasma = (p1 + p2 + p3 + p4) / 4
Average of all four waves. Division by 4 normalizes to [-1, 1] range.
r = plasma * 0.8 + 0.2
g = plasma * 0.4 + 0.3
b = plasma * 0.2 + 0.6
Linear color mapping to warm sunset palette. Each channel has different scaling and offset for color variation.
Customization
More Waves
p5 = torch.sin(X * 2 + t/8)
p6 = torch.sin(Y * 2 + t/9)
plasma = (p1 + p2 + p3 + p4 + p5 + p6) / 6
Different Frequencies
p1 = torch.sin(2*X + t/5) # Tighter horizontal waves
p2 = torch.sin(3*Y + t/4) # Tighter vertical waves
Color Cycling
r = torch.sin(plasma * torch.pi + t/10)
g = torch.sin(plasma * torch.pi + t/10 + 2*torch.pi/3)
b = torch.sin(plasma * torch.pi + t/10 + 4*torch.pi/3)
rgb = ((rgb + 1) / 2).clamp(0, 1)
Mathematical Insight
Wave Superposition
When you add sine waves:
- Constructive interference: Peaks align → brighter regions
- Destructive interference: Peak meets trough → darker regions
- Partial interference: Intermediate brightness
The four waves with different spatial orientations create a complex interference pattern that appears to flow in multiple directions simultaneously.
Why Division by 4?
Each sine wave ranges from -1 to 1. Summing four waves gives a range of -4 to 4. Dividing by 4 normalizes back to [-1, 1], which is convenient for color mapping.
Performance Notes
- All operations are vectorized (fast on GPU)
- Precompute coordinate grids for efficiency
- Fewer waves = faster, more waves = more complex