From d24409d0f0d446717e48dfe2fe91e58b2bb23ef0 Mon Sep 17 00:00:00 2001 From: Ted Kulp Date: Mon, 30 Dec 2024 06:32:48 -0500 Subject: [PATCH] feat: ghostty config --- .config/ghostty/config | 155 +++++++++ .config/ghostty/shaders/bettercrt.glsl | 33 ++ .config/ghostty/shaders/bloom.glsl | 52 +++ .config/ghostty/shaders/crt.glsl | 310 ++++++++++++++++++ .config/ghostty/shaders/glitchy.glsl | 117 +++++++ .../ghostty/shaders/gradient-background.glsl | 25 ++ .config/ghostty/shaders/just-snow.glsl | 52 +++ .config/ghostty/shaders/retro-terminal.glsl | 34 ++ .config/ghostty/shaders/starfield-colors.glsl | 145 ++++++++ .config/ghostty/shaders/starfield.glsl | 125 +++++++ .config/ghostty/shaders/tft.glsl | 23 ++ 11 files changed, 1071 insertions(+) create mode 100644 .config/ghostty/config create mode 100644 .config/ghostty/shaders/bettercrt.glsl create mode 100644 .config/ghostty/shaders/bloom.glsl create mode 100644 .config/ghostty/shaders/crt.glsl create mode 100644 .config/ghostty/shaders/glitchy.glsl create mode 100644 .config/ghostty/shaders/gradient-background.glsl create mode 100644 .config/ghostty/shaders/just-snow.glsl create mode 100644 .config/ghostty/shaders/retro-terminal.glsl create mode 100644 .config/ghostty/shaders/starfield-colors.glsl create mode 100644 .config/ghostty/shaders/starfield.glsl create mode 100644 .config/ghostty/shaders/tft.glsl diff --git a/.config/ghostty/config b/.config/ghostty/config new file mode 100644 index 0000000..7790be1 --- /dev/null +++ b/.config/ghostty/config @@ -0,0 +1,155 @@ +#~~~~~~~~~~~~~~~~~~~~~~~# +# Ghostty configuration # +#~~~~~~~~~~~~~~~~~~~~~~~# + +# vim: set filetype=dosini : + +font-family = "Iosevka NFM" +font-size = 15 +font-thicken = false +grapheme-width-method = unicode +freetype-load-flags = hinting,force-autohint,monochrome,autohint +theme = "catppuccin-mocha" +cursor-opacity = 1 +#cursor-style = block +#cursor-style-blink = +#cursor-text = +cursor-click-to-move = true +mouse-hide-while-typing = false +mouse-shift-capture = false +mouse-scroll-multiplier = 1 +background-opacity = .90 +background-blur-radius = 40 +unfocused-split-opacity = 0.2 +unfocused-split-fill = +scrollback-limit = 10000000 +link-url = true +fullscreen = false +title = +class = +keybind = super+page_up=scroll_page_up +keybind = super+ctrl+equal=equalize_splits +keybind = super+physical:four=goto_tab:4 +keybind = super+shift+down=jump_to_prompt:1 +keybind = super+shift+w=close_window +keybind = super+shift+left_bracket=previous_tab +keybind = super+alt+i=inspector:toggle +keybind = super+w=close_surface +keybind = super+physical:eight=goto_tab:8 +keybind = super+alt+right=goto_split:right +keybind = shift+up=adjust_selection:up +keybind = super+down=jump_to_prompt:1 +keybind = super+enter=toggle_fullscreen +keybind = super+t=new_tab +keybind = super+c=copy_to_clipboard +keybind = super+shift+right_bracket=next_tab +keybind = super+physical:one=goto_tab:1 +keybind = shift+left=adjust_selection:left +keybind = super+equal=increase_font_size:1 +keybind = shift+page_up=adjust_selection:page_up +keybind = super+physical:three=goto_tab:3 +keybind = super+physical:zero=last_tab +keybind = super+right=text:\x05 +keybind = super+d=new_split:right +keybind = super+ctrl+down=resize_split:down,10 +keybind = shift+end=adjust_selection:end +keybind = super+plus=increase_font_size:1 +keybind = super+q=quit +keybind = super+home=scroll_to_top +keybind = super+ctrl+left=resize_split:left,10 +keybind = alt+left=esc:b +keybind = super+ctrl+up=resize_split:up,10 +keybind = super+left=text:\x01 +keybind = super+shift+up=jump_to_prompt:-1 +keybind = shift+right=adjust_selection:right +keybind = super+comma=open_config +keybind = super+shift+comma=reload_config +keybind = super+minus=decrease_font_size:1 +keybind = shift+page_down=adjust_selection:page_down +keybind = ctrl+tab=next_tab +keybind = super+a=select_all +keybind = alt+right=esc:f +keybind = super+shift+enter=toggle_split_zoom +keybind = super+alt+down=goto_split:bottom +keybind = super+ctrl+f=toggle_fullscreen +keybind = super+ctrl+right=resize_split:right,10 +keybind = super+alt+shift+j=write_scrollback_file:open +keybind = shift+down=adjust_selection:down +keybind = ctrl+shift+tab=previous_tab +keybind = super+n=new_window +keybind = super+alt+left=goto_split:left +keybind = super+page_down=scroll_page_down +keybind = super+alt+shift+w=close_all_windows +keybind = super+alt+up=goto_split:top +keybind = super+left_bracket=goto_split:previous +keybind = super+physical:nine=goto_tab:9 +keybind = super+right_bracket=goto_split:next +keybind = super+end=scroll_to_bottom +keybind = super+shift+j=write_scrollback_file:paste +keybind = super+shift+d=new_split:down +keybind = super+zero=reset_font_size +keybind = super+physical:five=goto_tab:5 +keybind = shift+home=adjust_selection:home +keybind = super+physical:seven=goto_tab:7 +keybind = super+up=jump_to_prompt:-1 +keybind = super+k=clear_screen +keybind = super+physical:two=goto_tab:2 +keybind = super+physical:six=goto_tab:6 +keybind = super+v=paste_from_clipboard +window-padding-x = 2 +window-padding-y = 2 +window-padding-balance = false +window-padding-color = background +window-vsync = true +window-inherit-working-directory = true +window-inherit-font-size = true +window-decoration = true +window-title-font-family = +window-theme = auto +window-colorspace = srgb +window-height = 0 +window-width = 0 +window-save-state = default +window-step-resize = false +window-new-tab-position = current +resize-overlay = after-first +resize-overlay-position = center +resize-overlay-duration = 750ms +focus-follows-mouse = false +clipboard-read = allow +clipboard-write = allow +clipboard-trim-trailing-spaces = false +clipboard-paste-protection = true +clipboard-paste-bracketed-safe = true +image-storage-limit = 320000000 +copy-on-select = false +click-repeat-interval = 0 +config-file = +config-default-files = true +confirm-close-surface = true +quit-after-last-window-closed = false +quit-after-last-window-closed-delay = +initial-window = true +quick-terminal-position = top +quick-terminal-screen = main +quick-terminal-animation-duration = 0.2 +quick-terminal-autohide = true +shell-integration = detect +shell-integration-features = cursor,no-sudo,title +osc-color-report-format = 16-bit +vt-kam-allowed = false +custom-shader = +custom-shader-animation = true +macos-non-native-fullscreen = false +macos-titlebar-style = hidden +macos-titlebar-proxy-icon = visible +macos-option-as-alt = true +macos-window-shadow = true +macos-auto-secure-input = true +macos-secure-input-indication = true +macos-icon = official +macos-icon-frame = aluminum +macos-icon-ghost-color = +macos-icon-screen-color = +desktop-notifications = true +bold-is-bright = true diff --git a/.config/ghostty/shaders/bettercrt.glsl b/.config/ghostty/shaders/bettercrt.glsl new file mode 100644 index 0000000..a2a1a14 --- /dev/null +++ b/.config/ghostty/shaders/bettercrt.glsl @@ -0,0 +1,33 @@ +// Original shader collected from: https://www.shadertoy.com/view/WsVSzV +// Licensed under Shadertoy's default since the original creator didn't provide any license. (CC BY NC SA 3.0) +// Slight modifications were made to give a green-ish effect. + +// This shader was modified by April Hall (arithefirst) +// Sourced from https://github.com/m-ahdal/ghostty-shaders/blob/main/retro-terminal.glsl +// Changes made: +// - Removed tint +// - Made the boundaries match ghostty's background color + +float warp = 0.20; // simulate curvature of CRT monitor +float scan = 1.00; // simulate darkness between scanlines + +void mainImage(out vec4 fragColor, in vec2 fragCoord) +{ + // squared distance from center + vec2 uv = fragCoord / iResolution.xy; + vec2 dc = abs(0.5 - uv); + dc *= dc; + + // warp the fragment coordinates + uv.x -= 0.5; uv.x *= 1.0 + (dc.y * (0.3 * warp)); uv.x += 0.5; + uv.y -= 0.5; uv.y *= 1.0 + (dc.x * (0.4 * warp)); uv.y += 0.5; + + // determine if we are drawing in a scanline + float apply = abs(sin(fragCoord.y) * 0.25 * scan); + + // sample the texture + vec3 color = texture(iChannel0, uv).rgb; + + // mix the sampled color with the scanline intensity + fragColor = vec4(mix(color, vec3(0.0), apply), 1.0); +} diff --git a/.config/ghostty/shaders/bloom.glsl b/.config/ghostty/shaders/bloom.glsl new file mode 100644 index 0000000..ad22448 --- /dev/null +++ b/.config/ghostty/shaders/bloom.glsl @@ -0,0 +1,52 @@ +// source: https://gist.github.com/qwerasd205/c3da6c610c8ffe17d6d2d3cc7068f17f +// credits: https://github.com/qwerasd205 +// Golden spiral samples, [x, y, weight] weight is inverse of distance. +const vec3[24] samples = { + vec3(0.1693761725038636, 0.9855514761735895, 1), + vec3(-1.333070830962943, 0.4721463328627773, 0.7071067811865475), + vec3(-0.8464394909806497, -1.51113870578065, 0.5773502691896258), + vec3(1.554155680728463, -1.2588090085709776, 0.5), + vec3(1.681364377589461, 1.4741145918052656, 0.4472135954999579), + vec3(-1.2795157692199817, 2.088741103228784, 0.4082482904638631), + vec3(-2.4575847530631187, -0.9799373355024756, 0.3779644730092272), + vec3(0.5874641440200847, -2.7667464429345077, 0.35355339059327373), + vec3(2.997715703369726, 0.11704939884745152, 0.3333333333333333), + vec3(0.41360842451688395, 3.1351121305574803, 0.31622776601683794), + vec3(-3.167149933769243, 0.9844599011770256, 0.30151134457776363), + vec3(-1.5736713846521535, -3.0860263079123245, 0.2886751345948129), + vec3(2.888202648340422, -2.1583061557896213, 0.2773500981126146), + vec3(2.7150778983300325, 2.5745586041105715, 0.2672612419124244), + vec3(-2.1504069972377464, 3.2211410627650165, 0.2581988897471611), + vec3(-3.6548858794907493, -1.6253643308191343, 0.25), + vec3(1.0130775986052671, -3.9967078676335834, 0.24253562503633297), + vec3(4.229723673607257, 0.33081361055181563, 0.23570226039551587), + vec3(0.40107790291173834, 4.340407413572593, 0.22941573387056174), + vec3(-4.319124570236028, 1.159811599693438, 0.22360679774997896), + vec3(-1.9209044802827355, -4.160543952132907, 0.2182178902359924), + vec3(3.8639122286635708, -2.6589814382925123, 0.21320071635561041), + vec3(3.3486228404946234, 3.4331800232609, 0.20851441405707477), + vec3(-2.8769733643574344, 3.9652268864187157, 0.20412414523193154) + }; + +float lum(vec4 c) { + return 0.299 * c.r + 0.587 * c.g + 0.114 * c.b; +} + +void mainImage(out vec4 fragColor, in vec2 fragCoord) { + vec2 uv = fragCoord.xy / iResolution.xy; + + vec4 color = texture(iChannel0, uv); + + vec2 step = vec2(1.414) / iResolution.xy; + + for (int i = 0; i < 24; i++) { + vec3 s = samples[i]; + vec4 c = texture(iChannel0, uv + s.xy * step); + float l = lum(c); + if (l > 0.2) { + color += l * s.z * c * 0.2; + } + } + + fragColor = color; +} \ No newline at end of file diff --git a/.config/ghostty/shaders/crt.glsl b/.config/ghostty/shaders/crt.glsl new file mode 100644 index 0000000..226c6b8 --- /dev/null +++ b/.config/ghostty/shaders/crt.glsl @@ -0,0 +1,310 @@ +// source: https://gist.github.com/qwerasd205/c3da6c610c8ffe17d6d2d3cc7068f17f +// credits: https://github.com/qwerasd205 +//============================================================== +// +// [CRTS] PUBLIC DOMAIN CRT-STYLED SCALAR by Timothy Lottes +// +// [+] Adapted with alterations for use in Ghostty by Qwerasd. +// For more information on changes, see comment below license. +// +//============================================================== +// +// LICENSE = UNLICENSE (aka PUBLIC DOMAIN) +// +//-------------------------------------------------------------- +// This is free and unencumbered software released into the +// public domain. +//-------------------------------------------------------------- +// Anyone is free to copy, modify, publish, use, compile, sell, +// or distribute this software, either in source code form or as +// a compiled binary, for any purpose, commercial or +// non-commercial, and by any means. +//-------------------------------------------------------------- +// In jurisdictions that recognize copyright laws, the author or +// authors of this software dedicate any and all copyright +// interest in the software to the public domain. We make this +// dedication for the benefit of the public at large and to the +// detriment of our heirs and successors. We intend this +// dedication to be an overt act of relinquishment in perpetuity +// of all present and future rights to this software under +// copyright law. +//-------------------------------------------------------------- +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +// KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +// WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR +// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +// AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT +// OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +// DEALINGS IN THE SOFTWARE. +//-------------------------------------------------------------- +// For more information, please refer to +// +//============================================================== + +// This shader is a modified version of the excellent +// FixingPixelArtFast by Timothy Lottes on Shadertoy. +// +// The original shader can be found at: +// https://www.shadertoy.com/view/MtSfRK +// +// Modifications have been made to reduce the verbosity, +// and many of the comments have been removed / reworded. +// Additionally, the license has been moved to the top of +// the file, and can be read above. I (Qwerasd) choose to +// release the modified version under the same license. + +// The appearance of this shader can be altered +// by adjusting the parameters defined below. + +// "Scanlines" per real screen pixel. +// e.g. SCALE 0.5 means each scanline is 2 pixels. +// Recommended values: +// o High DPI displays: 0.33333333 +// - Low DPI displays: 0.66666666 +#define SCALE 0.66666666 + +// "Tube" warp +#define CRTS_WARP 1 + +// Darkness of vignette in corners after warping +// 0.0 = completely black +// 1.0 = no vignetting +#define MIN_VIN 0.25 + +// Try different masks +// #define CRTS_MASK_GRILLE 1 +// #define CRTS_MASK_GRILLE_LITE 1 +// #define CRTS_MASK_NONE 1 +#define CRTS_MASK_SHADOW 1 + +// Scanline thinness +// 0.50 = fused scanlines +// 0.70 = recommended default +// 1.00 = thinner scanlines (too thin) +#define INPUT_THIN 0.70 + +// Horizonal scan blur +// -3.0 = pixely +// -2.5 = default +// -2.0 = smooth +// -1.0 = too blurry +#define INPUT_BLUR -2.75 + +// Shadow mask effect, ranges from, +// 0.25 = large amount of mask (not recommended, too dark) +// 0.50 = recommended default +// 1.00 = no shadow mask +#define INPUT_MASK 0.65 + +float FromSrgb1(float c) { + return (c <= 0.04045) ? c * (1.0 / 12.92) : + pow(c * (1.0 / 1.055) + (0.055 / 1.055), 2.4); +} +vec3 FromSrgb(vec3 c) { + return vec3( + FromSrgb1(c.r), FromSrgb1(c.g), FromSrgb1(c.b)); +} + +vec3 CrtsFetch(vec2 uv) { + return FromSrgb(texture(iChannel0, uv.xy).rgb); +} + +#define CrtsRcpF1(x) (1.0/(x)) +#define CrtsSatF1(x) clamp((x),0.0,1.0) + +float CrtsMax3F1(float a, float b, float c) { + return max(a, max(b, c)); +} + +vec2 CrtsTone( + float thin, + float mask) { + #ifdef CRTS_MASK_NONE + mask = 1.0; + #endif + + #ifdef CRTS_MASK_GRILLE_LITE + // Normal R mask is {1.0,mask,mask} + // LITE R mask is {mask,1.0,1.0} + mask = 0.5 + mask * 0.5; + #endif + + vec2 ret; + float midOut = 0.18 / ((1.5 - thin) * (0.5 * mask + 0.5)); + float pMidIn = 0.18; + ret.x = ((-pMidIn) + midOut) / ((1.0 - pMidIn) * midOut); + ret.y = ((-pMidIn) * midOut + pMidIn) / (midOut * (-pMidIn) + midOut); + + return ret; +} + +vec3 CrtsMask(vec2 pos, float dark) { + #ifdef CRTS_MASK_GRILLE + vec3 m = vec3(dark, dark, dark); + float x = fract(pos.x * (1.0 / 3.0)); + if (x < (1.0 / 3.0)) m.r = 1.0; + else if (x < (2.0 / 3.0)) m.g = 1.0; + else m.b = 1.0; + return m; + #endif + + #ifdef CRTS_MASK_GRILLE_LITE + vec3 m = vec3(1.0, 1.0, 1.0); + float x = fract(pos.x * (1.0 / 3.0)); + if (x < (1.0 / 3.0)) m.r = dark; + else if (x < (2.0 / 3.0)) m.g = dark; + else m.b = dark; + return m; + #endif + + #ifdef CRTS_MASK_NONE + return vec3(1.0, 1.0, 1.0); + #endif + + #ifdef CRTS_MASK_SHADOW + pos.x += pos.y * 3.0; + vec3 m = vec3(dark, dark, dark); + float x = fract(pos.x * (1.0 / 6.0)); + if (x < (1.0 / 3.0)) m.r = 1.0; + else if (x < (2.0 / 3.0)) m.g = 1.0; + else m.b = 1.0; + return m; + #endif +} + +vec3 CrtsFilter( + vec2 ipos, + vec2 inputSizeDivOutputSize, + vec2 halfInputSize, + vec2 rcpInputSize, + vec2 rcpOutputSize, + vec2 twoDivOutputSize, + float inputHeight, + vec2 warp, + float thin, + float blur, + float mask, + vec2 tone +) { + // Optional apply warp + vec2 pos; + #ifdef CRTS_WARP + // Convert to {-1 to 1} range + pos = ipos * twoDivOutputSize - vec2(1.0, 1.0); + + // Distort pushes image outside {-1 to 1} range + pos *= vec2( + 1.0 + (pos.y * pos.y) * warp.x, + 1.0 + (pos.x * pos.x) * warp.y); + + // TODO: Vignette needs optimization + float vin = 1.0 - ( + (1.0 - CrtsSatF1(pos.x * pos.x)) * (1.0 - CrtsSatF1(pos.y * pos.y))); + vin = CrtsSatF1((-vin) * inputHeight + inputHeight); + + // Leave in {0 to inputSize} + pos = pos * halfInputSize + halfInputSize; + #else + pos = ipos * inputSizeDivOutputSize; + #endif + + // Snap to center of first scanline + float y0 = floor(pos.y - 0.5) + 0.5; + // Snap to center of one of four pixels + float x0 = floor(pos.x - 1.5) + 0.5; + + // Inital UV position + vec2 p = vec2(x0 * rcpInputSize.x, y0 * rcpInputSize.y); + // Fetch 4 nearest texels from 2 nearest scanlines + vec3 colA0 = CrtsFetch(p); + p.x += rcpInputSize.x; + vec3 colA1 = CrtsFetch(p); + p.x += rcpInputSize.x; + vec3 colA2 = CrtsFetch(p); + p.x += rcpInputSize.x; + vec3 colA3 = CrtsFetch(p); + p.y += rcpInputSize.y; + vec3 colB3 = CrtsFetch(p); + p.x -= rcpInputSize.x; + vec3 colB2 = CrtsFetch(p); + p.x -= rcpInputSize.x; + vec3 colB1 = CrtsFetch(p); + p.x -= rcpInputSize.x; + vec3 colB0 = CrtsFetch(p); + + // Vertical filter + // Scanline intensity is using sine wave + // Easy filter window and integral used later in exposure + float off = pos.y - y0; + float pi2 = 6.28318530717958; + float hlf = 0.5; + float scanA = cos(min(0.5, off * thin) * pi2) * hlf + hlf; + float scanB = cos(min(0.5, (-off) * thin + thin) * pi2) * hlf + hlf; + + // Horizontal kernel is simple gaussian filter + float off0 = pos.x - x0; + float off1 = off0 - 1.0; + float off2 = off0 - 2.0; + float off3 = off0 - 3.0; + float pix0 = exp2(blur * off0 * off0); + float pix1 = exp2(blur * off1 * off1); + float pix2 = exp2(blur * off2 * off2); + float pix3 = exp2(blur * off3 * off3); + float pixT = CrtsRcpF1(pix0 + pix1 + pix2 + pix3); + + #ifdef CRTS_WARP + // Get rid of wrong pixels on edge + pixT *= max(MIN_VIN, vin); + #endif + + scanA *= pixT; + scanB *= pixT; + + // Apply horizontal and vertical filters + vec3 color = + (colA0 * pix0 + colA1 * pix1 + colA2 * pix2 + colA3 * pix3) * scanA + + (colB0 * pix0 + colB1 * pix1 + colB2 * pix2 + colB3 * pix3) * scanB; + + // Apply phosphor mask + color *= CrtsMask(ipos, mask); + + // Tonal control, start by protecting from /0 + float peak = max(1.0 / (256.0 * 65536.0), + CrtsMax3F1(color.r, color.g, color.b)); + // Compute the ratios of {R,G,B} + vec3 ratio = color * CrtsRcpF1(peak); + // Apply tonal curve to peak value + peak = peak * CrtsRcpF1(peak * tone.x + tone.y); + // Reconstruct color + return ratio * peak; +} + +float ToSrgb1(float c) { + return (c < 0.0031308 ? c * 12.92 : 1.055 * pow(c, 0.41666) - 0.055); +} +vec3 ToSrgb(vec3 c) { + return vec3( + ToSrgb1(c.r), ToSrgb1(c.g), ToSrgb1(c.b)); +} + +void mainImage(out vec4 fragColor, in vec2 fragCoord) { + float aspect = iResolution.x / iResolution.y; + fragColor.rgb = CrtsFilter( + fragCoord.xy, + vec2(1.0), + iResolution.xy * SCALE * 0.5, + 1.0 / (iResolution.xy * SCALE), + 1.0 / iResolution.xy, + 2.0 / iResolution.xy, + iResolution.y, + vec2(1.0 / (50.0 * aspect), 1.0 / 50.0), + INPUT_THIN, + INPUT_BLUR, + INPUT_MASK, + CrtsTone(INPUT_THIN, INPUT_MASK) + ); + + // Linear to SRGB for output. + fragColor.rgb = ToSrgb(fragColor.rgb); +} diff --git a/.config/ghostty/shaders/glitchy.glsl b/.config/ghostty/shaders/glitchy.glsl new file mode 100644 index 0000000..81ec83d --- /dev/null +++ b/.config/ghostty/shaders/glitchy.glsl @@ -0,0 +1,117 @@ +// modified version of https://www.shadertoy.com/view/wld3WN +// amount of seconds for which the glitch loop occurs +#define DURATION 10. +// percentage of the duration for which the glitch is triggered +#define AMT .01 + +#define SS(a, b, x) (smoothstep(a, b, x) * smoothstep(b, a, x)) + +#define UI0 1597334673U +#define UI1 3812015801U +#define UI2 uvec2(UI0, UI1) +#define UI3 uvec3(UI0, UI1, 2798796415U) +#define UIF (1. / float(0xffffffffU)) + +// Hash by David_Hoskins +vec3 hash33(vec3 p) +{ + uvec3 q = uvec3(ivec3(p)) * UI3; + q = (q.x ^ q.y ^ q.z)*UI3; + return -1. + 2. * vec3(q) * UIF; +} + +// Gradient noise by iq +float gnoise(vec3 x) +{ + // grid + vec3 p = floor(x); + vec3 w = fract(x); + + // quintic interpolant + vec3 u = w * w * w * (w * (w * 6. - 15.) + 10.); + + // gradients + vec3 ga = hash33(p + vec3(0., 0., 0.)); + vec3 gb = hash33(p + vec3(1., 0., 0.)); + vec3 gc = hash33(p + vec3(0., 1., 0.)); + vec3 gd = hash33(p + vec3(1., 1., 0.)); + vec3 ge = hash33(p + vec3(0., 0., 1.)); + vec3 gf = hash33(p + vec3(1., 0., 1.)); + vec3 gg = hash33(p + vec3(0., 1., 1.)); + vec3 gh = hash33(p + vec3(1., 1., 1.)); + + // projections + float va = dot(ga, w - vec3(0., 0., 0.)); + float vb = dot(gb, w - vec3(1., 0., 0.)); + float vc = dot(gc, w - vec3(0., 1., 0.)); + float vd = dot(gd, w - vec3(1., 1., 0.)); + float ve = dot(ge, w - vec3(0., 0., 1.)); + float vf = dot(gf, w - vec3(1., 0., 1.)); + float vg = dot(gg, w - vec3(0., 1., 1.)); + float vh = dot(gh, w - vec3(1., 1., 1.)); + + // interpolation + float gNoise = va + u.x * (vb - va) + + u.y * (vc - va) + + u.z * (ve - va) + + u.x * u.y * (va - vb - vc + vd) + + u.y * u.z * (va - vc - ve + vg) + + u.z * u.x * (va - vb - ve + vf) + + u.x * u.y * u.z * (-va + vb + vc - vd + ve - vf - vg + vh); + + return 2. * gNoise; +} + +// gradient noise in range [0, 1] +float gnoise01(vec3 x) +{ + return .5 + .5 * gnoise(x); +} + +// warp uvs for the crt effect +vec2 crt(vec2 uv) +{ + float tht = atan(uv.y, uv.x); + float r = length(uv); + // curve without distorting the center + r /= (1. - .1 * r * r); + uv.x = r * cos(tht); + uv.y = r * sin(tht); + return .5 * (uv + 1.); +} + + +void mainImage( out vec4 fragColor, in vec2 fragCoord ) +{ + vec2 uv = fragCoord / iResolution.xy; + float t = iTime; + + // smoothed interval for which the glitch gets triggered + float glitchAmount = SS(DURATION * .001, DURATION * AMT, mod(t, DURATION)); + float displayNoise = 0.; + vec3 col = vec3(0.); + vec2 eps = vec2(5. / iResolution.x, 0.); + vec2 st = vec2(0.); + + // analog distortion + float y = uv.y * iResolution.y; + float distortion = gnoise(vec3(0., y * .01, t * 500.)) * (glitchAmount * 4. + .1); + distortion *= gnoise(vec3(0., y * .02, t * 250.)) * (glitchAmount * 2. + .025); + + ++displayNoise; + distortion += smoothstep(.999, 1., sin((uv.y + t * 1.6) * 2.)) * .02; + distortion -= smoothstep(.999, 1., sin((uv.y + t) * 2.)) * .02; + st = uv + vec2(distortion, 0.); + // chromatic aberration + col.r += textureLod(iChannel0, st + eps + distortion, 0.).r; + col.g += textureLod(iChannel0, st, 0.).g; + col.b += textureLod(iChannel0, st - eps - distortion, 0.).b; + + // white noise + scanlines + displayNoise = 0.2 * clamp(displayNoise, 0., 1.); + col += (.15 + .65 * glitchAmount) * (hash33(vec3(fragCoord, mod(float(iFrame), + 1000.))).r) * displayNoise; + col -= (.25 + .75 * glitchAmount) * (sin(4. * t + uv.y * iResolution.y * 1.75)) + * displayNoise; + fragColor = vec4(col, 1.0); +} diff --git a/.config/ghostty/shaders/gradient-background.glsl b/.config/ghostty/shaders/gradient-background.glsl new file mode 100644 index 0000000..beae0cf --- /dev/null +++ b/.config/ghostty/shaders/gradient-background.glsl @@ -0,0 +1,25 @@ +// credits: https://github.com/unkn0wncode +void mainImage(out vec4 fragColor, in vec2 fragCoord) +{ + // Normalize pixel coordinates (range from 0 to 1) + vec2 uv = fragCoord.xy / iResolution.xy; + + // Create a gradient from bottom right to top left as a function (x + y)/2 + float gradientFactor = (uv.x + uv.y) / 2.0; + + // Define gradient colors (adjust to your preference) + vec3 gradientStartColor = vec3(0.1, 0.1, 0.5); // Start color (e.g., dark blue) + vec3 gradientEndColor = vec3(0.5, 0.1, 0.1); // End color (e.g., dark red) + + vec3 gradientColor = mix(gradientStartColor, gradientEndColor, gradientFactor); + + // Sample the terminal screen texture including alpha channel + vec4 terminalColor = texture(iChannel0, uv); + + // Make a mask that is 1.0 where the terminal content is not black + float mask = 1 - step(0.5, dot(terminalColor.rgb, vec3(1.0))); + vec3 blendedColor = mix(terminalColor.rgb, gradientColor, mask); + + // Apply terminal's alpha to control overall opacity + fragColor = vec4(blendedColor, terminalColor.a); +} \ No newline at end of file diff --git a/.config/ghostty/shaders/just-snow.glsl b/.config/ghostty/shaders/just-snow.glsl new file mode 100644 index 0000000..0eb7c80 --- /dev/null +++ b/.config/ghostty/shaders/just-snow.glsl @@ -0,0 +1,52 @@ +// Copyright (c) 2013 Andrew Baldwin (twitter: baldand, www: http://thndl.com) +// License = Attribution-NonCommercial-ShareAlike (http://creativecommons.org/licenses/by-nc-sa/3.0/deed.en_US) + +// "Just snow" +// Simple (but not cheap) snow made from multiple parallax layers with randomly positioned +// flakes and directions. Also includes a DoF effect. Pan around with mouse. + +#define LIGHT_SNOW // Comment this out for a blizzard + +#ifdef LIGHT_SNOW + #define LAYERS 50 + #define DEPTH .5 + #define WIDTH .3 + #define SPEED .6 +#else // BLIZZARD + #define LAYERS 200 + #define DEPTH .1 + #define WIDTH .8 + #define SPEED 1.5 +#endif + +void mainImage( out vec4 fragColor, in vec2 fragCoord ) +{ + const mat3 p = mat3(13.323122,23.5112,21.71123,21.1212,28.7312,11.9312,21.8112,14.7212,61.3934); + vec2 uv = fragCoord.xy / iResolution.xy; + + vec3 acc = vec3(0.0); + float dof = 5.0 * sin(iTime * 0.1); + for (int i = 0; i < LAYERS; i++) { + float fi = float(i); + vec2 q =-uv*(1.0 + fi * DEPTH); + q += vec2(q.y * (WIDTH * mod(fi * 7.238917, 1.0) - WIDTH * 0.5), SPEED * iTime / (1.0 + fi * DEPTH * 0.03)); + vec3 n = vec3(floor(q), 31.189 + fi); + vec3 m = floor(n) * 0.00001 + fract(n); + vec3 mp = (31415.9 + m) / fract(p * m); + vec3 r = fract(mp); + vec2 s = abs(mod(q, 1.0) - 0.5 + 0.9 * r.xy - 0.45); + s += 0.01 * abs(2.0 * fract(10.0 * q.yx) - 1.0); + float d = 0.6 * max(s.x - s.y, s.x + s.y) + max(s.x, s.y) - 0.01; + float edge = 0.005 + 0.05 * min(0.5 * abs(fi - 5.0 - dof), 1.0); + acc += vec3(smoothstep(edge, -edge, d) * (r.x / (1.0 + 0.02 * fi * DEPTH))); + } + + // Sample the terminal screen texture including alpha channel + vec4 terminalColor = texture(iChannel0, uv); + + // Combine the snow effect with the terminal color + vec3 blendedColor = terminalColor.rgb + acc; + + // Use the terminal's original alpha + fragColor = vec4(blendedColor, terminalColor.a); +} diff --git a/.config/ghostty/shaders/retro-terminal.glsl b/.config/ghostty/shaders/retro-terminal.glsl new file mode 100644 index 0000000..dadf2cb --- /dev/null +++ b/.config/ghostty/shaders/retro-terminal.glsl @@ -0,0 +1,34 @@ +// Original shader collected from: https://www.shadertoy.com/view/WsVSzV +// Licensed under Shadertoy's default since the original creator didn't provide any license. (CC BY NC SA 3.0) +// Slight modifications were made to give a green-ish effect. + +float warp = 0.25; // simulate curvature of CRT monitor +float scan = 0.50; // simulate darkness between scanlines + +void mainImage(out vec4 fragColor, in vec2 fragCoord) +{ + // squared distance from center + vec2 uv = fragCoord / iResolution.xy; + vec2 dc = abs(0.5 - uv); + dc *= dc; + + // warp the fragment coordinates + uv.x -= 0.5; uv.x *= 1.0 + (dc.y * (0.3 * warp)); uv.x += 0.5; + uv.y -= 0.5; uv.y *= 1.0 + (dc.x * (0.4 * warp)); uv.y += 0.5; + + // sample inside boundaries, otherwise set to black + if (uv.y > 1.0 || uv.x < 0.0 || uv.x > 1.0 || uv.y < 0.0) + fragColor = vec4(0.0, 0.0, 0.0, 1.0); + else + { + // determine if we are drawing in a scanline + float apply = abs(sin(fragCoord.y) * 0.5 * scan); + + // sample the texture and apply a teal tint + vec3 color = texture(iChannel0, uv).rgb; + vec3 tealTint = vec3(0.0, 0.8, 0.6); // teal color (slightly more green than blue) + + // mix the sampled color with the teal tint based on scanline intensity + fragColor = vec4(mix(color * tealTint, vec3(0.0), apply), 1.0); + } +} \ No newline at end of file diff --git a/.config/ghostty/shaders/starfield-colors.glsl b/.config/ghostty/shaders/starfield-colors.glsl new file mode 100644 index 0000000..1915635 --- /dev/null +++ b/.config/ghostty/shaders/starfield-colors.glsl @@ -0,0 +1,145 @@ +// divisions of grid +const float repeats = 30.; + +// number of layers +const float layers = 21.; + +// star colours +const vec3 blue = vec3(51.,64.,195.)/255.; +const vec3 cyan = vec3(117.,250.,254.)/255.; +const vec3 white = vec3(255.,255.,255.)/255.; +const vec3 yellow = vec3(251.,245.,44.)/255.; +const vec3 red = vec3(247,2.,20.)/255.; + +// spectrum function +vec3 spectrum(vec2 pos){ + pos.x *= 4.; + vec3 outCol = vec3(0); + if( pos.x > 0.){ + outCol = mix(blue, cyan, fract(pos.x)); + } + if( pos.x > 1.){ + outCol = mix(cyan, white, fract(pos.x)); + } + if( pos.x > 2.){ + outCol = mix(white, yellow, fract(pos.x)); + } + if( pos.x > 3.){ + outCol = mix(yellow, red, fract(pos.x)); + } + + return 1.-(pos.y * (1.-outCol)); +} + +float N21(vec2 p) { + p = fract(p * vec2(233.34, 851.73)); + p += dot(p, p + 23.45); + return fract(p.x * p.y); +} + +vec2 N22(vec2 p) { + float n = N21(p); + return vec2(n, N21(p + n)); +} + +mat2 scale(vec2 _scale) { + return mat2(_scale.x, 0.0, + 0.0, _scale.y); +} + +// 2D Noise based on Morgan McGuire +float noise(in vec2 st) { + vec2 i = floor(st); + vec2 f = fract(st); + + // Four corners in 2D of a tile + float a = N21(i); + float b = N21(i + vec2(1.0, 0.0)); + float c = N21(i + vec2(0.0, 1.0)); + float d = N21(i + vec2(1.0, 1.0)); + + // Smooth Interpolation + vec2 u = f * f * (3.0 - 2.0 * f); // Cubic Hermite Curve + + // Mix 4 corners percentages + return mix(a, b, u.x) + + (c - a) * u.y * (1.0 - u.x) + + (d - b) * u.x * u.y; +} + +float perlin2(vec2 uv, int octaves, float pscale) { + float col = 1.; + float initScale = 4.; + for (int l; l < octaves; l++) { + float val = noise(uv * initScale); + if (col <= 0.01) { + col = 0.; + break; + } + val -= 0.01; + val *= 0.5; + col *= val; + initScale *= pscale; + } + return col; +} + +vec3 stars(vec2 uv, float offset) { + float timeScale = -(iTime + offset) / layers; + float trans = fract(timeScale); + float newRnd = floor(timeScale); + vec3 col = vec3(0.); + + // Translate uv then scale for center + uv -= vec2(0.5); + uv = scale(vec2(trans)) * uv; + uv += vec2(0.5); + + // Create square aspect ratio + uv.x *= iResolution.x / iResolution.y; + + // Create boxes + uv *= repeats; + + // Get position + vec2 ipos = floor(uv); + + // Return uv as 0 to 1 + uv = fract(uv); + + // Calculate random xy and size + vec2 rndXY = N22(newRnd + ipos * (offset + 1.)) * 0.9 + 0.05; + float rndSize = N21(ipos) * 100. + 200.; + + vec2 j = (rndXY - uv) * rndSize; + float sparkle = 1. / dot(j, j); + + // Set stars to be pure white + col += spectrum(fract(rndXY*newRnd*ipos)) * vec3(sparkle); + + col *= smoothstep(1., 0.8, trans); + return col; // Return pure white stars only +} + +void mainImage( out vec4 fragColor, in vec2 fragCoord ) +{ + // Normalized pixel coordinates (from 0 to 1) + vec2 uv = fragCoord/iResolution.xy; + + vec3 col = vec3(0.); + + for (float i = 0.; i < layers; i++ ){ + col += stars(uv, i); + } + + // Sample the terminal screen texture including alpha channel + vec4 terminalColor = texture(iChannel0, uv); + + // Make a mask that is 1.0 where the terminal content is not black + float mask = 1 - step(0.5, dot(terminalColor.rgb, vec3(1.0))); + vec3 blendedColor = mix(terminalColor.rgb, col, mask); + + // Apply terminal's alpha to control overall opacity + fragColor = vec4(blendedColor, terminalColor.a); + +} \ No newline at end of file diff --git a/.config/ghostty/shaders/starfield.glsl b/.config/ghostty/shaders/starfield.glsl new file mode 100644 index 0000000..480aa38 --- /dev/null +++ b/.config/ghostty/shaders/starfield.glsl @@ -0,0 +1,125 @@ +// divisions of grid +const float repeats = 30.; + +// number of layers +const float layers = 21.; + +// star colors +const vec3 white = vec3(1.0); // Set star color to pure white + +float N21(vec2 p) { + p = fract(p * vec2(233.34, 851.73)); + p += dot(p, p + 23.45); + return fract(p.x * p.y); +} + +vec2 N22(vec2 p) { + float n = N21(p); + return vec2(n, N21(p + n)); +} + +mat2 scale(vec2 _scale) { + return mat2(_scale.x, 0.0, + 0.0, _scale.y); +} + +// 2D Noise based on Morgan McGuire +float noise(in vec2 st) { + vec2 i = floor(st); + vec2 f = fract(st); + + // Four corners in 2D of a tile + float a = N21(i); + float b = N21(i + vec2(1.0, 0.0)); + float c = N21(i + vec2(0.0, 1.0)); + float d = N21(i + vec2(1.0, 1.0)); + + // Smooth Interpolation + vec2 u = f * f * (3.0 - 2.0 * f); // Cubic Hermite Curve + + // Mix 4 corners percentages + return mix(a, b, u.x) + + (c - a) * u.y * (1.0 - u.x) + + (d - b) * u.x * u.y; +} + +float perlin2(vec2 uv, int octaves, float pscale) { + float col = 1.; + float initScale = 4.; + for (int l; l < octaves; l++) { + float val = noise(uv * initScale); + if (col <= 0.01) { + col = 0.; + break; + } + val -= 0.01; + val *= 0.5; + col *= val; + initScale *= pscale; + } + return col; +} + +vec3 stars(vec2 uv, float offset) { + float timeScale = -(iTime + offset) / layers; + float trans = fract(timeScale); + float newRnd = floor(timeScale); + vec3 col = vec3(0.); + + // Translate uv then scale for center + uv -= vec2(0.5); + uv = scale(vec2(trans)) * uv; + uv += vec2(0.5); + + // Create square aspect ratio + uv.x *= iResolution.x / iResolution.y; + + // Create boxes + uv *= repeats; + + // Get position + vec2 ipos = floor(uv); + + // Return uv as 0 to 1 + uv = fract(uv); + + // Calculate random xy and size + vec2 rndXY = N22(newRnd + ipos * (offset + 1.)) * 0.9 + 0.05; + float rndSize = N21(ipos) * 100. + 200.; + + vec2 j = (rndXY - uv) * rndSize; + float sparkle = 1. / dot(j, j); + + // Set stars to be pure white + col += white * sparkle; + + col *= smoothstep(1., 0.8, trans); + return col; // Return pure white stars only +} + +void mainImage( out vec4 fragColor, in vec2 fragCoord ) +{ + // Normalized pixel coordinates (from 0 to 1) + vec2 uv = fragCoord/iResolution.xy; + + vec3 col = vec3(0.); + + for (float i = 0.; i < layers; i++ ){ + col += stars(uv, i); + } + + + // Output to screen + // fragColor = vec4(col,1.0); + + // Sample the terminal screen texture including alpha channel + vec4 terminalColor = texture(iChannel0, uv); + + // Make a mask that is 1.0 where the terminal content is not black + float mask = 1 - step(0.5, dot(terminalColor.rgb, vec3(1.0))); + vec3 blendedColor = mix(terminalColor.rgb, col, mask); + + // Apply terminal's alpha to control overall opacity + fragColor = vec4(blendedColor, terminalColor.a); + +} \ No newline at end of file diff --git a/.config/ghostty/shaders/tft.glsl b/.config/ghostty/shaders/tft.glsl new file mode 100644 index 0000000..3d77443 --- /dev/null +++ b/.config/ghostty/shaders/tft.glsl @@ -0,0 +1,23 @@ +/** Size of TFT "pixels" */ +float resolution = 4.0; + +/** Strength of effect */ +float strength = 0.5; + +void _scanline(inout vec3 color, vec2 uv) +{ + float scanline = step(1.2, mod(uv.y * iResolution.y, resolution)); + float grille = step(1.2, mod(uv.x * iResolution.x, resolution)); + color *= max(1.0 - strength, scanline * grille); +} + +void mainImage(out vec4 fragColor, in vec2 fragCoord) +{ + vec2 uv = fragCoord.xy / iResolution.xy; + vec3 color = texture(iChannel0, uv).rgb; + + _scanline(color, uv); + + fragColor.xyz = color; + fragColor.w = 1.0; +}