shader_type canvas_item; // Анимированный фон главного меню: градиент + полярное сияние + звёзды + виньетка. uniform vec4 color_top : source_color = vec4(0.035, 0.043, 0.098, 1.0); uniform vec4 color_bottom : source_color = vec4(0.020, 0.106, 0.133, 1.0); uniform vec4 aurora_a : source_color = vec4(0.180, 0.850, 0.760, 1.0); uniform vec4 aurora_b : source_color = vec4(0.470, 0.360, 0.960, 1.0); uniform float speed : hint_range(0.0, 0.3) = 0.035; uniform float aurora_strength : hint_range(0.0, 2.0) = 0.55; uniform float star_amount : hint_range(0.0, 1.0) = 0.45; uniform float vignette_strength : hint_range(0.0, 1.0) = 0.65; float hash21(vec2 p) { p = fract(p * vec2(123.34, 456.21)); p += dot(p, p + 45.32); return fract(p.x * p.y); } // Мягкая волнистая полоса «сияния» на высоте center. float aurora_band(vec2 uv, float t, float center, float freq, float thickness) { float y = center + 0.090 * sin(uv.x * freq + t) + 0.050 * sin(uv.x * freq * 1.6 - t * 0.8) + 0.018 * sin(uv.x * freq * 2.7 + t * 0.5); float d = abs(uv.y - y); float band = smoothstep(thickness, 0.0, d); return band * band; } // Звёздное поле. Три независимых хеша на ячейку: положение внутри ячейки, // базовая яркость и характер мерцания. Без этого звёзды садятся на решётку // и подмигивают синхронно, волной. vec3 starfield(vec2 uv) { vec2 grid = uv * vec2(190.0, 107.0); vec2 cell = floor(grid); vec2 local = fract(grid); float h1 = hash21(cell); float h2 = hash21(cell + 17.31); float h3 = hash21(cell + 41.77); float present = step(1.0 - star_amount * 0.045, h1); // Смещение внутри ячейки убирает регулярность решётки. vec2 offset = vec2(h2, h3) * 0.66 + 0.17; float d = length(local - offset); // Ядро плюс мягкий ореол — так звезда читается, не превращаясь в точку. float radius = mix(0.13, 0.32, h3); float shape = smoothstep(radius, 0.0, d) + 0.22 * smoothstep(radius * 3.0, 0.0, d); // Две несоизмеримые частоты — рисунок мерцания не повторяется на глаз. float phase = h1 * 62.83; float flicker = 0.5 + 0.5 * ( 0.62 * sin(TIME * (0.5 + h3 * 1.8) + phase) + 0.38 * sin(TIME * (0.31 + h2 * 1.1) * 1.618 + phase * 1.7) ); // У части звёзд мерцание почти незаметно, у части — заметное. float amplitude = 0.12 + 0.5 * h3; float brightness = (0.30 + 0.70 * h2) * (1.0 - amplitude + amplitude * flicker); vec3 tint = mix(vec3(0.74, 0.84, 1.0), vec3(1.0, 0.93, 0.80), h2); return tint * present * shape * brightness; } void fragment() { vec2 uv = UV; float t = TIME * speed * 6.28318; vec3 col = mix(color_top.rgb, color_bottom.rgb, smoothstep(0.0, 1.0, uv.y)); col += aurora_a.rgb * aurora_band(uv, t, 0.34, 4.0, 0.22) * aurora_strength; col += aurora_b.rgb * aurora_band(uv, t * 0.75 + 2.0, 0.62, 3.0, 0.28) * aurora_strength * 0.75; col += starfield(uv); // Виньетка по краям кадра. float v = distance(uv, vec2(0.5, 0.5)); col *= 1.0 - smoothstep(0.32, 0.95, v) * vignette_strength; COLOR = vec4(col, 1.0); }