viernes, 6 de junio de 2014

Lo básico


Tutoriales THREEJS - Lo básico

¿Que es THREE JS?

La llegada de HTML5 trajo bazo el brazo un gran número de novedades para el desarrollo de páginas y aplicaciones. Una de las mas impactantes es la librería para programación de gráficos 3D llamada WebGL. Con ella podemos mostrar en navegador imágenes, animaciones o aplicaciones interactivas completamente realizadas en un entorno 3D renderizadas en tiempo real dentro de nuestra página web sin necesidad de plug-ins o aplicaciones externas.
Solo hay un problema, la programación en WebGL no es excesivamente difícil ni complicada, pero es infernalmente tediosa, para dibujar un simple cubo, aplicar un textura o realizar cualquier operación sencilla hay que escribir una cuantas decenas de líneas de código. La solución, o crearte tu propia librería de clases y enfrentarte tu solito a los infiernos o utilizar alguna existente que te facilite un poco el trabajo.
Pues bien, Three js es un framework realizado por el señor Doob muy sencillo de usar y comprender.
¿Pegas? Como todo, Three js esta desarrollo y puedes encontrarte algunas situaciones donde la diferencia de rendimiento entre WebGL puro y Three js es notable. No es lo mismo crear un código especifico para una acción en concreto que cargar una librería de clases completa, y más en javascript, pero eso.... ya lo sabemos todos...
¿Ventajas? Existe una gran comunidad de programadores trabajando de forma continuada en Three js y las actualizaciones y mejoras son constantes. Three js tiene ya una amplísima colección de librerías no solo para el trabajo con WebGL, con unas pocas líneas de codigo dispones además de todo un conjunto de operaciones con vectores, matrix y cuaternios ,importadores de modelos desde aplicaciones de diseño en 3D de toda la vida, librerias para el trabajo con OpenGL Shaders, controles de ratón y teclado, joyticks, etc...
En resumen, que el tiempo de desarrollo y/o aprendizaje de WebGL respecto a Threejs compensa con creces estas diferencias y ademas, siempre puedes aportar ideas y mejoras al proyecto ;)
Bueno, y después de la obligada chapa de presentación... estoy seguro ademas de que ya vendreis bastante informados sobre el tema. Así que... a la sustancia!

El marco

Para mostrar 3D en nuestra página, necesitamos al menos unas cuantas cosas, un objeto 2D o 3D, un escenario donde colocarlo, algo de luz, una cámara para mostrarlo, un lugar en nuestra página o una página completa donde colocarlo y por supuesto... la librerías de threejs.

La librerías de THREE JS

Podeis bajaros la ultima librería actualizada de Threejs en la página del proyecto http://threejs.org

El codigo HTML

Como de esto ya sabeis la tira... a lo simple, simplemente necesitamos un marco HTML con su body y cargar las librerías de threejs, algo como...


 <html>
 <head>
 <script src="js/three.min.js"></script>
 </head>
 <body>
 </body>
 </html>


El fichero three.min.js es la versión ofuscada(comprimida) de las librerías mas habituales de Threejs, la encontrareis dentro del archivo zip que os hayáis descargado o en el github dentro del directorio /build/, podeis utilizar cualquiera de los dos ficheros, el ofuscado "three.min.js" o el legible "three.js".

El objeto WebGLRenderer

Digamos que es nuestra pantalla, comunmente llamada... "canvas" o "render", es el área donde vamos a visualizar nuestro contenido 3D.
Para crearlo basta con crear el objeto WebGLRenderer, ajustar algunos parámetros, en principio nos basta con el tamaño, el color de fondo o borrado e insertarlo en un bloque html.
Como vamos a utilizar todo el espacio disponible dentro de nuestro navegador, obtenemos el tamaño de las propiedades innerWidth e innerHeight del objeto window de toda la vida.

 //creamos un objeto div
 var canvas3d = document.createElement("div");
 document.body.appendChild(canvas3d);

 //creamos el objeto WebGLRenderer
 var renderer = new THREE.WebGLRenderer();
 renderer.setSize(window.innerWidth, window.innerHeight); //width, height
 renderer.setClearColor(0x000000, 1) //color, alfa

 //e insertamos el objeto render en el div

 canvas3d.appendChild(this.renderer.domElement);


La escena

El escenario, donde vamos a poner nuestros objetos, luces, cámaras, ect...
Tan solo con...


 var scene = new THREE.Scene();


nos basta para crearlo.
*El objeto Scene, como todos los objetos que podemos añadirle, hereda del objeto Object3D que es donde están declaradas las propiedades y métodos referentes a posición, rotación, orden de coordenadas y otros muchos comunes tanto a cámaras, luces y objetos

La iluminación

