#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum ShaderUniformKind {
Float1,
Float2,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub struct ShaderUniform {
pub name: &'static str,
pub kind: ShaderUniformKind,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub struct ShaderSource {
pub name: &'static str,
pub vertex: &'static str,
pub fragment: &'static str,
pub uniforms: &'static [ShaderUniform],
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum ShaderFamily {
Background,
Panel,
Prompt,
Interaction,
Code,
Flow,
Data,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub struct ShaderDescriptor {
pub source: ShaderSource,
pub family: ShaderFamily,
pub description: &'static str,
pub complexity: u8,
pub animated: bool,
}
pub const MAX_SHADER_PASS_STACK: usize = 4;
pub const MAX_SHADER_PASS_DOWNSAMPLE: u8 = 4;
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum ShaderPassRole {
Primary,
Mask,
Lighting,
Composite,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum ShaderBlendMode {
Replace,
Alpha,
Additive,
Screen,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub struct ShaderPassDescriptor {
pub role: ShaderPassRole,
pub shader: ShaderDescriptor,
pub blend: ShaderBlendMode,
pub downsample: u8,
}
impl ShaderPassDescriptor {
pub const fn new(role: ShaderPassRole, shader: ShaderDescriptor) -> Self {
Self {
role,
shader,
blend: ShaderBlendMode::Replace,
downsample: 0,
}
}
pub const fn with_blend(mut self, blend: ShaderBlendMode) -> Self {
self.blend = blend;
self
}
pub fn with_downsample(mut self, downsample: u8) -> Self {
self.downsample = downsample.min(MAX_SHADER_PASS_DOWNSAMPLE);
self
}
pub fn sanitized(self) -> Self {
Self {
downsample: self.downsample.min(MAX_SHADER_PASS_DOWNSAMPLE),
..self
}
}
pub fn estimated_complexity(self) -> u16 {
let pass = self.sanitized();
let scale = 1u16 << pass.downsample;
(pass.shader.complexity as u16).max(1).div_ceil(scale)
}
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub struct ShaderPassStack {
pub passes: [Option<ShaderPassDescriptor>; MAX_SHADER_PASS_STACK],
pub pass_count: usize,
}
impl ShaderPassStack {
pub const MAX_PASSES: usize = MAX_SHADER_PASS_STACK;
pub const fn empty() -> Self {
Self {
passes: [None; Self::MAX_PASSES],
pass_count: 0,
}
}
pub fn single(shader: ShaderDescriptor) -> Self {
Self::empty().with_pass(shader.primary_pass())
}
pub fn with_pass(self, pass: ShaderPassDescriptor) -> Self {
let mut compacted = Self::empty();
for existing in self.passes() {
compacted.passes[compacted.pass_count] = Some(existing);
compacted.pass_count += 1;
}
if compacted.pass_count < Self::MAX_PASSES {
compacted.passes[compacted.pass_count] = Some(pass.sanitized());
compacted.pass_count += 1;
}
compacted
}
pub fn len(&self) -> usize {
self.passes().count()
}
pub fn is_empty(&self) -> bool {
self.len() == 0
}
pub fn passes(&self) -> impl Iterator<Item = ShaderPassDescriptor> + '_ {
self.passes[..self.slot_count()]
.iter()
.flatten()
.copied()
.map(ShaderPassDescriptor::sanitized)
}
pub fn estimated_complexity(&self) -> u16 {
self.passes()
.map(ShaderPassDescriptor::estimated_complexity)
.fold(0u16, u16::saturating_add)
}
fn slot_count(&self) -> usize {
self.pass_count.min(Self::MAX_PASSES)
}
}
impl ShaderDescriptor {
pub const fn primary_pass(self) -> ShaderPassDescriptor {
ShaderPassDescriptor::new(ShaderPassRole::Primary, self)
}
pub fn pass_stack(self) -> ShaderPassStack {
ShaderPassStack::single(self)
}
}
pub const COMMON_UNIFORMS: &[ShaderUniform] = &[
ShaderUniform {
name: "u_time",
kind: ShaderUniformKind::Float1,
},
ShaderUniform {
name: "u_resolution",
kind: ShaderUniformKind::Float2,
},
ShaderUniform {
name: "u_intensity",
kind: ShaderUniformKind::Float1,
},
];
pub const VERTEX: &str = r#"#version 100
attribute vec3 position;
attribute vec2 texcoord;
attribute vec4 color0;
varying lowp vec2 uv;
varying lowp vec4 color;
uniform mat4 Model;
uniform mat4 Projection;
void main() {
gl_Position = Projection * Model * vec4(position, 1.0);
uv = texcoord;
color = color0;
}
"#;
pub const BACKGROUND_FRAGMENT: &str = r#"#version 100
precision mediump float;
varying lowp vec2 uv;
varying lowp vec4 color;
uniform float u_time;
uniform vec2 u_resolution;
uniform float u_intensity;
float hash(vec2 p) {
p = fract(p * vec2(123.34, 456.21));
p += dot(p, p + 45.32);
return fract(p.x * p.y);
}
float noise(vec2 p) {
vec2 i = floor(p);
vec2 f = fract(p);
vec2 u = f * f * (3.0 - 2.0 * f);
return mix(
mix(hash(i + vec2(0.0, 0.0)), hash(i + vec2(1.0, 0.0)), u.x),
mix(hash(i + vec2(0.0, 1.0)), hash(i + vec2(1.0, 1.0)), u.x),
u.y
);
}
float fbm(vec2 p) {
float value = 0.0;
float amplitude = 0.5;
mat2 warp = mat2(1.62, 1.18, -1.18, 1.62);
for (int i = 0; i < 6; i++) {
value += amplitude * noise(p);
p = warp * p + vec2(0.17, 0.31);
amplitude *= 0.53;
}
return value;
}
vec2 curl(vec2 p) {
float e = 0.035;
float n1 = fbm(p + vec2(0.0, e));
float n2 = fbm(p - vec2(0.0, e));
float n3 = fbm(p + vec2(e, 0.0));
float n4 = fbm(p - vec2(e, 0.0));
return vec2(n1 - n2, n4 - n3) / (2.0 * e);
}
float rings(vec2 p, float t) {
float d = length(p);
float wave = sin(34.0 * d - t * 3.5 + fbm(p * 4.0) * 2.5);
return smoothstep(0.84, 1.0, wave) * smoothstep(1.2, 0.12, d);
}
void main() {
vec2 res = max(u_resolution.xy, vec2(1.0));
vec2 p = (gl_FragCoord.xy * 2.0 - res) / max(max(res.x, res.y), 1.0);
float t = u_time * 0.18;
vec2 flow = curl(p * 2.0 + t);
vec2 q = p + flow * 0.22 + vec2(sin(t * 1.7), cos(t * 1.3)) * 0.08;
float nebula = fbm(q * 2.6 + t * 0.7);
float veins = fbm(q * 9.0 - flow * 1.4);
float halo = rings(p - vec2(0.38, -0.2), u_time);
float vignette = smoothstep(1.36, 0.18, length(p));
vec3 ink = vec3(0.010, 0.014, 0.034);
vec3 blue = vec3(0.09, 0.32, 0.78);
vec3 cyan = vec3(0.12, 0.82, 1.0);
vec3 violet = vec3(0.56, 0.14, 0.96);
vec3 gold = vec3(1.0, 0.55, 0.17);
vec3 col = ink;
col += blue * nebula * 0.34;
col += cyan * smoothstep(0.52, 0.96, veins) * 0.24;
col += violet * pow(max(nebula, 0.0), 2.2) * 0.32;
col += gold * halo * 0.36;
col *= 0.55 + vignette * 0.75;
col += vec3(hash(gl_FragCoord.xy + u_time) * 0.025);
gl_FragColor = vec4(col * (0.72 + u_intensity * 0.42), 1.0) * color;
}
"#;
pub const PANE_FRAGMENT: &str = r#"#version 100
precision mediump float;
varying lowp vec2 uv;
varying lowp vec4 color;
uniform float u_time;
uniform vec2 u_resolution;
uniform float u_intensity;
float hex(vec2 p) {
p.x *= 0.57735 * 2.0;
p.y += mod(floor(p.x), 2.0) * 0.5;
p = abs(fract(p) - 0.5);
return abs(max(p.x * 1.5 + p.y, p.y * 2.0) - 1.0);
}
float hash(vec2 p) {
return fract(sin(dot(p, vec2(127.1, 311.7))) * 43758.5453123);
}
float grid(vec2 p, float t) {
vec2 id = floor(p);
float h = hash(id);
float cell = smoothstep(0.035, 0.0, hex(p));
float sweep = smoothstep(0.98, 0.4, abs(fract(h + t * 0.08) - 0.5));
return cell * sweep;
}
void main() {
vec2 p = uv;
vec2 centered = p - 0.5;
float edge = smoothstep(0.5, 0.47, max(abs(centered.x), abs(centered.y)));
float border = 1.0 - smoothstep(0.0, 0.018, min(min(p.x, p.y), min(1.0 - p.x, 1.0 - p.y)));
float lattice = grid((p + vec2(u_time * 0.018, -u_time * 0.012)) * 18.0, u_time);
float scan = sin((p.y + u_time * 0.11) * 420.0) * 0.5 + 0.5;
vec3 base = vec3(0.018, 0.032, 0.070);
vec3 glow = vec3(0.10, 0.54, 0.95) * lattice * 0.22;
vec3 rim = vec3(0.36, 0.76, 1.0) * border * (0.32 + 0.22 * sin(u_time * 1.9));
vec3 col = base + glow + rim + vec3(scan * 0.018 * u_intensity);
gl_FragColor = vec4(col, 0.82 * edge) * color;
}
"#;
pub const PROMPT_FRAGMENT: &str = r#"#version 100
precision mediump float;
varying lowp vec2 uv;
varying lowp vec4 color;
uniform float u_time;
uniform vec2 u_resolution;
uniform float u_intensity;
float line(vec2 p, float offset, float width) {
return smoothstep(width, 0.0, abs(p.y - offset));
}
void main() {
vec2 p = uv;
float t = u_time;
float beam = line(p, 0.5 + sin(t * 1.4 + p.x * 7.0) * 0.08, 0.018);
float beam2 = line(p, 0.34 + cos(t * 1.1 + p.x * 9.0) * 0.05, 0.012);
float edge = 1.0 - smoothstep(0.0, 0.026, min(min(p.x, p.y), min(1.0 - p.x, 1.0 - p.y)));
float caret = smoothstep(0.015, 0.0, abs(fract(p.x * 34.0 - t * 0.9) - 0.5));
vec3 base = vec3(0.020, 0.030, 0.070);
vec3 cyan = vec3(0.16, 0.86, 1.0);
vec3 violet = vec3(0.75, 0.24, 1.0);
vec3 col = base + cyan * beam * 0.28 + violet * beam2 * 0.18;
col += cyan * edge * 0.32;
col += vec3(0.35, 0.85, 1.0) * caret * 0.035 * u_intensity;
gl_FragColor = vec4(col, 0.90) * color;
}
"#;
pub const AURORA_FRAGMENT: &str = r#"#version 100
precision mediump float;
varying lowp vec2 uv;
varying lowp vec4 color;
uniform float u_time;
uniform vec2 u_resolution;
uniform float u_intensity;
float hash(vec2 p) {
return fract(sin(dot(p, vec2(41.0, 289.0))) * 45758.5453);
}
float noise(vec2 p) {
vec2 i = floor(p);
vec2 f = fract(p);
f = f * f * (3.0 - 2.0 * f);
float a = hash(i);
float b = hash(i + vec2(1.0, 0.0));
float c = hash(i + vec2(0.0, 1.0));
float d = hash(i + vec2(1.0, 1.0));
return mix(mix(a, b, f.x), mix(c, d, f.x), f.y);
}
float ridge(float v) {
return 1.0 - abs(v * 2.0 - 1.0);
}
void main() {
vec2 res = max(u_resolution.xy, vec2(1.0));
vec2 p = gl_FragCoord.xy / res;
float t = u_time * 0.12;
float curtain = 0.0;
for (int i = 0; i < 5; i++) {
float fi = float(i);
vec2 q = vec2(p.x * (2.0 + fi * 0.65) + t * (0.7 + fi * 0.13), p.y * (7.0 + fi));
float band = ridge(noise(q + vec2(fi * 8.7, -t * 2.0)));
curtain += smoothstep(0.44, 1.0, band) * (0.18 + fi * 0.035);
}
float horizon = smoothstep(0.98, 0.16, p.y);
float stars = step(0.996, hash(gl_FragCoord.xy + floor(u_time * 8.0))) * smoothstep(0.8, 0.05, p.y);
vec3 deep = vec3(0.005, 0.015, 0.042);
vec3 green = vec3(0.18, 1.00, 0.70);
vec3 blue = vec3(0.10, 0.42, 1.00);
vec3 magenta = vec3(0.85, 0.16, 1.00);
vec3 col = deep + mix(blue, green, p.y) * curtain * horizon * u_intensity;
col += magenta * pow(curtain, 3.0) * 0.18;
col += vec3(stars) * 0.75;
gl_FragColor = vec4(col, 1.0) * color;
}
"#;
pub const KNOT_FIELD_FRAGMENT: &str = r#"#version 100
precision mediump float;
varying lowp vec2 uv;
varying lowp vec4 color;
uniform float u_time;
uniform vec2 u_resolution;
uniform float u_intensity;
float sdTorus(vec3 p, vec2 t) {
vec2 q = vec2(length(p.xz) - t.x, p.y);
return length(q) - t.y;
}
mat2 rot(float a) {
float s = sin(a);
float c = cos(a);
return mat2(c, -s, s, c);
}
float field(vec3 p) {
p.xz *= rot(u_time * 0.23);
p.xy *= rot(sin(u_time * 0.17) * 0.6);
float d = sdTorus(p, vec2(0.62, 0.055));
vec3 q = p;
q.xy *= rot(2.094);
float d2 = sdTorus(q, vec2(0.62, 0.055));
q = p;
q.xy *= rot(-2.094);
float d3 = sdTorus(q, vec2(0.62, 0.055));
return min(d, min(d2, d3));
}
void main() {
vec2 res = max(u_resolution.xy, vec2(1.0));
vec2 p = (gl_FragCoord.xy * 2.0 - res) / max(max(res.x, res.y), 1.0);
vec3 ro = vec3(0.0, 0.0, 2.1);
vec3 rd = normalize(vec3(p, -1.65));
float t = 0.0;
float glow = 0.0;
float hit = 0.0;
for (int i = 0; i < 58; i++) {
vec3 pos = ro + rd * t;
float d = field(pos);
glow += 0.006 / (0.018 + abs(d));
if (d < 0.003) {
hit = 1.0;
break;
}
t += max(d * 0.58, 0.012);
if (t > 4.0) {
break;
}
}
vec3 base = vec3(0.005, 0.010, 0.025);
vec3 cyan = vec3(0.10, 0.78, 1.00);
vec3 violet = vec3(0.65, 0.14, 1.00);
vec3 gold = vec3(1.00, 0.48, 0.10);
vec3 col = base + cyan * glow * 0.24 + violet * pow(glow, 1.4) * 0.08 + gold * hit * 0.35;
col *= 0.74 + u_intensity * 0.34;
gl_FragColor = vec4(col, 0.96) * color;
}
"#;
pub const TERMINAL_RAIN_FRAGMENT: &str = r#"#version 100
precision mediump float;
varying lowp vec2 uv;
varying lowp vec4 color;
uniform float u_time;
uniform vec2 u_resolution;
uniform float u_intensity;
float hash(vec2 p) {
return fract(sin(dot(p, vec2(13.13, 91.77))) * 43758.5453);
}
void main() {
vec2 cell = floor(gl_FragCoord.xy / vec2(10.0, 18.0));
float column = hash(vec2(cell.x, 2.0));
float speed = mix(0.8, 3.4, column);
float trail = fract(cell.y * 0.071 - u_time * speed + column * 9.0);
float glyph = hash(cell + floor(u_time * speed));
float on = smoothstep(0.92, 1.0, trail) * step(0.22, glyph);
float tail = smoothstep(0.45, 0.0, trail) * step(0.65, column);
vec3 base = vec3(0.0, 0.012, 0.025);
vec3 green = vec3(0.18, 1.0, 0.56);
vec3 blue = vec3(0.1, 0.68, 1.0);
vec3 col = base + green * on * u_intensity + blue * tail * 0.18;
col += vec3(hash(gl_FragCoord.xy) * 0.018);
gl_FragColor = vec4(col, 0.72) * color;
}
"#;
pub const FLOW_BEAMS_FRAGMENT: &str = r#"#version 100
precision mediump float;
varying lowp vec2 uv;
varying lowp vec4 color;
uniform float u_time;
uniform vec2 u_resolution;
uniform float u_intensity;
float capsule(vec2 p, vec2 a, vec2 b, float r) {
vec2 pa = p - a;
vec2 ba = b - a;
float h = clamp(dot(pa, ba) / max(dot(ba, ba), 0.00001), 0.0, 1.0);
return length(pa - ba * h) - r;
}
void main() {
vec2 p = uv;
float glow = 0.0;
for (int i = 0; i < 7; i++) {
float fi = float(i);
vec2 a = vec2(0.08, 0.16 + fi * 0.115);
vec2 b = vec2(0.92, 0.22 + sin(u_time * 0.7 + fi) * 0.24 + fi * 0.08);
float d = capsule(p, a, b, 0.006 + 0.002 * sin(u_time + fi));
float pulse = smoothstep(0.05, 0.0, abs(fract(u_time * 0.22 + fi * 0.17) - p.x));
glow += smoothstep(0.028, 0.0, d) * (0.28 + pulse * 0.72);
}
float node = 0.0;
for (int j = 0; j < 5; j++) {
float fj = float(j);
vec2 c = vec2(0.16 + fj * 0.18, 0.5 + sin(u_time * 0.5 + fj * 1.7) * 0.28);
node += smoothstep(0.06, 0.0, length(p - c));
}
vec3 base = vec3(0.014, 0.020, 0.050);
vec3 cyan = vec3(0.08, 0.80, 1.00);
vec3 violet = vec3(0.62, 0.16, 1.00);
vec3 col = base + cyan * glow * 0.45 * u_intensity + violet * node * 0.20;
gl_FragColor = vec4(col, 0.86) * color;
}
"#;
pub const RIPPLE_FRAGMENT: &str = r#"#version 100
precision mediump float;
varying lowp vec2 uv;
varying lowp vec4 color;
uniform float u_time;
uniform vec2 u_resolution;
uniform float u_intensity;
float ring(vec2 p, vec2 c, float radius, float width) {
float d = length(p - c);
return smoothstep(width, 0.0, abs(d - radius));
}
float disk(vec2 p, vec2 c, float radius) {
return smoothstep(radius, 0.0, length(p - c));
}
void main() {
vec2 p = uv;
float t = fract(u_time * 0.62);
vec2 c1 = vec2(0.30 + sin(u_time * 0.37) * 0.09, 0.50 + cos(u_time * 0.41) * 0.08);
vec2 c2 = vec2(0.70 + cos(u_time * 0.29) * 0.11, 0.46 + sin(u_time * 0.53) * 0.10);
float r1 = ring(p, c1, t * 0.72, 0.026) * (1.0 - t);
float r2 = ring(p, c2, fract(t + 0.38) * 0.66, 0.020) * (1.0 - fract(t + 0.38));
float ink = disk(p, c1, 0.12 + t * 0.5) * 0.055 + disk(p, c2, 0.10 + fract(t + 0.38) * 0.45) * 0.045;
float border = 1.0 - smoothstep(0.0, 0.018, min(min(p.x, p.y), min(1.0 - p.x, 1.0 - p.y)));
vec3 base = vec3(0.018, 0.026, 0.055);
vec3 cyan = vec3(0.12, 0.82, 1.0);
vec3 violet = vec3(0.72, 0.20, 1.0);
vec3 col = base + cyan * r1 * u_intensity + violet * r2 * 0.72 * u_intensity + cyan * border * 0.22 + vec3(ink);
gl_FragColor = vec4(col, 0.82) * color;
}
"#;
pub const BLOOM_GLOW_FRAGMENT: &str = r#"#version 100
precision mediump float;
varying lowp vec2 uv;
varying lowp vec4 color;
uniform float u_time;
uniform vec2 u_resolution;
uniform float u_intensity;
float blob(vec2 p, vec2 c, float radius) {
float d = length(p - c);
return radius * radius / max(d * d, 0.001);
}
void main() {
vec2 p = uv;
float t = u_time;
float glow = 0.0;
glow += blob(p, vec2(0.22 + sin(t * 0.7) * 0.12, 0.34 + cos(t * 0.6) * 0.08), 0.045);
glow += blob(p, vec2(0.76 + cos(t * 0.5) * 0.10, 0.52 + sin(t * 0.9) * 0.12), 0.060);
glow += blob(p, vec2(0.50 + sin(t * 0.4) * 0.18, 0.78 + cos(t * 0.8) * 0.05), 0.038);
glow = min(glow, 3.0);
float scan = sin((p.y + t * 0.11) * 540.0) * 0.5 + 0.5;
float vignette = smoothstep(0.82, 0.12, length(p - 0.5));
vec3 base = vec3(0.010, 0.014, 0.030);
vec3 hot = mix(vec3(0.10, 0.55, 1.0), vec3(0.95, 0.18, 1.0), p.x);
vec3 col = base + hot * glow * 0.23 * u_intensity + vec3(scan * 0.018);
col *= 0.62 + vignette * 0.72;
gl_FragColor = vec4(col, 0.78) * color;
}
"#;
pub const CODE_LENS_FRAGMENT: &str = r#"#version 100
precision mediump float;
varying lowp vec2 uv;
varying lowp vec4 color;
uniform float u_time;
uniform vec2 u_resolution;
uniform float u_intensity;
float hash(vec2 p) {
return fract(sin(dot(p, vec2(101.7, 203.3))) * 43758.5453);
}
float line_y(float y, float target, float width) {
return smoothstep(width, 0.0, abs(y - target));
}
void main() {
vec2 p = uv;
float lens = smoothstep(0.38, 0.0, length((p - vec2(0.5, 0.52)) * vec2(1.0, 1.8)));
float code = 0.0;
for (int i = 0; i < 18; i++) {
float fi = float(i);
float y = 0.08 + fi * 0.048;
float len = 0.2 + hash(vec2(fi, 1.0)) * 0.58;
float start = 0.08 + hash(vec2(fi, 2.0)) * 0.18;
float seg = smoothstep(start, start + 0.018, p.x) * smoothstep(start + len, start + len - 0.018, p.x);
code += line_y(p.y, y + sin(u_time * 0.9 + fi) * 0.003, 0.004 + lens * 0.006) * seg;
}
float cursor = smoothstep(0.015, 0.0, abs(p.x - (0.16 + fract(u_time * 0.11) * 0.68))) * line_y(p.y, 0.52, 0.022);
vec3 base = vec3(0.012, 0.017, 0.034);
vec3 text = vec3(0.52, 0.85, 1.0);
vec3 lens_col = vec3(0.18, 0.58, 1.0) * lens * 0.18;
vec3 col = base + text * code * (0.22 + lens * 0.50) * u_intensity + lens_col + vec3(0.9, 0.6, 0.2) * cursor * 0.6;
gl_FragColor = vec4(col, 0.86) * color;
}
"#;
pub const REACTION_DIFFUSION_FRAGMENT: &str = r#"#version 100
precision mediump float;
varying lowp vec2 uv;
varying lowp vec4 color;
uniform float u_time;
uniform vec2 u_resolution;
uniform float u_intensity;
float hash(vec2 p) {
return fract(sin(dot(p, vec2(17.17, 313.13))) * 43758.5453);
}
float n(vec2 p) {
vec2 i = floor(p);
vec2 f = fract(p);
f = f * f * (3.0 - 2.0 * f);
return mix(mix(hash(i), hash(i + vec2(1.0, 0.0)), f.x), mix(hash(i + vec2(0.0, 1.0)), hash(i + vec2(1.0, 1.0)), f.x), f.y);
}
void main() {
vec2 res = max(u_resolution.xy, vec2(1.0));
vec2 p = (gl_FragCoord.xy * 2.0 - res) / max(max(res.x, res.y), 1.0);
float t = u_time * 0.12;
float a = n(p * 4.0 + t);
float b = n(p * 9.0 - t * 1.7 + a);
float c = n(p * 19.0 + vec2(a, b) * 3.0 - t);
float cells = smoothstep(0.48, 0.54, abs(a - b) + c * 0.14);
float veins = smoothstep(0.72, 0.98, sin((a - b + c) * 18.0 + u_time));
vec3 base = vec3(0.008, 0.014, 0.028);
vec3 acid = vec3(0.30, 1.0, 0.58);
vec3 plasma = vec3(0.45, 0.18, 1.0);
vec3 col = base + acid * cells * 0.32 * u_intensity + plasma * veins * 0.26;
gl_FragColor = vec4(col, 0.80) * color;
}
"#;
pub const VORONOI_CRYSTAL_FRAGMENT: &str = r#"#version 100
precision mediump float;
varying lowp vec2 uv;
varying lowp vec4 color;
uniform float u_time;
uniform vec2 u_resolution;
uniform float u_intensity;
vec2 hash2(vec2 p) {
p = vec2(dot(p, vec2(127.1, 311.7)), dot(p, vec2(269.5, 183.3)));
return fract(sin(p) * 43758.5453);
}
void main() {
vec2 p = uv * vec2(u_resolution.x / max(u_resolution.y, 1.0), 1.0) * 8.0;
vec2 i = floor(p);
vec2 f = fract(p);
float min_d = 8.0;
float second_d = 8.0;
for (int y = -1; y <= 1; y++) {
for (int x = -1; x <= 1; x++) {
vec2 g = vec2(float(x), float(y));
vec2 o = hash2(i + g);
o = 0.5 + 0.5 * sin(u_time * 0.35 + 6.2831 * o);
float d = length(g + o - f);
if (d < min_d) {
second_d = min_d;
min_d = d;
} else if (d < second_d) {
second_d = d;
}
}
}
float edge = smoothstep(0.045, 0.0, second_d - min_d);
float facet = smoothstep(0.9, 0.0, min_d);
vec3 base = vec3(0.010, 0.012, 0.032);
vec3 cyan = vec3(0.18, 0.82, 1.0);
vec3 rose = vec3(1.0, 0.20, 0.62);
vec3 col = base + cyan * edge * 0.58 * u_intensity + rose * facet * 0.10;
gl_FragColor = vec4(col, 0.78) * color;
}
"#;
pub const PLASMA_GRAPH_FRAGMENT: &str = r#"#version 100
precision mediump float;
varying lowp vec2 uv;
varying lowp vec4 color;
uniform float u_time;
uniform vec2 u_resolution;
uniform float u_intensity;
float line(vec2 p, vec2 a, vec2 b, float w) {
vec2 pa = p - a;
vec2 ba = b - a;
float h = clamp(dot(pa, ba) / max(dot(ba, ba), 0.00001), 0.0, 1.0);
return smoothstep(w, 0.0, length(pa - ba * h));
}
void main() {
vec2 p = uv;
vec2 nodes[6];
nodes[0] = vec2(0.14, 0.25 + sin(u_time * 0.8) * 0.06);
nodes[1] = vec2(0.32, 0.68 + cos(u_time * 0.5) * 0.07);
nodes[2] = vec2(0.48, 0.36 + sin(u_time * 0.6 + 1.0) * 0.08);
nodes[3] = vec2(0.64, 0.72 + cos(u_time * 0.7 + 2.0) * 0.06);
nodes[4] = vec2(0.82, 0.30 + sin(u_time * 0.55 + 3.0) * 0.07);
nodes[5] = vec2(0.90, 0.82 + cos(u_time * 0.45 + 4.0) * 0.05);
float network = 0.0;
float sparks = 0.0;
for (int i = 0; i < 5; i++) {
vec2 a = nodes[i];
vec2 b = nodes[i + 1];
network += line(p, a, b, 0.010);
float pulse = fract(u_time * 0.22 + float(i) * 0.19);
sparks += smoothstep(0.045, 0.0, length(p - mix(a, b, pulse)));
}
for (int j = 0; j < 6; j++) {
network += smoothstep(0.055, 0.0, length(p - nodes[j])) * 0.9;
}
vec3 base = vec3(0.007, 0.010, 0.028);
vec3 blue = vec3(0.10, 0.58, 1.0);
vec3 hot = vec3(1.0, 0.36, 0.12);
vec3 col = base + blue * network * 0.34 * u_intensity + hot * sparks * 0.42;
gl_FragColor = vec4(col, 0.84) * color;
}
"#;
pub const SDF_CARD_MORPH_FRAGMENT: &str = r#"#version 100
precision mediump float;
varying lowp vec2 uv;
varying lowp vec4 color;
uniform float u_time;
uniform vec2 u_resolution;
uniform float u_intensity;
float sdRoundBox(vec2 p, vec2 b, float r) {
vec2 q = abs(p) - b + r;
return length(max(q, 0.0)) + min(max(q.x, q.y), 0.0) - r;
}
float sdCapsuleBox(vec2 p, vec2 b) {
float r = min(b.x, b.y);
return sdRoundBox(p, b, r);
}
float blobWarp(vec2 p, float t) {
float a = atan(p.y, p.x);
return sin(a * 3.0 + t * 1.7) * 0.035 + sin(a * 7.0 - t * 1.2) * 0.018;
}
float sdTicket(vec2 p, vec2 b, float r) {
float box = sdRoundBox(p, b, r);
float left = length(p - vec2(-b.x, 0.0)) - 0.115;
float right = length(p - vec2(b.x, 0.0)) - 0.115;
return max(box, -min(left, right));
}
void main() {
vec2 p = uv * 2.0 - 1.0;
p.x *= u_resolution.x / max(u_resolution.y, 1.0);
float t = u_time;
float morph = 0.5 + 0.5 * sin(t * 0.55);
float morph2 = 0.5 + 0.5 * sin(t * 0.37 + 1.8);
vec2 b = mix(vec2(0.72, 0.38), vec2(0.58, 0.58), morph2);
float card = sdRoundBox(p, b, mix(0.08, 0.24, morph));
float capsule = sdCapsuleBox(p, b * vec2(1.08, 0.72));
vec2 warped = p * (1.0 + blobWarp(p, t) * mix(0.0, 2.6, morph));
float blob = sdRoundBox(warped, b * vec2(0.96, 0.94), 0.34);
float ticket = sdTicket(p, b, 0.08);
float d = mix(card, capsule, smoothstep(0.0, 0.36, morph));
d = mix(d, blob, smoothstep(0.26, 0.76, morph));
d = mix(d, ticket, smoothstep(0.70, 1.0, morph2) * 0.45);
float fill = smoothstep(0.012, -0.006, d);
float edge = smoothstep(0.018, 0.0, abs(d));
float outer = smoothstep(0.18, 0.0, d) * smoothstep(-0.02, 0.08, d);
float grid = (sin((p.x + t * 0.05) * 42.0) * sin((p.y - t * 0.04) * 34.0)) * 0.5 + 0.5;
vec3 base = vec3(0.015, 0.020, 0.045);
vec3 fill_col = mix(vec3(0.05, 0.18, 0.45), vec3(0.22, 0.08, 0.45), morph);
vec3 rim = mix(vec3(0.10, 0.72, 1.0), vec3(0.95, 0.24, 1.0), morph2);
vec3 col = base + fill_col * fill * 0.92 + rim * edge * u_intensity + rim * outer * 0.22;
col += vec3(grid * fill * 0.025);
gl_FragColor = vec4(col, 0.92 * max(fill, outer)) * color;
}
"#;
pub const METABALL_CARD_FRAGMENT: &str = r#"#version 100
precision mediump float;
varying lowp vec2 uv;
varying lowp vec4 color;
uniform float u_time;
uniform vec2 u_resolution;
uniform float u_intensity;
float ball(vec2 p, vec2 c, float r) {
float d = length(p - c);
return r * r / max(d * d, 0.002);
}
void main() {
vec2 p = uv * 2.0 - 1.0;
p.x *= u_resolution.x / max(u_resolution.y, 1.0);
float t = u_time;
float f = 0.0;
f += ball(p, vec2(-0.48 + sin(t * 0.7) * 0.18, -0.20 + cos(t * 0.5) * 0.14), 0.34);
f += ball(p, vec2(0.30 + cos(t * 0.6) * 0.20, -0.04 + sin(t * 0.9) * 0.12), 0.38);
f += ball(p, vec2(-0.08 + sin(t * 0.4 + 2.0) * 0.16, 0.32 + cos(t * 0.8) * 0.12), 0.32);
f += ball(p, vec2(0.58 + sin(t * 0.55 + 1.1) * 0.10, 0.20 + cos(t * 0.45) * 0.14), 0.24);
float surface = smoothstep(1.08, 1.16, f);
float edge = smoothstep(1.05, 1.22, f) - smoothstep(1.24, 1.42, f);
float core = smoothstep(1.8, 3.0, f);
vec3 base = vec3(0.005, 0.010, 0.026);
vec3 cyan = vec3(0.08, 0.82, 1.0);
vec3 pink = vec3(1.0, 0.16, 0.72);
vec3 amber = vec3(1.0, 0.58, 0.08);
vec3 col = base + mix(cyan, pink, uv.x) * surface * 0.54 * u_intensity + amber * edge * 0.45 + vec3(core * 0.18);
gl_FragColor = vec4(col, 0.88 * max(surface, edge)) * color;
}
"#;
pub const GOOGLE_AURA_FRAGMENT: &str = r#"#version 100
precision mediump float;
varying lowp vec2 uv;
varying lowp vec4 color;
uniform float u_time;
uniform vec2 u_resolution;
uniform float u_intensity;
float hash(vec2 p) { return fract(sin(dot(p, vec2(37.2, 171.9))) * 43758.5453); }
float noise(vec2 p) {
vec2 i = floor(p);
vec2 f = fract(p);
f = f * f * (3.0 - 2.0 * f);
return mix(mix(hash(i), hash(i + vec2(1.0, 0.0)), f.x), mix(hash(i + vec2(0.0, 1.0)), hash(i + vec2(1.0, 1.0)), f.x), f.y);
}
void main() {
vec2 p = uv - 0.5;
p.x *= u_resolution.x / max(u_resolution.y, 1.0);
float t = u_time * 0.16;
float n = noise(p * 3.0 + t) * 0.5 + noise(p * 7.0 - t * 1.7) * 0.3 + noise(p * 15.0 + t * 2.1) * 0.2;
float angle = atan(p.y, p.x) / 6.2831853 + 0.5 + n * 0.18 + t * 0.25;
vec3 blue = vec3(0.10, 0.42, 1.0);
vec3 red = vec3(1.0, 0.20, 0.12);
vec3 yellow = vec3(1.0, 0.74, 0.08);
vec3 green = vec3(0.10, 0.72, 0.28);
vec3 a = mix(blue, red, smoothstep(0.0, 0.35, fract(angle)));
vec3 b = mix(yellow, green, smoothstep(0.35, 1.0, fract(angle)));
vec3 hue = mix(a, b, smoothstep(0.25, 0.8, n));
float d = length(p);
float aura = smoothstep(0.72, 0.08, d + n * 0.12);
float ring = smoothstep(0.018, 0.0, abs(d - (0.26 + sin(u_time * 0.8) * 0.035 + n * 0.06)));
vec3 col = hue * aura * (0.36 + u_intensity * 0.44) + vec3(ring) * 0.32;
gl_FragColor = vec4(col, 0.78 * aura) * color;
}
"#;
pub const ORBITAL_MESH_FRAGMENT: &str = r#"#version 100
precision mediump float;
varying lowp vec2 uv;
varying lowp vec4 color;
uniform float u_time;
uniform vec2 u_resolution;
uniform float u_intensity;
float seg(vec2 p, vec2 a, vec2 b, float w) {
vec2 pa = p - a;
vec2 ba = b - a;
float h = clamp(dot(pa, ba) / max(dot(ba, ba), 0.00001), 0.0, 1.0);
return smoothstep(w, 0.0, length(pa - ba * h));
}
vec2 orbit(float i, float t, float r) {
return vec2(cos(t + i * 1.047), sin(t * 0.83 + i * 1.618)) * r;
}
void main() {
vec2 p = uv * 2.0 - 1.0;
p.x *= u_resolution.x / max(u_resolution.y, 1.0);
float t = u_time * 0.55;
vec2 n0 = orbit(0.0, t, 0.52);
vec2 n1 = orbit(1.0, t, 0.48);
vec2 n2 = orbit(2.0, t, 0.56);
vec2 n3 = orbit(3.0, t, 0.42);
vec2 n4 = orbit(4.0, t, 0.50);
float network = 0.0;
network += seg(p, n0, n1, 0.009);
network += seg(p, n1, n2, 0.009);
network += seg(p, n2, n3, 0.009);
network += seg(p, n3, n4, 0.009);
network += seg(p, n4, n0, 0.009);
network += smoothstep(0.055, 0.0, length(p - n0));
network += smoothstep(0.055, 0.0, length(p - n1));
network += smoothstep(0.055, 0.0, length(p - n2));
network += smoothstep(0.055, 0.0, length(p - n3));
network += smoothstep(0.055, 0.0, length(p - n4));
float halo = smoothstep(0.75, 0.10, length(p));
vec3 col = vec3(0.006, 0.012, 0.032) + vec3(0.10, 0.72, 1.0) * network * 0.38 * u_intensity + vec3(0.75, 0.2, 1.0) * halo * 0.08;
gl_FragColor = vec4(col, 0.84) * color;
}
"#;
pub const GLASS_CAUSTIC_FRAGMENT: &str = r#"#version 100
precision mediump float;
varying lowp vec2 uv;
varying lowp vec4 color;
uniform float u_time;
uniform vec2 u_resolution;
uniform float u_intensity;
float wave(vec2 p, float t) {
return sin(p.x * 18.0 + t) + sin(p.y * 21.0 - t * 1.2) + sin((p.x + p.y) * 15.0 + t * 0.7);
}
void main() {
vec2 p = uv;
float t = u_time * 0.7;
float c = wave(p, t);
float c2 = wave(p + vec2(c * 0.018, -c * 0.014), -t * 0.8);
float caustic = smoothstep(1.7, 2.7, c2);
float edge = 1.0 - smoothstep(0.0, 0.018, min(min(p.x, p.y), min(1.0 - p.x, 1.0 - p.y)));
float glare = smoothstep(0.02, 0.0, abs(p.y - (0.22 + sin(t) * 0.04))) * smoothstep(0.15, 0.75, p.x) * smoothstep(0.95, 0.45, p.x);
vec3 glass = vec3(0.040, 0.070, 0.120);
vec3 cyan = vec3(0.34, 0.88, 1.0);
vec3 col = glass + cyan * caustic * 0.22 * u_intensity + vec3(glare * 0.22) + cyan * edge * 0.24;
gl_FragColor = vec4(col, 0.62) * color;
}
"#;
pub const LIQUID_CHROME_FRAGMENT: &str = r#"#version 100
precision mediump float;
varying lowp vec2 uv;
varying lowp vec4 color;
uniform float u_time;
uniform vec2 u_resolution;
uniform float u_intensity;
float hash(vec2 p) { return fract(sin(dot(p, vec2(93.1, 67.7))) * 43758.5453); }
float noise(vec2 p) {
vec2 i = floor(p);
vec2 f = fract(p);
f = f * f * (3.0 - 2.0 * f);
return mix(mix(hash(i), hash(i + vec2(1.0, 0.0)), f.x), mix(hash(i + vec2(0.0, 1.0)), hash(i + vec2(1.0, 1.0)), f.x), f.y);
}
void main() {
vec2 p = uv * 2.0 - 1.0;
p.x *= u_resolution.x / max(u_resolution.y, 1.0);
float t = u_time * 0.18;
vec2 q = p;
q += vec2(noise(p * 2.0 + t), noise(p * 2.0 - t)) * 0.22;
float bands = sin(q.x * 12.0 + noise(q * 5.0) * 5.0 + u_time) * 0.5 + 0.5;
float spec = pow(smoothstep(0.62, 1.0, bands), 5.0);
float body = smoothstep(0.72, 0.12, length(p));
vec3 cold = vec3(0.18, 0.42, 0.88);
vec3 warm = vec3(1.0, 0.55, 0.22);
vec3 chrome = mix(cold, warm, bands);
vec3 col = chrome * body * (0.22 + u_intensity * 0.30) + vec3(spec * 0.52);
gl_FragColor = vec4(col, 0.82 * body) * color;
}
"#;
pub const AISLING_BLACKHOLE_FRAGMENT: &str = r#"#version 100
precision mediump float;
varying lowp vec2 uv;
varying lowp vec4 color;
uniform float u_time;
uniform vec2 u_resolution;
uniform float u_intensity;
float hash(vec2 p) {
p = fract(p * vec2(123.34, 345.45));
p += dot(p, p + 34.23);
return fract(p.x * p.y);
}
void main() {
vec2 res = max(u_resolution.xy, vec2(1.0));
vec2 p = (gl_FragCoord.xy * 2.0 - res) / max(max(res.x, res.y), 1.0);
float t = u_time * 0.42;
float d = length(p);
float a = atan(p.y, p.x);
float swirl = sin(a * 4.0 - t * 4.0 + 1.0 / max(d, 0.035));
float accretion = smoothstep(0.030, 0.0, abs(d - (0.34 + swirl * 0.030))) * smoothstep(0.95, 0.10, d);
accretion += smoothstep(0.018, 0.0, abs(d - (0.54 + sin(a * 2.0 + t) * 0.045))) * 0.62;
float horizon = smoothstep(0.155, 0.115, d);
float lens = (smoothstep(0.80, 0.16, d) - smoothstep(0.24, 0.10, d)) * (0.42 + 0.58 * abs(swirl));
float stars = step(0.992, hash(floor(gl_FragCoord.xy / 2.0) + floor(u_time * 8.0))) * smoothstep(0.18, 1.10, d);
vec3 base = vec3(0.004, 0.006, 0.018);
vec3 violet = vec3(0.46, 0.28, 1.0);
vec3 cyan = vec3(0.08, 0.88, 1.0);
vec3 amber = vec3(1.0, 0.48, 0.12);
vec3 col = base + violet * lens * 0.30 + cyan * accretion * 0.60 * u_intensity;
col += amber * pow(accretion, 2.0) * 0.34 + vec3(stars) * 0.72;
col = mix(col, vec3(0.0), horizon * 0.92);
gl_FragColor = vec4(col, 0.96) * color;
}
"#;
pub const AISLING_RINGS_FRAGMENT: &str = r#"#version 100
precision mediump float;
varying lowp vec2 uv;
varying lowp vec4 color;
uniform float u_time;
uniform vec2 u_resolution;
uniform float u_intensity;
float hash(float n) {
return fract(sin(n * 91.17) * 43758.5453);
}
void main() {
vec2 p = uv * 2.0 - 1.0;
p.x *= u_resolution.x / max(u_resolution.y, 1.0);
float t = u_time * 0.48;
float d = length(p * vec2(1.0, 1.85));
float bands = 0.0;
for (int i = 0; i < 6; i++) {
float fi = float(i);
float radius = 0.15 + fi * 0.115 + sin(t * 1.7 + fi) * 0.014;
bands += smoothstep(0.018, 0.0, abs(d - radius)) * (0.75 - fi * 0.075);
}
float orbit = 0.0;
for (int j = 0; j < 12; j++) {
float fj = float(j);
float angle = t * (0.8 + hash(fj) * 1.5) + fj * 0.5236;
float radius = 0.20 + hash(fj + 4.0) * 0.50;
vec2 node = vec2(cos(angle) * radius, sin(angle) * radius * 0.45);
orbit += smoothstep(0.038, 0.0, length(p - node));
}
float core = smoothstep(0.12, 0.0, length(p));
vec3 base = vec3(0.006, 0.010, 0.028);
vec3 violet = vec3(0.68, 0.30, 1.0);
vec3 mint = vec3(0.18, 1.0, 0.78);
vec3 col = base + violet * bands * 0.48 * u_intensity + mint * orbit * 0.24 + vec3(core * 0.18);
gl_FragColor = vec4(col, 0.88) * color;
}
"#;
pub const AISLING_FIREWORKS_FRAGMENT: &str = r#"#version 100
precision mediump float;
varying lowp vec2 uv;
varying lowp vec4 color;
uniform float u_time;
uniform vec2 u_resolution;
uniform float u_intensity;
float hash(vec2 p) {
return fract(sin(dot(p, vec2(127.1, 311.7))) * 43758.5453);
}
float segment(vec2 p, vec2 a, vec2 b, float w) {
vec2 pa = p - a;
vec2 ba = b - a;
float h = clamp(dot(pa, ba) / max(dot(ba, ba), 0.00001), 0.0, 1.0);
return smoothstep(w, 0.0, length(pa - ba * h));
}
void main() {
vec2 p = uv * 2.0 - 1.0;
p.x *= u_resolution.x / max(u_resolution.y, 1.0);
float t = u_time * 0.22;
float fire = 0.0;
vec3 sparks = vec3(0.0);
vec2 launcher = vec2(0.0, -1.05);
for (int i = 0; i < 7; i++) {
float fi = float(i);
float phase = fract(t + hash(vec2(fi, 3.0)));
vec2 center = vec2(mix(-0.72, 0.72, hash(vec2(fi, 4.0))), mix(-0.18, 0.68, hash(vec2(fi, 5.0))));
float lift = (1.0 - smoothstep(0.18, 0.38, phase)) * smoothstep(0.0, 0.20, phase);
fire += segment(p, launcher, mix(launcher, center, smoothstep(0.0, 0.35, phase)), 0.010) * lift;
float radius = max(phase - 0.32, 0.0) * 1.25;
float d = length(p - center);
float ring = smoothstep(0.028, 0.0, abs(d - radius)) * (1.0 - smoothstep(0.72, 1.0, phase));
float angle = atan(p.y - center.y, p.x - center.x);
float spoke = step(0.55, sin(angle * (10.0 + hash(vec2(fi, 6.0)) * 10.0) + fi) * 0.5 + 0.5);
float glitter = step(0.955, hash(floor((p - center) * 44.0) + fi + floor(u_time * 10.0)));
vec3 hue = mix(vec3(1.0, 0.42, 0.10), vec3(0.18, 0.86, 1.0), hash(vec2(fi, 7.0)));
sparks += hue * (ring * (0.35 + spoke * 0.75) + glitter * ring * 1.4);
}
vec3 base = vec3(0.004, 0.007, 0.020);
vec3 col = base + vec3(1.0, 0.70, 0.18) * fire * 0.55 + sparks * u_intensity;
gl_FragColor = vec4(col, 0.90) * color;
}
"#;
pub const AISLING_LASER_ETCH_FRAGMENT: &str = r#"#version 100
precision mediump float;
varying lowp vec2 uv;
varying lowp vec4 color;
uniform float u_time;
uniform vec2 u_resolution;
uniform float u_intensity;
float hash(vec2 p) {
return fract(sin(dot(p, vec2(83.7, 217.3))) * 43758.5453);
}
void main() {
vec2 p = uv;
float scan = fract(u_time * 0.18) * 2.35 - 0.20;
float diag = p.x + p.y;
float beam = smoothstep(0.032, 0.0, abs(diag - scan));
float trail = smoothstep(0.28, 0.0, scan - diag) * step(diag, scan);
float vertical = smoothstep(0.020, 0.0, abs(p.x - fract(u_time * 0.32)));
float etched = smoothstep(0.010, 0.0, abs(fract((p.x + p.y) * 36.0) - 0.5)) * trail;
float spark = step(0.972, hash(floor(p * vec2(64.0, 32.0)) + floor(u_time * 18.0))) * smoothstep(0.075, 0.0, abs(diag - scan));
float heat = smoothstep(0.0, 0.18, trail) * (1.0 - smoothstep(0.20, 0.62, trail));
vec3 base = vec3(0.014, 0.012, 0.024);
vec3 red = vec3(1.0, 0.14, 0.06);
vec3 gold = vec3(1.0, 0.78, 0.18);
vec3 green = vec3(0.24, 1.0, 0.62);
vec3 col = base + red * beam * 0.92 * u_intensity + gold * spark * 0.85;
col += mix(red, green, trail) * etched * 0.34 + green * vertical * 0.16 + red * heat * 0.16;
gl_FragColor = vec4(col, 0.88) * color;
}
"#;
pub const AISLING_BEAMS_FRAGMENT: &str = r#"#version 100
precision mediump float;
varying lowp vec2 uv;
varying lowp vec4 color;
uniform float u_time;
uniform vec2 u_resolution;
uniform float u_intensity;
float line(vec2 p, vec2 a, vec2 b, float w) {
vec2 pa = p - a;
vec2 ba = b - a;
float h = clamp(dot(pa, ba) / max(dot(ba, ba), 0.00001), 0.0, 1.0);
return smoothstep(w, 0.0, length(pa - ba * h));
}
void main() {
vec2 p = uv;
float t = u_time;
float vx = fract(t * 0.18);
float hy = fract(t * 0.13 + 0.31);
float beam = smoothstep(0.020, 0.0, abs(p.x - vx));
beam += smoothstep(0.018, 0.0, abs(p.y - hy));
for (int i = 0; i < 4; i++) {
float fi = float(i);
float shift = fract(t * (0.07 + fi * 0.015) + fi * 0.23) * 1.45 - 0.22;
beam += line(p, vec2(-0.08, shift), vec2(1.08, shift - 0.58 + fi * 0.18), 0.010) * 0.62;
}
float cross = smoothstep(0.065, 0.0, length(p - vec2(vx, hy)));
float scan = sin((p.y + t * 0.10) * 480.0) * 0.5 + 0.5;
vec3 base = vec3(0.010, 0.018, 0.042);
vec3 cyan = vec3(0.10, 0.78, 1.0);
vec3 amber = vec3(1.0, 0.72, 0.18);
vec3 col = base + cyan * beam * 0.38 * u_intensity + amber * cross * 0.45 + vec3(scan * 0.012);
gl_FragColor = vec4(col, 0.86) * color;
}
"#;
pub const AISLING_SYNTH_GRID_FRAGMENT: &str = r#"#version 100
precision mediump float;
varying lowp vec2 uv;
varying lowp vec4 color;
uniform float u_time;
uniform vec2 u_resolution;
uniform float u_intensity;
float grid_line(float value, float width) {
return smoothstep(width, 0.0, abs(fract(value) - 0.5));
}
void main() {
vec2 p = uv * 2.0 - 1.0;
p.x *= u_resolution.x / max(u_resolution.y, 1.0);
float t = u_time * 0.28;
float depth = max(0.04, p.y + 0.92);
float perspective = 1.0 / depth;
float horizon = smoothstep(0.08, 0.0, abs(p.y + 0.18));
float verticals = grid_line(p.x * perspective * 3.5, 0.030) * smoothstep(-0.22, 0.85, p.y);
float horizontals = grid_line(perspective * 1.65 - t * 2.2, 0.020) * smoothstep(-0.22, 0.90, p.y);
float diagonal = grid_line((uv.x + uv.y) * 9.0 + t * 2.0, 0.018) * 0.32;
float pulse = sin(length(p * vec2(1.0, 1.9)) * 13.0 - u_time * 4.0) * 0.5 + 0.5;
float grid = (verticals + horizontals + diagonal) * (0.62 + pulse * 0.38);
vec3 base = mix(vec3(0.010, 0.006, 0.030), vec3(0.025, 0.014, 0.060), uv.y);
vec3 magenta = vec3(1.0, 0.18, 0.86);
vec3 cyan = vec3(0.04, 0.94, 1.0);
vec3 col = base + mix(magenta, cyan, uv.y) * grid * 0.44 * u_intensity + magenta * horizon * 0.25;
gl_FragColor = vec4(col, 0.88) * color;
}
"#;
pub const AISLING_SPOTLIGHTS_FRAGMENT: &str = r#"#version 100
precision mediump float;
varying lowp vec2 uv;
varying lowp vec4 color;
uniform float u_time;
uniform vec2 u_resolution;
uniform float u_intensity;
void main() {
vec2 p = uv * 2.0 - 1.0;
p.x *= u_resolution.x / max(u_resolution.y, 1.0);
float t = u_time * 0.55;
float light = 0.0;
for (int i = 0; i < 3; i++) {
float fi = float(i);
float angle = t + fi * 2.094;
vec2 center = vec2(cos(angle) * (0.36 - fi * 0.03), sin(angle * 0.84) * (0.30 + fi * 0.04));
float radius = 0.38 + 0.04 * sin(t * 1.7 + fi);
light = max(light, smoothstep(radius, 0.0, length(p - center)));
}
float reveal = smoothstep(-0.12, 0.88, uv.x + sin(u_time * 0.25) * 0.12);
float grain = sin((uv.y + u_time * 0.04) * 520.0) * 0.5 + 0.5;
vec3 base = vec3(0.012, 0.014, 0.027);
vec3 warm = vec3(1.0, 0.92, 0.58);
vec3 blue = vec3(0.12, 0.54, 1.0);
vec3 col = base + warm * light * (0.30 + u_intensity * 0.36) + blue * reveal * 0.07 + vec3(grain * light * 0.020);
gl_FragColor = vec4(col, 0.86) * color;
}
"#;
pub const AISLING_SWARM_FRAGMENT: &str = r#"#version 100
precision mediump float;
varying lowp vec2 uv;
varying lowp vec4 color;
uniform float u_time;
uniform vec2 u_resolution;
uniform float u_intensity;
float hash(float n) {
return fract(sin(n * 113.7) * 43758.5453);
}
void main() {
vec2 p = uv;
p.x *= u_resolution.x / max(u_resolution.y, 1.0);
float t = u_time;
float glow = 0.0;
float dots = 0.0;
vec3 chroma = vec3(0.0);
for (int i = 0; i < 44; i++) {
float fi = float(i);
float h = hash(fi);
float cursor = fract(t * 0.055 + h);
vec2 target = vec2(cursor * u_resolution.x / max(u_resolution.y, 1.0), 0.52 + sin(t * 0.55 + fi) * 0.11);
float angle = t * (0.9 + h * 1.7) + fi * 0.61;
float radius = 0.035 + hash(fi + 9.0) * 0.22;
vec2 node = target + vec2(cos(angle) * radius, sin(angle) * radius * 0.52);
float d = length(p - node);
float particle = smoothstep(0.020, 0.0, d);
glow += 0.0018 / (d * d + 0.0012);
dots += particle;
chroma += mix(vec3(0.10, 1.0, 0.64), vec3(1.0, 0.18, 0.86), h) * particle;
}
glow = min(glow, 3.0);
vec3 base = vec3(0.006, 0.012, 0.028);
vec3 col = base + chroma * 0.42 * u_intensity + vec3(0.06, 0.45, 1.0) * glow * 0.08;
col += vec3(dots * 0.018);
gl_FragColor = vec4(col, 0.86) * color;
}
"#;
pub const AISLING_STORM_FRAGMENT: &str = r#"#version 100
precision mediump float;
varying lowp vec2 uv;
varying lowp vec4 color;
uniform float u_time;
uniform vec2 u_resolution;
uniform float u_intensity;
float hash(vec2 p) {
return fract(sin(dot(p, vec2(29.1, 173.7))) * 43758.5453);
}
void main() {
vec2 cell = floor(gl_FragCoord.xy / vec2(7.0, 14.0));
float column = hash(vec2(cell.x, 1.0));
float speed = mix(0.7, 2.8, column);
float fall = fract(cell.y * 0.12 - u_time * speed + column * 8.0);
float rain = smoothstep(0.92, 1.0, fall) + smoothstep(0.35, 0.0, fall) * 0.35;
float flash_seed = hash(vec2(floor(u_time * 1.4), 8.0));
float flash = step(0.78, flash_seed) * smoothstep(0.42, 1.0, sin(fract(u_time * 1.4) * 3.14159));
float bolt_x = 0.18 + 0.64 * hash(vec2(floor(u_time * 1.4), 4.0));
float jag = sin(uv.y * 34.0 + floor(u_time * 1.4) * 2.7) * 0.030 + sin(uv.y * 79.0) * 0.014;
float bolt = smoothstep(0.018, 0.0, abs(uv.x - bolt_x - jag)) * flash;
float cloud = smoothstep(0.72, 0.18, uv.y) * (0.5 + 0.5 * sin(uv.x * 12.0 + u_time));
vec3 base = vec3(0.007, 0.011, 0.026);
vec3 rain_col = vec3(0.28, 0.62, 1.0);
vec3 bolt_col = vec3(1.0, 0.96, 0.62);
vec3 col = base + rain_col * rain * 0.24 * u_intensity + vec3(cloud * 0.035);
col += bolt_col * bolt * (0.9 + u_intensity * 0.4) + vec3(flash * 0.10);
gl_FragColor = vec4(col, 0.88) * color;
}
"#;
pub const AISLING_VHS_FRAGMENT: &str = r#"#version 100
precision mediump float;
varying lowp vec2 uv;
varying lowp vec4 color;
uniform float u_time;
uniform vec2 u_resolution;
uniform float u_intensity;
float hash(vec2 p) {
return fract(sin(dot(p, vec2(101.3, 241.9))) * 43758.5453);
}
void main() {
float row = floor(uv.y * 96.0);
float tick = floor(u_time * 18.0);
float row_noise = hash(vec2(row, tick)) - 0.5;
float instability = 0.35 + 0.65 * (sin(u_time * 0.9) * 0.5 + 0.5);
float offset = row_noise * 0.085 * instability;
vec2 q = vec2(fract(uv.x + offset), uv.y);
float scan = sin(q.y * 920.0) * 0.5 + 0.5;
float tracking = step(0.972, hash(vec2(row, floor(u_time * 5.0)))) * smoothstep(0.02, 0.0, abs(fract(q.y * 12.0 + u_time * 0.4) - 0.5));
float blocks = step(0.965, hash(floor(q * vec2(28.0, 18.0)) + tick));
float signal = smoothstep(0.44, 0.0, abs(fract(q.x * 9.0 + floor(q.y * 14.0) * 0.11) - 0.5));
vec3 base = vec3(0.013, 0.015, 0.032);
vec3 col = base + vec3(0.12, 0.26, 0.46) * signal * 0.20;
col.r += signal * 0.10 + blocks * 0.24;
col.g += signal * 0.08;
col.b += scan * 0.035 + tracking * 0.42 * u_intensity;
col += vec3(blocks * 0.08 * u_intensity);
gl_FragColor = vec4(col, 0.84) * color;
}
"#;
pub const AISLING_WAVES_FRAGMENT: &str = r#"#version 100
precision mediump float;
varying lowp vec2 uv;
varying lowp vec4 color;
uniform float u_time;
uniform vec2 u_resolution;
uniform float u_intensity;
void main() {
vec2 p = uv;
float t = u_time * 0.62;
float waves = 0.0;
float foam = 0.0;
for (int i = 0; i < 8; i++) {
float fi = float(i);
float y = 0.10 + fi * 0.105 + sin(p.x * (7.0 + fi * 0.55) + t * (1.0 + fi * 0.13) + fi) * 0.045;
float line = smoothstep(0.018, 0.0, abs(p.y - y));
waves += line * (1.0 - fi * 0.055);
foam += line * smoothstep(0.70, 1.0, sin(p.x * 32.0 + t * 4.0 + fi) * 0.5 + 0.5);
}
float sweep = smoothstep(0.16, 0.0, abs(p.x - fract(u_time * 0.16))) * smoothstep(0.05, 0.85, p.y);
vec3 base = vec3(0.004, 0.018, 0.036);
vec3 deep = vec3(0.04, 0.30, 0.72);
vec3 cyan = vec3(0.14, 0.88, 1.0);
vec3 col = base + deep * waves * 0.22 * u_intensity + cyan * foam * 0.26 + cyan * sweep * 0.12;
gl_FragColor = vec4(col, 0.84) * color;
}
"#;
pub const AISLING_VORTEX_FRAGMENT: &str = r#"#version 100
precision mediump float;
varying lowp vec2 uv;
varying lowp vec4 color;
uniform float u_time;
uniform vec2 u_resolution;
uniform float u_intensity;
float hash(vec2 p) {
return fract(sin(dot(p, vec2(59.7, 337.1))) * 43758.5453);
}
void main() {
vec2 p = uv * 2.0 - 1.0;
p.x *= u_resolution.x / max(u_resolution.y, 1.0);
float d = length(p);
float a = atan(p.y, p.x);
float t = u_time * 0.78;
float arms = sin(a * 5.0 - d * 14.0 + t * 3.0) * 0.5 + 0.5;
float spiral = smoothstep(0.66, 1.0, arms) * smoothstep(1.15, 0.08, d);
float polar = step(0.86, hash(vec2(floor(a * 18.0), floor(d * 22.0 - t * 4.0)))) * smoothstep(0.96, 0.15, d);
float core = smoothstep(0.11, 0.0, d);
vec3 base = vec3(0.006, 0.009, 0.026);
vec3 cyan = vec3(0.10, 0.95, 1.0);
vec3 violet = vec3(0.75, 0.18, 1.0);
vec3 col = base + mix(violet, cyan, arms) * spiral * 0.44 * u_intensity + cyan * polar * 0.28 + vec3(core * 0.16);
gl_FragColor = vec4(col, 0.88) * color;
}
"#;
pub const AISLING_CASCADE_FRAGMENT: &str = r#"#version 100
precision mediump float;
varying lowp vec2 uv;
varying lowp vec4 color;
uniform float u_time;
uniform vec2 u_resolution;
uniform float u_intensity;
float hash(vec2 p) {
return fract(sin(dot(p, vec2(17.9, 211.3))) * 43758.5453);
}
void main() {
vec2 cell = floor(gl_FragCoord.xy / vec2(9.0, 16.0));
vec2 local = fract(gl_FragCoord.xy / vec2(9.0, 16.0));
float column = hash(vec2(cell.x, 0.0));
float speed = mix(0.45, 1.55, column);
float head = fract(cell.y * 0.075 - u_time * speed + column * 6.0);
float drop = smoothstep(0.94, 1.0, head) * smoothstep(0.45, 0.0, length(local - 0.5));
float trail = smoothstep(0.56, 0.08, head) * smoothstep(0.09, 0.0, abs(local.x - 0.5)) * 0.55;
float surface = smoothstep(0.020, 0.0, abs(uv.y - (0.80 + sin(uv.x * 14.0 + u_time) * 0.025)));
vec3 base = vec3(0.006, 0.014, 0.032);
vec3 blue = vec3(0.18, 0.58, 1.0);
vec3 mint = vec3(0.16, 1.0, 0.72);
vec3 col = base + blue * trail * 0.28 + mint * drop * 0.72 * u_intensity + blue * surface * 0.22;
gl_FragColor = vec4(col, 0.82) * color;
}
"#;
pub const AISLING_GRID_PULSE_FRAGMENT: &str = r#"#version 100
precision mediump float;
varying lowp vec2 uv;
varying lowp vec4 color;
uniform float u_time;
uniform vec2 u_resolution;
uniform float u_intensity;
float hash(vec2 p) {
return fract(sin(dot(p, vec2(43.1, 97.7))) * 43758.5453);
}
void main() {
vec2 scale = vec2(24.0, 14.0);
vec2 g = uv * scale;
vec2 id = floor(g);
vec2 local = fract(g) - 0.5;
vec2 center = scale * 0.5 + vec2(sin(u_time * 0.33), cos(u_time * 0.27)) * 2.2;
float dist = length(id - center);
float wave = sin(dist * 0.82 - u_time * 4.0 + hash(id) * 2.0) * 0.5 + 0.5;
float dot = smoothstep(0.15, 0.0, length(local));
float alive = step(0.22, hash(id + floor(u_time * 2.0)));
float pulse = dot * alive * smoothstep(0.42, 1.0, wave);
float grid = smoothstep(0.018, 0.0, min(abs(local.x), abs(local.y)));
vec3 base = vec3(0.006, 0.010, 0.030);
vec3 cyan = vec3(0.10, 0.86, 1.0);
vec3 pink = vec3(1.0, 0.18, 0.76);
vec3 col = base + mix(cyan, pink, uv.x) * pulse * 0.72 * u_intensity + cyan * grid * 0.045;
gl_FragColor = vec4(col, 0.84) * color;
}
"#;
pub fn background_shader() -> ShaderSource {
ShaderSource {
name: "rae-background-curl-nebula",
vertex: VERTEX,
fragment: BACKGROUND_FRAGMENT,
uniforms: COMMON_UNIFORMS,
}
}
pub fn pane_shader() -> ShaderSource {
ShaderSource {
name: "rae-pane-hex-lattice",
vertex: VERTEX,
fragment: PANE_FRAGMENT,
uniforms: COMMON_UNIFORMS,
}
}
pub fn prompt_shader() -> ShaderSource {
ShaderSource {
name: "rae-prompt-beam-field",
vertex: VERTEX,
fragment: PROMPT_FRAGMENT,
uniforms: COMMON_UNIFORMS,
}
}
pub fn aurora_shader() -> ShaderSource {
ShaderSource {
name: "rae-background-aurora-curtains",
vertex: VERTEX,
fragment: AURORA_FRAGMENT,
uniforms: COMMON_UNIFORMS,
}
}
pub fn knot_field_shader() -> ShaderSource {
ShaderSource {
name: "rae-knot-raymarch-field",
vertex: VERTEX,
fragment: KNOT_FIELD_FRAGMENT,
uniforms: COMMON_UNIFORMS,
}
}
pub fn terminal_rain_shader() -> ShaderSource {
ShaderSource {
name: "rae-terminal-rain",
vertex: VERTEX,
fragment: TERMINAL_RAIN_FRAGMENT,
uniforms: COMMON_UNIFORMS,
}
}
pub fn flow_beams_shader() -> ShaderSource {
ShaderSource {
name: "rae-flow-beams",
vertex: VERTEX,
fragment: FLOW_BEAMS_FRAGMENT,
uniforms: COMMON_UNIFORMS,
}
}
pub fn ripple_shader() -> ShaderSource {
ShaderSource {
name: "rae-interaction-ripples",
vertex: VERTEX,
fragment: RIPPLE_FRAGMENT,
uniforms: COMMON_UNIFORMS,
}
}
pub fn bloom_glow_shader() -> ShaderSource {
ShaderSource {
name: "rae-bloom-glow-field",
vertex: VERTEX,
fragment: BLOOM_GLOW_FRAGMENT,
uniforms: COMMON_UNIFORMS,
}
}
pub fn code_lens_shader() -> ShaderSource {
ShaderSource {
name: "rae-code-lens-scan",
vertex: VERTEX,
fragment: CODE_LENS_FRAGMENT,
uniforms: COMMON_UNIFORMS,
}
}
pub fn reaction_diffusion_shader() -> ShaderSource {
ShaderSource {
name: "rae-reaction-diffusion",
vertex: VERTEX,
fragment: REACTION_DIFFUSION_FRAGMENT,
uniforms: COMMON_UNIFORMS,
}
}
pub fn voronoi_crystal_shader() -> ShaderSource {
ShaderSource {
name: "rae-voronoi-crystal",
vertex: VERTEX,
fragment: VORONOI_CRYSTAL_FRAGMENT,
uniforms: COMMON_UNIFORMS,
}
}
pub fn plasma_graph_shader() -> ShaderSource {
ShaderSource {
name: "rae-plasma-graph",
vertex: VERTEX,
fragment: PLASMA_GRAPH_FRAGMENT,
uniforms: COMMON_UNIFORMS,
}
}
pub fn sdf_card_morph_shader() -> ShaderSource {
ShaderSource {
name: "rae-sdf-card-morph",
vertex: VERTEX,
fragment: SDF_CARD_MORPH_FRAGMENT,
uniforms: COMMON_UNIFORMS,
}
}
pub fn metaball_card_shader() -> ShaderSource {
ShaderSource {
name: "rae-metaball-card",
vertex: VERTEX,
fragment: METABALL_CARD_FRAGMENT,
uniforms: COMMON_UNIFORMS,
}
}
pub fn google_aura_shader() -> ShaderSource {
ShaderSource {
name: "rae-google-aura",
vertex: VERTEX,
fragment: GOOGLE_AURA_FRAGMENT,
uniforms: COMMON_UNIFORMS,
}
}
pub fn orbital_mesh_shader() -> ShaderSource {
ShaderSource {
name: "rae-orbital-mesh",
vertex: VERTEX,
fragment: ORBITAL_MESH_FRAGMENT,
uniforms: COMMON_UNIFORMS,
}
}
pub fn glass_caustic_shader() -> ShaderSource {
ShaderSource {
name: "rae-glass-caustic",
vertex: VERTEX,
fragment: GLASS_CAUSTIC_FRAGMENT,
uniforms: COMMON_UNIFORMS,
}
}
pub fn liquid_chrome_shader() -> ShaderSource {
ShaderSource {
name: "rae-liquid-chrome",
vertex: VERTEX,
fragment: LIQUID_CHROME_FRAGMENT,
uniforms: COMMON_UNIFORMS,
}
}
pub fn aisling_blackhole_shader() -> ShaderSource {
ShaderSource {
name: "rae-aisling-blackhole",
vertex: VERTEX,
fragment: AISLING_BLACKHOLE_FRAGMENT,
uniforms: COMMON_UNIFORMS,
}
}
pub fn aisling_rings_shader() -> ShaderSource {
ShaderSource {
name: "rae-aisling-rings",
vertex: VERTEX,
fragment: AISLING_RINGS_FRAGMENT,
uniforms: COMMON_UNIFORMS,
}
}
pub fn aisling_fireworks_shader() -> ShaderSource {
ShaderSource {
name: "rae-aisling-fireworks",
vertex: VERTEX,
fragment: AISLING_FIREWORKS_FRAGMENT,
uniforms: COMMON_UNIFORMS,
}
}
pub fn aisling_laser_etch_shader() -> ShaderSource {
ShaderSource {
name: "rae-aisling-laser-etch",
vertex: VERTEX,
fragment: AISLING_LASER_ETCH_FRAGMENT,
uniforms: COMMON_UNIFORMS,
}
}
pub fn aisling_beams_shader() -> ShaderSource {
ShaderSource {
name: "rae-aisling-beams",
vertex: VERTEX,
fragment: AISLING_BEAMS_FRAGMENT,
uniforms: COMMON_UNIFORMS,
}
}
pub fn aisling_synth_grid_shader() -> ShaderSource {
ShaderSource {
name: "rae-aisling-synth-grid",
vertex: VERTEX,
fragment: AISLING_SYNTH_GRID_FRAGMENT,
uniforms: COMMON_UNIFORMS,
}
}
pub fn aisling_spotlights_shader() -> ShaderSource {
ShaderSource {
name: "rae-aisling-spotlights",
vertex: VERTEX,
fragment: AISLING_SPOTLIGHTS_FRAGMENT,
uniforms: COMMON_UNIFORMS,
}
}
pub fn aisling_swarm_shader() -> ShaderSource {
ShaderSource {
name: "rae-aisling-swarm",
vertex: VERTEX,
fragment: AISLING_SWARM_FRAGMENT,
uniforms: COMMON_UNIFORMS,
}
}
pub fn aisling_storm_shader() -> ShaderSource {
ShaderSource {
name: "rae-aisling-storm",
vertex: VERTEX,
fragment: AISLING_STORM_FRAGMENT,
uniforms: COMMON_UNIFORMS,
}
}
pub fn aisling_vhs_shader() -> ShaderSource {
ShaderSource {
name: "rae-aisling-vhs",
vertex: VERTEX,
fragment: AISLING_VHS_FRAGMENT,
uniforms: COMMON_UNIFORMS,
}
}
pub fn aisling_waves_shader() -> ShaderSource {
ShaderSource {
name: "rae-aisling-waves",
vertex: VERTEX,
fragment: AISLING_WAVES_FRAGMENT,
uniforms: COMMON_UNIFORMS,
}
}
pub fn aisling_vortex_shader() -> ShaderSource {
ShaderSource {
name: "rae-aisling-vortex",
vertex: VERTEX,
fragment: AISLING_VORTEX_FRAGMENT,
uniforms: COMMON_UNIFORMS,
}
}
pub fn aisling_cascade_shader() -> ShaderSource {
ShaderSource {
name: "rae-aisling-cascade",
vertex: VERTEX,
fragment: AISLING_CASCADE_FRAGMENT,
uniforms: COMMON_UNIFORMS,
}
}
pub fn aisling_grid_pulse_shader() -> ShaderSource {
ShaderSource {
name: "rae-aisling-grid-pulse",
vertex: VERTEX,
fragment: AISLING_GRID_PULSE_FRAGMENT,
uniforms: COMMON_UNIFORMS,
}
}
pub fn all_shaders() -> Vec<ShaderSource> {
vec![
background_shader(),
pane_shader(),
prompt_shader(),
aurora_shader(),
knot_field_shader(),
terminal_rain_shader(),
flow_beams_shader(),
ripple_shader(),
bloom_glow_shader(),
code_lens_shader(),
reaction_diffusion_shader(),
voronoi_crystal_shader(),
plasma_graph_shader(),
sdf_card_morph_shader(),
metaball_card_shader(),
google_aura_shader(),
orbital_mesh_shader(),
glass_caustic_shader(),
liquid_chrome_shader(),
aisling_blackhole_shader(),
aisling_rings_shader(),
aisling_fireworks_shader(),
aisling_laser_etch_shader(),
aisling_beams_shader(),
aisling_synth_grid_shader(),
aisling_spotlights_shader(),
aisling_swarm_shader(),
aisling_storm_shader(),
aisling_vhs_shader(),
aisling_waves_shader(),
aisling_vortex_shader(),
aisling_cascade_shader(),
aisling_grid_pulse_shader(),
]
}
pub fn shader_catalog() -> Vec<ShaderDescriptor> {
vec![
ShaderDescriptor {
source: background_shader(),
family: ShaderFamily::Background,
description: "Curl-noise nebula with ring interference for full-window depth.",
complexity: 7,
animated: true,
},
ShaderDescriptor {
source: pane_shader(),
family: ShaderFamily::Panel,
description: "Hex lattice pane surface with scanning rim light.",
complexity: 4,
animated: true,
},
ShaderDescriptor {
source: prompt_shader(),
family: ShaderFamily::Prompt,
description: "Prompt beam field with animated caret energy.",
complexity: 3,
animated: true,
},
ShaderDescriptor {
source: aurora_shader(),
family: ShaderFamily::Background,
description: "Layered aurora curtains for context and reference views.",
complexity: 5,
animated: true,
},
ShaderDescriptor {
source: knot_field_shader(),
family: ShaderFamily::Data,
description: "Raymarched torus-knot field for high-energy focus states.",
complexity: 9,
animated: true,
},
ShaderDescriptor {
source: terminal_rain_shader(),
family: ShaderFamily::Code,
description: "Terminal rain data stream for run and log surfaces.",
complexity: 3,
animated: true,
},
ShaderDescriptor {
source: flow_beams_shader(),
family: ShaderFamily::Flow,
description: "Animated routed beam network for flow and routing lanes.",
complexity: 5,
animated: true,
},
ShaderDescriptor {
source: ripple_shader(),
family: ShaderFamily::Interaction,
description: "Material-style click ripple field with two animated origins.",
complexity: 4,
animated: true,
},
ShaderDescriptor {
source: bloom_glow_shader(),
family: ShaderFamily::Interaction,
description: "Soft bloom blobs for hover, focus, and elevated surfaces.",
complexity: 4,
animated: true,
},
ShaderDescriptor {
source: code_lens_shader(),
family: ShaderFamily::Code,
description: "Code-line lens shimmer for transcript/code panes.",
complexity: 5,
animated: true,
},
ShaderDescriptor {
source: reaction_diffusion_shader(),
family: ShaderFamily::Background,
description: "Procedural reaction-diffusion cells for organic loading states.",
complexity: 6,
animated: true,
},
ShaderDescriptor {
source: voronoi_crystal_shader(),
family: ShaderFamily::Panel,
description: "Voronoi crystal facets for glassy command-palette surfaces.",
complexity: 6,
animated: true,
},
ShaderDescriptor {
source: plasma_graph_shader(),
family: ShaderFamily::Flow,
description: "Plasma graph nodes and sparks for runtime visualizers.",
complexity: 6,
animated: true,
},
ShaderDescriptor {
source: sdf_card_morph_shader(),
family: ShaderFamily::Panel,
description:
"SDF whole-card morph between rounded cards, capsules, blobs, and ticket notches.",
complexity: 8,
animated: true,
},
ShaderDescriptor {
source: metaball_card_shader(),
family: ShaderFamily::Panel,
description: "Metaball card topology that merges moving lobes into one liquid surface.",
complexity: 6,
animated: true,
},
ShaderDescriptor {
source: google_aura_shader(),
family: ShaderFamily::Interaction,
description: "Google-style multicolor aura for focus and assistant activity states.",
complexity: 6,
animated: true,
},
ShaderDescriptor {
source: orbital_mesh_shader(),
family: ShaderFamily::Flow,
description: "Orbital node mesh for runtime flow maps.",
complexity: 5,
animated: true,
},
ShaderDescriptor {
source: glass_caustic_shader(),
family: ShaderFamily::Panel,
description: "Glass caustic surface for translucent elevated cards.",
complexity: 5,
animated: true,
},
ShaderDescriptor {
source: liquid_chrome_shader(),
family: ShaderFamily::Data,
description: "Liquid chrome spectral body for high-energy hero surfaces.",
complexity: 6,
animated: true,
},
ShaderDescriptor {
source: aisling_blackhole_shader(),
family: ShaderFamily::Data,
description:
"Aisling-inspired gravity well with accretion rings and deterministic stars.",
complexity: 7,
animated: true,
},
ShaderDescriptor {
source: aisling_rings_shader(),
family: ShaderFamily::Interaction,
description:
"Aisling rings translated into elliptical orbit bands and resolving nodes.",
complexity: 5,
animated: true,
},
ShaderDescriptor {
source: aisling_fireworks_shader(),
family: ShaderFamily::Interaction,
description:
"Firework launch trails and burst rings for celebratory task completion states.",
complexity: 6,
animated: true,
},
ShaderDescriptor {
source: aisling_laser_etch_shader(),
family: ShaderFamily::Prompt,
description: "Laser etch and sweep loader translated into hot diagonal scan beams.",
complexity: 5,
animated: true,
},
ShaderDescriptor {
source: aisling_beams_shader(),
family: ShaderFamily::Flow,
description: "Crossing beam scanner based on Aisling's beams loader/effect timing.",
complexity: 4,
animated: true,
},
ShaderDescriptor {
source: aisling_synth_grid_shader(),
family: ShaderFamily::Panel,
description: "Neon synth grid with perspective pulses and diagonal loader traces.",
complexity: 5,
animated: true,
},
ShaderDescriptor {
source: aisling_spotlights_shader(),
family: ShaderFamily::Interaction,
description: "Three moving spotlights for hover, selected, and reveal choreography.",
complexity: 4,
animated: true,
},
ShaderDescriptor {
source: aisling_swarm_shader(),
family: ShaderFamily::Flow,
description: "Swarming particles following a progress cursor for busy flow states.",
complexity: 7,
animated: true,
},
ShaderDescriptor {
source: aisling_storm_shader(),
family: ShaderFamily::Background,
description:
"Thunderstorm rain, lightning, and storm-flicker field for alert surfaces.",
complexity: 5,
animated: true,
},
ShaderDescriptor {
source: aisling_vhs_shader(),
family: ShaderFamily::Code,
description: "VHS tape row jitter, tracking bands, scanlines, and block glitches.",
complexity: 5,
animated: true,
},
ShaderDescriptor {
source: aisling_waves_shader(),
family: ShaderFamily::Panel,
description: "Layered wavefronts and foam sweeps for calm loading and stream states.",
complexity: 4,
animated: true,
},
ShaderDescriptor {
source: aisling_vortex_shader(),
family: ShaderFamily::Background,
description: "Vortex loader translated into polar spiral arms and seeded particles.",
complexity: 6,
animated: true,
},
ShaderDescriptor {
source: aisling_cascade_shader(),
family: ShaderFamily::Code,
description: "Cascade loader as falling blue drops with short deterministic trails.",
complexity: 4,
animated: true,
},
ShaderDescriptor {
source: aisling_grid_pulse_shader(),
family: ShaderFamily::Data,
description: "Grid pulse loader as radial cell waves over a seeded dot matrix.",
complexity: 4,
animated: true,
},
]
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn shader_catalog_names_are_unique() {
let shaders = all_shaders();
let mut names = shaders.iter().map(|shader| shader.name).collect::<Vec<_>>();
names.sort_unstable();
names.dedup();
assert_eq!(names.len(), shaders.len());
}
#[test]
fn all_shaders_expose_common_uniforms() {
for shader in all_shaders() {
assert_eq!(shader.uniforms, COMMON_UNIFORMS);
}
}
#[test]
fn shader_descriptors_expose_single_primary_pass_stack() {
for descriptor in shader_catalog() {
let stack = descriptor.pass_stack();
let passes = stack.passes().collect::<Vec<_>>();
assert_eq!(passes.len(), 1);
assert_eq!(passes[0], descriptor.primary_pass());
assert_eq!(passes[0].role, ShaderPassRole::Primary);
}
}
#[test]
fn shader_pass_stack_compacts_and_sanitizes_public_fields() {
let descriptor = shader_catalog()[0];
let oversized = ShaderPassDescriptor::new(ShaderPassRole::Lighting, descriptor)
.with_blend(ShaderBlendMode::Screen)
.with_downsample(u8::MAX);
let stack = ShaderPassStack {
passes: [Some(oversized); MAX_SHADER_PASS_STACK],
pass_count: usize::MAX,
};
let passes = stack.passes().collect::<Vec<_>>();
assert_eq!(passes.len(), MAX_SHADER_PASS_STACK);
assert!(passes
.iter()
.all(|pass| pass.downsample <= MAX_SHADER_PASS_DOWNSAMPLE));
assert!(stack.estimated_complexity() > 0);
}
#[test]
fn shader_pass_stack_keeps_fixed_capacity() {
let descriptor = shader_catalog()[0];
let mut stack = ShaderPassStack::empty();
for _ in 0..(MAX_SHADER_PASS_STACK + 3) {
stack = stack.with_pass(
ShaderPassDescriptor::new(ShaderPassRole::Composite, descriptor)
.with_blend(ShaderBlendMode::Alpha),
);
}
assert_eq!(stack.len(), MAX_SHADER_PASS_STACK);
assert!(stack
.passes()
.all(|pass| pass.blend == ShaderBlendMode::Alpha));
}
#[test]
fn fragment_sources_match_documented_uniform_abi() {
for shader in all_shaders() {
assert!(!shader.fragment.contains("sampler2D Texture"));
assert!(shader.fragment.contains("uniform float u_time;"));
assert!(shader.fragment.contains("uniform vec2 u_resolution;"));
assert!(shader.fragment.contains("uniform float u_intensity;"));
}
}
#[test]
fn segment_helpers_guard_zero_length_denominators() {
for shader in all_shaders() {
assert!(!shader.fragment.contains("/ dot(ba, ba)"));
}
assert!(all_shaders()
.iter()
.any(|shader| shader.fragment.contains("max(dot(ba, ba), 0.00001)")));
}
#[test]
fn descriptor_catalog_matches_sources() {
let descriptors = shader_catalog();
let sources = all_shaders();
let descriptor_names = descriptors
.iter()
.map(|descriptor| descriptor.source.name)
.collect::<Vec<_>>();
let source_names = sources.iter().map(|shader| shader.name).collect::<Vec<_>>();
assert_eq!(descriptors.len(), sources.len());
assert_eq!(descriptor_names, source_names);
assert!(descriptors
.iter()
.all(|descriptor| descriptor.complexity > 0 && !descriptor.description.is_empty()));
}
}