|
| 1 | +#version 330 |
| 2 | + |
| 3 | +in vec2 fragTexCoord; |
| 4 | +out vec4 finalColor; |
| 5 | + |
| 6 | +uniform sampler2D texture0; |
| 7 | +uniform vec2 texelSize; // 1.0 / vec2(textureWidth, textureHeight) |
| 8 | +uniform float glowStrength; // driven by cos in time |
| 9 | +uniform float fadeAlpha; // 0..1 fade-in multiplier |
| 10 | + |
| 11 | +void main() |
| 12 | +{ |
| 13 | + vec2 uv = fragTexCoord; |
| 14 | + float c = texture(texture0, uv).a; |
| 15 | + |
| 16 | + // Solid pixels stay fully opaque — no shader math needed |
| 17 | + if (c > 0.5) { |
| 18 | + vec3 color = vec3(0.0, 0.87, 0.87); |
| 19 | + finalColor = vec4(color * fadeAlpha, fadeAlpha); |
| 20 | + return; |
| 21 | + } |
| 22 | + |
| 23 | + // Find the distance to the nearest solid pixel, then apply a smooth |
| 24 | + // exponential falloff on that distance. This gives a proper gradient |
| 25 | + // rather than a flat accumulated plateau. |
| 26 | + float min_dist = 32.0; |
| 27 | + int R = 32; |
| 28 | + for (int dx = -R; dx <= R; dx++) { |
| 29 | + for (int dy = -R; dy <= R; dy++) { |
| 30 | + float s = texture(texture0, uv + texelSize * vec2(dx, dy)).a; |
| 31 | + if (s > 0.5) { |
| 32 | + min_dist = min(min_dist, length(vec2(dx, dy))); |
| 33 | + } |
| 34 | + } |
| 35 | + } |
| 36 | + |
| 37 | + float glow = exp(-0.12 * min_dist); // bright at d=1, fades over ~20px |
| 38 | + float halo = glow * (0.4 + glowStrength * 0.6) * fadeAlpha; |
| 39 | + vec3 color = vec3(0.0, 0.87, 0.87); |
| 40 | + finalColor = vec4(color * halo, halo); |
| 41 | +} |
0 commit comments