Header
Your content here
Issues
- Left side UV.
Snippets
ShaderToy
// Shadertoy - Flying Through a Neon Tunnel
// Paste into Shadertoy as-is.
#define PI 3.14159265359
#define TAU 6.28318530718
mat2 rot(float a)
{
float c = cos(a), s = sin(a);
return mat2(c, -s, s, c);
}
float hash11(float p)
{
p = fract(p * 0.1031);
p *= p + 33.33;
p *= p + p;
return fract(p);
}
float hash21(vec2 p)
{
p = fract(p * vec2(234.34, 435.345));
p += dot(p, p + 34.23);
return fract(p.x * p.y);
}
float noise(vec2 p)
{
vec2 i = floor(p);
vec2 f = fract(p);
float a = hash21(i);
float b = hash21(i + vec2(1.0, 0.0));
float c = hash21(i + vec2(0.0, 1.0));
float d = hash21(i + vec2(1.0, 1.0));
vec2 u = f * f * (3.0 - 2.0 * f);
return mix(mix(a, b, u.x), mix(c, d, u.x), u.y);
}
float fbm(vec2 p)
{
float v = 0.0;
float a = 0.5;
for (int i = 0; i < 5; i++)
{
v += noise(p) * a;
p = rot(0.5) * p * 2.0 + 1.37;
a *= 0.5;
}
return v;
}
vec3 palette(float t)
{
vec3 a = vec3(0.5, 0.5, 0.5);
vec3 b = vec3(0.5, 0.5, 0.5);
vec3 c = vec3(1.0, 1.0, 1.0);
vec3 d = vec3(0.02, 0.18, 0.32);
return a + b * cos(TAU * (c * t + d));
}
float lanePulse(float x, float count, float sharpness)
{
float v = cos(x * count);
v = 0.5 + 0.5 * v;
return pow(v, sharpness);
}
void mainImage(out vec4 fragColor, in vec2 fragCoord)
{
vec2 uv = (fragCoord - 0.5 * iResolution.xy) / iResolution.y;
float t = iTime;
// Slight camera wobble for screensaver feel
vec2 cam = vec2(
0.10 * sin(t * 0.70),
0.10 * cos(t * 0.53)
);
vec2 p = uv + cam;
// Polar mapping
float r = length(p);
float ang = atan(p.y, p.x);
// Tunnel coordinates:
// z grows rapidly toward center, giving "forward motion"
float z = 1.0 / max(r, 0.08);
float forward = t * 6.0;
float tz = z + forward;
// Twist tunnel as it moves
ang += 0.7 * sin(tz * 0.12 + t * 0.8) + 0.15 * t;
ang += 0.25 * fbm(vec2(tz * 0.05, ang * 2.0));
// Tunnel surface coordinates
vec2 tuv = vec2(ang * 2.5, tz * 0.22);
// Surface detail
float n1 = fbm(tuv * 2.0);
float n2 = fbm(vec2(tuv.x * 6.0, tuv.y * 1.2 + t * 0.3));
float n3 = noise(vec2(ang * 12.0, tz * 0.5));
// Neon ring structure along depth
float rings = sin(tz * 1.8 - n1 * 4.0);
rings = pow(0.5 + 0.5 * rings, 10.0);
// Angular lane lights
float lanes = lanePulse(ang + n2 * 0.3, 10.0, 14.0);
float lanes2 = lanePulse(ang * 2.0 - tz * 0.05, 6.0, 18.0);
// Grid-ish energy pattern
float grid = rings * lanes;
grid += 0.6 * rings * lanes2;
// Extra streaking
float streaks = pow(1.0 - abs(sin(ang * 20.0 + tz * 0.35)), 18.0);
streaks *= 0.4 + 0.6 * n3;
// Central glow / vanishing point
float core = 0.015 / (r * r + 0.002);
// Tunnel mask: brightest around a cylindrical wall feel
float wall = smoothstep(0.02, 0.18, r) * (1.0 - smoothstep(0.85, 1.4, r));
// Color phase shifts over depth
float hue = tz * 0.025 + n1 * 0.6 + lanes * 0.15;
vec3 base = palette(hue);
vec3 col = vec3(0.0);
// Base tunnel glow
col += base * (0.25 + 0.75 * n1) * wall;
// Neon structures
col += palette(hue + 0.10) * grid * 1.6 * wall;
col += vec3(0.2, 0.8, 1.6) * streaks * wall * 1.2;
col += vec3(0.8, 0.2, 1.4) * rings * 0.5 * wall;
// Bright moving flashes down the tunnel
float flash = sin(tz * 0.9 - t * 5.0 + ang * 3.0);
flash = pow(0.5 + 0.5 * flash, 24.0);
col += palette(hue + 0.35) * flash * 2.0 * wall;
// Vanishing point energy
col += vec3(0.7, 0.9, 1.4) * core;
// Edge vignette
float vignette = smoothstep(1.5, 0.25, length(uv));
col *= vignette;
// Fake bloom / tonemap
col = 1.0 - exp(-col * 1.1);
// Slight gamma
col = pow(col, vec3(0.92));
fragColor = vec4(col, 1.0);
}