WebGL con tres.js texturas y partículas

Desde su introducción, los gráficos 3D en el navegador han sido un tema popular. Pero si tuviera que crear sus aplicaciones utilizando WebGL antiguo, tomaría mucho tiempo. Pero ahora tenemos algunas bibliotecas muy útiles que podemos aprovechar, como Three.js. Así que en esta serie te mostraré cómo crear impresionantes experiencias en 3D para el navegador..

Espero que tengas una comprensión básica del espacio 3D antes de comenzar a leer este tutorial, ya que no explicaré cosas como coordenadas, vectores, etc..


Preparación

Comenzaremos con el código de la parte anterior de esta serie. Además, tome los recursos que proporcioné y colóquelos en la misma carpeta que su aplicación. Ahora, ya que usaremos imágenes aquí, tendrá que colocar su aplicación en algún servidor estático (puede ser local), porque a menos que inicie el navegador con el acceso a archivos habilitado desde archivos (por ejemplo, usando el --permitir acceso a archivos desde indicador en Chrome) CORS no le permitirá cargarlos desde un archivo. Eso es todo lo que necesitas hacer antes de continuar.


Paso 1: Cargando la textura

Si alguna vez te has aburrido tanto que creaste algo utilizando OpenGL puro, probablemente recuerdes cuánto dolor te cuesta cargar una textura. Afortunadamente, Three.js viene con una buena función que cargará y configurará la textura para nosotros. Agregue esta línea antes de la definición del material de nuestro cubo:

 var cubeTexture = THREE.ImageUtils.loadTexture ('./ box.png');

Es realmente todo lo que tienes que hacer para cargar tu textura.

En una aplicación del mundo real, tendrá que precargar la textura como cualquier imagen normal y mostrar a los usuarios una barra de carga elegante para informarles que está cargando (Three.js usará la imagen almacenada en caché)..


Paso 2: pintando el cubo

Ahora aplicaremos la textura a nuestro cubo. Esto también es fácil, solo necesitas reemplazar la definición de color en el material del cubo para tener este aspecto:

 var cubeMaterial = new THREE.MeshLambertMaterial (map: cubeTexture);

los mapa atributo establece la textura. Ahora puede abrir el navegador y debería ver un cubo giratorio con textura:


También puedes colorear la textura, solo agrega la color Definición en las opciones del material, así:

 var cubeMaterial = new THREE.MeshLambertMaterial (map: cubeTexture, color: 0x28c0ec);

Y ahora el cubo se vuelve azul:


De esta manera, puede tener varios objetos diferentes con la misma textura si solo cambia el color.


Paso 3: Múltiples materiales

Puedes configurar diferentes materiales para cada cara del cubo. Para lograrlo, tienes que cambiar la definición de todo el material. Primero, define el materiales formación. Cada elemento de la matriz corresponderá al material de una cara. Van en este orden: derecha, izquierda, arriba, abajo, frente y atrás:

 materiales var = []; materiales.push (nuevo THREE.MeshLambertMaterial (map: cubeTexture, color: 0xff0000)); // materiales de la cara derecha.push (nuevo THREE.MeshLambertMaterial (map: cubeTexture, color: 0xffff00)); // materiales de la cara izquierda.push (nuevo THREE.MeshLambertMaterial (map: cubeTexture, color: 0xffffff)); // top face materials.push (nuevo THREE.MeshLambertMaterial (map: cubeTexture, color: 0x00ffff)); // materiales de la cara inferior.push (nuevo THREE.MeshLambertMaterial (map: cubeTexture, color: 0x0000ff)); // front face materials.push (nuevo THREE.MeshLambertMaterial (map: cubeTexture, color: 0xff00ff)); // cara posterior

Como puede ver, cada cara tiene su propio material, por lo que puede configurar diferentes texturas, colores y otros atributos para cada una. A continuación, cambie el tipo de material del cubo a THREE.MeshFaceMaterial:

 var cubeMaterial = new THREE.MeshFaceMaterial (materiales);

Solo necesitas pasar el materiales La matriz como parámetro. En el navegador debes ver que cada lado del cubo tiene un color diferente:



Paso 4: Partículas!

Digamos que desea crear un efecto de copos de nieve girando en su aplicación. Si renderizas cada copo de nieve como malla obtendrás fps muy bajos. Ahí es donde las partículas entran en juego. Son mucho menos complicados, y dibujarlos como un sistema de partículas completo los hace realmente eficientes.

Comience con la creación de una geometría para nuestras partículas:

 partículas var = nueva TRES. Geometría;

Tres. Geometría Es un objeto de geometría base, sin forma alguna. Ahora tenemos que definir la posición de cada partícula en el sistema. Deja que sea completamente al azar:

 para (var p = 0; p < 2000; p++)  var particle = new THREE.Vector3(Math.random() * 500 - 250, Math.random() * 500 - 250, Math.random() * 500 - 250); particles.vertices.push(particle); 

