Created
February 8, 2025 17:46
-
-
Save zfedoran/4e8c2c172f3a8f381e2a92acdc894002 to your computer and use it in GitHub Desktop.
ghostty glow effect
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// A set of sample offsets (x, y) and corresponding weights | |
const vec3[24] samples = vec3[]( | |
vec3( 0.16937617, 0.98555148, 1.0), | |
vec3(-1.33307083, 0.47214633, 0.70710678), | |
vec3(-0.84643949, -1.51113871, 0.57735027), | |
vec3( 1.55415568, -1.25880901, 0.5), | |
vec3( 1.68136438, 1.47411459, 0.44721360), | |
vec3(-1.27951577, 2.08874110, 0.40824829), | |
vec3(-2.45758475, -0.97993734, 0.37796447), | |
vec3( 0.58746414, -2.76674644, 0.35355339), | |
vec3( 2.99771570, 0.11704940, 0.33333333), | |
vec3( 0.41360842, 3.13511213, 0.31622777), | |
vec3(-3.16714993, 0.98445990, 0.30151134), | |
vec3(-1.57367138, -3.08602631, 0.28867513), | |
vec3( 2.88820265, -2.15830616, 0.27735010), | |
vec3( 2.71507790, 2.57455860, 0.26726124), | |
vec3(-2.15040700, 3.22114106, 0.25819889), | |
vec3(-3.65488588, -1.62536433, 0.25), | |
vec3( 1.01307760, -3.99670787, 0.24253563), | |
vec3( 4.22972367, 0.33081361, 0.23570226), | |
vec3( 0.40107790, 4.34040741, 0.22941573), | |
vec3(-4.31912457, 1.15981160, 0.22360680), | |
vec3(-1.92090448, -4.16054395, 0.21821789), | |
vec3( 3.86391223, -2.65898144, 0.21320072), | |
vec3( 3.34862284, 3.43318002, 0.20851441), | |
vec3(-2.87697336, 3.96522689, 0.20412415) | |
); | |
// Colors we want to detect | |
const vec3 targetColors[4] = vec3[]( | |
vec3(0.956, 0.933, 0.894), // #f4eee4 | |
vec3(0.212, 0.976, 0.965), // #36f9f6 | |
vec3(1.0, 1.0, 1.0 ), // #ffffff | |
vec3(0.600, 0.271, 1.000) // #9945ff | |
); | |
// Tint colors for bloom | |
const vec3 bloomColors[4] = vec3[]( | |
vec3(0.953, 0.624, 0.02), // #f39f05 | |
vec3(0.533, 0.122, 0.988), // #881ffc | |
vec3(0.011, 0.933, 0.976), // #03edf9 | |
vec3(0.533, 0.122, 0.988) // #881ffc | |
); | |
// Per-color bloom strength | |
const float bloomStrength[4] = float[]( | |
0.20, // yellow-white | |
0.15, // cyan | |
0.10, // white | |
0.15 // purple | |
); | |
// Distance threshold to treat two colors as a match | |
const float threshold = 0.1; | |
// Return index of the closest matching color if within threshold, otherwise -1 | |
int getMatchingColorIndex(vec3 color) { | |
int bestIndex = -1; | |
float bestDist = 9999.0; | |
for (int i = 0; i < 4; i++) { | |
float d = distance(color, targetColors[i]); | |
if (d < bestDist) { | |
bestDist = d; | |
bestIndex = i; | |
} | |
} | |
return (bestDist < threshold) ? bestIndex : -1; | |
} | |
void mainImage(out vec4 fragColor, in vec2 fragCoord) { | |
vec2 uv = fragCoord.xy / iResolution.xy; | |
vec4 color = texture(iChannel0, uv); | |
// Step size for sampling around the pixel | |
//vec2 step = vec2(1.414) / iResolution.xy; | |
vec2 step = vec2(1.0) / iResolution.xy; | |
// Accumulate bloom | |
for (int i = 0; i < 24; i++) { | |
vec3 s = samples[i]; | |
vec4 c = texture(iChannel0, uv + s.xy * step); | |
// Check if this neighbor matches one of the target colors | |
int idx = getMatchingColorIndex(c.rgb); | |
if (idx != -1) { | |
// Add bloom tint | |
float w = s.z; | |
color += vec4(bloomColors[idx], 0.0) * (bloomStrength[idx] * w); | |
} | |
} | |
// Clamp final color | |
fragColor = clamp(color, 0.0, 1.0); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment