#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; // 0.0 = no threat, 1.0 = max lockout float uThreat; // 0.0-1.0 heartbeat pulse (0 when inactive) float uPulse; // accent/threat color vec4 uColor; }; layout(binding = 1) uniform sampler2D source; void main() { vec2 uv = qt_TexCoord0; float threat = clamp(uThreat, 0.0, 1.0); float pulse = clamp(uPulse, 0.0, 1.0); // Combined intensity: base threat + heartbeat spike float intensity = threat + pulse * threat * 0.4; // Chromatic aberration - RGB channel split increasing with threat float aberration = intensity * 0.008; float r = texture(source, uv + vec2(aberration, 0.0)).r; float g = texture(source, uv).g; float b = texture(source, uv - vec2(aberration, 0.0)).b; float a = texture(source, uv).a; vec4 tex = vec4(r, g, b, a); // Vignette - radial darkening from edges, creeping inward with threat vec2 center = uv - 0.5; float dist = length(center * vec2(1.0, 0.7)); // wider horizontally // Inner edge shrinks as threat rises (0.7 -> 0.25) float vigInner = mix(0.7, 0.25, intensity); // Outer edge also shrinks (1.0 -> 0.6) float vigOuter = mix(1.0, 0.6, intensity); float vig = smoothstep(vigInner, vigOuter, dist); // Red tint on the vignette area vec3 threatColor = uColor.rgb; vec3 tinted = mix(tex.rgb, threatColor * 0.15, vig * intensity); // Darken edges tinted *= 1.0 - vig * intensity * 0.7; fragColor = vec4(tinted, tex.a) * qt_Opacity; }