Este bucle creará 2000 partículas colocadas al azar y las pondrá todas en la geometría. A continuación, tienes que definir el material de las partículas:

 var particleMaterial = new THREE.ParticleBasicMaterial (color: 0xeeeeee, tamaño: 2);

Note que estamos usando THREE.ParticleBasicMaterial, que es sólo para partículas. En las opciones solo definimos el color y el tamaño de cada partícula. Finalmente, puedes crear el sistema de partículas y agregarlo a la escena:

 var particleSystem = new THREE.ParticleSystem (partículas, material de partículas); scene.add (sistema de partículas);

Ahora, para hacer que la escena se vea mejor, giremos las partículas en la dirección opuesta a la que está girando el cubo (cambie la hacer función para parecerse a esto):

 función render () requestAnimationFrame (render); var delta = clock.getDelta (); cube.rotation.y - = delta; particleSystem.rotation.y + = delta; renderer.render (escena, cámara); 

Movimos el clock.getDelta a la variable, porque si la usaras asi:

 cube.rotation.y - = clock.getDelta (); particleSystem.rotation.y + = clock.getDelta ();

El sistema de partículas no giraría, porque la segunda llamada devolverá un número cercano a cero (recuerde que está obteniendo el tiempo de la última llamada).

Ahora abre el navegador y deberías ver un cubo y partículas girando:


Combinemos las dos cosas que aprendió en este tutorial y convirtamos esos feos cuadrados blancos en verdaderos copos de nieve. Primero, cargue la textura del copo de nieve:

 var particleTexture = THREE.ImageUtils.loadTexture ('./ snowflake.png');

Ahora, cambia el material de las partículas para usar la textura. Además, habilite la transparencia y aumente las partículas para que podamos ver la forma:

 var particleMaterial = new THREE.ParticleBasicMaterial (map: particleTexture, transparent: true, size: 5);

Si abres el navegador, deberías ver algunos copos de nieve agradables que fluyen alrededor del cubo:



Paso 5: Humo

El efecto humo es bastante fácil de lograr y se ve bien. Comience por crear la geometría, al igual que con los copos de nieve:

 var smokeParticles = new THREE.Geometry; para (var i = 0; i < 300; i++)  var particle = new THREE.Vector3(Math.random() * 32 - 16, Math.random() * 230, Math.random() * 32 - 16); smokeParticles.vertices.push(particle); 

La única diferencia aquí es que estamos eligiendo la posición de un prisma rectangular con dimensiones 32x32x230. Ahora, vamos a cargar la textura y definir el material:

 var smokeTexture = THREE.ImageUtils.loadTexture ('./ smoke.png'); var smokeMaterial = new THREE.ParticleBasicMaterial (map: smokeTexture, transparente: verdadero, mezcla: THREE.AdditiveBlending, tamaño: 50, color: 0x111111);

En la definición del material, hay una mezcla opción. Le dice al renderizador cómo debe renderizar un objeto sobre otro. Con TRES. los valores de color superpuestos se agregarán entre sí, lo que dará como resultado un humo más brillante en las áreas con mayor densidad de partículas. También ajustamos el color a casi negro, para que el humo se vea más natural..

Finalmente, crea el sistema de partículas, muévelo un poco hacia la izquierda y agrégalo a la escena:

 var smoke = nuevo THREE.ParticleSystem (smokePartticles, smokeMaterial); smoke.sortParticles = true; smoke.position.x = -150; scene.add (humo);

También tienes que configurar humos.sortPartículas a la verdad Cuando es falso, el fondo del sprite se puede dibujar en negro. Si abres el navegador, deberías ver una columna de humo inmóvil junto al cubo:


Para animar el humo, tenemos que recorrer todas las partículas y moverlas un poco hacia arriba. Agregue este código a la hacer función:

 var particleCount = smokeParticles.vertices.length; while (particleCount--) var partícula = smokeParticles.vertices [particleCount]; partícula.y + = delta * 50; if (partícula.y> = 230) partícula.y = Matemáticas.random () * 16; partícula.x = Math.random () * 32 - 16; partícula.z = Math.random () * 32 - 16;  smokeParticles .__ dirtyVertices = true;

En el bucle estamos añadiendo delta * 50 a la posición y de la partícula. A continuación, verificamos si la partícula es más alta que 230, si es así, elegimos al azar su nueva posición en algún lugar en la parte inferior del pilar de humo. Finalmente, lo más importante: configurar la geometría. __dirtyVertices bandera a verdadero.

Para mejorar el rendimiento, Three.js almacena en caché los objetos para evitar la creación de todas las llamadas de WebGL de nuevo en cada fotograma, por lo que si cambiamos algo en la geometría del objeto, debemos informar al renderizador de que ha cambiado. Básicamente, la __dirtyVertices bandera solo alcanzará el elemento.

Si abres el navegador ahora deberías ver un humo animado al lado del cubo.


Conclusión

En este tutorial has aprendido a usar texturas y partículas. Como antes, no tengas miedo de experimentar un poco con tu aplicación. Si tiene problemas, eche un vistazo a la documentación. En el siguiente artículo te enseñaré cómo cargar modelos y animarlos..