#version 440 layout(location = 0) in vec2 qt_TexCoord0; layout(location = 0) out vec4 fragColor; layout(std140, binding = 0) uniform buf { mat4 qt_Matrix; float qt_Opacity; float time; }; layout(binding = 1) uniform sampler2D source; void main() { vec2 uv = qt_TexCoord0; // CRT curvature distortion vec2 crtUV = uv - 0.5; float curvature = 0.03; crtUV *= 1.0 + curvature * (crtUV.x * crtUV.x + crtUV.y * crtUV.y); crtUV += 0.5; // Clamp to avoid sampling outside if (crtUV.x < 0.0 || crtUV.x > 1.0 || crtUV.y < 0.0 || crtUV.y > 1.0) { fragColor = vec4(0.0, 0.0, 0.0, 0.0); return; } // Sample the texture vec4 color = texture(source, crtUV); // Scanlines effect (fine and subtle) float scanlineIntensity = 0.04; float scanline = sin(crtUV.y * 2400.0) * scanlineIntensity; color.rgb -= scanline; // RGB color separation (chromatic aberration) float aberration = 0.001; float r = texture(source, crtUV + vec2(aberration, 0.0)).r; float g = color.g; float b = texture(source, crtUV - vec2(aberration, 0.0)).b; color.rgb = vec3(r, g, b); // Subtle vignette float vignette = 1.0 - 0.3 * length(crtUV - 0.5); color.rgb *= vignette; // Slight green/cyan phosphor tint color.rgb *= vec3(0.95, 1.0, 0.98); // Flicker (very subtle) float flicker = 0.98 + 0.02 * sin(time * 15.0); color.rgb *= flicker; fragColor = color * qt_Opacity; }