Pixel Inferno
by MusicBar, visualizer
A chunky demoscene pixel fire roars along the bar, its flames leaping with the spectrum, bass in the middle, and pixel embers popping out on every beat.
How it installs, its SHA-256 and its code
Click Apply: MusicBar downloads it, checks its SHA-256 and puts it on the taskbar, or just puts it on if it already has it. Needs MusicBar 1.8 or newer.
SHA-256 e2abb59b74af35d45c53ceb6091be8bd89f5cd127ce522b72ab2073a89ce55b0
//! name: Pixel Inferno
//! author: MusicBar
//! kind: visualizer
//! description: A chunky demoscene pixel fire roars along the bar, its flames leaping with the spectrum, bass in the middle, and pixel embers popping out on every beat.
// A steady random number for a cell.
float hash2(float2 p)
{
float3 q = frac(float3(p.x, p.y, p.x) * 0.1031);
q += dot(q, q.yzx + 33.33);
return frac((q.x + q.y) * q.z);
}
// Smooth value noise.
float vnoise(float2 p)
{
float2 i = floor(p);
float2 f = frac(p);
f = f * f * (3.0 - 2.0 * f);
return lerp(lerp(hash2(i), hash2(i + float2(1, 0)), f.x), lerp(hash2(i + float2(0, 1)), hash2(i + float2(1, 1)), f.x), f.y);
}
// The fire in eight flat steps, black to white; the middle steps lean a little toward the palette.
float3 ramp(float k)
{
float3 c = float3(0.20, 0.03, 0.05);
c = lerp(c, float3(0.48, 0.05, 0.05), step(1.5, k));
c = lerp(c, float3(0.80, 0.11, 0.05), step(2.5, k));
c = lerp(c, float3(0.97, 0.34, 0.06), step(3.5, k));
c = lerp(c, float3(1.00, 0.56, 0.10), step(4.5, k));
c = lerp(c, float3(1.00, 0.80, 0.24), step(5.5, k));
c = lerp(c, float3(1.00, 0.97, 0.80), step(6.5, k));
float mids = step(1.5, k) * step(k, 4.5);
return lerp(c, colorA.rgb, 0.3 * mids);
}
void layer(inout float3 acc, inout float cover, float3 rgb, float a)
{
a = saturate(a);
acc = rgb * a + acc * (1.0 - a);
cover = a + cover * (1.0 - a);
}
float4 main(float2 uv : TEXCOORD) : COLOR
{
// Everything snaps to chunky pixels: c counts them along the bar and up from the screen edge.
float p = max(2.0, floor(size.y / 10.0));
float rows = floor(size.y / p);
float cols = floor(size.x / p);
float2 c = floor(float2(uv.x * size.x, rise(uv) * size.y) / p);
float q = (c.y + 0.5) / rows;
// Each column burns as high as its band of the spectrum, mirrored with the bass in the middle.
float x = (c.x + 0.5) / cols;
float sv = spectrum(abs(x - 0.5) * 2.0);
float env = (0.14 + 1.05 * sv + 0.1 * level) * (0.7 + 0.4 * (1.0 - abs(x - 0.5) * 2.0)) * (1.0 + 0.3 * beat);
// Tongues rising fast and swaying sideways, plus a small per-pixel flicker that changes 15 times a second.
float tick = floor(time * 15.0);
float n1 = vnoise(float2(c.x * 0.28 + 0.7 * sin(c.y * 0.35 + time * 1.7), c.y * 0.3 - time * 6.0));
float n2 = vnoise(float2(c.x * 0.7, c.y * 0.6 - time * 10.0));
float flick = hash2(c + float2(tick * 7.3, tick * 3.1));
float hq = q / env;
float heat = (1.0 - hq) * (0.6 + 0.45 * sv) + (n1 * 0.75 + n2 * 0.25 - 0.5) * (0.35 + 1.1 * hq) + (flick - 0.5) * 0.08;
float k = floor(saturate(heat) * 7.99);
float3 acc = float3(0, 0, 0);
float cover = 0;
// The fire itself, the darkest step a little see-through.
layer(acc, cover, ramp(k), step(0.5, k) * lerp(0.7, 1.0, step(1.5, k)));
// Pixel embers rising out of the fire, popping out in a crowd on the beat.
float2 ec = float2(c.x, c.y - floor(time * 9.0));
float er = hash2(ec * float2(1.0, 1.7) + 11.0);
float swarm = step(1.0 - (0.012 + 0.03 * level + 0.12 * beat), er);
float above = step(k, 0.5) * step(env * 0.5, q) * step(q / env, 1.1 + 0.9 * frac(er * 53.0));
float tw = step(0.3, frac(time * 6.0 + er * 13.0));
float3 emberColor = lerp(float3(1.0, 0.85, 0.3), colorC.rgb, 0.4);
emberColor = lerp(emberColor, lerp(float3(1.0, 0.4, 0.1), colorA.rgb, 0.4), step(1.25, q / env));
emberColor = lerp(emberColor, float3(1, 1, 1), step(0.6, beat) * step(0.5, frac(er * 37.0)));
layer(acc, cover, emberColor, swarm * above * tw);
return paint(acc / max(cover, 0.001), cover);
}