#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; float warpStrength; float flowSpeed; float scale; float edgeReflectionStrength; float edgeReflectionWidth; } ubuf; layout(binding = 1) uniform sampler2D source; // Smooth noise function for organic liquid movement float noise(vec2 p) { return sin(p.x * 1.5) * sin(p.y * 1.5); } // Fractal noise for more complex patterns float fbm(vec2 p) { float value = 0.0; float amplitude = 0.5; for(int i = 0; i < 4; i++) { value += amplitude * noise(p); p *= 2.0; amplitude *= 0.5; } return value; } void main() { vec2 uv = qt_TexCoord0; // Create flowing liquid-like distortion vec2 flowDir1 = vec2( fbm(uv * ubuf.scale + ubuf.time * ubuf.flowSpeed), fbm(uv * ubuf.scale + ubuf.time * ubuf.flowSpeed + 100.0) ); vec2 flowDir2 = vec2( fbm(uv * ubuf.scale * 0.7 - ubuf.time * ubuf.flowSpeed * 0.8 + 200.0), fbm(uv * ubuf.scale * 0.7 - ubuf.time * ubuf.flowSpeed * 0.8 + 300.0) ); // Combine flows for more organic movement vec2 finalFlow = (flowDir1 + flowDir2 * 0.5) * ubuf.warpStrength * 0.01; // Apply subtle chromatic aberration float aberration = length(finalFlow) * 0.5; vec2 distortedUV = uv + finalFlow; // Sample with slight chromatic separation for main glass effect float r = texture(source, distortedUV + vec2(aberration, 0.0)).r; float g = texture(source, distortedUV).g; float b = texture(source, distortedUV - vec2(aberration, 0.0)).b; vec4 glassColor = vec4(r, g, b, 1.0); // Simple edge reflection - back to what worked float edgeWidth = ubuf.edgeReflectionWidth; // Calculate distance from edges float distFromLeft = uv.x; float distFromRight = 1.0 - uv.x; float distFromTop = uv.y; float distFromBottom = 1.0 - uv.y; // Find the minimum distance to any edge float minDistToEdge = min(min(distFromLeft, distFromRight), min(distFromTop, distFromBottom)); // Create edge mask float edgeMask = smoothstep(edgeWidth, 0.0, minDistToEdge); if (edgeMask > 0.0) { vec2 reflectionUV = distortedUV; // Simple reflection logic if (minDistToEdge == distFromLeft) { // Left edge - flip horizontally reflectionUV.x = 1.0 - distortedUV.x; } else if (minDistToEdge == distFromRight) { // Right edge - keep as is but sample from further right reflectionUV.x = distortedUV.x + 0.1; } else if (minDistToEdge == distFromTop) { // Top edge - flip vertically reflectionUV.y = 1.0 - distortedUV.y; } else { // Bottom edge - flip vertically reflectionUV.y = 1.0 - distortedUV.y + 0.1; } // Clamp to valid range reflectionUV = clamp(reflectionUV, 0.0, 1.0); // Sample reflection with same chromatic aberration float rRefl = texture(source, reflectionUV + vec2(aberration, 0.0)).r; float gRefl = texture(source, reflectionUV).g; float bRefl = texture(source, reflectionUV - vec2(aberration, 0.0)).b; vec4 reflectionColor = vec4(rRefl, gRefl, bRefl, 1.0); // Blend reflection with glass effect glassColor = mix(glassColor, reflectionColor, edgeMask * ubuf.edgeReflectionStrength); } // Simple glass overlay enhancement vec2 centeredUV = (uv - 0.5) * 2.0; float fresnel = pow(1.0 - abs(dot(normalize(vec3(centeredUV, 1.0)), vec3(0.0, 0.0, 1.0))), 1.5); // Add subtle white tint and fresnel glassColor.rgb = mix(glassColor.rgb, vec3(1.0), 0.02 + fresnel * 0.03); fragColor = glassColor * ubuf.qt_Opacity; }