ProyectosExperimentos
Grid TSL
Un material de grilla procedural para suelos en Three.js con WebGPU y TSL: líneas principales, secundarias y cruces, filtradas para que no aparezcan moiré ni parpadeo, ni a lo lejos ni en ángulos rasantes.
- Estado
- Activo
- Periodo
- 2025.09 — actualidad
- Tipo
- Librería / paquete
- Rol
- Proyecto individual, Shaders, Optimización de rendimiento
- Tecnologías
- Three.js
- WebGPU
- TSL
- Vite
- Enlaces
- Log de desarrollo
- 1 entrada
Contexto y objetivo
Una grilla de suelo es de los primeros elementos de casi cualquier escena 3D, y también de los que peor se ven si no están bien filtrados: a lo lejos las líneas se vuelven más finas que un píxel, parpadean al mover la cámara y forman patrones de moiré.
La primera versión, de septiembre de 2025, era un material con dos capas de líneas y una de cruces, con presets fijos y una variante triplanar. La versión 2, de noviembre de 2026, es una reescritura desde cero: un único material para suelos, con todas las capas filtradas, todos los parámetros editables en vivo y empaquetado para usar en otros proyectos.
Demo interactiva
Arrastrá para girar la cámara y bajala hasta un ángulo rasante: a lo lejos la grilla se vuelve un tono parejo, sin moiré. Con #debug al final de la URL aparece el panel del material en el Inspector de three.js, que permite editar cada parámetro y copiar la configuración como JS o JSON. Necesita un navegador con WebGPU.
Cómo se filtra
- Huella anisotrópica del píxel: las derivadas de la posición se calculan una sola vez y por eje. En ángulos rasantes, cada dirección se filtra según lo que de verdad cubre en pantalla.
- Líneas: con la técnica pristine grid de Ben Golus, el ancho dibujado nunca baja de un píxel, pero su intensidad se reduce en la misma proporción, así las líneas finas no parpadean. Cuando una celda ocupa menos de unos dos píxeles, la capa converge a su cobertura media: a lo lejos se ve un tono parejo en lugar de moiré.
- Cruces: cada brazo es una línea filtrada multiplicada por una banda con un filtro de caja analítico, que conserva la energía. El grosor y el largo de los brazos también convergen a su media.
- Composición en espacio lineal según la cobertura de cada capa: fondo, líneas secundarias, cruces y líneas principales.
Como paquete
Se instala con npm y usa el three.js del proyecto que lo importa, sin otras dependencias:
import { GridMaterial } from 'grid-tsl'
const material = new GridMaterial({
primaryColor: '#5c6370',
secondarySpacing: 0.5,
fadeRadius: 80,
})
material.crossSize = 0.3 // cualquier parámetro se cambia en vivo
grid-tsl: el material y sus valores por defecto.grid-tsl/debug: un panel en el Inspector de three.js que edita el material y copia los parámetros como JS o JSON. Se importa de forma dinámica, así no entra en el bundle de producción.grid-tsl/nodes: las funciones de TSL sueltas, para armar un material propio.
Para que el shader sea liviano, los valores derivados (inversas, proporciones respecto de la celda, radios del fundido) se calculan en la CPU al cambiar un parámetro, y el fundido circular solo se compila si está activado: apagado, el material es opaco y no tiene ese código ni blending.
Resultados y limitaciones
- La grilla se proyecta sobre el plano XZ del mundo, así que solo sirve para superficies horizontales. La variante triplanar de la versión 1, para objetos sin UV, ya no existe.
- La versión 2 cambió los nombres de los parámetros y eliminó los presets: un proyecto que usaba la versión 1 tiene que adaptarse. La 1 sigue disponible en el tag
v1.0.0. - Necesita un navegador con WebGPU.
Créditos
- Ben Golus, The Best Darn Grid Shader (Yet), para el filtrado de las líneas.
- Inigo Quilez, Filtering procedurals, para el filtro de caja de las cruces.
- La versión 1 partió del devlog de Bruno Simon Procedural Grid with TSL.
Log de desarrollo
Grid TSL v2: lo que saqué y lo que mejoró
Una reescritura desde cero: menos variantes y presets, y una grilla que ya no hace moiré en ninguna de sus capas.

