Background
By Ayfri
Image
#ifdef GL_ES
precision highp float;
#endif
uniform vec2 uResolution;
uniform float uTime;
#define PI 3.14159265359
mat2 rot(float a) {
float s = sin(a);
float c = cos(a);
return mat2(c, -s, s, c);
}
float hash11(float p) {
return fract(sin(p * 127.1) * 43758.5453123);
}
vec2 hash21(float p) {
return fract(sin(vec2(p * 127.1, p * 311.7)) * 43758.5453123);
}
float hash12(vec2 p) {
return fract(sin(dot(p, vec2(127.1, 311.7))) * 43758.5453123);
}
float sdBox(vec2 p, vec2 b) {
vec2 d = abs(p) - b;
return length(max(d, 0.0)) + min(max(d.x, d.y), 0.0);
}
float softGlow(float d, float spread) {
return exp(-max(d, 0.0) / max(spread, 1e-4));
}
void addBand(inout vec3 col, vec2 q, float seed, float aa) {
float across = mix(-0.78, 0.78, hash11(seed + 1.0));
float along = mix(-1.20, 1.20, hash11(seed + 2.0));
float len = mix(0.10, 1.25, pow(hash11(seed + 3.0), 0.70));
float wid = mix(0.003, 0.12, pow(hash11(seed + 4.0), 2.2));
float driftDir = mix(-1.0, 1.0, hash11(seed + 5.0));
float speed = mix(0.015, 0.08, hash11(seed + 6.0));
along = mod(along + uTime * speed * driftDir + 1.75, 3.50) - 1.75;
vec2 p = q - vec2(along, across);
float d = sdBox(p, vec2(len, wid));
float fill = 1.0 - smoothstep(0.0, aa * 2.0, d);
float glow = softGlow(d, 0.05 + wid * 1.25);
float kind = hash11(seed + 7.0);
vec3 darkCol = vec3(0.03, 0.005, 0.08);
vec3 lightCol = vec3(0.22, 0.05, 0.34);
vec3 bandCol = mix(darkCol, lightCol, hash11(seed + 8.0));
float core = exp(-10.0 * pow(p.y / (wid + 0.003), 2.0));
float pulseCenter = sin(uTime * mix(0.25, 0.70, hash11(seed + 9.0)) + seed * 1.37) * 0.70;
float pulse = exp(-22.0 * pow(p.x / (len + 0.001) - pulseCenter, 2.0)) * core * fill;
if (kind < 0.32) {
// bandes sombres / découpes
col -= vec3(0.03, 0.00, 0.05) * fill * mix(0.4, 1.0, hash11(seed + 10.0));
col += bandCol * glow * 0.02;
} else {
// bandes violettes
float opacity = mix(0.08, 0.34, hash11(seed + 10.0));
col += bandCol * fill * opacity;
col += bandCol * glow * 0.07;
col += vec3(0.80, 0.22, 1.00) * pulse * mix(0.08, 0.45, hash11(seed + 11.0));
}
}
void addStreak(inout vec3 col, vec2 q, float seed, float aa) {
float across = mix(-0.95, 0.95, hash11(seed + 1.0));
float along = mix(-1.35, 1.35, hash11(seed + 2.0));
float len = mix(0.02, 0.20, hash11(seed + 3.0));
float wid = mix(0.0008, 0.0035, hash11(seed + 4.0));
along += sin(uTime * mix(0.4, 1.3, hash11(seed + 5.0)) + seed) * 0.08;
vec2 p = q - vec2(along, across);
float d = sdBox(p, vec2(len, wid));
float fill = 1.0 - smoothstep(0.0, aa, d);
float glow = softGlow(d, 0.01);
col += vec3(0.65, 0.18, 0.95) * (fill * 0.55 + glow * 0.07) * mix(0.2, 0.8, hash11(seed + 6.0));
}
void addParticle(inout vec3 col, vec2 uv, float seed) {
float aspect = uResolution.x / uResolution.y;
vec2 h = hash21(seed) * 2.0 - 1.0;
vec2 pos = vec2(h.x * aspect * 0.52, h.y * 0.52);
pos += 0.015 * vec2(
sin(uTime * 0.35 + seed * 2.7),
cos(uTime * 0.27 + seed * 1.9)
);
float size = mix(0.002, 0.010, pow(hash11(seed + 1.0), 3.0));
float d = length(uv - pos);
float twinkle = 0.35 + 0.65 * (0.5 + 0.5 * sin(uTime * mix(0.8, 2.2, hash11(seed + 2.0)) + seed * 6.0));
float core = exp(-d * d / (size * size));
float halo = exp(-d * d / (size * size * 18.0));
vec3 c = mix(vec3(0.45, 0.10, 0.72), vec3(0.95, 0.30, 1.00), hash11(seed + 3.0));
col += c * core * twinkle * 0.9;
col += c * halo * 0.12;
}
void addHeroBand(inout vec3 col, vec2 q, float aa) {
// grosse bande lumineuse vers le bas/droite
vec2 p = q - vec2(0.55 + sin(uTime * 0.18) * 0.05, -0.12);
float d = sdBox(p, vec2(1.05, 0.085));
float fill = 1.0 - smoothstep(0.0, aa * 2.0, d);
float glow = softGlow(d, 0.08);
float core = exp(-14.0 * pow(p.y / 0.09, 2.0));
col += vec3(0.20, 0.04, 0.32) * fill * 0.60;
col += vec3(0.40, 0.10, 0.65) * glow * 0.15;
float pulseCenter = sin(uTime * 0.45) * 0.45;
float pulse = exp(-18.0 * pow(p.x / 1.05 - pulseCenter, 2.0)) * core * fill;
col += vec3(0.95, 0.28, 1.00) * pulse * 0.65;
}
void main() {
vec2 uv = (gl_FragCoord.xy - 0.5 * uResolution.xy) / uResolution.y;
float aa = 1.5 / uResolution.y;
// très légère dérive de caméra
uv += 0.012 * vec2(sin(uTime * 0.08), cos(uTime * 0.06));
// fond très sombre
vec3 col = vec3(0.004, 0.001, 0.018);
// gradient diagonal
float diagGrad = smoothstep(-1.1, 0.9, uv.x * 0.55 + uv.y * 0.9);
col += vec3(0.05, 0.00, 0.10) * diagGrad;
// repère aligné avec les bandes diagonales
vec2 q = rot(-0.95) * uv;
// halo à gauche
float dLeft = length(uv - vec2(-0.65, 0.10));
col += vec3(0.80, 0.25, 1.00) * exp(-dLeft * 26.0) * (0.85 + 0.15 * sin(uTime * 1.2));
col += vec3(0.30, 0.08, 0.50) * exp(-dLeft * 8.0) * 0.25;
// halo en haut à droite
float dTopRight = length(uv - vec2(0.42, 0.56));
col += vec3(0.22, 0.04, 0.36) * exp(-dTopRight * 5.2) * 0.45;
// bande principale
addHeroBand(col, q, aa);
// grandes bandes
for (int i = 0; i < 12; i++) {
addBand(col, q, float(i) * 13.17 + 2.0, aa);
}
// fins streaks
for (int i = 0; i < 16; i++) {
addStreak(col, q, float(i) * 7.91 + 17.0, aa);
}
// particules lumineuses
for (int i = 0; i < 18; i++) {
addParticle(col, uv, float(i) * 5.73 + 1.0);
}
// grain subtil
float grain = hash12(gl_FragCoord.xy + vec2(uTime * 12.0, 0.0)) - 0.5;
col += grain * 0.012;
// vignette douce
float vignette = 1.0 - smoothstep(0.35, 1.25, length(uv * vec2(0.95, 1.10)));
col *= 0.55 + 0.45 * vignette;
col = clamp(col, 0.0, 1.0);
col = pow(col, vec3(0.92));
gl_FragColor = vec4(col, 1.0);
}