Crea un efecto de lápiz en SVG

Mi juego Dragons Abound crea mapas en formato de gráficos vectoriales SVG. Los gráficos vectoriales tienen muchas características (por ejemplo, zoom sin pérdida), lo cual es conveniente para los mapas. Además, los gráficos vectoriales son buenos para crear líneas claras, como contornos de tinta:


Por otro lado, los gráficos vectoriales no son muy buenos para crear texturas con pequeños detalles que no se repiten. En los gráficos vectoriales, cada elemento representado está representado por una descripción de su tamaño, forma, ubicación, color, etc. Para presentar muchos pequeños detalles no repetitivos, es necesario describir una gran cantidad de elementos. Por ejemplo, para una línea de lápiz


Se requerirán decenas de miles de elementos diferentes. De hecho, cada punto gris en la imagen se establecerá por separado. Otros elementos, como las imágenes borrosas, son aún más problemáticos.

Esta es una limitación bastante seria de los gráficos vectoriales, por lo que se han agregado trucos a SVG que le permiten reproducir de manera más efectiva algunos de estos efectos de textura. Exploraré algunas de estas características SVG para crear un efecto de línea de lápiz. Por supuesto, hay muchas soluciones más complejas para recrear líneas de lápiz. Se han escrito artículos científicos completos sobre este tema . Pero solo espero crear un filtro bastante simple que proporcione un resultado aceptable.

Como siempre, preferiría tomar prestado o modificar un filtro creado por alguien más talentoso que yo, pero en este caso hubo una sorprendente escasez de filtros de lápiz vectoriales que se pueden usar como inspiración. (Suena una siniestra advertencia musical: puede haber razones para esto). Por lo tanto, de hecho, solo puedo confiar en mí mismo.

Anteriormente, yo escribí acerca de las posibilidades de los dragones abundanpara crear líneas "escritas a mano". Básicamente, luego consideré la posibilidad de evitar matemáticamente líneas rectas y crear líneas con ligeras desviaciones que se parezcan más a lo que podría dibujar la mano de una persona. Al comienzo del artículo, se muestran ejemplos de ilustraciones de montañas. Para crear un estilo de ilustración de tinta, esto es suficiente, pero no es adecuado para crear una línea de lápiz, ya que carece de una textura de lápiz.

Si observa las líneas de lápiz que se muestran arriba y abajo:


Notará muchas características que distinguen los trazos de lápiz de las líneas de tinta (o líneas dibujadas por una computadora). La diferencia más importante es que tienen una textura resultante de la forma en que el lápiz interactúa con el papel. El papel es granulado y el lápiz generalmente deja grafito en las partes altas del grano, mientras que las partes bajas permanecen blancas. En papel rugoso, la textura es más notable; dibujar cartón es tan fino que casi no crea textura. En segundo lugar, los bordes de las líneas del lápiz son bastante vagos. Esto se debe nuevamente en gran medida a la irregularidad del papel y la punta del lápiz; Esto lleva al hecho de que a lo largo del borde de la línea permanece una cantidad diferente de grafito.

(Por supuesto, hay otros efectos. El trazo de lápiz se superpone a sí mismo, por lo que se vuelve más oscura en las intersecciones de los trazos. Los trazos mismos varían en la presión y esto puede cambiar la oscuridad de la carrera a lo largo de su longitud. En este post, voy a centrar principalmente en la reconstrucción de la textura del papel.)

Para Comencé preparando simples líneas grises:


Dibujé líneas "escritas a mano" con un grosor de 4, 2 y 1 píxel. Desafortunadamente, los efectos SVG generalmente se ven diferentes para líneas de diferentes longitudes, por lo que quería comparar el efecto en diferentes tamaños.