Tenemos varios tipos de objetos de iluminación en Threejs que podemos utilizar, arealights, spotLights... asi a ojo creo recordar que 7, pero de momento y para no liar la madeja nos basta con una luz direccional con sus propiedades por defecto para ver el objeto y proyectar algunas sombras. En los próximos tutoriales las iremos explicando todas con mas detalle.

 //Creamos la luz, la posicionamos en la escena y la añadimos a escena
 var light1 = new THREE.DirectionalLight(0xAAAAAA, 0.8); //color, intensidad
 light1.position.set(10, 20, 5); //x,y,z
 scene.add(light1);


La camara

Disponemos de dos tipos de cámara, vista ortográfica(los objetos mantienen el mismo tamaño independientemente de la distancia) y perspectiva(los objetos cambian su tamaño en funcián de la distancia), vamos a crear una del tipo perspectiva también con los mínimos parámetros, la posición y la dirección hacia la que "mira" la cámara

 //fov o campo de visión en mm, y aspect, la relación entre anchura y altura del objeto webglrenderer o del área de renderizado
 var aspect = window.innerWidth / window.innerHeight;
 var camera1 = new THREE.PerspectiveCamera(47, aspect); //fov, aspect
 camera1.position.set(5, 3, -5); //x,y,z....
 camera1.lookAt(scene.position); //objeto THREE.Vector3;

 scene.add(camera1);


Y el mítico.... cubo!

Para crear una figura(Mesh) sea 2D o 3D necesitamos un material y una geometría, posicionarlo y añadirlo a la escena. Tenemos ya predefinidas un buen número de geometrías, ahi va la de siempre... el cubo.

//Para crear la geometría

var geom = new THREE.BoxGeometry(2, 2, 2, 1, 1, 1); //ancho, alto, profundidad, número de segmentos de ancho, nseg alto, nseg profundidad

//el material

var mat = new THREE.MeshBasicMaterial({color: 0xFF6666}); // Objeto con las propiedades del material

Y el objeto en si...

var cubo = new THREE.Mesh(geom, mat); //geometría, material
cubo.position.set(1, 1, 1);
scene.add(cubo);



Ahora solo quedaría renderizar todo lo que hemos puesto y mostrarlo en nuestro canvas de la siguiente forma...


 renderer.render(scene, camera1);




Y !tachannnn, vaya birria de cubo!
Como en todos los tutoriales, os dejo el código completo aquí debajo, este es el tutorial chorras de toda la vida, pero hay que empezar con lo básico, en los siguientes ya haremos cosas un poco mas complejas. Espero que os haya gustado, hasta el siguiente tutorial ;)


<html>
<head>
<script src="js/three.min.js"></script>
</head>
<body>
<script type="text/javascript">
 
 //creamos un objeto div
 var canvas3d = document.createElement("div");
 document.body.appendChild(canvas3d);
 
 //creamos el objeto WebGLRenderer
 var renderer = new THREE.WebGLRenderer();
 renderer.setSize(window.innerWidth, window.innerHeight); //width, height
 renderer.setClearColor(0x000000, 1) //color, alfa

 //e insertamos el objeto render en el div
 canvas3d.appendChild(this.renderer.domElement);
 
 //La escena
 var scene = new THREE.Scene();

 //Creamos la luz, la posicionamos en la escena y la añadimos a escena
 var light1 = new THREE.DirectionalLight(0xAAAAAA, 0.8); //color, intensidad
 light1.position.set(10, 20, 5); //x,y,z
 scene.add(light1);
 
 var aspect = window.innerWidth / window.innerHeight;
 var camera1 = new THREE.PerspectiveCamera(47, aspect); //fov, aspect
 camera1.position.set(5, 3, -5); //x,y,z....
 camera1.lookAt(scene.position); //objeto THREE.Vector3;

 scene.add(camera1);
 
 //Para crear la geometria
 var geom = new THREE.BoxGeometry(2, 2, 2, 1, 1, 1); //ancho, alto, profundidad, numero de segmentos de ancho, nseg alto, nseg profundidad

 //el material
 var mat = new THREE.MeshBasicMaterial({color: 0xFF6666}); // Objeto con las propiedades del material

 //Y el objeto en si...
 var cubo = new THREE.Mesh(geom, mat); //geometría, material
 cubo.position.set(1, 1, 1);
 scene.add(cubo);
 

 //Tachaaaaan!
 renderer.render(scene, camera1);

</script>
</body>
</html>


PD: Si lees esto veras un enlace a la campaña de financiación de nuestro futuro videojuego Damn Cars!, te agradeceríamos muchísimo que entraras y colaboraras, ya sea compartiendo, difundiendo o que carajo, incluso contribuyendo ;).