Introducción a Three.js, la librería 3D número uno para HTML5
Three.js es una librería bastante liviana y muy eficiente para generar y animar gráficos en 3D dentro del navegador, aprovechando las grandes novedades que nos ofrece HTML5 para la generación de contenidos multimedia. Aprovecha tanto las capacidades de HTML5 que es capaz de generar escenas 3D con WebGL, Canvas (2D) y SVG.
Su código está disponible en GitHub y en su web podemos encontrar ejemplos alucinantes de lo que se puede a llegar a hacer con Three.js.
Posibilidades de diseño
Three.js no es popular solo porque es simple a la hora de usarlo a través de JavaScript, sino porque tiene un equilibrio perfecto entre el diseño y la programación.
Permite, entre otras cosas, importar archivos 3D a partir de Blender o Maya, pudiendo generar terrenos u objetos totalmente complejos y de gran calidad.
La librería también incorpora potentísimos shaders que se pueden personalizar con OpenGL Shading Language (GLSL). Y sin duda incorpora todo lo necesario para crear escenas 3D, como son la posibilidad de manipular luces, cámaras, animar objetos, perspectivas, control de visualizaciones y mucho más.
Conceptos básicos
Antes de empezar, vemos el siguiente ejemplo simple que podremos realizar fácilmente tras haber visto los conceptos básicos.
Lo primero que tenemos que tener es nuestro archivo HTML listo para insertar la ventana donde se visualizará todo el 3D, de una forma muy simple, ya que el objeto del Canvas nos los genera Three.js.
Lo primero es descargar la librería para poderla usar, que pesa unos 300kb. Para realizar la prueba haremos que la visualización ocupe toda el espacio del navegador y lo haremos mediante CSS.
Creando la escena
Para interactuar con Three.js lo haremos a través del objeto THREE
, que nos brinda todos los elementos necesarios.
Lo primero de todo es generar el renderizador, que en este caso usaremos el de WebGL, que es el más completo. Posteriormente le daremos las dimensiones de la pantalla y lo añadiremos al documento. Al igual que ahora lo añadimos directamente al body
y con las dimensiones de la página, podríamos añadirlo en cualquier lugar y con cualquier dimensión.
WIDTH = window.innerWidth; // Ancho de pantalla
HEIGHT = window.innerHeight; // Alto de pantalla
// Lienzo u objeto encargado del renderizado
var lienzo = new THREE.WebGLRenderer();
// Establecemos las dimensiones del lienzo
lienzo.setSize(
WIDTH,
HEIGHT
);
// Añadimos el lienzo a la página
document.body.appendChild(lienzo.domElement);
Y ahora tenemos que crear la propia escena, que se encarga de almacenar todos los elementos que posteriormente visualizaremos.
// Creamos la escena
var escena = new THREE.Scene;
Añadiendo objetos
Ahora que ya tenemos lo básico creado añadiremos un elemento básico a la escena, en este caso un cubo o prisma. Pero la forma de tratar los objetos es muy similar, por lo que podríamos crear una esfera de la misma forma prácticamente.
Primero crearemos un objeto CubeGeometry
al que le daremos un tamaño, y solo sirve como forma para generar el prisma. Posteriormente crearemos un material con MeshLambertMaterial
, que podría contener texturas, pero en este caso será de color lila.
// Creamos un prisma
var geometriaCubo = new THREE.CubeGeometry(
100, // Dimensiones en eje X
140, // Dimensiones en eje Y
100 // Dimensiones en eje Z
);
// Creamos una apariencia (de lila claro)
var aparienciaLila = new THREE.MeshLambertMaterial({
color: 0x9999FF // Color hexadecimal
});
// Generamos el prisma y le aplicamos la apariencia
var cubo = new THREE.Mesh(geometriaCubo, aparienciaLila);
Lo último, cuando creamos cualquier elemento, es añadirlo a la propia escena que habíamos creado.
// Añadimos el cubo a la escena
escena.add(cubo);
Cámara
Para poder visualizar una escena debemos de tener una cámara que nos de la visión de los elementos. En la práctica no es mucho más diferente que cualquier otro elemento, ya que lo podemos mover y rotar igual que podemos hacer con un prisma, por ejemplo.
Three.js dispone de distintos tipos de cámara, pero la que hace la visualización más realista es PerspectiveCamera
, por lo que no tendríamos que necesitar mucho las demás.
La cámara nos permite establecer el ángulo de visión (estando entre los 40º y 50º un ángulo natural), la relación entre el ancho y el alto y el rango de alcance de la vista (si un elemento está más lejos de eso desaparecerá).
// Generamos la cámara
var camara = new THREE.PerspectiveCamera(
45, // Campo de visión
(WIDTH / HEIGHT), // Proporcion
0.1,
10000 // Campo de visión
);
// Situamos la cámara
camara.position.y = 160; // Elevamos la cámara
camara.position.z = 400; // Alejamos la cámara
También la cámara dispone de un método para centrar su visión a un objeto, y es lo que haremos para ver claramente el prisma. También añadimos la cámara a la escena.
// Centramos la vista en el cubo
camara.lookAt(cubo.position);
// Añadimos la cámara a la escena
escena.add(camara);
Ahora ya podríamos visualizar la escena a través de la ventana o renderizador que ya creamos al principio. Aunque en el código final no se visualiza en este paso, esta sería la forma.
// Renderizamos la escena
lienzo.render(escena, camara);
Simplemente le hemos pasado la escena y la cámara con la que vamos a ver la escena. También se podría usar otra cámara o mostrar dos vistas distintas de la misma escena con mucha facilidad.
El resultado, antes de aplicar las luces es el siguiente.
Iluminación
Para poder ver con claridad los colores de la escena necesitamos añadirle luz, que actúa de forma similar a una cámara, pero en lugar de darle parámetros de visualización le pasaremos un número (en hexadecimal, pero numérico). También tenemos que darle una posición, al igual que con la cámara (aunque en este caso por el método directo) y añadirla a la escena.
En este ejemplo voy a añadir dos luces, una rojiza y otra azulada.
// Creamos una par de focos de luz
var luz1 = new THREE.PointLight(0xff0044); // Rojizo
luz1.position.set(
120, // Posición en eje X
260, // Posición en eje Y
100 // Posición en eje Z
);
var luz2 = new THREE.PointLight(0x4499ff); // Azulado
luz2.position.set(
-100, // Posición en eje X
100, // Posición en eje Y
200 // Posición en eje Z
);
// Añadimos las luces
escena.add(luz1);
escena.add(luz2);
Tras añadir las luces si le enviamos la imagen al render veríamos lo siguiente.
Animar la escena
Three.js nos facilita una función para ejecutar de forma correcta la escena, creando un nuevo fotograma cuando está disponible el equipo. Es decir, si se pilla la ejecución o se ralentiza el equipo no se animará el siguiente fotograma, lo que ayuda a mejorar la estabilidad (de nada sirve sobrecargar la página si ya esta pillada).
Esta acción la haremos con requestAnimationFrame
que funciona de forma similar a un setTimeout, al que le tenemos que pasar una función y el tiempo lo determina solo.
En este ejemplo que estamos realizando haremos rotar a nuestro prisma (en el eje Z de forma continua y en el eje Y oscilando).
Al final de mover los elementos hacemos la petición de nuevo con requestAnimationFrame
.
x=0; // Lo usamos para la oscilación
function renderizar(){
// Rotamos el cubo
cubo.rotation.y += Math.PI * 0.5 / 180; // Ángulo en radianes
cubo.rotation.z += Math.PI * Math.cos(x++ / 50) / 180;
// Renderizamos la escena
lienzo.render(escena, camara);
// Volvemos a renderizar
requestAnimationFrame(renderizar);
}
// Empezamos a renderizar
renderizar();
El resultado final es el siguiente y podéis consultar el código completo en GitHub.
Resumen
Esto es solo la punta del iceberg, tras Three.js hay un mundo con infinitas posibilidades y que cada día está dejando ver mejores ejemplos de uso. Y sin duda deja la puerta abierta a los videojuegos serios e indies para hacerse un hueco en todas las plataformas de un plumazo.
0 comentarios:
Publicar un comentario