Lección 1 de 10 · Patrones en shaders
Figuras
Anillos, cuadrados, diamantes. Cada forma es una ecuación de distancia.
En Start Here cada pixel preguntaba ¿qué color soy? Una forma responde una pregunta más fina: ¿qué tan lejos estoy de esta orilla?
Antes de medir distancias, una herramienta nueva: M. Es un vec2 que siempre trae la posición del mouse, normalizada entre 0 y 1, viene del navegador y se actualiza en cada frame. En el shader la traducimos al mismo espacio que p con una sola línea:
vec2 m = (2.*M*R - R) / min(R.x, R.y);
Ahora m vive en el mismo mundo que p, el cursor es una coordenada más, lista para entrar a las ecuaciones.
Cada forma es una función de distancia. length(p) - .65 es positivo afuera del anillo, negativo adentro, y cero exactamente en la orilla. Lo mismo pasa con el cuadrado y con el diamante, solo cambia la manera de medir.
Una ecuación. Una forma. Tres reglas para medir distancia.
M viene del navegador, el mouse en coordenadas normalizadas (0 a 1). m es M traducido al mismo espacio que p, donde el centro de la pantalla es (0,0). Esa fórmula (2.*M*R - R) / min(R.x, R.y) la vas a ver en cada lección con interacción.length(p), la regla recta desde el centro. El cuadrado mide con max, la coordenada más grande gana. El diamante mide con +, la suma de las dos coordenadas. Tres reglas, tres geometrías..65 del anillo a .85 y el anillo se aleja del centro.El código
void main(){
vec2 p = (2.*gl_FragCoord.xy - R) / min(R.x, R.y);
vec2 m = (2.*M*R - R) / min(R.x, R.y);
vec3 col = vec3(0.025, 0.018, 0.035);
float dRing = abs(length(p) - .65);
vec2 sq = abs(p) - .42;
float dSquare = max(sq.x, sq.y);
float dDiamond = abs(p.x) + abs(p.y) - .25;
float hRing = exp(-abs(length(m) - .65) * 3.);
vec2 msq = abs(m) - .42;
float hSquare = exp(-abs(max(msq.x, msq.y)) * 3.);
float hDiamond = exp(-abs(abs(m.x) + abs(m.y) - .25) * 3.);
vec3 cRing = vec3(.98, .55, .12);
vec3 cSquare = vec3(.85, .25, .08);
vec3 cDiamond = vec3(.96, .80, .28);
col += cRing * smoothstep(.018, 0., abs(dRing))
+ cRing * exp(-abs(dRing) * 5.) * (.30 + hRing * .9);
col += cSquare * smoothstep(.018, 0., abs(dSquare))
+ cSquare * exp(-abs(dSquare) * 5.) * (.30 + hSquare * .9);
col += cDiamond * smoothstep(.018, 0., abs(dDiamond))
+ cDiamond * exp(-abs(dDiamond) * 5.) * (.30 + hDiamond * .9);
gl_FragColor = vec4(col, 1.);
}