#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.02; 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.8 -> 0.35) float vigInner = mix(0.8, 0.35, intensity); // Outer edge also shrinks (1.1 -> 0.7) float vigOuter = mix(1.1, 0.7, intensity); float vig = smoothstep(vigInner, vigOuter, dist); // Red tint on the vignette area - translucent blend vec3 threatColor = uColor.rgb; vec3 tinted = mix(tex.rgb, threatColor * 0.12, vig * intensity * 0.6); // Darken edges - softer tinted *= 1.0 - vig * intensity * 0.35; fragColor = vec4(tinted, tex.a) * qt_Opacity; }