La función principal proporcionada por SVG para agregar efectos de textura se llama filtros . Los filtros se aplican después de representar el efecto vectorial y cambiar su apariencia. Los filtros convencionales pueden realizar acciones como cambiar el color de un objeto, agregarle ruido, etc. Los filtros son un tema bastante confuso con una sintaxis compleja, por lo que no daré un tutorial completo sobre cómo usarlos, pero explicaré con suficiente detalle para que quede claro lo que hice. Y al final de la publicación, le daré un enlace a Codepen con un filtro para que pueda experimentar con usted mismo.

En primer lugar, intentaré cambiar los bordes de las líneas para que no sean suaves, pero tengan irregularidades características del grano del papel. Lo haré moviendo los píxeles de la línea. El elemento de filtro que realiza esta tarea se llama "feDisplacementMap"; mueve cada píxel en función de los valores en otra imagen. Como queremos que cada píxel se mueva de manera aleatoria pero uniforme, necesitamos pasar ruido a feDisplacementMap para controlar el movimiento. Afortunadamente, SVG tiene otro elemento de filtro llamado "feTurbulence" que está diseñado específicamente para crear ruido. Por lo tanto, podemos combinar dos filtros para rugosizar los bordes de las líneas.

La magnitud y la aspereza de la línea pueden controlarse mediante los parámetros del mapa de desplazamiento y la generación de ruido. Desafortunadamente, el desplazamiento se indica en unidades absolutas, no en relación con el tamaño de la línea. Seleccioné los parámetros, tratando de encontrar algo que se ajuste a todos los anchos de línea, pero con un aumento en la escala de desplazamiento, puede notar el problema:


Ahora el desplazamiento es tan grande que puede mover toda la línea, y no solo cambiar sus bordes. Este efecto es aún más notable en líneas finas. En este ejemplo, una línea con un ancho de 4 píxeles básicamente parece que el borde es rugoso, y las distorsiones ya son notables en una línea con un grosor de 2 píxeles. Es decir, necesito elegir un valor que no cree distorsiones en líneas finas.

Al hacer zoom con un aumento estándar en el juego, el efecto se ve así (después de seleccionar parámetros para mejorar el efecto):


A esta escala, muchos bordes ásperos se convierten en puntos y puntos. Este no es un efecto muy desagradable, y recuerda un poco a una línea de lápiz. (Sin embargo, en general, los filtros SVG parecen tener problemas con el escalado; en muchos casos, cuando se acercan, se ven bien, pero están sujetos a un algoritmo de cambio de tamaño deficiente cuando se alejan).

Aquí se ve el efecto al dibujar montañas (efecto de lápiz a la izquierda):


No es tan terrible, pero la línea tiene artefactos afilados que se ven un poco extraños. Y cuando el efecto se aplica a líneas finas y muy próximas, se superponen y fusionan como resultado:


Repito, esto no es tan terrible, y las sombras en las montañas de lápices como resultado son muy similares a las dibujadas a lápiz, si necesitas tal efecto.

Esta solución agrega rugosidad a los contornos del trazo del lápiz, pero no cambia el color uniforme del trazo. La textura también está presente dentro de trazos reales de lápiz, porque el grafito deja manchas en el papel de manera desigual.

Para agregar textura al interior del trazo, uso un filtro SVG y luego combino el ruido con el trazo:


Cuando se acerca, puede ver que el interior de cada trazo ahora está lleno de una textura de pseudo-grafito. Así es como se ve en una escala normal:


Bastante bueno, especialmente en líneas gruesas. Así es como se ve al dibujar montañas:


En esta escala, todo no es muy bueno. Tenga en cuenta que este filtro también reduce la oscuridad de las líneas; Este es un resultado natural de agregar ruido blanco a las líneas. Hasta cierto punto, este problema se puede solucionar aumentando el contraste del ruido, de modo que algunas partes de la línea de compensación se vuelvan más oscuras:


Pero como los colores de la línea ya son bastante oscuros, esto destruye en gran medida el efecto del "lápiz". Por lo tanto, si uso esto, necesito seleccionar los parámetros para crear un equilibrio agradable.

