Controls

Text

Font Size (px)

Radius

0.15

Blur

0.50

Max Distortion

0.01

Twist

0.5

Bulge

0.2

Noise

0.50

Aberration

1.00

Description

Features multiple lens-like distortions modulated by cursor proximity. Instead of a single effect, we combine rotational, radial, and chaotic displacements to simulate a complex optical anomaly.

The foundation is the Influence Mask. We calculate the distance from the mouse to the pixel, corrected for aspect ratio, and create a smooth falloff value influence. This ensures the effect serves as a spotlight, leaving the edges of the canvas untouched:

vec2 dir = u_mousePos - texCoord;
float distance = length(dir * aspect);
float influence = smoothstep(u_radius, 0.0, distance);

The first optical effect is Twist. We rotate the texture coordinates around the mouse center. The angle of rotation depends on the influence mask, creating a spiral vortex at the center that fades out at the edges:

float angle = influence * u_twist;
float s = sin(angle), c = cos(angle);
vec2 twistedDir = vec2(dot(dir, vec2(c, -s)), dot(dir, vec2(s, c)));

Next, we add Bulge & Pinch. By scaling the direction vector based on distance, we can push pixels outward (magnifying) or pull them inward. We combine this with the Twist result to build our primary distortion vector:

vec2 bulgeOffset = dir * (1.0 - influence * u_bulge) - dir;
vec2 distortion = (twistedDir - dir) * 0.5 + bulgeOffset;

To break up the perfection of the lens, we introduce Digital Noise. We use a pseudo-random hash function to jitter the coordinates slightly, adding a "glitchy" texture to the distorted area:

float n = noise(texCoord * 20.0 + u_time);
distortion += vec2(n) * influence * u_noise * 0.1;

Finally, we apply a Radial Blur with Chromatic Aberration. We sample the texture multiple times along the distortion vector, splitting the RGB channels to simulate spectral dispersion at the edges of the lens:

vec2 chromaOff = direction * influence * u_chroma * 0.05;
float r = texture(tex, uv + chromaOff).r;
float b = texture(tex, uv - chromaOff).b;