Processing 5 y WebGL
Hasta ahora trabajamos con un espacio de dos dimensiones, que es básicamente mover figuritas en X e Y, que sería el equivalente a poner cartas sobre una mesa cuando jugamos al solitario.
En la web hay un estándar llamado WEBGL, que es como un "acuerdo" entre quienes desarrollan los navegadores web en diversas plataformas (Safari, Firefox, Opera, navegadores Moviles de Celulares, Realidad Virtual, etc.) pero si quisiéramos programar un sencillo cubo en javascript nos llevaría una considerable cantidad de código y conocimiento.
P5*Js, por su parte, nos facilita gran parte de el esfuerzo para poder concentrarnos en los aspectos creativos.
Antes que nada debemos descargar el archivo comprimido (descomprimir, y cargar la carpeta en brackets).
Motor WEBGL
Como se ve en la imagen de abajo, en la línea 9 al invocar createCanvas() siempre utilizamos 2 calores, uno para el ancho y otro para el alto. Para activar el motor 3D, debemos usar un tercer parámetro que es WEBGL (en mayúsculas).
Para éste caso, reempazamos los valores numéricos (usualmente eran 1000 de ancho y 600 de alto) por windowWidth (ancho de la ventana) y windowHeight (alto de la ventana) para que el canvas sea todo el espacio en el navegador. Si cambiamos el tamaño del mismo, debemos refrescar la vista (tecla F5) para que el canvas se escale al nuevo tamaño de la ventana.
En el function Draw, es justamente donde indicamos que elementos vamos a dibujar en la pantalla. En la línea 18, background(0,0,0) implica que no tendrá ningún valor en rojo, verde y azul respectivamente, y por eso el fondo queda negro.
En la línea 19 usamos sphere() para crear el primer objeto, y aquí es donde aparece nuestra primer GRAN DIFERENCIA. En el espacio 2D, el punto 0 (cero) estaba en el margen superior derecho, en cambio, cuando WEBGL está activo, el punto de origen o punto 0 está en el centro del canvas.
Creando más Objetos
En el espacio 3D de WEBGL, no se puede posicionar objetos como hacíamos en el espacio 2D, de hecho, debemos mover el punto de origen y crear un nuevo objeto. Como ya vimos en la clase de geometrías 2D, usábamos translate para mover el origen en 2D con 2 valores (x,y respectivamente), pero en éste caso pondremos 3 valores para indicar la posición horizontal, vertical, o la de profundidad (que por defecto apunta hacia la cámara).

Me gusta explicar el proceso como un perrito que deja su "regalito" en la vereda 💩, el perrito (en especial cierta parte por donde sale la misma) vendría a representar al punto de origen (punto CERO). Luego con translate() es como tomar la correa del mismo, caminar 200 pasos en línea recta (eje de las X) hacia la izquierda como se ve en la línea 22 para que deje otro 💩 que representaría al cubo (BOX), luego subimos 100 por el ascensor del edificio y retrocedemos 100 pasos para que el perrito deje un nuevo 💩(el CONO), y finalmente subimos a la terraza para que lo haga una vez más (el cuerpo geométrico TORO).
Como verán, el tercer valor, que es la profundidad, está siempre en cero, pero ahora haremos algunos cambios.
Rotar Objetos
En este ejemplo puse nuevos valores a la tercer posición y en la línea 20 agregué un rotateX(-0.6) que rota todos los objetos en el eje X (rojo) hacia atrás. Como hicimos en la clase anterior de transformaciones, reemplazaré el número con el contador de cuadros frameCount, que al iniciar vale 1, luego 2, luego 3... de forma muy rápida, así que lo dividiré por 100 para obtener una velocidad más lenta (distintos divisores nos darán un cambio de velocidad).
Para la rotación también tenemos rotateY y rotateZ, en ambos casos usaré mouseX y mouseY para controlarlos (pero con un divisor 100 para que la rotación sea más controlable).
En éste nuevo ejemplo que vemos en la imagen de abajo, se puso una rotaciónZ un translate y un box, luego se copia/pega ese bloque para tener varios cubos con la misma rotación lo que hará que se vayan sumando.
Cada una de éstas transformaciones, afectan a todos los objetos que siguen en el código, por lo tanto el último objeto recibirá o heredará las rotaciones de los objetos que están más arriba.
Para quienes les gustan los retos, les digo que hagan si propio hombrecito de Minecraft, requiere unos cuantos cubos.
El archivo de trabajo con el que empezamos, cuenta con nuevas imágenes que usaremos con WEBGL, como planetas y vistas de panorámicas de 360 grados. Ahora usaremos solo las variables imagen2 e imagen3 que que tienen cargadas las texturas de una pelota de fútbol y de básquet.
Como ocurre con el translate y el rotateX/Y/Z, usar texture() indica que todos los objetos tienen esa textura hasta indicar una nueva. Para el ejemplo redefiní varias veces, para obtener una de cada una intercaladas.
//código del sketch.js
var imagen1;
var imagen2;
var imagen3;
var imagen4;
var a=0;
function setup() {
createCanvas( windowWidth , windowHeight , WEBGL );
imagen1 = loadImage ("imagenes/tierra.jpg");
imagen2 = loadImage ("imagenes/futbol.jpg");
imagen3 = loadImage ("imagenes/basquet.jpg");
imagen4 = loadImage ("imagenes/luna.jpg");
}
function draw() {
background(0,0,0)
rotateX(frameCount/100)
rotateY(mouseX/100)
rotateZ(mouseY/100)
texture(imagen3)
box()
texture(imagen2)
rotateZ(frameCount/50)
translate(100,0,0)
cone()
texture(imagen3)
rotateZ(frameCount/50)
translate(100,0,0)
sphere()
texture(imagen2)
rotateZ(frameCount/50)
translate(100,0,0)
torus()
texture(imagen3)
rotateZ(frameCount/50)
translate(100,0,0)
cylinder()
texture(imagen2)
rotateZ(frameCount/50)
translate(100,0,0)
ellipsoid()
texture(imagen3)
rotateZ(frameCount/50)
translate(100,0,0)
plane()
}
Un buen ejercicio para entender como funciona la rotación, siempre les sugiero hacer un mini sistema solar, totalmente fuera de escala obvio (si la tierra y la luna estuvieran a la distancia correcta y del tamaño apropiado, serían pequeños puntos que entran y salen del canvas), pero podemos indicarle el tamaño del objeto primitiva con un número dentro de los paréntesis del mismo, por ejemplo: sphere(150) para el sol.
Considerando que el eclipse fué la semana pasada, incluí el rotateZ de la línea 21 para que pueda verse desde arriba o abajo la rotación y la translación.
//código del sketch.js
var imagen1;
var imagen2;
var imagen3;
function setup() {
createCanvas( windowWidth , windowHeight , WEBGL );
imagen1 = loadImage ("imagenes/sol.jpg");
imagen2 = loadImage ("imagenes/tierra.jpg");
imagen3 = loadImage ("imagenes/luna.jpg");
}
function draw() {
background(0,0,0)
rotateY(frameCount/50)
rotateZ( -mouseY/500)
texture(imagen1)
sphere(150)
rotateY(frameCount/50)
texture(imagen2)
translate (400,0,0)
sphere(50)
rotateY(frameCount/50)
texture(imagen3)
translate (100,0,0)
sphere(20)
}