Qué estás viendo
La estela no es una lista de posiciones anteriores. Nada aquí recuerda por dónde ha pasado el puntero.
Hay dos texturas. Cada fotograma lee una, la atenúa un poco, estampa encima el segmento que el puntero acaba de recorrer, y escribe el resultado en la otra. Después se intercambian. La cola que se desvanece es simplemente lo que queda de cada estampado anterior después de multiplicarlo por el factor de atenuación unos cuantos cientos de veces.
Por qué un shader y no un canvas 2D
Pintar negro translúcido sobre un canvas 2D en cada fotograma hace aproximadamente lo mismo, y es la forma habitual de conseguirlo. Tiene dos problemas.
El primero es que es una lectura-modificación-escritura de toda la superficie en la CPU, cada fotograma. El segundo se ve: los canales tienen 8 bits y la operación satura, así que en cuanto un píxel alcanza el color de fondo deja de cambiar, y las colas largas se escalonan en bandas visibles.
En la GPU la atenuación es una multiplicación en coma flotante sobre todos los téxeles a la vez, y la cola se disuelve hasta desaparecer.
El pincel es un segmento
Entre dos fotogramas el puntero se ha desplazado varios píxeles. Estampar un disco en su posición deja una línea de puntos en cuanto mueves la mano deprisa.
float segmentDistance(vec2 p, vec2 a, vec2 b) {
vec2 pa = p - a;
vec2 ba = b - a;
float h = clamp(dot(pa, ba) / max(dot(ba, ba), 0.0001), 0.0, 1.0);
return length(pa - ba * h);
}
El pincel es la distancia al segmento completo recorrido desde el fotograma anterior. Eso es lo que convierte un gesto rápido en un trazo continuo.
La cola, en fotogramas
El control de atenuación se lee mejor como duración: una estela conserva alrededor de 1 / (1 - decay) fotogramas de historia.
decay 0.90 -> 10 fotogramas
decay 0.96 -> 25 fotogramas
decay 0.99 -> 100 fotogramas
Por eso el panel muestra ese número junto al valor: 0,96 no dice nada por sí solo, y "25 fotogramas" sí.