06 Capítulo 6 · Lección 11

Shaders Reactivos al Mouse

Redactado por
Author Sebastian V.
Fecha de publicación

30/04/2026

Tiempo de lectura

6 min

Tema

Shaders GLSL

Tocando el Canvas

Hemos animado nuestros shaders con el tiempo (u_time). Eso los hace estar vivos. Pero para que la experiencia sea verdaderamente inmersiva y premium, el shader debe reaccionar a las acciones del usuario. La interacción número uno en web de escritorio es el movimiento del ratón.

El Uniform del Mouse

Para lograr esto, necesitamos enviar un nuevo uniform desde nuestro archivo JavaScript hacia la GPU. Lo llamaremos u_mouse y será un vector de dos dimensiones (vec2).

Normalización: El secreto

La posición del ratón en la pantalla del usuario puede ser (1920, 1080) píxeles. Si mandamos esos números brutos a un shader que trabaja con coordenadas UV entre 0.0 y 1.0, el shader se volverá loco. Siempre debes normalizar la posición del ratón en JS dividiendo la coordenada actual entre el ancho o alto total de la ventana.

Consejo profesional

En lugar de enviar la posición exacta y fría del ratón en cada frame, usa una función de interpolación lineal (Lerp) en tu archivo JavaScript. Esto hará que el shader persiga al cursor con un pequeño retraso suave, dándole una sensación fluida y lujosa a la interacción.

El Cursor como Linterna

> _
let targetMouse = new THREE.Vector2();
let currentMouse = new THREE.Vector2();

window.addEventListener('mousemove', (e) => {
  // Normalizamos de 0 a 1
  targetMouse.x = e.clientX / window.innerWidth;
  targetMouse.y = 1.0 - (e.clientY / window.innerHeight);
});

function animate() {
  // Lerp para suavidad premium (Inercia)
  currentMouse.lerp(targetMouse, 0.05);
  material.uniforms.u_mouse.value = currentMouse;
}
> _

Pasa el ratón por el área. El Fragment Shader reacciona en tiempo real, calculando la distancia a tu cursor suavizado.

Errores comunes

01
El mouse no actualiza en tiempo real Estás actualizando el uniform del mouse fuera del loop de requestAnimationFrame. Mándalo dentro del loop, no en el evento mousemove directamente.
02
La luz sigue al ratón de toda la ventana, no del canvas Usaste event.clientX directamente sin restarle el getBoundingClientRect() del contenedor. La luz aparecerá desplazada si el canvas no está en la esquina superior izquierda de la pantalla.

Practica lo aprendido

Haz que tu shader sienta.

01 Normaliza siempre los eventos del ratón (clientX / innerWidth).
02 Usa interpolación lineal (Lerp) para suavizar el movimiento.
03 Envía el u_mouse como vec2 a tu Fragment Shader y úsalo para dibujar luz.