dotfiles_chezmoi/dot_config/ghostty/shaders/iamond_teeth_cursor.glsl
2026-07-13 15:12:44 -04:00

91 lines
3.1 KiB
GLSL

#define PI 3.141592653589793
vec2 pxToNdc(vec2 p, float isPosition) {
return (p * 2.0 - iResolution.xy * isPosition) / iResolution.y;
}
float segPos(vec2 p, vec2 a, vec2 b) {
vec2 ba = b - a;
return clamp(dot(p - a, ba) / max(dot(ba, ba), 0.000001), 0.0, 1.0);
}
float segDist(vec2 p, vec2 a, vec2 b) {
float h = segPos(p, a, b);
return length(p - (a + (b - a) * h));
}
float diamond(vec2 p, vec2 c, float r) {
float d = abs(p.x - c.x) + abs(p.y - c.y);
return 1.0 - smoothstep(r * 0.25, r, d);
}
void mainImage(out vec4 fragColor, in vec2 fragCoord) {
vec2 uv = fragCoord.xy / iResolution.xy;
vec4 base = texture(iChannel0, uv);
vec3 col = base.rgb;
vec2 p = pxToNdc(fragCoord.xy, 1.0);
// Ghostty cursor rect: xy is the top-left-ish corner, zw is width/height.
vec2 curPx = vec2(
iCurrentCursor.x + iCurrentCursor.z * 0.5,
iCurrentCursor.y - iCurrentCursor.w * 0.5
);
vec2 prevPx = vec2(
iPreviousCursor.x + iPreviousCursor.z * 0.5,
iPreviousCursor.y - iPreviousCursor.w * 0.5
);
vec2 cur = pxToNdc(curPx, 1.0);
vec2 prev = pxToNdc(prevPx, 1.0);
float cell = max(0.008, max(iCurrentCursor.z, iCurrentCursor.w) * 2.0 / iResolution.y);
float age = clamp(iTime - iTimeCursorChange, 0.0, 2.0);
float pulse = exp(-age * 4.5);
float moved = smoothstep(cell * 1.2, cell * 5.0, distance(cur, prev));
// Orange-gold trail after cursor jumps.
float h = segPos(p, prev, cur);
float trailD = segDist(p, prev, cur);
float trail = (1.0 - smoothstep(cell * 0.18, cell * 0.85, trailD));
trail *= sin(h * PI) * moved * pulse;
col += trail * vec3(1.0, 0.36, 0.05) * 0.90;
// Gold glow around current cursor.
float d = length(p - cur);
float shimmer = 0.75 + 0.25 * sin(iTime * 9.0 + d * 90.0);
float glow = exp(-d / (cell * 4.0)) * 0.28 * shimmer;
col += glow * vec3(1.0, 0.62, 0.12);
// Expanding diamond ring when cursor moves.
float ringRadius = cell * (1.30 + 2.20 * pulse);
float ring = 1.0 - smoothstep(cell * 0.10, cell * 0.35, abs(d - ringRadius));
col += ring * vec3(1.0, 0.92, 0.65) * (0.42 + 0.75 * pulse);
// Tiny orbiting diamonds: pinky ring / grill sparkle.
float orbit = 0.0;
for (int k = 0; k < 8; k++) {
float fi = float(k);
float dir = mix(-1.0, 1.0, step(0.5, mod(fi, 2.0)));
float a = fi * PI * 2.0 / 8.0 + iTime * (1.5 + 0.1 * fi) * dir;
float rad = cell * (2.4 + 0.45 * sin(iTime * 2.0 + fi * 1.7));
vec2 q = cur + vec2(cos(a), sin(a)) * rad;
float tw = 0.65 + 0.35 * sin(iTime * 7.0 + fi * 2.0);
orbit += diamond(p, q, cell * 0.45) * tw;
}
col += orbit * vec3(1.0, 0.86, 0.50) * 0.70;
// Cross flare directly on cursor.
float flareX = (1.0 - smoothstep(0.0, cell * 0.035, abs(p.y - cur.y))) *
(1.0 - smoothstep(0.0, cell * 4.5, abs(p.x - cur.x)));
float flareY = (1.0 - smoothstep(0.0, cell * 0.035, abs(p.x - cur.x))) *
(1.0 - smoothstep(0.0, cell * 4.5, abs(p.y - cur.y)));
col += (flareX + flareY) * vec3(1.0, 0.92, 0.60) * 0.11;
fragColor = vec4(clamp(col, 0.0, 1.0), base.a);
}