Obviamente, ambas soluciones se pueden combinar. Con un aumento, el resultado se ve bastante bien:


De la línea de lápiz esperamos tanto un borde áspero como una textura interna. En una escala estándar, todo no es tan bueno:


debido a los artefactos afilados que aparecieron en esta escala.

Un buen truco para mejorar esta textura serĂ­a agregar textura de papel al fondo:


Ahora el ojo percibe la textura uniforme en toda la imagen. Incluso a un nivel muy implícito, esto ayuda a engañar a los ojos y convencer de que la textura de la línea es causada por la interacción con el papel.

AquĂ­ hay un ejemplo del uso de este filtro en un mapa (con textura de papel):


En general, no todo está mal, pero con un estudio detallado parece que en todas partes solo se agrega ruido. Con un aumento del 200%, los artefactos se vuelven aún más obvios:


Otra forma de crear un borde áspero de una línea de lápiz es dibujar la línea varias veces con desviaciones ligeramente diferentes y opacidad reducida. En el centro de la línea, donde se cruzan varias versiones, la densidad estará cerca de la densidad de la línea original; en los bordes exteriores, donde a veces solo hay una parte de las líneas, la opacidad será menor y los bordes serán menos legibles.

En general, para implementar dicha soluciĂłn usando filtros SVG, debe usar feTurbulence y feDisplacementMap juntos para crear una versiĂłn distorsionada de la lĂ­nea. Sin embargo, para hacer esto varias veces y combinar todas las lĂ­neas al final, necesita un conjunto de primitivas feBlend. Si, por ejemplo, mezclamos tres copias, debemos reducir adecuadamente la opacidad de las lĂ­neas. (No estoy muy seguro de cĂłmo calcular especĂ­ficamente la opacidad correspondiente, pero creo que puede ser la raĂ­z cĂşbica de la luminosidad de la lĂ­nea).

Esto crea el efecto (tres lĂ­neas con un aumento):


Este enfoque tiene un par de desventajas. El filtro tiene una desviación fija, por lo tanto, afecta las líneas estrechas con mayor fuerza, y en algunos puntos se puede ver que la línea de un solo píxel está completamente dividida. En segundo lugar, es un filtro bastante complejo que crea tres desviaciones separadas y las combina; puede ser muy lento en imágenes complejas como las cartas de Dragons Abound .

Así es como se ve a escala estándar:


En mi opinión, esto no es como un boceto a lápiz, pero elimina mejor los artefactos afilados de la solución anterior.

Este enfoque se puede combinar con el filtro de textura interno descrito anteriormente y agregar textura dentro de las líneas de lápiz, así como textura de papel:


Así es como se ve después de aplicar a las montañas:


Este filtro tiende a distribuir las líneas con más fuerza que el otro filtro, esencialmente haciéndolas más gruesas. A veces genera un efecto de boceto con varias líneas, lo que no es tan malo.

AquĂ­ hay un ejemplo del uso de este filtro en un mapa:


Conserva la oscuridad original mejor que el primer filtro, y aunque en mi opinión no se ve exactamente como un lápiz, el efecto es bastante agradable. Con un aumento del 200%:


Cuando se amplía, este filtro no adquiere artefactos agudos del primer filtro. El efecto de las líneas de intersección en líneas finas (por ejemplo, como en la imagen de un bosque) comienza a parecer bastante artificial, pero las líneas más anchas (montañas y ríos) aún se ven bien. Sin embargo, dentro de las líneas negras, como los ríos, el ruido interno se pierde casi por completo.

Publiqué ambos filtros en Codepen para que pueda probarlos usted mismo. El primer filtro está aquí , el segundo está aquí . Recomiendo experimentar con ellos e intentar mejorarlos, y si obtienes algo mejor que el mío, ¡házmelo saber! ¡Me gustaría tener un muy buen filtro de lápiz!

All Articles