The Book of Shaders by Patricio Gonzalez Vivo & Jen Lowe

日本語 - 中文版 - 한국어 - Español - Français - Italiano - Deutsch - English


Dibujando con algoritmos

Funciones de forma

Este capítulo se podría llamar "La lección de la cerca del Sr Miyagi". Anteriormente normalizamos la posición de x e y al canal de rojo y verde. Esencialmente creamos una función que tomaba dos vectores dimensionales (x e y) y devolvía un vector de cuatro dimensiones (rojo, verde, azul y transparencia). Pero antes de ir mas lejos, transformando valores entre dimensiones, necesitamos comenzar con algo sencillo... mucho mas sencillo. Eso significa comprender las funciones unidimensionales. A mayor tiempo y energía que pongas en aprender esto, mejor será tu karate.

The Karate Kid (1984)

El siguiente código va a ser nuestra cerca. Dentro del código visualizamos el valor normalizado de la coordenada x (st.x) de dos maneras: una visualizando el brillo (observa el bonito gradiente de fondo del negro al blanco) y otra dibujando una línea verde arriba (en este caso el valor de x es asignado directamente al valor de y). No te enfoques mucho en la función plot, la veremos en detalle en unos momentos.

Nota rápida: el constructor de vec3 "entiende" que quieres asignar tres colores con la misma variable, mientras que el vec4 entiende que quieres crear un vector tridimensional con un cuarto valor (en este caso el que controla el alpha). Mira por ejemplo la línea 20 y la 26 de arriba.

Este código es tu cerca; es importante observarlo y entenderlo. Volverás aquí una y otra vez, a este espacio entre el 0.0 y el 1.0. Aprenderás el arte de doblar y dar forma a esta línea.

Esta relación par entre x e y (o el brillo) es conocida como interpolación lineal. Desde aquí podemos utilizar funciones matemáticas para darle forma a esta línea. Por ejemplo podemos elevar x a la quinta potencia para generar una línea curva.

Interesante ¿No? En la línea 19 puedes probar diferentes exponentes: 20.0, 2.0, 1.0, 0.0, 0.2 o 0.02 por ejemplo. Entender esta relación entre el valor y el exponente nos será muy útil. Usar este tipo de funciones matemáticas aquí y allá nos dará un control expresivo sobre nuestro código, como si fuese un tipo de acupuntura con el que manejas el flujo de los valores.

pow() es una función nativa en GLSL y hay muchas mas. La mayoría de ellas son aceleradas por hardware, lo que significa que, usadas de la forma correcta, harán tu código mucho mas rápido.

Reemplaza la función de la línea 19. Prueba otras como: exp(), log() y sqrt(). Algunas de estas funciones son mucho mas interesantes cuando las usamos con PI. En la línea 5 definí un macro que reemplaza cualquier llamado a PI por el valor 3.14159265359.

Step y Smoothstep

GLSL también cuenta con algunas funciones únicas de interpolación, que también son aceleradas por hardware.

La interpolación step() recibe dos parámetros. El primero es el límite o umbral, el segundo es el valor que queremos chequear. Cualquier número por debajo del límite devuelve 0.0 todo lo que lo supere devuelve 1.0.

Intenta cambiar el límite en la línea 20 del siguiente código.

La otra función única es el smoothstep(). Dado un rango de dos números y un valor, esta función interpola el valor entre el rango definido. Los primeros dos parámetros son para el comienzo y el final de la transición, el tercero es el valor a interpolar.

En el anterior ejemplo, en la línea 12, hemos usado smoothstep para dibujar una línea verde en la función plot(). Por cada posición en el eje x esta función crea una salto en un valor particular de y. ¿Cómo? Conectando dos smoothstep() juntos. Observa la siguiente función y reemplaza la línea 20 por esta, y piensa en ella como un corte vertical. El fondo de parece a una línea ¿No?

    float y = smoothstep(0.2,0.5,st.x) - smoothstep(0.5,0.8,st.x);

Seno y Coseno

Cuando queremos usar un poco de matemática para animar, dar forma o mezclar valores, no hay nada mejor que ser amigos del seno y del coseno.

Estas dos funciones básicas trigonométricas trabajan juntas creando círculos y son mas útiles que la navaja suiza de MacGyver. Es importante saber como se comportan y de que forma pueden ser combinadas. En pocas palabras, dado un ángulo (en radianes) devolverán la posición de x (coseno) e y (seno) de un punto en el borde de un círculo con un radio igual a 1. Como estas funciones devuelven un valor normalizado (entre -1 y 1) y suavizado, terminan siendo una herramienta increíble.

Como es difícil describir la relación entre las funciones trigonométricas y los círculos, la hermosa animación de arriba hace el trabajo de explicarlo visualmente.

Presta mucha atención a esta curva sinusoidal. Nota como los valores de Y fluyen suavemente entre -1 y 1. Como vimos en el anterior capítulo, podemos utilizar el comportamiento rítmico de sin() para animar propiedades. Si estás leyendo este ejemplo en un navegador, puedes modificar la fórmula que aparece aquí arriba y ver cómo cambia la onda. (Nota: No olvidar el punto y coma al final.)

Completa los siguientes ejercicios y presta atención a lo que sucede:

Otras funciones útiles

Al final del último ejercicio hemos introducido algunas funciones nuevas. Ahora es el momento de experimentar con cada una descomentenando las siguientes lineas, de a una. Es importante entender estas funciones y estudiar como se comportan. Ya lo sé ¿Para qué? Si buscas rápidamente en Google "Arte Generativo" vas a entender el porque. Ten en cuenta que estas funciones son nuestra cerca. Estamos dominando el movimiento en una sola dimensión, arriba y abajo. ¡Pronto, será el momento de agregar la segunda, la tercera y la cuarta dimensión!

Anthony Mattox (2009)

Funciones de forma avanzadas

Golan Levin tiene en su página documentación muy útil sobre cómo generar formas complejas con funciones. Trasladar estas funciones a GLSL es una muy buena forma de comenzar a generar nuestras propias piezas de código.

Como los chefs que colectan especias e ingredientes exóticos, los artistas digitales y creative coders tienen un amor particular por crear sus propias funciones de dibujo.

Iñigo Quiles tiene una gran colección de funciones útiles. Después de leer este artículo echa un vistazo a la traducción de esas funciones a GLSL. Presta atención a los pequeños cambios necesarios, como poner "." (punto) en los valores flotantes y usar los nombres en GLSL de las funciones en C; por ejemplo en vez de powf() usamos pow():

Para que te mantengas motivado, aqui hay un elegante ejemplo (hecho por Danguafer) de alguien que logró dominar su karate en las funciones.

En el Siguiente >> capítulo comenzaremos a usar nuevos movimientos. Primero mezclaremos color y luego dibujaremos formas.

Ejercicio

Presta atención a la siguiente tabla de ecuaciones hecha por Kynd. Observa como combina las funciones y sus propiedades para controlar los valores de 0.0 a 1.0. Ahora es el momento de practicar replicando estas funciones. Recuerda que cuanto más practiques esto, mejor será tu karate.

Kynd - www.flickr.com/photos/kynd/9546075099/ (2013)

Para tu caja de herramientas

Estas son algunas herramientas que te ayudaran a visualizar este tipo de funciones.

OS X Grapher (2004)

Iñigo Quilez - GraphToy (2010)

Toby Schachman - Shadershop (2014)