#version 330 in vec2 fragTexCoord; in vec4 fragColor; uniform sampler2D texture0; uniform sampler2D distanceFieldTex; uniform vec2 resolution; uniform vec2 mousePos; uniform float ballRadius; uniform float shapeInfluence; out vec4 finalColor; float getBallInfluence(vec2 pos, vec2 center, float radius) { vec2 diff = pos - center; float distSq = dot(diff, diff); float radiusSq = radius * radius; if (distSq > radiusSq) return 0.0; float dist = sqrt(distSq); return 1.0 - (dist / radius); } float getShapeInfluence(vec2 pos) { vec2 uv = pos / resolution; uv.y = 1 - uv.y + 0.045; // invert y and offset to match with wallpaper texture if (any(lessThan(uv, vec2(0.0))) || any(greaterThan(uv, vec2(1.0)))) { return 0.0; } float signedDistance = texture(distanceFieldTex, uv).r * 255.0 - 128.0; float isInside = step(signedDistance, 0.0); float isOutside = 1.0 - isInside; // inside calculation float normalizedDist = abs(signedDistance) * 0.015625; // 1/64 float insideInfluence = shapeInfluence * exp(-normalizedDist * 0.5) * 3.0; // outside calculation float adjustedDistance = signedDistance * 0.5; float shapeInfluenceSq = shapeInfluence * shapeInfluence; float outsideInfluence = shapeInfluenceSq / (adjustedDistance * adjustedDistance + shapeInfluence) + shapeInfluence * 0.8 * exp(-signedDistance * 0.025); // 1/40 return isInside * insideInfluence + isOutside * outsideInfluence; } void main() { vec2 pixelPos = fragTexCoord * resolution; float ballValue = getBallInfluence(pixelPos, mousePos, ballRadius); float shapeValue = getShapeInfluence(pixelPos); float totalValue = ballValue + shapeValue * 0.01; float mask = step(0.75, totalValue); finalColor = vec4(mask, mask, mask, 1.0); }