mirror of
https://github.com/mr0xb/dotfiles_chezmoi.git
synced 2026-08-27 19:34:57 -04:00
initial commit
This commit is contained in:
commit
f1374f54c4
46 changed files with 4121 additions and 0 deletions
202
dot_config/ghostty/shaders/geocities.glsl
Normal file
202
dot_config/ghostty/shaders/geocities.glsl
Normal file
|
|
@ -0,0 +1,202 @@
|
|||
// geocities.glsl — a tribute to the golden age of blinking, tiled,
|
||||
// under-construction personal homepages. Caution-stripe wallpaper,
|
||||
// a rainbow sparkle field with hard blink (not a gentle twinkle),
|
||||
// a scrolling pixel-font "UNDER CONSTRUCTION" marquee, and a bouncing
|
||||
// rotating star badge, DVD-logo style.
|
||||
|
||||
// transparent background
|
||||
const bool transparent = true;
|
||||
|
||||
// terminal contents luminance threshold to be considered background (0.0 to 1.0)
|
||||
const float threshold = 0.02;
|
||||
|
||||
// show/hide individual gimmicks
|
||||
const bool showStripes = true;
|
||||
const bool showSparkles = true;
|
||||
const bool showMarquee = true;
|
||||
const bool showBadge = true;
|
||||
|
||||
// caution-stripe wallpaper opacity (0.0 to 1.0)
|
||||
const float stripeOpacity = 0.02;
|
||||
|
||||
// sparkle field brightness
|
||||
const float sparkleIntensity = 0.1;
|
||||
|
||||
// marquee scroll speed, in pixels per second
|
||||
const float scrollSpeed = 90.0;
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
// helpers
|
||||
// ---------------------------------------------------------------
|
||||
|
||||
float luminance(vec3 color) {
|
||||
return dot(color, vec3(0.2126, 0.7152, 0.0722));
|
||||
}
|
||||
|
||||
vec3 hsv2rgb(vec3 c) {
|
||||
vec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);
|
||||
vec3 p = abs(fract(c.xxx + K.xyz) * 6.0 - K.www);
|
||||
return c.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y);
|
||||
}
|
||||
|
||||
float hash21(vec2 p) {
|
||||
p = fract(p * vec2(233.34, 851.73));
|
||||
p += dot(p, p + 23.45);
|
||||
return fract(p.x * p.y);
|
||||
}
|
||||
|
||||
// 0 -> 1 -> 0 triangle wave, used to ping-pong the bouncing badge
|
||||
float triangleWave(float x, float period) {
|
||||
float t = fract(x / period);
|
||||
return 1.0 - abs(2.0 * t - 1.0);
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
// tiny 5x7 pixel font, just enough glyphs to spell "UNDER CONSTRUCTION"
|
||||
// each row is packed as a 5-bit value, bit weight 16 = leftmost column
|
||||
// ---------------------------------------------------------------
|
||||
|
||||
const int FONT_ROWS = 7;
|
||||
const int FONT[77] = int[77](
|
||||
0, 0, 0, 0, 0, 0, 0, // 0: space
|
||||
17, 17, 17, 17, 17, 17, 14, // 1: U
|
||||
17, 25, 21, 21, 19, 17, 17, // 2: N
|
||||
30, 17, 17, 17, 17, 17, 30, // 3: D
|
||||
31, 16, 16, 30, 16, 16, 31, // 4: E
|
||||
30, 17, 17, 30, 20, 18, 17, // 5: R
|
||||
15, 16, 16, 16, 16, 16, 15, // 6: C
|
||||
14, 17, 17, 17, 17, 17, 14, // 7: O
|
||||
15, 16, 16, 14, 1, 1, 30, // 8: S
|
||||
31, 4, 4, 4, 4, 4, 4, // 9: T
|
||||
31, 4, 4, 4, 4, 4, 31 // 10: I
|
||||
);
|
||||
|
||||
// "UNDER CONSTRUCTION" as indices into the glyph table above
|
||||
const int MSG_LEN = 18;
|
||||
const int MSG[18] = int[18](1, 2, 3, 4, 5, 0, 6, 7, 2, 8, 9, 5, 1, 6, 9, 10, 7, 2);
|
||||
|
||||
float fontBit(int code, int row, int col) {
|
||||
int rowVal = FONT[code * FONT_ROWS + row];
|
||||
float shifted = floor(float(rowVal) / pow(2.0, float(4 - col)));
|
||||
return mod(shifted, 2.0);
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
// background gimmicks
|
||||
// ---------------------------------------------------------------
|
||||
|
||||
vec3 hazardStripes(vec2 fragCoord) {
|
||||
float stripeWidth = 18.0;
|
||||
float diag = (fragCoord.x + fragCoord.y) + iTime * 40.0;
|
||||
float m = mod(diag, stripeWidth * 2.0);
|
||||
vec3 yellow = vec3(1.0, 0.82, 0.0);
|
||||
vec3 blk = vec3(0.05);
|
||||
return m < stripeWidth ? yellow : blk;
|
||||
}
|
||||
|
||||
vec3 sparkleStars(vec2 uv, vec2 resolution) {
|
||||
vec2 gridUV = uv;
|
||||
gridUV.x *= resolution.x / resolution.y;
|
||||
gridUV *= 26.0;
|
||||
|
||||
vec2 ipos = floor(gridUV);
|
||||
vec2 fpos = fract(gridUV);
|
||||
|
||||
// only a fraction of cells host a star
|
||||
float rnd = hash21(ipos);
|
||||
if (rnd > 0.12) return vec3(0.0);
|
||||
|
||||
vec2 center = vec2(hash21(ipos + 3.1), hash21(ipos + 7.7));
|
||||
float d = length(fpos - center);
|
||||
|
||||
// hard on/off blink rather than a smooth twinkle, tacky on purpose
|
||||
float phase = hash21(ipos + 11.0) * 10.0;
|
||||
float blink = step(0.5, fract(iTime * (1.5 + rnd * 4.0) + phase));
|
||||
|
||||
float glow = smoothstep(0.12, 0.0, d);
|
||||
vec3 hue = hsv2rgb(vec3(fract(rnd * 4.0 + iTime * 0.1), 1.0, 1.0));
|
||||
return hue * glow * blink;
|
||||
}
|
||||
|
||||
vec3 starBadge(vec2 fragCoord, vec2 resolution) {
|
||||
float radius = 26.0;
|
||||
float px = mix(radius, resolution.x - radius, triangleWave(iTime * 0.09, 1.0));
|
||||
float py = mix(radius, resolution.y - radius, triangleWave(iTime * 0.13 + 0.37, 1.0));
|
||||
vec2 p = fragCoord - vec2(px, py);
|
||||
|
||||
float d = length(p);
|
||||
float a = atan(p.y, p.x) - iTime * 2.0;
|
||||
float starR = radius * (0.55 + 0.45 * cos(a * 5.0));
|
||||
float shape = smoothstep(1.5, -1.5, d - starR);
|
||||
|
||||
vec3 hue = hsv2rgb(vec3(fract(iTime * 0.3), 1.0, 1.0));
|
||||
return hue * shape;
|
||||
}
|
||||
|
||||
// returns rgb + coverage alpha for the scrolling marquee ticker
|
||||
vec4 marquee(vec2 fragCoord, vec2 resolution) {
|
||||
float scale = clamp(resolution.y / 220.0, 2.0, 6.0);
|
||||
float charW = 6.0 * scale; // 5 columns + 1 spacing column
|
||||
float charH = 8.0 * scale; // 7 rows + 1 spacing row
|
||||
|
||||
int gap = 6; // blank characters between loops of the message
|
||||
int totalChars = MSG_LEN + gap;
|
||||
|
||||
// band hugs the bottom edge of the terminal
|
||||
float bandY0 = resolution.y - charH - scale * 2.0;
|
||||
float localY = fragCoord.y - bandY0;
|
||||
if (localY < 0.0 || localY >= charH) return vec4(0.0);
|
||||
int row = int(floor(localY / scale));
|
||||
if (row >= FONT_ROWS) return vec4(0.0);
|
||||
|
||||
float scrollX = fragCoord.x + iTime * scrollSpeed;
|
||||
float totalWidth = float(totalChars) * charW;
|
||||
float wrapped = mod(scrollX, totalWidth);
|
||||
int charIndex = int(floor(wrapped / charW));
|
||||
if (charIndex >= MSG_LEN) return vec4(0.0); // in the gap, blank
|
||||
|
||||
float localX = mod(wrapped, charW);
|
||||
int col = int(floor(localX / scale));
|
||||
if (col >= 5) return vec4(0.0);
|
||||
|
||||
int code = MSG[charIndex];
|
||||
if (fontBit(code, row, col) < 0.5) return vec4(0.0);
|
||||
|
||||
vec3 color = hsv2rgb(vec3(fract(float(charIndex) / float(MSG_LEN) + iTime * 0.15), 1.0, 1.0));
|
||||
return vec4(color, 1.0);
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
// main
|
||||
// ---------------------------------------------------------------
|
||||
|
||||
void mainImage(out vec4 fragColor, in vec2 fragCoord) {
|
||||
vec2 uv = fragCoord / iResolution.xy;
|
||||
vec4 terminalColor = texture(iChannel0, uv);
|
||||
|
||||
vec3 deco = vec3(0.0);
|
||||
|
||||
if (showStripes) {
|
||||
deco += hazardStripes(fragCoord) * stripeOpacity;
|
||||
}
|
||||
if (showSparkles) {
|
||||
deco += sparkleStars(uv, iResolution.xy) * sparkleIntensity;
|
||||
}
|
||||
if (showBadge) {
|
||||
deco = max(deco, starBadge(fragCoord, iResolution.xy));
|
||||
}
|
||||
if (showMarquee) {
|
||||
vec4 marq = marquee(fragCoord, iResolution.xy);
|
||||
deco = mix(deco, marq.rgb, marq.a);
|
||||
}
|
||||
|
||||
if (transparent) {
|
||||
deco += terminalColor.rgb;
|
||||
}
|
||||
|
||||
// only show the effect where the terminal is background (not text)
|
||||
float mask = 1.0 - step(threshold, luminance(terminalColor.rgb));
|
||||
vec3 blended = mix(terminalColor.rgb, deco, mask);
|
||||
|
||||
fragColor = vec4(blended, terminalColor.a);
|
||||
}
|
||||
Loading…
Reference in a new issue