Create a Dynamic Mouse-Following Lens Effect with Three.js and GLSL

Aug 25, 2026 689 views

Crafting an Interactive Mouse-Following Square Lens Effect with Three.js and GLSL

Explore a detailed guide on creating an engaging mouse-following lens effect, featuring image distortions, RGB shifts, and dynamic shaders, using Three.js and GLSL.

Interactive Mouse-Following Square Lens Effect

Editor’s Note: We’re excited to welcome Tomoyuki Nakata, a Creative Developer at baqemono, as a contributor to our Three.js special feature leading up to the inaugural Three.js conference in Paris. He’s showcasing this fascinating mouse-following lens effect crafted using Three.js and GLSL. Join us in this captivating journey!

🇫🇷 Still on the fence about attending? Don’t miss your chance to grab a ticket to the first-ever Three.js conference in Paris! Use code CODROPS for 15% off and secure your spot before they run out →

Concept Overview

Imagine merging a black-and-white image with a full-color one, creating an effect where a square area nimbly follows your mouse cursor. In this tutorial, we'll tackle the development of just such an effect using Three.js and GLSL.

The core involves layering two images—the grayscale one serves as the backdrop, while the color image is displayed only where the mouse pointer directs this square. To enhance the interaction, we’ll introduce lens distortion and radial RGB shifts within the square area, all while giving the grayscale layer a dynamic wave and noise texture effect.

Despite appearances, this visually rich effect is constructed from fundamental components. We will fashion a square mask that retains its proportions across various screen sizes, apply both the lens and RGB shifting effects in the fragment shader, and enable smooth animation as the square tracks the mouse seamlessly. Additionally, a graphical user interface (GUI) will allow for real-time adjustments to parameters.

The inspiration for this project sprang from a Pinterest design showcasing a similarly styled effect—where a grayscale image's colored section appeared to be cut out by a lens effect square. You can view the original inspiration here. I envisioned that implementing it with WebGL could yield even more fascinating outcomes, particularly with mouse interactivity and unique grayscale effects. Thus, the idea for our interactive lens effect was born.

Elements of the Final Effect

The completed effect comprises several key components:

  • A full-screen grayscale image.
  • A color image displayed solely within the square's confines.
  • A lens distortion effect reminiscent of a CC Lens that bulges outward from the square's center.
  • A pronounced RGB shift that escalates towards the square's perimeter.
  • A dynamically resizing square mask that retains its shape regardless of screen dimensions.
  • Smooth mouse tracking with a slight delay for a more fluid interaction.
  • Wave patterns and random distortions applied to the grayscale image for added depth.
  • A GUI that supports real-time parameter adjustments.

While the end result may appear intricate, there are no extensive post-processing techniques or complicated 3D models involved; instead, we achieve the entire effect through a fragment shader by harmonizing the listed components.

Organizing the Project Files

The project structure for this tutorial is neatly organized as follows:

src/
└── scripts/
    ├── webgl/
    │   ├── glsl/
    │   │   ├── chunks/
    │   │   │   ├── ccLens.glsl
    │   │   │   ├── coverUv.glsl
    │   │   │   └── random3.glsl
    │   │   ├── frag/
    │   │   │   └── frag.glsl
    │   │   └── vert/
    │   │       └── vert.glsl
    │   ├── mesh/
    │   │   └── Mesh.ts
    │   ├── stage/
    │   │   └── Stage.ts
    │   └── Webgl.ts
    └── index.ts
  • glsl: Contains reusable functions, with chunks for shader utilities, frag for fragment shaders, and vert for vertex shaders.
  • mesh (Mesh): Responsible for window resizing, loading textures, creating meshes, sizing them correctly, and updating uniforms.
  • stage (Stage): Manages the scene setup, viewport sizing, camera creation, and rendering updates.
  • Webgl: Initializes the Mesh and Stage classes while connecting the GUI and handling animation loops.

This class structure is quite straightforward, allowing us to direct our focus primarily on the implementation within the fragment shader.

Final Thoughts on Creating Visual Effects

As we wrap up this exploration of crafting a visually dynamic effect, it’s clear that the integration of various techniques can yield stunning results. What’s particularly fascinating about this process is the way that breaking down complex visuals into manageable components allows for creativity and experimentation. You can easily adjust parameters to develop a unique aesthetic tailored to your vision. Moreover, while the implementation discussed might seem intricate, it serves as a reminder that foundational concepts in graphics programming—like UV mapping, distortion effects, and parameter control—can provide a playground for further innovation. If you’re working in web development or game design, consider this a springboard. You can refine existing methods or invent entirely new ones by drawing inspiration from everyday visuals or art you encounter. That said, the potential for further exploration is vast. Whether it’s experimenting with shaders or exploring uncharted aspects of user interaction, the possibilities are limited only by your imagination. The skills and concepts you’ve learned here can be applied in myriad ways—so don’t hesitate to experiment beyond the provided framework. Lastly, if you stumble upon an intriguing visual or a creative technique in your daily life, think about how to translate it into code. It’s all about recognizing potential and transforming it into something that resonates with users. If you have feedback or questions regarding the techniques discussed, I’d love to hear from you on X. Thank you for joining me on this journey into the realm of visual effects!
Source: Tomoyuki Nakata · tympanus.net

Comments

Sign in to comment.
No comments yet. Be the first to comment.

Related Articles

Building a Mouse-Following Square Lens Effect with Three....